diff --git a/.cursor/coding-style.json b/.cursor/coding-style.json new file mode 100644 index 0000000000000..12f095f32e947 --- /dev/null +++ b/.cursor/coding-style.json @@ -0,0 +1,19 @@ +{ + "indentation": { + "type": "spaces", + "size": 4 + }, + "lineLength": 100, + "braceStyle": "allman", + "namingConventions": { + "functions": { + "public": "PascalCase", + "private": "_PascalCase" + }, + "variables": { + "local": "camelCase", + "global": "PascalCase", + "constants": "UPPER_CASE" + } + } +} diff --git a/.cursor/editor.json b/.cursor/editor.json new file mode 100644 index 0000000000000..76cfa5d0ccbf4 --- /dev/null +++ b/.cursor/editor.json @@ -0,0 +1,52 @@ +{ + "editor": { + "defaultFormatter": null + }, + "[c,cpp]": { + "editor": { + "tabSize": 4, + "insertSpaces": true, + "detectIndentation": false, + "trimAutoWhitespace": true, + "formatOnSave": false, + "formatOnType": true, + "defaultFormatter": "clang-format", + "rulers": [100], + "wordWrap": "off" + } + }, + "files": { + "associations": { + "*.c": "c", + "*.h": "c", + "*.cpp": "cpp", + "*.hpp": "cpp" + }, + "encoding": "utf8", + "trimTrailingWhitespace": true, + "insertFinalNewline": true, + "exclude": { + "**/.git": true, + "compile_commands.json": true, + "output-*": true, + "modules/optional": true, + "modules/3rdparty": true, + "modules/bootcd_extras": true, + "modules/livecd_extras": true, + "modules/hybridcd_extras": true, + "modules/[Aa][Hh][Kk]_[Tt]ests": true, + ".cache": true, + ".cproject": true, + ".DS_Store": true, + ".project": true, + ".settings": true, + ".vscode": true, + "sdk/tools/winesync/winesync.cfg": true, + "**/build": true, + "**/obj": true, + "**/bin": true, + "**/*.o": true, + "**/*.obj": true + } + } +} diff --git a/.cursor/settings.json b/.cursor/settings.json new file mode 100644 index 0000000000000..c8ffae7a0c185 --- /dev/null +++ b/.cursor/settings.json @@ -0,0 +1,46 @@ +{ + "projectType": "reactos", + "language": { + "c": { + "standard": "c99", + "warnings": ["all", "error", "pedantic", "unused"], + "formatter": "clang-format", + "linter": "clang-tidy" + }, + "cpp": { + "standard": "c++11", + "warnings": ["all", "error", "pedantic", "unused"], + "formatter": "clang-format", + "linter": "clang-tidy" + } + }, + "codingStyle": "reactos", + "formatOnSave": false, + "lintOnSave": false, + "paths": { + "source": [ + "base", + "boot", + "dll", + "drivers", + "hal", + "ntoskrnl", + "subsystems", + "win32ss" + ], + "include": [ + "sdk/include" + ], + "docs": [ + "**/*.md", + "media/doc/*.md", + "media/doc/*.txt" + ], + "tests": [ + "modules/rostests" + ], + "build": [ + "output-*" + ] + } +} diff --git a/.gitattributes b/.gitattributes index ee079a75c8dca..c2c723297f424 100644 --- a/.gitattributes +++ b/.gitattributes @@ -30,6 +30,9 @@ *.TXT text *.y text +# Files with these extensions must always have LF (Unix) line endings. +*.sh text eol=lf + # Files with these extensions end up in the built ReactOS system, so they # need to have CRLF line endings. *.bat text eol=crlf diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 8622a6e683aa9..a7f76ec4af5ab 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -17,3 +17,8 @@ _Use a TODO when your pull request is Work in Progress._ - [ ] - [ ] + +## Testbot runs (Filled in by Devs) + +- [ ] KVM x86: +- [ ] KVM x64: \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6e53c2df7f19c..ecf47dbc9c2ff 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,7 +15,7 @@ jobs: - dllver: 0x600 config: Release fail-fast: false - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - name: Get RosBE build specifics id: get_rosbe_spec diff --git a/.gitignore b/.gitignore index f14e4ccbe72ee..dbed57aa81dc1 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,5 @@ modules/[Aa][Hh][Kk]_[Tt]ests .settings .vscode sdk/tools/winesync/winesync.cfg +.cursor/cache/ +.cursor/logs/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 13916a9362a16..92cd61f0f7e02 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,12 +68,19 @@ include(sdk/cmake/config.cmake) # Compiler flags handling include(sdk/cmake/compilerflags.cmake) +# set_wine_module function +include(sdk/cmake/set_wine_module.cmake) + add_definitions( -D__REACTOS__ # swprintf without count argument is used in most of the codebase -D_CRT_NON_CONFORMING_SWPRINTFS ) +if (ARCH STREQUAL "amd64") + add_definitions(-DBUILD_WOW64_ENABLED) +endif() + # There doesn't seem to be a standard for __FILE__ being relative or absolute, so detect it at runtime. file(RELATIVE_PATH _PATH_PREFIX ${REACTOS_BINARY_DIR} ${REACTOS_SOURCE_DIR}) if (NOT MSVC AND ((CMAKE_C_COMPILER_ID STREQUAL "GNU") AND (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "8.0.0") @@ -140,6 +147,10 @@ if(NOT CMAKE_CROSSCOMPILING) add_definitions(/D_X86_ /D__i386__ /DWIN32 /D_WINDOWS) elseif(ARCH STREQUAL "amd64") add_definitions(-D_AMD64_ -D__x86_64__ /DWIN32 -D_WINDOWS) + elseif(ARCH STREQUAL "arm") + add_definitions(-D__arm__) + elseif(ARCH STREQUAL "arm64") + add_definitions(-D__aarch64__) endif() if(MSVC_VERSION GREATER 1699) add_definitions(/D_ALLOW_KEYWORD_MACROS) @@ -153,7 +164,10 @@ if(NOT CMAKE_CROSSCOMPILING) set(NATIVE_TARGETS asmpp bin2c widl gendib cabman fatten hpp isohybrid mkhive mkisofs obj2bin spec2def geninc mkshelllink utf16le xml2sdb) if(NOT MSVC) - list(APPEND NATIVE_TARGETS rsym pefixup) + list(APPEND NATIVE_TARGETS pefixup) + if (ARCH STREQUAL "i386") + list(APPEND NATIVE_TARGETS rsym) + endif() endif() install(TARGETS ${NATIVE_TARGETS}) @@ -248,11 +262,13 @@ Enable this if the module uses typeid or dynamic_cast. You will probably need to add_definitions(-DSARCH_XBOX) elseif(SARCH STREQUAL "pc98") add_definitions(-DSARCH_PC98) + elseif(SARCH STREQUAL "wow64") + add_definitions(-DBUILD_WOW6432) endif() elseif(ARCH STREQUAL "amd64") # clang-cl defines this one for itself if (NOT (MSVC AND CMAKE_C_COMPILER_ID STREQUAL "Clang")) - add_compile_definitions(_M_AMD64) + add_compile_definitions(_M_AMD64 _M_X64) endif() add_definitions(-D_AMD64_ -D__x86_64__ -D_WIN64) elseif(ARCH STREQUAL "arm") diff --git a/CODEOWNERS b/CODEOWNERS index a5c57c1639ecf..c9b63fca14cc0 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -116,6 +116,20 @@ # S: Abandoned /ntoskrnl/cache/ +# Client/Server Runtime Subsystem +# M: HBelusca, Hermès Bélusca-Maïto +# S: Maintained +/sdk/include/reactos/subsys/csr/ @HBelusca +/subsystems/csr/ @HBelusca +/win32ss/user/ntuser/csr.* @HBelusca + +# Clipboard Viewer +# M: HBelusca, Hermès Bélusca-Maïto +# R: Mondgestein, Ricardo Hanke +# S: Maintained +/base/applications/clipbrd/ @HBelusca +/base/applications/cmdutils/clip/ @HBelusca + # CMake Build Scripts # M: # R: learn-more, learn_more, Mark Jansen @@ -124,6 +138,56 @@ /sdk/cmake/ *.cmake +# Command-line Utilities +# M: HBelusca, Hermès Bélusca-Maïto +# S: Maintained +/base/applications/cmdutils/attrib/ @HBelusca +/base/applications/cmdutils/chcp/ @HBelusca +/base/applications/cmdutils/doskey/ @HBelusca +/base/applications/cmdutils/eventcreate/ @HBelusca +/base/applications/cmdutils/find/ @HBelusca +/base/applications/cmdutils/help/ @HBelusca +/base/applications/cmdutils/mode/ @HBelusca +/base/applications/cmdutils/more/ @HBelusca +/base/applications/cmdutils/taskkill/ @HBelusca +/base/applications/cmdutils/timeout/ @HBelusca +/sdk/lib/conutils/ @HBelusca + +# Command-line Prompt Interpreter +# M: HBelusca, Hermès Bélusca-Maïto +# S: Maintained +/base/shell/cmd/ @HBelusca + +# Console Client/Server Subsystem, Terminal Emulator / Text-Mode +# M: HBelusca, Hermès Bélusca-Maïto +# S: Maintained +/dll/cpl/console/ @HBelusca +/dll/win32/kernel32/client/console/ @HBelusca +/dll/win32/kernel32/include/console.h @HBelusca +/drivers/base/condrv/ @HBelusca +/drivers/setup/blue/ @HBelusca +/modules/rostests/winetests/kernel32/console.c @HBelusca +/sdk/include/reactos/drivers/condrv/ @HBelusca +/sdk/include/reactos/drivers/blue/ @HBelusca +/sdk/include/reactos/subsys/win/conmsg.h @HBelusca +/sdk/include/reactos/subsys/win/console.h @HBelusca +/win32ss/user/ntuser/console.c @HBelusca +/win32ss/user/winsrv/concfg/ @HBelusca +/win32ss/user/winsrv/consrv/ @HBelusca + +# Event Log Subsystem +# M: HBelusca, Hermès Bélusca-Maïto +# M: EricKohl, ekohl, Eric Kohl +# S: Maintained +/base/services/eventlog/ @EricKohl @HBelusca +/dll/win32/advapi32/service/eventlog.c @EricKohl @HBelusca +/sdk/lib/evtlib/ @HBelusca + +# Event Log Viewer +# M: HBelusca, Hermès Bélusca-Maïto +# S: Maintained +/base/applications/mscutils/eventvwr/ @HBelusca + # File Patch API # M: learn-more, learn_more, Mark Jansen # S: Maintained @@ -139,7 +203,7 @@ # Filesystem Filter Manager # M: gedmurphy, Ged, Ged Murphy # S: Maintained -/drivers/filters/fltmgr/ @gedmurphy +/drivers/filters/fltmgr/ @gedmurphy # File Systems Run Time Library # M: HeisSpiter, Heis Spiter, Pierre Schweitzer @@ -150,11 +214,13 @@ /sdk/lib/drivers/ntoskrnl_vista/fsrtl.c @HeisSpiter # Freeloader -# M: +# M: HBelusca, Hermès Bélusca-Maïto # R: tkreuzer, ThePhysicist, Timo Kreuzer # R: Extravert-ir, extravert34, Victor Perevertkin # S: Maintained -/boot/freeldr/freeldr/ @tkreuzer @Extravert-ir +/boot/freeldr/freeldr/ @HBelusca @tkreuzer @Extravert-ir +/boot/rtl/ @HBelusca +/ntoskrnl/config/cmboot.c @HBelusca # HAL / APIC # M: tkreuzer, ThePhysicist, Timo Kreuzer @@ -187,6 +253,12 @@ # S: Maintained /drivers/storage/mountmgr/ @HeisSpiter +# MSConfig +# M: HBelusca, Hermès Bélusca-Maïto +# S: Maintained +/base/applications/msconfig/ @HBelusca +/base/applications/msconfig_new/ @HBelusca + # Network Drivers # M: # R: ThFabba, Thomas Faber @@ -215,11 +287,29 @@ # S: Maintained /dll/ntdll/ @HeisSpiter @learn-more @ThFabba @tkreuzer +# NT Virtual DOS Machine +# M: HBelusca, Hermès Bélusca-Maïto +# R: reactos573, aandrejevic, Aleksandar Andrejevic +# S: Maintained +/dll/win32/kernel32/client/vdm.c @reactos573 @HBelusca +/dll/win32/kernel32/include/vdm.h @reactos573 @HBelusca +/sdk/include/reactos/subsys/win/vdm.h @reactos573 @HBelusca +/ntoskrnl/vdm @reactos573 @HBelusca +/sdk/include/reactos/libs/fast486/ @reactos573 @HBelusca +/sdk/lib/fast486/ @reactos573 @HBelusca +/subsystems/mvdm/ @reactos573 @HBelusca +/subsystems/win/basesrv/vdm.* @reactos573 @HBelusca + # Printing # M: ColinFinck, Colin Finck # S: Maintained /win32ss/printing/ @ColinFinck +# Program Manager +# M: HBelusca, Hermès Bélusca-Maïto +# S: Maintained +/base/shell/progman/ @HBelusca + # ReactOS API Tests # M: # R: learn-more, learn_more, Mark Jansen @@ -232,7 +322,25 @@ # S: Maintained /modules/rostests/kmtests/ @ThFabba -# ROS internals tools +# ReactOS Setup +# M: HBelusca, Hermès Bélusca-Maïto +# R: EricKohl, ekohl, Eric Kohl +# S: Maintained +/base/setup/ @HBelusca +/base/system/winlogon/setup.c @EricKohl +/dll/win32/setupapi/ +/dll/win32/syssetup/ @EricKohl +/drivers/setup/ @HBelusca +/sdk/include/reactos/libs/syssetup/ @EricKohl + +# ReactOS miscellaneous tools +# M: +# R: HBelusca, Hermès Bélusca-Maïto +# S: Maintained +/modules/rosapps/applications/cmdutils/cat/ @HBelusca +/modules/rosapps/applications/sysutils/utils/partinfo/ @HBelusca + +# ReactOS internals tools # M: HeisSpiter, Heis Spiter, Pierre Schweitzer # S: Maintained /modules/rosapps/applications/rosinternals/ @HeisSpiter @@ -252,15 +360,26 @@ /modules/rostests/kmtests/ntos_se/ @GeoB99 /ntoskrnl/se/ @GeoB99 +# Session Manager Subsystem +# M: HBelusca, Hermès Bélusca-Maïto +# S: Maintained +/base/system/smss/ @HBelusca +/sdk/include/reactos/subsys/sm/ @HBelusca +/sdk/lib/smlib/ @HBelusca + # Shell # M: # R: learn-more, learn_more, Mark Jansen # R: yagoulas, Giannis Adamopoulos +# R: HBelusca, Hermès Bélusca-Maïto # S: Maintained /base/shell/explorer/ @learn-more @yagoulas /base/shell/rshell/ @learn-more @yagoulas /dll/win32/browseui/ @learn-more @yagoulas /dll/win32/shell32/ @learn-more @yagoulas +/dll/win32/shell32/CShellLink.* @HBelusca +/dll/win32/shell32/CUserNotification.* @HBelusca +/dll/win32/shell32/systray.cpp @HBelusca # Shell Extensions # M: @@ -311,8 +430,30 @@ # Win32 file functions # M: HeisSpiter, Heis Spiter, Pierre Schweitzer +# R: HBelusca, Hermès Bélusca-Maïto +# S: Maintained +/dll/win32/kernel32/client/file/ @HeisSpiter +/dll/win32/kernel32/client/file/find.c @HBelusca + +# Win32 Subsystem - User Server +# M: +# R: HBelusca, Hermès Bélusca-Maïto # S: Maintained -/dll/win32/kernel32/client/file/ @HeisSpiter +/win32ss/user/winsrv/ +/win32ss/user/winsrv/usersrv/harderror.c @HBelusca + +# Win32 Subsystem Shutdown +# M: HBelusca, Hermès Bélusca-Maïto +# R: EricKohl, ekohl, Eric Kohl +# S: Maintained +/base/system/winlogon/sas.c @EricKohl @HBelusca +/base/system/winlogon/shutdown.c @EricKohl @HBelusca +/dll/win32/advapi32/misc/shutdown.c @EricKohl +/dll/win32/msgina/shutdown.c @EricKohl @HBelusca +/win32ss/user/ntuser/shutdown.* @HBelusca +/win32ss/user/user32/misc/exit.c @HBelusca +/win32ss/user/winsrv/consrv/shutdown.c @HBelusca +/win32ss/user/winsrv/usersrv/shutdown.c @HBelusca # Windows Network File Systems functions # M: HeisSpiter, Heis Spiter, Pierre Schweitzer @@ -338,6 +479,11 @@ amd64/ @tkreuzer /boot/freeldr/freeldr/arch/realmode/amd64.S @tkreuzer +# Wine DirectX +# M: DarkFire01, The_DarkFire_, Justin Miller +# S: Upstream +/dll/directx/wine/ @DarkFire01 + # Translations # This is the list of translation teams in ReactOS GitHub organization. # If you want to be part of one - hit us at https://chat.reactos.org/ diff --git a/CODING_STYLE.md b/CODING_STYLE.md new file mode 100644 index 0000000000000..4aefe31fe9d35 --- /dev/null +++ b/CODING_STYLE.md @@ -0,0 +1,356 @@ +# Coding Style + +This article describes general coding style guidelines, which should be used for new ReactOS code. These guidelines apply exclusively to C and C++ source files. The Members of ReactOS agreed on this document in the October 2013 meeting. + +As much existing ReactOS code as possible should be converted to this style unless there are reasons against doing this (like if the code is going to be rewritten from scratch in the near future). See [Notes on reformatting existing code](#notes-on-reformatting-existing-code) for more details. + +Code synchronized with other sources (like Wine) must not be rewritten. [3rd Party Files.txt](https://github.com/reactos/reactos/blob/master/media/doc/3rd%20Party%20Files.txt) and [WINESYNC.txt](https://github.com/reactos/reactos/blob/master/media/doc/WINESYNC.txt) files can be used for tracking synchronized files. + +## File Structure + +1. Every ReactOS source code file should include a file header like this: + +``` +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Does cool things like Memory Management + * COPYRIGHT: Copyright 2017 Arno Nymous + * Copyright 2017 Mike Blablabla + */ +``` + +Please use SPDX license identifiers available at https://spdx.org/licenses. +This makes our source file parseable by licensing tools! + +You should add yourself to the `COPYRIGHT` section of a file if you did a major contribution to it and could take responsibility for the whole file or a part of it. Not more than 3 people shall be in that list for each file. + +`FILE` line of the old header should be removed. + +2. [Doxygen](https://doxygen.reactos.org/) documentation generator is used for ReactOS codebase, so use a proper header for functions, see [API Documentation](https://reactos.org/wiki/Documentation_Guidelines#API_Documentation) for details. + +## Indentation and line width + +1. Line width must be at most **100 characters**. +2. Do not add a space or tab at the end of any line. +3. Indent with **4 spaces**, don't use tabs! +4. Indent both a case label and the case statement of a switch statement. + +**Right:** +```c +switch (Condition) +{ + case 1: + DoSomething(); + break; + + case 2: + { + DoMany(); + ManyMore(); + OtherThings(); + break; + } +} +``` + +**Wrong:** +```c +switch(Condition) +{ +case 1: + DoSomething(); + break; +case 2: + DoMany(); + ManyMore(); + OtherThings(); + break; +} +``` + +5. When a function call does not fit onto a line, align arguments like this: +```c +FunctionCall(arg1, + arg2, + arg3); +``` + +6. Function headers should have this format (preserving the order as in the example): +```c +static // scope identifier +CODE_SEG("PAGE") // section placement +// other attributes +BOOLEAN // return type +FASTCALL // calling convention +IsOdd( + _In_ UINT32 Number); +``` + +## Spacing + +1. Do not use spaces around unary operators. +**Right:** `i++;` +**Wrong:** `i ++;` + +2. Place spaces around binary and ternary operators. +**Right:** `a = b + c;` +**Wrong:** `a=b+c;` + +3. Do not place spaces before comma and semicolon. + +**Right:** +```c +for (int i = 0; i < 5; i++) + DoSomething(); + +func1(a, b); +``` + +**Wrong:** +```c +for (int i = 0; i < 5 ; i++) + DoSomething(); + +func1(a , b) ; +``` + +4. Place spaces between control statements and their parentheses. + +**Right:** +```c +if (Condition) + DoSomething(); +``` + +**Wrong:** +```c +if(Condition) + DoSomething(); +``` + +5. Do not place spaces between a function and its parentheses, or between a parenthesis and its content. + +**Right:** +```c +func(a, b); +``` + +**Wrong:** +```c +func (a, b); +func( a, b ); +``` + +## Line breaking + +1. Each statement should get its own line. + +**Right:** +```c +x++; +y++; + +if (Condition) + DoSomething(); +``` + +**Wrong:** +```c +x++; y++; + +if (Condition) DoSomething(); +``` + +## Braces + +1. Always put braces (`{` and `}`) on their own lines. +2. One-line control clauses may use braces, but this is not a requirement. An exception are one-line control clauses including additional comments. + +**Right:** +```c +if (Condition) + DoSomething(); + +if (Condition) +{ + DoSomething(); +} + +if (Condition) +{ + // This is a comment + DoSomething(); +} + +if (A_Very || (Very && Long || Condition) && + On_Many && Lines) +{ + DoSomething(); +} + +if (Condition) + DoSomething(); +else + DoSomethingElse(); + +if (Condition) +{ + DoSomething(); +} +else +{ + DoSomethingElse(); + YetAnother(); +} +``` + +**Wrong:** +```c +if (Condition) { + DoSomething(); +} + +if (Condition) + // This is a comment + DoSomething(); + +if (A_Very || (Very && Long || Condition) && + On_Many && Lines) + DoSomething(); + +if (Condition) + DoSomething(); +else { + DoSomethingElse(); + YetAnother(); +} +``` + +## Control structures + +1. Don't use inverse logic in control clauses. +**Right:** `if (i == 1)` +**Wrong:** `if (1 == i)` + +2. Avoid too many levels of cascaded control structures. Prefer a "linear style" over a "tree style". Use `goto` when it helps to make the code cleaner (e.g. for cleanup paths). + +**Right:** +```c +if (!func1()) + return; + +i = func2(); +if (i == 0) + return; + +j = func3(); +if (j == 1) + return; +... +``` + +**Wrong:** +```c +if (func1()) +{ + i = func2(); + if (func2()) + { + j = func3(); + if (func3()) + { + ... + } + } +} +``` + +## Naming + +1. Capitalize names of variables and functions. Hungarian Notation may be used when developing for Win32, but it is not required. If you don't use it, the first letter of a name must be a capital too (no lowerCamelCase). Do not use underscores as separators either. + +**Right:** +```c +PLIST_ENTRY FirstEntry; +VOID NTAPI IopDeleteIoCompletion(PVOID ObjectBody); +PWSTR pwszTest; +``` + +**Wrong:** +```c +PLIST_ENTRY first_entry; +VOID NTAPI iop_delete_io_completion(PVOID objectBody); +PWSTR pwsztest; +``` + +2. Avoid abbreviating function and variable names, use descriptive verbs where possible. + +3. Precede boolean values with meaningful verbs like "is" and "did" if possible and if it fits the usage. + +**Right:** +```c +BOOLEAN IsValid; +BOOLEAN DidSendData; +``` + +**Wrong:** +```c +BOOLEAN Valid; +BOOLEAN SentData; +``` + +## Commenting + +1. Avoid line-wasting comments, which could fit into a single line. + +**Right:** +```c +// This is a one-line comment + +/* This is a C-style comment */ + +// This is a comment over multiple lines. +// We don't define any strict rules for it. +``` + +**Wrong:** +```c +// +// This comment wastes two lines +// +``` + +## Null, false and 0 + +1. The null pointer should be written as `NULL`. In the rare case that your environment recommends a different null pointer (e.g. C++11 `nullptr`), you may use this one of course. Just don't use the value `0`. + +2. Win32/NT Boolean values should be written as `TRUE` and `FALSE`. In the rare case that you use C/C++ `bool` variables, you should write them as `true` and `false`. + +3. When you need to terminate ANSI or OEM string, or check for its terminator, use `ANSI_NULL`. If the string is Unicode or Wide string, use `UNICODE_NULL`. + +## Notes on reformatting existing code + +- Never totally reformat a file and put a code change into it. Do this in separate commits. +- If a commit only consists of formatting changes, say this clearly in the commit message by preceding it with *[FORMATTING]*. + +## Other points + +- Do not use `LARGE_INTEGER`/`ULARGE_INTEGER` unless needed for using APIs. Use `INT64`/`UINT64` instead +- Use `#pragma once` instead of guard defines in headers +- Don't specify a calling convention for a function unless required (usually for APIs or exported symbols) + +## Using an automatic code style tool + +TO BE ADDED BY User:Zefklop + +## Points deliberately left out + +Additional ideas were suggested during the discussion of this document, but a consensus couldn't be reached on them. Therefore we refrain from enforcing any rules on these points: + +- TO BE ADDED BY User:Hbelusca + +## See also + +- [Kernel Coding Style](https://reactos.org/wiki/Kernel_Coding_Style) +- [GNU Indent](https://reactos.org/wiki/GNU_Indent) diff --git a/README.md b/README.md index 02a2e11150933..f0601e3bad19c 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,8 @@ ---

- - ReactOS 0.4.14 Release + + ReactOS 0.4.15 Release Download ReactOS diff --git a/base/applications/CMakeLists.txt b/base/applications/CMakeLists.txt index dccaaa80438e8..fa6e056383648 100644 --- a/base/applications/CMakeLists.txt +++ b/base/applications/CMakeLists.txt @@ -3,6 +3,7 @@ add_subdirectory(atactl) add_subdirectory(cacls) add_subdirectory(calc) add_subdirectory(charmap) +add_subdirectory(cleanmgr) add_subdirectory(clipbrd) add_subdirectory(cmdutils) add_subdirectory(control) @@ -47,5 +48,6 @@ add_subdirectory(utilman) add_subdirectory(winhlp32) add_subdirectory(winver) add_subdirectory(wordpad) +add_subdirectory(wow64test) add_subdirectory(write) -add_subdirectory(wusa) +add_subdirectory(wusa) \ No newline at end of file diff --git a/base/applications/calc/resource.rc b/base/applications/calc/resource.rc index d756a6687fcce..e09c4d9d2c571 100644 --- a/base/applications/calc/resource.rc +++ b/base/applications/calc/resource.rc @@ -28,7 +28,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL /* Icons */ -IDI_CALC ICON DISCARDABLE "res/calc.ico" +IDI_CALC ICON "res/calc.ico" /* Manifest */ #include diff --git a/base/applications/cleanmgr/CMakeLists.txt b/base/applications/cleanmgr/CMakeLists.txt new file mode 100644 index 0000000000000..e3e3c65f6f93a --- /dev/null +++ b/base/applications/cleanmgr/CMakeLists.txt @@ -0,0 +1,9 @@ + +project(cleanmgr) + +# The main application +add_subdirectory(cleanmgr) + +# Cleanup handlers +#add_subdirectory(dataclen) # Data Driven Cleaner + diff --git a/base/applications/cleanmgr/cleanmgr/CCleanupHandler.cpp b/base/applications/cleanmgr/cleanmgr/CCleanupHandler.cpp new file mode 100644 index 0000000000000..f04e134646649 --- /dev/null +++ b/base/applications/cleanmgr/cleanmgr/CCleanupHandler.cpp @@ -0,0 +1,212 @@ +/* + * PROJECT: ReactOS Disk Cleanup + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: CCleanupHandler implementation + * COPYRIGHT: Copyright 2023-2025 Mark Jansen + */ + +#include "cleanmgr.h" + + +CCleanupHandler::CCleanupHandler(CRegKey &subKey, const CStringW &keyName, const GUID &guid) + : hSubKey(subKey) + , KeyName(keyName) + , Guid(guid) + , dwFlags(0) + , Priority(0) + , StateFlags(0) + , SpaceUsed(0) + , ShowHandler(true) + , hIcon(NULL) +{ +} + +CCleanupHandler::~CCleanupHandler() +{ + Deactivate(); + ::DestroyIcon(hIcon); +} + +void +CCleanupHandler::Deactivate() +{ + if (Handler) + { + DWORD dwFlags = 0; + Handler->Deactivate(&dwFlags); + if (dwFlags & EVCF_REMOVEFROMLIST) + UNIMPLEMENTED_DBGBREAK(); + } +} + +bool +CCleanupHandler::Initialize(LPCWSTR pcwszVolume) +{ + if (FAILED_UNEXPECTEDLY( + ::CoCreateInstance(Guid, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IEmptyVolumeCache, &Handler)))) + { + return false; + } + + DWORD dwSize = sizeof(Priority); + if (hSubKey.QueryBinaryValue(L"Priority", &Priority, &dwSize) != ERROR_SUCCESS) + { + if (hSubKey.QueryDWORDValue(L"Priority", Priority) != ERROR_SUCCESS) + Priority = 200; + } + + dwSize = sizeof(StateFlags); + if (hSubKey.QueryDWORDValue(L"StateFlags", StateFlags) != ERROR_SUCCESS) + StateFlags = 0; + + WCHAR PathBuffer[MAX_PATH] = {}; + ULONG nChars = _countof(PathBuffer); + if (hSubKey.QueryStringValue(L"IconPath", PathBuffer, &nChars) != ERROR_SUCCESS) + { + CStringW Tmp; + WCHAR GuidStr[50] = {}; + if (StringFromGUID2(Guid, GuidStr, _countof(GuidStr))) + { + Tmp.Format(L"CLSID\\%s\\DefaultIcon", GuidStr); + CRegKey clsid; + nChars = _countof(PathBuffer); + if (clsid.Open(HKEY_CLASSES_ROOT, Tmp, KEY_READ) != ERROR_SUCCESS || + clsid.QueryStringValue(NULL, PathBuffer, &nChars) != ERROR_SUCCESS) + { + PathBuffer[0] = UNICODE_NULL; + } + } + } + if (!PathBuffer[0]) + StringCchCopyW(PathBuffer, _countof(PathBuffer), L"%systemroot%\\system32\\shell32.dll"); + + int Index = 0; + WCHAR *ptr = wcschr(PathBuffer, L','); + if (ptr) + { + *ptr++ = UNICODE_NULL; + Index = wcstol(ptr, NULL, 10); + } + HICON Large, Small; + UINT Result = ExtractIconExW(PathBuffer, Index, &Large, &Small, 1); + if (Result < 1) + Result = ExtractIconExW(L"%systemroot%\\system32\\shell32.dll", 0, &Large, &Small, 1); + if (Result >= 1) + { + hIcon = Small; + if (!hIcon) + { + hIcon = Large; + } + else + { + ::DestroyIcon(Large); + } + } + + // These options should come from the command line + // dwFlags |= EVCF_SETTINGSMODE; + // dwFlags |= EVCF_OUTOFDISKSPACE; + + CComPtr spHandler2; + HRESULT hr = Handler->QueryInterface(IID_PPV_ARG(IEmptyVolumeCache2, &spHandler2)); + if (SUCCEEDED(hr)) + { + hr = spHandler2->InitializeEx( + hSubKey, pcwszVolume, KeyName, &wszDisplayName, &wszDescription, &wszBtnText, &dwFlags); + if (FAILED_UNEXPECTEDLY(hr)) + return false; + + // No files to clean will return S_FALSE; + if (hr != S_OK) + return false; + } + else + { + // Observed behavior: + // When Initialize is called, wszDescription is actually pointing to data + // wszDescription.AllocateBytes(0x400u); + hr = Handler->Initialize(hSubKey, pcwszVolume, &wszDisplayName, &wszDescription, &dwFlags); + if (FAILED_UNEXPECTEDLY(hr)) + return false; + + // No files to clean will return S_FALSE; + if (hr != S_OK) + return false; + + CComPtr spBag; + WCHAR GuidStr[50] = {}; + nChars = _countof(GuidStr); + if (hSubKey.QueryStringValue(L"PropertyBag", GuidStr, &nChars) == ERROR_SUCCESS) + { + GUID guid = {}; + if (!FAILED_UNEXPECTEDLY(CLSIDFromString(GuidStr, &guid))) + { + FAILED_UNEXPECTEDLY( + CoCreateInstance(guid, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IPropertyBag, &spBag))); + } + } + ReadProperty(L"Display", spBag, wszDisplayName); + ReadProperty(L"Description", spBag, wszDescription); + + if (dwFlags & EVCF_HASSETTINGS) + { + ReadProperty(L"AdvancedButtonText", spBag, wszBtnText); + } + } + + if ((dwFlags & EVCF_ENABLEBYDEFAULT) && !(StateFlags & HANDLER_STATE_SELECTED)) + { + StateFlags |= HANDLER_STATE_SELECTED; + } + + // For convenience + if (!wszDisplayName) + SHStrDupW(KeyName, &wszDisplayName); + + return true; +} + +void +CCleanupHandler::ReadProperty(LPCWSTR Name, IPropertyBag *pBag, CComHeapPtr &storage) +{ + if (storage) + return; + + if (pBag) + { + CComVariant tmp; + tmp.vt = VT_BSTR; + HRESULT hr = pBag->Read(Name, &tmp, NULL); + if (!FAILED_UNEXPECTEDLY(hr) && tmp.vt == VT_BSTR) + { + SHStrDupW(tmp.bstrVal, &storage); + } + } + + if (!storage) + { + WCHAR TmpStr[0x200] = {}; + DWORD dwSize = _countof(TmpStr); + + if (hSubKey.QueryStringValue(Name, TmpStr, &dwSize) == ERROR_SUCCESS) + { + WCHAR ResolvedStr[0x200] = {}; + SHLoadIndirectString(TmpStr, ResolvedStr, _countof(ResolvedStr), NULL); + SHStrDupW(ResolvedStr, &storage); + } + } +} + +BOOL +CCleanupHandler::HasSettings() const +{ + return !!(dwFlags & EVCF_HASSETTINGS); +} + +BOOL +CCleanupHandler::DontShowIfZero() const +{ + return !!(dwFlags & EVCF_DONTSHOWIFZERO); +} + diff --git a/base/applications/cleanmgr/cleanmgr/CCleanupHandler.hpp b/base/applications/cleanmgr/cleanmgr/CCleanupHandler.hpp new file mode 100644 index 0000000000000..3b829a82c2107 --- /dev/null +++ b/base/applications/cleanmgr/cleanmgr/CCleanupHandler.hpp @@ -0,0 +1,48 @@ +/* + * PROJECT: ReactOS Disk Cleanup + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: CCleanupHandler definition + * COPYRIGHT: Copyright 2023-2025 Mark Jansen + */ + +#define HANDLER_STATE_SELECTED 1 + + +struct CCleanupHandler +{ + CCleanupHandler(CRegKey &subKey, const CStringW &keyName, const GUID &guid); + ~CCleanupHandler(); + + void Deactivate(); + + bool + Initialize(LPCWSTR pcwszVolume); + + void + ReadProperty(LPCWSTR Name, IPropertyBag *pBag, CComHeapPtr &storage); + + BOOL + HasSettings() const; + + BOOL + DontShowIfZero() const; + + CRegKey hSubKey; + CStringW KeyName; + GUID Guid; + + CComHeapPtr wszDisplayName; + CComHeapPtr wszDescription; + CComHeapPtr wszBtnText; + + CStringW IconPath; + DWORD dwFlags; + DWORD Priority; + DWORD StateFlags; + + CComPtr Handler; + DWORDLONG SpaceUsed; + bool ShowHandler; + HICON hIcon; +}; + diff --git a/base/applications/cleanmgr/cleanmgr/CCleanupHandlerList.cpp b/base/applications/cleanmgr/cleanmgr/CCleanupHandlerList.cpp new file mode 100644 index 0000000000000..73af85d797449 --- /dev/null +++ b/base/applications/cleanmgr/cleanmgr/CCleanupHandlerList.cpp @@ -0,0 +1,163 @@ +/* + * PROJECT: ReactOS Disk Cleanup + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: CCleanupHandlerList implementation + * COPYRIGHT: Copyright 2023-2025 Mark Jansen + */ + +#include "cleanmgr.h" + +void CCleanupHandlerList::LoadHandlers(WCHAR Drive) +{ + m_DriveStr.Format(L"%c:", Drive); + + CRegKey VolumeCaches; + if (VolumeCaches.Open(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\VolumeCaches", KEY_READ) != ERROR_SUCCESS) + return; + + LONG ItemIndex = 0; + WCHAR szKeyName[MAX_PATH]; + + WCHAR wszVolume[] = { Drive, L':', L'\\', UNICODE_NULL }; + + while (TRUE) + { + DWORD dwSize = _countof(szKeyName); + if (VolumeCaches.EnumKey(ItemIndex++, szKeyName, &dwSize) != ERROR_SUCCESS) + { + break; + } + + + CRegKey hSubKey; + if (hSubKey.Open(VolumeCaches, szKeyName, KEY_READ) == ERROR_SUCCESS) + { + WCHAR GuidStr[50] = {}; + dwSize = _countof(GuidStr); + if (hSubKey.QueryStringValue(NULL, GuidStr, &dwSize) != ERROR_SUCCESS) + { + continue; + } + + GUID guid = {}; + if (FAILED_UNEXPECTEDLY(CLSIDFromString(GuidStr, &guid))) + continue; + + CCleanupHandler* handler = new CCleanupHandler(hSubKey, szKeyName, guid); + + if (!handler->Initialize(wszVolume)) + { + delete handler; + continue; + } + + m_Handlers.AddTail(handler); + } + } + + // Sort handlers + BOOL fChanged = m_Handlers.GetCount() > 0; + while (fChanged) + { + fChanged = FALSE; + + for (size_t n = 0; n < m_Handlers.GetCount() - 1; n++) + { + POSITION leftPos = m_Handlers.FindIndex(n); + POSITION rightPos = m_Handlers.FindIndex(n+1); + CCleanupHandler* left = m_Handlers.GetAt(leftPos); + CCleanupHandler* right = m_Handlers.GetAt(rightPos); + + if (right->Priority < left->Priority) + { + m_Handlers.SwapElements(leftPos, rightPos); + fChanged = TRUE; + } + else if (right->Priority == left->Priority) + { + CStringW leftStr(left->wszDisplayName); + if (leftStr.Compare(right->wszDisplayName) > 0) + { + m_Handlers.SwapElements(leftPos, rightPos); + fChanged = TRUE; + } + } + } + } +} + + +DWORDLONG +CCleanupHandlerList::ScanDrive(IEmptyVolumeCacheCallBack *picb) +{ + CProgressDlg progress; + CString Caption; + Caption.Format(IDS_CALCULATING, m_DriveStr.GetString()); + CStringW Title(MAKEINTRESOURCE(IDS_DISK_CLEANUP)); + progress.Start((DWORD)m_Handlers.GetCount(), Title, Caption); + int ItemIndex = 0; + DWORDLONG TotalSpaceUsed = 0; + ForEach( + [&](CCleanupHandler *current) + { + Caption.Format(IDS_SCANNING, current->wszDisplayName.m_pData); + progress.Step(++ItemIndex, Caption); + + HRESULT hr = current->Handler->GetSpaceUsed(¤t->SpaceUsed, picb); + + if (FAILED_UNEXPECTEDLY(hr)) + { + current->ShowHandler = false; + current->StateFlags &= ~HANDLER_STATE_SELECTED; + return; + } + + if (current->SpaceUsed == 0 && current->DontShowIfZero()) + { + current->ShowHandler = false; + current->StateFlags &= ~HANDLER_STATE_SELECTED; + } + TotalSpaceUsed += current->SpaceUsed; + }); + progress.Stop(); + + return TotalSpaceUsed; +} + +void +CCleanupHandlerList::ExecuteCleanup(IEmptyVolumeCacheCallBack *picb) +{ + CProgressDlg progress; + CString Caption; + Caption.Format(IDS_CLEANING_CAPTION, m_DriveStr.GetString()); + + DWORD TotalSelected = 0; + ForEach( + [&](CCleanupHandler *current) + { + if (current->StateFlags & HANDLER_STATE_SELECTED) + TotalSelected++; + }); + + CStringW Title(MAKEINTRESOURCE(IDS_DISK_CLEANUP)); + progress.Start(TotalSelected, Title, Caption); + int ItemIndex = 0; + ForEach( + [&](CCleanupHandler *current) + { + if (!(current->StateFlags & HANDLER_STATE_SELECTED)) + return; + + Caption.Format(IDS_CLEANING, current->wszDisplayName.m_pData); + progress.Step(++ItemIndex, Caption); + + // If there is nothing to clean, we might get STG_E_NOMOREFILES + if (current->SpaceUsed > 0) + { + HRESULT hr = current->Handler->Purge(-1, picb); + if (FAILED_UNEXPECTEDLY(hr)) + return; + } + }); + progress.Stop(); +} diff --git a/base/applications/cleanmgr/cleanmgr/CCleanupHandlerList.hpp b/base/applications/cleanmgr/cleanmgr/CCleanupHandlerList.hpp new file mode 100644 index 0000000000000..55e38502c83b1 --- /dev/null +++ b/base/applications/cleanmgr/cleanmgr/CCleanupHandlerList.hpp @@ -0,0 +1,31 @@ +/* + * PROJECT: ReactOS Disk Cleanup + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: CCleanupHandlerList definition + * COPYRIGHT: Copyright 2023-2025 Mark Jansen + */ + + +class CCleanupHandlerList +{ +private: + CAtlList m_Handlers; + CStringW m_DriveStr; + +public: + + void LoadHandlers(WCHAR Drive); + DWORDLONG ScanDrive(IEmptyVolumeCacheCallBack* picb); + void ExecuteCleanup(IEmptyVolumeCacheCallBack *picb); + + template + void ForEach(Fn callback) + { + for (POSITION it = m_Handlers.GetHeadPosition(); it; m_Handlers.GetNext(it)) + { + CCleanupHandler *current = m_Handlers.GetAt(it); + + callback(current); + } + } +}; diff --git a/base/applications/cleanmgr/cleanmgr/CEmptyVolumeCacheCallBack.hpp b/base/applications/cleanmgr/cleanmgr/CEmptyVolumeCacheCallBack.hpp new file mode 100644 index 0000000000000..8811d522dcc1d --- /dev/null +++ b/base/applications/cleanmgr/cleanmgr/CEmptyVolumeCacheCallBack.hpp @@ -0,0 +1,54 @@ +/* + * PROJECT: ReactOS Disk Cleanup + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: CEmptyVolumeCacheCallBack definition / implementation + * COPYRIGHT: Copyright 2023-2025 Mark Jansen + */ + + +// We don't really use this, but some windows handlers crash without it +struct CEmptyVolumeCacheCallBack + : public IEmptyVolumeCacheCallBack +{ + + STDMETHOD_(ULONG, AddRef)() throw() + { + return 2; + } + STDMETHOD_(ULONG, Release)() throw() + { + return 1; + } + STDMETHOD(QueryInterface)( + REFIID riid, + _COM_Outptr_ void** ppvObject) throw() + { + if (riid == IID_IUnknown || riid == IID_IEmptyVolumeCacheCallBack) + { + *ppvObject = (IUnknown*)this; + return S_OK; + } + *ppvObject = NULL; + return E_NOINTERFACE; + } + + + STDMETHODIMP ScanProgress( + _In_ DWORDLONG dwlSpaceUsed, + _In_ DWORD dwFlags, + _In_ LPCWSTR pcwszStatus) override + { + DPRINT("dwlSpaceUsed: %lld, dwFlags: %x\n", dwlSpaceUsed, dwFlags); + return S_OK; + } + + STDMETHODIMP PurgeProgress( + _In_ DWORDLONG dwlSpaceFreed, + _In_ DWORDLONG dwlSpaceToFree, + _In_ DWORD dwFlags, + _In_ LPCWSTR pcwszStatus) override + { + DPRINT("dwlSpaceFreed: %lld, dwlSpaceToFree: %lld, dwFlags: %x\n", dwlSpaceFreed, dwlSpaceToFree, dwFlags); + return S_OK; + } +}; diff --git a/base/applications/cleanmgr/cleanmgr/CMakeLists.txt b/base/applications/cleanmgr/cleanmgr/CMakeLists.txt new file mode 100644 index 0000000000000..f692c04796c7e --- /dev/null +++ b/base/applications/cleanmgr/cleanmgr/CMakeLists.txt @@ -0,0 +1,19 @@ + +add_executable(cleanmgr + cleanmgr.cpp + cleanmgr.h + cleanmgr.rc + resource.h + CEmptyVolumeCacheCallBack.hpp + CProgressDlg.hpp + CSelectDriveDlg.cpp + CCleanupHandler.cpp + CCleanupHandler.hpp + CCleanupHandlerList.cpp + CCleanupHandlerList.hpp +) +set_module_type(cleanmgr win32gui UNICODE) +target_link_libraries(cleanmgr uuid cpprt atl_classes) +add_importlibs(cleanmgr shlwapi oleaut32 ole32 shell32 comctl32 user32 advapi32 msvcrt kernel32 ntdll) +add_dependencies(cleanmgr psdk) +add_cd_file(TARGET cleanmgr DESTINATION reactos/system32 FOR all) diff --git a/base/applications/cleanmgr/cleanmgr/CProgressDlg.hpp b/base/applications/cleanmgr/cleanmgr/CProgressDlg.hpp new file mode 100644 index 0000000000000..66604de01de9f --- /dev/null +++ b/base/applications/cleanmgr/cleanmgr/CProgressDlg.hpp @@ -0,0 +1,50 @@ +/* + * PROJECT: ReactOS Disk Cleanup + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: Progress dialog implementation + * COPYRIGHT: Copyright 2023-2025 Mark Jansen + */ + +#pragma once + +class CProgressDlg +{ + CComPtr m_spProgress; + DWORD m_dwTotal = 0; +public: + + ~CProgressDlg() + { + Stop(); + } + + + void Start(DWORD dwTotalSteps, LPCWSTR Title, LPCWSTR Text) + { + HRESULT hr = CoCreateInstance(CLSID_ProgressDialog, NULL, CLSCTX_INPROC, IID_PPV_ARG(IProgressDialog, &m_spProgress)); + if (FAILED_UNEXPECTEDLY(hr)) + return; + + m_dwTotal = dwTotalSteps; + + m_spProgress->SetTitle(Title); + m_spProgress->SetLine(2, Text, TRUE, NULL); + m_spProgress->StartProgressDialog(NULL, NULL, PROGDLG_NOMINIMIZE, NULL); + m_spProgress->SetProgress(0, m_dwTotal); + } + + void Step(DWORD dwProgress, LPCWSTR Text) + { + m_spProgress->SetProgress(dwProgress, m_dwTotal); + m_spProgress->SetLine(1, Text, TRUE, NULL); + } + + void Stop() + { + if (m_spProgress) + { + m_spProgress->StopProgressDialog(); + m_spProgress.Release(); + } + } +}; diff --git a/base/applications/cleanmgr/cleanmgr/CSelectDriveDlg.cpp b/base/applications/cleanmgr/cleanmgr/CSelectDriveDlg.cpp new file mode 100644 index 0000000000000..c78927f909c23 --- /dev/null +++ b/base/applications/cleanmgr/cleanmgr/CSelectDriveDlg.cpp @@ -0,0 +1,80 @@ +/* + * PROJECT: ReactOS Disk Cleanup + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: Drive selection dialog + * COPYRIGHT: Copyright 2023-2025 Mark Jansen + */ + +#include "cleanmgr.h" + +class CSelectDriveDlg : public CDialogImpl +{ +public: + enum { IDD = IDD_SELECTDRIVE }; + + BEGIN_MSG_MAP(CSelectDriveDlg) + MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) + COMMAND_ID_HANDLER(IDOK, OnEndDialog) + COMMAND_ID_HANDLER(IDCANCEL, OnEndDialog) + END_MSG_MAP() + + CSelectDriveDlg() + :m_SelectedDrive(UNICODE_NULL) + { + } + + LRESULT OnInitDialog(UINT, WPARAM, LPARAM, BOOL&) + { + // Try to find an existing instance of this dialog + WCHAR buf[300]; + GetWindowTextW(buf, _countof(buf)); + for (HWND hNext = NULL, hFind; (hFind = ::FindWindowExW(NULL, hNext, NULL, buf)) != NULL; hNext = hFind) + { + if (hFind != *this && ::IsWindowVisible(hFind)) + { + ::SetForegroundWindow(hFind); + EndDialog(IDCANCEL); + return FALSE; + } + } + + CWindow cbo = GetDlgItem(IDC_DRIVES); + WCHAR VolumeNameBuffer[MAX_PATH + 1]; + CStringW Tmp; + for (WCHAR Drive = 'A'; Drive <= 'Z'; ++Drive) + { + WCHAR RootPathName[] = { Drive,':','\\',0 }; + UINT Type = GetDriveTypeW(RootPathName); + if (Type == DRIVE_FIXED) + { + GetVolumeInformationW(RootPathName, VolumeNameBuffer, _countof(VolumeNameBuffer), 0, 0, 0, 0, 0); + Tmp.Format(L"%s (%.2s)", VolumeNameBuffer, RootPathName); + + int index = (int)cbo.SendMessage(CB_ADDSTRING, NULL, (LPARAM)Tmp.GetString()); + cbo.SendMessage(CB_SETITEMDATA, index, Drive); + } + } + cbo.SendMessage(CB_SETCURSEL, 0); + return 1; + } + LRESULT OnEndDialog(WORD, WORD wID, HWND, BOOL&) + { + CWindow cbo = GetDlgItem(IDC_DRIVES); + m_SelectedDrive = (WCHAR)cbo.SendMessage(CB_GETITEMDATA, cbo.SendMessage(CB_GETCURSEL)); + EndDialog(wID); + return 0; + } + + WCHAR m_SelectedDrive; +}; + + +void +SelectDrive(WCHAR &Drive) +{ + CSelectDriveDlg dlgSelectDrive; + if (dlgSelectDrive.DoModal() == IDOK) + { + Drive = dlgSelectDrive.m_SelectedDrive; + } +} diff --git a/base/applications/cleanmgr/cleanmgr/cleanmgr.cpp b/base/applications/cleanmgr/cleanmgr/cleanmgr.cpp new file mode 100644 index 0000000000000..99918381b7411 --- /dev/null +++ b/base/applications/cleanmgr/cleanmgr/cleanmgr.cpp @@ -0,0 +1,328 @@ +/* + * PROJECT: ReactOS Disk Cleanup + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: Disk cleanup entrypoint + * COPYRIGHT: Copyright 2023-2025 Mark Jansen + */ + +#include "cleanmgr.h" + +// for listview with extend style LVS_EX_CHECKBOXES, State image 1 is the unchecked box, and state image 2 is the +// checked box. see this: https://docs.microsoft.com/en-us/windows/win32/controls/extended-list-view-styles +#define STATEIMAGETOINDEX(x) (((x)&LVIS_STATEIMAGEMASK) >> 12) +#define STATEIMAGE_UNCHECKED 1 +#define STATEIMAGE_CHECKED 2 + + +struct CCleanMgrProperties : + public CPropertyPageImpl +{ + enum { IDD = IDD_PROPERTIES_MAIN }; + CWindow m_HandlerListControl; + WCHAR m_Drive; + DWORDLONG m_TotalSpaceUsed; + CCleanupHandlerList* m_HandlerList; + bool m_IgnoreChanges = true; + + + CCleanMgrProperties(WCHAR Drive, DWORDLONG TotalSpaceUsed, CCleanupHandlerList *handlerList) + : m_Drive(Drive) + , m_TotalSpaceUsed(TotalSpaceUsed) + , m_HandlerList(handlerList) + { + } + + int OnApply() + { + CStringW Title(MAKEINTRESOURCE(IDS_DISK_CLEANUP)); + CStringW Text(MAKEINTRESOURCE(IDS_CONFIRM_DELETE)); + + if (MessageBoxW(Text, Title, MB_YESNO | MB_ICONQUESTION) != IDYES) + return PSNRET_INVALID; + + return PSNRET_NOERROR; + } + + LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) + { + HICON hIcon = (HICON)::LoadImageW( + _AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCEW(IDI_CLEANMGR), IMAGE_ICON, 0, 0, + LR_DEFAULTSIZE | LR_SHARED); + SendDlgItemMessage(IDC_DISKICON, STM_SETICON, (WPARAM)hIcon); + + m_HandlerListControl = GetDlgItem(IDC_HANDLERLIST); + RECT rc; + m_HandlerListControl.GetClientRect(&rc); + rc.right -= GetSystemMetrics(SM_CXVSCROLL); + + LV_COLUMN column = {}; + column.mask = LVCF_FMT | LVCF_WIDTH; + column.fmt = LVCFMT_LEFT; + column.cx = rc.right * 80 / 100; + ListView_InsertColumn(m_HandlerListControl, 0, &column); + column.fmt = LVCFMT_RIGHT; + column.cx = rc.right * 20 / 100; + + ListView_InsertColumn(m_HandlerListControl, 1, &column); + HIMAGELIST hImagelist = ImageList_Create(16, 16, ILC_MASK | ILC_COLOR32, 1, 1); + ListView_SetImageList(m_HandlerListControl, hImagelist, LVSIL_SMALL); + + ListView_SetExtendedListViewStyleEx(m_HandlerListControl, LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT, LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT); + + m_HandlerList->ForEach( + [&](CCleanupHandler *current) + { + if (!current->ShowHandler) + return; + + LV_ITEM item = {}; + item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; + item.lParam = (LPARAM)current; + item.pszText = (LPWSTR)current->wszDisplayName; + item.iItem = ListView_GetItemCount(m_HandlerListControl); + item.iImage = ImageList_AddIcon(hImagelist, current->hIcon); + item.iItem = ListView_InsertItem(m_HandlerListControl, &item); + ListView_SetCheckState( + m_HandlerListControl, item.iItem, !!(current->StateFlags & HANDLER_STATE_SELECTED)); + + item.mask = LVIF_TEXT; + WCHAR ByteSize[100] = {}; + StrFormatByteSizeW(current->SpaceUsed, ByteSize, _countof(ByteSize)); + ListView_SetItemText(m_HandlerListControl, item.iItem, 1, ByteSize); + }); + + // Now we should start responding to changes + m_IgnoreChanges = false; + + // Select the first item + ListView_SetItemState(m_HandlerListControl, 0, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); + + UpdateSpaceUsed(); + return TRUE; + } + + CCleanupHandler* GetHandler(int Index) + { + LVITEMW item = {}; + item.iItem = Index; + if (item.iItem >= 0) + { + item.mask = LVIF_PARAM; + ListView_GetItem(m_HandlerListControl, &item); + return (CCleanupHandler*)item.lParam; + } + return nullptr; + } + + + LRESULT OnDetails(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) + { + CCleanupHandler *handler = GetHandler(ListView_GetNextItem(m_HandlerListControl, -1, LVIS_FOCUSED)); + if (handler) + { + handler->Handler->ShowProperties(m_hWnd); + } + return 0L; + } + + LRESULT OnHandlerItemchanged(int idCtrl, LPNMHDR pnmh, BOOL& bHandled) + { + if (idCtrl == IDC_HANDLERLIST) + { + // We are still initializing, don't respond to changes just yet! + if (m_IgnoreChanges) + return 0L; + + LPNMLISTVIEW pnic = (LPNMLISTVIEW)pnmh; + + // We only care about state changes + if (!(pnic->uChanged & LVIF_STATE)) + return 0L; + + + INT ItemIndex = pnic->iItem; + if (ItemIndex == -1 || ItemIndex >= ListView_GetItemCount(pnic->hdr.hwndFrom)) + { + return 0L; + } + + bool GotSelected = (pnic->uNewState & LVIS_SELECTED) && !(pnic->uOldState & LVIS_SELECTED); + if (GotSelected) + { + CWindow DetailsButton = GetDlgItem(IDC_DETAILS); + CCleanupHandler* handler = (CCleanupHandler*)pnic->lParam; + + SetDlgItemText(IDC_DESCRIPTION, handler->wszDescription ? handler->wszDescription : L""); + if (handler->HasSettings()) + { + DetailsButton.ShowWindow(SW_SHOW); + DetailsButton.SetWindowText(handler->wszBtnText); + } + else + { + DetailsButton.ShowWindow(SW_HIDE); + } + } + + int iOldState = STATEIMAGETOINDEX(pnic->uOldState); + int iNewState = STATEIMAGETOINDEX(pnic->uNewState); + + if ((iOldState ^ iNewState) == (STATEIMAGE_UNCHECKED ^ STATEIMAGE_CHECKED)) + { + CCleanupHandler* handler = (CCleanupHandler*)pnic->lParam; + if (iNewState == STATEIMAGE_CHECKED) + handler->StateFlags |= HANDLER_STATE_SELECTED; + else + handler->StateFlags &= ~HANDLER_STATE_SELECTED; + UpdateSpaceUsed(); + } + } + return 0L; + } + + void UpdateSpaceUsed() + { + CStringW tmp; + WCHAR ByteSize[100]; + StrFormatByteSizeW(m_TotalSpaceUsed, ByteSize, _countof(ByteSize)); + + tmp.Format(IDS_TOTAL_CLEANABLE_CAPTION, ByteSize, m_Drive); + SetDlgItemText(IDC_TOTAL_CLEANABLE, tmp); + + DWORDLONG SelectedGained = 0; + + m_HandlerList->ForEach( + [&](CCleanupHandler *current) + { + if (current->StateFlags & HANDLER_STATE_SELECTED) + { + SelectedGained += current->SpaceUsed; + } + }); + + StrFormatByteSizeW(SelectedGained, ByteSize, _countof(ByteSize)); + SetDlgItemText(IDC_SELECTED_GAINED, ByteSize); + } + + BEGIN_MSG_MAP(CCleanMgrProperties) + MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) + COMMAND_ID_HANDLER(IDC_DETAILS, OnDetails) + NOTIFY_HANDLER(IDC_HANDLERLIST, LVN_ITEMCHANGED, OnHandlerItemchanged) + CHAIN_MSG_MAP(CPropertyPageImpl) // Allow the default handler to call 'OnApply' etc + END_MSG_MAP() +}; + + + +class CCleanMgrModule : public ATL::CAtlExeModuleT< CCleanMgrModule > +{ +public: + WCHAR m_Drive = UNICODE_NULL; + + bool ParseCommandLine( + _In_z_ LPCTSTR lpCmdLine, + _Out_ HRESULT* pnRetCode) throw() + { + int argc = 0; + CLocalPtr argv(CommandLineToArgvW(lpCmdLine, &argc)); + + for (int n = 1; n < argc; ++n) + { + if ((argv[n][0] == '/' || argv[n][0] == '-') && towlower(argv[n][1]) == 'd') + { + if (iswalpha(argv[n][2])) + { + m_Drive = towupper(argv[n][2]); + continue; + } + if ((n + 1) < argc) + { + m_Drive = towupper(argv[n + 1][0]); + ++n; + continue; + } + } + } + *pnRetCode = S_OK; + return true; + } + + static inline UINT GetWindowProcessId(_In_ HWND hWnd) + { + DWORD pid; + return GetWindowThreadProcessId(hWnd, &pid) ? pid : 0; + } + + static BOOL CALLBACK EnumSingleInstanceCallback(_In_ HWND hWnd, _In_ LPARAM lParam) + { + if (::IsWindowVisible(hWnd) && (LPARAM)GetWindowProcessId(hWnd) == lParam) + { + ::SetForegroundWindow(hWnd); + return FALSE; + } + return TRUE; + } + + HRESULT Run(_In_ int nShowCmd) throw() + { + if (m_Drive == UNICODE_NULL) + { + SelectDrive(m_Drive); + } + + if (m_Drive == UNICODE_NULL) + return E_FAIL; + + CStringW Title; + Title.Format(IDS_PROPERTIES_MAIN_TITLE, m_Drive); + + HWND hWndInstance = ::CreateWindowExW(WS_EX_TOOLWINDOW, WC_STATIC, Title, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL); + for (HWND hNext = NULL, hFind; (hFind = ::FindWindowExW(NULL, hNext, WC_STATIC, Title)) != NULL; hNext = hFind) + { + if (hFind != hWndInstance) + { + ::EnumWindows(EnumSingleInstanceCallback, GetWindowProcessId(hFind)); + return S_FALSE; + } + } + + CCleanupHandlerList Handlers; + CEmptyVolumeCacheCallBack CacheCallBack; + + Handlers.LoadHandlers(m_Drive); + DWORDLONG TotalSpaceUsed = Handlers.ScanDrive(&CacheCallBack); + + CCleanMgrProperties cleanMgr(m_Drive, TotalSpaceUsed, &Handlers); + HPROPSHEETPAGE hpsp[1] = { cleanMgr.Create() }; + + PROPSHEETHEADERW psh = { }; + psh.dwSize = sizeof(psh); + psh.dwFlags = PSH_NOAPPLYNOW | PSH_USEICONID | PSH_NOCONTEXTHELP; + psh.hInstance = _AtlBaseModule.GetResourceInstance(); + psh.pszIcon = MAKEINTRESOURCEW(IDI_CLEANMGR); + psh.pszCaption = Title; + psh.nPages = _countof(hpsp); + psh.phpage = hpsp; + + if (PropertySheetW(&psh) >= 1) + { + ::DestroyWindow(hWndInstance); // Allow new "cleanmgr /D" without waiting for these handlers + Handlers.ExecuteCleanup(&CacheCallBack); + } + else + { + ::DestroyWindow(hWndInstance); + } + return S_OK; + } +}; + +CCleanMgrModule _AtlModule; + + + +extern "C" int WINAPI wWinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, + LPWSTR /*lpCmdLine*/, int nShowCmd) +{ + return _AtlModule.WinMain(nShowCmd); +} diff --git a/base/applications/cleanmgr/cleanmgr/cleanmgr.h b/base/applications/cleanmgr/cleanmgr/cleanmgr.h new file mode 100644 index 0000000000000..742a585ba252d --- /dev/null +++ b/base/applications/cleanmgr/cleanmgr/cleanmgr.h @@ -0,0 +1,66 @@ +/* + * PROJECT: ReactOS Disk Cleanup + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: Main header file + * COPYRIGHT: Copyright 2023-2025 Mark Jansen + */ + +#pragma once + +#ifndef STRICT +#define STRICT +#endif + +#define _ATL_APARTMENT_THREADED +#define _ATL_NO_AUTOMATIC_NAMESPACE +#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit +#define ATL_NO_ASSERT_ON_DESTROY_NONEXISTENT_WINDOW + +#define _FORCENAMELESSUNION + +#include +#include +#include +#include +#include + + +#include +#include +#include +#include +#include +#include + + +using namespace ATL; + +#define NDEBUG +#include +#include +#include + + +template class CLocalPtr + : public CHeapPtr +{ +public: + CLocalPtr() throw() + { + } + + explicit CLocalPtr(_In_ T* pData) throw() : + CHeapPtr(pData) + { + } +}; + +#include "resource.h" +#include "CProgressDlg.hpp" +#include "CCleanupHandler.hpp" +#include "CCleanupHandlerList.hpp" +#include "CEmptyVolumeCacheCallBack.hpp" + +// CSelectDriveDlg.cpp +void +SelectDrive(WCHAR &Drive); diff --git a/base/applications/cleanmgr/cleanmgr/cleanmgr.rc b/base/applications/cleanmgr/cleanmgr/cleanmgr.rc new file mode 100644 index 0000000000000..07edd4d0d8a0a --- /dev/null +++ b/base/applications/cleanmgr/cleanmgr/cleanmgr.rc @@ -0,0 +1,64 @@ +/* + * PROJECT: ReactOS Disk Cleanup + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: Resources + * COPYRIGHT: Copyright 2023-2025 Mark Jansen + */ + +#include +#include +#include +#include "resource.h" + +#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Disk Cleanup" +#define REACTOS_STR_INTERNAL_NAME "cleanmgr" +#define REACTOS_STR_ORIGINAL_FILENAME "cleanmgr.exe" +#include + +#include + +IDI_CLEANMGR ICON "resources/cleanmgr.ico" + +#pragma code_page(65001) + +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +STRINGTABLE +BEGIN + IDS_PROPERTIES_MAIN_TITLE "Disk Cleanup for (%c:)" + IDS_TOTAL_CLEANABLE_CAPTION "You can use Disk Cleanup to free up to %s of disk space on (%c:)." + IDS_DISK_CLEANUP "Disk Cleanup" + IDS_CONFIRM_DELETE "Are you sure you want to delete these files permanently?" + IDS_CALCULATING "Disk Cleanup is calculating how much space can be gained on (%s)." + IDS_SCANNING "Scanning: %s" + IDS_CLEANING_CAPTION "Disk Cleanup is cleaning up files on %s." + IDS_CLEANING "Cleaning: %s" +END + +IDD_PROPERTIES_MAIN DIALOGEX 0, 0, 235, 215 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_CHILD | WS_DISABLED | WS_CAPTION +CAPTION "Disk Cleanup" +FONT 8, "MS Shell Dlg", 400, 0, 0x0 +BEGIN + CONTROL "",IDC_DISKICON,"Static",SS_ICON,6,6,20,20 + LTEXT "You can use Disk Cleanup to free up to 0.0MB of disk space on drive C.",IDC_TOTAL_CLEANABLE,36,6,192,18 + LTEXT "Files to delete:",IDC_STATIC,6,30,222,8 + CONTROL "",IDC_HANDLERLIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOCOLUMNHEADER | WS_BORDER | WS_TABSTOP,6,42,222,66 + LTEXT "Total amount of disk space gained:",IDC_STATIC,6,114,144,8 + RTEXT "",IDC_SELECTED_GAINED,156,114,73,8 + GROUPBOX "Description",IDC_STATIC,6,126,222,84 + LTEXT "",IDC_DESCRIPTION,12,138,210,54 + PUSHBUTTON "Details...",IDC_DETAILS,150,192,74,14 +END + +IDD_SELECTDRIVE DIALOGEX 0, 0, 177, 74 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Disk Cleanup - Select Drive" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,30,48,50,14 + PUSHBUTTON "E&xit",IDCANCEL,96,48,50,14 + LTEXT "Select the drive to clean up.",IDC_STATIC,12,6,150,8 + COMBOBOX IDC_DRIVES,12,24,150,90,CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP +END + diff --git a/base/applications/cleanmgr/cleanmgr/resource.h b/base/applications/cleanmgr/cleanmgr/resource.h new file mode 100644 index 0000000000000..5edb10b5b22e6 --- /dev/null +++ b/base/applications/cleanmgr/cleanmgr/resource.h @@ -0,0 +1,30 @@ +/* + * PROJECT: ReactOS Disk Cleanup + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: Resource definitions + * COPYRIGHT: Copyright 2023-2025 Mark Jansen + */ + +#define IDC_STATIC -1 + +#define IDI_CLEANMGR 100 + +#define IDD_PROPERTIES_MAIN 200 +#define IDC_DISKICON 201 +#define IDC_TOTAL_CLEANABLE 202 +#define IDC_HANDLERLIST 203 +#define IDC_SELECTED_GAINED 204 +#define IDC_DESCRIPTION 205 +#define IDC_DETAILS 206 + +#define IDD_SELECTDRIVE 220 +#define IDC_DRIVES 221 + +#define IDS_PROPERTIES_MAIN_TITLE 1000 +#define IDS_TOTAL_CLEANABLE_CAPTION 1001 +#define IDS_DISK_CLEANUP 1002 +#define IDS_CONFIRM_DELETE 1003 +#define IDS_CALCULATING 1004 +#define IDS_SCANNING 1005 +#define IDS_CLEANING_CAPTION 1006 +#define IDS_CLEANING 1007 diff --git a/base/applications/cleanmgr/cleanmgr/resources/cleanmgr.ico b/base/applications/cleanmgr/cleanmgr/resources/cleanmgr.ico new file mode 100644 index 0000000000000..577b6294d14c0 Binary files /dev/null and b/base/applications/cleanmgr/cleanmgr/resources/cleanmgr.ico differ diff --git a/base/applications/clipbrd/winutils.c b/base/applications/clipbrd/winutils.c index d97b4fb710ea6..520506bd114d1 100644 --- a/base/applications/clipbrd/winutils.c +++ b/base/applications/clipbrd/winutils.c @@ -257,9 +257,9 @@ void SetDIBitsToDeviceFromClipboard(UINT uFormat, PAINTSTRUCT ps, SCROLLSTATE st * * FIXME: investigate!! * ANSWER: this is a Windows bug; part of the answer is there: - * https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/ac7ab3b5-8609-4478-b86a-976dab44c271/bug-clipboard-format-conversions-cfdib-cfdibv5-cfdib + * https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/ac7ab3b5-8609-4478-b86a-976dab44c271/bug-clipboard-format-conversions-cfdib-cfdibv5-cfdib (DEAD_LINK) * May be related: - * https://blog.talosintelligence.com/2015/10/dangerous-clipboard.html + * https://blog.talosintelligence.com/dangerous-clipboard/ */ #if 0 if ((lpInfoHeader->biSize == sizeof(BITMAPINFOHEADER)) && diff --git a/base/applications/cmdutils/at/at.rc b/base/applications/cmdutils/at/at.rc index 364297c3f66a0..da29a956e2441 100644 --- a/base/applications/cmdutils/at/at.rc +++ b/base/applications/cmdutils/at/at.rc @@ -9,6 +9,7 @@ /* UTF-8 */ #pragma code_page(65001) + #ifdef LANGUAGE_DE_DE #include "lang/de-DE.rc" #endif diff --git a/base/applications/cmdutils/certutil/CMakeLists.txt b/base/applications/cmdutils/certutil/CMakeLists.txt index bb9cd3a2fde1b..bad17571c46bb 100644 --- a/base/applications/cmdutils/certutil/CMakeLists.txt +++ b/base/applications/cmdutils/certutil/CMakeLists.txt @@ -2,12 +2,14 @@ include_directories(${REACTOS_SOURCE_DIR}/sdk/lib/conutils) list(APPEND SOURCE - certutil.c + asn.cpp + certutil.cpp + hashfile.cpp precomp.h) add_executable(certutil ${SOURCE}) set_module_type(certutil win32cui UNICODE) target_link_libraries(certutil conutils ${PSEH_LIB}) -add_importlibs(certutil advapi32 msvcrt kernel32) +add_importlibs(certutil crypt32 advapi32 msvcrt kernel32) add_pch(certutil precomp.h SOURCE) add_cd_file(TARGET certutil DESTINATION reactos/system32 FOR all) diff --git a/base/applications/cmdutils/certutil/asn.cpp b/base/applications/cmdutils/certutil/asn.cpp new file mode 100644 index 0000000000000..030691d4f0172 --- /dev/null +++ b/base/applications/cmdutils/certutil/asn.cpp @@ -0,0 +1,508 @@ +/* + * PROJECT: ReactOS certutil + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: CertUtil asn implementation + * COPYRIGHT: Copyright 2020 Mark Jansen (mark.jansen@reactos.org) + * + * NOTES: + * To keep it simple, Tag and Class are combined in one identifier + * See for more details: + * https://en.wikipedia.org/wiki/X.690#BER_encoding + * https://www.strozhevsky.com/free_docs/asn1_by_simple_words.pdf + * http://mikk.net/~chris/asn1.pdf + * + * And for a test suite: + * https://github.com/YuryStrozhevsky/asn1-test-suite + */ + +#include "precomp.h" +#include +#include +#include + + +#define ASN_TAG_IS_CONSTRUCTED 0x20 + + +#define ASN_TAG_BITSTRING 0x03 +#define ASN_TAG_OCTET_STRING 0x04 +#define ASN_TAG_OBJECT_ID 0x06 + +#define ASN_TAG_SEQUENCE_RAW 0x10 +#define ASN_TAG_SET_RAW 0x11 + +#define ASN_TAG_SEQUENCE 0x30 +#define ASN_TAG_SET 0x31 + + +#define ASN_TAG_CONTEXT_SPECIFIC 0x80 +#define ASN_TAG_CONTEXT_SPECIFIC_N(n) (ASN_TAG_CONTEXT_SPECIFIC | (n)) + +#define ASN_TAG_OPTIONAL 0xA0 +#define ASN_TAG_OPTIONAL_N(n) (ASN_TAG_OPTIONAL | (n)) + +/* NOTE: These names are not the names listed in f.e. the wikipedia pages, + they are made to look like MS's names for this */ +LPCWSTR TagToName(DWORD dwTag) +{ + switch (dwTag) + { + case 0x0: return L"EOC"; + case 0x1: return L"BOOL"; + case 0x2: return L"INTEGER"; + case ASN_TAG_BITSTRING: return L"BIT_STRING"; + case ASN_TAG_OCTET_STRING: return L"OCTET_STRING"; + case 0x5: return L"NULL"; + case ASN_TAG_OBJECT_ID: return L"OBJECT_ID"; + case 0x7: return L"Object Descriptor"; + case 0x8: return L"EXTERNAL"; + case 0x9: return L"REAL"; + case 0xA: return L"ENUMERATED"; + case 0xB: return L"EMBEDDED PDV"; + case 0xC: return L"UTF8String"; + case 0xD: return L"RELATIVE-OID"; + case 0xE: return L"TIME"; + case 0xF: return L"Reserved"; + case ASN_TAG_SEQUENCE_RAW: __debugbreak(); return L"SEQUENCE_RAW"; + case ASN_TAG_SET_RAW: __debugbreak(); return L"SET_RAW"; + case 0x12: return L"NumericString"; + case 0x13: return L"PRINTABLE_STRING"; + case 0x14: return L"T61String"; + case 0x15: return L"VideotexString"; + case 0x16: return L"IA5String"; + case 0x17: return L"UTC_TIME"; + case 0x18: return L"GeneralizedTime"; + case 0x19: return L"GraphicString"; + case 0x1A: return L"VisibleString"; + case 0x1B: return L"GeneralString"; + case 0x1C: return L"UniversalString"; + case 0x1D: return L"CHARACTER STRING"; + case 0x1E: return L"BMPString"; + case 0x1F: return L"DATE"; + case 0x20: return L"CONSTRUCTED"; + + case ASN_TAG_SEQUENCE: return L"SEQUENCE"; + case ASN_TAG_SET: return L"SET"; + + + case ASN_TAG_CONTEXT_SPECIFIC_N(0): return L"CONTEXT_SPECIFIC[0]"; + case ASN_TAG_CONTEXT_SPECIFIC_N(1): return L"CONTEXT_SPECIFIC[1]"; + case ASN_TAG_CONTEXT_SPECIFIC_N(2): return L"CONTEXT_SPECIFIC[2]"; + case ASN_TAG_CONTEXT_SPECIFIC_N(3): return L"CONTEXT_SPECIFIC[3]"; + case ASN_TAG_CONTEXT_SPECIFIC_N(4): return L"CONTEXT_SPECIFIC[4]"; + case ASN_TAG_CONTEXT_SPECIFIC_N(5): return L"CONTEXT_SPECIFIC[5]"; + case ASN_TAG_CONTEXT_SPECIFIC_N(6): return L"CONTEXT_SPECIFIC[6]"; + case ASN_TAG_CONTEXT_SPECIFIC_N(7): return L"CONTEXT_SPECIFIC[7]"; + case ASN_TAG_CONTEXT_SPECIFIC_N(8): return L"CONTEXT_SPECIFIC[8]"; + case ASN_TAG_CONTEXT_SPECIFIC_N(9): return L"CONTEXT_SPECIFIC[9]"; + /* Experiments show that Windows' certutil only goes up to 9 */ + + + case ASN_TAG_OPTIONAL_N(0): return L"OPTIONAL[0]"; + case ASN_TAG_OPTIONAL_N(1): return L"OPTIONAL[1]"; + case ASN_TAG_OPTIONAL_N(2): return L"OPTIONAL[2]"; + case ASN_TAG_OPTIONAL_N(3): return L"OPTIONAL[3]"; + case ASN_TAG_OPTIONAL_N(4): return L"OPTIONAL[4]"; + case ASN_TAG_OPTIONAL_N(5): return L"OPTIONAL[5]"; + case ASN_TAG_OPTIONAL_N(6): return L"OPTIONAL[6]"; + case ASN_TAG_OPTIONAL_N(7): return L"OPTIONAL[7]"; + case ASN_TAG_OPTIONAL_N(8): return L"OPTIONAL[8]"; + case ASN_TAG_OPTIONAL_N(9): return L"OPTIONAL[9]"; + /* Experiments show that Windows' certutil only goes up to 9 */ + + default: + return L"???"; + } +} + +BOOL Move(DWORD dwLen, PBYTE& pData, DWORD& dwSize) +{ + if (dwSize < dwLen) + return FALSE; + + pData += dwLen; + dwSize -= dwLen; + + return TRUE; +} + +BOOL ParseTag(PBYTE& pData, DWORD& dwSize, DWORD& dwTagAndClass) +{ + if (dwSize == 0) + return FALSE; + + /* Is this a long form? */ + if ((pData[0] & 0x1f) != 0x1f) + { + /* No, so extract the tag and class (in one identifier) */ + dwTagAndClass = pData[0]; + return Move(1, pData, dwSize); + } + + DWORD dwClass = (pData[0] & 0xE0) >> 5; + dwTagAndClass = 0; + DWORD n; + for (n = 1; n < dwSize; ++n) + { + dwTagAndClass <<= 7; + dwTagAndClass |= (pData[n] & 0x7f); + + if (!(pData[n] & 0x80)) + { + break; + } + } + + Move(n, pData, dwSize); + + /* Any number bigger than this, we shift data out! */ + if (n > 4) + return FALSE; + + /* Just drop this in the hightest bits*/ + dwTagAndClass |= (dwClass << (32-3)); + + return TRUE; +} + +BOOL ParseLength(PBYTE& pData, DWORD& dwSize, DWORD& dwLength) +{ + if (dwSize == 0) + return FALSE; + + if (!(pData[0] & 0x80)) + { + dwLength = pData[0]; + return Move(1, pData, dwSize); + } + + DWORD dwBytes = pData[0] & 0x7f; + if (dwBytes == 0 || dwBytes > 8 || dwBytes + 1 > dwSize) + { + return FALSE; + } + + dwLength = 0; + for (DWORD n = 0; n < dwBytes; ++n) + { + dwLength <<= 8; + dwLength += pData[1 + n]; + } + + return Move(dwBytes + 1, pData, dwSize); +} + + +DWORD HexDump(PBYTE pRoot, PBYTE pData, DWORD dwSize, PWSTR wszPrefix) +{ + while (TRUE) + { + SIZE_T Address = pData - pRoot; + ConPrintf(StdOut, L"%04x: ", Address); + ConPuts(StdOut, wszPrefix); + + for (DWORD n = 0; n < min(dwSize, 0x10); ++n) + { + ConPrintf(StdOut, L"%02x ", pData[n]); + } + + if (dwSize <= 0x10) + break; + + Move(0x10, pData, dwSize); + ConPuts(StdOut, L"\n"); + } + + return 3 * dwSize; +} + +void PrintTag(PBYTE pRoot, PBYTE pHeader, DWORD dwTag, DWORD dwTagLength, PBYTE pData, PWSTR wszPrefix) +{ + DWORD dwRemainder = HexDump(pRoot, pHeader, pData - pHeader, wszPrefix); + + LPCWSTR wszTag = TagToName(dwTag); + DWORD dwPadding = dwRemainder + wcslen(wszPrefix); + while (dwPadding > 50) + dwPadding -= 50; + ConPrintf(StdOut, L"%*s; %s (%x Bytes)\n", 50 - dwPadding, L"", wszTag, dwTagLength); +} + +struct OID_NAMES +{ + CHAR* Oid; + LPCWSTR Names[20]; + DWORD NumberOfNames; +}; + +BOOL WINAPI CryptOIDEnumCallback(_In_ PCCRYPT_OID_INFO pInfo, _Inout_opt_ void *pvArg) +{ + OID_NAMES* Names = (OID_NAMES*)pvArg; + + if (pInfo && pInfo->pszOID && !_stricmp(pInfo->pszOID, Names->Oid)) + { + if (Names->NumberOfNames < RTL_NUMBER_OF(Names->Names)) + { + for (DWORD n = 0; n < Names->NumberOfNames; ++n) + { + // We already have this.. + if (!_wcsicmp(Names->Names[n], pInfo->pwszName)) + return TRUE; + } + + Names->Names[Names->NumberOfNames++] = pInfo->pwszName; + } + } + + return TRUE; +} + +void PrintOID(PBYTE pRoot, PBYTE pHeader, PBYTE pData, DWORD dwSize, PWSTR wszPrefix) +{ + /* CryptFindOIDInfo expects the OID to be in ANSI.. */ + CHAR szOID[250]; + CHAR* ptr = szOID; + size_t cchRemaining = RTL_NUMBER_OF(szOID); + + /* CryptFindOIDInfo just returns the first, we want multiple */ + OID_NAMES Names = {0}; + + if (dwSize == 0) + return; + + DWORD dwValue = 0, count = 0; + for (DWORD n = 0; n < dwSize; ++n) + { + dwValue <<= 7; + dwValue |= pData[n] & 0x7f; + + if (pData[n] & 0x80) + { + if (++count >= 4) + break; + continue; + } + count = 0; + + /* First & second octet have a special encoding */ + if (ptr == szOID) + { + DWORD id1 = dwValue / 40; + DWORD id2 = dwValue % 40; + + /* The first one can only be 0, 1 or 2, so handle special case: tc24.ber */ + if (id1 > 2) + { + id2 += (id1 - 2) * 40; + id1 = 2; + } + StringCchPrintfExA(ptr, cchRemaining, &ptr, &cchRemaining, 0, "%d.%d", id1, id2); + } + else + { + StringCchPrintfExA(ptr, cchRemaining, &ptr, &cchRemaining, 0, ".%d", dwValue); + } + + dwValue = 0; + } + + if (dwValue || count) + { + /* We cannot format this, so just add abort */ + return; + } + + SIZE_T Address = pData - pRoot; + /* Pad with spaces instead of printing the address again */ + DWORD addrDigits = (DWORD)log10((double)Address) + 1; + ConPrintf(StdOut, L"%*s ", max(addrDigits, 4), L""); + ConPrintf(StdOut, L"%s; %S", wszPrefix, szOID); + + Names.Oid = szOID; + + /* The order does not match a naive call with '0'... */ + CryptEnumOIDInfo(0, 0, &Names, CryptOIDEnumCallback); + + for (DWORD n = 0; n < Names.NumberOfNames; ++n) + { + if (n == 0) + ConPrintf(StdOut, L" %s", Names.Names[n]); + else if (n == 1) + ConPrintf(StdOut, L" (%s", Names.Names[n]); + else + ConPrintf(StdOut, L" / %s", Names.Names[n]); + } + + ConPrintf(StdOut, L"%s\n", Names.NumberOfNames > 1 ? L")" : L""); +} + + +BOOL ParseAsn(PBYTE pRoot, PBYTE pData, DWORD dwSize, PWSTR wszPrefix, BOOL fPrint) +{ + while (dwSize) + { + PBYTE pHeader = pData; + DWORD dwTagAndClass; + + if (!ParseTag(pData, dwSize, dwTagAndClass)) + { + if (fPrint) + ConPrintf(StdOut, L"CertUtil: -asn command failed to parse tag near 0x%x\n", pHeader - pRoot); + return FALSE; + } + + DWORD dwTagLength; + if (!ParseLength(pData, dwSize, dwTagLength)) + { + if (fPrint) + ConPrintf(StdOut, L"CertUtil: -asn command failed to parse tag length near 0x%x\n", pHeader - pRoot); + return FALSE; + } + + if (dwTagLength > dwSize) + { + if (fPrint) + ConPrintf(StdOut, L"CertUtil: -asn command malformed tag length near 0x%x\n", pHeader - pRoot); + return FALSE; + } + + + if (fPrint) + PrintTag(pRoot, pHeader, dwTagAndClass, dwTagLength, pData, wszPrefix); + + size_t len = wcslen(wszPrefix); + StringCchCatW(wszPrefix, MAX_PATH, dwTagLength != dwSize ? L"| " : L" "); + + if (dwTagAndClass & ASN_TAG_IS_CONSTRUCTED) + { + if (!ParseAsn(pRoot, pData, dwTagLength, wszPrefix, fPrint)) + { + return FALSE; + } + } + else + { + if (fPrint) + { + /* Special case for a bit string / octet string */ + if ((dwTagAndClass == ASN_TAG_BITSTRING || dwTagAndClass == ASN_TAG_OCTET_STRING) && dwTagLength) + { + if (dwTagAndClass == ASN_TAG_BITSTRING) + { + /* First, we print the 'unused bits' field of the bit string */ + HexDump(pRoot, pData, 1, wszPrefix); + ConPuts(StdOut, L"\n"); + + /* Move past it */ + Move(1, pData, dwSize); + dwTagLength--; + } + + /* Do we have any data left? */ + if (dwTagLength) + { + /* Try to parse this as ASN */ + if (ParseAsn(pRoot, pData, dwTagLength, wszPrefix, FALSE)) + { + /* We succeeded, this _could_ be ASN, so display it as if it is */ + if (!ParseAsn(pRoot, pData, dwTagLength, wszPrefix, TRUE)) + { + /* Uhhh, did someone edit the data? */ + ConPrintf(StdOut, L"CertUtil: -asn command unexpected failure parsing tag near 0x%x\n", pData - pRoot); + return FALSE; + } + + /* Move past what we just parsed */ + Move(dwTagLength, pData, dwSize); + /* Lie about this so that we don't also print a hexdump */ + dwTagLength = 0; + } + } + } + + /* Is there any data (left) to print? */ + if (dwTagLength) + { + HexDump(pRoot, pData, dwTagLength, wszPrefix); + ConPuts(StdOut, L"\n"); + + StringCchCatW(wszPrefix, MAX_PATH, L" "); + + /* Do we have additional formatters? */ + switch (dwTagAndClass) + { + case ASN_TAG_OBJECT_ID: + PrintOID(pRoot, pHeader, pData, dwTagLength, wszPrefix); + break; + default: + break; + } + } + } + } + + wszPrefix[len] = '\0'; + + if (!Move(dwTagLength, pData, dwSize)) + { + /* This should not be possible, it was checked before! */ + return FALSE; + } + } + + return TRUE; +} + + +BOOL asn_dump(LPCWSTR Filename) +{ + HANDLE hFile = CreateFileW(Filename, GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL); + + if (hFile == INVALID_HANDLE_VALUE) + { + ConPrintf(StdOut, L"CertUtil: -asn command failed to open: %d\n", GetLastError()); + return FALSE; + } + + DWORD dwSize = GetFileSize(hFile, NULL); + if (dwSize == INVALID_FILE_SIZE) + { + ConPrintf(StdOut, L"CertUtil: -asn command failed to get file size: %d\n", GetLastError()); + CloseHandle(hFile); + return FALSE; + } + + if (dwSize == 0) + { + ConPrintf(StdOut, L"CertUtil: -asn command got an empty file\n"); + CloseHandle(hFile); + return FALSE; + } + + PBYTE pData = (PBYTE)LocalAlloc(0, dwSize); + if (!pData) + { + ConPrintf(StdOut, L"CertUtil: -asn command failed to allocate: %d\n", GetLastError()); + CloseHandle(hFile); + return FALSE; + } + + DWORD cbRead; + BOOL fRead = ReadFile(hFile, pData, dwSize, &cbRead, NULL); + DWORD dwErr = GetLastError(); + CloseHandle(hFile); + + if (!fRead || cbRead != dwSize) + { + ConPrintf(StdOut, L"CertUtil: -asn command failed to read: %d\n", dwErr); + LocalFree(pData); + return FALSE; + } + + WCHAR Buffer[MAX_PATH] = {0}; + BOOL fSucceeded = ParseAsn(pData, pData, dwSize, Buffer, TRUE); + + LocalFree(pData); + return fSucceeded; +} + diff --git a/base/applications/cmdutils/certutil/certutil.cpp b/base/applications/cmdutils/certutil/certutil.cpp new file mode 100644 index 0000000000000..85d118961c3c2 --- /dev/null +++ b/base/applications/cmdutils/certutil/certutil.cpp @@ -0,0 +1,107 @@ +/* + * PROJECT: ReactOS certutil + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: CertUtil commandline handling + * COPYRIGHT: Copyright 2020 Mark Jansen (mark.jansen@reactos.org) + * + * Note: Only -hashfile and -asn are implemented for now, the rest is not present! + */ + +#include "precomp.h" +#include +#include + +typedef struct +{ + LPCWSTR Name; + BOOL (*pfn)(LPCWSTR Filename); +} Verb; + + +Verb verbs[] = { + { L"hashfile", hash_file }, + { L"asn", asn_dump }, +}; + +static void print_usage() +{ + ConPuts(StdOut, L"Verbs:\n"); + ConPuts(StdOut, L" -hashfile -- Display cryptographic hash over a file\n"); + ConPuts(StdOut, L" -asn -- Display ASN.1 encoding of a file\n"); + ConPuts(StdOut, L"\n"); + ConPuts(StdOut, L"CertUtil -? -- Display a list of all verbs\n"); + ConPuts(StdOut, L"CertUtil -hashfile -? -- Display help text for the 'hashfile' verb\n"); +} + + +Verb* MatchVerb(LPCWSTR arg) +{ + if (arg[0] != '-' && arg[0] != '/') + return NULL; + + for (size_t n = 0; n < RTL_NUMBER_OF(verbs); ++n) + { + if (!_wcsicmp(verbs[n].Name, arg + 1)) + { + return verbs + n; + } + } + + return NULL; +} + +int wmain(int argc, WCHAR *argv[]) +{ + int n; + + /* Initialize the Console Standard Streams */ + ConInitStdStreams(); + + if (argc == 1) /* i.e. no commandline arguments given */ + { + print_usage(); + return EXIT_SUCCESS; + } + + for (n = 1; n < argc; ++n) + { + if (!_wcsicmp(argv[n], L"-?")) + { + print_usage(); + return EXIT_SUCCESS; + } + + Verb* verb = MatchVerb(argv[n]); + + if (verb) + { + if (argc != 3) + { + ConPrintf(StdOut, L"CertUtil: -%s expected 1 argument, got %d\n", verb->Name, argc - 2); + return EXIT_FAILURE; + } + + if (!_wcsicmp(argv[n+1], L"-?")) + { + print_usage(); + return EXIT_SUCCESS; + } + + if (!verb->pfn(argv[n+1])) + { + /* The verb prints the failure */ + return EXIT_FAILURE; + } + + ConPrintf(StdOut, L"CertUtil: -%s command completed successfully\n", verb->Name); + return EXIT_SUCCESS; + } + else + { + ConPrintf(StdOut, L"CertUtil: Unknown verb: %s\n", argv[n]); + return EXIT_FAILURE; + } + } + + return EXIT_SUCCESS; +} diff --git a/base/applications/cmdutils/certutil/certutil.c b/base/applications/cmdutils/certutil/hashfile.cpp similarity index 53% rename from base/applications/cmdutils/certutil/certutil.c rename to base/applications/cmdutils/certutil/hashfile.cpp index 7d6d2d6898730..214ff54bae7c7 100644 --- a/base/applications/cmdutils/certutil/certutil.c +++ b/base/applications/cmdutils/certutil/hashfile.cpp @@ -1,10 +1,8 @@ /* * PROJECT: ReactOS certutil - * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) - * PURPOSE: CertUtil stub + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: CertUtil hashfile implementation * COPYRIGHT: Copyright 2020 Mark Jansen (mark.jansen@reactos.org) - * - * Note: Only -hashfile is implemented for now, the rest is not present! */ #include "precomp.h" @@ -12,7 +10,7 @@ #include -static BOOL hash_file(LPCWSTR Filename) +BOOL hash_file(LPCWSTR Filename) { HCRYPTPROV hProv; BOOL bSuccess = FALSE; @@ -87,69 +85,3 @@ static BOOL hash_file(LPCWSTR Filename) return bSuccess; } - -static void print_usage() -{ - ConPuts(StdOut, L"Verbs:\n"); - ConPuts(StdOut, L" -hashfile -- Display cryptographic hash over a file\n"); - ConPuts(StdOut, L"\n"); - ConPuts(StdOut, L"CertUtil -? -- Display a list of all verbs\n"); - ConPuts(StdOut, L"CertUtil -hashfile -? -- Display help text for the 'hashfile' verb\n"); -} - -int wmain(int argc, WCHAR *argv[]) -{ - int n; - - /* Initialize the Console Standard Streams */ - ConInitStdStreams(); - - if (argc == 1) /* i.e. no commandline arguments given */ - { - print_usage(); - return EXIT_SUCCESS; - } - - for (n = 1; n < argc; ++n) - { - if (!_wcsicmp(argv[n], L"-?")) - { - print_usage(); - return EXIT_SUCCESS; - } - else if (!_wcsicmp(argv[n], L"-hashfile")) - { - if (argc == 3) - { - if (!_wcsicmp(argv[n+1], L"-?")) - { - print_usage(); - return EXIT_SUCCESS; - } - else - { - if (!hash_file(argv[n+1])) - { - /* hash_file prints the failure itself */ - return EXIT_FAILURE; - } - - ConPuts(StdOut, L"CertUtil: -hashfile command completed successfully\n"); - return EXIT_SUCCESS; - } - } - else - { - ConPrintf(StdOut, L"CertUtil: -hashfile expected 1 argument, got %d\n", argc - 2); - return EXIT_FAILURE; - } - } - else - { - ConPrintf(StdOut, L"CertUtil: Unknown verb: %s\n", argv[n]); - return EXIT_FAILURE; - } - } - - return EXIT_SUCCESS; -} diff --git a/base/applications/cmdutils/certutil/precomp.h b/base/applications/cmdutils/certutil/precomp.h index 0c8e115bf5e70..9818fbee66815 100644 --- a/base/applications/cmdutils/certutil/precomp.h +++ b/base/applications/cmdutils/certutil/precomp.h @@ -7,10 +7,14 @@ #include #include -#include -#include +#include #include +BOOL hash_file(LPCWSTR Filename); +BOOL asn_dump(LPCWSTR Filename); + + + #endif /* __CERTUTIL_PRECOMP_H */ diff --git a/base/applications/cmdutils/cscript/CMakeLists.txt b/base/applications/cmdutils/cscript/CMakeLists.txt index 2d86060efe3e4..df53084c1e381 100644 --- a/base/applications/cmdutils/cscript/CMakeLists.txt +++ b/base/applications/cmdutils/cscript/CMakeLists.txt @@ -1,5 +1,5 @@ -add_definitions(-DCSCRIPT_BUILD -D__WINESRC__) +add_definitions(-DCSCRIPT_BUILD) set(wscript_folder ${REACTOS_SOURCE_DIR}/base/applications/cmdutils/wscript) include_directories(${wscript_folder}) @@ -20,3 +20,4 @@ add_importlibs(cscript shell32 oleaut32 ole32 advapi32 user32 msvcrt kernel32 nt add_dependencies(cscript stdole2 cscript_idlheader) add_pch(cscript ${wscript_folder}/precomp.h SOURCE) add_cd_file(TARGET cscript DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(cscript) # CORE-5743: No ARRAY_SIZE macro diff --git a/base/applications/cmdutils/fc/fc.rc b/base/applications/cmdutils/fc/fc.rc index d9199235b45d6..77890c55ad8d9 100644 --- a/base/applications/cmdutils/fc/fc.rc +++ b/base/applications/cmdutils/fc/fc.rc @@ -6,7 +6,9 @@ #define REACTOS_STR_ORIGINAL_FILENAME "fc.exe" #include -#pragma code_page(65001) /* UTF-8 */ +/* UTF-8 */ +#pragma code_page(65001) + #ifdef LANGUAGE_BG_BG #include "lang/bg-BG.rc" #endif diff --git a/base/applications/cmdutils/fc/lang/fr-FR.rc b/base/applications/cmdutils/fc/lang/fr-FR.rc index 70a021fae7f7c..b4a4d1cc7d99d 100644 --- a/base/applications/cmdutils/fc/lang/fr-FR.rc +++ b/base/applications/cmdutils/fc/lang/fr-FR.rc @@ -2,40 +2,40 @@ LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL STRINGTABLE BEGIN - IDS_USAGE "Compares two files or sets of files and displays the differences between\n\ -them.\n\ + IDS_USAGE "Compare deux fichiers ou un ensemble de fichiers et affiche les différences\n\ +entre eux.\n\ \n\ FC [/A] [/C] [/L] [/LBn] [/N] [/OFF[LINE]] [/T] [/U] [/W] [/nnnn]\n\ [drive1:][path1]filename1 [drive2:][path2]filename2\n\ FC /B [drive1:][path1]filename1 [drive2:][path2]filename2\n\ \n\ - /A Displays only first and last lines for each set of differences.\n\ - /B Performs a binary comparison.\n\ - /C Disregards the case of letters.\n\ - /L Compares files as ASCII text.\n\ - /LBn Sets the maximum consecutive mismatches to the specified\n\ - number of lines (default: 100).\n\ - /N Displays the line numbers on an ASCII comparison.\n\ - /OFF[LINE] Doesn't skip files with offline attribute set.\n\ - /T Doesn't expand tabs to spaces (default: expand).\n\ - /U Compare files as UNICODE text files.\n\ - /W Compresses white space (tabs and spaces) for comparison.\n\ - /nnnn Specifies the number of consecutive lines that must match\n\ - after a mismatch (default: 2).\n\ + /A Affiche uniquement la première et la dernière ligne pour chaque ensemble de différences.\n\ + /B Effectue une comparaison binaire.\n\ + /C Ne tient pas compte de la casse des lettres.\n\ + /L Compare les fichiers sous forme de texte ASCII.\n\ + /LBn Définit le nombre maximal de différences consécutives\n\ + au nombre de lignes spécifié (par défaut : 100).\n\ + /N Affiche les numéros de ligne sur une comparaison ASCII.\n\ + /OFF[LINE] N'ignore pas les fichiers ayant l'attribut hors-ligne.\n\ + /T Ne transforme pas les tabulations en espaces (par défaut : transformer).\n\ + /U Compare les fichiers en tant que fichiers texte UNICODE.\n\ + /W Compresse les espaces blancs (tabulations et espaces) pour la comparaison.\n\ + /nnnn Spécifie le nombre de lignes consécutives qui doivent correspondre\n\ + après une différence (par défaut : 2).\n\ [drive1:][path1]filename1\n\ - Specifies the first file or set of files to compare.\n\ + Spécifie le premier fichier ou ensemble de fichiers à comparer.\n\ [drive2:][path2]filename2\n\ - Specifies the second file or set of files to compare.\n" - IDS_NO_DIFFERENCE "FC: no differences encountered\n" - IDS_LONGER_THAN "FC: %ls longer than %ls\n" - IDS_COMPARING "Comparing files %ls and %ls\n" - IDS_OUT_OF_MEMORY "FC: Out of memory\n" - IDS_CANNOT_READ "FC: cannot read from %ls\n" - IDS_INVALID_SWITCH "FC: Invalid Switch\n" - IDS_CANNOT_OPEN "FC: cannot open %ls - No such file or folder\n" - IDS_NEEDS_FILES "FC: Insufficient number of file specifications\n" - IDS_CANT_USE_WILDCARD "Wildcard ('*' and '?') are not supported yet\n" - IDS_DIFFERENT "FC: File %ls and %ls are different\n" - IDS_TOO_LARGE "FC: File %ls too large\n" - IDS_RESYNC_FAILED "Resync failed. Files are too different.\n" + Spécifie le second fichier ou ensemble de fichiers à comparer.\n" + IDS_NO_DIFFERENCE "FC: Aucune différence constatée\n" + IDS_LONGER_THAN "FC: %ls plus grand que %ls\n" + IDS_COMPARING "Compare les fichiers %ls et %ls\n" + IDS_OUT_OF_MEMORY "FC: Dépassement de mémoire\n" + IDS_CANNOT_READ "FC: Ne peut pas lire depuis %ls\n" + IDS_INVALID_SWITCH "FC: Option invalide\n" + IDS_CANNOT_OPEN "FC: Ne peut pas ouvrir %ls - Fichier ou répertoire inexistant\n" + IDS_NEEDS_FILES "FC: Nombre insuffisant de fichiers spécifiés\n" + IDS_CANT_USE_WILDCARD "Les caractères joker ('*' et '?') ne sont pas encore supportés\n" + IDS_DIFFERENT "FC: Les fichiers %ls et %ls sont différents\n" + IDS_TOO_LARGE "FC: Fichier %ls trop grand\n" + IDS_RESYNC_FAILED "La resynchronisation a échoué. Les fichiers sont trop différents.\n" END diff --git a/base/applications/cmdutils/find/find.rc b/base/applications/cmdutils/find/find.rc index 71239582b07f7..b023b942a4918 100644 --- a/base/applications/cmdutils/find/find.rc +++ b/base/applications/cmdutils/find/find.rc @@ -9,6 +9,7 @@ /* UTF-8 */ #pragma code_page(65001) + #ifdef LANGUAGE_BG_BG #include "lang/bg-BG.rc" #endif diff --git a/base/applications/cmdutils/help/help.rc b/base/applications/cmdutils/help/help.rc index e0b22790180ed..bde222b397f5f 100644 --- a/base/applications/cmdutils/help/help.rc +++ b/base/applications/cmdutils/help/help.rc @@ -12,6 +12,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL /* UTF-8 */ #pragma code_page(65001) + #ifdef LANGUAGE_DE_DE #include "lang/de-DE.rc" #endif diff --git a/base/applications/cmdutils/more/more.c b/base/applications/cmdutils/more/more.c index d10b001ebd8ab..c05c21f313bb5 100644 --- a/base/applications/cmdutils/more/more.c +++ b/base/applications/cmdutils/more/more.c @@ -487,7 +487,7 @@ PagePrompt(PCON_PAGER Pager, DWORD Done, DWORD Total) * See base/applications/cmdutils/clip/clip.c!IsDataUnicode() * and base/applications/notepad/text.c!ReadText() for more details. * Also some good code example can be found at: - * https://github.com/AutoIt/text-encoding-detect + * https://github.com/AutoItConsulting/text-encoding-detect */ typedef enum { diff --git a/base/applications/cmdutils/reg/CMakeLists.txt b/base/applications/cmdutils/reg/CMakeLists.txt index 707e6080d92a6..d8cce2676d255 100644 --- a/base/applications/cmdutils/reg/CMakeLists.txt +++ b/base/applications/cmdutils/reg/CMakeLists.txt @@ -2,9 +2,9 @@ remove_definitions(-D_WIN32_WINNT=0x502) add_definitions(-D_WIN32_WINNT=0x600) -add_definitions(-D__WINESRC__) add_executable(reg add.c copy.c delete.c export.c import.c query.c reg.c reg.rc) set_module_type(reg win32cui UNICODE) target_link_libraries(reg wine oldnames) add_importlibs(reg advapi32 advapi32_vista user32 msvcrt kernel32 ntdll) add_cd_file(TARGET reg DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(reg) # CORE-5743: No ARRAY_SIZE macro diff --git a/base/applications/cmdutils/taskkill/CMakeLists.txt b/base/applications/cmdutils/taskkill/CMakeLists.txt index 5006fb3b6f1ad..742717b6a72bf 100644 --- a/base/applications/cmdutils/taskkill/CMakeLists.txt +++ b/base/applications/cmdutils/taskkill/CMakeLists.txt @@ -1,7 +1,7 @@ -add_definitions(-D__WINESRC__) add_executable(taskkill taskkill.c taskkill.rc) target_link_libraries(taskkill wine) set_module_type(taskkill win32cui UNICODE) -add_importlibs(taskkill psapi user32 msvcrt kernel32 ntdll) +add_importlibs(taskkill user32 msvcrt kernel32 ntdll) add_cd_file(TARGET taskkill DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(taskkill) # CORE-5743: No ARRAY_SIZE macro diff --git a/base/applications/cmdutils/taskkill/lang/de-DE.rc b/base/applications/cmdutils/taskkill/lang/de-DE.rc index 54a408fcc8a3e..241fd2bdb3449 100644 --- a/base/applications/cmdutils/taskkill/lang/de-DE.rc +++ b/base/applications/cmdutils/taskkill/lang/de-DE.rc @@ -2,7 +2,7 @@ LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL STRINGTABLE { - STRING_USAGE, "Usage: taskkill [/?] [/f] [/im Prozess Name | /pid Prozess ID]\n" + STRING_USAGE, "Usage: taskkill [/?] [/f] [/im Prozess Name | /pid Prozess ID] [/t]\n" STRING_INVALID_OPTION, "Fehler: Unbekannte oder ungülige Kommandozeilenoption angegeben.\n" STRING_INVALID_PARAM, "Fehler: Ungültiger Kommandozeilenparameter angegeben.\n" STRING_MISSING_OPTION, "Fehler: Eine der Optionen /im oder /pid muss angegeben werden.\n" @@ -16,6 +16,10 @@ STRINGTABLE STRING_ENUM_FAILED, "Fehler: Prozessliste kann nicht aufgebaut werden.\n" STRING_TERMINATE_FAILED, "Fehler: Prozess ""%1"" kann nicht beendet werden.\n" STRING_SELF_TERMINATION, "Fehler: Der Prozess kann sich nicht selbst beenden.\n" + // STRING_CLOSE_CHILD, "Sent termination signal to process with PID %1!u!, child of PID %2!u!.\n" + STRING_CLOSE_CHILD, "Close message sent to top-level windows of process with PID %1!u!, child of PID %2!u!.\n" + STRING_TERM_CHILD, "The process with PID %1!u! (child process of PID %2!u!) has been terminated.\n" + STRING_TERM_CHILD_FAILED, "Error: Unable to terminate process with PID %1!u!, child of PID %2!u!.\n" STRING_PARAM_TOO_MUCH, "Error: Invalid syntax. '%1' option is not allowed more than '%2!d!' time(s).\n" STRING_INVALID_SYNTAX, "Error: Invalid syntax.\n" } diff --git a/base/applications/cmdutils/taskkill/lang/en-US.rc b/base/applications/cmdutils/taskkill/lang/en-US.rc index e34b34bad2599..d9f61d3f7adf4 100644 --- a/base/applications/cmdutils/taskkill/lang/en-US.rc +++ b/base/applications/cmdutils/taskkill/lang/en-US.rc @@ -2,7 +2,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT STRINGTABLE { - STRING_USAGE, "Usage: taskkill [/?] [/f] [/im ProcessName | /pid ProcessID]\n" + STRING_USAGE, "Usage: taskkill [/?] [/f] [/im ProcessName | /pid ProcessID] [/t]\n" STRING_INVALID_OPTION, "Error: Unknown or invalid command line option specified.\n" STRING_INVALID_PARAM, "Error: Invalid command line parameter specified.\n" STRING_MISSING_OPTION, "Error: One of options /im or /pid must be specified.\n" @@ -10,12 +10,16 @@ STRINGTABLE STRING_MUTUAL_EXCLUSIVE, "Error: Options /im and /pid are mutually exclusive.\n" STRING_CLOSE_PID_SEARCH, "Close message sent to top-level windows of process with PID %1!u!.\n" STRING_CLOSE_PROC_SRCH, "Close message sent to top-level windows of process ""%1"" with PID %2!u!.\n" - STRING_TERM_PID_SEARCH, "Process with PID %1!u! was forcibly terminated.\n" - STRING_TERM_PROC_SEARCH, "Process ""%1"" with PID %2!u! was forcibly terminated.\n" + STRING_TERM_PID_SEARCH, "The process with PID %1!u! has been terminated.\n" + STRING_TERM_PROC_SEARCH, "The process ""%1"" with PID %2!u! has been terminated.\n" STRING_SEARCH_FAILED, "Error: Could not find process ""%1"".\n" STRING_ENUM_FAILED, "Error: Unable to enumerate the process list.\n" STRING_TERMINATE_FAILED, "Error: Unable to terminate process ""%1"".\n" STRING_SELF_TERMINATION, "Error: Process self-termination is not permitted.\n" + // STRING_CLOSE_CHILD, "Sent termination signal to process with PID %1!u!, child of PID %2!u!.\n" + STRING_CLOSE_CHILD, "Close message sent to top-level windows of process with PID %1!u!, child of PID %2!u!.\n" + STRING_TERM_CHILD, "The process with PID %1!u! (child process of PID %2!u!) has been terminated.\n" + STRING_TERM_CHILD_FAILED, "Error: Unable to terminate process with PID %1!u!, child of PID %2!u!.\n" STRING_PARAM_TOO_MUCH, "Error: Invalid syntax. '%1' option is not allowed more than '%2!d!' time(s).\n" STRING_INVALID_SYNTAX, "Error: Invalid syntax.\n" } diff --git a/base/applications/cmdutils/taskkill/lang/it-IT.rc b/base/applications/cmdutils/taskkill/lang/it-IT.rc index 0cb456bd91eaa..e916349583119 100644 --- a/base/applications/cmdutils/taskkill/lang/it-IT.rc +++ b/base/applications/cmdutils/taskkill/lang/it-IT.rc @@ -9,7 +9,7 @@ LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL STRINGTABLE { - STRING_USAGE, "Uso: taskkill [/?] [/f] [/im NomeProcesso | /pid IDProcesso]\n" + STRING_USAGE, "Uso: taskkill [/?] [/f] [/im NomeProcesso | /pid IDProcesso] [/t]\n" STRING_INVALID_OPTION, "Errore: L'opzione specificata è invalida o sconosciuta.\n" STRING_INVALID_PARAM, "Errore: Il parametro di comando a riga è invalido.\n" STRING_MISSING_OPTION, "Errore: Specifica una delle opzioni /im oppure /pid.\n" @@ -23,6 +23,10 @@ STRINGTABLE STRING_ENUM_FAILED, "Errore: Impossibile enumerare la lista dei processi.\n" STRING_TERMINATE_FAILED, "Errore: Impossibile terminare il processo ""%1"".\n" STRING_SELF_TERMINATION, "Errore: L'auto-terminazione non è consentita.\n" + // STRING_CLOSE_CHILD, "Sent termination signal to process with PID %1!u!, child of PID %2!u!.\n" + STRING_CLOSE_CHILD, "Close message sent to top-level windows of process with PID %1!u!, child of PID %2!u!.\n" + STRING_TERM_CHILD, "The process with PID %1!u! (child process of PID %2!u!) has been terminated.\n" + STRING_TERM_CHILD_FAILED, "Error: Unable to terminate process with PID %1!u!, child of PID %2!u!.\n" STRING_PARAM_TOO_MUCH, "Error: Invalid syntax. '%1' option is not allowed more than '%2!d!' time(s).\n" STRING_INVALID_SYNTAX, "Error: Invalid syntax.\n" } diff --git a/base/applications/cmdutils/taskkill/lang/pl-PL.rc b/base/applications/cmdutils/taskkill/lang/pl-PL.rc index 5dd0f3ed463d4..e22644586a735 100644 --- a/base/applications/cmdutils/taskkill/lang/pl-PL.rc +++ b/base/applications/cmdutils/taskkill/lang/pl-PL.rc @@ -9,7 +9,7 @@ LANGUAGE LANG_POLISH, SUBLANG_DEFAULT STRINGTABLE { - STRING_USAGE, "Sposób użycia: taskkill [/?] [/f] [/im nazwa_procesu | /pid id_procesu]\n" + STRING_USAGE, "Sposób użycia: taskkill [/?] [/f] [/im nazwa_procesu | /pid id_procesu] [/t]\n" STRING_INVALID_OPTION, "Błąd: Określono nieznaną lub nieprawidłową opcję.\n" STRING_INVALID_PARAM, "Błąd: Nieprawidłowy parametr.\n" STRING_MISSING_OPTION, "Błąd: Nie określono opcji /im ani /pid.\n" @@ -23,6 +23,10 @@ STRINGTABLE STRING_ENUM_FAILED, "Błąd: Nie można wyliczyć listy procesów.\n" STRING_TERMINATE_FAILED, "Błąd: Nie można zakończyć procesu ""%1"".\n" STRING_SELF_TERMINATION, "Błąd: Proces nie może zakończyć sam siebie.\n" + // STRING_CLOSE_CHILD, "Sent termination signal to process with PID %1!u!, child of PID %2!u!.\n" + STRING_CLOSE_CHILD, "Close message sent to top-level windows of process with PID %1!u!, child of PID %2!u!.\n" + STRING_TERM_CHILD, "The process with PID %1!u! (child process of PID %2!u!) has been terminated.\n" + STRING_TERM_CHILD_FAILED, "Error: Unable to terminate process with PID %1!u!, child of PID %2!u!.\n" STRING_PARAM_TOO_MUCH, "Błąd: Nieprawidłowa składnia. Opcja '%1' nie jest dozwolona więcej niż '%2!d!' razy.\n" STRING_INVALID_SYNTAX, "Błąd: Nieprawidłowa składnia.\n" } diff --git a/base/applications/cmdutils/taskkill/lang/ro-RO.rc b/base/applications/cmdutils/taskkill/lang/ro-RO.rc index 476201fb5e15d..7376300a46732 100644 --- a/base/applications/cmdutils/taskkill/lang/ro-RO.rc +++ b/base/applications/cmdutils/taskkill/lang/ro-RO.rc @@ -10,7 +10,7 @@ LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL STRINGTABLE { - STRING_USAGE, "Utilizare: taskkill [/?] [/f] [/im NumeProces | /pid IdProces]\n" + STRING_USAGE, "Utilizare: taskkill [/?] [/f] [/im NumeProces | /pid IdProces] [/t]\n" STRING_INVALID_OPTION, "Eroare: Opțiune specificată nevalidă sau necunoscută.\n" STRING_INVALID_PARAM, "Eroare: Parametrul de comandă specificat este nevalid.\n" STRING_MISSING_OPTION, "Eroare: Trebuie specificată una dintre opțiunile /im sau /pid.\n" @@ -24,6 +24,10 @@ STRINGTABLE STRING_ENUM_FAILED, "Eroare: Nu se poate enumera lista de procese.\n" STRING_TERMINATE_FAILED, "Eroare: Procesul «%1» nu poate fi oprit.\n" STRING_SELF_TERMINATION, "Eroare: Auto-terminarea nu este permisă.\n" + // STRING_CLOSE_CHILD, "Sent termination signal to process with PID %1!u!, child of PID %2!u!.\n" + STRING_CLOSE_CHILD, "Close message sent to top-level windows of process with PID %1!u!, child of PID %2!u!.\n" + STRING_TERM_CHILD, "The process with PID %1!u! (child process of PID %2!u!) has been terminated.\n" + STRING_TERM_CHILD_FAILED, "Error: Unable to terminate process with PID %1!u!, child of PID %2!u!.\n" STRING_PARAM_TOO_MUCH, "Eroare: Sintaxă nevalidă. Opțiunea '%1' nu este permisă mai mult de '%2!d!' dată(dăți).\n" STRING_INVALID_SYNTAX, "Eroare: Sintaxă nevalidă.\n" } diff --git a/base/applications/cmdutils/taskkill/lang/ru-RU.rc b/base/applications/cmdutils/taskkill/lang/ru-RU.rc index 69ddc4bc1137b..34911a20b07ba 100644 --- a/base/applications/cmdutils/taskkill/lang/ru-RU.rc +++ b/base/applications/cmdutils/taskkill/lang/ru-RU.rc @@ -4,7 +4,7 @@ LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT STRINGTABLE { - STRING_USAGE, "Использование: TASKKILL [/F] [/IM <образ> | /PID <процесс>]\n" + STRING_USAGE, "Использование: TASKKILL [/F] [/IM <образ> | /PID <процесс>] [/t]\n" STRING_INVALID_OPTION, "Ошибка: Указаны неверные параметры командной строки.\n" STRING_INVALID_PARAM, "Ошибка: Указаны неверные параметры командной строки.\n" STRING_MISSING_OPTION, "Ошибка: Должен быть указан параметр /im или /pid.\n" @@ -18,6 +18,10 @@ STRINGTABLE STRING_ENUM_FAILED, "Ошибка: Не удается получить список процессов.\n" STRING_TERMINATE_FAILED, "Ошибка: Не удается завершить процесс ""%1"".\n" STRING_SELF_TERMINATION, "Ошибка: Процесс не может завершить сам себя.\n" + // STRING_CLOSE_CHILD, "Sent termination signal to process with PID %1!u!, child of PID %2!u!.\n" + STRING_CLOSE_CHILD, "Close message sent to top-level windows of process with PID %1!u!, child of PID %2!u!.\n" + STRING_TERM_CHILD, "The process with PID %1!u! (child process of PID %2!u!) has been terminated.\n" + STRING_TERM_CHILD_FAILED, "Error: Unable to terminate process with PID %1!u!, child of PID %2!u!.\n" STRING_PARAM_TOO_MUCH, "Ошибка: Неверный синтаксис. Нельзя использовать опцию '%1' больше '%2!d!' раз(а).\n" STRING_INVALID_SYNTAX, "Ошибка: Неверный синтаксис.\n" } diff --git a/base/applications/cmdutils/taskkill/lang/sq-AL.rc b/base/applications/cmdutils/taskkill/lang/sq-AL.rc index 858781774882d..088e756fc7dd6 100644 --- a/base/applications/cmdutils/taskkill/lang/sq-AL.rc +++ b/base/applications/cmdutils/taskkill/lang/sq-AL.rc @@ -6,7 +6,7 @@ LANGUAGE LANG_ALBANIAN, SUBLANG_NEUTRAL STRINGTABLE { - STRING_USAGE, "Usage: taskkill [/?] [/f] [/im ProcessName | /pid ProcessID]\n" + STRING_USAGE, "Usage: taskkill [/?] [/f] [/im ProcessName | /pid ProcessID] [/t]\n" STRING_INVALID_OPTION, "Gabim: Panjohur ose i pavlefshëm opsioni linjes komandes i specifikuar.\n" STRING_INVALID_PARAM, "Gabim: Pavlefshëm parametri i specifikuar ne linjen e komandes.\n" STRING_MISSING_OPTION, "Gabim: Njera nga opsionet /im ose /pid duhet te specifikohet.\n" @@ -20,6 +20,10 @@ STRINGTABLE STRING_ENUM_FAILED, "Gabim: Në pamundësi për të numëruar listën proceseve.\n" STRING_TERMINATE_FAILED, "Gabim: Pamundur mbyllja e proceseve ""%1"".\n" STRING_SELF_TERMINATION, "Gabim: Procesi vetë-përfundimi nuk është i lejuar.\n" + // STRING_CLOSE_CHILD, "Sent termination signal to process with PID %1!u!, child of PID %2!u!.\n" + STRING_CLOSE_CHILD, "Close message sent to top-level windows of process with PID %1!u!, child of PID %2!u!.\n" + STRING_TERM_CHILD, "The process with PID %1!u! (child process of PID %2!u!) has been terminated.\n" + STRING_TERM_CHILD_FAILED, "Error: Unable to terminate process with PID %1!u!, child of PID %2!u!.\n" STRING_PARAM_TOO_MUCH, "Error: Invalid syntax. '%1' option is not allowed more than '%2!d!' time(s).\n" STRING_INVALID_SYNTAX, "Error: Invalid syntax.\n" } diff --git a/base/applications/cmdutils/taskkill/lang/tr-TR.rc b/base/applications/cmdutils/taskkill/lang/tr-TR.rc index d3f28161a2f03..1a179f3fd97d6 100644 --- a/base/applications/cmdutils/taskkill/lang/tr-TR.rc +++ b/base/applications/cmdutils/taskkill/lang/tr-TR.rc @@ -4,7 +4,7 @@ LANGUAGE LANG_TURKISH, SUBLANG_NEUTRAL STRINGTABLE { - STRING_USAGE, "Kullanım: taskkill [/?] [/f] [/im işlem adı | /pid işlem kimliği]\n" + STRING_USAGE, "Kullanım: taskkill [/?] [/f] [/im işlem adı | /pid işlem kimliği] [/t]\n" STRING_INVALID_OPTION, "Hata: Bilinmeyen veya geçersiz komut satırı seçeneği belirtildi.\n" STRING_INVALID_PARAM, "Hata: Geçersiz komut satırı değişkeni belirtildi.\n" STRING_MISSING_OPTION, "Hata: /im ve /pid seçeneklerinden biri belirtilmeli.\n" @@ -18,6 +18,10 @@ STRINGTABLE STRING_ENUM_FAILED, "Hata: İşlem numaralandırılamıyor.\n" STRING_TERMINATE_FAILED, "Hata: ""%1"" işlemi sonlandırılamıyor.\n" STRING_SELF_TERMINATION, "Hata: İşlemi kendi kendine sonlandırmaya izin verilmedi.\n" + // STRING_CLOSE_CHILD, "Sent termination signal to process with PID %1!u!, child of PID %2!u!.\n" + STRING_CLOSE_CHILD, "Close message sent to top-level windows of process with PID %1!u!, child of PID %2!u!.\n" + STRING_TERM_CHILD, "The process with PID %1!u! (child process of PID %2!u!) has been terminated.\n" + STRING_TERM_CHILD_FAILED, "Error: Unable to terminate process with PID %1!u!, child of PID %2!u!.\n" STRING_PARAM_TOO_MUCH, "Hata: Geçersiz sözdizimi. '%1' seçeneğine '%2!d!'den fazla kez izin verilmiyor..\n" STRING_INVALID_SYNTAX, "Hata: Geçersiz sözdizimi.\n" } diff --git a/base/applications/cmdutils/taskkill/lang/zh-CN.rc b/base/applications/cmdutils/taskkill/lang/zh-CN.rc index 008e3f7005fcc..ce0dc07a97d91 100644 --- a/base/applications/cmdutils/taskkill/lang/zh-CN.rc +++ b/base/applications/cmdutils/taskkill/lang/zh-CN.rc @@ -7,7 +7,7 @@ LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED STRINGTABLE { - STRING_USAGE, "用法:taskkill [/?] [/f] [/im 进程名称 | /pid 进程 ID]\n" + STRING_USAGE, "用法:taskkill [/?] [/f] [/im 进程名称 | /pid 进程 ID] [/t]\n" STRING_INVALID_OPTION, "错误:指定了未知或无效的命令行选项。\n" STRING_INVALID_PARAM, "错误:指定了无效的命令行参数。\n" STRING_MISSING_OPTION, "错误:必须指定选项 /im 或 /pid。\n" @@ -21,6 +21,10 @@ STRINGTABLE STRING_ENUM_FAILED, "错误:无法枚举进程列表。\n" STRING_TERMINATE_FAILED, "错误:无法终止进程“%1”。\n" STRING_SELF_TERMINATION, "错误:不允许终止自身。\n" + // STRING_CLOSE_CHILD, "Sent termination signal to process with PID %1!u!, child of PID %2!u!.\n" + STRING_CLOSE_CHILD, "Close message sent to top-level windows of process with PID %1!u!, child of PID %2!u!.\n" + STRING_TERM_CHILD, "The process with PID %1!u! (child process of PID %2!u!) has been terminated.\n" + STRING_TERM_CHILD_FAILED, "Error: Unable to terminate process with PID %1!u!, child of PID %2!u!.\n" STRING_PARAM_TOO_MUCH, "错误:无效语法。选项“%1”不允许超过“%2!d!”次。\n" STRING_INVALID_SYNTAX, "错误:无效语法。\n" } diff --git a/base/applications/cmdutils/taskkill/lang/zh-TW.rc b/base/applications/cmdutils/taskkill/lang/zh-TW.rc index 9f2b3637cebb6..bf268585a35dc 100644 --- a/base/applications/cmdutils/taskkill/lang/zh-TW.rc +++ b/base/applications/cmdutils/taskkill/lang/zh-TW.rc @@ -11,7 +11,7 @@ LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL STRINGTABLE { - STRING_USAGE, "用法: taskkill [/?] [/f] [/im 處理程序名稱 | /pid PID]\n" + STRING_USAGE, "用法: taskkill [/?] [/f] [/im 處理程序名稱 | /pid PID] [/t]\n" STRING_INVALID_OPTION, "錯誤: 指定了不明或不正確的命令列選項。\n" STRING_INVALID_PARAM, "錯誤: 指定了不正確的命令列參數。\n" STRING_MISSING_OPTION, "錯誤: 必須指定選項 /im 或 /pid 的其中之一。\n" @@ -25,6 +25,10 @@ STRINGTABLE STRING_ENUM_FAILED, "錯誤: 無法列舉處理程序清單。\n" STRING_TERMINATE_FAILED, "錯誤: 無法終止處理程序 '%1'。\n" STRING_SELF_TERMINATION, "錯誤: 處理程序不允許自我終止。\n" + // STRING_CLOSE_CHILD, "Sent termination signal to process with PID %1!u!, child of PID %2!u!.\n" + STRING_CLOSE_CHILD, "Close message sent to top-level windows of process with PID %1!u!, child of PID %2!u!.\n" + STRING_TERM_CHILD, "The process with PID %1!u! (child process of PID %2!u!) has been terminated.\n" + STRING_TERM_CHILD_FAILED, "Error: Unable to terminate process with PID %1!u!, child of PID %2!u!.\n" STRING_PARAM_TOO_MUCH, "錯誤: 無效的語法。'%1' 選項不允許超過 '%2!d!' 次。\n" STRING_INVALID_SYNTAX, "錯誤: 無效的語法。\n" } diff --git a/base/applications/cmdutils/taskkill/taskkill.c b/base/applications/cmdutils/taskkill/taskkill.c index 75706a66491d5..690c782e1ada5 100644 --- a/base/applications/cmdutils/taskkill/taskkill.c +++ b/base/applications/cmdutils/taskkill/taskkill.c @@ -4,6 +4,7 @@ * Copyright 2008 Andrew Riedi * Copyright 2010 Andrew Nguyen * Copyright 2020 He Yang + * Copyright 2025 Hermès Bélusca-Maïto * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -22,28 +23,47 @@ #include #include -#include +#include #include -#include + +#ifdef __REACTOS__ +#define wcsicmp _wcsicmp +#endif #include "taskkill.h" WINE_DEFAULT_DEBUG_CHANNEL(taskkill); static BOOL force_termination = FALSE; +static BOOL kill_child_processes = FALSE; static WCHAR **task_list; static unsigned int task_count; +static struct +{ + PROCESSENTRY32W p; + BOOL matched; + BOOL is_numeric; +} +*process_list; +static unsigned int process_count; + +struct pid_close_info +{ + DWORD pid; + BOOL found; +}; + #ifdef __REACTOS__ +unsigned int* pkill_list; +DWORD pkill_size; +DWORD self_pid; +#endif -static WCHAR opForceTerminate[] = L"f"; -static WCHAR opImage[] = L"im"; -static WCHAR opPID[] = L"pid"; -static WCHAR opHelp[] = L"?"; -static WCHAR opTerminateChildren[] = L"t"; +#ifdef __REACTOS__ -static PWCHAR opList[] = {opForceTerminate, opImage, opPID, opHelp, opTerminateChildren}; +static PWCHAR opList[] = {L"f", L"im", L"pid", L"?", L"t"}; #define OP_PARAM_INVALID -1 @@ -55,41 +75,32 @@ static PWCHAR opList[] = {opForceTerminate, opImage, opPID, opHelp, opTerminateC #endif // __REACTOS__ -struct pid_close_info -{ - DWORD pid; - BOOL found; -}; - -static int taskkill_vprintfW(const WCHAR *msg, __ms_va_list va_args) +static int taskkill_vprintfW(const WCHAR *msg, va_list va_args) { int wlen; - DWORD count, ret; + DWORD count; WCHAR msg_buffer[8192]; wlen = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, msg, 0, 0, msg_buffer, ARRAY_SIZE(msg_buffer), &va_args); - ret = WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), msg_buffer, wlen, &count, NULL); - if (!ret) + if (!WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), msg_buffer, wlen, &count, NULL)) { DWORD len; char *msgA; /* On Windows WriteConsoleW() fails if the output is redirected. So fall - * back to WriteFile(), assuming the console encoding is still the right - * one in that case. + * back to WriteFile() using OEM code page. */ - len = WideCharToMultiByte(GetConsoleOutputCP(), 0, msg_buffer, wlen, + len = WideCharToMultiByte(GetOEMCP(), 0, msg_buffer, wlen, NULL, 0, NULL, NULL); - msgA = HeapAlloc(GetProcessHeap(), 0, len); + msgA = malloc(len); if (!msgA) return 0; - WideCharToMultiByte(GetConsoleOutputCP(), 0, msg_buffer, wlen, msgA, len, - NULL, NULL); + WideCharToMultiByte(GetOEMCP(), 0, msg_buffer, wlen, msgA, len, NULL, NULL); WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), msgA, len, &count, FALSE); - HeapFree(GetProcessHeap(), 0, msgA); + free(msgA); } return count; @@ -97,39 +108,38 @@ static int taskkill_vprintfW(const WCHAR *msg, __ms_va_list va_args) static int WINAPIV taskkill_printfW(const WCHAR *msg, ...) { - __ms_va_list va_args; + va_list va_args; int len; - __ms_va_start(va_args, msg); + va_start(va_args, msg); len = taskkill_vprintfW(msg, va_args); - __ms_va_end(va_args); + va_end(va_args); return len; } static int WINAPIV taskkill_message_printfW(int msg, ...) { - __ms_va_list va_args; + va_list va_args; WCHAR msg_buffer[8192]; int len; LoadStringW(GetModuleHandleW(NULL), msg, msg_buffer, ARRAY_SIZE(msg_buffer)); - __ms_va_start(va_args, msg); + va_start(va_args, msg); len = taskkill_vprintfW(msg_buffer, va_args); - __ms_va_end(va_args); + va_end(va_args); return len; } static int taskkill_message(int msg) { - static const WCHAR formatW[] = {'%','1',0}; WCHAR msg_buffer[8192]; LoadStringW(GetModuleHandleW(NULL), msg, msg_buffer, ARRAY_SIZE(msg_buffer)); - return taskkill_printfW(formatW, msg_buffer); + return taskkill_printfW(L"%1", msg_buffer); } /* Post WM_CLOSE to all top-level windows belonging to the process with specified PID. */ @@ -149,72 +159,204 @@ static BOOL CALLBACK pid_enum_proc(HWND hwnd, LPARAM lParam) return TRUE; } -static DWORD *enumerate_processes(DWORD *list_count) +static BOOL enumerate_processes(void) { - DWORD *pid_list, alloc_bytes = 1024 * sizeof(*pid_list), needed_bytes; + unsigned int alloc_count = 128; + void *realloc_list; + HANDLE snapshot; + + snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if (snapshot == INVALID_HANDLE_VALUE) + return FALSE; - pid_list = HeapAlloc(GetProcessHeap(), 0, alloc_bytes); - if (!pid_list) - return NULL; + process_list = malloc(alloc_count * sizeof(*process_list)); + if (!process_list) + return FALSE; - for (;;) - { - DWORD *realloc_list; + process_list[0].p.dwSize = sizeof(process_list[0].p); + if (!Process32FirstW(snapshot, &process_list[0].p)) + return FALSE; - if (!EnumProcesses(pid_list, alloc_bytes, &needed_bytes)) + do + { + process_list[process_count].is_numeric = FALSE; + process_list[process_count++].matched = FALSE; + if (process_count == alloc_count) { - HeapFree(GetProcessHeap(), 0, pid_list); - return NULL; + alloc_count *= 2; + realloc_list = realloc(process_list, alloc_count * sizeof(*process_list)); + if (!realloc_list) + return FALSE; + process_list = realloc_list; } + process_list[process_count].p.dwSize = sizeof(process_list[process_count].p); + } while (Process32NextW(snapshot, &process_list[process_count].p)); + CloseHandle(snapshot); + return TRUE; +} + +static void mark_task_process(const WCHAR *str, int *status_code) +{ +#ifndef __REACTOS__ + DWORD self_pid = GetCurrentProcessId(); +#endif + const WCHAR *p = str; + BOOL is_numeric; + unsigned int i; + DWORD pid; - /* EnumProcesses can't signal an insufficient buffer condition, so the - * only way to possibly determine whether a larger buffer is required - * is to see whether the written number of bytes is the same as the - * buffer size. If so, the buffer will be reallocated to twice the - * size. */ - if (alloc_bytes != needed_bytes) + is_numeric = TRUE; + while (*p) + { + if (!iswdigit(*p++)) + { + is_numeric = FALSE; break; + } + } - alloc_bytes *= 2; - realloc_list = HeapReAlloc(GetProcessHeap(), 0, pid_list, alloc_bytes); - if (!realloc_list) + if (is_numeric) + { + pid = wcstol(str, NULL, 10); + for (i = 0; i < process_count; ++i) { - HeapFree(GetProcessHeap(), 0, pid_list); - return NULL; + if (process_list[i].p.th32ProcessID == pid) + break; + } + if (i == process_count || process_list[i].matched) + goto not_found; + process_list[i].matched = TRUE; + process_list[i].is_numeric = TRUE; + if (pid == self_pid) + { + taskkill_message(STRING_SELF_TERMINATION); + *status_code = 1; + } +#ifdef __REACTOS__ + else + { + pkill_list[pkill_size++] = i; } - pid_list = realloc_list; +#endif + return; + } + + for (i = 0; i < process_count; ++i) + { + if (!wcsicmp(process_list[i].p.szExeFile, str) && !process_list[i].matched) + { + process_list[i].matched = TRUE; + if (process_list[i].p.th32ProcessID == self_pid) + { + taskkill_message(STRING_SELF_TERMINATION); + *status_code = 1; + } +#ifdef __REACTOS__ + else + { + pkill_list[pkill_size++] = i; + continue; + } +#endif + return; + } + } + +#ifdef __REACTOS__ + // Cannot find any process matching the PID or name + if (pkill_size == 0) + { +#endif +not_found: + taskkill_message_printfW(STRING_SEARCH_FAILED, str); + *status_code = 128; +#ifdef __REACTOS__ } +#endif +} + +static void taskkill_message_print_process(int msg, unsigned int index) +{ + WCHAR pid_str[16]; - *list_count = needed_bytes / sizeof(*pid_list); - return pid_list; + if (!process_list[index].is_numeric) + { + taskkill_message_printfW(msg, process_list[index].p.szExeFile); + return; + } + wsprintfW(pid_str, L"%lu", process_list[index].p.th32ProcessID); + taskkill_message_printfW(msg, pid_str); } -static BOOL get_process_name_from_pid(DWORD pid, WCHAR *buf, DWORD chars) +#ifndef __REACTOS__ +/* + * Below is the Wine method of terminating child processes. + * Its problem is that it doesn't terminate them in either a parent-to-children + * or children-to-parent relationship, but instead in the order in which they + * appear in the process list. This differs from Windows' (or ReactOS) method. + * Wine's termination ordering can cause problems in scenarii where e.g. a + * parent process could re-spawn killed children processes, or, where it is + * of interest to kill the parent process first and then its children. + * + * NOTE: The following two functions implicitly assume that the process list + * obtained from the system, is such that any child process P[j] of a given + * parent process P[i] is enumerated *AFTER* its parent (i.e. i < j). + * + * Because of these facts, the ReactOS method is employed instead. + * Note however that the Wine method (below) has been adapted for + * ease of usage and comparison with that of ReactOS. + */ + +static BOOL find_parent(unsigned int process_index, unsigned int *parent_index) { - HANDLE process; - HMODULE module; - DWORD required_size; + DWORD parent_id = process_list[process_index].p.th32ParentProcessID; + unsigned int i; - process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid); - if (!process) + if (!parent_id) return FALSE; - if (!EnumProcessModules(process, &module, sizeof(module), &required_size)) + for (i = 0; i < process_count; ++i) { - CloseHandle(process); - return FALSE; + if (process_list[i].p.th32ProcessID == parent_id) + { + *parent_index = i; + return TRUE; + } } + return FALSE; +} + +static void mark_child_processes(void) +{ + unsigned int i, parent; - if (!GetModuleBaseNameW(process, module, buf, chars)) + for (i = 0; i < process_count; ++i) { - CloseHandle(process); - return FALSE; + if (process_list[i].matched) + continue; +#ifdef __REACTOS__ + // Prevent self-termination if we are in the process tree + if (process_list[i].p.th32ProcessID == self_pid) + continue; +#endif + parent = i; + while (find_parent(parent, &parent)) + { + if (process_list[parent].matched) + { + WINE_TRACE("Adding child %04lx.\n", process_list[i].p.th32ProcessID); + process_list[i].matched = TRUE; +#ifdef __REACTOS__ + pkill_list[pkill_size++] = i; +#endif + break; + } + } } - - CloseHandle(process); - return TRUE; } +#endif // !__REACTOS__ + /* The implemented task enumeration and termination behavior does not * exactly match native behavior. On Windows: * @@ -230,258 +372,202 @@ static BOOL get_process_name_from_pid(DWORD pid, WCHAR *buf, DWORD chars) * A PID of zero causes taskkill to warn about the inability to terminate * system processes. */ -#ifndef __REACTOS__ +#ifdef __REACTOS__ -static int send_close_messages(void) +static BOOL get_pid_creation_time(DWORD pid, FILETIME *time) { - DWORD *pid_list, pid_list_size; - DWORD self_pid = GetCurrentProcessId(); - unsigned int i; - int status_code = 0; + HANDLE process; + FILETIME t1, t2, t3; + BOOL success; - pid_list = enumerate_processes(&pid_list_size); - if (!pid_list) - { - taskkill_message(STRING_ENUM_FAILED); - return 1; - } + process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid); + if (!process) + return FALSE; - for (i = 0; i < task_count; i++) - { - WCHAR *p = task_list[i]; - BOOL is_numeric = TRUE; + success = GetProcessTimes(process, time, &t1, &t2, &t3); + CloseHandle(process); - /* Determine whether the string is not numeric. */ - while (*p) - { - if (!isdigitW(*p++)) - { - is_numeric = FALSE; - break; - } - } + return success; +} - if (is_numeric) - { - DWORD pid = atoiW(task_list[i]); - struct pid_close_info info = { pid }; +static void queue_children(DWORD ppid) +{ + FILETIME parent_creation_time; + unsigned int i; - if (pid == self_pid) - { - taskkill_message(STRING_SELF_TERMINATION); - status_code = 1; - continue; - } + if (!get_pid_creation_time(ppid, &parent_creation_time)) + return; - EnumWindows(pid_enum_proc, (LPARAM)&info); - if (info.found) - taskkill_message_printfW(STRING_CLOSE_PID_SEARCH, pid); - else - { - taskkill_message_printfW(STRING_SEARCH_FAILED, task_list[i]); - status_code = 128; - } - } - else - { - DWORD index; - BOOL found_process = FALSE; + for (i = 0; i < process_count; ++i) + { + FILETIME child_creation_time; + DWORD pid; - for (index = 0; index < pid_list_size; index++) - { - WCHAR process_name[MAX_PATH]; + // Ignore processes already marked for termination + if (process_list[i].matched) + continue; - if (get_process_name_from_pid(pid_list[index], process_name, MAX_PATH) && - !strcmpiW(process_name, task_list[i])) - { - struct pid_close_info info = { pid_list[index] }; - - found_process = TRUE; - if (pid_list[index] == self_pid) - { - taskkill_message(STRING_SELF_TERMINATION); - status_code = 1; - continue; - } - - EnumWindows(pid_enum_proc, (LPARAM)&info); - taskkill_message_printfW(STRING_CLOSE_PROC_SRCH, process_name, pid_list[index]); - } - } + // Prevent self-termination if we are in the process tree + pid = process_list[i].p.th32ProcessID; + if (pid == self_pid) + continue; - if (!found_process) - { - taskkill_message_printfW(STRING_SEARCH_FAILED, task_list[i]); - status_code = 128; - } + if (!get_pid_creation_time(pid, &child_creation_time)) + continue; + + // Compare creation time to avoid PID reuse cases + if (process_list[i].p.th32ParentProcessID == ppid && + CompareFileTime(&parent_creation_time, &child_creation_time) < 0) + { + // Process marked for termination + WINE_TRACE("Adding child %04lx.\n", pid); + process_list[i].matched = TRUE; + pkill_list[pkill_size++] = i; } } +} - HeapFree(GetProcessHeap(), 0, pid_list); - return status_code; +/* + * Based on the root processes to terminate, we perform a level order traversal + * (Breadth First Search) of the corresponding process trees, building the list + * of all processes and children to terminate, + * This allows terminating the processes, starting from parents down to their + * children. Note that this is in the reverse order than what Windows' taskkill + * does. The reason why we chose to do the reverse, is because there exist + * (parent) processes that detect whether their children are terminated, and + * if so, attempt to restart their terminated children. We want to avoid this + * scenario in order to ensure no extra processes get started, while the user + * wanted to terminate them. + */ +static void mark_child_processes(void) +{ + /* + * The temporary FIFO queue for BFS (starting empty), is embedded + * inside the result list. The queue resides between the [front, end) + * indices (if front == end, the queue is empty), and moves down + * through the result list, generating the sought values in order. + */ + unsigned int front = 0; // end = 0; given by pkill_size + + /* The root processes have already been + * enqueued in pkill_list[0..pkill_size] */ + + /* Now, find and enqueue the children processes */ + while (pkill_size - front > 0) + { + /* Begin search at the next level */ + unsigned int len = pkill_size - front; + unsigned int i; + for (i = 0; i < len; ++i) + { + /* Standard BFS would pop the element from the front of + * the queue and push it to the end of the result list. + * In our case, everything is already correctly positioned + * so that we can just simply emulate queue front popping. */ + DWORD pid = process_list[pkill_list[front++]].p.th32ProcessID; + + /* Enqueue the children processes */ + queue_children(pid); // Updates pkill_size accordingly. + } + } } #endif // __REACTOS__ -#ifdef __REACTOS__ -static int terminate_processes(BOOL force_termination) -#else -static int terminate_processes(void) -#endif +static int send_close_messages(void) { - DWORD *pid_list, pid_list_size; - DWORD self_pid = GetCurrentProcessId(); + const WCHAR *process_name; + struct pid_close_info info; unsigned int i; int status_code = 0; - pid_list = enumerate_processes(&pid_list_size); - if (!pid_list) - { - taskkill_message(STRING_ENUM_FAILED); - return 1; - } - - for (i = 0; i < task_count; i++) - { - WCHAR *p = task_list[i]; - BOOL is_numeric = TRUE; - - /* Determine whether the string is not numeric. */ - while (*p) - { - if (!isdigitW(*p++)) - { - is_numeric = FALSE; - break; - } - } - - if (is_numeric) - { - DWORD pid = atoiW(task_list[i]); -#ifndef __REACTOS__ - HANDLE process; +#ifdef __REACTOS__ + DWORD index; + for (index = 0; index < pkill_size; ++index) +#else + for (i = 0; i < process_count; i++) #endif - - if (pid == self_pid) - { - taskkill_message(STRING_SELF_TERMINATION); - status_code = 1; - continue; - } - + { #ifdef __REACTOS__ - if (force_termination) - { - HANDLE process; + i = pkill_list[index]; +#else + if (!process_list[i].matched) + continue; #endif - process = OpenProcess(PROCESS_TERMINATE, FALSE, pid); - if (!process) - { - taskkill_message_printfW(STRING_SEARCH_FAILED, task_list[i]); - status_code = 128; - continue; - } - - if (!TerminateProcess(process, 0)) - { - taskkill_message_printfW(STRING_TERMINATE_FAILED, task_list[i]); - status_code = 1; - CloseHandle(process); - continue; - } - taskkill_message_printfW(STRING_TERM_PID_SEARCH, pid); - CloseHandle(process); -#ifdef __REACTOS__ - } + info.pid = process_list[i].p.th32ProcessID; + process_name = process_list[i].p.szExeFile; + info.found = FALSE; + WINE_TRACE("Terminating pid %04lx.\n", info.pid); + EnumWindows(pid_enum_proc, (LPARAM)&info); + if (info.found) + { + if (kill_child_processes) + taskkill_message_printfW(STRING_CLOSE_CHILD, info.pid, process_list[i].p.th32ParentProcessID); + else if (process_list[i].is_numeric) + taskkill_message_printfW(STRING_CLOSE_PID_SEARCH, info.pid); else - { - struct pid_close_info info = { pid }; - - EnumWindows(pid_enum_proc, (LPARAM)&info); - if (info.found) - taskkill_message_printfW(STRING_CLOSE_PID_SEARCH, pid); - else - { - taskkill_message_printfW(STRING_SEARCH_FAILED, task_list[i]); - status_code = 128; - } - } -#endif + taskkill_message_printfW(STRING_CLOSE_PROC_SRCH, process_name, info.pid); + continue; } - else - { - DWORD index; - BOOL found_process = FALSE; + taskkill_message_print_process(STRING_SEARCH_FAILED, i); + status_code = 128; + } - for (index = 0; index < pid_list_size; index++) - { - WCHAR process_name[MAX_PATH]; + return status_code; +} + +static int terminate_processes(void) +{ + const WCHAR *process_name; + unsigned int i; + int status_code = 0; + HANDLE process; + DWORD pid; - if (get_process_name_from_pid(pid_list[index], process_name, MAX_PATH) && - !strcmpiW(process_name, task_list[i])) - { #ifdef __REACTOS__ - found_process = TRUE; + DWORD index; + for (index = 0; index < pkill_size; ++index) #else - HANDLE process; + for (i = 0; i < process_count; i++) #endif - - if (pid_list[index] == self_pid) - { - taskkill_message(STRING_SELF_TERMINATION); - status_code = 1; - continue; - } - + { #ifdef __REACTOS__ - if (force_termination) - { - HANDLE process; + i = pkill_list[index]; +#else + if (!process_list[i].matched) + continue; #endif - process = OpenProcess(PROCESS_TERMINATE, FALSE, pid_list[index]); - if (!process) - { - taskkill_message_printfW(STRING_SEARCH_FAILED, task_list[i]); - status_code = 128; - continue; - } - - if (!TerminateProcess(process, 0)) - { - taskkill_message_printfW(STRING_TERMINATE_FAILED, task_list[i]); - status_code = 1; - CloseHandle(process); - continue; - } -#ifndef __REACTOS__ - found_process = TRUE; -#endif - taskkill_message_printfW(STRING_TERM_PROC_SEARCH, task_list[i], pid_list[index]); - CloseHandle(process); + pid = process_list[i].p.th32ProcessID; + process_name = process_list[i].p.szExeFile; + process = OpenProcess(PROCESS_TERMINATE, FALSE, pid); + if (!process) + { + taskkill_message_print_process(STRING_SEARCH_FAILED, i); + status_code = 128; + continue; + } + if (!TerminateProcess(process, 1)) + { #ifdef __REACTOS__ - } - else - { - struct pid_close_info info = { pid_list[index] }; - EnumWindows(pid_enum_proc, (LPARAM)&info); - taskkill_message_printfW(STRING_CLOSE_PROC_SRCH, process_name, pid_list[index]); - } + if (kill_child_processes) + taskkill_message_printfW(STRING_TERM_CHILD_FAILED, pid, process_list[i].p.th32ParentProcessID); + else #endif - } - } - - if (!found_process) - { - taskkill_message_printfW(STRING_SEARCH_FAILED, task_list[i]); - status_code = 128; - } + taskkill_message_print_process(STRING_TERMINATE_FAILED, i); + status_code = 1; + CloseHandle(process); + continue; } + if (kill_child_processes) + taskkill_message_printfW(STRING_TERM_CHILD, pid, process_list[i].p.th32ParentProcessID); + else if (process_list[i].is_numeric) + taskkill_message_printfW(STRING_TERM_PID_SEARCH, pid); + else + taskkill_message_printfW(STRING_TERM_PROC_SEARCH, process_name, pid); + CloseHandle(process); } - - HeapFree(GetProcessHeap(), 0, pid_list); return status_code; } @@ -491,8 +577,7 @@ static BOOL add_to_task_list(WCHAR *name) if (!task_list) { - task_list = HeapAlloc(GetProcessHeap(), 0, - list_size * sizeof(*task_list)); + task_list = malloc(list_size * sizeof(*task_list)); if (!task_list) return FALSE; } @@ -501,8 +586,7 @@ static BOOL add_to_task_list(WCHAR *name) void *realloc_list; list_size *= 2; - realloc_list = HeapReAlloc(GetProcessHeap(), 0, task_list, - list_size * sizeof(*task_list)); + realloc_list = realloc(task_list, list_size * sizeof(*task_list)); if (!realloc_list) return FALSE; @@ -527,7 +611,7 @@ static int get_argument_type(WCHAR* argument) for (i = 0; i < _countof(opList); i++) { - if (!strcmpiW(opList[i], argument)) + if (!wcsicmp(opList[i], argument)) { return i; } @@ -535,10 +619,6 @@ static int get_argument_type(WCHAR* argument) return OP_PARAM_INVALID; } -/* FIXME -argument T not supported -*/ - static BOOL process_arguments(int argc, WCHAR* argv[]) { BOOL has_im = FALSE, has_pid = FALSE, has_help = FALSE; @@ -554,7 +634,7 @@ static BOOL process_arguments(int argc, WCHAR* argv[]) { case OP_PARAM_FORCE_TERMINATE: { - if (force_termination == TRUE) + if (force_termination) { // -f already specified taskkill_message_printfW(STRING_PARAM_TOO_MUCH, argv[i], 1); @@ -600,7 +680,7 @@ static BOOL process_arguments(int argc, WCHAR* argv[]) } case OP_PARAM_HELP: { - if (has_help == TRUE) + if (has_help) { // -? already specified taskkill_message_printfW(STRING_PARAM_TOO_MUCH, argv[i], 1); @@ -612,7 +692,14 @@ static BOOL process_arguments(int argc, WCHAR* argv[]) } case OP_PARAM_TERMINATE_CHILD: { - WINE_FIXME("argument T not supported\n"); + if (kill_child_processes) + { + // -t already specified + taskkill_message_printfW(STRING_PARAM_TOO_MUCH, argv[i], 1); + taskkill_message(STRING_USAGE); + return FALSE; + } + kill_child_processes = TRUE; break; } case OP_PARAM_INVALID: @@ -640,7 +727,7 @@ static BOOL process_arguments(int argc, WCHAR* argv[]) exit(0); } } - else if ((!has_im) && (!has_pid)) // has_help == FALSE + else if (!has_im && !has_pid) // has_help == FALSE { // both has_im and has_pid are missing (maybe -fi option is missing too, if implemented later) taskkill_message(STRING_MISSING_OPTION); @@ -658,12 +745,6 @@ static BOOL process_arguments(int argc, WCHAR* argv[]) * options are detected as parameters when placed after options that accept one. */ static BOOL process_arguments(int argc, WCHAR *argv[]) { - static const WCHAR opForceTerminate[] = {'f',0}; - static const WCHAR opImage[] = {'i','m',0}; - static const WCHAR opPID[] = {'p','i','d',0}; - static const WCHAR opHelp[] = {'?',0}; - static const WCHAR opTerminateChildren[] = {'t',0}; - if (argc > 1) { int i; @@ -674,7 +755,7 @@ static BOOL process_arguments(int argc, WCHAR *argv[]) if (argc == 2) { argdata = argv[1]; - if ((*argdata == '/' || *argdata == '-') && !strcmpW(opHelp, argdata + 1)) + if ((*argdata == '/' || *argdata == '-') && !lstrcmpW(L"?", argdata + 1)) { taskkill_message(STRING_USAGE); exit(0); @@ -690,14 +771,14 @@ static BOOL process_arguments(int argc, WCHAR *argv[]) goto invalid; argdata++; - if (!strcmpiW(opTerminateChildren, argdata)) - WINE_FIXME("argument T not supported\n"); - if (!strcmpiW(opForceTerminate, argdata)) + if (!wcsicmp(L"t", argdata)) + kill_child_processes = TRUE; + else if (!wcsicmp(L"f", argdata)) force_termination = TRUE; /* Options /IM and /PID appear to behave identically, except for * the fact that they cannot be specified at the same time. */ - else if ((got_im = !strcmpiW(opImage, argdata)) || - (got_pid = !strcmpiW(opPID, argdata))) + else if ((got_im = !wcsicmp(L"im", argdata)) || + (got_pid = !wcsicmp(L"pid", argdata))) { if (!argv[i + 1]) { @@ -743,23 +824,35 @@ static BOOL process_arguments(int argc, WCHAR *argv[]) int wmain(int argc, WCHAR *argv[]) { - int status_code = 0; + int search_status = 0, terminate_status; + unsigned int i; if (!process_arguments(argc, argv)) + return 1; + + if (!enumerate_processes()) { - HeapFree(GetProcessHeap(), 0, task_list); + taskkill_message(STRING_ENUM_FAILED); return 1; } #ifdef __REACTOS__ - status_code = terminate_processes(force_termination); -#else - if (force_termination) - status_code = terminate_processes(); - else - status_code = send_close_messages(); + pkill_list = malloc(process_count * sizeof(unsigned int*)); + if (!pkill_list) + return 1; + memset(pkill_list, 0, process_count * sizeof(unsigned int*)); + pkill_size = 0; + + self_pid = GetCurrentProcessId(); #endif - HeapFree(GetProcessHeap(), 0, task_list); - return status_code; + for (i = 0; i < task_count; ++i) + mark_task_process(task_list[i], &search_status); + if (kill_child_processes) + mark_child_processes(); + if (force_termination) + terminate_status = terminate_processes(); + else + terminate_status = send_close_messages(); + return search_status ? search_status : terminate_status; } diff --git a/base/applications/cmdutils/taskkill/taskkill.h b/base/applications/cmdutils/taskkill/taskkill.h index 03312fa8c9cc8..68f84fe81596d 100644 --- a/base/applications/cmdutils/taskkill/taskkill.h +++ b/base/applications/cmdutils/taskkill/taskkill.h @@ -35,6 +35,8 @@ #define STRING_ENUM_FAILED 112 #define STRING_TERMINATE_FAILED 113 #define STRING_SELF_TERMINATION 114 -#define STRING_PARAM_TOO_MUCH 115 -#define STRING_INVALID_SYNTAX 116 - +#define STRING_CLOSE_CHILD 115 +#define STRING_TERM_CHILD 116 +#define STRING_TERM_CHILD_FAILED 117 +#define STRING_PARAM_TOO_MUCH 118 +#define STRING_INVALID_SYNTAX 119 diff --git a/base/applications/cmdutils/tasklist/tasklist.rc b/base/applications/cmdutils/tasklist/tasklist.rc index 7f85446d43602..7a01c6003c974 100644 --- a/base/applications/cmdutils/tasklist/tasklist.rc +++ b/base/applications/cmdutils/tasklist/tasklist.rc @@ -9,6 +9,7 @@ /* UTF-8 */ #pragma code_page(65001) + #ifdef LANGUAGE_BG_BG #include "lang/bg-BG.rc" #endif diff --git a/base/applications/cmdutils/tree/tree.rc b/base/applications/cmdutils/tree/tree.rc index 63ce24f11b203..506578e6f6316 100644 --- a/base/applications/cmdutils/tree/tree.rc +++ b/base/applications/cmdutils/tree/tree.rc @@ -11,6 +11,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL /* UTF-8 */ #pragma code_page(65001) + #ifdef LANGUAGE_DE_DE #include "lang/de-DE.rc" #endif diff --git a/base/applications/cmdutils/where/where.rc b/base/applications/cmdutils/where/where.rc index 115d90a45b6f5..919dc71a35d2c 100644 --- a/base/applications/cmdutils/where/where.rc +++ b/base/applications/cmdutils/where/where.rc @@ -6,7 +6,8 @@ #define REACTOS_STR_ORIGINAL_FILENAME "where.exe" #include -#pragma code_page(65001) /* UTF-8 */ +/* UTF-8 */ +#pragma code_page(65001) #ifdef LANGUAGE_DE_DE #include "lang/de-DE.rc" diff --git a/base/applications/cmdutils/wmic/CMakeLists.txt b/base/applications/cmdutils/wmic/CMakeLists.txt index 0add8850c2293..ed6e3169c7ebb 100644 --- a/base/applications/cmdutils/wmic/CMakeLists.txt +++ b/base/applications/cmdutils/wmic/CMakeLists.txt @@ -1,7 +1,7 @@ -add_definitions(-D__WINESRC__) add_executable(wmic main.c wmic.rc) target_link_libraries(wmic wine) set_module_type(wmic win32cui UNICODE) add_importlibs(wmic oleaut32 ole32 user32 msvcrt kernel32 ntdll) add_cd_file(TARGET wmic DESTINATION reactos/system32/wbem FOR all) +set_wine_module_FIXME(wmic) # CORE-5743: No ARRAY_SIZE macro diff --git a/base/applications/cmdutils/wscript/CMakeLists.txt b/base/applications/cmdutils/wscript/CMakeLists.txt index 4ae6b1b401999..0772eb4445882 100644 --- a/base/applications/cmdutils/wscript/CMakeLists.txt +++ b/base/applications/cmdutils/wscript/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) - list(APPEND SOURCE arguments.c host.c @@ -18,3 +16,4 @@ add_importlibs(wscript shell32 oleaut32 ole32 user32 advapi32 msvcrt kernel32 nt add_dependencies(wscript stdole2 wscript_idlheader) add_pch(wscript precomp.h SOURCE) add_cd_file(TARGET wscript DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(wscript) # CORE-5743: No ARRAY_SIZE macro diff --git a/base/applications/cmdutils/xcopy/CMakeLists.txt b/base/applications/cmdutils/xcopy/CMakeLists.txt index f2fa0cf0ad400..2b269aca9537d 100644 --- a/base/applications/cmdutils/xcopy/CMakeLists.txt +++ b/base/applications/cmdutils/xcopy/CMakeLists.txt @@ -1,7 +1,7 @@ -add_definitions(-D__WINESRC__) add_executable(xcopy xcopy.c xcopy.rc) target_link_libraries(xcopy wine) set_module_type(xcopy win32cui UNICODE) add_importlibs(xcopy shell32 user32 msvcrt kernel32 ntdll) add_cd_file(TARGET xcopy DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(xcopy) # CORE-5743: No ARRAY_SIZE macro diff --git a/base/applications/cmdutils/xcopy/lang/fr-FR.rc b/base/applications/cmdutils/xcopy/lang/fr-FR.rc index fd97858751c6e..3aef349f3ff23 100644 --- a/base/applications/cmdutils/xcopy/lang/fr-FR.rc +++ b/base/applications/cmdutils/xcopy/lang/fr-FR.rc @@ -50,7 +50,7 @@ où :\n\ [/A] Copie uniquement les fichiers qui ont l'attribut archive défini\n\ [/M] Copie uniquement les fichiers qui ont l'attribut archive défini ; supprime\n\ \tensuite l'attribut\n\ -[/K] Copy file attributes, without this attributes are not preserved.\n\ +[/K] Copie les attributs de fichiers. Sans ce paramètre les attributs ne sont pas conservés.\n\ [/D | /D:m-d-y] Copie uniquement les nouveaux fichiers, ou ceux modifiés après la date spécifiée.\n\ \t\tSi aucune date n'est spécifiée, copie uniquement lorsque le fichier de destination est plus ancien\n\ \t\tque le fichier source\n\n" diff --git a/base/applications/drwtsn32/drwtsn32.rc b/base/applications/drwtsn32/drwtsn32.rc index 2e2946c72f7f2..22498777e8d4f 100644 --- a/base/applications/drwtsn32/drwtsn32.rc +++ b/base/applications/drwtsn32/drwtsn32.rc @@ -40,6 +40,9 @@ #ifdef LANGUAGE_IT_IT #include "lang/it-IT.rc" #endif +#ifdef LANGUAGE_JA_JP + #include "lang/ja-JP.rc" +#endif #ifdef LANGUAGE_PL_PL #include "lang/pl-PL.rc" #endif diff --git a/base/applications/drwtsn32/lang/ja-JP.rc b/base/applications/drwtsn32/lang/ja-JP.rc new file mode 100644 index 0000000000000..7829faea8db09 --- /dev/null +++ b/base/applications/drwtsn32/lang/ja-JP.rc @@ -0,0 +1,7 @@ +LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT + +STRINGTABLE +BEGIN + IDS_APP_TITLE "ReactOS クラッシュレポーター" + IDS_USER_ALERT_MESSAGE "アプリケーション %ls がクラッシュしました。このクラッシュに関する情報は次の場所に保存されました:\n\n%ls" +END diff --git a/base/applications/dxdiag/lang/ro-RO.rc b/base/applications/dxdiag/lang/ro-RO.rc index 2e57b0806d11e..bfde7621fa48a 100644 --- a/base/applications/dxdiag/lang/ro-RO.rc +++ b/base/applications/dxdiag/lang/ro-RO.rc @@ -3,7 +3,7 @@ * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) * PURPOSE: Romanian resource file * TRANSLATORS: Copyright 2011-2019 Ștefan Fulea - * Copyright 2023 Andrei Miloiu + * Copyright 2023-2025 Andrei Miloiu */ LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL @@ -11,22 +11,22 @@ LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL IDD_MAIN_DIALOG DIALOGEX 0, 0, 478, 280 STYLE DS_SHELLFONT | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU -CAPTION "Diagnostic ReactX" +CAPTION "Instrument de diagnosticare ReactX" FONT 8, "MS Shell Dlg" BEGIN CONTROL "Tab1", IDC_TAB_CONTROL, "SysTabControl32", WS_TABSTOP, 2, 2, 474, 250 - PUSHBUTTON "&Manual…", IDC_BUTTON_HELP, 2, 260, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_DISABLED - DEFPUSHBUTTON "&Următorul compartiment", IDC_BUTTON_NEXT, 187, 260, 120, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP - PUSHBUTTON "S&alvare informații…", IDC_BUTTON_SAVE_INFO, 311, 260, 110, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_DISABLED - PUSHBUTTON "Î&nchide", IDC_BUTTON_EXIT, 425, 260, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP + PUSHBUTTON "&Ajutor", IDC_BUTTON_HELP, 2, 260, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_DISABLED + DEFPUSHBUTTON "&Pagina următoare", IDC_BUTTON_NEXT, 187, 260, 120, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP + PUSHBUTTON "&Salvare a tuturor informațiilor…", IDC_BUTTON_SAVE_INFO, 311, 260, 110, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_DISABLED + PUSHBUTTON "Î&nchidere", IDC_BUTTON_EXIT, 425, 260, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP END IDD_SYSTEM_DIALOG DIALOGEX 0, 0, 462, 220 STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN FONT 8, "MS Shell Dlg" BEGIN - LTEXT "Acest instrument oferă informații detaliate despre componentele ReactX și drivere instalate în sistem.", IDC_STATIC, 5, 0, 443, 17 - LTEXT "Dacă aveți la cunoștință careva probleme la o anumită categorie, mergeți la compartimentul corespunzător de mai sus. Altfel, puteți utiliza butonul „Următorul compartiment” de mai jos pentru a trece secvențial prin fiecare categorie.", IDC_STATIC, 5, 15, 443, 25 + LTEXT "Acest instrument raportează informații detaliate despre componentele ReactX și driverele instalate pe sistem.", IDC_STATIC, 5, 0, 443, 17 + LTEXT "Dacă întâmpinați o problemă cu ReactX și știți ce este, atunci faceți clic pe fila corespunzătoare de mai sus. Dacă nu, puteți face clic pe butonul ""Pagina următoare"" de mai jos pentru a vizita fiecare pagină în succesiune.", IDC_STATIC, 5, 15, 443, 25 GROUPBOX "Informații despre sistem", IDC_STATIC, 5, 35, 452, 150, SS_RIGHT LTEXT "Data/Ora curentă:", IDC_STATIC, 70, 50, 80, 10, SS_RIGHT LTEXT "Numele calculatorului:", IDC_STATIC, 70, 60, 80, 10, SS_RIGHT @@ -60,11 +60,11 @@ BEGIN GROUPBOX "Dispozitiv", IDC_STATIC, 5, 0, 250, 95 RTEXT "Nume:", IDC_STATIC, 20, 10, 70, 10 RTEXT "Producător:", IDC_STATIC, 20, 20, 70, 10 - RTEXT "Tipul cipului:", IDC_STATIC, 20, 30, 70, 10 - RTEXT "Tipul CDA:", IDC_STATIC, 20, 40, 70, 10 - RTEXT "Memorie aprox.:", IDC_STATIC, 20, 50, 70, 10 - RTEXT "Afișare curentă:", IDC_STATIC, 20, 60, 70, 10 - RTEXT "Ecran:", IDC_STATIC, 20, 70, 70, 10 + RTEXT "Tipul chip-ului:", IDC_STATIC, 20, 30, 70, 10 + RTEXT "Tipul DAC:", IDC_STATIC, 20, 40, 70, 10 + RTEXT "Mem. tot. aprox.:", IDC_STATIC, 20, 50, 70, 10 + RTEXT "Mod afișare curentă:", IDC_STATIC, 20, 60, 70, 10 + RTEXT "Monitor:", IDC_STATIC, 20, 70, 70, 10 EDITTEXT IDC_STATIC_ADAPTER_ID, 95, 10, 150, 10, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL EDITTEXT IDC_STATIC_ADAPTER_VENDOR, 95, 20, 150, 10, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL EDITTEXT IDC_STATIC_ADAPTER_CHIP, 95, 30, 150, 10, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL @@ -73,10 +73,10 @@ BEGIN EDITTEXT IDC_STATIC_ADAPTER_MODE, 95, 60, 150, 10, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL EDITTEXT IDC_STATIC_ADAPTER_MONITOR, 95, 70, 150, 10, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL GROUPBOX "Driver", IDC_STATIC, 260, 0, 197, 95 - RTEXT "Driver primar:", IDC_STATIC, 275, 10, 55, 10 + RTEXT "Driver principal:", IDC_STATIC, 275, 10, 55, 10 RTEXT "Versiune:", IDC_STATIC, 275, 20, 55, 10 RTEXT "Dată:", IDC_STATIC, 275, 30, 55, 10 - RTEXT "Semnăt. WHQL:", IDC_STATIC, 275, 40, 55, 10 + RTEXT "Logo WHQL:", IDC_STATIC, 275, 40, 55, 10 RTEXT "Mini-VDD:", IDC_STATIC, 275, 50, 55, 10 RTEXT "VDD:", IDC_STATIC, 275, 60, 55, 10 RTEXT "Versiune DDI:", IDC_STATIC, 275, 70, 55, 10 @@ -87,18 +87,18 @@ BEGIN EDITTEXT IDC_STATIC_ADAPTER_MINIVDD, 335, 50, 120, 10, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL EDITTEXT IDC_STATIC_ADAPTER_VDD, 335, 60, 120, 10, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL EDITTEXT IDC_STATIC_ADAPTER_DDI, 335, 70, 120, 10, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL - GROUPBOX "Funcționalități ReactX", IDC_STATIC, 5, 97, 452, 70 + GROUPBOX "Caracteristici ReactX", IDC_STATIC, 5, 97, 452, 70 RTEXT "Accelerare DirectDraw:", IDC_STATIC, 15, 115, 110, 12 RTEXT "Accelerare Direct3D:", IDC_STATIC, 15, 130, 110, 12 - RTEXT "Accelerare Textură AGP:", IDC_STATIC, 15, 145, 110, 12 + RTEXT "Accelerare a texturilor AGP:", IDC_STATIC, 15, 145, 110, 12 LTEXT "", IDC_STATIC_DDSTATE, 130, 115, 40, 10 LTEXT "", IDC_STATIC_D3DSTATE, 130, 130, 40, 10 LTEXT "", IDC_STATIC_AGPSTATE, 130, 145, 40, 10 - PUSHBUTTON "Activează", IDC_BUTTON_DDRAW, 170, 112, 60, 14, WS_DISABLED - PUSHBUTTON "Activează", IDC_BUTTON_D3D, 170, 128, 60, 14, WS_DISABLED - PUSHBUTTON "Activează", IDC_BUTTON_AGP, 170, 144, 60, 14, WS_DISABLED - PUSHBUTTON "Testează DirectDraw", IDC_BUTTON_TESTDD, 250, 112, 80, 14 - PUSHBUTTON "Testează Direct3D", IDC_BUTTON_TEST3D, 250, 128, 80, 14 + PUSHBUTTON "Activare", IDC_BUTTON_DDRAW, 170, 112, 60, 14, WS_DISABLED + PUSHBUTTON "Activare", IDC_BUTTON_D3D, 170, 128, 60, 14, WS_DISABLED + PUSHBUTTON "Activare", IDC_BUTTON_AGP, 170, 144, 60, 14, WS_DISABLED + PUSHBUTTON "Testare DirectDraw", IDC_BUTTON_TESTDD, 250, 112, 80, 14 + PUSHBUTTON "Testare Direct3D", IDC_BUTTON_TEST3D, 250, 128, 80, 14 GROUPBOX "Note", IDC_STATIC, 5, 170, 452, 50 EDITTEXT IDC_TEXT_INFO, 15, 182, 432, 30, ES_LEFT | WS_BORDER | ES_READONLY | WS_TABSTOP END @@ -124,7 +124,7 @@ BEGIN RTEXT "Nume:", IDC_STATIC, 275, 10, 55, 10 RTEXT "Versiune:", IDC_STATIC, 275, 20, 55, 10 RTEXT "Dată:", IDC_STATIC, 275, 30, 55, 10 - RTEXT "Semnătură WHQL:", IDC_STATIC, 275, 40, 55, 10 + RTEXT "Logo WHQL:", IDC_STATIC, 275, 40, 55, 10 RTEXT "Alte fișiere:", IDC_STATIC, 275, 50, 55, 10 RTEXT "Furnizor:", IDC_STATIC, 275, 60, 55, 10 EDITTEXT IDC_STATIC_DSOUND_DRIVER, 335, 10, 100, 10, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL @@ -133,10 +133,10 @@ BEGIN EDITTEXT IDC_STATIC_DSOUND_LOGO, 335, 40, 100, 10, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL EDITTEXT IDC_STATIC_DSOUND_FILES, 335, 50, 100, 10, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL EDITTEXT IDC_STATIC_ADAPTER_PROVIDER, 335, 60, 100, 10, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL - GROUPBOX "Funcționalități ReactX", IDC_STATIC, 5, 97, 452, 70 + GROUPBOX "Caracteristici ReactX", IDC_STATIC, 5, 97, 452, 70 CONTROL "", IDC_SLIDER_DSOUND, "msctls_trackbar32", TBS_BOTTOM | TBS_AUTOTICKS | WS_TABSTOP, 110, 125, 80, 17 - RTEXT "Echipament de sunet\nNivel de accelerare::", IDC_STATIC, 10, 125, 90, 20, WS_DISABLED - PUSHBUTTON "Testează DirectSound", IDC_BUTTON_TESTDSOUND, 270, 125, 80, 14, WS_DISABLED + RTEXT "Hardware de sunet\nNivel de accelerare:", IDC_STATIC, 10, 125, 90, 20, WS_DISABLED + PUSHBUTTON "Testare DirectSound", IDC_BUTTON_TESTDSOUND, 270, 125, 80, 14, WS_DISABLED GROUPBOX "Note", IDC_STATIC, 5, 170, 452, 50 EDITTEXT IDC_TEXT_DSOUNDINFO, 15, 182, 432, 30, ES_LEFT | WS_BORDER | ES_READONLY | WS_TABSTOP END @@ -148,13 +148,13 @@ BEGIN RTEXT "Colecție de MIDI DLS generală:", IDC_STATIC, 0, 0, 100, 10 EDITTEXT IDC_MIDI_DLS_COLLECTION, 105, 0, 250, 10, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL GROUPBOX "Porturi de muzică", IDC_STATIC, 5, 10, 452, 85 - GROUPBOX "Funcționalități ReactX", IDC_STATIC, 5, 97, 452, 70 + GROUPBOX "Caracteristici ReactX", IDC_STATIC, 5, 97, 452, 70 LTEXT "Port de accelerare implicit:", IDC_STATIC, 15, 120, 95, 17 LTEXT "", IDC_STATIC_DEFAULT_PORT_ACCELERATION, 115, 120, 50, 10 PUSHBUTTON "Dezactivează", IDC_BUTTON_DISABLEDMUSIC, 75, 135, 80, 14, WS_DISABLED LTEXT "Testare utilizare port:", IDC_STATIC, 180, 105, 100, 10 LISTBOX IDC_DMUSIC_TEST_LIST, 180, 115, 180, 45, LBS_NOINTEGRALHEIGHT | LBS_EXTENDEDSEL | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Testează DirectMusic", IDC_BUTTON_TESTDMUSIC, 370, 145, 80, 14, WS_DISABLED + PUSHBUTTON "Testare DirectMusic", IDC_BUTTON_TESTDMUSIC, 370, 145, 80, 14, WS_DISABLED GROUPBOX "Note", IDC_STATIC, 5, 170, 452, 50 EDITTEXT IDC_MUSIC_NOTES, 15, 182, 432, 30, ES_LEFT | WS_BORDER | ES_READONLY | WS_TABSTOP END @@ -176,12 +176,12 @@ IDD_NETWORK_DIALOG DIALOGEX 0, 0, 462, 220 STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN FONT 8, "MS Shell Dlg" BEGIN - GROUPBOX "Furnizori înregistrați de servicii DirectPlay", IDC_STATIC, 5, 0, 452, 75 + GROUPBOX "Furnizori de servicii DirectPlay înregistrați", IDC_STATIC, 5, 0, 452, 75 CONTROL "", IDC_LIST_PROVIDER, "SysListView32", LVS_REPORT | WS_CHILD | WS_BORDER | WS_TABSTOP, 15, 12, 432, 55 - GROUPBOX "Aplicații înregistrate pentru DirectPlay", IDC_STATIC, 5, 77, 452, 55 - GROUPBOX "Funcționalități ReactX", IDC_STATIC, 5, 133, 452, 35 + GROUPBOX "Aplicații Lobbyable DirectPlay înregistrate", IDC_STATIC, 5, 77, 452, 55 + GROUPBOX "Caracteristici ReactX", IDC_STATIC, 5, 133, 452, 35 PUSHBUTTON "Opțiuni de voce DirectPlay", IDC_BUTTON_VOICE_OPTIONS, 10, 145, 90, 14, WS_DISABLED - PUSHBUTTON "Testează DirectPlay", IDC_BUTTON_TESTDPLAY, 130, 145, 80, 14, WS_DISABLED + PUSHBUTTON "Testare DirectPlay", IDC_BUTTON_TESTDPLAY, 130, 145, 80, 14, WS_DISABLED GROUPBOX "Note", IDC_STATIC, 5, 170, 452, 50 EDITTEXT IDC_NETWORK_NOTES, 15, 182, 432, 30, ES_LEFT | WS_BORDER | ES_READONLY | WS_TABSTOP END @@ -190,73 +190,73 @@ IDD_HELP_DIALOG DIALOGEX 0, 0, 462, 220 STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN FONT 8, "MS Shell Dlg" BEGIN - LTEXT "Încă nu ați găsit informația necesară? Iată câteva lucruri suplimentare pe care le puteți face:", IDC_STATIC, 5, 0, 300, 10 + LTEXT "Încă nu găsiți informațiile pe care le căutați? Iată câteva lucruri suplimentare pe care le puteți face:", IDC_STATIC, 5, 0, 300, 10 PUSHBUTTON "Informații de sistem", IDC_BUTTON_SYSINFO, 5, 20, 80, 14, WS_DISABLED - LTEXT "Afișează informații suplimantare de sistem", IDC_STATIC, 90, 23, 300, 10 - PUSHBUTTON "Ajustează rata de împrospătare", IDC_BUTTON_DDRAW_REFRESH, 5, 40, 80, 14, WS_DISABLED - LTEXT "Ajustează rata de împrospătare pentru DirectDraw", IDC_STATIC, 90, 43, 300, 10 + LTEXT "Afișează informații suplimentare de sistem", IDC_STATIC, 90, 23, 300, 10 + PUSHBUTTON "Ajust. rata de împrosp.", IDC_BUTTON_DDRAW_REFRESH, 5, 40, 80, 14, WS_DISABLED + LTEXT "Ignoră rata de reîmprospătare pentru DirectDraw", IDC_STATIC, 90, 43, 300, 10 END STRINGTABLE BEGIN - IDS_MAIN_DIALOG "Diagnostic ReactX" + IDS_MAIN_DIALOG "Instrument de diagnosticare ReactX" IDS_SYSTEM_DIALOG "Sistem" - IDS_DISPLAY_DIALOG "Ecran" + IDS_DISPLAY_DIALOG "Afișaj" IDS_SOUND_DIALOG "Sunet" IDS_MUSIC_DIALOG "Muzică" - IDS_INPUT_DIALOG "Intrări" + IDS_INPUT_DIALOG "Intrare" IDS_NETWORK_DIALOG "Rețea" - IDS_HELP_DIALOG "Asistență" - IDS_FORMAT_MB "%I64u Mo memorie" - IDS_FORMAT_SWAP "%I64u Mo utilizată, %I64u Mo disponibilă" - IDS_FORMAT_UNIPROC "%s (%u procesor)" - IDS_FORMAT_MPPROC "%s (%u procesoare)" - IDS_VERSION_UNKNOWN "Versiune neidentificată" + IDS_HELP_DIALOG "Ajutor" + IDS_FORMAT_MB "%I64uMB de RAM" + IDS_FORMAT_SWAP "%I64u (de) MB folosit (folosiți), %I64u (de) MB disponibil(i)" + IDS_FORMAT_UNIPROC "%s (%u CPU)" + IDS_FORMAT_MPPROC "%s (%u CPUs)" + IDS_VERSION_UNKNOWN "Versiune necunoscută" IDS_DEVICE_STATUS_ATTACHED "Conectat" IDS_DEVICE_STATUS_MISSING "Deconectat" - IDS_DEVICE_STATUS_UNKNOWN "Neidentificat" - IDS_DEVICE_NAME "Nume dispozitiv" + IDS_DEVICE_STATUS_UNKNOWN "Necunoscut" + IDS_DEVICE_NAME "Numele dispozitivului" IDS_DEVICE_STATUS "Stare" - IDS_DEVICE_CONTROLLER "ID controlor" - IDS_DEVICE_MANUFACTURER "ID producător" - IDS_DEVICE_PRODUCT "ID produs" - IDS_DEVICE_FORCEFEEDBACK "Forțează reacția driverului" + IDS_DEVICE_CONTROLLER "ID controller-ului" + IDS_DEVICE_MANUFACTURER "ID-ul producătorului" + IDS_DEVICE_PRODUCT "ID-ul produsului" + IDS_DEVICE_FORCEFEEDBACK "Forțare a driverului de feedback" IDS_NOT_APPLICABLE "n/a" IDS_OPTION_YES "Da" IDS_DIRECTPLAY_COL_NAME1 "Nume" IDS_DIRECTPLAY_COL_NAME2 "Registru" IDS_DIRECTPLAY_COL_NAME3 "Fișier" IDS_DIRECTPLAY_COL_NAME4 "Versiune" - IDS_DIRECTPLAY8_MODEMSP "Furnizor de serviciu Modem-DirectPlay8" - IDS_DIRECTPLAY8_SERIALSP "Furnizor de serviciu Serial-DirectPlay8" - IDS_DIRECTPLAY8_IPXSP "Furnizor de serviciu IPX-DirectPlay8" - IDS_DIRECTPLAY8_TCPSP "Furnizor de serviciu TCP/IP-DirectPlay8" + IDS_DIRECTPLAY8_MODEMSP "Furnizor de servicii de modem DirectPlay8" + IDS_DIRECTPLAY8_SERIALSP "Furnizor de servicii seriale DirectPlay8" + IDS_DIRECTPLAY8_IPXSP "Furnizor de servicii DirectPlay8 IPX" + IDS_DIRECTPLAY8_TCPSP "DirectPlay8 TCP/IP Service Provider" IDS_DIRECTPLAY_TCPCONN "Conexiune de Internet TCP/IP pentru DirectPlay" IDS_DIRECTPLAY_IPXCONN "Conexiune IPX pentru DirectPlay" - IDS_DIRECTPLAY_MODEMCONN "Conexiune Modem pentru DirectPlay" - IDS_DIRECTPLAY_SERIALCONN "Conexiune Serială pentru DirectPlay" - IDS_REG_SUCCESS "Î&nchide" + IDS_DIRECTPLAY_MODEMCONN "Conexiune de modem pentru DirectPlay" + IDS_DIRECTPLAY_SERIALCONN "Conexiune serială pentru DirectPlay" + IDS_REG_SUCCESS "OK" IDS_REG_FAIL "Eroare" - IDS_DDTEST_ERROR "Testul a eșuat!" - IDS_DDTEST_DESCRIPTION "Urmează testele de interfață DirectDraw. Continuați?" - IDS_DDPRIMARY_DESCRIPTION "Testul următor va utiliza DirectDraw pentru a desena dreptunghiuri albe și negre pe suprafața primară. Continuați?" - IDS_DDPRIMARY_RESULT "Dreptunghiurile albe și negre au fost vizibile?" - IDS_DDOFFSCREEN_DESCRIPTION "Testul următor va utiliza DirectDraw pentru desenarea unui dreptunghi alb în mișcare utilizând o memorie tampon din afara ecranului. Continuați?" - IDS_DDOFFSCREEN_RESULT "Dreptunghiul alb în mișcare a fost vizibil?" - IDS_DDFULLSCREEN_DESCRIPTION "Testul următor va utiliza DirectDraw pentru desenarea unui dreptunghi alb în mișcare utilizând tot ecranul. Continuați?" - IDS_DDFULLSCREEN_RESULT "Pe ecranul complet, dreptunghiul alb în mișcare a fost vizibil?" - IDS_FORMAT_ADAPTER_MEM "%u Mo" - IDS_FORMAT_ADAPTER_MODE "%d x %d (%u biți)(%uHz)" + IDS_DDTEST_ERROR "Testul de randare DirectDraw a eșuat.\nVă rugăm să consultați notele pentru mai multe informații." + IDS_DDTEST_DESCRIPTION "Acesta va porni testarea interfeței DirectDraw. Doriți să continuați?" + IDS_DDPRIMARY_DESCRIPTION "Acest test va folosi DirectDraw pentru a desena pe suprafața principală.\nAr trebui desenate dreptunghiuri alb-negru. Doriți să continuați?" + IDS_DDPRIMARY_RESULT "Ați văzut dreptunghiuri alb-negru?" + IDS_DDOFFSCREEN_DESCRIPTION "Acest test va folosi DirectDraw pentru a desena un tampon în afara ecranului. Ar trebui desenat un dreptunghi alb în mișcare. Doriți să continuați?" + IDS_DDOFFSCREEN_RESULT "Ați văzut dreptunghi alb în mișcare?" + IDS_DDFULLSCREEN_DESCRIPTION "Acest test va folosi DirectDraw pentru a desena în modul ecran complet. Ar trebui desenat un dreptunghi alb în mișcare. Doriți să continuați?" + IDS_DDFULLSCREEN_RESULT "Ați văzut dreptunghi alb în mișcare în modul ecran complet?" + IDS_FORMAT_ADAPTER_MEM "%u (de) MB" + IDS_FORMAT_ADAPTER_MODE "%d x %d (%u (de) biți)(%uHz)" IDS_OPTION_NO "Nu" - IDS_D3DTEST_DESCRIPTION "Urmează testul de interfață Direct3D. Continuați?" - IDS_D3DTEST_D3Dx "Testul următor va utiliza interfața Direct3D %u cu accelerare de echipament fizic." - IDS_OS_VERSION "%s %s (%d.%d, Build %d)" + IDS_D3DTEST_DESCRIPTION "Acesta va porni testarea interfeței Direct3D. Doriți să continuați?" + IDS_D3DTEST_D3Dx "Acest test va folosi interfața Direct3D %u accelerată hardware." + IDS_OS_VERSION "%s %s (%d.%d, Subversiunea %d)" IDS_DMUSIC_DESC "Descriere" IDS_DMUSIC_TYPE "Tip" - IDS_DMUSIC_KERNEL "Mod nucleu" - IDS_DMUSIC_IO "In/Ex" - IDS_DMUSIC_DLS "DLS de suport" + IDS_DMUSIC_KERNEL "Modul nucleu" + IDS_DMUSIC_IO "I/E" + IDS_DMUSIC_DLS "Suportă DLS" IDS_DMUSIC_EXT "Extern" IDS_DMUSIC_PORT "Port implicit" - IDS_DDDISABLE_MSG "Accelerările fizice DirectDraw vor fi dezactivate pentru toate dispozitivele.\nDoriți să continuați?\n" + IDS_DDDISABLE_MSG "Acesta va dezactiva toată accelerarea hardware pentru DirectDraw pe toate dispozitivele de afișare.\nDoriți să continuați?\n" END diff --git a/base/applications/extrac32/CMakeLists.txt b/base/applications/extrac32/CMakeLists.txt index 50f6ca75a2bcb..986b4e63a6a1a 100644 --- a/base/applications/extrac32/CMakeLists.txt +++ b/base/applications/extrac32/CMakeLists.txt @@ -1,7 +1,7 @@ -add_definitions(-D__WINESRC__) add_executable(extrac32 extrac32.c) target_link_libraries(extrac32 wine) set_module_type(extrac32 win32gui UNICODE) add_importlibs(extrac32 shell32 setupapi shlwapi user32 msvcrt kernel32 ntdll) add_cd_file(TARGET extrac32 DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(extrac32) # CORE-5743: No ARRAY_SIZE macro diff --git a/base/applications/findstr/findstr.rc b/base/applications/findstr/findstr.rc index d9feacff659e2..d48278a41ba55 100644 --- a/base/applications/findstr/findstr.rc +++ b/base/applications/findstr/findstr.rc @@ -40,6 +40,9 @@ #ifdef LANGUAGE_IT_IT #include "lang/it-IT.rc" #endif +#ifdef LANGUAGE_JA_JP + #include "lang/ja-JP.rc" +#endif #ifdef LANGUAGE_LT_LT #include "lang/lt-LT.rc" #endif diff --git a/base/applications/findstr/lang/ja-JP.rc b/base/applications/findstr/lang/ja-JP.rc new file mode 100644 index 0000000000000..aafec23884089 --- /dev/null +++ b/base/applications/findstr/lang/ja-JP.rc @@ -0,0 +1,13 @@ +LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT + +STRINGTABLE +BEGIN + IDS_USAGE "FINDSTR: 文字列を含むファイルのすべての行を出力します。\n\n\ + FIND [ /C ] [ /I ] [ /N ] [ /V ] ""文字列"" [ ファイル... ]\n\ + /C 文字列を含む行の個数を数えます\n\ + /I 大文字小文字を無視します\n\ + /N 表示される行に1から番号を付けます\n\ + /V 文字列を含まない行を出力します" + IDS_NO_SUCH_FILE "FINDSTR: %s: そのようなファイルはありません\n" + IDS_CANNOT_OPEN "FINDSTR: %s: ファイルが開けません\n" +END diff --git a/base/applications/fontview/lang/fr-FR.rc b/base/applications/fontview/lang/fr-FR.rc index 1588ba4ca6b30..e1c56ae47b7a1 100644 --- a/base/applications/fontview/lang/fr-FR.rc +++ b/base/applications/fontview/lang/fr-FR.rc @@ -18,12 +18,12 @@ BEGIN IDS_ERROR_NOMEM "Mémoire insuffisante pour terminer l'opération." IDS_ERROR_NOFONT "Le fichier %1 n'est pas un fichier de polices valide." IDS_ERROR_NOCLASS "Impossible d'initialiser la classe de fenêtre." - IDS_ERROR_ISINSTALLED "This font is already installed!" - IDS_ERROR_FONTCPY "Failed to copy the font file!" - IDS_ERROR_OPENKEY "Failed to open the fonts registry key!" - IDS_ERROR_REGISTER "Failed to register the new font!" - IDS_SUCCESS "Success" - IDS_COMPLETED "Font installation completed." + IDS_ERROR_ISINSTALLED "Cette police est déjà installée !" + IDS_ERROR_FONTCPY "Échec lors de la copie du fichier police !" + IDS_ERROR_OPENKEY "Échec lors de l'ouverture de la clé de registre de la police !" + IDS_ERROR_REGISTER "Échec lors de l'enregistrement de la nouvelle police !" + IDS_SUCCESS "Succès" + IDS_COMPLETED "Installation de la police effectuée." IDS_FILTER_LIST "Toutes polices supportées (*.fon;*.fnt;*.ttf;*.ttc;*.otf;*.otc)\0*.fon;*.fnt;*.ttf;*.ttc;*.otf;*.otc\0\ Fichier de polices (*.fon;*.fnt)\0*.fon;*.fnt\0\ Fichier de polices TrueType (*.ttf)\0*.ttf\0\ diff --git a/base/applications/games/solitaire/ReadMe.txt b/base/applications/games/solitaire/ReadMe.txt index c4f60d8b42d2d..ddcafd2a153c7 100644 --- a/base/applications/games/solitaire/ReadMe.txt +++ b/base/applications/games/solitaire/ReadMe.txt @@ -7,7 +7,7 @@ card-game library. Freeware Copyright J Brown 2001 -Updates at http://www.catch22.net +Updates at https://www.catch22.net/ ******************************************/ diff --git a/base/applications/games/solitaire/lang/cs-CZ.rc b/base/applications/games/solitaire/lang/cs-CZ.rc index 3acd94595fa28..4b4e6baa0a51f 100644 --- a/base/applications/games/solitaire/lang/cs-CZ.rc +++ b/base/applications/games/solitaire/lang/cs-CZ.rc @@ -1,7 +1,11 @@ -/* FILE: applications/games/solitaire/lang/cs-CZ.rc - * PURPOSE: Czech Language File - * TRANSLATOR: Radek Liska aka Black_Fox (radekliska at gmail dot com) - * UPDATED: 2008-11-30 by Kario +/* + * PROJECT: ReactOS Solitaire + * LICENSE: Freeware, permission to use under Public Domain + * PURPOSE: Czech resource file + * TRANSLATORS: Copyright 2008 Radek Liška (Black_Fox) + * Copyright 2008 Mário Kačmár + * Copyright 2011-2017 Kamil Horníček + * Copyright 2024 Václav Zouzalík (Venca24) */ LANGUAGE LANG_CZECH, SUBLANG_DEFAULT @@ -13,13 +17,13 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_SHELLFONT CAPTION "Možnosti" FONT 8, "MS Shell Dlg" BEGIN - GROUPBOX "Karty", -1, 7, 7, 90, 40 + GROUPBOX "Sejmout", -1, 7, 7, 90, 40 AUTORADIOBUTTON "Sejmout &jednu", IDC_OPT_DRAWONE, 14, 19, 70, 10, WS_GROUP | WS_TABSTOP AUTORADIOBUTTON "Sejmout &tři", IDC_OPT_DRAWTHREE, 14, 32, 70, 10 - GROUPBOX "Scoring", -1, 100, 7, 75, 53 + GROUPBOX "Skórování", -1, 100, 7, 75, 53 AUTORADIOBUTTON "&Standard", IDC_OPT_STANDARD, 107, 19, 60, 10, WS_GROUP | WS_TABSTOP AUTORADIOBUTTON "&Vegas", IDC_OPT_VEGAS, 107, 32, 60, 10 - AUTORADIOBUTTON "&None", IDC_OPT_NOSCORE, 107, 45, 60, 10 + AUTORADIOBUTTON "Žá&dné", IDC_OPT_NOSCORE, 107, 45, 60, 10 AUTOCHECKBOX "Zobrazit č&as", IDC_OPT_SHOWTIME, 7 ,51 ,65 ,10, WS_TABSTOP AUTOCHECKBOX "Stavový řád&ek", IDC_OPT_STATUSBAR, 7, 66, 64, 10, WS_TABSTOP AUTOCHECKBOX "&Ponechat skóre", IDC_OPT_KEEPSCORE, 100, 66, 65, 10, WS_TABSTOP @@ -55,7 +59,7 @@ BEGIN IDS_SOL_NAME "Solitaire" IDS_SOL_ABOUT "Solitaire by J Brown\nCardLib verze 1.0" IDS_SOL_QUIT "Ukončit rozehranou hru?" - IDS_SOL_WIN "Gratulujeme, zvítězili jste!!" + IDS_SOL_WIN "Gratulujeme, zvítězili jste!" IDS_SOL_DEAL "Rozdat znova?" IDS_SOL_SCORE "Skóre: %d" IDS_SOL_TIME "Čas: %d" @@ -69,8 +73,8 @@ BEGIN BEGIN MENUITEM "&Rozdat\tF2", IDM_GAME_NEW MENUITEM SEPARATOR - MENUITEM "&Undo", IDM_GAME_UNDO, GRAYED - MENUITEM "Rub& karet...", IDM_GAME_DECK + MENUITEM "&Zpět", IDM_GAME_UNDO, GRAYED + MENUITEM "Ru&b karet...", IDM_GAME_DECK MENUITEM "&Možnosti...", IDM_GAME_OPTIONS MENUITEM SEPARATOR MENUITEM "&Konec", IDM_GAME_EXIT diff --git a/base/applications/mplay32/lang/fr-FR.rc b/base/applications/mplay32/lang/fr-FR.rc index 90fc3e35773a0..acfb862474710 100644 --- a/base/applications/mplay32/lang/fr-FR.rc +++ b/base/applications/mplay32/lang/fr-FR.rc @@ -18,7 +18,7 @@ BEGIN END POPUP "&View" BEGIN - MENUITEM "Single-Window &Mode", IDM_SWITCHVIEW + MENUITEM "&Mode fenêtre unique", IDM_SWITCHVIEW END POPUP "Périp&hérique" BEGIN diff --git a/base/applications/mplay32/lang/ja-JP.rc b/base/applications/mplay32/lang/ja-JP.rc index dea9998812db1..a3e31f27faa80 100644 --- a/base/applications/mplay32/lang/ja-JP.rc +++ b/base/applications/mplay32/lang/ja-JP.rc @@ -9,23 +9,23 @@ BEGIN MENUITEM SEPARATOR MENUITEM "終了(&E)", IDM_EXIT END - POPUP "&Play" + POPUP "再生(&P)" BEGIN - MENUITEM "Play/&Pause\tCtrl+P", IDC_PLAY - MENUITEM "St&op\tCtrl+S", IDC_STOP + MENUITEM "再生/再開(&P)\tCtrl+P", IDC_PLAY + MENUITEM "停止(&O)\tCtrl+S", IDC_STOP MENUITEM SEPARATOR - MENUITEM "Repea&t\tCtrl+T", IDM_REPEAT + MENUITEM "リピート(&T)\tCtrl+T", IDM_REPEAT END - POPUP "&View" + POPUP "表示(&V)" BEGIN - MENUITEM "Single-Window &Mode", IDM_SWITCHVIEW + MENUITEM "単一ウィンドウモード(&M)", IDM_SWITCHVIEW END - POPUP "&Device" + POPUP "デバイス(&D)" BEGIN MENUITEM SEPARATOR - MENUITEM "&Properties", IDM_DEVPROPS + MENUITEM "プロパティ(&P)", IDM_DEVPROPS MENUITEM SEPARATOR - MENUITEM "&Volume Control", IDM_VOLUMECTL + MENUITEM "音量調節(&V)", IDM_VOLUMECTL END POPUP "ヘルプ(&H)" BEGIN @@ -44,14 +44,14 @@ END STRINGTABLE BEGIN - IDS_MODE_UNKNOWN "Unknown" - IDS_MODE_OPEN "Opened" - IDS_MODE_STOP "Stopped" - IDS_MODE_PLAY "Playing" - IDS_MODE_PAUSE "Paused" - IDS_MODE_RECORD "Recording" - IDS_MODE_SEEK "Seeking" - IDS_MODE_NOT_READY "Not ready" + IDS_MODE_UNKNOWN "不明" + IDS_MODE_OPEN "開きました" + IDS_MODE_STOP "停止中" + IDS_MODE_PLAY "再生中" + IDS_MODE_PAUSE "一時停止中" + IDS_MODE_RECORD "録音中" + IDS_MODE_SEEK "シーク中" + IDS_MODE_NOT_READY "準備ができていません" IDS_ALL_TYPES_FILTER "すべてのサポートされたファイル" IDS_TOOLTIP_PLAY "再生" IDS_TOOLTIP_STOP "停止" @@ -60,8 +60,8 @@ BEGIN IDS_TOOLTIP_SEEKBACK "後ろへシーク" IDS_TOOLTIP_SEEKFORW "前へシーク" IDS_TOOLTIP_FORWARD "前へスキップ" - IDS_TOOLTIP_PAUSE "Pause" + IDS_TOOLTIP_PAUSE "一時停止" IDS_APPTITLE "ReactOS マルチメディア プレーヤー" IDS_PLAY "再生" - IDS_DEFAULTMCIERRMSG "No description is available for this error." + IDS_DEFAULTMCIERRMSG "このエラーの説明はありません。" END diff --git a/base/applications/msconfig/lang/ja-JP.rc b/base/applications/msconfig/lang/ja-JP.rc new file mode 100644 index 0000000000000..b1de888d3f2b5 --- /dev/null +++ b/base/applications/msconfig/lang/ja-JP.rc @@ -0,0 +1,171 @@ +LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT + +IDD_MSCONFIG_DIALOG DIALOGEX 0, 0, 378, 220 +STYLE DS_SHELLFONT | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | + WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU +CAPTION "システム構成プログラム" +FONT 9, "MS UI Gothic" +BEGIN + CONTROL "Tab1", IDC_TAB, "SysTabControl32", WS_TABSTOP, 2, 2, 374, 195 + DEFPUSHBUTTON "OK", IDOK, 211, 201, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP + PUSHBUTTON "ヘルプ(&H)", IDC_BTN_HELP, 2, 201, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP + PUSHBUTTON "キャンセル", IDCANCEL, 267, 201, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP + PUSHBUTTON "適用", IDC_BTN_APPLY, 323, 201, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP +END + +IDD_STARTUP_PAGE DIALOGEX 0, 0, 362, 175 +STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN +FONT 9, "MS UI Gothic" +BEGIN + CONTROL "List3", IDC_STARTUP_LIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | + LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP, 2, 1, 360, 148 + PUSHBUTTON "すべて有効化(&A)", IDC_BTN_STARTUP_ACTIVATE, 223, 155, 66, 14 + PUSHBUTTON "すべて無効化(&D)", IDC_BTN_STARTUP_DEACTIVATE, 295, 155, 66, 14 +END + +IDD_SYSTEM_PAGE DIALOGEX 0, 0, 362, 175 +STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN +FONT 9, "MS UI Gothic" +BEGIN + CONTROL "", IDC_SYSTEM_TREE, "SysTreeView32", TVS_HASBUTTONS | TVS_HASLINES | + TVS_LINESATROOT | TVS_EDITLABELS | TVS_SHOWSELALWAYS | WS_CHILD | + WS_VISIBLE | WS_BORDER | WS_TABSTOP, 2, 1, 280, 148 + PUSHBUTTON "上へ(&U)", IDC_BTN_SYSTEM_UP, 290, 5, 66, 14 + PUSHBUTTON "下へ(&D)", IDC_BTN_SYSTEM_DOWN, 290, 25, 66, 14 + PUSHBUTTON "有効化(&E)", IDC_BTN_SYSTEM_ENABLE, 290, 50, 66, 14 + PUSHBUTTON "無効化(&I)", IDC_BTN_SYSTEM_DISABLE, 290, 70, 66, 14 + PUSHBUTTON "検索(&F)", IDC_BTN_SYSTEM_FIND, 290, 95, 66, 14 + PUSHBUTTON "新規(&N)", IDC_BTN_SYSTEM_NEW, 290, 115, 66, 14 + PUSHBUTTON "編集(&T)", IDC_BTN_SYSTEM_EDIT, 290, 135, 66, 14 + PUSHBUTTON "すべて有効化(&B)", IDC_BTN_SYSTEM_ACTIVATE, 123, 155, 66, 14 + PUSHBUTTON "すべて無効化(&L)", IDC_BTN_SYSTEM_DEACTIVATE, 195, 155, 66, 14 +END + +IDD_TOOLS_PAGE DIALOGEX 0, 0, 362, 175 +STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN +FONT 9, "MS UI Gothic" +BEGIN + CONTROL "List2", IDC_TOOLS_LIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | + LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP, 2, 1, 360, 134 + EDITTEXT IDC_TOOLS_CMDLINE, 1, 139, 360, 12, ES_READONLY + PUSHBUTTON "実行(&R)", IDC_BTN_RUN, 311, 155, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP +END + +IDD_SERVICES_PAGE DIALOGEX 0, 0, 362, 175 +STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN +FONT 9, "MS UI Gothic" +BEGIN + CONTROL "List1", IDC_SERVICES_LIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | + LVS_SHOWSELALWAYS | LVS_SORTASCENDING | WS_BORDER | WS_TABSTOP, 2, 1, 360, 148 + PUSHBUTTON "すべて有効化(&A)", IDC_BTN_SERVICES_ACTIVATE, 223, 155, 66, 14 + PUSHBUTTON "すべて無効化(&D)", IDC_BTN_SERVICES_DEACTIVATE, 295, 155, 66, 14 +END + +IDD_GENERAL_PAGE DIALOGEX 0, 0, 362, 175 +STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN +FONT 9, "MS UI Gothic" +BEGIN + GROUPBOX "起動の種類の選択", -1, 10, 10, 340, 150, 0, WS_EX_TRANSPARENT + CONTROL "通常起動(&N) - すべてのデバイスドライバとサービスを読み込む", IDC_CBX_NORMAL_START, "Button", 0x50010009, 20, 30, 260, 10 + CONTROL "診断的起動(&D) - 基本的なデバイスとサービスのみを読み込む", IDC_CBX_DIAGNOSTIC_START, "Button", 0x50010009, 20, 45, 260, 10 + CONTROL "選択的起動(&E)", IDC_CBX_SELECTIVE_STARTUP, "Button", 0x50010009, 20, 60, 260, 10 + AUTOCHECKBOX "ファイル SYSTEM.INI を処理(&R)", IDC_CBX_SYSTEM_INI, 30, 80, 260, 10 + AUTOCHECKBOX "システムサービスの読み込み(&L)", IDC_CBX_SYSTEM_SERVICE, 30, 95, 260, 10 + AUTOCHECKBOX "スタートアップ項目を読み込む(&O)", IDC_CBX_STARTUP_ITEM, 30, 110, 260, 10 +END + +IDD_FREELDR_PAGE DIALOGEX 0, 0, 362, 175 +STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN +FONT 9, "MS UI Gothic" +BEGIN + LISTBOX IDC_LIST_BOX, 10, 10, 340, 50, WS_CHILD | WS_VISIBLE | WS_TABSTOP | + LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_HSCROLL + PUSHBUTTON "すべての起動パスを確認する(&C)", IDC_BTN_CHECK_BOOT_PATH, 10, 65, 70, 12 + PUSHBUTTON "デフォルトにする(&S)", IDC_BTN_SET_DEFAULT_BOOT, 100, 65, 70, 12 + PUSHBUTTON "上へ(&U)", IDC_BTN_MOVE_UP_BOOT_OPTION, 190, 65, 70, 12 + PUSHBUTTON "下へ(&D)", IDC_BTN_MOVE_DOWN_BOOT_OPTION, 280, 65, 70, 12 + GROUPBOX "起動オプション", -1, 10, 80, 250, 90, 0, WS_EX_TRANSPARENT + CHECKBOX "/SA&FEBOOT", IDC_CBX_SAFE_BOOT, 15, 90, 55, 10 + CHECKBOX "/&NOGUIBOOT", IDC_CBX_NO_GUI_BOOT, 15, 105, 60, 10 + CHECKBOX "/&BOOTLOG", IDC_CBX_BOOT_LOG, 15, 120, 50, 10 + CHECKBOX "/BAS&EVIDEO", IDC_CBX_BASE_VIDEO, 15, 135, 55, 10 + CHECKBOX "/S&OS", IDC_CBX_SOS, 15, 150, 50, 10 + PUSHBUTTON "詳細オプション(&V)...", IDC_BTN_ADVANCED_OPTIONS, 100, 150, 70, 12 + LTEXT "タイムアウト(&T):", -1, 280, 91, 30, 10 + EDITTEXT IDC_TXT_BOOT_TIMEOUT, 310, 90, 25, 12, ES_LEFT + LTEXT "秒", -1, 340, 91, 15, 10 +END + +IDD_FREELDR_ADVANCED_PAGE DIALOGEX 0, 0, 175, 175 +STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN +FONT 9, "MS UI Gothic" +BEGIN + CHECKBOX "/&MAXMEM=", IDC_CBX_MAX_MEM, 10, 10, 50, 10 + EDITTEXT IDC_TXT_MAX_MEM, 80, 10, 60, 12 + CONTROL "", IDC_SCR_MAX_MEM, "msctls_updown32", 0x50000000, 140, 10, 11, 11 + CHECKBOX "/&NUMPROC=", IDC_CBX_NUM_PROC, 10, 25, 50, 10 + COMBOBOX IDC_DRP_NUM_PROC, 80, 25, 60, 10, CBS_DROPDOWNLIST | CBS_SORT | WS_CHILD | WS_VISIBLE | WS_TABSTOP + CHECKBOX "/&PCILOCK", IDC_CBX_PCI_LOCK, 10, 40, 50, 10 + CHECKBOX "/P&ROFILE", IDC_CBX_PROFILE, 10, 55, 50, 10 + CHECKBOX "/&IRQ", IDC_CBX_IRQ, 10, 70, 40, 12 + EDITTEXT IDC_TXT_IRQ, 80, 70, 60, 12, ES_LEFT + CHECKBOX "/&DEBUG", IDC_CBX_DEBUG, 10, 85, 40, 10 + CHECKBOX "/D&EBUGPORT", IDC_CBX_DEBUG_PORT, 20, 100, 60, 10 + COMBOBOX IDC_DRP_DEBUG_PORT, 80, 100, 60, 10, CBS_DROPDOWNLIST | CBS_SORT | WS_CHILD | WS_VISIBLE | WS_TABSTOP + CHECKBOX "/&BAUDRATE", IDC_CBX_BAUD_RATE, 20, 115, 50, 10 + COMBOBOX IDC_DRP_DRP_BAUD_RATE, 80, 115, 60, 10, CBS_DROPDOWNLIST | CBS_SORT | WS_CHILD | WS_VISIBLE | WS_TABSTOP + CHECKBOX "/&CHANNEL", IDC_CBX_CHANNEL, 20, 130, 50, 10 + EDITTEXT IDC_TXT_CHANNEL, 80, 130, 60, 12, ES_LEFT + CONTROL "", IDC_SCR_CHANNEL, "msctls_updown32", 0x50000000, 140, 130, 11, 11 + PUSHBUTTON "OK", IDC_OK, 20, 160, 50, 12 + PUSHBUTTON "キャンセル", IDC_CANCEL, 100, 160, 50, 12 +END + +STRINGTABLE +BEGIN + IDS_MSCONFIG "システム構成プログラム" + IDS_TAB_GENERAL "一般" + IDS_TAB_SYSTEM "SYSTEM.INI" + IDS_TAB_FREELDR "FREELDR.INI" + IDS_TAB_SERVICES "サービス" + IDS_TAB_STARTUP "スタートアップ" + IDS_TAB_TOOLS "ツール" +END + +STRINGTABLE +BEGIN + IDS_SERVICES_COLUMN_SERVICE "サービス" + IDS_SERVICES_COLUMN_REQ "必要" + IDS_SERVICES_COLUMN_VENDOR "ベンダー" + IDS_SERVICES_COLUMN_STATUS "状態" +END + +STRINGTABLE +BEGIN + IDS_TOOLS_COLUMN_NAME "名前" + IDS_TOOLS_COLUMN_DESCR "説明" + IDS_TOOLS_CMD_NAME "コンソール" + IDS_TOOLS_CMD_DESCR "" + IDS_TOOLS_CMD_CMD "cmd.exe" + IDS_TOOLS_INFO_NAME "バージョン" + IDS_TOOLS_INFO_DESCR "バージョン情報を表示します。" + IDS_TOOLS_INFO_CMD "winver.exe" + IDS_TOOLS_REGEDIT_NAME "レジストリ エディタ" + IDS_TOOLS_REGEDIT_DESCR "レジストリ エディタを開きます。" + IDS_TOOLS_REGEDIT_CMD "regedit.exe" + IDS_TOOLS_SYSDM_NAME "システムプロパティ" + IDS_TOOLS_SYSDM_DESCR "このコンピューターに関する情報を表示します。" + IDS_TOOLS_SYSDM_CMD "control.exe" + IDS_TOOLS_SYSDM_PARAM "sysdm.cpl" + IDS_STARTUP_COLUMN_ELEMENT "要素" + IDS_STARTUP_COLUMN_CMD "コマンド" + IDS_STARTUP_COLUMN_PATH "パス" +END + +STRINGTABLE +BEGIN + IDS_SERVICES_STATUS_RUNNING "実行中" + IDS_SERVICES_STATUS_STOPPED "停止" + IDS_SERVICES_YES "はい" + IDS_SERVICES_UNKNOWN "不明" +END diff --git a/base/applications/msconfig/msconfig.rc b/base/applications/msconfig/msconfig.rc index cf705711972fe..a780a1ddacf54 100644 --- a/base/applications/msconfig/msconfig.rc +++ b/base/applications/msconfig/msconfig.rc @@ -54,6 +54,9 @@ IDI_APPICON ICON "res/msconfig.ico" #ifdef LANGUAGE_IT_IT #include "lang/it-IT.rc" #endif +#ifdef LANGUAGE_JA_JP + #include "lang/ja-JP.rc" +#endif #ifdef LANGUAGE_KO_KR #include "lang/ko-KR.rc" #endif diff --git a/base/applications/msconfig_new/comctl32ex/comctl32supp.c b/base/applications/msconfig_new/comctl32ex/comctl32supp.c index 20a5c3d90fa67..49e77f867bdd5 100644 --- a/base/applications/msconfig_new/comctl32ex/comctl32supp.c +++ b/base/applications/msconfig_new/comctl32ex/comctl32supp.c @@ -28,7 +28,7 @@ HRESULT GetComCtl32Version(OUT PDWORD pdwMajor, OUT PDWORD pdwMinor, OUT PDWORD */ /* - * See: https://msdn.microsoft.com/en-us/library/windows/desktop/hh298349(v=vs.85).aspx + * See: https://learn.microsoft.com/en-us/windows/win32/controls/common-control-versions * and: http://www.geoffchappell.com/studies/windows/shell/comctl32/history/ * for the possible version values to be returned. */ diff --git a/base/applications/msconfig_new/lang/fr-FR.rc b/base/applications/msconfig_new/lang/fr-FR.rc index 4633296f3d976..766b2e3890688 100644 --- a/base/applications/msconfig_new/lang/fr-FR.rc +++ b/base/applications/msconfig_new/lang/fr-FR.rc @@ -28,11 +28,11 @@ BEGIN CONTROL "Exécuter le fichier &WIN.INI", IDC_CBX_WIN_INI, "Button", BS_AUTO3STATE | WS_TABSTOP, 35, 98, 316, 10 CONTROL "C&harger les services système", IDC_CBX_LOAD_SYSTEM_SERVICES, "Button", BS_AUTO3STATE | WS_TABSTOP, 35, 110, 316, 10 CONTROL "&Charger les éléments de démarrage", IDC_CBX_LOAD_STARTUP_ITEMS, "Button", BS_AUTO3STATE | WS_TABSTOP, 35, 122, 316, 10 - CONTROL "&Utiliser la configuration de démarrage d’origine", IDC_CBX_USE_ORIGINAL_BOOTCFG, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 35, 134, 316, 10 + CONTROL "&Utiliser la configuration de démarrage d'origine", IDC_CBX_USE_ORIGINAL_BOOTCFG, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 35, 134, 316, 10 PUSHBUTTON "Exéc&uter la restauration du système", IDC_BTN_SYSTEM_RESTORE_START, 146, 156, 124, 14 PUSHBUTTON "E&xtraire le fichier...", IDC_BTN_FILE_EXTRACTION, 275, 156, 85, 14 GROUPBOX "Sélection du mode de démarrage ", IDC_STATIC, 5, 5, 356, 145 - LTEXT "Charger tous les pilotes de périphériques et tous les services", IDC_STATIC, 25, 30, 322, 10 + LTEXT "Charger tous les pilotes de périphérique et tous les services", IDC_STATIC, 25, 30, 322, 10 LTEXT "Charger seulement les pilotes de périphérique et les services de base", IDC_STATIC, 25, 58, 322, 10 END diff --git a/base/applications/msconfig_new/systempage.cpp b/base/applications/msconfig_new/systempage.cpp index fb9483dc3febf..f5399c1cae383 100644 --- a/base/applications/msconfig_new/systempage.cpp +++ b/base/applications/msconfig_new/systempage.cpp @@ -717,7 +717,7 @@ CommonWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) /* * Ehh yes, we have to deal with a "dialog proc", which is quite different from a "window proc": * - * (excerpt from: MSDN library http://msdn.microsoft.com/en-us/library/ms645469(VS.85).aspx) + * (excerpt from: MSDN library https://learn.microsoft.com/en-us/windows/win32/api/winuser/nc-winuser-dlgproc) * * Return Value * ============ diff --git a/base/applications/msconfig_new/utils.c b/base/applications/msconfig_new/utils.c index fc797ffe96d52..901e6802ffb60 100644 --- a/base/applications/msconfig_new/utils.c +++ b/base/applications/msconfig_new/utils.c @@ -155,7 +155,7 @@ RunCommand(IN LPCWSTR lpszCommand, //////////////////// The following comes from MSDN samples /////////////////// -// https://msdn.microsoft.com/en-us/library/windows/desktop/dd162826(v=vs.85).aspx +// https://learn.microsoft.com/en-us/windows/win32/gdi/positioning-objects-on-a-multiple-display-setup // // diff --git a/base/applications/msconfig_new/utils.h b/base/applications/msconfig_new/utils.h index 9fb97011ef271..8fcee47063aff 100644 --- a/base/applications/msconfig_new/utils.h +++ b/base/applications/msconfig_new/utils.h @@ -58,7 +58,7 @@ RunCommand(IN LPCWSTR lpszCommand, //////////////////// The following comes from MSDN samples /////////////////// -// https://msdn.microsoft.com/en-us/library/windows/desktop/dd162826(v=vs.85).aspx +// https://learn.microsoft.com/en-us/windows/win32/gdi/positioning-objects-on-a-multiple-display-setup // // diff --git a/base/applications/mscutils/eventvwr/eventvwr.c b/base/applications/mscutils/eventvwr/eventvwr.c index 0e356afd7d635..87be9a337b37a 100644 --- a/base/applications/mscutils/eventvwr/eventvwr.c +++ b/base/applications/mscutils/eventvwr/eventvwr.c @@ -908,7 +908,7 @@ ApplyParameterStringsToMessage( { /* * This code is heavily adapted from the MSDN example: - * https://msdn.microsoft.com/en-us/library/windows/desktop/bb427356.aspx + * https://learn.microsoft.com/en-us/windows/win32/eventlog/querying-for-event-source-messages * with bugs removed. */ @@ -1978,6 +1978,7 @@ EnumEventsThread(IN LPVOID lpParameter) BOOL bResult = TRUE; /* Read succeeded */ HANDLE hProcessHeap = GetProcessHeap(); PSID pLastSid = NULL; + INT nItems; UINT uStep = 0, uStepAt = 0, uPos = 0; @@ -1997,11 +1998,12 @@ EnumEventsThread(IN LPVOID lpParameter) SYSTEMTIME time; LVITEMW lviEventItem; + EnableEventDetailsButtons(hwndEventDetails, FALSE); + /* Save the current event log filter globally */ EventLogFilter_AddRef(EventLogFilter); ActiveFilter = EventLogFilter; - /** HACK!! **/ EventLog = EventLogFilter->EventLogs[0]; @@ -2263,6 +2265,8 @@ EnumEventsThread(IN LPVOID lpParameter) /* All events loaded */ Cleanup: + nItems = ListView_GetItemCount(hwndListView); + EnableEventDetailsButtons(hwndEventDetails, (nItems > 0)); ShowWindow(hwndStatusProgress, SW_HIDE); SendMessageW(hwndListView, LVM_PROGRESS, 0, FALSE); @@ -3037,6 +3041,22 @@ InitInstance(HINSTANCE hInstance) HIMAGELIST hSmall; LVCOLUMNW lvc = {0}; WCHAR szTemp[256]; + INT iColumn; + static const struct + { + WORD width; + WORD uID; + } columnItems[] = + { + { 90, IDS_COLUMNTYPE }, + { 70, IDS_COLUMNDATE }, + { 70, IDS_COLUMNTIME }, + { 150, IDS_COLUMNSOURCE }, + { 100, IDS_COLUMNCATEGORY }, + { 60, IDS_COLUMNEVENT }, + { 120, IDS_COLUMNUSER }, + { 100, IDS_COLUMNCOMPUTER }, + }; /* Create the main window */ rs = Settings.wpPos.rcNormalPosition; @@ -3180,69 +3200,13 @@ InitInstance(HINSTANCE hInstance) /* Now set up the listview with its columns */ lvc.mask = LVCF_TEXT | LVCF_WIDTH; - lvc.cx = 90; - LoadStringW(hInstance, - IDS_COLUMNTYPE, - szTemp, - ARRAYSIZE(szTemp)); - lvc.pszText = szTemp; - ListView_InsertColumn(hwndListView, 0, &lvc); - - lvc.cx = 70; - LoadStringW(hInstance, - IDS_COLUMNDATE, - szTemp, - ARRAYSIZE(szTemp)); - lvc.pszText = szTemp; - ListView_InsertColumn(hwndListView, 1, &lvc); - - lvc.cx = 70; - LoadStringW(hInstance, - IDS_COLUMNTIME, - szTemp, - ARRAYSIZE(szTemp)); - lvc.pszText = szTemp; - ListView_InsertColumn(hwndListView, 2, &lvc); - - lvc.cx = 150; - LoadStringW(hInstance, - IDS_COLUMNSOURCE, - szTemp, - ARRAYSIZE(szTemp)); lvc.pszText = szTemp; - ListView_InsertColumn(hwndListView, 3, &lvc); - - lvc.cx = 100; - LoadStringW(hInstance, - IDS_COLUMNCATEGORY, - szTemp, - ARRAYSIZE(szTemp)); - lvc.pszText = szTemp; - ListView_InsertColumn(hwndListView, 4, &lvc); - - lvc.cx = 60; - LoadStringW(hInstance, - IDS_COLUMNEVENT, - szTemp, - ARRAYSIZE(szTemp)); - lvc.pszText = szTemp; - ListView_InsertColumn(hwndListView, 5, &lvc); - - lvc.cx = 120; - LoadStringW(hInstance, - IDS_COLUMNUSER, - szTemp, - ARRAYSIZE(szTemp)); - lvc.pszText = szTemp; - ListView_InsertColumn(hwndListView, 6, &lvc); - - lvc.cx = 100; - LoadStringW(hInstance, - IDS_COLUMNCOMPUTER, - szTemp, - ARRAYSIZE(szTemp)); - lvc.pszText = szTemp; - ListView_InsertColumn(hwndListView, 7, &lvc); + for (iColumn = 0; iColumn < ARRAYSIZE(columnItems); ++iColumn) + { + lvc.cx = columnItems[iColumn].width; + LoadStringW(hInstance, columnItems[iColumn].uID, szTemp, ARRAYSIZE(szTemp)); + ListView_InsertColumn(hwndListView, iColumn, &lvc); + } /* Initialize the save Dialog */ ZeroMemory(&sfn, sizeof(sfn)); diff --git a/base/applications/mscutils/eventvwr/evtdetctl.c b/base/applications/mscutils/eventvwr/evtdetctl.c index b476e4db8478f..1583440a0e876 100644 --- a/base/applications/mscutils/eventvwr/evtdetctl.c +++ b/base/applications/mscutils/eventvwr/evtdetctl.c @@ -751,9 +751,9 @@ InitDetailsDlgCtrl(HWND hDlg, PDETAILDATA pData) /* * Activate automatic URL recognition by the RichEdit control. For more information, see: - * https://blogs.msdn.microsoft.com/murrays/2009/08/31/automatic-richedit-hyperlinks/ - * https://blogs.msdn.microsoft.com/murrays/2009/09/24/richedit-friendly-name-hyperlinks/ - * https://msdn.microsoft.com/en-us/library/windows/desktop/bb787991(v=vs.85).aspx + * https://learn.microsoft.com/en-us/archive/blogs/murrays/automatic-richedit-hyperlinks + * https://learn.microsoft.com/en-us/archive/blogs/murrays/richedit-friendly-name-hyperlinks + * https://learn.microsoft.com/en-us/windows/win32/controls/em-autourldetect */ SendDlgItemMessageW(hDlg, IDC_EVENTTEXTEDIT, EM_AUTOURLDETECT, AURL_ENABLEURL /* | AURL_ENABLEEAURLS */, 0); @@ -792,6 +792,11 @@ EventDetailsCtrl(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) pData->EventLogFilter = DetailInfo->EventLogFilter; pData->iEventItem = DetailInfo->iEventItem; } + else + { + pData->iEventItem = -1; + } + pData->bDisplayWords = FALSE; pData->hMonospaceFont = CreateMonospaceFont(); @@ -838,31 +843,26 @@ EventDetailsCtrl(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) case IDC_NEXT: { BOOL bPrev = (LOWORD(wParam) == IDC_PREVIOUS); - INT iItem, iSel; + INT iItem, iSel, nItems = ListView_GetItemCount(hwndListView); + WCHAR szText[200]; + + if (nItems <= 0) /* No items? */ + break; /* Select the previous/next item from our current one */ - iItem = ListView_GetNextItem(hwndListView, - pData->iEventItem, - bPrev ? LVNI_ABOVE : LVNI_BELOW); - if (iItem == -1) + iItem = ListView_GetNextItem(hwndListView, -1, LVNI_ALL | LVNI_SELECTED); + iItem = ListView_GetNextItem(hwndListView, iItem, + (bPrev ? LVNI_ABOVE : LVNI_BELOW)); + if (iItem < 0 || iItem >= nItems) { - // TODO: Localization. - if (MessageBoxW(hDlg, - bPrev - ? L"You have reached the beginning of the event log. Do you want to continue from the end?" - : L"You have reached the end of the event log. Do you want to continue from the beginning?", - szTitle, - MB_YESNO | MB_ICONQUESTION) - == IDNO) - { + LoadStringW(hInst, + (bPrev ? IDS_CONTFROMEND : IDS_CONTFROMBEGINNING), + szText, _countof(szText)); + if (MessageBoxW(hDlg, szText, szTitle, MB_YESNO | MB_ICONQUESTION) == IDNO) break; - } /* Determine from where to restart */ - if (bPrev) - iItem = ListView_GetItemCount(hwndListView) - 1; - else - iItem = 0; + iItem = (bPrev ? (nItems - 1) : 0); } /* @@ -959,3 +959,11 @@ CreateEventDetailsCtrl(HINSTANCE hInstance, MAKEINTRESOURCEW(IDD_EVENTDETAILS_CTRL), hParentWnd, EventDetailsCtrl, lParam); } + +VOID +EnableEventDetailsButtons(HWND hWnd, BOOL bEnable) +{ + EnableDlgItem(hWnd, IDC_PREVIOUS, bEnable); + EnableDlgItem(hWnd, IDC_NEXT, bEnable); + EnableDlgItem(hWnd, IDC_COPY, bEnable); +} diff --git a/base/applications/mscutils/eventvwr/evtdetctl.h b/base/applications/mscutils/eventvwr/evtdetctl.h index a123232bf869a..cb22cfa0d0ab3 100644 --- a/base/applications/mscutils/eventvwr/evtdetctl.h +++ b/base/applications/mscutils/eventvwr/evtdetctl.h @@ -7,8 +7,7 @@ * Copyright 2016-2022 Hermès Bélusca-Maïto */ -#ifndef _EVTDETCTL_H_ -#define _EVTDETCTL_H_ +#pragma once /* Optional structure passed by pointer * as LPARAM to CreateEventDetailsCtrl() */ @@ -26,4 +25,4 @@ CreateEventDetailsCtrl(HINSTANCE hInstance, HWND hParentWnd, LPARAM lParam); -#endif /* _EVTDETCTL_H_ */ +VOID EnableEventDetailsButtons(HWND hWnd, BOOL bEnable); diff --git a/base/applications/mscutils/eventvwr/lang/bg-BG.rc b/base/applications/mscutils/eventvwr/lang/bg-BG.rc index 26b7c2e4040ef..f1054ac80d28e 100644 --- a/base/applications/mscutils/eventvwr/lang/bg-BG.rc +++ b/base/applications/mscutils/eventvwr/lang/bg-BG.rc @@ -167,6 +167,8 @@ BEGIN IDS_CLEAREVENTS_MSG "Do you want to save this event log before clearing it?" IDS_RESTOREDEFAULTS "Do you want to restore all settings for this log to their default values?" IDS_EVENTSTRINGIDNOTFOUND "Не е намерено описанието на събитие ( %lu ) в източник ( %s ). Възможно е местият компютър да няма нужните сведения в регистъра или DLL файловет, нужни за показване на съобщения от отдалечен компютър.\n\nThe following information is part of the event:\n\n" + IDS_CONTFROMBEGINNING "You have reached the end of the event log. Do you want to continue from the beginning?" + IDS_CONTFROMEND "You have reached the beginning of the event log. Do you want to continue from the end?" END STRINGTABLE diff --git a/base/applications/mscutils/eventvwr/lang/cs-CZ.rc b/base/applications/mscutils/eventvwr/lang/cs-CZ.rc index 11e3a926d96c9..76dfbae4283a4 100644 --- a/base/applications/mscutils/eventvwr/lang/cs-CZ.rc +++ b/base/applications/mscutils/eventvwr/lang/cs-CZ.rc @@ -167,6 +167,8 @@ BEGIN IDS_CLEAREVENTS_MSG "Chcete tento protokol před odstraněním uložit?" IDS_RESTOREDEFAULTS "Do you want to restore all settings for this log to their default values?" IDS_EVENTSTRINGIDNOTFOUND "Popis ID události ( %lu ) zdroj ( %s ) nebyl nalezen. Místní počítač neobsahuje potřebné informace v registru nebo chybí DLL soubory pro zobrazení zpráv ze vzdáleného počítače.\n\nThe following information is part of the event:\n\n" + IDS_CONTFROMBEGINNING "You have reached the end of the event log. Do you want to continue from the beginning?" + IDS_CONTFROMEND "You have reached the beginning of the event log. Do you want to continue from the end?" END STRINGTABLE diff --git a/base/applications/mscutils/eventvwr/lang/de-DE.rc b/base/applications/mscutils/eventvwr/lang/de-DE.rc index acb061a907803..26ffe32450838 100644 --- a/base/applications/mscutils/eventvwr/lang/de-DE.rc +++ b/base/applications/mscutils/eventvwr/lang/de-DE.rc @@ -168,6 +168,8 @@ BEGIN IDS_CLEAREVENTS_MSG "Möchten Sie dieses Protokoll vor dem Löschen speichern?" IDS_RESTOREDEFAULTS "Möchten Sie alle Einstellungen für dieses Protokoll wieder auf die Standardwerte zurücksetzen?" IDS_EVENTSTRINGIDNOTFOUND "Die Bezeichnung für die Ereignis-ID ( %lu ) in der Quelle ( %s ) kann nicht gefunden werden. Es könnte sein, dass der lokale Computer die notwendigen Registry Einträge oder Nachrichten DLLs, um Nachrichten entfernter Computer anzuzeigen, nicht besitzt.\n\nDas Ereignis enthält folgende Informationen:\n\n" + IDS_CONTFROMBEGINNING "You have reached the end of the event log. Do you want to continue from the beginning?" + IDS_CONTFROMEND "You have reached the beginning of the event log. Do you want to continue from the end?" END STRINGTABLE diff --git a/base/applications/mscutils/eventvwr/lang/el-GR.rc b/base/applications/mscutils/eventvwr/lang/el-GR.rc index 542531f3b8f01..47806b2fc03cc 100644 --- a/base/applications/mscutils/eventvwr/lang/el-GR.rc +++ b/base/applications/mscutils/eventvwr/lang/el-GR.rc @@ -167,6 +167,8 @@ BEGIN IDS_CLEAREVENTS_MSG "Do you want to save this event log before clearing it?" IDS_RESTOREDEFAULTS "Do you want to restore all settings for this log to their default values?" IDS_EVENTSTRINGIDNOTFOUND "The description for Event ID ( %lu ) in Source ( %s ) cannot be found. The local computer may not have the necessary registry information or message DLL files to display messages from a remote computer.\n\nThe following information is part of the event:\n\n" + IDS_CONTFROMBEGINNING "You have reached the end of the event log. Do you want to continue from the beginning?" + IDS_CONTFROMEND "You have reached the beginning of the event log. Do you want to continue from the end?" END STRINGTABLE diff --git a/base/applications/mscutils/eventvwr/lang/en-US.rc b/base/applications/mscutils/eventvwr/lang/en-US.rc index 917c26a60b016..045e76e3fe11c 100644 --- a/base/applications/mscutils/eventvwr/lang/en-US.rc +++ b/base/applications/mscutils/eventvwr/lang/en-US.rc @@ -169,6 +169,8 @@ BEGIN IDS_CLEAREVENTS_MSG "Do you want to save this event log before clearing it?" IDS_RESTOREDEFAULTS "Do you want to restore all settings for this log to their default values?" IDS_EVENTSTRINGIDNOTFOUND "The description for Event ID ( %lu ) in Source ( %s ) cannot be found. The local computer may not have the necessary registry information or message DLL files to display messages from a remote computer.\n\nThe following information is part of the event:\n\n" + IDS_CONTFROMBEGINNING "You have reached the end of the event log. Do you want to continue from the beginning?" + IDS_CONTFROMEND "You have reached the beginning of the event log. Do you want to continue from the end?" END STRINGTABLE diff --git a/base/applications/mscutils/eventvwr/lang/es-ES.rc b/base/applications/mscutils/eventvwr/lang/es-ES.rc index 494632a858925..86eb305e342ec 100644 --- a/base/applications/mscutils/eventvwr/lang/es-ES.rc +++ b/base/applications/mscutils/eventvwr/lang/es-ES.rc @@ -170,6 +170,8 @@ BEGIN IDS_CLEAREVENTS_MSG "¿Desea guardar este registro de eventos antes de borrarlo?" IDS_RESTOREDEFAULTS "Do you want to restore all settings for this log to their default values?" IDS_EVENTSTRINGIDNOTFOUND "No se pudo recuperar la descripción para el evento con ID ( %lu ) y origen ( %s ). El equipo local puede no tener la información necesaria en el registro o las DLLs necesarias para mostrar los mensajes de un equipo remoto.\n\nLa siguiente información es parte del evento:\n\n" + IDS_CONTFROMBEGINNING "You have reached the end of the event log. Do you want to continue from the beginning?" + IDS_CONTFROMEND "You have reached the beginning of the event log. Do you want to continue from the end?" END STRINGTABLE diff --git a/base/applications/mscutils/eventvwr/lang/fr-FR.rc b/base/applications/mscutils/eventvwr/lang/fr-FR.rc index 18a0cf122540e..e9e70e8b3ea8f 100644 --- a/base/applications/mscutils/eventvwr/lang/fr-FR.rc +++ b/base/applications/mscutils/eventvwr/lang/fr-FR.rc @@ -50,12 +50,12 @@ IDM_EVENTWR_CTX MENU BEGIN POPUP "" BEGIN - MENUITEM "&Open Event Log...", IDM_OPEN_EVENTLOG - MENUITEM "&Save Event Log as...", IDM_SAVE_EVENTLOG + MENUITEM "&Ouvrir le journal d'événements...", IDM_OPEN_EVENTLOG + MENUITEM "Enregistrer le journal d'événements &sous...", IDM_SAVE_EVENTLOG MENUITEM SEPARATOR - MENUITEM "&Clear all Events", IDM_CLEAR_EVENTS - MENUITEM "&Rename\tF2", IDM_RENAME_EVENTLOG - MENUITEM "Log Se&ttings...", IDM_EVENTLOG_SETTINGS + MENUITEM "&Effacer tous les événements", IDM_CLEAR_EVENTS + MENUITEM "&Renommer\tF2", IDM_RENAME_EVENTLOG + MENUITEM "&Paramètres du journal...", IDM_EVENTLOG_SETTINGS END END @@ -168,6 +168,8 @@ BEGIN IDS_CLEAREVENTS_MSG "Voulez-vous enregistrer ce journal d'événements avant de l'effacer ?" IDS_RESTOREDEFAULTS "Voulez-vous vraiment réinitialiser tous les paramètres pour ce journal aux valeurs par défaut ?" IDS_EVENTSTRINGIDNOTFOUND "La description pour l'événement d'ID ( %lu ) dans la source ( %s ) ne peut être trouvée. L'ordinateur local pourrait ne pas avoir les informations registres nécessaires ou les fichiers DLL de message pour afficher les messages depuis un ordinateur distant.\n\nLes informations suivantes font partie de l'événement :\n\n" + IDS_CONTFROMBEGINNING "You have reached the end of the event log. Do you want to continue from the beginning?" + IDS_CONTFROMEND "You have reached the beginning of the event log. Do you want to continue from the end?" END STRINGTABLE diff --git a/base/applications/mscutils/eventvwr/lang/he-IL.rc b/base/applications/mscutils/eventvwr/lang/he-IL.rc index ac4b5e6a82e37..f6ba603938af6 100644 --- a/base/applications/mscutils/eventvwr/lang/he-IL.rc +++ b/base/applications/mscutils/eventvwr/lang/he-IL.rc @@ -167,6 +167,8 @@ BEGIN IDS_CLEAREVENTS_MSG "Do you want to save this event log before clearing it?" IDS_RESTOREDEFAULTS "Do you want to restore all settings for this log to their default values?" IDS_EVENTSTRINGIDNOTFOUND "The description for Event ID ( %lu ) in Source ( %s ) cannot be found. The local computer may not have the necessary registry information or message DLL files to display messages from a remote computer.\n\nThe following information is part of the event:\n\n" + IDS_CONTFROMBEGINNING "You have reached the end of the event log. Do you want to continue from the beginning?" + IDS_CONTFROMEND "You have reached the beginning of the event log. Do you want to continue from the end?" END STRINGTABLE diff --git a/base/applications/mscutils/eventvwr/lang/it-IT.rc b/base/applications/mscutils/eventvwr/lang/it-IT.rc index e2c6d3605fc7f..387f675df2fb0 100644 --- a/base/applications/mscutils/eventvwr/lang/it-IT.rc +++ b/base/applications/mscutils/eventvwr/lang/it-IT.rc @@ -168,6 +168,8 @@ BEGIN IDS_CLEAREVENTS_MSG "Do you want to save this event log before clearing it?" IDS_RESTOREDEFAULTS "Do you want to restore all settings for this log to their default values?" IDS_EVENTSTRINGIDNOTFOUND "La descrizione per l'ID evento ( %lu ) proveniente da ( %s ) non può essere trovata. Il computer locale potrebbe non avere le informazioni sul registry necessarie o i file DLL con i messaggi necessari per la visualizzazione da un computer remoto.\n\nThe following information is part of the event:\n\n" + IDS_CONTFROMBEGINNING "You have reached the end of the event log. Do you want to continue from the beginning?" + IDS_CONTFROMEND "You have reached the beginning of the event log. Do you want to continue from the end?" END STRINGTABLE diff --git a/base/applications/mscutils/eventvwr/lang/ja-JP.rc b/base/applications/mscutils/eventvwr/lang/ja-JP.rc index b2ce3e869eb4f..3a0f9c540fa56 100644 --- a/base/applications/mscutils/eventvwr/lang/ja-JP.rc +++ b/base/applications/mscutils/eventvwr/lang/ja-JP.rc @@ -168,6 +168,8 @@ BEGIN IDS_CLEAREVENTS_MSG "このイベントをクリアする前に保存したいですか?" IDS_RESTOREDEFAULTS "すべての設定をデフォルトに戻しますか?" IDS_EVENTSTRINGIDNOTFOUND "イベント ID (%lu) (ソース %s 内) に関する説明が見つかりませんでした。 リモート コンピュータからメッセージを表示するために必要なレジストリ情報またはメッセージ DLL ファイルがローカル コンピュータにない可能性があります。\n\n次の情報はイベントの一部です:\n\n" + IDS_CONTFROMBEGINNING "イベント ログの最後に到達しました。最初から続けますか?" + IDS_CONTFROMEND "イベント ログの先頭に到達しました。最後から続けますか?" END STRINGTABLE diff --git a/base/applications/mscutils/eventvwr/lang/ko-KR.rc b/base/applications/mscutils/eventvwr/lang/ko-KR.rc index 867322cf33efd..e91500361159f 100644 --- a/base/applications/mscutils/eventvwr/lang/ko-KR.rc +++ b/base/applications/mscutils/eventvwr/lang/ko-KR.rc @@ -167,6 +167,8 @@ BEGIN IDS_CLEAREVENTS_MSG "Do you want to save this event log before clearing it?" IDS_RESTOREDEFAULTS "Do you want to restore all settings for this log to their default values?" IDS_EVENTSTRINGIDNOTFOUND "( %s ) 의 이벤트ID ( %lu ) 에 대한 설명을 찾을 수 없습니다. 로컬 컴퓨터가 원격 컴퓨터의 메세지를 표시하는데 필요한 레지스트리나 DLL 파일을 가지지 않고 있을수 있습니다.\n\nThe following information is part of the event:\n\n" + IDS_CONTFROMBEGINNING "You have reached the end of the event log. Do you want to continue from the beginning?" + IDS_CONTFROMEND "You have reached the beginning of the event log. Do you want to continue from the end?" END STRINGTABLE diff --git a/base/applications/mscutils/eventvwr/lang/no-NO.rc b/base/applications/mscutils/eventvwr/lang/no-NO.rc index e74b7300f558e..16a5fd167c15f 100644 --- a/base/applications/mscutils/eventvwr/lang/no-NO.rc +++ b/base/applications/mscutils/eventvwr/lang/no-NO.rc @@ -167,6 +167,8 @@ BEGIN IDS_CLEAREVENTS_MSG "Do you want to save this event log before clearing it?" IDS_RESTOREDEFAULTS "Do you want to restore all settings for this log to their default values?" IDS_EVENTSTRINGIDNOTFOUND "Beskrivelsen for Hendelse ID ( %lu ) i kilden ( %s ) kan ikke bli finnet. Lokale datamaskinen har ikke nødvendige register informasjon eller melding DLL filer for å vise melding fra en fjern datamaskin.\n\nThe following information is part of the event:\n\n" + IDS_CONTFROMBEGINNING "You have reached the end of the event log. Do you want to continue from the beginning?" + IDS_CONTFROMEND "You have reached the beginning of the event log. Do you want to continue from the end?" END STRINGTABLE diff --git a/base/applications/mscutils/eventvwr/lang/pl-PL.rc b/base/applications/mscutils/eventvwr/lang/pl-PL.rc index 7d3dd9d957a73..b7a42625686cb 100644 --- a/base/applications/mscutils/eventvwr/lang/pl-PL.rc +++ b/base/applications/mscutils/eventvwr/lang/pl-PL.rc @@ -170,6 +170,8 @@ BEGIN IDS_CLEAREVENTS_MSG "Czy chcesz zapisać dziennik zdarzeń przed czyszczeniem?" IDS_RESTOREDEFAULTS "Czy chcesz przywrócić wszystkie ustawienia tego dziennika do wartości domyślnych?" IDS_EVENTSTRINGIDNOTFOUND "Opis zdarzenia dla danego numeru ID ( %lu ) nie został odnaleziony w źródle ( %s ). Ten komputer może nie miec wystarczających informacji w rejestrze, albo bibliotek DLL, aby wyświetlić wiadomości z komputera zdalnego.\n\nThe following information is part of the event:\n\n" + IDS_CONTFROMBEGINNING "You have reached the end of the event log. Do you want to continue from the beginning?" + IDS_CONTFROMEND "You have reached the beginning of the event log. Do you want to continue from the end?" END STRINGTABLE diff --git a/base/applications/mscutils/eventvwr/lang/pt-BR.rc b/base/applications/mscutils/eventvwr/lang/pt-BR.rc index 9302e01e9f48d..0d6f9296cc942 100644 --- a/base/applications/mscutils/eventvwr/lang/pt-BR.rc +++ b/base/applications/mscutils/eventvwr/lang/pt-BR.rc @@ -167,6 +167,8 @@ BEGIN IDS_CLEAREVENTS_MSG "Do you want to save this event log before clearing it?" IDS_RESTOREDEFAULTS "Do you want to restore all settings for this log to their default values?" IDS_EVENTSTRINGIDNOTFOUND "A descrição para Event ID ( %lu ) em Fonte ( %s ) não foi encontrado. O computador local talvez não possua a informação de registro necessária ou mensagem de arquivos DLL para exibir mensagens de um computador remoto.\n\nThe following information is part of the event:\n\n" + IDS_CONTFROMBEGINNING "You have reached the end of the event log. Do you want to continue from the beginning?" + IDS_CONTFROMEND "You have reached the beginning of the event log. Do you want to continue from the end?" END STRINGTABLE diff --git a/base/applications/mscutils/eventvwr/lang/pt-PT.rc b/base/applications/mscutils/eventvwr/lang/pt-PT.rc index fd0791aa3e059..1ea4d73a52158 100644 --- a/base/applications/mscutils/eventvwr/lang/pt-PT.rc +++ b/base/applications/mscutils/eventvwr/lang/pt-PT.rc @@ -167,6 +167,8 @@ BEGIN IDS_CLEAREVENTS_MSG "Deseja guardar este registo de eventos antes de limpar?" IDS_RESTOREDEFAULTS "Tem a certeza de que pretende repor todas definições deste registo para os valores predefinidos?" IDS_EVENTSTRINGIDNOTFOUND "A descrição do ID de Evento ( %lu ) na Origem ( %s ) não foi encontrado. O computador local talvez não possua a informação de registo necessária ou os ficheiros DLL necessárias para apresentar mensagens de um computador remoto.\n\nA informação seguinte é parte do evento:\n\n" + IDS_CONTFROMBEGINNING "You have reached the end of the event log. Do you want to continue from the beginning?" + IDS_CONTFROMEND "You have reached the beginning of the event log. Do you want to continue from the end?" END STRINGTABLE diff --git a/base/applications/mscutils/eventvwr/lang/ro-RO.rc b/base/applications/mscutils/eventvwr/lang/ro-RO.rc index baa02ec0431c8..c95bcd52d045e 100644 --- a/base/applications/mscutils/eventvwr/lang/ro-RO.rc +++ b/base/applications/mscutils/eventvwr/lang/ro-RO.rc @@ -14,21 +14,21 @@ BEGIN POPUP "&Jurnal" BEGIN MENUITEM "&Deschidere…", IDM_OPEN_EVENTLOG - MENUITEM "&Salvare jurnal de evenimente ca…", IDM_SAVE_EVENTLOG//FIXME: accelerator collision &S + MENUITEM "&Salvare a jurnalului de evenimente ca…", IDM_SAVE_EVENTLOG MENUITEM "Î&nchidere", IDM_CLOSE_EVENTLOG MENUITEM SEPARATOR MENUITEM "Înlăt&urare a tuturor evenimentelor", IDM_CLEAR_EVENTS MENUITEM "&Redenumire\tF2", IDM_RENAME_EVENTLOG - MENUITEM "&Setări pentru jurnal…", IDM_EVENTLOG_SETTINGS//FIXME: accelerator collision &S + MENUITEM "Se&tări pentru jurnal…", IDM_EVENTLOG_SETTINGS MENUITEM SEPARATOR MENUITEM "I&eșire", IDM_EXIT END POPUP "&Afișare" BEGIN - MENUITEM "După vârstă &crescător", IDM_LIST_NEWEST - MENUITEM "După vârstă &descrescător", IDM_LIST_OLDEST//FIXME: accelerator collision &D + MENUITEM "Cel mai &nou primul", IDM_LIST_NEWEST + MENUITEM "Cel mai &vechi primul", IDM_LIST_OLDEST MENUITEM SEPARATOR - MENUITEM "&Detalii…\tEnter", IDM_EVENT_DETAILS//FIXME: accelerator collision &D + MENUITEM "&Detalii…\tEnter", IDM_EVENT_DETAILS MENUITEM SEPARATOR MENUITEM "Împ&rospătare\tF5", IDM_REFRESH END @@ -41,7 +41,7 @@ BEGIN END POPUP "Aj&utor" BEGIN - MENUITEM "&Manual…", IDM_HELP + MENUITEM "Aju&tor", IDM_HELP MENUITEM SEPARATOR MENUITEM "&Despre…", IDM_ABOUT END @@ -51,12 +51,12 @@ IDM_EVENTWR_CTX MENU BEGIN POPUP "" BEGIN - MENUITEM "&Deschidere jurnalul de evenimente...", IDM_OPEN_EVENTLOG - MENUITEM "Salv&are jurnal de evenimente ca...", IDM_SAVE_EVENTLOG + MENUITEM "&Deschidere jurnalul de evenimente…", IDM_OPEN_EVENTLOG + MENUITEM "Salv&are a jurnalului de evenimente ca…", IDM_SAVE_EVENTLOG MENUITEM SEPARATOR - MENUITEM "Șter&gere toate evenimentele", IDM_CLEAR_EVENTS + MENUITEM "Șter&gere a tuturor evenimentelor", IDM_CLEAR_EVENTS MENUITEM "&Redenumire\tF2", IDM_RENAME_EVENTLOG - MENUITEM "Setări de &jurnal...", IDM_EVENTLOG_SETTINGS + MENUITEM "Setări ale &jurnalului…", IDM_EVENTLOG_SETTINGS END END @@ -71,12 +71,12 @@ END IDD_EVENTDETAILS_DLG DIALOGEX 0, 0, 266, 240 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_THICKFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_CONTEXTHELP -CAPTION "Detalii eveniment" +CAPTION "Detalii despre eveniment" FONT 8, "MS Shell Dlg" BEGIN LTEXT "EvtDetailsCtrl", IDC_STATIC, 0, 0, 266, 215 - PUSHBUTTON "&Manual…", IDHELP, 8, 220, 50, 14 - DEFPUSHBUTTON "Î&nchide", IDOK, 208, 220, 50, 14 + PUSHBUTTON "&Ajutor", IDHELP, 8, 220, 50, 14 + DEFPUSHBUTTON "Î&nchidere", IDOK, 208, 220, 50, 14 END IDD_EVENTDETAILS_CTRL DIALOGEX 0, 0, 266, 215 @@ -115,79 +115,81 @@ END IDD_LOGPROPERTIES_GENERAL DIALOGEX 0, 0, 252, 234 STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION -CAPTION "Generale" +CAPTION "General" FONT 8, "MS Shell Dlg" BEGIN - LTEXT "N&ume afișat:", IDC_STATIC, 7, 9, 60, 8 + LTEXT "&Nume afișat:", IDC_STATIC, 7, 9, 60, 8 EDITTEXT IDC_DISPLAYNAME, 67, 7, 178, 12, ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP - LTEXT "Nume de ju&rnal:", IDC_STATIC, 7, 25, 60, 8 + LTEXT "Numele &jurnalului:", IDC_STATIC, 7, 25, 60, 8 EDITTEXT IDC_LOGNAME, 67, 23, 178, 12, ES_LEFT | ES_AUTOHSCROLL | ES_READONLY | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP - LTEXT "Fiși&er de jurnal:", IDC_STATIC, 7, 41, 60, 8 + LTEXT "&Fișier de jurnal:", IDC_STATIC, 7, 41, 60, 8 EDITTEXT IDC_LOGFILE, 67, 39, 178, 12, ES_LEFT | ES_AUTOHSCROLL | ES_READONLY | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP // The following 4 IDC_STATIC shall have accels in ReactOS, although MS doesn't have accels for them. // Translation note: First fill out ALL accels that MS has in this dialog for your language, // and only then as a final step use some remaining unused letters for those 4 controls! - LTEXT "Dimen&siune:", IDC_STATIC, 7, 57, 60, 8 + LTEXT "&Dimensiune:", IDC_STATIC, 7, 57, 60, 8 EDITTEXT IDC_SIZE_LABEL, 67, 57, 178, 12, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL - LTEXT "Crea&t:", IDC_STATIC, 7, 69, 60, 8 + LTEXT "&Creat:", IDC_STATIC, 7, 69, 60, 8 EDITTEXT IDC_CREATED_LABEL, 67, 69, 178, 12, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL LTEXT "&Modificat:", IDC_STATIC, 7, 81, 60, 8 EDITTEXT IDC_MODIFIED_LABEL, 67, 81, 178, 12, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL LTEXT "&Accesat:", IDC_STATIC, 7, 93, 60, 8 EDITTEXT IDC_ACCESSED_LABEL, 67, 93, 178, 12, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL - GROUPBOX "Dimensiune jurnal", IDC_STATIC, 7, 106, 238, 99 - LTEXT "Dimensiune ma&ximă pentru jurnal:", IDC_STATIC, 17, 122, 58, 8 + GROUPBOX "Dimensiunea jurnalului", IDC_STATIC, 7, 106, 238, 99 + LTEXT "Dimensiune ma&ximă a jurnalului:", IDC_STATIC, 17, 122, 58, 8 EDITTEXT IDC_EDIT_MAXLOGSIZE, 80, 119, 40, 14, ES_LEFT | ES_NUMBER | WS_GROUP CONTROL "", IDC_UPDOWN_MAXLOGSIZE, UPDOWN_CLASS, UDS_SETBUDDYINT | UDS_NOTHOUSANDS | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | WS_GROUP, 120, 119, 10, 14 - LTEXT "Kio", IDC_STATIC, 130, 122, 20, 8 + LTEXT "KB", IDC_STATIC, 130, 122, 20, 8 LTEXT "Când dimensiunea maximă este atinsă:", IDC_STATIC, 17, 140, 219, 8 - AUTORADIOBUTTON "Suprascrie evenimentele cân&d este necesar", IDC_OVERWRITE_AS_NEEDED, 17, 155, 219, 10, WS_GROUP | WS_TABSTOP - AUTORADIOBUTTON "Suprascrie evenimentele mai &vechi de", IDC_OVERWRITE_OLDER_THAN, 17, 168, 155, 10 - AUTORADIOBUTTON "Inter&zice suprascrierea\n(gestiune manuală de jurnal)", IDC_NO_OVERWRITE, 17, 180, 143, 20, BS_MULTILINE | WS_TABSTOP + AUTORADIOBUTTON "&Suprascriere a evenimentelor când este necesar", IDC_OVERWRITE_AS_NEEDED, 17, 155, 219, 10, WS_GROUP | WS_TABSTOP + AUTORADIOBUTTON "Suprascriere a evenimentelor mai &vechi de", IDC_OVERWRITE_OLDER_THAN, 17, 168, 155, 10 + AUTORADIOBUTTON "Nu se suprascriu evenimentele\n(&golire manuală a jurnalului)", IDC_NO_OVERWRITE, 17, 180, 143, 20, BS_MULTILINE | WS_TABSTOP EDITTEXT IDC_EDIT_EVENTS_AGE, 175, 165, 35, 14, ES_LEFT | ES_NUMBER | WS_GROUP CONTROL "", IDC_UPDOWN_EVENTS_AGE, UPDOWN_CLASS, UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS, 104, 165, 10, 14 LTEXT "zile", IDC_STATIC, 215, 168, 20, 8 - PUSHBUTTON "&Opțiuni implicite", IDC_RESTOREDEFAULTS, 166, 183, 70, 14 - AUTOCHECKBOX "Conexiune de &bandă limitată", IDC_LOW_SPEED_CONNECTION, 7, 217, 167, 10 + PUSHBUTTON "&Restaurare implicite", IDC_RESTOREDEFAULTS, 166, 183, 70, 14 + AUTOCHECKBOX "&Folosind o conexiune de viteză mică", IDC_LOW_SPEED_CONNECTION, 7, 217, 167, 10 PUSHBUTTON "&Curăță jurnal", ID_CLEARLOG, 195, 213, 50, 14 END STRINGTABLE BEGIN IDS_COPYRIGHT "Drept de autor (C) 2007 Marc Piulachs (marc.piulachs@codexchange.net)" - IDS_APP_TITLE "Observator de evenimente" + IDS_APP_TITLE "Vizualizator de evenimente" IDS_APP_TITLE_EX "%s - %s autentificat pe \\\\" IDS_STATUS_MSG "%s are %lu (de) eveniment(e) (afișate: %lu)" - IDS_LOADING_WAIT "Jurnal de evenimente în încărcare. Așteptați…" - IDS_NO_ITEMS "Nu există elemente de afișat." // "No events in this log." + IDS_LOADING_WAIT "Se încarcă jurnalele de evenimente. Așteptați…" + IDS_NO_ITEMS "Nu există elemente de afișat în această vizualizare." // "No events in this log." IDS_EVENTLOG_SYSTEM "Jurnale de sistem" - IDS_EVENTLOG_APP "Jurnale de aplicație" + IDS_EVENTLOG_APP "Jurnale de aplicații" IDS_EVENTLOG_USER "Jurnale de utilizator" IDS_SAVE_FILTER "Jurnal de evenimente (*.evt)\0*.evt\0" IDS_CLEAREVENTS_MSG "Doriți să salvați acest jurnal de evenimente înainte de a-l închide?" - IDS_RESTOREDEFAULTS "Doriți să restaurați toate setările pentru acest jurnal la valorile lor implicite?" - IDS_EVENTSTRINGIDNOTFOUND "Descrierea evenimentului cu ID-ul ( %lu ) în sursa ( %s ) nu a fost găsită. Este posibil ca în calculatorul local să nu existe informațiile de registru necesare sau fișierele dll de mesaje să afișeze mesaje de la un calculator din rețea.\n\nInformații aferente evenimentului:\n\n" + IDS_RESTOREDEFAULTS "Doriți să restabiliți toate setările pentru acest jurnal la valorile lor implicite?" + IDS_EVENTSTRINGIDNOTFOUND "Imposibil de găsit descrierea evenimentului cu ID-ul ( %lu ) în sursa ( %s ). Este posibil ca computerul local să nu aibă informațiile de registru necesare sau fișierele DLL de mesaje pentru a afișa mesaje de la un computer la distanță.\n\nUrmătoarele informații fac parte din eveniment:\n\n" + IDS_CONTFROMBEGINNING "You have reached the end of the event log. Do you want to continue from the beginning?" + IDS_CONTFROMEND "You have reached the beginning of the event log. Do you want to continue from the end?" END STRINGTABLE BEGIN /* Please note that explicit TAB characters '\t' are used to fix the alignment of the message in the MessageBox */ - IDS_USAGE "Inspector de Evenimente ReactOS\n\ + IDS_USAGE "Vizualizatorul de evenimente ReactOS\n\ \n\ -EventVwr [nume calculator] [/L:] [/?]\n\ +EventVwr [numele computerului] [/L:] [/?]\n\ \n\ -""nume calculator"" : Specifică calculatorul la distanță de la care\n\ -\tvor fi preluate evenimentele afișate. Dacă nu e furnizat un\n\ -\tnume de calculator, va fi utilizat calculatorul local.\n\ +""numele computerului"" : Specifică computerul de la distanță unde să se conecteze\n\ +\tpentru a prelua evenimentele de afișat. Dacă nu este specificat niciun nume,\n\ +\tcomputerul local este folosit.\n\ \n\ -/L: : Specifică deschiderea unui fișier.\n\ +/L: : Specifică deschiderea unui fișier.\n\ \tSunt acceptate doar fișierele în format .evt (NT ≤ 5.2)\n\ \n\ /? : Afișează acest mesaj cu informații de utilizare.\n\ " - IDS_EVENTLOGFILE "Fișier jurnal de evenimente" + IDS_EVENTLOGFILE "Fișier de jurnal de evenimente" END STRINGTABLE @@ -216,7 +218,7 @@ BEGIN IDS_COLUMNCATEGORY "Categorie" IDS_COLUMNEVENT "Eveniment" IDS_COLUMNUSER "Utilizator" - IDS_COLUMNCOMPUTER "Calculator" + IDS_COLUMNCOMPUTER "Computer" END STRINGTABLE @@ -229,12 +231,12 @@ ID eveniment: %s\r\n\ Dată: %s\r\n\ Oră: %s\r\n\ Utilizator: %s\r\n\ -Calculator: %s\r\n\ +Computer: %s\r\n\ Descriere:\r\n%s" END STRINGTABLE BEGIN - IDS_NONE "Nespecificată" - IDS_NOT_AVAILABLE "Nespecificat" + IDS_NONE "Nespecificat" + IDS_NOT_AVAILABLE "N/A" END diff --git a/base/applications/mscutils/eventvwr/lang/ru-RU.rc b/base/applications/mscutils/eventvwr/lang/ru-RU.rc index 9d3423bfd66f6..0bb9b7f61f722 100644 --- a/base/applications/mscutils/eventvwr/lang/ru-RU.rc +++ b/base/applications/mscutils/eventvwr/lang/ru-RU.rc @@ -171,6 +171,8 @@ BEGIN IDS_CLEAREVENTS_MSG "Вы хотите сохранить журнал событий перед очисткой?" IDS_RESTOREDEFAULTS "Do you want to restore all settings for this log to their default values?" IDS_EVENTSTRINGIDNOTFOUND "Не найдено описание для события с кодом ( %lu ) в источнике ( %s ). Возможно, на локальном компьютере нет нужных данных в реестре или файлов DLL сообщений для отображения сообщений удаленного компьютера.\n\nСледующая информация часть события:\n\n" + IDS_CONTFROMBEGINNING "You have reached the end of the event log. Do you want to continue from the beginning?" + IDS_CONTFROMEND "You have reached the beginning of the event log. Do you want to continue from the end?" END STRINGTABLE diff --git a/base/applications/mscutils/eventvwr/lang/sk-SK.rc b/base/applications/mscutils/eventvwr/lang/sk-SK.rc index 3f6a3fe5bb022..16cd7cdb414dc 100644 --- a/base/applications/mscutils/eventvwr/lang/sk-SK.rc +++ b/base/applications/mscutils/eventvwr/lang/sk-SK.rc @@ -167,6 +167,8 @@ BEGIN IDS_CLEAREVENTS_MSG "Do you want to save this event log before clearing it?" IDS_RESTOREDEFAULTS "Do you want to restore all settings for this log to their default values?" IDS_EVENTSTRINGIDNOTFOUND "Popis pre udalosť ID ( %lu ) zo zdroja ( %s ) nebol nájdený. The local computer may not have the necessary registry information or message DLL files to display messages from a remote computer.\n\nThe following information is part of the event:\n\n" + IDS_CONTFROMBEGINNING "You have reached the end of the event log. Do you want to continue from the beginning?" + IDS_CONTFROMEND "You have reached the beginning of the event log. Do you want to continue from the end?" END STRINGTABLE diff --git a/base/applications/mscutils/eventvwr/lang/sq-AL.rc b/base/applications/mscutils/eventvwr/lang/sq-AL.rc index 2a3b1a556b0da..95f7e50fad9c3 100644 --- a/base/applications/mscutils/eventvwr/lang/sq-AL.rc +++ b/base/applications/mscutils/eventvwr/lang/sq-AL.rc @@ -167,6 +167,8 @@ BEGIN IDS_CLEAREVENTS_MSG "Do you want to save this event log before clearing it?" IDS_RESTOREDEFAULTS "Do you want to restore all settings for this log to their default values?" IDS_EVENTSTRINGIDNOTFOUND "Përshkrimi për ngjarjet ID ( %lu ) në burim ( %s ) nuk gjindet. Kompjuter vendas mund të mos ketë informacionin e regjistrit te nevojshem ose mesazhin për dokumentat DLL për të shfaqur nga një kompjuter në distancë.\n\nThe following information is part of the event:\n\n" + IDS_CONTFROMBEGINNING "You have reached the end of the event log. Do you want to continue from the beginning?" + IDS_CONTFROMEND "You have reached the beginning of the event log. Do you want to continue from the end?" END STRINGTABLE diff --git a/base/applications/mscutils/eventvwr/lang/sv-SE.rc b/base/applications/mscutils/eventvwr/lang/sv-SE.rc index d420514293233..723a2ef19367b 100644 --- a/base/applications/mscutils/eventvwr/lang/sv-SE.rc +++ b/base/applications/mscutils/eventvwr/lang/sv-SE.rc @@ -167,6 +167,8 @@ BEGIN IDS_CLEAREVENTS_MSG "Do you want to save this event log before clearing it?" IDS_RESTOREDEFAULTS "Do you want to restore all settings for this log to their default values?" IDS_EVENTSTRINGIDNOTFOUND "Beskrivning av Händelse ID ( %lu ) i källan ( %s ) kan inte hittas. Lokal dator har inte nödvendig registerinformation eller meddelander DLL filer for å vise meddelander från en fjärr dator.\n\nThe following information is part of the event:\n\n" + IDS_CONTFROMBEGINNING "You have reached the end of the event log. Do you want to continue from the beginning?" + IDS_CONTFROMEND "You have reached the beginning of the event log. Do you want to continue from the end?" END STRINGTABLE diff --git a/base/applications/mscutils/eventvwr/lang/tr-TR.rc b/base/applications/mscutils/eventvwr/lang/tr-TR.rc index e9710e2c39aed..b951b08dd5f01 100644 --- a/base/applications/mscutils/eventvwr/lang/tr-TR.rc +++ b/base/applications/mscutils/eventvwr/lang/tr-TR.rc @@ -168,6 +168,8 @@ BEGIN IDS_CLEAREVENTS_MSG "Silmeden önce bu olay kaydını kaydetmek ister misiniz?" IDS_RESTOREDEFAULTS "Bu günlük için tüm ayarları varsayılan değerlerine geri yüklemek istiyor musunuz?" IDS_EVENTSTRINGIDNOTFOUND "( %s ) kaynağındaki ( %lu ) olay kimliği için açıklama bulunamıyor. Yerel bilgisayarda, uzak bilgisayardan iletileri görüntülemesi için gerekli Kayıt Defteri bilgisi veya ileti DLL dosyaları olmayabilir.\n\nAşağıdaki bilgi olayın parçasıdır:\n\n" + IDS_CONTFROMBEGINNING "You have reached the end of the event log. Do you want to continue from the beginning?" + IDS_CONTFROMEND "You have reached the beginning of the event log. Do you want to continue from the end?" END STRINGTABLE diff --git a/base/applications/mscutils/eventvwr/lang/uk-UA.rc b/base/applications/mscutils/eventvwr/lang/uk-UA.rc index c50f93892e268..644267f9edc6c 100644 --- a/base/applications/mscutils/eventvwr/lang/uk-UA.rc +++ b/base/applications/mscutils/eventvwr/lang/uk-UA.rc @@ -169,6 +169,8 @@ BEGIN IDS_CLEAREVENTS_MSG "Do you want to save this event log before clearing it?" IDS_RESTOREDEFAULTS "Do you want to restore all settings for this log to their default values?" IDS_EVENTSTRINGIDNOTFOUND "Опис для Ідентифікатора події ( %lu ) за джерелом ( %s ) не знайдено. Локальний комп'ютер може не мати необхідної інформації в реєстрі чи DLL файлів повідомлень для відображення повідомлень, що надходять від віддаленого комп'ютера.\n\nThe following information is part of the event:\n\n" + IDS_CONTFROMBEGINNING "You have reached the end of the event log. Do you want to continue from the beginning?" + IDS_CONTFROMEND "You have reached the beginning of the event log. Do you want to continue from the end?" END STRINGTABLE diff --git a/base/applications/mscutils/eventvwr/lang/zh-CN.rc b/base/applications/mscutils/eventvwr/lang/zh-CN.rc index 3a94b9120340c..42c844605608f 100644 --- a/base/applications/mscutils/eventvwr/lang/zh-CN.rc +++ b/base/applications/mscutils/eventvwr/lang/zh-CN.rc @@ -169,6 +169,8 @@ BEGIN IDS_CLEAREVENTS_MSG "你想要在清除之前保存此事件日志吗?" IDS_RESTOREDEFAULTS "你想要将这个日志的所有设置恢复为默认值吗?" IDS_EVENTSTRINGIDNOTFOUND "无法找到来源(%s)中的事件 ID(%lu)的描述。本地计算机可能没有显示来自远程计算机的消息所必需的注册表信息或消息 DLL 文件。\n\n下面的信息是事件的一部分:\n\n" + IDS_CONTFROMBEGINNING "You have reached the end of the event log. Do you want to continue from the beginning?" + IDS_CONTFROMEND "You have reached the beginning of the event log. Do you want to continue from the end?" END STRINGTABLE diff --git a/base/applications/mscutils/eventvwr/lang/zh-HK.rc b/base/applications/mscutils/eventvwr/lang/zh-HK.rc index 98097e6154918..08a3105b454dd 100644 --- a/base/applications/mscutils/eventvwr/lang/zh-HK.rc +++ b/base/applications/mscutils/eventvwr/lang/zh-HK.rc @@ -168,6 +168,8 @@ BEGIN IDS_CLEAREVENTS_MSG "您想在清除之前儲存這個事件記錄嗎?" IDS_RESTOREDEFAULTS "您要將這個記錄的所有設定還原至預設值嗎?" IDS_EVENTSTRINGIDNOTFOUND "找不到來源(%s)中的事件 ID(%lu)的描述。本地電腦可能沒有顯示來自遠端電腦訊息所需的註冊表資訊或訊息 DLL 檔。\n\n下列資訊是部分事件:\n\n" + IDS_CONTFROMBEGINNING "You have reached the end of the event log. Do you want to continue from the beginning?" + IDS_CONTFROMEND "You have reached the beginning of the event log. Do you want to continue from the end?" END STRINGTABLE diff --git a/base/applications/mscutils/eventvwr/lang/zh-TW.rc b/base/applications/mscutils/eventvwr/lang/zh-TW.rc index 43fafc0e50049..f48152455f8e3 100644 --- a/base/applications/mscutils/eventvwr/lang/zh-TW.rc +++ b/base/applications/mscutils/eventvwr/lang/zh-TW.rc @@ -168,6 +168,8 @@ BEGIN IDS_CLEAREVENTS_MSG "您要在清除之前儲存此事件記錄嗎?" IDS_RESTOREDEFAULTS "您要這個記錄的所有設定還原至預設值嗎?" IDS_EVENTSTRINGIDNOTFOUND "找不到來源(%s)中的事件 ID(%lu)的描述。本地電腦可能沒有顯示來自遠端電腦消息所必需的註冊表資訊或消息 DLL 檔。\n\n下列資訊是部分事件︰\n\n" + IDS_CONTFROMBEGINNING "You have reached the end of the event log. Do you want to continue from the beginning?" + IDS_CONTFROMEND "You have reached the beginning of the event log. Do you want to continue from the end?" END STRINGTABLE diff --git a/base/applications/mscutils/eventvwr/resource.h b/base/applications/mscutils/eventvwr/resource.h index 27c61bc2cb00c..141d4945d6c89 100644 --- a/base/applications/mscutils/eventvwr/resource.h +++ b/base/applications/mscutils/eventvwr/resource.h @@ -105,6 +105,8 @@ #define IDS_CLEAREVENTS_MSG 110 #define IDS_EVENTSTRINGIDNOTFOUND 111 #define IDS_RESTOREDEFAULTS 112 +#define IDS_CONTFROMBEGINNING 113 +#define IDS_CONTFROMEND 114 #define IDS_USAGE 120 #define IDS_EVENTLOGFILE 121 diff --git a/base/applications/mscutils/servman/lang/ja-JP.rc b/base/applications/mscutils/servman/lang/ja-JP.rc index e80dee826cc5f..24728904d25cd 100644 --- a/base/applications/mscutils/servman/lang/ja-JP.rc +++ b/base/applications/mscutils/servman/lang/ja-JP.rc @@ -96,52 +96,52 @@ BEGIN END IDD_LOGON DIALOGEX 6, 6, 253, 232 -CAPTION "Log On" -FONT 8, "MS Shell Dlg", 0, 0 +CAPTION "ログオン" +FONT 9, "MS UI Gothic", 0, 0 STYLE DS_SHELLFONT | WS_BORDER | WS_VISIBLE | WS_DLGFRAME | WS_SYSMENU | WS_GROUP | WS_TABSTOP BEGIN - LTEXT "Log on as:", IDC_STATIC, 7, 7, 238, 8 - AUTORADIOBUTTON "&Local System account", IDC_LOGON_SYSTEMACCOUNT, 7, 22, 238, 10, BS_TOP | BS_MULTILINE | WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP - AUTORADIOBUTTON "&This account:", IDC_LOGON_THISACCOUNT, 7, 52, 60, 10, BS_TOP | BS_MULTILINE | WS_CHILD | WS_VISIBLE - AUTOCHECKBOX "Allo&w service to interact with desktop", IDC_LOGON_INTERACTIVE, 18, 34, 227, 10, WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP | BS_TOP | BS_MULTILINE + LTEXT "ログオン ユーザー:", IDC_STATIC, 7, 7, 238, 8 + AUTORADIOBUTTON "ローカル システム アカウント(&L)", IDC_LOGON_SYSTEMACCOUNT, 7, 22, 238, 10, BS_TOP | BS_MULTILINE | WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP + AUTORADIOBUTTON "このアカウント(&T):", IDC_LOGON_THISACCOUNT, 7, 52, 60, 10, BS_TOP | BS_MULTILINE | WS_CHILD | WS_VISIBLE + AUTOCHECKBOX "サービスがデスクトップと対話できるようにする(&W)", IDC_LOGON_INTERACTIVE, 18, 34, 227, 10, WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP | BS_TOP | BS_MULTILINE EDITTEXT IDC_LOGON_ACCOUNTNAME, 72, 50, 103, 14, ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Browse...", IDC_LOGON_SEARCH, 185, 50, 60, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP - LTEXT "&Password:", IDC_LOGON_PW1TEXT, 18, 71, 33, 8, WS_CHILD | WS_VISIBLE | WS_DISABLED | WS_GROUP + PUSHBUTTON "参照(&B)...", IDC_LOGON_SEARCH, 185, 50, 60, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP + LTEXT "パスワード(&P):", IDC_LOGON_PW1TEXT, 18, 71, 33, 8, WS_CHILD | WS_VISIBLE | WS_DISABLED | WS_GROUP EDITTEXT IDC_LOGON_PASSWORD1, 72, 68, 104, 14, ES_LEFT | ES_PASSWORD | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP - LTEXT "&Confirm password:", IDC_LOGON_PW2TEXT, 18, 84, 47, 18, WS_CHILD | WS_VISIBLE | WS_DISABLED | WS_GROUP + LTEXT "パスワードの確認(&C):", IDC_LOGON_PW2TEXT, 18, 84, 47, 18, WS_CHILD | WS_VISIBLE | WS_DISABLED | WS_GROUP EDITTEXT IDC_LOGON_PASSWORD2, 72, 86, 104, 14, ES_LEFT | ES_PASSWORD | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP - LTEXT "You can enable or disable this service for the hardware profiles listed below:", IDC_STATIC, 7, 114, 210, 8, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "以下のハードウェア プロファイルに対してこのサービスを有効または無効にすることができます:", IDC_STATIC, 7, 114, 210, 8, WS_CHILD | WS_VISIBLE | WS_GROUP CONTROL "", IDC_LOGON_HWPROFILE, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_GROUP | WS_TABSTOP, 7, 124, 238, 65 - PUSHBUTTON "&Enable", IDC_LOGON_HWENABLE, 116, 197, 60, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_DISABLED - PUSHBUTTON "&Disable", IDC_LOGON_HWDISABLE, 185, 197, 60, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_DISABLED + PUSHBUTTON "有効にする(&E)", IDC_LOGON_HWENABLE, 116, 197, 60, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_DISABLED + PUSHBUTTON "無効にする(&D)", IDC_LOGON_HWDISABLE, 185, 197, 60, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_DISABLED END IDD_RECOVERY DIALOGEX 6, 6, 253, 232 -CAPTION "Recovery" -FONT 8, "MS Shell Dlg", 0, 0 +CAPTION "回復" +FONT 9, "MS UI Gothic", 0, 0 STYLE DS_SHELLFONT | WS_BORDER | WS_VISIBLE | WS_DLGFRAME | WS_SYSMENU | WS_GROUP | WS_TABSTOP BEGIN - LTEXT "Select the computer's response if this service fails.", IDC_STATIC, 7, 7, 238, 8 - LTEXT "&First failure:", IDC_STATIC, 7, 24, 92, 8 + LTEXT "このサービスが失敗した場合のコンピュータの応答を選択します。", IDC_STATIC, 7, 7, 238, 8 + LTEXT "最初の失敗(&F):", IDC_STATIC, 7, 24, 92, 8 COMBOBOX IDC_FIRST_FAILURE, 104, 22, 141, 147, WS_CHILD | WS_VISIBLE | WS_TABSTOP | CBS_DROPDOWNLIST - LTEXT "&Second failure:", IDC_STATIC, 7, 41, 92, 8 + LTEXT "二番目の失敗(&S):", IDC_STATIC, 7, 41, 92, 8 COMBOBOX IDC_SECOND_FAILURE, 104, 39, 141, 147, WS_CHILD | WS_VISIBLE | WS_TABSTOP | CBS_DROPDOWNLIST - LTEXT "Subsequent failures:", IDC_STATIC, 7, 58, 92, 8 + LTEXT "その後の失敗:", IDC_STATIC, 7, 58, 92, 8 COMBOBOX IDC_SUBSEQUENT_FAILURES, 104, 56, 141, 147, WS_CHILD | WS_VISIBLE | WS_TABSTOP | CBS_DROPDOWNLIST - LTEXT "Reset fail c&ounter after:", IDC_STATIC, 7, 75, 72, 8 + LTEXT "失敗カウンタのリセット(&O):", IDC_STATIC, 7, 75, 72, 8 EDITTEXT IDC_RESET_TIME, 104, 73, 40, 13, WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL | ES_NUMBER - LTEXT "days", IDC_STATIC, 150, 75, 95, 8 - LTEXT "Restart ser&vice after:", IDC_RESTART_TEXT1, 7, 92, 92, 8 + LTEXT "日後", IDC_STATIC, 150, 75, 95, 8 + LTEXT "サービスの再開(&V):", IDC_RESTART_TEXT1, 7, 92, 92, 8 EDITTEXT IDC_RESTART_TIME, 104, 90, 40, 13, WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL | ES_NUMBER - LTEXT "minutes", IDC_RESTART_TEXT2, 150, 92, 95, 8 - GROUPBOX "Run program", IDC_RUN_GROUPBOX, 7, 108, 238, 80 - LTEXT "&Program:", IDC_RUN_TEXT1, 14, 121, 168, 8 + LTEXT "分後", IDC_RESTART_TEXT2, 150, 92, 95, 8 + GROUPBOX "プログラムを実行する", IDC_RUN_GROUPBOX, 7, 108, 238, 80 + LTEXT "プログラム(&P):", IDC_RUN_TEXT1, 14, 121, 168, 8 EDITTEXT IDC_PROGRAM, 14, 131, 165, 14 - PUSHBUTTON "&Browse...", IDC_BROWSE_PROGRAM, 180, 131, 58, 14 - LTEXT "&Command line parameters:", IDC_RUN_TEXT2, 14, 155, 108, 8 + PUSHBUTTON "参照(&B)...", IDC_BROWSE_PROGRAM, 180, 131, 58, 14 + LTEXT "コマンドライン引数(&C):", IDC_RUN_TEXT2, 14, 155, 108, 8 EDITTEXT IDC_PARAMETERS, 128, 152, 110, 14 - AUTOCHECKBOX "Append fail count to &end of command line (/fail=%1%)", IDC_ADD_FAILCOUNT, 14, 171, 219, 10, WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_TOP | BS_MULTILINE - PUSHBUTTON "&Restart Computer Options...", IDC_RESTART_OPTIONS, 116, 197, 129, 14 + AUTOCHECKBOX "失敗回数をコマンドラインの末尾に追加する(&E) (/fail=%1%)", IDC_ADD_FAILCOUNT, 14, 171, 219, 10, WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_TOP | BS_MULTILINE + PUSHBUTTON "コンピュータの再起動オプション(&R)...", IDC_RESTART_OPTIONS, 116, 197, 129, 14 END IDD_DLG_DEPEND DIALOGEX 6, 6, 253, 225 @@ -324,14 +324,14 @@ END STRINGTABLE BEGIN - IDS_NO_ACTION "Take no action" - IDS_RESTART_SERVICE "Restart the Service" - IDS_RUN_PROGRAM "Run a Program" - IDS_RESTART_COMPUTER "Restart the Computer" + IDS_NO_ACTION "何もしない" + IDS_RESTART_SERVICE "サービスを再起動する" + IDS_RUN_PROGRAM "プログラムを実行する" + IDS_RESTART_COMPUTER "コンピュータを再起動" END STRINGTABLE BEGIN - IDS_NOT_SAME_PASSWORD "The Passwords are not the same!" - IDS_INVALID_PASSWORD "Enter a valid Password!" + IDS_NOT_SAME_PASSWORD "パスワードが同じではありません!" + IDS_INVALID_PASSWORD "有効なパスワードを入力してください。" END diff --git a/base/applications/mspaint/canvas.cpp b/base/applications/mspaint/canvas.cpp index 06074cf0c45a4..d95395320abff 100644 --- a/base/applications/mspaint/canvas.cpp +++ b/base/applications/mspaint/canvas.cpp @@ -16,16 +16,11 @@ CCanvasWindow::CCanvasWindow() , m_hitCanvasSizeBox(HIT_NONE) , m_ptOrig { -1, -1 } { - m_ahbmCached[0] = m_ahbmCached[1] = NULL; m_rcResizing.SetRectEmpty(); } CCanvasWindow::~CCanvasWindow() { - if (m_ahbmCached[0]) - ::DeleteObject(m_ahbmCached[0]); - if (m_ahbmCached[1]) - ::DeleteObject(m_ahbmCached[1]); } RECT CCanvasWindow::GetBaseRect() @@ -119,16 +114,30 @@ VOID CCanvasWindow::zoomTo(INT newZoom, LONG left, LONG top) Invalidate(TRUE); } -VOID CCanvasWindow::DoDraw(HDC hDC, RECT& rcClient, RECT& rcPaint) +BOOL CCanvasWindow::DoDraw(HDC hDC, RECT& rcClient, RECT& rcPaint) { // This is the target area we have to draw on CRect rcCanvasDraw; rcCanvasDraw.IntersectRect(&rcClient, &rcPaint); + // Calculate image size + CRect rcImage; + GetImageRect(rcImage); + SIZE sizeImage = { imageModel.GetWidth(), imageModel.GetHeight() }; + // We use a memory bitmap to reduce flickering + HBITMAP hbmCache1 = CreateDIBWithProperties(rcClient.right, rcClient.bottom); + if (!hbmCache1) + return FALSE; // Out of memory + HBITMAP hbmCache2 = CreateDIBWithProperties(sizeImage.cx, sizeImage.cy); + if (!hbmCache2) + { + ::DeleteObject(hbmCache1); + return FALSE; // Out of memory + } + HDC hdcMem0 = ::CreateCompatibleDC(hDC); - m_ahbmCached[0] = CachedBufferDIB(m_ahbmCached[0], rcClient.right, rcClient.bottom); - HGDIOBJ hbm0Old = ::SelectObject(hdcMem0, m_ahbmCached[0]); + HGDIOBJ hbm0Old = ::SelectObject(hdcMem0, hbmCache1); // Fill the background on hdcMem0 ::FillRect(hdcMem0, &rcCanvasDraw, (HBRUSH)(COLOR_APPWORKSPACE + 1)); @@ -138,11 +147,6 @@ VOID CCanvasWindow::DoDraw(HDC hDC, RECT& rcClient, RECT& rcPaint) if (!selectionModel.m_bShow && !::IsWindowVisible(textEditWindow)) drawSizeBoxes(hdcMem0, &rcBase, FALSE, &rcCanvasDraw); - // Calculate image size - CRect rcImage; - GetImageRect(rcImage); - SIZE sizeImage = { imageModel.GetWidth(), imageModel.GetHeight() }; - // Calculate the target area on the image CRect rcImageDraw = rcCanvasDraw; CanvasToImage(rcImageDraw); @@ -154,8 +158,7 @@ VOID CCanvasWindow::DoDraw(HDC hDC, RECT& rcClient, RECT& rcPaint) // hdcMem1 <-- imageModel HDC hdcMem1 = ::CreateCompatibleDC(hDC); - m_ahbmCached[1] = CachedBufferDIB(m_ahbmCached[1], sizeImage.cx, sizeImage.cy); - HGDIOBJ hbm1Old = ::SelectObject(hdcMem1, m_ahbmCached[1]); + HGDIOBJ hbm1Old = ::SelectObject(hdcMem1, hbmCache2); ::BitBlt(hdcMem1, rcImageDraw.left, rcImageDraw.top, rcImageDraw.Width(), rcImageDraw.Height(), imageModel.GetDC(), rcImageDraw.left, rcImageDraw.top, SRCCOPY); @@ -208,6 +211,10 @@ VOID CCanvasWindow::DoDraw(HDC hDC, RECT& rcClient, RECT& rcPaint) // Clean up hdcMem0 ::SelectObject(hdcMem0, hbm0Old); ::DeleteDC(hdcMem0); + ::DeleteObject(hbmCache2); + ::DeleteObject(hbmCache1); + + return TRUE; } VOID CCanvasWindow::updateScrollRange() @@ -691,9 +698,22 @@ LRESULT CCanvasWindow::OnPaint(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH RECT rcClient; GetClientRect(&rcClient); + static BOOL s_bShowedOutOfMemory = FALSE; // Don't show "Out Of Memory" message multiple time + PAINTSTRUCT ps; HDC hDC = BeginPaint(&ps); - DoDraw(hDC, rcClient, ps.rcPaint); + + if (DoDraw(hDC, rcClient, ps.rcPaint)) + { + s_bShowedOutOfMemory = FALSE; + } + else if (!s_bShowedOutOfMemory) + { + ShowOutOfMemory(); + s_bShowedOutOfMemory = TRUE; + imageModel.ClearHistory(); // Reduce memory usage + } + EndPaint(&ps); return 0; } diff --git a/base/applications/mspaint/canvas.h b/base/applications/mspaint/canvas.h index ef0323df65f46..9c803d572b663 100644 --- a/base/applications/mspaint/canvas.h +++ b/base/applications/mspaint/canvas.h @@ -57,12 +57,11 @@ class CCanvasWindow : public CWindowImpl protected: HITTEST m_hitCanvasSizeBox; POINT m_ptOrig; // The origin of drag start - HBITMAP m_ahbmCached[2]; // The cached buffer bitmaps CRect m_rcResizing; // Resizing rectagle HITTEST CanvasHitTest(POINT pt); RECT GetBaseRect(); - VOID DoDraw(HDC hDC, RECT& rcClient, RECT& rcPaint); + BOOL DoDraw(HDC hDC, RECT& rcClient, RECT& rcPaint); VOID OnHVScroll(WPARAM wParam, INT fnBar); LRESULT OnSize(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); diff --git a/base/applications/mspaint/dib.cpp b/base/applications/mspaint/dib.cpp index 6ff4f200a5b3e..93670e0e34cb0 100644 --- a/base/applications/mspaint/dib.cpp +++ b/base/applications/mspaint/dib.cpp @@ -230,6 +230,7 @@ HBITMAP InitializeImage(LPCWSTR name, LPWIN32_FIND_DATAW pFound, BOOL isFile) if (hBitmap == NULL) { ShowOutOfMemory(); + imageModel.ClearHistory(); return NULL; } diff --git a/base/applications/mspaint/history.cpp b/base/applications/mspaint/history.cpp index c7b32cc5ab46d..6fd7e7910d6bc 100644 --- a/base/applications/mspaint/history.cpp +++ b/base/applications/mspaint/history.cpp @@ -130,6 +130,7 @@ void ImageModel::PushImageForUndo() if (hbm == NULL) { ShowOutOfMemory(); + ClearHistory(); return; } @@ -143,6 +144,7 @@ void ImageModel::PushImageForUndo(HBITMAP hbm) if (hbm == NULL) { ShowOutOfMemory(); + ClearHistory(); return; } @@ -201,6 +203,7 @@ void ImageModel::Crop(int nWidth, int nHeight, int nOffsetX, int nOffsetY) if (!hbmNew) { ShowOutOfMemory(); + ClearHistory(); return; } diff --git a/base/applications/mspaint/lang/fr-FR.rc b/base/applications/mspaint/lang/fr-FR.rc index 84c2b2d6468ff..b7aa30eaba765 100644 --- a/base/applications/mspaint/lang/fr-FR.rc +++ b/base/applications/mspaint/lang/fr-FR.rc @@ -44,7 +44,7 @@ BEGIN MENUITEM "&Copier\tCtrl+C", IDM_EDITCOPY MENUITEM "C&oller\tCtrl+V", IDM_EDITPASTE MENUITEM SEPARATOR - MENUITEM "Crop &selection", IDM_CROPSELECTION + MENUITEM "Ro&gner la sélection", IDM_CROPSELECTION MENUITEM "&Effacer la sélection\tDel", IDM_EDITDELETESELECTION MENUITEM "&Inverser la sélection", IDM_EDITINVERTSELECTION MENUITEM "&Sélectionner tout\tCtrl+A", IDM_EDITSELECTALL @@ -110,7 +110,7 @@ BEGIN MENUITEM "&Copier\tCtrl+C", IDM_EDITCOPY MENUITEM "C&oller\tCtrl+V", IDM_EDITPASTE MENUITEM SEPARATOR - MENUITEM "Crop &selection", IDM_CROPSELECTION + MENUITEM "Ro&gner la sélection", IDM_CROPSELECTION MENUITEM "&Effacer la sélection\tDel", IDM_EDITDELETESELECTION MENUITEM "&Sélectionner tout\tCtrl+A", IDM_EDITSELECTALL MENUITEM SEPARATOR @@ -269,8 +269,8 @@ BEGIN IDS_UNDERLINE "Underline" IDS_VERTICAL "Vertical" IDS_PRINTRES "%d x %d pixel/cm" - IDS_CANTPASTE "Failed to paste from the clipboard. The data format is either incorrect or not supported." - IDS_SAVEERROR "Failed to save the bitmap to file:\n\n%s" - IDS_CANTSENDMAIL "Failed to send a mail." - IDS_LOSECOLOR "The color information will be lost in this operation. Are you sure to proceed?" + IDS_CANTPASTE "Échec lors de la copie depuis le presse-papiers. Les données sont soit incorrectes soit non supportées." + IDS_SAVEERROR "Échec lors de la sauvegarde dans le fichier :\n\n%s" + IDS_CANTSENDMAIL "Échec lors de l'envoi d'un mail." + IDS_LOSECOLOR "Les informations de couleurs vont être perdues dans cette opération. Êtes-vous sûr de continuer ?" END diff --git a/base/applications/mspaint/main.cpp b/base/applications/mspaint/main.cpp index 3b6aa307810b9..53ae63300178b 100644 --- a/base/applications/mspaint/main.cpp +++ b/base/applications/mspaint/main.cpp @@ -957,9 +957,14 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH HBITMAP hbmCopy = selectionModel.GetSelectionContents(); HGLOBAL hGlobal = BitmapToClipboardDIB(hbmCopy); if (hGlobal) + { ::SetClipboardData(CF_DIB, hGlobal); + } else + { ShowOutOfMemory(); + imageModel.ClearHistory(); + } ::DeleteObject(hbmCopy); } @@ -1093,6 +1098,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH if (!hbmSelection) { ShowOutOfMemory(); + imageModel.ClearHistory(); break; } SaveDIBToFile(hbmSelection, szFileName, FALSE); diff --git a/base/applications/mstsc/lang/fr-FR.rc b/base/applications/mstsc/lang/fr-FR.rc index 1210df9f74d08..fc756449871e2 100644 --- a/base/applications/mstsc/lang/fr-FR.rc +++ b/base/applications/mstsc/lang/fr-FR.rc @@ -55,7 +55,7 @@ BEGIN IDS_HIGHCOLOR15 "32,768 Couleurs (15 bit)" IDS_HIGHCOLOR16 "65,536 Couleurs (16 bit)" IDS_HIGHCOLOR24 "16,777,216 Couleurs (24 bit)" - IDS_HIGHCOLOR32 "Highest Quality (32 bit)" + IDS_HIGHCOLOR32 "La plus haute qualité (32 bit)" IDS_PIXEL "%lux%lu Pixels" IDS_FULLSCREEN "Plein écran" IDS_BROWSESERVER "" diff --git a/base/applications/mstsc/secure.c b/base/applications/mstsc/secure.c index 9de0b0919ec00..ddaf68d3e09d7 100644 --- a/base/applications/mstsc/secure.c +++ b/base/applications/mstsc/secure.c @@ -542,7 +542,7 @@ sec_out_mcs_data(STREAM s, uint32 selected_protocol) out_uint8s(s, 30 - hostlen); /* See - http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceddk40/html/cxtsksupportingremotedesktopprotocol.asp */ + http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceddk40/html/cxtsksupportingremotedesktopprotocol.asp (DEAD_LINK) */ out_uint32_le(s, g_keyboard_type); out_uint32_le(s, g_keyboard_subtype); out_uint32_le(s, g_keyboard_functionkeys); diff --git a/base/applications/network/dwnl/dwnl.rc b/base/applications/network/dwnl/dwnl.rc index 8047407d55166..070a9b477b3b0 100644 --- a/base/applications/network/dwnl/dwnl.rc +++ b/base/applications/network/dwnl/dwnl.rc @@ -11,6 +11,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL /* UTF-8 */ #pragma code_page(65001) + #ifdef LANGUAGE_DE_DE #include "lang/de-DE.rc" #endif diff --git a/base/applications/network/ping/lang/fr-FR.rc b/base/applications/network/ping/lang/fr-FR.rc index f37d2926caaf6..94809d9fe3ece 100644 --- a/base/applications/network/ping/lang/fr-FR.rc +++ b/base/applications/network/ping/lang/fr-FR.rc @@ -32,7 +32,7 @@ Options :\n\ IDS_CTRL_C "Ctrl-C\n" IDS_NO_RESOURCES "Ressources libres disponibles insuffisantes.\n" IDS_MISSING_ADDRESS "L'adresse IP doit être spécifiée.\n" - IDS_MISSING_VALUE "Une valeur doit être spécifie pour l'option %s.\n" + IDS_MISSING_VALUE "Une valeur doit être spécifiée pour l'option %s.\n" IDS_BAD_OPTION "Option incorrecte %s.\n" IDS_BAD_PARAMETER "Paramètre incorrect %s.\n" IDS_BAD_VALUE "Valeur incorrecte pour l'option %s, elle doit être entre %u et %u.\n" diff --git a/base/applications/network/ping/ping.c b/base/applications/network/ping/ping.c index 17afdfc57386f..d0ebc0397ae50 100644 --- a/base/applications/network/ping/ping.c +++ b/base/applications/network/ping/ping.c @@ -432,7 +432,11 @@ Ping(void) exit(1); } - ZeroMemory(SendBuffer, RequestSize); + /* Windows ping utility fills the optional data field with + * ASCII characters from 'a' to 'w', wrapping back around + * until SendBuffer is full. */ + for (ULONG i = 0; i < RequestSize; i++) + ((PUCHAR)SendBuffer)[i] = (UCHAR)('a' + (i % ('w' - 'a' + 1))); } if (Family == AF_INET6) @@ -483,6 +487,7 @@ Ping(void) ReplyBuffer, ReplySize, Timeout); } + /* TODO: Compare ReplyBuffer data to SendBuffer. */ free(SendBuffer); if (Status == 0) diff --git a/base/applications/network/telnet/doc/readme.txt b/base/applications/network/telnet/doc/readme.txt index abebe3415207e..4b0ff272d2c4c 100644 --- a/base/applications/network/telnet/doc/readme.txt +++ b/base/applications/network/telnet/doc/readme.txt @@ -59,8 +59,8 @@ Support for multiple screen sizes. ---------------- Since version 2.0, Console Telnet's new home page is -http://www.musc.edu/~brannanp/telnet/. You can get the latest version from -ftp://argeas.cs-net.gr/Telnet-Win32 or from the web page. Telnet is +https://web.archive.org/web/20010126035900/http://www.musc.edu/~brannanp/telnet/ . You can get the latest version from +ftp://argeas.cs-net.gr/Telnet-Win32 (DEAD_LINK) or from the web page. Telnet is available as full project (sources included) or as binaries only. If you would like to help to the development check the /devel directory on the ftp site for a recent alpha version. @@ -72,7 +72,7 @@ Telnet has it's own mailing list for announcements, bug reports, support, suggestions etc. To subscribe send e-mail to majordomo@argeas.cs-net.gr with empty Subject, and the word subscribe in the body. List's address is telnet-win32@argeas.cs-net.gr You can find the old archives at -http://www.cs-net.gr/lists +http://www.cs-net.gr/lists (DEAD_LINK) If you are only interested in announcements, follow the above procedures to subscribe to telnet-win32-announce. The development list is @@ -172,7 +172,7 @@ included to the next version. Telnet compiles with a variety of compilers. You will need at least Borland 4.x or newer compiler, or MSVC 2.0 or newer, or download a version -of gcc for Win32 (see http://www.musc.edu/~brannanp/telnet/gccwin32.html). +of gcc for Win32 (see https://web.archive.org/web/20010126054500/http://www.musc.edu/~brannanp/telnet/gccwin32.html). Copy the files from the directories BORLAND or MSVC to the main directory, change them to fit to your system, and recompile. The project comes with IDE files and makefiles. diff --git a/base/applications/network/telnet/doc/ssh.txt b/base/applications/network/telnet/doc/ssh.txt index 89d3f29d1a17c..e7b2ded179181 100644 --- a/base/applications/network/telnet/doc/ssh.txt +++ b/base/applications/network/telnet/doc/ssh.txt @@ -19,4 +19,4 @@ Unfortunately, all the ssh clients I've found don't work this way. You can outp 3) Get Openssh from http://www.openssh.com 4) Modify Openssh so it will compile, and get rid of all the termios stuff -Obviously this is a lot of work. If you need a good ssh client, try PuTTY from http://www.chiark.greenend.org.uk/~sgtatham/putty/. It may be possible to integrate PuTTY and Telnet, and that would certainly be easier than the above option. PuTTY is licensed under the MIT license, which seems to be compatible with the GPL. The primary advantage of integrating the two projects is that PuTTY would gain the key mappings that telnet has, and telnet would gain encryption. +Obviously this is a lot of work. If you need a good ssh client, try PuTTY from https://www.chiark.greenend.org.uk/~sgtatham/putty/ . It may be possible to integrate PuTTY and Telnet, and that would certainly be easier than the above option. PuTTY is licensed under the MIT license, which seems to be compatible with the GPL. The primary advantage of integrating the two projects is that PuTTY would gain the key mappings that telnet has, and telnet would gain encryption. diff --git a/base/applications/network/telnet/lang/en-US.rc b/base/applications/network/telnet/lang/en-US.rc index a13ad7f41443e..edac1d7d5c185 100644 --- a/base/applications/network/telnet/lang/en-US.rc +++ b/base/applications/network/telnet/lang/en-US.rc @@ -9,25 +9,25 @@ BEGIN MSG_HELP "Commands may be abbreviated. Commands are:\n\ncl[ose] close current connection\nop[en] connect to a site\nq[uit] exit telnet\n" MSG_HELP_1 "ke[ys] changes/displays keymaps (write keys to see the options)\nse[t] displays/alters configuration options\nz suspend\n? h[elp] print help information\n" MSG_INVCMD "Invalid command. Type ? for help.\n" - MSG_ERROR "%1 failed.\n" - MSG_INFO "%1\n" - MSG_WARNING "%1\n" - MSG_TRYING "Trying %1.%2.%3.%4:%5...\n" - MSG_CONNECTED "Connected to %1. Escape key is ALT-%2.\n" + MSG_ERROR "%1!hs! failed.\n" + MSG_INFO "%1!hs!\n" + MSG_WARNING "%1!hs!\n" + MSG_TRYING "Trying %1!hs!.%2!hs!.%3!hs!.%4!hs!:%5!hs!...\n" + MSG_CONNECTED "Connected to %1!hs!. Escape key is ALT-%2!hs!.\n" MSG_TERMBYREM "Connection terminated.\n" - MSG_KEYMAP "Loading %1 from %2.\n" + MSG_KEYMAP "Loading %1!hs! from %2!hs!.\n" MSG_ERRKEYMAP "Error loading keymap.\n" - MSG_DUMPFILE "Writing output to file %1.\n" - MSG_CONFIG "Loading configuration options from %1.\n" - MSG_NOINI "Error loading configuration file %1.\nLoading default options.\n" - MSG_BADVAL "Warning: invalid variable %1.\n" + MSG_DUMPFILE "Writing output to file %1!hs!.\n" + MSG_CONFIG "Loading configuration options from %1!hs!.\n" + MSG_NOINI "Error loading configuration file %1!hs!.\nLoading default options.\n" + MSG_BADVAL "Warning: invalid variable %1!hs!.\n" MSG_NOSPAWN "Unable to spawn process.\n" - MSG_RESOLVING "Looking up host: %1..." - MSG_NOSERVICE "Could not find TCP service %1.\n" - MSG_SIZEALIAS "Warning: size of alias %1 is too big, ignoring.\n" + MSG_RESOLVING "Looking up host: %1!hs!..." + MSG_NOSERVICE "Could not find TCP service %1!hs!.\n" + MSG_SIZEALIAS "Warning: size of alias %1!hs! is too big, ignoring.\n" MSG_ERRPIPE "Error: unable to spawn process for pipe.\n" MSG_BADUSAGE "Error: invalid usage of command.\n" - MSG_ALREADYCONNECTED "Already connected to %1.\n" + MSG_ALREADYCONNECTED "Already connected to %1!hs!.\n" MSG_WSAEINTR "Interrupted function call.\n" MSG_WSAEBADF "WSAEBADF\n" MSG_WSAEACCESS "Permission denied.\n" @@ -72,25 +72,25 @@ BEGIN MSG_WSATRY_AGAIN "Non-authoritative host not found.\n" MSG_WSANO_RECOVERY "This is a non-recoverable error.\n" MSG_WSANO_DATA "Valid name, no data record of requested type.\n" - MSG_KEYNOVAL "[GLOBAL]: No value for %1.\n" - MSG_KEYBADVAL "[GLOBAL]: Bad value for %1.\n" - MSG_KEYBADSTRUCT "%1: Bad structure.\n" - MSG_KEYBADCHARS "%1: Bad chars? %1 -> %3.\n" - MSG_KEYUNEXPLINE "Unexpected line ""%1"".\n" + MSG_KEYNOVAL "[GLOBAL]: No value for %1!hs!.\n" + MSG_KEYBADVAL "[GLOBAL]: Bad value for %1!hs!.\n" + MSG_KEYBADSTRUCT "%1!hs!: Bad structure.\n" + MSG_KEYBADCHARS "%1!hs!: Bad chars? %1!hs! -> %3!hs!.\n" + MSG_KEYUNEXPLINE "Unexpected line ""%1!hs!"".\n" MSG_KEYUNEXPEOF "Unexpended end of file.\n" - MSG_KEYUNEXPTOK "Unexpected token %1.\n" - MSG_KEYUNEXPTOKIN "Unexpected token in %1.\n" + MSG_KEYUNEXPTOK "Unexpected token %1!hs!.\n" + MSG_KEYUNEXPTOKIN "Unexpected token in %1!hs!.\n" MSG_KEYUNEXP "Unexpected end of file or token.\n" MSG_KEYNOGLOBAL "No [GLOBAL] definition!\n" - MSG_KEYNOCONFIG "No [CONFIG %1].\n" - MSG_KEYUSECONFIG "Use configuration: %1.\n" - MSG_KEYNOSWKEY "No switch key for ""%1"".\n" + MSG_KEYNOCONFIG "No [CONFIG %1!hs!].\n" + MSG_KEYUSECONFIG "Use configuration: %1!hs!.\n" + MSG_KEYNOSWKEY "No switch key for ""%1!hs!"".\n" MSG_KEYCANNOTDEF "You cannot define switch key for default keymap - ignored.\n" MSG_KEYDUPSWKEY "Duplicate switching key.\n" - MSG_KEYUNKNOWNMAP "Unknown keymap %1.\n" + MSG_KEYUNKNOWNMAP "Unknown keymap %1!hs!.\n" MSG_KEYNOCHARMAPS "No charmaps loaded.\n" MSG_KEYNOKEYMAPS "No keymaps loaded.\n" - MSG_KEYNUMMAPS "There are %1 maps.\n" + MSG_KEYNUMMAPS "There are %1!hs! maps.\n" MSG_KEYBADMAP "Bad keymap number - try 'keys display'\n" MSG_KEYMAPSWITCHED "keymap switched.\n" END diff --git a/base/applications/network/telnet/lang/pl-PL.rc b/base/applications/network/telnet/lang/pl-PL.rc index c75e95e825a1d..9cb42a47f85e0 100644 --- a/base/applications/network/telnet/lang/pl-PL.rc +++ b/base/applications/network/telnet/lang/pl-PL.rc @@ -9,25 +9,25 @@ BEGIN MSG_HELP "Polecenia mogą być skracane. Dostępne polecenia:\n\ncl[ose] zamknij bieżące połączenie\nop[en] połącz z witryną\nq[uit] zakończ telnet\n" MSG_HELP_1 "ke[ys] zmienia/wyświetla mapy klawiszy (wpisz klawisze,\naby zobaczyć opcje)\nse[t] wyświetla/zmienia opcje konfiguracji\nz wstrzymaj\n? h[elp] wypisz informacje pomocy\n" MSG_INVCMD "Nieprawidłowe polecenie. Wpisz ?, aby uzyskać pomoc.\n" - MSG_ERROR "%1 nie powiodło się.\n" - MSG_INFO "%1\n" - MSG_WARNING "%1\n" - MSG_TRYING "Podejmowanie próby %1.%2.%3.%4:%5...\n" - MSG_CONNECTED "Podłączono do %1. Klawisze wyjścia to ALT-%2.\n" + MSG_ERROR "%1!hs! nie powiodło się.\n" + MSG_INFO "%1!hs!\n" + MSG_WARNING "%1!hs!\n" + MSG_TRYING "Podejmowanie próby %1!hs!.%2!hs!.%3!hs!.%4!hs!:%5!hs!...\n" + MSG_CONNECTED "Podłączono do %1!hs!. Klawisze wyjścia to ALT-%2!hs!.\n" MSG_TERMBYREM "Połączenie zakończone.\n" - MSG_KEYMAP "Ładowanie %1 z %2.\n" + MSG_KEYMAP "Ładowanie %1!hs! z %2!hs!.\n" MSG_ERRKEYMAP "Błąd podczas ładowania mapy klawiszy.\n" - MSG_DUMPFILE "Zapisywanie danych wyjściowych do pliku %1.\n" - MSG_CONFIG "Ładowanie opcji konfiguracji z %1.\n" - MSG_NOINI "Błąd podczas ładowania pliku konfiguracyjnego %1.\nŁadowanie domyślnych opcji.\n" - MSG_BADVAL "Ostrzeżenie: nieprawidłowa zmienna %1.\n" + MSG_DUMPFILE "Zapisywanie danych wyjściowych do pliku %1!hs!.\n" + MSG_CONFIG "Ładowanie opcji konfiguracji z %1!hs!.\n" + MSG_NOINI "Błąd podczas ładowania pliku konfiguracyjnego %1!hs!.\nŁadowanie domyślnych opcji.\n" + MSG_BADVAL "Ostrzeżenie: nieprawidłowa zmienna %1!hs!.\n" MSG_NOSPAWN "Nie można zduplikować procesu.\n" - MSG_RESOLVING "Wyszukiwanie hosta: %1..." - MSG_NOSERVICE "Nie odnaleziono usługi TCP %1.\n" - MSG_SIZEALIAS "Ostrzeżenie: rozmiar aliasu %1 jest zbyt duży, ignorowanie.\n" + MSG_RESOLVING "Wyszukiwanie hosta: %1!hs!..." + MSG_NOSERVICE "Nie odnaleziono usługi TCP %1!hs!.\n" + MSG_SIZEALIAS "Ostrzeżenie: rozmiar aliasu %1!hs! jest zbyt duży, ignorowanie.\n" MSG_ERRPIPE "Błąd: nie można zduplikować procesu dla potoku.\n" MSG_BADUSAGE "Błąd: nieprawidłowe użycie polecenia.\n" - MSG_ALREADYCONNECTED "Już połączono z %1.\n" + MSG_ALREADYCONNECTED "Już połączono z %1!hs!.\n" MSG_WSAEINTR "Przerwano wywołanie funkcji.\n" MSG_WSAEBADF "WSAEBADF\n" MSG_WSAEACCESS "Odmowa uprawnień.\n" @@ -72,25 +72,25 @@ BEGIN MSG_WSATRY_AGAIN "Nie odnaleziono nieautorytatywnego hosta.\n" MSG_WSANO_RECOVERY "Ten błąd jest niemożliwy do naprawienia.\n" MSG_WSANO_DATA "Nazwa jest prawidłowa, brak rekordu danych żądanego typu.\n" - MSG_KEYNOVAL "[GLOBAL]: Brak wartości dla %1.\n" - MSG_KEYBADVAL "[GLOBAL]: Zła wartość dla %1.\n" - MSG_KEYBADSTRUCT "%1: Zła struktura.\n" - MSG_KEYBADCHARS "%1: Złe znaki? %1 -> %3.\n" - MSG_KEYUNEXPLINE "Nieoczekiwany wiersz ""%1"".\n" + MSG_KEYNOVAL "[GLOBAL]: Brak wartości dla %1!hs!.\n" + MSG_KEYBADVAL "[GLOBAL]: Zła wartość dla %1!hs!.\n" + MSG_KEYBADSTRUCT "%1!hs!: Zła struktura.\n" + MSG_KEYBADCHARS "%1!hs!: Złe znaki? %1!hs! -> %3!hs!.\n" + MSG_KEYUNEXPLINE "Nieoczekiwany wiersz ""%1!hs!"".\n" MSG_KEYUNEXPEOF "Nieoczekiwany koniec pliku.\n" - MSG_KEYUNEXPTOK "Nieoczekiwany token %1.\n" - MSG_KEYUNEXPTOKIN "Nieoczekiwany token w %1.\n" + MSG_KEYUNEXPTOK "Nieoczekiwany token %1!hs!.\n" + MSG_KEYUNEXPTOKIN "Nieoczekiwany token w %1!hs!.\n" MSG_KEYUNEXP "Nieoczekiwany koniec pliku lub tokena.\n" MSG_KEYNOGLOBAL "Brak definicji [GLOBAL]!\n" - MSG_KEYNOCONFIG "Brak [CONFIG %1].\n" - MSG_KEYUSECONFIG "Użyj konfiguracji: %1.\n" - MSG_KEYNOSWKEY "Brak klawisza przełączającego dla ""%1"".\n" + MSG_KEYNOCONFIG "Brak [CONFIG %1!hs!].\n" + MSG_KEYUSECONFIG "Użyj konfiguracji: %1!hs!.\n" + MSG_KEYNOSWKEY "Brak klawisza przełączającego dla ""%1!hs!"".\n" MSG_KEYCANNOTDEF "Nie można zdefiniować klawisza przełączającego dla domyślnej mapy klawiszy - zignorowano.\n" MSG_KEYDUPSWKEY "Duplikuj klawisz przełączający.\n" - MSG_KEYUNKNOWNMAP "Nieznana mapa klawiszy %1.\n" + MSG_KEYUNKNOWNMAP "Nieznana mapa klawiszy %1!hs!.\n" MSG_KEYNOCHARMAPS "Nie załadowano żadnych tablic znaków.\n" MSG_KEYNOKEYMAPS "Nie załadowano żadnych map klawiszy.\n" - MSG_KEYNUMMAPS "Istnieje %1 map.\n" + MSG_KEYNUMMAPS "Istnieje %1!hs! map.\n" MSG_KEYBADMAP "Zły numer mapy klawiszy - sróbuj 'keys display'\n" MSG_KEYMAPSWITCHED "mapa klawiszy przełączona.\n" END diff --git a/base/applications/network/telnet/lang/ro-RO.rc b/base/applications/network/telnet/lang/ro-RO.rc index 4e22517242b07..05ac44a9620ad 100644 --- a/base/applications/network/telnet/lang/ro-RO.rc +++ b/base/applications/network/telnet/lang/ro-RO.rc @@ -10,25 +10,25 @@ BEGIN MSG_HELP "Comenzile pot fi abreviate. Acestea sunt:\n\ncl[ose] Închide conexiunea curentă.\nop[en] Conectează la un sit.\nq[uit] Ieșire din telnet.\n" MSG_HELP_1 "ke[ys] Afișează/alterează configurații de taste.\nse[t] Afișează/alterează opțiunile de configurare.\nz Suspendă.\n? h[elp] Afișează informațiile de utilizare.\n" MSG_INVCMD "Comandă nevalidă. Tastați ? pentru informații.\n" - MSG_ERROR "%1 a eșuat.\n" - MSG_INFO "%1\n" - MSG_WARNING "%1\n" - MSG_TRYING "Este încearcată %1.%2.%3.%4:%5...\n" - MSG_CONNECTED "Conectat la %1. Pentru ieșire apăsați ALT-%2.\n" + MSG_ERROR "%1!hs! a eșuat.\n" + MSG_INFO "%1!hs!\n" + MSG_WARNING "%1!hs!\n" + MSG_TRYING "Este încearcată %1!hs!.%2!hs!.%3!hs!.%4!hs!:%5!hs!...\n" + MSG_CONNECTED "Conectat la %1!hs!. Pentru ieșire apăsați ALT-%2!hs!.\n" MSG_TERMBYREM "Conexiune încheiată.\n" - MSG_KEYMAP "Este încarcată %1 de la %2.\n" + MSG_KEYMAP "Este încarcată %1!hs! de la %2!hs!.\n" MSG_ERRKEYMAP "Eșec la încărcarea configurației de taste.\n" - MSG_DUMPFILE "Sunt scrise informații de ieșire în fișierul %1.\n" - MSG_CONFIG "Este încarcată din %1 opțiunile de configurare.\n" - MSG_NOINI "Eroare la încărcarea fișierului de configurare %1.\nSunt încărcate opțiunile implicite.\n" - MSG_BADVAL "Avertisment: variabila %1 nu este validă.\n" + MSG_DUMPFILE "Sunt scrise informații de ieșire în fișierul %1!hs!.\n" + MSG_CONFIG "Este încarcată din %1!hs! opțiunile de configurare.\n" + MSG_NOINI "Eroare la încărcarea fișierului de configurare %1!hs!.\nSunt încărcate opțiunile implicite.\n" + MSG_BADVAL "Avertisment: variabila %1!hs! nu este validă.\n" MSG_NOSPAWN "Lansarea procesului a eșuat.\n" - MSG_RESOLVING "Este căutată gazda: %1..." - MSG_NOSERVICE "Serviciul TCP %1 nu a fost găsit.\n" - MSG_SIZEALIAS "Avertisment: dimensiunea de alias %1 este prea mare, va fi ignorată.\n" + MSG_RESOLVING "Este căutată gazda: %1!hs!..." + MSG_NOSERVICE "Serviciul TCP %1!hs! nu a fost găsit.\n" + MSG_SIZEALIAS "Avertisment: dimensiunea de alias %1!hs! este prea mare, va fi ignorată.\n" MSG_ERRPIPE "Eroare: lansarea procesului pentru conexiune a eșuat.\n" MSG_BADUSAGE "Eroare: utilizare nevalidă a comenzii.\n" - MSG_ALREADYCONNECTED "Conexiunea la %1 a fost deja stabilită.\n" + MSG_ALREADYCONNECTED "Conexiunea la %1!hs! a fost deja stabilită.\n" MSG_WSAEINTR "Apel de funcție întrerupt.\n" MSG_WSAEBADF "WSAEBADF\n" MSG_WSAEACCESS "Acces respins.\n" @@ -73,25 +73,25 @@ BEGIN MSG_WSATRY_AGAIN "Gazda ne-autoritată nu a fost găsită.\n" MSG_WSANO_RECOVERY "Eroare, stare nerecuperabilă.\n" MSG_WSANO_DATA "Numeele este valid, nu există date de tipul solicitat.\n" - MSG_KEYNOVAL "[GLOBAL]: Nu există valoare pentru %1.\n" - MSG_KEYBADVAL "[GLOBAL]: Valoarea pentru %1 este eronată.\n" - MSG_KEYBADSTRUCT "%1: Structură eronată.\n" - MSG_KEYBADCHARS "%1: Caractere eronate? %1 -> %3.\n" - MSG_KEYUNEXPLINE "Rând neprevăzut «%1».\n" + MSG_KEYNOVAL "[GLOBAL]: Nu există valoare pentru %1!hs!.\n" + MSG_KEYBADVAL "[GLOBAL]: Valoarea pentru %1!hs! este eronată.\n" + MSG_KEYBADSTRUCT "%1!hs!: Structură eronată.\n" + MSG_KEYBADCHARS "%1!hs!: Caractere eronate? %1!hs! -> %3!hs!.\n" + MSG_KEYUNEXPLINE "Rând neprevăzut «%1!hs!».\n" MSG_KEYUNEXPEOF "Sfârșit neprevăzut de fișier.\n" - MSG_KEYUNEXPTOK "Simbol neprevăzut %1.\n" - MSG_KEYUNEXPTOKIN "Simbol neprevăzut la %1.\n" + MSG_KEYUNEXPTOK "Simbol neprevăzut %1!hs!.\n" + MSG_KEYUNEXPTOKIN "Simbol neprevăzut la %1!hs!.\n" MSG_KEYUNEXP "Sfârșit neprevăzut de fișier sau simbol.\n" MSG_KEYNOGLOBAL "Nu există definiție pentru [GLOBAL]!\n" - MSG_KEYNOCONFIG "Nu există [CONFIG %1].\n" - MSG_KEYUSECONFIG "Utilizare configurație: %1.\n" - MSG_KEYNOSWKEY "Nu există tastă de comutare pentru «%1».\n" + MSG_KEYNOCONFIG "Nu există [CONFIG %1!hs!].\n" + MSG_KEYUSECONFIG "Utilizare configurație: %1!hs!.\n" + MSG_KEYNOSWKEY "Nu există tastă de comutare pentru «%1!hs!».\n" MSG_KEYCANNOTDEF "În configurația implicită nu pot fi definite taste de comutare, vor fi ignorate.\n" MSG_KEYDUPSWKEY "Duplicare tastă de comutare.\n" - MSG_KEYUNKNOWNMAP "%1 este o configurație de taste necunoscută.\n" + MSG_KEYUNKNOWNMAP "%1!hs! este o configurație de taste necunoscută.\n" MSG_KEYNOCHARMAPS "Nu au fost încărcate configurații de caractere.\n" MSG_KEYNOKEYMAPS "Nu au fost încărcate configurații de taste.\n" - MSG_KEYNUMMAPS "În total există %1 configurații.\n" + MSG_KEYNUMMAPS "În total există %1!hs! configurații.\n" MSG_KEYBADMAP "Număr de configurație de taste nevalid, încercați «keys display»\n" MSG_KEYMAPSWITCHED "Configurația de taste a fost comutată.\n" END diff --git a/base/applications/network/telnet/lang/ru-RU.rc b/base/applications/network/telnet/lang/ru-RU.rc index 007c60c1f782e..423f3f58105cf 100644 --- a/base/applications/network/telnet/lang/ru-RU.rc +++ b/base/applications/network/telnet/lang/ru-RU.rc @@ -9,25 +9,25 @@ BEGIN MSG_HELP "Команды можно сократить. Команды:\n\ncl[ose] закрыть текущее соединение\nop[en] подключиться к узлу\nq[uit] выйти из telnet\n" MSG_HELP_1 "ke[ys] изменить/показать раскладку\nse[t] изменить/показать опции\nz приостановить\n? h[elp] отобразить справку\n" MSG_INVCMD "Неверная команда. Введите ? для справки.\n" - MSG_ERROR "%1 не удалось.\n" - MSG_INFO "%1\n" - MSG_WARNING "%1\n" - MSG_TRYING "Попытка %1.%2.%3.%4:%5...\n" - MSG_CONNECTED "Подключение к %1. Для выхода нажмите ALT-%2.\n" + MSG_ERROR "%1!hs! не удалось.\n" + MSG_INFO "%1!hs!\n" + MSG_WARNING "%1!hs!\n" + MSG_TRYING "Попытка %1!hs!.%2!hs!.%3!hs!.%4!hs!:%5!hs!...\n" + MSG_CONNECTED "Подключение к %1!hs!. Для выхода нажмите ALT-%2!hs!.\n" MSG_TERMBYREM "Соединение прервано.\n" - MSG_KEYMAP "Загрузка %1 из %2.\n" + MSG_KEYMAP "Загрузка %1!hs! из %2!hs!.\n" MSG_ERRKEYMAP "Ошибка при загрузке раскладки.\n" - MSG_DUMPFILE "Запись вывода в файл %1.\n" - MSG_CONFIG "Загрузка параметров из %1.\n" - MSG_NOINI "Ошибка загрузки параметров из %1.\nЗагрузка параметров по умолчанию.\n" - MSG_BADVAL "Предупреждение: неправильная переменная %1.\n" + MSG_DUMPFILE "Запись вывода в файл %1!hs!.\n" + MSG_CONFIG "Загрузка параметров из %1!hs!.\n" + MSG_NOINI "Ошибка загрузки параметров из %1!hs!.\nЗагрузка параметров по умолчанию.\n" + MSG_BADVAL "Предупреждение: неправильная переменная %1!hs!.\n" MSG_NOSPAWN "Невозможно породить процесс.\n" - MSG_RESOLVING "Поиск узла: %1..." - MSG_NOSERVICE "TCP служба не найдена: %1.\n" - MSG_SIZEALIAS "Внимание: Размер псевдонима %1 слишком большой, игнорирование.\n" + MSG_RESOLVING "Поиск узла: %1!hs!..." + MSG_NOSERVICE "TCP служба не найдена: %1!hs!.\n" + MSG_SIZEALIAS "Внимание: Размер псевдонима %1!hs! слишком большой, игнорирование.\n" MSG_ERRPIPE "Ошибка: невозможно породить процесс для пайпа.\n" MSG_BADUSAGE "Ошибка: недопустимое использование команды.\n" - MSG_ALREADYCONNECTED "Уже подключен к %1.\n" + MSG_ALREADYCONNECTED "Уже подключен к %1!hs!.\n" MSG_WSAEINTR "Вызов функции прерван.\n" MSG_WSAEBADF "WSAEBADF\n" MSG_WSAEACCESS "Отказано в доступе.\n" @@ -72,25 +72,25 @@ BEGIN MSG_WSATRY_AGAIN "Ненадежный узел не найден.\n" MSG_WSANO_RECOVERY "Это неустранимая ошибка.\n" MSG_WSANO_DATA "Действительное имя, без записи данных требуемого типаe.\n" - MSG_KEYNOVAL "[GLOBAL]: Нет значения для %1.\n" - MSG_KEYBADVAL "[GLOBAL]: Неверное значение для %1.\n" - MSG_KEYBADSTRUCT "%1: Неправильная структура.\n" - MSG_KEYBADCHARS "%1: Неверные символы? %1 -> %3.\n" - MSG_KEYUNEXPLINE "Неожиданная строка ""%1"".\n" + MSG_KEYNOVAL "[GLOBAL]: Нет значения для %1!hs!.\n" + MSG_KEYBADVAL "[GLOBAL]: Неверное значение для %1!hs!.\n" + MSG_KEYBADSTRUCT "%1!hs!: Неправильная структура.\n" + MSG_KEYBADCHARS "%1!hs!: Неверные символы? %1!hs! -> %3!hs!.\n" + MSG_KEYUNEXPLINE "Неожиданная строка ""%1!hs!"".\n" MSG_KEYUNEXPEOF "Неожиданный конец файла.\n" - MSG_KEYUNEXPTOK "Неожиданный символ %1.\n" - MSG_KEYUNEXPTOKIN "Неожиданный символ в %1.\n" + MSG_KEYUNEXPTOK "Неожиданный символ %1!hs!.\n" + MSG_KEYUNEXPTOKIN "Неожиданный символ в %1!hs!.\n" MSG_KEYUNEXP "Неожиданный конец файла или символ.\n" MSG_KEYNOGLOBAL "[GLOBAL] Не определено!\n" - MSG_KEYNOCONFIG "Нет [CONFIG %1].\n" - MSG_KEYUSECONFIG "Используются настройки: %1.\n" - MSG_KEYNOSWKEY "Нет клавиши переключения для ""%1"".\n" + MSG_KEYNOCONFIG "Нет [CONFIG %1!hs!].\n" + MSG_KEYUSECONFIG "Используются настройки: %1!hs!.\n" + MSG_KEYNOSWKEY "Нет клавиши переключения для ""%1!hs!"".\n" MSG_KEYCANNOTDEF "Нельзя указать клавишу изменения раскладки клавиатуры по умолчанию – игнорирование.\n" MSG_KEYDUPSWKEY "Эта кнопка уже назначина.\n" - MSG_KEYUNKNOWNMAP "Неизвестная раскладка %1.\n" + MSG_KEYUNKNOWNMAP "Неизвестная раскладка %1!hs!.\n" MSG_KEYNOCHARMAPS "Не загружена таблица символов.\n" MSG_KEYNOKEYMAPS "Не загружена раскладка.\n" - MSG_KEYNUMMAPS "Раскладка %1 уже существует.\n" + MSG_KEYNUMMAPS "Раскладка %1!hs! уже существует.\n" MSG_KEYBADMAP "Неправильный номер раскладки - попробуйте 'keys display'\n" MSG_KEYMAPSWITCHED "раскладка переключена.\n" END diff --git a/base/applications/network/telnet/lang/tr-TR.rc b/base/applications/network/telnet/lang/tr-TR.rc index 77c29b4c85626..c051774738cce 100644 --- a/base/applications/network/telnet/lang/tr-TR.rc +++ b/base/applications/network/telnet/lang/tr-TR.rc @@ -11,25 +11,25 @@ BEGIN MSG_HELP "Komutlar kısaltılmış olabilir. Komutlar:\n\ncl[ose] Şimdiki bağlantıyı kapat.\nop[en] Bir siteye bağlan.\nq[uit] Telnet'ten çık.\n" MSG_HELP_1 "ke[ys] Tuş haritasını değiştirir ya da görüntüler. (Seçenekleri görmek için keys yazınız.)\nse[t] Yapılandırma seçeneklerini görüntüler ya da değiştirir.\nz Askıya al.\n? h[elp] Yardım bilgisini yazdır.\n" MSG_INVCMD "Geçersiz komut. Yardım için ? yazınız.\n" - MSG_ERROR "%1 başarısız.\n" - MSG_INFO "%1\n" - MSG_WARNING "%1\n" - MSG_TRYING "Deneniyor: %1.%2.%3.%4:%5...\n" - MSG_CONNECTED "%1 anabilgisayarına bağlandı. Çıkış tuş kombinasyonu ALT-%2.\n" + MSG_ERROR "%1!hs! başarısız.\n" + MSG_INFO "%1!hs!\n" + MSG_WARNING "%1!hs!\n" + MSG_TRYING "Deneniyor: %1!hs!.%2!hs!.%3!hs!.%4!hs!:%5!hs!...\n" + MSG_CONNECTED "%1!hs! anabilgisayarına bağlandı. Çıkış tuş kombinasyonu ALT-%2!hs!.\n" MSG_TERMBYREM "Bağlantı sonlandırıldı.\n" - MSG_KEYMAP "%2'den %1 yükleniyor.\n" + MSG_KEYMAP "%2!hs!'den %1!hs! yükleniyor.\n" MSG_ERRKEYMAP "Klavye yerleşimi yüklemede hata.\n" - MSG_DUMPFILE "%1 dosyasına çıktı yazdırılıyor.\n" - MSG_CONFIG "%1'den yapılandırma ayarları yükleniyor.\n" - MSG_NOINI "%1 yapılandırma dosyasına yüklemede hata.\nVarsayılan ayarlar yükleniyor.\n" - MSG_BADVAL "Uyarı: Geçersiz değişken (%1).\n" + MSG_DUMPFILE "%1!hs! dosyasına çıktı yazdırılıyor.\n" + MSG_CONFIG "%1!hs!'den yapılandırma ayarları yükleniyor.\n" + MSG_NOINI "%1!hs! yapılandırma dosyasına yüklemede hata.\nVarsayılan ayarlar yükleniyor.\n" + MSG_BADVAL "Uyarı: Geçersiz değişken (%1!hs!).\n" MSG_NOSPAWN "İşlem oluşturulamıyor.\n" - MSG_RESOLVING "Anabilgisayara bakılıyor: %1..." - MSG_NOSERVICE "%1 TCP hizmeti bulunamadı.\n" - MSG_SIZEALIAS "Uyarı: %1 takma adının büyüklüğü çok büyük, yok sayılıyor.\n" + MSG_RESOLVING "Anabilgisayara bakılıyor: %1!hs!..." + MSG_NOSERVICE "%1!hs! TCP hizmeti bulunamadı.\n" + MSG_SIZEALIAS "Uyarı: %1!hs! takma adının büyüklüğü çok büyük, yok sayılıyor.\n" MSG_ERRPIPE "Hata: Boru için işlem oluşturulamıyor.\n" MSG_BADUSAGE "Hata: Komutun kullanımı geçersiz.\n" - MSG_ALREADYCONNECTED "%1'e zaten bağlanılmış.\n" + MSG_ALREADYCONNECTED "%1!hs!'e zaten bağlanılmış.\n" MSG_WSAEINTR "Fonksiyon çağrısı kesildi.\n" MSG_WSAEBADF "WSAEBADF\n" MSG_WSAEACCESS "İzin geri çevrildi.\n" @@ -74,25 +74,25 @@ BEGIN MSG_WSATRY_AGAIN "Yetkili olmayan anabilgisayar bulunamadı.\n" MSG_WSANO_RECOVERY "Bu bir karşılanamayan hatadır.\n" MSG_WSANO_DATA "Geçerli ad, istenilen tür kaydı verisi yok.\n" - MSG_KEYNOVAL "[GENEL]: %1 için değer yok.\n" - MSG_KEYBADVAL "[GENEL]: %1 için geçersiz değer.\n" - MSG_KEYBADSTRUCT "%1: Geçersiz yapı.\n" - MSG_KEYBADCHARS "%1: Geçersiz karakterler? %1 -> %3.\n" - MSG_KEYUNEXPLINE "Beklenmeyen satır: ""%1"".\n" + MSG_KEYNOVAL "[GENEL]: %1!hs! için değer yok.\n" + MSG_KEYBADVAL "[GENEL]: %1!hs! için geçersiz değer.\n" + MSG_KEYBADSTRUCT "%1!hs!: Geçersiz yapı.\n" + MSG_KEYBADCHARS "%1!hs!: Geçersiz karakterler? %1!hs! -> %3!hs!.\n" + MSG_KEYUNEXPLINE "Beklenmeyen satır: ""%1!hs!"".\n" MSG_KEYUNEXPEOF "Beklemeyen dosya sonu.\n" - MSG_KEYUNEXPTOK "Beklenmeyen simge: %1.\n" - MSG_KEYUNEXPTOKIN "%1'de beklenmeyen simge.\n" + MSG_KEYUNEXPTOK "Beklenmeyen simge: %1!hs!.\n" + MSG_KEYUNEXPTOKIN "%1!hs!'de beklenmeyen simge.\n" MSG_KEYUNEXP "Beklenmeyen dosya sonu ya da simge.\n" MSG_KEYNOGLOBAL "[GENEL] tanımlama yok!\n" - MSG_KEYNOCONFIG "[CONFIG %1] yok.\n" - MSG_KEYUSECONFIG "Yapılandırmayı kullan: %1.\n" - MSG_KEYNOSWKEY """%1"" için geçiş anahtarı yok.\n" + MSG_KEYNOCONFIG "[CONFIG %1!hs!] yok.\n" + MSG_KEYUSECONFIG "Yapılandırmayı kullan: %1!hs!.\n" + MSG_KEYNOSWKEY """%1!hs!"" için geçiş anahtarı yok.\n" MSG_KEYCANNOTDEF "Varsayılan anahtar haritası için geçiş anahtarı tanımlayamazsınız - yok sayıldı.\n" MSG_KEYDUPSWKEY "Aynı geçiş anahtarı.\n" - MSG_KEYUNKNOWNMAP "Bilinmeyen anahtar haritası: %1.\n" + MSG_KEYUNKNOWNMAP "Bilinmeyen anahtar haritası: %1!hs!.\n" MSG_KEYNOCHARMAPS "Bir karakter haritası yüklenmedi.\n" MSG_KEYNOKEYMAPS "Bir anahtar haritası yüklenmedi.\n" - MSG_KEYNUMMAPS "Burada %1 harita var.\n" + MSG_KEYNUMMAPS "Burada %1!hs! harita var.\n" MSG_KEYBADMAP "Geçersiz anahtar haritası numarası, ""keys display""ı deneyiniz.\n" MSG_KEYMAPSWITCHED "Anahtar haritasına geçildi.\n" END diff --git a/base/applications/network/telnet/lang/zh-CN.rc b/base/applications/network/telnet/lang/zh-CN.rc index b9d70f10a9aec..e96ce2b7b8bbe 100644 --- a/base/applications/network/telnet/lang/zh-CN.rc +++ b/base/applications/network/telnet/lang/zh-CN.rc @@ -17,25 +17,25 @@ BEGIN MSG_HELP "命令可以被简写。命令有:\n\ncl[ose] 关闭当前连接\nop[en] 连接到一个站点\nq[uit] 退出 telnet\n" MSG_HELP_1 "ke[ys] 修改或显示按键映射(写入一些键来查看选项)\nse[t] 显示或修改配置选项\nz 暂停\n? h[elp] 打印帮助信息\n" MSG_INVCMD "无效命令。输入 ? 获得帮助。\n" - MSG_ERROR "%1 失败。\n" - MSG_INFO "%1\n" - MSG_WARNING "%1\n" - MSG_TRYING "正在尝试 %1.%2.%3.%4:%5...\n" - MSG_CONNECTED "已连接到 %1。Escape 键是 ALT-%2。\n" + MSG_ERROR "%1!hs! 失败。\n" + MSG_INFO "%1!hs!\n" + MSG_WARNING "%1!hs!\n" + MSG_TRYING "正在尝试 %1!hs!.%2!hs!.%3!hs!.%4!hs!:%5!hs!...\n" + MSG_CONNECTED "已连接到 %1!hs!。Escape 键是 ALT-%2!hs!。\n" MSG_TERMBYREM "连接结束。\n" - MSG_KEYMAP "正在从 %2 加载 %1。\n" + MSG_KEYMAP "正在从 %2!hs! 加载 %1!hs!。\n" MSG_ERRKEYMAP "加载按键映射时发生错误。\n" - MSG_DUMPFILE "正在将输出写入到文件 %1 中。\n" - MSG_CONFIG "正在从 %1 中加载配置选项。\n" - MSG_NOINI "从配置文件 %1 中加载发生错误。\n正在加载默认选项。\n" - MSG_BADVAL "警告:无效变量 %1。\n" + MSG_DUMPFILE "正在将输出写入到文件 %1!hs! 中。\n" + MSG_CONFIG "正在从 %1!hs! 中加载配置选项。\n" + MSG_NOINI "从配置文件 %1!hs! 中加载发生错误。\n正在加载默认选项。\n" + MSG_BADVAL "警告:无效变量 %1!hs!。\n" MSG_NOSPAWN "无法创建进程。\n" - MSG_RESOLVING "正在查找主机:%1..." - MSG_NOSERVICE "无法找到 TCP 服务 %1。\n" - MSG_SIZEALIAS "警告:别名 %1 过大,已忽略。\n" + MSG_RESOLVING "正在查找主机:%1!hs!..." + MSG_NOSERVICE "无法找到 TCP 服务 %1!hs!。\n" + MSG_SIZEALIAS "警告:别名 %1!hs! 过大,已忽略。\n" MSG_ERRPIPE "错误:无法为管道创建进程。\n" MSG_BADUSAGE "错误:命令的用法无效。\n" - MSG_ALREADYCONNECTED "已经连接到 %1。\n" + MSG_ALREADYCONNECTED "已经连接到 %1!hs!。\n" MSG_WSAEINTR "函数调用已被中断。\n" MSG_WSAEBADF "WSAEBADF\n" MSG_WSAEACCESS "拒绝访问。\n" @@ -80,25 +80,25 @@ BEGIN MSG_WSATRY_AGAIN "未找到非授权主机。\n" MSG_WSANO_RECOVERY "这是一个无法恢复的错误。\n" MSG_WSANO_DATA "名称有效,但是没有与请求类型相同的数据记录。\n" - MSG_KEYNOVAL "[全局]:没有 %1 的值。\n" - MSG_KEYBADVAL "[全局]:%1 的值有错误。\n" - MSG_KEYBADSTRUCT "%1:错误的结构。\n" - MSG_KEYBADCHARS "%1:错误的字符?%1 -> %3。\n" - MSG_KEYUNEXPLINE "未预料的行 ""%1""。\n" + MSG_KEYNOVAL "[全局]:没有 %1!hs! 的值。\n" + MSG_KEYBADVAL "[全局]:%1!hs! 的值有错误。\n" + MSG_KEYBADSTRUCT "%1!hs!:错误的结构。\n" + MSG_KEYBADCHARS "%1!hs!:错误的字符?%1!hs! -> %3!hs!。\n" + MSG_KEYUNEXPLINE "未预料的行 ""%1!hs!""。\n" MSG_KEYUNEXPEOF "未预料的文件结束。\n" - MSG_KEYUNEXPTOK "未预料的令牌 %1。\n" - MSG_KEYUNEXPTOKIN "未预料的 %1 中的令牌。\n" + MSG_KEYUNEXPTOK "未预料的令牌 %1!hs!。\n" + MSG_KEYUNEXPTOKIN "未预料的 %1!hs! 中的令牌。\n" MSG_KEYUNEXP "未预料的文件或令牌结束。\n" MSG_KEYNOGLOBAL "没有 [全局] 定义!\n" - MSG_KEYNOCONFIG "没有 [配置 %1]。\n" - MSG_KEYUSECONFIG "使用配置:%1。\n" - MSG_KEYNOSWKEY "没有“%1”的切换键。\n" + MSG_KEYNOCONFIG "没有 [配置 %1!hs!]。\n" + MSG_KEYUSECONFIG "使用配置:%1!hs!。\n" + MSG_KEYNOSWKEY "没有“%1!hs!”的切换键。\n" MSG_KEYCANNOTDEF "您不能定义默认按键映射的切换键 - 已忽略。\n" MSG_KEYDUPSWKEY "重复的切换键。\n" - MSG_KEYUNKNOWNMAP "未知的按键映射 %1。\n" + MSG_KEYUNKNOWNMAP "未知的按键映射 %1!hs!。\n" MSG_KEYNOCHARMAPS "没有加载的字符映射。\n" MSG_KEYNOKEYMAPS "没有加载的按键映射。\n" - MSG_KEYNUMMAPS "有 %1 个映射。\n" + MSG_KEYNUMMAPS "有 %1!hs! 个映射。\n" MSG_KEYBADMAP "错误的按键映射码 - 请尝试“keys display”\n" MSG_KEYMAPSWITCHED "按键映射已经切换。\n" END diff --git a/base/applications/network/telnet/lang/zh-TW.rc b/base/applications/network/telnet/lang/zh-TW.rc index 8be539d105d3d..56cd84ecbf82a 100644 --- a/base/applications/network/telnet/lang/zh-TW.rc +++ b/base/applications/network/telnet/lang/zh-TW.rc @@ -16,25 +16,25 @@ BEGIN MSG_HELP "命令可以被簡寫。 命令有:\n\ncl[ose] 關閉目前連線\nop[en] 連線到一個網站\nq[uit] 退出 telnet\n" MSG_HELP_1 "ke[ys] 修改或顯示按鍵映射 (寫入一些鍵來查看選項)\nse[t] 顯示或修改配置選項\nz 暫停\n? h[elp] 列印說明資訊\n" MSG_INVCMD "無效的命令。輸入 ? 以取得說明。\n" - MSG_ERROR "%1 失敗。\n" - MSG_INFO "%1\n" - MSG_WARNING "%1\n" - MSG_TRYING "正在嘗試 %1.%2.%3.%4:%5...\n" - MSG_CONNECTED "已經連線到 %1。Escape 鍵是 ALT-%2.\n" + MSG_ERROR "%1!hs! 失敗。\n" + MSG_INFO "%1!hs!\n" + MSG_WARNING "%1!hs!\n" + MSG_TRYING "正在嘗試 %1!hs!.%2!hs!.%3!hs!.%4!hs!:%5!hs!...\n" + MSG_CONNECTED "已經連線到 %1!hs!。Escape 鍵是 ALT-%2!hs!.\n" MSG_TERMBYREM "連線結束。\n" - MSG_KEYMAP "正在從 %2 載入 %1。\n" + MSG_KEYMAP "正在從 %2!hs! 載入 %1!hs!。\n" MSG_ERRKEYMAP "載入按鍵映射時發生錯誤。\n" - MSG_DUMPFILE "正在將輸出寫入到檔案 %1 中。\n" - MSG_CONFIG "正在從 %1 中載入配置選項。\n" - MSG_NOINI "從配置檔案 %1 中載入發生錯誤。\n正在載入預設選項。\n" - MSG_BADVAL "警告: 無效的變量 %1。\n" + MSG_DUMPFILE "正在將輸出寫入到檔案 %1!hs! 中。\n" + MSG_CONFIG "正在從 %1!hs! 中載入配置選項。\n" + MSG_NOINI "從配置檔案 %1!hs! 中載入發生錯誤。\n正在載入預設選項。\n" + MSG_BADVAL "警告: 無效的變量 %1!hs!。\n" MSG_NOSPAWN "無法建立進程。\n" - MSG_RESOLVING "正在查找主機: %1..." - MSG_NOSERVICE "無法找到 TCP 服務 %1。\n" - MSG_SIZEALIAS "警告: 别名 %1 太大了,正在忽略。\n" + MSG_RESOLVING "正在查找主機: %1!hs!..." + MSG_NOSERVICE "無法找到 TCP 服務 %1!hs!。\n" + MSG_SIZEALIAS "警告: 别名 %1!hs! 太大了,正在忽略。\n" MSG_ERRPIPE "錯誤: 無法為管道建立進程。\n" MSG_BADUSAGE "錯誤: 無效的命令用法。\n" - MSG_ALREADYCONNECTED "已經連線到 %1。\n" + MSG_ALREADYCONNECTED "已經連線到 %1!hs!。\n" MSG_WSAEINTR "中斷的函數調用。\n" MSG_WSAEBADF "WSAEBADF\n" MSG_WSAEACCESS "拒絕存取。\n" @@ -79,25 +79,25 @@ BEGIN MSG_WSATRY_AGAIN "找不到非授權主機。\n" MSG_WSANO_RECOVERY "這是一個無法恢復的錯誤。\n" MSG_WSANO_DATA "名稱有效,但沒有請求數據記錄的類型。\n" - MSG_KEYNOVAL "[全域]: 沒有 %1 的值。\n" - MSG_KEYBADVAL "[全域]: %1 的值有錯誤。\n" - MSG_KEYBADSTRUCT "%1: 錯誤的結構。\n" - MSG_KEYBADCHARS "%1: 錯誤的字符?%1 -> %3。\n" - MSG_KEYUNEXPLINE "未預期的行 ""%1""。\n" + MSG_KEYNOVAL "[全域]: 沒有 %1!hs! 的值。\n" + MSG_KEYBADVAL "[全域]: %1!hs! 的值有錯誤。\n" + MSG_KEYBADSTRUCT "%1!hs!: 錯誤的結構。\n" + MSG_KEYBADCHARS "%1!hs!: 錯誤的字符?%1!hs! -> %3!hs!。\n" + MSG_KEYUNEXPLINE "未預期的行 ""%1!hs!""。\n" MSG_KEYUNEXPEOF "未預期的檔案結尾。\n" - MSG_KEYUNEXPTOK "未預期的權杖 %1。\n" - MSG_KEYUNEXPTOKIN "在 %1 中出現未預期的權杖。\n" + MSG_KEYUNEXPTOK "未預期的權杖 %1!hs!。\n" + MSG_KEYUNEXPTOKIN "在 %1!hs! 中出現未預期的權杖。\n" MSG_KEYUNEXP "未預期的檔案結尾或權杖。\n" MSG_KEYNOGLOBAL "沒有 [全域] 定義!\n" - MSG_KEYNOCONFIG "沒有 [配置 %1]。\n" - MSG_KEYUSECONFIG "使用配置: %1。\n" - MSG_KEYNOSWKEY "沒有 ""%1"" 的切換鍵。\n" + MSG_KEYNOCONFIG "沒有 [配置 %1!hs!]。\n" + MSG_KEYUSECONFIG "使用配置: %1!hs!。\n" + MSG_KEYNOSWKEY "沒有 ""%1!hs!"" 的切換鍵。\n" MSG_KEYCANNOTDEF "您不能定義預設按鍵映射的切換鍵 - 已略過。\n" MSG_KEYDUPSWKEY "重複的切換鍵。\n" - MSG_KEYUNKNOWNMAP "未知的按鍵映射 %1。\n" + MSG_KEYUNKNOWNMAP "未知的按鍵映射 %1!hs!。\n" MSG_KEYNOCHARMAPS "沒有已載入的字符映射。\n" MSG_KEYNOKEYMAPS "沒有已載入的按鍵映射。\n" - MSG_KEYNUMMAPS "有 %1 個映射。\n" + MSG_KEYNUMMAPS "有 %1!hs! 個映射。\n" MSG_KEYBADMAP "錯誤的按鍵映射碼 - 請嘗試 'keys display'\n" MSG_KEYMAPSWITCHED "按鍵映射已經切換。\n" END diff --git a/base/applications/network/telnet/precomp.h b/base/applications/network/telnet/precomp.h index c678b12c4628d..bb215f3f71d5f 100644 --- a/base/applications/network/telnet/precomp.h +++ b/base/applications/network/telnet/precomp.h @@ -9,6 +9,7 @@ #include #include #include +#include #define _INC_WINDOWS #include diff --git a/base/applications/network/telnet/src/tnerror.cpp b/base/applications/network/telnet/src/tnerror.cpp index 5278cd266cfec..82fda0b218073 100644 --- a/base/applications/network/telnet/src/tnerror.cpp +++ b/base/applications/network/telnet/src/tnerror.cpp @@ -81,6 +81,47 @@ int printit(const char * it){ return 0; } +#ifdef __REACTOS__ +int wprintit(LPCWSTR it) +{ + DWORD numwritten; + if (!ini.get_output_redir()) + { + if (!WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), + it, wcslen(it), &numwritten, NULL)) + { + return -1; + } + } + else + { + // calculate the number of bytes needed to store the UTF-8 string + int cbMultibyte = WideCharToMultiByte(CP_UTF8, 0, it, -1, NULL, 0, NULL, NULL); + if (cbMultibyte == 0) + return 0; + if (cbMultibyte < 0) + return -1; + // allocate the buffer for the UTF-8 string + char* szBuffer = new char[cbMultibyte]; + if (!szBuffer) + return -1; + + bool bSuccess = false; + if (WideCharToMultiByte(CP_UTF8, 0, it, -1, szBuffer, cbMultibyte, NULL, NULL) && + WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), + szBuffer, cbMultibyte, &numwritten, NULL)) + { + bSuccess = true; + } + + delete[] szBuffer; + if (!bSuccess) + return -1; + } + return 0; +} +#endif + int printm(LPTSTR szModule, BOOL fSystem, DWORD dwMessageId, ...) { int Result = 0; @@ -91,7 +132,23 @@ int printm(LPTSTR szModule, BOOL fSystem, DWORD dwMessageId, ...) va_list Ellipsis; va_start(Ellipsis, dwMessageId); +#ifdef __REACTOS__ + LPWSTR pszMessage = NULL; + DWORD dwMessage = 0; + if(fSystem) { + dwMessage = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, hModule, dwMessageId, + LANG_USER_DEFAULT, (LPWSTR)&pszMessage, 128, &Ellipsis); + } else { + // we will use a string table. + WCHAR wszString[256]; + if(LoadStringW(0, dwMessageId, wszString, sizeof(wszString) / sizeof(*wszString))) + dwMessage = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_STRING, wszString, dwMessageId, + LANG_USER_DEFAULT, (LPWSTR)&pszMessage, sizeof(wszString) / sizeof(*wszString), &Ellipsis); + } +#else LPTSTR pszMessage = 0; DWORD dwMessage = 0; if(fSystem) { @@ -106,6 +163,7 @@ int printm(LPTSTR szModule, BOOL fSystem, DWORD dwMessageId, ...) FORMAT_MESSAGE_FROM_STRING, szString, dwMessageId, LANG_USER_DEFAULT, (LPTSTR)&pszMessage, 256, &Ellipsis); } +#endif va_end(Ellipsis); @@ -113,8 +171,11 @@ int printm(LPTSTR szModule, BOOL fSystem, DWORD dwMessageId, ...) FreeLibrary(hModule); if (dwMessage) { - +#ifdef __REACTOS__ + Result = wprintit(pszMessage); +#else Result = printit(pszMessage); +#endif LocalFree(pszMessage); } diff --git a/base/applications/network/telnet/src/tnmisc.cpp b/base/applications/network/telnet/src/tnmisc.cpp index 6c98739806e2c..adeb03d811ff6 100644 --- a/base/applications/network/telnet/src/tnmisc.cpp +++ b/base/applications/network/telnet/src/tnmisc.cpp @@ -1,6 +1,6 @@ #include "precomp.h" -// from the PVAX (http://www.ccas.ru/~posp/popov/spawn.htm) +// from the PVAX (https://web.archive.org/web/20030707153537/http://www.ccas.ru/~posp/popov/spawn.htm) // Create a process with pipes to stdin/out/err BOOL CreateHiddenConsoleProcess(LPCTSTR szChildName, PROCESS_INFORMATION* ppi, LPHANDLE phInWrite, LPHANDLE phOutRead, diff --git a/base/applications/network/tracert/lang/fr-FR.rc b/base/applications/network/tracert/lang/fr-FR.rc index 073aedf67603b..2123236a31718 100644 --- a/base/applications/network/tracert/lang/fr-FR.rc +++ b/base/applications/network/tracert/lang/fr-FR.rc @@ -8,7 +8,7 @@ Usage: tracert [-d] [-h sauts_max] [-j liste_dhôtes] [-w délai] nom_de_la_cibl Options :\n\ -d Ne pas résoudre les adresses en noms d'hôtes.\n\ -h sauts_max Nombre de sauts maximum pour atteindre la cible.\n\ - -j liste_dhôtes Intinéraire source imprécis dans la liste d'hôtes.\n\ + -j liste_dhôtes Itinéraire source imprécis dans la liste d'hôtes.\n\ -w délai Délai d'expiration en millisecondes pour chaque réponse.\n\ -4 Force l'utilisation d'IPv4.\n\ -6 Force l'utilisation d'IPv6.\n\ diff --git a/base/applications/network/tracert/tracert.rc b/base/applications/network/tracert/tracert.rc index a39998756f251..6d24085060ecd 100644 --- a/base/applications/network/tracert/tracert.rc +++ b/base/applications/network/tracert/tracert.rc @@ -7,7 +7,6 @@ #define REACTOS_STR_ORIGINAL_COPYRIGHT "Ged Murphy (gedmurphy@reactos.org)" #include - /* UTF-8 */ #pragma code_page(65001) diff --git a/base/applications/notepad/lang/fr-FR.rc b/base/applications/notepad/lang/fr-FR.rc index 8d5d8574981ca..2283a9e13e6e9 100644 --- a/base/applications/notepad/lang/fr-FR.rc +++ b/base/applications/notepad/lang/fr-FR.rc @@ -25,7 +25,7 @@ BEGIN POPUP "&Fichier" BEGIN MENUITEM "&Nouveau\tCtrl+N", CMD_NEW - MENUITEM "New &Window\tCtrl+Shift+N", CMD_NEW_WINDOW + MENUITEM "Nouvelle &fenêtre\tCtrl+Shift+N", CMD_NEW_WINDOW MENUITEM "&Ouvrir\tCtrl+O", CMD_OPEN MENUITEM "&Enregistrer\tCtrl+S", CMD_SAVE MENUITEM "Enregistrer &sous...", CMD_SAVE_AS @@ -75,35 +75,35 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU | DS_CONTEXTHELP FONT 8, "MS Shell Dlg" CAPTION "Page Setup" BEGIN - GROUPBOX "Preview", 0, 240, 6, 120, 153, BS_GROUPBOX + GROUPBOX "Aperçu", 0, 240, 6, 120, 153, BS_GROUPBOX CONTROL "", rct1, "Static", SS_WHITERECT, 260, 42, 80, 80 CONTROL "", rct2, "Static", SS_GRAYRECT, 340, 46, 4, 80 CONTROL "", rct3, "Static", SS_GRAYRECT, 264, 122, 80, 4 - GROUPBOX "Paper", grp2, 8, 6, 224, 56, BS_GROUPBOX - LTEXT "&Size:", stc2, 16, 22, 36, 8 + GROUPBOX "Papier", grp2, 8, 6, 224, 56, BS_GROUPBOX + LTEXT "&Taille :", stc2, 16, 22, 36, 8 COMBOBOX cmb2, 64, 20, 160, 160, CBS_SIMPLE | CBS_DROPDOWN | CBS_SORT | WS_GROUP | WS_TABSTOP | WS_VSCROLL - LTEXT "&Tray:", stc3, 16, 42, 36, 8 + LTEXT "&Source :", stc3, 16, 42, 36, 8 COMBOBOX cmb3, 64, 40, 160, 160, CBS_SIMPLE | CBS_DROPDOWN | CBS_SORT | WS_GROUP | WS_TABSTOP | WS_VSCROLL GROUPBOX "Orientation", grp1, 8, 66, 64, 56, BS_GROUPBOX - AUTORADIOBUTTON "&Portrait", rad1, 16, 80, 52, 12, WS_GROUP | WS_TABSTOP - AUTORADIOBUTTON "&Landscape", rad2, 16, 100, 52, 12 - GROUPBOX "Borders", grp4, 80, 66, 152, 56, BS_GROUPBOX - LTEXT "L&eft:", stc15, 88, 82, 30, 8 + AUTORADIOBUTTON "P&ortrait", rad1, 16, 80, 52, 12, WS_GROUP | WS_TABSTOP + AUTORADIOBUTTON "Pa&ysage", rad2, 16, 100, 52, 12 + GROUPBOX "Marges", grp4, 80, 66, 152, 56, BS_GROUPBOX + LTEXT "&Gauche :", stc15, 88, 82, 30, 8 EDITTEXT edt4, 119, 80, 36, 12, WS_TABSTOP | WS_GROUP | WS_BORDER - LTEXT "&Right:", stc16, 159, 82, 30, 8 + LTEXT "&Droite :", stc16, 159, 82, 30, 8 EDITTEXT edt6, 190, 80, 36, 12, WS_TABSTOP | WS_GROUP | WS_BORDER - LTEXT "T&op:", stc17, 88, 102, 30, 8 + LTEXT "&Haut :", stc17, 88, 102, 30, 8 EDITTEXT edt5, 119, 100, 36, 12, WS_TABSTOP | WS_GROUP | WS_BORDER - LTEXT "&Bottom:", stc18, 159, 102, 30, 8 + LTEXT "&Bas :", stc18, 159, 102, 30, 8 EDITTEXT edt7, 190, 100, 36, 12, WS_TABSTOP | WS_GROUP | WS_BORDER - LTEXT "&Header:", 0x140, 8, 132, 40, 15 + LTEXT "&En-tête :", 0x140, 8, 132, 40, 15 EDITTEXT 0x141, 58, 130, 173, 12, WS_BORDER | WS_TABSTOP | ES_AUTOHSCROLL - LTEXT "&Footer:", 0x142, 8, 149, 40, 15 + LTEXT "&Pied de page :", 0x142, 8, 149, 40, 15 EDITTEXT 0x143, 58, 147, 173, 12, WS_BORDER | WS_TABSTOP | ES_AUTOHSCROLL - PUSHBUTTON "Help", IDHELP, 8, 170, 50, 14 + PUSHBUTTON "Aide", IDHELP, 8, 170, 50, 14 DEFPUSHBUTTON "OK", IDOK, 198, 170, 50, 14, BS_PUSHBUTTON - PUSHBUTTON "Cancel", IDCANCEL, 254, 170, 50, 14 - PUSHBUTTON "P&rinter...", psh3, 310, 170, 50, 14 + PUSHBUTTON "Annuler", IDCANCEL, 254, 170, 50, 14 + PUSHBUTTON "&Imprimante...", psh3, 310, 170, 50, 14 END /* Dialog 'Encoding' */ @@ -135,8 +135,8 @@ CAPTION "Now printing" STYLE DS_SHELLFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU FONT 8, "MS Shell Dlg" BEGIN - CTEXT "Print job is starting...", IDC_PRINTING_STATUS, 5, 10, 150, 15 - CTEXT "(Filename)", IDC_PRINTING_FILENAME, 5, 35, 150, 15 + CTEXT "Le travail d'impression démarre...", IDC_PRINTING_STATUS, 5, 10, 150, 15 + CTEXT "(Nom de fichier)", IDC_PRINTING_FILENAME, 5, 35, 150, 15 CTEXT "Page %u", IDC_PRINTING_PAGE, 5, 55, 150, 15 PUSHBUTTON "Annuler", IDCANCEL, 50, 75, 60, 20 END @@ -176,12 +176,12 @@ de la mémoire." STRING_LINE_COLUMN "Ligne %d, colonne %d" STRING_PRINTERROR "Impossible d'imprimer le fichier '%s'.\n\nVérifiez que l'imprimante est allumée et correctement configurée." STRING_DEFAULTFONT "Lucida Console" - STRING_LINE_NUMBER_OUT_OF_RANGE "The specified line number is out of range." - STRING_NOWPRINTING "Now printing page..." - STRING_PRINTCANCELING "The print job is being canceled..." - STRING_PRINTCOMPLETE "Printing is successfully done." - STRING_PRINTCANCELED "Printing has been canceled." - STRING_PRINTFAILED "Printing failed." + STRING_LINE_NUMBER_OUT_OF_RANGE "Le numéro de ligne spécifié est hors limite." + STRING_NOWPRINTING "Impression de la page en cours..." + STRING_PRINTCANCELING "Le travail d'impression est en train d'être annulé..." + STRING_PRINTCOMPLETE "L'impression a été effectuée avec succès." + STRING_PRINTCANCELED "L'impression a été annulée." + STRING_PRINTFAILED "L'impression a échoué." STRING_TEXT_DOCUMENT "Document Texte" STRING_NOTEPAD_AUTHORS "Copyright 1997,98 Marcel Baur, 2000 Mike McCormack, 2002 Sylvain Petreolle, 2002 Andriy Palamarchuk\r\n" diff --git a/base/applications/notepad/lang/tr-TR.rc b/base/applications/notepad/lang/tr-TR.rc index f8016b4235d32..b1aaca4b1d18e 100644 --- a/base/applications/notepad/lang/tr-TR.rc +++ b/base/applications/notepad/lang/tr-TR.rc @@ -1,5 +1,12 @@ -// COPYRIGHT: 2012 Arda Tanrıkulu -// 2013-2019 Erdem Ersoy +/* + * PROJECT: ReactOS Notepad + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Turkish resource file + * TRANSLATORS: Copyright 2012 Arda Tanrıkulu + * Copyright 2013-2019 Erdem Ersoy + * Copyright 2021 Süleyman Poyraz + * Copyright 2024 Mahir Gül + */ LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT @@ -173,12 +180,12 @@ BEGIN STRING_LINE_COLUMN "%d. Satır, %d. Sütun" STRING_PRINTERROR """%s"" dosyası yazdırılamıyor.\n\nYazıcının açık olduğundan ve doğru yapılandırıldığından emin olunuz." STRING_DEFAULTFONT "Lucida Console" - STRING_LINE_NUMBER_OUT_OF_RANGE "The specified line number is out of range." - STRING_NOWPRINTING "Now printing page..." - STRING_PRINTCANCELING "The print job is being canceled..." - STRING_PRINTCOMPLETE "Printing is successfully done." - STRING_PRINTCANCELED "Printing has been canceled." - STRING_PRINTFAILED "Printing failed." + STRING_LINE_NUMBER_OUT_OF_RANGE "Belirtilen satır numarası aralık dışındadır." + STRING_NOWPRINTING "Yazdırılıyor..." + STRING_PRINTCANCELING "Yazdırma işi iptal ediliyor..." + STRING_PRINTCOMPLETE "Yazdırma işlemi başarıyla tamamlandı." + STRING_PRINTCANCELED "Yazdırma işlemi iptal edildi." + STRING_PRINTFAILED "Yazdırma başarısız oldu." STRING_TEXT_DOCUMENT "Metin Belgesi" STRING_NOTEPAD_AUTHORS "Telif Hakları: 1997,98 Marcel Baur, 2000 Mike McCormack, 2002 Sylvain Petreolle, 2002 Andriy Palamarchuk\r\n" diff --git a/base/applications/notepad/printing.c b/base/applications/notepad/printing.c index 65f4e7322b3f4..d5f97f621e27a 100644 --- a/base/applications/notepad/printing.c +++ b/base/applications/notepad/printing.c @@ -118,7 +118,7 @@ typedef struct /* * See also: - * https://support.microsoft.com/en-us/windows/changing-header-and-footer-commands-in-notepad-c1b0e27b-497d-c478-c4c1-0da491cac148 + * https://support.microsoft.com/en-us/windows/help-in-notepad-4d68c388-2ff2-0e7f-b706-35fb2ab88a8c */ static VOID DrawHeaderOrFooter(HDC hDC, LPRECT pRect, LPCTSTR pszFormat, INT nPageNo, const SYSTEMTIME *pstNow) diff --git a/base/applications/osk/lang/ar-DZ.rc b/base/applications/osk/lang/ar-DZ.rc index 458a7dd2645b8..cbffe39628503 100644 --- a/base/applications/osk/lang/ar-DZ.rc +++ b/base/applications/osk/lang/ar-DZ.rc @@ -8,7 +8,7 @@ LANGUAGE LANG_ARABIC, SUBLANG_DEFAULT -IDR_OSK_MENU MENU DISCARDABLE +IDR_OSK_MENU MENU BEGIN POPUP "File" BEGIN diff --git a/base/applications/osk/lang/cs-CZ.rc b/base/applications/osk/lang/cs-CZ.rc index b6b45b3eb443c..e45f2601ca09a 100644 --- a/base/applications/osk/lang/cs-CZ.rc +++ b/base/applications/osk/lang/cs-CZ.rc @@ -8,7 +8,7 @@ LANGUAGE LANG_CZECH, SUBLANG_DEFAULT -IDR_OSK_MENU MENU DISCARDABLE +IDR_OSK_MENU MENU BEGIN POPUP "File" BEGIN diff --git a/base/applications/osk/lang/de-DE.rc b/base/applications/osk/lang/de-DE.rc index 357de8326bc15..12b5351c0c6f1 100644 --- a/base/applications/osk/lang/de-DE.rc +++ b/base/applications/osk/lang/de-DE.rc @@ -8,7 +8,7 @@ LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL -IDR_OSK_MENU MENU DISCARDABLE +IDR_OSK_MENU MENU BEGIN POPUP "Datei" BEGIN diff --git a/base/applications/osk/lang/en-GB.rc b/base/applications/osk/lang/en-GB.rc index 7f9fd716a9ba7..ddbc7208904bc 100644 --- a/base/applications/osk/lang/en-GB.rc +++ b/base/applications/osk/lang/en-GB.rc @@ -8,7 +8,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK -IDR_OSK_MENU MENU DISCARDABLE +IDR_OSK_MENU MENU BEGIN POPUP "File" BEGIN diff --git a/base/applications/osk/lang/en-US.rc b/base/applications/osk/lang/en-US.rc index 2a6f9c54331e8..2a03dcf8a68f8 100644 --- a/base/applications/osk/lang/en-US.rc +++ b/base/applications/osk/lang/en-US.rc @@ -8,7 +8,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -IDR_OSK_MENU MENU DISCARDABLE +IDR_OSK_MENU MENU BEGIN POPUP "File" BEGIN diff --git a/base/applications/osk/lang/es-ES.rc b/base/applications/osk/lang/es-ES.rc index 0b44094337dd6..0589661bb6f80 100644 --- a/base/applications/osk/lang/es-ES.rc +++ b/base/applications/osk/lang/es-ES.rc @@ -10,7 +10,7 @@ LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL -IDR_OSK_MENU MENU DISCARDABLE +IDR_OSK_MENU MENU BEGIN POPUP "Archivo" BEGIN diff --git a/base/applications/osk/lang/et-EE.rc b/base/applications/osk/lang/et-EE.rc index 1d1e85110a2b2..91865d180fc5e 100644 --- a/base/applications/osk/lang/et-EE.rc +++ b/base/applications/osk/lang/et-EE.rc @@ -8,7 +8,7 @@ LANGUAGE LANG_ESTONIAN, SUBLANG_DEFAULT -IDR_OSK_MENU MENU DISCARDABLE +IDR_OSK_MENU MENU BEGIN POPUP "File" BEGIN diff --git a/base/applications/osk/lang/fr-CA.rc b/base/applications/osk/lang/fr-CA.rc index 74801b5c33ef3..a735ddc1be2fc 100644 --- a/base/applications/osk/lang/fr-CA.rc +++ b/base/applications/osk/lang/fr-CA.rc @@ -8,7 +8,7 @@ LANGUAGE LANG_FRENCH, SUBLANG_FRENCH_CANADIAN -IDR_OSK_MENU MENU DISCARDABLE +IDR_OSK_MENU MENU BEGIN POPUP "File" BEGIN diff --git a/base/applications/osk/lang/fr-FR.rc b/base/applications/osk/lang/fr-FR.rc index fecb5285be332..a6e6434fe4c7d 100644 --- a/base/applications/osk/lang/fr-FR.rc +++ b/base/applications/osk/lang/fr-FR.rc @@ -8,42 +8,42 @@ LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL -IDR_OSK_MENU MENU DISCARDABLE +IDR_OSK_MENU MENU BEGIN - POPUP "File" + POPUP "Fichier" BEGIN - MENUITEM "&Exit", IDM_EXIT + MENUITEM "&Quitter", IDM_EXIT END - POPUP "Keyboard" + POPUP "Clavier" BEGIN - MENUITEM "Enhanced Keyboard", IDM_ENHANCED_KB, CHECKED - MENUITEM "Standard Keyboard", IDM_STANDARD_KB + MENUITEM "Clavier étendu", IDM_ENHANCED_KB, CHECKED + MENUITEM "Clavier standard", IDM_STANDARD_KB MENUITEM SEPARATOR - MENUITEM "Regular Layout", IDM_REG_LAYOUT, CHECKED, GRAYED - MENUITEM "Block Layout", IDM_BLOCK_LAYOUT, GRAYED + MENUITEM "Disposition régulière", IDM_REG_LAYOUT, CHECKED, GRAYED + MENUITEM "Disposition en blocs", IDM_BLOCK_LAYOUT, GRAYED MENUITEM SEPARATOR - MENUITEM "101 keys", IDM_101_KEYS, CHECKED, GRAYED - MENUITEM "102 keys", IDM_102_KEYS, GRAYED - MENUITEM "106 keys", IDM_106_KEYS, GRAYED + MENUITEM "101 touches", IDM_101_KEYS, CHECKED, GRAYED + MENUITEM "102 touches", IDM_102_KEYS, GRAYED + MENUITEM "106 touches", IDM_106_KEYS, GRAYED END POPUP "Settings" BEGIN - MENUITEM "Always on Top", IDM_ON_TOP, CHECKED + MENUITEM "Toujours au premier plan", IDM_ON_TOP, CHECKED MENUITEM SEPARATOR - MENUITEM "&Use Click Sound", IDM_CLICK_SOUND + MENUITEM "&Son sur le clic", IDM_CLICK_SOUND MENUITEM SEPARATOR - MENUITEM "&Typing Mode...", IDM_TYPE_MODE, GRAYED + MENUITEM "&Mode de frappe...", IDM_TYPE_MODE, GRAYED MENUITEM SEPARATOR - MENUITEM "&Font...", IDM_FONT + MENUITEM "&Police...", IDM_FONT END POPUP "Help" BEGIN - MENUITEM "&Help Topics", IDM_HELP_TOPICS, GRAYED + MENUITEM "&Aide", IDM_HELP_TOPICS, GRAYED MENUITEM SEPARATOR - MENUITEM "&About On-Screen Keyboard...", IDM_ABOUT + MENUITEM "À &propos du Clavier visuel...", IDM_ABOUT END END @@ -61,7 +61,7 @@ END STRINGTABLE BEGIN - IDS_OSK "On-Screen Keyboard" + IDS_OSK "Clavier visuel" IDS_AUTHORS "Copyright Denis Robert" IDS_NUMLOCK "Num" IDS_CAPSLOCK "Caps" diff --git a/base/applications/osk/lang/he-IL.rc b/base/applications/osk/lang/he-IL.rc index f831262f50379..171541faf3a56 100644 --- a/base/applications/osk/lang/he-IL.rc +++ b/base/applications/osk/lang/he-IL.rc @@ -8,7 +8,7 @@ LANGUAGE LANG_HEBREW, SUBLANG_DEFAULT -IDR_OSK_MENU MENU DISCARDABLE +IDR_OSK_MENU MENU BEGIN POPUP "File" BEGIN diff --git a/base/applications/osk/lang/id-ID.rc b/base/applications/osk/lang/id-ID.rc index ae174e1705e57..21ac9aebffdf6 100644 --- a/base/applications/osk/lang/id-ID.rc +++ b/base/applications/osk/lang/id-ID.rc @@ -8,7 +8,7 @@ LANGUAGE LANG_INDONESIAN, SUBLANG_DEFAULT -IDR_OSK_MENU MENU DISCARDABLE +IDR_OSK_MENU MENU BEGIN POPUP "Be&rkas" BEGIN diff --git a/base/applications/osk/lang/it-IT.rc b/base/applications/osk/lang/it-IT.rc index 1f449cab0f47a..199d71409cd2c 100644 --- a/base/applications/osk/lang/it-IT.rc +++ b/base/applications/osk/lang/it-IT.rc @@ -8,7 +8,7 @@ LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL -IDR_OSK_MENU MENU DISCARDABLE +IDR_OSK_MENU MENU BEGIN POPUP "File" BEGIN diff --git a/base/applications/osk/lang/pl-PL.rc b/base/applications/osk/lang/pl-PL.rc index fb584a41db15a..0eb01f95bd085 100644 --- a/base/applications/osk/lang/pl-PL.rc +++ b/base/applications/osk/lang/pl-PL.rc @@ -8,7 +8,7 @@ LANGUAGE LANG_POLISH, SUBLANG_NEUTRAL -IDR_OSK_MENU MENU DISCARDABLE +IDR_OSK_MENU MENU BEGIN POPUP "Pl&ik" BEGIN diff --git a/base/applications/osk/lang/pt-BR.rc b/base/applications/osk/lang/pt-BR.rc index f49446e288f86..c1e6b4ea21107 100644 --- a/base/applications/osk/lang/pt-BR.rc +++ b/base/applications/osk/lang/pt-BR.rc @@ -7,7 +7,7 @@ LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN -IDR_OSK_MENU MENU DISCARDABLE +IDR_OSK_MENU MENU BEGIN POPUP "Arquivo" BEGIN diff --git a/base/applications/osk/lang/pt-PT.rc b/base/applications/osk/lang/pt-PT.rc index 71b5c1511dec9..661b0e8d20ba7 100644 --- a/base/applications/osk/lang/pt-PT.rc +++ b/base/applications/osk/lang/pt-PT.rc @@ -7,7 +7,7 @@ LANGUAGE LANG_PORTUGUESE, SUBLANG_NEUTRAL -IDR_OSK_MENU MENU DISCARDABLE +IDR_OSK_MENU MENU BEGIN POPUP "Ficheiro" BEGIN diff --git a/base/applications/osk/lang/ro-RO.rc b/base/applications/osk/lang/ro-RO.rc index afbe9a5fbe915..1ae967695e22f 100644 --- a/base/applications/osk/lang/ro-RO.rc +++ b/base/applications/osk/lang/ro-RO.rc @@ -9,7 +9,7 @@ LANGUAGE LANG_ROMANIAN, SUBLANG_DEFAULT -IDR_OSK_MENU MENU DISCARDABLE +IDR_OSK_MENU MENU BEGIN POPUP "&Fişier" BEGIN diff --git a/base/applications/osk/lang/ru-RU.rc b/base/applications/osk/lang/ru-RU.rc index 7befd7e17de12..cde6662f10b6b 100644 --- a/base/applications/osk/lang/ru-RU.rc +++ b/base/applications/osk/lang/ru-RU.rc @@ -8,7 +8,7 @@ LANGUAGE LANG_RUSSIAN, SUBLANG_NEUTRAL -IDR_OSK_MENU MENU DISCARDABLE +IDR_OSK_MENU MENU BEGIN POPUP "Файл" BEGIN diff --git a/base/applications/osk/lang/tr-TR.rc b/base/applications/osk/lang/tr-TR.rc index ca27a1913b6ea..8769db40a7bf7 100644 --- a/base/applications/osk/lang/tr-TR.rc +++ b/base/applications/osk/lang/tr-TR.rc @@ -8,7 +8,7 @@ LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT -IDR_OSK_MENU MENU DISCARDABLE +IDR_OSK_MENU MENU BEGIN POPUP "Dosya" BEGIN diff --git a/base/applications/osk/lang/zh-CN.rc b/base/applications/osk/lang/zh-CN.rc index 079b76f8f7a8a..58bad345027f9 100644 --- a/base/applications/osk/lang/zh-CN.rc +++ b/base/applications/osk/lang/zh-CN.rc @@ -12,7 +12,7 @@ LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED -IDR_OSK_MENU MENU DISCARDABLE +IDR_OSK_MENU MENU BEGIN POPUP "文件" BEGIN diff --git a/base/applications/osk/lang/zh-HK.rc b/base/applications/osk/lang/zh-HK.rc index 21804221f950d..b02047533e586 100644 --- a/base/applications/osk/lang/zh-HK.rc +++ b/base/applications/osk/lang/zh-HK.rc @@ -9,7 +9,7 @@ LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_HONGKONG -IDR_OSK_MENU MENU DISCARDABLE +IDR_OSK_MENU MENU BEGIN POPUP "檔案" BEGIN diff --git a/base/applications/osk/lang/zh-TW.rc b/base/applications/osk/lang/zh-TW.rc index 4ebb07cba09d1..ba0c24ed68604 100644 --- a/base/applications/osk/lang/zh-TW.rc +++ b/base/applications/osk/lang/zh-TW.rc @@ -8,7 +8,7 @@ LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL -IDR_OSK_MENU MENU DISCARDABLE +IDR_OSK_MENU MENU BEGIN POPUP "檔案" BEGIN diff --git a/base/applications/osk/osk.rc b/base/applications/osk/osk.rc index a599e61618498..307fc801c8181 100644 --- a/base/applications/osk/osk.rc +++ b/base/applications/osk/osk.rc @@ -6,6 +6,7 @@ */ /* INCLUDES ******************************************************************/ + #include "precomp.h" #define REACTOS_STR_FILE_DESCRIPTION "ReactOS On Screen Keyboard" @@ -17,7 +18,6 @@ IDI_OSK ICON "res/osk.ico" IDI_SOUNDCLICK WAVE "res/click.wav" - IDI_BACK ICON "res/back.ico" IDI_TAB ICON "res/tab.ico" IDI_CAPS_LOCK ICON "res/caps_lock.ico" @@ -35,8 +35,9 @@ IDI_BOTTOM ICON "res/bottom.ico" #include -// UTF-8 +/* UTF-8 */ #pragma code_page(65001) + #ifdef LANGUAGE_AR_DZ #include "lang/ar-DZ.rc" #endif @@ -100,4 +101,5 @@ IDI_BOTTOM ICON "res/bottom.ico" #ifdef LANGUAGE_ZH_TW #include "lang/zh-TW.rc" #endif + /* EOF */ diff --git a/base/applications/rapps/README.ENG b/base/applications/rapps/README.ENG index 18abc406fb2b6..e2f15631de89b 100644 --- a/base/applications/rapps/README.ENG +++ b/base/applications/rapps/README.ENG @@ -18,7 +18,7 @@ Also, each [Section] is language-independent and individual, you can override th program or any other field by adding a language-specific [Section.], followed by the language code. NOTE: You can find a complete listing of LCIDs and language names here, includes neutral codes: - + Now RAPPS also accepts neutral language codes, meaning that you can do things like this: diff --git a/base/applications/rapps/appdb.cpp b/base/applications/rapps/appdb.cpp index 97ba9626a648e..8ee19edb8e225 100644 --- a/base/applications/rapps/appdb.cpp +++ b/base/applications/rapps/appdb.cpp @@ -158,7 +158,7 @@ CAppDB::EnumInstalledRootKey(UINT Index, REGSAM &RegSam) { // Loop for through all combinations. // Note that HKEY_CURRENT_USER\Software does not have a redirect - // https://docs.microsoft.com/en-us/windows/win32/winprog64/shared-registry-keys#redirected-shared-and-reflected-keys-under-wow64 + // https://learn.microsoft.com/en-us/windows/win32/winprog64/shared-registry-keys#redirected-shared-and-reflected-keys-under-wow64 if (Index < (IsSystem64Bit() ? 3 : 2)) return GetRootKeyInfo(Index, RegSam); else diff --git a/base/applications/rapps/appinfo.cpp b/base/applications/rapps/appinfo.cpp index eefbb91d2e54b..5442380fbadc7 100644 --- a/base/applications/rapps/appinfo.cpp +++ b/base/applications/rapps/appinfo.cpp @@ -10,6 +10,14 @@ #include "rapps.h" #include "appview.h" +static inline AppsCategories +ClampAvailableCategory(AppsCategories Category) +{ + if (Category <= ENUM_LASTCATEGORY) + return Category; + return ENUM_CAT_OTHER; // Treat future categories we don't know as Other +} + CAppInfo::CAppInfo(const CStringW &Identifier, AppsCategories Category) : szIdentifier(Identifier), iCategory(Category) { @@ -24,7 +32,7 @@ CAvailableApplicationInfo::CAvailableApplicationInfo( const CStringW &PkgName, AppsCategories Category, const CPathW &BasePath) - : CAppInfo(PkgName, Category), m_Parser(Parser), m_ScrnshotRetrieved(false), m_LanguagesLoaded(false) + : CAppInfo(PkgName, ClampAvailableCategory(Category)), m_Parser(Parser), m_ScrnshotRetrieved(false), m_LanguagesLoaded(false) { m_Parser->GetString(L"Name", szDisplayName); m_Parser->GetString(L"Version", szDisplayVersion); @@ -163,16 +171,16 @@ CAvailableApplicationInfo::LicenseString() LicenseType licenseType; if (IsKnownLicenseType(IntBuffer)) - { licenseType = static_cast(IntBuffer); - } else - { licenseType = LICENSE_NONE; + + if (licenseType == LICENSE_NONE || licenseType == LICENSE_FREEWARE) + { if (szLicenseString.CompareNoCase(L"Freeware") == 0) { licenseType = LICENSE_FREEWARE; - szLicenseString = L""; + szLicenseString = L""; // Don't display as "Freeware (Freeware)" } } @@ -588,7 +596,7 @@ CInstalledApplicationInfo::GetInstallerType() const BOOL CInstalledApplicationInfo::UninstallApplication(UninstallCommandFlags Flags) { - if (GetInstallerType() == INSTALLER_GENERATE) + if (GetInstallerType() == INSTALLER_GENERATE && (Flags & UCF_SAMEPROCESS)) { return UninstallGenerated(*this, Flags); } diff --git a/base/applications/rapps/appview.cpp b/base/applications/rapps/appview.cpp index c0f18107c1ed9..94bee2f21b601 100644 --- a/base/applications/rapps/appview.cpp +++ b/base/applications/rapps/appview.cpp @@ -15,6 +15,7 @@ using namespace Gdiplus; HICON g_hDefaultPackageIcon = NULL; static int g_DefaultPackageIconILIdx = I_IMAGENONE; +UINT g_IconSize = 0; // **** Menu helpers **** @@ -955,19 +956,22 @@ CAppInfoDisplay::Create(HWND hwndParent) } VOID -CAppInfoDisplay::ShowAppInfo(CAppInfo *Info) +CAppInfoDisplay::ShowAppInfo(CAppInfo &Info, bool OnlyUpdateText) { - CStringW ScrnshotLocation; - if (Info->RetrieveScreenshot(ScrnshotLocation)) + if (!OnlyUpdateText) { - ScrnshotPrev->DisplayImage(ScrnshotLocation); - } - else - { - ScrnshotPrev->DisplayEmpty(); + CStringW ScrnshotLocation; + if (Info.RetrieveScreenshot(ScrnshotLocation)) + { + ScrnshotPrev->DisplayImage(ScrnshotLocation); + } + else + { + ScrnshotPrev->DisplayEmpty(); + } } ResizeChildren(); - Info->ShowAppInfo(RichEdit); + Info.ShowAppInfo(RichEdit); } void @@ -1060,9 +1064,11 @@ AsyncLoadIconProc(LPVOID Param) if (task->TaskId == g_AsyncIconTaskId) { HICON hIcon; + HICON *phBigIcon = SettingsInfo.bSmallIcons ? NULL : &hIcon; + HICON *phSmallIcon = phBigIcon ? NULL : &hIcon; if (!task->Parse) - hIcon = (HICON)LoadImageW(NULL, task->Location, IMAGE_ICON, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE); - else if (!ExtractIconExW(task->Location, PathParseIconLocationW(task->Location), &hIcon, NULL, 1)) + hIcon = (HICON)LoadImageW(NULL, task->Location, IMAGE_ICON, g_IconSize, g_IconSize, LR_LOADFROMFILE); + else if (!ExtractIconExW(task->Location, PathParseIconLocationW(task->Location), phBigIcon, phSmallIcon, 1)) hIcon = NULL; if (hIcon) @@ -1389,13 +1395,14 @@ CAppsListView::SetDisplayAppType(APPLICATION_VIEW_TYPE AppType) if (!g_hDefaultPackageIcon) { ImageList_Destroy(m_hImageListView); - UINT IconSize = GetSystemMetrics(SM_CXICON); + g_IconSize = GetSystemMetrics(SettingsInfo.bSmallIcons ? SM_CXSMICON : SM_CXICON); + g_IconSize = max(g_IconSize, 8); UINT ilc = GetSystemColorDepth() | ILC_MASK; - m_hImageListView = ImageList_Create(IconSize, IconSize, ilc, 0, 1); + m_hImageListView = ImageList_Create(g_IconSize, g_IconSize, ilc, 0, 1); SetImageList(m_hImageListView, LVSIL_SMALL); SetImageList(m_hImageListView, LVSIL_NORMAL); g_hDefaultPackageIcon = (HICON)LoadImageW(hInst, MAKEINTRESOURCEW(IDI_MAIN), - IMAGE_ICON, IconSize, IconSize, LR_SHARED); + IMAGE_ICON, g_IconSize, g_IconSize, LR_SHARED); } ImageList_RemoveAll(m_hImageListView); @@ -1637,6 +1644,11 @@ CApplicationView::ProcessWindowMessage( ItemCheckStateChanged(FALSE, (LPVOID)pnic->lParam); } } + + /* Ensure that if there are any items still focused/selected, + * the ID_INSTALL menu item and toolbar button stay enabled */ + if ((pnic->uChanged & LVIF_STATE) && !m_MainWindow->bUpdating) + _UpdateInstallBtn(); } break; @@ -1805,6 +1817,22 @@ CApplicationView::SetRedraw(BOOL bRedraw) m_ListView->SetRedraw(bRedraw); } +void +CApplicationView::RefreshAvailableItem(PCWSTR PackageName) +{ + if (ApplicationViewType != AppViewTypeAvailableApps || !PackageName) + return; + CAppInfo *pApp; + for (UINT i = 0; (pApp = (CAppInfo*)m_ListView->GetItemData(i)) != NULL; ++i) + { + if (pApp->szIdentifier.CompareNoCase(PackageName) == 0) + { + RefreshDetailsPane(*pApp, true); + break; + } + } +} + void CApplicationView::SetFocusOnSearchBar() { @@ -2016,25 +2044,19 @@ BOOL CApplicationView::SetDisplayAppType(APPLICATION_VIEW_TYPE AppType) { if (!m_ListView->SetDisplayAppType(AppType)) - { return FALSE; - } + ApplicationViewType = AppType; m_AppsInfo->SetWelcomeText(m_MainWindow->m_bAppwizMode); - HMENU hMenu = ::GetMenu(m_hWnd); + HMENU hMenu = GetMenu(); switch (AppType) { case AppViewTypeInstalledApps: { EnableMenuItem(hMenu, ID_INSTALL, MF_GRAYED); - EnableMenuItem(hMenu, ID_UNINSTALL, MF_ENABLED); - EnableMenuItem(hMenu, ID_MODIFY, MF_ENABLED); - EnableMenuItem(hMenu, ID_REGREMOVE, MF_ENABLED); - m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_INSTALL, FALSE); - m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_UNINSTALL, TRUE); - m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_MODIFY, TRUE); + m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_CHECK_ALL, FALSE); break; } @@ -2044,18 +2066,22 @@ CApplicationView::SetDisplayAppType(APPLICATION_VIEW_TYPE AppType) // We shouldn't get there in APPWIZ-mode. ATLASSERT(!m_MainWindow->m_bAppwizMode); - EnableMenuItem(hMenu, ID_INSTALL, MF_ENABLED); - EnableMenuItem(hMenu, ID_UNINSTALL, MF_GRAYED); - EnableMenuItem(hMenu, ID_MODIFY, MF_GRAYED); - EnableMenuItem(hMenu, ID_REGREMOVE, MF_GRAYED); + /* Even if no ListView item is focused at this point, enable + * or disable ID_INSTALL if there are selected applications. */ + _UpdateInstallBtn(); - m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_INSTALL, TRUE); - m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_UNINSTALL, FALSE); - m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_MODIFY, FALSE); m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_CHECK_ALL, TRUE); break; } } + + /* Always disable these items by default */ + EnableMenuItem(hMenu, ID_UNINSTALL, MF_GRAYED); + EnableMenuItem(hMenu, ID_MODIFY, MF_GRAYED); + EnableMenuItem(hMenu, ID_REGREMOVE, MF_GRAYED); + m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_UNINSTALL, FALSE); + m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_MODIFY, FALSE); + return TRUE; } @@ -2134,30 +2160,76 @@ CApplicationView::RestoreListSelection(const RESTORELISTSELECTION &Restore) } } -// this function is called when a item of listview get focus. -// CallbackParam is the param passed to listview when adding the item (the one getting focus now). +VOID +CApplicationView::RefreshDetailsPane(CAppInfo &Info, bool OnlyUpdateText) +{ + m_AppsInfo->ShowAppInfo(Info, OnlyUpdateText); +} + +void +CApplicationView::_UpdateInstallBtn() +{ + if (ApplicationViewType == AppViewTypeInstalledApps) + { + EnableMenuItem(GetMenu(), ID_INSTALL, MF_GRAYED); + m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_INSTALL, FALSE); + } + else if (ApplicationViewType == AppViewTypeAvailableApps) + { + // We shouldn't get there in APPWIZ-mode. + ATLASSERT(!m_MainWindow->m_bAppwizMode); + + /* Even if no ListView item is focused at this point, enable + * or disable ID_INSTALL if there are selected applications. */ + BOOL CanInstall = !m_MainWindow->m_Selected.IsEmpty(); + CanInstall = CanInstall || (m_ListView->GetSelectedCount() > 0); + EnableMenuItem(GetMenu(), ID_INSTALL, CanInstall ? MF_ENABLED : MF_GRAYED); + m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_INSTALL, CanInstall); + } +} + +// This function is called when a ListView item gets the focus. +// CallbackParam is the param passed to the ListView when adding the item (the one getting focus now). VOID CApplicationView::ItemGetFocus(LPVOID CallbackParam) { - if (CallbackParam) + if (!CallbackParam) + return; + + CAppInfo *Info = static_cast(CallbackParam); + RefreshDetailsPane(*Info); + + HMENU hMenu = GetMenu(); + if (ApplicationViewType == AppViewTypeInstalledApps) { - CAppInfo *Info = static_cast(CallbackParam); - m_AppsInfo->ShowAppInfo(Info); + /* ID_INSTALL is left disabled */ - if (ApplicationViewType == AppViewTypeInstalledApps) - { - HMENU hMenu = ::GetMenu(m_hWnd); + EnableMenuItem(hMenu, ID_UNINSTALL, MF_ENABLED); + m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_UNINSTALL, TRUE); - BOOL CanModify = Info->CanModify(); + BOOL CanModify = Info->CanModify(); + EnableMenuItem(hMenu, ID_MODIFY, CanModify ? MF_ENABLED : MF_GRAYED); + m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_MODIFY, CanModify); - EnableMenuItem(hMenu, ID_MODIFY, CanModify ? MF_ENABLED : MF_GRAYED); - m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_MODIFY, CanModify); - } + EnableMenuItem(hMenu, ID_REGREMOVE, MF_ENABLED); + } + else if (ApplicationViewType == AppViewTypeAvailableApps) + { + // We shouldn't get there in APPWIZ-mode. + ATLASSERT(!m_MainWindow->m_bAppwizMode); + + EnableMenuItem(hMenu, ID_INSTALL, MF_ENABLED); + m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_INSTALL, TRUE); + + /* ID_UNINSTALL, ID_MODIFY and ID_REGREMOVE are left disabled */ + // TODO: When we are able to detect whether this selected available + // application is already installed (could be an older version), + // do also what's done in the AppViewTypeInstalledApps case above. } } -// this function is called when a item of listview is checked/unchecked -// CallbackParam is the param passed to listview when adding the item (the one getting changed now). +// This function is called when a ListView item (an application) is checked/unchecked. +// CallbackParam is the param passed to the ListView when adding the item (the one getting changed now). VOID CApplicationView::ItemCheckStateChanged(BOOL bChecked, LPVOID CallbackParam) { diff --git a/base/applications/rapps/geninst.cpp b/base/applications/rapps/geninst.cpp index 9fff1d2b264b1..9d00156f55c66 100644 --- a/base/applications/rapps/geninst.cpp +++ b/base/applications/rapps/geninst.cpp @@ -28,6 +28,7 @@ extern "C" { #define REGPATH_UNINSTALL L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall" +#define DB_NONE L"!" // Skip/Ignore #define DB_GENINST_FILES L"Files" #define DB_GENINST_DIR L"Dir" #define DB_GENINST_ICON L"Icon" @@ -46,6 +47,17 @@ enum { UNOP_EMPTYREGKEY = 'k', }; +BOOL IsZipFile(PCWSTR Path) +{ + zlib_filefunc64_def zff; + fill_win32_filefunc64W(&zff); + unzFile hzf = unzOpen2_64(Path, &zff); + if (!hzf) + return FALSE; + unzClose(hzf); + return TRUE; +} + static int ExtractFilesFromZip(LPCWSTR Archive, const CStringW &OutputDir, EXTRACTCALLBACK Callback, void *Cookie) @@ -172,17 +184,10 @@ struct InstallInfo : CommonInfo } }; -static UINT +static inline UINT ErrorBox(UINT Error = GetLastError()) { - if (!Error) - Error = ERROR_INTERNAL_ERROR; - WCHAR buf[400]; - UINT fmf = FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM; - FormatMessageW(fmf, NULL, Error, 0, buf, _countof(buf), NULL); - MessageBoxW(g_pInfo->GetGuiOwner(), buf, 0, MB_OK | MB_ICONSTOP); - g_pInfo->Error = Error; - return Error; + return g_pInfo->Error = ErrorBox(g_pInfo->GetGuiOwner(), Error); } static LPCWSTR @@ -230,6 +235,8 @@ GetCustomIconPath(InstallInfo &Info, CStringW &Path) { if (*GetGenerateString(DB_GENINST_ICON, Path)) { + if (Path.Compare(DB_NONE) == 0) + return HRESULT_FROM_WIN32(ERROR_CAN_NOT_COMPLETE); Path = BuildPath(Info.InstallDir, Path); int idx = PathParseIconLocation(Path.GetBuffer()); Path.ReleaseBuffer(); @@ -268,15 +275,15 @@ GetLocalizedSMFolderName(LPCWSTR WinVal, LPCWSTR RosInf, LPCWSTR RosVal, CString return ReadIniValue(path, L"Strings", RosVal, Output) > 0; } -static BOOL -CreateShortcut(const CStringW &Target) +static CStringW +CreateMainShortcut(const CStringW &Target) { InstallInfo &Info = *static_cast(g_pInfo); UINT csidl = Info.PerUser ? CSIDL_PROGRAMS : CSIDL_COMMON_PROGRAMS; CStringW rel = Info.ShortcutFile, path, dir, tmp; if (FAILED(GetSpecialPath(csidl, path, Info.GetGuiOwner()))) - return TRUE; // Pretend everything is OK + return L""; // Pretend everything is OK int cat; if (Info.Parser.GetInt(DB_CATEGORY, cat) && cat == ENUM_CAT_GAMES) @@ -297,7 +304,7 @@ CreateShortcut(const CStringW &Target) if ((Info.Error = ErrorFromHResult(hr)) != 0) { ErrorBox(Info.Error); - return FALSE; + return L""; } CComPtr link; @@ -306,6 +313,9 @@ CreateShortcut(const CStringW &Target) { if (SUCCEEDED(hr = link->SetPath(Target))) { + SplitFileAndDirectory(Target, &tmp); + link->SetWorkingDirectory(tmp); + if (SUCCEEDED(GetCustomIconPath(Info, tmp))) { LPWSTR p = tmp.GetBuffer(); @@ -331,7 +341,7 @@ CreateShortcut(const CStringW &Target) { ErrorBox(ErrorFromHResult(hr)); } - return !Info.Error; + return Info.Error ? L"" : path; } static BOOL @@ -432,7 +442,7 @@ ExtractAndInstallThread(LPVOID Parameter) { const BOOL PerUserModeDefault = TRUE; InstallInfo &Info = *static_cast(g_pInfo); - LPCWSTR AppName = Info.AppName, Archive = Info.ArchivePath, None = L"!"; + LPCWSTR AppName = Info.AppName, Archive = Info.ArchivePath, None = DB_NONE; CStringW installdir, tempdir, files, shortcut, tmp; HRESULT hr; CRegKey arpkey; @@ -492,7 +502,7 @@ ExtractAndInstallThread(LPVOID Parameter) if (!Info.Error) { - BOOL isCab = SplitFileAndDirectory(Archive).Right(4).CompareNoCase(L".cab") == 0; + BOOL isCab = LOBYTE(ClassifyFile(tempdir)) == 'C'; Info.Error = isCab ? ExtractCab(Archive, tempdir, ExtractCallback, &Info) : ExtractZip(Archive, tempdir, ExtractCallback, &Info); } @@ -534,9 +544,9 @@ ExtractAndInstallThread(LPVOID Parameter) (tmp = tmp.Mid(0, cch)).AppendFormat(unparamsfmt, L" /S", modechar, bitness, arpkeyname); WriteArpEntry(L"QuietUninstallString", tmp); - if (GetCustomIconPath(Info, tmp) != S_OK) - tmp = Info.MainApp; - WriteArpEntry(L"DisplayIcon", tmp); + hr = GetCustomIconPath(Info, tmp); + if (hr != HRESULT_FROM_WIN32(ERROR_CAN_NOT_COMPLETE)) + WriteArpEntry(L"DisplayIcon", hr == S_OK ? tmp : Info.MainApp); if (*GetCommonString(DB_VERSION, tmp)) WriteArpEntry(L"DisplayVersion", tmp); @@ -557,7 +567,20 @@ ExtractAndInstallThread(LPVOID Parameter) if (!Info.Error && Info.ShortcutFile) { - CreateShortcut(Info.MainApp); + tmp = CreateMainShortcut(Info.MainApp); + if (!tmp.IsEmpty() && !Info.Silent) + { + CStringW message, format; + format.LoadString(IDS_INSTGEN_CONFIRMINSTRUNAPP); + message.Format(format, const_cast(AppName)); + if (MessageBoxW(Info.GetGuiOwner(), message, AppName, MB_YESNO | MB_ICONQUESTION) == IDYES) + { + SHELLEXECUTEINFOW sei = { sizeof(sei), SEE_MASK_NOASYNC, Info.GetGuiOwner() }; + sei.lpFile = tmp; + sei.nShow = SW_SHOW; + ShellExecuteExW(&sei); + } + } } } @@ -603,7 +626,7 @@ UIDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) ErrorBox(); SendMessageW(hDlg, IM_END, 0, 0); } - break; + return TRUE; } case WM_CLOSE: return TRUE; diff --git a/base/applications/rapps/gui.cpp b/base/applications/rapps/gui.cpp index 70cedb28a219d..8470ba092d124 100644 --- a/base/applications/rapps/gui.cpp +++ b/base/applications/rapps/gui.cpp @@ -81,6 +81,8 @@ CSideTreeView::~CSideTreeView() // **** CSideTreeView **** // **** CMainWindow **** +HWND CMainWindow::m_hLastFocus = NULL; +bool CMainWindow::m_PendingInstalledViewRefresh = false; CMainWindow::CMainWindow(CAppDB *db, BOOL bAppwiz) : m_ClientPanel(NULL), m_Db(db), m_bAppwizMode(bAppwiz), SelectedEnumType(ENUM_ALL_INSTALLED) { @@ -304,6 +306,7 @@ CMainWindow::CheckAvailable() { if (m_Db->GetAvailableCount() == 0) { + CUpdateDatabaseMutex lock; m_Db->RemoveCached(); m_Db->UpdateAvailable(); } @@ -342,10 +345,32 @@ CMainWindow::ProcessWindowMessage(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lPa SendMessage(WM_CLOSE, 0, 0); break; + case WM_NOTIFY_INSTALLERFINISHED: + m_PendingInstalledViewRefresh = true; // Something just installed, our uninstall list is probably outdated + m_ApplicationView->RefreshAvailableItem((PCWSTR)lParam); + break; + case DM_REPOSITION: EmulateDialogReposition(hwnd); // We are not a real dialog, we need help from a real one break; + case WM_ACTIVATE: + if (LOWORD(wParam) == WA_INACTIVE) + m_hLastFocus = ::GetFocus(); + break; + + case WM_SETFOCUS: + if (m_hLastFocus) + ::SetFocus(m_hLastFocus); + break; + + case WM_NEXTDLGCTL: + if (!LOWORD(lParam)) + HandleTabOrder(wParam ? -1 : 1); + else if (wParam) + ::SetFocus((HWND)wParam); + break; + case WM_COMMAND: OnCommand(wParam, lParam); break; @@ -591,9 +616,12 @@ CMainWindow::OnCommand(WPARAM wParam, LPARAM lParam) break; case ID_RESETDB: + { + CUpdateDatabaseMutex lock; m_Db->RemoveCached(); UpdateApplicationsList(SelectedEnumType, bReload); break; + } case ID_HELP: MessageBoxW(L"Help not implemented yet", NULL, MB_OK); @@ -674,6 +702,12 @@ CMainWindow::UpdateApplicationsList(AppsCategories EnumType, BOOL bReload, BOOL if (bCheckAvailable) CheckAvailable(); + if (m_PendingInstalledViewRefresh && IsInstalledEnum(EnumType) && !IsInstalledEnum(SelectedEnumType)) + { + m_PendingInstalledViewRefresh = FALSE; + bReload = TRUE; // Reload because we are switching from Available to Installed after something installed + } + BOOL TryRestoreSelection = SelectedEnumType == EnumType; if (SelectedEnumType != EnumType) SelectedEnumType = EnumType; @@ -808,16 +842,7 @@ CMainWindow::ItemCheckStateChanged(BOOL bChecked, LPVOID CallbackParam) BOOL CMainWindow::InstallApplication(CAppInfo *Info) { - if (Info) - { - if (DownloadApplication(Info)) - { - UpdateApplicationsList(SelectedEnumType); - return TRUE; - } - } - - return FALSE; + return Info && DownloadApplication(Info); } BOOL diff --git a/base/applications/rapps/include/appinfo.h b/base/applications/rapps/include/appinfo.h index 175048b60086e..961ad0711bd76 100644 --- a/base/applications/rapps/include/appinfo.h +++ b/base/applications/rapps/include/appinfo.h @@ -41,6 +41,7 @@ enum AppsCategories ENUM_CAT_THEMES, ENUM_CAT_OTHER, ENUM_CAT_SELECTED, + ENUM_LASTCATEGORY = ENUM_CAT_SELECTED - 1, ENUM_ALL_INSTALLED = 30, ENUM_INSTALLED_APPLICATIONS, ENUM_UPDATES, @@ -54,6 +55,12 @@ enum AppsCategories inline BOOL IsAvailableEnum(INT x) { + C_ASSERT(ENUM_CAT_AUDIO == 1 && ENUM_CAT_THEMES == 15 && ENUM_CAT_OTHER == 16); + C_ASSERT(ENUM_LASTCATEGORY >= ENUM_CAT_OTHER); + C_ASSERT(ENUM_LASTCATEGORY < ENUM_CAT_SELECTED); + C_ASSERT(ENUM_LASTCATEGORY < ENUM_INSTALLED_MIN); + C_ASSERT(ENUM_CAT_SELECTED < ENUM_INSTALLED_MIN); + return (x >= ENUM_AVAILABLE_MIN && x <= ENUM_AVAILABLE_MAX); } @@ -68,7 +75,9 @@ enum UninstallCommandFlags UCF_NONE = 0x00, UCF_MODIFY = 0x01, UCF_SILENT = 0x02, + UCF_SAMEPROCESS = 0x04, }; +DEFINE_ENUM_FLAG_OPERATORS(UninstallCommandFlags); enum InstallerType { @@ -82,6 +91,7 @@ enum InstallerType #define DB_REGNAME L"RegName" #define DB_INSTALLER L"Installer" #define DB_SCOPE L"Scope" // User or Machine +#define DB_SAVEAS L"SaveAs" #define DB_GENINSTSECTION L"Generate" #define GENERATE_ARPSUBKEY L"RApps" // Our uninstall data is stored here diff --git a/base/applications/rapps/include/appview.h b/base/applications/rapps/include/appview.h index d457d45c79941..26143bcba830c 100644 --- a/base/applications/rapps/include/appview.h +++ b/base/applications/rapps/include/appview.h @@ -175,7 +175,7 @@ class CAppInfoDisplay : public CUiWindow> Create(HWND hwndParent); VOID - ShowAppInfo(CAppInfo *Info); + ShowAppInfo(CAppInfo &Info, bool OnlyUpdateText = false); void SetWelcomeText(bool bAppwiz); VOID @@ -376,6 +376,9 @@ class CApplicationView : public CUiWindow> VOID OnCommand(WPARAM wParam, LPARAM lParam); + void + _UpdateInstallBtn(); + public: CApplicationView(CMainWindow *MainWindow); ~CApplicationView(); @@ -388,6 +391,8 @@ class CApplicationView : public CUiWindow> void SetRedraw(BOOL bRedraw); void + RefreshAvailableItem(PCWSTR PackageName); + void SetFocusOnSearchBar(); BOOL SetDisplayAppType(APPLICATION_VIEW_TYPE AppType); @@ -415,13 +420,12 @@ class CApplicationView : public CUiWindow> VOID RestoreListSelection(const RESTORELISTSELECTION &Restore); - // this function is called when a item of listview get focus. - // CallbackParam is the param passed to listview when adding the item (the one getting focus now). + VOID + RefreshDetailsPane(CAppInfo &Info, bool OnlyUpdateText = false); + VOID ItemGetFocus(LPVOID CallbackParam); - // this function is called when a item of listview is checked/unchecked - // CallbackParam is the param passed to listview when adding the item (the one getting focus now). VOID ItemCheckStateChanged(BOOL bChecked, LPVOID CallbackParam); }; diff --git a/base/applications/rapps/include/gui.h b/base/applications/rapps/include/gui.h index 36ff852dde3ec..fbe36a7fea1a2 100644 --- a/base/applications/rapps/include/gui.h +++ b/base/applications/rapps/include/gui.h @@ -65,6 +65,9 @@ class CMainWindow : public CWindowImpl AppsCategories SelectedEnumType; public: + static HWND m_hLastFocus; + static bool m_PendingInstalledViewRefresh; + explicit CMainWindow(CAppDB *db, BOOL bAppwiz = FALSE); ~CMainWindow(); diff --git a/base/applications/rapps/include/misc.h b/base/applications/rapps/include/misc.h index 4617050855ae3..6e7814b8cee86 100644 --- a/base/applications/rapps/include/misc.h +++ b/base/applications/rapps/include/misc.h @@ -26,12 +26,19 @@ ErrorFromHResult(HRESULT hr) return hr >= 0 ? ERROR_SUCCESS : hr; } +UINT +ErrorBox(HWND hOwner, UINT Error = GetLastError()); + VOID CopyTextToClipboard(LPCWSTR lpszText); VOID ShowPopupMenuEx(HWND hwnd, HWND hwndOwner, UINT MenuID, UINT DefaultItem, POINT *Point = NULL); VOID EmulateDialogReposition(HWND hwnd); +UINT +ClassifyFile(PCWSTR Path); +BOOL +OpensWithExplorer(PCWSTR Path); BOOL StartProcess(const CStringW &Path, BOOL Wait); BOOL @@ -117,3 +124,32 @@ GetProgramFilesPath(CStringW &Path, BOOL PerUser, HWND hwnd = NULL); template class CLocalPtr : public CHeapPtr { }; + +struct CScopedMutex +{ + HANDLE m_hMutex; + + CScopedMutex(LPCWSTR Name, UINT Timeout = INFINITE, BOOL InitialOwner = FALSE) + { + m_hMutex = CreateMutexW(NULL, InitialOwner, Name); + if (m_hMutex && !InitialOwner) + { + DWORD wait = WaitForSingleObject(m_hMutex, Timeout); + if (wait != WAIT_OBJECT_0 && wait != WAIT_ABANDONED) + { + CloseHandle(m_hMutex); + m_hMutex = NULL; + } + } + } + ~CScopedMutex() + { + if (m_hMutex) + { + ReleaseMutex(m_hMutex); + CloseHandle(m_hMutex); + } + } + + bool Acquired() const { return m_hMutex != NULL; } +}; diff --git a/base/applications/rapps/include/rapps.h b/base/applications/rapps/include/rapps.h index 49bb4691f092e..f42c5919c2e60 100644 --- a/base/applications/rapps/include/rapps.h +++ b/base/applications/rapps/include/rapps.h @@ -14,7 +14,18 @@ #include "configparser.h" extern LONG g_Busy; +extern bool g_PendingInstalledViewRefresh; #define WM_NOTIFY_OPERATIONCOMPLETED (WM_APP + 0) +#define WM_NOTIFY_INSTALLERFINISHED (WM_APP + 1) + +#define MAINWINDOWCLASSNAME L"ROSAPPMGR2" +#define MAINWINDOWMUTEX szWindowClass +#define UPDATEDBMUTEX ( MAINWINDOWCLASSNAME L":UpDB" ) + +struct CUpdateDatabaseMutex : public CScopedMutex +{ + CUpdateDatabaseMutex() : CScopedMutex(UPDATEDBMUTEX, 1000 * 60 * 10, FALSE) { }; +}; #endif /* _RAPPS_H */ diff --git a/base/applications/rapps/include/resource.h b/base/applications/rapps/include/resource.h index 790a9ae87e1a6..2d832027eb944 100644 --- a/base/applications/rapps/include/resource.h +++ b/base/applications/rapps/include/resource.h @@ -1,4 +1,5 @@ #pragma once +#define LVCHECKSTYLES LVS_REPORT | LVS_NOCOLUMNHEADER | LVS_SINGLESEL | LVS_SORTASCENDING /* Icons */ #define IDI_MAIN 10 @@ -40,11 +41,11 @@ #define IDC_STATUSBAR 1000 #define IDC_DOWNLOAD_PROGRESS 1001 #define IDC_DOWNLOAD_STATUS 1002 -#define IDC_SAVE_WINDOW_POS 1003 -#define IDC_UPDATE_AVLIST 1004 +#define IDC_GENERALLIST 1003 + #define IDC_DOWNLOAD_DIR_EDIT 1005 #define IDC_DEL_AFTER_INSTALL 1006 -#define IDC_LOG_ENABLED 1007 + #define IDC_CHOOSE 1008 #define IDC_DEFAULT_SETTINGS 1009 #define IDC_INSTALL_TEXT 1010 @@ -127,6 +128,10 @@ #define IDS_APP_DISPLAY_LIST 136 #define IDS_APP_DISPLAY_TILE 137 #define IDS_NO_SEARCH_RESULTS 138 +#define IDS_CFG_SAVE_WINDOW_POS 139 +#define IDS_CFG_UPDATE_AVLIST 140 +#define IDS_CFG_LOG_ENABLED 141 +#define IDS_CFG_SMALL_ICONS 142 /* Tooltips */ #define IDS_TOOLTIP_INSTALL 200 @@ -235,6 +240,7 @@ /* Generated installer */ #define IDS_INSTGEN_CONFIRMUNINST 1000 +#define IDS_INSTGEN_CONFIRMINSTRUNAPP 1001 /* Accelerators */ #define HOTKEYS 715 diff --git a/base/applications/rapps/include/settings.h b/base/applications/rapps/include/settings.h index 29f48985e71d3..51d01a2d27d3e 100644 --- a/base/applications/rapps/include/settings.h +++ b/base/applications/rapps/include/settings.h @@ -9,6 +9,7 @@ struct SETTINGS_INFO BOOL bLogEnabled; WCHAR szDownloadDir[MAX_PATH]; BOOL bDelInstaller; + BOOL bSmallIcons; /* Window Pos */ BOOL Maximized; INT Left; diff --git a/base/applications/rapps/lang/bg-BG.rc b/base/applications/rapps/lang/bg-BG.rc index c69ad32e4b5d0..5d8f27e4dbabc 100644 --- a/base/applications/rapps/lang/bg-BG.rc +++ b/base/applications/rapps/lang/bg-BG.rc @@ -49,9 +49,7 @@ CAPTION "Настройки" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Общи", -1, 4, 2, 244, 61 - AUTOCHECKBOX "&Съхраняване разположението на прозореца", IDC_SAVE_WINDOW_POS, 15, 12, 223, 12 - AUTOCHECKBOX "Об&новяване на списъка с достъпните приложения при пускане", IDC_UPDATE_AVLIST, 15, 29, 227, 12 - AUTOCHECKBOX "&Вписване на слаганията и маханията на приложения", IDC_LOG_ENABLED, 15, 46, 223, 12 + CONTROL "", IDC_GENERALLIST, "SysListView32", WS_TABSTOP | LVCHECKSTYLES, 15, 12, 219, 46, WS_EX_STATICEDGE GROUPBOX "Сваляне", -1, 4, 65, 244, 51 LTEXT "Папка за свалените файлове", -1, 16, 75, 100, 9 EDITTEXT IDC_DOWNLOAD_DIR_EDIT, 15, 86, 166, 12, WS_CHILD | WS_VISIBLE | WS_GROUP | ES_AUTOHSCROLL @@ -212,6 +210,10 @@ BEGIN IDS_APP_DISPLAY_LIST "List" IDS_APP_DISPLAY_TILE "Tile" IDS_NO_SEARCH_RESULTS "No search results" + IDS_CFG_SAVE_WINDOW_POS "Съхраняване разположението на прозореца" + IDS_CFG_UPDATE_AVLIST "Обновяване на списъка с достъпните приложения при пускане" + IDS_CFG_LOG_ENABLED "Вписване на слаганията и маханията на приложения" + IDS_CFG_SMALL_ICONS "Малки значета" END STRINGTABLE @@ -265,4 +267,5 @@ END STRINGTABLE BEGIN IDS_INSTGEN_CONFIRMUNINST "Are you sure you want to uninstall %s?" + IDS_INSTGEN_CONFIRMINSTRUNAPP "Installation complete, run %s now?" END diff --git a/base/applications/rapps/lang/cs-CZ.rc b/base/applications/rapps/lang/cs-CZ.rc index 41d01040fb109..8d336327cfe6e 100644 --- a/base/applications/rapps/lang/cs-CZ.rc +++ b/base/applications/rapps/lang/cs-CZ.rc @@ -50,9 +50,7 @@ CAPTION "Nastavení" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Obecné", -1, 4, 2, 240, 61 - AUTOCHECKBOX "&Uložit pozici okna", IDC_SAVE_WINDOW_POS, 15, 12, 219, 12 - AUTOCHECKBOX "&Aktualizovat seznam dostupných programů při startu programu", IDC_UPDATE_AVLIST, 15, 29, 222, 12 - AUTOCHECKBOX "Ukládat &záznam instalací a odstranění programů", IDC_LOG_ENABLED, 15, 46, 219, 12 + CONTROL "", IDC_GENERALLIST, "SysListView32", WS_TABSTOP | LVCHECKSTYLES, 15, 12, 219, 46, WS_EX_STATICEDGE GROUPBOX "Stahování", -1, 4, 65, 240, 51 LTEXT "Složka se staženými soubory:", -1, 16, 75, 100, 9 EDITTEXT IDC_DOWNLOAD_DIR_EDIT, 15, 86, 166, 12, WS_CHILD | WS_VISIBLE | WS_GROUP | ES_AUTOHSCROLL @@ -213,6 +211,10 @@ BEGIN IDS_APP_DISPLAY_LIST "Seznam" IDS_APP_DISPLAY_TILE "Dlaždice" IDS_NO_SEARCH_RESULTS "Žádné výsledky" + IDS_CFG_SAVE_WINDOW_POS "Uložit pozici okna" + IDS_CFG_UPDATE_AVLIST "Aktualizovat seznam dostupných programů při startu programu" + IDS_CFG_LOG_ENABLED "Ukládat záznam instalací a odstranění programů" + IDS_CFG_SMALL_ICONS "Malé ikony" END STRINGTABLE @@ -266,4 +268,5 @@ END STRINGTABLE BEGIN IDS_INSTGEN_CONFIRMUNINST "Opravdu chcete odinstalovat %s?" + IDS_INSTGEN_CONFIRMINSTRUNAPP "Installation complete, run %s now?" END diff --git a/base/applications/rapps/lang/de-DE.rc b/base/applications/rapps/lang/de-DE.rc index 3fedb68171fac..53d4a111147ed 100644 --- a/base/applications/rapps/lang/de-DE.rc +++ b/base/applications/rapps/lang/de-DE.rc @@ -52,9 +52,7 @@ CAPTION "Einstellungen" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Allgemein", -1, 4, 2, 240, 61 - AUTOCHECKBOX "Fensterposition &speichern", IDC_SAVE_WINDOW_POS, 15, 12, 219, 12 - AUTOCHECKBOX "Beim Start Liste der verfügbaren Programme &aktualisieren", IDC_UPDATE_AVLIST, 15, 29, 222, 12 - AUTOCHECKBOX "Hinzufügen und Entfernen von Programmen mit&loggen", IDC_LOG_ENABLED, 15, 46, 219, 12 + CONTROL "", IDC_GENERALLIST, "SysListView32", WS_TABSTOP | LVCHECKSTYLES, 15, 12, 219, 46, WS_EX_STATICEDGE GROUPBOX "Download", -1, 4, 65, 240, 51 LTEXT "Ordner für Downloads:", -1, 16, 75, 100, 9 EDITTEXT IDC_DOWNLOAD_DIR_EDIT, 15, 86, 166, 12, WS_CHILD | WS_VISIBLE | WS_GROUP | ES_AUTOHSCROLL @@ -215,6 +213,10 @@ BEGIN IDS_APP_DISPLAY_LIST "Liste" IDS_APP_DISPLAY_TILE "Kacheln" IDS_NO_SEARCH_RESULTS "No search results" + IDS_CFG_SAVE_WINDOW_POS "Fensterposition speichern" + IDS_CFG_UPDATE_AVLIST "Beim Start Liste der verfügbaren Programme aktualisieren" + IDS_CFG_LOG_ENABLED "Hinzufügen und Entfernen von Programmen mitloggen" + IDS_CFG_SMALL_ICONS "Kleine symbole" END STRINGTABLE @@ -268,4 +270,5 @@ END STRINGTABLE BEGIN IDS_INSTGEN_CONFIRMUNINST "Are you sure you want to uninstall %s?" + IDS_INSTGEN_CONFIRMINSTRUNAPP "Installation complete, run %s now?" END diff --git a/base/applications/rapps/lang/en-US.rc b/base/applications/rapps/lang/en-US.rc index 968360d3b130d..499aeb5142d8c 100644 --- a/base/applications/rapps/lang/en-US.rc +++ b/base/applications/rapps/lang/en-US.rc @@ -52,9 +52,7 @@ CAPTION "Settings" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "General", -1, 4, 2, 240, 61 - AUTOCHECKBOX "&Save window position", IDC_SAVE_WINDOW_POS, 15, 12, 219, 12 - AUTOCHECKBOX "&Update the list of accessible programs at start", IDC_UPDATE_AVLIST, 15, 29, 222, 12 - AUTOCHECKBOX "&Log of installation and removal of programs", IDC_LOG_ENABLED, 15, 46, 219, 12 + CONTROL "", IDC_GENERALLIST, "SysListView32", WS_TABSTOP | LVCHECKSTYLES, 15, 12, 219, 46, WS_EX_STATICEDGE GROUPBOX "Downloading", -1, 4, 65, 240, 51 LTEXT "Downloads folder:", -1, 16, 75, 100, 9 EDITTEXT IDC_DOWNLOAD_DIR_EDIT, 15, 86, 166, 12, WS_CHILD | WS_VISIBLE | WS_GROUP | ES_AUTOHSCROLL @@ -215,6 +213,10 @@ BEGIN IDS_APP_DISPLAY_LIST "List" IDS_APP_DISPLAY_TILE "Tile" IDS_NO_SEARCH_RESULTS "No search results" + IDS_CFG_SAVE_WINDOW_POS "Save window position" + IDS_CFG_UPDATE_AVLIST "Update the list of accessible programs at start" + IDS_CFG_LOG_ENABLED "Log of installation and removal of programs" + IDS_CFG_SMALL_ICONS "Small icons" END STRINGTABLE @@ -268,4 +270,5 @@ END STRINGTABLE BEGIN IDS_INSTGEN_CONFIRMUNINST "Are you sure you want to uninstall %s?" + IDS_INSTGEN_CONFIRMINSTRUNAPP "Installation complete, run %s now?" END diff --git a/base/applications/rapps/lang/es-ES.rc b/base/applications/rapps/lang/es-ES.rc index 60e047b0f2ccb..67f2a93080288 100644 --- a/base/applications/rapps/lang/es-ES.rc +++ b/base/applications/rapps/lang/es-ES.rc @@ -51,9 +51,7 @@ CAPTION "Ajustes" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "General", -1, 4, 2, 240, 61 - AUTOCHECKBOX "&Guardar posición de la ventana", IDC_SAVE_WINDOW_POS, 15, 12, 219, 12 - AUTOCHECKBOX "&Actualizar la lista de programas accesibles al comenzar", IDC_UPDATE_AVLIST, 15, 29, 222, 12 - AUTOCHECKBOX "&Registro de programas instalados y desinstalados", IDC_LOG_ENABLED, 15, 46, 219, 12 + CONTROL "", IDC_GENERALLIST, "SysListView32", WS_TABSTOP | LVCHECKSTYLES, 15, 12, 219, 46, WS_EX_STATICEDGE GROUPBOX "Descargas", -1, 4, 65, 240, 51 LTEXT "Carpeta de descargas:", -1, 16, 75, 100, 9 EDITTEXT IDC_DOWNLOAD_DIR_EDIT, 15, 86, 166, 12, WS_CHILD | WS_VISIBLE | WS_GROUP | ES_AUTOHSCROLL @@ -214,6 +212,10 @@ BEGIN IDS_APP_DISPLAY_LIST "Lista" IDS_APP_DISPLAY_TILE "Título" IDS_NO_SEARCH_RESULTS "Búsqueda sin resultados." + IDS_CFG_SAVE_WINDOW_POS "Guardar posición de la ventana" + IDS_CFG_UPDATE_AVLIST "Actualizar la lista de programas accesibles al comenzar" + IDS_CFG_LOG_ENABLED "Registro de programas instalados y desinstalados" + IDS_CFG_SMALL_ICONS "Iconos pequeños" END STRINGTABLE @@ -267,4 +269,5 @@ END STRINGTABLE BEGIN IDS_INSTGEN_CONFIRMUNINST "Are you sure you want to uninstall %s?" + IDS_INSTGEN_CONFIRMINSTRUNAPP "Installation complete, run %s now?" END diff --git a/base/applications/rapps/lang/et-EE.rc b/base/applications/rapps/lang/et-EE.rc index 6af7f201d002a..9ab9214ea411b 100644 --- a/base/applications/rapps/lang/et-EE.rc +++ b/base/applications/rapps/lang/et-EE.rc @@ -49,9 +49,7 @@ CAPTION "Sätted" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Üldine", -1, 4, 2, 240, 61 - AUTOCHECKBOX "&Salvesta akna asukoht", IDC_SAVE_WINDOW_POS, 15, 12, 219, 12 - AUTOCHECKBOX "&Värskenda kättesaadavate programmide nimekirja käivitusel", IDC_UPDATE_AVLIST, 15, 29, 222, 12 - AUTOCHECKBOX "Installeerimiste ja eemalduste &logi", IDC_LOG_ENABLED, 15, 46, 219, 12 + CONTROL "", IDC_GENERALLIST, "SysListView32", WS_TABSTOP | LVCHECKSTYLES, 15, 12, 219, 46, WS_EX_STATICEDGE GROUPBOX "Allalaadimine", -1, 4, 65, 240, 51 LTEXT "Allalaadimiste kaust:", -1, 16, 75, 100, 9 EDITTEXT IDC_DOWNLOAD_DIR_EDIT, 15, 86, 166, 12, WS_CHILD | WS_VISIBLE | WS_GROUP | ES_AUTOHSCROLL @@ -212,6 +210,10 @@ BEGIN IDS_APP_DISPLAY_LIST "List" IDS_APP_DISPLAY_TILE "Tile" IDS_NO_SEARCH_RESULTS "No search results" + IDS_CFG_SAVE_WINDOW_POS "Salvesta akna asukoht" + IDS_CFG_UPDATE_AVLIST "Värskenda kättesaadavate programmide nimekirja käivitusel" + IDS_CFG_LOG_ENABLED "Installeerimiste ja eemalduste logi" + IDS_CFG_SMALL_ICONS "Väikesed ikoonid" END STRINGTABLE @@ -265,4 +267,5 @@ END STRINGTABLE BEGIN IDS_INSTGEN_CONFIRMUNINST "Are you sure you want to uninstall %s?" + IDS_INSTGEN_CONFIRMINSTRUNAPP "Installation complete, run %s now?" END diff --git a/base/applications/rapps/lang/fr-FR.rc b/base/applications/rapps/lang/fr-FR.rc index 0a7baf2bb7604..ddad6d4c90a21 100644 --- a/base/applications/rapps/lang/fr-FR.rc +++ b/base/applications/rapps/lang/fr-FR.rc @@ -52,9 +52,7 @@ CAPTION "Configuration" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Général", -1, 4, 2, 240, 61 - AUTOCHECKBOX "&Enregistrer la position de la fenêtre", IDC_SAVE_WINDOW_POS, 15, 12, 219, 12 - AUTOCHECKBOX "&Mettre à jour la liste des programmes accessibles au démarrage", IDC_UPDATE_AVLIST, 15, 29, 222, 12 - AUTOCHECKBOX "&Journal de l'installation et de la suppression des programmes", IDC_LOG_ENABLED, 15, 46, 219, 12 + CONTROL "", IDC_GENERALLIST, "SysListView32", WS_TABSTOP | LVCHECKSTYLES, 15, 12, 219, 46, WS_EX_STATICEDGE GROUPBOX "Téléchargement", -1, 4, 65, 240, 51 LTEXT "Dossier des téléchargements :", -1, 16, 75, 100, 9 EDITTEXT IDC_DOWNLOAD_DIR_EDIT, 15, 86, 166, 12, WS_CHILD | WS_VISIBLE | WS_GROUP | ES_AUTOHSCROLL @@ -215,6 +213,10 @@ BEGIN IDS_APP_DISPLAY_LIST "Liste" IDS_APP_DISPLAY_TILE "Tuile" IDS_NO_SEARCH_RESULTS "Aucun résultat" + IDS_CFG_SAVE_WINDOW_POS "Enregistrer la position de la fenêtre" + IDS_CFG_UPDATE_AVLIST "Mettre à jour la liste des programmes accessibles au démarrage" + IDS_CFG_LOG_ENABLED "Journal de l'installation et de la suppression des programmes" + IDS_CFG_SMALL_ICONS "Petites icônes" END STRINGTABLE @@ -268,4 +270,5 @@ END STRINGTABLE BEGIN IDS_INSTGEN_CONFIRMUNINST "Êtes-vous sûr de vouloir désinstaller %s ?" + IDS_INSTGEN_CONFIRMINSTRUNAPP "Installation complete, run %s now?" END diff --git a/base/applications/rapps/lang/he-IL.rc b/base/applications/rapps/lang/he-IL.rc index 0090533fe187e..90837d9fc0105 100644 --- a/base/applications/rapps/lang/he-IL.rc +++ b/base/applications/rapps/lang/he-IL.rc @@ -52,9 +52,7 @@ CAPTION "הגדרות" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "כללי", -1, 4, 2, 240, 61 - AUTOCHECKBOX "שמור מיקום חלון", IDC_SAVE_WINDOW_POS, 15, 12, 219, 12 - AUTOCHECKBOX "עדכן את רשימת התוכניות האפשרויות בהפעלה", IDC_UPDATE_AVLIST, 15, 29, 222, 12 - AUTOCHECKBOX "תעד התקנה והסרה של תוכניות", IDC_LOG_ENABLED, 15, 46, 219, 12 + CONTROL "", IDC_GENERALLIST, "SysListView32", WS_TABSTOP | LVCHECKSTYLES, 15, 12, 219, 46, WS_EX_STATICEDGE GROUPBOX "הורדה", -1, 4, 65, 240, 51 LTEXT "תיקיית הורדות:", -1, 16, 75, 100, 9 EDITTEXT IDC_DOWNLOAD_DIR_EDIT, 15, 86, 166, 12, WS_CHILD | WS_VISIBLE | WS_GROUP | ES_AUTOHSCROLL @@ -217,6 +215,10 @@ BEGIN IDS_APP_DISPLAY_LIST "List" IDS_APP_DISPLAY_TILE "Tile" IDS_NO_SEARCH_RESULTS "No search results" + IDS_CFG_SAVE_WINDOW_POS "שמור מיקום חלון" + IDS_CFG_UPDATE_AVLIST "עדכן את רשימת התוכניות האפשרויות בהפעלה" + IDS_CFG_LOG_ENABLED "תעד התקנה והסרה של תוכניות" + IDS_CFG_SMALL_ICONS "סמלים קטנים" END STRINGTABLE @@ -270,4 +272,5 @@ END STRINGTABLE BEGIN IDS_INSTGEN_CONFIRMUNINST "Are you sure you want to uninstall %s?" + IDS_INSTGEN_CONFIRMINSTRUNAPP "Installation complete, run %s now?" END diff --git a/base/applications/rapps/lang/hu-HU.rc b/base/applications/rapps/lang/hu-HU.rc index 5fa6c502db50d..21f7b9b71ee39 100644 --- a/base/applications/rapps/lang/hu-HU.rc +++ b/base/applications/rapps/lang/hu-HU.rc @@ -49,9 +49,7 @@ CAPTION "Beállítások" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Általános", -1, 4, 2, 240, 61 - AUTOCHECKBOX "&Ablak helyének megjegyzése", IDC_SAVE_WINDOW_POS, 15, 12, 219, 12 - AUTOCHECKBOX "Elérhető programok listájának &frissítése indításkor", IDC_UPDATE_AVLIST, 15, 29, 222, 12 - AUTOCHECKBOX "Programok telepítésének és eltávolításának &naplózása", IDC_LOG_ENABLED, 15, 46, 219, 12 + CONTROL "", IDC_GENERALLIST, "SysListView32", WS_TABSTOP | LVCHECKSTYLES, 15, 12, 219, 46, WS_EX_STATICEDGE GROUPBOX "Letöltés", -1, 4, 65, 240, 51 LTEXT "Letöltés mappája:", -1, 16, 75, 100, 9 EDITTEXT IDC_DOWNLOAD_DIR_EDIT, 15, 86, 166, 12, WS_CHILD | WS_VISIBLE | WS_GROUP | ES_AUTOHSCROLL @@ -212,6 +210,10 @@ BEGIN IDS_APP_DISPLAY_LIST "Lista" IDS_APP_DISPLAY_TILE "Csempe" IDS_NO_SEARCH_RESULTS "No search results" + IDS_CFG_SAVE_WINDOW_POS "Ablak helyének megjegyzése" + IDS_CFG_UPDATE_AVLIST "Elérhető programok listájának frissítése indításkor" + IDS_CFG_LOG_ENABLED "Programok telepítésének és eltávolításának naplózása" + IDS_CFG_SMALL_ICONS "Kis képek" END STRINGTABLE @@ -265,4 +267,5 @@ END STRINGTABLE BEGIN IDS_INSTGEN_CONFIRMUNINST "Are you sure you want to uninstall %s?" + IDS_INSTGEN_CONFIRMINSTRUNAPP "Installation complete, run %s now?" END diff --git a/base/applications/rapps/lang/id-ID.rc b/base/applications/rapps/lang/id-ID.rc index 92942ec2325ea..1dde61b41363a 100644 --- a/base/applications/rapps/lang/id-ID.rc +++ b/base/applications/rapps/lang/id-ID.rc @@ -49,9 +49,7 @@ CAPTION "Pengaturan" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Umum", -1, 4, 2, 240, 61 - AUTOCHECKBOX "&Simpan posisi jendela", IDC_SAVE_WINDOW_POS, 15, 12, 219, 12 - AUTOCHECKBOX "&Perbarui daftar program yang bisa diakses saat mulai", IDC_UPDATE_AVLIST, 15, 29, 222, 12 - AUTOCHECKBOX "&Log pemasangan dan pembongkaran program", IDC_LOG_ENABLED, 15, 46, 219, 12 + CONTROL "", IDC_GENERALLIST, "SysListView32", WS_TABSTOP | LVCHECKSTYLES, 15, 12, 219, 46, WS_EX_STATICEDGE GROUPBOX "Mengunduh", -1, 4, 65, 240, 51 LTEXT "Folder unduhan:", -1, 16, 75, 100, 9 EDITTEXT IDC_DOWNLOAD_DIR_EDIT, 15, 86, 166, 12, WS_CHILD | WS_VISIBLE | WS_GROUP | ES_AUTOHSCROLL @@ -212,6 +210,10 @@ BEGIN IDS_APP_DISPLAY_LIST "List" IDS_APP_DISPLAY_TILE "Tile" IDS_NO_SEARCH_RESULTS "No search results" + IDS_CFG_SAVE_WINDOW_POS "Simpan posisi jendela" + IDS_CFG_UPDATE_AVLIST "Perbarui daftar program yang bisa diakses saat mulai" + IDS_CFG_LOG_ENABLED "Log pemasangan dan pembongkaran program" + IDS_CFG_SMALL_ICONS "Ikon Kecil" END STRINGTABLE @@ -265,4 +267,5 @@ END STRINGTABLE BEGIN IDS_INSTGEN_CONFIRMUNINST "Are you sure you want to uninstall %s?" + IDS_INSTGEN_CONFIRMINSTRUNAPP "Installation complete, run %s now?" END diff --git a/base/applications/rapps/lang/it-IT.rc b/base/applications/rapps/lang/it-IT.rc index a80578d2dcc60..1075574ba4c50 100644 --- a/base/applications/rapps/lang/it-IT.rc +++ b/base/applications/rapps/lang/it-IT.rc @@ -51,9 +51,7 @@ CAPTION "Impostazioni" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Generale", -1, 4, 2, 240, 61 - AUTOCHECKBOX "&Salva la posizione della finestra", IDC_SAVE_WINDOW_POS, 15, 12, 219, 12 - AUTOCHECKBOX "&Aggiorna la lista dei programmi accessibili", IDC_UPDATE_AVLIST, 15, 29, 222, 12 - AUTOCHECKBOX "&Registra la installazione o disinstallazione dei programmi", IDC_LOG_ENABLED, 15, 46, 219, 12 + CONTROL "", IDC_GENERALLIST, "SysListView32", WS_TABSTOP | LVCHECKSTYLES, 15, 12, 219, 46, WS_EX_STATICEDGE GROUPBOX "Scaricamenti", -1, 4, 65, 240, 51 LTEXT "Cartella:", -1, 16, 75, 100, 9 EDITTEXT IDC_DOWNLOAD_DIR_EDIT, 15, 86, 166, 12, WS_CHILD | WS_VISIBLE | WS_GROUP | ES_AUTOHSCROLL @@ -214,6 +212,10 @@ BEGIN IDS_APP_DISPLAY_LIST "List" IDS_APP_DISPLAY_TILE "Tile" IDS_NO_SEARCH_RESULTS "No search results" + IDS_CFG_SAVE_WINDOW_POS "Salva la posizione della finestra" + IDS_CFG_UPDATE_AVLIST "Aggiorna la lista dei programmi accessibili" + IDS_CFG_LOG_ENABLED "Registra la installazione o disinstallazione dei programmi" + IDS_CFG_SMALL_ICONS "Icone Piccole" END STRINGTABLE @@ -267,4 +269,5 @@ END STRINGTABLE BEGIN IDS_INSTGEN_CONFIRMUNINST "Are you sure you want to uninstall %s?" + IDS_INSTGEN_CONFIRMINSTRUNAPP "Installation complete, run %s now?" END diff --git a/base/applications/rapps/lang/ja-JP.rc b/base/applications/rapps/lang/ja-JP.rc index c17ffd03f8dff..b62872f52ae4a 100644 --- a/base/applications/rapps/lang/ja-JP.rc +++ b/base/applications/rapps/lang/ja-JP.rc @@ -51,9 +51,7 @@ CAPTION "設定" FONT 9, "MS UI Gothic" BEGIN GROUPBOX "全般", -1, 4, 2, 240, 61 - AUTOCHECKBOX "ウィンドウの場所を保存する(&S)", IDC_SAVE_WINDOW_POS, 15, 12, 219, 12 - AUTOCHECKBOX "起動時に利用できるプログラムのリストを更新する(&U)", IDC_UPDATE_AVLIST, 15, 29, 222, 12 - AUTOCHECKBOX "プログラムのインストールと削除を記録する(&L)", IDC_LOG_ENABLED, 15, 46, 219, 12 + CONTROL "", IDC_GENERALLIST, "SysListView32", WS_TABSTOP | LVCHECKSTYLES, 15, 12, 219, 46, WS_EX_STATICEDGE GROUPBOX "ダウンロード処理", -1, 4, 65, 240, 51 LTEXT "ダウンロードするフォルダ:", -1, 16, 75, 100, 9 EDITTEXT IDC_DOWNLOAD_DIR_EDIT, 15, 86, 166, 12, WS_CHILD | WS_VISIBLE | WS_GROUP | ES_AUTOHSCROLL @@ -214,6 +212,10 @@ BEGIN IDS_APP_DISPLAY_LIST "リスト" IDS_APP_DISPLAY_TILE "タイル" IDS_NO_SEARCH_RESULTS "検索結果はありません" + IDS_CFG_SAVE_WINDOW_POS "ウィンドウの場所を保存する" + IDS_CFG_UPDATE_AVLIST "起動時に利用できるプログラムのリストを更新する" + IDS_CFG_LOG_ENABLED "プログラムのインストールと削除を記録する" + IDS_CFG_SMALL_ICONS "小さいアイコン" END STRINGTABLE @@ -267,4 +269,5 @@ END STRINGTABLE BEGIN IDS_INSTGEN_CONFIRMUNINST "Are you sure you want to uninstall %s?" + IDS_INSTGEN_CONFIRMINSTRUNAPP "Installation complete, run %s now?" END diff --git a/base/applications/rapps/lang/no-NO.rc b/base/applications/rapps/lang/no-NO.rc index bb2393102e67a..b271227c78aa4 100644 --- a/base/applications/rapps/lang/no-NO.rc +++ b/base/applications/rapps/lang/no-NO.rc @@ -49,9 +49,7 @@ CAPTION "Settings" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "General", -1, 4, 2, 240, 61 - AUTOCHECKBOX "&Save window position", IDC_SAVE_WINDOW_POS, 15, 12, 219, 12 - AUTOCHECKBOX "&Update the list of accessible programs at start", IDC_UPDATE_AVLIST, 15, 29, 222, 12 - AUTOCHECKBOX "&Log of installation and removal of programs", IDC_LOG_ENABLED, 15, 46, 219, 12 + CONTROL "", IDC_GENERALLIST, "SysListView32", WS_TABSTOP | LVCHECKSTYLES, 15, 12, 219, 46, WS_EX_STATICEDGE GROUPBOX "Downloading", -1, 4, 65, 240, 51 LTEXT "Folder for downloadings:", -1, 16, 75, 100, 9 EDITTEXT IDC_DOWNLOAD_DIR_EDIT, 15, 86, 166, 12, WS_CHILD | WS_VISIBLE | WS_GROUP | ES_AUTOHSCROLL @@ -212,6 +210,10 @@ BEGIN IDS_APP_DISPLAY_LIST "List" IDS_APP_DISPLAY_TILE "Tile" IDS_NO_SEARCH_RESULTS "No search results" + IDS_CFG_SAVE_WINDOW_POS "Save window position" + IDS_CFG_UPDATE_AVLIST "Update the list of accessible programs at start" + IDS_CFG_LOG_ENABLED "Log of installation and removal of programs" + IDS_CFG_SMALL_ICONS "Små ikoner" END STRINGTABLE @@ -265,4 +267,5 @@ END STRINGTABLE BEGIN IDS_INSTGEN_CONFIRMUNINST "Are you sure you want to uninstall %s?" + IDS_INSTGEN_CONFIRMINSTRUNAPP "Installation complete, run %s now?" END diff --git a/base/applications/rapps/lang/pl-PL.rc b/base/applications/rapps/lang/pl-PL.rc index d4ff8f18ad4d7..1aa2fcc613519 100644 --- a/base/applications/rapps/lang/pl-PL.rc +++ b/base/applications/rapps/lang/pl-PL.rc @@ -51,9 +51,7 @@ CAPTION "Ustawienia" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Ogólne", -1, 4, 2, 240, 61 - AUTOCHECKBOX "&Zapisz pozycję okna", IDC_SAVE_WINDOW_POS, 15, 12, 219, 12 - AUTOCHECKBOX "&Aktualizuj listę dostępnych programów przy każdym uruchomieniu", IDC_UPDATE_AVLIST, 15, 29, 222, 12 - AUTOCHECKBOX "Zapisuj &dziennik instalacji i usuwania programów", IDC_LOG_ENABLED, 15, 46, 219, 12 + CONTROL "", IDC_GENERALLIST, "SysListView32", WS_TABSTOP | LVCHECKSTYLES, 15, 12, 219, 46, WS_EX_STATICEDGE GROUPBOX "Pobieranie", -1, 4, 65, 240, 51 LTEXT "Katalog dla pobranych plików:", -1, 16, 75, 100, 9 EDITTEXT IDC_DOWNLOAD_DIR_EDIT, 15, 86, 166, 12, WS_CHILD | WS_VISIBLE | WS_GROUP | ES_AUTOHSCROLL @@ -214,6 +212,10 @@ BEGIN IDS_APP_DISPLAY_LIST "Lista" IDS_APP_DISPLAY_TILE "Kafelki" IDS_NO_SEARCH_RESULTS "No search results" + IDS_CFG_SAVE_WINDOW_POS "Zapisz pozycję okna" + IDS_CFG_UPDATE_AVLIST "Aktualizuj listę dostępnych programów przy każdym uruchomieniu" + IDS_CFG_LOG_ENABLED "Zapisuj dziennik instalacji i usuwania programów" + IDS_CFG_SMALL_ICONS "Małe ikony" END STRINGTABLE @@ -267,4 +269,5 @@ END STRINGTABLE BEGIN IDS_INSTGEN_CONFIRMUNINST "Are you sure you want to uninstall %s?" + IDS_INSTGEN_CONFIRMINSTRUNAPP "Installation complete, run %s now?" END diff --git a/base/applications/rapps/lang/pt-BR.rc b/base/applications/rapps/lang/pt-BR.rc index 02be0fcd5f019..807615a63cac3 100644 --- a/base/applications/rapps/lang/pt-BR.rc +++ b/base/applications/rapps/lang/pt-BR.rc @@ -49,9 +49,7 @@ CAPTION "Configurações" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Geral", -1, 4, 2, 240, 61 - AUTOCHECKBOX "&Salvar posição da janela", IDC_SAVE_WINDOW_POS, 15, 12, 219, 12 - AUTOCHECKBOX "&Atualizar esta lista de programas ao iniciar", IDC_UPDATE_AVLIST, 15, 29, 222, 12 - AUTOCHECKBOX "&Registro de instalação e remoção de programas", IDC_LOG_ENABLED, 15, 46, 219, 12 + CONTROL "", IDC_GENERALLIST, "SysListView32", WS_TABSTOP | LVCHECKSTYLES, 15, 12, 219, 46, WS_EX_STATICEDGE GROUPBOX "Baixando", -1, 4, 65, 240, 51 LTEXT "Pasta de download:", -1, 16, 75, 100, 9 EDITTEXT IDC_DOWNLOAD_DIR_EDIT, 15, 86, 166, 12, WS_CHILD | WS_VISIBLE | WS_GROUP | ES_AUTOHSCROLL @@ -212,6 +210,10 @@ BEGIN IDS_APP_DISPLAY_LIST "List" IDS_APP_DISPLAY_TILE "Tile" IDS_NO_SEARCH_RESULTS "No search results" + IDS_CFG_SAVE_WINDOW_POS "Salvar posição da janela" + IDS_CFG_UPDATE_AVLIST "Atualizar esta lista de programas ao iniciar" + IDS_CFG_LOG_ENABLED "Registro de instalação e remoção de programas" + IDS_CFG_SMALL_ICONS "Ícones pequenos" END STRINGTABLE @@ -265,4 +267,5 @@ END STRINGTABLE BEGIN IDS_INSTGEN_CONFIRMUNINST "Are you sure you want to uninstall %s?" + IDS_INSTGEN_CONFIRMINSTRUNAPP "Installation complete, run %s now?" END diff --git a/base/applications/rapps/lang/pt-PT.rc b/base/applications/rapps/lang/pt-PT.rc index aea5ccc349124..dfdd2850137b4 100644 --- a/base/applications/rapps/lang/pt-PT.rc +++ b/base/applications/rapps/lang/pt-PT.rc @@ -49,9 +49,7 @@ CAPTION "Configurações" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Geral", -1, 4, 2, 240, 61 - AUTOCHECKBOX "&Guardar posição da janela", IDC_SAVE_WINDOW_POS, 15, 12, 219, 12 - AUTOCHECKBOX "&Actualizar a lista de programas ao iniciar", IDC_UPDATE_AVLIST, 15, 29, 222, 12 - AUTOCHECKBOX "&Registar a instalação e remoção de programas", IDC_LOG_ENABLED, 15, 46, 219, 12 + CONTROL "", IDC_GENERALLIST, "SysListView32", WS_TABSTOP | LVCHECKSTYLES, 15, 12, 219, 46, WS_EX_STATICEDGE GROUPBOX "A carregar", -1, 4, 65, 240, 51 LTEXT "Pasta de download:", -1, 16, 75, 100, 9 EDITTEXT IDC_DOWNLOAD_DIR_EDIT, 15, 86, 166, 12, WS_CHILD | WS_VISIBLE | WS_GROUP | ES_AUTOHSCROLL @@ -212,6 +210,10 @@ BEGIN IDS_APP_DISPLAY_LIST "Lista" IDS_APP_DISPLAY_TILE "Cabeçalho" IDS_NO_SEARCH_RESULTS "Busca sem resultados" + IDS_CFG_SAVE_WINDOW_POS "Guardar posição da janela" + IDS_CFG_UPDATE_AVLIST "Actualizar a lista de programas ao iniciar" + IDS_CFG_LOG_ENABLED "Registar a instalação e remoção de programas" + IDS_CFG_SMALL_ICONS "Ícones pequenos" END STRINGTABLE @@ -265,4 +267,5 @@ END STRINGTABLE BEGIN IDS_INSTGEN_CONFIRMUNINST "Are you sure you want to uninstall %s?" + IDS_INSTGEN_CONFIRMINSTRUNAPP "Installation complete, run %s now?" END diff --git a/base/applications/rapps/lang/ro-RO.rc b/base/applications/rapps/lang/ro-RO.rc index e4cb46dd2866f..ba9421f37fec6 100644 --- a/base/applications/rapps/lang/ro-RO.rc +++ b/base/applications/rapps/lang/ro-RO.rc @@ -51,9 +51,7 @@ CAPTION "Setări" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "General", -1, 4, 2, 240, 61 - AUTOCHECKBOX "&Salvare a poziției ferestrei", IDC_SAVE_WINDOW_POS, 15, 12, 219, 12 - AUTOCHECKBOX "&Actualizare la pornire a listei programelor disponibile", IDC_UPDATE_AVLIST, 15, 29, 222, 12 - AUTOCHECKBOX "Menținere a j&urnalului de instalare/dezinstalare a programelor", IDC_LOG_ENABLED, 15, 46, 219, 12 + CONTROL "", IDC_GENERALLIST, "SysListView32", WS_TABSTOP | LVCHECKSTYLES, 15, 12, 219, 46, WS_EX_STATICEDGE GROUPBOX "Descărcări", -1, 4, 65, 240, 51 LTEXT "Folderul pentru descărcări:", -1, 16, 75, 100, 9 EDITTEXT IDC_DOWNLOAD_DIR_EDIT, 15, 86, 166, 12, WS_CHILD | WS_VISIBLE | WS_GROUP | ES_AUTOHSCROLL @@ -214,6 +212,10 @@ BEGIN IDS_APP_DISPLAY_LIST "Listă" IDS_APP_DISPLAY_TILE "Dale" IDS_NO_SEARCH_RESULTS "Niciun rezultat al căutării" + IDS_CFG_SAVE_WINDOW_POS "Salvare a poziției ferestrei" + IDS_CFG_UPDATE_AVLIST "Actualizare la pornire a listei programelor disponibile" + IDS_CFG_LOG_ENABLED "Menținere a jurnalului de instalare/dezinstalare a programelor" + IDS_CFG_SMALL_ICONS "Pictograme mici" END STRINGTABLE @@ -267,4 +269,5 @@ END STRINGTABLE BEGIN IDS_INSTGEN_CONFIRMUNINST "Sigur doriți să dezinstalați %s?" + IDS_INSTGEN_CONFIRMINSTRUNAPP "Installation complete, run %s now?" END diff --git a/base/applications/rapps/lang/ru-RU.rc b/base/applications/rapps/lang/ru-RU.rc index bf4919daf42ed..6b11933488667 100644 --- a/base/applications/rapps/lang/ru-RU.rc +++ b/base/applications/rapps/lang/ru-RU.rc @@ -54,9 +54,7 @@ CAPTION "Параметры" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Общие", -1, 4, 2, 240, 61 - AUTOCHECKBOX "&Сохранять положение окна", IDC_SAVE_WINDOW_POS, 15, 12, 219, 12 - AUTOCHECKBOX "&Обновлять список доступных программ при запуске", IDC_UPDATE_AVLIST, 15, 29, 222, 12 - AUTOCHECKBOX "&Вести лог установки/удаления программ", IDC_LOG_ENABLED, 15, 46, 219, 12 + CONTROL "", IDC_GENERALLIST, "SysListView32", WS_TABSTOP | LVCHECKSTYLES, 15, 12, 219, 46, WS_EX_STATICEDGE GROUPBOX "Загрузка", -1, 4, 65, 240, 51 LTEXT "Папка для загрузок:", -1, 16, 75, 77, 9 EDITTEXT IDC_DOWNLOAD_DIR_EDIT, 15, 86, 166, 12, WS_CHILD | WS_VISIBLE | WS_GROUP | ES_AUTOHSCROLL @@ -217,6 +215,10 @@ BEGIN IDS_APP_DISPLAY_LIST "Список" IDS_APP_DISPLAY_TILE "Плитка" IDS_NO_SEARCH_RESULTS "Ничего не найдено" + IDS_CFG_SAVE_WINDOW_POS "Сохранять положение окна" + IDS_CFG_UPDATE_AVLIST "Обновлять список доступных программ при запуске" + IDS_CFG_LOG_ENABLED "Вести лог установки/удаления программ" + IDS_CFG_SMALL_ICONS "Мелкие значки" END STRINGTABLE @@ -270,4 +272,5 @@ END STRINGTABLE BEGIN IDS_INSTGEN_CONFIRMUNINST "Are you sure you want to uninstall %s?" + IDS_INSTGEN_CONFIRMINSTRUNAPP "Installation complete, run %s now?" END diff --git a/base/applications/rapps/lang/sk-SK.rc b/base/applications/rapps/lang/sk-SK.rc index 79d38ea468aad..44932a0b4e344 100644 --- a/base/applications/rapps/lang/sk-SK.rc +++ b/base/applications/rapps/lang/sk-SK.rc @@ -2,7 +2,8 @@ * PROJECT: ReactOS Applications Manager * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) * PURPOSE: Slovak resource file - * TRANSLATOR: Copyright 2009-2010 Mário Kačmár + * TRANSLATORS: Copyright 2009-2010 Mário Kačmár + * Copyright 2024 Václav Zouzalík (Venca24) */ LANGUAGE LANG_SLOVAK, SUBLANG_DEFAULT @@ -25,12 +26,12 @@ BEGIN MENUITEM SEPARATOR MENUITEM "&Obnoviť\tF5", ID_REFRESH MENUITEM SEPARATOR - MENUITEM "Update Data&base\tCtrl+F5", ID_RESETDB + MENUITEM "Aktualizovať data&bázu\tCtrl+F5", ID_RESETDB END POPUP "Pomocník" BEGIN MENUITEM "Pomocník\tF1", ID_HELP, GRAYED - MENUITEM "Čo je", ID_ABOUT + MENUITEM "O programe", ID_ABOUT END END @@ -38,8 +39,8 @@ IDR_LINKMENU MENU BEGIN POPUP "" BEGIN - MENUITEM "&Otvoriť linku v prehliadači", ID_OPEN_LINK - MENUITEM "&Kopírovať linku do schránky", ID_COPY_LINK + MENUITEM "&Otvoriť odkaz v prehliadači", ID_OPEN_LINK + MENUITEM "&Kopírovať odkaz do schránky", ID_COPY_LINK END END @@ -49,24 +50,22 @@ CAPTION "Nastavenia" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Všeobecné", -1, 4, 2, 240, 61 - AUTOCHECKBOX "&Uložiť pozíciu okna", IDC_SAVE_WINDOW_POS, 15, 12, 219, 12 - AUTOCHECKBOX "&Aktualizovať zoznam dostupných programov pri spustení", IDC_UPDATE_AVLIST, 15, 29, 222, 12 - AUTOCHECKBOX "&Záznam o inštalovaní a odstránení programov", IDC_LOG_ENABLED, 15, 46, 219, 12 + CONTROL "", IDC_GENERALLIST, "SysListView32", WS_TABSTOP | LVCHECKSTYLES, 15, 12, 219, 46, WS_EX_STATICEDGE GROUPBOX "Sťahovanie", -1, 4, 65, 240, 51 LTEXT "Priečinok pre sťahovanie:", -1, 16, 75, 100, 9 EDITTEXT IDC_DOWNLOAD_DIR_EDIT, 15, 86, 166, 12, WS_CHILD | WS_VISIBLE | WS_GROUP | ES_AUTOHSCROLL PUSHBUTTON "&Vybrať", IDC_CHOOSE, 187, 85, 50, 14 AUTOCHECKBOX "&Zmazať inštalačné programy po nainštalovaní", IDC_DEL_AFTER_INSTALL, 16, 100, 218, 12 - GROUPBOX "Software source", -1, 4, 118, 240, 46 - AUTORADIOBUTTON "Use default", IDC_SOURCE_DEFAULT, 15, 132, 74, 10, WS_GROUP | WS_TABSTOP - AUTORADIOBUTTON "Specified source", IDC_USE_SOURCE, 15, 147, 74, 10 + GROUPBOX "Zdroj softvéru", -1, 4, 118, 240, 46 + AUTORADIOBUTTON "Použiť predvolené", IDC_SOURCE_DEFAULT, 15, 132, 74, 10, WS_GROUP | WS_TABSTOP + AUTORADIOBUTTON "Vlastný zdroj", IDC_USE_SOURCE, 15, 147, 74, 10 EDITTEXT IDC_SOURCE_URL, 97, 147, 140, 12, ES_AUTOHSCROLL | WS_DISABLED GROUPBOX "Proxy", -1, 4, 166, 240, 76 - AUTORADIOBUTTON "System proxy settings", IDC_PROXY_DEFAULT, 15, 180, 210, 10, WS_GROUP | WS_TABSTOP - AUTORADIOBUTTON "Direct (No proxy)", IDC_NO_PROXY, 15, 195, 210, 10 + AUTORADIOBUTTON "Systémové nastavenia proxy", IDC_PROXY_DEFAULT, 15, 180, 210, 10, WS_GROUP | WS_TABSTOP + AUTORADIOBUTTON "Bez proxy servera", IDC_NO_PROXY, 15, 195, 210, 10 AUTORADIOBUTTON "Proxy", IDC_USE_PROXY, 15, 210, 74, 10 EDITTEXT IDC_PROXY_SERVER, 90, 210, 147, 12, ES_AUTOHSCROLL | WS_DISABLED - LTEXT "No proxy for", -1, 26, 226, 64, 10 + LTEXT "Žiadna proxy pre", -1, 26, 226, 64, 10 EDITTEXT IDC_NO_PROXY_FOR, 90, 225, 147, 12, ES_AUTOHSCROLL | WS_DISABLED PUSHBUTTON "Predvolené", IDC_DEFAULT_SETTINGS, 8, 245, 60, 14, WS_GROUP | WS_TABSTOP DEFPUSHBUTTON "OK", IDOK, 116, 245, 60, 14 @@ -100,10 +99,10 @@ BEGIN IDS_TOOLTIP_INSTALL "Inštalovať" IDS_TOOLTIP_UNINSTALL "Odinštalovať" IDS_TOOLTIP_MODIFY "Zmeniť" - IDS_TOOLTIP_SELECT_ALL "Select/Deselect All" + IDS_TOOLTIP_SELECT_ALL "Vybrať všetky/Zrušiť výber" IDS_TOOLTIP_SETTINGS "Nastavenia" IDS_TOOLTIP_REFRESH "Obnoviť" - IDS_TOOLTIP_UPDATE_DB "Update Database" + IDS_TOOLTIP_UPDATE_DB "Aktualizovať databázu" IDS_TOOLTIP_EXIT "Skončiť" END @@ -119,53 +118,53 @@ BEGIN IDS_INFO_VERSION "\nVerzia: " IDS_INFO_DESCRIPTION "\nPopis: " IDS_INFO_PUBLISHER "\nVydavateľ: " - IDS_INFO_HELPLINK "\nHelp Link: " - IDS_INFO_HELPPHONE "\nHelp Telephone: " - IDS_INFO_README "\nČítajMa: " + IDS_INFO_HELPLINK "\nInternetová pomoc: " + IDS_INFO_HELPPHONE "\nTelefonická pomoc: " + IDS_INFO_README "\nReadme: " IDS_INFO_REGOWNER "\nRegistrovaný vlastník: " IDS_INFO_PRODUCTID "\nID Produktu: " IDS_INFO_CONTACT "\nKontakt: " - IDS_INFO_UPDATEINFO "\nUpdate Information: " - IDS_INFO_INFOABOUT "\nInformation About: " - IDS_INFO_COMMENTS "\nComments: " - IDS_INFO_INSTLOCATION "\nInstall Location: " - IDS_INFO_INSTALLSRC "\nInstall Source: " - IDS_INFO_UNINSTALLSTR "\nUninstall String: " + IDS_INFO_UPDATEINFO "\nInformácie o aktualizáciach: " + IDS_INFO_INFOABOUT "\nInformácie o programe: " + IDS_INFO_COMMENTS "\nKomentáre: " + IDS_INFO_INSTLOCATION "\nUmiestnenie inštalácie: " + IDS_INFO_INSTALLSRC "\nZdroj inštalácie: " + IDS_INFO_UNINSTALLSTR "\nOdinstalačný reťazec: " IDS_INFO_MODIFYPATH "\nModify Path: " IDS_INFO_INSTALLDATE "\nDátum inštalácie: " - IDS_AINFO_PACKAGE_NAME "\nPackage Name: " + IDS_AINFO_PACKAGE_NAME "\nNázov balíčka: " END STRINGTABLE BEGIN IDS_AINFO_VERSION "\nVerzia: " - IDS_AINFO_AVAILABLEVERSION "\nAvailable Version: " + IDS_AINFO_AVAILABLEVERSION "\nDostupná verzia: " IDS_AINFO_DESCRIPTION "\nPopis: " IDS_AINFO_SIZE "\nVeľkosť: " IDS_AINFO_URLSITE "\nDomovská stránka: " IDS_AINFO_LICENSE "\nLicencia: " IDS_AINFO_URLDOWNLOAD "\nStiahnuť: " - IDS_AINFO_LANGUAGES "\nLanguages: " + IDS_AINFO_LANGUAGES "\nJazyky: " END STRINGTABLE BEGIN IDS_CAT_AUDIO "Audio" - IDS_CAT_DEVEL "Vývojárske" + IDS_CAT_DEVEL "Vývoj" IDS_CAT_DRIVERS "Ovládače" - IDS_CAT_EDU "Vzdelávacie" - IDS_CAT_ENGINEER "Inžinierske" - IDS_CAT_FINANCE "Finančné" + IDS_CAT_EDU "Vzdelávanie" + IDS_CAT_ENGINEER "Strojírenstvo" + IDS_CAT_FINANCE "Financie" IDS_CAT_GAMES "Hry & zábava" - IDS_CAT_GRAPHICS "Grafické" - IDS_CAT_INTERNET "Internet & sieť" + IDS_CAT_GRAPHICS "Grafika" + IDS_CAT_INTERNET "Internet a siete" IDS_CAT_LIBS "Knižnice" - IDS_CAT_OFFICE "Kancelárske" - IDS_CAT_OTHER "Iné" - IDS_CAT_SCIENCE "Vedecké" + IDS_CAT_OFFICE "Kancelária" + IDS_CAT_OTHER "Ostatné" + IDS_CAT_SCIENCE "Veda" IDS_CAT_TOOLS "Nástroje" IDS_CAT_VIDEO "Video" - IDS_CAT_THEMES "Themes" + IDS_CAT_THEMES "Vzhľad" END STRINGTABLE @@ -176,54 +175,58 @@ BEGIN IDS_WELCOME_TEXT "Vyberte si kategóriu na ľavej strane, potom vyberte aplikáciu, ktorú chcete nainštalovať alebo odinštalovať.\nWebstránka projektu ReactOS: " IDS_WELCOME_URL "https://reactos.org" - IDS_APPWIZ_TITLE "Add/Remove Programs" - IDS_APPWIZ_TEXT1 "Choose ""Applications"" or ""Updates"" to view the list of applications or updates installed on your system." - IDS_APPWIZ_TEXT2 "To remove a program or to modify its installed components, select it from the list and click on ""Uninstall"" or ""Modify""." + IDS_APPWIZ_TITLE "Pridať/Odobrať programy" + IDS_APPWIZ_TEXT1 "Vyberte ""Aplikácie"" alebo ""Aktualizácie"" pre zobrazenie zoznamu aplikácií alebo aktualizácií nainštalovaných vo vašom systéme." + IDS_APPWIZ_TEXT2 "Pre odobranie programu alebo pre zmenu jeho inštalovaných komponentov, ho vyberte zo zoznamu a kliknite na ""Odinštalovať"" alebo ""Upraviť""." END STRINGTABLE BEGIN IDS_SEARCH_TEXT "Hľadať…" IDS_APPS_COUNT "Počet programov: %d" - IDS_APPS_SELECT_COUNT "; Selected: %d" + IDS_APPS_SELECT_COUNT "; Vybrané: %d" IDS_INSTALLED "Nainštalované" IDS_AVAILABLEFORINST "Dostupné pre nainštalovanie" IDS_UPDATES "Aktualizácie" IDS_APPLICATIONS "Aplikácie" IDS_CHOOSE_FOLDER_TEXT "Vyberte priečinok, ktorý sa použije pre sťahovanie programov:" IDS_CHOOSE_FOLDER_ERROR "Zvolili ste si neexistujúci priečinok!" - IDS_URL_INVALID "The URL you have specified is invalid or not supported. Please correct it!" + IDS_URL_INVALID "Vami zadaná URL adresa nie je platná alebo nie je podporovaná. Prosím, opravte ju!" IDS_APP_REG_REMOVE "Naozaj chcete vymazať údaje o nainštalovanom programe z registrov?" IDS_INFORMATION "Informácie" - IDS_UNABLE_TO_DOWNLOAD "Unable to download the package! Address not found!" - IDS_UNABLE_TO_DOWNLOAD2 "Unable to download the package! Check Internet Connection!" + IDS_UNABLE_TO_DOWNLOAD "Súbor sa nepodarilo stiahnuť! Adresa nebola nájdená!" + IDS_UNABLE_TO_DOWNLOAD2 "Balíček sa nepodarilo stiahnuť! Skontrolujte pripojenie k Internetu" IDS_UNABLE_TO_REMOVE "Nie je možné odstrániť z registrov údaje o programe!" - IDS_UNABLE_TO_INSTALL "Unable to open installer!" - IDS_UNABLE_TO_QUERY_CERT "Unable to retrieve certificate info.\n\nDo you want to continue anyway?" - IDS_INTEG_CHECK_TITLE "Verifying package integrity…" - IDS_INTEG_CHECK_FAIL "The package did not pass the integrity check, it may have been corrupted or tampered with during downloading. Running the software is not recommended." - IDS_INTERRUPTED_DOWNLOAD "The download was interrupted. Check connection to Internet." - IDS_UNABLE_TO_WRITE "Unable to write to disk. Disk may be at capacity." - IDS_INSTALL_SELECTED "Install Selected" - IDS_SELECTEDFORINST "Selected for installation" - IDS_MISMATCH_CERT_INFO "The certificate used is unknown:\nSubject: %s\nIssuer: %s\nDo you want to continue anyway?" + IDS_UNABLE_TO_INSTALL "Nepodarilo sa otvoriť inštalátor!" + IDS_UNABLE_TO_QUERY_CERT "Nepodarilo sa získať informácie o certifikáte.\n\nChcete napriek tomu pokračovať?" + IDS_INTEG_CHECK_TITLE "Overujem integritu balíčka…" + IDS_INTEG_CHECK_FAIL "Balíček neprešiel kontrolou integrity, mohol byť poškodený alebo zmenený počas sťahovania. Spustenie tohto programu sa neodporúča." + IDS_INTERRUPTED_DOWNLOAD "Sťahovanie bolo prerušené. Skontrolujte pripojenie k Internetu." + IDS_UNABLE_TO_WRITE "Ukladanie na disk sa nepodarilo. Disk môže byť plný." + IDS_INSTALL_SELECTED "Nainštalovať vybrané" + IDS_SELECTEDFORINST "Vybrané pre inštaláciu" + IDS_MISMATCH_CERT_INFO "Neznámy certifikát:\nSubjekt: %s\nVydávateľ: %s\nChcete napriek tomu pokračovať?" IDS_UNABLE_PATH "Incorrect path format." - IDS_APP_DISPLAY_DETAILS "Details" - IDS_APP_DISPLAY_LIST "List" - IDS_APP_DISPLAY_TILE "Tile" - IDS_NO_SEARCH_RESULTS "No search results" + IDS_APP_DISPLAY_DETAILS "Podrobnosti" + IDS_APP_DISPLAY_LIST "Zoznam" + IDS_APP_DISPLAY_TILE "Dlaždice" + IDS_NO_SEARCH_RESULTS "Žiadne výsledky" + IDS_CFG_SAVE_WINDOW_POS "Uložiť pozíciu okna" + IDS_CFG_UPDATE_AVLIST "Aktualizovať zoznam dostupných programov pri spustení" + IDS_CFG_LOG_ENABLED "Záznam o inštalovaní a odstránení programov" + IDS_CFG_SMALL_ICONS "Malé ikony" END STRINGTABLE BEGIN - IDS_STATUS_INSTALLED "Installed" - IDS_STATUS_NOTINSTALLED "Not installed" - IDS_STATUS_DOWNLOADED "Downloaded" - IDS_STATUS_UPDATE_AVAILABLE "Update available" - IDS_STATUS_DOWNLOADING "Downloading…" - IDS_STATUS_INSTALLING "Installing…" - IDS_STATUS_WAITING "Waiting to install…" - IDS_STATUS_FINISHED "Finished" + IDS_STATUS_INSTALLED "Nainstalované" + IDS_STATUS_NOTINSTALLED "Nenainstalované" + IDS_STATUS_DOWNLOADED "Stiahnuté" + IDS_STATUS_UPDATE_AVAILABLE "Aktualizovateľné" + IDS_STATUS_DOWNLOADING "Sťahujem…" + IDS_STATUS_INSTALLING "Inštalujem…" + IDS_STATUS_WAITING "Čakám na inštaláciu…" + IDS_STATUS_FINISHED "Dokončené" END STRINGTABLE @@ -235,34 +238,35 @@ END STRINGTABLE BEGIN - IDS_LANGUAGE_AVAILABLE_TRANSLATION "Supports your language" - IDS_LANGUAGE_NO_TRANSLATION "Supports other languages" - IDS_LANGUAGE_ENGLISH_TRANSLATION "Supports English" - IDS_LANGUAGE_SINGLE "Single language" - IDS_LANGUAGE_MORE_PLACEHOLDER " (+%d more)" - IDS_LANGUAGE_AVAILABLE_PLACEHOLDER " (+%d available)" + IDS_LANGUAGE_AVAILABLE_TRANSLATION "Podporuje váš jazyk" + IDS_LANGUAGE_NO_TRANSLATION "Podporuje iné jazyky" + IDS_LANGUAGE_ENGLISH_TRANSLATION "Podporuje angličtinu" + IDS_LANGUAGE_SINGLE "Jediný jazyk" + IDS_LANGUAGE_MORE_PLACEHOLDER " (+%d ďalších)" + IDS_LANGUAGE_AVAILABLE_PLACEHOLDER " (+%d dostupných)" END STRINGTABLE BEGIN - IDS_DL_DIALOG_DB_DISP "Applications Database" - IDS_DL_DIALOG_DB_DOWNLOAD_DISP "Updating Database…" - IDS_DL_DIALOG_DB_UNOFFICIAL_DOWNLOAD_DISP "Updating Database… (Unofficial source)" + IDS_DL_DIALOG_DB_DISP "Databáza aplikácií" + IDS_DL_DIALOG_DB_DOWNLOAD_DISP "Aktualizujem databázu…" + IDS_DL_DIALOG_DB_UNOFFICIAL_DOWNLOAD_DISP "Aktualizujem databázu… (Neoficiálny zdroj)" END STRINGTABLE BEGIN - IDS_CMD_USAGE "Usage: " - IDS_CMD_NEED_PACKAGE_NAME "Error: option %1 expects one or more package name.\n" - IDS_CMD_NEED_FILE_NAME "Error: option %1 expects a file name.\n" - IDS_CMD_NEED_PARAMS "Error: option %1 expects one or more parameters.\n" - IDS_CMD_INVALID_OPTION "Error: Unknown or invalid command line option specified.\n" - IDS_CMD_FIND_RESULT_FOR "Find result for %1:\n" - IDS_CMD_PACKAGE_NOT_FOUND "Failed to find package %1.\n" - IDS_CMD_PACKAGE_INFO "Information about package %1:\n" + IDS_CMD_USAGE "Použitie: " + IDS_CMD_NEED_PACKAGE_NAME "Chyba: prepínač %1 očakáva jeden alebo viac názvov balíčkov.\n" + IDS_CMD_NEED_FILE_NAME "Chyba: prepínač %1 očakáva názov súboru.\n" + IDS_CMD_NEED_PARAMS "Chyba: prepínač %1 očakáva jeden alebo viac parametrov.\n" + IDS_CMD_INVALID_OPTION "Chyba: Neznámy alebo neplatný prepínač príkazového riadka.\n" + IDS_CMD_FIND_RESULT_FOR "Nájdi výsledok pre %1:\n" + IDS_CMD_PACKAGE_NOT_FOUND "Nepodarilo sa nájsť balíček %1.\n" + IDS_CMD_PACKAGE_INFO "Informácie o balíčku %1:\n" END STRINGTABLE BEGIN - IDS_INSTGEN_CONFIRMUNINST "Are you sure you want to uninstall %s?" + IDS_INSTGEN_CONFIRMUNINST "Ste si istí, že chcete odinštalovať %s?" + IDS_INSTGEN_CONFIRMINSTRUNAPP "Installation complete, run %s now?" END diff --git a/base/applications/rapps/lang/sq-AL.rc b/base/applications/rapps/lang/sq-AL.rc index 9d40291659b39..77feaa24eda66 100644 --- a/base/applications/rapps/lang/sq-AL.rc +++ b/base/applications/rapps/lang/sq-AL.rc @@ -49,9 +49,7 @@ CAPTION "Konfigurime" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Pergjithshem", -1, 4, 2, 240, 61 - AUTOCHECKBOX "Ruaj pozicionin e dritare", IDC_SAVE_WINDOW_POS, 15, 12, 219, 12 - AUTOCHECKBOX "&Updejto listen e programeve te aksesuar ne start", IDC_UPDATE_AVLIST, 15, 29, 222, 12 - AUTOCHECKBOX "&Log instalalimin dhe heqjen e programeve", IDC_LOG_ENABLED, 15, 46, 219, 12 + CONTROL "", IDC_GENERALLIST, "SysListView32", WS_TABSTOP | LVCHECKSTYLES, 15, 12, 219, 46, WS_EX_STATICEDGE GROUPBOX "Shkarko", -1, 4, 65, 240, 51 LTEXT "Dosja e shkarkimit:", -1, 16, 75, 100, 9 EDITTEXT IDC_DOWNLOAD_DIR_EDIT, 15, 86, 166, 12, WS_CHILD | WS_VISIBLE | WS_GROUP | ES_AUTOHSCROLL @@ -212,6 +210,10 @@ BEGIN IDS_APP_DISPLAY_LIST "List" IDS_APP_DISPLAY_TILE "Tile" IDS_NO_SEARCH_RESULTS "No search results" + IDS_CFG_SAVE_WINDOW_POS "Ruaj pozicionin e dritare" + IDS_CFG_UPDATE_AVLIST "Updejto listen e programeve te aksesuar ne start" + IDS_CFG_LOG_ENABLED "Log instalalimin dhe heqjen e programeve" + IDS_CFG_SMALL_ICONS "Ikonat e vogla" END STRINGTABLE @@ -265,4 +267,5 @@ END STRINGTABLE BEGIN IDS_INSTGEN_CONFIRMUNINST "Are you sure you want to uninstall %s?" + IDS_INSTGEN_CONFIRMINSTRUNAPP "Installation complete, run %s now?" END diff --git a/base/applications/rapps/lang/sv-SE.rc b/base/applications/rapps/lang/sv-SE.rc index 92e142cf9bcfa..c14b19adb5149 100644 --- a/base/applications/rapps/lang/sv-SE.rc +++ b/base/applications/rapps/lang/sv-SE.rc @@ -49,9 +49,7 @@ CAPTION "Inställningar" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Allmänna", -1, 4, 2, 240, 61 - AUTOCHECKBOX "&Spara fönsterposition", IDC_SAVE_WINDOW_POS, 15, 12, 219, 12 - AUTOCHECKBOX "&Uppdatera listan med tillgängliga program vid start", IDC_UPDATE_AVLIST, 15, 29, 222, 12 - AUTOCHECKBOX "&Logga ur installation och borttagning program", IDC_LOG_ENABLED, 15, 46, 219, 12 + CONTROL "", IDC_GENERALLIST, "SysListView32", WS_TABSTOP | LVCHECKSTYLES, 15, 12, 219, 46, WS_EX_STATICEDGE GROUPBOX "Nerladding", -1, 4, 65, 240, 51 LTEXT "Mapp för nerladdningar:", -1, 16, 75, 100, 9 EDITTEXT IDC_DOWNLOAD_DIR_EDIT, 15, 86, 166, 12, WS_CHILD | WS_VISIBLE | WS_GROUP | ES_AUTOHSCROLL @@ -212,6 +210,10 @@ BEGIN IDS_APP_DISPLAY_LIST "List" IDS_APP_DISPLAY_TILE "Tile" IDS_NO_SEARCH_RESULTS "No search results" + IDS_CFG_SAVE_WINDOW_POS "Spara fönsterposition" + IDS_CFG_UPDATE_AVLIST "Uppdatera listan med tillgängliga program vid start" + IDS_CFG_LOG_ENABLED "Logga ur installation och borttagning program" + IDS_CFG_SMALL_ICONS "Små ikoner" END STRINGTABLE @@ -265,4 +267,5 @@ END STRINGTABLE BEGIN IDS_INSTGEN_CONFIRMUNINST "Are you sure you want to uninstall %s?" + IDS_INSTGEN_CONFIRMINSTRUNAPP "Installation complete, run %s now?" END diff --git a/base/applications/rapps/lang/tr-TR.rc b/base/applications/rapps/lang/tr-TR.rc index e6fbdc062b2cf..c33ab128536ff 100644 --- a/base/applications/rapps/lang/tr-TR.rc +++ b/base/applications/rapps/lang/tr-TR.rc @@ -51,9 +51,7 @@ CAPTION "Ayarlar" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Genel", -1, 4, 2, 240, 61 - AUTOCHECKBOX "&Pencere Konumunu Kaydet", IDC_SAVE_WINDOW_POS, 15, 12, 219, 12 - AUTOCHECKBOX "&Başlangıçta Erişilebilir Programların Listesini Yenile", IDC_UPDATE_AVLIST, 15, 29, 222, 12 - AUTOCHECKBOX "P&rogramların Kurulma ve Kaldırma Günlüğünü Sakla", IDC_LOG_ENABLED, 15, 46, 219, 12 + CONTROL "", IDC_GENERALLIST, "SysListView32", WS_TABSTOP | LVCHECKSTYLES, 15, 12, 219, 46, WS_EX_STATICEDGE GROUPBOX "İndirme", -1, 4, 65, 240, 51 LTEXT "İndirme Dizini:", -1, 16, 75, 100, 9 EDITTEXT IDC_DOWNLOAD_DIR_EDIT, 15, 86, 166, 12, WS_CHILD | WS_VISIBLE | WS_GROUP | ES_AUTOHSCROLL @@ -178,9 +176,9 @@ BEGIN IDS_WELCOME_TEXT "Solda bir kategori seçiniz, ardından kurmak ya da kaldırmak için bir uygulama seçiniz.\nReactOS'un İnternet sitesi: " IDS_WELCOME_URL "https://reactos.org" - IDS_APPWIZ_TITLE "Add/Remove Programs" - IDS_APPWIZ_TEXT1 "Choose ""Applications"" or ""Updates"" to view the list of applications or updates installed on your system." - IDS_APPWIZ_TEXT2 "To remove a program or to modify its installed components, select it from the list and click on ""Uninstall"" or ""Modify""." + IDS_APPWIZ_TITLE "Program Ekle/Kaldır" + IDS_APPWIZ_TEXT1 "Sisteminizde yüklü olan uygulamaların veya güncellemelerin listesini görüntülemek için ""Uygulamalar"" veya ""Güncellemeler"" öğesini seçin." + IDS_APPWIZ_TEXT2 "Bir programı kaldırmak veya yüklü bileşenlerini değiştirmek için listeden seçin ve ""Kaldır"" veya ""Değiştir"" üzerine tıklayın." END STRINGTABLE @@ -213,7 +211,11 @@ BEGIN IDS_APP_DISPLAY_DETAILS "Detaylar" IDS_APP_DISPLAY_LIST "Liste" IDS_APP_DISPLAY_TILE "Karo" - IDS_NO_SEARCH_RESULTS "No search results" + IDS_NO_SEARCH_RESULTS "Arama sonucu yok" + IDS_CFG_SAVE_WINDOW_POS "Pencere Konumunu Kaydet" + IDS_CFG_UPDATE_AVLIST "Başlangıçta Erişilebilir Programların Listesini Yenile" + IDS_CFG_LOG_ENABLED "Programların Kurulma ve Kaldırma Günlüğünü Sakla" + IDS_CFG_SMALL_ICONS "Küçük simgeler" END STRINGTABLE @@ -266,5 +268,6 @@ END STRINGTABLE BEGIN - IDS_INSTGEN_CONFIRMUNINST "Are you sure you want to uninstall %s?" + IDS_INSTGEN_CONFIRMUNINST "Kaldırmak istediğinizden emin misiniz %s?" + IDS_INSTGEN_CONFIRMINSTRUNAPP "Installation complete, run %s now?" END diff --git a/base/applications/rapps/lang/uk-UA.rc b/base/applications/rapps/lang/uk-UA.rc index 9836138bcca25..35cb17f24f2da 100644 --- a/base/applications/rapps/lang/uk-UA.rc +++ b/base/applications/rapps/lang/uk-UA.rc @@ -52,9 +52,7 @@ CAPTION "Налаштування" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Загальні", -1, 4, 2, 240, 61 - AUTOCHECKBOX "&Зберігати положення вікна", IDC_SAVE_WINDOW_POS, 15, 12, 219, 12 - AUTOCHECKBOX "&Оновлювати список наявних програм при запуску", IDC_UPDATE_AVLIST, 15, 29, 222, 12 - AUTOCHECKBOX "&Вести звіт встановлення/видалення програм", IDC_LOG_ENABLED, 15, 46, 219, 12 + CONTROL "", IDC_GENERALLIST, "SysListView32", WS_TABSTOP | LVCHECKSTYLES, 15, 12, 219, 46, WS_EX_STATICEDGE GROUPBOX "Завантаження", -1, 4, 65, 240, 51 LTEXT "Тека для завантажень:", -1, 16, 75, 100, 9 EDITTEXT IDC_DOWNLOAD_DIR_EDIT, 15, 86, 166, 12, WS_CHILD | WS_VISIBLE | WS_GROUP | ES_AUTOHSCROLL @@ -215,6 +213,10 @@ BEGIN IDS_APP_DISPLAY_LIST "List" IDS_APP_DISPLAY_TILE "Tile" IDS_NO_SEARCH_RESULTS "No search results" + IDS_CFG_SAVE_WINDOW_POS "Зберігати положення вікна" + IDS_CFG_UPDATE_AVLIST "Оновлювати список наявних програм при запуску" + IDS_CFG_LOG_ENABLED "Вести звіт встановлення/видалення програм" + IDS_CFG_SMALL_ICONS "Дрібні значки" END STRINGTABLE @@ -268,4 +270,5 @@ END STRINGTABLE BEGIN IDS_INSTGEN_CONFIRMUNINST "Are you sure you want to uninstall %s?" + IDS_INSTGEN_CONFIRMINSTRUNAPP "Installation complete, run %s now?" END diff --git a/base/applications/rapps/lang/zh-CN.rc b/base/applications/rapps/lang/zh-CN.rc index b2ba23b085379..7eed7260cbffc 100644 --- a/base/applications/rapps/lang/zh-CN.rc +++ b/base/applications/rapps/lang/zh-CN.rc @@ -53,9 +53,7 @@ CAPTION "设置" FONT 9, "宋体" BEGIN GROUPBOX "常规", -1, 4, 2, 240, 61 - AUTOCHECKBOX "保存窗口位置(&S)", IDC_SAVE_WINDOW_POS, 15, 12, 219, 12 - AUTOCHECKBOX "启动时更新可获得的程序列表(&U)", IDC_UPDATE_AVLIST, 15, 29, 222, 12 - AUTOCHECKBOX "将程序的安装和卸载记录到日志(&L)", IDC_LOG_ENABLED, 15, 46, 219, 12 + CONTROL "", IDC_GENERALLIST, "SysListView32", WS_TABSTOP | LVCHECKSTYLES, 15, 12, 219, 46, WS_EX_STATICEDGE GROUPBOX "下载设置", -1, 4, 65, 240, 51 LTEXT "下载文件夹:", -1, 16, 75, 100, 9 EDITTEXT IDC_DOWNLOAD_DIR_EDIT, 15, 86, 166, 12, WS_CHILD | WS_VISIBLE | WS_GROUP | ES_AUTOHSCROLL @@ -216,6 +214,10 @@ BEGIN IDS_APP_DISPLAY_LIST "列表" IDS_APP_DISPLAY_TILE "卡片" IDS_NO_SEARCH_RESULTS "无搜索结果" + IDS_CFG_SAVE_WINDOW_POS "保存窗口位置" + IDS_CFG_UPDATE_AVLIST "启动时更新可获得的程序列表" + IDS_CFG_LOG_ENABLED "将程序的安装和卸载记录到日志" + IDS_CFG_SMALL_ICONS "小图标" END STRINGTABLE @@ -269,4 +271,5 @@ END STRINGTABLE BEGIN IDS_INSTGEN_CONFIRMUNINST "Are you sure you want to uninstall %s?" + IDS_INSTGEN_CONFIRMINSTRUNAPP "Installation complete, run %s now?" END diff --git a/base/applications/rapps/lang/zh-HK.rc b/base/applications/rapps/lang/zh-HK.rc index a1959f2d6054b..2340b0963c65f 100644 --- a/base/applications/rapps/lang/zh-HK.rc +++ b/base/applications/rapps/lang/zh-HK.rc @@ -50,9 +50,7 @@ CAPTION "設定" FONT 9, "新細明體" BEGIN GROUPBOX "一般", -1, 4, 2, 240, 61 - AUTOCHECKBOX "儲存視窗位置(&S)", IDC_SAVE_WINDOW_POS, 15, 12, 219, 12 - AUTOCHECKBOX "啟動時更新可獲得的程式列表(&U)", IDC_UPDATE_AVLIST, 15, 29, 222, 12 - AUTOCHECKBOX "將程式的安裝和解除安裝記錄到記錄檔(&L)", IDC_LOG_ENABLED, 15, 46, 219, 12 + CONTROL "", IDC_GENERALLIST, "SysListView32", WS_TABSTOP | LVCHECKSTYLES, 15, 12, 219, 46, WS_EX_STATICEDGE GROUPBOX "正在下載", -1, 4, 65, 240, 51 LTEXT "下載資料夾:", -1, 16, 75, 100, 9 EDITTEXT IDC_DOWNLOAD_DIR_EDIT, 15, 86, 166, 12, WS_CHILD | WS_VISIBLE | WS_GROUP | ES_AUTOHSCROLL @@ -213,6 +211,10 @@ BEGIN IDS_APP_DISPLAY_LIST "列表" IDS_APP_DISPLAY_TILE "並排" IDS_NO_SEARCH_RESULTS "沒有搜尋結果" + IDS_CFG_SAVE_WINDOW_POS "儲存視窗位置" + IDS_CFG_UPDATE_AVLIST "啟動時更新可獲得的程式列表" + IDS_CFG_LOG_ENABLED "將程式的安裝和解除安裝記錄到記錄檔" + IDS_CFG_SMALL_ICONS "小圖示" END STRINGTABLE @@ -266,4 +268,5 @@ END STRINGTABLE BEGIN IDS_INSTGEN_CONFIRMUNINST "Are you sure you want to uninstall %s?" + IDS_INSTGEN_CONFIRMINSTRUNAPP "Installation complete, run %s now?" END diff --git a/base/applications/rapps/lang/zh-TW.rc b/base/applications/rapps/lang/zh-TW.rc index 2c8badd29152d..a3befd8880da3 100644 --- a/base/applications/rapps/lang/zh-TW.rc +++ b/base/applications/rapps/lang/zh-TW.rc @@ -50,9 +50,7 @@ CAPTION "設定" FONT 9, "新細明體" BEGIN GROUPBOX "一般", -1, 4, 2, 240, 61 - AUTOCHECKBOX "儲存視窗位置(&S)", IDC_SAVE_WINDOW_POS, 15, 12, 219, 12 - AUTOCHECKBOX "啟動時更新可獲得的程式列表(&U)", IDC_UPDATE_AVLIST, 15, 29, 222, 12 - AUTOCHECKBOX "記錄程式的安裝和解除安裝過程(&L)", IDC_LOG_ENABLED, 15, 46, 219, 12 + CONTROL "", IDC_GENERALLIST, "SysListView32", WS_TABSTOP | LVCHECKSTYLES, 15, 12, 219, 46, WS_EX_STATICEDGE GROUPBOX "正在下載", -1, 4, 65, 240, 51 LTEXT "下載資料夾:", -1, 16, 75, 100, 9 EDITTEXT IDC_DOWNLOAD_DIR_EDIT, 15, 86, 166, 12, WS_CHILD | WS_VISIBLE | WS_GROUP | ES_AUTOHSCROLL @@ -213,6 +211,10 @@ BEGIN IDS_APP_DISPLAY_LIST "列表" IDS_APP_DISPLAY_TILE "並排" IDS_NO_SEARCH_RESULTS "沒有搜尋結果" + IDS_CFG_SAVE_WINDOW_POS "儲存視窗位置" + IDS_CFG_UPDATE_AVLIST "啟動時更新可獲得的程式列表" + IDS_CFG_LOG_ENABLED "記錄程式的安裝和解除安裝過程" + IDS_CFG_SMALL_ICONS "小圖示" END STRINGTABLE @@ -266,4 +268,5 @@ END STRINGTABLE BEGIN IDS_INSTGEN_CONFIRMUNINST "Are you sure you want to uninstall %s?" + IDS_INSTGEN_CONFIRMINSTRUNAPP "Installation complete, run %s now?" END diff --git a/base/applications/rapps/loaddlg.cpp b/base/applications/rapps/loaddlg.cpp index 7e926c3399f45..8d51fe78f8cc6 100644 --- a/base/applications/rapps/loaddlg.cpp +++ b/base/applications/rapps/loaddlg.cpp @@ -52,10 +52,23 @@ #include "unattended.h" #ifdef USE_CERT_PINNING +#define CERT_ISSUER_INFO_PREFIX "US\r\nLet's Encrypt\r\nR" #define CERT_ISSUER_INFO_OLD "US\r\nLet's Encrypt\r\nR3" #define CERT_ISSUER_INFO_NEW "US\r\nLet's Encrypt\r\nR11" #define CERT_SUBJECT_INFO "rapps.reactos.org" + +static bool +IsTrustedPinnedCert(LPCSTR Subject, LPCSTR Issuer) +{ + if (strcmp(Subject, CERT_SUBJECT_INFO)) + return false; +#ifdef CERT_ISSUER_INFO_PREFIX + return Issuer == StrStrA(Issuer, CERT_ISSUER_INFO_PREFIX); +#else + return !strcmp(Issuer, CERT_ISSUER_INFO_OLD) || !strcmp(Issuer, CERT_ISSUER_INFO_NEW); #endif +} +#endif // USE_CERT_PINNING enum DownloadType { @@ -106,6 +119,19 @@ UrlUnescapeAndMakeFileNameValid(CStringW& str) str = szPath; } +static void +SetFriendlyUrl(HWND hWnd, LPCWSTR pszUrl) +{ + CStringW buf; + DWORD cch = (DWORD)(wcslen(pszUrl) + 1); + if (InternetCanonicalizeUrlW(pszUrl, buf.GetBuffer(cch), &cch, ICU_DECODE | ICU_NO_ENCODE)) + { + buf.ReleaseBuffer(); + pszUrl = buf; + } + SetWindowTextW(hWnd, pszUrl); +} + struct DownloadInfo { DownloadInfo() : DLType(DLTYPE_APPLICATION), IType(INSTALLER_UNKNOWN), SizeInBytes(0) @@ -116,10 +142,16 @@ struct DownloadInfo AppInfo.GetDownloadInfo(szUrl, szSHA1, SizeInBytes); szName = AppInfo.szDisplayName; IType = AppInfo.GetInstallerType(); - if (IType == INSTALLER_GENERATE) - { - szPackageName = AppInfo.szIdentifier; - } + szPackageName = AppInfo.szIdentifier; + + CConfigParser *cfg = static_cast(AppInfo).GetConfigParser(); + if (cfg) + cfg->GetString(DB_SAVEAS, szFileName); + } + + bool Equal(const DownloadInfo &other) const + { + return DLType == other.DLType && !lstrcmpW(szUrl, other.szUrl); } DownloadType DLType; @@ -128,24 +160,10 @@ struct DownloadInfo CStringW szName; CStringW szSHA1; CStringW szPackageName; + CStringW szFileName; ULONG SizeInBytes; }; -struct DownloadParam -{ - DownloadParam() : Dialog(NULL), AppInfo(), szCaption(NULL) - { - } - DownloadParam(HWND dlg, const ATL::CSimpleArray &info, LPCWSTR caption) - : Dialog(dlg), AppInfo(info), szCaption(caption) - { - } - - HWND Dialog; - ATL::CSimpleArray AppInfo; - LPCWSTR szCaption; -}; - class CDownloaderProgress : public CWindowImpl { CStringW m_szProgressText; @@ -300,7 +318,7 @@ class CDowloadingAppsListView : public CListView RECT r; ::GetClientRect(hwndParent, &r); r.top = (2 * r.top + 1 * r.bottom) / 3; /* The vertical position at ratio 1 : 2 */ -#define MARGIN 10 + const INT MARGIN = 10; ::InflateRect(&r, -MARGIN, -MARGIN); const DWORD style = WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | @@ -315,11 +333,12 @@ class CDowloadingAppsListView : public CListView } VOID - LoadList(ATL::CSimpleArray arrInfo) + LoadList(ATL::CSimpleArray arrInfo, UINT Start = 0) { - for (INT i = 0; i < arrInfo.GetSize(); ++i) + const INT base = GetItemCount(); + for (INT i = Start; i < arrInfo.GetSize(); ++i) { - AddRow(i, arrInfo[i].szName.GetString(), DLSTATUS_WAITING); + AddRow(base + i - Start, arrInfo[i].szName, DLSTATUS_WAITING); } } @@ -407,7 +426,7 @@ CertGetSubjectAndIssuer(HINTERNET hFile, CLocalPtr &subjectInfo, CLocalPtr } #endif -inline VOID +static inline VOID MessageBox_LoadString(HWND hOwnerWnd, INT StringID) { CStringW szMsgText; @@ -417,65 +436,177 @@ MessageBox_LoadString(HWND hOwnerWnd, INT StringID) } } +static BOOL +ShowLastError(HWND hWndOwner, BOOL bInetError, DWORD dwLastError) +{ + CLocalPtr lpMsg; + + if (!FormatMessageW( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | + (bInetError ? FORMAT_MESSAGE_FROM_HMODULE : FORMAT_MESSAGE_FROM_SYSTEM), + (bInetError ? GetModuleHandleW(L"wininet.dll") : NULL), dwLastError, LANG_USER_DEFAULT, (LPWSTR)&lpMsg, 0, + NULL)) + { + DPRINT1("FormatMessageW unexpected failure (err %d)\n", GetLastError()); + return FALSE; + } + + if (hWndOwner && !IsWindowVisible(hWndOwner)) + hWndOwner = NULL; + MessageBoxW(hWndOwner, lpMsg, NULL, MB_OK | MB_ICONERROR); + return TRUE; +} + // Download dialog (loaddlg.cpp) -class CDownloadManager +HWND g_hDownloadWnd = NULL; + +class CDownloadManager : + public CComCoClass, + public CComObjectRootEx, + public IUnknown { - static ATL::CSimpleArray AppsDownloadList; - static CDowloadingAppsListView DownloadsListView; - static CDownloaderProgress ProgressBar; - static BOOL bCancelled; - static BOOL bModal; - static VOID - UpdateProgress(HWND hDlg, ULONG ulProgress, ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText); +public: + enum { + WM_ISCANCELLED = WM_APP, // Return BOOL + WM_SETSTATUS, // wParam DownloadStatus + WM_GETINSTANCE, // Return CDownloadManager* + WM_GETNEXT, // Return DownloadInfo* or NULL + }; + + CDownloadManager() : m_hDlg(NULL), m_Threads(0), m_Index(0), m_bCancelled(FALSE) {} + + static CDownloadManager* + CreateInstanceHelper(BOOL Modal) + { + if (!Modal) + { + CDownloadManager* pExisting = CDownloadManager::FindInstance(); + if (pExisting) + { + pExisting->AddRef(); + return pExisting; + } + } + CComPtr obj; + if (FAILED(ShellObjectCreator(obj))) + return NULL; + obj->m_bModal = Modal; + return obj.Detach(); + } - public: - static VOID - Add(DownloadInfo info); - static VOID - Download(const DownloadInfo &DLInfo, BOOL bIsModal = FALSE); - static INT_PTR CALLBACK - DownloadDlgProc(HWND Dlg, UINT uMsg, WPARAM wParam, LPARAM lParam); - static unsigned int WINAPI - ThreadFunc(LPVOID Context); - static VOID LaunchDownloadDialog(BOOL); + static BOOL + CreateInstance(BOOL Modal, CComPtr &Obj) + { + CDownloadManager *p = CreateInstanceHelper(Modal); + if (!p) + return FALSE; + Obj.Attach(p); + return TRUE; + } + + static CDownloadManager* + FindInstance() + { + if (g_hDownloadWnd) + return (CDownloadManager*)SendMessageW(g_hDownloadWnd, WM_GETINSTANCE, 0, 0); + return NULL; + } + + BOOL + IsCancelled() + { + return !IsWindow(m_hDlg) || SendMessageW(m_hDlg, WM_ISCANCELLED, 0, 0); + } + + void StartWorkerThread(); + void Add(const DownloadInfo &Info); + void Show(); + static INT_PTR CALLBACK DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); + INT_PTR RealDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); + void UpdateProgress(ULONG ulProgress, ULONG ulProgressMax); + static unsigned int CALLBACK ThreadFunc(void*ThreadParam); + void PerformDownloadAndInstall(const DownloadInfo &Info); + + DECLARE_NO_REGISTRY() + DECLARE_NOT_AGGREGATABLE(CDownloadManager) + BEGIN_COM_MAP(CDownloadManager) + END_COM_MAP() + +protected: + HWND m_hDlg; + UINT m_Threads; + UINT m_Index; + BOOL m_bCancelled; + BOOL m_bModal; + WCHAR m_szCaptionFmt[100]; + ATL::CSimpleArray m_List; + CDowloadingAppsListView m_ListView; + CDownloaderProgress m_ProgressBar; }; -// CDownloadManager -ATL::CSimpleArray CDownloadManager::AppsDownloadList; -CDowloadingAppsListView CDownloadManager::DownloadsListView; -CDownloaderProgress CDownloadManager::ProgressBar; -BOOL CDownloadManager::bCancelled = FALSE; -BOOL CDownloadManager::bModal = FALSE; +void +CDownloadManager::StartWorkerThread() +{ + AddRef(); // To keep m_List alive in thread + unsigned int ThreadId; + HANDLE Thread = (HANDLE)_beginthreadex(NULL, 0, ThreadFunc, this, 0, &ThreadId); + if (Thread) + CloseHandle(Thread); + else + Release(); +} -VOID -CDownloadManager::Add(DownloadInfo info) +void +CDownloadManager::Add(const DownloadInfo &Info) { - AppsDownloadList.Add(info); + const UINT count = m_List.GetSize(), start = count; + for (UINT i = 0; i < count; ++i) + { + if (Info.Equal(m_List[i])) + return; // Already in the list + } + m_List.Add(Info); + if (m_hDlg) + m_ListView.LoadList(m_List, start); } -VOID -CDownloadManager::Download(const DownloadInfo &DLInfo, BOOL bIsModal) +void +CDownloadManager::Show() { - AppsDownloadList.RemoveAll(); - AppsDownloadList.Add(DLInfo); - LaunchDownloadDialog(bIsModal); + if (m_bModal) + DialogBoxParamW(hInst, MAKEINTRESOURCEW(IDD_DOWNLOAD_DIALOG), hMainWnd, DlgProc, (LPARAM)this); + else if (!m_hDlg || !IsWindow(m_hDlg)) + CreateDialogParamW(hInst, MAKEINTRESOURCEW(IDD_DOWNLOAD_DIALOG), hMainWnd, DlgProc, (LPARAM)this); } INT_PTR CALLBACK -CDownloadManager::DownloadDlgProc(HWND Dlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +CDownloadManager::DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { - static WCHAR szCaption[MAX_PATH]; + CDownloadManager* pThis = (CDownloadManager*)GetWindowLongPtrW(hDlg, DWLP_USER); + if (!pThis) + { + if (uMsg != WM_INITDIALOG) + return FALSE; + SetWindowLongPtrW(hDlg, DWLP_USER, lParam); + pThis = (CDownloadManager*)lParam; + } + return pThis->RealDlgProc(hDlg, uMsg, wParam, lParam); +} +INT_PTR +CDownloadManager::RealDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ switch (uMsg) { case WM_INITDIALOG: { g_Busy++; - HICON hIconSm, hIconBg; - CStringW szTempCaption; - - bCancelled = FALSE; + AddRef(); + m_hDlg = hDlg; + if (!m_bModal) + g_hDownloadWnd = hDlg; + HICON hIconSm, hIconBg; if (hMainWnd) { hIconBg = (HICON)GetClassLongPtrW(hMainWnd, GCLP_HICON); @@ -483,670 +614,564 @@ CDownloadManager::DownloadDlgProc(HWND Dlg, UINT uMsg, WPARAM wParam, LPARAM lPa } if (!hMainWnd || (!hIconBg || !hIconSm)) { - /* Load the default icon */ hIconBg = hIconSm = LoadIconW(hInst, MAKEINTRESOURCEW(IDI_MAIN)); } + SendMessageW(hDlg, WM_SETICON, ICON_BIG, (LPARAM)hIconBg); + SendMessageW(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)hIconSm); - if (hIconBg && hIconSm) - { - SendMessageW(Dlg, WM_SETICON, ICON_BIG, (LPARAM)hIconBg); - SendMessageW(Dlg, WM_SETICON, ICON_SMALL, (LPARAM)hIconSm); - } + GetWindowTextW(hDlg, m_szCaptionFmt, _countof(m_szCaptionFmt)); + CStringW buf; + buf = m_szCaptionFmt; + buf.Replace(L"%ls", L""); + SetWindowTextW(hDlg, buf); // "Downloading..." - HWND Item = GetDlgItem(Dlg, IDC_DOWNLOAD_PROGRESS); - if (Item) + HWND hItem = GetDlgItem(hDlg, IDC_DOWNLOAD_PROGRESS); + if (hItem) { // initialize the default values for our nifty progress bar // and subclass it so that it learns to print a status text - ProgressBar.SubclassWindow(Item); - ProgressBar.SendMessage(PBM_SETRANGE, 0, MAKELPARAM(0, 100)); - ProgressBar.SendMessage(PBM_SETPOS, 0, 0); - if (AppsDownloadList.GetSize() > 0) - ProgressBar.SetProgress(0, AppsDownloadList[0].SizeInBytes); + m_ProgressBar.SubclassWindow(hItem); + m_ProgressBar.SendMessageW(PBM_SETRANGE, 0, MAKELPARAM(0, 100)); + m_ProgressBar.SendMessageW(PBM_SETPOS, 0, 0); + if (m_List.GetSize() > 0) + m_ProgressBar.SetProgress(0, m_List[0].SizeInBytes); } - // Add a ListView - HWND hListView = DownloadsListView.Create(Dlg); - if (!hListView) - { + if (!m_ListView.Create(hDlg)) return FALSE; - } - DownloadsListView.LoadList(AppsDownloadList); + m_ListView.LoadList(m_List); - // Get a dlg string for later use - GetWindowTextW(Dlg, szCaption, _countof(szCaption)); - - // Hide a placeholder from displaying - szTempCaption = szCaption; - szTempCaption.Replace(L"%ls", L""); - SetWindowText(Dlg, szTempCaption.GetString()); - - ShowWindow(Dlg, SW_SHOW); - - // Start download process - DownloadParam *param = new DownloadParam(Dlg, AppsDownloadList, szCaption); - unsigned int ThreadId; - HANDLE Thread = (HANDLE)_beginthreadex(NULL, 0, ThreadFunc, (void *)param, 0, &ThreadId); - if (!Thread) - { - return FALSE; - } - - CloseHandle(Thread); - AppsDownloadList.RemoveAll(); + ShowWindow(hDlg, SW_SHOW); + StartWorkerThread(); return TRUE; } case WM_COMMAND: - if (wParam == IDCANCEL) + if (LOWORD(wParam) == IDCANCEL) { - bCancelled = TRUE; - PostMessageW(Dlg, WM_CLOSE, 0, 0); + m_bCancelled = TRUE; + PostMessageW(hDlg, WM_CLOSE, 0, 0); } return FALSE; case WM_CLOSE: - if (ProgressBar) - ProgressBar.UnsubclassWindow(TRUE); - if (CDownloadManager::bModal) - { - ::EndDialog(Dlg, 0); - } - else - { - ::DestroyWindow(Dlg); - } - return TRUE; + m_bCancelled = TRUE; + if (m_ProgressBar) + m_ProgressBar.UnsubclassWindow(TRUE); + return m_bModal ? ::EndDialog(hDlg, 0) : ::DestroyWindow(hDlg); case WM_DESTROY: + if (g_hDownloadWnd == hDlg) + g_hDownloadWnd = NULL; g_Busy--; if (hMainWnd) PostMessage(hMainWnd, WM_NOTIFY_OPERATIONCOMPLETED, 0, 0); - return FALSE; - - default: - return FALSE; - } -} + Release(); + break; -BOOL UrlHasBeenCopied; + case WM_ISCANCELLED: + return SetDlgMsgResult(hDlg, uMsg, m_bCancelled); -VOID -CDownloadManager::UpdateProgress( - HWND hDlg, - ULONG ulProgress, - ULONG ulProgressMax, - ULONG ulStatusCode, - LPCWSTR szStatusText) -{ - HWND Item; - - if (!IsWindow(hDlg)) - return; - ProgressBar.SetProgress(ulProgress, ulProgressMax); + case WM_SETSTATUS: + m_ListView.SetDownloadStatus(m_Index - 1, (DownloadStatus)wParam); + break; - if (!IsWindow(hDlg)) - return; - Item = GetDlgItem(hDlg, IDC_DOWNLOAD_STATUS); - if (Item && szStatusText && wcslen(szStatusText) > 0 && UrlHasBeenCopied == FALSE) - { - SIZE_T len = wcslen(szStatusText) + 1; - CStringW buf; - DWORD dummyLen; + case WM_GETINSTANCE: + return SetDlgMsgResult(hDlg, uMsg, (INT_PTR)this); - /* beautify our url for display purposes */ - if (!InternetCanonicalizeUrlW(szStatusText, buf.GetBuffer(len), &dummyLen, ICU_DECODE | ICU_NO_ENCODE)) + case WM_GETNEXT: { - /* just use the original */ - buf.ReleaseBuffer(); - buf = szStatusText; + DownloadInfo *pItem = NULL; + if (!m_bCancelled && m_Index < (SIZE_T)m_List.GetSize()) + pItem = &m_List[m_Index++]; + return SetDlgMsgResult(hDlg, uMsg, (INT_PTR)pItem); } - else - { - buf.ReleaseBuffer(); - } - - /* paste it into our dialog and don't do it again in this instance */ - ::SetWindowText(Item, buf.GetString()); - UrlHasBeenCopied = TRUE; } + return FALSE; } -BOOL -ShowLastError(HWND hWndOwner, BOOL bInetError, DWORD dwLastError) +void +CDownloadManager::UpdateProgress(ULONG ulProgress, ULONG ulProgressMax) { - CLocalPtr lpMsg; + m_ProgressBar.SetProgress(ulProgress, ulProgressMax); +} - if (!FormatMessageW( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | - (bInetError ? FORMAT_MESSAGE_FROM_HMODULE : FORMAT_MESSAGE_FROM_SYSTEM), - (bInetError ? GetModuleHandleW(L"wininet.dll") : NULL), dwLastError, LANG_USER_DEFAULT, (LPWSTR)&lpMsg, 0, - NULL)) +unsigned int CALLBACK +CDownloadManager::ThreadFunc(void* ThreadParam) +{ + CDownloadManager *pThis = (CDownloadManager*)ThreadParam; + HWND hDlg = pThis->m_hDlg; + for (;;) { - DPRINT1("FormatMessageW unexpected failure (err %d)\n", GetLastError()); - return FALSE; + DownloadInfo *pItem = (DownloadInfo*)SendMessageW(hDlg, WM_GETNEXT, 0, 0); + if (!pItem) + break; + pThis->PerformDownloadAndInstall(*pItem); } - - MessageBoxW(hWndOwner, lpMsg, NULL, MB_OK | MB_ICONERROR); - return TRUE; + SendMessageW(hDlg, WM_CLOSE, 0, 0); + return pThis->Release(); } -unsigned int WINAPI -CDownloadManager::ThreadFunc(LPVOID param) +void +CDownloadManager::PerformDownloadAndInstall(const DownloadInfo &Info) { - CPathW Path; - PCWSTR p, q; + const HWND hDlg = m_hDlg; + const HWND hStatus = GetDlgItem(m_hDlg, IDC_DOWNLOAD_STATUS); + SetFriendlyUrl(hStatus, Info.szUrl); - HWND hDlg = static_cast(param)->Dialog; - HWND Item; - INT iAppId; + m_ProgressBar.SetMarquee(FALSE); + m_ProgressBar.SendMessageW(PBM_SETPOS, 0, 0); + m_ProgressBar.SetProgress(0, Info.SizeInBytes); - ULONG dwContentLen, dwBytesWritten, dwBytesRead, dwStatus; - ULONG dwCurrentBytesRead = 0; - ULONG dwStatusLen = sizeof(dwStatus); + CStringW str; + CPathW Path; + PCWSTR p; - BOOL bTempfile = FALSE; + ULONG dwContentLen, dwBytesWritten, dwBytesRead, dwStatus, dwStatusLen; + ULONG dwCurrentBytesRead = 0; + BOOL bTempfile = FALSE, bCancelled = FALSE; HINTERNET hOpen = NULL; HINTERNET hFile = NULL; HANDLE hOut = INVALID_HANDLE_VALUE; - unsigned char lpBuffer[4096]; + LPCWSTR lpszAgent = L"RApps/1.1"; - URL_COMPONENTSW urlComponents; - size_t urlLength, filenameLength; - - const ATL::CSimpleArray &InfoArray = static_cast(param)->AppInfo; - LPCWSTR szCaption = static_cast(param)->szCaption; - CStringW szNewCaption; - const DWORD dwUrlConnectFlags = INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_KEEP_CONNECTION; + URL_COMPONENTSW urlComponents; + size_t urlLength; + unsigned char lpBuffer[4096]; - if (InfoArray.GetSize() <= 0) + // Change caption to show the currently downloaded app + switch (Info.DLType) { - MessageBox_LoadString(hMainWnd, IDS_UNABLE_TO_DOWNLOAD); - goto end; + case DLTYPE_APPLICATION: + str.Format(m_szCaptionFmt, Info.szName.GetString()); + break; + case DLTYPE_DBUPDATE: + str.LoadStringW(IDS_DL_DIALOG_DB_DOWNLOAD_DISP); + break; + case DLTYPE_DBUPDATE_UNOFFICIAL: + str.LoadStringW(IDS_DL_DIALOG_DB_UNOFFICIAL_DOWNLOAD_DISP); + break; } + SetWindowTextW(hDlg, str); - for (iAppId = 0; iAppId < InfoArray.GetSize(); ++iAppId) + // is this URL an update package for RAPPS? if so store it in a different place + if (Info.DLType != DLTYPE_APPLICATION) { - // Reset progress bar - if (!IsWindow(hDlg)) - break; - Item = GetDlgItem(hDlg, IDC_DOWNLOAD_PROGRESS); - if (Item) + if (!GetStorageDirectory(Path)) { - ProgressBar.SetMarquee(FALSE); - ProgressBar.SendMessage(PBM_SETPOS, 0, 0); - ProgressBar.SetProgress(0, InfoArray[iAppId].SizeInBytes); + ShowLastError(hMainWnd, FALSE, GetLastError()); + goto end; } + } + else + { + Path = SettingsInfo.szDownloadDir; + } - // is this URL an update package for RAPPS? if so store it in a different place - if (InfoArray[iAppId].DLType != DLTYPE_APPLICATION) - { - if (!GetStorageDirectory(Path)) - { - ShowLastError(hMainWnd, FALSE, GetLastError()); - goto end; - } - } - else + // build the path for the download + p = wcsrchr(Info.szUrl.GetString(), L'/'); + + // do we have a final slash separator? + if (!p) + { + MessageBox_LoadString(hMainWnd, IDS_UNABLE_PATH); + goto end; + } + + // is the path valid? can we access it? + if (GetFileAttributesW(Path) == INVALID_FILE_ATTRIBUTES) + { + if (!CreateDirectoryW(Path, NULL)) { - Path = SettingsInfo.szDownloadDir; + ShowLastError(hMainWnd, FALSE, GetLastError()); + goto end; } + } - // Change caption to show the currently downloaded app - switch (InfoArray[iAppId].DLType) + switch (Info.DLType) + { + case DLTYPE_DBUPDATE: + case DLTYPE_DBUPDATE_UNOFFICIAL: + Path += APPLICATION_DATABASE_NAME; + break; + case DLTYPE_APPLICATION: { - case DLTYPE_APPLICATION: - szNewCaption.Format(szCaption, InfoArray[iAppId].szName.GetString()); - break; - case DLTYPE_DBUPDATE: - szNewCaption.LoadStringW(IDS_DL_DIALOG_DB_DOWNLOAD_DISP); - break; - case DLTYPE_DBUPDATE_UNOFFICIAL: - szNewCaption.LoadStringW(IDS_DL_DIALOG_DB_UNOFFICIAL_DOWNLOAD_DISP); - break; + CStringW name = Info.szFileName; + if (name.IsEmpty()) + name = p + 1; // use the filename retrieved from URL + UrlUnescapeAndMakeFileNameValid(name); + Path += name; + break; } + } - if (!IsWindow(hDlg)) - goto end; - SetWindowTextW(hDlg, szNewCaption.GetString()); + if ((Info.DLType == DLTYPE_APPLICATION) && Info.szSHA1[0] && + GetFileAttributesW(Path) != INVALID_FILE_ATTRIBUTES) + { + // only open it in case of total correctness + if (VerifyInteg(Info.szSHA1.GetString(), Path)) + goto run; + } - // build the path for the download - p = wcsrchr(InfoArray[iAppId].szUrl.GetString(), L'/'); - q = wcsrchr(InfoArray[iAppId].szUrl.GetString(), L'?'); + // Download it + SendMessageW(hDlg, WM_SETSTATUS, DLSTATUS_DOWNLOADING, 0); + /* FIXME: this should just be using the system-wide proxy settings */ + switch (SettingsInfo.Proxy) + { + case 0: // preconfig + default: + hOpen = InternetOpenW(lpszAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); + break; + case 1: // direct (no proxy) + hOpen = InternetOpenW(lpszAgent, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0); + break; + case 2: // use proxy + hOpen = InternetOpenW( + lpszAgent, INTERNET_OPEN_TYPE_PROXY, SettingsInfo.szProxyServer, SettingsInfo.szNoProxyFor, 0); + break; + } - // do we have a final slash separator? - if (!p) - { - MessageBox_LoadString(hMainWnd, IDS_UNABLE_PATH); - goto end; - } + if (!hOpen) + { + ShowLastError(hMainWnd, TRUE, GetLastError()); + goto end; + } - // prepare the tentative length of the filename, maybe we've to remove part of it later on - filenameLength = wcslen(p) * sizeof(WCHAR); + bTempfile = TRUE; + dwContentLen = 0; + dwStatusLen = sizeof(dwStatus); + ZeroMemory(&urlComponents, sizeof(urlComponents)); + urlComponents.dwStructSize = sizeof(urlComponents); - /* do we have query arguments in the target URL after the filename? account for them - (e.g. https://example.org/myfile.exe?no_adware_plz) */ - if (q && q > p && (q - p) > 0) - filenameLength -= wcslen(q - 1) * sizeof(WCHAR); + urlLength = Info.szUrl.GetLength(); + urlComponents.dwSchemeLength = urlLength + 1; + urlComponents.lpszScheme = (LPWSTR)malloc(urlComponents.dwSchemeLength * sizeof(WCHAR)); - // is the path valid? can we access it? - if (GetFileAttributesW(Path) == INVALID_FILE_ATTRIBUTES) - { - if (!CreateDirectoryW(Path, NULL)) - { - ShowLastError(hMainWnd, FALSE, GetLastError()); - goto end; - } - } + if (!InternetCrackUrlW(Info.szUrl, urlLength + 1, ICU_DECODE | ICU_ESCAPE, &urlComponents)) + { + ShowLastError(hMainWnd, TRUE, GetLastError()); + goto end; + } - switch (InfoArray[iAppId].DLType) + if (urlComponents.nScheme == INTERNET_SCHEME_HTTP || urlComponents.nScheme == INTERNET_SCHEME_HTTPS) + { + hFile = InternetOpenUrlW(hOpen, Info.szUrl, NULL, 0, dwUrlConnectFlags, 0); + if (!hFile) { - case DLTYPE_DBUPDATE: - case DLTYPE_DBUPDATE_UNOFFICIAL: - Path += APPLICATION_DATABASE_NAME; - break; - case DLTYPE_APPLICATION: + if (!ShowLastError(hMainWnd, TRUE, GetLastError())) { - CStringW str = p + 1; // use the filename retrieved from URL - UrlUnescapeAndMakeFileNameValid(str); - Path += str; - break; + /* Workaround for CORE-17377 */ + MessageBox_LoadString(hMainWnd, IDS_UNABLE_TO_DOWNLOAD2); } - } - - if ((InfoArray[iAppId].DLType == DLTYPE_APPLICATION) && InfoArray[iAppId].szSHA1[0] && - GetFileAttributesW(Path) != INVALID_FILE_ATTRIBUTES) - { - // only open it in case of total correctness - if (VerifyInteg(InfoArray[iAppId].szSHA1.GetString(), Path)) - goto run; - } - - // Add the download URL - if (!IsWindow(hDlg)) goto end; - SetDlgItemTextW(hDlg, IDC_DOWNLOAD_STATUS, InfoArray[iAppId].szUrl.GetString()); - - DownloadsListView.SetDownloadStatus(iAppId, DLSTATUS_DOWNLOADING); - - // download it - UrlHasBeenCopied = FALSE; - bTempfile = TRUE; - - /* FIXME: this should just be using the system-wide proxy settings */ - switch (SettingsInfo.Proxy) - { - case 0: // preconfig - default: - hOpen = InternetOpenW(lpszAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); - break; - case 1: // direct (no proxy) - hOpen = InternetOpenW(lpszAgent, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0); - break; - case 2: // use proxy - hOpen = InternetOpenW( - lpszAgent, INTERNET_OPEN_TYPE_PROXY, SettingsInfo.szProxyServer, SettingsInfo.szNoProxyFor, 0); - break; } - if (!hOpen) + // query connection + if (!HttpQueryInfoW(hFile, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwStatus, &dwStatusLen, NULL)) { ShowLastError(hMainWnd, TRUE, GetLastError()); goto end; } - dwStatusLen = sizeof(dwStatus); - - memset(&urlComponents, 0, sizeof(urlComponents)); - urlComponents.dwStructSize = sizeof(urlComponents); - - urlLength = InfoArray[iAppId].szUrl.GetLength(); - urlComponents.dwSchemeLength = urlLength + 1; - urlComponents.lpszScheme = (LPWSTR)malloc(urlComponents.dwSchemeLength * sizeof(WCHAR)); - - if (!InternetCrackUrlW(InfoArray[iAppId].szUrl, urlLength + 1, ICU_DECODE | ICU_ESCAPE, &urlComponents)) + if (dwStatus != HTTP_STATUS_OK) { - ShowLastError(hMainWnd, TRUE, GetLastError()); + MessageBox_LoadString(hMainWnd, IDS_UNABLE_TO_DOWNLOAD); goto end; } - dwContentLen = 0; - - if (urlComponents.nScheme == INTERNET_SCHEME_HTTP || urlComponents.nScheme == INTERNET_SCHEME_HTTPS) + // query content length + HttpQueryInfoW(hFile, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &dwContentLen, &dwStatusLen, NULL); + } + else if (urlComponents.nScheme == INTERNET_SCHEME_FTP) + { + // force passive mode on FTP + hFile = + InternetOpenUrlW(hOpen, Info.szUrl, NULL, 0, dwUrlConnectFlags | INTERNET_FLAG_PASSIVE, 0); + if (!hFile) { - hFile = InternetOpenUrlW(hOpen, InfoArray[iAppId].szUrl.GetString(), NULL, 0, dwUrlConnectFlags, 0); - if (!hFile) + if (!ShowLastError(hMainWnd, TRUE, GetLastError())) { - if (!ShowLastError(hMainWnd, TRUE, GetLastError())) - { - /* Workaround for CORE-17377 */ - MessageBox_LoadString(hMainWnd, IDS_UNABLE_TO_DOWNLOAD2); - } - goto end; + /* Workaround for CORE-17377 */ + MessageBox_LoadString(hMainWnd, IDS_UNABLE_TO_DOWNLOAD2); } - - // query connection - if (!HttpQueryInfoW(hFile, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwStatus, &dwStatusLen, NULL)) - { - ShowLastError(hMainWnd, TRUE, GetLastError()); - goto end; - } - - if (dwStatus != HTTP_STATUS_OK) - { - MessageBox_LoadString(hMainWnd, IDS_UNABLE_TO_DOWNLOAD); - goto end; - } - - // query content length - HttpQueryInfoW( - hFile, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &dwContentLen, &dwStatusLen, NULL); + goto end; } - else if (urlComponents.nScheme == INTERNET_SCHEME_FTP) - { - // force passive mode on FTP - hFile = - InternetOpenUrlW(hOpen, InfoArray[iAppId].szUrl, NULL, 0, dwUrlConnectFlags | INTERNET_FLAG_PASSIVE, 0); - if (!hFile) - { - if (!ShowLastError(hMainWnd, TRUE, GetLastError())) - { - /* Workaround for CORE-17377 */ - MessageBox_LoadString(hMainWnd, IDS_UNABLE_TO_DOWNLOAD2); - } - goto end; - } - dwContentLen = FtpGetFileSize(hFile, &dwStatus); - } - else if (urlComponents.nScheme == INTERNET_SCHEME_FILE) + dwContentLen = FtpGetFileSize(hFile, &dwStatus); + } + else if (urlComponents.nScheme == INTERNET_SCHEME_FILE) + { + // Add support for the file scheme so testing locally is simpler + WCHAR LocalFilePath[MAX_PATH]; + DWORD cchPath = _countof(LocalFilePath); + // Ideally we would use PathCreateFromUrlAlloc here, but that is not exported (yet) + HRESULT hr = PathCreateFromUrlW(Info.szUrl, LocalFilePath, &cchPath, 0); + if (SUCCEEDED(hr)) { - // Add support for the file scheme so testing locally is simpler - WCHAR LocalFilePath[MAX_PATH]; - DWORD cchPath = _countof(LocalFilePath); - // Ideally we would use PathCreateFromUrlAlloc here, but that is not exported (yet) - HRESULT hr = PathCreateFromUrlW(InfoArray[iAppId].szUrl, LocalFilePath, &cchPath, 0); - if (SUCCEEDED(hr)) + if (CopyFileW(LocalFilePath, Path, FALSE)) { - if (CopyFileW(LocalFilePath, Path, FALSE)) - { - goto run; - } - else - { - ShowLastError(hMainWnd, FALSE, GetLastError()); - goto end; - } + goto run; } else { - ShowLastError(hMainWnd, FALSE, hr); + ShowLastError(hMainWnd, FALSE, GetLastError()); goto end; } } + else + { + ShowLastError(hMainWnd, FALSE, hr); + goto end; + } + } - if (!dwContentLen) + if (!dwContentLen) + { + // Someone was nice enough to add this, let's use it + if (Info.SizeInBytes) { - // Someone was nice enough to add this, let's use it - if (InfoArray[iAppId].SizeInBytes) - { - dwContentLen = InfoArray[iAppId].SizeInBytes; - } - else - { - // content-length is not known, enable marquee mode - ProgressBar.SetMarquee(TRUE); - } + dwContentLen = Info.SizeInBytes; } + else + { + // content-length is not known, enable marquee mode + m_ProgressBar.SetMarquee(TRUE); + } + } - free(urlComponents.lpszScheme); + free(urlComponents.lpszScheme); #ifdef USE_CERT_PINNING - // are we using HTTPS to download the RAPPS update package? check if the certificate is original - if ((urlComponents.nScheme == INTERNET_SCHEME_HTTPS) && (InfoArray[iAppId].DLType == DLTYPE_DBUPDATE)) + // are we using HTTPS to download the RAPPS update package? check if the certificate is original + if ((urlComponents.nScheme == INTERNET_SCHEME_HTTPS) && (Info.DLType == DLTYPE_DBUPDATE)) + { + CLocalPtr subjectName, issuerName; + CStringA szMsgText; + bool bAskQuestion = false; + if (!CertGetSubjectAndIssuer(hFile, subjectName, issuerName)) { - CLocalPtr subjectName, issuerName; - CStringA szMsgText; - bool bAskQuestion = false; - if (!CertGetSubjectAndIssuer(hFile, subjectName, issuerName)) - { - szMsgText.LoadStringW(IDS_UNABLE_TO_QUERY_CERT); - bAskQuestion = true; - } - else - { - if (strcmp(subjectName, CERT_SUBJECT_INFO) || - (strcmp(issuerName, CERT_ISSUER_INFO_OLD) && strcmp(issuerName, CERT_ISSUER_INFO_NEW))) - { - szMsgText.Format(IDS_MISMATCH_CERT_INFO, (char *)subjectName, (const char *)issuerName); - bAskQuestion = true; - } - } + szMsgText.LoadStringW(IDS_UNABLE_TO_QUERY_CERT); + bAskQuestion = true; + } + else if (!IsTrustedPinnedCert(subjectName, issuerName)) + { + szMsgText.Format(IDS_MISMATCH_CERT_INFO, (LPCSTR)subjectName, (LPCSTR)issuerName); + bAskQuestion = true; + } - if (bAskQuestion) + if (bAskQuestion) + { + if (MessageBoxA(hDlg, szMsgText, NULL, MB_YESNO | MB_ICONERROR) != IDYES) { - if (MessageBoxA(hMainWnd, szMsgText.GetString(), NULL, MB_YESNO | MB_ICONERROR) != IDYES) - { - goto end; - } + goto end; } } + } #endif - hOut = CreateFileW(Path, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL); + hOut = CreateFileW(Path, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL); + if (hOut == INVALID_HANDLE_VALUE) + { + ShowLastError(hDlg, FALSE, GetLastError()); + goto end; + } + + dwCurrentBytesRead = 0; + do + { + bCancelled = IsCancelled(); + if (bCancelled) + break; - if (hOut == INVALID_HANDLE_VALUE) + if (!InternetReadFile(hFile, lpBuffer, _countof(lpBuffer), &dwBytesRead)) { - ShowLastError(hMainWnd, FALSE, GetLastError()); + ShowLastError(hDlg, TRUE, GetLastError()); goto end; } - dwCurrentBytesRead = 0; - do + if (!WriteFile(hOut, &lpBuffer[0], dwBytesRead, &dwBytesWritten, NULL)) { - if (!InternetReadFile(hFile, lpBuffer, _countof(lpBuffer), &dwBytesRead)) - { - ShowLastError(hMainWnd, TRUE, GetLastError()); - goto end; - } + ShowLastError(hDlg, FALSE, GetLastError()); + goto end; + } - if (!WriteFile(hOut, &lpBuffer[0], dwBytesRead, &dwBytesWritten, NULL)) - { - ShowLastError(hMainWnd, FALSE, GetLastError()); - goto end; - } + dwCurrentBytesRead += dwBytesRead; + UpdateProgress(dwCurrentBytesRead, dwContentLen); + + } while (dwBytesRead); - dwCurrentBytesRead += dwBytesRead; - if (!IsWindow(hDlg)) - goto end; - UpdateProgress(hDlg, dwCurrentBytesRead, dwContentLen, 0, InfoArray[iAppId].szUrl.GetString()); - } while (dwBytesRead && !bCancelled); + CloseHandle(hOut); + hOut = INVALID_HANDLE_VALUE; - CloseHandle(hOut); - hOut = INVALID_HANDLE_VALUE; + if (bCancelled) + { + DPRINT1("Operation cancelled\n"); + goto end; + } - if (bCancelled) + if (!dwContentLen) + { + // set progress bar to 100% + m_ProgressBar.SetMarquee(FALSE); + + dwContentLen = dwCurrentBytesRead; + UpdateProgress(dwCurrentBytesRead, dwContentLen); + } + + /* if this thing isn't a RAPPS update and it has a SHA-1 checksum + verify its integrity by using the native advapi32.A_SHA1 functions */ + if ((Info.DLType == DLTYPE_APPLICATION) && Info.szSHA1[0] != 0) + { + CStringW szMsgText; + + // change a few strings in the download dialog to reflect the verification process + if (!szMsgText.LoadStringW(IDS_INTEG_CHECK_TITLE)) { - DPRINT1("Operation cancelled\n"); + DPRINT1("Unable to load string\n"); goto end; } - if (!dwContentLen) - { - // set progress bar to 100% - ProgressBar.SetMarquee(FALSE); + SetWindowTextW(hDlg, szMsgText); + SetWindowTextW(hStatus, Path); - dwContentLen = dwCurrentBytesRead; - if (!IsWindow(hDlg)) - goto end; - UpdateProgress(hDlg, dwCurrentBytesRead, dwContentLen, 0, InfoArray[iAppId].szUrl.GetString()); - } - - /* if this thing isn't a RAPPS update and it has a SHA-1 checksum - verify its integrity by using the native advapi32.A_SHA1 functions */ - if ((InfoArray[iAppId].DLType == DLTYPE_APPLICATION) && InfoArray[iAppId].szSHA1[0] != 0) + // this may take a while, depending on the file size + if (!VerifyInteg(Info.szSHA1, Path)) { - CStringW szMsgText; - - // change a few strings in the download dialog to reflect the verification process - if (!szMsgText.LoadStringW(IDS_INTEG_CHECK_TITLE)) + if (!szMsgText.LoadStringW(IDS_INTEG_CHECK_FAIL)) { DPRINT1("Unable to load string\n"); goto end; } - if (!IsWindow(hDlg)) - goto end; - SetWindowTextW(hDlg, szMsgText.GetString()); - ::SetDlgItemTextW(hDlg, IDC_DOWNLOAD_STATUS, Path); - - // this may take a while, depending on the file size - if (!VerifyInteg(InfoArray[iAppId].szSHA1.GetString(), Path)) - { - if (!szMsgText.LoadStringW(IDS_INTEG_CHECK_FAIL)) - { - DPRINT1("Unable to load string\n"); - goto end; - } - - if (!IsWindow(hDlg)) - goto end; - MessageBoxW(hDlg, szMsgText.GetString(), NULL, MB_OK | MB_ICONERROR); - goto end; - } + MessageBoxW(hDlg, szMsgText, NULL, MB_OK | MB_ICONERROR); + goto end; } + } - run: - DownloadsListView.SetDownloadStatus(iAppId, DLSTATUS_WAITING_INSTALL); +run: + SendMessageW(hDlg, WM_SETSTATUS, DLSTATUS_WAITING_INSTALL, 0); - // run it - if (InfoArray[iAppId].DLType == DLTYPE_APPLICATION) + // run it + if (Info.DLType == DLTYPE_APPLICATION) + { + CStringW app, params; + SHELLEXECUTEINFOW shExInfo = {0}; + shExInfo.cbSize = sizeof(shExInfo); + shExInfo.fMask = SEE_MASK_NOCLOSEPROCESS; + shExInfo.lpVerb = L"open"; + shExInfo.lpFile = Path; + shExInfo.lpParameters = L""; + shExInfo.nShow = SW_SHOW; + + if (Info.IType == INSTALLER_GENERATE) { - CStringW app, params; - SHELLEXECUTEINFOW shExInfo = {0}; - shExInfo.cbSize = sizeof(shExInfo); - shExInfo.fMask = SEE_MASK_NOCLOSEPROCESS; - shExInfo.lpVerb = L"open"; - shExInfo.lpFile = Path; - shExInfo.lpParameters = L""; - shExInfo.nShow = SW_SHOW; - - if (InfoArray[iAppId].IType == INSTALLER_GENERATE) - { - params = L"/" + CStringW(CMD_KEY_GENINST) + L" \"" + - InfoArray[iAppId].szPackageName + L"\" \"" + - CStringW(shExInfo.lpFile) + L"\""; - shExInfo.lpParameters = params; - shExInfo.lpFile = app.GetBuffer(MAX_PATH); - GetModuleFileNameW(NULL, const_cast(shExInfo.lpFile), MAX_PATH); - app.ReleaseBuffer(); - } + params = L"/" + CStringW(CMD_KEY_GENINST) + L" \"" + + Info.szPackageName + L"\" \"" + + CStringW(shExInfo.lpFile) + L"\""; + shExInfo.lpParameters = params; + shExInfo.lpFile = app.GetBuffer(MAX_PATH); + GetModuleFileNameW(NULL, const_cast(shExInfo.lpFile), MAX_PATH); + app.ReleaseBuffer(); + } - /* FIXME: Do we want to log installer status? */ - WriteLogMessage(EVENTLOG_SUCCESS, MSG_SUCCESS_INSTALL, InfoArray[iAppId].szName); + /* FIXME: Do we want to log installer status? */ + WriteLogMessage(EVENTLOG_SUCCESS, MSG_SUCCESS_INSTALL, Info.szName); - if (ShellExecuteExW(&shExInfo)) - { - // reflect installation progress in the titlebar - // TODO: make a separate string with a placeholder to include app name? - CStringW szMsgText = LoadStatusString(DLSTATUS_INSTALLING); - if (!IsWindow(hDlg)) - goto end; - SetWindowTextW(hDlg, szMsgText.GetString()); + if (ShellExecuteExW(&shExInfo)) + { + // reflect installation progress in the titlebar + // TODO: make a separate string with a placeholder to include app name? + CStringW szMsgText = LoadStatusString(DLSTATUS_INSTALLING); + SetWindowTextW(hDlg, szMsgText); - DownloadsListView.SetDownloadStatus(iAppId, DLSTATUS_INSTALLING); + SendMessageW(hDlg, WM_SETSTATUS, DLSTATUS_INSTALLING, 0); - // TODO: issue an install operation separately so that the apps could be downloaded in the background + // TODO: issue an install operation separately so that the apps could be downloaded in the background + if (shExInfo.hProcess) + { WaitForSingleObject(shExInfo.hProcess, INFINITE); CloseHandle(shExInfo.hProcess); + SendMessageW(hMainWnd, WM_NOTIFY_INSTALLERFINISHED, 0, (LPARAM)(PCWSTR)Info.szPackageName); } - else - { - ShowLastError(hMainWnd, FALSE, GetLastError()); - } } + else + { + ShowLastError(hMainWnd, FALSE, GetLastError()); + } + } - end: - if (hOut != INVALID_HANDLE_VALUE) - CloseHandle(hOut); +end: + if (hOut != INVALID_HANDLE_VALUE) + CloseHandle(hOut); - if (hFile) - InternetCloseHandle(hFile); - InternetCloseHandle(hOpen); + if (hFile) + InternetCloseHandle(hFile); + InternetCloseHandle(hOpen); - if (bTempfile) + if (bTempfile) + { + if (bCancelled || (SettingsInfo.bDelInstaller && Info.DLType == DLTYPE_APPLICATION)) { - if (bCancelled || (SettingsInfo.bDelInstaller && (InfoArray[iAppId].DLType == DLTYPE_APPLICATION))) + // Don't delete .zip/.cab files so the user can extract from them + if (bCancelled || Info.IType == INSTALLER_GENERATE || !OpensWithExplorer(Path) || + HIBYTE(ClassifyFile(Path)) != PERCEIVED_TYPE_COMPRESSED) + { DeleteFileW(Path); + } } - - if (!IsWindow(hDlg)) - return 0; - DownloadsListView.SetDownloadStatus(iAppId, DLSTATUS_FINISHED); } - delete static_cast(param); - if (!IsWindow(hDlg)) - return 0; - SendMessageW(hDlg, WM_CLOSE, 0, 0); - return 0; + SendMessageW(hDlg, WM_SETSTATUS, DLSTATUS_FINISHED, 0); } -// TODO: Reuse the dialog -VOID -CDownloadManager::LaunchDownloadDialog(BOOL bIsModal) -{ - CDownloadManager::bModal = bIsModal; - if (bIsModal) - { - DialogBoxW(hInst, MAKEINTRESOURCEW(IDD_DOWNLOAD_DIALOG), hMainWnd, DownloadDlgProc); - } - else - { - CreateDialogW(hInst, MAKEINTRESOURCEW(IDD_DOWNLOAD_DIALOG), hMainWnd, DownloadDlgProc); - } -} -// CDownloadManager - BOOL DownloadListOfApplications(const CAtlList &AppsList, BOOL bIsModal) { if (AppsList.IsEmpty()) return FALSE; - POSITION CurrentListPosition = AppsList.GetHeadPosition(); - while (CurrentListPosition) + CComPtr pDM; + if (!CDownloadManager::CreateInstance(bIsModal, pDM)) + return FALSE; + + for (POSITION it = AppsList.GetHeadPosition(); it;) { - const CAppInfo *Info = AppsList.GetNext(CurrentListPosition); - CDownloadManager::Add(DownloadInfo(*Info)); + const CAppInfo *Info = AppsList.GetNext(it); + pDM->Add(DownloadInfo(*Info)); } - - // Create a dialog and issue a download process - CDownloadManager::LaunchDownloadDialog(bIsModal); - + pDM->Show(); return TRUE; } BOOL DownloadApplication(CAppInfo *pAppInfo) { + const bool bModal = false; if (!pAppInfo) return FALSE; - CDownloadManager::Download(*pAppInfo, FALSE); - return TRUE; + CAtlList list; + list.AddTail(pAppInfo); + return DownloadListOfApplications(list, bModal); } VOID DownloadApplicationsDB(LPCWSTR lpUrl, BOOL IsOfficial) { - static DownloadInfo DatabaseDLInfo; + const bool bModal = true; + CComPtr pDM; + if (!CDownloadManager::CreateInstance(bModal, pDM)) + return; + + DownloadInfo DatabaseDLInfo; DatabaseDLInfo.szUrl = lpUrl; DatabaseDLInfo.szName.LoadStringW(IDS_DL_DIALOG_DB_DISP); DatabaseDLInfo.DLType = IsOfficial ? DLTYPE_DBUPDATE : DLTYPE_DBUPDATE_UNOFFICIAL; - CDownloadManager::Download(DatabaseDLInfo, TRUE); + + pDM->Add(DatabaseDLInfo); + pDM->Show(); } diff --git a/base/applications/rapps/misc.cpp b/base/applications/rapps/misc.cpp index c5fe6f0c4bc21..0965cc945d015 100644 --- a/base/applications/rapps/misc.cpp +++ b/base/applications/rapps/misc.cpp @@ -12,6 +12,18 @@ static HANDLE hLog = NULL; +UINT +ErrorBox(HWND hOwner, UINT Error) +{ + if (!Error) + Error = ERROR_INTERNAL_ERROR; // Note: geninst.cpp depends on this + WCHAR buf[400]; + UINT fmf = FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM; + FormatMessageW(fmf, NULL, Error, 0, buf, _countof(buf), NULL); + MessageBoxW(hOwner, buf, 0, MB_OK | MB_ICONSTOP); + return Error; +} + VOID CopyTextToClipboard(LPCWSTR lpszText) { @@ -107,6 +119,59 @@ ShowPopupMenuEx(HWND hwnd, HWND hwndOwner, UINT MenuID, UINT DefaultItem, POINT } } +extern BOOL IsZipFile(PCWSTR Path); + +UINT +ClassifyFile(PCWSTR Path) +{ + const UINT share = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; + HANDLE hFile = CreateFileW(Path, GENERIC_READ, share, NULL, OPEN_EXISTING, 0, NULL); + if (hFile != INVALID_HANDLE_VALUE) + { + BYTE buf[8]; + DWORD io; + if (!ReadFile(hFile, buf, sizeof(buf), &io, NULL) || io != sizeof(buf)) + buf[0] = 0; + CloseHandle(hFile); + + if (buf[0] == 0xD0 && buf[1] == 0xCF && buf[2] == 0x11 && buf[3] == 0xE0 && + buf[4] == 0xA1 && buf[5] == 0xB1 && buf[6] == 0x1A && buf[7] == 0xE1) + { + return MAKEWORD('M', PERCEIVED_TYPE_APPLICATION); // MSI + } + if (buf[0] == 'M' || buf[0] == 'Z') + { + SHFILEINFO shfi; + if (SHGetFileInfoW(Path, 0, &shfi, sizeof(shfi), SHGFI_EXETYPE)) + return MAKEWORD('E', PERCEIVED_TYPE_APPLICATION); + } + if (buf[0] == 'M' && buf[1] == 'S' && buf[2] == 'C' && buf[3] == 'F') + { + return MAKEWORD('C', PERCEIVED_TYPE_COMPRESSED); // CAB + } + } + + if (IsZipFile(Path)) // .zip last because we want to return SFX.exe with higher priority + { + return MAKEWORD('Z', PERCEIVED_TYPE_COMPRESSED); + } + return PERCEIVED_TYPE_UNKNOWN; +} + +BOOL +OpensWithExplorer(PCWSTR Path) +{ + WCHAR szCmd[MAX_PATH * 2]; + DWORD cch = _countof(szCmd); + PCWSTR pszExt = PathFindExtensionW(Path); + HRESULT hr = AssocQueryStringW(ASSOCF_INIT_IGNOREUNKNOWN | ASSOCF_NOTRUNCATE, + ASSOCSTR_COMMAND, pszExt, NULL, szCmd, &cch); + if (SUCCEEDED(hr) && StrStrIW(szCmd, L" zipfldr.dll,")) // .zip + return TRUE; + PathRemoveArgsW(szCmd); + return SUCCEEDED(hr) && !StrCmpIW(PathFindFileNameW(szCmd), L"explorer.exe"); // .cab +} + BOOL StartProcess(const CStringW &Path, BOOL Wait) { @@ -160,6 +225,8 @@ StartProcess(const CStringW &Path, BOOL Wait) { EnableWindow(hMainWnd, TRUE); SetForegroundWindow(hMainWnd); + // We got the real activation message during MsgWaitForMultipleObjects while + // we were disabled, we need to set the focus again now. SetFocus(hMainWnd); } diff --git a/base/applications/rapps/settings.cpp b/base/applications/rapps/settings.cpp index b23c2dd7a49c3..e87d5d0315cad 100644 --- a/base/applications/rapps/settings.cpp +++ b/base/applications/rapps/settings.cpp @@ -118,6 +118,7 @@ AddInfoFields(ATL::CAtlList &infoFields, SETTINGS_INFO &setting infoFields.AddTail(new SettingsFieldBool(&(settings.bLogEnabled), L"bLogEnabled")); infoFields.AddTail(new SettingsFieldString(settings.szDownloadDir, MAX_PATH, L"szDownloadDir")); infoFields.AddTail(new SettingsFieldBool(&(settings.bDelInstaller), L"bDelInstaller")); + infoFields.AddTail(new SettingsFieldBool(&(settings.bSmallIcons), L"SmallIcons")); infoFields.AddTail(new SettingsFieldBool(&(settings.Maximized), L"WindowPosMaximized")); infoFields.AddTail(new SettingsFieldInt(&(settings.Left), L"WindowPosLeft")); infoFields.AddTail(new SettingsFieldInt(&(settings.Top), L"WindowPosTop")); diff --git a/base/applications/rapps/settingsdlg.cpp b/base/applications/rapps/settingsdlg.cpp index 92782d5948426..9daf0f7a40db7 100644 --- a/base/applications/rapps/settingsdlg.cpp +++ b/base/applications/rapps/settingsdlg.cpp @@ -7,7 +7,7 @@ */ #include "rapps.h" -SETTINGS_INFO NewSettingsInfo; +SETTINGS_INFO *g_pNewSettingsInfo; static int CALLBACK BrowseFolderCallback(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData) @@ -23,7 +23,7 @@ BrowseFolderCallback(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData) return 0; } -BOOL +static BOOL ChooseFolder(HWND hwnd) { BOOL bRet = FALSE; @@ -65,7 +65,7 @@ ChooseFolder(HWND hwnd) return bRet; } -BOOL +static BOOL IsUrlValid(const WCHAR *Url) { URL_COMPONENTSW UrlComponmentInfo = {0}; @@ -94,18 +94,74 @@ IsUrlValid(const WCHAR *Url) namespace { -inline BOOL +static inline BOOL IsCheckedDlgItem(HWND hDlg, INT nIDDlgItem) { - return (SendDlgItemMessageW(hDlg, nIDDlgItem, BM_GETCHECK, 0, 0) == BST_CHECKED) ? TRUE : FALSE; + return SendDlgItemMessageW(hDlg, nIDDlgItem, BM_GETCHECK, 0, 0) == BST_CHECKED; } -VOID +static inline void +AdjustListViewHeader(HWND hWndList) +{ + ListView_SetColumnWidth(hWndList, 0, LVSCW_AUTOSIZE_USEHEADER); +} + +static void +HandleGeneralListItems(HWND hWndList, PSETTINGS_INFO Load, PSETTINGS_INFO Save) +{ + PSETTINGS_INFO Info = Load ? Load : Save; + const struct { + WORD Id; + BOOL *Setting; + } Map[] = { + { IDS_CFG_SAVE_WINDOW_POS, &Info->bSaveWndPos }, + { IDS_CFG_UPDATE_AVLIST, &Info->bUpdateAtStart }, + { IDS_CFG_LOG_ENABLED, &Info->bLogEnabled }, + { IDS_CFG_SMALL_ICONS, &Info->bSmallIcons }, + }; + + if (Load) + { + UINT ExStyle = LVS_EX_CHECKBOXES | LVS_EX_LABELTIP; + ListView_SetExtendedListViewStyleEx(hWndList, ExStyle, ExStyle); + LVCOLUMN lvc; + lvc.mask = LVCF_TEXT | LVCF_SUBITEM; + lvc.iSubItem = 0; + lvc.pszText = const_cast(L""); + ListView_InsertColumn(hWndList, 0, &lvc); + + CStringW Name; + for (SIZE_T i = 0; i < _countof(Map); ++i) + { + LVITEMW Item; + Item.mask = LVIF_TEXT | LVIF_PARAM; + Item.iItem = 0x7fff; + Item.iSubItem = 0; + Item.lParam = Map[i].Id; + Name.LoadStringW(Map[i].Id); + Item.pszText = const_cast(Name.GetString()); + Item.iItem = ListView_InsertItem(hWndList, &Item); + ListView_SetCheckState(hWndList, Item.iItem, *Map[i].Setting); + } + ListView_SetItemState(hWndList, 0, -1, LVIS_FOCUSED | LVIS_SELECTED); + AdjustListViewHeader(hWndList); + } + else + { + for (SIZE_T i = 0; i < _countof(Map); ++i) + { + LVFINDINFOW FindInfo = { LVFI_PARAM, NULL, Map[i].Id }; + int Idx = ListView_FindItem(hWndList, -1, &FindInfo); + if (Idx >= 0) + *Map[i].Setting = ListView_GetCheckState(hWndList, Idx); + } + } +} + +static VOID InitSettingsControls(HWND hDlg, PSETTINGS_INFO Info) { - SendDlgItemMessageW(hDlg, IDC_SAVE_WINDOW_POS, BM_SETCHECK, Info->bSaveWndPos, 0); - SendDlgItemMessageW(hDlg, IDC_UPDATE_AVLIST, BM_SETCHECK, Info->bUpdateAtStart, 0); - SendDlgItemMessageW(hDlg, IDC_LOG_ENABLED, BM_SETCHECK, Info->bLogEnabled, 0); + HandleGeneralListItems(GetDlgItem(hDlg, IDC_GENERALLIST), Info, NULL); SendDlgItemMessageW(hDlg, IDC_DEL_AFTER_INSTALL, BM_SETCHECK, Info->bDelInstaller, 0); HWND hCtl = GetDlgItem(hDlg, IDC_DOWNLOAD_DIR_EDIT); @@ -134,16 +190,24 @@ InitSettingsControls(HWND hDlg, PSETTINGS_INFO Info) SetWindowTextW(GetDlgItem(hDlg, IDC_NO_PROXY_FOR), Info->szNoProxyFor); } -INT_PTR CALLBACK +static INT_PTR CALLBACK SettingsDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam) { + SETTINGS_INFO &NewSettingsInfo = *g_pNewSettingsInfo; + switch (Msg) { case WM_INITDIALOG: - NewSettingsInfo = SettingsInfo; InitSettingsControls(hDlg, &SettingsInfo); return TRUE; + case WM_SETTINGCHANGE: + case WM_THEMECHANGED: + case WM_SYSCOLORCHANGE: + SendMessage(GetDlgItem(hDlg, IDC_GENERALLIST), Msg, wParam, lParam); + AdjustListViewHeader(GetDlgItem(hDlg, IDC_GENERALLIST)); + break; + case WM_COMMAND: { switch (LOWORD(wParam)) @@ -152,18 +216,6 @@ SettingsDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam) ChooseFolder(hDlg); break; - case IDC_SAVE_WINDOW_POS: - NewSettingsInfo.bSaveWndPos = IsCheckedDlgItem(hDlg, IDC_SAVE_WINDOW_POS); - break; - - case IDC_UPDATE_AVLIST: - NewSettingsInfo.bUpdateAtStart = IsCheckedDlgItem(hDlg, IDC_UPDATE_AVLIST); - break; - - case IDC_LOG_ENABLED: - NewSettingsInfo.bLogEnabled = IsCheckedDlgItem(hDlg, IDC_LOG_ENABLED); - break; - case IDC_DEL_AFTER_INSTALL: NewSettingsInfo.bDelInstaller = IsCheckedDlgItem(hDlg, IDC_DEL_AFTER_INSTALL); break; @@ -203,6 +255,8 @@ SettingsDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam) case IDOK: { + HandleGeneralListItems(GetDlgItem(hDlg, IDC_GENERALLIST), NULL, &NewSettingsInfo); + CStringW szDir; CStringW szSource; CStringW szProxy; @@ -229,23 +283,21 @@ SettingsDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam) NewSettingsInfo.szNoProxyFor, _countof(NewSettingsInfo.szNoProxyFor), szNoProxy, szNoProxy.GetLength() + 1); + CStringW::CopyChars( + NewSettingsInfo.szDownloadDir, _countof(NewSettingsInfo.szDownloadDir), szDir, + szDir.GetLength() + 1); dwAttr = GetFileAttributesW(szDir); - if (dwAttr != INVALID_FILE_ATTRIBUTES && (dwAttr & FILE_ATTRIBUTE_DIRECTORY)) - { - CStringW::CopyChars( - NewSettingsInfo.szDownloadDir, _countof(NewSettingsInfo.szDownloadDir), szDir, - szDir.GetLength() + 1); - } - else + if (dwAttr == INVALID_FILE_ATTRIBUTES || !(dwAttr & FILE_ATTRIBUTE_DIRECTORY)) { CStringW szMsgText; szMsgText.LoadStringW(IDS_CHOOSE_FOLDER_ERROR); if (MessageBoxW(hDlg, szMsgText, NULL, MB_YESNO) == IDYES) { - if (CreateDirectoryW(szDir, NULL)) + if (!CreateDirectoryW(szDir, NULL)) { - EndDialog(hDlg, LOWORD(wParam)); + ErrorBox(hDlg); + break; } } else @@ -271,6 +323,11 @@ SettingsDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam) szSource.GetLength() + 1); } + if (SettingsInfo.bSmallIcons != NewSettingsInfo.bSmallIcons) + { + SendMessageW(hMainWnd, WM_SETTINGCHANGE, SPI_SETICONMETRICS, 0); // Note: WM_SETTINGCHANGE cannot be posted + PostMessageW(hMainWnd, WM_COMMAND, ID_REFRESH, 0); + } SettingsInfo = NewSettingsInfo; SaveSettings(GetParent(hDlg), &SettingsInfo); EndDialog(hDlg, LOWORD(wParam)); @@ -281,8 +338,25 @@ SettingsDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam) EndDialog(hDlg, LOWORD(wParam)); break; } + break; + } + + case WM_NOTIFY: + { + NMITEMACTIVATE &nmia = *(NMITEMACTIVATE*)lParam; + if (wParam == IDC_GENERALLIST && nmia.hdr.code == NM_CLICK) + { + LVHITTESTINFO lvhti; + lvhti.pt = nmia.ptAction; + if (nmia.iItem != -1 && ListView_HitTest(nmia.hdr.hwndFrom, &lvhti) != -1) + { + if (lvhti.flags & (LVHT_ONITEMICON | LVHT_ONITEMLABEL)) + ListView_SetCheckState(nmia.hdr.hwndFrom, nmia.iItem, + !ListView_GetCheckState(nmia.hdr.hwndFrom, nmia.iItem)); + } + } + break; } - break; } return FALSE; @@ -292,5 +366,8 @@ SettingsDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam) VOID CreateSettingsDlg(HWND hwnd) { + SETTINGS_INFO NewSettingsInfo = SettingsInfo; + g_pNewSettingsInfo = &NewSettingsInfo; + DialogBoxW(hInst, MAKEINTRESOURCEW(IDD_SETTINGS_DIALOG), hwnd, SettingsDlgProc); } diff --git a/base/applications/rapps/unattended.cpp b/base/applications/rapps/unattended.cpp index 12ffe79254a90..06db5f0aba63e 100644 --- a/base/applications/rapps/unattended.cpp +++ b/base/applications/rapps/unattended.cpp @@ -191,7 +191,7 @@ HandleUninstallCommand(CAppDB &db, UINT argcLeft, LPWSTR *argvLeft) if (pInfo) { - retval = pInfo->UninstallApplication(silent ? UCF_SILENT : UCF_NONE); + retval = pInfo->UninstallApplication((silent ? UCF_SILENT : UCF_NONE) | UCF_SAMEPROCESS); } delete pDelete; return retval; @@ -338,6 +338,7 @@ ParseCmdAndExecute(LPWSTR lpCmdLine, BOOL bIsFirstLaunch, int nCmdShow) BOOL bAppwizMode = (argc > 1 && MatchCmdOption(argv[1], CMD_KEY_APPWIZ)); if (!bAppwizMode) { + CUpdateDatabaseMutex lock; if (SettingsInfo.bUpdateAtStart || bIsFirstLaunch) db.RemoveCached(); @@ -350,7 +351,7 @@ ParseCmdAndExecute(LPWSTR lpCmdLine, BOOL bIsFirstLaunch, int nCmdShow) { // Check whether the RAPPS MainWindow is already launched in another process CStringW szWindowText(MAKEINTRESOURCEW(bAppwizMode ? IDS_APPWIZ_TITLE : IDS_APPTITLE)); - LPCWSTR pszMutex = bAppwizMode ? L"RAPPWIZ" : szWindowClass; + LPCWSTR pszMutex = bAppwizMode ? L"RAPPWIZ" : MAINWINDOWMUTEX; HANDLE hMutex = CreateMutexW(NULL, FALSE, pszMutex); if ((!hMutex) || (GetLastError() == ERROR_ALREADY_EXISTS)) @@ -367,7 +368,7 @@ ParseCmdAndExecute(LPWSTR lpCmdLine, BOOL bIsFirstLaunch, int nCmdShow) if (hWindow) { /* Activate the window in the other instance */ - ShowWindow(hWindow, SW_SHOW); + ShowWindow(hWindow, SW_SHOWNA); SwitchToThisWindow(hWindow, TRUE); if (bAppwizMode) PostMessage(hWindow, WM_COMMAND, ID_ACTIVATE_APPWIZ, 0); diff --git a/base/applications/rapps/winmain.cpp b/base/applications/rapps/winmain.cpp index 2c5c06a300f18..e36ac0db5aba1 100644 --- a/base/applications/rapps/winmain.cpp +++ b/base/applications/rapps/winmain.cpp @@ -13,10 +13,10 @@ #include #include -LPCWSTR szWindowClass = L"ROSAPPMGR2"; +LPCWSTR szWindowClass = MAINWINDOWCLASSNAME; LONG g_Busy = 0; -HWND hMainWnd; +HWND hMainWnd = NULL; HINSTANCE hInst; SETTINGS_INFO SettingsInfo; diff --git a/base/applications/regedit/childwnd.c b/base/applications/regedit/childwnd.c index b08736e532266..6ba0758bbbf3f 100644 --- a/base/applications/regedit/childwnd.c +++ b/base/applications/regedit/childwnd.c @@ -11,7 +11,7 @@ #include ChildWnd* g_pChildWnd; -static int last_split; +static int last_split = -1; HBITMAP SizingPattern; HBRUSH SizingBrush; WCHAR Suggestions[256]; @@ -99,16 +99,20 @@ extern void ResizeWnd(int cx, int cy) const int nButtonWidth = 44; const int nButtonHeight = 22; int cyEdge = GetSystemMetrics(SM_CYEDGE); - const UINT uFlags = SWP_NOZORDER | SWP_NOACTIVATE; - SetRect(&rt, 0, 0, cx, cy); + const UINT uFlags = SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOCOPYBITS; + cy = 0; - if (hStatusBar != NULL) + if (IsWindowVisible(hStatusBar)) { GetWindowRect(hStatusBar, &rs); cy = rs.bottom - rs.top; } + GetWindowRect(g_pChildWnd->hAddressBtnWnd, &rb); + GetClientRect(g_pChildWnd->hWnd, &rt); + RedrawWindow(g_pChildWnd->hWnd, &rt, NULL, RDW_INVALIDATE | RDW_NOCHILDREN); + g_pChildWnd->nSplitPos = ClampSplitBarX(g_pChildWnd->hWnd, g_pChildWnd->nSplitPos); cx = g_pChildWnd->nSplitPos + SPLIT_WIDTH / 2; @@ -148,7 +152,7 @@ static void draw_splitbar(HWND hWnd, int x) { RECT rt; HGDIOBJ OldObj; - HDC hdc = GetDC(hWnd); + HDC hdc = GetDCEx(hWnd, NULL, DCX_CACHE); if(!SizingPattern) { @@ -159,7 +163,10 @@ static void draw_splitbar(HWND hWnd, int x) { SizingBrush = CreatePatternBrush(SizingPattern); } - GetClientRect(hWnd, &rt); + + GetWindowRect(g_pChildWnd->hTreeWnd, &rt); + MapWindowPoints(NULL, hWnd, (POINT *)&rt, sizeof(rt) / sizeof(POINT)); + rt.left = x - SPLIT_WIDTH/2; rt.right = x + SPLIT_WIDTH/2+1; OldObj = SelectObject(hdc, SizingBrush); @@ -388,7 +395,8 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa g_pChildWnd->nSplitPos = 190; g_pChildWnd->hWnd = hWnd; - style = WS_CHILD | WS_VISIBLE | WS_TABSTOP; + /* ES_AUTOHSCROLL style enables horizontal scrolling and shrinking */ + style = WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_AUTOHSCROLL; g_pChildWnd->hAddressBarWnd = CreateWindowExW(WS_EX_CLIENTEDGE, L"Edit", NULL, style, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hWnd, (HMENU)0, hInst, 0); diff --git a/base/applications/regedit/clb/clb.rc b/base/applications/regedit/clb/clb.rc index fa642311fb79a..b6567cb7f5706 100644 --- a/base/applications/regedit/clb/clb.rc +++ b/base/applications/regedit/clb/clb.rc @@ -12,7 +12,6 @@ #include - /* UTF-8 */ #pragma code_page(65001) diff --git a/base/applications/regedit/clb/lang/fr-FR.rc b/base/applications/regedit/clb/lang/fr-FR.rc index 965412651ac15..43de608c98bc6 100644 --- a/base/applications/regedit/clb/lang/fr-FR.rc +++ b/base/applications/regedit/clb/lang/fr-FR.rc @@ -7,25 +7,25 @@ LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT IDD_COLUMNLISTBOXSTYLES DIALOGEX 0, 0, 227, 215 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU -CAPTION "Styles de Boites de la Liste de la Colonne" +CAPTION "Styles de la zone de liste en colonnes" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN - GROUPBOX "Styles des Colonne de la Liste", -1, 6, 7, 158, 71 + GROUPBOX "Styles de la zone de liste en colonnes", -1, 6, 7, 158, 71 CHECKBOX "&Standard", 1710, 10, 20, 42, 10, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP CHECKBOX "&Bordure", 1713, 10, 30, 34, 10, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - CHECKBOX "&Ordre", 1705, 10, 40, 26, 10, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + CHECKBOX "Tr&i", 1705, 10, 40, 26, 10, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP CHECKBOX "Notif&ier", 1706, 10, 50, 32, 10, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - CHECKBOX "Barre de Déplac. V&ert.", 1707, 10, 60, 64, 10, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - CHECKBOX "Sélection &Multiple", -1, 79, 20, 72, 10, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP | WS_DISABLED - CHECKBOX "Sélection E&tendue", -1, 79, 30, 77, 10, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP | WS_DISABLED - CHECKBOX "Montrer &Chevet", 1714, 79, 40, 68, 10, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - CHECKBOX "Colonnes &Elastiques", 1715, 79, 50, 66, 10, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - GROUPBOX "Styles Basiques", -1, 6, 80, 158, 34 + CHECKBOX "Barre de défil. v&ert.", 1707, 10, 60, 64, 10, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + CHECKBOX "Sélection &multiple", -1, 79, 20, 72, 10, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP | WS_DISABLED + CHECKBOX "Sélection é&tendue", -1, 79, 30, 77, 10, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP | WS_DISABLED + CHECKBOX "Montrer &chevet", 1714, 79, 40, 68, 10, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + CHECKBOX "Colonnes é&lastiques", 1715, 79, 50, 66, 10, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + GROUPBOX "Styles basiques", -1, 6, 80, 158, 34 CHECKBOX "&Visible", 1701, 10, 92, 34, 10, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP CHECKBOX "&Désactivé", 1702, 10, 102, 41, 10, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP CHECKBOX "&Groupe", 1703, 79, 92, 32, 10, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - CHECKBOX "Arrêter &Tab", 1704, 79, 102, 44, 10, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + CHECKBOX "&Tabulation", 1704, 79, 102, 44, 10, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP PUSHBUTTON "Accepter", IDOK, 37, 125, 40, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP PUSHBUTTON "Annuler", IDCANCEL, 93, 125, 40, 14, BS_PUSHBUTTON | WS_GROUP | WS_TABSTOP - CHECKBOX "Dé&sactiver Non-Déplac.", 1708, 79, 60, 66, 10, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + CHECKBOX "Dé&sactiver non-défil.", 1708, 79, 60, 66, 10, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP END diff --git a/base/applications/regedit/framewnd.c b/base/applications/regedit/framewnd.c index e22f383d97092..95f5cf9e9ecff 100644 --- a/base/applications/regedit/framewnd.c +++ b/base/applications/regedit/framewnd.c @@ -1446,7 +1446,8 @@ LRESULT CALLBACK FrameWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa // For now, the Help dialog item is disabled because of lacking of HTML Help support EnableMenuItem(GetMenu(hWnd), ID_HELP_HELPTOPICS, MF_BYCOMMAND | MF_GRAYED); GetClientRect(hWnd, &rc); - CreateWindowExW(0, szChildClass, NULL, WS_CHILD | WS_VISIBLE, + CreateWindowExW(0, szChildClass, NULL, + WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, hWnd, (HMENU)0, hInst, 0); break; diff --git a/base/applications/regedit/treeview.c b/base/applications/regedit/treeview.c index dcb6ce350dfc8..ca784f12e6c00 100644 --- a/base/applications/regedit/treeview.c +++ b/base/applications/regedit/treeview.c @@ -668,6 +668,8 @@ BOOL TreeWndNotifyProc(HWND hWnd, WPARAM wParam, LPARAM lParam, BOOL *Result) case TVN_BEGINLABELEDIT: { LPNMTVDISPINFO ptvdi = (LPNMTVDISPINFO)lParam; + HWND hWndFocus = GetFocus(); + /* cancel label edit for rootkeys */ if (!TreeView_GetParent(g_pChildWnd->hTreeWnd, ptvdi->item.hItem) || !TreeView_GetParent(g_pChildWnd->hTreeWnd, TreeView_GetParent(g_pChildWnd->hTreeWnd, ptvdi->item.hItem))) @@ -678,6 +680,12 @@ BOOL TreeWndNotifyProc(HWND hWnd, WPARAM wParam, LPARAM lParam, BOOL *Result) { *Result = FALSE; } + + /* cancel label edit if VK_DELETE accelerator opened a MessageBox */ + if (hWndFocus != g_pChildWnd->hTreeWnd && hWndFocus != TreeView_GetEditControl(g_pChildWnd->hTreeWnd)) + { + *Result = TRUE; + } return TRUE; } case TVN_ENDLABELEDIT: diff --git a/base/applications/screensavers/3dtext/rsrc.rc b/base/applications/screensavers/3dtext/rsrc.rc index f0550ade8fe9d..1417b27763a47 100644 --- a/base/applications/screensavers/3dtext/rsrc.rc +++ b/base/applications/screensavers/3dtext/rsrc.rc @@ -6,7 +6,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL -IDI_ICON ICON DISCARDABLE "res/icon_3dtext.ico" +IDI_ICON ICON "res/icon_3dtext.ico" #define REACTOS_VERSION_DLL #define REACTOS_STR_FILE_DESCRIPTION "OpenGL 3DText ScreenSaver" diff --git a/base/applications/screensavers/logon/logon.rc b/base/applications/screensavers/logon/logon.rc index 710bb93ec0a7b..061340fd299f7 100644 --- a/base/applications/screensavers/logon/logon.rc +++ b/base/applications/screensavers/logon/logon.rc @@ -6,7 +6,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL -IDI_ICON ICON DISCARDABLE "res/icon_logon.ico" +IDI_ICON ICON "res/icon_logon.ico" #define REACTOS_VERSION_DLL #define REACTOS_STR_FILE_DESCRIPTION "ReactOS Logon ScreenSaver" diff --git a/base/applications/shutdown/lang/ja-JP.rc b/base/applications/shutdown/lang/ja-JP.rc index 9fcfe5e2c2328..52141dc88fbe0 100644 --- a/base/applications/shutdown/lang/ja-JP.rc +++ b/base/applications/shutdown/lang/ja-JP.rc @@ -3,101 +3,103 @@ LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT /* Dialog */ IDD_GUI DIALOGEX 0, 0, 240, 255 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Remote Shutdown" +CAPTION "遠隔シャットダウン" FONT 9, "MS UI Gothic" BEGIN DEFPUSHBUTTON "&OK", IDC_OK, 125, 232, 50, 14 - PUSHBUTTON "&Cancel", IDC_CANCEL, 178, 232, 50, 14 - LTEXT "Co&mputers:", IDC_STATIC, 9, 9, 35, 36 + PUSHBUTTON "キャンセル(&C)", IDC_CANCEL, 178, 232, 50, 14 + LTEXT "コンピュータ(&M):", IDC_STATIC, 9, 9, 35, 36 LISTBOX IDC_COMPUTER_LIST, 8, 19, 162, 55 - PUSHBUTTON "&Add...", IDC_ADD_SYSTEM, 179, 19, 50, 14 - PUSHBUTTON "&Remove", IDC_REMOVE_SYSTEM, 179, 36, 50, 14, WS_DISABLED - PUSHBUTTON "&Browse...", IDC_BROWSE_SYSTEM, 179, 53, 50, 14 - LTEXT "Action", IDC_ACTION, 11, 81, 20, 14 + PUSHBUTTON "追加(&A)...", IDC_ADD_SYSTEM, 179, 19, 50, 14 + PUSHBUTTON "削除(&R)", IDC_REMOVE_SYSTEM, 179, 36, 50, 14, WS_DISABLED + PUSHBUTTON "参照(&B)...", IDC_BROWSE_SYSTEM, 179, 53, 50, 14 + LTEXT "アクション", IDC_ACTION, 11, 81, 20, 14 COMBOBOX IDC_ACTION_TYPE, 37, 79, 129, 14, WS_TABSTOP | CBS_DROPDOWN - CHECKBOX "Warn users", IDC_WARN_USERS, 175, 79, 55, 14, BS_AUTOCHECKBOX | WS_TABSTOP - LTEXT "Display warning for", IDC_SHOW_WARN_ONE, 11, 99, 65, 14 + CHECKBOX "ユーザーに警告", IDC_WARN_USERS, 175, 79, 55, 14, BS_AUTOCHECKBOX | WS_TABSTOP + LTEXT "次の間、警告を表示する", IDC_SHOW_WARN_ONE, 11, 99, 65, 14 EDITTEXT IDC_SHOW_WARN, 78, 97, 41, 14 - LTEXT "second(s)", IDC_SHOW_WARN_TWO, 124, 99, 32, 10 - GROUPBOX "Shutdown Event Tracker", IDC_STATIC, 5, 114, 224, 114 - LTEXT "Reason:", IDC_STATIC, 16, 130, 27, 8 - CHECKBOX "Planned", IDC_PLANNED, 175, 130, 40, 12, BS_AUTOCHECKBOX | WS_TABSTOP + LTEXT "秒間", IDC_SHOW_WARN_TWO, 124, 99, 32, 10 + GROUPBOX "シャットダウン イベント記録", IDC_STATIC, 5, 114, 224, 114 + LTEXT "理由:", IDC_STATIC, 16, 130, 27, 8 + CHECKBOX "予定済み", IDC_PLANNED, 175, 130, 40, 12, BS_AUTOCHECKBOX | WS_TABSTOP COMBOBOX IDC_REASON_CODE, 17, 142, 198, 13, WS_TABSTOP | CBS_DROPDOWN - LTEXT "Comm&ent:", IDC_COMMENT_CAPTION, 16, 159, 38, 8 + LTEXT "コメント(&E):", IDC_COMMENT_CAPTION, 16, 159, 38, 8 EDITTEXT IDC_COMMENT_TEXT, 17, 171, 198, 50, WS_VSCROLL END /* Information and error messages */ STRINGTABLE BEGIN - IDS_USAGE "ReactOS Shutdown Utility\n\ + IDS_USAGE "ReactOS シャットダウン ユーティリティ\n\ \n\ -Usage: shutdown [/?] [/i | /l | /s | /r | /g | /a | /p | /h | /e] [/f]\n\ - [/m \\\\computer][/t xxx][/d [p|u:]xx:yy [/c ""comment""]]\n\ +使い方: shutdown [/?] [/i | /l | /s | /r | /g | /a | /p | /h | /e] [/f]\n\ + [/m \\\\コンピュータ][/t xxx][/d [p|u:]xx:yy [/c ""コメント""]]\n\ \n\ - No arguments or /? Display this help.\n\ - /i Show the graphical user interface (GUI). This option must be the\n\ - first one.\n\ - /l Log off on the local system only. Cannot be used with /m or /d.\n\ - /s Shutdown the computer.\n\ - /r Restart the computer.\n\ - /g Restart the computer and restart all the registered applications.\n\ - /a Cancel a delayed shutdown. Can only be used during the delay\n\ - period.\n\ - /p Shutdown the local computer without any timeout or warning. Can be\n\ - used with /d or /f.\n\ - /h Hibernate the local computer. Usable with /f.\n\ - /e Document the reason for the unexpected computer shutdown.\n\ - /m \\\\computer Specify the target computer (UNC/IP address).\n\ - /t xxx Set the timeout period to xxx seconds before shutting down.\n\ - The valid range starts from 0 to 315360000 (10 years),\n\ - 30 being the default value.\n\ - /c ""comment"" Comment on the reason for shutdown or restart.\n\ - 512 characters maximum allowed.\n\ - /f Force running applications to close without warning users. If you\n\ - do not specify any other parameter, this option will also log off.\n\ - /d [p|u:]xx:yy Give the reason code for the shutdown or the restart.\n\ - p indicates that the shutdown or the restart is planned.\n\ - u indicates that the reason is defined by the user.\n\ - If neither p nor u are specified, the shutdown or the restart are\n\ - not planned.\n\ - xx is the major reason code (positive integer smaller than 256).\n\ - yy is the minor reason code (positive integer smaller than 65536).\n" + 引数なし または /? このヘルプを表示します。\n\ + /i グラフィカル ユーザー インターフェイス (GUI) を表示します。\n\ + このオプションは最初のオプションである必要があります。\n\ + /l ローカル システムのみでログオフします。/m または /d と一緒に\n\ + 使用することはできません。\n\ + /s コンピュータをシャットダウンします。\n\ + /r コンピュータを再起動します。\n\ + /g コンピュータを再起動し、登録されているすべてのアプリケーションを\n\ + 再起動します。\n\ + /a 遅延シャットダウンをキャンセルします。遅延期間中のみ使用できます。\n\ + /p タイムアウトや警告なしでローカル コンピューターをシャットダウン\n\ + します。/d または /f と一緒に使用できます。\n\ + /h ローカル コンピューターを休止状態にします。/f で使用できます。\n\ + /e 予期しないコンピュータのシャットダウンの理由を記録します。\n\ + /m \\\\コンピュータ 対象コンピュータを指定する (UNC/IP アドレス).\n\ + /t xxx シャットダウンする前にタイムアウト期間を xxx 秒に設定します。\n\ + 有効範囲は0から315360000(10年)までです。\n\ + デフォルト値は 30 です。\n\ + /c ""コメント"" シャットダウンまたは再起動の理由をコメントします。\n\ + 最大 512 文字まで入力できます。\n\ + /f ユーザーに警告せずに実行中のアプリケーションを強制的に終了\n\ + します。 他のパラメータを指定しない場合は、このオプションでも\n\ + ログオフされます。\n\ + /d [p|u:]xx:yy シャットダウンまたは再起動の理由コードを指定します。\n\ + p はシャットダウンまたは再起動が予定されていることを示します。\n\ + u は、理由がユーザーによって定義されていることを示します。\n\ + p も u も指定されていない場合は、シャットダウンまたは再起動は\n\ + 予定されていません。\n\ + xx はメジャーな理由コードです (256 未満の正の整数)。\n\ + yy はマイナーな理由コードです (65536 未満の正の整数)。\n" - IDS_ERROR_SHUTDOWN_REBOOT "ERROR: Unable to shutdown and restart at the same time.\n" - IDS_ERROR_TIMEOUT "ERROR: Timeout value of %u is out of bounds (0-315360000).\n" - IDS_ERROR_ABORT "ERROR: Unable to abort the shutdown of the system.\n" - IDS_ERROR_LOGOFF "ERROR: Unable to logoff the system.\n" - IDS_ERROR_SHUTDOWN "ERROR: Unable to shutdown the system.\n" - IDS_ERROR_RESTART "ERROR: Unable to restart the system.\n" - IDS_ERROR_MAX_COMMENT_LENGTH "ERROR: Comment length exceeds maximum character limit set by the system.\n" - IDS_ERROR_HIBERNATE "ERROR: Unable to send system into hibernation mode.\n" - IDS_ERROR_HIBERNATE_LOCAL "ERROR: Hibernation mode cannot be started remotely.\n" - IDS_ERROR_HIBERNATE_ENABLED "ERROR: Hibernation mode is not enabled.\n" - IDS_ERROR_DIALOG_CAPTION "Remote Shutdown" - IDS_ERROR_DIALOG_INIT "Unable to display the graphical user interface." + IDS_ERROR_SHUTDOWN_REBOOT "エラー: シャットダウンと再起動を同時に行うことはできません。\n" + IDS_ERROR_TIMEOUT "エラー: %u のタイムアウト値は範囲外です (0~315360000).\n" + IDS_ERROR_ABORT "エラー: システムのシャットダウンを中止できません。\n" + IDS_ERROR_LOGOFF "エラー: システムからログオフできません。\n" + IDS_ERROR_SHUTDOWN "エラー: システムをシャットダウンできません。\n" + IDS_ERROR_RESTART "エラー: システムを再起動できません。\n" + IDS_ERROR_MAX_COMMENT_LENGTH "エラー: コメントの長さがシステムで設定された最大文字数制限を超えています。\n" + IDS_ERROR_HIBERNATE "エラー: システムを休止モードにできません。\n" + IDS_ERROR_HIBERNATE_LOCAL "エラー: 休止モードは遠隔で起動できません。\n" + IDS_ERROR_HIBERNATE_ENABLED "エラー: 休止モードが有効になっていません。\n" + IDS_ERROR_DIALOG_CAPTION "遠隔シャットダウン" + IDS_ERROR_DIALOG_INIT "グラフィカル ユーザー インターフェイスを表示できません。" END /* Remote shutdown action strings */ STRINGTABLE BEGIN - IDS_ACTION_SHUTDOWN "Shutdown the system" - IDS_ACTION_RESTART "Restart the system" - IDS_ACTION_UNEXPECTED_SHUTDOWN "Annotate the unexpected shutdown" + IDS_ACTION_SHUTDOWN "システムをシャットダウンする" + IDS_ACTION_RESTART "システムを再起動する" + IDS_ACTION_UNEXPECTED_SHUTDOWN "予期しないシャットダウンを注釈する" END /* Remote shutdown reason strings */ STRINGTABLE BEGIN - IDS_REASON_OTHER "Other" - IDS_REASON_HARDWARE_MAINTENANCE "Hardware: Maintenance" - IDS_REASON_HARDWARE_INSTALL "Hardware: Installation" - IDS_REASON_OS_RECOVER "Operating System: Recovery" - IDS_REASON_OS_RECONFIGURE "Operating System: Reconfigure" - IDS_REASON_APP_MAINTENANCE "Application: Maintenance" - IDS_REASON_APP_INSTALL "Application: Installation" - IDS_REASON_APP_UNRESPONSIVE "Application: Unresponsive" - IDS_REASON_APP_UNSTABLE "Application: Unstable" - IDS_REASON_SECURITY "Security Issue" - IDS_REASON_NETWORK "Loss of network connectivity" + IDS_REASON_OTHER "その他" + IDS_REASON_HARDWARE_MAINTENANCE "ハードウェア: メンテナンス" + IDS_REASON_HARDWARE_INSTALL "ハードウェア: インストール" + IDS_REASON_OS_RECOVER "オペレーティングシステム: 回復" + IDS_REASON_OS_RECONFIGURE "オペレーティングシステム: 再構成" + IDS_REASON_APP_MAINTENANCE "アプリケーション: メンテナンス" + IDS_REASON_APP_INSTALL "アプリケーション: インストール" + IDS_REASON_APP_UNRESPONSIVE "アプリケーション: 応答なし" + IDS_REASON_APP_UNSTABLE "アプリケーション: 不安定" + IDS_REASON_SECURITY "セキュリティの問題" + IDS_REASON_NETWORK "ネットワーク接続の喪失" END diff --git a/base/applications/sndvol32/lang/fr-FR.rc b/base/applications/sndvol32/lang/fr-FR.rc index 43e34f08fcb15..cb80adfc70814 100644 --- a/base/applications/sndvol32/lang/fr-FR.rc +++ b/base/applications/sndvol32/lang/fr-FR.rc @@ -58,7 +58,7 @@ BEGIN LTEXT "Volume", -1, 4, 58, 80, 8 CONTROL "", IDC_LINE_SLIDER_VERT, "msctls_trackbar32", TBS_VERT | TBS_BOTH | TBS_DOWNISLEFT | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 32, 67, 30, 56 AUTOCHECKBOX "&Muet", IDC_LINE_SWITCH, 4, 123, 55, 12 - PUSHBUTTON "&Advanced", IDC_LINE_ADVANCED, 4, 138, 80, 14 + PUSHBUTTON "&Avancé", IDC_LINE_ADVANCED, 4, 138, 80, 14 CONTROL "", IDC_LINE_SEP, "static", SS_ETCHEDVERT | WS_CHILD | WS_VISIBLE, 90, 1, 1, 137 END @@ -75,7 +75,7 @@ BEGIN LTEXT "Volume", -1, 4, 58, 60, 8 CONTROL "", IDC_LINE_SLIDER_VERT, "msctls_trackbar32", TBS_VERT | TBS_BOTH | TBS_DOWNISLEFT | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 20, 67, 30, 56 AUTOCHECKBOX "&Muet", IDC_LINE_SWITCH, 4, 123, 55, 12 - PUSHBUTTON "&Advanced", IDC_LINE_ADVANCED, 7, 138, 55, 14 + PUSHBUTTON "&Avancé", IDC_LINE_ADVANCED, 7, 138, 55, 14 CONTROL "", IDC_LINE_SEP, "static", SS_ETCHEDVERT | WS_CHILD | WS_VISIBLE, 70, 25, 1, 113 END @@ -118,7 +118,7 @@ FONT 8, "MS Shell Dlg" BEGIN CONTROL IDI_MAINAPP, -1, "static", SS_ICON | WS_CHILD | WS_VISIBLE, 7, 7, 32, 32 LTEXT "Ces paramètres peuvent être utilisés pour des ajustements fins de l'audio.", -1, 44, 7, 200, 32 - GROUPBOX "Contrôles du ton", IDC_ADV_TONE_CONTROLS, 7, 33, 240, 80 + GROUPBOX "Contrôles de tonalité", IDC_ADV_TONE_CONTROLS, 7, 33, 240, 80 LTEXT "Ces paramètres contrôlent la tonalité de l'audio.", -1, 17, 48, 200, 14 LTEXT "&Basses :", -1, 17, 62, 50, 8 LTEXT "Bas", IDC_ADV_BASS_LOW, 77, 62, 20, 8 diff --git a/base/applications/sndvol32/lang/ja-JP.rc b/base/applications/sndvol32/lang/ja-JP.rc index ef570f945a930..4603c21fafb21 100644 --- a/base/applications/sndvol32/lang/ja-JP.rc +++ b/base/applications/sndvol32/lang/ja-JP.rc @@ -7,7 +7,7 @@ BEGIN MENUITEM "プロパティ(&R)", IDM_PROPERTIES MENUITEM "トーン調整(&A)", IDM_ADVANCED_CONTROLS MENUITEM SEPARATOR - MENUITEM "ボリューム コントロールの終了(&X)", IDM_EXIT + MENUITEM "音量調整の終了(&X)", IDM_EXIT END POPUP "ヘルプ(&H)" BEGIN @@ -19,10 +19,10 @@ END STRINGTABLE BEGIN - IDS_SNDVOL32 "ボリューム コントロール" + IDS_SNDVOL32 "音量調整" IDS_NOMIXERDEVICES "アクティブなミキサーが利用できません ! アプリケーションを終了します。" IDS_SELECT "&Select" - IDS_ADVANCED_CONTROLS "Advanced Controls for %s" + IDS_ADVANCED_CONTROLS "%s の高度な調整" IDS_OTHER_CONTROLS1 "&1 %s" IDS_OTHER_CONTROLS2 "&2 %s" END @@ -49,16 +49,16 @@ IDD_NORMAL_MASTER DIALOG 0, 0, 90, 138 STYLE WS_POPUP | WS_BORDER FONT 9, "MS UI Gothic" BEGIN - LTEXT "Master", IDC_LINE_NAME, 4, 7, 78, 8 + LTEXT "マスター", IDC_LINE_NAME, 4, 7, 78, 8 CONTROL "", -1, "static", SS_ETCHEDHORZ | WS_CHILD | WS_VISIBLE, 4, 19, 82, 1 - LTEXT "Balance", -1, 4, 25, 80, 8 + LTEXT "バランス", -1, 4, 25, 80, 8 CONTROL "", IDC_LINE_SLIDER_HORZ, "msctls_trackbar32", TBS_HORZ | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 25, 35, 40, 17 ICON IDI_SPEAKER_RIGHT, -1, 14, 38, 10, 10, SS_REALSIZEIMAGE ICON IDI_SPEAKER_LEFT, -1, 66, 38, 10, 10, SS_REALSIZEIMAGE - LTEXT "Volume", -1, 4, 58, 80, 8 + LTEXT "音量", -1, 4, 58, 80, 8 CONTROL "", IDC_LINE_SLIDER_VERT, "msctls_trackbar32", TBS_VERT | TBS_BOTH | TBS_DOWNISLEFT | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 32, 67, 30, 56 - AUTOCHECKBOX "&Mute", IDC_LINE_SWITCH, 4, 123, 55, 12 - PUSHBUTTON "&Advanced", IDC_LINE_ADVANCED, 4, 138, 80, 14 + AUTOCHECKBOX "消音(&M)", IDC_LINE_SWITCH, 4, 123, 55, 12 + PUSHBUTTON "詳細(&A)", IDC_LINE_ADVANCED, 4, 138, 80, 14 CONTROL "", IDC_LINE_SEP, "static", SS_ETCHEDVERT | WS_CHILD | WS_VISIBLE, 90, 1, 1, 137 END @@ -66,16 +66,16 @@ IDD_NORMAL_LINE DIALOG 0, 0, 70, 138 STYLE WS_POPUP | WS_BORDER FONT 9, "MS UI Gothic" BEGIN - LTEXT "Line", IDC_LINE_NAME, 4, 7, 60, 8 + LTEXT "ライン", IDC_LINE_NAME, 4, 7, 60, 8 CONTROL "", -1, "static", SS_ETCHEDHORZ | WS_CHILD | WS_VISIBLE, 4, 19, 72, 1 - LTEXT "Balance", -1, 4, 25, 60, 8 + LTEXT "バランス", -1, 4, 25, 60, 8 CONTROL "", IDC_LINE_SLIDER_HORZ, "msctls_trackbar32", TBS_HORZ | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 15, 35, 40, 17 ICON IDI_SPEAKER_RIGHT, -1, 4, 38, 10, 10, SS_REALSIZEIMAGE ICON IDI_SPEAKER_LEFT, -1, 56, 38, 10, 10, SS_REALSIZEIMAGE - LTEXT "Volume", -1, 4, 58, 60, 8 + LTEXT "音量", -1, 4, 58, 60, 8 CONTROL "", IDC_LINE_SLIDER_VERT, "msctls_trackbar32", TBS_VERT | TBS_BOTH | TBS_DOWNISLEFT | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 20, 67, 30, 56 - AUTOCHECKBOX "&Mute", IDC_LINE_SWITCH, 4, 123, 55, 12 - PUSHBUTTON "&Advanced", IDC_LINE_ADVANCED, 7, 138, 55, 14 + AUTOCHECKBOX "消音(&M)", IDC_LINE_SWITCH, 4, 123, 55, 12 + PUSHBUTTON "詳細(&A)", IDC_LINE_ADVANCED, 7, 138, 55, 14 CONTROL "", IDC_LINE_SEP, "static", SS_ETCHEDVERT | WS_CHILD | WS_VISIBLE, 70, 25, 1, 113 END @@ -83,10 +83,10 @@ IDD_SMALL_MASTER DIALOG 0, 0, 45, 100 STYLE WS_POPUP | WS_BORDER FONT 9, "MS UI Gothic" BEGIN - CTEXT "Master", IDC_LINE_NAME, 3, 3, 39, 8 + CTEXT "マスター", IDC_LINE_NAME, 3, 3, 39, 8 CONTROL "", IDC_LINE_SLIDER_HORZ, "msctls_trackbar32", TBS_HORZ | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 2, 12, 39, 18 CONTROL "", IDC_LINE_SLIDER_VERT, "msctls_trackbar32", TBS_VERT | TBS_BOTH | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 8, 30, 30, 50 - AUTOCHECKBOX "&Mute", IDC_LINE_SWITCH, 1, 85, 44, 10 + AUTOCHECKBOX "消音(&M)", IDC_LINE_SWITCH, 1, 85, 44, 10 CONTROL "", IDC_LINE_SEP, "static", SS_ETCHEDVERT | WS_CHILD | WS_VISIBLE, 45, 1, 1, 100 END @@ -94,10 +94,10 @@ IDD_SMALL_LINE DIALOG 0, 0, 42, 100 STYLE WS_POPUP | WS_BORDER FONT 9, "MS UI Gothic" BEGIN - CTEXT "Line", IDC_LINE_NAME, 3, 3, 39, 8 + CTEXT "ライン", IDC_LINE_NAME, 3, 3, 39, 8 CONTROL "", IDC_LINE_SLIDER_HORZ, "msctls_trackbar32", TBS_HORZ | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 2, 12, 39, 18 CONTROL "", IDC_LINE_SLIDER_VERT, "msctls_trackbar32", TBS_VERT | TBS_BOTH | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 8, 30, 30, 50 - AUTOCHECKBOX "&Mute", IDC_LINE_SWITCH, 1, 85, 41, 10 + AUTOCHECKBOX "消音(&M)", IDC_LINE_SWITCH, 1, 85, 41, 10 CONTROL "", IDC_LINE_SEP, "static", SS_ETCHEDVERT | WS_CHILD | WS_VISIBLE, 42, 1, 1, 100 END @@ -106,31 +106,31 @@ STYLE DS_MODALFRAME | WS_POPUP EXSTYLE WS_EX_TOOLWINDOW FONT 9, "MS UI Gothic" BEGIN - CTEXT "Volume", -1, 0, 4, 50, 8 + CTEXT "音量", -1, 0, 4, 50, 8 CONTROL "", IDC_LINE_SLIDER_VERT, "msctls_trackbar32", TBS_VERT | TBS_BOTH | TBS_NOTICKS | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 16, 15, 20, 50 - AUTOCHECKBOX "&Mute", IDC_LINE_SWITCH, 4, 70, 44, 8 + AUTOCHECKBOX "消音(&M)", IDC_LINE_SWITCH, 4, 70, 44, 8 END IDD_ADVANCED DIALOGEX 0, 0, 255, 140 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU -CAPTION "Advanced Controls for Volume Control" +CAPTION "音量調整の高度な調整" FONT 9, "MS UI Gothic" BEGIN CONTROL IDI_MAINAPP, -1, "static", SS_ICON | WS_CHILD | WS_VISIBLE, 7, 7, 32, 32 - LTEXT "These settings can be used to make fine adjustments to your audio.", -1, 44, 7, 200, 32 - GROUPBOX "Tone Controls", IDC_ADV_TONE_CONTROLS, 7, 33, 240, 80 - LTEXT "These settings control how the tone of your audio sounds.", -1, 17, 48, 200, 14 - LTEXT "&Bass:", -1, 17, 62, 50, 8 - LTEXT "Low", IDC_ADV_BASS_LOW, 77, 62, 20, 8 - LTEXT "High", IDC_ADV_BASS_HIGH, 182, 62, 20, 8 + LTEXT "これらの設定を使用して、音声を調整できます。", -1, 44, 7, 200, 32 + GROUPBOX "音色の調整", IDC_ADV_TONE_CONTROLS, 7, 33, 240, 80 + LTEXT "これらの設定は、音声の音色を制御します。", -1, 17, 48, 200, 14 + LTEXT "低音(&B):", -1, 17, 62, 50, 8 + LTEXT "低い", IDC_ADV_BASS_LOW, 77, 62, 20, 8 + LTEXT "高い", IDC_ADV_BASS_HIGH, 182, 62, 20, 8 CONTROL "", IDC_ADV_BASS_SLIDER, "msctls_trackbar32", TBS_HORZ | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 97, 62, 80, 20 - LTEXT "&Treble:", -1, 17, 90, 50, 8 - LTEXT "Low", IDC_ADV_TREBLE_LOW, 77, 90, 20, 8 - LTEXT "High", IDC_ADV_TREBLE_HIGH, 182, 90, 20, 8 + LTEXT "高音域(&T):", -1, 17, 90, 50, 8 + LTEXT "低い", IDC_ADV_TREBLE_LOW, 77, 90, 20, 8 + LTEXT "高い", IDC_ADV_TREBLE_HIGH, 182, 90, 20, 8 CONTROL "", IDC_ADV_TREBLE_SLIDER, "msctls_trackbar32", TBS_HORZ | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 97, 90, 80, 20 - GROUPBOX "Other Controls", IDC_ADV_OTHER_CONTROLS, 7, 119, 240, 66 - LTEXT "These settings make other changes to how your audio sounds. See your hardware documentation for details.", IDC_ADV_OTHER_TEXT, 17, 135, 220, 28 + GROUPBOX "その他の調整", IDC_ADV_OTHER_CONTROLS, 7, 119, 240, 66 + LTEXT "これらの設定により、音声に他の変更が加えられます。詳細については、ハードウェアの文書を参照してください。", IDC_ADV_OTHER_TEXT, 17, 135, 220, 28 AUTOCHECKBOX "&1 ", IDC_ADV_OTHER_CHECK1, 17, 159, 220, 14 AUTOCHECKBOX "&2 ", IDC_ADV_OTHER_CHECK2, 17, 174, 220, 14 - DEFPUSHBUTTON "Close", IDOK, 197, 120, 50, 14, WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP + DEFPUSHBUTTON "閉じる", IDOK, 197, 120, 50, 14, WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP END diff --git a/base/applications/taskmgr/lang/fr-FR.rc b/base/applications/taskmgr/lang/fr-FR.rc index ed8e3cfe49b1f..e603240519de9 100644 --- a/base/applications/taskmgr/lang/fr-FR.rc +++ b/base/applications/taskmgr/lang/fr-FR.rc @@ -322,7 +322,7 @@ END STRINGTABLE BEGIN ID_FILE_NEW "Exécute un nouveau programme" - ID_OPTIONS_ALWAYSONTOP "Le Gestionnaire des tâches reste devant toutes les autres fenêtre à moins d'être réduit" + ID_OPTIONS_ALWAYSONTOP "Le Gestionnaire des tâches reste devant toutes les autres fenêtres à moins d'être réduit" ID_OPTIONS_MINIMIZEONUSE "Le Gestionnaire des tâches est réduite lorqu'une action Basculer vers est réalisée" ID_OPTIONS_HIDEWHENMINIMIZED "Masquer le Gestionnaire des tâches lorsqu'il est réduit" ID_VIEW_REFRESH "Actualise l'affichage maintenant, sans tenir compte de la fréquence d'actualisation" @@ -347,7 +347,7 @@ BEGIN ID_HELP_ABOUT "Affiche les information sur le programme, la version et le copyright" ID_FILE_EXIT "Quitte l'application Gestionnaire des tâches" ID_OPTIONS_SHOW16BITTASKS "Affiche les tâches 16-bits sous le ntvdm.exe associé" - ID_VIEW_SELECTCOLUMNS "Sélectionne quelles colonnes seront affichés dans la page des processus" + ID_VIEW_SELECTCOLUMNS "Sélectionne quelles colonnes seront affichées dans la page des processus" ID_VIEW_SHOWKERNELTIMES "Affiche les temps du noyau dans les graphiques de performances" ID_VIEW_CPUHISTORY_ONEGRAPHALL "Un seul graphique montre l'usage de tous les UC" ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU "Chaque UC a son propre graphique" @@ -362,7 +362,7 @@ BEGIN ID_PROCESS_PAGE_ENDPROCESS "Enlève le processus du système" ID_PROCESS_PAGE_ENDPROCESSTREE "Enlève ce processus et tous ses descendants du système" ID_PROCESS_PAGE_DEBUG "Attache le débogueur à ce processus" - ID_PROCESS_PAGE_SETAFFINITY "Contrôle le processeur sur lequel le processus sera autorisé de s'exécuter" + ID_PROCESS_PAGE_SETAFFINITY "Contrôle le processeur sur lequel le processus sera autorisé à s'exécuter" ID_PROCESS_PAGE_SETPRIORITY_REALTIME "Place le processus dans la priorité TEMPS RÉEL" ID_PROCESS_PAGE_SETPRIORITY_HIGH "Place le processus dans la priorité HAUTE" ID_PROCESS_PAGE_SETPRIORITY_ABOVENORMAL "Place le processus dans la priorité SUPÉRIEURE À LA NORMALE" @@ -418,7 +418,7 @@ BEGIN IDS_MENU_SHOWKERNELTIMES "Aff&icher les temps du noyau" IDS_CREATENEWTASK "Créer une nouvelle tâche" IDS_CREATENEWTASK_DESC "Entrez le nom d'un programme, d'un dossier, d'un document ou d'une ressource Internet, et le Gestionnaire des tâches l'ouvrira pour vous." - IDS_MSG_ACCESSPROCESSAFF "Impossible d'accéder ou de mofier l'affinité du processeur." + IDS_MSG_ACCESSPROCESSAFF "Impossible d'accéder ou de modifier l'affinité du processeur." IDS_MSG_PROCESSONEPRO "Le processus doit avoir de l'affinité avec au moins un processeur." IDS_MSG_INVALIDOPTION "Option Invalide" IDS_MSG_UNABLEDEBUGPROCESS "Impossible de déboguer le processus." diff --git a/base/applications/taskmgr/taskmgr.c b/base/applications/taskmgr/taskmgr.c index 686abc37352ba..6ae907df366cb 100644 --- a/base/applications/taskmgr/taskmgr.c +++ b/base/applications/taskmgr/taskmgr.c @@ -38,7 +38,7 @@ TASKMANAGER_SETTINGS TaskManagerSettings; //////////////////////////////////////////////////////////////////////////////// // Taken from WinSpy++ 1.7 -// http://www.catch22.net/software/winspy +// https://www.catch22.net/projects/winspy/ // Copyright (c) 2002 by J Brown // diff --git a/base/applications/winhlp32/CMakeLists.txt b/base/applications/winhlp32/CMakeLists.txt index 1e2b6148442f8..11dfe6d56a20d 100644 --- a/base/applications/winhlp32/CMakeLists.txt +++ b/base/applications/winhlp32/CMakeLists.txt @@ -1,8 +1,5 @@ -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) - add_definitions( - -D__WINESRC__ -D__ROS_LONG64__ -Dstrcasecmp=_stricmp ) @@ -31,3 +28,4 @@ target_link_libraries(winhlp32 wine oldnames) add_importlibs(winhlp32 user32 gdi32 shell32 comctl32 comdlg32 msvcrt kernel32 ntdll) add_pch(winhlp32 precomp.h "${PCH_SKIP_SOURCE}") add_cd_file(TARGET winhlp32 DESTINATION reactos FOR all) +set_wine_module_FIXME(winhlp32) # CORE-5743: No ARRAY_SIZE macro diff --git a/base/applications/winver/CMakeLists.txt b/base/applications/winver/CMakeLists.txt index ac5b762b83ddd..9837665d4e517 100644 --- a/base/applications/winver/CMakeLists.txt +++ b/base/applications/winver/CMakeLists.txt @@ -1,5 +1,11 @@ -add_executable(winver winver.c winver.rc) +list(APPEND SOURCE + osinfo.c + winver.c + winver_p.h) + +add_executable(winver ${SOURCE} winver.rc) +add_pch(winver winver_p.h SOURCE) set_module_type(winver win32gui UNICODE) -add_importlibs(winver shell32 comctl32 msvcrt kernel32) +add_importlibs(winver advapi32 user32 shell32 comctl32 msvcrt kernel32) add_cd_file(TARGET winver DESTINATION reactos/system32 FOR all) diff --git a/base/applications/winver/lang/en-US.rc b/base/applications/winver/lang/en-US.rc new file mode 100644 index 0000000000000..d4ec8dd84d9db --- /dev/null +++ b/base/applications/winver/lang/en-US.rc @@ -0,0 +1,14 @@ +/* + * PROJECT: ReactOS Version Program + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: English (United States) resource file + * TRANSLATOR: Copyright 2025 Thamatip Chitpong + */ + +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +STRINGTABLE +BEGIN + IDS_OSINFO_COMPAT_FORMAT "Reporting NT %s (Build %s%s)" + IDS_OSINFO_SPK_FORMAT ": %s" +END diff --git a/base/applications/winver/osinfo.c b/base/applications/winver/osinfo.c new file mode 100644 index 0000000000000..ff79baa3aab9f --- /dev/null +++ b/base/applications/winver/osinfo.c @@ -0,0 +1,126 @@ +/* + * PROJECT: ReactOS Version Program + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: Retrieve OS name and simple compatibility information + * COPYRIGHT: Copyright 2025 Thamatip Chitpong + */ + +#include "winver_p.h" + +#define OSINFO_KEY L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion" + +static +VOID +Winver_GetRegValueString( + _In_ HKEY hKey, + _In_ LPCWSTR pValue, + _Out_ LPWSTR pBuffer, + _In_ DWORD cchSize) +{ + DWORD dwType, dwSize; + LSTATUS lError; + + /* NOTE: Reserved space for a NULL terminator */ + dwSize = (cchSize - 1) * sizeof(WCHAR); + lError = RegQueryValueExW(hKey, pValue, NULL, &dwType, (LPBYTE)pBuffer, &dwSize); + if (lError != ERROR_SUCCESS || dwType != REG_SZ) + { + /* Return empty string on failure */ + pBuffer[0] = UNICODE_NULL; + return; + } + + /* Ensure the returned string is NULL terminated */ + pBuffer[cchSize - 1] = UNICODE_NULL; +} + +static +VOID +Winver_GetFormattedSpkInfo( + _In_ HKEY hKey, + _Out_ LPWSTR pBuffer, + _In_ DWORD cchSize) +{ + WCHAR szRegValue[48]; + WCHAR szFormat[16] = L""; + + Winver_GetRegValueString(hKey, L"CSDVersion", szRegValue, _countof(szRegValue)); + if (!szRegValue[0]) + { + /* Return empty string on failure */ + pBuffer[0] = UNICODE_NULL; + return; + } + + LoadStringW(Winver_hInstance, + IDS_OSINFO_SPK_FORMAT, + szFormat, + _countof(szFormat)); + + StringCchPrintfW(pBuffer, cchSize, szFormat, szRegValue); +} + +static +VOID +Winver_FormatCompatInfo( + _In_ HKEY hKey, + _Out_ LPWSTR pBuffer, + _In_ DWORD cchSize) +{ + WCHAR szNtVersion[16]; + WCHAR szNtBuild[16]; + WCHAR szNtSpk[64]; + WCHAR szFormat[64] = L""; + + /* NOTE: Required info must be valid */ + Winver_GetRegValueString(hKey, L"CurrentVersion", szNtVersion, _countof(szNtVersion)); + Winver_GetRegValueString(hKey, L"CurrentBuildNumber", szNtBuild, _countof(szNtBuild)); + if (!szNtVersion[0] || !szNtBuild[0]) + { + /* Return empty string on failure */ + pBuffer[0] = UNICODE_NULL; + return; + } + + /* NOTE: Service pack info is optional */ + Winver_GetFormattedSpkInfo(hKey, szNtSpk, _countof(szNtSpk)); + + LoadStringW(Winver_hInstance, + IDS_OSINFO_COMPAT_FORMAT, + szFormat, + _countof(szFormat)); + + StringCchPrintfW(pBuffer, cchSize, szFormat, szNtVersion, szNtBuild, szNtSpk); +} + +BOOL +Winver_GetOSInfo( + _Out_ PWINVER_OS_INFO OSInfo) +{ + HKEY hKey; + LSTATUS lError; + + lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, + OSINFO_KEY, + 0, + KEY_QUERY_VALUE, + &hKey); + if (lError != ERROR_SUCCESS) + return FALSE; + + /* OS name */ + Winver_GetRegValueString(hKey, L"ProductName", OSInfo->szName, _countof(OSInfo->szName)); + if (!OSInfo->szName[0]) + { + /* This info must be valid */ + RegCloseKey(hKey); + return FALSE; + } + + /* Compatibility information */ + Winver_FormatCompatInfo(hKey, OSInfo->szCompatInfo, _countof(OSInfo->szCompatInfo)); + + RegCloseKey(hKey); + + return TRUE; +} diff --git a/base/applications/winver/resource.h b/base/applications/winver/resource.h new file mode 100644 index 0000000000000..ca00ee8231417 --- /dev/null +++ b/base/applications/winver/resource.h @@ -0,0 +1,11 @@ +/* + * PROJECT: ReactOS Version Program + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: Resource header file + * COPYRIGHT: Copyright 2025 Thamatip Chitpong + */ + +#pragma once + +#define IDS_OSINFO_COMPAT_FORMAT 1 +#define IDS_OSINFO_SPK_FORMAT 2 diff --git a/base/applications/winver/winver.c b/base/applications/winver/winver.c index 1e22096c4eef7..3eb2a9e3adfda 100644 --- a/base/applications/winver/winver.c +++ b/base/applications/winver/winver.c @@ -4,26 +4,32 @@ * FILE: base/applications/winver/winver.c */ -#include -#include -#include -#include -#include -#include +#include "winver_p.h" + +HINSTANCE Winver_hInstance; int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) { INITCOMMONCONTROLSEX iccx; + WINVER_OS_INFO OSInfo; - UNREFERENCED_PARAMETER(hInstance); UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); UNREFERENCED_PARAMETER(nCmdShow); + Winver_hInstance = hInstance; + /* Initialize common controls */ - iccx.dwSize = sizeof(INITCOMMONCONTROLSEX); + iccx.dwSize = sizeof(iccx); iccx.dwICC = ICC_STANDARD_CLASSES | ICC_WIN95_CLASSES; InitCommonControlsEx(&iccx); - return ShellAboutW(NULL, L"ReactOS", NULL, NULL); + if (!Winver_GetOSInfo(&OSInfo)) + { + /* OS info is not available, display the default contents */ + StringCchCopyW(OSInfo.szName, _countof(OSInfo.szName), L"ReactOS"); + OSInfo.szCompatInfo[0] = UNICODE_NULL; + } + + return ShellAboutW(NULL, OSInfo.szName, OSInfo.szCompatInfo, NULL); } diff --git a/base/applications/winver/winver.rc b/base/applications/winver/winver.rc index 050ae69437015..1d9dec6f9d928 100644 --- a/base/applications/winver/winver.rc +++ b/base/applications/winver/winver.rc @@ -2,9 +2,18 @@ #include #include +#include "resource.h" + #define REACTOS_STR_FILE_DESCRIPTION "ReactOS Version Program" #define REACTOS_STR_INTERNAL_NAME "winver" #define REACTOS_STR_ORIGINAL_FILENAME "winver.exe" #include #include + +/* UTF-8 */ +#pragma code_page(65001) + +#ifdef LANGUAGE_EN_US + #include "lang/en-US.rc" +#endif diff --git a/base/applications/winver/winver_p.h b/base/applications/winver/winver_p.h new file mode 100644 index 0000000000000..b7b76ed5db9e5 --- /dev/null +++ b/base/applications/winver/winver_p.h @@ -0,0 +1,34 @@ +/* + * PROJECT: ReactOS Version Program + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: Main header file + * COPYRIGHT: Copyright 2025 Thamatip Chitpong + */ + +#pragma once + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "resource.h" + +typedef struct _WINVER_OS_INFO +{ + WCHAR szName[64]; + WCHAR szCompatInfo[256]; +} WINVER_OS_INFO, *PWINVER_OS_INFO; + +extern HINSTANCE Winver_hInstance; + +BOOL +Winver_GetOSInfo( + _Out_ PWINVER_OS_INFO OSInfo); diff --git a/base/applications/wordpad/lang/fr-FR.rc b/base/applications/wordpad/lang/fr-FR.rc index 043616bbcc743..28c1669770fb7 100644 --- a/base/applications/wordpad/lang/fr-FR.rc +++ b/base/applications/wordpad/lang/fr-FR.rc @@ -179,7 +179,7 @@ BEGIN STRING_PROMPT_SAVE_CHANGES, "Enregistrer les modifications de « %s » ?" STRING_SEARCH_FINISHED, "Recherche terminée dans le document." STRING_LOAD_RICHED_FAILED, "Impossible de charger la bibliothèque RichEdit." - STRING_SAVE_LOSEFORMATTING, "Vous avez choisi d'enregistrer en texte simple, ce qui causera la perte de tout formattage. Voulez-vous vraiment continuer ?" + STRING_SAVE_LOSEFORMATTING, "Vous avez choisi d'enregistrer en texte simple, ce qui causera la perte de tout formatage. Voulez-vous vraiment continuer ?" STRING_INVALID_NUMBER, "Format de nombre invalide" STRING_OLE_STORAGE_NOT_SUPPORTED, "Les documents conteneur OLE ne sont pas supportés" STRING_WRITE_FAILED, "Impossible d'enregistrer le fichier." diff --git a/base/applications/wow64test/CMakeLists.txt b/base/applications/wow64test/CMakeLists.txt new file mode 100644 index 0000000000000..72a7c924eb103 --- /dev/null +++ b/base/applications/wow64test/CMakeLists.txt @@ -0,0 +1,8 @@ + +list(APPEND SOURCE + test.c) + +add_executable(wow64test ${SOURCE}) +set_module_type(wow64test win32cui UNICODE) +add_importlibs(wow64test ntdll kernel32 user32 msvcrt gdi32 comctl32) +add_cd_file(TARGET wow64test DESTINATION reactos/system32 FOR all) diff --git a/base/applications/wow64test/test.c b/base/applications/wow64test/test.c new file mode 100644 index 0000000000000..a9de5d93cc625 --- /dev/null +++ b/base/applications/wow64test/test.c @@ -0,0 +1,141 @@ +#include +#include +#include + +static HWND (WINAPI *pCreateWindowExW)(ULONG, LPCWSTR className, LPCWSTR windowName, ULONG windowStyle, int, int, int, int, PVOID, PVOID, HINSTANCE, PVOID) = NULL; +static ATOM (WINAPI *pRegisterClassW)(WNDCLASSW* pClass) = NULL; +static LRESULT (CALLBACK *pDefWindowProcW)(HWND, UINT, WPARAM, LPARAM); +static BOOL (WINAPI *pShowWindow)(HWND, int); +static BOOL (WINAPI *pUpdateWindow)(HWND); +static BOOL (WINAPI *pGetMessageW)(MSG*, HWND, UINT, UINT); +static BOOL (WINAPI *pDispatchMessageW)(MSG*); +static HDC (WINAPI *pBeginPaint)(HWND, PAINTSTRUCT*); +static void (WINAPI *pFillRect)(HDC, RECT*, HBRUSH); +static void (WINAPI *pEndPaint)(HWND, PAINTSTRUCT*); + +LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + LRESULT result; + + if (msg == WM_NCHITTEST) + { + result = pDefWindowProcW(hWnd, msg, wParam, lParam); + + return result; + } + if (msg == WM_CREATE) + { + HWND hwndButton = CreateWindow(L"BUTTON", // Predefined class; Unicode assumed + L"OK", // Button text + WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, // Styles + 10, // x position + 10, // y position + 100, // Button width + 100, // Button height + hWnd, // Parent window + NULL, // No menu. + (HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE), + NULL); // Pointer not needed. + + //printf("%p hwnd button\n", hwndButton); + (VOID) hwndButton; + } + else if (msg == WM_CLOSE) + { + PostQuitMessage(0); + } + else if ((msg < WM_MOUSEFIRST || msg > WM_MOUSELAST) && msg != 0x7F) + { +#if 0 + printf("msg: 00%X", msg); + fflush(stdout); +#endif + result = pDefWindowProcW(hWnd, msg, wParam, lParam); +#if 0 + printf(" - DONE\n"); +#endif + return result; + } + + return pDefWindowProcW(hWnd, msg, wParam, lParam); +} + +void DelayLoadUser32() +{ + HMODULE hUser32 = LoadLibraryW(L"user32.dll"); + + pCreateWindowExW = (PVOID)GetProcAddress(hUser32, "CreateWindowExW"); + pRegisterClassW = (PVOID)GetProcAddress(hUser32, "RegisterClassW"); + pDefWindowProcW = (PVOID)GetProcAddress(hUser32, "DefWindowProcW"); + + pUpdateWindow = (PVOID)GetProcAddress(hUser32, "UpdateWindow"); + pShowWindow = (PVOID)GetProcAddress(hUser32, "ShowWindow"); + pGetMessageW = (PVOID)GetProcAddress(hUser32, "GetMessageW"); + pDispatchMessageW = (PVOID)GetProcAddress(hUser32, "DispatchMessageW"); + + pBeginPaint = (PVOID)GetProcAddress(hUser32, "BeginPaint"); + pEndPaint = (PVOID)GetProcAddress(hUser32, "EndPaint"); + pFillRect = (PVOID)GetProcAddress(hUser32, "FillRect"); +} + +void Print(const wchar_t* wszBuffer) +{ + size_t i = 0; + while(wszBuffer[i++]); + + WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), wszBuffer, i, NULL, NULL); +} + +static +DWORD +WINAPI +ThreadTest(PVOID p) +{ + __debugbreak(); + printf("ngutrgrgrgjnnrg\n"); + return 69; +} + +int wmainCRTStartup() +{ + AllocConsole(); + + printf("W"); + CreateThread(NULL, 0x4000, ThreadTest, NULL, 0, NULL); + + WCHAR wszHello[] = L"Hello World!"; + SetPriorityClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS); + + //Print(wszHello); + + DelayLoadUser32(); + + WNDCLASSW wndClass = { 0 }; + wndClass.hInstance = (HINSTANCE)GetModuleHandle(NULL); + wndClass.lpszClassName = wszHello; + wndClass.lpfnWndProc = WndProc; + wndClass.style = CS_HREDRAW | CS_VREDRAW; + wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); + + pRegisterClassW(&wndClass); + + HWND result = pCreateWindowExW(0, wszHello, wszHello, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, wndClass.hInstance, NULL); + + if (result == 0 || result == INVALID_HANDLE_VALUE) + { + return -1; + } + + pUpdateWindow(result); + pShowWindow(result, 1); + + MSG msg; + + while(pGetMessageW(&msg, 0, 0, 0)) + { + pDispatchMessageW(&msg); + } + + TerminateProcess(GetCurrentProcess(), 0); + return 0; +} diff --git a/base/services/nfsd/CMakeLists.txt b/base/services/nfsd/CMakeLists.txt index 77054777c8c31..3aeb58722c067 100644 --- a/base/services/nfsd/CMakeLists.txt +++ b/base/services/nfsd/CMakeLists.txt @@ -55,6 +55,9 @@ else() # FIXME: Tons of warnings. target_compile_options(nfsd PRIVATE "-w") endif() +if(CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_compile_options(nfsd PRIVATE -Wno-incompatible-function-pointer-types) +endif() target_link_libraries(nfsd oldnames) diff --git a/base/services/nfsd/nfs41_client.c b/base/services/nfsd/nfs41_client.c index 566f17eea672f..53c50f992964f 100644 --- a/base/services/nfsd/nfs41_client.c +++ b/base/services/nfsd/nfs41_client.c @@ -233,10 +233,10 @@ void nfs41_client_free( * http://tools.ietf.org/html/rfc5661#section-2.4 * * MSDN: GetAdaptersAddresses Function - * http://msdn.microsoft.com/en-us/library/aa365915%28VS.85%29.aspx + * https://learn.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-getadaptersaddresses * * MSDN: Example C Program: Creating an MD5 Hash from File Content - * http://msdn.microsoft.com/en-us/library/aa382380%28VS.85%29.aspx */ + * https://learn.microsoft.com/en-us/windows/win32/seccrypto/example-c-program--creating-an-md-5-hash-from-file-content */ /* use an rbtree to sort mac address entries */ diff --git a/base/services/nfsd/util.h b/base/services/nfsd/util.h index 735c91d7d3c44..b064c29ecba9f 100644 --- a/base/services/nfsd/util.h +++ b/base/services/nfsd/util.h @@ -107,7 +107,7 @@ void nfs_to_network_openinfo( IN const nfs41_file_info *info, OUT PFILE_NETWORK_OPEN_INFORMATION std_out); -/* http://msdn.microsoft.com/en-us/library/ms724290%28VS.85%29.aspx: +/* https://learn.microsoft.com/en-us/windows/win32/sysinfo/file-times * A file time is a 64-bit value that represents the number of * 100-nanosecond intervals that have elapsed since 12:00 A.M. * January 1, 1601 Coordinated Universal Time (UTC). */ diff --git a/base/services/umpnpmgr/precomp.h b/base/services/umpnpmgr/precomp.h index 21c3622d92924..60f228469387b 100644 --- a/base/services/umpnpmgr/precomp.h +++ b/base/services/umpnpmgr/precomp.h @@ -33,6 +33,8 @@ #include +#define LOGCONF_NAME_BUFFER_SIZE 32 + typedef struct { LIST_ENTRY ListEntry; diff --git a/base/services/umpnpmgr/rpcserver.c b/base/services/umpnpmgr/rpcserver.c index ff7a15ac0fbf5..33ff9da1f5584 100644 --- a/base/services/umpnpmgr/rpcserver.c +++ b/base/services/umpnpmgr/rpcserver.c @@ -494,7 +494,9 @@ GetConfigurationData( _In_ ULONG ulLogConfType, _Out_ PULONG pulRegDataType, _Out_ PULONG pulDataSize, - _Out_ LPBYTE *ppBuffer) + _Out_ LPBYTE *ppBuffer, + _In_ ULONG ulValueNameBufferSize, + _Out_opt_ LPWSTR pszValueNameBuffer) { LPCWSTR pszValueName; @@ -535,6 +537,11 @@ GetConfigurationData( return CR_FAILURE; } + /* Return the selected configuration value name */ + if ((ulValueNameBufferSize > 0) && (pszValueNameBuffer != NULL) && + (wcslen(pszValueName) + 1 <= ulValueNameBufferSize)) + wcscpy(pszValueNameBuffer, pszValueName); + /* Get the configuration data size */ if (RegQueryValueExW(hKey, pszValueName, @@ -568,6 +575,41 @@ GetConfigurationData( } +static +PCM_FULL_RESOURCE_DESCRIPTOR +NextResourceDescriptor( + _In_ PCM_FULL_RESOURCE_DESCRIPTOR pDescriptor) +{ + PBYTE pNext = NULL; + ULONG ulLastIndex = 0; + + if (pDescriptor == NULL) + return NULL; + + /* Skip the full resource descriptor */ + pNext = (LPBYTE)pDescriptor + sizeof(CM_FULL_RESOURCE_DESCRIPTOR); + + /* Skip the partial resource descriptors */ + pNext += (pDescriptor->PartialResourceList.Count - 1) * + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR); + + /* Skip the device specific data, if present */ + if (pDescriptor->PartialResourceList.Count > 0) + { + ulLastIndex = pDescriptor->PartialResourceList.Count - 1; + + if (pDescriptor->PartialResourceList.PartialDescriptors[ulLastIndex].Type == + CmResourceTypeDeviceSpecific) + { + pNext += pDescriptor->PartialResourceList.PartialDescriptors[ulLastIndex]. + u.DeviceSpecificData.DataSize; + } + } + + return (PCM_FULL_RESOURCE_DESCRIPTOR)pNext; +} + + static BOOL IsCallerInteractive( @@ -4168,8 +4210,178 @@ PNP_AddEmptyLogConf( DWORD *pulLogConfTag, DWORD ulFlags) { - UNIMPLEMENTED; - return CR_CALL_NOT_IMPLEMENTED; + HKEY hConfigKey = NULL; + DWORD RegDataType = 0; + ULONG ulDataSize = 0, ulNewSize = 0; + PBYTE pDataBuffer = NULL; + WCHAR szValueNameBuffer[LOGCONF_NAME_BUFFER_SIZE]; + CONFIGRET ret = CR_SUCCESS; + + DPRINT("PNP_AddEmptyLogConf(%p %S %lu %p 0x%08lx)\n", + hBinding, pDeviceID, ulPriority, pulLogConfTag, ulFlags); + + if (pulLogConfTag == NULL) + return CR_INVALID_POINTER; + + *pulLogConfTag = 0; + + if (ulFlags & ~(LOG_CONF_BITS | PRIORITY_BIT)) + return CR_INVALID_FLAG; + + if (!IsValidDeviceInstanceID(pDeviceID) || IsRootDeviceInstanceID(pDeviceID)) + return CR_INVALID_DEVNODE; + + ret = OpenConfigurationKey(pDeviceID, + ulFlags & LOG_CONF_BITS, + &hConfigKey); + if (ret != CR_SUCCESS) + { + DPRINT1("OpenConfigurationKey() failed (Error %lu)\n", ret); + ret = CR_NO_MORE_LOG_CONF; + goto done; + } + + ret = GetConfigurationData(hConfigKey, + ulFlags & LOG_CONF_BITS, + &RegDataType, + &ulDataSize, + &pDataBuffer, + LOGCONF_NAME_BUFFER_SIZE, + szValueNameBuffer); + + if (ret != CR_SUCCESS || ulDataSize == 0) + { + ret = CR_SUCCESS; + + if (RegDataType == REG_RESOURCE_LIST) + { + PCM_RESOURCE_LIST pResourceList = NULL; + PCM_FULL_RESOURCE_DESCRIPTOR pResource = NULL; + + /* Allocate a buffer for the new configuration */ + ulDataSize = sizeof(CM_RESOURCE_LIST) - sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR); + pDataBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ulDataSize); + if (pDataBuffer == NULL) + { + ret = CR_OUT_OF_MEMORY; + goto done; + } + + pResourceList = (PCM_RESOURCE_LIST)pDataBuffer; + pResourceList->Count = 1; + + pResource = (PCM_FULL_RESOURCE_DESCRIPTOR)&pResourceList->List[0]; + pResource->InterfaceType = InterfaceTypeUndefined; + pResource->BusNumber = 0; + pResource->PartialResourceList.Version = 1; + pResource->PartialResourceList.Revision = 1; + pResource->PartialResourceList.Count = 0; + } + else if (RegDataType == REG_RESOURCE_REQUIREMENTS_LIST) + { + PIO_RESOURCE_REQUIREMENTS_LIST pRequirementsList = NULL; + PIO_RESOURCE_LIST pResourceList = NULL; + + ulDataSize = sizeof(IO_RESOURCE_REQUIREMENTS_LIST); + pDataBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ulDataSize); + if (pDataBuffer == NULL) + { + ret = CR_OUT_OF_MEMORY; + goto done; + } + + pRequirementsList = (PIO_RESOURCE_REQUIREMENTS_LIST)pDataBuffer; + pRequirementsList->ListSize = ulDataSize; + pRequirementsList->InterfaceType = InterfaceTypeUndefined; + pRequirementsList->BusNumber = 0; + pRequirementsList->SlotNumber = 0; + pRequirementsList->AlternativeLists = 1; + + pResourceList = (PIO_RESOURCE_LIST)&pRequirementsList->List[0]; + pResourceList->Version = 1; + pResourceList->Revision = 1; + pResourceList->Count = 1; + + pResourceList->Descriptors[0].Option = IO_RESOURCE_PREFERRED; + pResourceList->Descriptors[0].Type = CmResourceTypeConfigData; + pResourceList->Descriptors[0].u.ConfigData.Priority = ulPriority; + } + else + { + ret = CR_FAILURE; + goto done; + } + } + else + { + if (RegDataType == REG_RESOURCE_LIST) + { + PCM_RESOURCE_LIST pResourceList = NULL; + PCM_FULL_RESOURCE_DESCRIPTOR pResource = NULL; + ULONG ulIndex; + + /* Reallocate a larger buffer in order to add the new configuration */ + ulNewSize = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) - sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR); + pDataBuffer = HeapReAlloc(GetProcessHeap(), + 0, + pDataBuffer, + ulDataSize + ulNewSize); + if (pDataBuffer == NULL) + { + ret = CR_OUT_OF_MEMORY; + goto done; + } + + pResourceList = (PCM_RESOURCE_LIST)pDataBuffer; + + /* Get a pointer to the new (uninitialized) resource descriptor */ + pResource = (PCM_FULL_RESOURCE_DESCRIPTOR)&pResourceList->List[0]; + for (ulIndex = 0; ulIndex < pResourceList->Count; ulIndex++) + pResource = NextResourceDescriptor(pResource); + + /* Initialize the new resource descriptor */ + pResourceList->Count++; + pResource->InterfaceType= InterfaceTypeUndefined; + pResource->BusNumber = 0; + pResource->PartialResourceList.Version = 1; + pResource->PartialResourceList.Revision = 1; + pResource->PartialResourceList.Count = 0; + + *pulLogConfTag = ulIndex; + } + else if (RegDataType == REG_RESOURCE_REQUIREMENTS_LIST) + { + /* FIXME */ + } + else + { + ret = CR_FAILURE; + goto done; + } + } + + /* Store the configuration */ + if (RegSetValueEx(hConfigKey, + szValueNameBuffer, + 0, + RegDataType, + pDataBuffer, + ulDataSize + ulNewSize) != ERROR_SUCCESS) + { + ret = CR_REGISTRY_ERROR; + goto done; + } + +done: + if (pDataBuffer != NULL) + HeapFree(GetProcessHeap(), 0, pDataBuffer); + + if (hConfigKey != NULL) + RegCloseKey(hConfigKey); + + DPRINT("PNP_AddEmptyLogConf() returns %lu\n", ret); + + return ret; } @@ -4183,8 +4395,87 @@ PNP_FreeLogConf( DWORD ulLogConfTag, DWORD ulFlags) { - UNIMPLEMENTED; - return CR_CALL_NOT_IMPLEMENTED; + HKEY hConfigKey = NULL; + DWORD RegDataType = 0; + ULONG ulDataSize = 0; + LPBYTE pDataBuffer = NULL; + WCHAR szValueNameBuffer[LOGCONF_NAME_BUFFER_SIZE]; + CONFIGRET ret = CR_SUCCESS; + + DPRINT("PNP_FreeLogConf(%p %S %lu %lu 0x%08lx)\n", + hBinding, pDeviceID, ulLogConfType, ulLogConfTag, ulFlags); + + if (ulFlags != 0) + return CR_INVALID_FLAG; + + if (!IsValidDeviceInstanceID(pDeviceID)) + return CR_INVALID_DEVNODE; + + ret = OpenConfigurationKey(pDeviceID, + ulLogConfType, + &hConfigKey); + if (ret != CR_SUCCESS) + { + DPRINT1("OpenConfigurationKey() failed (Error %lu)\n", ret); + ret = CR_NO_MORE_LOG_CONF; + goto done; + } + + ret = GetConfigurationData(hConfigKey, + ulLogConfType, + &RegDataType, + &ulDataSize, + &pDataBuffer, + LOGCONF_NAME_BUFFER_SIZE, + szValueNameBuffer); + if (ret != CR_SUCCESS) + { + ret = CR_INVALID_LOG_CONF; + goto done; + } + + if (RegDataType == REG_RESOURCE_LIST) + { + if (((PCM_RESOURCE_LIST)pDataBuffer)->Count <= 1) + { + /* Delete the key if there is only one or no configuration in the key */ + DPRINT("Delete value %S\n", szValueNameBuffer); + RegDeleteValue(hConfigKey, szValueNameBuffer); + } + else + { + /* FIXME */ + } + } + else if (RegDataType == REG_RESOURCE_REQUIREMENTS_LIST) + { + if (((PIO_RESOURCE_REQUIREMENTS_LIST)pDataBuffer)->AlternativeLists <= 1) + { + /* Delete the key if there is only one or no configuration in the key */ + DPRINT("Delete value %S\n", szValueNameBuffer); + RegDeleteValue(hConfigKey, szValueNameBuffer); + } + else + { + /* FIXME */ + } + } + else + { + ret = CR_FAILURE; + goto done; + } + +done: + if (pDataBuffer != NULL) + HeapFree(GetProcessHeap(), 0, pDataBuffer); + + if (hConfigKey != NULL) + RegCloseKey(hConfigKey); + + DPRINT("PNP_FreeLogConf() returns %lu\n", ret); + + return ret; } @@ -4232,7 +4523,9 @@ PNP_GetFirstLogConf( ulLogConfType, &RegDataType, &ulDataSize, - &lpData); + &lpData, + 0, + NULL); if (ret != CR_SUCCESS) { DPRINT1("GetConfigurationData() failed (Error %lu)\n", ret); @@ -4332,7 +4625,9 @@ PNP_GetNextLogConf( ulLogConfType, &RegDataType, &ulDataSize, - &lpData); + &lpData, + 0, + NULL); if (ret != CR_SUCCESS) { DPRINT1("GetConfigurationData() failed (Error %lu)\n", ret); @@ -4507,7 +4802,9 @@ PNP_GetNextResDes( ulLogConfType, &RegDataType, &ulDataSize, - &lpData); + &lpData, + 0, + NULL); if (ret != CR_SUCCESS) { DPRINT1("GetConfigurationData() failed (Error %lu)\n", ret); diff --git a/base/services/wkssvc/info.c b/base/services/wkssvc/info.c index 98e90256ecd70..e596ffe529cd7 100644 --- a/base/services/wkssvc/info.c +++ b/base/services/wkssvc/info.c @@ -326,6 +326,7 @@ InitWorkstationInfo(VOID) else WkstaInfo502.wki502_use_unlock_behind = 1; + dwSize = sizeof(dwValue); dwError = RegQueryValueExW(hInfoKey, L"UseCloseBehind", 0, @@ -337,6 +338,7 @@ InitWorkstationInfo(VOID) else WkstaInfo502.wki502_use_close_behind = 1; + dwSize = sizeof(dwValue); dwError = RegQueryValueExW(hInfoKey, L"BufNamedPipes", 0, @@ -348,6 +350,7 @@ InitWorkstationInfo(VOID) else WkstaInfo502.wki502_buf_named_pipes = 1; + dwSize = sizeof(dwValue); dwError = RegQueryValueExW(hInfoKey, L"UseLockReadUnlock", 0, @@ -359,6 +362,7 @@ InitWorkstationInfo(VOID) else WkstaInfo502.wki502_use_lock_read_unlock = 1; + dwSize = sizeof(dwValue); dwError = RegQueryValueExW(hInfoKey, L"UtilizeNtCaching", 0, @@ -370,6 +374,7 @@ InitWorkstationInfo(VOID) else WkstaInfo502.wki502_utilize_nt_caching = 1; + dwSize = sizeof(dwValue); dwError = RegQueryValueExW(hInfoKey, L"UseRawRead", 0, @@ -381,6 +386,7 @@ InitWorkstationInfo(VOID) else WkstaInfo502.wki502_use_raw_read = 1; + dwSize = sizeof(dwValue); dwError = RegQueryValueExW(hInfoKey, L"UseRawWrite", 0, @@ -392,6 +398,7 @@ InitWorkstationInfo(VOID) else WkstaInfo502.wki502_use_raw_write = 1; + dwSize = sizeof(dwValue); dwError = RegQueryValueExW(hInfoKey, L"UseWriteRawData", 0, @@ -403,6 +410,7 @@ InitWorkstationInfo(VOID) else WkstaInfo502.wki502_use_write_raw_data = 0; + dwSize = sizeof(dwValue); dwError = RegQueryValueExW(hInfoKey, L"UseEncryption", 0, @@ -414,6 +422,7 @@ InitWorkstationInfo(VOID) else WkstaInfo502.wki502_use_encryption = 1; + dwSize = sizeof(dwValue); dwError = RegQueryValueExW(hInfoKey, L"BufFilesDenyWrite", 0, @@ -425,6 +434,7 @@ InitWorkstationInfo(VOID) else WkstaInfo502.wki502_buf_files_deny_write = 0; + dwSize = sizeof(dwValue); dwError = RegQueryValueExW(hInfoKey, L"BufReadOnlyFiles", 0, @@ -436,6 +446,7 @@ InitWorkstationInfo(VOID) else WkstaInfo502.wki502_buf_read_only_files = 0; + dwSize = sizeof(dwValue); dwError = RegQueryValueExW(hInfoKey, L"ForceCoreCreateMode", 0, @@ -447,6 +458,7 @@ InitWorkstationInfo(VOID) else WkstaInfo502.wki502_force_core_create_mode = 0; + dwSize = sizeof(dwValue); dwError = RegQueryValueExW(hInfoKey, L"Use512ByteMaxTransfer", 0, diff --git a/base/services/wkssvc/precomp.h b/base/services/wkssvc/precomp.h index b6d575316ab71..71a60f4ea5030 100644 --- a/base/services/wkssvc/precomp.h +++ b/base/services/wkssvc/precomp.h @@ -15,8 +15,12 @@ #include #include #include +#include //#include +#include +#include #include +#include #include diff --git a/base/services/wkssvc/rpcserver.c b/base/services/wkssvc/rpcserver.c index 703e35e693511..c51d8fda49e96 100644 --- a/base/services/wkssvc/rpcserver.c +++ b/base/services/wkssvc/rpcserver.c @@ -77,6 +77,55 @@ void __RPC_USER midl_user_free(void __RPC_FAR * ptr) } +static +NET_API_STATUS +NetpGetClientLogonId( + _Out_ PLUID LogonId) +{ + HANDLE ThreadToken = NULL; + TOKEN_STATISTICS Statistics; + ULONG Length; + NTSTATUS NtStatus; + NET_API_STATUS ApiStatus = NERR_Success; + + ApiStatus = RpcImpersonateClient(NULL); + if (ApiStatus != NERR_Success) + return ApiStatus; + + NtStatus = NtOpenThreadToken(NtCurrentThread(), + TOKEN_QUERY, + TRUE, + &ThreadToken); + if (!NT_SUCCESS(NtStatus)) + { + ApiStatus = RtlNtStatusToDosError(NtStatus); + goto done; + } + + NtStatus = NtQueryInformationToken(ThreadToken, + TokenStatistics, + (PVOID)&Statistics, + sizeof(Statistics), + &Length); + if (!NT_SUCCESS(NtStatus)) + { + ApiStatus = RtlNtStatusToDosError(NtStatus); + goto done; + } + + TRACE("Client LUID: %lx\n", Statistics.AuthenticationId.LowPart); + RtlCopyLuid(LogonId, &Statistics.AuthenticationId); + +done: + if (ThreadToken != NULL) + NtClose(ThreadToken); + + RpcRevertToSelf(); + + return ApiStatus; +} + + /* Function 0 */ unsigned long __stdcall @@ -92,6 +141,7 @@ NetrWkstaGetInfo( LSA_OBJECT_ATTRIBUTES ObjectAttributes; LSA_HANDLE PolicyHandle; PPOLICY_PRIMARY_DOMAIN_INFO DomainInfo = NULL; + ULONG LoggedOnUsers; NTSTATUS NtStatus; DWORD dwResult = NERR_Success; @@ -124,6 +174,33 @@ NetrWkstaGetInfo( return LsaNtStatusToWinError(NtStatus); } + if (Level == 102) + { + MSV1_0_ENUMUSERS_REQUEST EnumRequest; + PMSV1_0_ENUMUSERS_RESPONSE EnumResponseBuffer = NULL; + DWORD EnumResponseBufferSize = 0; + NTSTATUS ProtocolStatus; + + /* enumerate all currently logged-on users */ + EnumRequest.MessageType = MsV1_0EnumerateUsers; + NtStatus = LsaCallAuthenticationPackage(LsaHandle, + LsaAuthenticationPackage, + &EnumRequest, + sizeof(EnumRequest), + (PVOID*)&EnumResponseBuffer, + &EnumResponseBufferSize, + &ProtocolStatus); + if (!NT_SUCCESS(NtStatus)) + { + dwResult = RtlNtStatusToDosError(NtStatus); + goto done; + } + + LoggedOnUsers = EnumResponseBuffer->NumberOfLoggedOnUsers; + + LsaFreeReturnBuffer(EnumResponseBuffer); + } + switch (Level) { case 100: @@ -203,7 +280,7 @@ NetrWkstaGetInfo( if (pWkstaInfo->WkstaInfo102.wki102_lanroot != NULL) wcscpy(pWkstaInfo->WkstaInfo102.wki102_lanroot, pszLanRoot); - pWkstaInfo->WkstaInfo102.wki102_logged_on_users = 1; /* FIXME */ + pWkstaInfo->WkstaInfo102.wki102_logged_on_users = LoggedOnUsers; *WkstaInfo = pWkstaInfo; break; @@ -227,6 +304,7 @@ NetrWkstaGetInfo( break; } +done: if (DomainInfo != NULL) LsaFreeMemory(DomainInfo); @@ -243,6 +321,7 @@ NetrWkstaSetInfo( LPWKSTA_INFO WkstaInfo, unsigned long *ErrorParameter) { + DWORD dwErrParam = 0; DWORD dwResult = NERR_Success; TRACE("NetrWkstaSetInfo(%lu %p %p)\n", @@ -254,45 +333,50 @@ NetrWkstaSetInfo( if (WkstaInfo->WkstaInfo502.wki502_keep_conn >= 1 && WkstaInfo->WkstaInfo502.wki502_keep_conn <= 65535) { WkstaInfo502.wki502_keep_conn = WkstaInfo->WkstaInfo502.wki502_keep_conn; + } + else + { + dwErrParam = WKSTA_KEEPCONN_PARMNUM; + dwResult = ERROR_INVALID_PARAMETER; + } + if (dwResult == NERR_Success) + { if (WkstaInfo->WkstaInfo502.wki502_max_cmds >= 50 && WkstaInfo->WkstaInfo502.wki502_max_cmds <= 65535) { WkstaInfo502.wki502_max_cmds = WkstaInfo->WkstaInfo502.wki502_max_cmds; + } + else + { + dwErrParam = WKSTA_MAXCMDS_PARMNUM; + dwResult = ERROR_INVALID_PARAMETER; + } + } - if (WkstaInfo->WkstaInfo502.wki502_sess_timeout >= 60 && WkstaInfo->WkstaInfo502.wki502_sess_timeout <= 65535) - { - WkstaInfo502.wki502_sess_timeout = WkstaInfo->WkstaInfo502.wki502_sess_timeout; - - if (WkstaInfo->WkstaInfo502.wki502_dormant_file_limit != 0) - { - WkstaInfo502.wki502_dormant_file_limit = WkstaInfo->WkstaInfo502.wki502_dormant_file_limit; - } - else - { - if (ErrorParameter) - *ErrorParameter = WKSTA_DORMANTFILELIMIT_PARMNUM; - dwResult = ERROR_INVALID_PARAMETER; - } - } - else - { - if (ErrorParameter) - *ErrorParameter = WKSTA_SESSTIMEOUT_PARMNUM; - dwResult = ERROR_INVALID_PARAMETER; - } + if (dwResult == NERR_Success) + { + if (WkstaInfo->WkstaInfo502.wki502_sess_timeout >= 60 && WkstaInfo->WkstaInfo502.wki502_sess_timeout <= 65535) + { + WkstaInfo502.wki502_sess_timeout = WkstaInfo->WkstaInfo502.wki502_sess_timeout; } else { - if (ErrorParameter) - *ErrorParameter = WKSTA_MAXCMDS_PARMNUM; + dwErrParam = WKSTA_SESSTIMEOUT_PARMNUM; dwResult = ERROR_INVALID_PARAMETER; } } - else + + if (dwResult == NERR_Success) { - if (ErrorParameter) - *ErrorParameter = WKSTA_KEEPCONN_PARMNUM; - dwResult = ERROR_INVALID_PARAMETER; + if (WkstaInfo->WkstaInfo502.wki502_dormant_file_limit != 0) + { + WkstaInfo502.wki502_dormant_file_limit = WkstaInfo->WkstaInfo502.wki502_dormant_file_limit; + } + else + { + dwErrParam = WKSTA_DORMANTFILELIMIT_PARMNUM; + dwResult = ERROR_INVALID_PARAMETER; + } } break; @@ -303,8 +387,7 @@ NetrWkstaSetInfo( } else { - if (ErrorParameter) - *ErrorParameter = WKSTA_KEEPCONN_PARMNUM; + dwErrParam = WKSTA_KEEPCONN_PARMNUM; dwResult = ERROR_INVALID_PARAMETER; } break; @@ -316,8 +399,7 @@ NetrWkstaSetInfo( } else { - if (ErrorParameter) - *ErrorParameter = WKSTA_SESSTIMEOUT_PARMNUM; + dwErrParam = WKSTA_SESSTIMEOUT_PARMNUM; dwResult = ERROR_INVALID_PARAMETER; } break; @@ -329,23 +411,27 @@ NetrWkstaSetInfo( } else { - if (ErrorParameter) - *ErrorParameter = WKSTA_DORMANTFILELIMIT_PARMNUM; + dwErrParam = WKSTA_DORMANTFILELIMIT_PARMNUM; dwResult = ERROR_INVALID_PARAMETER; } break; default: - FIXME("Level %lu unimplemented\n", Level); + ERR("Invalid Level %lu\n", Level); dwResult = ERROR_INVALID_LEVEL; break; } /* Save the workstation in the registry */ if (dwResult == NERR_Success) + { SaveWorkstationInfo(Level); - /* FIXME: Notify the redirector */ + /* FIXME: Notify the redirector */ + } + + if ((dwResult == ERROR_INVALID_PARAMETER) && (ErrorParameter != NULL)) + *ErrorParameter = dwErrParam; return dwResult; } @@ -361,12 +447,243 @@ NetrWkstaUserEnum( unsigned long *TotalEntries, unsigned long *ResumeHandle) { - ERR("NetrWkstaUserEnum(%p %p 0x%lx %p %p)\n", - ServerName, UserInfo, PreferredMaximumLength, TotalEntries, ResumeHandle); + MSV1_0_ENUMUSERS_REQUEST EnumRequest; + PMSV1_0_ENUMUSERS_RESPONSE EnumResponseBuffer = NULL; + MSV1_0_GETUSERINFO_REQUEST UserInfoRequest; + PMSV1_0_GETUSERINFO_RESPONSE UserInfoResponseBuffer = NULL; + PMSV1_0_GETUSERINFO_RESPONSE *UserInfoArray = NULL; + DWORD EnumResponseBufferSize = 0; + DWORD UserInfoResponseBufferSize = 0; + NTSTATUS Status, ProtocolStatus; + ULONG i, start, count; + PLUID pLogonId; + PULONG pEnumHandle; + DWORD dwResult = NERR_Success; + PWKSTA_USER_INFO_0 pUserInfo0 = NULL; + PWKSTA_USER_INFO_1 pUserInfo1 = NULL; - UNIMPLEMENTED; - return 0; + TRACE("NetrWkstaUserEnum(%p %p 0x%lx %p %p)\n", + ServerName, UserInfo, PreferredMaximumLength, TotalEntries, ResumeHandle); + + if (UserInfo->Level > 1) + { + ERR("Invalid Level %lu\n", UserInfo->Level); + return ERROR_INVALID_LEVEL; + } + + /* Enumerate all currently logged-on users */ + EnumRequest.MessageType = MsV1_0EnumerateUsers; + Status = LsaCallAuthenticationPackage(LsaHandle, + LsaAuthenticationPackage, + &EnumRequest, + sizeof(EnumRequest), + (PVOID*)&EnumResponseBuffer, + &EnumResponseBufferSize, + &ProtocolStatus); + + TRACE("LsaCallAuthenticationPackage Status 0x%08lx ResponseBufferSize %lu\n", Status, EnumResponseBufferSize); + if (!NT_SUCCESS(Status)) + { + dwResult = RtlNtStatusToDosError(Status); + goto done; + } + + TRACE("LoggedOnUsers: %lu\n", EnumResponseBuffer->NumberOfLoggedOnUsers); + TRACE("ResponseBuffer: 0x%p\n", EnumResponseBuffer); + TRACE("LogonIds: 0x%p\n", EnumResponseBuffer->LogonIds); + TRACE("EnumHandles: 0x%p\n", EnumResponseBuffer->EnumHandles); + if (EnumResponseBuffer->NumberOfLoggedOnUsers > 0) + { + pLogonId = EnumResponseBuffer->LogonIds; + pEnumHandle = EnumResponseBuffer->EnumHandles; + TRACE("pLogonId: 0x%p\n", pLogonId); + TRACE("pEnumHandle: 0x%p\n", pEnumHandle); + + UserInfoArray = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + EnumResponseBuffer->NumberOfLoggedOnUsers * sizeof(PMSV1_0_GETUSERINFO_RESPONSE)); + if (UserInfoArray == NULL) + { + dwResult = ERROR_NOT_ENOUGH_MEMORY; + goto done; + } + + for (i = 0; i < EnumResponseBuffer->NumberOfLoggedOnUsers; i++) + { + TRACE("Logon %lu: 0x%08lx %lu\n", i, pLogonId->LowPart, *pEnumHandle); + + UserInfoRequest.MessageType = MsV1_0GetUserInfo; + UserInfoRequest.LogonId = *pLogonId; + Status = LsaCallAuthenticationPackage(LsaHandle, + LsaAuthenticationPackage, + &UserInfoRequest, + sizeof(UserInfoRequest), + (PVOID*)&UserInfoResponseBuffer, + &UserInfoResponseBufferSize, + &ProtocolStatus); + TRACE("LsaCallAuthenticationPackage:MsV1_0GetUserInfo Status 0x%08lx ResponseBufferSize %lu\n", Status, UserInfoResponseBufferSize); + if (!NT_SUCCESS(Status)) + { + dwResult = RtlNtStatusToDosError(Status); + goto done; + } + + UserInfoArray[i] = UserInfoResponseBuffer; + + TRACE("UserName: %wZ\n", &UserInfoArray[i]->UserName); + TRACE("LogonDomain: %wZ\n", &UserInfoArray[i]->LogonDomainName); + TRACE("LogonServer: %wZ\n", &UserInfoArray[i]->LogonServer); + + pLogonId++; + pEnumHandle++; + } + + if (PreferredMaximumLength == MAX_PREFERRED_LENGTH) + { + start = 0; + count = EnumResponseBuffer->NumberOfLoggedOnUsers; + } + else + { + FIXME("Calculate the start index and the number of matching array entries!"); + dwResult = ERROR_CALL_NOT_IMPLEMENTED; + goto done; + } + + switch (UserInfo->Level) + { + case 0: + pUserInfo0 = midl_user_allocate(count * sizeof(WKSTA_USER_INFO_0)); + if (pUserInfo0 == NULL) + { + ERR("\n"); + dwResult = ERROR_NOT_ENOUGH_MEMORY; + break; + } + + ZeroMemory(pUserInfo0, count * sizeof(WKSTA_USER_INFO_0)); + + for (i = 0; i < 0 + count; i++) + { + pUserInfo0[i].wkui0_username = midl_user_allocate(UserInfoArray[start + i]->UserName.Length + sizeof(WCHAR)); + if (pUserInfo0[i].wkui0_username == NULL) + { + ERR("\n"); + dwResult = ERROR_NOT_ENOUGH_MEMORY; + break; + } + + ZeroMemory(pUserInfo0[i].wkui0_username, UserInfoArray[start + i]->UserName.Length + sizeof(WCHAR)); + CopyMemory(pUserInfo0[i].wkui0_username, UserInfoArray[start + i]->UserName.Buffer, UserInfoArray[start + i]->UserName.Length); + } + + UserInfo->WkstaUserInfo.Level0.EntriesRead = count; + UserInfo->WkstaUserInfo.Level0.Buffer = pUserInfo0; + *TotalEntries = EnumResponseBuffer->NumberOfLoggedOnUsers; + *ResumeHandle = 0; + break; + + case 1: + pUserInfo1 = midl_user_allocate(count * sizeof(WKSTA_USER_INFO_1)); + if (pUserInfo1 == NULL) + { + ERR("\n"); + dwResult = ERROR_NOT_ENOUGH_MEMORY; + break; + } + + ZeroMemory(pUserInfo1, count * sizeof(WKSTA_USER_INFO_1)); + + for (i = 0; i < 0 + count; i++) + { + pUserInfo1[i].wkui1_username = midl_user_allocate(UserInfoArray[start + i]->UserName.Length + sizeof(WCHAR)); + if (pUserInfo1[i].wkui1_username == NULL) + { + ERR("\n"); + dwResult = ERROR_NOT_ENOUGH_MEMORY; + break; + } + + ZeroMemory(pUserInfo1[i].wkui1_username, UserInfoArray[start + i]->UserName.Length + sizeof(WCHAR)); + CopyMemory(pUserInfo1[i].wkui1_username, UserInfoArray[start + i]->UserName.Buffer, UserInfoArray[start + i]->UserName.Length); + + pUserInfo1[i].wkui1_logon_domain = midl_user_allocate(UserInfoArray[start + i]->LogonDomainName.Length + sizeof(WCHAR)); + if (pUserInfo1[i].wkui1_logon_domain == NULL) + { + ERR("\n"); + dwResult = ERROR_NOT_ENOUGH_MEMORY; + break; + } + + ZeroMemory(pUserInfo1[i].wkui1_logon_domain, UserInfoArray[start + i]->LogonDomainName.Length + sizeof(WCHAR)); + CopyMemory(pUserInfo1[i].wkui1_logon_domain, UserInfoArray[start + i]->LogonDomainName.Buffer, UserInfoArray[start + i]->LogonDomainName.Length); + + // FIXME: wkui1_oth_domains + + pUserInfo1[i].wkui1_logon_server = midl_user_allocate(UserInfoArray[start + i]->LogonServer.Length + sizeof(WCHAR)); + if (pUserInfo1[i].wkui1_logon_server == NULL) + { + ERR("\n"); + dwResult = ERROR_NOT_ENOUGH_MEMORY; + break; + } + + ZeroMemory(pUserInfo1[i].wkui1_logon_server, UserInfoArray[start + i]->LogonServer.Length + sizeof(WCHAR)); + CopyMemory(pUserInfo1[i].wkui1_logon_server, UserInfoArray[start + i]->LogonServer.Buffer, UserInfoArray[start + i]->LogonServer.Length); + } + + UserInfo->WkstaUserInfo.Level1.EntriesRead = count; + UserInfo->WkstaUserInfo.Level1.Buffer = pUserInfo1; + *TotalEntries = EnumResponseBuffer->NumberOfLoggedOnUsers; + *ResumeHandle = 0; + break; + + break; + } + } + else + { + if (UserInfo->Level == 0) + { + UserInfo->WkstaUserInfo.Level0.Buffer = NULL; + UserInfo->WkstaUserInfo.Level0.EntriesRead = 0; + } + else + { + UserInfo->WkstaUserInfo.Level1.Buffer = NULL; + UserInfo->WkstaUserInfo.Level1.EntriesRead = 0; + } + + *TotalEntries = 0; + dwResult = NERR_Success; + } + +done: + if (UserInfoArray !=NULL) + { + + for (i = 0; i < EnumResponseBuffer->NumberOfLoggedOnUsers; i++) + { + if (UserInfoArray[i]->UserName.Buffer != NULL) + LsaFreeReturnBuffer(UserInfoArray[i]->UserName.Buffer); + + if (UserInfoArray[i]->LogonDomainName.Buffer != NULL) + LsaFreeReturnBuffer(UserInfoArray[i]->LogonDomainName.Buffer); + + if (UserInfoArray[i]->LogonServer.Buffer != NULL) + LsaFreeReturnBuffer(UserInfoArray[i]->LogonServer.Buffer); + + LsaFreeReturnBuffer(UserInfoArray[i]); + } + + RtlFreeHeap(RtlGetProcessHeap(), 0, UserInfoArray); + } + + if (EnumResponseBuffer != NULL) + LsaFreeReturnBuffer(EnumResponseBuffer); + + return dwResult; } @@ -376,12 +693,185 @@ __stdcall NetrWkstaUserGetInfo( WKSSVC_IDENTIFY_HANDLE Unused, unsigned long Level, - LPWKSTA_USER_INFO UserInfo) + LPWKSTA_USER_INFO *UserInfo) { - FIXME("(%s, %d, %p)\n", debugstr_w(Unused), Level, UserInfo); + MSV1_0_GETUSERINFO_REQUEST UserInfoRequest; + PMSV1_0_GETUSERINFO_RESPONSE UserInfoResponseBuffer = NULL; + DWORD UserInfoResponseBufferSize = 0; + NTSTATUS Status, ProtocolStatus; + LUID LogonId; + PWKSTA_USER_INFO pUserInfo; + DWORD dwResult = NERR_Success; - UNIMPLEMENTED; - return 0; + TRACE("NetrWkstaUserGetInfo(%s, %d, %p)\n", debugstr_w(Unused), Level, UserInfo); + + if (Unused != NULL) + return ERROR_INVALID_PARAMETER; + + if (Level > 1 && Level != 1101) + return ERROR_INVALID_LEVEL; + + if (Level != 1101) + { + dwResult = NetpGetClientLogonId(&LogonId); + if (dwResult != NERR_Success) + { + ERR("NetpGetClientLogonId() failed (%u)\n", dwResult); + return dwResult; + } + + TRACE("LogonId: 0x%08lx\n", LogonId.LowPart); + + UserInfoRequest.MessageType = MsV1_0GetUserInfo; + UserInfoRequest.LogonId = LogonId; + Status = LsaCallAuthenticationPackage(LsaHandle, + LsaAuthenticationPackage, + &UserInfoRequest, + sizeof(UserInfoRequest), + (PVOID*)&UserInfoResponseBuffer, + &UserInfoResponseBufferSize, + &ProtocolStatus); + TRACE("LsaCallAuthenticationPackage:MsV1_0GetUserInfo Status 0x%08lx ResponseBufferSize %lu\n", Status, UserInfoResponseBufferSize); + if (!NT_SUCCESS(Status)) + { + ERR("\n"); + return RtlNtStatusToDosError(Status); + } + + TRACE("UserName: %wZ\n", &UserInfoResponseBuffer->UserName); + TRACE("LogonDomain: %wZ\n", &UserInfoResponseBuffer->LogonDomainName); + TRACE("LogonServer: %wZ\n", &UserInfoResponseBuffer->LogonServer); + } + + switch (Level) + { + case 0: + pUserInfo = midl_user_allocate(sizeof(WKSTA_USER_INFO_0)); + if (pUserInfo == NULL) + { + ERR("\n"); + dwResult = ERROR_NOT_ENOUGH_MEMORY; + break; + } + + ZeroMemory(pUserInfo, sizeof(WKSTA_USER_INFO_0)); + + /* User Name */ + pUserInfo->UserInfo0.wkui0_username = + midl_user_allocate(UserInfoResponseBuffer->UserName.Length + sizeof(WCHAR)); + if (pUserInfo->UserInfo0.wkui0_username == NULL) + { + ERR("\n"); + midl_user_free(pUserInfo); + dwResult = ERROR_NOT_ENOUGH_MEMORY; + break; + } + + ZeroMemory(pUserInfo->UserInfo0.wkui0_username, + UserInfoResponseBuffer->UserName.Length + sizeof(WCHAR)); + CopyMemory(pUserInfo->UserInfo0.wkui0_username, + UserInfoResponseBuffer->UserName.Buffer, + UserInfoResponseBuffer->UserName.Length); + + *UserInfo = pUserInfo; + break; + + case 1: + pUserInfo = midl_user_allocate(sizeof(WKSTA_USER_INFO_1)); + if (pUserInfo == NULL) + { + ERR("\n"); + dwResult = ERROR_NOT_ENOUGH_MEMORY; + break; + } + + ZeroMemory(pUserInfo, sizeof(WKSTA_USER_INFO_1)); + + /* User Name */ + pUserInfo->UserInfo1.wkui1_username = + midl_user_allocate(UserInfoResponseBuffer->UserName.Length + sizeof(WCHAR)); + if (pUserInfo->UserInfo1.wkui1_username == NULL) + { + ERR("\n"); + midl_user_free(pUserInfo); + dwResult = ERROR_NOT_ENOUGH_MEMORY; + break; + } + + ZeroMemory(pUserInfo->UserInfo1.wkui1_username, + UserInfoResponseBuffer->UserName.Length + sizeof(WCHAR)); + CopyMemory(pUserInfo->UserInfo1.wkui1_username, + UserInfoResponseBuffer->UserName.Buffer, + UserInfoResponseBuffer->UserName.Length); + + /* Logon Domain Name */ + pUserInfo->UserInfo1.wkui1_logon_domain = + midl_user_allocate(UserInfoResponseBuffer->LogonDomainName.Length + sizeof(WCHAR)); + if (pUserInfo->UserInfo1.wkui1_logon_domain == NULL) + { + ERR("\n"); + midl_user_free(pUserInfo->UserInfo1.wkui1_username); + midl_user_free(pUserInfo); + dwResult = ERROR_NOT_ENOUGH_MEMORY; + break; + } + + ZeroMemory(pUserInfo->UserInfo1.wkui1_logon_domain, + UserInfoResponseBuffer->LogonDomainName.Length + sizeof(WCHAR)); + CopyMemory(pUserInfo->UserInfo1.wkui1_logon_domain, + UserInfoResponseBuffer->LogonDomainName.Buffer, + UserInfoResponseBuffer->LogonDomainName.Length); + + /* FIXME: wkui1_oth_domains */ + + /* Logon Server */ + pUserInfo->UserInfo1.wkui1_logon_server = + midl_user_allocate(UserInfoResponseBuffer->LogonServer.Length + sizeof(WCHAR)); + if (pUserInfo->UserInfo1.wkui1_logon_server == NULL) + { + ERR("\n"); + midl_user_free(pUserInfo->UserInfo1.wkui1_username); + midl_user_free(pUserInfo->UserInfo1.wkui1_logon_domain); + midl_user_free(pUserInfo); + dwResult = ERROR_NOT_ENOUGH_MEMORY; + break; + } + + ZeroMemory(pUserInfo->UserInfo1.wkui1_logon_server, + UserInfoResponseBuffer->LogonServer.Length + sizeof(WCHAR)); + CopyMemory(pUserInfo->UserInfo1.wkui1_logon_server, + UserInfoResponseBuffer->LogonServer.Buffer, + UserInfoResponseBuffer->LogonServer.Length); + + *UserInfo = pUserInfo; + break; + + case 1101: + pUserInfo = midl_user_allocate(sizeof(WKSTA_USER_INFO_1101)); + if (pUserInfo == NULL) + { + ERR("Failed to allocate WKSTA_USER_INFO_1101\n"); + dwResult = ERROR_NOT_ENOUGH_MEMORY; + break; + } + + ZeroMemory(pUserInfo, sizeof(WKSTA_USER_INFO_1101)); + + /* FIXME: wkui1101_oth_domains */ + + *UserInfo = pUserInfo; + break; + + default: + ERR("\n"); + dwResult = ERROR_INVALID_LEVEL; + break; + } + + if (UserInfoResponseBuffer) + LsaFreeReturnBuffer(UserInfoResponseBuffer); + + return dwResult; } diff --git a/base/setup/lib/bootsup.c b/base/setup/lib/bootsup.c index 4c57fc8218b02..aa0ed8f31946b 100644 --- a/base/setup/lib/bootsup.c +++ b/base/setup/lib/bootsup.c @@ -19,7 +19,8 @@ #include "bootcode.h" #include "fsutil.h" -#include "setuplib.h" // HACK for IsUnattendedSetup +#include "setuplib.h" +extern BOOLEAN IsUnattendedSetup; // HACK #include "bootsup.h" @@ -880,7 +881,6 @@ InstallMbrBootCodeToDisk( InstallMbrBootCode); } - static NTSTATUS InstallBootloaderFiles( @@ -895,7 +895,19 @@ InstallBootloaderFiles( CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\freeldr.sys"); CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, L"freeldr.sys"); - DPRINT1("Copy: %S ==> %S\n", SrcPath, DstPath); + DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath); + Status = SetupCopyFile(SrcPath, DstPath, FALSE); + if (!NT_SUCCESS(Status)) + { + DPRINT1("SetupCopyFile() failed (Status 0x%08lx)\n", Status); + return Status; + } + + /* Copy rosload to the system partition, always overwriting the older version */ + CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\rosload.exe"); + CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, L"rosload.exe"); + + DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath); Status = SetupCopyFile(SrcPath, DstPath, FALSE); if (!NT_SUCCESS(Status)) { diff --git a/base/setup/lib/install.c b/base/setup/lib/install.c index a9bc1828db403..de883f138997b 100644 --- a/base/setup/lib/install.c +++ b/base/setup/lib/install.c @@ -61,7 +61,7 @@ LookupDirectoryById( * but here we try to remove this constraint. * * TXTSETUP.SIF entries syntax explained at: - * http://www.msfn.org/board/topic/125480-txtsetupsif-syntax/ + * https://msfn.org/board/topic/125480-txtsetupsif-syntax/ */ static NTSTATUS GetSourceFileAndTargetLocation( diff --git a/base/setup/lib/precomp.h b/base/setup/lib/precomp.h index 2195c55a9e628..fac676f9658cf 100644 --- a/base/setup/lib/precomp.h +++ b/base/setup/lib/precomp.h @@ -14,7 +14,6 @@ #include #include #include -#include #define NTOS_MODE_USER #include diff --git a/base/setup/lib/registry.c b/base/setup/lib/registry.c index 6c02869a282c4..e899f9e341e9c 100644 --- a/base/setup/lib/registry.c +++ b/base/setup/lib/registry.c @@ -712,7 +712,7 @@ RegInitializeRegistry( * Use a dummy root key name: * - On 2k/XP/2k3, this is "$$$PROTO.HIV" * - On Vista+, this is "CMI-CreateHive{guid}" - * See https://github.com/libyal/winreg-kb/blob/master/documentation/Registry%20files.asciidoc + * See https://github.com/libyal/winreg-kb/blob/main/docs/sources/windows-registry/Files.md * for more information. */ RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\SYSTEM\\$$$PROTO.HIV"); diff --git a/base/setup/lib/setuplib.c b/base/setup/lib/setuplib.c index 862c90207191b..a4b80bd2a1320 100644 --- a/base/setup/lib/setuplib.c +++ b/base/setup/lib/setuplib.c @@ -27,7 +27,7 @@ BOOLEAN IsUnattendedSetup = FALSE; /* FUNCTIONS ****************************************************************/ -VOID +BOOLEAN NTAPI CheckUnattendedSetup( IN OUT PUSETUP_DATA pSetupData) @@ -47,7 +47,7 @@ CheckUnattendedSetup( if (DoesFileExist(NULL, UnattendInfPath) == FALSE) { DPRINT("Does not exist: %S\n", UnattendInfPath); - return; + return IsUnattendedSetup; } /* Load 'unattend.inf' from installation media */ @@ -59,7 +59,7 @@ CheckUnattendedSetup( if (UnattendInf == INVALID_HANDLE_VALUE) { DPRINT("SpInfOpenInfFile() failed\n"); - return; + return IsUnattendedSetup; } /* Open 'Unattend' section */ @@ -200,6 +200,7 @@ CheckUnattendedSetup( Quit: SpInfCloseInfFile(UnattendInf); + return IsUnattendedSetup; } VOID diff --git a/base/setup/lib/setuplib.h b/base/setup/lib/setuplib.h index d969e894e8ac1..d0b49a7757c82 100644 --- a/base/setup/lib/setuplib.h +++ b/base/setup/lib/setuplib.h @@ -30,8 +30,6 @@ extern "C" { #endif -extern SPLIBAPI BOOLEAN IsUnattendedSetup; // HACK - /* NOTE: Please keep the header inclusion order! */ #include "errorcode.h" @@ -112,11 +110,11 @@ typedef struct _USETUP_DATA * * For more information, see: * https://en.wikipedia.org/wiki/System_partition_and_boot_partition - * http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/boot-and-system-volumes.html - * http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/arc-boot-process.html - * http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/efi-boot-process.html - * http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/determining-system-volume.html - * http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/determining-boot-volume.html + * https://web.archive.org/web/20160604095323/http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/boot-and-system-volumes.html + * https://web.archive.org/web/20160604095238/http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/arc-boot-process.html + * https://web.archive.org/web/20160508052211/http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/efi-boot-process.html + * https://web.archive.org/web/20160604093304/http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/determining-system-volume.html + * https://web.archive.org/web/20160604095540/http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/determining-boot-volume.html */ UNICODE_STRING SystemRootPath; @@ -167,7 +165,7 @@ typedef struct _USETUP_DATA #include "substset.h" -VOID +BOOLEAN NTAPI CheckUnattendedSetup( IN OUT PUSETUP_DATA pSetupData); diff --git a/base/setup/lib/setuplib.spec b/base/setup/lib/setuplib.spec index a2809a06b0a05..acfaa4ce680e0 100644 --- a/base/setup/lib/setuplib.spec +++ b/base/setup/lib/setuplib.spec @@ -1,8 +1,4 @@ -@ extern IsUnattendedSetup -@ extern MbrPartitionTypes -@ extern GptPartitionTypes - ;; fileqsup and infsupp function pointers to be initialized by the user of this library ;;@ extern SpFileExports ;;@ extern SpInfExports @@ -10,7 +6,6 @@ ;; infsupp @ cdecl INF_GetDataField(ptr long ptr) ## -private - ;; filesup @ cdecl ConcatPathsV(ptr long long ptr) @ cdecl CombinePathsV(ptr long long ptr) @@ -44,6 +39,9 @@ @ cdecl IsPartitionActive(ptr) ## -private @ cdecl SelectPartition(ptr long long) +;; partinfo +@ stdcall LookupPartitionTypeString(long ptr) + ;; osdetect @ stdcall CreateNTOSInstallationsList(ptr) @ stdcall FindSubStrI(wstr wstr) diff --git a/base/setup/lib/utils/arcname.c b/base/setup/lib/utils/arcname.c index a29076a2fdf26..e6db10046f0dc 100644 --- a/base/setup/lib/utils/arcname.c +++ b/base/setup/lib/utils/arcname.c @@ -8,14 +8,14 @@ * References: * * - ARC Specification v1.2: http://netbsd.org./docs/Hardware/Machines/ARC/riscspec.pdf - * - "Setup and Startup", MSDN article: https://technet.microsoft.com/en-us/library/cc977184.aspx - * - Answer for "How do I determine the ARC path for a particular drive letter in Windows?": https://serverfault.com/a/5929 - * - ARC - LinuxMIPS: https://www.linux-mips.org/wiki/ARC - * - ARCLoad - LinuxMIPS: https://www.linux-mips.org/wiki/ARCLoad + * - "Setup and Startup", MSDN article: https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-2000-server/cc977184(v=technet.10) + * - Answer for "How do I determine the ARC path for a particular drive letter in Windows?": https://serverfault.com/questions/5910/how-do-i-determine-the-arc-path-for-a-particular-drive-letter-in-windows/5929#5929 + * - ARC - LinuxMIPS: https://web.archive.org/web/20230922043211/https://www.linux-mips.org/wiki/ARC + * - ARCLoad - LinuxMIPS: https://web.archive.org/web/20221002210224/https://www.linux-mips.org/wiki/ARCLoad * - Inside Windows 2000 Server: https://books.google.fr/books?id=kYT7gKnwUQ8C&pg=PA71&lpg=PA71&dq=nt+arc+path&source=bl&ots=K8I1F_KQ_u&sig=EJq5t-v2qQk-QB7gNSREFj7pTVo&hl=en&sa=X&redir_esc=y#v=onepage&q=nt%20arc%20path&f=false * - Inside Windows Server 2003: https://books.google.fr/books?id=zayrcM9ZYdAC&pg=PA61&lpg=PA61&dq=arc+path+to+nt+path&source=bl&ots=x2JSWfp2MA&sig=g9mufN6TCOrPejDov6Rjp0Jrldo&hl=en&sa=X&redir_esc=y#v=onepage&q=arc%20path%20to%20nt%20path&f=false * - * Stuff to read: http://www.adminxp.com/windows2000/index.php?aid=46 and http://www.trcb.com/Computers-and-Technology/Windows-XP/Windows-XP-ARC-Naming-Conventions-1432.htm + * Stuff to read: http://www.adminxp.com/windows2000/index.php?aid=46 and https://web.archive.org/web/20170923151458/http://www.trcb.com/Computers-and-Technology/Windows-XP/Windows-XP-ARC-Naming-Conventions-1432.htm * concerning which values of disk() or rdisk() are valid when either scsi() or multi() adapters are specified. */ diff --git a/base/setup/lib/utils/bldrsup.c b/base/setup/lib/utils/bldrsup.c index ad13cbe51dfad..097a79dc222c4 100644 --- a/base/setup/lib/utils/bldrsup.c +++ b/base/setup/lib/utils/bldrsup.c @@ -124,7 +124,7 @@ NtLdrEnumerateBootEntries( // Question 2: What if many config files are possible? NTOS_BOOT_LOADER_FILES NtosBootLoaders[] = { - {FreeLdr, L"freeldr.sys\0", L"freeldr.ini", + {FreeLdr, L"freeldr.sys\0" L"rosload.exe\0", L"freeldr.ini", OpenIniBootLoaderStore, CloseIniBootLoaderStore, (PENUM_BOOT_STORE_ENTRIES)FreeLdrEnumerateBootEntries}, {NtLdr , L"ntldr\0" L"osloader.exe\0", L"boot.ini", OpenIniBootLoaderStore, CloseIniBootLoaderStore, (PENUM_BOOT_STORE_ENTRIES)NtLdrEnumerateBootEntries }, diff --git a/base/setup/lib/utils/bldrsup.h b/base/setup/lib/utils/bldrsup.h index 4496cbbea3d52..568d29a9f4f0a 100644 --- a/base/setup/lib/utils/bldrsup.h +++ b/base/setup/lib/utils/bldrsup.h @@ -20,8 +20,8 @@ typedef enum _BOOT_STORE_TYPE /* * Some references about EFI boot entries: - * https://docs.microsoft.com/en-us/windows-hardware/drivers/devtest/overview-of-boot-options-in-efi - * https://docs.microsoft.com/en-us/windows-hardware/drivers/devtest/identifying-backup-files-for-existing-boot-entries + * https://learn.microsoft.com/en-us/windows-hardware/drivers/devtest/overview-of-boot-options-in-efi + * https://learn.microsoft.com/en-us/windows-hardware/drivers/devtest/identifying-backup-files-for-existing-boot-entries */ /* diff --git a/base/setup/lib/utils/ntverrsrc.c b/base/setup/lib/utils/ntverrsrc.c index d8c1c64fc66fa..fc9859d416f77 100644 --- a/base/setup/lib/utils/ntverrsrc.c +++ b/base/setup/lib/utils/ntverrsrc.c @@ -22,26 +22,27 @@ /* FUNCTIONS ****************************************************************/ +#define MAKEINTRESOURCE(i) ((ULONG_PTR)(USHORT)(i)) +#define RT_VERSION MAKEINTRESOURCE(16) // See psdk/winuser.h +#define VS_VERSION_INFO 1 // See psdk/verrsrc.h +#define VS_FILE_INFO RT_VERSION + NTSTATUS NtGetVersionResource( IN PVOID BaseAddress, OUT PVOID* Resource, OUT PULONG ResourceSize OPTIONAL) { -// #define RT_VERSION MAKEINTRESOURCE(16) // See winuser.h -#define VS_VERSION_INFO 1 // See psdk/verrsrc.h -#define VS_FILE_INFO RT_VERSION - NTSTATUS Status; LDR_RESOURCE_INFO ResourceInfo; PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry; PVOID Data = NULL; ULONG Size = 0; - /* Try to find the resource */ - ResourceInfo.Type = 16; // RT_VERSION; - ResourceInfo.Name = VS_VERSION_INFO; // MAKEINTRESOURCEW(VS_VERSION_INFO); - ResourceInfo.Language = 0; // Don't care about the language + /* Try to find the resource (language-neutral) */ + ResourceInfo.Type = RT_VERSION; + ResourceInfo.Name = VS_VERSION_INFO; + ResourceInfo.Language = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL); Status = LdrFindResource_U(BaseAddress, &ResourceInfo, diff --git a/base/setup/lib/utils/partinfo.c b/base/setup/lib/utils/partinfo.c index bf6d98fde2427..6f813b97c5150 100644 --- a/base/setup/lib/utils/partinfo.c +++ b/base/setup/lib/utils/partinfo.c @@ -1,21 +1,21 @@ /* * PROJECT: ReactOS Setup Library - * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) * PURPOSE: MBR and GPT Partition types - * COPYRIGHT: Copyright 2018-2020 Hermes Belusca-Maito + * COPYRIGHT: Copyright 2018-2025 Hermès Bélusca-Maïto */ #include "precomp.h" #include "partinfo.h" -/* MBR PARTITION TYPES ******************************************************/ +/* MBR PARTITION TYPES *******************************************************/ /* * This partition type list is based from: * - the kernelDisk.c module of the Visopsys Operating System (see license below), * - Paragon Hard-Disk Manager, * - Haiku OS (Copyright 2003-2011, Haiku, Inc., under the terms of the MIT License) - * https://git.haiku-os.org/haiku/tree/src/add-ons/kernel/partitioning_systems/intel/PartitionMap.cpp#n52 + * https://git.haiku-os.org/haiku/tree/src/add-ons/kernel/partitioning_systems/intel/PartitionMap.cpp#n52 (DEAD_LINK) * - and the following websites: * http://www.win.tue.nl/~aeb/partitions/partition_types-1.html * https://en.wikipedia.org/wiki/Partition_type#List_of_partition_IDs @@ -42,8 +42,14 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +typedef struct _MBR_PARTITION_TYPE +{ + UCHAR Type; + PCSTR Description; +} MBR_PARTITION_TYPE, *PMBR_PARTITION_TYPE; + /* Known MBR partition type codes and descriptions */ -const MBR_PARTITION_TYPE MbrPartitionTypes[NUM_MBR_PARTITION_TYPES] = +const MBR_PARTITION_TYPE MbrPartitionTypes[] = { { 0x00, "(Empty)" }, // PARTITION_ENTRY_UNUSED { 0x01, "FAT12" }, // PARTITION_FAT_12 @@ -201,7 +207,7 @@ const MBR_PARTITION_TYPE MbrPartitionTypes[NUM_MBR_PARTITION_TYPES] = }; -/* GPT PARTITION TYPES ******************************************************/ +/* GPT PARTITION TYPES *******************************************************/ #define GUID_CONST(l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } @@ -267,8 +273,14 @@ DEFINE_GUID(PARTITION_DPP_GUID, 0x57434F53, 0x94CB, 0x43F0, 0xA5, 0 * https://www.magnumdb.com/search?q=PARTITION_* */ +typedef struct _GPT_PARTITION_TYPE +{ + GUID Guid; + PCSTR Description; +} GPT_PARTITION_TYPE, *PGPT_PARTITION_TYPE; + /* Known GPT partition type GUIDs and descriptions */ -const GPT_PARTITION_TYPE GptPartitionTypes[NUM_GPT_PARTITION_TYPES] = +const GPT_PARTITION_TYPE GptPartitionTypes[] = { /* * EFI specification @@ -784,4 +796,44 @@ const GPT_PARTITION_TYPE GptPartitionTypes[NUM_GPT_PARTITION_TYPES] = "ArcaOS Type 1" }, }; + +/* PARTITION TYPES LOOKUP ****************************************************/ + +PCSTR +NTAPI +LookupPartitionTypeString( + _In_ PARTITION_STYLE PartitionStyle, + _In_ PVOID PartitionType) +{ + UINT i; + + /* Do the table lookup */ + if (PartitionStyle == PARTITION_STYLE_MBR) + { + for (i = 0; i < _countof(MbrPartitionTypes); ++i) + { + if (*(PUCHAR)PartitionType == MbrPartitionTypes[i].Type) + { + return MbrPartitionTypes[i].Description; + } + } + } +#if 0 // TODO: GPT support! + else if (PartitionStyle == PARTITION_STYLE_GPT) + { + for (i = 0; i < _countof(GptPartitionTypes); ++i) + { + if (IsEqualPartitionType((PGUID)PartitionType, + &GptPartitionTypes[i].Guid)) + { + return GptPartitionTypes[i].Description; + } + } + } +#endif + + /* The partition type is unknown */ + return NULL; +} + /* EOF */ diff --git a/base/setup/lib/utils/partinfo.h b/base/setup/lib/utils/partinfo.h index dac7af89158ac..774a39982b37a 100644 --- a/base/setup/lib/utils/partinfo.h +++ b/base/setup/lib/utils/partinfo.h @@ -1,32 +1,16 @@ /* * PROJECT: ReactOS Setup Library - * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) * PURPOSE: MBR and GPT Partition types - * COPYRIGHT: Copyright 2018-2020 Hermes Belusca-Maito + * COPYRIGHT: Copyright 2018-2025 Hermès Bélusca-Maïto */ #pragma once -/* MBR PARTITION TYPES ******************************************************/ - -typedef struct _MBR_PARTITION_TYPE -{ - UCHAR Type; - PCSTR Description; -} MBR_PARTITION_TYPE, *PMBR_PARTITION_TYPE; - -#define NUM_MBR_PARTITION_TYPES 153 -extern SPLIBAPI const MBR_PARTITION_TYPE MbrPartitionTypes[NUM_MBR_PARTITION_TYPES]; - -/* GPT PARTITION TYPES ******************************************************/ - -typedef struct _GPT_PARTITION_TYPE -{ - GUID Guid; - PCSTR Description; -} GPT_PARTITION_TYPE, *PGPT_PARTITION_TYPE; - -#define NUM_GPT_PARTITION_TYPES 177 -extern SPLIBAPI const GPT_PARTITION_TYPE GptPartitionTypes[NUM_GPT_PARTITION_TYPES]; +PCSTR +NTAPI +LookupPartitionTypeString( + _In_ PARTITION_STYLE PartitionStyle, + _In_ PVOID PartitionType); /* EOF */ diff --git a/base/setup/reactos/drivepage.c b/base/setup/reactos/drivepage.c index dc4fc64cfb522..274aa069ac3ee 100644 --- a/base/setup/reactos/drivepage.c +++ b/base/setup/reactos/drivepage.c @@ -896,36 +896,14 @@ GetPartitionTypeString( } else { - UINT i; - /* Do the table lookup */ - if (PartEntry->DiskEntry->DiskStyle == PARTITION_STYLE_MBR) - { - for (i = 0; i < ARRAYSIZE(MbrPartitionTypes); ++i) - { - if (PartEntry->PartitionType == MbrPartitionTypes[i].Type) - { - StringCchCopyA(strBuffer, cchBuffer, - MbrPartitionTypes[i].Description); - return; - } - } - } -#if 0 // TODO: GPT support! - else if (PartEntry->DiskEntry->DiskStyle == PARTITION_STYLE_GPT) + PCSTR Description = LookupPartitionTypeString(PartEntry->DiskEntry->DiskStyle, + &PartEntry->PartitionType); + if (Description) { - for (i = 0; i < ARRAYSIZE(GptPartitionTypes); ++i) - { - if (IsEqualPartitionType(PartEntry->PartitionType, - GptPartitionTypes[i].Guid)) - { - StringCchCopyA(strBuffer, cchBuffer, - GptPartitionTypes[i].Description); - return; - } - } + StringCchCopyA(strBuffer, cchBuffer, Description); + return; } -#endif /* We are here because the partition type is unknown */ if (cchBuffer > 0) *strBuffer = '\0'; diff --git a/base/setup/reactos/lang/bg-BG.rc b/base/setup/reactos/lang/bg-BG.rc index 7c230e346b4d9..dd3fe00e6b7ec 100644 --- a/base/setup/reactos/lang/bg-BG.rc +++ b/base/setup/reactos/lang/bg-BG.rc @@ -8,8 +8,18 @@ CAPTION "Настройка на РеактОС" FONT 8, "MS Shell Dlg" BEGIN LTEXT "Съветникът за настройка на РеактОС ви приветства", IDC_STARTTITLE, 115, 8, 195, 24 - LTEXT "Все още не можете да сложите РеактОС направо от този КД! Презапуснете компютъра с този КД, за да сложите РеактОС.", IDC_STATIC, 115, 40, 195, 100 - LTEXT "Натиснете „Приключване“ за изход от настройването.", IDC_STATIC, 115, 169, 195, 17 + LTEXT "This wizard will install or upgrade ReactOS on your computer, \ +and prepare the second part of the setup.", IDC_STATIC, 115, 40, 195, 27 +//// + GROUPBOX " IMPORTANT INFORMATION ", IDC_WARNTEXT1, 115, 70, 195, 90, BS_CENTER + LTEXT "ReactOS is in Alpha stage: it is not feature- complete and is \ +under heavy development. It is recommended to use it only for \ +evaluation and testing and not as your daily-usage OS.\n\ +It may corrupt your data or damage your hardware.", IDC_WARNTEXT2, 120, 80, 185, 50, SS_CENTER + LTEXT "Backup your data or test on a secondary computer \ +if you attempt to run ReactOS on real hardware.", IDC_WARNTEXT3, 120, 130, 185, 27, SS_CENTER +//// + LTEXT "Натиснете „Напред“ за продължаване на настройката.", IDC_STATIC, 115, 169, 195, 17 END IDD_TYPEPAGE DIALOGEX 0, 0, 317, 143 @@ -17,11 +27,10 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "Настройка на РеактОС" FONT 8, "MS Shell Dlg" BEGIN - AUTORADIOBUTTON "Слагане на РеактОС", IDC_INSTALL, 7, 7, 277, 10, WS_GROUP | WS_TABSTOP - LTEXT "Install a new copy of ReactOS. This option does not keep your files, settings and programs. You can make changes to disks and partitions.", IDC_INSTALLTEXT, 18, 18, 269, 25, NOT WS_GROUP - AUTORADIOBUTTON "Поправка или осъвременяване на сложен РеактОС", IDC_UPDATE, 7, 50, 277, 10 - LTEXT "Update or repair an installed copy of ReactOS. This option keeps your files, settings and programs. This option is only available if ReactOS is already installed on this computer.", IDC_UPDATETEXT, 18, 61, 269, 30, NOT WS_GROUP - LTEXT "Натиснете „Напред“ за настройка на устройствата.", IDC_STATIC, 7, 128, 297, 8 + AUTORADIOBUTTON "&Слагане на РеактОС", IDC_INSTALL, 7, 20, 277, 10, WS_GROUP | WS_TABSTOP + LTEXT "Install a new copy of ReactOS. This option does not keep your files, settings and programs. You can make changes to disks and partitions.", IDC_INSTALLTEXT, 19, 36, 279, 27, NOT WS_GROUP + AUTORADIOBUTTON "&Поправка или осъвременяване на РеактОС", IDC_UPDATE, 7, 80, 277, 10 + LTEXT "Update or repair an installed copy of ReactOS. This option keeps your files, settings and programs. This option is only available if ReactOS is already installed on this computer.", IDC_UPDATETEXT, 19, 96, 279, 27, NOT WS_GROUP END IDD_UPDATEREPAIRPAGE DIALOGEX 0, 0, 317, 143 @@ -161,8 +170,10 @@ END STRINGTABLE BEGIN IDS_CAPTION "Настройка на РеактОС" - IDS_TYPETITLE "РеактОС ви приветства!" - IDS_TYPESUBTITLE "Изберете вид на настройването." + IDS_TYPETITLE "Installation Type" + IDS_TYPESUBTITLE "You can setup a new ReactOS installation, or update/repair an existing installation." + IDS_UPDATETITLE "Update or Repair ReactOS" + IDS_UPDATESUBTITLE "Choose which existing ReactOS installation you want to update or repair." IDS_DEVICETITLE "Настройване на основните устройства" IDS_DEVICESUBTITLE "Настройка на екрана и клавиатурата." IDS_DRIVETITLE "Приготвяне на дял за слагане и системна папка" diff --git a/base/setup/reactos/lang/cs-CZ.rc b/base/setup/reactos/lang/cs-CZ.rc index 8f1b30091c773..8d694465d5d7e 100644 --- a/base/setup/reactos/lang/cs-CZ.rc +++ b/base/setup/reactos/lang/cs-CZ.rc @@ -14,8 +14,18 @@ CAPTION "Instalace systému ReactOS" FONT 8, "MS Shell Dlg" BEGIN LTEXT "Vítejte v průvodci instalace systému ReactOS", IDC_STARTTITLE, 115, 8, 195, 24 - LTEXT "Systém ReactOS zatím nelze nainstalovat přímo z tohoto CD! Pro instalaci restartuje počítač z tohoto CD.", IDC_STATIC, 115, 40, 195, 100 - LTEXT "Klepnutím na Dokončit ukončíte instalaci.", IDC_STATIC, 115, 169, 195, 17 + LTEXT "This wizard will install or upgrade ReactOS on your computer, \ +and prepare the second part of the setup.", IDC_STATIC, 115, 40, 195, 27 +//// + GROUPBOX " IMPORTANT INFORMATION ", IDC_WARNTEXT1, 115, 70, 195, 90, BS_CENTER + LTEXT "ReactOS is in Alpha stage: it is not feature- complete and is \ +under heavy development. It is recommended to use it only for \ +evaluation and testing and not as your daily-usage OS.\n\ +It may corrupt your data or damage your hardware.", IDC_WARNTEXT2, 120, 80, 185, 50, SS_CENTER + LTEXT "Backup your data or test on a secondary computer \ +if you attempt to run ReactOS on real hardware.", IDC_WARNTEXT3, 120, 130, 185, 27, SS_CENTER +//// + LTEXT "Kliknutím na Další pokračujte v instalaci.", IDC_STATIC, 115, 169, 195, 17 END IDD_TYPEPAGE DIALOGEX 0, 0, 317, 143 @@ -23,11 +33,10 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "Instalace systému ReactOS" FONT 8, "MS Shell Dlg" BEGIN - AUTORADIOBUTTON "Nainstalovat systém ReactOS", IDC_INSTALL, 7, 7, 277, 10, WS_GROUP | WS_TABSTOP - LTEXT "Instalovat novou kopii systému ReactOS. Tato možnost odstraní Vaše soubory, nastavení a programy. Můžete provést úpravu disků a oddílů.", IDC_INSTALLTEXT, 18, 18, 269, 25, NOT WS_GROUP - AUTORADIOBUTTON "Opravit nebo aktualizovat již nainstalovaný systém ReactOS", IDC_UPDATE, 7, 50, 277, 10 - LTEXT "Aktualizovat nebo opravit kopii systémy ReactOS. Tato možnost zachová Vaše soubory, nastavení a programy. Tato možnost je dostupná pouze pokud je již na Vašem počítači systém ReactOS nainstalován.", IDC_UPDATETEXT, 18, 61, 269, 30, NOT WS_GROUP - LTEXT "Po klepnutí na Další bude možné nastavit zařízení.", IDC_STATIC, 7, 128, 297, 8 + AUTORADIOBUTTON "&Nainstalovat systém ReactOS", IDC_INSTALL, 7, 20, 277, 10, WS_GROUP | WS_TABSTOP + LTEXT "Instalovat novou kopii systému ReactOS. Tato možnost odstraní Vaše soubory, nastavení a programy. Můžete provést úpravu disků a oddílů.", IDC_INSTALLTEXT, 19, 36, 279, 27, NOT WS_GROUP + AUTORADIOBUTTON "&Opravit nebo aktualizovat ReactOS", IDC_UPDATE, 7, 80, 277, 10 + LTEXT "Aktualizovat nebo opravit kopii systémy ReactOS. Tato možnost zachová Vaše soubory, nastavení a programy. Tato možnost je dostupná pouze pokud je již na Vašem počítači systém ReactOS nainstalován.", IDC_UPDATETEXT, 19, 96, 279, 27, NOT WS_GROUP END IDD_UPDATEREPAIRPAGE DIALOGEX 0, 0, 317, 143 @@ -167,8 +176,10 @@ END STRINGTABLE BEGIN IDS_CAPTION "Instalace systému ReactOS" - IDS_TYPETITLE "Vítejte v průvodci instalace systému ReactOS" - IDS_TYPESUBTITLE "Volba typu instalace." + IDS_TYPETITLE "Installation Type" + IDS_TYPESUBTITLE "You can setup a new ReactOS installation, or update/repair an existing installation." + IDS_UPDATETITLE "Update or Repair ReactOS" + IDS_UPDATESUBTITLE "Choose which existing ReactOS installation you want to update or repair." IDS_DEVICETITLE "Nastavení základních zařízení" IDS_DEVICESUBTITLE "Volba nastavení obrazovky a klávesnice." IDS_DRIVETITLE "Nastavení instalačního oddílu a systémové složky" diff --git a/base/setup/reactos/lang/de-DE.rc b/base/setup/reactos/lang/de-DE.rc index ffb2edbd21786..29f03b8a5bf81 100644 --- a/base/setup/reactos/lang/de-DE.rc +++ b/base/setup/reactos/lang/de-DE.rc @@ -7,9 +7,19 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "ReactOS-Setup" FONT 8, "MS Shell Dlg" BEGIN - LTEXT "Willkommen beim ReactOS-Setup-Assistenten", IDC_STARTTITLE, 115, 8, 195, 24 - LTEXT "ReactOS kann noch nicht direkt von dieser CD installiert werden! Bitte starten Sie Ihren Computer mit dieser CD um ReactOS zu installieren.", IDC_STATIC, 115, 40, 195, 100 - LTEXT "Klicken Sie auf Beenden um das Setup zu verlassen.", IDC_STATIC, 115, 169, 195, 17 + LTEXT "Willkommen beim ReactOS Installationsassistenten", IDC_STARTTITLE, 115, 8, 195, 24 + LTEXT "This wizard will install or upgrade ReactOS on your computer, \ +and prepare the second part of the setup.", IDC_STATIC, 115, 40, 195, 27 +//// + GROUPBOX " IMPORTANT INFORMATION ", IDC_WARNTEXT1, 115, 70, 195, 90, BS_CENTER + LTEXT "ReactOS is in Alpha stage: it is not feature- complete and is \ +under heavy development. It is recommended to use it only for \ +evaluation and testing and not as your daily-usage OS.\n\ +It may corrupt your data or damage your hardware.", IDC_WARNTEXT2, 120, 80, 185, 50, SS_CENTER + LTEXT "Backup your data or test on a secondary computer \ +if you attempt to run ReactOS on real hardware.", IDC_WARNTEXT3, 120, 130, 185, 27, SS_CENTER +//// + LTEXT "Klicken Sie auf Weiter, um fortzufahren.", IDC_STATIC, 115, 169, 195, 17 END IDD_TYPEPAGE DIALOGEX 0, 0, 317, 143 @@ -17,11 +27,10 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "ReactOS-Setup" FONT 8, "MS Shell Dlg" BEGIN - AUTORADIOBUTTON "Installiere ReactOS", IDC_INSTALL, 7, 7, 277, 10, WS_GROUP | WS_TABSTOP - LTEXT "Installiert eine neue Kopie von ReactOS. Diese Option behält nicht Ihre Dateien, Einstellungen und Programme bei. Sie können Änderungen an Festplatten und Partitionen durchführen.", IDC_INSTALLTEXT, 18, 18, 269, 25, NOT WS_GROUP - AUTORADIOBUTTON "Aktualisiere oder repariere ein installiertes ReactOS", IDC_UPDATE, 7, 50, 277, 10 - LTEXT "Aktualisieren oder reparieren einer installierten Kopie von ReactOS. Diese Option behält Ihre Dateien, Einstellungen und Programme bei. Diese Option ist nur verfügbar, wenn ReactOS bereits auf diesem Computer installiert ist.", IDC_UPDATETEXT, 18, 61, 269, 30, NOT WS_GROUP - LTEXT "Klicken Sie auf Weiter um die Geräte einzustellen.", IDC_STATIC, 7, 128, 297, 8 + AUTORADIOBUTTON "&Installiere ReactOS", IDC_INSTALL, 7, 20, 277, 10, WS_GROUP | WS_TABSTOP + LTEXT "Installiert eine neue Kopie von ReactOS. Diese Option behält nicht Ihre Dateien, Einstellungen und Programme bei. Sie können Änderungen an Festplatten und Partitionen durchführen.", IDC_INSTALLTEXT, 19, 36, 279, 27, NOT WS_GROUP + AUTORADIOBUTTON "&Aktualisiere oder repariere ReactOS", IDC_UPDATE, 7, 80, 277, 10 + LTEXT "Aktualisieren oder reparieren einer installierten Kopie von ReactOS. Diese Option behält Ihre Dateien, Einstellungen und Programme bei. Diese Option ist nur verfügbar, wenn ReactOS bereits auf diesem Computer installiert ist.", IDC_UPDATETEXT, 19, 96, 279, 27, NOT WS_GROUP END IDD_UPDATEREPAIRPAGE DIALOGEX 0, 0, 317, 143 @@ -161,8 +170,10 @@ END STRINGTABLE BEGIN IDS_CAPTION "ReactOS Setup" - IDS_TYPETITLE "Willkommen zum ReactOS-Setup" - IDS_TYPESUBTITLE "Wählen Sie einen Setuptypen." + IDS_TYPETITLE "Installation Type" + IDS_TYPESUBTITLE "You can setup a new ReactOS installation, or update/repair an existing installation." + IDS_UPDATETITLE "Update or Repair ReactOS" + IDS_UPDATESUBTITLE "Choose which existing ReactOS installation you want to update or repair." IDS_DEVICETITLE "Einstellen der Basisgeräte" IDS_DEVICESUBTITLE "Einstellungen der Anzeigegeräte und der Tastatur." IDS_DRIVETITLE "Richte Installationspartition und Systemverzeichnis ein" diff --git a/base/setup/reactos/lang/el-GR.rc b/base/setup/reactos/lang/el-GR.rc index d8f3c06be632f..ba7662cd40911 100644 --- a/base/setup/reactos/lang/el-GR.rc +++ b/base/setup/reactos/lang/el-GR.rc @@ -8,8 +8,18 @@ CAPTION "Εγκατάσταση του ReactOS" FONT 8, "MS Shell Dlg" BEGIN LTEXT "Καλώς ήλθατε στον οδηγό εγκατάστασης του ReactOS", IDC_STARTTITLE, 115, 8, 195, 24 - LTEXT "Δε μπορείτε να εγκαταστήσετε το ReactOS απευθείας από αυτό το CD ακόμα! Παρακαλούμε επανεκκινήστε τον υπολογιστή σας από αυτό το CD για να μπορέσετε να εγκαταστήσετε το ReactOS.", IDC_STATIC, 115, 40, 195, 100 - LTEXT "Πατήστε Ολοκλήρωση για να βγείτε από την Εγκατάσταση.", IDC_STATIC, 115, 169, 195, 17 + LTEXT "This wizard will install or upgrade ReactOS on your computer, \ +and prepare the second part of the setup.", IDC_STATIC, 115, 40, 195, 27 +//// + GROUPBOX " IMPORTANT INFORMATION ", IDC_WARNTEXT1, 115, 70, 195, 90, BS_CENTER + LTEXT "ReactOS is in Alpha stage: it is not feature- complete and is \ +under heavy development. It is recommended to use it only for \ +evaluation and testing and not as your daily-usage OS.\n\ +It may corrupt your data or damage your hardware.", IDC_WARNTEXT2, 120, 80, 185, 50, SS_CENTER + LTEXT "Backup your data or test on a secondary computer \ +if you attempt to run ReactOS on real hardware.", IDC_WARNTEXT3, 120, 130, 185, 27, SS_CENTER +//// + LTEXT "Πατήστε το 'Επόμενο' για να συνεχίσει η εγκατάσταση.", IDC_STATIC, 115, 169, 195, 17 END IDD_TYPEPAGE DIALOGEX 0, 0, 317, 143 @@ -17,11 +27,10 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "Εγκατάσταση του ReactOS" FONT 8, "MS Shell Dlg" BEGIN - AUTORADIOBUTTON "Install ReactOS", IDC_INSTALL, 7, 7, 277, 10, WS_GROUP | WS_TABSTOP - LTEXT "Install a new copy of ReactOS. This option does not keep your files, settings and programs. You can make changes to disks and partitions.", IDC_INSTALLTEXT, 18, 18, 269, 25, NOT WS_GROUP - AUTORADIOBUTTON "Update or repair an installed ReactOS", IDC_UPDATE, 7, 50, 277, 10 - LTEXT "Update or repair an installed copy of ReactOS. This option keeps your files, settings and programs. This option is only available if ReactOS is already installed on this computer.", IDC_UPDATETEXT, 18, 61, 269, 30, NOT WS_GROUP - LTEXT "Πατήστε Επόμενο για να ρυθμίσετε τις συσκευές.", IDC_STATIC, 7, 128, 297, 8 + AUTORADIOBUTTON "&Install ReactOS", IDC_INSTALL, 7, 20, 277, 10, WS_GROUP | WS_TABSTOP + LTEXT "Install a new copy of ReactOS. This option does not keep your files, settings and programs. You can make changes to disks and partitions.", IDC_INSTALLTEXT, 19, 36, 279, 27, NOT WS_GROUP + AUTORADIOBUTTON "&Update or repair ReactOS", IDC_UPDATE, 7, 80, 277, 10 + LTEXT "Update or repair an installed copy of ReactOS. This option keeps your files, settings and programs. This option is only available if ReactOS is already installed on this computer.", IDC_UPDATETEXT, 19, 96, 279, 27, NOT WS_GROUP END IDD_UPDATEREPAIRPAGE DIALOGEX 0, 0, 317, 143 @@ -161,8 +170,10 @@ END STRINGTABLE BEGIN IDS_CAPTION "ReactOS Setup" - IDS_TYPETITLE "Καλώς ήλθατε στην Εγκατάσταση του ReactOS" - IDS_TYPESUBTITLE "Επιλέξτε τύπο εγκατάστασης." + IDS_TYPETITLE "Installation Type" + IDS_TYPESUBTITLE "You can setup a new ReactOS installation, or update/repair an existing installation." + IDS_UPDATETITLE "Update or Repair ReactOS" + IDS_UPDATESUBTITLE "Choose which existing ReactOS installation you want to update or repair." IDS_DEVICETITLE "Setup the basic devices" IDS_DEVICESUBTITLE "Ορισμός ρυθμίσεων για εμφάνιση και πληκτρολόγιο." IDS_DRIVETITLE "Ρύθμιση του partition εγκατάστασης και του φακέλου συστήματος" diff --git a/base/setup/reactos/lang/en-US.rc b/base/setup/reactos/lang/en-US.rc index 0c6d7e32b7ce8..fd2f3410e0017 100644 --- a/base/setup/reactos/lang/en-US.rc +++ b/base/setup/reactos/lang/en-US.rc @@ -8,8 +8,18 @@ CAPTION "ReactOS Setup" FONT 8, "MS Shell Dlg" BEGIN LTEXT "Welcome to the ReactOS Setup Wizard", IDC_STARTTITLE, 115, 8, 195, 24 - LTEXT "You cannot install ReactOS directly from this CD yet! Please restart your computer from this CD in order to install ReactOS.", IDC_STATIC, 115, 40, 195, 100 - LTEXT "Click Finish to exit the Setup.", IDC_STATIC, 115, 169, 195, 17 + LTEXT "This wizard will install or upgrade ReactOS on your computer, \ +and prepare the second part of the setup.", IDC_STATIC, 115, 40, 195, 27 +//// + GROUPBOX " IMPORTANT INFORMATION ", IDC_WARNTEXT1, 115, 70, 195, 90, BS_CENTER + LTEXT "ReactOS is in Alpha stage: it is not feature- complete and is \ +under heavy development. It is recommended to use it only for \ +evaluation and testing and not as your daily-usage OS.\n\ +It may corrupt your data or damage your hardware.", IDC_WARNTEXT2, 120, 80, 185, 50, SS_CENTER + LTEXT "Backup your data or test on a secondary computer \ +if you attempt to run ReactOS on real hardware.", IDC_WARNTEXT3, 120, 130, 185, 27, SS_CENTER +//// + LTEXT "Click Next to continue with Setup.", IDC_STATIC, 115, 169, 195, 17 END IDD_TYPEPAGE DIALOGEX 0, 0, 317, 143 @@ -17,11 +27,10 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "ReactOS Setup" FONT 8, "MS Shell Dlg" BEGIN - AUTORADIOBUTTON "Install ReactOS", IDC_INSTALL, 7, 7, 277, 10, WS_GROUP | WS_TABSTOP - LTEXT "Install a new copy of ReactOS. This option does not keep your files, settings and programs. You can make changes to disks and partitions.", IDC_INSTALLTEXT, 18, 18, 269, 25, NOT WS_GROUP - AUTORADIOBUTTON "Update or repair ReactOS", IDC_UPDATE, 7, 50, 277, 10 - LTEXT "Update or repair an installed copy of ReactOS. This option keeps your files, settings and programs. This option is only available if ReactOS is already installed on this computer.", IDC_UPDATETEXT, 18, 61, 269, 30, NOT WS_GROUP - LTEXT "Click Next to continue.", IDC_STATIC, 7, 128, 297, 8 + AUTORADIOBUTTON "&Install ReactOS", IDC_INSTALL, 7, 20, 277, 10, WS_GROUP | WS_TABSTOP + LTEXT "Install a new copy of ReactOS. This option does not keep your files, settings and programs. You can make changes to disks and partitions.", IDC_INSTALLTEXT, 19, 36, 279, 27, NOT WS_GROUP + AUTORADIOBUTTON "&Update or repair ReactOS", IDC_UPDATE, 7, 80, 277, 10 + LTEXT "Update or repair an installed copy of ReactOS. This option keeps your files, settings and programs. This option is only available if ReactOS is already installed on this computer.", IDC_UPDATETEXT, 19, 96, 279, 27, NOT WS_GROUP END IDD_UPDATEREPAIRPAGE DIALOGEX 0, 0, 317, 143 @@ -161,8 +170,10 @@ END STRINGTABLE BEGIN IDS_CAPTION "ReactOS Setup" - IDS_TYPETITLE "Welcome to ReactOS Setup" - IDS_TYPESUBTITLE "Choose setup type." + IDS_TYPETITLE "Installation Type" + IDS_TYPESUBTITLE "You can setup a new ReactOS installation, or update/repair an existing installation." + IDS_UPDATETITLE "Update or Repair ReactOS" + IDS_UPDATESUBTITLE "Choose which existing ReactOS installation you want to update or repair." IDS_DEVICETITLE "Setup the basic devices" IDS_DEVICESUBTITLE "Set the settings of display and keyboard." IDS_DRIVETITLE "Setup the installation partition and system folder" diff --git a/base/setup/reactos/lang/es-ES.rc b/base/setup/reactos/lang/es-ES.rc index acac98fea7c21..21cfa2cf4a64c 100644 --- a/base/setup/reactos/lang/es-ES.rc +++ b/base/setup/reactos/lang/es-ES.rc @@ -17,8 +17,18 @@ CAPTION "Instalación de ReactOS" FONT 8, "MS Shell Dlg" BEGIN LTEXT "Bienvenido al Asistente de Instalación de ReactOS", IDC_STARTTITLE, 115, 8, 195, 24 - LTEXT "¡Aún no puede instalar ReactOS desde el ejecutable del CD! Por favor, arranque su equipo desde el CD para instalar ReactOS.", IDC_STATIC, 115, 40, 200, 100 - LTEXT "Pulse Finalizar para salir del instalador.", IDC_STATIC, 115, 169, 195, 17 + LTEXT "This wizard will install or upgrade ReactOS on your computer, \ +and prepare the second part of the setup.", IDC_STATIC, 115, 40, 195, 27 +//// + GROUPBOX " IMPORTANT INFORMATION ", IDC_WARNTEXT1, 115, 70, 195, 90, BS_CENTER + LTEXT "ReactOS is in Alpha stage: it is not feature- complete and is \ +under heavy development. It is recommended to use it only for \ +evaluation and testing and not as your daily-usage OS.\n\ +It may corrupt your data or damage your hardware.", IDC_WARNTEXT2, 120, 80, 185, 50, SS_CENTER + LTEXT "Backup your data or test on a secondary computer \ +if you attempt to run ReactOS on real hardware.", IDC_WARNTEXT3, 120, 130, 185, 27, SS_CENTER +//// + LTEXT "Pulse Siguiente para continuar con la instalación.", IDC_STATIC, 115, 169, 195, 17 END IDD_TYPEPAGE DIALOGEX 0, 0, 317, 143 @@ -26,11 +36,10 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "Instalación de ReactOS" FONT 8, "MS Shell Dlg" BEGIN - AUTORADIOBUTTON "Instalar ReactOS", IDC_INSTALL, 7, 7, 277, 10, WS_GROUP | WS_TABSTOP - LTEXT "Instala una nueva copia de ReactOS. Esta opción no protege sus archivos, programas y ajustes. Puede realizar cambios a su disco duro y particiones.", IDC_INSTALLTEXT, 18, 18, 269, 25, NOT WS_GROUP - AUTORADIOBUTTON "Actualizar o reparar una instalación existente de ReactOS", IDC_UPDATE, 7, 50, 277, 10 - LTEXT "Actualiza o repara una instalación existente de ReactOS. Esta opción protege sus archivos, programas y ajustes. Esta opción sólo está disponible si ha instalado ReactOS previamente en este equipo.", IDC_UPDATETEXT, 18, 61, 269, 30, NOT WS_GROUP - LTEXT "Presione Siguiente para instalar los dispositivos.", IDC_STATIC, 7, 128, 297, 8 + AUTORADIOBUTTON "&Instalar ReactOS", IDC_INSTALL, 7, 20, 277, 10, WS_GROUP | WS_TABSTOP + LTEXT "Instala una nueva copia de ReactOS. Esta opción no protege sus archivos, programas y ajustes. Puede realizar cambios a su disco duro y particiones.", IDC_INSTALLTEXT, 19, 36, 279, 27, NOT WS_GROUP + AUTORADIOBUTTON "&Actualizar o reparar ReactOS", IDC_UPDATE, 7, 80, 277, 10 + LTEXT "Actualiza o repara una instalación existente de ReactOS. Esta opción protege sus archivos, programas y ajustes. Esta opción sólo está disponible si ha instalado ReactOS previamente en este equipo.", IDC_UPDATETEXT, 19, 96, 279, 27, NOT WS_GROUP END IDD_UPDATEREPAIRPAGE DIALOGEX 0, 0, 317, 143 @@ -170,8 +179,10 @@ END STRINGTABLE BEGIN IDS_CAPTION "Instalación de ReactOS" - IDS_TYPETITLE "Bienvenido a la instalación de ReactOS" - IDS_TYPESUBTITLE "Seleccione el tipo de instalación." + IDS_TYPETITLE "Installation Type" + IDS_TYPESUBTITLE "You can setup a new ReactOS installation, or update/repair an existing installation." + IDS_UPDATETITLE "Update or Repair ReactOS" + IDS_UPDATESUBTITLE "Choose which existing ReactOS installation you want to update or repair." IDS_DEVICETITLE "Instalación de los dispositivos básicos" IDS_DEVICESUBTITLE "Seleccione los ajustes de la pantalla y el teclado." IDS_DRIVETITLE "Crear la partición para la instalación y la carpeta del sistema" diff --git a/base/setup/reactos/lang/et-EE.rc b/base/setup/reactos/lang/et-EE.rc index c880c622caf18..bf7da3964c8e5 100644 --- a/base/setup/reactos/lang/et-EE.rc +++ b/base/setup/reactos/lang/et-EE.rc @@ -8,8 +8,18 @@ CAPTION "ReactOS'i paigaldamine" FONT 8, "MS Shell Dlg" BEGIN LTEXT "Tere tulemast ReactOS'i paigaldamus viisardisse", IDC_STARTTITLE, 115, 8, 195, 24 - LTEXT "Selle CD pealt ei saa praegu veel ReactOS'i paigaldada! ReactOS'i paigaldamiseks on tarvis arvuti taaskäivitada selle CD-ga.", IDC_STATIC, 115, 40, 195, 100 - LTEXT "Vajuta lõpeta, et installeerimine lõpetada.", IDC_STATIC, 115, 169, 195, 17 + LTEXT "This wizard will install or upgrade ReactOS on your computer, \ +and prepare the second part of the setup.", IDC_STATIC, 115, 40, 195, 27 +//// + GROUPBOX " IMPORTANT INFORMATION ", IDC_WARNTEXT1, 115, 70, 195, 90, BS_CENTER + LTEXT "ReactOS is in Alpha stage: it is not feature- complete and is \ +under heavy development. It is recommended to use it only for \ +evaluation and testing and not as your daily-usage OS.\n\ +It may corrupt your data or damage your hardware.", IDC_WARNTEXT2, 120, 80, 185, 50, SS_CENTER + LTEXT "Backup your data or test on a secondary computer \ +if you attempt to run ReactOS on real hardware.", IDC_WARNTEXT3, 120, 130, 185, 27, SS_CENTER +//// + LTEXT "Vajuta Edasi paigaldamise jätkamiseks.", IDC_STATIC, 115, 169, 195, 17 END IDD_TYPEPAGE DIALOGEX 0, 0, 317, 143 @@ -17,11 +27,10 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "ReactOS'i paigaldamine" FONT 8, "MS Shell Dlg" BEGIN - AUTORADIOBUTTON "Installeeri ReactOS", IDC_INSTALL, 7, 7, 277, 10 - LTEXT "Paigalda uus koopia ReactOS'ist. See valik ei jäta alles teie faile, suvandeid ja programme. Võite teha muudatusi kettastele ja partitsioonidele.", IDC_INSTALLTEXT, 18, 18, 269, 25 - AUTORADIOBUTTON "Paranda või uuenda installeeritud ReactOS'i", IDC_UPDATE, 7, 50, 277, 10 - LTEXT "Uuenda või paranda oma ReactOS'i installatsiooni. See valik säilitab teie failid, suvandid ja programmid. See valik on saadaval juhul kui ReactOS on juba paigaldatud siin arvutis.", IDC_UPDATETEXT, 18, 61, 269, 30 - LTEXT "Vajuta Järgmine, et seadmeid paigaldada.", IDC_STATIC, 7, 128, 297, 8 + AUTORADIOBUTTON "&Installeeri ReactOS", IDC_INSTALL, 7, 20, 277, 10 + LTEXT "Paigalda uus koopia ReactOS'ist. See valik ei jäta alles teie faile, suvandeid ja programme. Võite teha muudatusi kettastele ja partitsioonidele.", IDC_INSTALLTEXT, 19, 36, 279, 27 + AUTORADIOBUTTON "&Paranda või uuenda ReactOS'i", IDC_UPDATE, 7, 80, 277, 10 + LTEXT "Uuenda või paranda oma ReactOS'i installatsiooni. See valik säilitab teie failid, suvandid ja programmid. See valik on saadaval juhul kui ReactOS on juba paigaldatud siin arvutis.", IDC_UPDATETEXT, 19, 96, 279, 27 END IDD_UPDATEREPAIRPAGE DIALOGEX 0, 0, 317, 143 @@ -161,8 +170,10 @@ END STRINGTABLE BEGIN IDS_CAPTION "ReactOS'i paigaldamine" - IDS_TYPETITLE "Tere tulemast ReactOS'i paigaldama" - IDS_TYPESUBTITLE "Vali paigalduse tüüp." + IDS_TYPETITLE "Installation Type" + IDS_TYPESUBTITLE "You can setup a new ReactOS installation, or update/repair an existing installation." + IDS_UPDATETITLE "Update or Repair ReactOS" + IDS_UPDATESUBTITLE "Choose which existing ReactOS installation you want to update or repair." IDS_DEVICETITLE "Põhiliste seadmete paigaldamine" IDS_DEVICESUBTITLE "Ekraani ja klaviatuuri seadistamine." IDS_DRIVETITLE "Partitsioonide ja süsteemikausta seadistamine" diff --git a/base/setup/reactos/lang/eu-ES.rc b/base/setup/reactos/lang/eu-ES.rc index 5ea81031a3721..650f0bf3af27c 100644 --- a/base/setup/reactos/lang/eu-ES.rc +++ b/base/setup/reactos/lang/eu-ES.rc @@ -15,8 +15,18 @@ CAPTION "Instalación de ReactOS" FONT 8, "MS Shell Dlg" BEGIN LTEXT "Bienvenido al Asistente de Instalación de ReactOS", IDC_STARTTITLE, 115, 8, 195, 24 - LTEXT "¡Aún no puede instalar ReactOS directamente desde el CD! Por favor, reinicie su equipo desde el CD para instalar ReactOS.", IDC_STATIC, 115, 40, 200, 100 - LTEXT "Pulse Finalizar para salir del instalador.", IDC_STATIC, 115, 169, 195, 17 + LTEXT "This wizard will install or upgrade ReactOS on your computer, \ +and prepare the second part of the setup.", IDC_STATIC, 115, 40, 195, 27 +//// + GROUPBOX " IMPORTANT INFORMATION ", IDC_WARNTEXT1, 115, 70, 195, 90, BS_CENTER + LTEXT "ReactOS is in Alpha stage: it is not feature- complete and is \ +under heavy development. It is recommended to use it only for \ +evaluation and testing and not as your daily-usage OS.\n\ +It may corrupt your data or damage your hardware.", IDC_WARNTEXT2, 120, 80, 185, 50, SS_CENTER + LTEXT "Backup your data or test on a secondary computer \ +if you attempt to run ReactOS on real hardware.", IDC_WARNTEXT3, 120, 130, 185, 27, SS_CENTER +//// + LTEXT "Sakatu Aurrera instalazioa jarraitzeko.", IDC_STATIC, 115, 169, 195, 17 END IDD_TYPEPAGE DIALOGEX 0, 0, 317, 143 @@ -24,11 +34,10 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "Instalación de ReactOS" FONT 8, "MS Shell Dlg" BEGIN - AUTORADIOBUTTON "Instalar ReactOS", IDC_INSTALL, 7, 7, 277, 10, WS_GROUP | WS_TABSTOP - LTEXT "Instala una nueva copia de ReactOS. Esta opción no protege sus archivos, programas y ajustes. Puede realizar cambios a su disco duro y particiones.", IDC_INSTALLTEXT, 18, 18, 269, 25, NOT WS_GROUP - AUTORADIOBUTTON "Actualizar o reparar una instalación existente de ReactOS", IDC_UPDATE, 7, 50, 277, 10 - LTEXT "Actualiza o repara una instalación existente de ReactOS. Esta opción protege sus archivos, programas y ajustes. Esta opción sólo está disponible si ha instalado ReactOS previamente en este equipo.", IDC_UPDATETEXT, 18, 61, 269, 30, NOT WS_GROUP - LTEXT "Presione Siguiente para instalar los dispositivos.", IDC_STATIC, 7, 128, 297, 8 + AUTORADIOBUTTON "&Instalar ReactOS", IDC_INSTALL, 7, 20, 277, 10, WS_GROUP | WS_TABSTOP + LTEXT "Instala una nueva copia de ReactOS. Esta opción no protege sus archivos, programas y ajustes. Puede realizar cambios a su disco duro y particiones.", IDC_INSTALLTEXT, 19, 36, 279, 27, NOT WS_GROUP + AUTORADIOBUTTON "&Actualizar o reparar ReactOS", IDC_UPDATE, 7, 80, 277, 10 + LTEXT "Actualiza o repara una instalación existente de ReactOS. Esta opción protege sus archivos, programas y ajustes. Esta opción sólo está disponible si ha instalado ReactOS previamente en este equipo.", IDC_UPDATETEXT, 19, 96, 279, 27, NOT WS_GROUP END IDD_UPDATEREPAIRPAGE DIALOGEX 0, 0, 317, 143 @@ -168,8 +177,10 @@ END STRINGTABLE BEGIN IDS_CAPTION "Instalación de ReactOS" - IDS_TYPETITLE "Bienvenido a la instalación de ReactOS" - IDS_TYPESUBTITLE "Seleccione el tipo de instalación." + IDS_TYPETITLE "Installation Type" + IDS_TYPESUBTITLE "You can setup a new ReactOS installation, or update/repair an existing installation." + IDS_UPDATETITLE "Update or Repair ReactOS" + IDS_UPDATESUBTITLE "Choose which existing ReactOS installation you want to update or repair." IDS_DEVICETITLE "Instalación de los dispositivos básicos" IDS_DEVICESUBTITLE "Seleccione los ajustes de la pantalla y el teclado." IDS_DRIVETITLE "Crear la partición para la instalación y la carpeta del sistema" diff --git a/base/setup/reactos/lang/fi-FI.rc b/base/setup/reactos/lang/fi-FI.rc index 4acfbcce05647..84d0a5f199a81 100644 --- a/base/setup/reactos/lang/fi-FI.rc +++ b/base/setup/reactos/lang/fi-FI.rc @@ -8,8 +8,18 @@ CAPTION "ReactOS Asennus" FONT 8, "MS Shell Dlg" BEGIN LTEXT "Welcome to the ReactOS Setup Wizard", IDC_STARTTITLE, 115, 8, 195, 24 - LTEXT "Et voi asentaa ReactOS:ä suoraan tältä CDlevyltä! Käynnistä tietokoneesi tältä CD levyltä asentaaksesi ReactOS:ä.", IDC_STATIC, 115, 40, 195, 100 - LTEXT "Click Finish to exit the Setup.", IDC_STATIC, 115, 169, 195, 17 + LTEXT "This wizard will install or upgrade ReactOS on your computer, \ +and prepare the second part of the setup.", IDC_STATIC, 115, 40, 195, 27 +//// + GROUPBOX " IMPORTANT INFORMATION ", IDC_WARNTEXT1, 115, 70, 195, 90, BS_CENTER + LTEXT "ReactOS is in Alpha stage: it is not feature- complete and is \ +under heavy development. It is recommended to use it only for \ +evaluation and testing and not as your daily-usage OS.\n\ +It may corrupt your data or damage your hardware.", IDC_WARNTEXT2, 120, 80, 185, 50, SS_CENTER + LTEXT "Backup your data or test on a secondary computer \ +if you attempt to run ReactOS on real hardware.", IDC_WARNTEXT3, 120, 130, 185, 27, SS_CENTER +//// + LTEXT "Click Next to continue with Setup.", IDC_STATIC, 115, 169, 195, 17 END IDD_TYPEPAGE DIALOGEX 0, 0, 317, 143 @@ -17,11 +27,10 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "ReactOS Setup" FONT 8, "MS Shell Dlg" BEGIN - AUTORADIOBUTTON "Install ReactOS", IDC_INSTALL, 7, 7, 277, 10, WS_GROUP | WS_TABSTOP - LTEXT "Install a new copy of ReactOS. This option does not keep your files, settings and programs. You can make changes to disks and partitions.", IDC_INSTALLTEXT, 18, 18, 269, 25, NOT WS_GROUP - AUTORADIOBUTTON "Update or repair an installed ReactOS", IDC_UPDATE, 7, 50, 277, 10 - LTEXT "Update or repair an installed copy of ReactOS. This option keeps your files, settings and programs. This option is only available if ReactOS is already installed on this computer.", IDC_UPDATETEXT, 18, 61, 269, 30, NOT WS_GROUP - LTEXT "Click Next to setup the devices.", IDC_STATIC, 7, 128, 297, 8 + AUTORADIOBUTTON "&Install ReactOS", IDC_INSTALL, 7, 20, 277, 10, WS_GROUP | WS_TABSTOP + LTEXT "Install a new copy of ReactOS. This option does not keep your files, settings and programs. You can make changes to disks and partitions.", IDC_INSTALLTEXT, 19, 36, 279, 27, NOT WS_GROUP + AUTORADIOBUTTON "&Update or repair ReactOS", IDC_UPDATE, 7, 80, 277, 10 + LTEXT "Update or repair an installed copy of ReactOS. This option keeps your files, settings and programs. This option is only available if ReactOS is already installed on this computer.", IDC_UPDATETEXT, 19, 96, 279, 27, NOT WS_GROUP END IDD_UPDATEREPAIRPAGE DIALOGEX 0, 0, 317, 143 @@ -161,8 +170,10 @@ END STRINGTABLE BEGIN IDS_CAPTION "ReactOS Setup" - IDS_TYPETITLE "Welcome to ReactOS Setup" - IDS_TYPESUBTITLE "Choose setup type." + IDS_TYPETITLE "Installation Type" + IDS_TYPESUBTITLE "You can setup a new ReactOS installation, or update/repair an existing installation." + IDS_UPDATETITLE "Update or Repair ReactOS" + IDS_UPDATESUBTITLE "Choose which existing ReactOS installation you want to update or repair." IDS_DEVICETITLE "Setup the basic devices" IDS_DEVICESUBTITLE "Set the settings of display and keyboard." IDS_DRIVETITLE "Setup the installation partition and system folder" diff --git a/base/setup/reactos/lang/fr-FR.rc b/base/setup/reactos/lang/fr-FR.rc index a0737ad3a39f6..82be81c53c523 100644 --- a/base/setup/reactos/lang/fr-FR.rc +++ b/base/setup/reactos/lang/fr-FR.rc @@ -8,8 +8,18 @@ CAPTION "Installation de ReactOS" FONT 8, "MS Shell Dlg" BEGIN LTEXT "Bienvenue dans l'assistant d'installation de ReactOS", IDC_STARTTITLE, 115, 8, 195, 24 - LTEXT "Vous ne pouvez pas encore installer ReactOS directement depuis ce CD ! Veuillez redémarrer votre ordinateur depuis ce CD pour pouvoir installer ReactOS.", IDC_STATIC, 115, 40, 195, 100 - LTEXT "Cliquez sur Terminer pour quitter l'installation.", IDC_STATIC, 115, 169, 195, 17 + LTEXT "Cet assistant installe ou met à niveau ReactOS sur votre ordinateur, \ +et prépare la seconde étape d'installation.", IDC_STATIC, 115, 40, 195, 27 +//// + GROUPBOX " INFORMATION IMPORTANTE ", IDC_WARNTEXT1, 115, 70, 195, 90, BS_CENTER + LTEXT "ReactOS est en version Alpha : il n'est pas complet et est \ +en cours de développement. Il est conseillé de ne l'utiliser \ +que pour évaluation et test, pas pour un usage quotidien.\n\ +Il peut corrompre vos données ou endommager votre matériel.", IDC_WARNTEXT2, 120, 80, 185, 50, SS_CENTER + LTEXT "Sauvegardez vos données ou testez sur un ordinateur secondaire \ +si vous souhaitez utiliser ReactOS sur du matériel.", IDC_WARNTEXT3, 120, 130, 185, 27, SS_CENTER +//// + LTEXT "Cliquez sur Suivant pour continuer l'installation.", IDC_STATIC, 115, 169, 195, 17 END IDD_TYPEPAGE DIALOGEX 0, 0, 317, 143 @@ -17,11 +27,10 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "Installation de ReactOS" FONT 8, "MS Shell Dlg" BEGIN - AUTORADIOBUTTON "Installer ReactOS", IDC_INSTALL, 7, 7, 277, 10, WS_GROUP | WS_TABSTOP - LTEXT "Installer une nouvelle copie de ReactOS. Cette option ne conservera pas vos données, paramètres et programmes. Vous pouvez effectuer des modifications sur les disques et les partitions.", IDC_INSTALLTEXT, 18, 18, 269, 25, NOT WS_GROUP - AUTORADIOBUTTON "Mettre à jour ou réparer ReactOS", IDC_UPDATE, 7, 50, 277, 10 - LTEXT "Mettre à jour ou réparer une copie existante de ReactOS. Cette option conserve vos données, paramètres et programmes. Cette option est seulement disponible si ReactOS est déjà installé sur cet ordinateur.", IDC_UPDATETEXT, 18, 61, 269, 30, NOT WS_GROUP - LTEXT "Appuyer sur Suivant pour configurer les périphériques.", IDC_STATIC, 7, 1280, 297, 8 + AUTORADIOBUTTON "&Installer ReactOS", IDC_INSTALL, 7, 20, 277, 10, WS_GROUP | WS_TABSTOP + LTEXT "Installe une nouvelle copie de ReactOS. Cette option ne conservera pas vos données, paramètres et programmes. Vous pouvez effectuer des modifications sur les disques et les partitions.", IDC_INSTALLTEXT, 19, 36, 279, 27, NOT WS_GROUP + AUTORADIOBUTTON "&Mettre à niveau ou réparer ReactOS", IDC_UPDATE, 7, 80, 277, 10 + LTEXT "Met à niveau ou répare une copie existante de ReactOS. Cette option conserve vos données, paramètres et programmes. Cette option est seulement disponible si ReactOS est déjà installé sur cet ordinateur.", IDC_UPDATETEXT, 19, 96, 279, 27, NOT WS_GROUP END IDD_UPDATEREPAIRPAGE DIALOGEX 0, 0, 317, 143 @@ -32,7 +41,7 @@ BEGIN LTEXT "L'installation de ReactOS peut mettre à niveau les installations disponibles de ReactOS listées ci-dessous, ou, si une installation de ReactOS est endommagée, l'installation peut essayer de la réparer.", IDC_STATIC, 6, 6, 300, 18 CONTROL "", IDC_NTOSLIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP, 6, 30, 303, 90 PUSHBUTTON "&Ne pas mettre à jour", IDC_SKIPUPGRADE, 230, 128, 80, 14 - LTEXT "Appuyer sur Suivant pour mettre à niveau l'installation sélectionnée, ou sur 'Ne pas mettre à niveau' pour continuer une nouvelle installation.", IDC_STATIC, 7, 124, 222, 16 + LTEXT "Appuyer sur Suivant pour mettre à niveau l'installation sélectionnée, ou sur 'Ne pas mettre à jour' pour continuer une nouvelle installation.", IDC_STATIC, 7, 124, 222, 16 END IDD_DEVICEPAGE DIALOGEX 0, 0, 317, 143 @@ -57,7 +66,7 @@ BEGIN CONTROL "", IDC_PARTITION, "SysTreeList32", WS_BORDER | WS_VISIBLE | WS_TABSTOP | LVS_REPORT | LVS_SINGLESEL, 7, 7, 303, 112 PUSHBUTTON "&Initialiser", IDC_INITDISK, 7, 122, 50, 14 // NOTE: At same position as IDC_PARTCREATE PUSHBUTTON "&Créer", IDC_PARTCREATE, 7, 122, 50, 14 - PUSHBUTTON "&Formatter", IDC_PARTFORMAT, 7, 122, 50, 14 // NOTE: At same position as IDC_PARTCREATE + PUSHBUTTON "&Formater", IDC_PARTFORMAT, 7, 122, 50, 14 // NOTE: At same position as IDC_PARTCREATE PUSHBUTTON "&Supprimer", IDC_PARTDELETE, 63, 122, 50, 14 PUSHBUTTON "&Pilote", IDC_DEVICEDRIVER, 174, 122, 50, 14, WS_DISABLED PUSHBUTTON "&Options avancées...", IDC_PARTMOREOPTS, 230, 122, 80, 14 @@ -66,7 +75,7 @@ END IDD_PARTITION DIALOGEX 0, 0, 200, 120 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Créer et formatter une partition" +CAPTION "Créer et formater une partition" FONT 8, "MS Shell Dlg" BEGIN LTEXT "&Taille :", IDC_STATIC, 7, 9, 70, 9 @@ -84,7 +93,7 @@ END IDD_FORMAT DIALOGEX 0, 0, 200, 83 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Formatter une partition" +CAPTION "Formater une partition" FONT 8, "MS Shell Dlg" BEGIN LTEXT "&Système de fichier :", IDC_FS_STATIC, 7, 9, 70, 9 @@ -161,8 +170,10 @@ END STRINGTABLE BEGIN IDS_CAPTION "Installation de ReactOS" - IDS_TYPETITLE "Bienvenue dans l'installation de ReactOS" - IDS_TYPESUBTITLE "Choisissez un type d'installation." + IDS_TYPETITLE "Type d'installation" + IDS_TYPESUBTITLE "Vous pouvez configurer une nouvelle installation de ReactOS, ou bien mettre à niveau ou réparer une installation existante." + IDS_UPDATETITLE "Update or Repair ReactOS" + IDS_UPDATESUBTITLE "Choose which existing ReactOS installation you want to update or repair." IDS_DEVICETITLE "Configurer les périphériques de base" IDS_DEVICESUBTITLE "Configurer l'affichage et le clavier." IDS_DRIVETITLE "Configurer la partition d'installation et le dossier système" @@ -170,7 +181,7 @@ BEGIN IDS_SUMMARYTITLE "Résumé de l'installation" IDS_SUMMARYSUBTITLE "Lister les propriétés d'installation à vérifier avant application sur le périphérique d'installation." IDS_PROCESSTITLE "Configurer la partition, copier les fichiers et configurer le système" - IDS_PROCESSSUBTITLE "Créer et formatter la partition, copier les fichiers, installer et configurer le chargeur de démarrage." + IDS_PROCESSSUBTITLE "Créer et formater la partition, copier les fichiers, installer et configurer le chargeur de démarrage." IDS_RESTARTTITLE "Première étape de configuration terminée" IDS_RESTARTSUBTITLE "La première étape de l'installation est terminée. Veuillez redémarrer pour continuer avec la seconde étape." IDS_ABORTSETUP "ReactOS n'est pas complètement installé sur votre ordinateur. Si vous quittez l'installation maintenant, vous devrez lancer l'installation de nouveau pour installer ReactOS. Voulez-vous quitter ?" @@ -258,33 +269,33 @@ Les caractères d'espacement ne sont pas autorisés." IDS_ERROR_DIRECTORY_NAME "Le chemin d'installation de ReactOS doit être au format DOS de noms 8.3, \ et contenir seulement des lettres, chiffres, tirets et points. Les caractères d'espacement ne sont pas autorisés." - IDS_ERROR_CREATE_PARTITION_TITLE "Create partition" - IDS_ERROR_CREATE_PARTITION "Failed to create a new partition." + IDS_ERROR_CREATE_PARTITION_TITLE "Créer une partition" + IDS_ERROR_CREATE_PARTITION "Échec lors de la création d'une nouvelle partition." - IDS_WARN_DELETE_PARTITION_TITLE "Delete partition?" - IDS_WARN_DELETE_PARTITION "Are you sure you want to delete the selected partition?" - IDS_WARN_DELETE_MBR_EXTENDED_PARTITION "Are you sure you want to delete the selected extended partition and ALL the logical partitions it contains?" + IDS_WARN_DELETE_PARTITION_TITLE "Supprimer la partition ?" + IDS_WARN_DELETE_PARTITION "Êtes-vous sûr de vouloir supprimer la partition sélectionnée ?" + IDS_WARN_DELETE_MBR_EXTENDED_PARTITION "Êtes-vous sûr de vouloir supprimer la partition étendue sélectionnée et TOUTES les partitions logiques qu'elle contient ?" - IDS_ERROR_WRITE_PTABLE "Setup failed to write partition tables." + IDS_ERROR_WRITE_PTABLE "Le programme d'installation a échoué à écrire les tables de partition." - IDS_ERROR_SYSTEM_PARTITION "The ReactOS Setup could not find a supported system partition\n\ -on your system or could not create a new one. Without such a partition\n\ -the Setup program cannot install ReactOS.\ -\nClick on OK to return to the partition selection list." + IDS_ERROR_SYSTEM_PARTITION "Le programme d'installation de ReactOS ne peut pas trouver une partition système supportée\n\ +sur votre système, ou ne peut pas en créer une nouvelle. Sans une telle partition,\n\ +le programme d'installation ne peut pas installer ReactOS.\ +\nCliquez sur OK pour revenir à la liste de sélection des partitions." - IDS_ERROR_FORMAT_UNRECOGNIZED_VOLUME "Unrecognized volume while attempting to format the partition." + IDS_ERROR_FORMAT_UNRECOGNIZED_VOLUME "Volume non reconnu lors du formatage de la partition." - IDS_ERROR_COULD_NOT_FORMAT "Setup is currently unable to format a partition in %s.\n\ -\nClick on OK to continue Setup.\ -\nClick on CANCEL to quit Setup." + IDS_ERROR_COULD_NOT_FORMAT "Le programme d'installation ne parvient actuellement pas à formater une partition en %s.\n\ +\nCliquez sur OK pour continuer l'installation.\ +\nCliquez sur Annuler pour quitter l'installation." - IDS_ERROR_FORMATTING_PARTITION "Setup is unable to format the partition:\n %s\n" + IDS_ERROR_FORMATTING_PARTITION "Le programme d'installation ne parvient pas à formater la partition :\n %s\n" - IDS_ERROR_COULD_NOT_CHECK "Setup is currently unable to check a partition formatted in %s.\n\ -\nClick on OK to continue Setup.\ -\nClick on CANCEL to quit Setup." + IDS_ERROR_COULD_NOT_CHECK "Le programme d'installation ne parvient actuellement pas à vérifier une partition formatée en %s.\n\ +\nCliquez sur OK pour continuer l'installation.\ +\nCliquez sur Annuler pour quitter l'installation." - IDS_ERROR_CHECKING_PARTITION "ChkDsk detected some disk errors.\n(Status 0x%08lx)." + IDS_ERROR_CHECKING_PARTITION "ChkDsk a détecté des erreurs disque.\n(Status 0x%08lx)." IDS_ERROR_WRITE_BOOT "Échec de l'installation du code de démarrage %s sur la partition système." IDS_ERROR_INSTALL_BOOTCODE "Échec de l'installation du code de démarrage %s sur le disque système." diff --git a/base/setup/reactos/lang/he-IL.rc b/base/setup/reactos/lang/he-IL.rc index 1530d86da94f1..11465212ce5ec 100644 --- a/base/setup/reactos/lang/he-IL.rc +++ b/base/setup/reactos/lang/he-IL.rc @@ -9,9 +9,19 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "התקנת ReactOS" FONT 8, "MS Shell Dlg" BEGIN - LTEXT "ברוכים הבאים לאשף ההתקנה של ReactOS", IDC_STARTTITLE, 115, 8, 195, 24 - LTEXT "אתה לא יכול להתקין את ReactOS מהדיסק הזה ברגע זה! נע הפעל מחדש את המחשב מהדיסק הזה בשביל להתקין את ReactOS", IDC_STATIC, 115, 40, 195, 100 - LTEXT "לחץ על 'סיום' כדי לסיים את ההתקנה.", IDC_STATIC, 115, 169, 195, 17 + LTEXT "ברוכים לאשף ההתקנה של ReactOS", IDC_STARTTITLE, 115, 8, 195, 24 + LTEXT "This wizard will install or upgrade ReactOS on your computer, \ +and prepare the second part of the setup.", IDC_STATIC, 115, 40, 195, 27 +//// + GROUPBOX " IMPORTANT INFORMATION ", IDC_WARNTEXT1, 115, 70, 195, 90, BS_CENTER + LTEXT "ReactOS is in Alpha stage: it is not feature- complete and is \ +under heavy development. It is recommended to use it only for \ +evaluation and testing and not as your daily-usage OS.\n\ +It may corrupt your data or damage your hardware.", IDC_WARNTEXT2, 120, 80, 185, 50, SS_CENTER + LTEXT "Backup your data or test on a secondary computer \ +if you attempt to run ReactOS on real hardware.", IDC_WARNTEXT3, 120, 130, 185, 27, SS_CENTER +//// + LTEXT "לחץ על הבא כדי להמשיך עם ההתקנה", IDC_STATIC, 115, 169, 195, 17 END IDD_TYPEPAGE DIALOGEX 0, 0, 317, 143 @@ -19,11 +29,10 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "התקנת ReactOS" FONT 8, "MS Shell Dlg" BEGIN - AUTORADIOBUTTON "התקנת ReactOS", IDC_INSTALL, 7, 7, 277, 10, WS_GROUP | WS_TABSTOP - LTEXT "Install a new copy of ReactOS. This option does not keep your files, settings and programs. You can make changes to disks and partitions.", IDC_INSTALLTEXT, 18, 18, 269, 25, NOT WS_GROUP - AUTORADIOBUTTON "תיקון או עדכון גרסה קיימת", IDC_UPDATE, 7, 50, 277, 10 - LTEXT "Update or repair an installed copy of ReactOS. This option keeps your files, settings and programs. This option is only available if ReactOS is already installed on this computer.", IDC_UPDATETEXT, 18, 61, 269, 30, NOT WS_GROUP - LTEXT "לחץ על 'הבא' כדי להגדיר את ההתקנים.", IDC_STATIC, 7, 128, 297, 8 + AUTORADIOBUTTON "(&I)התקנת ReactOS", IDC_INSTALL, 7, 20, 277, 10, WS_GROUP | WS_TABSTOP + LTEXT "Install a new copy of ReactOS. This option does not keep your files, settings and programs. You can make changes to disks and partitions.", IDC_INSTALLTEXT, 19, 36, 279, 27, NOT WS_GROUP + AUTORADIOBUTTON "(&U)תיקון או עדכון ReactOS", IDC_UPDATE, 7, 80, 277, 10 + LTEXT "Update or repair an installed copy of ReactOS. This option keeps your files, settings and programs. This option is only available if ReactOS is already installed on this computer.", IDC_UPDATETEXT, 19, 96, 279, 27, NOT WS_GROUP END IDD_UPDATEREPAIRPAGE DIALOGEX 0, 0, 317, 143 @@ -163,8 +172,10 @@ END STRINGTABLE BEGIN IDS_CAPTION "התקנת ReactOS" - IDS_TYPETITLE "ברוכים הבאים לתוכנית ההתקנה של ReactOS" - IDS_TYPESUBTITLE "בחירת סוג התקנה." + IDS_TYPETITLE "Installation Type" + IDS_TYPESUBTITLE "You can setup a new ReactOS installation, or update/repair an existing installation." + IDS_UPDATETITLE "Update or Repair ReactOS" + IDS_UPDATESUBTITLE "Choose which existing ReactOS installation you want to update or repair." IDS_DEVICETITLE "Setup the basic devices" IDS_DEVICESUBTITLE "Set the settings of display and keyboard." IDS_DRIVETITLE "Setup the installation partition and system folder" diff --git a/base/setup/reactos/lang/hi-IN.rc b/base/setup/reactos/lang/hi-IN.rc index e0c2fbc92020e..da3381a871a94 100644 --- a/base/setup/reactos/lang/hi-IN.rc +++ b/base/setup/reactos/lang/hi-IN.rc @@ -15,8 +15,18 @@ CAPTION "रिऐक्ट ओएस सेटअप" FONT 8, "MS Shell Dlg" BEGIN LTEXT "रिऐक्ट ओएस सेटअप विज़ार्ड में आपका स्वागत है।", IDC_STARTTITLE, 115, 8, 195, 24 - LTEXT "आप अभी तक इस सीडी से सीधे रिऐक्ट ओएस इंस्टॉल नहीं कर सकते हैं! कृपया अपने कंप्यूटर को रिऐक्ट ओएस इंस्टॉल करने के लिए इस सीडी से रीस्टॉर्ट करें।", IDC_STATIC, 115, 40, 195, 100 - LTEXT "सेटअप से बाहर निकलने के लिए समाप्त क्लिक करें।", IDC_STATIC, 115, 169, 195, 17 + LTEXT "This wizard will install or upgrade ReactOS on your computer, \ +and prepare the second part of the setup.", IDC_STATIC, 115, 40, 195, 27 +//// + GROUPBOX " IMPORTANT INFORMATION ", IDC_WARNTEXT1, 115, 70, 195, 90, BS_CENTER + LTEXT "ReactOS is in Alpha stage: it is not feature- complete and is \ +under heavy development. It is recommended to use it only for \ +evaluation and testing and not as your daily-usage OS.\n\ +It may corrupt your data or damage your hardware.", IDC_WARNTEXT2, 120, 80, 185, 50, SS_CENTER + LTEXT "Backup your data or test on a secondary computer \ +if you attempt to run ReactOS on real hardware.", IDC_WARNTEXT3, 120, 130, 185, 27, SS_CENTER +//// + LTEXT "सेटअप के साथ जारी रखने के लिए आगे क्लिक करें।", IDC_STATIC, 115, 169, 195, 17 END IDD_TYPEPAGE DIALOGEX 0, 0, 317, 143 @@ -24,11 +34,10 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "रिऐक्ट ओएस सेटअप" FONT 8, "MS Shell Dlg" BEGIN - AUTORADIOBUTTON "रिऐक्ट ओएस इंस्टॉल करें", IDC_INSTALL, 7, 7, 277, 10 - LTEXT "रिऐक्ट ओएस की एक नई कापी इन्स्टॉल करें। यह विकल्प आपकी फाइलें, सेटिंग्स और प्रोग्राम नहीं रखता है। आप डिस्क और विभाजन में परिवर्तन कर सकते हैं।", IDC_INSTALLTEXT, 18, 18, 269, 25 - AUTORADIOBUTTON "रिऐक्ट ओएस की अद्यतन या मरम्मत करे। ", IDC_UPDATE, 7, 50, 277, 10 - LTEXT "रिऐक्ट ओएस की एक स्थापित कापी अद्यतन या मरम्मत करे। यह विकल्प आपकी फाइलें, सेटिंग्स और प्रोग्राम रखता है। यह विकल्प केवल तभी उपलब्ध होता है जब इस कंप्यूटर पर रिऐक्ट ओएस पहले से इंस्टॉल हो।", IDC_UPDATETEXT, 18, 61, 269, 30 - LTEXT "जारी रखने के लिए आगे दबाएँ।", IDC_STATIC, 7, 128, 297, 8 + AUTORADIOBUTTON "रिऐक्ट ओएस इंस्टॉल करें(&I)", IDC_INSTALL, 7, 20, 277, 10 + LTEXT "रिऐक्ट ओएस की एक नई कापी इन्स्टॉल करें। यह विकल्प आपकी फाइलें, सेटिंग्स और प्रोग्राम नहीं रखता है। आप डिस्क और विभाजन में परिवर्तन कर सकते हैं।", IDC_INSTALLTEXT, 19, 36, 279, 27 + AUTORADIOBUTTON "रिऐक्ट ओएस की अद्यतन या मरम्मत करे।(&U)", IDC_UPDATE, 7, 80, 277, 10 + LTEXT "रिऐक्ट ओएस की एक स्थापित कापी अद्यतन या मरम्मत करे। यह विकल्प आपकी फाइलें, सेटिंग्स और प्रोग्राम रखता है। यह विकल्प केवल तभी उपलब्ध होता है जब इस कंप्यूटर पर रिऐक्ट ओएस पहले से इंस्टॉल हो।", IDC_UPDATETEXT, 19, 96, 279, 27 END IDD_DEVICEPAGE DIALOGEX 0, 0, 317, 143 @@ -139,8 +148,10 @@ END STRINGTABLE BEGIN IDS_CAPTION "रिऐक्ट ओएस सेटअप" - IDS_TYPETITLE "रिऐक्ट ओएस सेटअप में आपका स्वागत है" - IDS_TYPESUBTITLE "सेटअप प्रकार चुनें।" + IDS_TYPETITLE "Installation Type" + IDS_TYPESUBTITLE "You can setup a new ReactOS installation, or update/repair an existing installation." + IDS_UPDATETITLE "Update or Repair ReactOS" + IDS_UPDATESUBTITLE "Choose which existing ReactOS installation you want to update or repair." IDS_DEVICETITLE "बुनियादी डिवाइसों को सेटअप करें" IDS_DEVICESUBTITLE "डिस्प्ले और कीबोर्ड की सेटिंग्स सेट करें।" IDS_DRIVETITLE "इन्स्टलेशन विभाजन और सिस्टम फ़ोल्डर सेटअप करें" diff --git a/base/setup/reactos/lang/hu-HU.rc b/base/setup/reactos/lang/hu-HU.rc index 93e27c3d5ca3d..b2cae277c1d4a 100644 --- a/base/setup/reactos/lang/hu-HU.rc +++ b/base/setup/reactos/lang/hu-HU.rc @@ -9,9 +9,19 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "ReactOS telepítõ" FONT 8, "MS Shell Dlg" BEGIN - LTEXT "Welcome to the ReactOS Setup Wizard", IDC_STARTTITLE, 115, 8, 195, 24 - LTEXT "Nem tudod feltelepíteni a ReactOS rendszert így! Kérlek indítsd újra a számítógépet ezzel a CD-vel, hogy feltudjad telepíteni a ReactOS rendszert.", IDC_STATIC, 115, 40, 195, 100 - LTEXT "Click Finish to exit the Setup.", IDC_STATIC, 115, 169, 195, 17 + LTEXT "Üdvözöljük a ReactOS telepítőben", IDC_STARTTITLE, 115, 8, 195, 24 + LTEXT "This wizard will install or upgrade ReactOS on your computer, \ +and prepare the second part of the setup.", IDC_STATIC, 115, 40, 195, 27 +//// + GROUPBOX " IMPORTANT INFORMATION ", IDC_WARNTEXT1, 115, 70, 195, 90, BS_CENTER + LTEXT "ReactOS is in Alpha stage: it is not feature- complete and is \ +under heavy development. It is recommended to use it only for \ +evaluation and testing and not as your daily-usage OS.\n\ +It may corrupt your data or damage your hardware.", IDC_WARNTEXT2, 120, 80, 185, 50, SS_CENTER + LTEXT "Backup your data or test on a secondary computer \ +if you attempt to run ReactOS on real hardware.", IDC_WARNTEXT3, 120, 130, 185, 27, SS_CENTER +//// + LTEXT "Kattintson a Tovább gombra a folytatáshoz.", IDC_STATIC, 115, 169, 195, 17 END IDD_TYPEPAGE DIALOGEX 0, 0, 317, 143 @@ -19,11 +29,10 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "ReactOS telepítõ" FONT 8, "MS Shell Dlg" BEGIN - AUTORADIOBUTTON "Install ReactOS", IDC_INSTALL, 7, 7, 277, 10, WS_GROUP | WS_TABSTOP - LTEXT "Install a new copy of ReactOS. This option does not keep your files, settings and programs. You can make changes to disks and partitions.", IDC_INSTALLTEXT, 18, 18, 269, 25, NOT WS_GROUP - AUTORADIOBUTTON "Update or repair an installed ReactOS", IDC_UPDATE, 7, 50, 277, 10 - LTEXT "Update or repair an installed copy of ReactOS. This option keeps your files, settings and programs. This option is only available if ReactOS is already installed on this computer.", IDC_UPDATETEXT, 18, 61, 269, 30, NOT WS_GROUP - LTEXT "Click Next to setup the devices.", IDC_STATIC, 7, 128, 297, 8 + AUTORADIOBUTTON "&Install ReactOS", IDC_INSTALL, 7, 20, 277, 10, WS_GROUP | WS_TABSTOP + LTEXT "Install a new copy of ReactOS. This option does not keep your files, settings and programs. You can make changes to disks and partitions.", IDC_INSTALLTEXT, 19, 36, 279, 27, NOT WS_GROUP + AUTORADIOBUTTON "&Update or repair ReactOS", IDC_UPDATE, 7, 80, 277, 10 + LTEXT "Update or repair an installed copy of ReactOS. This option keeps your files, settings and programs. This option is only available if ReactOS is already installed on this computer.", IDC_UPDATETEXT, 19, 96, 279, 27, NOT WS_GROUP END IDD_UPDATEREPAIRPAGE DIALOGEX 0, 0, 317, 143 @@ -163,8 +172,10 @@ END STRINGTABLE BEGIN IDS_CAPTION "ReactOS Setup" - IDS_TYPETITLE "Welcome to ReactOS Setup" - IDS_TYPESUBTITLE "Choose setup type." + IDS_TYPETITLE "Installation Type" + IDS_TYPESUBTITLE "You can setup a new ReactOS installation, or update/repair an existing installation." + IDS_UPDATETITLE "Update or Repair ReactOS" + IDS_UPDATESUBTITLE "Choose which existing ReactOS installation you want to update or repair." IDS_DEVICETITLE "Setup the basic devices" IDS_DEVICESUBTITLE "Set the settings of display and keyboard." IDS_DRIVETITLE "Setup the installation partition and system folder" diff --git a/base/setup/reactos/lang/id-ID.rc b/base/setup/reactos/lang/id-ID.rc index faeb2b7e961b9..46f4ceab711e7 100644 --- a/base/setup/reactos/lang/id-ID.rc +++ b/base/setup/reactos/lang/id-ID.rc @@ -8,8 +8,18 @@ CAPTION "Penyetelan ReactOS" FONT 8, "MS Shell Dlg" BEGIN LTEXT "Selamat datang di Penuntun Penyetelan ReactOS", IDC_STARTTITLE, 115, 8, 195, 24 - LTEXT "ReactOS belum bisa dipasang dari CD secara langsung! Mohon mulai ulang komputer ini dari CD secara berurutan untuk memasang ReactOS.", IDC_STATIC, 115, 40, 195, 100 - LTEXT "Klik selesai untuk keluar dari penyetelan.", IDC_STATIC, 115, 169, 195, 17 + LTEXT "Wisaya ini akan memasang atau meningkatkan ReactOS pada komputermu, \ +dan menyiapkan penyetelan bagian kedua.", IDC_STATIC, 115, 40, 195, 27 +//// + GROUPBOX " INFORMASI PENTING ", IDC_WARNTEXT1, 115, 70, 195, 90, BS_CENTER + LTEXT "ReactOS saat ini pada babak Alpha: Fiturnya belum lengkap dan \ +masih dalam tahap pengembangan besar. Sebaiknya gunakan hanya untuk \ +evaluasi dan pengujian, bukan sebagai OS untuk penggunaan sehari-hari.\n\ +Ini dapat merusak data Anda atau merusak perangkat kerasmu.", IDC_WARNTEXT2, 120, 80, 185, 50, SS_CENTER + LTEXT "Cadangkan datamu atau uji pada komputer sekunder \ +jika kamu mencoba menjalankan ReactOS pada perangkat keras yang asli.", IDC_WARNTEXT3, 120, 130, 185, 27, SS_CENTER +//// + LTEXT "Klik Lanjut untuk melanjutkan Penyetelan.", IDC_STATIC, 115, 169, 195, 17 END IDD_TYPEPAGE DIALOGEX 0, 0, 317, 143 @@ -17,11 +27,10 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "Penyetelan ReactOS" FONT 8, "MS Shell Dlg" BEGIN - AUTORADIOBUTTON "Pasang ReactOS", IDC_INSTALL, 7, 7, 277, 10, WS_GROUP | WS_TABSTOP - LTEXT "Pasang instalasi ReactOS yang baru. Ini tidak akan menjaga berkas, pengaturan, dan program Anda. Anda bisa membuat perubahan pada disk dan partisi.", IDC_INSTALLTEXT, 18, 18, 269, 25, NOT WS_GROUP - AUTORADIOBUTTON "Perbarui atau perbaiki ReactOS", IDC_UPDATE, 7, 50, 277, 10 - LTEXT "Perbarui atau perbaiki salinan terpasang dari ReactOS. Pilihan ini tetap menyimpan berkas, Pengaturan dan program. Pilihan ini hanya tersedia jika ReactOS telah terpasang di komputer ini.", IDC_UPDATETEXT, 18, 61, 269, 30, NOT WS_GROUP - LTEXT "Klik lanjut untuk meneruskan.", IDC_STATIC, 7, 128, 297, 8 + AUTORADIOBUTTON "&Pasang ReactOS", IDC_INSTALL, 7, 20, 277, 10, WS_GROUP | WS_TABSTOP + LTEXT "Pasang instalasi ReactOS yang baru. Ini tidak akan menjaga file, pengaturan, dan program Anda. Anda bisa membuat perubahan pada disk dan partisi.", IDC_INSTALLTEXT, 19, 36, 279, 27, NOT WS_GROUP + AUTORADIOBUTTON "P&erbarui atau perbaiki ReactOS", IDC_UPDATE, 7, 80, 277, 10 + LTEXT "Perbarui atau perbaiki salinan terpasang dari ReactOS. Pilihan ini tetap menyimpan file, Pengaturan dan program. Pilihan ini hanya tersedia jika ReactOS telah terpasang di komputer ini.", IDC_UPDATETEXT, 19, 96, 279, 27, NOT WS_GROUP END IDD_UPDATEREPAIRPAGE DIALOGEX 0, 0, 317, 143 @@ -55,13 +64,13 @@ CAPTION "Penyetelan ReactOS" FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_PARTITION, "SysTreeList32", WS_BORDER | WS_VISIBLE | WS_TABSTOP | LVS_REPORT | LVS_SINGLESEL, 7, 7, 303, 112 - PUSHBUTTON "&Initialize", IDC_INITDISK, 7, 122, 50, 14 // NOTE: At same position as IDC_PARTCREATE + PUSHBUTTON "&Menginisialisasi", IDC_INITDISK, 7, 122, 50, 14 // NOTE: At same position as IDC_PARTCREATE PUSHBUTTON "&Buat", IDC_PARTCREATE, 7, 122, 50, 14 PUSHBUTTON "&Format", IDC_PARTFORMAT, 7, 122, 50, 14 // NOTE: At same position as IDC_PARTCREATE PUSHBUTTON "&Hapus", IDC_PARTDELETE, 63, 122, 50, 14 PUSHBUTTON "&Perangkat", IDC_DEVICEDRIVER, 174, 122, 50, 14, WS_DISABLED PUSHBUTTON "Pilihan &Tingkat Lanjut...", IDC_PARTMOREOPTS, 230, 122, 80, 14 - // LTEXT "Click Next to check the summary.", IDC_STATIC, 7, 128, 277, 8 + // LTEXT "Tekan Lanjut untuk mmeriksa rangkuman.", IDC_STATIC, 7, 128, 277, 8 END IDD_PARTITION DIALOGEX 0, 0, 200, 120 @@ -74,7 +83,7 @@ BEGIN CONTROL "", IDC_UPDOWN_PARTSIZE, UPDOWN_CLASS, UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | WS_GROUP, 120, 22, 9, 13 LTEXT "MB", IDC_UNIT, 134, 9, 14, 9 - AUTOCHECKBOX "&Extended partition", IDC_CHECK_MBREXTPART, 7, 22, 180, 14 + AUTOCHECKBOX "Partisi yang dip&erluas", IDC_CHECK_MBREXTPART, 7, 22, 180, 14 LTEXT "&Sistem Berkas:", IDC_FS_STATIC, 7, 46, 70, 9 COMBOBOX IDC_FSTYPE, 82, 44, 100, 50, CBS_DROPDOWNLIST | WS_TABSTOP AUTOCHECKBOX "&Quick format", IDC_CHECK_QUICKFMT, 7, 59, 180, 14 @@ -89,20 +98,20 @@ FONT 8, "MS Shell Dlg" BEGIN LTEXT "&Sistem Berkas:", IDC_FS_STATIC, 7, 9, 70, 9 COMBOBOX IDC_FSTYPE, 82, 7, 100, 50, CBS_DROPDOWNLIST | WS_TABSTOP - AUTOCHECKBOX "&Quick format", IDC_CHECK_QUICKFMT, 7, 22, 180, 14 + AUTOCHECKBOX "&Format cepat", IDC_CHECK_QUICKFMT, 7, 22, 180, 14 PUSHBUTTON "OK", IDOK, 88, 61, 50, 14 PUSHBUTTON "Batal", IDCANCEL, 143, 61, 50, 14 END IDD_ADVINSTOPTS DIALOGEX 0, 0, 305, 135 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Advanced Installation Options" +CAPTION "Opsi Pemasangan Tingkat Lanjut" FONT 8, "MS Shell Dlg" BEGIN - LTEXT "Choose the &directory where you want to install ReactOS:", IDC_STATIC, 7, 9, 291, 10 + LTEXT "Pilih &direktori yang ingin kamu pasang ReactOS:", IDC_STATIC, 7, 9, 291, 10 EDITTEXT IDC_PATH, 7, 23, 291, 13 GROUPBOX "Bootloader", IDC_STATIC, 7, 45, 291, 60 - LTEXT "Select the location where the FreeLoader\nbootloader should be installed.\n\nBy default, it is installed on the system partition of the boot disk (and either in the Master or the Volume Boot Record for BIOS-based computers).", IDC_STATIC, 13, 57, 279, 44 + LTEXT "Memilih lokasi di mana Freeloader\nbootloader seharusnya dipasang.\n\nPada Aslinya, ini terpasang pada partisi sistem dari disk boot(bisa juga di Master atau Volume Boot Record untuk komputer berbasis BIOS).", IDC_STATIC, 13, 57, 279, 44 COMBOBOX IDC_INSTFREELDR, 150, 58, 142, 45, WS_VSCROLL | WS_TABSTOP | CBS_DROPDOWNLIST DEFPUSHBUTTON "OK", IDOK, 193, 113, 50, 14 PUSHBUTTON "Batal", IDCANCEL, 248, 113, 50, 14 @@ -161,8 +170,10 @@ END STRINGTABLE BEGIN IDS_CAPTION "Penyetelan ReactOS" - IDS_TYPETITLE "Selamat datang di Penyetelan ReactOS" - IDS_TYPESUBTITLE "Pilih jenis penyetelan." + IDS_TYPETITLE "Jenis Pemasangan" + IDS_TYPESUBTITLE "Kamu bisa menyetel pemasangan baru ReactOS, atau memperbarui/meningkatkan pemasangan yang telah ada." + IDS_UPDATETITLE "Perbarui atau Perbaiki ReactOS" + IDS_UPDATESUBTITLE "Pilih pemasangan ReactOS yang ada yang ingin kamu perbarui atau perbaiki." IDS_DEVICETITLE "Menyetel perangkat dasar" IDS_DEVICESUBTITLE "Setel pengaturan tampilan dan papan ketik." IDS_DRIVETITLE "Penyetelan pemasangan partisi dan folder sistem" @@ -177,7 +188,7 @@ BEGIN IDS_ABORTSETUP2 "Gugurkan pemasangan?" IDS_NO_TXTSETUP_SIF "Tidak bisa menemukan 'txtsetup.sif'.\nPenyetelan tidak bisa dilanjutkan." IDS_INSTALLBTN "&Install" - IDS_VOLUME_NOFORMAT "Not formatted" + IDS_VOLUME_NOFORMAT "Tidak terformat" END STRINGTABLE @@ -197,10 +208,10 @@ END STRINGTABLE BEGIN - IDS_BOOTLOADER_NOINST "No installation" - IDS_BOOTLOADER_REMOVABLE "Removable media" - IDS_BOOTLOADER_SYSTEM "System partition (Default)" - IDS_BOOTLOADER_MBRVBR "MBR dan VBR (Default)" + IDS_BOOTLOADER_NOINST "Tidak ada pemasangan" + IDS_BOOTLOADER_REMOVABLE "Media yang bisa dilepas" + IDS_BOOTLOADER_SYSTEM "Partisi sistem (Asli)" + IDS_BOOTLOADER_MBRVBR "MBR dan VBR (Asli)" IDS_BOOTLOADER_VBRONLY "Hanya VBR" END @@ -208,88 +219,88 @@ END STRINGTABLE BEGIN - IDS_FORMATTING_PROGRESS1 "Formatting volume %c: (%s) in %s..." - IDS_FORMATTING_PROGRESS2 "Formatting volume %s in %s..." + IDS_FORMATTING_PROGRESS1 "Memformat volume %c: (%s) dalam %s..." + IDS_FORMATTING_PROGRESS2 "Memformat volume %s dalam %s..." - IDS_CHECKING_PROGRESS1 "Checking volume %c: (%s)..." - IDS_CHECKING_PROGRESS2 "Checking volume %s..." + IDS_CHECKING_PROGRESS1 "Memeriksa volume %c: (%s)..." + IDS_CHECKING_PROGRESS2 "Memeriksa volume %s..." - IDS_COPYING "Copying %s" - IDS_MOVING "Moving %s to %s" - IDS_RENAMING "Renaming %s to %s" - IDS_DELETING "Deleting %s" + IDS_COPYING "Menyalin %s" + IDS_MOVING "Memindahkan %s ke %s" + IDS_RENAMING "Mengubah nama %s ke %s" + IDS_DELETING "Menghapus %s" - IDS_CONFIG_SYSTEM_PARTITION "Configuring the system partition..." - IDS_PREPARE_PARTITIONS "Preparing partitions..." - IDS_PREPARE_FILES "Preparing the list of files to be copied, please wait..." - IDS_COPYING_FILES "Copying the files..." + IDS_CONFIG_SYSTEM_PARTITION "Mengonfigurasi partisi sistem..." + IDS_PREPARE_PARTITIONS "Menyiapkan partisi..." + IDS_PREPARE_FILES "Menyiapkan daftar file yang akan disalin, mohon tunggu..." + IDS_COPYING_FILES "Menyalin file..." - IDS_CREATE_REGISTRY "Creating the registry..." - IDS_UPDATE_REGISTRY "Updating the registry..." + IDS_CREATE_REGISTRY "Membuat registri..." + IDS_UPDATE_REGISTRY "Memperbarui registri..." - // IDS_INSTALL_FINALIZE "Finalizing the installation..." - IDS_INSTALL_BOOTLOADER "Installing the bootloader..." + // IDS_INSTALL_FINALIZE "Menyelesaikan pemasangan..." + IDS_INSTALL_BOOTLOADER "Memasang bootloader..." END // Note to translators: please refer to the corresponding usetup/lang/*.h translations. STRINGTABLE BEGIN - IDS_REG_DONE "Done" - IDS_REG_REGHIVEUPDATE "Updating registry hives" - IDS_REG_IMPORTFILE "Importing %s" - IDS_REG_DISPLAYSETTINGSUPDATE "Updating display registry settings" - IDS_REG_LOCALESETTINGSUPDATE "Updating locale settings" + IDS_REG_DONE "Selesai" + IDS_REG_REGHIVEUPDATE "Memperbarui kumpulan registri" + IDS_REG_IMPORTFILE "Memasukkan %s" + IDS_REG_DISPLAYSETTINGSUPDATE "Memperbarui pengaturan registri tampilan" + IDS_REG_LOCALESETTINGSUPDATE "Memperbarui pengaturan lokal" IDS_REG_ADDKBLAYOUTS "Adding keyboard layouts" - IDS_REG_KEYBOARDSETTINGSUPDATE "Updating keyboard layout settings" - IDS_REG_CODEPAGEINFOUPDATE "Adding codepage information" - IDS_REG_UNKNOWN "Unknown status %d" + IDS_REG_KEYBOARDSETTINGSUPDATE "Memperbarui pengaturan tata letak papan ketik" + IDS_REG_CODEPAGEINFOUPDATE "Menambahkan informasi halaman kode" + IDS_REG_UNKNOWN "Status tidak diketahui %d" END /* Error Strings */ STRINGTABLE BEGIN - IDS_ERROR_INVALID_INSTALLDIR_CHAR_TITLE "Invalid character" - IDS_ERROR_INVALID_INSTALLDIR_CHAR "The only valid characters are:\n\ -alphanumericals (a-z, A-Z, 0-9), and\n . \\ - _\n\ -Spaces are not allowed." + IDS_ERROR_INVALID_INSTALLDIR_CHAR_TITLE "Karakter tidak sah" + IDS_ERROR_INVALID_INSTALLDIR_CHAR "Karakter yang sah hanya:\n\ +alfanumerik (a-z, A-Z, 0-9), dan\n . \\ - _\n\ +Spasi tidak diperbolehkan." - IDS_ERROR_DIRECTORY_NAME_TITLE "Invalid installation path" - IDS_ERROR_DIRECTORY_NAME "The ReactOS installation path must follow the DOS 8.3 naming scheme, \ -and only contain letters, digits, dashes and periods. Spaces are not allowed." + IDS_ERROR_DIRECTORY_NAME_TITLE "Jalur pemasangan tidak sah" + IDS_ERROR_DIRECTORY_NAME "Jalur pemasangan ReactOS harus mengikuti skema penamaan DOS 8.3 , \ +dan hanya mengandung huruf, angka, dan hanya berisi huruf, angka, tanda hubung, dan titik. Spasi tidak diperbolehkan." - IDS_ERROR_CREATE_PARTITION_TITLE "Create partition" - IDS_ERROR_CREATE_PARTITION "Failed to create a new partition." + IDS_ERROR_CREATE_PARTITION_TITLE "Membuat partisi" + IDS_ERROR_CREATE_PARTITION "Gagal membuat partisi baru." - IDS_WARN_DELETE_PARTITION_TITLE "Delete partition?" - IDS_WARN_DELETE_PARTITION "Are you sure you want to delete the selected partition?" - IDS_WARN_DELETE_MBR_EXTENDED_PARTITION "Are you sure you want to delete the selected extended partition and ALL the logical partitions it contains?" + IDS_WARN_DELETE_PARTITION_TITLE "Hapus partisi?" + IDS_WARN_DELETE_PARTITION "Kamu yakin ingin menghapus partisi terpilih?" + IDS_WARN_DELETE_MBR_EXTENDED_PARTITION "Apakah Anda yakin ingin menghapus partisi perluasan terpilih dan SEMUA partisi logikal yang ada di dalamnya?" - IDS_ERROR_WRITE_PTABLE "Setup failed to write partition tables." + IDS_ERROR_WRITE_PTABLE "Penyetelan gagal menulis tabel partisi." - IDS_ERROR_SYSTEM_PARTITION "The ReactOS Setup could not find a supported system partition\n\ -on your system or could not create a new one. Without such a partition\n\ -the Setup program cannot install ReactOS.\ -\nClick on OK to return to the partition selection list." + IDS_ERROR_SYSTEM_PARTITION "Penyetelan ReactOS tidak bisa menemukan partisi sistem yang didukung\n\ +pada sistemmu atau tidak bisa membuat baru. Tanpa partisi tersebut\n\ +Program penyetelan tidak bisa memasang ReactOS.\ +\nKlik OK untuk kembali ke to kembali ke daftar pilihan partisi." - IDS_ERROR_FORMAT_UNRECOGNIZED_VOLUME "Unrecognized volume while attempting to format the partition." + IDS_ERROR_FORMAT_UNRECOGNIZED_VOLUME "Volume tidak dikenal ketika mencoba memformat partisi." - IDS_ERROR_COULD_NOT_FORMAT "Setup is currently unable to format a partition in %s.\n\ -\nClick on OK to continue Setup.\ -\nClick on CANCEL to quit Setup." + IDS_ERROR_COULD_NOT_FORMAT "Penyetelan saat ini tidak bisa memformat partisi dalam %s.\n\ +\nKlik OK melanjutkan Penyetelan.\ +\nKlik BATAL untuk keluar dari Penyetelan." - IDS_ERROR_FORMATTING_PARTITION "Setup is unable to format the partition:\n %s\n" + IDS_ERROR_FORMATTING_PARTITION "Penyetelan tidak bisa memformat partisi:\n %s\n" - IDS_ERROR_COULD_NOT_CHECK "Setup is currently unable to check a partition formatted in %s.\n\ -\nClick on OK to continue Setup.\ -\nClick on CANCEL to quit Setup." + IDS_ERROR_COULD_NOT_CHECK "Penyetelan saat ini tidak bisa memeriksa partisi yang terformat dalam %s.\n\ +\nKlik OK melanjutkan Penyetelan.\ +\nKlik BATAL untuk keluar dari Penyetelan." - IDS_ERROR_CHECKING_PARTITION "ChkDsk detected some disk errors.\n(Status 0x%08lx)." + IDS_ERROR_CHECKING_PARTITION "ChkDsk mendeteksi kesalahan beberapa disk.\n(Status 0x%08lx)." - IDS_ERROR_WRITE_BOOT "Setup failed to install the %s bootcode on the system partition." - IDS_ERROR_INSTALL_BOOTCODE "Setup failed to install the %s bootcode on the boot disk." - IDS_ERROR_INSTALL_BOOTCODE_REMOVABLE "Setup failed to install the bootcode on the removable media." - IDS_ERROR_BOOTLDR_ARCH_UNSUPPORTED "Setup does not currently support installing the bootloader on the computer you are using.\ -\nClick on OK to continue anyway." - IDS_ERROR_BOOTLDR_FAILED "Setup could not install the bootloader (Status 0x%08lx)." + IDS_ERROR_WRITE_BOOT "Penyetelan gagal memasang bootcode %s pada partisi sistem." + IDS_ERROR_INSTALL_BOOTCODE "Penyetelan gagal memasang bootcode %s pada boot disk." + IDS_ERROR_INSTALL_BOOTCODE_REMOVABLE "Penyetelan gagal memasang bootcode pada media yang bisa dilepas." + IDS_ERROR_BOOTLDR_ARCH_UNSUPPORTED "Penyetelan saat ini tidak didukung untuk memasang bootloader pada komputer yang kamu gunakan.\ +\nKlik OK untuk tetap melanjutkan" + IDS_ERROR_BOOTLDR_FAILED "Penyetelan tidak bisa memasang bootloader (Status 0x%08lx)." END diff --git a/base/setup/reactos/lang/it-IT.rc b/base/setup/reactos/lang/it-IT.rc index 31368d066029b..eee40e0ce8733 100644 --- a/base/setup/reactos/lang/it-IT.rc +++ b/base/setup/reactos/lang/it-IT.rc @@ -8,8 +8,18 @@ CAPTION "Installazione di ReactOS" FONT 8, "MS Shell Dlg" BEGIN LTEXT "Benvenuto al wizard di installazione di ReactOS", IDC_STARTTITLE, 115, 8, 195, 24 - LTEXT "Non è ancora possibile installare ReactOS direttamente da questo CD! E' necessario riavviare il computer da questo CD per procedere alla installazione di ReactOS.", IDC_STATIC, 115, 40, 195, 100 - LTEXT "Cliccare Fine per uscire.", IDC_STATIC, 115, 169, 195, 17 + LTEXT "This wizard will install or upgrade ReactOS on your computer, \ +and prepare the second part of the setup.", IDC_STATIC, 115, 40, 195, 27 +//// + GROUPBOX " IMPORTANT INFORMATION ", IDC_WARNTEXT1, 115, 70, 195, 90, BS_CENTER + LTEXT "ReactOS is in Alpha stage: it is not feature- complete and is \ +under heavy development. It is recommended to use it only for \ +evaluation and testing and not as your daily-usage OS.\n\ +It may corrupt your data or damage your hardware.", IDC_WARNTEXT2, 120, 80, 185, 50, SS_CENTER + LTEXT "Backup your data or test on a secondary computer \ +if you attempt to run ReactOS on real hardware.", IDC_WARNTEXT3, 120, 130, 185, 27, SS_CENTER +//// + LTEXT "Selezionare Avanti per proseguire con la configurazione.", IDC_STATIC, 115, 169, 195, 17 END IDD_TYPEPAGE DIALOGEX 0, 0, 317, 143 @@ -17,11 +27,10 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "Installazione di ReactOS" FONT 8, "MS Shell Dlg" BEGIN - AUTORADIOBUTTON "Installa ReactOS", IDC_INSTALL, 7, 7, 277, 10, WS_GROUP | WS_TABSTOP - LTEXT "Installa una nuova coppia di ReactOS. Questo opzione non mantiene i tuoi file, le impostazioni e i programmi. E' possibile fare degli cambiamenti sul disco e partizioni.", IDC_INSTALLTEXT, 18, 18, 269, 25, NOT WS_GROUP - AUTORADIOBUTTON "Aggiorna o ripara una installazione precedente di ReactOS", IDC_UPDATE, 7, 50, 277, 10 - LTEXT "Aggiorna o ripara una coppia già installata di ReactOS. Questo opzione mantiene i tuoi file, le impostazioni e i programmi. Questo opzione è disponibile solo se ReactOS è già installato su questo computer.", IDC_UPDATETEXT, 18, 61, 269, 30, NOT WS_GROUP - LTEXT "Cliccare Avanti per impostare i dispositivi.", IDC_STATIC, 7, 128, 297, 8 + AUTORADIOBUTTON "&Installa ReactOS", IDC_INSTALL, 7, 20, 277, 10, WS_GROUP | WS_TABSTOP + LTEXT "Installa una nuova coppia di ReactOS. Questo opzione non mantiene i tuoi file, le impostazioni e i programmi. E' possibile fare degli cambiamenti sul disco e partizioni.", IDC_INSTALLTEXT, 19, 36, 279, 27, NOT WS_GROUP + AUTORADIOBUTTON "&Aggiorna o ripara ReactOS", IDC_UPDATE, 7, 80, 277, 10 + LTEXT "Aggiorna o ripara una coppia già installata di ReactOS. Questo opzione mantiene i tuoi file, le impostazioni e i programmi. Questo opzione è disponibile solo se ReactOS è già installato su questo computer.", IDC_UPDATETEXT, 19, 96, 279, 27, NOT WS_GROUP END IDD_UPDATEREPAIRPAGE DIALOGEX 0, 0, 317, 143 @@ -161,8 +170,10 @@ END STRINGTABLE BEGIN IDS_CAPTION "Installazione di ReactOS" - IDS_TYPETITLE "Benvenuti nell'installazione di ReactOS" - IDS_TYPESUBTITLE "Scegliere il tipo di installazione." + IDS_TYPETITLE "Installation Type" + IDS_TYPESUBTITLE "You can setup a new ReactOS installation, or update/repair an existing installation." + IDS_UPDATETITLE "Update or Repair ReactOS" + IDS_UPDATESUBTITLE "Choose which existing ReactOS installation you want to update or repair." IDS_DEVICETITLE "Impostazione dei dispositivi di base" IDS_DEVICESUBTITLE "Impostazione di monitor e tastiera." IDS_DRIVETITLE "Impostazione della partizione e della cartella per la installazione" diff --git a/base/setup/reactos/lang/ja-JP.rc b/base/setup/reactos/lang/ja-JP.rc index 580d42049bcfb..94d413b85f375 100644 --- a/base/setup/reactos/lang/ja-JP.rc +++ b/base/setup/reactos/lang/ja-JP.rc @@ -8,8 +8,18 @@ CAPTION "ReactOS セットアップ" FONT 9, "MS UI Gothic" BEGIN LTEXT "ReactOS セットアップウィザードへようこそ", IDC_STARTTITLE, 115, 8, 195, 24 - LTEXT "このCDからまだ直接ReactOSをインストールできません。ReactOSをインストールするために、このCDからコンピュータを再起動して下さい。", IDC_STATIC, 115, 40, 195, 100 - LTEXT "完了をクリックしてセットアップを終了して下さい。", IDC_STATIC, 115, 169, 195, 17 + LTEXT "This wizard will install or upgrade ReactOS on your computer, \ +and prepare the second part of the setup.", IDC_STATIC, 115, 40, 195, 27 +//// + GROUPBOX " IMPORTANT INFORMATION ", IDC_WARNTEXT1, 115, 70, 195, 90, BS_CENTER + LTEXT "ReactOS is in Alpha stage: it is not feature- complete and is \ +under heavy development. It is recommended to use it only for \ +evaluation and testing and not as your daily-usage OS.\n\ +It may corrupt your data or damage your hardware.", IDC_WARNTEXT2, 120, 80, 185, 50, SS_CENTER + LTEXT "Backup your data or test on a secondary computer \ +if you attempt to run ReactOS on real hardware.", IDC_WARNTEXT3, 120, 130, 185, 27, SS_CENTER +//// + LTEXT "セットアップを続行するには [次へ] をクリックして下さい。", IDC_STATIC, 115, 169, 195, 17 END IDD_TYPEPAGE DIALOGEX 0, 0, 317, 143 @@ -17,11 +27,10 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "ReactOS セットアップ" FONT 9, "MS UI Gothic" BEGIN - AUTORADIOBUTTON "ReactOSをインストールする", IDC_INSTALL, 7, 7, 277, 10, WS_GROUP | WS_TABSTOP - LTEXT "ReactOSを新しくインストールします。このオプションは、あなたのファイル、設定、プログラムを維持しません。あなたはディスクとパーティションに変更を加えることができます。", IDC_INSTALLTEXT, 18, 18, 269, 25, NOT WS_GROUP - AUTORADIOBUTTON "ReactOSを更新または修正する", IDC_UPDATE, 7, 50, 277, 10 - LTEXT "インストールされたReactOSを更新または修正します。このオプションはあなたのファイル、設定、プログラムを保持します。このオプションは、このコンピュータですでにReactOSがインストール済みのときのみ利用できます。", IDC_UPDATETEXT, 18, 61, 269, 30, NOT WS_GROUP - LTEXT "次へをクリックすると続行します。", IDC_STATIC, 7, 128, 297, 8 + AUTORADIOBUTTON "ReactOSをインストールする(&I)", IDC_INSTALL, 7, 20, 277, 10, WS_GROUP | WS_TABSTOP + LTEXT "ReactOSを新しくインストールします。このオプションは、あなたのファイル、設定、プログラムを維持しません。あなたはディスクとパーティションに変更を加えることができます。", IDC_INSTALLTEXT, 19, 36, 279, 27, NOT WS_GROUP + AUTORADIOBUTTON "ReactOSを更新または修正する(&U)", IDC_UPDATE, 7, 80, 277, 10 + LTEXT "インストールされたReactOSを更新または修正します。このオプションはあなたのファイル、設定、プログラムを保持します。このオプションは、このコンピュータですでにReactOSがインストール済みのときのみ利用できます。", IDC_UPDATETEXT, 19, 96, 279, 27, NOT WS_GROUP END IDD_UPDATEREPAIRPAGE DIALOGEX 0, 0, 317, 143 @@ -161,8 +170,10 @@ END STRINGTABLE BEGIN IDS_CAPTION "ReactOS セットアップ" - IDS_TYPETITLE "ReactOS セットアップにようこそ" - IDS_TYPESUBTITLE "セットアップの種類を選んで下さい。" + IDS_TYPETITLE "Installation Type" + IDS_TYPESUBTITLE "You can setup a new ReactOS installation, or update/repair an existing installation." + IDS_UPDATETITLE "Update or Repair ReactOS" + IDS_UPDATESUBTITLE "Choose which existing ReactOS installation you want to update or repair." IDS_DEVICETITLE "基本デバイスをセットアップします" IDS_DEVICESUBTITLE "ディスプレイとキーボードの設定をします。" IDS_DRIVETITLE "インストール先パーティションとシステムフォルダをセットアップします" diff --git a/base/setup/reactos/lang/ms-MY.rc b/base/setup/reactos/lang/ms-MY.rc index a7cd0c0921fe1..e470da49894a9 100644 --- a/base/setup/reactos/lang/ms-MY.rc +++ b/base/setup/reactos/lang/ms-MY.rc @@ -10,8 +10,18 @@ CAPTION "ReactOS Persediaan" FONT 8, "MS Shell Dlg" BEGIN LTEXT "Selamat datang ke Pendeta Persediaan ReactOS", IDC_STARTTITLE, 115, 8, 195, 24 - LTEXT "Anda tidak boleh memasang ReactOS terus dari CD ini lagi! Sila mula semula komputer anda dari CD ini untuk memasang ReactOS.", IDC_STATIC, 115, 40, 195, 100 - LTEXT "Klik Selesai untuk keluar persediaan.", IDC_STATIC, 115, 169, 195, 17 + LTEXT "This wizard will install or upgrade ReactOS on your computer, \ +and prepare the second part of the setup.", IDC_STATIC, 115, 40, 195, 27 +//// + GROUPBOX " IMPORTANT INFORMATION ", IDC_WARNTEXT1, 115, 70, 195, 90, BS_CENTER + LTEXT "ReactOS is in Alpha stage: it is not feature- complete and is \ +under heavy development. It is recommended to use it only for \ +evaluation and testing and not as your daily-usage OS.\n\ +It may corrupt your data or damage your hardware.", IDC_WARNTEXT2, 120, 80, 185, 50, SS_CENTER + LTEXT "Backup your data or test on a secondary computer \ +if you attempt to run ReactOS on real hardware.", IDC_WARNTEXT3, 120, 130, 185, 27, SS_CENTER +//// + LTEXT "Click Next to continue with Setup.", IDC_STATIC, 115, 169, 195, 17 END IDD_TYPEPAGE DIALOGEX 0, 0, 317, 143 @@ -19,11 +29,10 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "ReactOS Persediaan" FONT 8, "MS Shell Dlg" BEGIN - AUTORADIOBUTTON "Pasang ReactOS", IDC_INSTALL, 7, 7, 277, 10, WS_GROUP | WS_TABSTOP - LTEXT "Install a new copy of ReactOS. This option does not keep your files, settings and programs. You can make changes to disks and partitions.", IDC_INSTALLTEXT, 18, 18, 269, 25, NOT WS_GROUP - AUTORADIOBUTTON "Membaiki atau mengemaskini ReactOS yang dipasang", IDC_UPDATE, 7, 50, 277, 10 - LTEXT "Update or repair an installed copy of ReactOS. This option keeps your files, settings and programs. This option is only available if ReactOS is already installed on this computer.", IDC_UPDATETEXT, 18, 61, 269, 30, NOT WS_GROUP - LTEXT "Klik Seterusnya untuk memasang peranti.", IDC_STATIC, 7, 128, 297, 8 + AUTORADIOBUTTON "&Pasang ReactOS", IDC_INSTALL, 7, 20, 277, 10, WS_GROUP | WS_TABSTOP + LTEXT "Install a new copy of ReactOS. This option does not keep your files, settings and programs. You can make changes to disks and partitions.", IDC_INSTALLTEXT, 19, 36, 279, 27, NOT WS_GROUP + AUTORADIOBUTTON "&Membaiki atau mengemaskini ReactOS", IDC_UPDATE, 7, 80, 277, 10 + LTEXT "Update or repair an installed copy of ReactOS. This option keeps your files, settings and programs. This option is only available if ReactOS is already installed on this computer.", IDC_UPDATETEXT, 19, 96, 279, 27, NOT WS_GROUP END IDD_UPDATEREPAIRPAGE DIALOGEX 0, 0, 317, 143 @@ -163,8 +172,10 @@ END STRINGTABLE BEGIN IDS_CAPTION "ReactOS Persediaan" - IDS_TYPETITLE "Selamat datang ke persediaan ReactOS" - IDS_TYPESUBTITLE "Pilih jenis persediaan." + IDS_TYPETITLE "Installation Type" + IDS_TYPESUBTITLE "You can setup a new ReactOS installation, or update/repair an existing installation." + IDS_UPDATETITLE "Update or Repair ReactOS" + IDS_UPDATESUBTITLE "Choose which existing ReactOS installation you want to update or repair." IDS_DEVICETITLE "Sediakan peranti asas" IDS_DEVICESUBTITLE "Setkan seting paparan dan papan kekunci." IDS_DRIVETITLE "Sediakan folder pemasangan partition dan sistem" diff --git a/base/setup/reactos/lang/no-NO.rc b/base/setup/reactos/lang/no-NO.rc index 2b4949e4b96f5..d3c897a8ef69e 100644 --- a/base/setup/reactos/lang/no-NO.rc +++ b/base/setup/reactos/lang/no-NO.rc @@ -7,9 +7,19 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "ReactOS installering" FONT 8, "MS Shell Dlg" BEGIN - LTEXT "Velkommen til ReactOS installering veiviseren", IDC_STARTTITLE, 115, 8, 220, 24 - LTEXT "Du kan ennå ikke installere ReactOS direkte fra denne CD-en! Vennligst start datamaskinen på nytt og start fra denne platen for å installere ReactOS.", IDC_STATIC, 115, 40, 195, 100 - LTEXT "Trykk på Fullført for å avslutte installeringen.", IDC_STATIC, 115, 169, 195, 17 + LTEXT "Velkommen til ReactOS installering veiviseren", IDC_STARTTITLE, 115, 8, 195, 24 + LTEXT "This wizard will install or upgrade ReactOS on your computer, \ +and prepare the second part of the setup.", IDC_STATIC, 115, 40, 195, 27 +//// + GROUPBOX " IMPORTANT INFORMATION ", IDC_WARNTEXT1, 115, 70, 195, 90, BS_CENTER + LTEXT "ReactOS is in Alpha stage: it is not feature- complete and is \ +under heavy development. It is recommended to use it only for \ +evaluation and testing and not as your daily-usage OS.\n\ +It may corrupt your data or damage your hardware.", IDC_WARNTEXT2, 120, 80, 185, 50, SS_CENTER + LTEXT "Backup your data or test on a secondary computer \ +if you attempt to run ReactOS on real hardware.", IDC_WARNTEXT3, 120, 130, 185, 27, SS_CENTER +//// + LTEXT "Klikk Neste for å fortsette installasjonen.", IDC_STATIC, 115, 169, 195, 17 END IDD_TYPEPAGE DIALOGEX 0, 0, 317, 143 @@ -17,11 +27,10 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "ReactOS installering" FONT 8, "MS Shell Dlg" BEGIN - AUTORADIOBUTTON "Installere ReactOS", IDC_INSTALL, 7, 7, 277, 10, WS_GROUP | WS_TABSTOP - LTEXT "Install a new copy of ReactOS. This option does not keep your files, settings and programs. You can make changes to disks and partitions.", IDC_INSTALLTEXT, 18, 18, 269, 25, NOT WS_GROUP - AUTORADIOBUTTON "Reparere eller oppdatere en installert ReactOS", IDC_UPDATE, 7, 50, 277, 10 - LTEXT "Update or repair an installed copy of ReactOS. This option keeps your files, settings and programs. This option is only available if ReactOS is already installed on this computer.", IDC_UPDATETEXT, 18, 61, 269, 30, NOT WS_GROUP - LTEXT "Trykk på Neste for installere enhetene.", IDC_STATIC, 7, 128, 297, 8 + AUTORADIOBUTTON "&Installere ReactOS", IDC_INSTALL, 7, 20, 277, 10, WS_GROUP | WS_TABSTOP + LTEXT "Install a new copy of ReactOS. This option does not keep your files, settings and programs. You can make changes to disks and partitions.", IDC_INSTALLTEXT, 19, 36, 279, 27, NOT WS_GROUP + AUTORADIOBUTTON "&Reparere eller oppdatere ReactOS", IDC_UPDATE, 7, 80, 277, 10 + LTEXT "Update or repair an installed copy of ReactOS. This option keeps your files, settings and programs. This option is only available if ReactOS is already installed on this computer.", IDC_UPDATETEXT, 19, 96, 279, 27, NOT WS_GROUP END IDD_UPDATEREPAIRPAGE DIALOGEX 0, 0, 317, 143 @@ -161,8 +170,10 @@ END STRINGTABLE BEGIN IDS_CAPTION "ReactOS installering" - IDS_TYPETITLE "Velkommen til ReactOS installering" - IDS_TYPESUBTITLE "Velg installering type." + IDS_TYPETITLE "Installation Type" + IDS_TYPESUBTITLE "You can setup a new ReactOS installation, or update/repair an existing installation." + IDS_UPDATETITLE "Update or Repair ReactOS" + IDS_UPDATESUBTITLE "Choose which existing ReactOS installation you want to update or repair." IDS_DEVICETITLE "Installer grunnleggende enheter" IDS_DEVICESUBTITLE "Velg innstillingene til skjermen og tastaturet." IDS_DRIVETITLE "Valg av installasjon partisjon og system mappe" diff --git a/base/setup/reactos/lang/pl-PL.rc b/base/setup/reactos/lang/pl-PL.rc index c077f071a43f2..ea6d6591d9b4c 100644 --- a/base/setup/reactos/lang/pl-PL.rc +++ b/base/setup/reactos/lang/pl-PL.rc @@ -19,8 +19,18 @@ CAPTION "Instalator systemu ReactOS" FONT 8, "MS Shell Dlg" BEGIN LTEXT "Witamy w Kreatorze instalacji systemu ReactOS", IDC_STARTTITLE, 115, 8, 195, 24 - LTEXT "Obecnie nie można zainstalować systemu ReactOS bezpośrednio! Uruchom ponownie komputer z tej płyty, aby zainstalować system ReactOS.", IDC_STATIC, 115, 40, 195, 100 - LTEXT "Kliknij przycisk Anuluj, aby zakończyć pracę instalatora.", IDC_STATIC, 115, 169, 195, 17 + LTEXT "This wizard will install or upgrade ReactOS on your computer, \ +and prepare the second part of the setup.", IDC_STATIC, 115, 40, 195, 27 +//// + GROUPBOX " IMPORTANT INFORMATION ", IDC_WARNTEXT1, 115, 70, 195, 90, BS_CENTER + LTEXT "ReactOS is in Alpha stage: it is not feature- complete and is \ +under heavy development. It is recommended to use it only for \ +evaluation and testing and not as your daily-usage OS.\n\ +It may corrupt your data or damage your hardware.", IDC_WARNTEXT2, 120, 80, 185, 50, SS_CENTER + LTEXT "Backup your data or test on a secondary computer \ +if you attempt to run ReactOS on real hardware.", IDC_WARNTEXT3, 120, 130, 185, 27, SS_CENTER +//// + LTEXT "Kliknij Dalej, by kontynuować.", IDC_STATIC, 115, 169, 160, 17 END IDD_TYPEPAGE DIALOGEX 0, 0, 317, 143 @@ -28,11 +38,10 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "Instalator systemu ReactOS" FONT 8, "MS Shell Dlg" BEGIN - AUTORADIOBUTTON "Zainstaluj system ReactOS", IDC_INSTALL, 7, 7, 277, 10, WS_GROUP | WS_TABSTOP - LTEXT "Zainstaluj nową kopię systemu ReactOS. Ta opcja nie zachowa plików, ustawień i programów. Możesz dokonać zmian w dyskach i partycjach.", IDC_INSTALLTEXT, 18, 18, 269, 25, NOT WS_GROUP - AUTORADIOBUTTON "Napraw lub uaktualnij istniejącą instalację systemu ReactOS", IDC_UPDATE, 7, 50, 277, 10 - LTEXT "Napraw istniejącą instalację lub wykonaj uaktualnienie do nowszej wersji systemu ReactOS. Ta opcja zachowa pliki, ustawienia i programy. Jest dostępna, jeżeli system ReactOS znajduje się już na tym komputerze.", IDC_UPDATETEXT, 18, 61, 269, 30, NOT WS_GROUP - LTEXT "Kliknij Dalej, aby zmienić ustawienia sprzętu.", IDC_STATIC, 7, 128, 297, 8 + AUTORADIOBUTTON "&Zainstaluj system ReactOS", IDC_INSTALL, 7, 20, 277, 10, WS_GROUP | WS_TABSTOP + LTEXT "Zainstaluj nową kopię systemu ReactOS. Ta opcja nie zachowa plików, ustawień i programów. Możesz dokonać zmian w dyskach i partycjach.", IDC_INSTALLTEXT, 19, 36, 279, 27, NOT WS_GROUP + AUTORADIOBUTTON "&Napraw lub uaktualnij ReactOS", IDC_UPDATE, 7, 80, 277, 10 + LTEXT "Napraw istniejącą instalację lub wykonaj uaktualnienie do nowszej wersji systemu ReactOS. Ta opcja zachowa pliki, ustawienia i programy. Jest dostępna, jeżeli system ReactOS znajduje się już na tym komputerze.", IDC_UPDATETEXT, 19, 96, 279, 27, NOT WS_GROUP END IDD_UPDATEREPAIRPAGE DIALOGEX 0, 0, 317, 143 @@ -172,8 +181,10 @@ END STRINGTABLE BEGIN IDS_CAPTION "Instalator systemu ReactOS" - IDS_TYPETITLE "Witamy w Kreatorze instalacji systemu ReactOS" - IDS_TYPESUBTITLE "Wybierz typ instalacji." + IDS_TYPETITLE "Installation Type" + IDS_TYPESUBTITLE "You can setup a new ReactOS installation, or update/repair an existing installation." + IDS_UPDATETITLE "Update or Repair ReactOS" + IDS_UPDATESUBTITLE "Choose which existing ReactOS installation you want to update or repair." IDS_DEVICETITLE "Ustawienia podstawowych urządzeń" IDS_DEVICESUBTITLE "Zmień ustawienia monitora i klawiatury." IDS_DRIVETITLE "Ustaw partycję instalacji i katalog systemowy" diff --git a/base/setup/reactos/lang/pt-BR.rc b/base/setup/reactos/lang/pt-BR.rc index 750fff7a706df..47ed4e83fd769 100644 --- a/base/setup/reactos/lang/pt-BR.rc +++ b/base/setup/reactos/lang/pt-BR.rc @@ -8,8 +8,18 @@ CAPTION "Instalação do ReactOS" FONT 8, "MS Shell Dlg" BEGIN LTEXT "Bem-vindo(a) ao Assistente de Instalação do ReactOS", IDC_STARTTITLE, 115, 8, 195, 24 - LTEXT "Você não pode instalar o ReactOS diretamente deste CD! Por favor reinicie seu computador a partir deste CD para instalar o ReactOS.", IDC_STATIC, 115, 40, 195, 100 - LTEXT "Clique em Finalizar para sair da Instalação.", IDC_STATIC, 115, 169, 195, 17 + LTEXT "This wizard will install or upgrade ReactOS on your computer, \ +and prepare the second part of the setup.", IDC_STATIC, 115, 40, 195, 27 +//// + GROUPBOX " IMPORTANT INFORMATION ", IDC_WARNTEXT1, 115, 70, 195, 90, BS_CENTER + LTEXT "ReactOS is in Alpha stage: it is not feature- complete and is \ +under heavy development. It is recommended to use it only for \ +evaluation and testing and not as your daily-usage OS.\n\ +It may corrupt your data or damage your hardware.", IDC_WARNTEXT2, 120, 80, 185, 50, SS_CENTER + LTEXT "Backup your data or test on a secondary computer \ +if you attempt to run ReactOS on real hardware.", IDC_WARNTEXT3, 120, 130, 185, 27, SS_CENTER +//// + LTEXT "Clique Avançar para continuar a instalação.", IDC_STATIC, 115, 169, 195, 17 END IDD_TYPEPAGE DIALOGEX 0, 0, 317, 143 @@ -17,11 +27,10 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "Instalação do ReactOS" FONT 8, "MS Shell Dlg" BEGIN - AUTORADIOBUTTON "Instalar ReactOS", IDC_INSTALL, 7, 7, 277, 10, WS_GROUP | WS_TABSTOP - LTEXT "Install a new copy of ReactOS. This option does not keep your files, settings and programs. You can make changes to disks and partitions.", IDC_INSTALLTEXT, 18, 18, 269, 25, NOT WS_GROUP - AUTORADIOBUTTON "Reparar ou atualizar uma instalação do ReactOS", IDC_UPDATE, 7, 50, 277, 10 - LTEXT "Update or repair an installed copy of ReactOS. This option keeps your files, settings and programs. This option is only available if ReactOS is already installed on this computer.", IDC_UPDATETEXT, 18, 61, 269, 30, NOT WS_GROUP - LTEXT "Clique em Próximo para configurar os dispositivos.", IDC_STATIC, 7, 128, 297, 8 + AUTORADIOBUTTON "&Instalar ReactOS", IDC_INSTALL, 7, 20, 277, 10, WS_GROUP | WS_TABSTOP + LTEXT "Install a new copy of ReactOS. This option does not keep your files, settings and programs. You can make changes to disks and partitions.", IDC_INSTALLTEXT, 19, 36, 279, 27, NOT WS_GROUP + AUTORADIOBUTTON "&Reparar ou atualizar ReactOS", IDC_UPDATE, 7, 80, 277, 10 + LTEXT "Update or repair an installed copy of ReactOS. This option keeps your files, settings and programs. This option is only available if ReactOS is already installed on this computer.", IDC_UPDATETEXT, 19, 96, 279, 27, NOT WS_GROUP END IDD_UPDATEREPAIRPAGE DIALOGEX 0, 0, 317, 143 @@ -161,8 +170,10 @@ END STRINGTABLE BEGIN IDS_CAPTION "Instalação do ReactOS" - IDS_TYPETITLE "Bem-vindo(a) a Instalação do ReactOS" - IDS_TYPESUBTITLE "Escolha o modo de instalação." + IDS_TYPETITLE "Installation Type" + IDS_TYPESUBTITLE "You can setup a new ReactOS installation, or update/repair an existing installation." + IDS_UPDATETITLE "Update or Repair ReactOS" + IDS_UPDATESUBTITLE "Choose which existing ReactOS installation you want to update or repair." IDS_DEVICETITLE "Instalar dispositivos básicos" IDS_DEVICESUBTITLE "Definir as configurações de monitor e teclado." IDS_DRIVETITLE "Configurar a partição de instalação e pasta do sistema" diff --git a/base/setup/reactos/lang/pt-PT.rc b/base/setup/reactos/lang/pt-PT.rc index e7867b4b93a56..9ada098735feb 100644 --- a/base/setup/reactos/lang/pt-PT.rc +++ b/base/setup/reactos/lang/pt-PT.rc @@ -8,8 +8,18 @@ CAPTION "Instalação do ReactOS" FONT 8, "MS Shell Dlg" BEGIN LTEXT "Bem-vindo(a) ao Assistente de Instalação do ReactOS", IDC_STARTTITLE, 115, 8, 195, 24 - LTEXT "Não pode instalar o ReactOS directamente deste CD! Por favor reinicie o computador a partir deste CD para instalar o ReactOS.", IDC_STATIC, 115, 40, 195, 100 - LTEXT "Clique em Finalizar para sair da Instalação.", IDC_STATIC, 115, 169, 195, 17 + LTEXT "This wizard will install or upgrade ReactOS on your computer, \ +and prepare the second part of the setup.", IDC_STATIC, 115, 40, 195, 27 +//// + GROUPBOX " IMPORTANT INFORMATION ", IDC_WARNTEXT1, 115, 70, 195, 90, BS_CENTER + LTEXT "ReactOS is in Alpha stage: it is not feature- complete and is \ +under heavy development. It is recommended to use it only for \ +evaluation and testing and not as your daily-usage OS.\n\ +It may corrupt your data or damage your hardware.", IDC_WARNTEXT2, 120, 80, 185, 50, SS_CENTER + LTEXT "Backup your data or test on a secondary computer \ +if you attempt to run ReactOS on real hardware.", IDC_WARNTEXT3, 120, 130, 185, 27, SS_CENTER +//// + LTEXT "Clique Avançar para continuar a instalação.", IDC_STATIC, 115, 169, 195, 17 END IDD_TYPEPAGE DIALOGEX 0, 0, 317, 143 @@ -17,11 +27,10 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "Instalação do ReactOS" FONT 8, "MS Shell Dlg" BEGIN - AUTORADIOBUTTON "Instalar ReactOS", IDC_INSTALL, 7, 7, 277, 10, WS_GROUP | WS_TABSTOP - LTEXT "Instalar uma nova cópia do ReactOS. Esta opção não preserva os ficheiros, definições ou programas existentes. Pode fazer alterações nos discos ou partições.", IDC_INSTALLTEXT, 18, 18, 269, 25, NOT WS_GROUP - AUTORADIOBUTTON "Reparar ou actualizar uma instalação do ReactOS", IDC_UPDATE, 7, 50, 277, 10 - LTEXT "Reparar ou actualizar uma instalação do ReactOS. Esta opção preserva os ficheiros, definições e programas existentes. Esta opção só está disponivel se o ReactOS já está instalado neste computador.", IDC_UPDATETEXT, 18, 61, 269, 30, NOT WS_GROUP - LTEXT "Clique em Próximo para configurar os dispositivos.", IDC_STATIC, 7, 128, 297, 8 + AUTORADIOBUTTON "&Instalar ReactOS", IDC_INSTALL, 7, 20, 277, 10, WS_GROUP | WS_TABSTOP + LTEXT "Instalar uma nova cópia do ReactOS. Esta opção não preserva os ficheiros, definições ou programas existentes. Pode fazer alterações nos discos ou partições.", IDC_INSTALLTEXT, 19, 36, 279, 27, NOT WS_GROUP + AUTORADIOBUTTON "&Reparar ou actualizar ReactOS", IDC_UPDATE, 7, 80, 277, 10 + LTEXT "Reparar ou actualizar uma instalação do ReactOS. Esta opção preserva os ficheiros, definições e programas existentes. Esta opção só está disponivel se o ReactOS já está instalado neste computador.", IDC_UPDATETEXT, 19, 96, 279, 27, NOT WS_GROUP END IDD_UPDATEREPAIRPAGE DIALOGEX 0, 0, 317, 143 @@ -161,8 +170,10 @@ END STRINGTABLE BEGIN IDS_CAPTION "Instalação do ReactOS" - IDS_TYPETITLE "Bem-vindo(a) a Instalação do ReactOS" - IDS_TYPESUBTITLE "Escolha o modo de instalação." + IDS_TYPETITLE "Installation Type" + IDS_TYPESUBTITLE "You can setup a new ReactOS installation, or update/repair an existing installation." + IDS_UPDATETITLE "Update or Repair ReactOS" + IDS_UPDATESUBTITLE "Choose which existing ReactOS installation you want to update or repair." IDS_DEVICETITLE "Instalar dispositivos básicos" IDS_DEVICESUBTITLE "Definir as configurações de monitor e teclado." IDS_DRIVETITLE "Configurar a partição de instalação e pasta do sistema" diff --git a/base/setup/reactos/lang/ro-RO.rc b/base/setup/reactos/lang/ro-RO.rc index c0122941cfba5..1aa9d15448a59 100644 --- a/base/setup/reactos/lang/ro-RO.rc +++ b/base/setup/reactos/lang/ro-RO.rc @@ -4,7 +4,7 @@ * PURPOSE: Romanian resource file * TRANSLATORS: Copyright 2009 Petru Dimitriu * Copyright 2011-2019 Ștefan Fulea - * Copyright 2022-2024 Andrei Miloiu + * Copyright 2022-2025 Andrei Miloiu */ LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL @@ -17,8 +17,18 @@ CAPTION "Expert de instalare ReactOS" FONT 8, "MS Shell Dlg" BEGIN LTEXT "Bun venit la instalarea ReactOS", IDC_STARTTITLE, 115, 8, 195, 24 - LTEXT "ReactOS încă nu poate fi instalat direct de pe acest CD! Pentru a instala ReactOS, reporniți calculatorul și utilizați acest CD în secvența de inițializare.", IDC_STATIC, 115, 40, 195, 100 - LTEXT "Apăsați pe Sfârșit pentru a ieși.", IDC_STATIC, 115, 169, 195, 17 + LTEXT "Acest expert va instala sau va face upgrade la ReactOS pe computer \ +și va pregăti a doua parte a instalatorului.", IDC_STATIC, 115, 40, 195, 27 +//// + GROUPBOX " IMPORTANT INFORMATION ", IDC_WARNTEXT1, 115, 70, 195, 90, BS_CENTER + LTEXT "ReactOS este în stadiu Alfa: nu e o caracteristică- completă și e \ +în curs de dezvoltare intensă. E recomandat să îl folosiți numai pentru \ +evaluare și testare și nu ca SO de utilizare zilnică.\n\ +Vă poate deteriora datele sau vă poate deteriora hardware-ul.", IDC_WARNTEXT2, 120, 80, 185, 50, SS_CENTER + LTEXT "Faceți o copie de rezervă a datelor sau testați-l pe un computer secundar \ +dacă încrecați să folosiți ReactOS pe hardware real.", IDC_WARNTEXT3, 120, 130, 185, 27, SS_CENTER +//// + LTEXT "Apăsați Înainte pentru a continua.", IDC_STATIC, 115, 169, 195, 17 END IDD_TYPEPAGE DIALOGEX 0, 0, 317, 143 @@ -26,11 +36,10 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "Expert de instalare ReactOS" FONT 8, "MS Shell Dlg" BEGIN - AUTORADIOBUTTON "Instalează ReactOS", IDC_INSTALL, 7, 7, 277, 10, WS_GROUP | WS_TABSTOP - LTEXT "Instalarea unei noi copii a ReactOS. Fișierele, configurațiile și programele existente nu vor fi păstrate. Sunt posibile ajustări asupra discurilor și partițiilor.", IDC_INSTALLTEXT, 18, 18, 269, 25, NOT WS_GROUP - AUTORADIOBUTTON "Repară sau actualizează ReactOS", IDC_UPDATE, 7, 50, 277, 10 - LTEXT "Repararea sau actualizarea ReactOS. Această opțiune menține fișierele, configurațiile și programele existente. Opțiune validă doar dacă ReactOS e deja instalat în calculator.", IDC_UPDATETEXT, 18, 61, 269, 30, NOT WS_GROUP - LTEXT "Apăsați pe Înainte pentru configurarea de dispozitive.", IDC_STATIC, 7, 128, 297, 8 + AUTORADIOBUTTON "&Instalează ReactOS", IDC_INSTALL, 7, 20, 277, 10, WS_GROUP | WS_TABSTOP + LTEXT "Instalarea unei noi copii a ReactOS. Fișierele, configurațiile și programele existente nu vor fi păstrate. Sunt posibile ajustări asupra discurilor și partițiilor.", IDC_INSTALLTEXT, 19, 36, 279, 27, NOT WS_GROUP + AUTORADIOBUTTON "&Repară sau actualizează ReactOS", IDC_UPDATE, 7, 80, 277, 10 + LTEXT "Repararea sau actualizarea ReactOS. Această opțiune menține fișierele, configurațiile și programele existente. Opțiune validă doar dacă ReactOS e deja instalat în calculator.", IDC_UPDATETEXT, 19, 96, 279, 27, NOT WS_GROUP END IDD_UPDATEREPAIRPAGE DIALOGEX 0, 0, 317, 143 @@ -49,7 +58,7 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "Expert de instalare ReactOS" FONT 8, "MS Shell Dlg" BEGIN - LTEXT "Calculator:", IDC_STATIC, 20, 15, 80, 10 + LTEXT "Computer:", IDC_STATIC, 20, 15, 80, 10 COMBOBOX IDC_COMPUTER, 100, 15, 180, 80, WS_VSCROLL | WS_TABSTOP | CBS_DROPDOWNLIST LTEXT "Ecran:", IDC_STATIC, 20, 35, 80, 10 COMBOBOX IDC_DISPLAY, 100, 35, 180, 80, WS_VSCROLL | WS_TABSTOP | CBS_DROPDOWNLIST @@ -64,12 +73,12 @@ CAPTION "Expert de instalare ReactOS" FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_PARTITION, "SysTreeList32", WS_BORDER | WS_VISIBLE | WS_TABSTOP | LVS_REPORT | LVS_SINGLESEL, 7, 7, 303, 112 - PUSHBUTTON "&Initialize", IDC_INITDISK, 7, 122, 50, 14 // NOTE: At same position as IDC_PARTCREATE - PUSHBUTTON "&Crează", IDC_PARTCREATE, 7, 122, 50, 14 - PUSHBUTTON "&Format", IDC_PARTFORMAT, 7, 122, 50, 14 // NOTE: At same position as IDC_PARTCREATE - PUSHBUTTON "Șt&erge", IDC_PARTDELETE, 63, 122, 50, 14 + PUSHBUTTON "&Initializare", IDC_INITDISK, 7, 122, 50, 14 // NOTE: At same position as IDC_PARTCREATE + PUSHBUTTON "&Creare", IDC_PARTCREATE, 7, 122, 50, 14 + PUSHBUTTON "&Formatare", IDC_PARTFORMAT, 7, 122, 50, 14 // NOTE: At same position as IDC_PARTCREATE + PUSHBUTTON "Șt&ergere", IDC_PARTDELETE, 63, 122, 50, 14 PUSHBUTTON "&Driver", IDC_DEVICEDRIVER, 174, 122, 50, 14, WS_DISABLED - PUSHBUTTON "Opțiuni a&vansate…", IDC_PARTMOREOPTS, 230, 122, 80, 14 + PUSHBUTTON "&Opțiuni complexe…", IDC_PARTMOREOPTS, 230, 122, 80, 14 // LTEXT "Apăsați pe Înainte pentru a verifica sumarul.", IDC_STATIC, 7, 128, 277, 8 END @@ -78,15 +87,15 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSM CAPTION "Crearea și formatarea partiției" FONT 8, "MS Shell Dlg" BEGIN - LTEXT "&Mărime:", IDC_STATIC, 7, 9, 70, 9 + LTEXT "&Dimensiune:", IDC_STATIC, 7, 9, 70, 9 EDITTEXT IDC_EDIT_PARTSIZE, 82, 7, 47, 13, ES_RIGHT | ES_NUMBER | WS_GROUP CONTROL "", IDC_UPDOWN_PARTSIZE, UPDOWN_CLASS, UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | WS_GROUP, 120, 22, 9, 13 LTEXT "MO", IDC_UNIT, 134, 9, 14, 9 - AUTOCHECKBOX "&Extended partition", IDC_CHECK_MBREXTPART, 7, 22, 180, 14 + AUTOCHECKBOX "Partiție &extinsă", IDC_CHECK_MBREXTPART, 7, 22, 180, 14 LTEXT "&Sistemul de fișiere:", IDC_FS_STATIC, 7, 46, 70, 9 COMBOBOX IDC_FSTYPE, 82, 44, 100, 50, CBS_DROPDOWNLIST | WS_TABSTOP - AUTOCHECKBOX "&Quick format", IDC_CHECK_QUICKFMT, 7, 59, 180, 14 + AUTOCHECKBOX "&Formatare rapidă", IDC_CHECK_QUICKFMT, 7, 59, 180, 14 PUSHBUTTON "OK", IDOK, 88, 98, 50, 14 PUSHBUTTON "Revocare", IDCANCEL, 143, 98, 50, 14 END @@ -98,20 +107,20 @@ FONT 8, "MS Shell Dlg" BEGIN LTEXT "&Sistemul de fișiere:", IDC_FS_STATIC, 7, 9, 70, 9 COMBOBOX IDC_FSTYPE, 82, 7, 100, 50, CBS_DROPDOWNLIST | WS_TABSTOP - AUTOCHECKBOX "&Quick format", IDC_CHECK_QUICKFMT, 7, 22, 180, 14 + AUTOCHECKBOX "&Formatare rapidă", IDC_CHECK_QUICKFMT, 7, 22, 180, 14 PUSHBUTTON "OK", IDOK, 88, 61, 50, 14 PUSHBUTTON "Revocare", IDCANCEL, 143, 61, 50, 14 END IDD_ADVINSTOPTS DIALOGEX 0, 0, 305, 135 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Advanced Installation Options" +CAPTION "Opțiuni de instalare complexă" FONT 8, "MS Shell Dlg" BEGIN - LTEXT "Choose the &directory where you want to install ReactOS:", IDC_STATIC, 7, 9, 291, 10 + LTEXT "Alegeți &directorul unde vreți să instalați ReactOS:", IDC_STATIC, 7, 9, 291, 10 EDITTEXT IDC_PATH, 7, 23, 291, 13 GROUPBOX "Bootloader", IDC_STATIC, 7, 45, 291, 60 - LTEXT "Select the location where the FreeLoader\nbootloader should be installed.\n\nBy default, it is installed on the system partition of the boot disk (and either in the Master or the Volume Boot Record for BIOS-based computers).", IDC_STATIC, 13, 57, 279, 44 + LTEXT "Selectați locația unde ar trebui\ninstalat bootloader-ul FreeLoader.\n\nÎn mod implicit, este instalat pe partiția de sistem a discului de pornire (și fie în Master, fie în Volume Boot Record pentru computerele bazate pe BIOS).", IDC_STATIC, 13, 57, 279, 44 COMBOBOX IDC_INSTFREELDR, 150, 58, 142, 45, WS_VSCROLL | WS_TABSTOP | CBS_DROPDOWNLIST DEFPUSHBUTTON "OK", IDOK, 193, 113, 50, 14 PUSHBUTTON "Revocare", IDCANCEL, 248, 113, 50, 14 @@ -128,7 +137,7 @@ BEGIN EDITTEXT IDC_INSTALLSOURCE, 95, 16, 210, 13, ES_READONLY | ES_AUTOHSCROLL | WS_VISIBLE | NOT WS_BORDER | NOT WS_TABSTOP LTEXT "Arhitectură:", IDC_STATIC, 18, 29, 74, 11 EDITTEXT IDC_ARCHITECTURE, 95, 28, 210, 13, ES_READONLY | ES_AUTOHSCROLL | WS_VISIBLE | NOT WS_BORDER | NOT WS_TABSTOP - LTEXT "Calculator:", IDC_STATIC, 18, 41, 74, 11 + LTEXT "Computer:", IDC_STATIC, 18, 41, 74, 11 EDITTEXT IDC_COMPUTER, 95, 40, 210, 13, ES_READONLY | ES_AUTOHSCROLL | WS_VISIBLE | NOT WS_BORDER | NOT WS_TABSTOP LTEXT "Ecran:", IDC_STATIC, 18, 53, 74, 11 EDITTEXT IDC_DISPLAY, 95, 52, 210, 13, ES_READONLY | ES_AUTOHSCROLL | WS_VISIBLE | NOT WS_BORDER | NOT WS_TABSTOP @@ -138,9 +147,9 @@ BEGIN EDITTEXT IDC_DESTDRIVE, 95, 76, 210, 13, ES_READONLY | ES_AUTOHSCROLL | WS_VISIBLE | NOT WS_BORDER | NOT WS_TABSTOP LTEXT "Director de destinație:", IDC_STATIC, 18, 89, 74, 11 EDITTEXT IDC_PATH, 95, 88, 210, 13, ES_READONLY | ES_AUTOHSCROLL | WS_VISIBLE | NOT WS_BORDER | NOT WS_TABSTOP - AUTOCHECKBOX "Confirm că toate opțiunile de instalare sunt corecte. De asemenea, conștientizez că\nReactOS nu a ajuns la maturitate și în consecință îmi poate deteriora calculatorul sau datele.", + AUTOCHECKBOX "Confirm că toate setările de instalare sunt corecte. Recunosc, de asemenea, că\nReactOS este un software de calitate alfa și se poate deteriora pe computerul meu sau îmi poate deteriora datele.", IDC_CONFIRM_INSTALL, 7, 104, 310, 18, BS_MULTILINE - LTEXT "Verificați că toate opțiunile de instalare sunt corecte,\napoi acționați Instalează pentru a porni procesul de instalare.", IDC_STATIC, 7, 124, 303, 18 + LTEXT "Vă rugăm să confirmați că toate setările de instalare sunt corecte,\nfaceți clic pe Instalare pentru a începe procesul de instalare.", IDC_STATIC, 7, 124, 303, 18 END IDD_PROCESSPAGE DIALOGEX 0, 0, 317, 143 @@ -155,14 +164,14 @@ END IDD_RESTARTPAGE DIALOGEX 0, 0, 317, 193 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU -CAPTION "Expert de instalare ReactOS" +CAPTION "Se finalizează instalarea ReactOS" FONT 8, "MS Shell Dlg" BEGIN - LTEXT "Finalizarea instalării asistate a ReactOS", IDC_FINISHTITLE, 115, 8, 195, 24 - LTEXT "Ați dus la bun sfârșit prima etapă de instalare a ReactOS.", IDC_STATIC, 115, 50, 195, 17 - LTEXT "Când veți apăsa Sfârșit, calculatorul va reporni.", IDC_STATIC, 115, 80, 195, 17 + LTEXT "Se finalizează expertul de instalare ReactOS", IDC_FINISHTITLE, 115, 8, 195, 24 + LTEXT "Ați finalizat cu succes prima etapă a instalării ReactOS.", IDC_STATIC, 115, 50, 195, 17 + LTEXT "Când veți apăsa Terminare, calculatorul va reporni.", IDC_STATIC, 115, 80, 195, 17 CONTROL "", IDC_RESTART_PROGRESS, "msctls_progress32", PBS_SMOOTH | WS_CHILD | WS_VISIBLE | WS_BORDER, 115, 110, 195, 8 - LTEXT "Dacă aveți vreun CD în calculator, scoateți-l, după care apăsați Sfârșit pentru a reporni.", IDC_STATIC, 115, 169, 195, 17 + LTEXT "Dacă există un CD într-o unitate, scoateți-l. Apoi, pentru a reporni computerul, faceți clic pe Terminare.", IDC_STATIC, 115, 169, 195, 17 END /* Strings */ @@ -170,30 +179,32 @@ END STRINGTABLE BEGIN IDS_CAPTION "Expertul de instalare ReactOS" - IDS_TYPETITLE "Bun venit la instalarea ReactOS" - IDS_TYPESUBTITLE "Alegeți tipul de instalare." - IDS_DEVICETITLE "Instalare dispozitive de bază" - IDS_DEVICESUBTITLE "Stabilirea parametrilor de afișare și tastatură." - IDS_DRIVETITLE "Stabilirea destinației" - IDS_DRIVESUBTITLE "Pregătirea partiției de instalare, a folderului de sistem și a inițializatorului." - IDS_SUMMARYTITLE "Rezumat de instalare" - IDS_SUMMARYSUBTITLE "Lista cu opțiuni de instalare ce necesită verificare înainte de a continua instalarea." - IDS_PROCESSTITLE "Executare pași de instalare" - IDS_PROCESSSUBTITLE "Crearea și formatarea partiției, copierea de fișiere și instalarea inițializatorului." - IDS_RESTARTTITLE "Finalizare primă etapă" - IDS_RESTARTSUBTITLE "Prima etapă a instalarii a fost încheiată cu succes, reporniți pentru a doua etapă." - IDS_ABORTSETUP "ReactOS încă nu este complet instalat în calculator. Daca întrerupeți procesul de instalare, pentru a instala va fi necesară repetarea pașilor parcurși până acum. Sigur doriți asta?" - IDS_ABORTSETUP2 "Abandonați instalarea?" - IDS_NO_TXTSETUP_SIF "Fișierului „txtsetup.sif” nu poate fi găsit.\nInstalarea nu poate continua." - IDS_INSTALLBTN "&Install" - IDS_VOLUME_NOFORMAT "Not formatted" + IDS_TYPETITLE "Tipul de instalare" + IDS_TYPESUBTITLE "Puteți configura o nouă instalare ReactOS sau puteți actualiza/repara o instalare existentă." + IDS_UPDATETITLE "Actualizare sau reparare ReactOS" + IDS_UPDATESUBTITLE "Alegeți instalarea existentă ReactOS pe care doriți să o actualizați sau să reparați." + IDS_DEVICETITLE "Configurare a dispozitivelor de bază" + IDS_DEVICESUBTITLE "Setați setările pentru afișaj și tastatură." + IDS_DRIVETITLE "Configurați partiția de instalare și folderul de sistem" + IDS_DRIVESUBTITLE "Se pregătește instalarea partiției, a folderului de sistem și a încărcătorului de pornire." + IDS_SUMMARYTITLE "Rezumatul instalării" + IDS_SUMMARYSUBTITLE "Listează proprietățile de instalare de verificat înainte de le a aplica dispozitivului de instalare." + IDS_PROCESSTITLE "Se configurează partiția, se copiază fișierele și se configurează sistemul" + IDS_PROCESSSUBTITLE "Crează sau formatează partiția, copiază fișierele, instalează și configurează bootloader-ul" + IDS_RESTARTTITLE "Prima etapă de configurare s-a încheiat" + IDS_RESTARTSUBTITLE "Prima etapă de configurare s-a încheiat, reporniți pentru a continua cu a doua etapă." + IDS_ABORTSETUP "ReactOS nu este isntalat complet în computer. Dacă părăsiți Instalatorul acum, va trebui să rulați din nou Instalatorul pentru a instala ReactOS. Chiar renunțați?" + IDS_ABORTSETUP2 "Renunțați la instalare?" + IDS_NO_TXTSETUP_SIF "Nu s-a putut găsi 'txtsetup.sif'.\nInstalatorul nu poate continua." + IDS_INSTALLBTN "&Instalare" + IDS_VOLUME_NOFORMAT "Neformatat" END STRINGTABLE BEGIN IDS_INSTALLATION_NAME "Nume" - IDS_INSTALLATION_PATH "Cale de instalare" - IDS_INSTALLATION_VENDOR "Nume de producător" + IDS_INSTALLATION_PATH "Calea de instalare" + IDS_INSTALLATION_VENDOR "Numele producătorului" END STRINGTABLE @@ -206,10 +217,10 @@ END STRINGTABLE BEGIN - IDS_BOOTLOADER_NOINST "No installation" - IDS_BOOTLOADER_REMOVABLE "Removable media" - IDS_BOOTLOADER_SYSTEM "System partition (Default)" - IDS_BOOTLOADER_MBRVBR "MBR și VBR (Default)" + IDS_BOOTLOADER_NOINST "Nicio instalare" + IDS_BOOTLOADER_REMOVABLE "Suport media amovibil" + IDS_BOOTLOADER_SYSTEM "Partiție de sistem (Implicită)" + IDS_BOOTLOADER_MBRVBR "MBR și VBR (Implicit)" IDS_BOOTLOADER_VBRONLY "Numai VBR" END @@ -217,88 +228,88 @@ END STRINGTABLE BEGIN - IDS_FORMATTING_PROGRESS1 "Formatting volume %c: (%s) in %s..." - IDS_FORMATTING_PROGRESS2 "Formatting volume %s in %s..." + IDS_FORMATTING_PROGRESS1 "Se formatează volumul %c: (%s) în %s..." + IDS_FORMATTING_PROGRESS2 "Se formatează volumul %s în %s..." - IDS_CHECKING_PROGRESS1 "Checking volume %c: (%s)..." - IDS_CHECKING_PROGRESS2 "Checking volume %s..." + IDS_CHECKING_PROGRESS1 "Se verifică volumul %c: (%s)..." + IDS_CHECKING_PROGRESS2 "Se verifică volumul %s..." - IDS_COPYING "Copying %s" - IDS_MOVING "Moving %s to %s" - IDS_RENAMING "Renaming %s to %s" - IDS_DELETING "Deleting %s" + IDS_COPYING "Se copiază %s" + IDS_MOVING "Se mută %s în %s" + IDS_RENAMING "Se redenumește din %s în %s" + IDS_DELETING "Se șterge %s" - IDS_CONFIG_SYSTEM_PARTITION "Configuring the system partition..." - IDS_PREPARE_PARTITIONS "Preparing partitions..." - IDS_PREPARE_FILES "Preparing the list of files to be copied, please wait..." - IDS_COPYING_FILES "Copying the files..." + IDS_CONFIG_SYSTEM_PARTITION "Se configurează partiția de sistem..." + IDS_PREPARE_PARTITIONS "Se pregătesc partițiile..." + IDS_PREPARE_FILES "Se pregătește lista fișierelor ce urmează să fie copiate, așteptați..." + IDS_COPYING_FILES "Se copiază fișierele..." - IDS_CREATE_REGISTRY "Creating the registry..." - IDS_UPDATE_REGISTRY "Updating the registry..." + IDS_CREATE_REGISTRY "Se crează registrul..." + IDS_UPDATE_REGISTRY "Se actualizează registrul..." - // IDS_INSTALL_FINALIZE "Finalizing the installation..." - IDS_INSTALL_BOOTLOADER "Installing the bootloader..." + // IDS_INSTALL_FINALIZE "Se finalizează instalația..." + IDS_INSTALL_BOOTLOADER "Se instalează bootloader-ul..." END // Note to translators: please refer to the corresponding usetup/lang/*.h translations. STRINGTABLE BEGIN - IDS_REG_DONE "Done" - IDS_REG_REGHIVEUPDATE "Updating registry hives" - IDS_REG_IMPORTFILE "Importing %s" - IDS_REG_DISPLAYSETTINGSUPDATE "Updating display registry settings" - IDS_REG_LOCALESETTINGSUPDATE "Updating locale settings" - IDS_REG_ADDKBLAYOUTS "Adding keyboard layouts" - IDS_REG_KEYBOARDSETTINGSUPDATE "Updating keyboard layout settings" - IDS_REG_CODEPAGEINFOUPDATE "Adding codepage information" - IDS_REG_UNKNOWN "Unknown status %d" + IDS_REG_DONE "Gata" + IDS_REG_REGHIVEUPDATE "Se actualizează intrările de registru" + IDS_REG_IMPORTFILE "Se importă %s" + IDS_REG_DISPLAYSETTINGSUPDATE "Se actualizează setările registrului de afișare" + IDS_REG_LOCALESETTINGSUPDATE "Se actualizează setările de localizare" + IDS_REG_ADDKBLAYOUTS "Se adaugă limbi pentru tastatură" + IDS_REG_KEYBOARDSETTINGSUPDATE "Se actualizează setările pentru limbilor pentru tastatură" + IDS_REG_CODEPAGEINFOUPDATE "Se adaugă informațiile din pagina de coduri" + IDS_REG_UNKNOWN "Stare necunoscută %d" END /* Error Strings */ STRINGTABLE BEGIN - IDS_ERROR_INVALID_INSTALLDIR_CHAR_TITLE "Invalid character" - IDS_ERROR_INVALID_INSTALLDIR_CHAR "The only valid characters are:\n\ -alphanumericals (a-z, A-Z, 0-9), and\n . \\ - _\n\ -Spaces are not allowed." + IDS_ERROR_INVALID_INSTALLDIR_CHAR_TITLE "Caracter nevalid" + IDS_ERROR_INVALID_INSTALLDIR_CHAR "Singuirele caractere valide sunt:\n\ +alfanumerice (a-z, A-Z, 0-9) și\n . \\ - _\n\ +Spațiile nu sunt permise." - IDS_ERROR_DIRECTORY_NAME_TITLE "Invalid installation path" - IDS_ERROR_DIRECTORY_NAME "The ReactOS installation path must follow the DOS 8.3 naming scheme, \ -and only contain letters, digits, dashes and periods. Spaces are not allowed." + IDS_ERROR_DIRECTORY_NAME_TITLE "Calea instalării nu e validă" + IDS_ERROR_DIRECTORY_NAME "Calea de isntalare ReactOS trebuie să urmeze schema de denumire DOS 8.3 \ +și să conțină numai litere, cifre, liniuțe și puncte. Spațiile nu sunt permise." - IDS_ERROR_CREATE_PARTITION_TITLE "Create partition" - IDS_ERROR_CREATE_PARTITION "Failed to create a new partition." + IDS_ERROR_CREATE_PARTITION_TITLE "Crearea partiției" + IDS_ERROR_CREATE_PARTITION "Imposibil de creat noua partiție." - IDS_WARN_DELETE_PARTITION_TITLE "Delete partition?" - IDS_WARN_DELETE_PARTITION "Are you sure you want to delete the selected partition?" - IDS_WARN_DELETE_MBR_EXTENDED_PARTITION "Are you sure you want to delete the selected extended partition and ALL the logical partitions it contains?" + IDS_WARN_DELETE_PARTITION_TITLE "Ștergeți partiția?" + IDS_WARN_DELETE_PARTITION "Sigur vreți să ștergeți partiția selectată?" + IDS_WARN_DELETE_MBR_EXTENDED_PARTITION "Sigur vreți să ștergeți partiția selectată extinsă și TOATE partițiile logice pe care le conține?" - IDS_ERROR_WRITE_PTABLE "Setup failed to write partition tables." + IDS_ERROR_WRITE_PTABLE "Instalatorul a eșuat să scrie tabelele de partiții." - IDS_ERROR_SYSTEM_PARTITION "The ReactOS Setup could not find a supported system partition\n\ -on your system or could not create a new one. Without such a partition\n\ -the Setup program cannot install ReactOS.\ -\nClick on OK to return to the partition selection list." + IDS_ERROR_SYSTEM_PARTITION "Instalatorul ReactOS nu a putut găsi o partiție de sistem acceptată\n\ +pe sistem sau nu a putut crea unul nou. Fără o astfel de partiție\n\ +programul de instalare nu poate instala ReactOS.\ +\nApăsați OK pentru a reveni la lista de selecție a partițiilor." - IDS_ERROR_FORMAT_UNRECOGNIZED_VOLUME "Unrecognized volume while attempting to format the partition." + IDS_ERROR_FORMAT_UNRECOGNIZED_VOLUME "Volum necunoscut în timpul încercării de a formata partiția." - IDS_ERROR_COULD_NOT_FORMAT "Setup is currently unable to format a partition in %s.\n\ -\nClick on OK to continue Setup.\ -\nClick on CANCEL to quit Setup." + IDS_ERROR_COULD_NOT_FORMAT "Instalatorul nu poate în prezent, să formateze o partiție în %s.\n\ +\nApăsați pe OK pentru a continua configurarea.\ +\nApăsați pe REVOCARE pentru a ieși din Instalator." - IDS_ERROR_FORMATTING_PARTITION "Setup is unable to format the partition:\n %s\n" + IDS_ERROR_FORMATTING_PARTITION "Instalatorul nu poate formata partiția:\n %s\n" - IDS_ERROR_COULD_NOT_CHECK "Setup is currently unable to check a partition formatted in %s.\n\ -\nClick on OK to continue Setup.\ -\nClick on CANCEL to quit Setup." + IDS_ERROR_COULD_NOT_CHECK "În prezent, Instalatorul nu poate verifica o partiție formatată în %s.\n\ +\nApăsați pe OK pentru a continua configurarea.\ +\nApăsați pe REVOCARE pentru a ieși din Instalator." - IDS_ERROR_CHECKING_PARTITION "ChkDsk detected some disk errors.\n(Status 0x%08lx)." + IDS_ERROR_CHECKING_PARTITION "ChkDsk a detectat niște erori de disc.\n(Statutul 0x%08lx)." - IDS_ERROR_WRITE_BOOT "Setup failed to install the %s bootcode on the system partition." - IDS_ERROR_INSTALL_BOOTCODE "Setup failed to install the %s bootcode on the boot disk." - IDS_ERROR_INSTALL_BOOTCODE_REMOVABLE "Setup failed to install the bootcode on the removable media." - IDS_ERROR_BOOTLDR_ARCH_UNSUPPORTED "Setup does not currently support installing the bootloader on the computer you are using.\ -\nClick on OK to continue anyway." - IDS_ERROR_BOOTLDR_FAILED "Setup could not install the bootloader (Status 0x%08lx)." + IDS_ERROR_WRITE_BOOT "Instalatorul nu a reușit să instaleze codul de pornire %s pe partiția de sistem." + IDS_ERROR_INSTALL_BOOTCODE "Instalatorul nu a reușit să instaleze codul de pornire %s pe discul de pornire." + IDS_ERROR_INSTALL_BOOTCODE_REMOVABLE "Instalatorul nu a reușit să instaleze codul de pornire pe suportul amovibil." + IDS_ERROR_BOOTLDR_ARCH_UNSUPPORTED "În prezent, Instalatorul nu a reușit să instaleze codul de pornire pe computerul pe care îl folosiți.\ +\nApăsați pe OK pentru a continua oricum." + IDS_ERROR_BOOTLDR_FAILED "Instalatorul nu a putut instala bootloader-ul (Statutul 0x%08lx)." END diff --git a/base/setup/reactos/lang/ru-RU.rc b/base/setup/reactos/lang/ru-RU.rc index eacc18ce39d0a..def56ff609d24 100644 --- a/base/setup/reactos/lang/ru-RU.rc +++ b/base/setup/reactos/lang/ru-RU.rc @@ -8,8 +8,18 @@ CAPTION "Установка ReactOS" FONT 8, "MS Shell Dlg" BEGIN LTEXT "Вас приветствует программа установки ReactOS", IDC_STARTTITLE, 115, 8, 195, 24 - LTEXT "Установку ReactOS можно производить только загрузившись с этого диска! После перезапуска компьютера выберите загрузку с CD и начните установку ReactOS.", IDC_STATIC, 115, 40, 195, 100 - LTEXT "Нажмите кнопку ""Завершить"" для выхода.", IDC_STATIC, 115, 169, 195, 17 + LTEXT "This wizard will install or upgrade ReactOS on your computer, \ +and prepare the second part of the setup.", IDC_STATIC, 115, 40, 195, 27 +//// + GROUPBOX " IMPORTANT INFORMATION ", IDC_WARNTEXT1, 115, 70, 195, 90, BS_CENTER + LTEXT "ReactOS is in Alpha stage: it is not feature- complete and is \ +under heavy development. It is recommended to use it only for \ +evaluation and testing and not as your daily-usage OS.\n\ +It may corrupt your data or damage your hardware.", IDC_WARNTEXT2, 120, 80, 185, 50, SS_CENTER + LTEXT "Backup your data or test on a secondary computer \ +if you attempt to run ReactOS on real hardware.", IDC_WARNTEXT3, 120, 130, 185, 27, SS_CENTER +//// + LTEXT "Нажмите ""Далее"" для продолжения установки.", IDC_STATIC, 115, 169, 195, 17 END IDD_TYPEPAGE DIALOGEX 0, 0, 317, 143 @@ -17,11 +27,10 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "Установка ReactOS" FONT 8, "MS Shell Dlg" BEGIN - AUTORADIOBUTTON "Установка ReactOS", IDC_INSTALL, 7, 7, 277, 10, WS_GROUP | WS_TABSTOP - LTEXT "Установить новую копию системы ReactOS. Эта опция НЕ сохраняет файлы, настройки и программы. Вы можете изменять диски и разделы.", IDC_INSTALLTEXT, 18, 18, 269, 25, NOT WS_GROUP - AUTORADIOBUTTON "Восстановить или изменить установленный ранее ReactOS", IDC_UPDATE, 7, 50, 277, 10 - LTEXT "Обновить или восстановить установленную копию системы ReactOS. Эта опция СОХРАНЯЕТ файлы, настройки и программы. Доступно только при наличии уже установленной на компьютере системы ReactOS.", IDC_UPDATETEXT, 18, 61, 269, 30, NOT WS_GROUP - LTEXT "Для установки устройств нажмите ""Далее"".", IDC_STATIC, 7, 128, 297, 8 + AUTORADIOBUTTON "&Установка ReactOS", IDC_INSTALL, 7, 20, 277, 10, WS_GROUP | WS_TABSTOP + LTEXT "Установить новую копию системы ReactOS. Эта опция НЕ сохраняет файлы, настройки и программы. Вы можете изменять диски и разделы.", IDC_INSTALLTEXT, 19, 36, 279, 27, NOT WS_GROUP + AUTORADIOBUTTON "&Восстановить или изменить ReactOS", IDC_UPDATE, 7, 80, 277, 10 + LTEXT "Обновить или восстановить установленную копию системы ReactOS. Эта опция СОХРАНЯЕТ файлы, настройки и программы. Доступно только при наличии уже установленной на компьютере системы ReactOS.", IDC_UPDATETEXT, 19, 96, 279, 27, NOT WS_GROUP END IDD_UPDATEREPAIRPAGE DIALOGEX 0, 0, 317, 143 @@ -161,8 +170,10 @@ END STRINGTABLE BEGIN IDS_CAPTION "Установка ReactOS" - IDS_TYPETITLE "Вас приветствует программа установки ReactOS" - IDS_TYPESUBTITLE "Выберите тип установки." + IDS_TYPETITLE "Installation Type" + IDS_TYPESUBTITLE "You can setup a new ReactOS installation, or update/repair an existing installation." + IDS_UPDATETITLE "Update or Repair ReactOS" + IDS_UPDATESUBTITLE "Choose which existing ReactOS installation you want to update or repair." IDS_DEVICETITLE "Установка базовых устройств" IDS_DEVICESUBTITLE "Настройка параметров экрана и клавиатуры." IDS_DRIVETITLE "Выбор расположения на диске и системного каталога" diff --git a/base/setup/reactos/lang/sk-SK.rc b/base/setup/reactos/lang/sk-SK.rc index d94b765f18802..17364520feed9 100644 --- a/base/setup/reactos/lang/sk-SK.rc +++ b/base/setup/reactos/lang/sk-SK.rc @@ -13,8 +13,18 @@ CAPTION "Inštalácia systému ReactOS" //ReactOS Setup FONT 8, "MS Shell Dlg" BEGIN LTEXT "Víta Vás sprievodca inštaláciou systému ReactOS", IDC_STARTTITLE, 115, 8, 195, 24 - LTEXT "Systém ReactOS sa z tohto CD nedá nainštalovať ihneď! Reštartujte, prosím, počítač a inštalačné CD nechajte vložené, aby sa mohol systém ReactOS nainštalovať.", IDC_STATIC, 115, 40, 195, 100 - LTEXT "Inštaláciu ukončíte kliknutím na tlačidlo Dokončiť.", IDC_STATIC, 115, 169, 195, 17 + LTEXT "This wizard will install or upgrade ReactOS on your computer, \ +and prepare the second part of the setup.", IDC_STATIC, 115, 40, 195, 27 +//// + GROUPBOX " IMPORTANT INFORMATION ", IDC_WARNTEXT1, 115, 70, 195, 90, BS_CENTER + LTEXT "ReactOS is in Alpha stage: it is not feature- complete and is \ +under heavy development. It is recommended to use it only for \ +evaluation and testing and not as your daily-usage OS.\n\ +It may corrupt your data or damage your hardware.", IDC_WARNTEXT2, 120, 80, 185, 50, SS_CENTER + LTEXT "Backup your data or test on a secondary computer \ +if you attempt to run ReactOS on real hardware.", IDC_WARNTEXT3, 120, 130, 185, 27, SS_CENTER +//// + LTEXT "Kliknutím na Ďalej pokračujte v inštalácii.", IDC_STATIC, 115, 169, 195, 17 END IDD_TYPEPAGE DIALOGEX 0, 0, 317, 143 @@ -22,11 +32,10 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "Inštalácia systému ReactOS" FONT 8, "MS Shell Dlg" BEGIN - AUTORADIOBUTTON "Nainštalovať systém ReactOS", IDC_INSTALL, 7, 7, 277, 10, WS_GROUP | WS_TABSTOP - LTEXT "Install a new copy of ReactOS. This option does not keep your files, settings and programs. You can make changes to disks and partitions.", IDC_INSTALLTEXT, 18, 18, 269, 25, NOT WS_GROUP - AUTORADIOBUTTON "Opraviť alebo aktualizovať nainštalovaný systém ReactOS", IDC_UPDATE, 7, 50, 277, 10 - LTEXT "Update or repair an installed copy of ReactOS. This option keeps your files, settings and programs. This option is only available if ReactOS is already installed on this computer.", IDC_UPDATETEXT, 18, 61, 269, 30, NOT WS_GROUP - LTEXT "Click Next to setup the devices.", IDC_STATIC, 7, 128, 297, 8 + AUTORADIOBUTTON "&Nainštalovať systém ReactOS", IDC_INSTALL, 7, 20, 277, 10, WS_GROUP | WS_TABSTOP + LTEXT "Install a new copy of ReactOS. This option does not keep your files, settings and programs. You can make changes to disks and partitions.", IDC_INSTALLTEXT, 19, 36, 279, 27, NOT WS_GROUP + AUTORADIOBUTTON "&Opraviť alebo aktualizovať systém ReactOS", IDC_UPDATE, 7, 80, 277, 10 + LTEXT "Update or repair an installed copy of ReactOS. This option keeps your files, settings and programs. This option is only available if ReactOS is already installed on this computer.", IDC_UPDATETEXT, 19, 96, 279, 27, NOT WS_GROUP END IDD_UPDATEREPAIRPAGE DIALOGEX 0, 0, 317, 143 @@ -166,8 +175,10 @@ END STRINGTABLE BEGIN IDS_CAPTION "ReactOS Setup" - IDS_TYPETITLE "Víta Vás inštalátor systému ReactOS" //Welcome to ReactOS Setup - IDS_TYPESUBTITLE "Choose setup type." + IDS_TYPETITLE "Installation Type" + IDS_TYPESUBTITLE "You can setup a new ReactOS installation, or update/repair an existing installation." + IDS_UPDATETITLE "Update or Repair ReactOS" + IDS_UPDATESUBTITLE "Choose which existing ReactOS installation you want to update or repair." IDS_DEVICETITLE "Setup the basic devices" IDS_DEVICESUBTITLE "Set the settings of display and keyboard." IDS_DRIVETITLE "Setup the installation partition and system folder" diff --git a/base/setup/reactos/lang/sq-AL.rc b/base/setup/reactos/lang/sq-AL.rc index 99b09a3d02c21..d95ccc4a9cd0f 100644 --- a/base/setup/reactos/lang/sq-AL.rc +++ b/base/setup/reactos/lang/sq-AL.rc @@ -10,8 +10,18 @@ CAPTION "Instalimi i ReactOS" FONT 8, "MS Shell Dlg" BEGIN LTEXT "Mirë se vini në instalimin e ReactOS", IDC_STARTTITLE, 115, 8, 195, 24 - LTEXT "Ju nuk mund të instaloni ReactOS direkt nga ky CD! Ju lutem rinisni kompjuterin tuaj nga CD'ja në mënyrë që të instaloni ReactOS.", IDC_STATIC, 115, 40, 195, 100 - LTEXT "Kliko Finish për të dalë nga instalimi.", IDC_STATIC, 115, 169, 195, 17 + LTEXT "This wizard will install or upgrade ReactOS on your computer, \ +and prepare the second part of the setup.", IDC_STATIC, 115, 40, 195, 27 +//// + GROUPBOX " IMPORTANT INFORMATION ", IDC_WARNTEXT1, 115, 70, 195, 90, BS_CENTER + LTEXT "ReactOS is in Alpha stage: it is not feature- complete and is \ +under heavy development. It is recommended to use it only for \ +evaluation and testing and not as your daily-usage OS.\n\ +It may corrupt your data or damage your hardware.", IDC_WARNTEXT2, 120, 80, 185, 50, SS_CENTER + LTEXT "Backup your data or test on a secondary computer \ +if you attempt to run ReactOS on real hardware.", IDC_WARNTEXT3, 120, 130, 185, 27, SS_CENTER +//// + LTEXT "Klikoni Tjetër për të vazhduar me Ndërtimin.", IDC_STATIC, 115, 169, 195, 17 END IDD_TYPEPAGE DIALOGEX 0, 0, 317, 143 @@ -19,11 +29,10 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "Instalimi i ReactOS" FONT 8, "MS Shell Dlg" BEGIN - AUTORADIOBUTTON "InstalO ReactOS", IDC_INSTALL, 7, 7, 277, 10, WS_GROUP | WS_TABSTOP - LTEXT "Install a new copy of ReactOS. This option does not keep your files, settings and programs. You can make changes to disks and partitions.", IDC_INSTALLTEXT, 18, 18, 269, 25, NOT WS_GROUP - AUTORADIOBUTTON "Riparo ose apdejto ReactOS'in e instaluar", IDC_UPDATE, 7, 50, 277, 10 - LTEXT "Update or repair an installed copy of ReactOS. This option keeps your files, settings and programs. This option is only available if ReactOS is already installed on this computer.", IDC_UPDATETEXT, 18, 61, 269, 30, NOT WS_GROUP - LTEXT "Kliko vazhdo për të konfiguruar pajisjet.", IDC_STATIC, 7, 128, 297, 8 + AUTORADIOBUTTON "&Instalo ReactOS", IDC_INSTALL, 7, 20, 277, 10, WS_GROUP | WS_TABSTOP + LTEXT "Install a new copy of ReactOS. This option does not keep your files, settings and programs. You can make changes to disks and partitions.", IDC_INSTALLTEXT, 19, 36, 279, 27, NOT WS_GROUP + AUTORADIOBUTTON "&Riparo ose apdejto ReactOS", IDC_UPDATE, 7, 80, 277, 10 + LTEXT "Update or repair an installed copy of ReactOS. This option keeps your files, settings and programs. This option is only available if ReactOS is already installed on this computer.", IDC_UPDATETEXT, 19, 96, 279, 27, NOT WS_GROUP END IDD_UPDATEREPAIRPAGE DIALOGEX 0, 0, 317, 143 @@ -163,8 +172,10 @@ END STRINGTABLE BEGIN IDS_CAPTION "ReactOS Setup" - IDS_TYPETITLE "Mirë se vini në instalimin e ReactOS" - IDS_TYPESUBTITLE "Zgjidhni llojin e instalimit." + IDS_TYPETITLE "Installation Type" + IDS_TYPESUBTITLE "You can setup a new ReactOS installation, or update/repair an existing installation." + IDS_UPDATETITLE "Update or Repair ReactOS" + IDS_UPDATESUBTITLE "Choose which existing ReactOS installation you want to update or repair." IDS_DEVICETITLE "Instaloni pajisjet themelore" IDS_DEVICESUBTITLE "Vendos parametrat e ekranit dhe tastieres." IDS_DRIVETITLE "Konfiguro particionet për instalim dhe dosjet e sistemit" diff --git a/base/setup/reactos/lang/tr-TR.rc b/base/setup/reactos/lang/tr-TR.rc index 3cba7f7a35f5c..797e0dae23a28 100644 --- a/base/setup/reactos/lang/tr-TR.rc +++ b/base/setup/reactos/lang/tr-TR.rc @@ -14,9 +14,19 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "ReactOS Kur" FONT 8, "MS Shell Dlg" BEGIN - LTEXT "ReactOS Kur Sihirbazına'na Hoş Geldiniz", IDC_STARTTITLE, 115, 8, 195, 24 - LTEXT "Bu CD'den, henüz ReactOS'u doğrudan kuramazsınız. Lütfen ReactOS'u kurmak için bu CD'den bilgisayarınızı yeniden başlatınız.", IDC_STATIC, 115, 40, 195, 100 - LTEXT "Kurulumdan çıkmak için İptal'e tıklayınız.", IDC_STATIC, 115, 169, 195, 17 + LTEXT "ReactOS Kurulum Sihirbazı'na hoşgeldiniz", IDC_STARTTITLE, 115, 8, 195, 24 + LTEXT "This wizard will install or upgrade ReactOS on your computer, \ +and prepare the second part of the setup.", IDC_STATIC, 115, 40, 195, 27 +//// + GROUPBOX " IMPORTANT INFORMATION ", IDC_WARNTEXT1, 115, 70, 195, 90, BS_CENTER + LTEXT "ReactOS is in Alpha stage: it is not feature- complete and is \ +under heavy development. It is recommended to use it only for \ +evaluation and testing and not as your daily-usage OS.\n\ +It may corrupt your data or damage your hardware.", IDC_WARNTEXT2, 120, 80, 185, 50, SS_CENTER + LTEXT "Backup your data or test on a secondary computer \ +if you attempt to run ReactOS on real hardware.", IDC_WARNTEXT3, 120, 130, 185, 27, SS_CENTER +//// + LTEXT "Kuruluma devam etmek için İleri'ye tıklayınız.", IDC_STATIC, 115, 169, 195, 17 END IDD_TYPEPAGE DIALOGEX 0, 0, 317, 143 @@ -24,11 +34,10 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "ReactOS Kur" FONT 8, "MS Shell Dlg" BEGIN - AUTORADIOBUTTON "ReactOS'u Yükleme", IDC_INSTALL, 7, 7, 277, 10, WS_GROUP | WS_TABSTOP - LTEXT "ReactOS'un yeni bir kopyasını yükle. Bu seçenek, dosyalarınızı, ayarlarınızı ve programlarınızı korumaz. Disklere ve bölümlere değişiklikler yapabilirsiniz.", IDC_INSTALLTEXT, 18, 18, 269, 25, NOT WS_GROUP - AUTORADIOBUTTON "Kurulu ReactOS'u Onarma ya da Yükseltme", IDC_UPDATE, 7, 50, 277, 10 - LTEXT "Kurulu olan ReactOS'un günceller ya da onarır. Bu seçenek, dosyalarınızı, ayarlarınızı ve programlarınızı korur. Bu seçenek yalnızca ReactOS bu bilgisayarda önceden kuruluysa kullanılabilir.", IDC_UPDATETEXT, 18, 61, 269, 30, NOT WS_GROUP - LTEXT "Aygıtları kurmak için İleri'ye tıklayınız.", IDC_STATIC, 7, 128, 297, 8 + AUTORADIOBUTTON "ReactOS'u &Yükleme", IDC_INSTALL, 7, 20, 277, 10, WS_GROUP | WS_TABSTOP + LTEXT "ReactOS'un yeni bir kopyasını yükle. Bu seçenek, dosyalarınızı, ayarlarınızı ve programlarınızı korumaz. Disklere ve bölümlere değişiklikler yapabilirsiniz.", IDC_INSTALLTEXT, 19, 36, 279, 27, NOT WS_GROUP + AUTORADIOBUTTON "ReactOS'u &Onarma ya da Yükseltme", IDC_UPDATE, 7, 80, 277, 10 + LTEXT "Kurulu olan ReactOS'un günceller ya da onarır. Bu seçenek, dosyalarınızı, ayarlarınızı ve programlarınızı korur. Bu seçenek yalnızca ReactOS bu bilgisayarda önceden kuruluysa kullanılabilir.", IDC_UPDATETEXT, 19, 96, 279, 27, NOT WS_GROUP END IDD_UPDATEREPAIRPAGE DIALOGEX 0, 0, 317, 143 @@ -168,8 +177,10 @@ END STRINGTABLE BEGIN IDS_CAPTION "ReactOS Kur" - IDS_TYPETITLE "ReactOS Kurulum Yöneticisine Hoş Geldiniz" - IDS_TYPESUBTITLE "Kurulum türünü seçiniz." + IDS_TYPETITLE "Installation Type" + IDS_TYPESUBTITLE "You can setup a new ReactOS installation, or update/repair an existing installation." + IDS_UPDATETITLE "Update or Repair ReactOS" + IDS_UPDATESUBTITLE "Choose which existing ReactOS installation you want to update or repair." IDS_DEVICETITLE "Ana Aygıtların Kurulumu" IDS_DEVICESUBTITLE "Ekran ve Klavye ayarlarını yapınız." IDS_DRIVETITLE "Kurulum Bölümünün ve Sistem Dizininin Hazırlanması" diff --git a/base/setup/reactos/lang/uk-UA.rc b/base/setup/reactos/lang/uk-UA.rc index 3ddeee167a261..8fe8483a95b41 100644 --- a/base/setup/reactos/lang/uk-UA.rc +++ b/base/setup/reactos/lang/uk-UA.rc @@ -16,8 +16,18 @@ CAPTION "Встановлення ReactOS" FONT 8, "MS Shell Dlg" BEGIN LTEXT "Вас вітає програма встановлення ReactOS", IDC_STARTTITLE, 115, 8, 195, 24 - LTEXT "Ви не можете встановити ReactOS прямо з цього CD! Будь ласка перезапустіть Ваш комп’ютер з цього CD для того, щоб встановити ReactOS.", IDC_STATIC, 115, 40, 195, 100 - LTEXT "Натисніть кнопку Завершити для виходу.", IDC_STATIC, 115, 169, 195, 17 + LTEXT "This wizard will install or upgrade ReactOS on your computer, \ +and prepare the second part of the setup.", IDC_STATIC, 115, 40, 195, 27 +//// + GROUPBOX " IMPORTANT INFORMATION ", IDC_WARNTEXT1, 115, 70, 195, 90, BS_CENTER + LTEXT "ReactOS is in Alpha stage: it is not feature- complete and is \ +under heavy development. It is recommended to use it only for \ +evaluation and testing and not as your daily-usage OS.\n\ +It may corrupt your data or damage your hardware.", IDC_WARNTEXT2, 120, 80, 185, 50, SS_CENTER + LTEXT "Backup your data or test on a secondary computer \ +if you attempt to run ReactOS on real hardware.", IDC_WARNTEXT3, 120, 130, 185, 27, SS_CENTER +//// + LTEXT "Натисніть ""Далі"", щоб продовжити встановлення.", IDC_STATIC, 115, 169, 195, 17 END IDD_TYPEPAGE DIALOGEX 0, 0, 317, 143 @@ -25,11 +35,10 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "Встановлення ReactOS" FONT 8, "MS Shell Dlg" BEGIN - AUTORADIOBUTTON "Встановлення ReactOS", IDC_INSTALL, 7, 7, 277, 10, WS_GROUP | WS_TABSTOP - LTEXT "Install a new copy of ReactOS. This option does not keep your files, settings and programs. You can make changes to disks and partitions.", IDC_INSTALLTEXT, 18, 18, 269, 25, NOT WS_GROUP - AUTORADIOBUTTON "Відновити або змінити встановлений раніше ReactOS", IDC_UPDATE, 7, 50, 277, 10 - LTEXT "Update or repair an installed copy of ReactOS. This option keeps your files, settings and programs. This option is only available if ReactOS is already installed on this computer.", IDC_UPDATETEXT, 18, 61, 269, 30, NOT WS_GROUP - LTEXT "Для встановлення пристроїв натисніть Далі.", IDC_STATIC, 7, 128, 297, 8 + AUTORADIOBUTTON "&Встановлення ReactOS", IDC_INSTALL, 7, 20, 277, 10, WS_GROUP | WS_TABSTOP + LTEXT "Install a new copy of ReactOS. This option does not keep your files, settings and programs. You can make changes to disks and partitions.", IDC_INSTALLTEXT, 19, 36, 279, 27, NOT WS_GROUP + AUTORADIOBUTTON "В&ідновити або змінити ReactOS", IDC_UPDATE, 7, 80, 277, 10 + LTEXT "Update or repair an installed copy of ReactOS. This option keeps your files, settings and programs. This option is only available if ReactOS is already installed on this computer.", IDC_UPDATETEXT, 19, 96, 279, 27, NOT WS_GROUP END IDD_UPDATEREPAIRPAGE DIALOGEX 0, 0, 317, 143 @@ -169,8 +178,10 @@ END STRINGTABLE BEGIN IDS_CAPTION "Встановлення ReactOS" - IDS_TYPETITLE "Вас вітає програма встановлення ReactOS" - IDS_TYPESUBTITLE "Виберіть тип встановлення." + IDS_TYPETITLE "Installation Type" + IDS_TYPESUBTITLE "You can setup a new ReactOS installation, or update/repair an existing installation." + IDS_UPDATETITLE "Update or Repair ReactOS" + IDS_UPDATESUBTITLE "Choose which existing ReactOS installation you want to update or repair." IDS_DEVICETITLE "Встановлення базових пристроїв" IDS_DEVICESUBTITLE "Налаштування параметрів екрану та клавіатури." IDS_DRIVETITLE "Вибір розташування на диску і системного каталогу" diff --git a/base/setup/reactos/lang/vi-VN.rc b/base/setup/reactos/lang/vi-VN.rc index b082e0e475f34..301192db9220d 100644 --- a/base/setup/reactos/lang/vi-VN.rc +++ b/base/setup/reactos/lang/vi-VN.rc @@ -8,8 +8,18 @@ CAPTION "Cài đặt ReactOS" FONT 8, "MS Shell Dlg" BEGIN LTEXT "Chào mừng đến với Trình hướng dẫn thiết lập ReactOS", IDC_STARTTITLE, 115, 8, 195, 24 - LTEXT "Bạn chưa thể cài đặt ReactOS trực tiếp tư đĩa CD này được! Xin hãy khởi động lại máy tính của bạn từ đĩa CD trên để cài đặt ReactOS.", IDC_STATIC, 115, 40, 195, 100 - LTEXT "Ấn Hoàn tất để thoát trình Thiết lập.", IDC_STATIC, 115, 169, 195, 17 + LTEXT "This wizard will install or upgrade ReactOS on your computer, \ +and prepare the second part of the setup.", IDC_STATIC, 115, 40, 195, 27 +//// + GROUPBOX " IMPORTANT INFORMATION ", IDC_WARNTEXT1, 115, 70, 195, 90, BS_CENTER + LTEXT "ReactOS is in Alpha stage: it is not feature- complete and is \ +under heavy development. It is recommended to use it only for \ +evaluation and testing and not as your daily-usage OS.\n\ +It may corrupt your data or damage your hardware.", IDC_WARNTEXT2, 120, 80, 185, 50, SS_CENTER + LTEXT "Backup your data or test on a secondary computer \ +if you attempt to run ReactOS on real hardware.", IDC_WARNTEXT3, 120, 130, 185, 27, SS_CENTER +//// + LTEXT "Click Next to continue with Setup.", IDC_STATIC, 115, 169, 195, 17 END IDD_TYPEPAGE DIALOGEX 0, 0, 317, 143 @@ -17,11 +27,10 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "Cài đặt ReactOS" FONT 8, "MS Shell Dlg" BEGIN - AUTORADIOBUTTON "Cài đặt ReactOS", IDC_INSTALL, 7, 7, 277, 10, WS_GROUP | WS_TABSTOP - LTEXT "Cài đặt một bản sao mới của ReactOS. Tùy chọn này sẽ không giữ lại các thư mục,tập tin và chương trình của bạn. Bạn có thể thực hiện những thay đổi cho các ổ đĩa và những phần phân chia trong ổ đĩa.", IDC_INSTALLTEXT, 18, 18, 269, 25, NOT WS_GROUP - AUTORADIOBUTTON "Cập nhật hay sửa chữa ReactOS", IDC_UPDATE, 7, 50, 277, 10 - LTEXT "Cập nhật hay sửa chữa một bản sao đã cài đặt của ReactOS. Tùy chọn này sẽ giữ lại các tập tin, cài đặt và chương trình của bạn. Tùy chọn này chỉ dùng được nếu ReactOS đã được cài đặt trên máy tinh này.", IDC_UPDATETEXT, 18, 61, 269, 30, NOT WS_GROUP - LTEXT "Ấn Tiếp để tiếp tục.", IDC_STATIC, 7, 128, 297, 8 + AUTORADIOBUTTON "&Cài đặt ReactOS", IDC_INSTALL, 7, 20, 277, 10, WS_GROUP | WS_TABSTOP + LTEXT "Cài đặt một bản sao mới của ReactOS. Tùy chọn này sẽ không giữ lại các thư mục,tập tin và chương trình của bạn. Bạn có thể thực hiện những thay đổi cho các ổ đĩa và những phần phân chia trong ổ đĩa.", IDC_INSTALLTEXT, 19, 36, 279, 27, NOT WS_GROUP + AUTORADIOBUTTON "Cập &nhật hay sửa chữa ReactOS", IDC_UPDATE, 7, 80, 277, 10 + LTEXT "Cập nhật hay sửa chữa một bản sao đã cài đặt của ReactOS. Tùy chọn này sẽ giữ lại các tập tin, cài đặt và chương trình của bạn. Tùy chọn này chỉ dùng được nếu ReactOS đã được cài đặt trên máy tinh này.", IDC_UPDATETEXT, 19, 96, 279, 27, NOT WS_GROUP END IDD_UPDATEREPAIRPAGE DIALOGEX 0, 0, 317, 143 @@ -161,8 +170,10 @@ END STRINGTABLE BEGIN IDS_CAPTION "Cài đặt ReactOS" - IDS_TYPETITLE "Chào mừng tới trình Thiết lập ReactOS" - IDS_TYPESUBTITLE "Chọn kiểu thiết lập." + IDS_TYPETITLE "Installation Type" + IDS_TYPESUBTITLE "You can setup a new ReactOS installation, or update/repair an existing installation." + IDS_UPDATETITLE "Update or Repair ReactOS" + IDS_UPDATESUBTITLE "Choose which existing ReactOS installation you want to update or repair." IDS_DEVICETITLE "Thiết lập các thiết bị cơ bản" IDS_DEVICESUBTITLE "Chọn những cài đặt cho màn hình và bàn phím." IDS_DRIVETITLE "Thiết lập phần ổ cứng để cài đặt và thư mục hệ thống" diff --git a/base/setup/reactos/lang/zh-CN.rc b/base/setup/reactos/lang/zh-CN.rc index dc0cc6494b56a..98439dad03446 100644 --- a/base/setup/reactos/lang/zh-CN.rc +++ b/base/setup/reactos/lang/zh-CN.rc @@ -8,8 +8,18 @@ CAPTION "ReactOS 安装程序" FONT 9, "宋体" BEGIN LTEXT "欢迎使用 ReactOS 安装程序", IDC_STARTTITLE, 115, 8, 195, 24 - LTEXT "您暂时不能直接从此 CD 安装 ReactOS!请重新启动并从 CD 引导您的电脑以便安装 ReactOS。", IDC_STATIC, 115, 40, 195, 100 - LTEXT "点击完成退出安装。", IDC_STATIC, 115, 169, 195, 17 + LTEXT "This wizard will install or upgrade ReactOS on your computer, \ +and prepare the second part of the setup.", IDC_STATIC, 115, 40, 195, 27 +//// + GROUPBOX " IMPORTANT INFORMATION ", IDC_WARNTEXT1, 115, 70, 195, 90, BS_CENTER + LTEXT "ReactOS is in Alpha stage: it is not feature- complete and is \ +under heavy development. It is recommended to use it only for \ +evaluation and testing and not as your daily-usage OS.\n\ +It may corrupt your data or damage your hardware.", IDC_WARNTEXT2, 120, 80, 185, 50, SS_CENTER + LTEXT "Backup your data or test on a secondary computer \ +if you attempt to run ReactOS on real hardware.", IDC_WARNTEXT3, 120, 130, 185, 27, SS_CENTER +//// + LTEXT "若要继续,请单击“下一步”。", IDC_STATIC, 115, 169, 195, 17 END IDD_TYPEPAGE DIALOGEX 0, 0, 317, 143 @@ -17,11 +27,10 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "ReactOS 安装程序" FONT 9, "宋体" BEGIN - AUTORADIOBUTTON "安装 ReactOS", IDC_INSTALL, 7, 7, 277, 10, WS_GROUP | WS_TABSTOP - LTEXT "安装 ReactOS 的新副本。此选项将不会保存你的文件、设置和程序。你可以对磁盘和分区进行更改。", IDC_INSTALLTEXT, 18, 18, 269, 25, NOT WS_GROUP - AUTORADIOBUTTON "修复或更新已安装的 ReactOS 副本", IDC_UPDATE, 7, 50, 277, 10 - LTEXT "更新或修复 ReactOS 安装的副本。此选项会保存您的文件、设置和程序。如果 ReactOS 已经安装,此选项方可使用。", IDC_UPDATETEXT, 18, 61, 269, 30, NOT WS_GROUP - LTEXT "点击下一步安装设备。", IDC_STATIC, 7, 128, 297, 8 + AUTORADIOBUTTON "安装 ReactOS(&I)", IDC_INSTALL, 7, 20, 277, 10, WS_GROUP | WS_TABSTOP + LTEXT "安装 ReactOS 的新副本。此选项将不会保存你的文件、设置和程序。你可以对磁盘和分区进行更改。", IDC_INSTALLTEXT, 19, 36, 279, 27, NOT WS_GROUP + AUTORADIOBUTTON "修复或更新 ReactOS(&U)", IDC_UPDATE, 7, 80, 277, 10 + LTEXT "更新或修复 ReactOS 安装的副本。此选项会保存您的文件、设置和程序。如果 ReactOS 已经安装,此选项方可使用。", IDC_UPDATETEXT, 19, 96, 279, 27, NOT WS_GROUP END IDD_UPDATEREPAIRPAGE DIALOGEX 0, 0, 317, 143 @@ -161,8 +170,10 @@ END STRINGTABLE BEGIN IDS_CAPTION "ReactOS 安装程序" - IDS_TYPETITLE "ReactOS 安装程序" - IDS_TYPESUBTITLE "选择安装类型。" + IDS_TYPETITLE "Installation Type" + IDS_TYPESUBTITLE "You can setup a new ReactOS installation, or update/repair an existing installation." + IDS_UPDATETITLE "Update or Repair ReactOS" + IDS_UPDATESUBTITLE "Choose which existing ReactOS installation you want to update or repair." IDS_DEVICETITLE "设置基本设备" IDS_DEVICESUBTITLE "指定显示和键盘设置。" IDS_DRIVETITLE "设置安装分区和系统文件夹" diff --git a/base/setup/reactos/lang/zh-HK.rc b/base/setup/reactos/lang/zh-HK.rc index 689cc84cb68bf..6f94145c9078b 100644 --- a/base/setup/reactos/lang/zh-HK.rc +++ b/base/setup/reactos/lang/zh-HK.rc @@ -16,8 +16,18 @@ CAPTION "ReactOS 安裝程式" FONT 9, "新細明體" BEGIN LTEXT "歡迎使用 ReactOS 安裝程式精靈", IDC_STARTTITLE, 115, 8, 195, 24 - LTEXT "您目前不能直接從這個 CD 安裝 ReactOS!\n請重新開機並從 CD 啟動您的電腦以安裝 ReactOS。", IDC_STATIC, 115, 40, 195, 100 - LTEXT "按[完成]退出安裝程式。", IDC_STATIC, 115, 169, 195, 17 + LTEXT "This wizard will install or upgrade ReactOS on your computer, \ +and prepare the second part of the setup.", IDC_STATIC, 115, 40, 195, 27 +//// + GROUPBOX " IMPORTANT INFORMATION ", IDC_WARNTEXT1, 115, 70, 195, 90, BS_CENTER + LTEXT "ReactOS is in Alpha stage: it is not feature- complete and is \ +under heavy development. It is recommended to use it only for \ +evaluation and testing and not as your daily-usage OS.\n\ +It may corrupt your data or damage your hardware.", IDC_WARNTEXT2, 120, 80, 185, 50, SS_CENTER + LTEXT "Backup your data or test on a secondary computer \ +if you attempt to run ReactOS on real hardware.", IDC_WARNTEXT3, 120, 130, 185, 27, SS_CENTER +//// + LTEXT "按[下一步]繼續安裝程式。", IDC_STATIC, 115, 169, 195, 17 END IDD_TYPEPAGE DIALOGEX 0, 0, 317, 143 @@ -25,11 +35,10 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "ReactOS 安裝程式" FONT 9, "新細明體" BEGIN - AUTORADIOBUTTON "安裝 ReactOS", IDC_INSTALL, 7, 7, 277, 10, WS_GROUP | WS_TABSTOP - LTEXT "安裝 ReactOS 的新副本。這個選項不會儲存您的檔案、設定和程式。您可以對磁碟和磁碟區進行更改。", IDC_INSTALLTEXT, 18, 18, 269, 25, NOT WS_GROUP - AUTORADIOBUTTON "修復或更新已安裝的 ReactOS", IDC_UPDATE, 7, 50, 277, 10 - LTEXT "更新或修復已安裝的 ReactOS 副本。這個選項會儲存您的檔案、設定及程式。只有在 ReactOS 已經安裝在此電腦時才可使用這個選項。", IDC_UPDATETEXT, 18, 61, 269, 30, NOT WS_GROUP - LTEXT "按[下一步]繼續安裝。", IDC_STATIC, 7, 128, 297, 8 + AUTORADIOBUTTON "安裝 ReactOS(&I)", IDC_INSTALL, 7, 20, 277, 10, WS_GROUP | WS_TABSTOP + LTEXT "安裝 ReactOS 的新副本。這個選項不會儲存您的檔案、設定和程式。您可以對磁碟和磁碟區進行更改。", IDC_INSTALLTEXT, 19, 36, 279, 27, NOT WS_GROUP + AUTORADIOBUTTON "修復或更新 ReactOS(&U)", IDC_UPDATE, 7, 80, 277, 10 + LTEXT "更新或修復已安裝的 ReactOS 副本。這個選項會儲存您的檔案、設定及程式。只有在 ReactOS 已經安裝在此電腦時才可使用這個選項。", IDC_UPDATETEXT, 19, 96, 279, 27, NOT WS_GROUP END IDD_UPDATEREPAIRPAGE DIALOGEX 0, 0, 317, 143 @@ -169,8 +178,10 @@ END STRINGTABLE BEGIN IDS_CAPTION "ReactOS 安裝程式" - IDS_TYPETITLE "ReactOS 安裝程式" - IDS_TYPESUBTITLE "選擇安裝類型。" + IDS_TYPETITLE "Installation Type" + IDS_TYPESUBTITLE "You can setup a new ReactOS installation, or update/repair an existing installation." + IDS_UPDATETITLE "Update or Repair ReactOS" + IDS_UPDATESUBTITLE "Choose which existing ReactOS installation you want to update or repair." IDS_DEVICETITLE "設定基本裝置" IDS_DEVICESUBTITLE "指定顯示和鍵盤設定。" IDS_DRIVETITLE "設定安裝磁碟區和系統資料夾" diff --git a/base/setup/reactos/lang/zh-TW.rc b/base/setup/reactos/lang/zh-TW.rc index 91639246353b5..7eda19e8506e5 100644 --- a/base/setup/reactos/lang/zh-TW.rc +++ b/base/setup/reactos/lang/zh-TW.rc @@ -17,8 +17,18 @@ CAPTION "ReactOS 安裝程式" FONT 9, "新細明體" BEGIN LTEXT "歡迎使用 ReactOS 安裝程式精靈", IDC_STARTTITLE, 115, 8, 195, 24 - LTEXT "您目前不能直接從這個 CD 安裝 ReactOS!請重新開機並從 CD 啟動您的電腦以便安裝 ReactOS。", IDC_STATIC, 115, 40, 195, 100 - LTEXT "按[完成]退出安裝程式。", IDC_STATIC, 115, 169, 195, 17 + LTEXT "This wizard will install or upgrade ReactOS on your computer, \ +and prepare the second part of the setup.", IDC_STATIC, 115, 40, 195, 27 +//// + GROUPBOX " IMPORTANT INFORMATION ", IDC_WARNTEXT1, 115, 70, 195, 90, BS_CENTER + LTEXT "ReactOS is in Alpha stage: it is not feature- complete and is \ +under heavy development. It is recommended to use it only for \ +evaluation and testing and not as your daily-usage OS.\n\ +It may corrupt your data or damage your hardware.", IDC_WARNTEXT2, 120, 80, 185, 50, SS_CENTER + LTEXT "Backup your data or test on a secondary computer \ +if you attempt to run ReactOS on real hardware.", IDC_WARNTEXT3, 120, 130, 185, 27, SS_CENTER +//// + LTEXT "按[下一步]繼續安裝程式。", IDC_STATIC, 115, 169, 195, 17 END IDD_TYPEPAGE DIALOGEX 0, 0, 317, 143 @@ -26,11 +36,10 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "ReactOS 安裝程式" FONT 9, "新細明體" BEGIN - AUTORADIOBUTTON "安裝 ReactOS", IDC_INSTALL, 7, 7, 277, 10, WS_GROUP | WS_TABSTOP - LTEXT "安裝 ReactOS 的新副本。此選項不會儲存您的檔案、設定和程式。您可以對磁碟和磁碟區進行更改。", IDC_INSTALLTEXT, 18, 18, 269, 25, NOT WS_GROUP - AUTORADIOBUTTON "修復或更新已安裝的 ReactOS", IDC_UPDATE, 7, 50, 277, 10 - LTEXT "更新或修復已安裝的 ReactOS 副本。此選項會儲存您的檔案、設定和程式。只有在 ReactOS 已經安裝在此電腦時才能使用此選項。", IDC_UPDATETEXT, 18, 61, 269, 30, NOT WS_GROUP - LTEXT "按[下一步]繼續安裝。", IDC_STATIC, 7, 128, 297, 8 + AUTORADIOBUTTON "安裝 ReactOS(&I)", IDC_INSTALL, 7, 20, 277, 10, WS_GROUP | WS_TABSTOP + LTEXT "安裝 ReactOS 的新副本。此選項不會儲存您的檔案、設定和程式。您可以對磁碟和磁碟區進行更改。", IDC_INSTALLTEXT, 19, 36, 279, 27, NOT WS_GROUP + AUTORADIOBUTTON "修復或更新 ReactOS(&U)", IDC_UPDATE, 7, 80, 277, 10 + LTEXT "更新或修復已安裝的 ReactOS 副本。此選項會儲存您的檔案、設定和程式。只有在 ReactOS 已經安裝在此電腦時才能使用此選項。", IDC_UPDATETEXT, 19, 96, 279, 27, NOT WS_GROUP END IDD_UPDATEREPAIRPAGE DIALOGEX 0, 0, 317, 143 @@ -170,8 +179,10 @@ END STRINGTABLE BEGIN IDS_CAPTION "ReactOS 安裝程式" - IDS_TYPETITLE "ReactOS 安裝程式" - IDS_TYPESUBTITLE "選擇安裝類型。" + IDS_TYPETITLE "Installation Type" + IDS_TYPESUBTITLE "You can setup a new ReactOS installation, or update/repair an existing installation." + IDS_UPDATETITLE "Update or Repair ReactOS" + IDS_UPDATESUBTITLE "Choose which existing ReactOS installation you want to update or repair." IDS_DEVICETITLE "設定基本裝置" IDS_DEVICESUBTITLE "指定顯示和鍵盤設定。" IDS_DRIVETITLE "設定安裝磁碟區和系統資料夾" diff --git a/base/setup/reactos/reactos.c b/base/setup/reactos/reactos.c index fe169bd3ee91c..d84d3da37a6eb 100644 --- a/base/setup/reactos/reactos.c +++ b/base/setup/reactos/reactos.c @@ -39,6 +39,7 @@ HANDLE ProcessHeap; SETUPDATA SetupData; +static BOOLEAN IsUnattendedSetup; /* The partition where to perform the installation */ PPARTENTRY InstallPartition = NULL; @@ -79,29 +80,50 @@ CenterWindow(HWND hWnd) SWP_NOSIZE); } +/** + * @brief + * Create a bold font derived from the provided font. + **/ static HFONT -CreateTitleFont(VOID) +CreateBoldFont( + _In_opt_ HFONT hOrigFont, + _In_opt_ INT PointSize) +{ + LOGFONTW lf = {0}; + + if (hOrigFont) + { + GetObjectW(hOrigFont, sizeof(lf), &lf); + } + else + { + NONCLIENTMETRICSW ncm; + ncm.cbSize = sizeof(ncm); + SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0); + lf = ncm.lfMessageFont; + } + + /* Make the font bold, keeping the other attributes */ + lf.lfWeight = FW_BOLD; + + /* Determine the font height (logical units) if necessary */ + if (PointSize) + { + HDC hdc = GetDC(NULL); + lf.lfHeight = -MulDiv(PointSize, GetDeviceCaps(hdc, LOGPIXELSY), 72); + // lf.lfWidth = 0; + ReleaseDC(NULL, hdc); + } + + return CreateFontIndirect(&lf); +} + +static inline HFONT +CreateTitleFont( + _In_opt_ HFONT hOrigFont) { - NONCLIENTMETRICS ncm; - LOGFONT LogFont; - HDC hdc; - INT FontSize; - HFONT hFont; - - ncm.cbSize = sizeof(NONCLIENTMETRICS); - SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0); - - LogFont = ncm.lfMessageFont; - LogFont.lfWeight = FW_BOLD; - _tcscpy(LogFont.lfFaceName, _T("MS Shell Dlg")); - - hdc = GetDC(NULL); - FontSize = 12; - LogFont.lfHeight = 0 - GetDeviceCaps (hdc, LOGPIXELSY) * FontSize / 72; - hFont = CreateFontIndirect(&LogFont); - ReleaseDC(NULL, hdc); - - return hFont; + /* Title font is 12pt bold */ + return CreateBoldFont(hOrigFont, 12); } INT @@ -307,11 +329,13 @@ StartDlgProc( SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (DWORD_PTR)pSetupData); /* Set title font */ - SendDlgItemMessage(hwndDlg, - IDC_STARTTITLE, - WM_SETFONT, - (WPARAM)pSetupData->hTitleFont, - (LPARAM)TRUE); + SetDlgItemFont(hwndDlg, IDC_STARTTITLE, pSetupData->hTitleFont, TRUE); + + // TEMPTEMP: Set the ReactOS-Alpha information in bold. + // TODO: Remove once we reach 0.5/Beta :) + SetDlgItemFont(hwndDlg, IDC_WARNTEXT1, pSetupData->hBoldFont, TRUE); + SetDlgItemFont(hwndDlg, IDC_WARNTEXT2, pSetupData->hBoldFont, TRUE); + SetDlgItemFont(hwndDlg, IDC_WARNTEXT3, pSetupData->hBoldFont, TRUE); /* Center the wizard window */ CenterWindow(GetParent(hwndDlg)); @@ -325,8 +349,21 @@ StartDlgProc( switch (lpnm->code) { case PSN_SETACTIVE: + { + /* Only "Next" and "Cancel" for the first page and hide "Back" */ PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT); + // PropSheet_ShowWizButtons(GetParent(hwndDlg), 0, PSWIZB_BACK); + ShowDlgItem(GetParent(hwndDlg), ID_WIZBACK, SW_HIDE); break; + } + + case PSN_KILLACTIVE: + { + /* Show "Back" button */ + // PropSheet_ShowWizButtons(GetParent(hwndDlg), PSWIZB_BACK, PSWIZB_BACK); + ShowDlgItem(GetParent(hwndDlg), ID_WIZBACK, SW_SHOW); + break; + } default: break; @@ -362,11 +399,15 @@ TypeDlgProc( pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam; SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (DWORD_PTR)pSetupData); - /* Check the 'install' radio button */ + /* Set the options in bold */ + SetDlgItemFont(hwndDlg, IDC_INSTALL, pSetupData->hBoldFont, TRUE); + SetDlgItemFont(hwndDlg, IDC_UPDATE, pSetupData->hBoldFont, TRUE); + + /* Check the "Install" radio button */ CheckDlgButton(hwndDlg, IDC_INSTALL, BST_CHECKED); /* - * Enable the 'update' radio button and text only if we have + * Enable the "Update" radio button and text only if we have * available NT installations, otherwise disable them. */ if (pSetupData->NtOsInstallsList && @@ -2282,11 +2323,7 @@ RestartDlgProc( SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (DWORD_PTR)pSetupData); /* Set title font */ - SendDlgItemMessage(hwndDlg, - IDC_FINISHTITLE, - WM_SETFONT, - (WPARAM)pSetupData->hTitleFont, - (LPARAM)TRUE); + SetDlgItemFont(hwndDlg, IDC_FINISHTITLE, pSetupData->hTitleFont, TRUE); break; case WM_TIMER: @@ -2762,7 +2799,6 @@ HotkeyThread(LPVOID Parameter) DPRINT("HotkeyThread start\n"); hotkey = GlobalAddAtomW(L"Setup Shift+F10 Hotkey"); - if (!RegisterHotKey(NULL, hotkey, MOD_SHIFT, VK_F10)) DPRINT1("RegisterHotKey failed with %lu\n", GetLastError()); @@ -2770,11 +2806,12 @@ HotkeyThread(LPVOID Parameter) { if (msg.hwnd == NULL && msg.message == WM_HOTKEY && msg.wParam == hotkey) { + WCHAR CmdLine[] = L"cmd.exe"; // CreateProcess can modify this buffer. STARTUPINFOW si = { sizeof(si) }; PROCESS_INFORMATION pi; - if (CreateProcessW(L"cmd.exe", - NULL, + if (CreateProcessW(NULL, + CmdLine, NULL, NULL, FALSE, @@ -2844,8 +2881,7 @@ _tWinMain(HINSTANCE hInst, } /* Retrieve any supplemental options from the unattend file */ - CheckUnattendedSetup(&SetupData.USetupData); - SetupData.bUnattend = IsUnattendedSetup; // FIXME :-) + SetupData.bUnattend = IsUnattendedSetup = CheckUnattendedSetup(&SetupData.USetupData); /* Load extra setup data (HW lists etc...) */ if (!LoadSetupData(&SetupData)) @@ -2864,8 +2900,9 @@ _tWinMain(HINSTANCE hInst, // RegisterTreeListClass(hInst); TreeListRegister(hInst); - /* Create title font */ - SetupData.hTitleFont = CreateTitleFont(); + /* Create the title and bold fonts */ + SetupData.hTitleFont = CreateTitleFont(NULL); + SetupData.hBoldFont = CreateBoldFont(NULL, 0); if (!SetupData.bUnattend) { @@ -2893,8 +2930,8 @@ _tWinMain(HINSTANCE hInst, /* Create the upgrade/repair selection page */ psp.dwSize = sizeof(PROPSHEETPAGE); psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; - psp.pszHeaderTitle = MAKEINTRESOURCEW(IDS_TYPETITLE); - psp.pszHeaderSubTitle = MAKEINTRESOURCEW(IDS_TYPESUBTITLE); + psp.pszHeaderTitle = MAKEINTRESOURCEW(IDS_UPDATETITLE); + psp.pszHeaderSubTitle = MAKEINTRESOURCEW(IDS_UPDATESUBTITLE); psp.hInstance = hInst; psp.lParam = (LPARAM)&SetupData; psp.pfnDlgProc = UpgradeRepairDlgProc; @@ -2976,8 +3013,10 @@ _tWinMain(HINSTANCE hInst, CloseHandle(SetupData.hHaltInstallEvent); SetupData.hHaltInstallEvent = NULL; + if (SetupData.hBoldFont) + DeleteFont(SetupData.hBoldFont); if (SetupData.hTitleFont) - DeleteObject(SetupData.hTitleFont); + DeleteFont(SetupData.hTitleFont); /* Unregister the TreeList control */ // UnregisterTreeListClass(hInst); diff --git a/base/setup/reactos/reactos.h b/base/setup/reactos/reactos.h index 286a303034c7c..9d8aecc04398e 100644 --- a/base/setup/reactos/reactos.h +++ b/base/setup/reactos/reactos.h @@ -51,6 +51,9 @@ #define ShowDlgItem(hDlg, nID, nCmdShow) \ ShowWindow(GetDlgItem((hDlg), (nID)), (nCmdShow)) +#define SetDlgItemFont(hDlg, nID, hFont, bRedraw) \ + SetWindowFont(GetDlgItem((hDlg), (nID)), (hFont), (bRedraw)) + /* These are public names and values determined from MFC, and compatible with Windows */ // Property Sheet control id's (determined with Spy++) #define IDC_TAB_CONTROL 0x3020 @@ -134,6 +137,7 @@ typedef struct _SETUPDATA BOOL bUnattend; HFONT hTitleFont; + HFONT hBoldFont; HANDLE hInstallThread; HANDLE hHaltInstallEvent; diff --git a/base/setup/reactos/resource.h b/base/setup/reactos/resource.h index a54f4035f8cde..e0420cafa63df 100644 --- a/base/setup/reactos/resource.h +++ b/base/setup/reactos/resource.h @@ -17,6 +17,9 @@ /* Dialogs */ #define IDD_STARTPAGE 2000 #define IDC_STARTTITLE 2001 +#define IDC_WARNTEXT1 2002 // TEMPTEMP: TODO: Remove once we reach 0.5/Beta :) +#define IDC_WARNTEXT2 2003 // TEMPTEMP: TODO: Remove once we reach 0.5/Beta :) +#define IDC_WARNTEXT3 2004 // TEMPTEMP: TODO: Remove once we reach 0.5/Beta :) #define IDD_TYPEPAGE 2010 #define IDC_INSTALL 2011 @@ -83,16 +86,18 @@ #define IDS_CAPTION 5000 #define IDS_TYPETITLE 5001 #define IDS_TYPESUBTITLE 5002 -#define IDS_DEVICETITLE 5003 -#define IDS_DEVICESUBTITLE 5004 -#define IDS_DRIVETITLE 5005 -#define IDS_DRIVESUBTITLE 5006 -#define IDS_SUMMARYTITLE 5007 -#define IDS_SUMMARYSUBTITLE 5008 -#define IDS_PROCESSTITLE 5009 -#define IDS_PROCESSSUBTITLE 5010 -#define IDS_RESTARTTITLE 5011 -#define IDS_RESTARTSUBTITLE 5012 +#define IDS_UPDATETITLE 5003 +#define IDS_UPDATESUBTITLE 5004 +#define IDS_DEVICETITLE 5005 +#define IDS_DEVICESUBTITLE 5006 +#define IDS_DRIVETITLE 5007 +#define IDS_DRIVESUBTITLE 5008 +#define IDS_SUMMARYTITLE 5009 +#define IDS_SUMMARYSUBTITLE 5010 +#define IDS_PROCESSTITLE 5011 +#define IDS_PROCESSSUBTITLE 5012 +#define IDS_RESTARTTITLE 5013 +#define IDS_RESTARTSUBTITLE 5014 #define IDS_ABORTSETUP 5020 #define IDS_ABORTSETUP2 5021 #define IDS_NO_TXTSETUP_SIF 5022 diff --git a/base/setup/usetup/lang/id-ID.h b/base/setup/usetup/lang/id-ID.h index 3e51d6fe906cb..035d0c465d6bf 100644 --- a/base/setup/usetup/lang/id-ID.h +++ b/base/setup/usetup/lang/id-ID.h @@ -975,7 +975,7 @@ static MUI_ENTRY idIDSelectPartitionEntries[] = { 8, 17, - "\x07 Tekan E untuk membuat partisi extended.", + "\x07 Tekan E untuk membuat partisi yang diperluas.", TEXT_STYLE_NORMAL, TEXT_ID_STATIC }, @@ -2051,14 +2051,14 @@ MUI_ERROR idIDErrorEntries[] = }, { // ERROR_PARTITION_TABLE_FULL, - "Anda tidak dapat membuat partisi primary atau extended baru di\n" + "Anda tidak dapat membuat partisi primer baru atau yg diperluas di\n" "tabel partisi cakram ini karena tabel partisi ini penuh.\n" "\n" " * Tekan tombol apapun untuk lanjut." }, { // ERROR_ONLY_ONE_EXTENDED, - "Anda tidak dapat membuat lebih dari satu partisi extended per satu cakram.\n" + "Anda tidak dapat membuat lebih dari satu partisi yang diperluas per satu cakram.\n" "\n" " * Tekan tombol apapun untuk lanjut." }, @@ -2214,11 +2214,11 @@ MUI_STRING idIDStrings[] = {STRING_PARTITIONSIZE, "Ukuran partisi baru:"}, {STRING_CHOOSE_NEW_PARTITION, - "Anda telah memilih untuk membuat partisi primary pada"}, + "Anda telah memilih untuk membuat partisi primer pada"}, {STRING_CHOOSE_NEW_EXTENDED_PARTITION, - "Anda telah memilih untuk membuat partisi extended pada"}, + "Anda telah memilih untuk membuat partisi yg diperluas pada"}, {STRING_CHOOSE_NEW_LOGICAL_PARTITION, - "Anda telah memilih untuk membuat partisi logical pada"}, + "Anda telah memilih untuk membuat partisi logikal pada"}, {STRING_HDPARTSIZE, "Mohon masukkan ukuran pada partisi baru dalam bentuk megabyte."}, {STRING_CREATEPARTITION, @@ -2302,7 +2302,7 @@ MUI_STRING idIDStrings[] = {STRING_MAXSIZE, "MB (maks. %lu MB)"}, {STRING_EXTENDED_PARTITION, - "Partisi Extended"}, + "Partisi yang Diperluas"}, {STRING_UNFORMATTED, "Baru (Belum Diformat)"}, {STRING_FORMATUNUSED, diff --git a/base/setup/usetup/partlist.c b/base/setup/usetup/partlist.c index a7eb50a8b5933..7d41bea9c3cbe 100644 --- a/base/setup/usetup/partlist.c +++ b/base/setup/usetup/partlist.c @@ -49,36 +49,14 @@ GetPartitionTypeString( } else { - UINT i; - /* Do the table lookup */ - if (PartEntry->DiskEntry->DiskStyle == PARTITION_STYLE_MBR) - { - for (i = 0; i < ARRAYSIZE(MbrPartitionTypes); ++i) - { - if (PartEntry->PartitionType == MbrPartitionTypes[i].Type) - { - RtlStringCchCopyA(strBuffer, cchBuffer, - MbrPartitionTypes[i].Description); - return; - } - } - } -#if 0 // TODO: GPT support! - else if (PartEntry->DiskEntry->DiskStyle == PARTITION_STYLE_GPT) + PCSTR Description = LookupPartitionTypeString(PartEntry->DiskEntry->DiskStyle, + &PartEntry->PartitionType); + if (Description) { - for (i = 0; i < ARRAYSIZE(GptPartitionTypes); ++i) - { - if (IsEqualPartitionType(PartEntry->PartitionType, - GptPartitionTypes[i].Guid)) - { - RtlStringCchCopyA(strBuffer, cchBuffer, - GptPartitionTypes[i].Description); - return; - } - } + RtlStringCchCopyA(strBuffer, cchBuffer, Description); + return; } -#endif /* We are here because the partition type is unknown */ if (cchBuffer > 0) *strBuffer = '\0'; diff --git a/base/setup/usetup/usetup.c b/base/setup/usetup/usetup.c index 13b4238aa4688..d3c62e6b4906b 100644 --- a/base/setup/usetup/usetup.c +++ b/base/setup/usetup/usetup.c @@ -42,6 +42,7 @@ HANDLE ProcessHeap; static USETUP_DATA USetupData; +static BOOLEAN IsUnattendedSetup; /* The partition where to perform the installation */ static PPARTENTRY InstallPartition = NULL; @@ -604,8 +605,7 @@ SetupStartPage(PINPUT_RECORD Ir) if (WaitNoPendingInstallEvents(NULL) != STATUS_WAIT_0) DPRINT1("WaitNoPendingInstallEvents() failed to wait!\n"); - CheckUnattendedSetup(&USetupData); - + IsUnattendedSetup = CheckUnattendedSetup(&USetupData); if (IsUnattendedSetup) { // TODO: Read options from inf diff --git a/base/shell/cmd/cmdinput.c b/base/shell/cmd/cmdinput.c index b888e6d8fb745..b2be64ee1a829 100644 --- a/base/shell/cmd/cmdinput.c +++ b/base/shell/cmd/cmdinput.c @@ -103,8 +103,8 @@ #include "precomp.h" /* - * See https://technet.microsoft.com/en-us/library/cc978715.aspx - * and https://technet.microsoft.com/en-us/library/cc940805.aspx + * See https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-2000-server/cc978715(v=technet.10) + * and https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-2000-server/cc940805(v=technet.10) * to know the differences between those two settings. * Values 0x00, 0x0D (carriage return) and >= 0x20 (space) disable completion. */ diff --git a/base/shell/cmd/lang/fr-FR.rc b/base/shell/cmd/lang/fr-FR.rc index 304a5a9f4c625..2bb95bd46acd4 100644 --- a/base/shell/cmd/lang/fr-FR.rc +++ b/base/shell/cmd/lang/fr-FR.rc @@ -288,7 +288,7 @@ MOVE [/N][/Y|/-Y][lecteur:][chemin]nomrep1 nomrep2\n\n\ /N Nothing. Do everything but move files or directories.\n\n\ Limitations actuelles :\n\ - Vous ne pouvez pas déplacer un fichier/répertoire d'un disque à un autre.\n" - STRING_MSGBOX_HELP "Affiche une boite de dialogue et retourne la réponse de l'utilisateur\n\n\ + STRING_MSGBOX_HELP "Affiche une boîte de dialogue et retourne la réponse de l'utilisateur\n\n\ MSGBOX type ['titre'] prompt\n\n\ type boutons affichés\n\ les valeurs possibles sont: OK, OKCANCEL,\n\ @@ -374,7 +374,7 @@ START [""titre""] [/D chemin] [/I] [/B] [/MIN] [/MAX] [/WAIT]\n\ B Lance la commande ou le programme sans créer de fenêtre.\n\ MIN Démarre avec la fenêtre réduite.\n\ MAX Démarre avec la fenêtre agrandie.\n\ - WAIT Lance la commande ou le programme et attend qu'elle termine.\n\ + WAIT Lance la commande ou le programme et attend qu'elle se termine.\n\ commande Indique la commande ou le programme à lancer.\n\ paramètres Spécifie les paramètres à passer à la commande ou au programme.\n" STRING_TITLE_HELP "Change le titre de la fenêtre de l'invite de commandes.\n\n\ @@ -508,13 +508,13 @@ titre titre de la fenêtre" STRING_ERROR_CANNOTPIPE "Erreur ! Impossible de chaîner ! Échec à l'ouverture du fichier temporaire!\n" STRING_ERROR_D_PAUSEMSG "Appuyez sur une touche pour continuer . . . " STRING_ERROR_DRIVER_NOT_READY "Lecteur non prêt" - STRING_ERROR_INVALID_NUMBER1 "Invalid number. Numeric constants are either decimal (42), hexadecimal (0x2A), or octal (052).\n" - STRING_ERROR_INVALID_NUMBER2 "Invalid number. Numbers are limited to 32-bits of precision.\n" - STRING_ERROR_DIVISION_BY_ZERO "Division by zero error.\n" - STRING_ERROR_INVALID_DEVICE L"Invalid device '%s'\n" - STRING_ERROR_CALL_BAD_LABEL "Invalid attempt to call batch label outside of batch script.\n" - STRING_ERROR_UNEXPECTED "%s was unexpected.\n" - STRING_ERROR_WHILE_PROCESSING "Error occurred while processing: %s.\n" + STRING_ERROR_INVALID_NUMBER1 "Nombre invalide. Les constantes numériques sont soit décimales (42), hexadécimales (0x2A), ou octales (052).\n" + STRING_ERROR_INVALID_NUMBER2 "Nombre invalide. Les nombres sont limités à une précision de 32-bits.\n" + STRING_ERROR_DIVISION_BY_ZERO "Erreur de division par zéro.\n" + STRING_ERROR_INVALID_DEVICE L"Périphérique non valide '%s'\n" + STRING_ERROR_CALL_BAD_LABEL "Tentative non valide d'appel d'une étiquette en dehors du script de commandes.\n" + STRING_ERROR_UNEXPECTED "%s n'était pas attendu.\n" + STRING_ERROR_WHILE_PROCESSING "Une erreur est apparue lors du traitement : %s.\n" STRING_SET_ENV_ERROR "Variable d'environnement '%s' non définie\n" STRING_CMD_INFOLINE " ReactOS Command Prompt Type HELP = Help " STRING_CMD_COPYRIGHT "(C) Copyright 1996-%s ReactOS Team.\n" diff --git a/base/shell/explorer/explorer.rc b/base/shell/explorer/explorer.rc index c27464aebbc60..8cafd2633100a 100644 --- a/base/shell/explorer/explorer.rc +++ b/base/shell/explorer/explorer.rc @@ -49,15 +49,21 @@ IDB_TASKBARPROP_LOCK_GROUP_NOQL BITMAP "res/bmp/150.bmp" IDB_TASKBARPROP_NOLOCK_GROUP_NOQL BITMAP "res/bmp/151.bmp" IDB_TASKBARPROP_LOCK_NOGROUP_NOQL BITMAP "res/bmp/152.bmp" IDB_TASKBARPROP_NOLOCK_NOGROUP_NOQL BITMAP "res/bmp/153.bmp" -IDB_SYSTRAYPROP_SHOW_SECONDS BITMAP "res/bmp/154.bmp" -IDB_SYSTRAYPROP_HIDE_SECONDS BITMAP "res/bmp/155.bmp" +IDB_SYSTRAYPROP_SHOW_SECONDS_NODESK BITMAP "res/bmp/154.bmp" +IDB_SYSTRAYPROP_HIDE_SECONDS_NODESK BITMAP "res/bmp/155.bmp" IDB_STARTMENU BITMAP "res/bmp/158.bmp" IDB_STARTPREVIEW BITMAP "res/bmp/170.bmp" IDB_STARTPREVIEW_CLASSIC BITMAP "res/bmp/171.bmp" -IDB_SYSTRAYPROP_HIDE_CLOCK BITMAP "res/bmp/180.bmp" -IDB_SYSTRAYPROP_HIDE_NOCLOCK BITMAP "res/bmp/181.bmp" -IDB_SYSTRAYPROP_SHOW_CLOCK BITMAP "res/bmp/182.bmp" -IDB_SYSTRAYPROP_SHOW_NOCLOCK BITMAP "res/bmp/183.bmp" +IDB_SYSTRAYPROP_HIDE_CLOCK_NODESK BITMAP "res/bmp/180.bmp" +IDB_SYSTRAYPROP_HIDE_NOCLOCK_NODESK BITMAP "res/bmp/181.bmp" +IDB_SYSTRAYPROP_SHOW_CLOCK_NODESK BITMAP "res/bmp/182.bmp" +IDB_SYSTRAYPROP_SHOW_NOCLOCK_NODESK BITMAP "res/bmp/183.bmp" +IDB_SYSTRAYPROP_SHOW_SECONDS_DESK BITMAP "res/bmp/184.bmp" +IDB_SYSTRAYPROP_HIDE_SECONDS_DESK BITMAP "res/bmp/185.bmp" +IDB_SYSTRAYPROP_HIDE_CLOCK_DESK BITMAP "res/bmp/186.bmp" +IDB_SYSTRAYPROP_HIDE_NOCLOCK_DESK BITMAP "res/bmp/187.bmp" +IDB_SYSTRAYPROP_SHOW_CLOCK_DESK BITMAP "res/bmp/188.bmp" +IDB_SYSTRAYPROP_SHOW_NOCLOCK_DESK BITMAP "res/bmp/189.bmp" CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "explorer.exe.manifest" diff --git a/base/shell/explorer/lang/tr-TR.rc b/base/shell/explorer/lang/tr-TR.rc index f67bccb27b3c0..5909c74d0dd54 100644 --- a/base/shell/explorer/lang/tr-TR.rc +++ b/base/shell/explorer/lang/tr-TR.rc @@ -4,7 +4,7 @@ * PURPOSE: Turkish resource file * TRANSLATORS: Copyright 2013-2015 Erdem Ersoy (eersoy93) * Copyright 2021 Süleyman Poyraz - * Copyright 2024 Ethem De Santa (scropool) + * Copyright 2024-2025 Ethem Çılgın (snapzenic) */ LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT @@ -20,10 +20,10 @@ BEGIN MENUITEM "&Pencereleri basamakla", ID_SHELL_CMD_CASCADE_WND MENUITEM "P&encereleri yan yana göster", ID_SHELL_CMD_TILE_WND_H MENUITEM "Pe&ncereleri üst üste göster", ID_SHELL_CMD_TILE_WND_V - MENUITEM "&Masaüstünü göster", ID_SHELL_CMD_SHOW_DESKTOP + MENUITEM "&Masaüstünü Göster", ID_SHELL_CMD_SHOW_DESKTOP MENUITEM "&Geri Al", ID_SHELL_CMD_UNDO_ACTION MENUITEM SEPARATOR - MENUITEM "&Görev Yöneticisi'ni başlat", ID_SHELL_CMD_OPEN_TASKMGR + MENUITEM "&Görev Yöneticisi", ID_SHELL_CMD_OPEN_TASKMGR MENUITEM SEPARATOR MENUITEM "G&örev çubuğunu kilitle", ID_LOCKTASKBAR MENUITEM "&Özellikler", ID_SHELL_CMD_PROPERTIES @@ -217,5 +217,5 @@ BEGIN IDS_RESTORE_ALL "&Açık Pencereleri Göster" IDS_TRAYWND_UNDO_CASCADE "&Kademeyi Geri Al" IDS_TRAYWND_UNDO_TILE "&Döşemeyi Geri Al" - IDS_TRAYDESKBTN_TOOLTIP "Show Desktop/Windows" + IDS_TRAYDESKBTN_TOOLTIP "Masaüstünü/Pencereleri Göster" END diff --git a/base/shell/explorer/precomp.h b/base/shell/explorer/precomp.h index df60ef3a6f59f..f90ec62f1a821 100644 --- a/base/shell/explorer/precomp.h +++ b/base/shell/explorer/precomp.h @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -119,7 +120,7 @@ VOID InitRSHELL(VOID); HRESULT WINAPI _CStartMenu_CreateInstance(REFIID riid, void **ppv); HANDLE WINAPI _SHCreateDesktop(IShellDesktopTray *ShellDesk); BOOL WINAPI _SHDesktopMessageLoop(HANDLE hDesktop); -DWORD WINAPI _WinList_Init(void); +BOOL WINAPI _WinList_Init(void); void WINAPI _ShellDDEInit(BOOL bInit); HRESULT WINAPI _CBandSiteMenu_CreateInstance(REFIID riid, void **ppv); HRESULT WINAPI _CBandSite_CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, void **ppv); diff --git a/base/shell/explorer/res/bmp/184.bmp b/base/shell/explorer/res/bmp/184.bmp new file mode 100644 index 0000000000000..866e364ab1267 Binary files /dev/null and b/base/shell/explorer/res/bmp/184.bmp differ diff --git a/base/shell/explorer/res/bmp/185.bmp b/base/shell/explorer/res/bmp/185.bmp new file mode 100644 index 0000000000000..7767600156d5a Binary files /dev/null and b/base/shell/explorer/res/bmp/185.bmp differ diff --git a/base/shell/explorer/res/bmp/186.bmp b/base/shell/explorer/res/bmp/186.bmp new file mode 100644 index 0000000000000..4499898262d00 Binary files /dev/null and b/base/shell/explorer/res/bmp/186.bmp differ diff --git a/base/shell/explorer/res/bmp/187.bmp b/base/shell/explorer/res/bmp/187.bmp new file mode 100644 index 0000000000000..f81efb188cce2 Binary files /dev/null and b/base/shell/explorer/res/bmp/187.bmp differ diff --git a/base/shell/explorer/res/bmp/188.bmp b/base/shell/explorer/res/bmp/188.bmp new file mode 100644 index 0000000000000..7ed2f228ea02e Binary files /dev/null and b/base/shell/explorer/res/bmp/188.bmp differ diff --git a/base/shell/explorer/res/bmp/189.bmp b/base/shell/explorer/res/bmp/189.bmp new file mode 100644 index 0000000000000..62a0837fb5eb3 Binary files /dev/null and b/base/shell/explorer/res/bmp/189.bmp differ diff --git a/base/shell/explorer/resource.h b/base/shell/explorer/resource.h index 72b3456270b5d..d0253e7e9daab 100644 --- a/base/shell/explorer/resource.h +++ b/base/shell/explorer/resource.h @@ -39,15 +39,21 @@ #define IDB_TASKBARPROP_NOLOCK_GROUP_NOQL 151 #define IDB_TASKBARPROP_LOCK_NOGROUP_NOQL 152 #define IDB_TASKBARPROP_NOLOCK_NOGROUP_NOQL 153 -#define IDB_SYSTRAYPROP_SHOW_SECONDS 154 -#define IDB_SYSTRAYPROP_HIDE_SECONDS 155 +#define IDB_SYSTRAYPROP_SHOW_SECONDS_NODESK 154 +#define IDB_SYSTRAYPROP_HIDE_SECONDS_NODESK 155 #define IDB_STARTMENU 158 #define IDB_STARTPREVIEW 170 #define IDB_STARTPREVIEW_CLASSIC 171 -#define IDB_SYSTRAYPROP_HIDE_CLOCK 180 -#define IDB_SYSTRAYPROP_HIDE_NOCLOCK 181 -#define IDB_SYSTRAYPROP_SHOW_CLOCK 182 -#define IDB_SYSTRAYPROP_SHOW_NOCLOCK 183 +#define IDB_SYSTRAYPROP_HIDE_CLOCK_NODESK 180 +#define IDB_SYSTRAYPROP_HIDE_NOCLOCK_NODESK 181 +#define IDB_SYSTRAYPROP_SHOW_CLOCK_NODESK 182 +#define IDB_SYSTRAYPROP_SHOW_NOCLOCK_NODESK 183 +#define IDB_SYSTRAYPROP_SHOW_SECONDS_DESK 184 +#define IDB_SYSTRAYPROP_HIDE_SECONDS_DESK 185 +#define IDB_SYSTRAYPROP_HIDE_CLOCK_DESK 186 +#define IDB_SYSTRAYPROP_HIDE_NOCLOCK_DESK 187 +#define IDB_SYSTRAYPROP_SHOW_CLOCK_DESK 188 +#define IDB_SYSTRAYPROP_SHOW_NOCLOCK_DESK 189 /*******************************************************************************\ |* Menu Resources *| diff --git a/base/shell/explorer/rshell.cpp b/base/shell/explorer/rshell.cpp index 9767c23504d38..bdd5571ade62b 100644 --- a/base/shell/explorer/rshell.cpp +++ b/base/shell/explorer/rshell.cpp @@ -105,9 +105,9 @@ BOOL WINAPI _SHDesktopMessageLoop(HANDLE hDesktop) return FALSE; } -typedef DWORD(WINAPI* PWINLIST_INIT)(void); +typedef BOOL (WINAPI *PWINLIST_INIT)(void); -DWORD WINAPI _WinList_Init(void) +BOOL WINAPI _WinList_Init(void) { HINSTANCE hFallback; @@ -131,7 +131,7 @@ DWORD WINAPI _WinList_Init(void) } } - return 0; + return FALSE; } typedef void (WINAPI *PSHELLDDEINIT)(BOOL bInit); diff --git a/base/shell/explorer/startctxmnu.cpp b/base/shell/explorer/startctxmnu.cpp index ccee6ef6a7edb..412819e7a3b52 100644 --- a/base/shell/explorer/startctxmnu.cpp +++ b/base/shell/explorer/startctxmnu.cpp @@ -145,12 +145,12 @@ class CStartMenuBtnCtxMenu : return S_OK; } - virtual HRESULT STDMETHODCALLTYPE - QueryContextMenu(HMENU hPopup, - UINT indexMenu, - UINT idCmdFirst, - UINT idCmdLast, - UINT uFlags) + STDMETHODIMP + QueryContextMenu(HMENU hPopup, + UINT indexMenu, + UINT idCmdFirst, + UINT idCmdLast, + UINT uFlags) override { LPITEMIDLIST pidlStart; CComPtr psfDesktop; @@ -189,42 +189,53 @@ class CStartMenuBtnCtxMenu : return hRet; } - virtual HRESULT STDMETHODCALLTYPE - InvokeCommand(LPCMINVOKECOMMANDINFO lpici) + STDMETHODIMP + InvokeCommand(LPCMINVOKECOMMANDINFO lpici) override { UINT uiCmdId = PtrToUlong(lpici->lpVerb); - if (!IsShellCmdId((UINT_PTR)lpici->lpVerb)) + if (!IsShellCmdId(uiCmdId)) { - CMINVOKECOMMANDINFO cmici = { 0 }; - CHAR szDir[MAX_PATH]; + CMINVOKECOMMANDINFOEX cmici = { sizeof(cmici) }; /* Setup and invoke the shell command */ - cmici.cbSize = sizeof(cmici); cmici.hwnd = m_Owner; + cmici.nShow = SW_NORMAL; + cmici.fMask = CMIC_MASK_UNICODE; + WCHAR szVerbW[MAX_PATH]; if (IS_INTRESOURCE(lpici->lpVerb)) + { cmici.lpVerb = MAKEINTRESOURCEA(uiCmdId - INNERIDOFFSET); + cmici.lpVerbW = MAKEINTRESOURCEW(uiCmdId - INNERIDOFFSET); + } else + { cmici.lpVerb = lpici->lpVerb; - cmici.nShow = SW_NORMAL; + SHAnsiToUnicode(lpici->lpVerb, szVerbW, _countof(szVerbW)); + cmici.lpVerbW = szVerbW; + } - /* FIXME: Support Unicode!!! */ - if (SHGetPathFromIDListA(m_FolderPidl, szDir)) + CHAR szDirA[MAX_PATH]; + WCHAR szDirW[MAX_PATH]; + if (SHGetPathFromIDListW(m_FolderPidl, szDirW)) { - cmici.lpDirectory = szDir; + SHUnicodeToAnsi(szDirW, szDirA, _countof(szDirA)); + cmici.lpDirectory = szDirA; + cmici.lpDirectoryW = szDirW; } - return m_Inner->InvokeCommand(&cmici); + return m_Inner->InvokeCommand((LPCMINVOKECOMMANDINFO)&cmici); } m_TrayWnd->ExecContextMenuCmd(uiCmdId); return S_OK; } - virtual HRESULT STDMETHODCALLTYPE - GetCommandString(UINT_PTR idCmd, - UINT uType, - UINT *pwReserved, - LPSTR pszName, - UINT cchMax) + STDMETHODIMP + GetCommandString( + UINT_PTR idCmd, + UINT uType, + UINT *pwReserved, + LPSTR pszName, + UINT cchMax) override { if (!IsShellCmdId(idCmd) && m_Inner) return m_Inner->GetCommandString(idCmd, uType, pwReserved, pszName, cchMax); diff --git a/base/shell/explorer/startmnusite.cpp b/base/shell/explorer/startmnusite.cpp index 872a24e335ede..ceed50d37bde0 100644 --- a/base/shell/explorer/startmnusite.cpp +++ b/base/shell/explorer/startmnusite.cpp @@ -37,12 +37,13 @@ class CStartMenuSite : virtual ~CStartMenuSite() {} - /*******************************************************************/ + // *** IServiceProvider methods *** - virtual HRESULT STDMETHODCALLTYPE QueryService( + STDMETHODIMP + QueryService( IN REFGUID guidService, IN REFIID riid, - OUT PVOID *ppvObject) + OUT PVOID *ppvObject) override { if (IsEqualGUID(guidService, SID_SMenuPopup)) { @@ -52,10 +53,10 @@ class CStartMenuSite : return E_NOINTERFACE; } - /*******************************************************************/ + // *** IOleWindow methods *** - virtual HRESULT STDMETHODCALLTYPE GetWindow( - OUT HWND *phwnd) + STDMETHODIMP + GetWindow(OUT HWND *phwnd) override { TRACE("ITrayPriv::GetWindow\n"); @@ -66,16 +67,17 @@ class CStartMenuSite : return E_FAIL; } - virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp( - IN BOOL fEnterMode) + STDMETHODIMP + ContextSensitiveHelp(IN BOOL fEnterMode) override { TRACE("ITrayPriv::ContextSensitiveHelp\n"); return E_NOTIMPL; } - virtual HRESULT STDMETHODCALLTYPE Execute( + STDMETHODIMP + Execute( IN IShellFolder *pShellFolder, - IN LPCITEMIDLIST pidl) + IN LPCITEMIDLIST pidl) override { HRESULT ret = S_FALSE; @@ -86,11 +88,12 @@ class CStartMenuSite : return ret; } - virtual HRESULT STDMETHODCALLTYPE Unknown( + STDMETHODIMP + Unknown( IN PVOID Unknown1, IN PVOID Unknown2, IN PVOID Unknown3, - IN PVOID Unknown4) + IN PVOID Unknown4) override { TRACE("ITrayPriv::Unknown(0x%p,0x%p,0x%p,0x%p)\n", Unknown1, Unknown2, Unknown3, Unknown4); return E_NOTIMPL; @@ -112,8 +115,8 @@ class CStartMenuSite : return FALSE; } - virtual HRESULT STDMETHODCALLTYPE AppendMenu( - OUT HMENU* phMenu) + STDMETHODIMP + AppendMenu(OUT HMENU* phMenu) override { HMENU hMenu, hSettingsMenu; DWORD dwLogoff; @@ -279,53 +282,63 @@ class CStartMenuSite : /*******************************************************************/ - virtual HRESULT STDMETHODCALLTYPE QueryStatus( + STDMETHODIMP + QueryStatus( IN const GUID *pguidCmdGroup OPTIONAL, IN ULONG cCmds, IN OUT OLECMD *prgCmds, - IN OUT OLECMDTEXT *pCmdText OPTIONAL) + IN OUT OLECMDTEXT *pCmdText OPTIONAL) override { return E_NOTIMPL; } - virtual HRESULT STDMETHODCALLTYPE Exec( + STDMETHODIMP + Exec( IN const GUID *pguidCmdGroup OPTIONAL, IN DWORD nCmdID, IN DWORD nCmdExecOpt, IN VARIANTARG *pvaIn OPTIONAL, - IN VARIANTARG *pvaOut OPTIONAL) + IN VARIANTARG *pvaOut OPTIONAL) override { return E_NOTIMPL; } /*******************************************************************/ - virtual HRESULT STDMETHODCALLTYPE SetClient(IUnknown *punkClient) + STDMETHODIMP + SetClient(IUnknown *punkClient) override { return E_NOTIMPL; } - virtual HRESULT STDMETHODCALLTYPE GetClient(IUnknown ** ppunkClient) + STDMETHODIMP + GetClient(IUnknown ** ppunkClient) override { return E_NOTIMPL; } - virtual HRESULT STDMETHODCALLTYPE OnPosRectChangeDB(RECT *prc) + STDMETHODIMP + OnPosRectChangeDB(RECT *prc) override { return E_NOTIMPL; } - virtual HRESULT STDMETHODCALLTYPE Popup(POINTL *ppt, RECTL *prcExclude, MP_POPUPFLAGS dwFlags) + // *** IMenuPopup methods *** + + STDMETHODIMP + Popup(POINTL *ppt, RECTL *prcExclude, MP_POPUPFLAGS dwFlags) override { return E_NOTIMPL; } - virtual HRESULT STDMETHODCALLTYPE OnSelect(DWORD dwSelectType) + STDMETHODIMP + OnSelect(DWORD dwSelectType) override { return E_NOTIMPL; } - virtual HRESULT STDMETHODCALLTYPE SetSubMenu(IMenuPopup *pmp, BOOL fSet) + STDMETHODIMP + SetSubMenu(IMenuPopup *pmp, BOOL fSet) override { if (!fSet) { diff --git a/base/shell/explorer/syspager.cpp b/base/shell/explorer/syspager.cpp index 22063a18bc641..6706605bdb3a8 100644 --- a/base/shell/explorer/syspager.cpp +++ b/base/shell/explorer/syspager.cpp @@ -217,8 +217,10 @@ class CSysPagerWnd : LRESULT OnGetMinimumSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); public: + // *** IOleWindow methods *** - HRESULT WINAPI GetWindow(HWND* phwnd) + STDMETHODIMP + GetWindow(HWND* phwnd) override { if (!phwnd) return E_INVALIDARG; @@ -226,7 +228,8 @@ class CSysPagerWnd : return S_OK; } - HRESULT WINAPI ContextSensitiveHelp(BOOL fEnterMode) + STDMETHODIMP + ContextSensitiveHelp(BOOL fEnterMode) override { return E_NOTIMPL; } diff --git a/base/shell/explorer/taskband.cpp b/base/shell/explorer/taskband.cpp index 7d8d2d213ce74..48b4be6d587af 100644 --- a/base/shell/explorer/taskband.cpp +++ b/base/shell/explorer/taskband.cpp @@ -52,7 +52,8 @@ class CTaskBand : /*****************************************************************************/ - virtual HRESULT STDMETHODCALLTYPE GetWindow(OUT HWND *phwnd) + STDMETHODIMP + GetWindow(OUT HWND *phwnd) override { if (!m_hWnd) return E_FAIL; @@ -62,40 +63,42 @@ class CTaskBand : return S_OK; } - virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp( - IN BOOL fEnterMode) + STDMETHODIMP + ContextSensitiveHelp(IN BOOL fEnterMode) override { /* FIXME: Implement */ return E_NOTIMPL; } - virtual HRESULT STDMETHODCALLTYPE ShowDW( - IN BOOL bShow) + STDMETHODIMP + ShowDW(IN BOOL bShow) override { /* We don't do anything... */ return S_OK; } - virtual HRESULT STDMETHODCALLTYPE CloseDW( - IN DWORD dwReserved) + STDMETHODIMP + CloseDW(IN DWORD dwReserved) override { /* We don't do anything... */ return S_OK; } - virtual HRESULT STDMETHODCALLTYPE ResizeBorderDW( + STDMETHODIMP + ResizeBorderDW( LPCRECT prcBorder, IUnknown *punkToolbarSite, - BOOL fReserved) + BOOL fReserved) override { /* No need to implement this method */ return E_NOTIMPL; } - virtual HRESULT STDMETHODCALLTYPE GetBandInfo( + STDMETHODIMP + GetBandInfo( IN DWORD dwBandID, IN DWORD dwViewMode, - IN OUT DESKBANDINFO *pdbi) + IN OUT DESKBANDINFO *pdbi) override { TRACE("CTaskBand::GetBandInfo(0x%x,0x%x,0x%p) hWnd=0x%p\n", dwBandID, dwViewMode, pdbi, m_hWnd); @@ -151,13 +154,25 @@ class CTaskBand : /*****************************************************************************/ // *** IOleCommandTarget methods *** - virtual HRESULT STDMETHODCALLTYPE QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText) + + STDMETHODIMP + QueryStatus( + const GUID *pguidCmdGroup, + ULONG cCmds, + OLECMD prgCmds [], + OLECMDTEXT *pCmdText) override { UNIMPLEMENTED; return E_NOTIMPL; } - virtual HRESULT STDMETHODCALLTYPE Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut) + STDMETHODIMP + Exec( + const GUID *pguidCmdGroup, + DWORD nCmdID, + DWORD nCmdexecopt, + VARIANT *pvaIn, + VARIANT *pvaOut) override { if (IsEqualIID(*pguidCmdGroup, IID_IBandSite)) { @@ -175,22 +190,22 @@ class CTaskBand : /*****************************************************************************/ - virtual HRESULT STDMETHODCALLTYPE SetClient( - IN IUnknown *punkClient) + STDMETHODIMP + SetClient(IN IUnknown *punkClient) override { TRACE("IDeskBar::SetClient(0x%p)\n", punkClient); return E_NOTIMPL; } - virtual HRESULT STDMETHODCALLTYPE GetClient( - OUT IUnknown **ppunkClient) + STDMETHODIMP + GetClient(OUT IUnknown **ppunkClient) override { TRACE("IDeskBar::GetClient(0x%p)\n", ppunkClient); return E_NOTIMPL; } - virtual HRESULT STDMETHODCALLTYPE OnPosRectChangeDB( - IN RECT *prc) + STDMETHODIMP + OnPosRectChangeDB(IN RECT *prc) override { TRACE("IDeskBar::OnPosRectChangeDB(0x%p=(%d,%d,%d,%d))\n", prc, prc->left, prc->top, prc->right, prc->bottom); if (prc->bottom - prc->top == 0) @@ -201,8 +216,8 @@ class CTaskBand : /*****************************************************************************/ - virtual HRESULT STDMETHODCALLTYPE GetClassID( - OUT CLSID *pClassID) + STDMETHODIMP + GetClassID(OUT CLSID *pClassID) override { TRACE("CTaskBand::GetClassID(0x%p)\n", pClassID); /* We're going to return the (internal!) CLSID of the task band interface */ @@ -210,30 +225,32 @@ class CTaskBand : return S_OK; } - virtual HRESULT STDMETHODCALLTYPE IsDirty() + STDMETHODIMP + IsDirty() override { /* The object hasn't changed since the last save! */ return S_FALSE; } - virtual HRESULT STDMETHODCALLTYPE Load( - IN IStream *pStm) + STDMETHODIMP + Load(IN IStream *pStm) override { TRACE("CTaskBand::Load called\n"); /* Nothing to do */ return S_OK; } - virtual HRESULT STDMETHODCALLTYPE Save( + STDMETHODIMP + Save( IN IStream *pStm, - IN BOOL fClearDirty) + IN BOOL fClearDirty) override { /* Nothing to do */ return S_OK; } - virtual HRESULT STDMETHODCALLTYPE GetSizeMax( - OUT ULARGE_INTEGER *pcbSize) + STDMETHODIMP + GetSizeMax(OUT ULARGE_INTEGER *pcbSize) override { TRACE("CTaskBand::GetSizeMax called\n"); /* We don't need any space for the task band */ @@ -243,7 +260,8 @@ class CTaskBand : /*****************************************************************************/ - virtual HRESULT STDMETHODCALLTYPE SetSite(IUnknown *pUnkSite) + STDMETHODIMP + SetSite(IUnknown *pUnkSite) override { HRESULT hRet; HWND hwndSite; @@ -269,9 +287,10 @@ class CTaskBand : return S_OK; } - virtual HRESULT STDMETHODCALLTYPE GetSite( + STDMETHODIMP + GetSite( IN REFIID riid, - OUT VOID **ppvSite) + OUT VOID **ppvSite) override { TRACE("CTaskBand::GetSite(0x%p,0x%p)\n", riid, ppvSite); @@ -286,37 +305,20 @@ class CTaskBand : /*****************************************************************************/ - virtual HRESULT STDMETHODCALLTYPE ProcessMessage( - IN HWND hWnd, - IN UINT uMsg, - IN WPARAM wParam, - IN LPARAM lParam, - OUT LRESULT *plrResult) - { - TRACE("CTaskBand: IWinEventHandler::ProcessMessage(0x%p, 0x%x, 0x%p, 0x%p, 0x%p)\n", hWnd, uMsg, wParam, lParam, plrResult); - return E_NOTIMPL; - } - - virtual HRESULT STDMETHODCALLTYPE ContainsWindow( - IN HWND hWnd) - { - if (hWnd == m_hWnd || - IsChild(m_hWnd, hWnd)) - { - TRACE("CTaskBand::ContainsWindow(0x%p) returns S_OK\n", hWnd); - return S_OK; - } - - return S_FALSE; - } - - virtual HRESULT STDMETHODCALLTYPE OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult) + STDMETHODIMP + OnWinEvent( + HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam, + LRESULT *theResult) override { //UNIMPLEMENTED; return E_NOTIMPL; } - virtual HRESULT STDMETHODCALLTYPE IsWindowOwner(HWND hWnd) + STDMETHODIMP + IsWindowOwner(HWND hWnd) override { return (hWnd == m_hWnd) ? S_OK : S_FALSE; } diff --git a/base/shell/explorer/taskswnd.cpp b/base/shell/explorer/taskswnd.cpp index 9c800b295110b..c852e1f7cb2b4 100644 --- a/base/shell/explorer/taskswnd.cpp +++ b/base/shell/explorer/taskswnd.cpp @@ -1979,7 +1979,10 @@ class CTaskSwitchWnd : return S_OK; } - HRESULT WINAPI GetWindow(HWND* phwnd) + // *** IOleWindow methods *** + + STDMETHODIMP + GetWindow(HWND* phwnd) override { if (!phwnd) return E_INVALIDARG; @@ -1987,7 +1990,8 @@ class CTaskSwitchWnd : return S_OK; } - HRESULT WINAPI ContextSensitiveHelp(BOOL fEnterMode) + STDMETHODIMP + ContextSensitiveHelp(BOOL fEnterMode) override { return E_NOTIMPL; } diff --git a/base/shell/explorer/tbsite.cpp b/base/shell/explorer/tbsite.cpp index a842509d5da3b..2a00d35a71ac8 100644 --- a/base/shell/explorer/tbsite.cpp +++ b/base/shell/explorer/tbsite.cpp @@ -56,13 +56,14 @@ class CTrayBandSite : }; public: - - virtual ULONG STDMETHODCALLTYPE AddRef() + STDMETHODIMP_(ULONG) + AddRef() override { return InterlockedIncrement(&m_RefCount); } - virtual ULONG STDMETHODCALLTYPE Release() + STDMETHODIMP_(ULONG) + Release() override { ULONG Ret = InterlockedDecrement(&m_RefCount); @@ -72,7 +73,8 @@ class CTrayBandSite : return Ret; } - virtual HRESULT STDMETHODCALLTYPE QueryInterface(IN REFIID riid, OUT LPVOID *ppvObj) + STDMETHODIMP + QueryInterface(IN REFIID riid, OUT LPVOID *ppvObj) override { if (ppvObj == NULL) return E_POINTER; @@ -115,10 +117,11 @@ class CTrayBandSite : virtual ~CTrayBandSite() { } - virtual HRESULT STDMETHODCALLTYPE OnLoad( + STDMETHODIMP + OnLoad( IN OUT IStream *pStm, IN REFIID riid, - OUT PVOID *pvObj) + OUT PVOID *pvObj) override { LARGE_INTEGER liPosZero; ULARGE_INTEGER liCurrent; @@ -187,9 +190,10 @@ class CTrayBandSite : return hRet; } - virtual HRESULT STDMETHODCALLTYPE OnSave( + STDMETHODIMP + OnSave( IN OUT IUnknown *pUnk, - IN OUT IStream *pStm) + IN OUT IStream *pStm) override { /* NOTE: Callback routine called by the shell while saving the task band stream. We use it to intercept the default behavior when the task @@ -199,17 +203,19 @@ class CTrayBandSite : return E_NOTIMPL; } - virtual HRESULT STDMETHODCALLTYPE IsTaskBand(IN IUnknown *punk) + STDMETHODIMP + IsTaskBand(IN IUnknown *punk) override { return IsSameObject(m_BandSite, punk); } - virtual HRESULT STDMETHODCALLTYPE ProcessMessage( + STDMETHODIMP + ProcessMessage( IN HWND hWnd, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam, - OUT LRESULT *plResult) + OUT LRESULT *plResult) override { HRESULT hRet; @@ -277,13 +283,14 @@ class CTrayBandSite : return hRet; } - virtual HRESULT STDMETHODCALLTYPE AddContextMenus( + STDMETHODIMP + AddContextMenus( IN HMENU hmenu, IN UINT indexMenu, IN UINT idCmdFirst, IN UINT idCmdLast, IN UINT uFlags, - OUT IContextMenu **ppcm) + OUT IContextMenu **ppcm) override { HRESULT hRet; @@ -313,7 +320,8 @@ class CTrayBandSite : return S_OK; } - virtual HRESULT STDMETHODCALLTYPE Lock(IN BOOL bLock) + STDMETHODIMP + Lock(IN BOOL bLock) override { BOOL bPrevLocked = Locked; BANDSITEINFO bsi; @@ -342,7 +350,8 @@ class CTrayBandSite : /*******************************************************************/ - virtual HRESULT STDMETHODCALLTYPE AddBand(IN IUnknown *punk) + STDMETHODIMP + AddBand(IN IUnknown *punk) override { /* Send the DBID_DELAYINIT command to initialize the band to be added */ /* FIXME: Should be delayed */ @@ -367,19 +376,21 @@ class CTrayBandSite : return S_OK; } - virtual HRESULT STDMETHODCALLTYPE EnumBands( + STDMETHODIMP + EnumBands( IN UINT uBand, - OUT DWORD *pdwBandID) + OUT DWORD *pdwBandID) override { return m_BandSite->EnumBands(uBand, pdwBandID); } - virtual HRESULT STDMETHODCALLTYPE QueryBand( + STDMETHODIMP + QueryBand( IN DWORD dwBandID, OUT IDeskBand **ppstb, OUT DWORD *pdwState, OUT LPWSTR pszName, - IN int cchName) + IN int cchName) override { HRESULT hRet; IDeskBand *pstb = NULL; @@ -415,36 +426,38 @@ class CTrayBandSite : return hRet; } - virtual HRESULT STDMETHODCALLTYPE SetBandState( + STDMETHODIMP + SetBandState( IN DWORD dwBandID, IN DWORD dwMask, - IN DWORD dwState) + IN DWORD dwState) override { return m_BandSite->SetBandState(dwBandID, dwMask, dwState); } - virtual HRESULT STDMETHODCALLTYPE RemoveBand( - IN DWORD dwBandID) + STDMETHODIMP + RemoveBand(IN DWORD dwBandID) override { return m_BandSite->RemoveBand(dwBandID); } - virtual HRESULT STDMETHODCALLTYPE GetBandObject( + STDMETHODIMP + GetBandObject( IN DWORD dwBandID, IN REFIID riid, - OUT VOID **ppv) + OUT VOID **ppv) override { return m_BandSite->GetBandObject(dwBandID, riid, ppv); } - virtual HRESULT STDMETHODCALLTYPE SetBandSiteInfo( - IN const BANDSITEINFO *pbsinfo) + STDMETHODIMP + SetBandSiteInfo(IN const BANDSITEINFO *pbsinfo) override { return m_BandSite->SetBandSiteInfo(pbsinfo); } - virtual HRESULT STDMETHODCALLTYPE GetBandSiteInfo( - IN OUT BANDSITEINFO *pbsinfo) + STDMETHODIMP + GetBandSiteInfo(IN OUT BANDSITEINFO *pbsinfo) override { return m_BandSite->GetBandSiteInfo(pbsinfo); } diff --git a/base/shell/explorer/trayclock.cpp b/base/shell/explorer/trayclock.cpp index 4411d34d543c6..dd8224091ed57 100644 --- a/base/shell/explorer/trayclock.cpp +++ b/base/shell/explorer/trayclock.cpp @@ -104,8 +104,10 @@ class CTrayClockWnd : VOID PaintLine(IN HDC hDC, IN OUT RECT *rcClient, IN UINT LineNumber, IN UINT szLinesIndex); public: + // *** IOleWindow methods *** - HRESULT WINAPI GetWindow(HWND* phwnd) + STDMETHODIMP + GetWindow(HWND* phwnd) override { if (!phwnd) return E_INVALIDARG; @@ -113,7 +115,8 @@ class CTrayClockWnd : return S_OK; } - HRESULT WINAPI ContextSensitiveHelp(BOOL fEnterMode) + STDMETHODIMP + ContextSensitiveHelp(BOOL fEnterMode) override { return E_NOTIMPL; } diff --git a/base/shell/explorer/trayntfy.cpp b/base/shell/explorer/trayntfy.cpp index ed40b9a508275..1fad7c39cf9a9 100644 --- a/base/shell/explorer/trayntfy.cpp +++ b/base/shell/explorer/trayntfy.cpp @@ -496,7 +496,10 @@ class CTrayNotifyWnd : return GetParent().SendMessage(WM_NOTIFY, 0, (LPARAM)hdr); } - HRESULT WINAPI GetWindow(HWND* phwnd) + // *** IOleWindow methods *** + + STDMETHODIMP + GetWindow(HWND* phwnd) override { if (!phwnd) return E_INVALIDARG; @@ -504,7 +507,8 @@ class CTrayNotifyWnd : return S_OK; } - HRESULT WINAPI ContextSensitiveHelp(BOOL fEnterMode) + STDMETHODIMP + ContextSensitiveHelp(BOOL fEnterMode) override { return E_NOTIMPL; } diff --git a/base/shell/explorer/trayprop.cpp b/base/shell/explorer/trayprop.cpp index 99983402bc920..875334bf3404a 100644 --- a/base/shell/explorer/trayprop.cpp +++ b/base/shell/explorer/trayprop.cpp @@ -230,13 +230,14 @@ class CNotifySettingsPage : public CPropertyPageImpl private: HBITMAP m_hbmpTray; HWND m_hwndTaskbar; + static const WORD wImageIdLookupTable[2][2][2][2]; void _UpdateDialog() { BOOL bShowClock = IsDlgButtonChecked(IDC_TASKBARPROP_CLOCK); BOOL bShowSeconds = IsDlgButtonChecked(IDC_TASKBARPROP_SECONDS); BOOL bHideInactive = IsDlgButtonChecked(IDC_TASKBARPROP_HIDEICONS); - UINT uImageId; + BOOL bShowDesktopButton = IsDlgButtonChecked(IDC_TASKBARPROP_DESKTOP); HWND hwndCustomizeNotifyButton = GetDlgItem(IDC_TASKBARPROP_ICONCUST); HWND hwndSeconds = GetDlgItem(IDC_TASKBARPROP_SECONDS); @@ -246,19 +247,7 @@ class CNotifySettingsPage : public CPropertyPageImpl ::EnableWindow(hwndSeconds, bShowClock); if (!bShowSeconds) CheckDlgButton(IDC_TASKBARPROP_SECONDS, BST_UNCHECKED); - - if (bHideInactive && bShowClock && bShowSeconds) - uImageId = IDB_SYSTRAYPROP_HIDE_SECONDS; - else if (bHideInactive && bShowClock && !bShowSeconds) - uImageId = IDB_SYSTRAYPROP_HIDE_CLOCK; - else if (bHideInactive && !bShowClock) - uImageId = IDB_SYSTRAYPROP_HIDE_NOCLOCK; - else if (!bHideInactive && bShowClock && bShowSeconds) - uImageId = IDB_SYSTRAYPROP_SHOW_SECONDS; - else if (!bHideInactive && bShowClock && !bShowSeconds) - uImageId = IDB_SYSTRAYPROP_SHOW_CLOCK; - else if (!bHideInactive && !bShowClock) - uImageId = IDB_SYSTRAYPROP_SHOW_NOCLOCK; + UINT uImageId = wImageIdLookupTable[bShowClock][bShowSeconds][bHideInactive][bShowDesktopButton]; SetBitmap(hwndTrayBitmap, &m_hbmpTray, uImageId); } @@ -324,6 +313,30 @@ class CNotifySettingsPage : public CPropertyPageImpl } }; +const WORD CNotifySettingsPage::wImageIdLookupTable[2][2][2][2] = +{ + { + { + {IDB_SYSTRAYPROP_SHOW_NOCLOCK_NODESK, IDB_SYSTRAYPROP_SHOW_NOCLOCK_DESK}, + {IDB_SYSTRAYPROP_HIDE_NOCLOCK_NODESK, IDB_SYSTRAYPROP_HIDE_NOCLOCK_DESK} + }, + { + {IDB_SYSTRAYPROP_SHOW_NOCLOCK_NODESK, IDB_SYSTRAYPROP_SHOW_NOCLOCK_DESK}, + {IDB_SYSTRAYPROP_HIDE_NOCLOCK_NODESK, IDB_SYSTRAYPROP_HIDE_NOCLOCK_DESK} + } + }, + { + { + {IDB_SYSTRAYPROP_SHOW_CLOCK_NODESK, IDB_SYSTRAYPROP_SHOW_CLOCK_DESK}, + {IDB_SYSTRAYPROP_HIDE_CLOCK_NODESK, IDB_SYSTRAYPROP_HIDE_CLOCK_DESK} + }, + { + {IDB_SYSTRAYPROP_SHOW_SECONDS_NODESK, IDB_SYSTRAYPROP_SHOW_SECONDS_DESK}, + {IDB_SYSTRAYPROP_HIDE_SECONDS_NODESK, IDB_SYSTRAYPROP_HIDE_SECONDS_DESK} + } + } +}; + static int CALLBACK PropSheetProc(HWND hwndDlg, UINT uMsg, LPARAM lParam) { diff --git a/base/shell/explorer/traywnd.cpp b/base/shell/explorer/traywnd.cpp index ed2acdbfb542a..d5695c7411c6c 100644 --- a/base/shell/explorer/traywnd.cpp +++ b/base/shell/explorer/traywnd.cpp @@ -2454,6 +2454,9 @@ class CTrayWindow : CheckTrayWndPosition(); } + if (m_DesktopWnd) + ::SendMessageW(m_DesktopWnd, uMsg, wParam, lParam); + if (m_StartMenuPopup && lstrcmpiW((LPCWSTR)lParam, L"TraySettings") == 0) { HideStartMenu(); @@ -3490,21 +3493,24 @@ class CTrayWindow : * with it (especially positioning of desktop icons) */ - virtual ULONG STDMETHODCALLTYPE GetState() + STDMETHODIMP_(ULONG) + GetState() override { /* FIXME: Return ABS_ flags? */ TRACE("IShellDesktopTray::GetState() unimplemented!\n"); return 0; } - virtual HRESULT STDMETHODCALLTYPE GetTrayWindow(OUT HWND *phWndTray) + STDMETHODIMP + GetTrayWindow(OUT HWND *phWndTray) override { TRACE("IShellDesktopTray::GetTrayWindow(0x%p)\n", phWndTray); *phWndTray = m_hWnd; return S_OK; } - virtual HRESULT STDMETHODCALLTYPE RegisterDesktopWindow(IN HWND hWndDesktop) + STDMETHODIMP + RegisterDesktopWindow(IN HWND hWndDesktop) override { TRACE("IShellDesktopTray::RegisterDesktopWindow(0x%p)\n", hWndDesktop); @@ -3512,7 +3518,8 @@ class CTrayWindow : return S_OK; } - virtual HRESULT STDMETHODCALLTYPE Unknown(IN DWORD dwUnknown1, IN DWORD dwUnknown2) + STDMETHODIMP + Unknown(IN DWORD dwUnknown1, IN DWORD dwUnknown2) override { TRACE("IShellDesktopTray::Unknown(%u,%u) unimplemented!\n", dwUnknown1, dwUnknown2); return S_OK; @@ -3524,7 +3531,10 @@ class CTrayWindow : return S_OK; } - HRESULT WINAPI GetWindow(HWND* phwnd) + // *** IOleWindow methods *** + + STDMETHODIMP + GetWindow(HWND* phwnd) override { if (!phwnd) return E_INVALIDARG; @@ -3532,7 +3542,8 @@ class CTrayWindow : return S_OK; } - HRESULT WINAPI ContextSensitiveHelp(BOOL fEnterMode) + STDMETHODIMP + ContextSensitiveHelp(BOOL fEnterMode) override { return E_NOTIMPL; } @@ -3572,12 +3583,12 @@ class CTrayWindowCtxMenu : return S_OK; } - virtual HRESULT STDMETHODCALLTYPE - QueryContextMenu(HMENU hPopup, - UINT indexMenu, - UINT idCmdFirst, - UINT idCmdLast, - UINT uFlags) + STDMETHODIMP + QueryContextMenu(HMENU hPopup, + UINT indexMenu, + UINT idCmdFirst, + UINT idCmdLast, + UINT uFlags) override { HMENU hMenuBase; @@ -3632,8 +3643,8 @@ class CTrayWindowCtxMenu : return S_OK; } - virtual HRESULT STDMETHODCALLTYPE - InvokeCommand(LPCMINVOKECOMMANDINFO lpici) + STDMETHODIMP + InvokeCommand(LPCMINVOKECOMMANDINFO lpici) override { UINT uiCmdId = PtrToUlong(lpici->lpVerb); if (uiCmdId != 0) @@ -3662,12 +3673,13 @@ class CTrayWindowCtxMenu : return S_OK; } - virtual HRESULT STDMETHODCALLTYPE - GetCommandString(UINT_PTR idCmd, + STDMETHODIMP + GetCommandString( + UINT_PTR idCmd, UINT uType, UINT *pwReserved, LPSTR pszName, - UINT cchMax) + UINT cchMax) override { return E_NOTIMPL; } diff --git a/base/shell/progman/group.c b/base/shell/progman/group.c index 5b8362e994708..fdff507ae520b 100644 --- a/base/shell/progman/group.c +++ b/base/shell/progman/group.c @@ -72,7 +72,7 @@ CleanupUxTheme(VOID) //////////////////////////////////////////////////////////////////////////////// // Taken from WinSpy++ 1.7 -// http://www.catch22.net/software/winspy +// https://www.catch22.net/projects/winspy/ // Copyright (c) 2002 by J Brown // diff --git a/base/shell/progman/new_resources.rc b/base/shell/progman/new_resources.rc index 28717c413ab4c..9df5a143614bb 100644 --- a/base/shell/progman/new_resources.rc +++ b/base/shell/progman/new_resources.rc @@ -13,7 +13,7 @@ #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// -// Anglais (tats-Unis) resources +// Anglais (Etats-Unis) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US @@ -282,7 +282,7 @@ BEGIN IDS_SYMBOLS_ICO "Icons (*.ico)" END -#endif // Anglais (tats-Unis) resources +#endif // Anglais (Etats-Unis) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/base/shell/rshell/misc.cpp b/base/shell/rshell/misc.cpp index d0ed8c83e1bef..8e0403f4cfd04 100644 --- a/base/shell/rshell/misc.cpp +++ b/base/shell/rshell/misc.cpp @@ -52,12 +52,6 @@ extern "C" HRESULT WINAPI RSHELL_CMergedFolder_CreateInstance(REFIID riid, LPVOID *ppv); } -DWORD WINAPI WinList_Init(void) -{ - /* do something here (perhaps we may want to add our own implementation fo win8) */ - return 0; -} - class CRShellModule : public CComModule { public: diff --git a/base/system/CMakeLists.txt b/base/system/CMakeLists.txt index 8e82b217baef2..5fafe974173ef 100644 --- a/base/system/CMakeLists.txt +++ b/base/system/CMakeLists.txt @@ -7,13 +7,17 @@ add_subdirectory(dllhost) add_subdirectory(expand) add_subdirectory(format) add_subdirectory(logonui) -add_subdirectory(lsass) +if(NOT SARCH STREQUAL "wow64") + add_subdirectory(lsass) +endif() add_subdirectory(msiexec) add_subdirectory(regsvr32) add_subdirectory(rundll32) add_subdirectory(runonce) add_subdirectory(services) -add_subdirectory(smss) +if(NOT SARCH STREQUAL "wow64") + add_subdirectory(smss) +endif() add_subdirectory(subst) add_subdirectory(userinit) -add_subdirectory(winlogon) +add_subdirectory(winlogon) \ No newline at end of file diff --git a/base/system/format/format.c b/base/system/format/format.c index 29b22f9a27d75..3c1d200b59e07 100644 --- a/base/system/format/format.c +++ b/base/system/format/format.c @@ -367,9 +367,9 @@ int wmain(int argc, WCHAR *argv[]) WCHAR volumeName[1024] = {0}; WCHAR input[1024]; DWORD serialNumber; - DWORD flags, maxComponent; - ULARGE_INTEGER freeBytesAvailableToCaller, totalNumberOfBytes, totalNumberOfFreeBytes; + ULARGE_INTEGER totalNumberOfBytes, totalNumberOfFreeBytes; WCHAR szMsg[RC_STRING_MAX_SIZE]; + DWORD dwError; /* Initialize the Console Standard Streams */ ConInitStdStreams(); @@ -424,9 +424,9 @@ int wmain(int argc, WCHAR *argv[]) driveType = GetDriveTypeW(RootDirectory); switch (driveType) { - case DRIVE_UNKNOWN : - K32LoadStringW(GetModuleHandle(NULL), STRING_ERROR_DRIVE_TYPE, szMsg, ARRAYSIZE(szMsg)); - PrintWin32Error(szMsg, GetLastError()); + case DRIVE_UNKNOWN: + case DRIVE_NO_ROOT_DIR: // This case used to report STRING_NO_VOLUME, which has no ".\n". + ConResPuts(StdErr, STRING_ERROR_DRIVE_TYPE); return -1; case DRIVE_REMOTE: @@ -434,11 +434,6 @@ int wmain(int argc, WCHAR *argv[]) ConResPuts(StdOut, STRING_NO_SUPPORT); return -1; - case DRIVE_NO_ROOT_DIR: - K32LoadStringW(GetModuleHandle(NULL), STRING_NO_VOLUME, szMsg, ARRAYSIZE(szMsg)); - PrintWin32Error(szMsg, GetLastError()); - return -1; - case DRIVE_REMOVABLE: ConResPrintf(StdOut, STRING_INSERT_DISK, RootDirectory[0]); fgetws(input, ARRAYSIZE(input), stdin); @@ -468,25 +463,28 @@ int wmain(int argc, WCHAR *argv[]) } // - // Determine the drive's file system format + // Get the existing name and file system, and print out the latter // if (!GetVolumeInformationW(RootDirectory, volumeName, ARRAYSIZE(volumeName), - &serialNumber, &maxComponent, &flags, + NULL, NULL, NULL, fileSystem, ARRAYSIZE(fileSystem))) { - if (GetLastError() == ERROR_UNRECOGNIZED_VOLUME) + dwError = GetLastError(); + if (dwError == ERROR_UNRECOGNIZED_VOLUME) { wcscpy(fileSystem, L"RAW"); } else { K32LoadStringW(GetModuleHandle(NULL), STRING_NO_VOLUME, szMsg, ARRAYSIZE(szMsg)); - PrintWin32Error(szMsg, GetLastError()); + PrintWin32Error(szMsg, dwError); return -1; } } + ConResPrintf(StdOut, STRING_FILESYSTEM, fileSystem); + if (QueryDeviceInformation(RootDirectory, &DeviceInformation, sizeof(DeviceInformation))) @@ -500,15 +498,15 @@ int wmain(int argc, WCHAR *argv[]) * Fallback to GetFreeDiskSpaceExW if we did not get any volume length. */ if (totalNumberOfBytes.QuadPart == 0 && !GetDiskFreeSpaceExW(RootDirectory, - &freeBytesAvailableToCaller, + NULL, &totalNumberOfBytes, - &totalNumberOfFreeBytes)) + NULL)) { + dwError = GetLastError(); K32LoadStringW(GetModuleHandle(NULL), STRING_NO_VOLUME_SIZE, szMsg, ARRAYSIZE(szMsg)); - PrintWin32Error(szMsg, GetLastError()); + PrintWin32Error(szMsg, dwError); return -1; } - ConResPrintf(StdOut, STRING_FILESYSTEM, fileSystem); // // Make sure they want to do this @@ -605,32 +603,24 @@ int wmain(int argc, WCHAR *argv[]) input[wcslen(input) - 1] = 0; if (!SetVolumeLabelW(RootDirectory, input)) { + dwError = GetLastError(); K32LoadStringW(GetModuleHandle(NULL), STRING_NO_LABEL, szMsg, ARRAYSIZE(szMsg)); - PrintWin32Error(szMsg, GetLastError()); + PrintWin32Error(szMsg, dwError); return -1; } } - if (!GetVolumeInformationW(RootDirectory, - volumeName, ARRAYSIZE(volumeName), - &serialNumber, &maxComponent, &flags, - fileSystem, ARRAYSIZE(fileSystem))) - { - K32LoadStringW(GetModuleHandle(NULL), STRING_NO_VOLUME, szMsg, ARRAYSIZE(szMsg)); - PrintWin32Error(szMsg, GetLastError()); - return -1; - } - // - // Print out some stuff including the formatted size + // Get and print out some stuff including the formatted size // if (!GetDiskFreeSpaceExW(RootDirectory, - &freeBytesAvailableToCaller, + NULL, &totalNumberOfBytes, &totalNumberOfFreeBytes)) { + dwError = GetLastError(); K32LoadStringW(GetModuleHandle(NULL), STRING_NO_VOLUME_SIZE, szMsg, ARRAYSIZE(szMsg)); - PrintWin32Error(szMsg, GetLastError()); + PrintWin32Error(szMsg, dwError); return -1; } @@ -638,17 +628,19 @@ int wmain(int argc, WCHAR *argv[]) totalNumberOfFreeBytes.QuadPart); // - // Get the drive's serial number + // Get and print out the new serial number // if (!GetVolumeInformationW(RootDirectory, - volumeName, ARRAYSIZE(volumeName), - &serialNumber, &maxComponent, &flags, - fileSystem, ARRAYSIZE(fileSystem))) + NULL, 0, + &serialNumber, NULL, NULL, + NULL, 0)) { + dwError = GetLastError(); K32LoadStringW(GetModuleHandle(NULL), STRING_NO_VOLUME, szMsg, ARRAYSIZE(szMsg)); - PrintWin32Error(szMsg, GetLastError()); + PrintWin32Error(szMsg, dwError); return -1; } + ConResPrintf(StdOut, STRING_SERIAL_NUMBER, (unsigned int)(serialNumber >> 16), (unsigned int)(serialNumber & 0xFFFF)); diff --git a/base/system/format/lang/bg-BG.rc b/base/system/format/lang/bg-BG.rc index 75fe6e4d80418..cefadb9aa91f1 100644 --- a/base/system/format/lang/bg-BG.rc +++ b/base/system/format/lang/bg-BG.rc @@ -29,7 +29,7 @@ BEGIN STRING_FMIFS_FAIL "Неуспешно определяне разположението на входните точки на FMIFS\n\n" STRING_UNKNOW_ARG "Неизвестен ключ: %s\n" STRING_DRIVE_PARM "Задължителният ключ за името на устройството липсва.\n\n" - STRING_ERROR_DRIVE_TYPE "Неуспешно определяне вида на устройството" + STRING_ERROR_DRIVE_TYPE "Неуспешно определяне вида на устройството.\n" STRING_INSERT_DISK "Сложете нова дискета в устройство %C:\n,след което натиснете Enter..." STRING_NO_VOLUME "Неуспешно определяне на тома" STRING_NO_VOLUME_SIZE "Неуспешно определяне на размера на тома" diff --git a/base/system/format/lang/cs-CZ.rc b/base/system/format/lang/cs-CZ.rc index 329893e7c1d41..545b2c5a2fbff 100644 --- a/base/system/format/lang/cs-CZ.rc +++ b/base/system/format/lang/cs-CZ.rc @@ -27,7 +27,7 @@ BEGIN STRING_FMIFS_FAIL "Nelze najít vstupní body FMIFS.\n\n" STRING_UNKNOW_ARG "Neznámý agrument: %s\n" STRING_DRIVE_PARM "Schází nutný parametr disku.\n\n" - STRING_ERROR_DRIVE_TYPE "Nelze zjistit typ disku" + STRING_ERROR_DRIVE_TYPE "Nelze zjistit typ disku.\n" STRING_INSERT_DISK "Vložte novou disketu do jednotky %C:\na poté stiskněte klávesu ENTER..." STRING_NO_VOLUME "Nelze zjistit svazek" STRING_NO_VOLUME_SIZE "Nelze zjistit velikost svazku" diff --git a/base/system/format/lang/de-DE.rc b/base/system/format/lang/de-DE.rc index 3242887f8558b..72bf6b92a92df 100644 --- a/base/system/format/lang/de-DE.rc +++ b/base/system/format/lang/de-DE.rc @@ -32,7 +32,7 @@ BEGIN STRING_FMIFS_FAIL "Kann FMIFS-Eingangspunkte nicht lokalisieren.\n\n" STRING_UNKNOW_ARG "Unbekanntes Argument: %s\n" STRING_DRIVE_PARM "Benötigter Laufwerksparameter fehlt.\n\n" - STRING_ERROR_DRIVE_TYPE "Konnte den Laufwerkstyp nicht erhalten" + STRING_ERROR_DRIVE_TYPE "Konnte den Laufwerkstyp nicht erhalten.\n" STRING_INSERT_DISK "Legen Sie eine neue Diskette in Laufwerk %C: ein\nund drücken Sie ENTER, wenn das Laufwerk bereit ist." STRING_NO_VOLUME "Kann Medium nicht abfragen" STRING_NO_VOLUME_SIZE "Kann Mediengröße nicht abfragen" diff --git a/base/system/format/lang/el-GR.rc b/base/system/format/lang/el-GR.rc index f25a676d79ffb..d71bd6765702d 100644 --- a/base/system/format/lang/el-GR.rc +++ b/base/system/format/lang/el-GR.rc @@ -30,7 +30,7 @@ BEGIN STRING_FMIFS_FAIL "Could not located FMIFS entry points.\n\n" STRING_UNKNOW_ARG "Άγνωστο όρισμα: %s\n" STRING_DRIVE_PARM "Required drive parameter is missing.\n\n" - STRING_ERROR_DRIVE_TYPE "Δεν ήταν δυνατή η ανάγνωση του τύπου του τόμου." + STRING_ERROR_DRIVE_TYPE "Δεν ήταν δυνατή η ανάγνωση του τύπου του τόμου.\n" STRING_INSERT_DISK "ΕΙσάγετε μια νέα δισκέτα στο %C:\nκαι πατήστε Enter όταν είστε έτοιμοι..." STRING_NO_VOLUME "Could not query volume" STRING_NO_VOLUME_SIZE "Could not query volume size" diff --git a/base/system/format/lang/en-US.rc b/base/system/format/lang/en-US.rc index 2990400cd740c..dda08f0732c3d 100644 --- a/base/system/format/lang/en-US.rc +++ b/base/system/format/lang/en-US.rc @@ -28,7 +28,7 @@ BEGIN STRING_FMIFS_FAIL "Could not located FMIFS entry points.\n\n" STRING_UNKNOW_ARG "Unknown argument: %s\n" STRING_DRIVE_PARM "Required drive parameter is missing.\n\n" - STRING_ERROR_DRIVE_TYPE "Could not get drive type" + STRING_ERROR_DRIVE_TYPE "Could not get drive type.\n" STRING_INSERT_DISK "Insert a new floppy in drive %C:\nand press Enter when ready..." STRING_NO_VOLUME "Could not query volume" STRING_NO_VOLUME_SIZE "Could not query volume size" diff --git a/base/system/format/lang/es-ES.rc b/base/system/format/lang/es-ES.rc index 7930c1794b365..c6b118dff5906 100644 --- a/base/system/format/lang/es-ES.rc +++ b/base/system/format/lang/es-ES.rc @@ -28,7 +28,7 @@ BEGIN STRING_FMIFS_FAIL "Imposible localizar puntos de entrada FMIFS.\n\n" STRING_UNKNOW_ARG "Argumento desconocido: %s\n" STRING_DRIVE_PARM "Parámetro de unidad requerido no encontrado.\n\n" - STRING_ERROR_DRIVE_TYPE "Imposible determinar el tipo de unidad" + STRING_ERROR_DRIVE_TYPE "Imposible determinar el tipo de unidad.\n" STRING_INSERT_DISK "Inserte un nuevo disco en la unidad %C:\ny presione Enter cuando esté preparado..." STRING_NO_VOLUME "Imposible consultar el volumen" STRING_NO_VOLUME_SIZE "Imposible consultar el tamaño de volumen" diff --git a/base/system/format/lang/fr-FR.rc b/base/system/format/lang/fr-FR.rc index 70385a8bb9732..2321978f3f753 100644 --- a/base/system/format/lang/fr-FR.rc +++ b/base/system/format/lang/fr-FR.rc @@ -26,7 +26,7 @@ BEGIN STRING_FMIFS_FAIL "Impossible de trouver les points d'entrée FMIFS.\n\n" STRING_UNKNOW_ARG "Argument inconnu : %s\n" STRING_DRIVE_PARM "Le disque à formater n'est pas indiqué.\n\n" - STRING_ERROR_DRIVE_TYPE "Impossible d'obtenir le type de disque" + STRING_ERROR_DRIVE_TYPE "Impossible d'obtenir le type de disque.\n" STRING_INSERT_DISK "Mettre une nouvelle disquette dans le lecteur %C:\n et appuyer sur Entrée..." STRING_NO_VOLUME "Impossible de trouver le disque" STRING_NO_VOLUME_SIZE "Impossible de déterminer la taille du disque" diff --git a/base/system/format/lang/hu-HU.rc b/base/system/format/lang/hu-HU.rc index 9105327e755a3..8dbce283d6c60 100644 --- a/base/system/format/lang/hu-HU.rc +++ b/base/system/format/lang/hu-HU.rc @@ -32,7 +32,7 @@ BEGIN STRING_FMIFS_FAIL "Az FMIFS belépési pontok nem találhatók.\n\n" STRING_UNKNOW_ARG "Érvénytelen paraméter: %s\n" STRING_DRIVE_PARM "Hiányzik a meghajtó meghatározás.\n\n" - STRING_ERROR_DRIVE_TYPE "Nem sikerült lekérdezni a meghajtó típusát" + STRING_ERROR_DRIVE_TYPE "Nem sikerült lekérdezni a meghajtó típusát.\n" STRING_INSERT_DISK "Helyezzen be új lemezt a következő meghajtóba: %C:\nHa készen áll, nyomja meg az ENTER billentyűt..." STRING_NO_VOLUME "Nem sikerült megállapítani címkét" STRING_NO_VOLUME_SIZE "Nem sikerült megállapítani a kötet méretét" diff --git a/base/system/format/lang/id-ID.rc b/base/system/format/lang/id-ID.rc index 8369ece9de6d2..60ed8ccb294f9 100644 --- a/base/system/format/lang/id-ID.rc +++ b/base/system/format/lang/id-ID.rc @@ -29,7 +29,7 @@ BEGIN STRING_FMIFS_FAIL "Tidak bisa menemukan FMIFS entry points.\n\n" STRING_UNKNOW_ARG "Argumen tidak dikenal: %s\n" STRING_DRIVE_PARM "Parameter drive yang diperlukan hilang.\n\n" - STRING_ERROR_DRIVE_TYPE "Tidak bisa mendapatkan jenis drive" + STRING_ERROR_DRIVE_TYPE "Tidak bisa mendapatkan jenis drive.\n" STRING_INSERT_DISK "Sisipkan disket baru di drive %C:\ndan tekan Enter bila siap..." STRING_NO_VOLUME "Tidak bisa memdapatkan volume" STRING_NO_VOLUME_SIZE "Tidak bisa mendapatkan ukuran volume" diff --git a/base/system/format/lang/it-IT.rc b/base/system/format/lang/it-IT.rc index 0add43bd09a26..08ca2e5d9cdb9 100644 --- a/base/system/format/lang/it-IT.rc +++ b/base/system/format/lang/it-IT.rc @@ -27,7 +27,7 @@ BEGIN STRING_FMIFS_FAIL "Impossibile trovare 'FMIFS entry points'.\n\n" STRING_UNKNOW_ARG "Parametro sconosciuto: %s\n" STRING_DRIVE_PARM "Manca il parametro 'drive'.\n\n" - STRING_ERROR_DRIVE_TYPE "Impossibile rilevare il tipo di drive" + STRING_ERROR_DRIVE_TYPE "Impossibile rilevare il tipo di drive.\n" STRING_INSERT_DISK "Inserire un floppy nuovo nel drive %C:\n e successivamente premere Invio..." STRING_NO_VOLUME "Impossibile rilevare il volume" STRING_NO_VOLUME_SIZE "Impossibile rilevare la dimensione del volume" diff --git a/base/system/format/lang/ja-JP.rc b/base/system/format/lang/ja-JP.rc index f0203afbcbb92..b1cb767b9e11c 100644 --- a/base/system/format/lang/ja-JP.rc +++ b/base/system/format/lang/ja-JP.rc @@ -31,7 +31,7 @@ BEGIN STRING_FMIFS_FAIL "FMIFS エントリ ポイント を設定できませんでした。\n\n" STRING_UNKNOW_ARG "不明な引数: %s\n" STRING_DRIVE_PARM "必要なドライブを指定するパラメータが不足しています。\n\n" - STRING_ERROR_DRIVE_TYPE "ドライブの種類がわかりませんでした" + STRING_ERROR_DRIVE_TYPE "ドライブの種類がわかりませんでした。\n" STRING_INSERT_DISK "%C: ドライブに新しいフロッピーを挿入してください。\n準備ができたら、[Enter] キーを押してください..." STRING_NO_VOLUME "ボリュームの問い合わせができませんでした" STRING_NO_VOLUME_SIZE "ボリューム サイズの問い合わせができませんでした" diff --git a/base/system/format/lang/lt-LT.rc b/base/system/format/lang/lt-LT.rc index 30819ecb5a3a7..80b32b626b8a3 100644 --- a/base/system/format/lang/lt-LT.rc +++ b/base/system/format/lang/lt-LT.rc @@ -28,7 +28,7 @@ BEGIN STRING_FMIFS_FAIL "Nepavyko rasti FMIFS įėjimo taškų.\n\n" STRING_UNKNOW_ARG "Nežinomas parametras: %s\n" STRING_DRIVE_PARM "Trūksta reikiamo disko parametro.\n\n" - STRING_ERROR_DRIVE_TYPE "Nepavyko nustatyti disko tipo" + STRING_ERROR_DRIVE_TYPE "Nepavyko nustatyti disko tipo.\n" STRING_INSERT_DISK "Į įrenginį %C:\nįdėkite naują diskelį ir paspaukite Enter..." STRING_NO_VOLUME "Nepavyko kreiptis į tomą" STRING_NO_VOLUME_SIZE "Nepavyko nustatyti tomo dydžio" diff --git a/base/system/format/lang/no-NO.rc b/base/system/format/lang/no-NO.rc index d3e5b10f4f629..8ed731a533e86 100644 --- a/base/system/format/lang/no-NO.rc +++ b/base/system/format/lang/no-NO.rc @@ -28,7 +28,7 @@ BEGIN STRING_FMIFS_FAIL "Kunne ikke befinne seg FMIFS artikkel momenter.\n\n" STRING_UNKNOW_ARG "Ukjent argument: %s\n" STRING_DRIVE_PARM "Obligatorisk drive parameter er mistet.\n\n" - STRING_ERROR_DRIVE_TYPE "Kunne ikke få drive typen" + STRING_ERROR_DRIVE_TYPE "Kunne ikke få drive typen.\n" STRING_INSERT_DISK "Sett inn en ny diskett i stasjon %C:\nog trykk på Enter når du er klar..." STRING_NO_VOLUME "Kunne ikke spørre om volumet" STRING_NO_VOLUME_SIZE "Kunne ikke spørre om volumet størrelse" diff --git a/base/system/format/lang/pl-PL.rc b/base/system/format/lang/pl-PL.rc index aa4a70720cfe0..df2e825734efc 100644 --- a/base/system/format/lang/pl-PL.rc +++ b/base/system/format/lang/pl-PL.rc @@ -31,7 +31,7 @@ BEGIN STRING_FMIFS_FAIL "Nie można zlokalizować punktów wejściowych FMIFS.\n\n" STRING_UNKNOW_ARG "Nieprawidłowy parametr: %s\n" STRING_DRIVE_PARM "Brakujący wymagany parametr dysku.\n\n" - STRING_ERROR_DRIVE_TYPE "Nie można określić rodzaju dysku" + STRING_ERROR_DRIVE_TYPE "Nie można określić rodzaju dysku.\n" STRING_INSERT_DISK "Włóż nowy dysk do napędu %C:\ni naciśnij Enter..." STRING_NO_VOLUME "Nie można odczytać woluminu" STRING_NO_VOLUME_SIZE "Nie można odczytać rozmiaru woluminu" diff --git a/base/system/format/lang/ro-RO.rc b/base/system/format/lang/ro-RO.rc index 3a4103eaf0db2..1b611e5fdf7e4 100644 --- a/base/system/format/lang/ro-RO.rc +++ b/base/system/format/lang/ro-RO.rc @@ -33,7 +33,7 @@ BEGIN STRING_FMIFS_FAIL "Nu s-au putut localiza punctele de intrare FMIFS.\n\n" STRING_UNKNOW_ARG "Argument necunoscut: %s\n" STRING_DRIVE_PARM "Lipsește argumentul (obligatoriu) ce indică unitatea de stocare.\n\n" - STRING_ERROR_DRIVE_TYPE "Nu se poate determina tipul discului" + STRING_ERROR_DRIVE_TYPE "Nu se poate determina tipul discului.\n" STRING_INSERT_DISK "Introduceți un disc flexibil în unitatea %C:\napoi apăsați Enter pentru a continua..." STRING_NO_VOLUME "Nu se poate accesa volumul" STRING_NO_VOLUME_SIZE "Nu se poate determina dimensiunea volumului" diff --git a/base/system/format/lang/ru-RU.rc b/base/system/format/lang/ru-RU.rc index fcedd2654b6e2..614ec343416b4 100644 --- a/base/system/format/lang/ru-RU.rc +++ b/base/system/format/lang/ru-RU.rc @@ -29,7 +29,7 @@ BEGIN STRING_FMIFS_FAIL "Невозможно определить расположение точек входа FMIFS.\n\n" STRING_UNKNOW_ARG "Неправильные аргументы: %s\n" STRING_DRIVE_PARM "Требуемый параметр операции отсутствует.\n\n" - STRING_ERROR_DRIVE_TYPE "Не удалось получить тип тома" + STRING_ERROR_DRIVE_TYPE "Не удалось получить тип тома.\n" STRING_INSERT_DISK "Вставьте чистый диск в устройство чтения %C:\nи нажмите Enter для продолжения..." STRING_NO_VOLUME "Не удалось выполнить запрос к тому" STRING_NO_VOLUME_SIZE "Не удалось определить размер тома" diff --git a/base/system/format/lang/sk-SK.rc b/base/system/format/lang/sk-SK.rc index 7411a75db967d..a5778b2ffd0e2 100644 --- a/base/system/format/lang/sk-SK.rc +++ b/base/system/format/lang/sk-SK.rc @@ -29,7 +29,7 @@ BEGIN STRING_FMIFS_FAIL "Nepodarilo sa lokalizovať vstupné body FMIFS.\n\n" STRING_UNKNOW_ARG "Neznámy argument: %s\n" STRING_DRIVE_PARM "Chýba nevyhnutný parameter jednotky.\n\n" - STRING_ERROR_DRIVE_TYPE "Nemožno získať typ jednotky" + STRING_ERROR_DRIVE_TYPE "Nemožno získať typ jednotky.\n" STRING_INSERT_DISK "Vložte novú disketu do jednotky %C:\na potom stlačte ENTER..." STRING_NO_VOLUME "Nemožno dotazovať zväzok" STRING_NO_VOLUME_SIZE "Nemožno dotazovať veľkosť zväzku" diff --git a/base/system/format/lang/sq-AL.rc b/base/system/format/lang/sq-AL.rc index a8a93e55a02bd..3fbff9a9548f2 100644 --- a/base/system/format/lang/sq-AL.rc +++ b/base/system/format/lang/sq-AL.rc @@ -28,7 +28,7 @@ BEGIN STRING_FMIFS_FAIL "Nuk alokohet FMIFS pika hyrjes.\n\n" STRING_UNKNOW_ARG "Argument i panjohur: %s\n" STRING_DRIVE_PARM "Parametra e duhura te driverit mungojne.\n\n" - STRING_ERROR_DRIVE_TYPE "Nuk dihet tipi i driverit" + STRING_ERROR_DRIVE_TYPE "Nuk dihet tipi i driverit.\n" STRING_INSERT_DISK "Fusni nje floppy ne drive %C:\nadhe shtypni Enter kur te jeni gati..." STRING_NO_VOLUME "Nuk mund te pyesi nje volum" STRING_NO_VOLUME_SIZE "Nuk mund te pyesi masen e nje volumi" diff --git a/base/system/format/lang/tr-TR.rc b/base/system/format/lang/tr-TR.rc index 9504a3dd5d76b..2fea331eb4b87 100644 --- a/base/system/format/lang/tr-TR.rc +++ b/base/system/format/lang/tr-TR.rc @@ -30,7 +30,7 @@ BEGIN STRING_FMIFS_FAIL "FMIFS giriş noktaları konumlandırılamadı.\n\n" STRING_UNKNOW_ARG "Bilinmeyen değişken: %s\n" STRING_DRIVE_PARM "İstenen sürücü değişkeni eksik.\n\n" - STRING_ERROR_DRIVE_TYPE "Sürücü türü alınamadı." + STRING_ERROR_DRIVE_TYPE "Sürücü türü alınamadı.\n" STRING_INSERT_DISK "%C: sürücüsüne yeni bir yumuşak disk yerleştiriniz\nve hazır olduğunda Enter'e basınız..." STRING_NO_VOLUME "Birim sorgulanamadı." STRING_NO_VOLUME_SIZE "Birim boyutu sorgulanamadı." diff --git a/base/system/format/lang/uk-UA.rc b/base/system/format/lang/uk-UA.rc index f6ccf704148d8..a97178b03db63 100644 --- a/base/system/format/lang/uk-UA.rc +++ b/base/system/format/lang/uk-UA.rc @@ -27,7 +27,7 @@ BEGIN STRING_FMIFS_FAIL "Не зміг знацти FMIFS точки входу.\n\n" STRING_UNKNOW_ARG "Невідомий аргумент: %s\n" STRING_DRIVE_PARM "Необхідний параметр операції відсутній.\n\n" - STRING_ERROR_DRIVE_TYPE "Не вдалося втсанвити тип пристрою" + STRING_ERROR_DRIVE_TYPE "Не вдалося втсанвити тип пристрою.\n" STRING_INSERT_DISK "Вставте чистий диск в пристрій %C:\nі натисніть Enter щоб продовжити..." STRING_NO_VOLUME "Не вдалося виконати запит до пристрою" STRING_NO_VOLUME_SIZE "Не вдалося визначити розмір диску" diff --git a/base/system/format/lang/zh-CN.rc b/base/system/format/lang/zh-CN.rc index 1f5bba51926c5..3daff75905884 100644 --- a/base/system/format/lang/zh-CN.rc +++ b/base/system/format/lang/zh-CN.rc @@ -26,7 +26,7 @@ BEGIN STRING_FMIFS_FAIL "不能定位 FMIFS 入口点。\n\n" STRING_UNKNOW_ARG "未知参数:%s\n" STRING_DRIVE_PARM "必要的驱动器参数缺失。\n\n" - STRING_ERROR_DRIVE_TYPE "无法获得驱动器类型" + STRING_ERROR_DRIVE_TYPE "无法获得驱动器类型。\n" STRING_INSERT_DISK "在驱动器 %C: 中插入一张新的软盘\n就绪时按 Enter..." STRING_NO_VOLUME "无法查询卷" STRING_NO_VOLUME_SIZE "无法查询卷大小" diff --git a/base/system/format/lang/zh-TW.rc b/base/system/format/lang/zh-TW.rc index c9de9f4827c36..968186f8d3a13 100644 --- a/base/system/format/lang/zh-TW.rc +++ b/base/system/format/lang/zh-TW.rc @@ -26,7 +26,7 @@ BEGIN STRING_FMIFS_FAIL "無法定位 FMIFS 進入點。\n\n" STRING_UNKNOW_ARG "未知參數:%s\n" STRING_DRIVE_PARM "缺少必要的磁碟參數。\n\n" - STRING_ERROR_DRIVE_TYPE "無法獲得磁碟機類型" + STRING_ERROR_DRIVE_TYPE "無法獲得磁碟機類型。\n" STRING_INSERT_DISK "在磁碟機 %C: 中插入一張新的軟碟片\n如果您準備就緒,請按 ENTER..." STRING_NO_VOLUME "無法查詢磁碟" STRING_NO_VOLUME_SIZE "無法查詢磁碟大小" diff --git a/base/system/msiexec/CMakeLists.txt b/base/system/msiexec/CMakeLists.txt index 2c704510e2a57..ae8dde0d51399 100644 --- a/base/system/msiexec/CMakeLists.txt +++ b/base/system/msiexec/CMakeLists.txt @@ -1,7 +1,5 @@ -add_definitions(-D__WINESRC__) remove_definitions(-D_CRT_NON_CONFORMING_SWPRINTFS) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/wine) list(APPEND SOURCE msiexec.c @@ -15,3 +13,4 @@ target_link_libraries(msiexec uuid wine) add_importlibs(msiexec user32 advapi32 ole32 comctl32 msi msvcrt kernel32 ntdll) add_pch(msiexec precomp.h SOURCE) add_cd_file(TARGET msiexec DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(msiexec) # CORE-5743: No ARRAY_SIZE macro diff --git a/base/system/services/services.rc b/base/system/services/services.rc index 4b58c2a343af2..e7c3cc7574fff 100644 --- a/base/system/services/services.rc +++ b/base/system/services/services.rc @@ -8,7 +8,6 @@ #define REACTOS_STR_ORIGINAL_FILENAME "services.exe" #include - /* UTF-8 */ #pragma code_page(65001) diff --git a/base/system/userinit/lang/de-DE.rc b/base/system/userinit/lang/de-DE.rc index 1ef20ca30b95f..b4fc9726cda1f 100644 --- a/base/system/userinit/lang/de-DE.rc +++ b/base/system/userinit/lang/de-DE.rc @@ -1,3 +1,11 @@ +/* + * PROJECT: ReactOS Userinit Logon Application + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: German resource file + * TRANSLATORS: Copyright 2005 Kevin Schnabel (FooDerGrosse) + * Copyright 2024 Václav Zouzalík (Venca24) + */ + LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL IDD_LOCALEPAGE DIALOGEX 0, 0, 317, 193 @@ -6,15 +14,15 @@ CAPTION "ReactOS LiveCD" FONT 8, "MS Shell Dlg" BEGIN CONTROL "IDB_LOGO", IDC_LOCALELOGO, "Static", WS_CHILD | WS_VISIBLE | SS_OWNERDRAW, 18, 4, 290, 99 - RTEXT "&Language:", IDC_STATIC, 20, 109, 106, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + RTEXT "&Sprache:", IDC_STATIC, 20, 109, 106, 11, WS_CHILD | WS_VISIBLE | WS_GROUP COMBOBOX IDC_LANGUAGELIST, 132, 107, 176, 142, CBS_DROPDOWNLIST | CBS_NOINTEGRALHEIGHT | CBS_SORT | WS_VSCROLL | WS_CHILD | WS_VISIBLE | WS_TABSTOP - RTEXT "&Keyboard layout:", IDC_STATIC, 20, 132, 106, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + RTEXT "&Tastaturlayout:", IDC_STATIC, 20, 132, 106, 11, WS_CHILD | WS_VISIBLE | WS_GROUP COMBOBOX IDC_LAYOUTLIST, 132, 130, 176, 81, CBS_DROPDOWNLIST | CBS_NOINTEGRALHEIGHT | CBS_SORT | WS_VSCROLL | WS_CHILD | WS_VISIBLE | WS_TABSTOP - LTEXT "Select your language and keyboard layout and click Next to continue.", IDC_STATIC, 7, 152, 300, 8 + LTEXT "Wählen Sie Ihre Sprache und Ihr Tastaturlayout aus und klicken Sie auf Weiter.", IDC_STATIC, 7, 152, 300, 8 CONTROL "", IDC_STATIC, "STATIC", SS_ETCHEDHORZ, 0, 165, 317, 1 - DEFPUSHBUTTON "&Next", IDOK, 205, 172, 50, 14 - PUSHBUTTON "&Cancel", IDCANCEL, 260, 172, 50, 14 + DEFPUSHBUTTON "&Weiter", IDOK, 205, 172, 50, 14 + PUSHBUTTON "&Abbrechen", IDCANCEL, 260, 172, 50, 14 END IDD_STARTPAGE DIALOGEX 0, 0, 317, 193 @@ -23,24 +31,24 @@ CAPTION "ReactOS LiveCD" FONT 8, "MS Shell Dlg" BEGIN CONTROL "IDB_LOGO", IDC_STARTLOGO, "Static", WS_CHILD | WS_VISIBLE | SS_OWNERDRAW, 18, 4, 290, 99 - DEFPUSHBUTTON "Run ReactOS &Live CD", IDC_RUN, 71, 108, 175, 21 - PUSHBUTTON "&Install ReactOS", IDC_INSTALL, 71, 136, 175, 21 + DEFPUSHBUTTON "ReactOS &Live CD starten", IDC_RUN, 71, 108, 175, 21 + PUSHBUTTON "ReactOS &installieren", IDC_INSTALL, 71, 136, 175, 21 // LTEXT "", IDC_STATIC, 7, 152, 300, 8 CONTROL "", IDC_STATIC, "STATIC", SS_ETCHEDHORZ, 0, 165, 317, 1 - PUSHBUTTON "&Previous", IDOK, 205, 172, 50, 14 - PUSHBUTTON "&Cancel", IDCANCEL, 260, 172, 50, 14 + PUSHBUTTON "&Zurück", IDOK, 205, 172, 50, 14 + PUSHBUTTON "&Abbrechen", IDCANCEL, 260, 172, 50, 14 END STRINGTABLE BEGIN IDS_SHELL_FAIL "Userinit konnte die Shell nicht starten!" - IDS_INSTALLER_FAIL "Userinit failed to start the installer!" - IDS_CANCEL_CONFIRM "Are you sure you want to quit the ReactOS LiveCD?\nIf you choose to do so, your computer might restart." + IDS_INSTALLER_FAIL "Userinit konnte das Setup nicht starten!" + IDS_CANCEL_CONFIRM "Sind Sie sicher, dass Sie die ReactOS LiveCD beenden möchten?\nIhr Computer wird möglicherweise neu gestartet, wenn Sie fortfahren." END STRINGTABLE BEGIN - IDS_SPAIN "Spanish (Spain)" + IDS_SPAIN "Spanisch (Spanien)" END diff --git a/base/system/userinit/lang/eo-AA.rc b/base/system/userinit/lang/eo-AA.rc new file mode 100644 index 0000000000000..a5fe20e83d605 --- /dev/null +++ b/base/system/userinit/lang/eo-AA.rc @@ -0,0 +1,53 @@ +/* + * PROJECT: ReactOS Userinit Logon Application + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Esperanto resource file + * TRANSLATOR: Copyright 2024 Václav Zouzalík (Venca24) + */ + +LANGUAGE LANG_ESPERANTO, SUBLANG_DEFAULT + +IDD_LOCALEPAGE DIALOGEX 0, 0, 317, 193 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "ReactOS LiveCD" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "IDB_LOGO", IDC_LOCALELOGO, "Static", WS_CHILD | WS_VISIBLE | SS_OWNERDRAW, 18, 4, 290, 99 + RTEXT "&Lingvo:", IDC_STATIC, 20, 109, 106, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + COMBOBOX IDC_LANGUAGELIST, 132, 107, 176, 142, CBS_DROPDOWNLIST | CBS_NOINTEGRALHEIGHT | CBS_SORT | WS_VSCROLL | WS_CHILD | WS_VISIBLE | WS_TABSTOP + RTEXT "&Klavararanĝo:", IDC_STATIC, 20, 132, 106, 11, WS_CHILD | WS_VISIBLE | WS_GROUP + COMBOBOX IDC_LAYOUTLIST, 132, 130, 176, 81, CBS_DROPDOWNLIST | CBS_NOINTEGRALHEIGHT | CBS_SORT | WS_VSCROLL | WS_CHILD | WS_VISIBLE | WS_TABSTOP + LTEXT "Elektu vian lingvon kaj klavararanĝon kaj klaku al Sekva por daŭri.", IDC_STATIC, 7, 152, 300, 8 + + CONTROL "", IDC_STATIC, "STATIC", SS_ETCHEDHORZ, 0, 165, 317, 1 + DEFPUSHBUTTON "&Sekva", IDOK, 205, 172, 50, 14 + PUSHBUTTON "&Nuligi", IDCANCEL, 260, 172, 50, 14 +END + +IDD_STARTPAGE DIALOGEX 0, 0, 317, 193 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "ReactOS LiveCD" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "IDB_LOGO", IDC_STARTLOGO, "Static", WS_CHILD | WS_VISIBLE | SS_OWNERDRAW, 18, 4, 290, 99 + DEFPUSHBUTTON "Funkciigi ReactOS &Live CD", IDC_RUN, 71, 108, 175, 21 + PUSHBUTTON "&Instali ReactOS", IDC_INSTALL, 71, 136, 175, 21 + + // LTEXT "", IDC_STATIC, 7, 152, 300, 8 + + CONTROL "", IDC_STATIC, "STATIC", SS_ETCHEDHORZ, 0, 165, 317, 1 + PUSHBUTTON "&Antaŭa", IDOK, 205, 172, 50, 14 + PUSHBUTTON "&Nuligi", IDCANCEL, 260, 172, 50, 14 +END + +STRINGTABLE +BEGIN + IDS_SHELL_FAIL "Userinit malsukcesis startigi la ŝelon!" + IDS_INSTALLER_FAIL "Userinit malsukcesis startigi la instalilon!" + IDS_CANCEL_CONFIRM "Ĉu vi certas, ke vi volas foriri el ReactOS LiveCD?\nSe vi elektas tion, via komputilo povas restarti." +END + +STRINGTABLE +BEGIN + IDS_SPAIN "Hispana (Hispanio)" +END diff --git a/base/system/userinit/userinit.rc b/base/system/userinit/userinit.rc index c0c7fb917fedc..679b0a8dbeead 100644 --- a/base/system/userinit/userinit.rc +++ b/base/system/userinit/userinit.rc @@ -32,6 +32,9 @@ IDB_ROSMASK BITMAP "res/rosbitmap_mask.bmp" #ifdef LANGUAGE_EN_US #include "lang/en-US.rc" #endif +#ifdef LANGUAGE_EO_AA + #include "lang/eo-AA.rc" +#endif #ifdef LANGUAGE_ES_ES #include "lang/es-ES.rc" #endif diff --git a/base/system/winlogon/sas.c b/base/system/winlogon/sas.c index c9675ba314de9..17c7778e13aeb 100644 --- a/base/system/winlogon/sas.c +++ b/base/system/winlogon/sas.c @@ -46,6 +46,12 @@ static BOOL ExitReactOSInProgress = FALSE; LUID LuidNone = {0, 0}; +typedef struct tagLOGON_SOUND_DATA +{ + HANDLE UserToken; + BOOL IsStartup; +} LOGON_SOUND_DATA, *PLOGON_SOUND_DATA; + /* FUNCTIONS ****************************************************************/ static BOOL @@ -285,11 +291,13 @@ PlaySoundRoutine( return Ret; } +static DWORD WINAPI PlayLogonSoundThread( - IN LPVOID lpParameter) + _In_ LPVOID lpParameter) { + PLOGON_SOUND_DATA SoundData = (PLOGON_SOUND_DATA)lpParameter; SERVICE_STATUS_PROCESS Info; DWORD dwSize; ULONG Index = 0; @@ -300,7 +308,7 @@ PlayLogonSoundThread( if (!hSCManager) { ERR("OpenSCManager failed (%x)\n", GetLastError()); - return 0; + goto Cleanup; } /* Open the wdmaud service */ @@ -310,7 +318,7 @@ PlayLogonSoundThread( /* The service is not installed */ TRACE("Failed to open wdmaud service (%x)\n", GetLastError()); CloseServiceHandle(hSCManager); - return 0; + goto Cleanup; } /* Wait for wdmaud to start */ @@ -336,44 +344,65 @@ PlayLogonSoundThread( if (Info.dwCurrentState != SERVICE_RUNNING) { WARN("wdmaud has not started!\n"); - return 0; + goto Cleanup; } /* Sound subsystem is running. Play logon sound. */ - TRACE("Playing logon sound\n"); - if (!ImpersonateLoggedOnUser((HANDLE)lpParameter)) + TRACE("Playing %s sound\n", SoundData->IsStartup ? "startup" : "logon"); + if (!ImpersonateLoggedOnUser(SoundData->UserToken)) { ERR("ImpersonateLoggedOnUser failed (%x)\n", GetLastError()); } else { - PlaySoundRoutine(L"WindowsLogon", TRUE, SND_ALIAS | SND_NODEFAULT); + PlaySoundRoutine(SoundData->IsStartup ? L"SystemStart" : L"WindowsLogon", + TRUE, + SND_ALIAS | SND_NODEFAULT); RevertToSelf(); } + +Cleanup: + HeapFree(GetProcessHeap(), 0, SoundData); return 0; } static VOID PlayLogonSound( - IN OUT PWLSESSION Session) + _In_ PWLSESSION Session) { + PLOGON_SOUND_DATA SoundData; HANDLE hThread; - hThread = CreateThread(NULL, 0, PlayLogonSoundThread, (PVOID)Session->UserToken, 0, NULL); - if (hThread) - CloseHandle(hThread); + SoundData = HeapAlloc(GetProcessHeap(), 0, sizeof(LOGON_SOUND_DATA)); + if (!SoundData) + return; + + SoundData->UserToken = Session->UserToken; + SoundData->IsStartup = IsFirstLogon(Session); + + hThread = CreateThread(NULL, 0, PlayLogonSoundThread, SoundData, 0, NULL); + if (!hThread) + { + HeapFree(GetProcessHeap(), 0, SoundData); + return; + } + CloseHandle(hThread); } static VOID -PlayLogoffSound( - _In_ PWLSESSION Session) +PlayLogoffShutdownSound( + _In_ PWLSESSION Session, + _In_ BOOL bShutdown) { if (!ImpersonateLoggedOnUser(Session->UserToken)) return; - PlaySoundRoutine(L"WindowsLogoff", FALSE, SND_ALIAS | SND_NODEFAULT); + /* NOTE: Logoff and shutdown sounds play synchronously */ + PlaySoundRoutine(bShutdown ? L"SystemExit" : L"WindowsLogoff", + FALSE, + SND_ALIAS | SND_NODEFAULT); RevertToSelf(); } @@ -549,6 +578,9 @@ HandleLogon( /* Logon has succeeded. Play sound. */ PlayLogonSound(Session); + /* NOTE: The logon timestamp has to be set after calling PlayLogonSound + * to correctly detect the startup event (first logon) */ + SetLogonTimestamp(Session); ret = TRUE; cleanup: @@ -786,8 +818,8 @@ DestroyLogoffSecurityAttributes( static NTSTATUS HandleLogoff( - IN OUT PWLSESSION Session, - IN UINT Flags) + _Inout_ PWLSESSION Session, + _In_ DWORD wlxAction) { PLOGOFF_SHUTDOWN_DATA LSData; PSECURITY_ATTRIBUTES psa; @@ -802,7 +834,13 @@ HandleLogoff( ERR("Failed to allocate mem for thread data\n"); return STATUS_NO_MEMORY; } - LSData->Flags = Flags; + + LSData->Flags = EWX_LOGOFF; + if (wlxAction == WLX_SAS_ACTION_FORCE_LOGOFF) + { + LSData->Flags |= EWX_FORCE; + } + LSData->Session = Session; Status = CreateLogoffSecurityAttributes(&psa); @@ -842,7 +880,7 @@ HandleLogoff( SwitchDesktop(Session->WinlogonDesktop); - PlayLogoffSound(Session); + PlayLogoffShutdownSound(Session, WLX_SHUTTINGDOWN(wlxAction)); SetWindowStationUser(Session->InteractiveWindowStation, &LuidNone, NULL, 0); @@ -1065,12 +1103,9 @@ DoGenericAction( case WLX_SAS_ACTION_SHUTDOWN_REBOOT: /* 0x0b */ if (Session->LogonState != STATE_LOGGED_OFF) { - UINT LogOffFlags = EWX_LOGOFF; - if (wlxAction == WLX_SAS_ACTION_FORCE_LOGOFF) - LogOffFlags |= EWX_FORCE; if (!Session->Gina.Functions.WlxIsLogoffOk(Session->Gina.Context)) break; - if (!NT_SUCCESS(HandleLogoff(Session, LogOffFlags))) + if (!NT_SUCCESS(HandleLogoff(Session, wlxAction))) { RemoveStatusMessage(Session); break; diff --git a/base/system/winlogon/winlogon.h b/base/system/winlogon/winlogon.h index 3dcf6fda0c339..066749597e764 100644 --- a/base/system/winlogon/winlogon.h +++ b/base/system/winlogon/winlogon.h @@ -41,6 +41,7 @@ #include #include #include +#include #include /* PSEH for SEH Support */ @@ -134,7 +135,7 @@ typedef struct _GINAINSTANCE /* * The picture Microsoft is trying to paint here - * (http://msdn.microsoft.com/en-us/library/windows/desktop/aa380547%28v=vs.85%29.aspx) + * (https://learn.microsoft.com/en-us/windows/win32/secauthn/winlogon-states) * about the Winlogon states is a little too simple. * * The real picture should look more like this: @@ -233,6 +234,7 @@ typedef struct _WLSESSION HANDLE hProfileInfo; LOGON_STATE LogonState; DWORD DialogTimeout; /* Timeout for dialog boxes, in seconds */ + LARGE_INTEGER LastLogon; /* Screen-saver informations */ #ifndef USE_GETLASTINPUTINFO @@ -285,6 +287,23 @@ extern PWLSESSION WLSession; ((Status) == WLX_SAS_ACTION_SHUTDOWN_HIBERNATE) \ ) +FORCEINLINE +VOID +SetLogonTimestamp( + _Inout_ PWLSESSION Session) +{ + NtQuerySystemTime(&Session->LastLogon); +} + +FORCEINLINE +BOOL +IsFirstLogon( + _In_ PWLSESSION Session) +{ + /* The WLSESSION::LastLogon is initialized to 0 so this is OK */ + return (Session->LastLogon.QuadPart == 0); +} + /* environment.c */ BOOL CreateUserEnvironment(IN PWLSESSION Session); diff --git a/boot/bootdata/bootcd/unattend.inf b/boot/bootdata/bootcd/unattend.inf index ec41adcc97bd7..3dcffae4cd5f2 100644 --- a/boot/bootdata/bootcd/unattend.inf +++ b/boot/bootdata/bootcd/unattend.inf @@ -59,16 +59,12 @@ LocaleID = 409 ; 1: ReactOS Workstation ProductOption = 0 -; enable this section to automatically launch programs +; Enable this section to automatically launch programs ; after 3rd boot -; ; [GuiRunOnce] ; %SystemRoot%\system32\cmd.exe -; Enable the next line (+ the GuiRunOnce section) to enable the lautus theme -; "rundll32.exe shell32.dll,Control_RunDLL desk.cpl desk,@Appearance /Action:ActivateMSTheme /file:%SYSTEMROOT%\Resources\themes\lautus\lautus.msstyles" - -; enable this section to change resolution / bpp +; Enable this section to change resolution / bpp ; setting a value to 0 or skipping it will leave it unchanged ; [Display] ; BitsPerPel = 32 @@ -80,3 +76,8 @@ ProductOption = 0 ;[Env] ;WINETEST_PLATFORM=reactos +; Enable this section to enable the default ReactOS theme +; [Shell] +; DefaultThemesOff = no +; CustomDefaultThemeFile = "%WINDIR%\Resources\Themes\Lautus\lautus.msstyles" + diff --git a/boot/bootdata/hivedef.inf b/boot/bootdata/hivedef.inf index 6ca744345cc69..6f4b78d8ab6d4 100644 --- a/boot/bootdata/hivedef.inf +++ b/boot/bootdata/hivedef.inf @@ -2076,14 +2076,14 @@ HKCU,"AppEvents\Schemes\Apps\.Default\SystemQuestion",,0x00000012 HKCU,"AppEvents\Schemes\Apps\.Default\SystemQuestion\.Current","",0x00020000,"" HKCU,"AppEvents\Schemes\Apps\.Default\SystemQuestion\.Default","",0x00020000,"" HKCU,"AppEvents\Schemes\Apps\.Default\SystemStart",,0x00000012 -HKCU,"AppEvents\Schemes\Apps\.Default\SystemStart\.Current","",0x00020000,"" -HKCU,"AppEvents\Schemes\Apps\.Default\SystemStart\.Default","",0x00020000,"" +HKCU,"AppEvents\Schemes\Apps\.Default\SystemStart\.Current","",0x00020000,"%SystemRoot%\media\ReactOS_Startup.wav" +HKCU,"AppEvents\Schemes\Apps\.Default\SystemStart\.Default","",0x00020000,"%SystemRoot%\media\ReactOS_Startup.wav" HKCU,"AppEvents\Schemes\Apps\.Default\WindowsLogoff",,0x00000012 HKCU,"AppEvents\Schemes\Apps\.Default\WindowsLogoff\.Current","",0x00020000,"" HKCU,"AppEvents\Schemes\Apps\.Default\WindowsLogoff\.Default","",0x00020000,"" HKCU,"AppEvents\Schemes\Apps\.Default\WindowsLogon",,0x00000012 -HKCU,"AppEvents\Schemes\Apps\.Default\WindowsLogon\.Current","",0x00020000,"%SystemRoot%\media\ReactOS_LogOn.wav" -HKCU,"AppEvents\Schemes\Apps\.Default\WindowsLogon\.Default","",0x00020000,"%SystemRoot%\media\ReactOS_LogOn.wav" +HKCU,"AppEvents\Schemes\Apps\.Default\WindowsLogon\.Current","",0x00020000,"" +HKCU,"AppEvents\Schemes\Apps\.Default\WindowsLogon\.Default","",0x00020000,"" HKCU,"AppEvents\Schemes\Apps\Explorer","",0x00000002,"ReactOS Explorer" HKCU,"AppEvents\Schemes\Apps\Explorer","DispFileName",0x00000000,"@mmsys.cpl,-5854" HKCU,"AppEvents\Schemes\Apps\Explorer\EmptyRecycleBin",,0x00000012 diff --git a/boot/bootdata/hivesys.inf b/boot/bootdata/hivesys.inf index bcd2bda1e164d..d96762c2efa13 100644 --- a/boot/bootdata/hivesys.inf +++ b/boot/bootdata/hivesys.inf @@ -1100,7 +1100,7 @@ HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","040a",0x00000000,"l_intl.n HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","080a",0x00000000,"l_intl.nls" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","0c0a",0x00000000,"l_intl.nls" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","100a",0x00000000,"l_intl.nls" -;HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","140a",0x00000000,"l_intl.nls" +HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","140a",0x00000000,"l_intl.nls" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","180a",0x00000000,"l_intl.nls" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","1c0a",0x00000000,"l_intl.nls" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","200a",0x00000000,"l_intl.nls" @@ -1150,7 +1150,7 @@ HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","041d",0x00000000,"l_intl.n HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","081d",0x00000000,"l_intl.nls" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","041e",0x00000000,"l_intl.nls" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","041f",0x00000000,"l_intl.nls" -;HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","0420",0x00000000,"l_intl.nls" +HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","0420",0x00000000,"l_intl.nls" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","0421",0x00000000,"l_intl.nls" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","0422",0x00000000,"l_intl.nls" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","0423",0x00000000,"l_intl.nls" @@ -1158,15 +1158,15 @@ HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","0424",0x00000000,"l_intl.n HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","0425",0x00000000,"l_intl.nls" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","0426",0x00000000,"l_intl.nls" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","0427",0x00000000,"l_intl.nls" -;HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","0429",0x00000000,"l_intl.nls" -;HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","042a",0x00000000,"l_intl.nls" +HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","0429",0x00000000,"l_intl.nls" +HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","042a",0x00000000,"l_intl.nls" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","042b",0x00000000,"l_intl.nls" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","042c",0x00000000,"l_intl.nls" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","082c",0x00000000,"l_intl.nls" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","042d",0x00000000,"l_intl.nls" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","042f",0x00000000,"l_intl.nls" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","0436",0x00000000,"l_intl.nls" -;HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","0437",0x00000000,"l_intl.nls" +HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","0437",0x00000000,"l_intl.nls" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","0438",0x00000000,"l_intl.nls" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","0439",0x00000000,"l_intl.nls" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","043e",0x00000000,"l_intl.nls" @@ -1178,7 +1178,7 @@ HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","0443",0x00000000,"l_intl.n HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","0843",0x00000000,"l_intl.nls" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","0444",0x00000000,"l_intl.nls" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","0445",0x00000000,"l_intl.nls" -;HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","0455",0x00000000,"l_intl.nls" +HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","0455",0x00000000,"l_intl.nls" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","0456",0x00000000,"l_intl.nls" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","048f",0x00000000,"l_intl.nls" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","0490",0x00000000,"l_intl.nls" @@ -1189,26 +1189,30 @@ HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language","InstallLanguage",0x0000000 ; Supported and installed locales ; If you add/uncomment an entry here, please also add the appropriate Language ; in the previous section. +; See also: https://www.venea.net/web/culture-code +; https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-lcid/70feba9f-294e-491e-b6eb-56532684c37f HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale",,0x00000012 -HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000401",0x00000000,"" -HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000801",0x00000000,"" -HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000c01",0x00000000,"" -HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00001001",0x00000000,"" -HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00001401",0x00000000,"" -HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00001801",0x00000000,"" -HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00001c01",0x00000000,"" -HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00002001",0x00000000,"" -HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00002401",0x00000000,"" -HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00002801",0x00000000,"" -HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00002c01",0x00000000,"" -HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00003001",0x00000000,"" -HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00003401",0x00000000,"" -HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00003801",0x00000000,"" -HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00003c01",0x00000000,"" -HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00004001",0x00000000,"" +HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000401",0x00000000,"d" +HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000801",0x00000000,"d" +HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000c01",0x00000000,"d" +HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00001001",0x00000000,"d" +HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00001401",0x00000000,"d" +HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00001801",0x00000000,"d" +HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00001c01",0x00000000,"d" +HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00002001",0x00000000,"d" +HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00002401",0x00000000,"d" +HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00002801",0x00000000,"d" +HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00002c01",0x00000000,"d" +HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00003001",0x00000000,"d" +HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00003401",0x00000000,"d" +HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00003801",0x00000000,"d" +HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00003c01",0x00000000,"d" +HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00004001",0x00000000,"d" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000402",0x00000000,"5" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000403",0x00000000,"1" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000404",0x00000000,"9" +HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000c04",0x00000000,"9" +HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00001004",0x00000000,"a" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000804",0x00000000,"a" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000405",0x00000000,"2" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000406",0x00000000,"1" @@ -1231,7 +1235,7 @@ HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","0000040a",0x00000000,"1" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","0000080a",0x00000000,"1" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000c0a",0x00000000,"1" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","0000100a",0x00000000,"1" -;HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","0000140a",0x00000000,"1" +HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","0000140a",0x00000000,"1" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","0000180a",0x00000000,"1" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00001c0a",0x00000000,"1" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","0000200a",0x00000000,"1" @@ -1268,7 +1272,7 @@ HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000814",0x00000000,"1" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000415",0x00000000,"2" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000416",0x00000000,"1" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000816",0x00000000,"1" -;HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000417",0x00000000,"1" +HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000417",0x00000000,"1" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000418",0x00000000,"2" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000419",0x00000000,"5" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","0000041a",0x00000000,"2" @@ -1280,7 +1284,7 @@ HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","0000041d",0x00000000,"1" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","0000081d",0x00000000,"1" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","0000041e",0x00000000,"b" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","0000041f",0x00000000,"6" -;HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000420",0x00000000,"" +HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000420",0x00000000,"d" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000421",0x00000000,"1" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000422",0x00000000,"5" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000423",0x00000000,"5" @@ -1288,15 +1292,15 @@ HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000424",0x00000000,"2" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000425",0x00000000,"3" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000426",0x00000000,"3" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000427",0x00000000,"3" -;HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000429",0x00000000,"" -;HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","0000042a",0x00000000,"" +HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000429",0x00000000,"d" +HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","0000042a",0x00000000,"e" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","0000042b",0x00000000,"11" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","0000042c",0x00000000,"6" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","0000082c",0x00000000,"5" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","0000042d",0x00000000,"1" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","0000042f",0x00000000,"5" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000436",0x00000000,"1" -;HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000437",0x00000000,"10" +HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000437",0x00000000,"10" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000438",0x00000000,"1" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000439",0x00000000,"f" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","0000043e",0x00000000,"1" @@ -1307,11 +1311,11 @@ HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000441",0x00000000,"1" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000443",0x00000000,"6" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000843",0x00000000,"5" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000444",0x00000000,"5" -;HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000445",0x00000000,"f" -;HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000455",0x00000000,"" +HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000445",0x00000000,"f" +HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000455",0x00000000,"1" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000456",0x00000000,"1" -;HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","0000048f",0x00000000,"1" -;HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000490",0x00000000,"1" +;HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","0000048f",0x00000000,"1" ; tdd-Tale-CN, reserved +;HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Locale","00000490",0x00000000,"1" ; khb-Talu-CN, reserved HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language Groups","1",0x00000000,"1" HKLM,"SYSTEM\CurrentControlSet\Control\Nls\Language Groups","2",0x00000000,"1" @@ -1735,13 +1739,6 @@ HKLM,"SYSTEM\CurrentControlSet\Services\NMIDebug","ImagePath",0x00020000,"system HKLM,"SYSTEM\CurrentControlSet\Services\NMIDebug","Start",0x00010001,0x00000000 HKLM,"SYSTEM\CurrentControlSet\Services\NMIDebug","Type",0x00010001,0x00000001 -; NDIS User I/O driver (FIXME: Should be installed via INF and started on demand) -HKLM,"SYSTEM\CurrentControlSet\Services\Ndisuio","ErrorControl",0x00010001,0x00000001 -HKLM,"SYSTEM\CurrentControlSet\Services\Ndisuio","Group",0x00000000,"NDIS" -HKLM,"SYSTEM\CurrentControlSet\Services\Ndisuio","ImagePath",0x00020000,"system32\drivers\ndisuio.sys" -HKLM,"SYSTEM\CurrentControlSet\Services\Ndisuio","Start",0x00010001,0x00000001 -HKLM,"SYSTEM\CurrentControlSet\Services\Ndisuio","Type",0x00010001,0x00000001 - ; Packet driver HKLM,"SYSTEM\CurrentControlSet\Services\Packet","ErrorControl",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\Packet","Group",0x00000000,"PNP_TDI" diff --git a/boot/environ/include/bcd.h b/boot/environ/include/bcd.h index d0b8641cd3a46..b86389f39683e 100644 --- a/boot/environ/include/bcd.h +++ b/boot/environ/include/bcd.h @@ -11,7 +11,7 @@ /* ENUMERATIONS **************************************************************/ -/* See https://msdn.microsoft.com/en-us/library/windows/desktop/aa964229(v=vs.85).aspx */ +/* See https://learn.microsoft.com/en-us/previous-versions/windows/desktop/bcd/bcdelementtype */ #define BCD_CLASS_LIBRARY 0x01 #define BCD_CLASS_APPLICATION 0x02 diff --git a/boot/freeldr/bootsect/CMakeLists.txt b/boot/freeldr/bootsect/CMakeLists.txt index a46c9066c6a8f..986d399d13e63 100644 --- a/boot/freeldr/bootsect/CMakeLists.txt +++ b/boot/freeldr/bootsect/CMakeLists.txt @@ -4,7 +4,8 @@ include_directories(${REACTOS_SOURCE_DIR}/boot/freeldr) if(ARCH STREQUAL "i386" OR ARCH STREQUAL "amd64") CreateBootSectorTarget(dosmbr ${CMAKE_CURRENT_SOURCE_DIR}/dosmbr.S ${CMAKE_CURRENT_BINARY_DIR}/dosmbr.bin 7c00) - CreateBootSectorTarget(ext2 ${CMAKE_CURRENT_SOURCE_DIR}/ext2.S ${CMAKE_CURRENT_BINARY_DIR}/ext2.bin 0) + CreateBootSectorTarget(ext ${CMAKE_CURRENT_SOURCE_DIR}/ext.S ${CMAKE_CURRENT_BINARY_DIR}/ext.bin 7c00) + CreateBootSectorTarget(extldr ${CMAKE_CURRENT_SOURCE_DIR}/extldr.S ${CMAKE_CURRENT_BINARY_DIR}/extldr.sys 8000) CreateBootSectorTarget(fat ${CMAKE_CURRENT_SOURCE_DIR}/fat.S ${CMAKE_CURRENT_BINARY_DIR}/fat.bin 7c00) CreateBootSectorTarget(fat32 ${CMAKE_CURRENT_SOURCE_DIR}/fat32.S ${CMAKE_CURRENT_BINARY_DIR}/fat32.bin 7c00) @@ -31,7 +32,8 @@ if(ARCH STREQUAL "i386" OR ARCH STREQUAL "amd64") CreateBootSectorTarget(isombr ${CMAKE_CURRENT_SOURCE_DIR}/isombr.S ${CMAKE_CURRENT_BINARY_DIR}/isombr.bin 7000) add_cd_file(TARGET dosmbr DESTINATION loader NO_CAB FILE ${CMAKE_CURRENT_BINARY_DIR}/dosmbr.bin FOR bootcd regtest) - add_cd_file(TARGET ext2 DESTINATION loader NO_CAB FILE ${CMAKE_CURRENT_BINARY_DIR}/ext2.bin FOR bootcd regtest) + add_cd_file(TARGET ext DESTINATION loader NO_CAB FILE ${CMAKE_CURRENT_BINARY_DIR}/ext.bin FOR bootcd regtest) + add_cd_file(TARGET extldr DESTINATION loader NO_CAB FILE ${CMAKE_CURRENT_BINARY_DIR}/extldr.sys FOR bootcd regtest) add_cd_file(TARGET btrfsvbr DESTINATION loader NO_CAB FILE ${CMAKE_CURRENT_BINARY_DIR}/btrfs.bin FOR bootcd regtest) add_cd_file(TARGET fat DESTINATION loader NO_CAB FILE ${CMAKE_CURRENT_BINARY_DIR}/fat.bin FOR bootcd regtest) add_cd_file(TARGET fat32 DESTINATION loader NO_CAB FILE ${CMAKE_CURRENT_BINARY_DIR}/fat32.bin FOR bootcd regtest) diff --git a/boot/freeldr/bootsect/ext.S b/boot/freeldr/bootsect/ext.S new file mode 100644 index 0000000000000..f0c35ea520c67 --- /dev/null +++ b/boot/freeldr/bootsect/ext.S @@ -0,0 +1,726 @@ +/* + * PROJECT: FreeLoader + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: EXTFS volume boot sector + * COPYRIGHT: Copyright 2002-2003 Brian Palmer + * Copyright 2024-2025 Daniel Victor + */ + +#include +#include + +// Boot sector constants +#define BOOTSECTOR_BASE_ADDRESS HEX(7C00) +#define EXTLDR_BOOTSECTOR_SIZE 1024 +#define EXT_POINTER_SIZE 4 +#define EXT_EXTENT_SIZE 12 + +// Maximum extent values +#define EXT_EXTENT_MAX_LEVEL 5 +#define EXT_EXTENT_MAX_LENGTH 32768 + +// Group descriptor offsets +#define EXT_GROUP_DESC_INODE_TABLE_OFFSET 8 + +// Extent offsets +#define EXT_EXTENT_HEADER_ENTRIES_OFFSET 2 +#define EXT_EXTENT_HEADER_DEPTH_OFFSET 6 +#define EXT_EXTENT_INDEX_LEAF_OFFSET 4 +#define EXT_EXTENT_LENGTH_OFFSET 4 +#define EXT_EXTENT_START_OFFSET 8 + +// Inode offsets +#define EXT_INODE_SIZE_OFFSET 4 +#define EXT_INODE_FLAGS_OFFSET 32 +#define EXT_INODE_BLOCK_POINTER_OFFSET 40 + +// Directory entry offsets +#define EXT_DIRECTORY_ENTRY_SIZE_OFFSET 4 +#define EXT_DIRECTORY_ENTRY_NAME_LENGTH_OFFSET 6 +#define EXT_DIRECTORY_ENTRY_NAME_OFFSET 8 + +// Inode flags +#define EXT_INODE_FLAG_EXTENTS HEX(80000) + +// Inode blocks constants +#define EXT_INODE_BLOCKS 12 +#define EXT_INODE_INDIRECT_BLOCKS 3 + +// Root Inode +#define EXT_ROOT_INODE 2 + +// Inode address +#define EXT_INODE_ADDRESS HEX(9000) + +// Data block addresses +#define EXT_BLOCK_ADDRESS HEX(1000) +#define EXT_BLOCK2_ADDRESS HEX(2000) +#define EXT_BLOCK3_ADDRESS HEX(3000) +#define EXT_BLOCK4_ADDRESS HEX(4000) +#define EXT_BLOCK5_ADDRESS HEX(5000) +#define EXT_BLOCK6_ADDRESS HEX(6000) +#define EXT_BLOCK7_ADDRESS HEX(A000) + +// Inode types +#define EXT_INODE_TYPE_MASK HEX(F000) +#define EXT_INODE_TYPE_REGULAR HEX(8000) + +// File size limit +#define EXT_INODE_DATA_SIZE_LIMIT HEX(F000) + +// Offset of functions addresses that will be used by the extldr.sys 3rd-stage bootsector +#define ExtReadBlockOffset 2 +#define ExtReadInodeOffset 4 +#define DisplayItAndRebootOffset 6 +#define PutCharsOffset 8 + +// Boot sector stack constants +#define BOOTSECTOR_STACK_TEMP_VARIABLES 2 +#define BOOTSECTOR_STACK_TEMP_VARIABLES_SIZE (4 * BOOTSECTOR_STACK_TEMP_VARIABLES) +#define BOOTSECTOR_STACK_OFFSET (8 + BOOTSECTOR_STACK_TEMP_VARIABLES_SIZE) +#define BOOTSECTOR_STACK_BASE (BOOTSECTOR_BASE_ADDRESS - BOOTSECTOR_STACK_OFFSET) +#define BP_REL(x) ss:[bp + (x - BOOTSECTOR_BASE_ADDRESS)] + +// Temporary variables +#define ExtFileSizeState ((BOOTSECTOR_STACK_BASE + BOOTSECTOR_STACK_TEMP_VARIABLES_SIZE) - 4) +#define LBASectorsRead (ExtFileSizeState - 4) + +.code16 + +#ifndef INCLUDED_ASM + +start: + jmp short main + nop + +// Fields that will be changed by the installer +BootDrive: + .byte HEX(FF) +ExtVolumeStartSector: + .long 263088 // Start sector of the ext2 volume +ExtBlockSize: + .long 2 // Block size in sectors +ExtBlockSizeInBytes: + .long 1024 // Block size in bytes +ExtPointersPerBlock: + .long 256 // Number of block pointers that can be contained in one block +ExtGroupDescSize: + .long 32 // Size of Group Descriptor +ExtFirstDataBlock: + .long 2 // First data block (2 for 1024-byte blocks, 1 for bigger sizes) +ExtInodeSize: + .long 128 // Size of Inode +ExtInodesPerGroup: + .long 2048 // Number of inodes per group + +// File variables +ExtFileSize: + .long 0 // File size in bytes +ExtFileAddress: + .long FREELDR_BASE // File address +ExtFileAddressOld: + .long FREELDR_BASE // Old file address + +// Inode variables +ExtReadInodeGroup: + .long 0 +ExtReadInodeIndex: + .long 0 +ExtReadInodeGroupBlock: + .long 0 +ExtReadInodeIndexBlock: + .long 0 +ExtReadInodeGroupOffset: + .word 0 +ExtReadInodeIndexOffset: + .word 0 + +main: + xor ax, ax // Setup segment registers + mov ds, ax // Make DS correct + mov es, ax // Make ES correct + mov ss, ax // Make SS correct + mov bp, BOOTSECTOR_BASE_ADDRESS + mov sp, bp // Setup a stack + sub sp, BOOTSECTOR_STACK_OFFSET + + // Save the function addresses so the helper code knows where to call them + mov word ptr ss:[bp-ExtReadBlockOffset], offset ExtReadBlock + mov word ptr ss:[bp-ExtReadInodeOffset], offset ExtReadInode + mov word ptr ss:[bp-DisplayItAndRebootOffset], offset DisplayItAndReboot + mov word ptr ss:[bp-PutCharsOffset], offset PutChars + + mov si, offset BootDrive + cmp byte ptr [si], HEX(0ff) // If they have specified a boot drive then use it + jne CheckInt13hExtensions + + mov byte ptr [si], dl // Save the boot drive + +// Now check if this computer supports extended reads. This boot sector will not work without it. +CheckInt13hExtensions: + mov ah, HEX(41) // AH = 41h + mov bx, HEX(55aa) // BX = 55AAh + int HEX(13) // IBM/MS INT 13 Extensions - INSTALLATION CHECK + jc PrintDiskError // CF set on error (extensions not supported) + cmp bx, HEX(aa55) // BX = AA55h if installed + jne PrintDiskError + test cl, 1 // si = API subset support bitmap + jz PrintDiskError // Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported + +LoadExtraBootCode: + // First we have to load our extra boot code at + // sector 1 into memory at [0000:7e00h] + xor eax, eax + inc eax + mov cx, 1 + xor bx, bx + mov es, bx // Read sector to [0000:7e00h] + mov bx, HEX(7e00) + call ReadSectors + + jmp LoadRootDirectory + +// Reads logical sectors into ES:[BX] +// EAX has logical sector number to read +// CX has number of sectors to read +ReadSectors: + push es + add eax, dword ptr BP_REL(ExtVolumeStartSector) // Add the start of the volume + // If at all possible we want to use LBA routines because + // they are optimized to read more than 1 sector per read + +ReadSectorsLBA: + pushad // Save logical sector number & sector count + + cmp cx, 64 // Since the LBA calls only support 0x7F sectors at a time we will limit ourselves to 64 + jbe ReadSectorsSetupDiskAddressPacket // If we are reading less than 65 sectors then just do the read + mov cx, 64 // Otherwise read only 64 sectors on this loop iteration + +ReadSectorsSetupDiskAddressPacket: + movzx ecx, cx + mov dword ptr BP_REL(LBASectorsRead), ecx + data32 push 0 + push eax // Put 64-bit logical block address on stack + push es // Put transfer segment on stack + push bx // Put transfer offset on stack + push cx // Set transfer count + push 16 // Set size of packet to 10h + mov si, sp // Setup disk address packet on stack + + mov dl, byte ptr BP_REL(BootDrive) // Drive number + mov ah, HEX(42) // Int 13h, AH = 42h - Extended Read + int HEX(13) // Call BIOS + jc PrintDiskError // If the read failed then abort + + add sp, 16 // Remove disk address packet from stack + + popad // Restore sector count & logical sector number + + push bx + mov ebx, dword ptr BP_REL(LBASectorsRead) + add eax, ebx // Increment sector to read + shl ebx, 5 + mov dx, es + add dx, bx // Setup read buffer for next sector + mov es, dx + pop bx + + sub cx, word ptr BP_REL(LBASectorsRead) + jnz ReadSectorsLBA // Read next sector + + pop es + ret + +// Displays a disk error message +// And reboots +PrintDiskError: + mov si, offset msgDiskError // Bad boot disk message + call PutChars // Display it + +Reboot: + mov si, offset msgAnyKey // Press any key message + call PutChars // Display it + xor ax, ax + int HEX(16) // Wait for a keypress + int HEX(19) // Reboot + +.PutCharsLoop: + mov ah, HEX(0E) + mov bx, 7 + int HEX(10) +PutChars: + lodsb + or al, al + jnz .PutCharsLoop + ret + +SwapESWithDS: + // Swap ES and DS + push es + push ds + pop es + pop ds + ret + +ExtReadGroupDescriptor: + mov eax, dword ptr BP_REL(ExtReadInodeGroupBlock) // Get Inode group block + add eax, dword ptr BP_REL(ExtFirstDataBlock) // Add the Group Descriptor offset + call ExtSetInodeSegment + +ExtReadBlock: + xor edx, edx + mov ecx, dword ptr BP_REL(ExtBlockSize) + mul ecx + jmp ReadSectors + +// EAX +ExtCalculateBlock: + xor edx, edx // Clear EDX before division + div dword ptr BP_REL(ExtBlockSizeInBytes) // Inode /= ExtBlockSizeInBytes + mov dword ptr ds:[bp + si], eax // Store the Inode block + ret + +// SI, DI +ExtCalculateOffset: + add bx, bp // Sum BX with BP for absolute address + xor edx, edx // Clear EDX before multiplication + mov eax, dword ptr ds:[bp + si] // Get the Inode block + mul dword ptr BP_REL(ExtBlockSizeInBytes) // Inode *= ExtBlockSizeInBytes + mov ecx, dword ptr ds:[bx] // Get the Inode + sub ecx, eax // Subtract the original Inode with rounded down Inode + mov word ptr ds:[bp + di], cx // Store the rounded down Inode + ret + +ExtSetOldFileSegment: + mov ebx, dword ptr BP_REL(ExtFileAddressOld) // Get the EXT old file address + jmp .ExtSegSkip +ExtSetFileSegment: + mov ebx, dword ptr BP_REL(ExtFileAddress) // Get the EXT file address +.ExtSegSkip: + shr ebx, 4 // Shift four bits to the right to get segment + jmp .ExtSkip +ExtSetInodeSegment: + mov bx, EXT_INODE_ADDRESS / 16 // Get the EXT inode address +.ExtSkip: + mov es, bx // Set ES + xor bx, bx // Clear BX + ret + +// Read the Inode in EAX register +ExtReadInode: + xor edx, edx // Clear EDX before division + dec eax // Inode-- + div dword ptr BP_REL(ExtInodesPerGroup) // Inode /= ExtInodesPerGroup + mov dword ptr BP_REL(ExtReadInodeGroup), eax // Store the Inode group + mov dword ptr BP_REL(ExtReadInodeIndex), edx // Store the Inode index + + xor edx, edx // Clear EDX before multiplication + mul dword ptr BP_REL(ExtGroupDescSize) // Inode group *= ExtGroupDescSize + mov dword ptr BP_REL(ExtReadInodeGroup), eax // Store the precalculated Inode group + + xor edx, edx // Clear EDX before multiplication + mov eax, dword ptr BP_REL(ExtReadInodeIndex) // Get the read Inode index + mul dword ptr BP_REL(ExtInodeSize) // Inode group *= ExtInodeSize + mov dword ptr BP_REL(ExtReadInodeIndex), eax // Store the Inode index + + // Calculate the Inode index block + mov si, offset ExtReadInodeIndexBlock - start + call ExtCalculateBlock + + // Calculate the Inode group block + mov eax, dword ptr BP_REL(ExtReadInodeGroup) + mov si, offset ExtReadInodeGroupBlock - start + call ExtCalculateBlock + + // Calculate the Inode group offset + mov bx, offset ExtReadInodeGroup - start + mov si, offset ExtReadInodeGroupBlock - start + mov di, offset ExtReadInodeGroupOffset - start + call ExtCalculateOffset + + // Calculate the Inode index offset + mov bx, offset ExtReadInodeIndex - start + mov si, offset ExtReadInodeIndexBlock - start + mov di, offset ExtReadInodeIndexOffset - start + call ExtCalculateOffset + + // Read group descriptor + call ExtReadGroupDescriptor + + // Set the offset address + mov si, word ptr BP_REL(ExtReadInodeGroupOffset) + + // Get InodeTable field from the ExtGroupDescriptor structure + mov eax, dword ptr es:[si + EXT_GROUP_DESC_INODE_TABLE_OFFSET] + + // Sum EAX with Inode index block + add eax, dword ptr BP_REL(ExtReadInodeIndexBlock) + + jmp ExtReadBlock + +msgDiskError: + .ascii "Disk error", CR, LF, NUL +msgAnyKey: + .ascii "Press any key", CR, LF, NUL + +.org 509 + +BootPartition: + .byte 0 + +.word HEX(AA55) // BootSector signature + +// End of bootsector +// +// Now starts the extra boot code that we will store +// at sector 1 on a EXT volume + +LoadRootDirectory: + mov al, EXT_ROOT_INODE // Put the root directory inode number in AL + movzx eax, al // Convert AL to EAX + + call ExtReadInode // Read the inode + call BasicReadFile // Load the directory entries using basic function + call SearchFile // Find the extended loader and run it + + jmp ExtLdrPrintFileNotFound // If the extended loader wasn't found, display an error + +ExtInodeDetectExtentsFlag: + mov eax, es:[si + EXT_INODE_FLAGS_OFFSET] + test eax, EXT_INODE_FLAG_EXTENTS + ret + +ExtUpdateFileSize: + mov eax, dword ptr BP_REL(ExtBlockSizeInBytes) + +ExtAdjustFileSize: + // Update the file size + sub dword ptr BP_REL(ExtFileSizeState), eax + add dword ptr BP_REL(ExtFileAddress), eax + ret + +ExtReadFileDone: + push eax + mov eax, dword ptr BP_REL(ExtFileSizeState) + cmp eax, dword ptr BP_REL(ExtBlockSizeInBytes) + pop eax + ret + +ExtFileReadBlocks: + push es +.FRLoop: + // Check if there is no more blocks to read + call ExtReadFileDone + jb .FRDone + + // If the block count is zero then do nothing + test bx, bx + jz .FRDone + + // Read the block + pushad + call ExtSetFileSegment + call ExtReadBlock + popad + + // Update the file size + call ExtUpdateFileSize + + // Go to the next block and decrement the block count + inc eax + dec bx + + // Loop until all blocks are read + jmp .FRLoop +.FRDone: + pop es + ret + +BasicReadFileExtents: + // Add block pointer offset + add si, EXT_INODE_BLOCK_POINTER_OFFSET + +.DepthExtentsLoop: + // Load extent header depth + mov dx, word ptr es:[si + EXT_EXTENT_HEADER_DEPTH_OFFSET] + + // Check if depth is zero + test dx, dx + jz .DepthExtentsDone + + // Go to next extent + add si, EXT_EXTENT_SIZE + + // Push all registers + pushad + + // Read the extent block + mov eax, dword ptr es:[si + EXT_EXTENT_INDEX_LEAF_OFFSET] + call ExtSetInodeSegment + call ExtReadBlock + + // Pop all registers + popad + + // Reset SI + xor si, si + + jmp .DepthExtentsLoop +.DepthExtentsDone: + // Load extent header entries + mov cx, word ptr es:[si + EXT_EXTENT_HEADER_ENTRIES_OFFSET] + +.FinalExtentsLoop: + // Check if there is no more blocks to read + call ExtReadFileDone + jb .FinalExtentsDone + + // Go to next extent + add si, EXT_EXTENT_SIZE + + // Load extent length + mov bx, word ptr es:[si + EXT_EXTENT_LENGTH_OFFSET] + and ebx, HEX(FFFF) + + // Check if extent is sparse + cmp bx, EXT_EXTENT_MAX_LENGTH + jbe .NotSparse + + // Adjust sparse extent length + sub bx, EXT_EXTENT_MAX_LENGTH + + // Adjust extent length to byte count + // by multiplying extent length to block size + xor edx, edx + mov eax, dword ptr BP_REL(ExtBlockSizeInBytes) + mul ebx + + // Adjust file size for sparse extent + call ExtAdjustFileSize + + jmp .FinalExtentsSkip + +.NotSparse: + // Read blocks from extent start + mov eax, dword ptr es:[si + EXT_EXTENT_START_OFFSET] + call ExtFileReadBlocks + +.FinalExtentsSkip: + // Loop to process next extent + loop .FinalExtentsLoop + +.FinalExtentsDone: + ret + +BasicReadFile: + push es + pushad + call ExtSetInodeSegment + + // Set the correct Inode offset + mov si, word ptr BP_REL(ExtReadInodeIndexOffset) + + // Set the old file address + mov eax, dword ptr BP_REL(ExtFileAddress) + mov dword ptr BP_REL(ExtFileAddressOld), eax + + // Set the file size limit + mov eax, EXT_INODE_DATA_SIZE_LIMIT + + // Load file size from Inode + mov ebx, dword ptr es:[si + EXT_INODE_SIZE_OFFSET] + + // Compare and limit file size + cmp ebx, eax + jbe .BelowOrEqualSize + mov ebx, eax +.BelowOrEqualSize: + // Store the file size in the ExtFileSize variable + mov dword ptr BP_REL(ExtFileSize), ebx + + // Set rounded up file size + add ebx, dword ptr BP_REL(ExtBlockSizeInBytes) + dec ebx + mov dword ptr BP_REL(ExtFileSizeState), ebx + + // Don't use the extents method if theres no extents flag + call ExtInodeDetectExtentsFlag + jz .NoExtents + + // If this Inode use Extents mapping then use the extents method and skip the entire classic method + call BasicReadFileExtents + jmp .LDone + +.NoExtents: + // Set up for reading direct block addresses + xor ecx, ecx + mov cl, EXT_INODE_BLOCKS + add si, EXT_INODE_BLOCK_POINTER_OFFSET +.LLoop: + call ExtSetInodeSegment + + call ExtReadFileDone + jb .LDone + + // Get the block address + mov eax, dword ptr es:[si] + + // If the block address is zero, skip the block + test eax, eax + jz .LSkipBlock + + // Set the file segment + call ExtSetFileSegment + + // Read the block + call ExtReadBlock +.LSkipBlock: + call ExtUpdateFileSize + + // Increment block + add si, EXT_POINTER_SIZE + + // Loop until all blocks are loaded + loop .LLoop +.LDone: + popad + pop es + ret + +SearchFile: + call ExtSetOldFileSegment + call SwapESWithDS + + xor si, si + mov dx, word ptr BP_REL(ExtFileSize) +.FLoop: + mov eax, dword ptr ds:[si] // Load directory Inode + + cmp si, dx // End of buffer reached? + jae .Done // Abort the search if yes + + // Save SI + push si + + test eax, eax // Check if Inode is zero + jz .Skip // Skip this entry if yes + + mov di, offset ExtLdrFileName // Load target filename address + mov cx, offset ExtLdrFileNameEnd - ExtLdrFileName // Length of filename to compare + cmp byte ptr ds:[si + EXT_DIRECTORY_ENTRY_NAME_LENGTH_OFFSET], cl // Compare if both names have the same length + jnz .Skip // Skip this entry if not + add si, EXT_DIRECTORY_ENTRY_NAME_OFFSET // Move to filename in entry + repe cmpsb // Compare filenames + pop si // Restore SI + jz LoadExtLdr // Found matching file + push si // Save SI + +.Skip: + // Restore SI + pop si + + // Move to next directory entry and continue looping + add si, word ptr ds:[si + EXT_DIRECTORY_ENTRY_SIZE_OFFSET] + jmp .FLoop +.Done: + ret + +LoadExtLdr: + // Swap ES and DS + call SwapESWithDS + + push si // Save SI + mov si, offset msgLoadingExtLdr // Point SI to a loading message + call PutChars // Show the message + pop si // Restore SI + + mov eax, dword ptr es:[si] // Load directory Inode + call ExtReadInode // Read the inode + mov si, word ptr BP_REL(ExtReadInodeIndexOffset) // Set the correct offset + + // Get Inode type + mov ax, word ptr es:[si] + and ax, EXT_INODE_TYPE_MASK + + cmp ax, EXT_INODE_TYPE_REGULAR // Check if regular file + jnz ExtLdrPrintRegFileError // If not, handle error + + call BasicReadFile // Load the file using basic function + call ExtSetOldFileSegment // Set old file segment + call SwapESWithDS // Swap ES with DS before copy + + // Copy the loaded file to 1KB ahead of this bootsector + xor si, si + mov di, offset ExtLdrEntryPoint + mov cx, EXTLDR_BOOTSECTOR_SIZE + rep movsb + + ljmp16 0, ExtLdrEntryPoint + +ExtLdrPrintFileNotFound: + // Make DS correct, display it and reboot + call SwapESWithDS + mov si, offset msgExtLdr + jmp DisplayItAndReboot + +ExtLdrPrintRegFileError: + mov si, offset msgExtLdrNotRegularFile // ExtLdr not found message +DisplayItAndReboot: + call PutChars // Display it + jmp Reboot + +ExtLdrFileName: + .ascii "extldr.sys" +ExtLdrFileNameEnd: + +msgExtLdr: + .ascii "extldr.sys not found", CR, LF, NUL +msgExtLdrNotRegularFile: + .ascii "extldr.sys is not a regular file", CR, LF, NUL +msgLoadingExtLdr: + .ascii "Loading ExtLoader...", CR, LF, NUL + +.org 1022 + +.word HEX(AA55) // BootSector signature + +ExtLdrEntryPoint: +// ExtLdr is loaded here + +.endcode16 + +END + +#else + +#define start BOOTSECTOR_BASE_ADDRESS + +#define BootDrive (start + 3) +#define ExtVolumeStartSector (BootDrive + 1) +#define ExtBlockSize (ExtVolumeStartSector + 4) +#define ExtBlockSizeInBytes (ExtBlockSize + 4) +#define ExtPointersPerBlock (ExtBlockSizeInBytes + 4) +#define ExtGroupDescSize (ExtPointersPerBlock + 4) +#define ExtFirstDataBlock (ExtGroupDescSize + 4) +#define ExtInodeSize (ExtFirstDataBlock + 4) +#define ExtInodesPerGroup (ExtInodeSize + 4) + +#define ExtFileSize (ExtInodesPerGroup + 4) +#define ExtFileAddress (ExtFileSize + 4) +#define ExtFileAddressOld (ExtFileAddress + 4) + +#define ExtReadInodeGroup (ExtFileAddressOld + 4) +#define ExtReadInodeIndex (ExtReadInodeGroup + 4) +#define ExtReadInodeGroupBlock (ExtReadInodeIndex + 4) +#define ExtReadInodeIndexBlock (ExtReadInodeGroupBlock + 4) +#define ExtReadInodeGroupOffset (ExtReadInodeIndexBlock + 4) +#define ExtReadInodeIndexOffset (ExtReadInodeGroupOffset + 2) + +#define BootPartition (BootDrive + 506) + +#define ExtReadBlock word ptr ss:[bp-ExtReadBlockOffset] +#define ExtReadInode word ptr ss:[bp-ExtReadInodeOffset] +#define DisplayItAndReboot word ptr ss:[bp-DisplayItAndRebootOffset] +#define PutChars word ptr ss:[bp-PutCharsOffset] + +#endif diff --git a/boot/freeldr/bootsect/ext2.S b/boot/freeldr/bootsect/ext2.S deleted file mode 100644 index bd3119c635fea..0000000000000 --- a/boot/freeldr/bootsect/ext2.S +++ /dev/null @@ -1,688 +0,0 @@ -// EXT2.ASM -// EXT2 Boot Sector -// Copyright (c) 2002, 2003 Brian Palmer - -// [bp-0x04] Here we will store the number of sectors per track -// [bp-0x08] Here we will store the number of heads -// [bp-0x0c] Here we will store the size of the disk as the BIOS reports in CHS form -// [bp-0x10] Here we will store the number of LBA sectors read - -#include -.code16 - -SECTORS_PER_TRACK = HEX(04) -NUMBER_OF_HEADS = HEX(08) -BIOS_CHS_DRIVE_SIZE = HEX(0C) -LBA_SECTORS_READ = HEX(10) - - -EXT2_ROOT_INO = 2 -EXT2_S_IFMT = HEX(0f0) -EXT2_S_IFREG = HEX(080) - - -//org 7c00h - - -start: - jmp short main - nop - -BootDrive: - .byte HEX(80) -//BootPartition db 0 // Moved to end of boot sector to have a standard format across all boot sectors -//SectorsPerTrack db 63 // Moved to [bp-SECTORS_PER_TRACK] -//NumberOfHeads dw 16 // Moved to [bp-NUMBER_OF_HEADS] -//BiosCHSDriveSize dd (1024 * 1024 * 63) // Moved to [bp-BIOS_CHS_DRIVE_SIZE] -//LBASectorsRead dd 0 // Moved to [bp-LBA_SECTORS_READ] - -Ext2VolumeStartSector: - .long 263088 // Start sector of the ext2 volume -Ext2BlockSize: - .long 2 // Block size in sectors -Ext2BlockSizeInBytes: - .long 1024 // Block size in bytes -Ext2PointersPerBlock: - .long 256 // Number of block pointers that can be contained in one block -Ext2GroupDescPerBlock: - .long 32 // Number of group descriptors per block -Ext2FirstDataBlock: - .long 1 // First data block (1 for 1024-byte blocks, 0 for bigger sizes) -Ext2InodesPerGroup: - .long 2048 // Number of inodes per group -Ext2InodesPerBlock: - .long 8 // Number of inodes per block - -Ext2ReadEntireFileLoadSegment: - .word 0 -Ext2InodeIndirectPointer: - .long 0 -Ext2InodeDoubleIndirectPointer: - .long 0 -Ext2BlocksLeftToRead: - .long 0 - -main: - xor ax,ax // Setup segment registers - mov ds,ax // Make DS correct - mov es,ax // Make ES correct - mov ss,ax // Make SS correct - mov bp, HEX(7c00) - mov sp, HEX(7b00) // Setup a stack - - mov si, offset BootDrive - cmp byte ptr [si], HEX(0ff) // If they have specified a boot drive then use it - jne GetDriveParameters - - mov [si],dl // Save the boot drive - - -GetDriveParameters: - mov ah, 8 - mov dl,[si] // Get boot drive in dl - int HEX(13) // Request drive parameters from the bios - jnc CalcDriveSize // If the call succeeded then calculate the drive size - - // If we get here then the call to the BIOS failed - // so just set CHS equal to the maximum addressable - // size - mov cx, HEX(0ffff) - mov dh,cl - -CalcDriveSize: - // Now that we have the drive geometry - // lets calculate the drive size - mov bl,ch // Put the low 8-bits of the cylinder count into BL - mov bh,cl // Put the high 2-bits in BH - shr bh,6 // Shift them into position, now BX contains the cylinder count - and cl, HEX(3f) // Mask off cylinder bits from sector count - // CL now contains sectors per track and DH contains head count - movzx eax,dh // Move the heads into EAX - movzx ebx,bx // Move the cylinders into EBX - movzx ecx,cl // Move the sectors per track into ECX - inc eax // Make it one based because the bios returns it zero based - mov [bp-NUMBER_OF_HEADS],eax // Save number of heads - mov [bp-SECTORS_PER_TRACK],ecx // Save number of sectors per track - inc ebx // Make the cylinder count one based also - mul ecx // Multiply heads with the sectors per track, result in edx:eax - mul ebx // Multiply the cylinders with (heads * sectors) [stored in edx:eax already] - - // We now have the total number of sectors as reported - // by the bios in eax, so store it in our variable - mov [bp-BIOS_CHS_DRIVE_SIZE],eax - - -LoadExtraBootCode: - // First we have to load our extra boot code at - // sector 1 into memory at [0000:7e00h] - //mov eax,01h - xor eax,eax - inc eax // Read logical sector 1, EAX now = 1 - mov cx,1 // Read one sector - mov bx, HEX(7e00) // Read sector to [0000:7e00h] - call ReadSectors - - jmp LoadRootDirectory - - - -// Reads ext2 group descriptor into [7000:8000] -// We read it to this arbitrary location so -// it will not cross a 64k boundary -// EAX has group descriptor number to read -Ext2ReadGroupDesc: - shl eax,5 // Group = (Group * sizeof(GROUP_DESCRIPTOR) /* 32 */) - xor edx,edx - div dword ptr [bp+Ext2GroupDescPerBlock] // Group = (Group / Ext2GroupDescPerBlock) - add eax, dword ptr [bp+Ext2FirstDataBlock] // Group = Group + Ext2FirstDataBlock + 1 - inc eax // EAX now has the group descriptor block number - // EDX now has the group descriptor offset in the block - - // Adjust the read offset so that the - // group descriptor is read to 7000:8000 - mov ebx, HEX(78000) - sub ebx,edx - shr ebx,4 - mov es,bx - xor bx,bx - - - // Everything is now setup to call Ext2ReadBlock - // Instead of using the call instruction we will - // just put Ext2ReadBlock right after this routine - -// Reads ext2 block into ES:[BX] -// EAX has logical block number to read -Ext2ReadBlock: - mov ecx, dword ptr [bp+Ext2BlockSize] - mul ecx - jmp ReadSectors - -// Reads ext2 inode into [6000:8000] -// We read it to this arbitrary location so -// it will not cross a 64k boundary -// EAX has inode number to read -Ext2ReadInode: - dec eax // Inode = Inode - 1 - xor edx,edx - div dword ptr [bp+Ext2InodesPerGroup] // Inode = (Inode / Ext2InodesPerGroup) - mov ebx,eax // EBX now has the inode group number - mov eax,edx - xor edx,edx - div dword ptr [bp+Ext2InodesPerBlock] // Inode = (Inode / Ext2InodesPerBlock) - shl edx,7 // FIXME: InodeOffset *= 128 (make the array index a byte offset) - // EAX now has the inode offset block number from inode table - // EDX now has the inode offset in the block - - // Save the inode values and put the group - // descriptor number in EAX and read it in - push edx - push eax - mov eax,ebx - call Ext2ReadGroupDesc - - // Group descriptor has been read, now - // grab the inode table block number from it - push HEX(7000) - pop es - mov di, HEX(8008) - pop eax // Restore inode offset block number from stack - add eax, es:[di] // Add the inode table start block - - // Adjust the read offset so that the - // inode we want is read to 6000:8000 - pop edx // Restore inode offset in the block from stack - mov ebx, HEX(68000) - sub ebx,edx - shr ebx,4 - mov es,bx - xor bx,bx - - call Ext2ReadBlock - ret - - -// Reads logical sectors into ES:[BX] -// EAX has logical sector number to read -// CX has number of sectors to read -ReadSectors: - add eax, dword ptr [bp+Ext2VolumeStartSector] // Add the start of the volume - cmp eax, [bp-BIOS_CHS_DRIVE_SIZE] // Check if they are reading a sector outside CHS range - jae ReadSectorsLBA // Yes - go to the LBA routine - // If at all possible we want to use LBA routines because - // They are optimized to read more than 1 sector per read - - pushad // Save logical sector number & sector count - -CheckInt13hExtensions: // Now check if this computer supports extended reads - mov ah, HEX(41) // AH = 41h - mov bx, HEX(55aa) // BX = 55AAh - mov dl, byte ptr [bp+BootDrive] // DL = drive (80h-FFh) - int HEX(13) // IBM/MS INT 13 Extensions - INSTALLATION CHECK - jc ReadSectorsCHS // CF set on error (extensions not supported) - cmp bx, HEX(0aa55) // BX = AA55h if installed - jne ReadSectorsCHS - test cl,1 // CX = API subset support bitmap - jz ReadSectorsCHS // Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported - - popad // Restore sector count & logical sector number - -ReadSectorsLBA: - pushad // Save logical sector number & sector count - - cmp cx, 64 // Since the LBA calls only support 0x7F sectors at a time we will limit ourselves to 64 - jbe ReadSectorsSetupDiskAddressPacket // If we are reading less than 65 sectors then just do the read - mov cx,64 // Otherwise read only 64 sectors on this loop iteration - -ReadSectorsSetupDiskAddressPacket: - mov [bp-LBA_SECTORS_READ],cx - mov word ptr [bp-LBA_SECTORS_READ+2],0 - data32 push 0 - push eax // Put 64-bit logical block address on stack - push es // Put transfer segment on stack - push bx // Put transfer offset on stack - push cx // Set transfer count - push 16 // Set size of packet to 10h - mov si,sp // Setup disk address packet on stack - - - mov dl, byte ptr [bp+BootDrive] // Drive number - mov ah, HEX(42) // Int 13h, AH = 42h - Extended Read - int HEX(13) // Call BIOS - jc PrintDiskError // If the read failed then abort - - add sp, 16 // Remove disk address packet from stack - - popad // Restore sector count & logical sector number - - push bx - mov ebx, [bp-LBA_SECTORS_READ] - add eax,ebx // Increment sector to read - shl ebx,5 - mov dx,es - add dx,bx // Setup read buffer for next sector - mov es,dx - pop bx - - sub cx,[bp-LBA_SECTORS_READ] - jnz ReadSectorsLBA // Read next sector - - ret - - -// Reads logical sectors into ES:[BX] -// EAX has logical sector number to read -// CX has number of sectors to read -ReadSectorsCHS: - popad // Get logical sector number & sector count off stack - -ReadSectorsCHSLoop: - pushad - xor edx,edx - mov ecx, [bp-SECTORS_PER_TRACK] - div ecx // Divide logical by SectorsPerTrack - inc dl // Sectors numbering starts at 1 not 0 - mov cl,dl // Sector in CL - mov edx,eax - shr edx,16 - div word ptr [bp-NUMBER_OF_HEADS] // Divide logical by number of heads - mov dh,dl // Head in DH - mov dl, byte ptr [bp+BootDrive] // Drive number in DL - mov ch,al // Cylinder in CX - ror ah,2 // Low 8 bits of cylinder in CH, high 2 bits - // in CL shifted to bits 6 & 7 - or cl,ah // Or with sector number - mov ax, HEX(0201) - int HEX(13) // DISK - READ SECTORS INTO MEMORY - // AL = number of sectors to read, CH = track, CL = sector - // DH = head, DL = drive, ES:BX -> buffer to fill - // Return: CF set on error, AH = status (see AH=01h), AL = number of sectors read - - jc PrintDiskError // If the read failed then abort - - popad - - inc eax // Increment Sector to Read - - mov dx,es - add dx, HEX(20) // Increment read buffer for next sector - mov es,dx - - loop ReadSectorsCHSLoop // Read next sector - - ret - - - - -// Displays a disk error message -// And reboots -PrintDiskError: - mov si,msgDiskError // Bad boot disk message - call PutChars // Display it - -Reboot: - mov si,msgAnyKey // Press any key message - call PutChars // Display it - xor ax,ax - int HEX(16) // Wait for a keypress - int HEX(19) // Reboot - -PutChars: - lodsb - or al,al - jz short Done - call PutCharsCallBios - jmp short PutChars -PutCharsCallBios: - mov ah, HEX(0e) - mov bx, HEX(07) - int HEX(10) - ret -Done: - mov al, HEX(0d) - call PutCharsCallBios - mov al, HEX(0a) - call PutCharsCallBios - ret - - - -msgDiskError: - .ascii "Disk error", NUL -// Sorry, need the space... -//msgAnyKey db 'Press any key to restart',0 -msgAnyKey: - .ascii "Press key", NUL - -// times 509-($-$$) db 0 // Pad to 509 bytes - .org 509 - -BootPartition: - .byte 0 - - .word HEX(0aa55) // BootSector signature - - -// End of bootsector -// -// Now starts the extra boot code that we will store -// at sector 1 on a EXT2 volume - - - -LoadRootDirectory: - - mov eax,EXT2_ROOT_INO // Put the root directory inode number in EAX - call Ext2ReadInode // Read in the inode - - // Point ES:DI to the inode structure at 6000:8000 - push HEX(6000) - pop es - mov di, HEX(8000) - push di - push es // Save these for later - - // Get root directory size from inode structure - mov eax, es:[di+4] - push eax - - // Now that the inode has been read in load - // the root directory file data to 0000:8000 - call Ext2ReadEntireFile - - // Since the root directory was loaded to 0000:8000 - // then add 8000h to the root directory's size - pop eax - mov edx, HEX(8000) // Set EDX to the current offset in the root directory - add eax,edx // Initially add 8000h to the size of the root directory - -SearchRootDirectory: - push edx // Save current offset in root directory - push eax // Save the size of the root directory - - // Now we have to convert the current offset - // in the root directory to a SEGMENT:OFFSET pair - mov eax,edx - xor edx,edx - mov ecx,16 - div ecx // Now AX:DX has segment & offset - mov es,ax - mov di,dx - push di // Save the start of the directory entry - add di, 8 // Add the offset to the filename - mov si,filename - mov cl,11 - repe cmpsb // Compare the file names - pop di - pop eax - pop edx - jz FoundFile - - // Nope, didn't find it in this entry, keep looking - movzx ecx,word ptr es:[di+4] - add edx,ecx - - // Check to see if we have reached the - // end of the root directory - cmp edx,eax - jb SearchRootDirectory - jmp PrintFileNotFound - -FoundFile: - mov eax,es:[di] // Get inode number from directory entry - call Ext2ReadInode // Read in the inode - - // Point ES:DI to the inode structure at 6000:8000 - pop es - pop di // These were saved earlier - - mov cx, es:[di] // Get the file mode so we can make sure it's a regular file - and ch,EXT2_S_IFMT // Mask off everything but the file type - cmp ch,EXT2_S_IFREG // Make sure it's a regular file - je LoadFreeLoader - jmp PrintRegFileError - -LoadFreeLoader: - mov si,msgLoading // "Loading FreeLoader..." message - call PutChars // Display it - - call Ext2ReadEntireFile // Read freeldr.sys to 0000:8000 - - mov dl, byte ptr [bp+BootDrive] - mov dh, byte ptr [bp+BootPartition] - push 0 // push segment (0x0000) - mov eax, [HEX(8000) + HEX(0A8)] // load the RVA of the EntryPoint into eax - add eax, HEX(8000) // RVA -> VA - push ax // push offset - retf // Transfer control to FreeLoader - - - - - -// Reads ext2 file data into [0000:8000] -// This function assumes that the file's -// inode has been read in to 6000:8000 *and* -// ES:DI points to 6000:8000 -// This will load all the blocks up to -// and including the double-indirect pointers. -// This should be sufficient because it -// allows for ~64MB which is much bigger -// than we need for a boot loader. -Ext2ReadEntireFile: - - // Reset the load segment - mov word ptr [bp+Ext2ReadEntireFileLoadSegment], HEX(800) - - // Now we must calculate how - // many blocks to read in - // We will do this by rounding the - // file size up to the next block - // size and then dividing by the block size - mov eax, dword ptr [bp+Ext2BlockSizeInBytes] // Get the block size in bytes - push eax - dec eax // Ext2BlockSizeInBytes -= 1 - add eax, es:[di+4] // Add the file size - xor edx,edx - pop ecx // Divide by the block size in bytes - div ecx // EAX now contains the number of blocks to load - push eax - - // Make sure the file size isn't zero - cmp eax, 0 - jnz Ext2ReadEntireFile2 - jmp PrintFileSizeError - -Ext2ReadEntireFile2: - // Save the indirect & double indirect pointers - mov edx, es:[di+ HEX(58)] // Get indirect pointer - mov dword ptr [bp+Ext2InodeIndirectPointer], edx // Save indirect pointer - mov edx, es:[di+ HEX(5c)] // Get double indirect pointer - mov dword ptr [bp+Ext2InodeDoubleIndirectPointer],edx // Save double indirect pointer - - // Now copy the direct pointers to 7000:0000 - // so that we can call Ext2ReadDirectBlocks - push ds // Save DS - push es - push HEX(7000) - pop es - pop ds - mov si, HEX(8028) - xor di,di // DS:SI = 6000:8028 ES:DI = 7000:0000 - mov cx,24 // Moving 24 words of data - rep movsw - pop ds // Restore DS - - // Now we have all the block pointers in the - // right location so read them in - pop eax // Restore the total number of blocks in this file - xor ecx,ecx // Set the max count of blocks to read to 12 - mov cl,12 // which is the number of direct block pointers in the inode - call Ext2ReadDirectBlockList - - // Check to see if we actually have - // blocks left to read - cmp eax, 0 - jz Ext2ReadEntireFileDone - - // Now we have read all the direct blocks in - // the inode. So now we have to read the indirect - // block and read all it's direct blocks - push eax // Save the total block count - mov eax, dword ptr [bp+Ext2InodeIndirectPointer] // Get the indirect block pointer - push HEX(7000) - pop es - xor bx,bx // Set the load address to 7000:0000 - call Ext2ReadBlock // Read the block - - // Now we have all the block pointers from the - // indirect block in the right location so read them in - pop eax // Restore the total block count - mov ecx, dword ptr [bp+Ext2PointersPerBlock] // Get the number of block pointers that one block contains - call Ext2ReadDirectBlockList - - // Check to see if we actually have - // blocks left to read - cmp eax, 0 - jz Ext2ReadEntireFileDone - - // Now we have read all the direct blocks from - // the inode's indirect block pointer. So now - // we have to read the double indirect block - // and read all it's indirect blocks - // (whew, it's a good thing I don't support triple indirect blocks) - mov dword ptr [bp+Ext2BlocksLeftToRead],eax // Save the total block count - mov eax, dword ptr [bp+Ext2InodeDoubleIndirectPointer] // Get the double indirect block pointer - push HEX(7800) - pop es - push es // Save an extra copy of this value on the stack - xor bx,bx // Set the load address to 7000:8000 - call Ext2ReadBlock // Read the block - - pop es // Put 7800h into ES (saved on the stack already) - xor di,di - -Ext2ReadIndirectBlock: - mov eax, es:[di] // Get indirect block pointer - add di, 4 // Update DI for next array index - push es - push di - - push HEX(7000) - pop es - xor bx,bx // Set the load address to 7000:0000 - call Ext2ReadBlock // Read the indirect block - - // Now we have all the block pointers from the - // indirect block in the right location so read them in - mov eax, dword ptr [bp+Ext2BlocksLeftToRead] // Restore the total block count - mov ecx, dword ptr [bp+Ext2PointersPerBlock] // Get the number of block pointers that one block contains - call Ext2ReadDirectBlockList - mov dword ptr [bp+Ext2BlocksLeftToRead],eax // Save the total block count - pop di - pop es - - // Check to see if we actually have - // blocks left to read - cmp eax, 0 - jnz Ext2ReadIndirectBlock - -Ext2ReadEntireFileDone: - ret - -// Reads a maximum number of blocks -// from an array at 7000:0000 -// and updates the total count -// ECX contains the max number of blocks to read -// EAX contains the number of blocks left to read -// On return: -// EAX contains the new number of blocks left to read -Ext2ReadDirectBlockList: - cmp eax,ecx // Compare it to the maximum number of blocks to read - ja CallExt2ReadDirectBlocks // If it will take more blocks then just read all of the blocks - mov cx,ax // Otherwise adjust the block count accordingly - -CallExt2ReadDirectBlocks: - sub eax,ecx // Subtract the number of blocks being read from the total count - push eax // Save the new total count - call Ext2ReadDirectBlocks - pop eax // Restore the total count - ret - - -// Reads a specified number of blocks -// from an array at 7000:0000 -// CX contains the number of blocks to read -Ext2ReadDirectBlocks: - - push HEX(7000) - pop es - xor di,di // Set ES:DI = 7000:0000 - -Ext2ReadDirectBlocksLoop: - mov eax,es:[di] // Get direct block pointer from array - add di, 4 // Update DI for next array index - - push cx // Save number of direct blocks left - push es // Save array segment - push di // Save array offset - mov es,[bp+Ext2ReadEntireFileLoadSegment] - xor bx,bx // Setup load address for next read - - call Ext2ReadBlock // Read the block (this updates ES for the next read) - - mov [bp+Ext2ReadEntireFileLoadSegment],es // Save updated ES - - pop di // Restore the array offset - pop es // Restore the array segment - pop cx // Restore the number of blocks left - - loop Ext2ReadDirectBlocksLoop - - // At this point all the direct blocks should - // be loaded and ES (Ext2ReadEntireFileLoadSegment) - // should be ready for the next read. - ret - - - -// Displays a file not found error message -// And reboots -PrintFileNotFound: - mov si,msgFreeLdr // FreeLdr not found message - jmp short DisplayItAndReboot - -// Displays a file size is 0 error -// And reboots -PrintFileSizeError: - mov si,msgFileSize // Error message - jmp short DisplayItAndReboot - -// Displays a file is not a regular file error -// And reboots -PrintRegFileError: - mov si,msgRegFile // Error message -DisplayItAndReboot: - call PutChars // Display it - jmp Reboot - -msgFreeLdr: - .ascii "freeldr.sys not found", NUL -msgFileSize: - .ascii "File size 0", NUL -msgRegFile: - .ascii "freeldr.sys isnt a regular file", NUL -filename: - .ascii "freeldr.sys" -msgLoading: - .ascii "Loading...", NUL - -// times 1022-($-$$) db 0 // Pad to 1022 bytes -.org 1022 - - .word HEX(0aa55) // BootSector signature - -.endcode16 - -END diff --git a/boot/freeldr/bootsect/extldr.S b/boot/freeldr/bootsect/extldr.S new file mode 100644 index 0000000000000..5633f1597dbea --- /dev/null +++ b/boot/freeldr/bootsect/extldr.S @@ -0,0 +1,583 @@ +/* + * PROJECT: FreeLoader + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: EXTFS second stage loader + * COPYRIGHT: Copyright 2024-2025 Daniel Victor + */ + +#define INCLUDED_ASM +#include "ext.S" + +ExtLdrEntryPoint: + // Clear segment registers + xor eax, eax + mov ds, ax + mov es, ax + + // Read root directory Inode + mov al, EXT_ROOT_INODE + call ExtReadInode + + // Set file base address and search for freeldr + mov dword ptr BP_REL(ExtFileAddress), FREELDR_BASE + call ExtSetFileSegment + + // Swap ES with DS segment and clear SI + call SwapESWithDS + xor si, si + + // Set the directory entries size limit + mov eax, EXT_INODE_DATA_SIZE_LIMIT + + // Get directory entries size + mov edx, dword ptr BP_REL(ExtFileSize) + + // Set the buffer size with limit + cmp edx, eax + jbe .FLoop2 + mov edx, eax +.FLoop2: + // Load directory Inode + mov eax, dword ptr ds:[si] + + // If the buffer reached the end then abort the search + cmp si, dx + jae FreeLdrPrintFileNotFound + + // Save SI + push si + + // If the Inode is zero then skip this entry + test eax, eax + jz .FSkip2 + + mov di, offset FreeLdrFileName // Load target filename address + mov cx, offset FreeLdrFileNameEnd - FreeLdrFileName // Length of filename to compare + cmp byte ptr ds:[si + EXT_DIRECTORY_ENTRY_NAME_LENGTH_OFFSET], cl // Compare if both names have the same length + jnz .FSkip2 // Skip this entry if not + add si, EXT_DIRECTORY_ENTRY_NAME_OFFSET // Move to filename in entry + repe cmpsb // Compare filenames + pop si // Restore SI + jz LoadFreeLdr // Found matching file + push si // Save SI + +.FSkip2: + // Restore SI + pop si + + // Move to next directory entry + add si, word ptr ds:[si + EXT_DIRECTORY_ENTRY_SIZE_OFFSET] + + jmp .FLoop2 + +ExtFileIndirectPointer: + .long 0 +ExtFileIndirectPointerDouble: + .long 0 + +SwapESWithDS: + // Swap ES and DS + push es + push ds + pop es + pop ds + ret + +ExtSetFileSegment: + mov ebx, dword ptr BP_REL(ExtFileAddress) // Get the EXT file address + shr ebx, 4 // Shift four bits to the right to get segment + jmp .ExtSkip +ExtSetInodeSegment: + mov bx, EXT_INODE_ADDRESS / 16 // Get the EXT inode address + jmp .ExtSkip +ExtSetBlockSegment: + mov bx, EXT_BLOCK_ADDRESS / 16 // Get the EXT block address + jmp .ExtSkip +ExtSetBlock2Segment: + mov bx, EXT_BLOCK2_ADDRESS / 16 // Get the EXT second block address + jmp .ExtSkip +ExtSetBlock3Segment: + mov bx, EXT_BLOCK3_ADDRESS / 16 // Get the EXT third block address + jmp .ExtSkip +ExtSetBlock4Segment: + mov bx, EXT_BLOCK4_ADDRESS / 16 // Get the EXT fourth block address + jmp .ExtSkip +ExtSetBlock5Segment: + mov bx, EXT_BLOCK5_ADDRESS / 16 // Get the EXT fifth block address + jmp .ExtSkip +ExtSetBlock6Segment: + mov bx, EXT_BLOCK6_ADDRESS / 16 // Get the EXT sixth block address + jmp .ExtSkip +ExtSetBlock7Segment: + mov bx, EXT_BLOCK7_ADDRESS / 16 // Get the EXT seventh block address +.ExtSkip: + mov es, bx // Set ES + xor bx, bx // Clear BX + ret + +ExtUpdateFileSize: + mov eax, dword ptr BP_REL(ExtBlockSizeInBytes) + +ExtAdjustFileSize: + // Update the file size + sub dword ptr BP_REL(ExtFileSizeState), eax + add dword ptr BP_REL(ExtFileAddress), eax + ret + +ExtInodeDetectExtentsFlag: + push eax + mov eax, es:[si + EXT_INODE_FLAGS_OFFSET] + test eax, EXT_INODE_FLAG_EXTENTS + pop eax + ret + +ExtFileReadBlocks: + // If the block count is zero then do nothing + test bx, bx + jz .FRDone + + // Read the block + call ExtFileReadBlock + + // Go to the next block and decrement the block count + inc eax + dec bx + + // Loop until all blocks are read + jmp ExtFileReadBlocks +.FRDone: + ret + +ExtSafeReadBlock: + pushad + + // If the block is zero then just clear the block + test eax, eax + jz .NullBlk + + // Read the block safely + call ExtReadBlock + jmp .RBDone +.NullBlk: + // If the block is 0 then just clear the block + mov di, bx + xor ax, ax + mov cx, word ptr BP_REL(ExtBlockSizeInBytes) + rep stosb +.RBDone: + popad + ret + +// Reads a block from the EXT file +// EAX has the block to read +// ExtFileAddress has the address to write to +ExtFileReadBlock: + push es + pushad + + // Set the EXT file segment + call ExtSetFileSegment + + // Read the block safely + call ExtSafeReadBlock + + // Update the file size + call ExtUpdateFileSize + + // Exit + popad + pop es + ret + +ExtReadEntireFileDone: + push eax // Save EAX register + mov eax, dword ptr BP_REL(ExtBlockSizeInBytes) // Load block size in bytes into EAX + cmp dword ptr BP_REL(ExtFileSizeState), eax // Compare file size state with block size + pop eax // Restore EAX register + ret // Return from procedure + +// Loops over the block pointers and reads the blocks +// until the file size state is zero +ExtReadEntireFileLoop: + call ExtReadEntireFileDone + jb .RDone + + mov eax, dword ptr es:[si] + + // Read the block safely + call ExtFileReadBlock + + add si, EXT_POINTER_SIZE + loop ExtReadEntireFileLoop +.RDone: + ret + +// Reads the double indirect block data +// This function is used to read the blocks that are not contiguous +// to the blocks that are pointed by the indirect block +ExtReadEntireFileIndirectDouble: + push es + pushad + + // Check if there is no more blocks to read + call ExtReadEntireFileDone + jb .RDone4 + + // Reset block offset + xor si, si + + // Load the double indirect block address + mov eax, dword ptr BP_REL(ExtFileIndirectPointerDouble) + call ExtSetBlock2Segment + call ExtSafeReadBlock + + // Load the number of pointers per block + mov ecx, dword ptr BP_REL(ExtPointersPerBlock) +.RLoop4: + // Check if there is no more blocks to read + call ExtReadEntireFileDone + jb .RDone4 + + // Get the block address + mov eax, dword ptr es:[si] + + // Read the indirect block + call ExtReadEntireFileIndirect + + // Increment block offset + add si, EXT_POINTER_SIZE + + // Loop until all blocks are read + loop .RLoop4 +.RDone4: + popad + pop es + ret + +// Reads the indirect block data +ExtReadEntireFileIndirect: + push es + pushad + + // Check if there is no more blocks to read + call ExtReadEntireFileDone + jb .RDone3 + + // Reset block offset + xor si, si + + // Set the block segment + call ExtSetBlockSegment + + // Read the block safely + call ExtSafeReadBlock + + // Read the blocks + mov ecx, dword ptr BP_REL(ExtPointersPerBlock) + call ExtReadEntireFileLoop + +.RDone3: + popad + pop es + ret + +// Reads the direct block data +ExtReadEntireFileDirect: + push es + pushad + + // If there is no more blocks to read then abort it + call ExtReadEntireFileDone + jb .RDone2 + + // Move to block pointer in Inode + add si, EXT_INODE_BLOCK_POINTER_OFFSET + xor ecx, ecx + mov cl, EXT_INODE_BLOCKS + + // Set the correct segment + call ExtSetInodeSegment + + // Read the blocks + call ExtReadEntireFileLoop + +.RDone2: + popad + pop es + ret + +ExtExtentsLevelSegmentFunctionTable: + .word ExtSetBlockSegment + .word ExtSetBlock2Segment + .word ExtSetBlock3Segment + .word ExtSetBlock4Segment + .word ExtSetBlock5Segment + .word ExtSetBlock6Segment + +ExtExtentsLevelFunctionTable: + .word ExtReadEntireFileExtentsLevel0 + .word ExtReadEntireFileExtentsLevelX + .word ExtReadEntireFileExtentsLevelX + .word ExtReadEntireFileExtentsLevelX + .word ExtReadEntireFileExtentsLevelX + .word ExtReadEntireFileExtentsLevelX + +ExtReadEntireFileExtentsLevelX: + push es + pushad + + // Load extent header entries + mov cx, word ptr es:[si + EXT_EXTENT_HEADER_ENTRIES_OFFSET] +.ExtentsLoopX: + // Check if there is no more blocks to read + call ExtReadEntireFileDone + jb .ExtentsDoneX + + // Go to next extent + add si, EXT_EXTENT_SIZE + + // Save current state + push es + pushad + + // Read the extent block + mov eax, dword ptr es:[si + EXT_EXTENT_INDEX_LEAF_OFFSET] + + // Set block segment and read block safely + call ExtSetBlock7Segment + call ExtSafeReadBlock + + // Reset SI for calculations + xor si, si + + // Calculate function table offset + mov bp, word ptr es:[si + EXT_EXTENT_HEADER_DEPTH_OFFSET] + shl bp, 1 + + // Call the segment and level functions + call word ptr cs:ExtExtentsLevelSegmentFunctionTable[bp] + call ExtSafeReadBlock + call word ptr cs:ExtExtentsLevelFunctionTable[bp] + + // Restore state and continue loop + popad + pop es + + loop .ExtentsLoopX +.ExtentsDoneX: + popad + pop es + ret + +ExtReadEntireFileExtentsLevel0: + push es + pushad + + // Load extent header entries + mov cx, word ptr es:[si + EXT_EXTENT_HEADER_ENTRIES_OFFSET] + +.ExtentsLoop0: + // Check if there is no more blocks to read + call ExtReadEntireFileDone + jb .ExtentsDone0 + + // Go to next extent + add si, EXT_EXTENT_SIZE + + // Load extent length + mov bx, word ptr es:[si + EXT_EXTENT_LENGTH_OFFSET] + and ebx, HEX(FFFF) + + // Check if extent is sparse + cmp bx, EXT_EXTENT_MAX_LENGTH + jbe .NotSparse + + // Adjust sparse extent length + sub bx, EXT_EXTENT_MAX_LENGTH + + push es +.SparseLoop: + // Check if the sparse blocks reached the end + test bx, bx + jz .SparseDone + + xor eax, eax + call ExtFileReadBlock + + // Decrement the block count + dec bx + jmp .SparseLoop +.SparseDone: + pop es + jmp .ExtentsSkip0 + +.NotSparse: + // Read blocks from extent start + mov eax, dword ptr es:[si + EXT_EXTENT_START_OFFSET] + call ExtFileReadBlocks + +.ExtentsSkip0: + loop .ExtentsLoop0 +.ExtentsDone0: + popad + pop es + ret + +ExtReadEntireFileExtents: + push es + pushad + + // Add the extent header offset + add si, EXT_INODE_BLOCK_POINTER_OFFSET + + // Load extent header depth + mov ax, word ptr es:[si + EXT_EXTENT_HEADER_DEPTH_OFFSET] + + // Check if the file has more than the maximum allowed levels + cmp ax, EXT_EXTENT_MAX_LEVEL + ja FreeLdrPrintFileBig + + // If the extent header depth is zero then this is a level 0 extent + test ax, ax + jz .Level0 + + // Call the recursive function +.LevelX: + call ExtReadEntireFileExtentsLevelX + + // Jump to the end of the function + jmp .FEDone + + // Level 0 extent +.Level0: + // Call the level 0 extent function + call ExtReadEntireFileExtentsLevel0 + + // End of the function +.FEDone: + popad + pop es + ret + +// Reads the entire file in EXTFS +ExtReadEntireFile: + // Set the correct Inode offset + mov si, word ptr BP_REL(ExtReadInodeIndexOffset) + + // Set file size + mov ecx, dword ptr es:[si + EXT_INODE_SIZE_OFFSET] + mov dword ptr BP_REL(ExtFileSize), ecx + + // If file size is zero then abort it + test ecx, ecx + jz FreeLdrPrintFileZero + + // Set rounded up file size + add ecx, dword ptr BP_REL(ExtBlockSizeInBytes) + dec ecx + mov dword ptr BP_REL(ExtFileSizeState), ecx + + // Use extents method if necessary + call ExtInodeDetectExtentsFlag + jz .NoExtents + + // Call the extents method + call ExtReadEntireFileExtents + ret + +.NoExtents: + // Set Indirect pointer + mov eax, dword ptr es:[si + (EXT_INODE_BLOCK_POINTER_OFFSET + (EXT_INODE_BLOCKS * EXT_POINTER_SIZE))] + mov dword ptr BP_REL(ExtFileIndirectPointer), eax + + // Set Double indirect pointer + mov eax, dword ptr es:[si + (EXT_INODE_BLOCK_POINTER_OFFSET + (EXT_INODE_BLOCKS * EXT_POINTER_SIZE) + EXT_POINTER_SIZE)] + mov dword ptr BP_REL(ExtFileIndirectPointerDouble), eax + + call ExtReadEntireFileDirect // Read the direct blocks + + mov eax, dword ptr BP_REL(ExtFileIndirectPointer) // Load the simple indirect pointer + call ExtReadEntireFileIndirect // Read the simple indirect blocks + + call ExtReadEntireFileIndirectDouble // Read the double indirect blocks + ret + +LoadFreeLdr: + // Swap ES and DS + call SwapESWithDS + + // Show output loading status + push si + mov si, offset msgLoadingFreeLdr + call PutChars + pop si + + // Load Inode at directory entry + mov eax, dword ptr es:[si] + call ExtReadInode + mov si, word ptr BP_REL(ExtReadInodeIndexOffset) + + // Get Inode type + mov ax, word ptr es:[si] + and ax, EXT_INODE_TYPE_MASK + + // If it's not a regular file then abort it + cmp ax, EXT_INODE_TYPE_REGULAR + jnz FreeLdrPrintRegFileError + + // Load Freeldr at FREELDR_BASE + mov dword ptr BP_REL(ExtFileAddress), FREELDR_BASE + call ExtReadEntireFile + + // Restore the boot drive and partition + mov dl, byte ptr BP_REL(BootDrive) + mov dh, byte ptr BP_REL(BootPartition) + + // Transfer execution to the bootloader + ljmp16 FREELDR_BASE / 16, 0 + +FreeLdrPrintFileBig: + // Make DS correct, display it and reboot + call SwapESWithDS + mov si, offset msgFreeLdrBig + jmp DisplayItAndReboot + +FreeLdrPrintFileZero: + // Make DS correct, display it and reboot + call SwapESWithDS + mov si, offset msgFreeLdrZero + jmp DisplayItAndReboot + +FreeLdrPrintFileNotFound: + // Make DS correct, display it and reboot + call SwapESWithDS + mov si, offset msgFreeLdr + jmp DisplayItAndReboot + +FreeLdrPrintRegFileError: + // Make DS correct, display it and reboot + call SwapESWithDS + mov si, offset msgFreeLdrNotRegularFile // FreeLdr not found message + jmp DisplayItAndReboot + +FreeLdrFileName: + .ascii "freeldr.sys" +FreeLdrFileNameEnd: + +msgFreeLdrZero: + .ascii "freeldr.sys size is zero", CR, LF, NUL +msgFreeLdrBig: + .ascii "freeldr.sys has many extent levels", CR, LF, NUL +msgFreeLdr: + .ascii "freeldr.sys not found", CR, LF, NUL +msgFreeLdrNotRegularFile: + .ascii "freeldr.sys is not a regular file", CR, LF, NUL +msgLoadingFreeLdr: + .ascii "Loading FreeLoader...", CR, LF, NUL + +.org (EXTLDR_BOOTSECTOR_SIZE - 2) +.word HEX(AA55) // BootSector signature + +.endcode16 + +END diff --git a/boot/freeldr/bootsect/pc98/fat12fdd.S b/boot/freeldr/bootsect/pc98/fat12fdd.S index 51ebfec05c44a..82b5ae1deb8f9 100644 --- a/boot/freeldr/bootsect/pc98/fat12fdd.S +++ b/boot/freeldr/bootsect/pc98/fat12fdd.S @@ -145,11 +145,9 @@ relocated: mov ds, ax test byte ptr ds:[HEX(501)], HEX(08) // High-resolution mode check - jz VideoTestNormalMode - mov ax, HEX(0E000) - jmp short VideoTestDone -VideoTestNormalMode: - mov ax, HEX(0A000) + mov ax, HEX(0A000) // Suppose normal mode + jz short VideoTestDone + mov ah, HEX(E0) // Change 0xA000 to 0xE000, use hi-res mode VideoTestDone: mov word ptr BP_REL(VramSegment), ax @@ -360,14 +358,11 @@ PutChar: push di push es - push word ptr BP_REL(VramSegment) - pop es - mov di, word ptr BP_REL(VramOffset) // ES:DI = VramSegment:VramOffset + les di, dword ptr BP_REL(VramSegOff) // Load the VRAM segment and offset (ES:DI) .PutCharWrite: - xor ah, ah - stosw // Write ASCII directly to the VRAM - - mov word ptr BP_REL(VramOffset), di + xor ah, ah // Write ASCII directly to the VRAM + stosw // (two bytes per character) + mov word ptr BP_REL(VramOffset), di // Update the start position pop es pop di @@ -470,10 +465,12 @@ Reboot: Halt: jmp short Halt // Spin -VramSegment: - .word 0 +VramSegOff: VramOffset: .word 0 +VramSegment: + .word 0 + msgDiskError: .ascii "ERR", CR, LF, NUL msgNotFoundError: diff --git a/boot/freeldr/fdebug/lang/ro-RO.rc b/boot/freeldr/fdebug/lang/ro-RO.rc index ac354a92b500a..4df4ad77df7df 100644 --- a/boot/freeldr/fdebug/lang/ro-RO.rc +++ b/boot/freeldr/fdebug/lang/ro-RO.rc @@ -1,4 +1,10 @@ -/* Translator: Ștefan Fulea (stefan dot fulea at mail dot com) */ +/* + * PROJECT: ReactOS FreeLoader Debugger + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Romanian resource file + * TRANSLATORS: Copyright 2011-2018 Ștefan Fulea + * Copyright 2024 Andrei Miloiu + */ LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL @@ -10,16 +16,16 @@ BEGIN MENUITEM "&Conectare", IDM_FILE_CONNECT MENUITEM "&Deconectare", IDM_FILE_DISCONNECT, GRAYED MENUITEM SEPARATOR - MENUITEM "C&urăță ecran", IDM_FILE_CLEARDISPLAY + MENUITEM "C&urățare a ecranului", IDM_FILE_CLEARDISPLAY MENUITEM SEPARATOR - MENUITEM "&Pornește captură", IDM_FILE_STARTCAPTURE - MENUITEM "&Oprește captură", IDM_FILE_STOPCAPTURE, GRAYED + MENUITEM "&Pornire a capturii", IDM_FILE_STARTCAPTURE + MENUITEM "&Oprire a capturii", IDM_FILE_STOPCAPTURE, GRAYED MENUITEM SEPARATOR MENUITEM "Ecou loc&al", IDM_FILE_LOCALECHO MENUITEM SEPARATOR MENUITEM "I&eșire", IDM_EXIT END - POPUP "Aj&utor" + POPUP "&Ajutor" BEGIN MENUITEM "&Despre…", IDM_ABOUT END @@ -41,8 +47,6 @@ FONT 8, "MS Shell Dlg" BEGIN CONTROL "Depanatorul FreeLoader\nDrept de autor (C) 2003\nde Brian Palmer (brianp@reactos.org)", IDC_STATIC, "Static", SS_LEFTNOWORDWRAP | WS_GROUP, 53, 28, 122, 26 DEFPUSHBUTTON "Î&nchide", IDOK, 189, 44, 50, 14, WS_GROUP - ICON IDI_FDEBUG, IDC_STATIC, 19, 30, 20, 20 - EDITTEXT IDC_LICENSE_EDIT, 53, 63, 174, 107, ES_MULTILINE | ES_READONLY | WS_VSCROLL END IDD_CONNECTION DIALOGEX 0, 0, 196, 100 @@ -50,12 +54,12 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Opțiuni de conectare" FONT 8, "MS Shell Dlg" BEGIN - LTEXT "Alegeți portul COM (ex. COM1):", IDC_STATIC, 7, 7, 108, 8 + LTEXT "Treceți portul COM (ex. COM1):", IDC_STATIC, 7, 7, 108, 8 EDITTEXT IDC_COMPORT, 7, 17, 182, 14, ES_AUTOHSCROLL - LTEXT "Rata baud (ex. 115200):", IDC_STATIC, 7, 38, 114, 8 + LTEXT "Treceți rata baud (ex. 115200):", IDC_STATIC, 7, 38, 114, 8 EDITTEXT IDC_BAUTRATE, 7, 48, 182, 14, ES_AUTOHSCROLL - DEFPUSHBUTTON "Con&firmă", IDOK, 45, 79, 50, 14 - PUSHBUTTON "A&nulează", IDCANCEL, 100, 79, 50, 14 + DEFPUSHBUTTON "OK", IDOK, 45, 79, 50, 14 + PUSHBUTTON "Revocare", IDCANCEL, 100, 79, 50, 14 END IDD_CAPTURE DIALOGEX 0, 0, 251, 95 @@ -63,23 +67,23 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Fișierul de captură" FONT 8, "MS Shell Dlg" BEGIN - LTEXT "Numele fișierului:", IDC_STATIC, 7, 17, 62, 8 + LTEXT "Nume fișier capt.:", IDC_STATIC, 7, 17, 62, 8 EDITTEXT IDC_CAPTUREFILENAME, 7, 26, 181, 14, ES_AUTOHSCROLL - PUSHBUTTON "&Caută", IDC_BROWSE, 194, 26, 50, 14 - DEFPUSHBUTTON "Con&firmă", IDOK, 139, 74, 50, 14 - PUSHBUTTON "A&nulează", IDCANCEL, 194, 74, 50, 14 + PUSHBUTTON "&Specificare", IDC_BROWSE, 194, 26, 50, 14 + DEFPUSHBUTTON "OK", IDOK, 139, 74, 50, 14 + PUSHBUTTON "Revocare", IDCANCEL, 194, 74, 50, 14 END /* String Tables */ STRINGTABLE BEGIN - IDS_APP_TITLE "Program de depanare FreeLoader" - IDS_HELLO "Salut, lume!" + IDS_APP_TITLE "Depanatorul FreeLoader" + IDS_HELLO "Salut lume!" IDC_FDEBUG "FDEBUG" END STRINGTABLE BEGIN - IDS_LICENSE "Această aplicație este un soft public; poate fi redistribuită și/sau modificată respectând termenii Licenței Publice Generale GNU publicată de Free Software Foundation; sau respectând Licența în versiunea 2, sau (la alegere) o altă versiune ulterioară.\r\n\r\nAceastă aplicație este distribuită în speranța că va fi utilă, FĂRĂ însă NICI O GARANŢIE; nici măcar cu garanția implicită a VANDABILITĂŢII sau a UTILITĂŢII ÎNTR-UN SCOP ANUME. Consultați Licența Publică Generală GNU pentru mai multe detalii.\r\n\r\nPuteți vedea această licență aici:\r\nhttp://www.gnu.org/licenses/gpl.html\r\n\r\nDe asemenea puteți consulta traduceri neoficiale ale acestei licențe aici:\r\nhttp://www.gnu.org/licenses/translations.html" + IDS_LICENSE "Acest program este un software liber: dumneavoastră îl puteţi redistribui şi/sau modifica, în condiţiile Licenţei publice generale GNU, aşa cum a fost aceasta publicată de către Free Software Foundation, fie versiunea 2 a acestei Licenţe, fie (la alegerea dumneavoastră), orice versiune ulterioară.\r\n\r\nAcest program este distribuit în speranţa că va fi util, dar FĂRĂ NICIO GARANŢIE; chiar şi fără garanţia implicită de MERCANTILITATE sau de ADECVARE PENTRU UN ANUMIT SCOP. Vezi Licenţa publică generală GNU pentru mai multe detalii.\r\n\r\nTrebuie ca dumneavoastră să fi primit o copie a Licenţei publice generale GNU împreună cu acest program. Dacă nu, scrie la Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 SUA." END diff --git a/boot/freeldr/freeldr/CMakeLists.txt b/boot/freeldr/freeldr/CMakeLists.txt index b97b15a1763fb..7f3493c0c4a5c 100644 --- a/boot/freeldr/freeldr/CMakeLists.txt +++ b/boot/freeldr/freeldr/CMakeLists.txt @@ -44,7 +44,7 @@ list(APPEND FREELDR_BOOTLIB_SOURCE lib/comm/rs232.c ## add KD support lib/fs/btrfs.c - lib/fs/ext2.c + lib/fs/ext.c lib/fs/fat.c lib/fs/fs.c lib/fs/iso.c @@ -58,11 +58,6 @@ list(APPEND FREELDR_BOOTLIB_SOURCE list(APPEND FREELDR_BOOTMGR_SOURCE include/freeldr.h - custom.c - # linuxboot.c - miscboot.c - options.c - oslist.c settings.c ui/directui.c # ui/gui.c @@ -88,10 +83,7 @@ if(ARCH STREQUAL "i386") # arch/i386/linux.S list(APPEND FREELDR_ARC_SOURCE - arch/i386/i386bug.c - arch/i386/halstub.c - arch/i386/ntoskrnl.c - disk/scsiport.c) + arch/i386/i386bug.c) list(APPEND FREELDR_NTLDR_SOURCE ntldr/arch/i386/winldr.c @@ -118,23 +110,18 @@ else() endif() list(APPEND FREELDR_BASE_SOURCE - bootmgr.c # This file is compiled with custom definitions freeldr.c - ntldr/setupldr.c ## Strangely enough this file is needed in GCC builds - ## even if ${FREELDR_NTLDR_SOURCE} is not added, - ## otherwise we get linking errors with Rtl**Bitmap** APIs. - ## Do not happen on MSVC builds however... - ntldr/inffile.c - ntldr/ntldropts.c + ntldr/ntldropts.c # Should be in rosload, but is currently needed by machpc.c, etc. lib/rtl/libsupp.c) -if(ARCH STREQUAL "i386") +if(ARCH STREQUAL "i386" OR ARCH STREQUAL "amd64") # Must be included together with disk/scsiport.c list(APPEND FREELDR_BASE_SOURCE - ${CMAKE_CURRENT_BINARY_DIR}/freeldr_pe.def) + ${CMAKE_CURRENT_BINARY_DIR}/freeldr.def) endif() include(pcat.cmake) +include(rosload.cmake) if(NOT ARCH STREQUAL "i386" OR NOT (SARCH STREQUAL "pc98" OR SARCH STREQUAL "xbox")) include(uefi.cmake) endif() diff --git a/boot/freeldr/freeldr/arch/arcemul.c b/boot/freeldr/freeldr/arch/arcemul.c index a72f492bc5d33..edf8d66fc452d 100644 --- a/boot/freeldr/freeldr/arch/arcemul.c +++ b/boot/freeldr/freeldr/arch/arcemul.c @@ -40,4 +40,35 @@ ArcGetRelativeTime(VOID) return ret; } +PCONFIGURATION_COMPONENT_DATA +MachHwDetect(_In_opt_ PCSTR Options) +{ + return MachVtbl.HwDetect(Options); +} + +VOID MachPrepareForReactOS(VOID) +{ + MachVtbl.PrepareForReactOS(); +} + +VOID MachGetExtendedBIOSData(PULONG ExtendedBIOSDataArea, PULONG ExtendedBIOSDataSize) +{ + MachVtbl.GetExtendedBIOSData(ExtendedBIOSDataArea, ExtendedBIOSDataSize); +} + +VOID MachVideoGetFontsFromFirmware(PULONG RomFontPointers) +{ + MachVtbl.VideoGetFontsFromFirmware(RomFontPointers); +} + +ULONG +MachGetBootSectorLoadAddress(IN UCHAR DriveNumber) +{ +#if defined(SARCH_PC98) + return Pc98GetBootSectorLoadAddress(DriveNumber); +#else + return 0x7C00; +#endif +} + /* EOF */ diff --git a/boot/freeldr/freeldr/arch/archwsup.c b/boot/freeldr/freeldr/arch/archwsup.c index f112270ad2530..e46a8f87498d7 100644 --- a/boot/freeldr/freeldr/arch/archwsup.c +++ b/boot/freeldr/freeldr/arch/archwsup.c @@ -243,3 +243,18 @@ FldrCreateComponentKey( /* Return the child */ *ComponentKey = ComponentData; } + +ULONG ArcGetDiskCount(VOID) +{ + return reactos_disk_count; +} + +PARC_DISK_SIGNATURE_EX ArcGetDiskInfo(ULONG Index) +{ + if (Index >= reactos_disk_count) + { + return NULL; + } + + return &reactos_arc_disk_info[Index]; +} diff --git a/boot/freeldr/freeldr/arch/arm/debug.c b/boot/freeldr/freeldr/arch/arm/debug.c index f7d65d2bfc541..97fea6e6a3142 100644 --- a/boot/freeldr/freeldr/arch/arm/debug.c +++ b/boot/freeldr/freeldr/arch/arm/debug.c @@ -24,6 +24,7 @@ Rs232PortPutByte(UCHAR ByteToSend) *UART0DR = ByteToSend; } +DECLSPEC_NORETURN VOID FrLdrBugCheckWithMessage( ULONG BugCode, diff --git a/boot/freeldr/freeldr/arch/drivers/hwide.c b/boot/freeldr/freeldr/arch/drivers/hwide.c index 9eb92ada048d7..2baffe483456f 100644 --- a/boot/freeldr/freeldr/arch/drivers/hwide.c +++ b/boot/freeldr/freeldr/arch/drivers/hwide.c @@ -1,371 +1,750 @@ /* * PROJECT: FreeLoader - * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * LICENSE: MIT (https://spdx.org/licenses/MIT) * PURPOSE: ATA/ATAPI programmed I/O driver. - * COPYRIGHT: Copyright 2019-2020 Dmitry Borisov (di.sean@protonmail.com) + * COPYRIGHT: Copyright 2019-2025 Dmitry Borisov (di.sean@protonmail.com) */ /* INCLUDES *******************************************************************/ #include -#include /* DDK */ #include #include +#include +#include "hwidep.h" + #include DBG_DEFAULT_CHANNEL(DISK); /* GLOBALS ********************************************************************/ -#define TAG_ATA_DEVICE 'DatA' -#define ATAPI_PACKET_SIZE(IdentifyData) (IdentifyData.AtapiCmdSize ? 16 : 12) -#define ATA_STATUS_TIMEOUT 31e5 - -#define AtaWritePort(Channel, Port, Data) \ - WRITE_PORT_UCHAR(UlongToPtr(BaseArray[(Channel)] + (Port)), (Data)) - -#define AtaReadPort(Channel, Port) \ - READ_PORT_UCHAR(UlongToPtr(BaseArray[(Channel)] + (Port))) - -#define AtaWriteBuffer(Channel, Buffer, Count) \ - WRITE_PORT_BUFFER_USHORT(UlongToPtr(BaseArray[(Channel)] + IDX_IO1_o_Data), \ - (PUSHORT)(Buffer), (Count)/sizeof(USHORT)) - -#define AtaReadBuffer(Channel, Buffer, Count) \ - READ_PORT_BUFFER_USHORT(UlongToPtr(BaseArray[(Channel)] + IDX_IO1_i_Data), \ - (PUSHORT)(Buffer), (Count)/sizeof(USHORT)) - -/* IDE/ATA Channels base - Primary, Secondary, Tertiary, Quaternary */ -static const ULONG BaseArray[] = +/** IDE Channels base - Primary, Secondary, Tertiary, Quaternary */ +static const IDE_REG AtapChannelBaseArray[] = { -#if defined(SARCH_XBOX) +#if defined(SARCH_PC98) + 0x640 +#elif defined(SARCH_XBOX) 0x1F0 -#elif defined(SARCH_PC98) - 0x640, 0x640 #else 0x1F0, 0x170, 0x1E8, 0x168 #endif }; +#define CHANNEL_MAX_CHANNELS RTL_NUMBER_OF(AtapChannelBaseArray) -#define MAX_CHANNELS RTL_NUMBER_OF(BaseArray) -#define MAX_DEVICES 2 /* Master/Slave */ +static PHW_DEVICE_UNIT AtapUnits[CHANNEL_MAX_CHANNELS * CHANNEL_MAX_DEVICES]; -static PDEVICE_UNIT Units[MAX_CHANNELS * MAX_DEVICES]; - -/* PRIVATE PROTOTYPES *********************************************************/ +/* PRIVATE FUNCTIONS **********************************************************/ +#if defined(ATA_SUPPORT_32_BIT_IO) static +inline BOOLEAN -WaitForFlags( - IN UCHAR Channel, - IN UCHAR Flags, - IN UCHAR ExpectedValue, - IN ULONG Timeout -); +AtapIs32BitIoSupported( + _In_ PHW_DEVICE_UNIT DeviceUnit) +{ +#if defined(ATA_ALWAYS_DO_32_BIT_IO) + return TRUE; +#else + return !!(DeviceUnit->P.Flags & ATA_DEVICE_FLAG_IO32); +#endif +} +#endif static -BOOLEAN -WaitForFlagsOr( - IN UCHAR Channel, - IN UCHAR FirstValue, - IN UCHAR SecondValue, - IN ULONG Timeout -); +VOID +AtapSelectDevice( + _In_ PIDE_REGISTERS Registers, + _In_range_(0, 3) UCHAR DeviceNumber) +{ +#if defined(SARCH_PC98) + /* Select the primary (0) or secondary (1) IDE channel */ + ATA_WRITE(0x432, DeviceNumber >> 1); +#endif + + ATA_WRITE(Registers->Device, (DEV_SLAVE(DeviceNumber) << 4) | IDE_DRIVE_SELECT); + ATA_IO_WAIT(); +} static BOOLEAN -WaitForBusy( - IN UCHAR Channel, - IN ULONG Timeout -); +AtapWaitForNotBusy( + _In_ PIDE_REGISTERS Registers, + _In_range_(>, 0) ULONG Timeout, + _Out_opt_ PUCHAR Result) +{ + UCHAR IdeStatus; + ULONG i; -static -VOID -SelectDevice( - IN UCHAR Channel, - IN UCHAR DeviceNumber -); + ASSERT(Timeout != 0); + + for (i = 0; i < Timeout; ++i) + { + IdeStatus = ATA_READ(Registers->Status); + if (!(IdeStatus & IDE_STATUS_BUSY)) + { + if (Result) + *Result = IdeStatus; + return TRUE; + } + + if (IdeStatus == 0xFF) + break; + + StallExecutionProcessor(10); + } + + if (Result) + *Result = IdeStatus; + return FALSE; +} static BOOLEAN -IdentifyDevice( - IN UCHAR Channel, - IN UCHAR DeviceNumber, - OUT PDEVICE_UNIT *DeviceUnit -); +AtapWaitForIdle( + _In_ PIDE_REGISTERS Registers, + _Out_ PUCHAR Result) +{ + UCHAR IdeStatus; + ULONG i; + + for (i = 0; i < ATA_TIME_DRQ_CLEAR; ++i) + { + IdeStatus = ATA_READ(Registers->Status); + if (!(IdeStatus & (IDE_STATUS_DRQ | IDE_STATUS_BUSY))) + { + *Result = IdeStatus; + return TRUE; + } + + StallExecutionProcessor(2); + } + + *Result = IdeStatus; + return FALSE; +} static -BOOLEAN -AtapiRequestSense( - IN PDEVICE_UNIT DeviceUnit, - OUT PSENSE_DATA SenseData -); +VOID +AtapSendCdb( + _In_ PHW_DEVICE_UNIT DeviceUnit, + _In_ PATA_DEVICE_REQUEST Request) +{ +#if defined(ATA_SUPPORT_32_BIT_IO) + if (AtapIs32BitIoSupported(DeviceUnit)) + { + ATA_WRITE_BLOCK_32(DeviceUnit->Registers.Data, + Request->Cdb, + DeviceUnit->CdbSize / sizeof(USHORT)); + } + else +#endif + { + ATA_WRITE_BLOCK_16(DeviceUnit->Registers.Data, + Request->Cdb, + DeviceUnit->CdbSize); + } + + /* + * In polled mode (interrupts disabled) + * the NEC CDR-260 drive clears BSY before updating the interrupt reason register. + * As a workaround, we will wait for the phase change. + */ + if (DeviceUnit->P.Flags & ATA_DEVICE_IS_NEC_CDR260) + { + ULONG i; + + ATA_IO_WAIT(); + + for (i = 0; i < ATA_TIME_PHASE_CHANGE; ++i) + { + UCHAR InterruptReason = ATA_READ(DeviceUnit->Registers.InterruptReason); + if (InterruptReason != ATAPI_INT_REASON_COD) + break; + + StallExecutionProcessor(10); + } + } +} static VOID -AtapiPrintSenseData( - IN PDEVICE_UNIT DeviceUnit -); +AtapPioDataIn( + _In_ PHW_DEVICE_UNIT DeviceUnit, + _In_ ULONG ByteCount) +{ + ByteCount = min(ByteCount, DeviceUnit->BytesToTransfer); + +#if defined(ATA_SUPPORT_32_BIT_IO) + if (AtapIs32BitIoSupported(DeviceUnit)) + { + ATA_READ_BLOCK_32(DeviceUnit->Registers.Data, + (PULONG)DeviceUnit->DataBuffer, + ByteCount / sizeof(ULONG)); + } + else +#endif + { + ATA_READ_BLOCK_16(DeviceUnit->Registers.Data, + (PUSHORT)DeviceUnit->DataBuffer, + ByteCount / sizeof(USHORT)); + } + + DeviceUnit->DataBuffer += ByteCount; + DeviceUnit->BytesToTransfer -= ByteCount; +} static BOOLEAN -AtapiReadyCheck( - IN OUT PDEVICE_UNIT DeviceUnit -); +AtapWaitForRegisterAccess( + _In_ PIDE_REGISTERS Registers, + _In_range_(0, 3) UCHAR DeviceNumber) +{ + ULONG i; + + for (i = 0; i < ATA_TIME_RESET_SELECT; ++i) + { + /* Select the device again */ + AtapSelectDevice(Registers, DeviceNumber); + + /* Check whether the selection was successful */ + ATA_WRITE(Registers->ByteCountLow, 0xAA); + ATA_WRITE(Registers->ByteCountLow, 0x55); + ATA_WRITE(Registers->ByteCountLow, 0xAA); + if (ATA_READ(Registers->ByteCountLow) == 0xAA) + return TRUE; + + StallExecutionProcessor(10); + } + + return FALSE; +} static -BOOLEAN -AtapiReadLogicalSectorLBA( - IN PDEVICE_UNIT DeviceUnit, - IN ULONGLONG SectorNumber, - OUT PVOID Buffer -); +VOID +AtapSoftwareReset( + _In_ PIDE_REGISTERS Registers) +{ + ATA_WRITE(Registers->Control, IDE_DC_RESET_CONTROLLER | IDE_DC_ALWAYS); + StallExecutionProcessor(20); + ATA_WRITE(Registers->Control, IDE_DC_DISABLE_INTERRUPTS | IDE_DC_ALWAYS); + StallExecutionProcessor(20); +} static BOOLEAN -AtaReadLogicalSectorsLBA( - IN PDEVICE_UNIT DeviceUnit, - IN ULONGLONG SectorNumber, - IN ULONG SectorCount, - OUT PVOID Buffer -); +AtapPerformSoftwareReset( + _In_ PHW_DEVICE_UNIT DeviceUnit) +{ + PIDE_REGISTERS Registers = &DeviceUnit->Registers; -/* FUNCTIONS ******************************************************************/ + ERR("Reset device at %X:%u\n", Registers->Data, DeviceUnit->DeviceNumber); -/* Don't call this before running the system timer calibration and MM initialization */ -BOOLEAN -AtaInit(OUT PUCHAR DetectedCount) -{ - UCHAR Channel, DeviceNumber; - PDEVICE_UNIT DeviceUnit = NULL; + /* Perform a software reset */ + AtapSoftwareReset(Registers); - TRACE("AtaInit()\n"); + /* The reset will cause the master device to be selected */ + if (DEV_SLAVE(DeviceUnit->DeviceNumber)) + { + if (!AtapWaitForRegisterAccess(Registers, DeviceUnit->DeviceNumber)) + return FALSE; + } - *DetectedCount = 0; + /* Now wait for busy to clear */ + if (!AtapWaitForNotBusy(Registers, ATA_TIME_BUSY_RESET, NULL)) + return FALSE; - RtlZeroMemory(&Units, sizeof(Units)); + return TRUE; +} - /* Detect and enumerate ATA/ATAPI devices */ - for (Channel = 0; Channel < MAX_CHANNELS; ++Channel) +static +UCHAR +AtapProcessAtapiRequest( + _In_ PHW_DEVICE_UNIT DeviceUnit, + _In_ PATA_DEVICE_REQUEST Request, + _In_ UCHAR IdeStatus) +{ + UCHAR InterruptReason; + + InterruptReason = ATA_READ(DeviceUnit->Registers.InterruptReason); + InterruptReason &= ATAPI_INT_REASON_MASK; + InterruptReason |= IdeStatus & IDE_STATUS_DRQ; + + switch (InterruptReason) { - for (DeviceNumber = 0; DeviceNumber < MAX_DEVICES; ++DeviceNumber) + case ATAPI_INT_REASON_AWAIT_CDB: { - if (IdentifyDevice(Channel, DeviceNumber, &DeviceUnit)) - { - Units[(*DetectedCount)++] = DeviceUnit; - } + if (!(Request->Flags & REQUEST_FLAG_AWAIT_CDB)) + return ATA_STATUS_RESET; + + Request->Flags &= ~REQUEST_FLAG_AWAIT_CDB; + + AtapSendCdb(DeviceUnit, Request); + return ATA_STATUS_PENDING; } + + case ATAPI_INT_REASON_DATA_IN: + { + ULONG ByteCount; + + if (!Request->DataBuffer || (Request->Flags & REQUEST_FLAG_AWAIT_CDB)) + return ATA_STATUS_RESET; + + ByteCount = ATA_READ(DeviceUnit->Registers.ByteCountLow); + ByteCount |= ATA_READ(DeviceUnit->Registers.ByteCountHigh) << 8; + + AtapPioDataIn(DeviceUnit, ByteCount); + return ATA_STATUS_PENDING; + } + + case ATAPI_INT_REASON_STATUS_NEC: + { + /* The NEC CDR-260 drive always clears CoD and IO on command completion */ + if (!(DeviceUnit->P.Flags & ATA_DEVICE_IS_NEC_CDR260)) + return ATA_STATUS_RESET; + + __fallthrough; + } + case ATAPI_INT_REASON_STATUS: + { + if (IdeStatus & (IDE_STATUS_ERROR | IDE_STATUS_DEVICE_FAULT)) + return ATA_STATUS_ERROR; + + break; + } + + default: + return ATA_STATUS_RESET; } - return (*DetectedCount > 0); + return ATA_STATUS_SUCCESS; +} + +static +UCHAR +AtapProcessAtaRequest( + _In_ PHW_DEVICE_UNIT DeviceUnit, + _In_ PATA_DEVICE_REQUEST Request, + _In_ UCHAR IdeStatus) +{ + /* Check for errors */ + if (IdeStatus & (IDE_STATUS_ERROR | IDE_STATUS_DEVICE_FAULT)) + { + if (IdeStatus & IDE_STATUS_DRQ) + return ATA_STATUS_RESET; + else + return ATA_STATUS_ERROR; + } + + /* Read command */ + if (Request->DataBuffer) + { + if (!(IdeStatus & IDE_STATUS_DRQ)) + return ATA_STATUS_RESET; + + /* Read the next data block */ + AtapPioDataIn(DeviceUnit, DeviceUnit->DrqByteCount); + + if (DeviceUnit->BytesToTransfer != 0) + return ATA_STATUS_PENDING; + + /* All data has been transferred, wait for DRQ to clear */ + if (!AtapWaitForIdle(&DeviceUnit->Registers, &IdeStatus)) + return ATA_STATUS_RESET; + + if (IdeStatus & (IDE_STATUS_ERROR | IDE_STATUS_DEVICE_FAULT)) + return ATA_STATUS_ERROR; + } + + /* Status phase or non-data ATA command */ + return ATA_STATUS_SUCCESS; } +static +BOOLEAN +AtapProcessRequest( + _In_ PHW_DEVICE_UNIT DeviceUnit, + _In_ PATA_DEVICE_REQUEST Request, + _In_ UCHAR IdeStatus) +{ + if (Request->Flags & REQUEST_FLAG_PACKET_COMMAND) + return AtapProcessAtapiRequest(DeviceUnit, Request, IdeStatus); + else + return AtapProcessAtaRequest(DeviceUnit, Request, IdeStatus); +} + +static +VOID +AtapIssuePacketCommand( + _In_ PHW_DEVICE_UNIT DeviceUnit, + _In_ PATA_DEVICE_REQUEST Request) +{ + USHORT ByteCount; + + Request->Flags |= REQUEST_FLAG_AWAIT_CDB; + + /* + * If a larger transfer is attempted, the 16-bit ByteCount register might overflow. + * In this case we round down the length to the closest multiple of 2. + */ + ByteCount = min(Request->DataTransferLength, 0xFFFE); + + /* Prepare to transfer a device command */ + ATA_WRITE(DeviceUnit->Registers.ByteCountLow, (UCHAR)(ByteCount >> 0)); + ATA_WRITE(DeviceUnit->Registers.ByteCountHigh, (UCHAR)(ByteCount >> 8)); + ATA_WRITE(DeviceUnit->Registers.Features, IDE_FEATURE_PIO); + ATA_WRITE(DeviceUnit->Registers.Command, IDE_COMMAND_ATAPI_PACKET); +} + +static VOID -AtaFree(VOID) +AtapLoadTaskFile( + _In_ PHW_DEVICE_UNIT DeviceUnit, + _In_ PATA_DEVICE_REQUEST Request) { - UCHAR i; + PATA_TASKFILE TaskFile = &Request->TaskFile; + ULONG i, BlockCount; - for (i = 0; i < RTL_NUMBER_OF(Units); ++i) + /* Store the extra information in the second byte of FIFO for 48-bit commands */ + i = (Request->Flags & REQUEST_FLAG_LBA48) ? 2 : 1; + + while (i--) + { + ATA_WRITE(DeviceUnit->Registers.Features, TaskFile->Data[i].Feature); + ATA_WRITE(DeviceUnit->Registers.SectorCount, TaskFile->Data[i].SectorCount); + ATA_WRITE(DeviceUnit->Registers.LbaLow, TaskFile->Data[i].LowLba); + ATA_WRITE(DeviceUnit->Registers.LbaMid, TaskFile->Data[i].MidLba); + ATA_WRITE(DeviceUnit->Registers.LbaHigh, TaskFile->Data[i].HighLba); + } + if (Request->Flags & REQUEST_FLAG_SET_DEVICE_REGISTER) { - if (Units[i]) - FrLdrTempFree(Units[i], TAG_ATA_DEVICE); + ATA_WRITE(DeviceUnit->Registers.Device, TaskFile->DriveSelect); } + ATA_WRITE(DeviceUnit->Registers.Command, TaskFile->Command); + + /* Set the byte count per DRQ data block */ + if (Request->Flags & REQUEST_FLAG_READ_WRITE_MULTIPLE) + BlockCount = DeviceUnit->MultiSectorTransfer; + else + BlockCount = 1; + DeviceUnit->DrqByteCount = BlockCount * DeviceUnit->P.SectorSize; } -PDEVICE_UNIT -AtaGetDevice(IN UCHAR UnitNumber) +static +UCHAR +AtapSendCommand( + _In_ PHW_DEVICE_UNIT DeviceUnit, + _In_ PATA_DEVICE_REQUEST Request) { - if (UnitNumber < RTL_NUMBER_OF(Units)) - return Units[UnitNumber]; + UCHAR AtaStatus; + + DeviceUnit->BytesToTransfer = Request->DataTransferLength; + DeviceUnit->DataBuffer = Request->DataBuffer; + + /* Select the device */ + AtapSelectDevice(&DeviceUnit->Registers, DeviceUnit->DeviceNumber); + if (!AtapWaitForNotBusy(&DeviceUnit->Registers, ATA_TIME_BUSY_SELECT, NULL)) + return ATA_STATUS_RETRY; + + /* Always disable interrupts, otherwise it may lead to problems in underlying BIOS firmware */ + ATA_WRITE(DeviceUnit->Registers.Control, IDE_DC_DISABLE_INTERRUPTS | IDE_DC_ALWAYS); + + if (Request->Flags & REQUEST_FLAG_PACKET_COMMAND) + AtapIssuePacketCommand(DeviceUnit, Request); else - return NULL; + AtapLoadTaskFile(DeviceUnit, Request); + + while (TRUE) + { + UCHAR IdeStatus; + + ATA_IO_WAIT(); + + if (!AtapWaitForNotBusy(&DeviceUnit->Registers, ATA_TIME_BUSY_POLL, &IdeStatus)) + return ATA_STATUS_RESET; + + AtaStatus = AtapProcessRequest(DeviceUnit, Request, IdeStatus); + if (AtaStatus != ATA_STATUS_PENDING) + break; + } + + return AtaStatus; } +static +VOID +AtapAtapiBuildRequestSense( + _In_ PATA_DEVICE_REQUEST Request, + _Out_ PSENSE_DATA SenseData) +{ + Request->Flags = REQUEST_FLAG_PACKET_COMMAND; + Request->DataBuffer = SenseData; + Request->DataTransferLength = sizeof(*SenseData); + Request->Cdb[0] = SCSIOP_REQUEST_SENSE; + Request->Cdb[4] = (UCHAR)Request->DataTransferLength; +} + +static BOOLEAN -AtaAtapiReadLogicalSectorsLBA( - IN OUT PDEVICE_UNIT DeviceUnit, - IN ULONGLONG SectorNumber, - IN ULONG SectorCount, - OUT PVOID Buffer) +AtapAtapiHandleError( + _In_ PHW_DEVICE_UNIT DeviceUnit) { - UCHAR RetryCount; - BOOLEAN Success; + ATA_DEVICE_REQUEST Request = { 0 }; + SENSE_DATA SenseData; - if (DeviceUnit == NULL || SectorCount == 0) + AtapAtapiBuildRequestSense(&Request, &SenseData); + if (AtapSendCommand(DeviceUnit, &Request) != ATA_STATUS_SUCCESS) return FALSE; - if (DeviceUnit->Flags & ATA_DEVICE_ATAPI) + ERR("SK %02X, ASC %02X, ASCQ %02X\n", + SenseData.SenseKey, + SenseData.AdditionalSenseCode, + SenseData.AdditionalSenseCodeQualifier); + + return TRUE; +} + +static +BOOLEAN +AtapIssueCommand( + _In_ PHW_DEVICE_UNIT DeviceUnit, + _In_ PATA_DEVICE_REQUEST Request) +{ + ULONG RetryCount; + + for (RetryCount = 0; RetryCount < 3; ++RetryCount) { - if ((DeviceUnit->Flags & ATA_DEVICE_NO_MEDIA) || (DeviceUnit->Flags & ATA_DEVICE_NOT_READY)) + UCHAR AtaStatus; + + AtaStatus = AtapSendCommand(DeviceUnit, Request); + + if ((AtaStatus != ATA_STATUS_SUCCESS) && + !(Request->Flags & REQUEST_FLAG_IDENTIFY_COMMAND)) { - /* Retry 4 times */ - for (RetryCount = 0; RetryCount < 4; ++RetryCount) + ERR("ATA%s command %02X failed %u %02X:%02X at %X:%u\n", + (Request->Flags & REQUEST_FLAG_PACKET_COMMAND) ? "PI" : "", + (Request->Flags & REQUEST_FLAG_PACKET_COMMAND) ? + Request->Cdb[0] : Request->TaskFile.Command, + AtaStatus, + ATA_READ(DeviceUnit->Registers.Status), + ATA_READ(DeviceUnit->Registers.Error), + DeviceUnit->Registers.Data, + DeviceUnit->DeviceNumber); + } + + switch (AtaStatus) + { + case ATA_STATUS_SUCCESS: + return TRUE; + + case ATA_STATUS_RETRY: + break; + + case ATA_STATUS_RESET: { - /* Make the device ready */ - if (AtapiReadyCheck(DeviceUnit)) - break; + if (Request->Flags & REQUEST_FLAG_IDENTIFY_COMMAND) + { + /* + * Some controllers indicate status 0x00 + * when the selected device does not exist, + * no point in going further. + */ + if (ATA_READ(DeviceUnit->Registers.Status) == 0) + return FALSE; + } + + /* Turn off various things and retry the command */ + DeviceUnit->MultiSectorTransfer = 0; + DeviceUnit->P.Flags &= ~ATA_DEVICE_FLAG_IO32; + + if (!AtapPerformSoftwareReset(DeviceUnit)) + return FALSE; + + break; } - if (RetryCount >= 4) + + default: { - ERR("AtaAtapiReadLogicalSectorsLBA(): Device not ready.\n"); - return FALSE; - } - } - if (SectorNumber + SectorCount > DeviceUnit->TotalSectors + 1) - { - ERR("AtaAtapiReadLogicalSectorsLBA(): Attempt to read more than there is to read.\n"); - return FALSE; - } + if (Request->Flags & REQUEST_FLAG_PACKET_COMMAND) + { + if (!AtapAtapiHandleError(DeviceUnit)) + return FALSE; + } - while (SectorCount > 0) - { - /* Read a single sector */ - Success = AtapiReadLogicalSectorLBA(DeviceUnit, SectorNumber, Buffer); - if (!Success) - return FALSE; - - --SectorCount; - ++SectorNumber; - Buffer = (PVOID)((ULONG_PTR)Buffer + DeviceUnit->SectorSize); + /* Only retry failed read commands */ + if (!(Request->Flags & REQUEST_FLAG_READ_COMMAND)) + return FALSE; + + break; + } } } - else + + return FALSE; +} + +static +UCHAR +AtapGetReadCommand( + _In_ PATA_DEVICE_REQUEST Request) +{ + static const UCHAR AtapReadCommandMap[2][2] = { - /* Retry 3 times */ - for (RetryCount = 0; RetryCount < 3; ++RetryCount) - { - /* Read a multiple sectors */ - Success = AtaReadLogicalSectorsLBA(DeviceUnit, SectorNumber, SectorCount, Buffer); - if (Success) - return TRUE; - } - return FALSE; - } + /* Read Read EXT */ + { IDE_COMMAND_READ, IDE_COMMAND_READ_EXT }, // PIO single + { IDE_COMMAND_READ_MULTIPLE, IDE_COMMAND_READ_MULTIPLE_EXT }, // PIO multiple + }; - return TRUE; + return AtapReadCommandMap[(Request->Flags & REQUEST_FLAG_READ_WRITE_MULTIPLE) ? 1 : 0] + [(Request->Flags & REQUEST_FLAG_LBA48) ? 1 : 0]; } static -BOOLEAN -AtaReadLogicalSectorsLBA( - IN PDEVICE_UNIT DeviceUnit, - IN ULONGLONG SectorNumber, - IN ULONG SectorCount, - OUT PVOID Buffer) -{ - UCHAR Command; - ULONG ChsTemp; - USHORT Cylinder; - UCHAR Head; - UCHAR Sector; - ULONG BlockCount; - ULONG RemainingBlockCount; - ULONGLONG Lba; - BOOLEAN UseLBA48; - - UseLBA48 = (DeviceUnit->Flags & ATA_DEVICE_LBA48) && - (((SectorNumber + SectorCount) >= UINT64_C(0x0FFFFF80)) || SectorCount > 256); +VOID +AtapBuildReadTaskFile( + _In_ PHW_DEVICE_UNIT DeviceUnit, + _In_ PATA_DEVICE_REQUEST Request, + _In_ ULONG64 Lba, + _In_ ULONG SectorCount) +{ + PATA_TASKFILE TaskFile = &Request->TaskFile; + UCHAR DriveSelect; - while (SectorCount > 0) + Request->Flags = REQUEST_FLAG_READ_COMMAND | REQUEST_FLAG_SET_DEVICE_REGISTER; + + if (DeviceUnit->MultiSectorTransfer != 0) { - /* Prevent sector count overflow, divide it into maximum possible chunks and loop each one */ - if (UseLBA48) - BlockCount = min(SectorCount, USHRT_MAX); - else - BlockCount = min(SectorCount, UCHAR_MAX); + Request->Flags |= REQUEST_FLAG_READ_WRITE_MULTIPLE; + } - /* Convert LBA into a format CHS if needed */ - if (DeviceUnit->Flags & ATA_DEVICE_CHS) + if (DeviceUnit->P.Flags & ATA_DEVICE_LBA) + { + DriveSelect = IDE_LBA_MODE; + + TaskFile->Data[0].SectorCount = (UCHAR)SectorCount; + TaskFile->Data[0].LowLba = (UCHAR)Lba; // LBA bits 0-7 + TaskFile->Data[0].MidLba = (UCHAR)(Lba >> 8); // LBA bits 8-15 + TaskFile->Data[0].HighLba = (UCHAR)(Lba >> 16); // LBA bits 16-23 + + if ((DeviceUnit->P.Flags & ATA_DEVICE_LBA48) && (AtaCommandUseLba48(Lba, SectorCount))) { - ChsTemp = DeviceUnit->IdentifyData.SectorsPerTrack * DeviceUnit->IdentifyData.NumberOfHeads; - if (ChsTemp) - { - Cylinder = SectorNumber / ChsTemp; - Head = (SectorNumber % ChsTemp) / DeviceUnit->IdentifyData.SectorsPerTrack; - Sector = (SectorNumber % DeviceUnit->IdentifyData.SectorsPerTrack) + 1; - } - else - { - Cylinder = 0; - Head = 0; - Sector = 1; - } - Lba = (Sector & 0xFF) | ((Cylinder & 0xFFFFF) << 8) | ((Head & 0x0F) << 24); + ASSERT((Lba + SectorCount) <= ATA_MAX_LBA_48); + + /* 48-bit command */ + TaskFile->Data[1].SectorCount = (UCHAR)(SectorCount >> 8); + TaskFile->Data[1].LowLba = (UCHAR)(Lba >> 24); // LBA bits 24-31 + TaskFile->Data[1].MidLba = (UCHAR)(Lba >> 32); // LBA bits 32-39 + TaskFile->Data[1].HighLba = (UCHAR)(Lba >> 40); // LBA bits 40-47 + + Request->Flags |= REQUEST_FLAG_LBA48; } else { - Lba = SectorNumber; + ASSERT((Lba + SectorCount) <= ATA_MAX_LBA_28); + + /* 28-bit command */ + DriveSelect |= ((Lba >> 24) & 0x0F); // LBA bits 24-27 } + } + else + { + ULONG ChsTemp, Cylinder, Head, Sector; + + ChsTemp = (ULONG)Lba / DeviceUnit->P.SectorsPerTrack; + + /* Legacy CHS translation */ + Cylinder = ChsTemp / DeviceUnit->P.Heads; + Head = ChsTemp % DeviceUnit->P.Heads; + Sector = ((ULONG)Lba % DeviceUnit->P.SectorsPerTrack) + 1; + + ASSERT(Cylinder <= 65535 && Head <= 15 && Sector <= 255); + + TaskFile->Data[0].SectorCount = (UCHAR)SectorCount; + TaskFile->Data[0].LowLba = (UCHAR)Sector; + TaskFile->Data[0].MidLba = (UCHAR)Cylinder; + TaskFile->Data[0].HighLba = (UCHAR)(Cylinder >> 8); + + DriveSelect = Head; + } + TaskFile->DriveSelect = DeviceUnit->DeviceSelect | DriveSelect; + TaskFile->Command = AtapGetReadCommand(Request); +} - /* Select the drive */ - SelectDevice(DeviceUnit->Channel, DeviceUnit->DeviceNumber); - if (!WaitForBusy(DeviceUnit->Channel, ATA_STATUS_TIMEOUT)) - { - ERR("AtaReadLogicalSectorsLBA() failed. Device is busy.\n"); - return FALSE; - } +static +VOID +AtapBuildReadPacketCommand( + _In_ PATA_DEVICE_REQUEST Request, + _In_ ULONG64 Lba, + _In_ ULONG SectorCount) +{ + Request->Flags = REQUEST_FLAG_READ_COMMAND | REQUEST_FLAG_PACKET_COMMAND; - /* Disable interrupts */ - AtaWritePort(DeviceUnit->Channel, IDX_IO2_o_Control, IDE_DC_DISABLE_INTERRUPTS); - StallExecutionProcessor(1); + RtlZeroMemory(Request->Cdb, sizeof(Request->Cdb)); - if (UseLBA48) - { - /* FIFO */ - AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_Feature, 0); - AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_Feature, ATA_PIO); - AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_BlockCount, (BlockCount >> 8) & 0xFF); - AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_BlockCount, BlockCount & 0xFF); - AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_BlockNumber, (Lba >> 24) & 0xFF); - AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_BlockNumber, Lba & 0xFF); - AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_CylinderLow, (Lba >> 32) & 0xFF); - AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_CylinderLow, (Lba >> 8) & 0xFF); - AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_CylinderHigh, (Lba >> 40) & 0xFF); - AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_CylinderHigh, (Lba >> 16) & 0xFF); - AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_DriveSelect, - IDE_USE_LBA | (DeviceUnit->DeviceNumber ? IDE_DRIVE_2 : IDE_DRIVE_1)); - Command = IDE_COMMAND_READ_EXT; - } - else - { - AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_Feature, ATA_PIO); - AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_BlockCount, BlockCount & 0xFF); - AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_BlockNumber, Lba & 0xFF); - AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_CylinderLow, (Lba >> 8) & 0xFF); - AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_CylinderHigh, (Lba >> 16) & 0xFF); - AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_DriveSelect, - ((Lba >> 24) & 0x0F) | - (DeviceUnit->Flags & ATA_DEVICE_CHS ? 0x00 : IDE_USE_LBA) | - (DeviceUnit->DeviceNumber ? IDE_DRIVE_SELECT_2 : IDE_DRIVE_SELECT_1)); - Command = IDE_COMMAND_READ; - } + if (Lba > MAXULONG) + { + /* READ (16) */ + Request->Cdb[0] = SCSIOP_READ16; + Request->Cdb[2] = (UCHAR)(Lba >> 56); + Request->Cdb[3] = (UCHAR)(Lba >> 48); + Request->Cdb[4] = (UCHAR)(Lba >> 40); + Request->Cdb[5] = (UCHAR)(Lba >> 32); + Request->Cdb[6] = (UCHAR)(Lba >> 24); + Request->Cdb[7] = (UCHAR)(Lba >> 16); + Request->Cdb[8] = (UCHAR)(Lba >> 8); + Request->Cdb[9] = (UCHAR)(Lba >> 0); + Request->Cdb[10] = (UCHAR)(SectorCount >> 24); + Request->Cdb[11] = (UCHAR)(SectorCount >> 16); + Request->Cdb[12] = (UCHAR)(SectorCount >> 8); + Request->Cdb[13] = (UCHAR)(SectorCount >> 0); + } + else + { + /* READ (10) */ + Request->Cdb[0] = SCSIOP_READ; + Request->Cdb[2] = (UCHAR)(Lba >> 24); + Request->Cdb[3] = (UCHAR)(Lba >> 16); + Request->Cdb[4] = (UCHAR)(Lba >> 8); + Request->Cdb[5] = (UCHAR)(Lba >> 0); + Request->Cdb[7] = (UCHAR)(SectorCount >> 8); + Request->Cdb[8] = (UCHAR)(SectorCount >> 0); + } +} + +static +BOOLEAN +AtapIsDevicePresent( + _In_ PHW_DEVICE_UNIT DeviceUnit) +{ + PIDE_REGISTERS Registers = &DeviceUnit->Registers; + UCHAR IdeStatus; - /* Send read command */ - AtaWritePort(DeviceUnit->Channel, IDX_IO1_o_Command, Command); - StallExecutionProcessor(5); + AtapSelectDevice(Registers, DeviceUnit->DeviceNumber); - for (RemainingBlockCount = BlockCount; RemainingBlockCount > 0; --RemainingBlockCount) - { - /* Wait for ready to transfer data block */ - if (!WaitForFlags(DeviceUnit->Channel, IDE_STATUS_DRQ, - IDE_STATUS_DRQ, ATA_STATUS_TIMEOUT)) - { - ERR("AtaReadLogicalSectorsLBA() failed. Status: 0x%02x, Error: 0x%02x\n", - AtaReadPort(DeviceUnit->Channel, IDX_IO1_i_Status), - AtaReadPort(DeviceUnit->Channel, IDX_IO1_i_Error)); - return FALSE; - } + IdeStatus = ATA_READ(Registers->Status); + if (IdeStatus == 0xFF || IdeStatus == 0x7F) + return FALSE; - /* Transfer the data block */ - AtaReadBuffer(DeviceUnit->Channel, Buffer, DeviceUnit->SectorSize); + ATA_WRITE(Registers->ByteCountLow, 0x55); + ATA_WRITE(Registers->ByteCountLow, 0xAA); + ATA_WRITE(Registers->ByteCountLow, 0x55); + if (ATA_READ(Registers->ByteCountLow) != 0x55) + return FALSE; + ATA_WRITE(Registers->ByteCountHigh, 0xAA); + ATA_WRITE(Registers->ByteCountHigh, 0x55); + ATA_WRITE(Registers->ByteCountHigh, 0xAA); + if (ATA_READ(Registers->ByteCountHigh) != 0xAA) + return FALSE; - Buffer = (PVOID)((ULONG_PTR)Buffer + DeviceUnit->SectorSize); - } + if (!AtapWaitForNotBusy(Registers, ATA_TIME_BUSY_ENUM, &IdeStatus)) + { + ERR("Device %X:%u is busy %02x\n", Registers->Data, DeviceUnit->DeviceNumber, IdeStatus); - SectorNumber += BlockCount; - SectorCount -= BlockCount; + /* Bring the device into a known state */ + if (!AtapPerformSoftwareReset(DeviceUnit)) + return FALSE; } return TRUE; @@ -373,569 +752,577 @@ AtaReadLogicalSectorsLBA( static BOOLEAN -AtaSendAtapiPacket( - IN UCHAR Channel, - IN PUCHAR AtapiPacket, - IN UCHAR PacketSize, - IN USHORT ByteCount) +AtapReadIdentifyData( + _In_ PHW_DEVICE_UNIT DeviceUnit, + _In_ UCHAR Command) { + ATA_DEVICE_REQUEST Request = { 0 }; + PIDENTIFY_DEVICE_DATA Id = &DeviceUnit->IdentifyDeviceData; + + /* Send the identify command */ + Request.Flags = REQUEST_FLAG_IDENTIFY_COMMAND; + Request.DataBuffer = Id; + Request.DataTransferLength = sizeof(*Id); + Request.TaskFile.Command = Command; + + return AtapIssueCommand(DeviceUnit, &Request); +} + +static +ATA_DEVICE_CLASS +AtapIdentifyDevice( + _In_ PHW_DEVICE_UNIT DeviceUnit) +{ + if (!AtapIsDevicePresent(DeviceUnit)) + return DEV_NONE; + /* - * REQUEST SENSE is used by driver to clear the ATAPI 'Bus reset' indication. - * TEST UNIT READY doesn't require space for returned data. + * We don't check the device signature here, + * because the NEC CDR-260 drive reports an ATA signature. */ - UCHAR ExpectedFlagsMask = (AtapiPacket[0] == SCSIOP_REQUEST_SENSE) ? - IDE_STATUS_DRDY : (IDE_STATUS_DRQ | IDE_STATUS_DRDY); - UCHAR ExpectedFlags = ((AtapiPacket[0] == SCSIOP_TEST_UNIT_READY) || - (AtapiPacket[0] == SCSIOP_REQUEST_SENSE)) ? - IDE_STATUS_DRDY : (IDE_STATUS_DRQ | IDE_STATUS_DRDY); - - /* PIO mode */ - AtaWritePort(Channel, IDX_ATAPI_IO1_o_Feature, ATA_PIO); - - /* Maximum byte count that is to be transferred */ - AtaWritePort(Channel, IDX_ATAPI_IO1_o_ByteCountLow, ByteCount & 0xFF); - AtaWritePort(Channel, IDX_ATAPI_IO1_o_ByteCountHigh, (ByteCount >> 8) & 0xFF); - - /* Prepare to transfer a device command via a command packet */ - AtaWritePort(Channel, IDX_ATAPI_IO1_o_Command, IDE_COMMAND_ATAPI_PACKET); - StallExecutionProcessor(50); - if (!WaitForFlagsOr(Channel, IDE_STATUS_DRQ, IDE_STATUS_DRDY, ATA_STATUS_TIMEOUT)) - { - ERR("AtaSendAtapiPacket(0x%x) failed. A device error occurred Status: 0x%02x, Error: 0x%02x\n", - AtapiPacket[0], AtaReadPort(Channel, IDX_ATAPI_IO1_i_Status), AtaReadPort(Channel, IDX_ATAPI_IO1_i_Error)); - return FALSE; - } - /* Command packet transfer */ - AtaWriteBuffer(Channel, AtapiPacket, PacketSize); - if (!WaitForFlags(Channel, ExpectedFlagsMask, ExpectedFlags, ATA_STATUS_TIMEOUT)) - { - TRACE("AtaSendAtapiPacket(0x%x) failed. An execution error occurred Status: 0x%02x, Error: 0x%02x\n", - AtapiPacket[0], AtaReadPort(Channel, IDX_ATAPI_IO1_i_Status), AtaReadPort(Channel, IDX_ATAPI_IO1_i_Error)); - return FALSE; - } + /* Check for ATA */ + if (AtapReadIdentifyData(DeviceUnit, IDE_COMMAND_IDENTIFY)) + return DEV_ATA; - return TRUE; + /* Check for ATAPI */ + if (AtapReadIdentifyData(DeviceUnit, IDE_COMMAND_ATAPI_IDENTIFY)) + return DEV_ATAPI; + + return DEV_NONE; } static BOOLEAN -AtapiReadLogicalSectorLBA( - IN PDEVICE_UNIT DeviceUnit, - IN ULONGLONG SectorNumber, - OUT PVOID Buffer) +AtapAtapiReadCapacity16( + _In_ PHW_DEVICE_UNIT DeviceUnit, + _Out_ PREAD_CAPACITY16_DATA CapacityData) { - UCHAR AtapiPacket[16]; - USHORT DataSize; - BOOLEAN Success; + ATA_DEVICE_REQUEST Request = { 0 }; - /* Select the drive */ - SelectDevice(DeviceUnit->Channel, DeviceUnit->DeviceNumber); - if (!WaitForBusy(DeviceUnit->Channel, ATA_STATUS_TIMEOUT)) - { - ERR("AtapiReadLogicalSectorLBA() failed. Device is busy!\n"); - return FALSE; - } + /* Send the SCSI READ CAPACITY(16) command */ + Request.Flags = REQUEST_FLAG_PACKET_COMMAND; + Request.DataBuffer = CapacityData; + Request.DataTransferLength = sizeof(*CapacityData); + Request.Cdb[0] = SCSIOP_SERVICE_ACTION_IN16; + Request.Cdb[1] = SERVICE_ACTION_READ_CAPACITY16; + Request.Cdb[13] = sizeof(*CapacityData); - /* Disable interrupts */ - AtaWritePort(DeviceUnit->Channel, IDX_IO2_o_Control, IDE_DC_DISABLE_INTERRUPTS); - StallExecutionProcessor(1); - - /* Send the SCSI READ command */ - RtlZeroMemory(&AtapiPacket, sizeof(AtapiPacket)); - AtapiPacket[0] = SCSIOP_READ; - AtapiPacket[2] = (SectorNumber >> 24) & 0xFF; - AtapiPacket[3] = (SectorNumber >> 16) & 0xFF; - AtapiPacket[4] = (SectorNumber >> 8) & 0xFF; - AtapiPacket[5] = SectorNumber & 0xFF; - AtapiPacket[8] = 1; - Success = AtaSendAtapiPacket(DeviceUnit->Channel, - AtapiPacket, - ATAPI_PACKET_SIZE(DeviceUnit->IdentifyData), - DeviceUnit->SectorSize); - if (!Success) - { - ERR("AtapiReadLogicalSectorLBA() failed. A read error occurred.\n"); - AtapiPrintSenseData(DeviceUnit); - return FALSE; - } + return AtapIssueCommand(DeviceUnit, &Request); +} - DataSize = (AtaReadPort(DeviceUnit->Channel, IDX_ATAPI_IO1_i_ByteCountHigh) << 8) | - AtaReadPort(DeviceUnit->Channel, IDX_ATAPI_IO1_i_ByteCountLow); +static +BOOLEAN +AtapAtapiReadCapacity10( + _In_ PHW_DEVICE_UNIT DeviceUnit, + _Out_ PREAD_CAPACITY_DATA CapacityData) +{ + ATA_DEVICE_REQUEST Request = { 0 }; - /* Transfer the data block */ - AtaReadBuffer(DeviceUnit->Channel, Buffer, DataSize); + /* Send the SCSI READ CAPACITY(10) command */ + Request.Flags = REQUEST_FLAG_PACKET_COMMAND; + Request.DataBuffer = CapacityData; + Request.DataTransferLength = sizeof(*CapacityData); + Request.Cdb[0] = SCSIOP_READ_CAPACITY; - return TRUE; + return AtapIssueCommand(DeviceUnit, &Request); } static VOID -AtapiCapacityDetect( - IN PDEVICE_UNIT DeviceUnit, - OUT PULONGLONG TotalSectors, - OUT PULONG SectorSize) +AtapAtapiDetectCapacity( + _In_ PHW_DEVICE_UNIT DeviceUnit, + _Out_ PULONG64 TotalSectors, + _Out_ PULONG SectorSize) { - UCHAR AtapiPacket[16]; - UCHAR AtapiCapacity[8]; - - /* Send the SCSI READ CAPACITY(10) command */ - RtlZeroMemory(&AtapiPacket, sizeof(AtapiPacket)); - AtapiPacket[0] = SCSIOP_READ_CAPACITY; - if (AtaSendAtapiPacket(DeviceUnit->Channel, AtapiPacket, ATAPI_PACKET_SIZE(DeviceUnit->IdentifyData), 8)) + union { - AtaReadBuffer(DeviceUnit->Channel, &AtapiCapacity, 8); + READ_CAPACITY_DATA Cmd10; + READ_CAPACITY16_DATA Cmd16; + } CapacityData; + ULONG LastLba; - *TotalSectors = (AtapiCapacity[0] << 24) | (AtapiCapacity[1] << 16) | - (AtapiCapacity[2] << 8) | AtapiCapacity[3]; + *TotalSectors = 0; + *SectorSize = 0; - *SectorSize = (AtapiCapacity[4] << 24) | (AtapiCapacity[5] << 16) | - (AtapiCapacity[6] << 8) | AtapiCapacity[7]; + if (!AtapAtapiReadCapacity10(DeviceUnit, &CapacityData.Cmd10)) + return; - /* If device reports a non-zero block length, reset to defaults (we use READ command instead of READ CD) */ - if (*SectorSize != 0) - *SectorSize = 2048; + LastLba = RtlUlongByteSwap(CapacityData.Cmd10.LogicalBlockAddress); + if (LastLba == MAXULONG) + { + if (!AtapAtapiReadCapacity16(DeviceUnit, &CapacityData.Cmd16)) + return; + + *TotalSectors = RtlUlonglongByteSwap(CapacityData.Cmd16.LogicalBlockAddress.QuadPart) + 1; + *SectorSize = RtlUlongByteSwap(CapacityData.Cmd16.BytesPerBlock); } else { - *TotalSectors = 0; - *SectorSize = 0; - - AtapiPrintSenseData(DeviceUnit); + *TotalSectors = LastLba + 1; + *SectorSize = RtlUlongByteSwap(CapacityData.Cmd10.BytesPerBlock); } + + /* + * If device reports a non-zero block length, reset to defaults + * (we use a READ command instead of READ CD). + */ + if (*SectorSize != 0) + *SectorSize = 2048; } static BOOLEAN -AtapiRequestSense( - IN PDEVICE_UNIT DeviceUnit, - OUT PSENSE_DATA SenseData) -{ - UCHAR AtapiPacket[16]; - BOOLEAN Success; - - RtlZeroMemory(&AtapiPacket, sizeof(AtapiPacket)); - RtlZeroMemory(SenseData, sizeof(SENSE_DATA)); - AtapiPacket[0] = SCSIOP_REQUEST_SENSE; - AtapiPacket[4] = SENSE_BUFFER_SIZE; - Success = AtaSendAtapiPacket(DeviceUnit->Channel, - AtapiPacket, - ATAPI_PACKET_SIZE(DeviceUnit->IdentifyData), - SENSE_BUFFER_SIZE); - if (Success) - { - AtaReadBuffer(DeviceUnit->Channel, SenseData, SENSE_BUFFER_SIZE); - return TRUE; - } - else - { - ERR("Cannot read the sense data.\n"); - return FALSE; - } +AtapAtapiTestUnitReady( + _In_ PHW_DEVICE_UNIT DeviceUnit) +{ + ATA_DEVICE_REQUEST Request = { 0 }; + + /* Send the SCSI TEST UNIT READY command */ + Request.Flags = REQUEST_FLAG_PACKET_COMMAND; + Request.Cdb[0] = SCSIOP_TEST_UNIT_READY; + + return AtapIssueCommand(DeviceUnit, &Request); } static -VOID -AtapiPrintSenseData(IN PDEVICE_UNIT DeviceUnit) +BOOLEAN +AtapAtapiRequestSense( + _In_ PHW_DEVICE_UNIT DeviceUnit, + _Out_ PSENSE_DATA SenseData) { - SENSE_DATA SenseData; + ATA_DEVICE_REQUEST Request = { 0 }; - if (AtapiRequestSense(DeviceUnit, &SenseData)) - { - ERR("SK 0x%x, ASC 0x%x, ASCQ 0x%x\n", - SenseData.SenseKey, - SenseData.AdditionalSenseCode, - SenseData.AdditionalSenseCodeQualifier); - } + AtapAtapiBuildRequestSense(&Request, SenseData); + return AtapIssueCommand(DeviceUnit, &Request); } static BOOLEAN -AtapiReadyCheck(IN OUT PDEVICE_UNIT DeviceUnit) +AtapAtapiReadToc( + _In_ PHW_DEVICE_UNIT DeviceUnit) { - UCHAR AtapiPacket[16]; + ATA_DEVICE_REQUEST Request = { 0 }; UCHAR DummyData[MAXIMUM_CDROM_SIZE]; + + /* Send the SCSI READ TOC command */ + Request.Flags = REQUEST_FLAG_PACKET_COMMAND; + Request.DataBuffer = DummyData; + Request.DataTransferLength = sizeof(DummyData); + Request.Cdb[0] = SCSIOP_READ_TOC; + Request.Cdb[7] = (MAXIMUM_CDROM_SIZE >> 8) & 0xFF; + Request.Cdb[8] = MAXIMUM_CDROM_SIZE & 0xFF; + Request.Cdb[9] = READ_TOC_FORMAT_SESSION << 6; + + return AtapIssueCommand(DeviceUnit, &Request); +} + +static +BOOLEAN +AtapAtapiReadyCheck( + _In_ PHW_DEVICE_UNIT DeviceUnit) +{ SENSE_DATA SenseData; - BOOLEAN Success; - /* Select the drive */ - SelectDevice(DeviceUnit->Channel, DeviceUnit->DeviceNumber); - if (!WaitForBusy(DeviceUnit->Channel, ATA_STATUS_TIMEOUT)) + if (!AtapAtapiTestUnitReady(DeviceUnit)) return FALSE; - /* Send the SCSI TEST UNIT READY command */ - RtlZeroMemory(&AtapiPacket, sizeof(AtapiPacket)); - AtapiPacket[0] = SCSIOP_TEST_UNIT_READY; - AtaSendAtapiPacket(DeviceUnit->Channel, - AtapiPacket, - ATAPI_PACKET_SIZE(DeviceUnit->IdentifyData), - 0); - - if (!AtapiRequestSense(DeviceUnit, &SenseData)) + if (!AtapAtapiRequestSense(DeviceUnit, &SenseData)) return FALSE; - AtaReadBuffer(DeviceUnit->Channel, &SenseData, SENSE_BUFFER_SIZE); - TRACE("SK 0x%x, ASC 0x%x, ASCQ 0x%x\n", - SenseData.SenseKey, - SenseData.AdditionalSenseCode, - SenseData.AdditionalSenseCodeQualifier); - if (SenseData.SenseKey == SCSI_SENSE_NOT_READY) { + if (SenseData.AdditionalSenseCode == SCSI_ADSENSE_NO_MEDIA_IN_DEVICE) + return FALSE; + if (SenseData.AdditionalSenseCode == SCSI_ADSENSE_LUN_NOT_READY) { switch (SenseData.AdditionalSenseCodeQualifier) { case SCSI_SENSEQ_BECOMING_READY: /* Wait until the CD is spun up */ - StallExecutionProcessor(4e6); + StallExecutionProcessor(2e6); return FALSE; case SCSI_SENSEQ_INIT_COMMAND_REQUIRED: - /* The drive needs to be spun up, send the SCSI READ TOC command */ - RtlZeroMemory(&AtapiPacket, sizeof(AtapiPacket)); - AtapiPacket[0] = SCSIOP_READ_TOC; - AtapiPacket[7] = (MAXIMUM_CDROM_SIZE << 8) & 0xFF; - AtapiPacket[8] = MAXIMUM_CDROM_SIZE & 0xFF; - AtapiPacket[9] = READ_TOC_FORMAT_SESSION << 6; - Success = AtaSendAtapiPacket(DeviceUnit->Channel, - AtapiPacket, - ATAPI_PACKET_SIZE(DeviceUnit->IdentifyData), - MAXIMUM_CDROM_SIZE); - if (!Success) - { - AtapiPrintSenseData(DeviceUnit); - return FALSE; - } - - AtaReadBuffer(DeviceUnit->Channel, &DummyData, MAXIMUM_CDROM_SIZE); - /* fall through */ + /* The drive needs to be spun up */ + AtapAtapiReadToc(DeviceUnit); + return FALSE; default: - DeviceUnit->Flags &= ~ATA_DEVICE_NOT_READY; return FALSE; - } } - else if (SenseData.AdditionalSenseCode == SCSI_ADSENSE_NO_MEDIA_IN_DEVICE) + } + + return TRUE; +} + +static +VOID +AtapAtapiClearUnitAttention( + _In_ PHW_DEVICE_UNIT DeviceUnit) +{ + SENSE_DATA SenseData; + ULONG i; + + for (i = 0; i < 5; ++i) + { + if (!AtapAtapiRequestSense(DeviceUnit, &SenseData)) + continue; + + if ((SenseData.SenseKey != SCSI_SENSE_UNIT_ATTENTION) && + (SenseData.AdditionalSenseCode != SCSI_ADSENSE_BUS_RESET)) { - DeviceUnit->Flags |= ATA_DEVICE_NO_MEDIA; - return FALSE; + break; } } - else +} + +static +BOOLEAN +AtapAtapiInitDevice( + _In_ PHW_DEVICE_UNIT DeviceUnit) +{ + PIDENTIFY_PACKET_DATA IdentifyPacketData = &DeviceUnit->IdentifyPacketData; + ULONG i; + + DeviceUnit->CdbSize = AtaDevCdbSizeInWords(IdentifyPacketData); + + /* Clear the ATAPI 'Bus reset' indication */ + AtapAtapiClearUnitAttention(DeviceUnit); + + /* Make the device ready */ + for (i = 4; i > 0; i--) + { + if (AtapAtapiReadyCheck(DeviceUnit)) + break; + } + if (i == 0) { - DeviceUnit->Flags &= ~ATA_DEVICE_NOT_READY; + ERR("Device not ready\n"); + return FALSE; } - if (DeviceUnit->Flags & ATA_DEVICE_NO_MEDIA) + /* Detect a medium's capacity */ + AtapAtapiDetectCapacity(DeviceUnit, + &DeviceUnit->P.TotalSectors, + &DeviceUnit->P.SectorSize); + if (DeviceUnit->P.SectorSize == 0 || DeviceUnit->P.TotalSectors == 0) { - /* Detect a medium's capacity */ - AtapiCapacityDetect(DeviceUnit, &DeviceUnit->TotalSectors, &DeviceUnit->SectorSize); + TRACE("No media found\n"); + return FALSE; + } - /* If nothing was returned, reset to defaults */ - if (DeviceUnit->SectorSize == 0) - DeviceUnit->SectorSize = 2048; - if (DeviceUnit->TotalSectors == 0) - DeviceUnit->TotalSectors = 0xFFFFFFFF; + DeviceUnit->P.Cylinders = MAXULONG; + DeviceUnit->P.Heads = MAXULONG; + DeviceUnit->P.SectorsPerTrack = MAXULONG; - DeviceUnit->Flags &= ~ATA_DEVICE_NO_MEDIA; - } + DeviceUnit->MaximumTransferLength = 0xFFFF; return TRUE; } static -BOOLEAN -WaitForFlags( - IN UCHAR Channel, - IN UCHAR Flags, - IN UCHAR ExpectedValue, - IN ULONG Timeout) +VOID +AtapAtaSetMultipleMode( + _In_ PHW_DEVICE_UNIT DeviceUnit) { - UCHAR Status; + ATA_DEVICE_REQUEST Request = { 0 }; - ASSERT(Timeout != 0); +#if !defined(ATA_ENABLE_MULTIPLE_MODE) + /* Inherit multiple mode from the state the BIOS firmware left the device in during boot */ + DeviceUnit->MultiSectorTransfer = AtaDevCurrentSectorsPerDrq(&DeviceUnit->IdentifyDeviceData); + if (DeviceUnit->MultiSectorTransfer != 0) + return; +#endif - WaitForBusy(Channel, ATA_STATUS_TIMEOUT); + /* Use the maximum possible value */ + DeviceUnit->MultiSectorTransfer = AtaDevMaximumSectorsPerDrq(&DeviceUnit->IdentifyDeviceData); + if (DeviceUnit->MultiSectorTransfer == 0) + return; - while (Timeout--) + Request.TaskFile.Command = IDE_COMMAND_SET_MULTIPLE; + Request.TaskFile.Data[0].SectorCount = DeviceUnit->MultiSectorTransfer; + if (!AtapIssueCommand(DeviceUnit, &Request)) { - StallExecutionProcessor(10); - - Status = AtaReadPort(Channel, IDX_IO1_i_Status); - if (Status & IDE_STATUS_ERROR) - return FALSE; - else if ((Status & Flags) == ExpectedValue) - return TRUE; + DeviceUnit->MultiSectorTransfer = 0; } - return FALSE; } static BOOLEAN -WaitForFlagsOr( - IN UCHAR Channel, - IN UCHAR FirstValue, - IN UCHAR SecondValue, - IN ULONG Timeout) +AtapAtaInitDevice( + _In_ PHW_DEVICE_UNIT DeviceUnit) { - UCHAR Status; + PIDENTIFY_DEVICE_DATA IdentifyData = &DeviceUnit->IdentifyDeviceData; + ULONG64 TotalSectors; + USHORT Cylinders, Heads, SectorsPerTrack; - ASSERT(Timeout != 0); + DeviceUnit->MaximumTransferLength = 0xFF; - WaitForBusy(Channel, ATA_STATUS_TIMEOUT); + if (AtaDevIsCurrentGeometryValid(IdentifyData)) + AtaDevCurrentChsTranslation(IdentifyData, &Cylinders, &Heads, &SectorsPerTrack); + else + AtaDevDefaultChsTranslation(IdentifyData, &Cylinders, &Heads, &SectorsPerTrack); - while (Timeout--) + /* Using LBA addressing mode */ + if (AtaDevHasLbaTranslation(IdentifyData)) { - StallExecutionProcessor(10); + DeviceUnit->P.Flags |= ATA_DEVICE_LBA; - Status = AtaReadPort(Channel, IDX_IO1_i_Status); - if (Status & IDE_STATUS_ERROR) - return FALSE; - else if ((Status & FirstValue) || (Status & SecondValue)) - return TRUE; + if (AtaDevHas48BitAddressFeature(IdentifyData)) + { + /* Using LBA48 addressing mode */ + TotalSectors = AtaDevUserAddressableSectors48Bit(IdentifyData); + ASSERT(TotalSectors <= ATA_MAX_LBA_48); + + DeviceUnit->P.Flags |= ATA_DEVICE_LBA48; + DeviceUnit->MaximumTransferLength = 0x10000; + } + else + { + /* Using LBA28 addressing mode */ + TotalSectors = AtaDevUserAddressableSectors28Bit(IdentifyData); + ASSERT(TotalSectors <= ATA_MAX_LBA_28); + } } - return FALSE; + else + { + /* Using CHS addressing mode */ + TotalSectors = Cylinders * Heads * SectorsPerTrack; + } + + if (TotalSectors == 0) + { + ERR("Unknown geometry\n"); + return FALSE; + } + + DeviceUnit->P.TotalSectors = TotalSectors; + DeviceUnit->P.Cylinders = Cylinders; + DeviceUnit->P.Heads = Heads; + DeviceUnit->P.SectorsPerTrack = SectorsPerTrack; + DeviceUnit->P.SectorSize = AtaDevBytesPerLogicalSector(IdentifyData); + ASSERT(DeviceUnit->P.SectorSize >= 512); + DeviceUnit->P.SectorSize = max(DeviceUnit->P.SectorSize, 512); + + AtapAtaSetMultipleMode(DeviceUnit); + + TRACE("Multiple sector setting %u\n", DeviceUnit->MultiSectorTransfer); + + return TRUE; } static BOOLEAN -WaitForBusy( - IN UCHAR Channel, - IN ULONG Timeout) +AtapAnalyzeIdentifyData( + _In_ PHW_DEVICE_UNIT DeviceUnit, + _In_ ATA_DEVICE_CLASS DeviceClass) { - ASSERT(Timeout != 0); + PIDENTIFY_DEVICE_DATA Id = &DeviceUnit->IdentifyDeviceData; + ULONG i; - while (Timeout--) + /* Verify the checksum */ + if (!AtaDevIsIdentifyDataValid(Id)) { - StallExecutionProcessor(10); + ERR("Identify data CRC error\n"); + return FALSE; + } - if ((AtaReadPort(Channel, IDX_IO1_i_Status) & IDE_STATUS_BUSY) == 0) - return TRUE; + if (DeviceClass == DEV_ATAPI) + { + DeviceUnit->P.Flags |= ATA_DEVICE_ATAPI | ATA_DEVICE_LBA; + + /* The returned string is not byteswapped */ + if (Id->ModelNumber[0] == 'N' && + Id->ModelNumber[1] == 'E' && + Id->ModelNumber[2] == 'C' && + Id->ModelNumber[3] == ' ') + { + DeviceUnit->P.Flags |= ATA_DEVICE_IS_NEC_CDR260; + } } - return FALSE; + + /* Swap byte order of the ASCII data */ + for (i = 0; i < sizeof(Id->SerialNumber) / 2; ++i) + ((PUSHORT)Id->SerialNumber)[i] = RtlUshortByteSwap(((PUSHORT)Id->SerialNumber)[i]); + + for (i = 0; i < sizeof(Id->FirmwareRevision) / 2; ++i) + ((PUSHORT)Id->FirmwareRevision)[i] = RtlUshortByteSwap(((PUSHORT)Id->FirmwareRevision)[i]); + + for (i = 0; i < sizeof(Id->ModelNumber) / 2; ++i) + ((PUSHORT)Id->ModelNumber)[i] = RtlUshortByteSwap(((PUSHORT)Id->ModelNumber)[i]); + + TRACE("MN '%.*s'\n", sizeof(Id->ModelNumber), Id->ModelNumber); + TRACE("FR '%.*s'\n", sizeof(Id->FirmwareRevision), Id->FirmwareRevision); + TRACE("S/N '%.*s'\n", sizeof(Id->SerialNumber), Id->SerialNumber); + + return TRUE; } static -VOID -AtaHardReset(IN UCHAR Channel) +BOOLEAN +AtapInitDevice( + _In_ PHW_DEVICE_UNIT DeviceUnit, + _In_ ATA_DEVICE_CLASS DeviceClass) { - TRACE("AtaHardReset(Controller %d)\n", Channel); + if (!AtapAnalyzeIdentifyData(DeviceUnit, DeviceClass)) + return FALSE; - AtaWritePort(Channel, IDX_IO2_o_Control, IDE_DC_RESET_CONTROLLER); - StallExecutionProcessor(100000); - AtaWritePort(Channel, IDX_IO2_o_Control, IDE_DC_REENABLE_CONTROLLER); - StallExecutionProcessor(5); - WaitForBusy(Channel, ATA_STATUS_TIMEOUT); + if (DeviceClass == DEV_ATAPI) + return AtapAtapiInitDevice(DeviceUnit); + else + return AtapAtaInitDevice(DeviceUnit); } static -VOID -SelectDevice(IN UCHAR Channel, IN UCHAR DeviceNumber) +BOOLEAN +AtapIdentifyChannel( + _In_ ULONG ChannelNumber, + _Out_ PIDE_REGISTERS Registers) { + const IDE_REG IoBase = AtapChannelBaseArray[ChannelNumber]; + ULONG Spare; + +#if defined(SARCH_PC98) + if (ATA_READ(0x432) == 0xFF) + return FALSE; +#endif + #if defined(SARCH_PC98) - /* Select IDE Channel */ - WRITE_PORT_UCHAR((PUCHAR)IDE_IO_o_BankSelect, Channel); - StallExecutionProcessor(5); + Spare = 2; + Registers->Control = 0x74C; +#else + Spare = 1; + Registers->Control = IoBase + 0x206; #endif + Registers->Data = IoBase + 0 * Spare; + Registers->Error = IoBase + 1 * Spare; + Registers->SectorCount = IoBase + 2 * Spare; + Registers->LbaLow = IoBase + 3 * Spare; + Registers->LbaMid = IoBase + 4 * Spare; + Registers->LbaHigh = IoBase + 5 * Spare; + Registers->Device = IoBase + 6 * Spare; + Registers->Status = IoBase + 7 * Spare; - AtaWritePort(Channel, IDX_IO1_o_DriveSelect, - DeviceNumber ? IDE_DRIVE_SELECT_2 : IDE_DRIVE_SELECT_1); - StallExecutionProcessor(5); + return TRUE; } -static +/* PUBLIC FUNCTIONS ***********************************************************/ + BOOLEAN -IdentifyDevice( - IN UCHAR Channel, - IN UCHAR DeviceNumber, - OUT PDEVICE_UNIT *DeviceUnit) -{ - UCHAR SignatureLow, SignatureHigh, SignatureCount, SignatureNumber; - UCHAR Command; - IDENTIFY_DATA Id; - SENSE_DATA SenseData; - ULONG i; - ULONG SectorSize; - ULONGLONG TotalSectors; - USHORT Flags = 0; - - TRACE("IdentifyDevice() Channel = %x, Device = %x, BaseIoAddress = 0x%x\n", - Channel, DeviceNumber, BaseArray[Channel]); - - /* Look at controller */ - SelectDevice(Channel, DeviceNumber); - StallExecutionProcessor(5); - AtaWritePort(Channel, IDX_IO1_o_BlockNumber, 0x55); - AtaWritePort(Channel, IDX_IO1_o_BlockNumber, 0x55); - StallExecutionProcessor(5); - if (AtaReadPort(Channel, IDX_IO1_i_BlockNumber) != 0x55) - goto Failure; - - /* Reset the controller */ - AtaHardReset(Channel); - - /* Select the drive */ - SelectDevice(Channel, DeviceNumber); - if (!WaitForBusy(Channel, ATA_STATUS_TIMEOUT)) - goto Failure; - - /* Signature check */ - SignatureLow = AtaReadPort(Channel, IDX_IO1_i_CylinderLow); - SignatureHigh = AtaReadPort(Channel, IDX_IO1_i_CylinderHigh); - SignatureCount = AtaReadPort(Channel, IDX_IO1_i_BlockCount); - SignatureNumber = AtaReadPort(Channel, IDX_IO1_i_BlockNumber); - TRACE("IdentifyDevice(): SL = 0x%x, SH = 0x%x, SC = 0x%x, SN = 0x%x\n", - SignatureLow, SignatureHigh, SignatureCount, SignatureNumber); - if (SignatureLow == 0x00 && SignatureHigh == 0x00 && - SignatureCount == 0x01 && SignatureNumber == 0x01) - { - TRACE("IdentifyDevice(): Found PATA device at %d:%d\n", Channel, DeviceNumber); - Command = IDE_COMMAND_IDENTIFY; - } - else if (SignatureLow == ATAPI_MAGIC_LSB && - SignatureHigh == ATAPI_MAGIC_MSB) - { - TRACE("IdentifyDevice(): Found ATAPI device at %d:%d\n", Channel, DeviceNumber); - Flags |= ATA_DEVICE_ATAPI | ATA_DEVICE_LBA | ATA_DEVICE_NOT_READY; - Command = IDE_COMMAND_ATAPI_IDENTIFY; - } - else - { - goto Failure; - } +AtaReadLogicalSectors( + _In_ PDEVICE_UNIT DeviceUnit, + _In_ ULONG64 SectorNumber, + _In_ ULONG SectorCount, + _Out_writes_bytes_all_(SectorCount * DeviceUnit->SectorSize) PVOID Buffer) +{ + PHW_DEVICE_UNIT Unit = (PHW_DEVICE_UNIT)DeviceUnit; + ATA_DEVICE_REQUEST Request = { 0 }; - /* Disable interrupts */ - AtaWritePort(Channel, IDX_IO2_o_Control, IDE_DC_DISABLE_INTERRUPTS); - StallExecutionProcessor(5); + ASSERT((SectorNumber + SectorCount) <= Unit->P.TotalSectors); + ASSERT(SectorCount != 0); - /* Send the identify command */ - AtaWritePort(Channel, IDX_IO1_o_Command, Command); - StallExecutionProcessor(50); - if (!WaitForFlags(Channel, IDE_STATUS_DRQ, IDE_STATUS_DRQ, ATA_STATUS_TIMEOUT)) + while (SectorCount > 0) { - ERR("IdentifyDevice(): Identify command failed.\n"); - goto Failure; - } + ULONG BlockCount; - /* Receive parameter information from the device */ - AtaReadBuffer(Channel, &Id, IDENTIFY_DATA_SIZE); + BlockCount = min(SectorCount, Unit->MaximumTransferLength); - /* Swap byte order of the ASCII data */ - for (i = 0; i < RTL_NUMBER_OF(Id.SerialNumber); ++i) - Id.SerialNumber[i] = RtlUshortByteSwap(Id.SerialNumber[i]); + Request.DataBuffer = Buffer; + Request.DataTransferLength = BlockCount * Unit->P.SectorSize; - for (i = 0; i < RTL_NUMBER_OF(Id.FirmwareRevision); ++i) - Id.FirmwareRevision[i] = RtlUshortByteSwap(Id.FirmwareRevision[i]); + if (Unit->P.Flags & ATA_DEVICE_ATAPI) + AtapBuildReadPacketCommand(&Request, SectorNumber, BlockCount); + else + AtapBuildReadTaskFile(Unit, &Request, SectorNumber, BlockCount); - for (i = 0; i < RTL_NUMBER_OF(Id.ModelNumber); ++i) - Id.ModelNumber[i] = RtlUshortByteSwap(Id.ModelNumber[i]); + if (!AtapIssueCommand(Unit, &Request)) + return FALSE; - TRACE("S/N %.*s\n", sizeof(Id.SerialNumber), Id.SerialNumber); - TRACE("FR %.*s\n", sizeof(Id.FirmwareRevision), Id.FirmwareRevision); - TRACE("MN %.*s\n", sizeof(Id.ModelNumber), Id.ModelNumber); + SectorNumber += BlockCount; + SectorCount -= BlockCount; - /* Allocate a new device unit structure */ - *DeviceUnit = FrLdrTempAlloc(sizeof(DEVICE_UNIT), TAG_ATA_DEVICE); - if (*DeviceUnit == NULL) - { - ERR("Failed to allocate device unit!\n"); - return FALSE; + Buffer = (PVOID)((ULONG_PTR)Buffer + Unit->P.SectorSize); } - RtlZeroMemory(*DeviceUnit, sizeof(DEVICE_UNIT)); - (*DeviceUnit)->Channel = Channel; - (*DeviceUnit)->DeviceNumber = DeviceNumber; - (*DeviceUnit)->IdentifyData = Id; + return TRUE; +} - if (Flags & ATA_DEVICE_ATAPI) - { - /* Clear the ATAPI 'Bus reset' indication */ - for (i = 0; i < 10; ++i) - { - AtapiRequestSense(*DeviceUnit, &SenseData); - StallExecutionProcessor(10); - } +PDEVICE_UNIT +AtaGetDevice( + _In_ UCHAR UnitNumber) +{ + if (UnitNumber < RTL_NUMBER_OF(AtapUnits)) + return (PDEVICE_UNIT)AtapUnits[UnitNumber]; - /* Detect a medium's capacity */ - AtapiCapacityDetect(*DeviceUnit, &TotalSectors, &SectorSize); - if (SectorSize == 0 || TotalSectors == 0) - { - /* It's ok and can be used to show alert like "Please insert the CD" */ - TRACE("No media found.\n"); - Flags |= ATA_DEVICE_NO_MEDIA; - } - } - else + return NULL; +} + +BOOLEAN +AtaInit( + _Out_ PUCHAR DetectedCount) +{ + ULONG ChannelNumber; + + *DetectedCount = 0; + + /* Enumerate IDE channels */ + for (ChannelNumber = 0; ChannelNumber < CHANNEL_MAX_CHANNELS; ++ChannelNumber) { - if (Id.SupportLba || (Id.MajorRevision && Id.UserAddressableSectors)) - { - if (Id.FeaturesSupport.Address48) - { - TRACE("Using LBA48 addressing mode.\n"); - Flags |= ATA_DEVICE_LBA48 | ATA_DEVICE_LBA; - TotalSectors = Id.UserAddressableSectors48; - } - else - { - TRACE("Using LBA28 addressing mode.\n"); - Flags |= ATA_DEVICE_LBA; - TotalSectors = Id.UserAddressableSectors; - } + UCHAR DeviceNumber; + IDE_REGISTERS Registers; - /* LBA ATA drives always have a sector size of 512 */ - SectorSize = 512; - } - else + if (!AtapIdentifyChannel(ChannelNumber, &Registers)) + continue; + + /* Check for devices attached to the bus */ + for (DeviceNumber = 0; DeviceNumber < CHANNEL_MAX_DEVICES; ++DeviceNumber) { - TRACE("Using CHS addressing mode.\n"); - Flags |= ATA_DEVICE_CHS; + PHW_DEVICE_UNIT DeviceUnit; + ATA_DEVICE_CLASS DeviceClass; - if (Id.UnformattedBytesPerSector == 0) - { - SectorSize = 512; - } - else + /* Allocate a new device unit structure */ + DeviceUnit = FrLdrTempAlloc(sizeof(*DeviceUnit), TAG_ATA_DEVICE); + if (!DeviceUnit) { - for (i = 1 << 15; i > 0; i >>= 1) - { - if ((Id.UnformattedBytesPerSector & i) != 0) - { - SectorSize = i; - break; - } - } + ERR("Failed to allocate device unit!\n"); + continue; } - TotalSectors = Id.NumberOfCylinders * Id.NumberOfHeads * Id.SectorsPerTrack; - } - } - TRACE("Sector size %d ; Total sectors %I64d\n", SectorSize, TotalSectors); + RtlZeroMemory(DeviceUnit, sizeof(*DeviceUnit)); - (*DeviceUnit)->Flags = Flags; - (*DeviceUnit)->SectorSize = SectorSize; - (*DeviceUnit)->TotalSectors = TotalSectors; - if (Flags & ATA_DEVICE_ATAPI) - { - (*DeviceUnit)->Cylinders = 0xFFFFFFFF; - (*DeviceUnit)->Heads = 0xFFFFFFFF; - (*DeviceUnit)->Sectors = 0xFFFFFFFF; - } - else - { - (*DeviceUnit)->Cylinders = Id.NumberOfCylinders; - (*DeviceUnit)->Heads = Id.NumberOfHeads; - (*DeviceUnit)->Sectors = Id.SectorsPerTrack; - } + /* Perform a minimal initialization */ + RtlCopyMemory(&DeviceUnit->Registers, &Registers, sizeof(Registers)); + DeviceUnit->DeviceNumber = DeviceNumber; + DeviceUnit->P.SectorSize = 512; + DeviceUnit->DeviceSelect = (DEV_SLAVE(DeviceNumber) << 4) | IDE_DRIVE_SELECT; -#if DBG - DbgDumpBuffer(DPRINT_DISK, &Id, IDENTIFY_DATA_SIZE); -#endif + /* Let's see what kind of device this is */ + DeviceClass = AtapIdentifyDevice(DeviceUnit); + if (DeviceClass == DEV_NONE) + goto NextDevice; - TRACE("IdentifyDevice() done.\n"); - return TRUE; + TRACE("Found %lu device at %X:%u\n", DeviceClass, Registers.Data, DeviceNumber); -Failure: - TRACE("IdentifyDevice() done. No device present at %d:%d\n", Channel, DeviceNumber); - return FALSE; + if (!AtapInitDevice(DeviceUnit, DeviceClass)) + goto NextDevice; + + TRACE("Total sectors %I64u of size %lu, CHS %lu:%lu:%lu, %lx\n", + DeviceUnit->P.TotalSectors, + DeviceUnit->P.SectorSize, + DeviceUnit->P.Cylinders, + DeviceUnit->P.Heads, + DeviceUnit->P.SectorsPerTrack, + DeviceUnit->P.Flags); + + AtapUnits[(*DetectedCount)++] = DeviceUnit; + continue; + +NextDevice: + FrLdrTempFree(DeviceUnit, TAG_ATA_DEVICE); + } + } + + return (*DetectedCount > 0); } diff --git a/boot/freeldr/freeldr/arch/drivers/hwidep.h b/boot/freeldr/freeldr/arch/drivers/hwidep.h new file mode 100644 index 0000000000000..748b58b244017 --- /dev/null +++ b/boot/freeldr/freeldr/arch/drivers/hwidep.h @@ -0,0 +1,387 @@ +/* + * PROJECT: FreeLoader + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: Private header for ATA/ATAPI programmed I/O driver. + * COPYRIGHT: Copyright 2019-2025 Dmitry Borisov (di.sean@protonmail.com) + */ + +#pragma once + +#define TAG_ATA_DEVICE 'dATA' + +#define ATA_STATUS_SUCCESS 0 +#define ATA_STATUS_PENDING 1 +#define ATA_STATUS_ERROR 2 +#define ATA_STATUS_RESET 3 +#define ATA_STATUS_RETRY 4 + +#if defined(SARCH_PC98) +/* Master/Slave devices for Bank 0 and Bank 1 */ +#define CHANNEL_MAX_DEVICES 4 +#define DEV_SLAVE(DeviceNumber) ((DeviceNumber) & 1) +#else +/* Master/Slave devices */ +#define CHANNEL_MAX_DEVICES 2 +#define DEV_SLAVE(DeviceNumber) (DeviceNumber) +#endif + +#if defined(SARCH_XBOX) +/* It's safe to enable the multiple mode */ +#define ATA_ENABLE_MULTIPLE_MODE +#endif + +/* Delay of 400ns */ +#if defined(SARCH_PC98) +#define ATA_IO_WAIT() WRITE_PORT_UCHAR((PUCHAR)0x5F, 0) +#else +#define ATA_IO_WAIT() StallExecutionProcessor(1) +#endif + +#if defined(_M_IX86) || defined(_M_AMD64) +/* x86 I/O address space spans from 0 to 0xFFFF */ +typedef USHORT IDE_REG; +#else +typedef ULONG_PTR IDE_REG; +#endif + +#define ATA_MAX_LBA_28 0x0FFFFFFFULL +#define ATA_MAX_LBA_48 (1ULL << 48) + +#define IDE_FEATURE_PIO 0x00 + +#define IDE_DC_ALWAYS 0x08 + +#define IDE_DRIVE_SELECT 0xA0 + +#define ATAPI_INT_REASON_COD 0x01 +#define ATAPI_INT_REASON_IO 0x02 +#define ATAPI_INT_REASON_MASK (ATAPI_INT_REASON_IO | ATAPI_INT_REASON_COD) + +#define ATAPI_INT_REASON_STATUS_NEC 0x00 +#define ATAPI_INT_REASON_STATUS (ATAPI_INT_REASON_IO | ATAPI_INT_REASON_COD) +#define ATAPI_INT_REASON_AWAIT_CDB (IDE_STATUS_DRQ | ATAPI_INT_REASON_COD) +#define ATAPI_INT_REASON_DATA_IN (ATAPI_INT_REASON_IO | IDE_STATUS_DRQ) + +#define MAXIMUM_CDROM_SIZE 804 // == sizeof(CDROM_TOC) + +#define ATA_TIME_BUSY_SELECT 2000 ///< 20 ms +#define ATA_TIME_BUSY_POLL 500000 ///< 5 s +#define ATA_TIME_BUSY_ENUM 100 ///< 1 ms +#define ATA_TIME_BUSY_RESET 1000000 ///< 10 s +#define ATA_TIME_RESET_SELECT 200000 ///< 2 s +#define ATA_TIME_DRQ_CLEAR 100 ///< 200 us +#define ATA_TIME_PHASE_CHANGE 100 ///< 1 ms + +#define ATA_WRITE(Port, Value) \ + WRITE_PORT_UCHAR((PUCHAR)(ULONG_PTR)(Port), (Value)) + +#define ATA_WRITE_BLOCK_16(Port, Buffer, Count) \ + WRITE_PORT_BUFFER_USHORT((PUSHORT)(ULONG_PTR)(Port), (PUSHORT)(Buffer), (Count)) + +#define ATA_WRITE_BLOCK_32(Port, Buffer, Count) \ + WRITE_PORT_BUFFER_ULONG((PULONG)(ULONG_PTR)(Port), (PULONG)(Buffer), (Count)) + +#define ATA_READ(Port) \ + READ_PORT_UCHAR((PUCHAR)(ULONG_PTR)(Port)) + +#define ATA_READ_BLOCK_16(Port, Buffer, Count) \ + READ_PORT_BUFFER_USHORT((PUSHORT)(ULONG_PTR)(Port), (PUSHORT)(Buffer), (Count)) + +#define ATA_READ_BLOCK_32(Port, Buffer, Count) \ + READ_PORT_BUFFER_ULONG((PULONG)(ULONG_PTR)(Port), (PULONG)(Buffer), (Count)) + +typedef enum _ATA_DEVICE_CLASS +{ + DEV_ATA, + DEV_ATAPI, + DEV_NONE, +} ATA_DEVICE_CLASS, *PATA_DEVICE_CLASS; + +typedef struct _IDE_REGISTERS +{ + IDE_REG Data; + union + { + IDE_REG Features; + IDE_REG Error; + }; + union + { + IDE_REG SectorCount; + IDE_REG InterruptReason; + }; + IDE_REG LbaLow; ///< LBA bits 0-7, 24-31 + union + { + IDE_REG LbaMid; ///< LBA bits 8-15, 32-39 + IDE_REG ByteCountLow; + IDE_REG SignatureLow; + }; + union + { + IDE_REG LbaHigh; ///< LBA bits 16-23, 40-47 + IDE_REG ByteCountHigh; + IDE_REG SignatureHigh; + }; + IDE_REG Device; + union + { + IDE_REG Command; + IDE_REG Status; + }; + union + { + IDE_REG Control; + IDE_REG AlternateStatus; + }; +} IDE_REGISTERS, *PIDE_REGISTERS; + +typedef struct _ATA_TASKFILE +{ + UCHAR DriveSelect; + UCHAR Command; + struct + { + UCHAR Feature; + UCHAR SectorCount; + UCHAR LowLba; + UCHAR MidLba; + UCHAR HighLba; + } Data[2]; // 0 - low part, 1 - high part +} ATA_TASKFILE, *PATA_TASKFILE; + +typedef struct _ATA_DEVICE_REQUEST +{ + union + { + UCHAR Cdb[16]; + ATA_TASKFILE TaskFile; + }; + PVOID DataBuffer; + ULONG Flags; +#define REQUEST_FLAG_LBA48 0x00000001 +#define REQUEST_FLAG_READ_WRITE_MULTIPLE 0x00000002 +#define REQUEST_FLAG_PACKET_COMMAND 0x00000004 +#define REQUEST_FLAG_SET_DEVICE_REGISTER 0x00000008 +#define REQUEST_FLAG_AWAIT_CDB 0x00000010 +#define REQUEST_FLAG_READ_COMMAND 0x00000020 +#define REQUEST_FLAG_IDENTIFY_COMMAND 0x00000040 + + ULONG DataTransferLength; +} ATA_DEVICE_REQUEST, *PATA_DEVICE_REQUEST; + +typedef struct _HW_DEVICE_UNIT +{ + /* Public data, must be the first member */ + DEVICE_UNIT P; + + IDE_REGISTERS Registers; + ULONG BytesToTransfer; + PUCHAR DataBuffer; + ULONG DrqByteCount; + ULONG MaximumTransferLength; + UCHAR DeviceNumber; + UCHAR DeviceSelect; + UCHAR CdbSize; + UCHAR MultiSectorTransfer; + union + { + IDENTIFY_DEVICE_DATA IdentifyDeviceData; + IDENTIFY_PACKET_DATA IdentifyPacketData; + }; +} HW_DEVICE_UNIT, *PHW_DEVICE_UNIT; + +FORCEINLINE +BOOLEAN +AtaDevIsIdentifyDataValid( + _In_ PIDENTIFY_DEVICE_DATA IdentifyData) +{ + ULONG i; + UCHAR Crc; + + /* Bits 0:8 of word 255 */ + if (IdentifyData->Signature != 0xA5) + { + /* The integrity word is missing, assume the data provided by the device is valid */ + return TRUE; + } + + /* Verify the checksum */ + Crc = 0; + for (i = 0; i < sizeof(*IdentifyData); ++i) + { + Crc += ((PUCHAR)IdentifyData)[i]; + } + + return (Crc == 0); +} + +FORCEINLINE +UCHAR +AtaDevCdbSizeInWords( + _In_ PIDENTIFY_PACKET_DATA IdentifyPacketData) +{ + /* Bits 0:2 of word 0 */ + return (IdentifyPacketData->GeneralConfiguration.PacketType != 0) ? 8 : 6; +} + +FORCEINLINE +BOOLEAN +AtaDevHasLbaTranslation( + _In_ PIDENTIFY_DEVICE_DATA IdentifyData) +{ + /* Bit 9 of word 49 */ + return IdentifyData->Capabilities.LbaSupported; +} + +FORCEINLINE +ULONG +AtaDevUserAddressableSectors28Bit( + _In_ PIDENTIFY_DEVICE_DATA IdentifyData) +{ + /* Words 60-61 */ + return IdentifyData->UserAddressableSectors; +} + +FORCEINLINE +ULONG64 +AtaDevUserAddressableSectors48Bit( + _In_ PIDENTIFY_DEVICE_DATA IdentifyData) +{ + /* Words 100-103 */ + return ((ULONG64)IdentifyData->Max48BitLBA[1] << 32) | IdentifyData->Max48BitLBA[0]; +} + +FORCEINLINE +BOOLEAN +AtaDevHas48BitAddressFeature( + _In_ PIDENTIFY_DEVICE_DATA IdentifyData) +{ + /* Word 83: 15 = 0, 14 = 1 */ + if (IdentifyData->CommandSetSupport.WordValid83 == 1) + { + /* Bit 10 of word 83 */ + return IdentifyData->CommandSetSupport.BigLba; + } + + return FALSE; +} + +FORCEINLINE +BOOLEAN +AtaDevIsCurrentGeometryValid( + _In_ PIDENTIFY_DEVICE_DATA IdentifyData) +{ + return ((IdentifyData->TranslationFieldsValid & 1) && + (IdentifyData->NumberOfCurrentCylinders != 0) && + (IdentifyData->NumberOfCurrentCylinders <= 63) && + (IdentifyData->NumberOfCurrentHeads != 0) && + (IdentifyData->NumberOfCurrentHeads <= 16) && + (IdentifyData->CurrentSectorsPerTrack != 0)); +} + +FORCEINLINE +VOID +AtaDevDefaultChsTranslation( + _In_ PIDENTIFY_DEVICE_DATA IdentifyData, + _Out_ PUSHORT Cylinders, + _Out_ PUSHORT Heads, + _Out_ PUSHORT SectorsPerTrack) +{ + /* Word 1 */ + *Cylinders = IdentifyData->NumCylinders; + + /* Word 3 */ + *Heads = IdentifyData->NumHeads; + + /* Word 6 */ + *SectorsPerTrack = IdentifyData->NumSectorsPerTrack; +} + +FORCEINLINE +VOID +AtaDevCurrentChsTranslation( + _In_ PIDENTIFY_DEVICE_DATA IdentifyData, + _Out_ PUSHORT Cylinders, + _Out_ PUSHORT Heads, + _Out_ PUSHORT SectorsPerTrack) +{ + /* Word 54 */ + *Cylinders = IdentifyData->NumberOfCurrentCylinders; + + /* Word 55 */ + *Heads = IdentifyData->NumberOfCurrentHeads; + + /* Word 55 */ + *SectorsPerTrack = IdentifyData->CurrentSectorsPerTrack; +} + +FORCEINLINE +UCHAR +AtaDevCurrentSectorsPerDrq( + _In_ PIDENTIFY_DEVICE_DATA IdentifyData) +{ + UCHAR MultiSectorCurrent; + + /* Bit 8 of word 59 */ + if (!(IdentifyData->MultiSectorSettingValid)) + return 0; + + /* The word 59 should be a power of 2 */ + MultiSectorCurrent = IdentifyData->CurrentMultiSectorSetting; + + if ((MultiSectorCurrent > 0) && ((MultiSectorCurrent & (MultiSectorCurrent - 1)) == 0)) + return MultiSectorCurrent; + + return 0; +} + +FORCEINLINE +UCHAR +AtaDevMaximumSectorsPerDrq( + _In_ PIDENTIFY_DEVICE_DATA IdentifyData) +{ + UCHAR MultiSectorMax; + + /* The word 47 should be a power of 2 */ + MultiSectorMax = IdentifyData->MaximumBlockTransfer; + + if ((MultiSectorMax > 0) && ((MultiSectorMax & (MultiSectorMax - 1)) == 0)) + return MultiSectorMax; + + return 0; +} + +FORCEINLINE +ULONG +AtaDevBytesPerLogicalSector( + _In_ PIDENTIFY_DEVICE_DATA IdentifyData) +{ + ULONG WordCount; + + /* Word 106: 15 = 0, 14 = 1, 12 = 1 */ + if (IdentifyData->PhysicalLogicalSectorSize.Reserved1 == 1 && + IdentifyData->PhysicalLogicalSectorSize.LogicalSectorLongerThan256Words) + { + /* Words 116-117 */ + WordCount = IdentifyData->WordsPerLogicalSector[0]; + WordCount |= (ULONG)IdentifyData->WordsPerLogicalSector[1] << 16; + } + else + { + /* 256 words = 512 bytes */ + WordCount = 256; + } + + return WordCount * sizeof(USHORT); +} + +FORCEINLINE +BOOLEAN +AtaCommandUseLba48( + _In_ ULONG64 SectorNumber, + _In_ ULONG SectorCount) +{ + /* Use the 48-bit command when reasonable */ + return (((SectorNumber + SectorCount) >= ATA_MAX_LBA_28) || (SectorCount > 0x100)); +} diff --git a/boot/freeldr/freeldr/arch/i386/hwacpi.c b/boot/freeldr/freeldr/arch/i386/hwacpi.c index ccd42b144e099..f2b43fde015b7 100644 --- a/boot/freeldr/freeldr/arch/i386/hwacpi.c +++ b/boot/freeldr/freeldr/arch/i386/hwacpi.c @@ -25,6 +25,11 @@ DBG_DEFAULT_CHANNEL(HWDETECT); BOOLEAN AcpiPresent = FALSE; +BOOLEAN IsAcpiPresent(VOID) +{ + return AcpiPresent; +} + static PRSDP_DESCRIPTOR FindAcpiBios(VOID) { diff --git a/boot/freeldr/freeldr/arch/i386/i386bug.c b/boot/freeldr/freeldr/arch/i386/i386bug.c index 1276ddad9bc69..0627f1d5d24aa 100644 --- a/boot/freeldr/freeldr/arch/i386/i386bug.c +++ b/boot/freeldr/freeldr/arch/i386/i386bug.c @@ -12,25 +12,25 @@ typedef struct _FRAME static const CHAR *i386ExceptionDescriptionText[] = { - "Exception 00: DIVIDE BY ZERO", - "Exception 01: DEBUG EXCEPTION", - "Exception 02: NON-MASKABLE INTERRUPT EXCEPTION", - "Exception 03: BREAKPOINT (INT 3)", - "Exception 04: OVERFLOW", - "Exception 05: BOUND EXCEPTION", - "Exception 06: INVALID OPCODE", - "Exception 07: FPU NOT AVAILABLE", - "Exception 08: DOUBLE FAULT", - "Exception 09: COPROCESSOR SEGMENT OVERRUN", - "Exception 0A: INVALID TSS", - "Exception 0B: SEGMENT NOT PRESENT", - "Exception 0C: STACK EXCEPTION", - "Exception 0D: GENERAL PROTECTION FAULT", - "Exception 0E: PAGE FAULT", - "Exception 0F: Reserved", - "Exception 10: COPROCESSOR ERROR", - "Exception 11: ALIGNMENT CHECK", - "Exception 12: MACHINE CHECK" + "DIVIDE BY ZERO", + "DEBUG EXCEPTION", + "NON-MASKABLE INTERRUPT EXCEPTION", + "BREAKPOINT (INT 3)", + "OVERFLOW", + "BOUND EXCEPTION", + "INVALID OPCODE", + "FPU NOT AVAILABLE", + "DOUBLE FAULT", + "COPROCESSOR SEGMENT OVERRUN", + "INVALID TSS", + "SEGMENT NOT PRESENT", + "STACK EXCEPTION", + "GENERAL PROTECTION FAULT", + "PAGE FAULT", + "Reserved", + "COPROCESSOR ERROR", + "ALIGNMENT CHECK", + "MACHINE CHECK" }; #define SCREEN_ATTR 0x1F // Bright white on blue background @@ -118,7 +118,10 @@ i386PrintExceptionText(ULONG TrapIndex, PKTRAP_FRAME TrapFrame, PKSPECIAL_REGIST PrintText("FreeLdr " KERNEL_VERSION_STR " " KERNEL_VERSION_BUILD_STR "\n" "Report this error on the ReactOS Bug Tracker: https://jira.reactos.org\n\n" - "0x%02lx: %s\n\n", TrapIndex, i386ExceptionDescriptionText[TrapIndex]); + "0x%02lx: Exception %02X: %s\n\n", + TrapIndex, + TrapIndex, + i386ExceptionDescriptionText[TrapIndex]); #ifdef _M_IX86 PrintText("EAX: %.8lx ESP: %.8lx CR0: %.8lx DR0: %.8lx\n", @@ -194,6 +197,7 @@ i386PrintExceptionText(ULONG TrapIndex, PKTRAP_FRAME TrapFrame, PKSPECIAL_REGIST InstructionPointer[6], InstructionPointer[7]); } +DECLSPEC_NORETURN VOID FrLdrBugCheckWithMessage( ULONG BugCode, @@ -227,8 +231,9 @@ FrLdrBugCheckWithMessage( for (;;); } +static +DECLSPEC_NORETURN void -NTAPI FrLdrBugCheckEx( ULONG BugCode, PCHAR File, @@ -256,6 +261,7 @@ FrLdrBugCheckEx( for (;;); } +DECLSPEC_NORETURN void NTAPI FrLdrBugCheck(ULONG BugCode) diff --git a/boot/freeldr/freeldr/arch/i386/i386trap.S b/boot/freeldr/freeldr/arch/i386/i386trap.S index bbc5367d70dd0..95b41ccd80a9c 100644 --- a/boot/freeldr/freeldr/arch/i386/i386trap.S +++ b/boot/freeldr/freeldr/arch/i386/i386trap.S @@ -142,6 +142,7 @@ TRAP_STUB _i386AlignmentCheck, 17 TRAP_STUB _i386MachineCheck, 18 TRAP_STUB _i386SimdFloatError, 19 +#if DBG /************************************************************************ * DEBUGGING SUPPORT FUNCTIONS ************************************************************************/ @@ -176,5 +177,6 @@ BREAKPOINT_TEMPLATE _MEMORY_WRITE_BREAKPOINT3, HEX(0f0ffffff), HEX(001000330) BREAKPOINT_TEMPLATE _INSTRUCTION_BREAKPOINT4, HEX(00fffffff), HEX(0000003c0) BREAKPOINT_TEMPLATE _MEMORY_READWRITE_BREAKPOINT4, HEX(00fffffff), HEX(0300003c0) BREAKPOINT_TEMPLATE _MEMORY_WRITE_BREAKPOINT4, HEX(00fffffff), HEX(0100003c0) +#endif // DBG END diff --git a/boot/freeldr/freeldr/arch/i386/pc/machpc.c b/boot/freeldr/freeldr/arch/i386/pc/machpc.c index fff1673feb411..8ec80eea5c3e3 100644 --- a/boot/freeldr/freeldr/arch/i386/pc/machpc.c +++ b/boot/freeldr/freeldr/arch/i386/pc/machpc.c @@ -274,7 +274,7 @@ DetectPnpBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber) NodeCount &= 0xFF; // needed since some fscked up BIOSes return // wrong info (e.g. Mac Virtual PC) - // e.g. look: http://my.execpc.com/~geezer/osd/pnp/pnp16.c + // e.g. look: https://web.archive.org/web/20080329010332/http://my.execpc.com/~geezer/osd/pnp/pnp16.c if (x != 0 || NodeSize == 0 || NodeCount == 0) { ERR("PnP-BIOS failed to enumerate device nodes\n"); @@ -706,7 +706,7 @@ PcGetSerialPort(ULONG Index, PULONG Irq) /* * The BIOS data area 0x400 holds the address of the first valid COM port. * Each COM port address is stored in a 2-byte field. - * Infos at: http://www.bioscentral.com/misc/bda.htm + * Infos at: https://web.archive.org/web/20240119203029/http://www.bioscentral.com/misc/bda.htm */ BasePtr = (PUSHORT)0x400; *Irq = PcIrq[Index]; @@ -884,7 +884,7 @@ DetectParallelPorts(PCONFIGURATION_COMPONENT_DATA BusKey) /* * The BIOS data area 0x408 holds the address of the first valid LPT port. * Each LPT port address is stored in a 2-byte field. - * Infos at: http://www.bioscentral.com/misc/bda.htm + * Infos at: https://web.archive.org/web/20240119203029/http://www.bioscentral.com/misc/bda.htm */ BasePtr = (PUSHORT)0x408; diff --git a/boot/freeldr/freeldr/arch/i386/pc98/machpc98.c b/boot/freeldr/freeldr/arch/i386/pc98/machpc98.c index 2ba4707de7a4c..7fd9e292b558f 100644 --- a/boot/freeldr/freeldr/arch/i386/pc98/machpc98.c +++ b/boot/freeldr/freeldr/arch/i386/pc98/machpc98.c @@ -34,7 +34,6 @@ Pc98HwIdle(VOID) VOID Pc98PrepareForReactOS(VOID) { - Pc98DiskPrepareForReactOS(); Pc98VideoPrepareForReactOS(); DiskStopFloppyMotor(); DebugDisableScreenPort(); diff --git a/boot/freeldr/freeldr/arch/i386/pc98/pc98disk.c b/boot/freeldr/freeldr/arch/i386/pc98/pc98disk.c index e6f98d136f7b5..0f9fdf1eb27fe 100644 --- a/boot/freeldr/freeldr/arch/i386/pc98/pc98disk.c +++ b/boot/freeldr/freeldr/arch/i386/pc98/pc98disk.c @@ -132,11 +132,6 @@ BOOLEAN DiskResetController(IN PPC98_DISK_DRIVE DiskDrive) return INT386_SUCCESS(Regs); } -VOID Pc98DiskPrepareForReactOS(VOID) -{ - AtaFree(); -} - PPC98_DISK_DRIVE Pc98DiskDriveNumberToDrive(IN UCHAR DriveNumber) { @@ -187,7 +182,7 @@ Pc98DiskReadLogicalSectorsLBA( if (DiskDrive->Type & DRIVE_IDE && DiskDrive->Type & DRIVE_CDROM) { - return AtaAtapiReadLogicalSectorsLBA(AtaGetDevice(DiskDrive->IdeUnitNumber), SectorNumber, SectorCount, Buffer); + return AtaReadLogicalSectors(AtaGetDevice(DiskDrive->IdeUnitNumber), SectorNumber, SectorCount, Buffer); } else { @@ -503,7 +498,7 @@ InitIdeDrive( { DiskDrive->Geometry.Cylinders = DeviceUnit->Cylinders; DiskDrive->Geometry.Heads = DeviceUnit->Heads; - DiskDrive->Geometry.SectorsPerTrack = DeviceUnit->Sectors; + DiskDrive->Geometry.SectorsPerTrack = DeviceUnit->SectorsPerTrack; DiskDrive->Geometry.BytesPerSector = DeviceUnit->SectorSize; DiskDrive->Geometry.Sectors = DeviceUnit->TotalSectors; diff --git a/boot/freeldr/freeldr/arch/i386/pc98/pc98hw.c b/boot/freeldr/freeldr/arch/i386/pc98/pc98hw.c index 6cff3e8640021..4591ed2916bba 100644 --- a/boot/freeldr/freeldr/arch/i386/pc98/pc98hw.c +++ b/boot/freeldr/freeldr/arch/i386/pc98/pc98hw.c @@ -1085,7 +1085,7 @@ DetectPnpBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber) NodeCount &= 0xFF; // needed since some fscked up BIOSes return // wrong info (e.g. Mac Virtual PC) - // e.g. look: http://my.execpc.com/~geezer/osd/pnp/pnp16.c + // e.g. look: https://web.archive.org/web/20080329010332/http://my.execpc.com/~geezer/osd/pnp/pnp16.c if (x != 0 || NodeSize == 0 || NodeCount == 0) { ERR("PnP-BIOS failed to enumerate device nodes\n"); diff --git a/boot/freeldr/freeldr/arch/i386/xbox/machxbox.c b/boot/freeldr/freeldr/arch/i386/xbox/machxbox.c index 6c0b094f49be7..ab3f802004141 100644 --- a/boot/freeldr/freeldr/arch/i386/xbox/machxbox.c +++ b/boot/freeldr/freeldr/arch/i386/xbox/machxbox.c @@ -374,7 +374,6 @@ XboxPrepareForReactOS(VOID) { /* On Xbox, prepare video and disk support */ XboxVideoPrepareForReactOS(); - XboxDiskInit(FALSE); DiskStopFloppyMotor(); /* Turn off debug messages to screen */ diff --git a/boot/freeldr/freeldr/arch/i386/xbox/xboxdisk.c b/boot/freeldr/freeldr/arch/i386/xbox/xboxdisk.c index 4afdc99c39817..6d6fee8ce4000 100644 --- a/boot/freeldr/freeldr/arch/i386/xbox/xboxdisk.c +++ b/boot/freeldr/freeldr/arch/i386/xbox/xboxdisk.c @@ -3,7 +3,7 @@ * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) * PURPOSE: Xbox specific disk access routines * COPYRIGHT: Copyright 2004 Gé van Geldorp (gvg@reactos.com) - * Copyright 2019 Dmitry Borisov (di.sean@protonmail.com) + * Copyright 2019-2025 Dmitry Borisov (di.sean@protonmail.com) */ /* INCLUDES *******************************************************************/ @@ -22,39 +22,36 @@ static BOOLEAN AtaInitialized = FALSE; /* FUNCTIONS ******************************************************************/ +static VOID -XboxDiskInit(BOOLEAN Init) +XboxDiskInit(VOID) { UCHAR DetectedCount; UCHAR UnitNumber; PDEVICE_UNIT DeviceUnit = NULL; - if (Init & !AtaInitialized) + ASSERT(!AtaInitialized); + + AtaInitialized = TRUE; + + /* Find first HDD and CD */ + AtaInit(&DetectedCount); + for (UnitNumber = 0; UnitNumber <= DetectedCount; UnitNumber++) { - /* Find first HDD and CD */ - AtaInit(&DetectedCount); - for (UnitNumber = 0; UnitNumber <= DetectedCount; UnitNumber++) + DeviceUnit = AtaGetDevice(UnitNumber); + if (DeviceUnit) { - DeviceUnit = AtaGetDevice(UnitNumber); - if (DeviceUnit) + if (DeviceUnit->Flags & ATA_DEVICE_ATAPI) + { + if (!CdDrive) + CdDrive = DeviceUnit; + } + else { - if (DeviceUnit->Flags & ATA_DEVICE_ATAPI) - { - if (!CdDrive) - CdDrive = DeviceUnit; - } - else - { - if (!HardDrive) - HardDrive = DeviceUnit; - } + if (!HardDrive) + HardDrive = DeviceUnit; } } - AtaInitialized = TRUE; - } - else - { - AtaFree(); } } @@ -67,7 +64,7 @@ XboxDiskDriveNumberToDeviceUnit(UCHAR DriveNumber) return NULL; if (!AtaInitialized) - XboxDiskInit(TRUE); + XboxDiskInit(); /* HDD */ if ((DriveNumber == 0x80) && HardDrive) @@ -96,7 +93,7 @@ XboxDiskReadLogicalSectors( if (!DeviceUnit) return FALSE; - return AtaAtapiReadLogicalSectorsLBA(DeviceUnit, SectorNumber, SectorCount, Buffer); + return AtaReadLogicalSectors(DeviceUnit, SectorNumber, SectorCount, Buffer); } BOOLEAN @@ -112,7 +109,7 @@ XboxDiskGetDriveGeometry(UCHAR DriveNumber, PGEOMETRY Geometry) Geometry->Cylinders = DeviceUnit->Cylinders; Geometry->Heads = DeviceUnit->Heads; - Geometry->SectorsPerTrack = DeviceUnit->Sectors; + Geometry->SectorsPerTrack = DeviceUnit->SectorsPerTrack; Geometry->BytesPerSector = DeviceUnit->SectorSize; Geometry->Sectors = DeviceUnit->TotalSectors; @@ -135,7 +132,7 @@ XboxDiskGetCacheableBlockCount(UCHAR DriveNumber) if (DeviceUnit->Flags & ATA_DEVICE_LBA) return 64; else - return DeviceUnit->Sectors; + return DeviceUnit->SectorsPerTrack; } /* EOF */ diff --git a/boot/freeldr/freeldr/arch/realmode/amd64.S b/boot/freeldr/freeldr/arch/realmode/amd64.S index cfd6a396cdbbf..b1e88af37d675 100644 --- a/boot/freeldr/freeldr/arch/realmode/amd64.S +++ b/boot/freeldr/freeldr/arch/realmode/amd64.S @@ -67,11 +67,7 @@ Msg_LongModeSupported: call writestr /* Load the GDT */ -#ifdef _USE_ML - lgdt fword ptr [gdtptr] -#else - lgdt cs:[gdtptr] -#endif + lgdt lXdtPrefix ds:[gdtptr] /* Build the startup page tables */ call BuildPageTables @@ -120,11 +116,7 @@ gdt: /* GDT table pointer */ gdtptr: .word HEX(37) /* Limit */ -#ifdef _USE_ML - .long offset gdt /* Base Address */ -#else - .long gdt /* Base Address */ -#endif + .long OFF(gdt) /* Base Address */ CheckFor64BitSupport: diff --git a/boot/freeldr/freeldr/arch/realmode/helpers_pc98.inc b/boot/freeldr/freeldr/arch/realmode/helpers_pc98.inc index f935d370df884..67e5c1cc42c20 100644 --- a/boot/freeldr/freeldr/arch/realmode/helpers_pc98.inc +++ b/boot/freeldr/freeldr/arch/realmode/helpers_pc98.inc @@ -56,12 +56,12 @@ writestr: jmp short .writestr_loop .writestr_cr: - mov ax, word ptr VramOffset + mov ax, word ptr ds:[VramOffset] mov dl, 80 * 2 div dl inc ax mul dl - mov word ptr VramOffset, ax + mov word ptr ds:[VramOffset], ax /* Skip the next LF character */ inc si @@ -80,27 +80,39 @@ writechr: pushf pusha + /* Check if the VRAM segment was initialized */ + mov dx, word ptr ds:[VramSegment] + test dx, dx + jnz short .writechr_write + /* High-resolution mode check */ test byte ptr ds:[HEX(501)], HEX(08) - jz .writechr_normal - push HEX(0E000) - jmp short .writechr_test_done -.writechr_normal: - push HEX(0A000) - + mov dx, HEX(0A000) // Suppose normal mode + jz short .writechr_test_done + mov dh, HEX(E0) // Change 0xA000 to 0xE000, use hi-res mode .writechr_test_done: - pop es - mov di, word ptr VramOffset + mov word ptr ds:[VramSegment], dx + +.writechr_write: + /* Load the VRAM segment and offset (ES:DI) */ + les di, dword ptr ds:[VramSegOff] + + /* Write ASCII directly to the VRAM (two bytes per character) */ xor ah, ah stosw - mov word ptr VramOffset, di + + /* Update the start position */ + mov word ptr ds:[VramOffset], di popa popf ret +VramSegOff: VramOffset: .word 0 +VramSegment: + .word 0 /* * Writes a hex number in (AL, AX, EAX) to the console diff --git a/boot/freeldr/freeldr/arch/realmode/i386.S b/boot/freeldr/freeldr/arch/realmode/i386.S index d2bcd7b928877..fdac4e52932ff 100644 --- a/boot/freeldr/freeldr/arch/realmode/i386.S +++ b/boot/freeldr/freeldr/arch/realmode/i386.S @@ -191,7 +191,7 @@ gdt: /* GDT table pointer */ gdtptr: .word HEX(27) /* Limit */ - .word gdt, 0 /* Base Address */ + .long OFF(gdt) /* Base Address */ /* Real-mode IDT pointer */ rmode_idtptr: diff --git a/boot/freeldr/freeldr/arch/uefi/uefihw.c b/boot/freeldr/freeldr/arch/uefi/uefihw.c index f671446b474b9..674d4bff84d83 100644 --- a/boot/freeldr/freeldr/arch/uefi/uefihw.c +++ b/boot/freeldr/freeldr/arch/uefi/uefihw.c @@ -24,6 +24,11 @@ BOOLEAN AcpiPresent = FALSE; /* FUNCTIONS *****************************************************************/ +BOOLEAN IsAcpiPresent(VOID) +{ + return AcpiPresent; +} + static PRSDP_DESCRIPTOR FindAcpiBios(VOID) diff --git a/boot/freeldr/freeldr/arch/uefi/uefildr.c b/boot/freeldr/freeldr/arch/uefi/uefildr.c index 69d5041d2ca12..e694b7aa2b0d4 100644 --- a/boot/freeldr/freeldr/arch/uefi/uefildr.c +++ b/boot/freeldr/freeldr/arch/uefi/uefildr.c @@ -80,6 +80,7 @@ ExecuteLoaderCleanly(PVOID PreviousStack) } #ifndef _M_ARM +DECLSPEC_NORETURN VOID __cdecl Reboot(VOID) { //TODO: Replace with a true firmware reboot eventually diff --git a/boot/freeldr/freeldr/bootmgr.c b/boot/freeldr/freeldr/bootmgr.c index ce977170d5d71..5a5d8335df7dd 100644 --- a/boot/freeldr/freeldr/bootmgr.c +++ b/boot/freeldr/freeldr/bootmgr.c @@ -85,7 +85,7 @@ WarnDeprecated( CHAR msgString[300]; /* If the user didn't cancel the timeout, don't display the warning */ - if (BootMgrInfo.TimeOut >= 0) + if (GetBootMgrInfo()->TimeOut >= 0) return; va_start(ap, MsgFmt); @@ -183,6 +183,7 @@ BuildArgvForOsLoader( PCHAR* Argv; PCHAR* Args; PCHAR SettingName, SettingValue; + PCCHAR BootPath = FrLdrGetBootPath(); *pArgc = 0; @@ -208,7 +209,7 @@ BuildArgvForOsLoader( /* i == 0: Program name */ // TODO: Provide one in the future... /* i == 1: SystemPartition : from where FreeLdr has been started */ - Size += (strlen("SystemPartition=") + strlen(FrLdrBootPath) + 1) * sizeof(CHAR); + Size += (strlen("SystemPartition=") + strlen(BootPath) + 1) * sizeof(CHAR); /* i == 2: LoadIdentifier : ASCII string that may be used * to associate an identifier with a set of load parameters */ if (LoadIdentifier) @@ -236,7 +237,7 @@ BuildArgvForOsLoader( /* i == 1: SystemPartition */ { strcpy(SettingName, "SystemPartition="); - strcat(SettingName, FrLdrBootPath); + strcat(SettingName, BootPath); *Args++ = SettingName; SettingName += (strlen(SettingName) + 1); @@ -333,12 +334,13 @@ MainBootMenuKeyPressFilter( IN PVOID Context OPTIONAL) { /* Any key-press cancels the global timeout */ - BootMgrInfo.TimeOut = -1; + GetBootMgrInfo()->TimeOut = -1; switch (KeyPress) { case KEY_F8: DoOptionsMenu(&((OperatingSystemItem*)Context)[SelectedMenuItem]); + DisplayBootTimeOptions(); return TRUE; #ifdef HAS_OPTION_MENU_EDIT_CMDLINE @@ -362,12 +364,6 @@ VOID RunLoader(VOID) ULONG SelectedOperatingSystem; ULONG i; - if (!MachInitializeBootDevices()) - { - UiMessageBoxCritical("Error when detecting hardware."); - return; - } - #ifdef _M_IX86 #ifndef UEFIBOOT /* Load additional SCSI driver (if any) */ @@ -394,7 +390,7 @@ VOID RunLoader(VOID) #endif /* Debugger main initialization */ - DebugInit(BootMgrInfo.DebugString); + DebugInit(GetBootMgrInfo()->DebugString); /* UI main initialization */ if (!UiInitialize(TRUE)) @@ -427,22 +423,21 @@ VOID RunLoader(VOID) } /* Find all the message box settings and run them */ - UiShowMessageBoxesInSection(BootMgrInfo.FrLdrSection); + UiShowMessageBoxesInSection(GetBootMgrInfo()->FrLdrSection); for (;;) { - /* Redraw the backdrop */ - UiDrawBackdrop(); + /* Redraw the backdrop, but don't overwrite boot options */ + UiDrawBackdrop(UiGetScreenHeight() - 2); /* Show the operating system list menu */ if (!UiDisplayMenu("Please select the operating system to start:", "For troubleshooting and advanced startup options for " "ReactOS, press F8.", - TRUE, OperatingSystemDisplayNames, OperatingSystemCount, DefaultOperatingSystem, - BootMgrInfo.TimeOut, + GetBootMgrInfo()->TimeOut, &SelectedOperatingSystem, FALSE, MainBootMenuKeyPressFilter, @@ -455,12 +450,12 @@ VOID RunLoader(VOID) /* Load the chosen operating system */ LoadOperatingSystem(&OperatingSystemList[SelectedOperatingSystem]); - BootMgrInfo.TimeOut = -1; + GetBootMgrInfo()->TimeOut = -1; /* If we get there, the OS loader failed. As it may have * messed up the display, re-initialize the UI. */ #ifndef _M_ARM - UiVtbl.UnInitialize(); + UiUnInitialize(""); #endif UiInitialize(TRUE); } diff --git a/boot/freeldr/freeldr/custom.c b/boot/freeldr/freeldr/custom.c index f0e984deb666a..7519d2d7fa5d1 100644 --- a/boot/freeldr/freeldr/custom.c +++ b/boot/freeldr/freeldr/custom.c @@ -126,7 +126,6 @@ VOID OptionMenuCustomBoot(VOID) OperatingSystemItem OperatingSystem; if (!UiDisplayMenu("Please choose a boot method:", NULL, - FALSE, CustomBootMenuList, RTL_NUMBER_OF(CustomBootMenuList), 0, -1, diff --git a/boot/freeldr/freeldr/disk/scsiport.c b/boot/freeldr/freeldr/disk/scsiport.c index 52d6fd4ecc618..fa63d6e63879c 100644 --- a/boot/freeldr/freeldr/disk/scsiport.c +++ b/boot/freeldr/freeldr/disk/scsiport.c @@ -1647,7 +1647,7 @@ LoadBootDeviceDriver(VOID) #endif /* Create full ntbootdd.sys path */ - strcpy(NtBootDdPath, FrLdrBootPath); + strcpy(NtBootDdPath, FrLdrGetBootPath()); strcat(NtBootDdPath, "\\NTBOOTDD.SYS"); /* Load ntbootdd.sys */ diff --git a/boot/freeldr/freeldr/freeldr.c b/boot/freeldr/freeldr/freeldr.c index d533061fb5d02..e39cf7e84aa90 100644 --- a/boot/freeldr/freeldr/freeldr.c +++ b/boot/freeldr/freeldr/freeldr.c @@ -30,6 +30,64 @@ CCHAR FrLdrBootPath[MAX_PATH] = ""; /* FUNCTIONS ******************************************************************/ +static +BOOLEAN +LoadRosload( + _In_ PCSTR RosloadPath, + _Out_ PVOID* ImageBase, + _Out_ PLDR_DATA_TABLE_ENTRY* DataTableEntry) +{ + CHAR FullPath[MAX_PATH]; + BOOLEAN Success; + + /* Create full rosload.exe path */ + RtlStringCbPrintfA(FullPath, + sizeof(FullPath), + "%s\\%s", + FrLdrBootPath, + RosloadPath); + + TRACE("Loading second stage loader '%s'\n", FullPath); + + /* Load rosload.exe as a bootloader image. The base name is "scsiport.sys", + because it exports ScsiPort* functions for ntbootdd.sys */ + Success = PeLdrLoadBootImage(FullPath, + "scsiport.sys", + ImageBase, + DataTableEntry); + if (!Success) + { + WARN("Failed to load second stage loader '%s'\n", FullPath); + return FALSE; + } + + return TRUE; +} + +static +ULONG +LaunchSecondStageLoader(VOID) +{ + PLDR_DATA_TABLE_ENTRY RosloadDTE; + PVOID ImageBase; + LONG (*EntryPoint)(VOID); + + /* Load the second stage loader */ + if (!LoadRosload("rosload.exe", &ImageBase, &RosloadDTE)) + { + /* Try in loader directory */ + if (!LoadRosload("loader\\rosload.exe", &ImageBase, &RosloadDTE)) + { + return ENOENT; + } + } + + /* Call the entrypoint */ + printf("Launching rosload.exe...\n"); + EntryPoint = VaToPa(RosloadDTE->EntryPoint); + return (*EntryPoint)(); +} + VOID __cdecl BootMain(IN PCCH CmdLine) { /* Load the default settings from the command-line */ @@ -71,7 +129,17 @@ VOID __cdecl BootMain(IN PCCH CmdLine) goto Quit; } - RunLoader(); + if (!MachInitializeBootDevices()) + { + UiMessageBoxCritical("Error when detecting hardware."); + goto Quit; + } + + /* Launch second stage loader */ + if (LaunchSecondStageLoader() != ESUCCESS) + { + UiMessageBoxCritical("Unable to load second stage loader."); + } Quit: /* If we reach this point, something went wrong before, therefore reboot */ @@ -124,3 +192,18 @@ double log10(double x) __debugbreak(); return 0.0; } + +PCCHAR FrLdrGetBootPath(VOID) +{ + return FrLdrBootPath; +} + +UCHAR FrldrGetBootDrive(VOID) +{ + return FrldrBootDrive; +} + +ULONG FrldrGetBootPartition(VOID) +{ + return FrldrBootPartition; +} diff --git a/boot/freeldr/freeldr/freeldr.spec b/boot/freeldr/freeldr/freeldr.spec index 3ffd70aac37a2..eaab809e800f9 100644 --- a/boot/freeldr/freeldr/freeldr.spec +++ b/boot/freeldr/freeldr/freeldr.spec @@ -1,47 +1,139 @@ + +# ARC +@ cdecl ArcClose() +@ cdecl ArcGetDiskCount() +@ cdecl ArcGetDiskInfo() +@ cdecl ArcGetFileInformation() +@ cdecl ArcGetTime() +@ cdecl ArcOpen() +@ cdecl ArcRead() +@ cdecl ArcSeek() + +# Debug +@ cdecl DbgParseDebugChannels() +@ cdecl DbgPrint(str) +@ cdecl DbgPrint2(long long str long str) +@ cdecl DebugDumpBuffer() +@ cdecl DebugInit() +@ cdecl FrLdrBugCheckWithMessage() +@ stdcall KeBugCheckEx(long long long long long) + +# Heap +@ cdecl FrLdrHeapAllocateEx() +@ cdecl FrLdrHeapFreeEx() +@ cdecl FrLdrHeapAlloc() +@ cdecl FrLdrHeapFree() +@ cdecl FrLdrTempAlloc() +@ cdecl FrLdrTempFree() +@ cdecl FrLdrHeapCleanupAll() + +# INI (check if we can move this to rosload) +@ cdecl IniAddSection() +@ cdecl IniAddSettingValueToSection() +@ cdecl IniCleanup() +@ cdecl IniGetFileSectionListHead() +@ cdecl IniGetNumSectionItems() +@ cdecl IniGetSectionSettingNameSize() +@ cdecl IniGetSectionSettingValueSize() +@ cdecl IniFileInitialize() +@ cdecl IniModifySettingValue() +@ cdecl IniOpenSection() +@ cdecl IniReadSettingByName() +@ cdecl IniReadSettingByNumber() + +# Mm +@ cdecl AddMemoryDescriptor() +@ cdecl MmAllocateHighestMemoryBelowAddress() +@ cdecl MmAllocateMemoryAtAddress() +@ cdecl MmAllocateMemoryWithType() +@ cdecl MmFreeMemory() +@ cdecl MmGetBiosMemoryMap() +@ cdecl MmGetHighestPhysicalPage() +@ cdecl MmGetLoaderPagesSpanned() +@ cdecl MmGetMemoryMap() +@ cdecl MmGetSystemMemoryMapTypeString() +@ cdecl MmGetTotalPagesInLookupTable() + +# NtLdr options +@ cdecl NtLdrGetNextOption() +@ cdecl NtLdrGetOption() +@ cdecl NtLdrGetOptionEx() +@ cdecl NtLdrGetOptionExN() +@ cdecl NtLdrAddOptions() + +# PeLdr +@ cdecl PeLdrAllocateDataTableEntry() +@ cdecl PeLdrCheckForLoadedDll() +@ cdecl PeLdrFreeDataTableEntry() +@ cdecl PeLdrImportDllLoadCallback() +@ cdecl PeLdrInitSecurityCookie() +@ cdecl PeLdrLoadBootImage() +@ cdecl PeLdrLoadImage() +@ cdecl PeLdrLoadImageEx() +@ cdecl PeLdrScanImportDescriptorTable() + +# UI +@ cdecl UiDisplayMenu() +@ cdecl UiDrawBackdrop() +@ cdecl UiDrawProgressBarCenter() +@ cdecl UiDrawStatusText() +@ cdecl UiDrawText() +@ cdecl UiEditBox() +@ cdecl UiGetMenuBgColor() +@ cdecl UiGetScreenHeight() +@ cdecl UiIndicateProgress() +@ cdecl UiInitialize() +@ cdecl UiMessageBox() +@ cdecl UiMessageBoxCritical() +@ cdecl UiResetForSOS() +@ cdecl UiSetProgressBarSubset() +@ cdecl UiSetProgressBarText() +@ cdecl UiShowMessageBoxesInArgv() +@ cdecl UiShowMessageBoxesInSection() +@ cdecl UiUnInitialize() +@ cdecl UiUpdateProgressBar() +@ cdecl TuiPrintf() + +# Other +@ cdecl ChainLoadBiosBootSectorCode() +@ cdecl ConstructArcPath() +@ cdecl DissectArcPath() +@ cdecl DiskStopFloppyMotor() +@ cdecl DriveMapGetBiosDriveNumber() +@ cdecl FrldrGetBootDrive() +@ cdecl FrldrGetBootPartition() +@ cdecl FrLdrGetBootPath() +@ cdecl FsGetServiceName() +@ cdecl FsOpenFile() # Why not ArcOpen? +@ cdecl GetArgumentValue() +@ cdecl GetBootMgrInfo() +@ cdecl IsAcpiPresent() +@ cdecl LoadSettings() +@ cdecl MachHwDetect() +@ cdecl MachPrepareForReactOS() +@ cdecl MachGetExtendedBIOSData() +@ cdecl MachVideoGetFontsFromFirmware() +@ cdecl PxeCallApi() +@ cdecl RamDiskInitialize() +@ cdecl Reboot() +@ cdecl Relocator16Boot() @ stdcall RtlAssert(ptr ptr long ptr) -@ varargs ScsiDebugPrint(long str) -@ stdcall ScsiPortCompleteRequest(ptr long long long long) -@ stdcall ScsiPortConvertPhysicalAddressToUlong(long long) -@ stdcall -arch=i386 ScsiPortConvertUlongToPhysicalAddress(long) -@ stdcall -arch=x86_64 ScsiPortConvertUlongToPhysicalAddress(long) -@ stdcall ScsiPortFlushDma(ptr) -@ stdcall ScsiPortFreeDeviceBase(ptr ptr) -@ stdcall ScsiPortGetBusData(ptr long long long ptr long) -@ stdcall ScsiPortGetDeviceBase(ptr long long long long long long) -@ stdcall ScsiPortGetLogicalUnit(ptr long long long) -@ stdcall ScsiPortGetPhysicalAddress(ptr ptr ptr long) -@ stdcall ScsiPortGetSrb(ptr long long long long) -@ stdcall ScsiPortGetUncachedExtension(ptr ptr long) -@ stdcall ScsiPortGetVirtualAddress(ptr long long) -@ stdcall ScsiPortInitialize(ptr ptr ptr ptr) -@ stdcall ScsiPortIoMapTransfer(ptr ptr long long) -@ stdcall ScsiPortLogError(ptr ptr long long long long long) -@ stdcall ScsiPortMoveMemory(ptr ptr long) -@ cdecl ScsiPortNotification() -@ stdcall ScsiPortReadPortBufferUchar(ptr ptr long) -@ stdcall ScsiPortReadPortBufferUshort(ptr ptr long) -@ stdcall ScsiPortReadPortBufferUlong(ptr ptr long) -@ stdcall ScsiPortReadPortUchar(ptr) -@ stdcall ScsiPortReadPortUshort(ptr) -@ stdcall ScsiPortReadPortUlong(ptr) -@ stdcall ScsiPortReadRegisterBufferUchar(ptr ptr long) -@ stdcall ScsiPortReadRegisterBufferUshort(ptr ptr long) -@ stdcall ScsiPortReadRegisterBufferUlong(ptr ptr long) -@ stdcall ScsiPortReadRegisterUchar(ptr) -@ stdcall ScsiPortReadRegisterUshort(ptr) -@ stdcall ScsiPortReadRegisterUlong(ptr) -@ stdcall ScsiPortSetBusDataByOffset(ptr long long long ptr long long) -@ stdcall ScsiPortStallExecution(long) -@ stdcall ScsiPortValidateRange(ptr long long long long long long) -@ stdcall ScsiPortWritePortBufferUchar(ptr ptr long) -@ stdcall ScsiPortWritePortBufferUshort(ptr ptr long) -@ stdcall ScsiPortWritePortBufferUlong(ptr ptr long) -@ stdcall ScsiPortWritePortUchar(ptr long) -@ stdcall ScsiPortWritePortUshort(ptr long) -@ stdcall ScsiPortWritePortUlong(ptr long) -@ stdcall ScsiPortWriteRegisterBufferUchar(ptr ptr long) -@ stdcall ScsiPortWriteRegisterBufferUshort(ptr ptr long) -@ stdcall ScsiPortWriteRegisterBufferUlong(ptr ptr long) -@ stdcall ScsiPortWriteRegisterUchar(ptr long) -@ stdcall ScsiPortWriteRegisterUshort(ptr long) -@ stdcall ScsiPortWriteRegisterUlong(ptr long) +@ cdecl StallExecutionProcessor() +@ cdecl MachGetBootSectorLoadAddress() + +# Additional stuff for scsiport +@ stdcall CpDoesPortExist(ptr) +@ stdcall CpEnableFifo(ptr long) +@ stdcall CpGetByte(ptr ptr long long) +@ stdcall CpInitialize(ptr ptr long) +@ stdcall CpPutByte(ptr long) +@ cdecl DissectArcPath2() +@ cdecl -i386 DriveMapMapDrivesInSection() +@ cdecl FsRegisterDevice() +@ cdecl FsGetDeviceSpecific() +@ cdecl FsSetDeviceSpecific() +@ stdcall ExAllocatePool(long long) +@ stdcall ExAllocatePoolWithTag(long long long) +@ stdcall ExFreePool(ptr) +@ stdcall ExFreePoolWithTag(ptr long) +@ cdecl MmSetMemoryType() diff --git a/boot/freeldr/freeldr/include/arch/arm/hardware.h b/boot/freeldr/freeldr/include/arch/arm/hardware.h index 51ed5a8ebcfb1..a821391265a19 100644 --- a/boot/freeldr/freeldr/include/arch/arm/hardware.h +++ b/boot/freeldr/freeldr/include/arch/arm/hardware.h @@ -34,6 +34,7 @@ extern ULONG gDiskReadBuffer, gFileSysBuffer; #define DriveMapGetBiosDriveNumber(DeviceName) 0 +DECLSPEC_NORETURN FORCEINLINE VOID Reboot(VOID) { DbgBreakPoint(); diff --git a/boot/freeldr/freeldr/include/arch/i386/machpc98.h b/boot/freeldr/freeldr/include/arch/i386/machpc98.h index 23e268e9d9829..737d5d84ced98 100644 --- a/boot/freeldr/freeldr/include/arch/i386/machpc98.h +++ b/boot/freeldr/freeldr/include/arch/i386/machpc98.h @@ -151,7 +151,6 @@ UCHAR Pc98GetFloppyCount(VOID); PPC98_DISK_DRIVE Pc98DiskDriveNumberToDrive(IN UCHAR DriveNumber); ULONG Pc98GetBootSectorLoadAddress(IN UCHAR DriveNumber); -VOID Pc98DiskPrepareForReactOS(VOID); /* hwdisk.c */ BOOLEAN PcInitializeBootDevices(VOID); diff --git a/boot/freeldr/freeldr/include/arch/i386/machxbox.h b/boot/freeldr/freeldr/include/arch/i386/machxbox.h index 4d3a451026390..9591729784df2 100644 --- a/boot/freeldr/freeldr/include/arch/i386/machxbox.h +++ b/boot/freeldr/freeldr/include/arch/i386/machxbox.h @@ -51,7 +51,6 @@ VOID XboxPrepareForReactOS(VOID); VOID XboxMemInit(VOID); PFREELDR_MEMORY_DESCRIPTOR XboxMemGetMemoryMap(ULONG *MemoryMapSize); -VOID XboxDiskInit(BOOLEAN Init); BOOLEAN XboxDiskReadLogicalSectors(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer); BOOLEAN XboxDiskGetDriveGeometry(UCHAR DriveNumber, PGEOMETRY DriveGeometry); ULONG XboxDiskGetCacheableBlockCount(UCHAR DriveNumber); diff --git a/boot/freeldr/freeldr/include/arch/pc/hardware.h b/boot/freeldr/freeldr/include/arch/pc/hardware.h index de408b74cd9fe..6ca98ed6a0c33 100644 --- a/boot/freeldr/freeldr/include/arch/pc/hardware.h +++ b/boot/freeldr/freeldr/include/arch/pc/hardware.h @@ -23,6 +23,17 @@ #define TAG_HW_RESOURCE_LIST 'lRwH' #define TAG_HW_DISK_CONTEXT 'cDwH' +/* + * These aren't defined in the ioaccess.h header. + * Because of that we manually define the symbols we need to make use of I/O ports. + */ +#define READ_PORT_BUFFER_UCHAR(port, buffer, count) __inbytestring(H2I(port), buffer, count) +#define READ_PORT_BUFFER_USHORT(port, buffer, count) __inwordstring(H2I(port), buffer, count) +#define READ_PORT_BUFFER_ULONG(port, buffer, count) __indwordstring(H2I(port), buffer, count) +#define WRITE_PORT_BUFFER_UCHAR(port, buffer, count) __outbytestring(H2I(port), buffer, count) +#define WRITE_PORT_BUFFER_USHORT(port, buffer, count) __outwordstring(H2I(port), buffer, count) +#define WRITE_PORT_BUFFER_ULONG(port, buffer, count) __outdwordstring(H2I(port), buffer, count) + /* PROTOTYPES ***************************************************************/ /* hardware.c */ diff --git a/boot/freeldr/freeldr/include/arch/pc/pcbios.h b/boot/freeldr/freeldr/include/arch/pc/pcbios.h index f3539d214267a..5b876d07ae8ba 100644 --- a/boot/freeldr/freeldr/include/arch/pc/pcbios.h +++ b/boot/freeldr/freeldr/include/arch/pc/pcbios.h @@ -182,6 +182,7 @@ VOID __cdecl ChainLoadBiosBootSectorCode( IN UCHAR BootDrive OPTIONAL, IN ULONG BootPartition OPTIONAL); +DECLSPEC_NORETURN VOID __cdecl Relocator16Boot( IN REGS* In, IN USHORT StackSegment, @@ -189,7 +190,9 @@ VOID __cdecl Relocator16Boot( IN USHORT CodeSegment, IN USHORT CodePointer); +DECLSPEC_NORETURN VOID __cdecl Reboot(VOID); + VOID DetectHardware(VOID); #endif /* ! __ASM__ */ diff --git a/boot/freeldr/freeldr/include/debug.h b/boot/freeldr/freeldr/include/debug.h index 6460cacd2c3e6..efff30f395467 100644 --- a/boot/freeldr/freeldr/include/debug.h +++ b/boot/freeldr/freeldr/include/debug.h @@ -85,7 +85,7 @@ // // You may have as many BREAKPOINT()'s as you like but you may only // have up to four of any of the others. -#define BREAKPOINT() __asm__ ("int $3"); +#define BREAKPOINT() __debugbreak() void INSTRUCTION_BREAKPOINT1(unsigned long addr); void MEMORY_READWRITE_BREAKPOINT1(unsigned long addr); void MEMORY_WRITE_BREAKPOINT1(unsigned long addr); @@ -125,10 +125,12 @@ void MEMORY_WRITE_BREAKPOINT4(unsigned long addr); #endif // DBG +DECLSPEC_NORETURN void NTAPI FrLdrBugCheck(ULONG BugCode); +DECLSPEC_NORETURN VOID FrLdrBugCheckWithMessage( ULONG BugCode, diff --git a/boot/freeldr/freeldr/include/disk.h b/boot/freeldr/freeldr/include/disk.h index ec12a8f4b3136..2bf598901e9b7 100644 --- a/boot/freeldr/freeldr/include/disk.h +++ b/boot/freeldr/freeldr/include/disk.h @@ -153,3 +153,7 @@ DiskGetPartitionEntry( * SCSI support (disk/scsiport.c) */ ULONG LoadBootDeviceDriver(VOID); + +PCCHAR FrLdrGetBootPath(VOID); +UCHAR FrldrGetBootDrive(VOID); +ULONG FrldrGetBootPartition(VOID); diff --git a/boot/freeldr/freeldr/include/freeldr.h b/boot/freeldr/freeldr/include/freeldr.h index cc6478e10114e..034f7dd775ad2 100644 --- a/boot/freeldr/freeldr/include/freeldr.h +++ b/boot/freeldr/freeldr/include/freeldr.h @@ -86,7 +86,7 @@ #include /* File system headers */ -#include +#include #include #include #include diff --git a/boot/freeldr/freeldr/include/fs/ext.h b/boot/freeldr/freeldr/include/fs/ext.h new file mode 100644 index 0000000000000..3ca1fe18d92cf --- /dev/null +++ b/boot/freeldr/freeldr/include/fs/ext.h @@ -0,0 +1,253 @@ +/* + * FreeLoader + * Copyright (C) 1998-2003 Brian Palmer + * Copyright (C) 2024-2025 Daniel Victor + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#pragma once + +/* + * grub/fs/ext2.c + * + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2004,2005,2007 Free Software Foundation, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include + +#define EXT_SUPERBLOCK_MAGIC 0xEF53 +#define EXT_DYNAMIC_REVISION 1 +#define EXT_DEFAULT_INODE_SIZE 128 +#define EXT_DEFAULT_GROUP_DESC_SIZE 32 + +#define EXT_DIR_ENTRY_MAX_NAME_LENGTH 255 + +typedef struct _ExtSuperBlock +{ + /* SuperBlock Information Ext2 */ + ULONG InodesCount; + ULONG BlocksCountLo; + ULONG RBlocksCountLo; + ULONG FreeBlocksCountLo; + ULONG FreeInodesCount; + ULONG FirstDataBlock; + ULONG LogBlockSize; + LONG LogFragSize; + ULONG BlocksPerGroup; + ULONG FragsPerGroup; + ULONG InodesPerGroup; + ULONG MTime; + ULONG WTime; + USHORT MntCount; + USHORT MaxMntCount; + USHORT Magic; + USHORT State; + USHORT Errors; + USHORT MinorRevisionLevel; + ULONG LastCheck; + ULONG CheckInterval; + ULONG CreatorOS; + ULONG RevisionLevel; + USHORT DefResUID; + USHORT DefResGID; + + /* SuperBlock Information Ext3 */ + ULONG FirstInode; + USHORT InodeSize; + USHORT BlockGroupNr; + ULONG FeatureCompat; + ULONG FeatureIncompat; + ULONG FeatureROCompat; + UCHAR UUID[16]; + CHAR VolumeName[16]; + CHAR LastMounted[64]; + ULONG AlgorithmUsageBitmap; + UCHAR PreallocBlocks; + UCHAR PreallocDirBlocks; + USHORT ReservedGdtBlocks; + UCHAR JournalUUID[16]; + ULONG JournalInum; + ULONG JournalDev; + ULONG LastOrphan; + ULONG HashSeed[4]; + UCHAR DefHashVersion; + UCHAR JournalBackupType; + USHORT GroupDescSize; + UCHAR Reserved[768]; +} EXT_SUPER_BLOCK, *PEXT_SUPER_BLOCK; + +typedef struct _ExtGroupDescriptor +{ + ULONG BlockBitmap; + ULONG InodeBitmap; + ULONG InodeTable; + USHORT FreeBlocksCount; + USHORT FreeInodesCount; + USHORT UsedDirsCount; +} EXT_GROUP_DESC, *PEXT_GROUP_DESC; + +typedef struct _Ext4ExtentHeader +{ + USHORT Magic; + USHORT Entries; + USHORT Max; + USHORT Depth; + ULONG Generation; +} EXT4_EXTENT_HEADER, *PEXT4_EXTENT_HEADER; + +typedef struct _Ext4ExtentIdx +{ + ULONG Block; + ULONG Leaf; + USHORT LeafHigh; + USHORT Unused; +} EXT4_EXTENT_IDX, *PEXT4_EXTENT_IDX; + +typedef struct _Ext4Extent +{ + ULONG Block; + USHORT Length; + USHORT StartHigh; + ULONG Start; +} EXT4_EXTENT, *PEXT4_EXTENT; + +typedef struct _ExtInode +{ + USHORT Mode; + USHORT UID; + ULONG Size; + ULONG Atime; + ULONG Ctime; + ULONG Mtime; + ULONG Dtime; + USHORT GID; + USHORT LinksCount; + ULONG BlocksCount; + ULONG Flags; + ULONG OSD1; + union + { + CHAR SymLink[60]; + struct + { + ULONG DirectBlocks[12]; + ULONG IndirectBlock; + ULONG DoubleIndirectBlock; + ULONG TripleIndirectBlock; + } Blocks; + EXT4_EXTENT_HEADER ExtentHeader; + }; + ULONG Generation; + ULONG FileACL; + ULONG DirACL; + ULONG FragAddress; + ULONG OSD2[3]; +} EXT_INODE, *PEXT_INODE; + +typedef struct _ExtDirEntry +{ + ULONG Inode; + USHORT EntryLen; + UCHAR NameLen; + UCHAR FileType; + CHAR Name[EXT_DIR_ENTRY_MAX_NAME_LENGTH]; +} EXT_DIR_ENTRY, *PEXT_DIR_ENTRY; + +#include + +/* Special inode numbers. */ +#define EXT_ROOT_INODE 2 + +/* The revision level. */ +#define EXT_REVISION(sb) (sb->RevisionLevel) + +/* The inode size. */ +#define EXT_INODE_SIZE(sb) \ + (EXT_REVISION(sb) < EXT_DYNAMIC_REVISION ? EXT_DEFAULT_INODE_SIZE : sb->InodeSize) + +/* The group descriptor size. */ +#define EXT_GROUP_DESC_SIZE(sb) \ + ((EXT_REVISION(sb) >= EXT_DYNAMIC_REVISION && sb->GroupDescSize) ? sb->GroupDescSize : EXT_DEFAULT_GROUP_DESC_SIZE) + +/* The inode extents flag. */ +#define EXT4_INODE_FLAG_EXTENTS 0x80000 + +/* The extent header magic value. */ +#define EXT4_EXTENT_HEADER_MAGIC 0xF30A + +/* The maximum extent level. */ +#define EXT4_EXTENT_MAX_LEVEL 5 + +/* The maximum extent length used to check for sparse extents. */ +#define EXT4_EXTENT_MAX_LENGTH 32768 + +// EXT_INODE::mode values +#define EXT_S_IRWXO 0x0007 // Other mask +#define EXT_S_IXOTH 0x0001 // ---------x execute +#define EXT_S_IWOTH 0x0002 // --------w- write +#define EXT_S_IROTH 0x0004 // -------r-- read + +#define EXT_S_IRWXG 0x0038 // Group mask +#define EXT_S_IXGRP 0x0008 // ------x--- execute +#define EXT_S_IWGRP 0x0010 // -----w---- write +#define EXT_S_IRGRP 0x0020 // ----r----- read + +#define EXT_S_IRWXU 0x01C0 // User mask +#define EXT_S_IXUSR 0x0040 // ---x------ execute +#define EXT_S_IWUSR 0x0080 // --w------- write +#define EXT_S_IRUSR 0x0100 // -r-------- read + +#define EXT_S_ISVTX 0x0200 // Sticky bit +#define EXT_S_ISGID 0x0400 // SGID +#define EXT_S_ISUID 0x0800 // SUID + +#define EXT_S_IFMT 0xF000 // Format mask +#define EXT_S_IFIFO 0x1000 // FIFO buffer +#define EXT_S_IFCHR 0x2000 // Character device +#define EXT_S_IFDIR 0x4000 // Directory +#define EXT_S_IFBLK 0x6000 // Block device +#define EXT_S_IFREG 0x8000 // Regular file +#define EXT_S_IFLNK 0xA000 // Symbolic link +#define EXT_S_IFSOCK 0xC000 // Socket + +#define FAST_SYMLINK_MAX_NAME_SIZE 60 + +typedef struct _EXT_VOLUME_INFO *PEXT_VOLUME_INFO; + +typedef struct _EXT_FILE_INFO +{ + ULONGLONG FileSize; // File size + ULONGLONG FilePointer; // File pointer + PULONG FileBlockList; // File block list + EXT_INODE Inode; // File's inode + PEXT_VOLUME_INFO Volume; +} EXT_FILE_INFO, *PEXT_FILE_INFO; + +const DEVVTBL* ExtMount(ULONG DeviceId); diff --git a/boot/freeldr/freeldr/include/fs/ext2.h b/boot/freeldr/freeldr/include/fs/ext2.h deleted file mode 100644 index b1b3c7e8d38ac..0000000000000 --- a/boot/freeldr/freeldr/include/fs/ext2.h +++ /dev/null @@ -1,240 +0,0 @@ -/* - * FreeLoader - * Copyright (C) 1998-2003 Brian Palmer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#pragma once - -/* - * grub/fs/ext2.c - * - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2003,2004,2005,2007 Free Software Foundation, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -/* Magic value used to identify an ext2 filesystem. */ -#define EXT2_MAGIC 0xEF53 -/* Amount of indirect blocks in an inode. */ -#define INDIRECT_BLOCKS 12 -/* Maximum length of a pathname. */ -#define EXT2_PATH_MAX 4096 -/* Maximum nesting of symlinks, used to prevent a loop. */ -#define EXT2_MAX_SYMLINKCNT 8 - -/* The good old revision and the default inode size. */ -#define EXT2_GOOD_OLD_REVISION 0 -#define EXT2_DYNAMIC_REVISION 1 -#define EXT2_GOOD_OLD_INODE_SIZE 128 - -/* Filetype used in directory entry. */ -#define FILETYPE_UNKNOWN 0 -#define FILETYPE_REG 1 -#define FILETYPE_DIRECTORY 2 -#define FILETYPE_SYMLINK 7 - -/* Filetype information as used in inodes. */ -#define FILETYPE_INO_MASK 0170000 -#define FILETYPE_INO_REG 0100000 -#define FILETYPE_INO_DIRECTORY 0040000 -#define FILETYPE_INO_SYMLINK 0120000 - -/* The ext2 superblock. */ -struct ext2_sblock -{ - ULONG total_inodes; - ULONG total_blocks; - ULONG reserved_blocks; - ULONG free_blocks; - ULONG free_inodes; - ULONG first_data_block; - ULONG log2_block_size; - LONG log2_fragment_size; - ULONG blocks_per_group; - ULONG fragments_per_group; - ULONG inodes_per_group; - ULONG mtime; - ULONG utime; - USHORT mnt_count; - USHORT max_mnt_count; - USHORT magic; - USHORT fs_state; - USHORT error_handling; - USHORT minor_revision_level; - ULONG lastcheck; - ULONG checkinterval; - ULONG creator_os; - ULONG revision_level; - USHORT uid_reserved; - USHORT gid_reserved; - ULONG first_inode; - USHORT inode_size; - USHORT block_group_number; - ULONG feature_compatibility; - ULONG feature_incompat; - ULONG feature_ro_compat; - ULONG unique_id[4]; - char volume_name[16]; - char last_mounted_on[64]; - ULONG compression_info; - ULONG padding[77]; -}; - -/* The ext2 blockgroup. */ -struct ext2_block_group -{ - ULONG block_id; - ULONG inode_id; - ULONG inode_table_id; - USHORT free_blocks; - USHORT free_inodes; - USHORT used_dirs; - USHORT pad; - ULONG reserved[3]; -}; - -/* The ext2 inode. */ -struct ext2_inode -{ - USHORT mode; - USHORT uid; - ULONG size; - ULONG atime; - ULONG ctime; - ULONG mtime; - ULONG dtime; - USHORT gid; - USHORT nlinks; - ULONG blockcnt; /* Blocks of 512 bytes!! */ - ULONG flags; - ULONG osd1; - union - { - struct datablocks - { - ULONG dir_blocks[INDIRECT_BLOCKS]; - ULONG indir_block; - ULONG double_indir_block; - ULONG tripple_indir_block; - } blocks; - char symlink[60]; - }; - ULONG version; - ULONG acl; - ULONG dir_acl; - ULONG fragment_addr; - ULONG osd2[3]; -}; - -/* The header of an ext2 directory entry. */ -#define EXT2_NAME_LEN 255 - -struct ext2_dirent -{ - ULONG inode; - USHORT direntlen; - UCHAR namelen; - UCHAR filetype; - CHAR name[EXT2_NAME_LEN]; -}; - -/* - * End of code from grub/fs/ext2.c - */ - -typedef struct ext2_sblock EXT2_SUPER_BLOCK, *PEXT2_SUPER_BLOCK; -typedef struct ext2_inode EXT2_INODE, *PEXT2_INODE; -typedef struct ext2_block_group EXT2_GROUP_DESC, *PEXT2_GROUP_DESC; -typedef struct ext2_dirent EXT2_DIR_ENTRY, *PEXT2_DIR_ENTRY; - -/* Special inode numbers. */ -#define EXT2_ROOT_INO 2 - -/* Feature set definitions. */ -#define EXT3_FEATURE_INCOMPAT_SUPP 0x0002 - -/* Log2 size of ext2 block in bytes. */ -#define LOG2_BLOCK_SIZE(sb) (sb->log2_block_size + 10) - -/* The size of an ext2 block in bytes. */ -#define EXT2_BLOCK_SIZE(sb) (((SIZE_T)1) << LOG2_BLOCK_SIZE(sb)) - -/* The revision level. */ -#define EXT2_REVISION(sb) (sb->revision_level) - -/* The inode size. */ -#define EXT2_INODE_SIZE(sb) (EXT2_REVISION(sb) == EXT2_GOOD_OLD_REVISION \ - ? EXT2_GOOD_OLD_INODE_SIZE \ - : sb->inode_size) - -#define EXT2_DESC_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof(struct ext2_block_group)) - -// EXT2_INODE::mode values -#define EXT2_S_IRWXO 0x0007 // Other mask -#define EXT2_S_IXOTH 0x0001 // ---------x execute -#define EXT2_S_IWOTH 0x0002 // --------w- write -#define EXT2_S_IROTH 0x0004 // -------r-- read - -#define EXT2_S_IRWXG 0x0038 // Group mask -#define EXT2_S_IXGRP 0x0008 // ------x--- execute -#define EXT2_S_IWGRP 0x0010 // -----w---- write -#define EXT2_S_IRGRP 0x0020 // ----r----- read - -#define EXT2_S_IRWXU 0x01C0 // User mask -#define EXT2_S_IXUSR 0x0040 // ---x------ execute -#define EXT2_S_IWUSR 0x0080 // --w------- write -#define EXT2_S_IRUSR 0x0100 // -r-------- read - -#define EXT2_S_ISVTX 0x0200 // Sticky bit -#define EXT2_S_ISGID 0x0400 // SGID -#define EXT2_S_ISUID 0x0800 // SUID - -#define EXT2_S_IFMT 0xF000 // Format mask -#define EXT2_S_IFIFO 0x1000 // FIFO buffer -#define EXT2_S_IFCHR 0x2000 // Character device -#define EXT2_S_IFDIR 0x4000 // Directory -#define EXT2_S_IFBLK 0x6000 // Block device -#define EXT2_S_IFREG 0x8000 // Regular file -#define EXT2_S_IFLNK 0xA000 // Symbolic link -#define EXT2_S_IFSOCK 0xC000 // Socket - -#define FAST_SYMLINK_MAX_NAME_SIZE 60 - -typedef struct _EXT2_VOLUME_INFO *PEXT2_VOLUME_INFO; - -typedef struct -{ - ULONGLONG FileSize; // File size - ULONGLONG FilePointer; // File pointer - ULONG* FileBlockList; // File block list - EXT2_INODE Inode; // File's inode - PEXT2_VOLUME_INFO Volume; -} EXT2_FILE_INFO, * PEXT2_FILE_INFO; - -const DEVVTBL* Ext2Mount(ULONG DeviceId); diff --git a/boot/freeldr/freeldr/include/hwide.h b/boot/freeldr/freeldr/include/hwide.h index 23f7fd94ad030..60b2cce415c80 100644 --- a/boot/freeldr/freeldr/include/hwide.h +++ b/boot/freeldr/freeldr/include/hwide.h @@ -1,331 +1,52 @@ /* * PROJECT: FreeLoader - * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * LICENSE: MIT (https://spdx.org/licenses/MIT) * PURPOSE: ATA/ATAPI programmed I/O driver header file. - * COPYRIGHT: Copyright 2019-2020 Dmitry Borisov (di.sean@protonmail.com) + * COPYRIGHT: Copyright 2019-2025 Dmitry Borisov (di.sean@protonmail.com) */ -/* GLOBALS ********************************************************************/ +#pragma once -/* Some definitions were taken from UniATA driver by Alter */ - -/* - * IDE registers offsets - */ -#if defined(SARCH_PC98) -#define IDX_IO1_i_Data 0x00 -#define IDX_IO1_i_Error 0x02 -#define IDX_IO1_i_BlockCount 0x04 -#define IDX_IO1_i_BlockNumber 0x06 -#define IDX_IO1_i_CylinderLow 0x08 -#define IDX_IO1_i_CylinderHigh 0x0A -#define IDX_IO1_i_DriveSelect 0x0C -#define IDX_IO1_i_Status 0x0E - -#define IDX_IO2_i_AltStatus 0x10C -#define IDX_IO2_i_DriveAddress 0x10E -#define IDE_IO_i_Bank 0x432 - -#define IDX_IO1_o_Data 0x00 -#define IDX_IO1_o_Feature 0x02 -#define IDX_IO1_o_BlockCount 0x04 -#define IDX_IO1_o_BlockNumber 0x06 -#define IDX_IO1_o_CylinderLow 0x08 -#define IDX_IO1_o_CylinderHigh 0x0A -#define IDX_IO1_o_DriveSelect 0x0C -#define IDX_IO1_o_Command 0x0E - -#define IDX_IO2_o_Control 0x10C -#define IDE_IO_o_BankSelect 0x432 -#else /* SARCH_PC98 */ -#define IDX_IO1_i_Data 0x00 -#define IDX_IO1_i_Error 0x01 -#define IDX_IO1_i_BlockCount 0x02 -#define IDX_IO1_i_BlockNumber 0x03 -#define IDX_IO1_i_CylinderLow 0x04 -#define IDX_IO1_i_CylinderHigh 0x05 -#define IDX_IO1_i_DriveSelect 0x06 -#define IDX_IO1_i_Status 0x07 - -#define IDX_IO2_i_AltStatus 0x206 -#define IDX_IO2_i_DriveAddress 0x207 - -#define IDX_IO1_o_Data 0x00 -#define IDX_IO1_o_Feature 0x01 -#define IDX_IO1_o_BlockCount 0x02 -#define IDX_IO1_o_BlockNumber 0x03 -#define IDX_IO1_o_CylinderLow 0x04 -#define IDX_IO1_o_CylinderHigh 0x05 -#define IDX_IO1_o_DriveSelect 0x06 -#define IDX_IO1_o_Command 0x07 - -#define IDX_IO2_o_Control 0x206 -#endif - -/* - * ATAPI registers offsets - */ -#if defined(SARCH_PC98) -#define IDX_ATAPI_IO1_i_Data 0x00 -#define IDX_ATAPI_IO1_i_Error 0x02 -#define IDX_ATAPI_IO1_i_InterruptReason 0x04 -#define IDX_ATAPI_IO1_i_Unused1 0x06 -#define IDX_ATAPI_IO1_i_ByteCountLow 0x08 -#define IDX_ATAPI_IO1_i_ByteCountHigh 0x0A -#define IDX_ATAPI_IO1_i_DriveSelect 0x0C -#define IDX_ATAPI_IO1_i_Status 0x0E - -#define IDX_ATAPI_IO1_o_Data 0x00 -#define IDX_ATAPI_IO1_o_Feature 0x02 -#define IDX_ATAPI_IO1_o_Unused0 0x04 -#define IDX_ATAPI_IO1_o_Unused1 0x06 -#define IDX_ATAPI_IO1_o_ByteCountLow 0x08 -#define IDX_ATAPI_IO1_o_ByteCountHigh 0x0A -#define IDX_ATAPI_IO1_o_DriveSelect 0x0C -#define IDX_ATAPI_IO1_o_Command 0x0E -#else /* SARCH_PC98 */ -#define IDX_ATAPI_IO1_i_Data 0x00 -#define IDX_ATAPI_IO1_i_Error 0x01 -#define IDX_ATAPI_IO1_i_InterruptReason 0x02 -#define IDX_ATAPI_IO1_i_Unused1 0x03 -#define IDX_ATAPI_IO1_i_ByteCountLow 0x04 -#define IDX_ATAPI_IO1_i_ByteCountHigh 0x05 -#define IDX_ATAPI_IO1_i_DriveSelect 0x06 -#define IDX_ATAPI_IO1_i_Status 0x07 - -#define IDX_ATAPI_IO1_o_Data 0x00 -#define IDX_ATAPI_IO1_o_Feature 0x01 -#define IDX_ATAPI_IO1_o_Unused0 0x02 -#define IDX_ATAPI_IO1_o_Unused1 0x03 -#define IDX_ATAPI_IO1_o_ByteCountLow 0x04 -#define IDX_ATAPI_IO1_o_ByteCountHigh 0x05 -#define IDX_ATAPI_IO1_o_DriveSelect 0x06 -#define IDX_ATAPI_IO1_o_Command 0x07 -#endif - -/* - * IDE status definitions - */ -#define IDE_STATUS_SUCCESS 0x00 -#define IDE_STATUS_ERROR 0x01 -#define IDE_STATUS_INDEX 0x02 -#define IDE_STATUS_CORRECTED_ERROR 0x04 -#define IDE_STATUS_DRQ 0x08 -#define IDE_STATUS_DSC 0x10 -#define IDE_STATUS_DMA 0x20 /* DMA ready */ -#define IDE_STATUS_DWF 0x20 /* drive write fault */ -#define IDE_STATUS_DRDY 0x40 -#define IDE_STATUS_IDLE 0x50 -#define IDE_STATUS_BUSY 0x80 - -#define IDE_STATUS_WRONG 0xff -#define IDE_STATUS_MASK 0xff - -/* - * IDE drive select/head definitions - */ -#define IDE_DRIVE_SELECT 0xA0 -#define IDE_DRIVE_1 0x00 -#define IDE_DRIVE_2 0x10 -#define IDE_DRIVE_SELECT_1 (IDE_DRIVE_SELECT | IDE_DRIVE_1) -#define IDE_DRIVE_SELECT_2 (IDE_DRIVE_SELECT | IDE_DRIVE_2) -#define IDE_DRIVE_MASK (IDE_DRIVE_SELECT_1 | IDE_DRIVE_SELECT_2) -#define IDE_USE_LBA 0x40 - -/* - * IDE drive control definitions - */ -#define IDE_DC_DISABLE_INTERRUPTS 0x02 -#define IDE_DC_RESET_CONTROLLER 0x04 -#define IDE_DC_A_4BIT 0x80 -#define IDE_DC_USE_HOB 0x80 // use high-order byte(s) -#define IDE_DC_REENABLE_CONTROLLER 0x00 +/** @brief Data structure for the ATA device. */ +typedef struct _DEVICE_UNIT +{ + /** Number of cylinders on the device */ + ULONG Cylinders; -/* - * IDE error definitions - */ -#define IDE_ERROR_ICRC 0x80 -#define IDE_ERROR_BAD_BLOCK 0x80 -#define IDE_ERROR_DATA_ERROR 0x40 -#define IDE_ERROR_MEDIA_CHANGE 0x20 -#define IDE_ERROR_ID_NOT_FOUND 0x10 -#define IDE_ERROR_MEDIA_CHANGE_REQ 0x08 -#define IDE_ERROR_COMMAND_ABORTED 0x04 -#define IDE_ERROR_END_OF_MEDIA 0x02 -#define IDE_ERROR_NO_MEDIA 0x02 -#define IDE_ERROR_ILLEGAL_LENGTH 0x01 + /** Number of heads on the device */ + ULONG Heads; -/* - * Values for TransferMode - */ -#define ATA_PIO 0x00 + /** Number of sectors per track */ + ULONG SectorsPerTrack; -/* - * IDENTIFY data - */ -#include -typedef struct _IDENTIFY_DATA -{ - UCHAR AtapiCmdSize:2; // 00 00 General configuration - UCHAR Unused1:3; - UCHAR DrqType:2; - UCHAR Removable:1; - UCHAR DeviceType:5; - UCHAR Unused2:1; - UCHAR CmdProtocol:2; - USHORT NumberOfCylinders; // 02 1 - USHORT Reserved1; // 04 2 - USHORT NumberOfHeads; // 06 3 - USHORT UnformattedBytesPerTrack; // 08 4 - USHORT UnformattedBytesPerSector; // 0A 5 - USHORT SectorsPerTrack; // 0C 6 - USHORT VendorUnique1[3]; // 0E 7-9 - USHORT SerialNumber[10]; // 14 10-19 - USHORT BufferType; // 28 20 - USHORT BufferSectorSize; // 2A 21 - USHORT NumberOfEccBytes; // 2C 22 - USHORT FirmwareRevision[4]; // 2E 23-26 - USHORT ModelNumber[20]; // 36 27-46 - UCHAR ReadWriteMultipleSupport; // 5E 47 - UCHAR VendorUnique2; // 5F - USHORT DoubleWordIo; // 60 48 - USHORT Reserved62_0:8; // 62 49 Capabilities - USHORT SupportDma:1; - USHORT SupportLba:1; - USHORT DisableIordy:1; - USHORT SupportIordy:1; - USHORT SoftReset:1; - USHORT StandbyOverlap:1; - USHORT SupportQTag:1; - USHORT SupportIDma:1; - USHORT Reserved2; // 64 50 - UCHAR VendorUnique3; // 66 51 - UCHAR PioCycleTimingMode; // 67 - UCHAR VendorUnique4; // 68 52 - UCHAR DmaCycleTimingMode; // 69 - USHORT TranslationFieldsValid:1; // 6A 53 - USHORT Reserved3:15; - USHORT NumberOfCurrentCylinders; // 6C 54 - USHORT NumberOfCurrentHeads; // 6E 55 - USHORT CurrentSectorsPerTrack; // 70 56 - ULONG CurrentSectorCapacity; // 72 57-58 - USHORT CurrentMultiSectorSetting; // 59 - ULONG UserAddressableSectors; // 60-61 - USHORT SingleWordDMASupport:8; // 62 - USHORT SingleWordDMAActive:8; - USHORT MultiWordDMASupport:8; // 63 - USHORT MultiWordDMAActive:8; - USHORT AdvancedPIOModes:8; // 64 - USHORT Reserved4:8; - USHORT MinimumMWXferCycleTime; // 65 - USHORT RecommendedMWXferCycleTime; // 66 - USHORT MinimumPIOCycleTime; // 67 - USHORT MinimumPIOCycleTimeIORDY; // 68 - USHORT Reserved5[2]; // 69-70 - USHORT ReleaseTimeOverlapped; // 71 - USHORT ReleaseTimeServiceCommand; // 72 - USHORT Reserved73_74[2]; // 73-74 - USHORT QueueLength:5; // 75 - USHORT Reserved75_6:11; - USHORT SataCapabilities; // 76 - USHORT Reserved77; // 77 - USHORT SataSupport; // 78 - USHORT SataEnable; // 79 - USHORT MajorRevision; // 80 - USHORT MinorRevision; // 81 - struct { - USHORT Smart:1; // 82 - USHORT Security:1; - USHORT Removable:1; - USHORT PowerMngt:1; - USHORT Packet:1; - USHORT WriteCache:1; - USHORT LookAhead:1; - USHORT ReleaseDRQ:1; - USHORT ServiceDRQ:1; - USHORT Reset:1; - USHORT Protected:1; - USHORT Reserved_82_11:1; - USHORT WriteBuffer:1; - USHORT ReadBuffer:1; - USHORT Nop:1; - USHORT Reserved_82_15:1; - USHORT Microcode:1; // 83/86 - USHORT Queued:1; - USHORT CFA:1; - USHORT APM:1; - USHORT Notify:1; - USHORT Standby:1; - USHORT Spinup:1; - USHORT Reserver_83_7:1; - USHORT MaxSecurity:1; - USHORT AutoAcoustic:1; - USHORT Address48:1; - USHORT ConfigOverlay:1; - USHORT FlushCache:1; - USHORT FlushCache48:1; - USHORT SupportOne:1; - USHORT SupportZero:1; - USHORT SmartErrorLog:1; // 84/87 - USHORT SmartSelfTest:1; - USHORT MediaSerialNo:1; - USHORT MediaCardPass:1; - USHORT Streaming:1; - USHORT Logging:1; - USHORT Reserver_84_6:8; - USHORT ExtendedOne:1; - USHORT ExtendedZero:1; - } FeaturesSupport, FeaturesEnabled; - USHORT Reserved6[13]; // 88-99 - ULONGLONG UserAddressableSectors48; // 100-103 - USHORT Reserved7[151]; // 104-255 -} IDENTIFY_DATA, *PIDENTIFY_DATA; -#include -#define IDENTIFY_DATA_SIZE sizeof(IDENTIFY_DATA) + /** Number of bytes per sector */ + ULONG SectorSize; -#define ATAPI_MAGIC_LSB 0x14 -#define ATAPI_MAGIC_MSB 0xEB -#define MAXIMUM_CDROM_SIZE 804 + /** Total number of device sectors/LBA blocks */ + ULONG64 TotalSectors; -typedef struct _DEVICE_UNIT -{ - UCHAR Channel; - UCHAR DeviceNumber; - ULONG Cylinders; - ULONG Heads; - ULONG Sectors; - ULONG SectorSize; - ULONGLONG TotalSectors; /* This number starts from 0 */ - USHORT Flags; - IDENTIFY_DATA IdentifyData; + /** Device-specific flags */ + ULONG Flags; +#define ATA_DEVICE_ATAPI 0x00000001 +#define ATA_DEVICE_LBA 0x00000002 +#define ATA_DEVICE_LBA48 0x00000004 +#define ATA_DEVICE_IS_NEC_CDR260 0x00000008 +#define ATA_DEVICE_FLAG_IO32 0x00000010 } DEVICE_UNIT, *PDEVICE_UNIT; -#define ATA_DEVICE_ATAPI (1 << 0) -#define ATA_DEVICE_NO_MEDIA (1 << 1) -#define ATA_DEVICE_NOT_READY (1 << 2) -#define ATA_DEVICE_LBA48 (1 << 3) -#define ATA_DEVICE_LBA (1 << 4) -#define ATA_DEVICE_CHS (1 << 5) - -/* PROTOTYPES ****************************************************************/ +/* FUNCTIONS ******************************************************************/ BOOLEAN AtaInit( - OUT PUCHAR DetectedCount -); - -VOID -AtaFree(); + _Out_ PUCHAR DetectedCount); PDEVICE_UNIT AtaGetDevice( - IN UCHAR UnitNumber -); + _In_ UCHAR UnitNumber); BOOLEAN -AtaAtapiReadLogicalSectorsLBA( - IN OUT PDEVICE_UNIT DeviceUnit, - IN ULONGLONG SectorNumber, - IN ULONG SectorCount, - OUT PVOID Buffer -); +AtaReadLogicalSectors( + _In_ PDEVICE_UNIT DeviceUnit, + _In_ ULONG64 SectorNumber, + _In_ ULONG SectorCount, + _Out_writes_bytes_all_(SectorCount * DeviceUnit->SectorSize) PVOID Buffer); diff --git a/boot/freeldr/freeldr/include/inifile.h b/boot/freeldr/freeldr/include/inifile.h index 0bc8e60968aba..7a33a992bffe7 100644 --- a/boot/freeldr/freeldr/include/inifile.h +++ b/boot/freeldr/freeldr/include/inifile.h @@ -83,3 +83,4 @@ BOOLEAN IniAddSection(PCSTR SectionName, ULONG_PTR* SectionId); BOOLEAN IniAddSettingValueToSection(ULONG_PTR SectionId, PCSTR SettingName, PCSTR SettingValue); BOOLEAN IniModifySettingValue(ULONG_PTR SectionId, PCSTR SettingName, PCSTR SettingValue); VOID IniCleanup(VOID); +PLIST_ENTRY IniGetFileSectionListHead(VOID); diff --git a/boot/freeldr/freeldr/include/linux.h b/boot/freeldr/freeldr/include/linux.h index f7591db741007..d55bf8d51da6d 100644 --- a/boot/freeldr/freeldr/include/linux.h +++ b/boot/freeldr/freeldr/include/linux.h @@ -129,6 +129,7 @@ typedef struct #include // Implemented in linux.S +DECLSPEC_NORETURN VOID __cdecl BootLinuxKernel( _In_ ULONG KernelSize, diff --git a/boot/freeldr/freeldr/include/machine.h b/boot/freeldr/freeldr/include/machine.h index 7e6e5c249be2a..1a44f5f14e979 100644 --- a/boot/freeldr/freeldr/include/machine.h +++ b/boot/freeldr/freeldr/include/machine.h @@ -97,8 +97,6 @@ VOID MachInit(const char *CmdLine); MachVtbl.VideoGetDisplaySize((W), (H), (D)) #define MachVideoGetBufferSize() \ MachVtbl.VideoGetBufferSize() -#define MachVideoGetFontsFromFirmware(RomFontPointers) \ - MachVtbl.VideoGetFontsFromFirmware((RomFontPointers)) #define MachVideoSetTextCursorPosition(X, Y) \ MachVtbl.VideoSetTextCursorPosition((X), (Y)) #define MachVideoHideShowTextCursor(Show) \ @@ -117,10 +115,6 @@ VOID MachInit(const char *CmdLine); MachVtbl.VideoSync() #define MachBeep() \ MachVtbl.Beep() -#define MachPrepareForReactOS() \ - MachVtbl.PrepareForReactOS() -#define MachGetExtendedBIOSData(ExtendedBIOSDataArea, ExtendedBIOSDataSize) \ - MachVtbl.GetExtendedBIOSData((ExtendedBIOSDataArea), (ExtendedBIOSDataSize)) #define MachGetFloppyCount() \ MachVtbl.GetFloppyCount() #define MachDiskReadLogicalSectors(Drive, Start, Count, Buf) \ @@ -133,15 +127,19 @@ VOID MachInit(const char *CmdLine); #define MachInitializeBootDevices() \ MachVtbl.InitializeBootDevices() -#define MachHwDetect(Options) \ - MachVtbl.HwDetect(Options) - #define MachHwIdle() \ MachVtbl.HwIdle() + /* ARC FUNCTIONS **************************************************************/ TIMEINFO* ArcGetTime(VOID); ULONG ArcGetRelativeTime(VOID); +PCONFIGURATION_COMPONENT_DATA MachHwDetect(_In_opt_ PCSTR Options); +VOID MachPrepareForReactOS(VOID); +VOID MachGetExtendedBIOSData(PULONG ExtendedBIOSDataArea, PULONG ExtendedBIOSDataSize); +VOID MachVideoGetFontsFromFirmware(PULONG RomFontPointers); +ULONG MachGetBootSectorLoadAddress(IN UCHAR DriveNumber); + /* EOF */ diff --git a/boot/freeldr/freeldr/include/mm.h b/boot/freeldr/freeldr/include/mm.h index a3f34a55f78be..2c93415367457 100644 --- a/boot/freeldr/freeldr/include/mm.h +++ b/boot/freeldr/freeldr/include/mm.h @@ -118,7 +118,7 @@ BOOLEAN MmAreMemoryPagesAvailable(PVOID PageLookupTable, PFN_NUMBER TotalPageCou VOID MmSetMemoryType(PVOID MemoryAddress, SIZE_T MemorySize, TYPE_OF_MEMORY NewType); // Use with EXTREME caution! PPAGE_LOOKUP_TABLE_ITEM MmGetMemoryMap(PFN_NUMBER *NoEntries); // Returns a pointer to the memory mapping table and a number of entries in it - +PFN_NUMBER MmGetTotalPagesInLookupTable(VOID); //BOOLEAN MmInitializeMemoryManager(ULONG LowMemoryStart, ULONG LowMemoryLength); BOOLEAN MmInitializeMemoryManager(VOID); @@ -129,12 +129,14 @@ VOID MmFreeMemory(PVOID MemoryPointer); PVOID MmAllocateMemoryAtAddress(SIZE_T MemorySize, PVOID DesiredAddress, TYPE_OF_MEMORY MemoryType); PVOID MmAllocateHighestMemoryBelowAddress(SIZE_T MemorySize, PVOID DesiredAddress, TYPE_OF_MEMORY MemoryType); +PFN_NUMBER MmGetHighestPhysicalPage(VOID); +PFN_NUMBER MmGetLoaderPagesSpanned(VOID); +ULONG MmGetBiosMemoryMap(_Out_ PFREELDR_MEMORY_DESCRIPTOR *MemoryMap); + /* Heap */ #define DEFAULT_HEAP_SIZE (1024 * 1024) #define TEMP_HEAP_SIZE (32 * 1024 * 1024) -extern PVOID FrLdrDefaultHeap; -extern PVOID FrLdrTempHeap; extern SIZE_T FrLdrImageSize; PVOID @@ -169,34 +171,17 @@ FrLdrHeapFreeEx( PVOID Pointer, ULONG Tag); -FORCEINLINE PVOID -FrLdrHeapAlloc(SIZE_T MemorySize, ULONG Tag) -{ - return FrLdrHeapAllocateEx(FrLdrDefaultHeap, MemorySize, Tag); -} +FrLdrHeapAlloc(SIZE_T MemorySize, ULONG Tag); -FORCEINLINE VOID -FrLdrHeapFree(PVOID MemoryPointer, ULONG Tag) -{ - FrLdrHeapFreeEx(FrLdrDefaultHeap, MemoryPointer, Tag); -} +FrLdrHeapFree(PVOID MemoryPointer, ULONG Tag); -FORCEINLINE PVOID FrLdrTempAlloc( _In_ SIZE_T Size, - _In_ ULONG Tag) -{ - return FrLdrHeapAllocateEx(FrLdrTempHeap, Size, Tag); -} + _In_ ULONG Tag); -FORCEINLINE VOID FrLdrTempFree( - PVOID Allocation, ULONG Tag) -{ - FrLdrHeapFreeEx(FrLdrTempHeap, Allocation, Tag); -} - + PVOID Allocation, ULONG Tag); diff --git a/boot/freeldr/freeldr/include/peloader.h b/boot/freeldr/freeldr/include/peloader.h index b2374f74ceb41..cb7faa4c2340e 100644 --- a/boot/freeldr/freeldr/include/peloader.h +++ b/boot/freeldr/freeldr/include/peloader.h @@ -13,7 +13,7 @@ * (creating a native EFI loader for Windows). * * This article was very handy during development: - * http://msdn.microsoft.com/msdnmag/issues/02/03/PE2/ + * https://web.archive.org/web/20131202091645/http://msdn.microsoft.com/en-us/magazine/cc301808.aspx */ #pragma once @@ -63,9 +63,9 @@ PeLdrScanImportDescriptorTable( BOOLEAN PeLdrCheckForLoadedDll( - IN OUT PLIST_ENTRY ModuleListHead, - IN PCH DllName, - OUT PLDR_DATA_TABLE_ENTRY *LoadedEntry); + _Inout_ PLIST_ENTRY ModuleListHead, + _In_ PCSTR DllName, + _Out_ PLDR_DATA_TABLE_ENTRY* LoadedEntry); PVOID PeLdrInitSecurityCookie( diff --git a/boot/freeldr/freeldr/include/settings.h b/boot/freeldr/freeldr/include/settings.h index 8c60a14506844..e5f5c9c58b430 100644 --- a/boot/freeldr/freeldr/include/settings.h +++ b/boot/freeldr/freeldr/include/settings.h @@ -17,6 +17,8 @@ typedef struct _BOOTMGRINFO extern BOOTMGRINFO BootMgrInfo; +PBOOTMGRINFO GetBootMgrInfo(VOID); + VOID LoadSettings( _In_opt_ PCSTR CmdLine); diff --git a/boot/freeldr/freeldr/include/ui.h b/boot/freeldr/freeldr/include/ui.h index 1b47cc89447a0..1ee72572ae420 100644 --- a/boot/freeldr/freeldr/include/ui.h +++ b/boot/freeldr/freeldr/include/ui.h @@ -53,7 +53,7 @@ extern const PCSTR UiMonthNames[12]; BOOLEAN UiInitialize(BOOLEAN ShowUi); // Initialize User-Interface VOID UiUnInitialize(PCSTR BootText); // Un-initialize User-Interface -VOID UiDrawBackdrop(VOID); // Fills the entire screen with a backdrop +VOID UiDrawBackdrop(ULONG DrawHeight); // Fills the entire screen with a backdrop VOID UiFillArea(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, CHAR FillChar, UCHAR Attr /* Color Attributes */); // Fills the area specified with FillChar and Attr VOID UiDrawShadow(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom); // Draws a shadow on the bottom and right sides of the area specified VOID UiDrawBox(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, UCHAR VertStyle, UCHAR HorzStyle, BOOLEAN Fill, BOOLEAN Shadow, UCHAR Attr); // Draws a box around the area specified @@ -103,6 +103,12 @@ VOID UiMessageBoxCritical( _In_ PCSTR MessageText); +ULONG +UiGetScreenHeight(VOID); + +UCHAR +UiGetMenuBgColor(VOID); + /* Loading Progress-Bar Functions ********************************************/ /* @@ -205,7 +211,6 @@ typedef struct tagUI_MENU_INFO { PCSTR MenuHeader; PCSTR MenuFooter; - BOOLEAN ShowBootOptions; PCSTR* MenuItemList; ULONG MenuItemCount; @@ -230,7 +235,6 @@ BOOLEAN UiDisplayMenu( IN PCSTR MenuHeader, IN PCSTR MenuFooter OPTIONAL, - IN BOOLEAN ShowBootOptions, IN PCSTR MenuItemList[], IN ULONG MenuItemCount, IN ULONG DefaultMenuItem, @@ -250,7 +254,7 @@ typedef struct tagUIVTBL BOOLEAN (*Initialize)(VOID); VOID (*UnInitialize)(VOID); - VOID (*DrawBackdrop)(VOID); + VOID (*DrawBackdrop)(ULONG DrawHeight); VOID (*FillArea)(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, CHAR FillChar, UCHAR Attr); VOID (*DrawShadow)(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom); VOID (*DrawBox)(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, UCHAR VertStyle, UCHAR HorzStyle, BOOLEAN Fill, BOOLEAN Shadow, UCHAR Attr); @@ -287,7 +291,6 @@ typedef struct tagUIVTBL BOOLEAN (*DisplayMenu)( IN PCSTR MenuHeader, IN PCSTR MenuFooter OPTIONAL, - IN BOOLEAN ShowBootOptions, IN PCSTR MenuItemList[], IN ULONG MenuItemCount, IN ULONG DefaultMenuItem, @@ -302,6 +305,9 @@ typedef struct tagUIVTBL VOID UiInit(const char *CmdLine); +VOID +UiResetForSOS(VOID); + extern UIVTBL UiVtbl; /* diff --git a/boot/freeldr/freeldr/include/ui/minitui.h b/boot/freeldr/freeldr/include/ui/minitui.h index 6db89b41cc01d..e8743835d420e 100644 --- a/boot/freeldr/freeldr/include/ui/minitui.h +++ b/boot/freeldr/freeldr/include/ui/minitui.h @@ -10,7 +10,7 @@ /* Textual User Interface Functions ******************************************/ -VOID MiniTuiDrawBackdrop(VOID); +VOID MiniTuiDrawBackdrop(ULONG DrawHeight); VOID MiniTuiDrawStatusText(PCSTR StatusText); VOID diff --git a/boot/freeldr/freeldr/include/ui/noui.h b/boot/freeldr/freeldr/include/ui/noui.h index df986bfd178c6..99d66ceb3414b 100644 --- a/boot/freeldr/freeldr/include/ui/noui.h +++ b/boot/freeldr/freeldr/include/ui/noui.h @@ -13,7 +13,7 @@ BOOLEAN NoUiInitialize(VOID); VOID NoUiUnInitialize(VOID); -VOID NoUiDrawBackdrop(VOID); +VOID NoUiDrawBackdrop(ULONG DrawHeight); VOID NoUiFillArea(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, CHAR FillChar, UCHAR Attr); VOID NoUiDrawShadow(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom); VOID NoUiDrawBox(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, UCHAR VertStyle, UCHAR HorzStyle, BOOLEAN Fill, BOOLEAN Shadow, UCHAR Attr); @@ -93,7 +93,6 @@ BOOLEAN NoUiDisplayMenu( IN PCSTR MenuHeader, IN PCSTR MenuFooter OPTIONAL, - IN BOOLEAN ShowBootOptions, IN PCSTR MenuItemList[], IN ULONG MenuItemCount, IN ULONG DefaultMenuItem, diff --git a/boot/freeldr/freeldr/include/ui/tui.h b/boot/freeldr/freeldr/include/ui/tui.h index 9017c0b4ef67c..ee0c756d5263e 100644 --- a/boot/freeldr/freeldr/include/ui/tui.h +++ b/boot/freeldr/freeldr/include/ui/tui.h @@ -37,7 +37,7 @@ TuiTruncateStringEllipsis( BOOLEAN TuiInitialize(VOID); // Initialize User-Interface VOID TuiUnInitialize(VOID); // Un-initialize User-Interface -VOID TuiDrawBackdrop(VOID); // Fills the entire screen with a backdrop +VOID TuiDrawBackdrop(ULONG DrawHeight); // Fills the entire screen with a backdrop VOID TuiFillArea(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, CHAR FillChar, UCHAR Attr /* Color Attributes */); // Fills the area specified with FillChar and Attr VOID TuiDrawShadow(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom); // Draws a shadow on the bottom and right sides of the area specified @@ -149,7 +149,6 @@ BOOLEAN TuiDisplayMenu( IN PCSTR MenuHeader, IN PCSTR MenuFooter OPTIONAL, - IN BOOLEAN ShowBootOptions, IN PCSTR MenuItemList[], IN ULONG MenuItemCount, IN ULONG DefaultMenuItem, diff --git a/boot/freeldr/freeldr/lib/debug.c b/boot/freeldr/freeldr/lib/debug.c index c1f9d954cd36a..efb059e274086 100644 --- a/boot/freeldr/freeldr/lib/debug.c +++ b/boot/freeldr/freeldr/lib/debug.c @@ -424,12 +424,46 @@ DbgParseDebugChannels(PCHAR Value) #else +#undef DebugInit +VOID +DebugInit( + _In_ PCSTR DebugString) +{ + UNREFERENCED_PARAMETER(DebugString); +} + ULONG DbgPrint(PCCH Format, ...) { + UNREFERENCED_PARAMETER(Format); return 0; } +VOID +DbgPrint2(ULONG Mask, ULONG Level, const char *File, ULONG Line, char *Format, ...) +{ + UNREFERENCED_PARAMETER(Mask); + UNREFERENCED_PARAMETER(Level); + UNREFERENCED_PARAMETER(File); + UNREFERENCED_PARAMETER(Line); + UNREFERENCED_PARAMETER(Format); +} + +VOID +DebugDumpBuffer(ULONG Mask, PVOID Buffer, ULONG Length) +{ + UNREFERENCED_PARAMETER(Mask); + UNREFERENCED_PARAMETER(Buffer); + UNREFERENCED_PARAMETER(Length); +} + +#undef DbgParseDebugChannels +VOID +DbgParseDebugChannels(PCHAR Value) +{ + UNREFERENCED_PARAMETER(Value); +} + #endif // DBG ULONG diff --git a/boot/freeldr/freeldr/lib/fs/ext.c b/boot/freeldr/freeldr/lib/fs/ext.c new file mode 100644 index 0000000000000..288d708a915fe --- /dev/null +++ b/boot/freeldr/freeldr/lib/fs/ext.c @@ -0,0 +1,1435 @@ +/* + * FreeLoader + * Copyright (C) 1998-2003 Brian Palmer + * Copyright (C) 2024-2025 Daniel Victor + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef _M_ARM +#include + +#include +DBG_DEFAULT_CHANNEL(FILESYSTEM); + +BOOLEAN ExtOpenVolume(PEXT_VOLUME_INFO Volume); +PEXT_FILE_INFO ExtOpenFile(PEXT_VOLUME_INFO Volume, PCSTR FileName); +BOOLEAN ExtLookupFile(PEXT_VOLUME_INFO Volume, PCSTR FileName, PEXT_FILE_INFO ExtFileInfo); +BOOLEAN ExtSearchDirectoryBufferForFile(PVOID DirectoryBuffer, ULONG DirectorySize, PCHAR FileName, PEXT_DIR_ENTRY DirectoryEntry); +BOOLEAN ExtReadVolumeSectors(PEXT_VOLUME_INFO Volume, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer); + +BOOLEAN ExtReadFileBig(PEXT_FILE_INFO ExtFileInfo, ULONGLONG BytesToRead, ULONGLONG* BytesRead, PVOID Buffer); +BOOLEAN ExtReadSuperBlock(PEXT_VOLUME_INFO Volume); +BOOLEAN ExtReadGroupDescriptors(PEXT_VOLUME_INFO Volume); +BOOLEAN ExtReadDirectory(PEXT_VOLUME_INFO Volume, ULONG Inode, PVOID* DirectoryBuffer, PEXT_INODE InodePointer); +BOOLEAN ExtReadBlock(PEXT_VOLUME_INFO Volume, ULONG BlockNumber, PVOID Buffer); +BOOLEAN ExtReadPartialBlock(PEXT_VOLUME_INFO Volume, ULONG BlockNumber, ULONG StartingOffset, ULONG Length, PVOID Buffer); +BOOLEAN ExtReadInode(PEXT_VOLUME_INFO Volume, ULONG Inode, PEXT_INODE InodeBuffer); +BOOLEAN ExtReadGroupDescriptor(PEXT_VOLUME_INFO Volume, ULONG Group, PEXT_GROUP_DESC GroupBuffer); +ULONG* ExtReadBlockPointerList(PEXT_VOLUME_INFO Volume, PEXT_INODE Inode); +ULONGLONG ExtGetInodeFileSize(PEXT_INODE Inode); +BOOLEAN ExtCopyBlockPointersByExtents(PEXT_VOLUME_INFO Volume, ULONG* BlockList, ULONG* CurrentBlockInList, ULONG BlockCount, PEXT4_EXTENT_HEADER ExtentHeader); +BOOLEAN ExtCopyIndirectBlockPointers(PEXT_VOLUME_INFO Volume, ULONG* BlockList, ULONG* CurrentBlockInList, ULONG BlockCount, ULONG IndirectBlock); +BOOLEAN ExtCopyDoubleIndirectBlockPointers(PEXT_VOLUME_INFO Volume, ULONG* BlockList, ULONG* CurrentBlockInList, ULONG BlockCount, ULONG DoubleIndirectBlock); +BOOLEAN ExtCopyTripleIndirectBlockPointers(PEXT_VOLUME_INFO Volume, ULONG* BlockList, ULONG* CurrentBlockInList, ULONG BlockCount, ULONG TripleIndirectBlock); + +typedef struct _EXT_VOLUME_INFO +{ + ULONG BytesPerSector; // Usually 512... + + PEXT_SUPER_BLOCK SuperBlock; // Ext file system super block + PEXT_GROUP_DESC GroupDescriptors; // Ext file system group descriptors + + ULONG BlockSizeInBytes; // Block size in bytes + ULONG BlockSizeInSectors; // Block size in sectors + ULONG FragmentSizeInBytes; // Fragment size in bytes + ULONG FragmentSizeInSectors; // Fragment size in sectors + ULONG InodeSizeInBytes; // Inode size in bytes + ULONG GroupDescSizeInBytes; // Group descriptor size in bytes + ULONG GroupCount; // Number of groups in this file system + ULONG InodesPerBlock; // Number of inodes in one block + ULONG GroupDescPerBlock; // Number of group descriptors in one block + + ULONG DeviceId; // Ext file system device ID + +} EXT_VOLUME_INFO; + +PEXT_VOLUME_INFO ExtVolumes[MAX_FDS]; + +#define TAG_EXT_BLOCK_LIST 'LtxE' +#define TAG_EXT_FILE 'FtxE' +#define TAG_EXT_BUFFER 'BtxE' +#define TAG_EXT_SUPER_BLOCK 'StxE' +#define TAG_EXT_GROUP_DESC 'GtxE' +#define TAG_EXT_VOLUME 'VtxE' + +BOOLEAN ExtOpenVolume(PEXT_VOLUME_INFO Volume) +{ + TRACE("ExtOpenVolume() DeviceId = %d\n", Volume->DeviceId); + +#if 0 + /* Initialize the disk cache for this drive */ + if (!CacheInitializeDrive(DriveNumber)) + { + return FALSE; + } +#endif + Volume->BytesPerSector = SECTOR_SIZE; + + /* Read in the super block */ + if (!ExtReadSuperBlock(Volume)) + return FALSE; + + /* Read in the group descriptors */ + if (!ExtReadGroupDescriptors(Volume)) + return FALSE; + + return TRUE; +} + +/* + * ExtOpenFile() + * Tries to open the file 'name' and returns true or false + * for success and failure respectively + */ +PEXT_FILE_INFO ExtOpenFile(PEXT_VOLUME_INFO Volume, PCSTR FileName) +{ + EXT_FILE_INFO TempExtFileInfo; + PEXT_FILE_INFO FileHandle; + CHAR SymLinkPath[EXT_DIR_ENTRY_MAX_NAME_LENGTH]; + CHAR FullPath[EXT_DIR_ENTRY_MAX_NAME_LENGTH * 2]; + ULONG_PTR Index; + + TRACE("ExtOpenFile() FileName = \"%s\"\n", FileName); + + RtlZeroMemory(SymLinkPath, sizeof(SymLinkPath)); + + // Lookup the file in the file system + if (!ExtLookupFile(Volume, FileName, &TempExtFileInfo)) + { + return NULL; + } + + // If we got a symbolic link then fix up the path + // and re-call this function + if ((TempExtFileInfo.Inode.Mode & EXT_S_IFMT) == EXT_S_IFLNK) + { + TRACE("File is a symbolic link\n"); + + // Now read in the symbolic link path + if (!ExtReadFileBig(&TempExtFileInfo, TempExtFileInfo.FileSize, NULL, SymLinkPath)) + { + if (TempExtFileInfo.FileBlockList != NULL) + { + FrLdrTempFree(TempExtFileInfo.FileBlockList, TAG_EXT_BLOCK_LIST); + } + + return NULL; + } + + TRACE("Symbolic link path = \"%s\"\n", SymLinkPath); + + // Get the full path + if (SymLinkPath[0] == '/' || SymLinkPath[0] == '\\') + { + // Symbolic link is an absolute path + // So copy it to FullPath, but skip over + // the '/' character at the beginning + strcpy(FullPath, &SymLinkPath[1]); + } + else + { + // Symbolic link is a relative path + // Copy the first part of the path + strcpy(FullPath, FileName); + + // Remove the last part of the path + for (Index=strlen(FullPath); Index>0; ) + { + Index--; + if (FullPath[Index] == '/' || FullPath[Index] == '\\') + { + break; + } + } + FullPath[Index] = '\0'; + + // Concatenate the symbolic link + strcat(FullPath, Index == 0 ? "" : "/"); + strcat(FullPath, SymLinkPath); + } + + TRACE("Full file path = \"%s\"\n", FullPath); + + if (TempExtFileInfo.FileBlockList != NULL) + { + FrLdrTempFree(TempExtFileInfo.FileBlockList, TAG_EXT_BLOCK_LIST); + } + + return ExtOpenFile(Volume, FullPath); + } + else + { + FileHandle = FrLdrTempAlloc(sizeof(EXT_FILE_INFO), TAG_EXT_FILE); + if (FileHandle == NULL) + { + if (TempExtFileInfo.FileBlockList != NULL) + { + FrLdrTempFree(TempExtFileInfo.FileBlockList, TAG_EXT_BLOCK_LIST); + } + + return NULL; + } + + RtlCopyMemory(FileHandle, &TempExtFileInfo, sizeof(EXT_FILE_INFO)); + + return FileHandle; + } +} + +/* + * ExtLookupFile() + * This function searches the file system for the + * specified filename and fills in a EXT_FILE_INFO structure + * with info describing the file, etc. returns true + * if the file exists or false otherwise + */ +BOOLEAN ExtLookupFile(PEXT_VOLUME_INFO Volume, PCSTR FileName, PEXT_FILE_INFO ExtFileInfo) +{ + UINT32 i; + ULONG NumberOfPathParts; + CHAR PathPart[261]; + PVOID DirectoryBuffer; + ULONG DirectoryInode = EXT_ROOT_INODE; + EXT_INODE InodeData; + EXT_DIR_ENTRY DirectoryEntry; + + TRACE("ExtLookupFile() FileName = \"%s\"\n", FileName); + + RtlZeroMemory(ExtFileInfo, sizeof(EXT_FILE_INFO)); + + /* Skip leading path separator, if any */ + if (*FileName == '\\' || *FileName == '/') + ++FileName; + // + // Figure out how many sub-directories we are nested in + // + NumberOfPathParts = FsGetNumPathParts(FileName); + + // + // Loop once for each part + // + for (i=0; iVolume = Volume; + + // If it's a regular file or a regular symbolic link + // then get the block pointer list otherwise it must + // be a fast symbolic link which doesn't have a block list + if (((InodeData.Mode & EXT_S_IFMT) == EXT_S_IFREG) || + ((InodeData.Mode & EXT_S_IFMT) == EXT_S_IFLNK && InodeData.Size > FAST_SYMLINK_MAX_NAME_SIZE)) + { + ExtFileInfo->FileBlockList = ExtReadBlockPointerList(Volume, &InodeData); + if (ExtFileInfo->FileBlockList == NULL) + { + return FALSE; + } + } + else + { + ExtFileInfo->FileBlockList = NULL; + } + + ExtFileInfo->FilePointer = 0; + ExtFileInfo->FileSize = ExtGetInodeFileSize(&InodeData); + RtlCopyMemory(&ExtFileInfo->Inode, &InodeData, sizeof(EXT_INODE)); + + return TRUE; +} + +BOOLEAN ExtSearchDirectoryBufferForFile(PVOID DirectoryBuffer, ULONG DirectorySize, PCHAR FileName, PEXT_DIR_ENTRY DirectoryEntry) +{ + ULONG CurrentOffset = 0; + PEXT_DIR_ENTRY CurrentDirectoryEntry; + + TRACE("ExtSearchDirectoryBufferForFile() DirectoryBuffer = 0x%x DirectorySize = %d FileName = \"%s\"\n", DirectoryBuffer, DirectorySize, FileName); + + while (CurrentOffset < DirectorySize) + { + CurrentDirectoryEntry = (PEXT_DIR_ENTRY)((ULONG_PTR)DirectoryBuffer + CurrentOffset); + + if (!CurrentDirectoryEntry->EntryLen) + break; + + if ((CurrentDirectoryEntry->EntryLen + CurrentOffset) > DirectorySize) + { + FileSystemError("Directory entry extends past end of directory file."); + return FALSE; + } + + if (!CurrentDirectoryEntry->Inode) + goto NextDirectoryEntry; + + TRACE("EXT Directory Entry:\n"); + TRACE("Inode = %d\n", CurrentDirectoryEntry->Inode); + TRACE("EntryLen = %d\n", CurrentDirectoryEntry->EntryLen); + TRACE("NameLen = %d\n", CurrentDirectoryEntry->NameLen); + TRACE("FileType = %d\n", CurrentDirectoryEntry->FileType); + TRACE("Name = \""); + for (ULONG NameOffset = 0; NameOffset < CurrentDirectoryEntry->NameLen; NameOffset++) + { + TRACE("%c", CurrentDirectoryEntry->Name[NameOffset]); + } + TRACE("\"\n\n"); + + if (strlen(FileName) == CurrentDirectoryEntry->NameLen && + !_strnicmp(FileName, CurrentDirectoryEntry->Name, CurrentDirectoryEntry->NameLen)) + { + RtlCopyMemory(DirectoryEntry, CurrentDirectoryEntry, sizeof(EXT_DIR_ENTRY)); + + return TRUE; + } + +NextDirectoryEntry: + CurrentOffset += CurrentDirectoryEntry->EntryLen; + } + + return FALSE; +} + +/* + * ExtReadFileBig() + * Reads BytesToRead from open file and + * returns the number of bytes read in BytesRead + */ +BOOLEAN ExtReadFileBig(PEXT_FILE_INFO ExtFileInfo, ULONGLONG BytesToRead, ULONGLONG* BytesRead, PVOID Buffer) +{ + PEXT_VOLUME_INFO Volume = ExtFileInfo->Volume; + ULONG BlockNumber; + ULONG BlockNumberIndex; + ULONG OffsetInBlock; + ULONG LengthInBlock; + ULONG NumberOfBlocks; + + TRACE("ExtReadFileBig() BytesToRead = %d Buffer = 0x%x\n", (ULONG)BytesToRead, Buffer); + + if (BytesRead != NULL) + { + *BytesRead = 0; + } + + // Make sure we have the block pointer list if we need it + if (ExtFileInfo->FileBlockList == NULL) + { + // Block pointer list is NULL + // so this better be a fast symbolic link or else + if (((ExtFileInfo->Inode.Mode & EXT_S_IFMT) != EXT_S_IFLNK) || + (ExtFileInfo->FileSize > FAST_SYMLINK_MAX_NAME_SIZE)) + { + FileSystemError("Block pointer list is NULL and file is not a fast symbolic link."); + return FALSE; + } + } + + // + // If the user is trying to read past the end of + // the file then return success with BytesRead == 0. + // + if (ExtFileInfo->FilePointer >= ExtFileInfo->FileSize) + { + return TRUE; + } + + // + // If the user is trying to read more than there is to read + // then adjust the amount to read. + // + if ((ExtFileInfo->FilePointer + BytesToRead) > ExtFileInfo->FileSize) + { + BytesToRead = (ExtFileInfo->FileSize - ExtFileInfo->FilePointer); + } + + // Check if this is a fast symbolic link + // if so then the read is easy + if (((ExtFileInfo->Inode.Mode & EXT_S_IFMT) == EXT_S_IFLNK) && + (ExtFileInfo->FileSize <= FAST_SYMLINK_MAX_NAME_SIZE)) + { + TRACE("Reading fast symbolic link data\n"); + + // Copy the data from the link + RtlCopyMemory(Buffer, (PVOID)((ULONG_PTR)ExtFileInfo->FilePointer + ExtFileInfo->Inode.SymLink), (ULONG)BytesToRead); + + if (BytesRead != NULL) + { + *BytesRead = BytesToRead; + } + // ExtFileInfo->FilePointer += BytesToRead; + + return TRUE; + } + + // + // Ok, now we have to perform at most 3 calculations + // I'll draw you a picture (using nifty ASCII art): + // + // CurrentFilePointer -+ + // | + // +----------------+ + // | + // +-----------+-----------+-----------+-----------+ + // | Block 1 | Block 2 | Block 3 | Block 4 | + // +-----------+-----------+-----------+-----------+ + // | | + // +---------------+--------------------+ + // | + // BytesToRead -------+ + // + // 1 - The first calculation (and read) will align + // the file pointer with the next block. + // boundary (if we are supposed to read that much) + // 2 - The next calculation (and read) will read + // in all the full blocks that the requested + // amount of data would cover (in this case + // blocks 2 & 3). + // 3 - The last calculation (and read) would read + // in the remainder of the data requested out of + // the last block. + // + + // + // Only do the first read if we + // aren't aligned on a block boundary + // + if (ExtFileInfo->FilePointer % Volume->BlockSizeInBytes) + { + // + // Do the math for our first read + // + BlockNumberIndex = (ULONG)(ExtFileInfo->FilePointer / Volume->BlockSizeInBytes); + BlockNumber = ExtFileInfo->FileBlockList[BlockNumberIndex]; + OffsetInBlock = (ExtFileInfo->FilePointer % Volume->BlockSizeInBytes); + LengthInBlock = (ULONG)((BytesToRead > (Volume->BlockSizeInBytes - OffsetInBlock)) ? (Volume->BlockSizeInBytes - OffsetInBlock) : BytesToRead); + + // + // Now do the read and update BytesRead, BytesToRead, FilePointer, & Buffer + // + if (!ExtReadPartialBlock(Volume, BlockNumber, OffsetInBlock, LengthInBlock, Buffer)) + { + return FALSE; + } + if (BytesRead != NULL) + { + *BytesRead += LengthInBlock; + } + BytesToRead -= LengthInBlock; + ExtFileInfo->FilePointer += LengthInBlock; + Buffer = (PVOID)((ULONG_PTR)Buffer + LengthInBlock); + } + + // + // Do the math for our second read (if any data left) + // + if (BytesToRead > 0) + { + // + // Determine how many full clusters we need to read + // + NumberOfBlocks = (ULONG)(BytesToRead / Volume->BlockSizeInBytes); + + while (NumberOfBlocks > 0) + { + BlockNumberIndex = (ULONG)(ExtFileInfo->FilePointer / Volume->BlockSizeInBytes); + BlockNumber = ExtFileInfo->FileBlockList[BlockNumberIndex]; + + // + // Now do the read and update BytesRead, BytesToRead, FilePointer, & Buffer + // + if (!ExtReadBlock(Volume, BlockNumber, Buffer)) + { + return FALSE; + } + if (BytesRead != NULL) + { + *BytesRead += Volume->BlockSizeInBytes; + } + BytesToRead -= Volume->BlockSizeInBytes; + ExtFileInfo->FilePointer += Volume->BlockSizeInBytes; + Buffer = (PVOID)((ULONG_PTR)Buffer + Volume->BlockSizeInBytes); + NumberOfBlocks--; + } + } + + // + // Do the math for our third read (if any data left) + // + if (BytesToRead > 0) + { + BlockNumberIndex = (ULONG)(ExtFileInfo->FilePointer / Volume->BlockSizeInBytes); + BlockNumber = ExtFileInfo->FileBlockList[BlockNumberIndex]; + + // + // Now do the read and update BytesRead & FilePointer + // + if (!ExtReadPartialBlock(Volume, BlockNumber, 0, (ULONG)BytesToRead, Buffer)) + { + return FALSE; + } + if (BytesRead != NULL) + { + *BytesRead += BytesToRead; + } + ExtFileInfo->FilePointer += BytesToRead; + } + + return TRUE; +} + +BOOLEAN ExtReadVolumeSectors(PEXT_VOLUME_INFO Volume, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer) +{ +#if 0 + return CacheReadDiskSectors(DriveNumber, SectorNumber + ExtVolumeStartSector, SectorCount, Buffer); +#endif + + LARGE_INTEGER Position; + ULONG Count; + ARC_STATUS Status; + + /* Seek to right position */ + Position.QuadPart = (ULONGLONG)SectorNumber * 512; + Status = ArcSeek(Volume->DeviceId, &Position, SeekAbsolute); + if (Status != ESUCCESS) + { + TRACE("ExtReadVolumeSectors() Failed to seek\n"); + return FALSE; + } + + /* Read data */ + Status = ArcRead(Volume->DeviceId, Buffer, SectorCount * 512, &Count); + if (Status != ESUCCESS || Count != SectorCount * 512) + { + TRACE("ExtReadVolumeSectors() Failed to read\n"); + return FALSE; + } + + /* Return success */ + return TRUE; +} + +BOOLEAN ExtReadSuperBlock(PEXT_VOLUME_INFO Volume) +{ + PEXT_SUPER_BLOCK SuperBlock = Volume->SuperBlock; + LARGE_INTEGER Position; + ULONG Count; + ARC_STATUS Status; + + TRACE("ExtReadSuperBlock()\n"); + +#if 0 + /* Free any memory previously allocated */ + if (SuperBlock != NULL) + { + FrLdrTempFree(SuperBlock, TAG_EXT_SUPER_BLOCK); + SuperBlock = NULL; + } +#endif + + /* Allocate the memory to hold the super block if needed */ + if (SuperBlock == NULL) + { + SuperBlock = (PEXT_SUPER_BLOCK)FrLdrTempAlloc(1024, TAG_EXT_SUPER_BLOCK); + if (SuperBlock == NULL) + { + FileSystemError("Out of memory."); + return FALSE; + } + } + Volume->SuperBlock = SuperBlock; + + /* Reset its contents */ + RtlZeroMemory(SuperBlock, 1024); + + /* Read the SuperBlock */ + Position.QuadPart = 2 * 512; + Status = ArcSeek(Volume->DeviceId, &Position, SeekAbsolute); + if (Status != ESUCCESS) + return FALSE; + Status = ArcRead(Volume->DeviceId, SuperBlock, 2 * 512, &Count); + if (Status != ESUCCESS || Count != 2 * 512) + return FALSE; + + TRACE("Dumping super block:\n"); + TRACE("InodesCount: %d\n", SuperBlock->InodesCount); + TRACE("BlocksCountLo: %d\n", SuperBlock->BlocksCountLo); + TRACE("RBlocksCountLo: %d\n", SuperBlock->RBlocksCountLo); + TRACE("FreeBlocksCountLo: %d\n", SuperBlock->FreeBlocksCountLo); + TRACE("FreeInodesCount: %d\n", SuperBlock->FreeInodesCount); + TRACE("FirstDataBlock: %d\n", SuperBlock->FirstDataBlock); + TRACE("LogBlockSize: %d\n", SuperBlock->LogBlockSize); + TRACE("LogFragSize: %d\n", SuperBlock->LogFragSize); + TRACE("BlocksPerGroup: %d\n", SuperBlock->BlocksPerGroup); + TRACE("FragsPerGroup: %d\n", SuperBlock->FragsPerGroup); + TRACE("InodesPerGroup: %d\n", SuperBlock->InodesPerGroup); + TRACE("MTime: %d\n", SuperBlock->MTime); + TRACE("WTime: %d\n", SuperBlock->WTime); + TRACE("MntCount: %d\n", SuperBlock->MntCount); + TRACE("MaxMntCount: %d\n", SuperBlock->MaxMntCount); + TRACE("Magic: 0x%x\n", SuperBlock->Magic); + TRACE("State: 0x%x\n", SuperBlock->State); + TRACE("Errors: 0x%x\n", SuperBlock->Errors); + TRACE("MinorRevisionLevel: %d\n", SuperBlock->MinorRevisionLevel); + TRACE("LastCheck: %d\n", SuperBlock->LastCheck); + TRACE("CheckInterval: %d\n", SuperBlock->CheckInterval); + TRACE("CreatorOS: %d\n", SuperBlock->CreatorOS); + TRACE("RevisionLevel: %d\n", SuperBlock->RevisionLevel); + TRACE("DefResUID: %d\n", SuperBlock->DefResUID); + TRACE("DefResGID: %d\n", SuperBlock->DefResGID); + TRACE("FirstInode: %d\n", SuperBlock->FirstInode); + TRACE("InodeSize: %d\n", SuperBlock->InodeSize); + TRACE("BlockGroupNr: %d\n", SuperBlock->BlockGroupNr); + TRACE("FeatureCompat: 0x%x\n", SuperBlock->FeatureCompat); + TRACE("FeatureIncompat: 0x%x\n", SuperBlock->FeatureIncompat); + TRACE("FeatureROCompat: 0x%x\n", SuperBlock->FeatureROCompat); + TRACE("UUID: { "); + for (ULONG i = 0; i < sizeof(SuperBlock->UUID); i++) + { + TRACE("0x%02x", SuperBlock->UUID[i]); + if (i < sizeof(SuperBlock->UUID) - 1) + TRACE(", "); + } + TRACE(" }\n"); + TRACE("VolumeName: \"%s\"\n", SuperBlock->VolumeName); + TRACE("LastMounted: \"%s\"\n", SuperBlock->LastMounted); + TRACE("AlgorithmUsageBitmap: 0x%x\n", SuperBlock->AlgorithmUsageBitmap); + TRACE("PreallocBlocks: %d\n", SuperBlock->PreallocBlocks); + TRACE("PreallocDirBlocks: %d\n", SuperBlock->PreallocDirBlocks); + TRACE("ReservedGdtBlocks: %d\n", SuperBlock->ReservedGdtBlocks); + TRACE("JournalUUID: { "); + for (ULONG i = 0; i < sizeof(SuperBlock->JournalUUID); i++) + { + TRACE("0x%02x", SuperBlock->JournalUUID[i]); + if (i < sizeof(SuperBlock->JournalUUID) - 1) + TRACE(", "); + } + TRACE(" }\n"); + TRACE("JournalInum: %d\n", SuperBlock->JournalInum); + TRACE("JournalDev: %d\n", SuperBlock->JournalDev); + TRACE("LastOrphan: %d\n", SuperBlock->LastOrphan); + TRACE("HashSeed: { 0x%02x, 0x%02x, 0x%02x, 0x%02x }\n", + SuperBlock->HashSeed[0], SuperBlock->HashSeed[1], + SuperBlock->HashSeed[2], SuperBlock->HashSeed[3]); + TRACE("DefHashVersion: %d\n", SuperBlock->DefHashVersion); + TRACE("JournalBackupType: %d\n", SuperBlock->JournalBackupType); + TRACE("GroupDescSize: %d\n", SuperBlock->GroupDescSize); + + // + // Check the super block magic + // + if (SuperBlock->Magic != EXT_SUPERBLOCK_MAGIC) + { + FileSystemError("Invalid super block magic (0xef53)"); + return FALSE; + } + + // Calculate the group count + Volume->GroupCount = (SuperBlock->BlocksCountLo - SuperBlock->FirstDataBlock + SuperBlock->BlocksPerGroup - 1) / SuperBlock->BlocksPerGroup; + TRACE("ExtGroupCount: %d\n", Volume->GroupCount); + + // Calculate the block size + Volume->BlockSizeInBytes = 1024 << SuperBlock->LogBlockSize; + Volume->BlockSizeInSectors = Volume->BlockSizeInBytes / Volume->BytesPerSector; + TRACE("ExtBlockSizeInBytes: %d\n", Volume->BlockSizeInBytes); + TRACE("ExtBlockSizeInSectors: %d\n", Volume->BlockSizeInSectors); + + // Calculate the fragment size + if (SuperBlock->LogFragSize >= 0) + { + Volume->FragmentSizeInBytes = 1024 << SuperBlock->LogFragSize; + } + else + { + Volume->FragmentSizeInBytes = 1024 >> -(SuperBlock->LogFragSize); + } + Volume->FragmentSizeInSectors = Volume->FragmentSizeInBytes / Volume->BytesPerSector; + TRACE("ExtFragmentSizeInBytes: %d\n", Volume->FragmentSizeInBytes); + TRACE("ExtFragmentSizeInSectors: %d\n", Volume->FragmentSizeInSectors); + + // Verify that the fragment size and the block size are equal + if (Volume->BlockSizeInBytes != Volume->FragmentSizeInBytes) + { + FileSystemError("The fragment size must be equal to the block size."); + return FALSE; + } + + // Set the volume inode size in bytes + Volume->InodeSizeInBytes = EXT_INODE_SIZE(SuperBlock); + TRACE("InodeSizeInBytes: %d\n", Volume->InodeSizeInBytes); + + // Set the volume group descriptor size in bytes + Volume->GroupDescSizeInBytes = EXT_GROUP_DESC_SIZE(SuperBlock); + TRACE("GroupDescSizeInBytes: %d\n", Volume->GroupDescSizeInBytes); + + // Calculate the number of inodes in one block + Volume->InodesPerBlock = Volume->BlockSizeInBytes / Volume->InodeSizeInBytes; + TRACE("ExtInodesPerBlock: %d\n", Volume->InodesPerBlock); + + // Calculate the number of group descriptors in one block + Volume->GroupDescPerBlock = Volume->BlockSizeInBytes / Volume->GroupDescSizeInBytes; + TRACE("ExtGroupDescPerBlock: %d\n", Volume->GroupDescPerBlock); + + return TRUE; +} + +BOOLEAN ExtReadGroupDescriptors(PEXT_VOLUME_INFO Volume) +{ + ULONG GroupDescBlockCount; + ULONG BlockNumber; + PUCHAR CurrentGroupDescBlock; + + TRACE("ExtReadGroupDescriptors()\n"); + + /* Free any memory previously allocated */ + if (Volume->GroupDescriptors != NULL) + { + FrLdrTempFree(Volume->GroupDescriptors, TAG_EXT_GROUP_DESC); + Volume->GroupDescriptors = NULL; + } + + /* Now allocate the memory to hold the group descriptors */ + GroupDescBlockCount = ROUND_UP(Volume->GroupCount, Volume->GroupDescPerBlock) / Volume->GroupDescPerBlock; + Volume->GroupDescriptors = (PEXT_GROUP_DESC)FrLdrTempAlloc(GroupDescBlockCount * Volume->BlockSizeInBytes, TAG_EXT_GROUP_DESC); + if (Volume->GroupDescriptors == NULL) + { + FileSystemError("Out of memory."); + return FALSE; + } + + // Now read the group descriptors + CurrentGroupDescBlock = (PUCHAR)Volume->GroupDescriptors; + BlockNumber = Volume->SuperBlock->FirstDataBlock + 1; + + while (GroupDescBlockCount--) + { + if (!ExtReadBlock(Volume, BlockNumber, CurrentGroupDescBlock)) + { + return FALSE; + } + + BlockNumber++; + CurrentGroupDescBlock += Volume->BlockSizeInBytes; + } + + return TRUE; +} + +BOOLEAN ExtReadDirectory(PEXT_VOLUME_INFO Volume, ULONG Inode, PVOID* DirectoryBuffer, PEXT_INODE InodePointer) +{ + EXT_FILE_INFO DirectoryFileInfo; + + TRACE("ExtReadDirectory() Inode = %d\n", Inode); + + // Read the directory inode + if (!ExtReadInode(Volume, Inode, InodePointer)) + { + return FALSE; + } + + // Make sure it is a directory inode + if ((InodePointer->Mode & EXT_S_IFMT) != EXT_S_IFDIR) + { + FileSystemError("Inode is not a directory."); + return FALSE; + } + + // Fill in file info struct so we can call ExtReadFileBig() + RtlZeroMemory(&DirectoryFileInfo, sizeof(EXT_FILE_INFO)); + DirectoryFileInfo.Volume = Volume; + DirectoryFileInfo.FileBlockList = ExtReadBlockPointerList(Volume, InodePointer); + DirectoryFileInfo.FilePointer = 0; + DirectoryFileInfo.FileSize = ExtGetInodeFileSize(InodePointer); + + if (DirectoryFileInfo.FileBlockList == NULL) + { + return FALSE; + } + + // + // Now allocate the memory to hold the group descriptors + // + ASSERT(DirectoryFileInfo.FileSize <= 0xFFFFFFFF); + *DirectoryBuffer = (PEXT_DIR_ENTRY)FrLdrTempAlloc((ULONG)DirectoryFileInfo.FileSize, TAG_EXT_BUFFER); + + // + // Make sure we got the memory + // + if (*DirectoryBuffer == NULL) + { + FrLdrTempFree(DirectoryFileInfo.FileBlockList, TAG_EXT_BLOCK_LIST); + FileSystemError("Out of memory."); + return FALSE; + } + + // Now read the root directory data + if (!ExtReadFileBig(&DirectoryFileInfo, DirectoryFileInfo.FileSize, NULL, *DirectoryBuffer)) + { + FrLdrTempFree(*DirectoryBuffer, TAG_EXT_BUFFER); + *DirectoryBuffer = NULL; + FrLdrTempFree(DirectoryFileInfo.FileBlockList, TAG_EXT_BLOCK_LIST); + return FALSE; + } + + FrLdrTempFree(DirectoryFileInfo.FileBlockList, TAG_EXT_BLOCK_LIST); + return TRUE; +} + +BOOLEAN ExtReadBlock(PEXT_VOLUME_INFO Volume, ULONG BlockNumber, PVOID Buffer) +{ + CHAR ErrorString[80]; + + TRACE("ExtReadBlock() BlockNumber = %d Buffer = 0x%x\n", BlockNumber, Buffer); + + // Make sure its a valid block + if (BlockNumber > Volume->SuperBlock->BlocksCountLo) + { + sprintf(ErrorString, "Error reading block %d - block out of range.", (int) BlockNumber); + FileSystemError(ErrorString); + return FALSE; + } + + // Check to see if this is a sparse block + if (BlockNumber == 0) + { + TRACE("Block is part of a sparse file. Zeroing input buffer.\n"); + + RtlZeroMemory(Buffer, Volume->BlockSizeInBytes); + + return TRUE; + } + + return ExtReadVolumeSectors(Volume, (ULONGLONG)BlockNumber * Volume->BlockSizeInSectors, Volume->BlockSizeInSectors, Buffer); +} + +/* + * ExtReadPartialBlock() + * Reads part of a block into memory + */ +BOOLEAN ExtReadPartialBlock(PEXT_VOLUME_INFO Volume, ULONG BlockNumber, ULONG StartingOffset, ULONG Length, PVOID Buffer) +{ + PVOID TempBuffer; + + TRACE("ExtReadPartialBlock() BlockNumber = %d StartingOffset = %d Length = %d Buffer = 0x%x\n", BlockNumber, StartingOffset, Length, Buffer); + + TempBuffer = FrLdrTempAlloc(Volume->BlockSizeInBytes, TAG_EXT_BUFFER); + + if (!ExtReadBlock(Volume, BlockNumber, TempBuffer)) + { + FrLdrTempFree(TempBuffer, TAG_EXT_BUFFER); + return FALSE; + } + + RtlCopyMemory(Buffer, ((PUCHAR)TempBuffer + StartingOffset), Length); + + FrLdrTempFree(TempBuffer, TAG_EXT_BUFFER); + + return TRUE; +} + +ULONG ExtGetInodeGroupNumber(PEXT_VOLUME_INFO Volume, ULONG Inode) +{ + return ((Inode - 1) / Volume->SuperBlock->InodesPerGroup); +} + +ULONG ExtGetInodeBlockNumber(PEXT_VOLUME_INFO Volume, ULONG Inode) +{ + return (((Inode - 1) % Volume->SuperBlock->InodesPerGroup) / Volume->InodesPerBlock); +} + +ULONG ExtGetInodeOffsetInBlock(PEXT_VOLUME_INFO Volume, ULONG Inode) +{ + return (((Inode - 1) % Volume->SuperBlock->InodesPerGroup) % Volume->InodesPerBlock); +} + +BOOLEAN ExtReadInode(PEXT_VOLUME_INFO Volume, ULONG Inode, PEXT_INODE InodeBuffer) +{ + ULONG InodeGroupNumber; + ULONG InodeBlockNumber; + ULONG InodeOffsetInBlock; + CHAR ErrorString[80]; + EXT_GROUP_DESC GroupDescriptor; + + TRACE("ExtReadInode() Inode = %d\n", Inode); + + // Make sure its a valid inode + if ((Inode < 1) || (Inode > Volume->SuperBlock->InodesCount)) + { + sprintf(ErrorString, "Error reading inode %ld - inode out of range.", Inode); + FileSystemError(ErrorString); + return FALSE; + } + + // Get inode group & block number and offset in block + InodeGroupNumber = ExtGetInodeGroupNumber(Volume, Inode); + InodeBlockNumber = ExtGetInodeBlockNumber(Volume, Inode); + InodeOffsetInBlock = ExtGetInodeOffsetInBlock(Volume, Inode); + TRACE("InodeGroupNumber = %d\n", InodeGroupNumber); + TRACE("InodeBlockNumber = %d\n", InodeBlockNumber); + TRACE("InodeOffsetInBlock = %d\n", InodeOffsetInBlock); + + // Read the group descriptor + if (!ExtReadGroupDescriptor(Volume, InodeGroupNumber, &GroupDescriptor)) + { + return FALSE; + } + + // Add the start block of the inode table to the inode block number + InodeBlockNumber += GroupDescriptor.InodeTable; + TRACE("InodeBlockNumber (after group desc correction) = %d\n", InodeBlockNumber); + + // Read the block + if (!ExtReadPartialBlock(Volume, + InodeBlockNumber, + (InodeOffsetInBlock * Volume->InodeSizeInBytes), + sizeof(EXT_INODE), + InodeBuffer)) + { + return FALSE; + } + + TRACE("Dumping inode information:\n"); + TRACE("Mode = 0x%x\n", InodeBuffer->Mode); + TRACE("UID = %d\n", InodeBuffer->UID); + TRACE("Size = %d\n", InodeBuffer->Size); + TRACE("Atime = %d\n", InodeBuffer->Atime); + TRACE("Ctime = %d\n", InodeBuffer->Ctime); + TRACE("Mtime = %d\n", InodeBuffer->Mtime); + TRACE("Dtime = %d\n", InodeBuffer->Dtime); + TRACE("GID = %d\n", InodeBuffer->GID); + TRACE("LinksCount = %d\n", InodeBuffer->LinksCount); + TRACE("Blocks = %d\n", InodeBuffer->Blocks); + TRACE("Flags = 0x%x\n", InodeBuffer->Flags); + TRACE("OSD1 = 0x%x\n", InodeBuffer->OSD1); + TRACE("DirectBlocks = { %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u }\n", + InodeBuffer->Blocks.DirectBlocks[0], InodeBuffer->Blocks.DirectBlocks[1], InodeBuffer->Blocks.DirectBlocks[2], InodeBuffer->Blocks.DirectBlocks[3], + InodeBuffer->Blocks.DirectBlocks[4], InodeBuffer->Blocks.DirectBlocks[5], InodeBuffer->Blocks.DirectBlocks[6], InodeBuffer->Blocks.DirectBlocks[7], + InodeBuffer->Blocks.DirectBlocks[8], InodeBuffer->Blocks.DirectBlocks[9], InodeBuffer->Blocks.DirectBlocks[10], InodeBuffer->Blocks.DirectBlocks[11]); + TRACE("IndirectBlock = %u\n", InodeBuffer->Blocks.IndirectBlock); + TRACE("DoubleIndirectBlock = %u\n", InodeBuffer->Blocks.DoubleIndirectBlock); + TRACE("TripleIndirectBlock = %u\n", InodeBuffer->Blocks.TripleIndirectBlock); + TRACE("Generation = %d\n", InodeBuffer->Generation); + TRACE("FileACL = %d\n", InodeBuffer->FileACL); + TRACE("DirACL = %d\n", InodeBuffer->DirACL); + TRACE("FragAddress = %d\n", InodeBuffer->FragAddress); + TRACE("OSD2 = { %d, %d, %d }\n", + InodeBuffer->OSD2[0], InodeBuffer->OSD2[1], InodeBuffer->OSD2[2]); + + return TRUE; +} + +BOOLEAN ExtReadGroupDescriptor(PEXT_VOLUME_INFO Volume, ULONG Group, PEXT_GROUP_DESC GroupBuffer) +{ + TRACE("ExtReadGroupDescriptor()\n"); + +#if 0 + if (!ExtReadBlock(Volume, ExtGetGroupDescBlockNumber(Volume, Group), (PVOID)FILESYSBUFFER)) + { + return FALSE; + } + RtlCopyMemory(GroupBuffer, (PVOID)(FILESYSBUFFER + ExtGetGroupDescOffsetInBlock(Volume, Group)), sizeof(EXT_GROUP_DESC)); +#endif + + RtlCopyMemory(GroupBuffer, &((PUCHAR)Volume->GroupDescriptors)[Volume->GroupDescSizeInBytes * Group], sizeof(EXT_GROUP_DESC)); + + TRACE("Dumping group descriptor:\n"); + TRACE("BlockBitmap = %d\n", GroupBuffer->BlockBitmap); + TRACE("InodeBitmap = %d\n", GroupBuffer->InodeBitmap); + TRACE("InodeTable = %d\n", GroupBuffer->InodeTable); + TRACE("FreeBlocksCount = %d\n", GroupBuffer->FreeBlocksCount); + TRACE("FreeInodesCount = %d\n", GroupBuffer->FreeInodesCount); + TRACE("UsedDirsCount = %d\n", GroupBuffer->UsedDirsCount); + + return TRUE; +} + +ULONG* ExtReadBlockPointerList(PEXT_VOLUME_INFO Volume, PEXT_INODE Inode) +{ + ULONGLONG FileSize; + ULONG BlockCount; + ULONG* BlockList; + ULONG CurrentBlockInList; + ULONG CurrentBlock; + + TRACE("ExtReadBlockPointerList()\n"); + + // Get the number of blocks this file occupies + // I would just use Inode->i_blocks but it + // doesn't seem to be the number of blocks + // the file size corresponds to, but instead + // it is much bigger. + //BlockCount = Inode->i_blocks; + FileSize = ExtGetInodeFileSize(Inode); + FileSize = ROUND_UP(FileSize, Volume->BlockSizeInBytes); + BlockCount = (ULONG)(FileSize / Volume->BlockSizeInBytes); + + // Allocate the memory for the block list + BlockList = FrLdrTempAlloc(BlockCount * sizeof(ULONG), TAG_EXT_BLOCK_LIST); + if (BlockList == NULL) + { + return NULL; + } + + RtlZeroMemory(BlockList, BlockCount * sizeof(ULONG)); + + // If the file is stored in extents, copy the block pointers by reading the + // extent entries. + if (Inode->Flags & EXT4_INODE_FLAG_EXTENTS) + { + CurrentBlockInList = 0; + + if (!ExtCopyBlockPointersByExtents(Volume, BlockList, &CurrentBlockInList, BlockCount, &Inode->ExtentHeader)) + { + FrLdrTempFree(BlockList, TAG_EXT_BLOCK_LIST); + return NULL; + } + + return BlockList; + } + + // Copy the direct block pointers + for (CurrentBlockInList = CurrentBlock = 0; + CurrentBlockInList < BlockCount && CurrentBlock < sizeof(Inode->Blocks.DirectBlocks) / sizeof(*Inode->Blocks.DirectBlocks); + CurrentBlock++, CurrentBlockInList++) + { + BlockList[CurrentBlockInList] = Inode->Blocks.DirectBlocks[CurrentBlock]; + } + + // Copy the indirect block pointers + if (CurrentBlockInList < BlockCount) + { + if (!ExtCopyIndirectBlockPointers(Volume, BlockList, &CurrentBlockInList, BlockCount, Inode->Blocks.IndirectBlock)) + { + FrLdrTempFree(BlockList, TAG_EXT_BLOCK_LIST); + return NULL; + } + } + + // Copy the double indirect block pointers + if (CurrentBlockInList < BlockCount) + { + if (!ExtCopyDoubleIndirectBlockPointers(Volume, BlockList, &CurrentBlockInList, BlockCount, Inode->Blocks.DoubleIndirectBlock)) + { + FrLdrTempFree(BlockList, TAG_EXT_BLOCK_LIST); + return NULL; + } + } + + // Copy the triple indirect block pointers + if (CurrentBlockInList < BlockCount) + { + if (!ExtCopyTripleIndirectBlockPointers(Volume, BlockList, &CurrentBlockInList, BlockCount, Inode->Blocks.TripleIndirectBlock)) + { + FrLdrTempFree(BlockList, TAG_EXT_BLOCK_LIST); + return NULL; + } + } + + return BlockList; +} + +ULONGLONG ExtGetInodeFileSize(PEXT_INODE Inode) +{ + if ((Inode->Mode & EXT_S_IFMT) == EXT_S_IFDIR) + { + return (ULONGLONG)(Inode->Size); + } + else + { + return ((ULONGLONG)(Inode->Size) | ((ULONGLONG)(Inode->DirACL) << 32)); + } +} + +BOOLEAN ExtCopyBlockPointersByExtents(PEXT_VOLUME_INFO Volume, ULONG* BlockList, ULONG* CurrentBlockInList, ULONG BlockCount, PEXT4_EXTENT_HEADER ExtentHeader) +{ + TRACE("ExtCopyBlockPointersByExtents() BlockCount = 0x%p\n", BlockCount); + + if (ExtentHeader->Magic != EXT4_EXTENT_HEADER_MAGIC || + ExtentHeader->Depth > EXT4_EXTENT_MAX_LEVEL) + return FALSE; + + ULONG Level = ExtentHeader->Depth; + ULONG Entries = ExtentHeader->Entries; + + TRACE("Level: %d\n", Level); + TRACE("Entries: %d\n", Entries); + + // If the level is 0, we have a direct extent block mapping + if (!Level) + { + PEXT4_EXTENT Extent = (PVOID)&ExtentHeader[1]; + + while ((*CurrentBlockInList) < BlockCount && Entries--) + { + BOOLEAN SparseExtent = (Extent->Length > EXT4_EXTENT_MAX_LENGTH); + ULONG Length = SparseExtent ? (Extent->Length - EXT4_EXTENT_MAX_LENGTH) : Extent->Length; + ULONG CurrentBlock = SparseExtent ? 0 : Extent->Start; + + // Copy the pointers to the block list + while ((*CurrentBlockInList) < BlockCount && Length--) + { + BlockList[(*CurrentBlockInList)++] = CurrentBlock; + + if (!SparseExtent) + CurrentBlock++; + } + + Extent++; + } + } + else + { + PEXT4_EXTENT_IDX Extent = (PVOID)&ExtentHeader[1]; + + PEXT4_EXTENT_HEADER BlockBuffer = FrLdrTempAlloc(Volume->BlockSizeInBytes, TAG_EXT_BUFFER); + if (!BlockBuffer) + { + return FALSE; + } + + // Recursively copy the pointers to the block list + while ((*CurrentBlockInList) < BlockCount && Entries--) + { + if (!(ExtReadBlock(Volume, Extent->Leaf, BlockBuffer) && + ExtCopyBlockPointersByExtents(Volume, BlockList, CurrentBlockInList, BlockCount, BlockBuffer))) + { + FrLdrTempFree(BlockBuffer, TAG_EXT_BUFFER); + return FALSE; + } + + Extent++; + } + + FrLdrTempFree(BlockBuffer, TAG_EXT_BUFFER); + } + + return TRUE; +} + +BOOLEAN ExtCopyIndirectBlockPointers(PEXT_VOLUME_INFO Volume, ULONG* BlockList, ULONG* CurrentBlockInList, ULONG BlockCount, ULONG IndirectBlock) +{ + ULONG* BlockBuffer; + ULONG CurrentBlock; + ULONG BlockPointersPerBlock; + + TRACE("ExtCopyIndirectBlockPointers() BlockCount = %d\n", BlockCount); + + BlockPointersPerBlock = Volume->BlockSizeInBytes / sizeof(ULONG); + + BlockBuffer = FrLdrTempAlloc(Volume->BlockSizeInBytes, TAG_EXT_BUFFER); + if (!BlockBuffer) + { + return FALSE; + } + + if (!ExtReadBlock(Volume, IndirectBlock, BlockBuffer)) + { + return FALSE; + } + + for (CurrentBlock=0; (*CurrentBlockInList)BlockSizeInBytes / sizeof(ULONG); + + BlockBuffer = (ULONG*)FrLdrTempAlloc(Volume->BlockSizeInBytes, TAG_EXT_BUFFER); + if (BlockBuffer == NULL) + { + return FALSE; + } + + if (!ExtReadBlock(Volume, DoubleIndirectBlock, BlockBuffer)) + { + FrLdrTempFree(BlockBuffer, TAG_EXT_BUFFER); + return FALSE; + } + + for (CurrentBlock=0; (*CurrentBlockInList)BlockSizeInBytes / sizeof(ULONG); + + BlockBuffer = (ULONG*)FrLdrTempAlloc(Volume->BlockSizeInBytes, TAG_EXT_BUFFER); + if (BlockBuffer == NULL) + { + return FALSE; + } + + if (!ExtReadBlock(Volume, TripleIndirectBlock, BlockBuffer)) + { + FrLdrTempFree(BlockBuffer, TAG_EXT_BUFFER); + return FALSE; + } + + for (CurrentBlock=0; (*CurrentBlockInList)EndingAddress.QuadPart = FileHandle->FileSize; + Information->CurrentAddress.QuadPart = FileHandle->FilePointer; + + TRACE("ExtGetFileInformation(%lu) -> FileSize = %llu, FilePointer = 0x%llx\n", + FileId, Information->EndingAddress.QuadPart, Information->CurrentAddress.QuadPart); + + return ESUCCESS; +} + +ARC_STATUS ExtOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId) +{ + PEXT_VOLUME_INFO Volume; + PEXT_FILE_INFO FileHandle; + ULONG DeviceId; + + /* Check parameters */ + if (OpenMode != OpenReadOnly) + return EACCES; + + /* Get underlying device */ + DeviceId = FsGetDeviceId(*FileId); + Volume = ExtVolumes[DeviceId]; + + TRACE("ExtOpen() FileName = \"%s\"\n", Path); + + /* Call the internal open method */ + // Status = ExtOpenFile(Volume, Path, &FileHandle); + FileHandle = ExtOpenFile(Volume, Path); + if (!FileHandle) + return ENOENT; + + /* Success, remember the handle */ + FsSetDeviceSpecific(*FileId, FileHandle); + return ESUCCESS; +} + +ARC_STATUS ExtRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count) +{ + PEXT_FILE_INFO FileHandle = FsGetDeviceSpecific(FileId); + ULONGLONG BytesReadBig; + BOOLEAN Success; + + // + // Read data + // + Success = ExtReadFileBig(FileHandle, N, &BytesReadBig, Buffer); + *Count = (ULONG)BytesReadBig; + + // + // Check for success + // + if (Success) + return ESUCCESS; + else + return EIO; +} + +ARC_STATUS ExtSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekMode) +{ + PEXT_FILE_INFO FileHandle = FsGetDeviceSpecific(FileId); + LARGE_INTEGER NewPosition = *Position; + + switch (SeekMode) + { + case SeekAbsolute: + break; + case SeekRelative: + NewPosition.QuadPart += FileHandle->FilePointer; + break; + default: + ASSERT(FALSE); + return EINVAL; + } + + if (NewPosition.QuadPart >= FileHandle->FileSize) + return EINVAL; + + FileHandle->FilePointer = NewPosition.QuadPart; + return ESUCCESS; +} + +const DEVVTBL ExtFuncTable = +{ + ExtClose, + ExtGetFileInformation, + ExtOpen, + ExtRead, + ExtSeek, + L"ext2fs", +}; + +const DEVVTBL* ExtMount(ULONG DeviceId) +{ + PEXT_VOLUME_INFO Volume; + EXT_SUPER_BLOCK SuperBlock; + LARGE_INTEGER Position; + ULONG Count; + ARC_STATUS Status; + + TRACE("Enter ExtMount(%lu)\n", DeviceId); + + /* Allocate data for volume information */ + Volume = FrLdrTempAlloc(sizeof(EXT_VOLUME_INFO), TAG_EXT_VOLUME); + if (!Volume) + return NULL; + RtlZeroMemory(Volume, sizeof(EXT_VOLUME_INFO)); + + /* Read the SuperBlock */ + Position.QuadPart = 2 * 512; + Status = ArcSeek(DeviceId, &Position, SeekAbsolute); + if (Status != ESUCCESS) + { + FrLdrTempFree(Volume, TAG_EXT_VOLUME); + return NULL; + } + Status = ArcRead(DeviceId, &SuperBlock, sizeof(SuperBlock), &Count); + if (Status != ESUCCESS || Count != sizeof(SuperBlock)) + { + FrLdrTempFree(Volume, TAG_EXT_VOLUME); + return NULL; + } + + /* Check if SuperBlock is valid. If yes, return Ext function table. */ + if (SuperBlock.Magic != EXT_SUPERBLOCK_MAGIC) + { + FrLdrTempFree(Volume, TAG_EXT_VOLUME); + return NULL; + } + + Volume->DeviceId = DeviceId; + + /* Really open the volume */ + if (!ExtOpenVolume(Volume)) + { + FrLdrTempFree(Volume, TAG_EXT_VOLUME); + return NULL; + } + + /* Remember EXT volume information */ + ExtVolumes[DeviceId] = Volume; + + /* Return success */ + TRACE("ExtMount(%lu) success\n", DeviceId); + return &ExtFuncTable; +} + +#endif // _M_ARM diff --git a/boot/freeldr/freeldr/lib/fs/ext2.c b/boot/freeldr/freeldr/lib/fs/ext2.c deleted file mode 100644 index 6ff59398f29b5..0000000000000 --- a/boot/freeldr/freeldr/lib/fs/ext2.c +++ /dev/null @@ -1,1353 +0,0 @@ -/* - * FreeLoader - * Copyright (C) 1998-2003 Brian Palmer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef _M_ARM -#include - -#include -DBG_DEFAULT_CHANNEL(FILESYSTEM); - -BOOLEAN Ext2OpenVolume(PEXT2_VOLUME_INFO Volume); -PEXT2_FILE_INFO Ext2OpenFile(PEXT2_VOLUME_INFO Volume, PCSTR FileName); -BOOLEAN Ext2LookupFile(PEXT2_VOLUME_INFO Volume, PCSTR FileName, PEXT2_FILE_INFO Ext2FileInfo); -BOOLEAN Ext2SearchDirectoryBufferForFile(PVOID DirectoryBuffer, ULONG DirectorySize, PCHAR FileName, PEXT2_DIR_ENTRY DirectoryEntry); -BOOLEAN Ext2ReadVolumeSectors(PEXT2_VOLUME_INFO Volume, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer); - -BOOLEAN Ext2ReadFileBig(PEXT2_FILE_INFO Ext2FileInfo, ULONGLONG BytesToRead, ULONGLONG* BytesRead, PVOID Buffer); -BOOLEAN Ext2ReadSuperBlock(PEXT2_VOLUME_INFO Volume); -BOOLEAN Ext2ReadGroupDescriptors(PEXT2_VOLUME_INFO Volume); -BOOLEAN Ext2ReadDirectory(PEXT2_VOLUME_INFO Volume, ULONG Inode, PVOID* DirectoryBuffer, PEXT2_INODE InodePointer); -BOOLEAN Ext2ReadBlock(PEXT2_VOLUME_INFO Volume, ULONG BlockNumber, PVOID Buffer); -BOOLEAN Ext2ReadPartialBlock(PEXT2_VOLUME_INFO Volume, ULONG BlockNumber, ULONG StartingOffset, ULONG Length, PVOID Buffer); -BOOLEAN Ext2ReadInode(PEXT2_VOLUME_INFO Volume, ULONG Inode, PEXT2_INODE InodeBuffer); -BOOLEAN Ext2ReadGroupDescriptor(PEXT2_VOLUME_INFO Volume, ULONG Group, PEXT2_GROUP_DESC GroupBuffer); -ULONG* Ext2ReadBlockPointerList(PEXT2_VOLUME_INFO Volume, PEXT2_INODE Inode); -ULONGLONG Ext2GetInodeFileSize(PEXT2_INODE Inode); -BOOLEAN Ext2CopyIndirectBlockPointers(PEXT2_VOLUME_INFO Volume, ULONG* BlockList, ULONG* CurrentBlockInList, ULONG BlockCount, ULONG IndirectBlock); -BOOLEAN Ext2CopyDoubleIndirectBlockPointers(PEXT2_VOLUME_INFO Volume, ULONG* BlockList, ULONG* CurrentBlockInList, ULONG BlockCount, ULONG DoubleIndirectBlock); -BOOLEAN Ext2CopyTripleIndirectBlockPointers(PEXT2_VOLUME_INFO Volume, ULONG* BlockList, ULONG* CurrentBlockInList, ULONG BlockCount, ULONG TripleIndirectBlock); - -typedef struct _EXT2_VOLUME_INFO -{ - ULONG BytesPerSector; // Usually 512... - - PEXT2_SUPER_BLOCK SuperBlock; // Ext2 file system super block - PEXT2_GROUP_DESC GroupDescriptors; // Ext2 file system group descriptors - - ULONG BlockSizeInBytes; // Block size in bytes - ULONG BlockSizeInSectors; // Block size in sectors - ULONG FragmentSizeInBytes; // Fragment size in bytes - ULONG FragmentSizeInSectors; // Fragment size in sectors - ULONG GroupCount; // Number of groups in this file system - ULONG InodesPerBlock; // Number of inodes in one block - ULONG GroupDescPerBlock; // Number of group descriptors in one block - - ULONG DeviceId; // Ext2 file system device ID - -} EXT2_VOLUME_INFO; - -PEXT2_VOLUME_INFO Ext2Volumes[MAX_FDS]; - -#define TAG_EXT_BLOCK_LIST 'LtxE' -#define TAG_EXT_FILE 'FtxE' -#define TAG_EXT_BUFFER 'BtxE' -#define TAG_EXT_SUPER_BLOCK 'StxE' -#define TAG_EXT_GROUP_DESC 'GtxE' -#define TAG_EXT_VOLUME 'VtxE' - -BOOLEAN Ext2OpenVolume(PEXT2_VOLUME_INFO Volume) -{ - TRACE("Ext2OpenVolume() DeviceId = %d\n", Volume->DeviceId); - -#if 0 - /* Initialize the disk cache for this drive */ - if (!CacheInitializeDrive(DriveNumber)) - { - return FALSE; - } -#endif - Volume->BytesPerSector = SECTOR_SIZE; - - /* Read in the super block */ - if (!Ext2ReadSuperBlock(Volume)) - return FALSE; - - /* Read in the group descriptors */ - if (!Ext2ReadGroupDescriptors(Volume)) - return FALSE; - - return TRUE; -} - -/* - * Ext2OpenFile() - * Tries to open the file 'name' and returns true or false - * for success and failure respectively - */ -PEXT2_FILE_INFO Ext2OpenFile(PEXT2_VOLUME_INFO Volume, PCSTR FileName) -{ - EXT2_FILE_INFO TempExt2FileInfo; - PEXT2_FILE_INFO FileHandle; - CHAR SymLinkPath[EXT2_NAME_LEN]; - CHAR FullPath[EXT2_NAME_LEN * 2]; - ULONG_PTR Index; - - TRACE("Ext2OpenFile() FileName = %s\n", FileName); - - RtlZeroMemory(SymLinkPath, sizeof(SymLinkPath)); - - // Lookup the file in the file system - if (!Ext2LookupFile(Volume, FileName, &TempExt2FileInfo)) - { - return NULL; - } - - // If we got a symbolic link then fix up the path - // and re-call this function - if ((TempExt2FileInfo.Inode.mode & EXT2_S_IFMT) == EXT2_S_IFLNK) - { - TRACE("File is a symbolic link\n"); - - // Now read in the symbolic link path - if (!Ext2ReadFileBig(&TempExt2FileInfo, TempExt2FileInfo.FileSize, NULL, SymLinkPath)) - { - if (TempExt2FileInfo.FileBlockList != NULL) - { - FrLdrTempFree(TempExt2FileInfo.FileBlockList, TAG_EXT_BLOCK_LIST); - } - - return NULL; - } - - TRACE("Symbolic link path = %s\n", SymLinkPath); - - // Get the full path - if (SymLinkPath[0] == '/' || SymLinkPath[0] == '\\') - { - // Symbolic link is an absolute path - // So copy it to FullPath, but skip over - // the '/' char at the beginning - strcpy(FullPath, &SymLinkPath[1]); - } - else - { - // Symbolic link is a relative path - // Copy the first part of the path - strcpy(FullPath, FileName); - - // Remove the last part of the path - for (Index=strlen(FullPath); Index>0; ) - { - Index--; - if (FullPath[Index] == '/' || FullPath[Index] == '\\') - { - break; - } - } - FullPath[Index] = '\0'; - - // Concatenate the symbolic link - strcat(FullPath, Index == 0 ? "" : "/"); - strcat(FullPath, SymLinkPath); - } - - TRACE("Full file path = %s\n", FullPath); - - if (TempExt2FileInfo.FileBlockList != NULL) - { - FrLdrTempFree(TempExt2FileInfo.FileBlockList, TAG_EXT_BLOCK_LIST); - } - - return Ext2OpenFile(Volume, FullPath); - } - else - { - FileHandle = FrLdrTempAlloc(sizeof(EXT2_FILE_INFO), TAG_EXT_FILE); - if (FileHandle == NULL) - { - if (TempExt2FileInfo.FileBlockList != NULL) - { - FrLdrTempFree(TempExt2FileInfo.FileBlockList, TAG_EXT_BLOCK_LIST); - } - - return NULL; - } - - RtlCopyMemory(FileHandle, &TempExt2FileInfo, sizeof(EXT2_FILE_INFO)); - - return FileHandle; - } -} - -/* - * Ext2LookupFile() - * This function searches the file system for the - * specified filename and fills in a EXT2_FILE_INFO structure - * with info describing the file, etc. returns true - * if the file exists or false otherwise - */ -BOOLEAN Ext2LookupFile(PEXT2_VOLUME_INFO Volume, PCSTR FileName, PEXT2_FILE_INFO Ext2FileInfo) -{ - UINT32 i; - ULONG NumberOfPathParts; - CHAR PathPart[261]; - PVOID DirectoryBuffer; - ULONG DirectoryInode = EXT2_ROOT_INO; - EXT2_INODE InodeData; - EXT2_DIR_ENTRY DirectoryEntry; - - TRACE("Ext2LookupFile() FileName = %s\n", FileName); - - RtlZeroMemory(Ext2FileInfo, sizeof(EXT2_FILE_INFO)); - - /* Skip leading path separator, if any */ - if (*FileName == '\\' || *FileName == '/') - ++FileName; - // - // Figure out how many sub-directories we are nested in - // - NumberOfPathParts = FsGetNumPathParts(FileName); - - // - // Loop once for each part - // - for (i=0; iVolume = Volume; - - // If it's a regular file or a regular symbolic link - // then get the block pointer list otherwise it must - // be a fast symbolic link which doesn't have a block list - if (((InodeData.mode & EXT2_S_IFMT) == EXT2_S_IFREG) || - ((InodeData.mode & EXT2_S_IFMT) == EXT2_S_IFLNK && InodeData.size > FAST_SYMLINK_MAX_NAME_SIZE)) - { - Ext2FileInfo->FileBlockList = Ext2ReadBlockPointerList(Volume, &InodeData); - if (Ext2FileInfo->FileBlockList == NULL) - { - return FALSE; - } - } - else - { - Ext2FileInfo->FileBlockList = NULL; - } - - Ext2FileInfo->FilePointer = 0; - Ext2FileInfo->FileSize = Ext2GetInodeFileSize(&InodeData); - RtlCopyMemory(&Ext2FileInfo->Inode, &InodeData, sizeof(EXT2_INODE)); - - return TRUE; -} - -BOOLEAN Ext2SearchDirectoryBufferForFile(PVOID DirectoryBuffer, ULONG DirectorySize, PCHAR FileName, PEXT2_DIR_ENTRY DirectoryEntry) -{ - ULONG CurrentOffset; - PEXT2_DIR_ENTRY CurrentDirectoryEntry; - - TRACE("Ext2SearchDirectoryBufferForFile() DirectoryBuffer = 0x%x DirectorySize = %d FileName = %s\n", DirectoryBuffer, DirectorySize, FileName); - - for (CurrentOffset=0; CurrentOffsetdirentlen == 0) - { - break; - } - - if ((CurrentDirectoryEntry->direntlen + CurrentOffset) > DirectorySize) - { - FileSystemError("Directory entry extends past end of directory file."); - return FALSE; - } - - TRACE("Dumping directory entry at offset %d:\n", CurrentOffset); - DbgDumpBuffer(DPRINT_FILESYSTEM, CurrentDirectoryEntry, CurrentDirectoryEntry->direntlen); - - if ((_strnicmp(FileName, CurrentDirectoryEntry->name, CurrentDirectoryEntry->namelen) == 0) && - (strlen(FileName) == CurrentDirectoryEntry->namelen)) - { - RtlCopyMemory(DirectoryEntry, CurrentDirectoryEntry, sizeof(EXT2_DIR_ENTRY)); - - TRACE("EXT2 Directory Entry:\n"); - TRACE("inode = %d\n", DirectoryEntry->inode); - TRACE("direntlen = %d\n", DirectoryEntry->direntlen); - TRACE("namelen = %d\n", DirectoryEntry->namelen); - TRACE("filetype = %d\n", DirectoryEntry->filetype); - TRACE("name = "); - for (CurrentOffset=0; CurrentOffsetnamelen; CurrentOffset++) - { - TRACE("%c", DirectoryEntry->name[CurrentOffset]); - } - TRACE("\n"); - - return TRUE; - } - - CurrentOffset += CurrentDirectoryEntry->direntlen; - } - - return FALSE; -} - -/* - * Ext2ReadFileBig() - * Reads BytesToRead from open file and - * returns the number of bytes read in BytesRead - */ -BOOLEAN Ext2ReadFileBig(PEXT2_FILE_INFO Ext2FileInfo, ULONGLONG BytesToRead, ULONGLONG* BytesRead, PVOID Buffer) -{ - PEXT2_VOLUME_INFO Volume = Ext2FileInfo->Volume; - ULONG BlockNumber; - ULONG BlockNumberIndex; - ULONG OffsetInBlock; - ULONG LengthInBlock; - ULONG NumberOfBlocks; - - TRACE("Ext2ReadFileBig() BytesToRead = %d Buffer = 0x%x\n", (ULONG)BytesToRead, Buffer); - - if (BytesRead != NULL) - { - *BytesRead = 0; - } - - // Make sure we have the block pointer list if we need it - if (Ext2FileInfo->FileBlockList == NULL) - { - // Block pointer list is NULL - // so this better be a fast symbolic link or else - if (((Ext2FileInfo->Inode.mode & EXT2_S_IFMT) != EXT2_S_IFLNK) || - (Ext2FileInfo->FileSize > FAST_SYMLINK_MAX_NAME_SIZE)) - { - FileSystemError("Block pointer list is NULL and file is not a fast symbolic link."); - return FALSE; - } - } - - // - // If the user is trying to read past the end of - // the file then return success with BytesRead == 0. - // - if (Ext2FileInfo->FilePointer >= Ext2FileInfo->FileSize) - { - return TRUE; - } - - // - // If the user is trying to read more than there is to read - // then adjust the amount to read. - // - if ((Ext2FileInfo->FilePointer + BytesToRead) > Ext2FileInfo->FileSize) - { - BytesToRead = (Ext2FileInfo->FileSize - Ext2FileInfo->FilePointer); - } - - // Check if this is a fast symbolic link - // if so then the read is easy - if (((Ext2FileInfo->Inode.mode & EXT2_S_IFMT) == EXT2_S_IFLNK) && - (Ext2FileInfo->FileSize <= FAST_SYMLINK_MAX_NAME_SIZE)) - { - TRACE("Reading fast symbolic link data\n"); - - // Copy the data from the link - RtlCopyMemory(Buffer, (PVOID)((ULONG_PTR)Ext2FileInfo->FilePointer + Ext2FileInfo->Inode.symlink), (ULONG)BytesToRead); - - if (BytesRead != NULL) - { - *BytesRead = BytesToRead; - } - // Ext2FileInfo->FilePointer += BytesToRead; - - return TRUE; - } - - // - // Ok, now we have to perform at most 3 calculations - // I'll draw you a picture (using nifty ASCII art): - // - // CurrentFilePointer -+ - // | - // +----------------+ - // | - // +-----------+-----------+-----------+-----------+ - // | Block 1 | Block 2 | Block 3 | Block 4 | - // +-----------+-----------+-----------+-----------+ - // | | - // +---------------+--------------------+ - // | - // BytesToRead -------+ - // - // 1 - The first calculation (and read) will align - // the file pointer with the next block. - // boundary (if we are supposed to read that much) - // 2 - The next calculation (and read) will read - // in all the full blocks that the requested - // amount of data would cover (in this case - // blocks 2 & 3). - // 3 - The last calculation (and read) would read - // in the remainder of the data requested out of - // the last block. - // - - // - // Only do the first read if we - // aren't aligned on a block boundary - // - if (Ext2FileInfo->FilePointer % Volume->BlockSizeInBytes) - { - // - // Do the math for our first read - // - BlockNumberIndex = (ULONG)(Ext2FileInfo->FilePointer / Volume->BlockSizeInBytes); - BlockNumber = Ext2FileInfo->FileBlockList[BlockNumberIndex]; - OffsetInBlock = (Ext2FileInfo->FilePointer % Volume->BlockSizeInBytes); - LengthInBlock = (ULONG)((BytesToRead > (Volume->BlockSizeInBytes - OffsetInBlock)) ? (Volume->BlockSizeInBytes - OffsetInBlock) : BytesToRead); - - // - // Now do the read and update BytesRead, BytesToRead, FilePointer, & Buffer - // - if (!Ext2ReadPartialBlock(Volume, BlockNumber, OffsetInBlock, LengthInBlock, Buffer)) - { - return FALSE; - } - if (BytesRead != NULL) - { - *BytesRead += LengthInBlock; - } - BytesToRead -= LengthInBlock; - Ext2FileInfo->FilePointer += LengthInBlock; - Buffer = (PVOID)((ULONG_PTR)Buffer + LengthInBlock); - } - - // - // Do the math for our second read (if any data left) - // - if (BytesToRead > 0) - { - // - // Determine how many full clusters we need to read - // - NumberOfBlocks = (ULONG)(BytesToRead / Volume->BlockSizeInBytes); - - while (NumberOfBlocks > 0) - { - BlockNumberIndex = (ULONG)(Ext2FileInfo->FilePointer / Volume->BlockSizeInBytes); - BlockNumber = Ext2FileInfo->FileBlockList[BlockNumberIndex]; - - // - // Now do the read and update BytesRead, BytesToRead, FilePointer, & Buffer - // - if (!Ext2ReadBlock(Volume, BlockNumber, Buffer)) - { - return FALSE; - } - if (BytesRead != NULL) - { - *BytesRead += Volume->BlockSizeInBytes; - } - BytesToRead -= Volume->BlockSizeInBytes; - Ext2FileInfo->FilePointer += Volume->BlockSizeInBytes; - Buffer = (PVOID)((ULONG_PTR)Buffer + Volume->BlockSizeInBytes); - NumberOfBlocks--; - } - } - - // - // Do the math for our third read (if any data left) - // - if (BytesToRead > 0) - { - BlockNumberIndex = (ULONG)(Ext2FileInfo->FilePointer / Volume->BlockSizeInBytes); - BlockNumber = Ext2FileInfo->FileBlockList[BlockNumberIndex]; - - // - // Now do the read and update BytesRead & FilePointer - // - if (!Ext2ReadPartialBlock(Volume, BlockNumber, 0, (ULONG)BytesToRead, Buffer)) - { - return FALSE; - } - if (BytesRead != NULL) - { - *BytesRead += BytesToRead; - } - Ext2FileInfo->FilePointer += BytesToRead; - } - - return TRUE; -} - -BOOLEAN Ext2ReadVolumeSectors(PEXT2_VOLUME_INFO Volume, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer) -{ -#if 0 - return CacheReadDiskSectors(DriveNumber, SectorNumber + Ext2VolumeStartSector, SectorCount, Buffer); -#endif - - LARGE_INTEGER Position; - ULONG Count; - ARC_STATUS Status; - - /* Seek to right position */ - Position.QuadPart = (ULONGLONG)SectorNumber * 512; - Status = ArcSeek(Volume->DeviceId, &Position, SeekAbsolute); - if (Status != ESUCCESS) - { - TRACE("Ext2ReadVolumeSectors() Failed to seek\n"); - return FALSE; - } - - /* Read data */ - Status = ArcRead(Volume->DeviceId, Buffer, SectorCount * 512, &Count); - if (Status != ESUCCESS || Count != SectorCount * 512) - { - TRACE("Ext2ReadVolumeSectors() Failed to read\n"); - return FALSE; - } - - /* Return success */ - return TRUE; -} - -BOOLEAN Ext2ReadSuperBlock(PEXT2_VOLUME_INFO Volume) -{ - PEXT2_SUPER_BLOCK SuperBlock = Volume->SuperBlock; - LARGE_INTEGER Position; - ULONG Count; - ARC_STATUS Status; - - TRACE("Ext2ReadSuperBlock()\n"); - -#if 0 - /* Free any memory previously allocated */ - if (SuperBlock != NULL) - { - FrLdrTempFree(SuperBlock, TAG_EXT_SUPER_BLOCK); - SuperBlock = NULL; - } -#endif - - /* Allocate the memory to hold the super block if needed */ - if (SuperBlock == NULL) - { - SuperBlock = (PEXT2_SUPER_BLOCK)FrLdrTempAlloc(1024, TAG_EXT_SUPER_BLOCK); - if (SuperBlock == NULL) - { - FileSystemError("Out of memory."); - return FALSE; - } - } - Volume->SuperBlock = SuperBlock; - - /* Reset its contents */ - RtlZeroMemory(SuperBlock, 1024); - - /* Read the SuperBlock */ - Position.QuadPart = 2 * 512; - Status = ArcSeek(Volume->DeviceId, &Position, SeekAbsolute); - if (Status != ESUCCESS) - return FALSE; - Status = ArcRead(Volume->DeviceId, SuperBlock, 2 * 512, &Count); - if (Status != ESUCCESS || Count != 2 * 512) - return FALSE; - - TRACE("Dumping super block:\n"); - TRACE("total_inodes: %d\n", SuperBlock->total_inodes); - TRACE("total_blocks: %d\n", SuperBlock->total_blocks); - TRACE("reserved_blocks: %d\n", SuperBlock->reserved_blocks); - TRACE("free_blocks: %d\n", SuperBlock->free_blocks); - TRACE("free_inodes: %d\n", SuperBlock->free_inodes); - TRACE("first_data_block: %d\n", SuperBlock->first_data_block); - TRACE("log2_block_size: %d\n", SuperBlock->log2_block_size); - TRACE("log2_fragment_size: %d\n", SuperBlock->log2_fragment_size); - TRACE("blocks_per_group: %d\n", SuperBlock->blocks_per_group); - TRACE("fragments_per_group: %d\n", SuperBlock->fragments_per_group); - TRACE("inodes_per_group: %d\n", SuperBlock->inodes_per_group); - TRACE("mtime: %d\n", SuperBlock->mtime); - TRACE("utime: %d\n", SuperBlock->utime); - TRACE("mnt_count: %d\n", SuperBlock->mnt_count); - TRACE("max_mnt_count: %d\n", SuperBlock->max_mnt_count); - TRACE("magic: 0x%x\n", SuperBlock->magic); - TRACE("fs_state: %d\n", SuperBlock->fs_state); - TRACE("error_handling: %d\n", SuperBlock->error_handling); - TRACE("minor_revision_level: %d\n", SuperBlock->minor_revision_level); - TRACE("lastcheck: %d\n", SuperBlock->lastcheck); - TRACE("checkinterval: %d\n", SuperBlock->checkinterval); - TRACE("creator_os: %d\n", SuperBlock->creator_os); - TRACE("revision_level: %d\n", SuperBlock->revision_level); - TRACE("uid_reserved: %d\n", SuperBlock->uid_reserved); - TRACE("gid_reserved: %d\n", SuperBlock->gid_reserved); - TRACE("first_inode: %d\n", SuperBlock->first_inode); - TRACE("inode_size: %d\n", SuperBlock->inode_size); - TRACE("block_group_number: %d\n", SuperBlock->block_group_number); - TRACE("feature_compatibility: 0x%x\n", SuperBlock->feature_compatibility); - TRACE("feature_incompat: 0x%x\n", SuperBlock->feature_incompat); - TRACE("feature_ro_compat: 0x%x\n", SuperBlock->feature_ro_compat); - TRACE("unique_id = { 0x%x, 0x%x, 0x%x, 0x%x }\n", - SuperBlock->unique_id[0], SuperBlock->unique_id[1], - SuperBlock->unique_id[2], SuperBlock->unique_id[3]); - TRACE("volume_name = '%.16s'\n", SuperBlock->volume_name); - TRACE("last_mounted_on = '%.64s'\n", SuperBlock->last_mounted_on); - TRACE("compression_info = 0x%x\n", SuperBlock->compression_info); - - // - // Check the super block magic - // - if (SuperBlock->magic != EXT2_MAGIC) - { - FileSystemError("Invalid super block magic (0xef53)"); - return FALSE; - } - - // - // Check the revision level - // - if (SuperBlock->revision_level > EXT2_DYNAMIC_REVISION) - { - FileSystemError("FreeLoader does not understand the revision of this EXT2/EXT3 filesystem.\nPlease update FreeLoader."); - return FALSE; - } - - // - // Check the feature set - // Don't need to check the compatible or read-only compatible features - // because we only mount the filesystem as read-only - // - if ((SuperBlock->revision_level >= EXT2_DYNAMIC_REVISION) && - (/*((SuperBlock->s_feature_compat & ~EXT3_FEATURE_COMPAT_SUPP) != 0) ||*/ - /*((SuperBlock->s_feature_ro_compat & ~EXT3_FEATURE_RO_COMPAT_SUPP) != 0) ||*/ - ((SuperBlock->feature_incompat & ~EXT3_FEATURE_INCOMPAT_SUPP) != 0))) - { - FileSystemError("FreeLoader does not understand features of this EXT2/EXT3 filesystem.\nPlease update FreeLoader."); - return FALSE; - } - - // Calculate the group count - Volume->GroupCount = (SuperBlock->total_blocks - SuperBlock->first_data_block + SuperBlock->blocks_per_group - 1) / SuperBlock->blocks_per_group; - TRACE("Ext2GroupCount: %d\n", Volume->GroupCount); - - // Calculate the block size - Volume->BlockSizeInBytes = 1024 << SuperBlock->log2_block_size; - Volume->BlockSizeInSectors = Volume->BlockSizeInBytes / Volume->BytesPerSector; - TRACE("Ext2BlockSizeInBytes: %d\n", Volume->BlockSizeInBytes); - TRACE("Ext2BlockSizeInSectors: %d\n", Volume->BlockSizeInSectors); - - // Calculate the fragment size - if (SuperBlock->log2_fragment_size >= 0) - { - Volume->FragmentSizeInBytes = 1024 << SuperBlock->log2_fragment_size; - } - else - { - Volume->FragmentSizeInBytes = 1024 >> -(SuperBlock->log2_fragment_size); - } - Volume->FragmentSizeInSectors = Volume->FragmentSizeInBytes / Volume->BytesPerSector; - TRACE("Ext2FragmentSizeInBytes: %d\n", Volume->FragmentSizeInBytes); - TRACE("Ext2FragmentSizeInSectors: %d\n", Volume->FragmentSizeInSectors); - - // Verify that the fragment size and the block size are equal - if (Volume->BlockSizeInBytes != Volume->FragmentSizeInBytes) - { - FileSystemError("The fragment size must be equal to the block size."); - return FALSE; - } - - // Calculate the number of inodes in one block - Volume->InodesPerBlock = Volume->BlockSizeInBytes / EXT2_INODE_SIZE(SuperBlock); - TRACE("Ext2InodesPerBlock: %d\n", Volume->InodesPerBlock); - - // Calculate the number of group descriptors in one block - Volume->GroupDescPerBlock = EXT2_DESC_PER_BLOCK(SuperBlock); - TRACE("Ext2GroupDescPerBlock: %d\n", Volume->GroupDescPerBlock); - - return TRUE; -} - -BOOLEAN Ext2ReadGroupDescriptors(PEXT2_VOLUME_INFO Volume) -{ - ULONG GroupDescBlockCount; - ULONG BlockNumber; - PUCHAR CurrentGroupDescBlock; - - TRACE("Ext2ReadGroupDescriptors()\n"); - - /* Free any memory previously allocated */ - if (Volume->GroupDescriptors != NULL) - { - FrLdrTempFree(Volume->GroupDescriptors, TAG_EXT_GROUP_DESC); - Volume->GroupDescriptors = NULL; - } - - /* Now allocate the memory to hold the group descriptors */ - GroupDescBlockCount = ROUND_UP(Volume->GroupCount, Volume->GroupDescPerBlock) / Volume->GroupDescPerBlock; - Volume->GroupDescriptors = (PEXT2_GROUP_DESC)FrLdrTempAlloc(GroupDescBlockCount * Volume->BlockSizeInBytes, TAG_EXT_GROUP_DESC); - if (Volume->GroupDescriptors == NULL) - { - FileSystemError("Out of memory."); - return FALSE; - } - - // Now read the group descriptors - CurrentGroupDescBlock = (PUCHAR)Volume->GroupDescriptors; - BlockNumber = Volume->SuperBlock->first_data_block + 1; - - while (GroupDescBlockCount--) - { - if (!Ext2ReadBlock(Volume, BlockNumber, CurrentGroupDescBlock)) - { - return FALSE; - } - - BlockNumber++; - CurrentGroupDescBlock += Volume->BlockSizeInBytes; - } - - return TRUE; -} - -BOOLEAN Ext2ReadDirectory(PEXT2_VOLUME_INFO Volume, ULONG Inode, PVOID* DirectoryBuffer, PEXT2_INODE InodePointer) -{ - EXT2_FILE_INFO DirectoryFileInfo; - - TRACE("Ext2ReadDirectory() Inode = %d\n", Inode); - - // Read the directory inode - if (!Ext2ReadInode(Volume, Inode, InodePointer)) - { - return FALSE; - } - - // Make sure it is a directory inode - if ((InodePointer->mode & EXT2_S_IFMT) != EXT2_S_IFDIR) - { - FileSystemError("Inode is not a directory."); - return FALSE; - } - - // Fill in file info struct so we can call Ext2ReadFileBig() - RtlZeroMemory(&DirectoryFileInfo, sizeof(EXT2_FILE_INFO)); - DirectoryFileInfo.Volume = Volume; - DirectoryFileInfo.FileBlockList = Ext2ReadBlockPointerList(Volume, InodePointer); - DirectoryFileInfo.FilePointer = 0; - DirectoryFileInfo.FileSize = Ext2GetInodeFileSize(InodePointer); - - if (DirectoryFileInfo.FileBlockList == NULL) - { - return FALSE; - } - - // - // Now allocate the memory to hold the group descriptors - // - ASSERT(DirectoryFileInfo.FileSize <= 0xFFFFFFFF); - *DirectoryBuffer = (PEXT2_DIR_ENTRY)FrLdrTempAlloc((ULONG)DirectoryFileInfo.FileSize, TAG_EXT_BUFFER); - - // - // Make sure we got the memory - // - if (*DirectoryBuffer == NULL) - { - FrLdrTempFree(DirectoryFileInfo.FileBlockList, TAG_EXT_BLOCK_LIST); - FileSystemError("Out of memory."); - return FALSE; - } - - // Now read the root directory data - if (!Ext2ReadFileBig(&DirectoryFileInfo, DirectoryFileInfo.FileSize, NULL, *DirectoryBuffer)) - { - FrLdrTempFree(*DirectoryBuffer, TAG_EXT_BUFFER); - *DirectoryBuffer = NULL; - FrLdrTempFree(DirectoryFileInfo.FileBlockList, TAG_EXT_BLOCK_LIST); - return FALSE; - } - - FrLdrTempFree(DirectoryFileInfo.FileBlockList, TAG_EXT_BLOCK_LIST); - return TRUE; -} - -BOOLEAN Ext2ReadBlock(PEXT2_VOLUME_INFO Volume, ULONG BlockNumber, PVOID Buffer) -{ - CHAR ErrorString[80]; - - TRACE("Ext2ReadBlock() BlockNumber = %d Buffer = 0x%x\n", BlockNumber, Buffer); - - // Make sure its a valid block - if (BlockNumber > Volume->SuperBlock->total_blocks) - { - sprintf(ErrorString, "Error reading block %d - block out of range.", (int) BlockNumber); - FileSystemError(ErrorString); - return FALSE; - } - - // Check to see if this is a sparse block - if (BlockNumber == 0) - { - TRACE("Block is part of a sparse file. Zeroing input buffer.\n"); - - RtlZeroMemory(Buffer, Volume->BlockSizeInBytes); - - return TRUE; - } - - return Ext2ReadVolumeSectors(Volume, (ULONGLONG)BlockNumber * Volume->BlockSizeInSectors, Volume->BlockSizeInSectors, Buffer); -} - -/* - * Ext2ReadPartialBlock() - * Reads part of a block into memory - */ -BOOLEAN Ext2ReadPartialBlock(PEXT2_VOLUME_INFO Volume, ULONG BlockNumber, ULONG StartingOffset, ULONG Length, PVOID Buffer) -{ - PVOID TempBuffer; - - TRACE("Ext2ReadPartialBlock() BlockNumber = %d StartingOffset = %d Length = %d Buffer = 0x%x\n", BlockNumber, StartingOffset, Length, Buffer); - - TempBuffer = FrLdrTempAlloc(Volume->BlockSizeInBytes, TAG_EXT_BUFFER); - - if (!Ext2ReadBlock(Volume, BlockNumber, TempBuffer)) - { - FrLdrTempFree(TempBuffer, TAG_EXT_BUFFER); - return FALSE; - } - - RtlCopyMemory(Buffer, ((PUCHAR)TempBuffer + StartingOffset), Length); - - FrLdrTempFree(TempBuffer, TAG_EXT_BUFFER); - - return TRUE; -} - -#if 0 -ULONG Ext2GetGroupDescBlockNumber(PEXT2_VOLUME_INFO Volume, ULONG Group) -{ - return (((Group * sizeof(EXT2_GROUP_DESC)) / Volume->GroupDescPerBlock) + Volume->SuperBlock->first_data_block + 1); -} - -ULONG Ext2GetGroupDescOffsetInBlock(PEXT2_VOLUME_INFO Volume, ULONG Group) -{ - return ((Group * sizeof(EXT2_GROUP_DESC)) % Volume->GroupDescPerBlock); -} -#endif - -ULONG Ext2GetInodeGroupNumber(PEXT2_VOLUME_INFO Volume, ULONG Inode) -{ - return ((Inode - 1) / Volume->SuperBlock->inodes_per_group); -} - -ULONG Ext2GetInodeBlockNumber(PEXT2_VOLUME_INFO Volume, ULONG Inode) -{ - return (((Inode - 1) % Volume->SuperBlock->inodes_per_group) / Volume->InodesPerBlock); -} - -ULONG Ext2GetInodeOffsetInBlock(PEXT2_VOLUME_INFO Volume, ULONG Inode) -{ - return (((Inode - 1) % Volume->SuperBlock->inodes_per_group) % Volume->InodesPerBlock); -} - -BOOLEAN Ext2ReadInode(PEXT2_VOLUME_INFO Volume, ULONG Inode, PEXT2_INODE InodeBuffer) -{ - ULONG InodeGroupNumber; - ULONG InodeBlockNumber; - ULONG InodeOffsetInBlock; - CHAR ErrorString[80]; - EXT2_GROUP_DESC GroupDescriptor; - - TRACE("Ext2ReadInode() Inode = %d\n", Inode); - - // Make sure its a valid inode - if ((Inode < 1) || (Inode > Volume->SuperBlock->total_inodes)) - { - sprintf(ErrorString, "Error reading inode %ld - inode out of range.", Inode); - FileSystemError(ErrorString); - return FALSE; - } - - // Get inode group & block number and offset in block - InodeGroupNumber = Ext2GetInodeGroupNumber(Volume, Inode); - InodeBlockNumber = Ext2GetInodeBlockNumber(Volume, Inode); - InodeOffsetInBlock = Ext2GetInodeOffsetInBlock(Volume, Inode); - TRACE("InodeGroupNumber = %d\n", InodeGroupNumber); - TRACE("InodeBlockNumber = %d\n", InodeBlockNumber); - TRACE("InodeOffsetInBlock = %d\n", InodeOffsetInBlock); - - // Read the group descriptor - if (!Ext2ReadGroupDescriptor(Volume, InodeGroupNumber, &GroupDescriptor)) - { - return FALSE; - } - - // Add the start block of the inode table to the inode block number - InodeBlockNumber += GroupDescriptor.inode_table_id; - TRACE("InodeBlockNumber (after group desc correction) = %d\n", InodeBlockNumber); - - // Read the block - if (!Ext2ReadPartialBlock(Volume, - InodeBlockNumber, - (InodeOffsetInBlock * EXT2_INODE_SIZE(Volume->SuperBlock)), - sizeof(EXT2_INODE), - InodeBuffer)) - { - return FALSE; - } - - TRACE("Dumping inode information:\n"); - TRACE("mode = 0x%x\n", InodeBuffer->mode); - TRACE("uid = %d\n", InodeBuffer->uid); - TRACE("size = %d\n", InodeBuffer->size); - TRACE("atime = %d\n", InodeBuffer->atime); - TRACE("ctime = %d\n", InodeBuffer->ctime); - TRACE("mtime = %d\n", InodeBuffer->mtime); - TRACE("dtime = %d\n", InodeBuffer->dtime); - TRACE("gid = %d\n", InodeBuffer->gid); - TRACE("nlinks = %d\n", InodeBuffer->nlinks); - TRACE("blockcnt = %d\n", InodeBuffer->blockcnt); - TRACE("flags = 0x%x\n", InodeBuffer->flags); - TRACE("osd1 = 0x%x\n", InodeBuffer->osd1); - TRACE("dir_blocks = { %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u }\n", - InodeBuffer->blocks.dir_blocks[0], InodeBuffer->blocks.dir_blocks[1], InodeBuffer->blocks.dir_blocks[ 2], InodeBuffer->blocks.dir_blocks[ 3], - InodeBuffer->blocks.dir_blocks[4], InodeBuffer->blocks.dir_blocks[5], InodeBuffer->blocks.dir_blocks[ 6], InodeBuffer->blocks.dir_blocks[ 7], - InodeBuffer->blocks.dir_blocks[8], InodeBuffer->blocks.dir_blocks[9], InodeBuffer->blocks.dir_blocks[10], InodeBuffer->blocks.dir_blocks[11]); - TRACE("indir_block = %u\n", InodeBuffer->blocks.indir_block); - TRACE("double_indir_block = %u\n", InodeBuffer->blocks.double_indir_block); - TRACE("tripple_indir_block = %u\n", InodeBuffer->blocks.tripple_indir_block); - TRACE("version = %d\n", InodeBuffer->version); - TRACE("acl = %d\n", InodeBuffer->acl); - TRACE("dir_acl = %d\n", InodeBuffer->dir_acl); - TRACE("fragment_addr = %d\n", InodeBuffer->fragment_addr); - TRACE("osd2 = { %d, %d, %d }\n", - InodeBuffer->osd2[0], InodeBuffer->osd2[1], InodeBuffer->osd2[2]); - - return TRUE; -} - -BOOLEAN Ext2ReadGroupDescriptor(PEXT2_VOLUME_INFO Volume, ULONG Group, PEXT2_GROUP_DESC GroupBuffer) -{ - TRACE("Ext2ReadGroupDescriptor()\n"); - -#if 0 - if (!Ext2ReadBlock(Volume, Ext2GetGroupDescBlockNumber(Volume, Group), (PVOID)FILESYSBUFFER)) - { - return FALSE; - } - RtlCopyMemory(GroupBuffer, (PVOID)(FILESYSBUFFER + Ext2GetGroupDescOffsetInBlock(Volume, Group)), sizeof(EXT2_GROUP_DESC)); -#endif - - RtlCopyMemory(GroupBuffer, &Volume->GroupDescriptors[Group], sizeof(EXT2_GROUP_DESC)); - - TRACE("Dumping group descriptor:\n"); - TRACE("block_id = %d\n", GroupBuffer->block_id); - TRACE("inode_id = %d\n", GroupBuffer->inode_id); - TRACE("inode_table_id = %d\n", GroupBuffer->inode_table_id); - TRACE("free_blocks = %d\n", GroupBuffer->free_blocks); - TRACE("free_inodes = %d\n", GroupBuffer->free_inodes); - TRACE("used_dirs = %d\n", GroupBuffer->used_dirs); - - return TRUE; -} - -ULONG* Ext2ReadBlockPointerList(PEXT2_VOLUME_INFO Volume, PEXT2_INODE Inode) -{ - ULONGLONG FileSize; - ULONG BlockCount; - ULONG* BlockList; - ULONG CurrentBlockInList; - ULONG CurrentBlock; - - TRACE("Ext2ReadBlockPointerList()\n"); - - // Get the number of blocks this file occupies - // I would just use Inode->i_blocks but it - // doesn't seem to be the number of blocks - // the file size corresponds to, but instead - // it is much bigger. - //BlockCount = Inode->i_blocks; - FileSize = Ext2GetInodeFileSize(Inode); - FileSize = ROUND_UP(FileSize, Volume->BlockSizeInBytes); - BlockCount = (ULONG)(FileSize / Volume->BlockSizeInBytes); - - // Allocate the memory for the block list - BlockList = FrLdrTempAlloc(BlockCount * sizeof(ULONG), TAG_EXT_BLOCK_LIST); - if (BlockList == NULL) - { - return NULL; - } - - RtlZeroMemory(BlockList, BlockCount * sizeof(ULONG)); - - // Copy the direct block pointers - for (CurrentBlockInList = CurrentBlock = 0; - CurrentBlockInList < BlockCount && CurrentBlock < INDIRECT_BLOCKS; - CurrentBlock++, CurrentBlockInList++) - { - BlockList[CurrentBlockInList] = Inode->blocks.dir_blocks[CurrentBlock]; - } - - // Copy the indirect block pointers - if (CurrentBlockInList < BlockCount) - { - if (!Ext2CopyIndirectBlockPointers(Volume, BlockList, &CurrentBlockInList, BlockCount, Inode->blocks.indir_block)) - { - FrLdrTempFree(BlockList, TAG_EXT_BLOCK_LIST); - return NULL; - } - } - - // Copy the double indirect block pointers - if (CurrentBlockInList < BlockCount) - { - if (!Ext2CopyDoubleIndirectBlockPointers(Volume, BlockList, &CurrentBlockInList, BlockCount, Inode->blocks.double_indir_block)) - { - FrLdrTempFree(BlockList, TAG_EXT_BLOCK_LIST); - return NULL; - } - } - - // Copy the triple indirect block pointers - if (CurrentBlockInList < BlockCount) - { - if (!Ext2CopyTripleIndirectBlockPointers(Volume, BlockList, &CurrentBlockInList, BlockCount, Inode->blocks.tripple_indir_block)) - { - FrLdrTempFree(BlockList, TAG_EXT_BLOCK_LIST); - return NULL; - } - } - - return BlockList; -} - -ULONGLONG Ext2GetInodeFileSize(PEXT2_INODE Inode) -{ - if ((Inode->mode & EXT2_S_IFMT) == EXT2_S_IFDIR) - { - return (ULONGLONG)(Inode->size); - } - else - { - return ((ULONGLONG)(Inode->size) | ((ULONGLONG)(Inode->dir_acl) << 32)); - } -} - -BOOLEAN Ext2CopyIndirectBlockPointers(PEXT2_VOLUME_INFO Volume, ULONG* BlockList, ULONG* CurrentBlockInList, ULONG BlockCount, ULONG IndirectBlock) -{ - ULONG* BlockBuffer; - ULONG CurrentBlock; - ULONG BlockPointersPerBlock; - - TRACE("Ext2CopyIndirectBlockPointers() BlockCount = %d\n", BlockCount); - - BlockPointersPerBlock = Volume->BlockSizeInBytes / sizeof(ULONG); - - BlockBuffer = FrLdrTempAlloc(Volume->BlockSizeInBytes, TAG_EXT_BUFFER); - if (!BlockBuffer) - { - return FALSE; - } - - if (!Ext2ReadBlock(Volume, IndirectBlock, BlockBuffer)) - { - return FALSE; - } - - for (CurrentBlock=0; (*CurrentBlockInList)BlockSizeInBytes / sizeof(ULONG); - - BlockBuffer = (ULONG*)FrLdrTempAlloc(Volume->BlockSizeInBytes, TAG_EXT_BUFFER); - if (BlockBuffer == NULL) - { - return FALSE; - } - - if (!Ext2ReadBlock(Volume, DoubleIndirectBlock, BlockBuffer)) - { - FrLdrTempFree(BlockBuffer, TAG_EXT_BUFFER); - return FALSE; - } - - for (CurrentBlock=0; (*CurrentBlockInList)BlockSizeInBytes / sizeof(ULONG); - - BlockBuffer = (ULONG*)FrLdrTempAlloc(Volume->BlockSizeInBytes, TAG_EXT_BUFFER); - if (BlockBuffer == NULL) - { - return FALSE; - } - - if (!Ext2ReadBlock(Volume, TripleIndirectBlock, BlockBuffer)) - { - FrLdrTempFree(BlockBuffer, TAG_EXT_BUFFER); - return FALSE; - } - - for (CurrentBlock=0; (*CurrentBlockInList)EndingAddress.QuadPart = FileHandle->FileSize; - Information->CurrentAddress.QuadPart = FileHandle->FilePointer; - - TRACE("Ext2GetFileInformation(%lu) -> FileSize = %llu, FilePointer = 0x%llx\n", - FileId, Information->EndingAddress.QuadPart, Information->CurrentAddress.QuadPart); - - return ESUCCESS; -} - -ARC_STATUS Ext2Open(CHAR* Path, OPENMODE OpenMode, ULONG* FileId) -{ - PEXT2_VOLUME_INFO Volume; - PEXT2_FILE_INFO FileHandle; - ULONG DeviceId; - - /* Check parameters */ - if (OpenMode != OpenReadOnly) - return EACCES; - - /* Get underlying device */ - DeviceId = FsGetDeviceId(*FileId); - Volume = Ext2Volumes[DeviceId]; - - TRACE("Ext2Open() FileName = %s\n", Path); - - /* Call the internal open method */ - // Status = Ext2OpenFile(Volume, Path, &FileHandle); - FileHandle = Ext2OpenFile(Volume, Path); - if (!FileHandle) - return ENOENT; - - /* Success, remember the handle */ - FsSetDeviceSpecific(*FileId, FileHandle); - return ESUCCESS; -} - -ARC_STATUS Ext2Read(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count) -{ - PEXT2_FILE_INFO FileHandle = FsGetDeviceSpecific(FileId); - ULONGLONG BytesReadBig; - BOOLEAN Success; - - // - // Read data - // - Success = Ext2ReadFileBig(FileHandle, N, &BytesReadBig, Buffer); - *Count = (ULONG)BytesReadBig; - - // - // Check for success - // - if (Success) - return ESUCCESS; - else - return EIO; -} - -ARC_STATUS Ext2Seek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekMode) -{ - PEXT2_FILE_INFO FileHandle = FsGetDeviceSpecific(FileId); - LARGE_INTEGER NewPosition = *Position; - - switch (SeekMode) - { - case SeekAbsolute: - break; - case SeekRelative: - NewPosition.QuadPart += FileHandle->FilePointer; - break; - default: - ASSERT(FALSE); - return EINVAL; - } - - if (NewPosition.QuadPart >= FileHandle->FileSize) - return EINVAL; - - FileHandle->FilePointer = NewPosition.QuadPart; - return ESUCCESS; -} - -const DEVVTBL Ext2FuncTable = -{ - Ext2Close, - Ext2GetFileInformation, - Ext2Open, - Ext2Read, - Ext2Seek, - L"ext2fs", -}; - -const DEVVTBL* Ext2Mount(ULONG DeviceId) -{ - PEXT2_VOLUME_INFO Volume; - EXT2_SUPER_BLOCK SuperBlock; - LARGE_INTEGER Position; - ULONG Count; - ARC_STATUS Status; - - TRACE("Enter Ext2Mount(%lu)\n", DeviceId); - - /* Allocate data for volume information */ - Volume = FrLdrTempAlloc(sizeof(EXT2_VOLUME_INFO), TAG_EXT_VOLUME); - if (!Volume) - return NULL; - RtlZeroMemory(Volume, sizeof(EXT2_VOLUME_INFO)); - - /* Read the SuperBlock */ - Position.QuadPart = 2 * 512; - Status = ArcSeek(DeviceId, &Position, SeekAbsolute); - if (Status != ESUCCESS) - { - FrLdrTempFree(Volume, TAG_EXT_VOLUME); - return NULL; - } - Status = ArcRead(DeviceId, &SuperBlock, sizeof(SuperBlock), &Count); - if (Status != ESUCCESS || Count != sizeof(SuperBlock)) - { - FrLdrTempFree(Volume, TAG_EXT_VOLUME); - return NULL; - } - - /* Check if SuperBlock is valid. If yes, return Ext2 function table. */ - if (SuperBlock.magic != EXT2_MAGIC) - { - FrLdrTempFree(Volume, TAG_EXT_VOLUME); - return NULL; - } - - Volume->DeviceId = DeviceId; - - /* Really open the volume */ - if (!Ext2OpenVolume(Volume)) - { - FrLdrTempFree(Volume, TAG_EXT_VOLUME); - return NULL; - } - - /* Remember EXT2 volume information */ - Ext2Volumes[DeviceId] = Volume; - - /* Return success */ - TRACE("Ext2Mount(%lu) success\n", DeviceId); - return &Ext2FuncTable; -} - -#endif diff --git a/boot/freeldr/freeldr/lib/fs/fs.c b/boot/freeldr/freeldr/lib/fs/fs.c index cefdad7249fdb..fe640f69a55f5 100644 --- a/boot/freeldr/freeldr/lib/fs/fs.c +++ b/boot/freeldr/freeldr/lib/fs/fs.c @@ -65,7 +65,7 @@ PFS_MOUNT FileSystems[] = BtrFsMount, #ifndef _M_ARM NtfsMount, - Ext2Mount, + ExtMount, #endif #if defined(_M_IX86) || defined(_M_AMD64) #ifndef UEFIBOOT diff --git a/boot/freeldr/freeldr/lib/fs/iso.c b/boot/freeldr/freeldr/lib/fs/iso.c index a8314b1ac8adc..55ea802ebd2bb 100644 --- a/boot/freeldr/freeldr/lib/fs/iso.c +++ b/boot/freeldr/freeldr/lib/fs/iso.c @@ -25,9 +25,42 @@ DBG_DEFAULT_CHANNEL(FILESYSTEM); #define SECTORSIZE 2048 +#define TAG_ISO_VOLUME 'VosI' #define TAG_ISO_BUFFER 'BosI' #define TAG_ISO_FILE 'FosI' +typedef struct _ISO_VOLUME_INFO +{ + ULONG PvdDirectorySector; + ULONG PvdDirectoryLength; + ULONG DirectoryPathLength; + ULONG DirectoryLength; + PVOID DirectoryBuffer; + UCHAR DirectoryPath[261]; +} ISO_VOLUME_INFO, *PISO_VOLUME_INFO; + +static PISO_VOLUME_INFO IsoVolumes[MAX_FDS]; + +static +PCSTR +IsoLastPathSeparator( + _In_ PCSTR Path) +{ + PCSTR Last = NULL; + + ASSERT(Path != NULL); + + while (*Path != ANSI_NULL) + { + if (*Path == '\\' || *Path == '/') + Last = Path; + + ++Path; + } + + return Last; +} + static BOOLEAN IsoSearchDirectoryBufferForFile(PVOID DirectoryBuffer, ULONG DirectoryLength, PCHAR FileName, PISO_FILE_INFO IsoFileInfoPointer) { PDIR_RECORD Record; @@ -37,8 +70,6 @@ static BOOLEAN IsoSearchDirectoryBufferForFile(PVOID DirectoryBuffer, ULONG Dire TRACE("IsoSearchDirectoryBufferForFile() DirectoryBuffer = 0x%x DirectoryLength = %d FileName = %s\n", DirectoryBuffer, DirectoryLength, FileName); - RtlZeroMemory(Name, 32 * sizeof(UCHAR)); - Offset = 0; Record = (PDIR_RECORD)DirectoryBuffer; while (TRUE) @@ -67,7 +98,7 @@ static BOOLEAN IsoSearchDirectoryBufferForFile(PVOID DirectoryBuffer, ULONG Dire { for (i = 0; i < Record->FileIdLength && Record->FileId[i] != ';'; i++) Name[i] = Record->FileId[i]; - Name[i] = 0; + Name[i] = ANSI_NULL; TRACE("Name '%s'\n", Name); if (strlen(FileName) == strlen(Name) && _stricmp(FileName, Name) == 0) @@ -81,8 +112,6 @@ static BOOLEAN IsoSearchDirectoryBufferForFile(PVOID DirectoryBuffer, ULONG Dire } } - - RtlZeroMemory(Name, 32 * sizeof(UCHAR)); } return FALSE; @@ -140,109 +169,139 @@ static ARC_STATUS IsoBufferDirectory(ULONG DeviceId, ULONG DirectoryStartSector, return ESUCCESS; } - /* * IsoLookupFile() * This function searches the file system for the * specified filename and fills in an ISO_FILE_INFO structure * with info describing the file, etc. returns ARC error code */ -static ARC_STATUS IsoLookupFile(PCSTR FileName, ULONG DeviceId, PISO_FILE_INFO IsoFileInfoPointer) +static ARC_STATUS IsoLookupFile(PCSTR FileName, ULONG DeviceId, PISO_FILE_INFO IsoFileInfo) { - UCHAR Buffer[SECTORSIZE]; - PPVD Pvd = (PPVD)Buffer; - UINT32 i; - ULONG NumberOfPathParts; - CHAR PathPart[261]; - PVOID DirectoryBuffer; - ULONG DirectorySector; - ULONG DirectoryLength; - ISO_FILE_INFO IsoFileInfo; - LARGE_INTEGER Position; - ULONG Count; + PCSTR FullPath = FileName; + PISO_VOLUME_INFO Volume; + PCSTR FileNameStr; + ULONG i, DirectoryPathLength, DirectorySector, DirectoryLength; + PVOID DirectoryBuffer; + ULONG NumberOfPathParts; + CHAR PathBuffer[261]; + CHAR* PathPart; ARC_STATUS Status; + BOOLEAN DoFullLookup; TRACE("IsoLookupFile() FileName = %s\n", FileName); - RtlZeroMemory(IsoFileInfoPointer, sizeof(ISO_FILE_INFO)); - RtlZeroMemory(&IsoFileInfo, sizeof(ISO_FILE_INFO)); + Volume = IsoVolumes[DeviceId]; - // - // Read the Primary Volume Descriptor - // - Position.HighPart = 0; - Position.LowPart = 16 * SECTORSIZE; - Status = ArcSeek(DeviceId, &Position, SeekAbsolute); - if (Status != ESUCCESS) - return Status; - Status = ArcRead(DeviceId, Pvd, SECTORSIZE, &Count); - if (Status != ESUCCESS || Count < sizeof(PVD)) - return EIO; + /* + * Extract the file name + * '\test.ini' --> 'test.ini' + * '\folder\app.exe' --> 'app.exe' + */ + FileNameStr = IsoLastPathSeparator(FileName) + 1; - DirectorySector = Pvd->RootDirRecord.ExtentLocationL; - DirectoryLength = Pvd->RootDirRecord.DataLengthL; + /* + * Extract the directory path, including trailing slash + * '\test.ini' --> '\' + * '\folder\app.exe' --> '\folder\' + */ + DirectoryPathLength = FileNameStr - FileName; - /* Skip leading path separator, if any */ - if (*FileName == '\\' || *FileName == '/') - ++FileName; - // - // Figure out how many sub-directories we are nested in - // - NumberOfPathParts = FsGetNumPathParts(FileName); + /* See if this directory has been buffered before */ + DoFullLookup = (DirectoryPathLength != Volume->DirectoryPathLength) || + !RtlEqualMemory(FileName, Volume->DirectoryPath, DirectoryPathLength); + if (!DoFullLookup) + { + PathPart = (CHAR*)FileNameStr; + DirectoryBuffer = Volume->DirectoryBuffer; + DirectoryLength = Volume->DirectoryLength; + + NumberOfPathParts = 1; + } + else + { + PathPart = PathBuffer; + DirectorySector = Volume->PvdDirectorySector; + DirectoryLength = Volume->PvdDirectoryLength; + + /* Skip leading path separator, if any */ + if (*FileName == '\\' || *FileName == '/') + ++FileName; + + /* Figure out how many sub-directories we are nested in */ + NumberOfPathParts = FsGetNumPathParts(FileName); + } // // Loop once for each part // for (i=0; i= NumberOfPathParts) + { + if (Volume->DirectoryBuffer) + FrLdrTempFree(Volume->DirectoryBuffer, TAG_ISO_BUFFER); - // - // Search for file name in directory - // - if (!IsoSearchDirectoryBufferForFile(DirectoryBuffer, DirectoryLength, PathPart, &IsoFileInfo)) + Volume->DirectoryPathLength = DirectoryPathLength; + Volume->DirectoryBuffer = DirectoryBuffer; + Volume->DirectoryLength = DirectoryLength; + + RtlCopyMemory(Volume->DirectoryPath, FullPath, DirectoryPathLength); + } + } + + /* Search for file name in directory */ + if (!IsoSearchDirectoryBufferForFile(DirectoryBuffer, + DirectoryLength, + PathPart, + IsoFileInfo)) { - FrLdrTempFree(DirectoryBuffer, TAG_ISO_BUFFER); + /* Free the directory buffer that wasn't cached */ + if ((i + 1) < NumberOfPathParts) + { + ASSERT(DirectoryBuffer != Volume->DirectoryBuffer); + FrLdrTempFree(DirectoryBuffer, TAG_ISO_BUFFER); + } return ENOENT; } - FrLdrTempFree(DirectoryBuffer, TAG_ISO_BUFFER); - // // If we have another sub-directory to go then // grab the start sector and file size // if ((i+1) < NumberOfPathParts) { - DirectorySector = IsoFileInfo.FileStart; - DirectoryLength = IsoFileInfo.FileSize; - } + FrLdrTempFree(DirectoryBuffer, TAG_ISO_BUFFER); + DirectorySector = IsoFileInfo->FileStart; + DirectoryLength = IsoFileInfo->FileSize; + } } - RtlCopyMemory(IsoFileInfoPointer, &IsoFileInfo, sizeof(ISO_FILE_INFO)); - return ESUCCESS; } +static ARC_STATUS IsoClose(ULONG FileId) { PISO_FILE_INFO FileHandle = FsGetDeviceSpecific(FileId); @@ -250,6 +309,7 @@ ARC_STATUS IsoClose(ULONG FileId) return ESUCCESS; } +static ARC_STATUS IsoGetFileInformation(ULONG FileId, FILEINFORMATION* Information) { PISO_FILE_INFO FileHandle = FsGetDeviceSpecific(FileId); @@ -264,9 +324,9 @@ ARC_STATUS IsoGetFileInformation(ULONG FileId, FILEINFORMATION* Information) return ESUCCESS; } +static ARC_STATUS IsoOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId) { - ISO_FILE_INFO TempFileInfo; PISO_FILE_INFO FileHandle; ULONG DeviceId; ARC_STATUS Status; @@ -278,21 +338,22 @@ ARC_STATUS IsoOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId) TRACE("IsoOpen() FileName = %s\n", Path); - RtlZeroMemory(&TempFileInfo, sizeof(TempFileInfo)); - Status = IsoLookupFile(Path, DeviceId, &TempFileInfo); - if (Status != ESUCCESS) - return ENOENT; - - FileHandle = FrLdrTempAlloc(sizeof(ISO_FILE_INFO), TAG_ISO_FILE); + FileHandle = FrLdrTempAlloc(sizeof(*FileHandle), TAG_ISO_FILE); if (!FileHandle) return ENOMEM; - RtlCopyMemory(FileHandle, &TempFileInfo, sizeof(ISO_FILE_INFO)); + Status = IsoLookupFile(Path, DeviceId, FileHandle); + if (Status != ESUCCESS) + { + FrLdrTempFree(FileHandle, TAG_ISO_FILE); + return ENOENT; + } FsSetDeviceSpecific(*FileId, FileHandle); return ESUCCESS; } +static ARC_STATUS IsoRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count) { ARC_STATUS Status; @@ -459,6 +520,7 @@ ARC_STATUS IsoRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count) return ESUCCESS; } +static ARC_STATUS IsoSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekMode) { PISO_FILE_INFO FileHandle = FsGetDeviceSpecific(FileId); @@ -485,7 +547,7 @@ ARC_STATUS IsoSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekMode) return ESUCCESS; } -const DEVVTBL Iso9660FuncTable = +static const DEVVTBL Iso9660FuncTable = { IsoClose, IsoGetFileInformation, @@ -502,6 +564,7 @@ const DEVVTBL* IsoMount(ULONG DeviceId) LARGE_INTEGER Position; ULONG Count; ARC_STATUS Status; + PISO_VOLUME_INFO Volume; TRACE("Enter IsoMount(%lu)\n", DeviceId); @@ -533,6 +596,17 @@ const DEVVTBL* IsoMount(ULONG DeviceId) TRACE("Recognized ISO9660 drive, size %lu MB (%lu sectors)\n", Count, Pvd->VolumeSpaceSizeL); + Volume = FrLdrTempAlloc(sizeof(*Volume), TAG_ISO_VOLUME); + if (!Volume) + return NULL; + RtlZeroMemory(Volume, sizeof(*Volume)); + + /* Cache the PVD information */ + Volume->PvdDirectorySector = Pvd->RootDirRecord.ExtentLocationL; + Volume->PvdDirectoryLength = Pvd->RootDirRecord.DataLengthL; + + IsoVolumes[DeviceId] = Volume; + /* Everything OK, return the ISO9660 function table */ return &Iso9660FuncTable; } diff --git a/boot/freeldr/freeldr/lib/fs/pxe.c b/boot/freeldr/freeldr/lib/fs/pxe.c index 1a1866ed05803..93e2de75abf04 100644 --- a/boot/freeldr/freeldr/lib/fs/pxe.c +++ b/boot/freeldr/freeldr/lib/fs/pxe.c @@ -94,7 +94,7 @@ BOOLEAN CallPxe(UINT16 Service, PVOID Parameter) if (Service != PXENV_TFTP_READ) { // HACK: this delay shouldn't be necessary - KeStallExecutionProcessor(100 * 1000); // 100 ms + StallExecutionProcessor(100 * 1000); // 100 ms TRACE("PxeCall(0x%x, %p)\n", Service, Parameter); } diff --git a/boot/freeldr/freeldr/lib/inifile/ini_init.c b/boot/freeldr/freeldr/lib/inifile/ini_init.c index 9992b0b715129..4596eac759fbd 100644 --- a/boot/freeldr/freeldr/lib/inifile/ini_init.c +++ b/boot/freeldr/freeldr/lib/inifile/ini_init.c @@ -38,8 +38,15 @@ BOOLEAN IniFileInitialize(VOID) if (Status != ESUCCESS) { ERR("Error while opening freeldr.ini, Status: %d\n", Status); - UiMessageBoxCritical("Error opening freeldr.ini or file not found.\nYou need to re-install FreeLoader."); - return FALSE; + + /* Try to open boot.ini */ + Status = FsOpenFile("boot.ini", FrLdrBootPath, OpenReadOnly, &FileId); + if (Status != ESUCCESS) + { + ERR("Error while opening boot.ini, Status: %d\n", Status); + UiMessageBoxCritical("Error opening freeldr.ini/boot.ini or file not found.\nYou need to re-install FreeLoader."); + return FALSE; + } } /* Get the file size */ diff --git a/boot/freeldr/freeldr/lib/inifile/inifile.c b/boot/freeldr/freeldr/lib/inifile/inifile.c index a1bd7c9f91abf..64130c8a24d1f 100644 --- a/boot/freeldr/freeldr/lib/inifile/inifile.c +++ b/boot/freeldr/freeldr/lib/inifile/inifile.c @@ -22,6 +22,11 @@ #include DBG_DEFAULT_CHANNEL(INIFILE); +PLIST_ENTRY IniGetFileSectionListHead(VOID) +{ + return &IniFileSectionListHead; +} + BOOLEAN IniOpenSection(PCSTR SectionName, ULONG_PTR* SectionId) { PLIST_ENTRY Entry; diff --git a/boot/freeldr/freeldr/lib/mm/heap.c b/boot/freeldr/freeldr/lib/mm/heap.c index 35adcd3503921..66a8c6a8f23fe 100644 --- a/boot/freeldr/freeldr/lib/mm/heap.c +++ b/boot/freeldr/freeldr/lib/mm/heap.c @@ -31,8 +31,8 @@ DBG_DEFAULT_CHANNEL(HEAP); #define REDZONE_LOW(Block) ((ULONG64*)Block->Data + 1) #define REDZONE_HI(Block) ((ULONG64*)((PUCHAR)Block->Data + 16 + *REDZONE_SIZE(Block))) -PVOID FrLdrDefaultHeap; -PVOID FrLdrTempHeap; +static PVOID FrLdrDefaultHeap; +static PVOID FrLdrTempHeap; typedef struct _BLOCK_DATA { @@ -529,6 +529,32 @@ FrLdrHeapFreeEx( #endif } +PVOID +FrLdrHeapAlloc(SIZE_T MemorySize, ULONG Tag) +{ + return FrLdrHeapAllocateEx(FrLdrDefaultHeap, MemorySize, Tag); +} + +VOID +FrLdrHeapFree(PVOID MemoryPointer, ULONG Tag) +{ + FrLdrHeapFreeEx(FrLdrDefaultHeap, MemoryPointer, Tag); +} + +PVOID +FrLdrTempAlloc( + _In_ SIZE_T Size, + _In_ ULONG Tag) +{ + return FrLdrHeapAllocateEx(FrLdrTempHeap, Size, Tag); +} + +VOID +FrLdrTempFree( + PVOID Allocation, ULONG Tag) +{ + FrLdrHeapFreeEx(FrLdrTempHeap, Allocation, Tag); +} /* Wrapper functions *********************************************************/ diff --git a/boot/freeldr/freeldr/lib/mm/meminit.c b/boot/freeldr/freeldr/lib/mm/meminit.c index 953b6596330e2..b3b8ac3171e10 100644 --- a/boot/freeldr/freeldr/lib/mm/meminit.c +++ b/boot/freeldr/freeldr/lib/mm/meminit.c @@ -34,6 +34,19 @@ PFREELDR_MEMORY_DESCRIPTOR BiosMemoryMap; ULONG BiosMemoryMapEntryCount; SIZE_T FrLdrImageSize; +ULONG +MmGetBiosMemoryMap(_Out_ PFREELDR_MEMORY_DESCRIPTOR *MemoryMap) +{ + *MemoryMap = BiosMemoryMap; + return BiosMemoryMapEntryCount; +} + +PFN_NUMBER +MmGetTotalPagesInLookupTable(VOID) +{ + return TotalPagesInLookupTable; +} + #if DBG typedef struct { @@ -96,6 +109,14 @@ DbgDumpMemoryMap( } DbgPrint("\n"); } +#else +/* Dummy, so we can export it */ +PCSTR +MmGetSystemMemoryMapTypeString( + TYPE_OF_MEMORY Type) +{ + return "-"; +} #endif ULONG @@ -702,3 +723,9 @@ BOOLEAN MmAreMemoryPagesAvailable(PVOID PageLookupTable, PFN_NUMBER TotalPageCou return TRUE; } + +PFN_NUMBER +MmGetHighestPhysicalPage(VOID) +{ + return MmHighestPhysicalPage; +} diff --git a/boot/freeldr/freeldr/lib/mm/mm.c b/boot/freeldr/freeldr/lib/mm/mm.c index 7153c70f62f80..92967231d55af 100644 --- a/boot/freeldr/freeldr/lib/mm/mm.c +++ b/boot/freeldr/freeldr/lib/mm/mm.c @@ -303,3 +303,8 @@ PPAGE_LOOKUP_TABLE_ITEM MmGetMemoryMap(PFN_NUMBER *NoEntries) return RealPageLookupTable; } +PFN_NUMBER +MmGetLoaderPagesSpanned(VOID) +{ + return LoaderPagesSpanned; +} diff --git a/boot/freeldr/freeldr/lib/peloader.c b/boot/freeldr/freeldr/lib/peloader.c index 06bcf41720b8c..5015704a5213e 100644 --- a/boot/freeldr/freeldr/lib/peloader.c +++ b/boot/freeldr/freeldr/lib/peloader.c @@ -13,7 +13,7 @@ * (creating a native EFI loader for Windows). * * This article was very handy during development: - * http://msdn.microsoft.com/msdnmag/issues/02/03/PE2/ + * https://web.archive.org/web/20131202091645/http://msdn.microsoft.com/en-us/magazine/cc301808.aspx */ /* INCLUDES ******************************************************************/ @@ -74,11 +74,11 @@ PeLdrpFetchAddressOfSecurityCookie(PVOID BaseAddress, ULONG SizeOfImage) return Cookie; } -/* DllName - physical, UnicodeString->Buffer - virtual */ +/* DllName: physical, UnicodeString->Buffer: virtual */ static BOOLEAN PeLdrpCompareDllName( - IN PCH DllName, - IN PUNICODE_STRING UnicodeName) + _In_ PCSTR DllName, + _In_ PCUNICODE_STRING UnicodeName) { PWSTR Buffer; SIZE_T i, Length; @@ -92,8 +92,8 @@ PeLdrpCompareDllName( UnicodeNamePA.Length = UnicodeName->Length; UnicodeNamePA.MaximumLength = UnicodeName->MaximumLength; UnicodeNamePA.Buffer = VaToPa(UnicodeName->Buffer); - TRACE("PeLdrpCompareDllName: %s and %wZ, Length = %d " - "UN->Length %d\n", DllName, &UnicodeNamePA, Length, UnicodeName->Length); + TRACE("PeLdrpCompareDllName: %s and %wZ, Length = %d, UN->Length %d\n", + DllName, &UnicodeNamePA, Length, UnicodeName->Length); } #endif @@ -122,7 +122,7 @@ PeLdrpCompareDllName( return TRUE; } - /* Strings don't match, return FALSE */ + /* Strings don't match */ return FALSE; } @@ -528,10 +528,9 @@ PeLdrInitializeModuleList(VOID) InitializeListHead(&FrLdrModuleList); - /* Allocate a data table entry for freeldr.sys. - The base name is scsiport.sys for imports from ntbootdd.sys */ + /* Allocate a data table entry for freeldr.sys */ if (!PeLdrAllocateDataTableEntry(&FrLdrModuleList, - "scsiport.sys", + "freeldr.sys", "freeldr.sys", &__ImageBase, &FreeldrDTE)) @@ -582,27 +581,28 @@ PeLdrInitSecurityCookie(PLDR_DATA_TABLE_ENTRY LdrEntry) return Cookie; } -/* Returns TRUE if DLL has already been loaded - looks in LoadOrderList in LPB */ +/* Returns TRUE if the DLL has already been loaded in the module list */ BOOLEAN PeLdrCheckForLoadedDll( - IN OUT PLIST_ENTRY ModuleListHead, - IN PCH DllName, - OUT PLDR_DATA_TABLE_ENTRY *LoadedEntry) + _Inout_ PLIST_ENTRY ModuleListHead, + _In_ PCSTR DllName, + _Out_ PLDR_DATA_TABLE_ENTRY* LoadedEntry) { + PLIST_ENTRY ModuleEntry; PLDR_DATA_TABLE_ENTRY DataTableEntry; - LIST_ENTRY *ModuleEntry; TRACE("PeLdrCheckForLoadedDll: DllName %s\n", DllName); - /* Just go through each entry in the LoadOrderList and compare loaded module's - name with a given name */ - ModuleEntry = ModuleListHead->Flink; - while (ModuleEntry != ModuleListHead) + /* Go through each entry in the LoadOrderList and + * compare the module's name with the given name */ + for (ModuleEntry = ModuleListHead->Flink; + ModuleEntry != ModuleListHead; + ModuleEntry = ModuleEntry->Flink) { - /* Get pointer to the current DTE */ + /* Get a pointer to the current DTE */ DataTableEntry = CONTAINING_RECORD(ModuleEntry, - LDR_DATA_TABLE_ENTRY, - InLoadOrderLinks); + LDR_DATA_TABLE_ENTRY, + InLoadOrderLinks); TRACE("PeLdrCheckForLoadedDll: DTE %p, EP %p, Base %p, Name '%.*S'\n", DataTableEntry, DataTableEntry->EntryPoint, DataTableEntry->DllBase, @@ -612,16 +612,13 @@ PeLdrCheckForLoadedDll( /* Compare names */ if (PeLdrpCompareDllName(DllName, &DataTableEntry->BaseDllName)) { - /* Yes, found it, report pointer to the loaded module's DTE - to the caller and increase load count for it */ + /* Found it, return a pointer to the loaded module's + * DTE to the caller and increase its load count */ *LoadedEntry = DataTableEntry; DataTableEntry->LoadCount++; TRACE("PeLdrCheckForLoadedDll: LoadedEntry 0x%p\n", DataTableEntry); return TRUE; } - - /* Go to the next entry */ - ModuleEntry = ModuleEntry->Flink; } /* Nothing found */ diff --git a/boot/freeldr/freeldr/lib/rtl/libsupp.c b/boot/freeldr/freeldr/lib/rtl/libsupp.c index 585164d03f3b8..8ab6d9e007507 100644 --- a/boot/freeldr/freeldr/lib/rtl/libsupp.c +++ b/boot/freeldr/freeldr/lib/rtl/libsupp.c @@ -35,7 +35,7 @@ NTAPI RtlpAllocateMemory(ULONG Bytes, ULONG Tag) { - return FrLdrHeapAllocateEx(FrLdrDefaultHeap, Bytes, Tag); + return FrLdrHeapAlloc(Bytes, Tag); } @@ -44,7 +44,7 @@ NTAPI RtlpFreeMemory(PVOID Mem, ULONG Tag) { - FrLdrHeapFreeEx(FrLdrDefaultHeap, Mem, Tag); + FrLdrHeapFree(Mem, Tag); } NTSTATUS diff --git a/boot/freeldr/freeldr/linuxboot.c b/boot/freeldr/freeldr/linuxboot.c index e7f81d699d854..3cd90237fc8b7 100644 --- a/boot/freeldr/freeldr/linuxboot.c +++ b/boot/freeldr/freeldr/linuxboot.c @@ -114,7 +114,7 @@ LoadAndBootLinux( else strcpy(LinuxBootDescription, "Loading Linux..."); - UiDrawBackdrop(); + UiDrawBackdrop(UiGetScreenHeight()); UiDrawStatusText(LinuxBootDescription); UiDrawProgressBarCenter(LinuxBootDescription); diff --git a/boot/freeldr/freeldr/miscboot.c b/boot/freeldr/freeldr/miscboot.c index 5243d8c9186ad..9d9c4bf8efb98 100644 --- a/boot/freeldr/freeldr/miscboot.c +++ b/boot/freeldr/freeldr/miscboot.c @@ -145,8 +145,8 @@ LoadAndBootSector( BiosDriveNumber = 0; if (!BiosDriveNumber) { - BiosDriveNumber = FrldrBootDrive; - PartitionNumber = FrldrBootPartition; + BiosDriveNumber = FrldrGetBootDrive(); + PartitionNumber = FrldrGetBootPartition(); } @@ -161,11 +161,7 @@ LoadAndBootSector( return Status; } -#if defined(SARCH_PC98) - LoadAddress = Pc98GetBootSectorLoadAddress(BiosDriveNumber); -#else - LoadAddress = 0x7C00; -#endif + LoadAddress = MachGetBootSectorLoadAddress(BiosDriveNumber); /* * Now try to load the boot sector: disk MBR (when PartitionNumber == 0), diff --git a/boot/freeldr/freeldr/ntldr/arch/i386/winldr.c b/boot/freeldr/freeldr/ntldr/arch/i386/winldr.c index 0999baf60d048..2a2054ff405ad 100644 --- a/boot/freeldr/freeldr/ntldr/arch/i386/winldr.c +++ b/boot/freeldr/freeldr/ntldr/arch/i386/winldr.c @@ -117,7 +117,7 @@ MempAllocatePageTables(VOID) // Max number of entries = MaxPageNum >> 10 // FIXME: This is a number to describe ALL physical memory // and windows doesn't expect ALL memory mapped... - NumPageTables = TotalPagesInLookupTable >> 10; + NumPageTables = MmGetTotalPagesInLookupTable() >> 10; TRACE("NumPageTables = %d\n", NumPageTables); diff --git a/boot/freeldr/freeldr/ntldr/registry.c b/boot/freeldr/freeldr/ntldr/registry.c index 73d6f68097eb1..0b81b71cf1619 100644 --- a/boot/freeldr/freeldr/ntldr/registry.c +++ b/boot/freeldr/freeldr/ntldr/registry.c @@ -99,14 +99,7 @@ RegInitializeHive( _In_ BOOLEAN LoadAlternate) { NTSTATUS Status; -/* - * FIXME: Disable compilation of some parts of code for AMD64 for now, - * since it makes the FreeLdr binary size so large that it prevents - * x64 ROS from booting. - */ -#if !defined(_M_AMD64) CM_CHECK_REGISTRY_STATUS CmStatusCode; -#endif /* Initialize the hive */ Status = HvInitialize(GET_HHIVE(CmHive), @@ -128,8 +121,6 @@ RegInitializeHive( return FALSE; } -/* FIXME: See the comment above */ -#if !defined(_M_AMD64) /* Now check the hive and purge volatile data */ CmStatusCode = CmCheckRegistry(CmHive, CM_CHECK_REGISTRY_BOOTLOADER_PURGE_VOLATILES | CM_CHECK_REGISTRY_VALIDATE_HIVE); if (!CM_CHECK_REGISTRY_SUCCESS(CmStatusCode)) @@ -137,13 +128,10 @@ RegInitializeHive( ERR("CmCheckRegistry detected problems with the loaded flat hive (check code %lu)\n", CmStatusCode); return FALSE; } -#endif return TRUE; } -/* FIXME: See the comment above */ -#if !defined(_M_AMD64) /** * @brief * Loads and reads a hive log at specified @@ -418,7 +406,6 @@ RegRecoverDataHive( HiveBaseBlock->CheckSum = HvpHiveHeaderChecksum(HiveBaseBlock); return TRUE; } -#endif /** * @brief @@ -464,14 +451,6 @@ RegImportBinaryHive( CmSystemHive = FrLdrTempAlloc(sizeof(CMHIVE), 'eviH'); Success = RegInitializeHive(CmSystemHive, ChunkBase, LoadAlternate); if (!Success) -/* FIXME: See the comment above */ -#if defined(_M_AMD64) - { - ERR("Corrupted hive %p!\n", ChunkBase); - FrLdrTempFree(CmSystemHive, 'eviH'); - return FALSE; - } -#else { /* Free the buffer and retry again */ FrLdrTempFree(CmSystemHive, 'eviH'); @@ -505,7 +484,6 @@ RegImportBinaryHive( */ ((PHBASE_BLOCK)ChunkBase)->BootRecover = HBOOT_BOOT_RECOVERED_BY_HIVE_LOG; } -#endif /* Save the root key node */ SystemHive = GET_HHIVE(CmSystemHive); diff --git a/boot/freeldr/freeldr/ntldr/setupldr.c b/boot/freeldr/freeldr/ntldr/setupldr.c index 576222378f744..57931fc841e9d 100644 --- a/boot/freeldr/freeldr/ntldr/setupldr.c +++ b/boot/freeldr/freeldr/ntldr/setupldr.c @@ -531,7 +531,7 @@ LoadReactOSSetup( } /* Let the user know we started loading */ - UiDrawBackdrop(); + UiDrawBackdrop(UiGetScreenHeight()); UiDrawStatusText("Setup is loading..."); UiDrawProgressBarCenter("Loading ReactOS Setup..."); diff --git a/boot/freeldr/freeldr/ntldr/winldr.c b/boot/freeldr/freeldr/ntldr/winldr.c index f3405b70ba3af..198c673d9622e 100644 --- a/boot/freeldr/freeldr/ntldr/winldr.c +++ b/boot/freeldr/freeldr/ntldr/winldr.c @@ -15,12 +15,10 @@ #include DBG_DEFAULT_CHANNEL(WINDOWS); -// FIXME: Find a better way to retrieve ARC disk information -extern ULONG reactos_disk_count; -extern ARC_DISK_SIGNATURE_EX reactos_arc_disk_info[]; +ULONG ArcGetDiskCount(VOID); +PARC_DISK_SIGNATURE_EX ArcGetDiskInfo(ULONG Index); -extern ULONG LoaderPagesSpanned; -extern BOOLEAN AcpiPresent; +BOOLEAN IsAcpiPresent(VOID); extern HEADLESS_LOADER_BLOCK LoaderRedirectionInformation; extern BOOLEAN WinLdrTerminalConnected; @@ -199,7 +197,8 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock, InitializeListHead(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead); /* Convert ARC disk information from freeldr to a correct format */ - for (i = 0; i < reactos_disk_count; i++) + ULONG DiscCount = ArcGetDiskCount(); + for (i = 0; i < DiscCount; i++) { PARC_DISK_SIGNATURE_EX ArcDiskSig; @@ -208,12 +207,12 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock, if (!ArcDiskSig) { ERR("Failed to allocate ARC structure! Ignoring remaining ARC disks. (i = %lu, DiskCount = %lu)\n", - i, reactos_disk_count); + i, DiscCount); break; } /* Copy the data over */ - RtlCopyMemory(ArcDiskSig, &reactos_arc_disk_info[i], sizeof(ARC_DISK_SIGNATURE_EX)); + RtlCopyMemory(ArcDiskSig, ArcGetDiskInfo(i), sizeof(ARC_DISK_SIGNATURE_EX)); /* Set the ARC Name pointer */ ArcDiskSig->DiskSignature.ArcName = PaToVa(ArcDiskSig->ArcName); @@ -248,7 +247,7 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock, Extension->Profile.Status = 2; /* Check if FreeLdr detected a ACPI table */ - if (AcpiPresent) + if (IsAcpiPresent()) { /* Set the pointer to something for compatibility */ Extension->AcpiTable = (PVOID)1; @@ -1031,7 +1030,7 @@ LoadAndBootWindows( } /* Let the user know we started loading */ - UiDrawBackdrop(); + UiDrawBackdrop(UiGetScreenHeight()); UiDrawStatusText("Loading..."); UiDrawProgressBarCenter("Loading NT..."); @@ -1265,7 +1264,7 @@ LoadAndBootWindowsCommon( WinLdrSetProcessorContext(OperatingSystemVersion); /* Save final value of LoaderPagesSpanned */ - LoaderBlock->Extension->LoaderPagesSpanned = LoaderPagesSpanned; + LoaderBlock->Extension->LoaderPagesSpanned = MmGetLoaderPagesSpanned(); TRACE("Hello from paged mode, KiSystemStartup %p, LoaderBlockVA %p!\n", KiSystemStartup, LoaderBlockVA); diff --git a/boot/freeldr/freeldr/ntldr/winldr.h b/boot/freeldr/freeldr/ntldr/winldr.h index b18c8f4f78a58..0d8ba5fc26440 100644 --- a/boot/freeldr/freeldr/ntldr/winldr.h +++ b/boot/freeldr/freeldr/ntldr/winldr.h @@ -79,23 +79,6 @@ extern BOOLEAN SosEnabled; extern BOOLEAN PaeModeOn; #endif -FORCEINLINE -VOID -UiResetForSOS(VOID) -{ -#ifdef _M_ARM - /* Re-initialize the UI */ - UiInitialize(TRUE); -#else - /* Reset the UI and switch to MiniTui */ - UiVtbl.UnInitialize(); - UiVtbl = MiniTuiVtbl; - UiVtbl.Initialize(); -#endif - /* Disable the progress bar */ - UiProgressBar.Show = FALSE; -} - VOID NtLdrOutputLoadMsg( _In_ PCSTR FileName, diff --git a/boot/freeldr/freeldr/ntldr/wlmemory.c b/boot/freeldr/freeldr/ntldr/wlmemory.c index f784e1b2ef59f..1be38e97864fc 100644 --- a/boot/freeldr/freeldr/ntldr/wlmemory.c +++ b/boot/freeldr/freeldr/ntldr/wlmemory.c @@ -14,8 +14,6 @@ #include DBG_DEFAULT_CHANNEL(WINDOWS); -extern ULONG LoaderPagesSpanned; - static const PCSTR MemTypeDesc[] = { "ExceptionBlock ", // ? "SystemBlock ", // ? @@ -47,11 +45,6 @@ static VOID WinLdrInsertDescriptor(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, IN PMEMORY_ALLOCATION_DESCRIPTOR NewDescriptor); -extern PFREELDR_MEMORY_DESCRIPTOR BiosMemoryMap; -extern ULONG BiosMemoryMapEntryCount; -extern PFN_NUMBER MmLowestPhysicalPage; -extern PFN_NUMBER MmHighestPhysicalPage; - /* GLOBALS ***************************************************************/ MEMORY_ALLOCATION_DESCRIPTOR *Mad; @@ -114,7 +107,7 @@ MempSetupPagingForRegion( BasePage, PageCount, Type); /* Make sure we don't map too high */ - if (BasePage + PageCount > LoaderPagesSpanned) return; + if (BasePage + PageCount > MmGetLoaderPagesSpanned()) return; switch (Type) { @@ -310,12 +303,16 @@ WinLdrSetupMemoryLayout(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock) MadCount++; } #endif + PFREELDR_MEMORY_DESCRIPTOR BiosMemoryMap; + ULONG BiosMemoryMapEntryCount; + + BiosMemoryMapEntryCount = MmGetBiosMemoryMap(&BiosMemoryMap); /* Now we need to add high descriptors from the bios memory map */ for (i = 0; i < BiosMemoryMapEntryCount; i++) { /* Check if its higher than the lookup table */ - if (BiosMemoryMap->BasePage > MmHighestPhysicalPage) + if (BiosMemoryMap->BasePage > MmGetHighestPhysicalPage()) { /* Copy this descriptor */ MempAddMemoryBlock(LoaderBlock, diff --git a/boot/freeldr/freeldr/options.c b/boot/freeldr/freeldr/options.c index ac302254bf52f..49ec66ed07d29 100644 --- a/boot/freeldr/freeldr/options.c +++ b/boot/freeldr/freeldr/options.c @@ -95,7 +95,6 @@ VOID DoOptionsMenu(IN OperatingSystemItem* OperatingSystem) CHAR DebugChannelString[100]; if (!UiDisplayMenu("Select an option:", NULL, - TRUE, OptionsMenuList, sizeof(OptionsMenuList) / sizeof(OptionsMenuList[0]), 11, // Use "Start ReactOS normally" as default; see the switch below. @@ -109,7 +108,7 @@ VOID DoOptionsMenu(IN OperatingSystemItem* OperatingSystem) } /* Clear the backdrop */ - UiDrawBackdrop(); + UiDrawBackdrop(UiGetScreenHeight()); switch (SelectedMenuItem) { @@ -180,31 +179,32 @@ VOID DoOptionsMenu(IN OperatingSystemItem* OperatingSystem) VOID DisplayBootTimeOptions(VOID) { - CHAR BootOptions[260] = ""; + CHAR BootOptions[260]; switch (BootOptionChoice) { case SAFE_MODE: - strcat(BootOptions, OptionsMenuList[0]); + strcpy(BootOptions, OptionsMenuList[0]); break; case SAFE_MODE_WITH_NETWORKING: - strcat(BootOptions, OptionsMenuList[1]); + strcpy(BootOptions, OptionsMenuList[1]); break; case SAFE_MODE_WITH_COMMAND_PROMPT: - strcat(BootOptions, OptionsMenuList[2]); + strcpy(BootOptions, OptionsMenuList[2]); break; case LAST_KNOWN_GOOD_CONFIGURATION: - strcat(BootOptions, OptionsMenuList[6]); + strcpy(BootOptions, OptionsMenuList[6]); break; case DIRECTORY_SERVICES_RESTORE_MODE: - strcat(BootOptions, OptionsMenuList[7]); + strcpy(BootOptions, OptionsMenuList[7]); break; default: + BootOptions[0] = ANSI_NULL; break; } @@ -214,39 +214,31 @@ VOID DisplayBootTimeOptions(VOID) (BootOptionChoice != SAFE_MODE_WITH_NETWORKING) && (BootOptionChoice != SAFE_MODE_WITH_COMMAND_PROMPT) ) { - if (BootOptionChoice != NO_OPTION) - { + if (BootOptions[0] != ANSI_NULL) strcat(BootOptions, ", "); - } strcat(BootOptions, OptionsMenuList[4]); } } if (VgaMode) { - if ((BootOptionChoice != NO_OPTION) || - BootLogging) - { + if (BootOptions[0] != ANSI_NULL) strcat(BootOptions, ", "); - } strcat(BootOptions, OptionsMenuList[5]); } if (DebuggingMode) { - if ((BootOptionChoice != NO_OPTION) || - BootLogging || VgaMode) - { + if (BootOptions[0] != ANSI_NULL) strcat(BootOptions, ", "); - } strcat(BootOptions, OptionsMenuList[8]); } /* Display the chosen boot options */ UiDrawText(0, - UiScreenHeight - 2, + UiGetScreenHeight() - 2, BootOptions, - ATTR(COLOR_LIGHTBLUE, UiMenuBgColor)); + ATTR(COLOR_LIGHTBLUE, UiGetMenuBgColor())); } VOID AppendBootTimeOptions(PCHAR BootOptions) diff --git a/boot/freeldr/freeldr/oslist.c b/boot/freeldr/freeldr/oslist.c index a472345aa8710..d38d7f8aa3350 100644 --- a/boot/freeldr/freeldr/oslist.c +++ b/boot/freeldr/freeldr/oslist.c @@ -75,7 +75,7 @@ InitOperatingSystemList( return NULL; /* Retrieve the default OS */ - DefaultOSName = BootMgrInfo.DefaultOs; + DefaultOSName = GetBootMgrInfo()->DefaultOs; /* Now loop through the operating system section and load each item */ for (i = 0; i < Count; ++i) diff --git a/boot/freeldr/freeldr/pcat.cmake b/boot/freeldr/freeldr/pcat.cmake index 020ae7e018af9..78121be46f820 100644 --- a/boot/freeldr/freeldr/pcat.cmake +++ b/boot/freeldr/freeldr/pcat.cmake @@ -22,7 +22,7 @@ elseif(ARCH STREQUAL "amd64") endif() -spec2def(freeldr_pe.exe freeldr.spec) +spec2def(freeldr.sys freeldr.spec ADD_IMPORTLIB) list(APPEND PCATLDR_ARC_SOURCE ${FREELDR_ARC_SOURCE} @@ -155,7 +155,7 @@ add_library(freeldr_common ${PCATLDR_ARC_SOURCE} ${FREELDR_BOOTLIB_SOURCE} ${PCATLDR_BOOTMGR_SOURCE} - ${FREELDR_NTLDR_SOURCE}) +) if(MSVC AND CMAKE_C_COMPILER_ID STREQUAL "Clang") # We need to reduce the binary size @@ -170,7 +170,7 @@ set(PCH_SOURCE ${PCATLDR_ARC_SOURCE} ${FREELDR_BOOTLIB_SOURCE} ${PCATLDR_BOOTMGR_SOURCE} - ${FREELDR_NTLDR_SOURCE}) +) add_pch(freeldr_common include/freeldr.h PCH_SOURCE) add_dependencies(freeldr_common bugcodes asm xdk) @@ -221,7 +221,7 @@ if(ARCH STREQUAL "i386") target_link_libraries(freeldr_pe mini_hal) endif() -target_link_libraries(freeldr_pe freeldr_common cportlib blcmlib blrtl libcntpr) +target_link_libraries(freeldr_pe freeldr_common cportlib libcntpr blrtl) # dynamic analysis switches if(STACK_PROTECTOR) diff --git a/boot/freeldr/freeldr/rosload.cmake b/boot/freeldr/freeldr/rosload.cmake new file mode 100644 index 0000000000000..6af8eccf3807b --- /dev/null +++ b/boot/freeldr/freeldr/rosload.cmake @@ -0,0 +1,105 @@ +## +## PROJECT: FreeLoader +## LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) +## PURPOSE: Build definitions for rosload 2nd stage loader +## COPYRIGHT: Copyright 2024 Timo Kreuzer +## + +spec2def(rosload.exe rosload.spec) + +list(APPEND ROSLOAD_SOURCE + include/freeldr.h + bootmgr.c + custom.c + linuxboot.c + miscboot.c + options.c + oslist.c + lib/rtl/libsupp.c + ${REACTOS_SOURCE_DIR}/ntoskrnl/config/cmboot.c + ntldr/conversion.c + ntldr/inffile.c + ntldr/registry.c + ntldr/setupldr.c + ntldr/winldr.c + ntldr/wlmemory.c + ntldr/wlregistry.c +) + +if(ARCH STREQUAL "i386") + + list(APPEND ROSLOAD_SOURCE + arch/i386/halstub.c + arch/i386/ntoskrnl.c + disk/scsiport.c + ntldr/arch/i386/winldr.c + ntldr/headless.c) + + if(SARCH STREQUAL "pc98" OR SARCH STREQUAL "xbox") + # These machine types require built-in bitmap font + list(APPEND ROSLOAD_SOURCE + arch/vgafont.c) + endif() + + list(APPEND ROSLOAD_ASM_SOURCE + arch/i386/drvmap.S + arch/i386/linux.S) + +elseif(ARCH STREQUAL "amd64") + + list(APPEND ROSLOAD_SOURCE + ntldr/arch/amd64/winldr.c) + + list(APPEND ROSLOAD_ASM_SOURCE + arch/amd64/misc.S + arch/amd64/linux.S + ) + +elseif(ARCH STREQUAL "arm") + + list(APPEND ROSLOAD_SOURCE + ntldr/arch/arm/winldr.c) + + list(APPEND ROSLOAD_ASM_SOURCE + arch/arm/boot.S) + +else() + #TBD +endif() + +add_asm_files(rosload_asm ${ROSLOAD_ASM_SOURCE}) + +add_executable(rosload + ${ROSLOAD_SOURCE} + ${rosload_asm} + ${CMAKE_CURRENT_BINARY_DIR}/rosload.def +) + +set_target_properties(rosload + PROPERTIES + ENABLE_EXPORTS TRUE + DEFINE_SYMBOL "") + +set_image_base(rosload 0x10000) # 0x200000 +set_subsystem(rosload native) +set_entrypoint(rosload RunLoader) + +if(ARCH STREQUAL "i386") + target_link_libraries(rosload mini_hal) +endif() + +target_link_libraries(rosload blcmlib blrtl libcntpr) +add_importlibs(rosload freeldr) + +# dynamic analysis switches +if(STACK_PROTECTOR) + target_sources(rosload PRIVATE $) +endif() + +if(RUNTIME_CHECKS) + target_link_libraries(rosload runtmchk) +endif() + +add_dependencies(rosload bugcodes asm xdk) + +add_cd_file(TARGET rosload DESTINATION loader NO_CAB FOR bootcd regtest livecd hybridcd) diff --git a/boot/freeldr/freeldr/rosload.spec b/boot/freeldr/freeldr/rosload.spec new file mode 100644 index 0000000000000..04bfebebebebb --- /dev/null +++ b/boot/freeldr/freeldr/rosload.spec @@ -0,0 +1,47 @@ +@ stdcall RtlAssert(ptr ptr long ptr) +@ varargs -arch=i386 ScsiDebugPrint(long str) +@ stdcall -arch=i386 ScsiPortCompleteRequest(ptr long long long long) +@ stdcall -arch=i386 ScsiPortConvertPhysicalAddressToUlong(long long) +@ stdcall -arch=i386 ScsiPortConvertUlongToPhysicalAddress(long) +#@ stdcall -arch=x86_64 ScsiPortConvertUlongToPhysicalAddress(long) +@ stdcall -arch=i386 ScsiPortFlushDma(ptr) +@ stdcall -arch=i386 ScsiPortFreeDeviceBase(ptr ptr) +@ stdcall -arch=i386 ScsiPortGetBusData(ptr long long long ptr long) +@ stdcall -arch=i386 ScsiPortGetDeviceBase(ptr long long long long long long) +@ stdcall -arch=i386 ScsiPortGetLogicalUnit(ptr long long long) +@ stdcall -arch=i386 ScsiPortGetPhysicalAddress(ptr ptr ptr long) +@ stdcall -arch=i386 ScsiPortGetSrb(ptr long long long long) +@ stdcall -arch=i386 ScsiPortGetUncachedExtension(ptr ptr long) +@ stdcall -arch=i386 ScsiPortGetVirtualAddress(ptr long long) +@ stdcall -arch=i386 ScsiPortInitialize(ptr ptr ptr ptr) +@ stdcall -arch=i386 ScsiPortIoMapTransfer(ptr ptr long long) +@ stdcall -arch=i386 ScsiPortLogError(ptr ptr long long long long long) +@ stdcall -arch=i386 ScsiPortMoveMemory(ptr ptr long) +@ cdecl -arch=i386 ScsiPortNotification() +@ stdcall -arch=i386 ScsiPortReadPortBufferUchar(ptr ptr long) +@ stdcall -arch=i386 ScsiPortReadPortBufferUshort(ptr ptr long) +@ stdcall -arch=i386 ScsiPortReadPortBufferUlong(ptr ptr long) +@ stdcall -arch=i386 ScsiPortReadPortUchar(ptr) +@ stdcall -arch=i386 ScsiPortReadPortUshort(ptr) +@ stdcall -arch=i386 ScsiPortReadPortUlong(ptr) +@ stdcall -arch=i386 ScsiPortReadRegisterBufferUchar(ptr ptr long) +@ stdcall -arch=i386 ScsiPortReadRegisterBufferUshort(ptr ptr long) +@ stdcall -arch=i386 ScsiPortReadRegisterBufferUlong(ptr ptr long) +@ stdcall -arch=i386 ScsiPortReadRegisterUchar(ptr) +@ stdcall -arch=i386 ScsiPortReadRegisterUshort(ptr) +@ stdcall -arch=i386 ScsiPortReadRegisterUlong(ptr) +@ stdcall -arch=i386 ScsiPortSetBusDataByOffset(ptr long long long ptr long long) +@ stdcall -arch=i386 ScsiPortStallExecution(long) +@ stdcall -arch=i386 ScsiPortValidateRange(ptr long long long long long long) +@ stdcall -arch=i386 ScsiPortWritePortBufferUchar(ptr ptr long) +@ stdcall -arch=i386 ScsiPortWritePortBufferUshort(ptr ptr long) +@ stdcall -arch=i386 ScsiPortWritePortBufferUlong(ptr ptr long) +@ stdcall -arch=i386 ScsiPortWritePortUchar(ptr long) +@ stdcall -arch=i386 ScsiPortWritePortUshort(ptr long) +@ stdcall -arch=i386 ScsiPortWritePortUlong(ptr long) +@ stdcall -arch=i386 ScsiPortWriteRegisterBufferUchar(ptr ptr long) +@ stdcall -arch=i386 ScsiPortWriteRegisterBufferUshort(ptr ptr long) +@ stdcall -arch=i386 ScsiPortWriteRegisterBufferUlong(ptr ptr long) +@ stdcall -arch=i386 ScsiPortWriteRegisterUchar(ptr long) +@ stdcall -arch=i386 ScsiPortWriteRegisterUshort(ptr long) +@ stdcall -arch=i386 ScsiPortWriteRegisterUlong(ptr long) diff --git a/boot/freeldr/freeldr/settings.c b/boot/freeldr/freeldr/settings.c index 7f1e44e51af2b..510ac25d63527 100644 --- a/boot/freeldr/freeldr/settings.c +++ b/boot/freeldr/freeldr/settings.c @@ -120,18 +120,41 @@ LoadSettings( CmdLineParse(CmdLine); return; } - else if (IsListEmpty(&IniFileSectionListHead)) + else if (IsListEmpty(IniGetFileSectionListHead())) { // ERR("LoadSettings() called but no freeldr.ini\n"); return; } - /* Open the [FreeLoader] section and load the settings */ - if ((BootMgrInfo.FrLdrSection == 0) && - !IniOpenSection("FreeLoader", &BootMgrInfo.FrLdrSection)) + BOOLEAN FoundLoaderSection = FALSE; + PCSTR LoaderSections[] = { + "FreeLoader", + "Boot Loader", + "FlexBoot", + "MultiBoot", + }; + + /* Search for the first section in LoaderSections and load the settings, + * prioritizing the order in the file. + * If a section is already loaded, skip further checks. */ + if (!BootMgrInfo.FrLdrSection) { - UiMessageBoxCritical("Section [FreeLoader] not found in freeldr.ini"); - return; + for (ULONG i = 0; i < sizeof(LoaderSections) / sizeof(LoaderSections[0]); i++) + { + PCSTR Section = LoaderSections[i]; + + if (IniOpenSection(Section, &BootMgrInfo.FrLdrSection)) + { + FoundLoaderSection = TRUE; + break; + } + } + + if (!FoundLoaderSection) + { + UiMessageBoxCritical("Bootloader Section not found in freeldr.ini"); + return; + } } /* Get the debug string. Always override it with the one from freeldr.ini */ @@ -165,4 +188,9 @@ LoadSettings( } } +PBOOTMGRINFO GetBootMgrInfo(VOID) +{ + return &BootMgrInfo; +} + /* EOF */ diff --git a/boot/freeldr/freeldr/uefi.cmake b/boot/freeldr/freeldr/uefi.cmake index a3bc6a7e2e09d..97a9a82c1027e 100644 --- a/boot/freeldr/freeldr/uefi.cmake +++ b/boot/freeldr/freeldr/uefi.cmake @@ -43,13 +43,20 @@ else() #TBD endif() +list(APPEND UEFILDR_BOOTMGR_SOURCE + ${FREELDR_BOOTMGR_SOURCE} + custom.c + options.c + oslist.c +) + add_asm_files(uefifreeldr_common_asm ${FREELDR_COMMON_ASM_SOURCE} ${UEFILDR_COMMON_ASM_SOURCE}) add_library(uefifreeldr_common ${uefifreeldr_common_asm} ${UEFILDR_ARC_SOURCE} ${FREELDR_BOOTLIB_SOURCE} - ${FREELDR_BOOTMGR_SOURCE} + ${UEFILDR_BOOTMGR_SOURCE} ${FREELDR_NTLDR_SOURCE}) target_compile_definitions(uefifreeldr_common PRIVATE UEFIBOOT) @@ -62,7 +69,7 @@ endif() set(PCH_SOURCE ${UEFILDR_ARC_SOURCE} ${FREELDR_BOOTLIB_SOURCE} - ${FREELDR_BOOTMGR_SOURCE} + ${UEFILDR_BOOTMGR_SOURCE} ${FREELDR_NTLDR_SOURCE}) add_pch(uefifreeldr_common include/arch/uefi/uefildr.h PCH_SOURCE) @@ -79,6 +86,9 @@ spec2def(uefildr.exe freeldr.spec) list(APPEND UEFILDR_BASE_SOURCE include/arch/uefi/uefildr.h arch/uefi/uefildr.c + bootmgr.c + ntldr/setupldr.c + ntldr/inffile.c ${FREELDR_BASE_SOURCE}) if(ARCH STREQUAL "i386") diff --git a/boot/freeldr/freeldr/ui/directui.c b/boot/freeldr/freeldr/ui/directui.c index 197061927d2b9..54b4debb1cac4 100644 --- a/boot/freeldr/freeldr/ui/directui.c +++ b/boot/freeldr/freeldr/ui/directui.c @@ -35,7 +35,7 @@ UiInitialize(IN BOOLEAN ShowUi) MachVideoGetDisplaySize(&UiScreenWidth, &UiScreenHeight, &Depth); /* Clear the screen */ - UiDrawBackdrop(); + UiDrawBackdrop(UiGetScreenHeight()); return TRUE; } @@ -47,7 +47,7 @@ UiUnInitialize(IN PCSTR BootText) } VOID -UiDrawBackdrop(VOID) +UiDrawBackdrop(ULONG DrawHeight) { /* Clear the screen */ MachVideoClearScreen(ATTR(COLOR_WHITE, COLOR_BLACK)); @@ -139,7 +139,6 @@ BOOLEAN UiDisplayMenu( IN PCSTR MenuHeader, IN PCSTR MenuFooter OPTIONAL, - IN BOOLEAN ShowBootOptions, IN PCSTR MenuItemList[], IN ULONG MenuItemCount, IN ULONG DefaultMenuItem, diff --git a/boot/freeldr/freeldr/ui/minitui.c b/boot/freeldr/freeldr/ui/minitui.c index d44aef6bc67ce..8742244940b38 100644 --- a/boot/freeldr/freeldr/ui/minitui.c +++ b/boot/freeldr/freeldr/ui/minitui.c @@ -53,10 +53,10 @@ BOOLEAN MiniTuiInitialize(VOID) return TRUE; } -VOID MiniTuiDrawBackdrop(VOID) +VOID MiniTuiDrawBackdrop(ULONG DrawHeight) { /* Fill in a black background */ - TuiFillArea(0, 0, UiScreenWidth - 1, UiScreenHeight - 1, + TuiFillArea(0, 0, UiScreenWidth - 1, DrawHeight - 1, UiBackdropFillStyle, ATTR(UiBackdropFgColor, UiBackdropBgColor)); @@ -64,6 +64,12 @@ VOID MiniTuiDrawBackdrop(VOID) VideoCopyOffScreenBufferToVRAM(); } +VOID MiniTuiFadeInBackdrop(VOID) +{ + /* No fade-in effect in MiniTui */ + MiniTuiDrawBackdrop(UiScreenHeight); +} + VOID MiniTuiDrawStatusText(PCSTR StatusText) { /* Minimal UI doesn't have a status bar */ @@ -186,7 +192,7 @@ MiniTuiDrawMenu( ULONG i; /* Draw the backdrop */ - UiDrawBackdrop(); + UiDrawBackdrop(UiGetScreenHeight()); /* No GUI status bar text, just minimal text. Show the menu header. */ if (MenuInfo->MenuHeader) @@ -225,12 +231,6 @@ MiniTuiDrawMenu( ATTR(UiMenuFgColor, UiMenuBgColor)); } - /* Display the boot options if needed */ - if (MenuInfo->ShowBootOptions) - { - DisplayBootTimeOptions(); - } - VideoCopyOffScreenBufferToVRAM(); } @@ -256,7 +256,7 @@ const UIVTBL MiniTuiVtbl = TuiEditBox, TuiTextToColor, TuiTextToFillStyle, - MiniTuiDrawBackdrop, /* no FadeIn */ + MiniTuiFadeInBackdrop, TuiFadeOut, TuiDisplayMenu, MiniTuiDrawMenu, diff --git a/boot/freeldr/freeldr/ui/noui.c b/boot/freeldr/freeldr/ui/noui.c index e79598bec630f..b465acff5754a 100644 --- a/boot/freeldr/freeldr/ui/noui.c +++ b/boot/freeldr/freeldr/ui/noui.c @@ -17,7 +17,7 @@ VOID NoUiUnInitialize(VOID) { } -VOID NoUiDrawBackdrop(VOID) +VOID NoUiDrawBackdrop(ULONG DrawHeight) { } @@ -163,7 +163,6 @@ BOOLEAN NoUiDisplayMenu( IN PCSTR MenuHeader, IN PCSTR MenuFooter OPTIONAL, - IN BOOLEAN ShowBootOptions, IN PCSTR MenuItemList[], IN ULONG MenuItemCount, IN ULONG DefaultMenuItem, diff --git a/boot/freeldr/freeldr/ui/tui.c b/boot/freeldr/freeldr/ui/tui.c index 5960dcd5d4456..732c2a622d68f 100644 --- a/boot/freeldr/freeldr/ui/tui.c +++ b/boot/freeldr/freeldr/ui/tui.c @@ -269,13 +269,13 @@ VOID TuiUnInitialize(VOID) MachVideoHideShowTextCursor(TRUE); } -VOID TuiDrawBackdrop(VOID) +VOID TuiDrawBackdrop(ULONG DrawHeight) { /* Fill in the background (excluding title box & status bar) */ TuiFillArea(0, TUI_TITLE_BOX_CHAR_HEIGHT, UiScreenWidth - 1, - UiScreenHeight - 2, + DrawHeight - 2, UiBackdropFillStyle, ATTR(UiBackdropFgColor, UiBackdropBgColor)); @@ -996,7 +996,7 @@ VOID TuiFadeInBackdrop(VOID) } // Draw the backdrop and title box - TuiDrawBackdrop(); + TuiDrawBackdrop(UiGetScreenHeight()); if (UiUseSpecialEffects && ! MachVideoIsPaletteFixed() && TuiFadePalette != NULL) { diff --git a/boot/freeldr/freeldr/ui/tuimenu.c b/boot/freeldr/freeldr/ui/tuimenu.c index 7559380389c89..b3a7e3f5ef957 100644 --- a/boot/freeldr/freeldr/ui/tuimenu.c +++ b/boot/freeldr/freeldr/ui/tuimenu.c @@ -30,7 +30,6 @@ BOOLEAN TuiDisplayMenu( IN PCSTR MenuHeader, IN PCSTR MenuFooter OPTIONAL, - IN BOOLEAN ShowBootOptions, IN PCSTR MenuItemList[], IN ULONG MenuItemCount, IN ULONG DefaultMenuItem, @@ -80,7 +79,6 @@ TuiDisplayMenu( /* Setup the MENU_INFO structure */ MenuInformation.MenuHeader = MenuHeader; MenuInformation.MenuFooter = MenuFooter; - MenuInformation.ShowBootOptions = ShowBootOptions; MenuInformation.MenuItemList = MenuItemList; MenuInformation.MenuItemCount = MenuItemCount; MenuInformation.MenuTimeRemaining = MenuTimeOut; @@ -204,7 +202,7 @@ TuiDrawMenu( // FIXME: Theme-specific /* Draw the backdrop */ - UiDrawBackdrop(); + UiDrawBackdrop(UiGetScreenHeight()); /* Draw the menu box */ TuiDrawMenuBox(MenuInfo); @@ -219,12 +217,6 @@ TuiDrawMenu( /* Update the status bar */ UiVtbl.DrawStatusText("Use \x18 and \x19 to select, then press ENTER."); - /* Display the boot options if needed */ - if (MenuInfo->ShowBootOptions) - { - DisplayBootTimeOptions(); - } - VideoCopyOffScreenBufferToVRAM(); } diff --git a/boot/freeldr/freeldr/ui/ui.c b/boot/freeldr/freeldr/ui/ui.c index 6da20152e32ae..946b49f435495 100644 --- a/boot/freeldr/freeldr/ui/ui.c +++ b/boot/freeldr/freeldr/ui/ui.c @@ -223,16 +223,16 @@ BOOLEAN UiInitialize(BOOLEAN ShowUi) VOID UiUnInitialize(PCSTR BootText) { - UiDrawBackdrop(); + UiDrawBackdrop(UiGetScreenHeight()); UiDrawStatusText(BootText); UiInfoBox(BootText); UiVtbl.UnInitialize(); } -VOID UiDrawBackdrop(VOID) +VOID UiDrawBackdrop(ULONG DrawHeight) { - UiVtbl.DrawBackdrop(); + UiVtbl.DrawBackdrop(DrawHeight); } VOID UiFillArea(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, CHAR FillChar, UCHAR Attr /* Color Attributes */) @@ -605,7 +605,6 @@ BOOLEAN UiDisplayMenu( IN PCSTR MenuHeader, IN PCSTR MenuFooter OPTIONAL, - IN BOOLEAN ShowBootOptions, IN PCSTR MenuItemList[], IN ULONG MenuItemCount, IN ULONG DefaultMenuItem, @@ -615,7 +614,7 @@ UiDisplayMenu( IN UiMenuKeyPressFilterCallback KeyPressFilter OPTIONAL, IN PVOID Context OPTIONAL) { - return UiVtbl.DisplayMenu(MenuHeader, MenuFooter, ShowBootOptions, + return UiVtbl.DisplayMenu(MenuHeader, MenuFooter, MenuItemList, MenuItemCount, DefaultMenuItem, MenuTimeOut, SelectedMenuItem, CanEscape, KeyPressFilter, Context); @@ -636,4 +635,32 @@ BOOLEAN UiEditBox(PCSTR MessageText, PCHAR EditTextBuffer, ULONG Length) return UiVtbl.EditBox(MessageText, EditTextBuffer, Length); } +VOID +UiResetForSOS(VOID) +{ +#ifdef _M_ARM + /* Re-initialize the UI */ + UiInitialize(TRUE); +#else + /* Reset the UI and switch to MiniTui */ + UiVtbl.UnInitialize(); + UiVtbl = MiniTuiVtbl; + UiVtbl.Initialize(); +#endif + /* Disable the progress bar */ + UiProgressBar.Show = FALSE; +} + +ULONG +UiGetScreenHeight(VOID) +{ + return UiScreenHeight; +} + +UCHAR +UiGetMenuBgColor(VOID) +{ + return UiMenuBgColor; +} + /* EOF */ diff --git a/boot/freeldr/install/install.c b/boot/freeldr/install/install.c index ba663ce6788e5..47cfd35d39b06 100644 --- a/boot/freeldr/install/install.c +++ b/boot/freeldr/install/install.c @@ -51,7 +51,7 @@ int main(int argc, char *argv[]) InstallBootSector(argv[2]); - _tprintf(_T("You must now copy freeldr.sys & freeldr.ini to %s.\n"), argv[1]); + _tprintf(_T("You must now copy freeldr.sys, rosload.exe and freeldr.ini to %s.\n"), argv[1]); CloseVolume(); diff --git a/configure.cmd b/configure.cmd index d94501ab4bc96..053ada5780389 100755 --- a/configure.cmd +++ b/configure.cmd @@ -24,7 +24,7 @@ set REACTOS_SOURCE_DIR=%~dp0 REM Ensure there's no spaces in the source path echo %REACTOS_SOURCE_DIR%| find " " > NUL if %ERRORLEVEL% == 0 ( - echo. && echo Your source path contains at least one space. + echo. & echo Your source path contains at least one space. echo This will cause problems with building. echo Please rename your folders so there are no spaces in the source path, echo or move your source to a different folder. @@ -70,7 +70,7 @@ if defined ROS_ARCH ( REM Checkpoint if not defined ARCH ( - echo Unknown build architecture + echo Unknown build architecture. goto quit ) @@ -97,14 +97,14 @@ set REMAINING=%* ) else if /I "!PARAM!" == "Ninja" ( set CMAKE_GENERATOR="Ninja" ) else if /I "!PARAM!" == "VSSolution" ( - echo. && echo Error: Creation of VS Solution files is not supported in a MinGW environment. + echo. & echo Error: Creation of VS Solution files is not supported in a MinGW environment. echo Please run this command in a [Developer] Command Prompt for Visual Studio. goto quit ) else if /I "!PARAM:~0,2!" == "-D" ( REM User is passing a switch to CMake set "CMAKE_PARAMS=%CMAKE_PARAMS% !PARAM!" ) else ( - echo. && echo Warning: Unrecognized switch "!PARAM!" && echo. + echo. & echo Warning: Unrecognized switch "!PARAM!" & echo. ) ) else ( if /I "!PARAM!" == "CodeBlocks" ( @@ -142,10 +142,13 @@ set REMAINING=%* set CMAKE_ARCH=-A ARM64 ) ) else if /I "!PARAM:~0,2!" == "-D" ( + if /I "!PARAM!" == "-DSARCH=wow64" ( + set WOW64_BUILD=1 + ) REM User is passing a switch to CMake set "CMAKE_PARAMS=%CMAKE_PARAMS% !PARAM!" ) else ( - echo. && echo Warning: Unrecognized switch "!PARAM!" && echo. + echo. & echo Warning: Unrecognized switch "!PARAM!" & echo. ) ) @@ -157,9 +160,17 @@ if "!CMAKE_GENERATOR!" == "Ninja" ( echo This script defaults to Ninja. Type "configure help" for alternative options. ) +REM Display information +echo Configuring a new ReactOS build on: +(for /f "delims=" %%x in ('ver') do @echo %%x) & echo. + REM Create directories set REACTOS_OUTPUT_PATH=output-%BUILD_ENVIRONMENT%-%ARCH% +if "%WOW64_BUILD%" == "1" ( + set REACTOS_OUTPUT_PATH=%REACTOS_OUTPUT_PATH%-wow64 +) + if "%VS_SOLUTION%" == "1" ( set REACTOS_OUTPUT_PATH=%REACTOS_OUTPUT_PATH%-sln ) @@ -175,27 +186,24 @@ if "%REACTOS_SOURCE_DIR%" == "%CD%\" ( ) if "%VS_SOLUTION%" == "1" ( - if exist build.ninja ( - echo. && echo Error: This directory has already been configured for ninja. + echo. & echo Error: This directory has already been configured for ninja. echo An output folder configured for ninja can't be reconfigured for VSSolution. echo Use an empty folder or delete the contents of this folder, then try again. goto quit ) ) else if exist REACTOS.sln ( - echo. && echo Error: This directory has already been configured for Visual Studio. + echo. & echo Error: This directory has already been configured for Visual Studio. echo An output folder configured for VSSolution can't be reconfigured for ninja. - echo Use an empty folder or delete the contents of this folder, then try again. && echo. + echo Use an empty folder or delete the contents of this folder, then try again. & echo. goto quit ) -echo Preparing reactos... if EXIST CMakeCache.txt ( - del CMakeCache.txt /q + del /q CMakeCache.txt ) - if "%BUILD_ENVIRONMENT%" == "MinGW" ( cmake -G %CMAKE_GENERATOR% -DENABLE_CCACHE:BOOL=0 -DCMAKE_TOOLCHAIN_FILE:FILEPATH=%MINGW_TOOCHAIN_FILE% -DARCH:STRING=%ARCH% %BUILD_TOOLS_FLAG% %CMAKE_PARAMS% "%REACTOS_SOURCE_DIR%" ) else if %USE_CLANG_CL% == 1 ( @@ -213,17 +221,17 @@ if "%CD_SAME_AS_SOURCE%" == "1" ( ) if "%VS_SOLUTION%" == "1" ( - set ENDV= You can now use msbuild or open REACTOS.sln%ENDV%. + set ENDV= You can now use msbuild or open REACTOS.sln%ENDV% ) else ( - set ENDV= Execute appropriate build commands ^(ex: ninja, make, nmake, etc...^)%ENDV% + set ENDV= Execute appropriate build commands ^(e.g. ninja, make, nmake, etc.^)%ENDV% ) -echo. && echo Configure script complete^^!%ENDV% +echo. & echo Configure script complete^^!%ENDV% goto quit :cmake_notfound -echo Unable to find cmake, if it is installed, check your PATH variable. +echo Unable to find cmake. If it is installed, check your PATH variable. :quit endlocal diff --git a/configure.sh b/configure.sh index f9c4679ad13fa..10928fce7dec9 100755 --- a/configure.sh +++ b/configure.sh @@ -1,7 +1,7 @@ #!/bin/sh if [ "x$ROS_ARCH" = "x" ]; then - echo Could not detect RosBE. + echo "Could not detect RosBE." exit 1 fi @@ -11,7 +11,7 @@ REACTOS_SOURCE_DIR=$(cd `dirname $0` && pwd) REACTOS_OUTPUT_PATH=output-$BUILD_ENVIRONMENT-$ARCH usage() { - echo Invalid parameter given. + echo "Invalid parameter given." exit 1 } @@ -40,19 +40,21 @@ while [ $# -gt 0 ]; do shift done +echo "Configuring a new ReactOS build on:" +echo $(uname -srvpio); echo + if [ "$REACTOS_SOURCE_DIR" = "$PWD" ]; then - echo Creating directories in $REACTOS_OUTPUT_PATH + echo "Creating directories in $REACTOS_OUTPUT_PATH" mkdir -p "$REACTOS_OUTPUT_PATH" cd "$REACTOS_OUTPUT_PATH" fi -echo Preparing reactos... rm -f CMakeCache.txt host-tools/CMakeCache.txt cmake -G "$CMAKE_GENERATOR" -DENABLE_CCACHE:BOOL=0 -DCMAKE_TOOLCHAIN_FILE:FILEPATH=toolchain-gcc.cmake -DARCH:STRING=$ARCH $EXTRA_ARGS $ROS_CMAKEOPTS "$REACTOS_SOURCE_DIR" if [ $? -ne 0 ]; then - echo "An error occured while configuring ReactOS" + echo "An error occurred while configuring ReactOS" exit 1 fi -echo Configure script complete! Enter directories and execute appropriate build commands \(ex: ninja, make, makex, etc...\). +echo "Configure script complete! Execute appropriate build commands (e.g. ninja, make, makex, etc.) from $REACTOS_OUTPUT_PATH" diff --git a/dll/3rdparty/libjpeg/CMakeLists.txt b/dll/3rdparty/libjpeg/CMakeLists.txt index fefc3da850c5a..1b68ac714880f 100644 --- a/dll/3rdparty/libjpeg/CMakeLists.txt +++ b/dll/3rdparty/libjpeg/CMakeLists.txt @@ -10,6 +10,8 @@ include_directories( ${REACTOS_SOURCE_DIR}/sdk/include/reactos/libs/libjpeg ${REACTOS_SOURCE_DIR}/sdk/include/reactos/libs/zlib) +spec2def(libjpeg.dll libjpeg.spec ADD_IMPORTLIB) + list(APPEND SOURCE jaricom.c jcapimin.c @@ -59,7 +61,7 @@ list(APPEND SOURCE jmemnobs.c precomp.h) -add_library(libjpeg MODULE ${SOURCE}) +add_library(libjpeg MODULE ${SOURCE} ${CMAKE_CURRENT_BINARY_DIR}/libjpeg.def) set_module_type(libjpeg win32dll) add_importlibs(libjpeg msvcrt kernel32) add_pch(libjpeg precomp.h SOURCE) diff --git a/dll/3rdparty/libjpeg/libjpeg.spec b/dll/3rdparty/libjpeg/libjpeg.spec new file mode 100644 index 0000000000000..62eda3cbd0f70 --- /dev/null +++ b/dll/3rdparty/libjpeg/libjpeg.spec @@ -0,0 +1,14 @@ +@ cdecl jpeg_std_error(ptr) +@ cdecl jpeg_CreateCompress(ptr long) +@ cdecl jpeg_CreateDecompress(ptr long long) +@ cdecl jpeg_destroy_compress(ptr) +@ cdecl jpeg_destroy_decompress(ptr) +@ cdecl jpeg_set_defaults(ptr) +@ cdecl jpeg_start_compress(ptr long) +@ cdecl jpeg_write_scanlines(ptr ptr long) +@ cdecl jpeg_finish_compress(ptr) +@ cdecl jpeg_read_header(ptr long) +@ cdecl jpeg_start_decompress(ptr) +@ cdecl jpeg_read_scanlines(ptr ptr long) +@ cdecl jpeg_finish_decompress(ptr) +@ cdecl jpeg_resync_to_restart(ptr long) diff --git a/dll/3rdparty/libpng/CMakeLists.txt b/dll/3rdparty/libpng/CMakeLists.txt index e759953956276..a5b3849377f3e 100644 --- a/dll/3rdparty/libpng/CMakeLists.txt +++ b/dll/3rdparty/libpng/CMakeLists.txt @@ -9,6 +9,8 @@ include_directories( ${REACTOS_SOURCE_DIR}/sdk/include/reactos/libs/libpng ${REACTOS_SOURCE_DIR}/sdk/include/reactos/libs/zlib) +spec2def(libpng.dll libpng.spec ADD_IMPORTLIB) + list(APPEND SOURCE png.c pngerror.c @@ -27,7 +29,7 @@ list(APPEND SOURCE pngwutil.c pngpriv.h) -add_library(libpng MODULE ${SOURCE}) +add_library(libpng MODULE ${SOURCE} ${CMAKE_CURRENT_BINARY_DIR}/libpng.def) set_module_type(libpng win32dll) target_link_libraries(libpng zlib) add_importlibs(libpng msvcrt kernel32 ntdll) diff --git a/dll/3rdparty/libpng/libpng.spec b/dll/3rdparty/libpng/libpng.spec new file mode 100644 index 0000000000000..98fd045663566 --- /dev/null +++ b/dll/3rdparty/libpng/libpng.spec @@ -0,0 +1,53 @@ +@ cdecl png_create_info_struct(ptr) +@ cdecl png_create_read_struct(ptr ptr ptr ptr) +@ cdecl png_create_write_struct(ptr ptr ptr ptr) +@ cdecl png_get_compression_buffer_size(ptr) +@ cdecl png_set_compression_buffer_size(ptr long) +@ cdecl png_set_longjmp_fn(ptr ptr long) +@ cdecl png_destroy_read_struct(ptr ptr ptr) +@ cdecl png_destroy_write_struct(ptr ptr) +@ cdecl png_error(ptr ptr) +@ cdecl png_free(ptr ptr) +@ cdecl png_get_bit_depth(ptr ptr) +@ cdecl png_get_channels(ptr ptr) +@ cdecl png_get_color_type(ptr ptr) +@ cdecl png_get_error_ptr(ptr) +@ cdecl png_get_iCCP(ptr ptr ptr ptr ptr ptr) +@ cdecl png_get_IHDR(ptr ptr ptr ptr ptr ptr ptr ptr ptr) +@ cdecl png_get_image_height(ptr ptr) +@ cdecl png_get_image_width(ptr ptr) +@ cdecl png_get_io_ptr(ptr) +@ cdecl png_get_pHYs(ptr ptr ptr ptr) +@ cdecl png_get_PLTE(ptr ptr ptr ptr) +@ cdecl png_get_rowbytes(ptr ptr) +@ cdecl png_get_rows(ptr ptr) +@ cdecl png_get_tRNS(ptr ptr ptr ptr ptr) +@ cdecl png_malloc(ptr long) +@ cdecl png_read_end(ptr ptr) +@ cdecl png_read_image(ptr ptr) +@ cdecl png_read_info(ptr ptr) +@ cdecl png_read_update_info(ptr ptr) +@ cdecl png_set_bgr(ptr) +@ cdecl png_set_crc_action(ptr long long) +@ cdecl png_set_filter(ptr long long) +@ cdecl png_set_error_fn(ptr ptr ptr ptr) +@ cdecl png_set_filler(ptr long long) +@ cdecl png_set_gray_to_rgb(ptr) +@ cdecl png_set_IHDR(ptr ptr long long long long long long long) +@ cdecl png_set_interlace_handling(ptr) +@ cdecl png_set_palette_to_rgb(ptr) +@ cdecl png_set_pHYs(ptr ptr ptr long long long) +@ cdecl png_set_PLTE(ptr ptr ptr long) +@ cdecl png_set_read_fn(ptr ptr ptr) +@ cdecl png_set_rows(ptr ptr ptr) +@ cdecl png_set_scale_16(ptr) +@ cdecl png_set_sig_bytes(ptr long) +@ cdecl png_set_swap(ptr) +@ cdecl png_set_tRNS(ptr ptr ptr long ptr) +@ cdecl png_set_tRNS_to_alpha(ptr) +@ cdecl png_set_write_fn(ptr ptr ptr ptr) +@ cdecl png_set_chunk_malloc_max(ptr long) +@ cdecl png_sig_cmp(ptr long long) +@ cdecl png_write_end(ptr) +@ cdecl png_write_info(ptr ptr) +@ cdecl png_write_rows(ptr ptr long) diff --git a/dll/3rdparty/libtiff/CMakeLists.txt b/dll/3rdparty/libtiff/CMakeLists.txt index 2aff720a34029..882d3b3971f64 100644 --- a/dll/3rdparty/libtiff/CMakeLists.txt +++ b/dll/3rdparty/libtiff/CMakeLists.txt @@ -9,6 +9,8 @@ include_directories( ${REACTOS_SOURCE_DIR}/sdk/include/reactos/libs/libtiff ${REACTOS_SOURCE_DIR}/sdk/include/reactos/libs/zlib) +spec2def(libtiff.dll libtiff.spec ADD_IMPORTLIB) + list(APPEND SOURCE #mkg3states.c tif_aux.c @@ -54,7 +56,7 @@ list(APPEND SOURCE #tif_zstd.c precomp.h) -add_library(libtiff MODULE ${SOURCE} libtiff.def) +add_library(libtiff MODULE ${SOURCE} ${CMAKE_CURRENT_BINARY_DIR}/libtiff.def) set_module_type(libtiff win32dll) target_link_libraries(libtiff zlib getopt) diff --git a/dll/3rdparty/libtiff/libtiff.spec b/dll/3rdparty/libtiff/libtiff.spec new file mode 100644 index 0000000000000..f774b2ac4a140 --- /dev/null +++ b/dll/3rdparty/libtiff/libtiff.spec @@ -0,0 +1,17 @@ +# TODO: add remaining exports +@ cdecl TIFFClose(ptr) +@ cdecl TIFFClientOpen(ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr) +@ cdecl TIFFCurrentDirOffset(ptr) +@ cdecl TIFFGetField(ptr long long long) +@ cdecl TIFFIsByteSwapped(ptr) +@ cdecl TIFFNumberOfDirectories(ptr) +@ cdecl TIFFReadEncodedStrip(ptr) +@ cdecl TIFFReadEncodedTile(ptr long ptr long) +@ cdecl TIFFSetDirectory(ptr long) +@ cdecl TIFFSetErrorHandler(ptr) +@ cdecl TIFFSetErrorHandlerExt(ptr) +@ cdecl TIFFSetWarningHandler(ptr) +@ cdecl TIFFSetWarningHandlerExt(ptr) +@ cdecl TIFFSetField(ptr long long long) +@ cdecl TIFFWriteDirectory(ptr) +@ cdecl TIFFWriteScanline(ptr ptr long long) diff --git a/dll/CMakeLists.txt b/dll/CMakeLists.txt index 47c8bf28ff215..44b6c988e739d 100644 --- a/dll/CMakeLists.txt +++ b/dll/CMakeLists.txt @@ -11,3 +11,7 @@ add_subdirectory(ntdll) add_subdirectory(opengl) add_subdirectory(shellext) add_subdirectory(win32) +if(ARCH STREQUAL "amd64") + add_subdirectory(wow64) + add_subdirectory(wow64win) +endif() \ No newline at end of file diff --git a/dll/appcompat/apphelp/sdbfileattr.c b/dll/appcompat/apphelp/sdbfileattr.c index 309b16b343279..1635df5e920fb 100644 --- a/dll/appcompat/apphelp/sdbfileattr.c +++ b/dll/appcompat/apphelp/sdbfileattr.c @@ -311,7 +311,7 @@ BOOL WINAPI SdbGetFileAttributes(LPCWSTR path, PATTRINFO *attr_info_ret, LPDWORD SdbpSetStringAttr(&attr_info[10], TAG_INTERNAL_NAME, SdbpGetStringAttr(translation, str_InternalName, file_info)); SdbpSetStringAttr(&attr_info[11], TAG_LEGAL_COPYRIGHT, SdbpGetStringAttr(translation, str_LegalCopyright, file_info)); - /* http://msdn.microsoft.com/en-us/library/windows/desktop/ms680339(v=vs.85).aspx */ + /* https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-image_optional_header32 */ SdbpSetDWORDAttr(&attr_info[17], TAG_PE_CHECKSUM, headers->OptionalHeader.CheckSum); diff --git a/dll/cpl/access/lang/cs-CZ.rc b/dll/cpl/access/lang/cs-CZ.rc index a79053291ae80..848cd5d22eb09 100644 --- a/dll/cpl/access/lang/cs-CZ.rc +++ b/dll/cpl/access/lang/cs-CZ.rc @@ -1,3 +1,11 @@ +/* + * PROJECT: ReactOS Accessibility Control Panel + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Czech resource file + * TRANSLATORS: Copyright 2007 Kamil Horníček + * Copyright 2014 Radek Liška (Black_Fox) + * Copyright 2024 Václav Zouzalík (Venca24) + */ LANGUAGE LANG_CZECH, SUBLANG_DEFAULT IDD_PROPPAGEKEYBOARD DIALOGEX 0, 0, 246, 220 @@ -33,7 +41,7 @@ BEGIN LTEXT "Použijte funkci Zobrazení zvuku, pokud chcete aby ReactOS vizuálně upozorňoval na každý zvuk vydaný systémem.", -1, 12, 20, 222, 29 AUTOCHECKBOX "&Používat funkci Popis zvuku", IDC_SENTRY_BOX, 12, 49, 120, 14 - LTEXT "Use the following warning:", IDC_SENTRY_TEXT, 12, 72, 222, 11 + LTEXT "Použít následující upozornění:", IDC_SENTRY_TEXT, 12, 72, 222, 11 COMBOBOX IDC_SENTRY_COMBO, 12, 83, 222, 56, CBS_DROPDOWNLIST | WS_VSCROLL | WS_VISIBLE | WS_TABSTOP GROUPBOX "Funkce Zobrazení zvuku", -1, 6, 115, 234, 67 @@ -52,17 +60,17 @@ BEGIN -1, 12, 20, 222, 29 AUTOCHECKBOX "&Použít funkci Vysoký kontrast", IDC_CONTRAST_BOX, 12, 49, 126, 14 PUSHBUTTON "&Nastavení", IDC_CONTRAST_BUTTON, 144, 49, 90, 14 - GROUPBOX "Cursor options", -1, 6, 79, 234, 115 - LTEXT "Use the track bars to modify the blinking speed of the cursor and its width.", + GROUPBOX "Nastavení kurzoru", -1, 6, 79, 234, 115 + LTEXT "Použijte posuvníky pro změnu rychlosti blikání a šířky kurzoru.", -1, 12, 88, 222, 20 - CTEXT "Blinking speed:", -1, 12, 115, 222, 11 - LTEXT "None", -1, 18, 130, 36, 11 - LTEXT "Fast", -1, 192, 130, 36, 11 + CTEXT "Rychlost blikání:", -1, 12, 115, 222, 11 + LTEXT "Žádné", -1, 18, 130, 36, 11 + LTEXT "Rychlé", -1, 192, 130, 36, 11 CONTROL "", IDC_CURSOR_BLINK_TRACK, "msctls_trackbar32", TBS_AUTOTICKS | WS_TABSTOP, 60, 124, 126, 20 - CTEXT "Cursor width:", -1, 12, 151, 222, 11 - LTEXT "Narrow", -1, 18, 171, 36, 11 - LTEXT "Wide", -1, 192, 171, 36, 11 + CTEXT "Šířka kurzoru:", -1, 12, 151, 222, 11 + LTEXT "Úzký", -1, 18, 171, 36, 11 + LTEXT "Široký", -1, 192, 171, 36, 11 CONTROL "", IDC_CURSOR_WIDTH_TRACK, "msctls_trackbar32", TBS_AUTOTICKS | WS_TABSTOP, 60, 169, 126, 20 LTEXT "", IDC_CURSOR_WIDTH_TEXT, 18, 142, 24, 16 @@ -109,155 +117,155 @@ END IDD_STICKYKEYSOPTIONS DIALOGEX 0, 0, 246, 220 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Sticky Keys Settings" +CAPTION "Nastavení funkce Jedním prstem" FONT 8, "MS Shell Dlg" BEGIN - GROUPBOX "Keys", -1, 6, 11, 234, 62 - LTEXT "Press the SHIFT-Key 5 times in order to activate the Sticky Keys feature.", + GROUPBOX "Klávesy", -1, 6, 11, 234, 62 + LTEXT "Aktivujte funkci Jedním prstem stisknutím klávesy SHIFT 5krát.", -1, 12, 20, 222, 29 - AUTOCHECKBOX "A&ctivate sticky keys", IDC_STICKY_ACTIVATE_CHECK, 12, 49, 222, 14 - GROUPBOX "Options", -1, 6, 83, 234, 44 - AUTOCHECKBOX "&Press modifier key twice to lock", IDC_STICKY_LOCK_CHECK, + AUTOCHECKBOX "A&ktivovat Jedním prstem", IDC_STICKY_ACTIVATE_CHECK, 12, 49, 222, 14 + GROUPBOX "Nastavení", -1, 6, 83, 234, 44 + AUTOCHECKBOX "&Stiskněte modifikační klávesu dvakrát pro její aktivaci", IDC_STICKY_LOCK_CHECK, 12, 94, 222, 14 - AUTOCHECKBOX "&Turn StickyKeys off if two keys are pressed at once", IDC_STICKY_UNLOCK_CHECK, + AUTOCHECKBOX "Vypnou&t, když jsou stisknuty dvě klávesy najednou", IDC_STICKY_UNLOCK_CHECK, 12, 106, 222, 14 - GROUPBOX "Notifications", -1, 6, 133, 234, 44 - AUTOCHECKBOX "&Make sounds when the modifier key is pressed", IDC_STICKY_SOUND_CHECK, + GROUPBOX "Notifikace", -1, 6, 133, 234, 44 + AUTOCHECKBOX "&Přehrát zvuk při stisku modifikační klávesy", IDC_STICKY_SOUND_CHECK, 12, 148, 222, 14 - AUTOCHECKBOX "&Show StickyKeys status on screen", IDC_STICKY_STATUS_CHECK, + AUTOCHECKBOX "&Zobrazit stav funkce Jedním prstem na obrazovce", IDC_STICKY_STATUS_CHECK, 12, 160, 222, 14 DEFPUSHBUTTON "OK", IDOK, 135, 207, 50, 14 - PUSHBUTTON "Cancel", IDCANCEL, 189, 207, 50, 14 + PUSHBUTTON "Storno", IDCANCEL, 189, 207, 50, 14 END IDD_FILTERKEYSOPTIONS DIALOGEX 0, 0, 246, 220 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Filter Keys Settings" +CAPTION "Nastavení Filtrování kláves" FONT 8, "MS Shell Dlg" BEGIN - GROUPBOX "Keyboard shortcut", -1, 6, 11, 234, 62 - LTEXT "The shortcut for FilterKeys is:\nHold down for eight seconds.", + GROUPBOX "Klávesová zkratka", -1, 6, 11, 234, 62 + LTEXT "Klávesová zkratka pro Filtrování kláves je:\nPodržte po osm sekund.", -1, 12, 20, 222, 29 - AUTOCHECKBOX "&Use shortcut", IDC_FILTER_ACTIVATE_CHECK, 12, 49, 126, 14 - GROUPBOX "Filter options", -1, 6, 79, 234, 79 - AUTORADIOBUTTON "Ign&ore repeated keystrokes", IDC_FILTER_BOUNCE_RADIO, + AUTOCHECKBOX "&Použít klávesovou zkratku", IDC_FILTER_ACTIVATE_CHECK, 12, 49, 126, 14 + GROUPBOX "Nastavení filtrování", -1, 6, 79, 234, 79 + AUTORADIOBUTTON "Ign&orovat opakovaná stisknutí", IDC_FILTER_BOUNCE_RADIO, 12, 91, 120, 11, WS_GROUP | WS_TABSTOP - AUTORADIOBUTTON "Ig&nore quick keystrokes and slow down the repeat rate", IDC_FILTER_REPEAT_RADIO, + AUTORADIOBUTTON "Ig&norovat rychlá stisknutí a zpomalit opakování", IDC_FILTER_REPEAT_RADIO, 12, 106, 120, 20, BS_TOP | BS_MULTILINE - PUSHBUTTON "&Settings", IDC_FILTER_BOUNCE_BUTTON, 144, 88, 90, 14, WS_GROUP - PUSHBUTTON "S&ettings", IDC_FILTER_REPEAT_BUTTON, 144, 106, 90, 14, WS_GROUP - LTEXT "&Click here and type here to test the settings:", -1, 12, 129, 222, 11 + PUSHBUTTON "&Nastavení", IDC_FILTER_BOUNCE_BUTTON, 144, 88, 90, 14, WS_GROUP + PUSHBUTTON "N&astavení", IDC_FILTER_REPEAT_BUTTON, 144, 106, 90, 14, WS_GROUP + LTEXT "&Klikněte zde a pište pro vyzkoušení nastavení:", -1, 12, 129, 222, 11 EDITTEXT IDC_FILTER_TEST_EDIT, 12, 138, 222, 14, WS_GROUP | ES_AUTOHSCROLL - GROUPBOX "Notifications", -1, 6, 161, 234, 41 - AUTOCHECKBOX "&Beep when keys pressed or accepted", IDC_FILTER_SOUND_CHECK, + GROUPBOX "Notifikace", -1, 6, 161, 234, 41 + AUTOCHECKBOX "&Pípnout když je klávesa stisknuta nebo přijata", IDC_FILTER_SOUND_CHECK, 12, 169, 222, 10 - AUTOCHECKBOX "S&how FilterKey status on screen", IDC_FILTER_STATUS_CHECK, + AUTOCHECKBOX "&Zobrazit stav filtrování na obrazovce", IDC_FILTER_STATUS_CHECK, 12, 188, 222, 10 DEFPUSHBUTTON "OK", IDOK, 135, 207, 50, 14 - PUSHBUTTON "Cancel", IDCANCEL, 189, 207, 50, 14 + PUSHBUTTON "Storno", IDCANCEL, 189, 207, 50, 14 END IDD_TOGGLEKEYSOPTIONS DIALOGEX 0, 0, 246, 220 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Toggle Keys Settings" +CAPTION "Nastavení ozvučení kláves" FONT 8, "MS Shell Dlg" BEGIN - GROUPBOX "Keyboard shortcut", -1, 6, 11, 234, 62 - LTEXT "The shortcut for ToggleKeys is:\nHold down for five seconds.", + GROUPBOX "Klávesová zkratka", -1, 6, 11, 234, 62 + LTEXT "Klávesová zkratka pro zvučení kláves je:\nPodržte po dobu pěti sekund.", -1, 12, 20, 222, 29 - AUTOCHECKBOX "Use &shortcut", IDC_TOGGLE_ACTIVATE_CHECK, 12, 49, 222, 14 + AUTOCHECKBOX "Použít &klávesovou zkratku", IDC_TOGGLE_ACTIVATE_CHECK, 12, 49, 222, 14 DEFPUSHBUTTON "OK", IDOK, 135, 207, 50, 14 - PUSHBUTTON "Cancel", IDCANCEL, 189, 207, 50, 14 + PUSHBUTTON "Storno", IDCANCEL, 189, 207, 50, 14 END IDD_CONTRASTOPTIONS DIALOGEX 0, 0, 246, 220 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "High Contrast Settings" +CAPTION "Nastavení Vysokého kontrastu" FONT 8, "MS Shell Dlg" BEGIN - GROUPBOX "Keyboard shortcut", -1, 6, 11, 234, 62 - LTEXT "The shortcut for High Contrast is:\nPress .", + GROUPBOX "Klávesová zkratka", -1, 6, 11, 234, 62 + LTEXT "Klávesová zkratka pro Vysoký kontrast je:\nStiskněte .", -1, 12, 20, 222, 29 - AUTOCHECKBOX "&Use shortcut", IDC_CONTRAST_ACTIVATE_CHECK, 12, 49, 222, 14 - GROUPBOX "High Contrast Color Scheme", -1, 6, 83, 234, 44 - LTEXT "Current Color Scheme:", -1, 12, 94, 222, 11 + AUTOCHECKBOX "Po&užít klávesovou zkratku", IDC_CONTRAST_ACTIVATE_CHECK, 12, 49, 222, 14 + GROUPBOX "Barevné schéma Vysokého kontrastu", -1, 6, 83, 234, 44 + LTEXT "Aktuální barevné schéma:", -1, 12, 94, 222, 11 COMBOBOX IDC_CONTRAST_COMBO, 12, 103, 222, 56, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_VISIBLE | WS_TABSTOP DEFPUSHBUTTON "OK", IDOK, 135, 207, 50, 14 - PUSHBUTTON "Cancel", IDCANCEL, 189, 207, 50, 14 + PUSHBUTTON "Storno", IDCANCEL, 189, 207, 50, 14 END IDD_MOUSEKEYSOPTIONS DIALOGEX 0, 0, 246, 220 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Mouse Keys Settings" +CAPTION "Nastavení Myš klávesnicí" FONT 8, "MS Shell Dlg" BEGIN - GROUPBOX "Keyboard shortcut", -1, 6, 11, 234, 62 - LTEXT "The shortcut for Mouse Keys is:\nPress .", + GROUPBOX "Klávesová zkratka", -1, 6, 11, 234, 62 + LTEXT "Klávesová zkratka pro Myš klávesnicí je:\nStistkněte .", -1, 12, 20, 222, 29 - AUTOCHECKBOX "&Use shortcut", IDC_MOUSEKEYS_ACTIVATE_CHECK, + AUTOCHECKBOX "Po&užít klávesovou zkratku", IDC_MOUSEKEYS_ACTIVATE_CHECK, 12, 49, 222, 14 - GROUPBOX "Pointer speed", -1, 6, 83, 234, 83 - LTEXT "&Top speed:", -1, 12, 96, 48, 11 - LTEXT "Low", -1, 66, 96, 18, 11 + GROUPBOX "Rychlost kurzoru", -1, 6, 83, 234, 83 + LTEXT "&Nejvyšší:", -1, 12, 96, 48, 11 + LTEXT "Nízká", -1, 66, 96, 18, 11 CONTROL "", IDC_MOUSEKEYS_SPEED_TRACK, "msctls_trackbar32", TBS_AUTOTICKS | WS_TABSTOP, 90, 94, 114, 20 - LTEXT "High", -1, 204, 96, 18, 11 - LTEXT "&Acceleration:", -1, 12, 123, 48, 11 - LTEXT "Slow", -1, 66, 123, 18, 11 + LTEXT "Vysoká", -1, 204, 96, 24, 11 + LTEXT "&Zrychlení:", -1, 12, 123, 48, 11 + LTEXT "Pomalé", -1, 66, 123, 22, 11 CONTROL "", IDC_MOUSEKEYS_ACCEL_TRACK, "msctls_trackbar32", TBS_AUTOTICKS | WS_TABSTOP, 90, 121, 114, 20 - LTEXT "Fast", -1, 204, 123, 18, 11 - AUTOCHECKBOX "&Hold down Ctrl to speed up and Shift to slow down", IDC_MOUSEKEYS_SPEED_CHECK, + LTEXT "Rychlé", -1, 204, 123, 20, 11 + AUTOCHECKBOX "&Podržet Ctrl pro zrychlení a Shift pro zpomalení", IDC_MOUSEKEYS_SPEED_CHECK, 12, 142, 222, 14 - LTEXT "Use MouseKeys when NumLock is:", -1, 6, 171, 120, 11 - AUTORADIOBUTTON "O&n", IDC_MOUSEKEYS_ON_RADIO, 162, 171, 30, 11 - AUTORADIOBUTTON "Of&f", IDC_MOUSEKEYS_OFF_RADIO, 198, 171, 30, 11 - AUTOCHECKBOX "&Show MouseKey status on screen", IDC_MOUSEKEYS_STATUS_CHECK, + LTEXT "Použít Myš klávesnicí když NumLock je:", -1, 6, 171, 120, 11 + AUTORADIOBUTTON "Z&ap.", IDC_MOUSEKEYS_ON_RADIO, 162, 171, 30, 11 + AUTORADIOBUTTON "&Vyp.", IDC_MOUSEKEYS_OFF_RADIO, 198, 171, 30, 11 + AUTOCHECKBOX "Z&obrazit stav Myši klávesnicí na obrazovce", IDC_MOUSEKEYS_STATUS_CHECK, 6, 184, 222, 14 DEFPUSHBUTTON "OK", IDOK, 135, 207, 50, 14 - PUSHBUTTON "Cancel", IDCANCEL, 189, 207, 50, 14 + PUSHBUTTON "Storno", IDCANCEL, 189, 207, 50, 14 END IDD_BOUNCEKEYSOPTIONS DIALOGEX 0, 0, 246, 220 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Advanced FilterKeys Settings" +CAPTION "Pokročilá nastavení Filtrování kláves" FONT 8, "MS Shell Dlg" BEGIN - GROUPBOX "Bounce Keys", -1, 6, 11, 234, 47 - LTEXT "&Ignore keystrokes repeated faster than:", -1, 12, 21, 222, 20 + GROUPBOX "Odrazové klávesy", -1, 6, 11, 234, 47 + LTEXT "&Ignorovat stisky kláves opakované rychleji než:", -1, 12, 21, 222, 20 COMBOBOX IDC_BOUNCE_TIME_COMBO, 12, 34, 222, 56, CBS_DROPDOWNLIST | WS_VSCROLL | WS_VISIBLE | WS_TABSTOP - LTEXT "&Test area:", -1, 6, 68, 48, 11 + LTEXT "&Test:", -1, 6, 68, 48, 11 EDITTEXT IDC_BOUNCE_TEST_EDIT, 60, 65, 180, 14, ES_AUTOHSCROLL DEFPUSHBUTTON "OK", IDOK, 135, 207, 50, 14 - PUSHBUTTON "Cancel", IDCANCEL, 189, 207, 50, 14 + PUSHBUTTON "Storno", IDCANCEL, 189, 207, 50, 14 END IDD_REPEATKEYSOPTIONS DIALOGEX 0, 0, 246, 220 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Advanced FilterKeys Settings" +CAPTION "Pokročilá nastavení Filtrování kláves" FONT 8, "MS Shell Dlg" BEGIN - GROUPBOX "Repeat Keys", -1, 6, 11, 234, 106 - LTEXT "Override settings on the Keyboard control panel:", + GROUPBOX "Opakování kláves", -1, 6, 11, 234, 106 + LTEXT "Přepsat nastavení ve Vlastnostech klávesnice:", -1, 12, 20, 222, 20 - AUTORADIOBUTTON "&No keyboard repeat", IDC_REPEAT_NOREPEAT_RADIO, 12, 32, 78, 11, WS_GROUP - AUTORADIOBUTTON "&Slow down keyboard repeat rates", IDC_REPEAT_REPEAT_RADIO, 12, 45, 131, 11 - LTEXT "Repeat &delay:", -1, 24, 60, 60, 11 + AUTORADIOBUTTON "Žád&né opakování kláves", IDC_REPEAT_NOREPEAT_RADIO, 12, 32, 90, 11, WS_GROUP + AUTORADIOBUTTON "&Zpomalit rychlost opakování kláves", IDC_REPEAT_REPEAT_RADIO, 12, 45, 131, 11 + LTEXT "Zpož&dění:", -1, 24, 60, 60, 11 COMBOBOX IDC_REPEAT_DELAY_COMBO, 24, 71, 210, 56, CBS_DROPDOWNLIST | WS_VSCROLL | WS_VISIBLE | WS_TABSTOP - LTEXT "Repeat &rate:", -1, 24, 89, 60, 11 + LTEXT "&Rychlost:", -1, 24, 89, 60, 11 COMBOBOX IDC_REPEAT_REPEAT_COMBO, 24, 100, 210, 65, CBS_DROPDOWNLIST | WS_VSCROLL | WS_VISIBLE | WS_TABSTOP - GROUPBOX "Slow Keys", -1, 6, 124, 234, 42 - LTEXT "&Keys must be held down for:", -1, 12, 133, 222, 11 + GROUPBOX "Pomalé klávesy", -1, 6, 124, 234, 42 + LTEXT "&Klávesa musí být podržena po:", -1, 12, 133, 222, 11 COMBOBOX IDC_REPEAT_WAIT_COMBO, 12, 150, 222, 74, CBS_DROPDOWNLIST | WS_VSCROLL | WS_VISIBLE | WS_TABSTOP - LTEXT "&Test area:", -1, 6, 178, 48, 11 + LTEXT "&Test:", -1, 6, 178, 48, 11 EDITTEXT IDC_REPEAT_TEST_EDIT, 60, 180, 180, 14, ES_AUTOHSCROLL DEFPUSHBUTTON "OK", IDOK, 135, 207, 50, 14 - PUSHBUTTON "Cancel", IDCANCEL, 189, 207, 50, 14 + PUSHBUTTON "Storno", IDCANCEL, 189, 207, 50, 14 END IDD_SERIALKEYSOPTIONS DIALOGEX 0, 0, 246, 220 @@ -282,10 +290,10 @@ STRINGTABLE BEGIN IDS_CPLSYSTEMNAME "Možnosti usnadnění" IDS_CPLSYSTEMDESCRIPTION "Upraví možnosti usnadnění pro tento počítač." - IDS_SENTRY_NONE "[None]" - IDS_SENTRY_TITLE "Flash the titlebar" - IDS_SENTRY_WINDOW "Flash the active window" - IDS_SENTRY_DISPLAY "Flash the desktop" - IDS_SECONDS "Seconds" - IDS_MINUTES "Minutes" + IDS_SENTRY_NONE "[Žádné]" + IDS_SENTRY_TITLE "Zablikat horní lištou" + IDS_SENTRY_WINDOW "Zablikat aktivním oknem" + IDS_SENTRY_DISPLAY "Zablikat plochou" + IDS_SECONDS "sekund" + IDS_MINUTES "minut" END diff --git a/dll/cpl/appwiz/CMakeLists.txt b/dll/cpl/appwiz/CMakeLists.txt index a10165acfc1fd..97fe0704950a9 100644 --- a/dll/cpl/appwiz/CMakeLists.txt +++ b/dll/cpl/appwiz/CMakeLists.txt @@ -2,8 +2,7 @@ remove_definitions(-D_WIN32_WINNT=0x502) add_definitions(-D_WIN32_WINNT=0x600) -add_definitions(-D__WINESRC__ -D_CRT_DECLARE_NONSTDC_NAMES=1) -include_directories(BEFORE ${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) +add_definitions(-D_CRT_DECLARE_NONSTDC_NAMES=1) spec2def(appwiz.cpl appwiz.spec) list(APPEND SOURCE @@ -27,3 +26,4 @@ add_delay_importlibs(appwiz msi) add_importlibs(appwiz urlmon ole32 comctl32 advapi32 shell32 shlwapi user32 msvcrt kernel32 ntdll) add_pch(appwiz appwiz.h SOURCE) add_cd_file(TARGET appwiz DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(appwiz) # CORE-5743: No CONST_VTABLE diff --git a/dll/cpl/appwiz/createlink.c b/dll/cpl/appwiz/createlink.c index 768bdbcebd011..cfb3e820f3149 100644 --- a/dll/cpl/appwiz/createlink.c +++ b/dll/cpl/appwiz/createlink.c @@ -489,6 +489,9 @@ FinishDlgProc(HWND hwndDlg, PathRemoveExtensionW(pContext->szLinkName); PathAddExtensionW(pContext->szLinkName, L".lnk"); + /* Don't set a comment */ + pContext->szDescription[0] = UNICODE_NULL; + if (!CreateShortcut(pContext)) { WCHAR szMessage[128]; diff --git a/dll/cpl/console/console.rc b/dll/cpl/console/console.rc index 8143555c8056b..74e1f7b279c22 100644 --- a/dll/cpl/console/console.rc +++ b/dll/cpl/console/console.rc @@ -12,6 +12,8 @@ #include "resource.h" +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL + #define REACTOS_VERSION_DLL #define REACTOS_STR_FILE_DESCRIPTION "ReactOS Control Panel Console Applet" #define REACTOS_STR_INTERNAL_NAME "console" @@ -22,8 +24,6 @@ IDC_CPLICON ICON "res/terminal.ico" #include -LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL - /* UTF-8 */ #pragma code_page(65001) diff --git a/dll/cpl/console/font.c b/dll/cpl/console/font.c index 888375924bb19..138e205c2e6e8 100644 --- a/dll/cpl/console/font.c +++ b/dll/cpl/console/font.c @@ -225,7 +225,7 @@ FontSizeList_GetSelectedFontSize( /* * The user just selected an existing size, read the ComboBox selection. * - * See: https://support.microsoft.com/en-us/help/66365/how-to-process-a-cbn-selchange-notification-message + * See: https://support.microsoft.com/en-us/help/66365/how-to-process-a-cbn-selchange-notification-message (DEAD_LINK) * for more details. */ INT Length; diff --git a/dll/cpl/console/lang/ro-RO.rc b/dll/cpl/console/lang/ro-RO.rc index 0fa6fd79d65e2..fc60aff96f3f3 100644 --- a/dll/cpl/console/lang/ro-RO.rc +++ b/dll/cpl/console/lang/ro-RO.rc @@ -14,27 +14,27 @@ STYLE DS_SHELLFONT | WS_CHILD | WS_CAPTION CAPTION "Opțiuni" FONT 8, "MS Shell Dlg" BEGIN - GROUPBOX "Dimensiune cursor", IDC_STATIC, 7, 7, 120, 70, WS_CHILD | WS_VISIBLE | WS_GROUP - AUTORADIOBUTTON "Red&usă", IDC_RADIO_SMALL_CURSOR, 15, 20, 90, 10, WS_CHILD | WS_VISIBLE | WS_TABSTOP - AUTORADIOBUTTON "Me&die", IDC_RADIO_MEDIUM_CURSOR, 15, 40, 90, 10, WS_CHILD | WS_VISIBLE | WS_TABSTOP - AUTORADIOBUTTON "&Mărită", IDC_RADIO_LARGE_CURSOR, 15, 60, 90, 10, WS_CHILD | WS_VISIBLE | WS_TABSTOP - GROUPBOX "Mod de afișare", IDC_STATIC, 133, 7, 112, 70, WS_CHILD | WS_VISIBLE | WS_GROUP - AUTORADIOBUTTON "În fere&astră", IDC_RADIO_DISPLAY_WINDOW, 142, 20, 70, 10, WS_CHILD | WS_VISIBLE | WS_TABSTOP - AUTORADIOBUTTON "Pe t&ot ecranul", IDC_RADIO_DISPLAY_FULL, 142, 40, 70, 10, WS_CHILD | WS_VISIBLE | WS_TABSTOP - GROUPBOX "Istoric pentru comenzi", IDC_STATIC, 7, 85, 120, 77, WS_CHILD | WS_VISIBLE | WS_GROUP - LTEXT "Ma&xim înregistrări:", IDC_STATIC, 14, 101, 70, 12 + GROUPBOX "Dimensiunea cursorului", IDC_STATIC, 7, 7, 120, 70, WS_CHILD | WS_VISIBLE | WS_GROUP + AUTORADIOBUTTON "&Mică", IDC_RADIO_SMALL_CURSOR, 15, 20, 90, 10, WS_CHILD | WS_VISIBLE | WS_TABSTOP + AUTORADIOBUTTON "M&edie", IDC_RADIO_MEDIUM_CURSOR, 15, 40, 90, 10, WS_CHILD | WS_VISIBLE | WS_TABSTOP + AUTORADIOBUTTON "M&are", IDC_RADIO_LARGE_CURSOR, 15, 60, 90, 10, WS_CHILD | WS_VISIBLE | WS_TABSTOP + GROUPBOX "Opțiuni de afișare", IDC_STATIC, 133, 7, 112, 70, WS_CHILD | WS_VISIBLE | WS_GROUP + AUTORADIOBUTTON "&Fereastră", IDC_RADIO_DISPLAY_WINDOW, 142, 20, 70, 10, WS_CHILD | WS_VISIBLE | WS_TABSTOP + AUTORADIOBUTTON "E&cran complet", IDC_RADIO_DISPLAY_FULL, 142, 40, 70, 10, WS_CHILD | WS_VISIBLE | WS_TABSTOP + GROUPBOX "Istoricul comenzilor", IDC_STATIC, 7, 85, 120, 77, WS_CHILD | WS_VISIBLE | WS_GROUP + LTEXT "&Dimensiune tampon:", IDC_STATIC, 14, 101, 70, 12 EDITTEXT IDC_EDIT_BUFFER_SIZE, 90, 97, 30, 15, ES_RIGHT | ES_NUMBER | WS_GROUP CONTROL "", IDC_UPDOWN_BUFFER_SIZE, UPDOWN_CLASS, UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | WS_GROUP, 119, 97, 12, 15 - LTEXT "&Cantitate registre:", IDC_STATIC, 14, 124, 70, 12 + LTEXT "&Număr tampoane:", IDC_STATIC, 14, 124, 70, 12 EDITTEXT IDC_EDIT_NUM_BUFFER, 90, 120, 30, 15, ES_RIGHT | ES_NUMBER | WS_GROUP CONTROL "", IDC_UPDOWN_NUM_BUFFER, UPDOWN_CLASS, UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | WS_GROUP, 119, 120, 12, 15 - AUTOCHECKBOX "Înlătură duplicatele &vechi", IDC_CHECK_DISCARD_DUPLICATES, 12, 140, 110, 15 + AUTOCHECKBOX "Anulare a duplicatelor &vechi", IDC_CHECK_DISCARD_DUPLICATES, 12, 140, 110, 15 GROUPBOX "Opțiuni de editare", IDC_STATIC, 133, 85, 112, 77, BS_GROUPBOX | WS_CHILD | WS_VISIBLE | WS_GROUP - AUTOCHECKBOX "Mod de &editare rapidă", IDC_CHECK_QUICK_EDIT, 140, 97, 102, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP - AUTOCHECKBOX "Mod de inse&rție", IDC_CHECK_INSERT_MODE, 140, 113, 76, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP - GROUPBOX "Cod de pagină", IDC_STATIC, 7, 170, 238, 31 + AUTOCHECKBOX "M&odul de editare rapidă", IDC_CHECK_QUICK_EDIT, 140, 97, 102, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP + AUTOCHECKBOX "Modul de inse&rare", IDC_CHECK_INSERT_MODE, 140, 113, 76, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP + GROUPBOX "Pagina de cod", IDC_STATIC, 7, 170, 238, 31 COMBOBOX IDL_CODEPAGE, 13, 181, 224, 58, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP END @@ -43,15 +43,15 @@ STYLE DS_SHELLFONT | WS_CHILD | WS_CAPTION CAPTION "Font" FONT 8, "MS Shell Dlg" BEGIN - LTEXT "Previzionare:", IDC_STATIC, 7, 7, 115, 10 + LTEXT "Previzionare a ferestrei:", IDC_STATIC, 7, 7, 115, 10 CONTROL "", IDC_STATIC_FONT_WINDOW_PREVIEW, "WinPreview", WS_BORDER | WS_CHILD | WS_VISIBLE, 7, 20, 115, 70 LTEXT "Mărime:", IDC_STATIC, 130, 7, 45, 10 LISTBOX IDC_LBOX_FONTSIZE, 130, 20, 50, 86, LBS_SORT | LBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_CBOX_FONTSIZE, 130, 20, 30, 86, CBS_SIMPLE | CBS_SORT | WS_VSCROLL | WS_TABSTOP AUTORADIOBUTTON "pi&xeli", IDC_RADIO_PIXEL_UNIT, 165, 17, 60, 10, WS_CHILD | WS_VISIBLE | WS_TABSTOP - AUTORADIOBUTTON "p&uncte", IDC_RADIO_POINT_UNIT, 165, 28, 60, 10, WS_CHILD | WS_VISIBLE | WS_TABSTOP - LTEXT "F&ont:", IDC_STATIC, 10, 105, 33, 10 - AUTOCHECKBOX "&Aldin", IDC_CHECK_BOLD_FONTS, 56, 105, 60, 10 + AUTORADIOBUTTON "&puncte", IDC_RADIO_POINT_UNIT, 165, 28, 60, 10, WS_CHILD | WS_VISIBLE | WS_TABSTOP + LTEXT "&Font:", IDC_STATIC, 10, 105, 33, 10 + AUTOCHECKBOX "Fonturi &aldine", IDC_CHECK_BOLD_FONTS, 56, 105, 60, 10 LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP GROUPBOX "Font selectat", IDC_GROUPBOX_FONT_NAME, 7, 156, 240, 50 CONTROL "", IDC_STATIC_SELECT_FONT_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 12, 166, 104, 35, WS_EX_CLIENTEDGE @@ -66,11 +66,11 @@ STYLE DS_SHELLFONT | WS_CHILD | WS_CAPTION CAPTION "Aspect" FONT 8, "MS Shell Dlg" BEGIN - LTEXT "Previzionare:", IDC_STATIC, 7, 7, 115, 10 + LTEXT "Previzionare a ferestrei:", IDC_STATIC, 7, 7, 115, 10 CONTROL "", IDC_STATIC_LAYOUT_WINDOW_PREVIEW, "WinPreview", WS_BORDER | WS_CHILD | WS_VISIBLE, 7, 20, 115, 70 - GROUPBOX "Dimensiunea textului", IDC_STATIC, 130, 12, 115, 50 - LTEXT "&Coloane:", IDC_STATIC, 140, 28, 40, 10 - LTEXT "&Rânduri:", IDC_STATIC, 140, 46, 39, 10 + GROUPBOX "Dimensiunea tamponului de ecran", IDC_STATIC, 130, 12, 115, 50 + LTEXT "&Lăţime:", IDC_STATIC, 140, 28, 40, 10 + LTEXT "&Înălțime:", IDC_STATIC, 140, 46, 39, 10 EDITTEXT IDC_EDIT_SCREEN_BUFFER_WIDTH, 203, 25, 35, 14, ES_RIGHT | ES_NUMBER | WS_GROUP CONTROL "", IDC_UPDOWN_SCREEN_BUFFER_WIDTH, UPDOWN_CLASS, UDS_NOTHOUSANDS | UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | WS_GROUP, 238, 25, 13, 14 @@ -78,8 +78,8 @@ BEGIN CONTROL "", IDC_UPDOWN_SCREEN_BUFFER_HEIGHT, UPDOWN_CLASS, UDS_NOTHOUSANDS | UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | WS_GROUP, 238, 42, 13, 14 GROUPBOX "Dimensiunea ferestrei", IDC_STATIC, 130, 65, 115, 47 - LTEXT "C&oloane:", IDC_STATIC, 140, 78, 39, 10 - LTEXT "Rân&duri:", IDC_STATIC, 140, 95, 37, 10 + LTEXT "Lăți&me:", IDC_STATIC, 140, 78, 39, 10 + LTEXT "Î&nălțime:", IDC_STATIC, 140, 95, 37, 10 EDITTEXT IDC_EDIT_WINDOW_SIZE_WIDTH, 203, 75, 35, 14, ES_RIGHT | ES_NUMBER | WS_GROUP CONTROL "", IDC_UPDOWN_WINDOW_SIZE_WIDTH, UPDOWN_CLASS, UDS_NOTHOUSANDS | UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | WS_GROUP, 238, 75, 13, 14 @@ -95,7 +95,7 @@ BEGIN EDITTEXT IDC_EDIT_WINDOW_POS_TOP, 203, 146, 35, 14, ES_RIGHT | ES_NUMBER | WS_GROUP CONTROL "", IDC_UPDOWN_WINDOW_POS_TOP, UPDOWN_CLASS, UDS_NOTHOUSANDS | UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | WS_GROUP, 238, 146, 13, 14 - AUTOCHECKBOX "Po&ziționat de sistem", IDC_CHECK_SYSTEM_POS_WINDOW, 137, 165, 104, 10 + AUTOCHECKBOX "Fereastră po&ziționată de sist.", IDC_CHECK_SYSTEM_POS_WINDOW, 137, 165, 104, 10 END IDD_PROPPAGECOLORS DIALOGEX 0, 0, 253, 220 @@ -103,11 +103,11 @@ STYLE DS_SHELLFONT | WS_CHILD | WS_CAPTION CAPTION "Culori" FONT 8, "MS Shell Dlg" BEGIN - AUTORADIOBUTTON "T&ext ecran", IDC_RADIO_SCREEN_TEXT, 10, 12, 112, 10, WS_CHILD | WS_VISIBLE | WS_TABSTOP - AUTORADIOBUTTON "F&undal ecran", IDC_RADIO_SCREEN_BACKGROUND, 10, 30, 112, 10, WS_CHILD | WS_VISIBLE | WS_TABSTOP - AUTORADIOBUTTON "Te&xt ferestre popup", IDC_RADIO_POPUP_TEXT, 10, 48, 112, 10, WS_CHILD | WS_VISIBLE | WS_TABSTOP - AUTORADIOBUTTON "Fun&dal ferestre popup", IDC_RADIO_POPUP_BACKGROUND, 10, 67, 112, 10, WS_CHILD | WS_VISIBLE | WS_TABSTOP - GROUPBOX "Paleta culorii selectate:", IDC_STATIC, 129, 7, 118, 73 + AUTORADIOBUTTON "&Textul ecranului", IDC_RADIO_SCREEN_TEXT, 10, 12, 112, 10, WS_CHILD | WS_VISIBLE | WS_TABSTOP + AUTORADIOBUTTON "&Fundalul ecranului", IDC_RADIO_SCREEN_BACKGROUND, 10, 30, 112, 10, WS_CHILD | WS_VISIBLE | WS_TABSTOP + AUTORADIOBUTTON "Te&xtul ferestrelor popup", IDC_RADIO_POPUP_TEXT, 10, 48, 112, 10, WS_CHILD | WS_VISIBLE | WS_TABSTOP + AUTORADIOBUTTON "F&undalul ferestrelor popup", IDC_RADIO_POPUP_BACKGROUND, 10, 67, 112, 10, WS_CHILD | WS_VISIBLE | WS_TABSTOP + GROUPBOX "Componentele de culoare selectate", IDC_STATIC, 129, 7, 118, 73 LTEXT "&Roșu:", IDC_STATIC, 140, 25, 48, 10 EDITTEXT IDC_EDIT_COLOR_RED, 210, 22, 30, 14, ES_RIGHT | ES_NUMBER | WS_GROUP CONTROL "", IDC_UPDOWN_COLOR_RED, UPDOWN_CLASS, UDS_SETBUDDYINT | UDS_ALIGNRIGHT | @@ -144,20 +144,20 @@ END IDD_APPLYOPTIONS DIALOGEX 0, 0, 220, 79 STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION -CAPTION "Aplicare proprietăți" +CAPTION "Aplicare a proprietăților" FONT 8, "MS Shell Dlg" BEGIN - AUTORADIOBUTTON "&Doar pentru această fereastră", IDC_RADIO_APPLY_CURRENT, 12, 12, 207, 10, WS_CHILD | WS_VISIBLE | WS_TABSTOP - AUTORADIOBUTTON "&Pentru toate ferestrele cu acest titlu", IDC_RADIO_APPLY_ALL, 12, 31, 207, 10, WS_CHILD | WS_VISIBLE | WS_TABSTOP - PUSHBUTTON "Con&firmă", IDOK, 58, 58, 50, 14, WS_VISIBLE - PUSHBUTTON "A&nulează", IDCANCEL, 114, 58, 50, 14, WS_VISIBLE + AUTORADIOBUTTON "&Aplicare a proprietăților doar pentru festrele curente", IDC_RADIO_APPLY_CURRENT, 12, 12, 207, 10, WS_CHILD | WS_VISIBLE | WS_TABSTOP + AUTORADIOBUTTON "&Salvare proprietăți pentru ferestrele viitoare cu același titlu", IDC_RADIO_APPLY_ALL, 12, 31, 207, 10, WS_CHILD | WS_VISIBLE | WS_TABSTOP + PUSHBUTTON "OK", IDOK, 58, 58, 50, 14, WS_VISIBLE + PUSHBUTTON "Revocare", IDCANCEL, 114, 58, 50, 14, WS_VISIBLE END STRINGTABLE BEGIN - IDS_CPLNAME "Linie de comandă" - IDS_CPLDESCRIPTION "Configurarea proprietăților pentru programe linie de comandă." - IDS_APPLY_SHORTCUT_ALL "Modifică scurtătura care a pornit aplicația" - IDS_RASTERFONTS "Fonturi rastre" - IDS_GROUPBOX_FONT_NAME "Font selectat: " + IDS_CPLNAME "Consolă" + IDS_CPLDESCRIPTION "Configurează proprietățile pentru consolă." + IDS_APPLY_SHORTCUT_ALL "Modifică &scurtătura care a pornit această aplicație" + IDS_RASTERFONTS "Fonturi raster" + IDS_GROUPBOX_FONT_NAME "Fontul selectat: " END diff --git a/dll/cpl/desk/background.c b/dll/cpl/desk/background.c index 931ef142c5e5f..6079d67ee89b5 100644 --- a/dll/cpl/desk/background.c +++ b/dll/cpl/desk/background.c @@ -155,6 +155,9 @@ GdipGetSupportedFileExtensions(VOID) for (i = 0; i < num; ++i) { + if (!lstrcmpiW(codecInfo[i].FilenameExtension, L"*.ico")) + continue; + StringCbCatW(lpBuffer, size, codecInfo[i].FilenameExtension); if (i < (num - 1)) { diff --git a/dll/cpl/desk/lang/ro-RO.rc b/dll/cpl/desk/lang/ro-RO.rc index 71b08e302706a..c2e69adbbdc5d 100644 --- a/dll/cpl/desk/lang/ro-RO.rc +++ b/dll/cpl/desk/lang/ro-RO.rc @@ -10,15 +10,15 @@ LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL IDD_THEMES DIALOGEX 0, 0, 246, 210 -CAPTION "Themes" +CAPTION "Teme" STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION FONT 8, "MS Shell Dlg" BEGIN LTEXT "O temă este un fundal plus un set de sunete, pictograme şi alte elemente care vă ajută să vă personalizaţi computerul cu un singur clic.", IDC_STATIC, 5, 5, 235, 30 LTEXT "&Temă:", IDC_STATIC, 5, 42, 55, 10 COMBOBOX IDC_THEMES_COMBOBOX, 5, 52, 160, 300, CBS_HASSTRINGS | CBS_AUTOHSCROLL | CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Salvează &ca…", IDC_THEMES_SAVE_AS, 170, 52, 70, 14 - PUSHBUTTON "Şt&erge", IDC_THEMES_DELETE, 170, 70, 70, 14 + PUSHBUTTON "Salvare &ca…", IDC_THEMES_SAVE_AS, 170, 52, 70, 14 + PUSHBUTTON "Şt&ergere", IDC_THEMES_DELETE, 170, 70, 70, 14 CONTROL "", IDC_THEMES_PREVIEW, "STATIC", SS_BITMAP, 5, 90, 235, 115, WS_EX_CLIENTEDGE END @@ -30,32 +30,32 @@ BEGIN CONTROL "", IDC_BACKGROUND_PREVIEW, "Static", SS_OWNERDRAW, 70, 10, 105, 74 CONTROL "", IDC_BACKGROUND_LIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_NOCOLUMNHEADER | LVS_SHAREIMAGELISTS | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP, 8, 104, 174, 86 - LTEXT "Selectaţi o imagine pentru a o folosi ca fundal de desktop:", IDC_STATIC, 8, 93, 230, 9//FIXME: add accel. I used "I&magine pentru a o folosi ca decor de birou:" for the backport - PUSHBUTTON "Spe&cificare…", IDC_BROWSE_BUTTON, 188, 104, 55, 15 - PUSHBUTTON "C&uloare…", IDC_COLOR_BUTTON, 188, 167, 55, 15 - LTEXT "Poziţie:", IDC_STATIC, 188, 128, 55, 9//FIXME: add accel. I used "&Poziţie:" for the backport + LTEXT "&Selectaţi o imagine pentru a o folosi ca fundal de desktop:", IDC_STATIC, 8, 93, 230, 9 + PUSHBUTTON "&Răsfoire…", IDC_BROWSE_BUTTON, 188, 104, 55, 15 + PUSHBUTTON "&Culoare…", IDC_COLOR_BUTTON, 188, 167, 55, 15 + LTEXT "&Poziţie:", IDC_STATIC, 188, 128, 55, 9 COMBOBOX IDC_PLACEMENT_COMBO, 188, 139, 55, 54, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Personalizează &desktopul...", IDC_DESKTOP_CUSTOM, 8, 194, 90, 15 + PUSHBUTTON "Personalizare a &desktopului...", IDC_DESKTOP_CUSTOM, 8, 194, 90, 15 END IDD_SCREENSAVER DIALOGEX 0, 0, 246, 202 STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION -CAPTION "Regim de inactivitate" +CAPTION "Economizor de ecran" FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_SCREENS_PREVIEW, "Static", SS_OWNERDRAW, 70, 10, 105, 74 - GROUPBOX "P&rotector de ecran", IDC_SCREENS_DUMMY, 8, 92, 230, 52//FIXME: accelerator collision &R. I decided to use &P here for the backport to fix that + GROUPBOX "&Economizor de ecran", IDC_SCREENS_DUMMY, 8, 92, 230, 52 COMBOBOX IDC_SCREENS_LIST, 14, 103, 100, 100, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "&Setări", IDC_SCREENS_SETTINGS, 120, 102, 50, 15, WS_GROUP PUSHBUTTON "Pre&vizionare", IDC_SCREENS_TESTSC, 175, 102, 50, 15 - LTEXT "În vigoare &după", IDC_WAITTEXT, 14, 125, 54, 9 + LTEXT "Se &așteaptă", IDC_WAITTEXT, 14, 125, 54, 9 EDITTEXT IDC_SCREENS_TIMEDELAY, 68, 123, 32, 13, ES_RIGHT | WS_GROUP CONTROL "", IDC_SCREENS_TIME, UPDOWN_CLASS, UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | WS_BORDER | WS_GROUP, 88, 123, 12, 13 LTEXT "minute", IDC_MINTEXT, 102, 125, 23, 9 - AUTOCHECKBOX "Solicită pa&rolă la revenire", IDC_SCREENS_USEPASSCHK, 129, 120, 96, 19//FIXME: accelerator collision &R - GROUPBOX "Mecanisme de gestiune a consumului", IDC_SCREENS_DUMMY2, 8, 150, 230, 41 - LTEXT "Pentru a ajusta setările de alimentare ale monitorului dvs., apăsaţi pe Setări de alimentare.", IDC_STATIC, 16, 161, 146, 27 + AUTOCHECKBOX "Solicitare a pa&rolei la revenire", IDC_SCREENS_USEPASSCHK, 129, 120, 96, 19 + GROUPBOX "Caracteristicile de economisire a energiei ale monitorului", IDC_SCREENS_DUMMY2, 8, 150, 230, 41 + LTEXT "Pentru a regla setările de alimentare pentru monitor, faceți clic pe Setări de alimentare.", IDC_STATIC, 16, 161, 146, 27 PUSHBUTTON "Ali&mentare…", IDC_SCREENS_POWER_BUTTON, 167, 165, 61, 15 END @@ -65,48 +65,48 @@ CAPTION "Aspect" FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_APPEARANCE_PREVIEW, "PreviewWndClass", WS_VISIBLE | WS_BORDER, 7, 7, 232, 120 - LTEXT "Stil vizual:", IDC_STATIC, 7, 130, 104, 9//FIXME: add accel. I used "&Stil vizual:" for the backport + LTEXT "Stil &vizual:", IDC_STATIC, 7, 130, 104, 9 COMBOBOX IDC_APPEARANCE_VISUAL_STYLE, 7, 140, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Colorit:", IDC_STATIC, 7, 157, 104, 9//FIXME: add accel. I used "&Colorit:" for the backport + LTEXT "Schemă de &culori", IDC_STATIC, 7, 157, 104, 9 COMBOBOX IDC_APPEARANCE_COLORSCHEME, 7, 167, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Dimensiune:", IDC_STATIC, 7, 184, 104, 9//FIXME: add accel. I used "&Dimensiune:" for the backport + LTEXT "&Dimensiune a fontului:", IDC_STATIC, 7, 184, 104, 9 COMBOBOX IDC_APPEARANCE_SIZE, 7, 194, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "&Efecte…", IDC_APPEARANCE_EFFECTS, 182, 150, 56, 15 - PUSHBUTTON "A&vansate…", IDC_APPEARANCE_ADVANCED, 182, 170, 56, 15 + PUSHBUTTON "&Complex…", IDC_APPEARANCE_ADVANCED, 182, 170, 56, 15 END IDD_ADVAPPEARANCE DIALOGEX 0, 0, 250, 239 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE -CAPTION "Setări avansate" +CAPTION "Aspect complex" FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_APPEARANCE_PREVIEW, "PreviewWndClass", WS_VISIBLE | WS_BORDER, 7, 7, 232, 120 - LTEXT "Dacă selectaţi o temă alta decât ReactOS clasic, va suprascrie următoarele setări, cu excepţia unor programe mai vechi.", IDC_ADVAPPEARANCE_DISCLAIMER, 7, 133, 232, 30, BS_MULTILINE + LTEXT "Dacă selectați o altă temă decât ReactOS clasic, aceasta va înlocui următoarele setări, cu excepția unor programe mai vechi.", IDC_ADVAPPEARANCE_DISCLAIMER, 7, 133, 232, 30, BS_MULTILINE LTEXT "&Element", 8, 5, 160, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_ELEMENT, 5, 170, 130, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "&Mărime", IDC_ADVAPPEARANCE_SIZE_T, 142, 160, 39, 9 + LTEXT "&Dimensiune", IDC_ADVAPPEARANCE_SIZE_T, 142, 160, 39, 9 EDITTEXT IDC_ADVAPPEARANCE_SIZE_E, 142, 170, 38, 13, ES_RIGHT | WS_GROUP CONTROL "", IDC_ADVAPPEARANCE_SIZE_UD, UPDOWN_CLASS, UDS_AUTOBUDDY | WS_BORDER | WS_GROUP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_SETBUDDYINT | WS_CHILD | WS_VISIBLE, 172, 170, 10, 13 - LTEXT "Culoare &1", IDC_ADVAPPEARANCE_COLOR1_T, 184, 160, 40, 9 + LTEXT "Culoarea &1", IDC_ADVAPPEARANCE_COLOR1_T, 184, 160, 40, 9 CHECKBOX "-", IDC_ADVAPPEARANCE_COLOR1_B, 184, 170, 28, 13, BS_PUSHLIKE | BS_BITMAP - LTEXT "Culoare &2", IDC_ADVAPPEARANCE_COLOR2_T, 216, 160, 40, 9 + LTEXT "Culoarea &2", IDC_ADVAPPEARANCE_COLOR2_T, 216, 160, 40, 9 CHECKBOX "-", IDC_ADVAPPEARANCE_COLOR2_B, 216, 170, 28, 13, BS_PUSHLIKE | BS_BITMAP - LTEXT "F&ont", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 9 + LTEXT "&Tip caractere", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_FONT_C, 5, 200, 130, 90, CBS_DROPDOWN | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Mă&rime", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 9 + LTEXT "Di&mensiune", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 9 COMBOBOX IDC_ADVAPPEARANCE_FONTSIZE_E, 142, 200, 38, 200, CBS_DROPDOWN | WS_VSCROLL LTEXT "&Culoare", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 28, 9 CHECKBOX "", IDC_ADVAPPEARANCE_FONTCOLOR_B, 184, 200, 28, 13, BS_PUSHLIKE | BS_BITMAP AUTOCHECKBOX "A", IDC_ADVAPPEARANCE_FONTBOLD, 216, 200, 14, 13, BS_PUSHLIKE AUTOCHECKBOX "C", IDC_ADVAPPEARANCE_FONTITALIC, 230, 200, 14, 13, BS_PUSHLIKE - PUSHBUTTON "Anulare", IDCANCEL, 191, 220, 50, 14 + PUSHBUTTON "Revocare", IDCANCEL, 191, 220, 50, 14 DEFPUSHBUTTON "OK", IDOK, 137, 220, 50, 14 END @@ -116,18 +116,18 @@ EXSTYLE WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE CAPTION "Efecte vizuale" FONT 8, "MS Shell Dlg" BEGIN - AUTOCHECKBOX "Aplică &efect de tranziţie pentru meniuri şi ponturi:", IDC_EFFAPPEARANCE_ANIMATION, 10, 5, 267, 19 + AUTOCHECKBOX "&Utilizare a următorului efect de tranziție pentru meniuri și sfaturi cu instrumente:", IDC_EFFAPPEARANCE_ANIMATION, 10, 5, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_ANIMATIONTYPE, 20, 25, 95, 19, CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP - AUTOCHECKBOX "&Rotunjeşte marginile de text folosind metoda:", IDC_EFFAPPEARANCE_SMOOTHING, 10, 42, 267, 19 + AUTOCHECKBOX "&Folosire a următoarei metode pentru a netezi marginile fonturilor de pe ecran:", IDC_EFFAPPEARANCE_SMOOTHING, 10, 42, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_SMOOTHINGTYPE, 20, 62, 95, 19, CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP - AUTOCHECKBOX "&Pictograme mari", IDC_EFFAPPEARANCE_LARGEICONS, 10, 80, 267, 19, WS_TABSTOP | WS_DISABLED - AUTOCHECKBOX "Afişează &umbre sub meniuri", IDC_EFFAPPEARANCE_SETDROPSHADOW, 10, 95, 267, 19 - AUTOCHECKBOX "Afişează ferestrele şi în timpul &mişcării lor", IDC_EFFAPPEARANCE_DRAGFULLWINDOWS, 10, 110, 267, 19 - AUTOCHECKBOX "&Amână sublinierea literelor navigării din tastatură până la apăsarea tastei «Alt»", IDC_EFFAPPEARANCE_KEYBOARDCUES, 10, 125, 267, 19 - AUTOCHECKBOX "F&oloseşte meniuri plate", IDC_EFFAPPEARANCE_FLATMENUS, 10, 140, 267, 19 - PUSHBUTTON "Anulare", IDCANCEL, 226, 165, 50, 14 + AUTOCHECKBOX "Se folosesc &pictograme mari", IDC_EFFAPPEARANCE_LARGEICONS, 10, 80, 267, 19, WS_TABSTOP | WS_DISABLED + AUTOCHECKBOX "Afişare a &umbrelor sub meniuri", IDC_EFFAPPEARANCE_SETDROPSHADOW, 10, 95, 267, 19 + AUTOCHECKBOX "Afișare a conținutului &ferestrei în timpul tragerii", IDC_EFFAPPEARANCE_DRAGFULLWINDOWS, 10, 110, 267, 19 + AUTOCHECKBOX "&Ascunde litere subliniate pentru navigarea din tastatură până se apasă tasta Alt", IDC_EFFAPPEARANCE_KEYBOARDCUES, 10, 125, 267, 19 + AUTOCHECKBOX "F&olosire a meniurilor plate", IDC_EFFAPPEARANCE_FLATMENUS, 10, 140, 267, 19 + PUSHBUTTON "Revocare", IDCANCEL, 226, 165, 50, 14 DEFPUSHBUTTON "OK", IDOK, 172, 165, 50, 14 END @@ -137,20 +137,20 @@ CAPTION "Setări" FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_RESOLUTION_PREVIEW, "Static", SS_OWNERDRAW, 70, 10, 105, 74 - LTEXT "Trageţi pictogramele monitorului pentru a se potrivi cu aranjamentul fizic al monitoarelor dvs.", IDC_SETTINGS_MONTEXT, 3, 3, 240, 20 + LTEXT "Trageți pictogramele monitorului pentru a se potrivi cu aranjamentul fizic al monitoarelor", IDC_SETTINGS_MONTEXT, 3, 3, 240, 20 CONTROL "", IDC_SETTINGS_MONSEL, "MONITORSELWNDCLASS", WS_CHILD | WS_VISIBLE | WS_TABSTOP, 3, 23, 240, 82, WS_EX_CLIENTEDGE - LTEXT "&Dispozitive de afişare:", 1820, 3, 107, 75, 9 - LTEXT "", IDC_SETTINGS_DEVICE, 3, 116, 224, 9 - GROUPBOX "Re&zoluţie ecran", 1818, 3, 127, 115, 43 + LTEXT "&Afișare:", 1820, 3, 107, 75, 9 + LTEXT "", IDC_SETTINGS_DEVICE, 3, 116, 224, 9 + GROUPBOX "&Zona ecranului", 1818, 3, 127, 115, 43 CONTROL "", IDC_SETTINGS_RESOLUTION, "msctls_trackbar32", TBS_AUTOTICKS | WS_TABSTOP, 30, 137, 58, 17 - LTEXT "Mică", 1815, 9, 137, 25, 9, NOT WS_GROUP - LTEXT "Mare", 1816, 93, 137, 20, 9, NOT WS_GROUP + LTEXT "Minim", 1815, 9, 137, 25, 9, NOT WS_GROUP + LTEXT "Maxim", 1816, 93, 137, 20, 9, NOT WS_GROUP LTEXT "", IDC_SETTINGS_RESOLUTION_TEXT, 10, 157, 100, 10, NOT WS_GROUP | SS_CENTER - GROUPBOX "Amplitudine &culoare", 1817, 125, 127, 115, 43 + GROUPBOX "&Culori", 1817, 125, 127, 115, 43 COMBOBOX IDC_SETTINGS_BPP, 131, 137, 103, 80, CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP CONTROL "", IDC_SETTINGS_SPECTRUM, "Static", SS_OWNERDRAW | SS_SUNKEN, 131, 155, 103, 9 - PUSHBUTTON "A&vansate…", IDC_SETTINGS_ADVANCED, 170, 174, 70, 15 + PUSHBUTTON "C&omplex…", IDC_SETTINGS_ADVANCED, 170, 174, 70, 15 END IDD_DESKTOP_GENERAL DIALOGEX 0, 0, 293, 202 @@ -159,31 +159,31 @@ CAPTION "General" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Pictograme de desktop", IDC_STATIC, 6, 4, 212, 40 - AUTOCHECKBOX "&Documente", IDC_ICONS_MYDOCS, 14, 14, 100, 12 - AUTOCHECKBOX "Locurile din &reţeaua mea", IDC_ICONS_MYNET, 116, 14, 100, 12//FIXME: accelerator collision &R + AUTOCHECKBOX "&Documentele mele", IDC_ICONS_MYDOCS, 14, 14, 100, 12 + AUTOCHECKBOX "&Locațiile din reţeaua mea", IDC_ICONS_MYNET, 116, 14, 100, 12 AUTOCHECKBOX "&Computerul meu", IDC_ICONS_MYCOMP, 14, 28, 100, 12 AUTOCHECKBOX "&Navigatorul de Internet", IDC_ICONS_INTERNET, 116, 28, 100, 12 CONTROL "", IDC_ICONS_LISTVIEW, "SysListView32", LVS_ICON | LVS_ALIGNLEFT | LVS_AUTOARRANGE | LVS_SINGLESEL | WS_BORDER | WS_TABSTOP | WS_HSCROLL, 6, 60, 251, 54 - PUSHBUTTON "&Schimbă pictograma...", IDC_ICONS_CHANGEICON, 70, 120, 80, 15 - PUSHBUTTON "&Restabileşte valorile implicite", IDC_ICONS_SETDEFAULT, 154, 120, 103, 15//FIXME: accelerator collision &R + PUSHBUTTON "&Modificare pictogramă…", IDC_ICONS_CHANGEICON, 70, 120, 80, 15 + PUSHBUTTON "R&estabilire valori implicite", IDC_ICONS_SETDEFAULT, 154, 120, 103, 15 END IDD_ADVANCED_GENERAL DIALOGEX 0, 0, 253, 204 STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION -CAPTION "Generale" +CAPTION "General" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Afişare", -1, 7, 6, 237, 56, WS_GROUP - LTEXT "Mărime font:", -1, 14, 20, 222, 9//FIXME: add accel. I used "&Mărime font:" for the backport. 2k3sp2 does now call this "&DPI setting:". Feel free to translate that. + LTEXT "Setare &DPI:", -1, 14, 20, 222, 9 COMBOBOX IDC_FONTSIZE_COMBO, 14, 30, 223, 80, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "", IDC_FONTSIZE_CUSTOM, 14, 46, 223, 12 GROUPBOX "Compatibilitate", -1, 7, 67, 237, 97 - LTEXT "Unele programe funcţionează necorespunzător dacă nu reporniţi computerul după ce modificaţi setările de culoare.\n\nDupă ce schimb setările de culoare", -1, 12, 78, 228, 34 - AUTORADIOBUTTON "&Reporneşte computerul înainte de a aplica noile setări de culoare", IDC_RESTART_RB, 14, 116, 228, 10 - AUTORADIOBUTTON "Aplică noua &setări de culoare fără a repornire", IDC_WITHOUTREBOOT_RB, 14, 131, 228, 10 - AUTORADIOBUTTON "Întreabă-mă înainte de a aplica noile setări de culoare", IDC_ASKME_RB, 14, 146, 228, 10//FIXME: add accel. I used "Î&ntreabă-mă înainte de a aplica noile setări" for the backport + LTEXT "Unele programe funcționează necorespunzător dacă nu reporniți computerul după ce modificați setările de culoare.\n\nDupă ce schimb setările de culoare", -1, 12, 78, 228, 34 + AUTORADIOBUTTON "Se &reporneşte computerul înainte de a aplica noile setări de culoare", IDC_RESTART_RB, 14, 116, 228, 10 + AUTORADIOBUTTON "Se aplică noile &setări de culoare fără repornire", IDC_WITHOUTREBOOT_RB, 14, 131, 228, 10 + AUTORADIOBUTTON "Î&ntreabă-mă înainte de a aplica noile setări de culoare", IDC_ASKME_RB, 14, 146, 228, 10 END IDD_CONFIRMSETTINGS DIALOGEX 20, 30, 233, 57 @@ -193,8 +193,8 @@ FONT 8, "MS Shell Dlg" BEGIN LTEXT "Doriţi să păstraţi aceste setări de afişare?", IDC_STATIC, 7, 7, 219, 8 LTEXT "", IDC_TIMEOUTTEXT, 7, 20, 219, 8 - PUSHBUTTON "D&a", IDYES, 121, 36, 50, 14 - DEFPUSHBUTTON "N&u", IDNO, 175, 36, 50, 14 + PUSHBUTTON "&Da", IDYES, 121, 36, 50, 14 + DEFPUSHBUTTON "&Nu", IDNO, 175, 36, 50, 14 END IDR_PREVIEW_MENU MENU @@ -211,7 +211,7 @@ BEGIN MENUITEM "&Ataşat", ID_MENU_ATTACHED MENUITEM "&Primar", ID_MENU_PRIMARY MENUITEM SEPARATOR - MENUITEM "I&dentificare", ID_MENU_IDENTIFY + MENUITEM "&Identificare", ID_MENU_IDENTIFY MENUITEM "P&roprietăţi", ID_MENU_PROPERTIES END END @@ -235,31 +235,31 @@ END STRINGTABLE BEGIN - IDS_MULTIPLEMONITORS "(monitoare multiple)" - IDS_UNKNOWNMONITOR "(monitor necunoscut)" - IDS_ADVANCEDTITLEFMT "%s cu %s" + IDS_MULTIPLEMONITORS "(Monitoare multiple)" + IDS_UNKNOWNMONITOR "(Monitor necunoscut)" + IDS_ADVANCEDTITLEFMT "%s și %s" END STRINGTABLE BEGIN - IDS_CPLNAME "Afişaj" - IDS_CPLDESCRIPTION "Personalizează afişajului desktopului şi al protectorului de ecran." - IDS_NONE "(nespecificată)" + IDS_CPLNAME "Afişare" + IDS_CPLDESCRIPTION "Personalizează afișarea desktopului și economizorului de ecran." + IDS_NONE "(Nimic)" IDS_CENTER "Centrat" IDS_STRETCH "Extins" - IDS_TILE "Tapiţat" - IDS_FIT "Potrivit" + IDS_TILE "Mozaic" + IDS_FIT "Potrivire" IDS_FILL "Umplere" END STRINGTABLE BEGIN - IDS_COLOR_4BIT "Joasă (4 biţi, 16 culori)" - IDS_COLOR_8BIT "Limitată (8 biţi, 256 culori)" - IDS_COLOR_16BIT "Înaltă (16 biţi, > 65k culori)" - IDS_COLOR_24BIT "Foto (24 biţi, > 16M culori)" - IDS_COLOR_32BIT "Maximă (32 biţi, > 16M culori)" - IDS_PIXEL "%lux%lu pixeli" + IDS_COLOR_4BIT "16 culori" + IDS_COLOR_8BIT "256 de culori" + IDS_COLOR_16BIT "Culori înalte (16 biți)" + IDS_COLOR_24BIT "Culori adevărate (24 de biți)" + IDS_COLOR_32BIT "Culori adevărate (32 de biți)" + IDS_PIXEL "%lux%lu (de) pixeli" END STRINGTABLE @@ -271,16 +271,16 @@ STRINGTABLE BEGIN IDS_INACTWIN "Fereastră inactivă" IDS_ACTWIN "Fereastră activă" - IDS_WINTEXT "Text în fereastră" - IDS_MESSBOX "Fereastră mesaj" - IDS_MESSTEXT "Text mesaj" - IDS_BUTTEXT "Î&nchide" - IDS_CLASSIC_THEME "Temă clasică" + IDS_WINTEXT "Textul ferestrei" + IDS_MESSBOX "Casetă de mesaje" + IDS_MESSTEXT "Casetă de mesaje" + IDS_BUTTEXT "OK" + IDS_CLASSIC_THEME "Tema clasică" END STRINGTABLE BEGIN - IDS_ELEMENT_0 "Fundal" + IDS_ELEMENT_0 "Desktop" IDS_ELEMENT_1 "Titlul ferestrelor inactive" IDS_ELEMENT_2 "Chenarul ferestrelor inactive" IDS_ELEMENT_3 "Titlul ferestrelor active" @@ -290,13 +290,13 @@ BEGIN IDS_ELEMENT_7 "Ferestre" IDS_ELEMENT_8 "Bare de defilare" IDS_ELEMENT_9 "Obiecte 3D" - IDS_ELEMENT_10 "Titlu paletă" - IDS_ELEMENT_11 "Bară de titlu" + IDS_ELEMENT_10 "Titlul paletei" + IDS_ELEMENT_11 "Butoane pentru bara de titlu" IDS_ELEMENT_12 "Fereastră de dialog" - IDS_ELEMENT_13 "Fundal aplicaţie" - IDS_ELEMENT_14 "Distanţă simbol (orizontal)" - IDS_ELEMENT_15 "Distanţă simbol (vertical)" - IDS_ELEMENT_16 "Pont" + IDS_ELEMENT_13 "Fundalul aplicaţiei" + IDS_ELEMENT_14 "Distanţa pictogramei (orizontală)" + IDS_ELEMENT_15 "Distanţa pictogramei (verticală)" + IDS_ELEMENT_16 "Informații rapide" IDS_ELEMENT_17 "Simbol" // IDS_ELEMENT_18 "Elemente de meniu dezactivate" END @@ -304,7 +304,7 @@ END STRINGTABLE BEGIN IDS_DISPLAY_SETTINGS "Setări de afişare" - IDS_APPLY_FAILED "Nu s-au putut aplica noile setări." - IDS_APPLY_NEEDS_RESTART "Trebuie să reporniţi computerul înainte să aplicaţi noile setări." + IDS_APPLY_FAILED "Imposibil de aplicat noile setări…" + IDS_APPLY_NEEDS_RESTART "Trebuie să reporniți computerul pentru a aplica modificările." IDS_TIMEOUTTEXT "Revenire la setările anterioare în %d secunde." END diff --git a/dll/cpl/desk/theme.c b/dll/cpl/desk/theme.c index 8c9f9faa8e4ab..ac3eb839457db 100644 --- a/dll/cpl/desk/theme.c +++ b/dll/cpl/desk/theme.c @@ -140,7 +140,7 @@ LoadCurrentScheme(OUT COLOR_SCHEME *scheme) #if (WINVER >= 0x0600) /* Size of NONCLIENTMETRICSA/W depends on current version of the OS. * see: - * https://msdn.microsoft.com/en-us/library/windows/desktop/ff729175%28v=vs.85%29.aspx + * https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-nonclientmetricsa */ if (GetVersionEx(&osvi)) { diff --git a/dll/cpl/inetcpl/CMakeLists.txt b/dll/cpl/inetcpl/CMakeLists.txt index 09293f3393d5d..ff1bff5a81167 100644 --- a/dll/cpl/inetcpl/CMakeLists.txt +++ b/dll/cpl/inetcpl/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(BEFORE ${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(inetcpl.cpl inetcpl.spec) list(APPEND SOURCE @@ -26,3 +24,4 @@ add_delay_importlibs(inetcpl cryptui wininet ole32 urlmon shell32) add_importlibs(inetcpl advapi32 comctl32 user32 shlwapi msvcrt kernel32 ntdll) add_pch(inetcpl precomp.h SOURCE) add_cd_file(TARGET inetcpl DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(inetcpl) # CORE-5743: No ARRAY_SIZE macro diff --git a/dll/cpl/inetcpl/inetcpl.rc b/dll/cpl/inetcpl/inetcpl.rc index 23f939ca7e9c5..3c4218072af09 100644 --- a/dll/cpl/inetcpl/inetcpl.rc +++ b/dll/cpl/inetcpl/inetcpl.rc @@ -21,7 +21,6 @@ #include "inetcpl.h" - #include /* UTF-8 */ diff --git a/dll/cpl/inetcpl/lang/He.rc b/dll/cpl/inetcpl/lang/He.rc index a320c602cd19d..af905ea975bdc 100644 --- a/dll/cpl/inetcpl/lang/He.rc +++ b/dll/cpl/inetcpl/lang/He.rc @@ -22,8 +22,6 @@ * */ -#pragma code_page(65001) - LANGUAGE LANG_HEBREW, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/cpl/inetcpl/lang/Sr.rc b/dll/cpl/inetcpl/lang/Sr.rc index c205f51c0191c..ffa8e14b5c681 100644 --- a/dll/cpl/inetcpl/lang/Sr.rc +++ b/dll/cpl/inetcpl/lang/Sr.rc @@ -20,8 +20,6 @@ * */ -#pragma code_page(65001) - LANGUAGE LANG_SERBIAN, SUBLANG_SERBIAN_CYRILLIC STRINGTABLE diff --git a/dll/cpl/inetcpl/lang/cs-CZ.rc b/dll/cpl/inetcpl/lang/cs-CZ.rc index 411a5d5607146..30bbcdcb62919 100644 --- a/dll/cpl/inetcpl/lang/cs-CZ.rc +++ b/dll/cpl/inetcpl/lang/cs-CZ.rc @@ -3,9 +3,6 @@ * UPDATED: 2014-04-21 */ - /* UTF-8 */ - #pragma code_page(65001) - LANGUAGE LANG_CZECH, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/cpl/inetcpl/lang/de-DE.rc b/dll/cpl/inetcpl/lang/de-DE.rc index 713072838260e..bc9132464bbd8 100644 --- a/dll/cpl/inetcpl/lang/de-DE.rc +++ b/dll/cpl/inetcpl/lang/de-DE.rc @@ -19,8 +19,6 @@ * */ -#pragma code_page(65001) - LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/cpl/inetcpl/lang/fr-FR.rc b/dll/cpl/inetcpl/lang/fr-FR.rc index 7f3f169456cca..b2d5a43314d33 100644 --- a/dll/cpl/inetcpl/lang/fr-FR.rc +++ b/dll/cpl/inetcpl/lang/fr-FR.rc @@ -20,9 +20,6 @@ * */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/cpl/inetcpl/lang/it-IT.rc b/dll/cpl/inetcpl/lang/it-IT.rc index 8193d19262e05..c5db21ad75e36 100644 --- a/dll/cpl/inetcpl/lang/it-IT.rc +++ b/dll/cpl/inetcpl/lang/it-IT.rc @@ -19,9 +19,6 @@ * */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/cpl/inetcpl/lang/ja-JP.rc b/dll/cpl/inetcpl/lang/ja-JP.rc index c50a0ef068e05..fdb15f7b1b3b6 100644 --- a/dll/cpl/inetcpl/lang/ja-JP.rc +++ b/dll/cpl/inetcpl/lang/ja-JP.rc @@ -20,9 +20,6 @@ * */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/cpl/inetcpl/lang/ko-KR.rc b/dll/cpl/inetcpl/lang/ko-KR.rc index 3032ba5ced12a..56200e37ae6a2 100644 --- a/dll/cpl/inetcpl/lang/ko-KR.rc +++ b/dll/cpl/inetcpl/lang/ko-KR.rc @@ -20,8 +20,6 @@ * */ -#pragma code_page(65001) - LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/cpl/inetcpl/lang/lt-LT.rc b/dll/cpl/inetcpl/lang/lt-LT.rc index d37d53cdf7dda..2abd4e32eba68 100644 --- a/dll/cpl/inetcpl/lang/lt-LT.rc +++ b/dll/cpl/inetcpl/lang/lt-LT.rc @@ -19,9 +19,6 @@ * */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_LITHUANIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/cpl/inetcpl/lang/pl-PL.rc b/dll/cpl/inetcpl/lang/pl-PL.rc index dbb04c95e6178..bfd6b32ebb797 100644 --- a/dll/cpl/inetcpl/lang/pl-PL.rc +++ b/dll/cpl/inetcpl/lang/pl-PL.rc @@ -19,9 +19,6 @@ * */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_POLISH, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/cpl/inetcpl/lang/pt-BR.rc b/dll/cpl/inetcpl/lang/pt-BR.rc index d8fc04bc5f219..71a4816e03377 100644 --- a/dll/cpl/inetcpl/lang/pt-BR.rc +++ b/dll/cpl/inetcpl/lang/pt-BR.rc @@ -19,8 +19,6 @@ * */ -#pragma code_page(65001) - LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN STRINGTABLE diff --git a/dll/cpl/inetcpl/lang/pt-PT.rc b/dll/cpl/inetcpl/lang/pt-PT.rc index 3b5c9191ca027..65f07cd267d4d 100644 --- a/dll/cpl/inetcpl/lang/pt-PT.rc +++ b/dll/cpl/inetcpl/lang/pt-PT.rc @@ -20,9 +20,6 @@ * */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_PORTUGUESE, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/cpl/inetcpl/lang/ru-RU.rc b/dll/cpl/inetcpl/lang/ru-RU.rc index 9a283ecc087a4..19b2870bda940 100644 --- a/dll/cpl/inetcpl/lang/ru-RU.rc +++ b/dll/cpl/inetcpl/lang/ru-RU.rc @@ -19,9 +19,6 @@ * */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/cpl/inetcpl/lang/sv-SE.rc b/dll/cpl/inetcpl/lang/sv-SE.rc index 60887d9a7bf4d..fd6779cc7e183 100644 --- a/dll/cpl/inetcpl/lang/sv-SE.rc +++ b/dll/cpl/inetcpl/lang/sv-SE.rc @@ -19,8 +19,6 @@ * */ -#pragma code_page(65001) - LANGUAGE LANG_SWEDISH, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/cpl/inetcpl/lang/tr-TR.rc b/dll/cpl/inetcpl/lang/tr-TR.rc index b8897f98a5227..24025e35808e0 100644 --- a/dll/cpl/inetcpl/lang/tr-TR.rc +++ b/dll/cpl/inetcpl/lang/tr-TR.rc @@ -19,9 +19,6 @@ * */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_TURKISH, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/cpl/inetcpl/lang/uk-UA.rc b/dll/cpl/inetcpl/lang/uk-UA.rc index debac95408d51..27925e9ec001b 100644 --- a/dll/cpl/inetcpl/lang/uk-UA.rc +++ b/dll/cpl/inetcpl/lang/uk-UA.rc @@ -20,9 +20,6 @@ * */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/cpl/input/lang/de-DE.rc b/dll/cpl/input/lang/de-DE.rc index 4e55706aa2646..05b53b3006514 100644 --- a/dll/cpl/input/lang/de-DE.rc +++ b/dll/cpl/input/lang/de-DE.rc @@ -1,3 +1,14 @@ +/* + * PROJECT: ReactOS Language Control Panel + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: German resource file + * TRANSLATORS: Copyright 2007-2014 Daniel Reimer + * Copyright 2008 Colin Finck + * Copyright 2008-2011 Matthias Kupfer + * Copyright 2010 Sven Knurr (tux.) + * Copyright 2024 Václav Zouzalík (Venca24) + */ + LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL IDD_PROPPAGESETTINGS DIALOGEX 0, 0, 254, 228 @@ -5,10 +16,10 @@ STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION CAPTION "Einstellungen" FONT 8, "MS Shell Dlg" BEGIN - GROUPBOX "Default input &language", -1, 5, 5, 246, 55 - LTEXT "Select one of the installed input languages to use when your computer starts.", -1, 15, 15, 230, 23 + GROUPBOX "&Standard-Eingabesprache", -1, 5, 5, 246, 55 + LTEXT "Wählen Sie eine der installierten Eingabesprachen aus, die beim Start Ihres Computers verwendet werden soll.", -1, 15, 15, 230, 23 COMBOBOX IDC_DEFAULT_LANGUAGE, 15, 40, 230, 300, CBS_HASSTRINGS | CBS_AUTOHSCROLL | CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - GROUPBOX "&Installed services", -1, 5, 65, 246, 125 + GROUPBOX "&Installierte Dienste", -1, 5, 65, 246, 125 LTEXT "Wählen Sie die Dienste aus, die Sie für die Eingabesprachen in der Liste verwenden wollen. Verwenden Sie ""Hinzufügen"" und ""Entfernen"", um die Liste zu bearbeiten.", -1, 15, 78, 230, 25 CONTROL "", IDC_KEYLAYOUT_LIST, "SysTreeView32", TVS_SHOWSELALWAYS | TVS_DISABLEDRAGDROP | WS_BORDER | WS_VSCROLL | WS_TABSTOP, 15, 105, 155, 80 PUSHBUTTON "&Hinzufügen...", IDC_ADD_BUTTON, 175, 105, 70, 14 @@ -110,7 +121,7 @@ BEGIN IDS_CTRL_SHIFT "Strg+Umschalt" IDS_LEFT_ALT_SHIFT "Alt links+Umschalt" IDS_SWITCH_BET_INLANG "Zwischen Eingabesprachen umschalten" - IDS_REBOOT_NOW "You have to restart the system for the settings to take effect. Reboot now?" + IDS_REBOOT_NOW "Damit die Einstellungen wirksam werden, müssen Sie das System neu starten. Jetzt neu starten?" END STRINGTABLE diff --git a/dll/cpl/sysdm/advanced.c b/dll/cpl/sysdm/advanced.c index ce8a594223592..4b8c0bd69296f 100644 --- a/dll/cpl/sysdm/advanced.c +++ b/dll/cpl/sysdm/advanced.c @@ -9,6 +9,8 @@ */ #include "precomp.h" +#define WIN32_NO_STATUS +#include "pstypes.h" /* SharedUserData */ static TCHAR BugLink[] = _T("http://jira.reactos.org/"); static TCHAR ReportAsWorkstationKey[] = _T("SYSTEM\\CurrentControlSet\\Control\\ReactOS\\Settings\\Version"); @@ -51,9 +53,10 @@ static VOID OnInitSysSettingsDialog(HWND hwndDlg) { HKEY hKey; - DWORD dwVal; + DWORD dwVal = 0; DWORD dwType = REG_DWORD; DWORD cbData = sizeof(DWORD); + BOOL ReportAsWorkstation = SharedUserData->NtProductType == VER_NT_WORKSTATION; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, ReportAsWorkstationKey, @@ -68,19 +71,14 @@ OnInitSysSettingsDialog(HWND hwndDlg) (LPBYTE)&dwVal, &cbData) == ERROR_SUCCESS) { - if (dwVal != FALSE) - { - // set the check box - SendDlgItemMessageW(hwndDlg, - IDC_REPORTASWORKSTATION, - BM_SETCHECK, - BST_CHECKED, - 0); - } + if (cbData == sizeof(DWORD)) + ReportAsWorkstation = dwVal != FALSE; } RegCloseKey(hKey); } + SendDlgItemMessageW(hwndDlg, IDC_REPORTASWORKSTATION, BM_SETCHECK, + ReportAsWorkstation ? BST_CHECKED : BST_UNCHECKED, 0); } INT_PTR CALLBACK diff --git a/dll/cpl/wined3dcfg/lang/ro-RO.rc b/dll/cpl/wined3dcfg/lang/ro-RO.rc index 157eafb3cddba..8152264d0ea4c 100644 --- a/dll/cpl/wined3dcfg/lang/ro-RO.rc +++ b/dll/cpl/wined3dcfg/lang/ro-RO.rc @@ -1,39 +1,45 @@ -/* Translator: Ștefan Fulea (stefan dot fulea at mail dot com) */ +/* + * PROJECT: ReactOS WineD3D Configuration Control Panel + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Romanian resource file + * TRANSLATORS: Copyright 2011-2018 Ștefan Fulea + * Copyright 2024 Andrei Miloiu + */ LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL IDD_PROPPAGEGENERAL DIALOGEX 0, 0, 246, 228 STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION -CAPTION "Generale" +CAPTION "General" FONT 8, "MS Shell Dlg" BEGIN ICON IDI_CPLICON, IDI_CPLICON, 8, 0, 21, 20 GROUPBOX "Efecte de umbrire", -1, 5, 25, 230, 80 - LTEXT "Activează GLSL:", -1, 15, 42, 120, 10 + LTEXT "&Activare a GLSL:", -1, 15, 42, 120, 10 COMBOBOX IDC_GLSL, 135, 40, 90, 10, WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST - LTEXT "Nivelul GS maxim:", -1, 15, 57, 120, 10 + LTEXT "Nivelul &GS maxim:", -1, 15, 57, 120, 10 COMBOBOX IDC_GSLEVEL, 135, 55, 90, 10, WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST - LTEXT "Nivelul PS maxim:", -1, 15, 72, 120, 10 + LTEXT "Nivelul &PS maxim:", -1, 15, 72, 120, 10 COMBOBOX IDC_PSLEVEL, 135, 70, 90, 10, WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST - LTEXT "Nivelul VS maxim:", -1, 15, 87, 120, 10 + LTEXT "Nivelul &VS maxim:", -1, 15, 87, 120, 10 COMBOBOX IDC_VSLEVEL, 135, 85, 90, 10, WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST GROUPBOX "Randare", -1, 5, 110, 230, 110 - LTEXT "Multieșantionare:", -1, 15, 127, 120, 10 + LTEXT "&Multieșantionare:", -1, 15, 127, 120, 10 COMBOBOX IDC_MULTISAMPLING, 135, 125, 90, 10, WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST - LTEXT "Ordinea strictă de desenare:", -1, 15, 142, 120, 10 + LTEXT "&Ordine strictă de desenare:", -1, 15, 142, 120, 10 COMBOBOX IDC_STRICTDRAWORDERING, 135, 140, 90, 10, WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST - LTEXT "Randarea extra-ecran:", -1, 15, 157, 120, 10 + LTEXT "&Randare extra-ecran:", -1, 15, 157, 120, 10 COMBOBOX IDC_OFFSCREEN, 135, 155, 90, 10, WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST - LTEXT "Întotdeauna extra-ecran:", -1, 15, 172, 120, 10, SS_LEFT + LTEXT "Î&ntotdeauna extra-ecran:", -1, 15, 172, 120, 10, SS_LEFT COMBOBOX IDC_ALWAYSOFFSCREEN, 135, 170, 90, 10, WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST - LTEXT "Dimensiunea memoriei video:", -1, 15, 187, 120, 10, SS_LEFT + LTEXT "Dim&ensiunea memoriei video:", -1, 15, 187, 120, 10, SS_LEFT COMBOBOX IDC_VIDMEMSIZE, 135, 185, 90, 10, WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST - LTEXT "Randator DirectDraw:", -1, 15, 202, 120, 10, SS_LEFT + LTEXT "Randator &DirectDraw:", -1, 15, 202, 120, 10, SS_LEFT COMBOBOX IDC_DDRENDERER, 135, 200, 90, 10, WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST END STRINGTABLE BEGIN IDS_CPLNAME "Opțiuni WineD3D" - IDS_CPLDESCRIPTION "Configurarea opțiunilor de execuție WineD3D." + IDS_CPLDESCRIPTION "Configurează setările de rulare WineD3D." END diff --git a/dll/directx/ddraw/main.c b/dll/directx/ddraw/main.c index 6391c01136455..2d4019f55dba0 100644 --- a/dll/directx/ddraw/main.c +++ b/dll/directx/ddraw/main.c @@ -287,8 +287,7 @@ DirectDrawEnumerateExW(LPDDENUMCALLBACKEXW lpCallback, /* - See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ - Display_d/hh/Display_d/d3d_21ac30ea-9803-401e-b541-6b08af79653d.xml.asp + See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/Display_d/hh/Display_d/d3d_21ac30ea-9803-401e-b541-6b08af79653d.xml.asp (DEAD_LINK) for more info about this command see msdn documentation diff --git a/dll/directx/wine/d3d8/CMakeLists.txt b/dll/directx/wine/d3d8/CMakeLists.txt index 9160e2ada15eb..2373312006768 100644 --- a/dll/directx/wine/d3d8/CMakeLists.txt +++ b/dll/directx/wine/d3d8/CMakeLists.txt @@ -1,10 +1,8 @@ add_definitions( - -D__WINESRC__ -D__ROS_LONG64__ -DUSE_WIN32_OPENGL) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(d3d8.dll d3d8.spec) list(APPEND SOURCE @@ -33,3 +31,4 @@ target_link_libraries(d3d8 uuid wine) add_importlibs(d3d8 d3dwine msvcrt kernel32 ntdll) add_pch(d3d8 precomp.h "${PCH_SKIP_SOURCE}") add_cd_file(TARGET d3d8 DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(d3d8) # CORE-5743: No CONST_VTABLE diff --git a/dll/directx/wine/d3d9/CMakeLists.txt b/dll/directx/wine/d3d9/CMakeLists.txt index 5c729add466a5..e4f063ad1f974 100644 --- a/dll/directx/wine/d3d9/CMakeLists.txt +++ b/dll/directx/wine/d3d9/CMakeLists.txt @@ -1,9 +1,7 @@ add_definitions( - -D__WINESRC__ -DUSE_WIN32_OPENGL) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(d3d9.dll d3d9.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -35,3 +33,4 @@ target_link_libraries(d3d9 wine) add_importlibs(d3d9 d3dwine user32 msvcrt kernel32 ntdll) add_pch(d3d9 precomp.h "${PCH_SKIP_SOURCE}") add_cd_file(TARGET d3d9 DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(d3d9) # CORE-5743: No ARRAY_SIZE and CONST_VTABLE diff --git a/dll/directx/wine/d3dcompiler_43/main.c b/dll/directx/wine/d3dcompiler_43/main.c index 3404655ac8ebf..685bbe6e4bd3d 100644 --- a/dll/directx/wine/d3dcompiler_43/main.c +++ b/dll/directx/wine/d3dcompiler_43/main.c @@ -30,8 +30,10 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved) { switch (reason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(inst); break; diff --git a/dll/directx/wine/d3drm/CMakeLists.txt b/dll/directx/wine/d3drm/CMakeLists.txt index cd1eaad88321b..4fb8e3515f3b4 100644 --- a/dll/directx/wine/d3drm/CMakeLists.txt +++ b/dll/directx/wine/d3drm/CMakeLists.txt @@ -1,6 +1,5 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) +add_definitions(-D__ROS_LONG64__) spec2def(d3drm.dll d3drm.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -28,3 +27,8 @@ target_link_libraries(d3drm dxguid uuid wine) add_importlibs(d3drm ddraw d3dxof msvcrt kernel32 ntdll) add_pch(d3drm precomp.h SOURCE) add_cd_file(TARGET d3drm DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(d3drm) # CORE-5743: No ARRAY_SIZE and CONST_VTABLE + +if(CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_compile_options(d3drm PRIVATE -Wno-incompatible-function-pointer-types) +endif() diff --git a/dll/directx/wine/d3drm/d3drm_main.c b/dll/directx/wine/d3drm/d3drm_main.c index 075b331e051bb..09d4d42dc668d 100644 --- a/dll/directx/wine/d3drm/d3drm_main.c +++ b/dll/directx/wine/d3drm/d3drm_main.c @@ -27,8 +27,10 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved) { switch(reason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls( inst ); break; diff --git a/dll/directx/wine/d3dx9_36/main.c b/dll/directx/wine/d3dx9_36/main.c index e0fc2d5033205..4c0e78b2a57ba 100644 --- a/dll/directx/wine/d3dx9_36/main.c +++ b/dll/directx/wine/d3dx9_36/main.c @@ -34,8 +34,10 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved) { switch(reason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(inst); break; diff --git a/dll/directx/wine/d3dxof/CMakeLists.txt b/dll/directx/wine/d3dxof/CMakeLists.txt index 98fdae11965b0..fcdf2090377c5 100644 --- a/dll/directx/wine/d3dxof/CMakeLists.txt +++ b/dll/directx/wine/d3dxof/CMakeLists.txt @@ -1,6 +1,5 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) +add_definitions(-D__ROS_LONG64__) spec2def(d3dxof.dll d3dxof.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -22,3 +21,4 @@ target_link_libraries(d3dxof dxguid uuid wine) add_importlibs(d3dxof msvcrt kernel32 ntdll) add_pch(d3dxof precomp.h "${PCH_SKIP_SOURCE}") add_cd_file(TARGET d3dxof DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(d3dxof) # CORE-5743: No ARRAY_SIZE and CONST_VTABLE diff --git a/dll/directx/wine/ddraw/CMakeLists.txt b/dll/directx/wine/ddraw/CMakeLists.txt index 824633ebff08d..073e35c43dbbb 100644 --- a/dll/directx/wine/ddraw/CMakeLists.txt +++ b/dll/directx/wine/ddraw/CMakeLists.txt @@ -1,11 +1,8 @@ add_definitions( - -D__WINESRC__ -D__ROS_LONG64__ -DUSE_WIN32_OPENGL) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) - spec2def(ddraw.dll ddraw.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -41,3 +38,4 @@ add_importlibs(ddraw advapi32 gdi32 user32 d3dwine msvcrt kernel32 ntdll) add_dependencies(ddraw wineheaders) add_pch(ddraw precomp.h SOURCE) add_cd_file(TARGET ddraw DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(ddraw) # CORE-5743: No ARRAY_SIZE and CONST_VTABLE diff --git a/dll/directx/wine/devenum/CMakeLists.txt b/dll/directx/wine/devenum/CMakeLists.txt index d147a1b006adb..7cef8bfe29f8e 100644 --- a/dll/directx/wine/devenum/CMakeLists.txt +++ b/dll/directx/wine/devenum/CMakeLists.txt @@ -2,8 +2,6 @@ remove_definitions(-D_WIN32_WINNT=0x502 -DWINVER=0x502) add_definitions(-D_WIN32_WINNT=0x600 -DWINVER=0x600) -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(devenum.dll devenum.spec) list(APPEND SOURCE @@ -26,3 +24,4 @@ add_importlibs(devenum advapi32 advapi32_vista ole32 oleaut32 winmm user32 avica add_dependencies(devenum wineheaders) add_pch(devenum precomp.h SOURCE) add_cd_file(TARGET devenum DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(devenum) # CORE-5743: No ARRAY_SIZE and CONST_VTABLE diff --git a/dll/directx/wine/dinput/CMakeLists.txt b/dll/directx/wine/dinput/CMakeLists.txt index 638312f44b965..2d5824b481526 100644 --- a/dll/directx/wine/dinput/CMakeLists.txt +++ b/dll/directx/wine/dinput/CMakeLists.txt @@ -1,6 +1,5 @@ -add_definitions(-D__WINESRC__ -DDIRECTINPUT_VERSION=0x0700) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) +add_definitions(-DDIRECTINPUT_VERSION=0x0700) spec2def(dinput.dll dinput.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -22,9 +21,12 @@ add_library(dinput MODULE dinput.rc version.rc ${CMAKE_CURRENT_BINARY_DIR}/dinput.def) +set_wine_module_FIXME(dinput) # CORE-5743: No ARRAY_SIZE macro add_library(dinput_data_formats data_formats.c) add_dependencies(dinput_data_formats psdk) +set_wine_module_FIXME(dinput_data_formats) # CORE-5743: No ARRAY_SIZE macro + set_module_type(dinput win32dll) target_link_libraries(dinput dxguid uuid wine) add_importlibs(dinput comctl32 ole32 user32 advapi32 msvcrt kernel32 ntdll) diff --git a/dll/directx/wine/dinput8/CMakeLists.txt b/dll/directx/wine/dinput8/CMakeLists.txt index b408e1e1f0653..08f0fe30ed788 100644 --- a/dll/directx/wine/dinput8/CMakeLists.txt +++ b/dll/directx/wine/dinput8/CMakeLists.txt @@ -1,6 +1,5 @@ -add_definitions(-D__WINESRC__ -DDIRECTINPUT_VERSION=0x0800) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) +add_definitions(-DDIRECTINPUT_VERSION=0x0800) spec2def(dinput8.dll dinput8.spec ADD_IMPORTLIB) set(DINPUT_SOURCE_FOLDER ../dinput) @@ -27,3 +26,4 @@ set_module_type(dinput8 win32dll) target_link_libraries(dinput8 dxguid uuid wine) add_importlibs(dinput8 comctl32 ole32 user32 advapi32 msvcrt kernel32 ntdll) add_cd_file(TARGET dinput8 DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(dinput8) # CORE-5743: No ARRAY_SIZE and CONST_VTABLE diff --git a/dll/directx/wine/dmusic/CMakeLists.txt b/dll/directx/wine/dmusic/CMakeLists.txt index 88abed338bb9b..db69d9118cd6b 100644 --- a/dll/directx/wine/dmusic/CMakeLists.txt +++ b/dll/directx/wine/dmusic/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(dmusic.dll dmusic.spec) list(APPEND SOURCE @@ -25,3 +23,4 @@ target_link_libraries(dmusic dxguid uuid wine) add_importlibs(dmusic ole32 advapi32 winmm dsound user32 msvcrt kernel32 ntdll) add_pch(dmusic precomp.h SOURCE) add_cd_file(TARGET dmusic DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(dmusic) # CORE-5743: No CONST_VTABLE diff --git a/dll/directx/wine/dplayx/CMakeLists.txt b/dll/directx/wine/dplayx/CMakeLists.txt index 61049520d47bf..302823df7cc8a 100644 --- a/dll/directx/wine/dplayx/CMakeLists.txt +++ b/dll/directx/wine/dplayx/CMakeLists.txt @@ -1,9 +1,7 @@ add_definitions( - -DCOM_NO_WINDOWS_H - -D__WINESRC__) + -DCOM_NO_WINDOWS_H) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(dplayx.dll dplayx.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -28,3 +26,4 @@ target_link_libraries(dplayx dxguid uuid wine) add_importlibs(dplayx winmm ole32 user32 advapi32 msvcrt kernel32 ntdll) add_pch(dplayx precomp.h SOURCE) add_cd_file(TARGET dplayx DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(dplayx) # CORE-5743: No ARRAY_SIZE and CONST_VTABLE diff --git a/dll/directx/wine/dpnhpast/CMakeLists.txt b/dll/directx/wine/dpnhpast/CMakeLists.txt index 53d5cf51424e0..f7959cf944e0a 100644 --- a/dll/directx/wine/dpnhpast/CMakeLists.txt +++ b/dll/directx/wine/dpnhpast/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(dpnhpast.dll dpnhpast.spec) list(APPEND SOURCE @@ -13,3 +11,4 @@ set_module_type(dpnhpast win32dll) target_link_libraries(dpnhpast dxguid uuid wine) add_importlibs(dpnhpast msvcrt kernel32 ntdll) add_cd_file(TARGET dpnhpast DESTINATION reactos/system32 FOR all) +set_wine_module(dpnhpast) diff --git a/dll/directx/wine/dsound/CMakeLists.txt b/dll/directx/wine/dsound/CMakeLists.txt index 145453b6cdf69..d330cd4e3ff34 100644 --- a/dll/directx/wine/dsound/CMakeLists.txt +++ b/dll/directx/wine/dsound/CMakeLists.txt @@ -1,10 +1,8 @@ add_definitions( -D_WINE - -D_USE_MATH_DEFINES - -D__WINESRC__) + -D_USE_MATH_DEFINES) -include_directories(BEFORE ${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(dsound.dll dsound.spec ADD_IMPORTLIB) add_library(dsound MODULE @@ -26,3 +24,4 @@ set_module_type(dsound win32dll) target_link_libraries(dsound dxguid uuid wine) add_importlibs(dsound winmm advapi32 msvcrt kernel32 ntdll) add_cd_file(TARGET dsound DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(dsound) # CORE-5743: No CONST_VTABLE diff --git a/dll/directx/wine/dxdiagn/CMakeLists.txt b/dll/directx/wine/dxdiagn/CMakeLists.txt index 41adda026eebe..22d94ccbefc16 100644 --- a/dll/directx/wine/dxdiagn/CMakeLists.txt +++ b/dll/directx/wine/dxdiagn/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(dxdiagn.dll dxdiagn.spec) list(APPEND SOURCE @@ -23,3 +21,4 @@ add_dependencies(dxdiagn wineheaders) add_importlibs(dxdiagn d3d9 ddraw version ole32 oleaut32 psapi user32 dsound msvcrt kernel32 ntdll) add_pch(dxdiagn precomp.h "${PCH_SKIP_SOURCE}") add_cd_file(TARGET dxdiagn DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(dxdiagn) # CORE-5743: No ARRAY_SIZE and CONST_VTABLE diff --git a/dll/directx/wine/msdmo/CMakeLists.txt b/dll/directx/wine/msdmo/CMakeLists.txt index 03475b1d3660b..e9f3733f46032 100644 --- a/dll/directx/wine/msdmo/CMakeLists.txt +++ b/dll/directx/wine/msdmo/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(msdmo.dll msdmo.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -21,3 +19,4 @@ target_link_libraries(msdmo uuid wine mediaobj_guid) add_importlibs(msdmo user32 advapi32 ole32 msvcrt kernel32 ntdll) add_pch(msdmo precomp.h "${PCH_SKIP_SOURCE}") add_cd_file(TARGET msdmo DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(msdmo) # CORE-5743: No ARRAY_SIZE and CONST_VTABLE diff --git a/dll/directx/wine/qcap/CMakeLists.txt b/dll/directx/wine/qcap/CMakeLists.txt index cbd24d39bccad..58ba55f4c1340 100644 --- a/dll/directx/wine/qcap/CMakeLists.txt +++ b/dll/directx/wine/qcap/CMakeLists.txt @@ -1,7 +1,4 @@ -add_definitions(-D__WINESRC__) - -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(qcap.dll qcap.spec) list(APPEND SOURCE @@ -26,3 +23,4 @@ target_link_libraries(qcap strmbase strmiids uuid wine) add_importlibs(qcap ole32 oleaut32 gdi32 advapi32 advapi32_vista msvcrt kernel32 ntdll) add_delay_importlibs(qcap msvfw32) add_cd_file(TARGET qcap DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(qcap) # CORE-5743: No CONST_VTABLE diff --git a/dll/directx/wine/qedit/CMakeLists.txt b/dll/directx/wine/qedit/CMakeLists.txt index 50cca289d7593..45a1fcee75ae7 100644 --- a/dll/directx/wine/qedit/CMakeLists.txt +++ b/dll/directx/wine/qedit/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(qedit.dll qedit.spec) list(APPEND SOURCE @@ -20,3 +18,4 @@ target_link_libraries(qedit strmbase strmiids uuid wine) add_importlibs(qedit ole32 oleaut32 msvcrt kernel32 ntdll) add_pch(qedit precomp.h SOURCE) add_cd_file(TARGET qedit DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(qedit) # CORE-5743: No ARRAY_SIZE and CONST_VTABLE diff --git a/dll/directx/wine/quartz/CMakeLists.txt b/dll/directx/wine/quartz/CMakeLists.txt index 716edfd108c55..1200717cca151 100644 --- a/dll/directx/wine/quartz/CMakeLists.txt +++ b/dll/directx/wine/quartz/CMakeLists.txt @@ -3,12 +3,10 @@ remove_definitions(-D_WIN32_WINNT=0x502) add_definitions(-D_WIN32_WINNT=0x600) add_definitions( - -D__WINESRC__ -DENTRY_PREFIX=QUARTZ_ -DWINE_REGISTER_DLL -DPROXY_DELEGATION) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(quartz.dll quartz.spec) add_rpcproxy_files(quartz_strmif.idl) @@ -61,3 +59,4 @@ add_importlibs(quartz dsound msacm32 msvfw32 ole32 oleaut32 rpcrt4 user32 gdi32 add_dependencies(quartz dxsdk quartz_idlheader stdole2) add_pch(quartz precomp.h "${PCH_SKIP_SOURCE}") add_cd_file(TARGET quartz DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(quartz) # CORE-5743: No CONST_VTABLE diff --git a/dll/directx/wine/wined3d/CMakeLists.txt b/dll/directx/wine/wined3d/CMakeLists.txt index 58f15cfbc144c..d63bd61ca3a83 100644 --- a/dll/directx/wine/wined3d/CMakeLists.txt +++ b/dll/directx/wine/wined3d/CMakeLists.txt @@ -1,13 +1,10 @@ add_definitions( - -D__WINESRC__ -D_USE_MATH_DEFINES -DUSE_WIN32_OPENGL -D__ROS_LONG64__ -Dcopysignf=_copysignf) -include_directories(BEFORE ${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) - # We name this d3dwine.dll, because the Virtualbox additions ship with a custom wined3d.dll # and it breaks everything if it is installed. spec2def(d3dwine.dll wined3d.spec ADD_IMPORTLIB) @@ -52,6 +49,7 @@ target_link_libraries(d3dwine wine) add_importlibs(d3dwine user32 opengl32 gdi32 gdi32_vista advapi32 msvcrt kernel32 ntdll) add_pch(d3dwine precomp.h SOURCE) add_cd_file(TARGET d3dwine DESTINATION reactos/system32 FOR all) +set_wine_module(d3dwine) if(CMAKE_C_COMPILER_ID STREQUAL "GNU") target_compile_options(d3dwine PRIVATE -Wno-format-overflow) diff --git a/dll/ime/msctfime/lang/ro-RO.rc b/dll/ime/msctfime/lang/ro-RO.rc new file mode 100644 index 0000000000000..91cfb96576078 --- /dev/null +++ b/dll/ime/msctfime/lang/ro-RO.rc @@ -0,0 +1,23 @@ +/* + * PROJECT: ReactOS msctfime.ime + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Romanian resource file + * TRANSLATOR: Copyright 2024 Andrei Miloiu + */ + +LANGUAGE LANG_ROMANIAN, SUBLANG_DEFAULT + +STRINGTABLE +BEGIN + IDS_OK "OK" + IDS_CANCEL "Revocare" + IDS_ABORT "Î&ntrerupere" + IDS_RETRY "&Reîncercare" + IDS_IGNORE "&Ignorare" + IDS_YES "&Da" + IDS_NO "&Nu" + + IDS_ENTER "Intrare" + IDS_FINALIZE_STRING "Finalizare a șirului" + IDS_CONVERSION "Conversie" +END diff --git a/dll/ime/msctfime/msctfime.rc b/dll/ime/msctfime/msctfime.rc index 412ac4783f01d..59311d805e43a 100644 --- a/dll/ime/msctfime/msctfime.rc +++ b/dll/ime/msctfime/msctfime.rc @@ -33,6 +33,9 @@ IDI_DOWN ICON "res/down.ico" #ifdef LANGUAGE_PT_PT #include "lang/pt-PT.rc" #endif +#ifdef LANGUAGE_RO_RO + #include "lang/ro-RO.rc" +#endif #ifdef LANGUAGE_RU_RU #include "lang/ru-RU.rc" #endif diff --git a/dll/ntdll/CMakeLists.txt b/dll/ntdll/CMakeLists.txt index fdd7c11262a57..f2611c3c0dccc 100644 --- a/dll/ntdll/CMakeLists.txt +++ b/dll/ntdll/CMakeLists.txt @@ -1,7 +1,11 @@ add_subdirectory(nt_0600) -spec2def(ntdll.dll def/ntdll.spec ADD_IMPORTLIB) +if(SARCH STREQUAL "wow64") + spec2def(ntdll.dll def/ntdllwow.spec ADD_IMPORTLIB) +else() + spec2def(ntdll.dll def/ntdll.spec ADD_IMPORTLIB) +endif() # Embed RTC libs if (STACK_PROTECTOR) @@ -47,6 +51,11 @@ else() list(APPEND SOURCE dispatch/dispatch.c) endif() +if(ARCH STREQUAL "i386") + list(APPEND ASM_SOURCE wow64/gsfuncs.S) + list(APPEND SOURCE wow64/memory.c) +endif() + add_asm_files(ntdll_asm ${ASM_SOURCE}) list(APPEND PCH_SKIP_SOURCE @@ -65,7 +74,7 @@ set_module_type(ntdll win32dll ENTRYPOINT 0) set_subsystem(ntdll console) ################# END HACK ################# -target_link_libraries(ntdll etwtrace csrlib rtl rtl_um rtl_vista ntdllsys libcntpr uuid ${PSEH_LIB}) +target_link_libraries(ntdll ntdll_vista_static etwtrace csrlib rtl rtl_um rtl_vista ntdllsys libcntpr uuid ${PSEH_LIB}) if(DLL_EXPORT_VERSION GREATER_EQUAL 0x600) target_link_libraries(ntdll cryptlib) endif() diff --git a/dll/ntdll/def/ntdll.spec b/dll/ntdll/def/ntdll.spec index 62f374c05fbd9..ac17c9b37c977 100644 --- a/dll/ntdll/def/ntdll.spec +++ b/dll/ntdll/def/ntdll.spec @@ -64,44 +64,46 @@ @ stdcall -version=0x502 EtwControlTraceA(double str ptr long) @ stdcall -version=0x502 EtwControlTraceW(double wstr ptr long) @ stdcall -stub EtwCreateTraceInstanceId(ptr ptr) -@ stub -version=0x600+ EtwDeliverDataBlock +@ stdcall -stub -version=0x600+ EtwDeliverDataBlock(long) @ stdcall -version=0x502 EtwEnableTrace(long long long ptr double) -@ stub -version=0x600+ EtwEnumerateProcessRegGuids +@ stdcall -stub -version=0x600+ EtwEnumerateProcessRegGuids(ptr long ptr) @ stdcall -stub -version=0x502 EtwEnumerateTraceGuids(ptr long ptr) -@ stub -version=0x600+ EtwEventActivityIdControl -@ stub -version=0x600+ EtwEventEnabled -@ stub -version=0x600+ EtwEventProviderEnabled -@ stub -version=0x600+ EtwEventRegister -@ stub -version=0x600+ EtwEventUnregister -@ stub -version=0x600+ EtwEventWrite -@ stub -version=0x600+ EtwEventWriteEndScenario -@ stub -version=0x600+ EtwEventWriteFull -@ stub -version=0x600+ EtwEventWriteStartScenario -@ stub -version=0x600+ EtwEventWriteString -@ stub -version=0x600+ EtwEventWriteTransfer +@ stdcall -stub -version=0x600+ EtwEventActivityIdControl(long ptr) +@ stdcall -stub -version=0x600+ EtwEventEnabled(int64 ptr) +@ stdcall -stub -version=0x600+ EtwEventProviderEnabled(long long long) +@ stdcall -stub -version=0x600+ EtwEventRegister(ptr ptr ptr ptr) +@ stdcall -stub -version=0x600+ EtwEventSetInformation(int64 long ptr long) +@ stdcall -stub -version=0x600+ EtwEventUnregister(int64) +@ stdcall -stub -version=0x600+ EtwEventWrite(int64 ptr long ptr) +@ stdcall -stub -version=0x600+ EtwEventWriteEndScenario(long ptr long long) +@ stdcall -stub -version=0x600+ EtwEventWriteFull(long long long long long long long) +@ stdcall -stub -version=0x600+ EtwEventWriteStartScenario(long ptr long long) +@ stdcall -stub -version=0x600+ EtwEventWriteString(long long long long) +@ stdcall -stub -version=0x600+ EtwEventWriteTransfer(long ptr ptr ptr long long) @ stdcall -version=0x502 EtwFlushTraceA(double str ptr) @ stdcall -version=0x502 EtwFlushTraceW(double wstr ptr) @ stdcall EtwGetTraceEnableFlags(double) @ stdcall EtwGetTraceEnableLevel(double) @ stdcall EtwGetTraceLoggerHandle(ptr) -@ stub -version=0x600+ EtwLogTraceEvent -@ stub -version=0x600+ EtwNotificationRegister +@ stdcall -stub -version=0x600+ EtwLogTraceEvent(long long) +@ stdcall -stub -version=0x600+ EtwNotificationRegister(ptr long long long ptr) @ stdcall -stub -version=0x502 EtwNotificationRegistrationA(ptr long ptr long long) @ stdcall -stub -version=0x502 EtwNotificationRegistrationW(ptr long ptr long long) -@ stub -version=0x600+ EtwNotificationUnregister -@ stub -version=0x600+ EtwProcessPrivateLoggerRequest +@ stdcall -stub -version=0x600+ EtwNotificationUnregister(long ptr) +@ stdcall -stub -version=0x600+ EtwProcessPrivateLoggerRequest(ptr) @ stdcall -version=0x502 EtwQueryAllTracesA(ptr long ptr) @ stdcall -version=0x502 EtwQueryAllTracesW(ptr long ptr) @ stdcall -version=0x502 EtwQueryTraceA(double str ptr) @ stdcall -version=0x502 EtwQueryTraceW(double wstr ptr) @ stdcall -stub -version=0x502 EtwReceiveNotificationsA(long long long long) @ stdcall -stub -version=0x502 EtwReceiveNotificationsW(long long long long) -@ stub -version=0x600+ EtwRegisterSecurityProvider +@ stdcall -stub -version=0x600+ EtwRegister(ptr ptr ptr ptr) +@ stdcall -stub -version=0x600+ EtwRegisterSecurityProvider() @ stdcall EtwRegisterTraceGuidsA(ptr ptr ptr long ptr str str ptr) @ stdcall EtwRegisterTraceGuidsW(ptr ptr ptr long ptr wstr wstr ptr) -@ stub -version=0x600+ EtwReplyNotification -@ stub -version=0x600+ EtwSendNotification -@ stub -version=0x600+ EtwSetMark +@ stdcall -stub -version=0x600+ EtwReplyNotification(long) +@ stdcall -stub -version=0x600+ EtwSendNotification(long long ptr long long) +@ stdcall -stub -version=0x600+ EtwSetMark(long long long) @ stdcall -version=0x502 EtwStartTraceA(ptr str ptr) @ stdcall -version=0x502 EtwStartTraceW(ptr wstr ptr) @ stdcall -version=0x502 EtwStopTraceA(double str ptr) @@ -110,14 +112,16 @@ @ stdcall -stub EtwTraceEventInstance(double ptr ptr ptr) @ varargs EtwTraceMessage(int64 long ptr long) @ stdcall -stub EtwTraceMessageVa(int64 long ptr long ptr) +@ stdcall -stub -version=0x600+ EtwUnregister(int64) @ stdcall EtwUnregisterTraceGuids(double) @ stdcall -version=0x502 EtwUpdateTraceA(double str ptr) @ stdcall -version=0x502 EtwUpdateTraceW(double wstr ptr) -@ stub -version=0x600+ EtwWriteUMSecurityEvent -@ stub -version=0x600+ EtwpCreateEtwThread -@ stub -version=0x600+ EtwpGetCpuSpeed +@ stdcall -stub -version=0x600+ EtwWrite(int64 ptr ptr long ptr) +@ stdcall -stub -version=0x600+ EtwWriteUMSecurityEvent(ptr long long long) +@ stdcall -stub -version=0x600+ EtwpCreateEtwThread(long long) +@ stdcall -stub -version=0x600+ EtwpGetCpuSpeed(ptr) @ stdcall -stub -version=0x502 EtwpGetTraceBuffer(long long long long) -@ stub -version=0x600+ EtwpNotificationThread +@ stdcall -stub -version=0x600+ EtwpNotificationThread() ; doesn't exist in win11 @ stdcall -stub -version=0x502 EtwpSetHWConfigFunction(ptr long) @ stdcall -arch=x86_64 ExpInterlockedPopEntrySListEnd() @ stub -version=0x600+ -arch=x86_64 ExpInterlockedPopEntrySListEnd8 @@ -150,7 +154,7 @@ @ stdcall LdrFlushAlternateResourceModules() @ stdcall LdrGetDllHandle(wstr ptr ptr ptr) @ stdcall LdrGetDllHandleEx(long wstr ptr ptr ptr) -@ stub -version=0x600+ LdrGetFailureData +@ stdcall -stub -version=0x600+ LdrGetFailureData() @ stdcall -stub -version=0x600+ LdrGetFileNameFromLoadAsDataTable(ptr ptr) @ stdcall -stub -version=0x600+ -arch=x86_64 LdrGetKnownDllSectionHandle(wstr long ptr) @ stdcall LdrGetProcedureAddress(ptr ptr long ptr) @@ -159,38 +163,38 @@ @ stdcall LdrInitShimEngineDynamic(ptr) @ stdcall LdrInitializeThunk(long long long long) @ stdcall LdrLoadAlternateResourceModule(ptr ptr) -@ stub -version=0x600+ LdrLoadAlternateResourceModuleEx +@ stdcall -stub -version=0x600+ LdrLoadAlternateResourceModuleEx(long long ptr ptr long) @ stdcall LdrLoadDll(wstr long ptr ptr) @ stdcall LdrLockLoaderLock(long ptr ptr) @ stdcall LdrOpenImageFileOptionsKey(ptr long ptr) ; 5.2 SP1 and higher -@ stub -version=0x600+ -arch=x86_64 LdrProcessInitializationComplete +@ stdcall -stub -version=0x600+ -arch=x86_64 LdrProcessInitializationComplete() @ stdcall LdrProcessRelocationBlock(ptr long ptr long) @ stdcall LdrQueryImageFileExecutionOptions(ptr str long ptr long ptr) @ stdcall LdrQueryImageFileExecutionOptionsEx(ptr ptr long ptr long ptr long) @ stdcall LdrQueryImageFileKeyOption(ptr ptr long ptr long ptr) @ stdcall -stub -version=0x600+ LdrQueryModuleServiceTags(ptr ptr ptr) @ stdcall LdrQueryProcessModuleInformation(ptr long ptr) -@ stdcall -stub -version=0x600+ LdrRegisterDllNotification(long ptr ptr ptr) +@ stdcall -version=0x600+ LdrRegisterDllNotification(long ptr ptr ptr) @ stdcall -stub -version=0x600+ LdrRemoveLoadAsDataTable(ptr ptr ptr long) -@ stub -version=0x600+ LdrResFindResource -@ stub -version=0x600+ LdrResFindResourceDirectory -@ stub -version=0x600+ LdrResRelease -@ stub -version=0x600+ LdrResSearchResource +@ stdcall -stub -version=0x600+ LdrResFindResource(ptr long long long long long long long long) +@ stdcall -stub -version=0x600+ LdrResFindResourceDirectory(ptr long long long long long long) +@ stdcall -stub -version=0x600+ LdrResRelease(ptr ptr long long) +@ stdcall -stub -version=0x600+ LdrResSearchResource(wstr wstr long long long ptr long long) @ stdcall LdrSetAppCompatDllRedirectionCallback(long ptr ptr) @ stdcall LdrSetDllManifestProber(ptr) -@ stub -version=0x600+ LdrSetMUICacheType +@ stdcall -stub -version=0x600+ LdrSetMUICacheType(long) @ stdcall LdrShutdownProcess() @ stdcall LdrShutdownThread() @ stdcall LdrUnloadAlternateResourceModule(ptr) -@ stub -version=0x600+ LdrUnloadAlternateResourceModuleEx +@ stdcall -stub -version=0x600+ LdrUnloadAlternateResourceModuleEx(long long) @ stdcall LdrUnloadDll(ptr) @ stdcall LdrUnlockLoaderLock(long ptr) -@ stdcall -stub -version=0x600+ LdrUnregisterDllNotification(ptr) +@ stdcall -version=0x600+ LdrUnregisterDllNotification(ptr) @ stdcall LdrVerifyImageMatchesChecksum(ptr long long long) @ stdcall -stub -version=0x600+ LdrVerifyImageMatchesChecksumEx(ptr ptr) -@ stub -version=0x600+ LdrpResGetMappingSize -@ stub -version=0x600+ LdrpResGetRCConfig -@ stub -version=0x600+ LdrpResGetResourceDirectory +@ stdcall -stub -version=0x600+ LdrpResGetMappingSize(long ptr long long) +@ stdcall -stub -version=0x600+ LdrpResGetRCConfig(long long ptr long long) ; doesn't exist on win11 +@ stdcall -stub -version=0x600+ LdrpResGetResourceDirectory(long long long ptr ptr) @ stdcall -version=0x600+ MD4Final(ptr) @ stdcall -version=0x600+ MD4Init(ptr) @ stdcall -version=0x600+ MD4Update(ptr ptr long) @@ -208,7 +212,7 @@ @ stdcall NtAccessCheckByTypeResultList(ptr ptr ptr long ptr long ptr ptr long ptr ptr) @ stdcall NtAccessCheckByTypeResultListAndAuditAlarm(ptr ptr ptr ptr ptr ptr long long long ptr long ptr long ptr ptr ptr) @ stdcall NtAccessCheckByTypeResultListAndAuditAlarmByHandle(ptr ptr ptr ptr ptr ptr ptr long long long ptr long ptr long ptr ptr ptr) -@ stub -version=0x600+ NtAcquireCMFViewOwnership +@ stdcall -stub -version=0x600+ NtAcquireCMFViewOwnership(ptr ptr long) ; doesn't exist on Win11 @ stdcall NtAddAtom(ptr long ptr) @ stdcall NtAddBootEntry(ptr long) @ stdcall NtAddDriverEntry(ptr long) ; 5.2 and higher @@ -220,42 +224,42 @@ @ stdcall NtAllocateUserPhysicalPages(ptr ptr ptr) @ stdcall NtAllocateUuids(ptr ptr ptr ptr) @ stdcall NtAllocateVirtualMemory(long ptr ptr ptr long long) -@ stub -version=0x600+ NtAlpcAcceptConnectPort -@ stub -version=0x600+ NtAlpcCancelMessage -@ stub -version=0x600+ NtAlpcConnectPort -@ stub -version=0x600+ NtAlpcCreatePort -@ stub -version=0x600+ NtAlpcCreatePortSection -@ stub -version=0x600+ NtAlpcCreateResourceReserve -@ stub -version=0x600+ NtAlpcCreateSectionView -@ stub -version=0x600+ NtAlpcCreateSecurityContext -@ stub -version=0x600+ NtAlpcDeletePortSection -@ stub -version=0x600+ NtAlpcDeleteResourceReserve -@ stub -version=0x600+ NtAlpcDeleteSectionView -@ stub -version=0x600+ NtAlpcDeleteSecurityContext -@ stub -version=0x600+ NtAlpcDisconnectPort -@ stub -version=0x600+ NtAlpcImpersonateClientOfPort +@ stdcall -stub -version=0x600+ NtAlpcAcceptConnectPort(long long long long long long long long long) +@ stdcall -stub -version=0x600+ NtAlpcCancelMessage(long long long) +@ stdcall -stub -version=0x600+ NtAlpcConnectPort(long long long long long long long long long long long) +@ stdcall -stub -version=0x600+ NtAlpcCreatePort(long long long) +@ stdcall -stub -version=0x600+ NtAlpcCreatePortSection(long long long long ptr ptr) +@ stdcall -stub -version=0x600+ NtAlpcCreateResourceReserve(long long long ptr) +@ stdcall -stub -version=0x600+ NtAlpcCreateSectionView(long long long) +@ stdcall -stub -version=0x600+ NtAlpcCreateSecurityContext(long long ptr) +@ stdcall -stub -version=0x600+ NtAlpcDeletePortSection(long long long long ptr ptr) +@ stdcall -stub -version=0x600+ NtAlpcDeleteResourceReserve(long long long ptr) +@ stdcall -stub -version=0x600+ NtAlpcDeleteSectionView(long long long ptr) +@ stdcall -stub -version=0x600+ NtAlpcDeleteSecurityContext(long long long) +@ stdcall -stub -version=0x600+ NtAlpcDisconnectPort(long long) +@ stdcall -stub -version=0x600+ NtAlpcImpersonateClientOfPort(long long long) @ stub -version=0x600+ NtAlpcOpenSenderProcess @ stub -version=0x600+ NtAlpcOpenSenderThread -@ stub -version=0x600+ NtAlpcQueryInformation -@ stub -version=0x600+ NtAlpcQueryInformationMessage -@ stub -version=0x600+ NtAlpcRevokeSecurityContext -@ stub -version=0x600+ NtAlpcSendWaitReceivePort -@ stub -version=0x600+ NtAlpcSetInformation +@ stdcall -stub -version=0x600+ NtAlpcQueryInformation(long long long long long) +@ stdcall -stub -version=0x600+ NtAlpcQueryInformationMessage(long long long long long long) +@ stdcall -stub -version=0x600+ NtAlpcRevokeSecurityContext(long long long) +@ stdcall -stub -version=0x600+ NtAlpcSendWaitReceivePort(long long long long long long long long) +@ stdcall -stub -version=0x600+ NtAlpcSetInformation(long long long long) @ stdcall NtApphelpCacheControl(long ptr) @ stdcall NtAreMappedFilesTheSame(ptr ptr) @ stdcall NtAssignProcessToJobObject(long long) @ stdcall NtCallbackReturn(ptr long long) @ stdcall NtCancelDeviceWakeupRequest(ptr) @ stdcall NtCancelIoFile(long ptr) -@ stub -version=0x600+ NtCancelIoFileEx -@ stub -version=0x600+ NtCancelSynchronousIoFile +@ stdcall -stub -version=0x600+ NtCancelIoFileEx(long ptr ptr) +@ stdcall -stub -version=0x600+ NtCancelSynchronousIoFile(long ptr ptr) @ stdcall NtCancelTimer(long ptr) @ stdcall NtClearEvent(long) @ stdcall NtClose(long) @ stdcall NtCloseObjectAuditAlarm(ptr ptr long) -@ stub -version=0x600+ NtCommitComplete -@ stub -version=0x600+ NtCommitEnlistment -@ stub -version=0x600+ NtCommitTransaction +@ stdcall -stub -version=0x600+ NtCommitComplete(ptr ptr) +@ stdcall -stub -version=0x600+ NtCommitEnlistment(ptr ptr) +@ stdcall -stub -version=0x600+ NtCommitTransaction(ptr long) @ stdcall NtCompactKeys(long ptr) @ stdcall NtCompareTokens(ptr ptr ptr) @ stdcall NtCompleteConnectPort(ptr) @@ -264,7 +268,7 @@ @ stdcall NtContinue(ptr long) @ stdcall NtCreateDebugObject(ptr long ptr long) @ stdcall NtCreateDirectoryObject(long long long) -@ stub -version=0x600+ NtCreateEnlistment +@ stdcall -stub -version=0x600+ NtCreateEnlistment(ptr long ptr ptr ptr long long ptr) @ stdcall NtCreateEvent(long long long long long) @ stdcall NtCreateEventPair(ptr long ptr) @ stdcall NtCreateFile(ptr long ptr ptr long long long ptr long long ptr) @@ -272,18 +276,18 @@ @ stdcall NtCreateJobObject(ptr long ptr) @ stdcall NtCreateJobSet(long ptr long) @ stdcall NtCreateKey(ptr long ptr long ptr long long) -@ stub -version=0x600+ NtCreateKeyTransacted +@ stdcall -stub -version=0x600+ NtCreateKeyTransacted(ptr long ptr long ptr long long ptr) @ stdcall NtCreateKeyedEvent(ptr long ptr long) @ stdcall NtCreateMailslotFile(long long long long long long long long) @ stdcall NtCreateMutant(ptr long ptr long) @ stdcall NtCreateNamedPipeFile(ptr long ptr ptr long long long long long long long long long ptr) @ stdcall NtCreatePagingFile(ptr ptr ptr long) @ stdcall NtCreatePort(ptr ptr long long ptr) -@ stub -version=0x600+ NtCreatePrivateNamespace +@ stdcall -stub -version=0x600+ NtCreatePrivateNamespace(ptr long ptr ptr) @ stdcall NtCreateProcess(ptr long ptr ptr long ptr ptr ptr) @ stdcall NtCreateProcessEx(ptr long ptr ptr long ptr ptr ptr long) @ stdcall NtCreateProfile(ptr ptr ptr long long ptr long long long) ; CHECKME -@ stub -version=0x600+ NtCreateResourceManager +@ stdcall -stub -version=0x600+ NtCreateResourceManager(ptr long ptr ptr ptr long wstr) @ stdcall NtCreateSection(ptr long ptr ptr long long ptr) @ stdcall NtCreateSemaphore(ptr long ptr long long) @ stdcall NtCreateSymbolicLinkObject(ptr long ptr ptr) @@ -291,11 +295,11 @@ @ stub -version=0x600+ NtCreateThreadEx @ stdcall NtCreateTimer(ptr long ptr long) @ stdcall NtCreateToken(ptr long ptr long ptr ptr ptr ptr ptr ptr ptr ptr ptr) -@ stub -version=0x600+ NtCreateTransaction -@ stub -version=0x600+ NtCreateTransactionManager -@ stub -version=0x600+ NtCreateUserProcess +@ stdcall -stub -version=0x600+ NtCreateTransaction(ptr long ptr ptr ptr long long long ptr wstr) +@ stdcall -stub -version=0x600+ NtCreateTransactionManager(ptr long ptr wstr long long) +@ stdcall -stub -version=0x600+ NtCreateUserProcess(ptr ptr long long ptr ptr long long ptr long long) @ stdcall NtCreateWaitablePort(ptr ptr long long long) -@ stub -version=0x600+ NtCreateWorkerFactory +@ stdcall -stub -version=0x600+ NtCreateWorkerFactory(ptr long long long long long long long long long) @ stdcall -arch=win32 NtCurrentTeb() _NtCurrentTeb @ stdcall NtDebugActiveProcess(ptr ptr) @ stdcall NtDebugContinue(ptr ptr long) @@ -306,7 +310,7 @@ @ stdcall NtDeleteFile(ptr) @ stdcall NtDeleteKey(long) @ stdcall NtDeleteObjectAuditAlarm(ptr ptr long) -@ stub -version=0x600+ NtDeletePrivateNamespace +@ stdcall -stub -version=0x600+ NtDeletePrivateNamespace(long) @ stdcall NtDeleteValueKey(long ptr) @ stdcall NtDeviceIoControlFile(long long long long long long long long long long) @ stdcall NtDisplayString(ptr) @@ -322,37 +326,37 @@ @ stdcall NtFilterToken(ptr long ptr ptr ptr ptr) @ stdcall NtFindAtom(ptr long ptr) @ stdcall NtFlushBuffersFile(long ptr) -@ stub -version=0x600+ NtFlushInstallUILanguage +@ stdcall -stub -version=0x600+ NtFlushInstallUILanguage(long long) @ stdcall NtFlushInstructionCache(long ptr long) @ stdcall NtFlushKey(long) -@ stub -version=0x600+ NtFlushProcessWriteBuffers +@ stdcall -stub -version=0x600+ NtFlushProcessWriteBuffers() @ stdcall NtFlushVirtualMemory(long ptr ptr long) @ stdcall NtFlushWriteBuffer() @ stdcall NtFreeUserPhysicalPages(ptr ptr ptr) @ stdcall NtFreeVirtualMemory(long ptr ptr long) -@ stub -version=0x600+ NtFreezeRegistry -@ stub -version=0x600+ NtFreezeTransactions +@ stdcall -stub -version=0x600+ NtFreezeRegistry(long) +@ stdcall -stub -version=0x600+ NtFreezeTransactions(ptr ptr) @ stdcall NtFsControlFile(long long long long long long long long long long) @ stdcall NtGetContextThread(long ptr) @ stdcall NtGetCurrentProcessorNumber() ; 5.2 and higher @ stdcall NtGetDevicePowerState(ptr ptr) -@ stub -version=0x600+ NtGetMUIRegistryInfo -@ stub -version=0x600+ NtGetNextProcess -@ stub -version=0x600+ NtGetNextThread -@ stub -version=0x600+ NtGetNlsSectionPtr -@ stub -version=0x600+ NtGetNotificationResourceManager +@ stdcall -stub -version=0x600+ NtGetMUIRegistryInfo(long ptr ptr) +@ stdcall -stub -version=0x600+ NtGetNextProcess(long long long long ptr) +@ stdcall -stub -version=0x600+ NtGetNextThread(ptr ptr long long long ptr) +@ stdcall -stub -version=0x600+ NtGetNlsSectionPtr(long long long ptr ptr) +@ stdcall -stub -version=0x600+ NtGetNotificationResourceManager(ptr ptr long ptr ptr long long) @ stdcall NtGetPlugPlayEvent(long long ptr long) @ stdcall NtGetTickCount() RtlGetTickCount @ stdcall NtGetWriteWatch(long long ptr long ptr ptr ptr) @ stdcall NtImpersonateAnonymousToken(ptr) @ stdcall NtImpersonateClientOfPort(ptr ptr) @ stdcall NtImpersonateThread(ptr ptr ptr) -@ stub -version=0x600+ NtInitializeNlsFiles +@ stdcall -stub -version=0x600+ NtInitializeNlsFiles(ptr ptr) @ stdcall NtInitializeRegistry(long) @ stdcall NtInitiatePowerAction (long long long long) @ stdcall NtIsProcessInJob(long long) @ stdcall NtIsSystemResumeAutomatic() -@ stub -version=0x600+ NtIsUILanguageComitted +@ stdcall -stub -version=0x600+ NtIsUILanguageComitted() @ stdcall NtListenPort(ptr ptr) @ stdcall NtLoadDriver(ptr) @ stdcall NtLoadKey2(ptr ptr long) @@ -364,7 +368,7 @@ @ stdcall NtLockVirtualMemory(long ptr ptr long) @ stdcall NtMakePermanentObject(ptr) @ stdcall NtMakeTemporaryObject(long) -@ stub -version=0x600+ NtMapCMFModule +@ stdcall -stub -version=0x600+ NtMapCMFModule(long long ptr ptr ptr ptr) @ stdcall NtMapUserPhysicalPages(ptr ptr ptr) @ stdcall NtMapUserPhysicalPagesScatter(ptr ptr ptr) @ stdcall NtMapViewOfSection(long long ptr long long ptr ptr long long long) @@ -374,43 +378,43 @@ @ stdcall NtNotifyChangeKey(long long ptr ptr ptr long long ptr long long) @ stdcall NtNotifyChangeMultipleKeys(ptr long ptr ptr ptr ptr ptr long long ptr long long) @ stdcall NtOpenDirectoryObject(long long long) -@ stub -version=0x600+ NtOpenEnlistment +@ stdcall -stub -version=0x600+ NtOpenEnlistment(ptr long ptr ptr ptr) @ stdcall NtOpenEvent(long long long) @ stdcall NtOpenEventPair(ptr long ptr) @ stdcall NtOpenFile(ptr long ptr ptr long long) @ stdcall NtOpenIoCompletion(ptr long ptr) @ stdcall NtOpenJobObject(ptr long ptr) @ stdcall NtOpenKey(ptr long ptr) -@ stub -version=0x600+ NtOpenKeyTransacted +@ stdcall -stub -version=0x600+ NtOpenKeyTransacted(ptr long ptr ptr) @ stdcall NtOpenKeyedEvent(ptr long ptr) @ stdcall NtOpenMutant(ptr long ptr) @ stdcall NtOpenObjectAuditAlarm(ptr ptr ptr ptr ptr ptr long long ptr long long ptr) -@ stub -version=0x600+ NtOpenPrivateNamespace +@ stdcall -stub -version=0x600+ NtOpenPrivateNamespace(ptr long ptr ptr) @ stdcall NtOpenProcess(ptr long ptr ptr) @ stdcall NtOpenProcessToken(long long ptr) @ stdcall NtOpenProcessTokenEx(long long long ptr) -@ stub -version=0x600+ NtOpenResourceManager +@ stdcall -stub -version=0x600+ NtOpenResourceManager(ptr long ptr ptr ptr) @ stdcall NtOpenSection(ptr long ptr) @ stdcall NtOpenSemaphore(long long ptr) -@ stub -version=0x600+ NtOpenSession +@ stdcall -stub -version=0x600+ NtOpenSession(ptr long ptr) @ stdcall NtOpenSymbolicLinkObject (ptr long ptr) @ stdcall NtOpenThread(ptr long ptr ptr) @ stdcall NtOpenThreadToken(long long long ptr) @ stdcall NtOpenThreadTokenEx(long long long long ptr) @ stdcall NtOpenTimer(ptr long ptr) -@ stub -version=0x600+ NtOpenTransaction -@ stub -version=0x600+ NtOpenTransactionManager +@ stdcall -stub -version=0x600+ NtOpenTransaction(ptr long ptr ptr ptr) +@ stdcall -stub -version=0x600+ NtOpenTransactionManager(ptr long ptr ptr ptr long) @ stdcall NtPlugPlayControl(ptr ptr long) @ stdcall NtPowerInformation(long ptr long ptr long) -@ stub -version=0x600+ NtPrePrepareComplete -@ stub -version=0x600+ NtPrePrepareEnlistment -@ stub -version=0x600+ NtPrepareComplete -@ stub -version=0x600+ NtPrepareEnlistment +@ stdcall -stub -version=0x600+ NtPrePrepareComplete(ptr ptr) +@ stdcall -stub -version=0x600+ NtPrePrepareEnlistment(ptr ptr) +@ stdcall -stub -version=0x600+ NtPrepareComplete(ptr ptr) +@ stdcall -stub -version=0x600+ NtPrepareEnlistment(ptr ptr) @ stdcall NtPrivilegeCheck(ptr ptr ptr) @ stdcall NtPrivilegeObjectAuditAlarm(ptr ptr ptr long ptr long) @ stdcall NtPrivilegedServiceAuditAlarm(ptr ptr ptr ptr long) -@ stub -version=0x600+ NtPropagationComplete -@ stub -version=0x600+ NtPropagationFailed +@ stdcall -stub -version=0x600+ NtPropagationComplete(ptr long long ptr) +@ stdcall -stub -version=0x600+ NtPropagationFailed(ptr long long) @ stdcall NtProtectVirtualMemory(long ptr ptr long ptr) @ stdcall NtPulseEvent(long ptr) @ stdcall NtQueryAttributesFile(ptr ptr) @@ -426,22 +430,22 @@ @ stdcall NtQueryEvent(long long ptr long ptr) @ stdcall NtQueryFullAttributesFile(ptr ptr) @ stdcall NtQueryInformationAtom(long long ptr long ptr) -@ stub -version=0x600+ NtQueryInformationEnlistment +@ stdcall -stub -version=0x600+ NtQueryInformationEnlistment(ptr long ptr long ptr) @ stdcall NtQueryInformationFile(ptr ptr ptr long long) @ stdcall NtQueryInformationJobObject(ptr long ptr long ptr) @ stdcall NtQueryInformationPort(ptr long ptr long ptr) @ stdcall NtQueryInformationProcess(ptr long ptr long ptr) -@ stub -version=0x600+ NtQueryInformationResourceManager +@ stdcall -stub -version=0x600+ NtQueryInformationResourceManager(ptr long ptr long ptr) @ stdcall NtQueryInformationThread(ptr long ptr long ptr) @ stdcall NtQueryInformationToken(ptr long ptr long ptr) -@ stub -version=0x600+ NtQueryInformationTransaction -@ stub -version=0x600+ NtQueryInformationTransactionManager -@ stub -version=0x600+ NtQueryInformationWorkerFactory +@ stdcall -stub -version=0x600+ NtQueryInformationTransaction(ptr long ptr ptr ptr) +@ stdcall -stub -version=0x600+ NtQueryInformationTransactionManager(ptr long ptr long ptr) +@ stdcall -stub -version=0x600+ NtQueryInformationWorkerFactory(ptr long ptr long ptr) @ stdcall NtQueryInstallUILanguage(ptr) @ stdcall NtQueryIntervalProfile(long ptr) @ stdcall NtQueryIoCompletion(long long ptr long ptr) @ stdcall NtQueryKey (long long ptr long ptr) -@ stub -version=0x600+ NtQueryLicenseValue +@ stdcall -stub -version=0x600+ NtQueryLicenseValue(wstr ptr ptr long ptr) @ stdcall NtQueryMultipleValueKey(long ptr long ptr long ptr) @ stdcall NtQueryMutant(long long ptr long ptr) @ stdcall NtQueryObject(long long long long long) @@ -468,26 +472,26 @@ @ stdcall NtRaiseHardError(long long long ptr long ptr) @ stdcall NtReadFile(long long ptr ptr ptr ptr long ptr ptr) @ stdcall NtReadFileScatter(long long ptr ptr ptr ptr long ptr ptr) -@ stub -version=0x600+ NtReadOnlyEnlistment +@ stdcall -stub -version=0x600+ NtReadOnlyEnlistment(ptr ptr) @ stdcall NtReadRequestData(ptr ptr long ptr long ptr) @ stdcall NtReadVirtualMemory(long ptr ptr long ptr) -@ stub -version=0x600+ NtRecoverEnlistment -@ stub -version=0x600+ NtRecoverResourceManager -@ stub -version=0x600+ NtRecoverTransactionManager -@ stub -version=0x600+ NtRegisterProtocolAddressInformation +@ stdcall -stub -version=0x600+ NtRecoverEnlistment(ptr ptr) +@ stdcall -stub -version=0x600+ NtRecoverResourceManager(ptr) +@ stdcall -stub -version=0x600+ NtRecoverTransactionManager(ptr) +@ stdcall -stub -version=0x600+ NtRegisterProtocolAddressInformation(ptr ptr long ptr long) @ stdcall NtRegisterThreadTerminatePort(ptr) -@ stub -version=0x600+ NtReleaseCMFViewOwnership +@ stdcall -stub -version=0x600+ NtReleaseCMFViewOwnership() @ stdcall NtReleaseKeyedEvent(ptr ptr long ptr) @ stdcall NtReleaseMutant(long ptr) @ stdcall NtReleaseSemaphore(long long ptr) -@ stub -version=0x600+ NtReleaseWorkerFactoryWorker +@ stdcall -stub -version=0x600+ NtReleaseWorkerFactoryWorker(ptr) @ stdcall NtRemoveIoCompletion(ptr ptr ptr ptr ptr) -@ stub -version=0x600+ NtRemoveIoCompletionEx +@ stdcall -stub -version=0x600+ NtRemoveIoCompletionEx(ptr ptr long ptr ptr long) @ stdcall NtRemoveProcessDebug(ptr ptr) @ stdcall NtRenameKey(ptr ptr) -@ stub -version=0x600+ NtRenameTransactionManager +@ stdcall -stub -version=0x600+ NtRenameTransactionManager(ptr ptr) @ stdcall NtReplaceKey(ptr long ptr) -@ stub -version=0x600+ NtReplacePartitionUnit +@ stdcall -stub -version=0x600+ NtReplacePartitionUnit(wstr wstr long) @ stdcall NtReplyPort(ptr ptr) @ stdcall NtReplyWaitReceivePort(ptr ptr ptr ptr) @ stdcall NtReplyWaitReceivePortEx(ptr ptr ptr ptr ptr) @@ -501,10 +505,10 @@ @ stdcall NtRestoreKey(long long long) @ stdcall NtResumeProcess(ptr) @ stdcall NtResumeThread(long long) -@ stub -version=0x600+ NtRollbackComplete -@ stub -version=0x600+ NtRollbackEnlistment -@ stub -version=0x600+ NtRollbackTransaction -@ stub -version=0x600+ NtRollforwardTransactionManager +@ stdcall -stub -version=0x600+ NtRollbackComplete(ptr ptr) +@ stdcall -stub -version=0x600+ NtRollbackEnlistment(ptr long ptr long) +@ stdcall -stub -version=0x600+ NtRollbackTransaction(ptr long) +@ stdcall -stub -version=0x600+ NtRollforwardTransactionManager(ptr ptr) @ stdcall NtSaveKey(long long) @ stdcall NtSaveKeyEx(ptr ptr long) @ stdcall NtSaveMergedKeys(ptr ptr ptr) @@ -523,18 +527,18 @@ @ stdcall NtSetHighEventPair(ptr) @ stdcall NtSetHighWaitLowEventPair(ptr) @ stdcall NtSetInformationDebugObject(ptr long ptr long ptr) -@ stub -version=0x600+ NtSetInformationEnlistment +@ stdcall -stub -version=0x600+ NtSetInformationEnlistment(ptr long ptr long) @ stdcall NtSetInformationFile(ptr ptr ptr long long) @ stdcall NtSetInformationJobObject(ptr long ptr long) @ stdcall NtSetInformationKey(ptr long ptr long) @ stdcall NtSetInformationObject(ptr long ptr long) @ stdcall NtSetInformationProcess(ptr long ptr long) -@ stub -version=0x600+ NtSetInformationResourceManager +@ stdcall -stub -version=0x600+ NtSetInformationResourceManager(ptr long ptr long) @ stdcall NtSetInformationThread(ptr long ptr long) @ stdcall NtSetInformationToken(ptr long ptr long) -@ stub -version=0x600+ NtSetInformationTransaction -@ stub -version=0x600+ NtSetInformationTransactionManager -@ stub -version=0x600+ NtSetInformationWorkerFactory +@ stdcall -stub -version=0x600+ NtSetInformationTransaction(ptr long ptr long) +@ stdcall -stub -version=0x600+ NtSetInformationTransactionManager(ptr long ptr long) +@ stdcall -stub -version=0x600+ NtSetInformationWorkerFactory(ptr long ptr long) @ stdcall NtSetIntervalProfile(long long) @ stdcall NtSetIoCompletion(ptr long ptr long long) @ stdcall NtSetLdtEntries(long int64 long int64) @@ -554,9 +558,9 @@ @ stdcall NtSetValueKey(long long long long long long) @ stdcall NtSetVolumeInformationFile(long ptr ptr long long) @ stdcall NtShutdownSystem(long) -@ stub -version=0x600+ NtShutdownWorkerFactory +@ stdcall -stub -version=0x600+ NtShutdownWorkerFactory(ptr ptr) @ stdcall NtSignalAndWaitForSingleObject(long long long ptr) -@ stub -version=0x600+ NtSinglePhaseReject +@ stdcall -stub -version=0x600+ NtSinglePhaseReject(ptr ptr) @ stdcall NtStartProfile(ptr) @ stdcall NtStopProfile(ptr) @ stdcall NtSuspendProcess(ptr) @@ -566,9 +570,9 @@ @ stdcall NtTerminateProcess(ptr long) @ stdcall NtTerminateThread(ptr long) @ stdcall NtTestAlert() -@ stub -version=0x600+ NtThawRegistry -@ stub -version=0x600+ NtThawTransactions -@ stub -version=0x600+ NtTraceControl +@ stdcall -stub -version=0x600+ NtThawRegistry() +@ stdcall -stub -version=0x600+ NtThawTransactions() +@ stdcall -stub -version=0x600+ NtTraceControl(long ptr long ptr long long) @ stdcall NtTraceEvent(long long long ptr) @ stdcall NtTranslateFilePath(ptr long ptr long) @ stdcall NtUnloadDriver(ptr) @@ -587,16 +591,16 @@ @ stub -version=0x600+ NtWaitForWorkViaWorkerFactory @ stdcall NtWaitHighEventPair(ptr) @ stdcall NtWaitLowEventPair(ptr) -@ stub -version=0x600+ NtWorkerFactoryWorkerReady +@ stdcall -stub -version=0x600+ NtWorkerFactoryWorkerReady(long) @ stdcall NtWriteFile(long long ptr ptr ptr ptr long ptr ptr) @ stdcall NtWriteFileGather(long long ptr ptr ptr ptr long ptr ptr) @ stdcall NtWriteRequestData(ptr ptr long ptr long ptr) @ stdcall NtWriteVirtualMemory(long ptr ptr long ptr) @ stdcall NtYieldExecution() -@ stub -version=0x600+ NtdllDefWindowProc_A -@ stub -version=0x600+ NtdllDefWindowProc_W -@ stub -version=0x600+ NtdllDialogWndProc_A -@ stub -version=0x600+ NtdllDialogWndProc_W +@ stdcall -stub -version=0x600+ NtdllDefWindowProc_A(long long long long) +@ stdcall -stub -version=0x600+ NtdllDefWindowProc_W(long long long long) +@ stdcall -stub -version=0x600+ NtdllDialogWndProc_A(long long long long) +@ stdcall -stub -version=0x600+ NtdllDialogWndProc_W(long long long long) @ stdcall PfxFindPrefix(ptr ptr) @ stdcall PfxInitialize(ptr) @ stdcall PfxInsertPrefix(ptr ptr ptr) @@ -627,10 +631,10 @@ @ stdcall RtlAddAuditAccessObjectAce(ptr long long long ptr ptr ptr long long) @ stdcall -stub RtlAddCompoundAce(ptr long long long ptr ptr) @ stdcall -arch=x86_64 RtlAddFunctionTable(ptr long long) -@ stub -version=0x600+ RtlAddMandatoryAce +@ stdcall -stub -version=0x600+ RtlAddMandatoryAce(ptr long long long long ptr) ; not present in Win11 @ stdcall RtlAddRefActivationContext(ptr) @ stdcall RtlAddRefMemoryStream(ptr) -@ stub -version=0x600+ RtlAddSIDToBoundaryDescriptor +@ stdcall -stub -version=0x600+ RtlAddSIDToBoundaryDescriptor(ptr ptr) ; not present in Win11 @ stdcall RtlAddVectoredContinueHandler(long ptr) @ stdcall RtlAddVectoredExceptionHandler(long ptr) @ stdcall -stub RtlAddressInSectionTable(ptr ptr long) @@ -639,8 +643,8 @@ @ stdcall RtlAllocateAndInitializeSid(ptr long long long long long long long long long ptr) @ stdcall RtlAllocateHandle(ptr ptr) @ stdcall RtlAllocateHeap(ptr long ptr) -@ stub -version=0x600+ RtlAllocateMemoryBlockLookaside -@ stub -version=0x600+ RtlAllocateMemoryZone +@ stdcall -stub -version=0x600+ RtlAllocateMemoryBlockLookaside(ptr long ptr) ; not present in Win11 +@ stdcall -stub -version=0x600+ RtlAllocateMemoryZone(long long ptr) ; not present in Win11 @ stdcall RtlAnsiCharToUnicodeChar(ptr) @ stdcall RtlAnsiStringToUnicodeSize(ptr) RtlxAnsiStringToUnicodeSize @ stdcall RtlAnsiStringToUnicodeString(ptr ptr long) @@ -657,8 +661,8 @@ @ stdcall RtlAreBitsClear(ptr long long) @ stdcall RtlAreBitsSet(ptr long long) @ stdcall RtlAssert(ptr ptr long ptr) -@ stub -version=0x600+ RtlBarrier -@ stub -version=0x600+ RtlBarrierForDelete +@ stdcall -stub -version=0x600+ RtlBarrier(ptr long) +@ stdcall -stub -version=0x600+ RtlBarrierForDelete(long long) @ stdcall RtlCancelTimer(ptr ptr) @ stdcall -register RtlCaptureContext(ptr) @ stdcall RtlCaptureStackBackTrace(long long ptr ptr) @@ -667,23 +671,23 @@ @ stdcall RtlCheckForOrphanedCriticalSections(ptr) @ stdcall -stub -version=0x502 RtlCheckProcessParameters(ptr ptr ptr ptr) @ stdcall RtlCheckRegistryKey(long ptr) -@ stub -version=0x600+ RtlCleanUpTEBLangLists +@ stdcall -stub -version=0x600+ RtlCleanUpTEBLangLists() @ stdcall RtlClearAllBits(ptr) @ stdcall RtlClearBits(ptr long long) @ stdcall RtlCloneMemoryStream(ptr ptr) -@ stub -version=0x600+ RtlCloneUserProcess -@ stub -version=0x600+ RtlCmDecodeMemIoResource -@ stub -version=0x600+ RtlCmEncodeMemIoResource -@ stub -version=0x600+ RtlCommitDebugInfo +@ stdcall -stub -version=0x600+ RtlCloneUserProcess(long long long long long) +@ stdcall -stub -version=0x600+ RtlCmDecodeMemIoResource(ptr ptr) +@ stdcall -stub -version=0x600+ RtlCmEncodeMemIoResource(ptr long long long) +@ stdcall -stub -version=0x600+ RtlCommitDebugInfo(ptr long) @ stdcall RtlCommitMemoryStream(ptr long) @ stdcall RtlCompactHeap(long long) -@ stub -version=0x600+ RtlCompareAltitudes +@ stdcall -stub -version=0x600+ RtlCompareAltitudes(wstr wstr) @ stdcall RtlCompareMemory(ptr ptr long) @ stdcall RtlCompareMemoryUlong(ptr long long) @ stdcall RtlCompareString(ptr ptr long) @ stdcall RtlCompareUnicodeString (ptr ptr long) @ stdcall -version=0x600+ RtlCompareUnicodeStrings(wstr long wstr long long) -@ stub -version=0x600+ -arch=x86_64 RtlCompleteProcessCloning +@ stdcall -stub -version=0x600+ -arch=x86_64 RtlCompleteProcessCloning(long) @ stdcall RtlCompressBuffer(long ptr long ptr long long ptr ptr) @ stdcall RtlComputeCrc32(long ptr long) @ stdcall RtlComputeImportTableHash(ptr ptr long) @@ -691,7 +695,7 @@ @ stdcall -stub -version=0x600+ RtlConnectToSm(ptr ptr long ptr) @ stdcall RtlConsoleMultiByteToUnicodeN(ptr long ptr ptr long ptr) @ stdcall RtlConvertExclusiveToShared(ptr) -@ stub -version=0x600+ RtlConvertLCIDToString +@ stdcall -version=0x600+ RtlConvertLCIDToString(long long long ptr long) @ stdcall -arch=win32 -ret64 RtlConvertLongToLargeInteger(long) @ stdcall RtlConvertSharedToExclusive(ptr) @ stdcall RtlConvertSidToUnicodeString(ptr ptr long) @@ -702,7 +706,7 @@ @ stdcall RtlCopyLuidAndAttributesArray(long ptr ptr) @ stdcall RtlCopyMappedMemory(ptr ptr long) @ cdecl -version=0x600+ -arch=x86_64 RtlCopyMemory(ptr ptr long) memmove -@ stub -version=0x600+ -arch=x86_64 RtlCopyMemoryNonTemporal +@ stdcall -stub -version=0x600+ -arch=x86_64 RtlCopyMemoryNonTemporal(ptr ptr long) @ stdcall RtlCopyMemoryStreamTo(ptr ptr int64 ptr ptr) @ stdcall RtlCopyOutOfProcessMemoryStreamTo(ptr ptr int64 ptr ptr) RtlCopyMemoryStreamTo @ stdcall RtlCopySecurityDescriptor(ptr ptr) @@ -715,14 +719,14 @@ @ stdcall RtlCreateAndSetSD(ptr long ptr ptr ptr) @ stdcall RtlCreateAtomTable(long ptr) @ stdcall RtlCreateBootStatusDataFile() -@ stub -version=0x600+ RtlCreateBoundaryDescriptor +@ stdcall -stub -version=0x600+ RtlCreateBoundaryDescriptor(ptr long) @ stdcall RtlCreateEnvironment(long ptr) -@ stub -version=0x600+ RtlCreateEnvironmentEx +@ stdcall -stub -version=0x600+ RtlCreateEnvironmentEx(ptr ptr long) @ stdcall RtlCreateHeap(long ptr long long ptr ptr) -@ stub -version=0x600+ RtlCreateMemoryBlockLookaside -@ stub -version=0x600+ RtlCreateMemoryZone +@ stdcall -stub -version=0x600+ RtlCreateMemoryBlockLookaside(ptr long long long long) +@ stdcall -stub -version=0x600+ RtlCreateMemoryZone(ptr long long) @ stdcall RtlCreateProcessParameters(ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr) -@ stub -version=0x600+ RtlCreateProcessParametersEx +@ stdcall -stub -version=0x600+ RtlCreateProcessParametersEx(ptr wstr ptr wstr wstr ptr wstr wstr ptr ptr long) @ stdcall RtlCreateQueryDebugBuffer(long long) @ stdcall RtlCreateRegistryKey(long wstr) @ stdcall RtlCreateSecurityDescriptor(ptr long) @@ -735,12 +739,12 @@ @ stdcall RtlCreateUnicodeStringFromAsciiz(ptr str) @ stdcall RtlCreateUserProcess(ptr long ptr ptr ptr ptr long ptr ptr ptr) @ stdcall RtlCreateUserSecurityObject(ptr long ptr ptr long ptr ptr) -@ stub -version=0x600+ RtlCreateUserStack +@ stdcall -stub -version=0x600+ RtlCreateUserStack(long long long long long ptr) @ stdcall RtlCreateUserThread(long ptr long ptr long long ptr ptr ptr ptr) -@ stub -version=0x600+ RtlCultureNameToLCID +@ stdcall -version=0x600+ RtlCultureNameToLCID(ptr ptr) @ stdcall RtlCustomCPToUnicodeN(ptr wstr long ptr str long) @ stdcall RtlCutoverTimeToSystemTime(ptr ptr ptr long) -@ stub -version=0x600+ RtlDeCommitDebugInfo +@ stdcall -stub -version=0x600+ RtlDeCommitDebugInfo(long long long) ; doesn't exist in win11 @ stdcall RtlDeNormalizeProcessParams(ptr) @ stdcall RtlDeactivateActivationContext(long long) @ stdcall -arch=x86_64,arm RtlDeactivateActivationContextUnsafeFast(ptr) @@ -753,8 +757,8 @@ @ stdcall RtlDelete(ptr) @ stdcall RtlDeleteAce(ptr long) @ stdcall RtlDeleteAtomFromAtomTable(ptr long) -@ stub -version=0x600+ RtlDeleteBarrier -@ stub -version=0x600+ RtlDeleteBoundaryDescriptor +@ stdcall -stub -version=0x600+ RtlDeleteBarrier(long) +@ stdcall -stub -version=0x600+ RtlDeleteBoundaryDescriptor(ptr) @ stdcall RtlDeleteCriticalSection(ptr) @ stdcall RtlDeleteElementGenericTable(ptr ptr) @ stdcall RtlDeleteElementGenericTableAvl(ptr ptr) @@ -766,15 +770,15 @@ @ stdcall RtlDeleteTimer(ptr ptr ptr) @ stdcall RtlDeleteTimerQueue(ptr) @ stdcall RtlDeleteTimerQueueEx(ptr ptr) -@ stub -version=0x600+ RtlDeregisterSecureMemoryCacheCallback +@ stdcall -stub -version=0x600+ RtlDeregisterSecureMemoryCacheCallback(ptr) @ stdcall RtlDeregisterWait(ptr) @ stdcall RtlDeregisterWaitEx(ptr ptr) @ stdcall RtlDestroyAtomTable(ptr) @ stdcall RtlDestroyEnvironment(ptr) @ stdcall RtlDestroyHandleTable(ptr) @ stdcall RtlDestroyHeap(long) -@ stub -version=0x600+ RtlDestroyMemoryBlockLookaside -@ stub -version=0x600+ RtlDestroyMemoryZone +@ stdcall -stub -version=0x600+ RtlDestroyMemoryBlockLookaside(long) +@ stdcall -stub -version=0x600+ RtlDestroyMemoryZone(long) @ stdcall RtlDestroyProcessParameters(ptr) @ stdcall RtlDestroyQueryDebugBuffer(ptr) @ stdcall RtlDetermineDosPathNameType_U(wstr) @@ -814,27 +818,27 @@ @ stdcall RtlEqualString(ptr ptr long) @ stdcall RtlEqualUnicodeString(ptr ptr long) @ stdcall RtlEraseUnicodeString(ptr) -@ stub -version=0x600+ RtlExitUserProcess +@ stdcall -stub -version=0x600+ RtlExitUserProcess(long) @ stdcall RtlExitUserThread(long) -@ stub -version=0x600+ RtlExpandEnvironmentStrings +@ stdcall -stub -version=0x600+ RtlExpandEnvironmentStrings(long ptr long ptr long ptr) @ stdcall RtlExpandEnvironmentStrings_U(ptr ptr ptr ptr) @ stdcall -version=0x502 RtlExtendHeap(ptr long ptr ptr) -@ stub -version=0x600+ RtlExtendMemoryBlockLookaside -@ stub -version=0x600+ RtlExtendMemoryZone +@ stdcall -stub -version=0x600+ RtlExtendMemoryBlockLookaside(long) +@ stdcall -stub -version=0x600+ RtlExtendMemoryZone(long long) @ stdcall -arch=win32 -ret64 RtlExtendedIntegerMultiply(double long) @ stdcall -arch=win32 -ret64 RtlExtendedLargeIntegerDivide(double long ptr) @ stdcall -arch=win32 -ret64 RtlExtendedMagicDivide(double double long) @ stdcall RtlFillMemory(ptr long long) @ stdcall -arch=i386,arm RtlFillMemoryUlong(ptr long long) @ stdcall RtlFinalReleaseOutOfProcessMemoryStream(ptr) -@ stub -version=0x600+ RtlFindAceByType +@ stdcall -stub -version=0x600+ RtlFindAceByType(long long ptr) @ stdcall RtlFindActivationContextSectionGuid(long ptr long ptr ptr) @ stdcall RtlFindActivationContextSectionString(long ptr long ptr ptr) @ stdcall RtlFindCharInUnicodeString(long ptr ptr ptr) @ stdcall RtlFindClearBits(ptr long long) @ stdcall RtlFindClearBitsAndSet(ptr long long) @ stdcall RtlFindClearRuns(ptr ptr long long) -@ stub -version=0x600+ RtlFindClosestEncodableLength +@ stdcall -stub -version=0x600+ RtlFindClosestEncodableLength(long ptr) @ stdcall RtlFindLastBackwardRunClear(ptr long ptr) @ stdcall RtlFindLeastSignificantBit(double) @ stdcall RtlFindLongestRunClear(ptr long) @@ -845,8 +849,8 @@ @ stdcall RtlFindSetBitsAndClear(ptr long long) @ stdcall RtlFirstEntrySList(ptr) @ stdcall RtlFirstFreeAce(ptr ptr) -@ stub -version=0x600+ RtlFlsAlloc -@ stub -version=0x600+ RtlFlsFree +@ stdcall -stub -version=0x600+ RtlFlsAlloc(long long long long) +@ stdcall -stub -version=0x600+ RtlFlsFree(long) @ stdcall RtlFlushSecureMemoryCache(ptr ptr) @ stdcall RtlFormatCurrentUserKeyPath(ptr) @ stdcall RtlFormatMessage(ptr long long long long ptr ptr long ptr) @@ -855,12 +859,12 @@ @ stdcall RtlFreeAnsiString(long) @ stdcall RtlFreeHandle(ptr ptr) @ stdcall RtlFreeHeap(long long long) -@ stub -version=0x600+ RtlFreeMemoryBlockLookaside +@ stdcall -stub -version=0x600+ RtlFreeMemoryBlockLookaside(long long) @ stdcall RtlFreeOemString(ptr) @ stdcall RtlFreeSid(long) @ stdcall RtlFreeThreadActivationContextStack() @ stdcall RtlFreeUnicodeString(ptr) -@ stub -version=0x600+ RtlFreeUserStack +@ stdcall -stub -version=0x600+ RtlFreeUserStack(long) @ stdcall -version=0x502 RtlFreeUserThreadStack(ptr ptr) @ stdcall RtlGUIDFromString(ptr ptr) @ stdcall RtlGenerate8dot3Name(ptr ptr long ptr) @@ -873,11 +877,11 @@ @ stdcall RtlGetCurrentDirectory_U(long ptr) @ stdcall RtlGetCurrentPeb() @ stdcall RtlGetCurrentProcessorNumber() ; 5.2 SP1 and higher -@ stub -version=0x600+ RtlGetCurrentTransaction +@ stdcall -stub -version=0x600+ RtlGetCurrentTransaction() @ stdcall RtlGetDaclSecurityDescriptor(ptr ptr ptr ptr) @ stdcall RtlGetElementGenericTable(ptr long) @ stdcall RtlGetElementGenericTableAvl(ptr long) -@ stub -version=0x600+ RtlGetFileMUIPath +@ stdcall -stub -version=0x600+ RtlGetFileMUIPath(long long ptr ptr long long ptr) @ stdcall RtlGetFrame() @ stdcall RtlGetFullPathName_U(wstr long ptr ptr) @ stdcall RtlGetFullPathName_UstrEx(ptr ptr ptr ptr ptr ptr ptr ptr) @@ -895,38 +899,38 @@ @ stdcall RtlGetNtProductType(ptr) @ stdcall RtlGetNtVersionNumbers(ptr ptr ptr) @ stdcall RtlGetOwnerSecurityDescriptor(ptr ptr ptr) -@ stub -version=0x600+ RtlGetParentLocaleName +@ stdcall -stub -version=0x600+ RtlGetParentLocaleName(wstr long long long) @ stdcall RtlGetProcessHeaps(long ptr) @ stub -version=0x600+ RtlGetProductInfo @ stdcall RtlGetSaclSecurityDescriptor(ptr ptr ptr ptr) @ stdcall RtlGetSecurityDescriptorRMControl(ptr ptr) @ stdcall RtlGetSetBootStatusData(ptr long long ptr long long) -@ stub -version=0x600+ RtlGetSystemPreferredUILanguages +@ stdcall -stub -version=0x600+ RtlGetSystemPreferredUILanguages(long ptr ptr ptr ptr) @ stdcall RtlGetThreadErrorMode() -@ stub -version=0x600+ RtlGetThreadLangIdByIndex -@ stub -version=0x600+ RtlGetThreadPreferredUILanguages -@ stub -version=0x600+ RtlGetUILanguageInfo +@ stdcall -stub -version=0x600+ RtlGetThreadLangIdByIndex(long long ptr ptr) +@ stdcall -stub -version=0x600+ RtlGetThreadPreferredUILanguages(long long ptr ptr) +@ stdcall -stub -version=0x600+ RtlGetUILanguageInfo(long ptr long ptr ptr) @ stdcall RtlGetUnloadEventTrace() -@ stub -version=0x600+ RtlGetUnloadEventTraceEx +@ stdcall -stub -version=0x600+ RtlGetUnloadEventTraceEx(ptr ptr ptr) @ stdcall RtlGetUserInfoHeap(ptr long ptr ptr ptr) -@ stub -version=0x600+ RtlGetUserPreferredUILanguages +@ stdcall -stub -version=0x600+ RtlGetUserPreferredUILanguages(long ptr ptr ptr ptr) @ stdcall RtlGetVersion(ptr) @ stdcall RtlHashUnicodeString(ptr long long ptr) -@ stub -version=0x600+ RtlHeapTrkInitialize +@ stdcall -stub -version=0x600+ RtlHeapTrkInitialize(ptr) @ stdcall RtlIdentifierAuthoritySid(ptr) -@ stub -version=0x600+ RtlIdnToAscii -@ stub -version=0x600+ RtlIdnToNameprepUnicode -@ stub -version=0x600+ RtlIdnToUnicode +@ stdcall -stub -version=0x600+ RtlIdnToAscii(long long long long long) +@ stdcall -stub -version=0x600+ RtlIdnToNameprepUnicode(long long long long long) +@ stdcall -stub -version=0x600+ RtlIdnToUnicode(long long long long long) @ stdcall RtlImageDirectoryEntryToData(ptr long long ptr) @ stdcall RtlImageNtHeader(long) @ stdcall RtlImageNtHeaderEx(long ptr double ptr) @ stdcall RtlImageRvaToSection(ptr long long) @ stdcall RtlImageRvaToVa(ptr long long ptr) @ stdcall RtlImpersonateSelf(long) -@ stub -version=0x600+ RtlImpersonateSelfEx +@ stdcall -stub -version=0x600+ RtlImpersonateSelfEx(long long ptr) @ stdcall RtlInitAnsiString(ptr str) @ stdcall RtlInitAnsiStringEx(ptr str) -@ stub -version=0x600+ RtlInitBarrier +@ stdcall -stub -version=0x600+ RtlInitBarrier(long long) @ stdcall RtlInitCodePageTable(ptr ptr) @ stdcall RtlInitMemoryStream(ptr) @ stdcall RtlInitNlsTables(ptr ptr ptr ptr) @@ -941,11 +945,11 @@ @ stdcall RtlInitializeCriticalSection(ptr) @ stdcall RtlInitializeCriticalSectionAndSpinCount(ptr long) @ stdcall -version=0x600+ RtlInitializeCriticalSectionEx(ptr long long) -@ stub -version=0x600+ -arch=i386 RtlInitializeExceptionChain +@ stdcall -stub -version=0x600+ -arch=i386 RtlInitializeExceptionChain(ptr) @ stdcall RtlInitializeGenericTable(ptr ptr ptr ptr ptr) @ stdcall RtlInitializeGenericTableAvl(ptr ptr ptr ptr ptr) @ stdcall RtlInitializeHandleTable(long long ptr) -@ stub -version=0x600+ RtlInitializeNtUserPfn +@ stdcall -stub -version=0x600+ RtlInitializeNtUserPfn(wstr long ptr long wstr ptr) @ stdcall RtlInitializeRXact(ptr long ptr) @ stdcall RtlInitializeResource(ptr) @ stdcall RtlInitializeSListHead(ptr) @@ -964,8 +968,8 @@ @ stdcall RtlInterlockedPopEntrySList(ptr) @ stdcall RtlInterlockedPushEntrySList(ptr ptr) @ stdcall -arch=x86_64 RtlInterlockedPushListSList(ptr ptr ptr long) -@ stub -version=0x600+ RtlIoDecodeMemIoResource -@ stub -version=0x600+ RtlIoEncodeMemIoResource +@ stdcall -stub -version=0x600+ RtlIoDecodeMemIoResource(ptr ptr ptr ptr) +@ stdcall -stub -version=0x600+ RtlIoEncodeMemIoResource(ptr long long long long long) @ stdcall RtlIpv4AddressToStringA(ptr ptr) @ stdcall RtlIpv4AddressToStringExA(ptr long ptr ptr) @ stdcall RtlIpv4AddressToStringExW(ptr long ptr ptr) @@ -985,18 +989,18 @@ @ stdcall RtlIsActivationContextActive(ptr) @ stdcall RtlIsCriticalSectionLocked(ptr) @ stdcall RtlIsCriticalSectionLockedByThread(ptr) -@ stub -version=0x600+ RtlIsCurrentThreadAttachExempt +@ stdcall -stub -version=0x600+ RtlIsCurrentThreadAttachExempt() @ stdcall RtlIsDosDeviceName_U(wstr) @ stdcall RtlIsGenericTableEmpty(ptr) @ stdcall RtlIsGenericTableEmptyAvl(ptr) @ stdcall RtlIsNameLegalDOS8Dot3(ptr ptr ptr) -@ stub -version=0x600+ RtlIsNormalizedString +@ stdcall -stub -version=0x600+ RtlIsNormalizedString(long ptr long ptr) @ stdcall RtlIsTextUnicode(ptr long ptr) @ stdcall RtlIsThreadWithinLoaderCallout() @ stdcall RtlIsValidHandle(ptr ptr) @ stdcall RtlIsValidIndexHandle(ptr long ptr) -@ stub -version=0x600+ RtlIsValidLocaleName -@ stub -version=0x600+ RtlLCIDToCultureName +@ stdcall -version=0x600+ RtlIsValidLocaleName(wstr long) +@ stdcall -version=0x600+ RtlLCIDToCultureName(long ptr) @ stdcall -arch=win32 -ret64 RtlLargeIntegerAdd(double double) @ stdcall -arch=win32 -ret64 RtlLargeIntegerArithmeticShift(double long) @ stdcall -arch=win32 -ret64 RtlLargeIntegerDivide(double double ptr) @@ -1005,20 +1009,20 @@ @ stdcall -arch=win32 -ret64 RtlLargeIntegerShiftRight(double long) @ stdcall -arch=win32 -ret64 RtlLargeIntegerSubtract(double double) @ stdcall RtlLargeIntegerToChar(ptr long long ptr) -@ stub -version=0x600+ RtlLcidToLocaleName +@ stdcall -version=0x600+ RtlLcidToLocaleName(long ptr long long) @ stdcall RtlLeaveCriticalSection(ptr) @ stdcall RtlLengthRequiredSid(long) @ stdcall RtlLengthSecurityDescriptor(ptr) @ stdcall RtlLengthSid(ptr) @ stdcall RtlLocalTimeToSystemTime(ptr ptr) -@ stub -version=0x600+ RtlLocaleNameToLcid +@ stdcall -version=0x600+ RtlLocaleNameToLcid(wstr ptr long) @ stdcall RtlLockBootStatusData(ptr) -@ stub -version=0x600+ RtlLockCurrentThread +@ stdcall -stub -version=0x600+ RtlLockCurrentThread() @ stdcall RtlLockHeap(long) -@ stub -version=0x600+ RtlLockMemoryBlockLookaside +@ stdcall -stub -version=0x600+ RtlLockMemoryBlockLookaside(long) @ stdcall RtlLockMemoryStreamRegion(ptr int64 int64 long) -@ stub -version=0x600+ RtlLockMemoryZone -@ stub -version=0x600+ RtlLockModuleSection +@ stdcall -stub -version=0x600+ RtlLockMemoryZone(long) +@ stdcall -stub -version=0x600+ RtlLockModuleSection(long) @ stdcall -stub RtlLogStackBackTrace() @ stdcall RtlLookupAtomInAtomTable(ptr wstr ptr) @ stdcall RtlLookupElementGenericTable(ptr ptr) @@ -1042,7 +1046,7 @@ @ stdcall RtlNewSecurityObjectEx(ptr ptr ptr ptr long long ptr ptr) @ stdcall RtlNewSecurityObjectWithMultipleInheritance(ptr ptr ptr ptr long long long ptr ptr) @ stdcall RtlNormalizeProcessParams(ptr) -@ stub -version=0x600+ RtlNormalizeString +@ stdcall -stub -version=0x600+ RtlNormalizeString(long long long long ptr) @ stdcall RtlNtPathNameToDosPathName(long ptr ptr ptr) ; CHECKME (last arg) @ stdcall RtlNtStatusToDosError(long) @ stdcall RtlNtStatusToDosErrorNoTeb(long) @@ -1051,35 +1055,35 @@ @ stdcall RtlNumberGenericTableElementsAvl(ptr) @ stdcall RtlNumberOfClearBits(ptr) @ stdcall RtlNumberOfSetBits(ptr) -@ stub -version=0x600+ RtlNumberOfSetBitsUlongPtr +@ stdcall -stub -version=0x600+ RtlNumberOfSetBitsUlongPtr(long) @ stdcall RtlOemStringToUnicodeSize(ptr) RtlxOemStringToUnicodeSize @ stdcall RtlOemStringToUnicodeString(ptr ptr long) @ stdcall RtlOemToUnicodeN(ptr long ptr ptr long) @ stdcall RtlOpenCurrentUser(long ptr) -@ stub -version=0x600+ RtlOwnerAcesPresent +@ stdcall -stub -version=0x600+ RtlOwnerAcesPresent(long) @ stdcall RtlPcToFileHeader(ptr ptr) @ stdcall RtlPinAtomInAtomTable(ptr long) @ stdcall RtlPopFrame(ptr) @ stdcall RtlPrefixString(ptr ptr long) @ stdcall RtlPrefixUnicodeString(ptr ptr long) -@ stub -version=0x600+ -arch=x86_64 RtlPrepareForProcessCloning -@ stub -version=0x600+ RtlProcessFlsData +@ stdcall -stub -version=0x600+ -arch=x86_64 RtlPrepareForProcessCloning() +@ stdcall -stub -version=0x600+ RtlProcessFlsData(long long) @ stdcall RtlProtectHeap(ptr long) @ stdcall RtlPushFrame(ptr) @ stdcall -version=0x600+ RtlQueryActivationContextApplicationSettings(long ptr wstr wstr ptr ptr ptr) @ stdcall RtlQueryAtomInAtomTable(ptr long ptr ptr ptr ptr) -@ stub -version=0x600+ RtlQueryCriticalSectionOwner +@ stdcall -stub -version=0x600+ RtlQueryCriticalSectionOwner(ptr) @ stdcall RtlQueryDepthSList(ptr) -@ stub -version=0x600+ RtlQueryDynamicTimeZoneInformation -@ stub -version=0x600+ RtlQueryElevationFlags -@ stub -version=0x600+ RtlQueryEnvironmentVariable +@ stdcall -stub -version=0x600+ RtlQueryDynamicTimeZoneInformation(ptr) +@ stdcall -stub -version=0x600+ RtlQueryElevationFlags(ptr) +@ stdcall -stub -version=0x600+ RtlQueryEnvironmentVariable(ptr ptr long ptr long ptr) @ stdcall RtlQueryEnvironmentVariable_U(ptr ptr ptr) @ stdcall RtlQueryHeapInformation(long long ptr long ptr) @ stdcall RtlQueryInformationAcl(ptr ptr long long) @ stdcall RtlQueryInformationActivationContext(long long ptr long ptr long ptr) @ stdcall RtlQueryInformationActiveActivationContext(long ptr long ptr) @ stdcall RtlQueryInterfaceMemoryStream(ptr ptr ptr) -@ stub -version=0x600+ RtlQueryModuleInformation +@ stdcall -stub -version=0x600+ RtlQueryModuleInformation(ptr long ptr) @ stdcall -stub RtlQueryProcessBackTraceInformation(ptr) @ stdcall RtlQueryProcessDebugInformation(long long ptr) @ stdcall RtlQueryProcessHeapInformation(ptr) @@ -1114,13 +1118,13 @@ @ stdcall -version=0x600+ RtlRemovePrivileges(ptr ptr long) @ stdcall RtlRemoveVectoredContinueHandler(ptr) @ stdcall RtlRemoveVectoredExceptionHandler(ptr) -@ stub -version=0x600+ RtlReportException -@ stub -version=0x600+ RtlResetMemoryBlockLookaside -@ stub -version=0x600+ RtlResetMemoryZone +@ stdcall -stub -version=0x600+ RtlReportException(long long long) +@ stdcall -stub -version=0x600+ RtlResetMemoryBlockLookaside(long) +@ stdcall -stub -version=0x600+ RtlResetMemoryZone(long) @ stdcall RtlResetRtlTranslations(ptr) @ stdcall -arch=x86_64 RtlRestoreContext(ptr ptr) @ stdcall RtlRestoreLastWin32Error(long) RtlSetLastWin32Error -@ stub -version=0x600+ RtlRetrieveNtUserPfn +@ stdcall -stub -version=0x600+ RtlRetrieveNtUserPfn(ptr ptr ptr) @ stdcall RtlRevertMemoryStream(ptr) @ stdcall RtlRunDecodeUnicodeString(long ptr) @ stdcall RtlRunEncodeUnicodeString(long ptr) @@ -1141,11 +1145,11 @@ @ stdcall RtlSetCriticalSectionSpinCount(ptr long) @ stdcall RtlSetCurrentDirectory_U(ptr) @ stdcall RtlSetCurrentEnvironment(wstr ptr) -@ stub -version=0x600+ RtlSetCurrentTransaction +@ stdcall -stub -version=0x600+ RtlSetCurrentTransaction(ptr) @ stdcall RtlSetDaclSecurityDescriptor(ptr long ptr long) -@ stub -version=0x600+ RtlSetDynamicTimeZoneInformation +@ stdcall -stub -version=0x600+ RtlSetDynamicTimeZoneInformation(long) @ stdcall RtlSetEnvironmentStrings(wstr long) -@ stub -version=0x600+ RtlSetEnvironmentVar +@ stdcall -stub -version=0x600+ RtlSetEnvironmentVar(ptr ptr long ptr long) @ stdcall RtlSetEnvironmentVariable(ptr ptr ptr) @ stdcall RtlSetGroupSecurityDescriptor(ptr ptr long) @ stdcall RtlSetHeapInformation(ptr long ptr ptr) @@ -1155,7 +1159,7 @@ @ stdcall RtlSetLastWin32ErrorAndNtStatusFromNtStatus(long) @ stdcall RtlSetMemoryStreamSize(ptr int64) @ stdcall RtlSetOwnerSecurityDescriptor(ptr ptr long) -@ stub -version=0x600+ RtlSetProcessDebugInformation +@ stdcall -stub -version=0x600+ RtlSetProcessDebugInformation(ptr long ptr) @ cdecl RtlSetProcessIsCritical(long ptr long) @ stdcall RtlSetSaclSecurityDescriptor(ptr long ptr long) @ stdcall RtlSetSecurityDescriptorRMControl(ptr ptr) @@ -1164,18 +1168,18 @@ @ stdcall RtlSetThreadErrorMode(long ptr) @ cdecl RtlSetThreadIsCritical(long ptr long) @ stdcall RtlSetThreadPoolStartFunc(ptr ptr) -@ stub -version=0x600+ RtlSetThreadPreferredUILanguages +@ stdcall -stub -version=0x600+ RtlSetThreadPreferredUILanguages(long ptr ptr) @ stdcall RtlSetTimeZoneInformation(ptr) @ stdcall RtlSetTimer(ptr ptr ptr ptr long long long) @ stdcall RtlSetUnhandledExceptionFilter(ptr) @ stdcall -stub -version=0x502 RtlSetUnicodeCallouts(ptr) @ stdcall RtlSetUserFlagsHeap(ptr long ptr long long) @ stdcall RtlSetUserValueHeap(ptr long ptr ptr) -@ stub -version=0x600+ RtlSidDominates -@ stub -version=0x600+ RtlSidEqualLevel -@ stub -version=0x600+ RtlSidHashInitialize -@ stub -version=0x600+ RtlSidHashLookup -@ stub -version=0x600+ RtlSidIsHigherLevel +@ stdcall -stub -version=0x600+ RtlSidDominates(long long ptr) +@ stdcall -stub -version=0x600+ RtlSidEqualLevel(long long ptr) +@ stdcall -stub -version=0x600+ RtlSidHashInitialize(ptr long ptr) +@ stdcall -stub -version=0x600+ RtlSidHashLookup(long ptr) +@ stdcall -stub -version=0x600+ RtlSidIsHigherLevel(long long ptr) @ stdcall RtlSizeHeap(long long ptr) @ stdcall -version=0x600+ RtlSleepConditionVariableCS(ptr ptr ptr) @ stdcall -version=0x600+ RtlSleepConditionVariableSRW(ptr ptr ptr long) @@ -1202,7 +1206,9 @@ @ stdcall RtlTraceDatabaseLock(ptr) @ stdcall RtlTraceDatabaseUnlock(ptr) @ stdcall RtlTraceDatabaseValidate(ptr) -@ stub -version=0x600+ RtlTryAcquirePebLock +@ stdcall -stub -version=0x600+ RtlTryAcquirePebLock() +@ stdcall -version=0x601 RtlTryAcquireSRWLockExclusive(ptr) +@ stdcall -version=0x601 RtlTryAcquireSRWLockShared(ptr) @ stdcall RtlTryEnterCriticalSection(ptr) @ stdcall RtlUnhandledExceptionFilter2(ptr long) @ stdcall RtlUnhandledExceptionFilter(ptr) @@ -1218,14 +1224,14 @@ @ stdcall RtlUnicodeToOemN(ptr long ptr ptr long) @ stdcall RtlUniform(ptr) @ stdcall RtlUnlockBootStatusData(ptr) -@ stub -version=0x600+ RtlUnlockCurrentThread +@ stdcall -stub -version=0x600+ RtlUnlockCurrentThread() @ stdcall RtlUnlockHeap(long) -@ stub -version=0x600+ RtlUnlockMemoryBlockLookaside +@ stdcall -stub -version=0x600+ RtlUnlockMemoryBlockLookaside(long) @ stdcall RtlUnlockMemoryStreamRegion(ptr int64 int64 long) -@ stub -version=0x600+ RtlUnlockMemoryZone -@ stub -version=0x600+ RtlUnlockModuleSection +@ stdcall -stub -version=0x600+ RtlUnlockMemoryZone(long) +@ stdcall -stub -version=0x600+ RtlUnlockModuleSection(long) @ stdcall -register RtlUnwind(ptr ptr ptr ptr) -@ stdcall -arch=x86_64 RtlUnwindEx(long long ptr long ptr) +@ stdcall -arch=x86_64 RtlUnwindEx(ptr ptr ptr ptr ptr ptr) @ stdcall RtlUpcaseUnicodeChar(long) @ stdcall RtlUpcaseUnicodeString(ptr ptr long) @ stdcall RtlUpcaseUnicodeStringToAnsiString(ptr ptr long) @@ -1234,13 +1240,13 @@ @ stdcall RtlUpcaseUnicodeToCustomCPN(ptr ptr long ptr wstr long) @ stdcall RtlUpcaseUnicodeToMultiByteN(ptr long ptr ptr long) @ stdcall RtlUpcaseUnicodeToOemN(ptr long ptr ptr long) -@ stub -version=0x600+ RtlUpdateClonedCriticalSection -@ stub -version=0x600+ RtlUpdateClonedSRWLock +@ stdcall -stub -version=0x600+ RtlUpdateClonedCriticalSection(long) +@ stdcall -stub -version=0x600+ RtlUpdateClonedSRWLock(ptr long) @ stdcall RtlUpdateTimer(ptr ptr long long) @ stdcall RtlUpperChar(long) @ stdcall RtlUpperString(ptr ptr) @ stdcall -version=0x502 RtlUsageHeap(ptr long ptr) -@ stub -version=0x600+ RtlUserThreadStart +@ stdcall -stub -version=0x600+ RtlUserThreadStart(long long) @ stdcall RtlValidAcl(ptr) @ stdcall RtlValidRelativeSecurityDescriptor(ptr long long) @ stdcall RtlValidSecurityDescriptor(ptr) @@ -1249,43 +1255,43 @@ @ stdcall RtlValidateProcessHeaps() @ stdcall RtlValidateUnicodeString(long ptr) @ stdcall RtlVerifyVersionInfo(ptr long double) -@ stdcall -arch=x86_64 RtlVirtualUnwind(long long long ptr ptr ptr ptr ptr) +@ stdcall -arch=x86_64 RtlVirtualUnwind(long int64 int64 ptr ptr ptr ptr ptr) @ stdcall -version=0x600+ RtlWakeAllConditionVariable(ptr) @ stdcall -version=0x600+ RtlWakeConditionVariable(ptr) @ stdcall RtlWalkFrameChain(ptr long long) @ stdcall RtlWalkHeap(long ptr) -@ stub -version=0x600+ RtlWerpReportException -@ stub -version=0x600+ RtlWow64CallFunction64 +@ stdcall -stub -version=0x600+ RtlWerpReportException(long long ptr long long ptr) +@ stdcall -stub -version=0x600+ RtlWow64CallFunction64() @ stdcall RtlWow64EnableFsRedirection(long) @ stdcall RtlWow64EnableFsRedirectionEx(long ptr) -@ stub -version=0x600+ -arch=x86_64 RtlWow64GetThreadContext -@ stub -version=0x600+ -arch=x86_64 RtlWow64LogMessageInEventLogger -@ stub -version=0x600+ -arch=x86_64 RtlWow64SetThreadContext -@ stub -version=0x600+ -arch=x86_64 RtlWow64SuspendThread +@ stdcall -stub -version=0x600+ -arch=x86_64 RtlWow64GetThreadContext(ptr ptr) +@ stdcall -stub -version=0x600+ -arch=x86_64 RtlWow64LogMessageInEventLogger(long long long) +@ stdcall -stub -version=0x600+ -arch=x86_64 RtlWow64SetThreadContext(long long) +@ stdcall -stub -version=0x600+ -arch=x86_64 RtlWow64SuspendThread(long long) @ stdcall RtlWriteMemoryStream(ptr ptr long ptr) @ stdcall RtlWriteRegistryValue(long ptr ptr long ptr long) @ stdcall RtlZeroHeap(ptr long) @ stdcall RtlZeroMemory(ptr long) @ stdcall RtlZombifyActivationContext(ptr) @ stdcall RtlpApplyLengthFunction(long long ptr ptr) -@ stub -version=0x600+ RtlpCheckDynamicTimeZoneInformation -@ stub -version=0x600+ RtlpCleanupRegistryKeys -@ stub -version=0x600+ RtlpConvertCultureNamesToLCIDs -@ stub -version=0x600+ RtlpConvertLCIDsToCultureNames -@ stub -version=0x600+ RtlpCreateProcessRegistryInfo +@ stdcall -stub -version=0x600+ RtlpCheckDynamicTimeZoneInformation(ptr long) +@ stdcall -stub -version=0x600+ RtlpCleanupRegistryKeys() +@ stdcall -stub -version=0x600+ RtlpConvertCultureNamesToLCIDs(wstr ptr) +@ stdcall -stub -version=0x600+ RtlpConvertLCIDsToCultureNames(wstr ptr) +@ stdcall -stub -version=0x600+ RtlpCreateProcessRegistryInfo(ptr) @ stdcall RtlpEnsureBufferSize(long ptr long) -@ stub -version=0x600+ RtlpGetLCIDFromLangInfoNode -@ stub -version=0x600+ RtlpGetNameFromLangInfoNode -@ stub -version=0x600+ RtlpGetSystemDefaultUILanguage -@ stub -version=0x600+ RtlpGetUserOrMachineUILanguage4NLS -@ stub -version=0x600+ RtlpInitializeLangRegistryInfo -@ stub -version=0x600+ RtlpIsQualifiedLanguage -@ stub -version=0x600+ RtlpLoadMachineUIByPolicy -@ stub -version=0x600+ RtlpLoadUserUIByPolicy -@ stub -version=0x600+ RtlpMuiFreeLangRegistryInfo -@ stub -version=0x600+ RtlpMuiRegCreateRegistryInfo -@ stub -version=0x600+ RtlpMuiRegFreeRegistryInfo -@ stub -version=0x600+ RtlpMuiRegLoadRegistryInfo +@ stdcall -stub -version=0x600+ RtlpGetLCIDFromLangInfoNode(long long ptr) +@ stdcall -stub -version=0x600+ RtlpGetNameFromLangInfoNode(long long long) +@ stdcall -stub -version=0x600+ RtlpGetSystemDefaultUILanguage(ptr long) +@ stdcall -stub -version=0x600+ RtlpGetUserOrMachineUILanguage4NLS(long long ptr) +@ stdcall -stub -version=0x600+ RtlpInitializeLangRegistryInfo(ptr) +@ stdcall -stub -version=0x600+ RtlpIsQualifiedLanguage(long ptr long) +@ stdcall -stub -version=0x600+ RtlpLoadMachineUIByPolicy(ptr long ptr) +@ stdcall -stub -version=0x600+ RtlpLoadUserUIByPolicy(ptr long ptr) +@ stdcall -stub -version=0x600+ RtlpMuiFreeLangRegistryInfo(long) +@ stdcall -stub -version=0x600+ RtlpMuiRegCreateRegistryInfo() +@ stdcall -stub -version=0x600+ RtlpMuiRegFreeRegistryInfo(long long) +@ stdcall -stub -version=0x600+ RtlpMuiRegLoadRegistryInfo(long long) @ stdcall RtlpNotOwnerCriticalSection(ptr) @ stdcall RtlpNtCreateKey(ptr long ptr long ptr ptr) @ stdcall RtlpNtEnumerateSubKey(ptr ptr long long) @@ -1293,74 +1299,76 @@ @ stdcall RtlpNtOpenKey(ptr long ptr long) @ stdcall RtlpNtQueryValueKey(ptr ptr ptr ptr long) @ stdcall RtlpNtSetValueKey(ptr long ptr long) -@ stub -version=0x600+ RtlpQueryDefaultUILanguage -@ stub -version=0x600+ -arch=x86_64 RtlpQueryProcessDebugInformationFromWow64 -@ stub -version=0x600+ RtlpRefreshCachedUILanguage -@ stub -version=0x600+ RtlpSetInstallLanguage -@ stub -version=0x600+ RtlpSetPreferredUILanguages -@ stub -version=0x600+ RtlpSetUserPreferredUILanguages +@ stdcall -stub -version=0x600+ RtlpQueryDefaultUILanguage(ptr long) +@ stdcall -stub -version=0x600+ -arch=x86_64 RtlpQueryProcessDebugInformationFromWow64(long ptr) +@ stdcall -stub -version=0x600+ RtlpRefreshCachedUILanguage(wstr long) +@ stdcall -stub -version=0x600+ RtlpSetInstallLanguage(long ptr) +@ stdcall -stub -version=0x600+ RtlpSetPreferredUILanguages(long ptr ptr) ; x64 only? +@ stdcall -stub -arch=i386 -version=0x600+ RtlpSetUserPreferredUILanguages(long ptr ptr) ; seems to be i386 only @ stdcall RtlpUnWaitCriticalSection(ptr) -@ stub -version=0x600+ RtlpVerifyAndCommitUILanguageSettings +@ stdcall -stub -version=0x600+ RtlpVerifyAndCommitUILanguageSettings(long) @ stdcall RtlpWaitForCriticalSection(ptr) @ stdcall RtlxAnsiStringToUnicodeSize(ptr) @ stdcall RtlxOemStringToUnicodeSize(ptr) @ stdcall RtlxUnicodeStringToAnsiSize(ptr) @ stdcall RtlxUnicodeStringToOemSize(ptr) -@ stub -version=0x600+ ShipAssert -@ stub -version=0x600+ ShipAssertGetBufferInfo -@ stub -version=0x600+ ShipAssertMsgA -@ stub -version=0x600+ ShipAssertMsgW -@ stub -version=0x600+ TpAllocAlpcCompletion -@ stub -version=0x600+ TpAllocCleanupGroup -@ stub -version=0x600+ TpAllocIoCompletion -@ stub -version=0x600+ TpAllocPool -@ stub -version=0x600+ TpAllocTimer -@ stub -version=0x600+ TpAllocWait -@ stub -version=0x600+ TpAllocWork -@ stub -version=0x600+ TpCallbackLeaveCriticalSectionOnCompletion -@ stub -version=0x600+ TpCallbackMayRunLong -@ stub -version=0x600+ TpCallbackReleaseMutexOnCompletion -@ stub -version=0x600+ TpCallbackReleaseSemaphoreOnCompletion -@ stub -version=0x600+ TpCallbackSetEventOnCompletion -@ stub -version=0x600+ TpCallbackUnloadDllOnCompletion -@ stub -version=0x600+ TpCancelAsyncIoOperation -@ stub -version=0x600+ TpCaptureCaller -@ stub -version=0x600+ TpCheckTerminateWorker -@ stub -version=0x600+ TpDbgDumpHeapUsage -@ stub -version=0x600+ TpDbgSetLogRoutine -@ stub -version=0x600+ TpDisassociateCallback -@ stub -version=0x600+ TpIsTimerSet -@ stub -version=0x600+ TpPostWork -@ stub -version=0x600+ TpReleaseAlpcCompletion -@ stub -version=0x600+ TpReleaseCleanupGroup -@ stub -version=0x600+ TpReleaseCleanupGroupMembers -@ stub -version=0x600+ TpReleaseIoCompletion -@ stub -version=0x600+ TpReleasePool -@ stub -version=0x600+ TpReleaseTimer -@ stub -version=0x600+ TpReleaseWait -@ stub -version=0x600+ TpReleaseWork -@ stub -version=0x600+ TpSetPoolMaxThreads -@ stub -version=0x600+ TpSetPoolMinThreads -@ stub -version=0x600+ TpSetTimer -@ stub -version=0x600+ TpSetWait -@ stub -version=0x600+ TpSimpleTryPost -@ stub -version=0x600+ TpStartAsyncIoOperation -@ stub -version=0x600+ TpWaitForAlpcCompletion -@ stub -version=0x600+ TpWaitForIoCompletion -@ stub -version=0x600+ TpWaitForTimer -@ stub -version=0x600+ TpWaitForWait -@ stub -version=0x600+ TpWaitForWork +@ stdcall -stub -version=0x600+ ShipAssert(long long) +@ stdcall -stub -version=0x600+ ShipAssertGetBufferInfo(ptr ptr) +@ stdcall -stub -version=0x600+ ShipAssertMsgA(long long) +@ stdcall -stub -version=0x600+ ShipAssertMsgW(long long) +@ stdcall -stub -version=0x600+ TpAllocAlpcCompletion(ptr ptr ptr ptr ptr) +@ stdcall -version=0x600+ TpAllocCleanupGroup(ptr) +@ stdcall -version=0x600+ TpAllocIoCompletion(ptr ptr ptr ptr ptr) +@ stdcall -version=0x600+ TpAllocPool(ptr ptr) +@ stdcall -version=0x600+ TpAllocTimer(ptr ptr ptr ptr) +@ stdcall -version=0x600+ TpAllocWait(ptr ptr ptr ptr) +@ stdcall -version=0x600+ TpAllocWork(ptr ptr ptr ptr) +@ stdcall -version=0x600+ TpCallbackLeaveCriticalSectionOnCompletion(ptr ptr) +@ stdcall -version=0x600+ TpCallbackMayRunLong(ptr) +@ stdcall -version=0x600+ TpCallbackReleaseMutexOnCompletion(ptr ptr) +@ stdcall -version=0x600+ TpCallbackReleaseSemaphoreOnCompletion(ptr ptr long) +@ stdcall -version=0x600+ TpCallbackSetEventOnCompletion(ptr ptr) +@ stdcall -version=0x600+ TpCallbackUnloadDllOnCompletion(ptr ptr) +@ stdcall -version=0x600+ TpCancelAsyncIoOperation(ptr) +@ stdcall -stub -version=0x600+ TpCaptureCaller(long) +@ stdcall -stub -version=0x600+ TpCheckTerminateWorker(ptr) +@ stdcall -stub -version=0x600+ TpDbgDumpHeapUsage(long ptr long) +@ stdcall -stub -version=0x600+ TpDbgSetLogRoutine() +@ stdcall -version=0x600+ TpDisassociateCallback(ptr) +@ stdcall -version=0x600+ TpIsTimerSet(ptr) +@ stdcall -version=0x600+ TpPostWork(ptr) +@ stdcall -version=0x600+ TpQueryPoolStackInformation(ptr ptr) +@ stdcall -stub -version=0x600+ TpReleaseAlpcCompletion(ptr) +@ stdcall -version=0x600+ TpReleaseCleanupGroup(ptr) +@ stdcall -version=0x600+ TpReleaseCleanupGroupMembers(ptr long ptr) +@ stdcall -version=0x600+ TpReleaseIoCompletion(ptr) +@ stdcall -version=0x600+ TpReleasePool(ptr) +@ stdcall -version=0x600+ TpReleaseTimer(ptr) +@ stdcall -version=0x600+ TpReleaseWait(ptr) +@ stdcall -version=0x600+ TpReleaseWork(ptr) +@ stdcall -version=0x600+ TpSetPoolMaxThreads(ptr long) +@ stdcall -version=0x600+ TpSetPoolMinThreads(ptr long) +@ stdcall -version=0x600+ TpSetPoolStackInformation(ptr ptr) +@ stdcall -version=0x600+ TpSetTimer(ptr ptr long long) +@ stdcall -version=0x600+ TpSetWait(ptr long ptr) +@ stdcall -version=0x600+ TpSimpleTryPost(ptr ptr ptr) +@ stdcall -version=0x600+ TpStartAsyncIoOperation(ptr) +@ stdcall -stub -version=0x600+ TpWaitForAlpcCompletion(ptr) +@ stdcall -version=0x600+ TpWaitForIoCompletion(ptr long) +@ stdcall -version=0x600+ TpWaitForTimer(ptr long) +@ stdcall -version=0x600+ TpWaitForWait(ptr long) +@ stdcall -version=0x600+ TpWaitForWork(ptr long) @ stdcall -ret64 VerSetConditionMask(double long long) -@ stub -version=0x600+ WerCheckEventEscalation -@ stub -version=0x600+ WerReportSQMEvent -@ stub -version=0x600+ WerReportWatsonEvent -@ stub -version=0x600+ WinSqmAddToStream -@ stub -version=0x600+ WinSqmEndSession -@ stub -version=0x600+ WinSqmEventEnabled -@ stub -version=0x600+ WinSqmEventWrite -@ stub -version=0x600+ WinSqmIsOptedIn -@ stub -version=0x600+ WinSqmSetString -@ stub -version=0x600+ WinSqmStartSession +@ stdcall -stub -version=0x600+ WerCheckEventEscalation(long ptr) ; doesn't exist in win11 +@ stdcall -stub -version=0x600+ WerReportSQMEvent(long long long) +@ stdcall -stub -version=0x600+ WerReportWatsonEvent(long long long long) ; doesn't exist in win11 +@ stdcall -stub -version=0x600+ WinSqmAddToStream(ptr long long long) ; stub on Win11? +@ stdcall -stub -version=0x600+ WinSqmEndSession(ptr) ; stub on Win11? +@ stdcall -stub -version=0x600+ WinSqmEventEnabled(long ptr) ; stub on Win11? +@ stdcall -stub -version=0x600+ WinSqmEventWrite(long long long) ; stub on Win11? +@ stdcall -stub -version=0x600+ WinSqmIsOptedIn() ; stub on Win11? +@ stdcall -stub -version=0x600+ WinSqmSetString(ptr long ptr) ; stub on Win11? +@ stdcall -stub -version=0x600+ WinSqmStartSession(ptr) ; stub on Win11? @ stdcall ZwAcceptConnectPort(ptr long ptr long long ptr) @ stdcall ZwAccessCheck(ptr long long ptr ptr ptr ptr ptr) @ stdcall ZwAccessCheckAndAuditAlarm(ptr long ptr ptr ptr long ptr long ptr ptr ptr) @@ -1408,15 +1416,15 @@ @ stdcall ZwCallbackReturn(ptr long long) @ stdcall ZwCancelDeviceWakeupRequest(ptr) @ stdcall ZwCancelIoFile(long ptr) -@ stub -version=0x600+ ZwCancelIoFileEx -@ stub -version=0x600+ ZwCancelSynchronousIoFile +@ stdcall -stub -version=0x600+ ZwCancelIoFileEx(ptr ptr ptr) +@ stdcall -stub -version=0x600+ ZwCancelSynchronousIoFile(ptr ptr ptr) @ stdcall ZwCancelTimer(long ptr) @ stdcall ZwClearEvent(long) @ stdcall ZwClose(long) @ stdcall ZwCloseObjectAuditAlarm(ptr ptr long) -@ stub -version=0x600+ ZwCommitComplete -@ stub -version=0x600+ ZwCommitEnlistment -@ stub -version=0x600+ ZwCommitTransaction +@ stdcall -stub -version=0x600+ ZwCommitComplete(ptr ptr) +@ stdcall -stub -version=0x600+ ZwCommitEnlistment(ptr ptr) +@ stdcall -stub -version=0x600+ ZwCommitTransaction(ptr long) @ stdcall ZwCompactKeys(long ptr) @ stdcall ZwCompareTokens(ptr ptr ptr) @ stdcall ZwCompleteConnectPort(ptr) @@ -1425,7 +1433,7 @@ @ stdcall ZwContinue(ptr long) @ stdcall ZwCreateDebugObject(ptr long ptr long) @ stdcall ZwCreateDirectoryObject(long long long) -@ stub -version=0x600+ ZwCreateEnlistment +@ stdcall -stub -version=0x600+ ZwCreateEnlistment(ptr long ptr ptr ptr long long ptr) @ stdcall ZwCreateEvent(long long long long long) @ stdcall ZwCreateEventPair(ptr long ptr) @ stdcall ZwCreateFile(ptr long ptr ptr long long long ptr long long ptr) @@ -1433,7 +1441,7 @@ @ stdcall ZwCreateJobObject(ptr long ptr) @ stdcall ZwCreateJobSet(long ptr long) @ stdcall ZwCreateKey(ptr long ptr long ptr long long) -@ stub -version=0x600+ ZwCreateKeyTransacted +@ stdcall -stub -version=0x600+ ZwCreateKeyTransacted(ptr long ptr long ptr long ptr ptr) @ stdcall ZwCreateKeyedEvent(ptr long ptr long) @ stdcall ZwCreateMailslotFile(long long long long long long long long) @ stdcall ZwCreateMutant(ptr long ptr long) @@ -1443,19 +1451,19 @@ @ stdcall ZwCreateProcess(ptr long ptr ptr long ptr ptr ptr) @ stdcall ZwCreateProcessEx(ptr long ptr ptr long ptr ptr ptr long) @ stdcall ZwCreateProfile(ptr ptr ptr long long ptr long long long) ; CHECKME -@ stub -version=0x600+ ZwCreateResourceManager +@ stdcall -stub -version=0x600+ ZwCreateResourceManager(ptr long ptr ptr ptr long wstr) @ stdcall ZwCreateSection(ptr long ptr ptr long long long) @ stdcall ZwCreateSemaphore(ptr long ptr long long) @ stdcall ZwCreateSymbolicLinkObject(ptr long ptr ptr) @ stdcall ZwCreateThread(ptr long ptr ptr ptr ptr ptr long) -@ stub -version=0x600+ ZwCreateThreadEx +@ stdcall -stub -version=0x600+ ZwCreateThreadEx(ptr long ptr ptr ptr ptr long long long long ptr) @ stdcall ZwCreateTimer(ptr long ptr long) @ stdcall ZwCreateToken(ptr long ptr long ptr ptr ptr ptr ptr ptr ptr ptr ptr) -@ stub -version=0x600+ ZwCreateTransaction -@ stub -version=0x600+ ZwCreateTransactionManager -@ stub -version=0x600+ ZwCreateUserProcess +@ stdcall -stub -version=0x600+ ZwCreateTransaction(ptr long ptr ptr ptr long long long ptr wstr) +@ stdcall -stub -version=0x600+ ZwCreateTransactionManager(ptr long ptr ptr long long) +@ stdcall -stub -version=0x600+ ZwCreateUserProcess(ptr ptr long long ptr ptr long long ptr ptr ptr) @ stdcall ZwCreateWaitablePort(ptr ptr long long long) -@ stub -version=0x600+ ZwCreateWorkerFactory +@ stdcall -stub -version=0x600+ ZwCreateWorkerFactory(ptr long ptr ptr ptr ptr ptr long long long) @ stdcall ZwDebugActiveProcess(ptr ptr) @ stdcall ZwDebugContinue(ptr ptr long) @ stdcall ZwDelayExecution(long ptr) @@ -1465,7 +1473,7 @@ @ stdcall ZwDeleteFile(ptr) @ stdcall ZwDeleteKey(long) @ stdcall ZwDeleteObjectAuditAlarm(ptr ptr long) -@ stub -version=0x600+ ZwDeletePrivateNamespace +@ stdcall -stub -version=0x600+ ZwDeletePrivateNamespace(ptr) @ stdcall ZwDeleteValueKey(long ptr) @ stdcall ZwDeviceIoControlFile(long long long long long long long long long long) @ stdcall ZwDisplayString(ptr) @@ -1475,42 +1483,42 @@ @ stdcall ZwEnumerateDriverEntries(ptr ptr) @ stdcall ZwEnumerateKey(long long long ptr long ptr) @ stdcall ZwEnumerateSystemEnvironmentValuesEx(long ptr long) -@ stub -version=0x600+ ZwEnumerateTransactionObject +@ stdcall -stub -version=0x600+ ZwEnumerateTransactionObject(ptr long ptr long ptr) @ stdcall ZwEnumerateValueKey(long long long ptr long ptr) @ stdcall ZwExtendSection(ptr ptr) @ stdcall ZwFilterToken(ptr long ptr ptr ptr ptr) @ stdcall ZwFindAtom(ptr long ptr) @ stdcall ZwFlushBuffersFile(long ptr) -@ stub -version=0x600+ ZwFlushInstallUILanguage +@ stdcall -stub -version=0x600+ ZwFlushInstallUILanguage(long long) @ stdcall ZwFlushInstructionCache(long ptr long) @ stdcall ZwFlushKey(long) -@ stub -version=0x600+ ZwFlushProcessWriteBuffers +@ stdcall -stub -version=0x600+ ZwFlushProcessWriteBuffers() @ stdcall ZwFlushVirtualMemory(long ptr ptr long) @ stdcall ZwFlushWriteBuffer() @ stdcall ZwFreeUserPhysicalPages(ptr ptr ptr) @ stdcall ZwFreeVirtualMemory(long ptr ptr long) -@ stub -version=0x600+ ZwFreezeRegistry -@ stub -version=0x600+ ZwFreezeTransactions +@ stdcall -stub -version=0x600+ ZwFreezeRegistry(long) +@ stdcall -stub -version=0x600+ ZwFreezeTransactions(ptr ptr) @ stdcall ZwFsControlFile(long long long long long long long long long long) @ stdcall ZwGetContextThread(long ptr) @ stdcall ZwGetCurrentProcessorNumber() @ stdcall ZwGetDevicePowerState(ptr ptr) -@ stub -version=0x600+ ZwGetMUIRegistryInfo -@ stub -version=0x600+ ZwGetNextProcess -@ stub -version=0x600+ ZwGetNextThread -@ stub -version=0x600+ ZwGetNlsSectionPtr -@ stub -version=0x600+ ZwGetNotificationResourceManager +@ stdcall -stub -version=0x600+ ZwGetMUIRegistryInfo(long ptr ptr) +@ stdcall -stub -version=0x600+ ZwGetNextProcess(ptr long long long ptr) +@ stdcall -stub -version=0x600+ ZwGetNextThread(ptr ptr long long long ptr) +@ stdcall -stub -version=0x600+ ZwGetNlsSectionPtr(long long ptr ptr ptr) +@ stdcall -stub -version=0x600+ ZwGetNotificationResourceManager(ptr ptr long ptr ptr long ptr) @ stdcall ZwGetPlugPlayEvent(long long ptr long) @ stdcall ZwGetWriteWatch(long long ptr long ptr ptr ptr) @ stdcall ZwImpersonateAnonymousToken(ptr) @ stdcall ZwImpersonateClientOfPort(ptr ptr) @ stdcall ZwImpersonateThread(ptr ptr ptr) -@ stub -version=0x600+ ZwInitializeNlsFiles +@ stdcall -stub -version=0x600+ ZwInitializeNlsFiles(ptr ptr ptr ptr) @ stdcall ZwInitializeRegistry(long) @ stdcall ZwInitiatePowerAction(long long long long) @ stdcall ZwIsProcessInJob(long long) @ stdcall ZwIsSystemResumeAutomatic() -@ stub -version=0x600+ ZwIsUILanguageComitted +@ stdcall -stub -version=0x600+ ZwIsUILanguageComitted() @ stdcall ZwListenPort(ptr ptr) @ stdcall ZwLoadDriver(ptr) @ stdcall ZwLoadKey2(ptr ptr long) @@ -1522,7 +1530,7 @@ @ stdcall ZwLockVirtualMemory(long ptr ptr long) @ stdcall ZwMakePermanentObject(ptr) @ stdcall ZwMakeTemporaryObject(long) -@ stub -version=0x600+ ZwMapCMFModule +@ stdcall -stub -version=0x600+ ZwMapCMFModule(long long ptr ptr ptr) @ stdcall ZwMapUserPhysicalPages(ptr ptr ptr) @ stdcall ZwMapUserPhysicalPagesScatter(ptr ptr ptr) @ stdcall ZwMapViewOfSection(long long ptr long long ptr ptr long long long) @@ -1532,43 +1540,43 @@ @ stdcall ZwNotifyChangeKey(long long ptr ptr ptr long long ptr long long) @ stdcall ZwNotifyChangeMultipleKeys(ptr long ptr ptr ptr ptr ptr long long ptr long long) @ stdcall ZwOpenDirectoryObject(long long long) -@ stub -version=0x600+ ZwOpenEnlistment +@ stdcall -stub -version=0x600+ ZwOpenEnlistment(ptr long ptr ptr ptr) @ stdcall ZwOpenEvent(long long long) @ stdcall ZwOpenEventPair(ptr long ptr) @ stdcall ZwOpenFile(ptr long ptr ptr long long) @ stdcall ZwOpenIoCompletion(ptr long ptr) @ stdcall ZwOpenJobObject(ptr long ptr) @ stdcall ZwOpenKey(ptr long ptr) -@ stub -version=0x600+ ZwOpenKeyTransacted +@ stdcall -stub -version=0x600+ ZwOpenKeyTransacted(ptr long ptr ptr) @ stdcall ZwOpenKeyedEvent(ptr long ptr) @ stdcall ZwOpenMutant(ptr long ptr) @ stdcall ZwOpenObjectAuditAlarm(ptr ptr ptr ptr ptr ptr long long ptr long long ptr) -@ stub -version=0x600+ ZwOpenPrivateNamespace +@ stdcall -stub -version=0x600+ ZwOpenPrivateNamespace(ptr long ptr ptr) @ stdcall ZwOpenProcess(ptr long ptr ptr) @ stdcall ZwOpenProcessToken(long long ptr) @ stdcall ZwOpenProcessTokenEx(long long long ptr) -@ stub -version=0x600+ ZwOpenResourceManager +@ stdcall -stub -version=0x600+ ZwOpenResourceManager(ptr long ptr ptr ptr) @ stdcall ZwOpenSection(ptr long ptr) @ stdcall ZwOpenSemaphore(long long ptr) -@ stub -version=0x600+ ZwOpenSession +@ stdcall -stub -version=0x600+ ZwOpenSession(ptr long ptr) @ stdcall ZwOpenSymbolicLinkObject (ptr long ptr) @ stdcall ZwOpenThread(ptr long ptr ptr) @ stdcall ZwOpenThreadToken(long long long ptr) @ stdcall ZwOpenThreadTokenEx(long long long long ptr) @ stdcall ZwOpenTimer(ptr long ptr) -@ stub -version=0x600+ ZwOpenTransaction -@ stub -version=0x600+ ZwOpenTransactionManager +@ stdcall -stub -version=0x600+ ZwOpenTransaction(ptr long ptr ptr ptr) +@ stdcall -stub -version=0x600+ ZwOpenTransactionManager(ptr long ptr wstr ptr long) @ stdcall ZwPlugPlayControl(ptr ptr long) @ stdcall ZwPowerInformation(long ptr long ptr long) -@ stub -version=0x600+ ZwPrePrepareComplete -@ stub -version=0x600+ ZwPrePrepareEnlistment -@ stub -version=0x600+ ZwPrepareComplete -@ stub -version=0x600+ ZwPrepareEnlistment +@ stdcall -stub -version=0x600+ ZwPrePrepareComplete(ptr ptr) +@ stdcall -stub -version=0x600+ ZwPrePrepareEnlistment(ptr ptr) +@ stdcall -stub -version=0x600+ ZwPrepareComplete(ptr ptr) +@ stdcall -stub -version=0x600+ ZwPrepareEnlistment(ptr ptr) @ stdcall ZwPrivilegeCheck(ptr ptr ptr) @ stdcall ZwPrivilegeObjectAuditAlarm(ptr ptr ptr long ptr long) @ stdcall ZwPrivilegedServiceAuditAlarm(ptr ptr ptr ptr long) -@ stub -version=0x600+ ZwPropagationComplete -@ stub -version=0x600+ ZwPropagationFailed +@ stdcall -stub -version=0x600+ ZwPropagationComplete(ptr long long ptr) +@ stdcall -stub -version=0x600+ ZwPropagationFailed(ptr long long) @ stdcall ZwProtectVirtualMemory(long ptr ptr long ptr) @ stdcall ZwPulseEvent(long ptr) @ stdcall ZwQueryAttributesFile(ptr ptr) @@ -1584,22 +1592,22 @@ @ stdcall ZwQueryEvent(long long ptr long ptr) @ stdcall ZwQueryFullAttributesFile(ptr ptr) @ stdcall ZwQueryInformationAtom(long long ptr long ptr) -@ stub -version=0x600+ ZwQueryInformationEnlistment +@ stdcall -stub -version=0x600+ ZwQueryInformationEnlistment(ptr long ptr long ptr) @ stdcall ZwQueryInformationFile(long ptr ptr long long) @ stdcall ZwQueryInformationJobObject(long long ptr long ptr) @ stdcall ZwQueryInformationPort(ptr long ptr long ptr) @ stdcall ZwQueryInformationProcess(long long ptr long ptr) -@ stub -version=0x600+ ZwQueryInformationResourceManager +@ stdcall -stub -version=0x600+ ZwQueryInformationResourceManager(ptr long ptr long ptr) @ stdcall ZwQueryInformationThread(long long ptr long ptr) @ stdcall ZwQueryInformationToken(long long ptr long ptr) -@ stub -version=0x600+ ZwQueryInformationTransaction -@ stub -version=0x600+ ZwQueryInformationTransactionManager -@ stub -version=0x600+ ZwQueryInformationWorkerFactory +@ stdcall -stub -version=0x600+ ZwQueryInformationTransaction(ptr long ptr long ptr) +@ stdcall -stub -version=0x600+ ZwQueryInformationTransactionManager(ptr) +@ stdcall -stub -version=0x600+ ZwQueryInformationWorkerFactory(ptr long ptr long ptr) @ stdcall ZwQueryInstallUILanguage(ptr) @ stdcall ZwQueryIntervalProfile(long ptr) @ stdcall ZwQueryIoCompletion(long long ptr long ptr) @ stdcall ZwQueryKey(long long ptr long ptr) -@ stub -version=0x600+ ZwQueryLicenseValue +@ stdcall -stub -version=0x600+ ZwQueryLicenseValue(ptr ptr ptr long ptr) @ stdcall ZwQueryMultipleValueKey(long ptr long ptr long ptr) @ stdcall ZwQueryMutant(long long ptr long ptr) @ stdcall ZwQueryObject(long long long long long) @@ -1626,26 +1634,26 @@ @ stdcall ZwRaiseHardError(long long long ptr long ptr) @ stdcall ZwReadFile(long long ptr ptr ptr ptr long ptr ptr) @ stdcall ZwReadFileScatter(long long ptr ptr ptr ptr long ptr ptr) -@ stub -version=0x600+ ZwReadOnlyEnlistment +@ stdcall -stub -version=0x600+ ZwReadOnlyEnlistment(ptr ptr) @ stdcall ZwReadRequestData(ptr ptr long ptr long ptr) @ stdcall ZwReadVirtualMemory(long ptr ptr long ptr) -@ stub -version=0x600+ ZwRecoverEnlistment -@ stub -version=0x600+ ZwRecoverResourceManager -@ stub -version=0x600+ ZwRecoverTransactionManager -@ stub -version=0x600+ ZwRegisterProtocolAddressInformation +@ stdcall -stub -version=0x600+ ZwRecoverEnlistment(ptr ptr) +@ stdcall -stub -version=0x600+ ZwRecoverResourceManager(ptr) +@ stdcall -stub -version=0x600+ ZwRecoverTransactionManager(ptr) +@ stdcall -stub -version=0x600+ ZwRegisterProtocolAddressInformation(ptr ptr long ptr long) @ stdcall ZwRegisterThreadTerminatePort(ptr) -@ stub -version=0x600+ ZwReleaseCMFViewOwnership +@ stdcall -stub -version=0x600+ ZwReleaseCMFViewOwnership() @ stdcall ZwReleaseKeyedEvent(ptr ptr long ptr) @ stdcall ZwReleaseMutant(long ptr) @ stdcall ZwReleaseSemaphore(long long ptr) -@ stub -version=0x600+ ZwReleaseWorkerFactoryWorker +@ stdcall -stub -version=0x600+ ZwReleaseWorkerFactoryWorker(ptr) @ stdcall ZwRemoveIoCompletion(ptr ptr ptr ptr ptr) -@ stub -version=0x600+ ZwRemoveIoCompletionEx +@ stdcall -stub -version=0x600+ ZwRemoveIoCompletionEx(ptr ptr long ptr ptr long) @ stdcall ZwRemoveProcessDebug(ptr ptr) @ stdcall ZwRenameKey(ptr ptr) -@ stub -version=0x600+ ZwRenameTransactionManager +@ stdcall -stub -version=0x600+ ZwRenameTransactionManager(wstr ptr) @ stdcall ZwReplaceKey(ptr long ptr) -@ stub -version=0x600+ ZwReplacePartitionUnit +@ stdcall -stub -version=0x600+ ZwReplacePartitionUnit(wstr wstr long) @ stdcall ZwReplyPort(ptr ptr) @ stdcall ZwReplyWaitReceivePort(ptr ptr ptr ptr) @ stdcall ZwReplyWaitReceivePortEx(ptr ptr ptr ptr ptr) @@ -1659,10 +1667,10 @@ @ stdcall ZwRestoreKey(long long long) @ stdcall ZwResumeProcess(ptr) @ stdcall ZwResumeThread(long long) -@ stub -version=0x600+ ZwRollbackComplete -@ stub -version=0x600+ ZwRollbackEnlistment -@ stub -version=0x600+ ZwRollbackTransaction -@ stub -version=0x600+ ZwRollforwardTransactionManager +@ stdcall -stub -version=0x600+ ZwRollbackComplete(ptr ptr) +@ stdcall -stub -version=0x600+ ZwRollbackEnlistment(ptr ptr) +@ stdcall -stub -version=0x600+ ZwRollbackTransaction(ptr long) +@ stdcall -stub -version=0x600+ ZwRollforwardTransactionManager(ptr ptr) @ stdcall ZwSaveKey(long long) @ stdcall ZwSaveKeyEx(ptr ptr long) @ stdcall ZwSaveMergedKeys(ptr ptr ptr) @@ -1681,18 +1689,18 @@ @ stdcall ZwSetHighEventPair(ptr) @ stdcall ZwSetHighWaitLowEventPair(ptr) @ stdcall ZwSetInformationDebugObject(ptr long ptr long ptr) -@ stub -version=0x600+ ZwSetInformationEnlistment +@ stdcall -stub -version=0x600+ ZwSetInformationEnlistment(ptr long ptr long) @ stdcall ZwSetInformationFile(long long long long long) @ stdcall ZwSetInformationJobObject(long long ptr long) @ stdcall ZwSetInformationKey(long long ptr long) @ stdcall ZwSetInformationObject(long long ptr long) @ stdcall ZwSetInformationProcess(long long long long) -@ stub -version=0x600+ ZwSetInformationResourceManager +@ stdcall -stub -version=0x600+ ZwSetInformationResourceManager(ptr long ptr long) @ stdcall ZwSetInformationThread(long long ptr long) @ stdcall ZwSetInformationToken(long long ptr long) -@ stub -version=0x600+ ZwSetInformationTransaction -@ stub -version=0x600+ ZwSetInformationTransactionManager -@ stub -version=0x600+ ZwSetInformationWorkerFactory +@ stdcall -stub -version=0x600+ ZwSetInformationTransaction(ptr long ptr long) +@ stdcall -stub -version=0x600+ ZwSetInformationTransactionManager(ptr long ptr long) +@ stdcall -stub -version=0x600+ ZwSetInformationWorkerFactory(ptr long ptr long) @ stdcall ZwSetIntervalProfile(long long) @ stdcall ZwSetIoCompletion(ptr long ptr long long) @ stdcall ZwSetLdtEntries(long int64 long int64) @@ -1712,9 +1720,9 @@ @ stdcall ZwSetValueKey(long long long long long long) @ stdcall ZwSetVolumeInformationFile(long ptr ptr long long) @ stdcall ZwShutdownSystem(long) -@ stub -version=0x600+ ZwShutdownWorkerFactory +@ stdcall -stub -version=0x600+ ZwShutdownWorkerFactory(ptr ptr) @ stdcall ZwSignalAndWaitForSingleObject(long long long ptr) -@ stub -version=0x600+ ZwSinglePhaseReject +@ stdcall -stub -version=0x600+ ZwSinglePhaseReject(ptr ptr) @ stdcall ZwStartProfile(ptr) @ stdcall ZwStopProfile(ptr) @ stdcall ZwSuspendProcess(ptr) @@ -1724,9 +1732,9 @@ @ stdcall ZwTerminateProcess(ptr long) @ stdcall ZwTerminateThread(ptr long) @ stdcall ZwTestAlert() -@ stub -version=0x600+ ZwThawRegistry -@ stub -version=0x600+ ZwThawTransactions -@ stub -version=0x600+ ZwTraceControl +@ stdcall -stub -version=0x600+ ZwThawRegistry() +@ stdcall -stub -version=0x600+ ZwThawTransactions() +@ stdcall -stub -version=0x600+ ZwTraceControl(long ptr long ptr long long) @ stdcall ZwTraceEvent(long long long ptr) @ stdcall ZwTranslateFilePath(ptr long ptr long) @ stdcall ZwUnloadDriver(ptr) @@ -1742,10 +1750,10 @@ @ stdcall ZwWaitForMultipleObjects32(long ptr long long ptr) @ stdcall ZwWaitForMultipleObjects(long ptr long long ptr) @ stdcall ZwWaitForSingleObject(long long long) -@ stub -version=0x600+ ZwWaitForWorkViaWorkerFactory +@ stdcall -stub -version=0x600+ ZwWaitForWorkViaWorkerFactory(ptr ptr long ptr ptr) @ stdcall ZwWaitHighEventPair(ptr) @ stdcall ZwWaitLowEventPair(ptr) -@ stub -version=0x600+ ZwWorkerFactoryWorkerReady +@ stdcall -stub -version=0x600+ ZwWorkerFactoryWorkerReady(ptr) @ stdcall ZwWriteFile(long long ptr ptr ptr ptr long ptr ptr) @ stdcall ZwWriteFileGather(long long ptr ptr ptr ptr long ptr ptr) @ stdcall ZwWriteRequestData(ptr ptr long ptr long ptr) @@ -1767,8 +1775,8 @@ @ cdecl -arch=i386 -ret64 _alldiv(double double) @ cdecl -arch=i386 _alldvrm() @ cdecl -arch=i386 -ret64 _allmul(double double) -@ cdecl -arch=i386 -norelay _alloca_probe() -@ cdecl -version=0x600+ -arch=i386 _alloca_probe_16() +@ cdecl -arch=i386 -norelay -private _alloca_probe() +@ cdecl -version=0x600+ -arch=i386 -private _alloca_probe_16() @ stub -version=0x600+ -arch=i386 _alloca_probe_8 @ cdecl -arch=i386 -ret64 _allrem(double double) @ cdecl -arch=i386 _allshl() @@ -1812,7 +1820,7 @@ @ cdecl _vscwprintf(wstr ptr) @ cdecl _vsnprintf(ptr long str ptr) @ cdecl _vsnwprintf(ptr long wstr ptr) -@ stub -version=0x600+ _vswprintf +@ cdecl -stub -version=0x600+ _vswprintf(ptr wstr ptr) @ cdecl _wcsicmp(wstr wstr) @ cdecl _wcslwr(wstr) @ cdecl _wcsnicmp(wstr wstr long) @@ -1912,4 +1920,4 @@ @ stdcall -arch=arm __rt_sdiv64() @ stdcall -arch=arm __rt_udiv() @ stdcall -arch=arm __rt_udiv64() -@ stdcall -arch=arm __rt_srsh() +@ stdcall -arch=arm __rt_srsh() \ No newline at end of file diff --git a/dll/ntdll/def/ntdllwow.spec b/dll/ntdll/def/ntdllwow.spec new file mode 100644 index 0000000000000..22d508f917efc --- /dev/null +++ b/dll/ntdll/def/ntdllwow.spec @@ -0,0 +1,1926 @@ +@ stdcall -version=0x502 PropertyLengthAsVariant(ptr long long long) +@ stdcall -version=0x502 RtlConvertPropertyToVariant(ptr long ptr ptr) +@ stdcall -version=0x502 RtlConvertVariantToProperty(ptr long ptr ptr ptr long ptr) +@ fastcall -arch=i386 RtlActivateActivationContextUnsafeFast(ptr ptr) +@ fastcall -arch=i386 RtlDeactivateActivationContextUnsafeFast(ptr) +@ fastcall -arch=i386 RtlInterlockedPushListSList(ptr ptr ptr long) +@ fastcall -arch=i386 RtlUlongByteSwap(long) +@ fastcall -arch=i386 -ret64 RtlUlonglongByteSwap(double) +@ fastcall -arch=i386 RtlUshortByteSwap(long) +@ stdcall -arch=i386 ExpInterlockedPopEntrySListEnd() +@ stdcall -arch=i386 ExpInterlockedPopEntrySListFault() +@ stdcall -arch=i386 ExpInterlockedPopEntrySListResume() +@ stdcall -version=0x600+ A_SHAFinal(ptr ptr) +@ stdcall -version=0x600+ A_SHAInit(ptr) +@ stdcall -version=0x600+ A_SHAUpdate(ptr ptr long) +@ stdcall -stub -version=0x600+ AlpcAdjustCompletionListConcurrencyCount(ptr long) +@ stdcall -stub -version=0x600+ AlpcFreeCompletionListMessage(ptr ptr) +@ stdcall -stub -version=0x600+ AlpcGetCompletionListLastMessageInformation(ptr ptr ptr) +@ stdcall -stub -version=0x600+ AlpcGetCompletionListMessageAttributes(ptr ptr) +@ stdcall -stub -version=0x600+ AlpcGetHeaderSize(long) +@ stdcall -stub -version=0x600+ AlpcGetMessageAttribute(ptr long) +@ stdcall -stub -version=0x600+ AlpcGetMessageFromCompletionList(ptr ptr) +@ stdcall -stub -version=0x600+ AlpcGetOutstandingCompletionListMessageCount(ptr) +@ stdcall -stub -version=0x600+ AlpcInitializeMessageAttribute(long ptr long ptr) +@ stdcall -stub -version=0x600+ AlpcMaxAllowedMessageLength() +@ stdcall -stub -version=0x600+ AlpcRegisterCompletionList(ptr ptr long long long) +@ stdcall -stub -version=0x600+ AlpcRegisterCompletionListWorkerThread(ptr) +@ stdcall -stub -version=0x600+ AlpcUnregisterCompletionList(ptr) +@ stdcall -stub -version=0x600+ AlpcUnregisterCompletionListWorkerThread(ptr) +@ stdcall CsrAllocateCaptureBuffer(long long) +@ stdcall CsrAllocateMessagePointer(ptr long ptr) +@ stdcall CsrCaptureMessageBuffer(ptr ptr long ptr) +@ stdcall CsrCaptureMessageMultiUnicodeStringsInPlace(ptr long ptr) +@ stdcall CsrCaptureMessageString(ptr str long long ptr) +@ stdcall CsrCaptureTimeout(long ptr) +@ stdcall CsrClientCallServer(ptr ptr long long) +@ stdcall CsrClientConnectToServer(str long ptr ptr ptr) +@ stdcall CsrFreeCaptureBuffer(ptr) +@ stdcall CsrGetProcessId() +@ stdcall CsrIdentifyAlertableThread() +@ stdcall -version=0x502+ CsrNewThread() # Should be only 0x502, but we need it for now +@ stdcall -version=0x502 CsrProbeForRead(ptr long long) +@ stdcall -version=0x502 CsrProbeForWrite(ptr long long) +@ stdcall CsrSetPriorityClass(ptr ptr) +@ stdcall -stub -version=0x600+ CsrVerifyRegion(ptr long) +@ stdcall DbgBreakPoint() +@ varargs DbgPrint(str) +@ varargs DbgPrintEx(long long str) +@ varargs DbgPrintReturnControlC(str) +@ stdcall DbgPrompt(ptr ptr long) +@ stdcall DbgQueryDebugFilterState(long long) +@ stdcall DbgSetDebugFilterState(long long long) +@ stdcall DbgUiConnectToDbg() +@ stdcall DbgUiContinue(ptr long) +@ stdcall DbgUiConvertStateChangeStructure(ptr ptr) +@ stdcall DbgUiDebugActiveProcess(ptr) +@ stdcall DbgUiGetThreadDebugObject() +@ stdcall DbgUiIssueRemoteBreakin(ptr) +@ stdcall DbgUiRemoteBreakin() +@ stdcall DbgUiSetThreadDebugObject(ptr) +@ stdcall DbgUiStopDebugging(ptr) +@ stdcall DbgUiWaitStateChange(ptr ptr) +@ stdcall DbgUserBreakPoint() +@ stdcall -version=0x502 EtwControlTraceA(double str ptr long) +@ stdcall -version=0x502 EtwControlTraceW(double wstr ptr long) +@ stdcall -stub EtwCreateTraceInstanceId(ptr ptr) +@ stdcall -stub -version=0x600+ EtwDeliverDataBlock(long) +@ stdcall -version=0x502 EtwEnableTrace(long long long ptr double) +@ stdcall -stub -version=0x600+ EtwEnumerateProcessRegGuids(ptr long ptr) +@ stdcall -stub -version=0x502 EtwEnumerateTraceGuids(ptr long ptr) +@ stdcall -stub -version=0x600+ EtwEventActivityIdControl(long ptr) +@ stdcall -stub -version=0x600+ EtwEventEnabled(int64 ptr) +@ stdcall -stub -version=0x600+ EtwEventProviderEnabled(long long long) +@ stdcall -stub -version=0x600+ EtwEventRegister(ptr ptr ptr ptr) +@ stdcall -stub -version=0x600+ EtwEventSetInformation(int64 long ptr long) +@ stdcall -stub -version=0x600+ EtwEventUnregister(int64) +@ stdcall -stub -version=0x600+ EtwEventWrite(int64 ptr long ptr) +@ stdcall -stub -version=0x600+ EtwEventWriteEndScenario(long ptr long long) +@ stdcall -stub -version=0x600+ EtwEventWriteFull(long long long long long long long) +@ stdcall -stub -version=0x600+ EtwEventWriteStartScenario(long ptr long long) +@ stdcall -stub -version=0x600+ EtwEventWriteString(long long long long) +@ stdcall -stub -version=0x600+ EtwEventWriteTransfer(long ptr ptr ptr long long) +@ stdcall -version=0x502 EtwFlushTraceA(double str ptr) +@ stdcall -version=0x502 EtwFlushTraceW(double wstr ptr) +@ stdcall EtwGetTraceEnableFlags(double) +@ stdcall EtwGetTraceEnableLevel(double) +@ stdcall EtwGetTraceLoggerHandle(ptr) +@ stdcall -stub -version=0x600+ EtwLogTraceEvent(long long) +@ stdcall -stub -version=0x600+ EtwNotificationRegister(ptr long long long ptr) +@ stdcall -stub -version=0x502 EtwNotificationRegistrationA(ptr long ptr long long) +@ stdcall -stub -version=0x502 EtwNotificationRegistrationW(ptr long ptr long long) +@ stdcall -stub -version=0x600+ EtwNotificationUnregister(long ptr) +@ stdcall -stub -version=0x600+ EtwProcessPrivateLoggerRequest(ptr) +@ stdcall -version=0x502 EtwQueryAllTracesA(ptr long ptr) +@ stdcall -version=0x502 EtwQueryAllTracesW(ptr long ptr) +@ stdcall -version=0x502 EtwQueryTraceA(double str ptr) +@ stdcall -version=0x502 EtwQueryTraceW(double wstr ptr) +@ stdcall -stub -version=0x502 EtwReceiveNotificationsA(long long long long) +@ stdcall -stub -version=0x502 EtwReceiveNotificationsW(long long long long) +@ stdcall -stub -version=0x600+ EtwRegister(ptr ptr ptr ptr) +@ stdcall -stub -version=0x600+ EtwRegisterSecurityProvider() +@ stdcall EtwRegisterTraceGuidsA(ptr ptr ptr long ptr str str ptr) +@ stdcall EtwRegisterTraceGuidsW(ptr ptr ptr long ptr wstr wstr ptr) +@ stdcall -stub -version=0x600+ EtwReplyNotification(long) +@ stdcall -stub -version=0x600+ EtwSendNotification(long long ptr long long) +@ stdcall -stub -version=0x600+ EtwSetMark(long long long) +@ stdcall -version=0x502 EtwStartTraceA(ptr str ptr) +@ stdcall -version=0x502 EtwStartTraceW(ptr wstr ptr) +@ stdcall -version=0x502 EtwStopTraceA(double str ptr) +@ stdcall -version=0x502 EtwStopTraceW(double wstr ptr) +@ stdcall -version=0x502 EtwTraceEvent(double ptr) +@ stdcall -stub EtwTraceEventInstance(double ptr ptr ptr) +@ varargs EtwTraceMessage(int64 long ptr long) +@ stdcall -stub EtwTraceMessageVa(int64 long ptr long ptr) +@ stdcall -stub -version=0x600+ EtwUnregister(int64) +@ stdcall EtwUnregisterTraceGuids(double) +@ stdcall -version=0x502 EtwUpdateTraceA(double str ptr) +@ stdcall -version=0x502 EtwUpdateTraceW(double wstr ptr) +@ stdcall -stub -version=0x600+ EtwWrite(int64 ptr ptr long ptr) +@ stdcall -stub -version=0x600+ EtwWriteUMSecurityEvent(ptr long long long) +@ stdcall -stub -version=0x600+ EtwpCreateEtwThread(long long) +@ stdcall -stub -version=0x600+ EtwpGetCpuSpeed(ptr) +@ stdcall -stub -version=0x502 EtwpGetTraceBuffer(long long long long) +@ stdcall -stub -version=0x600+ EtwpNotificationThread() ; doesn't exist in win11 +@ stdcall -stub -version=0x502 EtwpSetHWConfigFunction(ptr long) +@ stdcall -arch=x86_64 ExpInterlockedPopEntrySListEnd() +@ stub -version=0x600+ -arch=x86_64 ExpInterlockedPopEntrySListEnd8 +@ stdcall -arch=x86_64 ExpInterlockedPopEntrySListFault() +@ stub -version=0x600+ -arch=x86_64 ExpInterlockedPopEntrySListFault8 +@ stdcall -arch=x86_64 ExpInterlockedPopEntrySListResume() +@ stub -version=0x600+ -arch=x86_64 ExpInterlockedPopEntrySListResume8 +@ stdcall -arch=i386 KiFastSystemCall() +@ stdcall -arch=i386 KiFastSystemCallRet() +@ stdcall -arch=i386 KiIntSystemCall() +@ stdcall KiRaiseUserExceptionDispatcher() +@ stdcall KiUserApcDispatcher(ptr ptr ptr ptr) +@ stdcall KiUserCallbackDispatcher(ptr ptr long) ; CHECKME +@ stdcall KiUserExceptionDispatcher(ptr ptr) +@ stdcall -version=0x502 LdrAccessOutOfProcessResource(ptr ptr ptr ptr ptr) +@ stdcall LdrAccessResource(ptr ptr ptr ptr) +@ stdcall -stub -version=0x600+ LdrAddLoadAsDataTable(ptr wstr long ptr) +@ stdcall LdrAddRefDll(long ptr) +@ stdcall -version=0x502 LdrAlternateResourcesEnabled() +@ stdcall -version=0x502 LdrCreateOutOfProcessImage(long ptr ptr ptr) +@ stdcall -version=0x502 LdrDestroyOutOfProcessImage(ptr) +@ stdcall LdrDisableThreadCalloutsForDll(ptr) +@ stdcall LdrEnumResources(ptr ptr long ptr ptr) +@ stdcall LdrEnumerateLoadedModules(long ptr ptr) +@ stdcall -version=0x501-0x502 LdrFindCreateProcessManifest(long ptr ptr long ptr) +@ stdcall LdrFindEntryForAddress(ptr ptr) +@ stdcall LdrFindResourceDirectory_U(ptr ptr long ptr) +@ stdcall -stub LdrFindResourceEx_U(ptr ptr ptr ptr ptr) ; 5.1 and higher +@ stdcall LdrFindResource_U(ptr ptr long ptr) +@ stdcall LdrFlushAlternateResourceModules() +@ stdcall LdrGetDllHandle(wstr ptr ptr ptr) +@ stdcall LdrGetDllHandleEx(long wstr ptr ptr ptr) +@ stdcall -stub -version=0x600+ LdrGetFailureData() +@ stdcall -stub -version=0x600+ LdrGetFileNameFromLoadAsDataTable(ptr ptr) +@ stdcall -stub -version=0x600+ -arch=x86_64 LdrGetKnownDllSectionHandle(wstr long ptr) +@ stdcall LdrGetProcedureAddress(ptr ptr long ptr) +@ stdcall -stub -version=0x600+ LdrGetProcedureAddressEx(ptr ptr long ptr long) +@ stdcall -stub LdrHotPatchRoutine(ptr) +@ stdcall LdrInitShimEngineDynamic(ptr) +@ stdcall LdrInitializeThunk(long long long long) +@ stdcall LdrLoadAlternateResourceModule(ptr ptr) +@ stdcall -stub -version=0x600+ LdrLoadAlternateResourceModuleEx(long long ptr ptr long) +@ stdcall LdrLoadDll(wstr long ptr ptr) +@ stdcall LdrLockLoaderLock(long ptr ptr) +@ stdcall LdrOpenImageFileOptionsKey(ptr long ptr) ; 5.2 SP1 and higher +@ stdcall -stub -version=0x600+ -arch=x86_64 LdrProcessInitializationComplete() +@ stdcall LdrProcessRelocationBlock(ptr long ptr long) +@ stdcall LdrQueryImageFileExecutionOptions(ptr str long ptr long ptr) +@ stdcall LdrQueryImageFileExecutionOptionsEx(ptr ptr long ptr long ptr long) +@ stdcall LdrQueryImageFileKeyOption(ptr ptr long ptr long ptr) +@ stdcall -stub -version=0x600+ LdrQueryModuleServiceTags(ptr ptr ptr) +@ stdcall LdrQueryProcessModuleInformation(ptr long ptr) +@ stdcall -version=0x600+ LdrRegisterDllNotification(long ptr ptr ptr) +@ stdcall -stub -version=0x600+ LdrRemoveLoadAsDataTable(ptr ptr ptr long) +@ stdcall -stub -version=0x600+ LdrResFindResource(ptr long long long long long long long long) +@ stdcall -stub -version=0x600+ LdrResFindResourceDirectory(ptr long long long long long long) +@ stdcall -stub -version=0x600+ LdrResRelease(ptr ptr long long) +@ stdcall -stub -version=0x600+ LdrResSearchResource(wstr wstr long long long ptr long long) +@ stdcall LdrSetAppCompatDllRedirectionCallback(long ptr ptr) +@ stdcall LdrSetDllManifestProber(ptr) +@ stdcall -stub -version=0x600+ LdrSetMUICacheType(long) +@ stdcall LdrShutdownProcess() +@ stdcall LdrShutdownThread() +@ stdcall LdrUnloadAlternateResourceModule(ptr) +@ stdcall -stub -version=0x600+ LdrUnloadAlternateResourceModuleEx(long long) +@ stdcall LdrUnloadDll(ptr) +@ stdcall LdrUnlockLoaderLock(long ptr) +@ stdcall -version=0x600+ LdrUnregisterDllNotification(ptr) +@ stdcall LdrVerifyImageMatchesChecksum(ptr long long long) +@ stdcall -stub -version=0x600+ LdrVerifyImageMatchesChecksumEx(ptr ptr) +@ stdcall -stub -version=0x600+ LdrpResGetMappingSize(long ptr long long) +@ stdcall -stub -version=0x600+ LdrpResGetRCConfig(long long ptr long long) ; doesn't exist on win11 +@ stdcall -stub -version=0x600+ LdrpResGetResourceDirectory(long long long ptr ptr) +@ stdcall -version=0x600+ MD4Final(ptr) +@ stdcall -version=0x600+ MD4Init(ptr) +@ stdcall -version=0x600+ MD4Update(ptr ptr long) +@ stdcall -version=0x600+ MD5Final(ptr) +@ stdcall -version=0x600+ MD5Init(ptr) +@ stdcall -version=0x600+ MD5Update(ptr ptr long) +@ extern NlsAnsiCodePage +@ extern NlsMbCodePageTag +@ extern NlsMbOemCodePageTag +@ stdcall NtAcceptConnectPort(ptr long ptr long long ptr) +@ stdcall NtAccessCheck(ptr long long ptr ptr ptr ptr ptr) +@ stdcall NtAccessCheckAndAuditAlarm(ptr long ptr ptr ptr long ptr long ptr ptr ptr) +@ stdcall NtAccessCheckByType(ptr ptr ptr long ptr long ptr ptr long ptr ptr) +@ stdcall NtAccessCheckByTypeAndAuditAlarm(ptr ptr ptr ptr ptr ptr long long long ptr long ptr long ptr ptr ptr) +@ stdcall NtAccessCheckByTypeResultList(ptr ptr ptr long ptr long ptr ptr long ptr ptr) +@ stdcall NtAccessCheckByTypeResultListAndAuditAlarm(ptr ptr ptr ptr ptr ptr long long long ptr long ptr long ptr ptr ptr) +@ stdcall NtAccessCheckByTypeResultListAndAuditAlarmByHandle(ptr ptr ptr ptr ptr ptr ptr long long long ptr long ptr long ptr ptr ptr) +@ stdcall -stub -version=0x600+ NtAcquireCMFViewOwnership(ptr ptr long) ; doesn't exist on Win11 +@ stdcall NtAddAtom(ptr long ptr) +@ stdcall NtAddBootEntry(ptr long) +@ stdcall NtAddDriverEntry(ptr long) ; 5.2 and higher +@ stdcall NtAdjustGroupsToken(long long ptr long ptr ptr) +@ stdcall NtAdjustPrivilegesToken(long long long long long long) +@ stdcall NtAlertResumeThread(long ptr) +@ stdcall NtAlertThread(long) +@ stdcall NtAllocateLocallyUniqueId(ptr) +@ stdcall NtAllocateUserPhysicalPages(ptr ptr ptr) +@ stdcall NtAllocateUuids(ptr ptr ptr ptr) +@ stdcall NtAllocateVirtualMemory(long ptr ptr ptr long long) +@ stdcall -stub -version=0x600+ NtAlpcAcceptConnectPort(long long long long long long long long long) +@ stdcall -stub -version=0x600+ NtAlpcCancelMessage(long long long) +@ stdcall -stub -version=0x600+ NtAlpcConnectPort(long long long long long long long long long long long) +@ stdcall -stub -version=0x600+ NtAlpcCreatePort(long long long) +@ stdcall -stub -version=0x600+ NtAlpcCreatePortSection(long long long long ptr ptr) +@ stdcall -stub -version=0x600+ NtAlpcCreateResourceReserve(long long long ptr) +@ stdcall -stub -version=0x600+ NtAlpcCreateSectionView(long long long) +@ stdcall -stub -version=0x600+ NtAlpcCreateSecurityContext(long long ptr) +@ stdcall -stub -version=0x600+ NtAlpcDeletePortSection(long long long long ptr ptr) +@ stdcall -stub -version=0x600+ NtAlpcDeleteResourceReserve(long long long ptr) +@ stdcall -stub -version=0x600+ NtAlpcDeleteSectionView(long long long ptr) +@ stdcall -stub -version=0x600+ NtAlpcDeleteSecurityContext(long long long) +@ stdcall -stub -version=0x600+ NtAlpcDisconnectPort(long long) +@ stdcall -stub -version=0x600+ NtAlpcImpersonateClientOfPort(long long long) +@ stub -version=0x600+ NtAlpcOpenSenderProcess +@ stub -version=0x600+ NtAlpcOpenSenderThread +@ stdcall -stub -version=0x600+ NtAlpcQueryInformation(long long long long long) +@ stdcall -stub -version=0x600+ NtAlpcQueryInformationMessage(long long long long long long) +@ stdcall -stub -version=0x600+ NtAlpcRevokeSecurityContext(long long long) +@ stdcall -stub -version=0x600+ NtAlpcSendWaitReceivePort(long long long long long long long long) +@ stdcall -stub -version=0x600+ NtAlpcSetInformation(long long long long) +@ stdcall NtApphelpCacheControl(long ptr) +@ stdcall NtAreMappedFilesTheSame(ptr ptr) +@ stdcall NtAssignProcessToJobObject(long long) +@ stdcall NtCallbackReturn(ptr long long) +@ stdcall NtCancelDeviceWakeupRequest(ptr) +@ stdcall NtCancelIoFile(long ptr) +@ stdcall -stub -version=0x600+ NtCancelIoFileEx(long ptr ptr) +@ stdcall -stub -version=0x600+ NtCancelSynchronousIoFile(long ptr ptr) +@ stdcall NtCancelTimer(long ptr) +@ stdcall NtClearEvent(long) +@ stdcall NtClose(long) +@ stdcall NtCloseObjectAuditAlarm(ptr ptr long) +@ stdcall -stub -version=0x600+ NtCommitComplete(ptr ptr) +@ stdcall -stub -version=0x600+ NtCommitEnlistment(ptr ptr) +@ stdcall -stub -version=0x600+ NtCommitTransaction(ptr long) +@ stdcall NtCompactKeys(long ptr) +@ stdcall NtCompareTokens(ptr ptr ptr) +@ stdcall NtCompleteConnectPort(ptr) +@ stdcall NtCompressKey(ptr) +@ stdcall NtConnectPort(ptr ptr ptr ptr ptr ptr ptr ptr) +@ stdcall NtContinue(ptr long) +@ stdcall NtCreateDebugObject(ptr long ptr long) +@ stdcall NtCreateDirectoryObject(long long long) +@ stdcall -stub -version=0x600+ NtCreateEnlistment(ptr long ptr ptr ptr long long ptr) +@ stdcall NtCreateEvent(long long long long long) +@ stdcall NtCreateEventPair(ptr long ptr) +@ stdcall NtCreateFile(ptr long ptr ptr long long long ptr long long ptr) +@ stdcall NtCreateIoCompletion(ptr long ptr long) +@ stdcall NtCreateJobObject(ptr long ptr) +@ stdcall NtCreateJobSet(long ptr long) +@ stdcall NtCreateKey(ptr long ptr long ptr long long) +@ stdcall -stub -version=0x600+ NtCreateKeyTransacted(ptr long ptr long ptr long long ptr) +@ stdcall NtCreateKeyedEvent(ptr long ptr long) +@ stdcall NtCreateMailslotFile(long long long long long long long long) +@ stdcall NtCreateMutant(ptr long ptr long) +@ stdcall NtCreateNamedPipeFile(ptr long ptr ptr long long long long long long long long long ptr) +@ stdcall NtCreatePagingFile(ptr ptr ptr long) +@ stdcall NtCreatePort(ptr ptr long long ptr) +@ stdcall -stub -version=0x600+ NtCreatePrivateNamespace(ptr long ptr ptr) +@ stdcall NtCreateProcess(ptr long ptr ptr long ptr ptr ptr) +@ stdcall NtCreateProcessEx(ptr long ptr ptr long ptr ptr ptr long) +@ stdcall NtCreateProfile(ptr ptr ptr long long ptr long long long) ; CHECKME +@ stdcall -stub -version=0x600+ NtCreateResourceManager(ptr long ptr ptr ptr long wstr) +@ stdcall NtCreateSection(ptr long ptr ptr long long ptr) +@ stdcall NtCreateSemaphore(ptr long ptr long long) +@ stdcall NtCreateSymbolicLinkObject(ptr long ptr ptr) +@ stdcall NtCreateThread(ptr long ptr ptr ptr ptr ptr long) +@ stub -version=0x600+ NtCreateThreadEx +@ stdcall NtCreateTimer(ptr long ptr long) +@ stdcall NtCreateToken(ptr long ptr long ptr ptr ptr ptr ptr ptr ptr ptr ptr) +@ stdcall -stub -version=0x600+ NtCreateTransaction(ptr long ptr ptr ptr long long long ptr wstr) +@ stdcall -stub -version=0x600+ NtCreateTransactionManager(ptr long ptr wstr long long) +@ stdcall -stub -version=0x600+ NtCreateUserProcess(ptr ptr long long ptr ptr long long ptr long long) +@ stdcall NtCreateWaitablePort(ptr ptr long long long) +@ stdcall -stub -version=0x600+ NtCreateWorkerFactory(ptr long long long long long long long long long) +@ stdcall -arch=win32 NtCurrentTeb() _NtCurrentTeb +@ stdcall NtDebugActiveProcess(ptr ptr) +@ stdcall NtDebugContinue(ptr ptr long) +@ stdcall NtDelayExecution(long ptr) +@ stdcall NtDeleteAtom(long) +@ stdcall NtDeleteBootEntry(long) +@ stdcall NtDeleteDriverEntry(long) +@ stdcall NtDeleteFile(ptr) +@ stdcall NtDeleteKey(long) +@ stdcall NtDeleteObjectAuditAlarm(ptr ptr long) +@ stdcall -stub -version=0x600+ NtDeletePrivateNamespace(long) +@ stdcall NtDeleteValueKey(long ptr) +@ stdcall NtDeviceIoControlFile(long long long long long long long long long long) +@ stdcall NtDisplayString(ptr) +@ stdcall NtDuplicateObject(long long long ptr long long long) +@ stdcall NtDuplicateToken(long long long long long long) +@ stdcall NtEnumerateBootEntries(ptr ptr) +@ stdcall NtEnumerateDriverEntries(ptr ptr) +@ stdcall NtEnumerateKey (long long long long long long) +@ stdcall NtEnumerateSystemEnvironmentValuesEx(long ptr long) +@ stub -version=0x600+ NtEnumerateTransactionObject +@ stdcall NtEnumerateValueKey(long long long long long long) +@ stdcall NtExtendSection(ptr ptr) +@ stdcall NtFilterToken(ptr long ptr ptr ptr ptr) +@ stdcall NtFindAtom(ptr long ptr) +@ stdcall NtFlushBuffersFile(long ptr) +@ stdcall -stub -version=0x600+ NtFlushInstallUILanguage(long long) +@ stdcall NtFlushInstructionCache(long ptr long) +@ stdcall NtFlushKey(long) +@ stdcall -stub -version=0x600+ NtFlushProcessWriteBuffers() +@ stdcall NtFlushVirtualMemory(long ptr ptr long) +@ stdcall NtFlushWriteBuffer() +@ stdcall NtFreeUserPhysicalPages(ptr ptr ptr) +@ stdcall NtFreeVirtualMemory(long ptr ptr long) +@ stdcall -stub -version=0x600+ NtFreezeRegistry(long) +@ stdcall -stub -version=0x600+ NtFreezeTransactions(ptr ptr) +@ stdcall NtFsControlFile(long long long long long long long long long long) +@ stdcall NtGetContextThread(long ptr) +@ stdcall NtGetCurrentProcessorNumber() ; 5.2 and higher +@ stdcall NtGetDevicePowerState(ptr ptr) +@ stdcall -stub -version=0x600+ NtGetMUIRegistryInfo(long ptr ptr) +@ stdcall -stub -version=0x600+ NtGetNextProcess(long long long long ptr) +@ stdcall -stub -version=0x600+ NtGetNextThread(ptr ptr long long long ptr) +@ stdcall -stub -version=0x600+ NtGetNlsSectionPtr(long long long ptr ptr) +@ stdcall -stub -version=0x600+ NtGetNotificationResourceManager(ptr ptr long ptr ptr long long) +@ stdcall NtGetPlugPlayEvent(long long ptr long) +@ stdcall NtGetTickCount() RtlGetTickCount +@ stdcall NtGetWriteWatch(long long ptr long ptr ptr ptr) +@ stdcall NtImpersonateAnonymousToken(ptr) +@ stdcall NtImpersonateClientOfPort(ptr ptr) +@ stdcall NtImpersonateThread(ptr ptr ptr) +@ stdcall -stub -version=0x600+ NtInitializeNlsFiles(ptr ptr) +@ stdcall NtInitializeRegistry(long) +@ stdcall NtInitiatePowerAction (long long long long) +@ stdcall NtIsProcessInJob(long long) +@ stdcall NtIsSystemResumeAutomatic() +@ stdcall -stub -version=0x600+ NtIsUILanguageComitted() +@ stdcall NtListenPort(ptr ptr) +@ stdcall NtLoadDriver(ptr) +@ stdcall NtLoadKey2(ptr ptr long) +@ stdcall NtLoadKey(ptr ptr) +@ stdcall NtLoadKeyEx(ptr ptr long ptr) +@ stdcall NtLockFile(long long ptr ptr ptr ptr ptr ptr long long) +@ stdcall NtLockProductActivationKeys(ptr ptr) +@ stdcall NtLockRegistryKey(ptr) +@ stdcall NtLockVirtualMemory(long ptr ptr long) +@ stdcall NtMakePermanentObject(ptr) +@ stdcall NtMakeTemporaryObject(long) +@ stdcall -stub -version=0x600+ NtMapCMFModule(long long ptr ptr ptr ptr) +@ stdcall NtMapUserPhysicalPages(ptr ptr ptr) +@ stdcall NtMapUserPhysicalPagesScatter(ptr ptr ptr) +@ stdcall NtMapViewOfSection(long long ptr long long ptr ptr long long long) +@ stdcall NtModifyBootEntry(ptr) +@ stdcall NtModifyDriverEntry(ptr) +@ stdcall NtNotifyChangeDirectoryFile(long long ptr ptr ptr ptr long long long) +@ stdcall NtNotifyChangeKey(long long ptr ptr ptr long long ptr long long) +@ stdcall NtNotifyChangeMultipleKeys(ptr long ptr ptr ptr ptr ptr long long ptr long long) +@ stdcall NtOpenDirectoryObject(long long long) +@ stdcall -stub -version=0x600+ NtOpenEnlistment(ptr long ptr ptr ptr) +@ stdcall NtOpenEvent(long long long) +@ stdcall NtOpenEventPair(ptr long ptr) +@ stdcall NtOpenFile(ptr long ptr ptr long long) +@ stdcall NtOpenIoCompletion(ptr long ptr) +@ stdcall NtOpenJobObject(ptr long ptr) +@ stdcall NtOpenKey(ptr long ptr) +@ stdcall -stub -version=0x600+ NtOpenKeyTransacted(ptr long ptr ptr) +@ stdcall NtOpenKeyedEvent(ptr long ptr) +@ stdcall NtOpenMutant(ptr long ptr) +@ stdcall NtOpenObjectAuditAlarm(ptr ptr ptr ptr ptr ptr long long ptr long long ptr) +@ stdcall -stub -version=0x600+ NtOpenPrivateNamespace(ptr long ptr ptr) +@ stdcall NtOpenProcess(ptr long ptr ptr) +@ stdcall NtOpenProcessToken(long long ptr) +@ stdcall NtOpenProcessTokenEx(long long long ptr) +@ stdcall -stub -version=0x600+ NtOpenResourceManager(ptr long ptr ptr ptr) +@ stdcall NtOpenSection(ptr long ptr) +@ stdcall NtOpenSemaphore(long long ptr) +@ stdcall -stub -version=0x600+ NtOpenSession(ptr long ptr) +@ stdcall NtOpenSymbolicLinkObject (ptr long ptr) +@ stdcall NtOpenThread(ptr long ptr ptr) +@ stdcall NtOpenThreadToken(long long long ptr) +@ stdcall NtOpenThreadTokenEx(long long long long ptr) +@ stdcall NtOpenTimer(ptr long ptr) +@ stdcall -stub -version=0x600+ NtOpenTransaction(ptr long ptr ptr ptr) +@ stdcall -stub -version=0x600+ NtOpenTransactionManager(ptr long ptr ptr ptr long) +@ stdcall NtPlugPlayControl(ptr ptr long) +@ stdcall NtPowerInformation(long ptr long ptr long) +@ stdcall -stub -version=0x600+ NtPrePrepareComplete(ptr ptr) +@ stdcall -stub -version=0x600+ NtPrePrepareEnlistment(ptr ptr) +@ stdcall -stub -version=0x600+ NtPrepareComplete(ptr ptr) +@ stdcall -stub -version=0x600+ NtPrepareEnlistment(ptr ptr) +@ stdcall NtPrivilegeCheck(ptr ptr ptr) +@ stdcall NtPrivilegeObjectAuditAlarm(ptr ptr ptr long ptr long) +@ stdcall NtPrivilegedServiceAuditAlarm(ptr ptr ptr ptr long) +@ stdcall -stub -version=0x600+ NtPropagationComplete(ptr long long ptr) +@ stdcall -stub -version=0x600+ NtPropagationFailed(ptr long long) +@ stdcall NtProtectVirtualMemory(long ptr ptr long ptr) +@ stdcall NtPulseEvent(long ptr) +@ stdcall NtQueryAttributesFile(ptr ptr) +@ stdcall NtQueryBootEntryOrder(ptr ptr) +@ stdcall NtQueryBootOptions(ptr ptr) +@ stdcall NtQueryDebugFilterState(long long) +@ stdcall NtQueryDefaultLocale(long ptr) +@ stdcall NtQueryDefaultUILanguage(ptr) +@ stdcall NtQueryDirectoryFile(long long ptr ptr ptr ptr long long long ptr long) +@ stdcall NtQueryDirectoryObject(long ptr long long long ptr ptr) +@ stdcall NtQueryDriverEntryOrder(ptr ptr) +@ stdcall NtQueryEaFile(long ptr ptr long long ptr long ptr long) +@ stdcall NtQueryEvent(long long ptr long ptr) +@ stdcall NtQueryFullAttributesFile(ptr ptr) +@ stdcall NtQueryInformationAtom(long long ptr long ptr) +@ stdcall -stub -version=0x600+ NtQueryInformationEnlistment(ptr long ptr long ptr) +@ stdcall NtQueryInformationFile(ptr ptr ptr long long) +@ stdcall NtQueryInformationJobObject(ptr long ptr long ptr) +@ stdcall NtQueryInformationPort(ptr long ptr long ptr) +@ stdcall NtQueryInformationProcess(ptr long ptr long ptr) +@ stdcall -stub -version=0x600+ NtQueryInformationResourceManager(ptr long ptr long ptr) +@ stdcall NtQueryInformationThread(ptr long ptr long ptr) +@ stdcall NtQueryInformationToken(ptr long ptr long ptr) +@ stdcall -stub -version=0x600+ NtQueryInformationTransaction(ptr long ptr ptr ptr) +@ stdcall -stub -version=0x600+ NtQueryInformationTransactionManager(ptr long ptr long ptr) +@ stdcall -stub -version=0x600+ NtQueryInformationWorkerFactory(ptr long ptr long ptr) +@ stdcall NtQueryInstallUILanguage(ptr) +@ stdcall NtQueryIntervalProfile(long ptr) +@ stdcall NtQueryIoCompletion(long long ptr long ptr) +@ stdcall NtQueryKey (long long ptr long ptr) +@ stdcall -stub -version=0x600+ NtQueryLicenseValue(wstr ptr ptr long ptr) +@ stdcall NtQueryMultipleValueKey(long ptr long ptr long ptr) +@ stdcall NtQueryMutant(long long ptr long ptr) +@ stdcall NtQueryObject(long long long long long) +@ stdcall NtQueryOpenSubKeys(ptr ptr) +@ stdcall NtQueryOpenSubKeysEx(ptr long ptr ptr) +@ stdcall NtQueryPerformanceCounter(ptr ptr) +@ stdcall NtQueryPortInformationProcess() +@ stdcall NtQueryQuotaInformationFile(ptr ptr ptr long long ptr long ptr long) +@ stdcall NtQuerySection (long long long long long) +@ stdcall NtQuerySecurityObject (long long long long long) +@ stdcall NtQuerySemaphore (long long ptr long ptr) +@ stdcall NtQuerySymbolicLinkObject(long ptr ptr) +@ stdcall NtQuerySystemEnvironmentValue(ptr ptr long ptr) +@ stdcall NtQuerySystemEnvironmentValueEx(ptr ptr ptr ptr ptr) +@ stdcall NtQuerySystemInformation(long long long long) +@ stdcall NtQuerySystemTime(ptr) +@ stdcall NtQueryTimer(ptr long ptr long ptr) +@ stdcall NtQueryTimerResolution(long long long) +@ stdcall NtQueryValueKey(long long long long long long) +@ stdcall NtQueryVirtualMemory(long ptr long ptr long ptr) +@ stdcall NtQueryVolumeInformationFile(long ptr ptr long long) +@ stdcall NtQueueApcThread(long ptr long long long) +@ stdcall NtRaiseException(ptr ptr long) +@ stdcall NtRaiseHardError(long long long ptr long ptr) +@ stdcall NtReadFile(long long ptr ptr ptr ptr long ptr ptr) +@ stdcall NtReadFileScatter(long long ptr ptr ptr ptr long ptr ptr) +@ stdcall -stub -version=0x600+ NtReadOnlyEnlistment(ptr ptr) +@ stdcall NtReadRequestData(ptr ptr long ptr long ptr) +@ stdcall NtReadVirtualMemory(long ptr ptr long ptr) +@ stdcall -stub -version=0x600+ NtRecoverEnlistment(ptr ptr) +@ stdcall -stub -version=0x600+ NtRecoverResourceManager(ptr) +@ stdcall -stub -version=0x600+ NtRecoverTransactionManager(ptr) +@ stdcall -stub -version=0x600+ NtRegisterProtocolAddressInformation(ptr ptr long ptr long) +@ stdcall NtRegisterThreadTerminatePort(ptr) +@ stdcall -stub -version=0x600+ NtReleaseCMFViewOwnership() +@ stdcall NtReleaseKeyedEvent(ptr ptr long ptr) +@ stdcall NtReleaseMutant(long ptr) +@ stdcall NtReleaseSemaphore(long long ptr) +@ stdcall -stub -version=0x600+ NtReleaseWorkerFactoryWorker(ptr) +@ stdcall NtRemoveIoCompletion(ptr ptr ptr ptr ptr) +@ stdcall -stub -version=0x600+ NtRemoveIoCompletionEx(ptr ptr long ptr ptr long) +@ stdcall NtRemoveProcessDebug(ptr ptr) +@ stdcall NtRenameKey(ptr ptr) +@ stdcall -stub -version=0x600+ NtRenameTransactionManager(ptr ptr) +@ stdcall NtReplaceKey(ptr long ptr) +@ stdcall -stub -version=0x600+ NtReplacePartitionUnit(wstr wstr long) +@ stdcall NtReplyPort(ptr ptr) +@ stdcall NtReplyWaitReceivePort(ptr ptr ptr ptr) +@ stdcall NtReplyWaitReceivePortEx(ptr ptr ptr ptr ptr) +@ stdcall NtReplyWaitReplyPort(ptr ptr) +@ stdcall NtRequestDeviceWakeup(ptr) +@ stdcall NtRequestPort(ptr ptr) +@ stdcall NtRequestWaitReplyPort(ptr ptr ptr) +@ stdcall NtRequestWakeupLatency(long) +@ stdcall NtResetEvent(long ptr) +@ stdcall NtResetWriteWatch(long ptr long) +@ stdcall NtRestoreKey(long long long) +@ stdcall NtResumeProcess(ptr) +@ stdcall NtResumeThread(long long) +@ stdcall -stub -version=0x600+ NtRollbackComplete(ptr ptr) +@ stdcall -stub -version=0x600+ NtRollbackEnlistment(ptr long ptr long) +@ stdcall -stub -version=0x600+ NtRollbackTransaction(ptr long) +@ stdcall -stub -version=0x600+ NtRollforwardTransactionManager(ptr ptr) +@ stdcall NtSaveKey(long long) +@ stdcall NtSaveKeyEx(ptr ptr long) +@ stdcall NtSaveMergedKeys(ptr ptr ptr) +@ stdcall NtSecureConnectPort(ptr ptr ptr ptr ptr ptr ptr ptr ptr) +@ stdcall NtSetBootEntryOrder(ptr ptr) +@ stdcall NtSetBootOptions(ptr long) +@ stdcall NtSetContextThread(long ptr) +@ stdcall NtSetDebugFilterState(long long long) +@ stdcall NtSetDefaultHardErrorPort(ptr) +@ stdcall NtSetDefaultLocale(long long) +@ stdcall NtSetDefaultUILanguage(long) +@ stdcall NtSetDriverEntryOrder(ptr ptr) +@ stdcall NtSetEaFile(long ptr ptr long) +@ stdcall NtSetEvent(long long) +@ stdcall NtSetEventBoostPriority(ptr) +@ stdcall NtSetHighEventPair(ptr) +@ stdcall NtSetHighWaitLowEventPair(ptr) +@ stdcall NtSetInformationDebugObject(ptr long ptr long ptr) +@ stdcall -stub -version=0x600+ NtSetInformationEnlistment(ptr long ptr long) +@ stdcall NtSetInformationFile(ptr ptr ptr long long) +@ stdcall NtSetInformationJobObject(ptr long ptr long) +@ stdcall NtSetInformationKey(ptr long ptr long) +@ stdcall NtSetInformationObject(ptr long ptr long) +@ stdcall NtSetInformationProcess(ptr long ptr long) +@ stdcall -stub -version=0x600+ NtSetInformationResourceManager(ptr long ptr long) +@ stdcall NtSetInformationThread(ptr long ptr long) +@ stdcall NtSetInformationToken(ptr long ptr long) +@ stdcall -stub -version=0x600+ NtSetInformationTransaction(ptr long ptr long) +@ stdcall -stub -version=0x600+ NtSetInformationTransactionManager(ptr long ptr long) +@ stdcall -stub -version=0x600+ NtSetInformationWorkerFactory(ptr long ptr long) +@ stdcall NtSetIntervalProfile(long long) +@ stdcall NtSetIoCompletion(ptr long ptr long long) +@ stdcall NtSetLdtEntries(long int64 long int64) +@ stdcall NtSetLowEventPair(ptr) +@ stdcall NtSetLowWaitHighEventPair(ptr) +@ stdcall NtSetQuotaInformationFile(ptr ptr ptr long) +@ stdcall NtSetSecurityObject(long long ptr) +@ stdcall NtSetSystemEnvironmentValue(ptr ptr) +@ stdcall NtSetSystemEnvironmentValueEx(ptr ptr ptr ptr ptr) +@ stdcall NtSetSystemInformation(long ptr long) +@ stdcall NtSetSystemPowerState(long long long) +@ stdcall NtSetSystemTime(ptr ptr) +@ stdcall NtSetThreadExecutionState(long ptr) +@ stdcall NtSetTimer(long ptr ptr ptr long long ptr) +@ stdcall NtSetTimerResolution(long long ptr) +@ stdcall NtSetUuidSeed(ptr) +@ stdcall NtSetValueKey(long long long long long long) +@ stdcall NtSetVolumeInformationFile(long ptr ptr long long) +@ stdcall NtShutdownSystem(long) +@ stdcall -stub -version=0x600+ NtShutdownWorkerFactory(ptr ptr) +@ stdcall NtSignalAndWaitForSingleObject(long long long ptr) +@ stdcall -stub -version=0x600+ NtSinglePhaseReject(ptr ptr) +@ stdcall NtStartProfile(ptr) +@ stdcall NtStopProfile(ptr) +@ stdcall NtSuspendProcess(ptr) +@ stdcall NtSuspendThread(long ptr) +@ stdcall NtSystemDebugControl(long ptr long ptr long ptr) +@ stdcall NtTerminateJobObject(ptr long) +@ stdcall NtTerminateProcess(ptr long) +@ stdcall NtTerminateThread(ptr long) +@ stdcall NtTestAlert() +@ stdcall -stub -version=0x600+ NtThawRegistry() +@ stdcall -stub -version=0x600+ NtThawTransactions() +@ stdcall -stub -version=0x600+ NtTraceControl(long ptr long ptr long long) +@ stdcall NtTraceEvent(long long long ptr) +@ stdcall NtTranslateFilePath(ptr long ptr long) +@ stdcall NtUnloadDriver(ptr) +@ stdcall NtUnloadKey2(ptr long) +@ stdcall NtUnloadKey(long) +@ stdcall NtUnloadKeyEx(ptr ptr) +@ stdcall NtUnlockFile(long ptr ptr ptr ptr) +@ stdcall NtUnlockVirtualMemory(long ptr ptr long) +@ stdcall NtUnmapViewOfSection(long ptr) +@ stdcall NtVdmControl(long ptr) +@ stdcall NtWaitForDebugEvent(ptr long ptr ptr) +@ stdcall NtWaitForKeyedEvent(ptr ptr long ptr) +@ stdcall NtWaitForMultipleObjects32(long ptr long long ptr) +@ stdcall NtWaitForMultipleObjects(long ptr long long ptr) +@ stdcall NtWaitForSingleObject(long long long) +@ stub -version=0x600+ NtWaitForWorkViaWorkerFactory +@ stdcall NtWaitHighEventPair(ptr) +@ stdcall NtWaitLowEventPair(ptr) +@ stdcall -stub -version=0x600+ NtWorkerFactoryWorkerReady(long) +@ stdcall NtWriteFile(long long ptr ptr ptr ptr long ptr ptr) +@ stdcall NtWriteFileGather(long long ptr ptr ptr ptr long ptr ptr) +@ stdcall NtWriteRequestData(ptr ptr long ptr long ptr) +@ stdcall NtWriteVirtualMemory(long ptr ptr long ptr) +@ stdcall NtYieldExecution() +@ stdcall -stub -version=0x600+ NtdllDefWindowProc_A(long long long long) +@ stdcall -stub -version=0x600+ NtdllDefWindowProc_W(long long long long) +@ stdcall -stub -version=0x600+ NtdllDialogWndProc_A(long long long long) +@ stdcall -stub -version=0x600+ NtdllDialogWndProc_W(long long long long) +@ stdcall PfxFindPrefix(ptr ptr) +@ stdcall PfxInitialize(ptr) +@ stdcall PfxInsertPrefix(ptr ptr ptr) +@ stdcall PfxRemovePrefix(ptr ptr) +@ stdcall RtlAbortRXact(ptr) +@ stdcall RtlAbsoluteToSelfRelativeSD(ptr ptr ptr) +@ stdcall RtlAcquirePebLock() +@ stdcall RtlAcquirePrivilege(ptr long long ptr) +@ stdcall RtlAcquireResourceExclusive(ptr long) +@ stdcall RtlAcquireResourceShared(ptr long) +@ stdcall -version=0x600+ RtlAcquireSRWLockExclusive(ptr) +@ stdcall -version=0x600+ RtlAcquireSRWLockShared(ptr) +@ stdcall RtlActivateActivationContext(long ptr ptr) +@ stdcall RtlActivateActivationContextEx(long ptr ptr ptr) +@ stdcall -arch=x86_64,arm RtlActivateActivationContextUnsafeFast(ptr ptr) +@ stdcall RtlAddAccessAllowedAce(ptr long long ptr) +@ stdcall RtlAddAccessAllowedAceEx(ptr long long long ptr) +@ stdcall RtlAddAccessAllowedObjectAce(ptr long long long ptr ptr ptr) +@ stdcall RtlAddAccessDeniedAce(ptr long long ptr) +@ stdcall RtlAddAccessDeniedAceEx(ptr long long long ptr) +@ stdcall RtlAddAccessDeniedObjectAce(ptr long long long ptr ptr ptr) +@ stdcall RtlAddAce(ptr long long ptr long) +@ stdcall RtlAddActionToRXact(ptr long ptr long ptr long) +@ stdcall RtlAddAtomToAtomTable(ptr wstr ptr) +@ stdcall RtlAddAttributeActionToRXact(ptr long ptr ptr ptr long ptr long) +@ stdcall RtlAddAuditAccessAce(ptr long long ptr long long) +@ stdcall RtlAddAuditAccessAceEx(ptr long long long ptr long long) +@ stdcall RtlAddAuditAccessObjectAce(ptr long long long ptr ptr ptr long long) +@ stdcall -stub RtlAddCompoundAce(ptr long long long ptr ptr) +@ stdcall -arch=x86_64 RtlAddFunctionTable(ptr long long) +@ stdcall -stub -version=0x600+ RtlAddMandatoryAce(ptr long long long long ptr) ; not present in Win11 +@ stdcall RtlAddRefActivationContext(ptr) +@ stdcall RtlAddRefMemoryStream(ptr) +@ stdcall -stub -version=0x600+ RtlAddSIDToBoundaryDescriptor(ptr ptr) ; not present in Win11 +@ stdcall RtlAddVectoredContinueHandler(long ptr) +@ stdcall RtlAddVectoredExceptionHandler(long ptr) +@ stdcall -stub RtlAddressInSectionTable(ptr ptr long) +@ stdcall RtlAdjustPrivilege(long long long ptr) +@ stdcall RtlAllocateActivationContextStack(ptr) ; CHECKME +@ stdcall RtlAllocateAndInitializeSid(ptr long long long long long long long long long ptr) +@ stdcall RtlAllocateHandle(ptr ptr) +@ stdcall RtlAllocateHeap(ptr long ptr) +@ stdcall -stub -version=0x600+ RtlAllocateMemoryBlockLookaside(ptr long ptr) ; not present in Win11 +@ stdcall -stub -version=0x600+ RtlAllocateMemoryZone(long long ptr) ; not present in Win11 +@ stdcall RtlAnsiCharToUnicodeChar(ptr) +@ stdcall RtlAnsiStringToUnicodeSize(ptr) RtlxAnsiStringToUnicodeSize +@ stdcall RtlAnsiStringToUnicodeString(ptr ptr long) +@ stdcall RtlAppendAsciizToString(ptr str) +@ stdcall -stub RtlAppendPathElement(ptr ptr ptr) +@ stdcall RtlAppendStringToString(ptr ptr) +@ stdcall RtlAppendUnicodeStringToString(ptr ptr) +@ stdcall RtlAppendUnicodeToString(ptr wstr) +@ stdcall RtlApplicationVerifierStop(ptr str ptr str ptr str ptr str ptr str) +@ stdcall RtlApplyRXact(ptr) +@ stdcall RtlApplyRXactNoFlush(ptr) +@ stdcall RtlAreAllAccessesGranted(long long) +@ stdcall RtlAreAnyAccessesGranted(long long) +@ stdcall RtlAreBitsClear(ptr long long) +@ stdcall RtlAreBitsSet(ptr long long) +@ stdcall RtlAssert(ptr ptr long ptr) +@ stdcall -stub -version=0x600+ RtlBarrier(ptr long) +@ stdcall -stub -version=0x600+ RtlBarrierForDelete(long long) +@ stdcall RtlCancelTimer(ptr ptr) +@ stdcall -register RtlCaptureContext(ptr) +@ stdcall RtlCaptureStackBackTrace(long long ptr ptr) +@ stdcall -stub -arch=i386 RtlCaptureStackContext(ptr ptr ptr) +@ stdcall RtlCharToInteger(ptr long ptr) +@ stdcall RtlCheckForOrphanedCriticalSections(ptr) +@ stdcall -stub -version=0x502 RtlCheckProcessParameters(ptr ptr ptr ptr) +@ stdcall RtlCheckRegistryKey(long ptr) +@ stdcall -stub -version=0x600+ RtlCleanUpTEBLangLists() +@ stdcall RtlClearAllBits(ptr) +@ stdcall RtlClearBits(ptr long long) +@ stdcall RtlCloneMemoryStream(ptr ptr) +@ stdcall -stub -version=0x600+ RtlCloneUserProcess(long long long long long) +@ stdcall -stub -version=0x600+ RtlCmDecodeMemIoResource(ptr ptr) +@ stdcall -stub -version=0x600+ RtlCmEncodeMemIoResource(ptr long long long) +@ stdcall -stub -version=0x600+ RtlCommitDebugInfo(ptr long) +@ stdcall RtlCommitMemoryStream(ptr long) +@ stdcall RtlCompactHeap(long long) +@ stdcall -stub -version=0x600+ RtlCompareAltitudes(wstr wstr) +@ stdcall RtlCompareMemory(ptr ptr long) +@ stdcall RtlCompareMemoryUlong(ptr long long) +@ stdcall RtlCompareString(ptr ptr long) +@ stdcall RtlCompareUnicodeString (ptr ptr long) +@ stdcall -version=0x600+ RtlCompareUnicodeStrings(wstr long wstr long long) +@ stdcall -stub -version=0x600+ -arch=x86_64 RtlCompleteProcessCloning(long) +@ stdcall RtlCompressBuffer(long ptr long ptr long long ptr ptr) +@ stdcall RtlComputeCrc32(long ptr long) +@ stdcall RtlComputeImportTableHash(ptr ptr long) +@ stdcall RtlComputePrivatizedDllName_U(ptr ptr ptr) +@ stdcall -stub -version=0x600+ RtlConnectToSm(ptr ptr long ptr) +@ stdcall RtlConsoleMultiByteToUnicodeN(ptr long ptr ptr long ptr) +@ stdcall RtlConvertExclusiveToShared(ptr) +@ stdcall -version=0x600+ RtlConvertLCIDToString(long long long ptr long) +@ stdcall -arch=win32 -ret64 RtlConvertLongToLargeInteger(long) +@ stdcall RtlConvertSharedToExclusive(ptr) +@ stdcall RtlConvertSidToUnicodeString(ptr ptr long) +@ stdcall RtlConvertToAutoInheritSecurityObject(ptr ptr ptr ptr long ptr) +@ stdcall RtlConvertUiListToApiList(ptr ptr long) +@ stdcall -arch=win32 -ret64 RtlConvertUlongToLargeInteger(long) +@ stdcall RtlCopyLuid(ptr ptr) +@ stdcall RtlCopyLuidAndAttributesArray(long ptr ptr) +@ stdcall RtlCopyMappedMemory(ptr ptr long) +@ cdecl -version=0x600+ -arch=x86_64 RtlCopyMemory(ptr ptr long) memmove +@ stdcall -stub -version=0x600+ -arch=x86_64 RtlCopyMemoryNonTemporal(ptr ptr long) +@ stdcall RtlCopyMemoryStreamTo(ptr ptr int64 ptr ptr) +@ stdcall RtlCopyOutOfProcessMemoryStreamTo(ptr ptr int64 ptr ptr) RtlCopyMemoryStreamTo +@ stdcall RtlCopySecurityDescriptor(ptr ptr) +@ stdcall RtlCopySid(long ptr ptr) +@ stdcall RtlCopySidAndAttributesArray(long ptr long ptr ptr ptr ptr) +@ stdcall RtlCopyString(ptr ptr) +@ stdcall RtlCopyUnicodeString(ptr ptr) +@ stdcall RtlCreateAcl(ptr long long) +@ stdcall RtlCreateActivationContext(long ptr long ptr ptr ptr) +@ stdcall RtlCreateAndSetSD(ptr long ptr ptr ptr) +@ stdcall RtlCreateAtomTable(long ptr) +@ stdcall RtlCreateBootStatusDataFile() +@ stdcall -stub -version=0x600+ RtlCreateBoundaryDescriptor(ptr long) +@ stdcall RtlCreateEnvironment(long ptr) +@ stdcall -stub -version=0x600+ RtlCreateEnvironmentEx(ptr ptr long) +@ stdcall RtlCreateHeap(long ptr long long ptr ptr) +@ stdcall -stub -version=0x600+ RtlCreateMemoryBlockLookaside(ptr long long long long) +@ stdcall -stub -version=0x600+ RtlCreateMemoryZone(ptr long long) +@ stdcall RtlCreateProcessParameters(ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr) +@ stdcall -stub -version=0x600+ RtlCreateProcessParametersEx(ptr wstr ptr wstr wstr ptr wstr wstr ptr ptr long) +@ stdcall RtlCreateQueryDebugBuffer(long long) +@ stdcall RtlCreateRegistryKey(long wstr) +@ stdcall RtlCreateSecurityDescriptor(ptr long) +@ stdcall RtlCreateServiceSid(ptr ptr ptr) # Exists in Windows 2003 SP 2 +@ stdcall RtlCreateSystemVolumeInformationFolder(ptr) +@ stdcall RtlCreateTagHeap(ptr long wstr wstr) +@ stdcall RtlCreateTimer(ptr ptr ptr ptr long long long) +@ stdcall RtlCreateTimerQueue(ptr) +@ stdcall RtlCreateUnicodeString(ptr wstr) +@ stdcall RtlCreateUnicodeStringFromAsciiz(ptr str) +@ stdcall RtlCreateUserProcess(ptr long ptr ptr ptr ptr long ptr ptr ptr) +@ stdcall RtlCreateUserSecurityObject(ptr long ptr ptr long ptr ptr) +@ stdcall -stub -version=0x600+ RtlCreateUserStack(long long long long long ptr) +@ stdcall RtlCreateUserThread(long ptr long ptr long long ptr ptr ptr ptr) +@ stdcall -version=0x600+ RtlCultureNameToLCID(ptr ptr) +@ stdcall RtlCustomCPToUnicodeN(ptr wstr long ptr str long) +@ stdcall RtlCutoverTimeToSystemTime(ptr ptr ptr long) +@ stdcall -stub -version=0x600+ RtlDeCommitDebugInfo(long long long) ; doesn't exist in win11 +@ stdcall RtlDeNormalizeProcessParams(ptr) +@ stdcall RtlDeactivateActivationContext(long long) +@ stdcall -arch=x86_64,arm RtlDeactivateActivationContextUnsafeFast(ptr) +@ stdcall -stub RtlDebugPrintTimes() +@ stdcall RtlDecodePointer(ptr) +@ stdcall RtlDecodeSystemPointer(ptr) +@ stdcall RtlDecompressBuffer(long ptr long ptr long ptr) +@ stdcall RtlDecompressFragment(long ptr long ptr long long ptr ptr) +@ stdcall RtlDefaultNpAcl(ptr) +@ stdcall RtlDelete(ptr) +@ stdcall RtlDeleteAce(ptr long) +@ stdcall RtlDeleteAtomFromAtomTable(ptr long) +@ stdcall -stub -version=0x600+ RtlDeleteBarrier(long) +@ stdcall -stub -version=0x600+ RtlDeleteBoundaryDescriptor(ptr) +@ stdcall RtlDeleteCriticalSection(ptr) +@ stdcall RtlDeleteElementGenericTable(ptr ptr) +@ stdcall RtlDeleteElementGenericTableAvl(ptr ptr) +@ cdecl -arch=x86_64 RtlDeleteFunctionTable(ptr) +@ stdcall RtlDeleteNoSplay(ptr ptr) +@ stdcall RtlDeleteRegistryValue(long ptr ptr) +@ stdcall RtlDeleteResource(ptr) +@ stdcall RtlDeleteSecurityObject(ptr) +@ stdcall RtlDeleteTimer(ptr ptr ptr) +@ stdcall RtlDeleteTimerQueue(ptr) +@ stdcall RtlDeleteTimerQueueEx(ptr ptr) +@ stdcall -stub -version=0x600+ RtlDeregisterSecureMemoryCacheCallback(ptr) +@ stdcall RtlDeregisterWait(ptr) +@ stdcall RtlDeregisterWaitEx(ptr ptr) +@ stdcall RtlDestroyAtomTable(ptr) +@ stdcall RtlDestroyEnvironment(ptr) +@ stdcall RtlDestroyHandleTable(ptr) +@ stdcall RtlDestroyHeap(long) +@ stdcall -stub -version=0x600+ RtlDestroyMemoryBlockLookaside(long) +@ stdcall -stub -version=0x600+ RtlDestroyMemoryZone(long) +@ stdcall RtlDestroyProcessParameters(ptr) +@ stdcall RtlDestroyQueryDebugBuffer(ptr) +@ stdcall RtlDetermineDosPathNameType_U(wstr) +@ stdcall RtlDllShutdownInProgress() +@ stdcall RtlDnsHostNameToComputerName(ptr ptr long) +@ stdcall RtlDoesFileExists_U(wstr) +@ stdcall RtlDosApplyFileIsolationRedirection_Ustr(long ptr ptr ptr ptr ptr ptr ptr ptr) +@ stdcall RtlDosPathNameToNtPathName_U(wstr ptr ptr ptr) +@ stdcall RtlDosPathNameToNtPathName_U_WithStatus(wstr ptr ptr ptr) ; 5.2 SP1, and higher +@ stdcall RtlDosPathNameToRelativeNtPathName_U(ptr ptr ptr ptr) +@ stdcall RtlDosPathNameToRelativeNtPathName_U_WithStatus(wstr ptr ptr ptr) +@ stdcall RtlDosSearchPath_U(wstr wstr wstr long ptr ptr) +@ stdcall RtlDosSearchPath_Ustr(long ptr ptr ptr ptr ptr ptr ptr ptr) +@ stdcall RtlDowncaseUnicodeChar(long) +@ stdcall RtlDowncaseUnicodeString(ptr ptr long) +@ stdcall RtlDumpResource(ptr) +@ stdcall RtlDuplicateUnicodeString(long ptr ptr) +@ stdcall RtlEmptyAtomTable(ptr long) +@ stdcall -stub RtlEnableEarlyCriticalSectionEventCreation() +@ stdcall RtlEncodePointer(ptr) +@ stdcall RtlEncodeSystemPointer(ptr) +@ stdcall -arch=win32 -ret64 RtlEnlargedIntegerMultiply(long long) +@ stdcall -arch=win32 RtlEnlargedUnsignedDivide(double long ptr) +@ stdcall -arch=win32 -ret64 RtlEnlargedUnsignedMultiply(long long) +@ stdcall RtlEnterCriticalSection(ptr) +@ stdcall RtlEnumProcessHeaps(ptr ptr) +@ stdcall RtlEnumerateGenericTable(ptr long) +@ stdcall RtlEnumerateGenericTableAvl(ptr long) +@ stdcall RtlEnumerateGenericTableLikeADirectory(ptr ptr ptr long ptr ptr ptr) +@ stdcall RtlEnumerateGenericTableWithoutSplaying(ptr ptr) +@ stdcall RtlEnumerateGenericTableWithoutSplayingAvl(ptr ptr) +@ stdcall RtlEqualComputerName(ptr ptr) +@ stdcall RtlEqualDomainName(ptr ptr) +@ stdcall RtlEqualLuid(ptr ptr) +@ stdcall RtlEqualPrefixSid(ptr ptr) +@ stdcall RtlEqualSid(long long) +@ stdcall RtlEqualString(ptr ptr long) +@ stdcall RtlEqualUnicodeString(ptr ptr long) +@ stdcall RtlEraseUnicodeString(ptr) +@ stdcall -stub -version=0x600+ RtlExitUserProcess(long) +@ stdcall RtlExitUserThread(long) +@ stdcall -stub -version=0x600+ RtlExpandEnvironmentStrings(long ptr long ptr long ptr) +@ stdcall RtlExpandEnvironmentStrings_U(ptr ptr ptr ptr) +@ stdcall -version=0x502 RtlExtendHeap(ptr long ptr ptr) +@ stdcall -stub -version=0x600+ RtlExtendMemoryBlockLookaside(long) +@ stdcall -stub -version=0x600+ RtlExtendMemoryZone(long long) +@ stdcall -arch=win32 -ret64 RtlExtendedIntegerMultiply(double long) +@ stdcall -arch=win32 -ret64 RtlExtendedLargeIntegerDivide(double long ptr) +@ stdcall -arch=win32 -ret64 RtlExtendedMagicDivide(double double long) +@ stdcall RtlFillMemory(ptr long long) +@ stdcall -arch=i386,arm RtlFillMemoryUlong(ptr long long) +@ stdcall RtlFinalReleaseOutOfProcessMemoryStream(ptr) +@ stdcall -stub -version=0x600+ RtlFindAceByType(long long ptr) +@ stdcall RtlFindActivationContextSectionGuid(long ptr long ptr ptr) +@ stdcall RtlFindActivationContextSectionString(long ptr long ptr ptr) +@ stdcall RtlFindCharInUnicodeString(long ptr ptr ptr) +@ stdcall RtlFindClearBits(ptr long long) +@ stdcall RtlFindClearBitsAndSet(ptr long long) +@ stdcall RtlFindClearRuns(ptr ptr long long) +@ stdcall -stub -version=0x600+ RtlFindClosestEncodableLength(long ptr) +@ stdcall RtlFindLastBackwardRunClear(ptr long ptr) +@ stdcall RtlFindLeastSignificantBit(double) +@ stdcall RtlFindLongestRunClear(ptr long) +@ stdcall RtlFindMessage(long long long long ptr) +@ stdcall RtlFindMostSignificantBit(double) +@ stdcall RtlFindNextForwardRunClear(ptr long ptr) +@ stdcall RtlFindSetBits(ptr long long) +@ stdcall RtlFindSetBitsAndClear(ptr long long) +@ stdcall RtlFirstEntrySList(ptr) +@ stdcall RtlFirstFreeAce(ptr ptr) +@ stdcall -stub -version=0x600+ RtlFlsAlloc(long long long long) +@ stdcall -stub -version=0x600+ RtlFlsFree(long) +@ stdcall RtlFlushSecureMemoryCache(ptr ptr) +@ stdcall RtlFormatCurrentUserKeyPath(ptr) +@ stdcall RtlFormatMessage(ptr long long long long ptr ptr long ptr) +@ stdcall RtlFormatMessageEx(ptr long long long long ptr ptr long ptr long) +@ stdcall RtlFreeActivationContextStack(ptr) +@ stdcall RtlFreeAnsiString(long) +@ stdcall RtlFreeHandle(ptr ptr) +@ stdcall RtlFreeHeap(long long long) +@ stdcall -stub -version=0x600+ RtlFreeMemoryBlockLookaside(long long) +@ stdcall RtlFreeOemString(ptr) +@ stdcall RtlFreeSid(long) +@ stdcall RtlFreeThreadActivationContextStack() +@ stdcall RtlFreeUnicodeString(ptr) +@ stdcall -stub -version=0x600+ RtlFreeUserStack(long) +@ stdcall -version=0x502 RtlFreeUserThreadStack(ptr ptr) +@ stdcall RtlGUIDFromString(ptr ptr) +@ stdcall RtlGenerate8dot3Name(ptr ptr long ptr) +@ stdcall RtlGetAce(ptr long ptr) +@ stdcall RtlGetActiveActivationContext(ptr) +@ stdcall RtlGetCallersAddress(ptr ptr) +@ stdcall RtlGetCompressionWorkSpaceSize(long ptr ptr) +@ stdcall RtlGetControlSecurityDescriptor(ptr ptr ptr) +@ stdcall RtlGetCriticalSectionRecursionCount(ptr) +@ stdcall RtlGetCurrentDirectory_U(long ptr) +@ stdcall RtlGetCurrentPeb() +@ stdcall RtlGetCurrentProcessorNumber() ; 5.2 SP1 and higher +@ stdcall -stub -version=0x600+ RtlGetCurrentTransaction() +@ stdcall RtlGetDaclSecurityDescriptor(ptr ptr ptr ptr) +@ stdcall RtlGetElementGenericTable(ptr long) +@ stdcall RtlGetElementGenericTableAvl(ptr long) +@ stdcall -stub -version=0x600+ RtlGetFileMUIPath(long long ptr ptr long long ptr) +@ stdcall RtlGetFrame() +@ stdcall RtlGetFullPathName_U(wstr long ptr ptr) +@ stdcall RtlGetFullPathName_UstrEx(ptr ptr ptr ptr ptr ptr ptr ptr) +@ stdcall -arch=x86_64 RtlGetFunctionTableListHead() +@ stdcall RtlGetGroupSecurityDescriptor(ptr ptr ptr) +@ stub -version=0x600+ RtlGetIntegerAtom +@ stdcall RtlGetLastNtStatus() +@ stdcall RtlGetLastWin32Error() +@ stdcall RtlGetLengthWithoutLastFullDosOrNtPathElement(long ptr ptr) +; Yes, Microsoft really misspelled this one! +@ stdcall RtlGetLengthWithoutTrailingPathSeperators(long ptr ptr) RtlGetLengthWithoutTrailingPathSeparators +@ stdcall RtlGetLongestNtPathLength() +@ stdcall RtlGetNativeSystemInformation(long long long long) NtQuerySystemInformation +@ stdcall RtlGetNtGlobalFlags() +@ stdcall RtlGetNtProductType(ptr) +@ stdcall RtlGetNtVersionNumbers(ptr ptr ptr) +@ stdcall RtlGetOwnerSecurityDescriptor(ptr ptr ptr) +@ stdcall -stub -version=0x600+ RtlGetParentLocaleName(wstr long long long) +@ stdcall RtlGetProcessHeaps(long ptr) +@ stub -version=0x600+ RtlGetProductInfo +@ stdcall RtlGetSaclSecurityDescriptor(ptr ptr ptr ptr) +@ stdcall RtlGetSecurityDescriptorRMControl(ptr ptr) +@ stdcall RtlGetSetBootStatusData(ptr long long ptr long long) +@ stdcall -stub -version=0x600+ RtlGetSystemPreferredUILanguages(long ptr ptr ptr ptr) +@ stdcall RtlGetThreadErrorMode() +@ stdcall -stub -version=0x600+ RtlGetThreadLangIdByIndex(long long ptr ptr) +@ stdcall -stub -version=0x600+ RtlGetThreadPreferredUILanguages(long long ptr ptr) +@ stdcall -stub -version=0x600+ RtlGetUILanguageInfo(long ptr long ptr ptr) +@ stdcall RtlGetUnloadEventTrace() +@ stdcall -stub -version=0x600+ RtlGetUnloadEventTraceEx(ptr ptr ptr) +@ stdcall RtlGetUserInfoHeap(ptr long ptr ptr ptr) +@ stdcall -stub -version=0x600+ RtlGetUserPreferredUILanguages(long ptr ptr ptr ptr) +@ stdcall RtlGetVersion(ptr) +@ stdcall RtlHashUnicodeString(ptr long long ptr) +@ stdcall -stub -version=0x600+ RtlHeapTrkInitialize(ptr) +@ stdcall RtlIdentifierAuthoritySid(ptr) +@ stdcall -stub -version=0x600+ RtlIdnToAscii(long long long long long) +@ stdcall -stub -version=0x600+ RtlIdnToNameprepUnicode(long long long long long) +@ stdcall -stub -version=0x600+ RtlIdnToUnicode(long long long long long) +@ stdcall RtlImageDirectoryEntryToData(ptr long long ptr) +@ stdcall RtlImageNtHeader(long) +@ stdcall RtlImageNtHeaderEx(long ptr double ptr) +@ stdcall RtlImageRvaToSection(ptr long long) +@ stdcall RtlImageRvaToVa(ptr long long ptr) +@ stdcall RtlImpersonateSelf(long) +@ stdcall -stub -version=0x600+ RtlImpersonateSelfEx(long long ptr) +@ stdcall RtlInitAnsiString(ptr str) +@ stdcall RtlInitAnsiStringEx(ptr str) +@ stdcall -stub -version=0x600+ RtlInitBarrier(long long) +@ stdcall RtlInitCodePageTable(ptr ptr) +@ stdcall RtlInitMemoryStream(ptr) +@ stdcall RtlInitNlsTables(ptr ptr ptr ptr) +@ stdcall RtlInitOutOfProcessMemoryStream(ptr) +@ stdcall RtlInitString(ptr str) +@ stdcall RtlInitUnicodeString(ptr wstr) +@ stdcall RtlInitUnicodeStringEx(ptr wstr) +@ stdcall -stub RtlInitializeAtomPackage(ptr) +@ stdcall RtlInitializeBitMap(ptr long long) +@ stdcall -version=0x600+ RtlInitializeConditionVariable(ptr) +@ stdcall RtlInitializeContext(ptr ptr ptr ptr ptr) +@ stdcall RtlInitializeCriticalSection(ptr) +@ stdcall RtlInitializeCriticalSectionAndSpinCount(ptr long) +@ stdcall -version=0x600+ RtlInitializeCriticalSectionEx(ptr long long) +@ stdcall -stub -version=0x600+ -arch=i386 RtlInitializeExceptionChain(ptr) +@ stdcall RtlInitializeGenericTable(ptr ptr ptr ptr ptr) +@ stdcall RtlInitializeGenericTableAvl(ptr ptr ptr ptr ptr) +@ stdcall RtlInitializeHandleTable(long long ptr) +@ stdcall -stub -version=0x600+ RtlInitializeNtUserPfn(wstr long ptr long wstr ptr) +@ stdcall RtlInitializeRXact(ptr long ptr) +@ stdcall RtlInitializeResource(ptr) +@ stdcall RtlInitializeSListHead(ptr) +@ stdcall -version=0x600+ RtlInitializeSRWLock(ptr) +@ stdcall RtlInitializeSid(ptr ptr long) +@ stdcall RtlInsertElementGenericTable(ptr ptr long ptr) +@ stdcall RtlInsertElementGenericTableAvl(ptr ptr long ptr) +@ stdcall RtlInsertElementGenericTableFull(ptr ptr long ptr ptr long) +@ stdcall RtlInsertElementGenericTableFullAvl(ptr ptr long ptr ptr long) +@ stdcall -arch=x86_64 RtlInstallFunctionTableCallback(double double long ptr ptr ptr) +@ stdcall RtlInt64ToUnicodeString(double long ptr) +@ stdcall RtlIntegerToChar(long long long ptr) +@ stdcall RtlIntegerToUnicodeString(long long ptr) +@ stdcall -arch=win32 -ret64 RtlInterlockedCompareExchange64(ptr double double) +@ stdcall RtlInterlockedFlushSList(ptr) +@ stdcall RtlInterlockedPopEntrySList(ptr) +@ stdcall RtlInterlockedPushEntrySList(ptr ptr) +@ stdcall -arch=x86_64 RtlInterlockedPushListSList(ptr ptr ptr long) +@ stdcall -stub -version=0x600+ RtlIoDecodeMemIoResource(ptr ptr ptr ptr) +@ stdcall -stub -version=0x600+ RtlIoEncodeMemIoResource(ptr long long long long long) +@ stdcall RtlIpv4AddressToStringA(ptr ptr) +@ stdcall RtlIpv4AddressToStringExA(ptr long ptr ptr) +@ stdcall RtlIpv4AddressToStringExW(ptr long ptr ptr) +@ stdcall RtlIpv4AddressToStringW(ptr ptr) +@ stdcall RtlIpv4StringToAddressA(str long ptr ptr) +@ stdcall RtlIpv4StringToAddressExA(str long ptr ptr) +@ stdcall RtlIpv4StringToAddressExW(wstr long ptr ptr) +@ stdcall RtlIpv4StringToAddressW(wstr long ptr ptr) +@ stdcall RtlIpv6AddressToStringA(ptr ptr) +@ stdcall RtlIpv6AddressToStringExA(ptr long long ptr ptr) +@ stdcall RtlIpv6AddressToStringExW(ptr long long ptr ptr) +@ stdcall RtlIpv6AddressToStringW(ptr ptr) +@ stdcall RtlIpv6StringToAddressA(str ptr ptr) +@ stdcall RtlIpv6StringToAddressExA(str ptr ptr ptr) +@ stdcall RtlIpv6StringToAddressExW(wstr ptr ptr ptr) +@ stdcall RtlIpv6StringToAddressW(wstr ptr ptr) +@ stdcall RtlIsActivationContextActive(ptr) +@ stdcall RtlIsCriticalSectionLocked(ptr) +@ stdcall RtlIsCriticalSectionLockedByThread(ptr) +@ stdcall -stub -version=0x600+ RtlIsCurrentThreadAttachExempt() +@ stdcall RtlIsDosDeviceName_U(wstr) +@ stdcall RtlIsGenericTableEmpty(ptr) +@ stdcall RtlIsGenericTableEmptyAvl(ptr) +@ stdcall RtlIsNameLegalDOS8Dot3(ptr ptr ptr) +@ stdcall -stub -version=0x600+ RtlIsNormalizedString(long ptr long ptr) +@ stdcall RtlIsTextUnicode(ptr long ptr) +@ stdcall RtlIsThreadWithinLoaderCallout() +@ stdcall RtlIsValidHandle(ptr ptr) +@ stdcall RtlIsValidIndexHandle(ptr long ptr) +@ stdcall -version=0x600+ RtlIsValidLocaleName(wstr long) +@ stdcall -version=0x600+ RtlLCIDToCultureName(long ptr) +@ stdcall -arch=win32 -ret64 RtlLargeIntegerAdd(double double) +@ stdcall -arch=win32 -ret64 RtlLargeIntegerArithmeticShift(double long) +@ stdcall -arch=win32 -ret64 RtlLargeIntegerDivide(double double ptr) +@ stdcall -arch=win32 -ret64 RtlLargeIntegerNegate(double) +@ stdcall -arch=win32 -ret64 RtlLargeIntegerShiftLeft(double long) +@ stdcall -arch=win32 -ret64 RtlLargeIntegerShiftRight(double long) +@ stdcall -arch=win32 -ret64 RtlLargeIntegerSubtract(double double) +@ stdcall RtlLargeIntegerToChar(ptr long long ptr) +@ stdcall -version=0x600+ RtlLcidToLocaleName(long ptr long long) +@ stdcall RtlLeaveCriticalSection(ptr) +@ stdcall RtlLengthRequiredSid(long) +@ stdcall RtlLengthSecurityDescriptor(ptr) +@ stdcall RtlLengthSid(ptr) +@ stdcall RtlLocalTimeToSystemTime(ptr ptr) +@ stdcall -version=0x600+ RtlLocaleNameToLcid(wstr ptr long) +@ stdcall RtlLockBootStatusData(ptr) +@ stdcall -stub -version=0x600+ RtlLockCurrentThread() +@ stdcall RtlLockHeap(long) +@ stdcall -stub -version=0x600+ RtlLockMemoryBlockLookaside(long) +@ stdcall RtlLockMemoryStreamRegion(ptr int64 int64 long) +@ stdcall -stub -version=0x600+ RtlLockMemoryZone(long) +@ stdcall -stub -version=0x600+ RtlLockModuleSection(long) +@ stdcall -stub RtlLogStackBackTrace() +@ stdcall RtlLookupAtomInAtomTable(ptr wstr ptr) +@ stdcall RtlLookupElementGenericTable(ptr ptr) +@ stdcall RtlLookupElementGenericTableAvl(ptr ptr) +@ stdcall RtlLookupElementGenericTableFull(ptr ptr ptr long) +@ stdcall RtlLookupElementGenericTableFullAvl(ptr ptr ptr long) +@ stdcall -arch=x86_64 RtlLookupFunctionEntry(long ptr ptr) +@ stdcall -arch=x86_64 RtlLookupFunctionTable(int64 ptr ptr) +@ stdcall RtlMakeSelfRelativeSD(ptr ptr ptr) +@ stdcall RtlMapGenericMask(long ptr) +@ stdcall RtlMapSecurityErrorToNtStatus(long) +@ stdcall RtlMoveMemory(ptr ptr long) +@ stdcall RtlMultiAppendUnicodeStringBuffer(ptr long ptr) +@ stdcall RtlMultiByteToUnicodeN(ptr long ptr ptr long) +@ stdcall RtlMultiByteToUnicodeSize(ptr str long) +@ stdcall RtlMultipleAllocateHeap(ptr long ptr long ptr) +@ stdcall RtlMultipleFreeHeap(ptr long long ptr) +@ stdcall RtlNewInstanceSecurityObject(long long ptr ptr ptr ptr ptr long ptr ptr) +@ stdcall RtlNewSecurityGrantedAccess(long ptr ptr ptr ptr ptr) +@ stdcall RtlNewSecurityObject(ptr ptr ptr long ptr ptr) +@ stdcall RtlNewSecurityObjectEx(ptr ptr ptr ptr long long ptr ptr) +@ stdcall RtlNewSecurityObjectWithMultipleInheritance(ptr ptr ptr ptr long long long ptr ptr) +@ stdcall RtlNormalizeProcessParams(ptr) +@ stdcall -stub -version=0x600+ RtlNormalizeString(long long long long ptr) +@ stdcall RtlNtPathNameToDosPathName(long ptr ptr ptr) ; CHECKME (last arg) +@ stdcall RtlNtStatusToDosError(long) +@ stdcall RtlNtStatusToDosErrorNoTeb(long) +@ stub -version=0x600+ -arch=x86_64 RtlNtdllName +@ stdcall RtlNumberGenericTableElements(ptr) +@ stdcall RtlNumberGenericTableElementsAvl(ptr) +@ stdcall RtlNumberOfClearBits(ptr) +@ stdcall RtlNumberOfSetBits(ptr) +@ stdcall -stub -version=0x600+ RtlNumberOfSetBitsUlongPtr(long) +@ stdcall RtlOemStringToUnicodeSize(ptr) RtlxOemStringToUnicodeSize +@ stdcall RtlOemStringToUnicodeString(ptr ptr long) +@ stdcall RtlOemToUnicodeN(ptr long ptr ptr long) +@ stdcall RtlOpenCurrentUser(long ptr) +@ stdcall -stub -version=0x600+ RtlOwnerAcesPresent(long) +@ stdcall RtlPcToFileHeader(ptr ptr) +@ stdcall RtlPinAtomInAtomTable(ptr long) +@ stdcall RtlPopFrame(ptr) +@ stdcall RtlPrefixString(ptr ptr long) +@ stdcall RtlPrefixUnicodeString(ptr ptr long) +@ stdcall -stub -version=0x600+ -arch=x86_64 RtlPrepareForProcessCloning() +@ stdcall -stub -version=0x600+ RtlProcessFlsData(long long) +@ stdcall RtlProtectHeap(ptr long) +@ stdcall RtlPushFrame(ptr) +@ stdcall -version=0x600+ RtlQueryActivationContextApplicationSettings(long ptr wstr wstr ptr ptr ptr) +@ stdcall RtlQueryAtomInAtomTable(ptr long ptr ptr ptr ptr) +@ stdcall -stub -version=0x600+ RtlQueryCriticalSectionOwner(ptr) +@ stdcall RtlQueryDepthSList(ptr) +@ stdcall -stub -version=0x600+ RtlQueryDynamicTimeZoneInformation(ptr) +@ stdcall -stub -version=0x600+ RtlQueryElevationFlags(ptr) +@ stdcall -stub -version=0x600+ RtlQueryEnvironmentVariable(ptr ptr long ptr long ptr) +@ stdcall RtlQueryEnvironmentVariable_U(ptr ptr ptr) +@ stdcall RtlQueryHeapInformation(long long ptr long ptr) +@ stdcall RtlQueryInformationAcl(ptr ptr long long) +@ stdcall RtlQueryInformationActivationContext(long long ptr long ptr long ptr) +@ stdcall RtlQueryInformationActiveActivationContext(long ptr long ptr) +@ stdcall RtlQueryInterfaceMemoryStream(ptr ptr ptr) +@ stdcall -stub -version=0x600+ RtlQueryModuleInformation(ptr long ptr) +@ stdcall -stub RtlQueryProcessBackTraceInformation(ptr) +@ stdcall RtlQueryProcessDebugInformation(long long ptr) +@ stdcall RtlQueryProcessHeapInformation(ptr) +@ stdcall -stub RtlQueryProcessLockInformation(ptr) +@ stdcall RtlQueryRegistryValues(long ptr ptr ptr ptr) +@ stdcall RtlQuerySecurityObject(ptr long ptr long ptr) +@ stdcall RtlQueryTagHeap(ptr long long long ptr) +@ stdcall RtlQueryTimeZoneInformation(ptr) +@ stdcall -arch=i386,x86_64 RtlQueueApcWow64Thread(ptr ptr ptr ptr ptr) +@ stdcall RtlQueueWorkItem(ptr ptr long) +@ stdcall -register RtlRaiseException(ptr) +@ stdcall RtlRaiseStatus(long) +@ stdcall RtlRandom(ptr) +@ stdcall RtlRandomEx(ptr) +@ stdcall RtlReAllocateHeap(long long ptr long) +@ stdcall RtlReadMemoryStream(ptr ptr long ptr) +@ stdcall RtlReadOutOfProcessMemoryStream(ptr ptr long ptr) +@ stdcall RtlRealPredecessor(ptr) +@ stdcall RtlRealSuccessor(ptr) +@ stdcall RtlRegisterSecureMemoryCacheCallback(ptr) +@ stdcall -stub -version=0x600+ RtlRegisterThreadWithCsrss() +@ stdcall RtlRegisterWait(ptr ptr ptr ptr long long) +@ stdcall RtlReleaseActivationContext(ptr) +@ stdcall RtlReleaseMemoryStream(ptr) +@ stdcall RtlReleasePebLock() +@ stdcall RtlReleasePrivilege(ptr) +@ stdcall RtlReleaseRelativeName(ptr) +@ stdcall RtlReleaseResource(ptr) +@ stdcall -version=0x600+ RtlReleaseSRWLockExclusive(ptr) +@ stdcall -version=0x600+ RtlReleaseSRWLockShared(ptr) +@ stdcall RtlRemoteCall(ptr ptr ptr long ptr long long) +@ stdcall -version=0x600+ RtlRemovePrivileges(ptr ptr long) +@ stdcall RtlRemoveVectoredContinueHandler(ptr) +@ stdcall RtlRemoveVectoredExceptionHandler(ptr) +@ stdcall -stub -version=0x600+ RtlReportException(long long long) +@ stdcall -stub -version=0x600+ RtlResetMemoryBlockLookaside(long) +@ stdcall -stub -version=0x600+ RtlResetMemoryZone(long) +@ stdcall RtlResetRtlTranslations(ptr) +@ stdcall -arch=x86_64 RtlRestoreContext(ptr ptr) +@ stdcall RtlRestoreLastWin32Error(long) RtlSetLastWin32Error +@ stdcall -stub -version=0x600+ RtlRetrieveNtUserPfn(ptr ptr ptr) +@ stdcall RtlRevertMemoryStream(ptr) +@ stdcall RtlRunDecodeUnicodeString(long ptr) +@ stdcall RtlRunEncodeUnicodeString(long ptr) +@ stdcall -version=0x600+ RtlRunOnceBeginInitialize(ptr long ptr) +@ stdcall -version=0x600+ RtlRunOnceComplete(ptr long ptr) +@ stdcall -version=0x600+ RtlRunOnceExecuteOnce(ptr ptr ptr ptr) +@ stdcall -version=0x600+ RtlRunOnceInitialize(ptr) +@ stdcall RtlSecondsSince1970ToTime(long ptr) +@ stdcall RtlSecondsSince1980ToTime(long ptr) +@ stdcall RtlSeekMemoryStream(ptr int64 long ptr) +@ stdcall RtlSelfRelativeToAbsoluteSD2(ptr ptr) +@ stdcall RtlSelfRelativeToAbsoluteSD(ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr) +@ stdcall -stub -version=0x600+ RtlSendMsgToSm(ptr ptr) +@ stdcall RtlSetAllBits(ptr) +@ stdcall RtlSetAttributesSecurityDescriptor(ptr long ptr) +@ stdcall RtlSetBits(ptr long long) +@ stdcall RtlSetControlSecurityDescriptor(ptr long long) +@ stdcall RtlSetCriticalSectionSpinCount(ptr long) +@ stdcall RtlSetCurrentDirectory_U(ptr) +@ stdcall RtlSetCurrentEnvironment(wstr ptr) +@ stdcall -stub -version=0x600+ RtlSetCurrentTransaction(ptr) +@ stdcall RtlSetDaclSecurityDescriptor(ptr long ptr long) +@ stdcall -stub -version=0x600+ RtlSetDynamicTimeZoneInformation(long) +@ stdcall RtlSetEnvironmentStrings(wstr long) +@ stdcall -stub -version=0x600+ RtlSetEnvironmentVar(ptr ptr long ptr long) +@ stdcall RtlSetEnvironmentVariable(ptr ptr ptr) +@ stdcall RtlSetGroupSecurityDescriptor(ptr ptr long) +@ stdcall RtlSetHeapInformation(ptr long ptr ptr) +@ stdcall RtlSetInformationAcl(ptr ptr long long) +@ stdcall RtlSetIoCompletionCallback(long ptr long) +@ stdcall RtlSetLastWin32Error(long) +@ stdcall RtlSetLastWin32ErrorAndNtStatusFromNtStatus(long) +@ stdcall RtlSetMemoryStreamSize(ptr int64) +@ stdcall RtlSetOwnerSecurityDescriptor(ptr ptr long) +@ stdcall -stub -version=0x600+ RtlSetProcessDebugInformation(ptr long ptr) +@ cdecl RtlSetProcessIsCritical(long ptr long) +@ stdcall RtlSetSaclSecurityDescriptor(ptr long ptr long) +@ stdcall RtlSetSecurityDescriptorRMControl(ptr ptr) +@ stdcall RtlSetSecurityObject(long ptr ptr ptr ptr) +@ stdcall RtlSetSecurityObjectEx(long ptr ptr long ptr ptr) +@ stdcall RtlSetThreadErrorMode(long ptr) +@ cdecl RtlSetThreadIsCritical(long ptr long) +@ stdcall RtlSetThreadPoolStartFunc(ptr ptr) +@ stdcall -stub -version=0x600+ RtlSetThreadPreferredUILanguages(long ptr ptr) +@ stdcall RtlSetTimeZoneInformation(ptr) +@ stdcall RtlSetTimer(ptr ptr ptr ptr long long long) +@ stdcall RtlSetUnhandledExceptionFilter(ptr) +@ stdcall -stub -version=0x502 RtlSetUnicodeCallouts(ptr) +@ stdcall RtlSetUserFlagsHeap(ptr long ptr long long) +@ stdcall RtlSetUserValueHeap(ptr long ptr ptr) +@ stdcall -stub -version=0x600+ RtlSidDominates(long long ptr) +@ stdcall -stub -version=0x600+ RtlSidEqualLevel(long long ptr) +@ stdcall -stub -version=0x600+ RtlSidHashInitialize(ptr long ptr) +@ stdcall -stub -version=0x600+ RtlSidHashLookup(long ptr) +@ stdcall -stub -version=0x600+ RtlSidIsHigherLevel(long long ptr) +@ stdcall RtlSizeHeap(long long ptr) +@ stdcall -version=0x600+ RtlSleepConditionVariableCS(ptr ptr ptr) +@ stdcall -version=0x600+ RtlSleepConditionVariableSRW(ptr ptr ptr long) +@ stdcall RtlSplay(ptr) +@ stdcall RtlStartRXact(ptr) +@ stdcall RtlStatMemoryStream(ptr ptr long) +@ stdcall RtlStringFromGUID(ptr ptr) +@ stdcall RtlSubAuthorityCountSid(ptr) +@ stdcall RtlSubAuthoritySid(ptr long) +@ stdcall RtlSubtreePredecessor(ptr) +@ stdcall RtlSubtreeSuccessor(ptr) +@ stdcall RtlSystemTimeToLocalTime(ptr ptr) +@ stdcall -version=0x600+ RtlTestBit(ptr long) +@ stdcall RtlTimeFieldsToTime(ptr ptr) +@ stdcall RtlTimeToElapsedTimeFields(long long) +@ stdcall RtlTimeToSecondsSince1970(ptr ptr) +@ stdcall RtlTimeToSecondsSince1980(ptr ptr) +@ stdcall RtlTimeToTimeFields (long long) +@ stdcall RtlTraceDatabaseAdd(ptr long ptr ptr) +@ stdcall RtlTraceDatabaseCreate(long ptr long long ptr) +@ stdcall RtlTraceDatabaseDestroy(ptr) +@ stdcall RtlTraceDatabaseEnumerate(ptr ptr ptr) +@ stdcall RtlTraceDatabaseFind(ptr long ptr ptr) +@ stdcall RtlTraceDatabaseLock(ptr) +@ stdcall RtlTraceDatabaseUnlock(ptr) +@ stdcall RtlTraceDatabaseValidate(ptr) +@ stdcall -stub -version=0x600+ RtlTryAcquirePebLock() +@ stdcall -version=0x601 RtlTryAcquireSRWLockExclusive(ptr) +@ stdcall -version=0x601 RtlTryAcquireSRWLockShared(ptr) +@ stdcall RtlTryEnterCriticalSection(ptr) +@ stdcall RtlUnhandledExceptionFilter2(ptr long) +@ stdcall RtlUnhandledExceptionFilter(ptr) +@ stdcall RtlUnicodeStringToAnsiSize(ptr) RtlxUnicodeStringToAnsiSize +@ stdcall RtlUnicodeStringToAnsiString(ptr ptr long) +@ stdcall RtlUnicodeStringToCountedOemString(ptr ptr long) +@ stdcall RtlUnicodeStringToInteger(ptr long ptr) +@ stdcall RtlUnicodeStringToOemSize(ptr) RtlxUnicodeStringToOemSize +@ stdcall RtlUnicodeStringToOemString(ptr ptr long) +@ stdcall RtlUnicodeToCustomCPN(ptr ptr long ptr wstr long) +@ stdcall RtlUnicodeToMultiByteN(ptr long ptr ptr long) +@ stdcall RtlUnicodeToMultiByteSize(ptr ptr long) +@ stdcall RtlUnicodeToOemN(ptr long ptr ptr long) +@ stdcall RtlUniform(ptr) +@ stdcall RtlUnlockBootStatusData(ptr) +@ stdcall -stub -version=0x600+ RtlUnlockCurrentThread() +@ stdcall RtlUnlockHeap(long) +@ stdcall -stub -version=0x600+ RtlUnlockMemoryBlockLookaside(long) +@ stdcall RtlUnlockMemoryStreamRegion(ptr int64 int64 long) +@ stdcall -stub -version=0x600+ RtlUnlockMemoryZone(long) +@ stdcall -stub -version=0x600+ RtlUnlockModuleSection(long) +@ stdcall -register RtlUnwind(ptr ptr ptr ptr) +@ stdcall -arch=x86_64 RtlUnwindEx(ptr ptr ptr ptr ptr ptr) +@ stdcall RtlUpcaseUnicodeChar(long) +@ stdcall RtlUpcaseUnicodeString(ptr ptr long) +@ stdcall RtlUpcaseUnicodeStringToAnsiString(ptr ptr long) +@ stdcall RtlUpcaseUnicodeStringToCountedOemString(ptr ptr long) +@ stdcall RtlUpcaseUnicodeStringToOemString(ptr ptr long) +@ stdcall RtlUpcaseUnicodeToCustomCPN(ptr ptr long ptr wstr long) +@ stdcall RtlUpcaseUnicodeToMultiByteN(ptr long ptr ptr long) +@ stdcall RtlUpcaseUnicodeToOemN(ptr long ptr ptr long) +@ stdcall -stub -version=0x600+ RtlUpdateClonedCriticalSection(long) +@ stdcall -stub -version=0x600+ RtlUpdateClonedSRWLock(ptr long) +@ stdcall RtlUpdateTimer(ptr ptr long long) +@ stdcall RtlUpperChar(long) +@ stdcall RtlUpperString(ptr ptr) +@ stdcall -version=0x502 RtlUsageHeap(ptr long ptr) +@ stdcall -stub -version=0x600+ RtlUserThreadStart(long long) +@ stdcall RtlValidAcl(ptr) +@ stdcall RtlValidRelativeSecurityDescriptor(ptr long long) +@ stdcall RtlValidSecurityDescriptor(ptr) +@ stdcall RtlValidSid(ptr) +@ stdcall RtlValidateHeap(long long ptr) +@ stdcall RtlValidateProcessHeaps() +@ stdcall RtlValidateUnicodeString(long ptr) +@ stdcall RtlVerifyVersionInfo(ptr long double) +@ stdcall -arch=x86_64 RtlVirtualUnwind(long int64 int64 ptr ptr ptr ptr ptr) +@ stdcall -version=0x600+ RtlWakeAllConditionVariable(ptr) +@ stdcall -version=0x600+ RtlWakeConditionVariable(ptr) +@ stdcall RtlWalkFrameChain(ptr long long) +@ stdcall RtlWalkHeap(long ptr) +@ stdcall -stub -version=0x600+ RtlWerpReportException(long long ptr long long ptr) +@ stdcall -stub -version=0x600+ RtlWow64CallFunction64() +@ stdcall RtlWow64EnableFsRedirection(long) +@ stdcall RtlWow64EnableFsRedirectionEx(long ptr) +@ stdcall -stub -version=0x600+ -arch=x86_64 RtlWow64GetThreadContext(ptr ptr) +@ stdcall -stub -version=0x600+ -arch=x86_64 RtlWow64LogMessageInEventLogger(long long long) +@ stdcall -stub -version=0x600+ -arch=x86_64 RtlWow64SetThreadContext(long long) +@ stdcall -stub -version=0x600+ -arch=x86_64 RtlWow64SuspendThread(long long) +@ stdcall RtlWriteMemoryStream(ptr ptr long ptr) +@ stdcall RtlWriteRegistryValue(long ptr ptr long ptr long) +@ stdcall RtlZeroHeap(ptr long) +@ stdcall RtlZeroMemory(ptr long) +@ stdcall RtlZombifyActivationContext(ptr) +@ stdcall RtlpApplyLengthFunction(long long ptr ptr) +@ stdcall -stub -version=0x600+ RtlpCheckDynamicTimeZoneInformation(ptr long) +@ stdcall -stub -version=0x600+ RtlpCleanupRegistryKeys() +@ stdcall -stub -version=0x600+ RtlpConvertCultureNamesToLCIDs(wstr ptr) +@ stdcall -stub -version=0x600+ RtlpConvertLCIDsToCultureNames(wstr ptr) +@ stdcall -stub -version=0x600+ RtlpCreateProcessRegistryInfo(ptr) +@ stdcall RtlpEnsureBufferSize(long ptr long) +@ stdcall -stub -version=0x600+ RtlpGetLCIDFromLangInfoNode(long long ptr) +@ stdcall -stub -version=0x600+ RtlpGetNameFromLangInfoNode(long long long) +@ stdcall -stub -version=0x600+ RtlpGetSystemDefaultUILanguage(ptr long) +@ stdcall -stub -version=0x600+ RtlpGetUserOrMachineUILanguage4NLS(long long ptr) +@ stdcall -stub -version=0x600+ RtlpInitializeLangRegistryInfo(ptr) +@ stdcall -stub -version=0x600+ RtlpIsQualifiedLanguage(long ptr long) +@ stdcall -stub -version=0x600+ RtlpLoadMachineUIByPolicy(ptr long ptr) +@ stdcall -stub -version=0x600+ RtlpLoadUserUIByPolicy(ptr long ptr) +@ stdcall -stub -version=0x600+ RtlpMuiFreeLangRegistryInfo(long) +@ stdcall -stub -version=0x600+ RtlpMuiRegCreateRegistryInfo() +@ stdcall -stub -version=0x600+ RtlpMuiRegFreeRegistryInfo(long long) +@ stdcall -stub -version=0x600+ RtlpMuiRegLoadRegistryInfo(long long) +@ stdcall RtlpNotOwnerCriticalSection(ptr) +@ stdcall RtlpNtCreateKey(ptr long ptr long ptr ptr) +@ stdcall RtlpNtEnumerateSubKey(ptr ptr long long) +@ stdcall RtlpNtMakeTemporaryKey(ptr) +@ stdcall RtlpNtOpenKey(ptr long ptr long) +@ stdcall RtlpNtQueryValueKey(ptr ptr ptr ptr long) +@ stdcall RtlpNtSetValueKey(ptr long ptr long) +@ stdcall -stub -version=0x600+ RtlpQueryDefaultUILanguage(ptr long) +@ stdcall -stub -version=0x600+ -arch=x86_64 RtlpQueryProcessDebugInformationFromWow64(long ptr) +@ stdcall -stub -version=0x600+ RtlpRefreshCachedUILanguage(wstr long) +@ stdcall -stub -version=0x600+ RtlpSetInstallLanguage(long ptr) +@ stdcall -stub -version=0x600+ RtlpSetPreferredUILanguages(long ptr ptr) ; x64 only? +@ stdcall -stub -arch=i386 -version=0x600+ RtlpSetUserPreferredUILanguages(long ptr ptr) ; seems to be i386 only +@ stdcall RtlpUnWaitCriticalSection(ptr) +@ stdcall -stub -version=0x600+ RtlpVerifyAndCommitUILanguageSettings(long) +@ stdcall RtlpWaitForCriticalSection(ptr) +@ stdcall RtlxAnsiStringToUnicodeSize(ptr) +@ stdcall RtlxOemStringToUnicodeSize(ptr) +@ stdcall RtlxUnicodeStringToAnsiSize(ptr) +@ stdcall RtlxUnicodeStringToOemSize(ptr) +@ stdcall -stub -version=0x600+ ShipAssert(long long) +@ stdcall -stub -version=0x600+ ShipAssertGetBufferInfo(ptr ptr) +@ stdcall -stub -version=0x600+ ShipAssertMsgA(long long) +@ stdcall -stub -version=0x600+ ShipAssertMsgW(long long) +@ stdcall -stub -version=0x600+ TpAllocAlpcCompletion(ptr ptr ptr ptr ptr) +@ stdcall -version=0x600+ TpAllocCleanupGroup(ptr) +@ stdcall -version=0x600+ TpAllocIoCompletion(ptr ptr ptr ptr ptr) +@ stdcall -version=0x600+ TpAllocPool(ptr ptr) +@ stdcall -version=0x600+ TpAllocTimer(ptr ptr ptr ptr) +@ stdcall -version=0x600+ TpAllocWait(ptr ptr ptr ptr) +@ stdcall -version=0x600+ TpAllocWork(ptr ptr ptr ptr) +@ stdcall -version=0x600+ TpCallbackLeaveCriticalSectionOnCompletion(ptr ptr) +@ stdcall -version=0x600+ TpCallbackMayRunLong(ptr) +@ stdcall -version=0x600+ TpCallbackReleaseMutexOnCompletion(ptr ptr) +@ stdcall -version=0x600+ TpCallbackReleaseSemaphoreOnCompletion(ptr ptr long) +@ stdcall -version=0x600+ TpCallbackSetEventOnCompletion(ptr ptr) +@ stdcall -version=0x600+ TpCallbackUnloadDllOnCompletion(ptr ptr) +@ stdcall -version=0x600+ TpCancelAsyncIoOperation(ptr) +@ stdcall -stub -version=0x600+ TpCaptureCaller(long) +@ stdcall -stub -version=0x600+ TpCheckTerminateWorker(ptr) +@ stdcall -stub -version=0x600+ TpDbgDumpHeapUsage(long ptr long) +@ stdcall -stub -version=0x600+ TpDbgSetLogRoutine() +@ stdcall -version=0x600+ TpDisassociateCallback(ptr) +@ stdcall -version=0x600+ TpIsTimerSet(ptr) +@ stdcall -version=0x600+ TpPostWork(ptr) +@ stdcall -version=0x600+ TpQueryPoolStackInformation(ptr ptr) +@ stdcall -stub -version=0x600+ TpReleaseAlpcCompletion(ptr) +@ stdcall -version=0x600+ TpReleaseCleanupGroup(ptr) +@ stdcall -version=0x600+ TpReleaseCleanupGroupMembers(ptr long ptr) +@ stdcall -version=0x600+ TpReleaseIoCompletion(ptr) +@ stdcall -version=0x600+ TpReleasePool(ptr) +@ stdcall -version=0x600+ TpReleaseTimer(ptr) +@ stdcall -version=0x600+ TpReleaseWait(ptr) +@ stdcall -version=0x600+ TpReleaseWork(ptr) +@ stdcall -version=0x600+ TpSetPoolMaxThreads(ptr long) +@ stdcall -version=0x600+ TpSetPoolMinThreads(ptr long) +@ stdcall -version=0x600+ TpSetPoolStackInformation(ptr ptr) +@ stdcall -version=0x600+ TpSetTimer(ptr ptr long long) +@ stdcall -version=0x600+ TpSetWait(ptr long ptr) +@ stdcall -version=0x600+ TpSimpleTryPost(ptr ptr ptr) +@ stdcall -version=0x600+ TpStartAsyncIoOperation(ptr) +@ stdcall -stub -version=0x600+ TpWaitForAlpcCompletion(ptr) +@ stdcall -version=0x600+ TpWaitForIoCompletion(ptr long) +@ stdcall -version=0x600+ TpWaitForTimer(ptr long) +@ stdcall -version=0x600+ TpWaitForWait(ptr long) +@ stdcall -version=0x600+ TpWaitForWork(ptr long) +@ stdcall -ret64 VerSetConditionMask(double long long) +@ stdcall -stub -version=0x600+ WerCheckEventEscalation(long ptr) ; doesn't exist in win11 +@ stdcall -stub -version=0x600+ WerReportSQMEvent(long long long) +@ stdcall -stub -version=0x600+ WerReportWatsonEvent(long long long long) ; doesn't exist in win11 +@ stdcall -stub -version=0x600+ WinSqmAddToStream(ptr long long long) ; stub on Win11? +@ stdcall -stub -version=0x600+ WinSqmEndSession(ptr) ; stub on Win11? +@ stdcall -stub -version=0x600+ WinSqmEventEnabled(long ptr) ; stub on Win11? +@ stdcall -stub -version=0x600+ WinSqmEventWrite(long long long) ; stub on Win11? +@ stdcall -stub -version=0x600+ WinSqmIsOptedIn() ; stub on Win11? +@ stdcall -stub -version=0x600+ WinSqmSetString(ptr long ptr) ; stub on Win11? +@ stdcall -stub -version=0x600+ WinSqmStartSession(ptr) ; stub on Win11? +@ stdcall ZwAcceptConnectPort(ptr long ptr long long ptr) +@ stdcall ZwAccessCheck(ptr long long ptr ptr ptr ptr ptr) +@ stdcall ZwAccessCheckAndAuditAlarm(ptr long ptr ptr ptr long ptr long ptr ptr ptr) +@ stdcall ZwAccessCheckByType(ptr ptr ptr long ptr long ptr ptr long ptr ptr) +@ stdcall ZwAccessCheckByTypeAndAuditAlarm(ptr ptr ptr ptr ptr ptr long long long ptr long ptr long ptr ptr ptr) +@ stdcall ZwAccessCheckByTypeResultList(ptr ptr ptr long ptr long ptr ptr long ptr ptr) +@ stdcall ZwAccessCheckByTypeResultListAndAuditAlarm(ptr ptr ptr ptr ptr ptr long long long ptr long ptr long ptr ptr ptr) +@ stdcall ZwAccessCheckByTypeResultListAndAuditAlarmByHandle(ptr ptr ptr ptr ptr ptr ptr long long long ptr long ptr long ptr ptr ptr) +@ stub -version=0x600+ ZwAcquireCMFViewOwnership +@ stdcall ZwAddAtom(ptr long ptr) +@ stdcall ZwAddBootEntry(ptr long) +@ stdcall ZwAddDriverEntry(ptr long) +@ stdcall ZwAdjustGroupsToken(long long long long long long) +@ stdcall ZwAdjustPrivilegesToken(long long long long long long) +@ stdcall ZwAlertResumeThread(long ptr) +@ stdcall ZwAlertThread(long) +@ stdcall ZwAllocateLocallyUniqueId(ptr) +@ stdcall ZwAllocateUserPhysicalPages(ptr ptr ptr) +@ stdcall ZwAllocateUuids(ptr ptr ptr ptr) +@ stdcall ZwAllocateVirtualMemory(long ptr ptr ptr long long) +@ stub -version=0x600+ ZwAlpcAcceptConnectPort +@ stub -version=0x600+ ZwAlpcCancelMessage +@ stub -version=0x600+ ZwAlpcConnectPort +@ stub -version=0x600+ ZwAlpcCreatePort +@ stub -version=0x600+ ZwAlpcCreatePortSection +@ stub -version=0x600+ ZwAlpcCreateResourceReserve +@ stub -version=0x600+ ZwAlpcCreateSectionView +@ stub -version=0x600+ ZwAlpcCreateSecurityContext +@ stub -version=0x600+ ZwAlpcDeletePortSection +@ stub -version=0x600+ ZwAlpcDeleteResourceReserve +@ stub -version=0x600+ ZwAlpcDeleteSectionView +@ stub -version=0x600+ ZwAlpcDeleteSecurityContext +@ stub -version=0x600+ ZwAlpcDisconnectPort +@ stub -version=0x600+ ZwAlpcImpersonateClientOfPort +@ stub -version=0x600+ ZwAlpcOpenSenderProcess +@ stub -version=0x600+ ZwAlpcOpenSenderThread +@ stub -version=0x600+ ZwAlpcQueryInformation +@ stub -version=0x600+ ZwAlpcQueryInformationMessage +@ stub -version=0x600+ ZwAlpcRevokeSecurityContext +@ stub -version=0x600+ ZwAlpcSendWaitReceivePort +@ stub -version=0x600+ ZwAlpcSetInformation +@ stdcall ZwApphelpCacheControl(long ptr) +@ stdcall ZwAreMappedFilesTheSame(ptr ptr) +@ stdcall ZwAssignProcessToJobObject(long long) +@ stdcall ZwCallbackReturn(ptr long long) +@ stdcall ZwCancelDeviceWakeupRequest(ptr) +@ stdcall ZwCancelIoFile(long ptr) +@ stdcall -stub -version=0x600+ ZwCancelIoFileEx(ptr ptr ptr) +@ stdcall -stub -version=0x600+ ZwCancelSynchronousIoFile(ptr ptr ptr) +@ stdcall ZwCancelTimer(long ptr) +@ stdcall ZwClearEvent(long) +@ stdcall ZwClose(long) +@ stdcall ZwCloseObjectAuditAlarm(ptr ptr long) +@ stdcall -stub -version=0x600+ ZwCommitComplete(ptr ptr) +@ stdcall -stub -version=0x600+ ZwCommitEnlistment(ptr ptr) +@ stdcall -stub -version=0x600+ ZwCommitTransaction(ptr long) +@ stdcall ZwCompactKeys(long ptr) +@ stdcall ZwCompareTokens(ptr ptr ptr) +@ stdcall ZwCompleteConnectPort(ptr) +@ stdcall ZwCompressKey(ptr) +@ stdcall ZwConnectPort(ptr ptr ptr ptr ptr ptr ptr ptr) +@ stdcall ZwContinue(ptr long) +@ stdcall ZwCreateDebugObject(ptr long ptr long) +@ stdcall ZwCreateDirectoryObject(long long long) +@ stdcall -stub -version=0x600+ ZwCreateEnlistment(ptr long ptr ptr ptr long long ptr) +@ stdcall ZwCreateEvent(long long long long long) +@ stdcall ZwCreateEventPair(ptr long ptr) +@ stdcall ZwCreateFile(ptr long ptr ptr long long long ptr long long ptr) +@ stdcall ZwCreateIoCompletion(ptr long ptr long) +@ stdcall ZwCreateJobObject(ptr long ptr) +@ stdcall ZwCreateJobSet(long ptr long) +@ stdcall ZwCreateKey(ptr long ptr long ptr long long) +@ stdcall -stub -version=0x600+ ZwCreateKeyTransacted(ptr long ptr long ptr long ptr ptr) +@ stdcall ZwCreateKeyedEvent(ptr long ptr long) +@ stdcall ZwCreateMailslotFile(long long long long long long long long) +@ stdcall ZwCreateMutant(ptr long ptr long) +@ stdcall ZwCreateNamedPipeFile(ptr long ptr ptr long long long long long long long long long ptr) +@ stdcall ZwCreatePagingFile(ptr ptr ptr long) +@ stdcall ZwCreatePort(ptr ptr long long long) +@ stdcall ZwCreateProcess(ptr long ptr ptr long ptr ptr ptr) +@ stdcall ZwCreateProcessEx(ptr long ptr ptr long ptr ptr ptr long) +@ stdcall ZwCreateProfile(ptr ptr ptr long long ptr long long long) ; CHECKME +@ stdcall -stub -version=0x600+ ZwCreateResourceManager(ptr long ptr ptr ptr long wstr) +@ stdcall ZwCreateSection(ptr long ptr ptr long long long) +@ stdcall ZwCreateSemaphore(ptr long ptr long long) +@ stdcall ZwCreateSymbolicLinkObject(ptr long ptr ptr) +@ stdcall ZwCreateThread(ptr long ptr ptr ptr ptr ptr long) +@ stdcall -stub -version=0x600+ ZwCreateThreadEx(ptr long ptr ptr ptr ptr long long long long ptr) +@ stdcall ZwCreateTimer(ptr long ptr long) +@ stdcall ZwCreateToken(ptr long ptr long ptr ptr ptr ptr ptr ptr ptr ptr ptr) +@ stdcall -stub -version=0x600+ ZwCreateTransaction(ptr long ptr ptr ptr long long long ptr wstr) +@ stdcall -stub -version=0x600+ ZwCreateTransactionManager(ptr long ptr ptr long long) +@ stdcall -stub -version=0x600+ ZwCreateUserProcess(ptr ptr long long ptr ptr long long ptr ptr ptr) +@ stdcall ZwCreateWaitablePort(ptr ptr long long long) +@ stdcall -stub -version=0x600+ ZwCreateWorkerFactory(ptr long ptr ptr ptr ptr ptr long long long) +@ stdcall ZwDebugActiveProcess(ptr ptr) +@ stdcall ZwDebugContinue(ptr ptr long) +@ stdcall ZwDelayExecution(long ptr) +@ stdcall ZwDeleteAtom(long) +@ stdcall ZwDeleteBootEntry(long) +@ stdcall ZwDeleteDriverEntry(long) +@ stdcall ZwDeleteFile(ptr) +@ stdcall ZwDeleteKey(long) +@ stdcall ZwDeleteObjectAuditAlarm(ptr ptr long) +@ stdcall -stub -version=0x600+ ZwDeletePrivateNamespace(ptr) +@ stdcall ZwDeleteValueKey(long ptr) +@ stdcall ZwDeviceIoControlFile(long long long long long long long long long long) +@ stdcall ZwDisplayString(ptr) +@ stdcall ZwDuplicateObject(long long long ptr long long long) +@ stdcall ZwDuplicateToken(long long long long long long) +@ stdcall ZwEnumerateBootEntries(ptr ptr) +@ stdcall ZwEnumerateDriverEntries(ptr ptr) +@ stdcall ZwEnumerateKey(long long long ptr long ptr) +@ stdcall ZwEnumerateSystemEnvironmentValuesEx(long ptr long) +@ stdcall -stub -version=0x600+ ZwEnumerateTransactionObject(ptr long ptr long ptr) +@ stdcall ZwEnumerateValueKey(long long long ptr long ptr) +@ stdcall ZwExtendSection(ptr ptr) +@ stdcall ZwFilterToken(ptr long ptr ptr ptr ptr) +@ stdcall ZwFindAtom(ptr long ptr) +@ stdcall ZwFlushBuffersFile(long ptr) +@ stdcall -stub -version=0x600+ ZwFlushInstallUILanguage(long long) +@ stdcall ZwFlushInstructionCache(long ptr long) +@ stdcall ZwFlushKey(long) +@ stdcall -stub -version=0x600+ ZwFlushProcessWriteBuffers() +@ stdcall ZwFlushVirtualMemory(long ptr ptr long) +@ stdcall ZwFlushWriteBuffer() +@ stdcall ZwFreeUserPhysicalPages(ptr ptr ptr) +@ stdcall ZwFreeVirtualMemory(long ptr ptr long) +@ stdcall -stub -version=0x600+ ZwFreezeRegistry(long) +@ stdcall -stub -version=0x600+ ZwFreezeTransactions(ptr ptr) +@ stdcall ZwFsControlFile(long long long long long long long long long long) +@ stdcall ZwGetContextThread(long ptr) +@ stdcall ZwGetCurrentProcessorNumber() +@ stdcall ZwGetDevicePowerState(ptr ptr) +@ stdcall -stub -version=0x600+ ZwGetMUIRegistryInfo(long ptr ptr) +@ stdcall -stub -version=0x600+ ZwGetNextProcess(ptr long long long ptr) +@ stdcall -stub -version=0x600+ ZwGetNextThread(ptr ptr long long long ptr) +@ stdcall -stub -version=0x600+ ZwGetNlsSectionPtr(long long ptr ptr ptr) +@ stdcall -stub -version=0x600+ ZwGetNotificationResourceManager(ptr ptr long ptr ptr long ptr) +@ stdcall ZwGetPlugPlayEvent(long long ptr long) +@ stdcall ZwGetWriteWatch(long long ptr long ptr ptr ptr) +@ stdcall ZwImpersonateAnonymousToken(ptr) +@ stdcall ZwImpersonateClientOfPort(ptr ptr) +@ stdcall ZwImpersonateThread(ptr ptr ptr) +@ stdcall -stub -version=0x600+ ZwInitializeNlsFiles(ptr ptr ptr ptr) +@ stdcall ZwInitializeRegistry(long) +@ stdcall ZwInitiatePowerAction(long long long long) +@ stdcall ZwIsProcessInJob(long long) +@ stdcall ZwIsSystemResumeAutomatic() +@ stdcall -stub -version=0x600+ ZwIsUILanguageComitted() +@ stdcall ZwListenPort(ptr ptr) +@ stdcall ZwLoadDriver(ptr) +@ stdcall ZwLoadKey2(ptr ptr long) +@ stdcall ZwLoadKey(ptr ptr) +@ stdcall ZwLoadKeyEx(ptr ptr long ptr) +@ stdcall ZwLockFile(long long ptr ptr ptr ptr ptr ptr long long) +@ stdcall ZwLockProductActivationKeys(ptr ptr) +@ stdcall ZwLockRegistryKey(ptr) +@ stdcall ZwLockVirtualMemory(long ptr ptr long) +@ stdcall ZwMakePermanentObject(ptr) +@ stdcall ZwMakeTemporaryObject(long) +@ stdcall -stub -version=0x600+ ZwMapCMFModule(long long ptr ptr ptr) +@ stdcall ZwMapUserPhysicalPages(ptr ptr ptr) +@ stdcall ZwMapUserPhysicalPagesScatter(ptr ptr ptr) +@ stdcall ZwMapViewOfSection(long long ptr long long ptr ptr long long long) +@ stdcall ZwModifyBootEntry(ptr) +@ stdcall ZwModifyDriverEntry(ptr) +@ stdcall ZwNotifyChangeDirectoryFile(long long ptr ptr ptr ptr long long long) +@ stdcall ZwNotifyChangeKey(long long ptr ptr ptr long long ptr long long) +@ stdcall ZwNotifyChangeMultipleKeys(ptr long ptr ptr ptr ptr ptr long long ptr long long) +@ stdcall ZwOpenDirectoryObject(long long long) +@ stdcall -stub -version=0x600+ ZwOpenEnlistment(ptr long ptr ptr ptr) +@ stdcall ZwOpenEvent(long long long) +@ stdcall ZwOpenEventPair(ptr long ptr) +@ stdcall ZwOpenFile(ptr long ptr ptr long long) +@ stdcall ZwOpenIoCompletion(ptr long ptr) +@ stdcall ZwOpenJobObject(ptr long ptr) +@ stdcall ZwOpenKey(ptr long ptr) +@ stdcall -stub -version=0x600+ ZwOpenKeyTransacted(ptr long ptr ptr) +@ stdcall ZwOpenKeyedEvent(ptr long ptr) +@ stdcall ZwOpenMutant(ptr long ptr) +@ stdcall ZwOpenObjectAuditAlarm(ptr ptr ptr ptr ptr ptr long long ptr long long ptr) +@ stdcall -stub -version=0x600+ ZwOpenPrivateNamespace(ptr long ptr ptr) +@ stdcall ZwOpenProcess(ptr long ptr ptr) +@ stdcall ZwOpenProcessToken(long long ptr) +@ stdcall ZwOpenProcessTokenEx(long long long ptr) +@ stdcall -stub -version=0x600+ ZwOpenResourceManager(ptr long ptr ptr ptr) +@ stdcall ZwOpenSection(ptr long ptr) +@ stdcall ZwOpenSemaphore(long long ptr) +@ stdcall -stub -version=0x600+ ZwOpenSession(ptr long ptr) +@ stdcall ZwOpenSymbolicLinkObject (ptr long ptr) +@ stdcall ZwOpenThread(ptr long ptr ptr) +@ stdcall ZwOpenThreadToken(long long long ptr) +@ stdcall ZwOpenThreadTokenEx(long long long long ptr) +@ stdcall ZwOpenTimer(ptr long ptr) +@ stdcall -stub -version=0x600+ ZwOpenTransaction(ptr long ptr ptr ptr) +@ stdcall -stub -version=0x600+ ZwOpenTransactionManager(ptr long ptr wstr ptr long) +@ stdcall ZwPlugPlayControl(ptr ptr long) +@ stdcall ZwPowerInformation(long ptr long ptr long) +@ stdcall -stub -version=0x600+ ZwPrePrepareComplete(ptr ptr) +@ stdcall -stub -version=0x600+ ZwPrePrepareEnlistment(ptr ptr) +@ stdcall -stub -version=0x600+ ZwPrepareComplete(ptr ptr) +@ stdcall -stub -version=0x600+ ZwPrepareEnlistment(ptr ptr) +@ stdcall ZwPrivilegeCheck(ptr ptr ptr) +@ stdcall ZwPrivilegeObjectAuditAlarm(ptr ptr ptr long ptr long) +@ stdcall ZwPrivilegedServiceAuditAlarm(ptr ptr ptr ptr long) +@ stdcall -stub -version=0x600+ ZwPropagationComplete(ptr long long ptr) +@ stdcall -stub -version=0x600+ ZwPropagationFailed(ptr long long) +@ stdcall ZwProtectVirtualMemory(long ptr ptr long ptr) +@ stdcall ZwPulseEvent(long ptr) +@ stdcall ZwQueryAttributesFile(ptr ptr) +@ stdcall ZwQueryBootEntryOrder(ptr ptr) +@ stdcall ZwQueryBootOptions(ptr ptr) +@ stdcall ZwQueryDebugFilterState(long long) +@ stdcall ZwQueryDefaultLocale(long ptr) +@ stdcall ZwQueryDefaultUILanguage(ptr) +@ stdcall ZwQueryDirectoryFile(long long ptr ptr ptr ptr long long long ptr long) +@ stdcall ZwQueryDirectoryObject(long ptr long long long ptr ptr) +@ stdcall ZwQueryDriverEntryOrder(ptr ptr) +@ stdcall ZwQueryEaFile(long ptr ptr long long ptr long ptr long) +@ stdcall ZwQueryEvent(long long ptr long ptr) +@ stdcall ZwQueryFullAttributesFile(ptr ptr) +@ stdcall ZwQueryInformationAtom(long long ptr long ptr) +@ stdcall -stub -version=0x600+ ZwQueryInformationEnlistment(ptr long ptr long ptr) +@ stdcall ZwQueryInformationFile(long ptr ptr long long) +@ stdcall ZwQueryInformationJobObject(long long ptr long ptr) +@ stdcall ZwQueryInformationPort(ptr long ptr long ptr) +@ stdcall ZwQueryInformationProcess(long long ptr long ptr) +@ stdcall -stub -version=0x600+ ZwQueryInformationResourceManager(ptr long ptr long ptr) +@ stdcall ZwQueryInformationThread(long long ptr long ptr) +@ stdcall ZwQueryInformationToken(long long ptr long ptr) +@ stdcall -stub -version=0x600+ ZwQueryInformationTransaction(ptr long ptr long ptr) +@ stdcall -stub -version=0x600+ ZwQueryInformationTransactionManager(ptr) +@ stdcall -stub -version=0x600+ ZwQueryInformationWorkerFactory(ptr long ptr long ptr) +@ stdcall ZwQueryInstallUILanguage(ptr) +@ stdcall ZwQueryIntervalProfile(long ptr) +@ stdcall ZwQueryIoCompletion(long long ptr long ptr) +@ stdcall ZwQueryKey(long long ptr long ptr) +@ stdcall -stub -version=0x600+ ZwQueryLicenseValue(ptr ptr ptr long ptr) +@ stdcall ZwQueryMultipleValueKey(long ptr long ptr long ptr) +@ stdcall ZwQueryMutant(long long ptr long ptr) +@ stdcall ZwQueryObject(long long long long long) +@ stdcall ZwQueryOpenSubKeys(ptr ptr) +@ stdcall ZwQueryOpenSubKeysEx(ptr long ptr ptr) +@ stdcall ZwQueryPerformanceCounter (long long) +@ stdcall ZwQueryPortInformationProcess() +@ stdcall ZwQueryQuotaInformationFile(ptr ptr ptr long long ptr long ptr long) +@ stdcall ZwQuerySection (long long long long long) +@ stdcall ZwQuerySecurityObject (long long long long long) +@ stdcall ZwQuerySemaphore (long long long long long) +@ stdcall ZwQuerySymbolicLinkObject(long ptr ptr) +@ stdcall ZwQuerySystemEnvironmentValue(ptr ptr long ptr) +@ stdcall ZwQuerySystemEnvironmentValueEx(ptr ptr ptr ptr ptr) +@ stdcall ZwQuerySystemInformation(long long long long) +@ stdcall ZwQuerySystemTime(ptr) +@ stdcall ZwQueryTimer(ptr long ptr long ptr) +@ stdcall ZwQueryTimerResolution(long long long) +@ stdcall ZwQueryValueKey(long ptr long ptr long ptr) +@ stdcall ZwQueryVirtualMemory(long ptr long ptr long ptr) +@ stdcall ZwQueryVolumeInformationFile(long ptr ptr long long) +@ stdcall ZwQueueApcThread(long ptr long long long) +@ stdcall ZwRaiseException(ptr ptr long) +@ stdcall ZwRaiseHardError(long long long ptr long ptr) +@ stdcall ZwReadFile(long long ptr ptr ptr ptr long ptr ptr) +@ stdcall ZwReadFileScatter(long long ptr ptr ptr ptr long ptr ptr) +@ stdcall -stub -version=0x600+ ZwReadOnlyEnlistment(ptr ptr) +@ stdcall ZwReadRequestData(ptr ptr long ptr long ptr) +@ stdcall ZwReadVirtualMemory(long ptr ptr long ptr) +@ stdcall -stub -version=0x600+ ZwRecoverEnlistment(ptr ptr) +@ stdcall -stub -version=0x600+ ZwRecoverResourceManager(ptr) +@ stdcall -stub -version=0x600+ ZwRecoverTransactionManager(ptr) +@ stdcall -stub -version=0x600+ ZwRegisterProtocolAddressInformation(ptr ptr long ptr long) +@ stdcall ZwRegisterThreadTerminatePort(ptr) +@ stdcall -stub -version=0x600+ ZwReleaseCMFViewOwnership() +@ stdcall ZwReleaseKeyedEvent(ptr ptr long ptr) +@ stdcall ZwReleaseMutant(long ptr) +@ stdcall ZwReleaseSemaphore(long long ptr) +@ stdcall -stub -version=0x600+ ZwReleaseWorkerFactoryWorker(ptr) +@ stdcall ZwRemoveIoCompletion(ptr ptr ptr ptr ptr) +@ stdcall -stub -version=0x600+ ZwRemoveIoCompletionEx(ptr ptr long ptr ptr long) +@ stdcall ZwRemoveProcessDebug(ptr ptr) +@ stdcall ZwRenameKey(ptr ptr) +@ stdcall -stub -version=0x600+ ZwRenameTransactionManager(wstr ptr) +@ stdcall ZwReplaceKey(ptr long ptr) +@ stdcall -stub -version=0x600+ ZwReplacePartitionUnit(wstr wstr long) +@ stdcall ZwReplyPort(ptr ptr) +@ stdcall ZwReplyWaitReceivePort(ptr ptr ptr ptr) +@ stdcall ZwReplyWaitReceivePortEx(ptr ptr ptr ptr ptr) +@ stdcall ZwReplyWaitReplyPort(ptr ptr) +@ stdcall ZwRequestDeviceWakeup(ptr) +@ stdcall ZwRequestPort(ptr ptr) +@ stdcall ZwRequestWaitReplyPort(ptr ptr ptr) +@ stdcall ZwRequestWakeupLatency(long) +@ stdcall ZwResetEvent(long ptr) +@ stdcall ZwResetWriteWatch(long ptr long) +@ stdcall ZwRestoreKey(long long long) +@ stdcall ZwResumeProcess(ptr) +@ stdcall ZwResumeThread(long long) +@ stdcall -stub -version=0x600+ ZwRollbackComplete(ptr ptr) +@ stdcall -stub -version=0x600+ ZwRollbackEnlistment(ptr ptr) +@ stdcall -stub -version=0x600+ ZwRollbackTransaction(ptr long) +@ stdcall -stub -version=0x600+ ZwRollforwardTransactionManager(ptr ptr) +@ stdcall ZwSaveKey(long long) +@ stdcall ZwSaveKeyEx(ptr ptr long) +@ stdcall ZwSaveMergedKeys(ptr ptr ptr) +@ stdcall ZwSecureConnectPort(ptr ptr ptr ptr ptr ptr ptr ptr ptr) +@ stdcall ZwSetBootEntryOrder(ptr ptr) +@ stdcall ZwSetBootOptions(ptr long) +@ stdcall ZwSetContextThread(long ptr) +@ stdcall ZwSetDebugFilterState(long long long) +@ stdcall ZwSetDefaultHardErrorPort(ptr) +@ stdcall ZwSetDefaultLocale(long long) +@ stdcall ZwSetDefaultUILanguage(long) +@ stdcall ZwSetDriverEntryOrder(ptr ptr) +@ stdcall ZwSetEaFile(long ptr ptr long) +@ stdcall ZwSetEvent(long long) +@ stdcall ZwSetEventBoostPriority(ptr) +@ stdcall ZwSetHighEventPair(ptr) +@ stdcall ZwSetHighWaitLowEventPair(ptr) +@ stdcall ZwSetInformationDebugObject(ptr long ptr long ptr) +@ stdcall -stub -version=0x600+ ZwSetInformationEnlistment(ptr long ptr long) +@ stdcall ZwSetInformationFile(long long long long long) +@ stdcall ZwSetInformationJobObject(long long ptr long) +@ stdcall ZwSetInformationKey(long long ptr long) +@ stdcall ZwSetInformationObject(long long ptr long) +@ stdcall ZwSetInformationProcess(long long long long) +@ stdcall -stub -version=0x600+ ZwSetInformationResourceManager(ptr long ptr long) +@ stdcall ZwSetInformationThread(long long ptr long) +@ stdcall ZwSetInformationToken(long long ptr long) +@ stdcall -stub -version=0x600+ ZwSetInformationTransaction(ptr long ptr long) +@ stdcall -stub -version=0x600+ ZwSetInformationTransactionManager(ptr long ptr long) +@ stdcall -stub -version=0x600+ ZwSetInformationWorkerFactory(ptr long ptr long) +@ stdcall ZwSetIntervalProfile(long long) +@ stdcall ZwSetIoCompletion(ptr long ptr long long) +@ stdcall ZwSetLdtEntries(long int64 long int64) +@ stdcall ZwSetLowEventPair(ptr) +@ stdcall ZwSetLowWaitHighEventPair(ptr) +@ stdcall ZwSetQuotaInformationFile(ptr ptr ptr long) +@ stdcall ZwSetSecurityObject(long long ptr) +@ stdcall ZwSetSystemEnvironmentValue(ptr ptr) +@ stdcall ZwSetSystemEnvironmentValueEx(ptr ptr ptr ptr ptr) +@ stdcall ZwSetSystemInformation(long ptr long) +@ stdcall ZwSetSystemPowerState(long long long) +@ stdcall ZwSetSystemTime(ptr ptr) +@ stdcall ZwSetThreadExecutionState(long ptr) +@ stdcall ZwSetTimer(long ptr ptr ptr long long ptr) +@ stdcall ZwSetTimerResolution(long long ptr) +@ stdcall ZwSetUuidSeed(ptr) +@ stdcall ZwSetValueKey(long long long long long long) +@ stdcall ZwSetVolumeInformationFile(long ptr ptr long long) +@ stdcall ZwShutdownSystem(long) +@ stdcall -stub -version=0x600+ ZwShutdownWorkerFactory(ptr ptr) +@ stdcall ZwSignalAndWaitForSingleObject(long long long ptr) +@ stdcall -stub -version=0x600+ ZwSinglePhaseReject(ptr ptr) +@ stdcall ZwStartProfile(ptr) +@ stdcall ZwStopProfile(ptr) +@ stdcall ZwSuspendProcess(ptr) +@ stdcall ZwSuspendThread(long ptr) +@ stdcall ZwSystemDebugControl(long ptr long ptr long ptr) +@ stdcall ZwTerminateJobObject(ptr long) +@ stdcall ZwTerminateProcess(ptr long) +@ stdcall ZwTerminateThread(ptr long) +@ stdcall ZwTestAlert() +@ stdcall -stub -version=0x600+ ZwThawRegistry() +@ stdcall -stub -version=0x600+ ZwThawTransactions() +@ stdcall -stub -version=0x600+ ZwTraceControl(long ptr long ptr long long) +@ stdcall ZwTraceEvent(long long long ptr) +@ stdcall ZwTranslateFilePath(ptr long ptr long) +@ stdcall ZwUnloadDriver(ptr) +@ stdcall ZwUnloadKey2(ptr long) +@ stdcall ZwUnloadKey(long) +@ stdcall ZwUnloadKeyEx(ptr ptr) +@ stdcall ZwUnlockFile(long ptr ptr ptr ptr) +@ stdcall ZwUnlockVirtualMemory(long ptr ptr long) +@ stdcall ZwUnmapViewOfSection(long ptr) +@ stdcall ZwVdmControl(long ptr) +@ stdcall ZwWaitForDebugEvent(ptr long ptr ptr) +@ stdcall ZwWaitForKeyedEvent(ptr ptr long ptr) +@ stdcall ZwWaitForMultipleObjects32(long ptr long long ptr) +@ stdcall ZwWaitForMultipleObjects(long ptr long long ptr) +@ stdcall ZwWaitForSingleObject(long long long) +@ stdcall -stub -version=0x600+ ZwWaitForWorkViaWorkerFactory(ptr ptr long ptr ptr) +@ stdcall ZwWaitHighEventPair(ptr) +@ stdcall ZwWaitLowEventPair(ptr) +@ stdcall -stub -version=0x600+ ZwWorkerFactoryWorkerReady(ptr) +@ stdcall ZwWriteFile(long long ptr ptr ptr ptr long ptr ptr) +@ stdcall ZwWriteFileGather(long long ptr ptr ptr ptr long ptr ptr) +@ stdcall ZwWriteRequestData(ptr ptr long ptr long ptr) +@ stdcall ZwWriteVirtualMemory(long ptr ptr long ptr) +@ stdcall ZwYieldExecution() +@ cdecl -arch=i386 _CIcos() +@ cdecl -arch=i386 _CIlog() +@ cdecl -arch=i386 _CIpow() +@ cdecl -arch=i386 _CIsin() +@ cdecl -arch=i386 _CIsqrt() +@ cdecl -arch=x86_64,arm,arm64 __C_specific_handler(ptr long ptr ptr) +@ cdecl -arch=x86_64,arm,arm64 __chkstk() +@ cdecl __isascii(long) +@ cdecl __iscsym(long) +@ cdecl __iscsymf(long) +@ cdecl -arch=arm __jump_unwind() +@ cdecl -stub -version=0x600+ -arch=x86_64 __misaligned_access() +@ cdecl __toascii(long) +@ cdecl -arch=i386 -ret64 _alldiv(double double) +@ cdecl -arch=i386 _alldvrm() +@ cdecl -arch=i386 -ret64 _allmul(double double) +@ cdecl -arch=i386 -norelay -private _alloca_probe() +@ cdecl -version=0x600+ -arch=i386 -private _alloca_probe_16() +@ stub -version=0x600+ -arch=i386 _alloca_probe_8 +@ cdecl -arch=i386 -ret64 _allrem(double double) +@ cdecl -arch=i386 _allshl() +@ cdecl -arch=i386 _allshr() +@ cdecl -ret64 _atoi64(str) +@ cdecl -arch=i386 -ret64 _aulldiv(double double) +@ cdecl -arch=i386 _aulldvrm() +@ cdecl -arch=i386 -ret64 _aullrem(double double) +@ cdecl -arch=i386 _aullshr() +@ extern -arch=i386 _chkstk +@ cdecl -arch=i386,x86_64,arm _fltused() +@ cdecl -arch=i386 -ret64 _ftol() +@ cdecl _i64toa(double ptr long) +@ cdecl _i64tow(double ptr long) +@ cdecl _itoa(long ptr long) +@ cdecl _itow(long ptr long) +@ cdecl _lfind(ptr ptr ptr long ptr) +@ cdecl -arch=x86_64 _local_unwind() +@ cdecl _ltoa(long ptr long) +@ cdecl _ltow(long ptr long) +@ cdecl _memccpy(ptr ptr long long) +@ cdecl _memicmp(str str long) +@ cdecl -arch=x86_64,arm _setjmp(ptr ptr) +@ cdecl -arch=x86_64,arm _setjmpex(ptr ptr) +@ varargs _snprintf(ptr long str) +@ varargs _snwprintf(ptr long wstr) +@ cdecl _splitpath(str ptr ptr ptr ptr) +@ cdecl _strcmpi(str str) _stricmp +@ cdecl _stricmp(str str) +@ cdecl _strlwr(str) +@ cdecl _strnicmp(str str long) +@ cdecl _strupr(str) +@ cdecl -version=0x400-0x502 -impsym _swprintf() swprintf # Compatibility for pre NT6 +@ cdecl -version=0x600+ _swprintf(ptr str) +@ cdecl -version=0x502 _tolower(long) +@ cdecl -version=0x502 _toupper(long) +@ cdecl _ui64toa(double ptr long) +@ cdecl _ui64tow(double ptr long) +@ cdecl _ultoa(long ptr long) +@ cdecl _ultow(long ptr long) +@ cdecl _vscwprintf(wstr ptr) +@ cdecl _vsnprintf(ptr long str ptr) +@ cdecl _vsnwprintf(ptr long wstr ptr) +@ cdecl -stub -version=0x600+ _vswprintf(ptr wstr ptr) +@ cdecl _wcsicmp(wstr wstr) +@ cdecl _wcslwr(wstr) +@ cdecl _wcsnicmp(wstr wstr long) +@ cdecl _wcstoui64(wstr ptr long) +@ cdecl _wcsupr(wstr) +@ cdecl _wtoi(wstr) +@ cdecl _wtoi64(wstr) +@ cdecl _wtol(wstr) +@ cdecl abs(long) +@ cdecl -arch=i386,x86_64 atan(double) +@ cdecl atoi(str) +@ cdecl atol(str) +@ cdecl bsearch(ptr ptr long long ptr) +@ cdecl ceil(double) +@ cdecl cos(double) +@ cdecl fabs(double) +@ cdecl floor(double) +@ cdecl isalnum(long) +@ cdecl isalpha(long) +@ cdecl iscntrl(long) +@ cdecl isdigit(long) +@ cdecl isgraph(long) +@ cdecl islower(long) +@ cdecl isprint(long) +@ cdecl ispunct(long) +@ cdecl isspace(long) +@ cdecl isupper(long) +@ cdecl iswalpha(long) +@ cdecl iswctype(long long) +@ cdecl iswdigit(long) +@ cdecl iswlower(long) +@ cdecl iswspace(long) +@ cdecl iswxdigit(long) +@ cdecl isxdigit(long) +@ cdecl labs(long) +@ cdecl -arch=i386,x86_64 log(double) +@ cdecl -arch=x86_64 longjmp(ptr) +@ cdecl mbstowcs(ptr str long) +@ cdecl memchr(ptr long long) +@ cdecl memcmp(ptr ptr long) +@ cdecl memcpy(ptr ptr long) memmove +@ cdecl memmove(ptr ptr long) +@ cdecl memset(ptr long long) +@ cdecl -arch=i386,x86_64,arm pow(double double) +@ cdecl qsort(ptr long long ptr) +@ cdecl sin(double) +@ varargs sprintf(ptr str) +@ cdecl -arch=i386,x86_64 sqrt(double) +@ varargs sscanf(str str) +@ cdecl strcat(str str) +@ cdecl strchr(str long) +@ cdecl strcmp(str str) +@ cdecl strcpy(ptr str) +@ cdecl strcspn(str str) +@ cdecl strlen(str) +@ cdecl strncat(str str long) +@ cdecl strncmp(str str long) +@ cdecl strncpy(ptr str long) +@ cdecl strpbrk(str str) +@ cdecl strrchr(str long) +@ cdecl strspn(str str) +@ cdecl strstr(str str) +@ cdecl strtol(str ptr long) +@ cdecl strtoul(str ptr long) +@ varargs swprintf(ptr wstr) +@ cdecl -arch=i386,x86_64 tan(double) +@ cdecl tolower(long) +@ cdecl toupper(long) +@ cdecl towlower(long) +@ cdecl towupper(long) +@ stdcall vDbgPrintEx(long long str ptr) +@ stdcall vDbgPrintExWithPrefix(str long long str ptr) +@ cdecl vsprintf(ptr str ptr) +@ cdecl wcscat(wstr wstr) +@ cdecl wcschr(wstr long) +@ cdecl wcscmp(wstr wstr) +@ cdecl wcscpy(ptr wstr) +@ cdecl wcscspn(wstr wstr) +@ cdecl wcslen(wstr) +@ cdecl wcsncat(wstr wstr long) +@ cdecl wcsncmp(wstr wstr long) +@ cdecl wcsncpy(ptr wstr long) +@ cdecl wcspbrk(wstr wstr) +@ cdecl wcsrchr(wstr long) +@ cdecl wcsspn(wstr wstr) +@ cdecl wcsstr(wstr wstr) +@ cdecl wcstol(wstr ptr long) +@ cdecl wcstombs(ptr ptr long) +@ cdecl wcstoul(wstr ptr long) + +# FIXME: check if this is correct +@ stdcall -arch=arm __dtoi64() +@ stdcall -arch=arm __dtou64() +@ stdcall -arch=arm __i64tod() +@ stdcall -arch=arm __u64tod() +@ stdcall -arch=arm __rt_sdiv() +@ stdcall -arch=arm __rt_sdiv64() +@ stdcall -arch=arm __rt_udiv() +@ stdcall -arch=arm __rt_udiv64() +@ stdcall -arch=arm __rt_srsh() + +@ stdcall -arch=i386 NtWow64ReadVirtualMemory64(ptr long long ptr long long ptr) +@ stdcall -arch=i386 NtWow64WriteVirtualMemory64(ptr long long ptr long long ptr) \ No newline at end of file diff --git a/dll/ntdll/dispatch/amd64/dispatch.S b/dll/ntdll/dispatch/amd64/dispatch.S index ea08389c919ae..278599d111066 100644 --- a/dll/ntdll/dispatch/amd64/dispatch.S +++ b/dll/ntdll/dispatch/amd64/dispatch.S @@ -16,6 +16,7 @@ EXTERN NtContinue:PROC EXTERN LdrpInit:PROC EXTERN ZwCallbackReturn:PROC EXTERN RtlRaiseStatus:PROC +EXTERN LdrpTryWow64Exception:PROC .code @@ -33,6 +34,32 @@ PUBLIC LdrInitializeThunk PUBLIC KiUserApcDispatcher .PROC KiUserApcDispatcher + + /* The stack is set up with a UAPC_FRAME, which ends with a MACHINE_FRAME */ + .PUSHFRAME + .ALLOCSTACK CONTEXT_FRAME_LENGTH + + /* The stack points to a CONTEXT structure. + Create unwind ops for all nonvolatile registers */ + .SAVEREG rbx, CxRbx + .SAVEREG rbp, CxRbp + .SAVEREG rsi, CxRsi + .SAVEREG rdi, CxRdi + .SAVEREG r12, CxR12 + .SAVEREG r13, CxR13 + .SAVEREG r14, CxR14 + .SAVEREG r15, CxR15 + .SAVEXMM128 xmm6, CxXmm6 + .SAVEXMM128 xmm7, CxXmm7 + .SAVEXMM128 xmm8, CxXmm8 + .SAVEXMM128 xmm9, CxXmm9 + .SAVEXMM128 xmm10, CxXmm10 + .SAVEXMM128 xmm11, CxXmm11 + .SAVEXMM128 xmm12, CxXmm12 + .SAVEXMM128 xmm13, CxXmm13 + .SAVEXMM128 xmm14, CxXmm14 + .SAVEXMM128 xmm15, CxXmm15 + .endprolog /* We enter with a 16 byte aligned stack */ @@ -170,12 +197,17 @@ PUBLIC KiUserExceptionDispatcher cld /* Dispatch the exception */ + push rcx + push rdx call RtlDispatchException + pop rdx + pop rcx /* Check for success */ or al, al - jz RaiseException + jz TryWow64 +Fine: /* We're fine, continue execution */ lea rcx, [rsp] /* ContextRecord */ mov dl, 0 /* TestAlert */ @@ -183,6 +215,12 @@ PUBLIC KiUserExceptionDispatcher /* Exit */ jmp Exit + +TryWow64: + call LdrpTryWow64Exception + + or al, al + jnz Fine RaiseException: diff --git a/dll/ntdll/include/ntdllp.h b/dll/ntdll/include/ntdllp.h index bd5cc9ea91c69..bbef5444e864c 100644 --- a/dll/ntdll/include/ntdllp.h +++ b/dll/ntdll/include/ntdllp.h @@ -229,6 +229,15 @@ VOID NTAPI LdrpFinalizeAndDeallocateDataTableEntry(IN PLDR_DATA_TABLE_ENTRY Entry); +#if (_WIN32_WINNT >= _WIN32_WINNT_VISTA) || (DLL_EXPORT_VERSION >= _WIN32_WINNT_VISTA) + +VOID +NTAPI +LdrpSendDllNotifications( + _In_ PLDR_DATA_TABLE_ENTRY DllEntry, + _In_ ULONG NotificationReason); + +#endif /* (_WIN32_WINNT >= _WIN32_WINNT_VISTA) || (DLL_EXPORT_VERSION >= _WIN32_WINNT_VISTA) */ /* path.c */ BOOLEAN @@ -242,4 +251,14 @@ NTAPI RtlpInitializeKeyedEvent( VOID); +VOID +NTAPI +RtlpCloseKeyedEvent( + VOID); + +VOID +NTAPI +RtlpInitializeThreadPooling( + VOID); + /* EOF */ diff --git a/dll/ntdll/ldr/ldrapi.c b/dll/ntdll/ldr/ldrapi.c index a688385cc3a28..8bb1f25ae139d 100644 --- a/dll/ntdll/ldr/ldrapi.c +++ b/dll/ntdll/ldr/ldrapi.c @@ -1497,6 +1497,11 @@ LdrUnloadDll( DPRINT1("LDR: Unmapping [%ws]\n", LdrEntry->BaseDllName.Buffer); } +#if (_WIN32_WINNT >= _WIN32_WINNT_VISTA) || (DLL_EXPORT_VERSION >= _WIN32_WINNT_VISTA) + /* Send shutdown notification */ + LdrpSendDllNotifications(CurrentEntry, LDR_DLL_NOTIFICATION_REASON_UNLOADED); +#endif + /* Check if this is a .NET executable */ CorImageData = RtlImageDirectoryEntryToData(LdrEntry->DllBase, TRUE, @@ -1520,9 +1525,6 @@ LdrUnloadDll( /* Unload the alternate resource module, if any */ LdrUnloadAlternateResourceModule(CurrentEntry->DllBase); - /* FIXME: Send shutdown notification */ - //LdrpSendDllNotifications(CurrentEntry, 2, LdrpShutdownInProgress); - /* Check if a Hotpatch is active */ if (LdrEntry->PatchInformation) { diff --git a/dll/ntdll/ldr/ldrinit.c b/dll/ntdll/ldr/ldrinit.c index 991f498dba252..a3675e0a8bd4d 100644 --- a/dll/ntdll/ldr/ldrinit.c +++ b/dll/ntdll/ldr/ldrinit.c @@ -25,6 +25,7 @@ UNICODE_STRING ImageExecOptionsString = RTL_CONSTANT_STRING(L"\\Registry\\Machin UNICODE_STRING Wow64OptionsString = RTL_CONSTANT_STRING(L""); UNICODE_STRING NtDllString = RTL_CONSTANT_STRING(L"ntdll.dll"); UNICODE_STRING Kernel32String = RTL_CONSTANT_STRING(L"kernel32.dll"); +UNICODE_STRING Wow64String = RTL_CONSTANT_STRING(L"wow64.dll"); const UNICODE_STRING LdrpDotLocal = RTL_CONSTANT_STRING(L".Local"); BOOLEAN LdrpInLdrInit; @@ -56,9 +57,7 @@ ULONG LdrpNumberOfProcessors; PVOID NtDllBase; extern LARGE_INTEGER RtlpTimeout; extern BOOLEAN RtlpTimeoutDisable; -PVOID LdrpHeap; LIST_ENTRY LdrpHashTable[LDR_HASH_TABLE_ENTRIES]; -LIST_ENTRY LdrpDllNotificationList; HANDLE LdrpKnownDllObjectDirectory; UNICODE_STRING LdrpKnownDllPath; WCHAR LdrpKnownDllPathBuffer[128]; @@ -88,6 +87,7 @@ ULONG LdrpActiveUnloadCount; VOID NTAPI RtlpInitializeVectoredExceptionHandling(VOID); VOID NTAPI RtlpInitDeferredCriticalSection(VOID); VOID NTAPI RtlInitializeHeapManager(VOID); +NTSTATUS NTAPI RtlpInitializeLocaleTable(VOID); ULONG RtlpDisableHeapLookaside; // TODO: Move to heap.c ULONG RtlpShutdownProcessFlags; // TODO: Use it @@ -96,6 +96,14 @@ NTSTATUS LdrPerformRelocations(PIMAGE_NT_HEADERS NTHeaders, PVOID ImageBase); NTSTATUS NTAPI RtlpInitializeActCtx(PVOID* pOldShimData); extern BOOLEAN RtlpUse16ByteSLists; +#ifdef _M_AMD64 +VOID (*LdrpWow64LdrpInitialize)(PVOID) = NULL; +BOOLEAN (*LdrpWow64PassExceptionToGuest)(PCONTEXT, PVOID) = NULL; +ANSI_STRING LdrpWow64LdrpInitializeImportName = RTL_CONSTANT_STRING("Wow64LdrpInitialize"); +ANSI_STRING LdrpWow64PassExceptionToGuestImportName = RTL_CONSTANT_STRING("Wow64PassExceptionToGuest"); +PVOID LdrpWow64BaseAddress = NULL; +#endif + #ifdef _WIN64 #define DEFAULT_SECURITY_COOKIE 0x00002B992DDFA232ll #else @@ -104,6 +112,67 @@ extern BOOLEAN RtlpUse16ByteSLists; /* FUNCTIONS *****************************************************************/ +#ifdef _M_AMD64 + +BOOLEAN +LdrpTryWow64Exception(PCONTEXT Context, PVOID Ptr2) +{ + if (LdrpWow64PassExceptionToGuest != NULL && + Context->SegCs == 0x23) + { + return LdrpWow64PassExceptionToGuest(Context, Ptr2); + } + + return FALSE; +} + +static +NTSTATUS +LdrpLoadWow64(VOID) +{ + NTSTATUS Status; + + DPRINT1("Loading WOW64.DLL\n"); + + if (LdrpWow64LdrpInitialize != NULL) + { + return STATUS_SUCCESS; + } + + Status = LdrLoadDll(NULL, NULL, &Wow64String, &LdrpWow64BaseAddress); + + if (!NT_SUCCESS(Status)) + { + DPRINT1("LDR: Unable to load %wZ, Status=0x%08lx\n", &Wow64String, Status); + return Status; + } + + Status = LdrGetProcedureAddress(LdrpWow64BaseAddress, + &LdrpWow64LdrpInitializeImportName, + 0, + (PVOID*)&LdrpWow64LdrpInitialize); + + if (!NT_SUCCESS(Status)) + { + DPRINT1("LDR: Unable to find WOW64 init function, Status=0x%08lx\n", Status); + return Status; + } + + Status = LdrGetProcedureAddress(LdrpWow64BaseAddress, + &LdrpWow64PassExceptionToGuestImportName, + 0, + (PVOID*)&LdrpWow64PassExceptionToGuest); + + if (!NT_SUCCESS(Status)) + { + DPRINT1("LDR: Unable to find WOW64 exception passing function, Status=0x%08lx\n", Status); + return Status; + } + + return STATUS_SUCCESS; +} +#endif + /* * @implemented */ @@ -511,12 +580,18 @@ LdrpInitializeThread(IN PCONTEXT Context) RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx; NTSTATUS Status; PVOID EntryPoint; +#ifdef _M_AMD64 + PIMAGE_NT_HEADERS NtHeader; +#endif DPRINT("LdrpInitializeThread() called for %wZ (%p/%p)\n", &LdrpImageEntry->BaseDllName, NtCurrentTeb()->RealClientId.UniqueProcess, NtCurrentTeb()->RealClientId.UniqueThread); + /* Acquire the loader Lock */ + RtlEnterCriticalSection(&LdrpLoaderLock); + /* Allocate an Activation Context Stack */ DPRINT("ActivationContextStack %p\n", NtCurrentTeb()->ActivationContextStackPointer); Status = RtlAllocateActivationContextStack(&NtCurrentTeb()->ActivationContextStackPointer); @@ -525,8 +600,28 @@ LdrpInitializeThread(IN PCONTEXT Context) DPRINT1("Warning: Unable to allocate ActivationContextStack\n"); } +#ifdef _M_AMD64 + /* Get the NT Headers */ + NtHeader = RtlImageNtHeader(Peb->ImageBaseAddress); + + /* FIXME */ + if (NtHeader->FileHeader.Machine == IMAGE_FILE_MACHINE_I386) + { + Status = LdrpLoadWow64(); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Loading WOW64 failed\n"); + ASSERT(FALSE); + } + + LdrpWow64LdrpInitialize(Context); + goto Exit; + } +#endif + /* Make sure we are not shutting down */ - if (LdrpShutdownInProgress) return; + if (LdrpShutdownInProgress) + goto Exit; /* Allocate TLS */ LdrpAllocateTls(); @@ -633,6 +728,11 @@ LdrpInitializeThread(IN PCONTEXT Context) RtlDeactivateActivationContextUnsafeFast(&ActCtx); } +Exit: + + /* Release the loader lock */ + RtlLeaveCriticalSection(&LdrpLoaderLock); + DPRINT("LdrpInitializeThread() done\n"); } @@ -1510,7 +1610,7 @@ LdrpInitializeExecutionOptions(PUNICODE_STRING ImagePathName, PPEB Peb, PHANDLE /* Call AVRF if necessary */ if (Peb->NtGlobalFlag & (FLG_APPLICATION_VERIFIER | FLG_HEAP_PAGE_ALLOCS)) { - Status = LdrpInitializeApplicationVerifierPackage(KeyHandle, Peb, TRUE, FALSE); + Status = LdrpInitializeApplicationVerifierPackage(KeyHandle, Peb, FALSE, FALSE); if (!NT_SUCCESS(Status)) { DPRINT1("AVRF: LdrpInitializeApplicationVerifierPackage failed with %08X\n", Status); @@ -1538,7 +1638,9 @@ VOID NTAPI LdrpValidateImageForMp(IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry) { - UNIMPLEMENTED; + DPRINT("LdrpValidateImageForMp is unimplemented\n"); + // TODO: + // Scan the LockPrefixTable in the load config directory } BOOLEAN @@ -1998,9 +2100,8 @@ LdrpInitializeProcess(IN PCONTEXT Context, //Peb->FastPebLockRoutine = (PPEBLOCKROUTINE)RtlEnterCriticalSection; //Peb->FastPebUnlockRoutine = (PPEBLOCKROUTINE)RtlLeaveCriticalSection; - /* Setup Callout Lock and Notification list */ + /* Setup Callout Lock */ //RtlInitializeCriticalSection(&RtlpCalloutEntryLock); - InitializeListHead(&LdrpDllNotificationList); /* For old executables, use 16-byte aligned heap */ if ((NtHeader->OptionalHeader.MajorSubsystemVersion <= 3) && @@ -2024,6 +2125,13 @@ LdrpInitializeProcess(IN PCONTEXT Context, return STATUS_NO_MEMORY; } + Status = RtlpInitializeLocaleTable(); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to initialize locale table\n"); + return Status; + } + /* Allocate an Activation Context Stack */ Status = RtlAllocateActivationContextStack(&Teb->ActivationContextStackPointer); if (!NT_SUCCESS(Status)) return Status; @@ -2267,6 +2375,22 @@ LdrpInitializeProcess(IN PCONTEXT Context, /* Initialize Wine's active context implementation for the current process */ RtlpInitializeActCtx(&OldShimData); +#ifdef _M_AMD64 + if (NtHeader->FileHeader.Machine == IMAGE_FILE_MACHINE_I386) + { + Status = LdrpLoadWow64(); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Loading WOW64 failed\n"); + return Status; + } + + _InterlockedIncrement(&LdrpProcessInitialized); + LdrpWow64LdrpInitialize(Context); + return STATUS_SUCCESS; + } +#endif + /* Set the current directory */ Status = RtlSetCurrentDirectory_U(&CurrentDirectory); if (!NT_SUCCESS(Status)) @@ -2405,10 +2529,10 @@ LdrpInitializeProcess(IN PCONTEXT Context, /* Check whether all static imports were properly loaded and return here */ if (!NT_SUCCESS(ImportStatus)) return ImportStatus; -#if (DLL_EXPORT_VERSION >= _WIN32_WINNT_VISTA) + /* Following two calls are for Vista+ support, required for winesync */ /* Initialize the keyed event for condition variables */ RtlpInitializeKeyedEvent(); -#endif + RtlpInitializeThreadPooling(); /* Initialize TLS */ Status = LdrpInitializeTls(); diff --git a/dll/ntdll/ldr/ldrutils.c b/dll/ntdll/ldr/ldrutils.c index e46bb3446dd69..19c90865531db 100644 --- a/dll/ntdll/ldr/ldrutils.c +++ b/dll/ntdll/ldr/ldrutils.c @@ -1226,7 +1226,12 @@ LdrpMapDll(IN PWSTR SearchPath OPTIONAL, /* Insert this entry */ LdrpInsertMemoryTableEntry(LdrEntry); - // LdrpSendDllNotifications(LdrEntry, TRUE, Status == STATUS_IMAGE_NOT_AT_BASE) +#if (_WIN32_WINNT >= _WIN32_WINNT_VISTA) || (DLL_EXPORT_VERSION >= _WIN32_WINNT_VISTA) + LdrpSendDllNotifications(LdrEntry, LDR_DLL_NOTIFICATION_REASON_LOADED); +#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) + LdrEntry->Flags |= LDRP_LOAD_NOTIFICATIONS_SENT; /* LdrEntry->LoadNotificationsSent = TRUE; */ +#endif +#endif /* Check for invalid CPU Image */ if (Status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH) diff --git a/dll/ntdll/ldr/verifier.c b/dll/ntdll/ldr/verifier.c index 2affe04dc804e..249d752140f0f 100644 --- a/dll/ntdll/ldr/verifier.c +++ b/dll/ntdll/ldr/verifier.c @@ -3,7 +3,7 @@ * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) * PURPOSE: Verifier support routines * COPYRIGHT: Copyright 2011 Aleksey Bragin (aleksey@reactos.org) - * Copyright 2018 Mark Jansen (mark.jansen@reactos.org) + * Copyright 2018-2025 Mark Jansen (mark.jansen@reactos.org) */ @@ -13,6 +13,10 @@ #define NDEBUG #include + /* heappage.c */ +HANDLE NTAPI RtlpPageHeapCreate(ULONG Flags, PVOID Addr, SIZE_T TotalSize, SIZE_T CommitSize, PVOID Lock, PRTL_HEAP_PARAMETERS Parameters); +PVOID NTAPI RtlpPageHeapDestroy(HANDLE HeapPtr); + extern PLDR_DATA_TABLE_ENTRY LdrpImageEntry; ULONG AVrfpVerifierFlags = 0; WCHAR AVrfpVerifierDllsString[256] = { 0 }; @@ -329,7 +333,7 @@ AVrfDllUnloadNotification(IN PLDR_DATA_TABLE_ENTRY LdrEntry) { PLIST_ENTRY Entry; - if (!(NtCurrentPeb()->NtGlobalFlag & FLG_APPLICATION_VERIFIER)) + if (!(NtCurrentPeb()->NtGlobalFlag & FLG_APPLICATION_VERIFIER) || !AVrfpInitialized) return; RtlEnterCriticalSection(&AVrfpVerifierLock); @@ -355,6 +359,31 @@ AVrfDllUnloadNotification(IN PLDR_DATA_TABLE_ENTRY LdrEntry) RtlLeaveCriticalSection(&AVrfpVerifierLock); } +VOID +NTAPI +AVrfInternalHeapFreeNotification(PVOID AllocationBase, SIZE_T AllocationSize) +{ + PLIST_ENTRY Entry; + + if (!(NtCurrentPeb()->NtGlobalFlag & FLG_APPLICATION_VERIFIER) || !AVrfpInitialized) + return; + + RtlEnterCriticalSection(&AVrfpVerifierLock); + for (Entry = AVrfpVerifierProvidersList.Flink; Entry != &AVrfpVerifierProvidersList; Entry = Entry->Flink) + { + PVERIFIER_PROVIDER Provider; + RTL_VERIFIER_NTDLLHEAPFREE_CALLBACK ProviderHeapFreeCallback; + + Provider = CONTAINING_RECORD(Entry, VERIFIER_PROVIDER, ListEntry); + + ProviderHeapFreeCallback = Provider->ProviderNtdllHeapFreeCallback; + if (ProviderHeapFreeCallback) + { + ProviderHeapFreeCallback(AllocationBase, AllocationSize); + } + } + RtlLeaveCriticalSection(&AVrfpVerifierLock); +} VOID NTAPI @@ -480,13 +509,48 @@ AVrfpChainDuplicateThunks(VOID) } } +static +PVOID +NTAPI +AVrfpGetStackTraceAddress(ULONG Arg0) +{ + UNIMPLEMENTED; + DbgBreakPoint(); + return NULL; +} + +static +HANDLE +NTAPI +AVrfpDebugPageHeapCreate(ULONG Flags, + PVOID Addr, + SIZE_T TotalSize, + SIZE_T CommitSize, + PVOID Lock, + PRTL_HEAP_PARAMETERS Parameters) +{ + HANDLE hHeap; + hHeap = RtlpPageHeapCreate(Flags, Addr, TotalSize, CommitSize, Lock, Parameters); + DbgPrint("AVRF: DebugPageHeapCreate(Flags=%x, Addr=%p, TotalSize=%u, CommitSize=%u, Lock=%p, Parameters=%p) = %p\n", + Flags, Addr, TotalSize, CommitSize, Lock, Parameters, hHeap); + return hHeap; +} + +static +PVOID +AVrfpDebugPageHeapDestroy(HANDLE HeapPtr) +{ + DbgPrint("AVRF: DebugPageHeapDestroy(HeapPtr=%p)\n", HeapPtr); + return RtlpPageHeapDestroy(HeapPtr); +} + NTSTATUS NTAPI AVrfpLoadAndInitializeProvider(PVERIFIER_PROVIDER Provider) { WCHAR StringBuffer[MAX_PATH + 11]; UNICODE_STRING DllPath; - PRTL_VERIFIER_PROVIDER_DESCRIPTOR Descriptor; + PRTL_VERIFIER_PROVIDER_DESCRIPTOR Descriptor = NULL; PIMAGE_NT_HEADERS ImageNtHeader; NTSTATUS Status; @@ -544,13 +608,9 @@ AVrfpLoadAndInitializeProvider(PVERIFIER_PROVIDER Provider) Descriptor->VerifierFlags = AVrfpVerifierFlags; Descriptor->VerifierDebug = AVrfpDebug; - /* We don't have these yet */ - DPRINT1("AVRF: RtlpGetStackTraceAddress MISSING\n"); - DPRINT1("AVRF: RtlpDebugPageHeapCreate MISSING\n"); - DPRINT1("AVRF: RtlpDebugPageHeapDestroy MISSING\n"); - Descriptor->RtlpGetStackTraceAddress = NULL; - Descriptor->RtlpDebugPageHeapCreate = NULL; - Descriptor->RtlpDebugPageHeapDestroy = NULL; + Descriptor->RtlpGetStackTraceAddress = AVrfpGetStackTraceAddress; + Descriptor->RtlpDebugPageHeapCreate = AVrfpDebugPageHeapCreate; + Descriptor->RtlpDebugPageHeapDestroy = AVrfpDebugPageHeapDestroy; Status = STATUS_SUCCESS; } else diff --git a/dll/ntdll/nt_0600/CMakeLists.txt b/dll/ntdll/nt_0600/CMakeLists.txt index 2eec0df994066..69b9b5f0ff861 100644 --- a/dll/ntdll/nt_0600/CMakeLists.txt +++ b/dll/ntdll/nt_0600/CMakeLists.txt @@ -11,12 +11,15 @@ include_directories( ${REACTOS_SOURCE_DIR}/sdk/include/reactos/subsys) list(APPEND SOURCE - DllMain.c - ${CMAKE_CURRENT_BINARY_DIR}/ntdll_vista.def) + ldr/ldrinit.c + ldr/ldrnotify.c) -add_library(ntdll_vista MODULE ${SOURCE} ntdll_vista.rc) +add_library(ntdll_vista_static ${SOURCE}) +target_link_libraries(ntdll_vista_static) +add_dependencies(ntdll_vista_static psdk) +add_library(ntdll_vista MODULE DllMain.c ${CMAKE_CURRENT_BINARY_DIR}/ntdll_vista.def ntdll_vista.rc) set_module_type(ntdll_vista win32dll ENTRYPOINT DllMain 12) -target_link_libraries(ntdll_vista smlib rtl_vista) +target_link_libraries(ntdll_vista ntdll_vista_static smlib rtl_vista ${PSEH_LIB}) if(ARCH STREQUAL "arm") target_link_libraries(ntdll_vista chkstk) endif() diff --git a/dll/ntdll/nt_0600/DllMain.c b/dll/ntdll/nt_0600/DllMain.c index 90a01419b97e3..38a0d44891667 100644 --- a/dll/ntdll/nt_0600/DllMain.c +++ b/dll/ntdll/nt_0600/DllMain.c @@ -1,25 +1,4 @@ -#include - -#define WIN32_NO_STATUS - -#include -#include -#include -#include -#include -#include -#include - -#define NDEBUG -#include - -VOID -NTAPI -RtlpInitializeKeyedEvent(VOID); - -VOID -NTAPI -RtlpCloseKeyedEvent(VOID); +#include "ntdll_vista.h" BOOL WINAPI diff --git a/dll/ntdll/nt_0600/ldr/ldrinit.c b/dll/ntdll/nt_0600/ldr/ldrinit.c new file mode 100644 index 0000000000000..e9251d9ebf5f2 --- /dev/null +++ b/dll/ntdll/nt_0600/ldr/ldrinit.c @@ -0,0 +1,3 @@ +#include "ntdll_vista.h" + +PVOID LdrpHeap; diff --git a/dll/ntdll/nt_0600/ldr/ldrnotify.c b/dll/ntdll/nt_0600/ldr/ldrnotify.c new file mode 100644 index 0000000000000..70ae996c131b1 --- /dev/null +++ b/dll/ntdll/nt_0600/ldr/ldrnotify.c @@ -0,0 +1,154 @@ +/* + * PROJECT: ReactOS NT Layer/System API + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: DLL Load Notification Implementation + * COPYRIGHT: Copyright 2024 Ratin Gao + */ + +#include "ntdll_vista.h" + +/* GLOBALS *******************************************************************/ + +typedef struct _LDR_DLL_NOTIFICATION_ENTRY +{ + LIST_ENTRY List; + PLDR_DLL_NOTIFICATION_FUNCTION Callback; + PVOID Context; +} LDR_DLL_NOTIFICATION_ENTRY, *PLDR_DLL_NOTIFICATION_ENTRY; + +static RTL_STATIC_LIST_HEAD(LdrpDllNotificationList); + +/* Initialize critical section statically */ +static RTL_CRITICAL_SECTION LdrpDllNotificationLock; +static RTL_CRITICAL_SECTION_DEBUG LdrpDllNotificationLockDebug = { + .CriticalSection = &LdrpDllNotificationLock +}; +static RTL_CRITICAL_SECTION LdrpDllNotificationLock = { + &LdrpDllNotificationLockDebug, + -1, + 0, + 0, + 0, + 0 +}; + +/* FUNCTIONS *****************************************************************/ + +NTSTATUS +NTAPI +LdrRegisterDllNotification( + _In_ ULONG Flags, + _In_ PLDR_DLL_NOTIFICATION_FUNCTION NotificationFunction, + _In_opt_ PVOID Context, + _Out_ PVOID *Cookie) +{ + PLDR_DLL_NOTIFICATION_ENTRY NewEntry; + + /* Check input parameters */ + if (Flags != 0 || NotificationFunction == NULL || Cookie == NULL) + { + return STATUS_INVALID_PARAMETER; + } + + /* Allocate new entry and assign input values */ + NewEntry = RtlAllocateHeap(LdrpHeap, 0, sizeof(*NewEntry)); + if (NewEntry == NULL) + { + return STATUS_NO_MEMORY; + } + NewEntry->Callback = NotificationFunction; + NewEntry->Context = Context; + + /* Add node to the end of global list */ + RtlEnterCriticalSection(&LdrpDllNotificationLock); + InsertTailList(&LdrpDllNotificationList, &NewEntry->List); + RtlLeaveCriticalSection(&LdrpDllNotificationLock); + + /* Cookie is address of the new entry */ + *Cookie = NewEntry; + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +LdrUnregisterDllNotification( + _In_ PVOID Cookie) +{ + NTSTATUS Status = STATUS_DLL_NOT_FOUND; + PLIST_ENTRY Entry; + + /* Find entry to remove */ + RtlEnterCriticalSection(&LdrpDllNotificationLock); + for (Entry = LdrpDllNotificationList.Flink; + Entry != &LdrpDllNotificationList; + Entry = Entry->Flink) + { + if (Entry == Cookie) + { + RemoveEntryList(Entry); + Status = STATUS_SUCCESS; + break; + } + } + RtlLeaveCriticalSection(&LdrpDllNotificationLock); + + if (NT_SUCCESS(Status)) + { + RtlFreeHeap(LdrpHeap, 0, Entry); + } + return Status; +} + +VOID +NTAPI +LdrpSendDllNotifications( + _In_ PLDR_DATA_TABLE_ENTRY DllEntry, + _In_ ULONG NotificationReason) +{ + PLIST_ENTRY Entry; + PLDR_DLL_NOTIFICATION_ENTRY NotificationEntry; + LDR_DLL_NOTIFICATION_DATA NotificationData; + + /* + * LDR_DLL_LOADED_NOTIFICATION_DATA and LDR_DLL_UNLOADED_NOTIFICATION_DATA + * currently are the same. Use C_ASSERT to ensure it, then fill either of them. + */ +#define LdrpAssertDllNotificationDataMember(x)\ + C_ASSERT(FIELD_OFFSET(LDR_DLL_NOTIFICATION_DATA, Loaded.x) ==\ + FIELD_OFFSET(LDR_DLL_NOTIFICATION_DATA, Unloaded.x)) + + C_ASSERT(sizeof(NotificationData.Loaded) == sizeof(NotificationData.Unloaded)); + LdrpAssertDllNotificationDataMember(Flags); + LdrpAssertDllNotificationDataMember(FullDllName); + LdrpAssertDllNotificationDataMember(BaseDllName); + LdrpAssertDllNotificationDataMember(DllBase); + LdrpAssertDllNotificationDataMember(SizeOfImage); + +#undef LdrpAssertDllNotificationDataMember + + NotificationData.Loaded.Flags = 0; /* Reserved and always 0, not DllEntry->Flags */ + NotificationData.Loaded.FullDllName = &DllEntry->FullDllName; + NotificationData.Loaded.BaseDllName = &DllEntry->BaseDllName; + NotificationData.Loaded.DllBase = DllEntry->DllBase; + NotificationData.Loaded.SizeOfImage = DllEntry->SizeOfImage; + + /* Send notification to all registered callbacks */ + RtlEnterCriticalSection(&LdrpDllNotificationLock); + _SEH2_TRY + { + for (Entry = LdrpDllNotificationList.Flink; + Entry != &LdrpDllNotificationList; + Entry = Entry->Flink) + { + NotificationEntry = CONTAINING_RECORD(Entry, LDR_DLL_NOTIFICATION_ENTRY, List); + NotificationEntry->Callback(NotificationReason, + &NotificationData, + NotificationEntry->Context); + } + } + _SEH2_FINALLY + { + RtlLeaveCriticalSection(&LdrpDllNotificationLock); + } + _SEH2_END; +} diff --git a/dll/ntdll/nt_0600/ntdll_vista.h b/dll/ntdll/nt_0600/ntdll_vista.h new file mode 100644 index 0000000000000..47051576c5c9a --- /dev/null +++ b/dll/ntdll/nt_0600/ntdll_vista.h @@ -0,0 +1,21 @@ +#pragma once + +#define _NTSYSTEM_ +#define _NTDLLBUILD_ + +#include + +#define WIN32_NO_STATUS +#include +#include +#include + +#define NTOS_MODE_USER +#include +#include +#include + +#define NDEBUG +#include + +#include "../include/ntdllp.h" diff --git a/dll/ntdll/nt_0600/ntdll_vista.spec b/dll/ntdll/nt_0600/ntdll_vista.spec index d36c6449d8e4b..2bf9f747a008a 100644 --- a/dll/ntdll/nt_0600/ntdll_vista.spec +++ b/dll/ntdll/nt_0600/ntdll_vista.spec @@ -1,3 +1,6 @@ +@ stdcall LdrRegisterDllNotification(long ptr ptr ptr) +@ stdcall LdrUnregisterDllNotification(ptr) + @ stdcall RtlInitializeConditionVariable(ptr) @ stdcall RtlWakeConditionVariable(ptr) @ stdcall RtlWakeAllConditionVariable(ptr) diff --git a/dll/ntdll/rtl/libsupp.c b/dll/ntdll/rtl/libsupp.c index 75618a769517d..021c3b9e75e7e 100644 --- a/dll/ntdll/rtl/libsupp.c +++ b/dll/ntdll/rtl/libsupp.c @@ -16,6 +16,10 @@ #define NDEBUG #include +#ifdef BUILD_WOW6432 +#include "../wow64/ntdll32.h" +#endif + SIZE_T RtlpAllocDeallocQueryBufferSize = PAGE_SIZE; PTEB LdrpTopLevelDllBeingLoadedTeb = NULL; PVOID MmHighestUserAddress = (PVOID)MI_HIGHEST_USER_ADDRESS; @@ -1163,10 +1167,17 @@ LdrpApplyFileNameRedirection( NTSYSAPI NTSTATUS NTAPI -RtlWow64EnableFsRedirection(IN BOOLEAN Wow64FsEnableRedirection) +RtlWow64EnableFsRedirection(IN BOOLEAN Wow64FsDisableRedirection) { - /* This is what Windows returns on x86 */ +#ifdef BUILD_WOW6432 + PVOID Prev; + + /* Negated to match dll\kernel32\client\utils.c implementation of + * Wow64DisableWow64FsRedirection */ + return RtlWow64EnableFsRedirectionEx((PVOID)!Wow64FsDisableRedirection, &Prev); +#else return STATUS_NOT_IMPLEMENTED; +#endif } /* @@ -1178,8 +1189,22 @@ NTAPI RtlWow64EnableFsRedirectionEx(IN PVOID Wow64FsEnableRedirection, OUT PVOID *OldFsRedirectionLevel) { - /* This is what Windows returns on x86 */ +#ifdef BUILD_WOW6432 + LONG Offset = TEB64_TLS_OFFSET + sizeof(UINT64) * WOW64_TLS_FILESYSREDIR; + + /* TODO: Refactor */ + if (OldFsRedirectionLevel != NULL) + { + *OldFsRedirectionLevel = (PVOID)__readgsdword(Offset); + } + + DPRINT1("Setting offset %X (prev: %X) to %X\n", Offset, __readgsdword(Offset), Wow64FsEnableRedirection); + + __writegsdword(Offset, (ULONG)Wow64FsEnableRedirection); + return STATUS_SUCCESS; +#else return STATUS_NOT_IMPLEMENTED; +#endif } /* diff --git a/dll/ntdll/rtl/version.c b/dll/ntdll/rtl/version.c index 96a9be1f16227..63f94592f882f 100644 --- a/dll/ntdll/rtl/version.c +++ b/dll/ntdll/rtl/version.c @@ -17,6 +17,8 @@ /* FUNCTIONS ******************************************************************/ +static signed char g_ReportProductType = 0; + /* HACK: ReactOS specific changes, see bug-reports CORE-6611 and CORE-4620 (aka. #5003) */ static VOID NTAPI SetRosSpecificInfo(IN OUT PRTL_OSVERSIONINFOEXW VersionInformation) @@ -24,7 +26,6 @@ SetRosSpecificInfo(IN OUT PRTL_OSVERSIONINFOEXW VersionInformation) CHAR Buffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(ULONG)]; PKEY_VALUE_PARTIAL_INFORMATION kvpInfo = (PVOID)Buffer; OBJECT_ATTRIBUTES ObjectAttributes; - ULONG ReportAsWorkstation = 0; HANDLE hKey; ULONG Length; NTSTATUS Status; @@ -38,7 +39,7 @@ SetRosSpecificInfo(IN OUT PRTL_OSVERSIONINFOEXW VersionInformation) NULL); /* Don't change anything if the key doesn't exist */ - Status = NtOpenKey(&hKey, KEY_READ, &ObjectAttributes); + Status = (g_ReportProductType == 0) ? NtOpenKey(&hKey, KEY_READ, &ObjectAttributes) : STATUS_CANCELLED; if (NT_SUCCESS(Status)) { /* Get the value from the registry and make sure it's a 32-bit value */ @@ -52,20 +53,28 @@ SetRosSpecificInfo(IN OUT PRTL_OSVERSIONINFOEXW VersionInformation) (kvpInfo->Type == REG_DWORD) && (kvpInfo->DataLength == sizeof(ULONG))) { - /* Is the value set? */ - ReportAsWorkstation = *(PULONG)kvpInfo->Data; - if ((VersionInformation->wProductType == VER_NT_SERVER) && - (ReportAsWorkstation != 0)) + ULONG IsWorkstation = SharedUserData->NtProductType == NtProductWinNt; + ULONG ReportAsWorkstation = (*(PULONG)kvpInfo->Data) != 0; + if (IsWorkstation != ReportAsWorkstation) { - /* It is, modify the product type to report a workstation */ - VersionInformation->wProductType = VER_NT_WORKSTATION; - DPRINT("We modified the reported OS from NtProductServer to NtProductWinNt\n"); + g_ReportProductType = ReportAsWorkstation ? NtProductWinNt : NtProductServer; } } /* Close the handle */ NtClose(hKey); } + + if (g_ReportProductType > 0) + { + VersionInformation->wProductType = g_ReportProductType; + DPRINT("We modified the reported OS product type from %d to %d\n", + SharedUserData->NtProductType, VersionInformation->wProductType); + } + else + { + g_ReportProductType = -1; + } } /********************************************************************** @@ -96,6 +105,21 @@ BOOLEAN NTAPI RtlGetNtProductType(_Out_ PNT_PRODUCT_TYPE ProductType) { *ProductType = SharedUserData->NtProductType; + + if (g_ReportProductType == 0) + { + /* Initialize cached value */ + RTL_OSVERSIONINFOEXW ovi; + ovi.dwOSVersionInfoSize = sizeof(ovi); + ovi.wProductType = *ProductType; + SetRosSpecificInfo(&ovi); + } + + if (g_ReportProductType > 0) + { + *ProductType = g_ReportProductType; + DPRINT("Overriding RtlGetNtProductType to return %d\n", *ProductType); + } return TRUE; } diff --git a/dll/ntdll/wow64/gsfuncs.S b/dll/ntdll/wow64/gsfuncs.S new file mode 100644 index 0000000000000..bd16873169dfd --- /dev/null +++ b/dll/ntdll/wow64/gsfuncs.S @@ -0,0 +1,29 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS NT Library + * FILE: dll/ntdll/wow64/gsfuncs.S + * PURPOSE: WOW64 functions for dealing with 64-bit TEB + * PROGRAMMERS: Marcin Jabłoński + */ + +/* INCLUDES ******************************************************************/ + +#include + +/* FUNCTIONS ****************************************************************/ +.code + +PUBLIC ___readgsdword +___readgsdword: + mov eax, [esp + 4] + mov eax, gs:[eax] + ret + +PUBLIC ___writegsdword +___writegsdword: + mov eax, [esp + 8] + mov ecx, [esp + 4] + mov gs:[eax], ecx + ret + +END \ No newline at end of file diff --git a/dll/ntdll/wow64/memory.c b/dll/ntdll/wow64/memory.c new file mode 100644 index 0000000000000..fbc659ab654b1 --- /dev/null +++ b/dll/ntdll/wow64/memory.c @@ -0,0 +1,35 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS System Libraries + * FILE: dll/ntdll/wow64/memory.c + * PURPOSE: WOW64 NTDLL Functions Definitions + * PROGRAMMER: Marcin Jabłoński + */ + +#include "ntdll32.h" + +/* +NTSYSAPI +NTSTATUS +NTAPI +NtWow64ReadVirtualMemory64(HANDLE ProcessHandle, + UINT64 BaseAddress, + PVOID Buffer, + UINT64 BufferSize, + PUINT64 NumberOfBytesRead) +{ + return STATUS_NOT_IMPLEMENTED; +} + +NTSYSAPI +NTSTATUS +NTAPI +NtWow64WriteVirtualMemory64(HANDLE ProcessHandle, + UINT64 BaseAddress, + PVOID Buffer, + UINT64 BufferSize, + PUINT64 NumberOfBytesWritten) +{ + return STATUS_NOT_IMPLEMENTED; +} +*/ \ No newline at end of file diff --git a/dll/ntdll/wow64/ntdll32.h b/dll/ntdll/wow64/ntdll32.h new file mode 100644 index 0000000000000..89ab732c1651f --- /dev/null +++ b/dll/ntdll/wow64/ntdll32.h @@ -0,0 +1,311 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS System Libraries + * FILE: dll/ntdll/wow64/ntdll32.h + * PURPOSE: WOW64 NTDLL Functions Declarations + * PROGRAMMER: Marcin Jabłoński + */ + +/* TODO: move to some sensible place - somewhere like /sdk/include/reactos/... */ + +#pragma once + +#if defined(BUILD_WOW6432) + +#define TEB64_TLS_OFFSET 0x1480 + +#define WOW64_TLS_FILESYSREDIR 8 + +/********************************************************************** + * Exported functions + */ +NTSYSAPI +NTSTATUS +NTAPI +NtWow64ReadVirtualMemory64(HANDLE ProcessHandle, + UINT64 BaseAddress, + PVOID Buffer, + UINT64 BufferSize, + PUINT64 NumberOfBytesRead); + +NTSYSAPI +NTSTATUS +NTAPI +NtWow64WriteVirtualMemory64(HANDLE ProcessHandle, + UINT64 BaseAddress, + PVOID Buffer, + UINT64 BufferSize, + PUINT64 NumberOfBytesWritten); + +/********************************************************************** + * Helper functions + */ +void __writegsdword(ULONG offset, ULONG value); +ULONG __readgsdword(ULONG offset); + +static +inline +WORD +Wow64ReadNativeWord(UINT64 Address) +{ + WORD Result; + UINT64 BytesRead = 0; + + NTSTATUS Status = + NtWow64ReadVirtualMemory64(NtCurrentProcess(), + Address, + &Result, + sizeof(Result), + &BytesRead); + + if (!NT_SUCCESS(Status) || BytesRead != sizeof(Result)) + { + /* TODO: Throw an access violation exception or something */ + __debugbreak(); + ASSERT(FALSE); + } + + return Result; +} + +static +inline +ULONG +Wow64ReadNativeULong(UINT64 Address) +{ + ULONG Result; + UINT64 BytesRead = 0; + + NTSTATUS Status = + NtWow64ReadVirtualMemory64(NtCurrentProcess(), + Address, + &Result, + sizeof(Result), + &BytesRead); + + if (!NT_SUCCESS(Status) || BytesRead != sizeof(Result)) + { + __debugbreak(); + ASSERT(FALSE); + } + + return Result; +} + +static +inline +UINT64 +Wow64ReadNativePtr(UINT64 Address) +{ + UINT64 Result; + UINT64 BytesRead = 0; + + NTSTATUS Status = + NtWow64ReadVirtualMemory64(NtCurrentProcess(), + Address, + &Result, + sizeof(Result), + &BytesRead); + + if (!NT_SUCCESS(Status) || BytesRead != sizeof(Result)) + { + __debugbreak(); + ASSERT(FALSE); + } + + return Result; +} + +static +inline +void +Wow64WriteNativeULong(UINT64 Address, ULONG Value) +{ + UINT64 BytesWritten = 0; + + NTSTATUS Status = + NtWow64WriteVirtualMemory64(NtCurrentProcess(), + Address, + &Value, + sizeof(Value), + &BytesWritten); + + if (!NT_SUCCESS(Status) || BytesWritten != sizeof(Value)) + { + __debugbreak(); + ASSERT(FALSE); + } +} + +static +inline +void +Wow64WriteNativePtr(UINT64 Address, UINT64 Value) +{ + UINT64 BytesWritten = 0; + + NTSTATUS Status = + NtWow64WriteVirtualMemory64(NtCurrentProcess(), + Address, + &Value, + sizeof(Value), + &BytesWritten); + + if (!NT_SUCCESS(Status) || BytesWritten != sizeof(Value)) + { + __debugbreak(); + ASSERT(FALSE); + } +} + +typedef struct DECLSPEC_ALIGN(16) _M128A64 +{ + ULONGLONG Low; + LONGLONG High; +} M128A64, *PM128A64; + +typedef struct DECLSPEC_ALIGN(16) _XSAVE_FORMAT64 +{ + USHORT ControlWord; + USHORT StatusWord; + UCHAR TagWord; + UCHAR Reserved1; + USHORT ErrorOpcode; + ULONG ErrorOffset; + USHORT ErrorSelector; + USHORT Reserved2; + ULONG DataOffset; + USHORT DataSelector; + USHORT Reserved3; + ULONG MxCsr; + ULONG MxCsr_Mask; + M128A64 FloatRegisters[8]; + M128A64 XmmRegisters[16]; + UCHAR Reserved4[96]; +} XSAVE_FORMAT64, *PXSAVE_FORMAT64; + +typedef struct DECLSPEC_ALIGN(16) _CONTEXT64 +{ + ULONG64 P1Home; + ULONG64 P2Home; + ULONG64 P3Home; + ULONG64 P4Home; + ULONG64 P5Home; + ULONG64 P6Home; + ULONG ContextFlags; + ULONG MxCsr; + USHORT SegCs; + USHORT SegDs; + USHORT SegEs; + USHORT SegFs; + USHORT SegGs; + USHORT SegSs; + ULONG EFlags; + ULONG64 Dr0; + ULONG64 Dr1; + ULONG64 Dr2; + ULONG64 Dr3; + ULONG64 Dr6; + ULONG64 Dr7; + ULONG64 Rax; + ULONG64 Rcx; + ULONG64 Rdx; + ULONG64 Rbx; + ULONG64 Rsp; + ULONG64 Rbp; + ULONG64 Rsi; + ULONG64 Rdi; + ULONG64 R8; + ULONG64 R9; + ULONG64 R10; + ULONG64 R11; + ULONG64 R12; + ULONG64 R13; + ULONG64 R14; + ULONG64 R15; + ULONG64 Rip; + union + { + XSAVE_FORMAT64 FltSave; + struct + { + M128A64 Header[2]; + M128A64 Legacy[8]; + M128A64 Xmm0; + M128A64 Xmm1; + M128A64 Xmm2; + M128A64 Xmm3; + M128A64 Xmm4; + M128A64 Xmm5; + M128A64 Xmm6; + M128A64 Xmm7; + M128A64 Xmm8; + M128A64 Xmm9; + M128A64 Xmm10; + M128A64 Xmm11; + M128A64 Xmm12; + M128A64 Xmm13; + M128A64 Xmm14; + M128A64 Xmm15; + } DUMMYSTRUCTNAME DECLSPEC_ALIGN(16); + } DUMMYUNIONNAME DECLSPEC_ALIGN(16); + M128A64 VectorRegister[26]; + ULONG64 VectorControl; + ULONG64 DebugControl; + ULONG64 LastBranchToRip; + ULONG64 LastBranchFromRip; + ULONG64 LastExceptionToRip; + ULONG64 LastExceptionFromRip; +} CONTEXT64, *PCONTEXT64; + +#ifdef _M_AMD64 +C_ASSERT(sizeof(CONTEXT64) == sizeof(CONTEXT)); +#endif + +#define WOW64_READ_PTR_FIELD(Ptr, StructType, Field) \ + Wow64ReadNativePtr((UINT64)(Ptr) + (ULONG_PTR)&((StructType*)0)->Field) +#define WOW64_WRITE_PTR_FIELD(Ptr, StructType, Field, Value) \ + Wow64WriteNativePtr((UINT64)(Ptr) + (ULONG_PTR)&((StructType*)0)->Field, Value) +#define WOW64_READ_ULONG_FIELD(Ptr, StructType, Field) \ + Wow64ReadNativeULong((UINT64)(Ptr) + (ULONG_PTR)&((StructType*)0)->Field) +#define WOW64_WRITE_ULONG_FIELD(Ptr, StructType, Field, Value) \ + Wow64WriteNativeULong((UINT64)(Ptr) + (ULONG_PTR)&((StructType*)0)->Field, Value) +#define WOW64_READ_WORD_FIELD(Ptr, StructType, Field) \ + Wow64ReadNativeWord((UINT64)(Ptr) + (ULONG_PTR)&((StructType*)0)->Field) +#define WOW64_READ_BYTE_FIELD(Ptr, StructType, Field) ((BYTE)(WOW64_READ_WORD_FIELD(Ptr, StructType, Field) & 0xFF)) + +#define WOW64_READ_HANDLE_FIELD(Ptr, StructType, Field) ((HANDLE)WOW64_READ_ULONG_FIELD(Ptr, StructType, Field)) +#define WOW64_WRITE_HANDLE_FIELD(Ptr, StructType, Field, Value) (WOW64_WRITE_PTR_FIELD(Ptr, StructType, Field, (ULONG_PTR)Value)) + +#define WOW64_CONTAINING_RECORD(Ptr, StructType, Field) ((Ptr) - (ULONG_PTR)&((StructType*)NULL)->Field) +#define WOW64_FIELD_PTR(Ptr, Type, Field) ((Ptr) + (ULONG_PTR)&((Type*)NULL)->Field) + +#define WOW64_CAST_TO_PTR(Ptr) ((PVOID)(ULONG_PTR)(Ptr)) +#define WOW64_CAST_TO_HANDLE(H) ((HANDLE)(ULONG_PTR)(H)) +#define WOW64_CAST_FROM_PTR(Ptr) ((UINT64)((ULONG_PTR)(Ptr))) +#define WOW64_CAST_FROM_HANDLE(H) ((UINT64)((ULONG_PTR)(H))) + +#define NtCurrentPeb64() ((PPEB64)(((ULONG_PTR)NtCurrentPeb()) - ALIGN_UP_BY(sizeof(PEB64), PAGE_SIZE))) +#define NtCurrentTeb64() ((PTEB64)(((ULONG_PTR)NtCurrentTeb()) - ALIGN_UP_BY(sizeof(TEB64), PAGE_SIZE))) + +#else + +#define WOW64_READ_PTR_FIELD(Ptr, StructType, Field) (Ptr->Field) +#define WOW64_WRITE_PTR_FIELD(Ptr, StructType, Field, Value) (Ptr->Field = (Value)) +#define WOW64_READ_ULONG_FIELD(Ptr, StructType, Field) (Ptr->Field) +#define WOW64_WRITE_ULONG_FIELD(Ptr, StructType, Field, Value) (Ptr->Field = (Value)) +#define WOW64_READ_WORD_FIELD(Ptr, StructType, Field) (Ptr->Field) +#define WOW64_READ_BYTE_FIELD(Ptr, StructType, Field) (Ptr->Field) + +#define WOW64_READ_HANDLE_FIELD(Ptr, StructType, Field) (Ptr->Field) +#define WOW64_WRITE_HANDLE_FIELD(Ptr, StructType, Field, Value) (Ptr->Field = (Value)) + +#define WOW64_CONTAINING_RECORD(Ptr, StructType, Field) CONTAINING_RECORD(Ptr, StructType, Field) +#define WOW64_FIELD_PTR(Ptr, Type, Field) (&(Ptr)->Field) + +#define WOW64_CAST_TO_PTR(Ptr) (Ptr) +#define WOW64_CAST_TO_HANDLE(H) (H) +#define WOW64_CAST_FROM_PTR(Ptr) (Ptr) +#define WOW64_CAST_FROM_HANDLE(H) (H) + +#endif diff --git a/dll/shellext/acppage/lang/de-DE.rc b/dll/shellext/acppage/lang/de-DE.rc index a1232a3c17a76..352ae5699cec7 100644 --- a/dll/shellext/acppage/lang/de-DE.rc +++ b/dll/shellext/acppage/lang/de-DE.rc @@ -1,3 +1,14 @@ +/* + * PROJECT: ReactOS Compatibility Layer Shell Extension + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: German resource file + * TRANSLATORS: Copyright 2005 Klemens Friedl + * Copyright 2013 Daniel Reimer + * Copyright 2014 Zehnvor + * Copyright 2017 Robert Naumann + * Copyright 2024 Václav Zouzalík (Venca24) + */ + LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL IDD_ACPPAGESHEET DIALOGEX 0, 0, 224, 226 @@ -30,8 +41,8 @@ BEGIN PUSHBUTTON "<",IDC_REMOVE,144,60,18,14,WS_DISABLED PUSHBUTTON "&OK",IDOK,174,114,60,14 PUSHBUTTON "&Abbrechen",IDCANCEL,240,114,60,14 - LTEXT "Available modes",-1,6,6,52,8 - LTEXT "Selected modes",-1,168,6,51,8 + LTEXT "Verfügbare Modi",-1,6,6,53,8 + LTEXT "Ausgewählte Modi",-1,168,6,58,8 END STRINGTABLE diff --git a/dll/shellext/fontext/CDataObject.cpp b/dll/shellext/fontext/CDataObject.cpp index bff709100439c..8c94a5bc4a0fc 100644 --- a/dll/shellext/fontext/CDataObject.cpp +++ b/dll/shellext/fontext/CDataObject.cpp @@ -9,7 +9,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(fontext); - #if 0 static inline void DumpDataObjectFormats(IDataObject* pObject) { @@ -34,7 +33,6 @@ static inline void DumpDataObjectFormats(IDataObject* pObject) } #endif - HRESULT _CDataObject_CreateInstance(PCIDLIST_ABSOLUTE folder, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, REFIID riid, LPVOID* ppvOut) { @@ -99,4 +97,3 @@ HRESULT _CDataObject_CreateInstance(PCIDLIST_ABSOLUTE folder, UINT cidl, PCUITEM return hr; } - diff --git a/dll/shellext/fontext/CEnumFonts.cpp b/dll/shellext/fontext/CEnumFonts.cpp index 957e816d322c7..95d67bc117f1b 100644 --- a/dll/shellext/fontext/CEnumFonts.cpp +++ b/dll/shellext/fontext/CEnumFonts.cpp @@ -9,8 +9,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(fontext); - - class CEnumFonts : public CComObjectRootEx, public IEnumIDList @@ -21,12 +19,12 @@ class CEnumFonts : public: CEnumFonts() - :m_dwFlags(0) - ,m_Index(0) + : m_dwFlags(0) + , m_Index(0) { } - STDMETHODIMP Initialize(CFontExt* folder, DWORD flags) + HRESULT Initialize(CFontExt* folder, DWORD flags) { m_dwFlags = flags; m_Index = 0; @@ -34,7 +32,7 @@ class CEnumFonts : } // *** IEnumIDList methods *** - STDMETHODIMP Next(ULONG celt, LPITEMIDLIST *rgelt, ULONG *pceltFetched) + STDMETHODIMP Next(ULONG celt, LPITEMIDLIST *rgelt, ULONG *pceltFetched) override { if (!rgelt || (!pceltFetched && celt != 1)) return E_POINTER; @@ -69,22 +67,24 @@ class CEnumFonts : *pceltFetched = Fetched; return hr; } - STDMETHODIMP Skip(ULONG celt) + + STDMETHODIMP Skip(ULONG celt) override { m_Index += celt; return S_OK; } - STDMETHODIMP Reset() + + STDMETHODIMP Reset() override { m_Index = 0; return S_OK; } - STDMETHODIMP Clone(IEnumIDList **ppenum) + + STDMETHODIMP Clone(IEnumIDList **ppenum) override { return E_NOTIMPL; } - public: DECLARE_NOT_AGGREGATABLE(CEnumFonts) DECLARE_PROTECT_FINAL_CONSTRUCT() @@ -94,9 +94,7 @@ class CEnumFonts : END_COM_MAP() }; - HRESULT _CEnumFonts_CreateInstance(CFontExt* zip, DWORD flags, REFIID riid, LPVOID * ppvOut) { return ShellObjectCreatorInit(zip, flags, riid, ppvOut); } - diff --git a/dll/shellext/fontext/CFontCache.cpp b/dll/shellext/fontext/CFontCache.cpp index 53a7a5a6aec10..28413779b54cc 100644 --- a/dll/shellext/fontext/CFontCache.cpp +++ b/dll/shellext/fontext/CFontCache.cpp @@ -241,4 +241,3 @@ void CFontCache::Read() Index++; } } - diff --git a/dll/shellext/fontext/CFontCache.hpp b/dll/shellext/fontext/CFontCache.hpp index ba9d9e39636e3..48435bf008c40 100644 --- a/dll/shellext/fontext/CFontCache.hpp +++ b/dll/shellext/fontext/CFontCache.hpp @@ -7,7 +7,6 @@ #pragma once - class CFontInfo { private: @@ -34,7 +33,6 @@ class CFontInfo DWORD FileAttributes(); }; - class CFontCache { private: @@ -61,7 +59,4 @@ class CFontCache friend class CFontExtModule; }; - extern CFontCache* g_FontCache; - - diff --git a/dll/shellext/fontext/CFontExt.cpp b/dll/shellext/fontext/CFontExt.cpp index 3a011bb3f779d..cf770e21c8eec 100644 --- a/dll/shellext/fontext/CFontExt.cpp +++ b/dll/shellext/fontext/CFontExt.cpp @@ -3,11 +3,10 @@ * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) * PURPOSE: CFontExt implementation * COPYRIGHT: Copyright 2019-2021 Mark Jansen - * Copyright 2019 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) + * Copyright 2019-2025 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) */ #include "precomp.h" -#include "undocgdi.h" // for GetFontResourceInfoW WINE_DEFAULT_DEBUG_CHANNEL(fontext); @@ -41,7 +40,6 @@ static FolderViewColumns g_ColumnDefs[] = { IDS_COL_ATTR, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, 12, LVCFMT_RIGHT }, }; - // Helper functions to translate a guid to a readable name bool GetInterfaceName(const WCHAR* InterfaceString, WCHAR* buf, size_t size) { @@ -79,7 +77,6 @@ WCHAR* g2s(REFCLSID iid) return buf[idx]; } - CFontExt::CFontExt() { InterlockedIncrement(&g_ModuleRefCnt); @@ -365,7 +362,6 @@ STDMETHODIMP CFontExt::GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY apidl, D return S_OK; } - STDMETHODIMP CFontExt::GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, REFIID riid, UINT * prgfInOut, LPVOID * ppvOut) { if (riid == IID_IContextMenu || @@ -456,7 +452,6 @@ STDMETHODIMP CFontExt::GetCurFolder(LPITEMIDLIST *ppidl) return E_POINTER; } - // *** IPersistFolder methods *** STDMETHODIMP CFontExt::Initialize(LPCITEMIDLIST pidl) { @@ -487,7 +482,6 @@ STDMETHODIMP CFontExt::Initialize(LPCITEMIDLIST pidl) return S_OK; } - // *** IPersist methods *** STDMETHODIMP CFontExt::GetClassID(CLSID *lpClassId) { @@ -523,7 +517,7 @@ STDMETHODIMP CFontExt::Drop(IDataObject* pDataObj, DWORD grfKeyState, POINTL pt, *pdwEffect = DROPEFFECT_NONE; CDataObjectHIDA cida(pDataObj); - if (!cida) + if (!cida || cida->cidl <= 0) return E_UNEXPECTED; PCUIDLIST_ABSOLUTE pidlParent = HIDA_GetPIDLFolder(cida); @@ -533,71 +527,23 @@ STDMETHODIMP CFontExt::Drop(IDataObject* pDataObj, DWORD grfKeyState, POINTL pt, return E_FAIL; } - BOOL bOK = TRUE; - CAtlArray FontPaths; + CAtlArray apidl; for (UINT n = 0; n < cida->cidl; ++n) { PCUIDLIST_RELATIVE pidlRelative = HIDA_GetPIDLItem(cida, n); if (!pidlRelative) - continue; - - PIDLIST_ABSOLUTE pidl = ILCombine(pidlParent, pidlRelative); - if (!pidl) - { - ERR("ILCombine failed\n"); - bOK = FALSE; - break; - } - - WCHAR szPath[MAX_PATH]; - BOOL ret = SHGetPathFromIDListW(pidl, szPath); - ILFree(pidl); - - if (!ret) - { - ERR("SHGetPathFromIDListW failed\n"); - bOK = FALSE; - break; - } - - if (PathIsDirectoryW(szPath)) - { - ERR("PathIsDirectory\n"); - bOK = FALSE; - break; - } - - LPCWSTR pchDotExt = PathFindExtensionW(szPath); - if (!IsFontDotExt(pchDotExt)) - { - ERR("'%S' is not supported\n", pchDotExt); - bOK = FALSE; - break; - } + return E_FAIL; - FontPaths.Add(szPath); + apidl.Add(pidlRelative); } - if (!bOK) - return E_FAIL; - - CRegKey keyFonts; - if (keyFonts.Open(FONT_HIVE, FONT_KEY, KEY_WRITE) != ERROR_SUCCESS) + CStringW strMessage; + if (InstallFontFiles(strMessage, pidlParent, cida->cidl, &apidl[0]) != S_OK) { - ERR("keyFonts.Open failed\n"); + // TODO: Show message return E_FAIL; } - for (size_t iItem = 0; iItem < FontPaths.GetCount(); ++iItem) - { - HRESULT hr = DoInstallFontFile(FontPaths[iItem], g_FontCache->FontPath(), keyFonts.m_hKey); - if (FAILED_UNEXPECTEDLY(hr)) - { - bOK = FALSE; - break; - } - } - // Invalidate our cache g_FontCache->Read(); @@ -609,79 +555,5 @@ STDMETHODIMP CFontExt::Drop(IDataObject* pDataObj, DWORD grfKeyState, POINTL pt, // TODO: Show message - return bOK ? S_OK : E_FAIL; -} - -HRESULT CFontExt::DoInstallFontFile(LPCWSTR pszFontPath, LPCWSTR pszFontsDir, HKEY hkeyFonts) -{ - WCHAR szDestFile[MAX_PATH]; - - // Add this font to the font list, so we can query the name - if (!AddFontResourceW(pszFontPath)) - { - ERR("AddFontResourceW('%S') failed\n", pszFontPath); - DeleteFileW(szDestFile); - return E_FAIL; - } - - CStringW strFontName; - HRESULT hr = DoGetFontTitle(pszFontPath, strFontName); - - // We got the name, remove it again - RemoveFontResourceW(pszFontPath); - - if (!SUCCEEDED(hr)) - { - ERR("DoGetFontTitle failed (err=0x%x)!\n", hr); - return hr; - } - - StringCchCopyW(szDestFile, sizeof(szDestFile), pszFontsDir); - - LPCWSTR pszFileTitle = PathFindFileName(pszFontPath); - PathAppendW(szDestFile, pszFileTitle); - if (!CopyFileW(pszFontPath, szDestFile, FALSE)) - { - ERR("CopyFileW('%S', '%S') failed\n", pszFontPath, szDestFile); - return E_FAIL; - } - - DWORD cbData = (wcslen(pszFileTitle) + 1) * sizeof(WCHAR); - LONG nError = RegSetValueExW(hkeyFonts, strFontName, 0, REG_SZ, - (const BYTE *)pszFileTitle, cbData); - if (nError) - { - ERR("RegSetValueExW failed with %ld\n", nError); - DeleteFileW(szDestFile); - return E_FAIL; - } - - AddFontResourceW(szDestFile); - return S_OK; } - -HRESULT -CFontExt::DoGetFontTitle(IN LPCWSTR pszFontPath, OUT CStringW& strFontName) -{ - DWORD cbInfo = 0; - BOOL ret = GetFontResourceInfoW(pszFontPath, &cbInfo, NULL, 1); - if (!ret || !cbInfo) - { - ERR("GetFontResourceInfoW failed (err: %u)\n", GetLastError()); - return E_FAIL; - } - - LPWSTR pszBuffer = strFontName.GetBuffer(cbInfo / sizeof(WCHAR)); - ret = GetFontResourceInfoW(pszFontPath, &cbInfo, pszBuffer, 1); - DWORD dwErr = GetLastError();; - strFontName.ReleaseBuffer(); - if (ret) - { - TRACE("pszFontName: %S\n", (LPCWSTR)strFontName); - return S_OK; - } - - ERR("GetFontResourceInfoW failed (err: %u)\n", dwErr); - return E_FAIL; -} diff --git a/dll/shellext/fontext/CFontExt.hpp b/dll/shellext/fontext/CFontExt.hpp index a3e5431c90ff7..c95952d8114f8 100644 --- a/dll/shellext/fontext/CFontExt.hpp +++ b/dll/shellext/fontext/CFontExt.hpp @@ -3,7 +3,7 @@ * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) * PURPOSE: CFontExt definition * COPYRIGHT: Copyright 2019,2020 Mark Jansen - * Copyright 2019 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) + * Copyright 2019-2025 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) */ #pragma once @@ -18,46 +18,50 @@ class CFontExt : CComHeapPtr m_Folder; public: - CFontExt(); ~CFontExt(); // *** IShellFolder2 methods *** - virtual STDMETHODIMP GetDefaultSearchGUID(GUID *lpguid); - virtual STDMETHODIMP EnumSearches(IEnumExtraSearch **ppenum); - virtual STDMETHODIMP GetDefaultColumn(DWORD dwReserved, ULONG *pSort, ULONG *pDisplay); - virtual STDMETHODIMP GetDefaultColumnState(UINT iColumn, SHCOLSTATEF *pcsFlags); - virtual STDMETHODIMP GetDetailsEx(PCUITEMID_CHILD pidl, const SHCOLUMNID *pscid, VARIANT *pv); - virtual STDMETHODIMP GetDetailsOf(PCUITEMID_CHILD pidl, UINT iColumn, SHELLDETAILS *psd); - virtual STDMETHODIMP MapColumnToSCID(UINT iColumn, SHCOLUMNID *pscid); + STDMETHODIMP GetDefaultSearchGUID(GUID *lpguid) override; + STDMETHODIMP EnumSearches(IEnumExtraSearch **ppenum) override; + STDMETHODIMP GetDefaultColumn(DWORD dwReserved, ULONG *pSort, ULONG *pDisplay) override; + STDMETHODIMP GetDefaultColumnState(UINT iColumn, SHCOLSTATEF *pcsFlags) override; + STDMETHODIMP GetDetailsEx(PCUITEMID_CHILD pidl, const SHCOLUMNID *pscid, VARIANT *pv) override; + STDMETHODIMP GetDetailsOf(PCUITEMID_CHILD pidl, UINT iColumn, SHELLDETAILS *psd) override; + STDMETHODIMP MapColumnToSCID(UINT iColumn, SHCOLUMNID *pscid) override; // *** IShellFolder methods *** - virtual STDMETHODIMP ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName, DWORD *pchEaten, PIDLIST_RELATIVE *ppidl, DWORD *pdwAttributes); - virtual STDMETHODIMP EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList); - virtual STDMETHODIMP BindToObject(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut); - virtual STDMETHODIMP BindToStorage(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut); - virtual STDMETHODIMP CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2); - virtual STDMETHODIMP CreateViewObject(HWND hwndOwner, REFIID riid, LPVOID *ppvOut); - virtual STDMETHODIMP GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY apidl, DWORD *rgfInOut); - virtual STDMETHODIMP GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, REFIID riid, UINT * prgfInOut, LPVOID * ppvOut); - virtual STDMETHODIMP GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET strRet); - virtual STDMETHODIMP SetNameOf(HWND hwndOwner, PCUITEMID_CHILD pidl, LPCOLESTR lpName, DWORD dwFlags, PITEMID_CHILD *pPidlOut); - + STDMETHODIMP ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName, DWORD *pchEaten, + PIDLIST_RELATIVE *ppidl, DWORD *pdwAttributes) override; + STDMETHODIMP EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList) override; + STDMETHODIMP BindToObject(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, + LPVOID *ppvOut) override; + STDMETHODIMP BindToStorage(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, + LPVOID *ppvOut) override; + STDMETHODIMP CompareIDs(LPARAM lParam, + PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2) override; + STDMETHODIMP CreateViewObject(HWND hwndOwner, REFIID riid, LPVOID *ppvOut) override; + STDMETHODIMP GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY apidl, DWORD *rgfInOut) override; + STDMETHODIMP GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, REFIID riid, + UINT * prgfInOut, LPVOID * ppvOut) override; + STDMETHODIMP GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET strRet) override; + STDMETHODIMP SetNameOf(HWND hwndOwner, PCUITEMID_CHILD pidl, LPCOLESTR lpName, DWORD dwFlags, + PITEMID_CHILD *pPidlOut) override; // *** IPersistFolder2 methods *** - virtual STDMETHODIMP GetCurFolder(LPITEMIDLIST *ppidl); + STDMETHODIMP GetCurFolder(LPITEMIDLIST *ppidl) override; // *** IPersistFolder methods *** - virtual STDMETHODIMP Initialize(LPCITEMIDLIST pidl); + STDMETHODIMP Initialize(LPCITEMIDLIST pidl) override; // *** IPersist methods *** - virtual STDMETHODIMP GetClassID(CLSID *lpClassId); + STDMETHODIMP GetClassID(CLSID *lpClassId) override; // *** IDropTarget methods *** - virtual STDMETHODIMP DragEnter(IDataObject* pDataObj, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect); - virtual STDMETHODIMP DragOver(DWORD grfKeyState, POINTL pt, DWORD* pdwEffect); - virtual STDMETHODIMP DragLeave(); - virtual STDMETHODIMP Drop(IDataObject* pDataObj, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect); + STDMETHODIMP DragEnter(IDataObject* pDataObj, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect) override; + STDMETHODIMP DragOver(DWORD grfKeyState, POINTL pt, DWORD* pdwEffect) override; + STDMETHODIMP DragLeave() override; + STDMETHODIMP Drop(IDataObject* pDataObj, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect) override; #if 0 static HRESULT WINAPI log_stuff(void* pv, REFIID riid, LPVOID* ppv, DWORD_PTR dw) @@ -72,10 +76,7 @@ class CFontExt : } #endif -protected: - public: - DECLARE_REGISTRY_RESOURCEID(IDR_FONTEXT) DECLARE_NOT_AGGREGATABLE(CFontExt) @@ -89,7 +90,4 @@ class CFontExt : COM_INTERFACE_ENTRY_IID(IID_IDropTarget, IDropTarget) //COM_INTERFACE_ENTRY_FUNC_BLIND(0, log_stuff) END_COM_MAP() - - HRESULT DoInstallFontFile(LPCWSTR pszFontPath, LPCWSTR pszFontsDir, HKEY hkeyFonts); - HRESULT DoGetFontTitle(IN LPCWSTR pszFontPath, OUT CStringW& strFontName); }; diff --git a/dll/shellext/fontext/CFontMenu.cpp b/dll/shellext/fontext/CFontMenu.cpp index a57e1843c6515..a8c70f359b7d2 100644 --- a/dll/shellext/fontext/CFontMenu.cpp +++ b/dll/shellext/fontext/CFontMenu.cpp @@ -9,7 +9,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(fontext); - const char* DFM_TO_STR(UINT uMsg) { switch(uMsg) @@ -31,7 +30,6 @@ const char* DFM_TO_STR(UINT uMsg) } } - static void RunFontViewer(HWND hwnd, const FontPidlEntry* fontEntry) { WCHAR FontViewerPath[MAX_PATH] = L"%SystemRoot%\\System32\\fontview.exe"; @@ -110,7 +108,6 @@ static HRESULT CALLBACK FontFolderMenuCallback(IShellFolder *psf, HWND hwnd, IDa return E_NOTIMPL; } - HRESULT _CFontMenu_CreateInstance(HWND hwnd, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, IShellFolder *psf, REFIID riid, LPVOID* ppvOut) { @@ -133,4 +130,3 @@ HRESULT _CFontMenu_CreateInstance(HWND hwnd, UINT cidl, PCUITEMID_CHILD_ARRAY ap // We can't create a background menu return E_FAIL; } - diff --git a/dll/shellext/fontext/fontext.cpp b/dll/shellext/fontext/fontext.cpp index f56a884983071..c72f620515aa7 100644 --- a/dll/shellext/fontext/fontext.cpp +++ b/dll/shellext/fontext/fontext.cpp @@ -6,12 +6,12 @@ */ #include "precomp.h" +#include "undocgdi.h" // for GetFontResourceInfoW WINE_DEFAULT_DEBUG_CHANNEL(fontext); const GUID CLSID_CFontExt = { 0xbd84b380, 0x8ca2, 0x1069, { 0xab, 0x1d, 0x08, 0x00, 0x09, 0x48, 0xf5, 0x34 } }; - class CFontExtModule : public CComModule { public: @@ -33,11 +33,9 @@ BEGIN_OBJECT_MAP(ObjectMap) OBJECT_ENTRY(CLSID_CFontExt, CFontExt) END_OBJECT_MAP() - LONG g_ModuleRefCnt; CFontExtModule gModule; - STDAPI DllCanUnloadNow() { if (g_ModuleRefCnt) @@ -50,7 +48,6 @@ STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) return gModule.DllGetClassObject(rclsid, riid, ppv); } - STDAPI DllRegisterServer() { WCHAR Path[MAX_PATH] = { 0 }; @@ -103,6 +100,129 @@ STDAPI DllUnregisterServer() return gModule.DllUnregisterServer(FALSE); } +HRESULT +InstallFontFiles( + _Out_ CStringW& strMsg, + _In_ PCUIDLIST_ABSOLUTE pidlParent, + _In_ UINT cidl, + _In_ PCUITEMID_CHILD_ARRAY apidl) +{ + CAtlArray FontPaths; + for (UINT n = 0; n < cidl; ++n) + { + CComHeapPtr pidl; + pidl.Attach(ILCombine(pidlParent, apidl[n])); + if (!pidl) + { + ERR("Out of memory\n"); + return E_OUTOFMEMORY; + } + + WCHAR szPath[MAX_PATH]; + if (!SHGetPathFromIDListW(pidl, szPath) || PathIsDirectoryW(szPath) || + !IsFontDotExt(PathFindExtensionW(szPath))) + { + ERR("Not font file: %s\n", wine_dbgstr_w(szPath)); + return E_FAIL; + } + + FontPaths.Add(szPath); + } + + CRegKey keyFonts; + if (keyFonts.Open(FONT_HIVE, FONT_KEY, KEY_WRITE) != ERROR_SUCCESS) + { + ERR("CRegKey::Open failed\n"); + return E_FAIL; + } + + for (SIZE_T iItem = 0; iItem < FontPaths.GetCount(); ++iItem) + { + HRESULT hr = DoInstallFontFile(strMsg, FontPaths[iItem], g_FontCache->FontPath(), keyFonts); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + } + + return S_OK; +} + +HRESULT +DoInstallFontFile( + _Out_ CStringW& strMsg, + _In_ PCWSTR pszFontPath, + _In_ PCWSTR pszFontsDir, + _In_ HKEY hkeyFonts) +{ + WCHAR szDestFile[MAX_PATH]; + + // Add this font to the font list, so we can query the name + if (!AddFontResourceW(pszFontPath)) + { + ERR("AddFontResourceW('%S') failed\n", pszFontPath); + return E_FAIL; + } + + CStringW strFontName; + HRESULT hr = DoGetFontTitle(pszFontPath, strFontName); + + // We got the name, remove it again + RemoveFontResourceW(pszFontPath); + + if (!SUCCEEDED(hr)) + { + ERR("DoGetFontTitle failed (err=0x%x)!\n", hr); + return hr; + } + + StringCchCopyW(szDestFile, sizeof(szDestFile), pszFontsDir); + + LPCWSTR pszFileTitle = PathFindFileName(pszFontPath); + PathAppendW(szDestFile, pszFileTitle); + if (!CopyFileW(pszFontPath, szDestFile, FALSE)) + { + ERR("CopyFileW('%S', '%S') failed\n", pszFontPath, szDestFile); + return E_FAIL; + } + + DWORD cbData = (wcslen(pszFileTitle) + 1) * sizeof(WCHAR); + LONG nError = RegSetValueExW(hkeyFonts, strFontName, 0, REG_SZ, + (const BYTE *)pszFileTitle, cbData); + if (nError) + { + ERR("RegSetValueExW failed with %ld\n", nError); + DeleteFileW(szDestFile); + return E_FAIL; + } + + return AddFontResourceW(szDestFile) ? S_OK : E_FAIL; +} + +HRESULT +DoGetFontTitle( + _In_ LPCWSTR pszFontPath, + _Out_ CStringW& strFontName) +{ + DWORD cbInfo = 0; + BOOL ret = GetFontResourceInfoW(pszFontPath, &cbInfo, NULL, 1); + if (!ret || !cbInfo) + { + ERR("GetFontResourceInfoW failed (err: %u)\n", GetLastError()); + return E_FAIL; + } + + LPWSTR pszBuffer = strFontName.GetBuffer(cbInfo / sizeof(WCHAR)); + ret = GetFontResourceInfoW(pszFontPath, &cbInfo, pszBuffer, 1); + DWORD dwErr = GetLastError();; + strFontName.ReleaseBuffer(); + if (ret) + { + TRACE("pszFontName: %S\n", (LPCWSTR)strFontName); + return S_OK; + } + + ERR("GetFontResourceInfoW failed (err: %u)\n", dwErr); + return E_FAIL; +} EXTERN_C BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) diff --git a/dll/shellext/fontext/fontext.h b/dll/shellext/fontext/fontext.h deleted file mode 100644 index a5dd1d088396d..0000000000000 --- a/dll/shellext/fontext/fontext.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef FONTEXT_PRECOMP_H -#define FONTEXT_PRECOMP_H - - -#define WIN32_NO_STATUS -#define _INC_WINDOWS -#define COM_NO_WINDOWS_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern const GUID CLSID_CFontExt; - -#include "CFontExt.hpp" - - -#endif /* FONTEXT_PRECOMP_H */ diff --git a/dll/shellext/fontext/fontpidl.cpp b/dll/shellext/fontext/fontpidl.cpp index 6354e848bf23b..8e7c75dc13690 100644 --- a/dll/shellext/fontext/fontpidl.cpp +++ b/dll/shellext/fontext/fontpidl.cpp @@ -28,7 +28,6 @@ LPITEMIDLIST _ILCreate(LPCWSTR lpString, ULONG Index) return (LPITEMIDLIST)pidl; } - const FontPidlEntry* _FontFromIL(LPCITEMIDLIST pidl) { const FontPidlEntry* fontEntry = (const FontPidlEntry*)pidl; diff --git a/dll/shellext/fontext/fontpidl.hpp b/dll/shellext/fontext/fontpidl.hpp index 1546f646f78b8..4944c3bd4988a 100644 --- a/dll/shellext/fontext/fontpidl.hpp +++ b/dll/shellext/fontext/fontpidl.hpp @@ -18,7 +18,5 @@ struct FontPidlEntry }; #include - LPITEMIDLIST _ILCreate(LPCWSTR lpString, ULONG Index); const FontPidlEntry* _FontFromIL(LPCITEMIDLIST pidl); - diff --git a/dll/shellext/fontext/precomp.h b/dll/shellext/fontext/precomp.h index 2e46032986d41..609a4ce7d2c05 100644 --- a/dll/shellext/fontext/precomp.h +++ b/dll/shellext/fontext/precomp.h @@ -1,6 +1,11 @@ -#ifndef FONTEXT_PRECOMP_H -#define FONTEXT_PRECOMP_H +/* + * PROJECT: ReactOS Font Shell Extension + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Font folder shell extension + * COPYRIGHT: Copyright 2019,2020 Mark Jansen + */ +#pragma once #define WIN32_NO_STATUS #define COM_NO_WINDOWS_H @@ -50,4 +55,20 @@ inline BOOL IsFontDotExt(LPCWSTR pchDotExt) return FALSE; } -#endif /* FONTEXT_PRECOMP_H */ +HRESULT +InstallFontFiles( + _Out_ CStringW& strMessage, + _In_ PCUIDLIST_ABSOLUTE pidlParent, + _In_ UINT cidl, + _In_ PCUITEMID_CHILD_ARRAY apidl); + +HRESULT +DoInstallFontFile( + _Out_ CStringW& strMsg, + _In_ PCWSTR pszFontPath, + _In_ PCWSTR pszFontsDir, + _In_ HKEY hkeyFonts); + +HRESULT DoGetFontTitle( + _In_ PCWSTR pszFontPath, + _Out_ CStringW& strFontName); diff --git a/dll/shellext/mydocs/mydocs.rc b/dll/shellext/mydocs/mydocs.rc index ec24cb9414b8c..9a9aa19a3c16e 100644 --- a/dll/shellext/mydocs/mydocs.rc +++ b/dll/shellext/mydocs/mydocs.rc @@ -9,18 +9,18 @@ #include #include "resource.h" -#include "mydocs_version.rc" - -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +#include "mydocs_version.rc" + 100 ICON "../../win32/shell32/res/icons/235.ico" // IDI_SHELL_MY_DOCUMENTS 101 ICON "../../win32/shell32/res/icons/236.ico" // IDI_SHELL_MY_PICTURES IDR_MYDOCS REGISTRY "res/mydocs.rgs" +/* UTF-8 */ +#pragma code_page(65001) + #ifdef LANGUAGE_DE_DE #include "lang/de-DE.rc" #endif diff --git a/dll/shellext/netshell/lang/bg-BG.rc b/dll/shellext/netshell/lang/bg-BG.rc index 592a2702763d7..a2a827116ed76 100644 --- a/dll/shellext/netshell/lang/bg-BG.rc +++ b/dll/shellext/netshell/lang/bg-BG.rc @@ -76,6 +76,16 @@ BEGIN PUSHBUTTON "&Затваряне", IDC_CLOSE, 120, 155, 60, 14 END +IDD_NETWORKINITPAGE DIALOGEX 0, 0, 317, 143 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "ReactOS Setup" +FONT 8, "MS Shell Dlg" +BEGIN + ICON IDI_NET_SETUP, IDC_STATIC, 21, 10, 20, 20 + LTEXT "Please wait while ReactOS installs networking components.", IDC_STATIC, 53, 7, 240, 20 + CONTROL "", IDC_INSTALL_PROGRESS, "msctls_progress32", PBS_SMOOTH | WS_CHILD | WS_VISIBLE | WS_BORDER, 21, 58, 275, 11 +END + IDD_NETWORKSETTINGSPAGE DIALOGEX 0, 0, 317, 143 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "ReactOS Setup" @@ -165,6 +175,8 @@ END STRINGTABLE BEGIN + IDS_NETWORKINITTITLE "Network Install" + IDS_NETWORKINITSUBTITLE "Installs reqired networking components." IDS_NETWORKSETTINGSTITLE "Network Settings" IDS_NETWORKSETTINGSSUBTITLE "Installs network software used to connect to other networks, computers, and the Internet." IDS_NETWORKCOMPONENTTITLE "Network Components" diff --git a/dll/shellext/netshell/lang/cs-CZ.rc b/dll/shellext/netshell/lang/cs-CZ.rc index d8c18c17d9a2f..139b9aa9070b0 100644 --- a/dll/shellext/netshell/lang/cs-CZ.rc +++ b/dll/shellext/netshell/lang/cs-CZ.rc @@ -76,6 +76,16 @@ BEGIN PUSHBUTTON "&zavřít", IDC_CLOSE, 120, 155, 60, 14 END +IDD_NETWORKINITPAGE DIALOGEX 0, 0, 317, 143 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "ReactOS Setup" +FONT 8, "MS Shell Dlg" +BEGIN + ICON IDI_NET_SETUP, IDC_STATIC, 21, 10, 20, 20 + LTEXT "Please wait while ReactOS installs networking components.", IDC_STATIC, 53, 7, 240, 20 + CONTROL "", IDC_INSTALL_PROGRESS, "msctls_progress32", PBS_SMOOTH | WS_CHILD | WS_VISIBLE | WS_BORDER, 21, 58, 275, 11 +END + IDD_NETWORKSETTINGSPAGE DIALOGEX 0, 0, 317, 143 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Instalátor ReactOS" @@ -165,6 +175,8 @@ END STRINGTABLE BEGIN + IDS_NETWORKINITTITLE "Network Install" + IDS_NETWORKINITSUBTITLE "Installs reqired networking components." IDS_NETWORKSETTINGSTITLE "Síťová nastavení" IDS_NETWORKSETTINGSSUBTITLE "Instaluje síťový software používaný k připojení k dalším sítím, počítačům a k Internetu." IDS_NETWORKCOMPONENTTITLE "Síťové součásti" diff --git a/dll/shellext/netshell/lang/da-DK.rc b/dll/shellext/netshell/lang/da-DK.rc index 557b5f61bca63..1e7333af03683 100644 --- a/dll/shellext/netshell/lang/da-DK.rc +++ b/dll/shellext/netshell/lang/da-DK.rc @@ -76,6 +76,16 @@ BEGIN PUSHBUTTON "&Close", IDC_CLOSE, 120, 155, 60, 14 END +IDD_NETWORKINITPAGE DIALOGEX 0, 0, 317, 143 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "ReactOS Setup" +FONT 8, "MS Shell Dlg" +BEGIN + ICON IDI_NET_SETUP, IDC_STATIC, 21, 10, 20, 20 + LTEXT "Please wait while ReactOS installs networking components.", IDC_STATIC, 53, 7, 240, 20 + CONTROL "", IDC_INSTALL_PROGRESS, "msctls_progress32", PBS_SMOOTH | WS_CHILD | WS_VISIBLE | WS_BORDER, 21, 58, 275, 11 +END + IDD_NETWORKSETTINGSPAGE DIALOGEX 0, 0, 317, 143 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "ReactOS Setup" @@ -165,6 +175,8 @@ END STRINGTABLE BEGIN + IDS_NETWORKINITTITLE "Network Install" + IDS_NETWORKINITSUBTITLE "Installs reqired networking components." IDS_NETWORKSETTINGSTITLE "Network Settings" IDS_NETWORKSETTINGSSUBTITLE "Installs network software used to connect to other networks, computers, and the Internet." IDS_NETWORKCOMPONENTTITLE "Network Components" diff --git a/dll/shellext/netshell/lang/de-DE.rc b/dll/shellext/netshell/lang/de-DE.rc index cfb2da5f0b5ff..c942a6f26ab1f 100644 --- a/dll/shellext/netshell/lang/de-DE.rc +++ b/dll/shellext/netshell/lang/de-DE.rc @@ -76,6 +76,16 @@ BEGIN PUSHBUTTON "&Schließen", IDC_CLOSE, 120, 155, 60, 14 END +IDD_NETWORKINITPAGE DIALOGEX 0, 0, 317, 143 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "ReactOS Setup" +FONT 8, "MS Shell Dlg" +BEGIN + ICON IDI_NET_SETUP, IDC_STATIC, 21, 10, 20, 20 + LTEXT "Bitte warten Sie, während ReactOS Netzwerkkomponenten installiert.", IDC_STATIC, 53, 7, 240, 20 + CONTROL "", IDC_INSTALL_PROGRESS, "msctls_progress32", PBS_SMOOTH | WS_CHILD | WS_VISIBLE | WS_BORDER, 21, 58, 275, 11 +END + IDD_NETWORKSETTINGSPAGE DIALOGEX 0, 0, 317, 143 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "ReactOS Setup" @@ -165,6 +175,8 @@ END STRINGTABLE BEGIN + IDS_NETWORKINITTITLE "Netzwerkinstallation" + IDS_NETWORKINITSUBTITLE "Netzwerkkomponenten werden instaliert." IDS_NETWORKSETTINGSTITLE "Netzwerkeinstellungen" IDS_NETWORKSETTINGSSUBTITLE "Die Installation von Netzwerksoftware ermöglicht das Herstellen von Verbindungen mit anderen Computern, Netzwerken und dem Internet." IDS_NETWORKCOMPONENTTITLE "Netzwerkkomponenten" diff --git a/dll/shellext/netshell/lang/el-GR.rc b/dll/shellext/netshell/lang/el-GR.rc index 42cce6e4c83a9..06818522d7449 100644 --- a/dll/shellext/netshell/lang/el-GR.rc +++ b/dll/shellext/netshell/lang/el-GR.rc @@ -76,6 +76,16 @@ BEGIN PUSHBUTTON "&Close", IDC_CLOSE, 120, 155, 60, 14 END +IDD_NETWORKINITPAGE DIALOGEX 0, 0, 317, 143 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "ReactOS Setup" +FONT 8, "MS Shell Dlg" +BEGIN + ICON IDI_NET_SETUP, IDC_STATIC, 21, 10, 20, 20 + LTEXT "Please wait while ReactOS installs networking components.", IDC_STATIC, 53, 7, 240, 20 + CONTROL "", IDC_INSTALL_PROGRESS, "msctls_progress32", PBS_SMOOTH | WS_CHILD | WS_VISIBLE | WS_BORDER, 21, 58, 275, 11 +END + IDD_NETWORKSETTINGSPAGE DIALOGEX 0, 0, 317, 143 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "ReactOS Setup" @@ -165,6 +175,8 @@ END STRINGTABLE BEGIN + IDS_NETWORKINITTITLE "Network Install" + IDS_NETWORKINITSUBTITLE "Installs reqired networking components." IDS_NETWORKSETTINGSTITLE "Network Settings" IDS_NETWORKSETTINGSSUBTITLE "Installs network software used to connect to other networks, computers, and the Internet." IDS_NETWORKCOMPONENTTITLE "Network Components" diff --git a/dll/shellext/netshell/lang/en-US.rc b/dll/shellext/netshell/lang/en-US.rc index 3b9ac61b58bd6..6191d836647b3 100644 --- a/dll/shellext/netshell/lang/en-US.rc +++ b/dll/shellext/netshell/lang/en-US.rc @@ -76,6 +76,16 @@ BEGIN PUSHBUTTON "&Close", IDC_CLOSE, 120, 155, 60, 14 END +IDD_NETWORKINITPAGE DIALOGEX 0, 0, 317, 143 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "ReactOS Setup" +FONT 8, "MS Shell Dlg" +BEGIN + ICON IDI_NET_SETUP, IDC_STATIC, 21, 10, 20, 20 + LTEXT "Please wait while ReactOS installs networking components.", IDC_STATIC, 53, 7, 240, 20 + CONTROL "", IDC_INSTALL_PROGRESS, "msctls_progress32", PBS_SMOOTH | WS_CHILD | WS_VISIBLE | WS_BORDER, 21, 58, 275, 11 +END + IDD_NETWORKSETTINGSPAGE DIALOGEX 0, 0, 317, 143 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "ReactOS Setup" @@ -165,6 +175,8 @@ END STRINGTABLE BEGIN + IDS_NETWORKINITTITLE "Network Install" + IDS_NETWORKINITSUBTITLE "Installs reqired networking components." IDS_NETWORKSETTINGSTITLE "Network Settings" IDS_NETWORKSETTINGSSUBTITLE "Installs network software used to connect to other networks, computers, and the Internet." IDS_NETWORKCOMPONENTTITLE "Network Components" diff --git a/dll/shellext/netshell/lang/es-ES.rc b/dll/shellext/netshell/lang/es-ES.rc index 5b79c156d3b17..410797605b37d 100644 --- a/dll/shellext/netshell/lang/es-ES.rc +++ b/dll/shellext/netshell/lang/es-ES.rc @@ -84,6 +84,16 @@ BEGIN PUSHBUTTON "&Cerrar", IDC_CLOSE, 120, 155, 60, 14 END +IDD_NETWORKINITPAGE DIALOGEX 0, 0, 317, 143 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "ReactOS Setup" +FONT 8, "MS Shell Dlg" +BEGIN + ICON IDI_NET_SETUP, IDC_STATIC, 21, 10, 20, 20 + LTEXT "Please wait while ReactOS installs networking components.", IDC_STATIC, 53, 7, 240, 20 + CONTROL "", IDC_INSTALL_PROGRESS, "msctls_progress32", PBS_SMOOTH | WS_CHILD | WS_VISIBLE | WS_BORDER, 21, 58, 275, 11 +END + IDD_NETWORKSETTINGSPAGE DIALOGEX 0, 0, 317, 143 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Instalador de ReactOS" @@ -173,6 +183,8 @@ END STRINGTABLE BEGIN + IDS_NETWORKINITTITLE "Network Install" + IDS_NETWORKINITSUBTITLE "Installs reqired networking components." IDS_NETWORKSETTINGSTITLE "Configuración de red" IDS_NETWORKSETTINGSSUBTITLE "Instala aplicaciones de red necesarias para conectarse a otras redes, equipos, y la Internet." IDS_NETWORKCOMPONENTTITLE "Componetes de red" diff --git a/dll/shellext/netshell/lang/fr-FR.rc b/dll/shellext/netshell/lang/fr-FR.rc index 092aa710e62aa..6b8a3c8888712 100644 --- a/dll/shellext/netshell/lang/fr-FR.rc +++ b/dll/shellext/netshell/lang/fr-FR.rc @@ -76,6 +76,16 @@ BEGIN PUSHBUTTON "Fermer", IDC_CLOSE, 120, 155, 60, 14 END +IDD_NETWORKINITPAGE DIALOGEX 0, 0, 317, 143 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "ReactOS Setup" +FONT 8, "MS Shell Dlg" +BEGIN + ICON IDI_NET_SETUP, IDC_STATIC, 21, 10, 20, 20 + LTEXT "Please wait while ReactOS installs networking components.", IDC_STATIC, 53, 7, 240, 20 + CONTROL "", IDC_INSTALL_PROGRESS, "msctls_progress32", PBS_SMOOTH | WS_CHILD | WS_VISIBLE | WS_BORDER, 21, 58, 275, 11 +END + IDD_NETWORKSETTINGSPAGE DIALOGEX 0, 0, 317, 143 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Installation de ReactOS" @@ -165,6 +175,8 @@ END STRINGTABLE BEGIN + IDS_NETWORKINITTITLE "Network Install" + IDS_NETWORKINITSUBTITLE "Installs reqired networking components." IDS_NETWORKSETTINGSTITLE "Paramètres réseau" IDS_NETWORKSETTINGSSUBTITLE "Installe les logiciels réseau utilisés pour se connecter à d'autres réseaux, ordinateurs et à l'Internet." IDS_NETWORKCOMPONENTTITLE "Composants réseau" diff --git a/dll/shellext/netshell/lang/he-IL.rc b/dll/shellext/netshell/lang/he-IL.rc index ea668baa15f68..d71b7cbccd80b 100644 --- a/dll/shellext/netshell/lang/he-IL.rc +++ b/dll/shellext/netshell/lang/he-IL.rc @@ -76,6 +76,16 @@ BEGIN PUSHBUTTON "סגור", IDC_CLOSE, 120, 155, 60, 14 END +IDD_NETWORKINITPAGE DIALOGEX 0, 0, 317, 143 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "ReactOS Setup" +FONT 8, "MS Shell Dlg" +BEGIN + ICON IDI_NET_SETUP, IDC_STATIC, 21, 10, 20, 20 + LTEXT "Please wait while ReactOS installs networking components.", IDC_STATIC, 53, 7, 240, 20 + CONTROL "", IDC_INSTALL_PROGRESS, "msctls_progress32", PBS_SMOOTH | WS_CHILD | WS_VISIBLE | WS_BORDER, 21, 58, 275, 11 +END + IDD_NETWORKSETTINGSPAGE DIALOGEX 0, 0, 317, 143 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "ReactOS Setup" @@ -165,6 +175,8 @@ END STRINGTABLE BEGIN + IDS_NETWORKINITTITLE "Network Install" + IDS_NETWORKINITSUBTITLE "Installs reqired networking components." IDS_NETWORKSETTINGSTITLE "Network Settings" IDS_NETWORKSETTINGSSUBTITLE "Installs network software used to connect to other networks, computers, and the Internet." IDS_NETWORKCOMPONENTTITLE "Network Components" diff --git a/dll/shellext/netshell/lang/hi-IN.rc b/dll/shellext/netshell/lang/hi-IN.rc index 698f640db129d..fbb4edf673834 100644 --- a/dll/shellext/netshell/lang/hi-IN.rc +++ b/dll/shellext/netshell/lang/hi-IN.rc @@ -82,6 +82,16 @@ BEGIN PUSHBUTTON "&बंद करे", IDC_CLOSE, 120, 155, 60, 14 END +IDD_NETWORKINITPAGE DIALOGEX 0, 0, 317, 143 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "ReactOS Setup" +FONT 8, "MS Shell Dlg" +BEGIN + ICON IDI_NET_SETUP, IDC_STATIC, 21, 10, 20, 20 + LTEXT "Please wait while ReactOS installs networking components.", IDC_STATIC, 53, 7, 240, 20 + CONTROL "", IDC_INSTALL_PROGRESS, "msctls_progress32", PBS_SMOOTH | WS_CHILD | WS_VISIBLE | WS_BORDER, 21, 58, 275, 11 +END + IDD_NETWORKSETTINGSPAGE DIALOGEX 0, 0, 317, 143 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "रिऐक्ट ओएस सेटअप" @@ -171,6 +181,8 @@ END STRINGTABLE BEGIN + IDS_NETWORKINITTITLE "Network Install" + IDS_NETWORKINITSUBTITLE "Installs reqired networking components." IDS_NETWORKSETTINGSTITLE "नेटवर्क सेटिंग" IDS_NETWORKSETTINGSSUBTITLE "अन्य नेटवर्क, कंप्यूटर और इंटरनेट से कनेक्ट करने के लिए उपयोग किया जाने वाला नेटवर्क सॉफ़्टवेयर इंस्टॉल करता है।" IDS_NETWORKCOMPONENTTITLE "नेटवर्क कम्पोनेन्ट" diff --git a/dll/shellext/netshell/lang/hu-HU.rc b/dll/shellext/netshell/lang/hu-HU.rc index 599ac84ce3b1a..d93157c2de2c3 100644 --- a/dll/shellext/netshell/lang/hu-HU.rc +++ b/dll/shellext/netshell/lang/hu-HU.rc @@ -76,6 +76,16 @@ BEGIN PUSHBUTTON "&Bezárás", IDC_CLOSE, 120, 155, 60, 14 END +IDD_NETWORKINITPAGE DIALOGEX 0, 0, 317, 143 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "ReactOS Setup" +FONT 8, "MS Shell Dlg" +BEGIN + ICON IDI_NET_SETUP, IDC_STATIC, 21, 10, 20, 20 + LTEXT "Please wait while ReactOS installs networking components.", IDC_STATIC, 53, 7, 240, 20 + CONTROL "", IDC_INSTALL_PROGRESS, "msctls_progress32", PBS_SMOOTH | WS_CHILD | WS_VISIBLE | WS_BORDER, 21, 58, 275, 11 +END + IDD_NETWORKSETTINGSPAGE DIALOGEX 0, 0, 317, 143 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "ReactOS telepítő" @@ -165,6 +175,8 @@ END STRINGTABLE BEGIN + IDS_NETWORKINITTITLE "Network Install" + IDS_NETWORKINITSUBTITLE "Installs reqired networking components." IDS_NETWORKSETTINGSTITLE "Hálózati beállítások" IDS_NETWORKSETTINGSSUBTITLE "Hálózati szoftverek telepítése, melyek segítségével más hálózatokhoz, számítógépekhez vagy az internethez lehet csatlakozni." IDS_NETWORKCOMPONENTTITLE "Hálózati összetevők" diff --git a/dll/shellext/netshell/lang/id-ID.rc b/dll/shellext/netshell/lang/id-ID.rc index 063538fd644b0..d5dbb02a03c7e 100644 --- a/dll/shellext/netshell/lang/id-ID.rc +++ b/dll/shellext/netshell/lang/id-ID.rc @@ -76,6 +76,16 @@ BEGIN PUSHBUTTON "&Close", IDC_CLOSE, 120, 155, 60, 14 END +IDD_NETWORKINITPAGE DIALOGEX 0, 0, 317, 143 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "ReactOS Setup" +FONT 8, "MS Shell Dlg" +BEGIN + ICON IDI_NET_SETUP, IDC_STATIC, 21, 10, 20, 20 + LTEXT "Please wait while ReactOS installs networking components.", IDC_STATIC, 53, 7, 240, 20 + CONTROL "", IDC_INSTALL_PROGRESS, "msctls_progress32", PBS_SMOOTH | WS_CHILD | WS_VISIBLE | WS_BORDER, 21, 58, 275, 11 +END + IDD_NETWORKSETTINGSPAGE DIALOGEX 0, 0, 317, 143 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "ReactOS Setup" @@ -165,6 +175,8 @@ END STRINGTABLE BEGIN + IDS_NETWORKINITTITLE "Network Install" + IDS_NETWORKINITSUBTITLE "Installs reqired networking components." IDS_NETWORKSETTINGSTITLE "Network Settings" IDS_NETWORKSETTINGSSUBTITLE "Installs network software used to connect to other networks, computers, and the Internet." IDS_NETWORKCOMPONENTTITLE "Network Components" diff --git a/dll/shellext/netshell/lang/it-IT.rc b/dll/shellext/netshell/lang/it-IT.rc index abcbc9626192b..6ab9a353b3180 100644 --- a/dll/shellext/netshell/lang/it-IT.rc +++ b/dll/shellext/netshell/lang/it-IT.rc @@ -76,6 +76,16 @@ BEGIN PUSHBUTTON "&Close", IDC_CLOSE, 120, 155, 60, 14 END +IDD_NETWORKINITPAGE DIALOGEX 0, 0, 317, 143 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "ReactOS Setup" +FONT 8, "MS Shell Dlg" +BEGIN + ICON IDI_NET_SETUP, IDC_STATIC, 21, 10, 20, 20 + LTEXT "Please wait while ReactOS installs networking components.", IDC_STATIC, 53, 7, 240, 20 + CONTROL "", IDC_INSTALL_PROGRESS, "msctls_progress32", PBS_SMOOTH | WS_CHILD | WS_VISIBLE | WS_BORDER, 21, 58, 275, 11 +END + IDD_NETWORKSETTINGSPAGE DIALOGEX 0, 0, 317, 143 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "ReactOS Setup" @@ -165,6 +175,8 @@ END STRINGTABLE BEGIN + IDS_NETWORKINITTITLE "Network Install" + IDS_NETWORKINITSUBTITLE "Installs reqired networking components." IDS_NETWORKSETTINGSTITLE "Network Settings" IDS_NETWORKSETTINGSSUBTITLE "Installs network software used to connect to other networks, computers, and the Internet." IDS_NETWORKCOMPONENTTITLE "Network Components" diff --git a/dll/shellext/netshell/lang/ja-JP.rc b/dll/shellext/netshell/lang/ja-JP.rc index 52fa74df0f9d7..5189dd2301f6c 100644 --- a/dll/shellext/netshell/lang/ja-JP.rc +++ b/dll/shellext/netshell/lang/ja-JP.rc @@ -76,6 +76,16 @@ BEGIN PUSHBUTTON "閉じる(&C)", IDC_CLOSE, 120, 155, 60, 14 END +IDD_NETWORKINITPAGE DIALOGEX 0, 0, 317, 143 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "ReactOS Setup" +FONT 8, "MS Shell Dlg" +BEGIN + ICON IDI_NET_SETUP, IDC_STATIC, 21, 10, 20, 20 + LTEXT "Please wait while ReactOS installs networking components.", IDC_STATIC, 53, 7, 240, 20 + CONTROL "", IDC_INSTALL_PROGRESS, "msctls_progress32", PBS_SMOOTH | WS_CHILD | WS_VISIBLE | WS_BORDER, 21, 58, 275, 11 +END + IDD_NETWORKSETTINGSPAGE DIALOGEX 0, 0, 317, 143 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "ReactOS セットアップ" @@ -164,6 +174,8 @@ END STRINGTABLE BEGIN + IDS_NETWORKINITTITLE "Network Install" + IDS_NETWORKINITSUBTITLE "Installs reqired networking components." IDS_NETWORKSETTINGSTITLE "ネットワークの設定" IDS_NETWORKSETTINGSSUBTITLE "別のネットワーク、別のコンピュータ、そしてインターネットに接続するために使うネットワーク ソフトウェアをインストールします。" IDS_NETWORKCOMPONENTTITLE "ネットワーク コンポーネント" diff --git a/dll/shellext/netshell/lang/nl-NL.rc b/dll/shellext/netshell/lang/nl-NL.rc index 9d580bf59e8bc..d92b5a331aab0 100644 --- a/dll/shellext/netshell/lang/nl-NL.rc +++ b/dll/shellext/netshell/lang/nl-NL.rc @@ -76,6 +76,16 @@ BEGIN PUSHBUTTON "&Close", IDC_CLOSE, 120, 155, 60, 14 END +IDD_NETWORKINITPAGE DIALOGEX 0, 0, 317, 143 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "ReactOS Setup" +FONT 8, "MS Shell Dlg" +BEGIN + ICON IDI_NET_SETUP, IDC_STATIC, 21, 10, 20, 20 + LTEXT "Please wait while ReactOS installs networking components.", IDC_STATIC, 53, 7, 240, 20 + CONTROL "", IDC_INSTALL_PROGRESS, "msctls_progress32", PBS_SMOOTH | WS_CHILD | WS_VISIBLE | WS_BORDER, 21, 58, 275, 11 +END + IDD_NETWORKSETTINGSPAGE DIALOGEX 0, 0, 317, 143 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "ReactOS Setup" @@ -165,6 +175,8 @@ END STRINGTABLE BEGIN + IDS_NETWORKINITTITLE "Network Install" + IDS_NETWORKINITSUBTITLE "Installs reqired networking components." IDS_NETWORKSETTINGSTITLE "Network Settings" IDS_NETWORKSETTINGSSUBTITLE "Installs network software used to connect to other networks, computers, and the Internet." IDS_NETWORKCOMPONENTTITLE "Network Components" diff --git a/dll/shellext/netshell/lang/no-NO.rc b/dll/shellext/netshell/lang/no-NO.rc index b687747e32e0b..1bab98808b948 100644 --- a/dll/shellext/netshell/lang/no-NO.rc +++ b/dll/shellext/netshell/lang/no-NO.rc @@ -76,6 +76,16 @@ BEGIN PUSHBUTTON "&Lukk", IDC_CLOSE, 120, 155, 60, 14 END +IDD_NETWORKINITPAGE DIALOGEX 0, 0, 317, 143 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "ReactOS Setup" +FONT 8, "MS Shell Dlg" +BEGIN + ICON IDI_NET_SETUP, IDC_STATIC, 21, 10, 20, 20 + LTEXT "Please wait while ReactOS installs networking components.", IDC_STATIC, 53, 7, 240, 20 + CONTROL "", IDC_INSTALL_PROGRESS, "msctls_progress32", PBS_SMOOTH | WS_CHILD | WS_VISIBLE | WS_BORDER, 21, 58, 275, 11 +END + IDD_NETWORKSETTINGSPAGE DIALOGEX 0, 0, 317, 143 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "ReactOS Setup" @@ -165,6 +175,8 @@ END STRINGTABLE BEGIN + IDS_NETWORKINITTITLE "Network Install" + IDS_NETWORKINITSUBTITLE "Installs reqired networking components." IDS_NETWORKSETTINGSTITLE "Network Settings" IDS_NETWORKSETTINGSSUBTITLE "Installs network software used to connect to other networks, computers, and the Internet." IDS_NETWORKCOMPONENTTITLE "Network Components" diff --git a/dll/shellext/netshell/lang/pl-PL.rc b/dll/shellext/netshell/lang/pl-PL.rc index 5b110e2c82b8b..b7019c8d0be22 100644 --- a/dll/shellext/netshell/lang/pl-PL.rc +++ b/dll/shellext/netshell/lang/pl-PL.rc @@ -78,6 +78,16 @@ BEGIN PUSHBUTTON "&Zamknij", IDC_CLOSE, 120, 155, 60, 14 END +IDD_NETWORKINITPAGE DIALOGEX 0, 0, 317, 143 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "ReactOS Setup" +FONT 8, "MS Shell Dlg" +BEGIN + ICON IDI_NET_SETUP, IDC_STATIC, 21, 10, 20, 20 + LTEXT "Please wait while ReactOS installs networking components.", IDC_STATIC, 53, 7, 240, 20 + CONTROL "", IDC_INSTALL_PROGRESS, "msctls_progress32", PBS_SMOOTH | WS_CHILD | WS_VISIBLE | WS_BORDER, 21, 58, 275, 11 +END + IDD_NETWORKSETTINGSPAGE DIALOGEX 0, 0, 317, 143 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Instalator systemu ReactOS" @@ -167,6 +177,8 @@ END STRINGTABLE BEGIN + IDS_NETWORKINITTITLE "Network Install" + IDS_NETWORKINITSUBTITLE "Installs reqired networking components." IDS_NETWORKSETTINGSTITLE "Ustawienia sieciowe" IDS_NETWORKSETTINGSSUBTITLE "Zainstalowanie oprogramowania sieciowego pozwala na nawiązywanie połączeń z innymi komputerami, sieciami i Internetem." IDS_NETWORKCOMPONENTTITLE "Składniki sieciowe" diff --git a/dll/shellext/netshell/lang/pt-PT.rc b/dll/shellext/netshell/lang/pt-PT.rc index 945fa72cb37fd..e28ba5755578d 100644 --- a/dll/shellext/netshell/lang/pt-PT.rc +++ b/dll/shellext/netshell/lang/pt-PT.rc @@ -83,6 +83,16 @@ BEGIN PUSHBUTTON "&Fechar", IDC_CLOSE, 120, 155, 60, 14 END +IDD_NETWORKINITPAGE DIALOGEX 0, 0, 317, 143 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "ReactOS Setup" +FONT 8, "MS Shell Dlg" +BEGIN + ICON IDI_NET_SETUP, IDC_STATIC, 21, 10, 20, 20 + LTEXT "Please wait while ReactOS installs networking components.", IDC_STATIC, 53, 7, 240, 20 + CONTROL "", IDC_INSTALL_PROGRESS, "msctls_progress32", PBS_SMOOTH | WS_CHILD | WS_VISIBLE | WS_BORDER, 21, 58, 275, 11 +END + IDD_NETWORKSETTINGSPAGE DIALOGEX 0, 0, 317, 143 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Programa de configuração do ReactOS" @@ -172,6 +182,8 @@ END STRINGTABLE BEGIN + IDS_NETWORKINITTITLE "Network Install" + IDS_NETWORKINITSUBTITLE "Installs reqired networking components." IDS_NETWORKSETTINGSTITLE "Definições de rede" IDS_NETWORKSETTINGSSUBTITLE "Instala aplicações de rede necessárias para ligar a outras redes, equipamentos, e à internet." IDS_NETWORKCOMPONENTTITLE "Componentes de rede" diff --git a/dll/shellext/netshell/lang/ro-RO.rc b/dll/shellext/netshell/lang/ro-RO.rc index 180844c682aa0..008a6d1f66f33 100644 --- a/dll/shellext/netshell/lang/ro-RO.rc +++ b/dll/shellext/netshell/lang/ro-RO.rc @@ -85,6 +85,16 @@ BEGIN PUSHBUTTON "Î&nchidere", IDC_CLOSE, 120, 155, 60, 14 END +IDD_NETWORKINITPAGE DIALOGEX 0, 0, 317, 143 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "ReactOS Setup" +FONT 8, "MS Shell Dlg" +BEGIN + ICON IDI_NET_SETUP, IDC_STATIC, 21, 10, 20, 20 + LTEXT "Please wait while ReactOS installs networking components.", IDC_STATIC, 53, 7, 240, 20 + CONTROL "", IDC_INSTALL_PROGRESS, "msctls_progress32", PBS_SMOOTH | WS_CHILD | WS_VISIBLE | WS_BORDER, 21, 58, 275, 11 +END + IDD_NETWORKSETTINGSPAGE DIALOGEX 0, 0, 317, 143 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Expert de instalare ReactOS" @@ -174,6 +184,8 @@ END STRINGTABLE BEGIN + IDS_NETWORKINITTITLE "Network Install" + IDS_NETWORKINITSUBTITLE "Installs reqired networking components." IDS_NETWORKSETTINGSTITLE "Setări de rețea" IDS_NETWORKSETTINGSSUBTITLE "Instalarea software-ului de rețea permite conectarea la alte computere, rețele şi la Internet." IDS_NETWORKCOMPONENTTITLE "Componente de rețea" diff --git a/dll/shellext/netshell/lang/ru-RU.rc b/dll/shellext/netshell/lang/ru-RU.rc index f62468d3a65e4..2b20b11ddee7d 100644 --- a/dll/shellext/netshell/lang/ru-RU.rc +++ b/dll/shellext/netshell/lang/ru-RU.rc @@ -76,6 +76,16 @@ BEGIN PUSHBUTTON "&Закрыть", IDC_CLOSE, 120, 155, 60, 14 END +IDD_NETWORKINITPAGE DIALOGEX 0, 0, 317, 143 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "ReactOS Setup" +FONT 8, "MS Shell Dlg" +BEGIN + ICON IDI_NET_SETUP, IDC_STATIC, 21, 10, 20, 20 + LTEXT "Please wait while ReactOS installs networking components.", IDC_STATIC, 53, 7, 240, 20 + CONTROL "", IDC_INSTALL_PROGRESS, "msctls_progress32", PBS_SMOOTH | WS_CHILD | WS_VISIBLE | WS_BORDER, 21, 58, 275, 11 +END + IDD_NETWORKSETTINGSPAGE DIALOGEX 0, 0, 317, 143 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Установка ReactOS" @@ -165,6 +175,8 @@ END STRINGTABLE BEGIN + IDS_NETWORKINITTITLE "Network Install" + IDS_NETWORKINITSUBTITLE "Installs reqired networking components." IDS_NETWORKSETTINGSTITLE "Настройки сети" IDS_NETWORKSETTINGSSUBTITLE "Устанавливает сетевое программное обеспечение, необходимое для соединени с другими сетями, компьютерами или Интернетом." IDS_NETWORKCOMPONENTTITLE "Сетевые компоненты" diff --git a/dll/shellext/netshell/lang/sk-SK.rc b/dll/shellext/netshell/lang/sk-SK.rc index 21f93eefd9cfb..a7f2671d3d015 100644 --- a/dll/shellext/netshell/lang/sk-SK.rc +++ b/dll/shellext/netshell/lang/sk-SK.rc @@ -78,6 +78,16 @@ BEGIN PUSHBUTTON "&Zavrieť", IDC_CLOSE, 120, 155, 60, 14 END +IDD_NETWORKINITPAGE DIALOGEX 0, 0, 317, 143 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "ReactOS Setup" +FONT 8, "MS Shell Dlg" +BEGIN + ICON IDI_NET_SETUP, IDC_STATIC, 21, 10, 20, 20 + LTEXT "Please wait while ReactOS installs networking components.", IDC_STATIC, 53, 7, 240, 20 + CONTROL "", IDC_INSTALL_PROGRESS, "msctls_progress32", PBS_SMOOTH | WS_CHILD | WS_VISIBLE | WS_BORDER, 21, 58, 275, 11 +END + IDD_NETWORKSETTINGSPAGE DIALOGEX 0, 0, 317, 143 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "ReactOS Setup" @@ -167,6 +177,8 @@ END STRINGTABLE BEGIN + IDS_NETWORKINITTITLE "Network Install" + IDS_NETWORKINITSUBTITLE "Installs reqired networking components." IDS_NETWORKSETTINGSTITLE "Network Settings" IDS_NETWORKSETTINGSSUBTITLE "Installs network software used to connect to other networks, computers, and the Internet." IDS_NETWORKCOMPONENTTITLE "Network Components" diff --git a/dll/shellext/netshell/lang/sq-AL.rc b/dll/shellext/netshell/lang/sq-AL.rc index 28f8071757a97..43a5c07b7983a 100644 --- a/dll/shellext/netshell/lang/sq-AL.rc +++ b/dll/shellext/netshell/lang/sq-AL.rc @@ -78,6 +78,16 @@ BEGIN PUSHBUTTON "&Mbyll", IDC_CLOSE, 125, 165, 62, 14 END +IDD_NETWORKINITPAGE DIALOGEX 0, 0, 317, 143 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "ReactOS Setup" +FONT 8, "MS Shell Dlg" +BEGIN + ICON IDI_NET_SETUP, IDC_STATIC, 21, 10, 20, 20 + LTEXT "Please wait while ReactOS installs networking components.", IDC_STATIC, 53, 7, 240, 20 + CONTROL "", IDC_INSTALL_PROGRESS, "msctls_progress32", PBS_SMOOTH | WS_CHILD | WS_VISIBLE | WS_BORDER, 21, 58, 275, 11 +END + IDD_NETWORKSETTINGSPAGE DIALOGEX 0, 0, 317, 143 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "ReactOS Setup" @@ -167,6 +177,8 @@ END STRINGTABLE BEGIN + IDS_NETWORKINITTITLE "Network Install" + IDS_NETWORKINITSUBTITLE "Installs reqired networking components." IDS_NETWORKSETTINGSTITLE "Network Settings" IDS_NETWORKSETTINGSSUBTITLE "Installs network software used to connect to other networks, computers, and the Internet." IDS_NETWORKCOMPONENTTITLE "Network Components" diff --git a/dll/shellext/netshell/lang/sv-SE.rc b/dll/shellext/netshell/lang/sv-SE.rc index faecdb3a58d1f..62fd00d58c8c1 100644 --- a/dll/shellext/netshell/lang/sv-SE.rc +++ b/dll/shellext/netshell/lang/sv-SE.rc @@ -76,6 +76,16 @@ BEGIN PUSHBUTTON "&Close", IDC_CLOSE, 120, 155, 60, 14 END +IDD_NETWORKINITPAGE DIALOGEX 0, 0, 317, 143 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "ReactOS Setup" +FONT 8, "MS Shell Dlg" +BEGIN + ICON IDI_NET_SETUP, IDC_STATIC, 21, 10, 20, 20 + LTEXT "Please wait while ReactOS installs networking components.", IDC_STATIC, 53, 7, 240, 20 + CONTROL "", IDC_INSTALL_PROGRESS, "msctls_progress32", PBS_SMOOTH | WS_CHILD | WS_VISIBLE | WS_BORDER, 21, 58, 275, 11 +END + IDD_NETWORKSETTINGSPAGE DIALOGEX 0, 0, 317, 143 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "ReactOS Setup" @@ -165,6 +175,8 @@ END STRINGTABLE BEGIN + IDS_NETWORKINITTITLE "Network Install" + IDS_NETWORKINITSUBTITLE "Installs reqired networking components." IDS_NETWORKSETTINGSTITLE "Network Settings" IDS_NETWORKSETTINGSSUBTITLE "Installs network software used to connect to other networks, computers, and the Internet." IDS_NETWORKCOMPONENTTITLE "Network Components" diff --git a/dll/shellext/netshell/lang/tr-TR.rc b/dll/shellext/netshell/lang/tr-TR.rc index b4e553afb6ed0..94003f8cace68 100644 --- a/dll/shellext/netshell/lang/tr-TR.rc +++ b/dll/shellext/netshell/lang/tr-TR.rc @@ -78,6 +78,16 @@ BEGIN PUSHBUTTON "&Kapat", IDC_CLOSE, 120, 155, 60, 14 END +IDD_NETWORKINITPAGE DIALOGEX 0, 0, 317, 143 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "ReactOS Setup" +FONT 8, "MS Shell Dlg" +BEGIN + ICON IDI_NET_SETUP, IDC_STATIC, 21, 10, 20, 20 + LTEXT "Please wait while ReactOS installs networking components.", IDC_STATIC, 53, 7, 240, 20 + CONTROL "", IDC_INSTALL_PROGRESS, "msctls_progress32", PBS_SMOOTH | WS_CHILD | WS_VISIBLE | WS_BORDER, 21, 58, 275, 11 +END + IDD_NETWORKSETTINGSPAGE DIALOGEX 0, 0, 317, 143 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "ReactOS Kur" @@ -167,6 +177,8 @@ END STRINGTABLE BEGIN + IDS_NETWORKINITTITLE "Network Install" + IDS_NETWORKINITSUBTITLE "Installs reqired networking components." IDS_NETWORKSETTINGSTITLE "Ağ Ayarları" IDS_NETWORKSETTINGSSUBTITLE "Başka ağlara, bilgisayarlara ve İnternet'e bağlanmak için kullanılacak ağ yazılımını kurar." IDS_NETWORKCOMPONENTTITLE "Ağ Bileşenleri" diff --git a/dll/shellext/netshell/lang/uk-UA.rc b/dll/shellext/netshell/lang/uk-UA.rc index 73851236c8fa0..c4a785b828e05 100644 --- a/dll/shellext/netshell/lang/uk-UA.rc +++ b/dll/shellext/netshell/lang/uk-UA.rc @@ -82,6 +82,16 @@ BEGIN PUSHBUTTON "&Закрити", IDC_CLOSE, 120, 155, 60, 14 END +IDD_NETWORKINITPAGE DIALOGEX 0, 0, 317, 143 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "ReactOS Setup" +FONT 8, "MS Shell Dlg" +BEGIN + ICON IDI_NET_SETUP, IDC_STATIC, 21, 10, 20, 20 + LTEXT "Please wait while ReactOS installs networking components.", IDC_STATIC, 53, 7, 240, 20 + CONTROL "", IDC_INSTALL_PROGRESS, "msctls_progress32", PBS_SMOOTH | WS_CHILD | WS_VISIBLE | WS_BORDER, 21, 58, 275, 11 +END + IDD_NETWORKSETTINGSPAGE DIALOGEX 0, 0, 317, 143 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Встановлення ReactOS" @@ -171,6 +181,8 @@ END STRINGTABLE BEGIN + IDS_NETWORKINITTITLE "Network Install" + IDS_NETWORKINITSUBTITLE "Installs reqired networking components." IDS_NETWORKSETTINGSTITLE "Налаштування мережі" IDS_NETWORKSETTINGSSUBTITLE "Встановлює мережеве програмне забезпечення, необхідне для з'єднання з іншими мережами, комп'ютерами або Інтернетом." IDS_NETWORKCOMPONENTTITLE "Мережеві компоненти" diff --git a/dll/shellext/netshell/lang/zh-CN.rc b/dll/shellext/netshell/lang/zh-CN.rc index 19ab0466641d9..6df6485fb263d 100644 --- a/dll/shellext/netshell/lang/zh-CN.rc +++ b/dll/shellext/netshell/lang/zh-CN.rc @@ -84,6 +84,16 @@ BEGIN PUSHBUTTON "关闭(&C)", IDC_CLOSE, 120, 155, 60, 14 END +IDD_NETWORKINITPAGE DIALOGEX 0, 0, 317, 143 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "ReactOS Setup" +FONT 8, "MS Shell Dlg" +BEGIN + ICON IDI_NET_SETUP, IDC_STATIC, 21, 10, 20, 20 + LTEXT "Please wait while ReactOS installs networking components.", IDC_STATIC, 53, 7, 240, 20 + CONTROL "", IDC_INSTALL_PROGRESS, "msctls_progress32", PBS_SMOOTH | WS_CHILD | WS_VISIBLE | WS_BORDER, 21, 58, 275, 11 +END + IDD_NETWORKSETTINGSPAGE DIALOGEX 0, 0, 317, 143 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "ReactOS 安装程序" @@ -173,6 +183,8 @@ END STRINGTABLE BEGIN + IDS_NETWORKINITTITLE "Network Install" + IDS_NETWORKINITSUBTITLE "Installs reqired networking components." IDS_NETWORKSETTINGSTITLE "网络设置" IDS_NETWORKSETTINGSSUBTITLE "安装用于连接其他网络、计算机和 Internet 的网络软件。" IDS_NETWORKCOMPONENTTITLE "网络组件" diff --git a/dll/shellext/netshell/lang/zh-HK.rc b/dll/shellext/netshell/lang/zh-HK.rc index f759809083c95..c57c241fba715 100644 --- a/dll/shellext/netshell/lang/zh-HK.rc +++ b/dll/shellext/netshell/lang/zh-HK.rc @@ -84,6 +84,16 @@ BEGIN PUSHBUTTON "關閉(&C)", IDC_CLOSE, 120, 155, 60, 14 END +IDD_NETWORKINITPAGE DIALOGEX 0, 0, 317, 143 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "ReactOS Setup" +FONT 8, "MS Shell Dlg" +BEGIN + ICON IDI_NET_SETUP, IDC_STATIC, 21, 10, 20, 20 + LTEXT "Please wait while ReactOS installs networking components.", IDC_STATIC, 53, 7, 240, 20 + CONTROL "", IDC_INSTALL_PROGRESS, "msctls_progress32", PBS_SMOOTH | WS_CHILD | WS_VISIBLE | WS_BORDER, 21, 58, 275, 11 +END + IDD_NETWORKSETTINGSPAGE DIALOGEX 0, 0, 317, 143 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "ReactOS 安裝程式" @@ -173,6 +183,8 @@ END STRINGTABLE BEGIN + IDS_NETWORKINITTITLE "Network Install" + IDS_NETWORKINITSUBTITLE "Installs reqired networking components." IDS_NETWORKSETTINGSTITLE "網絡設定" IDS_NETWORKSETTINGSSUBTITLE "安裝用於連接到其他網絡、電腦和互聯網的網絡軟件。" IDS_NETWORKCOMPONENTTITLE "網絡元件" diff --git a/dll/shellext/netshell/lang/zh-TW.rc b/dll/shellext/netshell/lang/zh-TW.rc index 225bf0c169115..fc09d3704ee60 100644 --- a/dll/shellext/netshell/lang/zh-TW.rc +++ b/dll/shellext/netshell/lang/zh-TW.rc @@ -84,6 +84,16 @@ BEGIN PUSHBUTTON "關閉(&C)", IDC_CLOSE, 120, 155, 60, 14 END +IDD_NETWORKINITPAGE DIALOGEX 0, 0, 317, 143 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "ReactOS Setup" +FONT 8, "MS Shell Dlg" +BEGIN + ICON IDI_NET_SETUP, IDC_STATIC, 21, 10, 20, 20 + LTEXT "Please wait while ReactOS installs networking components.", IDC_STATIC, 53, 7, 240, 20 + CONTROL "", IDC_INSTALL_PROGRESS, "msctls_progress32", PBS_SMOOTH | WS_CHILD | WS_VISIBLE | WS_BORDER, 21, 58, 275, 11 +END + IDD_NETWORKSETTINGSPAGE DIALOGEX 0, 0, 317, 143 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "ReactOS 安裝程式" @@ -173,6 +183,8 @@ END STRINGTABLE BEGIN + IDS_NETWORKINITTITLE "Network Install" + IDS_NETWORKINITSUBTITLE "Installs reqired networking components." IDS_NETWORKSETTINGSTITLE "網路設定" IDS_NETWORKSETTINGSSUBTITLE "安裝用於連接到其他網路、電腦和網際網路的網路軟體。" IDS_NETWORKCOMPONENTTITLE "網路元件" diff --git a/dll/shellext/netshell/resource.h b/dll/shellext/netshell/resource.h index 1519c473099fb..3d13418807a64 100644 --- a/dll/shellext/netshell/resource.h +++ b/dll/shellext/netshell/resource.h @@ -52,6 +52,9 @@ #define IDC_CLOSE 1300 /* Network setup wizard pages */ +#define IDD_NETWORKINITPAGE 3400 +#define IDC_INSTALL_PROGRESS 3401 + #define IDD_NETWORKSETTINGSPAGE 3500 #define IDC_NETWORK_TYPICAL 3501 #define IDC_NETWORK_CUSTOM 3502 @@ -115,12 +118,14 @@ #define IDS_PROPERTY 10309 #define IDS_VALUE 10310 -#define IDS_NETWORKSETTINGSTITLE 13050 -#define IDS_NETWORKSETTINGSSUBTITLE 13051 -#define IDS_NETWORKCOMPONENTTITLE 13052 -#define IDS_NETWORKCOMPONENTSUBTITLE 13053 -#define IDS_NETWORKDOMAINTITLE 13054 -#define IDS_NETWORKDOMAINSUBTITLE 13055 +#define IDS_NETWORKINITTITLE 13050 +#define IDS_NETWORKINITSUBTITLE 13051 +#define IDS_NETWORKSETTINGSTITLE 13052 +#define IDS_NETWORKSETTINGSSUBTITLE 13053 +#define IDS_NETWORKCOMPONENTTITLE 13054 +#define IDS_NETWORKCOMPONENTSUBTITLE 13055 +#define IDS_NETWORKDOMAINTITLE 13056 +#define IDS_NETWORKDOMAINSUBTITLE 13057 #define IDS_REACTOS_SETUP 13456 #define IDS_WZD_DOMAIN_NAME 13457 diff --git a/dll/shellext/netshell/setup.cpp b/dll/shellext/netshell/setup.cpp index 800cb0b4c1f39..e2027fd52191f 100644 --- a/dll/shellext/netshell/setup.cpp +++ b/dll/shellext/netshell/setup.cpp @@ -15,16 +15,29 @@ typedef struct _NETWORKSETUPDATA { DWORD dwMagic; - BOOL bTypicalNetworkSetup; - - PSETUPDATA pSetupData; -} NETWORKSETUPDATA, *PNETWORKSETUPDATA; + /* settings page data */ + BOOL bInitialSetupRun; + BOOL bTypicalNetworkSetup; + HWND hwndPage; +} NETWORKSETUPDATA, *PNETWORKSETUPDATA; extern "C" { +typedef struct _NETWORKCOMPONENT +{ + LPWSTR pszDeviceId; + const GUID *pClassGuid; +} NETWORKCOMPONENT, PNETWORKCOMPONENT; + +static NETWORKCOMPONENT NetworkComponents[] = { + {(LPWSTR)L"MS_TCPIP", &GUID_DEVCLASS_NETTRANS}, + {(LPWSTR)L"MS_NDISUIO", &GUID_DEVCLASS_NETTRANS} +}; + + static VOID SetBoldText( @@ -38,18 +51,19 @@ SetBoldText( static HRESULT -InstallTypicalNetworkSettings(VOID) +InstallNetworkComponent( + LPWSTR pszComponentName, + const GUID *pClassGuid) { INetCfg *pNetCfg = NULL; INetCfgLock *pNetCfgLock = NULL; - INetCfgComponent *pTcpipComponent = NULL; - INetCfgComponent *pNicComponent = NULL; - IEnumNetCfgComponent *pEnumNicComponents = NULL; - WCHAR *pszNicName; + INetCfgClassSetup *pNetCfgClassSetup = NULL; + INetCfgComponent *pNetCfgComponent = NULL; BOOL fWriteLocked = FALSE, fInitialized = FALSE; + OBO_TOKEN OboToken; HRESULT hr; - TRACE("InstallTypicalNetworkSettings()\n"); + TRACE("InstallNetworkComponent(%S)\n", pszComponentName); hr = CoInitialize(NULL); if (hr != S_OK) @@ -99,61 +113,46 @@ InstallTypicalNetworkSettings(VOID) fInitialized = TRUE; - /* Find the TCP/IP driver */ - hr = pNetCfg->FindComponent(L"ms_tcpip", - &pTcpipComponent); + hr = pNetCfg->QueryNetCfgClass(pClassGuid, + IID_INetCfgClassSetup, + (PVOID*)&pNetCfgClassSetup); + if (hr != S_OK) + { + ERR("QueryNetCfgClass failed\n"); + goto exit; + } + + ZeroMemory(&OboToken, sizeof(OboToken)); + OboToken.Type = OBO_USER; + + hr = pNetCfgClassSetup->Install(pszComponentName, + &OboToken, + 0, //NSF_PRIMARYINSTALL, + 0, + NULL, + NULL, + &pNetCfgComponent); if (hr == S_OK) { - FIXME("Found the TCP/IP driver!\n"); + if (pNetCfgComponent != NULL) + pNetCfgComponent->Release(); } else { - ERR("Initialize failed\n"); + ERR("Install failed\n"); goto exit; } - hr = pNetCfg->EnumComponents(&GUID_DEVCLASS_NET, - &pEnumNicComponents); + hr = pNetCfg->Apply(); if (hr != S_OK) { - ERR("EnumComponents failed\n"); + ERR("Apply failed\n"); goto exit; } - for (;;) - { - hr = pEnumNicComponents->Next(1, - &pNicComponent, - NULL); - if (hr != S_OK) - { - TRACE("EnumNicComponents done!\n"); - break; - } - - hr = pNicComponent->GetDisplayName(&pszNicName); - if (hr == S_OK) - { - FIXME("NIC name: %S\n", pszNicName); - CoTaskMemFree(pszNicName); - } - - // FIXME Bind Tcpip to the NIC - - pNicComponent->Release(); - pNicComponent = NULL; - } - - TRACE("Done!\n"); exit: - if (pNicComponent != NULL) - pNicComponent->Release(); - - if (pEnumNicComponents != NULL) - pEnumNicComponents->Release(); - - if (pTcpipComponent != NULL) - pTcpipComponent->Release(); + if (pNetCfgClassSetup != NULL) + pNetCfgClassSetup->Release(); if (fInitialized) pNetCfg->Uninitialize(); @@ -169,11 +168,118 @@ InstallTypicalNetworkSettings(VOID) CoUninitialize(); - TRACE("InstallTypicalNetworkSettings() done!\n"); + TRACE("InstallNetworkComponent() done!\n"); return hr; } +static +DWORD +WINAPI +InstallThreadProc( + _In_ LPVOID lpParameter) +{ + PNETWORKSETUPDATA pNetworkSetupData = (PNETWORKSETUPDATA)lpParameter; + UINT i, count; + + TRACE("InstallThreadProc()\n"); + + count = sizeof(NetworkComponents) / sizeof(NETWORKCOMPONENT); + TRACE("Network Components: %u\n", count); + + SendDlgItemMessage(pNetworkSetupData->hwndPage, IDC_INSTALL_PROGRESS, PBM_SETRANGE, 0, MAKELPARAM(0, count)); + SendDlgItemMessage(pNetworkSetupData->hwndPage, IDC_INSTALL_PROGRESS, PBM_SETPOS, 0, 0); + + for (i = 0; i < count; i++) + { + TRACE("Install Network Component: %S\n", NetworkComponents[i].pszDeviceId); + InstallNetworkComponent(NetworkComponents[i].pszDeviceId, NetworkComponents[i].pClassGuid); + SendDlgItemMessage(pNetworkSetupData->hwndPage, IDC_INSTALL_PROGRESS, PBM_SETPOS, i, 0); + Sleep(500); + } + + TRACE("Done\n"); + + /* Done */ + pNetworkSetupData->bInitialSetupRun = TRUE; + PostMessage(pNetworkSetupData->hwndPage, WM_USER, 0, 0); + + return 0; +} + +static +INT_PTR +CALLBACK +NetworkInitPageDlgProc( + HWND hwndDlg, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + PNETWORKSETUPDATA pNetworkSetupData; + PSETUPDATA pSetupData; + LPNMHDR lpnm; + + /* Retrieve pointer to the global setup data */ + pNetworkSetupData = (PNETWORKSETUPDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + if ((pNetworkSetupData != NULL) && + (pNetworkSetupData->dwMagic == NETWORK_SETUP_MAGIC)) + pSetupData = pNetworkSetupData->pSetupData; + + switch (uMsg) + { + case WM_INITDIALOG: + /* Save pointer to the global setup data */ + pNetworkSetupData = (PNETWORKSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam; + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)pNetworkSetupData); + pSetupData = pNetworkSetupData->pSetupData; + + if (pSetupData->UnattendSetup) + { + //... + } + break; + + case WM_DESTROY: + /* ATTENTION: Free pNetworkSetupData only in one of the page functions!!! */ + //... + break; + + case WM_NOTIFY: + lpnm = (LPNMHDR)lParam; + + switch (lpnm->code) + { + case PSN_SETACTIVE: + /* Disable the Back and Next buttons */ + PropSheet_SetWizButtons(GetParent(hwndDlg), 0); + TRACE("Starting install thread!\n"); + pNetworkSetupData->hwndPage = hwndDlg; + CreateThread(NULL, 0, InstallThreadProc, (LPVOID)pNetworkSetupData, 0, NULL); + TRACE("Install thread done!\n"); + break; + + case PSN_WIZNEXT: + break; + + case PSN_WIZBACK: + break; + } + break; + + case WM_USER: + TRACE("WM_USER!\n"); + /* Enable the Next button and press it */ + PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT); + PropSheet_PressButton(GetParent(hwndDlg), PSBTN_NEXT); + break; + + default: + break; + } + + return FALSE; +} static INT_PTR @@ -226,8 +332,8 @@ NetworkSettingsPageDlgProc( switch (lpnm->code) { case PSN_SETACTIVE: - /* Enable the Back and Next buttons */ - PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT); + /* Enable the Next button only */ + PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT); if (pSetupData->UnattendSetup) { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_NETWORKCOMPONENTPAGE); @@ -243,8 +349,6 @@ NetworkSettingsPageDlgProc( { pNetworkSetupData->bTypicalNetworkSetup = TRUE; - InstallTypicalNetworkSettings(); - SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_NETWORKDOMAINPAGE); return TRUE; } @@ -459,14 +563,17 @@ NetSetupRequestWizardPages( { PNETWORKSETUPDATA pNetworkSetupData; PROPSHEETPAGE psp = {0}; - DWORD dwPageCount = 3; + DWORD dwPageCount = 4; INT nPage = 0; + TRACE("NetSetupRequestWizardPages(%p %p %p)\n", pPageCount, pPages, pSetupData); + if (pPageCount == NULL) return ERROR_INVALID_PARAMETER; if (pPages == NULL) { + TRACE("Return %lu pages\n", dwPageCount); *pPageCount = dwPageCount; return ERROR_SUCCESS; } @@ -474,7 +581,7 @@ NetSetupRequestWizardPages( if (*pPageCount < dwPageCount) return ERROR_BUFFER_OVERFLOW; - pSetupData->uFirstNetworkWizardPage = IDD_NETWORKSETTINGSPAGE; + pSetupData->uFirstNetworkWizardPage = IDD_NETWORKINITPAGE; pNetworkSetupData = (PNETWORKSETUPDATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(NETWORKSETUPDATA)); if (pNetworkSetupData == NULL) @@ -483,12 +590,18 @@ NetSetupRequestWizardPages( pNetworkSetupData->dwMagic = NETWORK_SETUP_MAGIC; pNetworkSetupData->pSetupData = pSetupData; - /* Create the Network Settings page */ psp.dwSize = sizeof(PROPSHEETPAGE); psp.hInstance = netshell_hInstance; psp.lParam = (LPARAM)pNetworkSetupData; + psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; + psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_NETWORKINITTITLE); + psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_NETWORKINITSUBTITLE); + psp.pfnDlgProc = NetworkInitPageDlgProc; + psp.pszTemplate = MAKEINTRESOURCE(IDD_NETWORKINITPAGE); + pPages[nPage++] = CreatePropertySheetPage(&psp); + psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_NETWORKSETTINGSTITLE); psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_NETWORKSETTINGSSUBTITLE); @@ -512,6 +625,7 @@ NetSetupRequestWizardPages( psp.pszTemplate = MAKEINTRESOURCE(IDD_NETWORKDOMAINPAGE); pPages[nPage++] = CreatePropertySheetPage(&psp); + TRACE("Return %lu pages\n", dwPageCount); *pPageCount = dwPageCount; return ERROR_SUCCESS; diff --git a/dll/shellext/netshell/shfldr_netconnect.cpp b/dll/shellext/netshell/shfldr_netconnect.cpp index 3c14b9672e9c1..30689990fcda9 100644 --- a/dll/shellext/netshell/shfldr_netconnect.cpp +++ b/dll/shellext/netshell/shfldr_netconnect.cpp @@ -641,6 +641,14 @@ HRESULT WINAPI CNetConUiObject::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi) { CmdId = IDS_NET_PROPERTIES; } + else if ((UINT_PTR)lpcmi->lpVerb == FCIDM_SHVIEW_RENAME) // DefView accelerator + { + CmdId = IDS_NET_RENAME; + } + else if ((UINT_PTR)lpcmi->lpVerb == FCIDM_SHVIEW_PROPERTIES) // DefView accelerator + { + CmdId = IDS_NET_PROPERTIES; + } else if (!IS_INTRESOURCE(lpcmi->lpVerb) || LOWORD(lpcmi->lpVerb) > 7) { FIXME("Got invalid command\n"); @@ -653,7 +661,7 @@ HRESULT WINAPI CNetConUiObject::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi) { HRESULT hr; CComPtr psv; - hr = IUnknown_QueryService(m_pUnknown, SID_IFolderView, IID_PPV_ARG(IShellView, &psv)); + hr = IUnknown_QueryService(m_pUnknown, SID_SFolderView, IID_PPV_ARG(IShellView, &psv)); if (SUCCEEDED(hr)) { SVSIF selFlags = SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE | SVSI_FOCUSED | SVSI_SELECT; diff --git a/dll/shellext/sendmail/sendmail.rc b/dll/shellext/sendmail/sendmail.rc index 378b89f444570..c209b8c4f63f7 100644 --- a/dll/shellext/sendmail/sendmail.rc +++ b/dll/shellext/sendmail/sendmail.rc @@ -9,15 +9,15 @@ #include #include "resource.h" +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL + #include "sendmail_version.rc" +IDR_DESKLINK REGISTRY "res/desklink.rgs" + /* UTF-8 */ #pragma code_page(65001) -LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL - -IDR_DESKLINK REGISTRY "res/desklink.rgs" - #ifdef LANGUAGE_DE_DE #include "lang/de-DE.rc" #endif diff --git a/dll/shellext/stobject/lang/cs-CZ.rc b/dll/shellext/stobject/lang/cs-CZ.rc index cc7005990080f..69cdeca8c57c1 100644 --- a/dll/shellext/stobject/lang/cs-CZ.rc +++ b/dll/shellext/stobject/lang/cs-CZ.rc @@ -24,6 +24,7 @@ BEGIN IDS_PWR_AC "On AC power" IDS_PWR_HOURS_REMAINING "zbývá %1!u!:%2!02u! hodin (%3!u!%%)" IDS_PWR_MINUTES_REMAINING "zbývá %1!u! minut (%2!u!%%)" + IDS_PWR_FULLY_CHARGED "Fully charged" //Hotplug related strings IDS_HOTPLUG_REMOVE_1 "Bezpečně odebrat hardware" diff --git a/dll/shellext/stobject/lang/de-DE.rc b/dll/shellext/stobject/lang/de-DE.rc index 0c4cf561ea249..1ca26f38d0f5d 100644 --- a/dll/shellext/stobject/lang/de-DE.rc +++ b/dll/shellext/stobject/lang/de-DE.rc @@ -24,6 +24,7 @@ BEGIN IDS_PWR_AC "Mit Wechselstrom" IDS_PWR_HOURS_REMAINING "%1!u!:%2!02u! Stunden (%3!u!%%) verbleibend" IDS_PWR_MINUTES_REMAINING "%1!u! Min. (%2!u!%%) verbleibend" + IDS_PWR_FULLY_CHARGED "Fully charged" //Hotplug related strings IDS_HOTPLUG_REMOVE_1 "Hardware sicher entfernen" diff --git a/dll/shellext/stobject/lang/en-US.rc b/dll/shellext/stobject/lang/en-US.rc index 8fc4e540827a4..178a82b63d5ca 100644 --- a/dll/shellext/stobject/lang/en-US.rc +++ b/dll/shellext/stobject/lang/en-US.rc @@ -24,6 +24,7 @@ BEGIN IDS_PWR_AC "On AC power" IDS_PWR_HOURS_REMAINING "%1!u!:%2!02u! hours (%3!u!%%) remaining" IDS_PWR_MINUTES_REMAINING "%1!u! min (%2!u!%%) remaining" + IDS_PWR_FULLY_CHARGED "Fully charged" //Hotplug related strings IDS_HOTPLUG_REMOVE_1 "Safely Remove Hardware" diff --git a/dll/shellext/stobject/lang/es-ES.rc b/dll/shellext/stobject/lang/es-ES.rc index 1c50681e70a27..279c739c10b3e 100644 --- a/dll/shellext/stobject/lang/es-ES.rc +++ b/dll/shellext/stobject/lang/es-ES.rc @@ -25,6 +25,7 @@ BEGIN IDS_PWR_AC "En corriente alterna" IDS_PWR_HOURS_REMAINING "Quedan %1!u!:%2!02u! horas (%3!u!%%)" IDS_PWR_MINUTES_REMAINING "Quedan %1!u! minutos (%2!u!%%)" + IDS_PWR_FULLY_CHARGED "Fully charged" //Hotplug related strings IDS_HOTPLUG_REMOVE_1 "Desconectar de forma segura" diff --git a/dll/shellext/stobject/lang/fr-FR.rc b/dll/shellext/stobject/lang/fr-FR.rc index 878655f3a0232..1a43d5833e1bf 100644 --- a/dll/shellext/stobject/lang/fr-FR.rc +++ b/dll/shellext/stobject/lang/fr-FR.rc @@ -24,6 +24,7 @@ BEGIN IDS_PWR_AC "Sur secteur" IDS_PWR_HOURS_REMAINING "%1!u!:%2!02u! heures (%3!u!%%) restantes" IDS_PWR_MINUTES_REMAINING "%1!u! mins (%2!u!%%) restantes" + IDS_PWR_FULLY_CHARGED "Fully charged" //Hotplug related strings IDS_HOTPLUG_REMOVE_1 "Retirer le périphérique en sécurité" diff --git a/dll/shellext/stobject/lang/hi-IN.rc b/dll/shellext/stobject/lang/hi-IN.rc index f205dc413ed0a..db15fe20467dc 100644 --- a/dll/shellext/stobject/lang/hi-IN.rc +++ b/dll/shellext/stobject/lang/hi-IN.rc @@ -31,6 +31,7 @@ BEGIN IDS_PWR_AC "On AC power" IDS_PWR_HOURS_REMAINING "%1!u!:%2!02u! घंटे (%3!u!%%) शेष" IDS_PWR_MINUTES_REMAINING "%1!u! मिनट (%2!u!%%) शेष" + IDS_PWR_FULLY_CHARGED "Fully charged" //Hotplug related strings IDS_HOTPLUG_REMOVE_1 "हार्डवेयर सुरक्षित रूप से निकालें" diff --git a/dll/shellext/stobject/lang/it-IT.rc b/dll/shellext/stobject/lang/it-IT.rc index 7ab7548cd5e0f..a61a5ba93970b 100644 --- a/dll/shellext/stobject/lang/it-IT.rc +++ b/dll/shellext/stobject/lang/it-IT.rc @@ -24,6 +24,7 @@ BEGIN IDS_PWR_AC "Alimentazione da rete AC" IDS_PWR_HOURS_REMAINING "%1!u!:%2!02u! ore (%3!u!%%) rimanenti" IDS_PWR_MINUTES_REMAINING "%1!u! minuti (%2!u!%%) rimanenti" + IDS_PWR_FULLY_CHARGED "Fully charged" //Hotplug related strings IDS_HOTPLUG_REMOVE_1 "Rimozione sicura dell'Hardware" diff --git a/dll/shellext/stobject/lang/ja-JP.rc b/dll/shellext/stobject/lang/ja-JP.rc index c775f35b4255b..c382671f7e457 100644 --- a/dll/shellext/stobject/lang/ja-JP.rc +++ b/dll/shellext/stobject/lang/ja-JP.rc @@ -24,6 +24,7 @@ BEGIN IDS_PWR_AC "交流電源" IDS_PWR_HOURS_REMAINING "残り %1!u!:%2!02u! 時間 (%3!u!%%)" IDS_PWR_MINUTES_REMAINING "残り %1!u! 分 (%2!u!%%)" + IDS_PWR_FULLY_CHARGED "Fully charged" //Hotplug related strings IDS_HOTPLUG_REMOVE_1 "安全なハードウェアの取り外し" diff --git a/dll/shellext/stobject/lang/pl-PL.rc b/dll/shellext/stobject/lang/pl-PL.rc index f5e136cdd2f5f..0d534801fff46 100644 --- a/dll/shellext/stobject/lang/pl-PL.rc +++ b/dll/shellext/stobject/lang/pl-PL.rc @@ -24,6 +24,7 @@ BEGIN IDS_PWR_AC "Podłączony do zasilania" IDS_PWR_HOURS_REMAINING "Pozostało %1!u!:%2!02u! godzin (%3!u!%%)" IDS_PWR_MINUTES_REMAINING "Pozostało %1!u! minut (%2!u!%%)" + IDS_PWR_FULLY_CHARGED "Fully charged" //Hotplug related strings IDS_HOTPLUG_REMOVE_1 "Bezpieczne usuwanie sprzętu" diff --git a/dll/shellext/stobject/lang/pt-PT.rc b/dll/shellext/stobject/lang/pt-PT.rc index ed1b9f1277a80..82010cca9ca63 100644 --- a/dll/shellext/stobject/lang/pt-PT.rc +++ b/dll/shellext/stobject/lang/pt-PT.rc @@ -24,6 +24,7 @@ BEGIN IDS_PWR_AC "Energia AC" IDS_PWR_HOURS_REMAINING "%1!u!:%2!02u! horas (%3!u!%%) remanescente" IDS_PWR_MINUTES_REMAINING "%1!u! min (%2!u!%%) remanescente" + IDS_PWR_FULLY_CHARGED "Fully charged" //Hotplug related strings IDS_HOTPLUG_REMOVE_1 "&Remover Hardware em segurança" diff --git a/dll/shellext/stobject/lang/ro-RO.rc b/dll/shellext/stobject/lang/ro-RO.rc index a98f894e4932d..47fd079cc1441 100644 --- a/dll/shellext/stobject/lang/ro-RO.rc +++ b/dll/shellext/stobject/lang/ro-RO.rc @@ -32,6 +32,7 @@ BEGIN IDS_PWR_AC "Când există sursă CA" IDS_PWR_HOURS_REMAINING "%1!u!:%2!02u! ore (%3!u!%%) rămase" IDS_PWR_MINUTES_REMAINING "%1!u! minute (%2!u!%%) rămase" + IDS_PWR_FULLY_CHARGED "Fully charged" //Hotplug related strings IDS_HOTPLUG_REMOVE_1 "Eliminarea în siguranţă a unui dispozitiv hardware" diff --git a/dll/shellext/stobject/lang/ru-RU.rc b/dll/shellext/stobject/lang/ru-RU.rc index a3bd305690f73..cd18fd1fccdfc 100644 --- a/dll/shellext/stobject/lang/ru-RU.rc +++ b/dll/shellext/stobject/lang/ru-RU.rc @@ -32,6 +32,7 @@ BEGIN IDS_PWR_AC "От сети переменного тока" IDS_PWR_HOURS_REMAINING "%1!u!:%2!02u! часов (%3!u!%%) осталось" IDS_PWR_MINUTES_REMAINING "%1!u! минут (%2!u!%%) осталось" + IDS_PWR_FULLY_CHARGED "Fully charged" //Hotplug related strings IDS_HOTPLUG_REMOVE_1 "Безопасное извлечение устройства" diff --git a/dll/shellext/stobject/lang/tr-TR.rc b/dll/shellext/stobject/lang/tr-TR.rc index 1eb0e1a0167d5..8912a2645c4bc 100644 --- a/dll/shellext/stobject/lang/tr-TR.rc +++ b/dll/shellext/stobject/lang/tr-TR.rc @@ -26,6 +26,7 @@ BEGIN IDS_PWR_AC "Dalgalı akımda (AC)." IDS_PWR_HOURS_REMAINING "%1!u!.%2!02u! saat (%%%3!u!) kalan" IDS_PWR_MINUTES_REMAINING "%1!u! dakika (%%%2!u!) kalan" + IDS_PWR_FULLY_CHARGED "Fully charged" //Hotplug related strings IDS_HOTPLUG_REMOVE_1 "Donanımı Güvenli Kaldır" diff --git a/dll/shellext/stobject/lang/zh-CN.rc b/dll/shellext/stobject/lang/zh-CN.rc index 158ad795c3e09..e57736e01fb58 100644 --- a/dll/shellext/stobject/lang/zh-CN.rc +++ b/dll/shellext/stobject/lang/zh-CN.rc @@ -26,6 +26,7 @@ BEGIN IDS_PWR_AC "交流电源" IDS_PWR_HOURS_REMAINING "剩余 %1!u!:%2!02u!(%3!u!%%)" IDS_PWR_MINUTES_REMAINING "剩余 %1!u! 分钟(%2!u!%%)" + IDS_PWR_FULLY_CHARGED "Fully charged" //Hotplug related strings IDS_HOTPLUG_REMOVE_1 "安全地删除硬件" diff --git a/dll/shellext/stobject/lang/zh-HK.rc b/dll/shellext/stobject/lang/zh-HK.rc index e8b6d0e75f71f..a9100033bf798 100644 --- a/dll/shellext/stobject/lang/zh-HK.rc +++ b/dll/shellext/stobject/lang/zh-HK.rc @@ -32,6 +32,7 @@ BEGIN IDS_PWR_AC "交流電源" IDS_PWR_HOURS_REMAINING "剩餘 %1!u!:%2!02u! 小時(%3!u!%%) " IDS_PWR_MINUTES_REMAINING "剩餘 %1!u! 分鐘(%2!u!%%) " + IDS_PWR_FULLY_CHARGED "Fully charged" //Hotplug related strings IDS_HOTPLUG_REMOVE_1 "安全地移除硬件" diff --git a/dll/shellext/stobject/lang/zh-TW.rc b/dll/shellext/stobject/lang/zh-TW.rc index 9b892f9dc8efb..303469b82005b 100644 --- a/dll/shellext/stobject/lang/zh-TW.rc +++ b/dll/shellext/stobject/lang/zh-TW.rc @@ -32,6 +32,7 @@ BEGIN IDS_PWR_AC "交流電源" IDS_PWR_HOURS_REMAINING "剩餘 %1!u!:%2!02u! 小時(%3!u!%%)" IDS_PWR_MINUTES_REMAINING "剩餘 %1!u! 分鐘(%2!u!%%)" + IDS_PWR_FULLY_CHARGED "Fully charged" //Hotplug related strings IDS_HOTPLUG_REMOVE_1 "安全地移除硬體" diff --git a/dll/shellext/stobject/power.cpp b/dll/shellext/stobject/power.cpp index ecae456b66ec2..4ccae037bddce 100644 --- a/dll/shellext/stobject/power.cpp +++ b/dll/shellext/stobject/power.cpp @@ -29,6 +29,8 @@ typedef struct _PWRSCHEMECONTEXT CString g_strTooltip; static HICON g_hIconBattery = NULL; +#define HOUR_IN_SECS 3600 +#define MIN_IN_SECS 60 /*++ * @name Quantize @@ -78,6 +80,7 @@ static HICON DynamicLoadIcon(HINSTANCE hinst) { SYSTEM_POWER_STATUS PowerStatus; HICON hBatIcon; + UINT uiHour, uiMin; UINT index = -1; if (!GetSystemPowerStatus(&PowerStatus) || @@ -102,12 +105,37 @@ static HICON DynamicLoadIcon(HINSTANCE hinst) hBatIcon = LoadIcon(hinst, MAKEINTRESOURCE(bc_icons[index])); g_strTooltip.Format(IDS_PWR_CHARGING, PowerStatus.BatteryLifePercent); } + else if (PowerStatus.ACLineStatus == AC_LINE_ONLINE && + PowerStatus.BatteryLifePercent == 100) + { + index = Quantize(PowerStatus.BatteryLifePercent); + hBatIcon = LoadIcon(hinst, MAKEINTRESOURCE(bc_icons[index])); + g_strTooltip.LoadStringW(IDS_PWR_FULLY_CHARGED); + } else if (((PowerStatus.BatteryFlag & BATTERY_FLAG_NO_BATTERY) == 0) && ((PowerStatus.BatteryFlag & BATTERY_FLAG_CHARGING) == 0)) { index = Quantize(PowerStatus.BatteryLifePercent); hBatIcon = LoadIcon(hinst, MAKEINTRESOURCE(br_icons[index])); - g_strTooltip.Format(IDS_PWR_PERCENT_REMAINING, PowerStatus.BatteryLifePercent); + + if (PowerStatus.BatteryLifeTime != BATTERY_UNKNOWN_TIME) + { + uiHour = PowerStatus.BatteryLifeTime / HOUR_IN_SECS; + uiMin = (PowerStatus.BatteryLifeTime % HOUR_IN_SECS) / MIN_IN_SECS; + + if (uiHour != 0) + { + g_strTooltip.Format(IDS_PWR_HOURS_REMAINING, uiHour, uiMin, PowerStatus.BatteryLifePercent); + } + else + { + g_strTooltip.Format(IDS_PWR_MINUTES_REMAINING, uiMin, PowerStatus.BatteryLifePercent); + } + } + else + { + g_strTooltip.Format(IDS_PWR_PERCENT_REMAINING, PowerStatus.BatteryLifePercent); + } } else { diff --git a/dll/shellext/stobject/resource.h b/dll/shellext/stobject/resource.h index 66e6aed204f01..e7b609540157b 100644 --- a/dll/shellext/stobject/resource.h +++ b/dll/shellext/stobject/resource.h @@ -11,6 +11,7 @@ #define IDS_PWR_AC 161 #define IDS_PWR_HOURS_REMAINING 162 #define IDS_PWR_MINUTES_REMAINING 163 +#define IDS_PWR_FULLY_CHARGED 164 #define IDI_BATTERY 200 #define IDI_EXTRACT 210 diff --git a/dll/shellext/zipfldr/CZipFolder.hpp b/dll/shellext/zipfldr/CZipFolder.hpp index cb98f68deb52d..8e5f86693d881 100644 --- a/dll/shellext/zipfldr/CZipFolder.hpp +++ b/dll/shellext/zipfldr/CZipFolder.hpp @@ -6,6 +6,17 @@ * Copyright 2023 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) */ +enum FOLDERCOLUMN +{ + COL_NAME = 0, + COL_TYPE, + COL_COMPRSIZE, + COL_PASSWORD, + COL_SIZE, + COL_RATIO, + COL_DATE_MOD, +}; + struct FolderViewColumns { int iResource; @@ -84,8 +95,11 @@ class CZipFolder : } STDMETHODIMP GetDefaultColumn(DWORD dwRes, ULONG *pSort, ULONG *pDisplay) { - UNIMPLEMENTED; - return E_NOTIMPL; + if (pSort) + *pSort = COL_NAME; + if (pDisplay) + *pDisplay = COL_NAME; + return S_OK; } STDMETHODIMP GetDefaultColumnState(UINT iColumn, DWORD *pcsFlags) { @@ -155,9 +169,9 @@ class CZipFolder : bool isDir = zipEntry->ZipType == ZIP_PIDL_DIRECTORY; switch (iColumn) { - case 0: /* Name, ReactOS specific? */ + case COL_NAME: return GetDisplayNameOf(pidl, 0, &psd->str); - case 1: /* Type */ + case COL_TYPE: { SHFILEINFOW shfi; DWORD dwAttributes = isDir ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL; @@ -166,22 +180,22 @@ class CZipFolder : return E_FAIL; return SHSetStrRet(&psd->str, shfi.szTypeName); } - case 2: /* Compressed size */ - case 4: /* Size */ + case COL_COMPRSIZE: + case COL_SIZE: { if (isDir) return SHSetStrRet(&psd->str, L""); - ULONG64 Size = iColumn == 2 ? zipEntry->CompressedSize : zipEntry->UncompressedSize; + ULONG64 Size = iColumn == COL_COMPRSIZE ? zipEntry->CompressedSize : zipEntry->UncompressedSize; if (!StrFormatByteSizeW(Size, Buffer, _countof(Buffer))) return E_FAIL; return SHSetStrRet(&psd->str, Buffer); } - case 3: /* Password */ + case COL_PASSWORD: if (isDir) return SHSetStrRet(&psd->str, L""); return SHSetStrRet(&psd->str, _AtlBaseModule.GetResourceInstance(), zipEntry->Password ? IDS_YES : IDS_NO); - case 5: /* Ratio */ + case COL_RATIO: { if (isDir) return SHSetStrRet(&psd->str, L""); @@ -192,7 +206,7 @@ class CZipFolder : StringCchPrintfW(Buffer, _countof(Buffer), L"%d%%", ratio); return SHSetStrRet(&psd->str, Buffer); } - case 6: /* Date */ + case COL_DATE_MOD: { if (isDir) return SHSetStrRet(&psd->str, L""); @@ -610,8 +624,8 @@ class CZipFolder : // *** IPersist methods *** STDMETHODIMP GetClassID(CLSID *lpClassId) { - DbgPrint("%s\n", __FUNCTION__); - return E_NOTIMPL; + *lpClassId = CLSID_ZipFolderStorageHandler; + return S_OK; } diff --git a/dll/shellext/zipfldr/zipfldr.rc b/dll/shellext/zipfldr/zipfldr.rc index 83d736fefd446..8f6b7b9279c68 100644 --- a/dll/shellext/zipfldr/zipfldr.rc +++ b/dll/shellext/zipfldr/zipfldr.rc @@ -22,7 +22,6 @@ IDR_ZIPFLDR REGISTRY "res/zipfldr.rgs" /* UTF-8 */ #pragma code_page(65001) - #ifdef LANGUAGE_DE_DE #include "lang/de-DE.rc" #endif diff --git a/dll/win32/CMakeLists.txt b/dll/win32/CMakeLists.txt index 78e8df9abc31c..cc7076ee575e8 100644 --- a/dll/win32/CMakeLists.txt +++ b/dll/win32/CMakeLists.txt @@ -74,7 +74,9 @@ add_subdirectory(jsproxy) add_subdirectory(kernel32) add_subdirectory(loadperf) add_subdirectory(lpk) -add_subdirectory(lsasrv) +if(NOT SARCH STREQUAL "wow64") # FIXME + add_subdirectory(lsasrv) +endif() add_subdirectory(lz32) add_subdirectory(mapi32) add_subdirectory(mciavi32) @@ -116,7 +118,9 @@ add_subdirectory(mssign32) add_subdirectory(mssip32) add_subdirectory(mstask) add_subdirectory(msutb) -add_subdirectory(msv1_0) +if(NOT SARCH STREQUAL "wow64") # FIX lsasrv + add_subdirectory(msv1_0) +endif() add_subdirectory(msvcrt) add_subdirectory(msvcrt20) add_subdirectory(msvcrt40) @@ -212,6 +216,7 @@ add_subdirectory(traffic) add_subdirectory(twain_32) add_subdirectory(ubtrfs) add_subdirectory(ucdfs) +add_subdirectory(ucrtbase) add_subdirectory(uext2) add_subdirectory(ufat) add_subdirectory(ufatx) diff --git a/dll/win32/activeds/CMakeLists.txt b/dll/win32/activeds/CMakeLists.txt index 58225f1b3c42b..137f52128750e 100644 --- a/dll/win32/activeds/CMakeLists.txt +++ b/dll/win32/activeds/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(activeds.dll activeds.spec) list(APPEND SOURCE @@ -17,3 +15,4 @@ target_link_libraries(activeds wine) add_importlibs(activeds msvcrt kernel32 ntdll) add_pch(activeds precomp.h SOURCE) add_cd_file(TARGET activeds DESTINATION reactos/system32 FOR all) +set_wine_module(activeds) diff --git a/dll/win32/activeds/activeds_main.c b/dll/win32/activeds/activeds_main.c index 69c5c447dcc8d..5407ea9dc6e6d 100644 --- a/dll/win32/activeds/activeds_main.c +++ b/dll/win32/activeds/activeds_main.c @@ -46,8 +46,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) switch(fdwReason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls( hinstDLL ); break; diff --git a/dll/win32/advpack/CMakeLists.txt b/dll/win32/advpack/CMakeLists.txt index 5df9b29d62bdb..c24f9e0f57bc3 100644 --- a/dll/win32/advpack/CMakeLists.txt +++ b/dll/win32/advpack/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(BEFORE ${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(advpack.dll advpack.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -20,3 +18,4 @@ target_link_libraries(advpack wine) add_importlibs(advpack ole32 setupapi version advapi32 msvcrt kernel32 ntdll) add_pch(advpack precomp.h SOURCE) add_cd_file(TARGET advpack DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(advpack) # CORE-5743: No ARRAY_SIZE macro diff --git a/dll/win32/atl/CMakeLists.txt b/dll/win32/atl/CMakeLists.txt index 475ebab24ffd5..b598826fdbded 100644 --- a/dll/win32/atl/CMakeLists.txt +++ b/dll/win32/atl/CMakeLists.txt @@ -3,10 +3,8 @@ remove_definitions(-D_WIN32_WINNT=0x502) add_definitions(-D_WIN32_WINNT=0x600) add_definitions( - -D__WINESRC__ -D_ATL_VER=_ATL_VER_30) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(atl.dll atl.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -37,3 +35,4 @@ target_link_libraries(atl uuid wine) add_importlibs(atl oleaut32 ole32 user32 gdi32 advapi32 advapi32_vista shlwapi msvcrt kernel32 ntdll) add_pch(atl precomp.h SOURCE) add_cd_file(TARGET atl DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(atl) # CORE-5743: No ARRAY_SIZE macro diff --git a/dll/win32/atl/atl_ax.c b/dll/win32/atl/atl_ax.c index eabf8942a9c2f..59c6bd0c7a5bc 100644 --- a/dll/win32/atl/atl_ax.c +++ b/dll/win32/atl/atl_ax.c @@ -1036,7 +1036,7 @@ static enum content get_content_type(LPCOLESTR name, CLSID *control_id) * AtlAxCreateControlLicEx [atl100.@] * * REMARKS - * See http://www.codeproject.com/com/cwebpage.asp for some background + * See https://www.codeproject.com/KB/com/cwebpage.aspx for some background * */ HRESULT WINAPI AtlAxCreateControlLicEx(LPCOLESTR lpszName, HWND hWnd, diff --git a/dll/win32/atl100/CMakeLists.txt b/dll/win32/atl100/CMakeLists.txt index 73c7843bbe5a5..4a5e0c6a87f0b 100644 --- a/dll/win32/atl100/CMakeLists.txt +++ b/dll/win32/atl100/CMakeLists.txt @@ -3,10 +3,8 @@ remove_definitions(-D_WIN32_WINNT=0x502) add_definitions(-D_WIN32_WINNT=0x600) add_definitions( - -D__WINESRC__ -D_ATL_VER=_ATL_VER_100) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(atl100.dll atl100.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -25,3 +23,4 @@ target_link_libraries(atl100 uuid wine) add_importlibs(atl100 ole32 oleaut32 user32 gdi32 advapi32 advapi32_vista shlwapi msvcrt kernel32 ntdll) add_pch(atl100 precomp.h SOURCE) add_cd_file(TARGET atl100 DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(atl100) # CORE-5743: No ARRAY_SIZE macro diff --git a/dll/win32/atl80/CMakeLists.txt b/dll/win32/atl80/CMakeLists.txt index 50bb95445f8a5..1351ba9ea02a7 100644 --- a/dll/win32/atl80/CMakeLists.txt +++ b/dll/win32/atl80/CMakeLists.txt @@ -3,7 +3,6 @@ remove_definitions(-D_WIN32_WINNT=0x502) add_definitions(-D_WIN32_WINNT=0x600) add_definitions( - -D__WINESRC__ -D_ATL_VER=_ATL_VER_80) spec2def(atl80.dll atl80.spec ADD_IMPORTLIB) @@ -25,3 +24,4 @@ target_link_libraries(atl80 uuid wine) add_importlibs(atl80 oleaut32 user32 ole32 gdi32 advapi32 advapi32_vista shlwapi msvcrt kernel32 ntdll) add_pch(atl80 precomp.h SOURCE) add_cd_file(TARGET atl80 DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(atl80) # CORE-5743: No ARRAY_SIZE macro diff --git a/dll/win32/avifil32/CMakeLists.txt b/dll/win32/avifil32/CMakeLists.txt index 3d7b7799e7f86..2dd220e9c8268 100644 --- a/dll/win32/avifil32/CMakeLists.txt +++ b/dll/win32/avifil32/CMakeLists.txt @@ -2,8 +2,7 @@ remove_definitions(-D_WIN32_WINNT=0x502) add_definitions(-D_WIN32_WINNT=0x600) -add_definitions(-D__WINESRC__ -DENTRY_PREFIX=avifil32_) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) +add_definitions(-DENTRY_PREFIX=avifil32_) spec2def(avifil32.dll avifil32.spec ADD_IMPORTLIB) add_rpcproxy_files(avifil32.idl) @@ -40,3 +39,4 @@ target_link_libraries(avifil32 wine ${PSEH_LIB}) add_importlibs(avifil32 msacm32 msvfw32 winmm ole32 user32 advapi32 rpcrt4 msvcrt kernel32 ntdll) add_pch(avifil32 precomp.h "${PCH_SKIP_SOURCE}") add_cd_file(TARGET avifil32 DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(avifil32) # CORE-5743: No ARRAY_SIZE nor CONST_VTABLE diff --git a/dll/win32/avrt/CMakeLists.txt b/dll/win32/avrt/CMakeLists.txt index 63015040a76fd..a9bbb4890970e 100644 --- a/dll/win32/avrt/CMakeLists.txt +++ b/dll/win32/avrt/CMakeLists.txt @@ -1,6 +1,4 @@ -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) -add_definitions(-D__WINESRC__) spec2def(avrt.dll avrt.spec) list(APPEND SOURCE @@ -13,3 +11,4 @@ set_module_type(avrt win32dll) target_link_libraries(avrt wine) add_importlibs(avrt user32 msvcrt kernel32 ntdll) add_cd_file(TARGET avrt DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(avrt) # CORE-5743: ??? diff --git a/dll/win32/bcrypt/CMakeLists.txt b/dll/win32/bcrypt/CMakeLists.txt index eee62d3a6ab68..53b009163303c 100644 --- a/dll/win32/bcrypt/CMakeLists.txt +++ b/dll/win32/bcrypt/CMakeLists.txt @@ -1,7 +1,5 @@ -add_definitions(-D__WINESRC__) include_directories( - ${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine ${REACTOS_SOURCE_DIR}/sdk/include/reactos/libs/mbedtls) spec2def(bcrypt.dll bcrypt.spec ADD_IMPORTLIB) @@ -16,3 +14,4 @@ set_module_type(bcrypt win32dll) target_link_libraries(bcrypt wine) add_importlibs(bcrypt mbedtls advapi32 msvcrt kernel32 ntdll) add_cd_file(TARGET bcrypt DESTINATION reactos/system32 FOR all) +set_wine_module(bcrypt) diff --git a/dll/win32/browseui/CAutoComplete.cpp b/dll/win32/browseui/CAutoComplete.cpp index e05c31b8b76a3..4f50d094206ee 100644 --- a/dll/win32/browseui/CAutoComplete.cpp +++ b/dll/win32/browseui/CAutoComplete.cpp @@ -86,7 +86,7 @@ static BOOL DoesMatch(const CStringW& strTarget, const CStringW& strText) } // mouse hook procedure to watch the mouse click -// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms644988(v=vs.85) +// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms644988(v=vs.85) static LRESULT CALLBACK MouseProc(INT nCode, WPARAM wParam, LPARAM lParam) { if (s_hMouseHook == NULL) @@ -121,7 +121,7 @@ static LRESULT CALLBACK MouseProc(INT nCode, WPARAM wParam, LPARAM lParam) ////////////////////////////////////////////////////////////////////////////// // sorting algorithm -// http://www.ics.kagoshima-u.ac.jp/~fuchida/edu/algorithm/sort-algorithm/ +// https://web.archive.org/web/20210228194050/http://www.ics.kagoshima-u.ac.jp/~fuchida/edu/algorithm/sort-algorithm/ typedef CSimpleArray list_t; @@ -261,7 +261,7 @@ static inline BOOL IsWordBreak(WCHAR ch) } // This function is an application-defined callback function. -// https://docs.microsoft.com/en-us/windows/win32/api/winuser/nc-winuser-editwordbreakprocw +// https://learn.microsoft.com/en-us/windows/win32/api/winuser/nc-winuser-editwordbreakprocw static INT CALLBACK EditWordBreakProcW(LPWSTR lpch, INT index, INT count, INT code) { @@ -1584,9 +1584,9 @@ LRESULT CAutoComplete::OnNCDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL m_hwndSizeBox.m_pDropDown = NULL; // destroy controls - m_hwndList.DestroyWindow(); - m_hwndScrollBar.DestroyWindow(); - m_hwndSizeBox.DestroyWindow(); + if (m_hwndList) m_hwndList.DestroyWindow(); + if (m_hwndScrollBar) m_hwndScrollBar.DestroyWindow(); + if (m_hwndSizeBox) m_hwndSizeBox.DestroyWindow(); // clean up m_hwndCombo = NULL; diff --git a/dll/win32/browseui/CMakeLists.txt b/dll/win32/browseui/CMakeLists.txt index e420dc6968607..c138e897a508f 100644 --- a/dll/win32/browseui/CMakeLists.txt +++ b/dll/win32/browseui/CMakeLists.txt @@ -48,7 +48,7 @@ add_library(browseui MODULE set_module_type(browseui win32dll UNICODE) target_link_libraries(browseui shellbars shellfind uuid wine cpprt atl_classes) -add_importlibs(browseui uxtheme shlwapi shell32 comctl32 gdi32 ole32 oleaut32 user32 advapi32 mpr msvcrt kernel32 ntdll) +add_importlibs(browseui uxtheme shdocvw shlwapi shell32 comctl32 gdi32 ole32 oleaut32 user32 advapi32 mpr msvcrt kernel32 ntdll) add_pch(browseui precomp.h "${PCH_SKIP_SOURCE}") add_cd_file(TARGET browseui DESTINATION reactos/system32 FOR all) diff --git a/dll/win32/browseui/addressband.cpp b/dll/win32/browseui/addressband.cpp index 25b038655e057..51a80735ec108 100644 --- a/dll/win32/browseui/addressband.cpp +++ b/dll/win32/browseui/addressband.cpp @@ -37,6 +37,9 @@ Implements the navigation band of the cabinet window Implement Save */ +// Unique GUID of the DLL where this CAddressBand is implemented so we can tell if it's really us +static const GUID THISMODULE_GUID = { 0x60ebab6e, 0x2e4b, 0x42f6, { 0x8a,0xbc,0x80,0x73,0x1c,0xa6,0x42,0x02} }; + CAddressBand::CAddressBand() { fEditControl = NULL; @@ -49,6 +52,20 @@ CAddressBand::~CAddressBand() { } +BOOL CAddressBand::ShouldShowGoButton() +{ + return SHRegGetBoolUSValueW(L"Software\\Microsoft\\Internet Explorer\\Main", L"ShowGoButton", FALSE, TRUE); +} + +BOOL CAddressBand::IsGoButtonVisible(IUnknown *pUnkBand) +{ + CComPtr pAB; + IUnknown_QueryService(pUnkBand, THISMODULE_GUID, IID_PPV_ARG(IAddressBand, &pAB)); + if (pAB) + return static_cast(pAB.p)->fGoButtonShown; + return ShouldShowGoButton(); // We don't know, return the global state +} + void CAddressBand::FocusChange(BOOL bFocus) { // m_bFocus = bFocus; @@ -168,7 +185,7 @@ HRESULT STDMETHODCALLTYPE CAddressBand::SetSite(IUnknown *pUnkSite) if (FAILED_UNEXPECTEDLY(hResult)) return hResult; - fGoButtonShown = SHRegGetBoolUSValueW(L"Software\\Microsoft\\Internet Explorer\\Main", L"ShowGoButton", FALSE, TRUE); + fGoButtonShown = ShouldShowGoButton(); if (fGoButtonShown) CreateGoButton(); @@ -365,7 +382,7 @@ HRESULT STDMETHODCALLTYPE CAddressBand::OnWinEvent( case WM_COMMAND: if (wParam == IDM_TOOLBARS_GOBUTTON) { - fGoButtonShown = !SHRegGetBoolUSValueW(L"Software\\Microsoft\\Internet Explorer\\Main", L"ShowGoButton", FALSE, TRUE); + fGoButtonShown = !IsGoButtonVisible(static_cast(this)); SHRegSetUSValueW(L"Software\\Microsoft\\Internet Explorer\\Main", L"ShowGoButton", REG_SZ, fGoButtonShown ? (LPVOID)L"yes" : (LPVOID)L"no", fGoButtonShown ? 8 : 6, SHREGSET_FORCE_HKCU); if (!fGoButton) CreateGoButton(); @@ -421,6 +438,8 @@ HRESULT STDMETHODCALLTYPE CAddressBand::Refresh(long param8) HRESULT STDMETHODCALLTYPE CAddressBand::QueryService(REFGUID guidService, REFIID riid, void **ppvObject) { + if (guidService == THISMODULE_GUID) + return QueryInterface(riid, ppvObject); return E_NOTIMPL; } diff --git a/dll/win32/browseui/addressband.h b/dll/win32/browseui/addressband.h index 1ffa7cea0d801..52986f1d78256 100644 --- a/dll/win32/browseui/addressband.h +++ b/dll/win32/browseui/addressband.h @@ -51,6 +51,9 @@ class CAddressBand : void FocusChange(BOOL bFocus); void CreateGoButton(); public: + static BOOL ShouldShowGoButton(); + static BOOL IsGoButtonVisible(IUnknown *pUnkBand); + // *** IDeskBand methods *** STDMETHOD(GetBandInfo)(DWORD dwBandID, DWORD dwViewMode, DESKBANDINFO *pdbi) override; diff --git a/dll/win32/browseui/addresseditbox.cpp b/dll/win32/browseui/addresseditbox.cpp index 7eb6581f7314e..ef15277a93f24 100644 --- a/dll/win32/browseui/addresseditbox.cpp +++ b/dll/win32/browseui/addresseditbox.cpp @@ -1,28 +1,11 @@ /* - * ReactOS Explorer - * - * Copyright 2009 Andrew Hill - * Copyright 2023 Katayama Hirofumi MZ - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * PROJECT: ReactOS Explorer + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: The combo box of the address band + * COPYRIGHT: Copyright 2009 Andrew Hill + * Copyright 2023-2025 Katayama Hirofumi MZ */ -/* -This class handles the combo box of the address band. -*/ - #include "precomp.h" /* @@ -34,15 +17,12 @@ This class handles the combo box of the address band. CAddressEditBox::CAddressEditBox() : fCombobox(WC_COMBOBOXEXW, this), fEditWindow(WC_EDITW, this), - fSite(NULL), - pidlLastParsed(NULL) + fSite(NULL) { } CAddressEditBox::~CAddressEditBox() { - if (pidlLastParsed) - ILFree(pidlLastParsed); } HRESULT STDMETHODCALLTYPE CAddressEditBox::SetOwner(IUnknown *pOwner) @@ -90,9 +70,11 @@ HRESULT STDMETHODCALLTYPE CAddressEditBox::Init(HWND comboboxEx, HWND editContro return hResult; } -HRESULT STDMETHODCALLTYPE CAddressEditBox::SetCurrentDir(long paramC) +HRESULT STDMETHODCALLTYPE CAddressEditBox::SetCurrentDir(PCWSTR pszPath) { - return E_NOTIMPL; + m_pidlLastParsed.Free(); + m_pidlLastParsed.Attach(ILCreateFromPathW(pszPath)); + return m_pidlLastParsed ? S_OK : E_OUTOFMEMORY; } BOOL CAddressEditBox::GetComboBoxText(CComHeapPtr& pszText) @@ -196,19 +178,20 @@ BOOL CAddressEditBox::ExecuteCommandLine() HRESULT STDMETHODCALLTYPE CAddressEditBox::ParseNow(long paramC) { - ULONG eaten; - ULONG attributes; - HRESULT hr; - HWND topLevelWindow; - PIDLIST_ABSOLUTE pidlCurrent= NULL; - PIDLIST_RELATIVE pidlRelative = NULL; + ULONG eaten, attributes; + CComHeapPtr pidlCurrent; + CComHeapPtr pidlRelative; CComPtr psfCurrent; + HRESULT hr; + + ATLASSERT(!m_pidlLastParsed); CComPtr pbs; hr = IUnknown_QueryService(fSite, SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &pbs)); if (FAILED_UNEXPECTEDLY(hr)) return hr; + HWND topLevelWindow; hr = IUnknown_GetWindow(pbs, &topLevelWindow); if (FAILED_UNEXPECTEDLY(hr)) return hr; @@ -231,7 +214,7 @@ HRESULT STDMETHODCALLTYPE CAddressEditBox::ParseNow(long paramC) CComPtr psfDesktop; hr = SHGetDesktopFolder(&psfDesktop); if (FAILED_UNEXPECTEDLY(hr)) - goto cleanup; + return hr; hr = pbs->GetPidl(&pidlCurrent); if (FAILED_UNEXPECTEDLY(hr)) @@ -244,18 +227,13 @@ HRESULT STDMETHODCALLTYPE CAddressEditBox::ParseNow(long paramC) hr = psfCurrent->ParseDisplayName(topLevelWindow, NULL, address, &eaten, &pidlRelative, &attributes); if (SUCCEEDED(hr)) { - pidlLastParsed = ILCombine(pidlCurrent, pidlRelative); - ILFree(pidlRelative); - goto cleanup; + m_pidlLastParsed.Attach(ILCombine(pidlCurrent, pidlRelative)); + return hr; } parseabsolute: /* We couldn't parse a relative path, attempt to parse an absolute path */ - hr = psfDesktop->ParseDisplayName(topLevelWindow, NULL, address, &eaten, &pidlLastParsed, &attributes); - -cleanup: - if (pidlCurrent) - ILFree(pidlCurrent); + hr = psfDesktop->ParseDisplayName(topLevelWindow, NULL, address, &eaten, &m_pidlLastParsed, &attributes); return hr; } @@ -277,7 +255,7 @@ HRESULT STDMETHODCALLTYPE CAddressEditBox::Execute(long paramC) /* * Parse the path if it wasn't parsed */ - if (!pidlLastParsed) + if (!m_pidlLastParsed) { hr = ParseNow(0); @@ -290,7 +268,7 @@ HRESULT STDMETHODCALLTYPE CAddressEditBox::Execute(long paramC) return ShowFileNotFoundError(hr); } - if (!pidlLastParsed) + if (!m_pidlLastParsed) return E_FAIL; } @@ -315,24 +293,20 @@ HRESULT STDMETHODCALLTYPE CAddressEditBox::Execute(long paramC) if (FAILED(hr)) return hr; - hr = psf->CompareIDs(0, pidl, pidlLastParsed); + hr = psf->CompareIDs(0, pidl, m_pidlLastParsed); SHFree(pidl); - if (hr == 0) + if (hr == S_OK) { - if (pidlLastParsed) - { - ILFree(pidlLastParsed); - pidlLastParsed = NULL; - } + m_pidlLastParsed.Free(); return S_OK; } /* * Attempt to browse to the parsed pidl */ - hr = pisb->BrowseObject(pidlLastParsed, 0); + hr = pisb->BrowseObject(m_pidlLastParsed, 0); if (SUCCEEDED(hr)) return hr; @@ -346,7 +320,7 @@ HRESULT STDMETHODCALLTYPE CAddressEditBox::Execute(long paramC) LPCITEMIDLIST pidlChild; CComPtr sf; - hr = SHBindToParent(pidlLastParsed, IID_PPV_ARG(IShellFolder, &sf), &pidlChild); + hr = SHBindToParent(m_pidlLastParsed, IID_PPV_ARG(IShellFolder, &sf), &pidlChild); if (FAILED(hr)) return hr; @@ -374,10 +348,15 @@ HRESULT STDMETHODCALLTYPE CAddressEditBox::OnWinEvent( { case WM_COMMAND: { - if (HIWORD(wParam) == CBN_SELCHANGE) + if (HIWORD(wParam) == CBN_SELCHANGE && fCombobox == (HWND)lParam) { - UINT selectedIndex = SendMessageW((HWND)lParam, CB_GETCURSEL, 0, 0); - pidlLastParsed = ILClone((LPITEMIDLIST)SendMessageW((HWND)lParam, CB_GETITEMDATA, selectedIndex, 0)); + INT iItem = (INT)fCombobox.SendMessage(CB_GETCURSEL); + PIDLIST_ABSOLUTE pidl = + (PIDLIST_ABSOLUTE)fCombobox.SendMessage(CB_GETITEMDATA, iItem); + m_pidlLastParsed.Free(); + if (pidl) + m_pidlLastParsed.Attach(ILClone(pidl)); + Execute(0); } break; @@ -460,12 +439,7 @@ HRESULT STDMETHODCALLTYPE CAddressEditBox::Invoke(DISPID dispIdMember, REFIID ri { case DISPID_NAVIGATECOMPLETE2: case DISPID_DOCUMENTCOMPLETE: - if (pidlLastParsed) - { - ILFree(pidlLastParsed); - pidlLastParsed = NULL; - } - + m_pidlLastParsed.Free(); RefreshAddress(); break; } diff --git a/dll/win32/browseui/addresseditbox.h b/dll/win32/browseui/addresseditbox.h index cab0e7a5c4c6a..e91f129d0a087 100644 --- a/dll/win32/browseui/addresseditbox.h +++ b/dll/win32/browseui/addresseditbox.h @@ -1,21 +1,9 @@ /* - * ReactOS Explorer - * - * Copyright 2009 Andrew Hill - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * PROJECT: ReactOS Explorer + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: The combo box of the address band + * COPYRIGHT: Copyright 2009 Andrew Hill + * Copyright 2023-2025 Katayama Hirofumi MZ */ #pragma once @@ -37,7 +25,7 @@ class CAddressEditBox : CContainedWindow fEditWindow; DWORD fAdviseCookie; CComPtr fSite; - LPITEMIDLIST pidlLastParsed; + CComHeapPtr m_pidlLastParsed; HWND hComboBoxEx; public: CAddressEditBox(); @@ -62,7 +50,7 @@ class CAddressEditBox : // *** IAddressEditBox methods *** STDMETHOD(Init)(HWND comboboxEx, HWND editControl, long param14, IUnknown *param18) override; - STDMETHOD(SetCurrentDir)(long paramC) override; + STDMETHOD(SetCurrentDir)(PCWSTR pszPath) override; STDMETHOD(ParseNow)(long paramC) override; STDMETHOD(Execute)(long paramC) override; STDMETHOD(Save)(long paramC) override; diff --git a/dll/win32/browseui/basebarsite.cpp b/dll/win32/browseui/basebarsite.cpp index e67e9b7e9bd04..dc40977de4d10 100644 --- a/dll/win32/browseui/basebarsite.cpp +++ b/dll/win32/browseui/basebarsite.cpp @@ -380,15 +380,13 @@ HRESULT STDMETHODCALLTYPE CBaseBarSite::SetDeskBarSite(IUnknown *punkSite) if (punkSite == NULL) { - - TRACE("Destroying site \n"); + TRACE("Destroying site\n"); /* Cleanup our bands */ - while(SUCCEEDED(EnumBands(-1, &dwBandID)) && dwBandID) + for (UINT i = EnumBands(-1, NULL); i;) { - hResult = EnumBands(0, &dwBandID); - if(FAILED_UNEXPECTEDLY(hResult)) - continue; - RemoveBand(dwBandID); + hResult = EnumBands(--i, &dwBandID); + if (!FAILED_UNEXPECTEDLY(hResult)) + RemoveBand(dwBandID); } fDeskBarSite = NULL; } @@ -535,13 +533,11 @@ HRESULT STDMETHODCALLTYPE CBaseBarSite::EnumBands(UINT uBand, DWORD *pdwBandID) { REBARBANDINFO bandInfo; + if (uBand == -1ul) + return (HRESULT)SendMessage(RB_GETBANDCOUNT, 0, 0); if (pdwBandID == NULL) return E_INVALIDARG; - if (uBand == 0xffffffff) - { - *pdwBandID = (DWORD)SendMessage(RB_GETBANDCOUNT, 0, 0); - return S_OK; - } + if (!SUCCEEDED(GetInternalBandInfo(uBand, &bandInfo))) return E_INVALIDARG; *pdwBandID = bandInfo.wID; @@ -565,7 +561,7 @@ HRESULT STDMETHODCALLTYPE CBaseBarSite::RemoveBand(DWORD dwBandID) HRESULT hr; CBarInfo *pInfo; CComPtr pSite; - CComPtr pDockWnd; + CComPtr pDockWnd; DWORD index; // Retrieve the right index of the coolbar knowing the id @@ -580,19 +576,14 @@ HRESULT STDMETHODCALLTYPE CBaseBarSite::RemoveBand(DWORD dwBandID) if (!pInfo) return E_INVALIDARG; - hr = pInfo->fTheBar->QueryInterface(IID_PPV_ARG(IDeskBand, &pDockWnd)); - if (FAILED_UNEXPECTEDLY(hr)) - { - return E_NOINTERFACE; - } - hr = pInfo->fTheBar->QueryInterface(IID_PPV_ARG(IObjectWithSite, &pSite)); - if (FAILED_UNEXPECTEDLY(hr)) - { - return E_NOINTERFACE; - } /* Windows sends a CloseDW before setting site to NULL */ - pDockWnd->CloseDW(0); - pSite->SetSite(NULL); + hr = pInfo->fTheBar->QueryInterface(IID_PPV_ARG(IDockingWindow, &pDockWnd)); + if (SUCCEEDED(hr)) + pDockWnd->CloseDW(0); + + hr = pInfo->fTheBar->QueryInterface(IID_PPV_ARG(IObjectWithSite, &pSite)); + if (SUCCEEDED(hr)) + pSite->SetSite(NULL); // Delete the band from rebar if (!SendMessage(RB_DELETEBAND, index, 0)) @@ -773,15 +764,11 @@ HRESULT CBaseBarSite::FindBandByGUID(REFGUID pGuid, DWORD *pdwBandID) { DWORD numBands; DWORD i; - HRESULT hr; REBARBANDINFO bandInfo; CBarInfo *realInfo; - hr = EnumBands(-1, &numBands); - if (FAILED_UNEXPECTEDLY(hr)) - return E_FAIL; - - for(i = 0; i < numBands; i++) + numBands = EnumBands(-1, NULL); + for (i = 0; i < numBands; i++) { if (FAILED_UNEXPECTEDLY(GetInternalBandInfo(i, &bandInfo))) return E_FAIL; diff --git a/dll/win32/browseui/internettoolbar.cpp b/dll/win32/browseui/internettoolbar.cpp index 2ff27b6a2cb4b..2f6f2145aeeda 100644 --- a/dll/win32/browseui/internettoolbar.cpp +++ b/dll/win32/browseui/internettoolbar.cpp @@ -167,7 +167,7 @@ class CDockSite : STDMETHOD(GetWindow)(HWND *lphwnd) override; STDMETHOD(ContextSensitiveHelp)(BOOL fEnterMode) override; - // *** IDockingWindow methods *** + // *** IDockingWindowSite methods *** STDMETHOD(GetBorderDW)(IUnknown* punkObj, LPRECT prcBorder) override; STDMETHOD(RequestBorderSpaceDW)(IUnknown* punkObj, LPCBORDERWIDTHS pbw) override; STDMETHOD(SetBorderSpaceDW)(IUnknown* punkObj, LPCBORDERWIDTHS pbw) override; @@ -658,6 +658,16 @@ HRESULT CInternetToolbar::EnumBands(UINT Index, int *pBandId, IUnknown **ppUnkBa return *ppUnkBand ? S_OK : S_FALSE; } +HRESULT CInternetToolbar::QIBand(int BandID, REFIID riid, void **ppv) +{ + IUnknown *pUnk; // Not ref. counted + int temp = (UINT) SendMessageW(fMainReBar, RB_IDTOINDEX, BandID, 0); + if (EnumBands(temp, &temp, &pUnk) == S_OK) + return pUnk->QueryInterface(riid, ppv); + *ppv = NULL; + return E_NOINTERFACE; +} + HRESULT CInternetToolbar::ReserveBorderSpace(LONG maxHeight) { CComPtr dockingWindowSite; @@ -1182,7 +1192,7 @@ HRESULT STDMETHODCALLTYPE CInternetToolbar::QueryStatus(const GUID *pguidCmdGrou break; case ITID_MENUBANDSHOWN: // Menubar band visibility prgCmds->cmdf = OLECMDF_SUPPORTED; - if (fMenuBar) + if (IsBandVisible(ITBBID_MENUBAND) == S_OK) prgCmds->cmdf |= OLECMDF_LATCHED; break; case ITID_AUTOHIDEENABLED: // Auto hide enabled/disabled @@ -1223,6 +1233,8 @@ HRESULT STDMETHODCALLTYPE CInternetToolbar::Exec(const GUID *pguidCmdGroup, DWOR return S_OK; case ITID_TOOLBARBANDSHOWN: return ToggleBandVisibility(ITBBID_TOOLSBAND); + case ITID_MENUBANDSHOWN: + return ToggleBandVisibility(ITBBID_MENUBAND); case ITID_ADDRESSBANDSHOWN: return ToggleBandVisibility(ITBBID_ADDRESSBAND); case ITID_LINKSBANDSHOWN: @@ -1746,6 +1758,7 @@ LRESULT CInternetToolbar::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, RBHITTESTINFO hitTestInfo; REBARBANDINFOW rebarBandInfo; int bandID; + CComPtr pAddress; clickLocation.x = LOWORD(lParam); clickLocation.y = HIWORD(lParam); @@ -1780,6 +1793,8 @@ LRESULT CInternetToolbar::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, case ITBBID_ADDRESSBAND: // navigation band DeleteMenu(contextMenu, IDM_TOOLBARS_CUSTOMIZE, MF_BYCOMMAND); DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND); + QIBand(ITBBID_ADDRESSBAND, IID_PPV_ARG(IAddressBand, &pAddress)); + pSettings->fShowGoButton = CAddressBand::IsGoButtonVisible(pAddress); break; default: break; diff --git a/dll/win32/browseui/internettoolbar.h b/dll/win32/browseui/internettoolbar.h index 7e97608c48484..b1e93501e2536 100644 --- a/dll/win32/browseui/internettoolbar.h +++ b/dll/win32/browseui/internettoolbar.h @@ -103,6 +103,7 @@ class CInternetToolbar : virtual ~CInternetToolbar(); void AddDockItem(IUnknown *newItem, int bandID, int flags); HRESULT EnumBands(UINT Index, int *pBandId, IUnknown **ppUnkBand); + HRESULT QIBand(int BandID, REFIID riid, void **ppv); HRESULT ReserveBorderSpace(LONG maxHeight = -1); HRESULT CreateMenuBar(IShellMenu **menuBar); HRESULT CreateToolsBar(IUnknown **toolsBar); diff --git a/dll/win32/browseui/lang/bg-BG.rc b/dll/win32/browseui/lang/bg-BG.rc index 37dbe92508379..58ae078489e4c 100644 --- a/dll/win32/browseui/lang/bg-BG.rc +++ b/dll/win32/browseui/lang/bg-BG.rc @@ -93,7 +93,7 @@ BEGIN MENUITEM "&Close Toolbar", IDM_BAND_CLOSE END -IDM_POPUPMENU MENUEX DISCARDABLE +IDM_POPUPMENU MENUEX BEGIN POPUP "" BEGIN @@ -174,6 +174,7 @@ BEGIN "E", IDM_EXPLORERBAR_SEARCH, VIRTKEY, CONTROL, NOINVERT "I", IDM_EXPLORERBAR_FAVORITES, VIRTKEY, CONTROL, NOINVERT "H", IDM_EXPLORERBAR_HISTORY, VIRTKEY, CONTROL, NOINVERT + VK_F11, FCIDM_BROWSER_TOGGLEFULLSCREEN, VIRTKEY, NOINVERT END /* Strings */ diff --git a/dll/win32/browseui/lang/de-DE.rc b/dll/win32/browseui/lang/de-DE.rc index 825dc9b796299..d7c5fc496616c 100644 --- a/dll/win32/browseui/lang/de-DE.rc +++ b/dll/win32/browseui/lang/de-DE.rc @@ -100,7 +100,7 @@ BEGIN MENUITEM "Symbolleiste schließen", IDM_BAND_CLOSE END -IDM_POPUPMENU MENUEX DISCARDABLE +IDM_POPUPMENU MENUEX BEGIN POPUP "" BEGIN @@ -181,6 +181,7 @@ BEGIN "E", IDM_EXPLORERBAR_SEARCH, VIRTKEY, CONTROL, NOINVERT "I", IDM_EXPLORERBAR_FAVORITES, VIRTKEY, CONTROL, NOINVERT "H", IDM_EXPLORERBAR_HISTORY, VIRTKEY, CONTROL, NOINVERT + VK_F11, FCIDM_BROWSER_TOGGLEFULLSCREEN, VIRTKEY, NOINVERT END /* Strings */ diff --git a/dll/win32/browseui/lang/en-US.rc b/dll/win32/browseui/lang/en-US.rc index 64098afe57619..6b8cb976aac4c 100644 --- a/dll/win32/browseui/lang/en-US.rc +++ b/dll/win32/browseui/lang/en-US.rc @@ -111,7 +111,7 @@ BEGIN MENUITEM "&Close Toolbar", IDM_BAND_CLOSE END -IDM_POPUPMENU MENUEX DISCARDABLE +IDM_POPUPMENU MENUEX BEGIN POPUP "" BEGIN @@ -192,6 +192,7 @@ BEGIN "E", IDM_EXPLORERBAR_SEARCH, VIRTKEY, CONTROL, NOINVERT "I", IDM_EXPLORERBAR_FAVORITES, VIRTKEY, CONTROL, NOINVERT "H", IDM_EXPLORERBAR_HISTORY, VIRTKEY, CONTROL, NOINVERT + VK_F11, FCIDM_BROWSER_TOGGLEFULLSCREEN, VIRTKEY, NOINVERT END /* Strings */ diff --git a/dll/win32/browseui/lang/es-ES.rc b/dll/win32/browseui/lang/es-ES.rc index 567ff90a0bc26..5a8d1fd2c731c 100644 --- a/dll/win32/browseui/lang/es-ES.rc +++ b/dll/win32/browseui/lang/es-ES.rc @@ -102,7 +102,7 @@ BEGIN MENUITEM "&Cerrar barra de herramientas", IDM_BAND_CLOSE END -IDM_POPUPMENU MENUEX DISCARDABLE +IDM_POPUPMENU MENUEX BEGIN POPUP "" BEGIN @@ -183,6 +183,7 @@ BEGIN "Q", IDM_EXPLORERBAR_SEARCH, VIRTKEY, CONTROL, NOINVERT "I", IDM_EXPLORERBAR_FAVORITES, VIRTKEY, CONTROL, NOINVERT "H", IDM_EXPLORERBAR_HISTORY, VIRTKEY, CONTROL, NOINVERT + VK_F11, FCIDM_BROWSER_TOGGLEFULLSCREEN, VIRTKEY, NOINVERT END /* Strings */ diff --git a/dll/win32/browseui/lang/et-EE.rc b/dll/win32/browseui/lang/et-EE.rc index 3cd0d001535e2..77bc0749496dd 100644 --- a/dll/win32/browseui/lang/et-EE.rc +++ b/dll/win32/browseui/lang/et-EE.rc @@ -100,7 +100,7 @@ BEGIN MENUITEM "&Sule tööriistariba", IDM_BAND_CLOSE END -IDM_POPUPMENU MENUEX DISCARDABLE +IDM_POPUPMENU MENUEX BEGIN POPUP "" BEGIN @@ -181,6 +181,7 @@ BEGIN "E", IDM_EXPLORERBAR_SEARCH, VIRTKEY, CONTROL, NOINVERT "I", IDM_EXPLORERBAR_FAVORITES, VIRTKEY, CONTROL, NOINVERT "H", IDM_EXPLORERBAR_HISTORY, VIRTKEY, CONTROL, NOINVERT + VK_F11, FCIDM_BROWSER_TOGGLEFULLSCREEN, VIRTKEY, NOINVERT END /* Strings */ diff --git a/dll/win32/browseui/lang/eu-ES.rc b/dll/win32/browseui/lang/eu-ES.rc index 19aa87830de65..0f9d17ced860b 100644 --- a/dll/win32/browseui/lang/eu-ES.rc +++ b/dll/win32/browseui/lang/eu-ES.rc @@ -100,7 +100,7 @@ BEGIN MENUITEM "&Cerrar barra de herramientas", IDM_BAND_CLOSE END -IDM_POPUPMENU MENUEX DISCARDABLE +IDM_POPUPMENU MENUEX BEGIN POPUP "" BEGIN @@ -181,6 +181,7 @@ BEGIN "Q", IDM_EXPLORERBAR_SEARCH, VIRTKEY, CONTROL, NOINVERT "I", IDM_EXPLORERBAR_FAVORITES, VIRTKEY, CONTROL, NOINVERT "H", IDM_EXPLORERBAR_HISTORY, VIRTKEY, CONTROL, NOINVERT + VK_F11, FCIDM_BROWSER_TOGGLEFULLSCREEN, VIRTKEY, NOINVERT END /* Strings */ diff --git a/dll/win32/browseui/lang/fr-FR.rc b/dll/win32/browseui/lang/fr-FR.rc index 63dd8eb93b721..a522c3ed9bdcc 100644 --- a/dll/win32/browseui/lang/fr-FR.rc +++ b/dll/win32/browseui/lang/fr-FR.rc @@ -111,7 +111,7 @@ BEGIN MENUITEM "&Fermer la barre d'outils", IDM_BAND_CLOSE END -IDM_POPUPMENU MENUEX DISCARDABLE +IDM_POPUPMENU MENUEX BEGIN POPUP "" BEGIN @@ -192,6 +192,7 @@ BEGIN "E", IDM_EXPLORERBAR_SEARCH, VIRTKEY, CONTROL, NOINVERT "I", IDM_EXPLORERBAR_FAVORITES, VIRTKEY, CONTROL, NOINVERT "H", IDM_EXPLORERBAR_HISTORY, VIRTKEY, CONTROL, NOINVERT + VK_F11, FCIDM_BROWSER_TOGGLEFULLSCREEN, VIRTKEY, NOINVERT END /* Strings */ diff --git a/dll/win32/browseui/lang/he-IL.rc b/dll/win32/browseui/lang/he-IL.rc index 30c0a9c8f5cab..94574f8071d3b 100644 --- a/dll/win32/browseui/lang/he-IL.rc +++ b/dll/win32/browseui/lang/he-IL.rc @@ -95,7 +95,7 @@ BEGIN MENUITEM "&Close Toolbar", IDM_BAND_CLOSE END -IDM_POPUPMENU MENUEX DISCARDABLE +IDM_POPUPMENU MENUEX BEGIN POPUP "" BEGIN @@ -176,6 +176,7 @@ BEGIN "E", IDM_EXPLORERBAR_SEARCH, VIRTKEY, CONTROL, NOINVERT "I", IDM_EXPLORERBAR_FAVORITES, VIRTKEY, CONTROL, NOINVERT "H", IDM_EXPLORERBAR_HISTORY, VIRTKEY, CONTROL, NOINVERT + VK_F11, FCIDM_BROWSER_TOGGLEFULLSCREEN, VIRTKEY, NOINVERT END /* Strings */ diff --git a/dll/win32/browseui/lang/hi-IN.rc b/dll/win32/browseui/lang/hi-IN.rc index a26363efd33e4..0a775f41c2652 100644 --- a/dll/win32/browseui/lang/hi-IN.rc +++ b/dll/win32/browseui/lang/hi-IN.rc @@ -93,7 +93,7 @@ BEGIN MENUITEM "टूलबार &बंद करें", IDM_BAND_CLOSE END -IDM_POPUPMENU MENUEX DISCARDABLE +IDM_POPUPMENU MENUEX BEGIN POPUP "" BEGIN @@ -174,6 +174,7 @@ BEGIN "E", IDM_EXPLORERBAR_SEARCH, VIRTKEY, CONTROL, NOINVERT "I", IDM_EXPLORERBAR_FAVORITES, VIRTKEY, CONTROL, NOINVERT "H", IDM_EXPLORERBAR_HISTORY, VIRTKEY, CONTROL, NOINVERT + VK_F11, FCIDM_BROWSER_TOGGLEFULLSCREEN, VIRTKEY, NOINVERT END /* Strings */ diff --git a/dll/win32/browseui/lang/hu-HU.rc b/dll/win32/browseui/lang/hu-HU.rc index 463c43710a6b0..e5106f017a0f8 100644 --- a/dll/win32/browseui/lang/hu-HU.rc +++ b/dll/win32/browseui/lang/hu-HU.rc @@ -111,7 +111,7 @@ BEGIN MENUITEM "Az eszköztár &bezárása", IDM_BAND_CLOSE END -IDM_POPUPMENU MENUEX DISCARDABLE +IDM_POPUPMENU MENUEX BEGIN POPUP "" BEGIN @@ -192,6 +192,7 @@ BEGIN "E", IDM_EXPLORERBAR_SEARCH, VIRTKEY, CONTROL, NOINVERT "I", IDM_EXPLORERBAR_FAVORITES, VIRTKEY, CONTROL, NOINVERT "H", IDM_EXPLORERBAR_HISTORY, VIRTKEY, CONTROL, NOINVERT + VK_F11, FCIDM_BROWSER_TOGGLEFULLSCREEN, VIRTKEY, NOINVERT END /* Strings */ diff --git a/dll/win32/browseui/lang/id-ID.rc b/dll/win32/browseui/lang/id-ID.rc index c1d397fd70f2c..882532025b4af 100644 --- a/dll/win32/browseui/lang/id-ID.rc +++ b/dll/win32/browseui/lang/id-ID.rc @@ -112,7 +112,7 @@ BEGIN MENUITEM "&Tutup Bilah Alat", IDM_BAND_CLOSE END -IDM_POPUPMENU MENUEX DISCARDABLE +IDM_POPUPMENU MENUEX BEGIN POPUP "" BEGIN @@ -193,6 +193,7 @@ BEGIN "E", IDM_EXPLORERBAR_SEARCH, VIRTKEY, CONTROL, NOINVERT "I", IDM_EXPLORERBAR_FAVORITES, VIRTKEY, CONTROL, NOINVERT "H", IDM_EXPLORERBAR_HISTORY, VIRTKEY, CONTROL, NOINVERT + VK_F11, FCIDM_BROWSER_TOGGLEFULLSCREEN, VIRTKEY, NOINVERT END /* Strings */ diff --git a/dll/win32/browseui/lang/it-IT.rc b/dll/win32/browseui/lang/it-IT.rc index dd9c906df1556..a9be40d22bdf5 100644 --- a/dll/win32/browseui/lang/it-IT.rc +++ b/dll/win32/browseui/lang/it-IT.rc @@ -93,7 +93,7 @@ BEGIN MENUITEM "&Chiudi barra degli strumenti", IDM_BAND_CLOSE END -IDM_POPUPMENU MENUEX DISCARDABLE +IDM_POPUPMENU MENUEX BEGIN POPUP "" BEGIN @@ -174,6 +174,7 @@ BEGIN "E", IDM_EXPLORERBAR_SEARCH, VIRTKEY, CONTROL, NOINVERT "I", IDM_EXPLORERBAR_FAVORITES, VIRTKEY, CONTROL, NOINVERT "H", IDM_EXPLORERBAR_HISTORY, VIRTKEY, CONTROL, NOINVERT + VK_F11, FCIDM_BROWSER_TOGGLEFULLSCREEN, VIRTKEY, NOINVERT END /* Strings */ diff --git a/dll/win32/browseui/lang/ja-JP.rc b/dll/win32/browseui/lang/ja-JP.rc index ea4f0583ea719..56f0879114728 100644 --- a/dll/win32/browseui/lang/ja-JP.rc +++ b/dll/win32/browseui/lang/ja-JP.rc @@ -111,7 +111,7 @@ BEGIN MENUITEM "ツールバーを閉じる(&C)", IDM_BAND_CLOSE END -IDM_POPUPMENU MENUEX DISCARDABLE +IDM_POPUPMENU MENUEX BEGIN POPUP "" BEGIN @@ -192,6 +192,7 @@ BEGIN "E", IDM_EXPLORERBAR_SEARCH, VIRTKEY, CONTROL, NOINVERT "I", IDM_EXPLORERBAR_FAVORITES, VIRTKEY, CONTROL, NOINVERT "H", IDM_EXPLORERBAR_HISTORY, VIRTKEY, CONTROL, NOINVERT + VK_F11, FCIDM_BROWSER_TOGGLEFULLSCREEN, VIRTKEY, NOINVERT END /* Strings */ diff --git a/dll/win32/browseui/lang/pl-PL.rc b/dll/win32/browseui/lang/pl-PL.rc index f7526430f5401..db28a5924b512 100644 --- a/dll/win32/browseui/lang/pl-PL.rc +++ b/dll/win32/browseui/lang/pl-PL.rc @@ -102,7 +102,7 @@ BEGIN MENUITEM "&Zamknij pasek narzędzi", IDM_BAND_CLOSE END -IDM_POPUPMENU MENUEX DISCARDABLE +IDM_POPUPMENU MENUEX BEGIN POPUP "" BEGIN @@ -183,6 +183,7 @@ BEGIN "E", IDM_EXPLORERBAR_SEARCH, VIRTKEY, CONTROL, NOINVERT "I", IDM_EXPLORERBAR_FAVORITES, VIRTKEY, CONTROL, NOINVERT "H", IDM_EXPLORERBAR_HISTORY, VIRTKEY, CONTROL, NOINVERT + VK_F11, FCIDM_BROWSER_TOGGLEFULLSCREEN, VIRTKEY, NOINVERT END /* Strings */ diff --git a/dll/win32/browseui/lang/pt-BR.rc b/dll/win32/browseui/lang/pt-BR.rc index 1a49d76377762..0622c1698365b 100644 --- a/dll/win32/browseui/lang/pt-BR.rc +++ b/dll/win32/browseui/lang/pt-BR.rc @@ -95,7 +95,7 @@ BEGIN MENUITEM "&Close Toolbar", IDM_BAND_CLOSE END -IDM_POPUPMENU MENUEX DISCARDABLE +IDM_POPUPMENU MENUEX BEGIN POPUP "" BEGIN @@ -176,6 +176,7 @@ BEGIN "E", IDM_EXPLORERBAR_SEARCH, VIRTKEY, CONTROL, NOINVERT "I", IDM_EXPLORERBAR_FAVORITES, VIRTKEY, CONTROL, NOINVERT "H", IDM_EXPLORERBAR_HISTORY, VIRTKEY, CONTROL, NOINVERT + VK_F11, FCIDM_BROWSER_TOGGLEFULLSCREEN, VIRTKEY, NOINVERT END /* Strings */ diff --git a/dll/win32/browseui/lang/pt-PT.rc b/dll/win32/browseui/lang/pt-PT.rc index 2e1cd2c708ae6..5c3dc63637b6b 100644 --- a/dll/win32/browseui/lang/pt-PT.rc +++ b/dll/win32/browseui/lang/pt-PT.rc @@ -101,7 +101,7 @@ BEGIN MENUITEM "&Fechar barra de ferramentas", IDM_BAND_CLOSE END -IDM_POPUPMENU MENUEX DISCARDABLE +IDM_POPUPMENU MENUEX BEGIN POPUP "" BEGIN @@ -182,6 +182,7 @@ BEGIN "E", IDM_EXPLORERBAR_SEARCH, VIRTKEY, CONTROL, NOINVERT "I", IDM_EXPLORERBAR_FAVORITES, VIRTKEY, CONTROL, NOINVERT "H", IDM_EXPLORERBAR_HISTORY, VIRTKEY, CONTROL, NOINVERT + VK_F11, FCIDM_BROWSER_TOGGLEFULLSCREEN, VIRTKEY, NOINVERT END /* Strings */ diff --git a/dll/win32/browseui/lang/ro-RO.rc b/dll/win32/browseui/lang/ro-RO.rc index 3ce2a8fa36400..8f0422990f260 100644 --- a/dll/win32/browseui/lang/ro-RO.rc +++ b/dll/win32/browseui/lang/ro-RO.rc @@ -101,7 +101,7 @@ BEGIN MENUITEM "As&cunde bara de instrumente", IDM_BAND_CLOSE END -IDM_POPUPMENU MENUEX DISCARDABLE +IDM_POPUPMENU MENUEX BEGIN POPUP "" BEGIN @@ -182,6 +182,7 @@ BEGIN "E", IDM_EXPLORERBAR_SEARCH, VIRTKEY, CONTROL, NOINVERT "I", IDM_EXPLORERBAR_FAVORITES, VIRTKEY, CONTROL, NOINVERT "H", IDM_EXPLORERBAR_HISTORY, VIRTKEY, CONTROL, NOINVERT + VK_F11, FCIDM_BROWSER_TOGGLEFULLSCREEN, VIRTKEY, NOINVERT END /* Strings */ diff --git a/dll/win32/browseui/lang/ru-RU.rc b/dll/win32/browseui/lang/ru-RU.rc index c4eeffd39e968..7e5d840d0989a 100644 --- a/dll/win32/browseui/lang/ru-RU.rc +++ b/dll/win32/browseui/lang/ru-RU.rc @@ -102,7 +102,7 @@ BEGIN MENUITEM "&Закрыть панель инструментов", IDM_BAND_CLOSE END -IDM_POPUPMENU MENUEX DISCARDABLE +IDM_POPUPMENU MENUEX BEGIN POPUP "" BEGIN @@ -183,6 +183,7 @@ BEGIN "E", IDM_EXPLORERBAR_SEARCH, VIRTKEY, CONTROL, NOINVERT "I", IDM_EXPLORERBAR_FAVORITES, VIRTKEY, CONTROL, NOINVERT "H", IDM_EXPLORERBAR_HISTORY, VIRTKEY, CONTROL, NOINVERT + VK_F11, FCIDM_BROWSER_TOGGLEFULLSCREEN, VIRTKEY, NOINVERT END /* Strings */ diff --git a/dll/win32/browseui/lang/sq-AL.rc b/dll/win32/browseui/lang/sq-AL.rc index 0298e25408956..33be1301c492e 100644 --- a/dll/win32/browseui/lang/sq-AL.rc +++ b/dll/win32/browseui/lang/sq-AL.rc @@ -112,7 +112,7 @@ BEGIN MENUITEM "&Close Toolbar", IDM_BAND_CLOSE END -IDM_POPUPMENU MENUEX DISCARDABLE +IDM_POPUPMENU MENUEX BEGIN POPUP "" BEGIN @@ -193,6 +193,7 @@ BEGIN "E", IDM_EXPLORERBAR_SEARCH, VIRTKEY, CONTROL, NOINVERT "I", IDM_EXPLORERBAR_FAVORITES, VIRTKEY, CONTROL, NOINVERT "H", IDM_EXPLORERBAR_HISTORY, VIRTKEY, CONTROL, NOINVERT + VK_F11, FCIDM_BROWSER_TOGGLEFULLSCREEN, VIRTKEY, NOINVERT END /* Strings */ diff --git a/dll/win32/browseui/lang/tr-TR.rc b/dll/win32/browseui/lang/tr-TR.rc index 71039340ddd91..084fb050ee6d9 100644 --- a/dll/win32/browseui/lang/tr-TR.rc +++ b/dll/win32/browseui/lang/tr-TR.rc @@ -95,7 +95,7 @@ BEGIN MENUITEM "&Araç Çubuğunu Kapat", IDM_BAND_CLOSE END -IDM_POPUPMENU MENUEX DISCARDABLE +IDM_POPUPMENU MENUEX BEGIN POPUP "" BEGIN @@ -176,6 +176,7 @@ BEGIN "E", IDM_EXPLORERBAR_SEARCH, VIRTKEY, CONTROL, NOINVERT "I", IDM_EXPLORERBAR_FAVORITES, VIRTKEY, CONTROL, NOINVERT "H", IDM_EXPLORERBAR_HISTORY, VIRTKEY, CONTROL, NOINVERT + VK_F11, FCIDM_BROWSER_TOGGLEFULLSCREEN, VIRTKEY, NOINVERT END /* Strings */ diff --git a/dll/win32/browseui/lang/uk-UA.rc b/dll/win32/browseui/lang/uk-UA.rc index a5dc172200cd8..28ce1e6042bf7 100644 --- a/dll/win32/browseui/lang/uk-UA.rc +++ b/dll/win32/browseui/lang/uk-UA.rc @@ -101,7 +101,7 @@ BEGIN MENUITEM "&Закрити панель", IDM_BAND_CLOSE END -IDM_POPUPMENU MENUEX DISCARDABLE +IDM_POPUPMENU MENUEX BEGIN POPUP "" BEGIN @@ -182,6 +182,7 @@ BEGIN "E", IDM_EXPLORERBAR_SEARCH, VIRTKEY, CONTROL, NOINVERT "I", IDM_EXPLORERBAR_FAVORITES, VIRTKEY, CONTROL, NOINVERT "H", IDM_EXPLORERBAR_HISTORY, VIRTKEY, CONTROL, NOINVERT + VK_F11, FCIDM_BROWSER_TOGGLEFULLSCREEN, VIRTKEY, NOINVERT END /* Strings */ diff --git a/dll/win32/browseui/lang/zh-CN.rc b/dll/win32/browseui/lang/zh-CN.rc index 86c1ca80181ec..4b68197d69e02 100644 --- a/dll/win32/browseui/lang/zh-CN.rc +++ b/dll/win32/browseui/lang/zh-CN.rc @@ -115,7 +115,7 @@ BEGIN MENUITEM "关闭工具栏(&C)", IDM_BAND_CLOSE END -IDM_POPUPMENU MENUEX DISCARDABLE +IDM_POPUPMENU MENUEX BEGIN POPUP "" BEGIN @@ -196,6 +196,7 @@ BEGIN "E", IDM_EXPLORERBAR_SEARCH, VIRTKEY, CONTROL, NOINVERT "I", IDM_EXPLORERBAR_FAVORITES, VIRTKEY, CONTROL, NOINVERT "H", IDM_EXPLORERBAR_HISTORY, VIRTKEY, CONTROL, NOINVERT + VK_F11, FCIDM_BROWSER_TOGGLEFULLSCREEN, VIRTKEY, NOINVERT END /* Strings */ diff --git a/dll/win32/browseui/lang/zh-TW.rc b/dll/win32/browseui/lang/zh-TW.rc index 15665202889c3..65c4e43f7ea25 100644 --- a/dll/win32/browseui/lang/zh-TW.rc +++ b/dll/win32/browseui/lang/zh-TW.rc @@ -117,7 +117,7 @@ BEGIN MENUITEM "選擇工具列(&C)", IDM_BAND_CLOSE END -IDM_POPUPMENU MENUEX DISCARDABLE +IDM_POPUPMENU MENUEX BEGIN POPUP "" BEGIN @@ -198,6 +198,7 @@ BEGIN "E", IDM_EXPLORERBAR_SEARCH, VIRTKEY, CONTROL, NOINVERT "I", IDM_EXPLORERBAR_FAVORITES, VIRTKEY, CONTROL, NOINVERT "H", IDM_EXPLORERBAR_HISTORY, VIRTKEY, CONTROL, NOINVERT + VK_F11, FCIDM_BROWSER_TOGGLEFULLSCREEN, VIRTKEY, NOINVERT END /* Strings */ diff --git a/dll/win32/browseui/resource.h b/dll/win32/browseui/resource.h index d6c1a39b558e4..c0cfae522b06d 100644 --- a/dll/win32/browseui/resource.h +++ b/dll/win32/browseui/resource.h @@ -20,6 +20,7 @@ #pragma once +// FCIDM_BROWSERFIRST..LAST: 0xa000..0xbf00 #define IDM_FILE_CLOSE 0xA021 #define IDM_FILE_EXPLORE_MENU 0xA027 #define IDM_BACKSPACE 0xA032 @@ -63,6 +64,7 @@ #define IDM_BAND_MENU 269 #define IDM_BAND_TITLE 0xA200 #define IDM_BAND_CLOSE 0xA201 +#define FCIDM_BROWSER_TOGGLEFULLSCREEN 0xA21B #define IDM_POPUPMENU 2001 #define IDM_LARGE_ICONS 2002 diff --git a/dll/win32/browseui/settings.cpp b/dll/win32/browseui/settings.cpp index 89fb28f366690..ceb7a4e91f5ee 100644 --- a/dll/win32/browseui/settings.cpp +++ b/dll/win32/browseui/settings.cpp @@ -26,8 +26,7 @@ void ShellSettings::Load() fStatusBarVisible = SHRegGetBoolUSValueW(L"Software\\Microsoft\\Internet Explorer\\Main", L"StatusBarOther", FALSE, TRUE); - fShowGoButton = SHRegGetBoolUSValueW(L"Software\\Microsoft\\Internet Explorer\\Main", - L"ShowGoButton", FALSE, TRUE); + fShowGoButton = CAddressBand::ShouldShowGoButton(); fLocked = SHRegGetBoolUSValueW(L"Software\\Microsoft\\Internet Explorer\\Toolbar", L"Locked", FALSE, TRUE); diff --git a/dll/win32/browseui/shellbrowser.cpp b/dll/win32/browseui/shellbrowser.cpp index eb67209a6745f..de7b48f449213 100644 --- a/dll/win32/browseui/shellbrowser.cpp +++ b/dll/win32/browseui/shellbrowser.cpp @@ -23,6 +23,7 @@ #include #include #include +#include extern HRESULT IUnknown_ShowDW(IUnknown * punk, BOOL fShow); @@ -128,6 +129,19 @@ BOOL createNewStuff = false; // this class is private to browseui.dll and is not registered externally? //DEFINE_GUID(CLSID_ShellFldSetExt, 0x6D5313C0, 0x8C62, 0x11D1, 0xB2, 0xCD, 0x00, 0x60, 0x97, 0xDF, 0x8C, 0x11); +static void GetWindowMonitorInfo(HWND hWnd, MONITORINFO &mi) +{ + HMONITOR hMon = MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST); + mi.cbSize = sizeof(mi); + if (!hMon || !GetMonitorInfo(hMon, &mi)) + { + mi.rcMonitor.left = mi.rcMonitor.top = 0; + mi.rcMonitor.right = GetSystemMetrics(SM_CXFULLSCREEN); + mi.rcMonitor.bottom = GetSystemMetrics(SM_CYFULLSCREEN); + SystemParametersInfo(SPI_GETWORKAREA, 0, &mi.rcWork, 0); + } +} + void DeleteMenuItems(HMENU theMenu, unsigned int firstIDToDelete, unsigned int lastIDToDelete) { MENUITEMINFO menuItemInfo; @@ -195,16 +209,12 @@ class CToolbarProxy : void CToolbarProxy::Initialize(HWND parent, IUnknown *explorerToolbar) { - HWND myWindow; - HRESULT hResult; - - myWindow = SHCreateWorkerWindowW(0, parent, 0, WS_CHILD, NULL, 0); + HWND myWindow = SHCreateWorkerWindowW(0, parent, 0, WS_CHILD, NULL, 0); if (myWindow != NULL) { SubclassWindow(myWindow); SetWindowPos(NULL, -32000, -32000, 0, 0, SWP_NOOWNERZORDER | SWP_NOZORDER); - hResult = explorerToolbar->QueryInterface( - IID_PPV_ARG(IExplorerToolbar, &fExplorerToolbar)); + explorerToolbar->QueryInterface(IID_PPV_ARG(IExplorerToolbar, &fExplorerToolbar)); } } @@ -216,15 +226,12 @@ void CToolbarProxy::Destroy() LRESULT CToolbarProxy::OnAddBitmap(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) { - long int result; - HRESULT hResult; - - result = 0; + long result = 0; if (fExplorerToolbar.p != NULL) { - hResult = fExplorerToolbar->AddBitmap(&CGID_ShellBrowser, 1, (long)wParam, + fExplorerToolbar->AddBitmap(&CGID_ShellBrowser, 1, (long)wParam, reinterpret_cast(lParam), &result, RGB(192, 192, 192)); - hResult = fExplorerToolbar->AddBitmap(&CGID_ShellBrowser, 2, (long)wParam, + fExplorerToolbar->AddBitmap(&CGID_ShellBrowser, 2, (long)wParam, reinterpret_cast(lParam), &result, RGB(192, 192, 192)); } return result; @@ -232,12 +239,9 @@ LRESULT CToolbarProxy::OnAddBitmap(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL LRESULT CToolbarProxy::OnForwardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) { - LRESULT result; - HRESULT hResult; - - result = 0; + LRESULT result = 0; if (fExplorerToolbar.p != NULL) - hResult = fExplorerToolbar->SendToolbarMsg(&CGID_ShellBrowser, uMsg, wParam, lParam, &result); + fExplorerToolbar->SendToolbarMsg(&CGID_ShellBrowser, uMsg, wParam, lParam, &result); return result; } @@ -252,6 +256,8 @@ struct MenuBandInfo { BOOL fVertical; }; +#define BWM_ONDISPLAYCHANGEDELAYED (WM_APP) + class CShellBrowser : public CWindowImpl, public CComObjectRootEx, @@ -271,6 +277,8 @@ class CShellBrowser : public MyIConnectionPointImpl { private: + enum { BSF_ROS_REGBROWSER = 0x04, BSF_ROS_KIOSK = 0x08 }; // Custom values + class barInfo { public: @@ -309,6 +317,10 @@ class CShellBrowser : SBFOLDERSETTINGS m_deffoldersettings; DWORD m_BrowserSvcFlags; bool m_Destroyed; + BYTE m_NonFullscreenState; + + enum { FSF_MBAR = 0x1, FSF_SBAR = 0x2, FSF_RESIZE = 0x4, FSF_MAXIMIZED = 0x8 }; + public: #if 0 ULONG InternalAddRef() @@ -340,13 +352,13 @@ class CShellBrowser : HRESULT ShowBand(const CLSID &classID, bool vertical); HRESULT NavigateToParent(); HRESULT DoFolderOptions(); - HRESULT ApplyBrowserDefaultFolderSettings(IShellView *pvs); + HRESULT ApplyBrowserDefaultFolderSettings(IShellView *pSV); static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); void RepositionBars(); HRESULT BuildExplorerBandMenu(); HRESULT BuildExplorerBandCategory(HMENU hBandsMenu, CATID category, DWORD dwPos, UINT *nbFound); BOOL IsBuiltinBand(CLSID &bandID); - virtual WNDPROC GetWindowProc() + virtual WNDPROC GetWindowProc() override { return WindowProc; } @@ -354,6 +366,7 @@ class CShellBrowser : HRESULT FireNavigateComplete(const wchar_t *newDirectory); HRESULT FireCommandStateChange(bool newState, int commandID); HRESULT FireCommandStateChangeAll(); + HRESULT FireEvent_VBOOL(DISPID dispIdMember, VARIANT_BOOL Param1); HRESULT UpdateForwardBackState(); HRESULT UpdateUpState(); void UpdateGotoMenu(HMENU theMenu); @@ -363,6 +376,8 @@ class CShellBrowser : void UpdateWindowTitle(); void SaveITBarLayout(); + inline HWND GetTopLevelBrowserWindow() { return m_hWnd; } + /* // *** IDockingWindowFrame methods *** STDMETHOD(AddToolbar)(IUnknown *punkSrc, LPCWSTR pwszItem, DWORD dwAddFlags) override; STDMETHOD(RemoveToolbar)(IUnknown *punkSrc, DWORD dwRemoveFlags) override; @@ -614,6 +629,8 @@ class CShellBrowser : LRESULT RelayMsgToShellView(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); LRESULT OnSettingChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); LRESULT OnSysColorChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); + LRESULT OnDisplayChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnDisplayChangeDelayed(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); LRESULT OnClose(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled); LRESULT OnFolderOptions(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled); LRESULT OnMapNetworkDrive(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled); @@ -626,6 +643,7 @@ class CShellBrowser : LRESULT OnGoHome(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled); LRESULT OnAddToFavorites(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled); LRESULT OnOrganizeFavorites(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled); + LRESULT OnToggleFullscreen(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled); LRESULT OnToggleStatusBarVisible(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled); LRESULT OnToggleToolbarLock(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled); LRESULT OnToggleToolbarBandVisible(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled); @@ -666,6 +684,8 @@ class CShellBrowser : MESSAGE_HANDLER(WM_MENUSELECT, RelayMsgToShellView) MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange) MESSAGE_HANDLER(WM_SYSCOLORCHANGE, OnSysColorChange) + MESSAGE_HANDLER(WM_DISPLAYCHANGE, OnDisplayChange) + MESSAGE_HANDLER(BWM_ONDISPLAYCHANGEDELAYED, OnDisplayChangeDelayed) COMMAND_ID_HANDLER(IDM_FILE_CLOSE, OnClose) COMMAND_ID_HANDLER(IDM_TOOLS_FOLDEROPTIONS, OnFolderOptions) COMMAND_ID_HANDLER(IDM_TOOLS_MAPNETWORKDRIVE, OnMapNetworkDrive) @@ -679,6 +699,7 @@ class CShellBrowser : COMMAND_ID_HANDLER(IDM_FAVORITES_ORGANIZEFAVORITES, OnOrganizeFavorites) COMMAND_ID_HANDLER(IDM_VIEW_STATUSBAR, OnToggleStatusBarVisible) COMMAND_ID_HANDLER(IDM_VIEW_REFRESH, OnRefresh) + COMMAND_ID_HANDLER(FCIDM_BROWSER_TOGGLEFULLSCREEN, OnToggleFullscreen) COMMAND_ID_HANDLER(IDM_TOOLBARS_LOCKTOOLBARS, OnToggleToolbarLock) COMMAND_ID_HANDLER(IDM_TOOLBARS_STANDARDBUTTONS, OnToggleToolbarBandVisible) COMMAND_ID_HANDLER(IDM_TOOLBARS_ADDRESSBAR, OnToggleAddressBandVisible) @@ -813,14 +834,14 @@ HRESULT CShellBrowser::Initialize() return S_OK; } -HRESULT CShellBrowser::ApplyBrowserDefaultFolderSettings(IShellView *pvs) +HRESULT CShellBrowser::ApplyBrowserDefaultFolderSettings(IShellView *pSV) { HRESULT hr; - if (pvs) + if (pSV) { m_settings.Save(); SBFOLDERSETTINGS &sbfs = m_deffoldersettings, defsbfs; - if (FAILED(pvs->GetCurrentInfo(&sbfs.FolderSettings))) + if (FAILED(pSV->GetCurrentInfo(&sbfs.FolderSettings))) { defsbfs.InitializeDefaults(); sbfs = defsbfs; @@ -1151,14 +1172,14 @@ HRESULT CShellBrowser::BrowseToPath(IShellFolder *newShellFolder, UpdateWindowTitle(); LPCITEMIDLIST pidlChild; - INT index, indexOpen; HIMAGELIST himlSmall, himlLarge; CComPtr sf; hResult = SHBindToParent(absolutePIDL, IID_PPV_ARG(IShellFolder, &sf), &pidlChild); if (SUCCEEDED(hResult)) { - index = SHMapPIDLToSystemImageListIndex(sf, pidlChild, &indexOpen); + INT indexOpen; + SHMapPIDLToSystemImageListIndex(sf, pidlChild, &indexOpen); Shell_GetImageLists(&himlLarge, &himlSmall); @@ -1196,11 +1217,8 @@ HRESULT CShellBrowser::GetMenuBand(REFIID riid, void **shellMenu) if (FAILED_UNEXPECTEDLY(hResult)) return hResult; - hResult = bandSite->QueryBand(1, &deskBand, NULL, NULL, 0); - if (FAILED_UNEXPECTEDLY(hResult)) - return hResult; - - return deskBand->QueryInterface(riid, shellMenu); + hResult = bandSite->QueryBand(ITBBID_MENUBAND, &deskBand, NULL, NULL, 0); + return FAILED(hResult) ? hResult : deskBand->QueryInterface(riid, shellMenu); // It is expected that this might fail during WM_DESTROY } HRESULT CShellBrowser::GetBaseBar(bool vertical, REFIID riid, void **theBaseBar) @@ -1276,11 +1294,8 @@ BOOL CShellBrowser::IsBandLoaded(const CLSID clsidBand, bool vertical, DWORD *pd if (FAILED_UNEXPECTEDLY(hResult)) return FALSE; - hResult = bandSite->EnumBands(-1, &numBands); - if (FAILED_UNEXPECTEDLY(hResult)) - return FALSE; - - for(i = 0; i < numBands; i++) + numBands = bandSite->EnumBands(-1, NULL); + for (i = 0; i < numBands; i++) { CComPtr bandPersist; @@ -1504,7 +1519,6 @@ LRESULT CALLBACK CShellBrowser::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, wParam = msg.wParam; lParam = msg.lParam; } - menuBand.Release(); } handled = pThis->ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult, 0); @@ -1625,9 +1639,9 @@ HRESULT CShellBrowser::FireEvent(DISPID dispIdMember, int argCount, VARIANT *arg if (*pp != NULL) { CComPtr theDispatch; - hResult = (*pp)->QueryInterface(IID_PPV_ARG(IDispatch, &theDispatch)); - hResult = theDispatch->Invoke(dispIdMember, GUID_NULL, 0, DISPATCH_METHOD, ¶ms, NULL, NULL, NULL); + if (SUCCEEDED(hResult)) + hResult = theDispatch->Invoke(dispIdMember, GUID_NULL, 0, DISPATCH_METHOD, ¶ms, NULL, NULL, NULL); } pp++; } @@ -1637,9 +1651,9 @@ HRESULT CShellBrowser::FireEvent(DISPID dispIdMember, int argCount, VARIANT *arg if (*pp != NULL) { CComPtr theDispatch; - hResult = (*pp)->QueryInterface(IID_PPV_ARG(IDispatch, &theDispatch)); - hResult = theDispatch->Invoke(dispIdMember, GUID_NULL, 0, DISPATCH_METHOD, ¶ms, NULL, NULL, NULL); + if (SUCCEEDED(hResult)) + hResult = theDispatch->Invoke(dispIdMember, GUID_NULL, 0, DISPATCH_METHOD, ¶ms, NULL, NULL, NULL); } pp++; } @@ -1682,6 +1696,14 @@ HRESULT CShellBrowser::FireCommandStateChangeAll() return FireCommandStateChange(false, -1); } +HRESULT CShellBrowser::FireEvent_VBOOL(DISPID dispIdMember, VARIANT_BOOL Param1) +{ + VARIANT vArgs[1]; + V_VT(&vArgs[0]) = VT_BOOL; + V_BOOL(&vArgs[0]) = Param1 ? VARIANT_TRUE : VARIANT_FALSE; + return FireEvent(dispIdMember, 1, vArgs); +} + HRESULT CShellBrowser::UpdateForwardBackState() { CComPtr travelLog; @@ -1714,13 +1736,8 @@ HRESULT CShellBrowser::UpdateForwardBackState() HRESULT CShellBrowser::UpdateUpState() { - bool canGoUp; - HRESULT hResult; - - canGoUp = true; - if (_ILIsDesktop(fCurrentDirectoryPIDL)) - canGoUp = false; - hResult = FireCommandStateChange(canGoUp, 3); + bool canGoUp = !_ILIsDesktop(fCurrentDirectoryPIDL); + FireCommandStateChange(canGoUp, 3); return S_OK; } @@ -2101,7 +2118,7 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::QueryStatus(const GUID *pguidCmdGroup, { case IDM_GOTO_UPONELEVEL: prgCmds->cmdf = OLECMDF_SUPPORTED; - if (fCurrentDirectoryPIDL->mkid.cb != 0) + if (!_ILIsDesktop(fCurrentDirectoryPIDL)) prgCmds->cmdf |= OLECMDF_ENABLED; break; } @@ -2115,8 +2132,6 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::QueryStatus(const GUID *pguidCmdGroup, HRESULT STDMETHODCALLTYPE CShellBrowser::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut) { - HRESULT hResult; - if (!pguidCmdGroup) { TRACE("Unhandled null CGID %d %d %p %p\n", nCmdID, nCmdexecopt, pvaIn, pvaOut); @@ -2138,13 +2153,13 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::Exec(const GUID *pguidCmdGroup, DWORD n if (IsEqualCLSID(*pclsid, fCurrentVertBar)) { - hResult = IUnknown_ShowDW(fClientBars[BIVerticalBaseBar].clientBar.p, FALSE); + IUnknown_ShowDW(fClientBars[BIVerticalBaseBar].clientBar.p, FALSE); memset(&fCurrentVertBar, 0, sizeof(fCurrentVertBar)); FireCommandStateChangeAll(); } else { - hResult = ShowBand(*pclsid, true); + ShowBand(*pclsid, true); } return S_OK; case 0x22: @@ -2618,6 +2633,9 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::ShowControlWindow(UINT id, BOOL fShow) return S_OK; case FCW_TREE: return Exec(&CGID_Explorer, SBCMDID_EXPLORERBARFOLDERS, 0, NULL, NULL); + case FCW_MENU: + return IUnknown_Exec(fClientBars[BIInternetToolbar].clientBar, + CGID_PrivCITCommands, ITID_MENUBANDSHOWN, 0, NULL, NULL); case FCW_ADDRESSBAR: return IUnknown_Exec(fClientBars[BIInternetToolbar].clientBar, CGID_PrivCITCommands, ITID_ADDRESSBANDSHOWN, 0, NULL, NULL); @@ -2641,9 +2659,11 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::IsControlWindowShown(UINT id, BOOL *pfS shown = cmd.cmdf & OLECMDF_LATCHED; break; } + case FCW_MENU: + shown = (hr = IsInternetToolbarBandShown(ITID_MENUBANDSHOWN)) == S_OK; + break; case FCW_ADDRESSBAR: - hr = IsInternetToolbarBandShown(ITID_ADDRESSBANDSHOWN); - shown = hr == S_OK; + shown = (hr = IsInternetToolbarBandShown(ITID_ADDRESSBANDSHOWN)) == S_OK; break; default: hr = E_NOTIMPL; @@ -2899,7 +2919,7 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::InitializeTravelLog(ITravelLog *ptl, DW HRESULT STDMETHODCALLTYPE CShellBrowser::SetTopBrowser() { - m_BrowserSvcFlags |= BSF_TOPBROWSER; + SetFlags(BSF_TOPBROWSER, BSF_TOPBROWSER); return S_OK; } @@ -3143,19 +3163,41 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::v_CheckZoneCrossing(LPCITEMIDLIST pidl) HRESULT STDMETHODCALLTYPE CShellBrowser::GoBack() { CComPtr travelLog; - HRESULT hResult = GetTravelLog(&travelLog); + CComPtr unusedEntry; + HRESULT hResult; + + hResult = GetTravelLog(&travelLog); if (FAILED_UNEXPECTEDLY(hResult)) return hResult; - return travelLog->Travel(static_cast(this), TLOG_BACK); + + hResult = travelLog->GetTravelEntry(static_cast(this), TLOG_BACK, &unusedEntry); + if (SUCCEEDED(hResult)) + { + unusedEntry.Release(); + return travelLog->Travel(static_cast(this), TLOG_BACK); + } + + return hResult; } HRESULT STDMETHODCALLTYPE CShellBrowser::GoForward() { CComPtr travelLog; - HRESULT hResult = GetTravelLog(&travelLog); + CComPtr unusedEntry; + HRESULT hResult; + + hResult = GetTravelLog(&travelLog); if (FAILED_UNEXPECTEDLY(hResult)) return hResult; - return travelLog->Travel(static_cast(this), TLOG_FORE); + + hResult = travelLog->GetTravelEntry(static_cast(this), TLOG_FORE, &unusedEntry); + if (SUCCEEDED(hResult)) + { + unusedEntry.Release(); + return travelLog->Travel(static_cast(this), TLOG_FORE); + } + + return hResult; } HRESULT STDMETHODCALLTYPE CShellBrowser::GoHome() @@ -3300,7 +3342,8 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::get_Busy(VARIANT_BOOL *pBool) HRESULT STDMETHODCALLTYPE CShellBrowser::Quit() { - return E_NOTIMPL; + ::PostMessageW(GetTopLevelBrowserWindow(), WM_CLOSE, 0, 0); + return S_OK; } HRESULT STDMETHODCALLTYPE CShellBrowser::ClientToWindow(int *pcx, int *pcy) @@ -3325,7 +3368,8 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::get_Name(BSTR *Name) HRESULT STDMETHODCALLTYPE CShellBrowser::get_HWND(SHANDLE_PTR *pHWND) { - return E_NOTIMPL; + *pHWND = HandleToLong(GetTopLevelBrowserWindow()); + return *pHWND ? S_OK : E_UNEXPECTED; } HRESULT STDMETHODCALLTYPE CShellBrowser::get_FullName(BSTR *FullName) @@ -3340,22 +3384,35 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::get_Path(BSTR *Path) HRESULT STDMETHODCALLTYPE CShellBrowser::get_Visible(VARIANT_BOOL *pBool) { - return E_NOTIMPL; + HWND hWnd = GetTopLevelBrowserWindow(); + *pBool = hWnd && ::IsWindowVisible(hWnd) ? VARIANT_TRUE : VARIANT_FALSE; + return S_OK; } HRESULT STDMETHODCALLTYPE CShellBrowser::put_Visible(VARIANT_BOOL Value) { - return E_NOTIMPL; + if (HWND hWnd = GetTopLevelBrowserWindow()) + { + ::ShowWindow(hWnd, Value? SW_SHOW : SW_HIDE); + if (Value) + ::SetForegroundWindow(hWnd); + FireEvent_VBOOL(DISPID_ONVISIBLE, Value); + } + return S_OK; } HRESULT STDMETHODCALLTYPE CShellBrowser::get_StatusBar(VARIANT_BOOL *pBool) { - return E_NOTIMPL; + *pBool = IsControlWindowShown(FCW_STATUS, NULL) == S_OK ? VARIANT_TRUE : VARIANT_FALSE; + return S_OK; } HRESULT STDMETHODCALLTYPE CShellBrowser::put_StatusBar(VARIANT_BOOL Value) { - return E_NOTIMPL; + SetFlags(BSF_UISETBYAUTOMATION, BSF_UISETBYAUTOMATION); + HRESULT hr = ShowControlWindow(FCW_STATUS, Value != VARIANT_FALSE); + FireEvent_VBOOL(DISPID_ONSTATUSBAR, Value); + return hr; } HRESULT STDMETHODCALLTYPE CShellBrowser::get_StatusText(BSTR *StatusText) @@ -3365,37 +3422,54 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::get_StatusText(BSTR *StatusText) HRESULT STDMETHODCALLTYPE CShellBrowser::put_StatusText(BSTR StatusText) { - return E_NOTIMPL; + SendControlMsg(FCW_STATUS, SB_SETTEXTW, 0, (LPARAM)StatusText, NULL); + return S_OK; } HRESULT STDMETHODCALLTYPE CShellBrowser::get_ToolBar(int *Value) { - return E_NOTIMPL; + *Value = IsControlWindowShown(FCW_INTERNETBAR, NULL) == S_OK; + if (!*Value && IsControlWindowShown(FCW_TOOLBAR, NULL) == S_OK) + *Value = FCW_TOOLBAR; + return S_OK; } HRESULT STDMETHODCALLTYPE CShellBrowser::put_ToolBar(int Value) { - return E_NOTIMPL; + SetFlags(BSF_UISETBYAUTOMATION, BSF_UISETBYAUTOMATION); + ShowControlWindow(FCW_INTERNETBAR, Value != VARIANT_FALSE && Value != FCW_TOOLBAR); + ShowControlWindow(FCW_TOOLBAR, Value == FCW_TOOLBAR); + FireEvent_VBOOL(DISPID_ONTOOLBAR, Value); + return S_OK; } HRESULT STDMETHODCALLTYPE CShellBrowser::get_MenuBar(VARIANT_BOOL *Value) { - return E_NOTIMPL; + *Value = IsControlWindowShown(FCW_MENU, NULL) == S_OK ? VARIANT_TRUE : VARIANT_FALSE; + return S_OK; } HRESULT STDMETHODCALLTYPE CShellBrowser::put_MenuBar(VARIANT_BOOL Value) { - return E_NOTIMPL; + SetFlags(BSF_UISETBYAUTOMATION, BSF_UISETBYAUTOMATION); + HRESULT hr = ShowControlWindow(FCW_MENU, Value != VARIANT_FALSE); + FireEvent_VBOOL(DISPID_ONMENUBAR, Value); + return hr; } HRESULT STDMETHODCALLTYPE CShellBrowser::get_FullScreen(VARIANT_BOOL *pbFullScreen) { - return E_NOTIMPL; + *pbFullScreen = (m_BrowserSvcFlags & BSF_ROS_KIOSK) ? VARIANT_TRUE : VARIANT_FALSE; + return S_OK; } HRESULT STDMETHODCALLTYPE CShellBrowser::put_FullScreen(VARIANT_BOOL bFullScreen) { - return E_NOTIMPL; + SetFlags(BSF_UISETBYAUTOMATION, BSF_UISETBYAUTOMATION); + SetFlags(bFullScreen ? BSF_ROS_KIOSK : 0, BSF_ROS_KIOSK); + put_TheaterMode(bFullScreen); + FireEvent_VBOOL(DISPID_ONFULLSCREEN, bFullScreen); + return S_OK; } HRESULT STDMETHODCALLTYPE CShellBrowser::Navigate2(VARIANT *URL, VARIANT *Flags, @@ -3425,13 +3499,21 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::Navigate2(VARIANT *URL, VARIANT *Flags, HRESULT STDMETHODCALLTYPE CShellBrowser::QueryStatusWB(OLECMDID cmdID, OLECMDF *pcmdf) { - return E_NOTIMPL; + OLECMD cmd = { (ULONG)cmdID, (DWORD)(*pcmdf) }; + HRESULT hr = QueryStatus(NULL, 1, &cmd, NULL); + *pcmdf = (OLECMDF)cmd.cmdf; + return hr; } HRESULT STDMETHODCALLTYPE CShellBrowser::ExecWB(OLECMDID cmdID, OLECMDEXECOPT cmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut) { - return E_NOTIMPL; + CComPtr pOCT; + IShellView *pSV = fCurrentShellView; + HRESULT hr = pSV ? pSV->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &pOCT)) : E_FAIL; + if (SUCCEEDED(hr)) + hr = pOCT->Exec(NULL, cmdID, cmdexecopt, pvaIn, pvaOut); + return hr; } HRESULT STDMETHODCALLTYPE CShellBrowser::ShowBrowserBar(VARIANT *pvaClsid, VARIANT *pvarShow, VARIANT *pvarSize) @@ -3475,52 +3557,67 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::put_Silent(VARIANT_BOOL bSilent) HRESULT STDMETHODCALLTYPE CShellBrowser::get_RegisterAsBrowser(VARIANT_BOOL *pbRegister) { - return E_NOTIMPL; + *pbRegister = (m_BrowserSvcFlags & BSF_ROS_REGBROWSER) ? VARIANT_TRUE : VARIANT_FALSE; + return S_OK; } HRESULT STDMETHODCALLTYPE CShellBrowser::put_RegisterAsBrowser(VARIANT_BOOL bRegister) { - return E_NOTIMPL; + if (!bRegister) + return E_UNEXPECTED; + SetFlags(BSF_ROS_REGBROWSER, BSF_ROS_REGBROWSER); + return RegisterWindow(TRUE, SWC_3RDPARTY); } HRESULT STDMETHODCALLTYPE CShellBrowser::get_RegisterAsDropTarget(VARIANT_BOOL *pbRegister) { - return E_NOTIMPL; + *pbRegister = (m_BrowserSvcFlags & BSF_REGISTERASDROPTARGET) ? VARIANT_TRUE : VARIANT_FALSE; + return S_OK; } HRESULT STDMETHODCALLTYPE CShellBrowser::put_RegisterAsDropTarget(VARIANT_BOOL bRegister) { - return E_NOTIMPL; + SetFlags(bRegister ? BSF_REGISTERASDROPTARGET : 0, BSF_REGISTERASDROPTARGET); + return S_OK; } HRESULT STDMETHODCALLTYPE CShellBrowser::get_TheaterMode(VARIANT_BOOL *pbRegister) { - return E_NOTIMPL; + *pbRegister = (m_BrowserSvcFlags & BSF_THEATERMODE) ? VARIANT_TRUE : VARIANT_FALSE; + return S_OK; } HRESULT STDMETHODCALLTYPE CShellBrowser::put_TheaterMode(VARIANT_BOOL bRegister) { - return E_NOTIMPL; + BOOL handled; + OnToggleFullscreen(bRegister, 0, NULL, handled); + return S_OK; } HRESULT STDMETHODCALLTYPE CShellBrowser::get_AddressBar(VARIANT_BOOL *Value) { - return E_NOTIMPL; + *Value = IsControlWindowShown(FCW_ADDRESSBAR, NULL) == S_OK ? VARIANT_TRUE : VARIANT_FALSE; + return S_OK; } HRESULT STDMETHODCALLTYPE CShellBrowser::put_AddressBar(VARIANT_BOOL Value) { - return E_NOTIMPL; + SetFlags(BSF_UISETBYAUTOMATION, BSF_UISETBYAUTOMATION); + HRESULT hr = ShowControlWindow(FCW_ADDRESSBAR, Value != VARIANT_FALSE); + FireEvent_VBOOL(DISPID_ONADDRESSBAR, Value); + return hr; } HRESULT STDMETHODCALLTYPE CShellBrowser::get_Resizable(VARIANT_BOOL *Value) { + *Value = (m_BrowserSvcFlags & BSF_RESIZABLE) ? VARIANT_TRUE : VARIANT_FALSE; return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE CShellBrowser::put_Resizable(VARIANT_BOOL Value) { - return E_NOTIMPL; + SetFlags(Value ? (BSF_RESIZABLE | BSF_CANMAXIMIZE) : 0, (BSF_RESIZABLE | BSF_CANMAXIMIZE)); + return S_OK; } HRESULT STDMETHODCALLTYPE CShellBrowser::FindWindowByIndex(DWORD dwID, IUnknown **ppunk) @@ -3650,6 +3747,13 @@ LRESULT CShellBrowser::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &b LRESULT CShellBrowser::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) { HRESULT hr; + if (m_BrowserSvcFlags & (BSF_THEATERMODE | BSF_ROS_KIOSK)) + { + if (m_NonFullscreenState & FSF_MBAR) + put_MenuBar(VARIANT_TRUE); + if (m_NonFullscreenState & FSF_SBAR) + put_StatusBar(VARIANT_TRUE); + } SaveViewState(); /* The current thread is about to go down so render any IDataObject that may be left in the clipboard */ @@ -3658,16 +3762,15 @@ LRESULT CShellBrowser::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & // TODO: rip down everything { m_Destroyed = true; // Ignore browse requests from Explorer band TreeView during destruction + fCurrentShellView->UIActivate(SVUIA_DEACTIVATE); fToolbarProxy.Destroy(); fCurrentShellView->DestroyViewWindow(); - fCurrentShellView->UIActivate(SVUIA_DEACTIVATE); for (int i = 0; i < 3; i++) { CComPtr pdw; CComPtr bar; CComPtr pBarSite; - CComPtr pClient; if (fClientBars[i].clientBar == NULL) continue; @@ -3683,6 +3786,7 @@ LRESULT CShellBrowser::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & hr = bar->GetClient(&pBarSite); if (SUCCEEDED(hr) && pBarSite) { + CComPtr pClient; hr = pBarSite->QueryInterface(IID_PPV_ARG(IDeskBarClient, &pClient)); if (SUCCEEDED(hr)) pClient->SetDeskBarSite(NULL); @@ -3690,7 +3794,6 @@ LRESULT CShellBrowser::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & } pdw->CloseDW(0); - pClient = NULL; pBarSite = NULL; pdw = NULL; bar = NULL; @@ -3701,6 +3804,7 @@ LRESULT CShellBrowser::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & fCurrentShellFolder.Release(); ILFree(fCurrentDirectoryPIDL); + fCurrentDirectoryPIDL = NULL; ::DestroyWindow(fStatusBar); DestroyMenu(fCurrentMenuBar); } @@ -3720,7 +3824,7 @@ LRESULT CShellBrowser::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHa GetEffectiveClientRect(m_hWnd, &availableBounds, excludeItems); for (INT x = 0; x < 3; x++) { - if (fClientBars[x].clientBar != NULL) + if (fClientBars[x].clientBar) { hResult = fClientBars[x].clientBar->QueryInterface( IID_PPV_ARG(IDockingWindow, &dockingWindow)); @@ -3871,48 +3975,17 @@ LRESULT CShellBrowser::OnGoHome(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL & LRESULT CShellBrowser::OnBackspace(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled) { - // FIXME: This does not appear to be what windows does. - HRESULT hResult = NavigateToParent(); + HRESULT hResult; + if (LOBYTE(GetVersion()) < 6) + hResult = NavigateToParent(); + else if (FAILED(hResult = GoBack())) + hResult = GoForward(); + if (FAILED(hResult)) - TRACE("NavigateToParent failed with hResult=%08lx\n", hResult); + TRACE("Backspace navigation failed with hResult=%08lx\n", hResult); return 0; } -static BOOL -CreateShortcut( - IN LPCWSTR pszLnkFileName, - IN LPCITEMIDLIST pidl, - IN LPCWSTR pszDescription OPTIONAL) -{ - IPersistFile *pPF; - IShellLinkW *pSL; - HRESULT hr = CoInitialize(NULL); - if (FAILED(hr)) - return hr; - - hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, - IID_IShellLinkW, (LPVOID*)&pSL); - if (SUCCEEDED(hr)) - { - pSL->SetIDList(pidl); - - if (pszDescription) - pSL->SetDescription(pszDescription); - - hr = pSL->QueryInterface(IID_IPersistFile, (LPVOID*)&pPF); - if (SUCCEEDED(hr)) - { - hr = pPF->Save(pszLnkFileName, TRUE); - pPF->Release(); - } - pSL->Release(); - } - - CoUninitialize(); - - return SUCCEEDED(hr); -} - HRESULT GetFavsLocation(HWND hWnd, LPITEMIDLIST *pPidl) { HRESULT hr = SHGetSpecialFolderLocation(hWnd, CSIDL_FAVORITES, pPidl); @@ -3924,24 +3997,23 @@ HRESULT GetFavsLocation(HWND hWnd, LPITEMIDLIST *pPidl) LRESULT CShellBrowser::OnAddToFavorites(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled) { - LPITEMIDLIST pidlFavs; - HRESULT hr = GetFavsLocation(m_hWnd, &pidlFavs); + CComPtr pParent; + LPCITEMIDLIST pidlLast; + HRESULT hr = SHBindToParent(fCurrentDirectoryPIDL, IID_PPV_ARG(IShellFolder, &pParent), &pidlLast); if (FAILED_UNEXPECTEDLY(hr)) - return 0; + return hr; - SHFILEINFOW fileInfo = { NULL }; - if (!SHGetFileInfoW((LPCWSTR)fCurrentDirectoryPIDL, 0, &fileInfo, sizeof(fileInfo), - SHGFI_PIDL | SHGFI_DISPLAYNAME)) - { + STRRET strret; + hr = pParent->GetDisplayNameOf(pidlLast, SHGDN_FORPARSING, &strret); + if (FAILED_UNEXPECTEDLY(hr)) return 0; - } - WCHAR szPath[MAX_PATH]; - SHGetPathFromIDListW(pidlFavs, szPath); - PathAppendW(szPath, fileInfo.szDisplayName); - PathAddExtensionW(szPath, L".lnk"); + CComHeapPtr pszURL; + hr = StrRetToStrW(&strret, NULL, &pszURL); + if (FAILED_UNEXPECTEDLY(hr)) + return 0; - CreateShortcut(szPath, fCurrentDirectoryPIDL, NULL); + AddUrlToFavorites(m_hWnd, pszURL, NULL, TRUE); return 0; } @@ -4128,6 +4200,69 @@ LRESULT CShellBrowser::OnAppCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOO return 0; } +LRESULT CShellBrowser::OnToggleFullscreen(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled) +{ + const UINT OrgUiSetAuto = m_BrowserSvcFlags & BSF_UISETBYAUTOMATION; + const BOOL fCurrentlyFullscreen = (m_BrowserSvcFlags & BSF_THEATERMODE); + const BOOL fEnter = wID ? !fCurrentlyFullscreen : wNotifyCode; + const HWND hWnd = GetTopLevelBrowserWindow(); + if (fEnter) + { + VARIANT_BOOL varb; + m_NonFullscreenState = (m_BrowserSvcFlags & BSF_RESIZABLE) ? FSF_RESIZE : 0; + m_NonFullscreenState |= (FAILED(get_MenuBar(&varb)) || varb) ? FSF_MBAR : 0; + m_NonFullscreenState |= (FAILED(get_StatusBar(&varb)) || varb) ? FSF_SBAR : 0; + m_NonFullscreenState |= (SHSetWindowBits(hWnd, GWL_STYLE, 0, 0) & WS_MAXIMIZE) ? FSF_MAXIMIZED : 0; + SetFlags(BSF_THEATERMODE, BSF_THEATERMODE); + put_MenuBar(VARIANT_FALSE); + put_StatusBar(VARIANT_FALSE); + SHSetWindowBits(hWnd, GWL_STYLE, WS_CAPTION | WS_BORDER | WS_DLGFRAME | WS_THICKFRAME, 0); + SHSetWindowBits(hWnd, GWL_EXSTYLE, WS_EX_WINDOWEDGE, 0); + ::ShowWindow(hWnd, SW_SHOWMAXIMIZED); + MONITORINFO mi; + GetWindowMonitorInfo(hWnd, mi); + int x = mi.rcMonitor.left, w = mi.rcMonitor.right - x; + int y = mi.rcMonitor.top, h = mi.rcMonitor.bottom - y; + ::SetWindowPos(hWnd, HWND_TOPMOST, x, y, w, h, SWP_FRAMECHANGED); + } + else + { + SetFlags(0, BSF_THEATERMODE); + put_MenuBar((m_NonFullscreenState & FSF_MBAR) ? VARIANT_TRUE : VARIANT_FALSE); + put_StatusBar((m_NonFullscreenState & FSF_SBAR) ? VARIANT_TRUE : VARIANT_FALSE); + SHSetWindowBits(hWnd, GWL_EXSTYLE, WS_EX_WINDOWEDGE, WS_EX_WINDOWEDGE); + UINT styles = WS_CAPTION | WS_BORDER | WS_DLGFRAME | ((m_NonFullscreenState & FSF_RESIZE) ? WS_THICKFRAME : 0); + SHSetWindowBits(hWnd, GWL_STYLE, styles | WS_THICKFRAME, styles); + ::SetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE); + ::ShowWindow(hWnd, SW_SHOWNOACTIVATE); + if (m_NonFullscreenState & FSF_MAXIMIZED) + ::ShowWindow(hWnd, SW_SHOWMAXIMIZED); + } + SetFlags(OrgUiSetAuto, BSF_UISETBYAUTOMATION); + ::RedrawWindow(hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN); + return 0; +} + +LRESULT CShellBrowser::OnDisplayChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + PostMessage(BWM_ONDISPLAYCHANGEDELAYED, wParam, lParam); + return 0; +} + +LRESULT CShellBrowser::OnDisplayChangeDelayed(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + if (m_BrowserSvcFlags & (BSF_THEATERMODE | BSF_ROS_KIOSK)) // Resize fullscreen on resolution change (CORE-20072) + { + const HWND hWnd = GetTopLevelBrowserWindow(); + MONITORINFO mi; + GetWindowMonitorInfo(hWnd, mi); + int x = mi.rcMonitor.left, w = mi.rcMonitor.right - x; + int y = mi.rcMonitor.top, h = mi.rcMonitor.bottom - y; + ::SetWindowPos(hWnd, HWND_TOPMOST, x, y, w, h, SWP_NOZORDER | SWP_NOCOPYBITS); + } + return 0; +} + HRESULT CShellBrowser_CreateInstance(REFIID riid, void **ppv) { return ShellObjectCreatorInit(riid, ppv); diff --git a/dll/win32/browseui/shellfind/CFindFolder.cpp b/dll/win32/browseui/shellfind/CFindFolder.cpp index ea703158c3085..2937663b0872b 100644 --- a/dll/win32/browseui/shellfind/CFindFolder.cpp +++ b/dll/win32/browseui/shellfind/CFindFolder.cpp @@ -84,7 +84,7 @@ struct FolderViewColumns int cxChar; }; -static FolderViewColumns g_ColumnDefs[] = +static const FolderViewColumns g_ColumnDefs[] = { {IDS_COL_NAME, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 30}, {IDS_COL_LOCATION, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 30}, @@ -92,6 +92,7 @@ static FolderViewColumns g_ColumnDefs[] = }; CFindFolder::CFindFolder() : + m_pidl(NULL), m_hStopEvent(NULL) { } @@ -106,26 +107,32 @@ static LPITEMIDLIST _ILCreate(LPCWSTR lpszPath) } LPITEMIDLIST lpLastFSPidl = ILFindLastID(lpFSPidl); - int pathLen = (PathFindFileNameW(lpszPath) - lpszPath) * sizeof(WCHAR); - int cbData = sizeof(WORD) + pathLen + lpLastFSPidl->mkid.cb; + SIZE_T cbPath = (PathFindFileNameW(lpszPath) - lpszPath + 1) * sizeof(WCHAR); + SIZE_T cbData = sizeof(WORD) + cbPath + lpLastFSPidl->mkid.cb; + if (cbData > 0xffff) + return NULL; LPITEMIDLIST pidl = (LPITEMIDLIST) SHAlloc(cbData + sizeof(WORD)); if (!pidl) return NULL; LPBYTE p = (LPBYTE) pidl; - *((WORD *) p) = cbData; - p += sizeof(WORD); + p += sizeof(WORD); // mkid.cb - memcpy(p, lpszPath, pathLen); - p += pathLen - sizeof(WCHAR); - *((WCHAR *) p) = '\0'; - p += sizeof(WCHAR); + PWSTR path = (PWSTR)p; + memcpy(p, lpszPath, cbPath); + p += cbPath; + ((PWSTR)p)[-1] = UNICODE_NULL; // "C:\" not "C:" (required by ILCreateFromPathW and matches Windows) + if (!PathIsRootW(path)) + { + p -= sizeof(WCHAR); + ((PWSTR)p)[-1] = UNICODE_NULL; // "C:\folder" + } memcpy(p, lpLastFSPidl, lpLastFSPidl->mkid.cb); p += lpLastFSPidl->mkid.cb; - *((WORD *) p) = 0; - + pidl->mkid.cb = p - (LPBYTE)pidl; + ((LPITEMIDLIST)p)->mkid.cb = 0; // Terminator return pidl; } @@ -144,11 +151,79 @@ static LPCITEMIDLIST _ILGetFSPidl(LPCITEMIDLIST pidl) + ((wcslen((LPCWSTR) pidl->mkid.abID) + 1) * sizeof(WCHAR))); } +static PIDLIST_ABSOLUTE _ILCreateAbsolute(LPCITEMIDLIST pidlChild) +{ + PIDLIST_ABSOLUTE pidl = NULL; + if (PIDLIST_ABSOLUTE pidlFolder = SHSimpleIDListFromPath(_ILGetPath(pidl))) // FIXME: SHELL32_CreateSimpleIDListFromPath(, DIRECTORY) + { + pidl = ILCombine(pidlFolder, _ILGetFSPidl(pidl)); + ILFree(pidlFolder); + } + return pidl; +} + +HRESULT CFindFolder::GetFSFolderAndChild(LPCITEMIDLIST pidl, IShellFolder **ppSF, PCUITEMID_CHILD *ppidlLast) +{ + ATLASSERT(m_pSfDesktop); + PCWSTR path = _ILGetPath(pidl); + if (!path || !path[0]) + return E_INVALIDARG; + PIDLIST_ABSOLUTE pidlFolder = ILCreateFromPathW(path); // FIXME: SHELL32_CreateSimpleIDListFromPath(, DIRECTORY); + if (!pidlFolder) + return E_FAIL; + HRESULT hr = m_pSfDesktop->BindToObject(pidlFolder, NULL, IID_PPV_ARG(IShellFolder, ppSF)); + ILFree(pidlFolder); + if (ppidlLast) + *ppidlLast = _ILGetFSPidl(pidl); + return hr; +} + +HRESULT CFindFolder::GetFSFolder2AndChild(LPCITEMIDLIST pidl, IShellFolder2 **ppSF, PCUITEMID_CHILD *ppidlLast) +{ + CComPtr pSF1; + HRESULT hr = GetFSFolderAndChild(pidl, &pSF1, ppidlLast); + if (SUCCEEDED(hr)) + hr = pSF1->QueryInterface(IID_PPV_ARG(IShellFolder2, ppSF)); + return hr; +} + +static int CALLBACK ILFreeHelper(void *pItem, void *pCaller) +{ + ILFree((LPITEMIDLIST)pItem); + return TRUE; +} + +void CFindFolder::FreePidlArray(HDPA hDpa) +{ + DPA_DestroyCallback(hDpa, ILFreeHelper, NULL); +} + +HDPA CFindFolder::CreateAbsolutePidlArray(UINT cidl, PCUITEMID_CHILD_ARRAY apidl) +{ + HDPA hDpa = DPA_Create(cidl / 2); + if (hDpa) + { + for (UINT i = 0; i < cidl; ++i) + { + PIDLIST_ABSOLUTE pidl = _ILCreateAbsolute(apidl[i]); + if (pidl) + { + if (DPA_InsertPtr(hDpa, i, pidl) >= 0) + continue; + ILFree(pidl); + } + FreePidlArray(hDpa); + return NULL; + } + } + return hDpa; +} + struct _SearchData { HWND hwnd; HANDLE hStopEvent; - CStringW szPath; + LOCATIONITEM *pPaths; CStringW szFileName; CStringA szQueryA; CStringW szQueryW; @@ -156,6 +231,11 @@ struct _SearchData CStringA szQueryU8; BOOL SearchHidden; CComPtr pFindFolder; + + ~_SearchData() + { + FreeList(pPaths); + } }; template @@ -461,11 +541,17 @@ DWORD WINAPI CFindFolder::SearchThreadProc(LPVOID lpParameter) { _SearchData *data = static_cast<_SearchData*>(lpParameter); + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL); + HRESULT hrCoInit = CoInitializeEx(NULL, COINIT_MULTITHREADED); data->pFindFolder->NotifyConnections(DISPID_SEARCHSTART); - UINT uTotalFound = RecursiveFind(data->szPath, data); + UINT uTotalFound = 0; + for (LOCATIONITEM *pLocation = data->pPaths; pLocation; pLocation = pLocation->pNext) + { + uTotalFound += RecursiveFind(pLocation->szPath, data); + } data->pFindFolder->NotifyConnections(DISPID_SEARCHCOMPLETE); @@ -521,7 +607,7 @@ LRESULT CFindFolder::StartSearch(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & pSearchData->hwnd = m_hWnd; SearchStart *pSearchParams = (SearchStart *) lParam; - pSearchData->szPath = pSearchParams->szPath; + pSearchData->pPaths = pSearchParams->pPaths; pSearchData->szFileName = pSearchParams->szFileName; pSearchData->szQueryA = pSearchParams->szQuery; pSearchData->szQueryW = pSearchParams->szQuery; @@ -589,12 +675,15 @@ LRESULT CFindFolder::StartSearch(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & SetEvent(m_hStopEvent); pSearchData->hStopEvent = m_hStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - if (!SHCreateThread(SearchThreadProc, pSearchData, NULL, NULL)) + if (!SHCreateThread(SearchThreadProc, pSearchData, 0, NULL)) { - SHFree(pSearchData); - return 0; + if (pSearchData->hStopEvent) + { + CloseHandle(pSearchData->hStopEvent); + m_hStopEvent = NULL; + } + delete pSearchData; } - return 0; } @@ -652,9 +741,9 @@ STDMETHODIMP CFindFolder::EnumSearches(IEnumExtraSearch **ppenum) STDMETHODIMP CFindFolder::GetDefaultColumn(DWORD, ULONG *pSort, ULONG *pDisplay) { if (pSort) - *pSort = 0; + *pSort = COL_NAME_INDEX; if (pDisplay) - *pDisplay = 0; + *pDisplay = COL_NAME_INDEX; return S_OK; } @@ -670,17 +759,31 @@ STDMETHODIMP CFindFolder::GetDefaultColumnState(UINT iColumn, DWORD *pcsFlags) STDMETHODIMP CFindFolder::GetDetailsEx(PCUITEMID_CHILD pidl, const SHCOLUMNID *pscid, VARIANT *pv) { - return m_pisfInner->GetDetailsEx(pidl, pscid, pv); + // FIXME: Handle COL_LOCATION_INDEX and COL_RELEVANCE_INDEX + CComPtr pFolder; + PCUITEMID_CHILD pChild; + if (SUCCEEDED(GetFSFolder2AndChild(pidl, &pFolder, &pChild))) + return pFolder->GetDetailsEx(pChild, pscid, pv); + return E_FAIL; } STDMETHODIMP CFindFolder::GetDetailsOf(PCUITEMID_CHILD pidl, UINT iColumn, SHELLDETAILS *pDetails) { if (iColumn >= _countof(g_ColumnDefs)) - return m_pisfInner->GetDetailsOf(_ILGetFSPidl(pidl), iColumn - _countof(g_ColumnDefs) + 1, pDetails); + { + UINT FSColumn = iColumn - _countof(g_ColumnDefs) + 1; + if (pidl) + { + CComPtr pFolder; + PCUITEMID_CHILD pChild; + if (SUCCEEDED(GetFSFolder2AndChild(pidl, &pFolder, &pChild))) + return pFolder->GetDetailsOf(pChild, FSColumn, pDetails); + } + return m_pisfInner->GetDetailsOf(pidl, FSColumn, pDetails); // Column header info + } pDetails->cxChar = g_ColumnDefs[iColumn].cxChar; pDetails->fmt = g_ColumnDefs[iColumn].fmt; - if (!pidl) return SHSetStrRet(&pDetails->str, _AtlBaseModule.GetResourceInstance(), g_ColumnDefs[iColumn].iResource); @@ -695,7 +798,8 @@ STDMETHODIMP CFindFolder::GetDetailsOf(PCUITEMID_CHILD pidl, UINT iColumn, SHELL return SHSetStrRet(&pDetails->str, ""); } - return GetDisplayNameOf(pidl, SHGDN_NORMAL, &pDetails->str); + ATLASSERT(iColumn == COL_NAME_INDEX); + return GetDisplayNameOf(pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &pDetails->str); } STDMETHODIMP CFindFolder::MapColumnToSCID(UINT iColumn, SHCOLUMNID *pscid) @@ -720,8 +824,12 @@ STDMETHODIMP CFindFolder::EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIS STDMETHODIMP CFindFolder::BindToObject(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut) { - UNIMPLEMENTED; - return E_NOTIMPL; + HRESULT hr; + CComPtr pInnerFolder; + PCUITEMID_CHILD pidlChild; + if (FAILED_UNEXPECTEDLY(hr = GetFSFolderAndChild(pidl, &pInnerFolder, &pidlChild))) + return hr; + return pInnerFolder->BindToObject(pidlChild, pbcReserved, riid, ppvOut); } STDMETHODIMP CFindFolder::BindToStorage(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut) @@ -745,6 +853,7 @@ STDMETHODIMP CFindFolder::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PC wColumn -= _countof(g_ColumnDefs) - 1; break; } + // FIXME: DefView does not like the way we sort return m_pisfInner->CompareIDs(HIWORD(lParam) | wColumn, _ILGetFSPidl(pidl1), _ILGetFSPidl(pidl2)); } @@ -769,14 +878,24 @@ STDMETHODIMP CFindFolder::CreateViewObject(HWND hwndOwner, REFIID riid, LPVOID * STDMETHODIMP CFindFolder::GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY apidl, DWORD *rgfInOut) { - CComHeapPtr aFSPidl; - aFSPidl.Allocate(cidl); - for (UINT i = 0; i < cidl; i++) + if (!cidl) { - aFSPidl[i] = _ILGetFSPidl(apidl[i]); + *rgfInOut &= SFGAO_BROWSABLE; // TODO: SFGAO_CANRENAME? + return S_OK; } - return m_pisfInner->GetAttributesOf(cidl, aFSPidl, rgfInOut); + HRESULT hr = E_INVALIDARG; + for (UINT i = 0; i < cidl; ++i) + { + CComPtr pFolder; + PCUITEMID_CHILD pidlChild; + if (FAILED_UNEXPECTEDLY(hr = GetFSFolderAndChild(apidl[i], &pFolder, &pidlChild))) + break; + if (FAILED(hr = pFolder->GetAttributesOf(1, &pidlChild, rgfInOut))) + break; + } + *rgfInOut &= ~SFGAO_CANRENAME; // FIXME: Handle SetNameOf + return hr; } class CFindFolderContextMenu : @@ -791,7 +910,7 @@ class CFindFolderContextMenu : //// *** IContextMenu methods *** STDMETHODIMP QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags) { - m_firstCmdId = indexMenu; + m_firstCmdId = idCmdFirst; _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst++, MFT_STRING, MAKEINTRESOURCEW(IDS_SEARCH_OPEN_FOLDER), MFS_ENABLED); _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst++, MFT_SEPARATOR, NULL, 0); return m_pInner->QueryContextMenu(hMenu, indexMenu, idCmdFirst, idCmdLast, uFlags); @@ -804,7 +923,7 @@ class CFindFolderContextMenu : return m_pInner->InvokeCommand(lpcmi); } - if (LOWORD(lpcmi->lpVerb) < m_firstCmdId + ADDITIONAL_MENU_ITEMS) + if (LOWORD(lpcmi->lpVerb) >= m_firstCmdId && LOWORD(lpcmi->lpVerb) < m_firstCmdId + ADDITIONAL_MENU_ITEMS) { PCUITEMID_CHILD *apidl; UINT cidl; @@ -824,9 +943,11 @@ class CFindFolderContextMenu : return S_OK; } + // FIXME: We can't block FCIDM_SHVIEW_REFRESH here, add items on SFVM_LISTREFRESHED instead CMINVOKECOMMANDINFOEX actualCmdInfo; memcpy(&actualCmdInfo, lpcmi, lpcmi->cbSize); - actualCmdInfo.lpVerb -= ADDITIONAL_MENU_ITEMS; + if (LOWORD(lpcmi->lpVerb) < FCIDM_SHVIEW_ARRANGE) // HACKFIX for DefView using direct FCIDM_SHVIEW ids + actualCmdInfo.lpVerb -= ADDITIONAL_MENU_ITEMS; return m_pInner->InvokeCommand((CMINVOKECOMMANDINFO *)&actualCmdInfo); } @@ -852,16 +973,39 @@ class CFindFolderContextMenu : END_COM_MAP() }; +int CALLBACK CFindFolder::SortItemsForDataObject(void *p1, void *p2, LPARAM lparam) +{ + // For Delete/Move operations, a subfolder/file needs to come before the parent folder + return ::ILGetSize((LPCITEMIDLIST)p1) - ::ILGetSize((LPCITEMIDLIST)p2); +} + STDMETHODIMP CFindFolder::GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, REFIID riid, UINT *prgfInOut, LPVOID *ppvOut) { + HRESULT hr; if (cidl <= 0) + return E_INVALIDARG; + + CComHeapPtr aFSPidlAlloc; + PCITEMID_CHILD pidlSingleBuffer, *aFSPidl = &pidlSingleBuffer; // Optimize for single item callers + if (cidl != 1) { - return m_pisfInner->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, ppvOut); - } + if (riid == IID_IDataObject) + { + if (HDPA hDpa = CreateAbsolutePidlArray(cidl, apidl)) + { + DPA_Sort(hDpa, SortItemsForDataObject, NULL); + ITEMIDLIST pidlRoot = {}; + hr = SHCreateFileDataObject(&pidlRoot, cidl, (PCUITEMID_CHILD_ARRAY)DPA_GetPtrPtr(hDpa), + NULL, (IDataObject**)ppvOut); + FreePidlArray(hDpa); + return hr; + } + } - CComHeapPtr aFSPidl; - aFSPidl.Allocate(cidl); + aFSPidlAlloc.Allocate(cidl); + aFSPidl = aFSPidlAlloc; + } for (UINT i = 0; i < cidl; i++) { aFSPidl[i] = _ILGetFSPidl(apidl[i]); @@ -869,30 +1013,38 @@ STDMETHODIMP CFindFolder::GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_CHI if (riid == IID_IContextMenu) { + // FIXME: Use CDefFolderMenu_Create2(..., AddFSClassKeysToArray()) CComHeapPtr folderPidl(ILCreateFromPathW(_ILGetPath(apidl[0]))); if (!folderPidl) return E_OUTOFMEMORY; CComPtr pDesktopFolder; - HRESULT hResult = SHGetDesktopFolder(&pDesktopFolder); - if (FAILED_UNEXPECTEDLY(hResult)) - return hResult; + if (FAILED_UNEXPECTEDLY(hr = SHGetDesktopFolder(&pDesktopFolder))) + return hr; CComPtr pShellFolder; - hResult = pDesktopFolder->BindToObject(folderPidl, NULL, IID_PPV_ARG(IShellFolder, &pShellFolder)); - if (FAILED_UNEXPECTEDLY(hResult)) - return hResult; + hr = pDesktopFolder->BindToObject(folderPidl, NULL, IID_PPV_ARG(IShellFolder, &pShellFolder)); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; CComPtr pContextMenu; - hResult = pShellFolder->GetUIObjectOf(hwndOwner, cidl, aFSPidl, riid, prgfInOut, (LPVOID *)&pContextMenu); - if (FAILED_UNEXPECTEDLY(hResult)) - return hResult; + hr = pShellFolder->GetUIObjectOf(hwndOwner, cidl, aFSPidl, riid, prgfInOut, (void**)&pContextMenu); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; return CFindFolderContextMenu::Create(m_shellFolderView, pContextMenu, (IContextMenu **)ppvOut); } - return m_pisfInner->GetUIObjectOf(hwndOwner, cidl, aFSPidl, riid, prgfInOut, ppvOut); + CComPtr pFolder; + if (FAILED_UNEXPECTEDLY(hr = GetFSFolderAndChild(apidl[0], &pFolder))) + return hr; + return pFolder->GetUIObjectOf(hwndOwner, cidl, aFSPidl, riid, prgfInOut, ppvOut); } STDMETHODIMP CFindFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET pName) { - return m_pisfInner->GetDisplayNameOf(_ILGetFSPidl(pidl), dwFlags, pName); + HRESULT hr; + CComPtr pFolder; + PCUITEMID_CHILD pidlChild; + if (FAILED_UNEXPECTEDLY(hr = GetFSFolderAndChild(pidl, &pFolder, &pidlChild))) + return hr; + return pFolder->GetDisplayNameOf(pidlChild, dwFlags, pName); } STDMETHODIMP CFindFolder::SetNameOf(HWND hwndOwner, PCUITEMID_CHILD pidl, LPCOLESTR lpName, DWORD dwFlags, @@ -919,11 +1071,7 @@ STDMETHODIMP CFindFolder::MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam) SubclassWindow((HWND) wParam); // Get shell browser for updating status bar text - CComPtr pServiceProvider; - HRESULT hr = m_shellFolderView->QueryInterface(IID_PPV_ARG(IServiceProvider, &pServiceProvider)); - if (FAILED_UNEXPECTEDLY(hr)) - return hr; - hr = pServiceProvider->QueryService(SID_SShellBrowser, IID_PPV_ARG(IShellBrowser, &m_shellBrowser)); + HRESULT hr = IUnknown_QueryService(m_shellFolderView, SID_SShellBrowser, IID_PPV_ARG(IShellBrowser, &m_shellBrowser)); if (FAILED_UNEXPECTEDLY(hr)) return hr; @@ -932,9 +1080,9 @@ STDMETHODIMP CFindFolder::MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam) hr = m_shellBrowser->QueryInterface(IID_PPV_ARG(IWebBrowser2, &pWebBrowser2)); if (FAILED_UNEXPECTEDLY(hr)) return hr; - WCHAR pwszGuid[MAX_PATH]; - StringFromGUID2(CLSID_FileSearchBand, pwszGuid, _countof(pwszGuid)); - CComVariant searchBar(pwszGuid); + WCHAR wszGuid[39]; + StringFromGUID2(CLSID_FileSearchBand, wszGuid, _countof(wszGuid)); + CComVariant searchBar(wszGuid); return pWebBrowser2->ShowBrowserBar(&searchBar, NULL, NULL); } case SFVM_WINDOWCLOSING: @@ -959,6 +1107,7 @@ STDMETHODIMP CFindFolder::MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam) } return hr; } + // TODO: SFVM_GETCOLUMNSTREAM } return E_NOTIMPL; } @@ -966,21 +1115,20 @@ STDMETHODIMP CFindFolder::MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam) //// *** IPersistFolder2 methods *** STDMETHODIMP CFindFolder::GetCurFolder(PIDLIST_ABSOLUTE *pidl) { - *pidl = ILClone(m_pidl); - return S_OK; + return SHILClone(m_pidl, pidl); } // *** IPersistFolder methods *** STDMETHODIMP CFindFolder::Initialize(PCIDLIST_ABSOLUTE pidl) { - m_pidl = ILClone(pidl); - if (!m_pidl) - return E_OUTOFMEMORY; - - return SHELL32_CoCreateInitSF(m_pidl, - NULL, - NULL, - &CLSID_ShellFSFolder, + if (m_pidl) + return E_UNEXPECTED; + HRESULT hr; + if (FAILED(hr = SHGetDesktopFolder((IShellFolder**)&m_pSfDesktop))) + return hr; + if (FAILED(hr = SHILClone(pidl, &m_pidl))) + return hr; + return SHELL32_CoCreateInitSF(m_pidl, NULL, NULL, &CLSID_ShellFSFolder, IID_PPV_ARG(IShellFolder2, &m_pisfInner)); } diff --git a/dll/win32/browseui/shellfind/CFindFolder.h b/dll/win32/browseui/shellfind/CFindFolder.h index a19651bde49c7..142a3e6265c2e 100644 --- a/dll/win32/browseui/shellfind/CFindFolder.h +++ b/dll/win32/browseui/shellfind/CFindFolder.h @@ -64,11 +64,16 @@ class CFindFolder : private: LPITEMIDLIST m_pidl; - CComPtr m_pisfInner; + CComPtr m_pisfInner, m_pSfDesktop; CComPtr m_shellFolderView; CComPtr m_shellBrowser; HANDLE m_hStopEvent; + HRESULT GetFSFolderAndChild(LPCITEMIDLIST pidl, IShellFolder **ppSF, PCUITEMID_CHILD *ppidlLast = NULL); + HRESULT GetFSFolder2AndChild(LPCITEMIDLIST pidl, IShellFolder2 **ppSF, PCUITEMID_CHILD *ppidlLast = NULL); + void FreePidlArray(HDPA hDpa); + HDPA CreateAbsolutePidlArray(UINT cidl, PCUITEMID_CHILD_ARRAY apidl); + static int CALLBACK SortItemsForDataObject(void *p1, void *p2, LPARAM lparam); void NotifyConnections(DISPID id); static DWORD WINAPI SearchThreadProc(LPVOID lpParameter); diff --git a/dll/win32/browseui/shellfind/CSearchBar.cpp b/dll/win32/browseui/shellfind/CSearchBar.cpp index b7d97123798fc..8fb7ae3321bfc 100644 --- a/dll/win32/browseui/shellfind/CSearchBar.cpp +++ b/dll/win32/browseui/shellfind/CSearchBar.cpp @@ -20,8 +20,160 @@ WINE_DEFAULT_DEBUG_CHANNEL(shellfind); #define UNIMPLEMENTED DbgPrint("%s is UNIMPLEMENTED!\n", __FUNCTION__) #endif +static BOOL IsWindowChildOf(const HWND hNeedle, const HWND hRoot) +{ + if (hNeedle != hRoot) + { + for (HWND hParent = hNeedle; hParent;) + { + hParent = GetParent(hParent); + if (hParent == hRoot) + return TRUE; + } + } + return FALSE; +} + +static UINT GetShellViewItemCount(IShellView *pSV) +{ + int signedCount; + CComQIIDPtr pFV(pSV); + if (pFV && SUCCEEDED(pFV->ItemCount(SVGIO_ALLVIEW, &signedCount))) + return signedCount; + UINT unsignedCount; + CComQIIDPtr pSFV(pSV); + if (pSFV && SUCCEEDED(pSFV->GetObjectCount(&unsignedCount))) + return unsignedCount; + return 0; +} + + +struct SPECIALFINDITEMID +{ + WORD cb; + BYTE Type, Id; + CLSID Cls; + WORD Terminator; +}; +enum { SPECIAL_BROWSE = 42 }; + +static const SPECIALFINDITEMID g_pidlBrowseDir = { FIELD_OFFSET(SPECIALFINDITEMID, Terminator), + 0, SPECIAL_BROWSE, CLSID_FindFolder, 0 }; + +static BYTE GetSpecial(PCIDLIST_ABSOLUTE pidl) +{ + if (pidl && pidl->mkid.cb == FIELD_OFFSET(SPECIALFINDITEMID, Terminator)) + { + SPECIALFINDITEMID *pSpecial = (SPECIALFINDITEMID*)pidl; + if (pSpecial->Type == g_pidlBrowseDir.Type && pSpecial->Cls == g_pidlBrowseDir.Cls && + ILIsEmpty(ILGetNext(pidl))) + { + return pSpecial->Id; + } + } + return 0; +} + +static HRESULT BindToObject(PCIDLIST_ABSOLUTE pidl, REFIID riid, void **ppv) +{ + if (GetSpecial(pidl)) + return E_FAIL; + + PCUITEMID_CHILD pidlChild; + CComPtr psf; + HRESULT hr = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &psf), &pidlChild); + return SUCCEEDED(hr) ? psf->BindToObject(pidlChild, NULL, riid, ppv) : hr; +} + +static HRESULT GetClassOfItem(PCIDLIST_ABSOLUTE pidl, CLSID *pCLSID) +{ + CComPtr psf; + HRESULT hr = BindToObject(pidl, IID_PPV_ARG(IShellFolder, &psf)); + return SUCCEEDED(hr) ? IUnknown_GetClassID(psf, pCLSID) : hr; +} + +void FreeList(LOCATIONITEM *pItems) +{ + while (pItems) + { + LOCATIONITEM *pNext = pItems->pNext; + CoTaskMemFree(pItems); + pItems = pNext; + } +} + +static LOCATIONITEM* CreateLocationListItem(PCWSTR szPath) +{ + const SIZE_T cch = lstrlenW(szPath) + 1; + LOCATIONITEM *p = (LOCATIONITEM*)CoTaskMemAlloc(FIELD_OFFSET(LOCATIONITEM, szPath[cch])); + if (p) + { + p->pNext = NULL; + CopyMemory(p->szPath, szPath, cch * sizeof(*szPath)); + } + return p; +} + +template static LOCATIONITEM* BuildLocationList(T **rgszPaths, SIZE_T nCount) +{ + LOCATIONITEM *pStart = NULL, *pPrev = NULL; + for (SIZE_T i = 0; i < nCount; ++i) + { + LOCATIONITEM *pItem = CreateLocationListItem(rgszPaths[i]); + if (!pStart) + pStart = pItem; + else if (pPrev) + pPrev->pNext = pItem; + pPrev = pItem; + if (!pItem) + { + FreeList(pStart); + return NULL; + } + } + return pStart; +} + +static LOCATIONITEM* GetDesktopLocations() +{ + SIZE_T nCount = 0; + PCWSTR rgszLocations[2]; + WCHAR szUser[MAX_PATH], szCommon[MAX_PATH]; + + rgszLocations[nCount] = szUser; + nCount += !!SHGetSpecialFolderPathW(NULL, szUser, CSIDL_DESKTOPDIRECTORY, TRUE); + rgszLocations[nCount] = szCommon; + nCount += !!SHGetSpecialFolderPathW(NULL, szCommon, CSIDL_COMMON_DESKTOPDIRECTORY, TRUE); + return BuildLocationList(rgszLocations, nCount); +} + +static LOCATIONITEM* GetLocalDisksLocations() +{ + PCWSTR rgszLocations[26]; + WCHAR rgszDrives[_countof(rgszLocations)][4]; + UINT nCount = 0; + for (UINT i = 0, fDrives = GetLogicalDrives(); i < _countof(rgszLocations); ++i) + { + if (fDrives & (1 << i)) + { + rgszDrives[nCount][0] = 'A' + i; + rgszDrives[nCount][1] = ':'; + rgszDrives[nCount][2] = '\\'; + rgszDrives[nCount][3] = UNICODE_NULL; + UINT fType = GetDriveTypeW(rgszDrives[nCount]); + if (fType == DRIVE_FIXED || fType == DRIVE_RAMDISK) + { + rgszLocations[nCount] = rgszDrives[nCount]; + nCount++; + } + } + } + return BuildLocationList(rgszLocations, nCount); +} + CSearchBar::CSearchBar() : m_pSite(NULL), + m_RealItemIndex(0), m_bVisible(FALSE) { } @@ -167,11 +319,15 @@ LRESULT CSearchBar::OnSearchButtonClicked(WORD wNotifyCode, WORD wID, HWND hWndC pSearchStart->SearchHidden = IsDlgButtonChecked(IDC_SEARCH_HIDDEN); - if (!GetAddressEditBoxPath(pSearchStart->szPath)) + WCHAR buf[MAX_PATH]; + pSearchStart->pPaths = GetAddressEditBoxLocations(buf); + if (!pSearchStart->pPaths) { - ShellMessageBoxW(_AtlBaseModule.GetResourceInstance(), m_hWnd, MAKEINTRESOURCEW(IDS_SEARCHINVALID), MAKEINTRESOURCEW(IDS_SEARCHLABEL), MB_OK | MB_ICONERROR, pSearchStart->szPath); + ShellMessageBoxW(_AtlBaseModule.GetResourceInstance(), m_hWnd, MAKEINTRESOURCEW(IDS_SEARCHINVALID), + MAKEINTRESOURCEW(IDS_SEARCHLABEL), MB_OK | MB_ICONERROR, buf); return 0; } + ScopedFreeLocationItems FreeLocationsHelper(pSearchStart->pPaths); // See if we have an szFileName by testing for its entry lenth > 0 and our searched FileName does not contain // an asterisk or a question mark. If so, then prepend and append an asterisk to the searched FileName. @@ -228,6 +384,7 @@ LRESULT CSearchBar::OnSearchButtonClicked(WORD wNotifyCode, WORD wID, HWND hWndC return 0; } + FreeLocationsHelper.Detach(); ::PostMessageW(hwnd, WM_SEARCH_START, 0, (LPARAM) pSearchStart.Detach()); SetSearchInProgress(TRUE); @@ -245,31 +402,89 @@ LRESULT CSearchBar::OnStopButtonClicked(WORD wNotifyCode, WORD wID, HWND hWndCtl return 0; } -BOOL CSearchBar::GetAddressEditBoxPath(WCHAR *szPath) +LRESULT CSearchBar::OnLocationEditChange(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled) +{ + HWND hComboboxEx = hWndCtl; + INT_PTR idx = SendMessageW(hComboboxEx, CB_GETCURSEL, 0, 0); + if (idx < 0) + return 0; + COMBOBOXEXITEMW item; + item.mask = CBEIF_LPARAM; + item.iItem = idx; + item.cchTextMax = 0; + if (!SendMessageW(hComboboxEx, CBEM_GETITEMW, 0, (LPARAM)&item) || + GetSpecial((LPITEMIDLIST)item.lParam) != SPECIAL_BROWSE) + { + m_RealItemIndex = idx; + return 0; + } + + idx = max(m_RealItemIndex, 0); + SendMessageW(hComboboxEx, CB_SETCURSEL, idx, 0); // Reset to previous item + + BROWSEINFOW bi = { hComboboxEx }; + bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE; + if (PIDLIST_ABSOLUTE pidl = SHBrowseForFolderW(&bi)) + { + idx = FindItemInComboEx(hComboboxEx, pidl, ILIsEqual, TRUE); + if (idx < 0) + { + SHFILEINFO shfi; + if (SHGetFileInfoW((WCHAR*)pidl, 0, &shfi, sizeof(shfi), SHGFI_PIDL | SHGFI_DISPLAYNAME | SHGFI_SYSICONINDEX)) + { + item.mask = CBEIF_LPARAM | CBEIF_TEXT | CBEIF_SELECTEDIMAGE | CBEIF_IMAGE; + item.iItem = -1; + item.iImage = item.iSelectedImage = shfi.iIcon; + item.pszText = shfi.szDisplayName; + item.lParam = (LPARAM)pidl; // IAddressEditBox takes ownership + idx = SendMessageW(hComboboxEx, CBEM_INSERTITEMW, 0, (LPARAM)&item); + } + } + if (idx >= 0) + SendMessageW(hComboboxEx, CB_SETCURSEL, idx, 0); // Select the browsed item + else + SHFree(pidl); + } + return 0; +} + +LOCATIONITEM* CSearchBar::GetAddressEditBoxLocations(WCHAR *szPath) { + WCHAR szItemText[MAX_PATH], *pszPath = szPath; HWND hComboboxEx = GetDlgItem(IDC_SEARCH_COMBOBOX); ::GetWindowTextW(hComboboxEx, szPath, MAX_PATH); INT iSelectedIndex = SendMessageW(hComboboxEx, CB_GETCURSEL, 0, 0); if (iSelectedIndex != CB_ERR) { - WCHAR szItemText[MAX_PATH]; - COMBOBOXEXITEMW item = {0}; + COMBOBOXEXITEMW item; item.mask = CBEIF_LPARAM | CBEIF_TEXT; item.iItem = iSelectedIndex; item.pszText = szItemText; item.cchTextMax = _countof(szItemText); SendMessageW(hComboboxEx, CBEM_GETITEMW, 0, (LPARAM)&item); - - if (!wcscmp(szItemText, szPath) && SHGetPathFromIDListW((LPCITEMIDLIST)item.lParam, szItemText)) + if (!wcscmp(szItemText, szPath)) { - StringCbCopyW(szPath, MAX_PATH * sizeof(WCHAR), szItemText); - return TRUE; + LPCITEMIDLIST pidl = (LPCITEMIDLIST)item.lParam; + CLSID clsid; + HRESULT hr = GetClassOfItem(pidl, &clsid); + if (SUCCEEDED(hr) && clsid == CLSID_MyComputer) + return GetLocalDisksLocations(); + // TODO: Shell enumerate the network neighborhood if it is chosen + if (!pidl || !pidl->mkid.cb) + return GetDesktopLocations(); + if (GetSpecial(pidl) || !SHGetPathFromIDListW(pidl, szItemText)) + return NULL; + pszPath = szItemText; } } - DWORD dwAttributes = GetFileAttributesW(szPath); - return dwAttributes != INVALID_FILE_ATTRIBUTES - && (dwAttributes & FILE_ATTRIBUTE_DIRECTORY); + DWORD dwAttributes = GetFileAttributesW(pszPath); + if (dwAttributes != INVALID_FILE_ATTRIBUTES && (dwAttributes & FILE_ATTRIBUTE_DIRECTORY) && + PathIsAbsolute(pszPath)) + { + return BuildLocationList(&pszPath, 1); + } + return NULL; } LRESULT CSearchBar::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) @@ -336,6 +551,8 @@ HRESULT STDMETHODCALLTYPE CSearchBar::ShowDW(BOOL fShow) { m_bVisible = fShow; ShowWindow(fShow); + if (fShow) + TrySetFocus(DISPID_WINDOWSTATECHANGED); return S_OK; } @@ -562,6 +779,7 @@ HRESULT STDMETHODCALLTYPE CSearchBar::Invoke(DISPID dispIdMember, REFIID riid, L case DISPID_DOCUMENTCOMPLETE: { TrySubscribeToSearchEvents(); + TrySetFocus(DISPID_NAVIGATECOMPLETE2); // Remove the search results folder from the address box CComPtr pDispatch; @@ -577,37 +795,97 @@ HRESULT STDMETHODCALLTYPE CSearchBar::Invoke(DISPID dispIdMember, REFIID riid, L if (FAILED_UNEXPECTEDLY(hResult)) return hResult; HWND hComboboxEx = GetDlgItem(IDC_SEARCH_COMBOBOX); - int index = SendMessageW(hComboboxEx, CB_GETCOUNT, 0, 0); - if (index <= 0) + INT_PTR count = SendMessageW(hComboboxEx, CB_GETCOUNT, 0, 0); + if (count <= 0) return S_OK; COMBOBOXEXITEMW item = {0}; item.mask = CBEIF_LPARAM; - item.iItem = index - 1; + item.iItem = count - 1; SendMessageW(hComboboxEx, CBEM_GETITEMW, 0, (LPARAM)&item); if (!item.lParam) return S_OK; - CComPtr pDesktopFolder; - hResult = SHGetDesktopFolder(&pDesktopFolder); - if (FAILED_UNEXPECTEDLY(hResult)) - return hResult; - CComPtr pShellFolder; - hResult = pDesktopFolder->BindToObject((LPCITEMIDLIST)item.lParam, NULL, IID_PPV_ARG(IShellFolder, &pShellFolder)); - if (FAILED(hResult)) - return S_OK; CLSID clsid; - hResult = IUnknown_GetClassID(pShellFolder, &clsid); + hResult = GetClassOfItem((LPCITEMIDLIST)item.lParam, &clsid); if (SUCCEEDED(hResult) && clsid == CLSID_FindFolder) { SendMessageW(hComboboxEx, CBEM_DELETEITEM, item.iItem, 0); SendMessageW(hComboboxEx, CB_SETCURSEL, 0, 0); + // Starting in My Computer is better than just searching the desktop folder + PIDLIST_ABSOLUTE pidl; + if (SUCCEEDED(SHGetSpecialFolderLocation(NULL, CSIDL_DRIVES, &pidl))) + { + INT_PTR idx = FindItemInComboEx(hComboboxEx, pidl, ILIsEqual, TRUE); + if (idx >= 0) + SendMessageW(hComboboxEx, CB_SETCURSEL, idx, 0); + SHFree(pidl); + } } + + // Remove all non-filesystem items since we currently use FindFirstFile to search + BOOL fFoundBrowse = FALSE; + for (item.iItem = 0; SendMessageW(hComboboxEx, CBEM_GETITEMW, 0, (LPARAM)&item); item.iItem++) + { + LPCITEMIDLIST pidl = (LPCITEMIDLIST)item.lParam; + BYTE special = GetSpecial(pidl); + fFoundBrowse |= special == SPECIAL_BROWSE; + if (special) + continue; + const UINT fQuery = SFGAO_FILESYSTEM | SFGAO_FILESYSANCESTOR; + SHFILEINFO shfi; + shfi.dwAttributes = fQuery; + if (SHGetFileInfoW((WCHAR*)pidl, 0, &shfi, sizeof(shfi), SHGFI_PIDL | SHGFI_ATTRIBUTES | SHGFI_ATTR_SPECIFIED)) + { + if (!(shfi.dwAttributes & fQuery)) + { + if (SendMessageW(hComboboxEx, CBEM_DELETEITEM, item.iItem, 0) != CB_ERR) + item.iItem--; + } + } + } + + // Add our custom Browse item + if (!fFoundBrowse) + { + WCHAR buf[200]; + item.mask = CBEIF_LPARAM | CBEIF_TEXT | CBEIF_INDENT; + item.iItem = -1; + item.iIndent = -2; // Remove space reserved for the non-existing item icon + item.lParam = (LPARAM)ILClone((LPITEMIDLIST)&g_pidlBrowseDir); + item.pszText = const_cast(L"..."); + #define IDS_SEARCH_BROWSEITEM 10244 /* shell32 shresdef.h */ + if (LoadStringW(GetModuleHandleW(L"SHELL32"), IDS_SEARCH_BROWSEITEM, buf, _countof(buf))) + item.pszText = buf; + if (item.lParam) + SendMessageW(hComboboxEx, CBEM_INSERTITEMW, 0, (LPARAM)&item); + } + return S_OK; } case DISPID_SEARCHCOMPLETE: case DISPID_SEARCHABORT: SetSearchInProgress(FALSE); + TrySetFocus(DISPID_SEARCHCOMPLETE); return S_OK; default: return E_INVALIDARG; } } + +void CSearchBar::TrySetFocus(UINT Source) +{ + CComPtr pBrowser; + CComPtr pResultsSV; + if (SUCCEEDED(GetSearchResultsFolder(&pBrowser, NULL, NULL))) + pBrowser->QueryActiveShellView(&pResultsSV); + UINT cItems = pResultsSV ? GetShellViewItemCount(pResultsSV) : 0; + + // Attempt to set the focus if we are not in the results folder or if there are no results + HWND hWndFocus = ::GetFocus(); + if (!hWndFocus || !pResultsSV || cItems == 0) + { + BOOL IsOnButton = GetDlgItem(IDC_SEARCH_BUTTON) == hWndFocus; + BOOL IsOnSelfPane = hWndFocus == m_hWnd; + if (!hWndFocus || IsOnSelfPane || IsOnButton || !IsWindowChildOf(hWndFocus, m_hWnd)) + SendMessageW(WM_NEXTDLGCTL, (WPARAM)GetDlgItem(IDC_SEARCH_FILENAME), TRUE); + } +} diff --git a/dll/win32/browseui/shellfind/CSearchBar.h b/dll/win32/browseui/shellfind/CSearchBar.h index a798e368d5c0d..0e3710152f161 100644 --- a/dll/win32/browseui/shellfind/CSearchBar.h +++ b/dll/win32/browseui/shellfind/CSearchBar.h @@ -24,18 +24,21 @@ class CSearchBar : // *** BaseBarSite information *** CComPtr m_pSite; CComPtr m_AddressEditBox; + INT_PTR m_RealItemIndex; BOOL m_bVisible; HRESULT GetSearchResultsFolder(IShellBrowser **ppShellBrowser, HWND *pHwnd, IShellFolder **ppShellFolder); - BOOL GetAddressEditBoxPath(WCHAR *szPath); + LOCATIONITEM* GetAddressEditBoxLocations(WCHAR *szPath); void SetSearchInProgress(BOOL bInProgress); HRESULT TrySubscribeToSearchEvents(); + void TrySetFocus(UINT Source); // *** ATL event handlers *** LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); LRESULT OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); LRESULT OnSearchButtonClicked(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled); LRESULT OnStopButtonClicked(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled); + LRESULT OnLocationEditChange(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled); LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); public: @@ -104,5 +107,6 @@ class CSearchBar : MESSAGE_HANDLER(WM_SIZE, OnSize) COMMAND_HANDLER(IDC_SEARCH_BUTTON, BN_CLICKED, OnSearchButtonClicked) COMMAND_HANDLER(IDC_SEARCH_STOP_BUTTON, BN_CLICKED, OnStopButtonClicked) + COMMAND_HANDLER(IDC_SEARCH_COMBOBOX, CBN_EDITCHANGE, OnLocationEditChange) END_MSG_MAP() }; diff --git a/dll/win32/browseui/shellfind/shellfind.h b/dll/win32/browseui/shellfind/shellfind.h index 93256cb7970ab..1f42f99d7c1a7 100644 --- a/dll/win32/browseui/shellfind/shellfind.h +++ b/dll/win32/browseui/shellfind/shellfind.h @@ -31,12 +31,58 @@ #define WM_SEARCH_ADD_RESULT WM_USER + 2 #define WM_SEARCH_UPDATE_STATUS WM_USER + 3 +typedef struct tagLOCATIONITEM +{ + struct tagLOCATIONITEM *pNext; + WCHAR szPath[ANYSIZE_ARRAY]; +} LOCATIONITEM; + +void FreeList(LOCATIONITEM *pLI); + +struct ScopedFreeLocationItems +{ + LOCATIONITEM *m_ptr; + ScopedFreeLocationItems(LOCATIONITEM *ptr) : m_ptr(ptr) {} + ~ScopedFreeLocationItems() { FreeList(m_ptr); } + void Detach() { m_ptr = NULL; } +}; + struct SearchStart { - WCHAR szPath[MAX_PATH]; + LOCATIONITEM *pPaths; WCHAR szFileName[MAX_PATH]; WCHAR szQuery[MAX_PATH]; BOOL SearchHidden; }; +template +static INT_PTR FindItemInComboEx(HWND hCombo, T &FindItem, F CompareFunc, R RetMatch) +{ + COMBOBOXEXITEMW item; + item.mask = CBEIF_LPARAM; + item.cchTextMax = 0; + for (item.iItem = 0; SendMessageW(hCombo, CBEM_GETITEMW, 0, (LPARAM)&item); item.iItem++) + { + if (CompareFunc((T&)item.lParam, FindItem) == RetMatch) + return item.iItem; + } + return -1; +} + +static inline bool PathIsOnDrive(PCWSTR Path) +{ + return PathGetDriveNumberW(Path) >= 0 && (Path[2] == '\\' || !Path[2]); +} + +static inline BOOL PathIsOnUnc(PCWSTR Path) +{ + return PathIsUNCW(Path); // FIXME: Verify the path starts with <\\Server\Share>[\] +} + +static inline bool PathIsAbsolute(PCWSTR Path) +{ + // Note: PathIsRelativeW is too forgiving + return PathIsOnDrive(Path) || PathIsOnUnc(Path); +} + #endif /* _SHELLFIND_PCH_ */ diff --git a/dll/win32/cabinet/CMakeLists.txt b/dll/win32/cabinet/CMakeLists.txt index 042d0aa18428f..29704895d1a51 100644 --- a/dll/win32/cabinet/CMakeLists.txt +++ b/dll/win32/cabinet/CMakeLists.txt @@ -1,10 +1,8 @@ add_definitions( - -D__WINESRC__ -DHAVE_ZLIB) include_directories( - ${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine ${REACTOS_SOURCE_DIR}/sdk/include/reactos/libs/zlib) spec2def(cabinet.dll cabinet.spec ADD_IMPORTLIB) @@ -28,3 +26,4 @@ target_link_libraries(cabinet wine zlib) add_importlibs(cabinet msvcrt kernel32 ntdll) add_pch(cabinet precomp.h "${PCH_SKIP_SOURCE}") add_cd_file(TARGET cabinet DESTINATION reactos/system32 FOR all) +set_wine_module(cabinet) diff --git a/dll/win32/clusapi/CMakeLists.txt b/dll/win32/clusapi/CMakeLists.txt index b060e4b94df2f..86ff2e14c7589 100644 --- a/dll/win32/clusapi/CMakeLists.txt +++ b/dll/win32/clusapi/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(clusapi.dll clusapi.spec) list(APPEND SOURCE @@ -19,3 +17,4 @@ set_module_type(clusapi win32dll) target_link_libraries(clusapi wine) add_importlibs(clusapi msvcrt kernel32 ntdll) add_cd_file(TARGET clusapi DESTINATION reactos/system32 FOR all) +set_wine_module(clusapi) diff --git a/dll/win32/clusapi/clusapi.c b/dll/win32/clusapi/clusapi.c index 88c6fbfc12beb..e9de50ecc9030 100644 --- a/dll/win32/clusapi/clusapi.c +++ b/dll/win32/clusapi/clusapi.c @@ -124,8 +124,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { switch(fdwReason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls( hinstDLL ); break; diff --git a/dll/win32/comcat/CMakeLists.txt b/dll/win32/comcat/CMakeLists.txt index 0e5d6810106a2..2ec2ea1148945 100644 --- a/dll/win32/comcat/CMakeLists.txt +++ b/dll/win32/comcat/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(comcat.dll comcat.spec) list(APPEND SOURCE @@ -11,3 +9,4 @@ add_library(comcat MODULE ${SOURCE} version.rc) set_module_type(comcat win32dll) add_importlibs(comcat ole32 msvcrt kernel32) add_cd_file(TARGET comcat DESTINATION reactos/system32 FOR all) +set_wine_module(comcat) diff --git a/dll/win32/comctl32/CMakeLists.txt b/dll/win32/comctl32/CMakeLists.txt index 57baf681c0c82..b61bc4eb84e78 100644 --- a/dll/win32/comctl32/CMakeLists.txt +++ b/dll/win32/comctl32/CMakeLists.txt @@ -1,6 +1,5 @@ add_definitions( - -D__WINESRC__ -D_WINE -D__ROS_LONG64__ -D_COMCTL32_) @@ -8,7 +7,6 @@ add_definitions( remove_definitions(-D_WIN32_WINNT=0x502 -DWINVER=0x502) add_definitions(-D_WIN32_WINNT=0x600 -DWINVER=0x600) -include_directories(BEFORE ${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(comctl32.dll comctl32.spec ADD_IMPORTLIB) if(MSVC) @@ -82,3 +80,4 @@ add_cd_file(TARGET comctl32 DESTINATION reactos/winsxs/${WINARCH}_microsoft.wind add_cd_file(TARGET comctl32 DESTINATION reactos/winsxs/${WINARCH}_microsoft.windows.common-controls_6595b64144ccf1df_6.0.2600.2982_none_deadbeef FOR all) add_cd_file(FILE ${CMAKE_CURRENT_SOURCE_DIR}/${WINARCH}_microsoft.windows.common-controls_6595b64144ccf1df_5.82.2600.2982_none_deadbeef.manifest DESTINATION reactos/winsxs/manifests FOR all) add_cd_file(FILE ${CMAKE_CURRENT_SOURCE_DIR}/${WINARCH}_microsoft.windows.common-controls_6595b64144ccf1df_6.0.2600.2982_none_deadbeef.manifest DESTINATION reactos/winsxs/manifests FOR all) +set_wine_module_FIXME(comctl32) # CORE-5743: No ARRAY_SIZE macro diff --git a/dll/win32/comctl32/edit.c b/dll/win32/comctl32/edit.c index 767a63942f902..36286b92161e5 100644 --- a/dll/win32/comctl32/edit.c +++ b/dll/win32/comctl32/edit.c @@ -2591,7 +2591,11 @@ static void EDIT_EM_ReplaceSel(EDITSTATE *es, BOOL can_undo, const WCHAR *lpsz_r EDIT_CalcLineWidth_SL(es); /* remove chars that don't fit */ if (honor_limit && !(es->style & ES_AUTOHSCROLL) && (es->text_width > fw)) { +#ifdef __REACTOS__ + while ((es->text_width > fw) && s + strl > 0) { +#else while ((es->text_width > fw) && s + strl >= s) { +#endif lstrcpyW(es->text + s + strl - 1, es->text + s + strl); strl--; es->text_length = -1; diff --git a/dll/win32/comctl32/imagelist.c b/dll/win32/comctl32/imagelist.c index 8d74aac6ba623..1ebf0cf484eb5 100644 --- a/dll/win32/comctl32/imagelist.c +++ b/dll/win32/comctl32/imagelist.c @@ -112,12 +112,22 @@ struct _IMAGELIST BOOL color_table_set; LONG ref; /* reference count */ +#ifdef __REACTOS__ + USHORT usVersion; /* hack for IL from stream. Keep version here */ +#endif }; #define IMAGELIST_MAGIC 0x53414D58 #ifdef __REACTOS__ #define IMAGELIST_MAGIC_DESTROYED 0x44454144 -#endif +#define IMAGELIST_VERSION 0x101 + +#define WinVerMajor() LOBYTE(GetVersion()) + +#include +#define ILC_PUBLICFLAGS ( 0xFFFFFFFF ) /* Allow all flags for now */ +#define ILC_COLORMASK 0xFE +#endif /* __REACTOS__ */ /* Header used by ImageList_Read() and ImageList_Write() */ #include "pshpack2.h" @@ -841,6 +851,9 @@ ImageList_Create (INT cx, INT cy, UINT flags, himl->clrFg = CLR_DEFAULT; himl->clrBk = CLR_NONE; himl->color_table_set = FALSE; +#ifdef __REACTOS__ + himl->usVersion = 0; +#endif /* initialize overlay mask indices */ for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++) @@ -928,7 +941,12 @@ BOOL WINAPI ImageList_Destroy (HIMAGELIST himl) { if (!is_valid(himl)) - return FALSE; + return FALSE; + +#ifdef __REACTOS__ + if ((himl->flags & ILC_SYSTEM) && WinVerMajor() >= 6) + return FALSE; +#endif IImageList_Release((IImageList *) himl); return TRUE; @@ -1937,7 +1955,7 @@ ImageList_GetFlags(HIMAGELIST himl) #ifdef __REACTOS__ if(!is_valid2(himl)) return 0; - return himl->flags; + return himl->flags & ILC_PUBLICFLAGS; #else return is_valid(himl) ? himl->flags : 0; #endif @@ -2245,7 +2263,20 @@ ImageList_LoadImageW (HINSTANCE hi, LPCWSTR lpbmp, INT cx, INT cGrow, DeleteObject (handle); return NULL; } +#ifdef __REACTOS__ + if (clrMask == CLR_NONE) + nImageCount = ImageList_Add(himl, handle, NULL); + else + nImageCount = ImageList_AddMasked(himl, handle, clrMask); + + if (nImageCount < 0) + { + ImageList_Destroy(himl); + himl = NULL; + } +#else ImageList_AddMasked (himl, handle, clrMask); +#endif } else if ((uType == IMAGE_ICON) || (uType == IMAGE_CURSOR)) { ICONINFO ii; @@ -2477,7 +2508,13 @@ HIMAGELIST WINAPI ImageList_Read(IStream *pstm) return NULL; if (ilHead.usMagic != (('L' << 8) | 'I')) return NULL; +#ifdef __REACTOS__ + if (ilHead.usVersion != IMAGELIST_VERSION && + ilHead.usVersion != 0x600 && /* XP/2003 version */ + ilHead.usVersion != 0x620) /* Vista/7 version */ +#else if (ilHead.usVersion != 0x101) /* probably version? */ +#endif return NULL; TRACE("cx %u, cy %u, flags 0x%04x, cCurImage %u, cMaxImage %u\n", @@ -2487,6 +2524,11 @@ HIMAGELIST WINAPI ImageList_Read(IStream *pstm) if (!himl) return NULL; +#ifdef __REACTOS__ + /* keep version from stream */ + himl->usVersion = ilHead.usVersion; +#endif + if (!(image_bits = read_bitmap(pstm, image_info))) { WARN("failed to read bitmap from stream\n"); @@ -2506,17 +2548,34 @@ HIMAGELIST WINAPI ImageList_Read(IStream *pstm) { DWORD *ptr = image_bits; BYTE *mask_ptr = mask_bits; +#ifdef __REACTOS__ + int stride = himl->cy * (ilHead.usVersion != IMAGELIST_VERSION ? himl->cx : image_info->bmiHeader.biWidth); + int image_step = ilHead.usVersion != IMAGELIST_VERSION ? 1 : TILE_COUNT; + int mask_step = ilHead.usVersion != IMAGELIST_VERSION ? 4 : 8; +#else int stride = himl->cy * image_info->bmiHeader.biWidth; - +#endif if (image_info->bmiHeader.biHeight > 0) /* bottom-up */ { ptr += image_info->bmiHeader.biHeight * image_info->bmiHeader.biWidth - stride; +#ifdef __REACTOS__ + mask_ptr += (image_info->bmiHeader.biHeight * image_info->bmiHeader.biWidth - stride) / mask_step; +#else mask_ptr += (image_info->bmiHeader.biHeight * image_info->bmiHeader.biWidth - stride) / 8; +#endif stride = -stride; image_info->bmiHeader.biHeight = himl->cy; } else image_info->bmiHeader.biHeight = -himl->cy; - +#ifdef __REACTOS__ + for (i = 0; i < ilHead.cCurImage; i += image_step) + { + add_dib_bits(himl, i, min(ilHead.cCurImage - i, image_step), + himl->cx, himl->cy, image_info, mask_info, ptr, mask_ptr); + ptr += stride; + mask_ptr += stride / mask_step; + } +#else for (i = 0; i < ilHead.cCurImage; i += TILE_COUNT) { add_dib_bits( himl, i, min( ilHead.cCurImage - i, TILE_COUNT ), @@ -2524,6 +2583,7 @@ HIMAGELIST WINAPI ImageList_Read(IStream *pstm) ptr += stride; mask_ptr += stride / 8; } +#endif } else { @@ -3011,12 +3071,46 @@ ImageList_SetFilter (HIMAGELIST himl, INT i, DWORD dwFilter) * Stub. */ +#ifdef __REACTOS__ +static BOOL +ChangeColorDepth(HIMAGELIST himl) +{ + UINT ilc = himl->flags & ILC_COLORMASK; + if (ilc >= ILC_COLOR4 && ilc <= ILC_COLOR32) + himl->uBitsPixel = ilc; + else + himl->uBitsPixel = (UINT)GetDeviceCaps (himl->hdcImage, BITSPIXEL); + + /* Create new himl->hbmImage for BPP changes (for SHELL32) */ + return ((IImageList*)himl)->lpVtbl->SetImageCount((IImageList*)himl, 0) == S_OK; +} + +BOOL WINAPI +ImageList_SetFlags(HIMAGELIST himl, DWORD flags) +{ + if (!is_valid(himl)) + return FALSE; + + if (flags & ~ILC_PUBLICFLAGS) + return FALSE; + + if (((himl->flags ^ flags) & ILC_SYSTEM) && WinVerMajor() < 6) + return FALSE; /* Can't change this flag */ + + if (himl->flags == flags && WinVerMajor() >= 6) + return TRUE; + + himl->flags = flags; + return ChangeColorDepth(himl); +} +#else DWORD WINAPI ImageList_SetFlags(HIMAGELIST himl, DWORD flags) { FIXME("(%p %08x):empty stub\n", himl, flags); return 0; } +#endif /* __REACTOS__ */ /************************************************************************* diff --git a/dll/win32/comctl32/listbox.c b/dll/win32/comctl32/listbox.c index 804edeca47ae2..709a9a1241a50 100644 --- a/dll/win32/comctl32/listbox.c +++ b/dll/win32/comctl32/listbox.c @@ -611,6 +611,9 @@ static void LISTBOX_PaintItem( LB_DESCR *descr, HDC hdc, const RECT *rect, if (index < descr->nb_items) { item_str = get_item_string(descr, index); +#ifdef __REACTOS__ + if (!(descr->style & LBS_NOSEL)) +#endif selected = is_item_selected(descr, index); } diff --git a/dll/win32/comctl32/listview.c b/dll/win32/comctl32/listview.c index 5279c7b0d27b4..e9f8fd0b4404f 100644 --- a/dll/win32/comctl32/listview.c +++ b/dll/win32/comctl32/listview.c @@ -2270,11 +2270,7 @@ static void LISTVIEW_InvalidateSelectedItems(const LISTVIEW_INFO *infoPtr) iterator_frameditems(&i, infoPtr, &infoPtr->rcList); while(iterator_next(&i)) { -#ifdef __REACTOS__ - if (LISTVIEW_GetItemState(infoPtr, i.nItem, LVIS_SELECTED | LVIS_CUT)) -#else if (LISTVIEW_GetItemState(infoPtr, i.nItem, LVIS_SELECTED)) -#endif LISTVIEW_InvalidateItem(infoPtr, i.nItem); } iterator_destroy(&i); @@ -3729,8 +3725,10 @@ static void LISTVIEW_SetGroupSelection(LISTVIEW_INFO *infoPtr, INT nItem) item.state = LVIS_SELECTED; item.stateMask = LVIS_SELECTED; +#ifndef __REACTOS__ if ((infoPtr->uView == LV_VIEW_LIST) || (infoPtr->uView == LV_VIEW_DETAILS)) { +#endif if (infoPtr->nSelectionMark == -1) { infoPtr->nSelectionMark = nItem; @@ -3744,6 +3742,7 @@ static void LISTVIEW_SetGroupSelection(LISTVIEW_INFO *infoPtr, INT nItem) sel.upper = max(infoPtr->nSelectionMark, nItem) + 1; ranges_add(selection, sel); } +#ifndef __REACTOS__ } else { @@ -3769,6 +3768,7 @@ static void LISTVIEW_SetGroupSelection(LISTVIEW_INFO *infoPtr, INT nItem) } iterator_destroy(&i); } +#endif /* disable per item notifications on LVS_OWNERDATA style FIXME: single LVN_ODSTATECHANGED should be used */ @@ -4782,7 +4782,11 @@ static void LISTVIEW_DrawItemPart(LISTVIEW_INFO *infoPtr, LVITEMW *item, const N TRACE("iImage=%d\n", item->iImage); +#ifdef __REACTOS__ + if (item->state & (LVIS_CUT | (infoPtr->bFocus ? LVIS_SELECTED : 0))) +#else if (item->state & (LVIS_SELECTED | LVIS_CUT) && infoPtr->bFocus) +#endif style = ILD_SELECTED; else style = ILD_NORMAL; @@ -8552,8 +8556,13 @@ static BOOL LISTVIEW_SetColumnWidth(LISTVIEW_INFO *infoPtr, INT nColumn, INT cx) if (infoPtr->himlSmall && (nColumn == 0 || (LISTVIEW_GetColumnInfo(infoPtr, nColumn)->fmt & LVCFMT_IMAGE))) max_cx += infoPtr->iconSize.cx; max_cx += TRAILING_LABEL_PADDING; +#ifdef __REACTOS__ + if (nColumn == 0 && infoPtr->himlState) + max_cx += infoPtr->iconStateSize.cx; +#else if (nColumn == 0 && (infoPtr->dwLvExStyle & LVS_EX_CHECKBOXES)) max_cx += GetSystemMetrics(SM_CXSMICON); +#endif } /* autosize based on listview items width */ @@ -11997,7 +12006,36 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } return DefWindowProcW(hwnd, uMsg, wParam, lParam); +#ifdef __REACTOS__ + case WM_SETTINGCHANGE: /* Same as WM_WININICHANGE */ + if (wParam == SPI_SETICONMETRICS || + wParam == SPI_SETICONTITLELOGFONT || + wParam == SPI_SETNONCLIENTMETRICS || + (!wParam && !lParam)) + { + BOOL bDefaultOrNullFont = (infoPtr->hDefaultFont == infoPtr->hFont || !infoPtr->hFont); + LOGFONTW logFont; + SystemParametersInfoW(SPI_GETICONTITLELOGFONT, 0, &logFont, 0); + + if (infoPtr->autoSpacing) + LISTVIEW_SetIconSpacing(infoPtr, -1, -1); + + if (infoPtr->hDefaultFont) + DeleteObject(infoPtr->hDefaultFont); + infoPtr->hDefaultFont = CreateFontIndirectW(&logFont); + + if (bDefaultOrNullFont) + infoPtr->hFont = infoPtr->hDefaultFont; + + LISTVIEW_SaveTextMetrics(infoPtr); + LISTVIEW_UpdateItemSize(infoPtr); + LISTVIEW_UpdateScroll(infoPtr); + LISTVIEW_InvalidateRect(infoPtr, NULL); + } + return 0; +#else /* case WM_WININICHANGE: */ +#endif default: if ((uMsg >= WM_USER) && (uMsg < WM_APP) && !COMCTL32_IsReflectedMessage(uMsg)) diff --git a/dll/win32/comctl32/pager.c b/dll/win32/comctl32/pager.c index 4763ed5640daf..601be2fb74bae 100644 --- a/dll/win32/comctl32/pager.c +++ b/dll/win32/comctl32/pager.c @@ -86,6 +86,9 @@ typedef struct INT direction; /* direction of the scroll, (e.g. PGF_SCROLLUP) */ WCHAR *pwszBuffer;/* text buffer for converted notifications */ INT nBufferSize;/* size of the above buffer */ +#ifdef __REACTOS__ + BOOL m_bProcessingReCalcSize; +#endif } PAGER_INFO; #define TIMERID1 1 @@ -423,6 +426,15 @@ PAGER_RecalcSize(PAGER_INFO *infoPtr) { TRACE("[%p]\n", infoPtr->hwndSelf); +#ifdef __REACTOS__ + if (!infoPtr->m_bProcessingReCalcSize) + { + infoPtr->m_bProcessingReCalcSize = TRUE; + /* NOTE: Posting a recalc message to ourselves, not actually an edit control message */ + PostMessageW(infoPtr->hwndSelf, EM_FMTLINES, 0, 0); + } + return 0; +#else if (infoPtr->hwndChild) { INT scrollRange = PAGER_GetScrollRange(infoPtr, TRUE); @@ -437,6 +449,7 @@ PAGER_RecalcSize(PAGER_INFO *infoPtr) } return 1; +#endif } @@ -555,8 +568,15 @@ PAGER_Scroll(PAGER_INFO* infoPtr, INT dir) } static LRESULT +#ifdef __REACTOS__ +PAGER_FmtLines(PAGER_INFO *infoPtr) +#else PAGER_FmtLines(const PAGER_INFO *infoPtr) +#endif { +#ifdef __REACTOS__ + infoPtr->m_bProcessingReCalcSize = FALSE; +#endif /* initiate NCCalcSize to resize client wnd and get size */ SetWindowPos(infoPtr->hwndSelf, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | diff --git a/dll/win32/comdlg32/CMakeLists.txt b/dll/win32/comdlg32/CMakeLists.txt index 2516c4e2d22df..e8fc1d7b5d9bc 100644 --- a/dll/win32/comdlg32/CMakeLists.txt +++ b/dll/win32/comdlg32/CMakeLists.txt @@ -1,9 +1,8 @@ add_definitions( - -D__WINESRC__ - -D_WINE) + -D_WINE + -D__ROS_LONG64__) -include_directories(BEFORE ${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(comdlg32.dll comdlg32.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -31,3 +30,4 @@ add_delay_importlibs(comdlg32 ole32) add_importlibs(comdlg32 shell32 shlwapi comctl32 winspool user32 gdi32 advapi32 msvcrt kernel32 ntdll) add_pch(comdlg32 precomp.h SOURCE) add_cd_file(TARGET comdlg32 DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(comdlg32) # CORE-5743: No ARRAY_SIZE and CONST_VTABLE diff --git a/dll/win32/comdlg32/rsrc.rc b/dll/win32/comdlg32/rsrc.rc index efaec2a50240d..3b589a7c67d1c 100644 --- a/dll/win32/comdlg32/rsrc.rc +++ b/dll/win32/comdlg32/rsrc.rc @@ -42,7 +42,8 @@ * get localized bitmaps for example. */ -#pragma code_page(65001) // UTF-8 +/* UTF-8 */ +#pragma code_page(65001) #ifdef LANGUAGE_BG_BG #include "lang/cdlg_Bg.rc" diff --git a/dll/win32/compstui/CMakeLists.txt b/dll/win32/compstui/CMakeLists.txt index bb561428ef574..a7d13e983c2bb 100644 --- a/dll/win32/compstui/CMakeLists.txt +++ b/dll/win32/compstui/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(compstui.dll compstui.spec) list(APPEND SOURCE @@ -12,3 +10,4 @@ set_module_type(compstui win32dll) target_link_libraries(compstui wine) add_importlibs(compstui msvcrt kernel32 ntdll) add_cd_file(TARGET compstui DESTINATION reactos/system32 FOR all) +set_wine_module(compstui) diff --git a/dll/win32/compstui/compstui_main.c b/dll/win32/compstui/compstui_main.c index e05acdc0fad28..934ba07659351 100644 --- a/dll/win32/compstui/compstui_main.c +++ b/dll/win32/compstui/compstui_main.c @@ -40,8 +40,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) switch(fdwReason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls( hinstDLL ); diff --git a/dll/win32/credui/CMakeLists.txt b/dll/win32/credui/CMakeLists.txt index 6c2ec1d583f08..b638dce6bef5c 100644 --- a/dll/win32/credui/CMakeLists.txt +++ b/dll/win32/credui/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(credui.dll credui.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -13,3 +11,4 @@ set_module_type(credui win32dll) target_link_libraries(credui wine oldnames) add_importlibs(credui advapi32 user32 comctl32 msvcrt kernel32 ntdll) add_cd_file(TARGET credui DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(credui) # CORE-5743: No ARRAY_SIZE macro diff --git a/dll/win32/credui/credui_main.c b/dll/win32/credui/credui_main.c index 56789bc57d681..5684309bdb27e 100644 --- a/dll/win32/credui/credui_main.c +++ b/dll/win32/credui/credui_main.c @@ -74,8 +74,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) switch (fdwReason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hinstDLL); diff --git a/dll/win32/credui/lang/credui_Da.rc b/dll/win32/credui/lang/credui_Da.rc index 522037a4d3507..fab8e914c51d4 100644 --- a/dll/win32/credui/lang/credui_Da.rc +++ b/dll/win32/credui/lang/credui_Da.rc @@ -19,8 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_DANISH, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/credui/lang/credui_De.rc b/dll/win32/credui/lang/credui_De.rc index a8177d8dfb7e2..ede8139eb8ace 100644 --- a/dll/win32/credui/lang/credui_De.rc +++ b/dll/win32/credui/lang/credui_De.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/credui/lang/credui_Es.rc b/dll/win32/credui/lang/credui_Es.rc index fef58e72e203b..087d5825aa4ca 100644 --- a/dll/win32/credui/lang/credui_Es.rc +++ b/dll/win32/credui/lang/credui_Es.rc @@ -19,8 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/credui/lang/credui_Fr.rc b/dll/win32/credui/lang/credui_Fr.rc index e59b5f1c23f10..3f5cf64c186a8 100644 --- a/dll/win32/credui/lang/credui_Fr.rc +++ b/dll/win32/credui/lang/credui_Fr.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/credui/lang/credui_Hu.rc b/dll/win32/credui/lang/credui_Hu.rc index d47d24b899c8a..7aadcd3e907e8 100644 --- a/dll/win32/credui/lang/credui_Hu.rc +++ b/dll/win32/credui/lang/credui_Hu.rc @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/credui/lang/credui_It.rc b/dll/win32/credui/lang/credui_It.rc index 5889170325416..961d75066686f 100644 --- a/dll/win32/credui/lang/credui_It.rc +++ b/dll/win32/credui/lang/credui_It.rc @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/credui/lang/credui_Lt.rc b/dll/win32/credui/lang/credui_Lt.rc index f6cc96ddfcbb7..cb0db4b4a49cf 100644 --- a/dll/win32/credui/lang/credui_Lt.rc +++ b/dll/win32/credui/lang/credui_Lt.rc @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_LITHUANIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/credui/lang/credui_Pt.rc b/dll/win32/credui/lang/credui_Pt.rc index a5579fb1d1d0b..29cb751b38acf 100644 --- a/dll/win32/credui/lang/credui_Pt.rc +++ b/dll/win32/credui/lang/credui_Pt.rc @@ -19,8 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN STRINGTABLE diff --git a/dll/win32/credui/lang/credui_Ro.rc b/dll/win32/credui/lang/credui_Ro.rc index f032f1ab510db..941f8e349de27 100644 --- a/dll/win32/credui/lang/credui_Ro.rc +++ b/dll/win32/credui/lang/credui_Ro.rc @@ -19,8 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/credui/lang/credui_Ru.rc b/dll/win32/credui/lang/credui_Ru.rc index 504e2ad7546ff..6f319c57b4f41 100644 --- a/dll/win32/credui/lang/credui_Ru.rc +++ b/dll/win32/credui/lang/credui_Ru.rc @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/credui/lang/credui_Si.rc b/dll/win32/credui/lang/credui_Si.rc index 92041812a48a3..88d4570c425ac 100644 --- a/dll/win32/credui/lang/credui_Si.rc +++ b/dll/win32/credui/lang/credui_Si.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/credui/lang/credui_Uk.rc b/dll/win32/credui/lang/credui_Uk.rc index 50f7ed5a61c6e..a1dca8fd138c4 100644 --- a/dll/win32/credui/lang/credui_Uk.rc +++ b/dll/win32/credui/lang/credui_Uk.rc @@ -19,9 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/credui/lang/credui_Zh.rc b/dll/win32/credui/lang/credui_Zh.rc index 6dc6e702920b9..277a788491010 100644 --- a/dll/win32/credui/lang/credui_Zh.rc +++ b/dll/win32/credui/lang/credui_Zh.rc @@ -21,9 +21,6 @@ * Copyright 2021 Chan Chilung */ -/* Chinese text is encoded in UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED STRINGTABLE diff --git a/dll/win32/crypt32/CMakeLists.txt b/dll/win32/crypt32/CMakeLists.txt index 6796617d6247c..e5ee97541edad 100644 --- a/dll/win32/crypt32/CMakeLists.txt +++ b/dll/win32/crypt32/CMakeLists.txt @@ -3,14 +3,12 @@ remove_definitions(-D_WIN32_WINNT=0x502 -DWINVER=0x502) add_definitions(-D_WIN32_WINNT=0x600 -DWINVER=0x600) add_definitions( - -D__WINESRC__ -D__ROS_LONG64__ -D_WINE -D_CRYPT32_ -Dstrncasecmp=_strnicmp ) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(crypt32.dll crypt32.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -60,3 +58,4 @@ add_delay_importlibs(crypt32 cryptnet) add_importlibs(crypt32 bcrypt user32 advapi32 advapi32_vista msvcrt kernel32 ntdll) add_pch(crypt32 precomp.h "${PCH_SKIP_SOURCE}") add_cd_file(TARGET crypt32 DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(crypt32) # CORE-5743: No ARRAY_SIZE macro diff --git a/dll/win32/crypt32/crypt32.spec b/dll/win32/crypt32/crypt32.spec index fc32570b52e3d..9754b0296cd3a 100644 --- a/dll/win32/crypt32/crypt32.spec +++ b/dll/win32/crypt32/crypt32.spec @@ -39,6 +39,7 @@ @ stdcall CertEnumCertificatesInStore(ptr ptr) @ stdcall CertEnumPhysicalStore(ptr long ptr ptr) @ stdcall CertEnumSystemStore(long ptr ptr ptr) +@ stdcall CertEnumSystemStoreLocation(long ptr ptr) @ stdcall CertFindAttribute(str long ptr) @ stdcall CertFindCRLInStore(ptr long long long ptr ptr) @ stdcall CertFindCTLInStore(ptr long long long ptr ptr) diff --git a/dll/win32/crypt32/store.c b/dll/win32/crypt32/store.c index 2b8ea1d5d82aa..c89d414a2c037 100644 --- a/dll/win32/crypt32/store.c +++ b/dll/win32/crypt32/store.c @@ -1358,6 +1358,61 @@ BOOL WINAPI CertEnumSystemStore(DWORD dwFlags, void *pvSystemStoreLocationPara, return ret; } +#ifdef __REACTOS__ + +typedef struct _CERT_SYSTEM_STORE_LOCATION +{ + DWORD dwFlags; + PCWSTR pwszStoreLocation; +} CERT_SYSTEM_STORE_LOCATION, *PCERT_SYSTEM_STORE_LOCATION; + +static const CERT_SYSTEM_STORE_LOCATION gSystemStoreLocations[] = { + { CERT_SYSTEM_STORE_CURRENT_USER, L"CurrentUser" }, + { CERT_SYSTEM_STORE_LOCAL_MACHINE, L"LocalMachine" }, + { CERT_SYSTEM_STORE_CURRENT_SERVICE, L"CurrentService" }, + { CERT_SYSTEM_STORE_SERVICES, L"Services" }, + { CERT_SYSTEM_STORE_USERS, L"Users" }, + { CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY, L"CurrentUserGroupPolicy" }, + { CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY, L"LocalMachineGroupPolicy" }, + { CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE, L"LocalMachineEnterprise" }, +}; + +BOOL +WINAPI +CertEnumSystemStoreLocation( + _In_ DWORD dwFlags, + _Inout_opt_ void *pvArg, + __callback PFN_CERT_ENUM_SYSTEM_STORE_LOCATION pfnEnum) +{ + DWORD i; + + /* Check input flags */ + if (dwFlags != 0) + { + SetLastError(E_INVALIDARG); + return FALSE; + } + + /* Return fixed system stores */ + for (i = 0; i < ARRAYSIZE(gSystemStoreLocations); i++) + { + if (!pfnEnum(gSystemStoreLocations[i].pwszStoreLocation, + gSystemStoreLocations[i].dwFlags, + NULL, + pvArg)) + { + return FALSE; + } + } + + /* FIXME: Return registered OID system stores by calling CryptEnumOIDFunction */ + FIXME("Registered OID system stores is not enumerated\n"); + + return TRUE; +} + +#endif /* __REACTOS__ */ + BOOL WINAPI CertEnumPhysicalStore(const void *pvSystemStore, DWORD dwFlags, void *pvArg, PFN_CERT_ENUM_PHYSICAL_STORE pfnEnum) { diff --git a/dll/win32/cryptdlg/CMakeLists.txt b/dll/win32/cryptdlg/CMakeLists.txt index 0ce55339078c8..11eabe33dd20e 100644 --- a/dll/win32/cryptdlg/CMakeLists.txt +++ b/dll/win32/cryptdlg/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(cryptdlg.dll cryptdlg.spec) list(APPEND SOURCE @@ -13,3 +11,4 @@ set_module_type(cryptdlg win32dll) target_link_libraries(cryptdlg wine) add_importlibs(cryptdlg advapi32 user32 crypt32 cryptui wintrust msvcrt kernel32 ntdll) add_cd_file(TARGET cryptdlg DESTINATION reactos/system32 FOR all) +set_wine_module(cryptdlg) diff --git a/dll/win32/cryptdlg/lang/cryptdlg_De.rc b/dll/win32/cryptdlg/lang/cryptdlg_De.rc index 6550e199d5329..5d543066a1264 100644 --- a/dll/win32/cryptdlg/lang/cryptdlg_De.rc +++ b/dll/win32/cryptdlg/lang/cryptdlg_De.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/cryptdlg/lang/cryptdlg_Fr.rc b/dll/win32/cryptdlg/lang/cryptdlg_Fr.rc index 76b933f14c4e4..1ff68556bd63b 100644 --- a/dll/win32/cryptdlg/lang/cryptdlg_Fr.rc +++ b/dll/win32/cryptdlg/lang/cryptdlg_Fr.rc @@ -19,9 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/cryptdlg/lang/cryptdlg_Hu.rc b/dll/win32/cryptdlg/lang/cryptdlg_Hu.rc index 59860508291c8..8b62e041d0a80 100644 --- a/dll/win32/cryptdlg/lang/cryptdlg_Hu.rc +++ b/dll/win32/cryptdlg/lang/cryptdlg_Hu.rc @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/cryptdlg/lang/cryptdlg_It.rc b/dll/win32/cryptdlg/lang/cryptdlg_It.rc index 0c29429e66cab..2786b4c4f2e41 100644 --- a/dll/win32/cryptdlg/lang/cryptdlg_It.rc +++ b/dll/win32/cryptdlg/lang/cryptdlg_It.rc @@ -19,9 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/cryptdlg/lang/cryptdlg_Lt.rc b/dll/win32/cryptdlg/lang/cryptdlg_Lt.rc index 9b38e5c9e0b49..b856baf0778dd 100644 --- a/dll/win32/cryptdlg/lang/cryptdlg_Lt.rc +++ b/dll/win32/cryptdlg/lang/cryptdlg_Lt.rc @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_LITHUANIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/cryptdlg/lang/cryptdlg_No.rc b/dll/win32/cryptdlg/lang/cryptdlg_No.rc index ae58f2532049c..3eaa6a74a1a60 100644 --- a/dll/win32/cryptdlg/lang/cryptdlg_No.rc +++ b/dll/win32/cryptdlg/lang/cryptdlg_No.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL STRINGTABLE diff --git a/dll/win32/cryptdlg/lang/cryptdlg_Pt.rc b/dll/win32/cryptdlg/lang/cryptdlg_Pt.rc index 81adca17db74b..b7ac445c6a88b 100644 --- a/dll/win32/cryptdlg/lang/cryptdlg_Pt.rc +++ b/dll/win32/cryptdlg/lang/cryptdlg_Pt.rc @@ -19,8 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN STRINGTABLE diff --git a/dll/win32/cryptdlg/lang/cryptdlg_Ro.rc b/dll/win32/cryptdlg/lang/cryptdlg_Ro.rc index 3c448e3bd8c11..7b68be9e20bd4 100644 --- a/dll/win32/cryptdlg/lang/cryptdlg_Ro.rc +++ b/dll/win32/cryptdlg/lang/cryptdlg_Ro.rc @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/cryptdlg/lang/cryptdlg_Ru.rc b/dll/win32/cryptdlg/lang/cryptdlg_Ru.rc index 0991cceb7a093..518d8d1c81b34 100644 --- a/dll/win32/cryptdlg/lang/cryptdlg_Ru.rc +++ b/dll/win32/cryptdlg/lang/cryptdlg_Ru.rc @@ -19,9 +19,6 @@ */ /* Russian language resource file by Kudratov Olimjon (olim98@bk.ru) */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/cryptdlg/lang/cryptdlg_Uk.rc b/dll/win32/cryptdlg/lang/cryptdlg_Uk.rc index 4248eb4c65e75..acf86c6454c75 100644 --- a/dll/win32/cryptdlg/lang/cryptdlg_Uk.rc +++ b/dll/win32/cryptdlg/lang/cryptdlg_Uk.rc @@ -19,9 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/cryptdlg/lang/cryptdlg_Zh.rc b/dll/win32/cryptdlg/lang/cryptdlg_Zh.rc index 918c75b115264..815dfa758862a 100644 --- a/dll/win32/cryptdlg/lang/cryptdlg_Zh.rc +++ b/dll/win32/cryptdlg/lang/cryptdlg_Zh.rc @@ -21,9 +21,6 @@ * Copyright 2021 Chan Chilung */ -/* Chinese text is encoded in UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED STRINGTABLE diff --git a/dll/win32/cryptdlg/main.c b/dll/win32/cryptdlg/main.c index 5a3e6bf418fec..79cb64b57593b 100644 --- a/dll/win32/cryptdlg/main.c +++ b/dll/win32/cryptdlg/main.c @@ -46,8 +46,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) switch (fdwReason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hinstDLL); hInstance = hinstDLL; diff --git a/dll/win32/cryptdll/CMakeLists.txt b/dll/win32/cryptdll/CMakeLists.txt index 8d64df81d03dd..fde99f4b5c4f5 100644 --- a/dll/win32/cryptdll/CMakeLists.txt +++ b/dll/win32/cryptdll/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(cryptdll.dll cryptdll.spec) list(APPEND SOURCE @@ -13,3 +11,4 @@ set_module_type(cryptdll win32dll) target_link_libraries(cryptdll wine) add_importlibs(cryptdll advapi32 msvcrt kernel32 ntdll) add_cd_file(TARGET cryptdll DESTINATION reactos/system32 FOR all) +set_wine_module(cryptdll) diff --git a/dll/win32/cryptdll/cryptdll.c b/dll/win32/cryptdll/cryptdll.c index 963a2684e08e5..3f1e438d02c5e 100644 --- a/dll/win32/cryptdll/cryptdll.c +++ b/dll/win32/cryptdll/cryptdll.c @@ -29,8 +29,10 @@ BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) TRACE("%p,%x,%p\n", hinstDLL, fdwReason, lpvReserved); switch (fdwReason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hinstDLL); break; diff --git a/dll/win32/cryptnet/CMakeLists.txt b/dll/win32/cryptnet/CMakeLists.txt index 9bbb47e694ac8..9657cc7fdfa4b 100644 --- a/dll/win32/cryptnet/CMakeLists.txt +++ b/dll/win32/cryptnet/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(cryptnet.dll cryptnet.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -14,3 +12,4 @@ target_link_libraries(cryptnet wine) add_delay_importlibs(cryptnet wininet) add_importlibs(cryptnet crypt32 msvcrt kernel32 ntdll) add_cd_file(TARGET cryptnet DESTINATION reactos/system32 FOR all) +set_wine_module(cryptnet) diff --git a/dll/win32/cryptui/CMakeLists.txt b/dll/win32/cryptui/CMakeLists.txt index 92ab7aaed0dc0..ea6501c2989a7 100644 --- a/dll/win32/cryptui/CMakeLists.txt +++ b/dll/win32/cryptui/CMakeLists.txt @@ -1,7 +1,7 @@ add_definitions( - -D__WINESRC__ - -D_WINE) + -D_WINE + -D__ROS_LONG64__) include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(cryptui.dll cryptui.spec ADD_IMPORTLIB) @@ -17,3 +17,4 @@ target_link_libraries(cryptui uuid wine oldnames) add_delay_importlibs(cryptui urlmon wintrust) add_importlibs(cryptui user32 ole32 crypt32 gdi32 advapi32 comctl32 comdlg32 msvcrt kernel32 ntdll) add_cd_file(TARGET cryptui DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(cryptui) # CORE-5743: No ARRAY_SIZE macro diff --git a/dll/win32/cryptui/lang/cryptui_Bg.rc b/dll/win32/cryptui/lang/cryptui_Bg.rc index bdb5a2d404a48..0a7291956503d 100644 --- a/dll/win32/cryptui/lang/cryptui_Bg.rc +++ b/dll/win32/cryptui/lang/cryptui_Bg.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "cryptuires.h" - LANGUAGE LANG_BULGARIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/cryptui/lang/cryptui_De.rc b/dll/win32/cryptui/lang/cryptui_De.rc index 562f6f3ea8949..b05f3d18307c4 100644 --- a/dll/win32/cryptui/lang/cryptui_De.rc +++ b/dll/win32/cryptui/lang/cryptui_De.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "cryptuires.h" - LANGUAGE LANG_GERMAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/cryptui/lang/cryptui_En.rc b/dll/win32/cryptui/lang/cryptui_En.rc index d20f90ba006e5..1e4d5cb669501 100644 --- a/dll/win32/cryptui/lang/cryptui_En.rc +++ b/dll/win32/cryptui/lang/cryptui_En.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "cryptuires.h" - LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/cryptui/lang/cryptui_Fr.rc b/dll/win32/cryptui/lang/cryptui_Fr.rc index 57d074348fb9c..dada7f34074f4 100644 --- a/dll/win32/cryptui/lang/cryptui_Fr.rc +++ b/dll/win32/cryptui/lang/cryptui_Fr.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "cryptuires.h" - LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/cryptui/lang/cryptui_He.rc b/dll/win32/cryptui/lang/cryptui_He.rc index 52ffd73ac4b87..c875aeefcb6f1 100644 --- a/dll/win32/cryptui/lang/cryptui_He.rc +++ b/dll/win32/cryptui/lang/cryptui_He.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "cryptuires.h" - LANGUAGE LANG_HEBREW, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/cryptui/lang/cryptui_It.rc b/dll/win32/cryptui/lang/cryptui_It.rc index 5fd8333dc0c91..841fcac705708 100644 --- a/dll/win32/cryptui/lang/cryptui_It.rc +++ b/dll/win32/cryptui/lang/cryptui_It.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "cryptuires.h" - LANGUAGE LANG_ITALIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/cryptui/lang/cryptui_Ko.rc b/dll/win32/cryptui/lang/cryptui_Ko.rc index 1298663d96e21..2b1cda75b3f88 100644 --- a/dll/win32/cryptui/lang/cryptui_Ko.rc +++ b/dll/win32/cryptui/lang/cryptui_Ko.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "cryptuires.h" - LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/cryptui/lang/cryptui_Lt.rc b/dll/win32/cryptui/lang/cryptui_Lt.rc index 2cfb5ea477193..9b49dca869d81 100644 --- a/dll/win32/cryptui/lang/cryptui_Lt.rc +++ b/dll/win32/cryptui/lang/cryptui_Lt.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "cryptuires.h" - LANGUAGE LANG_LITHUANIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/cryptui/lang/cryptui_Nl.rc b/dll/win32/cryptui/lang/cryptui_Nl.rc index bfb7d54677f8c..a5e7705e6efa6 100644 --- a/dll/win32/cryptui/lang/cryptui_Nl.rc +++ b/dll/win32/cryptui/lang/cryptui_Nl.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "cryptuires.h" - LANGUAGE LANG_DUTCH, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/cryptui/lang/cryptui_No.rc b/dll/win32/cryptui/lang/cryptui_No.rc index 5ffbd88085468..d773603891e6f 100644 --- a/dll/win32/cryptui/lang/cryptui_No.rc +++ b/dll/win32/cryptui/lang/cryptui_No.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "cryptuires.h" - LANGUAGE LANG_NORWEGIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/cryptui/lang/cryptui_Pl.rc b/dll/win32/cryptui/lang/cryptui_Pl.rc index cb0a3e19fe626..9a4e3bd67dd26 100644 --- a/dll/win32/cryptui/lang/cryptui_Pl.rc +++ b/dll/win32/cryptui/lang/cryptui_Pl.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "cryptuires.h" - LANGUAGE LANG_POLISH, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/cryptui/lang/cryptui_Pt.rc b/dll/win32/cryptui/lang/cryptui_Pt.rc index d00f43016571c..3da42cd642691 100644 --- a/dll/win32/cryptui/lang/cryptui_Pt.rc +++ b/dll/win32/cryptui/lang/cryptui_Pt.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "cryptuires.h" - LANGUAGE LANG_PORTUGUESE, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/cryptui/lang/cryptui_Ro.rc b/dll/win32/cryptui/lang/cryptui_Ro.rc index 0d490f78b6213..c4fa60015a38f 100644 --- a/dll/win32/cryptui/lang/cryptui_Ro.rc +++ b/dll/win32/cryptui/lang/cryptui_Ro.rc @@ -22,8 +22,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "cryptuires.h" - LANGUAGE LANG_ROMANIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/cryptui/lang/cryptui_Ru.rc b/dll/win32/cryptui/lang/cryptui_Ru.rc index a7c71c2ab97f5..5bd0becef11ca 100644 --- a/dll/win32/cryptui/lang/cryptui_Ru.rc +++ b/dll/win32/cryptui/lang/cryptui_Ru.rc @@ -20,8 +20,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "cryptuires.h" - LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/cryptui/lang/cryptui_Sq.rc b/dll/win32/cryptui/lang/cryptui_Sq.rc index 4051dee27dd76..67dabbd0fa39f 100644 --- a/dll/win32/cryptui/lang/cryptui_Sq.rc +++ b/dll/win32/cryptui/lang/cryptui_Sq.rc @@ -19,8 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "cryptuires.h" - LANGUAGE LANG_ALBANIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/cryptui/lang/cryptui_Tr.rc b/dll/win32/cryptui/lang/cryptui_Tr.rc index 7ff03ccc66601..acdd95038bd0f 100644 --- a/dll/win32/cryptui/lang/cryptui_Tr.rc +++ b/dll/win32/cryptui/lang/cryptui_Tr.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "cryptuires.h" - LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/cryptui/lang/cryptui_Uk.rc b/dll/win32/cryptui/lang/cryptui_Uk.rc index 3f95e2b8ce9f1..6c4166fafd2bb 100644 --- a/dll/win32/cryptui/lang/cryptui_Uk.rc +++ b/dll/win32/cryptui/lang/cryptui_Uk.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "cryptuires.h" - LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/cryptui/lang/cryptui_Zh.rc b/dll/win32/cryptui/lang/cryptui_Zh.rc index 24f1089ff42a5..acc1bf434a342 100644 --- a/dll/win32/cryptui/lang/cryptui_Zh.rc +++ b/dll/win32/cryptui/lang/cryptui_Zh.rc @@ -21,11 +21,6 @@ * Copyright 2021 Chan Chilung */ -#include "cryptuires.h" - -/* Chinese text is encoded in UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED STRINGTABLE diff --git a/dll/win32/cryptui/main.c b/dll/win32/cryptui/main.c index 75f55df1c1702..c39ab5ed82a59 100644 --- a/dll/win32/cryptui/main.c +++ b/dll/win32/cryptui/main.c @@ -52,8 +52,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) switch (fdwReason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: hInstance = hinstDLL; DisableThreadLibraryCalls(hinstDLL); diff --git a/dll/win32/dbgeng/CMakeLists.txt b/dll/win32/dbgeng/CMakeLists.txt index 9270aead99fbd..a83ad63897e3c 100644 --- a/dll/win32/dbgeng/CMakeLists.txt +++ b/dll/win32/dbgeng/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(dbgeng.dll dbgeng.spec) list(APPEND SOURCE @@ -14,3 +12,4 @@ target_link_libraries(dbgeng wine) add_importlibs(dbgeng psapi msvcrt ntdll) add_delay_importlibs(dbgeng version) add_cd_file(TARGET dbgeng DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(dbgeng) # CORE-5743: No ARRAY_SIZE and CONST_VTABLE diff --git a/dll/win32/dbghelp/CMakeLists.txt b/dll/win32/dbghelp/CMakeLists.txt index 8f12ce938087f..6f2e8fc19d03d 100644 --- a/dll/win32/dbghelp/CMakeLists.txt +++ b/dll/win32/dbghelp/CMakeLists.txt @@ -26,7 +26,6 @@ if(NOT CMAKE_CROSSCOMPILING) target_link_libraries(dbghelphost PRIVATE host_includes) else() add_definitions( - -D__WINESRC__ -D_WINE -DHAVE_ALLOCA_H -D_IMAGEHLP_SOURCE_) @@ -75,6 +74,7 @@ else() add_importlibs(dbghelp psapi msvcrt kernel32 ntdll) add_pch(dbghelp precomp.h SOURCE) add_cd_file(TARGET dbghelp DESTINATION reactos/system32 FOR all) + set_wine_module_FIXME(dbghelp) # CORE-5743: No ARRAY_SIZE macro if(MSVC) # Disable warning C4146: unary minus operator applied to unsigned type, result still unsigned diff --git a/dll/win32/dciman32/CMakeLists.txt b/dll/win32/dciman32/CMakeLists.txt index 5cd47dbec951b..5392ad7e3eb14 100644 --- a/dll/win32/dciman32/CMakeLists.txt +++ b/dll/win32/dciman32/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(dciman32.dll dciman32.spec) list(APPEND SOURCE @@ -13,3 +11,4 @@ set_module_type(dciman32 win32dll) target_link_libraries(dciman32 wine) add_importlibs(dciman32 msvcrt kernel32 ntdll) add_cd_file(TARGET dciman32 DESTINATION reactos/system32 FOR all) +set_wine_module(dciman32) diff --git a/dll/win32/devmgr/api.cpp b/dll/win32/devmgr/api.cpp index c128d1055a8e3..7f0c1699e1804 100644 --- a/dll/win32/devmgr/api.cpp +++ b/dll/win32/devmgr/api.cpp @@ -9,7 +9,7 @@ * NOTES: * Some helpful resources: * http://support.microsoft.com/default.aspx?scid=kb;%5BLN%5D;815320 -* http://www.jsiinc.com/SUBO/tip7400/rh7482.htm +* https://web.archive.org/web/20050321020634/http://www.jsifaq.com/SUBO/tip7400/rh7482.htm * http://www.jsiinc.com/SUBM/tip6400/rh6490.htm * * UPDATE HISTORY: diff --git a/dll/win32/devmgr/devmgr.rc b/dll/win32/devmgr/devmgr.rc index ac4f33ea7ec17..c338d67878ee2 100644 --- a/dll/win32/devmgr/devmgr.rc +++ b/dll/win32/devmgr/devmgr.rc @@ -18,7 +18,7 @@ IDI_MAIN_ICON ICON "resources/computer.ico" IDB_ROOT_IMAGE BITMAP "resources/root.bmp" /* main toolbar icons */ -IDB_TOOLBAR BITMAP DISCARDABLE "resources/toolbar.bmp" +IDB_TOOLBAR BITMAP "resources/toolbar.bmp" /* UTF-8 */ diff --git a/dll/win32/devmgr/lang/bg-BG.rc b/dll/win32/devmgr/lang/bg-BG.rc index 7fc1b01d60b78..d421c69316c0d 100644 --- a/dll/win32/devmgr/lang/bg-BG.rc +++ b/dll/win32/devmgr/lang/bg-BG.rc @@ -286,14 +286,15 @@ BEGIN END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_APPNAME "ReactOS Device Manager" IDS_APP_AUTHORS "Copyright 2015 Ged Murphy" IDS_CONFIRM_DISABLE "Disabling this device will cause it to stop functioning.\nDo you really want to disable it?" IDS_CONFIRM_UNINSTALL "Warning: You are about to uninstall this device from your system.\nDo you want to continue?" END -STRINGTABLE DISCARDABLE + +STRINGTABLE BEGIN IDS_MENU_UPDATE "Update driver software..." IDS_MENU_ENABLE "Enable" @@ -304,7 +305,7 @@ BEGIN IDS_MENU_PROPERTIES "Properties" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_PROPERTIES "Properties" IDS_TOOLTIP_SCAN "Scan for hardware changes" @@ -315,7 +316,7 @@ BEGIN END /* Hints */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_PROPERTIES " Open property dialog for the current selection." diff --git a/dll/win32/devmgr/lang/cs-CZ.rc b/dll/win32/devmgr/lang/cs-CZ.rc index eac630946e47e..2f0afd87efa50 100644 --- a/dll/win32/devmgr/lang/cs-CZ.rc +++ b/dll/win32/devmgr/lang/cs-CZ.rc @@ -290,14 +290,15 @@ BEGIN END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_APPNAME "Správce zařízení ReactOS" IDS_APP_AUTHORS "Copyright 2015 Ged Murphy" IDS_CONFIRM_DISABLE "Zakázáním tohoto zařízení dojde k ukončení jeho činnosti.\nOpravdu si jej přejete zakázat?" IDS_CONFIRM_UNINSTALL "Varování: Chystáte se odebrat toto zařízení ze systému.\nPřejete si pokračovat?" END -STRINGTABLE DISCARDABLE + +STRINGTABLE BEGIN IDS_MENU_UPDATE "Aktualizovat software ovladače..." IDS_MENU_ENABLE "Povolit" @@ -308,7 +309,7 @@ BEGIN IDS_MENU_PROPERTIES "Vlastnosti" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_PROPERTIES "Vlastnosti" IDS_TOOLTIP_SCAN "Vyhledat změny hardwaru" @@ -319,7 +320,7 @@ BEGIN END /* Hints */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_PROPERTIES " Otevře seznam vlastností pro vybrané zařízení." diff --git a/dll/win32/devmgr/lang/de-DE.rc b/dll/win32/devmgr/lang/de-DE.rc index 1e341dcc2a09e..4d9ab57721543 100644 --- a/dll/win32/devmgr/lang/de-DE.rc +++ b/dll/win32/devmgr/lang/de-DE.rc @@ -286,14 +286,15 @@ BEGIN END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_APPNAME "ReactOS Geräte-Manager" IDS_APP_AUTHORS "Copyright 2015 Ged Murphy" IDS_CONFIRM_DISABLE "Dieses Gerät zu deaktivieren wird dessen Funktion einstellen.\nWollen Sie es wirklich deaktivieren?" IDS_CONFIRM_UNINSTALL "Warnung: Sie sind dabei, dieses Gerät deinstallieren\nMöchten Sie den Vorgang fortsetzen?" END -STRINGTABLE DISCARDABLE + +STRINGTABLE BEGIN IDS_MENU_UPDATE "Treibersoftware aktualisieren ..." IDS_MENU_ENABLE "Aktivieren" @@ -304,7 +305,7 @@ BEGIN IDS_MENU_PROPERTIES "Eigenschaften" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_PROPERTIES "Eigenschaften" IDS_TOOLTIP_SCAN "Nach geänderter Hardware suchen" @@ -315,7 +316,7 @@ BEGIN END /* Hints */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_PROPERTIES " Öffnet Eigenschaftsdialog für die aktuelle Auswahl." diff --git a/dll/win32/devmgr/lang/el-GR.rc b/dll/win32/devmgr/lang/el-GR.rc index c6b70a7b3aec7..8e1e00c476c0b 100644 --- a/dll/win32/devmgr/lang/el-GR.rc +++ b/dll/win32/devmgr/lang/el-GR.rc @@ -287,14 +287,15 @@ BEGIN END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_APPNAME "ReactOS Device Manager" IDS_APP_AUTHORS "Copyright 2015 Ged Murphy" IDS_CONFIRM_DISABLE "Disabling this device will cause it to stop functioning.\nDo you really want to disable it?" IDS_CONFIRM_UNINSTALL "Warning: You are about to uninstall this device from your system.\nDo you want to continue?" END -STRINGTABLE DISCARDABLE + +STRINGTABLE BEGIN IDS_MENU_UPDATE "Update driver software..." IDS_MENU_ENABLE "Enable" @@ -305,7 +306,7 @@ BEGIN IDS_MENU_PROPERTIES "Properties" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_PROPERTIES "Properties" IDS_TOOLTIP_SCAN "Scan for hardware changes" @@ -316,7 +317,7 @@ BEGIN END /* Hints */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_PROPERTIES " Open property dialog for the current selection." diff --git a/dll/win32/devmgr/lang/en-US.rc b/dll/win32/devmgr/lang/en-US.rc index c2da4b467ce7a..530d735a414c9 100644 --- a/dll/win32/devmgr/lang/en-US.rc +++ b/dll/win32/devmgr/lang/en-US.rc @@ -285,14 +285,15 @@ BEGIN END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_APPNAME "ReactOS Device Manager" IDS_APP_AUTHORS "Copyright 2015 Ged Murphy" IDS_CONFIRM_DISABLE "Disabling this device will cause it to stop functioning.\nDo you really want to disable it?" IDS_CONFIRM_UNINSTALL "Warning: You are about to uninstall this device from your system.\nDo you want to continue?" END -STRINGTABLE DISCARDABLE + +STRINGTABLE BEGIN IDS_MENU_UPDATE "Update driver software..." IDS_MENU_ENABLE "Enable" @@ -303,7 +304,7 @@ BEGIN IDS_MENU_PROPERTIES "Properties" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_PROPERTIES "Properties" IDS_TOOLTIP_SCAN "Scan for hardware changes" @@ -314,7 +315,7 @@ BEGIN END /* Hints */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_PROPERTIES " Open property dialog for the current selection." diff --git a/dll/win32/devmgr/lang/es-ES.rc b/dll/win32/devmgr/lang/es-ES.rc index 41b898b2dbb35..3a9cf882a2083 100644 --- a/dll/win32/devmgr/lang/es-ES.rc +++ b/dll/win32/devmgr/lang/es-ES.rc @@ -294,14 +294,15 @@ BEGIN END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_APPNAME "Administrador de dispositivos de ReactOS" IDS_APP_AUTHORS "Copyright 2015 Ged Murphy" IDS_CONFIRM_DISABLE "Deshabilitar este dispositivo hará que deje de funcionar.\n¿Seguro que quiere deshabilitarlo?" IDS_CONFIRM_UNINSTALL "Advertencia: Está a punto de desinstalar este dispositivo de su equipo.\n¿Seguro que quiere continuar?" END -STRINGTABLE DISCARDABLE + +STRINGTABLE BEGIN IDS_MENU_UPDATE "Actualizar controladores..." IDS_MENU_ENABLE "Habilitar" @@ -312,7 +313,7 @@ BEGIN IDS_MENU_PROPERTIES "Propiedades" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_PROPERTIES "Propiedades" IDS_TOOLTIP_SCAN "Buscar cambios de hardware" @@ -323,7 +324,7 @@ BEGIN END /* Hints */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_PROPERTIES " Abre el diálogo de propiedades para le selección actual." diff --git a/dll/win32/devmgr/lang/et-EE.rc b/dll/win32/devmgr/lang/et-EE.rc index 85cb255a969b6..3759f9f200134 100644 --- a/dll/win32/devmgr/lang/et-EE.rc +++ b/dll/win32/devmgr/lang/et-EE.rc @@ -292,14 +292,15 @@ BEGIN END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_APPNAME "ReactOS Seadmehaldur" IDS_APP_AUTHORS "Copyright 2015 Ged Murphy" IDS_CONFIRM_DISABLE "Selle seadme keelamine põhjustab selle töötamise lakkamise.\nKas soovite kindlasti seda keelata?" IDS_CONFIRM_UNINSTALL "Hoiatus: Hakkate seda seadet süsteemist desinstallima.\nKas soovite jätkata?" END -STRINGTABLE DISCARDABLE + +STRINGTABLE BEGIN IDS_MENU_UPDATE "Draiveritarkvara värskendamine..." IDS_MENU_ENABLE "Luba" @@ -310,7 +311,7 @@ BEGIN IDS_MENU_PROPERTIES "Atribuudid" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_PROPERTIES "Atribuudid" IDS_TOOLTIP_SCAN "Otsi riistvaramuudatusi" @@ -321,7 +322,7 @@ BEGIN END /* Hints */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_PROPERTIES " Avab antud valike atribuudilehe." diff --git a/dll/win32/devmgr/lang/fr-FR.rc b/dll/win32/devmgr/lang/fr-FR.rc index ea9155328e223..8a8fe52747729 100644 --- a/dll/win32/devmgr/lang/fr-FR.rc +++ b/dll/win32/devmgr/lang/fr-FR.rc @@ -286,14 +286,15 @@ BEGIN END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_APPNAME "Gestionnaire de périphériques ReactOS" IDS_APP_AUTHORS "Copyright 2015 Ged Murphy" IDS_CONFIRM_DISABLE "Désactiver ce périphérique va le rendre inopérant.\nVoulez-vous réellement le désactiver ?" IDS_CONFIRM_UNINSTALL "Attention : vous êtes sur le point de désinstaller ce périphérique de votre système.\nVoulez-vous continuer ?" END -STRINGTABLE DISCARDABLE + +STRINGTABLE BEGIN IDS_MENU_UPDATE "Mettre le pilote logiciel à jour..." IDS_MENU_ENABLE "Activer" @@ -304,7 +305,7 @@ BEGIN IDS_MENU_PROPERTIES "Propriétés" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_PROPERTIES "Propriétés" IDS_TOOLTIP_SCAN "Vérifier les changements de matériel" @@ -315,7 +316,7 @@ BEGIN END /* Hints */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_PROPERTIES " Ouvre les priopriétés pour la sélection actuelle." diff --git a/dll/win32/devmgr/lang/he-IL.rc b/dll/win32/devmgr/lang/he-IL.rc index 2c43c050c9595..eca9c521c438c 100644 --- a/dll/win32/devmgr/lang/he-IL.rc +++ b/dll/win32/devmgr/lang/he-IL.rc @@ -287,14 +287,15 @@ BEGIN END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_APPNAME "מנהל ההתקנים של ReactOS" IDS_APP_AUTHORS "Copyright 2015 Ged Murphy" IDS_CONFIRM_DISABLE "Disabling this device will cause it to stop functioning.\nDo you really want to disable it?" IDS_CONFIRM_UNINSTALL "Warning: You are about to uninstall this device from your system.\nDo you want to continue?" END -STRINGTABLE DISCARDABLE + +STRINGTABLE BEGIN IDS_MENU_UPDATE "Update driver software..." IDS_MENU_ENABLE "Enable" @@ -305,7 +306,7 @@ BEGIN IDS_MENU_PROPERTIES "Properties" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_PROPERTIES "Properties" IDS_TOOLTIP_SCAN "Scan for hardware changes" @@ -316,7 +317,7 @@ BEGIN END /* Hints */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_PROPERTIES " Open property dialog for the current selection." diff --git a/dll/win32/devmgr/lang/hu-HU.rc b/dll/win32/devmgr/lang/hu-HU.rc index ca3384c9a56cc..dbe9a9a9fcc51 100644 --- a/dll/win32/devmgr/lang/hu-HU.rc +++ b/dll/win32/devmgr/lang/hu-HU.rc @@ -286,14 +286,15 @@ BEGIN END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_APPNAME "ReactOS Eszközkezelő" IDS_APP_AUTHORS "Copyright 2015 Ged Murphy" IDS_CONFIRM_DISABLE "Az eszköz letiltás után nem fog működni.\nBiztosan letiltja?" IDS_CONFIRM_UNINSTALL "Figyelem: arra készül hogy eltávolítsa ezt az eszközt a rendszerből.\nFolytatni szeretné?" END -STRINGTABLE DISCARDABLE + +STRINGTABLE BEGIN IDS_MENU_UPDATE "Illesztőprogram frissítése..." IDS_MENU_ENABLE "Engedélyezés" @@ -304,7 +305,7 @@ BEGIN IDS_MENU_PROPERTIES "Tulajdonságok" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_PROPERTIES "Tulajdonságok" IDS_TOOLTIP_SCAN "Hardverváltozások keresése" @@ -315,7 +316,7 @@ BEGIN END /* Hints */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_PROPERTIES " Az aktuális kijelölés tulajdonságainak megnyitása." diff --git a/dll/win32/devmgr/lang/id-ID.rc b/dll/win32/devmgr/lang/id-ID.rc index 6219a40f91754..bc5cfe81b11ce 100644 --- a/dll/win32/devmgr/lang/id-ID.rc +++ b/dll/win32/devmgr/lang/id-ID.rc @@ -287,14 +287,15 @@ BEGIN END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_APPNAME "Manajer Perangkat ReactOS" IDS_APP_AUTHORS "Copyright 2015 Ged Murphy" IDS_CONFIRM_DISABLE "Mematikan perangkat ini akan menyebabkan fungsionalitasnya berhenti.\nYakin ingin mematikannya?" IDS_CONFIRM_UNINSTALL "Peringatan: Anda akan mencopot perangkat ini dari sistem anda.\nIngin melanjutkan?" END -STRINGTABLE DISCARDABLE + +STRINGTABLE BEGIN IDS_MENU_UPDATE "Perbarui perangkat lunak driver..." IDS_MENU_ENABLE "Hidupkan" @@ -305,7 +306,7 @@ BEGIN IDS_MENU_PROPERTIES "Properti" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_PROPERTIES "Properti" IDS_TOOLTIP_SCAN "Pindai perubahan perangkat keras" @@ -316,7 +317,7 @@ BEGIN END /* Hints */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_PROPERTIES " Buka dialog properti untuk pilihan saat ini." diff --git a/dll/win32/devmgr/lang/it-IT.rc b/dll/win32/devmgr/lang/it-IT.rc index 0d930cbf99a2e..5d58b412ce054 100644 --- a/dll/win32/devmgr/lang/it-IT.rc +++ b/dll/win32/devmgr/lang/it-IT.rc @@ -287,14 +287,15 @@ BEGIN END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_APPNAME "ReactOS Device Manager" IDS_APP_AUTHORS "Copyright 2015 Ged Murphy" IDS_CONFIRM_DISABLE "Disabling this device will cause it to stop functioning.\nDo you really want to disable it?" IDS_CONFIRM_UNINSTALL "Warning: You are about to uninstall this device from your system.\nDo you want to continue?" END -STRINGTABLE DISCARDABLE + +STRINGTABLE BEGIN IDS_MENU_UPDATE "Update driver software..." IDS_MENU_ENABLE "Enable" @@ -305,7 +306,7 @@ BEGIN IDS_MENU_PROPERTIES "Properties" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_PROPERTIES "Properties" IDS_TOOLTIP_SCAN "Scan for hardware changes" @@ -316,7 +317,7 @@ BEGIN END /* Hints */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_PROPERTIES " Open property dialog for the current selection." diff --git a/dll/win32/devmgr/lang/ja-JP.rc b/dll/win32/devmgr/lang/ja-JP.rc index da0477b927478..afbcbaf5eb6d5 100644 --- a/dll/win32/devmgr/lang/ja-JP.rc +++ b/dll/win32/devmgr/lang/ja-JP.rc @@ -285,14 +285,15 @@ BEGIN END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_APPNAME "ReactOS デバイス マネージャ" IDS_APP_AUTHORS "Copyright 2015 Ged Murphy" IDS_CONFIRM_DISABLE "このデバイスを無効にすると、機能が止まります。\nこれを本当に無効にしたいですか?" IDS_CONFIRM_UNINSTALL "警告: あなたのシステムからこのデバイスをアンインストールしようとしています。\n続行したいですか?" END -STRINGTABLE DISCARDABLE + +STRINGTABLE BEGIN IDS_MENU_UPDATE "ドライバ ソフトウェアを更新..." IDS_MENU_ENABLE "有効にする" @@ -303,7 +304,7 @@ BEGIN IDS_MENU_PROPERTIES "プロパティ" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_PROPERTIES "プロパティ" IDS_TOOLTIP_SCAN "ハードウェアの変更をスキャン" @@ -314,7 +315,7 @@ BEGIN END /* Hints */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_PROPERTIES " 現在の選択に対するプロパティ ダイアログを開きます。" diff --git a/dll/win32/devmgr/lang/no-NO.rc b/dll/win32/devmgr/lang/no-NO.rc index b1bf6dfac0f07..a0dc9ecfd6183 100644 --- a/dll/win32/devmgr/lang/no-NO.rc +++ b/dll/win32/devmgr/lang/no-NO.rc @@ -287,14 +287,15 @@ BEGIN END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_APPNAME "ReactOS Device Manager" IDS_APP_AUTHORS "Copyright 2015 Ged Murphy" IDS_CONFIRM_DISABLE "Disabling this device will cause it to stop functioning.\nDo you really want to disable it?" IDS_CONFIRM_UNINSTALL "Warning: You are about to uninstall this device from your system.\nDo you want to continue?" END -STRINGTABLE DISCARDABLE + +STRINGTABLE BEGIN IDS_MENU_UPDATE "Update driver software..." IDS_MENU_ENABLE "Enable" @@ -305,7 +306,7 @@ BEGIN IDS_MENU_PROPERTIES "Properties" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_PROPERTIES "Properties" IDS_TOOLTIP_SCAN "Scan for hardware changes" @@ -316,7 +317,7 @@ BEGIN END /* Hints */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_PROPERTIES " Open property dialog for the current selection." diff --git a/dll/win32/devmgr/lang/pl-PL.rc b/dll/win32/devmgr/lang/pl-PL.rc index 551077f3365a3..0f5884eceb50d 100644 --- a/dll/win32/devmgr/lang/pl-PL.rc +++ b/dll/win32/devmgr/lang/pl-PL.rc @@ -296,14 +296,15 @@ BEGIN END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_APPNAME "Menedźer urządzeń ReactOS" IDS_APP_AUTHORS "Copyright 2015 Ged Murphy" IDS_CONFIRM_DISABLE "Wyłączenie tego urządzenia spowoduje, że przestanie ono funkcjonować.\nCzy na pewno chcesz je wyłączyć?" IDS_CONFIRM_UNINSTALL "Ostrzeżenie: Urządzenie to zostanie zaraz odinstalowane z systemu.\nCzy chcesz kontynuować?" END -STRINGTABLE DISCARDABLE + +STRINGTABLE BEGIN IDS_MENU_UPDATE "Aktualizuj sterownik..." IDS_MENU_ENABLE "Włącz" @@ -314,7 +315,7 @@ BEGIN IDS_MENU_PROPERTIES "Właściwości" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_PROPERTIES "Właściwości" IDS_TOOLTIP_SCAN "Skanuj w poszukiwaniu zmian sprzętu" @@ -325,7 +326,7 @@ BEGIN END /* Hints */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_PROPERTIES " Otwiera okno dialogowe właściwiości dla bieżącego zaznaczenia." diff --git a/dll/win32/devmgr/lang/pt-BR.rc b/dll/win32/devmgr/lang/pt-BR.rc index 9a827214a45a6..bfee500875984 100644 --- a/dll/win32/devmgr/lang/pt-BR.rc +++ b/dll/win32/devmgr/lang/pt-BR.rc @@ -287,14 +287,15 @@ BEGIN END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_APPNAME "ReactOS Device Manager" IDS_APP_AUTHORS "Copyright 2015 Ged Murphy" IDS_CONFIRM_DISABLE "Disabling this device will cause it to stop functioning.\nDo you really want to disable it?" IDS_CONFIRM_UNINSTALL "Warning: You are about to uninstall this device from your system.\nDo you want to continue?" END -STRINGTABLE DISCARDABLE + +STRINGTABLE BEGIN IDS_MENU_UPDATE "Update driver software..." IDS_MENU_ENABLE "Enable" @@ -305,7 +306,7 @@ BEGIN IDS_MENU_PROPERTIES "Properties" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_PROPERTIES "Properties" IDS_TOOLTIP_SCAN "Scan for hardware changes" @@ -316,7 +317,7 @@ BEGIN END /* Hints */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_PROPERTIES " Open property dialog for the current selection." diff --git a/dll/win32/devmgr/lang/pt-PT.rc b/dll/win32/devmgr/lang/pt-PT.rc index d1267d2022e38..5cf2ca97c2b1e 100644 --- a/dll/win32/devmgr/lang/pt-PT.rc +++ b/dll/win32/devmgr/lang/pt-PT.rc @@ -285,7 +285,7 @@ BEGIN END END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_APPNAME "ReactOS Gestor de dispositivos" IDS_APP_AUTHORS "Copyright 2015 Ged Murphy" @@ -293,7 +293,7 @@ BEGIN IDS_CONFIRM_UNINSTALL "Aviso: Está prestes a desinstalar este dispositivo do sistema.\nDeseja continuar?" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_MENU_UPDATE "Actualizar software do controlador..." IDS_MENU_ENABLE "Habilitar" @@ -304,7 +304,7 @@ BEGIN IDS_MENU_PROPERTIES "Propriedades" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_PROPERTIES "Propriedades" IDS_TOOLTIP_SCAN "Verificar alterações de hardware" @@ -315,7 +315,7 @@ BEGIN END /* Hints */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_PROPERTIES " Abrir a caixa de diálogo ""Propriedades"" para a selecção actual." diff --git a/dll/win32/devmgr/lang/ro-RO.rc b/dll/win32/devmgr/lang/ro-RO.rc index d18eeda4c8831..fc2c4ac2b66ab 100644 --- a/dll/win32/devmgr/lang/ro-RO.rc +++ b/dll/win32/devmgr/lang/ro-RO.rc @@ -294,14 +294,15 @@ BEGIN END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_APPNAME "Manager de dispozitive" IDS_APP_AUTHORS "Copyright 2015 Ged Murphy" IDS_CONFIRM_DISABLE "Dezactivarea acestui dispozitiv va cauza oprirea funcționării sale.\nSigur doriți dezactivarea sa?" IDS_CONFIRM_UNINSTALL "Avertisment: Urmează să dezinstalați acest dispozitiv din sistem.\nContinuați?" END -STRINGTABLE DISCARDABLE + +STRINGTABLE BEGIN IDS_MENU_UPDATE "Actualizare driver…" IDS_MENU_ENABLE "Activare" @@ -312,7 +313,7 @@ BEGIN IDS_MENU_PROPERTIES "Proprietăți" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_PROPERTIES "Proprietăți" IDS_TOOLTIP_SCAN "Scanare configurație hardware" @@ -323,7 +324,7 @@ BEGIN END /* Hints */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_PROPERTIES " Inspectarea proprietăților pentru selecția curentă." diff --git a/dll/win32/devmgr/lang/ru-RU.rc b/dll/win32/devmgr/lang/ru-RU.rc index 0b9feea8c0a74..451b6951bbab8 100644 --- a/dll/win32/devmgr/lang/ru-RU.rc +++ b/dll/win32/devmgr/lang/ru-RU.rc @@ -287,14 +287,15 @@ BEGIN END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_APPNAME "Диспетчер устройств ReactOS" IDS_APP_AUTHORS "Copyright 2015 Ged Murphy" IDS_CONFIRM_DISABLE "Отключение устройства означает, что оно перестанет работать.\nОтключить устройство?" IDS_CONFIRM_UNINSTALL "Предупреждение: Сейчас устройство будет удалено из системы.\nВы хотите продолжить?" END -STRINGTABLE DISCARDABLE + +STRINGTABLE BEGIN IDS_MENU_UPDATE "&Обновить драйвер..." IDS_MENU_ENABLE "&Включить" @@ -305,7 +306,7 @@ BEGIN IDS_MENU_PROPERTIES "&Свойства" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_PROPERTIES "Свойства" IDS_TOOLTIP_SCAN "Обновить конфигурацию оборудования" @@ -316,7 +317,7 @@ BEGIN END /* Hints */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_PROPERTIES " Открытие страницы свойств для выделенного объекта." diff --git a/dll/win32/devmgr/lang/sk-SK.rc b/dll/win32/devmgr/lang/sk-SK.rc index 617fc5c0b26f3..c9366979efe25 100644 --- a/dll/win32/devmgr/lang/sk-SK.rc +++ b/dll/win32/devmgr/lang/sk-SK.rc @@ -290,14 +290,15 @@ BEGIN END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_APPNAME "ReactOS Device Manager" IDS_APP_AUTHORS "Copyright 2015 Ged Murphy" IDS_CONFIRM_DISABLE "Disabling this device will cause it to stop functioning.\nDo you really want to disable it?" IDS_CONFIRM_UNINSTALL "Warning: You are about to uninstall this device from your system.\nDo you want to continue?" END -STRINGTABLE DISCARDABLE + +STRINGTABLE BEGIN IDS_MENU_UPDATE "Update driver software..." IDS_MENU_ENABLE "Enable" @@ -308,7 +309,7 @@ BEGIN IDS_MENU_PROPERTIES "Properties" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_PROPERTIES "Properties" IDS_TOOLTIP_SCAN "Scan for hardware changes" @@ -319,7 +320,7 @@ BEGIN END /* Hints */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_PROPERTIES " Open property dialog for the current selection." diff --git a/dll/win32/devmgr/lang/sq-AL.rc b/dll/win32/devmgr/lang/sq-AL.rc index ef2f22b9dfaef..fa3724737d3b7 100644 --- a/dll/win32/devmgr/lang/sq-AL.rc +++ b/dll/win32/devmgr/lang/sq-AL.rc @@ -289,14 +289,15 @@ BEGIN END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_APPNAME "ReactOS Device Manager" IDS_APP_AUTHORS "Copyright 2015 Ged Murphy" IDS_CONFIRM_DISABLE "Disabling this device will cause it to stop functioning.\nDo you really want to disable it?" IDS_CONFIRM_UNINSTALL "Warning: You are about to uninstall this device from your system.\nDo you want to continue?" END -STRINGTABLE DISCARDABLE + +STRINGTABLE BEGIN IDS_MENU_UPDATE "Update driver software..." IDS_MENU_ENABLE "Enable" @@ -307,7 +308,7 @@ BEGIN IDS_MENU_PROPERTIES "Properties" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_PROPERTIES "Properties" IDS_TOOLTIP_SCAN "Scan for hardware changes" @@ -318,7 +319,7 @@ BEGIN END /* Hints */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_PROPERTIES " Open property dialog for the current selection." diff --git a/dll/win32/devmgr/lang/tr-TR.rc b/dll/win32/devmgr/lang/tr-TR.rc index 819c4e26d0550..6ba85c66875f2 100644 --- a/dll/win32/devmgr/lang/tr-TR.rc +++ b/dll/win32/devmgr/lang/tr-TR.rc @@ -287,7 +287,7 @@ BEGIN END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_APPNAME "ReactOS Aygıt Yöneticisi" IDS_APP_AUTHORS "Telif Hakkı: 2015 Ged Murphy" @@ -295,7 +295,7 @@ BEGIN IDS_CONFIRM_UNINSTALL "Uyarı: Bu aygıtı sisteminizden kaldırmak üzeresiniz.\nDevam etmek istiyor musunuz?" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_MENU_UPDATE "Sürücü Yazılımını Güncelleştir..." IDS_MENU_ENABLE "Etkinleştir" @@ -306,7 +306,7 @@ BEGIN IDS_MENU_PROPERTIES "Özellikler" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_PROPERTIES "Özellikler" IDS_TOOLTIP_SCAN "Donanım Değişiklikleri İçin Tara" @@ -317,7 +317,7 @@ BEGIN END /* Hints */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_PROPERTIES " Şimdiki seçilen için özellik penceresini açar." diff --git a/dll/win32/devmgr/lang/uk-UA.rc b/dll/win32/devmgr/lang/uk-UA.rc index dd4c1f3f68fa0..c5ca33b935d72 100644 --- a/dll/win32/devmgr/lang/uk-UA.rc +++ b/dll/win32/devmgr/lang/uk-UA.rc @@ -293,14 +293,15 @@ BEGIN END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_APPNAME "ReactOS Device Manager" IDS_APP_AUTHORS "Copyright 2015 Ged Murphy" IDS_CONFIRM_DISABLE "Disabling this device will cause it to stop functioning.\nDo you really want to disable it?" IDS_CONFIRM_UNINSTALL "Warning: You are about to uninstall this device from your system.\nDo you want to continue?" END -STRINGTABLE DISCARDABLE + +STRINGTABLE BEGIN IDS_MENU_UPDATE "Update driver software..." IDS_MENU_ENABLE "Enable" @@ -311,7 +312,7 @@ BEGIN IDS_MENU_PROPERTIES "Properties" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_PROPERTIES "Properties" IDS_TOOLTIP_SCAN "Scan for hardware changes" @@ -322,7 +323,7 @@ BEGIN END /* Hints */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_PROPERTIES " Open property dialog for the current selection." diff --git a/dll/win32/devmgr/lang/zh-CN.rc b/dll/win32/devmgr/lang/zh-CN.rc index 08a0162814440..f1474bd936be1 100644 --- a/dll/win32/devmgr/lang/zh-CN.rc +++ b/dll/win32/devmgr/lang/zh-CN.rc @@ -294,14 +294,15 @@ BEGIN END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_APPNAME "ReactOS 设备管理器" IDS_APP_AUTHORS "Copyright 2015 Ged Murphy" IDS_CONFIRM_DISABLE "禁用此设备会使其停止运行。\n你真的想要禁用它吗?" IDS_CONFIRM_UNINSTALL "警告: 您将要从系统中卸载此设备。\n你想要继续吗?" END -STRINGTABLE DISCARDABLE + +STRINGTABLE BEGIN IDS_MENU_UPDATE "更新驱动程序软件..." IDS_MENU_ENABLE "启用" @@ -312,7 +313,7 @@ BEGIN IDS_MENU_PROPERTIES "属性" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_PROPERTIES "属性" IDS_TOOLTIP_SCAN "扫描检测硬件改动" @@ -323,7 +324,7 @@ BEGIN END /* Hints */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_PROPERTIES " 当前所选内容的公开的属性对话框。" diff --git a/dll/win32/devmgr/lang/zh-HK.rc b/dll/win32/devmgr/lang/zh-HK.rc index 833da6c7e388e..c8aae24c56901 100644 --- a/dll/win32/devmgr/lang/zh-HK.rc +++ b/dll/win32/devmgr/lang/zh-HK.rc @@ -293,14 +293,15 @@ BEGIN END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_APPNAME "ReactOS 裝置管理員" IDS_APP_AUTHORS "2015 Ged Murphy 版權所有" IDS_CONFIRM_DISABLE "停用這個裝置會使其停止運作。\n你真的想要停用它嗎?" IDS_CONFIRM_UNINSTALL "警告:您將要從系統中解除安裝這個裝置。\n你想要繼續嗎?" END -STRINGTABLE DISCARDABLE + +STRINGTABLE BEGIN IDS_MENU_UPDATE "更新驅動程式軟件..." IDS_MENU_ENABLE "啟用" @@ -311,7 +312,7 @@ BEGIN IDS_MENU_PROPERTIES "內容" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_PROPERTIES "內容" IDS_TOOLTIP_SCAN "掃描硬件變更" @@ -322,7 +323,7 @@ BEGIN END /* Hints */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_PROPERTIES " 開啟目前選擇的內容對話方塊。" diff --git a/dll/win32/devmgr/lang/zh-TW.rc b/dll/win32/devmgr/lang/zh-TW.rc index f0565d556e824..f8e0eeea5dbcf 100644 --- a/dll/win32/devmgr/lang/zh-TW.rc +++ b/dll/win32/devmgr/lang/zh-TW.rc @@ -293,14 +293,15 @@ BEGIN END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_APPNAME "ReactOS 裝置管理員" IDS_APP_AUTHORS "2015 Ged Murphy 版權所有" IDS_CONFIRM_DISABLE "停用這個裝置會使其停止運作。\n你真的想要停用它嗎?" IDS_CONFIRM_UNINSTALL "警告:您將要從系統中解除安裝這個裝置。\n你想要繼續嗎?" END -STRINGTABLE DISCARDABLE + +STRINGTABLE BEGIN IDS_MENU_UPDATE "更新驅動程式軟體..." IDS_MENU_ENABLE "啟用" @@ -311,7 +312,7 @@ BEGIN IDS_MENU_PROPERTIES "內容" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_PROPERTIES "內容" IDS_TOOLTIP_SCAN "掃描硬體變更" @@ -322,7 +323,7 @@ BEGIN END /* Hints */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_PROPERTIES " 開啟目前選擇的內容對話方塊。" diff --git a/dll/win32/devmgr/properties/stubs.cpp b/dll/win32/devmgr/properties/stubs.cpp index 37142269cd7df..1790f51a85153 100644 --- a/dll/win32/devmgr/properties/stubs.cpp +++ b/dll/win32/devmgr/properties/stubs.cpp @@ -8,9 +8,9 @@ * NOTES: If you implement a function, remove it from this file * * Some helpful resources: - * http://support.microsoft.com/default.aspx?scid=kb;%5BLN%5D;815320 - * http://www.jsiinc.com/SUBO/tip7400/rh7482.htm - * http://www.jsiinc.com/SUBM/tip6400/rh6490.htm + * http://support.microsoft.com/default.aspx?scid=kb;%5BLN%5D;815320 (DEAD_LINK) + * https://web.archive.org/web/20050321020634/http://www.jsifaq.com/SUBO/tip7400/rh7482.htm + * https://web.archive.org/web/20050909185602/http://www.jsifaq.com/SUBM/tip6400/rh6490.htm * * UPDATE HISTORY: * 04-04-2004 Created diff --git a/dll/win32/faultrep/CMakeLists.txt b/dll/win32/faultrep/CMakeLists.txt index a5172103fe7e9..ef2766e16598b 100644 --- a/dll/win32/faultrep/CMakeLists.txt +++ b/dll/win32/faultrep/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(faultrep.dll faultrep.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -13,3 +11,4 @@ set_module_type(faultrep win32dll) target_link_libraries(faultrep wine) add_importlibs(faultrep advapi32 msvcrt kernel32 ntdll) add_cd_file(TARGET faultrep DESTINATION reactos/system32 FOR all) +set_wine_module(faultrep) diff --git a/dll/win32/faultrep/faultrep.c b/dll/win32/faultrep/faultrep.c index 3191659cd6c98..7c5f2157750c6 100644 --- a/dll/win32/faultrep/faultrep.c +++ b/dll/win32/faultrep/faultrep.c @@ -117,8 +117,10 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved) { switch(reason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(inst); break; diff --git a/dll/win32/fontsub/CMakeLists.txt b/dll/win32/fontsub/CMakeLists.txt index 1e801ffd6f0d2..0d59c712af633 100644 --- a/dll/win32/fontsub/CMakeLists.txt +++ b/dll/win32/fontsub/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(fontsub.dll fontsub.spec) add_library(fontsub MODULE @@ -12,3 +10,4 @@ set_module_type(fontsub win32dll) target_link_libraries(fontsub wine) add_importlibs(fontsub msvcrt kernel32 ntdll) add_cd_file(TARGET fontsub DESTINATION reactos/system32 FOR all) +set_wine_module(fontsub) diff --git a/dll/win32/fontsub/main.c b/dll/win32/fontsub/main.c index a0a6032d0511c..e8eb06b195aba 100644 --- a/dll/win32/fontsub/main.c +++ b/dll/win32/fontsub/main.c @@ -30,8 +30,10 @@ BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) TRACE("%p,%x,%p\n", hinstDLL, fdwReason, lpvReserved); switch (fdwReason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hinstDLL); break; diff --git a/dll/win32/fusion/CMakeLists.txt b/dll/win32/fusion/CMakeLists.txt index 93f40cea51ce7..7159a2f9bdb08 100644 --- a/dll/win32/fusion/CMakeLists.txt +++ b/dll/win32/fusion/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(fusion.dll fusion.spec) list(APPEND COMMON_SOURCE @@ -16,6 +14,7 @@ add_library(fusion_common STATIC ${COMMON_SOURCE}) target_link_libraries(fusion_common oldnames) add_dependencies(fusion_common psdk) add_pch(fusion_common precomp.h COMMON_SOURCE) +set_wine_module_FIXME(fusion_common) # CORE-5743: No ARRAY_SIZE and CONST_VTABLE add_library(fusion MODULE version.rc diff --git a/dll/win32/gdiplus/CMakeLists.txt b/dll/win32/gdiplus/CMakeLists.txt index 65522334bf2be..3fd65cbe46033 100644 --- a/dll/win32/gdiplus/CMakeLists.txt +++ b/dll/win32/gdiplus/CMakeLists.txt @@ -1,10 +1,8 @@ add_definitions( - -D__WINESRC__ -D__ROS_LONG64__ -D_USE_MATH_DEFINES) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(gdiplus.dll gdiplus.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -51,3 +49,4 @@ add_cd_file(FILE ${CMAKE_CURRENT_SOURCE_DIR}/${WINARCH}_microsoft.windows.gdiplu add_cd_file(TARGET gdiplus DESTINATION reactos/winsxs/${WINARCH}_microsoft.windows.gdiplus_6595b64144ccf1df_1.0.14393.0_none_deadbeef FOR all) add_cd_file(FILE ${CMAKE_CURRENT_SOURCE_DIR}/${WINARCH}_microsoft.windows.gdiplus_6595b64144ccf1df_1.0.14393.0_none_deadbeef.manifest DESTINATION reactos/winsxs/manifests FOR all) +set_wine_module_FIXME(gdiplus) # CORE-5743: No ARRAY_SIZE macro diff --git a/dll/win32/gdiplus/image.c b/dll/win32/gdiplus/image.c index e9fd781a1beb0..8240a41ad429d 100644 --- a/dll/win32/gdiplus/image.c +++ b/dll/win32/gdiplus/image.c @@ -4969,7 +4969,11 @@ static const struct image_codec codecs[NUM_CODECS] = { { { /* ICO */ /* Clsid */ { 0x557cf407, 0x1a04, 0x11d3, { 0x9a, 0x73, 0x0, 0x0, 0xf8, 0x1e, 0xf3, 0x2e } }, +#ifdef __REACTOS__ + /* FormatID */ { 0xb96b3cb5U, 0x0728U, 0x11d3U, {0x9d, 0x7b, 0x00, 0x00, 0xf8, 0x1e, 0xf3, 0x2e} }, /* ImageFormatIcon */ +#else /* FormatID */ { 0xb96b3cabU, 0x0728U, 0x11d3U, {0x9d, 0x7b, 0x00, 0x00, 0xf8, 0x1e, 0xf3, 0x2e} }, +#endif /* CodecName */ ico_codecname, /* DllName */ NULL, /* FormatDescription */ ico_format, diff --git a/dll/win32/hhctrl.ocx/CMakeLists.txt b/dll/win32/hhctrl.ocx/CMakeLists.txt index 32b6f023dc8f8..a85cc4ab268b4 100644 --- a/dll/win32/hhctrl.ocx/CMakeLists.txt +++ b/dll/win32/hhctrl.ocx/CMakeLists.txt @@ -2,8 +2,6 @@ remove_definitions(-D_WIN32_WINNT=0x502) add_definitions(-D_WIN32_WINNT=0x600) -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(hhctrl.ocx hhctrl.ocx.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -38,3 +36,4 @@ add_importlibs(hhctrl advapi32 comctl32 shlwapi ole32 oleaut32 user32 gdi32 msvc add_dependencies(hhctrl stdole2 wineheaders) add_pch(hhctrl precomp.h "${PCH_SKIP_SOURCE}") add_cd_file(TARGET hhctrl DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(hhctrl) # CORE-5743: No ARRAY_SIZE and CONST_VTABLE diff --git a/dll/win32/hhctrl.ocx/lang/De.rc b/dll/win32/hhctrl.ocx/lang/De.rc index a88450e4bba02..5e56c0c78abdb 100644 --- a/dll/win32/hhctrl.ocx/lang/De.rc +++ b/dll/win32/hhctrl.ocx/lang/De.rc @@ -19,8 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/hhctrl.ocx/lang/Es.rc b/dll/win32/hhctrl.ocx/lang/Es.rc index 879dae1e77829..8dfd6e950e1bd 100644 --- a/dll/win32/hhctrl.ocx/lang/Es.rc +++ b/dll/win32/hhctrl.ocx/lang/Es.rc @@ -19,9 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/hhctrl.ocx/lang/Fr.rc b/dll/win32/hhctrl.ocx/lang/Fr.rc index 8fb8de93d1048..8bc687255e006 100644 --- a/dll/win32/hhctrl.ocx/lang/Fr.rc +++ b/dll/win32/hhctrl.ocx/lang/Fr.rc @@ -19,9 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/hhctrl.ocx/lang/It.rc b/dll/win32/hhctrl.ocx/lang/It.rc index 5a934a5cca240..98660dd29abd3 100644 --- a/dll/win32/hhctrl.ocx/lang/It.rc +++ b/dll/win32/hhctrl.ocx/lang/It.rc @@ -20,9 +20,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/hhctrl.ocx/lang/Ja.rc b/dll/win32/hhctrl.ocx/lang/Ja.rc index a359e8bed0cb9..8df2ff64cdca3 100644 --- a/dll/win32/hhctrl.ocx/lang/Ja.rc +++ b/dll/win32/hhctrl.ocx/lang/Ja.rc @@ -20,9 +20,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/hhctrl.ocx/lang/Lt.rc b/dll/win32/hhctrl.ocx/lang/Lt.rc index c01d293968ae2..107728e5d756d 100644 --- a/dll/win32/hhctrl.ocx/lang/Lt.rc +++ b/dll/win32/hhctrl.ocx/lang/Lt.rc @@ -19,9 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_LITHUANIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/hhctrl.ocx/lang/Pt.rc b/dll/win32/hhctrl.ocx/lang/Pt.rc index 9555029935204..8438b3171ab5b 100644 --- a/dll/win32/hhctrl.ocx/lang/Pt.rc +++ b/dll/win32/hhctrl.ocx/lang/Pt.rc @@ -20,8 +20,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_PORTUGUESE, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/hhctrl.ocx/lang/Ro.rc b/dll/win32/hhctrl.ocx/lang/Ro.rc index 97555fc898aab..2e3e63ba3b96a 100644 --- a/dll/win32/hhctrl.ocx/lang/Ro.rc +++ b/dll/win32/hhctrl.ocx/lang/Ro.rc @@ -23,8 +23,6 @@ LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL -#pragma code_page(65001) - STRINGTABLE BEGIN #ifdef __REACTOS__ diff --git a/dll/win32/hhctrl.ocx/lang/Ru.rc b/dll/win32/hhctrl.ocx/lang/Ru.rc index 62cef188c0602..742a83f210aa1 100644 --- a/dll/win32/hhctrl.ocx/lang/Ru.rc +++ b/dll/win32/hhctrl.ocx/lang/Ru.rc @@ -19,9 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/hhctrl.ocx/lang/Si.rc b/dll/win32/hhctrl.ocx/lang/Si.rc index 9c62b7b77fc5f..155fe4ecdbe6c 100644 --- a/dll/win32/hhctrl.ocx/lang/Si.rc +++ b/dll/win32/hhctrl.ocx/lang/Si.rc @@ -19,8 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/hhctrl.ocx/lang/Uk.rc b/dll/win32/hhctrl.ocx/lang/Uk.rc index 6bd8fe2650a34..5d19e3e02b128 100644 --- a/dll/win32/hhctrl.ocx/lang/Uk.rc +++ b/dll/win32/hhctrl.ocx/lang/Uk.rc @@ -21,9 +21,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/hhctrl.ocx/lang/Zh.rc b/dll/win32/hhctrl.ocx/lang/Zh.rc index cedf748a8966e..a885cc1169388 100644 --- a/dll/win32/hhctrl.ocx/lang/Zh.rc +++ b/dll/win32/hhctrl.ocx/lang/Zh.rc @@ -19,9 +19,6 @@ * Copyright 2021-2022 Chan Chilung */ -/* Chinese text is encoded in UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED STRINGTABLE diff --git a/dll/win32/hlink/CMakeLists.txt b/dll/win32/hlink/CMakeLists.txt index d1463d0fdf37c..695e974f800f6 100644 --- a/dll/win32/hlink/CMakeLists.txt +++ b/dll/win32/hlink/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(hlink.dll hlink.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -24,3 +22,4 @@ add_delay_importlibs(hlink urlmon) add_importlibs(hlink shell32 ole32 advapi32 msvcrt kernel32 ntdll) add_pch(hlink precomp.h "${PCH_SKIP_SOURCE}") add_cd_file(TARGET hlink DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(hlink) # CORE-5743: No ARRAY_SIZE and CONST_VTABLE diff --git a/dll/win32/hnetcfg/CMakeLists.txt b/dll/win32/hnetcfg/CMakeLists.txt index 14353e9f4ad84..0a190fbcf0c67 100644 --- a/dll/win32/hnetcfg/CMakeLists.txt +++ b/dll/win32/hnetcfg/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(hnetcfg.dll hnetcfg.spec) list(APPEND SOURCE @@ -32,3 +30,4 @@ target_link_libraries(hnetcfg wine uuid) add_importlibs(hnetcfg ole32 oleaut32 advapi32 mpr msvcrt kernel32 ntdll) add_pch(hnetcfg precomp.h SOURCE) add_cd_file(TARGET hnetcfg DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(hnetcfg) # CORE-5743: No ARRAY_SIZE and CONST_VTABLE diff --git a/dll/win32/hnetcfg/hnetcfg.c b/dll/win32/hnetcfg/hnetcfg.c index 5cc24a1447bdb..9d90fa4301e36 100644 --- a/dll/win32/hnetcfg/hnetcfg.c +++ b/dll/win32/hnetcfg/hnetcfg.c @@ -123,8 +123,10 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID reserved) TRACE("(0x%p, %d, %p)\n", hInstDLL, fdwReason, reserved); switch(fdwReason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; +#endif case DLL_PROCESS_ATTACH: instance = hInstDLL; DisableThreadLibraryCalls(hInstDLL); diff --git a/dll/win32/iccvid/CMakeLists.txt b/dll/win32/iccvid/CMakeLists.txt index 68dc7057a1f82..2b7b45903dc25 100644 --- a/dll/win32/iccvid/CMakeLists.txt +++ b/dll/win32/iccvid/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(iccvid.dll iccvid.spec) list(APPEND SOURCE @@ -12,3 +10,4 @@ set_module_type(iccvid win32dll) target_link_libraries(iccvid wine) add_importlibs(iccvid user32 msvcrt kernel32 ntdll) add_cd_file(TARGET iccvid DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(iccvid) # CORE-5743: No ARRAY_SIZE macro diff --git a/dll/win32/iccvid/lang/iccvid_De.rc b/dll/win32/iccvid/lang/iccvid_De.rc index ed20fc7cbedb5..d757199e0a0e3 100644 --- a/dll/win32/iccvid/lang/iccvid_De.rc +++ b/dll/win32/iccvid/lang/iccvid_De.rc @@ -17,8 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/iccvid/lang/iccvid_Es.rc b/dll/win32/iccvid/lang/iccvid_Es.rc index de6e94ea44136..746995d3538fe 100644 --- a/dll/win32/iccvid/lang/iccvid_Es.rc +++ b/dll/win32/iccvid/lang/iccvid_Es.rc @@ -16,9 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/iccvid/lang/iccvid_Fr.rc b/dll/win32/iccvid/lang/iccvid_Fr.rc index 5998b611ad5a9..9fc32549e757e 100644 --- a/dll/win32/iccvid/lang/iccvid_Fr.rc +++ b/dll/win32/iccvid/lang/iccvid_Fr.rc @@ -16,9 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/iccvid/lang/iccvid_It.rc b/dll/win32/iccvid/lang/iccvid_It.rc index f1d90385e794c..33c63721fdc6c 100644 --- a/dll/win32/iccvid/lang/iccvid_It.rc +++ b/dll/win32/iccvid/lang/iccvid_It.rc @@ -16,9 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/iccvid/lang/iccvid_Ja.rc b/dll/win32/iccvid/lang/iccvid_Ja.rc index 9b0bac197d9d1..d00995cd78b90 100644 --- a/dll/win32/iccvid/lang/iccvid_Ja.rc +++ b/dll/win32/iccvid/lang/iccvid_Ja.rc @@ -16,9 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/iccvid/lang/iccvid_Lt.rc b/dll/win32/iccvid/lang/iccvid_Lt.rc index a46b01caa1a00..af8b0f7c2ae55 100644 --- a/dll/win32/iccvid/lang/iccvid_Lt.rc +++ b/dll/win32/iccvid/lang/iccvid_Lt.rc @@ -16,9 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_LITHUANIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/iccvid/lang/iccvid_Ro.rc b/dll/win32/iccvid/lang/iccvid_Ro.rc index 191539ef927d2..9d8f2d544012a 100644 --- a/dll/win32/iccvid/lang/iccvid_Ro.rc +++ b/dll/win32/iccvid/lang/iccvid_Ro.rc @@ -17,8 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/iccvid/lang/iccvid_Ru.rc b/dll/win32/iccvid/lang/iccvid_Ru.rc index 4909cf0640847..333d709675c68 100644 --- a/dll/win32/iccvid/lang/iccvid_Ru.rc +++ b/dll/win32/iccvid/lang/iccvid_Ru.rc @@ -16,9 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/iccvid/lang/iccvid_Si.rc b/dll/win32/iccvid/lang/iccvid_Si.rc index f6a83251b8f57..d10c613cf7300 100644 --- a/dll/win32/iccvid/lang/iccvid_Si.rc +++ b/dll/win32/iccvid/lang/iccvid_Si.rc @@ -16,8 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/iccvid/lang/iccvid_Uk.rc b/dll/win32/iccvid/lang/iccvid_Uk.rc index 33a3fab364211..7be4f6d6cb8ca 100644 --- a/dll/win32/iccvid/lang/iccvid_Uk.rc +++ b/dll/win32/iccvid/lang/iccvid_Uk.rc @@ -16,9 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/iccvid/lang/iccvid_Zh.rc b/dll/win32/iccvid/lang/iccvid_Zh.rc index 96183a28c0c26..4d0a2fbece090 100644 --- a/dll/win32/iccvid/lang/iccvid_Zh.rc +++ b/dll/win32/iccvid/lang/iccvid_Zh.rc @@ -21,9 +21,6 @@ * Copyright 2021 Chan Chilung */ -/* Chinese text is encoded in UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED STRINGTABLE diff --git a/dll/win32/ieframe/CMakeLists.txt b/dll/win32/ieframe/CMakeLists.txt index 830a3f5b9c3af..f61201dec0ce5 100644 --- a/dll/win32/ieframe/CMakeLists.txt +++ b/dll/win32/ieframe/CMakeLists.txt @@ -1,6 +1,5 @@ -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) -add_definitions(-D__WINESRC__) +add_definitions(-D__ROS_LONG64__) spec2def(ieframe.dll ieframe.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -13,6 +12,7 @@ list(APPEND SOURCE ieframe_main.c iehtmlwnd.c iexplore.c + inetfolder.c intshcut.c navigate.c oleobject.c @@ -46,3 +46,4 @@ target_link_libraries(ieframe uuid wine) add_importlibs(ieframe urlmon shell32 comctl32 shlwapi oleaut32 ole32 user32 gdi32 advapi32 msvcrt kernel32 ntdll) add_pch(ieframe precomp.h SOURCE) add_cd_file(TARGET ieframe DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(ieframe) # CORE-5743: No CONST_VTABLE diff --git a/dll/win32/ieframe/ieframe_main.c b/dll/win32/ieframe/ieframe_main.c index 5abe502f1e419..b07569e92ec21 100644 --- a/dll/win32/ieframe/ieframe_main.c +++ b/dll/win32/ieframe/ieframe_main.c @@ -178,6 +178,20 @@ static const IClassFactoryVtbl CUrlHistoryFactoryVtbl = { static IClassFactory CUrlHistoryFactory = { &CUrlHistoryFactoryVtbl }; +#ifdef __REACTOS__ +extern HRESULT WINAPI CInternetFolder_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv); + +static const IClassFactoryVtbl CInternetFolderFactoryVtbl = { + ClassFactory_QueryInterface, + ClassFactory_AddRef, + ClassFactory_Release, + CInternetFolder_CreateInstance, + ClassFactory_LockServer +}; + +static IClassFactory CInternetFolderFactory = { &CInternetFolderFactoryVtbl }; +#endif + /****************************************************************** * DllMain (ieframe.@) */ @@ -226,6 +240,13 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) return IClassFactory_QueryInterface(&CUrlHistoryFactory, riid, ppv); } +#ifdef __REACTOS__ + if(IsEqualGUID(&CLSID_Internet, rclsid)) { + TRACE("(CLSID_Internet %s %p)\n", debugstr_guid(riid), ppv); + return IClassFactory_QueryInterface(&CInternetFolderFactory, riid, ppv); + } +#endif + FIXME("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv); return CLASS_E_CLASSNOTAVAILABLE; } diff --git a/dll/win32/ieframe/inetfolder.c b/dll/win32/ieframe/inetfolder.c new file mode 100644 index 0000000000000..80c1333a9596c --- /dev/null +++ b/dll/win32/ieframe/inetfolder.c @@ -0,0 +1,358 @@ +/* + * PROJECT: ReactOS ieframe + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Internet IShellFolder implementation + * COPYRIGHT: Copyright 2025 Whindmar Saksit + */ + +#define NONAMELESSUNION + +#include "ieframe.h" + +#include "shlobj.h" +#include "shobjidl.h" +#include "shellapi.h" +#include "shlwapi.h" +#include "shlguid.h" +#include "intshcut.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ieframe); + +extern int WINAPI SHAnsiToUnicodeCP(UINT CodePage, LPCSTR pszSrc, LPWSTR pwszDst, int cwchBuf); + +#define MAX_URL_LENGTH 1024 + +#define PT_INTERNET_URL 0x61 +#define IFUIF_UNICODE 0x80 +typedef struct _IFURLITEM +{ + WORD cb; + BYTE Type; // PT_INTERNET_URL + BYTE Flags; // IFUIF_* + UINT Unknown; + WCHAR Url[ANYSIZE_ARRAY]; +} IFURLITEM; + +static int GetSchemeCharType(WCHAR c) +{ + if (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z')) + return 0; + return c == '+' || c == '-' || c == '.' ? 1 : -1; +} + +static unsigned int GetSchemeLength(PCWSTR s) +{ + if (GetSchemeCharType(s[0]) != 0) // The first character MUST be A-Z, a-z. + return 0; + for (unsigned int i = 0;;) + { + if (s[++i] == ':') + return ++i; + if (GetSchemeCharType(s[i]) < 0) + return 0; + } +} + +static LPITEMIDLIST CreateUrlItem(PCWSTR pszUrl) +{ + UINT cch = lstrlenW(pszUrl) + 1; + UINT cb = FIELD_OFFSET(IFURLITEM, Url[cch]); + IFURLITEM *pidl = SHAlloc(cb + sizeof(WORD)); + if (!pidl) + return (LPITEMIDLIST)pidl; + pidl->cb = cb; + pidl->Type = PT_INTERNET_URL; + pidl->Flags = IFUIF_UNICODE; + pidl->Unknown = 0; + CopyMemory(pidl->Url, pszUrl, cch * sizeof(*pszUrl)); + ILGetNext((LPITEMIDLIST)pidl)->mkid.cb = 0; + return (LPITEMIDLIST)pidl; +} + +static IFURLITEM* IsUrlItem(LPCITEMIDLIST pidl) +{ + IFURLITEM *p = (IFURLITEM*)pidl; + if (p && p->cb > FIELD_OFFSET(IFURLITEM, Url) && p->Type == PT_INTERNET_URL) + return p; + return NULL; +} + +static PWSTR GetUrl(IFURLITEM *pUrl, PWSTR Buffer) +{ + if (pUrl->Flags & IFUIF_UNICODE) + return pUrl->Url; + SHAnsiToUnicodeCP(CP_ACP, (PCSTR)pUrl->Url, Buffer, MAX_URL_LENGTH); + return Buffer; +} + +static HRESULT CreateUrlShortcut(PCWSTR Url, IUniformResourceLocatorW **ppv) +{ + HRESULT hr = CoCreateInstance(&CLSID_InternetShortcut, NULL, CLSCTX_INPROC_SERVER, + &IID_IUniformResourceLocatorW, (void**)ppv); + if (SUCCEEDED(hr)) + hr = (*ppv)->lpVtbl->SetURL(*ppv, Url, 0); + return hr; +} + +typedef struct _CInternetFolder +{ + IShellFolder IShellFolder_iface; + IPersistFolder IPersistFolder_iface; + LONG refCount; +} CInternetFolder; + +static HRESULT Unknown_QueryInterface(CInternetFolder *This, REFIID riid, PVOID *ppvObject) +{ + TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppvObject); + *ppvObject = NULL; + if (IsEqualGUID(&IID_IUnknown, riid)) + *ppvObject = &This->IShellFolder_iface; + else if (IsEqualGUID(&IID_IShellFolder, riid)) + *ppvObject = &This->IShellFolder_iface; + else if (IsEqualGUID(&IID_IPersist, riid) || IsEqualGUID(&IID_IPersistFolder, riid)) + *ppvObject = &This->IPersistFolder_iface; + else + return E_NOINTERFACE; + IUnknown_AddRef((IUnknown*)*ppvObject); + return S_OK; +} + +static ULONG Unknown_AddRef(CInternetFolder *This) +{ + return InterlockedIncrement(&This->refCount); +} + +static ULONG Unknown_Release(CInternetFolder *This) +{ + const ULONG count = InterlockedDecrement(&This->refCount); + if (count == 0) + { + SHFree(This); + unlock_module(); + } + return count; +} + +static HRESULT WINAPI ShellFolder_QueryInterface(IShellFolder *This, REFIID riid, PVOID *ppvObject) +{ + return Unknown_QueryInterface(CONTAINING_RECORD(This, CInternetFolder, IShellFolder_iface), riid, ppvObject); +} + +static ULONG WINAPI ShellFolder_AddRef(IShellFolder *This) +{ + return Unknown_AddRef(CONTAINING_RECORD(This, CInternetFolder, IShellFolder_iface)); +} + +static ULONG WINAPI ShellFolder_Release(IShellFolder *This) +{ + return Unknown_Release(CONTAINING_RECORD(This, CInternetFolder, IShellFolder_iface)); +} + +static HRESULT WINAPI ParseDisplayName(IShellFolder *This, HWND hwnd, IBindCtx *pbc, LPWSTR pszDisplayName, ULONG *pchEaten, PIDLIST_RELATIVE *ppidl, ULONG *pdwAttributes) +{ + UINT len; + + *ppidl = NULL; + len = GetSchemeLength(pszDisplayName); + if (len) + { + if (len + 1 == sizeof("shell:")) + { + WCHAR szBuf[100]; + lstrcpynW(szBuf, pszDisplayName, sizeof("shell:")); + if (!lstrcmpiW(szBuf, L"shell:")) + return E_FAIL; + } + + if ((*ppidl = CreateUrlItem(pszDisplayName)) == NULL) + return E_OUTOFMEMORY; + if (pchEaten) + *pchEaten = lstrlenW(pszDisplayName); + if (pdwAttributes) + IShellFolder_GetAttributesOf(This, 1, (PCUITEMID_CHILD_ARRAY)ppidl, pdwAttributes); + return S_OK; + } + return E_FAIL; +} + +static HRESULT WINAPI ShellFolder_EnumObjects(IShellFolder *This, HWND hwndOwner, SHCONTF grfFlags, IEnumIDList **ppenumIDList) +{ + *ppenumIDList = NULL; + return E_NOTIMPL; +} + +static HRESULT WINAPI BindToObject(IShellFolder *This, PCUIDLIST_RELATIVE pidl, IBindCtx *pbc, REFIID riid, void **ppvOut) +{ + *ppvOut = NULL; + return E_NOTIMPL; +} + +static HRESULT WINAPI BindToStorage(IShellFolder *This, PCUIDLIST_RELATIVE pidl, IBindCtx *pbc, REFIID riid, void **ppvOut) +{ + *ppvOut = NULL; + return E_NOTIMPL; +} + +static HRESULT WINAPI CompareIDs(IShellFolder *This, LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2) +{ + IFURLITEM *pUrl1 = IsUrlItem(pidl1), *pUrl2 = IsUrlItem(pidl2); + if (pUrl1 && pUrl2) + { + WCHAR szUrl1[MAX_URL_LENGTH], *pszUrl1 = GetUrl(pUrl1, szUrl1); + WCHAR szUrl2[MAX_URL_LENGTH], *pszUrl2 = GetUrl(pUrl2, szUrl2); + int cmp = lstrcmpiW(pszUrl1, pszUrl2); + return cmp < 0 ? 0xffff : cmp != 0; + } + return E_FAIL; +} + +static HRESULT WINAPI CreateViewObject(IShellFolder *This, HWND hwndOwner,REFIID riid,void **ppv) +{ + *ppv = NULL; + return E_NOTIMPL; +} + +static HRESULT WINAPI GetAttributesOf(IShellFolder *This, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, SFGAOF *rgfInOut) +{ + UINT i; + + if (cidl == 0) + { + *rgfInOut &= SFGAO_FOLDER | SFGAO_CANLINK | SFGAO_STREAM; // Folder attributes + return S_OK; + } + + for (i = 0; i < cidl; ++i) + { + IFURLITEM *pUrl = IsUrlItem(apidl[i]); + if (!pUrl) + return E_FAIL; + *rgfInOut &= SFGAO_CANLINK | SFGAO_BROWSABLE | SFGAO_STREAM; + } + return S_OK; +} + +static HRESULT WINAPI GetUIObjectOf(IShellFolder *This, HWND hwndOwner, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, REFIID riid, UINT *rgfReserved, void **ppv) +{ + IFURLITEM *pUrl; + if (cidl == 1 && (pUrl = IsUrlItem(apidl[0])) != NULL) + { + if (IsEqualIID(riid, &IID_IExtractIconW) || IsEqualIID(riid, &IID_IExtractIconA) || + IsEqualIID(riid, &IID_IContextMenu) || + IsEqualIID(riid, &IID_IDataObject) || + IsEqualIID(riid, &IID_IQueryInfo)) + { + IUniformResourceLocatorW *pUrlLnk; + WCHAR szUrl[MAX_URL_LENGTH], *pszUrl = GetUrl(pUrl, szUrl); + HRESULT hr = CreateUrlShortcut(pszUrl, &pUrlLnk); + if (SUCCEEDED(hr)) + { + hr = IUnknown_QueryInterface(pUrlLnk, riid, ppv); + IUnknown_Release(pUrlLnk); + } + return hr; + } + } + return E_NOINTERFACE; +} + +static HRESULT WINAPI GetDisplayNameOf(IShellFolder *This, PCUITEMID_CHILD pidl, SHGDNF uFlags, STRRET *pSR) +{ + IFURLITEM *pUrl = IsUrlItem(pidl); + if (pUrl) + { + WCHAR szUrl[MAX_URL_LENGTH], *pszUrl = GetUrl(pUrl, szUrl); + pSR->uType = STRRET_WSTR; + return SHStrDupW(pszUrl, &pSR->u.pOleStr); + } + return E_FAIL; +} + +static HRESULT WINAPI SetNameOf(IShellFolder *This, HWND hwndOwner, PCUITEMID_CHILD pidl, LPCWSTR pszName, SHGDNF uFlags, PITEMID_CHILD*ppidlOut) +{ + if (ppidlOut) + *ppidlOut = NULL; + return E_NOTIMPL; +} + +static HRESULT WINAPI PersistFolder_QueryInterface(IPersistFolder *This, REFIID riid, PVOID *ppvObject) +{ + return Unknown_QueryInterface(CONTAINING_RECORD(This, CInternetFolder, IPersistFolder_iface), riid, ppvObject); +} + +static ULONG WINAPI PersistFolder_AddRef(IPersistFolder *This) +{ + return Unknown_AddRef(CONTAINING_RECORD(This, CInternetFolder, IPersistFolder_iface)); +} + +static ULONG WINAPI PersistFolder_Release(IPersistFolder *This) +{ + return Unknown_Release(CONTAINING_RECORD(This, CInternetFolder, IPersistFolder_iface)); +} + +static HRESULT WINAPI PersistFolder_GetClassID(IPersistFolder *This, CLSID *pClassID) +{ + *pClassID = CLSID_Internet; + return S_OK; +} + +static HRESULT WINAPI PersistFolder_Initialize(IPersistFolder *This, PCIDLIST_ABSOLUTE pidl) +{ + return S_OK; +} + +static const IShellFolderVtbl ShellFolderVtbl = { + ShellFolder_QueryInterface, + ShellFolder_AddRef, + ShellFolder_Release, + ParseDisplayName, + ShellFolder_EnumObjects, + BindToObject, + BindToStorage, + CompareIDs, + CreateViewObject, + GetAttributesOf, + GetUIObjectOf, + GetDisplayNameOf, + SetNameOf +}; + +static const IPersistFolderVtbl PersistFolderVtbl = { + PersistFolder_QueryInterface, + PersistFolder_AddRef, + PersistFolder_Release, + PersistFolder_GetClassID, + PersistFolder_Initialize +}; + +static CInternetFolder* CreateInstance(void) +{ + CInternetFolder *obj = SHAlloc(sizeof(CInternetFolder)); + if (obj) + { + obj->IShellFolder_iface.lpVtbl = &ShellFolderVtbl; + obj->IPersistFolder_iface.lpVtbl = &PersistFolderVtbl; + obj->refCount = 1; + lock_module(); + } + return obj; +} + +HRESULT WINAPI CInternetFolder_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv) +{ + CInternetFolder *pThis; + + *ppv = NULL; + if (outer) + return CLASS_E_NOAGGREGATION; + + if ((pThis = CreateInstance()) != NULL) + { + HRESULT hr = Unknown_QueryInterface(pThis, riid, ppv); + Unknown_Release(pThis); + return hr; + } + return E_OUTOFMEMORY; +} diff --git a/dll/win32/ieframe/lang/ro-RO.rc b/dll/win32/ieframe/lang/ro-RO.rc index f188dca989942..c31364a70ec1e 100644 --- a/dll/win32/ieframe/lang/ro-RO.rc +++ b/dll/win32/ieframe/lang/ro-RO.rc @@ -3,7 +3,7 @@ * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) * PURPOSE: Romanian resource file * TRANSLATORS: Copyright 2011-2018 Ștefan Fulea - * Copyright 2023 Andrei Miloiu + * Copyright 2023-2024 Andrei Miloiu */ LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL @@ -17,30 +17,30 @@ IDR_BROWSE_MAIN_MENU MENU MENUITEM "&Fereastră", ID_BROWSE_NEW_WINDOW } MENUITEM "&Deschidere…", ID_BROWSE_OPEN - MENUITEM "S&alvează", ID_BROWSE_SAVE - MENUITEM "Salvea&ză ca…", ID_BROWSE_SAVE_AS + MENUITEM "&Salvează", ID_BROWSE_SAVE + MENUITEM "S&alvare ca…", ID_BROWSE_SAVE_AS MENUITEM SEPARATOR - MENUITEM "Formatare imprima&bil…", ID_BROWSE_PRINT_FORMAT - MENUITEM "I&mprimare…", ID_BROWSE_PRINT - MENUITEM "Pre&vizionează pagină", ID_BROWSE_PRINT_PREVIEW + MENUITEM "Formatare i&mprimare…", ID_BROWSE_PRINT_FORMAT + MENUITEM "Im&primare…", ID_BROWSE_PRINT + MENUITEM "&Previzionare a paginii", ID_BROWSE_PRINT_PREVIEW MENUITEM SEPARATOR MENUITEM "Pr&oprietăți…", ID_BROWSE_PROPERTIES MENUITEM "I&eșire", ID_BROWSE_QUIT } POPUP "&Afișare" { - POPUP "&Bare" + POPUP "&Bare de instrumente" { MENUITEM "Bară stan&dard", ID_BROWSE_BAR_STD - MENUITEM "Bară de &adrasă", ID_BROWSE_BAR_ADDR + MENUITEM "Bară de &adresă", ID_BROWSE_BAR_ADDR } } POPUP "Fa&vorite" { - MENUITEM "&Adaugă la Favorite…", ID_BROWSE_ADDFAV + MENUITEM "&Adăugare la Favorite…", ID_BROWSE_ADDFAV MENUITEM SEPARATOR } - POPUP "Aj&utor" + POPUP "A&jutor" { MENUITEM "&Despre Internet Explorer", ID_BROWSE_ABOUT } @@ -48,13 +48,13 @@ IDR_BROWSE_MAIN_MENU MENU STRINGTABLE { - IDS_INTERNET "Navigatorul de Internet" - IDS_INTERNET_DESCRIPTION "Deschide navigatorul de rețea și afișează informații din Internet." + IDS_INTERNET "Browserul de Internet" + IDS_INTERNET_DESCRIPTION "Deschide un browser Web și afișează informații de pe Internet." IDS_TB_BACK "Înapoi" IDS_TB_FORWARD "Înainte" - IDS_TB_STOP "Oprește" - IDS_TB_REFRESH "Împrospătează" + IDS_TB_STOP "Oprire" + IDS_TB_REFRESH "Împrospătare" IDS_TB_HOME "Acasă" IDS_TB_PRINT "Imprimare…" } @@ -66,24 +66,24 @@ STRINGTABLE STRINGTABLE { - IDS_FINDINGRESOURCE "În căutarea resursei %s" - IDS_BEGINDOWNLOADDATA "În început de descărcare din %s" - IDS_ENDDOWNLOADDATA "În curs de descărcare din %s" - IDS_SENDINGREQUEST "În așteptarea răspunsului de la %s" + IDS_FINDINGRESOURCE "Se caută %s" + IDS_BEGINDOWNLOADDATA "Începe descărcarea %s" + IDS_ENDDOWNLOADDATA "Se descarcă %s" + IDS_SENDINGREQUEST "Se interoghează %s" } IDD_BROWSE_OPEN DIALOG 10, 10, 200, 70 STYLE DS_MODALFRAME | WS_CAPTION -CAPTION "Deschide URL" +CAPTION "Deschidere URL" FONT 8, "MS Shell Dlg" { - LTEXT "Specificați adresa URL pe care doriți s-o deschideți în Internet Explorer",-1, 35,5,160,25 + LTEXT "Specificați adresa URL pe care doriți să o deschideți în Internet Explorer",-1, 35,5,160,25 LTEXT "Deschide:", -1, 5, 32, 30, 15 #ifdef __REACTOS__ ICON IDC_PAGEICO, IDC_PAGEICO, 2, 5, 21, 20, SS_ICON #endif EDITTEXT IDC_BROWSE_OPEN_URL, 35, 30, 160, 13 - DEFPUSHBUTTON "Con&firmă", IDOK, 90, 50, 50, 14 - PUSHBUTTON "A&nulează", IDCANCEL, 145, 50, 50, 14 + DEFPUSHBUTTON "OK", IDOK, 90, 50, 50, 14 + PUSHBUTTON "Revocare", IDCANCEL, 145, 50, 50, 14 } diff --git a/dll/win32/iernonce/registry.cpp b/dll/win32/iernonce/registry.cpp index a5c764b6c58d9..c497b3d18f537 100644 --- a/dll/win32/iernonce/registry.cpp +++ b/dll/win32/iernonce/registry.cpp @@ -311,8 +311,11 @@ BOOL RunOnceExInstance::Exec(_In_opt_ HWND hwnd) m_SectionList[i].CloseAndDelete(m_RegKey); } - m_RegKey.DeleteValue(L"Title"); - m_RegKey.DeleteValue(L"Flags"); + if (m_RegKey) + { + m_RegKey.DeleteValue(L"Title"); + m_RegKey.DeleteValue(L"Flags"); + } // Notify the dialog all sections are handled. if (hwnd) diff --git a/dll/win32/imaadp32.acm/CMakeLists.txt b/dll/win32/imaadp32.acm/CMakeLists.txt index fa6e30a2479d3..b605f03acf852 100644 --- a/dll/win32/imaadp32.acm/CMakeLists.txt +++ b/dll/win32/imaadp32.acm/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(imaadp32.acm imaadp32.acm.spec) list(APPEND SOURCE @@ -13,3 +11,4 @@ set_target_properties(imaadp32.acm PROPERTIES SUFFIX "") target_link_libraries(imaadp32.acm wine) add_importlibs(imaadp32.acm winmm user32 msvcrt kernel32 ntdll) add_cd_file(TARGET imaadp32.acm DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(imaadp32.acm) # CORE-5743: No ARRAY_SIZE macro diff --git a/dll/win32/imm32/imm.c b/dll/win32/imm32/imm.c index 117cb52eaa91e..19c76137f011d 100644 --- a/dll/win32/imm32/imm.c +++ b/dll/win32/imm32/imm.c @@ -16,7 +16,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(imm); HMODULE ghImm32Inst = NULL; /* The IMM32 instance */ PSERVERINFO gpsi = NULL; -SHAREDINFO gSharedInfo = { NULL }; +SHAREDINFO gSharedInfo = { 0 }; BYTE gfImmInitialized = FALSE; /* Is IMM32 initialized? */ ULONG_PTR gHighestUserAddress = 0; @@ -57,7 +57,7 @@ static BOOL APIENTRY ImmInitializeGlobals(HMODULE hMod) BOOL WINAPI ImmRegisterClient(PSHAREDINFO ptr, HINSTANCE hMod) { gSharedInfo = *ptr; - gpsi = gSharedInfo.psi; + gpsi = WOW64_CAST_TO_PTR(gSharedInfo.psi); return ImmInitializeGlobals(hMod); } @@ -511,7 +511,7 @@ HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC) if (hIMC && IS_CROSS_THREAD_HIMC(hIMC)) return NULL; - hOldIMC = pWnd->hImc; + hOldIMC = WOW64_CAST_TO_HANDLE(pWnd->hImc); if (hOldIMC == hIMC) return hIMC; @@ -559,7 +559,7 @@ BOOL WINAPI ImmAssociateContextEx(HWND hWnd, HIMC hIMC, DWORD dwFlags) hwndFocus = (HWND)NtUserQueryWindow(hWnd, QUERY_WINDOW_FOCUS); pFocusWnd = ValidateHwnd(hwndFocus); if (pFocusWnd) - hOldIMC = pFocusWnd->hImc; + hOldIMC = WOW64_CAST_TO_HANDLE(pFocusWnd->hImc); dwValue = NtUserAssociateInputContext(hWnd, hIMC, dwFlags); switch (dwValue) @@ -571,7 +571,7 @@ BOOL WINAPI ImmAssociateContextEx(HWND hWnd, HIMC hIMC, DWORD dwFlags) pFocusWnd = ValidateHwnd(hwndFocus); if (pFocusWnd) { - hIMC = pFocusWnd->hImc; + hIMC = WOW64_CAST_TO_HANDLE(pFocusWnd->hImc); if (hIMC != hOldIMC) { ImmSetActiveContext(hwndFocus, hOldIMC, FALSE); @@ -662,7 +662,7 @@ BOOL APIENTRY Imm32DestroyInputContext(HIMC hIMC, HKL hKL, BOOL bKeep) if (IS_NULL_UNEXPECTEDLY(pIMC)) return FALSE; - if (pIMC->head.pti != Imm32CurrentPti()) + if (WOW64_CAST_TO_PTR(pIMC->head.pti) != Imm32CurrentPti()) { ERR("Thread mismatch\n"); return FALSE; @@ -1023,7 +1023,7 @@ static HIMC APIENTRY ImmGetSaveContext(HWND hWnd, DWORD dwContextFlags) if (IS_NULL_UNEXPECTEDLY(pWnd) || IS_CROSS_PROCESS_HWND(hWnd)) return NULL; - hIMC = pWnd->hImc; + hIMC = WOW64_CAST_TO_HANDLE(pWnd->hImc); if (!hIMC && (dwContextFlags & 1)) hIMC = (HIMC)NtUserQueryWindow(hWnd, QUERY_WINDOW_DEFAULT_ICONTEXT); diff --git a/dll/win32/imm32/keymsg.c b/dll/win32/imm32/keymsg.c index f1dd211b60749..0a7456e95c84a 100644 --- a/dll/win32/imm32/keymsg.c +++ b/dll/win32/imm32/keymsg.c @@ -525,7 +525,7 @@ Imm32ProcessRequest(HIMC hIMC, PWND pWnd, DWORD dwCommand, LPVOID pData, BOOL bA DoIt: /* The main task */ - hWnd = pWnd->head.h; + hWnd = WOW64_CAST_TO_HANDLE(pWnd->head.h); if (bAnsiWnd) ret = SendMessageA(hWnd, WM_IME_REQUEST, dwCommand, (LPARAM)pTempData); else @@ -597,7 +597,7 @@ LRESULT APIENTRY ImmRequestMessageAW(HIMC hIMC, WPARAM wParam, LPARAM lParam, BO if (hWnd) pWnd = ValidateHwnd(hWnd); - if (pWnd && pWnd->head.pti == Imm32CurrentPti()) + if (pWnd && WOW64_CAST_TO_PTR(pWnd->head.pti) == Imm32CurrentPti()) ret = Imm32ProcessRequest(hIMC, pWnd, (DWORD)wParam, (LPVOID)lParam, bAnsi); ImmUnlockIMC(hIMC); diff --git a/dll/win32/imm32/precomp.h b/dll/win32/imm32/precomp.h index 1f309737211ac..c2564002dd063 100644 --- a/dll/win32/imm32/precomp.h +++ b/dll/win32/imm32/precomp.h @@ -47,6 +47,8 @@ #include #include +#include "../../ntdll/wow64/ntdll32.h" + #define IMM_INIT_MAGIC 0x19650412 #define IMM_INVALID_CANDFORM ULONG_MAX #define INVALID_HOTKEY_ID 0xFFFFFFFF diff --git a/dll/win32/imm32/utils.c b/dll/win32/imm32/utils.c index 9fc0375b64dbb..1f4f7261a48f3 100644 --- a/dll/win32/imm32/utils.c +++ b/dll/win32/imm32/utils.c @@ -328,7 +328,7 @@ static PVOID FASTCALL DesktopPtrToUser(PVOID ptr) ASSERT(ptr != NULL); ASSERT(pdi != NULL); - if (pdi->pvDesktopBase <= ptr && ptr < pdi->pvDesktopLimit) + if (WOW64_CAST_TO_PTR(pdi->pvDesktopBase) <= ptr && ptr < WOW64_CAST_TO_PTR(pdi->pvDesktopLimit)) return (PVOID)((ULONG_PTR)ptr - pci->ulClientDelta); else return (PVOID)NtUserCallOneParam((DWORD_PTR)ptr, ONEPARAM_ROUTINE_GETDESKTOPMAPPING); @@ -349,7 +349,7 @@ LPVOID FASTCALL ValidateHandleNoErr(HANDLE hObject, UINT uType) return NULL; } - ht = gSharedInfo.aheList; /* handle table */ + ht = WOW64_CAST_TO_PTR(gSharedInfo.aheList); /* handle table */ ASSERT(ht); /* ReactOS-Specific! */ ASSERT(gSharedInfo.ulSharedDelta != 0); @@ -366,7 +366,7 @@ LPVOID FASTCALL ValidateHandleNoErr(HANDLE hObject, UINT uType) if (generation != he[index].generation && generation && generation != 0xFFFF) return NULL; - ptr = he[index].ptr; + ptr = WOW64_CAST_TO_PTR(he[index].ptr); if (ptr) ptr = DesktopPtrToUser(ptr); @@ -396,10 +396,10 @@ BOOL APIENTRY Imm32CheckImcProcess(PIMC pIMC) if (IS_NULL_UNEXPECTEDLY(pIMC)) return FALSE; - if (pIMC->head.pti == Imm32CurrentPti()) + if (WOW64_CAST_TO_PTR(pIMC->head.pti) == Imm32CurrentPti()) return TRUE; - hIMC = pIMC->head.h; + hIMC = WOW64_CAST_TO_HANDLE(pIMC->head.h); dwPID1 = (DWORD)NtUserQueryInputContext(hIMC, QIC_INPUTPROCESSID); dwPID2 = (DWORD_PTR)NtCurrentTeb()->ClientId.UniqueProcess; if (dwPID1 != dwPID2) diff --git a/dll/win32/inetcomm/CMakeLists.txt b/dll/win32/inetcomm/CMakeLists.txt index 90ff8513cdc89..9873c26a5137e 100644 --- a/dll/win32/inetcomm/CMakeLists.txt +++ b/dll/win32/inetcomm/CMakeLists.txt @@ -1,6 +1,5 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) +add_definitions(-D__ROS_LONG64__) spec2def(inetcomm.dll inetcomm.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -28,3 +27,4 @@ target_link_libraries(inetcomm uuid wine) add_importlibs(inetcomm ole32 oleaut32 ws2_32 user32 propsys urlmon msvcrt kernel32 ntdll) add_pch(inetcomm precomp.h "${PCH_SKIP_SOURCE}") add_cd_file(TARGET inetcomm DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(inetcomm) # CORE-5743: No ARRAY_SIZE and CONST_VTABLE diff --git a/dll/win32/inetcomm/inetcomm_main.c b/dll/win32/inetcomm/inetcomm_main.c index 754362866310a..c916ea18d747f 100644 --- a/dll/win32/inetcomm/inetcomm_main.c +++ b/dll/win32/inetcomm/inetcomm_main.c @@ -48,8 +48,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) switch (fdwReason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hinstDLL); instance = hinstDLL; diff --git a/dll/win32/inetmib1/CMakeLists.txt b/dll/win32/inetmib1/CMakeLists.txt index dd1cc379bdb99..8cb3f2da3a81f 100644 --- a/dll/win32/inetmib1/CMakeLists.txt +++ b/dll/win32/inetmib1/CMakeLists.txt @@ -1,6 +1,5 @@ -add_definitions(-D__WINESRC__ -D__ROS_LONG64__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) +add_definitions(-D__ROS_LONG64__) spec2def(inetmib1.dll inetmib1.spec) list(APPEND SOURCE @@ -14,3 +13,4 @@ target_link_libraries(inetmib1 wine) add_delay_importlibs(inetmib1 iphlpapi) add_importlibs(inetmib1 snmpapi msvcrt kernel32 ntdll) add_cd_file(TARGET inetmib1 DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(inetmib1) # CORE-5743: No ARRAY_SIZE macro diff --git a/dll/win32/initpki/CMakeLists.txt b/dll/win32/initpki/CMakeLists.txt index 406ece9b3a713..e18ca1b8b7d5d 100644 --- a/dll/win32/initpki/CMakeLists.txt +++ b/dll/win32/initpki/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(initpki.dll initpki.spec) list(APPEND SOURCE @@ -13,3 +11,4 @@ set_module_type(initpki win32dll) target_link_libraries(initpki wine) add_importlibs(initpki msvcrt kernel32 ntdll) add_cd_file(TARGET initpki DESTINATION reactos/system32 FOR all) +set_wine_module(initpki) diff --git a/dll/win32/initpki/main.c b/dll/win32/initpki/main.c index b7260f37ee068..0583f7152e9b1 100644 --- a/dll/win32/initpki/main.c +++ b/dll/win32/initpki/main.c @@ -31,8 +31,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) switch (fdwReason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hinstDLL); break; diff --git a/dll/win32/inseng/CMakeLists.txt b/dll/win32/inseng/CMakeLists.txt index b8dee48b7cfdb..05865d496eaf6 100644 --- a/dll/win32/inseng/CMakeLists.txt +++ b/dll/win32/inseng/CMakeLists.txt @@ -3,11 +3,9 @@ remove_definitions(-D_WIN32_WINNT=0x502) add_definitions(-D_WIN32_WINNT=0x600) add_definitions( - -D__WINESRC__ -Dstrcasecmp=_stricmp -Dstrncasecmp=_strnicmp ) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(inseng.dll inseng.spec) list(APPEND SOURCE @@ -30,3 +28,4 @@ target_link_libraries(inseng uuid wine) add_importlibs(inseng ole32 urlmon kernel32_vista msvcrt kernel32 ntdll) add_pch(inseng precomp.h "${PCH_SKIP_SOURCE}") add_cd_file(TARGET inseng DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(inseng) # CORE-5743: No CONST_VTABLE diff --git a/dll/win32/inseng/inseng_main.c b/dll/win32/inseng/inseng_main.c index 213b27ee7b8a0..958724275d736 100644 --- a/dll/win32/inseng/inseng_main.c +++ b/dll/win32/inseng/inseng_main.c @@ -1275,8 +1275,10 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) { switch(fdwReason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: instance = hInstDLL; DisableThreadLibraryCalls(hInstDLL); diff --git a/dll/win32/itircl/CMakeLists.txt b/dll/win32/itircl/CMakeLists.txt index e6b3f6a6db782..eb6f5dcb5cf43 100644 --- a/dll/win32/itircl/CMakeLists.txt +++ b/dll/win32/itircl/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(itircl.dll itircl.spec) list(APPEND SOURCE @@ -13,3 +11,4 @@ set_module_type(itircl win32dll) target_link_libraries(itircl wine) add_importlibs(itircl msvcrt kernel32 ntdll) add_cd_file(TARGET itircl DESTINATION reactos/system32 FOR all) +set_wine_module(itircl) diff --git a/dll/win32/itircl/itircl_main.c b/dll/win32/itircl/itircl_main.c index e35bbba3359b2..9b18a7423fca0 100644 --- a/dll/win32/itircl/itircl_main.c +++ b/dll/win32/itircl/itircl_main.c @@ -33,8 +33,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) switch (fdwReason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hinstDLL); break; diff --git a/dll/win32/itss/CMakeLists.txt b/dll/win32/itss/CMakeLists.txt index 7568e08f6f84b..35283930d7e5a 100644 --- a/dll/win32/itss/CMakeLists.txt +++ b/dll/win32/itss/CMakeLists.txt @@ -1,6 +1,5 @@ -add_definitions(-D__WINESRC__ -D__ROS_LONG64__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) +add_definitions(-D__ROS_LONG64__) spec2def(itss.dll itss.spec) list(APPEND SOURCE @@ -27,3 +26,4 @@ add_importlibs(itss urlmon shlwapi ole32 msvcrt kernel32 ntdll) add_pch(itss precomp.h "${PCH_SKIP_SOURCE}") add_dependencies(itss wineheaders) add_cd_file(TARGET itss DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(itss) # CORE-5743: No ARRAY_SIZE and CONST_VTABLE diff --git a/dll/win32/jscript/lang/jscript_Da.rc b/dll/win32/jscript/lang/jscript_Da.rc index 6f043fb960473..e373a0af9b6c7 100644 --- a/dll/win32/jscript/lang/jscript_Da.rc +++ b/dll/win32/jscript/lang/jscript_Da.rc @@ -17,8 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_DANISH, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/jscript/lang/jscript_De.rc b/dll/win32/jscript/lang/jscript_De.rc index 88751d4a8cfec..967a39fcab441 100644 --- a/dll/win32/jscript/lang/jscript_De.rc +++ b/dll/win32/jscript/lang/jscript_De.rc @@ -16,8 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/jscript/lang/jscript_Es.rc b/dll/win32/jscript/lang/jscript_Es.rc index 5ab0de96853fa..73cfe3b8f02f8 100644 --- a/dll/win32/jscript/lang/jscript_Es.rc +++ b/dll/win32/jscript/lang/jscript_Es.rc @@ -16,9 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/*UTF-8*/ -#pragma code_page(65001) - LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/jscript/lang/jscript_Fr.rc b/dll/win32/jscript/lang/jscript_Fr.rc index cf250f3ea5aad..dc5abfde4df41 100644 --- a/dll/win32/jscript/lang/jscript_Fr.rc +++ b/dll/win32/jscript/lang/jscript_Fr.rc @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/jscript/lang/jscript_Hu.rc b/dll/win32/jscript/lang/jscript_Hu.rc index 3c2061a28828d..401ccd9ca1565 100644 --- a/dll/win32/jscript/lang/jscript_Hu.rc +++ b/dll/win32/jscript/lang/jscript_Hu.rc @@ -16,9 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/jscript/lang/jscript_It.rc b/dll/win32/jscript/lang/jscript_It.rc index 52a11c1ba9b4a..23fa96588a9cd 100644 --- a/dll/win32/jscript/lang/jscript_It.rc +++ b/dll/win32/jscript/lang/jscript_It.rc @@ -17,9 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/jscript/lang/jscript_Ja.rc b/dll/win32/jscript/lang/jscript_Ja.rc index 2e2c48f1c0055..415eaee49e3fe 100644 --- a/dll/win32/jscript/lang/jscript_Ja.rc +++ b/dll/win32/jscript/lang/jscript_Ja.rc @@ -17,9 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/jscript/lang/jscript_Ko.rc b/dll/win32/jscript/lang/jscript_Ko.rc index acd1747afea71..59c39aadd3cd7 100644 --- a/dll/win32/jscript/lang/jscript_Ko.rc +++ b/dll/win32/jscript/lang/jscript_Ko.rc @@ -17,9 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/jscript/lang/jscript_Lt.rc b/dll/win32/jscript/lang/jscript_Lt.rc index 8e77fef5dfbc5..b180923b2130e 100644 --- a/dll/win32/jscript/lang/jscript_Lt.rc +++ b/dll/win32/jscript/lang/jscript_Lt.rc @@ -16,9 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_LITHUANIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/jscript/lang/jscript_Nl.rc b/dll/win32/jscript/lang/jscript_Nl.rc index 164d668d822b1..d4fef4621c642 100644 --- a/dll/win32/jscript/lang/jscript_Nl.rc +++ b/dll/win32/jscript/lang/jscript_Nl.rc @@ -18,8 +18,6 @@ LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL -#pragma code_page(65001) - STRINGTABLE { IDS_TO_PRIMITIVE "Fout bij het omzetten van het object naar een primitief type" diff --git a/dll/win32/jscript/lang/jscript_No.rc b/dll/win32/jscript/lang/jscript_No.rc index 1273e889d884f..1112371cfd9e0 100644 --- a/dll/win32/jscript/lang/jscript_No.rc +++ b/dll/win32/jscript/lang/jscript_No.rc @@ -16,8 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL STRINGTABLE diff --git a/dll/win32/jscript/lang/jscript_Pt.rc b/dll/win32/jscript/lang/jscript_Pt.rc index 26ce7ff983486..5016e05f4037e 100644 --- a/dll/win32/jscript/lang/jscript_Pt.rc +++ b/dll/win32/jscript/lang/jscript_Pt.rc @@ -17,8 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN STRINGTABLE diff --git a/dll/win32/jscript/lang/jscript_Ro.rc b/dll/win32/jscript/lang/jscript_Ro.rc index 40650c482f114..da3db3e404cc3 100644 --- a/dll/win32/jscript/lang/jscript_Ro.rc +++ b/dll/win32/jscript/lang/jscript_Ro.rc @@ -22,8 +22,6 @@ LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL -#pragma code_page(65001) - STRINGTABLE { IDS_TO_PRIMITIVE "Eroare la convertirea obiectului la un tip primitiv" diff --git a/dll/win32/jscript/lang/jscript_Ru.rc b/dll/win32/jscript/lang/jscript_Ru.rc index c4e9d80f2075b..274e8a659681b 100644 --- a/dll/win32/jscript/lang/jscript_Ru.rc +++ b/dll/win32/jscript/lang/jscript_Ru.rc @@ -17,9 +17,6 @@ */ /* Russian language resource file by Kudratov Olimjon (olim98@bk.ru) */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/jscript/lang/jscript_Si.rc b/dll/win32/jscript/lang/jscript_Si.rc index 8368d6474d58b..b49e212bb227f 100644 --- a/dll/win32/jscript/lang/jscript_Si.rc +++ b/dll/win32/jscript/lang/jscript_Si.rc @@ -16,8 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/jscript/lang/jscript_Uk.rc b/dll/win32/jscript/lang/jscript_Uk.rc index 677f773de3a06..90eb81897361c 100644 --- a/dll/win32/jscript/lang/jscript_Uk.rc +++ b/dll/win32/jscript/lang/jscript_Uk.rc @@ -17,9 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/jscript/lang/jscript_Zh.rc b/dll/win32/jscript/lang/jscript_Zh.rc index 5e69793ae1762..c2a11dc12a513 100644 --- a/dll/win32/jscript/lang/jscript_Zh.rc +++ b/dll/win32/jscript/lang/jscript_Zh.rc @@ -19,9 +19,6 @@ * Copyright 2021 Chan Chilung */ -/* Chinese text is encoded in UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED STRINGTABLE diff --git a/dll/win32/jsproxy/CMakeLists.txt b/dll/win32/jsproxy/CMakeLists.txt index 46ae1b7ecf1d9..095193ad86575 100644 --- a/dll/win32/jsproxy/CMakeLists.txt +++ b/dll/win32/jsproxy/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(jsproxy.dll jsproxy.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -13,3 +11,4 @@ set_module_type(jsproxy win32dll) target_link_libraries(jsproxy uuid wine) add_importlibs(jsproxy oleaut32 ole32 ws2_32 msvcrt kernel32 ntdll) add_cd_file(TARGET jsproxy DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(jsproxy) # CORE-5743: No ARRAY_SIZE and CONST_VTABLE diff --git a/dll/win32/kernel32/CMakeLists.txt b/dll/win32/kernel32/CMakeLists.txt index 4661ef9b0cb86..b037e6978007c 100644 --- a/dll/win32/kernel32/CMakeLists.txt +++ b/dll/win32/kernel32/CMakeLists.txt @@ -130,7 +130,7 @@ set_module_type(kernel32 win32dll ENTRYPOINT DllMain 12) set_subsystem(kernel32 console) ################# END HACK ################# -target_link_libraries(kernel32 kernel32_vista_static kernel32_shared wine chkstk ${PSEH_LIB}) +target_link_libraries(kernel32 psapi_static kernel32_vista_static kernel32_shared wine chkstk ${PSEH_LIB}) add_importlibs(kernel32 ntdll) add_pch(kernel32 k32.h SOURCE) add_dependencies(kernel32 psdk errcodes asm) diff --git a/dll/win32/kernel32/client/actctx.c b/dll/win32/kernel32/client/actctx.c index cad514ef065c3..fe43928ab8aa0 100644 --- a/dll/win32/kernel32/client/actctx.c +++ b/dll/win32/kernel32/client/actctx.c @@ -156,7 +156,7 @@ BasepProbeForDllManifest(IN PVOID DllHandle, /* Check whether the image has manifest resource associated with it */ Info.Type = (ULONG_PTR)RT_MANIFEST; Info.Name = (ULONG_PTR)ISOLATIONAWARE_MANIFEST_RESOURCE_ID; - Info.Language = 0; + Info.Language = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL); if (!(Status = LdrFindResource_U(DllHandle, &Info, 3, &Entry))) { /* Create the activation context */ diff --git a/dll/win32/kernel32/client/console/alias.c b/dll/win32/kernel32/client/console/alias.c index d835c05632bd4..ea68971b938bc 100644 --- a/dll/win32/kernel32/client/console/alias.c +++ b/dll/win32/kernel32/client/console/alias.c @@ -39,7 +39,7 @@ IntAddConsoleAlias(LPCVOID Source, return FALSE; } - ConsoleAliasRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + ConsoleAliasRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); /* Determine the needed sizes */ ConsoleAliasRequest->SourceLength = SourceBufferLength; @@ -91,7 +91,7 @@ IntAddConsoleAlias(LPCVOID Source, } else { - ConsoleAliasRequest->Target = NULL; + ConsoleAliasRequest->Target = (LPC_PVOID)NULL; } CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, @@ -187,7 +187,7 @@ IntGetConsoleAlias(LPVOID Source, return 0; } - ConsoleAliasRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + ConsoleAliasRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); /* Determine the needed sizes */ ConsoleAliasRequest->SourceLength = SourceBufferLength; @@ -241,7 +241,7 @@ IntGetConsoleAlias(LPVOID Source, /* Copy the returned target string into the user buffer */ RtlCopyMemory(Target, - ConsoleAliasRequest->Target, + (PVOID)ConsoleAliasRequest->Target, ConsoleAliasRequest->TargetLength); /* Release the capture buffer and exit */ @@ -315,7 +315,7 @@ IntGetConsoleAliases(LPVOID AliasBuffer, return 0; } - GetAllAliasesRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + GetAllAliasesRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); /* Determine the needed sizes */ GetAllAliasesRequest->ExeLength = NumChars * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR)); @@ -357,7 +357,7 @@ IntGetConsoleAliases(LPVOID AliasBuffer, /* Copy the returned aliases string into the user buffer */ RtlCopyMemory(AliasBuffer, - GetAllAliasesRequest->AliasesBuffer, + (PVOID)GetAllAliasesRequest->AliasesBuffer, GetAllAliasesRequest->AliasesBufferLength); /* Release the capture buffer and exit */ @@ -422,7 +422,7 @@ IntGetConsoleAliasesLength(LPVOID lpExeName, BOOLEAN bUnicode) return 0; } - GetAllAliasesLengthRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + GetAllAliasesLengthRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); GetAllAliasesLengthRequest->ExeLength = NumChars * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR)); GetAllAliasesLengthRequest->Unicode = GetAllAliasesLengthRequest->Unicode2 = bUnicode; @@ -490,7 +490,7 @@ IntGetConsoleAliasExes(PVOID lpExeNameBuffer, PCONSOLE_GETALIASESEXES GetAliasesExesRequest = &ApiMessage.Data.GetAliasesExesRequest; PCSR_CAPTURE_BUFFER CaptureBuffer; - GetAliasesExesRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + GetAliasesExesRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); GetAliasesExesRequest->Length = ExeNameBufferLength; GetAliasesExesRequest->Unicode = bUnicode; @@ -518,7 +518,7 @@ IntGetConsoleAliasExes(PVOID lpExeNameBuffer, } RtlCopyMemory(lpExeNameBuffer, - GetAliasesExesRequest->ExeNames, + (PVOID)GetAliasesExesRequest->ExeNames, GetAliasesExesRequest->Length); CsrFreeCaptureBuffer(CaptureBuffer); @@ -560,7 +560,7 @@ IntGetConsoleAliasExesLength(BOOLEAN bUnicode) CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_GETALIASESEXESLENGTH GetAliasesExesLengthRequest = &ApiMessage.Data.GetAliasesExesLengthRequest; - GetAliasesExesLengthRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + GetAliasesExesLengthRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); GetAliasesExesLengthRequest->Unicode = bUnicode; CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, diff --git a/dll/win32/kernel32/client/console/console.c b/dll/win32/kernel32/client/console/console.c index dfa8ab7f21b4f..552d7ac8cc715 100644 --- a/dll/win32/kernel32/client/console/console.c +++ b/dll/win32/kernel32/client/console/console.c @@ -400,8 +400,8 @@ ConsoleMenuControl(HANDLE hConsoleOutput, CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_MENUCONTROL MenuControlRequest = &ApiMessage.Data.MenuControlRequest; - MenuControlRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - MenuControlRequest->OutputHandle = hConsoleOutput; + MenuControlRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + MenuControlRequest->OutputHandle = TO_LPC_HANDLE(hConsoleOutput); MenuControlRequest->CmdIdLow = dwCmdIdLow; MenuControlRequest->CmdIdHigh = dwCmdIdHigh; MenuControlRequest->MenuHandle = NULL; @@ -437,8 +437,8 @@ DuplicateConsoleHandle(HANDLE hConsole, return INVALID_HANDLE_VALUE; } - DuplicateHandleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - DuplicateHandleRequest->SourceHandle = hConsole; + DuplicateHandleRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + DuplicateHandleRequest->SourceHandle = TO_LPC_HANDLE(hConsole); DuplicateHandleRequest->DesiredAccess = dwDesiredAccess; DuplicateHandleRequest->InheritHandle = bInheritHandle; DuplicateHandleRequest->Options = dwOptions; @@ -453,7 +453,7 @@ DuplicateConsoleHandle(HANDLE hConsole, return INVALID_HANDLE_VALUE; } - return DuplicateHandleRequest->TargetHandle; + return FROM_LPC_HANDLE(DuplicateHandleRequest->TargetHandle); } @@ -468,8 +468,8 @@ GetConsoleHandleInformation(IN HANDLE hHandle, CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_GETHANDLEINFO GetHandleInfoRequest = &ApiMessage.Data.GetHandleInfoRequest; - GetHandleInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - GetHandleInfoRequest->Handle = hHandle; + GetHandleInfoRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + GetHandleInfoRequest->Handle = TO_LPC_HANDLE(hHandle); CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, @@ -499,8 +499,8 @@ SetConsoleHandleInformation(IN HANDLE hHandle, CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_SETHANDLEINFO SetHandleInfoRequest = &ApiMessage.Data.SetHandleInfoRequest; - SetHandleInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - SetHandleInfoRequest->Handle = hHandle; + SetHandleInfoRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + SetHandleInfoRequest->Handle = TO_LPC_HANDLE(hHandle); SetHandleInfoRequest->Mask = dwMask; SetHandleInfoRequest->Flags = dwFlags; @@ -534,7 +534,7 @@ GetConsoleDisplayMode(LPDWORD lpModeFlags) return FALSE; } - GetDisplayModeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + GetDisplayModeRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, @@ -554,7 +554,7 @@ GetConsoleDisplayMode(LPDWORD lpModeFlags) /* * @implemented (Undocumented) - * @note See http://cboard.cprogramming.com/windows-programming/102187-console-font-size.html + * @note See https://cboard.cprogramming.com/windows-programming/102187-console-font-size.html */ DWORD WINAPI @@ -567,8 +567,8 @@ GetConsoleFontInfo(IN HANDLE hConsoleOutput, PCONSOLE_GETFONTINFO GetFontInfoRequest = &ApiMessage.Data.GetFontInfoRequest; PCSR_CAPTURE_BUFFER CaptureBuffer; - GetFontInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - GetFontInfoRequest->OutputHandle = hConsoleOutput; + GetFontInfoRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + GetFontInfoRequest->OutputHandle = TO_LPC_HANDLE(hConsoleOutput); GetFontInfoRequest->MaximumWindow = bMaximumWindow; GetFontInfoRequest->NumFonts = nFontCount; @@ -595,7 +595,7 @@ GetConsoleFontInfo(IN HANDLE hConsoleOutput, else { RtlCopyMemory(lpConsoleFontInfo, - GetFontInfoRequest->FontInfo, + (PVOID)GetFontInfoRequest->FontInfo, GetFontInfoRequest->NumFonts * sizeof(CONSOLE_FONT_INFO)); } @@ -617,8 +617,8 @@ GetConsoleFontSize(IN HANDLE hConsoleOutput, PCONSOLE_GETFONTSIZE GetFontSizeRequest = &ApiMessage.Data.GetFontSizeRequest; COORD Empty = {0, 0}; - GetFontSizeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - GetFontSizeRequest->OutputHandle = hConsoleOutput; + GetFontSizeRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + GetFontSizeRequest->OutputHandle = TO_LPC_HANDLE(hConsoleOutput); GetFontSizeRequest->FontIndex = nFont; CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, @@ -655,8 +655,8 @@ GetConsoleHardwareState(HANDLE hConsoleOutput, return FALSE; } - HardwareStateRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - HardwareStateRequest->OutputHandle = hConsoleOutput; + HardwareStateRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + HardwareStateRequest->OutputHandle = TO_LPC_HANDLE(hConsoleOutput); CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, @@ -698,8 +698,8 @@ GetCurrentConsoleFont(IN HANDLE hConsoleOutput, CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_GETCURRENTFONT GetCurrentFontRequest = &ApiMessage.Data.GetCurrentFontRequest; - GetCurrentFontRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - GetCurrentFontRequest->OutputHandle = hConsoleOutput; + GetCurrentFontRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + GetCurrentFontRequest->OutputHandle = TO_LPC_HANDLE(hConsoleOutput); GetCurrentFontRequest->MaximumWindow = bMaximumWindow; CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, @@ -721,7 +721,7 @@ GetCurrentConsoleFont(IN HANDLE hConsoleOutput, /* * @implemented (Undocumented) - * @note See http://cboard.cprogramming.com/windows-programming/102187-console-font-size.html + * @note See https://cboard.cprogramming.com/windows-programming/102187-console-font-size.html */ DWORD WINAPI @@ -731,7 +731,7 @@ GetNumberOfConsoleFonts(VOID) CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_GETNUMFONTS GetNumFontsRequest = &ApiMessage.Data.GetNumFontsRequest; - GetNumFontsRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + GetNumFontsRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, @@ -765,8 +765,8 @@ InvalidateConsoleDIBits(IN HANDLE hConsoleOutput, return FALSE; } - InvalidateDIBitsRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - InvalidateDIBitsRequest->OutputHandle = hConsoleOutput; + InvalidateDIBitsRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + InvalidateDIBitsRequest->OutputHandle = TO_LPC_HANDLE(hConsoleOutput); InvalidateDIBitsRequest->Region = *lpRect; CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, @@ -818,7 +818,7 @@ OpenConsoleW(LPCWSTR wsName, return INVALID_HANDLE_VALUE; } - OpenConsoleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + OpenConsoleRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); OpenConsoleRequest->HandleType = HandleType; OpenConsoleRequest->DesiredAccess = dwDesiredAccess; OpenConsoleRequest->InheritHandle = bInheritHandle; @@ -834,7 +834,7 @@ OpenConsoleW(LPCWSTR wsName, return INVALID_HANDLE_VALUE; } - return OpenConsoleRequest->Handle; + return FROM_LPC_HANDLE(OpenConsoleRequest->Handle); } @@ -851,8 +851,8 @@ SetConsoleCursor(HANDLE hConsoleOutput, CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_SETCURSOR SetCursorRequest = &ApiMessage.Data.SetCursorRequest; - SetCursorRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - SetCursorRequest->OutputHandle = hConsoleOutput; + SetCursorRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + SetCursorRequest->OutputHandle = TO_LPC_HANDLE(hConsoleOutput); SetCursorRequest->CursorHandle = hCursor; CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, @@ -881,8 +881,8 @@ SetConsoleDisplayMode(HANDLE hConsoleOutput, CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_SETDISPLAYMODE SetDisplayModeRequest = &ApiMessage.Data.SetDisplayModeRequest; - SetDisplayModeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - SetDisplayModeRequest->OutputHandle = hConsoleOutput; + SetDisplayModeRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + SetDisplayModeRequest->OutputHandle = TO_LPC_HANDLE(hConsoleOutput); SetDisplayModeRequest->DisplayMode = dwFlags; // ModeFlags ; dwModeFlags SetDisplayModeRequest->NewSBDim.X = 0; SetDisplayModeRequest->NewSBDim.Y = 0; @@ -907,7 +907,7 @@ SetConsoleDisplayMode(HANDLE hConsoleOutput, /* * @implemented (Undocumented) - * @note See http://cboard.cprogramming.com/windows-programming/102187-console-font-size.html + * @note See https://cboard.cprogramming.com/windows-programming/102187-console-font-size.html */ BOOL WINAPI @@ -918,8 +918,8 @@ SetConsoleFont(IN HANDLE hConsoleOutput, CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_SETFONT SetFontRequest = &ApiMessage.Data.SetFontRequest; - SetFontRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - SetFontRequest->OutputHandle = hConsoleOutput; + SetFontRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + SetFontRequest->OutputHandle = TO_LPC_HANDLE(hConsoleOutput); SetFontRequest->FontIndex = nFont; CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, @@ -950,8 +950,8 @@ SetConsoleHardwareState(HANDLE hConsoleOutput, DPRINT1("SetConsoleHardwareState(%lu, %lu) UNIMPLEMENTED!\n", Flags, State); - HardwareStateRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - HardwareStateRequest->OutputHandle = hConsoleOutput; + HardwareStateRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + HardwareStateRequest->OutputHandle = TO_LPC_HANDLE(hConsoleOutput); HardwareStateRequest->Flags = Flags; HardwareStateRequest->State = State; @@ -1013,7 +1013,7 @@ SetConsoleMenuClose(BOOL bEnable) CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_SETMENUCLOSE SetMenuCloseRequest = &ApiMessage.Data.SetMenuCloseRequest; - SetMenuCloseRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + SetMenuCloseRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); SetMenuCloseRequest->Enable = bEnable; CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, @@ -1032,7 +1032,7 @@ SetConsoleMenuClose(BOOL bEnable) /* * @implemented (Undocumented) - * @note See http://comments.gmane.org/gmane.comp.lang.harbour.devel/27844 + * @note See http://comments.gmane.org/gmane.comp.lang.harbour.devel/27844 (DEAD_LINK) * Usage example: https://github.com/harbour/core/commit/d79a1b7b812cbde6ddf718ebfd6939a24f633e52 */ BOOL @@ -1045,9 +1045,9 @@ SetConsolePalette(HANDLE hConsoleOutput, CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_SETPALETTE SetPaletteRequest = &ApiMessage.Data.SetPaletteRequest; - SetPaletteRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - SetPaletteRequest->OutputHandle = hConsoleOutput; - SetPaletteRequest->PaletteHandle = hPalette; + SetPaletteRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + SetPaletteRequest->OutputHandle = TO_LPC_HANDLE(hConsoleOutput); + SetPaletteRequest->PaletteHandle = (LPC_PTRTYPE(HPALETTE))hPalette; SetPaletteRequest->Usage = dwUsage; CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, @@ -1076,8 +1076,8 @@ ShowConsoleCursor(HANDLE hConsoleOutput, CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_SHOWCURSOR ShowCursorRequest = &ApiMessage.Data.ShowCursorRequest; - ShowCursorRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - ShowCursorRequest->OutputHandle = hConsoleOutput; + ShowCursorRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + ShowCursorRequest->OutputHandle = TO_LPC_HANDLE(hConsoleOutput); ShowCursorRequest->Show = bShow; ShowCursorRequest->RefCount = 0; @@ -1112,12 +1112,12 @@ VerifyConsoleIoHandle(HANDLE hIoHandle) CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_VERIFYHANDLE VerifyHandleRequest = &ApiMessage.Data.VerifyHandleRequest; - VerifyHandleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - VerifyHandleRequest->Handle = hIoHandle; + VerifyHandleRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + VerifyHandleRequest->Handle = TO_LPC_HANDLE(hIoHandle); VerifyHandleRequest->IsValid = FALSE; /* If the process is not attached to a console, return invalid handle */ - if (VerifyHandleRequest->ConsoleHandle == NULL) return FALSE; + if (VerifyHandleRequest->ConsoleHandle == (LPC_HANDLE)NULL) return FALSE; CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, @@ -1144,8 +1144,8 @@ CloseConsoleHandle(HANDLE hHandle) CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_CLOSEHANDLE CloseHandleRequest = &ApiMessage.Data.CloseHandleRequest; - CloseHandleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - CloseHandleRequest->Handle = hHandle; + CloseHandleRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + CloseHandleRequest->Handle = TO_LPC_HANDLE(hHandle); CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, @@ -1230,15 +1230,15 @@ SetStdHandle(DWORD nStdHandle, switch (nStdHandle) { case STD_INPUT_HANDLE: - Ppb->StandardInput = hHandle; + Ppb->StandardInput = FROM_LPC_HANDLE(hHandle); return TRUE; case STD_OUTPUT_HANDLE: - Ppb->StandardOutput = hHandle; + Ppb->StandardOutput = FROM_LPC_HANDLE(hHandle); return TRUE; case STD_ERROR_HANDLE: - Ppb->StandardError = hHandle; + Ppb->StandardError = FROM_LPC_HANDLE(hHandle); return TRUE; } @@ -1266,13 +1266,15 @@ IntAllocConsole(LPWSTR Title, { BOOL Success = TRUE; NTSTATUS Status; + HANDLE Temp[MAX_INIT_EVENTS]; + INT i; CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_ALLOCCONSOLE AllocConsoleRequest = &ApiMessage.Data.AllocConsoleRequest; PCSR_CAPTURE_BUFFER CaptureBuffer; - AllocConsoleRequest->CtrlRoutine = CtrlRoutine; - AllocConsoleRequest->PropRoutine = PropRoutine; + AllocConsoleRequest->CtrlRoutine = (LPC_PTRTYPE(LPTHREAD_START_ROUTINE))CtrlRoutine; + AllocConsoleRequest->PropRoutine = (LPC_PTRTYPE(LPTHREAD_START_ROUTINE))PropRoutine; CaptureBuffer = CsrAllocateCaptureBuffer(5, TitleLength + DesktopLength + @@ -1326,9 +1328,11 @@ IntAllocConsole(LPWSTR Title, goto Quit; } - // Is AllocConsoleRequest->ConsoleStartInfo->InitEvents aligned on handle boundary ???? + for (i = 0; i < MAX_INIT_EVENTS; i++) Temp[i] = FROM_LPC_HANDLE(((PCONSOLE_START_INFO)AllocConsoleRequest->ConsoleStartInfo)->InitEvents[i]); + + // Is ((PCONSOLE_START_INFO)AllocConsoleRequest->ConsoleStartInfo)->InitEvents aligned on handle boundary ???? Status = NtWaitForMultipleObjects(MAX_INIT_EVENTS, - AllocConsoleRequest->ConsoleStartInfo->InitEvents, + Temp, WaitAny, FALSE, NULL); if (!NT_SUCCESS(Status)) { @@ -1337,8 +1341,8 @@ IntAllocConsole(LPWSTR Title, goto Quit; } - NtClose(AllocConsoleRequest->ConsoleStartInfo->InitEvents[INIT_SUCCESS]); - NtClose(AllocConsoleRequest->ConsoleStartInfo->InitEvents[INIT_FAILURE]); + NtClose(FROM_LPC_HANDLE(((PCONSOLE_START_INFO)AllocConsoleRequest->ConsoleStartInfo)->InitEvents[INIT_SUCCESS])); + NtClose(FROM_LPC_HANDLE(((PCONSOLE_START_INFO)AllocConsoleRequest->ConsoleStartInfo)->InitEvents[INIT_FAILURE])); if (Status != INIT_SUCCESS) { NtCurrentPeb()->ProcessParameters->ConsoleHandle = NULL; @@ -1347,7 +1351,7 @@ IntAllocConsole(LPWSTR Title, else { RtlCopyMemory(ConsoleStartInfo, - AllocConsoleRequest->ConsoleStartInfo, + (PVOID)AllocConsoleRequest->ConsoleStartInfo, sizeof(CONSOLE_START_INFO)); Success = TRUE; } @@ -1366,7 +1370,7 @@ AllocConsole(VOID) CONSOLE_START_INFO ConsoleStartInfo; PWCHAR ConsoleTitle; - PWCHAR Desktop; + LPC_PTRTYPE(PWCHAR) Desktop; PWCHAR AppName; PWCHAR CurDir; @@ -1407,7 +1411,7 @@ AllocConsole(VOID) Success = IntAllocConsole(ConsoleTitle, TitleLength, - Desktop, + (PVOID)Desktop, DesktopLength, CurDir, CurDirLength, @@ -1420,7 +1424,7 @@ AllocConsole(VOID) { /* Set up the handles */ SetUpHandles(&ConsoleStartInfo); - InputWaitHandle = ConsoleStartInfo.InputWaitHandle; + InputWaitHandle = FROM_LPC_HANDLE(ConsoleStartInfo.InputWaitHandle); /* Initialize Console Ctrl Handling */ InitializeCtrlHandling(); @@ -1459,7 +1463,7 @@ FreeConsole(VOID) } /* Set up the data to send to the Console Server */ - FreeConsoleRequest->ConsoleHandle = ConsoleHandle; + FreeConsoleRequest->ConsoleHandle = TO_LPC_HANDLE(ConsoleHandle); /* Call the server */ CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, @@ -1505,8 +1509,8 @@ GetConsoleScreenBufferInfo(HANDLE hConsoleOutput, return FALSE; } - ScreenBufferInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - ScreenBufferInfoRequest->OutputHandle = hConsoleOutput; + ScreenBufferInfoRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + ScreenBufferInfoRequest->OutputHandle = TO_LPC_HANDLE(hConsoleOutput); CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, @@ -1543,8 +1547,8 @@ SetConsoleCursorPosition(HANDLE hConsoleOutput, CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_SETCURSORPOSITION SetCursorPositionRequest = &ApiMessage.Data.SetCursorPositionRequest; - SetCursorPositionRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - SetCursorPositionRequest->OutputHandle = hConsoleOutput; + SetCursorPositionRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + SetCursorPositionRequest->OutputHandle = TO_LPC_HANDLE(hConsoleOutput); SetCursorPositionRequest->Position = dwCursorPosition; CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, @@ -1578,8 +1582,8 @@ GetConsoleMode(HANDLE hConsoleHandle, return FALSE; } - ConsoleModeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - ConsoleModeRequest->Handle = hConsoleHandle; + ConsoleModeRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + ConsoleModeRequest->Handle = TO_LPC_HANDLE(hConsoleHandle); CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, @@ -1609,8 +1613,8 @@ SetConsoleMode(HANDLE hConsoleHandle, CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest = &ApiMessage.Data.ConsoleModeRequest; - ConsoleModeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - ConsoleModeRequest->Handle = hConsoleHandle; + ConsoleModeRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + ConsoleModeRequest->Handle = TO_LPC_HANDLE(hConsoleHandle); ConsoleModeRequest->Mode = dwMode; CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, @@ -1638,8 +1642,8 @@ GetNumberOfConsoleInputEvents(HANDLE hConsoleInput, CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_GETNUMINPUTEVENTS GetNumInputEventsRequest = &ApiMessage.Data.GetNumInputEventsRequest; - GetNumInputEventsRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - GetNumInputEventsRequest->InputHandle = hConsoleInput; + GetNumInputEventsRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + GetNumInputEventsRequest->InputHandle = TO_LPC_HANDLE(hConsoleInput); GetNumInputEventsRequest->NumberOfEvents = 0; CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, @@ -1675,8 +1679,8 @@ GetLargestConsoleWindowSize(HANDLE hConsoleOutput) CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_GETLARGESTWINDOWSIZE GetLargestWindowSizeRequest = &ApiMessage.Data.GetLargestWindowSizeRequest; - GetLargestWindowSizeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - GetLargestWindowSizeRequest->OutputHandle = hConsoleOutput; + GetLargestWindowSizeRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + GetLargestWindowSizeRequest->OutputHandle = TO_LPC_HANDLE(hConsoleOutput); GetLargestWindowSizeRequest->Size.X = 0; GetLargestWindowSizeRequest->Size.Y = 0; @@ -1715,8 +1719,8 @@ GetConsoleCursorInfo(HANDLE hConsoleOutput, return FALSE; } - CursorInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - CursorInfoRequest->OutputHandle = hConsoleOutput; + CursorInfoRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + CursorInfoRequest->OutputHandle = TO_LPC_HANDLE(hConsoleOutput); CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, @@ -1745,8 +1749,8 @@ SetConsoleCursorInfo(HANDLE hConsoleOutput, CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_GETSETCURSORINFO CursorInfoRequest = &ApiMessage.Data.CursorInfoRequest; - CursorInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - CursorInfoRequest->OutputHandle = hConsoleOutput; + CursorInfoRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + CursorInfoRequest->OutputHandle = TO_LPC_HANDLE(hConsoleOutput); CursorInfoRequest->Info = *lpConsoleCursorInfo; CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, @@ -1773,7 +1777,7 @@ GetNumberOfConsoleMouseButtons(LPDWORD lpNumberOfMouseButtons) CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_GETMOUSEINFO GetMouseInfoRequest = &ApiMessage.Data.GetMouseInfoRequest; - GetMouseInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + GetMouseInfoRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, @@ -1801,8 +1805,8 @@ SetConsoleActiveScreenBuffer(HANDLE hConsoleOutput) CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_SETACTIVESCREENBUFFER SetScreenBufferRequest = &ApiMessage.Data.SetScreenBufferRequest; - SetScreenBufferRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - SetScreenBufferRequest->OutputHandle = hConsoleOutput; + SetScreenBufferRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + SetScreenBufferRequest->OutputHandle = TO_LPC_HANDLE(hConsoleOutput); CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, @@ -1829,8 +1833,8 @@ FlushConsoleInputBuffer(HANDLE hConsoleInput) CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_FLUSHINPUTBUFFER FlushInputBufferRequest = &ApiMessage.Data.FlushInputBufferRequest; - FlushInputBufferRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - FlushInputBufferRequest->InputHandle = hConsoleInput; + FlushInputBufferRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + FlushInputBufferRequest->InputHandle = TO_LPC_HANDLE(hConsoleInput); CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, @@ -1858,8 +1862,8 @@ SetConsoleScreenBufferSize(HANDLE hConsoleOutput, CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_SETSCREENBUFFERSIZE SetScreenBufferSizeRequest = &ApiMessage.Data.SetScreenBufferSizeRequest; - SetScreenBufferSizeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - SetScreenBufferSizeRequest->OutputHandle = hConsoleOutput; + SetScreenBufferSizeRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + SetScreenBufferSizeRequest->OutputHandle = TO_LPC_HANDLE(hConsoleOutput); SetScreenBufferSizeRequest->Size = dwSize; CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, @@ -1888,8 +1892,8 @@ IntScrollConsoleScreenBuffer(HANDLE hConsoleOutput, CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_SCROLLSCREENBUFFER ScrollScreenBufferRequest = &ApiMessage.Data.ScrollScreenBufferRequest; - ScrollScreenBufferRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - ScrollScreenBufferRequest->OutputHandle = hConsoleOutput; + ScrollScreenBufferRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + ScrollScreenBufferRequest->OutputHandle = TO_LPC_HANDLE(hConsoleOutput); ScrollScreenBufferRequest->ScrollRectangle = *lpScrollRectangle; if (lpClipRectangle != NULL) @@ -1980,8 +1984,8 @@ SetConsoleWindowInfo(HANDLE hConsoleOutput, return FALSE; } - SetWindowInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - SetWindowInfoRequest->OutputHandle = hConsoleOutput; + SetWindowInfoRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + SetWindowInfoRequest->OutputHandle = TO_LPC_HANDLE(hConsoleOutput); SetWindowInfoRequest->Absolute = bAbsolute; SetWindowInfoRequest->WindowRect = *lpConsoleWindow; @@ -2011,8 +2015,8 @@ SetConsoleTextAttribute(HANDLE hConsoleOutput, CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_SETTEXTATTRIB SetTextAttribRequest = &ApiMessage.Data.SetTextAttribRequest; - SetTextAttribRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - SetTextAttribRequest->OutputHandle = hConsoleOutput; + SetTextAttribRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + SetTextAttribRequest->OutputHandle = TO_LPC_HANDLE(hConsoleOutput); SetTextAttribRequest->Attributes = wAttributes; CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, @@ -2141,7 +2145,7 @@ GenerateConsoleCtrlEvent(DWORD dwCtrlEvent, return FALSE; } - GenerateCtrlEventRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + GenerateCtrlEventRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); GenerateCtrlEventRequest->CtrlEvent = dwCtrlEvent; GenerateCtrlEventRequest->ProcessGroupId = dwProcessGroupId; @@ -2168,7 +2172,7 @@ IntGetConsoleTitle(LPVOID lpConsoleTitle, DWORD dwNumChars, BOOLEAN bUnicode) if (dwNumChars == 0) return 0; - TitleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + TitleRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); TitleRequest->Length = dwNumChars * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR)); TitleRequest->Unicode = bUnicode; @@ -2199,7 +2203,7 @@ IntGetConsoleTitle(LPVOID lpConsoleTitle, DWORD dwNumChars, BOOLEAN bUnicode) if (dwNumChars > 0) { - RtlCopyMemory(lpConsoleTitle, TitleRequest->Title, TitleRequest->Length); + RtlCopyMemory(lpConsoleTitle, (PVOID)TitleRequest->Title, TitleRequest->Length); if (bUnicode) ((LPWSTR)lpConsoleTitle)[dwNumChars] = UNICODE_NULL; @@ -2248,7 +2252,7 @@ IntSetConsoleTitle(CONST VOID *lpConsoleTitle, BOOLEAN bUnicode) ULONG NumChars = (ULONG)(lpConsoleTitle ? (bUnicode ? wcslen(lpConsoleTitle) : strlen(lpConsoleTitle)) : 0); - TitleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + TitleRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); TitleRequest->Length = NumChars * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR)); TitleRequest->Unicode = bUnicode; @@ -2329,7 +2333,7 @@ CreateConsoleScreenBuffer(DWORD dwDesiredAccess, return INVALID_HANDLE_VALUE; } - CreateScreenBufferRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + CreateScreenBufferRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); CreateScreenBufferRequest->DesiredAccess = dwDesiredAccess; CreateScreenBufferRequest->InheritHandle = (lpSecurityAttributes ? lpSecurityAttributes->bInheritHandle : FALSE); @@ -2374,11 +2378,11 @@ CreateConsoleScreenBuffer(DWORD dwDesiredAccess, if (dwFlags == CONSOLE_GRAPHICS_BUFFER && GraphicsBufferInfo) { - GraphicsBufferInfo->hMutex = CreateScreenBufferRequest->hMutex ; // CreateScreenBufferRequest->GraphicsBufferInfo.hMutex ; - GraphicsBufferInfo->lpBitMap = CreateScreenBufferRequest->lpBitMap; // CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMap; + GraphicsBufferInfo->hMutex = FROM_LPC_HANDLE(CreateScreenBufferRequest->hMutex); // CreateScreenBufferRequest->GraphicsBufferInfo.hMutex ; + GraphicsBufferInfo->lpBitMap = FROM_LPC_HANDLE(CreateScreenBufferRequest->lpBitMap); // CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMap; } - return CreateScreenBufferRequest->OutputHandle; + return FROM_LPC_HANDLE(CreateScreenBufferRequest->OutputHandle); } @@ -2394,7 +2398,7 @@ GetConsoleCP(VOID) PCONSOLE_GETINPUTOUTPUTCP GetConsoleCPRequest = &ApiMessage.Data.GetConsoleCPRequest; /* Get the Input Code Page */ - GetConsoleCPRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + GetConsoleCPRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); GetConsoleCPRequest->OutputCP = FALSE; CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, @@ -2423,7 +2427,7 @@ SetConsoleCP(UINT wCodePageID) PCONSOLE_SETINPUTOUTPUTCP SetConsoleCPRequest = &ApiMessage.Data.SetConsoleCPRequest; /* Set the Input Code Page */ - SetConsoleCPRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + SetConsoleCPRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); SetConsoleCPRequest->CodePage = wCodePageID; SetConsoleCPRequest->OutputCP = FALSE; /* SetConsoleCPRequest->EventHandle; */ @@ -2454,7 +2458,7 @@ GetConsoleOutputCP(VOID) PCONSOLE_GETINPUTOUTPUTCP GetConsoleCPRequest = &ApiMessage.Data.GetConsoleCPRequest; /* Get the Output Code Page */ - GetConsoleCPRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + GetConsoleCPRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); GetConsoleCPRequest->OutputCP = TRUE; CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, @@ -2483,7 +2487,7 @@ SetConsoleOutputCP(UINT wCodePageID) PCONSOLE_SETINPUTOUTPUTCP SetConsoleCPRequest = &ApiMessage.Data.SetConsoleCPRequest; /* Set the Output Code Page */ - SetConsoleCPRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + SetConsoleCPRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); SetConsoleCPRequest->CodePage = wCodePageID; SetConsoleCPRequest->OutputCP = TRUE; /* SetConsoleCPRequest->EventHandle; */ @@ -2532,7 +2536,7 @@ GetConsoleProcessList(LPDWORD lpdwProcessList, return 0; } - GetProcessListRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + GetProcessListRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); GetProcessListRequest->ProcessCount = dwProcessCount; CsrAllocateMessagePointer(CaptureBuffer, @@ -2552,7 +2556,7 @@ GetConsoleProcessList(LPDWORD lpdwProcessList, nProcesses = GetProcessListRequest->ProcessCount; if (dwProcessCount >= nProcesses) { - RtlCopyMemory(lpdwProcessList, GetProcessListRequest->ProcessIdsList, nProcesses * sizeof(DWORD)); + RtlCopyMemory(lpdwProcessList, (PVOID)GetProcessListRequest->ProcessIdsList, nProcesses * sizeof(DWORD)); } } @@ -2577,7 +2581,7 @@ GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo) return FALSE; } - GetSelectionInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + GetSelectionInfoRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, @@ -2607,14 +2611,16 @@ IntAttachConsole(DWORD ProcessId, { BOOL Success = TRUE; NTSTATUS Status; + INT i; + HANDLE Temp[MAX_INIT_EVENTS]; CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_ATTACHCONSOLE AttachConsoleRequest = &ApiMessage.Data.AttachConsoleRequest; PCSR_CAPTURE_BUFFER CaptureBuffer; AttachConsoleRequest->ProcessId = ProcessId; - AttachConsoleRequest->CtrlRoutine = CtrlRoutine; - AttachConsoleRequest->PropRoutine = PropRoutine; + AttachConsoleRequest->CtrlRoutine = (LPC_PTRTYPE(LPTHREAD_START_ROUTINE))CtrlRoutine; + AttachConsoleRequest->PropRoutine = (LPC_PTRTYPE(LPTHREAD_START_ROUTINE))PropRoutine; CaptureBuffer = CsrAllocateCaptureBuffer(1, sizeof(CONSOLE_START_INFO)); if (CaptureBuffer == NULL) @@ -2639,10 +2645,12 @@ IntAttachConsole(DWORD ProcessId, Success = FALSE; goto Quit; } - + + for (i = 0; i < MAX_INIT_EVENTS; i++) Temp[i] = FROM_LPC_HANDLE(((PCONSOLE_START_INFO)AttachConsoleRequest->ConsoleStartInfo)->InitEvents[i]); + // Is AttachConsoleRequest->ConsoleStartInfo->InitEvents aligned on handle boundary ???? Status = NtWaitForMultipleObjects(MAX_INIT_EVENTS, - AttachConsoleRequest->ConsoleStartInfo->InitEvents, + Temp, WaitAny, FALSE, NULL); if (!NT_SUCCESS(Status)) { @@ -2651,8 +2659,8 @@ IntAttachConsole(DWORD ProcessId, goto Quit; } - NtClose(AttachConsoleRequest->ConsoleStartInfo->InitEvents[INIT_SUCCESS]); - NtClose(AttachConsoleRequest->ConsoleStartInfo->InitEvents[INIT_FAILURE]); + NtClose(FROM_LPC_HANDLE(((PCONSOLE_START_INFO)AttachConsoleRequest->ConsoleStartInfo)->InitEvents[INIT_SUCCESS])); + NtClose(FROM_LPC_HANDLE(((PCONSOLE_START_INFO)AttachConsoleRequest->ConsoleStartInfo)->InitEvents[INIT_FAILURE])); if (Status != INIT_SUCCESS) { NtCurrentPeb()->ProcessParameters->ConsoleHandle = NULL; @@ -2661,7 +2669,7 @@ IntAttachConsole(DWORD ProcessId, else { RtlCopyMemory(ConsoleStartInfo, - AttachConsoleRequest->ConsoleStartInfo, + (PVOID)AttachConsoleRequest->ConsoleStartInfo, sizeof(CONSOLE_START_INFO)); Success = TRUE; } @@ -2705,7 +2713,7 @@ AttachConsole(DWORD dwProcessId) { /* Set up the handles */ SetUpHandles(&ConsoleStartInfo); - InputWaitHandle = ConsoleStartInfo.InputWaitHandle; + InputWaitHandle = FROM_LPC_HANDLE(ConsoleStartInfo.InputWaitHandle); /* Initialize Console Ctrl Handling */ InitializeCtrlHandling(); @@ -2731,7 +2739,7 @@ GetConsoleWindow(VOID) CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_GETWINDOW GetWindowRequest = &ApiMessage.Data.GetWindowRequest; - GetWindowRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + GetWindowRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, @@ -2743,7 +2751,7 @@ GetConsoleWindow(VOID) return (HWND)NULL; } - return GetWindowRequest->WindowHandle; + return FROM_LPC_HANDLE(GetWindowRequest->WindowHandle); } @@ -2758,8 +2766,8 @@ SetConsoleIcon(HICON hIcon) CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_SETICON SetIconRequest = &ApiMessage.Data.SetIconRequest; - SetIconRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - SetIconRequest->IconHandle = hIcon; + SetIconRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + SetIconRequest->IconHandle = (LPC_PTRTYPE(HICON))hIcon; CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, @@ -3050,8 +3058,8 @@ IntRegisterConsoleIME( cbDesktop = min(cbDesktop, (MAX_PATH + 1) * sizeof(WCHAR)); - RegisterConsoleIME->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - RegisterConsoleIME->hWnd = hWnd; + RegisterConsoleIME->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + RegisterConsoleIME->hWnd = (LPC_PTRTYPE(HWND))hWnd; RegisterConsoleIME->dwThreadId = dwThreadId; RegisterConsoleIME->cbDesktop = cbDesktop; @@ -3104,7 +3112,7 @@ IntUnregisterConsoleIME( CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_UNREGISTERCONSOLEIME UnregisterConsoleIME = &ApiMessage.Data.UnregisterConsoleIME; - UnregisterConsoleIME->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + UnregisterConsoleIME->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); UnregisterConsoleIME->dwThreadId = dwThreadId; CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, @@ -3175,7 +3183,7 @@ SetTEBLangID(VOID) /* Retrieve the "best-suited" language ID corresponding * to the active console output code page. */ - LangIdRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + LangIdRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, @@ -3214,7 +3222,7 @@ IntGetConsoleKeyboardLayoutName(OUT PVOID pszLayoutName, PCONSOLE_GETKBDLAYOUTNAME GetKbdLayoutNameRequest = &ApiMessage.Data.GetKbdLayoutNameRequest; /* Set up the data to send to the Console Server */ - GetKbdLayoutNameRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + GetKbdLayoutNameRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); GetKbdLayoutNameRequest->Ansi = bAnsi; /* Call the server */ @@ -3285,7 +3293,7 @@ SetLastConsoleEventActive(VOID) LastCloseNotify = TRUE; /* Set up the input arguments */ - NotifyLastCloseRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + NotifyLastCloseRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); /* Call CSRSS; just return the NTSTATUS cast to DWORD */ return CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, diff --git a/dll/win32/kernel32/client/console/history.c b/dll/win32/kernel32/client/console/history.c index b4513ea6329d1..6ae107442e6b3 100644 --- a/dll/win32/kernel32/client/console/history.c +++ b/dll/win32/kernel32/client/console/history.c @@ -42,7 +42,7 @@ IntExpungeConsoleCommandHistory(LPCVOID lpExeName, BOOLEAN bUnicode) return; } - ExpungeCommandHistoryRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + ExpungeCommandHistoryRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); ExpungeCommandHistoryRequest->ExeLength = NumChars * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR)); ExpungeCommandHistoryRequest->Unicode = ExpungeCommandHistoryRequest->Unicode2 = bUnicode; @@ -88,7 +88,7 @@ IntGetConsoleCommandHistory(LPVOID lpHistory, DWORD cbHistory, LPCVOID lpExeName return 0; } - GetCommandHistoryRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + GetCommandHistoryRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); GetCommandHistoryRequest->HistoryLength = cbHistory; GetCommandHistoryRequest->ExeLength = NumChars * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR)); GetCommandHistoryRequest->Unicode = @@ -125,7 +125,7 @@ IntGetConsoleCommandHistory(LPVOID lpHistory, DWORD cbHistory, LPCVOID lpExeName } RtlCopyMemory(lpHistory, - GetCommandHistoryRequest->History, + (PVOID)GetCommandHistoryRequest->History, GetCommandHistoryRequest->HistoryLength); CsrFreeCaptureBuffer(CaptureBuffer); @@ -149,7 +149,7 @@ IntGetConsoleCommandHistoryLength(LPCVOID lpExeName, BOOL bUnicode) return 0; } - GetCommandHistoryLengthRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + GetCommandHistoryLengthRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); GetCommandHistoryLengthRequest->ExeLength = NumChars * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR)); GetCommandHistoryLengthRequest->Unicode = GetCommandHistoryLengthRequest->Unicode2 = bUnicode; @@ -202,7 +202,7 @@ IntSetConsoleNumberOfCommands(DWORD dwNumCommands, return FALSE; } - SetHistoryNumberCommandsRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + SetHistoryNumberCommandsRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); SetHistoryNumberCommandsRequest->NumCommands = dwNumCommands; SetHistoryNumberCommandsRequest->ExeLength = NumChars * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR)); SetHistoryNumberCommandsRequest->Unicode = @@ -354,7 +354,7 @@ SetConsoleCommandHistoryMode(IN DWORD dwMode) CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_SETHISTORYMODE SetHistoryModeRequest = &ApiMessage.Data.SetHistoryModeRequest; - SetHistoryModeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + SetHistoryModeRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); SetHistoryModeRequest->Mode = dwMode; CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, diff --git a/dll/win32/kernel32/client/console/init.c b/dll/win32/kernel32/client/console/init.c index eb97ac73ded74..f35a005eeeae9 100644 --- a/dll/win32/kernel32/client/console/init.c +++ b/dll/win32/kernel32/client/console/init.c @@ -135,7 +135,7 @@ SetUpConsoleInfo(IN BOOLEAN CaptureTitle, IN OUT LPDWORD pTitleLength, IN OUT LPWSTR* lpTitle OPTIONAL, IN OUT LPDWORD pDesktopLength, - IN OUT LPWSTR* lpDesktop OPTIONAL, + IN OUT LPC_PTRTYPE(LPWSTR)* lpDesktop OPTIONAL, IN OUT PCONSOLE_START_INFO ConsoleStartInfo) { PRTL_USER_PROCESS_PARAMETERS Parameters = NtCurrentPeb()->ProcessParameters; @@ -144,8 +144,8 @@ SetUpConsoleInfo(IN BOOLEAN CaptureTitle, /* Initialize the fields */ ConsoleStartInfo->IconIndex = 0; - ConsoleStartInfo->hIcon = NULL; - ConsoleStartInfo->hIconSm = NULL; + ConsoleStartInfo->hIcon = (LPC_PTRTYPE(HICON))NULL; + ConsoleStartInfo->hIconSm = (LPC_PTRTYPE(HICON))NULL; ConsoleStartInfo->dwStartupFlags = Parameters->WindowFlags; ConsoleStartInfo->nFont = 0; ConsoleStartInfo->nInputBufferSize = 0; @@ -201,12 +201,12 @@ SetUpConsoleInfo(IN BOOLEAN CaptureTitle, *pDesktopLength = Length; /* Return a pointer to the data */ - *lpDesktop = Parameters->DesktopInfo.Buffer; + *lpDesktop = (LPC_PTRTYPE(LPWSTR))Parameters->DesktopInfo.Buffer; } else { *pDesktopLength = 0; - if (lpDesktop) *lpDesktop = NULL; + if (lpDesktop) *lpDesktop = (LPC_PTRTYPE(LPWSTR))NULL; } if (Parameters->WindowFlags & STARTF_USEFILLATTRIBUTE) @@ -261,13 +261,13 @@ SetUpHandles(IN PCONSOLE_START_INFO ConsoleStartInfo) } /* We got the handles, let's set them */ - Parameters->ConsoleHandle = ConsoleStartInfo->ConsoleHandle; + Parameters->ConsoleHandle = FROM_LPC_HANDLE(ConsoleStartInfo->ConsoleHandle); if ((ConsoleStartInfo->dwStartupFlags & STARTF_USESTDHANDLES) == 0) { - Parameters->StandardInput = ConsoleStartInfo->InputHandle; - Parameters->StandardOutput = ConsoleStartInfo->OutputHandle; - Parameters->StandardError = ConsoleStartInfo->ErrorHandle; + Parameters->StandardInput = FROM_LPC_HANDLE(ConsoleStartInfo->InputHandle); + Parameters->StandardOutput = FROM_LPC_HANDLE(ConsoleStartInfo->OutputHandle); + Parameters->StandardError = FROM_LPC_HANDLE(ConsoleStartInfo->ErrorHandle); } } @@ -288,6 +288,8 @@ ConnectConsole(IN PWSTR SessionDir, { NTSTATUS Status; ULONG ConnectInfoSize = sizeof(*ConnectInfo); + HANDLE Temp[MAX_INIT_EVENTS]; + INT i; ASSERT(SessionDir); @@ -310,10 +312,12 @@ ConnectConsole(IN PWSTR SessionDir, /* Nothing to do if this is not a console app */ if (!ConnectInfo->IsConsoleApp) return TRUE; + for (i = 0; i < MAX_INIT_EVENTS; i++) Temp[i] = FROM_LPC_HANDLE(ConnectInfo->ConsoleStartInfo.InitEvents[i]); + /* Wait for the connection to finish */ // Is ConnectInfo->ConsoleStartInfo.InitEvents aligned on handle boundary ???? Status = NtWaitForMultipleObjects(MAX_INIT_EVENTS, - ConnectInfo->ConsoleStartInfo.InitEvents, + Temp, WaitAny, FALSE, NULL); if (!NT_SUCCESS(Status)) { @@ -321,8 +325,8 @@ ConnectConsole(IN PWSTR SessionDir, return FALSE; } - NtClose(ConnectInfo->ConsoleStartInfo.InitEvents[INIT_SUCCESS]); - NtClose(ConnectInfo->ConsoleStartInfo.InitEvents[INIT_FAILURE]); + NtClose(FROM_LPC_HANDLE(ConnectInfo->ConsoleStartInfo.InitEvents[INIT_SUCCESS])); + NtClose(FROM_LPC_HANDLE(ConnectInfo->ConsoleStartInfo.InitEvents[INIT_FAILURE])); if (Status != INIT_SUCCESS) { NtCurrentPeb()->ProcessParameters->ConsoleHandle = NULL; @@ -437,11 +441,11 @@ ConDllInitialize(IN ULONG Reason, } /* Now use the proper console handle */ - ConnectInfo.ConsoleStartInfo.ConsoleHandle = Parameters->ConsoleHandle; + ConnectInfo.ConsoleStartInfo.ConsoleHandle = TO_LPC_HANDLE(Parameters->ConsoleHandle); /* Initialize the console dispatchers */ - ConnectInfo.CtrlRoutine = ConsoleControlDispatcher; - ConnectInfo.PropRoutine = PropDialogHandler; + ConnectInfo.CtrlRoutine = (LPC_PTRTYPE(LPTHREAD_START_ROUTINE))ConsoleControlDispatcher; + ConnectInfo.PropRoutine = (LPC_PTRTYPE(LPTHREAD_START_ROUTINE))PropDialogHandler; // ConnectInfo.ImeRoutine = ImeRoutine; /* Set up the console properties */ @@ -519,7 +523,7 @@ ConDllInitialize(IN ULONG Reason, if (Parameters->ConsoleHandle == NULL) SetUpHandles(&ConnectInfo.ConsoleStartInfo); - InputWaitHandle = ConnectInfo.ConsoleStartInfo.InputWaitHandle; + InputWaitHandle = FROM_LPC_HANDLE(ConnectInfo.ConsoleStartInfo.InputWaitHandle); /* Sync the current thread's LangId with the console's one */ SetTEBLangID(); diff --git a/dll/win32/kernel32/client/console/readwrite.c b/dll/win32/kernel32/client/console/readwrite.c index 297fb71dc7df9..3cf9b3c099377 100644 --- a/dll/win32/kernel32/client/console/readwrite.c +++ b/dll/win32/kernel32/client/console/readwrite.c @@ -24,7 +24,6 @@ #define ConioRectWidth(Rect) \ (((Rect)->Left > (Rect)->Right) ? 0 : ((Rect)->Right - (Rect)->Left + 1)) - /* PRIVATE FUNCTIONS **********************************************************/ /****************** @@ -49,8 +48,8 @@ IntReadConsole(IN HANDLE hConsoleInput, DPRINT("IntReadConsole\n"); /* Set up the data to send to the Console Server */ - ReadConsoleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - ReadConsoleRequest->InputHandle = hConsoleInput; + ReadConsoleRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + ReadConsoleRequest->InputHandle = TO_LPC_HANDLE(hConsoleInput); ReadConsoleRequest->Unicode = bUnicode; /* @@ -85,7 +84,7 @@ IntReadConsole(IN HANDLE hConsoleInput, */ if (SizeBytes <= sizeof(ReadConsoleRequest->StaticBuffer)) { - ReadConsoleRequest->Buffer = ReadConsoleRequest->StaticBuffer; + ReadConsoleRequest->Buffer = (LPC_PVOID)ReadConsoleRequest->StaticBuffer; // CaptureBuffer = NULL; } else @@ -136,7 +135,7 @@ IntReadConsole(IN HANDLE hConsoleInput, * stored in the static buffer because it was first grabbed when * we started the first read. */ - RtlCopyMemory(ReadConsoleRequest->Buffer, + RtlCopyMemory((PVOID)(PVOID)ReadConsoleRequest->Buffer, lpBuffer, ReadConsoleRequest->InitialNumBytes); } @@ -193,7 +192,7 @@ IntReadConsole(IN HANDLE hConsoleInput, pInputControl->dwControlKeyState = ReadConsoleRequest->ControlKeyState; RtlCopyMemory(lpBuffer, - ReadConsoleRequest->Buffer, + (PVOID)ReadConsoleRequest->Buffer, ReadConsoleRequest->NumBytes); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) @@ -259,8 +258,8 @@ IntGetConsoleInput(IN HANDLE hConsoleInput, DPRINT("IntGetConsoleInput: %lx %p\n", nLength, lpNumberOfEventsRead); /* Set up the data to send to the Console Server */ - GetInputRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - GetInputRequest->InputHandle = hConsoleInput; + GetInputRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + GetInputRequest->InputHandle = TO_LPC_HANDLE(hConsoleInput); GetInputRequest->NumRecords = nLength; GetInputRequest->Flags = wFlags; GetInputRequest->Unicode = bUnicode; @@ -273,7 +272,7 @@ IntGetConsoleInput(IN HANDLE hConsoleInput, */ if (nLength <= sizeof(GetInputRequest->RecordStaticBuffer)/sizeof(INPUT_RECORD)) { - GetInputRequest->RecordBufPtr = GetInputRequest->RecordStaticBuffer; + GetInputRequest->RecordBufPtr = (LPC_PVOID)(ULONG_PTR)GetInputRequest->RecordStaticBuffer; // CaptureBuffer = NULL; } else @@ -313,7 +312,7 @@ IntGetConsoleInput(IN HANDLE hConsoleInput, if (Success) { RtlCopyMemory(lpBuffer, - GetInputRequest->RecordBufPtr, + (PVOID)GetInputRequest->RecordBufPtr, GetInputRequest->NumRecords * sizeof(INPUT_RECORD)); } else @@ -354,8 +353,8 @@ IntReadConsoleOutput(IN HANDLE hConsoleOutput, ULONG NumCells; /* Set up the data to send to the Console Server */ - ReadOutputRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - ReadOutputRequest->OutputHandle = hConsoleOutput; + ReadOutputRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + ReadOutputRequest->OutputHandle = TO_LPC_HANDLE(hConsoleOutput); ReadOutputRequest->Unicode = bUnicode; /* Update lpReadRegion */ @@ -391,7 +390,7 @@ IntReadConsoleOutput(IN HANDLE hConsoleOutput, */ if (NumCells <= 1) { - ReadOutputRequest->CharInfo = &ReadOutputRequest->StaticBuffer; + ReadOutputRequest->CharInfo = (LPC_PVOID)&ReadOutputRequest->StaticBuffer; // CaptureBuffer = NULL; } else @@ -441,7 +440,7 @@ IntReadConsoleOutput(IN HANDLE hConsoleOutput, for (y = 0, Y = ReadOutputRequest->ReadRegion.Top; Y <= ReadOutputRequest->ReadRegion.Bottom; ++y, ++Y) { RtlCopyMemory(lpBuffer + (y + dwBufferCoord.Y) * dwBufferSize.X + dwBufferCoord.X, - ReadOutputRequest->CharInfo + y * SizeX, + (CHAR_INFO*)ReadOutputRequest->CharInfo + y * SizeX, SizeX * sizeof(CHAR_INFO)); #if 0 for (x = 0, X = ReadOutputRequest->ReadRegion.Left; X <= ReadOutputRequest->ReadRegion.Right; ++x, ++X) @@ -498,8 +497,8 @@ IntReadConsoleOutputCode(IN HANDLE hConsoleOutput, } /* Set up the data to send to the Console Server */ - ReadOutputCodeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - ReadOutputCodeRequest->OutputHandle = hConsoleOutput; + ReadOutputCodeRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + ReadOutputCodeRequest->OutputHandle = TO_LPC_HANDLE(hConsoleOutput); ReadOutputCodeRequest->Coord = dwReadCoord; ReadOutputCodeRequest->NumCodes = nLength; @@ -529,7 +528,7 @@ IntReadConsoleOutputCode(IN HANDLE hConsoleOutput, */ if (SizeBytes <= sizeof(ReadOutputCodeRequest->CodeStaticBuffer)) { - ReadOutputCodeRequest->pCode = ReadOutputCodeRequest->CodeStaticBuffer; + ReadOutputCodeRequest->pCode = (LPC_PVOID)(ULONG_PTR)ReadOutputCodeRequest->CodeStaticBuffer; // CaptureBuffer = NULL; } else @@ -566,7 +565,7 @@ IntReadConsoleOutputCode(IN HANDLE hConsoleOutput, if (Success) { RtlCopyMemory(pCode, - ReadOutputCodeRequest->pCode, + (PVOID)ReadOutputCodeRequest->pCode, ReadOutputCodeRequest->NumCodes * CodeSize); } else @@ -611,8 +610,8 @@ IntWriteConsole(IN HANDLE hConsoleOutput, DPRINT("IntWriteConsole\n"); /* Set up the data to send to the Console Server */ - WriteConsoleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - WriteConsoleRequest->OutputHandle = hConsoleOutput; + WriteConsoleRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + WriteConsoleRequest->OutputHandle = TO_LPC_HANDLE(hConsoleOutput); WriteConsoleRequest->Unicode = bUnicode; /* Those members are unused by the client, on Windows */ @@ -633,13 +632,13 @@ IntWriteConsole(IN HANDLE hConsoleOutput, */ if (SizeBytes <= sizeof(WriteConsoleRequest->StaticBuffer)) { - WriteConsoleRequest->Buffer = WriteConsoleRequest->StaticBuffer; + WriteConsoleRequest->Buffer = (LPC_PVOID)(ULONG_PTR)WriteConsoleRequest->StaticBuffer; // CaptureBuffer = NULL; WriteConsoleRequest->UsingStaticBuffer = TRUE; _SEH2_TRY { - RtlCopyMemory(WriteConsoleRequest->Buffer, + RtlCopyMemory((PVOID)WriteConsoleRequest->Buffer, lpBuffer, SizeBytes); } @@ -722,8 +721,8 @@ IntWriteConsoleInput(IN HANDLE hConsoleInput, DPRINT("IntWriteConsoleInput: %lx %p\n", nLength, lpNumberOfEventsWritten); /* Set up the data to send to the Console Server */ - WriteInputRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - WriteInputRequest->InputHandle = hConsoleInput; + WriteInputRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + WriteInputRequest->InputHandle = TO_LPC_HANDLE(hConsoleInput); WriteInputRequest->NumRecords = nLength; WriteInputRequest->Unicode = bUnicode; WriteInputRequest->AppendToEnd = bAppendToEnd; @@ -736,12 +735,12 @@ IntWriteConsoleInput(IN HANDLE hConsoleInput, */ if (nLength <= sizeof(WriteInputRequest->RecordStaticBuffer)/sizeof(INPUT_RECORD)) { - WriteInputRequest->RecordBufPtr = WriteInputRequest->RecordStaticBuffer; + WriteInputRequest->RecordBufPtr = (LPC_PVOID)(ULONG_PTR)WriteInputRequest->RecordStaticBuffer; // CaptureBuffer = NULL; _SEH2_TRY { - RtlCopyMemory(WriteInputRequest->RecordBufPtr, + RtlCopyMemory((PVOID)WriteInputRequest->RecordBufPtr, lpBuffer, nLength * sizeof(INPUT_RECORD)); } @@ -823,8 +822,8 @@ IntWriteConsoleOutput(IN HANDLE hConsoleOutput, ULONG NumCells; /* Set up the data to send to the Console Server */ - WriteOutputRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - WriteOutputRequest->OutputHandle = hConsoleOutput; + WriteOutputRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + WriteOutputRequest->OutputHandle = TO_LPC_HANDLE(hConsoleOutput); WriteOutputRequest->Unicode = bUnicode; /* Update lpWriteRegion */ @@ -860,7 +859,7 @@ IntWriteConsoleOutput(IN HANDLE hConsoleOutput, */ if (NumCells <= 1) { - WriteOutputRequest->CharInfo = &WriteOutputRequest->StaticBuffer; + WriteOutputRequest->CharInfo = (LPC_PVOID)(ULONG_PTR)&WriteOutputRequest->StaticBuffer; // CaptureBuffer = NULL; WriteOutputRequest->UseVirtualMemory = FALSE; } @@ -889,11 +888,11 @@ IntWriteConsoleOutput(IN HANDLE hConsoleOutput, */ DPRINT1("CsrAllocateCaptureBuffer failed with size %ld, let's use local heap buffer...\n", Size); - WriteOutputRequest->CharInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, Size); + WriteOutputRequest->CharInfo = (LPC_PVOID)(ULONG_PTR)RtlAllocateHeap(RtlGetProcessHeap(), 0, Size); WriteOutputRequest->UseVirtualMemory = TRUE; /* Bail out if we still cannot allocate memory */ - if (WriteOutputRequest->CharInfo == NULL) + if (WriteOutputRequest->CharInfo == (LPC_PVOID)NULL) { DPRINT1("Failed to allocate heap buffer with size %ld!\n", Size); SetLastError(ERROR_NOT_ENOUGH_MEMORY); @@ -916,7 +915,7 @@ IntWriteConsoleOutput(IN HANDLE hConsoleOutput, for (y = 0, Y = WriteOutputRequest->WriteRegion.Top; Y <= WriteOutputRequest->WriteRegion.Bottom; ++y, ++Y) { - RtlCopyMemory(WriteOutputRequest->CharInfo + y * SizeX, + RtlCopyMemory((CHAR_INFO*)WriteOutputRequest->CharInfo + y * SizeX, lpBuffer + (y + dwBufferCoord.Y) * dwBufferSize.X + dwBufferCoord.X, SizeX * sizeof(CHAR_INFO)); #if 0 @@ -953,7 +952,7 @@ IntWriteConsoleOutput(IN HANDLE hConsoleOutput, { /* If we used a heap buffer, free it */ if (WriteOutputRequest->UseVirtualMemory) - RtlFreeHeap(RtlGetProcessHeap(), 0, WriteOutputRequest->CharInfo); + RtlFreeHeap(RtlGetProcessHeap(), 0, (PVOID)(ULONG_PTR)WriteOutputRequest->CharInfo); } /* Retrieve the results */ @@ -1002,8 +1001,8 @@ IntWriteConsoleOutputCode(IN HANDLE hConsoleOutput, DPRINT("IntWriteConsoleOutputCode\n"); /* Set up the data to send to the Console Server */ - WriteOutputCodeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - WriteOutputCodeRequest->OutputHandle = hConsoleOutput; + WriteOutputCodeRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + WriteOutputCodeRequest->OutputHandle = TO_LPC_HANDLE(hConsoleOutput); WriteOutputCodeRequest->Coord = dwWriteCoord; WriteOutputCodeRequest->NumCodes = nLength; @@ -1033,12 +1032,12 @@ IntWriteConsoleOutputCode(IN HANDLE hConsoleOutput, */ if (SizeBytes <= sizeof(WriteOutputCodeRequest->CodeStaticBuffer)) { - WriteOutputCodeRequest->pCode = WriteOutputCodeRequest->CodeStaticBuffer; + WriteOutputCodeRequest->pCode = (LPC_PVOID)(ULONG_PTR)WriteOutputCodeRequest->CodeStaticBuffer; // CaptureBuffer = NULL; _SEH2_TRY { - RtlCopyMemory(WriteOutputCodeRequest->pCode, + RtlCopyMemory((PVOID)WriteOutputCodeRequest->pCode, pCode, SizeBytes); } @@ -1123,8 +1122,8 @@ IntFillConsoleOutputCode(IN HANDLE hConsoleOutput, } /* Set up the data to send to the Console Server */ - FillOutputRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; - FillOutputRequest->OutputHandle = hConsoleOutput; + FillOutputRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); + FillOutputRequest->OutputHandle = TO_LPC_HANDLE(hConsoleOutput); FillOutputRequest->WriteCoord = dwWriteCoord; FillOutputRequest->CodeType = CodeType; FillOutputRequest->Code = Code; diff --git a/dll/win32/kernel32/client/dllmain.c b/dll/win32/kernel32/client/dllmain.c index fe173bb10d8da..d13a0e5eee466 100644 --- a/dll/win32/kernel32/client/dllmain.c +++ b/dll/win32/kernel32/client/dllmain.c @@ -16,7 +16,7 @@ /* GLOBALS *******************************************************************/ -PBASE_STATIC_SERVER_DATA BaseStaticServerData; +LPC_PTRTYPE(PBASE_STATIC_SERVER_DATA) BaseStaticServerData; BOOLEAN BaseRunningInServerProcess = FALSE; WCHAR BaseDefaultPathBuffer[6140]; @@ -28,6 +28,11 @@ PPEB Peb; ULONG SessionId; static BOOL DllInitialized = FALSE; +#ifdef BUILD_WOW6432 +static WCHAR BaseWindowsSystemDirectoryBuffer[MAX_PATH]; +static WCHAR BaseWindowsDirectoryBuffer[MAX_PATH]; +#endif + /* Critical section for various kernel32 data structures */ RTL_CRITICAL_SECTION BaseDllDirectoryLock; @@ -149,9 +154,20 @@ DllMain(HANDLE hDll, } /* Get the server data */ +#ifndef BUILD_WOW6432 ASSERT(Peb->ReadOnlyStaticServerData); BaseStaticServerData = Peb->ReadOnlyStaticServerData[BASESRV_SERVERDLL_INDEX]; - ASSERT(BaseStaticServerData); +#else + ASSERT(NtCurrentPeb64()->ReadOnlyStaticServerData); + BaseStaticServerData = + Wow64ReadNativePtr((UINT64)NtCurrentPeb64()->ReadOnlyStaticServerData + + BASESRV_SERVERDLL_INDEX * sizeof(LPC_PVOID)); +#endif + if (!BaseStaticServerData) + { + DPRINT1("BaseStaticServerData NULL\n"); + __debugbreak(); + } /* Check if we are running a CSR Server */ if (!BaseRunningInServerProcess) @@ -168,8 +184,56 @@ DllMain(HANDLE hDll, kernel32_handle = hCurrentModule = hDll; /* Set the directories */ - BaseWindowsDirectory = BaseStaticServerData->WindowsDirectory; - BaseWindowsSystemDirectory = BaseStaticServerData->WindowsSystemDirectory; +#ifndef BUILD_WOW6432 + BaseWindowsDirectory.Length = BaseStaticServerData->WindowsDirectory.Length; + BaseWindowsSystemDirectory.Length = BaseStaticServerData->WindowsSystemDirectory.Length; + BaseWindowsDirectory.MaximumLength = BaseStaticServerData->WindowsDirectory.MaximumLength; + BaseWindowsSystemDirectory.MaximumLength = BaseStaticServerData->WindowsSystemDirectory.MaximumLength; + BaseWindowsDirectory.Buffer = (PVOID)BaseStaticServerData->WindowsDirectory.Buffer; + BaseWindowsSystemDirectory.Buffer = (PVOID)BaseStaticServerData->WindowsSystemDirectory.Buffer; +#else + BaseWindowsDirectory.Length = + WOW64_READ_WORD_FIELD(BaseStaticServerData, BASE_STATIC_SERVER_DATA, WindowsDirectory.Length); + BaseWindowsSystemDirectory.Length = + WOW64_READ_WORD_FIELD(BaseStaticServerData, BASE_STATIC_SERVER_DATA, WindowsSystemDirectory.Length); + BaseWindowsDirectory.MaximumLength = + WOW64_READ_WORD_FIELD(BaseStaticServerData, BASE_STATIC_SERVER_DATA, WindowsDirectory.MaximumLength); + BaseWindowsSystemDirectory.MaximumLength = + WOW64_READ_WORD_FIELD(BaseStaticServerData, BASE_STATIC_SERVER_DATA, WindowsSystemDirectory.MaximumLength); + BaseWindowsDirectory.Buffer = BaseWindowsDirectoryBuffer; + BaseWindowsSystemDirectory.Buffer = BaseWindowsSystemDirectoryBuffer; + + ASSERT(BaseWindowsDirectory.Length < MAX_PATH * sizeof(WCHAR)); + ASSERT(BaseWindowsSystemDirectory.Length < MAX_PATH * sizeof(WCHAR)); + + Status = NtWow64ReadVirtualMemory64(NtCurrentProcess(), + WOW64_READ_PTR_FIELD( + BaseStaticServerData, + BASE_STATIC_SERVER_DATA, + WindowsDirectory.Buffer), + BaseWindowsDirectoryBuffer, + BaseWindowsDirectory.Length, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("WOW64: Failed to set up BaseWindowsDirectory\n"); + return FALSE; + } + + Status = NtWow64ReadVirtualMemory64(NtCurrentProcess(), + WOW64_READ_PTR_FIELD( + BaseStaticServerData, + BASE_STATIC_SERVER_DATA, + WindowsSystemDirectory.Buffer), + BaseWindowsSystemDirectoryBuffer, + BaseWindowsSystemDirectory.Length, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("WOW64: Failed to set up BaseWindowsSystemDirectory\n"); + return FALSE; + } +#endif /* Construct the default path (using the static buffer) */ Status = RtlStringCbPrintfW(BaseDefaultPathBuffer, diff --git a/dll/win32/kernel32/client/dosdev.c b/dll/win32/kernel32/client/dosdev.c index c6045625dea5f..d2aef9685ff27 100644 --- a/dll/win32/kernel32/client/dosdev.c +++ b/dll/win32/kernel32/client/dosdev.c @@ -252,7 +252,7 @@ DefineDosDeviceW( WPARAM wParam; /* Get status about local device mapping */ - LUIDDeviceMapsEnabled = BaseStaticServerData->LUIDDeviceMapsEnabled; + LUIDDeviceMapsEnabled = WOW64_READ_BYTE_FIELD(BaseStaticServerData, BASE_STATIC_SERVER_DATA, LUIDDeviceMapsEnabled); /* Validate input & flags */ if ((dwFlags & 0xFFFFFFE0) || @@ -325,6 +325,7 @@ DefineDosDeviceW( DefineDosDeviceRequest->DeviceName.MaximumLength = CsrAllocateMessagePointer(CaptureBuffer, DeviceNameU.MaximumLength, (PVOID*)&DefineDosDeviceRequest->DeviceName.Buffer); + /* And copy it while upcasing it */ RtlUpcaseUnicodeString(&DefineDosDeviceRequest->DeviceName, &DeviceNameU, FALSE); @@ -334,6 +335,7 @@ DefineDosDeviceW( DefineDosDeviceRequest->TargetPath.MaximumLength = CsrAllocateMessagePointer(CaptureBuffer, NtTargetPathU.MaximumLength, (PVOID*)&DefineDosDeviceRequest->TargetPath.Buffer); + RtlCopyUnicodeString(&DefineDosDeviceRequest->TargetPath, &NtTargetPathU); if (!(dwFlags & DDD_RAW_TARGET_PATH)) @@ -655,7 +657,7 @@ QueryDosDeviceW( * Global?? for global devices */ GlobalNeeded = FALSE; - if (BaseStaticServerData->LUIDDeviceMapsEnabled) + if (WOW64_READ_BYTE_FIELD(BaseStaticServerData, BASE_STATIC_SERVER_DATA, LUIDDeviceMapsEnabled)) { /* Assume ?? == Global?? */ IsGlobal = TRUE; @@ -808,7 +810,8 @@ QueryDosDeviceW( } /* Now, if we had to handle GLOBAL??, go for it! */ - if (BaseStaticServerData->LUIDDeviceMapsEnabled && NT_SUCCESS(Status) && GlobalNeeded) + if (WOW64_READ_BYTE_FIELD(BaseStaticServerData, BASE_STATIC_SERVER_DATA, LUIDDeviceMapsEnabled) && + NT_SUCCESS(Status) && GlobalNeeded) { NtClose(DirectoryHandle); DirectoryHandle = 0; diff --git a/dll/win32/kernel32/client/except.c b/dll/win32/kernel32/client/except.c index 04931ecd606bd..330355ad8c3eb 100644 --- a/dll/win32/kernel32/client/except.c +++ b/dll/win32/kernel32/client/except.c @@ -489,8 +489,8 @@ UnhandledExceptionFilter(IN PEXCEPTION_POINTERS ExceptionInfo) // // Since Windows XP/2003, we have the ReportFault API available. // See http://www.clausbrod.de/twiki/pub/Blog/DefinePrivatePublic20070616/reportfault.cpp - // and https://msdn.microsoft.com/en-us/library/windows/desktop/bb513616(v=vs.85).aspx - // and the legacy ReportFault API: https://msdn.microsoft.com/en-us/library/windows/desktop/bb513615(v=vs.85).aspx + // and https://learn.microsoft.com/en-us/windows/win32/wer/using-wer + // and the legacy ReportFault API: https://learn.microsoft.com/en-us/windows/win32/api/errorrep/nf-errorrep-reportfault // // NOTE: Starting Vista+, the fault API is constituted of the WerXXX functions. // @@ -541,7 +541,7 @@ UnhandledExceptionFilter(IN PEXCEPTION_POINTERS ExceptionInfo) * so that we can give it control over the process being debugged, * by passing it the exception. * - * See https://msdn.microsoft.com/en-us/library/ms809754.aspx + * See https://learn.microsoft.com/en-us/previous-versions/ms809754(v=msdn.10) * and http://www.debuginfo.com/articles/ntsdwatson.html * and https://sourceware.org/ml/gdb-patches/2012-08/msg00893.html * for more details. @@ -815,7 +815,7 @@ IsBadReadPtr(IN LPCVOID lp, if (!lp) return TRUE; /* Get the page size */ - PageSize = BaseStaticServerData->SysInfo.PageSize; + PageSize = WOW64_READ_ULONG_FIELD(BaseStaticServerData, BASE_STATIC_SERVER_DATA, SysInfo.PageSize); /* Calculate start and end */ Current = (volatile CHAR*)lp; @@ -893,7 +893,7 @@ IsBadWritePtr(IN LPVOID lp, if (!lp) return TRUE; /* Get the page size */ - PageSize = BaseStaticServerData->SysInfo.PageSize; + PageSize = WOW64_READ_ULONG_FIELD(BaseStaticServerData, BASE_STATIC_SERVER_DATA, SysInfo.PageSize); /* Calculate start and end */ Current = (volatile CHAR*)lp; diff --git a/dll/win32/kernel32/client/file/copy.c b/dll/win32/kernel32/client/file/copy.c index 92c45558e6fcd..7213611b6abf8 100644 --- a/dll/win32/kernel32/client/file/copy.c +++ b/dll/win32/kernel32/client/file/copy.c @@ -102,7 +102,7 @@ CopyLoop ( NULL, NULL); /* With sync read, 0 length + status success mean EOF: - * https://msdn.microsoft.com/en-us/library/windows/desktop/aa365467(v=vs.85).aspx + * https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-readfile */ if (NT_SUCCESS(errCode) && IoStatusBlock.Information == 0) { diff --git a/dll/win32/kernel32/client/file/filename.c b/dll/win32/kernel32/client/file/filename.c index 7365ac148bbab..a506678f9cdd2 100644 --- a/dll/win32/kernel32/client/file/filename.c +++ b/dll/win32/kernel32/client/file/filename.c @@ -104,7 +104,7 @@ GetTempFileNameW(IN LPCWSTR lpPathName, } /* lpTempFileName must be able to contain: PathName, Prefix (3), number(4), .tmp(4) & \0(1) - * See: http://msdn.microsoft.com/en-us/library/aa364991%28v=vs.85%29.aspx + * See: https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettempfilenamea */ if (PathNameString.Length > (MAX_PATH - 3 - 4 - 4 - 1) * sizeof(WCHAR)) { diff --git a/dll/win32/kernel32/client/heapmem.c b/dll/win32/kernel32/client/heapmem.c index 12b775c3785a9..6ccae1f236c0d 100644 --- a/dll/win32/kernel32/client/heapmem.c +++ b/dll/win32/kernel32/client/heapmem.c @@ -56,7 +56,7 @@ HeapCreate(DWORD flOptions, /* Check if heap is growable and ensure max size is correct */ if (dwMaximumSize == 0) Flags |= HEAP_GROWABLE; - else if (dwMaximumSize < BaseStaticServerData->SysInfo.PageSize && + else if (dwMaximumSize < WOW64_READ_ULONG_FIELD(BaseStaticServerData, BASE_STATIC_SERVER_DATA, SysInfo.PageSize) && dwInitialSize > dwMaximumSize) { /* Max size is non-zero but less than page size which can't be correct. @@ -1276,6 +1276,17 @@ GlobalMemoryStatusEx(LPMEMORYSTATUSEX lpBuffer) QUOTA_LIMITS QuotaLimits; ULONGLONG PageFile, PhysicalMemory; NTSTATUS Status; + ULONG PageSize; + ULONG NumberOfPhysicalPages; + + NumberOfPhysicalPages = + WOW64_READ_ULONG_FIELD(BaseStaticServerData, + BASE_STATIC_SERVER_DATA, + SysInfo.NumberOfPhysicalPages); + PageSize = + WOW64_READ_ULONG_FIELD(BaseStaticServerData, + BASE_STATIC_SERVER_DATA, + SysInfo.PageSize); if (lpBuffer->dwLength != sizeof(*lpBuffer)) { @@ -1295,18 +1306,18 @@ GlobalMemoryStatusEx(LPMEMORYSTATUSEX lpBuffer) } /* Calculate memory load */ - lpBuffer->dwMemoryLoad = ((DWORD)(BaseStaticServerData->SysInfo.NumberOfPhysicalPages - + lpBuffer->dwMemoryLoad = ((DWORD)(NumberOfPhysicalPages - PerformanceInfo.AvailablePages) * 100) / - BaseStaticServerData->SysInfo.NumberOfPhysicalPages; + NumberOfPhysicalPages; /* Save physical memory */ - PhysicalMemory = BaseStaticServerData->SysInfo.NumberOfPhysicalPages * - BaseStaticServerData->SysInfo.PageSize; + PhysicalMemory = NumberOfPhysicalPages * + PageSize; lpBuffer->ullTotalPhys = PhysicalMemory; /* Now save available physical memory */ PhysicalMemory = PerformanceInfo.AvailablePages * - BaseStaticServerData->SysInfo.PageSize; + PageSize; lpBuffer->ullAvailPhys = PhysicalMemory; /* Query VM and Quota Limits */ @@ -1335,7 +1346,7 @@ GlobalMemoryStatusEx(LPMEMORYSTATUSEX lpBuffer) /* Save the commit limit */ lpBuffer->ullTotalPageFile = min(QuotaLimits.PagefileLimit, PerformanceInfo.CommitLimit); - lpBuffer->ullTotalPageFile *= BaseStaticServerData->SysInfo.PageSize; + lpBuffer->ullTotalPageFile *= PageSize; /* Calculate how many pages are left */ PageFile = PerformanceInfo.CommitLimit - PerformanceInfo.CommittedPages; @@ -1344,11 +1355,15 @@ GlobalMemoryStatusEx(LPMEMORYSTATUSEX lpBuffer) lpBuffer->ullAvailPageFile = min(PageFile, QuotaLimits.PagefileLimit - VmCounters.PagefileUsage); - lpBuffer->ullAvailPageFile *= BaseStaticServerData->SysInfo.PageSize; + lpBuffer->ullAvailPageFile *= PageSize; /* Now calculate the total virtual space */ - lpBuffer->ullTotalVirtual = (BaseStaticServerData->SysInfo.MaximumUserModeAddress - - BaseStaticServerData->SysInfo.MinimumUserModeAddress) + 1; + lpBuffer->ullTotalVirtual = (WOW64_READ_PTR_FIELD(BaseStaticServerData, + BASE_STATIC_SERVER_DATA, + SysInfo.MaximumUserModeAddress) - + WOW64_READ_PTR_FIELD(BaseStaticServerData, + BASE_STATIC_SERVER_DATA, + SysInfo.MinimumUserModeAddress)) + 1; /* And finally the available virtual space */ lpBuffer->ullAvailVirtual = lpBuffer->ullTotalVirtual - VmCounters.VirtualSize; diff --git a/dll/win32/kernel32/client/path.c b/dll/win32/kernel32/client/path.c index ea014bb512d30..50842b76c114c 100644 --- a/dll/win32/kernel32/client/path.c +++ b/dll/win32/kernel32/client/path.c @@ -2421,9 +2421,17 @@ WINAPI GetSystemWow64DirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize) { -#ifdef _WIN64 - UNIMPLEMENTED; - return 0; +#if defined(_WIN64) || defined(BUILD_WOW6432) + const WCHAR WowDir[] = L"C:\\ReactOS\\SysWOW64"; + + /* FIXME */ + if (uSize < sizeof(WowDir) / sizeof(WCHAR)) + { + SetLastError(ERROR_INSUFFICIENT_BUFFER); + return 0; + } + RtlCopyMemory(lpBuffer, WowDir, sizeof(WowDir)); + return sizeof(WowDir) / sizeof(WCHAR) - 1; #else SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return 0; @@ -2438,9 +2446,17 @@ WINAPI GetSystemWow64DirectoryA(OUT LPSTR lpBuffer, IN UINT uSize) { -#ifdef _WIN64 - UNIMPLEMENTED; - return 0; +#if defined(_WIN64) || defined(BUILD_WOW6432) + const char WowDir[] = "C:\\ReactOS\\SysWOW64"; + + /* FIXME */ + if (uSize < sizeof(WowDir)) + { + SetLastError(ERROR_INSUFFICIENT_BUFFER); + return 0; + } + RtlCopyMemory(lpBuffer, WowDir, sizeof(WowDir)); + return sizeof(WowDir) - 1; #else SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return 0; diff --git a/dll/win32/kernel32/client/proc.c b/dll/win32/kernel32/client/proc.c index 669ede0e2f988..b9d5f8870406d 100644 --- a/dll/win32/kernel32/client/proc.c +++ b/dll/win32/kernel32/client/proc.c @@ -56,11 +56,18 @@ VOID WINAPI StuffStdHandle(IN HANDLE ProcessHandle, IN HANDLE StandardHandle, - IN PHANDLE Address) +#ifndef BUILD_WOW6432 + IN PHANDLE Address +#else + IN UINT64 Address +#endif + ) { NTSTATUS Status; HANDLE DuplicatedHandle; - SIZE_T NumberOfBytesWritten; +#ifdef BUILD_WOW6432 + UINT64 Tmp; +#endif /* If there is no handle to duplicate, return immediately */ if (!StandardHandle) return; @@ -77,11 +84,20 @@ StuffStdHandle(IN HANDLE ProcessHandle, if (!NT_SUCCESS(Status)) return; /* Write it */ +#ifndef BUILD_WOW6432 NtWriteVirtualMemory(ProcessHandle, Address, &DuplicatedHandle, sizeof(HANDLE), - &NumberOfBytesWritten); + NULL); +#else + Tmp = (ULONG_PTR)DuplicatedHandle; + NtWow64WriteVirtualMemory64(ProcessHandle, + Address, + &Tmp, + sizeof(Tmp), + NULL); +#endif } BOOLEAN @@ -479,11 +495,189 @@ BaseProcessStartup( _SEH2_END; } +#ifdef BUILD_WOW6432 +static +VOID +CopyParameterString(PWCHAR *Ptr, + PUNICODE_STRING64 Destination, + PUNICODE_STRING Source, + USHORT Size) +{ + Destination->Length = Source->Length; + Destination->MaximumLength = Size ? Size : Source->MaximumLength; + Destination->Buffer = WOW64_CAST_FROM_PTR(*Ptr); + if (Source->Length) + memmove(WOW64_CAST_TO_PTR(Destination->Buffer), Source->Buffer, Source->Length); + ((LPWSTR)WOW64_CAST_TO_PTR(Destination->Buffer))[Destination->Length / sizeof(WCHAR)] = 0; + *Ptr += Destination->MaximumLength / sizeof(WCHAR); +} + +/* TODO: This is duplicated code, find a better way to handle this. */ +static +NTSTATUS +CreateProcessParameters64( + PRTL_USER_PROCESS_PARAMETERS64 *ProcessParameters, + PUNICODE_STRING ImagePathName, + PUNICODE_STRING DllPath, + PUNICODE_STRING CurrentDirectory, + PUNICODE_STRING CommandLine, + PWSTR Environment, + PUNICODE_STRING WindowTitle, + PUNICODE_STRING DesktopInfo, + PUNICODE_STRING ShellInfo, + PUNICODE_STRING RuntimeData) +{ + PRTL_USER_PROCESS_PARAMETERS64 Param = NULL; + ULONG Length = 0; + PWCHAR Dest; + UNICODE_STRING EmptyString; + HANDLE CurrentDirectoryHandle; + HANDLE ConsoleHandle; + ULONG ConsoleFlags; + + DPRINT("CreateProcessParameters64\n"); + + RtlAcquirePebLock(); + + EmptyString.Length = 0; + EmptyString.MaximumLength = sizeof(WCHAR); + EmptyString.Buffer = L""; + + if (DllPath == NULL) + DllPath = &NtCurrentPeb()->ProcessParameters->DllPath; + if (Environment == NULL) + Environment = NtCurrentPeb()->ProcessParameters->Environment; + if (CurrentDirectory == NULL) + CurrentDirectory = &NtCurrentPeb()->ProcessParameters->CurrentDirectory.DosPath; + CurrentDirectoryHandle = NtCurrentPeb()->ProcessParameters->CurrentDirectory.Handle; + ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + ConsoleFlags = NtCurrentPeb()->ProcessParameters->ConsoleFlags; + + + if (CommandLine == NULL) + CommandLine = &EmptyString; + if (WindowTitle == NULL) + WindowTitle = &EmptyString; + if (DesktopInfo == NULL) + DesktopInfo = &EmptyString; + if (ShellInfo == NULL) + ShellInfo = &EmptyString; + if (RuntimeData == NULL) + RuntimeData = &EmptyString; + + /* size of process parameter block */ + Length = sizeof(RTL_USER_PROCESS_PARAMETERS64); + + /* size of current directory buffer */ + Length += (MAX_PATH * sizeof(WCHAR)); + + /* add string lengths */ + Length += ALIGN_UP_BY(DllPath->MaximumLength, sizeof(ULONG)); + Length += ALIGN_UP_BY(ImagePathName->Length + sizeof(WCHAR), sizeof(ULONG)); + Length += ALIGN_UP_BY(CommandLine->Length + sizeof(WCHAR), sizeof(ULONG)); + Length += ALIGN_UP_BY(WindowTitle->MaximumLength, sizeof(ULONG)); + Length += ALIGN_UP_BY(DesktopInfo->MaximumLength, sizeof(ULONG)); + Length += ALIGN_UP_BY(ShellInfo->MaximumLength, sizeof(ULONG)); + Length += ALIGN_UP_BY(RuntimeData->MaximumLength, sizeof(ULONG)); + + /* Calculate the required block size */ + Param = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length); + if (!Param) + { + RtlReleasePebLock(); + return STATUS_INSUFFICIENT_RESOURCES; + } + + DPRINT("Process parameters allocated\n"); + + Param->MaximumLength = Length; + Param->Length = Length; + Param->Flags = RTL_USER_PROCESS_PARAMETERS_NORMALIZED; + Param->Environment = WOW64_CAST_FROM_PTR(Environment); + Param->CurrentDirectory.Handle = WOW64_CAST_FROM_HANDLE(CurrentDirectoryHandle); + Param->ConsoleHandle = WOW64_CAST_FROM_HANDLE(ConsoleHandle); + Param->ConsoleFlags = ConsoleFlags; + + Dest = (PWCHAR)(((PBYTE)Param) + sizeof(RTL_USER_PROCESS_PARAMETERS64)); + + /* copy current directory */ + CopyParameterString(&Dest, &Param->CurrentDirectory.DosPath, CurrentDirectory, MAX_PATH * sizeof(WCHAR)); + + /* make sure the current directory has a trailing backslash */ + if (Param->CurrentDirectory.DosPath.Length > 0) + { + Length = Param->CurrentDirectory.DosPath.Length / sizeof(WCHAR); + if (((LPWSTR)WOW64_CAST_TO_PTR(Param->CurrentDirectory.DosPath.Buffer))[Length - 1] != L'\\') + { + ((LPWSTR)WOW64_CAST_TO_PTR(Param->CurrentDirectory.DosPath.Buffer))[Length] = L'\\'; + ((LPWSTR)WOW64_CAST_TO_PTR(Param->CurrentDirectory.DosPath.Buffer))[Length + 1] = 0; + Param->CurrentDirectory.DosPath.Length += sizeof(WCHAR); + } + } + + /* copy dll path */ + CopyParameterString(&Dest, &Param->DllPath, DllPath, 0); + + /* copy image path name */ + CopyParameterString(&Dest, &Param->ImagePathName, ImagePathName, ImagePathName->Length + sizeof(WCHAR)); + + /* copy command line */ + CopyParameterString(&Dest, &Param->CommandLine, CommandLine, CommandLine->Length + sizeof(WCHAR)); + + /* copy title */ + CopyParameterString(&Dest, &Param->WindowTitle, WindowTitle, 0); + + /* copy desktop */ + CopyParameterString(&Dest, &Param->DesktopInfo, DesktopInfo, 0); + + /* copy shell info */ + CopyParameterString(&Dest, &Param->ShellInfo, ShellInfo, 0); + + /* copy runtime info */ + CopyParameterString(&Dest, &Param->RuntimeData, RuntimeData, 0); + +#define DENORMALIZE(x,addr) {if(x) x=(UINT64)((ULONG_PTR)(x)-(ULONG_PTR)(addr));} + if (Param && (Param->Flags & RTL_USER_PROCESS_PARAMETERS_NORMALIZED)) + { + DENORMALIZE(Param->CurrentDirectory.DosPath.Buffer, Param); + DENORMALIZE(Param->DllPath.Buffer, Param); + DENORMALIZE(Param->ImagePathName.Buffer, Param); + DENORMALIZE(Param->CommandLine.Buffer, Param); + DENORMALIZE(Param->WindowTitle.Buffer, Param); + DENORMALIZE(Param->DesktopInfo.Buffer, Param); + DENORMALIZE(Param->ShellInfo.Buffer, Param); + DENORMALIZE(Param->RuntimeData.Buffer, Param); + + Param->Flags &= ~RTL_USER_PROCESS_PARAMETERS_NORMALIZED; + } +#undef DENORMALIZE + + *ProcessParameters = Param; + RtlReleasePebLock(); + + return STATUS_SUCCESS; +} + +/* TODO: This is duplicated code, find a better way to handle this. */ +static +NTSTATUS +DestroyProcessParameters64(IN PRTL_USER_PROCESS_PARAMETERS64 ProcessParameters) +{ + RtlFreeHeap(RtlGetProcessHeap(), 0, ProcessParameters); + return STATUS_SUCCESS; +} +#endif + + BOOLEAN WINAPI BasePushProcessParameters(IN ULONG ParameterFlags, IN HANDLE ProcessHandle, +#ifndef BUILD_WOW6432 IN PPEB RemotePeb, +#else + IN UINT64 RemotePeb, +#endif IN LPCWSTR ApplicationPathName, IN LPWSTR lpCurrentDirectory, IN LPWSTR lpCommandLine, @@ -497,7 +691,13 @@ BasePushProcessParameters(IN ULONG ParameterFlags, { WCHAR FullPath[MAX_PATH + 5]; PWCHAR Remaining, DllPathString, ScanChar; +#ifndef BUILD_WOW6432 PRTL_USER_PROCESS_PARAMETERS ProcessParameters, RemoteParameters; +#else + PRTL_USER_PROCESS_PARAMETERS64 ProcessParameters, RemoteParameters; + UINT64 Tmp; +#endif + PVOID RemoteAppCompatData; UNICODE_STRING DllPath, ImageName, CommandLine, CurrentDirectory; UNICODE_STRING Desktop, Shell, Runtime, Title; @@ -591,7 +791,11 @@ BasePushProcessParameters(IN ULONG ParameterFlags, DPRINT("Desktop : '%wZ'\n", &Desktop); DPRINT("Shell : '%wZ'\n", &Shell); DPRINT("Runtime : '%wZ'\n", &Runtime); +#ifndef BUILD_WOW6432 Status = RtlCreateProcessParameters(&ProcessParameters, +#else + Status = CreateProcessParameters64(&ProcessParameters, +#endif &ImageName, &DllPath, lpCurrentDirectory ? @@ -605,14 +809,14 @@ BasePushProcessParameters(IN ULONG ParameterFlags, if (!NT_SUCCESS(Status)) goto FailPath; /* Clear the current directory handle if not inheriting */ - if (!InheritHandles) ProcessParameters->CurrentDirectory.Handle = NULL; + if (!InheritHandles) ProcessParameters->CurrentDirectory.Handle = WOW64_CAST_FROM_HANDLE(NULL); /* Check if the user passed in an environment */ if (lpEnvironment) { /* We should've made it part of the parameters block, enforce this */ - ASSERT(ProcessParameters->Environment == lpEnvironment); - lpEnvironment = ProcessParameters->Environment; + ASSERT(ProcessParameters->Environment == WOW64_CAST_FROM_PTR(lpEnvironment)); + lpEnvironment = WOW64_CAST_TO_PTR(ProcessParameters->Environment); } else { @@ -632,7 +836,7 @@ BasePushProcessParameters(IN ULONG ParameterFlags, /* Allocate and Initialize new Environment Block */ Size = EnviroSize; - ProcessParameters->Environment = NULL; + ProcessParameters->Environment = WOW64_CAST_FROM_PTR(NULL); Status = NtAllocateVirtualMemory(ProcessHandle, (PVOID*)&ProcessParameters->Environment, 0, @@ -643,7 +847,7 @@ BasePushProcessParameters(IN ULONG ParameterFlags, /* Write the Environment Block */ Status = NtWriteVirtualMemory(ProcessHandle, - ProcessParameters->Environment, + WOW64_CAST_TO_PTR(ProcessParameters->Environment), lpEnvironment, EnviroSize, NULL); @@ -675,28 +879,28 @@ BasePushProcessParameters(IN ULONG ParameterFlags, if (StartupInfo->dwFlags & (STARTF_USESTDHANDLES | STARTF_USEHOTKEY | STARTF_SHELLPRIVATE)) { - ProcessParameters->StandardInput = StartupInfo->hStdInput; - ProcessParameters->StandardOutput = StartupInfo->hStdOutput; - ProcessParameters->StandardError = StartupInfo->hStdError; + ProcessParameters->StandardInput = WOW64_CAST_FROM_HANDLE(StartupInfo->hStdInput); + ProcessParameters->StandardOutput = WOW64_CAST_FROM_HANDLE(StartupInfo->hStdOutput); + ProcessParameters->StandardError = WOW64_CAST_FROM_HANDLE(StartupInfo->hStdError); } /* Use Special Flags for ConDllInitialize in Kernel32 */ if (CreationFlags & DETACHED_PROCESS) { - ProcessParameters->ConsoleHandle = HANDLE_DETACHED_PROCESS; + ProcessParameters->ConsoleHandle = WOW64_CAST_FROM_HANDLE(HANDLE_DETACHED_PROCESS); } else if (CreationFlags & CREATE_NEW_CONSOLE) { - ProcessParameters->ConsoleHandle = HANDLE_CREATE_NEW_CONSOLE; + ProcessParameters->ConsoleHandle = WOW64_CAST_FROM_HANDLE(HANDLE_CREATE_NEW_CONSOLE); } else if (CreationFlags & CREATE_NO_WINDOW) { - ProcessParameters->ConsoleHandle = HANDLE_CREATE_NO_WINDOW; + ProcessParameters->ConsoleHandle = WOW64_CAST_FROM_HANDLE(HANDLE_CREATE_NO_WINDOW); } else { /* Inherit our Console Handle */ - ProcessParameters->ConsoleHandle = Peb->ProcessParameters->ConsoleHandle; + ProcessParameters->ConsoleHandle = WOW64_CAST_FROM_HANDLE(Peb->ProcessParameters->ConsoleHandle); /* Make sure that the shell isn't trampling on our handles first */ if (!(StartupInfo->dwFlags & @@ -706,17 +910,17 @@ BasePushProcessParameters(IN ULONG ParameterFlags, if ((InheritHandles) || (IsConsoleHandle(Peb->ProcessParameters->StandardInput))) { - ProcessParameters->StandardInput = Peb->ProcessParameters->StandardInput; + ProcessParameters->StandardInput = WOW64_CAST_FROM_HANDLE(Peb->ProcessParameters->StandardInput); } if ((InheritHandles) || (IsConsoleHandle(Peb->ProcessParameters->StandardOutput))) { - ProcessParameters->StandardOutput = Peb->ProcessParameters->StandardOutput; + ProcessParameters->StandardOutput = WOW64_CAST_FROM_HANDLE(Peb->ProcessParameters->StandardOutput); } if ((InheritHandles) || (IsConsoleHandle(Peb->ProcessParameters->StandardError))) { - ProcessParameters->StandardError = Peb->ProcessParameters->StandardError; + ProcessParameters->StandardError = WOW64_CAST_FROM_HANDLE(Peb->ProcessParameters->StandardError); } } } @@ -773,11 +977,20 @@ BasePushProcessParameters(IN ULONG ParameterFlags, if (!NT_SUCCESS(Status)) goto FailPath; /* Write the PEB Pointer */ +#ifndef BUILD_WOW6432 Status = NtWriteVirtualMemory(ProcessHandle, &RemotePeb->ProcessParameters, &RemoteParameters, sizeof(PVOID), NULL); +#else + Tmp = (ULONG_PTR)RemoteParameters; + Status = NtWow64WriteVirtualMemory64(ProcessHandle, + RemotePeb + offsetof(PEB64, ProcessParameters), + &Tmp, + sizeof(Tmp), + NULL); +#endif if (!NT_SUCCESS(Status)) goto FailPath; /* Check if there's any app compat data to write */ @@ -804,21 +1017,39 @@ BasePushProcessParameters(IN ULONG ParameterFlags, } /* Write the PEB Pointer to the app compat data (might be NULL) */ +#ifndef BUILD_WOW6432 Status = NtWriteVirtualMemory(ProcessHandle, &RemotePeb->pShimData, &RemoteAppCompatData, sizeof(PVOID), NULL); +#else + Tmp = (ULONG_PTR)RemoteAppCompatData; + Status = NtWow64WriteVirtualMemory64(ProcessHandle, + RemotePeb + offsetof(PEB64, pShimData), + &Tmp, + sizeof(Tmp), + NULL); +#endif if (!NT_SUCCESS(Status)) goto FailPath; /* Now write Peb->ImageSubSystem */ if (ImageSubsystem) { +#ifndef BUILD_WOW6432 NtWriteVirtualMemory(ProcessHandle, &RemotePeb->ImageSubsystem, &ImageSubsystem, sizeof(ImageSubsystem), NULL); +#else + Tmp = ImageSubsystem; + NtWow64WriteVirtualMemory64(ProcessHandle, + RemotePeb + offsetof(PEB64, ImageSubsystem), + &Tmp, + sizeof(Tmp), + NULL); +#endif } /* Success path */ @@ -828,7 +1059,11 @@ BasePushProcessParameters(IN ULONG ParameterFlags, /* Cleanup */ if (HavePebLock) RtlReleasePebLock(); RtlFreeHeap(RtlGetProcessHeap(), 0, DllPath.Buffer); +#ifndef BUILD_WOW6432 if (ProcessParameters) RtlDestroyProcessParameters(ProcessParameters); +#else + if (ProcessParameters) DestroyProcessParameters64(ProcessParameters); +#endif return Result; FailPath: DPRINT1("Failure to create process parameters: %lx\n", Status); @@ -882,7 +1117,9 @@ GetProcessAffinityMask(IN HANDLE hProcess, /* Copy the affinity mask, and get the system one from our shared data */ *lpProcessAffinityMask = (DWORD)ProcessInfo.AffinityMask; - *lpSystemAffinityMask = (DWORD)BaseStaticServerData->SysInfo.ActiveProcessorsAffinityMask; + *lpSystemAffinityMask = WOW64_READ_ULONG_FIELD(BaseStaticServerData, + BASE_STATIC_SERVER_DATA, + SysInfo.ActiveProcessorsAffinityMask); return TRUE; } @@ -2276,13 +2513,20 @@ CreateProcessInternalW(IN HANDLE hUserToken, ULONG ResumeCount; PROCESS_PRIORITY_CLASS PriorityClass; NTSTATUS Status, AppCompatStatus, SaferStatus, IFEOStatus, ImageDbgStatus; - PPEB Peb, RemotePeb; +#ifndef BUILD_WOW6432 + PPEB RemotePeb; + PRTL_USER_PROCESS_PARAMETERS ProcessParameters; + PVOID TibValue; +#else + UINT64 ProcessParameters; + UINT64 RemotePeb; + UINT64 TibValue; +#endif + PPEB Peb; PTEB Teb; INITIAL_TEB InitialTeb; - PVOID TibValue; PIMAGE_NT_HEADERS NtHeaders; STARTUPINFOW StartupInfo; - PRTL_USER_PROCESS_PARAMETERS ProcessParameters; UNICODE_STRING DebuggerString; BOOL Result; // @@ -2501,7 +2745,7 @@ CreateProcessInternalW(IN HANDLE hUserToken, return FALSE; } else if (!(dwCreationFlags & CREATE_SHARED_WOW_VDM) && - (BaseStaticServerData->DefaultSeparateVDM)) + (WOW64_READ_BYTE_FIELD(BaseStaticServerData, BASE_STATIC_SERVER_DATA, DefaultSeparateVDM))) { /* A shared WoW VDM was not requested but system enforces separation */ dwCreationFlags |= CREATE_SEPARATE_WOW_VDM; @@ -2986,7 +3230,7 @@ CreateProcessInternalW(IN HANDLE hUserToken, /* Is a DOS VDM being forced, but we already have a WOW32 instance ready? */ if ((dwCreationFlags & CREATE_FORCEDOS) && - (BaseStaticServerData->IsWowTaskReady)) + (WOW64_READ_BYTE_FIELD(BaseStaticServerData, BASE_STATIC_SERVER_DATA, IsWowTaskReady))) { /* This request can't be satisfied, instead, a separate VDM is needed */ dwCreationFlags &= ~(CREATE_FORCEDOS | CREATE_SHARED_WOW_VDM); @@ -3627,6 +3871,11 @@ CreateProcessInternalW(IN HANDLE hUserToken, } } +#if defined(_M_AMD64) || defined(BUILD_WOW6432) + /* Allow x86_32 */ + if (ImageInformation.Machine == IMAGE_FILE_MACHINE_I386) {} + else +#endif /* Make sure the image was compiled for this processor */ if ((ImageInformation.Machine < SharedUserData->ImageNumberLow) || (ImageInformation.Machine > SharedUserData->ImageNumberHigh)) @@ -3864,7 +4113,11 @@ CreateProcessInternalW(IN HANDLE hUserToken, } /* Save the current TIB value since kernel overwrites it to store PEB */ +#ifndef BUILD_WOW6432 TibValue = Teb->NtTib.ArbitraryUserPointer; +#else + TibValue = NtCurrentTeb64()->NtTib.ArbitraryUserPointer; +#endif /* Tell the kernel to create the process */ Status = NtCreateProcessEx(&ProcessHandle, @@ -3878,10 +4131,15 @@ CreateProcessInternalW(IN HANDLE hUserToken, InJob); /* Load the PEB address from the hacky location where the kernel stores it */ +#ifndef BUILD_WOW6432 RemotePeb = Teb->NtTib.ArbitraryUserPointer; - + /* And restore the old TIB value */ Teb->NtTib.ArbitraryUserPointer = TibValue; +#else + RemotePeb = NtCurrentTeb64()->NtTib.ArbitraryUserPointer; + NtCurrentTeb64()->NtTib.ArbitraryUserPointer = TibValue; +#endif /* Release the large page privilege if we had acquired it */ if (HavePrivilege) RtlReleasePrivilege(PrivilegeState); @@ -4138,11 +4396,19 @@ CreateProcessInternalW(IN HANDLE hUserToken, (ImageInformation.SubSystemType == IMAGE_SUBSYSTEM_WINDOWS_CUI)) { /* Get the remote parameters */ +#ifndef BUILD_WOW6432 Status = NtReadVirtualMemory(ProcessHandle, &RemotePeb->ProcessParameters, &ProcessParameters, sizeof(PRTL_USER_PROCESS_PARAMETERS), NULL); +#else + Status = NtWow64ReadVirtualMemory64(ProcessHandle, + RemotePeb + offsetof(PEB64, ProcessParameters), + &ProcessParameters, + sizeof(ProcessParameters), + NULL); +#endif if (NT_SUCCESS(Status)) { /* Duplicate standard input unless it's a console handle */ @@ -4150,7 +4416,7 @@ CreateProcessInternalW(IN HANDLE hUserToken, { StuffStdHandle(ProcessHandle, Peb->ProcessParameters->StandardInput, - &ProcessParameters->StandardInput); + WOW64_FIELD_PTR(ProcessParameters, RTL_USER_PROCESS_PARAMETERS64, StandardInput)); } /* Duplicate standard output unless it's a console handle */ @@ -4158,7 +4424,7 @@ CreateProcessInternalW(IN HANDLE hUserToken, { StuffStdHandle(ProcessHandle, Peb->ProcessParameters->StandardOutput, - &ProcessParameters->StandardOutput); + WOW64_FIELD_PTR(ProcessParameters, RTL_USER_PROCESS_PARAMETERS64, StandardOutput)); } /* Duplicate standard error unless it's a console handle */ @@ -4166,7 +4432,7 @@ CreateProcessInternalW(IN HANDLE hUserToken, { StuffStdHandle(ProcessHandle, Peb->ProcessParameters->StandardError, - &ProcessParameters->StandardError); + WOW64_FIELD_PTR(ProcessParameters, RTL_USER_PROCESS_PARAMETERS64, StandardError)); } } } @@ -4186,11 +4452,19 @@ CreateProcessInternalW(IN HANDLE hUserToken, } /* Create the Thread's Context */ +#ifndef BUILD_WOW6432 BaseInitializeContext(&Context, RemotePeb, ImageInformation.TransferAddress, InitialTeb.StackBase, 0); +#else + BaseInitializeContext(&Context, + NULL, + ImageInformation.TransferAddress, + InitialTeb.StackBase, + 0); +#endif /* Convert the thread attributes */ ObjectAttributes = BaseFormatObjectAttributes(&LocalObjectAttributes, @@ -4225,19 +4499,25 @@ CreateProcessInternalW(IN HANDLE hUserToken, } /* Begin filling out the CSRSS message, first with our IDs and handles */ - CreateProcessMsg->ProcessHandle = ProcessHandle; - CreateProcessMsg->ThreadHandle = ThreadHandle; - CreateProcessMsg->ClientId = ClientId; + CreateProcessMsg->ProcessHandle = TO_LPC_HANDLE(ProcessHandle); + CreateProcessMsg->ThreadHandle = TO_LPC_HANDLE(ThreadHandle); + CreateProcessMsg->ClientId.UniqueProcess = TO_LPC_HANDLE(ClientId.UniqueProcess); + CreateProcessMsg->ClientId.UniqueThread = TO_LPC_HANDLE(ClientId.UniqueThread); /* Write the remote PEB address and clear it locally, we no longer use it */ - CreateProcessMsg->PebAddressNative = RemotePeb; + CreateProcessMsg->PebAddressNative = (LPC_PVOID)RemotePeb; #ifdef _WIN64 DPRINT("TODO: WOW64 is not supported yet\n"); CreateProcessMsg->PebAddressWow64 = 0; #else CreateProcessMsg->PebAddressWow64 = (ULONG)RemotePeb; #endif + +#ifndef BUILD_WOW6432 RemotePeb = NULL; +#else + RemotePeb = 0; +#endif /* Now check what kind of architecture this image was made for */ switch (ImageInformation.Machine) @@ -4274,7 +4554,7 @@ CreateProcessInternalW(IN HANDLE hUserToken, * (basesrv in particular) to know whether or not this is a GUI or a * TUI application. */ - AddToHandle(CreateProcessMsg->ProcessHandle, 2); + AddToHandle(FROM_LPC_HANDLE(CreateProcessMsg->ProcessHandle), 2); /* Also check if the parent is also a GUI process */ NtHeaders = RtlImageNtHeader(GetModuleHandle(NULL)); @@ -4282,7 +4562,7 @@ CreateProcessInternalW(IN HANDLE hUserToken, (NtHeaders->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI)) { /* Let it know that it should display the hourglass mouse cursor */ - AddToHandle(CreateProcessMsg->ProcessHandle, 1); + AddToHandle(FROM_LPC_HANDLE(CreateProcessMsg->ProcessHandle), 1); } } @@ -4290,11 +4570,11 @@ CreateProcessInternalW(IN HANDLE hUserToken, * Likewise, the opposite holds as well, and no-feedback has precedence. */ if (StartupInfo.dwFlags & STARTF_FORCEONFEEDBACK) { - AddToHandle(CreateProcessMsg->ProcessHandle, 1); + AddToHandle(FROM_LPC_HANDLE(CreateProcessMsg->ProcessHandle), 1); } if (StartupInfo.dwFlags & STARTF_FORCEOFFFEEDBACK) { - RemoveFromHandle(CreateProcessMsg->ProcessHandle, 1); + RemoveFromHandle(FROM_LPC_HANDLE(CreateProcessMsg->ProcessHandle), 1); } /* Also store which kind of VDM app (if any) this is */ @@ -4304,7 +4584,7 @@ CreateProcessInternalW(IN HANDLE hUserToken, if (VdmBinaryType) { /* Store the VDM console handle (none if inherited or WOW app) and the task ID */ - CreateProcessMsg->hVDM = VdmTask ? NULL : Peb->ProcessParameters->ConsoleHandle; + CreateProcessMsg->hVDM = TO_LPC_HANDLE(VdmTask ? NULL : Peb->ProcessParameters->ConsoleHandle); CreateProcessMsg->VdmTask = VdmTask; } else if (VdmReserve) diff --git a/dll/win32/kernel32/client/synch.c b/dll/win32/kernel32/client/synch.c index 2c0e9a7f06305..bbe88d9957c79 100644 --- a/dll/win32/kernel32/client/synch.c +++ b/dll/win32/kernel32/client/synch.c @@ -757,6 +757,16 @@ InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection) if (!NT_SUCCESS(Status)) RtlRaiseStatus(Status); } +/* + * @implemented + */ +BOOL +WINAPI +TryEnterCriticalSection(IN LPCRITICAL_SECTION lpCriticalSection) +{ + return !!RtlTryEnterCriticalSection((PVOID)lpCriticalSection); +} + /* * @implemented */ diff --git a/dll/win32/kernel32/client/thread.c b/dll/win32/kernel32/client/thread.c index 0df088d510e5f..0ed9c6a8fa39e 100644 --- a/dll/win32/kernel32/client/thread.c +++ b/dll/win32/kernel32/client/thread.c @@ -11,6 +11,12 @@ #include +#ifdef _M_IX86 +#include "i386/ketypes.h" +#elif defined _M_AMD64 +#include "amd64/ketypes.h" +#endif + #define NDEBUG #include @@ -32,8 +38,9 @@ BasepNotifyCsrOfThread(IN HANDLE ThreadHandle, ClientId->UniqueThread, ThreadHandle); /* Fill out the request */ - CreateThreadRequest->ClientId = *ClientId; - CreateThreadRequest->ThreadHandle = ThreadHandle; + CreateThreadRequest->ClientId.UniqueProcess = TO_LPC_HANDLE(ClientId->UniqueProcess); + CreateThreadRequest->ClientId.UniqueThread = TO_LPC_HANDLE(ClientId->UniqueThread); + CreateThreadRequest->ThreadHandle = TO_LPC_HANDLE(ThreadHandle); /* Call CSR */ CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, diff --git a/dll/win32/kernel32/client/time.c b/dll/win32/kernel32/client/time.c index 7c67e1165ce97..3217112054967 100644 --- a/dll/win32/kernel32/client/time.c +++ b/dll/win32/kernel32/client/time.c @@ -26,7 +26,42 @@ WINAPI IsTimeZoneRedirectionEnabled(VOID) { /* Return if a TS Timezone ID is active */ - return (BaseStaticServerData->TermsrvClientTimeZoneId != TIME_ZONE_ID_INVALID); + return (WOW64_READ_ULONG_FIELD(BaseStaticServerData, + BASE_STATIC_SERVER_DATA, + TermsrvClientTimeZoneId) != TIME_ZONE_ID_INVALID); +} + +static +VOID +GetTimeZoneBias(OUT PLARGE_INTEGER pTimeZoneBias) +{ +#ifndef BUILD_WOW6432 + volatile KSYSTEM_TIME *TimePtr; + + TimePtr = IsTimeZoneRedirectionEnabled() ? + &BaseStaticServerData->ktTermsrvClientBias : + &SharedUserData->TimeZoneBias; + + do + { + pTimeZoneBias->HighPart = TimePtr->High1Time; + pTimeZoneBias->LowPart = TimePtr->LowPart; + } + while (pTimeZoneBias->HighPart != TimePtr->High2Time); +#else + UINT64 TimePtr; + + TimePtr = IsTimeZoneRedirectionEnabled() ? + (BaseStaticServerData + offsetof(BASE_STATIC_SERVER_DATA, ktTermsrvClientBias)) : + WOW64_CAST_FROM_PTR(&SharedUserData->TimeZoneBias); + + do + { + pTimeZoneBias->HighPart = (LONG)WOW64_READ_ULONG_FIELD(TimePtr, volatile KSYSTEM_TIME, High1Time); + pTimeZoneBias->LowPart = WOW64_READ_ULONG_FIELD(TimePtr, volatile KSYSTEM_TIME, LowPart); + } + while (pTimeZoneBias->HighPart != (LONG)WOW64_READ_ULONG_FIELD(TimePtr, volatile KSYSTEM_TIME, High2Time)); +#endif } /* @@ -222,17 +257,7 @@ FileTimeToLocalFileTime(IN CONST FILETIME *lpFileTime, OUT LPFILETIME lpLocalFileTime) { LARGE_INTEGER TimeZoneBias, FileTime; - volatile KSYSTEM_TIME *TimePtr; - - TimePtr = IsTimeZoneRedirectionEnabled() ? - &BaseStaticServerData->ktTermsrvClientBias : - &SharedUserData->TimeZoneBias; - do - { - TimeZoneBias.HighPart = TimePtr->High1Time; - TimeZoneBias.LowPart = TimePtr->LowPart; - } - while (TimeZoneBias.HighPart != TimePtr->High2Time); + GetTimeZoneBias(&TimeZoneBias); FileTime.LowPart = lpFileTime->dwLowDateTime; FileTime.HighPart = lpFileTime->dwHighDateTime; @@ -254,18 +279,7 @@ LocalFileTimeToFileTime(IN CONST FILETIME *lpLocalFileTime, OUT LPFILETIME lpFileTime) { LARGE_INTEGER TimeZoneBias, FileTime; - volatile KSYSTEM_TIME *TimePtr; - - TimePtr = IsTimeZoneRedirectionEnabled() ? - &BaseStaticServerData->ktTermsrvClientBias : - &SharedUserData->TimeZoneBias; - - do - { - TimeZoneBias.HighPart = TimePtr->High1Time; - TimeZoneBias.LowPart = TimePtr->LowPart; - } - while (TimeZoneBias.HighPart != TimePtr->High2Time); + GetTimeZoneBias(&TimeZoneBias); FileTime.LowPart = lpLocalFileTime->dwLowDateTime; FileTime.HighPart = lpLocalFileTime->dwHighDateTime; @@ -287,7 +301,6 @@ GetLocalTime(OUT LPSYSTEMTIME lpSystemTime) { LARGE_INTEGER SystemTime, TimeZoneBias; TIME_FIELDS TimeFields; - volatile KSYSTEM_TIME *TimePtr; do { @@ -296,15 +309,7 @@ GetLocalTime(OUT LPSYSTEMTIME lpSystemTime) } while (SystemTime.HighPart != SharedUserData->SystemTime.High2Time); - TimePtr = IsTimeZoneRedirectionEnabled() ? - &BaseStaticServerData->ktTermsrvClientBias : - &SharedUserData->TimeZoneBias; - do - { - TimeZoneBias.HighPart = TimePtr->High1Time; - TimeZoneBias.LowPart = TimePtr->LowPart; - } - while (TimeZoneBias.HighPart != TimePtr->High2Time); + GetTimeZoneBias(&TimeZoneBias); SystemTime.QuadPart -= TimeZoneBias.QuadPart; RtlTimeToTimeFields(&SystemTime, &TimeFields); @@ -360,17 +365,8 @@ SetLocalTime(IN CONST SYSTEMTIME *lpSystemTime) ULONG Privilege = SE_SYSTEMTIME_PRIVILEGE; TIME_FIELDS TimeFields; PVOID State; - volatile KSYSTEM_TIME *TimePtr; - TimePtr = IsTimeZoneRedirectionEnabled() ? - &BaseStaticServerData->ktTermsrvClientBias : - &SharedUserData->TimeZoneBias; - do - { - TimeZoneBias.HighPart = TimePtr->High1Time; - TimeZoneBias.LowPart = TimePtr->LowPart; - } - while (TimeZoneBias.HighPart != TimePtr->High2Time); + GetTimeZoneBias(&TimeZoneBias); TimeFields.Year = lpSystemTime->wYear; TimeFields.Month = lpSystemTime->wMonth; @@ -551,7 +547,7 @@ GetSystemTimes(OUT LPFILETIME lpIdleTime OPTIONAL, TotalUserTime.QuadPart = TotalKernTime.QuadPart = TotalIdleTime.QuadPart = 0; BufferSize = sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * - BaseStaticServerData->SysInfo.NumberOfProcessors; + WOW64_READ_BYTE_FIELD(BaseStaticServerData, BASE_STATIC_SERVER_DATA, SysInfo.NumberOfProcessors); ProcPerfInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferSize); if (!ProcPerfInfo) @@ -568,7 +564,11 @@ GetSystemTimes(OUT LPFILETIME lpIdleTime OPTIONAL, { if (lpIdleTime) { - for (i = 0; i < BaseStaticServerData->SysInfo.NumberOfProcessors; i++) + for (i = 0; + i < (CCHAR)WOW64_READ_BYTE_FIELD(BaseStaticServerData, + BASE_STATIC_SERVER_DATA, + SysInfo.NumberOfProcessors); + i++) { TotalIdleTime.QuadPart += ProcPerfInfo[i].IdleTime.QuadPart; } @@ -579,7 +579,11 @@ GetSystemTimes(OUT LPFILETIME lpIdleTime OPTIONAL, if (lpKernelTime) { - for (i = 0; i < BaseStaticServerData->SysInfo.NumberOfProcessors; i++) + for (i = 0; + i < (CCHAR)WOW64_READ_BYTE_FIELD(BaseStaticServerData, + BASE_STATIC_SERVER_DATA, + SysInfo.NumberOfProcessors); + i++) { TotalKernTime.QuadPart += ProcPerfInfo[i].KernelTime.QuadPart; } @@ -590,7 +594,11 @@ GetSystemTimes(OUT LPFILETIME lpIdleTime OPTIONAL, if (lpUserTime) { - for (i = 0; i < BaseStaticServerData->SysInfo.NumberOfProcessors; i++) + for (i = 0; + i < (CCHAR)WOW64_READ_BYTE_FIELD(BaseStaticServerData, + BASE_STATIC_SERVER_DATA, + SysInfo.NumberOfProcessors); + i++) { TotalUserTime.QuadPart += ProcPerfInfo[i].UserTime.QuadPart; } diff --git a/dll/win32/kernel32/client/utils.c b/dll/win32/kernel32/client/utils.c index 54a6f05fa5cdf..d9773630985f2 100644 --- a/dll/win32/kernel32/client/utils.c +++ b/dll/win32/kernel32/client/utils.c @@ -65,6 +65,10 @@ BaseGetNamedObjectDirectory(VOID) OBJECT_ATTRIBUTES ObjectAttributes; NTSTATUS Status; HANDLE DirHandle, BnoHandle, Token, NewToken; + UNICODE_STRING Temp; +#ifdef BUILD_WOW6432 + WCHAR TempBuffer[MAX_PATH]; +#endif if (BaseNamedObjectDirectory) return BaseNamedObjectDirectory; @@ -95,8 +99,32 @@ BaseGetNamedObjectDirectory(VOID) RtlAcquirePebLock(); if (BaseNamedObjectDirectory) goto Quickie; + Temp.Length = + WOW64_READ_WORD_FIELD(BaseStaticServerData, + BASE_STATIC_SERVER_DATA, + NamedObjectDirectory.Length); + Temp.MaximumLength = + WOW64_READ_WORD_FIELD(BaseStaticServerData, + BASE_STATIC_SERVER_DATA, + NamedObjectDirectory.MaximumLength); +#ifndef BUILD_WOW6432 + Temp.Buffer = BaseStaticServerData->NamedObjectDirectory.Buffer; +#else + Temp.Buffer = TempBuffer; + + ASSERT(Temp.MaximumLength < sizeof(TempBuffer)); + + NtWow64ReadVirtualMemory64(NtCurrentProcess(), + WOW64_READ_PTR_FIELD(BaseStaticServerData, + BASE_STATIC_SERVER_DATA, + NamedObjectDirectory.Buffer), + TempBuffer, + Temp.MaximumLength, + NULL); +#endif + InitializeObjectAttributes(&ObjectAttributes, - &BaseStaticServerData->NamedObjectDirectory, + &Temp, OBJ_CASE_INSENSITIVE, NULL, NULL); @@ -368,8 +396,14 @@ BaseCreateStack( hProcess, StackReserve, StackCommit); /* Read page size */ - PageSize = BaseStaticServerData->SysInfo.PageSize; - AllocationGranularity = BaseStaticServerData->SysInfo.AllocationGranularity; + PageSize = + WOW64_READ_ULONG_FIELD(BaseStaticServerData, + BASE_STATIC_SERVER_DATA, + SysInfo.PageSize); + AllocationGranularity = + WOW64_READ_ULONG_FIELD(BaseStaticServerData, + BASE_STATIC_SERVER_DATA, + SysInfo.AllocationGranularity); /* Get the Image Headers */ Headers = RtlImageNtHeader(NtCurrentPeb()->ImageBaseAddress); diff --git a/dll/win32/kernel32/client/vdm.c b/dll/win32/kernel32/client/vdm.c index 98c326a5f246d..609ab49c0c4a3 100644 --- a/dll/win32/kernel32/client/vdm.c +++ b/dll/win32/kernel32/client/vdm.c @@ -1840,14 +1840,14 @@ RegisterConsoleVDM(IN DWORD dwRegisterFlags, PCSR_CAPTURE_BUFFER CaptureBuffer = NULL; /* Set up the data to send to the Console Server */ - RegisterVDMRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + RegisterVDMRequest->ConsoleHandle = TO_LPC_HANDLE(NtCurrentPeb()->ProcessParameters->ConsoleHandle); RegisterVDMRequest->RegisterFlags = dwRegisterFlags; if (dwRegisterFlags != 0) { - RegisterVDMRequest->StartHardwareEvent = hStartHardwareEvent; - RegisterVDMRequest->EndHardwareEvent = hEndHardwareEvent; - RegisterVDMRequest->ErrorHardwareEvent = hErrorHardwareEvent; + RegisterVDMRequest->StartHardwareEvent = TO_LPC_HANDLE(hStartHardwareEvent); + RegisterVDMRequest->EndHardwareEvent = TO_LPC_HANDLE(hEndHardwareEvent); + RegisterVDMRequest->ErrorHardwareEvent = TO_LPC_HANDLE(hErrorHardwareEvent); RegisterVDMRequest->VDMBufferSize = dwVDMBufferSize; @@ -1895,8 +1895,8 @@ RegisterConsoleVDM(IN DWORD dwRegisterFlags, _SEH2_TRY { *lpVideoStateLength = RegisterVDMRequest->VideoStateLength; - *lpVideoState = RegisterVDMRequest->VideoState; - *lpVDMBuffer = RegisterVDMRequest->VDMBuffer; + *lpVideoState = (PVOID)RegisterVDMRequest->VideoState; + *lpVDMBuffer = (PVOID)RegisterVDMRequest->VDMBuffer; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { diff --git a/dll/win32/kernel32/client/virtmem.c b/dll/win32/kernel32/client/virtmem.c index e2ae076266f79..702a92322665a 100644 --- a/dll/win32/kernel32/client/virtmem.c +++ b/dll/win32/kernel32/client/virtmem.c @@ -30,7 +30,9 @@ VirtualAllocEx(IN HANDLE hProcess, /* Make sure the address is within the granularity of the system (64K) */ if ((lpAddress != NULL) && - (lpAddress < UlongToPtr(BaseStaticServerData->SysInfo.AllocationGranularity))) + (lpAddress < UlongToPtr(WOW64_READ_ULONG_FIELD(BaseStaticServerData, + BASE_STATIC_SERVER_DATA, + SysInfo.AllocationGranularity)))) { /* Fail the call */ SetLastError(ERROR_INVALID_PARAMETER); diff --git a/dll/win32/kernel32/include/baseheap.h b/dll/win32/kernel32/include/baseheap.h index 9312290f88517..91a71d028f390 100644 --- a/dll/win32/kernel32/include/baseheap.h +++ b/dll/win32/kernel32/include/baseheap.h @@ -24,7 +24,7 @@ // // Apart from MSDN, a wonderful source of information about how this works is // available on Raymond's blog, in a 4-parter series starting at: -// http://blogs.msdn.com/oldnewthing/archive/2004/11/04/252258.aspx. +// https://devblogs.microsoft.com/oldnewthing/20041104-00/?p=37393 . // // Finally, as Raymond points out, be aware that some applications depend on // the way this implementation was done, since global memory handles are a diff --git a/dll/win32/kernel32/include/console.h b/dll/win32/kernel32/include/console.h index 5fe84cb304c07..e01c9936618e4 100644 --- a/dll/win32/kernel32/include/console.h +++ b/dll/win32/kernel32/include/console.h @@ -68,7 +68,7 @@ SetUpConsoleInfo(IN BOOLEAN CaptureTitle, IN OUT LPDWORD pTitleLength, IN OUT LPWSTR* lpTitle OPTIONAL, IN OUT LPDWORD pDesktopLength, - IN OUT LPWSTR* lpDesktop OPTIONAL, + IN OUT LPC_PTRTYPE(LPWSTR)* lpDesktop OPTIONAL, IN OUT PCONSOLE_START_INFO ConsoleStartInfo); VOID diff --git a/dll/win32/kernel32/include/kernel32.h b/dll/win32/kernel32/include/kernel32.h index c331e45f465d6..624d6e99ce7ca 100644 --- a/dll/win32/kernel32/include/kernel32.h +++ b/dll/win32/kernel32/include/kernel32.h @@ -108,7 +108,11 @@ typedef struct _BASEP_ACTCTX_BLOCK #define BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_SUCCESS 2 #define BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_CONTINUE 3 +#ifndef BUILD_WOW6432 extern PBASE_STATIC_SERVER_DATA BaseStaticServerData; +#else +extern UINT64 BaseStaticServerData; +#endif typedef DWORD diff --git a/dll/win32/kernel32/k32.h b/dll/win32/kernel32/k32.h index c84dabe00866c..5a3f5f49ffe5a 100644 --- a/dll/win32/kernel32/k32.h +++ b/dll/win32/kernel32/k32.h @@ -75,4 +75,8 @@ /* Virtual DOS Machines (VDM) Support Definitions */ #include "include/vdm.h" +/* WOW64 */ +#include "../../ntdll/wow64/ntdll32.h" +#include "../../wow64/wine/struct32.h" + #endif /* __K32_H */ diff --git a/dll/win32/kernel32/kernel32.spec b/dll/win32/kernel32/kernel32.spec index 831681d1aaac1..642e3e03750c5 100644 --- a/dll/win32/kernel32/kernel32.spec +++ b/dll/win32/kernel32/kernel32.spec @@ -32,12 +32,14 @@ @ stub -version=0x600+ BaseGenerateAppCompatData @ stdcall BaseInitAppcompatCacheSupport() @ stdcall BaseIsAppcompatInfrastructureDisabled() IsShimInfrastructureDisabled -@ stdcall -version=0x501-0x502 BaseProcessInitPostImport() -@ stdcall -version=0x600+ BaseProcessInitPostImport() # HACK: This export is dynamicaly imported by ntdll -;@ stdcall -version=0x502 -arch=x86_64 BaseProcessStart() +;@ stdcall -version=0x501-0x502 BaseProcessInitPostImport() +@ stdcall BaseProcessInitPostImport() # HACK: This export is dynamicaly imported by ntdll +@ stdcall -version=0x502 -arch=x86_64 BaseProcessStart() BaseProcessStartup +@ stdcall -version=0x502 -arch=i386 BaseProcessStartThunk() ; FIXME: WOW64 only @ stdcall BaseQueryModuleData(str str ptr ptr ptr) ;check -@ stub -version=0x600+ BaseThreadInitThunk -;@ stdcall -version=0x502 -arch=x86_64 BaseThreadStart() +;@ stub -version=0x600+ BaseThreadInitThunk +@ stdcall -version=0x502 -arch=x86_64 BaseThreadStart() BaseThreadStartup +@ stdcall -version=0x502 -arch=i386 BaseThreadStartupThunk() ; FIXME: WOW64 only @ stdcall BaseUpdateAppcompatCache(long long long) @ stdcall BasepCheckBadapp(long ptr long long long long long long long) @ stdcall BasepCheckWinSaferRestrictions(long long long long long long) @@ -760,6 +762,33 @@ @ stdcall IsValidLocale(long long) @ stdcall -version=0x501-0x502 IsValidUILanguage(long) @ stdcall IsWow64Process(ptr ptr) +@ stdcall -version=0x601+ K32EmptyWorkingSet(long) EmptyWorkingSet +@ stdcall -version=0x601+ K32EnumDeviceDrivers(ptr long ptr) EnumDeviceDrivers +@ stdcall -version=0x601+ K32EnumPageFilesA(ptr ptr) EnumPageFilesA +@ stdcall -version=0x601+ K32EnumPageFilesW(ptr ptr) EnumPageFilesW +@ stdcall -version=0x601+ K32EnumProcessModules(long ptr long ptr) EnumProcessModules +@ stdcall -stub -version=0x601+ K32EnumProcessModulesEx(long ptr long ptr long); EnumProcessModulesEx +@ stdcall -version=0x601+ K32EnumProcesses(ptr long ptr) EnumProcesses +@ stdcall -version=0x601+ K32GetDeviceDriverBaseNameA(ptr ptr long) GetDeviceDriverBaseNameA +@ stdcall -version=0x601+ K32GetDeviceDriverBaseNameW(ptr ptr long) GetDeviceDriverBaseNameW +@ stdcall -version=0x601+ K32GetDeviceDriverFileNameA(ptr ptr long) GetDeviceDriverFileNameA +@ stdcall -version=0x601+ K32GetDeviceDriverFileNameW(ptr ptr long) GetDeviceDriverFileNameW +@ stdcall -version=0x601+ K32GetMappedFileNameA(long ptr ptr long) GetMappedFileNameA +@ stdcall -version=0x601+ K32GetMappedFileNameW(long ptr ptr long) GetMappedFileNameW +@ stdcall -version=0x601+ K32GetModuleBaseNameA(long long ptr long) GetModuleBaseNameA +@ stdcall -version=0x601+ K32GetModuleBaseNameW(long long ptr long) GetModuleBaseNameW +@ stdcall -version=0x601+ K32GetModuleFileNameExA(long long ptr long) GetModuleFileNameExA +@ stdcall -version=0x601+ K32GetModuleFileNameExW(long long ptr long) GetModuleFileNameExW +@ stdcall -version=0x601+ K32GetModuleInformation(long long ptr long) GetModuleInformation +@ stdcall -version=0x601+ K32GetPerformanceInfo(ptr long) GetPerformanceInfo +@ stdcall -version=0x601+ K32GetProcessImageFileNameA(long ptr long) GetProcessImageFileNameA +@ stdcall -version=0x601+ K32GetProcessImageFileNameW(long ptr long) GetProcessImageFileNameW +@ stdcall -version=0x601+ K32GetProcessMemoryInfo(long ptr long) GetProcessMemoryInfo +@ stdcall -version=0x601+ K32GetWsChanges(long ptr long) GetWsChanges +@ stdcall -stub -version=0x601+ K32GetWsChangesEx(long ptr ptr); GetWsChangesEx +@ stdcall -version=0x601+ K32InitializeProcessForWsWatch(long) InitializeProcessForWsWatch +@ stdcall -version=0x601+ K32QueryWorkingSet(long ptr long) QueryWorkingSet +@ stdcall -version=0x601+ K32QueryWorkingSetEx(long ptr long) QueryWorkingSetEx @ stdcall -version=0x600+ LCIDToLocaleName(long wstr long long) @ stdcall LCMapStringA(long long str long ptr long) @ stdcall -version=0x600+ LCMapStringEx(long long wstr long ptr long ptr ptr long) @@ -954,7 +983,7 @@ @ stdcall -arch=x86_64 RtlRestoreContext(ptr ptr) ntdll.RtlRestoreContext @ stdcall RtlUnwind(ptr ptr ptr ptr) ntdll.RtlUnwind @ stdcall -arch=x86_64 RtlUnwindEx(ptr ptr ptr ptr ptr ptr) ntdll.RtlUnwindEx -@ stdcall -arch=x86_64 RtlVirtualUnwind(ptr ptr ptr long) ntdll.RtlVirtualUnwind +@ stdcall -arch=x86_64 RtlVirtualUnwind(long int64 int64 ptr ptr ptr ptr ptr) ntdll.RtlVirtualUnwind @ stdcall RtlZeroMemory(ptr long) ntdll.RtlZeroMemory @ stdcall ScrollConsoleScreenBufferA(long ptr ptr ptr ptr) @ stdcall ScrollConsoleScreenBufferW(long ptr ptr ptr ptr) @@ -1128,7 +1157,7 @@ @ stdcall Toolhelp32ReadProcessMemory(long ptr ptr long ptr) @ stdcall TransactNamedPipe(long ptr long ptr long ptr ptr) @ stdcall TransmitCommChar(long long) -@ stdcall TryEnterCriticalSection(ptr) ntdll.RtlTryEnterCriticalSection +@ stdcall TryEnterCriticalSection(ptr) @ stub -version=0x600+ TrySubmitThreadpoolCallback @ stdcall TzSpecificLocalTimeToSystemTime(ptr ptr ptr) @ stdcall UTRegister(long str str str ptr ptr ptr) @@ -1267,4 +1296,4 @@ ;@ stdcall -arch=x86_64 uaw_wcscpy(ptr wstr) ;@ stdcall -arch=x86_64 uaw_wcsicmp(wstr wstr) ;@ stdcall -arch=x86_64 uaw_wcslen(wstr) -;@ stdcall -arch=x86_64 uaw_wcsrchr(wstr long) +;@ stdcall -arch=x86_64 uaw_wcsrchr(wstr long) \ No newline at end of file diff --git a/dll/win32/kernel32/kernel32_vista/vista.c b/dll/win32/kernel32/kernel32_vista/vista.c index ca96b233b3bc3..1d34450220a5b 100644 --- a/dll/win32/kernel32/kernel32_vista/vista.c +++ b/dll/win32/kernel32/kernel32_vista/vista.c @@ -591,12 +591,12 @@ OpenFileById(IN HANDLE hFile, Vista+ MUI support functions References: - Evolution of MUI Support across Windows Versions: http://msdn.microsoft.com/en-US/library/ee264317.aspx - Comparing Windows XP Professional Multilingual Options: http://technet.microsoft.com/en-us/library/bb457045.aspx + Evolution of MUI Support across Windows Versions: https://learn.microsoft.com/en-us/windows/win32/intl/evolution-of-mui-support-across-windows-versions + Comparing Windows XP Professional Multilingual Options: https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-xp/bb457045(v=technet.10)?redirectedfrom=MSDN More info: - http://msdn.microsoft.com/en-us/goglobal/bb978454.aspx - http://msdn.microsoft.com/en-us/library/dd319074.aspx + https://web.archive.org/web/20170930153551/http://msdn.microsoft.com/en-us/goglobal/bb978454.aspx + https://learn.microsoft.com/en-us/windows/win32/intl/multilingual-user-interface-functions */ /* FUNCTIONS *****************************************************************/ diff --git a/dll/win32/kernel32/wine/profile.c b/dll/win32/kernel32/wine/profile.c index 0cd9970a13520..f89da3f2988a9 100644 --- a/dll/win32/kernel32/wine/profile.c +++ b/dll/win32/kernel32/wine/profile.c @@ -103,7 +103,7 @@ static RTL_CRITICAL_SECTION_DEBUG critsect_debug = { 0, 0, &PROFILE_CritSect, { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList }, - 0, 0, 0 + 0, 0, { 0 } }; static RTL_CRITICAL_SECTION PROFILE_CritSect = { &critsect_debug, -1, 0, 0, 0, 0 }; diff --git a/dll/win32/kernel32/winnls/string/japanese.c b/dll/win32/kernel32/winnls/string/japanese.c index ff2495e21d692..312de71ea44d5 100644 --- a/dll/win32/kernel32/winnls/string/japanese.c +++ b/dll/win32/kernel32/winnls/string/japanese.c @@ -105,7 +105,7 @@ BOOL JapaneseEra_IsFirstYearGannen(void) /* * SEE ALSO: * https://en.wikipedia.org/wiki/Japanese_era_name - * https://docs.microsoft.com/en-us/windows/desktop/Intl/era-handling-for-the-japanese-calendar + * https://learn.microsoft.com/en-us/windows/win32/intl/era-handling-for-the-japanese-calendar */ static PCJAPANESE_ERA JapaneseEra_Load(DWORD *pdwCount) { diff --git a/dll/win32/kernel32/winnls/string/lcformat.c b/dll/win32/kernel32/winnls/string/lcformat.c index 5761035109fbd..25a5e4e325906 100644 --- a/dll/win32/kernel32/winnls/string/lcformat.c +++ b/dll/win32/kernel32/winnls/string/lcformat.c @@ -126,11 +126,7 @@ static CRITICAL_SECTION_DEBUG NLS_FormatsCS_debug = 0, 0, &NLS_FormatsCS, { &NLS_FormatsCS_debug.ProcessLocksList, &NLS_FormatsCS_debug.ProcessLocksList }, -#ifdef __REACTOS__ - 0, 0, 0 -#else 0, 0, { (DWORD_PTR)(__FILE__ ": NLS_Formats") } -#endif }; static CRITICAL_SECTION NLS_FormatsCS = { &NLS_FormatsCS_debug, -1, 0, 0, 0, 0 }; diff --git a/dll/win32/loadperf/CMakeLists.txt b/dll/win32/loadperf/CMakeLists.txt index 770b188ee9629..ac7ed123c9184 100644 --- a/dll/win32/loadperf/CMakeLists.txt +++ b/dll/win32/loadperf/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(loadperf.dll loadperf.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -13,3 +11,4 @@ set_module_type(loadperf win32dll) target_link_libraries(loadperf wine) add_importlibs(loadperf msvcrt kernel32 ntdll) add_cd_file(TARGET loadperf DESTINATION reactos/system32 FOR all) +set_wine_module(loadperf) diff --git a/dll/win32/loadperf/loadperf_main.c b/dll/win32/loadperf/loadperf_main.c index 54901a739af30..8172ec2dc630e 100644 --- a/dll/win32/loadperf/loadperf_main.c +++ b/dll/win32/loadperf/loadperf_main.c @@ -37,8 +37,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) switch(fdwReason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hinstDLL); break; diff --git a/dll/win32/lsasrv/authport.c b/dll/win32/lsasrv/authport.c index e8140c0930f1b..f15faecbde18c 100644 --- a/dll/win32/lsasrv/authport.c +++ b/dll/win32/lsasrv/authport.c @@ -135,10 +135,24 @@ LsapCheckLogonProcess(PLSA_API_MSG RequestMsg, TRACE("New LogonContext: %p\n", Context); Context->ClientProcessHandle = ProcessHandle; - Context->TrustedCaller = RequestMsg->ConnectInfo.TrustedCaller; - if (Context->TrustedCaller) - Context->TrustedCaller = LsapIsTrustedClient(ProcessHandle); + switch (RequestMsg->ConnectInfo.TrustedCaller) + { + case NO: + Context->TrustedCaller = FALSE; + break; + + case YES: + Context->TrustedCaller = TRUE; + break; + + case CHECK: + default: + Context->TrustedCaller = LsapIsTrustedClient(ProcessHandle); + break; + } + + TRACE("TrustedCaller: %u\n", Context->TrustedCaller); *LogonContext = Context; diff --git a/dll/win32/lz32/CMakeLists.txt b/dll/win32/lz32/CMakeLists.txt index cbad018bf8e95..d1bf8835eb530 100644 --- a/dll/win32/lz32/CMakeLists.txt +++ b/dll/win32/lz32/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(lz32.dll lz32.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -13,3 +11,4 @@ target_link_libraries(lz32 wine) add_importlibs(lz32 kernel32 ntdll) add_dependencies(lz32 psdk) add_cd_file(TARGET lz32 DESTINATION reactos/system32 FOR all) +set_wine_module(lz32) diff --git a/dll/win32/mapi32/lang/Es.rc b/dll/win32/mapi32/lang/Es.rc index 22af69c063669..3c9ac28a994e5 100644 --- a/dll/win32/mapi32/lang/Es.rc +++ b/dll/win32/mapi32/lang/Es.rc @@ -19,9 +19,6 @@ * */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/mapi32/lang/Fr.rc b/dll/win32/mapi32/lang/Fr.rc index e7a9296f3bd3c..5d9e7f4d25eda 100644 --- a/dll/win32/mapi32/lang/Fr.rc +++ b/dll/win32/mapi32/lang/Fr.rc @@ -19,9 +19,6 @@ * */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/mapi32/lang/Hu.rc b/dll/win32/mapi32/lang/Hu.rc index e275b269678ae..666f3fbfbfef8 100644 --- a/dll/win32/mapi32/lang/Hu.rc +++ b/dll/win32/mapi32/lang/Hu.rc @@ -19,9 +19,6 @@ * */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/mapi32/lang/It.rc b/dll/win32/mapi32/lang/It.rc index 0c74648b27218..f97240b08fd8a 100644 --- a/dll/win32/mapi32/lang/It.rc +++ b/dll/win32/mapi32/lang/It.rc @@ -20,9 +20,6 @@ * */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/mapi32/lang/Ja.rc b/dll/win32/mapi32/lang/Ja.rc index cd3fc55287bb1..fa686e1c1110c 100644 --- a/dll/win32/mapi32/lang/Ja.rc +++ b/dll/win32/mapi32/lang/Ja.rc @@ -20,9 +20,6 @@ * */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/mapi32/lang/Ko.rc b/dll/win32/mapi32/lang/Ko.rc index e9796bf5a7997..3ca3cc3ab4568 100644 --- a/dll/win32/mapi32/lang/Ko.rc +++ b/dll/win32/mapi32/lang/Ko.rc @@ -20,9 +20,6 @@ * */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/mapi32/lang/Lt.rc b/dll/win32/mapi32/lang/Lt.rc index 63b6e83a2f29c..d1ebadd8b58cc 100644 --- a/dll/win32/mapi32/lang/Lt.rc +++ b/dll/win32/mapi32/lang/Lt.rc @@ -19,9 +19,6 @@ * */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_LITHUANIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/mapi32/lang/Nl.rc b/dll/win32/mapi32/lang/Nl.rc index dda4221920dd6..b20a26ab00be0 100644 --- a/dll/win32/mapi32/lang/Nl.rc +++ b/dll/win32/mapi32/lang/Nl.rc @@ -21,8 +21,6 @@ LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL -#pragma code_page(65001) - STRINGTABLE { IDS_NO_MAPI_CLIENT, "Mail kan niet worden verstuurd aangezien er geen MAPI mail client is geïnstalleerd." diff --git a/dll/win32/mapi32/lang/No.rc b/dll/win32/mapi32/lang/No.rc index 63f64bd34da23..4717564d45420 100644 --- a/dll/win32/mapi32/lang/No.rc +++ b/dll/win32/mapi32/lang/No.rc @@ -19,8 +19,6 @@ * */ -#pragma code_page(65001) - LANGUAGE LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL STRINGTABLE diff --git a/dll/win32/mapi32/lang/Pt.rc b/dll/win32/mapi32/lang/Pt.rc index bc17797d8b241..2fcdc8b8018d2 100644 --- a/dll/win32/mapi32/lang/Pt.rc +++ b/dll/win32/mapi32/lang/Pt.rc @@ -20,8 +20,6 @@ * */ -#pragma code_page(65001) - LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN STRINGTABLE diff --git a/dll/win32/mapi32/lang/Ro.rc b/dll/win32/mapi32/lang/Ro.rc index 56e81fe4cfee3..b440c073f062e 100644 --- a/dll/win32/mapi32/lang/Ro.rc +++ b/dll/win32/mapi32/lang/Ro.rc @@ -20,8 +20,6 @@ LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL -#pragma code_page(65001) - STRINGTABLE { IDS_NO_MAPI_CLIENT, "Eroare la trimiterea emailului. Nu aveți un client de email MAPI instalat." diff --git a/dll/win32/mapi32/lang/Ru.rc b/dll/win32/mapi32/lang/Ru.rc index b4448fb1ad44b..0675b5c41dccf 100644 --- a/dll/win32/mapi32/lang/Ru.rc +++ b/dll/win32/mapi32/lang/Ru.rc @@ -19,9 +19,6 @@ * */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/mapi32/lang/Si.rc b/dll/win32/mapi32/lang/Si.rc index 519958f1effdf..110d47afc16ee 100644 --- a/dll/win32/mapi32/lang/Si.rc +++ b/dll/win32/mapi32/lang/Si.rc @@ -19,8 +19,6 @@ * */ -#pragma code_page(65001) - LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/mapi32/lang/Uk.rc b/dll/win32/mapi32/lang/Uk.rc index fa1a9edc4344f..5dcf7724b3c3f 100644 --- a/dll/win32/mapi32/lang/Uk.rc +++ b/dll/win32/mapi32/lang/Uk.rc @@ -20,9 +20,6 @@ * */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/mapi32/lang/Zh.rc b/dll/win32/mapi32/lang/Zh.rc index 96a63d8dcb116..14a1b7a5de6e5 100644 --- a/dll/win32/mapi32/lang/Zh.rc +++ b/dll/win32/mapi32/lang/Zh.rc @@ -21,9 +21,6 @@ * Copyright 2021 Chan Chilung */ -/* Chinese text is encoded in UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED STRINGTABLE diff --git a/dll/win32/mapi32/version.rc b/dll/win32/mapi32/version.rc index 61b67d3b5750f..65818f28efbe4 100644 --- a/dll/win32/mapi32/version.rc +++ b/dll/win32/mapi32/version.rc @@ -27,7 +27,6 @@ #include "wine/wine_common_ver.rc" - /* UTF-8 */ #pragma code_page(65001) diff --git a/dll/win32/mciavi32/CMakeLists.txt b/dll/win32/mciavi32/CMakeLists.txt index 3f49fc1175428..ea184ef078ce1 100644 --- a/dll/win32/mciavi32/CMakeLists.txt +++ b/dll/win32/mciavi32/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(mciavi32.dll mciavi32.spec) list(APPEND SOURCE @@ -20,3 +18,4 @@ target_link_libraries(mciavi32 wine) add_importlibs(mciavi32 msvfw32 winmm user32 gdi32 msvcrt kernel32 ntdll) add_pch(mciavi32 precomp.h SOURCE) add_cd_file(TARGET mciavi32 DESTINATION reactos/system32 FOR all) +set_wine_module(mciavi32) diff --git a/dll/win32/mciqtz32/CMakeLists.txt b/dll/win32/mciqtz32/CMakeLists.txt index d47f5089ecca9..f992378446979 100644 --- a/dll/win32/mciqtz32/CMakeLists.txt +++ b/dll/win32/mciqtz32/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(mciqtz32.dll mciqtz32.spec) list(APPEND SOURCE @@ -13,3 +11,4 @@ target_link_libraries(mciqtz32 wine strmiids) add_importlibs(mciqtz32 winmm ole32 user32 gdi32 msvcrt kernel32 ntdll) add_dependencies(mciqtz32 dxsdk) add_cd_file(TARGET mciqtz32 DESTINATION reactos/system32 FOR all) +set_wine_module(mciqtz32) diff --git a/dll/win32/mciseq/CMakeLists.txt b/dll/win32/mciseq/CMakeLists.txt index 6d0091f5e2d9d..d5b8aa66274b7 100644 --- a/dll/win32/mciseq/CMakeLists.txt +++ b/dll/win32/mciseq/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(mciseq.dll mciseq.spec) list(APPEND SOURCE @@ -12,6 +10,7 @@ set_module_type(mciseq win32dll) target_link_libraries(mciseq wine) add_importlibs(mciseq winmm user32 msvcrt kernel32 ntdll) add_cd_file(TARGET mciseq DESTINATION reactos/system32 FOR all) +set_wine_module(mciseq) if(MSVC) # Disable warning C4305: '=': truncation from 'UINT' to 'WORD' diff --git a/dll/win32/mciwave/CMakeLists.txt b/dll/win32/mciwave/CMakeLists.txt index 37f44ea86bdd1..cedd7909f2111 100644 --- a/dll/win32/mciwave/CMakeLists.txt +++ b/dll/win32/mciwave/CMakeLists.txt @@ -1,9 +1,7 @@ add_definitions( - -D__WINESRC__ -D_WINE) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(mciwave.dll mciwave.spec) list(APPEND SOURCE @@ -15,6 +13,7 @@ set_module_type(mciwave win32dll) target_link_libraries(mciwave wine) add_importlibs(mciwave user32 winmm msvcrt kernel32 ntdll) add_cd_file(TARGET mciwave DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(mciwave) # CORE-5743: No ARRAY_SIZE macro if(MSVC) # Disable warning C4305: '=': truncation from 'UINT' to 'WORD' diff --git a/dll/win32/mgmtapi/CMakeLists.txt b/dll/win32/mgmtapi/CMakeLists.txt index c2d5ce1118171..f112be0da67a0 100644 --- a/dll/win32/mgmtapi/CMakeLists.txt +++ b/dll/win32/mgmtapi/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(mgmtapi.dll mgmtapi.spec) list(APPEND SOURCE @@ -13,3 +11,4 @@ set_module_type(mgmtapi win32dll) target_link_libraries(mgmtapi wine) add_importlibs(mgmtapi msvcrt kernel32 ntdll) add_cd_file(TARGET mgmtapi DESTINATION reactos/system32 FOR all) +set_wine_module(mgmtapi) diff --git a/dll/win32/mgmtapi/mgmtapi.c b/dll/win32/mgmtapi/mgmtapi.c index 06c540a527eb6..5fc90fa51dd75 100644 --- a/dll/win32/mgmtapi/mgmtapi.c +++ b/dll/win32/mgmtapi/mgmtapi.c @@ -29,8 +29,10 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved ) switch (reason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls( hinst ); break; diff --git a/dll/win32/mlang/CMakeLists.txt b/dll/win32/mlang/CMakeLists.txt index 806d7d7b3c94c..451d1b5ed338b 100644 --- a/dll/win32/mlang/CMakeLists.txt +++ b/dll/win32/mlang/CMakeLists.txt @@ -1,9 +1,7 @@ add_definitions( - -D__WINESRC__ -DCOM_NO_WINDOWS_H) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(mlang.dll mlang.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -17,3 +15,4 @@ target_link_libraries(mlang uuid wine oldnames) add_delay_importlibs(mlang oleaut32) add_importlibs(mlang gdi32 advapi32 msvcrt kernel32 ntdll) add_cd_file(TARGET mlang DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(mlang) # CORE-5743: No ARRAY_SIZE and CONST_VTABLE diff --git a/dll/win32/mmdevapi/CMakeLists.txt b/dll/win32/mmdevapi/CMakeLists.txt index 1cda15a8c5f75..bbf246b9801bc 100644 --- a/dll/win32/mmdevapi/CMakeLists.txt +++ b/dll/win32/mmdevapi/CMakeLists.txt @@ -2,8 +2,6 @@ remove_definitions(-D_WIN32_WINNT=0x502) add_definitions(-D_WIN32_WINNT=0x600) -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(mmdevapi.dll mmdevapi.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -25,3 +23,4 @@ add_importlibs(mmdevapi ole32 oleaut32 user32 advapi32 msvcrt kernel32 ntdll) add_pch(mmdevapi precomp.h SOURCE) add_dependencies(mmdevapi dxsdk) add_cd_file(TARGET mmdevapi DESTINATION reactos/system32 FOR all) +set_wine_module(mmdevapi) diff --git a/dll/win32/mpr/CMakeLists.txt b/dll/win32/mpr/CMakeLists.txt index af182ae04215b..b0b435f500038 100644 --- a/dll/win32/mpr/CMakeLists.txt +++ b/dll/win32/mpr/CMakeLists.txt @@ -1,9 +1,7 @@ add_definitions( - -D__WINESRC__ -D_WINE) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(mpr.dll mpr.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -26,3 +24,4 @@ target_link_libraries(mpr wine) add_importlibs(mpr advapi32 user32 msvcrt kernel32 ntdll) add_pch(mpr precomp.h SOURCE) add_cd_file(TARGET mpr DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(mpr) # CORE-5743: No ARRAY_SIZE macro diff --git a/dll/win32/mpr/lang/mpr_De.rc b/dll/win32/mpr/lang/mpr_De.rc index 93c2cf23ad083..14bac1864c149 100644 --- a/dll/win32/mpr/lang/mpr_De.rc +++ b/dll/win32/mpr/lang/mpr_De.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/mpr/lang/mpr_Fr.rc b/dll/win32/mpr/lang/mpr_Fr.rc index 539005a5413f1..45fb14844e02b 100644 --- a/dll/win32/mpr/lang/mpr_Fr.rc +++ b/dll/win32/mpr/lang/mpr_Fr.rc @@ -19,9 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/mpr/lang/mpr_Ja.rc b/dll/win32/mpr/lang/mpr_Ja.rc index a9c5c2e3c6ed3..20f11234e3435 100644 --- a/dll/win32/mpr/lang/mpr_Ja.rc +++ b/dll/win32/mpr/lang/mpr_Ja.rc @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/mpr/lang/mpr_Lt.rc b/dll/win32/mpr/lang/mpr_Lt.rc index 90e9e0a819382..f0e2c62043d5e 100644 --- a/dll/win32/mpr/lang/mpr_Lt.rc +++ b/dll/win32/mpr/lang/mpr_Lt.rc @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_LITHUANIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/mpr/lang/mpr_Pt.rc b/dll/win32/mpr/lang/mpr_Pt.rc index 477b94304b387..234891752770b 100644 --- a/dll/win32/mpr/lang/mpr_Pt.rc +++ b/dll/win32/mpr/lang/mpr_Pt.rc @@ -19,8 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_PORTUGUESE, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/mpr/lang/mpr_Ro.rc b/dll/win32/mpr/lang/mpr_Ro.rc index 0ff5ef7eef35d..399c7ca8f7f9c 100644 --- a/dll/win32/mpr/lang/mpr_Ro.rc +++ b/dll/win32/mpr/lang/mpr_Ro.rc @@ -21,8 +21,6 @@ LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL -#pragma code_page(65001) - STRINGTABLE { IDS_ENTIRENETWORK "Toată rețeaua" diff --git a/dll/win32/mpr/lang/mpr_Ru.rc b/dll/win32/mpr/lang/mpr_Ru.rc index 8b519fc6bbb42..89a7901eec3d5 100644 --- a/dll/win32/mpr/lang/mpr_Ru.rc +++ b/dll/win32/mpr/lang/mpr_Ru.rc @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/mpr/lang/mpr_Si.rc b/dll/win32/mpr/lang/mpr_Si.rc index 8cae253b72d31..1367f6f1a10a7 100644 --- a/dll/win32/mpr/lang/mpr_Si.rc +++ b/dll/win32/mpr/lang/mpr_Si.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/mpr/lang/mpr_Uk.rc b/dll/win32/mpr/lang/mpr_Uk.rc index 73f731b02578c..254bb9775a1ac 100644 --- a/dll/win32/mpr/lang/mpr_Uk.rc +++ b/dll/win32/mpr/lang/mpr_Uk.rc @@ -19,9 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/mpr/lang/mpr_Zh.rc b/dll/win32/mpr/lang/mpr_Zh.rc index 301cfc385c8f3..00b507f6075be 100644 --- a/dll/win32/mpr/lang/mpr_Zh.rc +++ b/dll/win32/mpr/lang/mpr_Zh.rc @@ -21,9 +21,6 @@ * Copyright 2021 Chan Chilung */ -/* Chinese text is encoded in UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED STRINGTABLE diff --git a/dll/win32/mprapi/CMakeLists.txt b/dll/win32/mprapi/CMakeLists.txt index 17a1a1b40429b..c6f940279a605 100644 --- a/dll/win32/mprapi/CMakeLists.txt +++ b/dll/win32/mprapi/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(mprapi.dll mprapi.spec) list(APPEND SOURCE @@ -13,3 +11,4 @@ set_module_type(mprapi win32dll) target_link_libraries(mprapi wine) add_importlibs(mprapi msvcrt kernel32 ntdll) add_cd_file(TARGET mprapi DESTINATION reactos/system32 FOR all) +set_wine_module(mprapi) diff --git a/dll/win32/mprapi/mprapi.c b/dll/win32/mprapi/mprapi.c index 715f1b8cadaa4..248e9bec540d0 100644 --- a/dll/win32/mprapi/mprapi.c +++ b/dll/win32/mprapi/mprapi.c @@ -34,8 +34,10 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) switch(reason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls( hinst ); diff --git a/dll/win32/msacm32/CMakeLists.txt b/dll/win32/msacm32/CMakeLists.txt index ecc5abd5d640b..dda93b14d2096 100644 --- a/dll/win32/msacm32/CMakeLists.txt +++ b/dll/win32/msacm32/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(msacm32.dll msacm32.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -24,3 +22,4 @@ target_link_libraries(msacm32 wine oldnames) add_importlibs(msacm32 advapi32 user32 winmm msvcrt kernel32 ntdll) add_pch(msacm32 precomp.h SOURCE) add_cd_file(TARGET msacm32 DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(msacm32) # CORE-5743: No ARRAY_SIZE macro diff --git a/dll/win32/msacm32/lang/msacm_De.rc b/dll/win32/msacm32/lang/msacm_De.rc index 2867b475a2d57..27800552852d5 100644 --- a/dll/win32/msacm32/lang/msacm_De.rc +++ b/dll/win32/msacm32/lang/msacm_De.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL DLG_ACMFORMATCHOOSE_ID DIALOGEX 10, 20, 225, 118 diff --git a/dll/win32/msacm32/lang/msacm_Fr.rc b/dll/win32/msacm32/lang/msacm_Fr.rc index 8a243331f5504..4221f532664cf 100644 --- a/dll/win32/msacm32/lang/msacm_Fr.rc +++ b/dll/win32/msacm32/lang/msacm_Fr.rc @@ -20,9 +20,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL DLG_ACMFORMATCHOOSE_ID DIALOGEX 10, 20, 225, 118 diff --git a/dll/win32/msacm32/lang/msacm_He.rc b/dll/win32/msacm32/lang/msacm_He.rc index cde2c4696613a..bc56636e75cc3 100644 --- a/dll/win32/msacm32/lang/msacm_He.rc +++ b/dll/win32/msacm32/lang/msacm_He.rc @@ -20,9 +20,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_HEBREW, SUBLANG_DEFAULT DLG_ACMFORMATCHOOSE_ID DIALOGEX 10, 20, 225, 118 diff --git a/dll/win32/msacm32/lang/msacm_Ja.rc b/dll/win32/msacm32/lang/msacm_Ja.rc index ba727854e1bcc..26232d27cb1b1 100644 --- a/dll/win32/msacm32/lang/msacm_Ja.rc +++ b/dll/win32/msacm32/lang/msacm_Ja.rc @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT DLG_ACMFORMATCHOOSE_ID DIALOGEX 10, 20, 225, 118 diff --git a/dll/win32/msacm32/lang/msacm_Lt.rc b/dll/win32/msacm32/lang/msacm_Lt.rc index 36fc328ce6bbf..76e04e37d266f 100644 --- a/dll/win32/msacm32/lang/msacm_Lt.rc +++ b/dll/win32/msacm32/lang/msacm_Lt.rc @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_LITHUANIAN, SUBLANG_NEUTRAL DLG_ACMFORMATCHOOSE_ID DIALOGEX 10, 20, 225, 118 diff --git a/dll/win32/msacm32/lang/msacm_Pt.rc b/dll/win32/msacm32/lang/msacm_Pt.rc index 109847c2a832b..57971d63709c4 100644 --- a/dll/win32/msacm32/lang/msacm_Pt.rc +++ b/dll/win32/msacm32/lang/msacm_Pt.rc @@ -20,8 +20,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN DLG_ACMFORMATCHOOSE_ID DIALOGEX 10, 20, 225, 118 diff --git a/dll/win32/msacm32/lang/msacm_Ro.rc b/dll/win32/msacm32/lang/msacm_Ro.rc index 9cf54e8105429..d3ece4320a610 100644 --- a/dll/win32/msacm32/lang/msacm_Ro.rc +++ b/dll/win32/msacm32/lang/msacm_Ro.rc @@ -21,8 +21,6 @@ LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL -#pragma code_page(65001) - DLG_ACMFORMATCHOOSE_ID DIALOGEX 10, 20, 225, 118 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Selectare sunet" diff --git a/dll/win32/msacm32/lang/msacm_Ru.rc b/dll/win32/msacm32/lang/msacm_Ru.rc index a4f0e6425ac1c..7192847f8582b 100644 --- a/dll/win32/msacm32/lang/msacm_Ru.rc +++ b/dll/win32/msacm32/lang/msacm_Ru.rc @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT DLG_ACMFORMATCHOOSE_ID DIALOGEX 10, 20, 225, 118 diff --git a/dll/win32/msacm32/lang/msacm_Si.rc b/dll/win32/msacm32/lang/msacm_Si.rc index 376520aac6a58..28c7e0d2322fe 100644 --- a/dll/win32/msacm32/lang/msacm_Si.rc +++ b/dll/win32/msacm32/lang/msacm_Si.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT DLG_ACMFORMATCHOOSE_ID DIALOGEX 10, 20, 225, 118 diff --git a/dll/win32/msacm32/lang/msacm_Uk.rc b/dll/win32/msacm32/lang/msacm_Uk.rc index 5c652a75bff7e..ca4c2115f7769 100644 --- a/dll/win32/msacm32/lang/msacm_Uk.rc +++ b/dll/win32/msacm32/lang/msacm_Uk.rc @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT DLG_ACMFORMATCHOOSE_ID DIALOGEX 10, 20, 225, 118 diff --git a/dll/win32/msacm32/lang/msacm_Zh.rc b/dll/win32/msacm32/lang/msacm_Zh.rc index 2ef255ce78bc0..32868f8986a79 100644 --- a/dll/win32/msacm32/lang/msacm_Zh.rc +++ b/dll/win32/msacm32/lang/msacm_Zh.rc @@ -21,9 +21,6 @@ * Copyright 2021 Chan Chilung */ -/* Chinese text is encoded in UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED DLG_ACMFORMATCHOOSE_ID DIALOGEX 10, 20, 225, 118 diff --git a/dll/win32/msacm32/msacm.rc b/dll/win32/msacm32/msacm.rc index f72be33cacaa5..0a27f54ac8da3 100644 --- a/dll/win32/msacm32/msacm.rc +++ b/dll/win32/msacm32/msacm.rc @@ -20,7 +20,6 @@ #include "wineacm.h" - #include /* UTF-8 */ diff --git a/dll/win32/msadp32.acm/CMakeLists.txt b/dll/win32/msadp32.acm/CMakeLists.txt index f784c6c60df74..b8f4897ed0d35 100644 --- a/dll/win32/msadp32.acm/CMakeLists.txt +++ b/dll/win32/msadp32.acm/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(msadp32.acm msadp32.acm.spec) list(APPEND SOURCE @@ -13,3 +11,4 @@ set_target_properties(msadp32.acm PROPERTIES SUFFIX "") target_link_libraries(msadp32.acm wine) add_importlibs(msadp32.acm winmm user32 msvcrt kernel32 ntdll) add_cd_file(TARGET msadp32.acm DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(msadp32.acm) # CORE-5743: No ARRAY_SIZE macro diff --git a/dll/win32/mscat32/CMakeLists.txt b/dll/win32/mscat32/CMakeLists.txt index 94788acc589e4..fab403a6fb0b4 100644 --- a/dll/win32/mscat32/CMakeLists.txt +++ b/dll/win32/mscat32/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(mscat32.dll mscat32.spec) list(APPEND SOURCE @@ -12,3 +10,4 @@ set_module_type(mscat32 win32dll) target_link_libraries(mscat32 wine) add_importlibs(mscat32 wintrust msvcrt kernel32 ntdll) add_cd_file(TARGET mscat32 DESTINATION reactos/system32 FOR all) +set_wine_module(mscat32) diff --git a/dll/win32/mscat32/main.c b/dll/win32/mscat32/main.c index 8408070282c58..6009a29a1d373 100644 --- a/dll/win32/mscat32/main.c +++ b/dll/win32/mscat32/main.c @@ -29,7 +29,9 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { TRACE("(%p, %d, %p)\n",hinstDLL,fdwReason,lpvReserved); +#ifndef __REACTOS__ if (fdwReason == DLL_WINE_PREATTACH) return FALSE; /* prefer native version */ +#endif if (fdwReason == DLL_PROCESS_ATTACH) { diff --git a/dll/win32/mscms/CMakeLists.txt b/dll/win32/mscms/CMakeLists.txt index 785e1e425d30d..0c5efd078309e 100644 --- a/dll/win32/mscms/CMakeLists.txt +++ b/dll/win32/mscms/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(mscms.dll mscms.spec) list(APPEND SOURCE @@ -18,3 +16,4 @@ set_module_type(mscms win32dll) target_link_libraries(mscms wine) add_importlibs(mscms advapi32 msvcrt kernel32 ntdll) add_cd_file(TARGET mscms DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(mscms) # CORE-5743: No ARRAY_SIZE macro diff --git a/dll/win32/mscoree/CMakeLists.txt b/dll/win32/mscoree/CMakeLists.txt index 2671d7a79e331..090fa4876c1da 100644 --- a/dll/win32/mscoree/CMakeLists.txt +++ b/dll/win32/mscoree/CMakeLists.txt @@ -2,8 +2,6 @@ remove_definitions(-D_WIN32_WINNT=0x502) add_definitions(-D_WIN32_WINNT=0x600) -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(mscoree.dll mscoree.spec) list(APPEND SOURCE @@ -30,3 +28,4 @@ target_link_libraries(mscoree uuid wine) add_importlibs(mscoree dbghelp advapi32 shell32 ole32 shlwapi msvcrt kernel32 ntdll) add_pch(mscoree mscoree_private.h "${PCH_SKIP_SOURCE}") add_cd_file(TARGET mscoree DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(mscoree) # CORE-5743: No CONST_VTABLE diff --git a/dll/win32/mscoree/mscoree_main.c b/dll/win32/mscoree/mscoree_main.c index 2af851806cfaf..e3507c4d27501 100644 --- a/dll/win32/mscoree/mscoree_main.c +++ b/dll/win32/mscoree/mscoree_main.c @@ -197,8 +197,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) switch (fdwReason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: runtimehost_init(); DisableThreadLibraryCalls(hinstDLL); diff --git a/dll/win32/msctf/CMakeLists.txt b/dll/win32/msctf/CMakeLists.txt index 896fc3cc94351..5c6f3b8b0890b 100644 --- a/dll/win32/msctf/CMakeLists.txt +++ b/dll/win32/msctf/CMakeLists.txt @@ -2,8 +2,6 @@ remove_definitions(-D_WIN32_WINNT=0x502) add_definitions(-D_WIN32_WINNT=0x600) -add_definitions(-D__WINESRC__) -include_directories(BEFORE ${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(msctf.dll msctf.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -36,3 +34,4 @@ add_importlibs(msctf user32 advapi32 advapi32_vista msvcrt kernel32 ntdll) add_delay_importlibs(msctf shell32 shlwapi ole32 oleaut32 imm32 gdi32) add_pch(msctf precomp.h SOURCE) add_cd_file(TARGET msctf DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(msctf) # CORE-5743: No CONST_VTABLE diff --git a/dll/win32/msctf/msctf.c b/dll/win32/msctf/msctf.c index a20d0fd55b657..ff166716ccf54 100644 --- a/dll/win32/msctf/msctf.c +++ b/dll/win32/msctf/msctf.c @@ -556,8 +556,10 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD fdwReason, LPVOID fImpLoad) TRACE("%p 0x%x %p\n", hinst, fdwReason, fImpLoad); switch (fdwReason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: MSCTF_hinstance = hinst; tlsIndex = TlsAlloc(); diff --git a/dll/win32/msftedit/CMakeLists.txt b/dll/win32/msftedit/CMakeLists.txt index 8fba4ccd089a5..e59d71551cde7 100644 --- a/dll/win32/msftedit/CMakeLists.txt +++ b/dll/win32/msftedit/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(msftedit.dll msftedit.spec) list(APPEND SOURCE @@ -14,3 +12,4 @@ set_module_type(msftedit win32dll) target_link_libraries(msftedit uuid wine) add_importlibs(msftedit riched20 msvcrt kernel32 ntdll) add_cd_file(TARGET msftedit DESTINATION reactos/system32 FOR all) +set_wine_module(msftedit) diff --git a/dll/win32/msftedit/msftedit_main.c b/dll/win32/msftedit/msftedit_main.c index c578efafda3dc..112aae456049c 100644 --- a/dll/win32/msftedit/msftedit_main.c +++ b/dll/win32/msftedit/msftedit_main.c @@ -47,8 +47,10 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved) switch(reason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: /* explicitly load riched20 since it creates the window classes at dll attach time */ richedit = LoadLibraryW( riched20W ); diff --git a/dll/win32/msg711.acm/CMakeLists.txt b/dll/win32/msg711.acm/CMakeLists.txt index 3dc5c79492e0d..d85ea1b7b0538 100644 --- a/dll/win32/msg711.acm/CMakeLists.txt +++ b/dll/win32/msg711.acm/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(msg711.acm msg711.acm.spec) list(APPEND SOURCE @@ -13,3 +11,4 @@ set_target_properties(msg711.acm PROPERTIES SUFFIX "") target_link_libraries(msg711.acm wine) add_importlibs(msg711.acm winmm user32 msvcrt kernel32 ntdll) add_cd_file(TARGET msg711.acm DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(msg711.acm) # CORE-5743: No ARRAY_SIZE macro diff --git a/dll/win32/msgina/resources/reactos.bmp b/dll/win32/msgina/resources/reactos.bmp index 2ec7eeb1772f6..ef1fc5765c858 100644 Binary files a/dll/win32/msgina/resources/reactos.bmp and b/dll/win32/msgina/resources/reactos.bmp differ diff --git a/dll/win32/msgina/resources/svg/reactos.svg b/dll/win32/msgina/resources/svg/reactos.svg index 3daa8299cd4a4..5c9d24de58650 100644 --- a/dll/win32/msgina/resources/svg/reactos.svg +++ b/dll/win32/msgina/resources/svg/reactos.svg @@ -1928,7 +1928,7 @@ x="5.59375" y="1047.7255" style="font-size:8px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#1e2122;fill-opacity:1;font-family:Lucida Sans Unicode;-inkscape-font-specification:Lucida Sans Unicode" - id="tspan3618">Copyright © 1996-2024 ReactOS Team & Contributors + id="tspan3618">Copyright © 1996-2025 ReactOS Team & Contributors diff --git a/dll/win32/msgsm32.acm/CMakeLists.txt b/dll/win32/msgsm32.acm/CMakeLists.txt index 5a0238ceef46d..4fc294a99bb31 100644 --- a/dll/win32/msgsm32.acm/CMakeLists.txt +++ b/dll/win32/msgsm32.acm/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(msgsm32.acm msgsm32.acm.spec) list(APPEND SOURCE @@ -13,3 +11,4 @@ set_target_properties(msgsm32.acm PROPERTIES SUFFIX "") target_link_libraries(msgsm32.acm wine) add_importlibs(msgsm32.acm winmm user32 msvcrt kernel32 ntdll) add_cd_file(TARGET msgsm32.acm DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(msgsm32.acm) # CORE-5743: No ARRAY_SIZE macro diff --git a/dll/win32/mshtml.tlb/CMakeLists.txt b/dll/win32/mshtml.tlb/CMakeLists.txt index c795544636dc9..03650c6190f48 100644 --- a/dll/win32/mshtml.tlb/CMakeLists.txt +++ b/dll/win32/mshtml.tlb/CMakeLists.txt @@ -1,7 +1,5 @@ add_typelib(mshtml_tlb.idl) -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) add_library(mshtml.tlb MODULE rsrc.rc) list(APPEND mshtml_tlb_rc_deps @@ -13,3 +11,4 @@ set_module_type(mshtml.tlb module) set_target_properties(mshtml.tlb PROPERTIES SUFFIX "") add_dependencies(mshtml.tlb stdole2) add_cd_file(TARGET mshtml.tlb DESTINATION reactos/system32 FOR all) +set_wine_module(mshtml.tlb) diff --git a/dll/win32/mshtml/CMakeLists.txt b/dll/win32/mshtml/CMakeLists.txt index d7c767f26f02b..7af590cb30605 100644 --- a/dll/win32/mshtml/CMakeLists.txt +++ b/dll/win32/mshtml/CMakeLists.txt @@ -3,14 +3,12 @@ remove_definitions(-D_WIN32_WINNT=0x502) add_definitions(-D_WIN32_WINNT=0x600) add_definitions( - -D__WINESRC__ -D__ROS_LONG64__ -DCOM_NO_WINDOWS_H -Dstrcasecmp=_stricmp -Dstrncasecmp=_strnicmp ) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) add_idl_headers(mshtml_nsiface_header nsiface.idl) spec2def(mshtml.dll mshtml.spec ADD_IMPORTLIB) @@ -116,3 +114,4 @@ add_importlibs(mshtml urlmon shlwapi shell32 ole32 oleaut32 user32 gdi32 advapi3 add_dependencies(mshtml mshtml_nsiface_header) add_pch(mshtml mshtml_private.h "${PCH_SKIP_SOURCE}") add_cd_file(TARGET mshtml DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(mshtml) # CORE-5743: No CONST_VTABLE diff --git a/dll/win32/mshtml/lang/Da.rc b/dll/win32/mshtml/lang/Da.rc index 93d8abc5ec794..47b9f3e3cd501 100644 --- a/dll/win32/mshtml/lang/Da.rc +++ b/dll/win32/mshtml/lang/Da.rc @@ -19,8 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_DANISH, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/mshtml/lang/De.rc b/dll/win32/mshtml/lang/De.rc index f536587986998..415e82d7ab011 100644 --- a/dll/win32/mshtml/lang/De.rc +++ b/dll/win32/mshtml/lang/De.rc @@ -20,8 +20,6 @@ LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL -#pragma code_page(65001) - STRINGTABLE { IDS_STATUS_DONE "Fertig" diff --git a/dll/win32/mshtml/lang/Fr.rc b/dll/win32/mshtml/lang/Fr.rc index a02abf42d42ae..77b0274f82e8d 100644 --- a/dll/win32/mshtml/lang/Fr.rc +++ b/dll/win32/mshtml/lang/Fr.rc @@ -20,9 +20,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/mshtml/lang/Hu.rc b/dll/win32/mshtml/lang/Hu.rc index 990738b5c14a4..c94efbb1d68b9 100644 --- a/dll/win32/mshtml/lang/Hu.rc +++ b/dll/win32/mshtml/lang/Hu.rc @@ -16,9 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/mshtml/lang/It.rc b/dll/win32/mshtml/lang/It.rc index 0e2c5a45d255e..a9209e5b24f40 100644 --- a/dll/win32/mshtml/lang/It.rc +++ b/dll/win32/mshtml/lang/It.rc @@ -16,9 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/*UTF-8*/ -#pragma code_page(65001) - LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/mshtml/lang/Ja.rc b/dll/win32/mshtml/lang/Ja.rc index caa4ac33d4049..d9e619469698b 100644 --- a/dll/win32/mshtml/lang/Ja.rc +++ b/dll/win32/mshtml/lang/Ja.rc @@ -16,9 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/mshtml/lang/Lt.rc b/dll/win32/mshtml/lang/Lt.rc index 180b0cdeb36d1..96d8582dffe73 100644 --- a/dll/win32/mshtml/lang/Lt.rc +++ b/dll/win32/mshtml/lang/Lt.rc @@ -16,9 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_LITHUANIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/mshtml/lang/No.rc b/dll/win32/mshtml/lang/No.rc index 0120272270666..b28229b7a1a48 100644 --- a/dll/win32/mshtml/lang/No.rc +++ b/dll/win32/mshtml/lang/No.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL STRINGTABLE diff --git a/dll/win32/mshtml/lang/Pt.rc b/dll/win32/mshtml/lang/Pt.rc index 52c28cd1aee9e..d9b9e2cab9268 100644 --- a/dll/win32/mshtml/lang/Pt.rc +++ b/dll/win32/mshtml/lang/Pt.rc @@ -17,8 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN STRINGTABLE diff --git a/dll/win32/mshtml/lang/Ro.rc b/dll/win32/mshtml/lang/Ro.rc index 44dd4c1148970..181e5b4c78ef5 100644 --- a/dll/win32/mshtml/lang/Ro.rc +++ b/dll/win32/mshtml/lang/Ro.rc @@ -21,8 +21,6 @@ LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL -#pragma code_page(65001) - STRINGTABLE { IDS_STATUS_DONE "Finalizat" diff --git a/dll/win32/mshtml/lang/Ru.rc b/dll/win32/mshtml/lang/Ru.rc index 5f46c69784c75..6ee3b082e8528 100644 --- a/dll/win32/mshtml/lang/Ru.rc +++ b/dll/win32/mshtml/lang/Ru.rc @@ -16,9 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/mshtml/lang/Si.rc b/dll/win32/mshtml/lang/Si.rc index 146503cafec8e..9079745465502 100644 --- a/dll/win32/mshtml/lang/Si.rc +++ b/dll/win32/mshtml/lang/Si.rc @@ -16,8 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/mshtml/lang/Uk.rc b/dll/win32/mshtml/lang/Uk.rc index 3376b10724eee..0ae3acdcd1646 100644 --- a/dll/win32/mshtml/lang/Uk.rc +++ b/dll/win32/mshtml/lang/Uk.rc @@ -17,9 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/mshtml/lang/Zh.rc b/dll/win32/mshtml/lang/Zh.rc index 46e8bebb368d2..5bb65fe989ed6 100644 --- a/dll/win32/mshtml/lang/Zh.rc +++ b/dll/win32/mshtml/lang/Zh.rc @@ -22,9 +22,6 @@ * Copyright 2021 Chan Chilung */ -/* Chinese text is encoded in UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED STRINGTABLE diff --git a/dll/win32/msi/custom.c b/dll/win32/msi/custom.c index 6e660233444ae..56e5b6cad0f95 100644 --- a/dll/win32/msi/custom.c +++ b/dll/win32/msi/custom.c @@ -868,17 +868,6 @@ static UINT HANDLE_CustomType1( MSIPACKAGE *package, const WCHAR *source, const if (!(binary = get_temp_binary(package, source))) return ERROR_FUNCTION_FAILED; -#if defined(__REACTOS__) && defined(_M_AMD64) - { - DWORD arch; - get_binary_type(binary->tmpfile, &arch); - if (arch == SCS_32BIT_BINARY) { - ERR("%s is a 32 bit custom action. Returning as ERROR_SUCCESS\n", debugstr_w(source)); - return ERROR_SUCCESS; // HACK: NO WOW64! return as executed though it's not true - } - } -#endif - TRACE("Calling function %s from %s\n", debugstr_w(target), debugstr_w(binary->tmpfile)); if (!(info = do_msidbCustomActionTypeDll( package, type, binary->tmpfile, target, action ))) @@ -987,17 +976,6 @@ static UINT HANDLE_CustomType17( MSIPACKAGE *package, const WCHAR *source, const return ERROR_FUNCTION_FAILED; } -#if defined(__REACTOS__) && defined(_M_AMD64) - { - DWORD arch; - get_binary_type(file->TargetPath, &arch); - if (arch == SCS_32BIT_BINARY) { - ERR("%s is a 32 bit custom action. Returning as ERROR_SUCCESS\n", debugstr_w(source)); - return ERROR_SUCCESS; // HACK: NO WOW64! return as executed though it's not true - } - } -#endif - if (!(info = do_msidbCustomActionTypeDll( package, type, file->TargetPath, target, action ))) return ERROR_FUNCTION_FAILED; return wait_thread_handle( info ); diff --git a/dll/win32/msimg32/CMakeLists.txt b/dll/win32/msimg32/CMakeLists.txt index c55790ef3526e..fe556b98b8952 100644 --- a/dll/win32/msimg32/CMakeLists.txt +++ b/dll/win32/msimg32/CMakeLists.txt @@ -1,6 +1,4 @@ -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) -add_definitions(-D__WINESRC__) spec2def(msimg32.dll msimg32.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -12,3 +10,4 @@ set_module_type(msimg32 win32dll) target_link_libraries(msimg32 wine) add_importlibs(msimg32 gdi32 msvcrt kernel32 ntdll) add_cd_file(TARGET msimg32 DESTINATION reactos/system32 FOR all) +set_wine_module(msimg32) diff --git a/dll/win32/msimtf/CMakeLists.txt b/dll/win32/msimtf/CMakeLists.txt index 567159de0718a..0b3c49ecd3d4b 100644 --- a/dll/win32/msimtf/CMakeLists.txt +++ b/dll/win32/msimtf/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(msimtf.dll msimtf.spec) list(APPEND SOURCE @@ -19,3 +17,4 @@ target_link_libraries(msimtf uuid wine) add_importlibs(msimtf imm32 msvcrt kernel32 ntdll) add_pch(msimtf precomp.h SOURCE) add_cd_file(TARGET msimtf DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(msimtf) # CORE-5743: No CONST_VTABLE diff --git a/dll/win32/msimtf/main.c b/dll/win32/msimtf/main.c index 76ad6548f4ba1..8410c4884db51 100644 --- a/dll/win32/msimtf/main.c +++ b/dll/win32/msimtf/main.c @@ -44,8 +44,10 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) { switch(fdwReason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: msimtf_instance = hInstDLL; DisableThreadLibraryCalls(hInstDLL); diff --git a/dll/win32/msisip/CMakeLists.txt b/dll/win32/msisip/CMakeLists.txt index 3a194e7bc1689..4727864cfacf5 100644 --- a/dll/win32/msisip/CMakeLists.txt +++ b/dll/win32/msisip/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(msisip.dll msisip.spec) list(APPEND SOURCE @@ -13,3 +11,4 @@ set_module_type(msisip win32dll) target_link_libraries(msisip wine) add_importlibs(msisip crypt32 ole32 msvcrt kernel32 ntdll) add_cd_file(TARGET msisip DESTINATION reactos/system32 FOR all) +set_wine_module(msisip) diff --git a/dll/win32/msisip/main.c b/dll/win32/msisip/main.c index aabea78ae6208..4ef12c2c94502 100644 --- a/dll/win32/msisip/main.c +++ b/dll/win32/msisip/main.c @@ -34,8 +34,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) switch (fdwReason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hinstDLL); break; diff --git a/dll/win32/msisys.ocx/CMakeLists.txt b/dll/win32/msisys.ocx/CMakeLists.txt index 0d711a5817d9d..c187df683f878 100644 --- a/dll/win32/msisys.ocx/CMakeLists.txt +++ b/dll/win32/msisys.ocx/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(msisys.ocx msisys.ocx.spec) list(APPEND SOURCE @@ -12,3 +10,4 @@ set_module_type(msisys win32ocx) target_link_libraries(msisys wine) add_importlibs(msisys msvcrt kernel32 ntdll) add_cd_file(TARGET msisys DESTINATION reactos/system32 FOR all) +set_wine_module(msisys) diff --git a/dll/win32/msnet32/CMakeLists.txt b/dll/win32/msnet32/CMakeLists.txt index c8a5c5a2f5c0c..12fb6b7abc70a 100644 --- a/dll/win32/msnet32/CMakeLists.txt +++ b/dll/win32/msnet32/CMakeLists.txt @@ -1,9 +1,8 @@ -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) -add_definitions(-D__WINESRC__) spec2def(msnet32.dll msnet32.spec) add_library(msnet32 MODULE msnet_main.c ${CMAKE_CURRENT_BINARY_DIR}/msnet32.def) set_module_type(msnet32 win32dll) target_link_libraries(msnet32 wine) add_importlibs(msnet32 msvcrt kernel32 ntdll) add_cd_file(TARGET msnet32 DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(msnet32) # CORE-5743 diff --git a/dll/win32/msnet32/msnet_main.c b/dll/win32/msnet32/msnet_main.c index 8303b8f1730a8..6229fd25e8818 100644 --- a/dll/win32/msnet32/msnet_main.c +++ b/dll/win32/msnet32/msnet_main.c @@ -35,8 +35,10 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved ) { switch(reason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls( inst ); break; diff --git a/dll/win32/msports/lang/it-IT.rc b/dll/win32/msports/lang/it-IT.rc index 666a6b8886864..43e693b10d7bb 100644 --- a/dll/win32/msports/lang/it-IT.rc +++ b/dll/win32/msports/lang/it-IT.rc @@ -9,7 +9,7 @@ BEGIN COMBOBOX IDC_SERIAL_BITSPERSECOND, 139, 17, 106, 90, CBS_DROPDOWNLIST | WS_TABSTOP | WS_VSCROLL RTEXT "Bit di &Dati:", -1, 6, 40, 130, 8, WS_GROUP COMBOBOX IDC_SERIAL_DATABITS, 139, 38, 106, 54, CBS_DROPDOWNLIST | WS_TABSTOP | WS_VSCROLL - RTEXT "&Parit:", -1, 6, 61, 130, 8, WS_GROUP + RTEXT "&Parità:", -1, 6, 61, 130, 8, WS_GROUP COMBOBOX IDC_SERIAL_PARITY, 139, 59, 106, 62, CBS_DROPDOWNLIST | WS_TABSTOP | WS_VSCROLL RTEXT "Bit di &Stop:", -1, 6, 82, 130, 8, WS_GROUP COMBOBOX IDC_SERIAL_STOPBITS, 139, 80, 106, 54, CBS_DROPDOWNLIST | WS_TABSTOP | WS_VSCROLL diff --git a/dll/win32/msrle32/CMakeLists.txt b/dll/win32/msrle32/CMakeLists.txt index 85311b2fad5d4..7dadba7b25bd9 100644 --- a/dll/win32/msrle32/CMakeLists.txt +++ b/dll/win32/msrle32/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(msrle32.dll msrle32.spec) list(APPEND SOURCE @@ -18,3 +16,4 @@ set_module_type(msrle32 win32dll) target_link_libraries(msrle32 wine) add_importlibs(msrle32 winmm user32 msvcrt kernel32 ntdll) add_cd_file(TARGET msrle32 DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(msrle32) # CORE-5743: No ARRAY_SIZE macro diff --git a/dll/win32/msrle32/lang/msrle_Bg.rc b/dll/win32/msrle32/lang/msrle_Bg.rc index ad3bc10aefa89..3e0ec5a10ad2b 100644 --- a/dll/win32/msrle32/lang/msrle_Bg.rc +++ b/dll/win32/msrle32/lang/msrle_Bg.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "msrle_private.h" - LANGUAGE LANG_BULGARIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/msrle32/lang/msrle_Cs.rc b/dll/win32/msrle32/lang/msrle_Cs.rc index 6fd321588c230..1ca1fba27ed94 100644 --- a/dll/win32/msrle32/lang/msrle_Cs.rc +++ b/dll/win32/msrle32/lang/msrle_Cs.rc @@ -20,8 +20,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "msrle_private.h" - LANGUAGE LANG_CZECH, SUBLANG_DEFAULT /* Czech strings in CP1250 */ diff --git a/dll/win32/msrle32/lang/msrle_Cy.rc b/dll/win32/msrle32/lang/msrle_Cy.rc index 1794fd551c4e9..e13bc5db4d363 100644 --- a/dll/win32/msrle32/lang/msrle_Cy.rc +++ b/dll/win32/msrle32/lang/msrle_Cy.rc @@ -19,10 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "msrle_private.h" - -#pragma code_page(65001) - LANGUAGE LANG_WELSH, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/msrle32/lang/msrle_Da.rc b/dll/win32/msrle32/lang/msrle_Da.rc index 6c4aba0c9f03e..26d1ef0a3b2ef 100644 --- a/dll/win32/msrle32/lang/msrle_Da.rc +++ b/dll/win32/msrle32/lang/msrle_Da.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "msrle_private.h" - LANGUAGE LANG_DANISH, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/msrle32/lang/msrle_De.rc b/dll/win32/msrle32/lang/msrle_De.rc index 71dc2c2be0269..2aef429d5b725 100644 --- a/dll/win32/msrle32/lang/msrle_De.rc +++ b/dll/win32/msrle32/lang/msrle_De.rc @@ -18,10 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "msrle_private.h" - -#pragma code_page(65001) - LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/msrle32/lang/msrle_En.rc b/dll/win32/msrle32/lang/msrle_En.rc index 2a3520769d002..69aaba87086aa 100644 --- a/dll/win32/msrle32/lang/msrle_En.rc +++ b/dll/win32/msrle32/lang/msrle_En.rc @@ -18,10 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "msrle_private.h" - -#pragma code_page(65001) - LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/msrle32/lang/msrle_Es.rc b/dll/win32/msrle32/lang/msrle_Es.rc index 1f5bbecf2018c..c2a66659b43b8 100644 --- a/dll/win32/msrle32/lang/msrle_Es.rc +++ b/dll/win32/msrle32/lang/msrle_Es.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "msrle_private.h" - LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/msrle32/lang/msrle_Fr.rc b/dll/win32/msrle32/lang/msrle_Fr.rc index aa046c1d330fa..66830fdd5028c 100644 --- a/dll/win32/msrle32/lang/msrle_Fr.rc +++ b/dll/win32/msrle32/lang/msrle_Fr.rc @@ -18,11 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "msrle_private.h" - -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/msrle32/lang/msrle_He.rc b/dll/win32/msrle32/lang/msrle_He.rc index ff36acd14ca09..69f958fd769e1 100644 --- a/dll/win32/msrle32/lang/msrle_He.rc +++ b/dll/win32/msrle32/lang/msrle_He.rc @@ -20,10 +20,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "msrle_private.h" - -#pragma code_page(65001) - LANGUAGE LANG_HEBREW, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/msrle32/lang/msrle_Hu.rc b/dll/win32/msrle32/lang/msrle_Hu.rc index 0e7876cecf1ff..29d558edee749 100644 --- a/dll/win32/msrle32/lang/msrle_Hu.rc +++ b/dll/win32/msrle32/lang/msrle_Hu.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "msrle_private.h" - LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/msrle32/lang/msrle_It.rc b/dll/win32/msrle32/lang/msrle_It.rc index ebc30056d2baf..d89990db618bd 100644 --- a/dll/win32/msrle32/lang/msrle_It.rc +++ b/dll/win32/msrle32/lang/msrle_It.rc @@ -19,8 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "msrle_private.h" - LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/msrle32/lang/msrle_Ja.rc b/dll/win32/msrle32/lang/msrle_Ja.rc index 804a8ac0396cd..b42ddccfadff5 100644 --- a/dll/win32/msrle32/lang/msrle_Ja.rc +++ b/dll/win32/msrle32/lang/msrle_Ja.rc @@ -18,11 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "msrle_private.h" - -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/msrle32/lang/msrle_Ko.rc b/dll/win32/msrle32/lang/msrle_Ko.rc index c050da9580a67..824795eadd1d2 100644 --- a/dll/win32/msrle32/lang/msrle_Ko.rc +++ b/dll/win32/msrle32/lang/msrle_Ko.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "msrle_private.h" - LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/msrle32/lang/msrle_Lt.rc b/dll/win32/msrle32/lang/msrle_Lt.rc index f6e5e0c98e8b6..dff519a0f0c31 100644 --- a/dll/win32/msrle32/lang/msrle_Lt.rc +++ b/dll/win32/msrle32/lang/msrle_Lt.rc @@ -18,11 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "msrle_private.h" - -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_LITHUANIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/msrle32/lang/msrle_Nl.rc b/dll/win32/msrle32/lang/msrle_Nl.rc index ae627ba87394f..939d203294f64 100644 --- a/dll/win32/msrle32/lang/msrle_Nl.rc +++ b/dll/win32/msrle32/lang/msrle_Nl.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "msrle_private.h" - LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/msrle32/lang/msrle_No.rc b/dll/win32/msrle32/lang/msrle_No.rc index 0ce410f940361..fed4c9aae1dbb 100644 --- a/dll/win32/msrle32/lang/msrle_No.rc +++ b/dll/win32/msrle32/lang/msrle_No.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "msrle_private.h" - LANGUAGE LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL STRINGTABLE diff --git a/dll/win32/msrle32/lang/msrle_Pl.rc b/dll/win32/msrle32/lang/msrle_Pl.rc index 8a5d995a54214..d4fa19aed57ca 100644 --- a/dll/win32/msrle32/lang/msrle_Pl.rc +++ b/dll/win32/msrle32/lang/msrle_Pl.rc @@ -19,8 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "msrle_private.h" - LANGUAGE LANG_POLISH, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/msrle32/lang/msrle_Pt.rc b/dll/win32/msrle32/lang/msrle_Pt.rc index 0bc8637166b18..09a6e51824610 100644 --- a/dll/win32/msrle32/lang/msrle_Pt.rc +++ b/dll/win32/msrle32/lang/msrle_Pt.rc @@ -19,8 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "msrle_private.h" - LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN STRINGTABLE diff --git a/dll/win32/msrle32/lang/msrle_Ro.rc b/dll/win32/msrle32/lang/msrle_Ro.rc index d0ac98670f394..119317f1c8bca 100644 --- a/dll/win32/msrle32/lang/msrle_Ro.rc +++ b/dll/win32/msrle32/lang/msrle_Ro.rc @@ -17,12 +17,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "msrle_private.h" - LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL -#pragma code_page(65001) - STRINGTABLE { IDS_NAME "WINE-MS-RLE" diff --git a/dll/win32/msrle32/lang/msrle_Ru.rc b/dll/win32/msrle32/lang/msrle_Ru.rc index 456d724001894..f1c785b385f09 100644 --- a/dll/win32/msrle32/lang/msrle_Ru.rc +++ b/dll/win32/msrle32/lang/msrle_Ru.rc @@ -18,11 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "msrle_private.h" - -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/msrle32/lang/msrle_Si.rc b/dll/win32/msrle32/lang/msrle_Si.rc index e99d6a1bb8950..6073573331c4d 100644 --- a/dll/win32/msrle32/lang/msrle_Si.rc +++ b/dll/win32/msrle32/lang/msrle_Si.rc @@ -18,10 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "msrle_private.h" - -#pragma code_page(65001) - LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/msrle32/lang/msrle_Sq.rc b/dll/win32/msrle32/lang/msrle_Sq.rc index 9e8e287c9c368..f5dfc7ff44820 100644 --- a/dll/win32/msrle32/lang/msrle_Sq.rc +++ b/dll/win32/msrle32/lang/msrle_Sq.rc @@ -18,10 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "msrle_private.h" - -#pragma code_page(65001) - LANGUAGE LANG_ALBANIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/msrle32/lang/msrle_Sv.rc b/dll/win32/msrle32/lang/msrle_Sv.rc index d6a4c17e6ecad..6e447b872951c 100644 --- a/dll/win32/msrle32/lang/msrle_Sv.rc +++ b/dll/win32/msrle32/lang/msrle_Sv.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "msrle_private.h" - LANGUAGE LANG_SWEDISH, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/msrle32/lang/msrle_Tr.rc b/dll/win32/msrle32/lang/msrle_Tr.rc index 2e25db5bb1acf..7405961b57090 100644 --- a/dll/win32/msrle32/lang/msrle_Tr.rc +++ b/dll/win32/msrle32/lang/msrle_Tr.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "msrle_private.h" - LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/msrle32/lang/msrle_Uk.rc b/dll/win32/msrle32/lang/msrle_Uk.rc index 1e12f4982be5e..8304269140ee2 100644 --- a/dll/win32/msrle32/lang/msrle_Uk.rc +++ b/dll/win32/msrle32/lang/msrle_Uk.rc @@ -19,11 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "msrle_private.h" - -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/msrle32/lang/msrle_Zh.rc b/dll/win32/msrle32/lang/msrle_Zh.rc index 3b4211e80cc2b..dabf53abf5eeb 100644 --- a/dll/win32/msrle32/lang/msrle_Zh.rc +++ b/dll/win32/msrle32/lang/msrle_Zh.rc @@ -21,11 +21,6 @@ * Copyright 2021 Chan Chilung */ -#include "msrle_private.h" - -/* Chinese text is encoded in UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED STRINGTABLE diff --git a/dll/win32/mssign32/CMakeLists.txt b/dll/win32/mssign32/CMakeLists.txt index b60527f2529ef..326f43cf20f0a 100644 --- a/dll/win32/mssign32/CMakeLists.txt +++ b/dll/win32/mssign32/CMakeLists.txt @@ -1,6 +1,4 @@ -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) -add_definitions(-D__WINESRC__) spec2def(mssign32.dll mssign32.spec) list(APPEND SOURCE @@ -13,3 +11,4 @@ set_module_type(mssign32 win32dll) target_link_libraries(mssign32 wine) add_importlibs(mssign32 msvcrt kernel32 ntdll) add_cd_file(TARGET mssign32 DESTINATION reactos/system32 FOR all) +set_wine_module(mssign32) diff --git a/dll/win32/mssign32/mssign32_main.c b/dll/win32/mssign32/mssign32_main.c index da7551e6d1bf4..4385d0a254387 100644 --- a/dll/win32/mssign32/mssign32_main.c +++ b/dll/win32/mssign32/mssign32_main.c @@ -35,8 +35,10 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID lpv ) { switch(reason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls( hinst ); break; diff --git a/dll/win32/mssip32/CMakeLists.txt b/dll/win32/mssip32/CMakeLists.txt index 1dcdae40bafb2..657108b9c80c2 100644 --- a/dll/win32/mssip32/CMakeLists.txt +++ b/dll/win32/mssip32/CMakeLists.txt @@ -1,6 +1,4 @@ -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) -add_definitions(-D__WINESRC__) spec2def(mssip32.dll mssip32.spec) list(APPEND SOURCE @@ -13,3 +11,4 @@ set_module_type(mssip32 win32dll) target_link_libraries(mssip32 wine) add_importlibs(mssip32 msvcrt kernel32 ntdll) add_cd_file(TARGET mssip32 DESTINATION reactos/system32 FOR all) +set_wine_module(mssip32) diff --git a/dll/win32/mssip32/main.c b/dll/win32/mssip32/main.c index abefdd0b1b22a..0306b91389d7e 100644 --- a/dll/win32/mssip32/main.c +++ b/dll/win32/mssip32/main.c @@ -30,8 +30,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) switch (fdwReason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hinstDLL); break; diff --git a/dll/win32/mstask/CMakeLists.txt b/dll/win32/mstask/CMakeLists.txt index 9571b5a0e814f..73aea9d312195 100644 --- a/dll/win32/mstask/CMakeLists.txt +++ b/dll/win32/mstask/CMakeLists.txt @@ -1,7 +1,5 @@ -add_definitions(-D__WINESRC__) include_directories(BEFORE - ${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine ${REACTOS_BINARY_DIR}/dll/win32/netapi32) generate_idl_iids(mstask_local.idl) spec2def(mstask.dll mstask.spec) @@ -28,3 +26,4 @@ add_importlibs(mstask ole32 msvcrt kernel32 ntdll) add_dependencies(mstask netapi32) add_pch(mstask precomp.h SOURCE) add_cd_file(TARGET mstask DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(mstask) # CORE-5743: No CONST_VTABLE diff --git a/dll/win32/mstask/mstask_main.c b/dll/win32/mstask/mstask_main.c index aa6693d1e8e46..34851f868fcac 100644 --- a/dll/win32/mstask/mstask_main.c +++ b/dll/win32/mstask/mstask_main.c @@ -36,8 +36,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) switch (fdwReason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hinstDLL); hInst = hinstDLL; diff --git a/dll/win32/msv1_0/msv1_0.c b/dll/win32/msv1_0/msv1_0.c index 735b4a3e0dfad..1d4d6efc44843 100644 --- a/dll/win32/msv1_0/msv1_0.c +++ b/dll/win32/msv1_0/msv1_0.c @@ -17,16 +17,47 @@ typedef struct _LOGON_LIST_ENTRY LIST_ENTRY ListEntry; LUID LogonId; ULONG EnumHandle; + UNICODE_STRING UserName; + UNICODE_STRING LogonDomainName; + UNICODE_STRING LogonServer; + SECURITY_LOGON_TYPE LogonType; } LOGON_LIST_ENTRY, *PLOGON_LIST_ENTRY; /* GLOBALS *****************************************************************/ BOOL PackageInitialized = FALSE; LIST_ENTRY LogonListHead; +RTL_RESOURCE LogonListResource; ULONG EnumCounter; /* FUNCTIONS ***************************************************************/ +static +PLOGON_LIST_ENTRY +GetLogonByLogonId( + _In_ PLUID LogonId) +{ + PLOGON_LIST_ENTRY LogonEntry; + PLIST_ENTRY CurrentEntry; + + CurrentEntry = LogonListHead.Flink; + while (CurrentEntry != &LogonListHead) + { + LogonEntry = CONTAINING_RECORD(CurrentEntry, + LOGON_LIST_ENTRY, + ListEntry); + + if ((LogonEntry->LogonId.HighPart == LogonId->HighPart) && + (LogonEntry->LogonId.LowPart == LogonId->LowPart)) + return LogonEntry; + + CurrentEntry = CurrentEntry->Flink; + } + + return NULL; +} + + static NTSTATUS BuildInteractiveProfileBuffer(IN PLSA_CLIENT_REQUEST ClientRequest, @@ -287,6 +318,7 @@ BuildLm20LogonProfileBuffer( return Status; } + static PSID AppendRidToSid(PSID SrcSid, @@ -854,6 +886,14 @@ MsvpEnumerateUsers( TRACE("MsvpEnumerateUsers()\n"); + if (SubmitBufferLength < sizeof(MSV1_0_ENUMUSERS_REQUEST)) + { + ERR("Invalid SubmitBufferLength %lu\n", SubmitBufferLength); + return STATUS_INVALID_PARAMETER; + } + + RtlAcquireResourceShared(&LogonListResource, TRUE); + /* Count the currently logged-on users */ CurrentEntry = LogonListHead.Flink; while (CurrentEntry != &LogonListHead) @@ -931,11 +971,13 @@ MsvpEnumerateUsers( goto done; } - *ProtocolReturnBuffer = (PMSV1_0_INTERACTIVE_PROFILE)ClientBaseAddress; + *ProtocolReturnBuffer = ClientBaseAddress; *ReturnBufferLength = BufferLength; *ProtocolStatus = STATUS_SUCCESS; done: + RtlReleaseResource(&LogonListResource); + if (LocalBuffer != NULL) DispatchTable.FreeLsaHeap(LocalBuffer); @@ -946,7 +988,138 @@ MsvpEnumerateUsers( ClientBaseAddress); } - return STATUS_SUCCESS; + return Status; +} + + +static +NTSTATUS +MsvpGetUserInfo( + _In_ PLSA_CLIENT_REQUEST ClientRequest, + _In_ PVOID ProtocolSubmitBuffer, + _In_ PVOID ClientBufferBase, + _In_ ULONG SubmitBufferLength, + _Out_ PVOID *ProtocolReturnBuffer, + _Out_ PULONG ReturnBufferLength, + _Out_ PNTSTATUS ProtocolStatus) +{ + PMSV1_0_GETUSERINFO_REQUEST RequestBuffer; + PLOGON_LIST_ENTRY LogonEntry; + PMSV1_0_GETUSERINFO_RESPONSE LocalBuffer = NULL; + PVOID ClientBaseAddress = NULL; + ULONG BufferLength; + PWSTR BufferPtr; + NTSTATUS Status = STATUS_SUCCESS; + + TRACE("MsvpGetUserInfo()\n"); + + if (SubmitBufferLength < sizeof(MSV1_0_GETUSERINFO_REQUEST)) + { + ERR("Invalid SubmitBufferLength %lu\n", SubmitBufferLength); + return STATUS_INVALID_PARAMETER; + } + + RequestBuffer = (PMSV1_0_GETUSERINFO_REQUEST)ProtocolSubmitBuffer; + + TRACE("LogonId: 0x%lx\n", RequestBuffer->LogonId.LowPart); + + RtlAcquireResourceShared(&LogonListResource, TRUE); + + LogonEntry = GetLogonByLogonId(&RequestBuffer->LogonId); + if (LogonEntry == NULL) + { + ERR("No logon found for LogonId %lx\n", RequestBuffer->LogonId.LowPart); + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + TRACE("UserName: %wZ\n", &LogonEntry->UserName); + TRACE("LogonDomain: %wZ\n", &LogonEntry->LogonDomainName); + TRACE("LogonServer: %wZ\n", &LogonEntry->LogonServer); + + BufferLength = sizeof(MSV1_0_GETUSERINFO_RESPONSE) + + LogonEntry->UserName.MaximumLength + + LogonEntry->LogonDomainName.MaximumLength + + LogonEntry->LogonServer.MaximumLength; + + LocalBuffer = DispatchTable.AllocateLsaHeap(BufferLength); + if (LocalBuffer == NULL) + { + ERR("Failed to allocate the local buffer!\n"); + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + Status = DispatchTable.AllocateClientBuffer(ClientRequest, + BufferLength, + &ClientBaseAddress); + if (!NT_SUCCESS(Status)) + { + ERR("DispatchTable.AllocateClientBuffer failed (Status 0x%08lx)\n", Status); + goto done; + } + + TRACE("ClientBaseAddress: %p\n", ClientBaseAddress); + + /* Fill the local buffer */ + LocalBuffer->MessageType = MsV1_0GetUserInfo; + + BufferPtr = (PWSTR)((ULONG_PTR)LocalBuffer + sizeof(MSV1_0_GETUSERINFO_RESPONSE)); + + /* UserName */ + LocalBuffer->UserName.Length = LogonEntry->UserName.Length; + LocalBuffer->UserName.MaximumLength = LogonEntry->UserName.MaximumLength; + LocalBuffer->UserName.Buffer = (PWSTR)((ULONG_PTR)ClientBaseAddress + (ULONG_PTR)BufferPtr - (ULONG_PTR)LocalBuffer); + + RtlCopyMemory(BufferPtr, LogonEntry->UserName.Buffer, LogonEntry->UserName.MaximumLength); + BufferPtr = (PWSTR)((ULONG_PTR)BufferPtr + (ULONG_PTR)LocalBuffer->UserName.MaximumLength); + + /* LogonDomainName */ + LocalBuffer->LogonDomainName.Length = LogonEntry->LogonDomainName.Length; + LocalBuffer->LogonDomainName.MaximumLength = LogonEntry->LogonDomainName.MaximumLength; + LocalBuffer->LogonDomainName.Buffer = (PWSTR)((ULONG_PTR)ClientBaseAddress + (ULONG_PTR)BufferPtr - (ULONG_PTR)LocalBuffer); + + RtlCopyMemory(BufferPtr, LogonEntry->LogonDomainName.Buffer, LogonEntry->LogonDomainName.MaximumLength); + BufferPtr = (PWSTR)((ULONG_PTR)BufferPtr + (ULONG_PTR)LocalBuffer->LogonDomainName.MaximumLength); + + /* LogonServer */ + LocalBuffer->LogonServer.Length = LogonEntry->LogonServer.Length; + LocalBuffer->LogonServer.MaximumLength = LogonEntry->LogonServer.MaximumLength; + LocalBuffer->LogonServer.Buffer = (PWSTR)((ULONG_PTR)ClientBaseAddress + (ULONG_PTR)BufferPtr - (ULONG_PTR)LocalBuffer); + + RtlCopyMemory(BufferPtr, LogonEntry->LogonServer.Buffer, LogonEntry->LogonServer.MaximumLength); + + /* Logon Type */ + LocalBuffer->LogonType = LogonEntry->LogonType; + + Status = DispatchTable.CopyToClientBuffer(ClientRequest, + BufferLength, + ClientBaseAddress, + LocalBuffer); + if (!NT_SUCCESS(Status)) + { + ERR("DispatchTable.CopyToClientBuffer failed (Status 0x%08lx)\n", Status); + goto done; + } + + *ProtocolReturnBuffer = ClientBaseAddress; + *ReturnBufferLength = BufferLength; + *ProtocolStatus = STATUS_SUCCESS; + +done: + RtlReleaseResource(&LogonListResource); + + if (LocalBuffer != NULL) + DispatchTable.FreeLsaHeap(LocalBuffer); + + if (!NT_SUCCESS(Status)) + { + if (ClientBaseAddress != NULL) + DispatchTable.FreeClientBuffer(ClientRequest, + ClientBaseAddress); + } + + return Status; } @@ -994,6 +1167,15 @@ LsaApCallPackage(IN PLSA_CLIENT_REQUEST ClientRequest, break; case MsV1_0GetUserInfo: + Status = MsvpGetUserInfo(ClientRequest, + ProtocolSubmitBuffer, + ClientBufferBase, + SubmitBufferLength, + ProtocolReturnBuffer, + ReturnBufferLength, + ProtocolStatus); + break; + case MsV1_0ReLogonUsers: Status = STATUS_INVALID_PARAMETER; break; @@ -1105,6 +1287,7 @@ LsaApInitializePackage(IN ULONG AuthenticationPackageId, if (!PackageInitialized) { InitializeListHead(&LogonListHead); + RtlInitializeResource(&LogonListResource); EnumCounter = 0; PackageInitialized = TRUE; } @@ -1149,9 +1332,32 @@ LsaApInitializePackage(IN ULONG AuthenticationPackageId, */ VOID NTAPI -LsaApLogonTerminated(IN PLUID LogonId) +LsaApLogonTerminated( + _In_ PLUID LogonId) { + PLOGON_LIST_ENTRY LogonEntry; + TRACE("LsaApLogonTerminated()\n"); + + /* Remove the given logon entry from the list */ + LogonEntry = GetLogonByLogonId(LogonId); + if (LogonEntry != NULL) + { + RtlAcquireResourceExclusive(&LogonListResource, TRUE); + RemoveEntryList(&LogonEntry->ListEntry); + RtlReleaseResource(&LogonListResource); + + if (LogonEntry->UserName.Buffer) + RtlFreeHeap(RtlGetProcessHeap(), 0, LogonEntry->UserName.Buffer); + + if (LogonEntry->LogonDomainName.Buffer) + RtlFreeHeap(RtlGetProcessHeap(), 0, LogonEntry->LogonDomainName.Buffer); + + if (LogonEntry->LogonServer.Buffer) + RtlFreeHeap(RtlGetProcessHeap(), 0, LogonEntry->LogonServer.Buffer); + + RtlFreeHeap(RtlGetProcessHeap(), 0, LogonEntry); + } } @@ -1484,7 +1690,33 @@ LsaApLogonUserEx2(IN PLSA_CLIENT_REQUEST ClientRequest, LogonEntry->EnumHandle = EnumCounter; EnumCounter++; + TRACE("Logon User: %wZ %wZ %lx\n", LogonUserName, LogonDomain, LogonId->LowPart); + LogonEntry->UserName.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, LogonUserName->MaximumLength); + if (LogonEntry->UserName.Buffer) + { + LogonEntry->UserName.MaximumLength = LogonUserName->MaximumLength; + RtlCopyUnicodeString(&LogonEntry->UserName, LogonUserName); + } + + LogonEntry->LogonDomainName.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, LogonDomain->MaximumLength); + if (LogonEntry->LogonDomainName.Buffer) + { + LogonEntry->LogonDomainName.MaximumLength = LogonDomain->MaximumLength; + RtlCopyUnicodeString(&LogonEntry->LogonDomainName, LogonDomain); + } + + LogonEntry->LogonServer.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, ComputerName.MaximumLength); + if (LogonEntry->LogonServer.Buffer) + { + LogonEntry->LogonServer.MaximumLength = ComputerName.MaximumLength; + RtlCopyUnicodeString(&LogonEntry->LogonServer, &ComputerName); + } + + LogonEntry->LogonType = LogonType; + + RtlAcquireResourceExclusive(&LogonListResource, TRUE); InsertTailList(&LogonListHead, &LogonEntry->ListEntry); + RtlReleaseResource(&LogonListResource); } if (LogonType == Interactive || LogonType == Batch || LogonType == Service) diff --git a/dll/win32/msv1_0/precomp.h b/dll/win32/msv1_0/precomp.h index a034c3e610061..a56611e4ff2d3 100644 --- a/dll/win32/msv1_0/precomp.h +++ b/dll/win32/msv1_0/precomp.h @@ -27,10 +27,10 @@ #include #include #include +#include #include //#include -#include #include "ntlm/global.h" #include "ntlm/protocol.h" diff --git a/dll/win32/msvcrt/msvcrt.spec b/dll/win32/msvcrt/msvcrt.spec index f2f12e95c1019..f0ec4ea34a585 100644 --- a/dll/win32/msvcrt/msvcrt.spec +++ b/dll/win32/msvcrt/msvcrt.spec @@ -555,7 +555,7 @@ @ cdecl -version=0x600+ _get_errno(ptr) @ stub -version=0x600+ _get_fileinfo @ stub -version=0x600+ _get_fmode -# @ cdecl _get_heap_handle() +@ cdecl _get_heap_handle() @ cdecl _get_osfhandle(long) @ cdecl -version=0x600+ _get_osplatform(ptr) @ stub -version=0x600+ _get_osver diff --git a/dll/win32/msvfw32/CMakeLists.txt b/dll/win32/msvfw32/CMakeLists.txt index 8c6309f80bff1..bf68959aa760f 100644 --- a/dll/win32/msvfw32/CMakeLists.txt +++ b/dll/win32/msvfw32/CMakeLists.txt @@ -1,7 +1,5 @@ -add_definitions(-D__WINESRC__) add_definitions(-D_WINE) -include_directories(BEFORE ${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(msvfw32.dll msvfw32.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -21,3 +19,4 @@ target_link_libraries(msvfw32 wine) add_importlibs(msvfw32 winmm comctl32 user32 gdi32 advapi32 msvcrt kernel32 ntdll) add_pch(msvfw32 precomp.h SOURCE) add_cd_file(TARGET msvfw32 DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(msvfw32) # CORE-5743: No ARRAY_SIZE macro diff --git a/dll/win32/msvfw32/lang/msvfw32_De.rc b/dll/win32/msvfw32/lang/msvfw32_De.rc index 3db4ad72ca9c0..334ebbec04d8b 100644 --- a/dll/win32/msvfw32/lang/msvfw32_De.rc +++ b/dll/win32/msvfw32/lang/msvfw32_De.rc @@ -17,8 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/msvfw32/lang/msvfw32_Es.rc b/dll/win32/msvfw32/lang/msvfw32_Es.rc index d0bb9dafc4080..6d11b237cf494 100644 --- a/dll/win32/msvfw32/lang/msvfw32_Es.rc +++ b/dll/win32/msvfw32/lang/msvfw32_Es.rc @@ -17,8 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/msvfw32/lang/msvfw32_Fr.rc b/dll/win32/msvfw32/lang/msvfw32_Fr.rc index fd1a88872c090..66fbcd051e8e6 100644 --- a/dll/win32/msvfw32/lang/msvfw32_Fr.rc +++ b/dll/win32/msvfw32/lang/msvfw32_Fr.rc @@ -16,9 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/msvfw32/lang/msvfw32_It.rc b/dll/win32/msvfw32/lang/msvfw32_It.rc index 9d5ba8bef04a9..84628f810b0f6 100644 --- a/dll/win32/msvfw32/lang/msvfw32_It.rc +++ b/dll/win32/msvfw32/lang/msvfw32_It.rc @@ -16,9 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/msvfw32/lang/msvfw32_Lt.rc b/dll/win32/msvfw32/lang/msvfw32_Lt.rc index 4a652aa30fde1..1695ef7edb4f7 100644 --- a/dll/win32/msvfw32/lang/msvfw32_Lt.rc +++ b/dll/win32/msvfw32/lang/msvfw32_Lt.rc @@ -16,9 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_LITHUANIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/msvfw32/lang/msvfw32_Ro.rc b/dll/win32/msvfw32/lang/msvfw32_Ro.rc index 4f25829de03f4..d99ea12bcd851 100644 --- a/dll/win32/msvfw32/lang/msvfw32_Ro.rc +++ b/dll/win32/msvfw32/lang/msvfw32_Ro.rc @@ -20,8 +20,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/msvfw32/lang/msvfw32_Ru.rc b/dll/win32/msvfw32/lang/msvfw32_Ru.rc index 51924c89b4c7e..379a7c664249a 100644 --- a/dll/win32/msvfw32/lang/msvfw32_Ru.rc +++ b/dll/win32/msvfw32/lang/msvfw32_Ru.rc @@ -16,9 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/msvfw32/lang/msvfw32_Si.rc b/dll/win32/msvfw32/lang/msvfw32_Si.rc index f359a0ba87275..64def77a23125 100644 --- a/dll/win32/msvfw32/lang/msvfw32_Si.rc +++ b/dll/win32/msvfw32/lang/msvfw32_Si.rc @@ -16,8 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/msvfw32/lang/msvfw32_Uk.rc b/dll/win32/msvfw32/lang/msvfw32_Uk.rc index a5b5efca95504..62fa590eb0028 100644 --- a/dll/win32/msvfw32/lang/msvfw32_Uk.rc +++ b/dll/win32/msvfw32/lang/msvfw32_Uk.rc @@ -17,9 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/msvfw32/lang/msvfw32_Zh.rc b/dll/win32/msvfw32/lang/msvfw32_Zh.rc index add2432531f80..deb7f610c92c9 100644 --- a/dll/win32/msvfw32/lang/msvfw32_Zh.rc +++ b/dll/win32/msvfw32/lang/msvfw32_Zh.rc @@ -21,9 +21,6 @@ * Copyright 2021 Chan Chilung */ -/* Chinese text is encoded in UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED STRINGTABLE diff --git a/dll/win32/msvfw32/rsrc.rc b/dll/win32/msvfw32/rsrc.rc index 9f502c6da5fb5..460e9a0d03a8f 100644 --- a/dll/win32/msvfw32/rsrc.rc +++ b/dll/win32/msvfw32/rsrc.rc @@ -18,7 +18,6 @@ #include "msvideo_private.h" - #include /* UTF-8 */ diff --git a/dll/win32/msvidc32/CMakeLists.txt b/dll/win32/msvidc32/CMakeLists.txt index ca5da724207c8..ad69d91abbe68 100644 --- a/dll/win32/msvidc32/CMakeLists.txt +++ b/dll/win32/msvidc32/CMakeLists.txt @@ -1,9 +1,7 @@ add_definitions( - -D__WINESRC__ -D_WINE) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(msvidc32.dll msvidc32.spec) list(APPEND SOURCE @@ -15,3 +13,4 @@ set_module_type(msvidc32 win32dll) target_link_libraries(msvidc32 wine) add_importlibs(msvidc32 user32 msvcrt kernel32 ntdll) add_cd_file(TARGET msvidc32 DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(msvidc32) # CORE-5743: No ARRAY_SIZE macro diff --git a/dll/win32/msvidc32/lang/msvidc32_De.rc b/dll/win32/msvidc32/lang/msvidc32_De.rc index 97dfddf95f360..5c5547aa9e96f 100644 --- a/dll/win32/msvidc32/lang/msvidc32_De.rc +++ b/dll/win32/msvidc32/lang/msvidc32_De.rc @@ -17,8 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/msvidc32/lang/msvidc32_Es.rc b/dll/win32/msvidc32/lang/msvidc32_Es.rc index 41a92ba7bbc22..627c3e969f2b7 100644 --- a/dll/win32/msvidc32/lang/msvidc32_Es.rc +++ b/dll/win32/msvidc32/lang/msvidc32_Es.rc @@ -19,9 +19,6 @@ LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL -/*UTF-8*/ -#pragma code_page(65001) - STRINGTABLE { IDS_NAME "MS-CRAM" diff --git a/dll/win32/msvidc32/lang/msvidc32_Fr.rc b/dll/win32/msvidc32/lang/msvidc32_Fr.rc index 76240b3dff8ba..9353151392b4e 100644 --- a/dll/win32/msvidc32/lang/msvidc32_Fr.rc +++ b/dll/win32/msvidc32/lang/msvidc32_Fr.rc @@ -16,9 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/msvidc32/lang/msvidc32_It.rc b/dll/win32/msvidc32/lang/msvidc32_It.rc index 7c29524774e65..9187fff9f437a 100644 --- a/dll/win32/msvidc32/lang/msvidc32_It.rc +++ b/dll/win32/msvidc32/lang/msvidc32_It.rc @@ -16,9 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/msvidc32/lang/msvidc32_Ja.rc b/dll/win32/msvidc32/lang/msvidc32_Ja.rc index 6ae1958e5c6e9..c97adb98fa36a 100644 --- a/dll/win32/msvidc32/lang/msvidc32_Ja.rc +++ b/dll/win32/msvidc32/lang/msvidc32_Ja.rc @@ -16,9 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/msvidc32/lang/msvidc32_Lt.rc b/dll/win32/msvidc32/lang/msvidc32_Lt.rc index 765cd9f13b713..f3ff97726b9c3 100644 --- a/dll/win32/msvidc32/lang/msvidc32_Lt.rc +++ b/dll/win32/msvidc32/lang/msvidc32_Lt.rc @@ -16,9 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_LITHUANIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/msvidc32/lang/msvidc32_Ro.rc b/dll/win32/msvidc32/lang/msvidc32_Ro.rc index 656b0a7d17303..c601a67e43dc8 100644 --- a/dll/win32/msvidc32/lang/msvidc32_Ro.rc +++ b/dll/win32/msvidc32/lang/msvidc32_Ro.rc @@ -17,8 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/msvidc32/lang/msvidc32_Ru.rc b/dll/win32/msvidc32/lang/msvidc32_Ru.rc index dfd086574ac4c..4c06e53fc077a 100644 --- a/dll/win32/msvidc32/lang/msvidc32_Ru.rc +++ b/dll/win32/msvidc32/lang/msvidc32_Ru.rc @@ -16,9 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/msvidc32/lang/msvidc32_Si.rc b/dll/win32/msvidc32/lang/msvidc32_Si.rc index d721377ecd01d..298ddd1460302 100644 --- a/dll/win32/msvidc32/lang/msvidc32_Si.rc +++ b/dll/win32/msvidc32/lang/msvidc32_Si.rc @@ -16,8 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/msvidc32/lang/msvidc32_Uk.rc b/dll/win32/msvidc32/lang/msvidc32_Uk.rc index c5b6764888fe7..2cc4ab5867d9c 100644 --- a/dll/win32/msvidc32/lang/msvidc32_Uk.rc +++ b/dll/win32/msvidc32/lang/msvidc32_Uk.rc @@ -17,9 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/msvidc32/lang/msvidc32_Zh.rc b/dll/win32/msvidc32/lang/msvidc32_Zh.rc index b9c0e48ed5b4a..0ab97d494acd1 100644 --- a/dll/win32/msvidc32/lang/msvidc32_Zh.rc +++ b/dll/win32/msvidc32/lang/msvidc32_Zh.rc @@ -19,9 +19,6 @@ * Copyright 2021 Chan Chilung */ -/* Chinese text is encoded in UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED STRINGTABLE diff --git a/dll/win32/msxml/CMakeLists.txt b/dll/win32/msxml/CMakeLists.txt index 44fc897ff8453..eece0711fe0f0 100644 --- a/dll/win32/msxml/CMakeLists.txt +++ b/dll/win32/msxml/CMakeLists.txt @@ -3,10 +3,8 @@ remove_definitions(-D_WIN32_WINNT=0x502) add_definitions(-D_WIN32_WINNT=0x601) add_definitions( - -D__WINESRC__ -D_WINE) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(msxml.dll msxml.spec) add_typelib(msxml_tlb.idl) @@ -21,3 +19,4 @@ target_link_libraries(msxml wine) add_importlibs(msxml msxml3 msvcrt kernel32) add_dependencies(msxml stdole2) add_cd_file(TARGET msxml DESTINATION reactos/system32 FOR all) +set_wine_module(msxml) diff --git a/dll/win32/msxml2/CMakeLists.txt b/dll/win32/msxml2/CMakeLists.txt index 52deb1777de0f..8c8880c5e4621 100644 --- a/dll/win32/msxml2/CMakeLists.txt +++ b/dll/win32/msxml2/CMakeLists.txt @@ -3,10 +3,8 @@ remove_definitions(-D_WIN32_WINNT=0x502) add_definitions(-D_WIN32_WINNT=0x601) add_definitions( - -D__WINESRC__ -D_WINE) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(msxml2.dll msxml2.spec) add_typelib(msxml2_tlb.idl) @@ -21,3 +19,4 @@ target_link_libraries(msxml2 wine) add_importlibs(msxml2 msxml3 msvcrt kernel32) add_dependencies(msxml2 stdole2) add_cd_file(TARGET msxml2 DESTINATION reactos/system32 FOR all) +set_wine_module(msxml2) diff --git a/dll/win32/msxml3/CMakeLists.txt b/dll/win32/msxml3/CMakeLists.txt index be0ebf4105f61..0db9010cb0ba3 100644 --- a/dll/win32/msxml3/CMakeLists.txt +++ b/dll/win32/msxml3/CMakeLists.txt @@ -1,13 +1,11 @@ add_definitions( - -D__WINESRC__ -D__ROS_LONG64__ -D_WINE -DLIBXML_STATIC -DCOM_NO_WINDOWS_H) include_directories( - ${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine ${REACTOS_SOURCE_DIR}/sdk/lib/3rdparty/libwin-iconv) spec2def(msxml3.dll msxml3.spec ADD_IMPORTLIB NO_PRIVATE_WARNINGS) @@ -81,7 +79,12 @@ if(MSVC) target_compile_options(msxml3 PRIVATE /wd4090) endif() +if(CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_compile_options(msxml3 PRIVATE -Wno-incompatible-function-pointer-types) +endif() + add_importlibs(msxml3 urlmon ws2_32 shlwapi oleaut32 ole32 user32 msvcrt kernel32 ntdll) add_dependencies(msxml3 xmlparser_idlheader stdole2) # msxml3_v1.tlb needs stdole2.tlb add_pch(msxml3 precomp.h "${PCH_SKIP_SOURCE}") add_cd_file(TARGET msxml3 DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(msxml3) # CORE-5743: No ARRAY_SIZE and CONST_VTABLE diff --git a/dll/win32/msxml4/CMakeLists.txt b/dll/win32/msxml4/CMakeLists.txt index ae8258358da3e..be050db2a9b17 100644 --- a/dll/win32/msxml4/CMakeLists.txt +++ b/dll/win32/msxml4/CMakeLists.txt @@ -3,11 +3,9 @@ remove_definitions(-D_WIN32_WINNT=0x502) add_definitions(-D_WIN32_WINNT=0x601) add_definitions( - -D__WINESRC__ -D_WINE -DCOM_NO_WINDOWS_H) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(msxml4.dll msxml4.spec) add_typelib(msxml4_tlb.idl) @@ -22,3 +20,4 @@ target_link_libraries(msxml4 wine) add_importlibs(msxml4 msxml3 msvcrt kernel32) add_dependencies(msxml4 stdole2) add_cd_file(TARGET msxml4 DESTINATION reactos/system32 FOR all) +set_wine_module(msxml4) diff --git a/dll/win32/msxml6/CMakeLists.txt b/dll/win32/msxml6/CMakeLists.txt index b0a95ec0457f4..f751b67866d3c 100644 --- a/dll/win32/msxml6/CMakeLists.txt +++ b/dll/win32/msxml6/CMakeLists.txt @@ -3,11 +3,9 @@ remove_definitions(-D_WIN32_WINNT=0x502) add_definitions(-D_WIN32_WINNT=0x601) add_definitions( - -D__WINESRC__ -D_WINE -DCOM_NO_WINDOWS_H) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(msxml6.dll msxml6.spec) add_typelib(msxml6_tlb.idl) @@ -22,3 +20,4 @@ target_link_libraries(msxml6 wine) add_importlibs(msxml6 msxml3 msvcrt kernel32) add_dependencies(msxml6 stdole2) add_cd_file(TARGET msxml6 DESTINATION reactos/system32 FOR all) +set_wine_module(msxml6) diff --git a/dll/win32/nddeapi/CMakeLists.txt b/dll/win32/nddeapi/CMakeLists.txt index b3b6568c9be04..998ec49de341b 100644 --- a/dll/win32/nddeapi/CMakeLists.txt +++ b/dll/win32/nddeapi/CMakeLists.txt @@ -1,6 +1,4 @@ -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) -add_definitions(-D__WINESRC__) spec2def(nddeapi.dll nddeapi.spec) list(APPEND SOURCE @@ -13,3 +11,4 @@ set_module_type(nddeapi win32dll) target_link_libraries(nddeapi wine) add_importlibs(nddeapi msvcrt kernel32 ntdll) add_cd_file(TARGET nddeapi DESTINATION reactos/system32 FOR all) +set_wine_module(nddeapi) diff --git a/dll/win32/netapi32/obsolete.c b/dll/win32/netapi32/obsolete.c index 42b4440ca1d5e..78f1eea71ca05 100644 --- a/dll/win32/netapi32/obsolete.c +++ b/dll/win32/netapi32/obsolete.c @@ -145,7 +145,7 @@ NetErrorLogRead( _In_opt_ LPDWORD Reserved2, _In_ DWORD Reserved3, _In_ DWORD OffsetFlag, - _Deref_out_ LPBYTE *BufPtr, + _Outptr_ LPBYTE *BufPtr, _In_ DWORD PrefMaxSize, _Out_ LPDWORD BytesRead, _Out_ LPDWORD TotalAvailable) @@ -409,11 +409,11 @@ NetReplSetInfo( NET_API_STATUS WINAPI NetServiceControl( - __in_opt LPCWSTR servername, - __in LPCWSTR service, - __in DWORD opcode, - __in DWORD arg, - __deref_out LPBYTE *bufptr) + _In_opt_ LPCWSTR servername, + _In_ LPCWSTR service, + _In_ DWORD opcode, + _In_ DWORD arg, + _Outptr_ LPBYTE *bufptr) { return ERROR_NOT_SUPPORTED; } @@ -422,13 +422,13 @@ NetServiceControl( NET_API_STATUS WINAPI NetServiceEnum( - __in_opt LPCWSTR servername, - __in DWORD level, - __deref_out LPBYTE *bufptr, - __in DWORD prefmaxlen, - __out LPDWORD entriesread, - __out LPDWORD totalentries, - __inout_opt LPDWORD resume_handle) + _In_opt_ LPCWSTR servername, + _In_ DWORD level, + _Outptr_ LPBYTE *bufptr, + _In_ DWORD prefmaxlen, + _Out_ LPDWORD entriesread, + _Out_ LPDWORD totalentries, + _Inout_opt_ LPDWORD resume_handle) { return ERROR_NOT_SUPPORTED; } @@ -437,10 +437,10 @@ NetServiceEnum( NET_API_STATUS WINAPI NetServiceGetInfo( - __in_opt LPCWSTR servername, - __in LPCWSTR service, - __in DWORD level, - __deref_out LPBYTE *bufptr) + _In_opt_ LPCWSTR servername, + _In_ LPCWSTR service, + _In_ DWORD level, + _Outptr_ LPBYTE *bufptr) { return ERROR_NOT_SUPPORTED; } @@ -449,11 +449,11 @@ NetServiceGetInfo( NET_API_STATUS WINAPI NetServiceInstall( - __in_opt LPCWSTR servername, - __in LPCWSTR service, - __in DWORD argc, - __in_ecount(argc) LPCWSTR argv[], - __deref_out LPBYTE *bufptr) + _In_opt_ LPCWSTR servername, + _In_ LPCWSTR service, + _In_ DWORD argc, + _In_reads_(argc) LPCWSTR argv[], + _Outptr_ LPBYTE *bufptr) { return ERROR_NOT_SUPPORTED; } diff --git a/dll/win32/netapi32/wksta.c b/dll/win32/netapi32/wksta.c index 8890d7ce7e5c4..d09c5cb201c0b 100644 --- a/dll/win32/netapi32/wksta.c +++ b/dll/win32/netapi32/wksta.c @@ -273,152 +273,6 @@ NetWkstaTransportEnum(LMSTR ServerName, DWORD level, PBYTE* pbuf, } -/************************************************************ - * NetWkstaUserGetInfo (NETAPI32.@) - */ -NET_API_STATUS WINAPI NetWkstaUserGetInfo(LMSTR reserved, DWORD level, - PBYTE* bufptr) -{ - NET_API_STATUS nastatus; - - TRACE("(%s, %d, %p)\n", debugstr_w(reserved), level, bufptr); - switch (level) - { - case 0: - { - PWKSTA_USER_INFO_0 ui; - DWORD dwSize = UNLEN + 1; - - /* set up buffer */ - nastatus = NetApiBufferAllocate(sizeof(WKSTA_USER_INFO_0) + dwSize * sizeof(WCHAR), - (LPVOID *) bufptr); - if (nastatus != NERR_Success) - return ERROR_NOT_ENOUGH_MEMORY; - - ui = (PWKSTA_USER_INFO_0) *bufptr; - ui->wkui0_username = (LMSTR) (*bufptr + sizeof(WKSTA_USER_INFO_0)); - - /* get data */ - if (!GetUserNameW(ui->wkui0_username, &dwSize)) - { - NetApiBufferFree(ui); - return ERROR_NOT_ENOUGH_MEMORY; - } - else { - nastatus = NetApiBufferReallocate( - *bufptr, sizeof(WKSTA_USER_INFO_0) + - (lstrlenW(ui->wkui0_username) + 1) * sizeof(WCHAR), - (LPVOID *) bufptr); - if (nastatus != NERR_Success) - { - NetApiBufferFree(ui); - return nastatus; - } - ui = (PWKSTA_USER_INFO_0) *bufptr; - ui->wkui0_username = (LMSTR) (*bufptr + sizeof(WKSTA_USER_INFO_0)); - } - break; - } - - case 1: - { - PWKSTA_USER_INFO_1 ui; - PWKSTA_USER_INFO_0 ui0; - LSA_OBJECT_ATTRIBUTES ObjectAttributes; - LSA_HANDLE PolicyHandle; - PPOLICY_ACCOUNT_DOMAIN_INFO DomainInfo; - NTSTATUS NtStatus; - - /* sizes of the field buffers in WCHARS */ - int username_sz, logon_domain_sz, oth_domains_sz, logon_server_sz; - - FIXME("Level 1 processing is partially implemented\n"); - oth_domains_sz = 1; - logon_server_sz = 1; - - /* get some information first to estimate size of the buffer */ - ui0 = NULL; - nastatus = NetWkstaUserGetInfo(NULL, 0, (PBYTE *) &ui0); - if (nastatus != NERR_Success) - return nastatus; - username_sz = lstrlenW(ui0->wkui0_username) + 1; - - ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes)); - NtStatus = LsaOpenPolicy(NULL, &ObjectAttributes, - POLICY_VIEW_LOCAL_INFORMATION, - &PolicyHandle); - if (NtStatus != STATUS_SUCCESS) - { - TRACE("LsaOpenPolicyFailed with NT status %x\n", - LsaNtStatusToWinError(NtStatus)); - NetApiBufferFree(ui0); - return ERROR_NOT_ENOUGH_MEMORY; - } - LsaQueryInformationPolicy(PolicyHandle, PolicyAccountDomainInformation, - (PVOID*) &DomainInfo); - logon_domain_sz = lstrlenW(DomainInfo->DomainName.Buffer) + 1; - LsaClose(PolicyHandle); - - /* set up buffer */ - nastatus = NetApiBufferAllocate(sizeof(WKSTA_USER_INFO_1) + - (username_sz + logon_domain_sz + - oth_domains_sz + logon_server_sz) * sizeof(WCHAR), - (LPVOID *) bufptr); - if (nastatus != NERR_Success) { - NetApiBufferFree(ui0); - return nastatus; - } - ui = (WKSTA_USER_INFO_1 *) *bufptr; - ui->wkui1_username = (LMSTR) (*bufptr + sizeof(WKSTA_USER_INFO_1)); - ui->wkui1_logon_domain = (LMSTR) ( - ((PBYTE) ui->wkui1_username) + username_sz * sizeof(WCHAR)); - ui->wkui1_oth_domains = (LMSTR) ( - ((PBYTE) ui->wkui1_logon_domain) + - logon_domain_sz * sizeof(WCHAR)); - ui->wkui1_logon_server = (LMSTR) ( - ((PBYTE) ui->wkui1_oth_domains) + - oth_domains_sz * sizeof(WCHAR)); - - /* get data */ - lstrcpyW(ui->wkui1_username, ui0->wkui0_username); - NetApiBufferFree(ui0); - - lstrcpynW(ui->wkui1_logon_domain, DomainInfo->DomainName.Buffer, - logon_domain_sz); - LsaFreeMemory(DomainInfo); - - /* FIXME. Not implemented. Populated with empty strings */ - ui->wkui1_oth_domains[0] = 0; - ui->wkui1_logon_server[0] = 0; - break; - } - case 1101: - { - PWKSTA_USER_INFO_1101 ui; - DWORD dwSize = 1; - - FIXME("Stub. Level 1101 processing is not implemented\n"); - /* FIXME see also wkui1_oth_domains for level 1 */ - - /* set up buffer */ - nastatus = NetApiBufferAllocate(sizeof(WKSTA_USER_INFO_1101) + dwSize * sizeof(WCHAR), - (LPVOID *) bufptr); - if (nastatus != NERR_Success) - return nastatus; - ui = (PWKSTA_USER_INFO_1101) *bufptr; - ui->wkui1101_oth_domains = (LMSTR)(ui + 1); - - /* get data */ - ui->wkui1101_oth_domains[0] = 0; - break; - } - default: - TRACE("Invalid level %d is specified\n", level); - return ERROR_INVALID_LEVEL; - } - return NERR_Success; -} - /************************************************************ * NetpGetComputerName (NETAPI32.@) */ diff --git a/dll/win32/netapi32/wksta_new.c b/dll/win32/netapi32/wksta_new.c index 2739a6c86e0ce..48873eefbabdf 100644 --- a/dll/win32/netapi32/wksta_new.c +++ b/dll/win32/netapi32/wksta_new.c @@ -1057,8 +1057,8 @@ NetWkstaUserEnum( _Inout_ LPDWORD resumehandle) { WKSTA_USER_ENUM_STRUCT UserEnumInfo; - WKSTA_USER_INFO_0_CONTAINER Container0; - WKSTA_USER_INFO_1_CONTAINER Container1; +// WKSTA_USER_INFO_0_CONTAINER Container0; +// WKSTA_USER_INFO_1_CONTAINER Container1; NET_API_STATUS status; TRACE("NetWkstaUserEnum(%s, %d, %p, %d, %p, %p, %p)\n", debugstr_w(servername), @@ -1068,15 +1068,19 @@ NetWkstaUserEnum( switch (level) { case 0: - UserEnumInfo.WkstaUserInfo.Level0 = &Container0; - Container0.EntriesRead = 0; - Container0.Buffer = NULL; +// UserEnumInfo.WkstaUserInfo.Level0 = &Container0; +// Container0.EntriesRead = 0; +// Container0.Buffer = NULL; + UserEnumInfo.WkstaUserInfo.Level0.EntriesRead = 0; + UserEnumInfo.WkstaUserInfo.Level0.Buffer = NULL; break; case 1: - UserEnumInfo.WkstaUserInfo.Level1 = &Container1; - Container1.EntriesRead = 0; - Container1.Buffer = NULL; +// UserEnumInfo.WkstaUserInfo.Level1 = &Container1; +// Container1.EntriesRead = 0; +// Container1.Buffer = NULL; + UserEnumInfo.WkstaUserInfo.Level1.EntriesRead = 0; + UserEnumInfo.WkstaUserInfo.Level1.Buffer = NULL; break; default: @@ -1095,13 +1099,17 @@ NetWkstaUserEnum( switch (level) { case 0: - *bufptr = (LPBYTE)UserEnumInfo.WkstaUserInfo.Level0->Buffer; - *entriesread = UserEnumInfo.WkstaUserInfo.Level0->EntriesRead; +// *bufptr = (LPBYTE)UserEnumInfo.WkstaUserInfo.Level0->Buffer; +// *entriesread = UserEnumInfo.WkstaUserInfo.Level0->EntriesRead; + *bufptr = (LPBYTE)UserEnumInfo.WkstaUserInfo.Level0.Buffer; + *entriesread = UserEnumInfo.WkstaUserInfo.Level0.EntriesRead; break; case 1: - *bufptr = (LPBYTE)UserEnumInfo.WkstaUserInfo.Level1->Buffer; - *entriesread = UserEnumInfo.WkstaUserInfo.Level1->EntriesRead; +// *bufptr = (LPBYTE)UserEnumInfo.WkstaUserInfo.Level1->Buffer; +// *entriesread = UserEnumInfo.WkstaUserInfo.Level1->EntriesRead; + *bufptr = (LPBYTE)UserEnumInfo.WkstaUserInfo.Level1.Buffer; + *entriesread = UserEnumInfo.WkstaUserInfo.Level1.EntriesRead; break; } } @@ -1116,20 +1124,19 @@ NetWkstaUserEnum( } -#if 0 NET_API_STATUS WINAPI NetWkstaUserGetInfo( - LPWSTR reserved, + _In_ LPWSTR reserved, _In_ DWORD level, - _Out_ PBYTE *bufptr) + _Out_ LPBYTE *bufptr) { NET_API_STATUS status; TRACE("NetWkstaUserGetInfo(%s, %d, %p)\n", debugstr_w(reserved), level, bufptr); - if (reserved != NULL) + if (reserved != NULL || bufptr == NULL) return ERROR_INVALID_PARAMETER; *bufptr = NULL; @@ -1138,7 +1145,7 @@ NetWkstaUserGetInfo( { status = NetrWkstaUserGetInfo(NULL, level, - (LPWKSTA_USER_INFO)bufptr); + (LPWKSTA_USER_INFO*)bufptr); } RpcExcept(EXCEPTION_EXECUTE_HANDLER) { @@ -1148,13 +1155,12 @@ NetWkstaUserGetInfo( return status; } -#endif NET_API_STATUS WINAPI NetWkstaUserSetInfo( - LPWSTR reserved, + _In_ LPWSTR reserved, _In_ DWORD level, _In_ LPBYTE buf, _Out_ LPDWORD parm_err) diff --git a/dll/win32/netcfgx/CMakeLists.txt b/dll/win32/netcfgx/CMakeLists.txt index bde3f69f9db41..5f499a2e0fd24 100644 --- a/dll/win32/netcfgx/CMakeLists.txt +++ b/dll/win32/netcfgx/CMakeLists.txt @@ -8,9 +8,11 @@ list(APPEND SOURCE netcfgx.c classfactory.c installer.c + netinstall.c netcfg_iface.c netcfgbindinginterface_iface.c netcfgbindingpath_iface.c + netcfgclass_iface.c inetcfgcomp_iface.c tcpipconf_notify.c propertypage.c diff --git a/dll/win32/netcfgx/netcfg_iface.c b/dll/win32/netcfgx/netcfg_iface.c index e292e4c7b4bca..72122513843a1 100644 --- a/dll/win32/netcfgx/netcfg_iface.c +++ b/dll/win32/netcfgx/netcfg_iface.c @@ -845,7 +845,7 @@ INetCfg_fnQueryNetCfgClass( REFIID riid, void **ppvObject) { - return E_FAIL; + return INetCfgClass_Constructor((IUnknown *)iface, riid, ppvObject, pguidClass, iface); } static const INetCfgVtbl vt_NetCfg = diff --git a/dll/win32/netcfgx/netcfgclass_iface.c b/dll/win32/netcfgx/netcfgclass_iface.c new file mode 100644 index 0000000000000..667f36df07cd4 --- /dev/null +++ b/dll/win32/netcfgx/netcfgclass_iface.c @@ -0,0 +1,235 @@ +#include "precomp.h" + +typedef struct +{ + const INetCfgClass *lpVtbl; + const INetCfgClassSetup *lpVtblSetup; + LONG ref; + GUID ClassGuid; + INetCfg *pNetCfg; +} INetCfgClassImpl, *LPINetCfgClassImpl; + +static __inline LPINetCfgClassImpl impl_from_INetCfgClassSetup(INetCfgClassSetup *iface) +{ + return (INetCfgClassImpl*)((char *)iface - FIELD_OFFSET(INetCfgClassImpl, lpVtblSetup)); +} + +/*************************************************************** + * INetCfgClassSetup + */ + +HRESULT +WINAPI +INetCfgClassSetup_fnQueryInterface( + INetCfgClassSetup *iface, + REFIID iid, + LPVOID *ppvObj) +{ + INetCfgClassImpl *This = impl_from_INetCfgClassSetup(iface); + return INetCfgClass_QueryInterface((INetCfgClass*)This, iid, ppvObj); +} + + +ULONG +WINAPI +INetCfgClassSetup_fnAddRef( + INetCfgClassSetup *iface) +{ + INetCfgClassImpl *This = impl_from_INetCfgClassSetup(iface); + return INetCfgClass_AddRef((INetCfgClass*)This); +} + +ULONG +WINAPI +INetCfgClassSetup_fnRelease( + INetCfgClassSetup *iface) +{ + INetCfgClassImpl *This = impl_from_INetCfgClassSetup(iface); + return INetCfgClass_Release((INetCfgClass*)This); +} + +HRESULT +WINAPI +INetCfgClassSetup_fnSelectAndInstall( + _In_ INetCfgClassSetup *iface, + _In_ HWND hwndParent, + _In_opt_ OBO_TOKEN *pOboToken, + _Out_opt_ INetCfgComponent **ppnccItem) +{ +// INetCfgClassImpl *This = impl_from_INetCfgClassSetup(iface); + return S_OK; +} + +HRESULT +WINAPI +INetCfgClassSetup_fnInstall( + _In_ INetCfgClassSetup *iface, + _In_ LPCWSTR pszwComponentId, + _In_opt_ OBO_TOKEN *pOboToken, + _In_opt_ DWORD dwSetupFlags, + _In_opt_ DWORD dwUpgradeFromBuildNo, + _In_opt_ LPCWSTR pszwAnswerFile, + _In_opt_ LPCWSTR pszwAnswerSections, + _Out_opt_ INetCfgComponent **ppComponent) +{ +// INetCfgClassImpl *This = impl_from_INetCfgClassSetup(iface); + + if (ppComponent) + *ppComponent = NULL; + + InstallNetworkComponent(pszwComponentId); + + return S_OK; +} + + +HRESULT +WINAPI +INetCfgClassSetup_fnDeInstall( + _In_ INetCfgClassSetup *iface, + _In_ INetCfgComponent *pComponent, + _In_opt_ OBO_TOKEN *pOboToken, + _Out_opt_ LPWSTR *pmszwRefs) +{ +// INetCfgClassImpl *This = impl_from_INetCfgClassSetup(iface); + + return S_OK; +} + +static const INetCfgClassSetupVtbl vt_NetCfgClassSetup = +{ + INetCfgClassSetup_fnQueryInterface, + INetCfgClassSetup_fnAddRef, + INetCfgClassSetup_fnRelease, + INetCfgClassSetup_fnSelectAndInstall, + INetCfgClassSetup_fnInstall, + INetCfgClassSetup_fnDeInstall +}; + +/*************************************************************** + * INetCfgClass + */ + +HRESULT +WINAPI +INetCfgClass_fnQueryInterface( + INetCfgClass *iface, + REFIID iid, + LPVOID *ppvObj) +{ + INetCfgClassImpl *This = (INetCfgClassImpl*)iface; + *ppvObj = NULL; + + if (IsEqualIID (iid, &IID_IUnknown) || + IsEqualIID (iid, &IID_INetCfgClass)) + { + *ppvObj = This; + INetCfgClass_AddRef(iface); + return S_OK; + } + else if (IsEqualIID (iid, &IID_INetCfgClassSetup)) + { + *ppvObj = (LPVOID)&This->lpVtblSetup; + INetCfgClass_AddRef(iface); + return S_OK; + } + + return E_NOINTERFACE; +} + +ULONG +WINAPI +INetCfgClass_fnAddRef( + INetCfgClass *iface) +{ + INetCfgClassImpl *This = (INetCfgClassImpl*)iface; + ULONG refCount = InterlockedIncrement(&This->ref); + + return refCount; +} + +ULONG +WINAPI +INetCfgClass_fnRelease( + INetCfgClass *iface) +{ + INetCfgClassImpl *This = (INetCfgClassImpl*)iface; + ULONG refCount = InterlockedDecrement(&This->ref); + + if (!refCount) + { + CoTaskMemFree(This); + } + return refCount; +} + +HRESULT +WINAPI +INetCfgClass_fnFindComponent( + INetCfgClass *iface, + INetCfgComponent **pComponent) +{ +// HRESULT hr; +// INetCfgClassImpl *This = (INetCfgClassImpl *)iface; + + + /* TODO */ + + return S_FALSE; +} + +HRESULT +WINAPI +INetCfgClass_fnEnumComponents( + INetCfgClass *iface, + IEnumNetCfgComponent **ppenumComponent) +{ +// INetCfgClassImpl *This = (INetCfgClassImpl *)iface; + + + return E_NOINTERFACE; +} + +static const INetCfgClassVtbl vt_NetCfgClass = +{ + INetCfgClass_fnQueryInterface, + INetCfgClass_fnAddRef, + INetCfgClass_fnRelease, + INetCfgClass_fnFindComponent, + INetCfgClass_fnEnumComponents, +}; + +HRESULT +WINAPI +INetCfgClass_Constructor( + IUnknown *pUnkOuter, + REFIID riid, + LPVOID *ppv, + const GUID *pguidClass, + INetCfg *pNetCfg) +{ + INetCfgClassImpl *This; + + if (!ppv) + return E_POINTER; + + This = (INetCfgClassImpl *)CoTaskMemAlloc(sizeof(INetCfgClassImpl)); + if (!This) + return E_OUTOFMEMORY; + + This->ref = 1; + This->lpVtbl = (const INetCfgClass*)&vt_NetCfgClass; + This->lpVtblSetup = (const INetCfgClassSetup*)&vt_NetCfgClassSetup; + + memcpy(&This->ClassGuid, pguidClass, sizeof(GUID)); + This->pNetCfg = pNetCfg; + + if (!SUCCEEDED(INetCfgClass_QueryInterface((INetCfgClass*)This, riid, ppv))) + { + INetCfgClass_Release((INetCfgClass*)This); + return E_NOINTERFACE; + } + + INetCfgClass_Release((INetCfgClass*)This); + return S_OK; +} diff --git a/dll/win32/netcfgx/netcfgx.rc b/dll/win32/netcfgx/netcfgx.rc index a353624735eb1..b6d8f049d7f13 100644 --- a/dll/win32/netcfgx/netcfgx.rc +++ b/dll/win32/netcfgx/netcfgx.rc @@ -17,12 +17,12 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL #include -/* UTF-8 */ -#pragma code_page(65001) - IDI_NETWORK ICON "res/network.ico" IDI_INTERNET ICON "res/internet.ico" +/* UTF-8 */ +#pragma code_page(65001) + #ifdef LANGUAGE_BG_BG #include "lang/bg-BG.rc" #endif diff --git a/dll/win32/netcfgx/netinstall.c b/dll/win32/netcfgx/netinstall.c new file mode 100644 index 0000000000000..1d167d81d0365 --- /dev/null +++ b/dll/win32/netcfgx/netinstall.c @@ -0,0 +1,627 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * PURPOSE: Network configuration + * FILE: dll/win32/netcfgx/netinstall.c + * PROGRAMER: Eric Kohl + */ + +/* INCLUDES *****************************************************************/ + +#include "precomp.h" +#include + + +typedef struct _COMPONENT_INFO +{ + PWSTR pszFullInfPath; + PWSTR pszInfPath; + PWSTR pszInfSection; + PWSTR pszComponentId; + PWSTR pszDescription; + PWSTR pszClassGuid; + DWORD dwCharacteristics; +} COMPONENT_INFO, *PCOMPONENT_INFO; + + +/* GLOBALS ******************************************************************/ + + +/* FUNCTIONS ****************************************************************/ + +static +BOOL +InstallInfSections( + _In_ HWND hWnd, + _In_ HKEY hKey, + _In_ LPCWSTR InfFile, + _In_ LPCWSTR InfSection) +{ + WCHAR Buffer[MAX_PATH]; + HINF hInf = INVALID_HANDLE_VALUE; + UINT BufferSize; + PVOID Context = NULL; + BOOL ret = FALSE; + + TRACE("InstallInfSections()\n"); + + if (InfSection == NULL) + return FALSE; + + /* Get Windows directory */ + BufferSize = ARRAYSIZE(Buffer) - 5 - wcslen(InfFile); + if (GetWindowsDirectoryW(Buffer, BufferSize) > BufferSize) + { + /* Function failed */ + SetLastError(ERROR_GEN_FAILURE); + goto cleanup; + } + + /* We have enough space to add some information in the buffer */ + if (Buffer[wcslen(Buffer) - 1] != '\\') + wcscat(Buffer, L"\\"); + wcscat(Buffer, L"Inf\\"); + wcscat(Buffer, InfFile); + + /* Install specified section */ + hInf = SetupOpenInfFileW(Buffer, NULL, INF_STYLE_WIN4, NULL); + if (hInf == INVALID_HANDLE_VALUE) + goto cleanup; + + Context = SetupInitDefaultQueueCallback(hWnd); + if (Context == NULL) + goto cleanup; + + ret = SetupInstallFromInfSectionW( + hWnd, hInf, + InfSection, SPINST_ALL, + hKey, NULL, SP_COPY_NEWER, + SetupDefaultQueueCallbackW, Context, + NULL, NULL); + if (ret == FALSE) + { + ERR("SetupInstallFromInfSectionW(%S) failed (Error %lx)\n", InfSection, GetLastError()); + goto cleanup; + } + + wcscpy(Buffer, InfSection); + wcscat(Buffer, L".Services"); + + ret = SetupInstallServicesFromInfSectionW(hInf, Buffer, 0); + if (ret == FALSE) + { + ERR("SetupInstallServicesFromInfSectionW(%S) failed (Error %lx)\n", Buffer, GetLastError()); + goto cleanup; + } + +cleanup: + if (Context) + SetupTermDefaultQueueCallback(Context); + + if (hInf != INVALID_HANDLE_VALUE) + SetupCloseInfFile(hInf); + + TRACE("InstallInfSections() done %u\n", ret); + + return ret; +} + + +static +BOOL +CreateInstanceKey( + _In_ PCOMPONENT_INFO pComponentInfo, + _Out_ PHKEY pInstanceKey) +{ + WCHAR szKeyBuffer[128]; + LPWSTR UuidString = NULL; + UUID Uuid; + RPC_STATUS RpcStatus; + HKEY hInstanceKey; + DWORD rc; + BOOL ret = FALSE; + + TRACE("CreateInstanceKey()\n"); + + *pInstanceKey = NULL; + + wcscpy(szKeyBuffer, L"SYSTEM\\CurrentControlSet\\Control\\Network\\"); + wcscat(szKeyBuffer, pComponentInfo->pszClassGuid); + wcscat(szKeyBuffer, L"\\{"); + + /* Create a new UUID */ + RpcStatus = UuidCreate(&Uuid); + if (RpcStatus != RPC_S_OK && RpcStatus != RPC_S_UUID_LOCAL_ONLY) + { + ERR("UuidCreate() failed with RPC status 0x%lx\n", RpcStatus); + goto done; + } + + RpcStatus = UuidToStringW(&Uuid, &UuidString); + if (RpcStatus != RPC_S_OK) + { + ERR("UuidToStringW() failed with RPC status 0x%lx\n", RpcStatus); + goto done; + } + + wcscat(szKeyBuffer, UuidString); + wcscat(szKeyBuffer, L"}"); + + RpcStringFreeW(&UuidString); + + TRACE("szKeyBuffer %S\n", szKeyBuffer); + + rc = RegCreateKeyExW(HKEY_LOCAL_MACHINE, + szKeyBuffer, + 0, + NULL, + REG_OPTION_NON_VOLATILE, + KEY_CREATE_SUB_KEY | KEY_SET_VALUE, + NULL, + &hInstanceKey, + NULL); + if (rc != ERROR_SUCCESS) + { + ERR("RegCreateKeyExW() failed with error 0x%lx\n", rc); + goto done; + } + + rc = RegSetValueExW(hInstanceKey, + L"Characteristics", + 0, + REG_DWORD, + (LPBYTE)&pComponentInfo->dwCharacteristics, + sizeof(DWORD)); + if (rc != ERROR_SUCCESS) + { + ERR("RegSetValueExW() failed with error 0x%lx\n", rc); + goto done; + } + + rc = RegSetValueExW(hInstanceKey, + L"ComponentId", + 0, + REG_SZ, + (LPBYTE)pComponentInfo->pszComponentId, + (wcslen(pComponentInfo->pszComponentId) + 1) * sizeof(WCHAR)); + if (rc != ERROR_SUCCESS) + { + ERR("RegSetValueExW() failed with error 0x%lx\n", rc); + goto done; + } + + rc = RegSetValueExW(hInstanceKey, + L"Description", + 0, + REG_SZ, + (LPBYTE)pComponentInfo->pszDescription, + (wcslen(pComponentInfo->pszDescription) + 1) * sizeof(WCHAR)); + if (rc != ERROR_SUCCESS) + { + ERR("RegSetValueExW() failed with error 0x%lx\n", rc); + goto done; + } + + rc = RegSetValueExW(hInstanceKey, + L"InfPath", + 0, + REG_SZ, + (LPBYTE)pComponentInfo->pszInfPath, + (wcslen(pComponentInfo->pszInfPath) + 1) * sizeof(WCHAR)); + if (rc != ERROR_SUCCESS) + { + ERR("RegSetValueExW() failed with error 0x%lx\n", rc); + goto done; + } + + rc = RegSetValueExW(hInstanceKey, + L"InfSection", + 0, + REG_SZ, + (LPBYTE)pComponentInfo->pszInfSection, + (wcslen(pComponentInfo->pszInfSection) + 1) * sizeof(WCHAR)); + if (rc != ERROR_SUCCESS) + { + ERR("RegSetValueExW() failed with error 0x%lx\n", rc); + goto done; + } + + *pInstanceKey = hInstanceKey; + ret = TRUE; + +done: + if (ret == FALSE) + RegCloseKey(hInstanceKey); + + TRACE("CreateInstanceKey() done %u\n", ret); + + return ret; +} + + +static +BOOL +CheckInfFile( + _In_ PWSTR pszFullInfName, + _In_ PCWSTR pszComponentId, + _In_ PCOMPONENT_INFO pComponentInfo) +{ + WCHAR szLineBuffer[MAX_PATH]; + HINF hInf = INVALID_HANDLE_VALUE; + INFCONTEXT MfgContext, DevContext, MiscContext; + DWORD dwLength; + + hInf = SetupOpenInfFileW(pszFullInfName, + NULL, + INF_STYLE_WIN4, + NULL); + if (hInf == INVALID_HANDLE_VALUE) + { + ERR("\n"); + return FALSE; + } + + if (!SetupFindFirstLineW(hInf, + L"Manufacturer", + NULL, + &MfgContext)) + { + ERR("No Manufacurer section found!\n"); + goto done; + } + + for (;;) + { + if (!SetupGetStringFieldW(&MfgContext, + 1, + szLineBuffer, + MAX_PATH, + NULL)) + break; + + TRACE("Manufacturer: %S\n", szLineBuffer); + if (!SetupFindFirstLineW(hInf, + szLineBuffer, + NULL, + &DevContext)) + break; + + for (;;) + { + if (!SetupGetStringFieldW(&DevContext, + 2, + szLineBuffer, + MAX_PATH, + NULL)) + break; + + TRACE("Device: %S\n", szLineBuffer); + if (_wcsicmp(szLineBuffer, pszComponentId) == 0) + { + TRACE("Found it!\n"); + + /* Get the section name*/ + SetupGetStringFieldW(&DevContext, + 1, + NULL, + 0, + &dwLength); + + pComponentInfo->pszInfSection = HeapAlloc(GetProcessHeap(), + 0, + dwLength * sizeof(WCHAR)); + if (pComponentInfo->pszInfSection) + { + SetupGetStringFieldW(&DevContext, + 1, + pComponentInfo->pszInfSection, + dwLength, + &dwLength); + } + + /* Get the description*/ + SetupGetStringFieldW(&DevContext, + 0, + NULL, + 0, + &dwLength); + + pComponentInfo->pszDescription = HeapAlloc(GetProcessHeap(), + 0, + dwLength * sizeof(WCHAR)); + if (pComponentInfo->pszDescription) + { + SetupGetStringFieldW(&DevContext, + 0, + pComponentInfo->pszDescription, + dwLength, + &dwLength); + } + + /* Get the class GUID */ + if (SetupFindFirstLineW(hInf, + L"Version", + L"ClassGuid", + &MiscContext)) + { + SetupGetStringFieldW(&MiscContext, + 1, + NULL, + 0, + &dwLength); + + pComponentInfo->pszClassGuid = HeapAlloc(GetProcessHeap(), + 0, + dwLength * sizeof(WCHAR)); + if (pComponentInfo->pszInfSection) + { + SetupGetStringFieldW(&MiscContext, + 1, + pComponentInfo->pszClassGuid, + dwLength, + &dwLength); + } + } + + /* Get the Characteristics value */ + if (SetupFindFirstLineW(hInf, + pComponentInfo->pszInfSection, + L"Characteristics", + &MiscContext)) + { + SetupGetIntField(&MiscContext, + 1, + (PINT)&pComponentInfo->dwCharacteristics); + } + + SetupCloseInfFile(hInf); + return TRUE; + } + + if (!SetupFindNextLine(&DevContext, &DevContext)) + break; + } + + if (!SetupFindNextLine(&MfgContext, &MfgContext)) + break; + } + +done: + if (hInf != INVALID_HANDLE_VALUE) + SetupCloseInfFile(hInf); + + return FALSE; +} + + +static +BOOL +ScanForInfFile( + _In_ PCWSTR pszComponentId, + _In_ PCOMPONENT_INFO pComponentInfo) +{ + WCHAR szInfPath[MAX_PATH]; + WCHAR szFullInfName[MAX_PATH]; + WCHAR szPathBuffer[MAX_PATH]; + WIN32_FIND_DATAW fdw; + HANDLE hFindFile = INVALID_HANDLE_VALUE; + BOOL bFound = FALSE; + + GetWindowsDirectoryW(szInfPath, MAX_PATH); + wcscat(szInfPath, L"\\inf"); + + wcscpy(szPathBuffer, szInfPath); + wcscat(szPathBuffer, L"\\*.inf"); + + hFindFile = FindFirstFileW(szPathBuffer, &fdw); + if (hFindFile == INVALID_HANDLE_VALUE) + return FALSE; + + for (;;) + { + if (wcscmp(fdw.cFileName, L".") == 0 || + wcscmp(fdw.cFileName, L"..") == 0) + continue; + + TRACE("FileName: %S\n", fdw.cFileName); + + wcscpy(szFullInfName, szInfPath); + wcscat(szFullInfName, L"\\"); + wcscat(szFullInfName, fdw.cFileName); + + TRACE("Full Inf Name: %S\n", szFullInfName); + if (CheckInfFile(szFullInfName, + pszComponentId, + pComponentInfo)) + { + pComponentInfo->pszFullInfPath = HeapAlloc(GetProcessHeap(), + 0, + (wcslen(szFullInfName) + 1) * sizeof(WCHAR)); + if (pComponentInfo->pszFullInfPath) + wcscpy(pComponentInfo->pszFullInfPath, szFullInfName); + + pComponentInfo->pszInfPath = HeapAlloc(GetProcessHeap(), + 0, + (wcslen(fdw.cFileName) + 1) * sizeof(WCHAR)); + if (pComponentInfo->pszInfPath) + wcscpy(pComponentInfo->pszInfPath, fdw.cFileName); + + pComponentInfo->pszComponentId = HeapAlloc(GetProcessHeap(), + 0, + (wcslen(pszComponentId) + 1) * sizeof(WCHAR)); + if (pComponentInfo->pszComponentId) + wcscpy(pComponentInfo->pszComponentId, pszComponentId); + + bFound = TRUE; + break; + } + + if (!FindNextFileW(hFindFile, &fdw)) + break; + } + + if (hFindFile != INVALID_HANDLE_VALUE) + FindClose(hFindFile); + + return bFound; +} + +static +VOID +StartNetworkServices( + _In_ PCOMPONENT_INFO pComponentInfo) +{ + WCHAR szServiceName[64]; + HINF hInf = INVALID_HANDLE_VALUE; + INFCONTEXT Context; + PWSTR pServiceSection = NULL; + + SC_HANDLE hManager = NULL; + SC_HANDLE hService = NULL; + + hManager = OpenSCManagerW(NULL, + NULL, + SC_MANAGER_ALL_ACCESS); + if (hManager == NULL) + { + ERR("\n"); + goto done; + } + + hInf = SetupOpenInfFileW(pComponentInfo->pszFullInfPath, + NULL, + INF_STYLE_WIN4, + NULL); + if (hInf == INVALID_HANDLE_VALUE) + { + ERR("\n"); + goto done; + } + + pServiceSection = HeapAlloc(GetProcessHeap(), 0, + (wcslen(pComponentInfo->pszInfSection) + wcslen(L".Service") + 1) * sizeof(WCHAR)); + if (pServiceSection == NULL) + { + ERR("\n"); + goto done; + } + + wcscpy(pServiceSection, pComponentInfo->pszInfSection); + wcscat(pServiceSection, L".Service"); + + TRACE("ServiceSection: %S\n", pServiceSection); + + if (!SetupFindFirstLineW(hInf, + pServiceSection, + L"AddService", + &Context)) + { + ERR("\n"); + goto done; + } + + for (;;) + { + SetupGetStringFieldW(&Context, + 1, + szServiceName, + 64, + NULL); + + hService = OpenServiceW(hManager, + szServiceName, + SERVICE_START); + if (hService) + { + if (!StartService(hService, 0, NULL)) + { + ERR("StartService() %S failed %lu\n", szServiceName, GetLastError()); + } + + CloseServiceHandle(hService); + } + + if (!SetupFindNextLine(&Context, &Context)) + break; + } + +done: + if (pServiceSection) + HeapFree(GetProcessHeap(), 0, pServiceSection); + + if (hInf != INVALID_HANDLE_VALUE) + SetupCloseInfFile(hInf); + + if (hManager != NULL) + CloseServiceHandle(hManager); +} + + +BOOL +InstallNetworkComponent( + _In_ PCWSTR pszComponentId) +{ + COMPONENT_INFO ComponentInfo; + HKEY hInstanceKey = NULL; + BOOL bResult = FALSE; + + TRACE("InstallNetworkComponent(%S)\n", pszComponentId); + + ZeroMemory(&ComponentInfo, sizeof(COMPONENT_INFO)); + + if (!ScanForInfFile(pszComponentId, &ComponentInfo)) + goto done; + + TRACE("Characteristics: 0x%lx\n", ComponentInfo.dwCharacteristics); + TRACE("ComponentId: %S\n", ComponentInfo.pszComponentId); + TRACE("Description: %S\n", ComponentInfo.pszDescription); + TRACE("InfPath: %S\n", ComponentInfo.pszInfPath); + TRACE("InfSection: %S\n", ComponentInfo.pszInfSection); + TRACE("ClassGuid: %S\n", ComponentInfo.pszClassGuid); + + if (!CreateInstanceKey(&ComponentInfo, + &hInstanceKey)) + { + ERR("CreateInstanceKey() failed (Error %lx)\n", GetLastError()); + goto done; + } + + if (!InstallInfSections(NULL, + hInstanceKey, + ComponentInfo.pszInfPath, + ComponentInfo.pszInfSection)) + { + ERR("InstallInfSections() failed (Error %lx)\n", GetLastError()); + goto done; + } + + bResult = TRUE; + + StartNetworkServices(&ComponentInfo); + +done: + if (hInstanceKey != NULL) + RegCloseKey(hInstanceKey); + + if (ComponentInfo.pszFullInfPath) + HeapFree(GetProcessHeap(), 0, ComponentInfo.pszFullInfPath); + + if (ComponentInfo.pszInfPath) + HeapFree(GetProcessHeap(), 0, ComponentInfo.pszInfPath); + + if (ComponentInfo.pszInfSection) + HeapFree(GetProcessHeap(), 0, ComponentInfo.pszInfSection); + + if (ComponentInfo.pszComponentId) + HeapFree(GetProcessHeap(), 0, ComponentInfo.pszComponentId); + + if (ComponentInfo.pszDescription) + HeapFree(GetProcessHeap(), 0, ComponentInfo.pszDescription); + + if (ComponentInfo.pszClassGuid) + HeapFree(GetProcessHeap(), 0, ComponentInfo.pszClassGuid); + + return bResult; +} + +/* EOF */ diff --git a/dll/win32/netcfgx/precomp.h b/dll/win32/netcfgx/precomp.h index 77ba0e969681e..4823576c483ec 100644 --- a/dll/win32/netcfgx/precomp.h +++ b/dll/win32/netcfgx/precomp.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -73,6 +74,12 @@ HRESULT WINAPI IEnumNetCfgBindingInterface_Constructor(IUnknown *pUnkOuter, REFI HRESULT WINAPI INetCfgBindingPath_Constructor(IUnknown *pUnkOuter, REFIID riid, LPVOID *ppv); HRESULT WINAPI IEnumNetCfgBindingPath_Constructor(IUnknown *pUnkOuter, REFIID riid, LPVOID *ppv, DWORD dwFlags); +/* netcfgclass_iface.c */ +HRESULT WINAPI INetCfgClass_Constructor(IUnknown *pUnkOuter, REFIID riid, LPVOID *ppv, const GUID *pguidClass, INetCfg *pNetCfg); + +/* netinstall.c */ +BOOL InstallNetworkComponent(_In_ PCWSTR pszComponentId); + /* tcpipconf_notify.c */ HRESULT WINAPI TcpipConfigNotify_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv); diff --git a/dll/win32/newdev/newdev.c b/dll/win32/newdev/newdev.c index 8eade90eb32c0..bd62f858de54c 100644 --- a/dll/win32/newdev/newdev.c +++ b/dll/win32/newdev/newdev.c @@ -1,7 +1,7 @@ /* * New device installer (newdev.dll) * - * Copyright 2005-2006 Herv Poussineau (hpoussin@reactos.org) + * Copyright 2005-2006 Hervé Poussineau (hpoussin@reactos.org) * 2005 Christoph von Wittich (Christoph@ActiveVB.de) * 2009 Colin Finck (colin@reactos.org) * @@ -50,6 +50,7 @@ UpdateDriverForPlugAndPlayDevicesW( LPWSTR Buffer = NULL; DWORD BufferSize; LPCWSTR CurrentHardwareId; /* Pointer into Buffer */ + DWORD Property; BOOL FoundHardwareId, FoundAtLeastOneDevice = FALSE; BOOL ret = FALSE; @@ -86,51 +87,58 @@ UpdateDriverForPlugAndPlayDevicesW( break; } - /* Get Hardware ID */ - HeapFree(GetProcessHeap(), 0, Buffer); - Buffer = NULL; - BufferSize = 0; - while (!SetupDiGetDeviceRegistryPropertyW( - DevInstData.hDevInfo, - &DevInstData.devInfoData, - SPDRP_HARDWAREID, - NULL, - (PBYTE)Buffer, - BufferSize, - &BufferSize)) + /* Match Hardware ID */ + FoundHardwareId = FALSE; + Property = SPDRP_HARDWAREID; + while (TRUE) { - if (GetLastError() == ERROR_FILE_NOT_FOUND) - { - Buffer = NULL; - break; - } - else if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) + /* Get IDs data */ + Buffer = NULL; + BufferSize = 0; + while (!SetupDiGetDeviceRegistryPropertyW(DevInstData.hDevInfo, + &DevInstData.devInfoData, + Property, + NULL, + (PBYTE)Buffer, + BufferSize, + &BufferSize)) { - TRACE("SetupDiGetDeviceRegistryPropertyW() failed with error 0x%x\n", GetLastError()); - goto cleanup; + if (GetLastError() == ERROR_FILE_NOT_FOUND) + { + break; + } + else if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) + { + TRACE("SetupDiGetDeviceRegistryPropertyW() failed with error 0x%x\n", GetLastError()); + goto cleanup; + } + /* This error was expected */ + HeapFree(GetProcessHeap(), 0, Buffer); + Buffer = HeapAlloc(GetProcessHeap(), 0, BufferSize); + if (!Buffer) + { + TRACE("HeapAlloc() failed\n", GetLastError()); + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + goto cleanup; + } } - /* This error was expected */ - HeapFree(GetProcessHeap(), 0, Buffer); - Buffer = HeapAlloc(GetProcessHeap(), 0, BufferSize); - if (!Buffer) + if (Buffer) { - TRACE("HeapAlloc() failed\n", GetLastError()); - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - goto cleanup; + /* Check if we match the given hardware ID */ + for (CurrentHardwareId = Buffer; *CurrentHardwareId != UNICODE_NULL; CurrentHardwareId += wcslen(CurrentHardwareId) + 1) + { + if (_wcsicmp(CurrentHardwareId, HardwareId) == 0) + { + FoundHardwareId = TRUE; + break; + } + } } - } - if (Buffer == NULL) - continue; - - /* Check if we match the given hardware ID */ - FoundHardwareId = FALSE; - for (CurrentHardwareId = Buffer; *CurrentHardwareId != UNICODE_NULL; CurrentHardwareId += wcslen(CurrentHardwareId) + 1) - { - if (wcscmp(CurrentHardwareId, HardwareId) == 0) + if (FoundHardwareId || Property == SPDRP_COMPATIBLEIDS) { - FoundHardwareId = TRUE; break; } + Property = SPDRP_COMPATIBLEIDS; } if (!FoundHardwareId) continue; diff --git a/dll/win32/newdev/wizard.c b/dll/win32/newdev/wizard.c index 3dd231a401382..5204bcdf5d22f 100644 --- a/dll/win32/newdev/wizard.c +++ b/dll/win32/newdev/wizard.c @@ -545,9 +545,9 @@ WelcomeDlgProc( if (SendDlgItemMessage(hwndDlg, IDC_RADIO_AUTO, BM_GETCHECK, (WPARAM)0, (LPARAM)0) == BST_CHECKED) { if (PrepareFoldersToScan(DevInstData, TRUE, FALSE, NULL)) - PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_SEARCHDRV); + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_SEARCHDRV); else - PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_INSTALLFAILED); + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_INSTALLFAILED); } return TRUE; @@ -759,11 +759,11 @@ CHSourceDlgProc( IsDlgButtonChecked(hwndDlg, IDC_CHECK_PATH), GetDlgItem(hwndDlg, IDC_COMBO_PATH))) { - PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_SEARCHDRV); + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_SEARCHDRV); } else { - PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_INSTALLFAILED); + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_INSTALLFAILED); } } else @@ -1059,7 +1059,7 @@ NoDriverDlgProc( hwndControl = GetDlgItem(GetParent(hwndDlg), IDCANCEL); ShowWindow(hwndControl, SW_SHOW); EnableWindow(hwndControl, TRUE); - PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_CHSOURCE); + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_CHSOURCE); return TRUE; case PSN_WIZFINISH: diff --git a/dll/win32/npptools/CMakeLists.txt b/dll/win32/npptools/CMakeLists.txt index 122c121ef1d1d..0ef3b92d6d4f8 100644 --- a/dll/win32/npptools/CMakeLists.txt +++ b/dll/win32/npptools/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(npptools.dll npptools.spec) add_library(npptools MODULE @@ -11,3 +9,4 @@ add_library(npptools MODULE set_module_type(npptools win32dll) add_importlibs(npptools msvcrt kernel32 ntdll) add_cd_file(TARGET npptools DESTINATION reactos/system32 FOR all) +set_wine_module(npptools) diff --git a/dll/win32/npptools/main.c b/dll/win32/npptools/main.c index ad2b893155695..58cbda687b682 100644 --- a/dll/win32/npptools/main.c +++ b/dll/win32/npptools/main.c @@ -26,8 +26,10 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) { switch (reason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(instance); break; diff --git a/dll/win32/ntdsapi/CMakeLists.txt b/dll/win32/ntdsapi/CMakeLists.txt index 88a3f8165538d..796084fce8e04 100644 --- a/dll/win32/ntdsapi/CMakeLists.txt +++ b/dll/win32/ntdsapi/CMakeLists.txt @@ -1,6 +1,4 @@ -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) -add_definitions(-D__WINESRC__) spec2def(ntdsapi.dll ntdsapi.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -13,3 +11,4 @@ set_module_type(ntdsapi win32dll) target_link_libraries(ntdsapi wine) add_importlibs(ntdsapi user32 msvcrt kernel32 ntdll) add_cd_file(TARGET ntdsapi DESTINATION reactos/system32 FOR all) +set_wine_module(ntdsapi) diff --git a/dll/win32/ntdsapi/ntdsapi.c b/dll/win32/ntdsapi/ntdsapi.c index 8966a679acfc3..85ba76b469e96 100644 --- a/dll/win32/ntdsapi/ntdsapi.c +++ b/dll/win32/ntdsapi/ntdsapi.c @@ -36,8 +36,10 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) switch(reason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls( hinst ); diff --git a/dll/win32/ntmarta/CMakeLists.txt b/dll/win32/ntmarta/CMakeLists.txt index cecb8282bce29..2bbce34860d1f 100644 --- a/dll/win32/ntmarta/CMakeLists.txt +++ b/dll/win32/ntmarta/CMakeLists.txt @@ -1,5 +1,4 @@ -add_definitions(-D__WINESRC__) spec2def(ntmarta.dll ntmarta.spec) list(APPEND SOURCE diff --git a/dll/win32/objsel/CMakeLists.txt b/dll/win32/objsel/CMakeLists.txt index 4187d1d9b0bb6..25c05f03516c9 100644 --- a/dll/win32/objsel/CMakeLists.txt +++ b/dll/win32/objsel/CMakeLists.txt @@ -2,8 +2,6 @@ remove_definitions(-D_WIN32_WINNT=0x502) add_definitions(-D_WIN32_WINNT=0x600) -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(objsel.dll objsel.spec) list(APPEND SOURCE @@ -21,3 +19,4 @@ target_link_libraries(objsel uuid wine) add_importlibs(objsel ole32 advapi32 msvcrt kernel32 ntdll) add_pch(objsel precomp.h SOURCE) add_cd_file(TARGET objsel DESTINATION reactos/system32 FOR all) +set_wine_module(objsel) diff --git a/dll/win32/odbc32/CMakeLists.txt b/dll/win32/odbc32/CMakeLists.txt index 2fd48cc3c890e..669b6ac8f5383 100644 --- a/dll/win32/odbc32/CMakeLists.txt +++ b/dll/win32/odbc32/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(odbc32.dll odbc32.spec) list(APPEND SOURCE @@ -13,3 +11,4 @@ set_module_type(odbc32 win32dll) target_link_libraries(odbc32 wine) add_importlibs(odbc32 advapi32 msvcrt kernel32 ntdll) add_cd_file(TARGET odbc32 DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(odbc32) # CORE-5743: No ARRAY_SIZE macro diff --git a/dll/win32/odbccp32/CMakeLists.txt b/dll/win32/odbccp32/CMakeLists.txt index 77949d4d164f5..dbdea267dc5ac 100644 --- a/dll/win32/odbccp32/CMakeLists.txt +++ b/dll/win32/odbccp32/CMakeLists.txt @@ -2,8 +2,6 @@ remove_definitions(-D_WIN32_WINNT=0x502) add_definitions(-D_WIN32_WINNT=0x600) -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(odbccp32.dll odbccp32.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -16,3 +14,4 @@ set_module_type(odbccp32 win32dll) target_link_libraries(odbccp32 uuid wine) add_importlibs(odbccp32 advapi32 msvcrt kernel32 ntdll) add_cd_file(TARGET odbccp32 DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(odbccp32) # CORE-5743: No ARRAY_SIZE macro diff --git a/dll/win32/ole32/CMakeLists.txt b/dll/win32/ole32/CMakeLists.txt index a4c2728cf5197..ecb4cf041b411 100644 --- a/dll/win32/ole32/CMakeLists.txt +++ b/dll/win32/ole32/CMakeLists.txt @@ -3,7 +3,6 @@ remove_definitions(-D_WIN32_WINNT=0x502) add_definitions(-D_WIN32_WINNT=0x600) add_definitions( - -D__WINESRC__ -D_OLE32_ -D__ROS_LONG64__ -DCOM_NO_WINDOWS_H @@ -11,7 +10,6 @@ add_definitions( -DPROXY_CLSID=CLSID_PSFactoryBuffer -DWINE_REGISTER_DLL) -include_directories(BEFORE ${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(ole32.dll ole32.spec ADD_IMPORTLIB NO_PRIVATE_WARNINGS) generate_idl_iids(dcom.idl) add_idl_headers(ole32idl dcom.idl irot.idl) @@ -94,3 +92,4 @@ add_importlibs(ole32 advapi32 user32 gdi32 rpcrt4 msvcrt kernel32 kernel32_vista add_dependencies(ole32 ole32idl) add_pch(ole32 precomp.h "${PCH_SKIP_SOURCE}") add_cd_file(TARGET ole32 DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(ole32) # CORE-5743: No ARRAY_SIZE and CONST_VTABLE diff --git a/dll/win32/oleacc/CMakeLists.txt b/dll/win32/oleacc/CMakeLists.txt index abd7d6b5d5817..b42fa8951b836 100644 --- a/dll/win32/oleacc/CMakeLists.txt +++ b/dll/win32/oleacc/CMakeLists.txt @@ -1,11 +1,9 @@ add_definitions( - -D__WINESRC__ -DENTRY_PREFIX=OLEACC_ -DPROXY_DELEGATION -DWINE_REGISTER_DLL) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(oleacc.dll oleacc.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -43,3 +41,4 @@ target_link_libraries(oleacc uuid wine ${PSEH_LIB} oldnames) add_importlibs(oleacc oleaut32 ole32 user32 rpcrt4 msvcrt kernel32 ntdll) add_pch(oleacc precomp.h "${PCH_SKIP_SOURCE}") add_cd_file(TARGET oleacc DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(oleacc) # CORE-5743: No ARRAY_SIZE and CONST_VTABLE diff --git a/dll/win32/oleacc/lang/oleacc_De.rc b/dll/win32/oleacc/lang/oleacc_De.rc index 44620ad3a9439..3d7f4f653c78e 100644 --- a/dll/win32/oleacc/lang/oleacc_De.rc +++ b/dll/win32/oleacc/lang/oleacc_De.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/oleacc/lang/oleacc_Fr.rc b/dll/win32/oleacc/lang/oleacc_Fr.rc index 65a0f2236d3ac..2e632e76c0533 100644 --- a/dll/win32/oleacc/lang/oleacc_Fr.rc +++ b/dll/win32/oleacc/lang/oleacc_Fr.rc @@ -19,9 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/oleacc/lang/oleacc_Hu.rc b/dll/win32/oleacc/lang/oleacc_Hu.rc index 5d50a9989ee6b..8680be38c1bee 100644 --- a/dll/win32/oleacc/lang/oleacc_Hu.rc +++ b/dll/win32/oleacc/lang/oleacc_Hu.rc @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/oleacc/lang/oleacc_It.rc b/dll/win32/oleacc/lang/oleacc_It.rc index 3f8d10db2bdae..ae8a243a84458 100644 --- a/dll/win32/oleacc/lang/oleacc_It.rc +++ b/dll/win32/oleacc/lang/oleacc_It.rc @@ -19,9 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/oleacc/lang/oleacc_Lt.rc b/dll/win32/oleacc/lang/oleacc_Lt.rc index 60f4087cbac81..c066d06181572 100644 --- a/dll/win32/oleacc/lang/oleacc_Lt.rc +++ b/dll/win32/oleacc/lang/oleacc_Lt.rc @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_LITHUANIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/oleacc/lang/oleacc_No.rc b/dll/win32/oleacc/lang/oleacc_No.rc index e05ae900c5b23..caa7b516029c8 100644 --- a/dll/win32/oleacc/lang/oleacc_No.rc +++ b/dll/win32/oleacc/lang/oleacc_No.rc @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL STRINGTABLE diff --git a/dll/win32/oleacc/lang/oleacc_Pt.rc b/dll/win32/oleacc/lang/oleacc_Pt.rc index f09868a421468..fadfecc44ed4f 100644 --- a/dll/win32/oleacc/lang/oleacc_Pt.rc +++ b/dll/win32/oleacc/lang/oleacc_Pt.rc @@ -19,8 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN STRINGTABLE diff --git a/dll/win32/oleacc/lang/oleacc_Ro.rc b/dll/win32/oleacc/lang/oleacc_Ro.rc index b854f9df98d28..32cbf257c6901 100644 --- a/dll/win32/oleacc/lang/oleacc_Ro.rc +++ b/dll/win32/oleacc/lang/oleacc_Ro.rc @@ -21,8 +21,6 @@ LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL -#pragma code_page(65001) - STRINGTABLE { 0 "obiect necunoscut" /* undocumented */ diff --git a/dll/win32/oleacc/lang/oleacc_Si.rc b/dll/win32/oleacc/lang/oleacc_Si.rc index cee2ab3a5cd14..20ce8c7b50ca8 100644 --- a/dll/win32/oleacc/lang/oleacc_Si.rc +++ b/dll/win32/oleacc/lang/oleacc_Si.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/oleacc/lang/oleacc_Uk.rc b/dll/win32/oleacc/lang/oleacc_Uk.rc index 55da93f56da8a..1ea8cd0835a30 100644 --- a/dll/win32/oleacc/lang/oleacc_Uk.rc +++ b/dll/win32/oleacc/lang/oleacc_Uk.rc @@ -20,9 +20,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/oleacc/lang/oleacc_Zh.rc b/dll/win32/oleacc/lang/oleacc_Zh.rc index 23d77a1936697..9e110733e01fe 100644 --- a/dll/win32/oleacc/lang/oleacc_Zh.rc +++ b/dll/win32/oleacc/lang/oleacc_Zh.rc @@ -21,9 +21,6 @@ * Copyright 2021 Chan Chilung */ -/* Chinese text is encoded in UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED STRINGTABLE diff --git a/dll/win32/oleaut32/CMakeLists.txt b/dll/win32/oleaut32/CMakeLists.txt index 076582b8699ec..54f04d7549368 100644 --- a/dll/win32/oleaut32/CMakeLists.txt +++ b/dll/win32/oleaut32/CMakeLists.txt @@ -3,7 +3,6 @@ remove_definitions(-D_WIN32_WINNT=0x502) add_definitions(-D_WIN32_WINNT=0x600) add_definitions( - -D__WINESRC__ -D__ROS_LONG64__ -DCOM_NO_WINDOWS_H -D_OLEAUT32_ @@ -12,7 +11,6 @@ add_definitions( -DENTRY_PREFIX=OLEAUTPS_ -DPROXY_CLSID=CLSID_PSFactoryBuffer) -include_directories(BEFORE ${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(oleaut32.dll oleaut32.spec ADD_IMPORTLIB) add_rpcproxy_files(oleaut32_oaidl.idl oleaut32_ocidl.idl) @@ -63,3 +61,4 @@ add_delay_importlibs(oleaut32 comctl32 urlmon windowscodecs) add_importlibs(oleaut32 ole32 rpcrt4 user32 gdi32 advapi32 kernel32_vista msvcrt kernel32 ntdll) add_pch(oleaut32 precomp.h "${PCH_SKIP_SOURCE}") add_cd_file(TARGET oleaut32 DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(oleaut32) # CORE-5743: No ARRAY_SIZE and CONST_VTABLE diff --git a/dll/win32/oleaut32/lang/oleaut32_De.rc b/dll/win32/oleaut32/lang/oleaut32_De.rc index 73206c25a1d9f..12a96f622705c 100644 --- a/dll/win32/oleaut32/lang/oleaut32_De.rc +++ b/dll/win32/oleaut32/lang/oleaut32_De.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/oleaut32/lang/oleaut32_Lt.rc b/dll/win32/oleaut32/lang/oleaut32_Lt.rc index 77bd64e56741b..747bf7fc5e3b8 100644 --- a/dll/win32/oleaut32/lang/oleaut32_Lt.rc +++ b/dll/win32/oleaut32/lang/oleaut32_Lt.rc @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_LITHUANIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/oleaut32/lang/oleaut32_Ro.rc b/dll/win32/oleaut32/lang/oleaut32_Ro.rc index 8f71883332268..8ede4e8ca0c8f 100644 --- a/dll/win32/oleaut32/lang/oleaut32_Ro.rc +++ b/dll/win32/oleaut32/lang/oleaut32_Ro.rc @@ -19,8 +19,6 @@ LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL -#pragma code_page(65001) - STRINGTABLE { IDS_TRUE "Adevărat" diff --git a/dll/win32/oleaut32/lang/oleaut32_Ru.rc b/dll/win32/oleaut32/lang/oleaut32_Ru.rc index e2f0161e5118e..245e40bf94d3e 100644 --- a/dll/win32/oleaut32/lang/oleaut32_Ru.rc +++ b/dll/win32/oleaut32/lang/oleaut32_Ru.rc @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/oleaut32/lang/oleaut32_Si.rc b/dll/win32/oleaut32/lang/oleaut32_Si.rc index c0a4d23ec15ef..cd71fb0a39c41 100644 --- a/dll/win32/oleaut32/lang/oleaut32_Si.rc +++ b/dll/win32/oleaut32/lang/oleaut32_Si.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/oleaut32/lang/oleaut32_Uk.rc b/dll/win32/oleaut32/lang/oleaut32_Uk.rc index 38b020c486bdd..db469803510cc 100644 --- a/dll/win32/oleaut32/lang/oleaut32_Uk.rc +++ b/dll/win32/oleaut32/lang/oleaut32_Uk.rc @@ -20,9 +20,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/oleaut32/lang/oleaut32_Zh.rc b/dll/win32/oleaut32/lang/oleaut32_Zh.rc index 0005e4cd43f43..e9b9260c42792 100644 --- a/dll/win32/oleaut32/lang/oleaut32_Zh.rc +++ b/dll/win32/oleaut32/lang/oleaut32_Zh.rc @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* Chinese text is encoded in UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED STRINGTABLE diff --git a/dll/win32/olecli32/CMakeLists.txt b/dll/win32/olecli32/CMakeLists.txt index e9f3f0cdc65ee..aede67cfccbe8 100644 --- a/dll/win32/olecli32/CMakeLists.txt +++ b/dll/win32/olecli32/CMakeLists.txt @@ -1,6 +1,4 @@ -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) -add_definitions(-D__WINESRC__) spec2def(olecli32.dll olecli32.spec) list(APPEND SOURCE @@ -13,3 +11,4 @@ set_module_type(olecli32 win32dll) target_link_libraries(olecli32 wine ${PSEH_LIB}) add_importlibs(olecli32 ole32 gdi32 msvcrt kernel32 ntdll) add_cd_file(TARGET olecli32 DESTINATION reactos/system32 FOR all) +set_wine_module(olecli32) diff --git a/dll/win32/oledlg/CMakeLists.txt b/dll/win32/oledlg/CMakeLists.txt index f1abe4e3e12e3..2328e5cdb2d2c 100644 --- a/dll/win32/oledlg/CMakeLists.txt +++ b/dll/win32/oledlg/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(oledlg.dll oledlg.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -19,3 +17,4 @@ target_link_libraries(oledlg wine) add_importlibs(oledlg ole32 comdlg32 user32 advapi32 msvcrt kernel32 ntdll) add_pch(oledlg precomp.h SOURCE) add_cd_file(TARGET oledlg DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(oledlg) # CORE-5743: No ARRAY_SIZE macro diff --git a/dll/win32/oledlg/lang/oledlg_De.rc b/dll/win32/oledlg/lang/oledlg_De.rc index bd99c1c33e297..385228fb5c3c2 100644 --- a/dll/win32/oledlg/lang/oledlg_De.rc +++ b/dll/win32/oledlg/lang/oledlg_De.rc @@ -16,8 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/oledlg/lang/oledlg_Fr.rc b/dll/win32/oledlg/lang/oledlg_Fr.rc index 4f284de68a1fd..06ad4fc20446d 100644 --- a/dll/win32/oledlg/lang/oledlg_Fr.rc +++ b/dll/win32/oledlg/lang/oledlg_Fr.rc @@ -20,9 +20,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/oledlg/lang/oledlg_Hu.rc b/dll/win32/oledlg/lang/oledlg_Hu.rc index a96bd727968a0..75e66af16a8d2 100644 --- a/dll/win32/oledlg/lang/oledlg_Hu.rc +++ b/dll/win32/oledlg/lang/oledlg_Hu.rc @@ -16,9 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/oledlg/lang/oledlg_It.rc b/dll/win32/oledlg/lang/oledlg_It.rc index 9cdd49c61f898..dbd976013bdea 100644 --- a/dll/win32/oledlg/lang/oledlg_It.rc +++ b/dll/win32/oledlg/lang/oledlg_It.rc @@ -17,9 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/oledlg/lang/oledlg_Ja.rc b/dll/win32/oledlg/lang/oledlg_Ja.rc index bd18b9219eee2..f33f1e830f5a6 100644 --- a/dll/win32/oledlg/lang/oledlg_Ja.rc +++ b/dll/win32/oledlg/lang/oledlg_Ja.rc @@ -16,9 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/oledlg/lang/oledlg_Lt.rc b/dll/win32/oledlg/lang/oledlg_Lt.rc index bebe9ed51ccb5..d66681ed42900 100644 --- a/dll/win32/oledlg/lang/oledlg_Lt.rc +++ b/dll/win32/oledlg/lang/oledlg_Lt.rc @@ -16,9 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_LITHUANIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/oledlg/lang/oledlg_Nl.rc b/dll/win32/oledlg/lang/oledlg_Nl.rc index 968fe4f72a0bc..f6fdeff9a6392 100644 --- a/dll/win32/oledlg/lang/oledlg_Nl.rc +++ b/dll/win32/oledlg/lang/oledlg_Nl.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/oledlg/lang/oledlg_Pt.rc b/dll/win32/oledlg/lang/oledlg_Pt.rc index 23dc29f500588..312b291f2989f 100644 --- a/dll/win32/oledlg/lang/oledlg_Pt.rc +++ b/dll/win32/oledlg/lang/oledlg_Pt.rc @@ -19,8 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN STRINGTABLE diff --git a/dll/win32/oledlg/lang/oledlg_Ro.rc b/dll/win32/oledlg/lang/oledlg_Ro.rc index e976733c9b307..2754d5434475b 100644 --- a/dll/win32/oledlg/lang/oledlg_Ro.rc +++ b/dll/win32/oledlg/lang/oledlg_Ro.rc @@ -20,8 +20,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/oledlg/lang/oledlg_Ru.rc b/dll/win32/oledlg/lang/oledlg_Ru.rc index a5224fc31aadc..d9d4b015bc276 100644 --- a/dll/win32/oledlg/lang/oledlg_Ru.rc +++ b/dll/win32/oledlg/lang/oledlg_Ru.rc @@ -16,9 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/oledlg/lang/oledlg_Si.rc b/dll/win32/oledlg/lang/oledlg_Si.rc index fe7bd07c30530..91523179cde90 100644 --- a/dll/win32/oledlg/lang/oledlg_Si.rc +++ b/dll/win32/oledlg/lang/oledlg_Si.rc @@ -16,8 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/oledlg/lang/oledlg_Uk.rc b/dll/win32/oledlg/lang/oledlg_Uk.rc index 960841063b61a..f504c56ef0070 100644 --- a/dll/win32/oledlg/lang/oledlg_Uk.rc +++ b/dll/win32/oledlg/lang/oledlg_Uk.rc @@ -16,9 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/oledlg/lang/oledlg_Zh.rc b/dll/win32/oledlg/lang/oledlg_Zh.rc index 4ef55df193b7f..0d6e33c5e536e 100644 --- a/dll/win32/oledlg/lang/oledlg_Zh.rc +++ b/dll/win32/oledlg/lang/oledlg_Zh.rc @@ -19,9 +19,6 @@ * Copyright 2021 Chan Chilung */ -/* Chinese text is encoded in UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED STRINGTABLE diff --git a/dll/win32/olepro32/CMakeLists.txt b/dll/win32/olepro32/CMakeLists.txt index 0513497edd75f..6131f5ff4bc89 100644 --- a/dll/win32/olepro32/CMakeLists.txt +++ b/dll/win32/olepro32/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(olepro32.dll olepro32.spec) add_typelib(olepro.idl) @@ -20,3 +18,4 @@ set_module_type(olepro32 win32dll) target_link_libraries(olepro32 wine) add_importlibs(olepro32 oleaut32 msvcrt kernel32 ntdll) add_cd_file(TARGET olepro32 DESTINATION reactos/system32 FOR all) +set_wine_module(olepro32) diff --git a/dll/win32/olesvr32/CMakeLists.txt b/dll/win32/olesvr32/CMakeLists.txt index 13188640f2b8d..416676ed6a474 100644 --- a/dll/win32/olesvr32/CMakeLists.txt +++ b/dll/win32/olesvr32/CMakeLists.txt @@ -1,6 +1,4 @@ -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) -add_definitions(-D__WINESRC__) spec2def(olesvr32.dll olesvr32.spec) list(APPEND SOURCE @@ -13,3 +11,4 @@ set_module_type(olesvr32 win32dll) target_link_libraries(olesvr32 wine) add_importlibs(olesvr32 msvcrt kernel32 ntdll) add_cd_file(TARGET olesvr32 DESTINATION reactos/system32 FOR all) +set_wine_module(olesvr32) diff --git a/dll/win32/olethk32/CMakeLists.txt b/dll/win32/olethk32/CMakeLists.txt index aa5bb2da22071..626614ff14983 100644 --- a/dll/win32/olethk32/CMakeLists.txt +++ b/dll/win32/olethk32/CMakeLists.txt @@ -1,6 +1,4 @@ -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) -add_definitions(-D__WINESRC__) spec2def(olethk32.dll olethk32.spec) list(APPEND SOURCE @@ -14,3 +12,4 @@ set_module_type(olethk32 win32dll) target_link_libraries(olethk32 wine) add_importlibs(olethk32 msvcrt kernel32 ntdll) add_cd_file(TARGET olethk32 DESTINATION reactos/system32 FOR all) +set_wine_module(olethk32) diff --git a/dll/win32/olethk32/main.c b/dll/win32/olethk32/main.c index 13de72eb19762..e96b364e90f3b 100644 --- a/dll/win32/olethk32/main.c +++ b/dll/win32/olethk32/main.c @@ -27,8 +27,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { TRACE("(0x%p, %d, %p)\n",hinstDLL,fdwReason,lpvReserved); +#ifndef __REACTOS__ if (fdwReason == DLL_WINE_PREATTACH) return FALSE; /* prefer native version */ +#endif if (fdwReason == DLL_PROCESS_ATTACH) DisableThreadLibraryCalls(hinstDLL); diff --git a/dll/win32/pdh/CMakeLists.txt b/dll/win32/pdh/CMakeLists.txt index dc735a73677c4..c13007bf952dc 100644 --- a/dll/win32/pdh/CMakeLists.txt +++ b/dll/win32/pdh/CMakeLists.txt @@ -2,8 +2,6 @@ remove_definitions(-D_WIN32_WINNT=0x502) add_definitions(-D_WIN32_WINNT=0x600) -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(pdh.dll pdh.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -16,3 +14,4 @@ set_module_type(pdh win32dll) target_link_libraries(pdh wine) add_importlibs(pdh msvcrt kernel32_vista kernel32 ntdll) add_cd_file(TARGET pdh DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(pdh) # CORE-5743: No ARRAY_SIZE macro diff --git a/dll/win32/pdh/pdh_main.c b/dll/win32/pdh/pdh_main.c index cd1aed909796b..56374dd67dd3b 100644 --- a/dll/win32/pdh/pdh_main.c +++ b/dll/win32/pdh/pdh_main.c @@ -76,8 +76,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) TRACE("(0x%p, %d, %p)\n",hinstDLL,fdwReason,lpvReserved); switch (fdwReason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hinstDLL); break; diff --git a/dll/win32/pidgen/CMakeLists.txt b/dll/win32/pidgen/CMakeLists.txt index f15cb982b86e9..fd59456b06433 100644 --- a/dll/win32/pidgen/CMakeLists.txt +++ b/dll/win32/pidgen/CMakeLists.txt @@ -1,6 +1,4 @@ -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) -add_definitions(-D__WINESRC__) spec2def(pidgen.dll pidgen.spec) list(APPEND SOURCE @@ -14,3 +12,4 @@ set_module_type(pidgen win32dll) target_link_libraries(pidgen wine) add_importlibs(pidgen msvcrt kernel32 ntdll) add_cd_file(TARGET pidgen DESTINATION reactos/system32 FOR all) +set_wine_module(pidgen) diff --git a/dll/win32/pidgen/main.c b/dll/win32/pidgen/main.c index 35af226ffd23c..5d64655bd33c8 100644 --- a/dll/win32/pidgen/main.c +++ b/dll/win32/pidgen/main.c @@ -33,8 +33,10 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved ) switch(reason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls( hinst ); diff --git a/dll/win32/powrprof/CMakeLists.txt b/dll/win32/powrprof/CMakeLists.txt index cf6a2199a9b30..a2b3ca0c056d0 100644 --- a/dll/win32/powrprof/CMakeLists.txt +++ b/dll/win32/powrprof/CMakeLists.txt @@ -6,6 +6,11 @@ add_library(powrprof MODULE powrprof.rc ${CMAKE_CURRENT_BINARY_DIR}/powrprof.def) +if(MSVC) + # Disable warning C4312: 'type cast': conversion from 'unsigned int' to 'HANDLE' of greater size + target_compile_options(powrprof PRIVATE /wd4312) +endif() + set_module_type(powrprof win32dll UNICODE) target_link_libraries(powrprof wine) add_importlibs(powrprof advapi32 user32 comctl32 msvcrt kernel32 ntdll) diff --git a/dll/win32/powrprof/powrprof.c b/dll/win32/powrprof/powrprof.c index 7172bb43646c9..fa19aec08688e 100644 --- a/dll/win32/powrprof/powrprof.c +++ b/dll/win32/powrprof/powrprof.c @@ -510,6 +510,12 @@ PowerGetActiveScheme(HKEY UserRootPowerKey, GUID **polguid) return ERROR_CALL_NOT_IMPLEMENTED; } +DWORD WINAPI PowerSetActiveScheme(HKEY UserRootPowerKey, GUID *polguid) +{ + FIXME("(%p,%s) stub!\n", UserRootPowerKey, wine_dbgstr_guid(polguid)); + return ERROR_SUCCESS; +} + DWORD WINAPI PowerReadDCValue(HKEY RootPowerKey, const GUID *Scheme, const GUID *SubGroup, const GUID *PowerSettings, PULONG Type, PUCHAR Buffer, DWORD *BufferSize) { @@ -517,6 +523,111 @@ PowerReadDCValue(HKEY RootPowerKey, const GUID *Scheme, const GUID *SubGroup, co return ERROR_CALL_NOT_IMPLEMENTED; } +DWORD WINAPI PowerReadFriendlyName(HKEY RootPowerKey, const GUID *Scheme, + const GUID *SubGroup, const GUID *PowerSettings, UCHAR *Buffer, + DWORD *BufferSize) +{ + FIXME("(%p,%s,%s,%s,%p,%p) stub!\n", RootPowerKey, debugstr_guid(Scheme), debugstr_guid(SubGroup), debugstr_guid(PowerSettings), Buffer, BufferSize); + return ERROR_CALL_NOT_IMPLEMENTED; +} + +POWER_PLATFORM_ROLE WINAPI PowerDeterminePlatformRole(void) +{ + FIXME("stub\n"); + return PlatformRoleDesktop; +} + +POWER_PLATFORM_ROLE WINAPI PowerDeterminePlatformRoleEx(ULONG version) +{ + FIXME("%lu stub.\n", version); + return PlatformRoleDesktop; +} + +DWORD WINAPI PowerEnumerate(HKEY key, const GUID *scheme, const GUID *subgroup, POWER_DATA_ACCESSOR flags, + ULONG index, UCHAR *buffer, DWORD *buffer_size) +{ + FIXME("(%p,%s,%s,%d,%ld,%p,%p) stub!\n", key, debugstr_guid(scheme), debugstr_guid(subgroup), + flags, index, buffer, buffer_size); + return ERROR_CALL_NOT_IMPLEMENTED; +} + +DWORD WINAPI PowerRegisterSuspendResumeNotification(DWORD flags, HANDLE recipient, PHPOWERNOTIFY handle) +{ + FIXME("(0x%08lx,%p,%p) stub!\n", flags, recipient, handle); + *handle = (HPOWERNOTIFY)0xdeadbeef; + return ERROR_SUCCESS; +} + +DWORD WINAPI PowerUnregisterSuspendResumeNotification(HPOWERNOTIFY handle) +{ + FIXME("(%p) stub!\n", handle); + return ERROR_SUCCESS; +} + +DWORD WINAPI PowerSettingRegisterNotification(const GUID *setting, DWORD flags, HANDLE recipient, PHPOWERNOTIFY handle) +{ + FIXME("(%s,0x%08lx,%p,%p) stub!\n", debugstr_guid(setting), flags, recipient, handle); + *handle = (PHPOWERNOTIFY)0xdeadbeef; + return ERROR_SUCCESS; +} + +DWORD WINAPI PowerSettingUnregisterNotification(HPOWERNOTIFY handle) +{ + FIXME("(%p) stub!\n", handle); + return ERROR_SUCCESS; +} + +DWORD WINAPI PowerWriteACValueIndex(HKEY key, const GUID *scheme, const GUID *subgroup, const GUID *setting, DWORD index) +{ + FIXME("(%p,%s,%s,%s,0x%08lx) stub!\n", key, debugstr_guid(scheme), debugstr_guid(subgroup), debugstr_guid(setting), index); + return ERROR_SUCCESS; +} + +#ifdef __REACTOS__ +DWORD WINAPI PowerWriteDCValueIndex( + HKEY key, + const GUID *scheme, + const GUID *subgroup, + const GUID *setting, + DWORD index +) +{ + FIXME("(%p,%s,%s,%s,0x%08lx) stub!\n", key, debugstr_guid(scheme), debugstr_guid(subgroup), debugstr_guid(setting), index); + return ERROR_SUCCESS; +} + +DWORD WINAPI PowerReadACValueIndex( + HKEY key, + const GUID *scheme, + const GUID *subgroup, + const GUID *setting, + LPDWORD AcValueIndex +) +{ + FIXME("(%p,%s,%s,%s,0x%08lx) stub!\n", key, debugstr_guid(scheme), debugstr_guid(subgroup), debugstr_guid(setting)); + return ERROR_SUCCESS; +} + +DWORD WINAPI PowerReadDCValueIndex( + HKEY key, + const GUID *scheme, + const GUID *subgroup, + const GUID *setting, + LPDWORD DcValuetIndex +) +{ + FIXME("(%p,%s,%s,%s,0x%08lx) stub!\n", key, debugstr_guid(scheme), debugstr_guid(subgroup), debugstr_guid(setting)); + return ERROR_SUCCESS; +} + +DWORD WINAPI +PowerReadACValue(HKEY RootPowerKey, const GUID *Scheme, const GUID *SubGroup, const GUID *PowerSettings, PULONG Type, PUCHAR Buffer, DWORD *BufferSize) +{ + FIXME("(%p,%s,%s,%s,%p,%p,%p) stub!\n", RootPowerKey, debugstr_guid(Scheme), debugstr_guid(SubGroup), debugstr_guid(PowerSettings), Type, Buffer, BufferSize); + return ERROR_CALL_NOT_IMPLEMENTED; +} +#endif + BOOLEAN WINAPI ReadGlobalPwrPolicy(PGLOBAL_POWER_POLICY pGlobalPowerPolicy) { diff --git a/dll/win32/powrprof/powrprof.spec b/dll/win32/powrprof/powrprof.spec index 43a9723f7938b..37f2b02c84d30 100644 --- a/dll/win32/powrprof/powrprof.spec +++ b/dll/win32/powrprof/powrprof.spec @@ -10,8 +10,22 @@ @ stdcall IsPwrHibernateAllowed () @ stdcall IsPwrShutdownAllowed () @ stdcall IsPwrSuspendAllowed () +@ stdcall PowerDeterminePlatformRole () +@ stdcall PowerDeterminePlatformRoleEx(long) +@ stdcall PowerEnumerate(long ptr ptr long long ptr ptr) @ stdcall PowerGetActiveScheme (ptr ptr) -@ stdcall PowerReadDCValue (ptr ptr ptr ptr ptr ptr ptr) +@ stdcall PowerSetActiveScheme (ptr ptr) +@ stdcall PowerReadACValue(ptr ptr ptr ptr ptr ptr ptr) +@ stdcall PowerReadACValueIndex(ptr ptr ptr ptr ptr) +@ stdcall PowerReadDCValue(ptr ptr ptr ptr ptr ptr ptr) +@ stdcall PowerReadDCValueIndex(ptr ptr ptr ptr ptr) +@ stdcall PowerReadFriendlyName (ptr ptr ptr ptr ptr ptr) +@ stdcall PowerRegisterSuspendResumeNotification(long ptr ptr) +@ stdcall PowerUnregisterSuspendResumeNotification(ptr) +@ stdcall PowerSettingRegisterNotification(ptr long ptr ptr) +@ stdcall PowerSettingUnregisterNotification(ptr) +@ stdcall PowerWriteACValueIndex(ptr ptr ptr ptr long) +@ stdcall PowerWriteDCValueIndex(ptr ptr ptr ptr long) @ stdcall ReadGlobalPwrPolicy (ptr) @ stdcall ReadProcessorPwrScheme (long ptr) @ stdcall ReadPwrScheme (long ptr) @@ -20,4 +34,4 @@ @ stdcall WriteGlobalPwrPolicy (ptr) @ stdcall WriteProcessorPwrScheme (long ptr) @ stdcall WritePwrScheme (ptr str str ptr) -@ stdcall ValidatePowerPolicies (ptr ptr) \ No newline at end of file +@ stdcall ValidatePowerPolicies (ptr ptr) diff --git a/dll/win32/propsys/CMakeLists.txt b/dll/win32/propsys/CMakeLists.txt index 8d788ae20d457..d161ebd5eef5c 100644 --- a/dll/win32/propsys/CMakeLists.txt +++ b/dll/win32/propsys/CMakeLists.txt @@ -1,6 +1,6 @@ -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) -add_definitions(-D__WINESRC__) +remove_definitions(-D_CRT_NON_CONFORMING_SWPRINTFS -D__ROS_LONG64__) +add_definitions(-D_PROPSYS_) spec2def(propsys.dll propsys.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -16,7 +16,8 @@ add_library(propsys MODULE ${CMAKE_CURRENT_BINARY_DIR}/propsys.def) set_module_type(propsys win32dll) -target_link_libraries(propsys uuid wine) +target_link_libraries(propsys uuid wine wine_dll_register) add_importlibs(propsys ole32 oleaut32 msvcrt kernel32 ntdll) add_pch(propsys precomp.h SOURCE) add_cd_file(TARGET propsys DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(propsys) # CORE-5743: No ARRAY_SIZE and CONST_VTABLE diff --git a/dll/win32/propsys/precomp.h b/dll/win32/propsys/precomp.h index 1f432757e3af5..a233f258ae0fb 100644 --- a/dll/win32/propsys/precomp.h +++ b/dll/win32/propsys/precomp.h @@ -9,13 +9,14 @@ #define COM_NO_WINDOWS_H #define COBJMACROS -#define NONAMELESSUNION #include #include #include #include #include +#include +#include #include diff --git a/dll/win32/propsys/propstore.c b/dll/win32/propsys/propstore.c index 6212f2931238d..adef3b38916e2 100644 --- a/dll/win32/propsys/propstore.c +++ b/dll/win32/propsys/propstore.c @@ -92,7 +92,7 @@ static ULONG WINAPI PropertyStore_AddRef(IPropertyStoreCache *iface) PropertyStore *This = impl_from_IPropertyStoreCache(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -113,7 +113,7 @@ static ULONG WINAPI PropertyStore_Release(IPropertyStoreCache *iface) PropertyStore *This = impl_from_IPropertyStoreCache(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { @@ -159,7 +159,7 @@ static HRESULT WINAPI PropertyStore_GetAt(IPropertyStoreCache *iface, propstore_value *value; HRESULT hr; - TRACE("%p,%d,%p\n", iface, iProp, pkey); + TRACE("%p,%ld,%p\n", iface, iProp, pkey); if (!pkey) return E_POINTER; @@ -464,7 +464,11 @@ HRESULT PropertyStore_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv This->IPropertyStoreCache_iface.lpVtbl = &PropertyStore_Vtbl; This->ref = 1; +#ifdef __REACTOS__ InitializeCriticalSection(&This->lock); +#else + InitializeCriticalSectionEx(&This->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PropertyStore.lock"); list_init(&This->formats); @@ -473,3 +477,19 @@ HRESULT PropertyStore_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv return ret; } + +HRESULT WINAPI PSCreatePropertyStoreFromObject(IUnknown *obj, DWORD access, REFIID riid, void **ret) +{ + HRESULT hr; + + TRACE("(%p, %ld, %s, %p)\n", obj, access, debugstr_guid(riid), ret); + + if (!obj || !ret) + return E_POINTER; + + if (IsEqualIID(riid, &IID_IPropertyStore) && SUCCEEDED(hr = IUnknown_QueryInterface(obj, riid, ret))) + return hr; + + FIXME("Unimplemented for %s.\n", debugstr_guid(riid)); + return E_NOTIMPL; +} diff --git a/dll/win32/propsys/propsys.spec b/dll/win32/propsys/propsys.spec index 19e16aedc1ee2..5771848917b3e 100644 --- a/dll/win32/propsys/propsys.spec +++ b/dll/win32/propsys/propsys.spec @@ -42,7 +42,7 @@ @ stub InitPropVariantFromResource @ stub InitPropVariantFromStrRet @ stub InitPropVariantFromStringAsVector -@ stub InitPropVariantFromStringVector +@ stdcall InitPropVariantFromStringVector(ptr long ptr) @ stub InitPropVariantFromUInt16Vector @ stub InitPropVariantFromUInt32Vector @ stub InitPropVariantFromUInt64Vector @@ -50,7 +50,7 @@ @ stub InitVariantFromBooleanArray @ stdcall InitVariantFromBuffer(ptr long ptr) @ stub InitVariantFromDoubleArray -@ stub InitVariantFromFileTime +@ stdcall InitVariantFromFileTime(ptr ptr) @ stub InitVariantFromFileTimeArray @ stdcall InitVariantFromGUIDAsString(ptr ptr) @ stub InitVariantFromInt16Array @@ -69,7 +69,7 @@ @ stdcall PSCreateMemoryPropertyStore(ptr ptr) @ stub PSCreateMultiplexPropertyStore @ stub PSCreatePropertyChangeArray -@ stub PSCreatePropertyStoreFromObject +@ stdcall PSCreatePropertyStoreFromObject(ptr long ptr ptr) @ stub PSCreatePropertyStoreFromPropertySetStorage @ stub PSCreateSimplePropertyChange @ stub PSEnumeratePropertyDescriptions @@ -107,7 +107,7 @@ @ stub PropVariantGetUInt16Elem @ stub PropVariantGetUInt32Elem @ stub PropVariantGetUInt64Elem -@ stub PropVariantToBSTR +@ stdcall PropVariantToBSTR(ptr ptr) @ stdcall PropVariantToBoolean(ptr ptr) @ stub PropVariantToBooleanVector @ stub PropVariantToBooleanVectorAlloc @@ -146,12 +146,12 @@ @ stdcall PropVariantToUInt32(ptr ptr) @ stub PropVariantToUInt32Vector @ stub PropVariantToUInt32VectorAlloc -@ stub PropVariantToUInt32WithDefault +@ stdcall PropVariantToUInt32WithDefault(ptr long) @ stdcall PropVariantToUInt64(ptr ptr) @ stub PropVariantToUInt64Vector @ stub PropVariantToUInt64VectorAlloc @ stub PropVariantToUInt64WithDefault -@ stub PropVariantToVariant +@ stdcall PropVariantToVariant(ptr ptr) @ stub StgDeserializePropVariant @ stub StgSerializePropVariant @ stub VariantCompare @@ -189,13 +189,13 @@ @ stub VariantToInt64Array @ stub VariantToInt64ArrayAlloc @ stub VariantToInt64WithDefault -@ stub VariantToPropVariant +@ stdcall VariantToPropVariant(ptr ptr) @ stub VariantToStrRet -@ stub VariantToString +@ stdcall VariantToString(ptr ptr long) @ stub VariantToStringAlloc @ stub VariantToStringArray @ stub VariantToStringArrayAlloc -@ stub VariantToStringWithDefault +@ stdcall VariantToStringWithDefault(ptr wstr) @ stub VariantToUInt16 @ stub VariantToUInt16Array @ stub VariantToUInt16ArrayAlloc diff --git a/dll/win32/propsys/propsys_main.c b/dll/win32/propsys/propsys_main.c index 6f7dc8a397c1a..5557131ed4b1e 100644 --- a/dll/win32/propsys/propsys_main.c +++ b/dll/win32/propsys/propsys_main.c @@ -22,9 +22,6 @@ #define COBJMACROS #include -#ifdef __REACTOS__ -#include -#endif #include "windef.h" #include "winbase.h" @@ -37,35 +34,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(propsys); -static HINSTANCE propsys_hInstance; - -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) -{ - TRACE("(0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved); - - switch (fdwReason) - { - case DLL_WINE_PREATTACH: - return FALSE; /* prefer native version */ - case DLL_PROCESS_ATTACH: - propsys_hInstance = hinstDLL; - DisableThreadLibraryCalls(hinstDLL); - break; - } - - return TRUE; -} - -HRESULT WINAPI DllRegisterServer(void) -{ - return __wine_register_resources( propsys_hInstance ); -} - -HRESULT WINAPI DllUnregisterServer(void) -{ - return __wine_unregister_resources( propsys_hInstance ); -} - static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv) { *ppv = NULL; @@ -135,11 +103,6 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) return CLASS_E_CLASSNOTAVAILABLE; } -HRESULT WINAPI DllCanUnloadNow(void) -{ - return S_FALSE; -} - static HRESULT WINAPI propsys_QueryInterface(IPropertySystem *iface, REFIID riid, void **obj) { *obj = NULL; @@ -194,7 +157,7 @@ static HRESULT WINAPI propsys_FormatForDisplay(IPropertySystem *iface, REFPROPERTYKEY key, REFPROPVARIANT propvar, PROPDESC_FORMAT_FLAGS flags, LPWSTR dest, DWORD destlen) { - FIXME("%p %p %x %p %d: stub\n", key, propvar, flags, dest, destlen); + FIXME("%p %p %x %p %ld: stub\n", key, propvar, flags, dest, destlen); return E_NOTIMPL; } @@ -283,12 +246,6 @@ HRESULT WINAPI PSRefreshPropertySchema(void) HRESULT WINAPI PSStringFromPropertyKey(REFPROPERTYKEY pkey, LPWSTR psz, UINT cch) { - static const WCHAR guid_fmtW[] = {'{','%','0','8','X','-','%','0','4','X','-', - '%','0','4','X','-','%','0','2','X','%','0','2','X','-', - '%','0','2','X','%','0','2','X','%','0','2','X', - '%','0','2','X','%','0','2','X','%','0','2','X','}',0}; - static const WCHAR pid_fmtW[] = {'%','u',0}; - WCHAR pidW[PKEY_PIDSTR_MAX + 1]; LPWSTR p = psz; int len; @@ -308,8 +265,8 @@ HRESULT WINAPI PSStringFromPropertyKey(REFPROPERTYKEY pkey, LPWSTR psz, UINT cch return E_NOT_SUFFICIENT_BUFFER; } - swprintf(psz, guid_fmtW, pkey->fmtid.Data1, pkey->fmtid.Data2, - pkey->fmtid.Data3, pkey->fmtid.Data4[0], pkey->fmtid.Data4[1], + swprintf(psz, cch, L"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", pkey->fmtid.Data1, + pkey->fmtid.Data2, pkey->fmtid.Data3, pkey->fmtid.Data4[0], pkey->fmtid.Data4[1], pkey->fmtid.Data4[2], pkey->fmtid.Data4[3], pkey->fmtid.Data4[4], pkey->fmtid.Data4[5], pkey->fmtid.Data4[6], pkey->fmtid.Data4[7]); @@ -318,7 +275,7 @@ HRESULT WINAPI PSStringFromPropertyKey(REFPROPERTYKEY pkey, LPWSTR psz, UINT cch *p++ = ' '; cch -= GUIDSTRING_MAX - 1 + 1; - len = swprintf(pidW, pid_fmtW, pkey->pid); + len = swprintf(pidW, ARRAY_SIZE(pidW), L"%u", pkey->pid); if (cch >= len + 1) { @@ -498,7 +455,7 @@ HRESULT WINAPI PSPropertyKeyFromString(LPCWSTR pszString, PROPERTYKEY *pkey) } /* Overflow is not checked. */ - while (iswdigit(*pszString)) + while ('0' <= *pszString && *pszString <= '9') { pkey->pid *= 10; pkey->pid += (*pszString - '0'); @@ -517,3 +474,10 @@ HRESULT WINAPI PSCreateMemoryPropertyStore(REFIID riid, void **ppv) return PropertyStore_CreateInstance(NULL, riid, ppv); } + +#ifdef __REACTOS__ +HRESULT WINAPI DllCanUnloadNow(void) +{ + return S_FALSE; +} +#endif diff --git a/dll/win32/propsys/propsys_private.h b/dll/win32/propsys/propsys_private.h index d43de7534d26e..a91b5c5c2894c 100644 --- a/dll/win32/propsys/propsys_private.h +++ b/dll/win32/propsys/propsys_private.h @@ -20,4 +20,4 @@ #pragma once -HRESULT PropertyStore_CreateInstance(IUnknown *outer, REFIID riid, void **ppv) DECLSPEC_HIDDEN; +HRESULT PropertyStore_CreateInstance(IUnknown *outer, REFIID riid, void **ppv); diff --git a/dll/win32/propsys/propvar.c b/dll/win32/propsys/propvar.c index f03dc148435e0..e1375134f115d 100644 --- a/dll/win32/propsys/propvar.c +++ b/dll/win32/propsys/propvar.c @@ -23,8 +23,6 @@ #include #include -#define NONAMELESSUNION - #include "windef.h" #include "winbase.h" #include "winerror.h" @@ -33,11 +31,31 @@ #include "shlobj.h" #include "propvarutil.h" #include "strsafe.h" - #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(propsys); +#define GUID_STR_LEN 38 +static HRESULT VARIANT_ValidateType(VARTYPE vt) +{ + VARTYPE vtExtra = vt & (VT_VECTOR | VT_ARRAY | VT_BYREF | VT_RESERVED); + + vt &= VT_TYPEMASK; + + if (!(vtExtra & (VT_VECTOR | VT_RESERVED))) + { + if (vt < VT_VOID || vt == VT_RECORD || vt == VT_CLSID) + { + if ((vtExtra & (VT_BYREF | VT_ARRAY)) && vt <= VT_NULL) + return DISP_E_BADVARTYPE; + if (vt != (VARTYPE)15) + return S_OK; + } + } + + return DISP_E_BADVARTYPE; +} + static HRESULT PROPVAR_ConvertFILETIME(const FILETIME *ft, PROPVARIANT *ppropvarDest, VARTYPE vt) { SYSTEMTIME time; @@ -47,11 +65,11 @@ static HRESULT PROPVAR_ConvertFILETIME(const FILETIME *ft, PROPVARIANT *ppropvar switch (vt) { case VT_LPSTR: - ppropvarDest->u.pszVal = HeapAlloc(GetProcessHeap(), 0, 64); - if (!ppropvarDest->u.pszVal) + ppropvarDest->pszVal = HeapAlloc(GetProcessHeap(), 0, 64); + if (!ppropvarDest->pszVal) return E_OUTOFMEMORY; - sprintf( ppropvarDest->u.pszVal, "%04d/%02d/%02d:%02d:%02d:%02d.%03d", + sprintf( ppropvarDest->pszVal, "%04d/%02d/%02d:%02d:%02d:%02d.%03d", time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond, time.wMilliseconds ); @@ -74,35 +92,35 @@ static HRESULT PROPVAR_ConvertNumber(REFPROPVARIANT pv, int dest_bits, { case VT_I1: src_signed = TRUE; - *res = pv->u.cVal; + *res = pv->cVal; break; case VT_UI1: src_signed = FALSE; - *res = pv->u.bVal; + *res = pv->bVal; break; case VT_I2: src_signed = TRUE; - *res = pv->u.iVal; + *res = pv->iVal; break; case VT_UI2: src_signed = FALSE; - *res = pv->u.uiVal; + *res = pv->uiVal; break; case VT_I4: src_signed = TRUE; - *res = pv->u.lVal; + *res = pv->lVal; break; case VT_UI4: src_signed = FALSE; - *res = pv->u.ulVal; + *res = pv->ulVal; break; case VT_I8: src_signed = TRUE; - *res = pv->u.hVal.QuadPart; + *res = pv->hVal.QuadPart; break; case VT_UI8: src_signed = FALSE; - *res = pv->u.uhVal.QuadPart; + *res = pv->uhVal.QuadPart; break; case VT_EMPTY: src_signed = FALSE; @@ -111,8 +129,12 @@ static HRESULT PROPVAR_ConvertNumber(REFPROPVARIANT pv, int dest_bits, case VT_LPSTR: { char *end; - *res = _strtoi64(pv->u.pszVal, &end, 0); - if (pv->u.pszVal == end) +#ifdef __REACTOS__ + *res = _strtoi64(pv->pszVal, &end, 0); +#else + *res = strtoll(pv->pszVal, &end, 0); +#endif + if (pv->pszVal == end) return DISP_E_TYPEMISMATCH; src_signed = *res < 0; break; @@ -121,8 +143,8 @@ static HRESULT PROPVAR_ConvertNumber(REFPROPVARIANT pv, int dest_bits, case VT_BSTR: { WCHAR *end; - *res = wcstol(pv->u.pwszVal, &end, 0); - if (pv->u.pwszVal == end) + *res = wcstol(pv->pwszVal, &end, 0); + if (pv->pwszVal == end) return DISP_E_TYPEMISMATCH; src_signed = *res < 0; break; @@ -130,7 +152,7 @@ static HRESULT PROPVAR_ConvertNumber(REFPROPVARIANT pv, int dest_bits, case VT_R8: { src_signed = TRUE; - *res = pv->u.dblVal; + *res = pv->dblVal; break; } default: @@ -231,6 +253,20 @@ HRESULT WINAPI PropVariantToUInt32(REFPROPVARIANT propvarIn, ULONG *ret) return hr; } +ULONG WINAPI PropVariantToUInt32WithDefault(REFPROPVARIANT propvarIn, ULONG ulDefault) +{ + LONGLONG res; + HRESULT hr; + + TRACE("%p,%lu\n", propvarIn, ulDefault); + + hr = PROPVAR_ConvertNumber(propvarIn, 32, FALSE, &res); + if (SUCCEEDED(hr)) + return (ULONG)res; + + return ulDefault; +} + HRESULT WINAPI PropVariantToUInt64(REFPROPVARIANT propvarIn, ULONGLONG *ret) { LONGLONG res; @@ -245,10 +281,6 @@ HRESULT WINAPI PropVariantToUInt64(REFPROPVARIANT propvarIn, ULONGLONG *ret) HRESULT WINAPI PropVariantToBoolean(REFPROPVARIANT propvarIn, BOOL *ret) { - static const WCHAR trueW[] = {'t','r','u','e',0}; - static const WCHAR falseW[] = {'f','a','l','s','e',0}; - static const WCHAR true2W[] = {'#','T','R','U','E','#',0}; - static const WCHAR false2W[] = {'#','F','A','L','S','E','#',0}; LONGLONG res; HRESULT hr; @@ -259,21 +291,21 @@ HRESULT WINAPI PropVariantToBoolean(REFPROPVARIANT propvarIn, BOOL *ret) switch (propvarIn->vt) { case VT_BOOL: - *ret = propvarIn->u.boolVal == VARIANT_TRUE; + *ret = propvarIn->boolVal == VARIANT_TRUE; return S_OK; case VT_LPWSTR: case VT_BSTR: - if (!propvarIn->u.pwszVal) + if (!propvarIn->pwszVal) return DISP_E_TYPEMISMATCH; - if (!lstrcmpiW(propvarIn->u.pwszVal, trueW) || !lstrcmpW(propvarIn->u.pwszVal, true2W)) + if (!lstrcmpiW(propvarIn->pwszVal, L"true") || !lstrcmpW(propvarIn->pwszVal, L"#TRUE#")) { *ret = TRUE; return S_OK; } - if (!lstrcmpiW(propvarIn->u.pwszVal, falseW) || !lstrcmpW(propvarIn->u.pwszVal, false2W)) + if (!lstrcmpiW(propvarIn->pwszVal, L"false") || !lstrcmpW(propvarIn->pwszVal, L"#FALSE#")) { *ret = FALSE; return S_OK; @@ -281,16 +313,16 @@ HRESULT WINAPI PropVariantToBoolean(REFPROPVARIANT propvarIn, BOOL *ret) break; case VT_LPSTR: - if (!propvarIn->u.pszVal) + if (!propvarIn->pszVal) return DISP_E_TYPEMISMATCH; - if (!lstrcmpiA(propvarIn->u.pszVal, "true") || !lstrcmpA(propvarIn->u.pszVal, "#TRUE#")) + if (!lstrcmpiA(propvarIn->pszVal, "true") || !lstrcmpA(propvarIn->pszVal, "#TRUE#")) { *ret = TRUE; return S_OK; } - if (!lstrcmpiA(propvarIn->u.pszVal, "false") || !lstrcmpA(propvarIn->u.pszVal, "#FALSE#")) + if (!lstrcmpiA(propvarIn->pszVal, "false") || !lstrcmpA(propvarIn->pszVal, "#FALSE#")) { *ret = FALSE; return S_OK; @@ -303,6 +335,26 @@ HRESULT WINAPI PropVariantToBoolean(REFPROPVARIANT propvarIn, BOOL *ret) return hr; } +HRESULT WINAPI PropVariantToBSTR(REFPROPVARIANT propvar, BSTR *bstr) +{ + WCHAR *str; + HRESULT hr; + + TRACE("propvar %p, propvar->vt %#x, bstr %p.\n", + propvar, propvar ? propvar->vt : 0, bstr); + + if (FAILED(hr = PropVariantToStringAlloc(propvar, &str))) + return hr; + + *bstr = SysAllocString(str); + CoTaskMemFree(str); + + if (!*bstr) + return E_OUTOFMEMORY; + + return S_OK; +} + HRESULT WINAPI PropVariantToBuffer(REFPROPVARIANT propvarIn, void *ret, UINT cb) { HRESULT hr = S_OK; @@ -312,9 +364,9 @@ HRESULT WINAPI PropVariantToBuffer(REFPROPVARIANT propvarIn, void *ret, UINT cb) switch(propvarIn->vt) { case VT_VECTOR|VT_UI1: - if(cb > propvarIn->u.caub.cElems) + if(cb > propvarIn->caub.cElems) return E_FAIL; - memcpy(ret, propvarIn->u.caub.pElems, cb); + memcpy(ret, propvarIn->caub.pElems, cb); break; case VT_ARRAY|VT_UI1: FIXME("Unsupported type: VT_ARRAY|VT_UI1\n"); @@ -328,7 +380,6 @@ HRESULT WINAPI PropVariantToBuffer(REFPROPVARIANT propvarIn, void *ret, UINT cb) return hr; } - HRESULT WINAPI PropVariantToString(REFPROPVARIANT propvarIn, PWSTR ret, UINT cch) { HRESULT hr; @@ -369,27 +420,36 @@ HRESULT WINAPI PropVariantToStringAlloc(REFPROPVARIANT propvarIn, WCHAR **ret) break; case VT_LPSTR: - if(propvarIn->u.pszVal) + if(propvarIn->pszVal) { DWORD len; - len = MultiByteToWideChar(CP_ACP, 0, propvarIn->u.pszVal, -1, NULL, 0); + len = MultiByteToWideChar(CP_ACP, 0, propvarIn->pszVal, -1, NULL, 0); res = CoTaskMemAlloc(len*sizeof(WCHAR)); if(!res) return E_OUTOFMEMORY; - MultiByteToWideChar(CP_ACP, 0, propvarIn->u.pszVal, -1, res, len); + MultiByteToWideChar(CP_ACP, 0, propvarIn->pszVal, -1, res, len); } break; case VT_LPWSTR: case VT_BSTR: - if (propvarIn->u.pwszVal) + if (propvarIn->pwszVal) { - DWORD size = (lstrlenW(propvarIn->u.pwszVal) + 1) * sizeof(WCHAR); + DWORD size = (lstrlenW(propvarIn->pwszVal) + 1) * sizeof(WCHAR); res = CoTaskMemAlloc(size); if(!res) return E_OUTOFMEMORY; - memcpy(res, propvarIn->u.pwszVal, size); + memcpy(res, propvarIn->pwszVal, size); + } + break; + + case VT_CLSID: + if (propvarIn->puuid) + { + if (!(res = CoTaskMemAlloc((GUID_STR_LEN + 1) * sizeof(WCHAR)))) + return E_OUTOFMEMORY; + StringFromGUID2(propvarIn->puuid, res, GUID_STR_LEN + 1); } break; @@ -406,21 +466,70 @@ HRESULT WINAPI PropVariantToStringAlloc(REFPROPVARIANT propvarIn, WCHAR **ret) PCWSTR WINAPI PropVariantToStringWithDefault(REFPROPVARIANT propvarIn, LPCWSTR pszDefault) { - static const WCHAR str_empty[] = {0}; if (propvarIn->vt == VT_BSTR) { - if (propvarIn->u.bstrVal == NULL) - return str_empty; + if (propvarIn->bstrVal == NULL) + return L""; - return propvarIn->u.bstrVal; + return propvarIn->bstrVal; } - if (propvarIn->vt == VT_LPWSTR && propvarIn->u.pwszVal != NULL) - return propvarIn->u.pwszVal; + if (propvarIn->vt == VT_LPWSTR && propvarIn->pwszVal != NULL) + return propvarIn->pwszVal; return pszDefault; } +/****************************************************************** + * VariantToStringWithDefault (PROPSYS.@) + */ +PCWSTR WINAPI VariantToStringWithDefault(const VARIANT *pvar, const WCHAR *default_value) +{ + TRACE("%s, %s.\n", debugstr_variant(pvar), debugstr_w(default_value)); + + if (V_VT(pvar) == (VT_BYREF | VT_VARIANT)) pvar = V_VARIANTREF(pvar); + if (V_VT(pvar) == (VT_BYREF | VT_BSTR) || V_VT(pvar) == VT_BSTR) + { + BSTR ret = V_ISBYREF(pvar) ? *V_BSTRREF(pvar) : V_BSTR(pvar); + return ret ? ret : L""; + } + + return default_value; +} + +/****************************************************************** + * VariantToString (PROPSYS.@) + */ +HRESULT WINAPI VariantToString(REFVARIANT var, PWSTR ret, UINT cch) +{ + WCHAR buffer[64], *str = buffer; + + TRACE("%p, %p, %u.\n", var, ret, cch); + + *ret = 0; + + if (!cch) + return E_INVALIDARG; + + switch (V_VT(var)) + { + case VT_BSTR: + str = V_BSTR(var); + break; + case VT_I4: + swprintf(buffer, ARRAY_SIZE(buffer), L"%d", V_I4(var)); + break; + default: + FIXME("Unsupported type %d.\n", V_VT(var)); + return E_NOTIMPL; + } + + if (wcslen(str) > cch - 1) + return STRSAFE_E_INSUFFICIENT_BUFFER; + wcscpy(ret, str); + + return S_OK; +} /****************************************************************** * PropVariantChangeType (PROPSYS.@) @@ -437,7 +546,7 @@ HRESULT WINAPI PropVariantChangeType(PROPVARIANT *ppropvarDest, REFPROPVARIANT p return PropVariantCopy(ppropvarDest, propvarSrc); if (propvarSrc->vt == VT_FILETIME) - return PROPVAR_ConvertFILETIME(&propvarSrc->u.filetime, ppropvarDest, vt); + return PROPVAR_ConvertFILETIME(&propvarSrc->filetime, ppropvarDest, vt); switch (vt) { @@ -449,7 +558,7 @@ HRESULT WINAPI PropVariantChangeType(PROPVARIANT *ppropvarDest, REFPROPVARIANT p if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_I1; - ppropvarDest->u.cVal = (char)res; + ppropvarDest->cVal = (char)res; } return hr; } @@ -462,7 +571,7 @@ HRESULT WINAPI PropVariantChangeType(PROPVARIANT *ppropvarDest, REFPROPVARIANT p if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_UI1; - ppropvarDest->u.bVal = (UCHAR)res; + ppropvarDest->bVal = (UCHAR)res; } return hr; } @@ -474,7 +583,7 @@ HRESULT WINAPI PropVariantChangeType(PROPVARIANT *ppropvarDest, REFPROPVARIANT p if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_I2; - ppropvarDest->u.iVal = res; + ppropvarDest->iVal = res; } return hr; } @@ -485,7 +594,7 @@ HRESULT WINAPI PropVariantChangeType(PROPVARIANT *ppropvarDest, REFPROPVARIANT p if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_UI2; - ppropvarDest->u.uiVal = res; + ppropvarDest->uiVal = res; } return hr; } @@ -496,7 +605,7 @@ HRESULT WINAPI PropVariantChangeType(PROPVARIANT *ppropvarDest, REFPROPVARIANT p if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_I4; - ppropvarDest->u.lVal = res; + ppropvarDest->lVal = res; } return hr; } @@ -507,7 +616,7 @@ HRESULT WINAPI PropVariantChangeType(PROPVARIANT *ppropvarDest, REFPROPVARIANT p if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_UI4; - ppropvarDest->u.ulVal = res; + ppropvarDest->ulVal = res; } return hr; } @@ -518,7 +627,7 @@ HRESULT WINAPI PropVariantChangeType(PROPVARIANT *ppropvarDest, REFPROPVARIANT p if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_I8; - ppropvarDest->u.hVal.QuadPart = res; + ppropvarDest->hVal.QuadPart = res; } return hr; } @@ -529,7 +638,7 @@ HRESULT WINAPI PropVariantChangeType(PROPVARIANT *ppropvarDest, REFPROPVARIANT p if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_UI8; - ppropvarDest->u.uhVal.QuadPart = res; + ppropvarDest->uhVal.QuadPart = res; } return hr; } @@ -542,7 +651,7 @@ HRESULT WINAPI PropVariantChangeType(PROPVARIANT *ppropvarDest, REFPROPVARIANT p if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_LPWSTR; - ppropvarDest->u.pwszVal = res; + ppropvarDest->pwszVal = res; } return hr; } @@ -562,7 +671,7 @@ HRESULT WINAPI PropVariantChangeType(PROPVARIANT *ppropvarDest, REFPROPVARIANT p { WideCharToMultiByte(CP_ACP, 0, resW, -1, res, len, NULL, NULL); ppropvarDest->vt = VT_LPSTR; - ppropvarDest->u.pszVal = res; + ppropvarDest->pszVal = res; } else hr = E_OUTOFMEMORY; @@ -577,18 +686,6 @@ HRESULT WINAPI PropVariantChangeType(PROPVARIANT *ppropvarDest, REFPROPVARIANT p return E_FAIL; } } - -static void PROPVAR_GUIDToWSTR(REFGUID guid, WCHAR *str) -{ - static const WCHAR format[] = {'{','%','0','8','X','-','%','0','4','X','-','%','0','4','X', - '-','%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','%','0','2','X', - '%','0','2','X','%','0','2','X','%','0','2','X','}',0}; - - swprintf(str, format, guid->Data1, guid->Data2, guid->Data3, - guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3], - guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]); -} - HRESULT WINAPI InitPropVariantFromGUIDAsString(REFGUID guid, PROPVARIANT *ppropvar) { TRACE("(%p %p)\n", guid, ppropvar); @@ -597,11 +694,11 @@ HRESULT WINAPI InitPropVariantFromGUIDAsString(REFGUID guid, PROPVARIANT *ppropv return E_FAIL; ppropvar->vt = VT_LPWSTR; - ppropvar->u.pwszVal = CoTaskMemAlloc(39*sizeof(WCHAR)); - if(!ppropvar->u.pwszVal) + ppropvar->pwszVal = CoTaskMemAlloc((GUID_STR_LEN + 1) * sizeof(WCHAR)); + if(!ppropvar->pwszVal) return E_OUTOFMEMORY; - PROPVAR_GUIDToWSTR(guid, ppropvar->u.pwszVal); + StringFromGUID2(guid, ppropvar->pwszVal, GUID_STR_LEN + 1); return S_OK; } @@ -615,11 +712,11 @@ HRESULT WINAPI InitVariantFromGUIDAsString(REFGUID guid, VARIANT *pvar) } V_VT(pvar) = VT_BSTR; - V_BSTR(pvar) = SysAllocStringLen(NULL, 38); + V_BSTR(pvar) = SysAllocStringLen(NULL, GUID_STR_LEN); if(!V_BSTR(pvar)) return E_OUTOFMEMORY; - PROPVAR_GUIDToWSTR(guid, V_BSTR(pvar)); + StringFromGUID2(guid, V_BSTR(pvar), GUID_STR_LEN + 1); return S_OK; } @@ -627,13 +724,13 @@ HRESULT WINAPI InitPropVariantFromBuffer(const VOID *pv, UINT cb, PROPVARIANT *p { TRACE("(%p %u %p)\n", pv, cb, ppropvar); - ppropvar->u.caub.pElems = CoTaskMemAlloc(cb); - if(!ppropvar->u.caub.pElems) + ppropvar->caub.pElems = CoTaskMemAlloc(cb); + if(!ppropvar->caub.pElems) return E_OUTOFMEMORY; ppropvar->vt = VT_VECTOR|VT_UI1; - ppropvar->u.caub.cElems = cb; - memcpy(ppropvar->u.caub.pElems, pv, cb); + ppropvar->caub.cElems = cb; + memcpy(ppropvar->caub.pElems, pv, cb); return S_OK; } @@ -641,12 +738,44 @@ HRESULT WINAPI InitPropVariantFromCLSID(REFCLSID clsid, PROPVARIANT *ppropvar) { TRACE("(%s %p)\n", debugstr_guid(clsid), ppropvar); - ppropvar->u.puuid = CoTaskMemAlloc(sizeof(*ppropvar->u.puuid)); - if(!ppropvar->u.puuid) + ppropvar->puuid = CoTaskMemAlloc(sizeof(*ppropvar->puuid)); + if(!ppropvar->puuid) return E_OUTOFMEMORY; ppropvar->vt = VT_CLSID; - memcpy(ppropvar->u.puuid, clsid, sizeof(*ppropvar->u.puuid)); + memcpy(ppropvar->puuid, clsid, sizeof(*ppropvar->puuid)); + return S_OK; +} + +HRESULT WINAPI InitPropVariantFromStringVector(PCWSTR *strs, ULONG count, PROPVARIANT *ppropvar) +{ + unsigned int i; + + TRACE("(%p %lu %p)\n", strs, count, ppropvar); + + ppropvar->calpwstr.pElems = CoTaskMemAlloc(count * sizeof(*ppropvar->calpwstr.pElems)); + if(!ppropvar->calpwstr.pElems) + return E_OUTOFMEMORY; + + ppropvar->vt = VT_LPWSTR | VT_VECTOR; + ppropvar->calpwstr.cElems = 0; + if (count) + memset(ppropvar->calpwstr.pElems, 0, count * sizeof(*ppropvar->calpwstr.pElems)); + + for (i = 0; i < count; ++i) + { + if (strs[i]) + { + if (!(ppropvar->calpwstr.pElems[i] = CoTaskMemAlloc((wcslen(strs[i]) + 1)*sizeof(**strs)))) + { + PropVariantClear(ppropvar); + return E_OUTOFMEMORY; + } + } + wcscpy(ppropvar->calpwstr.pElems[i], strs[i]); + ppropvar->calpwstr.cElems++; + } + return S_OK; } @@ -681,6 +810,21 @@ HRESULT WINAPI InitVariantFromBuffer(const VOID *pv, UINT cb, VARIANT *pvar) return S_OK; } +HRESULT WINAPI InitVariantFromFileTime(const FILETIME *ft, VARIANT *var) +{ + SYSTEMTIME st; + + TRACE("%p, %p\n", ft, var); + + VariantInit(var); + if (!FileTimeToSystemTime(ft, &st)) + return E_INVALIDARG; + if (!SystemTimeToVariantTime(&st, &V_DATE(var))) + return E_INVALIDARG; + V_VT(var) = VT_DATE; + return S_OK; +} + static inline DWORD PROPVAR_HexToNum(const WCHAR *hex) { DWORD ret; @@ -759,11 +903,11 @@ HRESULT WINAPI PropVariantToGUID(const PROPVARIANT *ppropvar, GUID *guid) switch(ppropvar->vt) { case VT_BSTR: - return PROPVAR_WCHARToGUID(ppropvar->u.bstrVal, SysStringLen(ppropvar->u.bstrVal), guid); + return PROPVAR_WCHARToGUID(ppropvar->bstrVal, SysStringLen(ppropvar->bstrVal), guid); case VT_LPWSTR: - return PROPVAR_WCHARToGUID(ppropvar->u.pwszVal, lstrlenW(ppropvar->u.pwszVal), guid); + return PROPVAR_WCHARToGUID(ppropvar->pwszVal, lstrlenW(ppropvar->pwszVal), guid); case VT_CLSID: - memcpy(guid, ppropvar->u.puuid, sizeof(*ppropvar->u.puuid)); + memcpy(guid, ppropvar->puuid, sizeof(*ppropvar->puuid)); return S_OK; default: @@ -797,17 +941,20 @@ static BOOL isemptyornull(const PROPVARIANT *propvar) if ((propvar->vt & VT_ARRAY) == VT_ARRAY) { int i; - for (i=0; iu.parray->cDims; i++) + for (i=0; iparray->cDims; i++) { - if (propvar->u.parray->rgsabound[i].cElements != 0) + if (propvar->parray->rgsabound[i].cElements != 0) break; } - return i == propvar->u.parray->cDims; + return i == propvar->parray->cDims; } if (propvar->vt == VT_CLSID) - return !propvar->u.puuid; + return !propvar->puuid; + + if (propvar->vt & VT_VECTOR) + return !propvar->caub.cElems; - /* FIXME: vectors, byrefs, errors? */ + /* FIXME: byrefs, errors? */ return FALSE; } @@ -816,6 +963,7 @@ INT WINAPI PropVariantCompareEx(REFPROPVARIANT propvar1, REFPROPVARIANT propvar2 { const PROPVARIANT *propvar2_converted; PROPVARIANT propvar2_static; + unsigned int count; HRESULT hr; INT res=-1; @@ -844,9 +992,9 @@ INT WINAPI PropVariantCompareEx(REFPROPVARIANT propvar1, REFPROPVARIANT propvar2 propvar2_converted = propvar2; #define CMP_NUM_VALUE(var) do { \ - if (propvar1->u.var > propvar2_converted->u.var) \ + if (propvar1->var > propvar2_converted->var) \ res = 1; \ - else if (propvar1->u.var < propvar2_converted->u.var) \ + else if (propvar1->var < propvar2_converted->var) \ res = -1; \ else \ res = 0; \ @@ -870,7 +1018,7 @@ INT WINAPI PropVariantCompareEx(REFPROPVARIANT propvar1, REFPROPVARIANT propvar2 CMP_NUM_VALUE(lVal); break; case VT_UI4: - CMP_NUM_VALUE(uiVal); + CMP_NUM_VALUE(ulVal); break; case VT_I8: CMP_NUM_VALUE(hVal.QuadPart); @@ -888,20 +1036,27 @@ INT WINAPI PropVariantCompareEx(REFPROPVARIANT propvar1, REFPROPVARIANT propvar2 case VT_LPWSTR: /* FIXME: Use other string flags. */ if (flags & (PVCF_USESTRCMPI | PVCF_USESTRCMPIC)) - res = lstrcmpiW(propvar1->u.bstrVal, propvar2_converted->u.bstrVal); + res = lstrcmpiW(propvar1->bstrVal, propvar2_converted->bstrVal); else - res = lstrcmpW(propvar1->u.bstrVal, propvar2_converted->u.bstrVal); + res = lstrcmpW(propvar1->bstrVal, propvar2_converted->bstrVal); break; case VT_LPSTR: /* FIXME: Use other string flags. */ if (flags & (PVCF_USESTRCMPI | PVCF_USESTRCMPIC)) - res = lstrcmpiA(propvar1->u.pszVal, propvar2_converted->u.pszVal); + res = lstrcmpiA(propvar1->pszVal, propvar2_converted->pszVal); else - res = lstrcmpA(propvar1->u.pszVal, propvar2_converted->u.pszVal); + res = lstrcmpA(propvar1->pszVal, propvar2_converted->pszVal); break; case VT_CLSID: - res = memcmp(propvar1->u.puuid, propvar2->u.puuid, sizeof(*propvar1->u.puuid)); + res = memcmp(propvar1->puuid, propvar2->puuid, sizeof(*propvar1->puuid)); + if (res) res = res > 0 ? 1 : -1; + break; + case VT_VECTOR | VT_UI1: + count = min(propvar1->caub.cElems, propvar2->caub.cElems); + res = count ? memcmp(propvar1->caub.pElems, propvar2->caub.pElems, sizeof(*propvar1->caub.pElems) * count) : 0; if (res) res = res > 0 ? 1 : -1; + if (!res && propvar1->caub.cElems != propvar2->caub.cElems) + res = propvar1->caub.cElems > propvar2->caub.cElems ? 1 : -1; break; default: FIXME("vartype %#x not handled\n", propvar1->vt); @@ -914,3 +1069,158 @@ INT WINAPI PropVariantCompareEx(REFPROPVARIANT propvar1, REFPROPVARIANT propvar2 return res; } + +HRESULT WINAPI PropVariantToVariant(const PROPVARIANT *propvar, VARIANT *var) +{ + HRESULT hr = S_OK; + + TRACE("propvar %p, var %p, propvar->vt %#x.\n", propvar, var, propvar ? propvar->vt : 0); + + if (!var || !propvar) + return E_INVALIDARG; + + VariantInit(var); +#ifdef __REACTOS__ + V_VT(var) = propvar->vt; +#else + var->vt = propvar->vt; +#endif + + switch (propvar->vt) + { + case VT_EMPTY: + case VT_NULL: + break; + case VT_I1: + V_I1(var) = propvar->cVal; + break; + case VT_I2: + V_I2(var) = propvar->iVal; + break; + case VT_I4: + V_I4(var) = propvar->lVal; + break; + case VT_I8: + V_I8(var) = propvar->hVal.QuadPart; + break; + case VT_UI1: + V_UI1(var) = propvar->bVal; + break; + case VT_UI2: + V_UI2(var) = propvar->uiVal; + break; + case VT_UI4: + V_UI4(var) = propvar->ulVal; + break; + case VT_UI8: + V_UI8(var) = propvar->uhVal.QuadPart; + break; + case VT_BOOL: + V_BOOL(var) = propvar->boolVal; + break; + case VT_R4: + V_R4(var) = propvar->fltVal; + break; + case VT_R8: + V_R8(var) = propvar->dblVal; + break; + case VT_LPSTR: + case VT_LPWSTR: + case VT_BSTR: + case VT_CLSID: +#ifdef __REACTOS__ + V_VT(var) = VT_BSTR; +#else + var->vt = VT_BSTR; +#endif + hr = PropVariantToBSTR(propvar, &V_BSTR(var)); + break; + default: + FIXME("Unsupported type %d.\n", propvar->vt); + return E_INVALIDARG; + } + + return hr; +} + +HRESULT WINAPI VariantToPropVariant(const VARIANT *var, PROPVARIANT *propvar) +{ + HRESULT hr; + + TRACE("var %p, propvar %p.\n", debugstr_variant(var), propvar); + + if (!var || !propvar) + return E_INVALIDARG; + +#ifdef __REACTOS__ + if (FAILED(hr = VARIANT_ValidateType(V_VT(var)))) +#else + if (FAILED(hr = VARIANT_ValidateType(var->vt))) +#endif + return hr; + + PropVariantInit(propvar); + + +#ifdef __REACTOS__ + propvar->vt = V_VT(var); +#else + propvar->vt = var->vt; +#endif + +#ifdef __REACTOS__ + switch (V_VT(var)) +#else + switch (var->vt) +#endif + { + case VT_EMPTY: + case VT_NULL: + break; + case VT_I1: + propvar->cVal = V_I1(var); + break; + case VT_I2: + propvar->iVal = V_I2(var); + break; + case VT_I4: + propvar->lVal = V_I4(var); + break; + case VT_I8: + propvar->hVal.QuadPart = V_I8(var); + break; + case VT_UI1: + propvar->bVal = V_UI1(var); + break; + case VT_UI2: + propvar->uiVal = V_UI2(var); + break; + case VT_UI4: + propvar->ulVal = V_UI4(var); + break; + case VT_UI8: + propvar->uhVal.QuadPart = V_UI8(var); + break; + case VT_BOOL: + propvar->boolVal = V_BOOL(var); + break; + case VT_R4: + propvar->fltVal = V_R4(var); + break; + case VT_R8: + propvar->dblVal = V_R8(var); + break; + case VT_BSTR: + propvar->bstrVal = SysAllocString(V_BSTR(var)); + break; + default: +#ifdef __REACTOS__ + FIXME("Unsupported type %d.\n", V_VT(var)); +#else + FIXME("Unsupported type %d.\n", var->vt); +#endif + return E_INVALIDARG; + } + + return S_OK; +} diff --git a/dll/win32/psapi/CMakeLists.txt b/dll/win32/psapi/CMakeLists.txt index 60c1398b70e91..8a45c7b5d2e15 100644 --- a/dll/win32/psapi/CMakeLists.txt +++ b/dll/win32/psapi/CMakeLists.txt @@ -1,13 +1,17 @@ spec2def(psapi.dll psapi.spec ADD_IMPORTLIB) +list(APPEND PSAPI_STATIC_SOURCE psapi.c) +add_library(psapi_static ${PSAPI_STATIC_SOURCE}) +add_dependencies(psapi_static psdk) + list(APPEND SOURCE - psapi.c + main.c psapi.rc ${CMAKE_CURRENT_BINARY_DIR}/psapi.def) add_library(psapi MODULE ${SOURCE}) set_module_type(psapi win32dll ENTRYPOINT DllMain 12) -target_link_libraries(psapi ${PSEH_LIB}) +target_link_libraries(psapi psapi_static ${PSEH_LIB}) add_importlibs(psapi kernel32 ntdll) add_cd_file(TARGET psapi DESTINATION reactos/system32 FOR all) diff --git a/dll/win32/psapi/main.c b/dll/win32/psapi/main.c new file mode 100644 index 0000000000000..f93f2ca9c93e4 --- /dev/null +++ b/dll/win32/psapi/main.c @@ -0,0 +1,74 @@ +/* + * PROJECT: ReactOS Process Status Helper Library + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: PSAPI Win2k3 style entrypoint + * COPYRIGHT: Copyright 2013 Pierre Schweitzer + */ + +#include + +#define WIN32_NO_STATUS +#include +#include +#define NTOS_MODE_USER +#include +#include + +#include + +#define NDEBUG +#include + +static +VOID +NTAPI +PsParseCommandLine(VOID) +{ + UNIMPLEMENTED; +} + +static +VOID +NTAPI +PsInitializeAndStartProfile(VOID) +{ + UNIMPLEMENTED; +} + +static +VOID +NTAPI +PsStopAndAnalyzeProfile(VOID) +{ + UNIMPLEMENTED; +} + +/* + * @implemented + */ +BOOLEAN +WINAPI +DllMain(HINSTANCE hDllHandle, + DWORD nReason, + LPVOID Reserved) +{ + switch(nReason) + { + case DLL_PROCESS_ATTACH: + DisableThreadLibraryCalls(hDllHandle); + if (NtCurrentPeb()->ProcessParameters->Flags & RTL_USER_PROCESS_PARAMETERS_PROFILE_USER) + { + PsParseCommandLine(); + PsInitializeAndStartProfile(); + } + break; + + case DLL_PROCESS_DETACH: + if (NtCurrentPeb()->ProcessParameters->Flags & RTL_USER_PROCESS_PARAMETERS_PROFILE_USER) + { + PsStopAndAnalyzeProfile(); + } + break; + } + return TRUE; +} diff --git a/dll/win32/psapi/psapi.c b/dll/win32/psapi/psapi.c index c73f3176d3b98..bf47f8e2ceb40 100644 --- a/dll/win32/psapi/psapi.c +++ b/dll/win32/psapi/psapi.c @@ -244,67 +244,6 @@ CallBackConvertToAscii(LPVOID pContext, return Ret; } -/* - * @unimplemented - */ -static VOID NTAPI -PsParseCommandLine(VOID) -{ - UNIMPLEMENTED; -} - -/* - * @unimplemented - */ -static VOID NTAPI -PsInitializeAndStartProfile(VOID) -{ - UNIMPLEMENTED; -} - -/* - * @unimplemented - */ -static VOID NTAPI -PsStopAndAnalyzeProfile(VOID) -{ - UNIMPLEMENTED; -} - -/* PUBLIC *********************************************************************/ - -/* - * @implemented - */ -BOOLEAN -WINAPI -DllMain(HINSTANCE hDllHandle, - DWORD nReason, - LPVOID Reserved) -{ - switch(nReason) - { - case DLL_PROCESS_ATTACH: - DisableThreadLibraryCalls(hDllHandle); - if (NtCurrentPeb()->ProcessParameters->Flags & RTL_USER_PROCESS_PARAMETERS_PROFILE_USER) - { - PsParseCommandLine(); - PsInitializeAndStartProfile(); - } - break; - - case DLL_PROCESS_DETACH: - if (NtCurrentPeb()->ProcessParameters->Flags & RTL_USER_PROCESS_PARAMETERS_PROFILE_USER) - { - PsStopAndAnalyzeProfile(); - } - break; - } - - return TRUE; -} - - /* * @implemented */ diff --git a/dll/win32/pstorec/CMakeLists.txt b/dll/win32/pstorec/CMakeLists.txt index 1f168e3fbf49b..109d4123594a6 100644 --- a/dll/win32/pstorec/CMakeLists.txt +++ b/dll/win32/pstorec/CMakeLists.txt @@ -1,5 +1,4 @@ -add_definitions(-D__WINESRC__) spec2def(pstorec.dll pstorec.spec) list(APPEND SOURCE @@ -15,3 +14,4 @@ target_link_libraries(pstorec uuid wine) add_importlibs(pstorec msvcrt kernel32 ntdll) add_dependencies(pstorec stdole2) add_cd_file(TARGET pstorec DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(pstorec) # CORE-5743: No CONST_VTABLE diff --git a/dll/win32/pstorec/pstorec.c b/dll/win32/pstorec/pstorec.c index 02cd803c116ce..9dc2138accca9 100644 --- a/dll/win32/pstorec/pstorec.c +++ b/dll/win32/pstorec/pstorec.c @@ -49,8 +49,10 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD fdwReason, LPVOID fImpLoad) switch (fdwReason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hinst); break; diff --git a/dll/win32/qmgr/CMakeLists.txt b/dll/win32/qmgr/CMakeLists.txt index eea7ab2bf3372..1c3a193163128 100644 --- a/dll/win32/qmgr/CMakeLists.txt +++ b/dll/win32/qmgr/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) generate_idl_iids(qmgr_local.idl) spec2def(qmgr.dll qmgr.spec) @@ -29,3 +27,4 @@ add_importlibs(qmgr winhttp ole32 advapi32 msvcrt kernel32 ntdll) add_pch(qmgr precomp.h SOURCE) add_cd_file(TARGET qmgr DESTINATION reactos/system32 FOR all) add_dependencies(qmgr qmgr_idlheader) +set_wine_module_FIXME(qmgr) # CORE-5743: No ARRAY_SIZE and CONST_VTABLE diff --git a/dll/win32/qmgr/qmgr_main.c b/dll/win32/qmgr/qmgr_main.c index 7bea214ed2b3e..f48de877520de 100644 --- a/dll/win32/qmgr/qmgr_main.c +++ b/dll/win32/qmgr/qmgr_main.c @@ -47,8 +47,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) switch (fdwReason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hinstDLL); hInst = hinstDLL; diff --git a/dll/win32/qmgrprxy/CMakeLists.txt b/dll/win32/qmgrprxy/CMakeLists.txt index a207e3eff363b..f188784388890 100644 --- a/dll/win32/qmgrprxy/CMakeLists.txt +++ b/dll/win32/qmgrprxy/CMakeLists.txt @@ -1,9 +1,7 @@ add_definitions( - -D__WINESRC__ -DWINE_REGISTER_DLL) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) generate_idl_iids(qmgrprxy.idl) spec2def(qmgrprxy.dll qmgrprxy.spec) add_rpcproxy_files(qmgrprxy.idl) @@ -20,3 +18,4 @@ set_module_type(qmgrprxy win32dll) target_link_libraries(qmgrprxy ${PSEH_LIB} wine) add_importlibs(qmgrprxy rpcrt4 msvcrt kernel32 ntdll) add_cd_file(TARGET qmgrprxy DESTINATION reactos/system32 FOR all) +set_wine_module(qmgrprxy) diff --git a/dll/win32/query/CMakeLists.txt b/dll/win32/query/CMakeLists.txt index dcceb5106a85e..ccfda97f69f48 100644 --- a/dll/win32/query/CMakeLists.txt +++ b/dll/win32/query/CMakeLists.txt @@ -1,9 +1,7 @@ add_definitions( - -D__WINESRC__ -DCOM_NO_WINDOWS_H) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(query.dll query.spec) list(APPEND SOURCE @@ -16,3 +14,4 @@ set_module_type(query win32dll) target_link_libraries(query wine) add_importlibs(query msvcrt kernel32 ntdll) add_cd_file(TARGET query DESTINATION reactos/system32 FOR all) +set_wine_module(query) diff --git a/dll/win32/query/query_main.c b/dll/win32/query/query_main.c index b93973addea0f..a2f74c6119564 100644 --- a/dll/win32/query/query_main.c +++ b/dll/win32/query/query_main.c @@ -40,8 +40,10 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) { switch(fdwReason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hInstDLL); break; diff --git a/dll/win32/rasapi32/CMakeLists.txt b/dll/win32/rasapi32/CMakeLists.txt index 41c7cca761902..c140ebb9a7157 100644 --- a/dll/win32/rasapi32/CMakeLists.txt +++ b/dll/win32/rasapi32/CMakeLists.txt @@ -1,6 +1,4 @@ -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) -add_definitions(-D__WINESRC__) spec2def(rasapi32.dll rasapi32.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -13,3 +11,4 @@ set_module_type(rasapi32 win32dll) target_link_libraries(rasapi32 wine) add_importlibs(rasapi32 msvcrt kernel32 ntdll) add_cd_file(TARGET rasapi32 DESTINATION reactos/system32 FOR all) +set_wine_module(rasapi32) diff --git a/dll/win32/regapi/CMakeLists.txt b/dll/win32/regapi/CMakeLists.txt index c5d45a10bb544..3227ab020022b 100644 --- a/dll/win32/regapi/CMakeLists.txt +++ b/dll/win32/regapi/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(regapi.dll regapi.spec) list(APPEND SOURCE @@ -13,3 +11,4 @@ set_module_type(regapi win32dll) target_link_libraries(regapi wine) add_importlibs(regapi advapi32 msvcrt kernel32 ntdll) add_cd_file(TARGET regapi DESTINATION reactos/system32 FOR all) +set_wine_module(regapi) diff --git a/dll/win32/regapi/main.c b/dll/win32/regapi/main.c index 1164e92102a60..fc63925eaa1d8 100644 --- a/dll/win32/regapi/main.c +++ b/dll/win32/regapi/main.c @@ -31,8 +31,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) switch (fdwReason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hinstDLL); break; diff --git a/dll/win32/resutils/CMakeLists.txt b/dll/win32/resutils/CMakeLists.txt index 111ab7e1839bd..7c595b3dc3699 100644 --- a/dll/win32/resutils/CMakeLists.txt +++ b/dll/win32/resutils/CMakeLists.txt @@ -1,6 +1,4 @@ -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) -add_definitions(-D__WINESRC__) spec2def(resutils.dll resutils.spec) list(APPEND SOURCE @@ -13,3 +11,4 @@ set_module_type(resutils win32dll) target_link_libraries(resutils wine) add_importlibs(resutils msvcrt kernel32 ntdll) add_cd_file(TARGET resutils DESTINATION reactos/system32 FOR all) +set_wine_module(resutils) diff --git a/dll/win32/resutils/resutils.c b/dll/win32/resutils/resutils.c index b9e3c66fa1a33..b5168f6e43521 100644 --- a/dll/win32/resutils/resutils.c +++ b/dll/win32/resutils/resutils.c @@ -37,8 +37,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) switch(fdwReason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls( hinstDLL ); break; diff --git a/dll/win32/riched20/CMakeLists.txt b/dll/win32/riched20/CMakeLists.txt index b61a49dfa0681..15e448ac204bc 100644 --- a/dll/win32/riched20/CMakeLists.txt +++ b/dll/win32/riched20/CMakeLists.txt @@ -1,5 +1,6 @@ -add_definitions(-D__WINESRC__ -D__ROS_LONG64__) +remove_definitions(-D_CRT_NON_CONFORMING_SWPRINTFS) +add_definitions(-D__ROS_LONG64__) include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(riched20.dll riched20.spec ADD_IMPORTLIB) @@ -35,6 +36,11 @@ add_library(riched20 MODULE version.rc ${CMAKE_CURRENT_BINARY_DIR}/riched20.def) +if(MSVC AND ARCH STREQUAL "i386") + # MSVC doesn't support __thiscall in C code + target_compile_definitions(riched20 PRIVATE __ASM_USE_THISCALL_WRAPPER) +endif() + add_typelib(riched_tom.idl) add_dependencies(riched20 stdole2) set_module_type(riched20 win32dll) @@ -42,3 +48,4 @@ target_link_libraries(riched20 wine uuid) add_importlibs(riched20 ole32 oleaut32 usp10 imm32 user32 gdi32 msvcrt kernel32 ntdll) add_pch(riched20 precomp.h SOURCE) add_cd_file(TARGET riched20 DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(riched20) # CORE-5743: No ARRAY_SIZE and CONST_VTABLE diff --git a/dll/win32/riched20/caret.c b/dll/win32/riched20/caret.c index 96a95872c2ddb..4785650bb7801 100644 --- a/dll/win32/riched20/caret.c +++ b/dll/win32/riched20/caret.c @@ -26,16 +26,16 @@ WINE_DEFAULT_DEBUG_CHANNEL(richedit); void ME_SetCursorToStart(ME_TextEditor *editor, ME_Cursor *cursor) { - cursor->pPara = editor->pBuffer->pFirst->member.para.next_para; - cursor->pRun = ME_FindItemFwd(cursor->pPara, diRun); + cursor->para = editor_first_para( editor ); + cursor->run = para_first_run( cursor->para ); cursor->nOffset = 0; } static void ME_SetCursorToEnd(ME_TextEditor *editor, ME_Cursor *cursor, BOOL final_eop) { - cursor->pPara = editor->pBuffer->pLast->member.para.prev_para; - cursor->pRun = ME_FindItemBack(editor->pBuffer->pLast, diRun); - cursor->nOffset = final_eop ? cursor->pRun->member.run.len : 0; + cursor->para = para_prev( editor_end_para( editor ) ); + cursor->run = para_end_run( cursor->para ); + cursor->nOffset = final_eop ? cursor->run->len : 0; } @@ -99,7 +99,7 @@ int ME_GetTextLengthEx(ME_TextEditor *editor, const GETTEXTLENGTHEX *how) length = ME_GetTextLength(editor); - if ((editor->styleFlags & ES_MULTILINE) + if ((editor->props & TXTBIT_MULTILINE) && (how->flags & GTL_USECRLF) && !editor->bEmulateVersion10) /* Ignore GTL_USECRLF flag in 1.0 emulation */ length += editor->nParagraphs - 1; @@ -201,16 +201,16 @@ int set_selection_cursors(ME_TextEditor *editor, int from, int to) return len; } - ME_CursorFromCharOfs(editor, from, &editor->pCursors[1]); + cursor_from_char_ofs( editor, from, &editor->pCursors[1] ); editor->pCursors[0] = editor->pCursors[1]; ME_MoveCursorChars(editor, &editor->pCursors[0], to - from, FALSE); /* Selection is not allowed in the middle of an end paragraph run. */ - if (editor->pCursors[1].pRun->member.run.nFlags & MERF_ENDPARA) + if (editor->pCursors[1].run->nFlags & MERF_ENDPARA) editor->pCursors[1].nOffset = 0; - if (editor->pCursors[0].pRun->member.run.nFlags & MERF_ENDPARA) + if (editor->pCursors[0].run->nFlags & MERF_ENDPARA) { if (to > len) - editor->pCursors[0].nOffset = editor->pCursors[0].pRun->member.run.len; + editor->pCursors[0].nOffset = editor->pCursors[0].run->len; else editor->pCursors[0].nOffset = 0; } @@ -218,54 +218,33 @@ int set_selection_cursors(ME_TextEditor *editor, int from, int to) } -void ME_GetCursorCoordinates(ME_TextEditor *editor, ME_Cursor *pCursor, - int *x, int *y, int *height) +void cursor_coords( ME_TextEditor *editor, ME_Cursor *cursor, + int *x, int *y, int *height ) { - ME_DisplayItem *row; - ME_DisplayItem *run = pCursor->pRun; - ME_DisplayItem *para = pCursor->pPara; - ME_DisplayItem *pSizeRun = run; + ME_Row *row; + ME_Run *run = cursor->run; + ME_Paragraph *para = cursor->para; + ME_Run *size_run = run, *prev; ME_Context c; int run_x; + HDC hdc = ITextHost_TxGetDC( editor->texthost ); - assert(height && x && y); - assert(~para->member.para.nFlags & MEPF_REWRAP); - assert(run && run->type == diRun); - assert(para && para->type == diParagraph); + assert(~para->nFlags & MEPF_REWRAP); - row = ME_FindItemBack(run, diStartRowOrParagraph); - assert(row && row->type == diStartRow); + row = row_from_cursor( cursor ); - ME_InitContext(&c, editor, ITextHost_TxGetDC(editor->texthost)); + ME_InitContext( &c, editor, hdc ); - if (!pCursor->nOffset) - { - ME_DisplayItem *prev = ME_FindItemBack(run, diRunOrParagraph); - assert(prev); - if (prev->type == diRun) - pSizeRun = prev; - } - if (editor->bCaretAtEnd && !pCursor->nOffset && - run == ME_FindItemFwd(row, diRun)) - { - ME_DisplayItem *tmp = ME_FindItemBack(row, diRunOrParagraph); - assert(tmp); - if (tmp->type == diRun) - { - row = ME_FindItemBack(tmp, diStartRow); - pSizeRun = run = tmp; - assert(run); - assert(run->type == diRun); - } - } - run_x = ME_PointFromCharContext( &c, &run->member.run, pCursor->nOffset, TRUE ); + if (!cursor->nOffset && (prev = run_prev( run ))) size_run = prev; - *height = pSizeRun->member.run.nAscent + pSizeRun->member.run.nDescent; - *x = c.rcView.left + run->member.run.pt.x + run_x - editor->horz_si.nPos; - *y = c.rcView.top + para->member.para.pt.y + row->member.row.nBaseline - + run->member.run.pt.y - pSizeRun->member.run.nAscent - - editor->vert_si.nPos; + run_x = ME_PointFromCharContext( &c, run, cursor->nOffset, TRUE ); + + *height = size_run->nAscent + size_run->nDescent; + *x = c.rcView.left + run->pt.x + run_x - editor->horz_si.nPos; + *y = c.rcView.top + para->pt.y + row->nBaseline + + run->pt.y - size_run->nAscent - editor->vert_si.nPos; ME_DestroyContext(&c); + ITextHost_TxReleaseDC( editor->texthost, hdc ); return; } @@ -273,7 +252,7 @@ void create_caret(ME_TextEditor *editor) { int x, y, height; - ME_GetCursorCoordinates(editor, &editor->pCursors[0], &x, &y, &height); + cursor_coords( editor, &editor->pCursors[0], &x, &y, &height ); ITextHost_TxCreateCaret(editor->texthost, NULL, 0, height); editor->caret_height = height; editor->caret_hidden = TRUE; @@ -302,7 +281,7 @@ void update_caret(ME_TextEditor *editor) if (!editor->bHaveFocus) return; if (!ME_IsSelection(editor)) { - ME_GetCursorCoordinates(editor, &editor->pCursors[0], &x, &y, &height); + cursor_coords( editor, &editor->pCursors[0], &x, &y, &height ); if (height != editor->caret_height) create_caret(editor); x = min(x, editor->rcFormat.right-1); ITextHost_TxSetCaretPos(editor->texthost, x, y); @@ -364,60 +343,57 @@ BOOL ME_InternalDeleteText(ME_TextEditor *editor, ME_Cursor *start, int nOfs = ME_GetCursorOfs(start), text_len = ME_GetTextLength( editor ); int shift = 0; int totalChars = nChars; - ME_DisplayItem *start_para; + ME_Paragraph *start_para; BOOL delete_all = FALSE; /* Prevent deletion past last end of paragraph run. */ nChars = min(nChars, text_len - nOfs); if (nChars == text_len) delete_all = TRUE; - start_para = c.pPara; + start_para = c.para; if (!bForce) { - ME_ProtectPartialTableDeletion(editor, &c, &nChars); - if (nChars == 0) - return FALSE; + table_protect_partial_deletion( editor, &c, &nChars ); + if (nChars == 0) return FALSE; } - while(nChars > 0) + while (nChars > 0) { ME_Run *run; - ME_CursorFromCharOfs(editor, nOfs+nChars, &c); - if (!c.nOffset && - nOfs+nChars == (c.pRun->member.run.nCharOfs - + c.pPara->member.para.nCharOfs)) + cursor_from_char_ofs( editor, nOfs + nChars, &c ); + if (!c.nOffset) { /* We aren't deleting anything in this run, so we will go back to the * last run we are deleting text in. */ - ME_PrevRun(&c.pPara, &c.pRun, TRUE); - c.nOffset = c.pRun->member.run.len; + c.run = run_prev_all_paras( c.run ); + c.para = c.run->para; + c.nOffset = c.run->len; } - run = &c.pRun->member.run; - if (run->nFlags & MERF_ENDPARA) { - int eollen = c.pRun->member.run.len; + run = c.run; + if (run->nFlags & MERF_ENDPARA) + { + int eollen = c.run->len; BOOL keepFirstParaFormat; - if (!ME_FindItemFwd(c.pRun, diParagraph)) - { - return TRUE; - } + if (!para_next( para_next( c.para ) )) return TRUE; + keepFirstParaFormat = (totalChars == nChars && nChars <= eollen && run->nCharOfs); if (!editor->bEmulateVersion10) /* v4.1 */ { - ME_DisplayItem *next_para = ME_FindItemFwd(c.pRun, diParagraphOrEnd); - ME_DisplayItem *this_para = next_para->member.para.prev_para; + ME_Paragraph *this_para = run->para; + ME_Paragraph *next_para = para_next( this_para ); /* The end of paragraph before a table row is only deleted if there * is nothing else on the line before it. */ - if (this_para == start_para && - next_para->member.para.nFlags & MEPF_ROWSTART) + if (this_para == start_para && next_para->nFlags & MEPF_ROWSTART) { /* If the paragraph will be empty, then it should be deleted, however * it still might have text right now which would inherit the * MEPF_STARTROW property if we joined it right now. * Instead we will delete it after the preceding text is deleted. */ - if (nOfs > this_para->member.para.nCharOfs) { + if (nOfs > this_para->nCharOfs) + { /* Skip this end of line. */ nChars -= (eollen < nChars) ? eollen : nChars; continue; @@ -425,7 +401,7 @@ BOOL ME_InternalDeleteText(ME_TextEditor *editor, ME_Cursor *start, keepFirstParaFormat = TRUE; } } - ME_JoinParagraphs(editor, c.pPara, keepFirstParaFormat); + para_join( editor, c.para, keepFirstParaFormat ); /* ME_SkipAndPropagateCharOffset(p->pRun, shift); */ ME_CheckCharOffsets(editor); nChars -= (eollen < nChars) ? eollen : nChars; @@ -439,7 +415,7 @@ BOOL ME_InternalDeleteText(ME_TextEditor *editor, ME_Cursor *start, c.nOffset -= nCharsToDelete; - mark_para_rewrap(editor, ME_FindItemBack(c.pRun, diParagraph)); + para_mark_rewrap( editor, c.run->para ); cursor = c; /* nChars is the number of characters that should be deleted from the @@ -464,7 +440,7 @@ BOOL ME_InternalDeleteText(ME_TextEditor *editor, ME_Cursor *start, for (i=-1; inCursors; i++) { ME_Cursor *pThisCur = editor->pCursors + i; if (i == -1) pThisCur = &c; - if (pThisCur->pRun == cursor.pRun) { + if (pThisCur->run == cursor.run) { if (pThisCur->nOffset > cursor.nOffset) { if (pThisCur->nOffset-cursor.nOffset < nCharsToDelete) pThisCur->nOffset = cursor.nOffset; @@ -475,8 +451,8 @@ BOOL ME_InternalDeleteText(ME_TextEditor *editor, ME_Cursor *start, } if (pThisCur->nOffset == run->len) { - pThisCur->pRun = ME_FindItemFwd(pThisCur->pRun, diRunOrParagraphOrEnd); - assert(pThisCur->pRun->type == diRun); + pThisCur->run = run_next( pThisCur->run ); + assert( pThisCur->run ); pThisCur->nOffset = 0; } } @@ -484,26 +460,21 @@ BOOL ME_InternalDeleteText(ME_TextEditor *editor, ME_Cursor *start, /* c = updated data now */ - if (c.pRun == cursor.pRun) - ME_SkipAndPropagateCharOffset(c.pRun, shift); - else - ME_PropagateCharOffset(c.pRun, shift); + if (c.run == cursor.run) c.run->nCharOfs -= shift; + editor_propagate_char_ofs( NULL, c.run, shift ); - if (!cursor.pRun->member.run.len) + if (!cursor.run->len) { TRACE("Removing empty run\n"); - ME_Remove(cursor.pRun); - ME_DestroyDisplayItem(cursor.pRun); + ME_Remove( run_get_di( cursor.run )); + ME_DestroyDisplayItem( run_get_di( cursor.run )); } shift = 0; - /* - ME_CheckCharOffsets(editor); - */ continue; } } - if (delete_all) ME_SetDefaultParaFormat( editor, &start_para->member.para.fmt ); + if (delete_all) editor_set_default_para_fmt( editor, &start_para->fmt ); return TRUE; } @@ -516,20 +487,6 @@ BOOL ME_DeleteTextAtCursor(ME_TextEditor *editor, int nCursor, int nChars) nChars, FALSE); } -static ME_DisplayItem * -ME_InternalInsertTextFromCursor(ME_TextEditor *editor, int nCursor, - const WCHAR *str, int len, ME_Style *style, - int flags) -{ - ME_Cursor *p = &editor->pCursors[nCursor]; - - editor->bCaretAtEnd = FALSE; - - assert(p->pRun->type == diRun); - - return ME_InsertRunAtCursor(editor, p, style, str, len, flags); -} - static struct re_object* create_re_object(const REOBJECT *reo) { struct re_object *reobj = heap_alloc(sizeof(*reobj)); @@ -545,66 +502,65 @@ static struct re_object* create_re_object(const REOBJECT *reo) void ME_InsertOLEFromCursor(ME_TextEditor *editor, const REOBJECT* reo, int nCursor) { - ME_Style *pStyle = ME_GetInsertStyle(editor, nCursor); - ME_DisplayItem *di; - WCHAR space = ' '; - ME_DisplayItem *di_prev = NULL; - struct re_object *reobj_prev = NULL; - + ME_Run *run, *prev; + const WCHAR space = ' '; + struct re_object *reobj_prev = NULL; + ME_Cursor *cursor = editor->pCursors + nCursor; + ME_Style *style = style_get_insert_style( editor, cursor ); + /* FIXME no no no */ if (ME_IsSelection(editor)) ME_DeleteSelection(editor); - di = ME_InternalInsertTextFromCursor(editor, nCursor, &space, 1, pStyle, - MERF_GRAPHICS); - di->member.run.reobj = create_re_object(reo); + run = run_insert( editor, cursor, style, &space, 1, MERF_GRAPHICS ); + + run->reobj = create_re_object( reo ); - di_prev = di; - while (ME_PrevRun(NULL, &di_prev, TRUE)) + prev = run; + while ((prev = run_prev_all_paras( prev ))) { - if (di_prev->member.run.reobj) + if (prev->reobj) { - reobj_prev = di_prev->member.run.reobj; + reobj_prev = prev->reobj; break; } } if (reobj_prev) - list_add_after(&reobj_prev->entry, &di->member.run.reobj->entry); + list_add_after(&reobj_prev->entry, &run->reobj->entry); else - list_add_head(&editor->reobj_list, &di->member.run.reobj->entry); + list_add_head(&editor->reobj_list, &run->reobj->entry); - ME_ReleaseStyle(pStyle); + ME_ReleaseStyle( style ); } void ME_InsertEndRowFromCursor(ME_TextEditor *editor, int nCursor) { - ME_Style *pStyle = ME_GetInsertStyle(editor, nCursor); - WCHAR space = ' '; + const WCHAR space = ' '; + ME_Cursor *cursor = editor->pCursors + nCursor; + ME_Style *style = style_get_insert_style( editor, cursor ); /* FIXME no no no */ if (ME_IsSelection(editor)) ME_DeleteSelection(editor); - ME_InternalInsertTextFromCursor(editor, nCursor, &space, 1, pStyle, - MERF_ENDROW); - ME_ReleaseStyle(pStyle); + run_insert( editor, cursor, style, &space, 1, MERF_ENDROW ); + + ME_ReleaseStyle( style ); } void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor, - const WCHAR *str, int len, ME_Style *style) + const WCHAR *str, int len, ME_Style *style) { const WCHAR *pos; - ME_Cursor *p = NULL; + ME_Cursor *cursor = editor->pCursors + nCursor; int oldLen; /* FIXME really HERE ? */ if (ME_IsSelection(editor)) ME_DeleteSelection(editor); - /* FIXME: is this too slow? */ - /* Didn't affect performance for WM_SETTEXT (around 50sec/30K) */ oldLen = ME_GetTextLength(editor); /* text operations set modified state */ @@ -612,34 +568,35 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor, assert(style); - assert(nCursor>=0 && nCursornCursors); - if (len == -1) - len = lstrlenW(str); + if (len == -1) len = lstrlenW( str ); /* grow the text limit to fit our text */ - if(editor->nTextLimit < oldLen +len) - editor->nTextLimit = oldLen + len; + if (editor->nTextLimit < oldLen + len) editor->nTextLimit = oldLen + len; pos = str; while (len) { /* FIXME this sucks - no respect for unicode (what else can be a line separator in unicode?) */ - while(pos - str < len && *pos != '\r' && *pos != '\n' && *pos != '\t') + while (pos - str < len && *pos != '\r' && *pos != '\n' && *pos != '\t') pos++; - if (pos != str) { /* handle text */ - ME_InternalInsertTextFromCursor(editor, nCursor, str, pos-str, style, 0); - } else if (*pos == '\t') { /* handle tabs */ - WCHAR tab = '\t'; - ME_InternalInsertTextFromCursor(editor, nCursor, &tab, 1, style, MERF_TAB); + if (pos != str) /* handle text */ + run_insert( editor, cursor, style, str, pos - str, 0 ); + else if (*pos == '\t') /* handle tabs */ + { + const WCHAR tab = '\t'; + run_insert( editor, cursor, style, &tab, 1, MERF_TAB ); pos++; - } else { /* handle EOLs */ - ME_DisplayItem *tp, *end_run, *run, *prev; + } + else /* handle EOLs */ + { + ME_Run *end_run, *run, *prev; + ME_Paragraph *new_para; int eol_len = 0; /* Check if new line is allowed for this control */ - if (!(editor->styleFlags & ES_MULTILINE)) + if (!(editor->props & TXTBIT_MULTILINE)) break; /* Find number of CR and LF in end of paragraph run */ @@ -651,7 +608,9 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor, eol_len = 3; else eol_len = 1; - } else { + } + else + { assert(*pos == '\n'); eol_len = 1; } @@ -660,9 +619,11 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor, if (!editor->bEmulateVersion10 && eol_len == 3) { /* handle special \r\r\n sequence (richedit 2.x and higher only) */ - WCHAR space = ' '; - ME_InternalInsertTextFromCursor(editor, nCursor, &space, 1, style, 0); - } else { + const WCHAR space = ' '; + run_insert( editor, cursor, style, &space, 1, 0 ); + } + else + { const WCHAR cr = '\r', *eol_str = str; if (!editor->bEmulateVersion10) @@ -671,35 +632,32 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor, eol_len = 1; } - p = &editor->pCursors[nCursor]; - - if (p->nOffset == p->pRun->member.run.len) + if (cursor->nOffset == cursor->run->len) { - run = ME_FindItemFwd( p->pRun, diRun ); - if (!run) run = p->pRun; + run = run_next( cursor->run ); + if (!run) run = cursor->run; } else { - if (p->nOffset) ME_SplitRunSimple(editor, p); - run = p->pRun; + if (cursor->nOffset) run_split( editor, cursor ); + run = cursor->run; } - tp = ME_SplitParagraph(editor, run, style, eol_str, eol_len, 0); - - end_run = ME_FindItemBack(tp, diRun); + new_para = para_split( editor, run, style, eol_str, eol_len, 0 ); + end_run = para_end_run( para_prev( new_para ) ); /* Move any cursors that were at the end of the previous run to the beginning of the new para */ - prev = ME_FindItemBack( end_run, diRun ); + prev = run_prev( end_run ); if (prev) { int i; for (i = 0; i < editor->nCursors; i++) { - if (editor->pCursors[i].pRun == prev && - editor->pCursors[i].nOffset == prev->member.run.len) + if (editor->pCursors[i].run == prev && + editor->pCursors[i].nOffset == prev->len) { - editor->pCursors[i].pPara = tp; - editor->pCursors[i].pRun = run; + editor->pCursors[i].para = new_para; + editor->pCursors[i].run = run; editor->pCursors[i].nOffset = 0; } } @@ -722,18 +680,18 @@ int ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs, BO cursor->nOffset += nRelOfs; if (cursor->nOffset < 0) { - cursor->nOffset += cursor->pRun->member.run.nCharOfs; + cursor->nOffset += cursor->run->nCharOfs; if (cursor->nOffset >= 0) { /* new offset in the same paragraph */ do { - cursor->pRun = ME_FindItemBack(cursor->pRun, diRun); - } while (cursor->nOffset < cursor->pRun->member.run.nCharOfs); - cursor->nOffset -= cursor->pRun->member.run.nCharOfs; + cursor->run = run_prev( cursor->run ); + } while (cursor->nOffset < cursor->run->nCharOfs); + cursor->nOffset -= cursor->run->nCharOfs; return nRelOfs; } - cursor->nOffset += cursor->pPara->member.para.nCharOfs; + cursor->nOffset += cursor->para->nCharOfs; if (cursor->nOffset <= 0) { /* moved to the start of the text */ @@ -744,28 +702,29 @@ int ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs, BO /* new offset in a previous paragraph */ do { - cursor->pPara = cursor->pPara->member.para.prev_para; - } while (cursor->nOffset < cursor->pPara->member.para.nCharOfs); - cursor->nOffset -= cursor->pPara->member.para.nCharOfs; - - cursor->pRun = ME_FindItemBack(cursor->pPara->member.para.next_para, diRun); - while (cursor->nOffset < cursor->pRun->member.run.nCharOfs) { - cursor->pRun = ME_FindItemBack(cursor->pRun, diRun); - } - cursor->nOffset -= cursor->pRun->member.run.nCharOfs; - } else if (cursor->nOffset >= cursor->pRun->member.run.len) { - ME_DisplayItem *next_para; + cursor->para = para_prev( cursor->para ); + } while (cursor->nOffset < cursor->para->nCharOfs); + cursor->nOffset -= cursor->para->nCharOfs; + + cursor->run = para_end_run( cursor->para ); + while (cursor->nOffset < cursor->run->nCharOfs) + cursor->run = run_prev( cursor->run ); + cursor->nOffset -= cursor->run->nCharOfs; + } + else if (cursor->nOffset >= cursor->run->len) + { + ME_Paragraph *next_para; int new_offset; new_offset = ME_GetCursorOfs(cursor); - next_para = cursor->pPara->member.para.next_para; - if (new_offset < next_para->member.para.nCharOfs) + next_para = para_next( cursor->para ); + if (new_offset < next_para->nCharOfs) { /* new offset in the same paragraph */ do { - cursor->nOffset -= cursor->pRun->member.run.len; - cursor->pRun = ME_FindItemFwd(cursor->pRun, diRun); - } while (cursor->nOffset >= cursor->pRun->member.run.len); + cursor->nOffset -= cursor->run->len; + cursor->run = run_next( cursor->run ); + } while (cursor->nOffset >= cursor->run->len); return nRelOfs; } @@ -779,16 +738,16 @@ int ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs, BO /* new offset in a following paragraph */ do { - cursor->pPara = next_para; - next_para = next_para->member.para.next_para; - } while (new_offset >= next_para->member.para.nCharOfs); + cursor->para = next_para; + next_para = para_next( next_para ); + } while (new_offset >= next_para->nCharOfs); - cursor->nOffset = new_offset - cursor->pPara->member.para.nCharOfs; - cursor->pRun = ME_FindItemFwd(cursor->pPara, diRun); - while (cursor->nOffset >= cursor->pRun->member.run.len) + cursor->nOffset = new_offset - cursor->para->nCharOfs; + cursor->run = para_first_run( cursor->para ); + while (cursor->nOffset >= cursor->run->len) { - cursor->nOffset -= cursor->pRun->member.run.len; - cursor->pRun = ME_FindItemFwd(cursor->pRun, diRun); + cursor->nOffset -= cursor->run->len; + cursor->run = run_next( cursor->run ); } } /* else new offset is in the same run */ return nRelOfs; @@ -798,8 +757,8 @@ int ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs, BO BOOL ME_MoveCursorWords(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs) { - ME_DisplayItem *pRun = cursor->pRun, *pOtherRun; - ME_DisplayItem *pPara = cursor->pPara; + ME_Run *run = cursor->run, *other_run; + ME_Paragraph *para = cursor->para; int nOffset = cursor->nOffset; if (nRelOfs == -1) @@ -807,40 +766,31 @@ ME_MoveCursorWords(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs) /* Backward movement */ while (TRUE) { - nOffset = ME_CallWordBreakProc(editor, get_text( &pRun->member.run, 0 ), - pRun->member.run.len, nOffset, WB_MOVEWORDLEFT); - if (nOffset) - break; - pOtherRun = ME_FindItemBack(pRun, diRunOrParagraph); - if (pOtherRun->type == diRun) + nOffset = ME_CallWordBreakProc( editor, get_text( run, 0 ), run->len, nOffset, WB_MOVEWORDLEFT ); + if (nOffset) break; + other_run = run_prev( run ); + if (other_run) { - if (ME_CallWordBreakProc(editor, get_text( &pOtherRun->member.run, 0 ), - pOtherRun->member.run.len, - pOtherRun->member.run.len - 1, - WB_ISDELIMITER) - && !(pRun->member.run.nFlags & MERF_ENDPARA) - && !(cursor->pRun == pRun && cursor->nOffset == 0) - && !ME_CallWordBreakProc(editor, get_text( &pRun->member.run, 0 ), - pRun->member.run.len, 0, - WB_ISDELIMITER)) + if (ME_CallWordBreakProc( editor, get_text( other_run, 0 ), other_run->len, other_run->len - 1, WB_ISDELIMITER ) + && !(run->nFlags & MERF_ENDPARA) + && !(cursor->run == run && cursor->nOffset == 0) + && !ME_CallWordBreakProc( editor, get_text( run, 0 ), run->len, 0, WB_ISDELIMITER )) break; - pRun = pOtherRun; - nOffset = pOtherRun->member.run.len; + run = other_run; + nOffset = other_run->len; } - else if (pOtherRun->type == diParagraph) + else { - if (cursor->pRun == pRun && cursor->nOffset == 0) + if (cursor->run == run && cursor->nOffset == 0) { - pPara = pOtherRun; + para = run->para; /* Skip empty start of table row paragraph */ - if (pPara->member.para.prev_para->member.para.nFlags & MEPF_ROWSTART) - pPara = pPara->member.para.prev_para; + if (para_prev( para ) && para_prev( para )->nFlags & MEPF_ROWSTART) + para = para_prev( para ); /* Paragraph breaks are treated as separate words */ - if (pPara->member.para.prev_para->type == diTextStart) - return FALSE; - - pRun = ME_FindItemBack(pPara, diRun); - pPara = pPara->member.para.prev_para; + if (!para_prev( para )) return FALSE; + para = para_prev( para ); + run = para_end_run( para ); } break; } @@ -853,43 +803,35 @@ ME_MoveCursorWords(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs) while (TRUE) { - if (last_delim && !ME_CallWordBreakProc(editor, get_text( &pRun->member.run, 0 ), - pRun->member.run.len, nOffset, WB_ISDELIMITER)) - break; - nOffset = ME_CallWordBreakProc(editor, get_text( &pRun->member.run, 0 ), - pRun->member.run.len, nOffset, WB_MOVEWORDRIGHT); - if (nOffset < pRun->member.run.len) + if (last_delim && !ME_CallWordBreakProc( editor, get_text( run, 0 ), run->len, nOffset, WB_ISDELIMITER )) break; - pOtherRun = ME_FindItemFwd(pRun, diRunOrParagraphOrEnd); - if (pOtherRun->type == diRun) + nOffset = ME_CallWordBreakProc( editor, get_text( run, 0 ), run->len, nOffset, WB_MOVEWORDRIGHT ); + if (nOffset < run->len) break; + other_run = run_next( run ); + if (other_run) { - last_delim = ME_CallWordBreakProc(editor, get_text( &pRun->member.run, 0 ), - pRun->member.run.len, nOffset - 1, WB_ISDELIMITER); - pRun = pOtherRun; + last_delim = ME_CallWordBreakProc( editor, get_text( run, 0 ), run->len, nOffset - 1, WB_ISDELIMITER ); + run = other_run; nOffset = 0; } - else if (pOtherRun->type == diParagraph) + else { - if (pOtherRun->member.para.nFlags & MEPF_ROWSTART) - pOtherRun = pOtherRun->member.para.next_para; - if (cursor->pRun == pRun) { - pPara = pOtherRun; - pRun = ME_FindItemFwd(pPara, diRun); + para = para_next( para ); + if (!para_next( para )) + { + if (cursor->run == run) return FALSE; + nOffset = 0; + break; } - nOffset = 0; - break; - } - else /* diTextEnd */ - { - if (cursor->pRun == pRun) - return FALSE; + if (para->nFlags & MEPF_ROWSTART) para = para_next( para ); + if (cursor->run == run) run = para_first_run( para ); nOffset = 0; break; } } } - cursor->pPara = pPara; - cursor->pRun = pRun; + cursor->para = para; + cursor->run = run; cursor->nOffset = nOffset; return TRUE; } @@ -914,38 +856,28 @@ ME_SelectByType(ME_TextEditor *editor, ME_SelectionType selectionType) editor->pCursors[1] = editor->pCursors[0]; ME_MoveCursorWords(editor, &editor->pCursors[1], -1); break; - case stLine: case stParagraph: - { - ME_DisplayItem *pItem; - ME_DIType fwdSearchType, backSearchType; - if (selectionType == stParagraph) { - backSearchType = diParagraph; - fwdSearchType = diParagraphOrEnd; - } else { - backSearchType = diStartRow; - fwdSearchType = diStartRowOrParagraphOrEnd; - } - pItem = ME_FindItemFwd(editor->pCursors[0].pRun, fwdSearchType); - assert(pItem); - if (pItem->type == diTextEnd) - editor->pCursors[0].pRun = ME_FindItemBack(pItem, diRun); - else - editor->pCursors[0].pRun = ME_FindItemFwd(pItem, diRun); - editor->pCursors[0].pPara = ME_GetParagraph(editor->pCursors[0].pRun); - editor->pCursors[0].nOffset = 0; + editor->pCursors[1] = editor->pCursors[0]; + + editor->pCursors[0].run = para_end_run( editor->pCursors[0].para ); + editor->pCursors[0].para = editor->pCursors[0].run->para; + editor->pCursors[0].nOffset = editor->pCursors[0].run->len; - pItem = ME_FindItemBack(pItem, backSearchType); - editor->pCursors[1].pRun = ME_FindItemFwd(pItem, diRun); - editor->pCursors[1].pPara = ME_GetParagraph(editor->pCursors[1].pRun); + editor->pCursors[1].run = para_first_run( editor->pCursors[1].para ); editor->pCursors[1].nOffset = 0; break; + case stLine: + { + ME_Row *row = row_from_cursor( editor->pCursors ); + + row_first_cursor( row, editor->pCursors + 1 ); + row_end_cursor( row, editor->pCursors, TRUE ); + break; } case stDocument: /* Select everything with cursor anchored from the start of the text */ - editor->nSelectionType = stDocument; ME_SetCursorToStart(editor, &editor->pCursors[1]); - ME_SetCursorToEnd(editor, &editor->pCursors[0], FALSE); + ME_SetCursorToEnd(editor, &editor->pCursors[0], TRUE); break; default: assert(0); } @@ -956,90 +888,81 @@ ME_SelectByType(ME_TextEditor *editor, ME_SelectionType selectionType) int ME_GetCursorOfs(const ME_Cursor *cursor) { - return cursor->pPara->member.para.nCharOfs - + cursor->pRun->member.run.nCharOfs + cursor->nOffset; + return cursor->para->nCharOfs + cursor->run->nCharOfs + cursor->nOffset; } -/* Helper function for ME_FindPixelPos to find paragraph within tables */ -static ME_DisplayItem* ME_FindPixelPosInTableRow(int x, int y, - ME_DisplayItem *para) +/* Helper function for cursor_from_virtual_coords() to find paragraph within tables */ +static ME_Paragraph *pixel_pos_in_table_row( int x, int y, ME_Paragraph *para ) { - ME_DisplayItem *cell, *next_cell; - assert(para->member.para.nFlags & MEPF_ROWSTART); - cell = para->member.para.next_para->member.para.pCell; - assert(cell); + ME_Cell *cell, *next_cell; + + assert( para->nFlags & MEPF_ROWSTART ); + cell = table_row_first_cell( para ); + assert( cell ); /* find the cell we are in */ - while ((next_cell = cell->member.cell.next_cell) != NULL) { - if (x < next_cell->member.cell.pt.x) + while ((next_cell = cell_next( cell )) != NULL) + { + if (x < next_cell->pt.x) { - para = ME_FindItemFwd(cell, diParagraph); + para = cell_first_para( cell ); /* Found the cell, but there might be multiple paragraphs in * the cell, so need to search down the cell for the paragraph. */ - while (cell == para->member.para.pCell) { - if (y < para->member.para.pt.y + para->member.para.nHeight) + while (cell == para_cell( para )) + { + if (y < para->pt.y + para->nHeight) { - if (para->member.para.nFlags & MEPF_ROWSTART) - return ME_FindPixelPosInTableRow(x, y, para); - else - return para; + if (para->nFlags & MEPF_ROWSTART) return pixel_pos_in_table_row( x, y, para ); + else return para; } - para = para->member.para.next_para; + para = para_next( para ); } /* Past the end of the cell, so go back to the last cell paragraph */ - return para->member.para.prev_para; + return para_prev( para ); } cell = next_cell; } /* Return table row delimiter */ - para = ME_FindItemFwd(cell, diParagraph); - assert(para->member.para.nFlags & MEPF_ROWEND); - assert(para->member.para.fmt.dwMask & PFM_TABLEROWDELIMITER); - assert(para->member.para.fmt.wEffects & PFE_TABLEROWDELIMITER); + para = table_row_end( para ); + assert( para->nFlags & MEPF_ROWEND ); + assert( para->fmt.dwMask & PFM_TABLEROWDELIMITER ); + assert( para->fmt.wEffects & PFE_TABLEROWDELIMITER ); return para; } -static BOOL ME_FindRunInRow(ME_TextEditor *editor, ME_DisplayItem *pRow, - int x, ME_Cursor *cursor, BOOL *pbCaretAtEnd) +static BOOL row_cursor( ME_TextEditor *editor, ME_Row *row, int x, + ME_Cursor *cursor ) { - ME_DisplayItem *pNext, *pLastRun; - ME_Row *row = &pRow->member.row; - BOOL exact = TRUE; + ME_Run *run, *last; + BOOL exact = TRUE; - if (x < row->pt.x) - { - x = row->pt.x; - exact = FALSE; - } - pNext = ME_FindItemFwd(pRow, diRunOrStartRow); - assert(pNext->type == diRun); - if (pbCaretAtEnd) *pbCaretAtEnd = FALSE; - cursor->nOffset = 0; - do { - int run_x = pNext->member.run.pt.x; - int width = pNext->member.run.nWidth; - - if (x >= run_x && x < run_x+width) + if (x < row->pt.x) { - cursor->nOffset = ME_CharFromPoint(editor, x-run_x, &pNext->member.run, TRUE, TRUE); - cursor->pRun = pNext; - cursor->pPara = ME_GetParagraph( cursor->pRun ); - return exact; + x = row->pt.x; + exact = FALSE; } - pLastRun = pNext; - pNext = ME_FindItemFwd(pNext, diRunOrStartRow); - } while(pNext && pNext->type == diRun); - if ((pLastRun->member.run.nFlags & MERF_ENDPARA) == 0) - { - cursor->pRun = ME_FindItemFwd(pNext, diRun); - if (pbCaretAtEnd) *pbCaretAtEnd = TRUE; - } - else - cursor->pRun = pLastRun; + run = row_first_run( row ); + assert( run ); + cursor->nOffset = 0; + do + { + if (x >= run->pt.x && x < run->pt.x + run->nWidth) + { + cursor->nOffset = ME_CharFromPoint( editor, x - run->pt.x, run, TRUE, TRUE ); + cursor->run = run; + cursor->para = run->para; + return exact; + } + last = run; + run = row_next_run( row, run ); + } while (run); - cursor->pPara = ME_GetParagraph( cursor->pRun ); - return FALSE; + run = last; + + cursor->run = run; + cursor->para = run->para; + return FALSE; } /* Finds the run and offset from the pixel position. @@ -1052,57 +975,51 @@ static BOOL ME_FindRunInRow(ME_TextEditor *editor, ME_DisplayItem *pRow, * returns TRUE if the result was exactly under the cursor, otherwise returns * FALSE, and result is set to the closest position to the coordinates. */ -static BOOL ME_FindPixelPos(ME_TextEditor *editor, int x, int y, - ME_Cursor *result, BOOL *is_eol, BOOL final_eop) +static BOOL cursor_from_virtual_coords( ME_TextEditor *editor, int x, int y, + ME_Cursor *result, BOOL final_eop ) { - ME_DisplayItem *p = editor->pBuffer->pFirst->member.para.next_para; + ME_Paragraph *para = editor_first_para( editor ); + ME_Row *row = NULL, *next_row; BOOL isExact = TRUE; x -= editor->rcFormat.left; y -= editor->rcFormat.top; - if (is_eol) - *is_eol = FALSE; - /* find paragraph */ - for (; p != editor->pBuffer->pLast; p = p->member.para.next_para) + for (; para_next( para ); para = para_next( para )) { - assert(p->type == diParagraph); - if (y < p->member.para.pt.y + p->member.para.nHeight) + if (y < para->pt.y + para->nHeight) { - if (p->member.para.nFlags & MEPF_ROWSTART) - p = ME_FindPixelPosInTableRow(x, y, p); - y -= p->member.para.pt.y; - p = ME_FindItemFwd(p, diStartRow); + if (para->nFlags & MEPF_ROWSTART) + para = pixel_pos_in_table_row( x, y, para ); + y -= para->pt.y; + row = para_first_row( para ); break; - } else if (p->member.para.nFlags & MEPF_ROWSTART) { - p = ME_GetTableRowEnd(p); + } + else if (para->nFlags & MEPF_ROWSTART) + { + para = table_row_end( para ); } } /* find row */ - for (; p != editor->pBuffer->pLast; ) + while (row) { - ME_DisplayItem *pp; - assert(p->type == diStartRow); - if (y < p->member.row.pt.y + p->member.row.nHeight) break; - pp = ME_FindItemFwd(p, diStartRow); - if (!pp) break; - p = pp; + if (y < row->pt.y + row->nHeight) break; + next_row = row_next( row ); + if (!next_row) break; + row = next_row; } - if (p == editor->pBuffer->pLast && !final_eop) + + if (!row && !final_eop && para_prev( para )) { /* The position is below the last paragraph, so the last row will be used * rather than the end of the text, so the x position will be used to * determine the offset closest to the pixel position. */ isExact = FALSE; - p = ME_FindItemBack(p, diStartRow); - if (!p) p = editor->pBuffer->pLast; + row = para_end_row( para_prev( para ) ); } - assert( p->type == diStartRow || p == editor->pBuffer->pLast ); - - if( p->type == diStartRow ) - return ME_FindRunInRow( editor, p, x, result, is_eol ) && isExact; + if (row) return row_cursor( editor, row, x, result ) && isExact; ME_SetCursorToEnd(editor, result, TRUE); return FALSE; @@ -1132,7 +1049,7 @@ BOOL ME_CharFromPos(ME_TextEditor *editor, int x, int y, } x += editor->horz_si.nPos; y += editor->vert_si.nPos; - bResult = ME_FindPixelPos(editor, x, y, cursor, NULL, FALSE); + bResult = cursor_from_virtual_coords( editor, x, y, cursor, FALSE ); if (isExact) *isExact = bResult; return TRUE; } @@ -1166,37 +1083,53 @@ static void ME_ExtendAnchorSelection(ME_TextEditor *editor) { /* Extend the left side of selection */ editor->pCursors[1] = tmp_cursor; - if (editor->nSelectionType == stWord) + switch (editor->nSelectionType) + { + case stWord: ME_MoveCursorWords(editor, &editor->pCursors[1], -1); - else + break; + + case stLine: { - ME_DisplayItem *pItem; - ME_DIType searchType = ((editor->nSelectionType == stLine) ? - diStartRowOrParagraph:diParagraph); - pItem = ME_FindItemBack(editor->pCursors[1].pRun, searchType); - editor->pCursors[1].pRun = ME_FindItemFwd(pItem, diRun); - editor->pCursors[1].pPara = ME_GetParagraph(editor->pCursors[1].pRun); + ME_Row *row = row_from_cursor( editor->pCursors + 1 ); + row_first_cursor( row, editor->pCursors + 1 ); + break; + } + + case stParagraph: + editor->pCursors[1].run = para_first_run( editor->pCursors[1].para ); editor->pCursors[1].nOffset = 0; + break; + + default: + break; } } else if (curOfs >= anchorEndOfs) { /* Extend the right side of selection */ editor->pCursors[0] = tmp_cursor; - if (editor->nSelectionType == stWord) - ME_MoveCursorWords(editor, &editor->pCursors[0], +1); - else + switch (editor->nSelectionType) { - ME_DisplayItem *pItem; - ME_DIType searchType = ((editor->nSelectionType == stLine) ? - diStartRowOrParagraphOrEnd:diParagraphOrEnd); - pItem = ME_FindItemFwd(editor->pCursors[0].pRun, searchType); - if (pItem->type == diTextEnd) - editor->pCursors[0].pRun = ME_FindItemBack(pItem, diRun); - else - editor->pCursors[0].pRun = ME_FindItemFwd(pItem, diRun); - editor->pCursors[0].pPara = ME_GetParagraph(editor->pCursors[0].pRun); - editor->pCursors[0].nOffset = 0; + case stWord: + ME_MoveCursorWords( editor, &editor->pCursors[0], +1 ); + break; + + case stLine: + { + ME_Row *row = row_from_cursor( editor->pCursors ); + row_end_cursor( row, editor->pCursors, TRUE ); + break; + } + + case stParagraph: + editor->pCursors[0].run = para_end_run( editor->pCursors[0].para ); + editor->pCursors[0].para = editor->pCursors[0].run->para; + editor->pCursors[0].nOffset = editor->pCursors[0].run->len; + break; + + default: + break; } } } @@ -1215,7 +1148,7 @@ void ME_LButtonDown(ME_TextEditor *editor, int x, int y, int clickNum) is_selection = ME_IsSelection(editor); is_shift = GetKeyState(VK_SHIFT) < 0; - ME_FindPixelPos(editor, x, y, &editor->pCursors[0], &editor->bCaretAtEnd, FALSE); + cursor_from_virtual_coords( editor, x, y, &editor->pCursors[0], FALSE ); if (x >= editor->rcFormat.left || is_shift) { @@ -1273,8 +1206,8 @@ void ME_MouseMove(ME_TextEditor *editor, int x, int y) y += editor->vert_si.nPos; tmp_cursor = editor->pCursors[0]; - /* FIXME: do something with the return value of ME_FindPixelPos */ - ME_FindPixelPos(editor, x, y, &tmp_cursor, &editor->bCaretAtEnd, TRUE); + /* FIXME: do something with the return value of cursor_from_virtual_coords */ + cursor_from_virtual_coords( editor, x, y, &tmp_cursor, TRUE ); ME_InvalidateSelection(editor); editor->pCursors[0] = tmp_cursor; @@ -1282,13 +1215,11 @@ void ME_MouseMove(ME_TextEditor *editor, int x, int y) if (editor->nSelectionType != stPosition && memcmp(&editor->pCursors[1], &editor->pCursors[3], sizeof(ME_Cursor))) - { /* The scroll the cursor towards the other end, since it was the one * extended by ME_ExtendAnchorSelection */ - ME_EnsureVisible(editor, &editor->pCursors[1]); - } else { - ME_EnsureVisible(editor, &editor->pCursors[0]); - } + editor_ensure_visible( editor, &editor->pCursors[1] ); + else + editor_ensure_visible( editor, &editor->pCursors[0] ); ME_InvalidateSelection(editor); update_caret(editor); @@ -1297,287 +1228,178 @@ void ME_MouseMove(ME_TextEditor *editor, int x, int y) static int ME_GetXForArrow(ME_TextEditor *editor, ME_Cursor *pCursor) { - ME_DisplayItem *pRun = pCursor->pRun; + ME_Run *run = pCursor->run; int x; if (editor->nUDArrowX != -1) x = editor->nUDArrowX; - else { - if (editor->bCaretAtEnd) - { - pRun = ME_FindItemBack(pRun, diRun); - assert(pRun); - x = pRun->member.run.pt.x + pRun->member.run.nWidth; - } - else { - x = pRun->member.run.pt.x; - x += ME_PointFromChar(editor, &pRun->member.run, pCursor->nOffset, TRUE); - } + else + { + x = run->pt.x; + x += ME_PointFromChar( editor, run, pCursor->nOffset, TRUE ); editor->nUDArrowX = x; } return x; } -static void -ME_MoveCursorLines(ME_TextEditor *editor, ME_Cursor *pCursor, int nRelOfs, BOOL extend) +static void cursor_move_line( ME_TextEditor *editor, ME_Cursor *cursor, BOOL up, BOOL extend ) { - ME_DisplayItem *pRun = pCursor->pRun; - ME_DisplayItem *pOldPara = pCursor->pPara; - ME_DisplayItem *pItem, *pNewPara; - int x = ME_GetXForArrow(editor, pCursor); - - if (editor->bCaretAtEnd && !pCursor->nOffset) - if (!ME_PrevRun(&pOldPara, &pRun, TRUE)) - return; + ME_Paragraph *old_para = cursor->para, *new_para; + ME_Row *row = row_from_cursor( cursor ); + int x = ME_GetXForArrow( editor, cursor ); - if (nRelOfs == -1) - { - /* start of this row */ - pItem = ME_FindItemBack(pRun, diStartRow); - assert(pItem); - /* start of the previous row */ - pItem = ME_FindItemBack(pItem, diStartRow); - if (!pItem) /* row not found */ - { - if (extend) - ME_SetCursorToStart(editor, pCursor); - return; - } - pNewPara = ME_GetParagraph(pItem); - if (pOldPara->member.para.nFlags & MEPF_ROWEND || - (pOldPara->member.para.pCell && - pOldPara->member.para.pCell != pNewPara->member.para.pCell)) - { - /* Brought out of a cell */ - pNewPara = ME_GetTableRowStart(pOldPara)->member.para.prev_para; - if (pNewPara->type == diTextStart) - return; /* At the top, so don't go anywhere. */ - pItem = ME_FindItemFwd(pNewPara, diStartRow); - } - if (pNewPara->member.para.nFlags & MEPF_ROWEND) + if (up) { - /* Brought into a table row */ - ME_Cell *cell = &ME_FindItemBack(pNewPara, diCell)->member.cell; - while (x < cell->pt.x && cell->prev_cell) - cell = &cell->prev_cell->member.cell; - if (cell->next_cell) /* else - we are still at the end of the row */ - pItem = ME_FindItemBack(cell->next_cell, diStartRow); - } - } - else - { - /* start of the next row */ - pItem = ME_FindItemFwd(pRun, diStartRow); - if (!pItem) /* row not found */ - { - if (extend) - ME_SetCursorToEnd(editor, pCursor, TRUE); - return; - } - pNewPara = ME_GetParagraph(pItem); - if (pOldPara->member.para.nFlags & MEPF_ROWSTART || - (pOldPara->member.para.pCell && - pOldPara->member.para.pCell != pNewPara->member.para.pCell)) - { - /* Brought out of a cell */ - pNewPara = ME_GetTableRowEnd(pOldPara)->member.para.next_para; - if (pNewPara->type == diTextEnd) - return; /* At the bottom, so don't go anywhere. */ - pItem = ME_FindItemFwd(pNewPara, diStartRow); + /* start of the previous row */ + row = row_prev_all_paras( row ); + if (!row) + { + if (extend) ME_SetCursorToStart( editor, cursor ); + return; + } + new_para = row_para( row ); + if (old_para->nFlags & MEPF_ROWEND || + (para_cell( old_para ) && para_cell( old_para ) != para_cell( new_para ))) + { + /* Brought out of a cell */ + new_para = para_prev( table_row_start( old_para )); + if (!new_para) return; /* At the top, so don't go anywhere. */ + row = para_first_row( new_para ); + } + if (new_para->nFlags & MEPF_ROWEND) + { + /* Brought into a table row */ + ME_Cell *cell = table_row_end_cell( new_para ); + while (x < cell->pt.x && cell_prev( cell )) + cell = cell_prev( cell ); + if (cell_next( cell )) /* else - we are still at the end of the row */ + row = para_end_row( cell_end_para( cell ) ); + } } - if (pNewPara->member.para.nFlags & MEPF_ROWSTART) + else { - /* Brought into a table row */ - ME_DisplayItem *cell = ME_FindItemFwd(pNewPara, diCell); - while (cell->member.cell.next_cell && - x >= cell->member.cell.next_cell->member.cell.pt.x) - cell = cell->member.cell.next_cell; - pItem = ME_FindItemFwd(cell, diStartRow); + /* start of the next row */ + row = row_next_all_paras( row ); + if (!row) + { + if (extend) ME_SetCursorToEnd( editor, cursor, TRUE ); + return; + } + new_para = row_para( row ); + if (old_para->nFlags & MEPF_ROWSTART || + (para_cell( old_para ) && para_cell( old_para ) != para_cell( new_para ))) + { + /* Brought out of a cell */ + new_para = para_next( table_row_end( old_para ) ); + if (!para_next( new_para )) return; /* At the bottom, so don't go anywhere. */ + row = para_first_row( new_para ); + } + if (new_para->nFlags & MEPF_ROWSTART) + { + /* Brought into a table row */ + ME_Cell *cell = table_row_first_cell( new_para ); + while (cell_next( cell ) && x >= cell_next( cell )->pt.x) + cell = cell_next( cell ); + row = para_first_row( cell_first_para( cell ) ); + } } - } - if (!pItem) - { - /* row not found - ignore */ - return; - } - ME_FindRunInRow(editor, pItem, x, pCursor, &editor->bCaretAtEnd); - assert(pCursor->pRun); - assert(pCursor->pRun->type == diRun); + if (!row) return; + + row_cursor( editor, row, x, cursor ); } -static void ME_ArrowPageUp(ME_TextEditor *editor, ME_Cursor *pCursor) +static void ME_ArrowPageUp( ME_TextEditor *editor, ME_Cursor *cursor ) { - ME_DisplayItem *p = ME_FindItemFwd(editor->pBuffer->pFirst, diStartRow); + ME_Row *row = para_first_row( editor_first_para( editor ) ), *last_row; + int x, yd, old_scroll_pos = editor->vert_si.nPos; - if (editor->vert_si.nPos < p->member.row.nHeight) - { - ME_SetCursorToStart(editor, pCursor); - editor->bCaretAtEnd = FALSE; - /* Native clears seems to clear this x value on page up at the top - * of the text, but not on page down at the end of the text. - * Doesn't make sense, but we try to be bug for bug compatible. */ - editor->nUDArrowX = -1; - } else { - ME_DisplayItem *pRun = pCursor->pRun; - ME_DisplayItem *pLast; - int x, y, yd, yp; - int yOldScrollPos = editor->vert_si.nPos; - - x = ME_GetXForArrow(editor, pCursor); - if (!pCursor->nOffset && editor->bCaretAtEnd) - pRun = ME_FindItemBack(pRun, diRun); - - p = ME_FindItemBack(pRun, diStartRowOrParagraph); - assert(p->type == diStartRow); - yp = ME_FindItemBack(p, diParagraph)->member.para.pt.y; - y = yp + p->member.row.pt.y; + if (editor->vert_si.nPos < row->nHeight) + { + ME_SetCursorToStart( editor, cursor ); + /* Native clears seems to clear this x value on page up at the top + * of the text, but not on page down at the end of the text. + * Doesn't make sense, but we try to be bug for bug compatible. */ + editor->nUDArrowX = -1; + } + else + { + x = ME_GetXForArrow( editor, cursor ); + row = row_from_cursor( cursor ); - ME_ScrollUp(editor, editor->sizeWindow.cy); - /* Only move the cursor by the amount scrolled. */ - yd = y + editor->vert_si.nPos - yOldScrollPos; - pLast = p; + ME_ScrollUp( editor, editor->sizeWindow.cy ); + /* Only move the cursor by the amount scrolled. */ + yd = cursor->para->pt.y + row->pt.y + editor->vert_si.nPos - old_scroll_pos; + last_row = row; - do { - p = ME_FindItemBack(p, diStartRowOrParagraph); - if (!p) - break; - if (p->type == diParagraph) { /* crossing paragraphs */ - if (p->member.para.prev_para == NULL) - break; - yp = p->member.para.prev_para->member.para.pt.y; - continue; - } - y = yp + p->member.row.pt.y; - if (y < yd) - break; - pLast = p; - } while(1); + while ((row = row_prev_all_paras( row ))) + { + if (row_para( row )->pt.y + row->pt.y < yd) break; + last_row = row; + } - ME_FindRunInRow(editor, pLast, x, pCursor, &editor->bCaretAtEnd); - } - assert(pCursor->pRun); - assert(pCursor->pRun->type == diRun); + row_cursor( editor, last_row, x, cursor ); + } } -static void ME_ArrowPageDown(ME_TextEditor *editor, ME_Cursor *pCursor) +static void ME_ArrowPageDown( ME_TextEditor *editor, ME_Cursor *cursor ) { - ME_DisplayItem *pLast; - int x, y; + ME_Row *row = para_end_row( para_prev( editor_end_para( editor ) ) ), *last_row; + int x, yd, old_scroll_pos = editor->vert_si.nPos; - /* Find y position of the last row */ - pLast = editor->pBuffer->pLast; - y = pLast->member.para.prev_para->member.para.pt.y - + ME_FindItemBack(pLast, diStartRow)->member.row.pt.y; + x = ME_GetXForArrow( editor, cursor ); - x = ME_GetXForArrow(editor, pCursor); + if (editor->vert_si.nPos >= row_para( row )->pt.y + row->pt.y - editor->sizeWindow.cy) + ME_SetCursorToEnd( editor, cursor, FALSE ); + else + { + row = row_from_cursor( cursor ); - if (editor->vert_si.nPos >= y - editor->sizeWindow.cy) - { - ME_SetCursorToEnd(editor, pCursor, FALSE); - editor->bCaretAtEnd = FALSE; - } else { - ME_DisplayItem *pRun = pCursor->pRun; - ME_DisplayItem *p; - int yd, yp; - int yOldScrollPos = editor->vert_si.nPos; - - if (!pCursor->nOffset && editor->bCaretAtEnd) - pRun = ME_FindItemBack(pRun, diRun); - - p = ME_FindItemBack(pRun, diStartRowOrParagraph); - assert(p->type == diStartRow); - yp = ME_FindItemBack(p, diParagraph)->member.para.pt.y; - y = yp + p->member.row.pt.y; - - /* For native richedit controls: - * v1.0 - v3.1 can only scroll down as far as the scrollbar lets us - * v4.1 can scroll past this position here. */ - ME_ScrollDown(editor, editor->sizeWindow.cy); - /* Only move the cursor by the amount scrolled. */ - yd = y + editor->vert_si.nPos - yOldScrollPos; - pLast = p; + /* For native richedit controls: + * v1.0 - v3.1 can only scroll down as far as the scrollbar lets us + * v4.1 can scroll past this position here. */ + ME_ScrollDown( editor, editor->sizeWindow.cy ); + /* Only move the cursor by the amount scrolled. */ + yd = cursor->para->pt.y + row->pt.y + editor->vert_si.nPos - old_scroll_pos; + last_row = row; - do { - p = ME_FindItemFwd(p, diStartRowOrParagraph); - if (!p) - break; - if (p->type == diParagraph) { - yp = p->member.para.pt.y; - continue; - } - y = yp + p->member.row.pt.y; - if (y >= yd) - break; - pLast = p; - } while(1); + while ((row = row_next_all_paras( row ))) + { + if (row_para( row )->pt.y + row->pt.y >= yd) break; + last_row = row; + } - ME_FindRunInRow(editor, pLast, x, pCursor, &editor->bCaretAtEnd); - } - assert(pCursor->pRun); - assert(pCursor->pRun->type == diRun); + row_cursor( editor, last_row, x, cursor ); + } } -static void ME_ArrowHome(ME_TextEditor *editor, ME_Cursor *pCursor) +static void ME_ArrowHome( ME_TextEditor *editor, ME_Cursor *cursor ) { - ME_DisplayItem *pRow = ME_FindItemBack(pCursor->pRun, diStartRow); - if (pRow) { - ME_DisplayItem *pRun; - if (editor->bCaretAtEnd && !pCursor->nOffset) { - pRow = ME_FindItemBack(pRow, diStartRow); - if (!pRow) - return; - } - pRun = ME_FindItemFwd(pRow, diRun); - if (pRun) { - pCursor->pRun = pRun; - assert(pCursor->pPara == ME_GetParagraph(pRun)); - pCursor->nOffset = 0; - } - } - editor->bCaretAtEnd = FALSE; + ME_Row *row = row_from_cursor( cursor ); + + row_first_cursor( row, cursor ); } static void ME_ArrowCtrlHome(ME_TextEditor *editor, ME_Cursor *pCursor) { ME_SetCursorToStart(editor, pCursor); - editor->bCaretAtEnd = FALSE; } -static void ME_ArrowEnd(ME_TextEditor *editor, ME_Cursor *pCursor) +static void ME_ArrowEnd( ME_TextEditor *editor, ME_Cursor *cursor ) { - ME_DisplayItem *pRow; - - if (editor->bCaretAtEnd && !pCursor->nOffset) - return; - - pRow = ME_FindItemFwd(pCursor->pRun, diStartRowOrParagraphOrEnd); - assert(pRow); - if (pRow->type == diStartRow) { - ME_DisplayItem *pRun = ME_FindItemFwd(pRow, diRun); - assert(pRun); - pCursor->pRun = pRun; - assert(pCursor->pPara == ME_GetParagraph(pCursor->pRun)); - pCursor->nOffset = 0; - editor->bCaretAtEnd = TRUE; - return; - } - pCursor->pRun = ME_FindItemBack(pRow, diRun); - assert(pCursor->pRun && pCursor->pRun->member.run.nFlags & MERF_ENDPARA); - assert(pCursor->pPara == ME_GetParagraph(pCursor->pRun)); - pCursor->nOffset = 0; - editor->bCaretAtEnd = FALSE; + ME_Row *row = row_from_cursor( cursor ); + + row_end_cursor( row, cursor, FALSE ); } static void ME_ArrowCtrlEnd(ME_TextEditor *editor, ME_Cursor *pCursor) { ME_SetCursorToEnd(editor, pCursor, FALSE); - editor->bCaretAtEnd = FALSE; } BOOL ME_IsSelection(ME_TextEditor *editor) { - return editor->pCursors[0].pRun != editor->pCursors[1].pRun || + return editor->pCursors[0].run != editor->pCursors[1].run || editor->pCursors[0].nOffset != editor->pCursors[1].nOffset; } @@ -1592,7 +1414,7 @@ void ME_DeleteSelection(ME_TextEditor *editor) ME_Style *ME_GetSelectionInsertStyle(ME_TextEditor *editor) { - return ME_GetInsertStyle(editor, 0); + return style_get_insert_style( editor, editor->pCursors ); } void ME_SendSelChange(ME_TextEditor *editor) @@ -1637,24 +1459,22 @@ ME_ArrowKey(ME_TextEditor *editor, int nVKey, BOOL extend, BOOL ctrl) ME_CheckCharOffsets(editor); switch(nVKey) { case VK_LEFT: - editor->bCaretAtEnd = FALSE; if (ctrl) success = ME_MoveCursorWords(editor, &tmp_curs, -1); else success = ME_MoveCursorChars(editor, &tmp_curs, -1, extend); break; case VK_RIGHT: - editor->bCaretAtEnd = FALSE; if (ctrl) success = ME_MoveCursorWords(editor, &tmp_curs, +1); else success = ME_MoveCursorChars(editor, &tmp_curs, +1, extend); break; case VK_UP: - ME_MoveCursorLines(editor, &tmp_curs, -1, extend); + cursor_move_line( editor, &tmp_curs, TRUE, extend ); break; case VK_DOWN: - ME_MoveCursorLines(editor, &tmp_curs, +1, extend); + cursor_move_line( editor, &tmp_curs, FALSE, extend ); break; case VK_PRIOR: ME_ArrowPageUp(editor, &tmp_curs); @@ -1667,7 +1487,6 @@ ME_ArrowKey(ME_TextEditor *editor, int nVKey, BOOL extend, BOOL ctrl) ME_ArrowCtrlHome(editor, &tmp_curs); else ME_ArrowHome(editor, &tmp_curs); - editor->bCaretAtEnd = FALSE; break; } case VK_END: @@ -1685,7 +1504,7 @@ ME_ArrowKey(ME_TextEditor *editor, int nVKey, BOOL extend, BOOL ctrl) ME_InvalidateSelection(editor); ME_Repaint(editor); hide_caret(editor); - ME_EnsureVisible(editor, &tmp_curs); + editor_ensure_visible( editor, &tmp_curs ); update_caret(editor); ME_SendSelChange(editor); return success; diff --git a/dll/win32/riched20/clipboard.c b/dll/win32/riched20/clipboard.c index 578fb02fd99b6..10a814214be5e 100644 --- a/dll/win32/riched20/clipboard.c +++ b/dll/win32/riched20/clipboard.c @@ -344,13 +344,12 @@ static HGLOBAL get_unicode_text(ME_TextEditor *editor, const ME_Cursor *start, i int pars = 0; WCHAR *data; HANDLE ret; - ME_DisplayItem *para; + ME_Paragraph *para; int nEnd = ME_GetCursorOfs(start) + nChars; /* count paragraphs in range */ - para = start->pPara; - while((para = para->member.para.next_para) && - para->member.para.nCharOfs <= nEnd) + para = start->para; + while ((para = para_next( para )) && para->nCharOfs <= nEnd) pars++; ret = GlobalAlloc(GMEM_MOVEABLE, sizeof(WCHAR) * (nChars + pars + 1)); diff --git a/dll/win32/riched20/editor.c b/dll/win32/riched20/editor.c index cbc959851ec1d..d08f781d1dac2 100644 --- a/dll/win32/riched20/editor.c +++ b/dll/win32/riched20/editor.c @@ -250,24 +250,12 @@ WINE_DEFAULT_DEBUG_CHANNEL(richedit); -static BOOL ME_RegisterEditorClass(HINSTANCE); static BOOL ME_UpdateLinkAttribute(ME_TextEditor *editor, ME_Cursor *start, int nChars); -static const WCHAR REListBox20W[] = {'R','E','L','i','s','t','B','o','x','2','0','W', 0}; -static const WCHAR REComboBox20W[] = {'R','E','C','o','m','b','o','B','o','x','2','0','W', 0}; -static HCURSOR hLeft; - +HINSTANCE dll_instance = NULL; BOOL me_debug = FALSE; HANDLE me_heap = NULL; -static BOOL ME_ListBoxRegistered = FALSE; -static BOOL ME_ComboBoxRegistered = FALSE; - -static inline BOOL is_version_nt(void) -{ - return !(GetVersion() & 0x80000000); -} - static ME_TextBuffer *ME_MakeText(void) { ME_TextBuffer *buf = heap_alloc(sizeof(*buf)); ME_DisplayItem *p1 = ME_MakeDI(diTextStart); @@ -288,6 +276,21 @@ static ME_TextBuffer *ME_MakeText(void) { return buf; } +ME_Paragraph *editor_first_para( ME_TextEditor *editor ) +{ + return para_next( &editor->pBuffer->pFirst->member.para ); +} + +/* Note, returns the diTextEnd sentinel paragraph */ +ME_Paragraph *editor_end_para( ME_TextEditor *editor ) +{ + return &editor->pBuffer->pLast->member.para; +} + +static BOOL editor_beep( ME_TextEditor *editor, UINT type ) +{ + return editor->props & TXTBIT_ALLOWBEEP && MessageBeep( type ); +} static LRESULT ME_StreamInText(ME_TextEditor *editor, DWORD dwFormat, ME_InStream *stream, ME_Style *style) { @@ -583,27 +586,29 @@ void ME_RTFParAttrHook(RTF_Info *info) if (!info->editor->bEmulateVersion10) /* v4.1 */ { - if (info->tableDef && info->tableDef->tableRowStart && - info->tableDef->tableRowStart->member.para.nFlags & MEPF_ROWEND) + if (info->tableDef && info->tableDef->row_start && + info->tableDef->row_start->nFlags & MEPF_ROWEND) { ME_Cursor cursor; - ME_DisplayItem *para; + ME_Paragraph *para; /* We are just after a table row. */ RTFFlushOutputBuffer(info); cursor = info->editor->pCursors[0]; - para = cursor.pPara; - if (para == info->tableDef->tableRowStart->member.para.next_para - && !cursor.nOffset && !cursor.pRun->member.run.nCharOfs) + para = cursor.para; + if (para == para_next( info->tableDef->row_start ) + && !cursor.nOffset && !cursor.run->nCharOfs) { /* Since the table row end, no text has been inserted, and the \intbl * control word has not be used. We can confirm that we are not in a * table anymore. */ - info->tableDef->tableRowStart = NULL; + info->tableDef->row_start = NULL; info->canInheritInTbl = FALSE; } } - } else { /* v1.0 - v3.0 */ + } + else /* v1.0 - v3.0 */ + { info->fmt.dwMask |= PFM_TABLE; info->fmt.wEffects &= ~PFE_TABLE; } @@ -611,26 +616,25 @@ void ME_RTFParAttrHook(RTF_Info *info) case rtfNestLevel: if (!info->editor->bEmulateVersion10) /* v4.1 */ { - while (info->rtfParam > info->nestingLevel) { + while (info->rtfParam > info->nestingLevel) + { RTFTable *tableDef = heap_alloc_zero(sizeof(*tableDef)); tableDef->parent = info->tableDef; info->tableDef = tableDef; RTFFlushOutputBuffer(info); - if (tableDef->tableRowStart && - tableDef->tableRowStart->member.para.nFlags & MEPF_ROWEND) + if (tableDef->row_start && tableDef->row_start->nFlags & MEPF_ROWEND) + { + ME_Paragraph *para = para_next( tableDef->row_start ); + tableDef->row_start = table_insert_row_start_at_para( info->editor, para ); + } + else { - ME_DisplayItem *para = tableDef->tableRowStart; - para = para->member.para.next_para; - para = ME_InsertTableRowStartAtParagraph(info->editor, para); - tableDef->tableRowStart = para; - } else { ME_Cursor cursor; - WCHAR endl = '\r'; cursor = info->editor->pCursors[0]; - if (cursor.nOffset || cursor.pRun->member.run.nCharOfs) - ME_InsertTextFromCursor(info->editor, 0, &endl, 1, info->style); - tableDef->tableRowStart = ME_InsertTableRowStartFromCursor(info->editor); + if (cursor.nOffset || cursor.run->nCharOfs) + ME_InsertTextFromCursor(info->editor, 0, L"\r", 1, info->style); + tableDef->row_start = table_insert_row_start( info->editor, info->editor->pCursors ); } info->nestingLevel++; @@ -645,25 +649,19 @@ void ME_RTFParAttrHook(RTF_Info *info) if (info->nestingLevel < 1) { RTFTable *tableDef; + ME_Paragraph *para; + if (!info->tableDef) info->tableDef = heap_alloc_zero(sizeof(*info->tableDef)); tableDef = info->tableDef; RTFFlushOutputBuffer(info); - if (tableDef->tableRowStart && - tableDef->tableRowStart->member.para.nFlags & MEPF_ROWEND) - { - ME_DisplayItem *para = tableDef->tableRowStart; - para = para->member.para.next_para; - para = ME_InsertTableRowStartAtParagraph(info->editor, para); - tableDef->tableRowStart = para; - } else { - ME_Cursor cursor; - WCHAR endl = '\r'; - cursor = info->editor->pCursors[0]; - if (cursor.nOffset || cursor.pRun->member.run.nCharOfs) - ME_InsertTextFromCursor(info->editor, 0, &endl, 1, info->style); - tableDef->tableRowStart = ME_InsertTableRowStartFromCursor(info->editor); - } + if (tableDef->row_start && tableDef->row_start->nFlags & MEPF_ROWEND) + para = para_next( tableDef->row_start ); + else + para = info->editor->pCursors[0].para; + + tableDef->row_start = table_insert_row_start_at_para( info->editor, para ); + info->nestingLevel = 1; info->canInheritInTbl = TRUE; } @@ -680,7 +678,7 @@ void ME_RTFParAttrHook(RTF_Info *info) { PARAFORMAT2 fmt; fmt.cbSize = sizeof(fmt); - ME_GetSelectionParaFormat(info->editor, &fmt); + editor_get_selection_para_fmt( info->editor, &fmt ); info->fmt.dwMask |= PFM_STARTINDENT | PFM_OFFSET; info->fmt.dxStartIndent = fmt.dxStartIndent; info->fmt.dxOffset = fmt.dxOffset; @@ -715,7 +713,7 @@ void ME_RTFParAttrHook(RTF_Info *info) { PARAFORMAT2 fmt; fmt.cbSize = sizeof(fmt); - ME_GetSelectionParaFormat(info->editor, &fmt); + editor_get_selection_para_fmt( info->editor, &fmt ); memcpy(info->fmt.rgxTabs, fmt.rgxTabs, fmt.cTabCount * sizeof(fmt.rgxTabs[0])); info->fmt.cTabCount = fmt.cTabCount; @@ -899,13 +897,13 @@ void ME_RTFTblAttrHook(RTF_Info *info) if (cellNum >= MAX_TABLE_CELLS) break; info->tableDef->cells[cellNum].rightBoundary = info->rtfParam; - if (cellNum < MAX_TAB_STOPS) { + if (cellNum < MAX_TAB_STOPS) + { /* Tab stops were used to store cell positions before v4.1 but v4.1 * still seems to set the tabstops without using them. */ - ME_DisplayItem *para = info->editor->pCursors[0].pPara; - PARAFORMAT2 *pFmt = ¶->member.para.fmt; - pFmt->rgxTabs[cellNum] &= ~0x00FFFFFF; - pFmt->rgxTabs[cellNum] |= 0x00FFFFFF & info->rtfParam; + PARAFORMAT2 *fmt = &info->editor->pCursors[0].para->fmt; + fmt->rgxTabs[cellNum] &= ~0x00FFFFFF; + fmt->rgxTabs[cellNum] |= 0x00FFFFFF & info->rtfParam; } info->tableDef->numCellsDefined++; break; @@ -958,25 +956,24 @@ void ME_RTFSpecialCharHook(RTF_Info *info) if (!tableDef) break; RTFFlushOutputBuffer(info); - if (!info->editor->bEmulateVersion10) { /* v4.1 */ - if (tableDef->tableRowStart) + if (!info->editor->bEmulateVersion10) /* v4.1 */ + { + if (tableDef->row_start) { - if (!info->nestingLevel && - tableDef->tableRowStart->member.para.nFlags & MEPF_ROWEND) + if (!info->nestingLevel && tableDef->row_start->nFlags & MEPF_ROWEND) { - ME_DisplayItem *para = tableDef->tableRowStart; - para = para->member.para.next_para; - para = ME_InsertTableRowStartAtParagraph(info->editor, para); - tableDef->tableRowStart = para; + ME_Paragraph *para = para_next( tableDef->row_start ); + tableDef->row_start = table_insert_row_start_at_para( info->editor, para ); info->nestingLevel = 1; } - ME_InsertTableCellFromCursor(info->editor); + table_insert_cell( info->editor, info->editor->pCursors ); } - } else { /* v1.0 - v3.0 */ - ME_DisplayItem *para = info->editor->pCursors[0].pPara; - PARAFORMAT2 *pFmt = ¶->member.para.fmt; - if (pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE && - tableDef->numCellsInserted < tableDef->numCellsDefined) + } + else /* v1.0 - v3.0 */ + { + ME_Paragraph *para = info->editor->pCursors[0].para; + + if (para_in_table( para ) && tableDef->numCellsInserted < tableDef->numCellsDefined) { WCHAR tab = '\t'; ME_InsertTextFromCursor(info->editor, 0, &tab, 1, info->style); @@ -990,68 +987,68 @@ void ME_RTFSpecialCharHook(RTF_Info *info) /* else fall through since v4.1 treats rtfNestRow and rtfRow the same */ case rtfRow: { - ME_DisplayItem *para, *cell, *run; + ME_Run *run; + ME_Paragraph *para; + ME_Cell *cell; int i; if (!tableDef) break; RTFFlushOutputBuffer(info); - if (!info->editor->bEmulateVersion10) { /* v4.1 */ - if (!tableDef->tableRowStart) - break; - if (!info->nestingLevel && - tableDef->tableRowStart->member.para.nFlags & MEPF_ROWEND) + if (!info->editor->bEmulateVersion10) /* v4.1 */ + { + if (!tableDef->row_start) break; + if (!info->nestingLevel && tableDef->row_start->nFlags & MEPF_ROWEND) { - para = tableDef->tableRowStart; - para = para->member.para.next_para; - para = ME_InsertTableRowStartAtParagraph(info->editor, para); - tableDef->tableRowStart = para; + para = para_next( tableDef->row_start ); + tableDef->row_start = table_insert_row_start_at_para( info->editor, para ); info->nestingLevel++; } - para = tableDef->tableRowStart; - cell = ME_FindItemFwd(para, diCell); - assert(cell && !cell->member.cell.prev_cell); + para = tableDef->row_start; + cell = table_row_first_cell( para ); + assert( cell && !cell_prev( cell ) ); if (tableDef->numCellsDefined < 1) { /* 2000 twips appears to be the cell size that native richedit uses * when no cell sizes are specified. */ - const int defaultCellSize = 2000; - int nRightBoundary = defaultCellSize; - cell->member.cell.nRightBoundary = nRightBoundary; - while (cell->member.cell.next_cell) { - cell = cell->member.cell.next_cell; - nRightBoundary += defaultCellSize; - cell->member.cell.nRightBoundary = nRightBoundary; + const int default_size = 2000; + int right_boundary = default_size; + cell->nRightBoundary = right_boundary; + while (cell_next( cell )) + { + cell = cell_next( cell ); + right_boundary += default_size; + cell->nRightBoundary = right_boundary; } - para = ME_InsertTableCellFromCursor(info->editor); - cell = para->member.para.pCell; - cell->member.cell.nRightBoundary = nRightBoundary; - } else { + para = table_insert_cell( info->editor, info->editor->pCursors ); + cell = para_cell( para ); + cell->nRightBoundary = right_boundary; + } + else + { for (i = 0; i < tableDef->numCellsDefined; i++) { RTFCell *cellDef = &tableDef->cells[i]; - cell->member.cell.nRightBoundary = cellDef->rightBoundary; - ME_ApplyBorderProperties(info, &cell->member.cell.border, - cellDef->border); - cell = cell->member.cell.next_cell; + cell->nRightBoundary = cellDef->rightBoundary; + ME_ApplyBorderProperties( info, &cell->border, cellDef->border ); + cell = cell_next( cell ); if (!cell) { - para = ME_InsertTableCellFromCursor(info->editor); - cell = para->member.para.pCell; + para = table_insert_cell( info->editor, info->editor->pCursors ); + cell = para_cell( para ); } } /* Cell for table row delimiter is empty */ - cell->member.cell.nRightBoundary = tableDef->cells[i-1].rightBoundary; + cell->nRightBoundary = tableDef->cells[i - 1].rightBoundary; } - run = ME_FindItemFwd(cell, diRun); - if (info->editor->pCursors[0].pRun != run || - info->editor->pCursors[0].nOffset) + run = para_first_run( cell_first_para( cell ) ); + if (info->editor->pCursors[0].run != run || info->editor->pCursors[0].nOffset) { int nOfs, nChars; /* Delete inserted cells that aren't defined. */ - info->editor->pCursors[1].pRun = run; - info->editor->pCursors[1].pPara = ME_GetParagraph(run); + info->editor->pCursors[1].run = run; + info->editor->pCursors[1].para = run->para; info->editor->pCursors[1].nOffset = 0; nOfs = ME_GetCursorOfs(&info->editor->pCursors[1]); nChars = ME_GetCursorOfs(&info->editor->pCursors[0]) - nOfs; @@ -1059,59 +1056,59 @@ void ME_RTFSpecialCharHook(RTF_Info *info) nChars, TRUE); } - para = ME_InsertTableRowEndFromCursor(info->editor); - para->member.para.fmt.dxOffset = abs(info->tableDef->gapH); - para->member.para.fmt.dxStartIndent = info->tableDef->leftEdge; - ME_ApplyBorderProperties(info, ¶->member.para.border, - tableDef->border); + para = table_insert_row_end( info->editor, info->editor->pCursors ); + para->fmt.dxOffset = abs(info->tableDef->gapH); + para->fmt.dxStartIndent = info->tableDef->leftEdge; + ME_ApplyBorderProperties( info, ¶->border, tableDef->border ); info->nestingLevel--; if (!info->nestingLevel) { - if (info->canInheritInTbl) { - tableDef->tableRowStart = para; - } else { - while (info->tableDef) { + if (info->canInheritInTbl) tableDef->row_start = para; + else + { + while (info->tableDef) + { tableDef = info->tableDef; info->tableDef = tableDef->parent; heap_free(tableDef); } } - } else { + } + else + { info->tableDef = tableDef->parent; heap_free(tableDef); } - } else { /* v1.0 - v3.0 */ - WCHAR endl = '\r'; - ME_DisplayItem *para = info->editor->pCursors[0].pPara; - PARAFORMAT2 *pFmt = ¶->member.para.fmt; - pFmt->dxOffset = info->tableDef->gapH; - pFmt->dxStartIndent = info->tableDef->leftEdge; - - ME_ApplyBorderProperties(info, ¶->member.para.border, - tableDef->border); + } + else /* v1.0 - v3.0 */ + { + para = info->editor->pCursors[0].para; + para->fmt.dxOffset = info->tableDef->gapH; + para->fmt.dxStartIndent = info->tableDef->leftEdge; + + ME_ApplyBorderProperties( info, ¶->border, tableDef->border ); while (tableDef->numCellsInserted < tableDef->numCellsDefined) { WCHAR tab = '\t'; ME_InsertTextFromCursor(info->editor, 0, &tab, 1, info->style); tableDef->numCellsInserted++; } - pFmt->cTabCount = min(tableDef->numCellsDefined, MAX_TAB_STOPS); - if (!tableDef->numCellsDefined) - pFmt->wEffects &= ~PFE_TABLE; - ME_InsertTextFromCursor(info->editor, 0, &endl, 1, info->style); + para->fmt.cTabCount = min(tableDef->numCellsDefined, MAX_TAB_STOPS); + if (!tableDef->numCellsDefined) para->fmt.wEffects &= ~PFE_TABLE; + ME_InsertTextFromCursor(info->editor, 0, L"\r", 1, info->style); tableDef->numCellsInserted = 0; } break; } case rtfTab: case rtfPar: - if (info->editor->bEmulateVersion10) { /* v1.0 - 3.0 */ - ME_DisplayItem *para; - PARAFORMAT2 *pFmt; + if (info->editor->bEmulateVersion10) /* v1.0 - 3.0 */ + { + ME_Paragraph *para; + RTFFlushOutputBuffer(info); - para = info->editor->pCursors[0].pPara; - pFmt = ¶->member.para.fmt; - if (pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE) + para = info->editor->pCursors[0].para; + if (para_in_table( para )) { /* rtfPar is treated like a space within a table. */ info->rtfClass = rtfText; @@ -1132,7 +1129,6 @@ static HRESULT insert_static_object(ME_TextEditor *editor, HENHMETAFILE hemf, HB LPOLECLIENTSITE lpClientSite = NULL; LPDATAOBJECT lpDataObject = NULL; LPOLECACHE lpOleCache = NULL; - LPRICHEDITOLE lpReOle = NULL; STGMEDIUM stgm; FORMATETC fm; CLSID clsid; @@ -1151,6 +1147,8 @@ static HRESULT insert_static_object(ME_TextEditor *editor, HENHMETAFILE hemf, HB stgm.u.hBitmap = hbmp; fm.cfFormat = CF_BITMAP; } + else return E_FAIL; + stgm.pUnkForRelease = NULL; fm.ptd = NULL; @@ -1158,15 +1156,8 @@ static HRESULT insert_static_object(ME_TextEditor *editor, HENHMETAFILE hemf, HB fm.lindex = -1; fm.tymed = stgm.tymed; - if (!editor->reOle) - { - if (!CreateIRichEditOle(NULL, editor, (LPVOID *)&editor->reOle)) - return hr; - } - if (OleCreateDefaultHandler(&CLSID_NULL, NULL, &IID_IOleObject, (void**)&lpObject) == S_OK && - IUnknown_QueryInterface(editor->reOle, &IID_IRichEditOle, (void**)&lpReOle) == S_OK && - IRichEditOle_GetClientSite(lpReOle, &lpClientSite) == S_OK && + IRichEditOle_GetClientSite(editor->richole, &lpClientSite) == S_OK && IOleObject_SetClientSite(lpObject, lpClientSite) == S_OK && IOleObject_GetUserClassID(lpObject, &clsid) == S_OK && IOleObject_QueryInterface(lpObject, &IID_IOleCache, (void**)&lpOleCache) == S_OK && @@ -1198,7 +1189,6 @@ static HRESULT insert_static_object(ME_TextEditor *editor, HENHMETAFILE hemf, HB if (lpStorage) IStorage_Release(lpStorage); if (lpDataObject) IDataObject_Release(lpDataObject); if (lpOleCache) IOleCache_Release(lpOleCache); - if (lpReOle) IRichEditOle_Release(lpReOle); return hr; } @@ -1605,29 +1595,27 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre ME_InternalDeleteText(editor, selStart, to - from, FALSE); /* Don't insert text at the end of the table row */ - if (!editor->bEmulateVersion10) { /* v4.1 */ - ME_DisplayItem *para = editor->pCursors->pPara; - if (para->member.para.nFlags & MEPF_ROWEND) - { - para = para->member.para.next_para; - editor->pCursors[0].pPara = para; - editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); - editor->pCursors[0].nOffset = 0; - } - if (para->member.para.nFlags & MEPF_ROWSTART) + if (!editor->bEmulateVersion10) /* v4.1 */ + { + ME_Paragraph *para = editor->pCursors->para; + if (para->nFlags & (MEPF_ROWSTART | MEPF_ROWEND)) { - para = para->member.para.next_para; - editor->pCursors[0].pPara = para; - editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); + para = para_next( para ); + editor->pCursors[0].para = para; + editor->pCursors[0].run = para_first_run( para ); editor->pCursors[0].nOffset = 0; } editor->pCursors[1] = editor->pCursors[0]; - } else { /* v1.0 - 3.0 */ - if (editor->pCursors[0].pRun->member.run.nFlags & MERF_ENDPARA && - ME_IsInTable(editor->pCursors[0].pRun)) + } + else /* v1.0 - 3.0 */ + { + if (editor->pCursors[0].run->nFlags & MERF_ENDPARA && + para_in_table( editor->pCursors[0].para )) return 0; } - } else { + } + else + { style = editor->pBuffer->pDefaultStyle; ME_AddRefStyle(style); set_selection_cursors(editor, 0, 0); @@ -1635,7 +1623,7 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre ME_GetTextLength(editor), FALSE); from = to = 0; ME_ClearTempStyle(editor); - ME_SetDefaultParaFormat(editor, &editor->pCursors[0].pPara->member.para.fmt); + editor_set_default_para_fmt( editor, &editor->pCursors[0].para->fmt ); } @@ -1695,13 +1683,14 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre /* do the parsing */ RTFRead(&parser); RTFFlushOutputBuffer(&parser); - if (!editor->bEmulateVersion10) { /* v4.1 */ - if (parser.tableDef && parser.tableDef->tableRowStart && + if (!editor->bEmulateVersion10) /* v4.1 */ + { + if (parser.tableDef && parser.tableDef->row_start && (parser.nestingLevel > 0 || parser.canInheritInTbl)) { /* Delete any incomplete table row at the end of the rich text. */ int nOfs, nChars; - ME_DisplayItem *para; + ME_Paragraph *para; parser.rtfMinor = rtfRow; /* Complete the table row before deleting it. @@ -1712,26 +1701,26 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre { while (parser.nestingLevel > 1) ME_RTFSpecialCharHook(&parser); /* Decrements nestingLevel */ - para = parser.tableDef->tableRowStart; + para = parser.tableDef->row_start; ME_RTFSpecialCharHook(&parser); - } else { - para = parser.tableDef->tableRowStart; + } + else + { + para = parser.tableDef->row_start; ME_RTFSpecialCharHook(&parser); - assert(para->member.para.nFlags & MEPF_ROWEND); - para = para->member.para.next_para; + assert( para->nFlags & MEPF_ROWEND ); + para = para_next( para ); } - editor->pCursors[1].pPara = para; - editor->pCursors[1].pRun = ME_FindItemFwd(para, diRun); + editor->pCursors[1].para = para; + editor->pCursors[1].run = para_first_run( para ); editor->pCursors[1].nOffset = 0; nOfs = ME_GetCursorOfs(&editor->pCursors[1]); nChars = ME_GetCursorOfs(&editor->pCursors[0]) - nOfs; ME_InternalDeleteText(editor, &editor->pCursors[1], nChars, TRUE); - if (parser.tableDef) - parser.tableDef->tableRowStart = NULL; + if (parser.tableDef) parser.tableDef->row_start = NULL; } } - ME_CheckTablesForCorruption(editor); RTFDestroy(&parser); if (parser.stackTop > 0) @@ -1790,7 +1779,7 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre /* put the cursor at the top */ if (!(format & SFF_SELECTION)) set_selection_cursors(editor, 0, 0); - ME_CursorFromCharOfs(editor, from, &start); + cursor_from_char_ofs( editor, from, &start ); ME_UpdateLinkAttribute(editor, &start, to - from); } @@ -1810,7 +1799,6 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre if (!(format & SFF_SELECTION)) { ME_ClearTempStyle(editor); } - update_caret(editor); ME_SendSelChange(editor); ME_SendRequestResize(editor, FALSE); @@ -1919,20 +1907,19 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH /* If possible, find the character before where the search starts */ if ((flags & FR_WHOLEWORD) && nMin) { - ME_CursorFromCharOfs(editor, nMin - 1, &cursor); - wLastChar = *get_text( &cursor.pRun->member.run, cursor.nOffset ); + cursor_from_char_ofs( editor, nMin - 1, &cursor ); + wLastChar = *get_text( cursor.run, cursor.nOffset ); ME_MoveCursorChars(editor, &cursor, 1, FALSE); - } else { - ME_CursorFromCharOfs(editor, nMin, &cursor); } + else cursor_from_char_ofs( editor, nMin, &cursor ); - while (cursor.pRun && ME_GetCursorOfs(&cursor) + nLen <= nMax) + while (cursor.run && ME_GetCursorOfs(&cursor) + nLen <= nMax) { - ME_DisplayItem *pCurItem = cursor.pRun; + ME_Run *run = cursor.run; int nCurStart = cursor.nOffset; int nMatched = 0; - while (pCurItem && ME_CharCompare( *get_text( &pCurItem->member.run, nCurStart + nMatched ), text[nMatched], (flags & FR_MATCHCASE))) + while (run && ME_CharCompare( *get_text( run, nCurStart + nMatched ), text[nMatched], (flags & FR_MATCHCASE))) { if ((flags & FR_WHOLEWORD) && iswalnum(wLastChar)) break; @@ -1940,21 +1927,21 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH nMatched++; if (nMatched == nLen) { - ME_DisplayItem *pNextItem = pCurItem; + ME_Run *next_run = run; int nNextStart = nCurStart; WCHAR wNextChar; /* Check to see if next character is a whitespace */ if (flags & FR_WHOLEWORD) { - if (nCurStart + nMatched == pCurItem->member.run.len) + if (nCurStart + nMatched == run->len) { - pNextItem = ME_FindItemFwd(pCurItem, diRun); + next_run = run_next_all_paras( run ); nNextStart = -nMatched; } - if (pNextItem) - wNextChar = *get_text( &pNextItem->member.run, nNextStart + nMatched ); + if (next_run) + wNextChar = *get_text( next_run, nNextStart + nMatched ); else wNextChar = ' '; @@ -1962,7 +1949,7 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH break; } - cursor.nOffset += cursor.pPara->member.para.nCharOfs + cursor.pRun->member.run.nCharOfs; + cursor.nOffset += cursor.para->nCharOfs + cursor.run->nCharOfs; if (chrgText) { chrgText->cpMin = cursor.nOffset; @@ -1971,22 +1958,28 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH TRACE("found at %d-%d\n", cursor.nOffset, cursor.nOffset + nLen); return cursor.nOffset; } - if (nCurStart + nMatched == pCurItem->member.run.len) + if (nCurStart + nMatched == run->len) { - pCurItem = ME_FindItemFwd(pCurItem, diRun); + run = run_next_all_paras( run ); nCurStart = -nMatched; } } - if (pCurItem) - wLastChar = *get_text( &pCurItem->member.run, nCurStart + nMatched ); + if (run) + wLastChar = *get_text( run, nCurStart + nMatched ); else wLastChar = ' '; cursor.nOffset++; - if (cursor.nOffset == cursor.pRun->member.run.len) + if (cursor.nOffset == cursor.run->len) { - ME_NextRun(&cursor.pPara, &cursor.pRun, TRUE); - cursor.nOffset = 0; + if (run_next_all_paras( cursor.run )) + { + cursor.run = run_next_all_paras( cursor.run ); + cursor.para = cursor.run->para; + cursor.nOffset = 0; + } + else + cursor.run = NULL; } } } @@ -1995,28 +1988,28 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH /* If possible, find the character after where the search ends */ if ((flags & FR_WHOLEWORD) && nMax < nTextLen - 1) { - ME_CursorFromCharOfs(editor, nMax + 1, &cursor); - wLastChar = *get_text( &cursor.pRun->member.run, cursor.nOffset ); + cursor_from_char_ofs( editor, nMax + 1, &cursor ); + wLastChar = *get_text( cursor.run, cursor.nOffset ); ME_MoveCursorChars(editor, &cursor, -1, FALSE); - } else { - ME_CursorFromCharOfs(editor, nMax, &cursor); } + else cursor_from_char_ofs( editor, nMax, &cursor ); - while (cursor.pRun && ME_GetCursorOfs(&cursor) - nLen >= nMin) + while (cursor.run && ME_GetCursorOfs(&cursor) - nLen >= nMin) { - ME_DisplayItem *pCurItem = cursor.pRun; - ME_DisplayItem *pCurPara = cursor.pPara; + ME_Run *run = cursor.run; + ME_Paragraph *para = cursor.para; int nCurEnd = cursor.nOffset; int nMatched = 0; - if (nCurEnd == 0) + if (nCurEnd == 0 && run_prev_all_paras( run )) { - ME_PrevRun(&pCurPara, &pCurItem, TRUE); - nCurEnd = pCurItem->member.run.len; + run = run_prev_all_paras( run ); + para = run->para; + nCurEnd = run->len; } - while (pCurItem && ME_CharCompare( *get_text( &pCurItem->member.run, nCurEnd - nMatched - 1 ), - text[nLen - nMatched - 1], (flags & FR_MATCHCASE) )) + while (run && ME_CharCompare( *get_text( run, nCurEnd - nMatched - 1 ), + text[nLen - nMatched - 1], (flags & FR_MATCHCASE) )) { if ((flags & FR_WHOLEWORD) && iswalnum(wLastChar)) break; @@ -2024,7 +2017,7 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH nMatched++; if (nMatched == nLen) { - ME_DisplayItem *pPrevItem = pCurItem; + ME_Run *prev_run = run; int nPrevEnd = nCurEnd; WCHAR wPrevChar; int nStart; @@ -2034,22 +2027,18 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH { if (nPrevEnd - nMatched == 0) { - pPrevItem = ME_FindItemBack(pCurItem, diRun); - if (pPrevItem) - nPrevEnd = pPrevItem->member.run.len + nMatched; + prev_run = run_prev_all_paras( run ); + if (prev_run) nPrevEnd = prev_run->len + nMatched; } - if (pPrevItem) - wPrevChar = *get_text( &pPrevItem->member.run, nPrevEnd - nMatched - 1 ); - else - wPrevChar = ' '; + if (prev_run) wPrevChar = *get_text( prev_run, nPrevEnd - nMatched - 1 ); + else wPrevChar = ' '; if (iswalnum(wPrevChar)) break; } - nStart = pCurPara->member.para.nCharOfs - + pCurItem->member.run.nCharOfs + nCurEnd - nMatched; + nStart = para->nCharOfs + run->nCharOfs + nCurEnd - nMatched; if (chrgText) { chrgText->cpMin = nStart; @@ -2060,22 +2049,32 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH } if (nCurEnd - nMatched == 0) { - ME_PrevRun(&pCurPara, &pCurItem, TRUE); + if (run_prev_all_paras( run )) + { + run = run_prev_all_paras( run ); + para = run->para; + } /* Don't care about pCurItem becoming NULL here; it's already taken * care of in the exterior loop condition */ - nCurEnd = pCurItem->member.run.len + nMatched; + nCurEnd = run->len + nMatched; } } - if (pCurItem) - wLastChar = *get_text( &pCurItem->member.run, nCurEnd - nMatched - 1 ); + if (run) + wLastChar = *get_text( run, nCurEnd - nMatched - 1 ); else wLastChar = ' '; cursor.nOffset--; if (cursor.nOffset < 0) { - ME_PrevRun(&cursor.pPara, &cursor.pRun, TRUE); - cursor.nOffset = cursor.pRun->member.run.len; + if (run_prev_all_paras( cursor.run ) ) + { + cursor.run = run_prev_all_paras( cursor.run ); + cursor.para = cursor.run->para; + cursor.nOffset = cursor.run->len; + } + else + cursor.run = NULL; } } } @@ -2137,22 +2136,11 @@ static int ME_GetTextEx(ME_TextEditor *editor, GETTEXTEX *ex, LPARAM pText) } } -static int ME_GetTextRange(ME_TextEditor *editor, WCHAR *strText, - const ME_Cursor *start, int nLen, BOOL unicode) +static int get_text_range( ME_TextEditor *editor, WCHAR *buffer, + const ME_Cursor *start, int len ) { - if (!strText) return 0; - if (unicode) { - return ME_GetTextW(editor, strText, INT_MAX, start, nLen, FALSE, FALSE); - } else { - int nChars; - WCHAR *p = heap_alloc((nLen+1) * sizeof(*p)); - if (!p) return 0; - nChars = ME_GetTextW(editor, p, nLen, start, nLen, FALSE, FALSE); - WideCharToMultiByte(CP_ACP, 0, p, nChars+1, (char *)strText, - nLen+1, NULL, NULL); - heap_free(p); - return nChars; - } + if (!buffer) return 0; + return ME_GetTextW( editor, buffer, INT_MAX, start, len, FALSE, FALSE ); } int set_selection( ME_TextEditor *editor, int to, int from ) @@ -2211,8 +2199,6 @@ static DWORD CALLBACK ME_ReadFromHGLOBALRTF(DWORD_PTR dwCookie, LPBYTE lpBuff, L return 0; } -static const WCHAR rtfW[] = {'R','i','c','h',' ','T','e','x','t',' ','F','o','r','m','a','t',0}; - static HRESULT paste_rtf(ME_TextEditor *editor, FORMATETC *fmt, STGMEDIUM *med) { EDITSTREAM es; @@ -2267,7 +2253,7 @@ static struct paste_format const WCHAR *name; } paste_formats[] = { - {{ -1, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, paste_rtf, rtfW }, + {{ -1, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, paste_rtf, L"Rich Text Format" }, {{ CF_UNICODETEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, paste_text }, {{ CF_ENHMETAFILE, NULL, DVASPECT_CONTENT, -1, TYMED_ENHMF }, paste_emf }, {{ 0 }} @@ -2297,10 +2283,9 @@ static BOOL paste_special(ME_TextEditor *editor, UINT cf, REPASTESPECIAL *ps, BO IDataObject *data; /* Protect read-only edit control from modification */ - if (editor->styleFlags & ES_READONLY) + if (editor->props & TXTBIT_READONLY) { - if (!check_only) - MessageBeep(MB_ICONERROR); + if (!check_only) editor_beep( editor, MB_ICONERROR ); return FALSE; } @@ -2337,146 +2322,111 @@ static BOOL paste_special(ME_TextEditor *editor, UINT cf, REPASTESPECIAL *ps, BO return hr == S_OK; } -static BOOL ME_Copy(ME_TextEditor *editor, const ME_Cursor *start, int nChars) +static HRESULT editor_copy( ME_TextEditor *editor, ME_Cursor *start, int chars, IDataObject **data_out ) { - LPDATAOBJECT dataObj = NULL; - HRESULT hr = S_OK; + IDataObject *data = NULL; + HRESULT hr = S_OK; - if (editor->cPasswordMask) - return FALSE; /* Copying or Cutting masked text isn't allowed */ + if (editor->lpOleCallback) + { + CHARRANGE range; + range.cpMin = ME_GetCursorOfs( start ); + range.cpMax = range.cpMin + chars; + hr = IRichEditOleCallback_GetClipboardData( editor->lpOleCallback, &range, RECO_COPY, &data ); + } - if(editor->lpOleCallback) - { - CHARRANGE range; - range.cpMin = ME_GetCursorOfs(start); - range.cpMax = range.cpMin + nChars; - hr = IRichEditOleCallback_GetClipboardData(editor->lpOleCallback, &range, RECO_COPY, &dataObj); - } - if(FAILED(hr) || !dataObj) - hr = ME_GetDataObject(editor, start, nChars, &dataObj); - if(SUCCEEDED(hr)) { - hr = OleSetClipboard(dataObj); - IDataObject_Release(dataObj); - } - return SUCCEEDED(hr); + if (FAILED( hr ) || !data) + hr = ME_GetDataObject( editor, start, chars, &data ); + + if (SUCCEEDED( hr )) + { + if (data_out) + *data_out = data; + else + { + hr = OleSetClipboard( data ); + IDataObject_Release( data ); + } + } + + return hr; } -static BOOL copy_or_cut(ME_TextEditor *editor, BOOL cut) +HRESULT editor_copy_or_cut( ME_TextEditor *editor, BOOL cut, ME_Cursor *start, int count, + IDataObject **data_out ) { - BOOL result; - int offs, num_chars; - int start_cursor = ME_GetSelectionOfs(editor, &offs, &num_chars); - ME_Cursor *sel_start = &editor->pCursors[start_cursor]; + HRESULT hr; - if (cut && (editor->styleFlags & ES_READONLY)) + if (cut && (editor->props & TXTBIT_READONLY)) { - MessageBeep(MB_ICONERROR); - return FALSE; + return E_ACCESSDENIED; } - num_chars -= offs; - result = ME_Copy(editor, sel_start, num_chars); - if (result && cut) + hr = editor_copy( editor, start, count, data_out ); + if (SUCCEEDED(hr) && cut) { - ME_InternalDeleteText(editor, sel_start, num_chars, FALSE); - ME_CommitUndo(editor); - ME_UpdateRepaint(editor, TRUE); + ME_InternalDeleteText( editor, start, count, FALSE ); + ME_CommitUndo( editor ); + ME_UpdateRepaint( editor, TRUE ); } - return result; + return hr; } -/* helper to send a msg filter notification */ -static BOOL -ME_FilterEvent(ME_TextEditor *editor, UINT msg, WPARAM* wParam, LPARAM* lParam) +static BOOL copy_or_cut( ME_TextEditor *editor, BOOL cut ) { - MSGFILTER msgf; - - if (!editor->hWnd || !editor->hwndParent) return FALSE; - msgf.nmhdr.hwndFrom = editor->hWnd; - msgf.nmhdr.idFrom = GetWindowLongW(editor->hWnd, GWLP_ID); - msgf.nmhdr.code = EN_MSGFILTER; - msgf.msg = msg; - msgf.wParam = *wParam; - msgf.lParam = *lParam; - if (SendMessageW(editor->hwndParent, WM_NOTIFY, msgf.nmhdr.idFrom, (LPARAM)&msgf)) - return FALSE; - *wParam = msgf.wParam; - *lParam = msgf.lParam; - msgf.wParam = *wParam; + HRESULT hr; + int offs, count; + int start_cursor = ME_GetSelectionOfs( editor, &offs, &count ); + ME_Cursor *sel_start = &editor->pCursors[start_cursor]; - return TRUE; + if (editor->password_char) return FALSE; + + count -= offs; + hr = editor_copy_or_cut( editor, cut, sel_start, count, NULL ); + if (FAILED( hr )) editor_beep( editor, MB_ICONERROR ); + + return SUCCEEDED( hr ); } static void ME_UpdateSelectionLinkAttribute(ME_TextEditor *editor) { - ME_DisplayItem *startPara, *endPara; - ME_DisplayItem *prev_para; - ME_Cursor *from, *to; - ME_Cursor start; - int nChars; + ME_Paragraph *start_para, *end_para; + ME_Cursor *from, *to, start; + int num_chars; if (!editor->AutoURLDetect_bEnable) return; ME_GetSelection(editor, &from, &to); /* Find paragraph previous to the one that contains start cursor */ - startPara = from->pPara; - prev_para = startPara->member.para.prev_para; - if (prev_para->type == diParagraph) startPara = prev_para; + start_para = from->para; + if (para_prev( start_para )) start_para = para_prev( start_para ); /* Find paragraph that contains end cursor */ - endPara = to->pPara->member.para.next_para; + end_para = para_next( to->para ); - start.pPara = startPara; - start.pRun = ME_FindItemFwd(startPara, diRun); + start.para = start_para; + start.run = para_first_run( start_para ); start.nOffset = 0; - nChars = endPara->member.para.nCharOfs - startPara->member.para.nCharOfs; + num_chars = end_para->nCharOfs - start_para->nCharOfs; - ME_UpdateLinkAttribute(editor, &start, nChars); + ME_UpdateLinkAttribute( editor, &start, num_chars ); } static BOOL handle_enter(ME_TextEditor *editor) { - BOOL ctrl_is_down = GetKeyState(VK_CONTROL) & 0x8000; BOOL shift_is_down = GetKeyState(VK_SHIFT) & 0x8000; - if (editor->bDialogMode) - { - if (ctrl_is_down) - return TRUE; - - if (!(editor->styleFlags & ES_WANTRETURN)) - { - if (editor->hwndParent) - { - DWORD dw; - dw = SendMessageW(editor->hwndParent, DM_GETDEFID, 0, 0); - if (HIWORD(dw) == DC_HASDEFID) - { - HWND hwDefCtrl = GetDlgItem(editor->hwndParent, LOWORD(dw)); - if (hwDefCtrl) - { - SendMessageW(editor->hwndParent, WM_NEXTDLGCTL, (WPARAM)hwDefCtrl, TRUE); - PostMessageW(hwDefCtrl, WM_KEYDOWN, VK_RETURN, 0); - } - } - } - return TRUE; - } - } - - if (editor->styleFlags & ES_MULTILINE) + if (editor->props & TXTBIT_MULTILINE) { - static const WCHAR endl = '\r'; - static const WCHAR endlv10[] = {'\r','\n'}; ME_Cursor cursor = editor->pCursors[0]; - ME_DisplayItem *para = cursor.pPara; + ME_Paragraph *para = cursor.para; int from, to; ME_Style *style, *eop_style; - if (editor->styleFlags & ES_READONLY) + if (editor->props & TXTBIT_READONLY) { - MessageBeep(MB_ICONERROR); + editor_beep( editor, MB_ICONERROR ); return TRUE; } @@ -2485,60 +2435,57 @@ static BOOL handle_enter(ME_TextEditor *editor) { if (!editor->bEmulateVersion10) /* v4.1 */ { - if (para->member.para.nFlags & MEPF_ROWEND) + if (para->nFlags & MEPF_ROWEND) { /* Add a new table row after this row. */ - para = ME_AppendTableRow(editor, para); - para = para->member.para.next_para; - editor->pCursors[0].pPara = para; - editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); + para = table_append_row( editor, para ); + para = para_next( para ); + editor->pCursors[0].para = para; + editor->pCursors[0].run = para_first_run( para ); editor->pCursors[0].nOffset = 0; editor->pCursors[1] = editor->pCursors[0]; ME_CommitUndo(editor); - ME_CheckTablesForCorruption(editor); ME_UpdateRepaint(editor, FALSE); return TRUE; } - else if (para == editor->pCursors[1].pPara && - cursor.nOffset + cursor.pRun->member.run.nCharOfs == 0 && - para->member.para.prev_para->member.para.nFlags & MEPF_ROWSTART && - !para->member.para.prev_para->member.para.nCharOfs) + else if (para == editor->pCursors[1].para && + cursor.nOffset + cursor.run->nCharOfs == 0 && + para_prev( para ) && para_prev( para )->nFlags & MEPF_ROWSTART && + !para_prev( para )->nCharOfs) { /* Insert a newline before the table. */ - para = para->member.para.prev_para; - para->member.para.nFlags &= ~MEPF_ROWSTART; - editor->pCursors[0].pPara = para; - editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); + para = para_prev( para ); + para->nFlags &= ~MEPF_ROWSTART; + editor->pCursors[0].para = para; + editor->pCursors[0].run = para_first_run( para ); editor->pCursors[1] = editor->pCursors[0]; - ME_InsertTextFromCursor(editor, 0, &endl, 1, - editor->pCursors[0].pRun->member.run.style); - para = editor->pBuffer->pFirst->member.para.next_para; - ME_SetDefaultParaFormat(editor, ¶->member.para.fmt); - para->member.para.nFlags = 0; - mark_para_rewrap(editor, para); - editor->pCursors[0].pPara = para; - editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); + ME_InsertTextFromCursor( editor, 0, L"\r", 1, editor->pCursors[0].run->style ); + para = editor_first_para( editor ); + editor_set_default_para_fmt( editor, ¶->fmt ); + para->nFlags = 0; + para_mark_rewrap( editor, para ); + editor->pCursors[0].para = para; + editor->pCursors[0].run = para_first_run( para ); editor->pCursors[1] = editor->pCursors[0]; - para->member.para.next_para->member.para.nFlags |= MEPF_ROWSTART; + para_next( para )->nFlags |= MEPF_ROWSTART; ME_CommitCoalescingUndo(editor); - ME_CheckTablesForCorruption(editor); ME_UpdateRepaint(editor, FALSE); return TRUE; } } else /* v1.0 - 3.0 */ { - ME_DisplayItem *para = cursor.pPara; - if (ME_IsInTable(para)) + ME_Paragraph *para = cursor.para; + if (para_in_table( para )) { - if (cursor.pRun->member.run.nFlags & MERF_ENDPARA) + if (cursor.run->nFlags & MERF_ENDPARA) { if (from == to) { ME_ContinueCoalescingTransaction(editor); - para = ME_AppendTableRow(editor, para); - editor->pCursors[0].pPara = para; - editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); + para = table_append_row( editor, para ); + editor->pCursors[0].para = para; + editor->pCursors[0].run = para_first_run( para ); editor->pCursors[0].nOffset = 0; editor->pCursors[1] = editor->pCursors[0]; ME_CommitCoalescingUndo(editor); @@ -2549,27 +2496,26 @@ static BOOL handle_enter(ME_TextEditor *editor) else { ME_ContinueCoalescingTransaction(editor); - if (cursor.pRun->member.run.nCharOfs + cursor.nOffset == 0 && - !ME_IsInTable(para->member.para.prev_para)) + if (cursor.run->nCharOfs + cursor.nOffset == 0 && + para_prev( para ) && !para_in_table( para_prev( para ) )) { /* Insert newline before table */ - cursor.pRun = ME_FindItemBack(para, diRun); - if (cursor.pRun) + cursor.run = para_end_run( para_prev( para ) ); + if (cursor.run) { - editor->pCursors[0].pRun = cursor.pRun; - editor->pCursors[0].pPara = para->member.para.prev_para; + editor->pCursors[0].run = cursor.run; + editor->pCursors[0].para = para_prev( para ); } editor->pCursors[0].nOffset = 0; editor->pCursors[1] = editor->pCursors[0]; - ME_InsertTextFromCursor(editor, 0, &endl, 1, - editor->pCursors[0].pRun->member.run.style); + ME_InsertTextFromCursor( editor, 0, L"\r", 1, editor->pCursors[0].run->style ); } else { editor->pCursors[1] = editor->pCursors[0]; - para = ME_AppendTableRow(editor, para); - editor->pCursors[0].pPara = para; - editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); + para = table_append_row( editor, para ); + editor->pCursors[0].para = para; + editor->pCursors[0].run = para_first_run( para ); editor->pCursors[0].nOffset = 0; editor->pCursors[1] = editor->pCursors[0]; } @@ -2580,13 +2526,13 @@ static BOOL handle_enter(ME_TextEditor *editor) } } - style = ME_GetInsertStyle(editor, 0); + style = style_get_insert_style( editor, editor->pCursors ); /* Normally the new eop style is the insert style, however in a list it is copied from the existing eop style (this prevents the list label style changing when the new eop is inserted). No extra ref is taken here on eop_style. */ - if (para->member.para.fmt.wNumbering) - eop_style = para->member.para.eop_run->style; + if (para->fmt.wNumbering) + eop_style = para->eop_run->style; else eop_style = style; ME_ContinueCoalescingTransaction(editor); @@ -2594,9 +2540,9 @@ static BOOL handle_enter(ME_TextEditor *editor) ME_InsertEndRowFromCursor(editor, 0); else if (!editor->bEmulateVersion10) - ME_InsertTextFromCursor(editor, 0, &endl, 1, eop_style); + ME_InsertTextFromCursor(editor, 0, L"\r", 1, eop_style); else - ME_InsertTextFromCursor(editor, 0, endlv10, 2, eop_style); + ME_InsertTextFromCursor(editor, 0, L"\r\n", 2, eop_style); ME_CommitCoalescingUndo(editor); SetCursor(NULL); @@ -2640,7 +2586,7 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey) case VK_DELETE: editor->nUDArrowX = -1; /* FIXME backspace and delete aren't the same, they act different wrt paragraph style of the merged paragraph */ - if (editor->styleFlags & ES_READONLY) + if (editor->props & TXTBIT_READONLY) return FALSE; if (ME_IsSelection(editor)) { @@ -2670,7 +2616,7 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey) } else return TRUE; - ME_MoveCursorFromTableRowStartParagraph(editor); + table_move_from_row_start( editor ); ME_UpdateSelectionLinkAttribute(editor); ME_UpdateRepaint(editor, FALSE); ME_SendRequestResize(editor, FALSE); @@ -2679,14 +2625,6 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey) if (!editor->bEmulateVersion10) return handle_enter(editor); break; - case VK_ESCAPE: - if (editor->bDialogMode && editor->hwndParent) - PostMessageW(editor->hwndParent, WM_CLOSE, 0, 0); - return TRUE; - case VK_TAB: - if (editor->bDialogMode && editor->hwndParent) - SendMessageW(editor->hwndParent, WM_NEXTDLGCTL, shift_is_down, 0); - return TRUE; case 'A': if (ctrl_is_down) { @@ -2742,35 +2680,24 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey) return FALSE; } -static LRESULT ME_Char(ME_TextEditor *editor, WPARAM charCode, - LPARAM flags, BOOL unicode) +static LRESULT handle_wm_char( ME_TextEditor *editor, WCHAR wstr, LPARAM flags ) { - WCHAR wstr; - if (editor->bMouseCaptured) return 0; - if (editor->styleFlags & ES_READONLY) + if (editor->props & TXTBIT_READONLY) { - MessageBeep(MB_ICONERROR); + editor_beep( editor, MB_ICONERROR ); return 0; /* FIXME really 0 ? */ } - if (unicode) - wstr = (WCHAR)charCode; - else - { - CHAR charA = charCode; - MultiByteToWideChar(CP_ACP, 0, &charA, 1, &wstr, 1); - } - if (editor->bEmulateVersion10 && wstr == '\r') handle_enter(editor); if ((unsigned)wstr >= ' ' || wstr == '\t') { ME_Cursor cursor = editor->pCursors[0]; - ME_DisplayItem *para = cursor.pPara; + ME_Paragraph *para = cursor.para; int from, to; BOOL ctrl_is_down = GetKeyState(VK_CONTROL) & 0x8000; ME_GetSelectionOfs(editor, &from, &to); @@ -2778,43 +2705,43 @@ static LRESULT ME_Char(ME_TextEditor *editor, WPARAM charCode, /* v4.1 allows tabs to be inserted with ctrl key down */ !(ctrl_is_down && !editor->bEmulateVersion10)) { - ME_DisplayItem *para; - BOOL bSelectedRow = FALSE; + BOOL selected_row = FALSE; - para = cursor.pPara; if (ME_IsSelection(editor) && - cursor.pRun->member.run.nCharOfs + cursor.nOffset == 0 && - to == ME_GetCursorOfs(&editor->pCursors[0]) && - para->member.para.prev_para->type == diParagraph) + cursor.run->nCharOfs + cursor.nOffset == 0 && + to == ME_GetCursorOfs(&editor->pCursors[0]) && para_prev( para )) { - para = para->member.para.prev_para; - bSelectedRow = TRUE; + para = para_prev( para ); + selected_row = TRUE; } - if (ME_IsInTable(para)) + if (para_in_table( para )) { - ME_TabPressedInTable(editor, bSelectedRow); + table_handle_tab( editor, selected_row ); ME_CommitUndo(editor); return 0; } - } else if (!editor->bEmulateVersion10) { /* v4.1 */ - if (para->member.para.nFlags & MEPF_ROWEND) { - if (from == to) { - para = para->member.para.next_para; - if (para->member.para.nFlags & MEPF_ROWSTART) - para = para->member.para.next_para; - editor->pCursors[0].pPara = para; - editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); + } + else if (!editor->bEmulateVersion10) /* v4.1 */ + { + if (para->nFlags & MEPF_ROWEND) + { + if (from == to) + { + para = para_next( para ); + if (para->nFlags & MEPF_ROWSTART) para = para_next( para ); + editor->pCursors[0].para = para; + editor->pCursors[0].run = para_first_run( para ); editor->pCursors[0].nOffset = 0; editor->pCursors[1] = editor->pCursors[0]; } } - } else { /* v1.0 - 3.0 */ - if (ME_IsInTable(cursor.pRun) && - cursor.pRun->member.run.nFlags & MERF_ENDPARA && - from == to) + } + else /* v1.0 - 3.0 */ + { + if (para_in_table( para ) && cursor.run->nFlags & MERF_ENDPARA && from == to) { /* Text should not be inserted at the end of the table. */ - MessageBeep(-1); + editor_beep( editor, -1 ); return 0; } } @@ -2822,7 +2749,7 @@ static LRESULT ME_Char(ME_TextEditor *editor, WPARAM charCode, /* WM_CHAR is restricted to nTextLimit */ if(editor->nTextLimit > ME_GetTextLength(editor) - (to-from)) { - ME_Style *style = ME_GetInsertStyle(editor, 0); + ME_Style *style = style_get_insert_style( editor, editor->pCursors ); ME_ContinueCoalescingTransaction(editor); ME_InsertTextFromCursor(editor, 0, &wstr, 1, style); ME_ReleaseStyle(style); @@ -2894,104 +2821,52 @@ static BOOL is_link( ME_Run *run ) return (run->style->fmt.dwMask & CFM_LINK) && (run->style->fmt.dwEffects & CFE_LINK); } -static BOOL ME_SetCursor(ME_TextEditor *editor) +void editor_set_cursor( ME_TextEditor *editor, int x, int y ) { - ME_Cursor cursor; - POINT pt; - BOOL isExact; - SCROLLBARINFO sbi; - DWORD messagePos = GetMessagePos(); - pt.x = (short)LOWORD(messagePos); - pt.y = (short)HIWORD(messagePos); + ME_Cursor pos; + BOOL is_exact; + static HCURSOR cursor_arrow, cursor_hand, cursor_ibeam, cursor_reverse; + HCURSOR cursor; - if (editor->hWnd) - { - sbi.cbSize = sizeof(sbi); - GetScrollBarInfo(editor->hWnd, OBJID_HSCROLL, &sbi); - if (!(sbi.rgstate[0] & (STATE_SYSTEM_INVISIBLE|STATE_SYSTEM_OFFSCREEN)) && - PtInRect(&sbi.rcScrollBar, pt)) + if (!cursor_arrow) { - ITextHost_TxSetCursor(editor->texthost, - LoadCursorW(NULL, (WCHAR*)IDC_ARROW), FALSE); - return TRUE; + cursor_arrow = LoadCursorW( NULL, MAKEINTRESOURCEW( IDC_ARROW ) ); + cursor_hand = LoadCursorW( NULL, MAKEINTRESOURCEW( IDC_HAND ) ); + cursor_ibeam = LoadCursorW( NULL, MAKEINTRESOURCEW( IDC_IBEAM ) ); + cursor_reverse = LoadCursorW( dll_instance, MAKEINTRESOURCEW( OCR_REVERSE ) ); } - sbi.cbSize = sizeof(sbi); - GetScrollBarInfo(editor->hWnd, OBJID_VSCROLL, &sbi); - if (!(sbi.rgstate[0] & (STATE_SYSTEM_INVISIBLE|STATE_SYSTEM_OFFSCREEN)) && - PtInRect(&sbi.rcScrollBar, pt)) + + cursor = cursor_ibeam; + + if ((editor->nSelectionType == stLine && editor->bMouseCaptured) || + (!editor->bEmulateVersion10 && y < editor->rcFormat.top && x < editor->rcFormat.left)) + cursor = cursor_reverse; + else if (y < editor->rcFormat.top || y > editor->rcFormat.bottom) { - ITextHost_TxSetCursor(editor->texthost, - LoadCursorW(NULL, (WCHAR*)IDC_ARROW), FALSE); - return TRUE; + if (editor->bEmulateVersion10) cursor = cursor_arrow; + else cursor = cursor_ibeam; } - } - ITextHost_TxScreenToClient(editor->texthost, &pt); + else if (x < editor->rcFormat.left) cursor = cursor_reverse; + else + { + ME_CharFromPos( editor, x, y, &pos, &is_exact ); + if (is_exact) + { + ME_Run *run = pos.run; - if (editor->nSelectionType == stLine && editor->bMouseCaptured) { - ITextHost_TxSetCursor(editor->texthost, hLeft, FALSE); - return TRUE; - } - if (!editor->bEmulateVersion10 /* v4.1 */ && - pt.y < editor->rcFormat.top && - pt.x < editor->rcFormat.left) - { - ITextHost_TxSetCursor(editor->texthost, hLeft, FALSE); - return TRUE; - } - if (pt.y < editor->rcFormat.top || pt.y > editor->rcFormat.bottom) - { - if (editor->bEmulateVersion10) /* v1.0 - 3.0 */ - ITextHost_TxSetCursor(editor->texthost, - LoadCursorW(NULL, (WCHAR*)IDC_ARROW), FALSE); - else /* v4.1 */ - ITextHost_TxSetCursor(editor->texthost, - LoadCursorW(NULL, (WCHAR*)IDC_IBEAM), TRUE); - return TRUE; - } - if (pt.x < editor->rcFormat.left) - { - ITextHost_TxSetCursor(editor->texthost, hLeft, FALSE); - return TRUE; - } - ME_CharFromPos(editor, pt.x, pt.y, &cursor, &isExact); - if (isExact) - { - ME_Run *run; + if (is_link( run )) cursor = cursor_hand; - run = &cursor.pRun->member.run; - if (is_link( run )) - { - ITextHost_TxSetCursor(editor->texthost, - LoadCursorW(NULL, (WCHAR*)IDC_HAND), - FALSE); - return TRUE; - } + else if (ME_IsSelection( editor )) + { + int start, end, offset = ME_GetCursorOfs( &pos ); - if (ME_IsSelection(editor)) - { - int selStart, selEnd; - int offset = ME_GetCursorOfs(&cursor); - - ME_GetSelectionOfs(editor, &selStart, &selEnd); - if (selStart <= offset && selEnd >= offset) { - ITextHost_TxSetCursor(editor->texthost, - LoadCursorW(NULL, (WCHAR*)IDC_ARROW), - FALSE); - return TRUE; - } - } - } - ITextHost_TxSetCursor(editor->texthost, - LoadCursorW(NULL, (WCHAR*)IDC_IBEAM), TRUE); - return TRUE; -} + ME_GetSelectionOfs( editor, &start, &end ); + if (start <= offset && end >= offset) cursor = cursor_arrow; + } + } + } -static void ME_SetDefaultFormatRect(ME_TextEditor *editor) -{ - ITextHost_TxGetClientRect(editor->texthost, &editor->rcFormat); - editor->rcFormat.top += editor->exStyleFlags & WS_EX_CLIENTEDGE ? 1 : 0; - editor->rcFormat.left += 1 + editor->selofs; - editor->rcFormat.right -= 1; + ITextHost_TxSetCursor( editor->texthost, cursor, cursor == cursor_ibeam ); } static LONG ME_GetSelectionType(ME_TextEditor *editor) @@ -3011,11 +2886,9 @@ static LONG ME_GetSelectionType(ME_TextEditor *editor) { ME_Cursor cursor; - ME_CursorFromCharOfs(editor, start + i, &cursor); - if (cursor.pRun->member.run.reobj) - object_count++; - else - character_count++; + cursor_from_char_ofs( editor, start + i, &cursor ); + if (cursor.run->reobj) object_count++; + else character_count++; if (character_count >= 2 && object_count >= 2) return (SEL_TEXT | SEL_MULTICHAR | SEL_OBJECT | SEL_MULTIOBJECT); } @@ -3037,49 +2910,54 @@ static LONG ME_GetSelectionType(ME_TextEditor *editor) static BOOL ME_ShowContextMenu(ME_TextEditor *editor, int x, int y) { - CHARRANGE selrange; - HMENU menu; - int seltype; - - if(!editor->lpOleCallback || !editor->hWnd) - return FALSE; - ME_GetSelectionOfs(editor, &selrange.cpMin, &selrange.cpMax); - seltype = ME_GetSelectionType(editor); - if(SUCCEEDED(IRichEditOleCallback_GetContextMenu(editor->lpOleCallback, seltype, NULL, &selrange, &menu))) - { - TrackPopupMenu(menu, TPM_LEFTALIGN | TPM_RIGHTBUTTON, x, y, 0, editor->hwndParent, NULL); - DestroyMenu(menu); - } - return TRUE; + CHARRANGE selrange; + HMENU menu; + int seltype; + HWND hwnd, parent; + + if (!editor->lpOleCallback || !editor->have_texthost2) return FALSE; + if (FAILED( ITextHost2_TxGetWindow( editor->texthost, &hwnd ))) return FALSE; + parent = GetParent( hwnd ); + if (!parent) parent = hwnd; + + ME_GetSelectionOfs( editor, &selrange.cpMin, &selrange.cpMax ); + seltype = ME_GetSelectionType( editor ); + if (SUCCEEDED( IRichEditOleCallback_GetContextMenu( editor->lpOleCallback, seltype, NULL, &selrange, &menu ) )) + { + TrackPopupMenu( menu, TPM_LEFTALIGN | TPM_RIGHTBUTTON, x, y, 0, parent, NULL ); + DestroyMenu( menu ); + } + return TRUE; } ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10) { ME_TextEditor *ed = heap_alloc(sizeof(*ed)); int i; - DWORD props; LONG selbarwidth; + HRESULT hr; - ed->hWnd = NULL; - ed->hwndParent = NULL; ed->sizeWindow.cx = ed->sizeWindow.cy = 0; - ed->texthost = texthost; - ed->reOle = NULL; + if (ITextHost_QueryInterface( texthost, &IID_ITextHost2, (void **)&ed->texthost ) == S_OK) + { + ITextHost_Release( texthost ); + ed->have_texthost2 = TRUE; + } + else + { + ed->texthost = (ITextHost2 *)texthost; + ed->have_texthost2 = FALSE; + } + ed->bEmulateVersion10 = bEmulateVersion10; - ed->styleFlags = 0; - ed->exStyleFlags = 0; - ed->first_marked_para = NULL; + ed->in_place_active = FALSE; ed->total_rows = 0; - ITextHost_TxGetPropertyBits(texthost, - (TXTBIT_RICHTEXT|TXTBIT_MULTILINE| - TXTBIT_READONLY|TXTBIT_USEPASSWORD| - TXTBIT_HIDESELECTION|TXTBIT_SAVESELECTION| - TXTBIT_AUTOWORDSEL|TXTBIT_VERTICAL| - TXTBIT_WORDWRAP|TXTBIT_DISABLEDRAG), - &props); - ITextHost_TxGetScrollBars(texthost, &ed->styleFlags); - ed->styleFlags &= (WS_VSCROLL|WS_HSCROLL|ES_AUTOVSCROLL| - ES_AUTOHSCROLL|ES_DISABLENOSCROLL); + ITextHost_TxGetPropertyBits( ed->texthost, TXTBIT_RICHTEXT | TXTBIT_MULTILINE | TXTBIT_READONLY | + TXTBIT_USEPASSWORD | TXTBIT_HIDESELECTION | TXTBIT_SAVESELECTION | + TXTBIT_AUTOWORDSEL | TXTBIT_VERTICAL | TXTBIT_WORDWRAP | TXTBIT_ALLOWBEEP | + TXTBIT_DISABLEDRAG, + &ed->props ); + ITextHost_TxGetScrollBars( ed->texthost, &ed->scrollbars ); ed->pBuffer = ME_MakeText(); ed->nZoomNumerator = ed->nZoomDenominator = 0; ed->nAvailWidth = 0; /* wrap to client area */ @@ -3100,9 +2978,6 @@ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10) ed->nLastTotalLength = ed->nTotalLength = 0; ed->nLastTotalWidth = ed->nTotalWidth = 0; ed->nUDArrowX = -1; - ed->rgbBackColor = -1; - ed->hbrBackground = GetSysColorBrush(COLOR_WINDOW); - ed->bCaretAtEnd = FALSE; ed->nEventMask = 0; ed->nModifyStep = 0; ed->nTextLimit = TEXT_LIMIT_DEFAULT; @@ -3113,15 +2988,15 @@ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10) ed->nUndoMode = umAddToUndo; ed->nParagraphs = 1; ed->nLastSelStart = ed->nLastSelEnd = 0; - ed->pLastSelStartPara = ed->pLastSelEndPara = ed->pCursors[0].pPara; + ed->last_sel_start_para = ed->last_sel_end_para = ed->pCursors[0].para; ed->bHideSelection = FALSE; ed->pfnWordBreak = NULL; + ed->richole = NULL; ed->lpOleCallback = NULL; ed->mode = TM_MULTILEVELUNDO | TM_MULTICODEPAGE; - ed->mode |= (props & TXTBIT_RICHTEXT) ? TM_RICHTEXT : TM_PLAINTEXT; + ed->mode |= (ed->props & TXTBIT_RICHTEXT) ? TM_RICHTEXT : TM_PLAINTEXT; ed->AutoURLDetect_bEnable = FALSE; ed->bHaveFocus = FALSE; - ed->bDialogMode = FALSE; ed->bMouseCaptured = FALSE; ed->caret_hidden = FALSE; ed->caret_height = 0; @@ -3134,39 +3009,17 @@ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10) ME_CheckCharOffsets(ed); SetRectEmpty(&ed->rcFormat); - ed->bDefaultFormatRect = TRUE; - ITextHost_TxGetSelectionBarWidth(ed->texthost, &selbarwidth); - if (selbarwidth) { - /* FIXME: Convert selbarwidth from HIMETRIC to pixels */ - ed->selofs = SELECTIONBAR_WIDTH; - ed->styleFlags |= ES_SELECTIONBAR; - } else { - ed->selofs = 0; - } + hr = ITextHost_TxGetSelectionBarWidth( ed->texthost, &selbarwidth ); + /* FIXME: Convert selbarwidth from HIMETRIC to pixels */ + if (hr == S_OK && selbarwidth) ed->selofs = SELECTIONBAR_WIDTH; + else ed->selofs = 0; ed->nSelectionType = stPosition; - ed->cPasswordMask = 0; - if (props & TXTBIT_USEPASSWORD) - ITextHost_TxGetPasswordChar(texthost, &ed->cPasswordMask); - - if (props & TXTBIT_AUTOWORDSEL) - ed->styleFlags |= ECO_AUTOWORDSELECTION; - if (props & TXTBIT_MULTILINE) { - ed->styleFlags |= ES_MULTILINE; - ed->bWordWrap = (props & TXTBIT_WORDWRAP) != 0; - } else { - ed->bWordWrap = FALSE; - } - if (props & TXTBIT_READONLY) - ed->styleFlags |= ES_READONLY; - if (!(props & TXTBIT_HIDESELECTION)) - ed->styleFlags |= ES_NOHIDESEL; - if (props & TXTBIT_SAVESELECTION) - ed->styleFlags |= ES_SAVESEL; - if (props & TXTBIT_VERTICAL) - ed->styleFlags |= ES_VERTICAL; - if (props & TXTBIT_DISABLEDRAG) - ed->styleFlags |= ES_NOOLEDRAGDROP; + ed->password_char = 0; + if (ed->props & TXTBIT_USEPASSWORD) + ITextHost_TxGetPasswordChar( ed->texthost, &ed->password_char ); + + ed->bWordWrap = (ed->props & TXTBIT_WORDWRAP) && (ed->props & TXTBIT_MULTILINE); ed->notified_cr.cpMin = ed->notified_cr.cpMax = 0; @@ -3176,15 +3029,34 @@ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10) ed->vert_si.nMax = 0; ed->vert_si.nPage = 0; ed->vert_si.nPos = 0; + ed->vert_sb_enabled = 0; ed->horz_si.cbSize = sizeof(SCROLLINFO); ed->horz_si.nMin = 0; ed->horz_si.nMax = 0; ed->horz_si.nPage = 0; ed->horz_si.nPos = 0; + ed->horz_sb_enabled = 0; + + if (ed->scrollbars & ES_DISABLENOSCROLL) + { + if (ed->scrollbars & WS_VSCROLL) + { + ITextHost_TxSetScrollRange( ed->texthost, SB_VERT, 0, 1, TRUE ); + ITextHost_TxEnableScrollBar( ed->texthost, SB_VERT, ESB_DISABLE_BOTH ); + } + if (ed->scrollbars & WS_HSCROLL) + { + ITextHost_TxSetScrollRange( ed->texthost, SB_HORZ, 0, 1, TRUE ); + ITextHost_TxEnableScrollBar( ed->texthost, SB_HORZ, ESB_DISABLE_BOTH ); + } + } ed->wheel_remain = 0; + ed->back_style = TXTBACK_OPAQUE; + ITextHost_TxGetBackStyle( ed->texthost, &ed->back_style ); + list_init( &ed->reobj_list ); OleInitialize(NULL); @@ -3200,10 +3072,11 @@ void ME_DestroyEditor(ME_TextEditor *editor) ME_ClearTempStyle(editor); ME_EmptyUndoStack(editor); editor->pBuffer->pFirst = NULL; - while(p) { + while(p) + { pNext = p->next; if (p->type == diParagraph) - destroy_para(editor, p); + para_destroy( editor, &p->member.para ); else ME_DestroyDisplayItem(p); p = pNext; @@ -3218,16 +3091,9 @@ void ME_DestroyEditor(ME_TextEditor *editor) if (editor->pFontCache[i].hFont) DeleteObject(editor->pFontCache[i].hFont); } - if (editor->rgbBackColor != -1) - DeleteObject(editor->hbrBackground); if(editor->lpOleCallback) IRichEditOleCallback_Release(editor->lpOleCallback); - ITextHost_Release(editor->texthost); - if (editor->reOle) - { - IUnknown_Release(editor->reOle); - editor->reOle = NULL; - } + OleUninitialize(); heap_free(editor->pBuffer); @@ -3235,37 +3101,6 @@ void ME_DestroyEditor(ME_TextEditor *editor) heap_free(editor); } -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) -{ - TRACE("\n"); - switch (fdwReason) - { - case DLL_PROCESS_ATTACH: - DisableThreadLibraryCalls(hinstDLL); - me_heap = HeapCreate (0, 0x10000, 0); - if (!ME_RegisterEditorClass(hinstDLL)) return FALSE; - hLeft = LoadCursorW(hinstDLL, MAKEINTRESOURCEW(OCR_REVERSE)); - LookupInit(); - break; - - case DLL_PROCESS_DETACH: - if (lpvReserved) break; - UnregisterClassW(RICHEDIT_CLASS20W, 0); - UnregisterClassW(MSFTEDIT_CLASS, 0); - UnregisterClassA(RICHEDIT_CLASS20A, 0); - UnregisterClassA("RichEdit50A", 0); - if (ME_ListBoxRegistered) - UnregisterClassW(REListBox20W, 0); - if (ME_ComboBoxRegistered) - UnregisterClassW(REComboBox20W, 0); - LookupCleanup(); - HeapDestroy (me_heap); - release_typelib(); - break; - } - return TRUE; -} - static inline int get_default_line_height( ME_TextEditor *editor ) { int height = 0; @@ -3284,158 +3119,21 @@ static inline int calc_wheel_change( int *remain, int amount_per_click ) return change; } -static const char * const edit_messages[] = { - "EM_GETSEL", - "EM_SETSEL", - "EM_GETRECT", - "EM_SETRECT", - "EM_SETRECTNP", - "EM_SCROLL", - "EM_LINESCROLL", - "EM_SCROLLCARET", - "EM_GETMODIFY", - "EM_SETMODIFY", - "EM_GETLINECOUNT", - "EM_LINEINDEX", - "EM_SETHANDLE", - "EM_GETHANDLE", - "EM_GETTHUMB", - "EM_UNKNOWN_BF", - "EM_UNKNOWN_C0", - "EM_LINELENGTH", - "EM_REPLACESEL", - "EM_UNKNOWN_C3", - "EM_GETLINE", - "EM_LIMITTEXT", - "EM_CANUNDO", - "EM_UNDO", - "EM_FMTLINES", - "EM_LINEFROMCHAR", - "EM_UNKNOWN_CA", - "EM_SETTABSTOPS", - "EM_SETPASSWORDCHAR", - "EM_EMPTYUNDOBUFFER", - "EM_GETFIRSTVISIBLELINE", - "EM_SETREADONLY", - "EM_SETWORDBREAKPROC", - "EM_GETWORDBREAKPROC", - "EM_GETPASSWORDCHAR", - "EM_SETMARGINS", - "EM_GETMARGINS", - "EM_GETLIMITTEXT", - "EM_POSFROMCHAR", - "EM_CHARFROMPOS", - "EM_SETIMESTATUS", - "EM_GETIMESTATUS" -}; - -static const char * const richedit_messages[] = { - "EM_CANPASTE", - "EM_DISPLAYBAND", - "EM_EXGETSEL", - "EM_EXLIMITTEXT", - "EM_EXLINEFROMCHAR", - "EM_EXSETSEL", - "EM_FINDTEXT", - "EM_FORMATRANGE", - "EM_GETCHARFORMAT", - "EM_GETEVENTMASK", - "EM_GETOLEINTERFACE", - "EM_GETPARAFORMAT", - "EM_GETSELTEXT", - "EM_HIDESELECTION", - "EM_PASTESPECIAL", - "EM_REQUESTRESIZE", - "EM_SELECTIONTYPE", - "EM_SETBKGNDCOLOR", - "EM_SETCHARFORMAT", - "EM_SETEVENTMASK", - "EM_SETOLECALLBACK", - "EM_SETPARAFORMAT", - "EM_SETTARGETDEVICE", - "EM_STREAMIN", - "EM_STREAMOUT", - "EM_GETTEXTRANGE", - "EM_FINDWORDBREAK", - "EM_SETOPTIONS", - "EM_GETOPTIONS", - "EM_FINDTEXTEX", - "EM_GETWORDBREAKPROCEX", - "EM_SETWORDBREAKPROCEX", - "EM_SETUNDOLIMIT", - "EM_UNKNOWN_USER_83", - "EM_REDO", - "EM_CANREDO", - "EM_GETUNDONAME", - "EM_GETREDONAME", - "EM_STOPGROUPTYPING", - "EM_SETTEXTMODE", - "EM_GETTEXTMODE", - "EM_AUTOURLDETECT", - "EM_GETAUTOURLDETECT", - "EM_SETPALETTE", - "EM_GETTEXTEX", - "EM_GETTEXTLENGTHEX", - "EM_SHOWSCROLLBAR", - "EM_SETTEXTEX", - "EM_UNKNOWN_USER_98", - "EM_UNKNOWN_USER_99", - "EM_SETPUNCTUATION", - "EM_GETPUNCTUATION", - "EM_SETWORDWRAPMODE", - "EM_GETWORDWRAPMODE", - "EM_SETIMECOLOR", - "EM_GETIMECOLOR", - "EM_SETIMEOPTIONS", - "EM_GETIMEOPTIONS", - "EM_CONVPOSITION", - "EM_UNKNOWN_USER_109", - "EM_UNKNOWN_USER_110", - "EM_UNKNOWN_USER_111", - "EM_UNKNOWN_USER_112", - "EM_UNKNOWN_USER_113", - "EM_UNKNOWN_USER_114", - "EM_UNKNOWN_USER_115", - "EM_UNKNOWN_USER_116", - "EM_UNKNOWN_USER_117", - "EM_UNKNOWN_USER_118", - "EM_UNKNOWN_USER_119", - "EM_SETLANGOPTIONS", - "EM_GETLANGOPTIONS", - "EM_GETIMECOMPMODE", - "EM_FINDTEXTW", - "EM_FINDTEXTEXW", - "EM_RECONVERSION", - "EM_SETIMEMODEBIAS", - "EM_GETIMEMODEBIAS" -}; - -static const char * -get_msg_name(UINT msg) -{ - if (msg >= EM_GETSEL && msg <= EM_CHARFROMPOS) - return edit_messages[msg - EM_GETSEL]; - if (msg >= EM_CANPASTE && msg <= EM_GETIMEMODEBIAS) - return richedit_messages[msg - EM_CANPASTE]; - return ""; -} - -static void ME_LinkNotify(ME_TextEditor *editor, UINT msg, WPARAM wParam, LPARAM lParam) +void link_notify(ME_TextEditor *editor, UINT msg, WPARAM wParam, LPARAM lParam) { int x,y; BOOL isExact; ME_Cursor cursor; /* The start of the clicked text. */ - + ME_Run *run; ENLINK info; + x = (short)LOWORD(lParam); y = (short)HIWORD(lParam); ME_CharFromPos(editor, x, y, &cursor, &isExact); if (!isExact) return; - if (is_link( &cursor.pRun->member.run )) + if (is_link( cursor.run )) { /* The clicked run has CFE_LINK set */ - ME_DisplayItem *di; - info.nmhdr.hwndFrom = NULL; info.nmhdr.idFrom = 0; info.nmhdr.code = EN_LINK; @@ -3446,15 +3144,15 @@ static void ME_LinkNotify(ME_TextEditor *editor, UINT msg, WPARAM wParam, LPARAM /* find the first contiguous run with CFE_LINK set */ info.chrg.cpMin = ME_GetCursorOfs(&cursor); - di = cursor.pRun; - while (ME_PrevRun( NULL, &di, FALSE ) && is_link( &di->member.run )) - info.chrg.cpMin -= di->member.run.len; + run = cursor.run; + while ((run = run_prev( run )) && is_link( run )) + info.chrg.cpMin -= run->len; /* find the last contiguous run with CFE_LINK set */ - info.chrg.cpMax = ME_GetCursorOfs(&cursor) + cursor.pRun->member.run.len; - di = cursor.pRun; - while (ME_NextRun( NULL, &di, FALSE ) && is_link( &di->member.run )) - info.chrg.cpMax += di->member.run.len; + info.chrg.cpMax = ME_GetCursorOfs(&cursor) + cursor.run->len; + run = cursor.run; + while ((run = run_next( run )) && is_link( run )) + info.chrg.cpMax += run->len; ITextHost_TxNotify(editor->texthost, info.nmhdr.code, &info); } @@ -3494,52 +3192,6 @@ static void ME_SetText(ME_TextEditor *editor, void *text, BOOL unicode) ME_EndToUnicode(codepage, wszText); } -static LRESULT ME_WmCreate(ME_TextEditor *editor, LPARAM lParam, BOOL unicode) -{ - CREATESTRUCTW *createW = (CREATESTRUCTW*)lParam; - CREATESTRUCTA *createA = (CREATESTRUCTA*)lParam; - void *text = NULL; - INT max; - - if (lParam) - text = unicode ? (void*)createW->lpszName : (void*)createA->lpszName; - - ME_SetDefaultFormatRect(editor); - - max = (editor->styleFlags & ES_DISABLENOSCROLL) ? 1 : 0; - if (~editor->styleFlags & ES_DISABLENOSCROLL || editor->styleFlags & WS_VSCROLL) - ITextHost_TxSetScrollRange(editor->texthost, SB_VERT, 0, max, TRUE); - - if (~editor->styleFlags & ES_DISABLENOSCROLL || editor->styleFlags & WS_HSCROLL) - ITextHost_TxSetScrollRange(editor->texthost, SB_HORZ, 0, max, TRUE); - - if (editor->styleFlags & ES_DISABLENOSCROLL) - { - if (editor->styleFlags & WS_VSCROLL) - { - ITextHost_TxEnableScrollBar(editor->texthost, SB_VERT, ESB_DISABLE_BOTH); - ITextHost_TxShowScrollBar(editor->texthost, SB_VERT, TRUE); - } - if (editor->styleFlags & WS_HSCROLL) - { - ITextHost_TxEnableScrollBar(editor->texthost, SB_HORZ, ESB_DISABLE_BOTH); - ITextHost_TxShowScrollBar(editor->texthost, SB_HORZ, TRUE); - } - } - - if (text) - { - ME_SetText(editor, text, unicode); - ME_SetCursorToStart(editor, &editor->pCursors[0]); - ME_SetCursorToStart(editor, &editor->pCursors[1]); - } - - ME_CommitUndo(editor); - ME_WrapMarkedParagraphs(editor); - update_caret(editor); - return 0; -} - static LRESULT handle_EM_SETCHARFORMAT( ME_TextEditor *editor, WPARAM flags, const CHARFORMAT2W *fmt_in ) { CHARFORMAT2W fmt; @@ -3601,8 +3253,8 @@ static LRESULT handle_EM_SETCHARFORMAT( ME_TextEditor *editor, WPARAM flags, con * The LRESULT that is returned is a return value for window procs, * and the phresult parameter is the COM return code needed by the * text services interface. */ -LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, - LPARAM lParam, BOOL unicode, HRESULT* phresult) +LRESULT editor_handle_message( ME_TextEditor *editor, UINT msg, WPARAM wParam, + LPARAM lParam, HRESULT* phresult ) { *phresult = S_OK; @@ -3637,18 +3289,6 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, return ME_StreamIn(editor, wParam, (EDITSTREAM*)lParam, TRUE); case EM_STREAMOUT: return ME_StreamOut(editor, wParam, (EDITSTREAM *)lParam); - case WM_GETDLGCODE: - { - UINT code = DLGC_WANTCHARS|DLGC_WANTTAB|DLGC_WANTARROWS; - - if (lParam) - editor->bDialogMode = TRUE; - if (editor->styleFlags & ES_MULTILINE) - code |= DLGC_WANTMESSAGE; - if (!(editor->styleFlags & ES_SAVESEL)) - code |= DLGC_HASSETSEL; - return code; - } case EM_EMPTYUNDOBUFFER: ME_EmptyUndoStack(editor); return 0; @@ -3690,16 +3330,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, return ME_Undo(editor); case EM_REDO: return ME_Redo(editor); - case EM_GETOPTIONS: - { - /* these flags are equivalent to the ES_* counterparts */ - DWORD mask = ECO_VERTICAL | ECO_AUTOHSCROLL | ECO_AUTOVSCROLL | - ECO_NOHIDESEL | ECO_READONLY | ECO_WANTRETURN | ECO_SELECTIONBAR; - DWORD settings = editor->styleFlags & mask; - - return settings; - } - case EM_SETFONTSIZE: + case EM_SETFONTSIZE: { CHARFORMAT2W cf; LONG tmp_size, size; @@ -3740,68 +3371,6 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, return TRUE; } - case EM_SETOPTIONS: - { - /* these flags are equivalent to ES_* counterparts, except for - * ECO_AUTOWORDSELECTION that doesn't have an ES_* counterpart, - * but is still stored in editor->styleFlags. */ - const DWORD mask = ECO_VERTICAL | ECO_AUTOHSCROLL | ECO_AUTOVSCROLL | - ECO_NOHIDESEL | ECO_READONLY | ECO_WANTRETURN | - ECO_SELECTIONBAR | ECO_AUTOWORDSELECTION; - DWORD settings = mask & editor->styleFlags; - DWORD oldSettings = settings; - DWORD changedSettings; - - switch(wParam) - { - case ECOOP_SET: - settings = lParam; - break; - case ECOOP_OR: - settings |= lParam; - break; - case ECOOP_AND: - settings &= lParam; - break; - case ECOOP_XOR: - settings ^= lParam; - } - changedSettings = oldSettings ^ settings; - - if (changedSettings) { - editor->styleFlags = (editor->styleFlags & ~mask) | (settings & mask); - - if (changedSettings & ECO_SELECTIONBAR) - { - ITextHost_TxInvalidateRect(editor->texthost, &editor->rcFormat, TRUE); - if (settings & ECO_SELECTIONBAR) { - assert(!editor->selofs); - editor->selofs = SELECTIONBAR_WIDTH; - editor->rcFormat.left += editor->selofs; - } else { - editor->rcFormat.left -= editor->selofs; - editor->selofs = 0; - } - ME_RewrapRepaint(editor); - } - - if ((changedSettings & settings & ES_NOHIDESEL) && !editor->bHaveFocus) - ME_InvalidateSelection( editor ); - - if (changedSettings & settings & ECO_VERTICAL) - FIXME("ECO_VERTICAL not implemented yet!\n"); - if (changedSettings & settings & ECO_AUTOHSCROLL) - FIXME("ECO_AUTOHSCROLL not implemented yet!\n"); - if (changedSettings & settings & ECO_AUTOVSCROLL) - FIXME("ECO_AUTOVSCROLL not implemented yet!\n"); - if (changedSettings & settings & ECO_WANTRETURN) - FIXME("ECO_WANTRETURN not implemented yet!\n"); - if (changedSettings & settings & ECO_AUTOWORDSELECTION) - FIXME("ECO_AUTOWORDSELECTION not implemented yet!\n"); - } - - return settings; - } case EM_SETSEL: { return set_selection( editor, wParam, lParam ); @@ -3809,7 +3378,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, case EM_SETSCROLLPOS: { POINT *point = (POINT *)lParam; - ME_ScrollAbs(editor, point->x, point->y); + scroll_abs( editor, point->x, point->y, TRUE ); return 0; } case EM_AUTOURLDETECT: @@ -3831,39 +3400,6 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, return set_selection( editor, range.cpMin, range.cpMax ); } - case EM_SHOWSCROLLBAR: - { - DWORD flags; - - switch (wParam) - { - case SB_HORZ: - flags = WS_HSCROLL; - break; - case SB_VERT: - flags = WS_VSCROLL; - break; - case SB_BOTH: - flags = WS_HSCROLL|WS_VSCROLL; - break; - default: - return 0; - } - - if (lParam) { - editor->styleFlags |= flags; - if (flags & WS_HSCROLL) - ITextHost_TxShowScrollBar(editor->texthost, SB_HORZ, - editor->nTotalWidth > editor->sizeWindow.cx); - if (flags & WS_VSCROLL) - ITextHost_TxShowScrollBar(editor->texthost, SB_VERT, - editor->nTotalLength > editor->sizeWindow.cy); - } else { - editor->styleFlags &= ~flags; - ITextHost_TxShowScrollBar(editor->texthost, wParam, FALSE); - } - return 0; - } case EM_SETTEXTEX: { LPWSTR wszText; @@ -3938,28 +3474,6 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, } case EM_SELECTIONTYPE: return ME_GetSelectionType(editor); - case EM_SETBKGNDCOLOR: - { - LRESULT lColor; - if (editor->rgbBackColor != -1) { - DeleteObject(editor->hbrBackground); - lColor = editor->rgbBackColor; - } - else lColor = ITextHost_TxGetSysColor(editor->texthost, COLOR_WINDOW); - - if (wParam) - { - editor->rgbBackColor = -1; - editor->hbrBackground = GetSysColorBrush(COLOR_WINDOW); - } - else - { - editor->rgbBackColor = lParam; - editor->hbrBackground = CreateSolidBrush(editor->rgbBackColor); - } - ITextHost_TxInvalidateRect(editor->texthost, NULL, TRUE); - return lColor; - } case EM_GETMODIFY: return editor->nModifyStep == 0 ? 0 : -1; case EM_SETMODIFY: @@ -3971,14 +3485,6 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, return 0; } - case EM_SETREADONLY: - { - if (wParam) - editor->styleFlags |= ES_READONLY; - else - editor->styleFlags &= ~ES_READONLY; - return 1; - } case EM_SETEVENTMASK: { DWORD nOldMask = editor->nEventMask; @@ -4008,36 +3514,35 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, } case EM_SETPARAFORMAT: { - BOOL result = ME_SetSelectionParaFormat(editor, (PARAFORMAT2 *)lParam); + BOOL result = editor_set_selection_para_fmt( editor, (PARAFORMAT2 *)lParam ); ME_WrapMarkedParagraphs(editor); ME_UpdateScrollBar(editor); ME_CommitUndo(editor); return result; } case EM_GETPARAFORMAT: - ME_GetSelectionParaFormat(editor, (PARAFORMAT2 *)lParam); + editor_get_selection_para_fmt( editor, (PARAFORMAT2 *)lParam ); return ((PARAFORMAT2 *)lParam)->dwMask; case EM_GETFIRSTVISIBLELINE: { - ME_DisplayItem *p = editor->pBuffer->pFirst; + ME_Paragraph *para = editor_first_para( editor ); + ME_Row *row; int y = editor->vert_si.nPos; - int ypara = 0; int count = 0; - int ystart, yend; - while(p) { - p = ME_FindItemFwd(p, diStartRowOrParagraphOrEnd); - if (p->type == diTextEnd) - break; - if (p->type == diParagraph) { - ypara = p->member.para.pt.y; - continue; - } - ystart = ypara + p->member.row.pt.y; - yend = ystart + p->member.row.nHeight; - if (y < yend) { - break; - } + + while (para_next( para )) + { + if (y < para->pt.y + para->nHeight) break; + count += para->nRows; + para = para_next( para ); + } + + row = para_first_row( para ); + while (row) + { + if (y < para->pt.y + row->pt.y + row->nHeight) break; count++; + row = row_next( row ); } return count; } @@ -4049,7 +3554,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, } case EM_LINESCROLL: { - if (!(editor->styleFlags & ES_MULTILINE)) + if (!(editor->props & TXTBIT_MULTILINE)) return FALSE; ME_ScrollDown( editor, lParam * get_default_line_height( editor ) ); return TRUE; @@ -4065,18 +3570,15 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, } case EM_REPLACESEL: { - int len = 0; - LONG codepage = unicode ? CP_UNICODE : CP_ACP; - LPWSTR wszText = ME_ToUnicode(codepage, (void *)lParam, &len); + WCHAR *text = (WCHAR *)lParam; + int len = text ? lstrlenW( text ) : 0; - TRACE("EM_REPLACESEL - %s\n", debugstr_w(wszText)); - - ME_ReplaceSel(editor, !!wParam, wszText, len); - ME_EndToUnicode(codepage, wszText); + TRACE( "EM_REPLACESEL - %s\n", debugstr_w( text ) ); + ME_ReplaceSel( editor, !!wParam, text, len ); return len; } case EM_SCROLLCARET: - ME_EnsureVisible(editor, &editor->pCursors[0]); + editor_ensure_visible( editor, &editor->pCursors[0] ); return 0; case WM_SETFONT: { @@ -4102,7 +3604,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, ME_SetDefaultCharFormat(editor, &fmt); ME_CommitUndo(editor); - ME_MarkAllForWrapping(editor); + editor_mark_rewrap_all( editor ); ME_WrapMarkedParagraphs(editor); ME_UpdateScrollBar(editor); if (bRepaint) @@ -4132,7 +3634,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, ME_StreamInRTFString(editor, 0, (char *)lParam); } else - ME_SetText(editor, (void*)lParam, unicode); + ME_SetText( editor, (void*)lParam, TRUE ); } else TRACE("WM_SETTEXT - NULL\n"); @@ -4162,10 +3664,8 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, case WM_GETTEXTLENGTH: { GETTEXTLENGTHEX how; - - /* CR/LF conversion required in 2.0 mode, verbatim in 1.0 mode */ how.flags = GTL_CLOSE | (editor->bEmulateVersion10 ? 0 : GTL_USECRLF) | GTL_NUMCHARS; - how.codepage = unicode ? CP_UNICODE : CP_ACP; + how.codepage = CP_UNICODE; return ME_GetTextLengthEx(editor, &how); } case EM_GETTEXTLENGTHEX: @@ -4173,9 +3673,9 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, case WM_GETTEXT: { GETTEXTEX ex; - ex.cb = wParam * (unicode ? sizeof(WCHAR) : sizeof(CHAR)); + ex.cb = wParam * sizeof(WCHAR); ex.flags = GT_USECRLF; - ex.codepage = unicode ? CP_UNICODE : CP_ACP; + ex.codepage = CP_UNICODE; ex.lpDefaultChar = NULL; ex.lpUsedDefChar = NULL; return ME_GetTextEx(editor, &ex, lParam); @@ -4186,8 +3686,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, { int nFrom, nTo, nStartCur = ME_GetSelectionOfs(editor, &nFrom, &nTo); ME_Cursor *from = &editor->pCursors[nStartCur]; - return ME_GetTextRange(editor, (WCHAR *)lParam, from, - nTo - nFrom, unicode); + return get_text_range( editor, (WCHAR *)lParam, from, nTo - nFrom ); } case EM_GETSCROLLPOS: { @@ -4209,122 +3708,106 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, int nEnd = rng->chrg.cpMax; int textlength = ME_GetTextLength(editor); - TRACE("EM_GETTEXTRANGE min=%d max=%d unicode=%d textlength=%d\n", - rng->chrg.cpMin, rng->chrg.cpMax, unicode, textlength); + TRACE( "EM_GETTEXTRANGE min = %d max = %d textlength = %d\n", rng->chrg.cpMin, rng->chrg.cpMax, textlength ); if (nStart < 0) return 0; if ((nStart == 0 && nEnd == -1) || nEnd > textlength) nEnd = textlength; if (nStart >= nEnd) return 0; - ME_CursorFromCharOfs(editor, nStart, &start); - return ME_GetTextRange(editor, rng->lpstrText, &start, nEnd - nStart, unicode); + cursor_from_char_ofs( editor, nStart, &start ); + return get_text_range( editor, rng->lpstrText, &start, nEnd - nStart ); } case EM_GETLINE: { - ME_DisplayItem *run; + ME_Row *row; + ME_Run *run; const unsigned int nMaxChars = *(WORD *) lParam; unsigned int nCharsLeft = nMaxChars; char *dest = (char *) lParam; - BOOL wroteNull = FALSE; + ME_Cursor start, end; - TRACE("EM_GETLINE: row=%d, nMaxChars=%d (%s)\n", (int) wParam, nMaxChars, - unicode ? "Unicode" : "Ansi"); + TRACE( "EM_GETLINE: row=%d, nMaxChars=%d\n", (int)wParam, nMaxChars ); - run = ME_FindRowWithNumber(editor, wParam); - if (run == NULL) - return 0; + row = row_from_row_number( editor, wParam ); + if (row == NULL) return 0; - while (nCharsLeft && (run = ME_FindItemFwd(run, diRunOrStartRow)) - && run->type == diRun) + row_first_cursor( row, &start ); + row_end_cursor( row, &end, TRUE ); + run = start.run; + while (nCharsLeft) { - WCHAR *str = get_text( &run->member.run, 0 ); + WCHAR *str; unsigned int nCopy; + int ofs = (run == start.run) ? start.nOffset : 0; + int len = (run == end.run) ? end.nOffset : run->len; - nCopy = min(nCharsLeft, run->member.run.len); + str = get_text( run, ofs ); + nCopy = min( nCharsLeft, len ); - if (unicode) - memcpy(dest, str, nCopy * sizeof(WCHAR)); - else - nCopy = WideCharToMultiByte(CP_ACP, 0, str, nCopy, dest, - nCharsLeft, NULL, NULL); - dest += nCopy * (unicode ? sizeof(WCHAR) : 1); + memcpy(dest, str, nCopy * sizeof(WCHAR)); + dest += nCopy * sizeof(WCHAR); nCharsLeft -= nCopy; + if (run == end.run) break; + run = row_next_run( row, run ); } /* append line termination, space allowing */ - if (nCharsLeft > 0) - { - if (unicode) - *((WCHAR *)dest) = '\0'; - else - *dest = '\0'; - nCharsLeft--; - wroteNull = TRUE; - } + if (nCharsLeft > 0) *((WCHAR *)dest) = '\0'; TRACE("EM_GETLINE: got %u characters\n", nMaxChars - nCharsLeft); - return nMaxChars - nCharsLeft - (wroteNull ? 1 : 0); + return nMaxChars - nCharsLeft; } case EM_GETLINECOUNT: { - ME_DisplayItem *item = editor->pBuffer->pLast; - int nRows = editor->total_rows; - ME_DisplayItem *prev_para = NULL, *last_para = NULL; - - last_para = ME_FindItemBack(item, diRun); - prev_para = ME_FindItemBack(last_para, diRun); - assert(last_para); - assert(last_para->member.run.nFlags & MERF_ENDPARA); - if (editor->bEmulateVersion10 && prev_para && - last_para->member.run.nCharOfs == 0 && - prev_para->member.run.len == 1 && - *get_text( &prev_para->member.run, 0 ) == '\r') + int count = editor->total_rows; + ME_Run *prev_run, *last_run; + + last_run = para_end_run( para_prev( editor_end_para( editor ) ) ); + prev_run = run_prev_all_paras( last_run ); + + if (editor->bEmulateVersion10 && prev_run && last_run->nCharOfs == 0 && + prev_run->len == 1 && *get_text( prev_run, 0 ) == '\r') { /* In 1.0 emulation, the last solitary \r at the very end of the text (if one exists) is NOT a line break. FIXME: this is an ugly hack. This should have a more regular model. */ - nRows--; + count--; } - TRACE("EM_GETLINECOUNT: nRows==%d\n", nRows); - return max(1, nRows); + count = max(1, count); + TRACE("EM_GETLINECOUNT: count==%d\n", count); + return count; } case EM_LINEFROMCHAR: { - if (wParam == -1) - return ME_RowNumberFromCharOfs(editor, ME_GetCursorOfs(&editor->pCursors[1])); - else - return ME_RowNumberFromCharOfs(editor, wParam); + if (wParam == -1) wParam = ME_GetCursorOfs( editor->pCursors + 1 ); + return row_number_from_char_ofs( editor, wParam ); } case EM_EXLINEFROMCHAR: { - if (lParam == -1) - return ME_RowNumberFromCharOfs(editor, ME_GetCursorOfs(&editor->pCursors[1])); - else - return ME_RowNumberFromCharOfs(editor, lParam); + if (lParam == -1) lParam = ME_GetCursorOfs( editor->pCursors + 1 ); + return row_number_from_char_ofs( editor, lParam ); } case EM_LINEINDEX: { - ME_DisplayItem *item, *para; - int nCharOfs; + ME_Row *row; + ME_Cursor cursor; + int ofs; - if (wParam == -1) - item = ME_FindItemBack(editor->pCursors[0].pRun, diStartRow); - else - item = ME_FindRowWithNumber(editor, wParam); - if (!item) - return -1; - para = ME_GetParagraph(item); - item = ME_FindItemFwd(item, diRun); - nCharOfs = para->member.para.nCharOfs + item->member.run.nCharOfs; - TRACE("EM_LINEINDEX: nCharOfs==%d\n", nCharOfs); - return nCharOfs; + if (wParam == -1) row = row_from_cursor( editor->pCursors ); + else row = row_from_row_number( editor, wParam ); + if (!row) return -1; + + row_first_cursor( row, &cursor ); + ofs = ME_GetCursorOfs( &cursor ); + TRACE( "EM_LINEINDEX: nCharOfs==%d\n", ofs ); + return ofs; } case EM_LINELENGTH: { - ME_DisplayItem *item, *item_end; - int nChars = 0, nThisLineOfs = 0, nNextLineOfs = 0; - ME_DisplayItem *para, *run; + ME_Row *row; + int start_ofs, end_ofs; + ME_Cursor cursor; if (wParam > ME_GetTextLength(editor)) return 0; @@ -4333,20 +3816,14 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, FIXME("EM_LINELENGTH: returning number of unselected characters on lines with selection unsupported.\n"); return 0; } - ME_RunOfsFromCharOfs(editor, wParam, ¶, &run, NULL); - item = ME_RowStart(run); - nThisLineOfs = ME_CharOfsFromRunOfs(editor, para, ME_FindItemFwd(item, diRun), 0); - item_end = ME_FindItemFwd(item, diStartRowOrParagraphOrEnd); - if (item_end->type == diStartRow) { - nNextLineOfs = ME_CharOfsFromRunOfs(editor, para, ME_FindItemFwd(item_end, diRun), 0); - } else { - ME_DisplayItem *endRun = ME_FindItemBack(item_end, diRun); - assert(endRun && endRun->member.run.nFlags & MERF_ENDPARA); - nNextLineOfs = item_end->member.para.nCharOfs - endRun->member.run.len; - } - nChars = nNextLineOfs - nThisLineOfs; - TRACE("EM_LINELENGTH(%ld)==%d\n",wParam, nChars); - return nChars; + cursor_from_char_ofs( editor, wParam, &cursor ); + row = row_from_cursor( &cursor ); + row_first_cursor( row, &cursor ); + start_ofs = ME_GetCursorOfs( &cursor ); + row_end_cursor( row, &cursor, FALSE ); + end_ofs = ME_GetCursorOfs( &cursor ); + TRACE( "EM_LINELENGTH(%ld)==%d\n", wParam, end_ofs - start_ofs ); + return end_ofs - start_ofs; } case EM_EXLIMITTEXT: { @@ -4371,46 +3848,12 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, return editor->nTextLimit; } case EM_FINDTEXT: - { - LRESULT r; - if(!unicode){ - FINDTEXTA *ft = (FINDTEXTA *)lParam; - int nChars = MultiByteToWideChar(CP_ACP, 0, ft->lpstrText, -1, NULL, 0); - WCHAR *tmp; - - if ((tmp = heap_alloc(nChars * sizeof(*tmp))) != NULL) - MultiByteToWideChar(CP_ACP, 0, ft->lpstrText, -1, tmp, nChars); - r = ME_FindText(editor, wParam, &ft->chrg, tmp, NULL); - heap_free(tmp); - }else{ - FINDTEXTW *ft = (FINDTEXTW *)lParam; - r = ME_FindText(editor, wParam, &ft->chrg, ft->lpstrText, NULL); - } - return r; - } - case EM_FINDTEXTEX: - { - LRESULT r; - if(!unicode){ - FINDTEXTEXA *ex = (FINDTEXTEXA *)lParam; - int nChars = MultiByteToWideChar(CP_ACP, 0, ex->lpstrText, -1, NULL, 0); - WCHAR *tmp; - - if ((tmp = heap_alloc(nChars * sizeof(*tmp))) != NULL) - MultiByteToWideChar(CP_ACP, 0, ex->lpstrText, -1, tmp, nChars); - r = ME_FindText(editor, wParam, &ex->chrg, tmp, &ex->chrgText); - heap_free(tmp); - }else{ - FINDTEXTEXW *ex = (FINDTEXTEXW *)lParam; - r = ME_FindText(editor, wParam, &ex->chrg, ex->lpstrText, &ex->chrgText); - } - return r; - } case EM_FINDTEXTW: { FINDTEXTW *ft = (FINDTEXTW *)lParam; return ME_FindText(editor, wParam, &ft->chrg, ft->lpstrText, NULL); } + case EM_FINDTEXTEX: case EM_FINDTEXTEXW: { FINDTEXTEXW *ex = (FINDTEXTEXW *)lParam; @@ -4435,8 +3878,8 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, } case EM_POSFROMCHAR: { - ME_DisplayItem *pPara, *pRun; - int nCharOfs, nOffset, nLength; + ME_Cursor cursor; + int nCharOfs, nLength; POINTL pt = {0,0}; nCharOfs = wParam; @@ -4447,61 +3890,37 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, nCharOfs = min(nCharOfs, nLength); nCharOfs = max(nCharOfs, 0); - ME_RunOfsFromCharOfs(editor, nCharOfs, &pPara, &pRun, &nOffset); - assert(pRun->type == diRun); - pt.y = pRun->member.run.pt.y; - pt.x = pRun->member.run.pt.x + ME_PointFromChar(editor, &pRun->member.run, nOffset, TRUE); - pt.y += pPara->member.para.pt.y + editor->rcFormat.top; + cursor_from_char_ofs( editor, nCharOfs, &cursor ); + pt.y = cursor.run->pt.y; + pt.x = cursor.run->pt.x + + ME_PointFromChar( editor, cursor.run, cursor.nOffset, TRUE ); + pt.y += cursor.para->pt.y + editor->rcFormat.top; pt.x += editor->rcFormat.left; pt.x -= editor->horz_si.nPos; pt.y -= editor->vert_si.nPos; - if (wParam >= 0x40000) { - *(POINTL *)wParam = pt; - } + if (wParam >= 0x40000) *(POINTL *)wParam = pt; + return (wParam >= 0x40000) ? 0 : MAKELONG( pt.x, pt.y ); } - case WM_CREATE: - return ME_WmCreate(editor, lParam, unicode); - case WM_DESTROY: - ME_DestroyEditor(editor); - return 0; - case WM_SETCURSOR: - { - POINT cursor_pos; - if (wParam == (WPARAM)editor->hWnd && GetCursorPos(&cursor_pos) && - ScreenToClient(editor->hWnd, &cursor_pos)) - ME_LinkNotify(editor, msg, 0, MAKELPARAM(cursor_pos.x, cursor_pos.y)); - return ME_SetCursor(editor); - } case WM_LBUTTONDBLCLK: case WM_LBUTTONDOWN: { ME_CommitUndo(editor); /* End coalesced undos for typed characters */ - if ((editor->nEventMask & ENM_MOUSEEVENTS) && - !ME_FilterEvent(editor, msg, &wParam, &lParam)) - return 0; ITextHost_TxSetFocus(editor->texthost); ME_LButtonDown(editor, (short)LOWORD(lParam), (short)HIWORD(lParam), ME_CalculateClickCount(editor, msg, wParam, lParam)); ITextHost_TxSetCapture(editor->texthost, TRUE); editor->bMouseCaptured = TRUE; - ME_LinkNotify(editor, msg, wParam, lParam); - if (!ME_SetCursor(editor)) goto do_default; + link_notify( editor, msg, wParam, lParam ); break; } case WM_MOUSEMOVE: - if ((editor->nEventMask & ENM_MOUSEEVENTS) && - !ME_FilterEvent(editor, msg, &wParam, &lParam)) - return 0; if (editor->bMouseCaptured) ME_MouseMove(editor, (short)LOWORD(lParam), (short)HIWORD(lParam)); else - ME_LinkNotify(editor, msg, wParam, lParam); - /* Set cursor if mouse is captured, since WM_SETCURSOR won't be received. */ - if (editor->bMouseCaptured) - ME_SetCursor(editor); + link_notify( editor, msg, wParam, lParam ); break; case WM_LBUTTONUP: if (editor->bMouseCaptured) { @@ -4510,23 +3929,16 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, } if (editor->nSelectionType == stDocument) editor->nSelectionType = stPosition; - if ((editor->nEventMask & ENM_MOUSEEVENTS) && - !ME_FilterEvent(editor, msg, &wParam, &lParam)) - return 0; else { - ME_SetCursor(editor); - ME_LinkNotify(editor, msg, wParam, lParam); + link_notify( editor, msg, wParam, lParam ); } break; case WM_RBUTTONUP: case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: ME_CommitUndo(editor); /* End coalesced undos for typed characters */ - if ((editor->nEventMask & ENM_MOUSEEVENTS) && - !ME_FilterEvent(editor, msg, &wParam, &lParam)) - return 0; - ME_LinkNotify(editor, msg, wParam, lParam); + link_notify( editor, msg, wParam, lParam ); goto do_default; case WM_CONTEXTMENU: if (!ME_ShowContextMenu(editor, (short)LOWORD(lParam), (short)HIWORD(lParam))) @@ -4536,8 +3948,8 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, editor->bHaveFocus = TRUE; create_caret(editor); update_caret(editor); - ME_SendOldNotify(editor, EN_SETFOCUS); - if (!editor->bHideSelection && !(editor->styleFlags & ES_NOHIDESEL)) + ITextHost_TxNotify( editor->texthost, EN_SETFOCUS, NULL ); + if (!editor->bHideSelection && (editor->props & TXTBIT_HIDESELECTION)) ME_InvalidateSelection( editor ); return 0; case WM_KILLFOCUS: @@ -4546,48 +3958,33 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, editor->wheel_remain = 0; hide_caret(editor); DestroyCaret(); - ME_SendOldNotify(editor, EN_KILLFOCUS); - if (!editor->bHideSelection && !(editor->styleFlags & ES_NOHIDESEL)) + ITextHost_TxNotify( editor->texthost, EN_KILLFOCUS, NULL ); + if (!editor->bHideSelection && (editor->props & TXTBIT_HIDESELECTION)) ME_InvalidateSelection( editor ); return 0; case WM_COMMAND: TRACE("editor wnd command = %d\n", LOWORD(wParam)); return 0; - case WM_KEYUP: - if ((editor->nEventMask & ENM_KEYEVENTS) && - !ME_FilterEvent(editor, msg, &wParam, &lParam)) - return 0; - goto do_default; case WM_KEYDOWN: - if ((editor->nEventMask & ENM_KEYEVENTS) && - !ME_FilterEvent(editor, msg, &wParam, &lParam)) - return 0; if (ME_KeyDown(editor, LOWORD(wParam))) return 0; goto do_default; case WM_CHAR: - if ((editor->nEventMask & ENM_KEYEVENTS) && - !ME_FilterEvent(editor, msg, &wParam, &lParam)) - return 0; - return ME_Char(editor, wParam, lParam, unicode); + return handle_wm_char( editor, wParam, lParam ); case WM_UNICHAR: - if (unicode) - { - if(wParam == UNICODE_NOCHAR) return TRUE; - if(wParam <= 0x000fffff) - { - if(wParam > 0xffff) /* convert to surrogates */ - { - wParam -= 0x10000; - ME_Char(editor, (wParam >> 10) + 0xd800, 0, TRUE); - ME_Char(editor, (wParam & 0x03ff) + 0xdc00, 0, TRUE); - } else { - ME_Char(editor, wParam, 0, TRUE); - } - } - return 0; - } - break; + if (wParam == UNICODE_NOCHAR) return TRUE; + if (wParam <= 0x000fffff) + { + if (wParam > 0xffff) /* convert to surrogates */ + { + wParam -= 0x10000; + handle_wm_char( editor, (wParam >> 10) + 0xd800, 0 ); + handle_wm_char( editor, (wParam & 0x03ff) + 0xdc00, 0 ); + } + else + handle_wm_char( editor, wParam, 0 ); + } + return 0; case EM_STOPGROUPTYPING: ME_CommitUndo(editor); /* End coalesced undos for typed characters */ return 0; @@ -4598,12 +3995,11 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, switch(LOWORD(wParam)) { case SB_LEFT: - ME_ScrollAbs(editor, 0, 0); + scroll_abs( editor, 0, 0, TRUE ); break; case SB_RIGHT: - ME_ScrollAbs(editor, - editor->horz_si.nMax - (int)editor->horz_si.nPage, - editor->vert_si.nMax - (int)editor->vert_si.nPage); + scroll_abs( editor, editor->horz_si.nMax - (int)editor->horz_si.nPage, + editor->vert_si.nMax - (int)editor->vert_si.nPage, TRUE ); break; case SB_LINELEFT: ME_ScrollLeft(editor, scrollUnit); @@ -4623,7 +4019,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, int pos = HIWORD(wParam); if (editor->horz_si.nMax > 0xffff) pos = MulDiv(pos, editor->horz_si.nMax, 0xffff); - ME_HScrollAbs(editor, pos); + scroll_h_abs( editor, pos, FALSE ); break; } } @@ -4640,12 +4036,11 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, switch(LOWORD(wParam)) { case SB_TOP: - ME_ScrollAbs(editor, 0, 0); + scroll_abs( editor, 0, 0, TRUE ); break; case SB_BOTTOM: - ME_ScrollAbs(editor, - editor->horz_si.nMax - (int)editor->horz_si.nPage, - editor->vert_si.nMax - (int)editor->vert_si.nPage); + scroll_abs( editor, editor->horz_si.nMax - (int)editor->horz_si.nPage, + editor->vert_si.nMax - (int)editor->vert_si.nPage, TRUE ); break; case SB_LINEUP: ME_ScrollUp(editor,lineHeight); @@ -4665,7 +4060,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, int pos = HIWORD(wParam); if (editor->vert_si.nMax > 0xffff) pos = MulDiv(pos, editor->vert_si.nMax, 0xffff); - ME_VScrollAbs(editor, pos); + scroll_v_abs( editor, pos, FALSE ); break; } } @@ -4675,16 +4070,8 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, } case WM_MOUSEWHEEL: { - int delta; - BOOL ctrl_is_down; - - if ((editor->nEventMask & ENM_MOUSEEVENTS) && - !ME_FilterEvent(editor, msg, &wParam, &lParam)) - return 0; - - ctrl_is_down = GetKeyState(VK_CONTROL) & 0x8000; - - delta = GET_WHEEL_DELTA_WPARAM(wParam); + int delta = GET_WHEEL_DELTA_WPARAM( wParam ); + BOOL ctrl_is_down = GetKeyState( VK_CONTROL ) & 0x8000; /* if scrolling changes direction, ignore left overs */ if ((delta < 0 && editor->wheel_remain < 0) || @@ -4719,78 +4106,9 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, } break; } - case EM_GETRECT: - { - *((RECT *)lParam) = editor->rcFormat; - if (editor->bDefaultFormatRect) - ((RECT *)lParam)->left -= editor->selofs; - return 0; - } - case EM_SETRECT: - case EM_SETRECTNP: - { - if (lParam) - { - int border = 0; - RECT clientRect; - RECT *rc = (RECT *)lParam; - - border = editor->exStyleFlags & WS_EX_CLIENTEDGE ? 1 : 0; - ITextHost_TxGetClientRect(editor->texthost, &clientRect); - if (wParam == 0) - { - editor->rcFormat.top = max(0, rc->top - border); - editor->rcFormat.left = max(0, rc->left - border); - editor->rcFormat.bottom = min(clientRect.bottom, rc->bottom); - editor->rcFormat.right = min(clientRect.right, rc->right + border); - } else if (wParam == 1) { - /* MSDN incorrectly says a wParam value of 1 causes the - * lParam rect to be used as a relative offset, - * however, the tests show it just prevents min/max bound - * checking. */ - editor->rcFormat.top = rc->top - border; - editor->rcFormat.left = rc->left - border; - editor->rcFormat.bottom = rc->bottom; - editor->rcFormat.right = rc->right + border; - } else { - return 0; - } - editor->bDefaultFormatRect = FALSE; - } - else - { - ME_SetDefaultFormatRect(editor); - editor->bDefaultFormatRect = TRUE; - } - ME_MarkAllForWrapping(editor); - ME_WrapMarkedParagraphs(editor); - ME_UpdateScrollBar(editor); - if (msg != EM_SETRECTNP) - ME_Repaint(editor); - return 0; - } case EM_REQUESTRESIZE: ME_SendRequestResize(editor, TRUE); return 0; - case WM_SETREDRAW: - goto do_default; - case WM_WINDOWPOSCHANGED: - { - RECT clientRect; - WINDOWPOS *winpos = (WINDOWPOS *)lParam; - - if (winpos->flags & SWP_NOCLIENTSIZE) goto do_default; - ITextHost_TxGetClientRect(editor->texthost, &clientRect); - if (editor->bDefaultFormatRect) { - ME_SetDefaultFormatRect(editor); - } else { - editor->rcFormat.right += clientRect.right - editor->prevClientRect.right; - editor->rcFormat.bottom += clientRect.bottom - editor->prevClientRect.bottom; - } - editor->prevClientRect = clientRect; - ME_RewrapRepaint(editor); - goto do_default; - } #ifndef __REACTOS__ /* IME messages to make richedit controls IME aware */ #endif @@ -4843,7 +4161,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, { HIMC hIMC; - ME_Style *style = ME_GetInsertStyle(editor, 0); + ME_Style *style = style_get_insert_style( editor, editor->pCursors ); hIMC = ITextHost_TxImmGetContext(editor->texthost); ME_DeleteSelection(editor); ME_SaveTempStyle(editor, style); @@ -4890,18 +4208,10 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, #endif } case EM_GETOLEINTERFACE: - { - if (!editor->reOle) - if (!CreateIRichEditOle(NULL, editor, (LPVOID *)&editor->reOle)) - return 0; - if (IUnknown_QueryInterface(editor->reOle, &IID_IRichEditOle, (LPVOID *)lParam) == S_OK) - return 1; - return 0; - } - case EM_GETPASSWORDCHAR: - { - return editor->cPasswordMask; - } + IRichEditOle_AddRef( editor->richole ); + *(IRichEditOle **)lParam = editor->richole; + return 1; + case EM_SETOLECALLBACK: if(editor->lpOleCallback) IRichEditOleCallback_Release(editor->lpOleCallback); @@ -4947,24 +4257,18 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, /* plain text can only have the default style. */ ME_ClearTempStyle(editor); ME_AddRefStyle(editor->pBuffer->pDefaultStyle); - ME_ReleaseStyle(editor->pCursors[0].pRun->member.run.style); - editor->pCursors[0].pRun->member.run.style = editor->pBuffer->pDefaultStyle; + ME_ReleaseStyle( editor->pCursors[0].run->style ); + editor->pCursors[0].run->style = editor->pBuffer->pDefaultStyle; } } /* FIXME: Currently no support for undo level and code page options */ editor->mode = (editor->mode & ~mask) | changes; return 0; } - case EM_SETPASSWORDCHAR: - { - editor->cPasswordMask = wParam; - ME_RewrapRepaint(editor); - return 0; - } case EM_SETTARGETDEVICE: if (wParam == 0) { - BOOL new = (lParam == 0 && (editor->styleFlags & ES_MULTILINE)); + BOOL new = (lParam == 0 && (editor->props & TXTBIT_MULTILINE)); if (editor->nAvailWidth || editor->bWordWrap != new) { editor->bWordWrap = new; @@ -4973,7 +4277,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, } } else { int width = max(0, lParam); - if ((editor->styleFlags & ES_MULTILINE) && + if ((editor->props & TXTBIT_MULTILINE) && (!editor->bWordWrap || editor->nAvailWidth != width)) { editor->nAvailWidth = width; @@ -4991,192 +4295,6 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, return 0L; } -static BOOL create_windowed_editor(HWND hwnd, CREATESTRUCTW *create, BOOL emulate_10) -{ - ITextHost *host = ME_CreateTextHost( hwnd, create, emulate_10 ); - ME_TextEditor *editor; - - if (!host) return FALSE; - - editor = ME_MakeEditor( host, emulate_10 ); - if (!editor) - { - ITextHost_Release( host ); - return FALSE; - } - - editor->exStyleFlags = GetWindowLongW( hwnd, GWL_EXSTYLE ); - editor->styleFlags |= GetWindowLongW( hwnd, GWL_STYLE ) & ES_WANTRETURN; - editor->hWnd = hwnd; /* FIXME: Remove editor's dependence on hWnd */ - editor->hwndParent = create->hwndParent; - - SetWindowLongPtrW( hwnd, 0, (LONG_PTR)editor ); - - return TRUE; -} - -static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam, - LPARAM lParam, BOOL unicode) -{ - ME_TextEditor *editor; - HRESULT hresult; - LRESULT lresult = 0; - - TRACE("enter hwnd %p msg %04x (%s) %lx %lx, unicode %d\n", - hWnd, msg, get_msg_name(msg), wParam, lParam, unicode); - - editor = (ME_TextEditor *)GetWindowLongPtrW(hWnd, 0); - if (!editor) - { - if (msg == WM_NCCREATE) - { - CREATESTRUCTW *pcs = (CREATESTRUCTW *)lParam; - - TRACE("WM_NCCREATE: hWnd %p style 0x%08x\n", hWnd, pcs->style); - return create_windowed_editor( hWnd, pcs, FALSE ); - } - else - { - return DefWindowProcW(hWnd, msg, wParam, lParam); - } - } - - switch (msg) - { - case WM_PAINT: - { - HDC hdc; - RECT rc; - PAINTSTRUCT ps; - HBRUSH old_brush; - - update_caret(editor); - hdc = BeginPaint(editor->hWnd, &ps); - if (!editor->bEmulateVersion10 || (editor->nEventMask & ENM_UPDATE)) - ME_SendOldNotify(editor, EN_UPDATE); - old_brush = SelectObject(hdc, editor->hbrBackground); - - /* Erase area outside of the formatting rectangle */ - if (ps.rcPaint.top < editor->rcFormat.top) - { - rc = ps.rcPaint; - rc.bottom = editor->rcFormat.top; - PatBlt(hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY); - ps.rcPaint.top = editor->rcFormat.top; - } - if (ps.rcPaint.bottom > editor->rcFormat.bottom) { - rc = ps.rcPaint; - rc.top = editor->rcFormat.bottom; - PatBlt(hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY); - ps.rcPaint.bottom = editor->rcFormat.bottom; - } - if (ps.rcPaint.left < editor->rcFormat.left) { - rc = ps.rcPaint; - rc.right = editor->rcFormat.left; - PatBlt(hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY); - ps.rcPaint.left = editor->rcFormat.left; - } - if (ps.rcPaint.right > editor->rcFormat.right) { - rc = ps.rcPaint; - rc.left = editor->rcFormat.right; - PatBlt(hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY); - ps.rcPaint.right = editor->rcFormat.right; - } - - ME_PaintContent(editor, hdc, &ps.rcPaint); - SelectObject(hdc, old_brush); - EndPaint(editor->hWnd, &ps); - return 0; - } - case WM_ERASEBKGND: - { - HDC hDC = (HDC)wParam; - RECT rc; - - if (GetUpdateRect(editor->hWnd, &rc, TRUE)) - FillRect(hDC, &rc, editor->hbrBackground); - return 1; - } - case EM_SETOPTIONS: - { - DWORD dwStyle; - const DWORD mask = ECO_VERTICAL | ECO_AUTOHSCROLL | ECO_AUTOVSCROLL | - ECO_NOHIDESEL | ECO_READONLY | ECO_WANTRETURN | - ECO_SELECTIONBAR; - lresult = ME_HandleMessage(editor, msg, wParam, lParam, unicode, &hresult); - dwStyle = GetWindowLongW(hWnd, GWL_STYLE); - dwStyle = (dwStyle & ~mask) | (lresult & mask); - SetWindowLongW(hWnd, GWL_STYLE, dwStyle); - return lresult; - } - case EM_SETREADONLY: - { - DWORD dwStyle; - lresult = ME_HandleMessage(editor, msg, wParam, lParam, unicode, &hresult); - dwStyle = GetWindowLongW(hWnd, GWL_STYLE); - dwStyle &= ~ES_READONLY; - if (wParam) - dwStyle |= ES_READONLY; - SetWindowLongW(hWnd, GWL_STYLE, dwStyle); - return lresult; - } - default: - lresult = ME_HandleMessage(editor, msg, wParam, lParam, unicode, &hresult); - } - - if (hresult == S_FALSE) - lresult = DefWindowProcW(hWnd, msg, wParam, lParam); - - TRACE("exit hwnd %p msg %04x (%s) %lx %lx, unicode %d -> %lu\n", - hWnd, msg, get_msg_name(msg), wParam, lParam, unicode, lresult); - - return lresult; -} - -static LRESULT WINAPI RichEditWndProcW(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - BOOL unicode = TRUE; - - /* Under Win9x RichEdit20W returns ANSI strings, see the tests. */ - if (msg == WM_GETTEXT && (GetVersion() & 0x80000000)) - unicode = FALSE; - - return RichEditWndProc_common(hWnd, msg, wParam, lParam, unicode); -} - -static LRESULT WINAPI RichEditWndProcA(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - return RichEditWndProc_common(hWnd, msg, wParam, lParam, FALSE); -} - -/****************************************************************** - * RichEditANSIWndProc (RICHED20.10) - */ -LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - return RichEditWndProcA(hWnd, msg, wParam, lParam); -} - -/****************************************************************** - * RichEdit10ANSIWndProc (RICHED20.9) - */ -LRESULT WINAPI RichEdit10ANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - if (msg == WM_NCCREATE && !GetWindowLongPtrW(hWnd, 0)) - { - CREATESTRUCTW *pcs = (CREATESTRUCTW *)lParam; - - TRACE("WM_NCCREATE: hWnd %p style 0x%08x\n", hWnd, pcs->style); - return create_windowed_editor( hWnd, pcs, TRUE ); - } - return RichEditANSIWndProc(hWnd, msg, wParam, lParam); -} - -void ME_SendOldNotify(ME_TextEditor *editor, int nCode) -{ - ITextHost_TxNotify(editor->texthost, nCode, NULL); -} - /* Fill buffer with srcChars unicode characters from the start cursor. * * buffer: destination buffer @@ -5193,27 +4311,23 @@ int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int buflen, const ME_Cursor *start, int srcChars, BOOL bCRLF, BOOL bEOP) { - ME_DisplayItem *pRun, *pNextRun; + ME_Run *run, *next_run; const WCHAR *pStart = buffer; - const WCHAR cr_lf[] = {'\r', '\n', 0}; const WCHAR *str; int nLen; /* bCRLF flag is only honored in 2.0 and up. 1.0 must always return text verbatim */ if (editor->bEmulateVersion10) bCRLF = FALSE; - pRun = start->pRun; - assert(pRun); - pNextRun = ME_FindItemFwd(pRun, diRun); + run = start->run; + next_run = run_next_all_paras( run ); - nLen = pRun->member.run.len - start->nOffset; - str = get_text( &pRun->member.run, start->nOffset ); + nLen = run->len - start->nOffset; + str = get_text( run, start->nOffset ); - while (srcChars && buflen && pNextRun) + while (srcChars && buflen && next_run) { - int nFlags = pRun->member.run.nFlags; - - if (bCRLF && nFlags & MERF_ENDPARA && ~nFlags & MERF_ENDCELL) + if (bCRLF && run->nFlags & MERF_ENDPARA && ~run->nFlags & MERF_ENDCELL) { if (buflen == 1) break; /* FIXME: native fails to reduce srcChars here for WM_GETTEXT or @@ -5221,8 +4335,10 @@ int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int buflen, * also uses this function. */ srcChars -= min(nLen, srcChars); nLen = 2; - str = cr_lf; - } else { + str = L"\r\n"; + } + else + { nLen = min(nLen, srcChars); srcChars -= nLen; } @@ -5234,14 +4350,18 @@ int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int buflen, buffer += nLen; - pRun = pNextRun; - pNextRun = ME_FindItemFwd(pRun, diRun); + run = next_run; + next_run = run_next_all_paras( run ); - nLen = pRun->member.run.len; - str = get_text( &pRun->member.run, 0 ); + nLen = run->len; + str = get_text( run, 0 ); } /* append '\r' to the last paragraph. */ - if (pRun->next->type == diTextEnd && bEOP) +#ifdef __REACTOS__ + if (run == para_end_run( para_prev( editor_end_para( editor ) ) ) && bEOP && buflen) +#else + if (run == para_end_run( para_prev( editor_end_para( editor ) ) ) && bEOP) +#endif { *buffer = '\r'; buffer ++; @@ -5250,114 +4370,6 @@ int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int buflen, return buffer - pStart; } -static BOOL ME_RegisterEditorClass(HINSTANCE hInstance) -{ - WNDCLASSW wcW; - WNDCLASSA wcA; - - wcW.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS; - wcW.lpfnWndProc = RichEditWndProcW; - wcW.cbClsExtra = 0; - wcW.cbWndExtra = sizeof(ME_TextEditor *); - wcW.hInstance = NULL; /* hInstance would register DLL-local class */ - wcW.hIcon = NULL; - wcW.hCursor = LoadCursorW(NULL, (LPWSTR)IDC_IBEAM); - wcW.hbrBackground = GetStockObject(NULL_BRUSH); - wcW.lpszMenuName = NULL; - - if (is_version_nt()) - { - wcW.lpszClassName = RICHEDIT_CLASS20W; - if (!RegisterClassW(&wcW)) return FALSE; - wcW.lpszClassName = MSFTEDIT_CLASS; - if (!RegisterClassW(&wcW)) return FALSE; - } - else - { - /* WNDCLASSA/W have the same layout */ - wcW.lpszClassName = (LPCWSTR)"RichEdit20W"; - if (!RegisterClassA((WNDCLASSA *)&wcW)) return FALSE; - wcW.lpszClassName = (LPCWSTR)"RichEdit50W"; - if (!RegisterClassA((WNDCLASSA *)&wcW)) return FALSE; - } - - wcA.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS; - wcA.lpfnWndProc = RichEditWndProcA; - wcA.cbClsExtra = 0; - wcA.cbWndExtra = sizeof(ME_TextEditor *); - wcA.hInstance = NULL; /* hInstance would register DLL-local class */ - wcA.hIcon = NULL; - wcA.hCursor = LoadCursorW(NULL, (LPWSTR)IDC_IBEAM); - wcA.hbrBackground = GetStockObject(NULL_BRUSH); - wcA.lpszMenuName = NULL; - wcA.lpszClassName = RICHEDIT_CLASS20A; - if (!RegisterClassA(&wcA)) return FALSE; - wcA.lpszClassName = "RichEdit50A"; - if (!RegisterClassA(&wcA)) return FALSE; - - return TRUE; -} - -static LRESULT WINAPI REComboWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - /* FIXME: Not implemented */ - TRACE("hWnd %p msg %04x (%s) %08lx %08lx\n", - hWnd, msg, get_msg_name(msg), wParam, lParam); - return DefWindowProcW(hWnd, msg, wParam, lParam); -} - -static LRESULT WINAPI REListWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - /* FIXME: Not implemented */ - TRACE("hWnd %p msg %04x (%s) %08lx %08lx\n", - hWnd, msg, get_msg_name(msg), wParam, lParam); - return DefWindowProcW(hWnd, msg, wParam, lParam); -} - -/****************************************************************** - * REExtendedRegisterClass (RICHED20.8) - * - * FIXME undocumented - * Need to check for errors and implement controls and callbacks - */ -LRESULT WINAPI REExtendedRegisterClass(void) -{ - WNDCLASSW wcW; - UINT result; - - FIXME("semi stub\n"); - - wcW.cbClsExtra = 0; - wcW.cbWndExtra = 4; - wcW.hInstance = NULL; - wcW.hIcon = NULL; - wcW.hCursor = NULL; - wcW.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); - wcW.lpszMenuName = NULL; - - if (!ME_ListBoxRegistered) - { - wcW.style = CS_PARENTDC | CS_DBLCLKS | CS_GLOBALCLASS; - wcW.lpfnWndProc = REListWndProc; - wcW.lpszClassName = REListBox20W; - if (RegisterClassW(&wcW)) ME_ListBoxRegistered = TRUE; - } - - if (!ME_ComboBoxRegistered) - { - wcW.style = CS_PARENTDC | CS_DBLCLKS | CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW; - wcW.lpfnWndProc = REComboWndProc; - wcW.lpszClassName = REComboBox20W; - if (RegisterClassW(&wcW)) ME_ComboBoxRegistered = TRUE; - } - - result = 0; - if (ME_ListBoxRegistered) - result += 1; - if (ME_ComboBoxRegistered) - result += 2; - - return result; -} - static int __cdecl wchar_comp( const void *key, const void *elem ) { return *(const WCHAR *)key - *(const WCHAR *)elem; @@ -5368,13 +4380,13 @@ static int __cdecl wchar_comp( const void *key, const void *elem ) static BOOL isurlneutral( WCHAR c ) { /* NB this list is sorted */ - static const WCHAR neutral_chars[] = {'!','\"','\'','(',')',',','-','.',':',';','<','>','?','[',']','{','}'}; + static const WCHAR neutral_chars[] = L"!\"'(),-.:;<>?[]{}"; /* Some shortcuts */ if (isalnum( c )) return FALSE; - if (c > neutral_chars[ARRAY_SIZE( neutral_chars ) - 1]) return FALSE; + if (c > L'}') return FALSE; - return !!bsearch( &c, neutral_chars, ARRAY_SIZE( neutral_chars ), sizeof(c), wchar_comp ); + return !!bsearch( &c, neutral_chars, ARRAY_SIZE( neutral_chars ) - 1, sizeof(c), wchar_comp ); } /** @@ -5396,8 +4408,8 @@ static BOOL ME_FindNextURLCandidate(ME_TextEditor *editor, while (nChars > 0) { - WCHAR *str = get_text( &cursor.pRun->member.run, 0 ); - int run_len = cursor.pRun->member.run.len; + WCHAR *str = get_text( cursor.run, 0 ); + int run_len = cursor.run->len; nChars -= run_len - cursor.nOffset; @@ -5411,8 +4423,8 @@ static BOOL ME_FindNextURLCandidate(ME_TextEditor *editor, { *candidate_min = cursor; candidateStarted = TRUE; - neutral_end.pPara = NULL; - space_end.pPara = NULL; + neutral_end.para = NULL; + space_end.para = NULL; cursor.nOffset++; break; } @@ -5431,9 +4443,9 @@ static BOOL ME_FindNextURLCandidate(ME_TextEditor *editor, { if (quoted && c != '\r') { - if (!space_end.pPara) + if (!space_end.para) { - if (neutral_end.pPara) + if (neutral_end.para) space_end = neutral_end; else space_end = cursor; @@ -5446,31 +4458,31 @@ static BOOL ME_FindNextURLCandidate(ME_TextEditor *editor, { if (quoted && c == '>') { - neutral_end.pPara = NULL; - space_end.pPara = NULL; + neutral_end.para = NULL; + space_end.para = NULL; goto done; } - if (!neutral_end.pPara) + if (!neutral_end.para) neutral_end = cursor; } else - neutral_end.pPara = NULL; + neutral_end.para = NULL; cursor.nOffset++; } } cursor.nOffset = 0; - if (!ME_NextRun(&cursor.pPara, &cursor.pRun, TRUE)) + if (!cursor_next_run( &cursor, TRUE )) goto done; } done: if (candidateStarted) { - if (space_end.pPara) + if (space_end.para) *candidate_max = space_end; - else if (neutral_end.pPara) + else if (neutral_end.para) *candidate_max = neutral_end; else *candidate_max = cursor; @@ -5486,23 +4498,25 @@ static BOOL ME_FindNextURLCandidate(ME_TextEditor *editor, static BOOL ME_IsCandidateAnURL(ME_TextEditor *editor, const ME_Cursor *start, int nChars) { #define MAX_PREFIX_LEN 9 +#define X(str) str, ARRAY_SIZE(str) - 1 struct prefix_s { const WCHAR text[MAX_PREFIX_LEN]; int length; }prefixes[] = { - {{'p','r','o','s','p','e','r','o',':'}, 9}, - {{'t','e','l','n','e','t',':'}, 7}, - {{'g','o','p','h','e','r',':'}, 7}, - {{'m','a','i','l','t','o',':'}, 7}, - {{'h','t','t','p','s',':'}, 6}, - {{'f','i','l','e',':'}, 5}, - {{'n','e','w','s',':'}, 5}, - {{'w','a','i','s',':'}, 5}, - {{'n','n','t','p',':'}, 5}, - {{'h','t','t','p',':'}, 5}, - {{'w','w','w','.'}, 4}, - {{'f','t','p',':'}, 4}, + {X(L"prospero:")}, + {X(L"telnet:")}, + {X(L"gopher:")}, + {X(L"mailto:")}, + {X(L"https:")}, + {X(L"file:")}, + {X(L"news:")}, + {X(L"wais:")}, + {X(L"nntp:")}, + {X(L"http:")}, + {X(L"www.")}, + {X(L"ftp:")}, }; +#undef X WCHAR bufferW[MAX_PREFIX_LEN + 1]; unsigned int i; @@ -5559,7 +4573,7 @@ static BOOL ME_UpdateLinkAttribute(ME_TextEditor *editor, ME_Cursor *start, int nChars = 0; } - if (startCur.pRun != candidateStart.pRun || + if (startCur.run != candidateStart.run || startCur.nOffset != candidateStart.nOffset) { /* CFE_LINK effect should be consistently unset */ @@ -5576,15 +4590,15 @@ static BOOL ME_UpdateLinkAttribute(ME_TextEditor *editor, ME_Cursor *start, int /* Update candidateEnd since setting character formats may split * runs, which can cause a cursor to be at an invalid offset within * a split run. */ - while (candidateEnd.nOffset >= candidateEnd.pRun->member.run.len) + while (candidateEnd.nOffset >= candidateEnd.run->len) { - candidateEnd.nOffset -= candidateEnd.pRun->member.run.len; - candidateEnd.pRun = ME_FindItemFwd(candidateEnd.pRun, diRun); + candidateEnd.nOffset -= candidateEnd.run->len; + candidateEnd.run = run_next_all_paras( candidateEnd.run ); } modified = TRUE; } } - if (candidateStart.pRun != candidateEnd.pRun || + if (candidateStart.run != candidateEnd.run || candidateStart.nOffset != candidateEnd.nOffset) { /* CFE_LINK effect should be consistently set */ diff --git a/dll/win32/riched20/editor.h b/dll/win32/riched20/editor.h index 2bd06be2cf61d..9f05a9e6c959b 100644 --- a/dll/win32/riched20/editor.h +++ b/dll/win32/riched20/editor.h @@ -24,6 +24,7 @@ struct _RTF_Info; +extern HINSTANCE dll_instance DECLSPEC_HIDDEN; extern HANDLE me_heap DECLSPEC_HIDDEN; #define RUN_IS_HIDDEN(run) ((run)->style->fmt.dwMask & CFM_HIDDEN \ @@ -49,11 +50,11 @@ static inline const char *debugstr_run( const ME_Run *run ) } /* style.c */ +ME_Style *style_get_insert_style( ME_TextEditor *editor, ME_Cursor *cursor ) DECLSPEC_HIDDEN; ME_Style *ME_MakeStyle(CHARFORMAT2W *style) DECLSPEC_HIDDEN; void ME_AddRefStyle(ME_Style *item) DECLSPEC_HIDDEN; void ME_DestroyStyle(ME_Style *item) DECLSPEC_HIDDEN; void ME_ReleaseStyle(ME_Style *item) DECLSPEC_HIDDEN; -ME_Style *ME_GetInsertStyle(ME_TextEditor *editor, int nCursor) DECLSPEC_HIDDEN; ME_Style *ME_ApplyStyle(ME_TextEditor *ed, ME_Style *sSrc, CHARFORMAT2W *style) DECLSPEC_HIDDEN; void select_style(ME_Context *c, ME_Style *s) DECLSPEC_HIDDEN; void ME_InitCharFormat2W(CHARFORMAT2W *pFmt) DECLSPEC_HIDDEN; @@ -69,15 +70,12 @@ void ME_CharFormatFromLogFont(HDC hDC, const LOGFONTW *lf, CHARFORMAT2W *fmt) DE /* list.c */ void ME_InsertBefore(ME_DisplayItem *diWhere, ME_DisplayItem *diWhat) DECLSPEC_HIDDEN; void ME_Remove(ME_DisplayItem *diWhere) DECLSPEC_HIDDEN; -BOOL ME_NextRun(ME_DisplayItem **para, ME_DisplayItem **run, BOOL all_para) DECLSPEC_HIDDEN; -BOOL ME_PrevRun(ME_DisplayItem **para, ME_DisplayItem **run, BOOL all_para) DECLSPEC_HIDDEN; ME_DisplayItem *ME_FindItemBack(ME_DisplayItem *di, ME_DIType nTypeOrClass) DECLSPEC_HIDDEN; ME_DisplayItem *ME_FindItemFwd(ME_DisplayItem *di, ME_DIType nTypeOrClass) DECLSPEC_HIDDEN; ME_DisplayItem *ME_FindItemBackOrHere(ME_DisplayItem *di, ME_DIType nTypeOrClass) DECLSPEC_HIDDEN; ME_DisplayItem *ME_MakeDI(ME_DIType type) DECLSPEC_HIDDEN; void ME_DestroyDisplayItem(ME_DisplayItem *item) DECLSPEC_HIDDEN; void ME_DumpDocument(ME_TextBuffer *buffer) DECLSPEC_HIDDEN; -void destroy_para(ME_TextEditor *editor, ME_DisplayItem *item) DECLSPEC_HIDDEN; /* string.c */ ME_String *ME_MakeStringN(LPCWSTR szText, int nMaxChars) DECLSPEC_HIDDEN; @@ -114,32 +112,47 @@ int ME_ReverseFindNonWhitespaceV(const ME_String *s, int nVChar) DECLSPEC_HIDDEN int ME_ReverseFindWhitespaceV(const ME_String *s, int nVChar) DECLSPEC_HIDDEN; /* row.c */ -ME_DisplayItem *ME_RowStart(ME_DisplayItem *item) DECLSPEC_HIDDEN; -/* ME_DisplayItem *ME_RowEnd(ME_DisplayItem *item); */ -ME_DisplayItem *ME_FindRowWithNumber(ME_TextEditor *editor, int nRow) DECLSPEC_HIDDEN; -int ME_RowNumberFromCharOfs(ME_TextEditor *editor, int nOfs) DECLSPEC_HIDDEN; +void row_end_cursor( ME_Row *row, ME_Cursor *cursor, BOOL include_eop ) DECLSPEC_HIDDEN; +void row_first_cursor( ME_Row *row, ME_Cursor *cursor ) DECLSPEC_HIDDEN; +ME_Run *row_first_run( ME_Row *row ) DECLSPEC_HIDDEN; +ME_Row *row_from_cursor( ME_Cursor *cursor ) DECLSPEC_HIDDEN; +ME_Row *row_from_row_number( ME_TextEditor *editor, int row_num ) DECLSPEC_HIDDEN; +ME_Row *row_next( ME_Row *row ) DECLSPEC_HIDDEN; +ME_Row *row_next_all_paras( ME_Row *row ) DECLSPEC_HIDDEN; +ME_Run *row_next_run( ME_Row *row, ME_Run *run ) DECLSPEC_HIDDEN; +int row_number_from_char_ofs( ME_TextEditor *editor, int ofs ) DECLSPEC_HIDDEN; +ME_Paragraph *row_para( ME_Row *row ) DECLSPEC_HIDDEN; +ME_Row *row_prev_all_paras( ME_Row *row ) DECLSPEC_HIDDEN; +static inline ME_DisplayItem *row_get_di( ME_Row *row ) +{ + return (ME_DisplayItem *)((ptrdiff_t)row - offsetof(ME_DisplayItem, member)); +} /* run.c */ -ME_DisplayItem *ME_MakeRun(ME_Style *s, int nFlags) DECLSPEC_HIDDEN; -ME_DisplayItem *ME_InsertRunAtCursor(ME_TextEditor *editor, ME_Cursor *cursor, - ME_Style *style, const WCHAR *str, int len, int flags) DECLSPEC_HIDDEN; +void cursor_from_char_ofs( ME_TextEditor *editor, int char_ofs, ME_Cursor *cursor ) DECLSPEC_HIDDEN; +BOOL cursor_next_run( ME_Cursor *cursor, BOOL all_para ) DECLSPEC_HIDDEN; +BOOL cursor_prev_run( ME_Cursor *cursor, BOOL all_para ) DECLSPEC_HIDDEN; +void editor_propagate_char_ofs( ME_Paragraph *para, ME_Run *run, int shift ) DECLSPEC_HIDDEN; +int run_char_ofs( ME_Run *run, int ofs ) DECLSPEC_HIDDEN; +ME_Run *run_create( ME_Style *s, int nFlags ) DECLSPEC_HIDDEN; +ME_Run *run_insert( ME_TextEditor *editor, ME_Cursor *cursor, + ME_Style *style, const WCHAR *str, int len, int flags ) DECLSPEC_HIDDEN; void ME_CheckCharOffsets(ME_TextEditor *editor) DECLSPEC_HIDDEN; -void ME_PropagateCharOffset(ME_DisplayItem *p, int shift) DECLSPEC_HIDDEN; /* this one accounts for 1/2 char tolerance */ int ME_CharFromPointContext(ME_Context *c, int cx, ME_Run *run, BOOL closest, BOOL visual_order) DECLSPEC_HIDDEN; int ME_CharFromPoint(ME_TextEditor *editor, int cx, ME_Run *run, BOOL closest, BOOL visual_order) DECLSPEC_HIDDEN; int ME_PointFromCharContext(ME_Context *c, ME_Run *pRun, int nOffset, BOOL visual_order) DECLSPEC_HIDDEN; int ME_PointFromChar(ME_TextEditor *editor, ME_Run *pRun, int nOffset, BOOL visual_order) DECLSPEC_HIDDEN; BOOL ME_CanJoinRuns(const ME_Run *run1, const ME_Run *run2) DECLSPEC_HIDDEN; -void ME_JoinRuns(ME_TextEditor *editor, ME_DisplayItem *p) DECLSPEC_HIDDEN; -ME_DisplayItem *ME_SplitRunSimple(ME_TextEditor *editor, ME_Cursor *cursor) DECLSPEC_HIDDEN; +void run_join( ME_TextEditor *editor, ME_Run *run ) DECLSPEC_HIDDEN; +ME_Run *run_next( ME_Run *run ) DECLSPEC_HIDDEN; +ME_Run *run_next_all_paras( ME_Run *run ) DECLSPEC_HIDDEN; +ME_Run *run_prev( ME_Run *run ) DECLSPEC_HIDDEN; +ME_Run *run_prev_all_paras( ME_Run *run ) DECLSPEC_HIDDEN; +ME_Run *run_split( ME_TextEditor *editor, ME_Cursor *cursor ) DECLSPEC_HIDDEN; void ME_UpdateRunFlags(ME_TextEditor *editor, ME_Run *run) DECLSPEC_HIDDEN; SIZE ME_GetRunSizeCommon(ME_Context *c, const ME_Paragraph *para, ME_Run *run, int nLen, int startx, int *pAscent, int *pDescent) DECLSPEC_HIDDEN; -void ME_CursorFromCharOfs(ME_TextEditor *editor, int nCharOfs, ME_Cursor *pCursor) DECLSPEC_HIDDEN; -void ME_RunOfsFromCharOfs(ME_TextEditor *editor, int nCharOfs, ME_DisplayItem **ppPara, ME_DisplayItem **ppRun, int *pOfs) DECLSPEC_HIDDEN; -int ME_CharOfsFromRunOfs(ME_TextEditor *editor, const ME_DisplayItem *pPara, const ME_DisplayItem *pRun, int nOfs) DECLSPEC_HIDDEN; -void ME_SkipAndPropagateCharOffset(ME_DisplayItem *p, int shift) DECLSPEC_HIDDEN; void ME_SetCharFormat(ME_TextEditor *editor, ME_Cursor *start, ME_Cursor *end, CHARFORMAT2W *pFmt) DECLSPEC_HIDDEN; void ME_SetSelectionCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt) DECLSPEC_HIDDEN; void ME_GetCharFormat(ME_TextEditor *editor, const ME_Cursor *from, @@ -147,8 +160,13 @@ void ME_GetCharFormat(ME_TextEditor *editor, const ME_Cursor *from, void ME_GetSelectionCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt) DECLSPEC_HIDDEN; void ME_GetDefaultCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt) DECLSPEC_HIDDEN; void ME_SetDefaultCharFormat(ME_TextEditor *editor, CHARFORMAT2W *mod) DECLSPEC_HIDDEN; +static inline ME_DisplayItem *run_get_di( ME_Run *run ) +{ + return (ME_DisplayItem *)((ptrdiff_t)run - offsetof(ME_DisplayItem, member)); +} /* caret.c */ +void cursor_coords( ME_TextEditor *editor, ME_Cursor *cursor, int *x, int *y, int *height ) DECLSPEC_HIDDEN; void ME_SetCursorToStart(ME_TextEditor *editor, ME_Cursor *cursor) DECLSPEC_HIDDEN; int set_selection_cursors(ME_TextEditor *editor, int from, int to) DECLSPEC_HIDDEN; BOOL ME_MoveCursorWords(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs) DECLSPEC_HIDDEN; @@ -177,7 +195,6 @@ BOOL ME_InternalDeleteText(ME_TextEditor *editor, ME_Cursor *start, int nChars, int ME_GetTextLength(ME_TextEditor *editor) DECLSPEC_HIDDEN; int ME_GetTextLengthEx(ME_TextEditor *editor, const GETTEXTLENGTHEX *how) DECLSPEC_HIDDEN; ME_Style *ME_GetSelectionInsertStyle(ME_TextEditor *editor) DECLSPEC_HIDDEN; -void ME_GetCursorCoordinates(ME_TextEditor *editor, ME_Cursor *pCursor, int *x, int *y, int *height) DECLSPEC_HIDDEN; /* context.c */ void ME_InitContext(ME_Context *c, ME_TextEditor *editor, HDC hDC) DECLSPEC_HIDDEN; @@ -185,36 +202,49 @@ void ME_DestroyContext(ME_Context *c) DECLSPEC_HIDDEN; /* wrap.c */ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) DECLSPEC_HIDDEN; -void ME_InvalidateParagraphRange(ME_TextEditor *editor, ME_DisplayItem *start_para, ME_DisplayItem *last_para) DECLSPEC_HIDDEN; +void para_range_invalidate( ME_TextEditor *editor, ME_Paragraph *start_para, ME_Paragraph *last_para ) DECLSPEC_HIDDEN; void ME_SendRequestResize(ME_TextEditor *editor, BOOL force) DECLSPEC_HIDDEN; +BOOL wrap_marked_paras_dc( ME_TextEditor *editor, HDC hdc, BOOL invalidate ) DECLSPEC_HIDDEN; /* para.c */ -ME_DisplayItem *ME_GetParagraph(ME_DisplayItem *run) DECLSPEC_HIDDEN; -void ME_GetSelectionParas(ME_TextEditor *editor, ME_DisplayItem **para, ME_DisplayItem **para_end) DECLSPEC_HIDDEN; +void editor_get_selection_paras(ME_TextEditor *editor, ME_Paragraph **para, ME_Paragraph **para_end ) DECLSPEC_HIDDEN; +void editor_get_selection_para_fmt( ME_TextEditor *editor, PARAFORMAT2 *fmt ) DECLSPEC_HIDDEN; +void editor_mark_rewrap_all( ME_TextEditor *editor ) DECLSPEC_HIDDEN; +void editor_set_default_para_fmt(ME_TextEditor *editor, PARAFORMAT2 *pFmt) DECLSPEC_HIDDEN; +BOOL editor_set_selection_para_fmt( ME_TextEditor *editor, const PARAFORMAT2 *fmt ) DECLSPEC_HIDDEN; void ME_MakeFirstParagraph(ME_TextEditor *editor) DECLSPEC_HIDDEN; -ME_DisplayItem *ME_SplitParagraph(ME_TextEditor *editor, ME_DisplayItem *rp, ME_Style *style, const WCHAR *eol_str, int eol_len, int paraFlags) DECLSPEC_HIDDEN; -ME_DisplayItem *ME_JoinParagraphs(ME_TextEditor *editor, ME_DisplayItem *tp, - BOOL keepFirstParaFormat) DECLSPEC_HIDDEN; void ME_DumpParaStyle(ME_Paragraph *s) DECLSPEC_HIDDEN; void ME_DumpParaStyleToBuf(const PARAFORMAT2 *pFmt, char buf[2048]) DECLSPEC_HIDDEN; -BOOL ME_SetSelectionParaFormat(ME_TextEditor *editor, const PARAFORMAT2 *pFmt) DECLSPEC_HIDDEN; -void ME_GetSelectionParaFormat(ME_TextEditor *editor, PARAFORMAT2 *pFmt) DECLSPEC_HIDDEN; -void ME_MarkAllForWrapping(ME_TextEditor *editor) DECLSPEC_HIDDEN; -void ME_SetDefaultParaFormat(ME_TextEditor *editor, PARAFORMAT2 *pFmt) DECLSPEC_HIDDEN; -void para_num_init( ME_Context *c, ME_Paragraph *para ) DECLSPEC_HIDDEN; -void para_num_clear( struct para_num *pn ) DECLSPEC_HIDDEN; int get_total_width(ME_TextEditor *editor) DECLSPEC_HIDDEN; -void mark_para_rewrap(ME_TextEditor *editor, ME_DisplayItem *para) DECLSPEC_HIDDEN; -ME_DisplayItem *get_di_from_para(ME_Paragraph *para) DECLSPEC_HIDDEN; -void add_marked_para(ME_TextEditor *editor, ME_DisplayItem *para) DECLSPEC_HIDDEN; -void remove_marked_para(ME_TextEditor *editor, ME_DisplayItem *para) DECLSPEC_HIDDEN; +ME_Cell *para_cell( ME_Paragraph *para ) DECLSPEC_HIDDEN; +void para_destroy( ME_TextEditor *editor, ME_Paragraph *item ) DECLSPEC_HIDDEN; +ME_Row *para_end_row( ME_Paragraph *para ) DECLSPEC_HIDDEN; +ME_Run *para_end_run( ME_Paragraph *para ) DECLSPEC_HIDDEN; +ME_Row *para_first_row( ME_Paragraph *para ) DECLSPEC_HIDDEN; +ME_Run *para_first_run( ME_Paragraph *para ) DECLSPEC_HIDDEN; +BOOL para_in_table( ME_Paragraph *para ) DECLSPEC_HIDDEN; +ME_Paragraph *para_join( ME_TextEditor *editor, ME_Paragraph *para, BOOL use_first_fmt ) DECLSPEC_HIDDEN; +void para_mark_add( ME_TextEditor *editor, ME_Paragraph *para ) DECLSPEC_HIDDEN; +void para_mark_remove( ME_TextEditor *editor, ME_Paragraph *para ) DECLSPEC_HIDDEN; +void para_mark_rewrap( ME_TextEditor *editor, ME_Paragraph *para ) DECLSPEC_HIDDEN; +ME_Paragraph *para_next( ME_Paragraph *para ) DECLSPEC_HIDDEN; +void para_num_clear( struct para_num *pn ) DECLSPEC_HIDDEN; +void para_num_init( ME_Context *c, ME_Paragraph *para ) DECLSPEC_HIDDEN; +ME_Paragraph *para_prev( ME_Paragraph *para ) DECLSPEC_HIDDEN; +ME_Paragraph *para_split( ME_TextEditor *editor, ME_Run *run, ME_Style *style, + const WCHAR *eol_str, int eol_len, int paraFlags ) DECLSPEC_HIDDEN; + +static inline ME_DisplayItem *para_get_di(ME_Paragraph *para) +{ + return (ME_DisplayItem *)((ptrdiff_t)para - offsetof(ME_DisplayItem, member)); +} /* paint.c */ -void ME_PaintContent(ME_TextEditor *editor, HDC hDC, const RECT *rcUpdate) DECLSPEC_HIDDEN; +void editor_draw( ME_TextEditor *editor, HDC hDC, const RECT *update ) DECLSPEC_HIDDEN; void ME_Repaint(ME_TextEditor *editor) DECLSPEC_HIDDEN; void ME_RewrapRepaint(ME_TextEditor *editor) DECLSPEC_HIDDEN; void ME_UpdateRepaint(ME_TextEditor *editor, BOOL update_now) DECLSPEC_HIDDEN; -void ME_EnsureVisible(ME_TextEditor *editor, ME_Cursor *pCursor) DECLSPEC_HIDDEN; +void editor_ensure_visible( ME_TextEditor *editor, ME_Cursor *cursor ) DECLSPEC_HIDDEN; void ME_InvalidateSelection(ME_TextEditor *editor) DECLSPEC_HIDDEN; BOOL ME_SetZoom(ME_TextEditor *editor, int numerator, int denominator) DECLSPEC_HIDDEN; int ME_twips2pointsX(const ME_Context *c, int x) DECLSPEC_HIDDEN; @@ -222,9 +252,9 @@ int ME_twips2pointsY(const ME_Context *c, int y) DECLSPEC_HIDDEN; /* scroll functions in paint.c */ -void ME_ScrollAbs(ME_TextEditor *editor, int x, int y) DECLSPEC_HIDDEN; -void ME_HScrollAbs(ME_TextEditor *editor, int x) DECLSPEC_HIDDEN; -void ME_VScrollAbs(ME_TextEditor *editor, int y) DECLSPEC_HIDDEN; +void scroll_abs( ME_TextEditor *editor, int x, int y, BOOL notify ) DECLSPEC_HIDDEN; +void scroll_h_abs( ME_TextEditor *editor, int x, BOOL notify ) DECLSPEC_HIDDEN; +void scroll_v_abs( ME_TextEditor *editor, int y, BOOL notify ) DECLSPEC_HIDDEN; void ME_ScrollUp(ME_TextEditor *editor, int cy) DECLSPEC_HIDDEN; void ME_ScrollDown(ME_TextEditor *editor, int cy) DECLSPEC_HIDDEN; void ME_ScrollLeft(ME_TextEditor *editor, int cx) DECLSPEC_HIDDEN; @@ -235,18 +265,19 @@ void ME_UpdateScrollBar(ME_TextEditor *editor) DECLSPEC_HIDDEN; int ME_GetParaBorderWidth(const ME_Context *c, int flags) DECLSPEC_HIDDEN; /* richole.c */ -LRESULT CreateIRichEditOle(IUnknown *outer_unk, ME_TextEditor *editor, LPVOID *ppvObj) DECLSPEC_HIDDEN; -void ME_DrawOLE(ME_Context *c, int x, int y, ME_Run* run, BOOL selected) DECLSPEC_HIDDEN; +void draw_ole( ME_Context *c, int x, int y, ME_Run* run, BOOL selected ) DECLSPEC_HIDDEN; void ME_GetOLEObjectSize(const ME_Context *c, ME_Run *run, SIZE *pSize) DECLSPEC_HIDDEN; void ME_CopyReObject(REOBJECT *dst, const REOBJECT *src, DWORD flags) DECLSPEC_HIDDEN; void ME_DeleteReObject(struct re_object *re_object) DECLSPEC_HIDDEN; +void richole_release_children( struct text_services *services ) DECLSPEC_HIDDEN; +extern const IRichEditOleVtbl re_ole_vtbl DECLSPEC_HIDDEN; +extern const ITextDocument2OldVtbl text_doc2old_vtbl DECLSPEC_HIDDEN; /* editor.c */ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10) DECLSPEC_HIDDEN; void ME_DestroyEditor(ME_TextEditor *editor) DECLSPEC_HIDDEN; -LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, - LPARAM lParam, BOOL unicode, HRESULT* phresult) DECLSPEC_HIDDEN; -void ME_SendOldNotify(ME_TextEditor *editor, int nCode) DECLSPEC_HIDDEN; +LRESULT editor_handle_message( ME_TextEditor *editor, UINT msg, WPARAM wParam, + LPARAM lParam, HRESULT* phresult ) DECLSPEC_HIDDEN; int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int buflen, const ME_Cursor *start, int srcChars, BOOL bCRLF, BOOL bEOP) DECLSPEC_HIDDEN; void ME_RTFCharAttrHook(struct _RTF_Info *info) DECLSPEC_HIDDEN; @@ -257,32 +288,47 @@ void ME_StreamInFill(ME_InStream *stream) DECLSPEC_HIDDEN; extern BOOL me_debug DECLSPEC_HIDDEN; void ME_ReplaceSel(ME_TextEditor *editor, BOOL can_undo, const WCHAR *str, int len) DECLSPEC_HIDDEN; int set_selection( ME_TextEditor *editor, int to, int from ) DECLSPEC_HIDDEN; +HRESULT editor_copy_or_cut( ME_TextEditor *editor, BOOL cut, ME_Cursor *start, int count, + IDataObject **data_out ) DECLSPEC_HIDDEN; +ME_Paragraph *editor_end_para( ME_TextEditor *editor ) DECLSPEC_HIDDEN; +ME_Paragraph *editor_first_para( ME_TextEditor *editor ) DECLSPEC_HIDDEN; +void editor_set_cursor( ME_TextEditor *editor, int x, int y ) DECLSPEC_HIDDEN; +void link_notify( ME_TextEditor *editor, UINT msg, WPARAM wParam, LPARAM lParam ) DECLSPEC_HIDDEN; /* table.c */ -BOOL ME_IsInTable(ME_DisplayItem *pItem) DECLSPEC_HIDDEN; -ME_DisplayItem *ME_InsertTableRowStartFromCursor(ME_TextEditor *editor) DECLSPEC_HIDDEN; -ME_DisplayItem *ME_InsertTableRowStartAtParagraph(ME_TextEditor *editor, - ME_DisplayItem *para) DECLSPEC_HIDDEN; -ME_DisplayItem *ME_InsertTableCellFromCursor(ME_TextEditor *editor) DECLSPEC_HIDDEN; -ME_DisplayItem *ME_InsertTableRowEndFromCursor(ME_TextEditor *editor) DECLSPEC_HIDDEN; -ME_DisplayItem *ME_GetTableRowEnd(ME_DisplayItem *para) DECLSPEC_HIDDEN; -ME_DisplayItem *ME_GetTableRowStart(ME_DisplayItem *para) DECLSPEC_HIDDEN; -ME_DisplayItem *ME_GetOuterParagraph(ME_DisplayItem *para) DECLSPEC_HIDDEN; -void ME_CheckTablesForCorruption(ME_TextEditor *editor) DECLSPEC_HIDDEN; -void ME_ProtectPartialTableDeletion(ME_TextEditor *editor, ME_Cursor *c, int *nChars) DECLSPEC_HIDDEN; -ME_DisplayItem* ME_AppendTableRow(ME_TextEditor *editor, ME_DisplayItem *table_row) DECLSPEC_HIDDEN; -void ME_TabPressedInTable(ME_TextEditor *editor, BOOL bSelectedRow) DECLSPEC_HIDDEN; -void ME_MoveCursorFromTableRowStartParagraph(ME_TextEditor *editor) DECLSPEC_HIDDEN; +ME_Cell *cell_create( void ) DECLSPEC_HIDDEN; +ME_Paragraph *cell_end_para( ME_Cell *cell ) DECLSPEC_HIDDEN; +ME_Paragraph *cell_first_para( ME_Cell *cell ) DECLSPEC_HIDDEN; +ME_Cell *cell_next( ME_Cell *cell ) DECLSPEC_HIDDEN; +ME_Cell *cell_prev( ME_Cell *cell ) DECLSPEC_HIDDEN; +ME_Paragraph *table_append_row( ME_TextEditor *editor, ME_Paragraph *table_row ) DECLSPEC_HIDDEN; +void table_handle_tab( ME_TextEditor *editor, BOOL selected_row ) DECLSPEC_HIDDEN; +ME_Paragraph *table_insert_cell( ME_TextEditor *editor, ME_Cursor *cursor ) DECLSPEC_HIDDEN; +ME_Paragraph *table_insert_row_end( ME_TextEditor *editor, ME_Cursor *cursor ) DECLSPEC_HIDDEN; +ME_Paragraph *table_insert_row_start( ME_TextEditor *editor, ME_Cursor *cursor ) DECLSPEC_HIDDEN; +ME_Paragraph *table_insert_row_start_at_para( ME_TextEditor *editor, ME_Paragraph *para ) DECLSPEC_HIDDEN; +void table_move_from_row_start( ME_TextEditor *editor ) DECLSPEC_HIDDEN; +ME_Paragraph *table_outer_para( ME_Paragraph *para ) DECLSPEC_HIDDEN; +void table_protect_partial_deletion( ME_TextEditor *editor, ME_Cursor *c, int *num_chars ) DECLSPEC_HIDDEN; +ME_Paragraph *table_row_end( ME_Paragraph *para ) DECLSPEC_HIDDEN; +ME_Cell *table_row_end_cell( ME_Paragraph *para ) DECLSPEC_HIDDEN; +ME_Cell *table_row_first_cell( ME_Paragraph *para ) DECLSPEC_HIDDEN; +ME_Paragraph *table_row_start( ME_Paragraph *para ) DECLSPEC_HIDDEN; struct RTFTable *ME_MakeTableDef(ME_TextEditor *editor) DECLSPEC_HIDDEN; void ME_InitTableDef(ME_TextEditor *editor, struct RTFTable *tableDef) DECLSPEC_HIDDEN; +static inline ME_DisplayItem *cell_get_di(ME_Cell *cell) +{ + return (ME_DisplayItem *)((ptrdiff_t)cell - offsetof(ME_DisplayItem, member)); +} + /* txthost.c */ -ITextHost *ME_CreateTextHost(HWND hwnd, CREATESTRUCTW *cs, BOOL bEmulateVersion10) DECLSPEC_HIDDEN; -#if defined(__i386__) && !defined(__MINGW32__) /* Use wrappers to perform thiscall on i386 */ -#define TXTHOST_VTABLE(This) (&itextHostStdcallVtbl) -#else /* __i386__ */ +#ifdef __ASM_USE_THISCALL_WRAPPER +extern const struct ITextHost2Vtbl text_host2_stdcall_vtbl DECLSPEC_HIDDEN; +#define TXTHOST_VTABLE(This) (&text_host2_stdcall_vtbl) +#else #define TXTHOST_VTABLE(This) (This)->lpVtbl -#endif /* __i386__ */ +#endif /*** ITextHost methods ***/ #define ITextHost_TxGetDC(This) TXTHOST_VTABLE(This)->TxGetDC(This) #define ITextHost_TxReleaseDC(This,a) TXTHOST_VTABLE(This)->TxReleaseDC(This,a) @@ -323,6 +369,19 @@ ITextHost *ME_CreateTextHost(HWND hwnd, CREATESTRUCTW *cs, BOOL bEmulateVersion1 #define ITextHost_TxImmGetContext(This) TXTHOST_VTABLE(This)->TxImmGetContext(This) #define ITextHost_TxImmReleaseContext(This,a) TXTHOST_VTABLE(This)->TxImmReleaseContext(This,a) #define ITextHost_TxGetSelectionBarWidth(This,a) TXTHOST_VTABLE(This)->TxGetSelectionBarWidth(This,a) +/* ITextHost2 */ +#define ITextHost2_TxIsDoubleClickPending(This) TXTHOST_VTABLE(This)->TxIsDoubleClickPending(This) +#define ITextHost2_TxGetWindow(This,a) TXTHOST_VTABLE(This)->TxGetWindow(This,a) +#define ITextHost2_TxSetForegroundWindow(This) TXTHOST_VTABLE(This)->TxSetForegroundWindow(This) +#define ITextHost2_TxGetPalette(This) TXTHOST_VTABLE(This)->TxGetPalette(This) +#define ITextHost2_TxGetEastAsianFlags(This,a) TXTHOST_VTABLE(This)->TxGetEastAsianFlags(This,a) +#define ITextHost2_TxSetCursor2(This,a,b) TXTHOST_VTABLE(This)->TxSetCursor2(This,a,b) +#define ITextHost2_TxFreeTextServicesNotification(This) TXTHOST_VTABLE(This)->TxFreeTextServicesNotification(This) +#define ITextHost2_TxGetEditStyle(This,a,b) TXTHOST_VTABLE(This)->TxGetEditStyle(This,a,b) +#define ITextHost2_TxGetWindowStyles(This,a,b) TXTHOST_VTABLE(This)->TxGetWindowStyles(This,a,b) +#define ITextHost2_TxShowDropCaret(This,a,b,c) TXTHOST_VTABLE(This)->TxShowDropCaret(This,a,b,c) +#define ITextHost2_TxDestroyCaret(This) TXTHOST_VTABLE(This)->TxDestroyCaret(This) +#define ITextHost2_TxGetHorzExtent(This,a) TXTHOST_VTABLE(This)->TxGetHorzExtent(This,a) /* undo.c */ BOOL add_undo_insert_run( ME_TextEditor *, int pos, const WCHAR *str, int len, int flags, ME_Style *style ) DECLSPEC_HIDDEN; @@ -338,6 +397,33 @@ BOOL ME_Undo(ME_TextEditor *editor) DECLSPEC_HIDDEN; BOOL ME_Redo(ME_TextEditor *editor) DECLSPEC_HIDDEN; void ME_EmptyUndoStack(ME_TextEditor *editor) DECLSPEC_HIDDEN; +/* txtsrv.c */ +HRESULT create_text_services( IUnknown *outer, ITextHost *text_host, IUnknown **unk, BOOL emulate_10 ) DECLSPEC_HIDDEN; +#ifdef __ASM_USE_THISCALL_WRAPPER +extern const struct ITextServicesVtbl text_services_stdcall_vtbl DECLSPEC_HIDDEN; +#define TXTSERV_VTABLE(This) (&text_services_stdcall_vtbl) +#else +#define TXTSERV_VTABLE(This) (This)->lpVtbl +#endif +#define ITextServices_TxSendMessage(This,a,b,c,d) TXTSERV_VTABLE(This)->TxSendMessage(This,a,b,c,d) +#define ITextServices_TxDraw(This,a,b,c,d,e,f,g,h,i,j,k,l) TXTSERV_VTABLE(This)->TxDraw(This,a,b,c,d,e,f,g,h,i,j,k,l) +#define ITextServices_TxGetHScroll(This,a,b,c,d,e) TXTSERV_VTABLE(This)->TxGetHScroll(This,a,b,c,d,e) +#define ITextServices_TxGetVScroll(This,a,b,c,d,e) TXTSERV_VTABLE(This)->TxGetVScroll(This,a,b,c,d,e) +#define ITextServices_OnTxSetCursor(This,a,b,c,d,e,f,g,h,i) TXTSERV_VTABLE(This)->OnTxSetCursor(This,a,b,c,d,e,f,g,h,i) +#define ITextServices_TxQueryHitPoint(This,a,b,c,d,e,f,g,h,i,j) TXTSERV_VTABLE(This)->TxQueryHitPoint(This,a,b,c,d,e,f,g,h,i,j) +#define ITextServices_OnTxInPlaceActivate(This,a) TXTSERV_VTABLE(This)->OnTxInPlaceActivate(This,a) +#define ITextServices_OnTxInPlaceDeactivate(This) TXTSERV_VTABLE(This)->OnTxInPlaceDeactivate(This) +#define ITextServices_OnTxUIActivate(This) TXTSERV_VTABLE(This)->OnTxUIActivate(This) +#define ITextServices_OnTxUIDeactivate(This) TXTSERV_VTABLE(This)->OnTxUIDeactivate(This) +#define ITextServices_TxGetText(This,a) TXTSERV_VTABLE(This)->TxGetText(This,a) +#define ITextServices_TxSetText(This,a) TXTSERV_VTABLE(This)->TxSetText(This,a) +#define ITextServices_TxGetCurTargetX(This,a) TXTSERV_VTABLE(This)->TxGetCurTargetX(This,a) +#define ITextServices_TxGetBaseLinePos(This,a) TXTSERV_VTABLE(This)->TxGetBaseLinePos(This,a) +#define ITextServices_TxGetNaturalSize(This,a,b,c,d,e,f,g,h) TXTSERV_VTABLE(This)->TxGetNaturalSize(This,a,b,c,d,e,f,g,h) +#define ITextServices_TxGetDropTarget(This,a) TXTSERV_VTABLE(This)->TxGetDropTarget(This,a) +#define ITextServices_OnTxPropertyBitsChange(This,a,b) TXTSERV_VTABLE(This)->OnTxPropertyBitsChange(This,a,b) +#define ITextServices_TxGetCachedSize(This,a,b) TXTSERV_VTABLE(This)->TxGetCachedSize(This,a,b) + /* writer.c */ LRESULT ME_StreamOutRange(ME_TextEditor *editor, DWORD dwFormat, const ME_Cursor *start, int nChars, EDITSTREAM *stream) DECLSPEC_HIDDEN; LRESULT ME_StreamOut(ME_TextEditor *editor, DWORD dwFormat, EDITSTREAM *stream) DECLSPEC_HIDDEN; @@ -346,3 +432,4 @@ LRESULT ME_StreamOut(ME_TextEditor *editor, DWORD dwFormat, EDITSTREAM *stream) HRESULT ME_GetDataObject(ME_TextEditor *editor, const ME_Cursor *start, int nChars, LPDATAOBJECT *lplpdataobj) DECLSPEC_HIDDEN; void release_typelib(void) DECLSPEC_HIDDEN; + diff --git a/dll/win32/riched20/editstr.h b/dll/win32/riched20/editstr.h index 337750c4052f8..115e550f5af77 100644 --- a/dll/win32/riched20/editstr.h +++ b/dll/win32/riched20/editstr.h @@ -41,15 +41,14 @@ #include #include "imm.h" #include +#include #include "usp10.h" +#include "wine/asm.h" #include "wine/debug.h" #include "wine/heap.h" #include "wine/list.h" - -#if defined(__i386__) && !defined(__MINGW32__) -extern const struct ITextHostVtbl itextHostStdcallVtbl DECLSPEC_HIDDEN; -#endif /* __i386__ */ +#include "wine/rbtree.h" typedef struct tagME_String { @@ -204,7 +203,7 @@ typedef struct tagME_Paragraph PARAFORMAT2 fmt; ME_String *text; - struct tagME_DisplayItem *pCell; /* v4.1 */ + struct tagME_Cell *cell; /* v4.1 */ ME_BorderRect border; int nCharOfs; @@ -215,7 +214,7 @@ typedef struct tagME_Paragraph struct para_num para_num; ME_Run *eop_run; /* ptr to the end-of-para run */ struct tagME_DisplayItem *prev_para, *next_para; - struct tagME_DisplayItem *prev_marked, *next_marked; + struct wine_rb_entry marked_entry; } ME_Paragraph; typedef struct tagME_Cell /* v4.1 */ @@ -226,7 +225,7 @@ typedef struct tagME_Cell /* v4.1 */ POINT pt; int nHeight, nWidth; int yTextOffset; /* The text offset is caused by the largest top border. */ - struct tagME_DisplayItem *prev_cell, *next_cell, *parent_cell; + struct tagME_Cell *prev_cell, *next_cell, *parent_cell; } ME_Cell; typedef struct tagME_Row @@ -272,8 +271,8 @@ typedef struct tagME_TextBuffer typedef struct tagME_Cursor { - ME_DisplayItem *pPara; - ME_DisplayItem *pRun; + ME_Paragraph *para; + ME_Run *run; int nOffset; } ME_Cursor; @@ -379,14 +378,20 @@ typedef struct tagME_InStream ME_InStream; typedef struct tagME_TextEditor { +#ifdef __REACTOS__ HWND hWnd, hwndParent; - ITextHost *texthost; - IUnknown *reOle; - BOOL bEmulateVersion10; +#endif + ITextHost2 *texthost; + unsigned int bEmulateVersion10 : 1; + unsigned int in_place_active : 1; + unsigned int have_texthost2 : 1; ME_TextBuffer *pBuffer; ME_Cursor *pCursors; +#ifdef __REACTOS__ DWORD styleFlags; - DWORD exStyleFlags; +#endif + DWORD props; + DWORD scrollbars; int nCursors; SIZE sizeWindow; int nTotalLength, nLastTotalLength; @@ -394,9 +399,6 @@ typedef struct tagME_TextEditor int nAvailWidth; /* 0 = wrap to client area, else wrap width in twips */ int nUDArrowX; int total_rows; - COLORREF rgbBackColor; - HBRUSH hbrBackground; - BOOL bCaretAtEnd; int nEventMask; int nModifyStep; struct list undo_stack; @@ -406,15 +408,14 @@ typedef struct tagME_TextEditor ME_UndoMode nUndoMode; int nParagraphs; int nLastSelStart, nLastSelEnd; - ME_DisplayItem *pLastSelStartPara, *pLastSelEndPara; + ME_Paragraph *last_sel_start_para, *last_sel_end_para; ME_FontCacheItem pFontCache[HFONT_CACHE_SIZE]; int nZoomNumerator, nZoomDenominator; - RECT prevClientRect; RECT rcFormat; - BOOL bDefaultFormatRect; BOOL bWordWrap; int nTextLimit; EDITWORDBREAKPROCW pfnWordBreak; + IRichEditOle *richole; LPRICHEDITOLECALLBACK lpOleCallback; /*TEXTMODE variable; contains only one of each of the following options: *TM_RICHTEXT or TM_PLAINTEXT @@ -423,29 +424,31 @@ typedef struct tagME_TextEditor int mode; BOOL bHideSelection; BOOL AutoURLDetect_bEnable; - WCHAR cPasswordMask; + WCHAR password_char; BOOL bHaveFocus; - BOOL bDialogMode; /* Indicates that we are inside a dialog window */ #ifndef __REACTOS__ /*for IME */ int imeStartIndex; #endif DWORD selofs; /* The size of the selection bar on the left side of control */ ME_SelectionType nSelectionType; - ME_DisplayItem *first_marked_para; /* Track previous notified selection */ CHARRANGE notified_cr; /* Cache previously set scrollbar info */ SCROLLINFO vert_si, horz_si; + unsigned int vert_sb_enabled : 1; + unsigned int horz_sb_enabled : 1; int caret_height; BOOL caret_hidden; BOOL bMouseCaptured; int wheel_remain; + TXTBACKSTYLE back_style; struct list style_list; struct list reobj_list; + struct wine_rb_tree marked_paras; } ME_TextEditor; typedef struct tagME_Context @@ -462,4 +465,27 @@ typedef struct tagME_Context ME_TextEditor *editor; } ME_Context; +struct text_selection +{ + ITextSelection ITextSelection_iface; + LONG ref; + + struct text_services *services; +}; + +struct text_services +{ + IUnknown IUnknown_inner; + ITextServices ITextServices_iface; + IRichEditOle IRichEditOle_iface; + ITextDocument2Old ITextDocument2Old_iface; + IUnknown *outer_unk; + LONG ref; + ME_TextEditor *editor; + struct text_selection *text_selection; + struct list rangelist; + struct list clientsites; + char spare[256]; /* for bug #12179 */ +}; + #endif diff --git a/dll/win32/riched20/list.c b/dll/win32/riched20/list.c index 23d1a38991d6b..891a52e605f10 100644 --- a/dll/win32/riched20/list.c +++ b/dll/win32/riched20/list.c @@ -63,51 +63,6 @@ static BOOL ME_DITypesEqual(ME_DIType type, ME_DIType nTypeOrClass) } } -/* Modifies run pointer to point to the next run. - * If all_para is FALSE constrain the search to the current para, - * otherwise modify the paragraph pointer if moving into the next paragraph. - * - * Returns TRUE if next run is found, otherwise returns FALSE. */ -BOOL ME_NextRun(ME_DisplayItem **para, ME_DisplayItem **run, BOOL all_para) -{ - ME_DisplayItem *p = (*run)->next; - while (p->type != diTextEnd) - { - if (p->type == diParagraph) { - if (!all_para) return FALSE; - *para = p; - } else if (p->type == diRun) { - *run = p; - return TRUE; - } - p = p->next; - } - return FALSE; -} - -/* Modifies run pointer to point to the previous run. - * If all_para is FALSE constrain the search to the current para, - * otherwise modify the paragraph pointer if moving into the previous paragraph. - * - * Returns TRUE if previous run is found, otherwise returns FALSE. */ -BOOL ME_PrevRun(ME_DisplayItem **para, ME_DisplayItem **run, BOOL all_para) -{ - ME_DisplayItem *p = (*run)->prev; - while (p->type != diTextStart) - { - if (p->type == diParagraph) { - if (!all_para) return FALSE; - if (para && p->member.para.prev_para->type == diParagraph) - *para = p->member.para.prev_para; - } else if (p->type == diRun) { - *run = p; - return TRUE; - } - p = p->prev; - } - return FALSE; -} - ME_DisplayItem *ME_FindItemBack(ME_DisplayItem *di, ME_DIType nTypeOrClass) { if (!di) diff --git a/dll/win32/riched20/paint.c b/dll/win32/riched20/paint.c index 05be17e24c5ec..6ab7e4de76bf7 100644 --- a/dll/win32/riched20/paint.c +++ b/dll/win32/riched20/paint.c @@ -23,14 +23,30 @@ WINE_DEFAULT_DEBUG_CHANNEL(richedit); -static void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph); +static void draw_paragraph( ME_Context *c, ME_Paragraph *para ); -void ME_PaintContent(ME_TextEditor *editor, HDC hDC, const RECT *rcUpdate) +static inline BOOL editor_opaque( ME_TextEditor *editor ) { - ME_DisplayItem *item; + return editor->back_style != TXTBACK_TRANSPARENT; +} + +void editor_draw( ME_TextEditor *editor, HDC hDC, const RECT *update ) +{ + ME_Paragraph *para; ME_Context c; + ME_Cell *cell; int ys, ye; HRGN oldRgn; + RECT rc, client; + HBRUSH brush = CreateSolidBrush( ITextHost_TxGetSysColor( editor->texthost, COLOR_WINDOW ) ); + + ME_InitContext( &c, editor, hDC ); + if (!update) + { + client = c.rcView; + client.left -= editor->selofs; + update = &client; + } oldRgn = CreateRectRgn(0, 0, 0, 0); if (!GetClipRgn(hDC, oldRgn)) @@ -38,69 +54,66 @@ void ME_PaintContent(ME_TextEditor *editor, HDC hDC, const RECT *rcUpdate) DeleteObject(oldRgn); oldRgn = NULL; } - IntersectClipRect(hDC, rcUpdate->left, rcUpdate->top, - rcUpdate->right, rcUpdate->bottom); + IntersectClipRect( hDC, update->left, update->top, update->right, update->bottom ); - ME_InitContext(&c, editor, hDC); + brush = SelectObject( hDC, brush ); SetBkMode(hDC, TRANSPARENT); - item = editor->pBuffer->pFirst->next; + para = editor_first_para( editor ); /* This context point is an offset for the paragraph positions stored * during wrapping. It shouldn't be modified during painting. */ c.pt.x = c.rcView.left - editor->horz_si.nPos; c.pt.y = c.rcView.top - editor->vert_si.nPos; - while(item != editor->pBuffer->pLast) + while (para_next( para )) { - assert(item->type == diParagraph); - - ys = c.pt.y + item->member.para.pt.y; - if (item->member.para.pCell - != item->member.para.next_para->member.para.pCell) - { - ME_Cell *cell = NULL; - cell = &ME_FindItemBack(item->member.para.next_para, diCell)->member.cell; + ys = c.pt.y + para->pt.y; + cell = para_cell( para ); + if (cell && para == cell_end_para( cell )) ye = c.pt.y + cell->pt.y + cell->nHeight; - } else { - ye = ys + item->member.para.nHeight; - } - if (item->member.para.pCell && !(item->member.para.nFlags & MEPF_ROWEND) && - item->member.para.pCell != item->member.para.prev_para->member.para.pCell) + else ye = ys + para->nHeight; + + if (cell && !(para->nFlags & MEPF_ROWEND) && para == cell_first_para( cell )) { /* the border shifts the text down */ - ys -= item->member.para.pCell->member.cell.yTextOffset; + ys -= para_cell( para )->yTextOffset; } /* Draw the paragraph if any of the paragraph is in the update region. */ - if (ys < rcUpdate->bottom && ye > rcUpdate->top) - ME_DrawParagraph(&c, item); - item = item->member.para.next_para; + if (ys < update->bottom && ye > update->top) + draw_paragraph( &c, para ); + para = para_next( para ); } - if (c.pt.y + editor->nTotalLength < c.rcView.bottom) + if (editor_opaque( editor )) { - /* Fill space after the end of the text. */ - RECT rc; - rc.top = c.pt.y + editor->nTotalLength; - rc.left = c.rcView.left; - rc.bottom = c.rcView.bottom; - rc.right = c.rcView.right; + if (c.pt.y + editor->nTotalLength < c.rcView.bottom) + { /* space after the end of the text */ + rc.top = c.pt.y + editor->nTotalLength; + rc.left = c.rcView.left; + rc.bottom = c.rcView.bottom; + rc.right = c.rcView.right; + if (IntersectRect( &rc, &rc, update )) + PatBlt(hDC, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY); + } + if (editor->selofs) + { /* selection bar */ + rc.left = c.rcView.left - editor->selofs; + rc.top = c.rcView.top; + rc.right = c.rcView.left; + rc.bottom = c.rcView.bottom; + if (IntersectRect( &rc, &rc, update )) + PatBlt( hDC, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY ); + } + } - IntersectRect(&rc, &rc, rcUpdate); + DeleteObject( SelectObject( hDC, brush ) ); + SelectClipRgn( hDC, oldRgn ); + if (oldRgn) DeleteObject( oldRgn ); + ME_DestroyContext( &c ); - if (!IsRectEmpty(&rc)) - PatBlt(hDC, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY); - } - if (editor->nTotalLength != editor->nLastTotalLength || - editor->nTotalWidth != editor->nLastTotalWidth) + if (editor->nTotalLength != editor->nLastTotalLength || editor->nTotalWidth != editor->nLastTotalWidth) ME_SendRequestResize(editor, FALSE); editor->nLastTotalLength = editor->nTotalLength; editor->nLastTotalWidth = editor->nTotalWidth; - - SelectClipRgn(hDC, oldRgn); - if (oldRgn) - DeleteObject(oldRgn); - - c.hDC = NULL; - ME_DestroyContext(&c); } void ME_Repaint(ME_TextEditor *editor) @@ -123,17 +136,18 @@ void ME_UpdateRepaint(ME_TextEditor *editor, BOOL update_now) ME_UpdateScrollBar(editor); /* Ensure that the cursor is visible */ - ME_EnsureVisible(editor, &editor->pCursors[0]); + editor_ensure_visible( editor, &editor->pCursors[0] ); + + update_caret( editor ); ITextHost_TxViewChange(editor->texthost, update_now); ME_SendSelChange(editor); - /* send EN_CHANGE if the event mask asks for it */ if(editor->nEventMask & ENM_CHANGE) { editor->nEventMask &= ~ENM_CHANGE; - ME_SendOldNotify(editor, EN_CHANGE); + ITextHost_TxNotify( editor->texthost, EN_CHANGE, NULL ); editor->nEventMask |= ENM_CHANGE; } } @@ -144,7 +158,7 @@ ME_RewrapRepaint(ME_TextEditor *editor) /* RewrapRepaint should be called whenever the control has changed in * looks, but not content. Like resizing. */ - ME_MarkAllForWrapping(editor); + editor_mark_rewrap_all( editor ); ME_WrapMarkedParagraphs(editor); ME_UpdateScrollBar(editor); ME_Repaint(editor); @@ -276,8 +290,8 @@ static void draw_space( ME_Context *c, ME_Run *run, int x, int y, SetRect( &rect, x, ymin, x + run->nWidth, ymin + cy ); - if (c->editor->bHideSelection || (!c->editor->bHaveFocus && - !(c->editor->styleFlags & ES_NOHIDESEL))) selected = FALSE; + if (c->editor->bHideSelection || (!c->editor->bHaveFocus && (c->editor->props & TXTBIT_HIDESELECTION))) + selected = FALSE; if (c->editor->bEmulateVersion10) { old_style_selected = selected; @@ -339,9 +353,9 @@ static void draw_text( ME_Context *c, ME_Run *run, int x, int y, BOOL selected, && !(CFE_AUTOBACKCOLOR & run->style->fmt.dwEffects) ) ); - if (c->editor->cPasswordMask) + if (c->editor->password_char) { - masked = ME_MakeStringR( c->editor->cPasswordMask, run->len ); + masked = ME_MakeStringR( c->editor->password_char, run->len ); text = masked->szData; } @@ -365,14 +379,14 @@ static void draw_text( ME_Context *c, ME_Run *run, int x, int y, BOOL selected, } -static void ME_DrawTextWithStyle(ME_Context *c, ME_Run *run, int x, int y, - int nSelFrom, int nSelTo, int ymin, int cy) +static void draw_text_with_style( ME_Context *c, ME_Run *run, int x, int y, + int nSelFrom, int nSelTo, int ymin, int cy ) { HDC hDC = c->hDC; int yOffset = 0; BOOL selected = (nSelFrom < run->len && nSelTo >= 0 && nSelFrom < nSelTo && !c->editor->bHideSelection && - (c->editor->bHaveFocus || (c->editor->styleFlags & ES_NOHIDESEL))); + (c->editor->bHaveFocus || !(c->editor->props & TXTBIT_HIDESELECTION))); BOOL old_style_selected = FALSE; RECT sel_rect; HRGN clip = NULL, sel_rgn = NULL; @@ -440,17 +454,16 @@ static void ME_DebugWrite(HDC hDC, const POINT *pt, LPCWSTR szText) { SetTextColor(hDC, color); } -static void ME_DrawRun(ME_Context *c, int x, int y, ME_DisplayItem *rundi, ME_Paragraph *para) +static void draw_run( ME_Context *c, int x, int y, ME_Cursor *cursor ) { - ME_Run *run = &rundi->member.run; - ME_DisplayItem *start; - int runofs = run->nCharOfs+para->nCharOfs; + ME_Row *row; + ME_Run *run = cursor->run; + int runofs = run_char_ofs( run, cursor->nOffset ); int nSelFrom, nSelTo; - - if (run->nFlags & MERF_HIDDEN) - return; - start = ME_FindItemBack(rundi, diStartRow); + if (run->nFlags & MERF_HIDDEN) return; + + row = row_from_cursor( cursor ); ME_GetSelectionOfs(c->editor, &nSelFrom, &nSelTo); /* Draw selected end-of-paragraph mark */ @@ -459,8 +472,7 @@ static void ME_DrawRun(ME_Context *c, int x, int y, ME_DisplayItem *rundi, ME_Pa if (runofs >= nSelFrom && runofs < nSelTo) { draw_space( c, run, x, y, TRUE, FALSE, - c->pt.y + para->pt.y + start->member.row.pt.y, - start->member.row.nHeight ); + c->pt.y + run->para->pt.y + row->pt.y, row->nHeight ); } return; } @@ -470,19 +482,15 @@ static void ME_DrawRun(ME_Context *c, int x, int y, ME_DisplayItem *rundi, ME_Pa BOOL selected = runofs >= nSelFrom && runofs < nSelTo; draw_space( c, run, x, y, selected, TRUE, - c->pt.y + para->pt.y + start->member.row.pt.y, - start->member.row.nHeight ); + c->pt.y + run->para->pt.y + row->pt.y, row->nHeight ); return; } if (run->nFlags & MERF_GRAPHICS) - ME_DrawOLE(c, x, y, run, (runofs >= nSelFrom) && (runofs < nSelTo)); + draw_ole( c, x, y, run, (runofs >= nSelFrom) && (runofs < nSelTo) ); else - { - ME_DrawTextWithStyle(c, run, x, y, nSelFrom - runofs, nSelTo - runofs, - c->pt.y + para->pt.y + start->member.row.pt.y, - start->member.row.nHeight); - } + draw_text_with_style( c, run, x, y, nSelFrom - runofs, nSelTo - runofs, + c->pt.y + run->para->pt.y + row->pt.y, row->nHeight ); } /* The documented widths are in points (72 dpi), but converting them to @@ -593,22 +601,28 @@ static void ME_DrawParaDecoration(ME_Context* c, ME_Paragraph* para, int y, RECT if (para->fmt.dwMask & PFM_SPACEBEFORE) { - rc.left = c->rcView.left; - rc.right = c->rcView.right; - rc.top = y; bounds->top = ME_twips2pointsY(c, para->fmt.dySpaceBefore); - rc.bottom = y + bounds->top + top_border; - PatBlt(c->hDC, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY); + if (editor_opaque( c->editor )) + { + rc.left = c->rcView.left; + rc.right = c->rcView.right; + rc.top = y; + rc.bottom = y + bounds->top + top_border; + PatBlt(c->hDC, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY); + } } if (para->fmt.dwMask & PFM_SPACEAFTER) { - rc.left = c->rcView.left; - rc.right = c->rcView.right; - rc.bottom = y + para->nHeight; bounds->bottom = ME_twips2pointsY(c, para->fmt.dySpaceAfter); - rc.top = rc.bottom - bounds->bottom - bottom_border; - PatBlt(c->hDC, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY); + if (editor_opaque( c->editor )) + { + rc.left = c->rcView.left; + rc.right = c->rcView.right; + rc.bottom = y + para->nHeight; + rc.top = rc.bottom - bounds->bottom - bottom_border; + PatBlt(c->hDC, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY); + } } /* Native richedit doesn't support paragraph borders in v1.0 - 4.1, @@ -696,51 +710,54 @@ static void ME_DrawParaDecoration(ME_Context* c, ME_Paragraph* para, int y, RECT } } -static void ME_DrawTableBorders(ME_Context *c, ME_DisplayItem *paragraph) +static void draw_table_borders( ME_Context *c, ME_Paragraph *para ) { - ME_Paragraph *para = ¶graph->member.para; if (!c->editor->bEmulateVersion10) /* v4.1 */ { - if (para->pCell) + if (para_cell( para )) { RECT rc; - ME_Cell *cell = ¶->pCell->member.cell; - ME_DisplayItem *paraAfterRow; + ME_Cell *cell = para_cell( para ); + ME_Paragraph *after_row; HPEN pen, oldPen; LOGBRUSH logBrush; HBRUSH brush; COLORREF color; POINT oldPt; int width; - BOOL atTop = (para->pCell != para->prev_para->member.para.pCell); - BOOL atBottom = (para->pCell != para->next_para->member.para.pCell); + BOOL atTop = (para == cell_first_para( cell )); + BOOL atBottom = (para == cell_end_para( cell )); int top = c->pt.y + (atTop ? cell->pt.y : para->pt.y); int bottom = (atBottom ? c->pt.y + cell->pt.y + cell->nHeight : top + para->nHeight + (atTop ? cell->yTextOffset : 0)); rc.left = c->pt.x + cell->pt.x; rc.right = rc.left + cell->nWidth; - if (atTop) { + if (atTop) + { /* Erase gap before text if not all borders are the same height. */ width = max(ME_twips2pointsY(c, cell->border.top.width), 1); rc.top = top + width; width = cell->yTextOffset - width; rc.bottom = rc.top + width; - if (width) + if (width && editor_opaque( c->editor )) PatBlt(c->hDC, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY); } /* Draw cell borders. * The order borders are draw in is left, top, bottom, right in order * to be consistent with native richedit. This is noticeable from the * overlap of borders of different colours. */ - if (!(para->nFlags & MEPF_ROWEND)) { + if (!(para->nFlags & MEPF_ROWEND)) + { rc.top = top; rc.bottom = bottom; if (cell->border.left.width > 0) { color = cell->border.left.colorRef; width = max(ME_twips2pointsX(c, cell->border.left.width), 1); - } else { + } + else + { color = RGB(192,192,192); width = 1; } @@ -757,12 +774,15 @@ static void ME_DrawTableBorders(ME_Context *c, ME_DisplayItem *paragraph) MoveToEx(c->hDC, oldPt.x, oldPt.y, NULL); } - if (atTop) { + if (atTop) + { if (cell->border.top.width > 0) { brush = CreateSolidBrush(cell->border.top.colorRef); width = max(ME_twips2pointsY(c, cell->border.top.width), 1); - } else { + } + else + { brush = GetStockObject(LTGRAY_BRUSH); width = 1; } @@ -775,29 +795,24 @@ static void ME_DrawTableBorders(ME_Context *c, ME_DisplayItem *paragraph) /* Draw the bottom border if at the last paragraph in the cell, and when * in the last row of the table. */ - if (atBottom) { + if (atBottom) + { int oldLeft = rc.left; width = max(ME_twips2pointsY(c, cell->border.bottom.width), 1); - paraAfterRow = ME_GetTableRowEnd(paragraph)->member.para.next_para; - if (paraAfterRow->member.para.nFlags & MEPF_ROWSTART) { - ME_DisplayItem *nextEndCell; - nextEndCell = ME_FindItemBack(ME_GetTableRowEnd(paraAfterRow), diCell); - assert(nextEndCell && !nextEndCell->member.cell.next_cell); - rc.left = c->pt.x + nextEndCell->member.cell.pt.x; - /* FIXME: Native draws FROM the bottom of the table rather than - * TO the bottom of the table in this case, but just doing so here - * will cause the next row to erase the border. */ - /* - rc.top = bottom; - rc.bottom = rc.top + width; - */ + after_row = para_next( table_row_end( para ) ); + if (after_row->nFlags & MEPF_ROWSTART) + { + ME_Cell *next_end; + next_end = table_row_end_cell( after_row ); + assert( next_end && !cell_next( next_end ) ); + rc.left = c->pt.x + next_end->pt.x; } - if (rc.left < rc.right) { - if (cell->border.bottom.width > 0) { + if (rc.left < rc.right) + { + if (cell->border.bottom.width > 0) brush = CreateSolidBrush(cell->border.bottom.colorRef); - } else { + else brush = GetStockObject(LTGRAY_BRUSH); - } rc.bottom = bottom; rc.top = rc.bottom - width; FillRect(c->hDC, &rc, brush); @@ -808,15 +823,17 @@ static void ME_DrawTableBorders(ME_Context *c, ME_DisplayItem *paragraph) } /* Right border only drawn if at the end of the table row. */ - if (!cell->next_cell->member.cell.next_cell && - !(para->nFlags & MEPF_ROWSTART)) + if (!cell_next( cell_next( cell ) ) && !(para->nFlags & MEPF_ROWSTART)) { rc.top = top; rc.bottom = bottom; - if (cell->border.right.width > 0) { + if (cell->border.right.width > 0) + { color = cell->border.right.colorRef; width = max(ME_twips2pointsX(c, cell->border.right.width), 1); - } else { + } + else + { color = RGB(192,192,192); width = 1; } @@ -833,19 +850,21 @@ static void ME_DrawTableBorders(ME_Context *c, ME_DisplayItem *paragraph) MoveToEx(c->hDC, oldPt.x, oldPt.y, NULL); } } - } else { /* v1.0 - 3.0 */ + } + else /* v1.0 - 3.0 */ + { /* Draw simple table border */ - if (para->fmt.dwMask & PFM_TABLE && para->fmt.wEffects & PFE_TABLE) { + if (para_in_table( para )) + { HPEN pen = NULL, oldpen = NULL; int i, firstX, startX, endX, rowY, rowBottom, nHeight; POINT oldPt; - PARAFORMAT2 *pNextFmt; pen = CreatePen(PS_SOLID, 0, para->border.top.colorRef); oldpen = SelectObject(c->hDC, pen); /* Find the start relative to the text */ - firstX = c->pt.x + ME_FindItemFwd(paragraph, diRun)->member.run.pt.x; + firstX = c->pt.x + para_first_run( para )->pt.x; /* Go back by the horizontal gap, which is stored in dxOffset */ firstX -= ME_twips2pointsX(c, para->fmt.dxOffset); /* The left edge, stored in dxStartIndent affected just the first edge */ @@ -853,7 +872,7 @@ static void ME_DrawTableBorders(ME_Context *c, ME_DisplayItem *paragraph) rowY = c->pt.y + para->pt.y; if (para->fmt.dwMask & PFM_SPACEBEFORE) rowY += ME_twips2pointsY(c, para->fmt.dySpaceBefore); - nHeight = ME_FindItemFwd(paragraph, diStartRow)->member.row.nHeight; + nHeight = para_first_row( para )->nHeight; rowBottom = rowY + nHeight; /* Draw horizontal lines */ @@ -861,11 +880,9 @@ static void ME_DrawTableBorders(ME_Context *c, ME_DisplayItem *paragraph) i = para->fmt.cTabCount - 1; endX = startX + ME_twips2pointsX(c, para->fmt.rgxTabs[i] & 0x00ffffff) + 1; LineTo(c->hDC, endX, rowY); - pNextFmt = ¶->next_para->member.para.fmt; /* The bottom of the row only needs to be drawn if the next row is * not a table. */ - if (!(pNextFmt && pNextFmt->dwMask & PFM_TABLE && pNextFmt->wEffects && - para->nRows == 1)) + if (!(para_next( para ) && para_in_table( para_next( para ) ) && para->nRows == 1)) { /* Decrement rowBottom to draw the bottom line within the row, and * to not draw over this line when drawing the vertical lines. */ @@ -892,9 +909,8 @@ static void ME_DrawTableBorders(ME_Context *c, ME_DisplayItem *paragraph) } } -static void draw_para_number( ME_Context *c, ME_DisplayItem *p ) +static void draw_para_number( ME_Context *c, ME_Paragraph *para ) { - ME_Paragraph *para = &p->member.para; int x, y; COLORREF old_text; @@ -912,12 +928,12 @@ static void draw_para_number( ME_Context *c, ME_DisplayItem *p ) } } -static void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph) +static void draw_paragraph( ME_Context *c, ME_Paragraph *para ) { int align = SetTextAlign(c->hDC, TA_BASELINE); ME_DisplayItem *p; + ME_Cell *cell; ME_Run *run; - ME_Paragraph *para = NULL; RECT rc, bounds; int y; int height = 0, baseline = 0, no=0; @@ -926,32 +942,33 @@ static void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph) rc.left = c->pt.x; rc.right = c->rcView.right; - assert(paragraph); - para = ¶graph->member.para; y = c->pt.y + para->pt.y; - if (para->pCell) + if ((cell = para_cell( para ))) { - ME_Cell *cell = ¶->pCell->member.cell; rc.left = c->pt.x + cell->pt.x; rc.right = rc.left + cell->nWidth; } - if (para->nFlags & MEPF_ROWSTART) { - ME_Cell *cell = ¶->next_para->member.para.pCell->member.cell; + if (para->nFlags & MEPF_ROWSTART) + { + cell = table_row_first_cell( para ); rc.right = c->pt.x + cell->pt.x; - } else if (para->nFlags & MEPF_ROWEND) { - ME_Cell *cell = ¶->prev_para->member.para.pCell->member.cell; + } + else if (para->nFlags & MEPF_ROWEND) + { + cell = table_row_end_cell( para ); rc.left = c->pt.x + cell->pt.x + cell->nWidth; } ME_DrawParaDecoration(c, para, y, &bounds); y += bounds.top; - if (bounds.left || bounds.right) { + if (bounds.left || bounds.right) + { rc.left = max(rc.left, c->pt.x + bounds.left); rc.right = min(rc.right, c->pt.x - bounds.right + max(c->editor->sizeWindow.cx, c->editor->nTotalWidth)); } - for (p = paragraph->next; p != para->next_para; p = p->next) + for (p = para_get_di( para )->next; p != para_get_di( para_next( para ) ); p = p->next) { switch(p->type) { case diParagraph: @@ -966,7 +983,7 @@ static void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph) rc.bottom = y + p->member.row.nHeight; } visible = RectVisible(c->hDC, &rc); - if (visible) + if (editor_opaque( c->editor ) && visible) PatBlt(c->hDC, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY); if (bounds.right) { @@ -975,16 +992,15 @@ static void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph) RECT after_bdr = rc; after_bdr.left = rc.right + bounds.right; after_bdr.right = c->rcView.right; - if (RectVisible(c->hDC, &after_bdr)) + if (editor_opaque( c->editor ) && RectVisible( c->hDC, &after_bdr )) PatBlt(c->hDC, after_bdr.left, after_bdr.top, after_bdr.right - after_bdr.left, after_bdr.bottom - after_bdr.top, PATCOPY); } if (me_debug) { - static const WCHAR wszRowDebug[] = {'r','o','w','[','%','d',']',0}; WCHAR buf[128]; POINT pt = c->pt; - wsprintfW(buf, wszRowDebug, no); + wsprintfW( buf, L"row[%d]", no ); pt.y = 12+y; ME_DebugWrite(c->hDC, &pt, buf); } @@ -1005,44 +1021,71 @@ static void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph) FrameRect(c->hDC, &rc, GetSysColorBrush(COLOR_GRAYTEXT)); } if (visible) - ME_DrawRun(c, c->pt.x + run->pt.x, - c->pt.y + para->pt.y + run->pt.y + baseline, p, para); + { + ME_Cursor cursor; + + cursor.run = run; + cursor.para = para; + cursor.nOffset = 0; + draw_run( c, c->pt.x + run->pt.x, c->pt.y + para->pt.y + run->pt.y + baseline, &cursor ); + } if (me_debug) { - static const WCHAR wszRunDebug[] = {'[','%','d',':','%','x',']',' ','%','l','s',0}; WCHAR buf[2560]; POINT pt; pt.x = c->pt.x + run->pt.x; pt.y = c->pt.y + para->pt.y + run->pt.y; - wsprintfW(buf, wszRunDebug, no, p->member.run.nFlags, get_text( &p->member.run, 0 )); + wsprintfW( buf, L"[%d:%x] %ls", no, p->member.run.nFlags, get_text( &p->member.run, 0 )); ME_DebugWrite(c->hDC, &pt, buf); } break; - case diCell: - /* Clear any space at the bottom of the cell after the text. */ - if (para->nFlags & (MEPF_ROWSTART|MEPF_ROWEND)) - break; - y += height; - rc.top = c->pt.y + para->pt.y + para->nHeight; - rc.bottom = c->pt.y + p->member.cell.pt.y + p->member.cell.nHeight; - if (RectVisible(c->hDC, &rc)) - PatBlt(c->hDC, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY); - break; default: break; } no++; } - ME_DrawTableBorders(c, paragraph); - draw_para_number(c, paragraph); + if (editor_opaque( c->editor ) && para_cell( para )) + { + /* Clear any space at the bottom of the cell after the text. */ + rc.top = c->pt.y + para->pt.y + para->nHeight; + rc.bottom = c->pt.y + cell->pt.y + cell->nHeight; + PatBlt( c->hDC, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY ); + } + + draw_table_borders( c, para ); + draw_para_number( c, para ); + + SetTextAlign( c->hDC, align ); +} + +static void enable_show_scrollbar( ME_TextEditor *editor, INT bar, BOOL enable ) +{ + if (enable || editor->scrollbars & ES_DISABLENOSCROLL) + ITextHost_TxEnableScrollBar( editor->texthost, bar, enable ? 0 : ESB_DISABLE_BOTH ); + if (!(editor->scrollbars & ES_DISABLENOSCROLL)) + ITextHost_TxShowScrollBar( editor->texthost, bar, enable ); +} - SetTextAlign(c->hDC, align); +static void set_scroll_range_pos( ME_TextEditor *editor, INT bar, SCROLLINFO *info, BOOL set_range, BOOL notify ) +{ + LONG max_pos = info->nMax, pos = info->nPos; + + /* Scale the scrollbar info to 16-bit values. */ + if (max_pos > 0xffff) + { + pos = MulDiv( pos, 0xffff, max_pos ); + max_pos = 0xffff; + } + if (set_range) ITextHost_TxSetScrollRange( editor->texthost, bar, 0, max_pos, FALSE ); + ITextHost_TxSetScrollPos( editor->texthost, bar, pos, TRUE ); + + if (notify && editor->nEventMask & ENM_SCROLL) + ITextHost_TxNotify( editor->texthost, bar == SB_VERT ? EN_VSCROLL : EN_HSCROLL, NULL ); } -void ME_ScrollAbs(ME_TextEditor *editor, int x, int y) +void scroll_abs( ME_TextEditor *editor, int x, int y, BOOL notify ) { - BOOL bScrollBarIsVisible, bScrollBarWillBeVisible; int scrollX = 0, scrollY = 0; if (editor->horz_si.nPos != x) { @@ -1050,9 +1093,7 @@ void ME_ScrollAbs(ME_TextEditor *editor, int x, int y) x = max(x, editor->horz_si.nMin); scrollX = editor->horz_si.nPos - x; editor->horz_si.nPos = x; - if (editor->horz_si.nMax > 0xFFFF) /* scale to 16-bit value */ - x = MulDiv(x, 0xFFFF, editor->horz_si.nMax); - ITextHost_TxSetScrollPos(editor->texthost, SB_HORZ, x, TRUE); + set_scroll_range_pos( editor, SB_HORZ, &editor->horz_si, FALSE, notify ); } if (editor->vert_si.nPos != y) { @@ -1060,269 +1101,153 @@ void ME_ScrollAbs(ME_TextEditor *editor, int x, int y) y = max(y, editor->vert_si.nMin); scrollY = editor->vert_si.nPos - y; editor->vert_si.nPos = y; - if (editor->vert_si.nMax > 0xFFFF) /* scale to 16-bit value */ - y = MulDiv(y, 0xFFFF, editor->vert_si.nMax); - ITextHost_TxSetScrollPos(editor->texthost, SB_VERT, y, TRUE); + set_scroll_range_pos( editor, SB_VERT, &editor->vert_si, FALSE, notify ); } - if (abs(scrollX) > editor->sizeWindow.cx || - abs(scrollY) > editor->sizeWindow.cy) + if (abs(scrollX) > editor->sizeWindow.cx || abs(scrollY) > editor->sizeWindow.cy) ITextHost_TxInvalidateRect(editor->texthost, NULL, TRUE); else ITextHost_TxScrollWindowEx(editor->texthost, scrollX, scrollY, &editor->rcFormat, &editor->rcFormat, NULL, NULL, SW_INVALIDATE); - ME_Repaint(editor); - - if (editor->hWnd) - { - LONG winStyle = GetWindowLongW(editor->hWnd, GWL_STYLE); - if (editor->styleFlags & WS_HSCROLL) - { - bScrollBarIsVisible = (winStyle & WS_HSCROLL) != 0; - bScrollBarWillBeVisible = (editor->nTotalWidth > editor->sizeWindow.cx - && (editor->styleFlags & WS_HSCROLL)) - || (editor->styleFlags & ES_DISABLENOSCROLL); - if (bScrollBarIsVisible != bScrollBarWillBeVisible) - ITextHost_TxShowScrollBar(editor->texthost, SB_HORZ, - bScrollBarWillBeVisible); - } - - if (editor->styleFlags & WS_VSCROLL) - { - bScrollBarIsVisible = (winStyle & WS_VSCROLL) != 0; - bScrollBarWillBeVisible = (editor->nTotalLength > editor->sizeWindow.cy - && (editor->styleFlags & WS_VSCROLL) - && (editor->styleFlags & ES_MULTILINE)) - || (editor->styleFlags & ES_DISABLENOSCROLL); - if (bScrollBarIsVisible != bScrollBarWillBeVisible) - ITextHost_TxShowScrollBar(editor->texthost, SB_VERT, - bScrollBarWillBeVisible); - } - } ME_UpdateScrollBar(editor); + ME_Repaint(editor); } -void ME_HScrollAbs(ME_TextEditor *editor, int x) +void scroll_h_abs( ME_TextEditor *editor, int x, BOOL notify ) { - ME_ScrollAbs(editor, x, editor->vert_si.nPos); + scroll_abs( editor, x, editor->vert_si.nPos, notify ); } -void ME_VScrollAbs(ME_TextEditor *editor, int y) +void scroll_v_abs( ME_TextEditor *editor, int y, BOOL notify ) { - ME_ScrollAbs(editor, editor->horz_si.nPos, y); + scroll_abs( editor, editor->horz_si.nPos, y, notify ); } void ME_ScrollUp(ME_TextEditor *editor, int cy) { - ME_VScrollAbs(editor, editor->vert_si.nPos - cy); + scroll_v_abs( editor, editor->vert_si.nPos - cy, TRUE ); } void ME_ScrollDown(ME_TextEditor *editor, int cy) { - ME_VScrollAbs(editor, editor->vert_si.nPos + cy); + scroll_v_abs( editor, editor->vert_si.nPos + cy, TRUE ); } void ME_ScrollLeft(ME_TextEditor *editor, int cx) { - ME_HScrollAbs(editor, editor->horz_si.nPos - cx); + scroll_h_abs( editor, editor->horz_si.nPos - cx, TRUE ); } void ME_ScrollRight(ME_TextEditor *editor, int cx) { - ME_HScrollAbs(editor, editor->horz_si.nPos + cx); -} - -/* Calculates the visibility after a call to SetScrollRange or - * SetScrollInfo with SIF_RANGE. */ -static BOOL ME_PostSetScrollRangeVisibility(SCROLLINFO *si) -{ - if (si->fMask & SIF_DISABLENOSCROLL) - return TRUE; - - /* This must match the check in SetScrollInfo to determine whether - * to show or hide the scrollbars. */ - return si->nMin < si->nMax - max(si->nPage - 1, 0); + scroll_h_abs( editor, editor->horz_si.nPos + cx, TRUE ); } void ME_UpdateScrollBar(ME_TextEditor *editor) { /* Note that this is the only function that should ever call * SetScrollInfo with SIF_PAGE or SIF_RANGE. */ - - SCROLLINFO si; - BOOL bScrollBarWasVisible, bScrollBarWillBeVisible; + BOOL enable; if (ME_WrapMarkedParagraphs(editor)) FIXME("ME_UpdateScrollBar had to call ME_WrapMarkedParagraphs\n"); - si.cbSize = sizeof(si); - si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS; - si.nMin = 0; - if (editor->styleFlags & ES_DISABLENOSCROLL) - si.fMask |= SIF_DISABLENOSCROLL; - /* Update horizontal scrollbar */ - bScrollBarWasVisible = editor->horz_si.nMax > editor->horz_si.nPage; - bScrollBarWillBeVisible = editor->nTotalWidth > editor->sizeWindow.cx; - if (editor->horz_si.nPos && !bScrollBarWillBeVisible) + enable = editor->nTotalWidth > editor->sizeWindow.cx; + if (editor->horz_si.nPos && !enable) { - ME_HScrollAbs(editor, 0); - /* ME_HScrollAbs will call this function, - * so nothing else needs to be done here. */ + scroll_h_abs( editor, 0, TRUE ); + /* ME_HScrollAbs will call this function, so nothing else needs to be done here. */ return; } - si.nMax = editor->nTotalWidth; - si.nPos = editor->horz_si.nPos; - si.nPage = editor->sizeWindow.cx; - - if (si.nMax != editor->horz_si.nMax || - si.nPage != editor->horz_si.nPage) + if (editor->scrollbars & WS_HSCROLL && !enable ^ !editor->horz_sb_enabled) { - TRACE("min=%d max=%d page=%d\n", si.nMin, si.nMax, si.nPage); - editor->horz_si.nMax = si.nMax; - editor->horz_si.nPage = si.nPage; - if ((bScrollBarWillBeVisible || bScrollBarWasVisible) && - editor->styleFlags & WS_HSCROLL) - { - if (si.nMax > 0xFFFF) - { - /* Native scales the scrollbar info to 16-bit external values. */ - si.nPos = MulDiv(si.nPos, 0xFFFF, si.nMax); - si.nMax = 0xFFFF; - } - if (editor->hWnd) { - SetScrollInfo(editor->hWnd, SB_HORZ, &si, TRUE); - } else { - ITextHost_TxSetScrollRange(editor->texthost, SB_HORZ, si.nMin, si.nMax, FALSE); - ITextHost_TxSetScrollPos(editor->texthost, SB_HORZ, si.nPos, TRUE); - } - /* SetScrollInfo or SetScrollRange change scrollbar visibility. */ - bScrollBarWasVisible = ME_PostSetScrollRangeVisibility(&si); - } + editor->horz_sb_enabled = enable; + enable_show_scrollbar( editor, SB_HORZ, enable ); } - if (editor->styleFlags & WS_HSCROLL) + if (editor->horz_si.nMax != editor->nTotalWidth || editor->horz_si.nPage != editor->sizeWindow.cx) { - if (si.fMask & SIF_DISABLENOSCROLL) { - bScrollBarWillBeVisible = TRUE; - } else if (!(editor->styleFlags & WS_HSCROLL)) { - bScrollBarWillBeVisible = FALSE; - } - - if (bScrollBarWasVisible != bScrollBarWillBeVisible) - ITextHost_TxShowScrollBar(editor->texthost, SB_HORZ, bScrollBarWillBeVisible); + editor->horz_si.nMax = editor->nTotalWidth; + editor->horz_si.nPage = editor->sizeWindow.cx; + TRACE( "min = %d max = %d page = %d\n", editor->horz_si.nMin, editor->horz_si.nMax, editor->horz_si.nPage ); + if ((enable || editor->horz_sb_enabled) && editor->scrollbars & WS_HSCROLL) + set_scroll_range_pos( editor, SB_HORZ, &editor->horz_si, TRUE, TRUE ); } /* Update vertical scrollbar */ - bScrollBarWasVisible = editor->vert_si.nMax > editor->vert_si.nPage; - bScrollBarWillBeVisible = editor->nTotalLength > editor->sizeWindow.cy && - (editor->styleFlags & ES_MULTILINE); + enable = editor->nTotalLength > editor->sizeWindow.cy && (editor->props & TXTBIT_MULTILINE); - if (editor->vert_si.nPos && !bScrollBarWillBeVisible) + if (editor->vert_si.nPos && !enable) { - ME_VScrollAbs(editor, 0); - /* ME_VScrollAbs will call this function, - * so nothing else needs to be done here. */ + scroll_v_abs( editor, 0, TRUE ); + /* ME_VScrollAbs will call this function, so nothing else needs to be done here. */ return; } - si.nMax = editor->nTotalLength; - si.nPos = editor->vert_si.nPos; - si.nPage = editor->sizeWindow.cy; - - if (si.nMax != editor->vert_si.nMax || - si.nPage != editor->vert_si.nPage) + if (editor->scrollbars & WS_VSCROLL && !enable ^ !editor->vert_sb_enabled) { - TRACE("min=%d max=%d page=%d\n", si.nMin, si.nMax, si.nPage); - editor->vert_si.nMax = si.nMax; - editor->vert_si.nPage = si.nPage; - if ((bScrollBarWillBeVisible || bScrollBarWasVisible) && - editor->styleFlags & WS_VSCROLL) - { - if (si.nMax > 0xFFFF) - { - /* Native scales the scrollbar info to 16-bit external values. */ - si.nPos = MulDiv(si.nPos, 0xFFFF, si.nMax); - si.nMax = 0xFFFF; - } - if (editor->hWnd) { - SetScrollInfo(editor->hWnd, SB_VERT, &si, TRUE); - } else { - ITextHost_TxSetScrollRange(editor->texthost, SB_VERT, si.nMin, si.nMax, FALSE); - ITextHost_TxSetScrollPos(editor->texthost, SB_VERT, si.nPos, TRUE); - } - /* SetScrollInfo or SetScrollRange change scrollbar visibility. */ - bScrollBarWasVisible = ME_PostSetScrollRangeVisibility(&si); - } + editor->vert_sb_enabled = enable; + enable_show_scrollbar( editor, SB_VERT, enable ); } - if (editor->styleFlags & WS_VSCROLL) + if (editor->vert_si.nMax != editor->nTotalLength || editor->vert_si.nPage != editor->sizeWindow.cy) { - if (si.fMask & SIF_DISABLENOSCROLL) { - bScrollBarWillBeVisible = TRUE; - } else if (!(editor->styleFlags & WS_VSCROLL)) { - bScrollBarWillBeVisible = FALSE; - } - - if (bScrollBarWasVisible != bScrollBarWillBeVisible) - ITextHost_TxShowScrollBar(editor->texthost, SB_VERT, - bScrollBarWillBeVisible); + editor->vert_si.nMax = editor->nTotalLength; + editor->vert_si.nPage = editor->sizeWindow.cy; + TRACE( "min = %d max = %d page = %d\n", editor->vert_si.nMin, editor->vert_si.nMax, editor->vert_si.nPage ); + if ((enable || editor->vert_sb_enabled) && editor->scrollbars & WS_VSCROLL) + set_scroll_range_pos( editor, SB_VERT, &editor->vert_si, TRUE, TRUE ); } } -void ME_EnsureVisible(ME_TextEditor *editor, ME_Cursor *pCursor) +void editor_ensure_visible( ME_TextEditor *editor, ME_Cursor *cursor ) { - ME_Run *pRun = &pCursor->pRun->member.run; - ME_DisplayItem *pRow = ME_FindItemBack(pCursor->pRun, diStartRow); - ME_DisplayItem *pPara = pCursor->pPara; + ME_Run *run = cursor->run; + ME_Row *row = row_from_cursor( cursor ); + ME_Paragraph *para = cursor->para; int x, y, yheight; -#ifdef __REACTOS__ - if (!pRow || !pPara) - return; -#else - assert(pRow); - assert(pPara); -#endif - if (editor->styleFlags & ES_AUTOHSCROLL) + if (editor->scrollbars & ES_AUTOHSCROLL) { - x = pRun->pt.x + ME_PointFromChar(editor, pRun, pCursor->nOffset, TRUE); + x = run->pt.x + ME_PointFromChar( editor, run, cursor->nOffset, TRUE ); if (x > editor->horz_si.nPos + editor->sizeWindow.cx) x = x + 1 - editor->sizeWindow.cx; else if (x > editor->horz_si.nPos) x = editor->horz_si.nPos; - if (~editor->styleFlags & ES_AUTOVSCROLL) + if (~editor->scrollbars & ES_AUTOVSCROLL) { - ME_HScrollAbs(editor, x); + scroll_h_abs( editor, x, TRUE ); return; } - } else { - if (~editor->styleFlags & ES_AUTOVSCROLL) - return; + } + else + { + if (~editor->scrollbars & ES_AUTOVSCROLL) return; x = editor->horz_si.nPos; } - y = pPara->member.para.pt.y + pRow->member.row.pt.y; - yheight = pRow->member.row.nHeight; + y = para->pt.y + row->pt.y; + yheight = row->nHeight; if (y < editor->vert_si.nPos) - ME_ScrollAbs(editor, x, y); + scroll_abs( editor, x, y, TRUE ); else if (y + yheight > editor->vert_si.nPos + editor->sizeWindow.cy) - ME_ScrollAbs(editor, x, y + yheight - editor->sizeWindow.cy); + scroll_abs( editor, x, y + yheight - editor->sizeWindow.cy, TRUE ); else if (x != editor->horz_si.nPos) - ME_ScrollAbs(editor, x, editor->vert_si.nPos); + scroll_abs( editor, x, editor->vert_si.nPos, TRUE ); } void ME_InvalidateSelection(ME_TextEditor *editor) { - ME_DisplayItem *sel_start, *sel_end; - ME_DisplayItem *repaint_start = NULL, *repaint_end = NULL; + ME_Paragraph *sel_start, *sel_end; + ME_Paragraph *repaint_start = NULL, *repaint_end = NULL; int nStart, nEnd; int len = ME_GetTextLength(editor); @@ -1332,41 +1257,47 @@ ME_InvalidateSelection(ME_TextEditor *editor) if (nStart == nEnd && editor->nLastSelStart == editor->nLastSelEnd) return; ME_WrapMarkedParagraphs(editor); - ME_GetSelectionParas(editor, &sel_start, &sel_end); - assert(sel_start->type == diParagraph); - assert(sel_end->type == diParagraph); + editor_get_selection_paras( editor, &sel_start, &sel_end ); + /* last selection markers aren't always updated, which means * they can point past the end of the document */ - if (editor->nLastSelStart > len || editor->nLastSelEnd > len) { - repaint_start = ME_FindItemFwd(editor->pBuffer->pFirst, diParagraph); - repaint_end = editor->pBuffer->pLast->member.para.prev_para; - } else { + if (editor->nLastSelStart > len || editor->nLastSelEnd > len) + { + repaint_start = editor_first_para( editor ); + repaint_end = para_prev( editor_end_para( editor ) ); + } + else + { /* if the start part of selection is being expanded or contracted... */ - if (nStart < editor->nLastSelStart) { + if (nStart < editor->nLastSelStart) + { repaint_start = sel_start; - repaint_end = editor->pLastSelStartPara; - } else if (nStart > editor->nLastSelStart) { - repaint_start = editor->pLastSelStartPara; + repaint_end = editor->last_sel_start_para; + } + else if (nStart > editor->nLastSelStart) + { + repaint_start = editor->last_sel_start_para; repaint_end = sel_start; } /* if the end part of selection is being contracted or expanded... */ - if (nEnd < editor->nLastSelEnd) { + if (nEnd < editor->nLastSelEnd) + { if (!repaint_start) repaint_start = sel_end; - repaint_end = editor->pLastSelEndPara; - } else if (nEnd > editor->nLastSelEnd) { - if (!repaint_start) repaint_start = editor->pLastSelEndPara; + repaint_end = editor->last_sel_end_para; + } + else if (nEnd > editor->nLastSelEnd) + { + if (!repaint_start) repaint_start = editor->last_sel_end_para; repaint_end = sel_end; } } if (repaint_start) - ME_InvalidateParagraphRange(editor, repaint_start, repaint_end); + para_range_invalidate( editor, repaint_start, repaint_end ); /* remember the last invalidated position */ ME_GetSelectionOfs(editor, &editor->nLastSelStart, &editor->nLastSelEnd); - ME_GetSelectionParas(editor, &editor->pLastSelStartPara, &editor->pLastSelEndPara); - assert(editor->pLastSelStartPara->type == diParagraph); - assert(editor->pLastSelEndPara->type == diParagraph); + editor_get_selection_paras( editor, &editor->last_sel_start_para, &editor->last_sel_end_para ); } BOOL diff --git a/dll/win32/riched20/para.c b/dll/win32/riched20/para.c index 3b3951b3986d4..1ddfe73b59fd0 100644 --- a/dll/win32/riched20/para.c +++ b/dll/win32/riched20/para.c @@ -23,42 +23,47 @@ WINE_DEFAULT_DEBUG_CHANNEL(richedit); -void mark_para_rewrap(ME_TextEditor *editor, ME_DisplayItem *para) +void para_mark_rewrap( ME_TextEditor *editor, ME_Paragraph *para ) { - para->member.para.nFlags |= MEPF_REWRAP; - add_marked_para(editor, para); + para->nFlags |= MEPF_REWRAP; + para_mark_add( editor, para ); } -ME_DisplayItem *get_di_from_para(ME_Paragraph *para) -{ - return (ME_DisplayItem *)((ptrdiff_t)para - offsetof(ME_DisplayItem, member)); -} - -static ME_DisplayItem *make_para(ME_TextEditor *editor) +static ME_Paragraph *para_create( ME_TextEditor *editor ) { ME_DisplayItem *item = ME_MakeDI(diParagraph); - ME_SetDefaultParaFormat(editor, &item->member.para.fmt); + editor_set_default_para_fmt( editor, &item->member.para.fmt ); item->member.para.nFlags = MEPF_REWRAP; - item->member.para.next_marked = item->member.para.prev_marked = NULL; - return item; + return &item->member.para; } -void destroy_para(ME_TextEditor *editor, ME_DisplayItem *item) +void para_destroy( ME_TextEditor *editor, ME_Paragraph *para ) { - assert(item->type == diParagraph); - - if (item->member.para.nWidth == editor->nTotalWidth) + if (para->nWidth == editor->nTotalWidth) { - item->member.para.nWidth = 0; + para->nWidth = 0; editor->nTotalWidth = get_total_width(editor); } - editor->total_rows -= item->member.para.nRows; - ME_DestroyString(item->member.para.text); - para_num_clear( &item->member.para.para_num ); - remove_marked_para(editor, item); - ME_DestroyDisplayItem(item); + editor->total_rows -= para->nRows; + ME_DestroyString( para->text ); + para_num_clear( ¶->para_num ); + para_mark_remove( editor, para ); + ME_DestroyDisplayItem( para_get_di( para ) ); +} + +/* Note para_next/prev will return the start and end doc nodes */ +ME_Paragraph *para_next( ME_Paragraph *para ) +{ + if (para->next_para) return ¶->next_para->member.para; + return NULL; +} + +ME_Paragraph *para_prev( ME_Paragraph *para ) +{ + if (para->prev_para && para->prev_para->type == diParagraph) return ¶->prev_para->member.para; + return NULL; } int get_total_width(ME_TextEditor *editor) @@ -79,90 +84,85 @@ int get_total_width(ME_TextEditor *editor) return total_width; } -void remove_marked_para(ME_TextEditor *editor, ME_DisplayItem *di) +static int para_mark_compare( const void *key, const struct wine_rb_entry *entry ) { - ME_DisplayItem *head = editor->first_marked_para; + ME_Paragraph *para = WINE_RB_ENTRY_VALUE( entry, ME_Paragraph, marked_entry ); - assert(di->type == diParagraph); - if (!di->member.para.next_marked && !di->member.para.prev_marked) - { - if (di == head) - editor->first_marked_para = NULL; - } - else if (di->member.para.next_marked && di->member.para.prev_marked) - { - di->member.para.prev_marked->member.para.next_marked = di->member.para.next_marked; - di->member.para.next_marked->member.para.prev_marked = di->member.para.prev_marked; - di->member.para.prev_marked = di->member.para.next_marked = NULL; - } - else if (di->member.para.next_marked) - { - assert(di == editor->first_marked_para); - editor->first_marked_para = di->member.para.next_marked; - di->member.para.next_marked->member.para.prev_marked = NULL; - di->member.para.next_marked = NULL; - } - else - { - di->member.para.prev_marked->member.para.next_marked = NULL; - di->member.para.prev_marked = NULL; - } + return *(int *)key - para->nCharOfs; +} + +void para_mark_remove( ME_TextEditor *editor, ME_Paragraph *para ) +{ + wine_rb_remove_key( &editor->marked_paras, ¶->nCharOfs ); +} + +void para_mark_add( ME_TextEditor *editor, ME_Paragraph *para ) +{ + wine_rb_put( &editor->marked_paras, ¶->nCharOfs, ¶->marked_entry ); } -void add_marked_para(ME_TextEditor *editor, ME_DisplayItem *di) +ME_Run *para_first_run( ME_Paragraph *para ) { - ME_DisplayItem *iter = editor->first_marked_para; + ME_DisplayItem *di; - if (!iter) + for (di = para_get_di( para ); di != para->next_para; di = di->next ) { - editor->first_marked_para = di; - return; - } - while (iter) - { - if (iter == di) - return; - else if (di->member.para.nCharOfs < iter->member.para.nCharOfs) - { - if (iter == editor->first_marked_para) - editor->first_marked_para = di; - di->member.para.next_marked = iter; - iter->member.para.prev_marked = di; - break; - } - else if (di->member.para.nCharOfs >= iter->member.para.nCharOfs) - { - if (!iter->member.para.next_marked || di->member.para.nCharOfs < iter->member.para.next_marked->member.para.nCharOfs) - { - if (iter->member.para.next_marked) - { - di->member.para.next_marked = iter->member.para.next_marked; - iter->member.para.next_marked->member.para.prev_marked = di; - } - di->member.para.prev_marked = iter; - iter->member.para.next_marked = di; - break; - } - } - iter = iter->member.para.next_marked; + if (di->type != diRun) continue; + return &di->member.run; } + ERR( "failed to find run in paragraph\n" ); + return NULL; +} + +ME_Run *para_end_run( ME_Paragraph *para ) +{ + return para->eop_run; +} + +BOOL para_in_table( ME_Paragraph *para ) +{ + return para->fmt.wEffects & PFE_TABLE; +} + +ME_Cell *para_cell( ME_Paragraph *para ) +{ + return para->cell; +} + +ME_Row *para_first_row( ME_Paragraph *para ) +{ + ME_DisplayItem *item; + + item = ME_FindItemFwd( para_get_di( para ), diStartRowOrParagraph ); + if (!item || item->type != diStartRow) return NULL; + return &item->member.row; +} + +ME_Row *para_end_row( ME_Paragraph *para ) +{ + ME_DisplayItem *item; + + para = para_next( para ); + item = ME_FindItemBack( para_get_di( para ), diStartRowOrParagraph ); + if (!item || item->type != diStartRow) return NULL; + return &item->member.row; } void ME_MakeFirstParagraph(ME_TextEditor *editor) { - static const WCHAR cr_lf[] = {'\r','\n',0}; ME_Context c; CHARFORMAT2W cf; const CHARFORMATW *host_cf; LOGFONTW lf; HFONT hf; ME_TextBuffer *text = editor->pBuffer; - ME_DisplayItem *para = make_para(editor); - ME_DisplayItem *run; + ME_Paragraph *para = para_create( editor ); + ME_Run *run; ME_Style *style; int eol_len; + HDC hdc = ITextHost_TxGetDC( editor->texthost ); - ME_InitContext(&c, editor, ITextHost_TxGetDC(editor->texthost)); + ME_InitContext( &c, editor, hdc ); hf = GetStockObject(SYSTEM_FONT); assert(hf); @@ -202,59 +202,57 @@ void ME_MakeFirstParagraph(ME_TextEditor *editor) } eol_len = editor->bEmulateVersion10 ? 2 : 1; - para->member.para.text = ME_MakeStringN( cr_lf, eol_len ); + para->text = ME_MakeStringN( L"\r\n", eol_len ); - run = ME_MakeRun(style, MERF_ENDPARA); - run->member.run.nCharOfs = 0; - run->member.run.len = eol_len; - run->member.run.para = ¶->member.para; + run = run_create( style, MERF_ENDPARA ); + run->nCharOfs = 0; + run->len = eol_len; + run->para = para; + para->eop_run = run; - para->member.para.eop_run = &run->member.run; - - ME_InsertBefore(text->pLast, para); - ME_InsertBefore(text->pLast, run); - para->member.para.prev_para = text->pFirst; - para->member.para.next_para = text->pLast; - text->pFirst->member.para.next_para = para; - text->pLast->member.para.prev_para = para; + ME_InsertBefore( text->pLast, para_get_di( para) ); + ME_InsertBefore( text->pLast, run_get_di( run ) ); + para->prev_para = text->pFirst; + para->next_para = text->pLast; + text->pFirst->member.para.next_para = para_get_di( para ); + text->pLast->member.para.prev_para = para_get_di( para ); text->pLast->member.para.nCharOfs = editor->bEmulateVersion10 ? 2 : 1; - add_marked_para(editor, para); + wine_rb_init( &editor->marked_paras, para_mark_compare ); + para_mark_add( editor, para ); ME_DestroyContext(&c); + ITextHost_TxReleaseDC( editor->texthost, hdc ); } -static void ME_MarkForWrapping(ME_TextEditor *editor, ME_DisplayItem *first, const ME_DisplayItem *last) +static void para_mark_rewrap_paras( ME_TextEditor *editor, ME_Paragraph *first, const ME_Paragraph *end ) { - while(first != last) - { - mark_para_rewrap(editor, first); - first = first->member.para.next_para; - } + while (first != end) + { + para_mark_rewrap( editor, first ); + first = para_next( first ); + } } -void ME_MarkAllForWrapping(ME_TextEditor *editor) +void editor_mark_rewrap_all( ME_TextEditor *editor ) { - ME_MarkForWrapping(editor, editor->pBuffer->pFirst->member.para.next_para, editor->pBuffer->pLast); + para_mark_rewrap_paras( editor, editor_first_para( editor ), editor_end_para( editor ) ); } -static void ME_UpdateTableFlags(ME_DisplayItem *para) +static void table_update_flags( ME_Paragraph *para ) { - para->member.para.fmt.dwMask |= PFM_TABLE|PFM_TABLEROWDELIMITER; - if (para->member.para.pCell) { - para->member.para.nFlags |= MEPF_CELL; - } else { - para->member.para.nFlags &= ~MEPF_CELL; - } - if (para->member.para.nFlags & MEPF_ROWEND) { - para->member.para.fmt.wEffects |= PFE_TABLEROWDELIMITER; - } else { - para->member.para.fmt.wEffects &= ~PFE_TABLEROWDELIMITER; - } - if (para->member.para.nFlags & (MEPF_ROWSTART|MEPF_CELL|MEPF_ROWEND)) - para->member.para.fmt.wEffects |= PFE_TABLE; - else - para->member.para.fmt.wEffects &= ~PFE_TABLE; + para->fmt.dwMask |= PFM_TABLE | PFM_TABLEROWDELIMITER; + + if (para_cell( para )) para->nFlags |= MEPF_CELL; + else para->nFlags &= ~MEPF_CELL; + + if (para->nFlags & MEPF_ROWEND) para->fmt.wEffects |= PFE_TABLEROWDELIMITER; + else para->fmt.wEffects &= ~PFE_TABLEROWDELIMITER; + + if (para->nFlags & (MEPF_ROWSTART | MEPF_CELL | MEPF_ROWEND)) + para->fmt.wEffects |= PFE_TABLE; + else + para->fmt.wEffects &= ~PFE_TABLE; } static inline BOOL para_num_same_list( const PARAFORMAT2 *item, const PARAFORMAT2 *base ) @@ -283,7 +281,6 @@ static ME_String *para_num_get_str( ME_Paragraph *para, WORD num ) /* max 4 Roman letters (representing '8') / decade + '(' + ')' */ ME_String *str = ME_MakeStringEmpty( 20 + 2 ); WCHAR *p; - static const WCHAR fmtW[] = {'%', 'd', 0}; static const WORD letter_base[] = { 1, 26, 26 * 26, 26 * 26 * 26 }; /* roman_base should start on a '5' not a '1', otherwise the 'total' code will need adjusting. 'N' and 'O' are what MS uses for 5000 and 10000, their version doesn't work well above 30000, @@ -312,7 +309,7 @@ static ME_String *para_num_get_str( ME_Paragraph *para, WORD num ) { case PFN_ARABIC: default: - p += swprintf( p, fmtW, num ); + p += swprintf( p, 20, L"%d", num ); break; case PFN_LCLETTER: @@ -396,9 +393,6 @@ void para_num_init( ME_Context *c, ME_Paragraph *para ) { ME_Style *style; CHARFORMAT2W cf; - static const WCHAR bullet_font[] = {'S','y','m','b','o','l',0}; - static const WCHAR bullet_str[] = {0xb7, 0}; - static const WCHAR spaceW[] = {' ', 0}; SIZE sz; if (!para->fmt.wNumbering) return; @@ -412,7 +406,7 @@ void para_num_init( ME_Context *c, ME_Paragraph *para ) { cf.cbSize = sizeof(cf); cf.dwMask = CFM_FACE | CFM_CHARSET; - memcpy( cf.szFaceName, bullet_font, sizeof(bullet_font) ); + lstrcpyW( cf.szFaceName, L"Symbol" ); cf.bCharSet = SYMBOL_CHARSET; style = ME_ApplyStyle( c->editor, style, &cf ); } @@ -429,13 +423,13 @@ void para_num_init( ME_Context *c, ME_Paragraph *para ) if (para->fmt.wNumbering != PFN_BULLET) para->para_num.text = para_num_get_str( para, para_num_get_num( para ) ); else - para->para_num.text = ME_MakeStringConst( bullet_str, 1 ); + para->para_num.text = ME_MakeStringConst( L"\x00b7", 1 ); } select_style( c, para->para_num.style ); GetTextExtentPointW( c->hDC, para->para_num.text->szData, para->para_num.text->nLen, &sz ); para->para_num.width = sz.cx; - GetTextExtentPointW( c->hDC, spaceW, 1, &sz ); + GetTextExtentPointW( c->hDC, L" ", 1, &sz ); para->para_num.width += sz.cx; } @@ -454,14 +448,14 @@ static void para_num_clear_list( ME_TextEditor *editor, ME_Paragraph *para, cons { do { - mark_para_rewrap(editor, get_di_from_para(para)); + para_mark_rewrap( editor, para ); para_num_clear( ¶->para_num ); if (para->next_para->type != diParagraph) break; para = ¶->next_para->member.para; } while (para_num_same_list( ¶->fmt, orig_fmt )); } -static BOOL ME_SetParaFormat(ME_TextEditor *editor, ME_Paragraph *para, const PARAFORMAT2 *pFmt) +static BOOL para_set_fmt( ME_TextEditor *editor, ME_Paragraph *para, const PARAFORMAT2 *pFmt ) { PARAFORMAT2 copy; DWORD dwMask; @@ -494,8 +488,9 @@ static BOOL ME_SetParaFormat(ME_TextEditor *editor, ME_Paragraph *para, const PA COPY_FIELD(PFM_ALIGNMENT, wAlignment); if (dwMask & PFM_TABSTOPS) { - para->fmt.cTabCount = max(0, min(pFmt->cTabCount, MAX_TAB_STOPS)); /* Clamp between 0 and MAX_TAB_STOPS */ - memcpy(para->fmt.rgxTabs, pFmt->rgxTabs, para->fmt.cTabCount*sizeof(LONG)); + /* Clamp between 0 and MAX_TAB_STOPS */ + para->fmt.cTabCount = max(0, min(pFmt->cTabCount, MAX_TAB_STOPS)); + memcpy(para->fmt.rgxTabs, pFmt->rgxTabs, para->fmt.cTabCount * sizeof(LONG)); } #define EFFECTS_MASK (PFM_RTLPARA|PFM_KEEP|PFM_KEEPNEXT|PFM_PAGEBREAKBEFORE| \ @@ -529,7 +524,7 @@ static BOOL ME_SetParaFormat(ME_TextEditor *editor, ME_Paragraph *para, const PA if (memcmp(©, ¶->fmt, sizeof(PARAFORMAT2))) { - mark_para_rewrap(editor, get_di_from_para(para)); + para_mark_rewrap( editor, para ); if (((dwMask & PFM_NUMBERING) && (copy.wNumbering != para->fmt.wNumbering)) || ((dwMask & PFM_NUMBERINGSTART) && (copy.wNumberingStart != para->fmt.wNumberingStart)) || ((dwMask & PFM_NUMBERINGSTYLE) && (copy.wNumberingStyle != para->fmt.wNumberingStyle))) @@ -542,278 +537,251 @@ static BOOL ME_SetParaFormat(ME_TextEditor *editor, ME_Paragraph *para, const PA } /* split paragraph at the beginning of the run */ -ME_DisplayItem *ME_SplitParagraph(ME_TextEditor *editor, ME_DisplayItem *run, - ME_Style *style, const WCHAR *eol_str, int eol_len, - int paraFlags) -{ - ME_DisplayItem *next_para = NULL; - ME_DisplayItem *run_para = NULL; - ME_DisplayItem *new_para = make_para(editor); - ME_DisplayItem *end_run; +ME_Paragraph *para_split( ME_TextEditor *editor, ME_Run *run, ME_Style *style, + const WCHAR *eol_str, int eol_len, int paraFlags ) +{ + ME_Paragraph *new_para = para_create( editor ), *old_para, *next_para; + ME_Run *end_run, *next_run; int ofs, i; - ME_DisplayItem *pp; int run_flags = MERF_ENDPARA; - if (!editor->bEmulateVersion10) { /* v4.1 */ + if (!editor->bEmulateVersion10) /* v4.1 */ + { /* At most 1 of MEPF_CELL, MEPF_ROWSTART, or MEPF_ROWEND should be set. */ - assert(!(paraFlags & ~(MEPF_CELL|MEPF_ROWSTART|MEPF_ROWEND))); - assert(!(paraFlags & (paraFlags-1))); + assert( !(paraFlags & ~(MEPF_CELL | MEPF_ROWSTART | MEPF_ROWEND)) ); + assert( !(paraFlags & (paraFlags-1)) ); if (paraFlags == MEPF_CELL) - run_flags |= MERF_ENDCELL; + run_flags |= MERF_ENDCELL; else if (paraFlags == MEPF_ROWSTART) - run_flags |= MERF_TABLESTART|MERF_HIDDEN; - } else { /* v1.0 - v3.0 */ - assert(!(paraFlags & (MEPF_CELL|MEPF_ROWSTART|MEPF_ROWEND))); + run_flags |= MERF_TABLESTART | MERF_HIDDEN; } - assert(run->type == diRun); - run_para = ME_GetParagraph(run); - assert(run_para->member.para.fmt.cbSize == sizeof(PARAFORMAT2)); + else /* v1.0 - v3.0 */ + assert( !(paraFlags & (MEPF_CELL |MEPF_ROWSTART | MEPF_ROWEND)) ); + + old_para = run->para; + assert( old_para->fmt.cbSize == sizeof(PARAFORMAT2) ); /* Clear any cached para numbering following this paragraph */ - if (run_para->member.para.fmt.wNumbering) - para_num_clear_list( editor, &run_para->member.para, &run_para->member.para.fmt ); + if (old_para->fmt.wNumbering) + para_num_clear_list( editor, old_para, &old_para->fmt ); - new_para->member.para.text = ME_VSplitString( run_para->member.para.text, run->member.run.nCharOfs ); + new_para->text = ME_VSplitString( old_para->text, run->nCharOfs ); - end_run = ME_MakeRun(style, run_flags); - ofs = end_run->member.run.nCharOfs = run->member.run.nCharOfs; - end_run->member.run.len = eol_len; - end_run->member.run.para = run->member.run.para; - ME_AppendString( run_para->member.para.text, eol_str, eol_len ); - next_para = run_para->member.para.next_para; - assert(next_para == ME_FindItemFwd(run_para, diParagraphOrEnd)); + end_run = run_create( style, run_flags ); + ofs = end_run->nCharOfs = run->nCharOfs; + end_run->len = eol_len; + end_run->para = run->para; + ME_AppendString( old_para->text, eol_str, eol_len ); + next_para = &old_para->next_para->member.para; - add_undo_join_paras( editor, run_para->member.para.nCharOfs + ofs ); + add_undo_join_paras( editor, old_para->nCharOfs + ofs ); /* Update selection cursors to point to the correct paragraph. */ - for (i = 0; i < editor->nCursors; i++) { - if (editor->pCursors[i].pPara == run_para && - run->member.run.nCharOfs <= editor->pCursors[i].pRun->member.run.nCharOfs) + for (i = 0; i < editor->nCursors; i++) + { + if (editor->pCursors[i].para == old_para && + run->nCharOfs <= editor->pCursors[i].run->nCharOfs) { - editor->pCursors[i].pPara = new_para; + editor->pCursors[i].para = new_para; } } - /* the new paragraph will have a different starting offset, so let's update its runs */ - pp = run; - while(pp->type == diRun) { - pp->member.run.nCharOfs -= ofs; - pp->member.run.para = &new_para->member.para; - pp = ME_FindItemFwd(pp, diRunOrParagraphOrEnd); + /* the new paragraph will have a different starting offset, so update its runs */ + for (next_run = run; next_run; next_run = run_next( next_run )) + { + next_run->nCharOfs -= ofs; + next_run->para = new_para; } - new_para->member.para.nCharOfs = run_para->member.para.nCharOfs + ofs; - new_para->member.para.nCharOfs += eol_len; - new_para->member.para.nFlags = 0; - mark_para_rewrap(editor, new_para); + + new_para->nCharOfs = old_para->nCharOfs + ofs; + new_para->nCharOfs += eol_len; + new_para->nFlags = 0; + para_mark_rewrap( editor, new_para ); /* FIXME initialize format style and call ME_SetParaFormat blah blah */ - new_para->member.para.fmt = run_para->member.para.fmt; - new_para->member.para.border = run_para->member.para.border; + new_para->fmt = old_para->fmt; + new_para->border = old_para->border; /* insert paragraph into paragraph double linked list */ - new_para->member.para.prev_para = run_para; - new_para->member.para.next_para = next_para; - run_para->member.para.next_para = new_para; - next_para->member.para.prev_para = new_para; + new_para->prev_para = para_get_di( old_para ); + new_para->next_para = para_get_di( next_para ); + old_para->next_para = para_get_di( new_para ); + next_para->prev_para = para_get_di( new_para ); /* insert end run of the old paragraph, and new paragraph, into DI double linked list */ - ME_InsertBefore(run, new_para); - ME_InsertBefore(new_para, end_run); + ME_InsertBefore( run_get_di( run ), para_get_di( new_para ) ); + ME_InsertBefore( para_get_di( new_para ), run_get_di( end_run ) ); /* Fix up the paras' eop_run ptrs */ - new_para->member.para.eop_run = run_para->member.para.eop_run; - run_para->member.para.eop_run = &end_run->member.run; + new_para->eop_run = old_para->eop_run; + old_para->eop_run = end_run; - if (!editor->bEmulateVersion10) { /* v4.1 */ - if (paraFlags & (MEPF_ROWSTART|MEPF_CELL)) + if (!editor->bEmulateVersion10) /* v4.1 */ + { + if (paraFlags & (MEPF_ROWSTART | MEPF_CELL)) { - ME_DisplayItem *cell = ME_MakeDI(diCell); - ME_InsertBefore(new_para, cell); - new_para->member.para.pCell = cell; - cell->member.cell.next_cell = NULL; + ME_Cell *cell = cell_create(); + ME_InsertBefore( para_get_di( new_para ), cell_get_di( cell ) ); + new_para->cell = cell; + cell->next_cell = NULL; if (paraFlags & MEPF_ROWSTART) { - run_para->member.para.nFlags |= MEPF_ROWSTART; - cell->member.cell.prev_cell = NULL; - cell->member.cell.parent_cell = run_para->member.para.pCell; - if (run_para->member.para.pCell) - cell->member.cell.nNestingLevel = run_para->member.para.pCell->member.cell.nNestingLevel + 1; + old_para->nFlags |= MEPF_ROWSTART; + cell->prev_cell = NULL; + cell->parent_cell = old_para->cell; + if (para_cell( old_para )) + cell->nNestingLevel = para_cell( old_para )->nNestingLevel + 1; else - cell->member.cell.nNestingLevel = 1; - } else { - cell->member.cell.prev_cell = run_para->member.para.pCell; - assert(cell->member.cell.prev_cell); - cell->member.cell.prev_cell->member.cell.next_cell = cell; - assert(run_para->member.para.nFlags & MEPF_CELL); - assert(!(run_para->member.para.nFlags & MEPF_ROWSTART)); - cell->member.cell.nNestingLevel = cell->member.cell.prev_cell->member.cell.nNestingLevel; - cell->member.cell.parent_cell = cell->member.cell.prev_cell->member.cell.parent_cell; + cell->nNestingLevel = 1; } - } else if (paraFlags & MEPF_ROWEND) { - run_para->member.para.nFlags |= MEPF_ROWEND; - run_para->member.para.pCell = run_para->member.para.pCell->member.cell.parent_cell; - new_para->member.para.pCell = run_para->member.para.pCell; - assert(run_para->member.para.prev_para->member.para.nFlags & MEPF_CELL); - assert(!(run_para->member.para.prev_para->member.para.nFlags & MEPF_ROWSTART)); - if (new_para->member.para.pCell != new_para->member.para.next_para->member.para.pCell - && new_para->member.para.next_para->member.para.pCell - && !new_para->member.para.next_para->member.para.pCell->member.cell.prev_cell) + else + { + cell->prev_cell = old_para->cell; + cell_prev( cell )->next_cell = cell; + assert( old_para->nFlags & MEPF_CELL ); + assert( !(old_para->nFlags & MEPF_ROWSTART) ); + cell->nNestingLevel = cell_prev( cell )->nNestingLevel; + cell->parent_cell = cell_prev( cell )->parent_cell; + } + } + else if (paraFlags & MEPF_ROWEND) + { + old_para->nFlags |= MEPF_ROWEND; + old_para->cell = old_para->cell->parent_cell; + new_para->cell = old_para->cell; + assert( para_prev( old_para )->nFlags & MEPF_CELL ); + assert( !(para_prev( old_para )->nFlags & MEPF_ROWSTART) ); + if (new_para->cell != para_next( new_para )->cell + && para_next( new_para )->cell + && !cell_prev( para_next( new_para )->cell )) { /* Row starts just after the row that was ended. */ - new_para->member.para.nFlags |= MEPF_ROWSTART; + new_para->nFlags |= MEPF_ROWSTART; } - } else { - new_para->member.para.pCell = run_para->member.para.pCell; } - ME_UpdateTableFlags(run_para); - ME_UpdateTableFlags(new_para); + else new_para->cell = old_para->cell; + + table_update_flags( old_para ); + table_update_flags( new_para ); } /* force rewrap of the */ - if (run_para->member.para.prev_para->type == diParagraph) - mark_para_rewrap(editor, run_para->member.para.prev_para); + if (old_para->prev_para->type == diParagraph) + para_mark_rewrap( editor, &old_para->prev_para->member.para ); - mark_para_rewrap(editor, new_para->member.para.prev_para); + para_mark_rewrap( editor, &new_para->prev_para->member.para ); /* we've added the end run, so we need to modify nCharOfs in the next paragraphs */ - ME_PropagateCharOffset(next_para, eol_len); + editor_propagate_char_ofs( next_para, NULL, eol_len ); editor->nParagraphs++; return new_para; } -/* join tp with tp->member.para.next_para, keeping tp's style; this - * is consistent with the original */ -ME_DisplayItem *ME_JoinParagraphs(ME_TextEditor *editor, ME_DisplayItem *tp, - BOOL keepFirstParaFormat) +/* join para with the next para keeping para's style using the paragraph fmt + specified in use_first_fmt */ +ME_Paragraph *para_join( ME_TextEditor *editor, ME_Paragraph *para, BOOL use_first_fmt ) { - ME_DisplayItem *pNext, *pFirstRunInNext, *pRun, *pTmp, *pCell = NULL; - int i, shift; - int end_len; + ME_Paragraph *next = para_next( para ); + ME_Run *end_run, *next_first_run, *tmp_run; + ME_Cell *cell = NULL; + int i, end_len; CHARFORMAT2W fmt; ME_Cursor startCur, endCur; ME_String *eol_str; - assert(tp->type == diParagraph); - assert(tp->member.para.next_para); - assert(tp->member.para.next_para->type == diParagraph); + assert( next && para_next( next ) ); /* Clear any cached para numbering following this paragraph */ - if (tp->member.para.fmt.wNumbering) - para_num_clear_list( editor, &tp->member.para, &tp->member.para.fmt ); + if (para->fmt.wNumbering) para_num_clear_list( editor, para, ¶->fmt ); - pNext = tp->member.para.next_para; + end_run = para_end_run( para ); + next_first_run = para_first_run( next ); - /* Need to locate end-of-paragraph run here, in order to know end_len */ - pRun = ME_FindItemBack(pNext, diRunOrParagraph); - - assert(pRun); - assert(pRun->type == diRun); - assert(pRun->member.run.nFlags & MERF_ENDPARA); - - end_len = pRun->member.run.len; - eol_str = ME_VSplitString( tp->member.para.text, pRun->member.run.nCharOfs ); - ME_AppendString( tp->member.para.text, pNext->member.para.text->szData, pNext->member.para.text->nLen ); + end_len = end_run->len; + eol_str = ME_VSplitString( para->text, end_run->nCharOfs ); + ME_AppendString( para->text, next->text->szData, next->text->nLen ); /* null char format operation to store the original char format for the ENDPARA run */ ME_InitCharFormat2W(&fmt); - endCur.pPara = pNext; - endCur.pRun = ME_FindItemFwd(pNext, diRun); - endCur.nOffset = 0; - startCur = endCur; - ME_PrevRun(&startCur.pPara, &startCur.pRun, TRUE); - ME_SetCharFormat(editor, &startCur, &endCur, &fmt); + startCur.para = para; + startCur.run = end_run; + endCur.para = next; + endCur.run = next_first_run; + startCur.nOffset = endCur.nOffset = 0; - if (!editor->bEmulateVersion10) { /* v4.1 */ - /* Table cell/row properties are always moved over from the removed para. */ - tp->member.para.nFlags = pNext->member.para.nFlags; - tp->member.para.pCell = pNext->member.para.pCell; + ME_SetCharFormat(editor, &startCur, &endCur, &fmt); + if (!editor->bEmulateVersion10) /* v4.1 */ + { /* Remove cell boundary if it is between the end paragraph run and the next * paragraph display item. */ - for (pTmp = pRun->next; pTmp != pNext; pTmp = pTmp->next) - { - if (pTmp->type == diCell) - { - pCell = pTmp; - break; - } - } + if (para->cell != next->cell) cell = next->cell; + + /* Table cell/row properties are always moved over from the removed para. */ + para->nFlags = next->nFlags; + para->cell = next->cell; } - add_undo_split_para( editor, &pNext->member.para, eol_str, pCell ? &pCell->member.cell : NULL ); + add_undo_split_para( editor, next, eol_str, cell ); - if (pCell) + if (cell) { - ME_Remove( pCell ); - if (pCell->member.cell.prev_cell) - pCell->member.cell.prev_cell->member.cell.next_cell = pCell->member.cell.next_cell; - if (pCell->member.cell.next_cell) - pCell->member.cell.next_cell->member.cell.prev_cell = pCell->member.cell.prev_cell; - ME_DestroyDisplayItem( pCell ); + ME_Remove( cell_get_di( cell ) ); + if (cell_prev( cell )) cell_prev( cell )->next_cell = cell_next( cell ); + if (cell_next( cell )) cell_next( cell )->prev_cell = cell_prev( cell ); + ME_DestroyDisplayItem( cell_get_di( cell ) ); } - if (!keepFirstParaFormat) + if (!use_first_fmt) { - add_undo_set_para_fmt( editor, &tp->member.para ); - tp->member.para.fmt = pNext->member.para.fmt; - tp->member.para.border = pNext->member.para.border; + add_undo_set_para_fmt( editor, para ); + para->fmt = next->fmt; + para->border = next->border; } - shift = pNext->member.para.nCharOfs - tp->member.para.nCharOfs - end_len; - - pFirstRunInNext = ME_FindItemFwd(pNext, diRunOrParagraph); - - assert(pFirstRunInNext->type == diRun); - /* Update selection cursors so they don't point to the removed end * paragraph run, and point to the correct paragraph. */ - for (i=0; i < editor->nCursors; i++) { - if (editor->pCursors[i].pRun == pRun) { - editor->pCursors[i].pRun = pFirstRunInNext; + for (i = 0; i < editor->nCursors; i++) + { + if (editor->pCursors[i].run == end_run) + { + editor->pCursors[i].run = next_first_run; editor->pCursors[i].nOffset = 0; - } else if (editor->pCursors[i].pPara == pNext) { - editor->pCursors[i].pPara = tp; } + else if (editor->pCursors[i].para == next) + editor->pCursors[i].para = para; } - pTmp = pNext; - do { - pTmp = ME_FindItemFwd(pTmp, diRunOrParagraphOrEnd); - if (pTmp->type != diRun) - break; - TRACE("shifting %s by %d (previous %d)\n", debugstr_run( &pTmp->member.run ), shift, pTmp->member.run.nCharOfs); - pTmp->member.run.nCharOfs += shift; - pTmp->member.run.para = &tp->member.para; - } while(1); + for (tmp_run = next_first_run; tmp_run; tmp_run = run_next( tmp_run )) + { + tmp_run->nCharOfs += next->nCharOfs - para->nCharOfs - end_len; + tmp_run->para = para; + } /* Fix up the para's eop_run ptr */ - tp->member.para.eop_run = pNext->member.para.eop_run; + para->eop_run = next->eop_run; - ME_Remove(pRun); - ME_DestroyDisplayItem(pRun); + ME_Remove( run_get_di( end_run ) ); + ME_DestroyDisplayItem( run_get_di( end_run) ); - if (editor->pLastSelStartPara == pNext) - editor->pLastSelStartPara = tp; - if (editor->pLastSelEndPara == pNext) - editor->pLastSelEndPara = tp; + if (editor->last_sel_start_para == next) + editor->last_sel_start_para = para; + if (editor->last_sel_end_para == next) + editor->last_sel_end_para = para; - tp->member.para.next_para = pNext->member.para.next_para; - pNext->member.para.next_para->member.para.prev_para = tp; - ME_Remove(pNext); - destroy_para(editor, pNext); + para->next_para = next->next_para; + next->next_para->member.para.prev_para = para_get_di( para ); + ME_Remove( para_get_di(next) ); + para_destroy( editor, next ); - ME_PropagateCharOffset(tp->member.para.next_para, -end_len); + editor_propagate_char_ofs( para_next( para ), NULL, -end_len ); ME_CheckCharOffsets(editor); editor->nParagraphs--; - mark_para_rewrap(editor, tp); - return tp; -} - -ME_DisplayItem *ME_GetParagraph(ME_DisplayItem *item) { - return ME_FindItemBackOrHere(item, diParagraph); + para_mark_rewrap( editor, para ); + return para; } void ME_DumpParaStyleToBuf(const PARAFORMAT2 *pFmt, char buf[2048]) @@ -879,18 +847,18 @@ void ME_DumpParaStyleToBuf(const PARAFORMAT2 *pFmt, char buf[2048]) #undef DUMP_EFFECT } -void -ME_GetSelectionParas(ME_TextEditor *editor, ME_DisplayItem **para, ME_DisplayItem **para_end) +void editor_get_selection_paras( ME_TextEditor *editor, ME_Paragraph **para, ME_Paragraph **para_end ) { ME_Cursor *pEndCursor = &editor->pCursors[1]; - *para = editor->pCursors[0].pPara; - *para_end = editor->pCursors[1].pPara; + *para = editor->pCursors[0].para; + *para_end = editor->pCursors[1].para; if (*para == *para_end) return; - if ((*para_end)->member.para.nCharOfs < (*para)->member.para.nCharOfs) { - ME_DisplayItem *tmp = *para; + if ((*para_end)->nCharOfs < (*para)->nCharOfs) + { + ME_Paragraph *tmp = *para; *para = *para_end; *para_end = tmp; @@ -899,78 +867,78 @@ ME_GetSelectionParas(ME_TextEditor *editor, ME_DisplayItem **para, ME_DisplayIte /* The paragraph at the end of a non-empty selection isn't included * if the selection ends at the start of the paragraph. */ - if (!pEndCursor->pRun->member.run.nCharOfs && !pEndCursor->nOffset) - *para_end = (*para_end)->member.para.prev_para; + if (!pEndCursor->run->nCharOfs && !pEndCursor->nOffset) + *para_end = para_prev( *para_end ); } -BOOL ME_SetSelectionParaFormat(ME_TextEditor *editor, const PARAFORMAT2 *pFmt) +BOOL editor_set_selection_para_fmt( ME_TextEditor *editor, const PARAFORMAT2 *fmt ) { - ME_DisplayItem *para, *para_end; + ME_Paragraph *para, *para_end; - ME_GetSelectionParas(editor, ¶, ¶_end); + editor_get_selection_paras( editor, ¶, ¶_end ); - do { - ME_SetParaFormat(editor, ¶->member.para, pFmt); - if (para == para_end) - break; - para = para->member.para.next_para; - } while(1); + do + { + para_set_fmt( editor, para, fmt ); + if (para == para_end) break; + para = para_next( para ); + } while(1); - return TRUE; + return TRUE; } -static void ME_GetParaFormat(ME_TextEditor *editor, - const ME_DisplayItem *para, - PARAFORMAT2 *pFmt) +static void para_copy_fmt( const ME_Paragraph *para, PARAFORMAT2 *fmt ) { - UINT cbSize = pFmt->cbSize; - if (pFmt->cbSize >= sizeof(PARAFORMAT2)) { - *pFmt = para->member.para.fmt; - } else { - CopyMemory(pFmt, ¶->member.para.fmt, pFmt->cbSize); - pFmt->dwMask &= PFM_ALL; - } - pFmt->cbSize = cbSize; + UINT size = fmt->cbSize; + + if (fmt->cbSize >= sizeof(PARAFORMAT2)) + *fmt = para->fmt; + else + { + memcpy( fmt, ¶->fmt, fmt->cbSize ); + fmt->dwMask &= PFM_ALL; + } + fmt->cbSize = size; } -void ME_GetSelectionParaFormat(ME_TextEditor *editor, PARAFORMAT2 *pFmt) +void editor_get_selection_para_fmt( ME_TextEditor *editor, PARAFORMAT2 *fmt ) { - ME_DisplayItem *para, *para_end; - PARAFORMAT2 *curFmt; + ME_Paragraph *para, *para_end; - if (pFmt->cbSize < sizeof(PARAFORMAT)) { - pFmt->dwMask = 0; + if (fmt->cbSize < sizeof(PARAFORMAT)) + { + fmt->dwMask = 0; return; } - ME_GetSelectionParas(editor, ¶, ¶_end); + editor_get_selection_paras( editor, ¶, ¶_end ); - ME_GetParaFormat(editor, para, pFmt); + para_copy_fmt( para, fmt ); /* Invalidate values that change across the selected paragraphs. */ while (para != para_end) { - para = para->member.para.next_para; - curFmt = ¶->member.para.fmt; + para = para_next( para ); #define CHECK_FIELD(m, f) \ - if (pFmt->f != curFmt->f) pFmt->dwMask &= ~(m); + if (fmt->f != para->fmt.f) fmt->dwMask &= ~(m); CHECK_FIELD(PFM_NUMBERING, wNumbering); CHECK_FIELD(PFM_STARTINDENT, dxStartIndent); CHECK_FIELD(PFM_RIGHTINDENT, dxRightIndent); CHECK_FIELD(PFM_OFFSET, dxOffset); CHECK_FIELD(PFM_ALIGNMENT, wAlignment); - if (pFmt->dwMask & PFM_TABSTOPS) { - if (pFmt->cTabCount != para->member.para.fmt.cTabCount || - memcmp(pFmt->rgxTabs, curFmt->rgxTabs, curFmt->cTabCount*sizeof(int))) - pFmt->dwMask &= ~PFM_TABSTOPS; + if (fmt->dwMask & PFM_TABSTOPS) + { + if (fmt->cTabCount != para->fmt.cTabCount || + memcmp(fmt->rgxTabs, para->fmt.rgxTabs, para->fmt.cTabCount * sizeof(int) )) + fmt->dwMask &= ~PFM_TABSTOPS; } - if (pFmt->dwMask >= sizeof(PARAFORMAT2)) + if (fmt->cbSize >= sizeof(PARAFORMAT2)) { - pFmt->dwMask &= ~((pFmt->wEffects ^ curFmt->wEffects) << 16); + fmt->dwMask &= ~((fmt->wEffects ^ para->fmt.wEffects) << 16); CHECK_FIELD(PFM_SPACEBEFORE, dySpaceBefore); CHECK_FIELD(PFM_SPACEAFTER, dySpaceAfter); CHECK_FIELD(PFM_LINESPACING, dyLineSpacing); @@ -989,7 +957,7 @@ void ME_GetSelectionParaFormat(ME_TextEditor *editor, PARAFORMAT2 *pFmt) } } -void ME_SetDefaultParaFormat(ME_TextEditor *editor, PARAFORMAT2 *pFmt) +void editor_set_default_para_fmt( ME_TextEditor *editor, PARAFORMAT2 *pFmt ) { const PARAFORMAT2 *host_fmt; HRESULT hr; diff --git a/dll/win32/riched20/reader.c b/dll/win32/riched20/reader.c index dc551bf584187..e73b8b87e9dc3 100644 --- a/dll/win32/riched20/reader.c +++ b/dll/win32/riched20/reader.c @@ -2519,7 +2519,7 @@ static void SpecialChar (RTF_Info *info) case rtfSect: case rtfPar: RTFFlushOutputBuffer(info); - ME_SetSelectionParaFormat(info->editor, &info->fmt); + editor_set_selection_para_fmt( info->editor, &info->fmt ); memset(&info->fmt, 0, sizeof(info->fmt)); info->fmt.cbSize = sizeof(info->fmt); RTFPutUnicodeChar (info, '\r'); diff --git a/dll/win32/riched20/riched20.h b/dll/win32/riched20/riched20.h new file mode 100644 index 0000000000000..d7246c0c1ab05 --- /dev/null +++ b/dll/win32/riched20/riched20.h @@ -0,0 +1,185 @@ +/* + * RichEdit - functions and interfaces around CreateTextServices for txtsrv.c + * + * Copyright 2005, 2006, Maarten Lankhorst + * + * RichEdit - ITextHost implementation for windowed richedit controls for txthost.c + * + * Copyright 2009 by Dylan Smith + * + * 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 + */ + + +/* Forward definitions from txtsrv.c to make MSVC compile in ReactOS. */ + +DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxSendMessage( ITextServices *iface, UINT msg, WPARAM wparam, + LPARAM lparam, LRESULT *result ); + +DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxDraw( ITextServices *iface, DWORD aspect, LONG index, void *aspect_info, + DVTARGETDEVICE *td, HDC draw, HDC target, + const RECTL *bounds, const RECTL *mf_bounds, RECT *update, + BOOL (CALLBACK *continue_fn)(DWORD), DWORD continue_param, + LONG view_id ); + +DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxGetHScroll( ITextServices *iface, LONG *min_pos, LONG *max_pos, LONG *pos, + LONG *page, BOOL *enabled ); + +DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxGetVScroll( ITextServices *iface, LONG *min_pos, LONG *max_pos, LONG *pos, + LONG *page, BOOL *enabled ); + +DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_OnTxSetCursor( ITextServices *iface, DWORD aspect, LONG index, + void *aspect_info, DVTARGETDEVICE *td, HDC draw, + HDC target, const RECT *client, INT x, INT y ); + +DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxQueryHitPoint(ITextServices *iface, DWORD dwDrawAspect, LONG lindex, + void *pvAspect, DVTARGETDEVICE *ptd, HDC hdcDraw, + HDC hicTargetDev, LPCRECT lprcClient, INT x, INT y, + DWORD *pHitResult); + +DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_OnTxInPlaceActivate( ITextServices *iface, const RECT *client ); + +DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_OnTxInPlaceDeactivate(ITextServices *iface); + +DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_OnTxUIActivate(ITextServices *iface); + +DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_OnTxUIDeactivate(ITextServices *iface); + +DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxGetText( ITextServices *iface, BSTR *text ); + +DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxSetText( ITextServices *iface, const WCHAR *text ); + +DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxGetCurTargetX(ITextServices *iface, LONG *x); + +DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxGetBaseLinePos(ITextServices *iface, LONG *x); + +DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxGetNaturalSize( ITextServices *iface, DWORD aspect, HDC draw, + HDC target, DVTARGETDEVICE *td, DWORD mode, + const SIZEL *extent, LONG *width, LONG *height ); + +DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxGetDropTarget(ITextServices *iface, IDropTarget **ppDropTarget); + +DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_OnTxPropertyBitsChange( ITextServices *iface, DWORD mask, DWORD bits ); + +DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxGetCachedSize(ITextServices *iface, DWORD *pdwWidth, DWORD *pdwHeight); + + +/* Forward definitions from txthost.c to make MSVC compile in ReactOS. */ + + +DECLSPEC_HIDDEN HDC __thiscall ITextHostImpl_TxGetDC( ITextHost2 *iface ); + +DECLSPEC_HIDDEN INT __thiscall ITextHostImpl_TxReleaseDC( ITextHost2 *iface, HDC hdc ); + +DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxShowScrollBar( ITextHost2 *iface, INT bar, BOOL show ); + +DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxEnableScrollBar( ITextHost2 *iface, INT bar, INT arrows ); + +DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxSetScrollRange( ITextHost2 *iface, INT bar, LONG min_pos, INT max_pos, BOOL redraw ); + +DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxSetScrollPos( ITextHost2 *iface, INT bar, INT pos, BOOL redraw ); + +DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxInvalidateRect( ITextHost2 *iface, const RECT *rect, BOOL mode ); + +DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxViewChange( ITextHost2 *iface, BOOL update ); + +DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxCreateCaret( ITextHost2 *iface, HBITMAP bitmap, INT width, INT height ); + +DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxShowCaret( ITextHost2 *iface, BOOL show ); + +DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxSetCaretPos( ITextHost2 *iface, INT x, INT y ); + +DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxSetTimer( ITextHost2 *iface, UINT id, UINT timeout ); + +DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxKillTimer( ITextHost2 *iface, UINT id ); + +DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxScrollWindowEx( ITextHost2 *iface, INT dx, INT dy, const RECT *scroll, + const RECT *clip, HRGN update_rgn, RECT *update_rect, + UINT flags ); + +DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxSetCapture( ITextHost2 *iface, BOOL capture ); + +DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxSetFocus( ITextHost2 *iface ); + +DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxSetCursor( ITextHost2 *iface, HCURSOR cursor, BOOL text ); + +DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxScreenToClient( ITextHost2 *iface, POINT *pt ); + +DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxClientToScreen( ITextHost2 *iface, POINT *pt ); + +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxActivate( ITextHost2 *iface, LONG *old_state ); + +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxDeactivate( ITextHost2 *iface, LONG new_state ); + +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetClientRect( ITextHost2 *iface, RECT *rect ); + +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetViewInset( ITextHost2 *iface, RECT *rect ); + +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetCharFormat( ITextHost2 *iface, const CHARFORMATW **ppCF ); + +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetParaFormat( ITextHost2 *iface, const PARAFORMAT **fmt ); + +DECLSPEC_HIDDEN COLORREF __thiscall ITextHostImpl_TxGetSysColor( ITextHost2 *iface, int index ); + +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetBackStyle( ITextHost2 *iface, TXTBACKSTYLE *style ); + +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetMaxLength( ITextHost2 *iface, DWORD *length ); + +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetScrollBars( ITextHost2 *iface, DWORD *scrollbars ); + +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetPasswordChar( ITextHost2 *iface, WCHAR *c ); + +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetAcceleratorPos( ITextHost2 *iface, LONG *pos ); + +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetExtent( ITextHost2 *iface, SIZEL *extent ); + +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_OnTxCharFormatChange( ITextHost2 *iface, const CHARFORMATW *pcf ); + +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_OnTxParaFormatChange( ITextHost2 *iface, const PARAFORMAT *ppf ); + +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetPropertyBits( ITextHost2 *iface, DWORD mask, DWORD *bits ); + +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxNotify( ITextHost2 *iface, DWORD iNotify, void *pv ); + +DECLSPEC_HIDDEN HIMC __thiscall ITextHostImpl_TxImmGetContext( ITextHost2 *iface ); + +DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxImmReleaseContext( ITextHost2 *iface, HIMC context ); + +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetSelectionBarWidth( ITextHost2 *iface, LONG *width ); + +DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxIsDoubleClickPending( ITextHost2 *iface ); + +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetWindow( ITextHost2 *iface, HWND *hwnd ); + +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxSetForegroundWindow( ITextHost2 *iface ); + +DECLSPEC_HIDDEN HPALETTE __thiscall ITextHostImpl_TxGetPalette( ITextHost2 *iface ); + +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetEastAsianFlags( ITextHost2 *iface, LONG *flags ); + +DECLSPEC_HIDDEN HCURSOR __thiscall ITextHostImpl_TxSetCursor2( ITextHost2 *iface, HCURSOR cursor, BOOL text ); + +DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxFreeTextServicesNotification( ITextHost2 *iface ); + +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetEditStyle( ITextHost2 *iface, DWORD item, DWORD *data ); + +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetWindowStyles( ITextHost2 *iface, DWORD *style, DWORD *ex_style ); + +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxShowDropCaret( ITextHost2 *iface, BOOL show, HDC hdc, const RECT *rect ); + +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxDestroyCaret( ITextHost2 *iface ); + +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetHorzExtent( ITextHost2 *iface, LONG *horz_extent ); + diff --git a/dll/win32/riched20/richole.c b/dll/win32/riched20/richole.c index 3bfc4663a28b1..72840a4cafa51 100644 --- a/dll/win32/riched20/richole.c +++ b/dll/win32/riched20/richole.c @@ -136,7 +136,6 @@ static HRESULT get_typeinfo(enum tid_t tid, ITypeInfo **typeinfo) /* private IID used to get back IRichEditOleImpl pointer */ DEFINE_GUID(IID_Igetrichole, 0xe3ce5c7a, 0x8247, 0x4622, 0x81, 0xad, 0x11, 0x81, 0x02, 0xaa, 0x01, 0x30); -typedef struct ITextSelectionImpl ITextSelectionImpl; typedef struct IOleClientSiteImpl IOleClientSiteImpl; typedef struct ITextRangeImpl ITextRangeImpl; @@ -206,23 +205,9 @@ enum range_update_op { RANGE_UPDATE_DELETE }; -typedef struct IRichEditOleImpl { - IUnknown IUnknown_inner; - IRichEditOle IRichEditOle_iface; - ITextDocument2Old ITextDocument2Old_iface; - IUnknown *outer_unk; - LONG ref; - - ME_TextEditor *editor; - ITextSelectionImpl *txtSel; - - struct list rangelist; - struct list clientsites; -} IRichEditOleImpl; - struct reole_child { struct list entry; - IRichEditOleImpl *reole; + struct text_services *reole; }; struct ITextRangeImpl { @@ -232,13 +217,6 @@ struct ITextRangeImpl { LONG start, end; }; -struct ITextSelectionImpl { - ITextSelection ITextSelection_iface; - LONG ref; - - IRichEditOleImpl *reOle; -}; - typedef struct ITextFontImpl { ITextFont ITextFont_iface; LONG ref; @@ -263,19 +241,14 @@ struct IOleClientSiteImpl { LONG ref; }; -static inline IRichEditOleImpl *impl_from_IRichEditOle(IRichEditOle *iface) +static inline struct text_services *impl_from_IRichEditOle( IRichEditOle *iface ) { - return CONTAINING_RECORD(iface, IRichEditOleImpl, IRichEditOle_iface); + return CONTAINING_RECORD( iface, struct text_services, IRichEditOle_iface ); } -static inline IRichEditOleImpl *impl_from_ITextDocument2Old(ITextDocument2Old *iface) +static inline struct text_services *impl_from_ITextDocument2Old( ITextDocument2Old *iface ) { - return CONTAINING_RECORD(iface, IRichEditOleImpl, ITextDocument2Old_iface); -} - -static inline IRichEditOleImpl *impl_from_IUnknown(IUnknown *iface) -{ - return CONTAINING_RECORD(iface, IRichEditOleImpl, IUnknown_inner); + return CONTAINING_RECORD( iface, struct text_services, ITextDocument2Old_iface ); } static inline IOleClientSiteImpl *impl_from_IOleInPlaceSite(IOleInPlaceSite *iface) @@ -288,9 +261,9 @@ static inline ITextRangeImpl *impl_from_ITextRange(ITextRange *iface) return CONTAINING_RECORD(iface, ITextRangeImpl, ITextRange_iface); } -static inline ITextSelectionImpl *impl_from_ITextSelection(ITextSelection *iface) +static inline struct text_selection *impl_from_ITextSelection(ITextSelection *iface) { - return CONTAINING_RECORD(iface, ITextSelectionImpl, ITextSelection_iface); + return CONTAINING_RECORD(iface, struct text_selection, ITextSelection_iface); } static inline ITextFontImpl *impl_from_ITextFont(ITextFont *iface) @@ -305,7 +278,7 @@ static inline ITextParaImpl *impl_from_ITextPara(ITextPara *iface) static HRESULT create_textfont(ITextRange*, const ITextFontImpl*, ITextFont**); static HRESULT create_textpara(ITextRange*, ITextPara**); -static ITextSelectionImpl *CreateTextSelection(IRichEditOleImpl*); +static struct text_selection *text_selection_create( struct text_services * ); static HRESULT textrange_get_storylength(ME_TextEditor *editor, LONG *length) { @@ -316,11 +289,11 @@ static HRESULT textrange_get_storylength(ME_TextEditor *editor, LONG *length) return S_OK; } -static void textranges_update_ranges(IRichEditOleImpl *reole, LONG start, LONG end, enum range_update_op op) +static void textranges_update_ranges(struct text_services *services, LONG start, LONG end, enum range_update_op op) { ITextRangeImpl *range; - LIST_FOR_EACH_ENTRY(range, &reole->rangelist, ITextRangeImpl, child.entry) { + LIST_FOR_EACH_ENTRY(range, &services->rangelist, ITextRangeImpl, child.entry) { switch (op) { case RANGE_UPDATE_DELETE: @@ -434,7 +407,7 @@ static inline FLOAT points_to_twips(FLOAT value) return value * 1440 / 72.0; } -static HRESULT get_textfont_prop_for_pos(const IRichEditOleImpl *reole, int pos, enum textfont_prop_id propid, +static HRESULT get_textfont_prop_for_pos(const struct text_services *services, int pos, enum textfont_prop_id propid, textfont_prop_val *value) { ME_Cursor from, to; @@ -444,10 +417,10 @@ static HRESULT get_textfont_prop_for_pos(const IRichEditOleImpl *reole, int pos, fmt.cbSize = sizeof(fmt); fmt.dwMask = textfont_prop_masks[propid][0]; - ME_CursorFromCharOfs(reole->editor, pos, &from); + cursor_from_char_ofs( services->editor, pos, &from ); to = from; - ME_MoveCursorChars(reole->editor, &to, 1, FALSE); - ME_GetCharFormat(reole->editor, &from, &to, &fmt); + ME_MoveCursorChars( services->editor, &to, 1, FALSE ); + ME_GetCharFormat( services->editor, &from, &to, &fmt ); switch (propid) { @@ -508,11 +481,11 @@ static HRESULT get_textfont_prop_for_pos(const IRichEditOleImpl *reole, int pos, return S_OK; } -static inline const IRichEditOleImpl *get_range_reole(ITextRange *range) +static inline const struct text_services *get_range_reole(ITextRange *range) { - IRichEditOleImpl *reole = NULL; - ITextRange_QueryInterface(range, &IID_Igetrichole, (void**)&reole); - return reole; + struct text_services *services = NULL; + ITextRange_QueryInterface(range, &IID_Igetrichole, (void**)&services); + return services; } static void textrange_set_font(ITextRange *range, ITextFont *font) @@ -662,23 +635,24 @@ static void textrange_set_font(ITextRange *range, ITextFont *font) fmt.wWeight = value; } - if (fmt.dwMask) { - const IRichEditOleImpl *reole = get_range_reole(range); + if (fmt.dwMask) + { + const struct text_services *services = get_range_reole(range); ME_Cursor from, to; LONG start, end; ITextRange_GetStart(range, &start); ITextRange_GetEnd(range, &end); - ME_CursorFromCharOfs(reole->editor, start, &from); - ME_CursorFromCharOfs(reole->editor, end, &to); - ME_SetCharFormat(reole->editor, &from, &to, &fmt); + cursor_from_char_ofs( services->editor, start, &from ); + cursor_from_char_ofs( services->editor, end, &to ); + ME_SetCharFormat( services->editor, &from, &to, &fmt ); } } static HRESULT get_textfont_prop(const ITextFontImpl *font, enum textfont_prop_id propid, textfont_prop_val *value) { - const IRichEditOleImpl *reole; + const struct text_services *services; textfont_prop_val v; LONG start, end, i; HRESULT hr; @@ -689,7 +663,7 @@ static HRESULT get_textfont_prop(const ITextFontImpl *font, enum textfont_prop_i return S_OK; } - if (!(reole = get_range_reole(font->range))) + if (!(services = get_range_reole(font->range))) return CO_E_RELEASED; init_textfont_prop_value(propid, value); @@ -698,14 +672,14 @@ static HRESULT get_textfont_prop(const ITextFontImpl *font, enum textfont_prop_i ITextRange_GetEnd(font->range, &end); /* iterate trough a range to see if property value is consistent */ - hr = get_textfont_prop_for_pos(reole, start, propid, &v); + hr = get_textfont_prop_for_pos( services, start, propid, &v ); if (FAILED(hr)) return hr; for (i = start + 1; i < end; i++) { textfont_prop_val cur; - hr = get_textfont_prop_for_pos(reole, i, propid, &cur); + hr = get_textfont_prop_for_pos( services, i, propid, &cur ); if (FAILED(hr)) return hr; @@ -746,7 +720,7 @@ static HRESULT get_textfont_propl(const ITextFontImpl *font, enum textfont_prop_ /* Value should already have a terminal value, for boolean properties it means tomToggle is not handled */ static HRESULT set_textfont_prop(ITextFontImpl *font, enum textfont_prop_id propid, const textfont_prop_val *value) { - const IRichEditOleImpl *reole; + const struct text_services *services; ME_Cursor from, to; CHARFORMAT2W fmt; LONG start, end; @@ -762,7 +736,7 @@ static HRESULT set_textfont_prop(ITextFontImpl *font, enum textfont_prop_id prop return S_OK; } - if (!(reole = get_range_reole(font->range))) + if (!(services = get_range_reole(font->range))) return CO_E_RELEASED; memset(&fmt, 0, sizeof(fmt)); @@ -828,9 +802,9 @@ static HRESULT set_textfont_prop(ITextFontImpl *font, enum textfont_prop_id prop ITextRange_GetStart(font->range, &start); ITextRange_GetEnd(font->range, &end); - ME_CursorFromCharOfs(reole->editor, start, &from); - ME_CursorFromCharOfs(reole->editor, end, &to); - ME_SetCharFormat(reole->editor, &from, &to, &fmt); + cursor_from_char_ofs( services->editor, start, &from ); + cursor_from_char_ofs( services->editor, end, &to ); + ME_SetCharFormat( services->editor, &from, &to, &fmt ); return S_OK; } @@ -879,16 +853,16 @@ static HRESULT set_textfont_propd(ITextFontImpl *font, enum textfont_prop_id pro static HRESULT textfont_getname_from_range(ITextRange *range, BSTR *ret) { - const IRichEditOleImpl *reole; + const struct text_services *services; textfont_prop_val v; HRESULT hr; LONG start; - if (!(reole = get_range_reole(range))) + if (!(services = get_range_reole( range ))) return CO_E_RELEASED; ITextRange_GetStart(range, &start); - hr = get_textfont_prop_for_pos(reole, start, FONT_NAME, &v); + hr = get_textfont_prop_for_pos( services, start, FONT_NAME, &v ); *ret = v.str; return hr; } @@ -933,126 +907,48 @@ static HRESULT textrange_expand(ITextRange *range, LONG unit, LONG *delta) return S_OK; } -static HRESULT WINAPI IRichEditOleImpl_inner_fnQueryInterface(IUnknown *iface, REFIID riid, LPVOID *ppvObj) -{ - IRichEditOleImpl *This = impl_from_IUnknown(iface); - - TRACE("%p %s\n", This, debugstr_guid(riid)); - - *ppvObj = NULL; - if (IsEqualGUID(riid, &IID_IUnknown)) - *ppvObj = &This->IUnknown_inner; - else if (IsEqualGUID(riid, &IID_IRichEditOle)) - *ppvObj = &This->IRichEditOle_iface; - else if (IsEqualGUID(riid, &IID_ITextDocument) || IsEqualGUID(riid, &IID_ITextDocument2Old)) - *ppvObj = &This->ITextDocument2Old_iface; - if (*ppvObj) - { - IUnknown_AddRef((IUnknown *)*ppvObj); - return S_OK; - } - - if (IsEqualGUID(riid, &IID_ITextServices)) - { - static int once; - if (!once++) FIXME("%p: unhandled interface IID_ITextServices\n", This); - return E_NOINTERFACE; - } - - FIXME("%p: unhandled interface %s\n", This, debugstr_guid(riid)); - - return E_NOINTERFACE; -} - -static ULONG WINAPI IRichEditOleImpl_inner_fnAddRef(IUnknown *iface) -{ - IRichEditOleImpl *This = impl_from_IUnknown(iface); - ULONG ref = InterlockedIncrement(&This->ref); - - TRACE("%p ref = %u\n", This, ref); - - return ref; -} - -static ULONG WINAPI IRichEditOleImpl_inner_fnRelease(IUnknown *iface) -{ - IRichEditOleImpl *This = impl_from_IUnknown(iface); - ULONG ref = InterlockedDecrement(&This->ref); - - TRACE ("%p ref=%u\n", This, ref); - - if (!ref) - { - IOleClientSiteImpl *clientsite; - ITextRangeImpl *txtRge; - - This->editor->reOle = NULL; - if (This->txtSel) { - This->txtSel->reOle = NULL; - ITextSelection_Release(&This->txtSel->ITextSelection_iface); - } - - LIST_FOR_EACH_ENTRY(txtRge, &This->rangelist, ITextRangeImpl, child.entry) - txtRge->child.reole = NULL; - - LIST_FOR_EACH_ENTRY(clientsite, &This->clientsites, IOleClientSiteImpl, child.entry) - clientsite->child.reole = NULL; - - heap_free(This); - } - return ref; -} - -static const IUnknownVtbl reo_unk_vtbl = -{ - IRichEditOleImpl_inner_fnQueryInterface, - IRichEditOleImpl_inner_fnAddRef, - IRichEditOleImpl_inner_fnRelease -}; - static HRESULT WINAPI -IRichEditOle_fnQueryInterface(IRichEditOle *me, REFIID riid, LPVOID *ppvObj) +IRichEditOle_fnQueryInterface(IRichEditOle *iface, REFIID riid, LPVOID *ppvObj) { - IRichEditOleImpl *This = impl_from_IRichEditOle(me); - return IUnknown_QueryInterface(This->outer_unk, riid, ppvObj); + struct text_services *services = impl_from_IRichEditOle( iface ); + return IUnknown_QueryInterface( services->outer_unk, riid, ppvObj ); } static ULONG WINAPI -IRichEditOle_fnAddRef(IRichEditOle *me) +IRichEditOle_fnAddRef(IRichEditOle *iface) { - IRichEditOleImpl *This = impl_from_IRichEditOle(me); - return IUnknown_AddRef(This->outer_unk); + struct text_services *services = impl_from_IRichEditOle( iface ); + return IUnknown_AddRef( services->outer_unk ); } static ULONG WINAPI -IRichEditOle_fnRelease(IRichEditOle *me) +IRichEditOle_fnRelease(IRichEditOle *iface) { - IRichEditOleImpl *This = impl_from_IRichEditOle(me); - return IUnknown_Release(This->outer_unk); + struct text_services *services = impl_from_IRichEditOle( iface ); + return IUnknown_Release( services->outer_unk ); } static HRESULT WINAPI -IRichEditOle_fnActivateAs(IRichEditOle *me, REFCLSID rclsid, REFCLSID rclsidAs) +IRichEditOle_fnActivateAs(IRichEditOle *iface, REFCLSID rclsid, REFCLSID rclsidAs) { - IRichEditOleImpl *This = impl_from_IRichEditOle(me); - FIXME("stub %p\n",This); + struct text_services *services = impl_from_IRichEditOle( iface ); + FIXME( "stub %p\n", services ); return E_NOTIMPL; } static HRESULT WINAPI -IRichEditOle_fnContextSensitiveHelp(IRichEditOle *me, BOOL fEnterMode) +IRichEditOle_fnContextSensitiveHelp(IRichEditOle *iface, BOOL fEnterMode) { - IRichEditOleImpl *This = impl_from_IRichEditOle(me); - FIXME("stub %p\n",This); + struct text_services *services = impl_from_IRichEditOle( iface ); + FIXME( "stub %p\n", services ); return E_NOTIMPL; } static HRESULT WINAPI -IRichEditOle_fnConvertObject(IRichEditOle *me, LONG iob, - REFCLSID rclsidNew, LPCSTR lpstrUserTypeNew) +IRichEditOle_fnConvertObject( IRichEditOle *iface, LONG iob, REFCLSID class, LPCSTR user_type ) { - IRichEditOleImpl *This = impl_from_IRichEditOle(me); - FIXME("stub %p\n",This); + struct text_services *services = impl_from_IRichEditOle( iface ); + FIXME( "stub %p\n", services ); return E_NOTIMPL; } @@ -1202,20 +1098,19 @@ static ULONG STDMETHODCALLTYPE IOleInPlaceSite_fnRelease(IOleInPlaceSite *iface) return IOleClientSite_Release(&This->IOleClientSite_iface); } -static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnGetWindow(IOleInPlaceSite *iface, HWND *phwnd) +static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnGetWindow( IOleInPlaceSite *iface, HWND *window ) { IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface); - TRACE("(%p)->(%p)\n", This, phwnd); + TRACE( "(%p)->(%p)\n", This, window ); if (!This->child.reole) return CO_E_RELEASED; - if (!phwnd) - return E_INVALIDARG; + if (!window) return E_INVALIDARG; - *phwnd = This->child.reole->editor->hWnd; - return S_OK; + if (!This->child.reole->editor->have_texthost2) return E_NOTIMPL; + return ITextHost2_TxGetWindow( This->child.reole->editor->texthost, window ); } static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnContextSensitiveHelp(IOleInPlaceSite *iface, BOOL fEnterMode) @@ -1316,7 +1211,7 @@ static const IOleInPlaceSiteVtbl olestvt = IOleInPlaceSite_fnOnPosRectChange }; -static HRESULT CreateOleClientSite(IRichEditOleImpl *reOle, IOleClientSite **ret) +static HRESULT CreateOleClientSite( struct text_services *services, IOleClientSite **ret ) { IOleClientSiteImpl *clientSite = heap_alloc(sizeof *clientSite); @@ -1326,64 +1221,67 @@ static HRESULT CreateOleClientSite(IRichEditOleImpl *reOle, IOleClientSite **ret clientSite->IOleClientSite_iface.lpVtbl = &ocst; clientSite->IOleInPlaceSite_iface.lpVtbl = &olestvt; clientSite->ref = 1; - clientSite->child.reole = reOle; - list_add_head(&reOle->clientsites, &clientSite->child.entry); + clientSite->child.reole = services; + list_add_head( &services->clientsites, &clientSite->child.entry ); *ret = &clientSite->IOleClientSite_iface; return S_OK; } static HRESULT WINAPI -IRichEditOle_fnGetClientSite(IRichEditOle *me, IOleClientSite **clientsite) +IRichEditOle_fnGetClientSite( IRichEditOle *iface, IOleClientSite **clientsite ) { - IRichEditOleImpl *This = impl_from_IRichEditOle(me); + struct text_services *services = impl_from_IRichEditOle( iface ); - TRACE("(%p)->(%p)\n", This, clientsite); + TRACE("(%p)->(%p)\n", services, clientsite); if (!clientsite) return E_INVALIDARG; - return CreateOleClientSite(This, clientsite); + return CreateOleClientSite( services, clientsite ); } static HRESULT WINAPI -IRichEditOle_fnGetClipboardData(IRichEditOle *me, CHARRANGE *lpchrg, +IRichEditOle_fnGetClipboardData(IRichEditOle *iface, CHARRANGE *lpchrg, DWORD reco, LPDATAOBJECT *lplpdataobj) { - IRichEditOleImpl *This = impl_from_IRichEditOle(me); + struct text_services *services = impl_from_IRichEditOle( iface ); ME_Cursor start; int nChars; - TRACE("(%p,%p,%d)\n",This, lpchrg, reco); + TRACE("(%p,%p,%d)\n", services, lpchrg, reco); if(!lplpdataobj) return E_INVALIDARG; - if(!lpchrg) { - int nFrom, nTo, nStartCur = ME_GetSelectionOfs(This->editor, &nFrom, &nTo); - start = This->editor->pCursors[nStartCur]; + if(!lpchrg) + { + int nFrom, nTo, nStartCur = ME_GetSelectionOfs( services->editor, &nFrom, &nTo ); + start = services->editor->pCursors[nStartCur]; nChars = nTo - nFrom; - } else { - ME_CursorFromCharOfs(This->editor, lpchrg->cpMin, &start); + } + else + { + cursor_from_char_ofs( services->editor, lpchrg->cpMin, &start ); nChars = lpchrg->cpMax - lpchrg->cpMin; } - return ME_GetDataObject(This->editor, &start, nChars, lplpdataobj); + return ME_GetDataObject( services->editor, &start, nChars, lplpdataobj ); } -static LONG WINAPI IRichEditOle_fnGetLinkCount(IRichEditOle *me) +static LONG WINAPI IRichEditOle_fnGetLinkCount(IRichEditOle *iface) { - IRichEditOleImpl *This = impl_from_IRichEditOle(me); - FIXME("stub %p\n",This); + struct text_services *services = impl_from_IRichEditOle( iface ); + FIXME("stub %p\n", services); return E_NOTIMPL; } static HRESULT WINAPI -IRichEditOle_fnGetObject(IRichEditOle *me, LONG iob, +IRichEditOle_fnGetObject(IRichEditOle *iface, LONG iob, REOBJECT *lpreobject, DWORD dwFlags) { - IRichEditOleImpl *This = impl_from_IRichEditOle(me); + struct text_services *services = impl_from_IRichEditOle( iface ); struct re_object *reobj = NULL; LONG count = 0; - TRACE("(%p)->(%x, %p, %x)\n", This, iob, lpreobject, dwFlags); + TRACE("(%p)->(%x, %p, %x)\n", services, iob, lpreobject, dwFlags); if (!lpreobject || !lpreobject->cbStruct) return E_INVALIDARG; @@ -1393,27 +1291,27 @@ IRichEditOle_fnGetObject(IRichEditOle *me, LONG iob, ME_Cursor cursor; TRACE("character offset: %d\n", lpreobject->cp); - ME_CursorFromCharOfs(This->editor, lpreobject->cp, &cursor); - if (!cursor.pRun->member.run.reobj) + cursor_from_char_ofs( services->editor, lpreobject->cp, &cursor ); + if (!cursor.run->reobj) return E_INVALIDARG; else - reobj = cursor.pRun->member.run.reobj; + reobj = cursor.run->reobj; } else if (iob == REO_IOB_SELECTION) { ME_Cursor *from, *to; - ME_GetSelection(This->editor, &from, &to); - if (!from->pRun->member.run.reobj) + ME_GetSelection(services->editor, &from, &to); + if (!from->run->reobj) return E_INVALIDARG; else - reobj = from->pRun->member.run.reobj; + reobj = from->run->reobj; } else { - if (iob > IRichEditOle_GetObjectCount(me)) + if (iob < 0 || iob >= IRichEditOle_GetObjectCount( iface )) return E_INVALIDARG; - LIST_FOR_EACH_ENTRY(reobj, &This->editor->reobj_list, struct re_object, entry) + LIST_FOR_EACH_ENTRY(reobj, &services->editor->reobj_list, struct re_object, entry) { if (count == iob) break; @@ -1425,89 +1323,90 @@ IRichEditOle_fnGetObject(IRichEditOle *me, LONG iob, } static LONG WINAPI -IRichEditOle_fnGetObjectCount(IRichEditOle *me) +IRichEditOle_fnGetObjectCount( IRichEditOle *iface ) { - IRichEditOleImpl *This = impl_from_IRichEditOle(me); - TRACE("(%p)\n",This); - return list_count(&This->editor->reobj_list); + struct text_services *services = impl_from_IRichEditOle( iface ); + TRACE("(%p)\n", services); + return list_count( &services->editor->reobj_list ); } static HRESULT WINAPI -IRichEditOle_fnHandsOffStorage(IRichEditOle *me, LONG iob) +IRichEditOle_fnHandsOffStorage(IRichEditOle *iface, LONG iob) { - IRichEditOleImpl *This = impl_from_IRichEditOle(me); - FIXME("stub %p\n",This); + struct text_services *services = impl_from_IRichEditOle( iface ); + FIXME("stub %p\n", services); return E_NOTIMPL; } static HRESULT WINAPI -IRichEditOle_fnImportDataObject(IRichEditOle *me, LPDATAOBJECT lpdataobj, +IRichEditOle_fnImportDataObject(IRichEditOle *iface, LPDATAOBJECT lpdataobj, CLIPFORMAT cf, HGLOBAL hMetaPict) { - IRichEditOleImpl *This = impl_from_IRichEditOle(me); - FIXME("stub %p\n",This); + struct text_services *services = impl_from_IRichEditOle( iface ); + FIXME("stub %p\n", services); return E_NOTIMPL; } static HRESULT WINAPI -IRichEditOle_fnInPlaceDeactivate(IRichEditOle *me) +IRichEditOle_fnInPlaceDeactivate(IRichEditOle *iface) { - IRichEditOleImpl *This = impl_from_IRichEditOle(me); - FIXME("stub %p\n",This); + struct text_services *services = impl_from_IRichEditOle( iface ); + FIXME("stub %p\n", services); return E_NOTIMPL; } static HRESULT WINAPI -IRichEditOle_fnInsertObject(IRichEditOle *me, REOBJECT *reo) +IRichEditOle_fnInsertObject(IRichEditOle *iface, REOBJECT *reo) { - IRichEditOleImpl *This = impl_from_IRichEditOle(me); + struct text_services *services = impl_from_IRichEditOle( iface ); - TRACE("(%p,%p)\n", This, reo); + TRACE("(%p,%p)\n", services, reo); if (!reo) return E_INVALIDARG; if (reo->cbStruct < sizeof(*reo)) return STG_E_INVALIDPARAMETER; - ME_InsertOLEFromCursor(This->editor, reo, 0); - ME_CommitUndo(This->editor); - ME_UpdateRepaint(This->editor, FALSE); + ME_InsertOLEFromCursor(services->editor, reo, 0); + ME_CommitUndo(services->editor); + ME_UpdateRepaint(services->editor, FALSE); return S_OK; } -static HRESULT WINAPI IRichEditOle_fnSaveCompleted(IRichEditOle *me, LONG iob, +static HRESULT WINAPI IRichEditOle_fnSaveCompleted(IRichEditOle *iface, LONG iob, LPSTORAGE lpstg) { - IRichEditOleImpl *This = impl_from_IRichEditOle(me); - FIXME("stub %p\n",This); + struct text_services *services = impl_from_IRichEditOle( iface ); + FIXME("stub %p\n", services); return E_NOTIMPL; } static HRESULT WINAPI -IRichEditOle_fnSetDvaspect(IRichEditOle *me, LONG iob, DWORD dvaspect) +IRichEditOle_fnSetDvaspect(IRichEditOle *iface, LONG iob, DWORD dvaspect) { - IRichEditOleImpl *This = impl_from_IRichEditOle(me); - FIXME("stub %p\n",This); + struct text_services *services = impl_from_IRichEditOle( iface ); + FIXME("stub %p\n", services); return E_NOTIMPL; } -static HRESULT WINAPI IRichEditOle_fnSetHostNames(IRichEditOle *me, +static HRESULT WINAPI IRichEditOle_fnSetHostNames(IRichEditOle *iface, LPCSTR lpstrContainerApp, LPCSTR lpstrContainerObj) { - IRichEditOleImpl *This = impl_from_IRichEditOle(me); - FIXME("stub %p %s %s\n",This, lpstrContainerApp, lpstrContainerObj); + struct text_services *services = impl_from_IRichEditOle( iface ); + FIXME("stub %p %s %s\n", services, lpstrContainerApp, lpstrContainerObj); return E_NOTIMPL; } static HRESULT WINAPI -IRichEditOle_fnSetLinkAvailable(IRichEditOle *me, LONG iob, BOOL fAvailable) +IRichEditOle_fnSetLinkAvailable(IRichEditOle *iface, LONG iob, BOOL fAvailable) { - IRichEditOleImpl *This = impl_from_IRichEditOle(me); - FIXME("stub %p\n",This); + struct text_services *services = impl_from_IRichEditOle( iface ); + FIXME("stub %p\n", services); return E_NOTIMPL; } -static const IRichEditOleVtbl revt = { +const IRichEditOleVtbl re_ole_vtbl = +{ IRichEditOle_fnQueryInterface, IRichEditOle_fnAddRef, IRichEditOle_fnRelease, @@ -1655,15 +1554,15 @@ static HRESULT WINAPI ITextRange_fnGetText(ITextRange *me, BSTR *str) } editor = This->child.reole->editor; - ME_CursorFromCharOfs(editor, This->start, &start); - ME_CursorFromCharOfs(editor, This->end, &end); + cursor_from_char_ofs( editor, This->start, &start ); + cursor_from_char_ofs( editor, This->end, &end ); length = This->end - This->start; *str = SysAllocStringLen(NULL, length); if (!*str) return E_OUTOFMEMORY; - bEOP = (end.pRun->next->type == diTextEnd && This->end > ME_GetTextLength(editor)); + bEOP = (!para_next( para_next( end.para )) && This->end > ME_GetTextLength(editor)); ME_GetTextW(editor, *str, length, &start, length, FALSE, bEOP); return S_OK; } @@ -1684,12 +1583,14 @@ static HRESULT WINAPI ITextRange_fnSetText(ITextRange *me, BSTR str) editor = This->child.reole->editor; /* delete only where's something to delete */ - if (This->start != This->end) { - ME_CursorFromCharOfs(editor, This->start, &cursor); + if (This->start != This->end) + { + cursor_from_char_ofs( editor, This->start, &cursor ); ME_InternalDeleteText(editor, &cursor, This->end - This->start, FALSE); } - if (!str || !*str) { + if (!str || !*str) + { /* will update this range as well */ textranges_update_ranges(This->child.reole, This->start, This->end, RANGE_UPDATE_DELETE); return S_OK; @@ -1698,8 +1599,8 @@ static HRESULT WINAPI ITextRange_fnSetText(ITextRange *me, BSTR str) /* it's safer not to rely on stored BSTR length */ len = lstrlenW(str); cursor = editor->pCursors[0]; - ME_CursorFromCharOfs(editor, This->start, &editor->pCursors[0]); - style = ME_GetInsertStyle(editor, 0); + cursor_from_char_ofs( editor, This->start, &editor->pCursors[0] ); + style = style_get_insert_style( editor, editor->pCursors ); ME_InsertTextFromCursor(editor, 0, str, len, style); ME_ReleaseStyle(style); editor->pCursors[0] = cursor; @@ -1716,7 +1617,7 @@ static HRESULT range_GetChar(ME_TextEditor *editor, ME_Cursor *cursor, LONG *pch { WCHAR wch[2]; - ME_GetTextW(editor, wch, 1, cursor, 1, FALSE, cursor->pRun->next->type == diTextEnd); + ME_GetTextW(editor, wch, 1, cursor, 1, FALSE, !para_next( para_next( cursor->para ) )); *pch = wch[0]; return S_OK; @@ -1737,7 +1638,7 @@ static HRESULT WINAPI ITextRange_fnGetChar(ITextRange *me, LONG *pch) return E_INVALIDARG; editor = This->child.reole->editor; - ME_CursorFromCharOfs(editor, This->start, &cursor); + cursor_from_char_ofs( editor, This->start, &cursor ); return range_GetChar(editor, &cursor, pch); } @@ -1753,7 +1654,7 @@ static HRESULT WINAPI ITextRange_fnSetChar(ITextRange *me, LONG ch) return E_NOTIMPL; } -static HRESULT CreateITextRange(IRichEditOleImpl *reOle, LONG start, LONG end, ITextRange** ppRange); +static HRESULT CreateITextRange(struct text_services *services, LONG start, LONG end, ITextRange** ppRange); static HRESULT WINAPI ITextRange_fnGetDuplicate(ITextRange *me, ITextRange **ppRange) { @@ -1810,7 +1711,7 @@ static HRESULT WINAPI ITextRange_fnGetStart(ITextRange *me, LONG *start) return S_OK; } -static HRESULT textrange_setstart(const IRichEditOleImpl *reole, LONG value, LONG *start, LONG *end) +static HRESULT textrange_setstart(const struct text_services *services, LONG value, LONG *start, LONG *end) { int len; @@ -1825,7 +1726,7 @@ static HRESULT textrange_setstart(const IRichEditOleImpl *reole, LONG value, LON return S_OK; } - len = ME_GetTextLength(reole->editor); + len = ME_GetTextLength(services->editor); *start = *end = value > len ? len : value; return S_OK; } @@ -1858,7 +1759,7 @@ static HRESULT WINAPI ITextRange_fnGetEnd(ITextRange *me, LONG *end) return S_OK; } -static HRESULT textrange_setend(const IRichEditOleImpl *reole, LONG value, LONG *start, LONG *end) +static HRESULT textrange_setend(const struct text_services *services, LONG value, LONG *start, LONG *end) { int len; @@ -1870,7 +1771,7 @@ static HRESULT textrange_setend(const IRichEditOleImpl *reole, LONG value, LONG return S_OK; } - len = ME_GetTextLength(reole->editor); + len = ME_GetTextLength( services->editor ); *end = value > len ? len + 1 : value; return S_OK; } @@ -2056,7 +1957,7 @@ static HRESULT WINAPI ITextRange_fnSetRange(ITextRange *me, LONG anchor, LONG ac { ITextRangeImpl *This = impl_from_ITextRange(me); - FIXME("(%p)->(%d %d): stub\n", This, anchor, active); + TRACE("(%p)->(%d %d)\n", This, anchor, active); if (!This->child.reole) return CO_E_RELEASED; @@ -2161,17 +2062,89 @@ static HRESULT WINAPI ITextRange_fnSelect(ITextRange *me) return S_OK; } +static HRESULT textrange_startof(ITextRange *range, LONG unit, LONG extend, LONG *delta) +{ + HRESULT hr; + LONG start, end; + LONG moved; + + ITextRange_GetStart(range, &start); + ITextRange_GetEnd(range, &end); + + switch (unit) + { + case tomCharacter: + { + moved = 0; + if (extend == tomMove) { + if (start != end) { + ITextRange_SetEnd(range, start); + moved = -1; + } + } + if (delta) + *delta = moved; + hr = moved ? S_OK : S_FALSE; + break; + } + default: + FIXME("unit %d is not supported\n", unit); + return E_NOTIMPL; + } + return hr; +} + static HRESULT WINAPI ITextRange_fnStartOf(ITextRange *me, LONG unit, LONG extend, LONG *delta) { ITextRangeImpl *This = impl_from_ITextRange(me); - FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta); + TRACE("(%p)->(%d %d %p)\n", This, unit, extend, delta); if (!This->child.reole) return CO_E_RELEASED; - return E_NOTIMPL; + return textrange_startof(me, unit, extend, delta); +} + +static HRESULT textrange_endof(ITextRange *range, ME_TextEditor *editor, LONG unit, LONG extend, LONG *delta) +{ + HRESULT hr; + LONG old_start, old_end, new_end; + LONG moved; + + ITextRange_GetStart(range, &old_start); + ITextRange_GetEnd(range, &old_end); + + switch (unit) + { + case tomCharacter: + { + moved = 0; + new_end = old_end; + if (old_end == 0) + { + ME_Cursor cursor; + cursor_from_char_ofs( editor, old_end, &cursor ); + moved = ME_MoveCursorChars(editor, &cursor, 1, TRUE); + new_end = old_end + moved; + } + else if (extend == tomMove && old_start != old_end) + moved = 1; + + ITextRange_SetEnd(range, new_end); + if (extend == tomMove) + ITextRange_SetStart(range, new_end); + if (delta) + *delta = moved; + hr = moved ? S_OK : S_FALSE; + break; + } + default: + FIXME("unit %d is not supported\n", unit); + return E_NOTIMPL; + } + return hr; } static HRESULT WINAPI ITextRange_fnEndOf(ITextRange *me, LONG unit, LONG extend, @@ -2179,24 +2152,133 @@ static HRESULT WINAPI ITextRange_fnEndOf(ITextRange *me, LONG unit, LONG extend, { ITextRangeImpl *This = impl_from_ITextRange(me); - FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta); + TRACE("(%p)->(%d %d %p)\n", This, unit, extend, delta); if (!This->child.reole) return CO_E_RELEASED; - return E_NOTIMPL; + return textrange_endof(me, This->child.reole->editor, unit, extend, delta); +} + +static HRESULT textrange_move(ITextRange *range, ME_TextEditor *editor, LONG unit, LONG count, LONG *delta) +{ + LONG old_start, old_end, new_start, new_end; + LONG move_by; + LONG moved; + HRESULT hr = S_OK; + + if (!count) + { + if (delta) + *delta = 0; + return S_FALSE; + } + + ITextRange_GetStart(range, &old_start); + ITextRange_GetEnd(range, &old_end); + switch (unit) + { + case tomCharacter: + { + ME_Cursor cursor; + + if (count > 0) + { + cursor_from_char_ofs( editor, old_end, &cursor ); + move_by = count; + if (old_start != old_end) + --move_by; + } + else + { + cursor_from_char_ofs( editor, old_start, &cursor ); + move_by = count; + if (old_start != old_end) + ++move_by; + } + moved = ME_MoveCursorChars(editor, &cursor, move_by, FALSE); + if (count > 0) + { + new_end = old_end + moved; + new_start = new_end; + if (old_start != old_end) + ++moved; + } + else + { + new_start = old_start + moved; + new_end = new_start; + if (old_start != old_end) + --moved; + } + if (delta) *delta = moved; + break; + } + default: + FIXME("unit %d is not supported\n", unit); + return E_NOTIMPL; + } + if (moved == 0) + hr = S_FALSE; + ITextRange_SetStart(range, new_start); + ITextRange_SetEnd(range, new_end); + + return hr; } static HRESULT WINAPI ITextRange_fnMove(ITextRange *me, LONG unit, LONG count, LONG *delta) { ITextRangeImpl *This = impl_from_ITextRange(me); - FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta); + TRACE("(%p)->(%d %d %p)\n", This, unit, count, delta); if (!This->child.reole) return CO_E_RELEASED; - return E_NOTIMPL; + return textrange_move(me, This->child.reole->editor, unit, count, delta); +} + +static HRESULT textrange_movestart(ITextRange *range, ME_TextEditor *editor, LONG unit, LONG count, LONG *delta) +{ + LONG old_start, old_end, new_start, new_end; + HRESULT hr = S_OK; + + if (!count) + { + if (delta) + *delta = 0; + return S_FALSE; + } + + ITextRange_GetStart(range, &old_start); + ITextRange_GetEnd(range, &old_end); + switch (unit) + { + case tomCharacter: + { + ME_Cursor cursor; + LONG moved; + + cursor_from_char_ofs( editor, old_start, &cursor ); + moved = ME_MoveCursorChars(editor, &cursor, count, FALSE); + new_start = old_start + moved; + new_end = old_end; + if (new_end < new_start) + new_end = new_start; + if (delta) + *delta = moved; + break; + } + default: + FIXME("unit %d is not supported\n", unit); + return E_NOTIMPL; + } + if (new_start == old_start) + hr = S_FALSE; + ITextRange_SetStart(range, new_start); + ITextRange_SetEnd(range, new_end); + + return hr; } static HRESULT WINAPI ITextRange_fnMoveStart(ITextRange *me, LONG unit, LONG count, @@ -2204,15 +2286,15 @@ static HRESULT WINAPI ITextRange_fnMoveStart(ITextRange *me, LONG unit, LONG cou { ITextRangeImpl *This = impl_from_ITextRange(me); - FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta); + TRACE("(%p)->(%d %d %p)\n", This, unit, count, delta); if (!This->child.reole) return CO_E_RELEASED; - return E_NOTIMPL; + return textrange_movestart(me, This->child.reole->editor, unit, count, delta); } -static HRESULT textrange_moveend(ITextRange *range, LONG unit, LONG count, LONG *delta) +static HRESULT textrange_moveend(ITextRange *range, ME_TextEditor *editor, LONG unit, LONG count, LONG *delta) { LONG old_start, old_end, new_start, new_end; HRESULT hr = S_OK; @@ -2228,6 +2310,21 @@ static HRESULT textrange_moveend(ITextRange *range, LONG unit, LONG count, LONG ITextRange_GetEnd(range, &old_end); switch (unit) { + case tomCharacter: + { + ME_Cursor cursor; + LONG moved; + + cursor_from_char_ofs( editor, old_end, &cursor ); + moved = ME_MoveCursorChars(editor, &cursor, count, TRUE); + new_start = old_start; + new_end = old_end + moved; + if (new_end < new_start) + new_start = new_end; + if (delta) + *delta = moved; + break; + } case tomStory: if (count < 0) new_start = new_end = 0; @@ -2268,7 +2365,7 @@ static HRESULT WINAPI ITextRange_fnMoveEnd(ITextRange *me, LONG unit, LONG count if (!This->child.reole) return CO_E_RELEASED; - return textrange_moveend(me, unit, count, delta); + return textrange_moveend(me, This->child.reole->editor, unit, count, delta); } static HRESULT WINAPI ITextRange_fnMoveWhile(ITextRange *me, VARIANT *charset, LONG count, @@ -2400,28 +2497,53 @@ static HRESULT WINAPI ITextRange_fnDelete(ITextRange *me, LONG unit, LONG count, return E_NOTIMPL; } +static HRESULT textrange_copy_or_cut( ITextRange *range, ME_TextEditor *editor, BOOL cut, VARIANT *v ) +{ + LONG start, end; + ME_Cursor cursor; + IDataObject **data_out = NULL; + + ITextRange_GetStart( range, &start ); + ITextRange_GetEnd( range, &end ); + if (start == end) + { + /* If the range is empty, all text is copied */ + LONG prev_end = end; + ITextRange_SetEnd( range, MAXLONG ); + start = 0; + ITextRange_GetEnd( range, &end ); + ITextRange_SetEnd( range, prev_end ); + } + cursor_from_char_ofs( editor, start, &cursor ); + + if (v && V_VT(v) == (VT_UNKNOWN | VT_BYREF) && V_UNKNOWNREF( v )) + data_out = (IDataObject **)V_UNKNOWNREF( v ); + + return editor_copy_or_cut( editor, cut, &cursor, end - start, data_out ); +} + static HRESULT WINAPI ITextRange_fnCut(ITextRange *me, VARIANT *v) { ITextRangeImpl *This = impl_from_ITextRange(me); - FIXME("(%p)->(%p): stub\n", This, v); + TRACE("(%p)->(%p)\n", This, v); if (!This->child.reole) return CO_E_RELEASED; - return E_NOTIMPL; + return textrange_copy_or_cut(me, This->child.reole->editor, TRUE, v); } static HRESULT WINAPI ITextRange_fnCopy(ITextRange *me, VARIANT *v) { ITextRangeImpl *This = impl_from_ITextRange(me); - FIXME("(%p)->(%p): stub\n", This, v); + TRACE("(%p)->(%p)\n", This, v); if (!This->child.reole) return CO_E_RELEASED; - return E_NOTIMPL; + return textrange_copy_or_cut(me, This->child.reole->editor, FALSE, v); } static HRESULT WINAPI ITextRange_fnPaste(ITextRange *me, VARIANT *v, LONG format) @@ -2514,18 +2636,18 @@ static HRESULT WINAPI ITextRange_fnScrollIntoView(ITextRange *me, LONG value) switch (value) { case tomStart: - ME_CursorFromCharOfs(editor, This->start, &cursor); - ME_GetCursorCoordinates(editor, &cursor, &x, &y, &height); + cursor_from_char_ofs( editor, This->start, &cursor ); + cursor_coords( editor, &cursor, &x, &y, &height ); break; case tomEnd: - ME_CursorFromCharOfs(editor, This->end, &cursor); - ME_GetCursorCoordinates(editor, &cursor, &x, &y, &height); + cursor_from_char_ofs( editor, This->end, &cursor ); + cursor_coords( editor, &cursor, &x, &y, &height ); break; default: FIXME("bStart value %d not handled\n", value); return E_NOTIMPL; } - ME_ScrollAbs(editor, x, y); + scroll_abs( editor, x, y, TRUE ); return S_OK; } @@ -2785,9 +2907,8 @@ static void textfont_reset_to_default(ITextFontImpl *font) font->props[id].l = GetSystemDefaultLCID(); break; case FONT_NAME: { - static const WCHAR sysW[] = {'S','y','s','t','e','m',0}; SysFreeString(font->props[id].str); - font->props[id].str = SysAllocString(sysW); + font->props[id].str = SysAllocString(L"System"); break; } case FONT_WEIGHT: @@ -3430,16 +3551,6 @@ static ULONG WINAPI TextPara_Release(ITextPara *iface) return ref; } -static IRichEditOleImpl *para_get_reole(ITextParaImpl *This) -{ - if (This->range) - { - ITextRangeImpl *rng = impl_from_ITextRange(This->range); - return rng->child.reole; - } - return NULL; -} - static HRESULT WINAPI TextPara_GetTypeInfoCount(ITextPara *iface, UINT *pctinfo) { ITextParaImpl *This = impl_from_ITextPara(iface); @@ -3507,10 +3618,6 @@ static HRESULT WINAPI TextPara_GetDuplicate(ITextPara *iface, ITextPara **ret) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%p)\n", This, ret); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3518,10 +3625,6 @@ static HRESULT WINAPI TextPara_SetDuplicate(ITextPara *iface, ITextPara *para) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%p)\n", This, para); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3529,10 +3632,6 @@ static HRESULT WINAPI TextPara_CanChange(ITextPara *iface, LONG *ret) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%p)\n", This, ret); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3540,10 +3639,6 @@ static HRESULT WINAPI TextPara_IsEqual(ITextPara *iface, ITextPara *para, LONG * { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%p %p)\n", This, para, ret); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3551,10 +3646,6 @@ static HRESULT WINAPI TextPara_Reset(ITextPara *iface, LONG value) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%d)\n", This, value); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3562,10 +3653,6 @@ static HRESULT WINAPI TextPara_GetStyle(ITextPara *iface, LONG *value) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%p)\n", This, value); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3573,23 +3660,13 @@ static HRESULT WINAPI TextPara_SetStyle(ITextPara *iface, LONG value) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%d)\n", This, value); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } static HRESULT WINAPI TextPara_GetAlignment(ITextPara *iface, LONG *value) { ITextParaImpl *This = impl_from_ITextPara(iface); - static int once; - - if (!once++) FIXME("(%p)->(%p)\n", This, value); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - + FIXME("(%p)->(%p)\n", This, value); return E_NOTIMPL; } @@ -3597,10 +3674,6 @@ static HRESULT WINAPI TextPara_SetAlignment(ITextPara *iface, LONG value) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%d)\n", This, value); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3608,10 +3681,6 @@ static HRESULT WINAPI TextPara_GetHyphenation(ITextPara *iface, LONG *value) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%p)\n", This, value); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3619,10 +3688,6 @@ static HRESULT WINAPI TextPara_SetHyphenation(ITextPara *iface, LONG value) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%d)\n", This, value); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3630,10 +3695,6 @@ static HRESULT WINAPI TextPara_GetFirstLineIndent(ITextPara *iface, FLOAT *value { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%p)\n", This, value); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3641,10 +3702,6 @@ static HRESULT WINAPI TextPara_GetKeepTogether(ITextPara *iface, LONG *value) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%p)\n", This, value); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3652,10 +3709,6 @@ static HRESULT WINAPI TextPara_SetKeepTogether(ITextPara *iface, LONG value) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%d)\n", This, value); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3663,10 +3716,6 @@ static HRESULT WINAPI TextPara_GetKeepWithNext(ITextPara *iface, LONG *value) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%p)\n", This, value); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3674,10 +3723,6 @@ static HRESULT WINAPI TextPara_SetKeepWithNext(ITextPara *iface, LONG value) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%d)\n", This, value); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3685,10 +3730,6 @@ static HRESULT WINAPI TextPara_GetLeftIndent(ITextPara *iface, FLOAT *value) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%p)\n", This, value); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3696,10 +3737,6 @@ static HRESULT WINAPI TextPara_GetLineSpacing(ITextPara *iface, FLOAT *value) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%p)\n", This, value); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3707,10 +3744,6 @@ static HRESULT WINAPI TextPara_GetLineSpacingRule(ITextPara *iface, LONG *value) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%p)\n", This, value); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3718,10 +3751,6 @@ static HRESULT WINAPI TextPara_GetListAlignment(ITextPara *iface, LONG *value) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%p)\n", This, value); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3729,10 +3758,6 @@ static HRESULT WINAPI TextPara_SetListAlignment(ITextPara *iface, LONG value) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%d)\n", This, value); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3740,10 +3765,6 @@ static HRESULT WINAPI TextPara_GetListLevelIndex(ITextPara *iface, LONG *value) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%p)\n", This, value); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3751,10 +3772,6 @@ static HRESULT WINAPI TextPara_SetListLevelIndex(ITextPara *iface, LONG value) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%d)\n", This, value); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3762,10 +3779,6 @@ static HRESULT WINAPI TextPara_GetListStart(ITextPara *iface, LONG *value) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%p)\n", This, value); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3773,10 +3786,6 @@ static HRESULT WINAPI TextPara_SetListStart(ITextPara *iface, LONG value) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%d)\n", This, value); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3784,10 +3793,6 @@ static HRESULT WINAPI TextPara_GetListTab(ITextPara *iface, FLOAT *value) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%p)\n", This, value); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3795,10 +3800,6 @@ static HRESULT WINAPI TextPara_SetListTab(ITextPara *iface, FLOAT value) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%.2f)\n", This, value); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3806,10 +3807,6 @@ static HRESULT WINAPI TextPara_GetListType(ITextPara *iface, LONG *value) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%p)\n", This, value); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3817,10 +3814,6 @@ static HRESULT WINAPI TextPara_SetListType(ITextPara *iface, LONG value) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%d)\n", This, value); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3828,10 +3821,6 @@ static HRESULT WINAPI TextPara_GetNoLineNumber(ITextPara *iface, LONG *value) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%p)\n", This, value); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3839,10 +3828,6 @@ static HRESULT WINAPI TextPara_SetNoLineNumber(ITextPara *iface, LONG value) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%d)\n", This, value); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3850,10 +3835,6 @@ static HRESULT WINAPI TextPara_GetPageBreakBefore(ITextPara *iface, LONG *value) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%p)\n", This, value); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3861,10 +3842,6 @@ static HRESULT WINAPI TextPara_SetPageBreakBefore(ITextPara *iface, LONG value) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%d)\n", This, value); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3872,10 +3849,6 @@ static HRESULT WINAPI TextPara_GetRightIndent(ITextPara *iface, FLOAT *value) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%p)\n", This, value); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3883,10 +3856,6 @@ static HRESULT WINAPI TextPara_SetRightIndent(ITextPara *iface, FLOAT value) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%.2f)\n", This, value); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3894,10 +3863,6 @@ static HRESULT WINAPI TextPara_SetIndents(ITextPara *iface, FLOAT StartIndent, F { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%.2f %.2f %.2f)\n", This, StartIndent, LeftIndent, RightIndent); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3905,10 +3870,6 @@ static HRESULT WINAPI TextPara_SetLineSpacing(ITextPara *iface, LONG LineSpacing { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%d %.2f)\n", This, LineSpacingRule, LineSpacing); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3916,10 +3877,6 @@ static HRESULT WINAPI TextPara_GetSpaceAfter(ITextPara *iface, FLOAT *value) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%p)\n", This, value); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3927,10 +3884,6 @@ static HRESULT WINAPI TextPara_SetSpaceAfter(ITextPara *iface, FLOAT value) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%.2f)\n", This, value); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3938,10 +3891,6 @@ static HRESULT WINAPI TextPara_GetSpaceBefore(ITextPara *iface, FLOAT *value) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%p)\n", This, value); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3949,10 +3898,6 @@ static HRESULT WINAPI TextPara_SetSpaceBefore(ITextPara *iface, FLOAT value) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%.2f)\n", This, value); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3960,10 +3905,6 @@ static HRESULT WINAPI TextPara_GetWidowControl(ITextPara *iface, LONG *value) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%p)\n", This, value); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3971,10 +3912,6 @@ static HRESULT WINAPI TextPara_SetWidowControl(ITextPara *iface, LONG value) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%d)\n", This, value); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3982,10 +3919,6 @@ static HRESULT WINAPI TextPara_GetTabCount(ITextPara *iface, LONG *value) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%p)\n", This, value); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -3993,10 +3926,6 @@ static HRESULT WINAPI TextPara_AddTab(ITextPara *iface, FLOAT tbPos, LONG tbAlig { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%.2f %d %d)\n", This, tbPos, tbAlign, tbLeader); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -4004,10 +3933,6 @@ static HRESULT WINAPI TextPara_ClearAllTabs(ITextPara *iface) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)\n", This); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -4015,10 +3940,6 @@ static HRESULT WINAPI TextPara_DeleteTab(ITextPara *iface, FLOAT pos) { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%.2f)\n", This, pos); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -4026,10 +3947,6 @@ static HRESULT WINAPI TextPara_GetTab(ITextPara *iface, LONG iTab, FLOAT *ptbPos { ITextParaImpl *This = impl_from_ITextPara(iface); FIXME("(%p)->(%d %p %p %p)\n", This, iTab, ptbPos, ptbAlign, ptbLeader); - - if (!para_get_reole(This)) - return CO_E_RELEASED; - return E_NOTIMPL; } @@ -4113,27 +4030,27 @@ static HRESULT create_textpara(ITextRange *range, ITextPara **ret) static HRESULT WINAPI ITextDocument2Old_fnQueryInterface(ITextDocument2Old* iface, REFIID riid, void **ppvObject) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); - return IRichEditOle_QueryInterface(&This->IRichEditOle_iface, riid, ppvObject); + struct text_services *services = impl_from_ITextDocument2Old(iface); + return IUnknown_QueryInterface( services->outer_unk, riid, ppvObject ); } static ULONG WINAPI ITextDocument2Old_fnAddRef(ITextDocument2Old *iface) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); - return IRichEditOle_AddRef(&This->IRichEditOle_iface); + struct text_services *services = impl_from_ITextDocument2Old(iface); + return IUnknown_AddRef( services->outer_unk ); } static ULONG WINAPI ITextDocument2Old_fnRelease(ITextDocument2Old *iface) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); - return IRichEditOle_Release(&This->IRichEditOle_iface); + struct text_services *services = impl_from_ITextDocument2Old(iface); + return IUnknown_Release( services->outer_unk ); } static HRESULT WINAPI ITextDocument2Old_fnGetTypeInfoCount(ITextDocument2Old *iface, UINT *pctinfo) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); - TRACE("(%p)->(%p)\n", This, pctinfo); + struct text_services *services = impl_from_ITextDocument2Old(iface); + TRACE("(%p)->(%p)\n", services, pctinfo); *pctinfo = 1; return S_OK; } @@ -4141,10 +4058,10 @@ static HRESULT WINAPI ITextDocument2Old_fnGetTypeInfoCount(ITextDocument2Old *if static HRESULT WINAPI ITextDocument2Old_fnGetTypeInfo(ITextDocument2Old *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); + struct text_services *services = impl_from_ITextDocument2Old(iface); HRESULT hr; - TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo); + TRACE("(%p)->(%u,%d,%p)\n", services, iTInfo, lcid, ppTInfo); hr = get_typeinfo(ITextDocument_tid, ppTInfo); if (SUCCEEDED(hr)) @@ -4156,11 +4073,11 @@ static HRESULT WINAPI ITextDocument2Old_fnGetIDsOfNames(ITextDocument2Old *iface LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); + struct text_services *services = impl_from_ITextDocument2Old(iface); ITypeInfo *ti; HRESULT hr; - TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), + TRACE("(%p)->(%s, %p, %u, %d, %p)\n", services, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId); hr = get_typeinfo(ITextDocument_tid, &ti); @@ -4174,11 +4091,11 @@ static HRESULT WINAPI ITextDocument2Old_fnInvoke(ITextDocument2Old *iface, DISPI DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); + struct text_services *services = impl_from_ITextDocument2Old(iface); ITypeInfo *ti; HRESULT hr; - TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, + TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", services, dispIdMember, debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); @@ -4190,142 +4107,144 @@ static HRESULT WINAPI ITextDocument2Old_fnInvoke(ITextDocument2Old *iface, DISPI static HRESULT WINAPI ITextDocument2Old_fnGetName(ITextDocument2Old *iface, BSTR *pName) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); - FIXME("stub %p\n",This); + struct text_services *services = impl_from_ITextDocument2Old(iface); + FIXME("stub %p\n", services); return E_NOTIMPL; } static HRESULT WINAPI ITextDocument2Old_fnGetSelection(ITextDocument2Old *iface, ITextSelection **selection) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); + struct text_services *services = impl_from_ITextDocument2Old(iface); TRACE("(%p)->(%p)\n", iface, selection); if (!selection) return E_INVALIDARG; - if (!This->txtSel) { - This->txtSel = CreateTextSelection(This); - if (!This->txtSel) { - *selection = NULL; - return E_OUTOFMEMORY; - } + if (!services->text_selection) + { + services->text_selection = text_selection_create( services ); + if (!services->text_selection) + { + *selection = NULL; + return E_OUTOFMEMORY; + } } - *selection = &This->txtSel->ITextSelection_iface; + *selection = &services->text_selection->ITextSelection_iface; ITextSelection_AddRef(*selection); return S_OK; } static HRESULT WINAPI ITextDocument2Old_fnGetStoryCount(ITextDocument2Old *iface, LONG *pCount) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); - FIXME("stub %p\n",This); + struct text_services *services = impl_from_ITextDocument2Old(iface); + FIXME("stub %p\n", services); return E_NOTIMPL; } static HRESULT WINAPI ITextDocument2Old_fnGetStoryRanges(ITextDocument2Old *iface, ITextStoryRanges **ppStories) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); - FIXME("stub %p\n",This); + struct text_services *services = impl_from_ITextDocument2Old(iface); + FIXME("stub %p\n", services); return E_NOTIMPL; } static HRESULT WINAPI ITextDocument2Old_fnGetSaved(ITextDocument2Old *iface, LONG *pValue) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); - FIXME("stub %p\n",This); + struct text_services *services = impl_from_ITextDocument2Old(iface); + FIXME("stub %p\n", services); return E_NOTIMPL; } static HRESULT WINAPI ITextDocument2Old_fnSetSaved(ITextDocument2Old *iface, LONG Value) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); - FIXME("stub %p\n",This); + struct text_services *services = impl_from_ITextDocument2Old(iface); + FIXME("stub %p\n", services); return E_NOTIMPL; } static HRESULT WINAPI ITextDocument2Old_fnGetDefaultTabStop(ITextDocument2Old *iface, float *pValue) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); - FIXME("stub %p\n",This); + struct text_services *services = impl_from_ITextDocument2Old(iface); + FIXME("stub %p\n", services); return E_NOTIMPL; } static HRESULT WINAPI ITextDocument2Old_fnSetDefaultTabStop(ITextDocument2Old *iface, float Value) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); - FIXME("stub %p\n",This); + struct text_services *services = impl_from_ITextDocument2Old(iface); + FIXME("stub %p\n", services); return E_NOTIMPL; } static HRESULT WINAPI ITextDocument2Old_fnNew(ITextDocument2Old *iface) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); - FIXME("stub %p\n",This); + struct text_services *services = impl_from_ITextDocument2Old(iface); + FIXME("stub %p\n", services); return E_NOTIMPL; } static HRESULT WINAPI ITextDocument2Old_fnOpen(ITextDocument2Old *iface, VARIANT *pVar, LONG Flags, LONG CodePage) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); - FIXME("stub %p\n",This); + struct text_services *services = impl_from_ITextDocument2Old(iface); + FIXME("stub %p\n", services); return E_NOTIMPL; } static HRESULT WINAPI ITextDocument2Old_fnSave(ITextDocument2Old *iface, VARIANT *pVar, LONG Flags, LONG CodePage) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); - FIXME("stub %p\n",This); + struct text_services *services = impl_from_ITextDocument2Old(iface); + FIXME("stub %p\n", services); return E_NOTIMPL; } static HRESULT WINAPI ITextDocument2Old_fnFreeze(ITextDocument2Old *iface, LONG *pCount) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); - FIXME("stub %p\n",This); + struct text_services *services = impl_from_ITextDocument2Old(iface); + FIXME("stub %p\n", services); return E_NOTIMPL; } static HRESULT WINAPI ITextDocument2Old_fnUnfreeze(ITextDocument2Old *iface, LONG *pCount) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); - FIXME("stub %p\n",This); + struct text_services *services = impl_from_ITextDocument2Old(iface); + FIXME("stub %p\n", services); return E_NOTIMPL; } static HRESULT WINAPI ITextDocument2Old_fnBeginEditCollection(ITextDocument2Old *iface) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); - FIXME("stub %p\n",This); + struct text_services *services = impl_from_ITextDocument2Old(iface); + FIXME("stub %p\n", services); return E_NOTIMPL; } static HRESULT WINAPI ITextDocument2Old_fnEndEditCollection(ITextDocument2Old *iface) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); - FIXME("stub %p\n",This); + struct text_services *services = impl_from_ITextDocument2Old(iface); + FIXME("stub %p\n", services); return E_NOTIMPL; } static HRESULT WINAPI ITextDocument2Old_fnUndo(ITextDocument2Old *iface, LONG Count, LONG *prop) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); - FIXME("stub %p\n",This); + struct text_services *services = impl_from_ITextDocument2Old(iface); + FIXME("stub %p\n", services); return E_NOTIMPL; } static HRESULT WINAPI ITextDocument2Old_fnRedo(ITextDocument2Old *iface, LONG Count, LONG *prop) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); - FIXME("stub %p\n",This); + struct text_services *services = impl_from_ITextDocument2Old(iface); + FIXME("stub %p\n", services); return E_NOTIMPL; } -static HRESULT CreateITextRange(IRichEditOleImpl *reOle, LONG start, LONG end, ITextRange** ppRange) +static HRESULT CreateITextRange(struct text_services *services, LONG start, LONG end, ITextRange** ppRange) { ITextRangeImpl *txtRge = heap_alloc(sizeof(ITextRangeImpl)); @@ -4333,10 +4252,10 @@ static HRESULT CreateITextRange(IRichEditOleImpl *reOle, LONG start, LONG end, I return E_OUTOFMEMORY; txtRge->ITextRange_iface.lpVtbl = &trvt; txtRge->ref = 1; - txtRge->child.reole = reOle; + txtRge->child.reole = services; txtRge->start = start; txtRge->end = end; - list_add_head(&reOle->rangelist, &txtRge->child.entry); + list_add_head( &services->rangelist, &txtRge->child.entry ); *ppRange = &txtRge->ITextRange_iface; return S_OK; } @@ -4344,84 +4263,84 @@ static HRESULT CreateITextRange(IRichEditOleImpl *reOle, LONG start, LONG end, I static HRESULT WINAPI ITextDocument2Old_fnRange(ITextDocument2Old *iface, LONG cp1, LONG cp2, ITextRange **ppRange) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); + struct text_services *services = impl_from_ITextDocument2Old(iface); - TRACE("%p %p %d %d\n", This, ppRange, cp1, cp2); + TRACE("%p %p %d %d\n", services, ppRange, cp1, cp2); if (!ppRange) return E_INVALIDARG; - cp2range(This->editor, &cp1, &cp2); - return CreateITextRange(This, cp1, cp2, ppRange); + cp2range(services->editor, &cp1, &cp2); + return CreateITextRange(services, cp1, cp2, ppRange); } static HRESULT WINAPI ITextDocument2Old_fnRangeFromPoint(ITextDocument2Old *iface, LONG x, LONG y, ITextRange **ppRange) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); - FIXME("stub %p\n",This); + struct text_services *services = impl_from_ITextDocument2Old(iface); + FIXME("stub %p\n", services); return E_NOTIMPL; } /* ITextDocument2Old methods */ static HRESULT WINAPI ITextDocument2Old_fnAttachMsgFilter(ITextDocument2Old *iface, IUnknown *filter) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); + struct text_services *services = impl_from_ITextDocument2Old(iface); - FIXME("(%p)->(%p): stub\n", This, filter); + FIXME("(%p)->(%p): stub\n", services, filter); return E_NOTIMPL; } static HRESULT WINAPI ITextDocument2Old_fnSetEffectColor(ITextDocument2Old *iface, LONG index, COLORREF cr) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); + struct text_services *services = impl_from_ITextDocument2Old(iface); - FIXME("(%p)->(%d, 0x%x): stub\n", This, index, cr); + FIXME("(%p)->(%d, 0x%x): stub\n", services, index, cr); return E_NOTIMPL; } static HRESULT WINAPI ITextDocument2Old_fnGetEffectColor(ITextDocument2Old *iface, LONG index, COLORREF *cr) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); + struct text_services *services = impl_from_ITextDocument2Old(iface); - FIXME("(%p)->(%d, %p): stub\n", This, index, cr); + FIXME("(%p)->(%d, %p): stub\n", services, index, cr); return E_NOTIMPL; } static HRESULT WINAPI ITextDocument2Old_fnGetCaretType(ITextDocument2Old *iface, LONG *type) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); + struct text_services *services = impl_from_ITextDocument2Old(iface); - FIXME("(%p)->(%p): stub\n", This, type); + FIXME("(%p)->(%p): stub\n", services, type); return E_NOTIMPL; } static HRESULT WINAPI ITextDocument2Old_fnSetCaretType(ITextDocument2Old *iface, LONG type) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); + struct text_services *services = impl_from_ITextDocument2Old(iface); - FIXME("(%p)->(%d): stub\n", This, type); + FIXME("(%p)->(%d): stub\n", services, type); return E_NOTIMPL; } static HRESULT WINAPI ITextDocument2Old_fnGetImmContext(ITextDocument2Old *iface, LONG *context) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); + struct text_services *services = impl_from_ITextDocument2Old(iface); - FIXME("(%p)->(%p): stub\n", This, context); + FIXME("(%p)->(%p): stub\n", services, context); return E_NOTIMPL; } static HRESULT WINAPI ITextDocument2Old_fnReleaseImmContext(ITextDocument2Old *iface, LONG context) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); + struct text_services *services = impl_from_ITextDocument2Old(iface); - FIXME("(%p)->(%d): stub\n", This, context); + FIXME("(%p)->(%d): stub\n", services, context); return E_NOTIMPL; } @@ -4430,9 +4349,9 @@ static HRESULT WINAPI ITextDocument2Old_fnGetPreferredFont(ITextDocument2Old *if LONG options, LONG current_charrep, LONG current_fontsize, BSTR *bstr, LONG *pitch_family, LONG *new_fontsize) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); + struct text_services *services = impl_from_ITextDocument2Old(iface); - FIXME("(%p)->(%d, %d, %d, %d, %d, %p, %p, %p): stub\n", This, cp, charrep, options, current_charrep, + FIXME("(%p)->(%d, %d, %d, %d, %d, %p, %p, %p): stub\n", services, cp, charrep, options, current_charrep, current_fontsize, bstr, pitch_family, new_fontsize); return E_NOTIMPL; @@ -4440,18 +4359,18 @@ static HRESULT WINAPI ITextDocument2Old_fnGetPreferredFont(ITextDocument2Old *if static HRESULT WINAPI ITextDocument2Old_fnGetNotificationMode(ITextDocument2Old *iface, LONG *mode) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); + struct text_services *services = impl_from_ITextDocument2Old(iface); - FIXME("(%p)->(%p): stub\n", This, mode); + FIXME("(%p)->(%p): stub\n", services, mode); return E_NOTIMPL; } static HRESULT WINAPI ITextDocument2Old_fnSetNotificationMode(ITextDocument2Old *iface, LONG mode) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); + struct text_services *services = impl_from_ITextDocument2Old(iface); - FIXME("(%p)->(0x%x): stub\n", This, mode); + FIXME("(%p)->(0x%x): stub\n", services, mode); return E_NOTIMPL; } @@ -4459,95 +4378,96 @@ static HRESULT WINAPI ITextDocument2Old_fnSetNotificationMode(ITextDocument2Old static HRESULT WINAPI ITextDocument2Old_fnGetClientRect(ITextDocument2Old *iface, LONG type, LONG *left, LONG *top, LONG *right, LONG *bottom) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); + struct text_services *services = impl_from_ITextDocument2Old(iface); - FIXME("(%p)->(%d, %p, %p, %p, %p): stub\n", This, type, left, top, right, bottom); + FIXME("(%p)->(%d, %p, %p, %p, %p): stub\n", services, type, left, top, right, bottom); return E_NOTIMPL; } static HRESULT WINAPI ITextDocument2Old_fnGetSelectionEx(ITextDocument2Old *iface, ITextSelection **selection) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); + struct text_services *services = impl_from_ITextDocument2Old(iface); - FIXME("(%p)->(%p): stub\n", This, selection); + FIXME("(%p)->(%p): stub\n", services, selection); return E_NOTIMPL; } static HRESULT WINAPI ITextDocument2Old_fnGetWindow(ITextDocument2Old *iface, LONG *hwnd) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); + struct text_services *services = impl_from_ITextDocument2Old(iface); - FIXME("(%p)->(%p): stub\n", This, hwnd); + FIXME("(%p)->(%p): stub\n", services, hwnd); return E_NOTIMPL; } static HRESULT WINAPI ITextDocument2Old_fnGetFEFlags(ITextDocument2Old *iface, LONG *flags) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); + struct text_services *services = impl_from_ITextDocument2Old(iface); - FIXME("(%p)->(%p): stub\n", This, flags); + FIXME("(%p)->(%p): stub\n", services, flags); return E_NOTIMPL; } static HRESULT WINAPI ITextDocument2Old_fnUpdateWindow(ITextDocument2Old *iface) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); + struct text_services *services = impl_from_ITextDocument2Old(iface); - FIXME("(%p): stub\n", This); + FIXME("(%p): stub\n", services); return E_NOTIMPL; } static HRESULT WINAPI ITextDocument2Old_fnCheckTextLimit(ITextDocument2Old *iface, LONG cch, LONG *exceed) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); + struct text_services *services = impl_from_ITextDocument2Old(iface); - FIXME("(%p)->(%d, %p): stub\n", This, cch, exceed); + FIXME("(%p)->(%d, %p): stub\n", services, cch, exceed); return E_NOTIMPL; } static HRESULT WINAPI ITextDocument2Old_fnIMEInProgress(ITextDocument2Old *iface, LONG mode) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); + struct text_services *services = impl_from_ITextDocument2Old(iface); - FIXME("(%p)->(0x%x): stub\n", This, mode); + FIXME("(%p)->(0x%x): stub\n", services, mode); return E_NOTIMPL; } static HRESULT WINAPI ITextDocument2Old_fnSysBeep(ITextDocument2Old *iface) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); + struct text_services *services = impl_from_ITextDocument2Old(iface); - FIXME("(%p): stub\n", This); + FIXME("(%p): stub\n", services); return E_NOTIMPL; } static HRESULT WINAPI ITextDocument2Old_fnUpdate(ITextDocument2Old *iface, LONG mode) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); + struct text_services *services = impl_from_ITextDocument2Old(iface); - FIXME("(%p)->(0x%x): stub\n", This, mode); + FIXME("(%p)->(0x%x): stub\n", services, mode); return E_NOTIMPL; } static HRESULT WINAPI ITextDocument2Old_fnNotify(ITextDocument2Old *iface, LONG notify) { - IRichEditOleImpl *This = impl_from_ITextDocument2Old(iface); + struct text_services *services = impl_from_ITextDocument2Old(iface); - FIXME("(%p)->(%d): stub\n", This, notify); + FIXME("(%p)->(%d): stub\n", services, notify); return E_NOTIMPL; } -static const ITextDocument2OldVtbl tdvt = { +const ITextDocument2OldVtbl text_doc2old_vtbl = +{ ITextDocument2Old_fnQueryInterface, ITextDocument2Old_fnAddRef, ITextDocument2Old_fnRelease, @@ -4603,7 +4523,7 @@ static HRESULT WINAPI ITextSelection_fnQueryInterface( REFIID riid, void **ppvObj) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); *ppvObj = NULL; if (IsEqualGUID(riid, &IID_IUnknown) @@ -4617,7 +4537,7 @@ static HRESULT WINAPI ITextSelection_fnQueryInterface( } else if (IsEqualGUID(riid, &IID_Igetrichole)) { - *ppvObj = This->reOle; + *ppvObj = This->services; return S_OK; } @@ -4626,13 +4546,13 @@ static HRESULT WINAPI ITextSelection_fnQueryInterface( static ULONG WINAPI ITextSelection_fnAddRef(ITextSelection *me) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); return InterlockedIncrement(&This->ref); } static ULONG WINAPI ITextSelection_fnRelease(ITextSelection *me) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); ULONG ref = InterlockedDecrement(&This->ref); if (ref == 0) heap_free(This); @@ -4641,7 +4561,7 @@ static ULONG WINAPI ITextSelection_fnRelease(ITextSelection *me) static HRESULT WINAPI ITextSelection_fnGetTypeInfoCount(ITextSelection *me, UINT *pctinfo) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); TRACE("(%p)->(%p)\n", This, pctinfo); *pctinfo = 1; return S_OK; @@ -4650,7 +4570,7 @@ static HRESULT WINAPI ITextSelection_fnGetTypeInfoCount(ITextSelection *me, UINT static HRESULT WINAPI ITextSelection_fnGetTypeInfo(ITextSelection *me, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); HRESULT hr; TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo); @@ -4664,7 +4584,7 @@ static HRESULT WINAPI ITextSelection_fnGetTypeInfo(ITextSelection *me, UINT iTIn static HRESULT WINAPI ITextSelection_fnGetIDsOfNames(ITextSelection *me, REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); ITypeInfo *ti; HRESULT hr; @@ -4688,7 +4608,7 @@ static HRESULT WINAPI ITextSelection_fnInvoke( EXCEPINFO *pExcepInfo, UINT *puArgErr) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); ITypeInfo *ti; HRESULT hr; @@ -4704,20 +4624,20 @@ static HRESULT WINAPI ITextSelection_fnInvoke( /*** ITextRange methods ***/ static HRESULT WINAPI ITextSelection_fnGetText(ITextSelection *me, BSTR *pbstr) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); ME_Cursor *start = NULL, *end = NULL; int nChars, endOfs; BOOL bEOP; TRACE("(%p)->(%p)\n", This, pbstr); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; if (!pbstr) return E_INVALIDARG; - ME_GetSelection(This->reOle->editor, &start, &end); + ME_GetSelection(This->services->editor, &start, &end); endOfs = ME_GetCursorOfs(end); nChars = endOfs - ME_GetCursorOfs(start); if (!nChars) @@ -4730,8 +4650,8 @@ static HRESULT WINAPI ITextSelection_fnGetText(ITextSelection *me, BSTR *pbstr) if (!*pbstr) return E_OUTOFMEMORY; - bEOP = (end->pRun->next->type == diTextEnd && endOfs > ME_GetTextLength(This->reOle->editor)); - ME_GetTextW(This->reOle->editor, *pbstr, nChars, start, nChars, FALSE, bEOP); + bEOP = (!para_next( para_next( end->para ) ) && endOfs > ME_GetTextLength(This->services->editor)); + ME_GetTextW(This->services->editor, *pbstr, nChars, start, nChars, FALSE, bEOP); TRACE("%s\n", wine_dbgstr_w(*pbstr)); return S_OK; @@ -4739,50 +4659,50 @@ static HRESULT WINAPI ITextSelection_fnGetText(ITextSelection *me, BSTR *pbstr) static HRESULT WINAPI ITextSelection_fnSetText(ITextSelection *me, BSTR str) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); ME_TextEditor *editor; int len, to, from; TRACE("(%p)->(%s)\n", This, debugstr_w(str)); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; - editor = This->reOle->editor; + editor = This->services->editor; len = lstrlenW(str); ME_GetSelectionOfs(editor, &from, &to); ME_ReplaceSel(editor, FALSE, str, len); if (len < to - from) - textranges_update_ranges(This->reOle, from, len, RANGE_UPDATE_DELETE); + textranges_update_ranges(This->services, from, len, RANGE_UPDATE_DELETE); return S_OK; } static HRESULT WINAPI ITextSelection_fnGetChar(ITextSelection *me, LONG *pch) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); ME_Cursor *start = NULL, *end = NULL; TRACE("(%p)->(%p)\n", This, pch); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; if (!pch) return E_INVALIDARG; - ME_GetSelection(This->reOle->editor, &start, &end); - return range_GetChar(This->reOle->editor, start, pch); + ME_GetSelection(This->services->editor, &start, &end); + return range_GetChar(This->services->editor, start, pch); } static HRESULT WINAPI ITextSelection_fnSetChar(ITextSelection *me, LONG ch) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); FIXME("(%p)->(%x): stub\n", This, ch); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; return E_NOTIMPL; @@ -4790,12 +4710,12 @@ static HRESULT WINAPI ITextSelection_fnSetChar(ITextSelection *me, LONG ch) static HRESULT WINAPI ITextSelection_fnGetDuplicate(ITextSelection *me, ITextRange **range) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); LONG start, end; TRACE("(%p)->(%p)\n", This, range); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; if (!range) @@ -4803,16 +4723,16 @@ static HRESULT WINAPI ITextSelection_fnGetDuplicate(ITextSelection *me, ITextRan ITextSelection_GetStart(me, &start); ITextSelection_GetEnd(me, &end); - return CreateITextRange(This->reOle, start, end, range); + return CreateITextRange(This->services, start, end, range); } static HRESULT WINAPI ITextSelection_fnGetFormattedText(ITextSelection *me, ITextRange **range) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); FIXME("(%p)->(%p): stub\n", This, range); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; return E_NOTIMPL; @@ -4820,11 +4740,11 @@ static HRESULT WINAPI ITextSelection_fnGetFormattedText(ITextSelection *me, ITex static HRESULT WINAPI ITextSelection_fnSetFormattedText(ITextSelection *me, ITextRange *range) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); FIXME("(%p)->(%p): stub\n", This, range); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; FIXME("not implemented\n"); @@ -4833,83 +4753,83 @@ static HRESULT WINAPI ITextSelection_fnSetFormattedText(ITextSelection *me, ITex static HRESULT WINAPI ITextSelection_fnGetStart(ITextSelection *me, LONG *pcpFirst) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); LONG lim; TRACE("(%p)->(%p)\n", This, pcpFirst); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; if (!pcpFirst) return E_INVALIDARG; - ME_GetSelectionOfs(This->reOle->editor, pcpFirst, &lim); + ME_GetSelectionOfs(This->services->editor, pcpFirst, &lim); return S_OK; } static HRESULT WINAPI ITextSelection_fnSetStart(ITextSelection *me, LONG value) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); LONG start, end; HRESULT hr; TRACE("(%p)->(%d)\n", This, value); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; - ME_GetSelectionOfs(This->reOle->editor, &start, &end); - hr = textrange_setstart(This->reOle, value, &start, &end); + ME_GetSelectionOfs(This->services->editor, &start, &end); + hr = textrange_setstart(This->services, value, &start, &end); if (hr == S_OK) - set_selection(This->reOle->editor, start, end); + set_selection(This->services->editor, start, end); return hr; } static HRESULT WINAPI ITextSelection_fnGetEnd(ITextSelection *me, LONG *pcpLim) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); LONG first; TRACE("(%p)->(%p)\n", This, pcpLim); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; if (!pcpLim) return E_INVALIDARG; - ME_GetSelectionOfs(This->reOle->editor, &first, pcpLim); + ME_GetSelectionOfs(This->services->editor, &first, pcpLim); return S_OK; } static HRESULT WINAPI ITextSelection_fnSetEnd(ITextSelection *me, LONG value) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); LONG start, end; HRESULT hr; TRACE("(%p)->(%d)\n", This, value); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; - ME_GetSelectionOfs(This->reOle->editor, &start, &end); - hr = textrange_setend(This->reOle, value, &start, &end); + ME_GetSelectionOfs(This->services->editor, &start, &end); + hr = textrange_setend(This->services, value, &start, &end); if (hr == S_OK) - set_selection(This->reOle->editor, start, end); + set_selection(This->services->editor, start, end); return hr; } static HRESULT WINAPI ITextSelection_fnGetFont(ITextSelection *me, ITextFont **font) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); ITextRange *range = NULL; HRESULT hr; TRACE("(%p)->(%p)\n", This, font); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; if (!font) @@ -4923,7 +4843,7 @@ static HRESULT WINAPI ITextSelection_fnGetFont(ITextSelection *me, ITextFont **f static HRESULT WINAPI ITextSelection_fnSetFont(ITextSelection *me, ITextFont *font) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); ITextRange *range = NULL; TRACE("(%p)->(%p)\n", This, font); @@ -4931,7 +4851,7 @@ static HRESULT WINAPI ITextSelection_fnSetFont(ITextSelection *me, ITextFont *fo if (!font) return E_INVALIDARG; - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range); @@ -4942,13 +4862,13 @@ static HRESULT WINAPI ITextSelection_fnSetFont(ITextSelection *me, ITextFont *fo static HRESULT WINAPI ITextSelection_fnGetPara(ITextSelection *me, ITextPara **para) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); ITextRange *range = NULL; HRESULT hr; TRACE("(%p)->(%p)\n", This, para); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; if (!para) @@ -4962,11 +4882,11 @@ static HRESULT WINAPI ITextSelection_fnGetPara(ITextSelection *me, ITextPara **p static HRESULT WINAPI ITextSelection_fnSetPara(ITextSelection *me, ITextPara *para) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); FIXME("(%p)->(%p): stub\n", This, para); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; FIXME("not implemented\n"); @@ -4975,23 +4895,23 @@ static HRESULT WINAPI ITextSelection_fnSetPara(ITextSelection *me, ITextPara *pa static HRESULT WINAPI ITextSelection_fnGetStoryLength(ITextSelection *me, LONG *length) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); TRACE("(%p)->(%p)\n", This, length); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; - return textrange_get_storylength(This->reOle->editor, length); + return textrange_get_storylength(This->services->editor, length); } static HRESULT WINAPI ITextSelection_fnGetStoryType(ITextSelection *me, LONG *value) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); TRACE("(%p)->(%p)\n", This, value); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; if (!value) @@ -5003,31 +4923,31 @@ static HRESULT WINAPI ITextSelection_fnGetStoryType(ITextSelection *me, LONG *va static HRESULT WINAPI ITextSelection_fnCollapse(ITextSelection *me, LONG bStart) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); LONG start, end; HRESULT hres; TRACE("(%p)->(%d)\n", This, bStart); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; - ME_GetSelectionOfs(This->reOle->editor, &start, &end); + ME_GetSelectionOfs(This->services->editor, &start, &end); hres = range_Collapse(bStart, &start, &end); if (SUCCEEDED(hres)) - set_selection(This->reOle->editor, start, end); + set_selection(This->services->editor, start, end); return hres; } static HRESULT WINAPI ITextSelection_fnExpand(ITextSelection *me, LONG unit, LONG *delta) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); ITextRange *range = NULL; HRESULT hr; TRACE("(%p)->(%d %p)\n", This, unit, delta); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range); @@ -5038,11 +4958,11 @@ static HRESULT WINAPI ITextSelection_fnExpand(ITextSelection *me, LONG unit, LON static HRESULT WINAPI ITextSelection_fnGetIndex(ITextSelection *me, LONG unit, LONG *index) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); FIXME("(%p)->(%d %p): stub\n", This, unit, index); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; return E_NOTIMPL; @@ -5051,11 +4971,11 @@ static HRESULT WINAPI ITextSelection_fnGetIndex(ITextSelection *me, LONG unit, L static HRESULT WINAPI ITextSelection_fnSetIndex(ITextSelection *me, LONG unit, LONG index, LONG extend) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); FIXME("(%p)->(%d %d %d): stub\n", This, unit, index, extend); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; return E_NOTIMPL; @@ -5063,11 +4983,11 @@ static HRESULT WINAPI ITextSelection_fnSetIndex(ITextSelection *me, LONG unit, L static HRESULT WINAPI ITextSelection_fnSetRange(ITextSelection *me, LONG anchor, LONG active) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); FIXME("(%p)->(%d %d): stub\n", This, anchor, active); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; return E_NOTIMPL; @@ -5075,7 +4995,7 @@ static HRESULT WINAPI ITextSelection_fnSetRange(ITextSelection *me, LONG anchor, static HRESULT WINAPI ITextSelection_fnInRange(ITextSelection *me, ITextRange *range, LONG *ret) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); ITextSelection *selection = NULL; LONG start, end; @@ -5084,7 +5004,7 @@ static HRESULT WINAPI ITextSelection_fnInRange(ITextSelection *me, ITextRange *r if (ret) *ret = tomFalse; - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; if (!range) @@ -5102,11 +5022,11 @@ static HRESULT WINAPI ITextSelection_fnInRange(ITextSelection *me, ITextRange *r static HRESULT WINAPI ITextSelection_fnInStory(ITextSelection *me, ITextRange *range, LONG *ret) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); FIXME("(%p)->(%p %p): stub\n", This, range, ret); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; return E_NOTIMPL; @@ -5114,7 +5034,7 @@ static HRESULT WINAPI ITextSelection_fnInStory(ITextSelection *me, ITextRange *r static HRESULT WINAPI ITextSelection_fnIsEqual(ITextSelection *me, ITextRange *range, LONG *ret) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); ITextSelection *selection = NULL; LONG start, end; @@ -5123,7 +5043,7 @@ static HRESULT WINAPI ITextSelection_fnIsEqual(ITextSelection *me, ITextRange *r if (ret) *ret = tomFalse; - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; if (!range) @@ -5141,11 +5061,11 @@ static HRESULT WINAPI ITextSelection_fnIsEqual(ITextSelection *me, ITextRange *r static HRESULT WINAPI ITextSelection_fnSelect(ITextSelection *me) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); TRACE("(%p)\n", This); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; /* nothing to do */ @@ -5155,68 +5075,88 @@ static HRESULT WINAPI ITextSelection_fnSelect(ITextSelection *me) static HRESULT WINAPI ITextSelection_fnStartOf(ITextSelection *me, LONG unit, LONG extend, LONG *delta) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); + ITextRange *range = NULL; + HRESULT hr; - FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta); + TRACE("(%p)->(%d %d %p)\n", This, unit, extend, delta); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; - return E_NOTIMPL; + ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range); + hr = textrange_startof(range, unit, extend, delta); + ITextRange_Release(range); + return hr; } static HRESULT WINAPI ITextSelection_fnEndOf(ITextSelection *me, LONG unit, LONG extend, LONG *delta) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); + ITextRange *range = NULL; + HRESULT hr; - FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta); + TRACE("(%p)->(%d %d %p)\n", This, unit, extend, delta); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; - return E_NOTIMPL; + ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range); + hr = textrange_endof(range, This->services->editor, unit, extend, delta); + ITextRange_Release(range); + return hr; } static HRESULT WINAPI ITextSelection_fnMove(ITextSelection *me, LONG unit, LONG count, LONG *delta) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); + ITextRange *range = NULL; + HRESULT hr; - FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta); + TRACE("(%p)->(%d %d %p)\n", This, unit, count, delta); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; - return E_NOTIMPL; + ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range); + hr = textrange_movestart(range, This->services->editor, unit, count, delta); + ITextRange_Release(range); + return hr; } static HRESULT WINAPI ITextSelection_fnMoveStart(ITextSelection *me, LONG unit, LONG count, LONG *delta) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); + ITextRange *range = NULL; + HRESULT hr; - FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta); + TRACE("(%p)->(%d %d %p)\n", This, unit, count, delta); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; - return E_NOTIMPL; + ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range); + hr = textrange_movestart(range, This->services->editor, unit, count, delta); + ITextRange_Release(range); + return hr; } static HRESULT WINAPI ITextSelection_fnMoveEnd(ITextSelection *me, LONG unit, LONG count, LONG *delta) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); ITextRange *range = NULL; HRESULT hr; TRACE("(%p)->(%d %d %p)\n", This, unit, count, delta); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range); - hr = textrange_moveend(range, unit, count, delta); + hr = textrange_moveend(range, This->services->editor, unit, count, delta); ITextRange_Release(range); return hr; } @@ -5224,11 +5164,11 @@ static HRESULT WINAPI ITextSelection_fnMoveEnd(ITextSelection *me, LONG unit, LO static HRESULT WINAPI ITextSelection_fnMoveWhile(ITextSelection *me, VARIANT *charset, LONG count, LONG *delta) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; return E_NOTIMPL; @@ -5237,11 +5177,11 @@ static HRESULT WINAPI ITextSelection_fnMoveWhile(ITextSelection *me, VARIANT *ch static HRESULT WINAPI ITextSelection_fnMoveStartWhile(ITextSelection *me, VARIANT *charset, LONG count, LONG *delta) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; return E_NOTIMPL; @@ -5250,11 +5190,11 @@ static HRESULT WINAPI ITextSelection_fnMoveStartWhile(ITextSelection *me, VARIAN static HRESULT WINAPI ITextSelection_fnMoveEndWhile(ITextSelection *me, VARIANT *charset, LONG count, LONG *delta) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; return E_NOTIMPL; @@ -5263,11 +5203,11 @@ static HRESULT WINAPI ITextSelection_fnMoveEndWhile(ITextSelection *me, VARIANT static HRESULT WINAPI ITextSelection_fnMoveUntil(ITextSelection *me, VARIANT *charset, LONG count, LONG *delta) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; return E_NOTIMPL; @@ -5276,11 +5216,11 @@ static HRESULT WINAPI ITextSelection_fnMoveUntil(ITextSelection *me, VARIANT *ch static HRESULT WINAPI ITextSelection_fnMoveStartUntil(ITextSelection *me, VARIANT *charset, LONG count, LONG *delta) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; return E_NOTIMPL; @@ -5289,11 +5229,11 @@ static HRESULT WINAPI ITextSelection_fnMoveStartUntil(ITextSelection *me, VARIAN static HRESULT WINAPI ITextSelection_fnMoveEndUntil(ITextSelection *me, VARIANT *charset, LONG count, LONG *delta) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; return E_NOTIMPL; @@ -5302,11 +5242,11 @@ static HRESULT WINAPI ITextSelection_fnMoveEndUntil(ITextSelection *me, VARIANT static HRESULT WINAPI ITextSelection_fnFindText(ITextSelection *me, BSTR text, LONG count, LONG flags, LONG *length) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; FIXME("not implemented\n"); @@ -5316,11 +5256,11 @@ static HRESULT WINAPI ITextSelection_fnFindText(ITextSelection *me, BSTR text, L static HRESULT WINAPI ITextSelection_fnFindTextStart(ITextSelection *me, BSTR text, LONG count, LONG flags, LONG *length) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; return E_NOTIMPL; @@ -5329,11 +5269,11 @@ static HRESULT WINAPI ITextSelection_fnFindTextStart(ITextSelection *me, BSTR te static HRESULT WINAPI ITextSelection_fnFindTextEnd(ITextSelection *me, BSTR text, LONG count, LONG flags, LONG *length) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; return E_NOTIMPL; @@ -5342,11 +5282,11 @@ static HRESULT WINAPI ITextSelection_fnFindTextEnd(ITextSelection *me, BSTR text static HRESULT WINAPI ITextSelection_fnDelete(ITextSelection *me, LONG unit, LONG count, LONG *delta) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; return E_NOTIMPL; @@ -5354,35 +5294,45 @@ static HRESULT WINAPI ITextSelection_fnDelete(ITextSelection *me, LONG unit, LON static HRESULT WINAPI ITextSelection_fnCut(ITextSelection *me, VARIANT *v) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); + ITextRange *range = NULL; + HRESULT hr; - FIXME("(%p)->(%p): stub\n", This, v); + TRACE("(%p)->(%p): stub\n", This, v); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; - return E_NOTIMPL; + ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range); + hr = textrange_copy_or_cut(range, This->services->editor, TRUE, v); + ITextRange_Release(range); + return hr; } static HRESULT WINAPI ITextSelection_fnCopy(ITextSelection *me, VARIANT *v) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); + ITextRange *range = NULL; + HRESULT hr; - FIXME("(%p)->(%p): stub\n", This, v); + TRACE("(%p)->(%p)\n", This, v); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; - return E_NOTIMPL; + ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range); + hr = textrange_copy_or_cut(range, This->services->editor, FALSE, v); + ITextRange_Release(range); + return hr; } static HRESULT WINAPI ITextSelection_fnPaste(ITextSelection *me, VARIANT *v, LONG format) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); FIXME("(%p)->(%s %x): stub\n", This, debugstr_variant(v), format); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; return E_NOTIMPL; @@ -5391,11 +5341,11 @@ static HRESULT WINAPI ITextSelection_fnPaste(ITextSelection *me, VARIANT *v, LON static HRESULT WINAPI ITextSelection_fnCanPaste(ITextSelection *me, VARIANT *v, LONG format, LONG *ret) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); FIXME("(%p)->(%s %x %p): stub\n", This, debugstr_variant(v), format, ret); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; return E_NOTIMPL; @@ -5403,11 +5353,11 @@ static HRESULT WINAPI ITextSelection_fnCanPaste(ITextSelection *me, VARIANT *v, static HRESULT WINAPI ITextSelection_fnCanEdit(ITextSelection *me, LONG *ret) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); FIXME("(%p)->(%p): stub\n", This, ret); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; return E_NOTIMPL; @@ -5415,11 +5365,11 @@ static HRESULT WINAPI ITextSelection_fnCanEdit(ITextSelection *me, LONG *ret) static HRESULT WINAPI ITextSelection_fnChangeCase(ITextSelection *me, LONG type) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); FIXME("(%p)->(%d): stub\n", This, type); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; return E_NOTIMPL; @@ -5427,11 +5377,11 @@ static HRESULT WINAPI ITextSelection_fnChangeCase(ITextSelection *me, LONG type) static HRESULT WINAPI ITextSelection_fnGetPoint(ITextSelection *me, LONG type, LONG *cx, LONG *cy) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); FIXME("(%p)->(%d %p %p): stub\n", This, type, cx, cy); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; return E_NOTIMPL; @@ -5440,11 +5390,11 @@ static HRESULT WINAPI ITextSelection_fnGetPoint(ITextSelection *me, LONG type, L static HRESULT WINAPI ITextSelection_fnSetPoint(ITextSelection *me, LONG x, LONG y, LONG type, LONG extend) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); FIXME("(%p)->(%d %d %d %d): stub\n", This, x, y, type, extend); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; return E_NOTIMPL; @@ -5452,11 +5402,11 @@ static HRESULT WINAPI ITextSelection_fnSetPoint(ITextSelection *me, LONG x, LONG static HRESULT WINAPI ITextSelection_fnScrollIntoView(ITextSelection *me, LONG value) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); FIXME("(%p)->(%d): stub\n", This, value); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; return E_NOTIMPL; @@ -5464,11 +5414,11 @@ static HRESULT WINAPI ITextSelection_fnScrollIntoView(ITextSelection *me, LONG v static HRESULT WINAPI ITextSelection_fnGetEmbeddedObject(ITextSelection *me, IUnknown **ppv) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); FIXME("(%p)->(%p): stub\n", This, ppv); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; return E_NOTIMPL; @@ -5477,11 +5427,11 @@ static HRESULT WINAPI ITextSelection_fnGetEmbeddedObject(ITextSelection *me, IUn /*** ITextSelection methods ***/ static HRESULT WINAPI ITextSelection_fnGetFlags(ITextSelection *me, LONG *flags) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); FIXME("(%p)->(%p): stub\n", This, flags); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; return E_NOTIMPL; @@ -5489,11 +5439,11 @@ static HRESULT WINAPI ITextSelection_fnGetFlags(ITextSelection *me, LONG *flags) static HRESULT WINAPI ITextSelection_fnSetFlags(ITextSelection *me, LONG flags) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); FIXME("(%p)->(%x): stub\n", This, flags); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; return E_NOTIMPL; @@ -5501,11 +5451,11 @@ static HRESULT WINAPI ITextSelection_fnSetFlags(ITextSelection *me, LONG flags) static HRESULT WINAPI ITextSelection_fnGetType(ITextSelection *me, LONG *type) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); FIXME("(%p)->(%p): stub\n", This, type); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; return E_NOTIMPL; @@ -5514,11 +5464,11 @@ static HRESULT WINAPI ITextSelection_fnGetType(ITextSelection *me, LONG *type) static HRESULT WINAPI ITextSelection_fnMoveLeft(ITextSelection *me, LONG unit, LONG count, LONG extend, LONG *delta) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; return E_NOTIMPL; @@ -5527,11 +5477,11 @@ static HRESULT WINAPI ITextSelection_fnMoveLeft(ITextSelection *me, LONG unit, L static HRESULT WINAPI ITextSelection_fnMoveRight(ITextSelection *me, LONG unit, LONG count, LONG extend, LONG *delta) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; return E_NOTIMPL; @@ -5540,11 +5490,11 @@ static HRESULT WINAPI ITextSelection_fnMoveRight(ITextSelection *me, LONG unit, static HRESULT WINAPI ITextSelection_fnMoveUp(ITextSelection *me, LONG unit, LONG count, LONG extend, LONG *delta) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; return E_NOTIMPL; @@ -5553,11 +5503,11 @@ static HRESULT WINAPI ITextSelection_fnMoveUp(ITextSelection *me, LONG unit, LON static HRESULT WINAPI ITextSelection_fnMoveDown(ITextSelection *me, LONG unit, LONG count, LONG extend, LONG *delta) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; return E_NOTIMPL; @@ -5566,11 +5516,11 @@ static HRESULT WINAPI ITextSelection_fnMoveDown(ITextSelection *me, LONG unit, L static HRESULT WINAPI ITextSelection_fnHomeKey(ITextSelection *me, LONG unit, LONG extend, LONG *delta) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; return E_NOTIMPL; @@ -5579,11 +5529,11 @@ static HRESULT WINAPI ITextSelection_fnHomeKey(ITextSelection *me, LONG unit, LO static HRESULT WINAPI ITextSelection_fnEndKey(ITextSelection *me, LONG unit, LONG extend, LONG *delta) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; return E_NOTIMPL; @@ -5591,11 +5541,11 @@ static HRESULT WINAPI ITextSelection_fnEndKey(ITextSelection *me, LONG unit, LON static HRESULT WINAPI ITextSelection_fnTypeText(ITextSelection *me, BSTR text) { - ITextSelectionImpl *This = impl_from_ITextSelection(me); + struct text_selection *This = impl_from_ITextSelection(me); FIXME("(%p)->(%s): stub\n", This, debugstr_w(text)); - if (!This->reOle) + if (!This->services) return CO_E_RELEASED; return E_NOTIMPL; @@ -5672,46 +5622,18 @@ static const ITextSelectionVtbl tsvt = { ITextSelection_fnTypeText }; -static ITextSelectionImpl * -CreateTextSelection(IRichEditOleImpl *reOle) +static struct text_selection *text_selection_create(struct text_services *services) { - ITextSelectionImpl *txtSel = heap_alloc(sizeof *txtSel); + struct text_selection *txtSel = heap_alloc(sizeof *txtSel); if (!txtSel) return NULL; txtSel->ITextSelection_iface.lpVtbl = &tsvt; txtSel->ref = 1; - txtSel->reOle = reOle; + txtSel->services = services; return txtSel; } -LRESULT CreateIRichEditOle(IUnknown *outer_unk, ME_TextEditor *editor, LPVOID *ppvObj) -{ - IRichEditOleImpl *reo; - - reo = heap_alloc(sizeof(IRichEditOleImpl)); - if (!reo) - return 0; - - reo->IUnknown_inner.lpVtbl = &reo_unk_vtbl; - reo->IRichEditOle_iface.lpVtbl = &revt; - reo->ITextDocument2Old_iface.lpVtbl = &tdvt; - reo->ref = 1; - reo->editor = editor; - reo->txtSel = NULL; - - TRACE("Created %p\n",reo); - list_init(&reo->rangelist); - list_init(&reo->clientsites); - if (outer_unk) - reo->outer_unk = outer_unk; - else - reo->outer_unk = &reo->IUnknown_inner; - *ppvObj = &reo->IUnknown_inner; - - return 1; -} - static void convert_sizel(const ME_Context *c, const SIZEL* szl, SIZE* sz) { /* sizel is in .01 millimeters, sz in pixels */ @@ -5801,7 +5723,7 @@ void ME_GetOLEObjectSize(const ME_Context *c, ME_Run *run, SIZE *pSize) } } -void ME_DrawOLE(ME_Context *c, int x, int y, ME_Run *run, BOOL selected) +void draw_ole( ME_Context *c, int x, int y, ME_Run *run, BOOL selected ) { IDataObject* ido; FORMATETC fmt; @@ -5927,3 +5849,21 @@ void ME_CopyReObject(REOBJECT *dst, const REOBJECT *src, DWORD flags) IOleClientSite_AddRef(dst->polesite); } } + +void richole_release_children( struct text_services *services ) +{ + ITextRangeImpl *range; + IOleClientSiteImpl *site; + + if (services->text_selection) + { + services->text_selection->services = NULL; + ITextSelection_Release( &services->text_selection->ITextSelection_iface ); + } + + LIST_FOR_EACH_ENTRY( range, &services->rangelist, ITextRangeImpl, child.entry ) + range->child.reole = NULL; + + LIST_FOR_EACH_ENTRY( site, &services->clientsites, IOleClientSiteImpl, child.entry ) + site->child.reole = NULL; +} diff --git a/dll/win32/riched20/row.c b/dll/win32/riched20/row.c index 1bf153f6ca96a..715d2adbf62d6 100644 --- a/dll/win32/riched20/row.c +++ b/dll/win32/riched20/row.c @@ -24,69 +24,132 @@ #include "editor.h" -/* I'm sure these functions would simplify some code in caret ops etc, - * I just didn't remember them when I wrote that code - */ +ME_Row *row_next( ME_Row *row ) +{ + ME_DisplayItem *item; -ME_DisplayItem *ME_RowStart(ME_DisplayItem *item) { - return ME_FindItemBackOrHere(item, diStartRow); + item = ME_FindItemFwd( row_get_di( row ), diStartRowOrParagraphOrEnd ); + if (!item || item->type != diStartRow) return NULL; + return &item->member.row; } -/* -ME_DisplayItem *ME_RowEnd(ME_DisplayItem *item) { - ME_DisplayItem *item2 = ME_FindItemFwd(item, diStartRowOrParagraphOrEnd); - if (!item2) return NULL; - return ME_FindItemBack(item, diRun); +ME_Row *row_next_all_paras( ME_Row *row ) +{ + ME_DisplayItem *item; + + item = ME_FindItemFwd( row_get_di( row ), diStartRow ); + if (!item) return NULL; + return &item->member.row; +} + +ME_Row *row_prev_all_paras( ME_Row *row ) +{ + ME_DisplayItem *item; + + item = ME_FindItemBack( row_get_di( row ), diStartRow ); + if (!item) return NULL; + return &item->member.row; +} + +ME_Run *row_first_run( ME_Row *row ) +{ + ME_DisplayItem *item; + + item = ME_FindItemFwd( row_get_di( row ), diRunOrStartRow ); + assert( item->type == diRun ); + return &item->member.run; +} + +ME_Run *row_next_run( ME_Row *row, ME_Run *run ) +{ + ME_DisplayItem *item; + + assert( row == &ME_FindItemBack( run_get_di( run ), diStartRow )->member.row ); + + item = ME_FindItemFwd( run_get_di( run ), diRunOrStartRow ); + if (!item || item->type == diStartRow) return NULL; + return &item->member.run; +} + +ME_Row *row_from_cursor( ME_Cursor *cursor ) +{ + ME_DisplayItem *item; + + item = ME_FindItemBack( run_get_di( cursor->run ), diStartRow ); + return &item->member.row; } -*/ -ME_DisplayItem * -ME_FindRowWithNumber(ME_TextEditor *editor, int nRow) +void row_first_cursor( ME_Row *row, ME_Cursor *cursor ) { - ME_DisplayItem *item = ME_FindItemFwd(editor->pBuffer->pFirst, diParagraph); - int nCount = 0; - - while (item->type == diParagraph && - nCount + item->member.para.nRows <= nRow) - { - nCount += item->member.para.nRows; - item = item->member.para.next_para; - } - if (item->type != diParagraph) - return NULL; - for (item = ME_FindItemFwd(item, diStartRow); item && nCount < nRow; nCount++) - item = ME_FindItemFwd(item, diStartRow); - return item; + ME_DisplayItem *item; + + item = ME_FindItemFwd( row_get_di( row ), diRun ); + cursor->run = &item->member.run; + cursor->para = cursor->run->para; + cursor->nOffset = 0; +} + +void row_end_cursor( ME_Row *row, ME_Cursor *cursor, BOOL include_eop ) +{ + ME_DisplayItem *item, *run; + + item = ME_FindItemFwd( row_get_di( row ), diStartRowOrParagraphOrEnd ); + run = ME_FindItemBack( item, diRun ); + cursor->run = &run->member.run; + cursor->para = cursor->run->para; + cursor->nOffset = (item->type == diStartRow || include_eop) ? cursor->run->len : 0; +} + +ME_Paragraph *row_para( ME_Row *row ) +{ + ME_Cursor cursor; + + row_first_cursor( row, &cursor ); + return cursor.para; +} + +ME_Row *row_from_row_number( ME_TextEditor *editor, int row_num ) +{ + ME_Paragraph *para = editor_first_para( editor ); + ME_Row *row; + int count = 0; + + while (para_next( para ) && count + para->nRows <= row_num) + { + count += para->nRows; + para = para_next( para ); + } + if (!para_next( para )) return NULL; + + for (row = para_first_row( para ); row && count < row_num; count++) + row = row_next( row ); + + return row; } -int -ME_RowNumberFromCharOfs(ME_TextEditor *editor, int nOfs) +int row_number_from_char_ofs( ME_TextEditor *editor, int ofs ) { - ME_DisplayItem *item = ME_FindItemFwd(editor->pBuffer->pFirst, diParagraph); - int nRow = 0; - - while (item->type == diParagraph && - item->member.para.next_para->member.para.nCharOfs <= nOfs) - { - nRow += item->member.para.nRows; - item = item->member.para.next_para; - } - if (item->type == diParagraph) - { - ME_DisplayItem *next_para = item->member.para.next_para; - - nOfs -= item->member.para.nCharOfs; - item = ME_FindItemFwd(item, diRun); - while ((item = ME_FindItemFwd(item, diStartRowOrParagraph)) != NULL) + ME_Paragraph *para = editor_first_para( editor ); + ME_Row *row; + ME_Cursor cursor; + int row_num = 0; + + while (para_next( para ) && para_next( para )->nCharOfs <= ofs) { - if (item == next_para) - break; - item = ME_FindItemFwd(item, diRun); - if (item->member.run.nCharOfs > nOfs) - break; - nRow++; + row_num += para->nRows; + para = para_next( para ); } - } - return nRow; + + if (para_next( para )) + { + for (row = para_first_row( para ); row; row = row_next( row )) + { + row_end_cursor( row, &cursor, TRUE ); + if (ME_GetCursorOfs( &cursor ) > ofs ) break; + row_num++; + } + } + + return row_num; } diff --git a/dll/win32/riched20/rtf.h b/dll/win32/riched20/rtf.h index 66d88b55da96a..35a0ee878e9cb 100644 --- a/dll/win32/riched20/rtf.h +++ b/dll/win32/riched20/rtf.h @@ -1035,10 +1035,10 @@ struct RTFTable int numCellsInserted; /* v4.1 */ - /* tableRowStart may be the start row paragraph of the table row, + /* row_start may be the start row paragraph of the table row, * or it may store the end of the previous row if it may still be * continued, otherwise NULL is stored. */ - ME_DisplayItem *tableRowStart; + ME_Paragraph *row_start; /* Table definitions are stored as a stack to support nested tables. */ RTFTable *parent; diff --git a/dll/win32/riched20/run.c b/dll/win32/riched20/run.c index 3912384451cdb..51e768f844106 100644 --- a/dll/win32/riched20/run.c +++ b/dll/win32/riched20/run.c @@ -27,6 +27,100 @@ WINE_DEFAULT_DEBUG_CHANNEL(richedit); WINE_DECLARE_DEBUG_CHANNEL(richedit_check); WINE_DECLARE_DEBUG_CHANNEL(richedit_lists); +BOOL cursor_next_run( ME_Cursor *cursor, BOOL all_para ) +{ + ME_DisplayItem *p = run_get_di( cursor->run )->next; + + while (p->type != diTextEnd) + { + if (p->type == diParagraph && !all_para) return FALSE; + else if (p->type == diRun) + { + cursor->run = &p->member.run; + cursor->para = cursor->run->para; + cursor->nOffset = 0; + return TRUE; + } + p = p->next; + } + return FALSE; +} + +BOOL cursor_prev_run( ME_Cursor *cursor, BOOL all_para ) +{ + ME_DisplayItem *p = run_get_di( cursor->run )->prev; + + while (p->type != diTextStart) + { + if (p->type == diParagraph && !all_para) return FALSE; + else if (p->type == diRun) + { + cursor->run = &p->member.run; + cursor->para = cursor->run->para; + cursor->nOffset = 0; + return TRUE; + } + p = p->prev; + } + return FALSE; +} + +ME_Run *run_next( ME_Run *run ) +{ + ME_Cursor cursor; + + cursor.run = run; + cursor.para = run->para; + cursor.nOffset = 0; + + if (cursor_next_run( &cursor, FALSE )) + return cursor.run; + + return NULL; +} + +ME_Run *run_prev( ME_Run *run ) +{ + ME_Cursor cursor; + + cursor.run = run; + cursor.para = run->para; + cursor.nOffset = 0; + + if (cursor_prev_run( &cursor, FALSE )) + return cursor.run; + + return NULL; +} + +ME_Run *run_next_all_paras( ME_Run *run ) +{ + ME_Cursor cursor; + + cursor.run = run; + cursor.para = run->para; + cursor.nOffset = 0; + + if (cursor_next_run( &cursor, TRUE )) + return cursor.run; + + return NULL; +} + +ME_Run *run_prev_all_paras( ME_Run *run ) +{ + ME_Cursor cursor; + + cursor.run = run; + cursor.para = run->para; + cursor.nOffset = 0; + + if (cursor_prev_run( &cursor, TRUE )) + return cursor.run; + + return NULL; +} + /****************************************************************************** * ME_CanJoinRuns * @@ -43,54 +137,32 @@ BOOL ME_CanJoinRuns(const ME_Run *run1, const ME_Run *run2) return TRUE; } -void ME_SkipAndPropagateCharOffset(ME_DisplayItem *p, int shift) -{ - p = ME_FindItemFwd(p, diRunOrParagraphOrEnd); - assert(p); - ME_PropagateCharOffset(p, shift); -} - /****************************************************************************** - * ME_PropagateCharOffsets + * editor_propagate_char_ofs * * Shifts (increases or decreases) character offset (relative to beginning of - * the document) of the part of the text starting from given place. + * the document) of the part of the text starting from given place. + * Call with only one of para or run non-NULL. */ -void ME_PropagateCharOffset(ME_DisplayItem *p, int shift) +void editor_propagate_char_ofs( ME_Paragraph *para, ME_Run *run, int shift ) { - /* Runs in one paragraph contain character offset relative to their owning - * paragraph. If we start the shifting from the run, we need to shift - * all the relative offsets until the end of the paragraph - */ - if (p->type == diRun) /* propagate in all runs in this para */ - { - TRACE("PropagateCharOffset(%s, %d)\n", debugstr_run( &p->member.run ), shift); - do { - p->member.run.nCharOfs += shift; - assert(p->member.run.nCharOfs >= 0); - p = ME_FindItemFwd(p, diRunOrParagraphOrEnd); - } while(p->type == diRun); - } - /* Runs in next paragraphs don't need their offsets updated, because they, - * again, those offsets are relative to their respective paragraphs. - * Instead of that, we're updating paragraphs' character offsets. - */ - if (p->type == diParagraph) /* propagate in all next paras */ - { - do { - p->member.para.nCharOfs += shift; - assert(p->member.para.nCharOfs >= 0); - p = p->member.para.next_para; - } while(p->type == diParagraph); - } - /* diTextEnd also has character offset in it, which makes finding text length - * easier. But it needs to be up to date first. - */ - if (p->type == diTextEnd) - { - p->member.para.nCharOfs += shift; - assert(p->member.para.nCharOfs >= 0); - } + assert( !para ^ !run ); + + if (run) + { + para = para_next( run->para ); + do + { + run->nCharOfs += shift; + run = run_next( run ); + } while (run); + } + + do + { + para->nCharOfs += shift; + para = para_next( para ); + } while (para); } /****************************************************************************** @@ -147,231 +219,208 @@ void ME_CheckCharOffsets(ME_TextEditor *editor) } /****************************************************************************** - * ME_CharOfsFromRunOfs + * run_char_ofs * - * Converts a character position relative to the start of the run, to a + * Converts a character position relative to the start of the run to a * character position relative to the start of the document. - * Kind of a "local to global" offset conversion. */ -int ME_CharOfsFromRunOfs(ME_TextEditor *editor, const ME_DisplayItem *pPara, - const ME_DisplayItem *pRun, int nOfs) + +int run_char_ofs( ME_Run *run, int ofs ) { - assert(pRun && pRun->type == diRun); - assert(pPara && pPara->type == diParagraph); - return pPara->member.para.nCharOfs + pRun->member.run.nCharOfs + nOfs; + return run->para->nCharOfs + run->nCharOfs + ofs; } /****************************************************************************** - * ME_CursorFromCharOfs + * cursor_from_char_ofs * * Converts a character offset (relative to the start of the document) to * a cursor structure (which contains a run and a position relative to that * run). */ -void ME_CursorFromCharOfs(ME_TextEditor *editor, int nCharOfs, ME_Cursor *pCursor) +void cursor_from_char_ofs( ME_TextEditor *editor, int char_ofs, ME_Cursor *cursor ) { - ME_RunOfsFromCharOfs(editor, nCharOfs, &pCursor->pPara, - &pCursor->pRun, &pCursor->nOffset); -} + ME_Paragraph *para; + ME_Run *run; -/****************************************************************************** - * ME_RunOfsFromCharOfs - * - * Find a run and relative character offset given an absolute character offset - * (absolute offset being an offset relative to the start of the document). - * Kind of a "global to local" offset conversion. - */ -void ME_RunOfsFromCharOfs(ME_TextEditor *editor, - int nCharOfs, - ME_DisplayItem **ppPara, - ME_DisplayItem **ppRun, - int *pOfs) -{ - ME_DisplayItem *item, *next_item; - int endOfs = nCharOfs, len = ME_GetTextLength(editor); + char_ofs = min( max( char_ofs, 0 ), ME_GetTextLength( editor ) ); - nCharOfs = max(nCharOfs, 0); - nCharOfs = min(nCharOfs, len); + /* Find the paragraph at the offset. */ + for (para = editor_first_para( editor ); + para_next( para )->nCharOfs <= char_ofs; + para = para_next( para )) + ; - /* Find the paragraph at the offset. */ - next_item = editor->pBuffer->pFirst->member.para.next_para; - do { - item = next_item; - next_item = item->member.para.next_para; - } while (next_item->member.para.nCharOfs <= nCharOfs); - assert(item->type == diParagraph); - nCharOfs -= item->member.para.nCharOfs; - if (ppPara) *ppPara = item; - - /* Find the run at the offset. */ - next_item = ME_FindItemFwd(item, diRun); - do { - item = next_item; - next_item = ME_FindItemFwd(item, diRunOrParagraphOrEnd); - } while (next_item->type == diRun && - next_item->member.run.nCharOfs <= nCharOfs); - assert(item->type == diRun); - nCharOfs -= item->member.run.nCharOfs; - - if (ppRun) *ppRun = item; - if (pOfs) { - if (((*ppRun)->member.run.nFlags & MERF_ENDPARA) && endOfs > len) - *pOfs = (*ppRun)->member.run.len; - else *pOfs = nCharOfs; - } + char_ofs -= para->nCharOfs; + + /* Find the run at the offset. */ + for (run = para_first_run( para ); + run_next( run ) && run_next( run )->nCharOfs <= char_ofs; + run = run_next( run )) + ; + + char_ofs -= run->nCharOfs; + + cursor->para = para; + cursor->run = run; + cursor->nOffset = char_ofs; } /****************************************************************************** - * ME_JoinRuns + * run_join * * Merges two adjacent runs, the one given as a parameter and the next one. */ -void ME_JoinRuns(ME_TextEditor *editor, ME_DisplayItem *p) +void run_join( ME_TextEditor *editor, ME_Run *run ) { - ME_DisplayItem *pNext = p->next; + ME_Run *next = run_next( run ); int i; - assert(p->type == diRun && pNext->type == diRun); - assert(p->member.run.nCharOfs != -1); - mark_para_rewrap(editor, ME_GetParagraph(p)); + + assert( run ); + assert( run->nCharOfs != -1 ); + para_mark_rewrap( editor, run->para ); /* Update all cursors so that they don't contain the soon deleted run */ - for (i=0; inCursors; i++) { - if (editor->pCursors[i].pRun == pNext) { - editor->pCursors[i].pRun = p; - editor->pCursors[i].nOffset += p->member.run.len; + for (i = 0; i < editor->nCursors; i++) + { + if (editor->pCursors[i].run == next) + { + editor->pCursors[i].run = run; + editor->pCursors[i].nOffset += run->len; } } - p->member.run.len += pNext->member.run.len; - ME_Remove(pNext); - ME_DestroyDisplayItem(pNext); - ME_UpdateRunFlags(editor, &p->member.run); - ME_CheckCharOffsets(editor); + run->len += next->len; + ME_Remove( run_get_di( next ) ); + ME_DestroyDisplayItem( run_get_di( next ) ); + ME_UpdateRunFlags( editor, run ); + ME_CheckCharOffsets( editor ); } /****************************************************************************** - * ME_SplitRunSimple + * run_split * * Does the most basic job of splitting a run into two - it does not * update the positions and extents. */ -ME_DisplayItem *ME_SplitRunSimple(ME_TextEditor *editor, ME_Cursor *cursor) +ME_Run *run_split( ME_TextEditor *editor, ME_Cursor *cursor ) { - ME_DisplayItem *run = cursor->pRun; - ME_DisplayItem *new_run; - int i; - int nOffset = cursor->nOffset; - - assert(!(run->member.run.nFlags & MERF_NONTEXT)); - - new_run = ME_MakeRun(run->member.run.style, - run->member.run.nFlags & MERF_SPLITMASK); - new_run->member.run.nCharOfs = run->member.run.nCharOfs + nOffset; - new_run->member.run.len = run->member.run.len - nOffset; - new_run->member.run.para = run->member.run.para; - run->member.run.len = nOffset; - cursor->pRun = new_run; - cursor->nOffset = 0; - - ME_InsertBefore(run->next, new_run); - - ME_UpdateRunFlags(editor, &run->member.run); - ME_UpdateRunFlags(editor, &new_run->member.run); - for (i = 0; i < editor->nCursors; i++) { - if (editor->pCursors[i].pRun == run && - editor->pCursors[i].nOffset >= nOffset) { - editor->pCursors[i].pRun = new_run; - editor->pCursors[i].nOffset -= nOffset; + ME_Run *run = cursor->run, *new_run; + int i; + int nOffset = cursor->nOffset; + + assert( !(run->nFlags & MERF_NONTEXT) ); + + new_run = run_create( run->style, run->nFlags & MERF_SPLITMASK ); + new_run->nCharOfs = run->nCharOfs + nOffset; + new_run->len = run->len - nOffset; + new_run->para = run->para; + run->len = nOffset; + cursor->run = new_run; + cursor->nOffset = 0; + + ME_InsertBefore( run_get_di( run )->next, run_get_di( new_run ) ); + + ME_UpdateRunFlags( editor, run ); + ME_UpdateRunFlags( editor, new_run ); + for (i = 0; i < editor->nCursors; i++) + { + if (editor->pCursors[i].run == run && + editor->pCursors[i].nOffset >= nOffset) + { + editor->pCursors[i].run = new_run; + editor->pCursors[i].nOffset -= nOffset; + } } - } - mark_para_rewrap(editor, cursor->pPara); - return run; + para_mark_rewrap( editor, run->para ); + return run; } /****************************************************************************** - * ME_MakeRun + * run_create * * A helper function to create run structures quickly. */ -ME_DisplayItem *ME_MakeRun(ME_Style *s, int nFlags) +ME_Run *run_create( ME_Style *s, int flags ) { - ME_DisplayItem *item = ME_MakeDI(diRun); - item->member.run.style = s; - item->member.run.reobj = NULL; - item->member.run.nFlags = nFlags; - item->member.run.nCharOfs = -1; - item->member.run.len = 0; - item->member.run.para = NULL; - item->member.run.num_glyphs = 0; - item->member.run.max_glyphs = 0; - item->member.run.glyphs = NULL; - item->member.run.vis_attrs = NULL; - item->member.run.advances = NULL; - item->member.run.offsets = NULL; - item->member.run.max_clusters = 0; - item->member.run.clusters = NULL; - ME_AddRefStyle(s); - return item; + ME_DisplayItem *item = ME_MakeDI( diRun ); + ME_Run *run = &item->member.run; + + if (!item) return NULL; + + ME_AddRefStyle( s ); + run->style = s; + run->reobj = NULL; + run->nFlags = flags; + run->nCharOfs = -1; + run->len = 0; + run->para = NULL; + run->num_glyphs = 0; + run->max_glyphs = 0; + run->glyphs = NULL; + run->vis_attrs = NULL; + run->advances = NULL; + run->offsets = NULL; + run->max_clusters = 0; + run->clusters = NULL; + return run; } /****************************************************************************** - * ME_InsertRunAtCursor + * run_insert * * Inserts a new run with given style, flags and content at a given position, * which is passed as a cursor structure (which consists of a run and * a run-relative character offset). */ -ME_DisplayItem * -ME_InsertRunAtCursor(ME_TextEditor *editor, ME_Cursor *cursor, ME_Style *style, - const WCHAR *str, int len, int flags) +ME_Run *run_insert( ME_TextEditor *editor, ME_Cursor *cursor, ME_Style *style, + const WCHAR *str, int len, int flags ) { - ME_DisplayItem *pDI, *insert_before = cursor->pRun, *prev; + ME_Run *insert_before = cursor->run, *run, *prev; if (cursor->nOffset) { - if (cursor->nOffset == cursor->pRun->member.run.len) + if (cursor->nOffset == insert_before->len) { - insert_before = ME_FindItemFwd( cursor->pRun, diRun ); - if (!insert_before) insert_before = cursor->pRun; /* Always insert before the final eop run */ + insert_before = run_next_all_paras( insert_before ); + if (!insert_before) insert_before = cursor->run; /* Always insert before the final eop run */ } else { - ME_SplitRunSimple( editor, cursor ); - insert_before = cursor->pRun; + run_split( editor, cursor ); + insert_before = cursor->run; } } - add_undo_delete_run( editor, insert_before->member.run.para->nCharOfs + - insert_before->member.run.nCharOfs, len ); + add_undo_delete_run( editor, insert_before->para->nCharOfs + insert_before->nCharOfs, len ); - pDI = ME_MakeRun(style, flags); - pDI->member.run.nCharOfs = insert_before->member.run.nCharOfs; - pDI->member.run.len = len; - pDI->member.run.para = insert_before->member.run.para; - ME_InsertString( pDI->member.run.para->text, pDI->member.run.nCharOfs, str, len ); - ME_InsertBefore( insert_before, pDI ); + run = run_create( style, flags ); + run->nCharOfs = insert_before->nCharOfs; + run->len = len; + run->para = insert_before->para; + ME_InsertString( run->para->text, run->nCharOfs, str, len ); + ME_InsertBefore( run_get_di( insert_before ), run_get_di( run ) ); TRACE("Shift length:%d\n", len); - ME_PropagateCharOffset( insert_before, len ); - mark_para_rewrap(editor, get_di_from_para(insert_before->member.run.para)); + editor_propagate_char_ofs( NULL, insert_before, len ); + para_mark_rewrap( editor, insert_before->para ); /* Move any cursors that were at the end of the previous run to the end of the inserted run */ - prev = ME_FindItemBack( pDI, diRun ); + prev = run_prev_all_paras( run ); if (prev) { int i; for (i = 0; i < editor->nCursors; i++) { - if (editor->pCursors[i].pRun == prev && - editor->pCursors[i].nOffset == prev->member.run.len) + if (editor->pCursors[i].run == prev && + editor->pCursors[i].nOffset == prev->len) { - editor->pCursors[i].pRun = pDI; + editor->pCursors[i].run = run; editor->pCursors[i].nOffset = len; } } } - return pDI; + return run; } static BOOL run_is_splittable( const ME_Run *run ) @@ -494,9 +543,9 @@ int ME_CharFromPointContext(ME_Context *c, int cx, ME_Run *run, BOOL closest, BO return closest ? cp + trailing : cp; } - if (c->editor->cPasswordMask) + if (c->editor->password_char) { - mask_text = ME_MakeStringR( c->editor->cPasswordMask, run->len ); + mask_text = ME_MakeStringR( c->editor->password_char, run->len ); str = mask_text->szData; } else @@ -522,10 +571,12 @@ int ME_CharFromPoint(ME_TextEditor *editor, int cx, ME_Run *run, BOOL closest, B { ME_Context c; int ret; + HDC hdc = ITextHost_TxGetDC( editor->texthost ); - ME_InitContext( &c, editor, ITextHost_TxGetDC( editor->texthost ) ); + ME_InitContext( &c, editor, hdc ); ret = ME_CharFromPointContext( &c, cx, run, closest, visual_order ); ME_DestroyContext(&c); + ITextHost_TxReleaseDC( editor->texthost, hdc ); return ret; } @@ -577,9 +628,9 @@ int ME_PointFromCharContext(ME_Context *c, ME_Run *pRun, int nOffset, BOOL visua if (visual_order && pRun->script_analysis.fRTL) x = pRun->nWidth - x - 1; return x; } - if (c->editor->cPasswordMask) + if (c->editor->password_char) { - mask_text = ME_MakeStringR(c->editor->cPasswordMask, pRun->len); + mask_text = ME_MakeStringR( c->editor->password_char, pRun->len ); str = mask_text->szData; } else @@ -599,10 +650,12 @@ int ME_PointFromChar(ME_TextEditor *editor, ME_Run *pRun, int nOffset, BOOL visu { ME_Context c; int ret; + HDC hdc = ITextHost_TxGetDC( editor->texthost ); - ME_InitContext(&c, editor, ITextHost_TxGetDC(editor->texthost)); + ME_InitContext( &c, editor, hdc ); ret = ME_PointFromCharContext( &c, pRun, nOffset, visual_order ); ME_DestroyContext(&c); + ITextHost_TxReleaseDC( editor->texthost, hdc ); return ret; } @@ -616,7 +669,6 @@ int ME_PointFromChar(ME_TextEditor *editor, ME_Run *pRun, int nOffset, BOOL visu SIZE ME_GetRunSizeCommon(ME_Context *c, const ME_Paragraph *para, ME_Run *run, int nLen, int startx, int *pAscent, int *pDescent) { - static const WCHAR spaceW[] = {' ',0}; SIZE size; nLen = min( nLen, run->len ); @@ -624,15 +676,15 @@ SIZE ME_GetRunSizeCommon(ME_Context *c, const ME_Paragraph *para, ME_Run *run, i if (run->nFlags & MERF_ENDPARA) { nLen = min( nLen, 1 ); - ME_GetTextExtent(c, spaceW, nLen, run->style, &size); + ME_GetTextExtent( c, L" ", nLen, run->style, &size ); } else if (para->nFlags & MEPF_COMPLEX) { size.cx = run->nWidth; } - else if (c->editor->cPasswordMask) + else if (c->editor->password_char) { - ME_String *szMasked = ME_MakeStringR(c->editor->cPasswordMask,nLen); + ME_String *szMasked = ME_MakeStringR( c->editor->password_char, nLen ); ME_GetTextExtent(c, szMasked->szData, nLen,run->style, &size); ME_DestroyString(szMasked); } @@ -699,7 +751,7 @@ void ME_SetSelectionCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt) { ME_Style *s; if (!editor->pBuffer->pCharStyle) - editor->pBuffer->pCharStyle = ME_GetInsertStyle(editor, 0); + editor->pBuffer->pCharStyle = style_get_insert_style( editor, editor->pCursors ); s = ME_ApplyStyle(editor, editor->pBuffer->pCharStyle, pFmt); ME_ReleaseStyle(editor->pBuffer->pCharStyle); editor->pBuffer->pCharStyle = s; @@ -722,63 +774,63 @@ void ME_SetSelectionCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt) * * If no text is selected, then nothing is done. */ -void ME_SetCharFormat(ME_TextEditor *editor, ME_Cursor *start, ME_Cursor *end, CHARFORMAT2W *pFmt) +void ME_SetCharFormat( ME_TextEditor *editor, ME_Cursor *start, ME_Cursor *end, CHARFORMAT2W *fmt ) { - ME_DisplayItem *run, *start_run = start->pRun, *end_run = NULL; + ME_Run *run, *start_run = start->run, *end_run = NULL; - if (end && start->pRun == end->pRun && start->nOffset == end->nOffset) + if (end && start->run == end->run && start->nOffset == end->nOffset) return; - if (start->nOffset == start->pRun->member.run.len) - start_run = ME_FindItemFwd( start->pRun, diRun ); + if (start->nOffset == start->run->len) + start_run = run_next_all_paras( start->run ); else if (start->nOffset) { - /* SplitRunSimple may or may not update the cursors, depending on whether they + /* run_split() may or may not update the cursors, depending on whether they * are selection cursors, but we need to make sure they are valid. */ int split_offset = start->nOffset; - ME_DisplayItem *split_run = ME_SplitRunSimple(editor, start); - start_run = start->pRun; - if (end && end->pRun == split_run) + ME_Run *split_run = run_split( editor, start ); + start_run = start->run; + if (end && end->run == split_run) { - end->pRun = start->pRun; + end->run = start->run; end->nOffset -= split_offset; } } if (end) { - if (end->nOffset == end->pRun->member.run.len) - end_run = ME_FindItemFwd( end->pRun, diRun ); + if (end->nOffset == end->run->len) + end_run = run_next_all_paras( end->run ); else { - if (end->nOffset) ME_SplitRunSimple(editor, end); - end_run = end->pRun; + if (end->nOffset) run_split( editor, end ); + end_run = end->run; } } - for (run = start_run; run != end_run; run = ME_FindItemFwd( run, diRun )) + for (run = start_run; run != end_run; run = run_next_all_paras( run )) { - ME_Style *new_style = ME_ApplyStyle(editor, run->member.run.style, pFmt); - ME_Paragraph *para = run->member.run.para; + ME_Style *new_style = ME_ApplyStyle( editor, run->style, fmt ); + ME_Paragraph *para = run->para; - add_undo_set_char_fmt( editor, run->member.run.para->nCharOfs + run->member.run.nCharOfs, - run->member.run.len, &run->member.run.style->fmt ); - ME_ReleaseStyle(run->member.run.style); - run->member.run.style = new_style; + add_undo_set_char_fmt( editor, para->nCharOfs + run->nCharOfs, + run->len, &run->style->fmt ); + ME_ReleaseStyle( run->style ); + run->style = new_style; /* The para numbering style depends on the eop style */ - if ((run->member.run.nFlags & MERF_ENDPARA) && para->para_num.style) + if ((run->nFlags & MERF_ENDPARA) && para->para_num.style) { ME_ReleaseStyle(para->para_num.style); para->para_num.style = NULL; } - mark_para_rewrap(editor, get_di_from_para(para)); + para_mark_rewrap( editor, para ); } } -static void ME_GetRunCharFormat(ME_TextEditor *editor, ME_DisplayItem *run, CHARFORMAT2W *pFmt) +static void run_copy_char_fmt( ME_Run *run, CHARFORMAT2W *fmt ) { - ME_CopyCharFormat(pFmt, &run->member.run.style->fmt); + ME_CopyCharFormat( fmt, &run->style->fmt ); } /****************************************************************************** @@ -816,33 +868,25 @@ void ME_GetSelectionCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt) * Returns the style consisting of those attributes which are consistently set * in the whole character range. */ -void ME_GetCharFormat(ME_TextEditor *editor, const ME_Cursor *from, - const ME_Cursor *to, CHARFORMAT2W *pFmt) +void ME_GetCharFormat( ME_TextEditor *editor, const ME_Cursor *from, + const ME_Cursor *to, CHARFORMAT2W *fmt ) { - ME_DisplayItem *run, *run_end; + ME_Run *run, *run_end, *prev_run; CHARFORMAT2W tmp; - run = from->pRun; + run = from->run; /* special case - if selection is empty, take previous char's formatting */ - if (from->pRun == to->pRun && from->nOffset == to->nOffset) + if (from->run == to->run && from->nOffset == to->nOffset) { - if (!from->nOffset) - { - ME_DisplayItem *tmp_run = ME_FindItemBack(run, diRunOrParagraph); - if (tmp_run->type == diRun) { - ME_GetRunCharFormat(editor, tmp_run, pFmt); - return; - } - } - ME_GetRunCharFormat(editor, run, pFmt); + if (!from->nOffset && (prev_run = run_prev( run ))) run = prev_run; + run_copy_char_fmt( run, fmt ); return; } - run_end = to->pRun; - if (!to->nOffset) - run_end = ME_FindItemBack(run_end, diRun); + run_end = to->run; + if (!to->nOffset) run_end = run_prev_all_paras( run_end ); - ME_GetRunCharFormat(editor, run, pFmt); + run_copy_char_fmt( run, fmt ); if (run == run_end) return; @@ -851,40 +895,37 @@ void ME_GetCharFormat(ME_TextEditor *editor, const ME_Cursor *from, DWORD dwAttribs = CFM_SIZE | CFM_FACE | CFM_COLOR | CFM_UNDERLINETYPE; DWORD dwEffects = CFM_BOLD | CFM_ITALIC | CFM_UNDERLINE | CFM_STRIKEOUT | CFM_PROTECTED | CFM_LINK | CFM_SUPERSCRIPT; - run = ME_FindItemFwd(run, diRun); + run = run_next_all_paras( run ); - ZeroMemory(&tmp, sizeof(tmp)); + memset( &tmp, 0, sizeof(tmp) ); tmp.cbSize = sizeof(tmp); - ME_GetRunCharFormat(editor, run, &tmp); + run_copy_char_fmt( run, &tmp ); assert((tmp.dwMask & dwAttribs) == dwAttribs); /* reset flags that differ */ - if (pFmt->yHeight != tmp.yHeight) - pFmt->dwMask &= ~CFM_SIZE; - if (pFmt->dwMask & CFM_FACE) + if (fmt->yHeight != tmp.yHeight) fmt->dwMask &= ~CFM_SIZE; + if (fmt->dwMask & CFM_FACE) { if (!(tmp.dwMask & CFM_FACE)) - pFmt->dwMask &= ~CFM_FACE; - else if (wcscmp(pFmt->szFaceName, tmp.szFaceName) || - pFmt->bPitchAndFamily != tmp.bPitchAndFamily) - pFmt->dwMask &= ~CFM_FACE; + fmt->dwMask &= ~CFM_FACE; + else if (wcscmp( fmt->szFaceName, tmp.szFaceName ) || + fmt->bPitchAndFamily != tmp.bPitchAndFamily) + fmt->dwMask &= ~CFM_FACE; } - if (pFmt->yHeight != tmp.yHeight) - pFmt->dwMask &= ~CFM_SIZE; - if (pFmt->bUnderlineType != tmp.bUnderlineType) - pFmt->dwMask &= ~CFM_UNDERLINETYPE; - if (pFmt->dwMask & CFM_COLOR) + if (fmt->yHeight != tmp.yHeight) fmt->dwMask &= ~CFM_SIZE; + if (fmt->bUnderlineType != tmp.bUnderlineType) fmt->dwMask &= ~CFM_UNDERLINETYPE; + if (fmt->dwMask & CFM_COLOR) { - if (!((pFmt->dwEffects&CFE_AUTOCOLOR) & (tmp.dwEffects&CFE_AUTOCOLOR))) + if (!((fmt->dwEffects&CFE_AUTOCOLOR) & (tmp.dwEffects&CFE_AUTOCOLOR))) { - if (pFmt->crTextColor != tmp.crTextColor) - pFmt->dwMask &= ~CFM_COLOR; + if (fmt->crTextColor != tmp.crTextColor) + fmt->dwMask &= ~CFM_COLOR; } } - pFmt->dwMask &= ~((pFmt->dwEffects ^ tmp.dwEffects) & dwEffects); - pFmt->dwEffects = tmp.dwEffects; + fmt->dwMask &= ~((fmt->dwEffects ^ tmp.dwEffects) & dwEffects); + fmt->dwEffects = tmp.dwEffects; } while(run != run_end); } diff --git a/dll/win32/riched20/style.c b/dll/win32/riched20/style.c index 37c0509621fcc..917a5bd810016 100644 --- a/dll/win32/riched20/style.c +++ b/dll/win32/riched20/style.c @@ -429,7 +429,7 @@ void select_style( ME_Context *c, ME_Style *s ) c->orig_font = NULL; } - if (c->current_style && c->current_style->font_cache) + if (c->current_style) { release_font_cache( c->current_style->font_cache ); c->current_style->font_cache = NULL; @@ -473,42 +473,26 @@ void ME_ReleaseStyle(ME_Style *s) ME_DestroyStyle(s); } -ME_Style *ME_GetInsertStyle(ME_TextEditor *editor, int nCursor) +ME_Style *style_get_insert_style( ME_TextEditor *editor, ME_Cursor *cursor ) { - if (ME_IsSelection(editor)) - { + ME_Style *style; ME_Cursor *from, *to; + ME_Run *prev; - ME_GetSelection(editor, &from, &to); - ME_AddRefStyle(from->pRun->member.run.style); - return from->pRun->member.run.style; - } - if (editor->pBuffer->pCharStyle) { - ME_AddRefStyle(editor->pBuffer->pCharStyle); - return editor->pBuffer->pCharStyle; - } - else - { - ME_Cursor *pCursor = &editor->pCursors[nCursor]; - ME_DisplayItem *pRunItem = pCursor->pRun; - ME_DisplayItem *pPrevItem = NULL; - if (pCursor->nOffset) { - ME_Run *pRun = &pRunItem->member.run; - ME_AddRefStyle(pRun->style); - return pRun->style; - } - pPrevItem = ME_FindItemBack(pRunItem, diRunOrParagraph); - if (pPrevItem->type == diRun) + if (ME_IsSelection( editor )) { - ME_AddRefStyle(pPrevItem->member.run.style); - return pPrevItem->member.run.style; + ME_GetSelection( editor, &from, &to ); + style = from->run->style; } + else if (editor->pBuffer->pCharStyle) + style = editor->pBuffer->pCharStyle; + else if (!cursor->nOffset && (prev = run_prev( cursor->run ))) + style = prev->style; else - { - ME_AddRefStyle(pRunItem->member.run.style); - return pRunItem->member.run.style; - } - } + style = cursor->run->style; + + ME_AddRefStyle( style ); + return style; } void ME_SaveTempStyle(ME_TextEditor *editor, ME_Style *style) @@ -552,5 +536,5 @@ void ME_SetDefaultCharFormat(ME_TextEditor *editor, CHARFORMAT2W *mod) } ScriptFreeCache( &def->script_cache ); ME_ReleaseStyle( style ); - ME_MarkAllForWrapping( editor ); + editor_mark_rewrap_all( editor ); } diff --git a/dll/win32/riched20/table.c b/dll/win32/riched20/table.c index 1b4b9143d1659..c3823e3b4937b 100644 --- a/dll/win32/riched20/table.c +++ b/dll/win32/riched20/table.c @@ -54,449 +54,362 @@ #include "editor.h" #include "rtf.h" -WINE_DEFAULT_DEBUG_CHANNEL(richedit_lists); +static ME_Paragraph* table_insert_end_para( ME_TextEditor *editor, ME_Cursor *cursor, + const WCHAR *eol_str, int eol_len, int para_flags ) +{ + ME_Style *style = style_get_insert_style( editor, cursor ); + ME_Paragraph *para; -static const WCHAR cr_lf[] = {'\r', '\n', 0}; + if (cursor->nOffset) run_split( editor, cursor ); -static ME_DisplayItem* ME_InsertEndParaFromCursor(ME_TextEditor *editor, - int nCursor, - const WCHAR *eol_str, int eol_len, - int paraFlags) -{ - ME_Style *pStyle = ME_GetInsertStyle(editor, nCursor); - ME_DisplayItem *tp; - ME_Cursor* cursor = &editor->pCursors[nCursor]; - if (cursor->nOffset) - ME_SplitRunSimple(editor, cursor); - - tp = ME_SplitParagraph(editor, cursor->pRun, pStyle, eol_str, eol_len, paraFlags); - ME_ReleaseStyle(pStyle); - cursor->pPara = tp; - cursor->pRun = ME_FindItemFwd(tp, diRun); - return tp; + para = para_split( editor, cursor->run, style, eol_str, eol_len, para_flags ); + ME_ReleaseStyle( style ); + cursor->para = para; + cursor->run = para_first_run( para ); + return para; } -ME_DisplayItem* ME_InsertTableRowStartFromCursor(ME_TextEditor *editor) +ME_Paragraph* table_insert_row_start( ME_TextEditor *editor, ME_Cursor *cursor ) { - ME_DisplayItem *para; - para = ME_InsertEndParaFromCursor(editor, 0, cr_lf, 2, MEPF_ROWSTART); - return para->member.para.prev_para; + ME_Paragraph *para; + + para = table_insert_end_para( editor, cursor, L"\r\n", 2, MEPF_ROWSTART ); + return para_prev( para ); } -ME_DisplayItem* ME_InsertTableRowStartAtParagraph(ME_TextEditor *editor, - ME_DisplayItem *para) +ME_Paragraph* table_insert_row_start_at_para( ME_TextEditor *editor, ME_Paragraph *para ) { - ME_DisplayItem *prev_para, *end_para; - ME_Cursor savedCursor = editor->pCursors[0]; - ME_DisplayItem *startRowPara; - editor->pCursors[0].pPara = para; - editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); - editor->pCursors[0].nOffset = 0; - editor->pCursors[1] = editor->pCursors[0]; - startRowPara = ME_InsertTableRowStartFromCursor(editor); - savedCursor.pPara = ME_GetParagraph(savedCursor.pRun); - editor->pCursors[0] = savedCursor; - editor->pCursors[1] = editor->pCursors[0]; - - end_para = editor->pCursors[0].pPara->member.para.next_para; - prev_para = startRowPara->member.para.next_para; - para = prev_para->member.para.next_para; - while (para != end_para) - { - para->member.para.pCell = prev_para->member.para.pCell; - para->member.para.nFlags |= MEPF_CELL; - para->member.para.nFlags &= ~(MEPF_ROWSTART|MEPF_ROWEND); - para->member.para.fmt.dwMask |= PFM_TABLE|PFM_TABLEROWDELIMITER; - para->member.para.fmt.wEffects |= PFE_TABLE; - para->member.para.fmt.wEffects &= ~PFE_TABLEROWDELIMITER; - prev_para = para; - para = para->member.para.next_para; - } - return startRowPara; + ME_Paragraph *prev_para, *end_para, *start_row; + ME_Cursor cursor; + + cursor.para = para; + cursor.run = para_first_run( para ); + cursor.nOffset = 0; + + start_row = table_insert_row_start( editor, &cursor ); + + end_para = para_next( editor->pCursors[0].para ); + prev_para = para_next( start_row ); + para = para_next( prev_para ); + + while (para != end_para) + { + para->cell = para_cell( prev_para ); + para->nFlags |= MEPF_CELL; + para->nFlags &= ~(MEPF_ROWSTART | MEPF_ROWEND); + para->fmt.dwMask |= PFM_TABLE | PFM_TABLEROWDELIMITER; + para->fmt.wEffects |= PFE_TABLE; + para->fmt.wEffects &= ~PFE_TABLEROWDELIMITER; + prev_para = para; + para = para_next( para ); + } + return start_row; } /* Inserts a diCell and starts a new paragraph for the next cell. * * Returns the first paragraph of the new cell. */ -ME_DisplayItem* ME_InsertTableCellFromCursor(ME_TextEditor *editor) +ME_Paragraph* table_insert_cell( ME_TextEditor *editor, ME_Cursor *cursor ) { - ME_DisplayItem *para; - WCHAR tab = '\t'; - para = ME_InsertEndParaFromCursor(editor, 0, &tab, 1, MEPF_CELL); - return para; + WCHAR tab = '\t'; + + return table_insert_end_para( editor, editor->pCursors, &tab, 1, MEPF_CELL ); } -ME_DisplayItem* ME_InsertTableRowEndFromCursor(ME_TextEditor *editor) +ME_Paragraph* table_insert_row_end( ME_TextEditor *editor, ME_Cursor *cursor ) { - ME_DisplayItem *para; - para = ME_InsertEndParaFromCursor(editor, 0, cr_lf, 2, MEPF_ROWEND); - return para->member.para.prev_para; + ME_Paragraph *para; + + para = table_insert_end_para( editor, cursor, L"\r\n", 2, MEPF_ROWEND ); + return para_prev( para ); } -ME_DisplayItem* ME_GetTableRowEnd(ME_DisplayItem *para) +ME_Paragraph* table_row_end( ME_Paragraph *para ) { - ME_DisplayItem *cell; - assert(para); - if (para->member.para.nFlags & MEPF_ROWEND) - return para; - if (para->member.para.nFlags & MEPF_ROWSTART) - para = para->member.para.next_para; - cell = para->member.para.pCell; - assert(cell && cell->type == diCell); - while (cell->member.cell.next_cell) - cell = cell->member.cell.next_cell; - - para = ME_FindItemFwd(cell, diParagraph); - assert(para && para->member.para.nFlags & MEPF_ROWEND); + ME_Cell *cell; + + if (para->nFlags & MEPF_ROWEND) return para; + if (para->nFlags & MEPF_ROWSTART) para = para_next( para ); + cell = para_cell( para ); + while (cell_next( cell )) + cell = cell_next( cell ); + + para = &ME_FindItemFwd( cell_get_di( cell ), diParagraph )->member.para; + assert( para && para->nFlags & MEPF_ROWEND ); return para; } -ME_DisplayItem* ME_GetTableRowStart(ME_DisplayItem *para) +ME_Paragraph* table_row_start( ME_Paragraph *para ) { - ME_DisplayItem *cell; - assert(para); - if (para->member.para.nFlags & MEPF_ROWSTART) - return para; - if (para->member.para.nFlags & MEPF_ROWEND) - para = para->member.para.prev_para; - cell = para->member.para.pCell; - assert(cell && cell->type == diCell); - while (cell->member.cell.prev_cell) - cell = cell->member.cell.prev_cell; - - para = ME_FindItemBack(cell, diParagraph); - assert(para && para->member.para.nFlags & MEPF_ROWSTART); + ME_Cell *cell; + + if (para->nFlags & MEPF_ROWSTART) return para; + if (para->nFlags & MEPF_ROWEND) para = para_prev( para ); + cell = para_cell( para ); + + while (cell_prev( cell )) + cell = cell_prev( cell ); + + para = &ME_FindItemBack( cell_get_di( cell ), diParagraph )->member.para; + assert( para && para->nFlags & MEPF_ROWSTART ); return para; } -ME_DisplayItem* ME_GetOuterParagraph(ME_DisplayItem *para) +ME_Paragraph* table_outer_para( ME_Paragraph *para ) { - if (para->member.para.nFlags & MEPF_ROWEND) - para = para->member.para.prev_para; - while (para->member.para.pCell) + if (para->nFlags & MEPF_ROWEND) para = para_prev( para ); + while (para_cell( para )) { - para = ME_GetTableRowStart(para); - if (!para->member.para.pCell) - break; - para = ME_FindItemBack(para->member.para.pCell, diParagraph); + para = table_row_start( para ); + if (!para_cell( para )) break; + para = &ME_FindItemBack( cell_get_di( para_cell( para ) ), diParagraph )->member.para; } return para; } -/* Make a bunch of assertions to make sure tables haven't been corrupted. - * - * These invariants may not hold true in the middle of streaming in rich text - * or during an undo and redo of streaming in rich text. It should be safe to - * call this method after an event is processed. - */ -void ME_CheckTablesForCorruption(ME_TextEditor *editor) +ME_Cell *table_row_first_cell( ME_Paragraph *para ) { - if(TRACE_ON(richedit_lists)) - { - TRACE("---\n"); - ME_DumpDocument(editor->pBuffer); - } -#ifndef NDEBUG - { - ME_DisplayItem *p, *pPrev; - pPrev = editor->pBuffer->pFirst; - p = pPrev->next; - if (!editor->bEmulateVersion10) /* v4.1 */ - { - while (p->type == diParagraph) - { - assert(p->member.para.fmt.dwMask & PFM_TABLE); - assert(p->member.para.fmt.dwMask & PFM_TABLEROWDELIMITER); - if (p->member.para.pCell) - { - assert(p->member.para.nFlags & MEPF_CELL); - assert(p->member.para.fmt.wEffects & PFE_TABLE); - } - if (p->member.para.pCell != pPrev->member.para.pCell) - { - /* There must be a diCell in between the paragraphs if pCell changes. */ - ME_DisplayItem *pCell = ME_FindItemBack(p, diCell); - assert(pCell); - assert(ME_FindItemBack(p, diRun) == ME_FindItemBack(pCell, diRun)); - } - if (p->member.para.nFlags & MEPF_ROWEND) - { - /* ROWEND must come after a cell. */ - assert(pPrev->member.para.pCell); - assert(p->member.para.pCell - == pPrev->member.para.pCell->member.cell.parent_cell); - assert(p->member.para.fmt.wEffects & PFE_TABLEROWDELIMITER); - } - else if (p->member.para.pCell) - { - assert(!(p->member.para.fmt.wEffects & PFE_TABLEROWDELIMITER)); - assert(pPrev->member.para.pCell || - pPrev->member.para.nFlags & MEPF_ROWSTART); - if (pPrev->member.para.pCell && - !(pPrev->member.para.nFlags & MEPF_ROWSTART)) - { - assert(p->member.para.pCell->member.cell.parent_cell - == pPrev->member.para.pCell->member.cell.parent_cell); - if (pPrev->member.para.pCell != p->member.para.pCell) - assert(pPrev->member.para.pCell - == p->member.para.pCell->member.cell.prev_cell); - } - } - else if (!(p->member.para.nFlags & MEPF_ROWSTART)) - { - assert(!(p->member.para.fmt.wEffects & PFE_TABLEROWDELIMITER)); - /* ROWSTART must be followed by a cell. */ - assert(!(p->member.para.nFlags & MEPF_CELL)); - /* ROWSTART must be followed by a cell. */ - assert(!(pPrev->member.para.nFlags & MEPF_ROWSTART)); - } - pPrev = p; - p = p->member.para.next_para; - } - } else { /* v1.0 - 3.0 */ - while (p->type == diParagraph) - { - assert(!(p->member.para.nFlags & (MEPF_ROWSTART|MEPF_ROWEND|MEPF_CELL))); - assert(p->member.para.fmt.dwMask & PFM_TABLE); - assert(!(p->member.para.fmt.wEffects & PFE_TABLEROWDELIMITER)); - assert(!p->member.para.pCell); - p = p->member.para.next_para; - } - return; - } - assert(p->type == diTextEnd); - assert(!pPrev->member.para.pCell); - } -#endif + if (!para_in_table( para )) return NULL; + + para = para_next( table_row_start( para ) ); + return para_cell( para ); +} + +ME_Cell *table_row_end_cell( ME_Paragraph *para ) +{ + if (!para_in_table( para )) return NULL; + + para = para_prev( table_row_end( para )); + return cell_next( para_cell( para ) ); +} + +ME_Cell *cell_create( void ) +{ + ME_DisplayItem *item = ME_MakeDI( diCell ); + return &item->member.cell; } -BOOL ME_IsInTable(ME_DisplayItem *pItem) +ME_Cell *cell_next( ME_Cell *cell ) { - PARAFORMAT2 *pFmt; - if (!pItem) - return FALSE; - if (pItem->type == diRun) - pItem = ME_GetParagraph(pItem); - if (pItem->type != diParagraph) - return FALSE; - pFmt = &pItem->member.para.fmt; - return pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE; + return cell->next_cell; +} + +ME_Cell *cell_prev( ME_Cell *cell ) +{ + return cell->prev_cell; +} + +ME_Paragraph *cell_first_para( ME_Cell *cell ) +{ + return &ME_FindItemFwd( cell_get_di( cell ), diParagraph )->member.para; +} + +ME_Paragraph *cell_end_para( ME_Cell *cell ) +{ + ME_Cell *next = cell_next( cell ); + + if (!next) return cell_first_para( cell ); /* End of row */ + + return &ME_FindItemBack( cell_get_di( next ), diParagraph )->member.para; } /* Table rows should either be deleted completely or not at all. */ -void ME_ProtectPartialTableDeletion(ME_TextEditor *editor, ME_Cursor *c, int *nChars) +void table_protect_partial_deletion( ME_TextEditor *editor, ME_Cursor *c, int *num_chars ) { - int nOfs = ME_GetCursorOfs(c); + int start_ofs = ME_GetCursorOfs( c ); ME_Cursor c2 = *c; - ME_DisplayItem *this_para = c->pPara; - ME_DisplayItem *end_para; + ME_Paragraph *this_para = c->para, *end_para; - ME_MoveCursorChars(editor, &c2, *nChars, FALSE); - end_para = c2.pPara; - if (c2.pRun->member.run.nFlags & MERF_ENDPARA) { + ME_MoveCursorChars( editor, &c2, *num_chars, FALSE ); + end_para = c2.para; + if (c2.run->nFlags & MERF_ENDPARA) + { /* End offset might be in the middle of the end paragraph run. * If this is the case, then we need to use the next paragraph as the last * paragraphs. */ - int remaining = nOfs + *nChars - c2.pRun->member.run.nCharOfs - - end_para->member.para.nCharOfs; + int remaining = start_ofs + *num_chars - c2.run->nCharOfs - end_para->nCharOfs; if (remaining) { - assert(remaining < c2.pRun->member.run.len); - end_para = end_para->member.para.next_para; + assert( remaining < c2.run->len ); + end_para = para_next( end_para ); } } - if (!editor->bEmulateVersion10) { /* v4.1 */ - if (this_para->member.para.pCell != end_para->member.para.pCell || - ((this_para->member.para.nFlags|end_para->member.para.nFlags) - & (MEPF_ROWSTART|MEPF_ROWEND))) + if (!editor->bEmulateVersion10) /* v4.1 */ + { + if (para_cell( this_para ) != para_cell( end_para ) || + ((this_para->nFlags | end_para->nFlags) & (MEPF_ROWSTART | MEPF_ROWEND))) { while (this_para != end_para) { - ME_DisplayItem *next_para = this_para->member.para.next_para; - BOOL bTruancateDeletion = FALSE; - if (this_para->member.para.nFlags & MEPF_ROWSTART) { + ME_Paragraph *next_para = para_next( this_para ); + BOOL truancate_del = FALSE; + if (this_para->nFlags & MEPF_ROWSTART) + { /* The following while loop assumes that next_para is MEPF_ROWSTART, - * so moving back one paragraph let's it be processed as the start + * so moving back one paragraph lets it be processed as the start * of the row. */ next_para = this_para; - this_para = this_para->member.para.prev_para; - } else if (next_para->member.para.pCell != this_para->member.para.pCell - || this_para->member.para.nFlags & MEPF_ROWEND) + this_para = para_prev( this_para ); + } + else if (para_cell( next_para) != para_cell( this_para ) || this_para->nFlags & MEPF_ROWEND) { /* Start of the deletion from after the start of the table row. */ - bTruancateDeletion = TRUE; + truancate_del = TRUE; } - while (!bTruancateDeletion && - next_para->member.para.nFlags & MEPF_ROWSTART) + while (!truancate_del && next_para->nFlags & MEPF_ROWSTART) { - next_para = ME_GetTableRowEnd(next_para)->member.para.next_para; - if (next_para->member.para.nCharOfs > nOfs + *nChars) + next_para = para_next( table_row_end( next_para ) ); + if (next_para->nCharOfs > start_ofs + *num_chars) { /* End of deletion is not past the end of the table row. */ - next_para = this_para->member.para.next_para; + next_para = para_next( this_para ); /* Delete the end paragraph preceding the table row if the * preceding table row will be empty. */ - if (this_para->member.para.nCharOfs >= nOfs) - { - next_para = next_para->member.para.next_para; - } - bTruancateDeletion = TRUE; - } else { - this_para = next_para->member.para.prev_para; + if (this_para->nCharOfs >= start_ofs) next_para = para_next( next_para ); + truancate_del = TRUE; } + else this_para = para_prev( next_para ); } - if (bTruancateDeletion) + if (truancate_del) { - ME_Run *end_run = &ME_FindItemBack(next_para, diRun)->member.run; - int nCharsNew = (next_para->member.para.nCharOfs - nOfs - - end_run->len); - nCharsNew = max(nCharsNew, 0); - assert(nCharsNew <= *nChars); - *nChars = nCharsNew; + ME_Run *end_run = para_end_run( para_prev( next_para ) ); + int new_chars = next_para->nCharOfs - start_ofs - end_run->len; + new_chars = max( new_chars, 0 ); + assert( new_chars <= *num_chars); + *num_chars = new_chars; break; } this_para = next_para; } } - } else { /* v1.0 - 3.0 */ - ME_DisplayItem *pRun; - int nCharsToBoundary; + } + else /* v1.0 - 3.0 */ + { + ME_Run *run; + int chars_to_boundary; - if ((this_para->member.para.nCharOfs != nOfs || this_para == end_para) && - this_para->member.para.fmt.dwMask & PFM_TABLE && - this_para->member.para.fmt.wEffects & PFE_TABLE) + if ((this_para->nCharOfs != start_ofs || this_para == end_para) && para_in_table( this_para )) { - pRun = c->pRun; + run = c->run; /* Find the next tab or end paragraph to use as a delete boundary */ - while (!(pRun->member.run.nFlags & (MERF_TAB|MERF_ENDPARA))) - pRun = ME_FindItemFwd(pRun, diRun); - nCharsToBoundary = pRun->member.run.nCharOfs - - c->pRun->member.run.nCharOfs - - c->nOffset; - *nChars = min(*nChars, nCharsToBoundary); - } else if (end_para->member.para.fmt.dwMask & PFM_TABLE && - end_para->member.para.fmt.wEffects & PFE_TABLE) + while (!(run->nFlags & (MERF_TAB | MERF_ENDPARA))) + run = run_next( run ); + chars_to_boundary = run->nCharOfs - c->run->nCharOfs - c->nOffset; + *num_chars = min( *num_chars, chars_to_boundary ); + } + else if (para_in_table( end_para )) { /* The deletion starts from before the row, so don't join it with * previous non-empty paragraphs. */ - ME_DisplayItem *curPara; - pRun = NULL; - if (nOfs > this_para->member.para.nCharOfs) { - pRun = ME_FindItemBack(end_para, diRun); - curPara = end_para->member.para.prev_para; + ME_Paragraph *cur_para; + run = NULL; + if (start_ofs > this_para->nCharOfs) + { + cur_para = para_prev( end_para ); + run = para_end_run( cur_para ); } - if (!pRun) { - pRun = ME_FindItemFwd(end_para, diRun); - curPara = end_para; + if (!run) + { + cur_para = end_para; + run = para_first_run( end_para ); } - if (pRun) + if (run) { - nCharsToBoundary = curPara->member.para.nCharOfs - + pRun->member.run.nCharOfs - - nOfs; - if (nCharsToBoundary >= 0) - *nChars = min(*nChars, nCharsToBoundary); + chars_to_boundary = cur_para->nCharOfs + run->nCharOfs - start_ofs; + if (chars_to_boundary >= 0) *num_chars = min( *num_chars, chars_to_boundary ); } } - if (*nChars < 0) - *nChars = 0; + if (*num_chars < 0) *num_chars = 0; } } -ME_DisplayItem* ME_AppendTableRow(ME_TextEditor *editor, - ME_DisplayItem *table_row) +ME_Paragraph* table_append_row( ME_TextEditor *editor, ME_Paragraph *table_row ) { WCHAR endl = '\r', tab = '\t'; - ME_DisplayItem *run; - PARAFORMAT2 *pFmt; + ME_Run *run; int i; - assert(table_row); - assert(table_row->type == diParagraph); - if (!editor->bEmulateVersion10) { /* v4.1 */ - ME_DisplayItem *insertedCell, *para, *cell, *prevTableEnd; - cell = ME_FindItemFwd(ME_GetTableRowStart(table_row), diCell); - prevTableEnd = ME_GetTableRowEnd(table_row); - para = prevTableEnd->member.para.next_para; - run = ME_FindItemFwd(para, diRun); - editor->pCursors[0].pPara = para; - editor->pCursors[0].pRun = run; + if (!editor->bEmulateVersion10) /* v4.1 */ + { + ME_Cell *new_cell, *cell; + ME_Paragraph *para, *prev_table_end, *new_row_start; + + cell = table_row_first_cell( table_row ); + prev_table_end = table_row_end( table_row ); + para = para_next( prev_table_end ); + run = para_first_run( para ); + editor->pCursors[0].para = para; + editor->pCursors[0].run = run; editor->pCursors[0].nOffset = 0; editor->pCursors[1] = editor->pCursors[0]; - para = ME_InsertTableRowStartFromCursor(editor); - insertedCell = ME_FindItemFwd(para, diCell); + new_row_start = table_insert_row_start( editor, editor->pCursors ); + new_cell = table_row_first_cell( new_row_start ); /* Copy cell properties */ - insertedCell->member.cell.nRightBoundary = cell->member.cell.nRightBoundary; - insertedCell->member.cell.border = cell->member.cell.border; - while (cell->member.cell.next_cell) { - cell = cell->member.cell.next_cell; - para = ME_InsertTableCellFromCursor(editor); - insertedCell = ME_FindItemBack(para, diCell); + new_cell->nRightBoundary = cell->nRightBoundary; + new_cell->border = cell->border; + while (cell_next( cell )) + { + cell = cell_next( cell ); + para = table_insert_cell( editor, editor->pCursors ); + new_cell = para_cell( para ); /* Copy cell properties */ - insertedCell->member.cell.nRightBoundary = cell->member.cell.nRightBoundary; - insertedCell->member.cell.border = cell->member.cell.border; + new_cell->nRightBoundary = cell->nRightBoundary; + new_cell->border = cell->border; }; - para = ME_InsertTableRowEndFromCursor(editor); - para->member.para.fmt = prevTableEnd->member.para.fmt; + para = table_insert_row_end( editor, editor->pCursors ); + para->fmt = prev_table_end->fmt; /* return the table row start for the inserted paragraph */ - return ME_FindItemFwd(cell, diParagraph)->member.para.next_para; - } else { /* v1.0 - 3.0 */ - run = ME_FindItemBack(table_row->member.para.next_para, diRun); - pFmt = &table_row->member.para.fmt; - assert(pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE); - editor->pCursors[0].pPara = table_row; - editor->pCursors[0].pRun = run; + return new_row_start; + } + else /* v1.0 - 3.0 */ + { + run = para_end_run( table_row ); + assert( para_in_table( table_row ) ); + editor->pCursors[0].para = table_row; + editor->pCursors[0].run = run; editor->pCursors[0].nOffset = 0; editor->pCursors[1] = editor->pCursors[0]; - ME_InsertTextFromCursor(editor, 0, &endl, 1, run->member.run.style); - run = editor->pCursors[0].pRun; - for (i = 0; i < pFmt->cTabCount; i++) { - ME_InsertTextFromCursor(editor, 0, &tab, 1, run->member.run.style); - } - return table_row->member.para.next_para; + ME_InsertTextFromCursor( editor, 0, &endl, 1, run->style ); + run = editor->pCursors[0].run; + for (i = 0; i < table_row->fmt.cTabCount; i++) + ME_InsertTextFromCursor( editor, 0, &tab, 1, run->style ); + + return para_next( table_row ); } } /* Selects the next table cell or appends a new table row if at end of table */ -static void ME_SelectOrInsertNextCell(ME_TextEditor *editor, - ME_DisplayItem *run) +static void table_select_next_cell_or_append( ME_TextEditor *editor, ME_Run *run ) { - ME_DisplayItem *para = ME_GetParagraph(run); + ME_Paragraph *para = run->para; + ME_Cell *cell; int i; - assert(run && run->type == diRun); - assert(ME_IsInTable(run)); - if (!editor->bEmulateVersion10) { /* v4.1 */ - ME_DisplayItem *cell; + assert( para_in_table( para ) ); + if (!editor->bEmulateVersion10) /* v4.1 */ + { /* Get the initial cell */ - if (para->member.para.nFlags & MEPF_ROWSTART) { - cell = para->member.para.next_para->member.para.pCell; - } else if (para->member.para.nFlags & MEPF_ROWEND) { - cell = para->member.para.prev_para->member.para.pCell; - } else { - cell = para->member.para.pCell; - } - assert(cell); + if (para->nFlags & MEPF_ROWSTART) cell = para_cell( para_next( para ) ); + else if (para->nFlags & MEPF_ROWEND) cell = para_cell( para_prev( para ) ); + else cell = para_cell( para ); + /* Get the next cell. */ - if (cell->member.cell.next_cell && - cell->member.cell.next_cell->member.cell.next_cell) + if (cell_next( cell ) && cell_next( cell_next( cell ) )) + cell = cell_next( cell ); + else { - cell = cell->member.cell.next_cell; - } else { - para = ME_GetTableRowEnd(ME_FindItemFwd(cell, diParagraph)); - para = para->member.para.next_para; - assert(para); - if (para->member.para.nFlags & MEPF_ROWSTART) { - cell = para->member.para.next_para->member.para.pCell; - } else { + para = para_next( table_row_end( para ) ); + if (para->nFlags & MEPF_ROWSTART) cell = para_cell( para_next( para ) ); + else + { /* Insert row */ - para = para->member.para.prev_para; - para = ME_AppendTableRow(editor, ME_GetTableRowStart(para)); + para = para_prev( para ); + para = table_append_row( editor, table_row_start( para ) ); /* Put cursor at the start of the new table row */ - para = para->member.para.next_para; - editor->pCursors[0].pPara = para; - editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); + para = para_next( para ); + editor->pCursors[0].para = para; + editor->pCursors[0].run = para_first_run( para ); editor->pCursors[0].nOffset = 0; editor->pCursors[1] = editor->pCursors[0]; ME_WrapMarkedParagraphs(editor); @@ -504,62 +417,60 @@ static void ME_SelectOrInsertNextCell(ME_TextEditor *editor, } } /* Select cell */ - editor->pCursors[1].pRun = ME_FindItemFwd(cell, diRun); - editor->pCursors[1].pPara = ME_GetParagraph(editor->pCursors[1].pRun); + editor->pCursors[1].para = cell_first_para( cell ); + editor->pCursors[1].run = para_first_run( editor->pCursors[1].para ); editor->pCursors[1].nOffset = 0; - assert(editor->pCursors[0].pRun); - cell = cell->member.cell.next_cell; - editor->pCursors[0].pRun = ME_FindItemBack(cell, diRun); - editor->pCursors[0].pPara = ME_GetParagraph(editor->pCursors[0].pRun); + editor->pCursors[0].para = cell_end_para( cell ); + editor->pCursors[0].run = para_end_run( editor->pCursors[0].para ); editor->pCursors[0].nOffset = 0; - assert(editor->pCursors[1].pRun); - } else { /* v1.0 - 3.0 */ - if (run->member.run.nFlags & MERF_ENDPARA && - ME_IsInTable(ME_FindItemFwd(run, diParagraphOrEnd))) + } + else /* v1.0 - 3.0 */ + { + if (run->nFlags & MERF_ENDPARA && para_in_table( para_next( para ) )) { - run = ME_FindItemFwd(run, diRun); + run = run_next_all_paras( run ); assert(run); } for (i = 0; i < 2; i++) { - while (!(run->member.run.nFlags & MERF_TAB)) + while (!(run->nFlags & MERF_TAB)) { - run = ME_FindItemFwd(run, diRunOrParagraphOrEnd); - if (run->type != diRun) + if (!run_next( run )) { - para = run; - if (ME_IsInTable(para)) + para = para_next( run->para ); + if (para_in_table( para )) { - run = ME_FindItemFwd(para, diRun); - assert(run); - editor->pCursors[0].pPara = para; - editor->pCursors[0].pRun = run; + run = para_first_run( para ); + editor->pCursors[0].para = para; + editor->pCursors[0].run = run; editor->pCursors[0].nOffset = 0; i = 1; - } else { + } + else + { /* Insert table row */ - para = ME_AppendTableRow(editor, para->member.para.prev_para); + para = table_append_row( editor, para_prev( para ) ); /* Put cursor at the start of the new table row */ - editor->pCursors[0].pPara = para; - editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); + editor->pCursors[0].para = para; + editor->pCursors[0].run = para_first_run( para ); editor->pCursors[0].nOffset = 0; editor->pCursors[1] = editor->pCursors[0]; ME_WrapMarkedParagraphs(editor); return; } } + else run = run_next( run ); } - if (i == 0) - run = ME_FindItemFwd(run, diRun); - editor->pCursors[i].pRun = run; - editor->pCursors[i].pPara = ME_GetParagraph(run); + if (i == 0) run = run_next_all_paras( run ); + editor->pCursors[i].run = run; + editor->pCursors[i].para = run->para; editor->pCursors[i].nOffset = 0; } } } -void ME_TabPressedInTable(ME_TextEditor *editor, BOOL bSelectedRow) +void table_handle_tab( ME_TextEditor *editor, BOOL selected_row ) { /* FIXME: Shift tab should move to the previous cell. */ ME_Cursor fromCursor, toCursor; @@ -572,43 +483,41 @@ void ME_TabPressedInTable(ME_TextEditor *editor, BOOL bSelectedRow) { fromCursor = editor->pCursors[0]; toCursor = editor->pCursors[1]; - } else { + } + else + { fromCursor = editor->pCursors[1]; toCursor = editor->pCursors[0]; } } if (!editor->bEmulateVersion10) /* v4.1 */ { - if (!ME_IsInTable(toCursor.pRun)) + if (!para_in_table( toCursor.para )) { editor->pCursors[0] = toCursor; editor->pCursors[1] = toCursor; - } else { - ME_SelectOrInsertNextCell(editor, toCursor.pRun); } - } else { /* v1.0 - 3.0 */ - if (!ME_IsInTable(fromCursor.pRun)) { + else table_select_next_cell_or_append( editor, toCursor.run ); + } + else /* v1.0 - 3.0 */ + { + if (!para_in_table( fromCursor.para )) + { editor->pCursors[0] = fromCursor; editor->pCursors[1] = fromCursor; /* FIXME: For some reason the caret is shown at the start of the - * previous paragraph in v1.0 to v3.0, and bCaretAtEnd only works - * within the paragraph for wrapped lines. */ - if (ME_FindItemBack(fromCursor.pRun, diRun)) - editor->bCaretAtEnd = TRUE; - } else if ((bSelectedRow || !ME_IsInTable(toCursor.pRun))) { - ME_SelectOrInsertNextCell(editor, fromCursor.pRun); - } else { - if (ME_IsSelection(editor) && !toCursor.nOffset) - { - ME_DisplayItem *run; - run = ME_FindItemBack(toCursor.pRun, diRunOrParagraphOrEnd); - if (run->type == diRun && run->member.run.nFlags & MERF_TAB) - ME_SelectOrInsertNextCell(editor, run); - else - ME_SelectOrInsertNextCell(editor, toCursor.pRun); - } else { - ME_SelectOrInsertNextCell(editor, toCursor.pRun); - } + * previous paragraph in v1.0 to v3.0 */ + } + else if ((selected_row || !para_in_table( toCursor.para ))) + table_select_next_cell_or_append( editor, fromCursor.run ); + else + { + ME_Run *run = run_prev( toCursor.run ); + + if (ME_IsSelection(editor) && !toCursor.nOffset && run && run->nFlags & MERF_TAB) + table_select_next_cell_or_append( editor, run ); + else + table_select_next_cell_or_append( editor, toCursor.run ); } } ME_InvalidateSelection(editor); @@ -619,16 +528,17 @@ void ME_TabPressedInTable(ME_TextEditor *editor, BOOL bSelectedRow) /* Make sure the cursor is not in the hidden table row start paragraph * without a selection. */ -void ME_MoveCursorFromTableRowStartParagraph(ME_TextEditor *editor) +void table_move_from_row_start( ME_TextEditor *editor ) { - ME_DisplayItem *para = editor->pCursors[0].pPara; - if (para == editor->pCursors[1].pPara && - para->member.para.nFlags & MEPF_ROWSTART) { + ME_Paragraph *para = editor->pCursors[0].para; + + if (para == editor->pCursors[1].para && para->nFlags & MEPF_ROWSTART) + { /* The cursors should not be at the hidden start row paragraph without * a selection, so the cursor is moved into the first cell. */ - para = para->member.para.next_para; - editor->pCursors[0].pPara = para; - editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); + para = para_next( para ); + editor->pCursors[0].para = para; + editor->pCursors[0].run = para_first_run( para ); editor->pCursors[0].nOffset = 0; editor->pCursors[1] = editor->pCursors[0]; } diff --git a/dll/win32/riched20/txthost.c b/dll/win32/riched20/txthost.c index 35e01633b93d9..f2560bccd3c25 100644 --- a/dll/win32/riched20/txthost.c +++ b/dll/win32/riched20/txthost.c @@ -25,33 +25,88 @@ #include "richole.h" #include "imm.h" #include "textserv.h" -#include "wine/asm.h" #include "wine/debug.h" #include "editstr.h" +#include "rtf.h" +#include "undocuser.h" +#include "riched20.h" WINE_DEFAULT_DEBUG_CHANNEL(richedit); -typedef struct ITextHostImpl { - ITextHost ITextHost_iface; +struct host +{ + ITextHost2 ITextHost_iface; LONG ref; - HWND hWnd; - BOOL bEmulateVersion10; + ITextServices *text_srv; + HWND window, parent; + unsigned int emulate_10 : 1; + unsigned int dialog_mode : 1; + unsigned int want_return : 1; + unsigned int sel_bar : 1; + unsigned int client_edge : 1; + unsigned int use_set_rect : 1; + unsigned int use_back_colour : 1; + unsigned int defer_release : 1; PARAFORMAT2 para_fmt; -} ITextHostImpl; + DWORD props, scrollbars, event_mask; + RECT client_rect, set_rect; + COLORREF back_colour; + WCHAR password_char; + unsigned int notify_level; +}; + +static const ITextHost2Vtbl textHostVtbl; + +static BOOL listbox_registered; +static BOOL combobox_registered; + +static void host_init_props( struct host *host ) +{ + DWORD style; -static const ITextHostVtbl textHostVtbl; + style = GetWindowLongW( host->window, GWL_STYLE ); + + /* text services assumes the scrollbars are originally not shown, so hide them. + However with ES_DISABLENOSCROLL it'll immediately show them, so don't bother */ + if (!(style & ES_DISABLENOSCROLL)) ShowScrollBar( host->window, SB_BOTH, FALSE ); + + host->scrollbars = style & (WS_VSCROLL | WS_HSCROLL | ES_AUTOVSCROLL | + ES_AUTOHSCROLL | ES_DISABLENOSCROLL); + if (style & WS_VSCROLL) host->scrollbars |= ES_AUTOVSCROLL; + if ((style & WS_HSCROLL) && !host->emulate_10) host->scrollbars |= ES_AUTOHSCROLL; + + host->props = TXTBIT_RICHTEXT | TXTBIT_ALLOWBEEP; + if (style & ES_MULTILINE) host->props |= TXTBIT_MULTILINE; + if (style & ES_READONLY) host->props |= TXTBIT_READONLY; + if (style & ES_PASSWORD) host->props |= TXTBIT_USEPASSWORD; + if (!(style & ES_NOHIDESEL)) host->props |= TXTBIT_HIDESELECTION; + if (style & ES_SAVESEL) host->props |= TXTBIT_SAVESELECTION; + if (style & ES_VERTICAL) host->props |= TXTBIT_VERTICAL; + if (style & ES_NOOLEDRAGDROP) host->props |= TXTBIT_DISABLEDRAG; + + if (!(host->scrollbars & ES_AUTOHSCROLL)) host->props |= TXTBIT_WORDWRAP; + + host->sel_bar = !!(style & ES_SELECTIONBAR); + host->want_return = !!(style & ES_WANTRETURN); + + style = GetWindowLongW( host->window, GWL_EXSTYLE ); + host->client_edge = !!(style & WS_EX_CLIENTEDGE); +} -ITextHost *ME_CreateTextHost(HWND hwnd, CREATESTRUCTW *cs, BOOL bEmulateVersion10) +struct host *host_create( HWND hwnd, CREATESTRUCTW *cs, BOOL emulate_10 ) { - ITextHostImpl *texthost; + struct host *texthost; texthost = CoTaskMemAlloc(sizeof(*texthost)); if (!texthost) return NULL; texthost->ITextHost_iface.lpVtbl = &textHostVtbl; texthost->ref = 1; - texthost->hWnd = hwnd; - texthost->bEmulateVersion10 = bEmulateVersion10; + texthost->text_srv = NULL; + texthost->window = hwnd; + texthost->parent = cs->hwndParent; + texthost->emulate_10 = emulate_10; + texthost->dialog_mode = 0; memset( &texthost->para_fmt, 0, sizeof(texthost->para_fmt) ); texthost->para_fmt.cbSize = sizeof(texthost->para_fmt); texthost->para_fmt.dwMask = PFM_ALIGNMENT; @@ -60,357 +115,367 @@ ITextHost *ME_CreateTextHost(HWND hwnd, CREATESTRUCTW *cs, BOOL bEmulateVersion1 texthost->para_fmt.wAlignment = PFA_RIGHT; if (cs->style & ES_CENTER) texthost->para_fmt.wAlignment = PFA_CENTER; - - return &texthost->ITextHost_iface; + host_init_props( texthost ); + texthost->event_mask = 0; + texthost->use_set_rect = 0; + SetRectEmpty( &texthost->set_rect ); + GetClientRect( hwnd, &texthost->client_rect ); + texthost->use_back_colour = 0; + texthost->password_char = (texthost->props & TXTBIT_USEPASSWORD) ? '*' : 0; + texthost->defer_release = 0; + texthost->notify_level = 0; + + return texthost; } -static inline ITextHostImpl *impl_from_ITextHost(ITextHost *iface) +static inline struct host *impl_from_ITextHost( ITextHost2 *iface ) { - return CONTAINING_RECORD(iface, ITextHostImpl, ITextHost_iface); + return CONTAINING_RECORD( iface, struct host, ITextHost_iface ); } -static HRESULT WINAPI ITextHostImpl_QueryInterface(ITextHost *iface, REFIID riid, void **ppvObject) +static HRESULT WINAPI ITextHostImpl_QueryInterface( ITextHost2 *iface, REFIID iid, void **obj ) { - ITextHostImpl *This = impl_from_ITextHost(iface); + struct host *host = impl_from_ITextHost( iface ); - if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_ITextHost)) { - *ppvObject = &This->ITextHost_iface; - ITextHost_AddRef((ITextHost *)*ppvObject); + if (IsEqualIID( iid, &IID_IUnknown ) || IsEqualIID( iid, &IID_ITextHost ) || IsEqualIID( iid, &IID_ITextHost2 )) + { + *obj = &host->ITextHost_iface; + ITextHost_AddRef( (ITextHost *)*obj ); return S_OK; } - FIXME("Unknown interface: %s\n", debugstr_guid(riid)); + FIXME( "Unknown interface: %s\n", debugstr_guid( iid ) ); return E_NOINTERFACE; } -static ULONG WINAPI ITextHostImpl_AddRef(ITextHost *iface) +static ULONG WINAPI ITextHostImpl_AddRef( ITextHost2 *iface ) { - ITextHostImpl *This = impl_from_ITextHost(iface); - ULONG ref = InterlockedIncrement(&This->ref); + struct host *host = impl_from_ITextHost( iface ); + ULONG ref = InterlockedIncrement( &host->ref ); return ref; } -static ULONG WINAPI ITextHostImpl_Release(ITextHost *iface) +static ULONG WINAPI ITextHostImpl_Release( ITextHost2 *iface ) { - ITextHostImpl *This = impl_from_ITextHost(iface); - ULONG ref = InterlockedDecrement(&This->ref); + struct host *host = impl_from_ITextHost( iface ); + ULONG ref = InterlockedDecrement( &host->ref ); if (!ref) { - SetWindowLongPtrW(This->hWnd, 0, 0); - CoTaskMemFree(This); + SetWindowLongPtrW( host->window, 0, 0 ); + ITextServices_Release( host->text_srv ); + CoTaskMemFree( host ); } return ref; } -DECLSPEC_HIDDEN HDC __thiscall ITextHostImpl_TxGetDC(ITextHost *iface) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetDC,4) +DECLSPEC_HIDDEN HDC __thiscall ITextHostImpl_TxGetDC( ITextHost2 *iface ) { - ITextHostImpl *This = impl_from_ITextHost(iface); - return GetDC(This->hWnd); + struct host *host = impl_from_ITextHost( iface ); + return GetDC( host->window ); } -DECLSPEC_HIDDEN INT __thiscall ITextHostImpl_TxReleaseDC(ITextHost *iface, HDC hdc) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxReleaseDC,8) +DECLSPEC_HIDDEN INT __thiscall ITextHostImpl_TxReleaseDC( ITextHost2 *iface, HDC hdc ) { - ITextHostImpl *This = impl_from_ITextHost(iface); - return ReleaseDC(This->hWnd, hdc); + struct host *host = impl_from_ITextHost( iface ); + return ReleaseDC( host->window, hdc ); } -DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxShowScrollBar(ITextHost *iface, INT fnBar, BOOL fShow) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxShowScrollBar,12) +DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxShowScrollBar( ITextHost2 *iface, INT bar, BOOL show ) { - ITextHostImpl *This = impl_from_ITextHost(iface); - return ShowScrollBar(This->hWnd, fnBar, fShow); + struct host *host = impl_from_ITextHost( iface ); + return ShowScrollBar( host->window, bar, show ); } -DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxEnableScrollBar(ITextHost *iface, INT fuSBFlags, INT fuArrowflags) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxEnableScrollBar,12) +DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxEnableScrollBar( ITextHost2 *iface, INT bar, INT arrows ) { - ITextHostImpl *This = impl_from_ITextHost(iface); - return EnableScrollBar(This->hWnd, fuSBFlags, fuArrowflags); + struct host *host = impl_from_ITextHost( iface ); + return EnableScrollBar( host->window, bar, arrows ); } -DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxSetScrollRange(ITextHost *iface, INT fnBar, LONG nMinPos, INT nMaxPos, - BOOL fRedraw) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetScrollRange,20) +DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxSetScrollRange( ITextHost2 *iface, INT bar, LONG min_pos, INT max_pos, BOOL redraw ) { - ITextHostImpl *This = impl_from_ITextHost(iface); - return SetScrollRange(This->hWnd, fnBar, nMinPos, nMaxPos, fRedraw); + struct host *host = impl_from_ITextHost( iface ); + SCROLLINFO info = { .cbSize = sizeof(info), .fMask = SIF_PAGE | SIF_RANGE }; + + if (bar != SB_HORZ && bar != SB_VERT) + { + FIXME( "Unexpected bar %d\n", bar ); + return FALSE; + } + + if (host->scrollbars & ES_DISABLENOSCROLL) info.fMask |= SIF_DISABLENOSCROLL; + + if (host->text_srv) /* This can be called during text services creation */ + { + if (bar == SB_HORZ) ITextServices_TxGetHScroll( host->text_srv, NULL, NULL, NULL, (LONG *)&info.nPage, NULL ); + else ITextServices_TxGetVScroll( host->text_srv, NULL, NULL, NULL, (LONG *)&info.nPage, NULL ); + } + + info.nMin = min_pos; + info.nMax = max_pos; + return SetScrollInfo( host->window, bar, &info, redraw ); } -DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxSetScrollPos(ITextHost *iface, INT fnBar, INT nPos, BOOL fRedraw) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetScrollPos,16) +DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxSetScrollPos( ITextHost2 *iface, INT bar, INT pos, BOOL redraw ) { - ITextHostImpl *This = impl_from_ITextHost(iface); - return SetScrollPos(This->hWnd, fnBar, nPos, fRedraw) != 0; + struct host *host = impl_from_ITextHost( iface ); + DWORD style = GetWindowLongW( host->window, GWL_STYLE ); + DWORD mask = (bar == SB_HORZ) ? WS_HSCROLL : WS_VSCROLL; + BOOL show = TRUE, shown = style & mask; + + if (bar != SB_HORZ && bar != SB_VERT) + { + FIXME( "Unexpected bar %d\n", bar ); + return FALSE; + } + + /* If the application has adjusted the scrollbar's visibility it is reset */ + if (!(host->scrollbars & ES_DISABLENOSCROLL)) + { + if (bar == SB_HORZ) ITextServices_TxGetHScroll( host->text_srv, NULL, NULL, NULL, NULL, &show ); + else ITextServices_TxGetVScroll( host->text_srv, NULL, NULL, NULL, NULL, &show ); + } + + if (!show ^ !shown) ShowScrollBar( host->window, bar, show ); + return SetScrollPos( host->window, bar, pos, redraw ) != 0; } -DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxInvalidateRect(ITextHost *iface, LPCRECT prc, BOOL fMode) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxInvalidateRect,12) +DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxInvalidateRect( ITextHost2 *iface, const RECT *rect, BOOL mode ) { - ITextHostImpl *This = impl_from_ITextHost(iface); - InvalidateRect(This->hWnd, prc, fMode); + struct host *host = impl_from_ITextHost( iface ); + InvalidateRect( host->window, rect, mode ); } -DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxViewChange(ITextHost *iface, BOOL fUpdate) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxViewChange,8) +DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxViewChange( ITextHost2 *iface, BOOL update ) { - ITextHostImpl *This = impl_from_ITextHost(iface); - if (fUpdate) - UpdateWindow(This->hWnd); + struct host *host = impl_from_ITextHost( iface ); + if (update) UpdateWindow( host->window ); } -DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxCreateCaret(ITextHost *iface, HBITMAP hbmp, INT xWidth, INT yHeight) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxCreateCaret,16) +DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxCreateCaret( ITextHost2 *iface, HBITMAP bitmap, INT width, INT height ) { - ITextHostImpl *This = impl_from_ITextHost(iface); - return CreateCaret(This->hWnd, hbmp, xWidth, yHeight); + struct host *host = impl_from_ITextHost( iface ); + return CreateCaret( host->window, bitmap, width, height ); } -DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxShowCaret(ITextHost *iface, BOOL fShow) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxShowCaret,8) +DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxShowCaret( ITextHost2 *iface, BOOL show ) { - ITextHostImpl *This = impl_from_ITextHost(iface); - if (fShow) - return ShowCaret(This->hWnd); - else - return HideCaret(This->hWnd); + struct host *host = impl_from_ITextHost( iface ); + if (show) return ShowCaret( host->window ); + else return HideCaret( host->window ); } -DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxSetCaretPos(ITextHost *iface, - INT x, INT y) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetCaretPos,12) +DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxSetCaretPos( ITextHost2 *iface, INT x, INT y ) { return SetCaretPos(x, y); } -DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxSetTimer(ITextHost *iface, UINT idTimer, UINT uTimeout) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetTimer,12) +DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxSetTimer( ITextHost2 *iface, UINT id, UINT timeout ) { - ITextHostImpl *This = impl_from_ITextHost(iface); - return SetTimer(This->hWnd, idTimer, uTimeout, NULL) != 0; + struct host *host = impl_from_ITextHost( iface ); + return SetTimer( host->window, id, timeout, NULL ) != 0; } -DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxKillTimer(ITextHost *iface, UINT idTimer) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxKillTimer,8) +DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxKillTimer( ITextHost2 *iface, UINT id ) { - ITextHostImpl *This = impl_from_ITextHost(iface); - KillTimer(This->hWnd, idTimer); + struct host *host = impl_from_ITextHost( iface ); + KillTimer( host->window, id ); } -DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxScrollWindowEx(ITextHost *iface, INT dx, INT dy, LPCRECT lprcScroll, - LPCRECT lprcClip, HRGN hRgnUpdate, LPRECT lprcUpdate, - UINT fuScroll) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxScrollWindowEx,32) +DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxScrollWindowEx( ITextHost2 *iface, INT dx, INT dy, const RECT *scroll, + const RECT *clip, HRGN update_rgn, RECT *update_rect, + UINT flags ) { - ITextHostImpl *This = impl_from_ITextHost(iface); - ScrollWindowEx(This->hWnd, dx, dy, lprcScroll, lprcClip, - hRgnUpdate, lprcUpdate, fuScroll); + struct host *host = impl_from_ITextHost( iface ); + ScrollWindowEx( host->window, dx, dy, scroll, clip, update_rgn, update_rect, flags ); } -DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxSetCapture(ITextHost *iface, BOOL fCapture) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetCapture,8) +DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxSetCapture( ITextHost2 *iface, BOOL capture ) { - ITextHostImpl *This = impl_from_ITextHost(iface); - if (fCapture) - SetCapture(This->hWnd); - else - ReleaseCapture(); + struct host *host = impl_from_ITextHost( iface ); + if (capture) SetCapture( host->window ); + else ReleaseCapture(); } -DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxSetFocus(ITextHost *iface) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetFocus,4) +DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxSetFocus( ITextHost2 *iface ) { - ITextHostImpl *This = impl_from_ITextHost(iface); - SetFocus(This->hWnd); + struct host *host = impl_from_ITextHost( iface ); + SetFocus( host->window ); } -DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxSetCursor(ITextHost *iface, HCURSOR hcur, BOOL fText) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetCursor,12) +DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxSetCursor( ITextHost2 *iface, HCURSOR cursor, BOOL text ) { - SetCursor(hcur); + SetCursor( cursor ); } -DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxScreenToClient(ITextHost *iface, LPPOINT lppt) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxScreenToClient,8) +DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxScreenToClient( ITextHost2 *iface, POINT *pt ) { - ITextHostImpl *This = impl_from_ITextHost(iface); - return ScreenToClient(This->hWnd, lppt); + struct host *host = impl_from_ITextHost( iface ); + return ScreenToClient( host->window, pt ); } -DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxClientToScreen(ITextHost *iface, LPPOINT lppt) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxClientToScreen,8) +DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxClientToScreen( ITextHost2 *iface, POINT *pt ) { - ITextHostImpl *This = impl_from_ITextHost(iface); - return ClientToScreen(This->hWnd, lppt); + struct host *host = impl_from_ITextHost( iface ); + return ClientToScreen( host->window, pt ); } -DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxActivate(ITextHost *iface, LONG *plOldState) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxActivate,8) +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxActivate( ITextHost2 *iface, LONG *old_state ) { - ITextHostImpl *This = impl_from_ITextHost(iface); - *plOldState = HandleToLong(SetActiveWindow(This->hWnd)); - return (*plOldState ? S_OK : E_FAIL); + struct host *host = impl_from_ITextHost( iface ); + *old_state = HandleToLong( SetActiveWindow( host->window ) ); + return *old_state ? S_OK : E_FAIL; } -DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxDeactivate(ITextHost *iface, LONG lNewState) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxDeactivate,8) +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxDeactivate( ITextHost2 *iface, LONG new_state ) { - HWND ret = SetActiveWindow(LongToHandle(lNewState)); - return (ret ? S_OK : E_FAIL); + HWND ret = SetActiveWindow( LongToHandle( new_state ) ); + return ret ? S_OK : E_FAIL; } -DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetClientRect(ITextHost *iface, LPRECT prc) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetClientRect,8) +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetClientRect( ITextHost2 *iface, RECT *rect ) { - ITextHostImpl *This = impl_from_ITextHost(iface); - int ret = GetClientRect(This->hWnd, prc); - return (ret ? S_OK : E_FAIL); + struct host *host = impl_from_ITextHost( iface ); + + if (!host->use_set_rect) + { + *rect = host->client_rect; + if (host->client_edge) rect->top += 1; + InflateRect( rect, -1, 0 ); + } + else *rect = host->set_rect; + + return S_OK; } -DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetViewInset(ITextHost *iface, LPRECT prc) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetViewInset,8) +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetViewInset( ITextHost2 *iface, RECT *rect ) { - prc->top = 0; - prc->left = 0; - prc->bottom = 0; - prc->right = 0; + SetRectEmpty( rect ); return S_OK; } -DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetCharFormat(ITextHost *iface, const CHARFORMATW **ppCF) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetCharFormat,8) +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetCharFormat( ITextHost2 *iface, const CHARFORMATW **ppCF ) { return E_NOTIMPL; } -DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetParaFormat(ITextHost *iface, const PARAFORMAT **fmt) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetParaFormat,8) +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetParaFormat( ITextHost2 *iface, const PARAFORMAT **fmt ) { - ITextHostImpl *This = impl_from_ITextHost(iface); - *fmt = (const PARAFORMAT *)&This->para_fmt; + struct host *host = impl_from_ITextHost( iface ); + *fmt = (const PARAFORMAT *)&host->para_fmt; return S_OK; } -DECLSPEC_HIDDEN COLORREF __thiscall ITextHostImpl_TxGetSysColor(ITextHost *iface, int nIndex) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetSysColor,8) +DECLSPEC_HIDDEN COLORREF __thiscall ITextHostImpl_TxGetSysColor( ITextHost2 *iface, int index ) { - return GetSysColor(nIndex); + struct host *host = impl_from_ITextHost( iface ); + + if (index == COLOR_WINDOW && host->use_back_colour) return host->back_colour; + return GetSysColor( index ); } -DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetBackStyle(ITextHost *iface, TXTBACKSTYLE *pStyle) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetBackStyle,8) +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetBackStyle( ITextHost2 *iface, TXTBACKSTYLE *style ) { - *pStyle = TXTBACK_OPAQUE; + *style = TXTBACK_OPAQUE; return S_OK; } -DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetMaxLength(ITextHost *iface, DWORD *pLength) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetMaxLength,8) +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetMaxLength( ITextHost2 *iface, DWORD *length ) { - *pLength = INFINITE; + *length = INFINITE; return S_OK; } -DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetScrollBars(ITextHost *iface, DWORD *pdwScrollBar) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetScrollBars,8) +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetScrollBars( ITextHost2 *iface, DWORD *scrollbars ) { - ITextHostImpl *This = impl_from_ITextHost(iface); - ME_TextEditor *editor = (ME_TextEditor*)GetWindowLongPtrW(This->hWnd, 0); - const DWORD mask = WS_VSCROLL| - WS_HSCROLL| - ES_AUTOVSCROLL| - ES_AUTOHSCROLL| - ES_DISABLENOSCROLL; - if (editor) - { - *pdwScrollBar = editor->styleFlags & mask; - } else { - DWORD style = GetWindowLongW(This->hWnd, GWL_STYLE); - if (style & WS_VSCROLL) - style |= ES_AUTOVSCROLL; - if (!This->bEmulateVersion10 && (style & WS_HSCROLL)) - style |= ES_AUTOHSCROLL; - *pdwScrollBar = style & mask; - } + struct host *host = impl_from_ITextHost( iface ); + + *scrollbars = host->scrollbars; return S_OK; } -DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetPasswordChar(ITextHost *iface, WCHAR *pch) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetPasswordChar,8) +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetPasswordChar( ITextHost2 *iface, WCHAR *c ) { - *pch = '*'; - return S_OK; + struct host *host = impl_from_ITextHost( iface ); + + *c = host->password_char; + return *c ? S_OK : S_FALSE; } -DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetAcceleratorPos(ITextHost *iface, LONG *pch) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetAcceleratorPos,8) +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetAcceleratorPos( ITextHost2 *iface, LONG *pos ) { - *pch = -1; + *pos = -1; return S_OK; } -DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetExtent(ITextHost *iface, LPSIZEL lpExtent) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetExtent,8) +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetExtent( ITextHost2 *iface, SIZEL *extent ) { return E_NOTIMPL; } -DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_OnTxCharFormatChange(ITextHost *iface, const CHARFORMATW *pcf) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_OnTxCharFormatChange,8) +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_OnTxCharFormatChange( ITextHost2 *iface, const CHARFORMATW *pcf ) { return S_OK; } -DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_OnTxParaFormatChange(ITextHost *iface, const PARAFORMAT *ppf) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_OnTxParaFormatChange,8) +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_OnTxParaFormatChange( ITextHost2 *iface, const PARAFORMAT *ppf ) { return S_OK; } -DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetPropertyBits(ITextHost *iface, DWORD dwMask, DWORD *pdwBits) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetPropertyBits,12) +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetPropertyBits( ITextHost2 *iface, DWORD mask, DWORD *bits ) { - ITextHostImpl *This = impl_from_ITextHost(iface); - ME_TextEditor *editor = (ME_TextEditor *)GetWindowLongPtrW(This->hWnd, 0); - DWORD style; - DWORD dwBits = 0; - - if (editor) - { - style = editor->styleFlags; - if (editor->mode & TM_RICHTEXT) - dwBits |= TXTBIT_RICHTEXT; - if (editor->bWordWrap) - dwBits |= TXTBIT_WORDWRAP; - if (style & ECO_AUTOWORDSELECTION) - dwBits |= TXTBIT_AUTOWORDSEL; - } else { - DWORD dwScrollBar; - - style = GetWindowLongW(This->hWnd, GWL_STYLE); - ITextHostImpl_TxGetScrollBars(iface, &dwScrollBar); - - dwBits |= TXTBIT_RICHTEXT|TXTBIT_AUTOWORDSEL; - if (!(dwScrollBar & ES_AUTOHSCROLL)) - dwBits |= TXTBIT_WORDWRAP; - } - - /* Bits that correspond to window styles. */ - if (style & ES_MULTILINE) - dwBits |= TXTBIT_MULTILINE; - if (style & ES_READONLY) - dwBits |= TXTBIT_READONLY; - if (style & ES_PASSWORD) - dwBits |= TXTBIT_USEPASSWORD; - if (!(style & ES_NOHIDESEL)) - dwBits |= TXTBIT_HIDESELECTION; - if (style & ES_SAVESEL) - dwBits |= TXTBIT_SAVESELECTION; - if (style & ES_VERTICAL) - dwBits |= TXTBIT_VERTICAL; - if (style & ES_NOOLEDRAGDROP) - dwBits |= TXTBIT_DISABLEDRAG; - - dwBits |= TXTBIT_ALLOWBEEP; - - /* The following bits are always FALSE because they are probably only - * needed for ITextServices_OnTxPropertyBitsChange: - * TXTBIT_VIEWINSETCHANGE - * TXTBIT_BACKSTYLECHANGE - * TXTBIT_MAXLENGTHCHANGE - * TXTBIT_CHARFORMATCHANGE - * TXTBIT_PARAFORMATCHANGE - * TXTBIT_SHOWACCELERATOR - * TXTBIT_EXTENTCHANGE - * TXTBIT_SELBARCHANGE - * TXTBIT_SCROLLBARCHANGE - * TXTBIT_CLIENTRECTCHANGE - * - * Documented by MSDN as not supported: - * TXTBIT_USECURRENTBKG - */ - - *pdwBits = dwBits & dwMask; + struct host *host = impl_from_ITextHost( iface ); + + *bits = host->props & mask; return S_OK; } -DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxNotify(ITextHost *iface, DWORD iNotify, void *pv) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxNotify,12) +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxNotify( ITextHost2 *iface, DWORD iNotify, void *pv ) { - ITextHostImpl *This = impl_from_ITextHost(iface); - ME_TextEditor *editor = (ME_TextEditor*)GetWindowLongPtrW(This->hWnd, 0); - HWND hwnd = This->hWnd; + struct host *host = impl_from_ITextHost( iface ); UINT id; - if (!editor || !editor->hwndParent) return S_OK; + if (!host->parent) return S_OK; - id = GetWindowLongW(hwnd, GWLP_ID); + id = GetWindowLongW( host->window, GWLP_ID ); switch (iNotify) { @@ -428,16 +493,16 @@ DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxNotify(ITextHost *iface, DWOR if (!info) return E_FAIL; - info->hwndFrom = hwnd; + info->hwndFrom = host->window; info->idFrom = id; info->code = iNotify; - SendMessageW(editor->hwndParent, WM_NOTIFY, id, (LPARAM)info); + SendMessageW( host->parent, WM_NOTIFY, id, (LPARAM)info ); break; } case EN_UPDATE: /* Only sent when the window is visible. */ - if (!IsWindowVisible(hwnd)) + if (!IsWindowVisible( host->window )) break; /* Fall through */ case EN_CHANGE: @@ -447,7 +512,7 @@ DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxNotify(ITextHost *iface, DWOR case EN_MAXTEXT: case EN_SETFOCUS: case EN_VSCROLL: - SendMessageW(editor->hwndParent, WM_COMMAND, MAKEWPARAM(id, iNotify), (LPARAM)hwnd); + SendMessageW( host->parent, WM_COMMAND, MAKEWPARAM( id, iNotify ), (LPARAM)host->window ); break; case EN_MSGFILTER: @@ -459,69 +524,105 @@ DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxNotify(ITextHost *iface, DWOR return S_OK; } -DECLSPEC_HIDDEN HIMC __thiscall ITextHostImpl_TxImmGetContext(ITextHost *iface) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxImmGetContext,4) +DECLSPEC_HIDDEN HIMC __thiscall ITextHostImpl_TxImmGetContext( ITextHost2 *iface ) { - ITextHostImpl *This = impl_from_ITextHost(iface); - return ImmGetContext(This->hWnd); + struct host *host = impl_from_ITextHost( iface ); + return ImmGetContext( host->window ); } -DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxImmReleaseContext(ITextHost *iface, HIMC himc) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxImmReleaseContext,8) +DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxImmReleaseContext( ITextHost2 *iface, HIMC context ) { - ITextHostImpl *This = impl_from_ITextHost(iface); - ImmReleaseContext(This->hWnd, himc); + struct host *host = impl_from_ITextHost( iface ); + ImmReleaseContext( host->window, context ); } -DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetSelectionBarWidth(ITextHost *iface, LONG *lSelBarWidth) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetSelectionBarWidth,8) +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetSelectionBarWidth( ITextHost2 *iface, LONG *width ) { - ITextHostImpl *This = impl_from_ITextHost(iface); - ME_TextEditor *editor = (ME_TextEditor *)GetWindowLongPtrW(This->hWnd, 0); + struct host *host = impl_from_ITextHost( iface ); - DWORD style = editor ? editor->styleFlags - : GetWindowLongW(This->hWnd, GWL_STYLE); - *lSelBarWidth = (style & ES_SELECTIONBAR) ? 225 : 0; /* in HIMETRIC */ + *width = host->sel_bar ? 225 : 0; /* in HIMETRIC */ return S_OK; } -DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetDC,4) -DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxReleaseDC,8) -DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxShowScrollBar,12) -DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxEnableScrollBar,12) -DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetScrollRange,20) -DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetScrollPos,16) -DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxInvalidateRect,12) -DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxViewChange,8) -DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxCreateCaret,16) -DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxShowCaret,8) -DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetCaretPos,12) -DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetTimer,12) -DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxKillTimer,8) -DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxScrollWindowEx,32) -DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetCapture,8) -DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetFocus,4) -DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetCursor,12) -DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxScreenToClient,8) -DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxClientToScreen,8) -DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxActivate,8) -DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxDeactivate,8) -DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetClientRect,8) -DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetViewInset,8) -DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetCharFormat,8) -DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetParaFormat,8) -DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetSysColor,8) -DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetBackStyle,8) -DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetMaxLength,8) -DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetScrollBars,8) -DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetPasswordChar,8) -DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetAcceleratorPos,8) -DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetExtent,8) -DEFINE_THISCALL_WRAPPER(ITextHostImpl_OnTxCharFormatChange,8) -DEFINE_THISCALL_WRAPPER(ITextHostImpl_OnTxParaFormatChange,8) -DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetPropertyBits,12) -DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxNotify,12) -DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxImmGetContext,4) -DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxImmReleaseContext,8) -DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetSelectionBarWidth,8) -#if defined(__i386__) && !defined(__MINGW32__) /* thiscall functions are i386-specific */ +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxIsDoubleClickPending,4) +DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxIsDoubleClickPending( ITextHost2 *iface ) +{ + return FALSE; +} + +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetWindow,8) +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetWindow( ITextHost2 *iface, HWND *hwnd ) +{ + struct host *host = impl_from_ITextHost( iface ); + *hwnd = host->window; + return S_OK; +} + +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetForegroundWindow,4) +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxSetForegroundWindow( ITextHost2 *iface ) +{ + return E_NOTIMPL; +} + +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetPalette,4) +DECLSPEC_HIDDEN HPALETTE __thiscall ITextHostImpl_TxGetPalette( ITextHost2 *iface ) +{ + return NULL; +} + +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetEastAsianFlags,8) +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetEastAsianFlags( ITextHost2 *iface, LONG *flags ) +{ + return E_NOTIMPL; +} + +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetCursor2,12) +DECLSPEC_HIDDEN HCURSOR __thiscall ITextHostImpl_TxSetCursor2( ITextHost2 *iface, HCURSOR cursor, BOOL text ) +{ + return NULL; +} + +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxFreeTextServicesNotification,4) +DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxFreeTextServicesNotification( ITextHost2 *iface ) +{ + return; +} + +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetEditStyle,12) +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetEditStyle( ITextHost2 *iface, DWORD item, DWORD *data ) +{ + return E_NOTIMPL; +} + +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetWindowStyles,12) +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetWindowStyles( ITextHost2 *iface, DWORD *style, DWORD *ex_style ) +{ + return E_NOTIMPL; +} + +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxShowDropCaret,16) +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxShowDropCaret( ITextHost2 *iface, BOOL show, HDC hdc, const RECT *rect ) +{ + return E_NOTIMPL; +} + +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxDestroyCaret,4) +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxDestroyCaret( ITextHost2 *iface ) +{ + return E_NOTIMPL; +} + +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetHorzExtent,8) +DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetHorzExtent( ITextHost2 *iface, LONG *horz_extent ) +{ + return E_NOTIMPL; +} + + +#ifdef __ASM_USE_THISCALL_WRAPPER #define STDCALL(func) (void *) __stdcall_ ## func #ifdef _MSC_VER @@ -584,8 +685,22 @@ DEFINE_STDCALL_WRAPPER(38,ITextHostImpl_TxNotify,12) DEFINE_STDCALL_WRAPPER(39,ITextHostImpl_TxImmGetContext,4) DEFINE_STDCALL_WRAPPER(40,ITextHostImpl_TxImmReleaseContext,8) DEFINE_STDCALL_WRAPPER(41,ITextHostImpl_TxGetSelectionBarWidth,8) - -const ITextHostVtbl itextHostStdcallVtbl = { +/* ITextHost2 */ +DEFINE_STDCALL_WRAPPER(42,ITextHostImpl_TxIsDoubleClickPending,4) +DEFINE_STDCALL_WRAPPER(43,ITextHostImpl_TxGetWindow,8) +DEFINE_STDCALL_WRAPPER(44,ITextHostImpl_TxSetForegroundWindow,4) +DEFINE_STDCALL_WRAPPER(45,ITextHostImpl_TxGetPalette,4) +DEFINE_STDCALL_WRAPPER(46,ITextHostImpl_TxGetEastAsianFlags,8) +DEFINE_STDCALL_WRAPPER(47,ITextHostImpl_TxSetCursor2,12) +DEFINE_STDCALL_WRAPPER(48,ITextHostImpl_TxFreeTextServicesNotification,4) +DEFINE_STDCALL_WRAPPER(49,ITextHostImpl_TxGetEditStyle,12) +DEFINE_STDCALL_WRAPPER(50,ITextHostImpl_TxGetWindowStyles,12) +DEFINE_STDCALL_WRAPPER(51,ITextHostImpl_TxShowDropCaret,16) +DEFINE_STDCALL_WRAPPER(52,ITextHostImpl_TxDestroyCaret,4) +DEFINE_STDCALL_WRAPPER(53,ITextHostImpl_TxGetHorzExtent,8) + +const ITextHost2Vtbl text_host2_stdcall_vtbl = +{ NULL, NULL, NULL, @@ -628,11 +743,25 @@ const ITextHostVtbl itextHostStdcallVtbl = { STDCALL(ITextHostImpl_TxImmGetContext), STDCALL(ITextHostImpl_TxImmReleaseContext), STDCALL(ITextHostImpl_TxGetSelectionBarWidth), +/* ITextHost2 */ + STDCALL(ITextHostImpl_TxIsDoubleClickPending), + STDCALL(ITextHostImpl_TxGetWindow), + STDCALL(ITextHostImpl_TxSetForegroundWindow), + STDCALL(ITextHostImpl_TxGetPalette), + STDCALL(ITextHostImpl_TxGetEastAsianFlags), + STDCALL(ITextHostImpl_TxSetCursor2), + STDCALL(ITextHostImpl_TxFreeTextServicesNotification), + STDCALL(ITextHostImpl_TxGetEditStyle), + STDCALL(ITextHostImpl_TxGetWindowStyles), + STDCALL(ITextHostImpl_TxShowDropCaret), + STDCALL(ITextHostImpl_TxDestroyCaret), + STDCALL(ITextHostImpl_TxGetHorzExtent) }; -#endif /* __i386__ */ +#endif /* __ASM_USE_THISCALL_WRAPPER */ -static const ITextHostVtbl textHostVtbl = { +static const ITextHost2Vtbl textHostVtbl = +{ ITextHostImpl_QueryInterface, ITextHostImpl_AddRef, ITextHostImpl_Release, @@ -675,4 +804,877 @@ static const ITextHostVtbl textHostVtbl = { THISCALL(ITextHostImpl_TxImmGetContext), THISCALL(ITextHostImpl_TxImmReleaseContext), THISCALL(ITextHostImpl_TxGetSelectionBarWidth), +/* ITextHost2 */ + THISCALL(ITextHostImpl_TxIsDoubleClickPending), + THISCALL(ITextHostImpl_TxGetWindow), + THISCALL(ITextHostImpl_TxSetForegroundWindow), + THISCALL(ITextHostImpl_TxGetPalette), + THISCALL(ITextHostImpl_TxGetEastAsianFlags), + THISCALL(ITextHostImpl_TxSetCursor2), + THISCALL(ITextHostImpl_TxFreeTextServicesNotification), + THISCALL(ITextHostImpl_TxGetEditStyle), + THISCALL(ITextHostImpl_TxGetWindowStyles), + THISCALL(ITextHostImpl_TxShowDropCaret), + THISCALL(ITextHostImpl_TxDestroyCaret), + THISCALL(ITextHostImpl_TxGetHorzExtent) }; + +static const char * const edit_messages[] = +{ + "EM_GETSEL", "EM_SETSEL", "EM_GETRECT", "EM_SETRECT", + "EM_SETRECTNP", "EM_SCROLL", "EM_LINESCROLL", "EM_SCROLLCARET", + "EM_GETMODIFY", "EM_SETMODIFY", "EM_GETLINECOUNT", "EM_LINEINDEX", + "EM_SETHANDLE", "EM_GETHANDLE", "EM_GETTHUMB", "EM_UNKNOWN_BF", + "EM_UNKNOWN_C0", "EM_LINELENGTH", "EM_REPLACESEL", "EM_UNKNOWN_C3", + "EM_GETLINE", "EM_LIMITTEXT", "EM_CANUNDO", "EM_UNDO", + "EM_FMTLINES", "EM_LINEFROMCHAR", "EM_UNKNOWN_CA", "EM_SETTABSTOPS", + "EM_SETPASSWORDCHAR", "EM_EMPTYUNDOBUFFER", "EM_GETFIRSTVISIBLELINE", "EM_SETREADONLY", + "EM_SETWORDBREAKPROC", "EM_GETWORDBREAKPROC", "EM_GETPASSWORDCHAR", "EM_SETMARGINS", + "EM_GETMARGINS", "EM_GETLIMITTEXT", "EM_POSFROMCHAR", "EM_CHARFROMPOS", + "EM_SETIMESTATUS", "EM_GETIMESTATUS" +}; + +static const char * const richedit_messages[] = +{ + "EM_CANPASTE", "EM_DISPLAYBAND", "EM_EXGETSEL", "EM_EXLIMITTEXT", + "EM_EXLINEFROMCHAR", "EM_EXSETSEL", "EM_FINDTEXT", "EM_FORMATRANGE", + "EM_GETCHARFORMAT", "EM_GETEVENTMASK", "EM_GETOLEINTERFACE", "EM_GETPARAFORMAT", + "EM_GETSELTEXT", "EM_HIDESELECTION", "EM_PASTESPECIAL", "EM_REQUESTRESIZE", + "EM_SELECTIONTYPE", "EM_SETBKGNDCOLOR", "EM_SETCHARFORMAT", "EM_SETEVENTMASK", + "EM_SETOLECALLBACK", "EM_SETPARAFORMAT", "EM_SETTARGETDEVICE", "EM_STREAMIN", + "EM_STREAMOUT", "EM_GETTEXTRANGE", "EM_FINDWORDBREAK", "EM_SETOPTIONS", + "EM_GETOPTIONS", "EM_FINDTEXTEX", "EM_GETWORDBREAKPROCEX", "EM_SETWORDBREAKPROCEX", + "EM_SETUNDOLIMIT", "EM_UNKNOWN_USER_83", "EM_REDO", "EM_CANREDO", + "EM_GETUNDONAME", "EM_GETREDONAME", "EM_STOPGROUPTYPING", "EM_SETTEXTMODE", + "EM_GETTEXTMODE", "EM_AUTOURLDETECT", "EM_GETAUTOURLDETECT", "EM_SETPALETTE", + "EM_GETTEXTEX", "EM_GETTEXTLENGTHEX", "EM_SHOWSCROLLBAR", "EM_SETTEXTEX", + "EM_UNKNOWN_USER_98", "EM_UNKNOWN_USER_99", "EM_SETPUNCTUATION", "EM_GETPUNCTUATION", + "EM_SETWORDWRAPMODE", "EM_GETWORDWRAPMODE", "EM_SETIMECOLOR", "EM_GETIMECOLOR", + "EM_SETIMEOPTIONS", "EM_GETIMEOPTIONS", "EM_CONVPOSITION", "EM_UNKNOWN_USER_109", + "EM_UNKNOWN_USER_110", "EM_UNKNOWN_USER_111", "EM_UNKNOWN_USER_112", "EM_UNKNOWN_USER_113", + "EM_UNKNOWN_USER_114", "EM_UNKNOWN_USER_115", "EM_UNKNOWN_USER_116", "EM_UNKNOWN_USER_117", + "EM_UNKNOWN_USER_118", "EM_UNKNOWN_USER_119", "EM_SETLANGOPTIONS", "EM_GETLANGOPTIONS", + "EM_GETIMECOMPMODE", "EM_FINDTEXTW", "EM_FINDTEXTEXW", "EM_RECONVERSION", + "EM_SETIMEMODEBIAS", "EM_GETIMEMODEBIAS" +}; + +static const char *get_msg_name( UINT msg ) +{ + if (msg >= EM_GETSEL && msg <= EM_CHARFROMPOS) + return edit_messages[msg - EM_GETSEL]; + if (msg >= EM_CANPASTE && msg <= EM_GETIMEMODEBIAS) + return richedit_messages[msg - EM_CANPASTE]; + return ""; +} + +static BOOL create_windowed_editor( HWND hwnd, CREATESTRUCTW *create, BOOL emulate_10 ) +{ + struct host *host = host_create( hwnd, create, emulate_10 ); + IUnknown *unk; + HRESULT hr; + + if (!host) return FALSE; + + hr = create_text_services( NULL, (ITextHost *)&host->ITextHost_iface, &unk, emulate_10 ); + if (FAILED( hr )) + { + ITextHost2_Release( &host->ITextHost_iface ); + return FALSE; + } + IUnknown_QueryInterface( unk, &IID_ITextServices, (void **)&host->text_srv ); + IUnknown_Release( unk ); + + SetWindowLongPtrW( hwnd, 0, (LONG_PTR)host ); + + return TRUE; +} + +static HRESULT get_lineA( ITextServices *text_srv, WPARAM wparam, LPARAM lparam, LRESULT *res ) +{ + LRESULT len = USHRT_MAX; + WORD sizeA; + HRESULT hr; + WCHAR *buf; + + *res = 0; + sizeA = *(WORD *)lparam; + *(WORD *)lparam = 0; + if (!sizeA) return S_OK; + buf = heap_alloc( len * sizeof(WCHAR) ); + if (!buf) return E_OUTOFMEMORY; + *(WORD *)buf = len; + hr = ITextServices_TxSendMessage( text_srv, EM_GETLINE, wparam, (LPARAM)buf, &len ); + if (hr == S_OK && len) + { + len = WideCharToMultiByte( CP_ACP, 0, buf, len, (char *)lparam, sizeA, NULL, NULL ); + if (!len && GetLastError() == ERROR_INSUFFICIENT_BUFFER) len = sizeA; + if (len < sizeA) ((char *)lparam)[len] = '\0'; + *res = len; + } + heap_free( buf ); + return hr; +} + +static HRESULT get_text_rangeA( struct host *host, TEXTRANGEA *rangeA, LRESULT *res ) +{ + TEXTRANGEW range; + HRESULT hr; + unsigned int count; + LRESULT len; + + *res = 0; + if (rangeA->chrg.cpMin < 0) return S_OK; + ITextServices_TxSendMessage( host->text_srv, WM_GETTEXTLENGTH, 0, 0, &len ); + range.chrg = rangeA->chrg; + if ((range.chrg.cpMin == 0 && range.chrg.cpMax == -1) || range.chrg.cpMax > len) + range.chrg.cpMax = len; + if (range.chrg.cpMin >= range.chrg.cpMax) return S_OK; + count = range.chrg.cpMax - range.chrg.cpMin + 1; + range.lpstrText = heap_alloc( count * sizeof(WCHAR) ); + if (!range.lpstrText) return E_OUTOFMEMORY; + hr = ITextServices_TxSendMessage( host->text_srv, EM_GETTEXTRANGE, 0, (LPARAM)&range, &len ); + if (hr == S_OK && len) + { + if (!host->emulate_10) count = INT_MAX; + len = WideCharToMultiByte( CP_ACP, 0, range.lpstrText, -1, rangeA->lpstrText, count, NULL, NULL ); + if (!host->emulate_10) *res = len - 1; + else + { + *res = count - 1; + rangeA->lpstrText[*res] = '\0'; + } + } + heap_free( range.lpstrText ); + return hr; +} + +static HRESULT set_options( struct host *host, DWORD op, DWORD value, LRESULT *res ) +{ + DWORD style, old_options, new_options, change, props_mask = 0; + DWORD mask = ECO_AUTOWORDSELECTION | ECO_AUTOVSCROLL | ECO_AUTOHSCROLL | ECO_NOHIDESEL | ECO_READONLY | + ECO_WANTRETURN | ECO_SAVESEL | ECO_SELECTIONBAR | ECO_VERTICAL; + + new_options = old_options = SendMessageW( host->window, EM_GETOPTIONS, 0, 0 ); + + switch (op) + { + case ECOOP_SET: + new_options = value; + break; + case ECOOP_OR: + new_options |= value; + break; + case ECOOP_AND: + new_options &= value; + break; + case ECOOP_XOR: + new_options ^= value; + } + new_options &= mask; + + change = (new_options ^ old_options); + + if (change & ECO_AUTOWORDSELECTION) + { + host->props ^= TXTBIT_AUTOWORDSEL; + props_mask |= TXTBIT_AUTOWORDSEL; + } + if (change & ECO_AUTOVSCROLL) + { + host->scrollbars ^= WS_VSCROLL; + props_mask |= TXTBIT_SCROLLBARCHANGE; + } + if (change & ECO_AUTOHSCROLL) + { + host->scrollbars ^= WS_HSCROLL; + props_mask |= TXTBIT_SCROLLBARCHANGE; + } + if (change & ECO_NOHIDESEL) + { + host->props ^= TXTBIT_HIDESELECTION; + props_mask |= TXTBIT_HIDESELECTION; + } + if (change & ECO_READONLY) + { + host->props ^= TXTBIT_READONLY; + props_mask |= TXTBIT_READONLY; + } + if (change & ECO_SAVESEL) + { + host->props ^= TXTBIT_SAVESELECTION; + props_mask |= TXTBIT_SAVESELECTION; + } + if (change & ECO_SELECTIONBAR) + { + host->sel_bar ^= 1; + props_mask |= TXTBIT_SELBARCHANGE; + if (host->use_set_rect) + { + int width = SELECTIONBAR_WIDTH; + host->set_rect.left += host->sel_bar ? width : -width; + props_mask |= TXTBIT_CLIENTRECTCHANGE; + } + } + if (change & ECO_VERTICAL) + { + host->props ^= TXTBIT_VERTICAL; + props_mask |= TXTBIT_VERTICAL; + } + if (change & ECO_WANTRETURN) host->want_return ^= 1; + + if (props_mask) + ITextServices_OnTxPropertyBitsChange( host->text_srv, props_mask, host->props & props_mask ); + + *res = new_options; + + mask &= ~ECO_AUTOWORDSELECTION; /* doesn't correspond to a window style */ + style = GetWindowLongW( host->window, GWL_STYLE ); + style = (style & ~mask) | (*res & mask); + SetWindowLongW( host->window, GWL_STYLE, style ); + return S_OK; +} + +/* handle dialog mode VK_RETURN. Returns TRUE if message has been processed */ +static BOOL handle_dialog_enter( struct host *host ) +{ + BOOL ctrl_is_down = GetKeyState( VK_CONTROL ) & 0x8000; + + if (ctrl_is_down) return TRUE; + + if (host->want_return) return FALSE; + + if (host->parent) + { + DWORD id = SendMessageW( host->parent, DM_GETDEFID, 0, 0 ); + if (HIWORD( id ) == DC_HASDEFID) + { + HWND ctrl = GetDlgItem( host->parent, LOWORD( id )); + if (ctrl) + { + SendMessageW( host->parent, WM_NEXTDLGCTL, (WPARAM)ctrl, TRUE ); + PostMessageW( ctrl, WM_KEYDOWN, VK_RETURN, 0 ); + } + } + } + return TRUE; +} + +static LRESULT send_msg_filter( struct host *host, UINT msg, WPARAM *wparam, LPARAM *lparam ) +{ + MSGFILTER msgf; + LRESULT res; + + if (!host->parent) return 0; + msgf.nmhdr.hwndFrom = host->window; + msgf.nmhdr.idFrom = GetWindowLongW( host->window, GWLP_ID ); + msgf.nmhdr.code = EN_MSGFILTER; + msgf.msg = msg; + msgf.wParam = *wparam; + msgf.lParam = *lparam; + if ((res = SendMessageW( host->parent, WM_NOTIFY, msgf.nmhdr.idFrom, (LPARAM)&msgf ))) + return res; + *wparam = msgf.wParam; + *lparam = msgf.lParam; + + return 0; +} + +static LRESULT RichEditWndProc_common( HWND hwnd, UINT msg, WPARAM wparam, + LPARAM lparam, BOOL unicode ) +{ + struct host *host; + HRESULT hr = S_OK; + LRESULT res = 0; + + TRACE( "enter hwnd %p msg %04x (%s) %lx %lx, unicode %d\n", + hwnd, msg, get_msg_name(msg), wparam, lparam, unicode ); + + host = (struct host *)GetWindowLongPtrW( hwnd, 0 ); + if (!host) + { + if (msg == WM_NCCREATE) + { + CREATESTRUCTW *pcs = (CREATESTRUCTW *)lparam; + + TRACE( "WM_NCCREATE: hwnd %p style 0x%08x\n", hwnd, pcs->style ); + return create_windowed_editor( hwnd, pcs, FALSE ); + } + else return DefWindowProcW( hwnd, msg, wparam, lparam ); + } + + if ((((host->event_mask & ENM_KEYEVENTS) && msg >= WM_KEYFIRST && msg <= WM_KEYLAST) || + ((host->event_mask & ENM_MOUSEEVENTS) && msg >= WM_MOUSEFIRST && msg <= WM_MOUSELAST) || + ((host->event_mask & ENM_SCROLLEVENTS) && msg >= WM_HSCROLL && msg <= WM_VSCROLL))) + { + host->notify_level++; + res = send_msg_filter( host, msg, &wparam, &lparam ); + if (!--host->notify_level && host->defer_release) + { + TRACE( "exit (filtered deferred release) hwnd %p msg %04x (%s) %lx %lx -> 0\n", + hwnd, msg, get_msg_name(msg), wparam, lparam ); + ITextHost2_Release( &host->ITextHost_iface ); + return 0; + } + + if (res) + { + TRACE( "exit (filtered %lu) hwnd %p msg %04x (%s) %lx %lx -> 0\n", + res, hwnd, msg, get_msg_name(msg), wparam, lparam ); + return 0; + } + } + + switch (msg) + { + case WM_CHAR: + { + WCHAR wc = wparam; + + if (!unicode) MultiByteToWideChar( CP_ACP, 0, (char *)&wparam, 1, &wc, 1 ); + if (wparam == '\r' && host->dialog_mode && host->emulate_10 && handle_dialog_enter( host )) break; + hr = ITextServices_TxSendMessage( host->text_srv, msg, wc, lparam, &res ); + break; + } + + case WM_CREATE: + { + CREATESTRUCTW *createW = (CREATESTRUCTW *)lparam; + CREATESTRUCTA *createA = (CREATESTRUCTA *)lparam; + void *text; + WCHAR *textW = NULL; + LONG codepage = unicode ? CP_UNICODE : CP_ACP; + int len; + + ITextServices_OnTxInPlaceActivate( host->text_srv, NULL ); + + if (lparam) + { + text = unicode ? (void *)createW->lpszName : (void *)createA->lpszName; + textW = ME_ToUnicode( codepage, text, &len ); + } + ITextServices_TxSetText( host->text_srv, textW ); + if (lparam) ME_EndToUnicode( codepage, textW ); + break; + } + case WM_DESTROY: + if (!host->notify_level) ITextHost2_Release( &host->ITextHost_iface ); + else host->defer_release = 1; + return 0; + + case WM_ERASEBKGND: + { + HDC hdc = (HDC)wparam; + RECT rc; + HBRUSH brush; + + if (GetUpdateRect( hwnd, &rc, TRUE )) + { + brush = CreateSolidBrush( ITextHost_TxGetSysColor( &host->ITextHost_iface, COLOR_WINDOW ) ); + FillRect( hdc, &rc, brush ); + DeleteObject( brush ); + } + return 1; + } + case EM_FINDTEXT: + { + FINDTEXTW *params = (FINDTEXTW *)lparam; + FINDTEXTW new_params; + int len; + + if (!unicode) + { + new_params.chrg = params->chrg; + new_params.lpstrText = ME_ToUnicode( CP_ACP, (char *)params->lpstrText, &len ); + params = &new_params; + } + hr = ITextServices_TxSendMessage( host->text_srv, EM_FINDTEXTW, wparam, (LPARAM)params, &res ); + if (!unicode) ME_EndToUnicode( CP_ACP, (WCHAR *)new_params.lpstrText ); + break; + } + case EM_FINDTEXTEX: + { + FINDTEXTEXA *paramsA = (FINDTEXTEXA *)lparam; + FINDTEXTEXW *params = (FINDTEXTEXW *)lparam; + FINDTEXTEXW new_params; + int len; + + if (!unicode) + { + new_params.chrg = params->chrg; + new_params.lpstrText = ME_ToUnicode( CP_ACP, (char *)params->lpstrText, &len ); + params = &new_params; + } + hr = ITextServices_TxSendMessage( host->text_srv, EM_FINDTEXTEXW, wparam, (LPARAM)params, &res ); + if (!unicode) + { + ME_EndToUnicode( CP_ACP, (WCHAR *)new_params.lpstrText ); + paramsA->chrgText = params->chrgText; + } + break; + } + case WM_GETDLGCODE: + if (lparam) host->dialog_mode = TRUE; + + res = DLGC_WANTCHARS | DLGC_WANTTAB | DLGC_WANTARROWS; + if (host->props & TXTBIT_MULTILINE) res |= DLGC_WANTMESSAGE; + if (!(host->props & TXTBIT_SAVESELECTION)) res |= DLGC_HASSETSEL; + break; + + case EM_GETLINE: + if (unicode) hr = ITextServices_TxSendMessage( host->text_srv, msg, wparam, lparam, &res ); + else hr = get_lineA( host->text_srv, wparam, lparam, &res ); + break; + + case EM_GETPASSWORDCHAR: + ITextHost_TxGetPasswordChar( &host->ITextHost_iface, (WCHAR *)&res ); + break; + + case EM_GETRECT: + hr = ITextHost_TxGetClientRect( &host->ITextHost_iface, (RECT *)lparam ); + break; + + case EM_GETSELTEXT: + { + TEXTRANGEA range; + + if (unicode) hr = ITextServices_TxSendMessage( host->text_srv, msg, wparam, lparam, &res ); + else + { + ITextServices_TxSendMessage( host->text_srv, EM_EXGETSEL, 0, (LPARAM)&range.chrg, &res ); + range.lpstrText = (char *)lparam; + range.lpstrText[0] = '\0'; + hr = get_text_rangeA( host, &range, &res ); + } + break; + } + case EM_GETOPTIONS: + if (host->props & TXTBIT_READONLY) res |= ECO_READONLY; + if (!(host->props & TXTBIT_HIDESELECTION)) res |= ECO_NOHIDESEL; + if (host->props & TXTBIT_SAVESELECTION) res |= ECO_SAVESEL; + if (host->props & TXTBIT_AUTOWORDSEL) res |= ECO_AUTOWORDSELECTION; + if (host->props & TXTBIT_VERTICAL) res |= ECO_VERTICAL; + if (host->scrollbars & ES_AUTOHSCROLL) res |= ECO_AUTOHSCROLL; + if (host->scrollbars & ES_AUTOVSCROLL) res |= ECO_AUTOVSCROLL; + if (host->want_return) res |= ECO_WANTRETURN; + if (host->sel_bar) res |= ECO_SELECTIONBAR; + break; + + case WM_GETTEXT: + { + GETTEXTEX params; + + params.cb = wparam * (unicode ? sizeof(WCHAR) : sizeof(CHAR)); + params.flags = GT_USECRLF; + params.codepage = unicode ? CP_UNICODE : CP_ACP; + params.lpDefaultChar = NULL; + params.lpUsedDefChar = NULL; + hr = ITextServices_TxSendMessage( host->text_srv, EM_GETTEXTEX, (WPARAM)¶ms, lparam, &res ); + break; + } + case WM_GETTEXTLENGTH: + { + GETTEXTLENGTHEX params; + + params.flags = GTL_CLOSE | (host->emulate_10 ? 0 : GTL_USECRLF) | GTL_NUMCHARS; + params.codepage = unicode ? CP_UNICODE : CP_ACP; + hr = ITextServices_TxSendMessage( host->text_srv, EM_GETTEXTLENGTHEX, (WPARAM)¶ms, 0, &res ); + break; + } + case EM_GETTEXTRANGE: + if (unicode) hr = ITextServices_TxSendMessage( host->text_srv, msg, wparam, lparam, &res ); + else hr = get_text_rangeA( host, (TEXTRANGEA *)lparam, &res ); + break; + + case WM_KEYDOWN: + switch (LOWORD( wparam )) + { + case VK_ESCAPE: + if (host->dialog_mode && host->parent) + PostMessageW( host->parent, WM_CLOSE, 0, 0 ); + break; + case VK_TAB: + if (host->dialog_mode && host->parent) + SendMessageW( host->parent, WM_NEXTDLGCTL, GetKeyState( VK_SHIFT ) & 0x8000, 0 ); + break; + case VK_RETURN: + if (host->dialog_mode && !host->emulate_10 && handle_dialog_enter( host )) break; + /* fall through */ + default: + hr = ITextServices_TxSendMessage( host->text_srv, msg, wparam, lparam, &res ); + } + break; + + case WM_PAINT: + case WM_PRINTCLIENT: + { + HDC hdc; + RECT rc, client, update; + PAINTSTRUCT ps; + HBRUSH brush = CreateSolidBrush( ITextHost_TxGetSysColor( &host->ITextHost_iface, COLOR_WINDOW ) ); + + ITextHost_TxGetClientRect( &host->ITextHost_iface, &client ); + + if (msg == WM_PAINT) + { + hdc = BeginPaint( hwnd, &ps ); + update = ps.rcPaint; + } + else + { + hdc = (HDC)wparam; + update = client; + } + + brush = SelectObject( hdc, brush ); + + /* Erase area outside of the formatting rectangle */ + if (update.top < client.top) + { + rc = update; + rc.bottom = client.top; + PatBlt( hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY ); + update.top = client.top; + } + if (update.bottom > client.bottom) + { + rc = update; + rc.top = client.bottom; + PatBlt( hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY ); + update.bottom = client.bottom; + } + if (update.left < client.left) + { + rc = update; + rc.right = client.left; + PatBlt( hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY ); + update.left = client.left; + } + if (update.right > client.right) + { + rc = update; + rc.left = client.right; + PatBlt( hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY ); + update.right = client.right; + } + + ITextServices_TxDraw( host->text_srv, DVASPECT_CONTENT, 0, NULL, NULL, hdc, NULL, NULL, NULL, + &update, NULL, 0, TXTVIEW_ACTIVE ); + DeleteObject( SelectObject( hdc, brush ) ); + if (msg == WM_PAINT) EndPaint( hwnd, &ps ); + return 0; + } + case EM_REPLACESEL: + { + int len; + LONG codepage = unicode ? CP_UNICODE : CP_ACP; + WCHAR *text = ME_ToUnicode( codepage, (void *)lparam, &len ); + + hr = ITextServices_TxSendMessage( host->text_srv, msg, wparam, (LPARAM)text, &res ); + ME_EndToUnicode( codepage, text ); + res = len; + break; + } + case EM_SETBKGNDCOLOR: + res = ITextHost_TxGetSysColor( &host->ITextHost_iface, COLOR_WINDOW ); + host->use_back_colour = !wparam; + if (host->use_back_colour) host->back_colour = lparam; + InvalidateRect( hwnd, NULL, TRUE ); + break; + + case WM_SETCURSOR: + { + POINT pos; + RECT rect; + + if (hwnd != (HWND)wparam) break; + GetCursorPos( &pos ); + ScreenToClient( hwnd, &pos ); + ITextHost_TxGetClientRect( &host->ITextHost_iface, &rect ); + if (PtInRect( &rect, pos )) + ITextServices_OnTxSetCursor( host->text_srv, DVASPECT_CONTENT, 0, NULL, NULL, NULL, NULL, NULL, pos.x, pos.y ); + else ITextHost_TxSetCursor( &host->ITextHost_iface, LoadCursorW( NULL, MAKEINTRESOURCEW( IDC_ARROW ) ), FALSE ); + break; + } + case EM_SETEVENTMASK: + host->event_mask = lparam; + hr = ITextServices_TxSendMessage( host->text_srv, msg, wparam, lparam, &res ); + break; + + case EM_SETOPTIONS: + hr = set_options( host, wparam, lparam, &res ); + break; + + case EM_SETPASSWORDCHAR: + if (wparam == host->password_char) break; + host->password_char = wparam; + if (wparam) host->props |= TXTBIT_USEPASSWORD; + else host->props &= ~TXTBIT_USEPASSWORD; + ITextServices_OnTxPropertyBitsChange( host->text_srv, TXTBIT_USEPASSWORD, host->props & TXTBIT_USEPASSWORD ); + break; + + case EM_SETREADONLY: + { + DWORD op = wparam ? ECOOP_OR : ECOOP_AND; + DWORD mask = wparam ? ECO_READONLY : ~ECO_READONLY; + + SendMessageW( hwnd, EM_SETOPTIONS, op, mask ); + return 1; + } + case EM_SETRECT: + case EM_SETRECTNP: + { + RECT *rc = (RECT *)lparam; + + if (!rc) host->use_set_rect = 0; + else + { + if (wparam >= 2) break; + host->set_rect = *rc; + if (host->client_edge) + { + InflateRect( &host->set_rect, 1, 0 ); + host->set_rect.top -= 1; + } + if (!wparam) IntersectRect( &host->set_rect, &host->set_rect, &host->client_rect ); + host->use_set_rect = 1; + } + ITextServices_OnTxPropertyBitsChange( host->text_srv, TXTBIT_CLIENTRECTCHANGE, 0 ); + break; + } + case WM_SETTEXT: + { + char *textA = (char *)lparam; + WCHAR *text = (WCHAR *)lparam; + int len; + + if (!unicode && textA && strncmp( textA, "{\\rtf", 5 ) && strncmp( textA, "{\\urtf", 6 )) + text = ME_ToUnicode( CP_ACP, textA, &len ); + hr = ITextServices_TxSendMessage( host->text_srv, msg, wparam, (LPARAM)text, &res ); + if (text != (WCHAR *)lparam) ME_EndToUnicode( CP_ACP, text ); + break; + } + case EM_SHOWSCROLLBAR: + { + DWORD mask = 0, new; + + if (wparam == SB_HORZ) mask = WS_HSCROLL; + else if (wparam == SB_VERT) mask = WS_VSCROLL; + else if (wparam == SB_BOTH) mask = WS_HSCROLL | WS_VSCROLL; + + if (mask) + { + new = lparam ? mask : 0; + if ((host->scrollbars & mask) != new) + { + host->scrollbars &= ~mask; + host->scrollbars |= new; + ITextServices_OnTxPropertyBitsChange( host->text_srv, TXTBIT_SCROLLBARCHANGE, 0 ); + } + } + + res = 0; + break; + } + case WM_WINDOWPOSCHANGED: + { + RECT client; + WINDOWPOS *winpos = (WINDOWPOS *)lparam; + + hr = S_FALSE; /* call defwndproc */ + if (winpos->flags & SWP_NOCLIENTSIZE) break; + GetClientRect( hwnd, &client ); + if (host->use_set_rect) + { + host->set_rect.right += client.right - host->client_rect.right; + host->set_rect.bottom += client.bottom - host->client_rect.bottom; + } + host->client_rect = client; + ITextServices_OnTxPropertyBitsChange( host->text_srv, TXTBIT_CLIENTRECTCHANGE, 0 ); + break; + } + default: + hr = ITextServices_TxSendMessage( host->text_srv, msg, wparam, lparam, &res ); + } + + if (hr == S_FALSE) + res = DefWindowProcW( hwnd, msg, wparam, lparam ); + + TRACE( "exit hwnd %p msg %04x (%s) %lx %lx, unicode %d -> %lu\n", + hwnd, msg, get_msg_name(msg), wparam, lparam, unicode, res ); + + return res; +} + +static LRESULT WINAPI RichEditWndProcW( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) +{ + BOOL unicode = TRUE; + + /* Under Win9x RichEdit20W returns ANSI strings, see the tests. */ + if (msg == WM_GETTEXT && (GetVersion() & 0x80000000)) + unicode = FALSE; + + return RichEditWndProc_common( hwnd, msg, wparam, lparam, unicode ); +} + +static LRESULT WINAPI RichEditWndProcA( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) +{ + return RichEditWndProc_common( hwnd, msg, wparam, lparam, FALSE ); +} + +/****************************************************************** + * RichEditANSIWndProc (RICHED20.10) + */ +LRESULT WINAPI RichEditANSIWndProc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) +{ + return RichEditWndProcA( hwnd, msg, wparam, lparam ); +} + +/****************************************************************** + * RichEdit10ANSIWndProc (RICHED20.9) + */ +LRESULT WINAPI RichEdit10ANSIWndProc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) +{ + if (msg == WM_NCCREATE && !GetWindowLongPtrW( hwnd, 0 )) + { + CREATESTRUCTW *pcs = (CREATESTRUCTW *)lparam; + + TRACE( "WM_NCCREATE: hwnd %p style 0x%08x\n", hwnd, pcs->style ); + return create_windowed_editor( hwnd, pcs, TRUE ); + } + return RichEditANSIWndProc( hwnd, msg, wparam, lparam ); +} + +static LRESULT WINAPI REComboWndProc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) +{ + /* FIXME: Not implemented */ + TRACE( "hwnd %p msg %04x (%s) %08lx %08lx\n", + hwnd, msg, get_msg_name( msg ), wparam, lparam ); + return DefWindowProcW( hwnd, msg, wparam, lparam ); +} + +static LRESULT WINAPI REListWndProc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) +{ + /* FIXME: Not implemented */ + TRACE( "hwnd %p msg %04x (%s) %08lx %08lx\n", + hwnd, msg, get_msg_name( msg ), wparam, lparam ); + return DefWindowProcW( hwnd, msg, wparam, lparam ); +} + +/****************************************************************** + * REExtendedRegisterClass (RICHED20.8) + * + * FIXME undocumented + * Need to check for errors and implement controls and callbacks + */ +LRESULT WINAPI REExtendedRegisterClass( void ) +{ + WNDCLASSW wc; + UINT result; + + FIXME( "semi stub\n" ); + wc.cbClsExtra = 0; + wc.cbWndExtra = 4; + wc.hInstance = NULL; + wc.hIcon = NULL; + wc.hCursor = NULL; + wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); + wc.lpszMenuName = NULL; + + if (!listbox_registered) + { + wc.style = CS_PARENTDC | CS_DBLCLKS | CS_GLOBALCLASS; + wc.lpfnWndProc = REListWndProc; + wc.lpszClassName = L"REListBox20W"; + if (RegisterClassW( &wc )) listbox_registered = TRUE; + } + + if (!combobox_registered) + { + wc.style = CS_PARENTDC | CS_DBLCLKS | CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW; + wc.lpfnWndProc = REComboWndProc; + wc.lpszClassName = L"REComboBox20W"; + if (RegisterClassW( &wc )) combobox_registered = TRUE; + } + + result = 0; + if (listbox_registered) result += 1; + if (combobox_registered) result += 2; + + return result; +} + +static BOOL register_classes( HINSTANCE instance ) +{ + WNDCLASSW wcW; + WNDCLASSA wcA; + + wcW.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS; + wcW.lpfnWndProc = RichEditWndProcW; + wcW.cbClsExtra = 0; + wcW.cbWndExtra = sizeof(struct host *); + wcW.hInstance = NULL; /* hInstance would register DLL-local class */ + wcW.hIcon = NULL; + wcW.hCursor = LoadCursorW( NULL, (LPWSTR)IDC_IBEAM ); + wcW.hbrBackground = GetStockObject( NULL_BRUSH ); + wcW.lpszMenuName = NULL; + + if (!(GetVersion() & 0x80000000)) + { + wcW.lpszClassName = RICHEDIT_CLASS20W; + if (!RegisterClassW( &wcW )) return FALSE; + wcW.lpszClassName = MSFTEDIT_CLASS; + if (!RegisterClassW( &wcW )) return FALSE; + } + else + { + /* WNDCLASSA/W have the same layout */ + wcW.lpszClassName = (LPCWSTR)"RichEdit20W"; + if (!RegisterClassA( (WNDCLASSA *)&wcW )) return FALSE; + wcW.lpszClassName = (LPCWSTR)"RichEdit50W"; + if (!RegisterClassA( (WNDCLASSA *)&wcW )) return FALSE; + } + + wcA.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS; + wcA.lpfnWndProc = RichEditWndProcA; + wcA.cbClsExtra = 0; + wcA.cbWndExtra = sizeof(struct host *); + wcA.hInstance = NULL; /* hInstance would register DLL-local class */ + wcA.hIcon = NULL; + wcA.hCursor = LoadCursorW( NULL, (LPWSTR)IDC_IBEAM ); + wcA.hbrBackground = GetStockObject(NULL_BRUSH); + wcA.lpszMenuName = NULL; + wcA.lpszClassName = RICHEDIT_CLASS20A; + if (!RegisterClassA( &wcA )) return FALSE; + wcA.lpszClassName = "RichEdit50A"; + if (!RegisterClassA( &wcA )) return FALSE; + + return TRUE; +} + +BOOL WINAPI DllMain( HINSTANCE instance, DWORD reason, void *reserved ) +{ + switch (reason) + { + case DLL_PROCESS_ATTACH: + dll_instance = instance; + DisableThreadLibraryCalls( instance ); + me_heap = HeapCreate( 0, 0x10000, 0 ); + if (!register_classes( instance )) return FALSE; + LookupInit(); + break; + + case DLL_PROCESS_DETACH: + if (reserved) break; + UnregisterClassW( RICHEDIT_CLASS20W, 0 ); + UnregisterClassW( MSFTEDIT_CLASS, 0 ); + UnregisterClassA( RICHEDIT_CLASS20A, 0 ); + UnregisterClassA( "RichEdit50A", 0 ); + if (listbox_registered) UnregisterClassW( L"REListBox20W", 0 ); + if (combobox_registered) UnregisterClassW( L"REComboBox20W", 0 ); + LookupCleanup(); + HeapDestroy( me_heap ); + release_typelib(); + break; + } + return TRUE; +} diff --git a/dll/win32/riched20/txtsrv.c b/dll/win32/riched20/txtsrv.c index 725dd471da18f..1e119601e9286 100644 --- a/dll/win32/riched20/txtsrv.c +++ b/dll/win32/riched20/txtsrv.c @@ -27,79 +27,64 @@ #include "tom.h" #include "imm.h" #include "textserv.h" -#include "wine/asm.h" #include "wine/debug.h" #include "editstr.h" +#include "riched20.h" WINE_DEFAULT_DEBUG_CHANNEL(richedit); -typedef struct ITextServicesImpl { - IUnknown IUnknown_inner; - ITextServices ITextServices_iface; - IUnknown *outer_unk; - LONG ref; - ITextHost *pMyHost; - CRITICAL_SECTION csTxtSrv; - ME_TextEditor *editor; - char spare[256]; -} ITextServicesImpl; - -static inline ITextServicesImpl *impl_from_IUnknown(IUnknown *iface) +static inline struct text_services *impl_from_IUnknown( IUnknown *iface ) { - return CONTAINING_RECORD(iface, ITextServicesImpl, IUnknown_inner); + return CONTAINING_RECORD( iface, struct text_services, IUnknown_inner ); } -static HRESULT WINAPI ITextServicesImpl_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) -{ - ITextServicesImpl *This = impl_from_IUnknown(iface); - - TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppv); - - if (IsEqualIID(riid, &IID_IUnknown)) - *ppv = &This->IUnknown_inner; - else if (IsEqualIID(riid, &IID_ITextServices)) - *ppv = &This->ITextServices_iface; - else if (IsEqualIID(riid, &IID_IRichEditOle) || IsEqualIID(riid, &IID_ITextDocument) || - IsEqualIID(riid, &IID_ITextDocument2Old)) { - if (!This->editor->reOle) - if (!CreateIRichEditOle(This->outer_unk, This->editor, (void **)(&This->editor->reOle))) - return E_OUTOFMEMORY; - return IUnknown_QueryInterface(This->editor->reOle, riid, ppv); - } else { - *ppv = NULL; - FIXME("Unknown interface: %s\n", debugstr_guid(riid)); - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; +static HRESULT WINAPI ITextServicesImpl_QueryInterface( IUnknown *iface, REFIID iid, void **obj ) +{ + struct text_services *services = impl_from_IUnknown( iface ); + + TRACE( "(%p)->(%s, %p)\n", iface, debugstr_guid( iid ), obj ); + + if (IsEqualIID( iid, &IID_IUnknown )) *obj = &services->IUnknown_inner; + else if (IsEqualIID( iid, &IID_ITextServices )) *obj = &services->ITextServices_iface; + else if (IsEqualIID( iid, &IID_IRichEditOle )) *obj= &services->IRichEditOle_iface; + else if (IsEqualIID( iid, &IID_IDispatch ) || + IsEqualIID( iid, &IID_ITextDocument ) || + IsEqualIID( iid, &IID_ITextDocument2Old )) *obj = &services->ITextDocument2Old_iface; + else + { + *obj = NULL; + FIXME( "Unknown interface: %s\n", debugstr_guid( iid ) ); + return E_NOINTERFACE; + } + + IUnknown_AddRef( (IUnknown *)*obj ); + return S_OK; } static ULONG WINAPI ITextServicesImpl_AddRef(IUnknown *iface) { - ITextServicesImpl *This = impl_from_IUnknown(iface); - LONG ref = InterlockedIncrement(&This->ref); + struct text_services *services = impl_from_IUnknown( iface ); + LONG ref = InterlockedIncrement( &services->ref ); - TRACE("(%p) ref=%d\n", This, ref); + TRACE( "(%p) ref = %d\n", services, ref ); - return ref; + return ref; } static ULONG WINAPI ITextServicesImpl_Release(IUnknown *iface) { - ITextServicesImpl *This = impl_from_IUnknown(iface); - LONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p) ref=%d\n", This, ref); - - if (!ref) - { - ME_DestroyEditor(This->editor); - This->csTxtSrv.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&This->csTxtSrv); - CoTaskMemFree(This); - } - return ref; + struct text_services *services = impl_from_IUnknown( iface ); + LONG ref = InterlockedDecrement( &services->ref ); + + TRACE( "(%p) ref = %d\n", services, ref ); + + if (!ref) + { + richole_release_children( services ); + ME_DestroyEditor( services->editor ); + CoTaskMemFree( services ); + } + return ref; } static const IUnknownVtbl textservices_inner_vtbl = @@ -109,306 +94,518 @@ static const IUnknownVtbl textservices_inner_vtbl = ITextServicesImpl_Release }; -static inline ITextServicesImpl *impl_from_ITextServices(ITextServices *iface) +static inline struct text_services *impl_from_ITextServices( ITextServices *iface ) { - return CONTAINING_RECORD(iface, ITextServicesImpl, ITextServices_iface); + return CONTAINING_RECORD( iface, struct text_services, ITextServices_iface ); } -static HRESULT WINAPI fnTextSrv_QueryInterface(ITextServices *iface, REFIID riid, void **ppv) +static HRESULT WINAPI fnTextSrv_QueryInterface( ITextServices *iface, REFIID iid, void **obj ) { - ITextServicesImpl *This = impl_from_ITextServices(iface); - return IUnknown_QueryInterface(This->outer_unk, riid, ppv); + struct text_services *services = impl_from_ITextServices( iface ); + return IUnknown_QueryInterface( services->outer_unk, iid, obj ); } static ULONG WINAPI fnTextSrv_AddRef(ITextServices *iface) { - ITextServicesImpl *This = impl_from_ITextServices(iface); - return IUnknown_AddRef(This->outer_unk); + struct text_services *services = impl_from_ITextServices( iface ); + return IUnknown_AddRef( services->outer_unk ); } static ULONG WINAPI fnTextSrv_Release(ITextServices *iface) { - ITextServicesImpl *This = impl_from_ITextServices(iface); - return IUnknown_Release(This->outer_unk); + struct text_services *services = impl_from_ITextServices( iface ); + return IUnknown_Release( services->outer_unk ); } -DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxSendMessage(ITextServices *iface, UINT msg, WPARAM wparam, - LPARAM lparam, LRESULT *plresult) +DEFINE_THISCALL_WRAPPER(fnTextSrv_TxSendMessage,20) +DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxSendMessage( ITextServices *iface, UINT msg, WPARAM wparam, + LPARAM lparam, LRESULT *result ) { - ITextServicesImpl *This = impl_from_ITextServices(iface); - HRESULT hresult; - LRESULT lresult; + struct text_services *services = impl_from_ITextServices( iface ); + HRESULT hr; + LRESULT res; - lresult = ME_HandleMessage(This->editor, msg, wparam, lparam, TRUE, &hresult); - if (plresult) *plresult = lresult; - return hresult; + res = editor_handle_message( services->editor, msg, wparam, lparam, &hr ); + if (result) *result = res; + return hr; } -DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxDraw(ITextServices *iface, DWORD dwDrawAspect, LONG lindex, - void *pvAspect, DVTARGETDEVICE *ptd, HDC hdcDraw, HDC hdcTargetDev, - LPCRECTL lprcBounds, LPCRECTL lprcWBounds, LPRECT lprcUpdate, - BOOL (CALLBACK * pfnContinue)(DWORD), DWORD dwContinue, - LONG lViewId) +static HRESULT update_client_rect( struct text_services *services, const RECT *client ) +{ + RECT rect; + HRESULT hr; + + if (!client) + { + if (!services->editor->in_place_active) return E_INVALIDARG; + hr = ITextHost_TxGetClientRect( services->editor->texthost, &rect ); + if (FAILED( hr )) return hr; + } + else rect = *client; + + rect.left += services->editor->selofs; + + if (EqualRect( &rect, &services->editor->rcFormat )) return S_FALSE; + services->editor->rcFormat = rect; + return S_OK; +} + +DEFINE_THISCALL_WRAPPER(fnTextSrv_TxDraw,52) +DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxDraw( ITextServices *iface, DWORD aspect, LONG index, void *aspect_info, + DVTARGETDEVICE *td, HDC draw, HDC target, + const RECTL *bounds, const RECTL *mf_bounds, RECT *update, + BOOL (CALLBACK *continue_fn)(DWORD), DWORD continue_param, + LONG view_id ) { - ITextServicesImpl *This = impl_from_ITextServices(iface); + struct text_services *services = impl_from_ITextServices( iface ); + HRESULT hr; + HDC dc = draw; + BOOL rewrap = FALSE; - FIXME("%p: STUB\n", This); - return E_NOTIMPL; + TRACE( "%p: aspect %d, %d, %p, %p, draw %p, target %p, bounds %s, mf_bounds %s, update %s, %p, %d, view %d\n", + services, aspect, index, aspect_info, td, draw, target, wine_dbgstr_rect( (RECT *)bounds ), + wine_dbgstr_rect( (RECT *)mf_bounds ), wine_dbgstr_rect( update ), continue_fn, continue_param, view_id ); + + if (aspect != DVASPECT_CONTENT || aspect_info || td || target || mf_bounds || continue_fn ) + FIXME( "Many arguments are ignored\n" ); + + hr = update_client_rect( services, (RECT *)bounds ); + if (FAILED( hr )) return hr; + if (hr == S_OK) rewrap = TRUE; + + if (!dc && services->editor->in_place_active) + dc = ITextHost_TxGetDC( services->editor->texthost ); + if (!dc) return E_FAIL; + + if (rewrap) + { + editor_mark_rewrap_all( services->editor ); + wrap_marked_paras_dc( services->editor, dc, FALSE ); + } + + if (!services->editor->bEmulateVersion10 || services->editor->nEventMask & ENM_UPDATE) + ITextHost_TxNotify( services->editor->texthost, EN_UPDATE, NULL ); + + editor_draw( services->editor, dc, update ); + + if (!draw) ITextHost_TxReleaseDC( services->editor->texthost, dc ); + return S_OK; } -DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxGetHScroll(ITextServices *iface, LONG *plMin, LONG *plMax, LONG *plPos, - LONG *plPage, BOOL *pfEnabled) -{ - ITextServicesImpl *This = impl_from_ITextServices(iface); - - if (plMin) - *plMin = This->editor->horz_si.nMin; - if (plMax) - *plMax = This->editor->horz_si.nMax; - if (plPos) - *plPos = This->editor->horz_si.nPos; - if (plPage) - *plPage = This->editor->horz_si.nPage; - if (pfEnabled) - *pfEnabled = (This->editor->styleFlags & WS_HSCROLL) != 0; - return S_OK; +DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetHScroll,24) +DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxGetHScroll( ITextServices *iface, LONG *min_pos, LONG *max_pos, LONG *pos, + LONG *page, BOOL *enabled ) +{ + struct text_services *services = impl_from_ITextServices( iface ); + + if (min_pos) *min_pos = services->editor->horz_si.nMin; + if (max_pos) *max_pos = services->editor->horz_si.nMax; + if (pos) *pos = services->editor->horz_si.nPos; + if (page) *page = services->editor->horz_si.nPage; + if (enabled) *enabled = services->editor->horz_sb_enabled; + return S_OK; } -DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxGetVScroll(ITextServices *iface, LONG *plMin, LONG *plMax, LONG *plPos, - LONG *plPage, BOOL *pfEnabled) -{ - ITextServicesImpl *This = impl_from_ITextServices(iface); - - if (plMin) - *plMin = This->editor->vert_si.nMin; - if (plMax) - *plMax = This->editor->vert_si.nMax; - if (plPos) - *plPos = This->editor->vert_si.nPos; - if (plPage) - *plPage = This->editor->vert_si.nPage; - if (pfEnabled) - *pfEnabled = (This->editor->styleFlags & WS_VSCROLL) != 0; - return S_OK; +DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetVScroll,24) +DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxGetVScroll( ITextServices *iface, LONG *min_pos, LONG *max_pos, LONG *pos, + LONG *page, BOOL *enabled ) +{ + struct text_services *services = impl_from_ITextServices( iface ); + + if (min_pos) *min_pos = services->editor->vert_si.nMin; + if (max_pos) *max_pos = services->editor->vert_si.nMax; + if (pos) *pos = services->editor->vert_si.nPos; + if (page) *page = services->editor->vert_si.nPage; + if (enabled) *enabled = services->editor->vert_sb_enabled; + return S_OK; } -DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_OnTxSetCursor(ITextServices *iface, DWORD dwDrawAspect, LONG lindex, - void *pvAspect, DVTARGETDEVICE *ptd, HDC hdcDraw, - HDC hicTargetDev, LPCRECT lprcClient, INT x, INT y) +DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxSetCursor,40) +DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_OnTxSetCursor( ITextServices *iface, DWORD aspect, LONG index, + void *aspect_info, DVTARGETDEVICE *td, HDC draw, + HDC target, const RECT *client, INT x, INT y ) { - ITextServicesImpl *This = impl_from_ITextServices(iface); + struct text_services *services = impl_from_ITextServices( iface ); + + TRACE( "%p: %d, %d, %p, %p, draw %p target %p client %s pos (%d, %d)\n", services, aspect, index, aspect_info, td, draw, + target, wine_dbgstr_rect( client ), x, y ); + + if (aspect != DVASPECT_CONTENT || index || aspect_info || td || draw || target || client) + FIXME( "Ignoring most params\n" ); - FIXME("%p: STUB\n", This); - return E_NOTIMPL; + link_notify( services->editor, WM_SETCURSOR, 0, MAKELPARAM( x, y ) ); + editor_set_cursor( services->editor, x, y ); + return S_OK; } +DEFINE_THISCALL_WRAPPER(fnTextSrv_TxQueryHitPoint,44) DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxQueryHitPoint(ITextServices *iface, DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd, HDC hdcDraw, HDC hicTargetDev, LPCRECT lprcClient, INT x, INT y, DWORD *pHitResult) { - ITextServicesImpl *This = impl_from_ITextServices(iface); + struct text_services *services = impl_from_ITextServices( iface ); - FIXME("%p: STUB\n", This); - return E_NOTIMPL; + FIXME( "%p: STUB\n", services ); + return E_NOTIMPL; } -DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_OnTxInplaceActivate(ITextServices *iface, LPCRECT prcClient) +DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxInPlaceActivate,8) +DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_OnTxInPlaceActivate( ITextServices *iface, const RECT *client ) { - ITextServicesImpl *This = impl_from_ITextServices(iface); - - FIXME("%p: STUB\n", This); - return E_NOTIMPL; + struct text_services *services = impl_from_ITextServices( iface ); + HRESULT hr; + BOOL old_active = services->editor->in_place_active; + + TRACE( "%p: %s\n", services, wine_dbgstr_rect( client ) ); + + services->editor->in_place_active = TRUE; + hr = update_client_rect( services, client ); + if (FAILED( hr )) + { + services->editor->in_place_active = old_active; + return hr; + } + ME_RewrapRepaint( services->editor ); + return S_OK; } -DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_OnTxInplaceDeactivate(ITextServices *iface) +DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxInPlaceDeactivate,4) +DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_OnTxInPlaceDeactivate(ITextServices *iface) { - ITextServicesImpl *This = impl_from_ITextServices(iface); + struct text_services *services = impl_from_ITextServices( iface ); - FIXME("%p: STUB\n", This); - return E_NOTIMPL; + TRACE( "%p\n", services ); + services->editor->in_place_active = FALSE; + return S_OK; } +DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxUIActivate,4) DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_OnTxUIActivate(ITextServices *iface) { - ITextServicesImpl *This = impl_from_ITextServices(iface); + struct text_services *services = impl_from_ITextServices( iface ); - FIXME("%p: STUB\n", This); - return E_NOTIMPL; + FIXME( "%p: STUB\n", services ); + return E_NOTIMPL; } +DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxUIDeactivate,4) DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_OnTxUIDeactivate(ITextServices *iface) { - ITextServicesImpl *This = impl_from_ITextServices(iface); + struct text_services *services = impl_from_ITextServices( iface ); - FIXME("%p: STUB\n", This); - return E_NOTIMPL; + FIXME( "%p: STUB\n", services ); + return E_NOTIMPL; } -DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxGetText(ITextServices *iface, BSTR *pbstrText) +DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetText,8) +DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxGetText( ITextServices *iface, BSTR *text ) { - ITextServicesImpl *This = impl_from_ITextServices(iface); - int length; - - length = ME_GetTextLength(This->editor); - if (length) - { - ME_Cursor start; - BSTR bstr; - bstr = SysAllocStringByteLen(NULL, length * sizeof(WCHAR)); - if (bstr == NULL) - return E_OUTOFMEMORY; - - ME_CursorFromCharOfs(This->editor, 0, &start); - ME_GetTextW(This->editor, bstr, length, &start, INT_MAX, FALSE, FALSE); - *pbstrText = bstr; - } else { - *pbstrText = NULL; - } - - return S_OK; + struct text_services *services = impl_from_ITextServices( iface ); + int length; + + length = ME_GetTextLength( services->editor ); + if (length) + { + ME_Cursor start; + BSTR bstr; + bstr = SysAllocStringByteLen( NULL, length * sizeof(WCHAR) ); + if (bstr == NULL) return E_OUTOFMEMORY; + + cursor_from_char_ofs( services->editor, 0, &start ); + ME_GetTextW( services->editor, bstr, length, &start, INT_MAX, FALSE, FALSE ); + *text = bstr; + } + else *text = NULL; + + return S_OK; } -DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxSetText(ITextServices *iface, LPCWSTR pszText) +DEFINE_THISCALL_WRAPPER(fnTextSrv_TxSetText,8) +DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxSetText( ITextServices *iface, const WCHAR *text ) { - ITextServicesImpl *This = impl_from_ITextServices(iface); - ME_Cursor cursor; - - ME_SetCursorToStart(This->editor, &cursor); - ME_InternalDeleteText(This->editor, &cursor, ME_GetTextLength(This->editor), FALSE); - if(pszText) - ME_InsertTextFromCursor(This->editor, 0, pszText, -1, This->editor->pBuffer->pDefaultStyle); - set_selection_cursors(This->editor, 0, 0); - This->editor->nModifyStep = 0; - OleFlushClipboard(); - ME_EmptyUndoStack(This->editor); - ME_UpdateRepaint(This->editor, FALSE); - - return S_OK; + struct text_services *services = impl_from_ITextServices( iface ); + ME_Cursor cursor; + + ME_SetCursorToStart( services->editor, &cursor ); + ME_InternalDeleteText( services->editor, &cursor, ME_GetTextLength( services->editor ), FALSE ); + if (text) ME_InsertTextFromCursor( services->editor, 0, text, -1, services->editor->pBuffer->pDefaultStyle ); + set_selection_cursors( services->editor, 0, 0); + services->editor->nModifyStep = 0; + OleFlushClipboard(); + ME_EmptyUndoStack( services->editor ); + ME_UpdateRepaint( services->editor, FALSE ); + + return S_OK; } +DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetCurTargetX,8) DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxGetCurTargetX(ITextServices *iface, LONG *x) { - ITextServicesImpl *This = impl_from_ITextServices(iface); + struct text_services *services = impl_from_ITextServices( iface ); - FIXME("%p: STUB\n", This); - return E_NOTIMPL; + FIXME( "%p: STUB\n", services ); + return E_NOTIMPL; } +DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetBaseLinePos,8) DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxGetBaseLinePos(ITextServices *iface, LONG *x) { - ITextServicesImpl *This = impl_from_ITextServices(iface); + struct text_services *services = impl_from_ITextServices( iface ); - FIXME("%p: STUB\n", This); - return E_NOTIMPL; + FIXME( "%p: STUB\n", services ); + return E_NOTIMPL; } -DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxGetNaturalSize(ITextServices *iface, DWORD dwAspect, HDC hdcDraw, - HDC hicTargetDev, DVTARGETDEVICE *ptd, DWORD dwMode, - const SIZEL *psizelExtent, LONG *pwidth, LONG *pheight) +DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetNaturalSize,36) +DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxGetNaturalSize( ITextServices *iface, DWORD aspect, HDC draw, + HDC target, DVTARGETDEVICE *td, DWORD mode, + const SIZEL *extent, LONG *width, LONG *height ) { - ITextServicesImpl *This = impl_from_ITextServices(iface); + struct text_services *services = impl_from_ITextServices( iface ); + RECT rect; + HDC dc = draw; + BOOL rewrap = FALSE; + HRESULT hr; + + TRACE( "%p: aspect %d, draw %p, target %p, td %p, mode %08x, extent %s, *width %d, *height %d\n", services, + aspect, draw, target, td, mode, wine_dbgstr_point( (POINT *)extent ), *width, *height ); + + if (aspect != DVASPECT_CONTENT || target || td || mode != TXTNS_FITTOCONTENT ) + FIXME( "Many arguments are ignored\n" ); + + SetRect( &rect, 0, 0, *width, *height ); + + hr = update_client_rect( services, &rect ); + if (FAILED( hr )) return hr; + if (hr == S_OK) rewrap = TRUE; - FIXME("%p: STUB\n", This); - return E_NOTIMPL; + if (!dc && services->editor->in_place_active) + dc = ITextHost_TxGetDC( services->editor->texthost ); + if (!dc) return E_FAIL; + + if (rewrap) + { + editor_mark_rewrap_all( services->editor ); + wrap_marked_paras_dc( services->editor, dc, FALSE ); + } + + *width = services->editor->nTotalWidth; + *height = services->editor->nTotalLength; + + if (!draw) ITextHost_TxReleaseDC( services->editor->texthost, dc ); + return S_OK; } +DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetDropTarget,8) DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxGetDropTarget(ITextServices *iface, IDropTarget **ppDropTarget) { - ITextServicesImpl *This = impl_from_ITextServices(iface); + struct text_services *services = impl_from_ITextServices( iface ); - FIXME("%p: STUB\n", This); - return E_NOTIMPL; + FIXME( "%p: STUB\n", services ); + return E_NOTIMPL; } -DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_OnTxPropertyBitsChange(ITextServices *iface, DWORD dwMask, DWORD dwBits) +DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxPropertyBitsChange,12) +DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_OnTxPropertyBitsChange( ITextServices *iface, DWORD mask, DWORD bits ) { - ITextServicesImpl *This = impl_from_ITextServices(iface); - - FIXME("%p: STUB\n", This); - return E_NOTIMPL; + struct text_services *services = impl_from_ITextServices( iface ); + DWORD scrollbars; + HRESULT hr; + BOOL repaint = FALSE; + + TRACE( "%p, mask %08x, bits %08x\n", services, mask, bits ); + + services->editor->props = (services->editor->props & ~mask) | (bits & mask); + if (mask & (TXTBIT_WORDWRAP | TXTBIT_MULTILINE)) + services->editor->bWordWrap = (services->editor->props & TXTBIT_WORDWRAP) && (services->editor->props & TXTBIT_MULTILINE); + + if (mask & TXTBIT_SCROLLBARCHANGE) + { + hr = ITextHost_TxGetScrollBars( services->editor->texthost, &scrollbars ); + if (SUCCEEDED( hr )) + { + if ((services->editor->scrollbars ^ scrollbars) & WS_HSCROLL) + ITextHost_TxShowScrollBar( services->editor->texthost, SB_HORZ, (scrollbars & WS_HSCROLL) && + services->editor->nTotalWidth > services->editor->sizeWindow.cx ); + if ((services->editor->scrollbars ^ scrollbars) & WS_VSCROLL) + ITextHost_TxShowScrollBar( services->editor->texthost, SB_VERT, (scrollbars & WS_VSCROLL) && + services->editor->nTotalLength > services->editor->sizeWindow.cy ); + services->editor->scrollbars = scrollbars; + } + } + + if ((mask & TXTBIT_HIDESELECTION) && !services->editor->bHaveFocus) ME_InvalidateSelection( services->editor ); + + if (mask & TXTBIT_SELBARCHANGE) + { + LONG width; + + hr = ITextHost_TxGetSelectionBarWidth( services->editor->texthost, &width ); + if (hr == S_OK) + { + ITextHost_TxInvalidateRect( services->editor->texthost, &services->editor->rcFormat, TRUE ); + services->editor->rcFormat.left -= services->editor->selofs; + services->editor->selofs = width ? SELECTIONBAR_WIDTH : 0; /* FIXME: convert from HIMETRIC */ + services->editor->rcFormat.left += services->editor->selofs; + repaint = TRUE; + } + } + + if (mask & TXTBIT_CLIENTRECTCHANGE) + { + hr = update_client_rect( services, NULL ); + if (SUCCEEDED( hr )) repaint = TRUE; + } + + if (mask & TXTBIT_USEPASSWORD) + { + if (bits & TXTBIT_USEPASSWORD) ITextHost_TxGetPasswordChar( services->editor->texthost, &services->editor->password_char ); + else services->editor->password_char = 0; + repaint = TRUE; + } + + if (repaint) ME_RewrapRepaint( services->editor ); + + return S_OK; } +DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetCachedSize,12) DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxGetCachedSize(ITextServices *iface, DWORD *pdwWidth, DWORD *pdwHeight) { - ITextServicesImpl *This = impl_from_ITextServices(iface); + struct text_services *services = impl_from_ITextServices( iface ); - FIXME("%p: STUB\n", This); - return E_NOTIMPL; + FIXME( "%p: STUB\n", services ); + return E_NOTIMPL; } -DEFINE_THISCALL_WRAPPER(fnTextSrv_TxSendMessage,20) -DEFINE_THISCALL_WRAPPER(fnTextSrv_TxDraw,52) -DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetHScroll,24) -DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetVScroll,24) -DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxSetCursor,40) -DEFINE_THISCALL_WRAPPER(fnTextSrv_TxQueryHitPoint,44) -DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxInplaceActivate,8) -DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxInplaceDeactivate,4) -DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxUIActivate,4) -DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxUIDeactivate,4) -DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetText,8) -DEFINE_THISCALL_WRAPPER(fnTextSrv_TxSetText,8) -DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetCurTargetX,8) -DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetBaseLinePos,8) -DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetNaturalSize,36) -DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetDropTarget,8) -DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxPropertyBitsChange,12) -DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetCachedSize,12) +#ifdef __ASM_USE_THISCALL_WRAPPER + +#define STDCALL(func) (void *) __stdcall_ ## func +#ifdef _MSC_VER +#define DEFINE_STDCALL_WRAPPER(num,func) \ + __declspec(naked) HRESULT __stdcall_##func(void) \ + { \ + __asm pop eax \ + __asm pop ecx \ + __asm push eax \ + __asm mov eax, [ecx] \ + __asm jmp dword ptr [eax + 4*num] \ + } +#else /* _MSC_VER */ +#define DEFINE_STDCALL_WRAPPER(num,func) \ + extern HRESULT __stdcall_ ## func(void); \ + __ASM_GLOBAL_FUNC(__stdcall_ ## func, \ + "popl %eax\n\t" \ + "popl %ecx\n\t" \ + "pushl %eax\n\t" \ + "movl (%ecx), %eax\n\t" \ + "jmp *(4*(" #num "))(%eax)" ) +#endif /* _MSC_VER */ + +DEFINE_STDCALL_WRAPPER(3, ITextServices_TxSendMessage) +DEFINE_STDCALL_WRAPPER(4, ITextServices_TxDraw) +DEFINE_STDCALL_WRAPPER(5, ITextServices_TxGetHScroll) +DEFINE_STDCALL_WRAPPER(6, ITextServices_TxGetVScroll) +DEFINE_STDCALL_WRAPPER(7, ITextServices_OnTxSetCursor) +DEFINE_STDCALL_WRAPPER(8, ITextServices_TxQueryHitPoint) +DEFINE_STDCALL_WRAPPER(9, ITextServices_OnTxInPlaceActivate) +DEFINE_STDCALL_WRAPPER(10, ITextServices_OnTxInPlaceDeactivate) +DEFINE_STDCALL_WRAPPER(11, ITextServices_OnTxUIActivate) +DEFINE_STDCALL_WRAPPER(12, ITextServices_OnTxUIDeactivate) +DEFINE_STDCALL_WRAPPER(13, ITextServices_TxGetText) +DEFINE_STDCALL_WRAPPER(14, ITextServices_TxSetText) +DEFINE_STDCALL_WRAPPER(15, ITextServices_TxGetCurTargetX) +DEFINE_STDCALL_WRAPPER(16, ITextServices_TxGetBaseLinePos) +DEFINE_STDCALL_WRAPPER(17, ITextServices_TxGetNaturalSize) +DEFINE_STDCALL_WRAPPER(18, ITextServices_TxGetDropTarget) +DEFINE_STDCALL_WRAPPER(19, ITextServices_OnTxPropertyBitsChange) +DEFINE_STDCALL_WRAPPER(20, ITextServices_TxGetCachedSize) + +const ITextServicesVtbl text_services_stdcall_vtbl = +{ + NULL, + NULL, + NULL, + STDCALL(ITextServices_TxSendMessage), + STDCALL(ITextServices_TxDraw), + STDCALL(ITextServices_TxGetHScroll), + STDCALL(ITextServices_TxGetVScroll), + STDCALL(ITextServices_OnTxSetCursor), + STDCALL(ITextServices_TxQueryHitPoint), + STDCALL(ITextServices_OnTxInPlaceActivate), + STDCALL(ITextServices_OnTxInPlaceDeactivate), + STDCALL(ITextServices_OnTxUIActivate), + STDCALL(ITextServices_OnTxUIDeactivate), + STDCALL(ITextServices_TxGetText), + STDCALL(ITextServices_TxSetText), + STDCALL(ITextServices_TxGetCurTargetX), + STDCALL(ITextServices_TxGetBaseLinePos), + STDCALL(ITextServices_TxGetNaturalSize), + STDCALL(ITextServices_TxGetDropTarget), + STDCALL(ITextServices_OnTxPropertyBitsChange), + STDCALL(ITextServices_TxGetCachedSize), +}; + +#endif /* __ASM_USE_THISCALL_WRAPPER */ static const ITextServicesVtbl textservices_vtbl = { - fnTextSrv_QueryInterface, - fnTextSrv_AddRef, - fnTextSrv_Release, - THISCALL(fnTextSrv_TxSendMessage), - THISCALL(fnTextSrv_TxDraw), - THISCALL(fnTextSrv_TxGetHScroll), - THISCALL(fnTextSrv_TxGetVScroll), - THISCALL(fnTextSrv_OnTxSetCursor), - THISCALL(fnTextSrv_TxQueryHitPoint), - THISCALL(fnTextSrv_OnTxInplaceActivate), - THISCALL(fnTextSrv_OnTxInplaceDeactivate), - THISCALL(fnTextSrv_OnTxUIActivate), - THISCALL(fnTextSrv_OnTxUIDeactivate), - THISCALL(fnTextSrv_TxGetText), - THISCALL(fnTextSrv_TxSetText), - THISCALL(fnTextSrv_TxGetCurTargetX), - THISCALL(fnTextSrv_TxGetBaseLinePos), - THISCALL(fnTextSrv_TxGetNaturalSize), - THISCALL(fnTextSrv_TxGetDropTarget), - THISCALL(fnTextSrv_OnTxPropertyBitsChange), - THISCALL(fnTextSrv_TxGetCachedSize) + fnTextSrv_QueryInterface, + fnTextSrv_AddRef, + fnTextSrv_Release, + THISCALL(fnTextSrv_TxSendMessage), + THISCALL(fnTextSrv_TxDraw), + THISCALL(fnTextSrv_TxGetHScroll), + THISCALL(fnTextSrv_TxGetVScroll), + THISCALL(fnTextSrv_OnTxSetCursor), + THISCALL(fnTextSrv_TxQueryHitPoint), + THISCALL(fnTextSrv_OnTxInPlaceActivate), + THISCALL(fnTextSrv_OnTxInPlaceDeactivate), + THISCALL(fnTextSrv_OnTxUIActivate), + THISCALL(fnTextSrv_OnTxUIDeactivate), + THISCALL(fnTextSrv_TxGetText), + THISCALL(fnTextSrv_TxSetText), + THISCALL(fnTextSrv_TxGetCurTargetX), + THISCALL(fnTextSrv_TxGetBaseLinePos), + THISCALL(fnTextSrv_TxGetNaturalSize), + THISCALL(fnTextSrv_TxGetDropTarget), + THISCALL(fnTextSrv_OnTxPropertyBitsChange), + THISCALL(fnTextSrv_TxGetCachedSize) }; +HRESULT create_text_services( IUnknown *outer, ITextHost *text_host, IUnknown **unk, BOOL emulate_10 ) +{ + struct text_services *services; + + TRACE( "%p %p --> %p\n", outer, text_host, unk ); + if (text_host == NULL) return E_POINTER; + + services = CoTaskMemAlloc( sizeof(*services) ); + if (services == NULL) return E_OUTOFMEMORY; + services->ref = 1; + services->IUnknown_inner.lpVtbl = &textservices_inner_vtbl; + services->ITextServices_iface.lpVtbl = &textservices_vtbl; + services->IRichEditOle_iface.lpVtbl = &re_ole_vtbl; + services->ITextDocument2Old_iface.lpVtbl = &text_doc2old_vtbl; + services->editor = ME_MakeEditor( text_host, emulate_10 ); + services->editor->richole = &services->IRichEditOle_iface; + + if (outer) services->outer_unk = outer; + else services->outer_unk = &services->IUnknown_inner; + + services->text_selection = NULL; + list_init( &services->rangelist ); + list_init( &services->clientsites ); + + *unk = &services->IUnknown_inner; + return S_OK; +} + /****************************************************************** * CreateTextServices (RICHED20.4) */ -HRESULT WINAPI CreateTextServices(IUnknown *pUnkOuter, ITextHost *pITextHost, IUnknown **ppUnk) -{ - ITextServicesImpl *ITextImpl; - - TRACE("%p %p --> %p\n", pUnkOuter, pITextHost, ppUnk); - if (pITextHost == NULL) - return E_POINTER; - - ITextImpl = CoTaskMemAlloc(sizeof(*ITextImpl)); - if (ITextImpl == NULL) - return E_OUTOFMEMORY; - InitializeCriticalSection(&ITextImpl->csTxtSrv); - ITextImpl->csTxtSrv.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ITextServicesImpl.csTxtSrv"); - ITextImpl->ref = 1; - ITextHost_AddRef(pITextHost); - ITextImpl->pMyHost = pITextHost; - ITextImpl->IUnknown_inner.lpVtbl = &textservices_inner_vtbl; - ITextImpl->ITextServices_iface.lpVtbl = &textservices_vtbl; - ITextImpl->editor = ME_MakeEditor(pITextHost, FALSE); - - if (pUnkOuter) - ITextImpl->outer_unk = pUnkOuter; - else - ITextImpl->outer_unk = &ITextImpl->IUnknown_inner; - - *ppUnk = &ITextImpl->IUnknown_inner; - return S_OK; +HRESULT WINAPI CreateTextServices( IUnknown *outer, ITextHost *text_host, IUnknown **unk ) +{ + return create_text_services( outer, text_host, unk, FALSE ); } diff --git a/dll/win32/riched20/undo.c b/dll/win32/riched20/undo.c index 2f18fc78bb31c..d95ce121234ae 100644 --- a/dll/win32/riched20/undo.c +++ b/dll/win32/riched20/undo.c @@ -335,19 +335,17 @@ static void ME_PlayUndoItem(ME_TextEditor *editor, struct undo_item *undo) case undo_set_para_fmt: { ME_Cursor tmp; - ME_DisplayItem *para; - ME_CursorFromCharOfs(editor, undo->u.set_para_fmt.pos, &tmp); - para = ME_FindItemBack(tmp.pRun, diParagraph); - add_undo_set_para_fmt( editor, ¶->member.para ); - para->member.para.fmt = undo->u.set_para_fmt.fmt; - para->member.para.border = undo->u.set_para_fmt.border; - mark_para_rewrap(editor, para); + cursor_from_char_ofs( editor, undo->u.set_para_fmt.pos, &tmp ); + add_undo_set_para_fmt( editor, tmp.para ); + tmp.para->fmt = undo->u.set_para_fmt.fmt; + tmp.para->border = undo->u.set_para_fmt.border; + para_mark_rewrap( editor, tmp.para ); break; } case undo_set_char_fmt: { ME_Cursor start, end; - ME_CursorFromCharOfs(editor, undo->u.set_char_fmt.pos, &start); + cursor_from_char_ofs( editor, undo->u.set_char_fmt.pos, &start ); end = start; ME_MoveCursorChars(editor, &end, undo->u.set_char_fmt.len, FALSE); ME_SetCharFormat(editor, &start, &end, &undo->u.set_char_fmt.fmt); @@ -356,55 +354,53 @@ static void ME_PlayUndoItem(ME_TextEditor *editor, struct undo_item *undo) case undo_insert_run: { ME_Cursor tmp; - ME_CursorFromCharOfs(editor, undo->u.insert_run.pos, &tmp); - ME_InsertRunAtCursor(editor, &tmp, undo->u.insert_run.style, - undo->u.insert_run.str, - undo->u.insert_run.len, - undo->u.insert_run.flags); + cursor_from_char_ofs( editor, undo->u.insert_run.pos, &tmp ); + run_insert( editor, &tmp, undo->u.insert_run.style, + undo->u.insert_run.str, undo->u.insert_run.len, + undo->u.insert_run.flags ); break; } case undo_delete_run: { ME_Cursor tmp; - ME_CursorFromCharOfs(editor, undo->u.delete_run.pos, &tmp); + cursor_from_char_ofs( editor, undo->u.delete_run.pos, &tmp ); ME_InternalDeleteText(editor, &tmp, undo->u.delete_run.len, TRUE); break; } case undo_join_paras: { ME_Cursor tmp; - ME_CursorFromCharOfs(editor, undo->u.join_paras.pos, &tmp); - ME_JoinParagraphs(editor, tmp.pPara, TRUE); + cursor_from_char_ofs( editor, undo->u.join_paras.pos, &tmp ); + para_join( editor, tmp.para, TRUE ); break; } case undo_split_para: { ME_Cursor tmp; - ME_DisplayItem *this_para, *new_para; + ME_Paragraph *this_para, *new_para; BOOL bFixRowStart; int paraFlags = undo->u.split_para.flags & (MEPF_ROWSTART|MEPF_CELL|MEPF_ROWEND); - ME_CursorFromCharOfs(editor, undo->u.split_para.pos, &tmp); - if (tmp.nOffset) - ME_SplitRunSimple(editor, &tmp); - this_para = tmp.pPara; - bFixRowStart = this_para->member.para.nFlags & MEPF_ROWSTART; + + cursor_from_char_ofs( editor, undo->u.split_para.pos, &tmp ); + if (tmp.nOffset) run_split( editor, &tmp ); + this_para = tmp.para; + bFixRowStart = this_para->nFlags & MEPF_ROWSTART; if (bFixRowStart) { /* Re-insert the paragraph before the table, making sure the nFlag value * is correct. */ - this_para->member.para.nFlags &= ~MEPF_ROWSTART; + this_para->nFlags &= ~MEPF_ROWSTART; } - new_para = ME_SplitParagraph(editor, tmp.pRun, tmp.pRun->member.run.style, - undo->u.split_para.eol_str->szData, undo->u.split_para.eol_str->nLen, paraFlags); + new_para = para_split( editor, tmp.run, tmp.run->style, + undo->u.split_para.eol_str->szData, undo->u.split_para.eol_str->nLen, paraFlags ); if (bFixRowStart) - new_para->member.para.nFlags |= MEPF_ROWSTART; - new_para->member.para.fmt = undo->u.split_para.fmt; - new_para->member.para.border = undo->u.split_para.border; + new_para->nFlags |= MEPF_ROWSTART; + new_para->fmt = undo->u.split_para.fmt; + new_para->border = undo->u.split_para.border; if (paraFlags) { - ME_DisplayItem *pCell = new_para->member.para.pCell; - pCell->member.cell.nRightBoundary = undo->u.split_para.cell_right_boundary; - pCell->member.cell.border = undo->u.split_para.cell_border; + para_cell( new_para )->nRightBoundary = undo->u.split_para.cell_right_boundary; + para_cell( new_para )->border = undo->u.split_para.cell_border; } break; } @@ -441,9 +437,8 @@ BOOL ME_Undo(ME_TextEditor *editor) destroy_undo_item( undo ); } - ME_MoveCursorFromTableRowStartParagraph(editor); + table_move_from_row_start( editor ); add_undo( editor, undo_end_transaction ); - ME_CheckTablesForCorruption(editor); editor->nUndoStackSize--; editor->nUndoMode = nMode; ME_UpdateRepaint(editor, FALSE); @@ -478,9 +473,8 @@ BOOL ME_Redo(ME_TextEditor *editor) list_remove( &undo->entry ); destroy_undo_item( undo ); } - ME_MoveCursorFromTableRowStartParagraph(editor); + table_move_from_row_start( editor ); add_undo( editor, undo_end_transaction ); - ME_CheckTablesForCorruption(editor); editor->nUndoMode = nMode; ME_UpdateRepaint(editor, FALSE); return TRUE; diff --git a/dll/win32/riched20/wrap.c b/dll/win32/riched20/wrap.c index c3b5883dbf1a7..9456d54d81508 100644 --- a/dll/win32/riched20/wrap.c +++ b/dll/win32/riched20/wrap.c @@ -43,10 +43,9 @@ typedef struct tagME_WrapContext int nRow; POINT pt; BOOL bOverflown, bWordWrap; - ME_DisplayItem *pPara; - ME_DisplayItem *pRowStart; - - ME_DisplayItem *pLastSplittableRun; + ME_Paragraph *para; + ME_Run *pRowStart; + ME_Run *pLastSplittableRun; } ME_WrapContext; static BOOL get_run_glyph_buffers( ME_Run *run ) @@ -128,31 +127,28 @@ static void calc_run_extent(ME_Context *c, const ME_Paragraph *para, int startx, * Splits a run into two in a given place. It also updates the screen position * and size (extent) of the newly generated runs. */ -static ME_DisplayItem *split_run_extents(ME_WrapContext *wc, ME_DisplayItem *item, int nVChar) +static ME_Run *split_run_extents( ME_WrapContext *wc, ME_Run *run, int nVChar ) { ME_TextEditor *editor = wc->context->editor; - ME_Run *run, *run2; - ME_Paragraph *para = &wc->pPara->member.para; - ME_Cursor cursor = {wc->pPara, item, nVChar}; + ME_Run *run2; + ME_Cursor cursor = { wc->para, run, nVChar }; - assert(item->member.run.nCharOfs != -1); + assert( run->nCharOfs != -1 ); ME_CheckCharOffsets(editor); - run = &item->member.run; - TRACE("Before split: %s(%d, %d)\n", debugstr_run( run ), run->pt.x, run->pt.y); - ME_SplitRunSimple(editor, &cursor); + run_split( editor, &cursor ); - run2 = &cursor.pRun->member.run; + run2 = cursor.run; run2->script_analysis = run->script_analysis; shape_run( wc->context, run ); shape_run( wc->context, run2 ); - calc_run_extent(wc->context, para, wc->nRow ? wc->nLeftMargin : wc->nFirstMargin, run); + calc_run_extent(wc->context, wc->para, wc->nRow ? wc->nLeftMargin : wc->nFirstMargin, run); - run2->pt.x = run->pt.x+run->nWidth; + run2->pt.x = run->pt.x + run->nWidth; run2->pt.y = run->pt.y; ME_CheckCharOffsets(editor); @@ -161,7 +157,7 @@ static ME_DisplayItem *split_run_extents(ME_WrapContext *wc, ME_DisplayItem *ite debugstr_run( run ), run->pt.x, run->pt.y, debugstr_run( run2 ), run2->pt.x, run2->pt.y); - return cursor.pRun; + return cursor.run; } /****************************************************************************** @@ -177,44 +173,44 @@ static int find_split_point( ME_Context *c, int cx, ME_Run *run ) return ME_CharFromPointContext( c, cx, run, FALSE, FALSE ); } -static ME_DisplayItem *ME_MakeRow(int height, int baseline, int width) +static ME_Row *row_create( int height, int baseline, int width ) { ME_DisplayItem *item = ME_MakeDI(diStartRow); item->member.row.nHeight = height; item->member.row.nBaseline = baseline; item->member.row.nWidth = width; - return item; + return &item->member.row; } static void ME_BeginRow(ME_WrapContext *wc) { - PARAFORMAT2 *pFmt; - ME_DisplayItem *para = wc->pPara; + ME_Cell *cell; - pFmt = ¶->member.para.fmt; wc->pRowStart = NULL; wc->bOverflown = FALSE; wc->pLastSplittableRun = NULL; wc->bWordWrap = wc->context->editor->bWordWrap; - if (para->member.para.nFlags & (MEPF_ROWSTART|MEPF_ROWEND)) { + if (wc->para->nFlags & (MEPF_ROWSTART | MEPF_ROWEND)) + { wc->nAvailWidth = 0; wc->bWordWrap = FALSE; - if (para->member.para.nFlags & MEPF_ROWEND) + if (wc->para->nFlags & MEPF_ROWEND) { - ME_Cell *cell = &ME_FindItemBack(para, diCell)->member.cell; + cell = table_row_end_cell( wc->para ); cell->nWidth = 0; } - } else if (para->member.para.pCell) { - ME_Cell *cell = ¶->member.para.pCell->member.cell; + } + else if (para_cell( wc->para )) + { int width; + cell = para_cell( wc->para ); width = cell->nRightBoundary; - if (cell->prev_cell) - width -= cell->prev_cell->member.cell.nRightBoundary; - if (!cell->prev_cell) + if (cell_prev( cell )) width -= cell_prev( cell )->nRightBoundary; + else { - int rowIndent = ME_GetTableRowEnd(para)->member.para.fmt.dxStartIndent; + int rowIndent = table_row_end( wc->para )->fmt.dxStartIndent; width -= rowIndent; } cell->nWidth = max(ME_twips2pointsX(wc->context, width), 0); @@ -222,33 +218,32 @@ static void ME_BeginRow(ME_WrapContext *wc) wc->nAvailWidth = cell->nWidth - (wc->nRow ? wc->nLeftMargin : wc->nFirstMargin) - wc->nRightMargin; wc->bWordWrap = TRUE; - } else { + } + else wc->nAvailWidth = wc->context->nAvailWidth - (wc->nRow ? wc->nLeftMargin : wc->nFirstMargin) - wc->nRightMargin; - } + wc->pt.x = wc->context->pt.x; if (wc->context->editor->bEmulateVersion10 && /* v1.0 - 3.0 */ - pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE) + para_in_table( wc->para )) /* Shift the text down because of the border. */ wc->pt.y++; } -static void layout_row( ME_DisplayItem *start, const ME_DisplayItem *end ) +static void layout_row( ME_Run *start, ME_Run *last ) { - ME_DisplayItem *p; + ME_Run *run; int i, num_runs = 0; int buf[16 * 5]; /* 5 arrays - 4 of int & 1 of BYTE, alloc space for 5 of ints */ int *vis_to_log = buf, *log_to_vis, *widths, *pos; BYTE *levels; BOOL found_black = FALSE; - for (p = end->prev; p != start->prev; p = p->prev) + for (run = last; run; run = run_prev( run )) { - if (p->type == diRun) - { - if (!found_black) found_black = !(p->member.run.nFlags & (MERF_WHITESPACE | MERF_ENDPARA)); - if (found_black) num_runs++; - } + if (!found_black) found_black = !(run->nFlags & (MERF_WHITESPACE | MERF_ENDPARA)); + if (found_black) num_runs++; + if (run == start) break; } TRACE("%d runs\n", num_runs); @@ -262,162 +257,138 @@ static void layout_row( ME_DisplayItem *start, const ME_DisplayItem *end ) pos = vis_to_log + 3 * num_runs; levels = (BYTE*)(vis_to_log + 4 * num_runs); - for (i = 0, p = start; i < num_runs; p = p->next) + for (i = 0, run = start; i < num_runs; run = run_next( run )) { - if (p->type == diRun) - { - levels[i] = p->member.run.script_analysis.s.uBidiLevel; - widths[i] = p->member.run.nWidth; - TRACE( "%d: level %d width %d\n", i, levels[i], widths[i] ); - i++; - } + levels[i] = run->script_analysis.s.uBidiLevel; + widths[i] = run->nWidth; + TRACE( "%d: level %d width %d\n", i, levels[i], widths[i] ); + i++; } ScriptLayout( num_runs, levels, vis_to_log, log_to_vis ); - pos[0] = start->member.run.para->pt.x; + pos[0] = run->para->pt.x; for (i = 1; i < num_runs; i++) pos[i] = pos[i - 1] + widths[ vis_to_log[ i - 1 ] ]; - for (i = 0, p = start; i < num_runs; p = p->next) + for (i = 0, run = start; i < num_runs; run = run_next( run )) { - if (p->type == diRun) - { - p->member.run.pt.x = pos[ log_to_vis[ i ] ]; - TRACE( "%d: x = %d\n", i, p->member.run.pt.x ); - i++; - } + run->pt.x = pos[ log_to_vis[ i ] ]; + TRACE( "%d: x = %d\n", i, run->pt.x ); + i++; } if (vis_to_log != buf) heap_free( vis_to_log ); } -static void ME_InsertRowStart(ME_WrapContext *wc, const ME_DisplayItem *pEnd) +static void ME_InsertRowStart( ME_WrapContext *wc, ME_Run *last ) { - ME_DisplayItem *p, *row; - ME_Paragraph *para = &wc->pPara->member.para; - BOOL bSkippingSpaces = TRUE; - int ascent = 0, descent = 0, width=0, shift = 0, align = 0; + ME_Run *run; + ME_Row *row; + BOOL bSkippingSpaces = TRUE; + int ascent = 0, descent = 0, width = 0, shift = 0, align = 0; - /* Include height of para numbering label */ - if (wc->nRow == 0 && para->fmt.wNumbering) - { - ascent = para->para_num.style->tm.tmAscent; - descent = para->para_num.style->tm.tmDescent; - } + /* Include height of para numbering label */ + if (wc->nRow == 0 && wc->para->fmt.wNumbering) + { + ascent = wc->para->para_num.style->tm.tmAscent; + descent = wc->para->para_num.style->tm.tmDescent; + } - for (p = pEnd->prev; p!=wc->pRowStart->prev; p = p->prev) - { - /* ENDPARA run shouldn't affect row height, except if it's the only run in the paragraph */ - if (p->type==diRun && ((p==wc->pRowStart) || !(p->member.run.nFlags & MERF_ENDPARA))) { /* FIXME add more run types */ - if (p->member.run.nAscent>ascent) - ascent = p->member.run.nAscent; - if (p->member.run.nDescent>descent) - descent = p->member.run.nDescent; - if (bSkippingSpaces) + for (run = last; run; run = run_prev( run )) + { + /* ENDPARA run shouldn't affect row height, except if it's the only run in the paragraph */ + if (run == wc->pRowStart || !(run->nFlags & MERF_ENDPARA)) { - /* Exclude space characters from run width. - * Other whitespace or delimiters are not treated this way. */ - int len = p->member.run.len; - WCHAR *text = get_text( &p->member.run, len - 1 ); - - assert (len); - if (~p->member.run.nFlags & MERF_GRAPHICS) - while (len && *(text--) == ' ') - len--; - if (len) - { - if (len == p->member.run.len) - width += p->member.run.nWidth; - else - width += ME_PointFromCharContext( wc->context, &p->member.run, len, FALSE ); - } - bSkippingSpaces = !len; - } else if (!(p->member.run.nFlags & MERF_ENDPARA)) - width += p->member.run.nWidth; - } - } + if (run->nAscent > ascent) ascent = run->nAscent; + if (run->nDescent > descent) descent = run->nDescent; + if (bSkippingSpaces) + { + /* Exclude space characters from run width. + * Other whitespace or delimiters are not treated this way. */ + int len = run->len; + WCHAR *text = get_text( run, len - 1 ); + + assert(len); + if (~run->nFlags & MERF_GRAPHICS) + while (len && *(text--) == ' ') len--; + if (len) + { + if (len == run->len) + width += run->nWidth; + else + width += ME_PointFromCharContext( wc->context, run, len, FALSE ); + } + bSkippingSpaces = !len; + } + else if (!(run->nFlags & MERF_ENDPARA)) + width += run->nWidth; + } + if (run == wc->pRowStart) break; + } - para->nWidth = max(para->nWidth, width); - row = ME_MakeRow(ascent+descent, ascent, width); - if (wc->context->editor->bEmulateVersion10 && /* v1.0 - 3.0 */ - (para->fmt.dwMask & PFM_TABLE) && (para->fmt.wEffects & PFE_TABLE)) - { - /* The text was shifted down in ME_BeginRow so move the wrap context - * back to where it should be. */ - wc->pt.y--; - /* The height of the row is increased by the borders. */ - row->member.row.nHeight += 2; - } - row->member.row.pt = wc->pt; - row->member.row.nLMargin = (!wc->nRow ? wc->nFirstMargin : wc->nLeftMargin); - row->member.row.nRMargin = wc->nRightMargin; - assert(para->fmt.dwMask & PFM_ALIGNMENT); - align = para->fmt.wAlignment; - if (align == PFA_CENTER) - shift = max((wc->nAvailWidth-width)/2, 0); - if (align == PFA_RIGHT) - shift = max(wc->nAvailWidth-width, 0); - - if (para->nFlags & MEPF_COMPLEX) layout_row( wc->pRowStart, pEnd ); - - row->member.row.pt.x = row->member.row.nLMargin + shift; - for (p = wc->pRowStart; p!=pEnd; p = p->next) - { - if (p->type==diRun) { /* FIXME add more run types */ - p->member.run.pt.x += row->member.row.nLMargin+shift; + wc->para->nWidth = max( wc->para->nWidth, width ); + row = row_create( ascent + descent, ascent, width ); + if (wc->context->editor->bEmulateVersion10 && /* v1.0 - 3.0 */ + (wc->para->fmt.dwMask & PFM_TABLE) && (wc->para->fmt.wEffects & PFE_TABLE)) + { + /* The text was shifted down in ME_BeginRow so move the wrap context + * back to where it should be. */ + wc->pt.y--; + /* The height of the row is increased by the borders. */ + row->nHeight += 2; } - } + row->pt = wc->pt; + row->nLMargin = (!wc->nRow ? wc->nFirstMargin : wc->nLeftMargin); + row->nRMargin = wc->nRightMargin; + assert(wc->para->fmt.dwMask & PFM_ALIGNMENT); + align = wc->para->fmt.wAlignment; + if (align == PFA_CENTER) shift = max((wc->nAvailWidth-width)/2, 0); + if (align == PFA_RIGHT) shift = max(wc->nAvailWidth-width, 0); - if (wc->nRow == 0 && para->fmt.wNumbering) - { - para->para_num.pt.x = wc->nParaNumOffset + shift; - para->para_num.pt.y = wc->pt.y + row->member.row.nBaseline; - } + if (wc->para->nFlags & MEPF_COMPLEX) layout_row( wc->pRowStart, last ); + + row->pt.x = row->nLMargin + shift; - ME_InsertBefore(wc->pRowStart, row); - wc->nRow++; - wc->pt.y += row->member.row.nHeight; - ME_BeginRow(wc); + for (run = wc->pRowStart; run; run = run_next( run )) + { + run->pt.x += row->nLMargin + shift; + if (run == last) break; + } + + if (wc->nRow == 0 && wc->para->fmt.wNumbering) + { + wc->para->para_num.pt.x = wc->nParaNumOffset + shift; + wc->para->para_num.pt.y = wc->pt.y + row->nBaseline; + } + + ME_InsertBefore( run_get_di( wc->pRowStart ), row_get_di( row ) ); + wc->nRow++; + wc->pt.y += row->nHeight; + ME_BeginRow( wc ); } -static void ME_WrapEndParagraph(ME_WrapContext *wc, ME_DisplayItem *p) +static void ME_WrapEndParagraph( ME_WrapContext *wc ) { - ME_DisplayItem *para = wc->pPara; - PARAFORMAT2 *pFmt = ¶->member.para.fmt; - if (wc->pRowStart) - ME_InsertRowStart(wc, p); + if (wc->pRowStart) ME_InsertRowStart( wc, wc->para->eop_run ); + if (wc->context->editor->bEmulateVersion10 && /* v1.0 - 3.0 */ - pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE) + wc->para->fmt.dwMask & PFM_TABLE && wc->para->fmt.wEffects & PFE_TABLE) { /* ME_BeginRow was called an extra time for the paragraph, and it shifts the * text down by one pixel for the border, so fix up the wrap context. */ wc->pt.y--; } - - /* - p = para->next; - while(p) { - if (p->type == diParagraph || p->type == diTextEnd) - return; - if (p->type == diRun) - { - ME_Run *run = &p->member.run; - TRACE("%s - (%d, %d)\n", debugstr_run(run), run->pt.x, run->pt.y); - } - p = p->next; - } - */ } -static void ME_WrapSizeRun(ME_WrapContext *wc, ME_DisplayItem *p) +static void ME_WrapSizeRun( ME_WrapContext *wc, ME_Run *run ) { /* FIXME compose style (out of character and paragraph styles) here */ - ME_UpdateRunFlags(wc->context->editor, &p->member.run); + ME_UpdateRunFlags( wc->context->editor, run ); - calc_run_extent(wc->context, &wc->pPara->member.para, - wc->nRow ? wc->nLeftMargin : wc->nFirstMargin, &p->member.run); + calc_run_extent( wc->context, wc->para, + wc->nRow ? wc->nLeftMargin : wc->nFirstMargin, run ); } @@ -453,178 +424,169 @@ static int reverse_find_whitespace(const WCHAR *s, int start) return i; } -static ME_DisplayItem *ME_MaximizeSplit(ME_WrapContext *wc, ME_DisplayItem *p, int i) +static ME_Run *ME_MaximizeSplit( ME_WrapContext *wc, ME_Run *run, int i ) { - ME_DisplayItem *pp, *piter = p; + ME_Run *new_run, *iter = run; int j; if (!i) return NULL; - j = reverse_find_non_whitespace( get_text( &p->member.run, 0 ), i); - if (j>0) { - pp = split_run_extents(wc, piter, j); - wc->pt.x += piter->member.run.nWidth; - return pp; + j = reverse_find_non_whitespace( get_text( run, 0 ), i ); + if (j > 0) + { + new_run = split_run_extents( wc, iter, j ); + wc->pt.x += iter->nWidth; + return new_run; } else { - pp = piter; + new_run = iter; /* omit all spaces before split point */ - while(piter != wc->pRowStart) + while (iter != wc->pRowStart) { - piter = ME_FindItemBack(piter, diRun); - if (piter->member.run.nFlags & MERF_WHITESPACE) + iter = run_prev( iter ); + if (iter->nFlags & MERF_WHITESPACE) { - pp = piter; + new_run = iter; continue; } - if (piter->member.run.nFlags & MERF_ENDWHITE) + if (iter->nFlags & MERF_ENDWHITE) { - i = reverse_find_non_whitespace( get_text( &piter->member.run, 0 ), - piter->member.run.len ); - pp = split_run_extents(wc, piter, i); - wc->pt = pp->member.run.pt; - return pp; + i = reverse_find_non_whitespace( get_text( iter, 0 ), iter->len ); + new_run = split_run_extents( wc, iter, i ); + wc->pt = new_run->pt; + return new_run; } /* this run is the end of spaces, so the run edge is a good point to split */ - wc->pt = pp->member.run.pt; + wc->pt = new_run->pt; wc->bOverflown = TRUE; - TRACE("Split point is: %s|%s\n", debugstr_run( &piter->member.run ), debugstr_run( &pp->member.run )); - return pp; + TRACE( "Split point is: %s|%s\n", debugstr_run( iter ), debugstr_run( new_run ) ); + return new_run; } - wc->pt = piter->member.run.pt; - return piter; + wc->pt = iter->pt; + return iter; } } -static ME_DisplayItem *ME_SplitByBacktracking(ME_WrapContext *wc, ME_DisplayItem *p, int loc) +static ME_Run *ME_SplitByBacktracking( ME_WrapContext *wc, ME_Run *run, int loc ) { - ME_DisplayItem *piter = p, *pp; + ME_Run *new_run; int i, idesp, len; - ME_Run *run = &p->member.run; idesp = i = find_split_point( wc->context, loc, run ); len = run->len; - assert(len>0); - assert(i 0 ); + assert( i < len ); + if (i) + { /* don't split words */ i = reverse_find_whitespace( get_text( run, 0 ), i ); - pp = ME_MaximizeSplit(wc, p, i); - if (pp) - return pp; + new_run = ME_MaximizeSplit(wc, run, i); + if (new_run) return new_run; } - TRACE("Must backtrack to split at: %s\n", debugstr_run( &p->member.run )); + TRACE("Must backtrack to split at: %s\n", debugstr_run( run )); if (wc->pLastSplittableRun) { - if (wc->pLastSplittableRun->member.run.nFlags & (MERF_GRAPHICS|MERF_TAB)) + if (wc->pLastSplittableRun->nFlags & (MERF_GRAPHICS|MERF_TAB)) { - wc->pt = wc->pLastSplittableRun->member.run.pt; + wc->pt = wc->pLastSplittableRun->pt; return wc->pLastSplittableRun; } - else if (wc->pLastSplittableRun->member.run.nFlags & MERF_SPLITTABLE) + else if (wc->pLastSplittableRun->nFlags & MERF_SPLITTABLE) { /* the following two lines are just to check if we forgot to call UpdateRunFlags earlier, they serve no other purpose */ ME_UpdateRunFlags(wc->context->editor, run); - assert((wc->pLastSplittableRun->member.run.nFlags & MERF_SPLITTABLE)); + assert((wc->pLastSplittableRun->nFlags & MERF_SPLITTABLE)); - piter = wc->pLastSplittableRun; - run = &piter->member.run; + run = wc->pLastSplittableRun; len = run->len; /* don't split words */ i = reverse_find_whitespace( get_text( run, 0 ), len ); if (i == len) i = reverse_find_non_whitespace( get_text( run, 0 ), len ); - if (i) { - ME_DisplayItem *piter2 = split_run_extents(wc, piter, i); - wc->pt = piter2->member.run.pt; - return piter2; - } - /* splittable = must have whitespaces */ - assert(0 == "Splittable, but no whitespaces"); + new_run = split_run_extents(wc, run, i); + wc->pt = new_run->pt; + return new_run; } else { /* restart from the first run beginning with spaces */ - wc->pt = wc->pLastSplittableRun->member.run.pt; + wc->pt = wc->pLastSplittableRun->pt; return wc->pLastSplittableRun; } } - TRACE("Backtracking failed, trying desperate: %s\n", debugstr_run( &p->member.run )); + TRACE("Backtracking failed, trying desperate: %s\n", debugstr_run( run )); /* OK, no better idea, so assume we MAY split words if we can split at all*/ if (idesp) - return split_run_extents(wc, piter, idesp); + return split_run_extents(wc, run, idesp); else - if (wc->pRowStart && piter != wc->pRowStart) + if (wc->pRowStart && run != wc->pRowStart) { /* don't need to break current run, because it's possible to split before this run */ wc->bOverflown = TRUE; - return piter; + return run; } else { /* split point inside first character - no choice but split after that char */ - if (len != 1) { + if (len != 1) /* the run is more than 1 char, so we may split */ - return split_run_extents(wc, piter, 1); - } + return split_run_extents( wc, run, 1 ); + /* the run is one char, can't split it */ - return piter; + return run; } } -static ME_DisplayItem *ME_WrapHandleRun(ME_WrapContext *wc, ME_DisplayItem *p) +static ME_Run *ME_WrapHandleRun( ME_WrapContext *wc, ME_Run *run ) { - ME_DisplayItem *pp; - ME_Run *run; + ME_Run *new_run; int len; - assert(p->type == diRun); - if (!wc->pRowStart) - wc->pRowStart = p; - run = &p->member.run; + if (!wc->pRowStart) wc->pRowStart = run; run->pt.x = wc->pt.x; run->pt.y = wc->pt.y; - ME_WrapSizeRun(wc, p); + ME_WrapSizeRun( wc, run ); len = run->len; if (wc->bOverflown) /* just skipping final whitespaces */ { /* End paragraph run can't overflow to the next line by itself. */ - if (run->nFlags & MERF_ENDPARA) - return p->next; + if (run->nFlags & MERF_ENDPARA) return run_next( run ); - if (run->nFlags & MERF_WHITESPACE) { + if (run->nFlags & MERF_WHITESPACE) + { wc->pt.x += run->nWidth; /* skip runs consisting of only whitespaces */ - return p->next; + return run_next( run ); } - if (run->nFlags & MERF_STARTWHITE) { + if (run->nFlags & MERF_STARTWHITE) + { /* try to split the run at the first non-white char */ int black; black = find_non_whitespace( get_text( run, 0 ), run->len, 0 ); - if (black) { + if (black) + { + ME_Run *new_run; wc->bOverflown = FALSE; - pp = split_run_extents(wc, p, black); - calc_run_extent(wc->context, &wc->pPara->member.para, - wc->nRow ? wc->nLeftMargin : wc->nFirstMargin, - &pp->member.run); - ME_InsertRowStart(wc, pp); - return pp; + new_run = split_run_extents( wc, run, black ); + calc_run_extent( wc->context, wc->para, + wc->nRow ? wc->nLeftMargin : wc->nFirstMargin, run ); + ME_InsertRowStart( wc, run ); + return new_run; } } /* black run: the row goes from pRowStart to the previous run */ - ME_InsertRowStart(wc, p); - return p; + ME_InsertRowStart( wc, run_prev( run ) ); + return run; } /* simply end the current row and move on to next one */ if (run->nFlags & MERF_ENDROW) { - p = p->next; - ME_InsertRowStart(wc, p); - return p; + ME_InsertRowStart( wc, run ); + return run_next( run ); } /* will current run fit? */ @@ -636,35 +598,35 @@ static ME_DisplayItem *ME_WrapHandleRun(ME_WrapContext *wc, ME_DisplayItem *p) if (run->nFlags & (MERF_WHITESPACE | MERF_ENDPARA)) { /* let the overflow logic handle it */ wc->bOverflown = TRUE; - return p; + return run; } /* TAB: we can split before */ if (run->nFlags & MERF_TAB) { wc->bOverflown = TRUE; - if (wc->pRowStart == p) + if (wc->pRowStart == run) /* Don't split before the start of the run, or we will get an * endless loop. */ - return p->next; + return run_next( run ); else - return p; + return run; } /* graphics: we can split before, if run's width is smaller than row's width */ if ((run->nFlags & MERF_GRAPHICS) && run->nWidth <= wc->nAvailWidth) { wc->bOverflown = TRUE; - return p; + return run; } /* can we separate out the last spaces ? (to use overflow logic later) */ if (run->nFlags & MERF_ENDWHITE) { /* we aren't sure if it's *really* necessary, it's a good start however */ int black = reverse_find_non_whitespace( get_text( run, 0 ), len ); - split_run_extents(wc, p, black); + split_run_extents( wc, run, black ); /* handle both parts again */ - return p; + return run; } /* determine the split point by backtracking */ - pp = ME_SplitByBacktracking(wc, p, loc); - if (pp == wc->pRowStart) + new_run = ME_SplitByBacktracking( wc, run, loc ); + if (new_run == wc->pRowStart) { if (run->nFlags & MERF_STARTWHITE) { @@ -676,32 +638,32 @@ static ME_DisplayItem *ME_WrapHandleRun(ME_WrapContext *wc, ME_DisplayItem *p) /* The lines will only contain spaces, and the rest of the run will * overflow onto the next line. */ wc->bOverflown = TRUE; - return p; + return run; } /* Couldn't split the first run, possible because we have a large font * with a single character that caused an overflow. */ wc->pt.x += run->nWidth; - return p->next; + return run_next( run ); } - if (p != pp) /* found a suitable split point */ + if (run != new_run) /* found a suitable split point */ { wc->bOverflown = TRUE; - return pp; + return new_run; } /* we detected that it's best to split on start of this run */ if (wc->bOverflown) - return pp; + return new_run; ERR("failure!\n"); /* not found anything - writing over margins is the only option left */ } if ((run->nFlags & (MERF_SPLITTABLE | MERF_STARTWHITE)) - || ((run->nFlags & (MERF_GRAPHICS|MERF_TAB)) && (p != wc->pRowStart))) + || ((run->nFlags & (MERF_GRAPHICS|MERF_TAB)) && (run != wc->pRowStart))) { - wc->pLastSplittableRun = p; + wc->pLastSplittableRun = run; } wc->pt.x += run->nWidth; - return p->next; + return run_next( run ); } static int ME_GetParaLineSpace(ME_Context* c, ME_Paragraph* para) @@ -727,39 +689,41 @@ static int ME_GetParaLineSpace(ME_Context* c, ME_Paragraph* para) return sp * c->editor->nZoomNumerator / c->editor->nZoomDenominator; } -static void ME_PrepareParagraphForWrapping(ME_TextEditor *editor, ME_Context *c, ME_DisplayItem *tp) { - ME_DisplayItem *p; - - tp->member.para.nWidth = 0; - /* remove row start items as they will be reinserted by the - * paragraph wrapper anyway */ - editor->total_rows -= tp->member.para.nRows; - tp->member.para.nRows = 0; - for (p = tp->next; p != tp->member.para.next_para; p = p->next) { - if (p->type == diStartRow) { - ME_DisplayItem *pRow = p; - p = p->prev; - ME_Remove(pRow); - ME_DestroyDisplayItem(pRow); +static void ME_PrepareParagraphForWrapping( ME_TextEditor *editor, ME_Context *c, ME_Paragraph *para ) +{ + ME_DisplayItem *p; + + para->nWidth = 0; + /* remove row start items as they will be reinserted by the + * paragraph wrapper anyway */ + editor->total_rows -= para->nRows; + para->nRows = 0; + for (p = para_get_di( para ); p != para->next_para; p = p->next) + { + if (p->type == diStartRow) + { + ME_DisplayItem *pRow = p; + p = p->prev; + ME_Remove( pRow ); + ME_DestroyDisplayItem( pRow ); + } } - } - /* join runs that can be joined */ - for (p = tp->next; p != tp->member.para.next_para; p = p->next) { - assert(p->type != diStartRow); /* should have been deleted above */ - if (p->type == diRun) { - while (p->next->type == diRun && /* FIXME */ - ME_CanJoinRuns(&p->member.run, &p->next->member.run)) { - ME_JoinRuns(c->editor, p); - } + + /* join runs that can be joined */ + for (p = para_get_di( para )->next; p != para->next_para; p = p->next) + { + assert(p->type != diStartRow); /* should have been deleted above */ + if (p->type == diRun) + { + while (p->next->type == diRun && ME_CanJoinRuns( &p->member.run, &p->next->member.run )) + run_join( c->editor, &p->member.run ); + } } - } } -static HRESULT itemize_para( ME_Context *c, ME_DisplayItem *p ) +static HRESULT itemize_para( ME_Context *c, ME_Paragraph *para ) { - ME_Paragraph *para = &p->member.para; ME_Run *run; - ME_DisplayItem *di; SCRIPT_ITEM buf[16], *items = buf; int items_passed = ARRAY_SIZE( buf ), num_items, cur_item; SCRIPT_CONTROL control = { LANG_USER_DEFAULT, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, @@ -767,8 +731,6 @@ static HRESULT itemize_para( ME_Context *c, ME_DisplayItem *p ) SCRIPT_STATE state = { 0, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 0, 0 }; HRESULT hr; - assert( p->type == diParagraph ); - if (para->fmt.dwMask & PFM_RTLPARA && para->fmt.wEffects & PFE_RTLPARA) state.uBidiLevel = 1; @@ -799,19 +761,13 @@ static HRESULT itemize_para( ME_Context *c, ME_DisplayItem *p ) } TRACE( "before splitting runs into ranges\n" ); - for (di = p->next; di != p->member.para.next_para; di = di->next) - { - if (di->type != diRun) continue; - TRACE( "\t%d: %s\n", di->member.run.nCharOfs, debugstr_run( &di->member.run ) ); - } + for (run = para_first_run( para ); run; run = run_next( run )) + TRACE( "\t%d: %s\n", run->nCharOfs, debugstr_run( run ) ); } /* split runs into ranges at item boundaries */ - for (di = p->next, cur_item = 0; di != p->member.para.next_para; di = di->next) + for (run = para_first_run( para ), cur_item = 0; run; run = run_next( run )) { - if (di->type != diRun) continue; - run = &di->member.run; - if (run->nCharOfs == items[cur_item+1].iCharPos) cur_item++; items[cur_item].a.fLogicalOrder = TRUE; @@ -821,19 +777,16 @@ static HRESULT itemize_para( ME_Context *c, ME_DisplayItem *p ) if (run->nCharOfs + run->len > items[cur_item+1].iCharPos) { - ME_Cursor cursor = {p, di, items[cur_item+1].iCharPos - run->nCharOfs}; - ME_SplitRunSimple( c->editor, &cursor ); + ME_Cursor cursor = { para, run, items[cur_item + 1].iCharPos - run->nCharOfs }; + run_split( c->editor, &cursor ); } } if (TRACE_ON( richedit )) { TRACE( "after splitting into ranges\n" ); - for (di = p->next; di != p->member.para.next_para; di = di->next) - { - if (di->type != diRun) continue; - TRACE( "\t%d: %s\n", di->member.run.nCharOfs, debugstr_run( &di->member.run ) ); - } + for (run = para_first_run( para ); run; run = run_next( run )) + TRACE( "\t%d: %s\n", run->nCharOfs, debugstr_run( run ) ); } para->nFlags |= MEPF_COMPLEX; @@ -844,353 +797,330 @@ static HRESULT itemize_para( ME_Context *c, ME_DisplayItem *p ) } -static HRESULT shape_para( ME_Context *c, ME_DisplayItem *p ) +static HRESULT shape_para( ME_Context *c, ME_Paragraph *para ) { - ME_DisplayItem *di; ME_Run *run; HRESULT hr; - for (di = p->next; di != p->member.para.next_para; di = di->next) + for (run = para_first_run( para ); run; run = run_next( run )) { - if (di->type != diRun) continue; - run = &di->member.run; - hr = shape_run( c, run ); if (FAILED( hr )) { - run->para->nFlags &= ~MEPF_COMPLEX; + para->nFlags &= ~MEPF_COMPLEX; return hr; } } return hr; } -static void ME_WrapTextParagraph(ME_TextEditor *editor, ME_Context *c, ME_DisplayItem *tp) { - ME_DisplayItem *p; +static void ME_WrapTextParagraph( ME_TextEditor *editor, ME_Context *c, ME_Paragraph *para ) +{ + ME_Run *run; ME_WrapContext wc; int border = 0; int linespace = 0; - PARAFORMAT2 *pFmt; - assert(tp->type == diParagraph); - if (!(tp->member.para.nFlags & MEPF_REWRAP)) { - return; - } - ME_PrepareParagraphForWrapping(editor, c, tp); + if (!(para->nFlags & MEPF_REWRAP)) return; + + ME_PrepareParagraphForWrapping( editor, c, para ); /* Calculate paragraph numbering label */ - para_num_init( c, &tp->member.para ); + para_num_init( c, para ); /* For now treating all non-password text as complex for better testing */ - if (!c->editor->cPasswordMask /* && + if (!c->editor->password_char /* && ScriptIsComplex( tp->member.para.text->szData, tp->member.para.text->nLen, SIC_COMPLEX ) == S_OK */) { - if (SUCCEEDED( itemize_para( c, tp ) )) - shape_para( c, tp ); + if (SUCCEEDED( itemize_para( c, para ) )) + shape_para( c, para ); } - pFmt = &tp->member.para.fmt; - wc.context = c; - wc.pPara = tp; -/* wc.para_style = tp->member.para.style; */ + wc.para = para; wc.style = NULL; wc.nParaNumOffset = 0; - if (tp->member.para.nFlags & MEPF_ROWEND) { + if (para->nFlags & MEPF_ROWEND) wc.nFirstMargin = wc.nLeftMargin = wc.nRightMargin = 0; - } else { - int dxStartIndent = pFmt->dxStartIndent; - if (tp->member.para.pCell) { - dxStartIndent += ME_GetTableRowEnd(tp)->member.para.fmt.dxOffset; - } - wc.nLeftMargin = ME_twips2pointsX(c, dxStartIndent + pFmt->dxOffset); - wc.nFirstMargin = ME_twips2pointsX(c, dxStartIndent); - if (pFmt->wNumbering) + else + { + int dxStartIndent = para->fmt.dxStartIndent; + if (para_cell( wc.para )) dxStartIndent += table_row_end( para )->fmt.dxOffset; + + wc.nLeftMargin = ME_twips2pointsX( c, dxStartIndent + para->fmt.dxOffset ); + wc.nFirstMargin = ME_twips2pointsX( c, dxStartIndent ); + if (para->fmt.wNumbering) { wc.nParaNumOffset = wc.nFirstMargin; - dxStartIndent = max( ME_twips2pointsX(c, pFmt->wNumberingTab), - tp->member.para.para_num.width ); + dxStartIndent = max( ME_twips2pointsX(c, para->fmt.wNumberingTab), + para->para_num.width ); wc.nFirstMargin += dxStartIndent; } - wc.nRightMargin = ME_twips2pointsX(c, pFmt->dxRightIndent); + wc.nRightMargin = ME_twips2pointsX( c, para->fmt.dxRightIndent ); - if (wc.nFirstMargin < 0) - wc.nFirstMargin = 0; - if (wc.nLeftMargin < 0) - wc.nLeftMargin = 0; + if (wc.nFirstMargin < 0) wc.nFirstMargin = 0; + if (wc.nLeftMargin < 0) wc.nLeftMargin = 0; } if (c->editor->bEmulateVersion10 && /* v1.0 - 3.0 */ - pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE) + para->fmt.dwMask & PFM_TABLE && para->fmt.wEffects & PFE_TABLE) { - wc.nFirstMargin += ME_twips2pointsX(c, pFmt->dxOffset * 2); + wc.nFirstMargin += ME_twips2pointsX( c, para->fmt.dxOffset * 2 ); } wc.nRow = 0; wc.pt.y = 0; - if (pFmt->dwMask & PFM_SPACEBEFORE) - wc.pt.y += ME_twips2pointsY(c, pFmt->dySpaceBefore); - if (!(pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE) && - pFmt->dwMask & PFM_BORDER) + if (para->fmt.dwMask & PFM_SPACEBEFORE) + wc.pt.y += ME_twips2pointsY( c, para->fmt.dySpaceBefore ); + if (!(para->fmt.dwMask & PFM_TABLE && para->fmt.wEffects & PFE_TABLE) && + para->fmt.dwMask & PFM_BORDER) { - border = ME_GetParaBorderWidth(c, tp->member.para.fmt.wBorders); - if (pFmt->wBorders & 1) { + border = ME_GetParaBorderWidth( c, para->fmt.wBorders ); + if (para->fmt.wBorders & 1) + { wc.nFirstMargin += border; wc.nLeftMargin += border; } - if (pFmt->wBorders & 2) - wc.nRightMargin -= border; - if (pFmt->wBorders & 4) - wc.pt.y += border; + if (para->fmt.wBorders & 2) wc.nRightMargin -= border; + if (para->fmt.wBorders & 4) wc.pt.y += border; } - linespace = ME_GetParaLineSpace(c, &tp->member.para); + linespace = ME_GetParaLineSpace( c, para ); - ME_BeginRow(&wc); - for (p = tp->next; p!=tp->member.para.next_para; ) { - assert(p->type != diStartRow); - if (p->type == diRun) { - p = ME_WrapHandleRun(&wc, p); - } - else p = p->next; - if (wc.nRow && p == wc.pRowStart) - wc.pt.y += linespace; + ME_BeginRow( &wc ); + run = para_first_run( para ); + while (run) + { + run = ME_WrapHandleRun( &wc, run ); + if (wc.nRow && run == wc.pRowStart) wc.pt.y += linespace; } - ME_WrapEndParagraph(&wc, p); - if (!(pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE) && - (pFmt->dwMask & PFM_BORDER) && (pFmt->wBorders & 8)) + ME_WrapEndParagraph( &wc ); + if (!(para->fmt.dwMask & PFM_TABLE && para->fmt.wEffects & PFE_TABLE) && + (para->fmt.dwMask & PFM_BORDER) && (para->fmt.wBorders & 8)) wc.pt.y += border; - if (tp->member.para.fmt.dwMask & PFM_SPACEAFTER) - wc.pt.y += ME_twips2pointsY(c, pFmt->dySpaceAfter); + if (para->fmt.dwMask & PFM_SPACEAFTER) + wc.pt.y += ME_twips2pointsY( c, para->fmt.dySpaceAfter ); - tp->member.para.nFlags &= ~MEPF_REWRAP; - tp->member.para.nHeight = wc.pt.y; - tp->member.para.nRows = wc.nRow; + para->nFlags &= ~MEPF_REWRAP; + para->nHeight = wc.pt.y; + para->nRows = wc.nRow; editor->total_rows += wc.nRow; } -static void ME_MarkRepaintEnd(ME_DisplayItem *para, - ME_DisplayItem **repaint_start, - ME_DisplayItem **repaint_end) +struct repaint_range +{ + ME_Paragraph *start, *end; +}; + +static void update_repaint( ME_Paragraph *para, struct repaint_range *repaint ) { - if (!*repaint_start) - *repaint_start = para; - *repaint_end = para; + if (!repaint->start) repaint->start = para; + repaint->end = para; } -static void adjust_para_y(ME_DisplayItem *item, ME_Context *c, ME_DisplayItem *repaint_start, ME_DisplayItem *repaint_end) +static void adjust_para_y( ME_Paragraph *para, ME_Context *c, struct repaint_range *repaint ) { - if (item->member.para.nFlags & MEPF_ROWSTART) + ME_Cell *cell; + + if (para->nFlags & MEPF_ROWSTART) { - ME_DisplayItem *cell = ME_FindItemFwd(item, diCell); - ME_DisplayItem *endRowPara; + ME_Paragraph *end_row_para = table_row_end( para ); int borderWidth = 0; - cell->member.cell.pt = c->pt; + + cell = table_row_first_cell( para ); + cell->pt = c->pt; /* Offset the text by the largest top border width. */ - while (cell->member.cell.next_cell) + while (cell_next( cell )) { - borderWidth = max(borderWidth, cell->member.cell.border.top.width); - cell = cell->member.cell.next_cell; + borderWidth = max( borderWidth, cell->border.top.width ); + cell = cell_next( cell ); } - endRowPara = ME_FindItemFwd(cell, diParagraph); - assert(endRowPara->member.para.nFlags & MEPF_ROWEND); if (borderWidth > 0) { borderWidth = max(ME_twips2pointsY(c, borderWidth), 1); while (cell) { - cell->member.cell.yTextOffset = borderWidth; - cell = cell->member.cell.prev_cell; + cell->yTextOffset = borderWidth; + cell = cell_prev( cell ); } c->pt.y += borderWidth; } - if (endRowPara->member.para.fmt.dxStartIndent > 0) + if (end_row_para->fmt.dxStartIndent > 0) { - int dxStartIndent = endRowPara->member.para.fmt.dxStartIndent; - cell = ME_FindItemFwd(item, diCell); - cell->member.cell.pt.x += ME_twips2pointsX(c, dxStartIndent); - c->pt.x = cell->member.cell.pt.x; + cell = table_row_first_cell( para ); + cell->pt.x += ME_twips2pointsX( c, end_row_para->fmt.dxStartIndent ); + c->pt.x = cell->pt.x; } } - else if (item->member.para.nFlags & MEPF_ROWEND) + else if (para->nFlags & MEPF_ROWEND) { /* Set all the cells to the height of the largest cell */ - ME_DisplayItem *startRowPara; + ME_Paragraph *start_row_para = table_row_start( para ); int prevHeight, nHeight, bottomBorder = 0; - ME_DisplayItem *cell = ME_FindItemBack(item, diCell); - item->member.para.nWidth = cell->member.cell.pt.x + cell->member.cell.nWidth; - if (!(item->member.para.next_para->member.para.nFlags & MEPF_ROWSTART)) + + cell = table_row_end_cell( para ); + para->nWidth = cell->pt.x + cell->nWidth; + if (!(para_next( para )->nFlags & MEPF_ROWSTART)) { /* Last row, the bottom border is added to the height. */ - cell = cell->member.cell.prev_cell; - while (cell) - { - bottomBorder = max(bottomBorder, cell->member.cell.border.bottom.width); - cell = cell->member.cell.prev_cell; - } + while ((cell = cell_prev( cell ))) + bottomBorder = max( bottomBorder, cell->border.bottom.width ); + bottomBorder = ME_twips2pointsY(c, bottomBorder); - cell = ME_FindItemBack(item, diCell); + cell = table_row_end_cell( para ); } - prevHeight = cell->member.cell.nHeight; - nHeight = cell->member.cell.prev_cell->member.cell.nHeight + bottomBorder; - cell->member.cell.nHeight = nHeight; - item->member.para.nHeight = nHeight; - cell = cell->member.cell.prev_cell; - cell->member.cell.nHeight = nHeight; - while (cell->member.cell.prev_cell) + prevHeight = cell->nHeight; + nHeight = cell_prev( cell )->nHeight + bottomBorder; + cell->nHeight = nHeight; + para->nHeight = nHeight; + while (cell_prev( cell )) { - cell = cell->member.cell.prev_cell; - cell->member.cell.nHeight = nHeight; + cell = cell_prev( cell ); + cell->nHeight = nHeight; } + /* Also set the height of the start row paragraph */ - startRowPara = ME_FindItemBack(cell, diParagraph); - startRowPara->member.para.nHeight = nHeight; - c->pt.x = startRowPara->member.para.pt.x; - c->pt.y = cell->member.cell.pt.y + nHeight; + start_row_para->nHeight = nHeight; + c->pt.x = start_row_para->pt.x; + c->pt.y = cell->pt.y + nHeight; if (prevHeight < nHeight) { /* The height of the cells has grown, so invalidate the bottom of * the cells. */ - ME_MarkRepaintEnd(item, &repaint_start, &repaint_end); - cell = ME_FindItemBack(item, diCell); + update_repaint( para, repaint ); + cell = cell_prev( table_row_end_cell( para ) ); while (cell) { - ME_MarkRepaintEnd(ME_FindItemBack(cell, diParagraph), &repaint_start, &repaint_end); - cell = cell->member.cell.prev_cell; + update_repaint( cell_end_para( cell ), repaint ); + cell = cell_prev( cell ); } } } - else if (item->member.para.pCell && - item->member.para.pCell != item->member.para.next_para->member.para.pCell) + else if ((cell = para_cell( para )) && para == cell_end_para( cell )) { /* The next paragraph is in the next cell in the table row. */ - ME_Cell *cell = &item->member.para.pCell->member.cell; - cell->nHeight = c->pt.y + item->member.para.nHeight - cell->pt.y; + cell->nHeight = c->pt.y + para->nHeight - cell->pt.y; /* Propagate the largest height to the end so that it can be easily * sent back to all the cells at the end of the row. */ - if (cell->prev_cell) - cell->nHeight = max(cell->nHeight, cell->prev_cell->member.cell.nHeight); + if (cell_prev( cell )) + cell->nHeight = max( cell->nHeight, cell_prev( cell )->nHeight ); c->pt.x = cell->pt.x + cell->nWidth; c->pt.y = cell->pt.y; - cell->next_cell->member.cell.pt = c->pt; - if (!(item->member.para.next_para->member.para.nFlags & MEPF_ROWEND)) + cell_next( cell )->pt = c->pt; + if (!(para_next( para )->nFlags & MEPF_ROWEND)) c->pt.y += cell->yTextOffset; } else { - if (item->member.para.pCell) - { - /* Next paragraph in the same cell. */ - c->pt.x = item->member.para.pCell->member.cell.pt.x; - } - else - /* Normal paragraph */ + if ((cell = para_cell( para ))) /* Next paragraph in the same cell. */ + c->pt.x = cell->pt.x; + else /* Normal paragraph */ c->pt.x = 0; - c->pt.y += item->member.para.nHeight; + c->pt.y += para->nHeight; } } -BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) +BOOL wrap_marked_paras_dc( ME_TextEditor *editor, HDC hdc, BOOL invalidate ) { - ME_DisplayItem *item; + ME_Paragraph *para, *next; + struct wine_rb_entry *entry, *next_entry = NULL; ME_Context c; - int totalWidth = editor->nTotalWidth, diff = 0, prev_width; - ME_DisplayItem *repaint_start = NULL, *repaint_end = NULL; - ME_Paragraph *para; + int totalWidth = editor->nTotalWidth, prev_width; + struct repaint_range repaint = { NULL, NULL }; - if (!editor->first_marked_para) - return FALSE; + if (!editor->marked_paras.root) return FALSE; - ME_InitContext(&c, editor, ITextHost_TxGetDC(editor->texthost)); + ME_InitContext( &c, editor, hdc ); - item = editor->first_marked_para; - c.pt = item->member.para.pt; - while (item != editor->pBuffer->pLast) + entry = wine_rb_head( editor->marked_paras.root ); + while (entry) { - assert(item->type == diParagraph); + para = WINE_RB_ENTRY_VALUE( entry, ME_Paragraph, marked_entry ); + + /* If the first entry lies inside a table, go back to the start + of the table to ensure cell heights are kept in sync. */ + if (!next_entry && para_in_table( para ) && para != table_outer_para( para )) + { + para = table_outer_para( para ); + next_entry = entry; + } + else + next_entry = wine_rb_next( entry ); - prev_width = item->member.para.nWidth; - ME_WrapTextParagraph(editor, &c, item); - if (prev_width == totalWidth && item->member.para.nWidth < totalWidth) + c.pt = para->pt; + prev_width = para->nWidth; + ME_WrapTextParagraph( editor, &c, para ); + if (prev_width == totalWidth && para->nWidth < totalWidth) totalWidth = get_total_width(editor); else - totalWidth = max(totalWidth, item->member.para.nWidth); + totalWidth = max(totalWidth, para->nWidth); - if (!item->member.para.nCharOfs) - ME_MarkRepaintEnd(item->member.para.prev_para, &repaint_start, &repaint_end); - ME_MarkRepaintEnd(item, &repaint_start, &repaint_end); - adjust_para_y(item, &c, repaint_start, repaint_end); + update_repaint( para, &repaint ); + adjust_para_y( para, &c, &repaint ); - if (item->member.para.next_para) + if (para_next( para )) { - diff = c.pt.y - item->member.para.next_para->member.para.pt.y; - if (diff) + if (c.pt.x != para_next( para )->pt.x || c.pt.y != para_next( para )->pt.y || + para_in_table( para )) { - para = &item->member.para; - while (para->next_para && para != &item->member.para.next_marked->member.para && - para != &editor->pBuffer->pLast->member.para) + next = para; + while (para_next( next ) && &next->marked_entry != next_entry && + next != &editor->pBuffer->pLast->member.para) { - ME_MarkRepaintEnd(para->next_para, &repaint_start, &repaint_end); - para->next_para->member.para.pt.y = c.pt.y; - adjust_para_y(para->next_para, &c, repaint_start, repaint_end); - para = ¶->next_para->member.para; + update_repaint( para_next( next ), &repaint ); + para_next( next )->pt = c.pt; + adjust_para_y( para_next( next ), &c, &repaint ); + next = para_next( next ); } } } - if (item->member.para.next_marked) - { - ME_DisplayItem *rem = item; - item = item->member.para.next_marked; - remove_marked_para(editor, rem); - } - else - { - remove_marked_para(editor, item); - item = editor->pBuffer->pLast; - } - c.pt.y = item->member.para.pt.y; + entry = next_entry; } + wine_rb_clear( &editor->marked_paras, NULL, NULL ); + editor->sizeWindow.cx = c.rcView.right-c.rcView.left; editor->sizeWindow.cy = c.rcView.bottom-c.rcView.top; - editor->nTotalLength = c.pt.y; + editor->nTotalLength = editor->pBuffer->pLast->member.para.pt.y; editor->nTotalWidth = totalWidth; - editor->pBuffer->pLast->member.para.pt.x = 0; - editor->pBuffer->pLast->member.para.pt.y = c.pt.y; ME_DestroyContext(&c); - if (repaint_start || editor->nTotalLength < editor->nLastTotalLength) - ME_InvalidateParagraphRange(editor, repaint_start, repaint_end); - return !!repaint_start; + if (invalidate && (repaint.start || editor->nTotalLength < editor->nLastTotalLength)) + para_range_invalidate( editor, repaint.start, repaint.end); + return !!repaint.start; } -void ME_InvalidateParagraphRange(ME_TextEditor *editor, - ME_DisplayItem *start_para, - ME_DisplayItem *last_para) +BOOL ME_WrapMarkedParagraphs( ME_TextEditor *editor ) +{ + HDC hdc = ITextHost_TxGetDC( editor->texthost ); + BOOL ret = wrap_marked_paras_dc( editor, hdc, TRUE ); + ITextHost_TxReleaseDC( editor->texthost, hdc ); + return ret; +} + +void para_range_invalidate( ME_TextEditor *editor, ME_Paragraph *start_para, + ME_Paragraph *last_para ) { - ME_Context c; RECT rc; int ofs; - ME_InitContext(&c, editor, ITextHost_TxGetDC(editor->texthost)); - rc = c.rcView; + rc = editor->rcFormat; ofs = editor->vert_si.nPos; - if (start_para) { - start_para = ME_GetOuterParagraph(start_para); - last_para = ME_GetOuterParagraph(last_para); - rc.top = c.rcView.top + start_para->member.para.pt.y - ofs; + if (start_para) + { + start_para = table_outer_para( start_para ); + last_para = table_outer_para( last_para ); + rc.top += start_para->pt.y - ofs; } else { - rc.top = c.rcView.top + editor->nTotalLength - ofs; + rc.top += editor->nTotalLength - ofs; } if (editor->nTotalLength < editor->nLastTotalLength) - rc.bottom = c.rcView.top + editor->nLastTotalLength - ofs; + rc.bottom = editor->rcFormat.top + editor->nLastTotalLength - ofs; else - rc.bottom = c.rcView.top + last_para->member.para.pt.y + last_para->member.para.nHeight - ofs; + rc.bottom = editor->rcFormat.top + last_para->pt.y + last_para->nHeight - ofs; ITextHost_TxInvalidateRect(editor->texthost, &rc, TRUE); - - ME_DestroyContext(&c); } diff --git a/dll/win32/riched20/writer.c b/dll/win32/riched20/writer.c index 94001ee44b280..7c7e648f107de 100644 --- a/dll/win32/riched20/writer.c +++ b/dll/win32/riched20/writer.c @@ -311,50 +311,46 @@ static BOOL find_color_in_colortbl( ME_OutStream *stream, COLORREF color, unsign return i < stream->nFontTblLen; } -static BOOL -ME_StreamOutRTFFontAndColorTbl(ME_OutStream *pStream, ME_DisplayItem *pFirstRun, - ME_DisplayItem *pLastRun) +static BOOL stream_out_font_and_colour_tbls( ME_OutStream *pStream, ME_Run *first, ME_Run *last ) { - ME_DisplayItem *item = pFirstRun; + ME_Run *run = first; ME_FontTableItem *table = pStream->fonttbl; unsigned int i; - ME_DisplayItem *pCell = NULL; + ME_Cell *cell = NULL; ME_Paragraph *prev_para = NULL; - do { - CHARFORMAT2W *fmt = &item->member.run.style->fmt; + do + { + CHARFORMAT2W *fmt = &run->style->fmt; - add_font_to_fonttbl( pStream, item->member.run.style ); + add_font_to_fonttbl( pStream, run->style ); if (fmt->dwMask & CFM_COLOR && !(fmt->dwEffects & CFE_AUTOCOLOR)) add_color_to_colortbl( pStream, fmt->crTextColor ); if (fmt->dwMask & CFM_BACKCOLOR && !(fmt->dwEffects & CFE_AUTOBACKCOLOR)) add_color_to_colortbl( pStream, fmt->crBackColor ); - if (item->member.run.para != prev_para) + if (run->para != prev_para) { /* check for any para numbering text */ - if (item->member.run.para->fmt.wNumbering) - add_font_to_fonttbl( pStream, item->member.run.para->para_num.style ); + if (run->para->fmt.wNumbering) + add_font_to_fonttbl( pStream, run->para->para_num.style ); - if ((pCell = item->member.para.pCell)) + if ((cell = para_cell( run->para ))) { - ME_Border* borders[4] = { &pCell->member.cell.border.top, - &pCell->member.cell.border.left, - &pCell->member.cell.border.bottom, - &pCell->member.cell.border.right }; + ME_Border* borders[4] = { &cell->border.top, &cell->border.left, + &cell->border.bottom, &cell->border.right }; for (i = 0; i < 4; i++) if (borders[i]->width > 0) add_color_to_colortbl( pStream, borders[i]->colorRef ); } - prev_para = item->member.run.para; + prev_para = run->para; } - if (item == pLastRun) - break; - item = ME_FindItemFwd(item, diRun); - } while (item); + if (run == last) break; + run = run_next_all_paras( run ); + } while (run); if (!ME_StreamOutPrint(pStream, "{\\fonttbl")) return FALSE; @@ -388,31 +384,29 @@ ME_StreamOutRTFFontAndColorTbl(ME_OutStream *pStream, ME_DisplayItem *pFirstRun, return TRUE; } -static BOOL -ME_StreamOutRTFTableProps(ME_TextEditor *editor, ME_OutStream *pStream, - ME_DisplayItem *para) +static BOOL stream_out_table_props( ME_TextEditor *editor, ME_OutStream *pStream, + ME_Paragraph *para ) { - ME_DisplayItem *cell; + ME_Cell *cell; char props[STREAMOUT_BUFFER_SIZE] = ""; int i; const char sideChar[4] = {'t','l','b','r'}; if (!ME_StreamOutPrint(pStream, "\\trowd")) return FALSE; - if (!editor->bEmulateVersion10) { /* v4.1 */ - PARAFORMAT2 *pFmt = &ME_GetTableRowEnd(para)->member.para.fmt; - para = ME_GetTableRowStart(para); - cell = para->member.para.next_para->member.para.pCell; - assert(cell); + if (!editor->bEmulateVersion10) /* v4.1 */ + { + PARAFORMAT2 *pFmt = &table_row_end( para )->fmt; + cell = table_row_first_cell( para ); + assert( cell ); if (pFmt->dxOffset) sprintf(props + strlen(props), "\\trgaph%d", pFmt->dxOffset); if (pFmt->dxStartIndent) sprintf(props + strlen(props), "\\trleft%d", pFmt->dxStartIndent); - do { - ME_Border* borders[4] = { &cell->member.cell.border.top, - &cell->member.cell.border.left, - &cell->member.cell.border.bottom, - &cell->member.cell.border.right }; + do + { + ME_Border* borders[4] = { &cell->border.top, &cell->border.left, + &cell->border.bottom, &cell->border.right }; for (i = 0; i < 4; i++) { if (borders[i]->width) @@ -426,17 +420,19 @@ ME_StreamOutRTFTableProps(ME_TextEditor *editor, ME_OutStream *pStream, sprintf(props + strlen(props), "\\brdrcf%u", idx); } } - sprintf(props + strlen(props), "\\cellx%d", cell->member.cell.nRightBoundary); - cell = cell->member.cell.next_cell; - } while (cell->member.cell.next_cell); - } else { /* v1.0 - 3.0 */ - const ME_Border* borders[4] = { ¶->member.para.border.top, - ¶->member.para.border.left, - ¶->member.para.border.bottom, - ¶->member.para.border.right }; - PARAFORMAT2 *pFmt = ¶->member.para.fmt; - - assert(!(para->member.para.nFlags & (MEPF_ROWSTART|MEPF_ROWEND|MEPF_CELL))); + sprintf( props + strlen(props), "\\cellx%d", cell->nRightBoundary ); + cell = cell_next( cell ); + } while (cell_next( cell )); + } + else /* v1.0 - 3.0 */ + { + const ME_Border* borders[4] = { ¶->border.top, + ¶->border.left, + ¶->border.bottom, + ¶->border.right }; + PARAFORMAT2 *pFmt = ¶->fmt; + + assert( !(para->nFlags & (MEPF_ROWSTART | MEPF_ROWEND | MEPF_CELL)) ); if (pFmt->dxOffset) sprintf(props + strlen(props), "\\trgaph%d", pFmt->dxOffset); if (pFmt->dxStartIndent) @@ -535,54 +531,46 @@ static BOOL stream_out_para_num( ME_OutStream *stream, ME_Paragraph *para, BOOL return TRUE; } -static BOOL -ME_StreamOutRTFParaProps(ME_TextEditor *editor, ME_OutStream *pStream, - ME_DisplayItem *para) +static BOOL stream_out_para_props( ME_TextEditor *editor, ME_OutStream *pStream, + ME_Paragraph *para ) { - PARAFORMAT2 *fmt = ¶->member.para.fmt; + PARAFORMAT2 *fmt = ¶->fmt; char props[STREAMOUT_BUFFER_SIZE] = ""; int i; - ME_Paragraph *prev_para = NULL; - - if (para->member.para.prev_para->type == diParagraph) - prev_para = ¶->member.para.prev_para->member.para; + ME_Paragraph *prev_para = para_prev( para ); - if (!editor->bEmulateVersion10) { /* v4.1 */ - if (para->member.para.nFlags & MEPF_ROWSTART) { + if (!editor->bEmulateVersion10) /* v4.1 */ + { + if (para->nFlags & MEPF_ROWSTART) + { pStream->nNestingLevel++; - if (pStream->nNestingLevel == 1) { - if (!ME_StreamOutRTFTableProps(editor, pStream, para)) - return FALSE; - } + if (pStream->nNestingLevel == 1) + if (!stream_out_table_props( editor, pStream, para )) return FALSE; return TRUE; - } else if (para->member.para.nFlags & MEPF_ROWEND) { + } + else if (para->nFlags & MEPF_ROWEND) + { pStream->nNestingLevel--; - if (pStream->nNestingLevel >= 1) { - if (!ME_StreamOutPrint(pStream, "{\\*\\nesttableprops")) - return FALSE; - if (!ME_StreamOutRTFTableProps(editor, pStream, para)) - return FALSE; - if (!ME_StreamOutPrint(pStream, "\\nestrow}{\\nonesttables\\par}\r\n")) - return FALSE; - } else { - if (!ME_StreamOutPrint(pStream, "\\row\r\n")) - return FALSE; + if (pStream->nNestingLevel >= 1) + { + if (!ME_StreamOutPrint(pStream, "{\\*\\nesttableprops")) return FALSE; + if (!stream_out_table_props( editor, pStream, para )) return FALSE; + if (!ME_StreamOutPrint(pStream, "\\nestrow}{\\nonesttables\\par}\r\n")) return FALSE; } + else if (!ME_StreamOutPrint(pStream, "\\row\r\n")) return FALSE; return TRUE; } - } else { /* v1.0 - 3.0 */ - if (para->member.para.fmt.dwMask & PFM_TABLE && - para->member.para.fmt.wEffects & PFE_TABLE) - { - if (!ME_StreamOutRTFTableProps(editor, pStream, para)) - return FALSE; - } + } + else /* v1.0 - 3.0 */ + { + if (para->fmt.dwMask & PFM_TABLE && para->fmt.wEffects & PFE_TABLE) + if (!stream_out_table_props( editor, pStream, para )) return FALSE; } if (prev_para && !memcmp( fmt, &prev_para->fmt, sizeof(*fmt) )) { if (fmt->wNumbering) - return stream_out_para_num( pStream, ¶->member.para, FALSE ); + return stream_out_para_num( pStream, para, FALSE ); return TRUE; } @@ -590,14 +578,15 @@ ME_StreamOutRTFParaProps(ME_TextEditor *editor, ME_OutStream *pStream, return FALSE; if (fmt->wNumbering) - if (!stream_out_para_num( pStream, ¶->member.para, TRUE )) return FALSE; + if (!stream_out_para_num( pStream, para, TRUE )) return FALSE; - if (!editor->bEmulateVersion10) { /* v4.1 */ - if (pStream->nNestingLevel > 0) - strcat(props, "\\intbl"); - if (pStream->nNestingLevel > 1) - sprintf(props + strlen(props), "\\itap%d", pStream->nNestingLevel); - } else { /* v1.0 - 3.0 */ + if (!editor->bEmulateVersion10) /* v4.1 */ + { + if (pStream->nNestingLevel > 0) strcat(props, "\\intbl"); + if (pStream->nNestingLevel > 1) sprintf(props + strlen(props), "\\itap%d", pStream->nNestingLevel); + } + else /* v1.0 - 3.0 */ + { if (fmt->dwMask & PFM_TABLE && fmt->wEffects & PFE_TABLE) strcat(props, "\\intbl"); } @@ -607,8 +596,10 @@ ME_StreamOutRTFParaProps(ME_TextEditor *editor, ME_OutStream *pStream, * set very different from the documentation. * (Tested with RichEdit 5.50.25.0601) */ - if (fmt->dwMask & PFM_ALIGNMENT) { - switch (fmt->wAlignment) { + if (fmt->dwMask & PFM_ALIGNMENT) + { + switch (fmt->wAlignment) + { case PFA_LEFT: /* Default alignment: not emitted */ break; @@ -624,10 +615,12 @@ ME_StreamOutRTFParaProps(ME_TextEditor *editor, ME_OutStream *pStream, } } - if (fmt->dwMask & PFM_LINESPACING) { + if (fmt->dwMask & PFM_LINESPACING) + { /* FIXME: MSDN says that the bLineSpacingRule field is controlled by the * PFM_SPACEAFTER flag. Is that true? I don't believe so. */ - switch (fmt->bLineSpacingRule) { + switch (fmt->bLineSpacingRule) + { case 0: /* Single spacing */ strcat(props, "\\sl-240\\slmult1"); break; @@ -678,8 +671,10 @@ ME_StreamOutRTFParaProps(ME_TextEditor *editor, ME_OutStream *pStream, if (fmt->dwMask & PFM_TABSTOPS) { static const char * const leader[6] = { "", "\\tldot", "\\tlhyph", "\\tlul", "\\tlth", "\\tleq" }; - for (i = 0; i < fmt->cTabCount; i++) { - switch ((fmt->rgxTabs[i] >> 24) & 0xF) { + for (i = 0; i < fmt->cTabCount; i++) + { + switch ((fmt->rgxTabs[i] >> 24) & 0xf) + { case 1: strcat(props, "\\tqc"); break; @@ -706,7 +701,8 @@ ME_StreamOutRTFParaProps(ME_TextEditor *editor, ME_OutStream *pStream, if (fmt->sStyle != -1) sprintf(props + strlen(props), "\\s%d", fmt->sStyle); - if (fmt->dwMask & PFM_SHADING) { + if (fmt->dwMask & PFM_SHADING) + { static const char * const style[16] = { "", "\\bgdkhoriz", "\\bgdkvert", "\\bgdkfdiag", "\\bgdkbdiag", "\\bgdkcross", "\\bgdkdcross", "\\bghoriz", "\\bgvert", "\\bgfdiag", @@ -943,11 +939,13 @@ static BOOL stream_out_graphics( ME_TextEditor *editor, ME_OutStream *stream, UINT size; SIZE goal, pic; ME_Context c; + HDC hdc; hr = IOleObject_QueryInterface( run->reobj->obj.poleobj, &IID_IDataObject, (void **)&data ); if (FAILED(hr)) return FALSE; - ME_InitContext( &c, editor, ITextHost_TxGetDC( editor->texthost ) ); + hdc = ITextHost_TxGetDC( editor->texthost ); + ME_InitContext( &c, editor, hdc ); hr = IDataObject_QueryGetData( data, &fmt ); if (hr != S_OK) goto done; @@ -989,6 +987,7 @@ static BOOL stream_out_graphics( ME_TextEditor *editor, ME_OutStream *stream, done: ME_DestroyContext( &c ); + ITextHost_TxReleaseDC( editor->texthost, hdc ); HeapFree( GetProcessHeap(), 0, emf_bits ); ReleaseStgMedium( &med ); IDataObject_Release( data ); @@ -999,7 +998,7 @@ static BOOL ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream, const ME_Cursor *start, int nChars, int dwFormat) { ME_Cursor cursor = *start; - ME_DisplayItem *prev_para = NULL; + ME_Paragraph *prev_para = NULL; ME_Cursor endCur = cursor; ME_MoveCursorChars(editor, &endCur, nChars, TRUE); @@ -1007,7 +1006,7 @@ static BOOL ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream, if (!ME_StreamOutRTFHeader(pStream, dwFormat)) return FALSE; - if (!ME_StreamOutRTFFontAndColorTbl(pStream, cursor.pRun, endCur.pRun)) + if (!stream_out_font_and_colour_tbls( pStream, cursor.run, endCur.run )) return FALSE; /* TODO: stylesheet table */ @@ -1023,77 +1022,95 @@ static BOOL ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream, /* TODO: section formatting properties */ - do { - if (cursor.pPara != prev_para) + do + { + if (cursor.para != prev_para) { - prev_para = cursor.pPara; - if (!ME_StreamOutRTFParaProps(editor, pStream, cursor.pPara)) + prev_para = cursor.para; + if (!stream_out_para_props( editor, pStream, cursor.para )) return FALSE; } - if (cursor.pRun == endCur.pRun && !endCur.nOffset) + if (cursor.run == endCur.run && !endCur.nOffset) break; - TRACE("flags %xh\n", cursor.pRun->member.run.nFlags); + + TRACE("flags %xh\n", cursor.run->nFlags); /* TODO: emit embedded objects */ - if (cursor.pPara->member.para.nFlags & (MEPF_ROWSTART|MEPF_ROWEND)) + if (cursor.para->nFlags & (MEPF_ROWSTART | MEPF_ROWEND)) continue; - if (cursor.pRun->member.run.nFlags & MERF_GRAPHICS) { - if (!stream_out_graphics(editor, pStream, &cursor.pRun->member.run)) + if (cursor.run->nFlags & MERF_GRAPHICS) + { + if (!stream_out_graphics( editor, pStream, cursor.run )) return FALSE; - } else if (cursor.pRun->member.run.nFlags & MERF_TAB) { + } + else if (cursor.run->nFlags & MERF_TAB) + { if (editor->bEmulateVersion10 && /* v1.0 - 3.0 */ - cursor.pPara->member.para.fmt.dwMask & PFM_TABLE && - cursor.pPara->member.para.fmt.wEffects & PFE_TABLE) + para_in_table( cursor.para )) { if (!ME_StreamOutPrint(pStream, "\\cell ")) return FALSE; - } else { + } + else + { if (!ME_StreamOutPrint(pStream, "\\tab ")) return FALSE; } - } else if (cursor.pRun->member.run.nFlags & MERF_ENDCELL) { - if (pStream->nNestingLevel > 1) { + } + else if (cursor.run->nFlags & MERF_ENDCELL) + { + if (pStream->nNestingLevel > 1) + { if (!ME_StreamOutPrint(pStream, "\\nestcell ")) return FALSE; - } else { + } + else + { if (!ME_StreamOutPrint(pStream, "\\cell ")) return FALSE; } nChars--; - } else if (cursor.pRun->member.run.nFlags & MERF_ENDPARA) { - if (!ME_StreamOutRTFCharProps(pStream, &cursor.pRun->member.run.style->fmt)) + } + else if (cursor.run->nFlags & MERF_ENDPARA) + { + if (!ME_StreamOutRTFCharProps( pStream, &cursor.run->style->fmt )) return FALSE; - if (cursor.pPara->member.para.fmt.dwMask & PFM_TABLE && - cursor.pPara->member.para.fmt.wEffects & PFE_TABLE && - !(cursor.pPara->member.para.nFlags & (MEPF_ROWSTART|MEPF_ROWEND|MEPF_CELL))) + if (para_in_table( cursor.para ) && + !(cursor.para->nFlags & (MEPF_ROWSTART | MEPF_ROWEND | MEPF_CELL))) { if (!ME_StreamOutPrint(pStream, "\\row\r\n")) return FALSE; - } else { + } + else + { if (!ME_StreamOutPrint(pStream, "\\par\r\n")) return FALSE; } /* Skip as many characters as required by current line break */ - nChars = max(0, nChars - cursor.pRun->member.run.len); - } else if (cursor.pRun->member.run.nFlags & MERF_ENDROW) { + nChars = max(0, nChars - cursor.run->len); + } + else if (cursor.run->nFlags & MERF_ENDROW) + { if (!ME_StreamOutPrint(pStream, "\\line\r\n")) return FALSE; nChars--; - } else { + } + else + { int nEnd; - TRACE("style %p\n", cursor.pRun->member.run.style); - if (!ME_StreamOutRTFCharProps(pStream, &cursor.pRun->member.run.style->fmt)) + TRACE("style %p\n", cursor.run->style); + if (!ME_StreamOutRTFCharProps( pStream, &cursor.run->style->fmt )) return FALSE; - nEnd = (cursor.pRun == endCur.pRun) ? endCur.nOffset : cursor.pRun->member.run.len; - if (!ME_StreamOutRTFText(pStream, get_text( &cursor.pRun->member.run, cursor.nOffset ), + nEnd = (cursor.run == endCur.run) ? endCur.nOffset : cursor.run->len; + if (!ME_StreamOutRTFText(pStream, get_text( cursor.run, cursor.nOffset ), nEnd - cursor.nOffset)) return FALSE; cursor.nOffset = 0; } - } while (cursor.pRun != endCur.pRun && ME_NextRun(&cursor.pPara, &cursor.pRun, TRUE)); + } while (cursor.run != endCur.run && cursor_next_run( &cursor, TRUE )); if (!ME_StreamOutMove(pStream, "}\0", 2)) return FALSE; @@ -1111,7 +1128,7 @@ static BOOL ME_StreamOutText(ME_TextEditor *editor, ME_OutStream *pStream, int nBufLen = 0; BOOL success = TRUE; - if (!cursor.pRun) + if (!cursor.run) return FALSE; if (dwFormat & SF_USECODEPAGE) @@ -1119,32 +1136,31 @@ static BOOL ME_StreamOutText(ME_TextEditor *editor, ME_OutStream *pStream, /* TODO: Handle SF_TEXTIZED */ - while (success && nChars && cursor.pRun) { - nLen = min(nChars, cursor.pRun->member.run.len - cursor.nOffset); + while (success && nChars && cursor.run) + { + nLen = min(nChars, cursor.run->len - cursor.nOffset); - if (!editor->bEmulateVersion10 && cursor.pRun->member.run.nFlags & MERF_ENDPARA) + if (!editor->bEmulateVersion10 && cursor.run->nFlags & MERF_ENDPARA) { - static const WCHAR szEOL[] = { '\r', '\n' }; - /* richedit 2.0 - all line breaks are \r\n */ if (dwFormat & SF_UNICODE) - success = ME_StreamOutMove(pStream, (const char *)szEOL, sizeof(szEOL)); + success = ME_StreamOutMove(pStream, (const char *)L"\r\n", 2 * sizeof(WCHAR)); else success = ME_StreamOutMove(pStream, "\r\n", 2); } else { if (dwFormat & SF_UNICODE) - success = ME_StreamOutMove(pStream, (const char *)(get_text( &cursor.pRun->member.run, cursor.nOffset )), + success = ME_StreamOutMove(pStream, (const char *)(get_text( cursor.run, cursor.nOffset )), sizeof(WCHAR) * nLen); else { int nSize; - nSize = WideCharToMultiByte(nCodePage, 0, get_text( &cursor.pRun->member.run, cursor.nOffset ), + nSize = WideCharToMultiByte(nCodePage, 0, get_text( cursor.run, cursor.nOffset ), nLen, NULL, 0, NULL, NULL); if (nSize > nBufLen) { buffer = heap_realloc(buffer, nSize); nBufLen = nSize; } - WideCharToMultiByte(nCodePage, 0, get_text( &cursor.pRun->member.run, cursor.nOffset ), + WideCharToMultiByte(nCodePage, 0, get_text( cursor.run, cursor.nOffset ), nLen, buffer, nSize, NULL, NULL); success = ME_StreamOutMove(pStream, buffer, nSize); } @@ -1152,7 +1168,7 @@ static BOOL ME_StreamOutText(ME_TextEditor *editor, ME_OutStream *pStream, nChars -= nLen; cursor.nOffset = 0; - cursor.pRun = ME_FindItemFwd(cursor.pRun, diRun); + cursor.run = run_next_all_paras( cursor.run ); } heap_free(buffer); diff --git a/dll/win32/riched32/CMakeLists.txt b/dll/win32/riched32/CMakeLists.txt index f719d7a261258..3d0783c858330 100644 --- a/dll/win32/riched32/CMakeLists.txt +++ b/dll/win32/riched32/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(riched32.dll riched32.spec) list(APPEND SOURCE @@ -12,3 +10,4 @@ set_module_type(riched32 win32dll) target_link_libraries(riched32 wine) add_importlibs(riched32 riched20 user32 msvcrt kernel32 ntdll) add_cd_file(TARGET riched32 DESTINATION reactos/system32 FOR all) +set_wine_module(riched32) diff --git a/dll/win32/rpcrt4/CMakeLists.txt b/dll/win32/rpcrt4/CMakeLists.txt index 0b6491043ad0f..3c38e389efa0f 100644 --- a/dll/win32/rpcrt4/CMakeLists.txt +++ b/dll/win32/rpcrt4/CMakeLists.txt @@ -3,12 +3,10 @@ remove_definitions(-D_WIN32_WINNT=0x502) add_definitions(-D_WIN32_WINNT=0x600) add_definitions( - -D__WINESRC__ -D_RPCRT4_ -DCOM_NO_WINDOWS_H -DMSWMSG) -include_directories(BEFORE ${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(rpcrt4.dll rpcrt4.spec ADD_IMPORTLIB) add_rpc_files(client epm.idl) @@ -70,3 +68,4 @@ add_importlibs(rpcrt4 advapi32 advapi32_vista kernel32_vista ws2_32 msvcrt kerne add_dependencies(rpcrt4 ndr_types_header) add_pch(rpcrt4 precomp.h "${PCH_SKIP_SOURCE}") add_cd_file(TARGET rpcrt4 DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(rpcrt4) # CORE-5743: No ARRAY_SIZE and CONST_VTABLE diff --git a/dll/win32/rsabase/CMakeLists.txt b/dll/win32/rsabase/CMakeLists.txt index 4b4cd83743c7c..66ffd15acaa53 100644 --- a/dll/win32/rsabase/CMakeLists.txt +++ b/dll/win32/rsabase/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(rsabase.dll rsabase.spec) list(APPEND SOURCE @@ -12,3 +10,4 @@ set_module_type(rsabase win32dll ENTRYPOINT 0 ) target_link_libraries(rsabase wine) add_importlibs(rsabase rsaenh ntdll) add_cd_file(TARGET rsabase DESTINATION reactos/system32 FOR all) +set_wine_module(rsabase) diff --git a/dll/win32/rsaenh/CMakeLists.txt b/dll/win32/rsaenh/CMakeLists.txt index 700ccb81f947d..c98a52cb17e14 100644 --- a/dll/win32/rsaenh/CMakeLists.txt +++ b/dll/win32/rsaenh/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(rsaenh.dll rsaenh.spec ADD_IMPORTLIB NO_PRIVATE_WARNINGS) list(APPEND SOURCE @@ -27,3 +25,4 @@ target_link_libraries(rsaenh wine) add_importlibs(rsaenh msvcrt crypt32 advapi32 kernel32 ntdll) add_pch(rsaenh tomcrypt.h SOURCE) add_cd_file(TARGET rsaenh DESTINATION reactos/system32 FOR all) +set_wine_module(rsaenh) diff --git a/dll/win32/sccbase/CMakeLists.txt b/dll/win32/sccbase/CMakeLists.txt index c4c81abc6c87c..c53eaa9871480 100644 --- a/dll/win32/sccbase/CMakeLists.txt +++ b/dll/win32/sccbase/CMakeLists.txt @@ -1,6 +1,4 @@ -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) -add_definitions(-D__WINESRC__) spec2def(sccbase.dll sccbase.spec) list(APPEND SOURCE @@ -13,3 +11,4 @@ set_module_type(sccbase win32dll) target_link_libraries(sccbase wine) add_importlibs(sccbase msvcrt kernel32 ntdll) add_cd_file(TARGET sccbase DESTINATION reactos/system32 FOR all) +set_wine_module(sccbase) diff --git a/dll/win32/sccbase/main.c b/dll/win32/sccbase/main.c index b263d4dc5dd1d..b9a894382b16a 100644 --- a/dll/win32/sccbase/main.c +++ b/dll/win32/sccbase/main.c @@ -30,8 +30,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) switch (fdwReason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hinstDLL); break; diff --git a/dll/win32/schannel/CMakeLists.txt b/dll/win32/schannel/CMakeLists.txt index 4a0cf0cc53a63..e10137acd8e40 100644 --- a/dll/win32/schannel/CMakeLists.txt +++ b/dll/win32/schannel/CMakeLists.txt @@ -1,10 +1,9 @@ include_directories( - ${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine ${REACTOS_SOURCE_DIR}/sdk/include/reactos/libs/mbedtls) -add_definitions(-D__WINESRC__ -D_WINE) +add_definitions(-D_WINE) spec2def(schannel.dll schannel.spec) list(APPEND SOURCE @@ -28,3 +27,4 @@ target_link_libraries(schannel wine) add_importlibs(schannel mbedtls crypt32 secur32 advapi32 msvcrt kernel32 ntdll) add_pch(schannel precomp.h SOURCE) add_cd_file(TARGET schannel DESTINATION reactos/system32 FOR all) +set_wine_module(schannel) diff --git a/dll/win32/schannel/schannel_main.c b/dll/win32/schannel/schannel_main.c index 546ad1475677b..f3ca9eaae9dec 100644 --- a/dll/win32/schannel/schannel_main.c +++ b/dll/win32/schannel/schannel_main.c @@ -38,7 +38,9 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { TRACE("(0x%p, %d, %p)\n",hinstDLL,fdwReason,lpvReserved); +#ifndef __REACTOS__ if (fdwReason == DLL_WINE_PREATTACH) return FALSE; /* prefer native version */ +#endif if (fdwReason == DLL_PROCESS_ATTACH) #ifdef __REACTOS__ diff --git a/dll/win32/scrrun/CMakeLists.txt b/dll/win32/scrrun/CMakeLists.txt index 0be68f7d022ad..5ac216763d78b 100644 --- a/dll/win32/scrrun/CMakeLists.txt +++ b/dll/win32/scrrun/CMakeLists.txt @@ -1,6 +1,5 @@ -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) -add_definitions(-D__WINESRC__ -D__ROS_LONG64__) +add_definitions(-D__ROS_LONG64__) spec2def(scrrun.dll scrrun.spec) add_idl_headers(scrrun_idlheader scrrun.idl) add_typelib(scrrun.idl) @@ -33,3 +32,4 @@ target_link_libraries(scrrun uuid wine oldnames) add_importlibs(scrrun oleaut32 version advapi32 msvcrt kernel32 ntdll) add_pch(scrrun precomp.h "${PCH_SKIP_SOURCE}") add_cd_file(TARGET scrrun DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(scrrun) # CORE-5743: No ARRAY_SIZE and CONST_VTABLE diff --git a/dll/win32/scrrun/scrrun.c b/dll/win32/scrrun/scrrun.c index c14fb130f6004..3ab26e76c2333 100644 --- a/dll/win32/scrrun/scrrun.c +++ b/dll/win32/scrrun/scrrun.c @@ -242,8 +242,10 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved ) switch (reason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls( hinst ); scrrun_instance = hinst; diff --git a/dll/win32/secur32/lsalpc.c b/dll/win32/secur32/lsalpc.c index 131538103c352..1103e6f6f6b9b 100644 --- a/dll/win32/secur32/lsalpc.c +++ b/dll/win32/secur32/lsalpc.c @@ -74,7 +74,7 @@ LsapOpenLsaPort(VOID) sizeof(ConnectInfo)); ConnectInfo.CreateContext = FALSE; - ConnectInfo.TrustedCaller = TRUE; + ConnectInfo.TrustedCaller = YES; ConnectInfoLength = sizeof(LSA_CONNECTION_INFO); Status = NtConnectPort(&LsaPortHandle, @@ -175,7 +175,7 @@ LsaConnectUntrusted( ConnectInfoLength); ConnectInfo.CreateContext = TRUE; - ConnectInfo.TrustedCaller = FALSE; + ConnectInfo.TrustedCaller = NO; Status = NtConnectPort(LsaHandle, &PortName, diff --git a/dll/win32/sensapi/CMakeLists.txt b/dll/win32/sensapi/CMakeLists.txt index fac2b2cd59ac5..5c6ff89f46dda 100644 --- a/dll/win32/sensapi/CMakeLists.txt +++ b/dll/win32/sensapi/CMakeLists.txt @@ -1,6 +1,4 @@ -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) -add_definitions(-D__WINESRC__) spec2def(sensapi.dll sensapi.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -12,3 +10,4 @@ set_module_type(sensapi win32dll) target_link_libraries(sensapi wine) add_importlibs(sensapi msvcrt kernel32 ntdll) add_cd_file(TARGET sensapi DESTINATION reactos/system32 FOR all) +set_wine_module(sensapi) diff --git a/dll/win32/setupapi/cfgmgr.c b/dll/win32/setupapi/cfgmgr.c index 30a38e811346f..f0b49db3fe9e4 100644 --- a/dll/win32/setupapi/cfgmgr.c +++ b/dll/win32/setupapi/cfgmgr.c @@ -7843,10 +7843,77 @@ CM_Set_Class_Registry_PropertyA( _In_ ULONG ulFlags, _In_opt_ HMACHINE hMachine) { - FIXME("CM_Set_Class_Registry_PropertyA(%p %lx %p %lu %lx %p)\n", + LPWSTR lpBuffer; + ULONG ulType; + CONFIGRET ret; + + TRACE("CM_Set_Class_Registry_PropertyA(%p %lx %p %lu %lx %p)\n", ClassGuid, ulProperty, Buffer, ulLength, ulFlags, hMachine); - return CR_CALL_NOT_IMPLEMENTED; + if (ClassGuid == NULL) + return CR_INVALID_POINTER; + + if ((Buffer == NULL) && (ulLength != 0)) + return CR_INVALID_POINTER; + + if (ulFlags != 0) + return CR_INVALID_FLAG; + + if (Buffer == NULL) + { + ret = CM_Set_Class_Registry_PropertyW(ClassGuid, + ulProperty, + Buffer, + ulLength, + ulFlags, + hMachine); + } + else + { + /* Get property type */ + ulType = GetRegistryPropertyType(ulProperty); + + /* Allocate buffer if needed */ + if ((ulType == REG_SZ) || (ulType == REG_MULTI_SZ)) + { + lpBuffer = MyMalloc(ulLength * sizeof(WCHAR)); + if (lpBuffer == NULL) + { + ret = CR_OUT_OF_MEMORY; + } + else + { + if (!MultiByteToWideChar(CP_ACP, 0, Buffer, + ulLength, lpBuffer, ulLength)) + { + MyFree(lpBuffer); + ret = CR_FAILURE; + } + else + { + ret = CM_Set_Class_Registry_PropertyW(ClassGuid, + ulProperty, + lpBuffer, + ulLength * sizeof(WCHAR), + ulFlags, + hMachine); + MyFree(lpBuffer); + } + } + } + else + { + ret = CM_Set_Class_Registry_PropertyW(ClassGuid, + ulProperty, + Buffer, + ulLength, + ulFlags, + hMachine); + } + + } + + return ret; } @@ -7863,10 +7930,90 @@ CM_Set_Class_Registry_PropertyW( _In_ ULONG ulFlags, _In_opt_ HMACHINE hMachine) { - FIXME("CM_Set_Class_Registry_PropertyW(%p %lx %p %lu %lx %p)\n", + RPC_BINDING_HANDLE BindingHandle = NULL; + WCHAR szGuidString[PNP_MAX_GUID_STRING_LEN + 1]; + ULONG ulType = 0; + PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL; + ULONG SecurityDescriptorSize = 0; + CONFIGRET ret; + + TRACE("CM_Set_Class_Registry_PropertyW(%p %lx %p %lu %lx %p)\n", ClassGuid, ulProperty, Buffer, ulLength, ulFlags, hMachine); - return CR_CALL_NOT_IMPLEMENTED; + if (ClassGuid == NULL) + return CR_INVALID_POINTER; + + if ((Buffer == NULL) && (ulLength != 0)) + return CR_INVALID_POINTER; + + if (ulFlags != 0) + return CR_INVALID_FLAG; + + if (pSetupStringFromGuid(ClassGuid, + szGuidString, + PNP_MAX_GUID_STRING_LEN) != 0) + return CR_INVALID_DATA; + + if ((ulProperty < CM_CRP_MIN) || (ulProperty > CM_CRP_MAX)) + return CR_INVALID_PROPERTY; + + if (hMachine != NULL) + { + BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle; + if (BindingHandle == NULL) + return CR_FAILURE; + } + else + { + if (!PnpGetLocalHandles(&BindingHandle, NULL)) + return CR_FAILURE; + } + + ulType = GetRegistryPropertyType(ulProperty); + if ((ulType == REG_DWORD) && (ulLength != sizeof(DWORD))) + return CR_INVALID_DATA; + + if (ulProperty == CM_CRP_SECURITY_SDS) + { + if (ulLength != 0) + { + if (!ConvertStringSecurityDescriptorToSecurityDescriptorW((LPCWSTR)Buffer, + SDDL_REVISION_1, + &pSecurityDescriptor, + &SecurityDescriptorSize)) + { + ERR("ConvertStringSecurityDescriptorToSecurityDescriptorW() failed (Error %lu)\n", GetLastError()); + return CR_INVALID_DATA; + } + + Buffer = (PCVOID)pSecurityDescriptor; + ulLength = SecurityDescriptorSize; + } + + ulProperty = CM_CRP_SECURITY; + ulType = REG_BINARY; + } + + RpcTryExcept + { + ret = PNP_SetClassRegProp(BindingHandle, + szGuidString, + ulProperty, + ulType, + (LPBYTE)Buffer, + ulLength, + ulFlags); + } + RpcExcept(EXCEPTION_EXECUTE_HANDLER) + { + ret = RpcStatusToCmStatus(RpcExceptionCode()); + } + RpcEndExcept; + + if (pSecurityDescriptor) + LocalFree(pSecurityDescriptor); + + return ret; } diff --git a/dll/win32/setupapi/devclass.c b/dll/win32/setupapi/devclass.c index b8f7840159875..c3bc47adb7c31 100644 --- a/dll/win32/setupapi/devclass.c +++ b/dll/win32/setupapi/devclass.c @@ -1419,3 +1419,323 @@ SetupDiGetClassDevPropertySheetsW( TRACE("Returning %d\n", ret); return ret; } + +/*********************************************************************** + * SetupDiGetClassRegistryPropertyA(SETUPAPI.@) + */ +BOOL WINAPI +SetupDiGetClassRegistryPropertyA( + IN CONST GUID *ClassGuid, + IN DWORD Property, + OUT PDWORD PropertyRegDataType OPTIONAL, + OUT PBYTE PropertyBuffer, + IN DWORD PropertyBufferSize, + OUT PDWORD RequiredSize OPTIONAL, + IN PCSTR MachineName OPTIONAL, + IN PVOID Reserved) +{ + HMACHINE hMachine = NULL; + DWORD PropLength = 0; + DWORD Error = ERROR_SUCCESS; + CONFIGRET cr; + + TRACE("%s %lu %p %p %lu %p %s %p\n", + debugstr_guid(ClassGuid), Property, PropertyRegDataType, PropertyBuffer, + PropertyBufferSize, RequiredSize, MachineName, Reserved); + + if (Reserved != NULL) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + if (MachineName) + { + cr = CM_Connect_MachineA(MachineName, &hMachine); + if (cr != CR_SUCCESS) + goto done; + } + + if (Property >= SPCRP_MAXIMUM_PROPERTY) + { + cr = CR_INVALID_PROPERTY; + goto done; + } + + PropLength = PropertyBufferSize; + cr = CM_Get_Class_Registry_PropertyA((LPGUID)ClassGuid, + Property + (CM_DRP_DEVICEDESC - SPDRP_DEVICEDESC), + PropertyRegDataType, + PropertyBuffer, + &PropLength, + 0, + hMachine); + if ((cr == CR_SUCCESS) || (cr == CR_BUFFER_SMALL)) + { + if (RequiredSize) + *RequiredSize = PropLength; + } + +done: + if (cr != CR_SUCCESS) + { + switch (cr) + { + case CR_INVALID_DEVINST : + Error = ERROR_NO_SUCH_DEVINST; + break; + + case CR_INVALID_PROPERTY : + Error = ERROR_INVALID_REG_PROPERTY; + break; + + case CR_BUFFER_SMALL : + Error = ERROR_INSUFFICIENT_BUFFER; + break; + + default : + Error = GetErrorCodeFromCrCode(cr); + } + } + + if (hMachine != NULL) + CM_Disconnect_Machine(hMachine); + + SetLastError(Error); + return (cr == CR_SUCCESS); +} + +/*********************************************************************** + * SetupDiGetClassRegistryPropertyW(SETUPAPI.@) + */ +BOOL WINAPI +SetupDiGetClassRegistryPropertyW( + IN CONST GUID *ClassGuid, + IN DWORD Property, + OUT PDWORD PropertyRegDataType OPTIONAL, + OUT PBYTE PropertyBuffer, + IN DWORD PropertyBufferSize, + OUT PDWORD RequiredSize OPTIONAL, + IN PCWSTR MachineName OPTIONAL, + IN PVOID Reserved) +{ + HMACHINE hMachine = NULL; + DWORD PropLength = 0; + DWORD Error = ERROR_SUCCESS; + CONFIGRET cr; + + TRACE("%s %lu %p %p %lu %p %s %p\n", + debugstr_guid(ClassGuid), Property, PropertyRegDataType, PropertyBuffer, + PropertyBufferSize, RequiredSize, debugstr_w(MachineName), Reserved); + + if (Reserved != NULL) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + if (MachineName) + { + cr = CM_Connect_MachineW(MachineName, &hMachine); + if (cr != CR_SUCCESS) + goto done; + } + + if (Property >= SPCRP_MAXIMUM_PROPERTY) + { + cr = CR_INVALID_PROPERTY; + goto done; + } + + PropLength = PropertyBufferSize; + cr = CM_Get_Class_Registry_PropertyW((LPGUID)ClassGuid, + Property + (CM_DRP_DEVICEDESC - SPDRP_DEVICEDESC), + PropertyRegDataType, + PropertyBuffer, + &PropLength, + 0, + hMachine); + if ((cr == CR_SUCCESS) || (cr == CR_BUFFER_SMALL)) + { + if (RequiredSize) + *RequiredSize = PropLength; + } + +done: + if (cr != CR_SUCCESS) + { + switch (cr) + { + case CR_INVALID_DEVINST : + Error = ERROR_NO_SUCH_DEVINST; + break; + + case CR_INVALID_PROPERTY : + Error = ERROR_INVALID_REG_PROPERTY; + break; + + case CR_BUFFER_SMALL : + Error = ERROR_INSUFFICIENT_BUFFER; + break; + + default : + Error = GetErrorCodeFromCrCode(cr); + } + } + + if (hMachine != NULL) + CM_Disconnect_Machine(hMachine); + + SetLastError(Error); + return (cr == CR_SUCCESS); +} + +/*********************************************************************** + * SetupDiSetClassRegistryPropertyA(SETUPAPI.@) + */ +BOOL WINAPI +SetupDiSetClassRegistryPropertyA( + IN CONST GUID *ClassGuid, + IN DWORD Property, + IN CONST BYTE *PropertyBuffer OPTIONAL, + IN DWORD PropertyBufferSize, + IN PCSTR MachineName OPTIONAL, + IN PVOID Reserved) +{ + HMACHINE hMachine = NULL; + DWORD Error = ERROR_SUCCESS; + CONFIGRET cr; + + TRACE("%s %lu %p %lu %s %p\n", + debugstr_guid(ClassGuid), Property, PropertyBuffer, + PropertyBufferSize, MachineName, Reserved); + + if (Reserved != NULL) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + if (MachineName) + { + cr = CM_Connect_MachineA(MachineName, &hMachine); + if (cr != CR_SUCCESS) + goto done; + } + + if (Property >= SPCRP_MAXIMUM_PROPERTY) + { + cr = CR_INVALID_PROPERTY; + goto done; + } + + cr = CM_Set_Class_Registry_PropertyA((LPGUID)ClassGuid, + Property + (CM_DRP_DEVICEDESC - SPDRP_DEVICEDESC), + PropertyBuffer, + PropertyBufferSize, + 0, + hMachine); + +done: + if (cr != CR_SUCCESS) + { + switch (cr) + { + case CR_INVALID_DEVINST: + Error = ERROR_NO_SUCH_DEVINST; + break; + + case CR_INVALID_PROPERTY: + Error = ERROR_INVALID_REG_PROPERTY; + break; + + case CR_BUFFER_SMALL: + Error = ERROR_INSUFFICIENT_BUFFER; + break; + + default : + Error = GetErrorCodeFromCrCode(cr); + } + } + + if (hMachine != NULL) + CM_Disconnect_Machine(hMachine); + + SetLastError(Error); + return (cr == CR_SUCCESS); +} + +/*********************************************************************** + * SetupDiSetClassRegistryPropertyW(SETUPAPI.@) + */ +BOOL WINAPI +SetupDiSetClassRegistryPropertyW( + IN CONST GUID *ClassGuid, + IN DWORD Property, + IN CONST BYTE *PropertyBuffer OPTIONAL, + IN DWORD PropertyBufferSize, + IN PCWSTR MachineName OPTIONAL, + IN PVOID Reserved) +{ + HMACHINE hMachine = NULL; + DWORD Error = ERROR_SUCCESS; + CONFIGRET cr; + + TRACE("%s %lu %p %lu %s %p\n", + debugstr_guid(ClassGuid), Property, PropertyBuffer, + PropertyBufferSize, debugstr_w(MachineName), Reserved); + + if (Reserved != NULL) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + if (MachineName) + { + cr = CM_Connect_MachineW(MachineName, &hMachine); + if (cr != CR_SUCCESS) + goto done; + } + + if (Property >= SPCRP_MAXIMUM_PROPERTY) + { + cr = CR_INVALID_PROPERTY; + goto done; + } + + cr = CM_Set_Class_Registry_PropertyW((LPGUID)ClassGuid, + Property + (CM_DRP_DEVICEDESC - SPDRP_DEVICEDESC), + PropertyBuffer, + PropertyBufferSize, + 0, + hMachine); + +done: + if (cr != CR_SUCCESS) + { + switch (cr) + { + case CR_INVALID_DEVINST: + Error = ERROR_NO_SUCH_DEVINST; + break; + + case CR_INVALID_PROPERTY: + Error = ERROR_INVALID_REG_PROPERTY; + break; + + case CR_BUFFER_SMALL: + Error = ERROR_INSUFFICIENT_BUFFER; + break; + + default : + Error = GetErrorCodeFromCrCode(cr); + } + } + + if (hMachine != NULL) + CM_Disconnect_Machine(hMachine); + + SetLastError(Error); + return (cr == CR_SUCCESS); +} diff --git a/dll/win32/setupapi/devinst.c b/dll/win32/setupapi/devinst.c index 47e2bf8beaa4b..9dbabb48a32c3 100644 --- a/dll/win32/setupapi/devinst.c +++ b/dll/win32/setupapi/devinst.c @@ -6150,3 +6150,163 @@ SetupDiRestartDevices( return TRUE; } + +/*********************************************************************** + * SetupDiGetCustomDevicePropertyA (SETUPAPI.@) + */ +BOOL +WINAPI +SetupDiGetCustomDevicePropertyA( + IN HDEVINFO DeviceInfoSet, + IN PSP_DEVINFO_DATA DeviceInfoData, + IN PCSTR CustomPropertyName, + IN DWORD Flags, + OUT PDWORD PropertyRegDataType OPTIONAL, + OUT PBYTE PropertyBuffer, + IN DWORD PropertyBufferSize, + OUT PDWORD RequiredSize OPTIONAL) +{ + struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet; + struct DeviceInfo *deviceInfo; + DWORD ConfigFlags = 0, PropertySize; + CONFIGRET cr; + + TRACE("%s(%p %p %s 0x%lx %p %p %lu %p)\n", __FUNCTION__, DeviceInfoSet, DeviceInfoData, + CustomPropertyName, Flags, PropertyRegDataType, PropertyBuffer, PropertyBufferSize, RequiredSize); + + if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE) + { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC) + { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + if (!DeviceInfoData || DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA) + || !DeviceInfoData->Reserved) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + if (Flags & ~DICUSTOMDEVPROP_MERGE_MULTISZ) + { + SetLastError(ERROR_INVALID_FLAGS); + return FALSE; + } + + deviceInfo = (struct DeviceInfo *)DeviceInfoData->Reserved; + if (deviceInfo->set != set) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + if (Flags & DICUSTOMDEVPROP_MERGE_MULTISZ) + { + ConfigFlags |= CM_CUSTOMDEVPROP_MERGE_MULTISZ; + } + + PropertySize = PropertyBufferSize; + cr = CM_Get_DevInst_Custom_Property_ExA(deviceInfo->dnDevInst, + CustomPropertyName, + PropertyRegDataType, + PropertyBuffer, + &PropertySize, + ConfigFlags, + set->hMachine); + if ((cr == CR_SUCCESS) || (cr == CR_BUFFER_SMALL)) + { + if (RequiredSize) + *RequiredSize = PropertySize; + } + + if (cr != CR_SUCCESS) + { + SetLastError(GetErrorCodeFromCrCode(cr)); + return FALSE; + } + + return TRUE; +} + +/*********************************************************************** + * SetupDiGetCustomDevicePropertyW (SETUPAPI.@) + */ +BOOL +WINAPI +SetupDiGetCustomDevicePropertyW( + IN HDEVINFO DeviceInfoSet, + IN PSP_DEVINFO_DATA DeviceInfoData, + IN PCWSTR CustomPropertyName, + IN DWORD Flags, + OUT PDWORD PropertyRegDataType OPTIONAL, + OUT PBYTE PropertyBuffer, + IN DWORD PropertyBufferSize, + OUT PDWORD RequiredSize OPTIONAL) +{ + struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet; + struct DeviceInfo *deviceInfo; + DWORD ConfigFlags = 0, PropertySize; + CONFIGRET cr; + + TRACE("%s(%p %p %s 0x%lx %p %p %lu %p)\n", __FUNCTION__, DeviceInfoSet, DeviceInfoData, + debugstr_w(CustomPropertyName), Flags, PropertyRegDataType, PropertyBuffer, PropertyBufferSize, RequiredSize); + + if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE) + { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC) + { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + if (!DeviceInfoData || DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA) + || !DeviceInfoData->Reserved) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + if (Flags & ~DICUSTOMDEVPROP_MERGE_MULTISZ) + { + SetLastError(ERROR_INVALID_FLAGS); + return FALSE; + } + + deviceInfo = (struct DeviceInfo *)DeviceInfoData->Reserved; + if (deviceInfo->set != set) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + if (Flags & DICUSTOMDEVPROP_MERGE_MULTISZ) + { + ConfigFlags |= CM_CUSTOMDEVPROP_MERGE_MULTISZ; + } + + PropertySize = PropertyBufferSize; + cr = CM_Get_DevInst_Custom_Property_ExW(deviceInfo->dnDevInst, + CustomPropertyName, + PropertyRegDataType, + PropertyBuffer, + &PropertySize, + ConfigFlags, + set->hMachine); + if ((cr == CR_SUCCESS) || (cr == CR_BUFFER_SMALL)) + { + if (RequiredSize) + *RequiredSize = PropertySize; + } + + if (cr != CR_SUCCESS) + { + SetLastError(GetErrorCodeFromCrCode(cr)); + return FALSE; + } + + return TRUE; +} diff --git a/dll/win32/setupapi/install.c b/dll/win32/setupapi/install.c index 742c4ba3f19c0..6305e1cf65659 100644 --- a/dll/win32/setupapi/install.c +++ b/dll/win32/setupapi/install.c @@ -1612,37 +1612,72 @@ void WINAPI InstallHinfSectionA( HWND hwnd, HINSTANCE handle, LPCSTR cmdline, IN /*********************************************************************** * SetupInstallServicesFromInfSectionW (SETUPAPI.@) */ -BOOL WINAPI SetupInstallServicesFromInfSectionW( HINF Inf, PCWSTR SectionName, DWORD Flags) +BOOL +WINAPI +SetupInstallServicesFromInfSectionW( + _In_ HINF InfHandle, + _In_ PCWSTR SectionName, + _In_ DWORD Flags) { - return SetupInstallServicesFromInfSectionExW( Inf, SectionName, Flags, - NULL, NULL, NULL, NULL ); + return SetupInstallServicesFromInfSectionExW(InfHandle, + SectionName, + Flags, + INVALID_HANDLE_VALUE, + NULL, + NULL, + NULL); } /*********************************************************************** * SetupInstallServicesFromInfSectionA (SETUPAPI.@) */ -BOOL WINAPI SetupInstallServicesFromInfSectionA( HINF Inf, PCSTR SectionName, DWORD Flags) +BOOL +WINAPI +SetupInstallServicesFromInfSectionA( + _In_ HINF InfHandle, + _In_ PCSTR SectionName, + _In_ DWORD Flags) { - return SetupInstallServicesFromInfSectionExA( Inf, SectionName, Flags, - NULL, NULL, NULL, NULL ); + return SetupInstallServicesFromInfSectionExA(InfHandle, + SectionName, + Flags, + INVALID_HANDLE_VALUE, + NULL, + NULL, + NULL); } /*********************************************************************** * SetupInstallServicesFromInfSectionExA (SETUPAPI.@) */ -BOOL WINAPI SetupInstallServicesFromInfSectionExA( HINF hinf, PCSTR sectionname, DWORD flags, HDEVINFO devinfo, PSP_DEVINFO_DATA devinfo_data, PVOID reserved1, PVOID reserved2 ) +BOOL +WINAPI +SetupInstallServicesFromInfSectionExA( + _In_ HINF InfHandle, + _In_ PCSTR SectionName, + _In_ DWORD Flags, + _In_opt_ HDEVINFO DeviceInfoSet, + _In_opt_ PSP_DEVINFO_DATA DeviceInfoData, + _Reserved_ PVOID Reserved1, + _Reserved_ PVOID Reserved2) { - UNICODE_STRING sectionnameW; - BOOL ret = FALSE; + UNICODE_STRING SectionNameW; + BOOL ret; - if (RtlCreateUnicodeStringFromAsciiz( §ionnameW, sectionname )) + if (!RtlCreateUnicodeStringFromAsciiz(&SectionNameW, SectionName)) { - ret = SetupInstallServicesFromInfSectionExW( hinf, sectionnameW.Buffer, flags, devinfo, devinfo_data, reserved1, reserved2 ); - RtlFreeUnicodeString( §ionnameW ); + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; } - else - SetLastError( ERROR_NOT_ENOUGH_MEMORY ); + ret = SetupInstallServicesFromInfSectionExW(InfHandle, + SectionNameW.Buffer, + Flags, + DeviceInfoSet, + DeviceInfoData, + Reserved1, + Reserved2); + RtlFreeUnicodeString(&SectionNameW); return ret; } @@ -2078,29 +2113,61 @@ static BOOL InstallOneService( /*********************************************************************** * SetupInstallServicesFromInfSectionExW (SETUPAPI.@) */ -BOOL WINAPI SetupInstallServicesFromInfSectionExW( HINF hinf, PCWSTR sectionname, DWORD flags, HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PVOID reserved1, PVOID reserved2 ) +BOOL +WINAPI +SetupInstallServicesFromInfSectionExW( + _In_ HINF InfHandle, + _In_ PCWSTR SectionName, + _In_ DWORD Flags, + _In_opt_ HDEVINFO DeviceInfoSet, + _In_opt_ PSP_DEVINFO_DATA DeviceInfoData, + _Reserved_ PVOID Reserved1, + _Reserved_ PVOID Reserved2) { - struct DeviceInfoSet *list = NULL; + struct DeviceInfoSet *list; BOOL ret = FALSE; - TRACE("%p, %s, 0x%lx, %p, %p, %p, %p\n", hinf, debugstr_w(sectionname), - flags, DeviceInfoSet, DeviceInfoData, reserved1, reserved2); + /* FIXME: SPSVCINST_ASSOCSERVICE is not fully supported */ + static const DWORD SupportedFlags = + SPSVCINST_TAGTOFRONT | SPSVCINST_DELETEEVENTLOGENTRY | SPSVCINST_NOCLOBBER_DISPLAYNAME | + SPSVCINST_NOCLOBBER_STARTTYPE | SPSVCINST_NOCLOBBER_ERRORCONTROL | + SPSVCINST_NOCLOBBER_LOADORDERGROUP | SPSVCINST_NOCLOBBER_DEPENDENCIES | + SPSVCINST_STOPSERVICE; - if (!sectionname) - SetLastError(ERROR_INVALID_PARAMETER); - else if (flags & ~(SPSVCINST_TAGTOFRONT | SPSVCINST_DELETEEVENTLOGENTRY | SPSVCINST_NOCLOBBER_DISPLAYNAME | SPSVCINST_NOCLOBBER_STARTTYPE | SPSVCINST_NOCLOBBER_ERRORCONTROL | SPSVCINST_NOCLOBBER_LOADORDERGROUP | SPSVCINST_NOCLOBBER_DEPENDENCIES | SPSVCINST_STOPSERVICE)) + TRACE("%p, %s, 0x%lx, %p, %p, %p, %p\n", + InfHandle, + debugstr_w(SectionName), + Flags, + DeviceInfoSet, + DeviceInfoData, + Reserved1, + Reserved2); + + if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE) + { + list = NULL; + } else { - TRACE("Unknown flags: 0x%08lx\n", flags & ~(SPSVCINST_TAGTOFRONT | SPSVCINST_DELETEEVENTLOGENTRY | SPSVCINST_NOCLOBBER_DISPLAYNAME | SPSVCINST_NOCLOBBER_STARTTYPE | SPSVCINST_NOCLOBBER_ERRORCONTROL | SPSVCINST_NOCLOBBER_LOADORDERGROUP | SPSVCINST_NOCLOBBER_DEPENDENCIES | SPSVCINST_STOPSERVICE)); + list = (struct DeviceInfoSet*)DeviceInfoSet; + } + + if (Flags & ~(SupportedFlags)) + { + TRACE("Unknown flags: 0x%08lx\n", Flags & ~(SupportedFlags)); SetLastError(ERROR_INVALID_FLAGS); } - else if (DeviceInfoSet == (HDEVINFO)INVALID_HANDLE_VALUE) - SetLastError(ERROR_INVALID_HANDLE); - else if (DeviceInfoSet && (list = (struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEVICE_INFO_SET_MAGIC) + else if (!SectionName || Reserved1 || Reserved2) + { + SetLastError(ERROR_INVALID_PARAMETER); + } + else if (list && list->magic != SETUP_DEVICE_INFO_SET_MAGIC) + { SetLastError(ERROR_INVALID_HANDLE); + } else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA)) + { SetLastError(ERROR_INVALID_USER_BUFFER); - else if (reserved1 != NULL || reserved2 != NULL) - SetLastError(ERROR_INVALID_PARAMETER); + } else { struct needs_callback_info needs_info; @@ -2111,16 +2178,16 @@ BOOL WINAPI SetupInstallServicesFromInfSectionExW( HINF hinf, PCWSTR sectionname BOOL bNeedReboot = FALSE; /* Parse 'Include' and 'Needs' directives */ - iterate_section_fields( hinf, sectionname, Include, include_callback, NULL); + iterate_section_fields(InfHandle, SectionName, Include, include_callback, NULL); needs_info.type = 1; - needs_info.flags = flags; + needs_info.flags = Flags; needs_info.devinfo = DeviceInfoSet; needs_info.devinfo_data = DeviceInfoData; - needs_info.reserved1 = reserved1; - needs_info.reserved2 = reserved2; - iterate_section_fields( hinf, sectionname, Needs, needs_callback, &needs_info); + needs_info.reserved1 = Reserved1; + needs_info.reserved2 = Reserved2; + iterate_section_fields(InfHandle, SectionName, Needs, needs_callback, &needs_info); - if (flags & SPSVCINST_STOPSERVICE) + if (Flags & SPSVCINST_STOPSERVICE) { FIXME("Stopping the device not implemented\n"); /* This may lead to require a reboot */ @@ -2136,16 +2203,16 @@ BOOL WINAPI SetupInstallServicesFromInfSectionExW( HINF hinf, PCWSTR sectionname goto done; } #endif - flags &= ~SPSVCINST_STOPSERVICE; + Flags &= ~SPSVCINST_STOPSERVICE; } - if (!(ret = SetupFindFirstLineW( hinf, sectionname, NULL, &ContextService ))) + if (!(ret = SetupFindFirstLineW(InfHandle, SectionName, NULL, &ContextService))) { - SetLastError( ERROR_SECTION_NOT_FOUND ); + SetLastError(ERROR_SECTION_NOT_FOUND); goto done; } - ret = SetupFindFirstLineW(hinf, sectionname, AddService, &ContextService); + ret = SetupFindFirstLineW(InfHandle, SectionName, AddService, &ContextService); while (ret) { if (!GetStringField(&ContextService, 1, &ServiceName)) @@ -2164,11 +2231,11 @@ BOOL WINAPI SetupInstallServicesFromInfSectionExW( HINF hinf, PCWSTR sectionname if (!GetStringField(&ContextService, 3, &ServiceSection)) goto done; - ret = InstallOneService(list, hinf, ServiceSection, ServiceName, (ServiceFlags & ~SPSVCINST_ASSOCSERVICE) | flags); + ret = InstallOneService(list, InfHandle, ServiceSection, ServiceName, (ServiceFlags & ~SPSVCINST_ASSOCSERVICE) | Flags); if (!ret) goto done; - if (ServiceFlags & SPSVCINST_ASSOCSERVICE) + if (list && (ServiceFlags & SPSVCINST_ASSOCSERVICE)) { ret = SetupDiSetDeviceRegistryPropertyW(DeviceInfoSet, DeviceInfoData, SPDRP_SERVICE, (LPBYTE)ServiceName, (strlenW(ServiceName) + 1) * sizeof(WCHAR)); if (!ret) diff --git a/dll/win32/setupapi/interface.c b/dll/win32/setupapi/interface.c index 09b84d519a4b5..6a627d1118e5b 100644 --- a/dll/win32/setupapi/interface.c +++ b/dll/win32/setupapi/interface.c @@ -212,8 +212,12 @@ SETUP_CreateInterfaceList( /* Read SymbolicLink value */ rc = RegQueryValueExW(hReferenceKey, SymbolicLink, NULL, &dwRegType, NULL, &dwLength); - if (rc != ERROR_SUCCESS ) - goto cleanup; + if (rc != ERROR_SUCCESS) + { + /* Skip device interface with invalid reference value (i.e. interface not actually available for this device) */ + RegCloseKey(hReferenceKey); + continue; + } if (dwRegType != REG_SZ) { rc = ERROR_GEN_FAILURE; diff --git a/dll/win32/setupapi/misc.c b/dll/win32/setupapi/misc.c index df03525a2ef99..9f92f71bf419e 100644 --- a/dll/win32/setupapi/misc.c +++ b/dll/win32/setupapi/misc.c @@ -839,7 +839,7 @@ DWORD WINAPI RetreiveFileSecurity(LPCWSTR lpFileName, /* - * See: https://msdn.microsoft.com/en-us/library/bb432397(v=vs.85).aspx + * See: https://learn.microsoft.com/en-us/windows/win32/devnotes/psetupsetglobalflags * for more information. */ DWORD GlobalSetupFlags = 0; diff --git a/dll/win32/setupapi/parser.c b/dll/win32/setupapi/parser.c index d5e83a481ac88..6cdc3b83d2a4f 100644 --- a/dll/win32/setupapi/parser.c +++ b/dll/win32/setupapi/parser.c @@ -1235,11 +1235,18 @@ HINF WINAPI SetupOpenInfFileW( PCWSTR name, PCWSTR class, DWORD style, UINT *err TRACE("%s %s %lx %p\n", debugstr_w(name), debugstr_w(class), style, error); +#ifdef __REACTOS__ if (style & ~(INF_STYLE_OLDNT | INF_STYLE_WIN4)) { SetLastError(ERROR_INVALID_PARAMETER); return (HINF)INVALID_HANDLE_VALUE; } + if (!name) + { + SetLastError(ERROR_INVALID_PARAMETER); + return (HINF)INVALID_HANDLE_VALUE; + } +#endif // __REACTOS__ if (strchrW( name, '\\' ) || strchrW( name, '/' )) { @@ -2326,6 +2333,12 @@ SetupDiGetINFClassW( TRACE("%s %p %p %ld %p\n", debugstr_w(InfName), ClassGuid, ClassName, ClassNameSize, RequiredSize); + if (!InfName || !ClassGuid || !ClassName || ClassNameSize == 0) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + /* Open .inf file */ hInf = SetupOpenInfFileW(InfName, NULL, INF_STYLE_WIN4, NULL); if (hInf == INVALID_HANDLE_VALUE) diff --git a/dll/win32/setupapi/query.c b/dll/win32/setupapi/query.c index 58c3d5b888e26..b4d1b0c162dc9 100644 --- a/dll/win32/setupapi/query.c +++ b/dll/win32/setupapi/query.c @@ -693,3 +693,21 @@ BOOL WINAPI SetupQueryInfOriginalFileInformationW( return TRUE; } + +BOOL WINAPI SetupQueryInfVersionInformationA(SP_INF_INFORMATION *info, UINT index, const char *key, char *buff, + DWORD size, DWORD *req_size) +{ + FIXME("info %p, index %d, key %s, buff %p, size %ld, req_size %p stub!\n", info, index, debugstr_a(key), buff, + size, req_size); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +BOOL WINAPI SetupQueryInfVersionInformationW(SP_INF_INFORMATION *info, UINT index, const WCHAR *key, WCHAR *buff, + DWORD size, DWORD *req_size) +{ + FIXME("info %p, index %d, key %s, buff %p, size %ld, req_size %p stub!\n", info, index, debugstr_w(key), buff, + size, req_size); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} diff --git a/dll/win32/setupapi/setupapi.spec b/dll/win32/setupapi/setupapi.spec index cc849483b99ab..29129da50767a 100644 --- a/dll/win32/setupapi/setupapi.spec +++ b/dll/win32/setupapi/setupapi.spec @@ -313,10 +313,10 @@ @ stdcall SetupDiGetClassImageListExW(ptr wstr ptr) @ stdcall SetupDiGetClassInstallParamsA(ptr ptr ptr long ptr) @ stdcall SetupDiGetClassInstallParamsW(ptr ptr ptr long ptr) -@ stub SetupDiGetClassRegistryPropertyA -@ stub SetupDiGetClassRegistryPropertyW -@ stub SetupDiGetCustomDevicePropertyA -@ stub SetupDiGetCustomDevicePropertyW +@ stdcall SetupDiGetClassRegistryPropertyA(ptr long ptr ptr long ptr str ptr) +@ stdcall SetupDiGetClassRegistryPropertyW(ptr long ptr ptr long ptr wstr ptr) +@ stdcall SetupDiGetCustomDevicePropertyA(ptr ptr str long ptr ptr long ptr) +@ stdcall SetupDiGetCustomDevicePropertyW(ptr ptr wstr long ptr ptr long ptr) @ stdcall SetupDiGetDeviceInfoListClass(ptr ptr) @ stdcall SetupDiGetDeviceInfoListDetailA(ptr ptr) @ stdcall SetupDiGetDeviceInfoListDetailW(ptr ptr) @@ -374,8 +374,8 @@ @ stub SetupDiSelectOEMDrv @ stdcall SetupDiSetClassInstallParamsA(ptr ptr ptr long) @ stdcall SetupDiSetClassInstallParamsW(ptr ptr ptr long) -@ stub SetupDiSetClassRegistryPropertyA -@ stub SetupDiSetClassRegistryPropertyW +@ stdcall SetupDiSetClassRegistryPropertyA(ptr long ptr long str ptr) +@ stdcall SetupDiSetClassRegistryPropertyW(ptr long ptr long wstr ptr) @ stdcall SetupDiSetDeviceInstallParamsA(ptr ptr ptr) @ stdcall SetupDiSetDeviceInstallParamsW(ptr ptr ptr) @ stub SetupDiSetDeviceInterfaceDefault @@ -475,8 +475,8 @@ @ stdcall SetupQueryInfFileInformationW(ptr long wstr long ptr) @ stdcall SetupQueryInfOriginalFileInformationA(ptr long ptr ptr) @ stdcall SetupQueryInfOriginalFileInformationW(ptr long ptr ptr) -@ stub SetupQueryInfVersionInformationA -@ stub SetupQueryInfVersionInformationW +@ stdcall SetupQueryInfVersionInformationA(ptr long str ptr long ptr) +@ stdcall SetupQueryInfVersionInformationW(ptr long wstr ptr long ptr) @ stub SetupQuerySourceListA @ stub SetupQuerySourceListW @ stdcall SetupQuerySpaceRequiredOnDriveA(long str ptr ptr long) diff --git a/dll/win32/setupapi/setupapi_private.h b/dll/win32/setupapi/setupapi_private.h index fb758142645d8..7a11aa680baa8 100644 --- a/dll/win32/setupapi/setupapi_private.h +++ b/dll/win32/setupapi/setupapi_private.h @@ -249,7 +249,7 @@ extern HINSTANCE hInstance; extern OSVERSIONINFOEXW OsVersionInfo; /* - * See: https://msdn.microsoft.com/en-us/library/bb432397(v=vs.85).aspx + * See: https://learn.microsoft.com/en-us/windows/win32/devnotes/psetupsetglobalflags * for more information. */ extern DWORD GlobalSetupFlags; diff --git a/dll/win32/shdocvw/CExplorerBand.cpp b/dll/win32/shdocvw/CExplorerBand.cpp index aa70c06c5c2a0..6ac5f14ae61e8 100644 --- a/dll/win32/shdocvw/CExplorerBand.cpp +++ b/dll/win32/shdocvw/CExplorerBand.cpp @@ -235,7 +235,7 @@ CExplorerBand::_NavigateToPIDL( HTREEITEM hParent = NULL, tmp; while (TRUE) { - CItemData *pItemData = GetItemData(hItem); + CItemData *pItemData = _GetItemData(hItem); if (!pItemData) { ERR("Something has gone wrong, no data associated to node\n"); diff --git a/dll/win32/shdocvw/CFavBand.cpp b/dll/win32/shdocvw/CFavBand.cpp index b79f2e27be2b5..de8938e8b867b 100644 --- a/dll/win32/shdocvw/CFavBand.cpp +++ b/dll/win32/shdocvw/CFavBand.cpp @@ -146,7 +146,7 @@ STDMETHODIMP CFavBand::OnSelectionChanged(_In_ PCIDLIST_ABSOLUTE pidl) if (attrs & SFGAO_FOLDER) { HTREEITEM hItem = TreeView_GetSelection(m_hwndTreeView); - CItemData *pItemData = GetItemData(hItem); + CItemData *pItemData = _GetItemData(hItem); if (pItemData && !pItemData->expanded) { _InsertSubitems(hItem, pItemData->absolutePidl); diff --git a/dll/win32/shdocvw/CMakeLists.txt b/dll/win32/shdocvw/CMakeLists.txt index 119e8aaf88201..6d178708672ac 100644 --- a/dll/win32/shdocvw/CMakeLists.txt +++ b/dll/win32/shdocvw/CMakeLists.txt @@ -37,7 +37,8 @@ add_library(shdocvw_sublib OBJECT CNSCBand.cpp mrulist.cpp objects.cpp - utility.cpp) + utility.cpp + winlist.cpp) target_link_libraries(shdocvw_sublib PRIVATE atl_classes) target_compile_definitions(shdocvw_sublib PRIVATE $) target_compile_options(shdocvw_sublib PRIVATE $) diff --git a/dll/win32/shdocvw/CNSCBand.cpp b/dll/win32/shdocvw/CNSCBand.cpp index d40a4c8ca3726..8868931bb1e04 100644 --- a/dll/win32/shdocvw/CNSCBand.cpp +++ b/dll/win32/shdocvw/CNSCBand.cpp @@ -45,33 +45,6 @@ SHDOCVW_GetPathOfShortcut( return S_OK; } -HRESULT -SHDOCVW_CreateShortcut( - _In_ LPCWSTR pszLnkFileName, - _In_ PCIDLIST_ABSOLUTE pidlTarget, - _In_opt_ LPCWSTR pszDescription) -{ - HRESULT hr; - - CComPtr psl; - hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, - IID_PPV_ARG(IShellLink, &psl)); - if (FAILED_UNEXPECTEDLY(hr)) - return hr; - - psl->SetIDList(pidlTarget); - - if (pszDescription) - psl->SetDescription(pszDescription); - - CComPtr ppf; - hr = psl->QueryInterface(IID_PPV_ARG(IPersistFile, &ppf)); - if (FAILED_UNEXPECTEDLY(hr)) - return hr; - - return ppf->Save(pszLnkFileName, TRUE); -} - CNSCBand::CNSCBand() { SHDOCVW_LockModule(); @@ -87,18 +60,20 @@ CNSCBand::~CNSCBand() ImageList_Destroy(m_hToolbarImageList); m_hToolbarImageList = NULL; } + SHFree(m_OriginalRename); SHDOCVW_UnlockModule(); } VOID CNSCBand::OnFinalMessage(HWND) { // The message loop is finished, now we can safely destruct! - static_cast(this)->Release(); + // HACKFIX: Who did this AddRef? Commenting out Release... + //static_cast(this)->Release(); } // *** helper methods *** -CNSCBand::CItemData* CNSCBand::GetItemData(_In_ HTREEITEM hItem) +CNSCBand::CItemData* CNSCBand::_GetItemData(_In_ HTREEITEM hItem) { if (hItem == TVI_ROOT) return NULL; @@ -110,6 +85,44 @@ CNSCBand::CItemData* CNSCBand::GetItemData(_In_ HTREEITEM hItem) return reinterpret_cast(tvItem.lParam); } +CNSCBand::CItemData* CNSCBand::_GetItemData(_In_ UINT ItemSpec) +{ + HTREEITEM hItem = m_hwndTreeView.GetNextItem(NULL, ItemSpec); + return hItem ? _GetItemData(hItem) : NULL; +} + +SFGAOF CNSCBand::_GetAttributesOfItem(_In_ CItemData *pData, _In_ SFGAOF Query) +{ + if (!pData) + return 0; + CComPtr pFolder; + LPCITEMIDLIST pidlChild; + HRESULT hr = SHBindToParent(pData->absolutePidl, IID_PPV_ARG(IShellFolder, &pFolder), &pidlChild); + if (FAILED_UNEXPECTEDLY(hr)) + return 0; + SFGAOF Attributes = Query; + if (FAILED_UNEXPECTEDLY(hr = pFolder->GetAttributesOf(1, &pidlChild, &Attributes))) + return 0; + return Attributes & Query; +} + +HRESULT CNSCBand::_GetNameOfItem(IShellFolder *pSF, PCUITEMID_CHILD pidl, UINT Flags, PWSTR Name) +{ + STRRET strret; + HRESULT hr = pSF->GetDisplayNameOf(pidl, Flags, &strret); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + hr = StrRetToBufW(&strret, pidl, Name, MAX_PATH); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + return hr; +} + +HRESULT CNSCBand::_GetNameOfItem(IShellFolder *pSF, PCUITEMID_CHILD pidl, PWSTR Name) +{ + return _GetNameOfItem(pSF, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, Name); +} + static HRESULT SHDOCVW_GetCurrentLocationFromView(_In_ IShellView& View, _In_ PIDLIST_ABSOLUTE *ppidl) { @@ -259,7 +272,7 @@ CNSCBand::_IsTreeItemInEnum( _In_ HTREEITEM hItem, _In_ IEnumIDList *pEnum) { - CItemData* pItemData = GetItemData(hItem); + CItemData* pItemData = _GetItemData(hItem); if (!pItemData) return FALSE; @@ -285,7 +298,7 @@ CNSCBand::_TreeItemHasThisChild( for (hItem = TreeView_GetChild(m_hwndTreeView, hItem); hItem; hItem = TreeView_GetNextSibling(m_hwndTreeView, hItem)) { - CItemData* pItemData = GetItemData(hItem); + CItemData* pItemData = _GetItemData(hItem); if (ILIsEqual(pItemData->relativePidl, pidlChild)) return TRUE; } @@ -315,7 +328,7 @@ CNSCBand::_GetItemEnum( } else { - CItemData* pItemData = GetItemData(hItem); + CItemData* pItemData = _GetItemData(hItem); if (!pItemData && hItem == TVI_ROOT && !_WantsRootItem()) hr = psfDesktop->BindToObject(m_pidlRoot, NULL, IID_PPV_ARG(IShellFolder, ppFolder)); else @@ -357,7 +370,7 @@ void CNSCBand::_RefreshRecurse(_In_ HTREEITEM hTarget) pEnum = NULL; hrEnum = _GetItemEnum(pEnum, hTarget); - CItemData* pItemData = ((hTarget == TVI_ROOT) ? NULL : GetItemData(hTarget)); + CItemData* pItemData = ((hTarget == TVI_ROOT) ? NULL : _GetItemData(hTarget)); // Insert new items and update items if (SUCCEEDED(hrEnum)) @@ -460,19 +473,12 @@ CNSCBand::_InsertItem( if (FAILED_UNEXPECTEDLY(hr)) return NULL; - /* Get the name of the node */ WCHAR wszDisplayName[MAX_PATH]; - STRRET strret; - hr = psfParent->GetDisplayNameOf(pEltRelative, SHGDN_INFOLDER, &strret); - if (FAILED_UNEXPECTEDLY(hr)) - return NULL; - - hr = StrRetToBufW(&strret, pEltRelative, wszDisplayName, MAX_PATH); - if (FAILED_UNEXPECTEDLY(hr)) + if (FAILED_UNEXPECTEDLY(hr = _GetNameOfItem(psfParent, pEltRelative, wszDisplayName))) return NULL; - /* Get the icon of the node */ - INT iIcon = SHMapPIDLToSystemImageListIndex(psfParent, pEltRelative, NULL); + INT iSelIcon = -1; + INT iIcon = SHMapPIDLToSystemImageListIndex(psfParent, pEltRelative, &iSelIcon); CItemData* pChildInfo = new CItemData; if (!pChildInfo) @@ -488,7 +494,8 @@ CNSCBand::_InsertItem( tvInsert.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN; tvInsert.item.cchTextMax = MAX_PATH; tvInsert.item.pszText = wszDisplayName; - tvInsert.item.iImage = tvInsert.item.iSelectedImage = iIcon; + tvInsert.item.iImage = iIcon; + tvInsert.item.iSelectedImage = iSelIcon >= 0 ? iSelIcon : iIcon; tvInsert.item.lParam = (LPARAM)pChildInfo; if (!(attrs & SFGAO_STREAM) && (attrs & SFGAO_HASSUBFOLDER)) @@ -614,31 +621,23 @@ HRESULT CNSCBand::_AddFavorite() CComHeapPtr pidlCurrent; _GetCurrentLocation(&pidlCurrent); - WCHAR szCurDir[MAX_PATH]; - if (!ILGetDisplayName(pidlCurrent, szCurDir)) - { - FIXME("\n"); - return E_FAIL; - } - - WCHAR szPath[MAX_PATH], szSuffix[32]; - SHGetSpecialFolderPathW(m_hWnd, szPath, CSIDL_FAVORITES, TRUE); - PathAppendW(szPath, PathFindFileNameW(szCurDir)); + CComPtr pParent; + LPCITEMIDLIST pidlLast; + HRESULT hr = SHBindToParent(pidlCurrent, IID_PPV_ARG(IShellFolder, &pParent), &pidlLast); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; - const INT ich = lstrlenW(szPath); - for (INT iTry = 2; iTry <= 9999; ++iTry) - { - PathAddExtensionW(szPath, L".lnk"); - if (!PathFileExistsW(szPath)) - break; - szPath[ich] = UNICODE_NULL; - wsprintfW(szSuffix, L" (%d)", iTry); - lstrcatW(szPath, szSuffix); - } + STRRET strret; + hr = pParent->GetDisplayNameOf(pidlLast, SHGDN_FORPARSING, &strret); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; - TRACE("%S, %S\n", szCurDir, szPath); + CComHeapPtr pszURL; + hr = StrRetToStrW(&strret, NULL, &pszURL); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; - return SHDOCVW_CreateShortcut(szPath, pidlCurrent, NULL); + return AddUrlToFavorites(m_hWnd, pszURL, NULL, TRUE); } LRESULT CNSCBand::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) @@ -683,7 +682,7 @@ BOOL CNSCBand::OnTreeItemExpanding(_In_ LPNMTREEVIEW pnmtv) if (pnmtv->action == TVE_EXPAND) { // Grab our directory PIDL - pItemData = GetItemData(pnmtv->itemNew.hItem); + pItemData = _GetItemData(pnmtv->itemNew.hItem); // We have it, let's try if (pItemData && !pItemData->expanded) { @@ -712,7 +711,7 @@ BOOL CNSCBand::OnTreeItemDeleted(_In_ LPNMTREEVIEW pnmtv) TreeView_SelectItem(m_hwndTreeView, hParent); /* Destroy memory associated to our node */ - CItemData* pItemData = GetItemData(hItem); + CItemData* pItemData = _GetItemData(hItem); if (!pItemData) return FALSE; @@ -726,14 +725,14 @@ void CNSCBand::_OnSelectionChanged(_In_ LPNMTREEVIEW pnmtv) HTREEITEM hItem = pnmtv->itemNew.hItem; if (!hItem) return; - CItemData* pItemData = GetItemData(hItem); + CItemData* pItemData = _GetItemData(hItem); if (pItemData) OnSelectionChanged(pItemData->absolutePidl); } void CNSCBand::OnTreeItemDragging(_In_ LPNMTREEVIEW pnmtv, _In_ BOOL isRightClick) { - CItemData* pItemData = GetItemData(pnmtv->itemNew.hItem); + CItemData* pItemData = _GetItemData(pnmtv->itemNew.hItem); if (!pItemData) return; @@ -770,27 +769,35 @@ LRESULT CNSCBand::OnBeginLabelEdit(_In_ LPNMTVDISPINFO dispInfo) CComPtr pParent; LPCITEMIDLIST pChild; HRESULT hr; + HWND hWndEdit = TreeView_GetEditControl(dispInfo->hdr.hwndFrom); - CItemData *info = GetItemData(dispInfo->item.hItem); - if (!info) - return FALSE; + SHFree(m_OriginalRename); + m_OriginalRename = NULL; + CItemData *info = _GetItemData(dispInfo->item.hItem); + if (!info || !hWndEdit) + return TRUE; hr = SHBindToParent(info->absolutePidl, IID_PPV_ARG(IShellFolder, &pParent), &pChild); if (FAILED_UNEXPECTEDLY(hr)) - return FALSE; + return TRUE; hr = pParent->GetAttributesOf(1, &pChild, &dwAttr); if (SUCCEEDED(hr) && (dwAttr & SFGAO_CANRENAME)) { + WCHAR szName[MAX_PATH]; + if (SUCCEEDED(_GetNameOfItem(pParent, pChild, SHGDN_FOREDITING | SHGDN_INFOLDER, szName))) + { + ::SetWindowTextW(hWndEdit, szName); + SHStrDupW(szName, &m_OriginalRename); + } m_isEditing = TRUE; m_oldSelected = NULL; return FALSE; } - return TRUE; } -HRESULT CNSCBand::_UpdateBrowser(LPCITEMIDLIST pidlGoto) +HRESULT CNSCBand::_UpdateBrowser(LPCITEMIDLIST pidlGoto, BOOL IgnoreSelfNavigation) { CComPtr pBrowserService; HRESULT hr = IUnknown_QueryService(m_pSite, SID_STopLevelBrowser, @@ -798,6 +805,17 @@ HRESULT CNSCBand::_UpdateBrowser(LPCITEMIDLIST pidlGoto) if (FAILED_UNEXPECTEDLY(hr)) return hr; + if (_IsCurrentLocation(pidlGoto) == S_OK) // Don't add duplicates to the travel log + { + if (IgnoreSelfNavigation) + return S_FALSE; + + CComPtr psv; + if (SUCCEEDED(hr = pBrowserService->QueryActiveShellView(&psv))) + hr = psv->Refresh(); + if (SUCCEEDED(hr)) + return hr; + } hr = pBrowserService->BrowseObject(pidlGoto, SBSP_SAMEBROWSER | SBSP_ABSOLUTE); if (FAILED_UNEXPECTEDLY(hr)) return hr; @@ -807,8 +825,9 @@ HRESULT CNSCBand::_UpdateBrowser(LPCITEMIDLIST pidlGoto) LRESULT CNSCBand::OnEndLabelEdit(_In_ LPNMTVDISPINFO dispInfo) { - CItemData *info = GetItemData(dispInfo->item.hItem); + CItemData *info = _GetItemData(dispInfo->item.hItem); HRESULT hr; + BOOL AllowTreeSetNewName = TRUE; m_isEditing = FALSE; if (m_oldSelected) @@ -821,6 +840,15 @@ LRESULT CNSCBand::OnEndLabelEdit(_In_ LPNMTVDISPINFO dispInfo) if (!dispInfo->item.pszText) return FALSE; + if (m_OriginalRename) + { + BOOL same = !lstrcmpW(m_OriginalRename, dispInfo->item.pszText); // Case-sensitive + SHFree(m_OriginalRename); + m_OriginalRename = NULL; + if (same) + return FALSE; + } + CComPtr pParent; LPCITEMIDLIST pidlChild; BOOL RenamedCurrent = _IsCurrentLocation(info->absolutePidl) == S_OK; @@ -846,7 +874,19 @@ LRESULT CNSCBand::OnEndLabelEdit(_In_ LPNMTVDISPINFO dispInfo) CComHeapPtr pidlNewAbs(ILCombine(pidlParent, pidlNew)); if (RenamedCurrent) { - _UpdateBrowser(pidlNewAbs); + // Get the new item name from the folder because RegItems can be renamed to their + // default name by the folder (which is not the string we have in NMTVDISPINFO). + WCHAR wszDisplayName[MAX_PATH]; + if (SUCCEEDED(_GetNameOfItem(pParent, pidlNew, wszDisplayName))) + { + TVITEMW tvi; + tvi.mask = TVIF_TEXT; + tvi.hItem = dispInfo->item.hItem; + tvi.pszText = wszDisplayName; + AllowTreeSetNewName = !m_hwndTreeView.SetItem(&tvi); + } + + _UpdateBrowser(pidlNewAbs, TRUE); } else { @@ -854,7 +894,7 @@ LRESULT CNSCBand::OnEndLabelEdit(_In_ LPNMTVDISPINFO dispInfo) SHChangeNotify(SHCNE_RENAMEFOLDER, SHCNF_IDLIST, info->absolutePidl, pidlNewAbs); } - return TRUE; + return AllowTreeSetNewName; } return FALSE; @@ -960,7 +1000,7 @@ LRESULT CNSCBand::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &b ClientToScreen(&pt); } - CItemData *info = GetItemData(hItem); + CItemData *info = _GetItemData(hItem); if (!info) { ERR("No node data, something has gone wrong\n"); @@ -991,6 +1031,7 @@ LRESULT CNSCBand::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &b hr = contextMenu->QueryContextMenu(menuTemp, 0, idCmdFirst, FCIDM_SHVIEWLAST, cmf); if (FAILED_UNEXPECTEDLY(hr)) return 0; + SHELL_RemoveVerb(contextMenu, idCmdFirst, menuTemp, L"link"); enum { flags = TPM_LEFTALIGN | TPM_RETURNCMD | TPM_LEFTBUTTON | TPM_RIGHTBUTTON }; UINT uCommand = ::TrackPopupMenu(menuTemp, flags, pt.x, pt.y, 0, m_hWnd, NULL); @@ -1244,14 +1285,46 @@ STDMETHODIMP CNSCBand::HasFocusIO() STDMETHODIMP CNSCBand::TranslateAcceleratorIO(LPMSG lpMsg) { + BOOL SkipAccelerators = m_isEditing || (!IsChild(lpMsg->hwnd) && lpMsg->hwnd != m_hWnd); + if (lpMsg->message == WM_KEYDOWN && lpMsg->wParam == VK_F2 && !SkipAccelerators) + { + if (HTREEITEM hItem = m_hwndTreeView.GetNextItem(NULL, TVGN_CARET)) + { + if (_GetAttributesOfItem(_GetItemData(hItem), SFGAO_CANRENAME)) + { + m_hwndTreeView.SetFocus(); + m_hwndTreeView.EditLabel(hItem); + return S_OK; + } + } + } + + if (lpMsg->message == WM_SYSKEYDOWN && lpMsg->wParam == VK_RETURN && !SkipAccelerators) + { + CItemData *pItem = _GetItemData(TVGN_CARET); + if (pItem && _GetAttributesOfItem(pItem, SFGAO_HASPROPSHEET)) + { + SHELLEXECUTEINFOW sei = { sizeof(sei), SEE_MASK_INVOKEIDLIST, m_hwndTreeView }; + sei.lpVerb = L"properties"; + sei.lpIDList = pItem->absolutePidl; + sei.nShow = SW_SHOW; + ShellExecuteExW(&sei); + return S_OK; + } + else + { + MessageBeep(0xFFFFFFFF); + } + } + if (lpMsg->hwnd == m_hWnd || (m_isEditing && IsChild(lpMsg->hwnd))) { + // TODO: Why is it doing this for m_hWnd for all messages?! TranslateMessage(lpMsg); DispatchMessage(lpMsg); return S_OK; } - return S_FALSE; } @@ -1411,7 +1484,7 @@ STDMETHODIMP CNSCBand::DragOver(DWORD glfKeyState, POINTL pt, DWORD *pdwEffect) if (info.hItem != m_childTargetNode) { - CItemData *pItemData = GetItemData(info.hItem); + CItemData *pItemData = _GetItemData(info.hItem); if (!pItemData) return E_FAIL; diff --git a/dll/win32/shdocvw/CNSCBand.h b/dll/win32/shdocvw/CNSCBand.h index f6c06afeb98a0..bb686bc48233c 100644 --- a/dll/win32/shdocvw/CNSCBand.h +++ b/dll/win32/shdocvw/CNSCBand.h @@ -41,7 +41,11 @@ class CNSCBand CComHeapPtr relativePidl; BOOL expanded = FALSE; }; - CItemData* GetItemData(_In_ HTREEITEM hItem); + CItemData* _GetItemData(_In_ HTREEITEM hItem); + CItemData* _GetItemData(_In_ UINT ItemSpec = TVGN_CARET); + SFGAOF _GetAttributesOfItem(_In_ CItemData *pData, _In_ SFGAOF Query); + HRESULT _GetNameOfItem(IShellFolder *pSF, PCUITEMID_CHILD pidl, UINT Flags, PWSTR Name); + HRESULT _GetNameOfItem(IShellFolder *pSF, PCUITEMID_CHILD pidl, PWSTR Name); // *** IOleWindow methods *** STDMETHODIMP GetWindow(HWND *lphwnd) override; @@ -144,6 +148,7 @@ class CNSCBand HTREEITEM m_oldSelected = NULL; DWORD m_adviseCookie = 0; ULONG m_shellRegID = 0; + PWSTR m_OriginalRename = NULL; // *** Drop target information *** CComPtr m_pDropTarget; @@ -189,7 +194,7 @@ class CNSCBand _In_ LPCITEMIDLIST pEltRelative, _In_ BOOL bSort); BOOL _InsertSubitems(HTREEITEM hItem, LPCITEMIDLIST entry); - HRESULT _UpdateBrowser(LPCITEMIDLIST pidlGoto); + HRESULT _UpdateBrowser(LPCITEMIDLIST pidlGoto, BOOL IgnoreSelfNavigation = FALSE); HRESULT _GetCurrentLocation(_Out_ PIDLIST_ABSOLUTE *ppidl); HRESULT _IsCurrentLocation(_In_ PCIDLIST_ABSOLUTE pidl); void _Refresh(); diff --git a/dll/win32/shdocvw/shdocvw.spec b/dll/win32/shdocvw/shdocvw.spec index 0a8bd10cd848c..22f99fa9dda1e 100644 --- a/dll/win32/shdocvw/shdocvw.spec +++ b/dll/win32/shdocvw/shdocvw.spec @@ -3,12 +3,12 @@ 103 stub -noname CreateShortcutInDirW # FIXME: Inspect 104 stdcall -noname WhichPlatformFORWARD() 105 stub -noname CreateShortcutInDirEx # FIXME: Inspect -106 stub AddUrlToFavorites +106 stdcall AddUrlToFavorites(ptr wstr wstr long) @ stdcall -private DllCanUnloadNow() @ stdcall -private DllGetClassObject(ptr ptr ptr) @ stdcall -private DllGetVersion(ptr) 110 stdcall -noname WinList_Init() -111 stub -noname WinList_Terminate +111 stdcall -noname WinList_Terminate() @ stdcall -private DllInstall(long wstr) @ stdcall -private DllRegisterServer() @ stub DllRegisterWindowClasses @@ -74,11 +74,11 @@ 174 stub -noname SHIsGlobalOffline 175 stub -noname DetectAndFixAssociations 176 stub -noname EnsureWebViewRegSettings -177 stub -noname WinList_NotifyNewLocation -178 stub -noname WinList_FindFolderWindow -179 stub -noname WinList_GetShellWindows -180 stub -noname WinList_RegisterPending -181 stub -noname WinList_Revoke +177 stdcall -noname WinList_NotifyNewLocation(ptr long ptr) +178 stdcall -noname WinList_FindFolderWindow(ptr long ptr ptr) +179 stdcall -noname WinList_GetShellWindows(long) +180 stdcall -noname WinList_RegisterPending(long ptr long ptr) +181 stdcall -noname WinList_Revoke(long) 182 stdcall SetQueryNetSessionCount(long) 183 stub -noname SHMapNbspToSp 184 stub SetShellOfflineState diff --git a/dll/win32/shdocvw/shdocvw_main.c b/dll/win32/shdocvw/shdocvw_main.c index c817bbb3c5f00..65e3c733c7970 100644 --- a/dll/win32/shdocvw/shdocvw_main.c +++ b/dll/win32/shdocvw/shdocvw_main.c @@ -236,6 +236,7 @@ static BOOL SHDOCVW_LoadShell32(void) return ((SHDOCVW_hshell32 = LoadLibraryA("shell32.dll")) != NULL); } +#ifndef __REACTOS__ /* See winlist.cpp */ /*********************************************************************** * @ (SHDOCVW.110) * @@ -247,6 +248,7 @@ DWORD WINAPI WinList_Init(void) FIXME("(), stub!\n"); return 0x0deadfeed; } +#endif /* ndef __REACTOS__ */ /*********************************************************************** * @ (SHDOCVW.118) diff --git a/dll/win32/shdocvw/utility.cpp b/dll/win32/shdocvw/utility.cpp index d9453696d3dce..a6dfcb93a58c8 100644 --- a/dll/win32/shdocvw/utility.cpp +++ b/dll/win32/shdocvw/utility.cpp @@ -3,16 +3,34 @@ * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) * PURPOSE: Utility routines * COPYRIGHT: Copyright 2024 Whindmar Saksit + * Copyright 2025 Katayama Hirofumi MZ */ #include "objects.h" +#include #include WINE_DEFAULT_DEBUG_CHANNEL(shdocvw); -#ifndef SHCIDS_CANONICALONLY -#define SHCIDS_CANONICALONLY 0x10000000L -#endif +static inline INT_PTR +GetMenuItemIdByPos(HMENU hMenu, UINT Pos) +{ + MENUITEMINFOW mii; + mii.cbSize = FIELD_OFFSET(MENUITEMINFOW, hbmpItem); /* USER32 version agnostic */ + mii.fMask = MIIM_ID; /* GetMenuItemID does not handle sub-menus, this does */ + mii.cch = 0; + return GetMenuItemInfoW(hMenu, Pos, TRUE, &mii) ? mii.wID : -1; +} + +static inline BOOL +IsMenuSeparator(HMENU hMenu, UINT Pos) +{ + MENUITEMINFOW mii; + mii.cbSize = FIELD_OFFSET(MENUITEMINFOW, hbmpItem); /* USER32 version agnostic */ + mii.fMask = MIIM_FTYPE; + mii.cch = 0; + return GetMenuItemInfoW(hMenu, Pos, TRUE, &mii) && (mii.fType & MFT_SEPARATOR); +} EXTERN_C HRESULT SHELL_GetIDListFromObject(IUnknown *punk, PIDLIST_ABSOLUTE *ppidl) @@ -71,6 +89,36 @@ SHELL_IsVerb(IContextMenu *pcm, UINT_PTR idCmd, LPCWSTR Verb) return FALSE; } +static int +SHELL_FindVerbPos(IContextMenu *pcm, UINT idCmdFirst, HMENU hMenu, LPCWSTR Verb) +{ + for (UINT i = 0, c = GetMenuItemCount(hMenu); i < c; ++i) + { + INT_PTR id = GetMenuItemIdByPos(hMenu, i); + if (id != -1 && SHELL_IsVerb(pcm, id - idCmdFirst, Verb)) + return i; + } + return -1; +} + +EXTERN_C VOID +SHELL_RemoveVerb(IContextMenu *pcm, UINT idCmdFirst, HMENU hMenu, LPCWSTR Verb) +{ + int nPos = SHELL_FindVerbPos(pcm, idCmdFirst, hMenu, Verb); + if (nPos < 0) + return; + int nCount = GetMenuItemCount(hMenu); + BOOL bSepBefore = nPos && IsMenuSeparator(hMenu, nPos - 1); + BOOL bSepAfter = IsMenuSeparator(hMenu, nPos + 1); + if (DeleteMenu(hMenu, nPos, MF_BYPOSITION)) + { + if ((bSepBefore && bSepAfter) || (bSepAfter && nPos == 0)) + DeleteMenu(hMenu, nPos, MF_BYPOSITION); + else if (bSepBefore && nPos + 1 == nCount) + DeleteMenu(hMenu, nPos - 1, MF_BYPOSITION); + } +} + EXTERN_C BOOL _ILIsDesktop(LPCITEMIDLIST pidl) { @@ -93,3 +141,89 @@ IEILIsEqual( FIXME("%p, %p\n", pidl1, pidl2); return FALSE; } + +static VOID +SHDOCVW_PathDeleteInvalidChars(LPWSTR pszDisplayName) +{ +#define PATH_VALID_ELEMENT ( \ + PATH_CHAR_CLASS_DOT | PATH_CHAR_CLASS_SEMICOLON | PATH_CHAR_CLASS_COMMA | \ + PATH_CHAR_CLASS_SPACE | PATH_CHAR_CLASS_OTHER_VALID \ +) + PWCHAR pch, pchSrc; + for (pch = pchSrc = pszDisplayName; *pchSrc; ++pchSrc) + { + if (PathIsValidCharW(*pchSrc, PATH_VALID_ELEMENT)) + *pch++ = *pchSrc; + } + *pch = UNICODE_NULL; +} + +static HRESULT +SHDOCVW_CreateShortcut( + _In_ LPCWSTR pszLnkFileName, + _In_ PCIDLIST_ABSOLUTE pidlTarget, + _In_opt_ LPCWSTR pszDescription) +{ + HRESULT hr; + + CComPtr psl; + hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, + IID_PPV_ARG(IShellLink, &psl)); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + + psl->SetIDList(pidlTarget); + + if (pszDescription) + psl->SetDescription(pszDescription); + + CComPtr ppf; + hr = psl->QueryInterface(IID_PPV_ARG(IPersistFile, &ppf)); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + + return ppf->Save(pszLnkFileName, TRUE); +} + +/************************************************************************* + * AddUrlToFavorites [SHDOCVW.106] + */ +EXTERN_C HRESULT WINAPI +AddUrlToFavorites( + _In_ HWND hwnd, + _In_ LPCWSTR pszUrlW, + _In_opt_ LPCWSTR pszTitleW, + _In_ BOOL fDisplayUI) +{ + TRACE("%p, %s, %s, %d\n", hwnd, wine_dbgstr_w(pszUrlW), wine_dbgstr_w(pszTitleW), fDisplayUI); + + if (fDisplayUI) + FIXME("fDisplayUI\n"); // NOTE: Use SHBrowseForFolder callback + + if (PathIsURLW(pszUrlW)) + FIXME("Internet Shortcut\n"); + + CComHeapPtr pidl; + HRESULT hr = SHParseDisplayName(pszUrlW, NULL, &pidl, 0, NULL); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + + // Get title + WCHAR szTitle[MAX_PATH]; + if (pszTitleW) + StringCchCopyW(szTitle, _countof(szTitle), pszTitleW); + else + ILGetDisplayNameEx(NULL, pidl, szTitle, ILGDN_NORMAL); + + // Delete invalid characters + SHDOCVW_PathDeleteInvalidChars(szTitle); + + // Build shortcut pathname + WCHAR szPath[MAX_PATH]; + if (!SHGetSpecialFolderPathW(hwnd, szPath, CSIDL_FAVORITES, TRUE)) + return E_FAIL; + PathAppendW(szPath, szTitle); + PathAddExtensionW(szPath, L".lnk"); + + return SHDOCVW_CreateShortcut(szPath, pidl, NULL); +} diff --git a/dll/win32/shdocvw/utility.h b/dll/win32/shdocvw/utility.h index 46399da02f1ce..3368ecc735651 100644 --- a/dll/win32/shdocvw/utility.h +++ b/dll/win32/shdocvw/utility.h @@ -10,4 +10,6 @@ EXTERN_C HRESULT SHELL_GetIDListFromObject(IUnknown *punk, PIDLIST_ABSOLUTE *ppidl); EXTERN_C BOOL SHELL_IsEqualAbsoluteID(PCIDLIST_ABSOLUTE a, PCIDLIST_ABSOLUTE b); EXTERN_C BOOL SHELL_IsVerb(IContextMenu *pcm, UINT_PTR idCmd, LPCWSTR Verb); +EXTERN_C VOID SHELL_RemoveVerb(IContextMenu *pcm, UINT idCmdFirst, HMENU hMenu, LPCWSTR Verb); EXTERN_C BOOL _ILIsDesktop(LPCITEMIDLIST pidl); + diff --git a/dll/win32/shdocvw/winlist.cpp b/dll/win32/shdocvw/winlist.cpp new file mode 100644 index 0000000000000..72562d77b427e --- /dev/null +++ b/dll/win32/shdocvw/winlist.cpp @@ -0,0 +1,255 @@ +/* + * PROJECT: ReactOS shdocvw + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: CLSID_ShellWindows and WinList_* functions + * COPYRIGHT: Copyright 2025 Katayama Hirofumi MZ + */ + +#include "objects.h" + +#include +WINE_DEFAULT_DEBUG_CHANNEL(shdocvw); + +static VARIANT s_vaEmpty = { VT_EMPTY }; + +static HRESULT +InitVariantFromBuffer( + _Out_ LPVARIANTARG pvarg, + _In_ LPCVOID pv, + _In_ SIZE_T cb) +{ + VariantInit(pvarg); + + LPSAFEARRAY pArray = SafeArrayCreateVector(VT_UI1, 0, cb); + if (!pArray) + { + ERR("!pArray\n"); + return E_OUTOFMEMORY; + } + + V_ARRAY(pvarg) = pArray; + V_VT(pvarg) = VT_ARRAY | VT_UI1; + CopyMemory(pArray->pvData, pv, cb); + return S_OK; +} + +static HRESULT +InitVariantFromIDList( + _Out_ LPVARIANTARG pvarg, + _In_ LPCITEMIDLIST pidl) +{ + return InitVariantFromBuffer(pvarg, pidl, ILGetSize(pidl)); +} + +static HRESULT +VariantClearLazy(_Inout_ LPVARIANTARG pvarg) +{ + switch (V_VT(pvarg)) + { + case VT_EMPTY: + case VT_BOOL: + case VT_I4: + case VT_UI4: + break; + case VT_UNKNOWN: + if (V_UNKNOWN(pvarg)) + V_UNKNOWN(pvarg)->Release(); + break; + case VT_DISPATCH: + if (V_DISPATCH(pvarg)) + V_DISPATCH(pvarg)->Release(); + break; + case VT_SAFEARRAY: + SafeArrayDestroy(V_ARRAY(pvarg)); + break; + default: + return VariantClear(pvarg); + } + V_VT(pvarg) = VT_EMPTY; + return S_OK; +} + +/************************************************************************* + * WinList_Init (SHDOCVW.110) + * + * Retired in NT 6.1. + */ +EXTERN_C +BOOL WINAPI +WinList_Init(VOID) +{ + FIXME("()\n"); + return FALSE; +} + +/************************************************************************* + * WinList_Terminate (SHDOCVW.111) + * + * NT 4.71 and higher. Retired in NT 6.1. + */ +EXTERN_C +VOID WINAPI +WinList_Terminate(VOID) +{ + FIXME("()\n"); +} + +/************************************************************************* + * WinList_GetShellWindows (SHDOCVW.179) + * + * NT 5.0 and higher. + * @see https://learn.microsoft.com/en-us/windows/win32/api/exdisp/nn-exdisp-ishellwindows + */ +EXTERN_C +IShellWindows* WINAPI +WinList_GetShellWindows( + _In_ BOOL bCreate) +{ + FIXME("(%d)\n", bCreate); + return NULL; +} + +/************************************************************************* + * WinList_NotifyNewLocation (SHDOCVW.177) + * + * NT 5.0 and higher. + * @see https://learn.microsoft.com/en-us/windows/win32/api/exdisp/nf-exdisp-ishellwindows-onnavigate + */ +EXTERN_C +HRESULT WINAPI +WinList_NotifyNewLocation( + _In_ IShellWindows *pShellWindows, + _In_ LONG lCookie, + _In_ LPCITEMIDLIST pidl) +{ + TRACE("(%p, %ld, %p)\n", pShellWindows, lCookie, pidl); + + if (!pidl) + { + ERR("!pidl\n"); + return E_UNEXPECTED; + } + + VARIANTARG varg; + HRESULT hr = InitVariantFromIDList(&varg, pidl); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + + hr = pShellWindows->OnNavigate(lCookie, &varg); + VariantClearLazy(&varg); + return hr; +} + +/************************************************************************* + * WinList_FindFolderWindow (SHDOCVW.178) + * + * NT 5.0 and higher. + * @see https://learn.microsoft.com/en-us/windows/win32/api/exdisp/nf-exdisp-ishellwindows-findwindowsw + */ +EXTERN_C +HRESULT WINAPI +WinList_FindFolderWindow( + _In_ LPCITEMIDLIST pidl, + _In_ DWORD dwUnused, + _Out_opt_ PLONG phwnd, // Stores a window handle but LONG type + _Out_opt_ IWebBrowserApp **ppWebBrowserApp) +{ + UNREFERENCED_PARAMETER(dwUnused); + + TRACE("(%p, %ld, %p, %p)\n", pidl, dwUnused, phwnd, ppWebBrowserApp); + + if (ppWebBrowserApp) + *ppWebBrowserApp = NULL; + + if (phwnd) + *phwnd = 0; + + if (!pidl) + { + ERR("!pidl\n"); + return E_UNEXPECTED; + } + + CComPtr pShellWindows(WinList_GetShellWindows(ppWebBrowserApp != NULL)); + if (!pShellWindows) + { + ERR("!pShellWindows\n"); + return E_UNEXPECTED; + } + + VARIANTARG varg; + HRESULT hr = InitVariantFromIDList(&varg, pidl); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + + CComPtr pDispatch; + const INT options = SWFO_INCLUDEPENDING | (ppWebBrowserApp ? SWFO_NEEDDISPATCH : 0); + hr = pShellWindows->FindWindowSW(&varg, &s_vaEmpty, SWC_BROWSER, phwnd, options, &pDispatch); + if (pDispatch && ppWebBrowserApp) + hr = pDispatch->QueryInterface(IID_PPV_ARG(IWebBrowserApp, ppWebBrowserApp)); + + VariantClearLazy(&varg); + return hr; +} + +/************************************************************************* + * WinList_RegisterPending (SHDOCVW.180) + * + * NT 5.0 and higher. + * @see https://learn.microsoft.com/en-us/windows/win32/api/exdisp/nf-exdisp-ishellwindows-registerpending + */ +EXTERN_C +HRESULT WINAPI +WinList_RegisterPending( + _In_ DWORD dwThreadId, + _In_ LPCITEMIDLIST pidl, + _In_ DWORD dwUnused, + _Out_ PLONG plCookie) +{ + TRACE("(%ld, %p, %ld, %p)\n", dwThreadId, pidl, dwUnused, plCookie); + + if (!pidl) + { + ERR("!pidl\n"); + return E_UNEXPECTED; + } + + CComPtr pShellWindows(WinList_GetShellWindows(FALSE)); + if (!pShellWindows) + { + ERR("!pShellWindows\n"); + return E_UNEXPECTED; + } + + VARIANTARG varg; + HRESULT hr = InitVariantFromIDList(&varg, pidl); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + + hr = pShellWindows->RegisterPending(dwThreadId, &varg, &s_vaEmpty, SWC_BROWSER, plCookie); + VariantClearLazy(&varg); + return hr; +} + +/************************************************************************* + * WinList_Revoke (SHDOCVW.181) + * + * NT 5.0 and higher. + * @see https://learn.microsoft.com/en-us/windows/win32/api/exdisp/nf-exdisp-ishellwindows-revoke + */ +EXTERN_C +HRESULT WINAPI +WinList_Revoke( + _In_ LONG lCookie) +{ + TRACE("(%ld)\n", lCookie); + + CComPtr pShellWindows(WinList_GetShellWindows(TRUE)); + if (!pShellWindows) + { + ERR("!pShellWindows\n"); + return E_FAIL; + } + + return pShellWindows->Revoke(lCookie); +} diff --git a/dll/win32/shell32/CCopyAsPathMenu.cpp b/dll/win32/shell32/CCopyAsPathMenu.cpp index f031874c5d405..3f8f43aeb2dba 100644 --- a/dll/win32/shell32/CCopyAsPathMenu.cpp +++ b/dll/win32/shell32/CCopyAsPathMenu.cpp @@ -103,6 +103,12 @@ CCopyAsPathMenu::DoCopyAsPath(IDataObject *pdto) return hr; } +static const CMVERBMAP g_VerbMap[] = +{ + { "copyaspath", IDC_COPYASPATH }, + { NULL } +}; + STDMETHODIMP CCopyAsPathMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags) { @@ -133,7 +139,8 @@ CCopyAsPathMenu::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi) { TRACE("CCopyAsPathMenu::InvokeCommand(%p %p)\n", this, lpcmi); - if (IS_INTRESOURCE(lpcmi->lpVerb) && LOWORD(lpcmi->lpVerb) == IDC_COPYASPATH) + int CmdId = SHELL_MapContextMenuVerbToCmdId(lpcmi, g_VerbMap); + if (CmdId == IDC_COPYASPATH) return DoCopyAsPath(m_pDataObject); return E_FAIL; @@ -142,10 +149,9 @@ CCopyAsPathMenu::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi) STDMETHODIMP CCopyAsPathMenu::GetCommandString(UINT_PTR idCommand, UINT uFlags, UINT *lpReserved, LPSTR lpszName, UINT uMaxNameLen) { - FIXME("CCopyAsPathMenu::GetCommandString(%p %lu %u %p %p %u)\n", this, + TRACE("CCopyAsPathMenu::GetCommandString(%p %lu %u %p %p %u)\n", this, idCommand, uFlags, lpReserved, lpszName, uMaxNameLen); - - return E_NOTIMPL; + return SHELL_GetCommandStringImpl(idCommand, uFlags, lpszName, uMaxNameLen, g_VerbMap); } STDMETHODIMP diff --git a/dll/win32/shell32/CDefView.cpp b/dll/win32/shell32/CDefView.cpp index d4c8ed82cab9e..953d7f133d322 100644 --- a/dll/win32/shell32/CDefView.cpp +++ b/dll/win32/shell32/CDefView.cpp @@ -238,6 +238,7 @@ class CDefView : CComPtr m_pCommDlgBrowser; CComPtr m_pFolderFilter; CComPtr m_pShellFolderViewDual; + ClipboardViewerChain m_ClipboardChain; CListView m_ListView; HWND m_hWndParent; FOLDERSETTINGS m_FolderSettings; @@ -272,8 +273,10 @@ class CDefView : CComPtr m_pFileMenu; BOOL m_isEditing; - BOOL m_isParentFolderSpecial; + signed char m_SpecialFolder; + bool m_isFullStatusBar; bool m_ScheduledStatusbarUpdate; + bool m_HasCutItems; CLSID m_Category; BOOL m_Destroyed; @@ -292,6 +295,12 @@ class CDefView : void _DoCopyToMoveToFolder(BOOL bCopy); BOOL IsDesktop() const { return m_FolderSettings.fFlags & FWF_DESKTOP; } + inline BOOL IsSpecialFolder(int &csidl) const + { + csidl = m_SpecialFolder; + return m_SpecialFolder >= 0; + } + public: CDefView(); ~CDefView(); @@ -300,6 +309,7 @@ class CDefView : HRESULT OnDefaultCommand(); HRESULT OnStateChange(UINT uFlags); void UpdateStatusbar(); + void UpdateStatusbarLocation(); void CheckToolbar(); BOOL CreateList(); void UpdateListColors(); @@ -313,13 +323,17 @@ class CDefView : HRESULT LoadColumn(UINT FoldCol, UINT ListCol, BOOL Insert, UINT ForceWidth = 0); HRESULT LoadColumns(SIZE_T *pColList = NULL, UINT ColListCount = 0); void ColumnListChanged(); + SFGAOF GetItemAttributes(PCUITEMID_CHILD pidl, UINT Query); + SFGAOF GetItemAttributes(int i, UINT Query); + void RefreshGhostedState(); PCUITEMID_CHILD _PidlByItem(int i); PCUITEMID_CHILD _PidlByItem(LVITEM& lvItem); int LV_FindItemByPidl(PCUITEMID_CHILD pidl); int LV_AddItem(PCUITEMID_CHILD pidl); BOOLEAN LV_DeleteItem(PCUITEMID_CHILD pidl); BOOLEAN LV_RenameItem(PCUITEMID_CHILD pidlOld, PCUITEMID_CHILD pidlNew); - BOOLEAN LV_UpdateItem(PCUITEMID_CHILD pidl); + BOOL LV_UpdateItem(INT nItem, PCUITEMID_CHILD pidl); + BOOL LV_UpdateItem(PCUITEMID_CHILD pidl); void LV_RefreshIcon(INT iItem); void LV_RefreshIcons(); static INT CALLBACK fill_list(LPVOID ptr, LPVOID arg); @@ -331,6 +345,7 @@ class CDefView : HRESULT CheckViewMode(HMENU hmenuView); LRESULT DoColumnContextMenu(LRESULT lParam); UINT GetSelections(); + SFGAOF GetSelectionAttributes(SFGAOF Query); HRESULT OpenSelectedItems(); void OnDeactivate(); void DoActivate(UINT uState); @@ -485,6 +500,8 @@ class CDefView : LRESULT OnCustomItem(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); LRESULT OnSettingChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); LRESULT OnInitMenuPopup(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); + LRESULT OnChangeCBChain(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); + LRESULT OnDrawClipboard(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); virtual VOID OnFinalMessage(HWND) override; @@ -501,7 +518,7 @@ class CDefView : return wc; } - virtual WNDPROC GetWindowProc() + virtual WNDPROC GetWindowProc() override { return WindowProc; } @@ -542,6 +559,8 @@ class CDefView : MESSAGE_HANDLER(CWM_GETISHELLBROWSER, OnGetShellBrowser) MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange) MESSAGE_HANDLER(WM_INITMENUPOPUP, OnInitMenuPopup) + MESSAGE_HANDLER(WM_CHANGECBCHAIN, OnChangeCBChain) + MESSAGE_HANDLER(WM_DRAWCLIPBOARD, OnDrawClipboard) END_MSG_MAP() BEGIN_COM_MAP(CDefView) @@ -590,8 +609,10 @@ CDefView::CDefView() : m_iDragOverItem(0), m_cScrollDelay(0), m_isEditing(FALSE), - m_isParentFolderSpecial(FALSE), + m_SpecialFolder(-1), + m_isFullStatusBar(true), m_ScheduledStatusbarUpdate(false), + m_HasCutItems(false), m_Destroyed(FALSE) { ZeroMemory(&m_FolderSettings, sizeof(m_FolderSettings)); @@ -709,8 +730,8 @@ void CDefView::CheckToolbar() void CDefView::UpdateStatusbar() { - WCHAR szFormat[MAX_PATH] = {0}; - WCHAR szPartText[MAX_PATH] = {0}; + WCHAR szFormat[MAX_PATH]; + WCHAR szPartText[MAX_PATH]; UINT cSelectedItems; if (!m_ListView) @@ -732,11 +753,10 @@ void CDefView::UpdateStatusbar() m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXT, 0, (LPARAM)szPartText, &lResult); // Don't bother with the extra processing if we only have one StatusBar part - if (!m_isParentFolderSpecial) + if (m_isFullStatusBar) { UINT64 uTotalFileSize = 0; WORD uFileFlags = LVNI_ALL; - LPARAM pIcon = NULL; INT nItem = -1; bool bIsOnlyFoldersSelected = true; @@ -761,25 +781,11 @@ void CDefView::UpdateStatusbar() // Don't show the file size text if there is 0 bytes in the folder // OR we only have folders selected if ((cSelectedItems && !bIsOnlyFoldersSelected) || uTotalFileSize) - { StrFormatByteSizeW(uTotalFileSize, szPartText, _countof(szPartText)); - } else - { *szPartText = 0; - } m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXT, 1, (LPARAM)szPartText, &lResult); - - // If we are in a Recycle Bin then show no text for the location part - if (!_ILIsBitBucket(m_pidlParent)) - { - LoadStringW(shell32_hInstance, IDS_MYCOMPUTER, szPartText, _countof(szPartText)); - pIcon = (LPARAM)m_hMyComputerIcon; - } - - m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETICON, 2, pIcon, &lResult); - m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXT, 2, (LPARAM)szPartText, &lResult); } SFGAOF att = 0; @@ -794,6 +800,32 @@ void CDefView::UpdateStatusbar() m_pShellBrowser->SendControlMsg(FCW_TOOLBAR, TB_ENABLEBUTTON, FCIDM_SHVIEW_MOVETO, (att & SFGAO_CANMOVE) != 0, &lResult); } +void CDefView::UpdateStatusbarLocation() +{ + LRESULT lResult; + LPARAM pIcon = NULL; + WCHAR szPartText[MAX_PATH]; + *szPartText = 0; + if (m_isFullStatusBar) + { + // If we are in a Recycle Bin then show no text for the location part + int csidl; + if (!IsSpecialFolder(csidl) || (csidl != CSIDL_NETWORK && csidl != CSIDL_BITBUCKET)) + { + LoadStringW(shell32_hInstance, IDS_MYCOMPUTER, szPartText, _countof(szPartText)); + pIcon = (LPARAM)m_hMyComputerIcon; + } + /*else if (csidl == CSIDL_NETWORK) // TODO: Figure out the type of share (My Computer/Local Intranet/Internet?) + { + ImageList_GetIconSize(ListView_GetImageList(m_ListView, LVSIL_SMALL), &x, &y); + pIcon = (LPARAM)LoadImage(shell32_hInstance, MAKEINTRESOURCEW(IDI_SHELL_MY_NETWORK_PLACES), + IMAGE_ICON, x, y, LR_SHARED); + }*/ + } + m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETICON, 2, pIcon, &lResult); + m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXT, 2, (LPARAM)szPartText, &lResult); +} + LRESULT CDefView::OnUpdateStatusbar(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) { m_ScheduledStatusbarUpdate = false; @@ -828,7 +860,9 @@ BOOL CDefView::CreateList() { dwStyle |= LVS_SHOWSELALWAYS; // MSDN says FWF_SHOWSELALWAYS is deprecated, always turn on for folders dwStyle |= (m_FolderSettings.fFlags & FWF_ALIGNLEFT) ? LVS_ALIGNLEFT : LVS_ALIGNTOP; +#if 0 // FIXME: Temporarily disabled until ListView is fixed (CORE-19624, CORE-19818) ListExStyle |= LVS_EX_DOUBLEBUFFER; +#endif } ViewMode = m_FolderSettings.ViewMode; @@ -1025,7 +1059,7 @@ HRESULT CDefView::GetDetailsByFolderColumn(PCUITEMID_CHILD pidl, UINT FoldCol, S { // According to learn.microsoft.com/en-us/windows/win32/shell/sfvm-getdetailsof // the query order is IShellFolder2, IShellDetails, SFVM_GETDETAILSOF. - HRESULT hr; + HRESULT hr = E_FAIL; if (m_pSF2Parent) { hr = m_pSF2Parent->GetDetailsOf(pidl, FoldCol, &sd); @@ -1196,6 +1230,7 @@ void CDefView::ColumnListChanged() break; HRESULT foldCol = MapListColumnToFolderColumn(listCol); assert(SUCCEEDED(foldCol)); + DBG_UNREFERENCED_LOCAL_VARIABLE(foldCol); AppendMenuItem(m_hMenuArrangeModes, MF_STRING, DVIDM_ARRANGESORT_FIRST + listCol, lvc.pszText, listCol); } @@ -1285,6 +1320,18 @@ BOOL CDefView::_Sort(int Col) return m_ListView.SortItems(ListViewCompareItems, this); } +SFGAOF CDefView::GetItemAttributes(PCUITEMID_CHILD pidl, UINT Query) +{ + SFGAOF Attr = (SFGAOF)Query; + return SUCCEEDED(m_pSFParent->GetAttributesOf(1, &pidl, &Attr)) ? (Attr & Query) : 0; +} + +SFGAOF CDefView::GetItemAttributes(int i, UINT Query) +{ + PCUITEMID_CHILD pItem = _PidlByItem(i); + return pItem ? GetItemAttributes(pItem, Query) : 0; +} + PCUITEMID_CHILD CDefView::_PidlByItem(int i) { if (!m_ListView) @@ -1318,6 +1365,7 @@ int CDefView::LV_FindItemByPidl(PCUITEMID_CHILD pidl) { for (i = 0; i < cItems; i++) { + //FIXME: ILIsEqual needs absolute pidls! currentpidl = _PidlByItem(i); if (ILIsEqual(pidl, currentpidl)) return i; @@ -1339,13 +1387,15 @@ int CDefView::LV_AddItem(PCUITEMID_CHILD pidl) if (_DoFolderViewCB(SFVM_ADDINGOBJECT, 0, (LPARAM)pidl) == S_FALSE) return -1; - lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; // set mask + lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE; lvItem.iItem = m_ListView.GetItemCount(); // add item to lists end lvItem.iSubItem = 0; lvItem.lParam = reinterpret_cast(ILClone(pidl)); // set item's data lvItem.pszText = LPSTR_TEXTCALLBACKW; // get text on a callback basis lvItem.iImage = I_IMAGECALLBACK; // get image on a callback basis lvItem.stateMask = LVIS_CUT; + if (m_HasCutItems) + lvItem.state = GetItemAttributes(pidl, SFGAO_HIDDEN | SFGAO_GHOSTED) ? LVIS_CUT : 0; return m_ListView.InsertItem(&lvItem); } @@ -1406,31 +1456,38 @@ BOOLEAN CDefView::LV_RenameItem(PCUITEMID_CHILD pidlOld, PCUITEMID_CHILD pidlNew return FALSE; } -BOOLEAN CDefView::LV_UpdateItem(PCUITEMID_CHILD pidl) +BOOL CDefView::LV_UpdateItem(INT nItem, PCUITEMID_CHILD pidl) { - int nItem; + BOOL bResult = FALSE; LVITEMW lvItem; - - TRACE("(%p)(pidl=%p)\n", this, pidl); - - ASSERT(m_ListView); - - nItem = LV_FindItemByPidl(pidl); - - if (-1 != nItem) + if (nItem >= 0) { - _DoFolderViewCB(SFVM_UPDATINGOBJECT, 0, (LPARAM)pidl); + _DoFolderViewCB(SFVM_UPDATINGOBJECT, nItem, (LPARAM)pidl); - lvItem.mask = LVIF_IMAGE; + lvItem.mask = LVIF_IMAGE | LVIF_STATE; lvItem.iItem = nItem; lvItem.iSubItem = 0; lvItem.iImage = SHMapPIDLToSystemImageListIndex(m_pSFParent, pidl, 0); - m_ListView.SetItem(&lvItem); - m_ListView.Update(nItem); - return TRUE; + lvItem.stateMask = LVIS_CUT; + if (m_HasCutItems) + lvItem.state = GetItemAttributes(pidl, SFGAO_HIDDEN | SFGAO_GHOSTED) ? LVIS_CUT : 0; + PCUITEMID_CHILD pidlOld = _PidlByItem(nItem); + if (pidlOld && (lvItem.lParam = reinterpret_cast(ILClone(pidl))) != NULL) + lvItem.mask |= LVIF_PARAM; + bResult = m_ListView.SetItem(&lvItem); + if (bResult && lvItem.lParam && pidlOld) + ILFree(const_cast(pidlOld)); + for (UINT i = 0; m_ListView.SetItemText(nItem, i, LPSTR_TEXTCALLBACK); ++i) {} // Update all columns } + return bResult; +} - return FALSE; +BOOL CDefView::LV_UpdateItem(PCUITEMID_CHILD pidl) +{ + TRACE("(%p)(pidl=%p)\n", this, pidl); + ASSERT(m_ListView); + INT nItem = LV_FindItemByPidl(pidl); + return nItem >= 0 ? LV_UpdateItem(nItem, pidl) : FALSE; } void CDefView::LV_RefreshIcon(INT iItem) @@ -1519,7 +1576,7 @@ HRESULT CDefView::FillList(BOOL IsRefreshCommand) // copy the items into the array while((S_OK == pEnumIDList->Next(1, &pidl, &dwFetched)) && dwFetched) { - if (DPA_InsertPtr(hdpa, 0x7fff, pidl) == -1) + if (DPA_AppendPtr(hdpa, pidl) == -1) { SHFree(pidl); } @@ -1569,6 +1626,9 @@ HRESULT CDefView::FillList(BOOL IsRefreshCommand) m_ListView.InvalidateRect(NULL, TRUE); } + if (IsRefreshCommand) + UpdateStatusbarLocation(); + _DoFolderViewCB(SFVM_LISTREFRESHED, 0, 0); return S_OK; @@ -1592,14 +1652,20 @@ LRESULT CDefView::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHand if (!m_Destroyed) { m_Destroyed = TRUE; + RevokeDragDrop(m_hWnd); + SHChangeNotifyDeregister(m_hNotify); + m_hNotify = NULL; + m_ClipboardChain.Unhook(m_hWnd); + if (m_pFileMenu) + { + IUnknown_SetSite(m_pFileMenu, NULL); + m_pFileMenu = NULL; + } if (m_hMenu) { DestroyMenu(m_hMenu); m_hMenu = NULL; } - RevokeDragDrop(m_hWnd); - SHChangeNotifyDeregister(m_hNotify); - m_hNotify = NULL; SHFree(m_pidlParent); m_pidlParent = NULL; } @@ -1751,22 +1817,27 @@ LRESULT CDefView::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandl m_hAccel = LoadAcceleratorsW(shell32_hInstance, MAKEINTRESOURCEW(IDA_SHELLVIEW)); - BOOL bPreviousParentSpecial = m_isParentFolderSpecial; - - // A folder is special if it is the Desktop folder, - // a network folder, or a Control Panel folder - m_isParentFolderSpecial = IsDesktop() || _ILIsNetHood(m_pidlParent) - || _ILIsControlPanel(ILFindLastID(m_pidlParent)); - - // Only force StatusBar part refresh if the state - // changed from the previous folder - if (bPreviousParentSpecial != m_isParentFolderSpecial) + int bForceFullStatusBar = false; + BOOL bIsFileSystem = SHGetAttributes(NULL, m_pidlParent, SFGAO_FILESYSTEM) & SFGAO_FILESYSTEM; + m_SpecialFolder = bIsFileSystem ? -1 : 0x7f; // FS folder or "generic" CSIDL + if (_ILIsDesktop(m_pidlParent)) { - // This handles changing StatusBar parts - _ForceStatusBarResize(); + m_SpecialFolder = CSIDL_DESKTOP; } - + else if (IsEqualPersistClassID(ppf2, CLSID_RecycleBin)) + { + m_SpecialFolder = bForceFullStatusBar = CSIDL_BITBUCKET; + } + else if (bIsFileSystem) + { + CComHeapPtr pidlNet(SHCloneSpecialIDList(NULL, CSIDL_NETWORK, FALSE)); + if (ILIsParent(pidlNet, m_pidlParent, FALSE) && ILGetSize(pidlNet) < ILGetSize(m_pidlParent)) + m_SpecialFolder = CSIDL_NETWORK; + } + m_isFullStatusBar = bIsFileSystem || bForceFullStatusBar; + _ForceStatusBarResize(); // This handles changing StatusBar parts UpdateStatusbar(); + UpdateStatusbarLocation(); return S_OK; } @@ -1801,7 +1872,7 @@ HRESULT CDefView::FillFileMenu() HMENU hmenu = CreatePopupMenu(); - UINT cmf = GetContextMenuFlags(m_pShellBrowser, SFGAO_CANRENAME); + UINT cmf = GetContextMenuFlags(m_pShellBrowser, GetSelectionAttributes(SFGAO_CANRENAME)); hr = m_pFileMenu->QueryContextMenu(hmenu, 0, DVIDM_CONTEXTMENU_FIRST, DVIDM_CONTEXTMENU_LAST, cmf); if (FAILED_UNEXPECTEDLY(hr)) return hr; @@ -2061,6 +2132,14 @@ UINT CDefView::GetSelections() return m_cidl; } +SFGAOF CDefView::GetSelectionAttributes(SFGAOF Query) +{ + if (!GetSelections()) + return 0; + SFGAOF Attr = Query; + return SUCCEEDED(m_pSFParent->GetAttributesOf(m_cidl, m_apidl, &Attr)) ? (Attr & Query) : 0; +} + HRESULT CDefView::InvokeContextMenuCommand(CComPtr& pCM, LPCSTR lpVerb, POINT* pt) { CMINVOKECOMMANDINFOEX cmi; @@ -2192,7 +2271,7 @@ LRESULT CDefView::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &b if (FAILED_UNEXPECTEDLY(hResult)) return 0; - UINT cmf = GetContextMenuFlags(m_pShellBrowser, SFGAO_CANRENAME); + UINT cmf = GetContextMenuFlags(m_pShellBrowser, GetSelectionAttributes(SFGAO_CANRENAME)); // Use 1 as the first id we want. 0 means that user canceled the menu hResult = m_pCM->QueryContextMenu(m_hContextMenu, 0, CONTEXT_MENU_BASE_ID, DVIDM_CONTEXTMENU_LAST, cmf); if (FAILED_UNEXPECTEDLY(hResult)) @@ -2664,18 +2743,14 @@ LRESULT CDefView::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandl TRACE("-- text=%s\n", debugstr_w(lpdi->item.pszText)); } } - if(lpdi->item.mask & LVIF_IMAGE) /* image requested */ + if (lpdi->item.mask & LVIF_IMAGE) { lpdi->item.iImage = SHMapPIDLToSystemImageListIndex(m_pSFParent, pidl, 0); } - if(lpdi->item.mask & LVIF_STATE) + if (lpdi->item.mask & LVIF_STATE) { - ULONG attributes = SFGAO_HIDDEN; - if (SUCCEEDED(m_pSFParent->GetAttributesOf(1, &pidl, &attributes))) - { - if (attributes & SFGAO_HIDDEN) - lpdi->item.state |= LVIS_CUT; - } + if ((lpdi->item.stateMask & LVIS_CUT) && GetItemAttributes(pidl, SFGAO_HIDDEN | SFGAO_GHOSTED)) + lpdi->item.state |= LVIS_CUT; } lpdi->item.mask |= LVIF_DI_SETITEM; break; @@ -2735,73 +2810,77 @@ LRESULT CDefView::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandl break; case LVN_BEGINLABELEDITW: { - DWORD dwAttr = SFGAO_CANRENAME; - pidl = _PidlByItem(lpdi->item); - TRACE("-- LVN_BEGINLABELEDITW %p\n", this); + HWND hEdit = ListView_GetEditControl(m_ListView); + pidl = _PidlByItem(lpdi->item); + DWORD fAttr = pidl ? GetItemAttributes(pidl, SFGAO_CANRENAME | SFGAO_FOLDER | SFGAO_FILESYSTEM) : 0; + if (!hEdit || !(fAttr & SFGAO_CANRENAME)) + { + MessageBeep(0xffffffff); + return TRUE; + } - m_pSFParent->GetAttributesOf(1, &pidl, &dwAttr); - if (SFGAO_CANRENAME & dwAttr) + WCHAR szName[MAX_PATH], *pszText = lpdi->item.pszText; + if (SUCCEEDED(DisplayNameOfW(m_pSFParent, pidl, SHGDN_FOREDITING | SHGDN_INFOLDER, + szName, _countof(szName)))) { - HWND hEdit = reinterpret_cast(m_ListView.SendMessage(LVM_GETEDITCONTROL)); - SHLimitInputEdit(hEdit, m_pSFParent); + pszText = szName; + ::SetWindowText(hEdit, pszText); + } - // smartass-renaming: See CORE-15242 - if (!(dwAttr & SFGAO_FOLDER) && (dwAttr & SFGAO_FILESYSTEM) && - (lpdi->item.mask & LVIF_TEXT) && !SelectExtOnRename()) + // smartass-renaming: See CORE-15242 + if (!(fAttr & SFGAO_FOLDER) && (fAttr & SFGAO_FILESYSTEM) && + (lpdi->item.mask & LVIF_TEXT) && !SelectExtOnRename()) + { + CComHeapPtr pidlFull(ILCombine(m_pidlParent, pidl)); + WCHAR szFullPath[MAX_PATH]; + if (SHGetPathFromIDListW(pidlFull, szFullPath) && !SHELL_FS_HideExtension(szFullPath)) { - WCHAR szFullPath[MAX_PATH]; - PIDLIST_ABSOLUTE pidlFull = ILCombine(m_pidlParent, pidl); - SHGetPathFromIDListW(pidlFull, szFullPath); - - INT cchLimit = 0; - _DoFolderViewCB(SFVM_GETNAMELENGTH, (WPARAM)pidlFull, (LPARAM)&cchLimit); - if (cchLimit) - ::SendMessageW(hEdit, EM_SETLIMITTEXT, cchLimit, 0); - - if (!SHELL_FS_HideExtension(szFullPath)) - { - LPWSTR pszText = lpdi->item.pszText; - LPWSTR pchDotExt = PathFindExtensionW(pszText); - ::PostMessageW(hEdit, EM_SETSEL, 0, pchDotExt - pszText); - ::PostMessageW(hEdit, EM_SCROLLCARET, 0, 0); - } - - ILFree(pidlFull); + LPWSTR pchDotExt = PathFindExtensionW(pszText); + ::PostMessageW(hEdit, EM_SETSEL, 0, pchDotExt - pszText); + ::PostMessageW(hEdit, EM_SCROLLCARET, 0, 0); } - - m_isEditing = TRUE; - return FALSE; } - return TRUE; + + INT cchLimit = 0; + _DoFolderViewCB(SFVM_GETNAMELENGTH, (WPARAM)pidl, (LPARAM)&cchLimit); + if (cchLimit) + ::SendMessageW(hEdit, EM_SETLIMITTEXT, cchLimit, 0); + SHLimitInputEdit(hEdit, m_pSFParent); + m_isEditing = TRUE; + return FALSE; } case LVN_ENDLABELEDITW: { TRACE("-- LVN_ENDLABELEDITW %p\n", this); m_isEditing = FALSE; + if (!lpdi->item.pszText) + return TRUE; - if (lpdi->item.pszText) + pidl = _PidlByItem(lpdi->item); + // We have to copy the old PIDL because SetNameOf might generate a SHCNE_UPDATEITEM + // and that notification can cause us to call LV_UpdateItem and free the old PIDL too soon. + CComHeapPtr pidlOld(ILClone(pidl)); + if (!pidlOld) { - HRESULT hr; - LVITEMW lvItem; - - pidl = _PidlByItem(lpdi->item); - PITEMID_CHILD pidlNew = NULL; - hr = m_pSFParent->SetNameOf(0, pidl, lpdi->item.pszText, SHGDN_INFOLDER, &pidlNew); - - if (SUCCEEDED(hr) && pidlNew) - { - lvItem.mask = LVIF_PARAM|LVIF_IMAGE; - lvItem.iItem = lpdi->item.iItem; - lvItem.iSubItem = 0; - lvItem.lParam = reinterpret_cast(pidlNew); - lvItem.iImage = SHMapPIDLToSystemImageListIndex(m_pSFParent, pidlNew, 0); - m_ListView.SetItem(&lvItem); - m_ListView.Update(lpdi->item.iItem); - return TRUE; - } + SHELL_ErrorBox(lpdi->hdr.hwndFrom, E_OUTOFMEMORY); + return FALSE; + } + PITEMID_CHILD pidlNew = NULL; + HRESULT hr = m_pSFParent->SetNameOf(0, pidlOld, lpdi->item.pszText, SHGDN_INFOLDER, &pidlNew); + if (SUCCEEDED(hr) && pidlNew) + { + int iNew = LV_FindItemByPidl(pidlNew); + if (iNew != lpdi->item.iItem && iNew >= 0) + ILFree(pidlNew);// A SHCNE has updated the item already + else if (!LV_UpdateItem(lpdi->item.iItem, pidlNew)) + ILFree(pidlNew); + OnStateChange(CDBOSC_RENAME); + } + else + { + ::PostMessageW(m_ListView, LVM_EDITLABEL, lpdi->item.iItem, 0); // Renaming failed, let the user try again } - return FALSE; } default: @@ -2848,29 +2927,35 @@ LRESULT CDefView::OnChangeNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & TRACE("(%p)(%p,%p,%p)\n", this, Pidls[0], Pidls[1], lParam); if (_DoFolderViewCB(SFVM_FSNOTIFY, (WPARAM)Pidls, lEvent) == S_FALSE) + { + SHChangeNotification_Unlock(hLock); return FALSE; + } // Translate child IDLs. // SHSimpleIDListFromPathW creates fake PIDLs (lacking some attributes) + lEvent &= ~SHCNE_INTERRUPT; HRESULT hr; PITEMID_CHILD child0 = NULL, child1 = NULL; CComHeapPtr pidl0Temp, pidl1Temp; - if (_ILIsSpecialFolder(Pidls[0]) || ILIsParentOrSpecialParent(m_pidlParent, Pidls[0])) - { - child0 = ILFindLastID(Pidls[0]); - hr = SHGetRealIDL(m_pSFParent, child0, &pidl0Temp); - if (SUCCEEDED(hr)) - child0 = pidl0Temp; - } - if (_ILIsSpecialFolder(Pidls[1]) || ILIsParentOrSpecialParent(m_pidlParent, Pidls[1])) + if (lEvent != SHCNE_UPDATEIMAGE && lEvent < SHCNE_EXTENDED_EVENT) { - child1 = ILFindLastID(Pidls[1]); - hr = SHGetRealIDL(m_pSFParent, child1, &pidl1Temp); - if (SUCCEEDED(hr)) - child1 = pidl1Temp; + if (_ILIsSpecialFolder(Pidls[0]) || ILIsParentOrSpecialParent(m_pidlParent, Pidls[0])) + { + child0 = ILFindLastID(Pidls[0]); + hr = SHGetRealIDL(m_pSFParent, child0, &pidl0Temp); + if (SUCCEEDED(hr)) + child0 = pidl0Temp; + } + if (_ILIsSpecialFolder(Pidls[1]) || ILIsParentOrSpecialParent(m_pidlParent, Pidls[1])) + { + child1 = ILFindLastID(Pidls[1]); + hr = SHGetRealIDL(m_pSFParent, child1, &pidl1Temp); + if (SUCCEEDED(hr)) + child1 = pidl1Temp; + } } - lEvent &= ~SHCNE_INTERRUPT; switch (lEvent) { case SHCNE_MKDIR: @@ -2910,7 +2995,10 @@ LRESULT CDefView::OnChangeNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & break; case SHCNE_UPDATEDIR: case SHCNE_ATTRIBUTES: - Refresh(); + if (child0) + LV_UpdateItem(child0); + else + Refresh(); UpdateStatusbar(); break; case SHCNE_FREESPACE: @@ -2954,6 +3042,7 @@ LRESULT CDefView::OnSettingChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL if (wParam == SPI_SETDESKWALLPAPER || wParam == 0) UpdateListColors(); + m_ListView.SendMessage(uMsg, wParam, lParam); return S_OK; } @@ -3015,6 +3104,31 @@ LRESULT CDefView::OnInitMenuPopup(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL return FALSE; } +LRESULT CDefView::OnChangeCBChain(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) +{ + bHandled = TRUE; + return m_ClipboardChain.HandleChangeCBChain(wParam, lParam); +} + +LRESULT CDefView::OnDrawClipboard(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) +{ + bHandled = TRUE; + const LRESULT res = m_ClipboardChain.HandleDrawClipboard(wParam, lParam); + if (m_HasCutItems) + { + m_ClipboardChain.Unhook(m_hWnd); + m_HasCutItems = false; + m_ListView.SetItemState(-1, 0, LVIS_CUT); // Somebody copied or pasted, nothing can be "cut" anymore + m_ListView.SendMessageW(LVM_SETCALLBACKMASK, m_ListView.SendMessageW(LVM_GETCALLBACKMASK, 0, 0) | LVIS_CUT, 0); + } + return res; +} + +void CDefView::RefreshGhostedState() +{ + for (UINT i = 0, c = m_ListView.GetItemCount(); i < c; ++i) + m_ListView.SetItemState(i, GetItemAttributes(i, SFGAO_HIDDEN | SFGAO_GHOSTED) ? LVIS_CUT : 0, LVIS_CUT); +} // The INTERFACE of the IShellView object @@ -3048,7 +3162,7 @@ HRESULT WINAPI CDefView::TranslateAccelerator(LPMSG lpmsg) TRACE("-- key=0x%04lx\n", lpmsg->wParam); } - return m_pShellBrowser->TranslateAcceleratorSB(lpmsg, 0); + return m_pShellBrowser ? m_pShellBrowser->TranslateAcceleratorSB(lpmsg, 0) : S_FALSE; } HRESULT WINAPI CDefView::EnableModeless(BOOL fEnable) @@ -3261,7 +3375,7 @@ HRESULT CDefView::LoadViewState() m_LoadColumnsList = NULL; } } - m_sortInfo.bLoadedFromViewState = !fallback && m_LoadColumnsList && cvs.SortColId != LISTVIEW_SORT_INFO::UNSPECIFIEDCOLUMN; + m_sortInfo.bLoadedFromViewState = !fallback && m_LoadColumnsList && (int)cvs.SortColId != LISTVIEW_SORT_INFO::UNSPECIFIEDCOLUMN; m_sortInfo.bColumnIsFolderColumn = TRUE; m_sortInfo.Direction = cvs.SortDir > 0 ? 1 : -1; m_sortInfo.ListColumn = cvs.SortColId; @@ -3280,10 +3394,10 @@ HRESULT CDefView::SaveViewState(IStream *pStream) cols.Signature = PERSISTCOLUMNS::SIG; cols.Count = 0; LVCOLUMN lvc; - lvc.mask = LVCF_WIDTH | LVCF_SUBITEM; + lvc.mask = LVCF_WIDTH; for (UINT i = 0, j = 0; i < PERSISTCOLUMNS::MAXCOUNT && ListView_GetColumn(m_ListView, j, &lvc); ++j) { - HRESULT hr = MapListColumnToFolderColumn(lvc.iSubItem); + HRESULT hr = MapListColumnToFolderColumn(j); if (SUCCEEDED(hr)) { cols.Columns[i] = MAKELONG(hr, lvc.cx); @@ -3335,6 +3449,7 @@ HRESULT CDefView::SaveViewState(IStream *pStream) if (SUCCEEDED(hr)) hr = pStream->Write(&cols, cbColumns, &written); } + // TODO: else if (SUCCEEDED(_DoFolderViewCB(SFVM_GETCOLUMNSTREAM))) if (pStream) pStream->Release(); return hr; @@ -3549,12 +3664,12 @@ HRESULT STDMETHODCALLTYPE CDefView::Item(int iItemIndex, PITEMID_CHILD *ppidl) HRESULT STDMETHODCALLTYPE CDefView::ItemCount(UINT uFlags, int *pcItems) { TRACE("(%p)->(%u %p)\n", this, uFlags, pcItems); - - if (uFlags != SVGIO_ALLVIEW) - FIXME("some flags unsupported, %x\n", uFlags & ~SVGIO_ALLVIEW); - - *pcItems = m_ListView.GetItemCount(); - + if (uFlags != SVGIO_ALLVIEW && uFlags != SVGIO_SELECTION) + FIXME("some flags unsupported, %x\n", uFlags & ~(SVGIO_ALLVIEW | SVGIO_SELECTION)); + if ((uFlags & SVGIO_TYPE_MASK) == SVGIO_SELECTION) + *pcItems = m_ListView.GetSelectedCount(); + else + *pcItems = m_ListView.GetItemCount(); return S_OK; } @@ -3813,14 +3928,15 @@ HRESULT STDMETHODCALLTYPE CDefView::SelectAndPositionItem(LPCITEMIDLIST item, UI HRESULT STDMETHODCALLTYPE CDefView::Rearrange(LPARAM sort) { - FIXME("(%p)->(%ld) stub\n", this, sort); - return E_NOTIMPL; + _Sort(LOWORD(sort & SHCIDS_COLUMNMASK)); + return S_OK; } HRESULT STDMETHODCALLTYPE CDefView::GetArrangeParam(LPARAM *sort) { - FIXME("(%p)->(%p) stub\n", this, sort); - return E_NOTIMPL; + int col = m_sortInfo.ListColumn; + *sort = col != LISTVIEW_SORT_INFO::UNSPECIFIEDCOLUMN ? col : 0; + return col != LISTVIEW_SORT_INFO::UNSPECIFIEDCOLUMN ? S_OK : S_FALSE; } HRESULT STDMETHODCALLTYPE CDefView::ArrangeGrid() @@ -3913,8 +4029,8 @@ HRESULT STDMETHODCALLTYPE CDefView::SetRedraw(BOOL redraw) HRESULT STDMETHODCALLTYPE CDefView::GetSelectedCount(UINT *count) { - FIXME("(%p)->(%p) stub\n", this, count); - return E_NOTIMPL; + *count = m_ListView.GetSelectedCount(); + return S_OK; } HRESULT STDMETHODCALLTYPE CDefView::GetSelectedObjects(PCUITEMID_CHILD **pidl, UINT *items) @@ -3984,8 +4100,26 @@ HRESULT STDMETHODCALLTYPE CDefView::IsBkDropTarget(IDropTarget *drop_target) HRESULT STDMETHODCALLTYPE CDefView::SetClipboard(BOOL move) { - FIXME("(%p)->(%d) stub\n", this, move); - return E_NOTIMPL; + if (!move) + return S_OK; + + UINT CutCount = 0; + for (int i = -1; (i = m_ListView.GetNextItem(i, LVNI_SELECTED)) != -1;) + { + if (!CutCount++) + { + // Turn off the LVIS_CUT LVM_SETCALLBACKMASK optimization + m_ListView.SendMessageW(LVM_SETCALLBACKMASK, m_ListView.SendMessageW(LVM_GETCALLBACKMASK, 0, 0) & ~LVIS_CUT, 0); + RefreshGhostedState(); + } + m_ListView.SetItemState(i, LVIS_CUT, LVIS_CUT); + } + if (CutCount) + { + m_ClipboardChain.Hook(m_hWnd); + m_HasCutItems = true; + } + return S_OK; } HRESULT STDMETHODCALLTYPE CDefView::SetPoints(IDataObject *obj) @@ -4108,13 +4242,13 @@ HRESULT WINAPI CDefView::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCm SHDeleteKey(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\ShellNoRoam\\Bags"); if (SUCCEEDED(GetDefaultViewStream(STGM_WRITE, &pStream))) SaveViewState(pStream); - break; + return S_OK; case DVCMDID_RESET_DEFAULTFOLDER_SETTINGS: - wsprintfW(SubKey, L"%s\\%s", REGSTR_PATH_EXPLORER, L"Streams\\Default"); + PathCombineW(SubKey, REGSTR_PATH_EXPLORER, L"Streams\\Default"); SHDeleteKey(HKEY_CURRENT_USER, SubKey); SHDeleteKey(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\ShellNoRoam\\Bags"); m_FolderSettings.fFlags |= FWF_NOBROWSERVIEWSTATE; // Don't let this folder save itself - break; + return S_OK; } } @@ -4370,7 +4504,7 @@ void CDefView::_HandleStatusBarResize(int nWidth) { LRESULT lResult; - if (m_isParentFolderSpecial) + if (!m_isFullStatusBar) { int nPartArray[] = {-1}; m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETPARTS, _countof(nPartArray), (LPARAM)nPartArray, &lResult); @@ -4608,12 +4742,9 @@ HRESULT WINAPI CDefView::GetAdvise(DWORD *pAspects, DWORD *pAdvf, IAdviseSink ** HRESULT STDMETHODCALLTYPE CDefView::QueryService(REFGUID guidService, REFIID riid, void **ppvObject) { - if (IsEqualIID(guidService, SID_IShellBrowser) && m_pShellBrowser) - return m_pShellBrowser->QueryInterface(riid, ppvObject); - else if (IsEqualIID(guidService, SID_IFolderView)) + if (IsEqualIID(guidService, SID_SFolderView)) return QueryInterface(riid, ppvObject); - - return E_NOINTERFACE; + return m_pShellBrowser ? IUnknown_QueryService(m_pShellBrowser, guidService, riid, ppvObject) : E_NOINTERFACE; } HRESULT CDefView::_MergeToolbar() @@ -4660,8 +4791,7 @@ HRESULT CDefView_CreateInstance(IShellFolder *pFolder, REFIID riid, LPVOID * ppv return ShellObjectCreatorInit(pFolder, riid, ppvOut); } -HRESULT WINAPI SHCreateShellFolderView(const SFV_CREATE *pcsfv, - IShellView **ppsv) +HRESULT WINAPI SHCreateShellFolderView(const SFV_CREATE *pcsfv, IShellView **ppsv) { CComPtr psv; HRESULT hRes; diff --git a/dll/win32/shell32/CDefViewBckgrndMenu.cpp b/dll/win32/shell32/CDefViewBckgrndMenu.cpp index 740b917f072c6..ad567c5829306 100644 --- a/dll/win32/shell32/CDefViewBckgrndMenu.cpp +++ b/dll/win32/shell32/CDefViewBckgrndMenu.cpp @@ -70,7 +70,7 @@ BOOL CDefViewBckgrndMenu::_bIsDesktopBrowserMenu() /* Get a pointer to the shell browser */ CComPtr psv; - HRESULT hr = IUnknown_QueryService(m_site, SID_IFolderView, IID_PPV_ARG(IShellView, &psv)); + HRESULT hr = IUnknown_QueryService(m_site, SID_SFolderView, IID_PPV_ARG(IShellView, &psv)); if (FAILED_UNEXPECTEDLY(hr)) return FALSE; @@ -265,7 +265,7 @@ CDefViewBckgrndMenu::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi) /* Get a pointer to the shell browser */ CComPtr psv; - HRESULT hr = IUnknown_QueryService(m_site, SID_IFolderView, IID_PPV_ARG(IShellView, &psv)); + HRESULT hr = IUnknown_QueryService(m_site, SID_SFolderView, IID_PPV_ARG(IShellView, &psv)); if (FAILED_UNEXPECTEDLY(hr)) return hr; diff --git a/dll/win32/shell32/CDefaultContextMenu.cpp b/dll/win32/shell32/CDefaultContextMenu.cpp index 6b83bd8a069b6..8cb12bfae9a0d 100644 --- a/dll/win32/shell32/CDefaultContextMenu.cpp +++ b/dll/win32/shell32/CDefaultContextMenu.cpp @@ -84,6 +84,25 @@ UINT MapVerbToDfmCmd(_In_ LPCSTR verba) return 0; } +static HRESULT +MapVerbToCmdId(PVOID Verb, BOOL IsUnicode, IContextMenu *pCM, UINT idFirst, UINT idLast) +{ + const UINT gcs = IsUnicode ? GCS_VERBW : GCS_VERBA; + for (UINT id = idFirst; id <= idLast; ++id) + { + WCHAR buf[MAX_PATH]; + *buf = UNICODE_NULL; + HRESULT hr = pCM->GetCommandString(id, gcs, NULL, (LPSTR)buf, _countof(buf)); + if (FAILED(hr) || !*buf) + continue; + else if (IsUnicode && !_wcsicmp((LPWSTR)Verb, buf)) + return id; + else if (!IsUnicode && !lstrcmpiA((LPSTR)Verb, (LPSTR)buf)) + return id; + } + return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); +} + static inline bool IsVerbListSeparator(WCHAR Ch) { return Ch == L' ' || Ch == L','; // learn.microsoft.com/en-us/windows/win32/shell/context-menu-handlers @@ -200,7 +219,7 @@ class CDefaultContextMenu : STDMETHOD(GetSite)(REFIID riid, void **ppvSite) override; // IServiceProvider - virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID svc, REFIID riid, void**ppv) + STDMETHOD(QueryService)(REFGUID svc, REFIID riid, void**ppv) override { return IUnknown_QueryService(m_site, svc, riid, ppv); } @@ -738,7 +757,7 @@ CDefaultContextMenu::AddStaticContextMenusToMenu( return cIds; } -void WINAPI _InsertMenuItemW( +BOOL WINAPI _InsertMenuItemW( HMENU hMenu, UINT indexMenu, BOOL fByPosition, @@ -764,7 +783,7 @@ void WINAPI _InsertMenuItemW( else { ERR("failed to load string %p\n", dwTypeData); - return; + return FALSE; } } else @@ -774,7 +793,7 @@ void WINAPI _InsertMenuItemW( mii.wID = wID; mii.fType = fType; - InsertMenuItemW(hMenu, indexMenu, fByPosition, &mii); + return InsertMenuItemW(hMenu, indexMenu, fByPosition, &mii); } void @@ -1012,10 +1031,16 @@ HRESULT CDefaultContextMenu::DoCopyOrCut(LPCMINVOKECOMMANDINFOEX lpcmi, BOOL bCo GlobalUnlock(medium.hGlobal); m_pDataObj->SetData(&formatetc, &medium, TRUE); + CComPtr psfv; + if (SUCCEEDED(IUnknown_QueryService(m_site, SID_SFolderView, IID_PPV_ARG(IShellFolderView, &psfv)))) + psfv->SetPoints(m_pDataObj); + HRESULT hr = OleSetClipboard(m_pDataObj); if (FAILED_UNEXPECTEDLY(hr)) return hr; + if (psfv) + psfv->SetClipboard(!bCopy); return S_OK; } @@ -1142,7 +1167,7 @@ CDefaultContextMenu::DoCreateNewFolder( return S_OK; /* Get a pointer to the shell view */ - hr = IUnknown_QueryService(m_site, SID_IFolderView, IID_PPV_ARG(IShellView, &psv)); + hr = IUnknown_QueryService(m_site, SID_SFolderView, IID_PPV_ARG(IShellView, &psv)); if (FAILED_UNEXPECTEDLY(hr)) return S_OK; @@ -1195,7 +1220,7 @@ CDefaultContextMenu::MapVerbToCmdId(PVOID Verb, PUINT idCmd, BOOL IsUnicode) { /* The static verbs are ANSI, get a unicode version before doing the compare */ SHAnsiToUnicode(g_StaticInvokeCmdMap[i].szStringVerb, UnicodeStr, MAX_VERB); - if (!wcscmp(UnicodeStr, (LPWSTR)Verb)) + if (!_wcsicmp(UnicodeStr, (LPWSTR)Verb)) { /* Return the Corresponding Id */ *idCmd = g_StaticInvokeCmdMap[i].IntVerb; @@ -1204,7 +1229,7 @@ CDefaultContextMenu::MapVerbToCmdId(PVOID Verb, PUINT idCmd, BOOL IsUnicode) } else { - if (!strcmp(g_StaticInvokeCmdMap[i].szStringVerb, (LPSTR)Verb)) + if (!_stricmp(g_StaticInvokeCmdMap[i].szStringVerb, (LPSTR)Verb)) { *idCmd = g_StaticInvokeCmdMap[i].IntVerb; return TRUE; @@ -1212,6 +1237,18 @@ CDefaultContextMenu::MapVerbToCmdId(PVOID Verb, PUINT idCmd, BOOL IsUnicode) } } + for (POSITION it = m_DynamicEntries.GetHeadPosition(); it != NULL;) + { + DynamicShellEntry& entry = m_DynamicEntries.GetNext(it); + if (!entry.NumIds) + continue; + HRESULT hr = ::MapVerbToCmdId(Verb, IsUnicode, entry.pCM, 0, entry.NumIds - 1); + if (SUCCEEDED(hr)) + { + *idCmd = m_iIdSHEFirst + entry.iIdCmdFirst + hr; + return TRUE; + } + } return FALSE; } @@ -1496,6 +1533,8 @@ CDefaultContextMenu::InvokeCommand( /* Get the ID which corresponds to this verb, and update our local copy */ if (MapVerbToCmdId((LPVOID)LocalInvokeInfo.lpVerb, &CmdId, FALSE)) LocalInvokeInfo.lpVerb = MAKEINTRESOURCEA(CmdId); + else + return E_INVALIDARG; } CmdId = LOWORD(LocalInvokeInfo.lpVerb); diff --git a/dll/win32/shell32/CFolderItemVerbs.cpp b/dll/win32/shell32/CFolderItemVerbs.cpp index 775f342f7375b..ce7f2266ba6e5 100644 --- a/dll/win32/shell32/CFolderItemVerbs.cpp +++ b/dll/win32/shell32/CFolderItemVerbs.cpp @@ -91,13 +91,7 @@ CFolderItemVerbs::~CFolderItemVerbs() HRESULT CFolderItemVerbs::Init(LPITEMIDLIST idlist) { - CComPtr folder; - LPCITEMIDLIST child; - HRESULT hr = SHBindToParent(idlist, IID_PPV_ARG(IShellFolder, &folder), &child); - if (FAILED_UNEXPECTEDLY(hr)) - return hr; - - hr = folder->GetUIObjectOf(NULL, 1, &child, IID_IContextMenu, NULL, (PVOID*)&m_contextmenu); + HRESULT hr = SHELL_GetUIObjectOfAbsoluteItem(NULL, idlist, IID_PPV_ARG(IContextMenu, &m_contextmenu)); if (FAILED_UNEXPECTEDLY(hr)) return hr; diff --git a/dll/win32/shell32/CFolderOptions.cpp b/dll/win32/shell32/CFolderOptions.cpp index 0f3513bcd8cc7..37d50a1de00b3 100644 --- a/dll/win32/shell32/CFolderOptions.cpp +++ b/dll/win32/shell32/CFolderOptions.cpp @@ -113,6 +113,45 @@ HRESULT STDMETHODCALLTYPE CFolderOptions::GetSite(REFIID riid, void **ppvSite) /************************************************************************* * FolderOptions helper methods */ +static HRESULT ResetGlobalFolderSettings() +{ + IGlobalFolderSettings *pgfs; + HRESULT hr = CoCreateInstance(CLSID_GlobalFolderSettings, NULL, CLSCTX_INPROC_SERVER, + IID_PPV_ARG(IGlobalFolderSettings, &pgfs)); + if (SUCCEEDED(hr)) + { + hr = pgfs->Set(NULL, 0, 0); + pgfs->Release(); + } + return hr; +} + +static inline HRESULT ExecResetDefViewFolderSettings(IUnknown *pUnk) +{ + return IUnknown_Exec(pUnk, CGID_DefView, DVCMDID_RESET_DEFAULTFOLDER_SETTINGS, + OLECMDEXECOPT_DODEFAULT, NULL, NULL); +} + +static HRESULT ResetDefViewFolderSettings() +{ + CComPtr pSF; + HRESULT hr = SHGetDesktopFolder(&pSF); + if (SUCCEEDED(hr)) + { + CComPtr pSV; + SFV_CREATE create = { sizeof(SFV_CREATE), pSF }; + if (SUCCEEDED(hr = SHCreateShellFolderView(&create, &pSV))) + hr = ExecResetDefViewFolderSettings(pSV); + } + return hr; +} + +HRESULT CFolderOptions::ResetGlobalAndDefViewFolderSettings() +{ + ResetDefViewFolderSettings(); + return ResetGlobalFolderSettings(); +} + HRESULT CFolderOptions::HandleDefFolderSettings(int Action) { IBrowserService2 *bs2; @@ -126,25 +165,19 @@ HRESULT CFolderOptions::HandleDefFolderSettings(int Action) else if (Action == DFSA_RESET) { // There does not seem to be a method in IBrowserService2 for this - IUnknown_Exec(bs2, CGID_DefView, DVCMDID_RESET_DEFAULTFOLDER_SETTINGS, OLECMDEXECOPT_DODEFAULT, NULL, NULL); + ExecResetDefViewFolderSettings(bs2); } else { - // FFSA_QUERY: hr is already correct + // DFSA_QUERY: hr is already correct } bs2->Release(); } if (Action == DFSA_RESET) { - IGlobalFolderSettings *pgfs; - HRESULT hr = CoCreateInstance(CLSID_GlobalFolderSettings, NULL, CLSCTX_INPROC_SERVER, - IID_IGlobalFolderSettings, (void **)&pgfs); - if (SUCCEEDED(hr)) - { - hr = pgfs->Set(NULL, 0, 0); - pgfs->Release(); - } + // In case the browser is hosting a 3rd-party view, we force a DefView reset + hr = ResetGlobalAndDefViewFolderSettings(); } return hr; diff --git a/dll/win32/shell32/CFolderOptions.h b/dll/win32/shell32/CFolderOptions.h index 3bb8f2973d9b8..c3785605545a1 100644 --- a/dll/win32/shell32/CFolderOptions.h +++ b/dll/win32/shell32/CFolderOptions.h @@ -66,6 +66,8 @@ class CFolderOptions : return HandleDefFolderSettings(ResetToDefault ? DFSA_RESET : DFSA_APPLY); } + static HRESULT ResetGlobalAndDefViewFolderSettings(); + DECLARE_REGISTRY_RESOURCEID(IDR_FOLDEROPTIONS) DECLARE_NOT_AGGREGATABLE(CFolderOptions) diff --git a/dll/win32/shell32/CMakeLists.txt b/dll/win32/shell32/CMakeLists.txt index 258191318b630..3660b02f36efb 100644 --- a/dll/win32/shell32/CMakeLists.txt +++ b/dll/win32/shell32/CMakeLists.txt @@ -38,6 +38,7 @@ list(APPEND SOURCE CDropTargetHelper.cpp CEnumIDListBase.cpp CExtractIcon.cpp + CRecycleBinCleaner.cpp folders.cpp iconcache.cpp propsheet.cpp @@ -120,7 +121,7 @@ set_source_files_properties(shell32.rc PROPERTIES OBJECT_DEPENDS ${CMAKE_CURRENT set_module_type(shell32 win32dll UNICODE) target_link_libraries(shell32 shellmenu shelldesktop wine uuid recyclebin cpprt atl_classes oldnames) -add_delay_importlibs(shell32 powrprof shdocvw devmgr winspool.drv winmm mpr uxtheme ole32 oleaut32 userenv browseui version fmifs) +add_delay_importlibs(shell32 powrprof shdocvw devmgr winspool.drv winmm mpr uxtheme ole32 oleaut32 userenv browseui version fmifs netapi32 secur32) add_importlibs(shell32 advapi32 gdi32 user32 comctl32 comdlg32 shlwapi msvcrt kernel32 ntdll) add_dependencies(shell32 stdole2) # shell32_shldisp.tlb needs stdole2.tlb add_pch(shell32 precomp.h "${PCH_SKIP_SOURCE}") diff --git a/dll/win32/shell32/CNewMenu.cpp b/dll/win32/shell32/CNewMenu.cpp index bef93ea986041..f525bf4ada4b8 100644 --- a/dll/win32/shell32/CNewMenu.cpp +++ b/dll/win32/shell32/CNewMenu.cpp @@ -430,7 +430,7 @@ HRESULT CNewMenu::SelectNewItem(LONG wEventId, UINT uFlags, LPWSTR pszName, BOOL return S_OK; /* Get a pointer to the shell view */ - hr = IUnknown_QueryService(m_pSite, SID_IFolderView, IID_PPV_ARG(IShellView, &lpSV)); + hr = IUnknown_QueryService(m_pSite, SID_SFolderView, IID_PPV_ARG(IShellView, &lpSV)); if (FAILED_UNEXPECTEDLY(hr)) return S_OK; diff --git a/dll/win32/shell32/COpenWithMenu.cpp b/dll/win32/shell32/COpenWithMenu.cpp index 42f538a7eeb58..9f646c00019e3 100644 --- a/dll/win32/shell32/COpenWithMenu.cpp +++ b/dll/win32/shell32/COpenWithMenu.cpp @@ -31,6 +31,56 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell); EXTERN_C BOOL PathIsExeW(LPCWSTR lpszPath); +static SIZE_T PathGetAppFromCommandLine(LPCWSTR pszIn, LPWSTR pszOut, SIZE_T cchMax) +{ + SIZE_T count = 0; + WCHAR stop = ' '; + if (pszIn[0] == '"') + stop = *(pszIn++); + + for (LPCWSTR pwszSrc = pszIn; *pwszSrc && *pwszSrc != stop; ++pwszSrc) + { + if (++count >= cchMax) + return 0; + *(pszOut++) = *pwszSrc; + } + *pszOut = UNICODE_NULL; + return count; +} + +HRESULT SHELL32_GetDllFromRundll32CommandLine(LPCWSTR pszCmd, LPWSTR pszOut, SIZE_T cchMax) +{ + WCHAR szDll[MAX_PATH + 100]; + if (!PathGetAppFromCommandLine(pszCmd, szDll, _countof(szDll))) + return HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW); + + PWSTR pszName = PathFindFileNameW(szDll); + if (_wcsicmp(pszName, L"rundll32") && _wcsicmp(pszName, L"rundll32.exe")) + return E_UNEXPECTED; + + PCWSTR pszDllStart = pszCmd + (pszName - szDll) + lstrlenW(pszName); + + if (*pszDllStart == '\"') + ++pszDllStart; // Skip possible end quote of ..\rundll32.exe" foo.dll,func + while (*pszDllStart <= ' ' && *pszDllStart) + ++pszDllStart; + if (PathGetAppFromCommandLine(pszDllStart, szDll, _countof(szDll))) + { + BOOL quoted = *pszDllStart == '\"'; + PWSTR pszComma = szDll + lstrlenW(szDll); + while (!quoted && pszComma > szDll && *pszComma != ',' && *pszComma != '\\' && *pszComma != '/') + --pszComma; + SIZE_T cch = pszComma - szDll; + if (cch <= cchMax && (quoted || *pszComma == ',')) + { + *pszComma = UNICODE_NULL; + lstrcpynW(pszOut, szDll, cchMax); + return S_OK; + } + } + return HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW); +} + class COpenWithList { public: @@ -396,26 +446,23 @@ BOOL COpenWithList::LoadInfo(COpenWithList::SApp *pApp) BOOL COpenWithList::GetPathFromCmd(LPWSTR pwszAppPath, LPCWSTR pwszCmd) { - WCHAR wszBuf[MAX_PATH], *pwszDest = wszBuf; + WCHAR wszBuf[MAX_PATH]; /* Remove arguments */ - if (pwszCmd[0] == '"') - { - for(LPCWSTR pwszSrc = pwszCmd + 1; *pwszSrc && *pwszSrc != '"'; ++pwszSrc) - *(pwszDest++) = *pwszSrc; - } - else - { - for(LPCWSTR pwszSrc = pwszCmd; *pwszSrc && *pwszSrc != ' '; ++pwszSrc) - *(pwszDest++) = *pwszSrc; - } + if (!PathGetAppFromCommandLine(pwszCmd, wszBuf, _countof(wszBuf))) + return FALSE; - *pwszDest = 0; + /* Replace rundll32.exe with the dll path */ + SHELL32_GetDllFromRundll32CommandLine(pwszCmd, wszBuf, _countof(wszBuf)); - /* Expand evn vers and optionally search for path */ + /* Expand env. vars and optionally search for path */ ExpandEnvironmentStrings(wszBuf, pwszAppPath, MAX_PATH); if (!PathFileExists(pwszAppPath)) - return SearchPath(NULL, pwszAppPath, NULL, MAX_PATH, pwszAppPath, NULL); + { + UINT cch = SearchPathW(NULL, pwszAppPath, NULL, MAX_PATH, pwszAppPath, NULL); + if (!cch || cch >= MAX_PATH) + return FALSE; + } return TRUE; } @@ -644,7 +691,7 @@ VOID COpenWithList::LoadRecommendedFromHKCU(LPCWSTR pwszExt) LoadMRUList(hKey); LoadProgIdList(hKey, pwszExt); - /* Handle "Aplication" value */ + /* Handle "Application" value */ DWORD cbBuf = sizeof(wszBuf); if (RegGetValueW(hKey, NULL, L"Application", RRF_RT_REG_SZ, NULL, wszBuf, &cbBuf) == ERROR_SUCCESS) { @@ -1250,6 +1297,12 @@ VOID COpenWithMenu::AddApp(PVOID pApp) m_idCmdLast++; } +static const CMVERBMAP g_VerbMap[] = +{ + { "openas", 0 }, + { NULL } +}; + HRESULT WINAPI COpenWithMenu::QueryContextMenu( HMENU hMenu, UINT indexMenu, @@ -1328,14 +1381,19 @@ HRESULT WINAPI COpenWithMenu::QueryContextMenu( HRESULT WINAPI COpenWithMenu::InvokeCommand(LPCMINVOKECOMMANDINFO lpici) { + const SIZE_T idChooseApp = m_idCmdLast; HRESULT hr = E_FAIL; TRACE("This %p idFirst %u idLast %u idCmd %u\n", this, m_idCmdFirst, m_idCmdLast, m_idCmdFirst + LOWORD(lpici->lpVerb)); - if (HIWORD(lpici->lpVerb) == 0 && m_idCmdFirst + LOWORD(lpici->lpVerb) <= m_idCmdLast) + if (!IS_INTRESOURCE(lpici->lpVerb) && SHELL_MapContextMenuVerbToCmdId(lpici, g_VerbMap) == 0) + goto DoChooseApp; + + if (IS_INTRESOURCE(lpici->lpVerb) && m_idCmdFirst + LOWORD(lpici->lpVerb) <= m_idCmdLast) { - if (m_idCmdFirst + LOWORD(lpici->lpVerb) == m_idCmdLast) + if (m_idCmdFirst + LOWORD(lpici->lpVerb) == idChooseApp) { +DoChooseApp: OPENASINFO info; LPCWSTR pwszExt = PathFindExtensionW(m_wszPath); @@ -1371,9 +1429,13 @@ HRESULT WINAPI COpenWithMenu::GetCommandString(UINT_PTR idCmd, UINT uType, UINT* pwReserved, LPSTR pszName, UINT cchMax ) { - FIXME("%p %lu %u %p %p %u\n", this, + TRACE("%p %lu %u %p %p %u\n", this, idCmd, uType, pwReserved, pszName, cchMax ); + const SIZE_T idChooseApp = m_idCmdLast; + if (m_idCmdFirst + idCmd == idChooseApp) + return SHELL_GetCommandStringImpl(0, uType, pszName, cchMax, g_VerbMap); + return E_NOTIMPL; } diff --git a/dll/win32/shell32/CRecycleBinCleaner.cpp b/dll/win32/shell32/CRecycleBinCleaner.cpp new file mode 100644 index 0000000000000..72a99cfc9d6ea --- /dev/null +++ b/dll/win32/shell32/CRecycleBinCleaner.cpp @@ -0,0 +1,149 @@ +/* + * PROJECT: shell32 + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: CRecycleBinCleaner implementation + * COPYRIGHT: Copyright 2023-2025 Mark Jansen + */ + +#include "precomp.h" + +WINE_DEFAULT_DEBUG_CHANNEL(shell); + + +CLSID CLSID_RecycleBinCleaner = { 0x5ef4af3a, 0xf726, 0x11d0, { 0xb8, 0xa2, 0x00, 0xc0, 0x4f, 0xc3, 0x09, 0xa4 } }; + +struct CRecycleBinCleaner : + public CComObjectRootEx, + public CComCoClass, + public IEmptyVolumeCache2 +{ + WCHAR m_wszVolume[4]; + + void + OutputResourceString(DWORD dwResId, _Out_ LPWSTR *ppwszOutput) + { + CStringW Tmp(MAKEINTRESOURCEW(dwResId)); + SHStrDupW(Tmp, ppwszOutput); + } + +public: + + // +IEmptyVolumeCache + STDMETHODIMP Initialize( + _In_ HKEY hkRegKey, + _In_ LPCWSTR pcwszVolume, + _Out_ LPWSTR* ppwszDisplayName, + _Out_ LPWSTR* ppwszDescription, + _Out_ DWORD* pdwFlags) + { + if (!pdwFlags) + return E_POINTER; + + *pdwFlags = EVCF_HASSETTINGS; + + OutputResourceString(IDS_RECYCLE_CLEANER_DISPLAYNAME, ppwszDisplayName); + OutputResourceString(IDS_RECYCLE_CLEANER_DESCRIPTION, ppwszDescription); + + return StringCchCopyW(m_wszVolume, _countof(m_wszVolume), pcwszVolume); + } + + STDMETHODIMP GetSpaceUsed( + _Out_ DWORDLONG* pdwlSpaceUsed, + _In_opt_ IEmptyVolumeCacheCallBack* picb) + { + if (!pdwlSpaceUsed) + return E_POINTER; + + SHQUERYRBINFO bin = { sizeof(bin) }; + HRESULT hr = SHQueryRecycleBinW(m_wszVolume, &bin); + if (FAILED_UNEXPECTEDLY(hr)) + { + bin.i64Size = 0; + } + *pdwlSpaceUsed = bin.i64Size; + if (picb) + { + picb->ScanProgress(bin.i64Size, EVCCBF_LASTNOTIFICATION, NULL); + } + + return S_OK; + } + + STDMETHODIMP Purge( + _In_ DWORDLONG dwlSpaceToFree, + _In_opt_ IEmptyVolumeCacheCallBack *picb) + { + DWORDLONG dwlPrevious = 0; + GetSpaceUsed(&dwlPrevious, NULL); + + SHEmptyRecycleBinW(NULL, m_wszVolume, SHERB_NOCONFIRMATION | SHERB_NOPROGRESSUI | SHERB_NOSOUND); + if (picb) + { + picb->PurgeProgress(dwlPrevious, 0, EVCCBF_LASTNOTIFICATION, NULL); + } + + return S_OK; + } + + STDMETHODIMP ShowProperties( + _In_ HWND hwnd) + { + CComHeapPtr pidl; + HRESULT hr; + if (FAILED_UNEXPECTEDLY(hr = SHGetSpecialFolderLocation(hwnd, CSIDL_BITBUCKET, &pidl))) + return hr; + + SHELLEXECUTEINFOW seei = {sizeof(seei)}; + seei.hwnd = hwnd; + seei.lpVerb = L"open"; + seei.nShow = SW_SHOWNORMAL; + seei.fMask = SEE_MASK_IDLIST; + seei.lpIDList = pidl; + ShellExecuteExW(&seei); + + return S_OK; + } + + STDMETHODIMP Deactivate( + _Out_ DWORD* pdwFlags) + { + if (!pdwFlags) + return E_POINTER; + + *pdwFlags = 0; + + return S_OK; + } + // -IEmptyVolumeCache + + + // +IEmptyVolumeCache2 + STDMETHODIMP InitializeEx( + _In_ HKEY hkRegKey, + _In_ LPCWSTR pcwszVolume, + _In_ LPCWSTR pcwszKeyName, + _Out_ LPWSTR* ppwszDisplayName, + _Out_ LPWSTR* ppwszDescription, + _Out_ LPWSTR* ppwszBtnText, + _Out_ DWORD* pdwFlags) + { + OutputResourceString(IDS_RECYCLE_CLEANER_BUTTON_TEXT, ppwszBtnText); + + return Initialize(hkRegKey, pcwszVolume, ppwszDisplayName, ppwszDescription, pdwFlags); + } + // -IEmptyVolumeCache2 + + + DECLARE_PROTECT_FINAL_CONSTRUCT(); + DECLARE_REGISTRY_RESOURCEID(IDR_RECYCLEBINCLEANER) + DECLARE_NOT_AGGREGATABLE(CRecycleBinCleaner) + + BEGIN_COM_MAP(CRecycleBinCleaner) + COM_INTERFACE_ENTRY_IID(IID_IEmptyVolumeCache2, IEmptyVolumeCache2) + COM_INTERFACE_ENTRY_IID(IID_IEmptyVolumeCache, IEmptyVolumeCache) + COM_INTERFACE_ENTRY_IID(IID_IUnknown, IUnknown) + END_COM_MAP() +}; + + +OBJECT_ENTRY_AUTO(CLSID_RecycleBinCleaner, CRecycleBinCleaner) diff --git a/dll/win32/shell32/CSendToMenu.cpp b/dll/win32/shell32/CSendToMenu.cpp index 131f21e2a0a2f..8cce580ba082b 100644 --- a/dll/win32/shell32/CSendToMenu.cpp +++ b/dll/win32/shell32/CSendToMenu.cpp @@ -130,14 +130,7 @@ HRESULT CSendToMenu::GetUIObjectFromPidl(HWND hwnd, PIDLIST_ABSOLUTE pidl, REFIID riid, LPVOID *ppvOut) { *ppvOut = NULL; - - PCITEMID_CHILD pidlLast; - CComPtr pFolder; - HRESULT hr = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &pFolder), &pidlLast); - if (FAILED_UNEXPECTEDLY(hr)) - return hr; - - hr = pFolder->GetUIObjectOf(hwnd, 1, &pidlLast, riid, NULL, ppvOut); + HRESULT hr = SHELL_GetUIObjectOfAbsoluteItem(hwnd, pidl, riid, ppvOut); if (FAILED_UNEXPECTEDLY(hr)) return hr; diff --git a/dll/win32/shell32/CShellLink.cpp b/dll/win32/shell32/CShellLink.cpp index d99db2f1470e5..3ea7c3d5e6c5e 100644 --- a/dll/win32/shell32/CShellLink.cpp +++ b/dll/win32/shell32/CShellLink.cpp @@ -40,13 +40,13 @@ * as well as its interface. * * General introduction about "Shell Links" (MSDN): - * https://msdn.microsoft.com/en-us/library/windows/desktop/bb776891(v=vs.85).aspx + * https://learn.microsoft.com/en-us/windows/win32/shell/links * * * Details of the file format: * * - Official MSDN documentation "[MS-SHLLINK]: Shell Link (.LNK) Binary File Format": - * https://msdn.microsoft.com/en-us/library/dd871305.aspx + * https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-shllink/16cb4ca1-9339-4d0c-a68d-bf1d6cc0f943 * * - Forensics: * http://forensicswiki.org/wiki/LNK @@ -55,8 +55,8 @@ * https://github.com/libyal/liblnk/blob/master/documentation/Windows%20Shortcut%20File%20(LNK)%20format.asciidoc * * - List of possible shell link header flags (SHELL_LINK_DATA_FLAGS enumeration): - * https://msdn.microsoft.com/en-us/library/windows/desktop/bb762540(v=vs.85).aspx - * https://msdn.microsoft.com/en-us/library/dd891314.aspx + * https://learn.microsoft.com/en-us/windows/win32/api/shlobj_core/ne-shlobj_core-shell_link_data_flags + * https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-shllink/ae350202-3ba9-4790-9e9e-98935f4ee5af * * * In addition to storing its target by using a PIDL, a shell link file also @@ -66,12 +66,12 @@ * * - The first and oldest one (from NewShell/WinNT4) is the "LinkInfo" structure, * stored in a serialized manner at the beginning of the shell link file: - * https://msdn.microsoft.com/en-us/library/dd871404.aspx + * https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-shllink/6813269d-0cc8-4be2-933f-e96e8e3412dc * The official API for manipulating this is located in LINKINFO.DLL . * * - The second, more recent one, is an extra binary block appended to the * extra-data list of the shell link file: this is the "TrackerDataBlock": - * https://msdn.microsoft.com/en-us/library/dd891376.aspx + * https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-shllink/df8e3748-fba5-4524-968a-f72be06d71fc * Its purpose is for link tracking, and works in coordination with the * "Distributed Link Tracking" service ('TrkWks' client, 'TrkSvr' server). * See a detailed explanation at: @@ -84,12 +84,12 @@ * The philosophy of this approach is explained in detail inside the MSDN article * "Application Resiliency: Unlock the Hidden Features of Windows Installer" * (by Michael Sanford), here: - * https://msdn.microsoft.com/en-us/library/aa302344.aspx + * https://learn.microsoft.com/en-us/previous-versions/dotnet/articles/aa302344(v=msdn.10) * * This functionality is implemented by adding a binary "Darwin" data block * of type "EXP_DARWIN_LINK", signature EXP_DARWIN_ID_SIG == 0xA0000006, * to the shell link file: - * https://msdn.microsoft.com/en-us/library/dd871369.aspx + * https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-shllink/48f8a4c4-99fe-4787-a39f-b1367103eba8 * or, this could be done more simply by specifying a special link target path * with the IShellLink::SetPath() function. Defining the following GUID: * SHELL32_AdvtShortcutComponent = "::{9db1186e-40df-11d1-aa8c-00c04fb67863}:" @@ -104,12 +104,12 @@ * older technology introduced in Internet Explorer 3 (and now obsolete since * Internet Explorer 7), called "MS Internet Component Download (MSICD)", see * this MSDN introductory article: - * https://msdn.microsoft.com/en-us/library/aa741198(v=vs.85).aspx + * https://learn.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/aa741198(v=vs.85) * and leveraged in Internet Explorer 4 with "Software Update Channels", see: - * https://msdn.microsoft.com/en-us/library/aa740931(v=vs.85).aspx + * https://learn.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/aa740931(v=vs.85) * Applications supporting this technology could present shell links having * a special target, see subsection "Modifying the Shortcut" in the article: - * https://msdn.microsoft.com/en-us/library/aa741201(v=vs.85).aspx#pub_shor + * https://learn.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/aa741201(v=vs.85)#pub_shor * * Similarly as for the MSI shortcuts, these MSICD shortcuts are created by * specifying a special link target path with the IShellLink::SetPath() function, @@ -129,7 +129,7 @@ * a different signature EXP_LOGO3_ID_SIG == 0xA0000007 . Such shell links are * called "Logo3" shortcuts. They were evoked in this user comment in "The Old * New Thing" blog: - * https://blogs.msdn.microsoft.com/oldnewthing/20121210-00/?p=5883#comment-1025083 + * https://web.archive.org/web/20190110073640/https://blogs.msdn.microsoft.com/oldnewthing/20121210-00/?p=5883#comment-1025083 * * The shell exports the API 'SoftwareUpdateMessageBox' (in shdocvw.dll) that * displays a message when an update for an application supporting this @@ -216,6 +216,22 @@ static LPWSTR __inline strdupW(LPCWSTR src) return dest; } +static BOOL PathEnvSubstIsDirectory(LPCWSTR pszPath) +{ + // Note: Don't call SHExpandEnvironmentStringsW here, we need the required length + WCHAR szStack[MAX_PATH]; + DWORD cch = ExpandEnvironmentStringsW(pszPath, szStack, _countof(szStack)); + if (cch <= _countof(szStack)) + return cch && PathIsDirectory(szStack); + + PWSTR szHeap = (PWSTR)SHAlloc(cch); + if (!szHeap) + return FALSE; + BOOL bResult = ExpandEnvironmentStringsW(pszPath, szHeap, cch) && PathIsDirectory(szHeap); + SHFree(szHeap); + return bResult; +} + // TODO: Use it for constructor & destructor too VOID CShellLink::Reset() { @@ -528,7 +544,7 @@ static BOOL Stream_LoadVolume(LOCAL_VOLUME_INFO *vol, CShellLink::volume_info *v INT len = vol->dwSize - vol->dwVolLabelOfs; LPSTR label = (LPSTR)vol; - label += vol->dwVolLabelOfs; + label += vol->dwVolLabelOfs; // FIXME: 0x14 Unicode MultiByteToWideChar(CP_ACP, 0, label, len, volume->label, _countof(volume->label)); return TRUE; @@ -579,7 +595,7 @@ static HRESULT Stream_LoadLocation(IStream *stm, /* if there's a local path, load it */ DWORD n = loc->dwLocalPathOfs; if (n && n < loc->dwTotalSize) - *path = Stream_LoadPath(&p[n], loc->dwTotalSize - n); + *path = Stream_LoadPath(&p[n], loc->dwTotalSize - n); // FIXME: Unicode offset (if present) TRACE("type %d serial %08x name %s path %s\n", volume->type, volume->serial, debugstr_w(volume->label), debugstr_w(*path)); @@ -834,7 +850,7 @@ static HRESULT Stream_WriteString(IStream* stm, LPCWSTR str) * Figure out how Windows deals with unicode paths here. */ static HRESULT Stream_WriteLocationInfo(IStream* stm, LPCWSTR path, - CShellLink::volume_info *volume) + CShellLink::volume_info *volume) // FIXME: Write Unicode strings { LOCAL_VOLUME_INFO *vol; LOCATION_INFO *loc; @@ -897,6 +913,7 @@ HRESULT STDMETHODCALLTYPE CShellLink::Save(IStream *stm, BOOL fClearDirty) m_Header.dwSize = sizeof(m_Header); m_Header.clsid = CLSID_ShellLink; + m_Header.dwReserved3 = m_Header.dwReserved2 = m_Header.wReserved1 = 0; /* Store target attributes */ WIN32_FIND_DATAW wfd = {}; @@ -918,8 +935,9 @@ HRESULT STDMETHODCALLTYPE CShellLink::Save(IStream *stm, BOOL fClearDirty) * already set in accordance by the different mutator member functions. * The other flags will be determined now by the presence or absence of data. */ - m_Header.dwFlags &= (SLDF_RUN_WITH_SHIMLAYER | SLDF_RUNAS_USER | - SLDF_RUN_IN_SEPARATE | SLDF_HAS_DARWINID | + UINT NT6SimpleFlags = LOBYTE(GetVersion()) > 6 ? (0x00040000 | 0x00400000 | 0x00800000 | 0x02000000) : 0; + m_Header.dwFlags &= (SLDF_RUN_WITH_SHIMLAYER | SLDF_RUNAS_USER | SLDF_RUN_IN_SEPARATE | + SLDF_HAS_DARWINID | SLDF_FORCE_NO_LINKINFO | NT6SimpleFlags | #if (NTDDI_VERSION < NTDDI_LONGHORN) SLDF_HAS_LOGO3ID | #endif @@ -1729,18 +1747,10 @@ HRESULT STDMETHODCALLTYPE CShellLink::GetIconLocation(LPWSTR pszIconPath, INT cc static HRESULT SHELL_PidlGetIconLocationW(PCIDLIST_ABSOLUTE pidl, UINT uFlags, PWSTR pszIconFile, UINT cchMax, int *piIndex, UINT *pwFlags) { - LPCITEMIDLIST pidlLast; - CComPtr psf; - - HRESULT hr = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &psf), &pidlLast); - if (FAILED_UNEXPECTEDLY(hr)) - return hr; - CComPtr pei; - hr = psf->GetUIObjectOf(0, 1, &pidlLast, IID_NULL_PPV_ARG(IExtractIconW, &pei)); + HRESULT hr = SHELL_GetUIObjectOfAbsoluteItem(NULL, pidl, IID_PPV_ARG(IExtractIconW, &pei)); if (FAILED_UNEXPECTEDLY(hr)) return hr; - hr = pei->GetIconLocation(uFlags, pszIconFile, cchMax, piIndex, pwFlags); if (FAILED_UNEXPECTEDLY(hr)) return hr; @@ -1782,6 +1792,7 @@ HRESULT STDMETHODCALLTYPE CShellLink::GetIconLocation(UINT uFlags, PWSTR pszIcon } else { + // TODO: If GetIconLocation succeeded, why are we setting GIL_NOTFILENAME? And are we not PERINSTANCE? *pwFlags = GIL_NOTFILENAME | GIL_PERCLASS; } @@ -2479,14 +2490,11 @@ HRESULT STDMETHODCALLTYPE CShellLink::GetFlags(DWORD *pdwFlags) HRESULT STDMETHODCALLTYPE CShellLink::SetFlags(DWORD dwFlags) { -#if 0 // FIXME! + if (m_Header.dwFlags == dwFlags) + return S_FALSE; m_Header.dwFlags = dwFlags; m_bDirty = TRUE; return S_OK; -#else - FIXME("\n"); - return E_NOTIMPL; -#endif } /************************************************************************** @@ -2567,13 +2575,12 @@ HRESULT STDMETHODCALLTYPE CShellLink::QueryContextMenu(HMENU hMenu, UINT indexMe if (!InsertMenuItemW(hMenu, indexMenu++, TRUE, &mii)) return E_FAIL; - UNREFERENCED_PARAMETER(indexMenu); - return MAKE_HRESULT(SEVERITY_SUCCESS, 0, id); } HRESULT CShellLink::DoOpenFileLocation() { + // TODO: SHOpenFolderAndSelectItems WCHAR szParams[MAX_PATH + 64]; StringCbPrintfW(szParams, sizeof(szParams), L"/select,%s", m_sPath); @@ -2675,7 +2682,7 @@ HRESULT CShellLink::DoOpen(LPCMINVOKECOMMANDINFO lpici) sei.nShow = lpici->nShow; // Allow invoker to override .lnk show mode // Use the invoker specified working directory if the link did not specify one - if (StrIsNullOrEmpty(sei.lpDirectory) || !PathIsDirectoryW(sei.lpDirectory)) + if (StrIsNullOrEmpty(sei.lpDirectory) || !PathEnvSubstIsDirectory(sei.lpDirectory)) { LPCSTR pszDirA = lpici->lpDirectory; if (unicode && !StrIsNullOrEmpty(iciex->lpDirectoryW)) @@ -2906,7 +2913,7 @@ BOOL CShellLink::OnInitDialog(HWND hwndDlg, HWND hwndFocus, LPARAM lParam) HWND hWndTarget = GetDlgItem(hwndDlg, IDC_SHORTCUT_TARGET_TEXT); EnableWindow(hWndTarget, !disablecontrols); - PostMessage(hWndTarget, EM_SETSEL, 0, -1); // Fix caret bug when first opening the tab + PostMessage(hWndTarget, EM_SETSEL, 0, -1); // Fix caret bug when first opening the tab [CORE-20016] /* auto-completion */ SHAutoComplete(hWndTarget, SHACF_DEFAULT); @@ -3142,20 +3149,9 @@ HRESULT STDMETHODCALLTYPE CShellLink::DragEnter(IDataObject *pDataObject, if (*pdwEffect == DROPEFFECT_NONE) return S_OK; - LPCITEMIDLIST pidlLast; - CComPtr psf; - - HRESULT hr = SHBindToParent(m_pPidl, IID_PPV_ARG(IShellFolder, &psf), &pidlLast); - + HRESULT hr = SHELL_GetUIObjectOfAbsoluteItem(NULL, m_pPidl, IID_PPV_ARG(IDropTarget, &m_DropTarget)); if (SUCCEEDED(hr)) - { - hr = psf->GetUIObjectOf(0, 1, &pidlLast, IID_NULL_PPV_ARG(IDropTarget, &m_DropTarget)); - - if (SUCCEEDED(hr)) - hr = m_DropTarget->DragEnter(pDataObject, dwKeyState, pt, pdwEffect); - else - *pdwEffect = DROPEFFECT_NONE; - } + hr = m_DropTarget->DragEnter(pDataObject, dwKeyState, pt, pdwEffect); else *pdwEffect = DROPEFFECT_NONE; diff --git a/dll/win32/shell32/brfolder.cpp b/dll/win32/shell32/brfolder.cpp index 7b211939ef174..0e8e5e791f7b7 100644 --- a/dll/win32/shell32/brfolder.cpp +++ b/dll/win32/shell32/brfolder.cpp @@ -15,7 +15,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell); +INT WINAPI Shell_GetCachedImageIndexW(LPCWSTR szPath, INT nIndex, UINT Flags); + #define SHV_CHANGE_NOTIFY (WM_USER + 0x1111) +enum { SHGDN_TREE = SHGDN_NORMAL | SHGDN_INFOLDER }; static LPITEMIDLIST ILCloneToDepth(LPCITEMIDLIST pidlSrc, UINT depth) @@ -33,14 +36,6 @@ ILCloneToDepth(LPCITEMIDLIST pidlSrc, UINT depth) return pidlOut; } -static INT -GetIconIndex(PCIDLIST_ABSOLUTE pidl, UINT uFlags) -{ - SHFILEINFOW sfi; - SHGetFileInfoW((LPCWSTR)pidl, 0, &sfi, sizeof(sfi), uFlags); - return sfi.iIcon; -} - struct BrFolder { LPBROWSEINFOW lpBrowseInfo; @@ -111,11 +106,12 @@ BrFolder_GetItemData(BrFolder *info, HTREEITEM hItem) } static SFGAOF -BrFolder_GetItemAttributes(BrFolder *info, HTREEITEM hItem, SFGAOF Att) +BrFolder_GetItemAttributes(BrFolder *info, HTREEITEM hItem, SFGAOF Query) { BrItemData *item = BrFolder_GetItemData(info, hItem); + SFGAOF Att = Query; HRESULT hr = item ? item->lpsfParent->GetAttributesOf(1, &item->pidlChild, &Att) : E_FAIL; - return SUCCEEDED(hr) ? Att : 0; + return SUCCEEDED(hr) ? (Query & Att) : 0; } static HRESULT @@ -203,15 +199,19 @@ BrFolder_InitTreeView(BrFolder *info) TreeView_Expand(info->hwndTreeView, hItem, TVE_EXPAND); } -static void -BrFolder_GetIconPair(PCIDLIST_ABSOLUTE pidl, LPTVITEMW pItem) +static HRESULT +BrFolder_GetIconPair(BrItemData &item, TVITEMW &tvi) { - static const ITEMIDLIST idlDesktop = { }; - if (!pidl) - pidl = &idlDesktop; - DWORD flags = SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON; - pItem->iImage = GetIconIndex(pidl, flags); - pItem->iSelectedImage = GetIconIndex(pidl, flags | SHGFI_OPENICON); + INT open = -1; + INT normal = SHMapPIDLToSystemImageListIndex(item.lpsfParent, item.pidlChild, &open); + if (normal >= 0) + { + tvi.iImage = normal; + tvi.iSelectedImage = (open >= 0) ? open : normal; + return S_OK; + } + tvi.iImage = tvi.iSelectedImage = Shell_GetCachedImageIndexW(swShell32Name, IDI_SHELL_FOLDER - 1, 0); + return S_FALSE; } /****************************************************************************** @@ -231,10 +231,10 @@ BrFolder_GetIconPair(PCIDLIST_ABSOLUTE pidl, LPTVITEMW pItem) */ static BOOL BrFolder_GetName( - IShellFolder *lpsf, - PCIDLIST_RELATIVE pidlChild, - DWORD dwFlags, - LPWSTR lpFriendlyName) + _In_ IShellFolder *lpsf, + _In_ PCIDLIST_RELATIVE pidlChild, + _In_ DWORD dwFlags, + _Out_ PWSTR lpFriendlyName) { BOOL bSuccess = FALSE; STRRET str; @@ -247,6 +247,18 @@ BrFolder_GetName( return bSuccess; } +static BOOL +BrFolder_GetName( + _In_ BrFolder *info, + _In_ HTREEITEM hItem, + _In_ UINT Flags, + _Out_ PWSTR Buffer) +{ + if (BrItemData *item = BrFolder_GetItemData(info, hItem)) + return BrFolder_GetName(item->lpsfParent, item->pidlChild, Flags, Buffer); + return FALSE; +} + static BOOL BrFolder_IsTreeItemInEnum( _Inout_ BrFolder *info, @@ -288,30 +300,82 @@ BrFolder_TreeItemHasThisChild( return FALSE; } -static void -BrFolder_UpdateItem( - _In_ BrFolder *info, - _In_ HTREEITEM hItem) +static HTREEITEM +BrFolder_FindTreeItemOfAbsoluteItem( + _In_ BrFolder &info, + _In_ PCIDLIST_ABSOLUTE pidl, + _In_opt_ HTREEITEM hItem = NULL) { - BrItemData *pItemData = BrFolder_GetItemData(info, hItem); - if (!pItemData) - return; + if (!hItem) + hItem = TreeView_GetRoot(info.hwndTreeView); - TVITEMW item = { TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN }; - item.hItem = hItem; + for (; pidl && hItem; hItem = TreeView_GetNextSibling(info.hwndTreeView, hItem)) + { + BrItemData *pItemData = BrFolder_GetItemData(&info, hItem); + if (ILIsEqual(pItemData->pidlFull, pidl)) + return hItem; + HTREEITEM hChild = TreeView_GetChild(info.hwndTreeView, hItem); + if (hChild && (hChild = BrFolder_FindTreeItemOfAbsoluteItem(info, pidl, hChild)) != NULL) + return hChild; + } + return NULL; +} + +static BOOL +BrFolder_UpdateItemEx( + _In_ BrFolder &info, + _In_ HTREEITEM hItem, + _In_opt_ PCIDLIST_ABSOLUTE pidlFull, + _In_ UINT Flags = TVIF_TEXT | TVIF_IMAGE | TVIF_CHILDREN) +{ + ASSERT(hItem); + TVITEMW item = { (TVIF_HANDLE | Flags), hItem }; + BrItemData *data = BrFolder_GetItemData(&info, hItem); + if (!data) + return FALSE; + + if (pidlFull) + { + if ((pidlFull = ILClone(pidlFull)) == NULL) + return FALSE; + data->pidlFull.Free(); + data->pidlFull.Attach(const_cast(pidlFull)); + data->pidlChild = ILFindLastID(data->pidlFull); + // Note: We assume lpsfParent does not change + } - BrFolder_GetIconPair(pItemData->pidlFull, &item); + WCHAR Name[MAX_PATH]; + if (Flags & TVIF_TEXT) + { + item.pszText = Name; + if (!BrFolder_GetName(data->lpsfParent, data->pidlChild, SHGDN_TREE, Name)) + return FALSE; + } + + if (Flags & TVIF_IMAGE) + { + item.mask |= TVIF_SELECTEDIMAGE; + BrFolder_GetIconPair(*data, item); + } item.cChildren = 0; CComPtr pEnum; - if (BrFolder_GetChildrenEnum(info, pItemData, &pEnum) == S_OK) + if ((Flags & TVIF_CHILDREN) && BrFolder_GetChildrenEnum(&info, data, &pEnum) == S_OK) { CComHeapPtr pidlTemp; if (pEnum->Next(1, &pidlTemp, NULL) == S_OK) ++item.cChildren; } - TreeView_SetItem(info->hwndTreeView, &item); + return TreeView_SetItem(info.hwndTreeView, &item); +} + +static void +BrFolder_UpdateItem( + _In_ BrFolder *info, + _In_ HTREEITEM hItem) +{ + BrFolder_UpdateItemEx(*info, hItem, NULL, TVIF_IMAGE | TVIF_CHILDREN); } /****************************************************************************** @@ -346,7 +410,7 @@ BrFolder_InsertItem( } WCHAR szName[MAX_PATH]; - if (!BrFolder_GetName(lpsf, pidlChild, SHGDN_NORMAL, szName)) + if (!BrFolder_GetName(lpsf, pidlChild, SHGDN_TREE, szName)) return NULL; BrItemData *pItemData = new BrItemData(); @@ -358,11 +422,11 @@ BrFolder_InsertItem( PIDLIST_ABSOLUTE pidlFull = (pidlParent ? ILCombine(pidlParent, pidlChild) : ILClone(pidlChild)); - BrFolder_GetIconPair(pidlFull, &item); pItemData->lpsfParent = lpsf; pItemData->pidlFull.Attach(pidlFull); pItemData->pidlChild = ILFindLastID(pItemData->pidlFull); + BrFolder_GetIconPair(*pItemData, item); if (BrFolder_GetChildrenEnum(info, pItemData, NULL) == S_OK) item.cChildren = 1; @@ -408,8 +472,8 @@ BrFolder_Expand( ULONG ulFetched; while (S_OK == pEnum->Next(1, &pidlTemp, &ulFetched)) { - if (!BrFolder_InsertItem(info, lpsf, pidlTemp, pidlFull, hParent)) - break; + /* Ignore return value of BrFolder_InsertItem to avoid incomplete folder listing */ + BrFolder_InsertItem(info, lpsf, pidlTemp, pidlFull, hParent); pidlTemp.Free(); // Finally, free the pidl that the shell gave us... } @@ -517,7 +581,7 @@ BrFolder_Treeview_Changed(BrFolder *info, NMTREEVIEWW *pnmtv) info->pidlRet = ILClone(pItemData->pidlFull); WCHAR szName[MAX_PATH]; - if (BrFolder_GetName(pItemData->lpsfParent, pItemData->pidlChild, SHGDN_NORMAL, szName)) + if (BrFolder_GetName(pItemData->lpsfParent, pItemData->pidlChild, SHGDN_NORMAL | SHGDN_INFOLDER, szName)) SetDlgItemTextW(info->hWnd, IDC_BROWSE_FOR_FOLDER_FOLDER_TEXT, szName); BrFolder_Callback(info->lpBrowseInfo, info->hWnd, BFFM_SELCHANGED, (LPARAM)info->pidlRet); @@ -537,8 +601,8 @@ BrFolder_Treeview_Rename(BrFolder *info, NMTVDISPINFOW *pnmtv) ASSERT(BrFolder_GetItemAttributes(info, hItem, SFGAO_CANRENAME) & SFGAO_CANRENAME); PITEMID_CHILD newChild; - HRESULT hr = data->lpsfParent->SetNameOf(info->hWnd, data->pidlChild, - pnmtv->item.pszText, SHGDN_NORMAL, &newChild); + HRESULT hr = data->lpsfParent->SetNameOf(info->hWnd, data->pidlChild, pnmtv->item.pszText, + SHGDN_NORMAL | SHGDN_INFOLDER, &newChild); if (FAILED(hr)) return FALSE; @@ -556,10 +620,14 @@ BrFolder_Treeview_Rename(BrFolder *info, NMTVDISPINFOW *pnmtv) } ILFree(newChild); + BOOL AllowTreeTextChange = !BrFolder_UpdateItemEx(*info, hItem, NULL, TVIF_TEXT); + NMTREEVIEWW nmtv; + nmtv.itemNew.hItem = hItem; + nmtv.itemNew.mask = TVIF_PARAM; nmtv.itemNew.lParam = (LPARAM)data; BrFolder_Treeview_Changed(info, &nmtv); - return TRUE; + return AllowTreeTextChange; } static HRESULT @@ -573,25 +641,18 @@ BrFolder_Rename(BrFolder *info, HTREEITEM hItem) static void BrFolder_Delete(BrFolder *info, HTREEITEM hItem) { - SHFILEOPSTRUCTW fileop = { info->hwndTreeView }; - WCHAR szzFrom[MAX_PATH + 1]; - - // Get item_data - BrItemData *item_data = BrFolder_GetItemData(info, hItem); - - // Get the path - if (!SHGetPathFromIDListW(item_data->pidlFull, szzFrom)) - { - ERR("SHGetPathFromIDListW failed\n"); + BrItemData *data = BrFolder_GetItemData(info, hItem); + if (!data || !BrFolder_GetItemAttributes(info, hItem, SFGAO_CANDELETE)) return; - } - szzFrom[lstrlenW(szzFrom) + 1] = UNICODE_NULL; // Double NULL-terminated - fileop.pFrom = szzFrom; - - // Delete folder - fileop.fFlags = FOF_ALLOWUNDO; - fileop.wFunc = FO_DELETE; - SHFileOperationW(&fileop); + CComPtr pCM; + if (FAILED(data->lpsfParent->GetUIObjectOf(info->hWnd, 1, &data->pidlChild, IID_NULL_PPV_ARG(IContextMenu, &pCM)))) + return; + UINT fCMIC = 0; + if (GetKeyState(VK_SHIFT) < 0) + fCMIC |= CMIC_MASK_SHIFT_DOWN; + if (GetKeyState(VK_CONTROL) < 0) + fCMIC |= CMIC_MASK_CONTROL_DOWN; + SHInvokeCommandOnContextMenu(info->hWnd, NULL, pCM, fCMIC, "delete"); } static void @@ -656,9 +717,18 @@ BrFolder_OnNotify(BrFolder *info, UINT CtlID, LPNMHDR lpnmh) case TVN_BEGINLABELEDITA: case TVN_BEGINLABELEDITW: { + HWND hWndEdit = TreeView_GetEditControl(lpnmh->hwndFrom); NMTVDISPINFO &tvdi = *(NMTVDISPINFO*)lpnmh; UINT att = BrFolder_GetItemAttributes(info, tvdi.item.hItem, SFGAO_CANRENAME); - return !(att & SFGAO_CANRENAME); + if (!(att & SFGAO_CANRENAME)) + { + MessageBeep(0xffffffff); + return S_FALSE; + } + WCHAR Name[MAX_PATH]; + if (BrFolder_GetName(info, tvdi.item.hItem, SHGDN_INFOLDER | SHGDN_FOREDITING, Name)) + SetWindowTextW(hWndEdit, Name); + return S_OK; } case TVN_ENDLABELEDITW: @@ -1186,11 +1256,31 @@ BrFolder_Refresh(_Inout_ BrFolder *info) static void BrFolder_OnChangeEx( _Inout_ BrFolder *info, - _In_ PCIDLIST_ABSOLUTE pidl0, _In_ PCIDLIST_ABSOLUTE pidl1, + _In_ PCIDLIST_ABSOLUTE pidl2, _In_ LONG event) { - TRACE("(%p)->(%p, %p, 0x%lX)\n", info, pidl0, pidl1, event); + TRACE("(%p)->(%p, %p, 0x%lX)\n", info, pidl1, pidl2, event); + + switch (event) + { + case SHCNE_RENAMEFOLDER: + case SHCNE_RENAMEITEM: + case SHCNE_UPDATEITEM: + { + UINT UpdateFlags = (event == SHCNE_UPDATEITEM) ? (TVIF_IMAGE | TVIF_CHILDREN) : (TVIF_TEXT); + if (HTREEITEM hTI = BrFolder_FindTreeItemOfAbsoluteItem(*info, pidl1)) + { + if (BrFolder_UpdateItemEx(*info, hTI, pidl2, UpdateFlags)) + { + if ((hTI = TreeView_GetParent(info->hwndTreeView, hTI)) != NULL) + TreeView_SortChildren(info->hwndTreeView, hTI, FALSE); + return; + } + } + break; + } + } switch (event) { diff --git a/dll/win32/shell32/debughlp.cpp b/dll/win32/shell32/debughlp.cpp index 6778418c7a8bd..79e314c8b00de 100644 --- a/dll/win32/shell32/debughlp.cpp +++ b/dll/win32/shell32/debughlp.cpp @@ -22,6 +22,17 @@ WINE_DEFAULT_DEBUG_CHANNEL(pidl); +static inline BYTE _dbg_ILGetType(LPCITEMIDLIST pidl) +{ + return pidl && pidl->mkid.cb >= 3 ? pidl->mkid.abID[0] : 0; +} + +static inline BYTE _dbg_ILGetFSType(LPCITEMIDLIST pidl) +{ + const BYTE type = _dbg_ILGetType(pidl); + return (type & PT_FOLDERTYPEMASK) == PT_FS ? type : 0; +} + static LPITEMIDLIST _dbg_ILGetNext(LPCITEMIDLIST pidl) { @@ -97,6 +108,9 @@ LPWSTR _dbg_ILGetTextPointerW(LPCITEMIDLIST pidl) if (pdata) { + if (_dbg_ILGetFSType(pidl) & PT_FS_UNICODE_FLAG) + return (LPWSTR)&(pdata->u.file.szNames); + switch (pdata->type) { case PT_GUID: @@ -126,9 +140,6 @@ LPWSTR _dbg_ILGetTextPointerW(LPCITEMIDLIST pidl) case PT_SHARE: /* return (LPSTR)&(pdata->u.network.szNames); */ return NULL; - - case PT_VALUEW: - return (LPWSTR)&(pdata->u.file.szNames); } } return NULL; @@ -271,7 +282,7 @@ static void pdump_impl (LPCITEMIDLIST pidl) char szName[MAX_PATH]; _dbg_ILSimpleGetText(pidltemp, szName, MAX_PATH); - if ( pData && (PT_FOLDER == type || PT_VALUE == type) ) + if (_dbg_ILGetFSType(pidltemp)) dwAttrib = pData->u.file.uFileAttribs; MESSAGE ("[%p] size=%04u type=%x attr=0x%08x name=%s (%s,%s)\n", @@ -288,7 +299,7 @@ static void pdump_impl (LPCITEMIDLIST pidl) char szName[MAX_PATH]; _dbg_ILSimpleGetText(pidltemp, szName, MAX_PATH); - if ( pData && (PT_FOLDER == type || PT_VALUE == type) ) + if (_dbg_ILGetFSType(pidltemp)) dwAttrib = pData->u.file.uFileAttribs; MESSAGE ("[%p] size=%04u type=%x attr=0x%08x name=%s (%s,%s)\n", @@ -441,7 +452,7 @@ const char * shdebugstr_guid( const struct _GUID *id ) } return wine_dbg_sprintf( "\n\t{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x} (%s)", - id->Data1, id->Data2, id->Data3, + (UINT)id->Data1, id->Data2, id->Data3, id->Data4[0], id->Data4[1], id->Data4[2], id->Data4[3], id->Data4[4], id->Data4[5], id->Data4[6], id->Data4[7], name ? name : "unknown" ); } diff --git a/dll/win32/shell32/dialogs/dialogs.cpp b/dll/win32/shell32/dialogs/dialogs.cpp index a01a442a50069..6e11361eea48e 100644 --- a/dll/win32/shell32/dialogs/dialogs.cpp +++ b/dll/win32/shell32/dialogs/dialogs.cpp @@ -151,9 +151,8 @@ DoLoadIcons(HWND hwndDlg, PPICK_ICON_CONTEXT pIconContext, LPCWSTR pszFile) } } - // Set the text and reset the edit control's modification flag SetDlgItemTextW(hwndDlg, IDC_EDIT_PATH, pIconContext->szPath); - SendDlgItemMessage(hwndDlg, IDC_EDIT_PATH, EM_SETMODIFY, FALSE, 0); + SendMessageW(pIconContext->hDlgCtrl, LB_SETCURSEL, 0, 0); if (pIconContext->nIcons == 0) { @@ -194,9 +193,7 @@ INT_PTR CALLBACK PickIconProc( HICON hIcon; INT index, count; WCHAR szText[MAX_PATH], szFilter[100]; - CStringW strTitle; OPENFILENAMEW ofn; - PPICK_ICON_CONTEXT pIconContext = (PPICK_ICON_CONTEXT)GetWindowLongPtr(hwndDlg, DWLP_USER); switch(uMsg) @@ -251,18 +248,11 @@ INT_PTR CALLBACK PickIconProc( case IDOK: { /* Check whether the path edit control has been modified; if so load the icons instead of validating */ - if (SendDlgItemMessage(hwndDlg, IDC_EDIT_PATH, EM_GETMODIFY, 0, 0)) + GetDlgItemTextW(hwndDlg, IDC_EDIT_PATH, szText, _countof(szText)); + if (lstrcmpiW(szText, pIconContext->szPath)) { - /* Reset the edit control's modification flag and retrieve the text */ - SendDlgItemMessage(hwndDlg, IDC_EDIT_PATH, EM_SETMODIFY, FALSE, 0); - GetDlgItemTextW(hwndDlg, IDC_EDIT_PATH, szText, _countof(szText)); - - // Load the icons if (!DoLoadIcons(hwndDlg, pIconContext, szText)) NoIconsInFile(hwndDlg, pIconContext); - - // Set the selection - SendMessageW(pIconContext->hDlgCtrl, LB_SETCURSEL, 0, 0); break; } @@ -293,6 +283,7 @@ INT_PTR CALLBACK PickIconProc( case IDC_BUTTON_PATH: { // Choose the module path + CStringW strTitle; szText[0] = 0; szFilter[0] = 0; ZeroMemory(&ofn, sizeof(ofn)); @@ -310,9 +301,6 @@ INT_PTR CALLBACK PickIconProc( // Load the icons if (!DoLoadIcons(hwndDlg, pIconContext, szText)) NoIconsInFile(hwndDlg, pIconContext); - - // Set the selection - SendMessageW(pIconContext->hDlgCtrl, LB_SETCURSEL, 0, 0); break; } @@ -331,8 +319,9 @@ INT_PTR CALLBACK PickIconProc( lpdis = (LPDRAWITEMSTRUCT)lParam; if (lpdis->itemID == (UINT)-1) break; - switch (lpdis->itemAction) + switch (lpdis->itemAction) // FIXME: MSDN says that more than one of these can be set { + // FIXME: ODA_FOCUS case ODA_SELECT: case ODA_DRAWENTIRE: { @@ -365,6 +354,7 @@ BOOL WINAPI PickIconDlg( UINT nMaxFile, INT* lpdwIconIndex) { + CCoInit ComInit; // For SHAutoComplete (CORE-20030) int res; WCHAR szExpandedPath[MAX_PATH]; @@ -583,7 +573,7 @@ static INT_PTR CALLBACK RunDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARA INT ic; WCHAR *psz, *pszExpanded, *parent = NULL; DWORD cchExpand; - SHELLEXECUTEINFOW sei; + SHELLEXECUTEINFOW sei = { sizeof(sei) }; NMRUNFILEDLGW nmrfd; ic = GetWindowTextLengthW(htxt); @@ -593,9 +583,6 @@ static INT_PTR CALLBACK RunDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARA return TRUE; } - ZeroMemory(&sei, sizeof(sei)); - sei.cbSize = sizeof(sei); - /* * Allocate a new MRU entry, we need to add two characters * for the terminating "\\1" part, then the NULL character. @@ -694,7 +681,7 @@ static INT_PTR CALLBACK RunDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARA EndDialog(hwnd, IDOK); break; } - else if (SUCCEEDED(ShellExecuteExW(&sei))) + else if (ShellExecuteExW(&sei)) { /* Call GetWindowText again in case the contents of the edit box have changed. */ GetWindowTextW(htxt, psz, ic + 1); diff --git a/dll/win32/shell32/dialogs/drive.cpp b/dll/win32/shell32/dialogs/drive.cpp index ff97054fcda5a..37175a05b8345 100644 --- a/dll/win32/shell32/dialogs/drive.cpp +++ b/dll/win32/shell32/dialogs/drive.cpp @@ -21,17 +21,35 @@ #include "precomp.h" #include +#include // For NtQueryObject WINE_DEFAULT_DEBUG_CHANNEL(shell); +extern BOOL IsDriveFloppyW(LPCWSTR pszDriveRoot); + typedef struct { - WCHAR Drive; + WCHAR Drive; // Note: This is the drive number, not a drive letter UINT Options; UINT Result; BOOL bFormattingNow; + HWND hWndMain; + HWND hWndTip, hWndTipTrigger; + struct tagTip { UNICODE_STRING Name; WCHAR Buffer[400]; } Tip; } FORMAT_DRIVE_CONTEXT, *PFORMAT_DRIVE_CONTEXT; +static inline BOOL +DevIoCtl(HANDLE hDevice, UINT Code, LPVOID pIn, UINT cbIn, LPVOID pOut, UINT cbOut) +{ + DWORD cb = 0; + return DeviceIoControl(hDevice, Code, pIn, cbIn, pOut, cbOut, &cb, NULL); +} + +static BOOL IsFloppy(PCWSTR pszDrive) +{ + return GetDriveTypeW(pszDrive) == DRIVE_REMOVABLE && IsDriveFloppyW(pszDrive); +} + /* * TODO: In Windows the Shell doesn't know by itself if a drive is * a system one or not but rather a packet message is being sent by @@ -47,18 +65,87 @@ typedef struct static BOOL IsSystemDrive(PFORMAT_DRIVE_CONTEXT pContext) { - WCHAR wszDriveLetter[6], wszSystemDrv[6]; + WCHAR wszSystemDrv[MAX_PATH]; + wszSystemDrv[0] = UNICODE_NULL; + GetSystemDirectory(wszSystemDrv, _countof(wszSystemDrv)); + return (wszSystemDrv[0] | 32) == pContext->Drive + L'a'; +} + +static HANDLE +OpenLogicalDriveHandle(WORD DriveNumber) +{ + const WCHAR szPath[] = { '\\', '\\', '?', '\\', WCHAR(DriveNumber + 'A'), ':', '\0' }; + return CreateFileW(szPath, FILE_READ_DATA, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + NULL, OPEN_EXISTING, 0, NULL); +} - wszDriveLetter[0] = pContext->Drive + L'A'; - StringCchCatW(wszDriveLetter, _countof(wszDriveLetter), L":"); +static BOOL +GetLogicalDriveSize(WORD DriveNumber, ULARGE_INTEGER &Result) +{ + BOOL bSuccess = FALSE; + const WCHAR szDrivePath[] = { WCHAR(DriveNumber + 'A'), ':', '\\', '\0' }; - if (!GetEnvironmentVariableW(L"SystemDrive", wszSystemDrv, _countof(wszSystemDrv))) - return FALSE; + HANDLE hDevice = OpenLogicalDriveHandle(DriveNumber); + if (hDevice != INVALID_HANDLE_VALUE) + { + GET_LENGTH_INFORMATION LengthInfo; + bSuccess = DevIoCtl(hDevice, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &LengthInfo, sizeof(LengthInfo)); + Result.QuadPart = LengthInfo.Length.QuadPart; + if (!bSuccess && GetDriveTypeW(szDrivePath) == DRIVE_REMOVABLE) // Blank floppy + { + DISK_GEOMETRY dg; + bSuccess = DevIoCtl(hDevice, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &dg, sizeof(dg)); + if (bSuccess) + Result.QuadPart = dg.Cylinders.QuadPart * dg.TracksPerCylinder * dg.SectorsPerTrack * dg.BytesPerSector; + } + CloseHandle(hDevice); + } + if (!bSuccess || !Result.QuadPart) + bSuccess = GetDiskFreeSpaceExW(szDrivePath, NULL, &Result, NULL); // Note: Not exact if NTFS quotas are in effect + return bSuccess; +} - if (!_wcsicmp(wszDriveLetter, wszSystemDrv)) - return TRUE; +static PWSTR +CreateTipText(FORMAT_DRIVE_CONTEXT &Ctx) +{ + HANDLE hDevice = OpenLogicalDriveHandle(Ctx.Drive); + if (hDevice == INVALID_HANDLE_VALUE) + return NULL; + + ULONG cb; + ZeroMemory(&Ctx.Tip, sizeof(Ctx.Tip)); + NtQueryObject(hDevice, ObjectNameInformation, &Ctx.Tip, sizeof(Ctx.Tip), &cb); + if (Ctx.Tip.Name.Buffer && Ctx.Tip.Name.Buffer[0] == '\\') + StringCbCatW(Ctx.Tip.Name.Buffer, sizeof(Ctx.Tip) - sizeof(UNICODE_STRING), L"\n"); + else + (Ctx.Tip.Name.Buffer = Ctx.Tip.Buffer)[0] = UNICODE_NULL; - return FALSE; + PARTITION_INFORMATION_EX pie; + if (!DevIoCtl(hDevice, IOCTL_DISK_GET_PARTITION_INFO_EX, NULL, 0, &pie, sizeof(pie))) + { + pie.PartitionStyle = PARTITION_STYLE_RAW; + PARTITION_INFORMATION pi; + if (DevIoCtl(hDevice, IOCTL_DISK_GET_PARTITION_INFO, NULL, 0, &pi, sizeof(pi))) + { + pie.PartitionStyle = PARTITION_STYLE_MBR; + pie.PartitionNumber = pi.PartitionNumber; + } + } + CloseHandle(hDevice); + + WCHAR szBuf[150], szGuid[39], *pszTip = Ctx.Tip.Name.Buffer; + szBuf[0] = UNICODE_NULL; + if (pie.PartitionStyle == PARTITION_STYLE_GPT) + { + StringFromGUID2(pie.Gpt.PartitionId, szGuid, _countof(szGuid)); + StringCchPrintfW(szBuf, _countof(szBuf), L"GPT %s %s", szGuid, pie.Gpt.Name); + } + if (pie.PartitionStyle == PARTITION_STYLE_MBR) + { + StringCchPrintfW(szBuf, _countof(szBuf), L"MBR (%d)", pie.PartitionNumber); + } + StringCbCatW(pszTip, sizeof(Ctx.Tip) - sizeof(Ctx.Tip.Name), szBuf); + return pszTip; } static BOOL @@ -162,9 +249,8 @@ InsertDefaultClusterSizeForFs(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext) WCHAR wszBuf[100] = {0}; WCHAR wszDefaultSize[100] = {0}; PCWSTR pwszFsSizeLimit; - WCHAR szDrive[] = L"C:\\"; INT iSelIndex; - ULARGE_INTEGER FreeBytesAvailableUser, TotalNumberOfBytes; + ULARGE_INTEGER TotalNumberOfBytes; DWORD ClusterSize; LRESULT lIndex; HWND hDlgCtrl; @@ -177,9 +263,7 @@ InsertDefaultClusterSizeForFs(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext) if (SendMessageW(hDlgCtrl, CB_GETLBTEXT, iSelIndex, (LPARAM)wszBuf) == CB_ERR) return; - szDrive[0] = pContext->Drive + L'A'; - - if (!GetDiskFreeSpaceExW(szDrive, &FreeBytesAvailableUser, &TotalNumberOfBytes, NULL)) + if (!GetLogicalDriveSize(pContext->Drive, TotalNumberOfBytes)) return; if (!_wcsicmp(wszBuf, L"FAT16") || @@ -250,6 +334,7 @@ InsertDefaultClusterSizeForFs(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext) } SendMessageW(GetDlgItem(hwndDlg, 28675), BM_SETCHECK, BST_UNCHECKED, 0); +#if 0 // TODO: Call EnableVolumeCompression if checked if (!_wcsicmp(wszBuf, L"EXT2") || !_wcsicmp(wszBuf, L"BtrFS") || !_wcsicmp(wszBuf, L"NTFS")) @@ -258,6 +343,7 @@ InsertDefaultClusterSizeForFs(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext) EnableWindow(GetDlgItem(hwndDlg, 28675), TRUE); } else +#endif { /* Disable the "Enable Compression" button */ EnableWindow(GetDlgItem(hwndDlg, 28675), FALSE); @@ -271,24 +357,49 @@ InsertDefaultClusterSizeForFs(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext) } } +static VOID +EnableFormatDriveDlgControls(HWND hwndDlg, int EnableState) +{ + BOOL CanClose = EnableState != 0, Enable = EnableState > 0; + HMENU hSysMenu = GetSystemMenu(hwndDlg, FALSE); + EnableMenuItem(hSysMenu, SC_CLOSE, MF_BYCOMMAND | (CanClose ? MF_ENABLED : MF_GRAYED)); + EnableWindow(GetDlgItem(hwndDlg, IDCANCEL), CanClose); + static const WORD id[] = { IDOK, 28673, 28677, 28680, 28679, 28674 }; + for (UINT i = 0; i < _countof(id); ++i) + EnableWindow(GetDlgItem(hwndDlg, id[i]), Enable); +} + static VOID InitializeFormatDriveDlg(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext) { - WCHAR szText[120]; - WCHAR szDrive[] = L"C:\\"; - WCHAR szFs[30] = L""; - INT cchText; - ULARGE_INTEGER FreeBytesAvailableUser, TotalNumberOfBytes; + WCHAR szDrive[] = { WCHAR(pContext->Drive + 'A'), ':', '\\', '\0' }; + WCHAR szText[120], szFs[30]; + SIZE_T cchText; + ULARGE_INTEGER TotalNumberOfBytes; DWORD dwIndex, dwDefault; UCHAR uMinor, uMajor; BOOLEAN Latest; HWND hwndFileSystems; + pContext->hWndMain = hwndDlg; + pContext->hWndTipTrigger = GetDlgItem(hwndDlg, 30000); + TTTOOLINFOW tool; + tool.cbSize = sizeof(tool); + tool.hwnd = hwndDlg; + tool.uFlags = TTF_SUBCLASS | TTF_IDISHWND | TTF_TRACK | TTF_ABSOLUTE; + tool.uId = (UINT_PTR)pContext->hWndTipTrigger; + tool.lpszText = LPSTR_TEXTCALLBACKW; + pContext->hWndTip = CreateWindowExW(WS_EX_TOPMOST, TOOLTIPS_CLASSW, NULL, WS_POPUP | + TTS_BALLOON | TTS_NOPREFIX | TTS_ALWAYSTIP, + 0, 0, 0, 0, hwndDlg, NULL, NULL, NULL); + SendMessageW(pContext->hWndTip, TTM_ADDTOOLW, 0, (LPARAM)&tool); + UINT nIcoSize = GetSystemMetrics(SM_CXSMICON); + HICON hIco = (HICON)LoadImageW(shell32_hInstance, MAKEINTRESOURCEW(IDI_SHELL_IDEA), IMAGE_ICON, nIcoSize, nIcoSize, LR_SHARED); + SendMessageW(pContext->hWndTipTrigger, STM_SETICON, (WPARAM)hIco, 0); + cchText = GetWindowTextW(hwndDlg, szText, _countof(szText) - 1); - if (cchText < 0) - cchText = 0; szText[cchText++] = L' '; - szDrive[0] = pContext->Drive + L'A'; + szFs[0] = UNICODE_NULL; if (GetVolumeInformationW(szDrive, &szText[cchText], _countof(szText) - cchText, NULL, NULL, NULL, szFs, _countof(szFs))) { if (szText[cchText] == UNICODE_NULL) @@ -309,7 +420,7 @@ InitializeFormatDriveDlg(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext) /* set window text */ SetWindowTextW(hwndDlg, szText); - if (GetDiskFreeSpaceExW(szDrive, &FreeBytesAvailableUser, &TotalNumberOfBytes, NULL)) + if (GetLogicalDriveSize(pContext->Drive, TotalNumberOfBytes)) { if (StrFormatByteSizeW(TotalNumberOfBytes.QuadPart, szText, _countof(szText))) { @@ -318,6 +429,11 @@ InitializeFormatDriveDlg(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext) SendDlgItemMessageW(hwndDlg, 28673, CB_SETCURSEL, 0, (LPARAM)0); } } + else + { + /* No known size, don't allow format (no partition or no floppy) */ + EnableFormatDriveDlgControls(hwndDlg, -1); + } if (pContext->Options & SHFMT_OPT_FULL) { @@ -330,9 +446,13 @@ InitializeFormatDriveDlg(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext) dwDefault = 0; hwndFileSystems = GetDlgItem(hwndDlg, 28677); - while(QueryAvailableFileSystemFormat(dwIndex, szText, &uMajor, &uMinor, &Latest)) + int iForceDefault = -1; + while (QueryAvailableFileSystemFormat(dwIndex, szText, &uMajor, &uMinor, &Latest)) { if (!_wcsicmp(szText, szFs)) + iForceDefault = dwDefault = dwIndex; /* default to the same filesystem */ + + if (iForceDefault < 0 && !_wcsicmp(szText, L"NTFS") && !IsFloppy(szDrive)) dwDefault = dwIndex; SendMessageW(hwndFileSystems, CB_ADDSTRING, 0, (LPARAM)szText); @@ -351,8 +471,12 @@ InitializeFormatDriveDlg(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext) InsertDefaultClusterSizeForFs(hwndDlg, pContext); } -static HWND FormatDrvDialog = NULL; -static BOOLEAN bSuccess = FALSE; +static inline PFORMAT_DRIVE_CONTEXT +GetFormatContext() +{ + // FormatEx does not allow us to specify a context parameter so we have to store it in the thread + return (PFORMAT_DRIVE_CONTEXT)NtCurrentTeb()->NtTib.ArbitraryUserPointer; +} static BOOLEAN NTAPI FormatExCB( @@ -360,26 +484,32 @@ FormatExCB( IN ULONG SubAction, IN PVOID ActionInfo) { + PFORMAT_DRIVE_CONTEXT pCtx = GetFormatContext(); + const WCHAR szDrive[] = { WCHAR(pCtx->Drive + 'A'), ':', '\\', '\0' }; + WCHAR szLabel[40]; PDWORD Progress; PBOOLEAN pSuccess; switch(Command) { case PROGRESS: Progress = (PDWORD)ActionInfo; - SendDlgItemMessageW(FormatDrvDialog, 28678, PBM_SETPOS, (WPARAM)*Progress, 0); + SendDlgItemMessageW(pCtx->hWndMain, 28678, PBM_SETPOS, (WPARAM)*Progress, 0); break; case DONE: pSuccess = (PBOOLEAN)ActionInfo; - bSuccess = (*pSuccess); - ShellMessageBoxW(shell32_hInstance, FormatDrvDialog, MAKEINTRESOURCEW(IDS_FORMAT_COMPLETE), MAKEINTRESOURCEW(IDS_FORMAT_TITLE), MB_OK | MB_ICONINFORMATION); - SendDlgItemMessageW(FormatDrvDialog, 28678, PBM_SETPOS, 0, 0); + pCtx->Result = (*pSuccess); + SendDlgItemMessageW(pCtx->hWndMain, 28679, WM_GETTEXT, _countof(szLabel), (LPARAM)szLabel); + SetVolumeLabelW(szDrive, *szLabel ? szLabel : NULL); + ShellMessageBoxW(shell32_hInstance, pCtx->hWndMain, MAKEINTRESOURCEW(IDS_FORMAT_COMPLETE), + MAKEINTRESOURCEW(IDS_FORMAT_TITLE), MB_OK | MB_ICONINFORMATION); + SendDlgItemMessageW(pCtx->hWndMain, 28678, PBM_SETPOS, 0, 0); break; case VOLUMEINUSE: case INSUFFICIENTRIGHTS: case FSNOTSUPPORTED: case CLUSTERSIZETOOSMALL: - bSuccess = FALSE; + pCtx->Result = FALSE; FIXME("Unsupported command in FormatExCB\n"); break; @@ -390,12 +520,12 @@ FormatExCB( return TRUE; } -VOID +static VOID FormatDrive(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext) { - WCHAR szDrive[4] = { L'C', ':', '\\', 0 }; - WCHAR szFileSys[40] = {0}; - WCHAR szLabel[40] = {0}; + WCHAR szDrive[] = { WCHAR(pContext->Drive + 'A'), ':', '\\', '\0' }; + WCHAR szFileSys[40]; + WCHAR szLabel[40]; INT iSelIndex; UINT Length; HWND hDlgCtrl; @@ -404,9 +534,6 @@ FormatDrive(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext) DWORD DriveType; FMIFS_MEDIA_FLAG MediaFlag = FMIFS_HARDDISK; - /* set volume path */ - szDrive[0] = pContext->Drive + L'A'; - /* get filesystem */ hDlgCtrl = GetDlgItem(hwndDlg, 28677); iSelIndex = SendMessageW(hDlgCtrl, CB_GETCURSEL, 0, 0); @@ -460,13 +587,6 @@ FormatDrive(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext) hDlgCtrl = GetDlgItem(hwndDlg, 28680); SendMessageW(hDlgCtrl, PBM_SETRANGE, 0, MAKELPARAM(0, 100)); - bSuccess = FALSE; - - /* FIXME - * will cause display problems - * when performing more than one format - */ - FormatDrvDialog = hwndDlg; /* See if the drive is removable or not */ DriveType = GetDriveTypeW(szDrive); @@ -492,6 +612,11 @@ FormatDrive(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext) } /* Format the drive */ + pContext->Result = FALSE; + NT_TIB &tib = NtCurrentTeb()->NtTib; + PVOID BakArbitraryUserPointer = tib.ArbitraryUserPointer; + tib.ArbitraryUserPointer = pContext; + FormatEx(szDrive, MediaFlag, szFileSys, @@ -500,8 +625,8 @@ FormatDrive(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext) ClusterSize, FormatExCB); - FormatDrvDialog = NULL; - if (!bSuccess) + tib.ArbitraryUserPointer = BakArbitraryUserPointer; + if (!pContext->Result) { pContext->Result = SHFMT_ERROR; } @@ -515,62 +640,48 @@ FormatDrive(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext) } } -struct FORMAT_DRIVE_PARAMS -{ - HWND hwndDlg; - PFORMAT_DRIVE_CONTEXT pContext; -}; -static unsigned __stdcall DoFormatDrive(void *args) + +static DWORD CALLBACK +FormatDriveThread(PVOID pThreadParameter) { - FORMAT_DRIVE_PARAMS *pParams = reinterpret_cast(args); - HWND hwndDlg = pParams->hwndDlg; - PFORMAT_DRIVE_CONTEXT pContext = pParams->pContext; + PFORMAT_DRIVE_CONTEXT pContext = (PFORMAT_DRIVE_CONTEXT)pThreadParameter; + HWND hwndDlg = pContext->hWndMain; + WCHAR szDrive[] = { WCHAR(pContext->Drive + 'A'), ':', '\\', '\0' }; - /* Disable controls during format */ - HMENU hSysMenu = GetSystemMenu(hwndDlg, FALSE); - EnableMenuItem(hSysMenu, SC_CLOSE, MF_BYCOMMAND | MF_GRAYED); - EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDCANCEL), FALSE); - EnableWindow(GetDlgItem(hwndDlg, 28673), FALSE); - EnableWindow(GetDlgItem(hwndDlg, 28677), FALSE); - EnableWindow(GetDlgItem(hwndDlg, 28680), FALSE); - EnableWindow(GetDlgItem(hwndDlg, 28679), FALSE); - EnableWindow(GetDlgItem(hwndDlg, 28674), FALSE); + /* Disable controls during format */ + EnableFormatDriveDlgControls(hwndDlg, FALSE); + + SHChangeNotify(SHCNE_MEDIAREMOVED, SHCNF_PATHW | SHCNF_FLUSH, szDrive, NULL); FormatDrive(hwndDlg, pContext); - /* Re-enable controls after format */ - EnableWindow(GetDlgItem(hwndDlg, IDOK), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDCANCEL), TRUE); - EnableWindow(GetDlgItem(hwndDlg, 28673), TRUE); - EnableWindow(GetDlgItem(hwndDlg, 28677), TRUE); - EnableWindow(GetDlgItem(hwndDlg, 28680), TRUE); - EnableWindow(GetDlgItem(hwndDlg, 28679), TRUE); - EnableWindow(GetDlgItem(hwndDlg, 28674), TRUE); - EnableMenuItem(hSysMenu, SC_CLOSE, MF_BYCOMMAND | MF_ENABLED); + if (pContext->Result != SHFMT_ERROR) + SHChangeNotify(SHCNE_MEDIAINSERTED, SHCNF_PATHW, szDrive, NULL); + SHChangeNotify(SHCNE_UPDATEITEM, SHCNF_PATHW, szDrive, NULL); + + /* Re-enable controls after format */ + EnableFormatDriveDlgControls(hwndDlg, TRUE); pContext->bFormattingNow = FALSE; - delete pParams; return 0; } static INT_PTR CALLBACK FormatDriveDlg(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { - PFORMAT_DRIVE_CONTEXT pContext; + PFORMAT_DRIVE_CONTEXT pContext = (PFORMAT_DRIVE_CONTEXT)GetWindowLongPtr(hwndDlg, DWLP_USER); switch(uMsg) { case WM_INITDIALOG: - InitializeFormatDriveDlg(hwndDlg, (PFORMAT_DRIVE_CONTEXT)lParam); SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)lParam); + InitializeFormatDriveDlg(hwndDlg, (PFORMAT_DRIVE_CONTEXT)lParam); return TRUE; case WM_COMMAND: switch(LOWORD(wParam)) { case IDOK: - pContext = (PFORMAT_DRIVE_CONTEXT)GetWindowLongPtr(hwndDlg, DWLP_USER); if (pContext->bFormattingNow) break; @@ -580,18 +691,10 @@ FormatDriveDlg(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) MB_OKCANCEL | MB_ICONWARNING) == IDOK) { pContext->bFormattingNow = TRUE; - - FORMAT_DRIVE_PARAMS *pParams = new FORMAT_DRIVE_PARAMS; - pParams->hwndDlg = hwndDlg; - pParams->pContext = pContext; - - unsigned tid; - HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, DoFormatDrive, pParams, 0, &tid); - CloseHandle(hThread); + SHCreateThread(FormatDriveThread, pContext, CTF_COINIT | CTF_PROCESS_REF | CTF_FREELIBANDEXIT, NULL); } break; case IDCANCEL: - pContext = (PFORMAT_DRIVE_CONTEXT)GetWindowLongPtr(hwndDlg, DWLP_USER); if (pContext->bFormattingNow) break; @@ -600,7 +703,6 @@ FormatDriveDlg(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) case 28677: // filesystem combo if (HIWORD(wParam) == CBN_SELENDOK) { - pContext = (PFORMAT_DRIVE_CONTEXT)GetWindowLongPtr(hwndDlg, DWLP_USER); if (pContext->bFormattingNow) break; @@ -608,6 +710,45 @@ FormatDriveDlg(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) } break; } + break; + case WM_NOTIFY: + { + NMTTDISPINFO &ttdi = *(NMTTDISPINFO*)lParam; + if (ttdi.hdr.code == TTN_NEEDTEXTW) + { + ttdi.uFlags |= TTF_DI_SETITEM; + if (PWSTR pszTip = CreateTipText(*pContext)) + ttdi.lpszText = pszTip; + } + break; + } + case WM_NEXTDLGCTL: + PostMessage(hwndDlg, WM_APP, TRUE, 0); // Delay our action until after focus has changed + break; + case WM_APP: // Show/Hide tip if tabbed to the info icon + { + TTTOOLINFOW tool; + tool.cbSize = sizeof(tool); + tool.hwnd = hwndDlg; + tool.uId = (UINT_PTR)pContext->hWndTipTrigger; + if (wParam && GetFocus() == pContext->hWndTipTrigger) + { + RECT r; + GetWindowRect(pContext->hWndTipTrigger, &r); + r.left += (r.right - r.left) / 2; + r.top += (r.bottom - r.top) / 2; + SendMessageW(pContext->hWndTip, TTM_TRACKPOSITION, 0, MAKELONG(r.left, r.top)); + SendMessageW(pContext->hWndTip, TTM_TRACKACTIVATE, TRUE, (LPARAM)&tool); + } + else + { + SendMessageW(pContext->hWndTip, TTM_TRACKACTIVATE, FALSE, (LPARAM)&tool); + } + break; + } + case WM_MOVING: + SendMessage(hwndDlg, WM_APP, FALSE, 0); + break; } return FALSE; } diff --git a/dll/win32/shell32/dialogs/drvdefext.cpp b/dll/win32/shell32/dialogs/drvdefext.cpp index f26413bea3a02..785de9daa1c1b 100644 --- a/dll/win32/shell32/dialogs/drvdefext.cpp +++ b/dll/win32/shell32/dialogs/drvdefext.cpp @@ -553,8 +553,13 @@ CDrvDefExt::GeneralPageProc( WCHAR wszCmd[MAX_PATH]; StringCbPrintfW(wszCmd, sizeof(wszCmd), wszBuf, pDrvDefExt->m_wszDrive[0]); + WCHAR* wszArgs = PathGetArgsW(wszCmd); + if (wszArgs && *wszArgs && wszArgs != wszCmd) + wszArgs[-1] = UNICODE_NULL; + else + wszArgs = NULL; - if (ShellExecuteW(hwndDlg, NULL, wszCmd, NULL, NULL, SW_SHOW) <= (HINSTANCE)32) + if (ShellExecuteW(hwndDlg, NULL, wszCmd, wszArgs, NULL, SW_SHOW) <= (HINSTANCE)32) ERR("Failed to create cleanup process %ls\n", wszCmd); } } @@ -573,11 +578,15 @@ CDrvDefExt::GeneralPageProc( if (lppsn->hdr.code == PSN_APPLY) { CDrvDefExt *pDrvDefExt = reinterpret_cast(GetWindowLongPtr(hwndDlg, DWLP_USER)); + + HRESULT hr = E_FAIL; + HWND hLabel = GetDlgItem(hwndDlg, 14000); WCHAR wszBuf[256]; + *wszBuf = UNICODE_NULL; + if (GetWindowTextW(hLabel, wszBuf, _countof(wszBuf)) || GetWindowTextLengthW(hLabel) == 0) + hr = CDrivesFolder::SetDriveLabel(hwndDlg, pDrvDefExt->m_wszDrive, wszBuf); - if (GetDlgItemTextW(hwndDlg, 14000, wszBuf, _countof(wszBuf))) - SetVolumeLabelW(pDrvDefExt->m_wszDrive, wszBuf); - SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FAILED(hr) ? PSNRET_INVALID : PSNRET_NOERROR); return TRUE; } } @@ -689,11 +698,39 @@ CDrvDefExt::~CDrvDefExt() } +struct CDrop +{ + HRESULT hr; + STGMEDIUM stgm; + HDROP hDrop; + + explicit CDrop(IDataObject *pDO) + { + FORMATETC format = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; + hDrop = SUCCEEDED(hr = pDO->GetData(&format, &stgm)) ? (HDROP)stgm.hGlobal : NULL; + } + + ~CDrop() + { + if (hDrop) + ReleaseStgMedium(&stgm); + } + + UINT GetCount() + { + return DragQueryFileW(hDrop, -1, NULL, 0); + } +}; + +static inline bool +IsValidDrivePath(PCWSTR Path) +{ + return GetDriveTypeW(Path) > DRIVE_NO_ROOT_DIR; +} + HRESULT WINAPI CDrvDefExt::Initialize(PCIDLIST_ABSOLUTE pidlFolder, IDataObject *pDataObj, HKEY hkeyProgID) { - FORMATETC format; - STGMEDIUM stgm; HRESULT hr; TRACE("%p %p %p %p\n", this, pidlFolder, pDataObj, hkeyProgID); @@ -701,24 +738,20 @@ CDrvDefExt::Initialize(PCIDLIST_ABSOLUTE pidlFolder, IDataObject *pDataObj, HKEY if (!pDataObj) return E_FAIL; - format.cfFormat = CF_HDROP; - format.ptd = NULL; - format.dwAspect = DVASPECT_CONTENT; - format.lindex = -1; - format.tymed = TYMED_HGLOBAL; - hr = pDataObj->GetData(&format, &stgm); - if (FAILED(hr)) + CDrop drop(pDataObj); + if (FAILED_UNEXPECTEDLY(hr = drop.hr)) return hr; - if (!DragQueryFileW((HDROP)stgm.hGlobal, 0, m_wszDrive, _countof(m_wszDrive))) + if (!DragQueryFileW(drop.hDrop, 0, m_wszDrive, _countof(m_wszDrive))) { ERR("DragQueryFileW failed\n"); - ReleaseStgMedium(&stgm); return E_FAIL; } - ReleaseStgMedium(&stgm); + if (drop.GetCount() > 1) + m_Multiple = pDataObj; + TRACE("Drive properties %ls\n", m_wszDrive); return S_OK; @@ -745,37 +778,75 @@ CDrvDefExt::GetCommandString(UINT_PTR idCmd, UINT uType, UINT *pwReserved, LPSTR return E_NOTIMPL; } -HRESULT WINAPI -CDrvDefExt::AddPages(LPFNADDPROPSHEETPAGE pfnAddPage, LPARAM lParam) +HRESULT +CDrvDefExt::AddMainPage(LPFNADDPROPSHEETPAGE pfnAddPage, LPARAM lParam) { - HPROPSHEETPAGE hPage; + WCHAR szTitle[MAX_PATH], *pszTitle = NULL; + if (m_Multiple) + { + CComHeapPtr pidl(SHSimpleIDListFromPathW(m_wszDrive)); + if (SUCCEEDED(SHGetNameAndFlagsW(pidl, SHGDN_INFOLDER, szTitle, _countof(szTitle), NULL))) + pszTitle = szTitle; + } + HPROPSHEETPAGE hPage; hPage = SH_CreatePropertySheetPageEx(IDD_DRIVE_PROPERTIES, GeneralPageProc, (LPARAM)this, - NULL, &PropSheetPageLifetimeCallback); + pszTitle, &PropSheetPageLifetimeCallback); HRESULT hr = AddPropSheetPage(hPage, pfnAddPage, lParam); if (FAILED_UNEXPECTEDLY(hr)) return hr; else AddRef(); // For PropSheetPageLifetimeCallback + return hr; +} + +HRESULT WINAPI +CDrvDefExt::AddPages(LPFNADDPROPSHEETPAGE pfnAddPage, LPARAM lParam) +{ + HRESULT hr = AddMainPage(pfnAddPage, lParam); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; - if (GetDriveTypeW(m_wszDrive) == DRIVE_FIXED) + if (m_Multiple) { - hPage = SH_CreatePropertySheetPage(IDD_DRIVE_TOOLS, - ExtraPageProc, - (LPARAM)this, - NULL); - if (hPage) - pfnAddPage(hPage, lParam); + CDrop drop(m_Multiple); + UINT count = SUCCEEDED(drop.hr) ? drop.GetCount() : 0; + for (UINT i = 0; ++i < count;) // Skipping the first drive since it already has a page + { + CComPtr SheetExt; + if (FAILED_UNEXPECTEDLY(hr = ShellObjectCreator(SheetExt))) + continue; + if (!DragQueryFileW(drop.hDrop, i, SheetExt->m_wszDrive, _countof(SheetExt->m_wszDrive))) + continue; + if (!IsValidDrivePath(SheetExt->m_wszDrive)) + continue; + + SheetExt->m_Multiple = m_Multiple; + SheetExt->AddMainPage(pfnAddPage, lParam); + } } - - if (GetDriveTypeW(m_wszDrive) != DRIVE_REMOTE) + else { - hPage = SH_CreatePropertySheetPage(IDD_DRIVE_HARDWARE, - HardwarePageProc, - (LPARAM)this, - NULL); - if (hPage) - pfnAddPage(hPage, lParam); + HPROPSHEETPAGE hPage; + if (GetDriveTypeW(m_wszDrive) == DRIVE_FIXED) + { + hPage = SH_CreatePropertySheetPage(IDD_DRIVE_TOOLS, + ExtraPageProc, + (LPARAM)this, + NULL); + if (hPage) + pfnAddPage(hPage, lParam); + } + + if (GetDriveTypeW(m_wszDrive) != DRIVE_REMOTE) + { + hPage = SH_CreatePropertySheetPage(IDD_DRIVE_HARDWARE, + HardwarePageProc, + (LPARAM)this, + NULL); + if (hPage) + pfnAddPage(hPage, lParam); + } } return S_OK; diff --git a/dll/win32/shell32/dialogs/drvdefext.h b/dll/win32/shell32/dialogs/drvdefext.h index 90cc6c7e109bc..ed555b481771f 100644 --- a/dll/win32/shell32/dialogs/drvdefext.h +++ b/dll/win32/shell32/dialogs/drvdefext.h @@ -38,6 +38,9 @@ class CDrvDefExt : WCHAR m_wszDrive[MAX_PATH]; UINT m_FreeSpacePerc; + CComPtr m_Multiple; + + HRESULT AddMainPage(LPFNADDPROPSHEETPAGE pfnAddPage, LPARAM lParam); public: CDrvDefExt(); diff --git a/dll/win32/shell32/dialogs/filedefext.cpp b/dll/win32/shell32/dialogs/filedefext.cpp index e8beb7f936ae3..ce7f1dbe3f2ed 100644 --- a/dll/win32/shell32/dialogs/filedefext.cpp +++ b/dll/win32/shell32/dialogs/filedefext.cpp @@ -299,17 +299,23 @@ CFileDefExt::InitOpensWithField(HWND hwndDlg) BOOL bUnknownApp = TRUE; LPCWSTR pwszExt = PathFindExtensionW(m_wszPath); + // TODO: Use ASSOCSTR_EXECUTABLE with ASSOCF_REMAPRUNDLL | ASSOCF_IGNOREBASECLASS if (RegGetValueW(HKEY_CLASSES_ROOT, pwszExt, L"", RRF_RT_REG_SZ, NULL, wszBuf, &dwSize) == ERROR_SUCCESS) { bUnknownApp = FALSE; StringCbCatW(wszBuf, sizeof(wszBuf), L"\\shell\\open\\command"); dwSize = sizeof(wszPath); + // FIXME: Missing FileExt check, see COpenWithList::SetDefaultHandler for details + // FIXME: Use HCR_GetDefaultVerbW to find the default verb if (RegGetValueW(HKEY_CLASSES_ROOT, wszBuf, L"", RRF_RT_REG_SZ, NULL, wszPath, &dwSize) == ERROR_SUCCESS) { /* Get path from command line */ ExpandEnvironmentStringsW(wszPath, wszBuf, _countof(wszBuf)); - PathRemoveArgs(wszBuf); - PathUnquoteSpacesW(wszBuf); + if (SHELL32_GetDllFromRundll32CommandLine(wszBuf, wszBuf, _countof(wszBuf)) != S_OK) + { + PathRemoveArgs(wszBuf); + PathUnquoteSpacesW(wszBuf); + } PathSearchAndQualify(wszBuf, wszPath, _countof(wszPath)); HICON hIcon; diff --git a/dll/win32/shell32/dialogs/filetypes.cpp b/dll/win32/shell32/dialogs/filetypes.cpp index a2206ad9fe93e..851e7fa2f7217 100644 --- a/dll/win32/shell32/dialogs/filetypes.cpp +++ b/dll/win32/shell32/dialogs/filetypes.cpp @@ -334,6 +334,7 @@ InitializeDefaultIcons(PFILE_TYPE_GLOBALS pG) { int idx = ImageList_AddIcon(pG->himlSmall, pG->hDefExtIconSmall); ASSERT(idx == 0); + DBG_UNREFERENCED_LOCAL_VARIABLE(idx); } } diff --git a/dll/win32/shell32/dialogs/item_prop.cpp b/dll/win32/shell32/dialogs/item_prop.cpp index 90160a8062e5f..5d00526a55ae1 100644 --- a/dll/win32/shell32/dialogs/item_prop.cpp +++ b/dll/win32/shell32/dialogs/item_prop.cpp @@ -17,6 +17,9 @@ SHELL_GetCaptionFromDataObject(IDataObject *pDO, LPWSTR Buf, UINT cchBuf) { hr = SHGetNameAndFlagsW(pidl, SHGDN_INFOLDER, Buf, cchBuf, NULL); ILFree(pidl); + + if (SUCCEEDED(hr) && DataObject_GetHIDACount(pDO) > 1) + StringCchCatW(Buf, cchBuf, L", ..."); } return hr; } @@ -47,6 +50,7 @@ struct ShellPropSheetDialog CLSID ClsidDefault; const CLSID *pClsidDefault; IStream *pObjStream; + HANDLE hEvent; }; static void FreeData(DATA *pData) @@ -74,6 +78,7 @@ struct ShellPropSheetDialog pData->ClsidDefault = *pClsidDefault; pData->pClsidDefault = &pData->ClsidDefault; } + HANDLE hEvent = pData->hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); HRESULT hr = S_OK; if (pDO) @@ -86,17 +91,35 @@ struct ShellPropSheetDialog pData->pObjStream->Release(); hr = E_FAIL; } - if (FAILED(hr)) + + if (SUCCEEDED(hr)) + { + if (hEvent) + { + DWORD index; + // Pump COM messages until the thread can create its own IDataObject (for CORE-19933). + // SHOpenPropSheetW is modal and we cannot wait for it to complete. + CoWaitForMultipleHandles(COWAIT_DEFAULT, INFINITE, 1, &hEvent, &index); + CloseHandle(hEvent); + } + } + else + { FreeData(pData); + } return hr; } static DWORD CALLBACK ShowPropertiesThread(LPVOID Param) { DATA *pData = (DATA*)Param; - CComPtr pDO; + CComPtr pDO, pLocalDO; if (pData->pObjStream) CoGetInterfaceAndReleaseStream(pData->pObjStream, IID_PPV_ARG(IDataObject, &pDO)); + if (pDO && SUCCEEDED(SHELL_CloneDataObject(pDO, &pLocalDO))) + pDO = pLocalDO; + if (pData->hEvent) + SetEvent(pData->hEvent); Show(pData->pClsidDefault, pDO, pData->InitFunc, pData->InitString); FreeData(pData); return 0; @@ -110,7 +133,15 @@ FSFolderItemPropDialogInitCallback(LPCWSTR InitString, IDataObject *pDO, HKEY *h CDataObjectHIDA cida(pDO); if (SUCCEEDED(cida.hr()) && cida->cidl) { +#if 0 + CCidaChildArrayHelper items(cida); + if (FAILED(hr = items.hr())) + return hr; +#else + // Note: Since we are only passing a single item to AddFSClassKeysToArray, + // we don't need the rest of the array to be valid. PCUITEMID_CHILD pidl = HIDA_GetPIDLItem(cida, 0); +#endif AddFSClassKeysToArray(1, &pidl, hKeys, cKeys); // Add file-type specific pages } } @@ -134,7 +165,7 @@ SHELL32_ShowFilesystemItemPropertiesDialogAsync(IDataObject *pDO) ShellPropSheetDialog::PFNINITIALIZE InitFunc = NULL; LPCWSTR InitString = NULL; - if (_ILIsDrive(HIDA_GetPIDLItem(cida, 0))) + if (cida->cidl && _ILIsDrive(HIDA_GetPIDLItem(cida, 0))) { pClsid = &CLSID_ShellDrvDefExt; InitFunc = ClassPropDialogInitCallback; @@ -149,6 +180,18 @@ SHELL32_ShowFilesystemItemPropertiesDialogAsync(IDataObject *pDO) return Dialog.ShowAsync(pClsid, pDO, InitFunc, InitString); } +HRESULT +SHELL32_ShowFilesystemItemsPropertiesDialogAsync(HWND hOwner, IDataObject *pDO) +{ + if (DataObject_GetHIDACount(pDO) == 1) + return SHELL32_ShowFilesystemItemPropertiesDialogAsync(pDO); + + ERR("SHMultiFileProperties is not implemented yet\n"); + HRESULT hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + SHELL_ErrorBox(hOwner, hr); + return hr; // TODO: return SHMultiFileProperties(pDO, 0); +} + HRESULT SHELL32_ShowShellExtensionProperties(const CLSID *pClsid, IDataObject *pDO) { diff --git a/dll/win32/shell32/dialogs/recycler_prop.cpp b/dll/win32/shell32/dialogs/recycler_prop.cpp index d7f79251a3e74..72387de388cf8 100644 --- a/dll/win32/shell32/dialogs/recycler_prop.cpp +++ b/dll/win32/shell32/dialogs/recycler_prop.cpp @@ -45,6 +45,9 @@ static void toggleNukeOnDeleteOption(HWND hwndDlg, BOOL bEnable) EnableWindow(GetDlgItem(hwndDlg, 14002), TRUE); SendDlgItemMessage(hwndDlg, 14003, BM_SETCHECK, BST_UNCHECKED, 0); } + + // FIXME: Max capacity not implemented yet, disable for now (CORE-13743) + EnableWindow(GetDlgItem(hwndDlg, 14002), FALSE); } static VOID @@ -129,7 +132,8 @@ InitializeRecycleBinDlg(HWND hwndDlg, WCHAR DefaultDrive) swprintf(szName, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\BitBucket\\Volume\\%04X-%04X", LOWORD(dwSerial), HIWORD(dwSerial)); dwSize = sizeof(DWORD); - RegGetValueW(HKEY_CURRENT_USER, szName, L"MaxCapacity", RRF_RT_DWORD, NULL, &pItem->dwMaxCapacity, &dwSize); + if (RegGetValueW(HKEY_CURRENT_USER, szName, L"MaxCapacity", RRF_RT_DWORD, NULL, &pItem->dwMaxCapacity, &dwSize)) + pItem->dwMaxCapacity = ~0; /* Check if the maximum capacity doesn't exceed the available disk space (in megabytes), and truncate it if needed */ FreeBytesAvailable.QuadPart = (FreeBytesAvailable.QuadPart / (1024 * 1024)); @@ -240,7 +244,7 @@ static VOID FreeDriveItemContext(HWND hwndDlg) } static INT -GetDefaultItem(HWND hwndDlg, LVITEMW* li) +GetSelectedDriveItem(HWND hwndDlg, LVITEMW* li) { HWND hDlgCtrl; UINT iItemCount, iIndex; @@ -275,6 +279,7 @@ RecycleBinDlg( WPARAM wParam, LPARAM lParam) { + enum { WM_NEWDRIVESELECTED = WM_APP, WM_UPDATEDRIVESETTINGS }; LPPSHNOTIFY lppsn; LPNMLISTVIEW lppl; LVITEMW li; @@ -329,25 +334,9 @@ RecycleBinDlg( ss.fNoConfirmRecycle = SendDlgItemMessage(hwndDlg, 14004, BM_GETCHECK, 0, 0) == BST_UNCHECKED; SHGetSetSettings(&ss, SSF_NOCONFIRMRECYCLE, TRUE); - if (GetDefaultItem(hwndDlg, &li) > -1) + if (GetSelectedDriveItem(hwndDlg, &li) > -1) { - pItem = (PDRIVE_ITEM_CONTEXT)li.lParam; - if (pItem) - { - uResult = GetDlgItemInt(hwndDlg, 14002, &bSuccess, FALSE); - if (bSuccess) - { - /* Check if the maximum capacity doesn't exceed the available disk space (in megabytes), and truncate it if needed */ - FreeBytesAvailable = pItem->FreeBytesAvailable; - FreeBytesAvailable.QuadPart = (FreeBytesAvailable.QuadPart / (1024 * 1024)); - pItem->dwMaxCapacity = min(uResult, FreeBytesAvailable.LowPart); - SetDlgItemInt(hwndDlg, 14002, pItem->dwMaxCapacity, FALSE); - } - if (SendDlgItemMessageW(hwndDlg, 14003, BM_GETCHECK, 0, 0) == BST_CHECKED) - pItem->dwNukeOnDelete = TRUE; - else - pItem->dwNukeOnDelete = FALSE; - } + SendMessage(hwndDlg, WM_UPDATEDRIVESETTINGS, 0, li.lParam); } if (StoreDriveSettings(hwndDlg)) { @@ -369,31 +358,45 @@ RecycleBinDlg( if (!(lppl->uOldState & LVIS_FOCUSED) && (lppl->uNewState & LVIS_FOCUSED)) { - /* new focused item */ - toggleNukeOnDeleteOption(lppl->hdr.hwndFrom, pItem->dwNukeOnDelete); - SetDlgItemInt(hwndDlg, 14002, pItem->dwMaxCapacity, FALSE); + // New focused item, delay handling until after kill focus has been processed + PostMessage(hwndDlg, WM_NEWDRIVESELECTED, 0, (LPARAM)pItem); } else if ((lppl->uOldState & LVIS_FOCUSED) && !(lppl->uNewState & LVIS_FOCUSED)) { - /* kill focus */ - uResult = GetDlgItemInt(hwndDlg, 14002, &bSuccess, FALSE); - if (bSuccess) - { - /* Check if the maximum capacity doesn't exceed the available disk space (in megabytes), and truncate it if needed */ - FreeBytesAvailable = pItem->FreeBytesAvailable; - FreeBytesAvailable.QuadPart = (FreeBytesAvailable.QuadPart / (1024 * 1024)); - pItem->dwMaxCapacity = min(uResult, FreeBytesAvailable.LowPart); - SetDlgItemInt(hwndDlg, 14002, pItem->dwMaxCapacity, FALSE); - } - if (SendDlgItemMessageW(hwndDlg, 14003, BM_GETCHECK, 0, 0) == BST_CHECKED) - pItem->dwNukeOnDelete = TRUE; - else - pItem->dwNukeOnDelete = FALSE; + // Kill focus + SendMessage(hwndDlg, WM_UPDATEDRIVESETTINGS, 0, (LPARAM)pItem); } return TRUE; } break; + case WM_NEWDRIVESELECTED: + if (lParam) + { + pItem = (PDRIVE_ITEM_CONTEXT)lParam; + toggleNukeOnDeleteOption(hwndDlg, pItem->dwNukeOnDelete); + SetDlgItemInt(hwndDlg, 14002, pItem->dwMaxCapacity, FALSE); + } + break; + case WM_UPDATEDRIVESETTINGS: + if (lParam) + { + pItem = (PDRIVE_ITEM_CONTEXT)lParam; + uResult = GetDlgItemInt(hwndDlg, 14002, &bSuccess, FALSE); + if (bSuccess) + { + /* Check if the maximum capacity doesn't exceed the available disk space (in megabytes), and truncate it if needed */ + FreeBytesAvailable = pItem->FreeBytesAvailable; + FreeBytesAvailable.QuadPart = (FreeBytesAvailable.QuadPart / (1024 * 1024)); + pItem->dwMaxCapacity = min(uResult, FreeBytesAvailable.LowPart); + SetDlgItemInt(hwndDlg, 14002, pItem->dwMaxCapacity, FALSE); + } + if (SendDlgItemMessageW(hwndDlg, 14003, BM_GETCHECK, 0, 0) == BST_CHECKED) + pItem->dwNukeOnDelete = TRUE; + else + pItem->dwNukeOnDelete = FALSE; + } + break; case WM_DESTROY: FreeDriveItemContext(hwndDlg); break; diff --git a/dll/win32/shell32/dialogs/view.cpp b/dll/win32/shell32/dialogs/view.cpp index 9bc8662c0888b..87f4c2704974a 100644 --- a/dll/win32/shell32/dialogs/view.cpp +++ b/dll/win32/shell32/dialogs/view.cpp @@ -249,7 +249,7 @@ ViewTree_InsertAll(HWND hwndTreeView) static BOOL ViewTree_LoadTree(HKEY hKey, LPCWSTR pszKeyName, DWORD dwParentID) { - DWORD dwIndex; + DWORD dwIndex = ~0UL; WCHAR szKeyName[64], szText[MAX_PATH], *pch; DWORD Size, Value; PVIEWTREE_ENTRY pAllocated; @@ -975,9 +975,12 @@ FolderOptionsViewDlg( case IDC_VIEW_RESET_ALL: { HRESULT hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + bool ResetToDefault = LOWORD(wParam) == IDC_VIEW_RESET_ALL; CFolderOptions *pFO = (CFolderOptions*)GetWindowLongPtr(hwndDlg, GWL_USERDATA); if (pFO) - hr = pFO->ApplyDefFolderSettings(LOWORD(wParam) == IDC_VIEW_RESET_ALL); + hr = pFO->ApplyDefFolderSettings(ResetToDefault); // Use IBrowserService2 + if (ResetToDefault && hr == HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED)) + hr = CFolderOptions::ResetGlobalAndDefViewFolderSettings(); // No browser if (FAILED(hr)) SHELL_ErrorBox(hwndDlg, hr); break; diff --git a/dll/win32/shell32/droptargets/CFSDropTarget.cpp b/dll/win32/shell32/droptargets/CFSDropTarget.cpp index fce1a88d5b8a8..458886bb5a66a 100644 --- a/dll/win32/shell32/droptargets/CFSDropTarget.cpp +++ b/dll/win32/shell32/droptargets/CFSDropTarget.cpp @@ -24,6 +24,11 @@ WINE_DEFAULT_DEBUG_CHANNEL (shell); +#define D_NONE DROPEFFECT_NONE +#define D_COPY DROPEFFECT_COPY +#define D_MOVE DROPEFFECT_MOVE +#define D_LINK DROPEFFECT_LINK + static void SHELL_StripIllegalFsNameCharacters(_Inout_ LPWSTR Buf) { for (LPWSTR src = Buf, dst = src;;) @@ -38,6 +43,17 @@ static void SHELL_StripIllegalFsNameCharacters(_Inout_ LPWSTR Buf) } } +static bool PathIsSameDrive(LPCWSTR Path1, LPCWSTR Path2) +{ + int d1 = PathGetDriveNumberW(Path1), d2 = PathGetDriveNumberW(Path2); + return d1 == d2 && d2 >= 0; +} + +static bool PathIsDriveRoot(LPCWSTR Path) +{ + return PathIsRootW(Path) && PathGetDriveNumberW(Path) >= 0; +} + static HRESULT SHELL_LimitDropEffectToItemAttributes(_In_ IDataObject *pDataObject, _Inout_ PDWORD pdwEffect) { @@ -134,7 +150,8 @@ CFSDropTarget::CFSDropTarget(): m_fAcceptFmt(FALSE), m_sPathTarget(NULL), m_hwndSite(NULL), - m_grfKeyState(0) + m_grfKeyState(0), + m_AllowedEffects(0) { } @@ -147,13 +164,7 @@ HRESULT CFSDropTarget::Initialize(LPWSTR PathTarget) if (!m_cfShellIDList) return E_FAIL; - m_sPathTarget = (WCHAR *)SHAlloc((wcslen(PathTarget) + 1) * sizeof(WCHAR)); - if (!m_sPathTarget) - return E_OUTOFMEMORY; - - wcscpy(m_sPathTarget, PathTarget); - - return S_OK; + return SHStrDupW(PathTarget, &m_sPathTarget); } CFSDropTarget::~CFSDropTarget() @@ -202,7 +213,13 @@ BOOL CFSDropTarget::_QueryDrop(DWORD dwKeyState, LPDWORD pdwEffect) *pdwEffect = DROPEFFECT_NONE; if (m_fAcceptFmt) { /* Does our interpretation of the keystate ... */ - *pdwEffect = KeyStateToDropEffect (dwKeyState); + *pdwEffect = KeyStateToDropEffect(dwKeyState); + + // Transform disallowed move to a copy + if ((*pdwEffect & D_MOVE) && (m_AllowedEffects & (D_MOVE | D_COPY)) == D_COPY) + *pdwEffect = D_COPY; + + *pdwEffect &= m_AllowedEffects; if (*pdwEffect == DROPEFFECT_NONE) *pdwEffect = dwEffect; @@ -320,6 +337,9 @@ HRESULT WINAPI CFSDropTarget::DragEnter(IDataObject *pDataObject, { TRACE("(%p)->(DataObject=%p)\n", this, pDataObject); + const BOOL bAnyKeyMod = dwKeyState & (MK_SHIFT | MK_CONTROL); + m_AllowedEffects = *pdwEffect; + if (*pdwEffect == DROPEFFECT_NONE) return S_OK; @@ -337,11 +357,9 @@ HRESULT WINAPI CFSDropTarget::DragEnter(IDataObject *pDataObject, m_grfKeyState = dwKeyState; -#define D_NONE DROPEFFECT_NONE -#define D_COPY DROPEFFECT_COPY -#define D_MOVE DROPEFFECT_MOVE -#define D_LINK DROPEFFECT_LINK - m_dwDefaultEffect = *pdwEffect; + SHELL_LimitDropEffectToItemAttributes(pDataObject, pdwEffect); + m_AllowedEffects = *pdwEffect; + m_dwDefaultEffect = m_AllowedEffects; switch (*pdwEffect & (D_COPY | D_MOVE | D_LINK)) { case D_COPY | D_MOVE: @@ -378,19 +396,24 @@ HRESULT WINAPI CFSDropTarget::DragEnter(IDataObject *pDataObject, WCHAR wstrFirstFile[MAX_PATH]; if (DragQueryFileW((HDROP)medium.hGlobal, 0, wstrFirstFile, _countof(wstrFirstFile))) { - /* Check if the drive letter is different */ - if (wstrFirstFile[0] != m_sPathTarget[0]) + if (!PathIsSameDrive(wstrFirstFile, m_sPathTarget) && m_dwDefaultEffect != D_LINK) { m_dwDefaultEffect = DROPEFFECT_COPY; } + + if (!bAnyKeyMod && PathIsDriveRoot(wstrFirstFile) && (m_AllowedEffects & DROPEFFECT_LINK)) + { + m_dwDefaultEffect = DROPEFFECT_LINK; // Don't copy a drive by default + } } ReleaseStgMedium(&medium); } if (!m_fAcceptFmt) - *pdwEffect = DROPEFFECT_NONE; + m_AllowedEffects = DROPEFFECT_NONE; else *pdwEffect = m_dwDefaultEffect; + *pdwEffect &= m_AllowedEffects; return S_OK; } @@ -445,7 +468,7 @@ HRESULT WINAPI CFSDropTarget::Drop(IDataObject *pDataObject, if (*pdwEffect == DROPEFFECT_MOVE && m_site) { CComPtr psfv; - HRESULT hr = IUnknown_QueryService(m_site, SID_IFolderView, IID_PPV_ARG(IShellFolderView, &psfv)); + HRESULT hr = IUnknown_QueryService(m_site, SID_SFolderView, IID_PPV_ARG(IShellFolderView, &psfv)); if (SUCCEEDED(hr) && psfv->IsDropOnSource(this) == S_OK) { _RepositionItems(psfv, pDataObject, pt); @@ -471,7 +494,7 @@ HRESULT WINAPI CFSDropTarget::Drop(IDataObject *pDataObject, data->pt = pt; // Need to dereference as pdweffect gets freed. data->pdwEffect = *pdwEffect; - SHCreateThread(CFSDropTarget::_DoDropThreadProc, data, NULL, NULL); + SHCreateThread(CFSDropTarget::_DoDropThreadProc, data, CTF_COINIT | CTF_PROCESS_REF, NULL); return S_OK; } } @@ -521,7 +544,7 @@ HRESULT CFSDropTarget::_DoDrop(IDataObject *pDataObject, bLinking = TRUE; } - if (SUCCEEDED(pDataObject->QueryGetData(&fmt))) + if (SUCCEEDED(hr = pDataObject->QueryGetData(&fmt))) { hr = pDataObject->GetData(&fmt, &medium); TRACE("CFSTR_SHELLIDLIST\n"); @@ -599,7 +622,7 @@ HRESULT CFSDropTarget::_DoDrop(IDataObject *pDataObject, // If the target is a virtual item, we ask for the friendly name because SHGDN_FORPARSING will return a GUID. BOOL UseParsing = (att & (SFGAO_FILESYSTEM | SFGAO_FOLDER)) == SFGAO_FILESYSTEM; DWORD ShgdnFor = UseParsing ? SHGDN_FORPARSING : SHGDN_FOREDITING; - hr = Shell_DisplayNameOf(psfFrom, apidl[i], ShgdnFor | SHGDN_INFOLDER, targetName, _countof(targetName)); + hr = DisplayNameOfW(psfFrom, apidl[i], ShgdnFor | SHGDN_INFOLDER, targetName, _countof(targetName)); } if (FAILED_UNEXPECTEDLY(hr)) { @@ -675,11 +698,11 @@ HRESULT CFSDropTarget::_DoDrop(IDataObject *pDataObject, _ILFreeaPidl(apidl, lpcida->cidl); ReleaseStgMedium(&medium); } - else if (SUCCEEDED(pDataObject->QueryGetData(&fmt2))) + else if (SUCCEEDED(hr = pDataObject->QueryGetData(&fmt2))) { FORMATETC fmt2; InitFormatEtc (fmt2, CF_HDROP, TYMED_HGLOBAL); - if (SUCCEEDED(pDataObject->GetData(&fmt2, &medium)) /* && SUCCEEDED(pDataObject->GetData(&fmt2, &medium))*/) + if (SUCCEEDED(hr = pDataObject->GetData(&fmt2, &medium)) /* && SUCCEEDED(pDataObject->GetData(&fmt2, &medium))*/) { WCHAR wszTargetPath[MAX_PATH + 1]; LPWSTR pszSrcList; @@ -726,7 +749,6 @@ HRESULT CFSDropTarget::_DoDrop(IDataObject *pDataObject, DWORD WINAPI CFSDropTarget::_DoDropThreadProc(LPVOID lpParameter) { - CoInitialize(NULL); _DoDropData *data = static_cast<_DoDropData*>(lpParameter); CComPtr pDataObject; HRESULT hr = CoGetInterfaceAndReleaseStream (data->pStream, IID_PPV_ARG(IDataObject, &pDataObject)); @@ -744,7 +766,6 @@ DWORD WINAPI CFSDropTarget::_DoDropThreadProc(LPVOID lpParameter) data->This->Release(); //Release the parameter from the heap. HeapFree(GetProcessHeap(), 0, data); - CoUninitialize(); return 0; } diff --git a/dll/win32/shell32/droptargets/CFSDropTarget.h b/dll/win32/shell32/droptargets/CFSDropTarget.h index 706164d8f6df5..bde59979c240e 100644 --- a/dll/win32/shell32/droptargets/CFSDropTarget.h +++ b/dll/win32/shell32/droptargets/CFSDropTarget.h @@ -35,6 +35,7 @@ class CFSDropTarget : HWND m_hwndSite; DWORD m_grfKeyState; DWORD m_dwDefaultEffect; + DWORD m_AllowedEffects; CComPtr m_site; BOOL _QueryDrop (DWORD dwKeyState, LPDWORD pdwEffect); diff --git a/dll/win32/shell32/folders/CDesktopFolder.cpp b/dll/win32/shell32/folders/CDesktopFolder.cpp index 945f3450edede..370a614285e3e 100644 --- a/dll/win32/shell32/folders/CDesktopFolder.cpp +++ b/dll/win32/shell32/folders/CDesktopFolder.cpp @@ -49,11 +49,23 @@ static BOOL IsSelf(UINT cidl, PCUITEMID_CHILD_ARRAY apidl) static const CLSID* IsRegItem(PCUITEMID_CHILD pidl) { - if (pidl && pidl->mkid.cb == 2 + 2 + sizeof(CLSID) && pidl->mkid.abID[0] == PT_GUID) + if (pidl && pidl->mkid.cb == 2 + 2 + sizeof(CLSID) && pidl->mkid.abID[0] == PT_DESKTOP_REGITEM) return (const CLSID*)(&pidl->mkid.abID[2]); return NULL; } +static bool IsRegItem(PCUITEMID_CHILD pidl, REFCLSID clsid) +{ + const CLSID *pClass = IsRegItem(pidl); + return pClass && *pClass == clsid; +} + +static inline void MarkAsCommonItem(LPITEMIDLIST pidl) +{ + ASSERT(_ILGetFSType(pidl) & PT_FS); + ((PIDLDATA*)pidl->mkid.abID)->type |= PT_FS_COMMON_FLAG; +} + STDMETHODIMP CDesktopFolder::ShellUrlParseDisplayName( HWND hwndOwner, @@ -201,8 +213,19 @@ class CDesktopFolderEnum : /* Enumerate the items in the two fs folders */ AppendItemsFromEnumerator(pDesktopEnumerator); + ENUMLIST *pCommon = this->mpLast; AppendItemsFromEnumerator(pCommonDesktopEnumerator); - + if (pCommon != this->mpLast) // Any common items added? + { + ENUMLIST fake; + if (!pCommon) // In the unlikely case that there are no RegItems nor user items + { + fake.pNext = this->mpFirst; + pCommon = &fake; + } + while ((pCommon = pCommon->pNext) != NULL) + MarkAsCommonItem(pCommon->pidl); + } return S_OK; } @@ -281,22 +304,20 @@ HRESULT WINAPI CDesktopFolder::FinalConstruct() HRESULT CDesktopFolder::_GetSFFromPidl(LPCITEMIDLIST pidl, IShellFolder2** psf) { - WCHAR szFileName[MAX_PATH]; - - if (_ILIsSpecialFolder(pidl)) + if (IsRegItem(pidl)) return m_regFolder->QueryInterface(IID_PPV_ARG(IShellFolder2, psf)); - - lstrcpynW(szFileName, sPathTarget, MAX_PATH - 1); - PathAddBackslashW(szFileName); - int cLen = wcslen(szFileName); - - if (!_ILSimpleGetTextW(pidl, szFileName + cLen, MAX_PATH - cLen)) - return E_FAIL; - - if (GetFileAttributes(szFileName) == INVALID_FILE_ATTRIBUTES) - return m_SharedDesktopFSFolder->QueryInterface(IID_PPV_ARG(IShellFolder2, psf)); - else - return m_DesktopFSFolder->QueryInterface(IID_PPV_ARG(IShellFolder2, psf)); +#if DBG + if (_ILIsDesktop(pidl)) + { + FIXME("Desktop is unexpected here!\n"); + } + else if (_ILIsSpecialFolder(pidl)) + { + FIXME("Unexpected PIDL type %#x\n", pidl->mkid.abID[0]); + } +#endif + IShellFolder *pSF = IsCommonItem(pidl) ? m_SharedDesktopFSFolder : m_DesktopFSFolder; + return pSF->QueryInterface(IID_PPV_ARG(IShellFolder2, psf)); } HRESULT CDesktopFolder::_ParseDisplayNameByParent( @@ -502,6 +523,8 @@ HRESULT WINAPI CDesktopFolder::ParseDisplayName( pchEaten, ppidl, pdwAttributes); + if (SUCCEEDED(hr)) + MarkAsCommonItem(*ppidl); } if (FAILED(hr) && bCreate && m_DesktopFSFolder) @@ -604,7 +627,10 @@ HRESULT WINAPI CDesktopFolder::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl if (_ILIsSpecialFolder(pidl1) || _ILIsSpecialFolder(pidl2)) return m_regFolder->CompareIDs(lParam, pidl1, pidl2); - return m_DesktopFSFolder->CompareIDs(lParam, pidl1, pidl2); + HRESULT ret = m_DesktopFSFolder->CompareIDs(lParam, pidl1, pidl2); + if (ret == 0 && ((lParam & SHCIDS_COLUMNMASK) == SHFSF_COL_NAME || (lParam & (SHCIDS_ALLFIELDS | SHCIDS_CANONICALONLY)))) + ret = MAKE_COMPARE_HRESULT(IsCommonItem(pidl1) - IsCommonItem(pidl2)); + return ret; } /************************************************************************** @@ -688,14 +714,14 @@ HRESULT WINAPI CDesktopFolder::GetAttributesOf( /* TODO: always add SFGAO_CANLINK */ for (UINT i = 0; i < cidl; ++i) { - pdump(*apidl); - if (_ILIsDesktop(*apidl)) + pdump(apidl[i]); + if (_ILIsDesktop(apidl[i])) *rgfInOut &= dwDesktopAttributes; else if (_ILIsMyComputer(apidl[i])) *rgfInOut &= dwMyComputerAttributes; - else if (_ILIsNetHood(apidl[i])) + else if (IsRegItem(apidl[i], CLSID_NetworkPlaces)) *rgfInOut &= dwMyNetPlacesAttributes; - else if (_ILIsFolder(apidl[i]) || _ILIsValue(apidl[i]) || _ILIsSpecialFolder(apidl[i])) + else if (_ILIsFolderOrFile(apidl[i]) || _ILIsSpecialFolder(apidl[i])) { CComPtr psf; HRESULT hr = _GetSFFromPidl(apidl[i], &psf); diff --git a/dll/win32/shell32/folders/CDesktopFolder.h b/dll/win32/shell32/folders/CDesktopFolder.h index 0f8ea5a35a266..b117ac2c8d7a6 100644 --- a/dll/win32/shell32/folders/CDesktopFolder.h +++ b/dll/win32/shell32/folders/CDesktopFolder.h @@ -75,6 +75,8 @@ class CDesktopFolder : ~CDesktopFolder(); HRESULT WINAPI FinalConstruct(); + static inline BOOL IsCommonItem(LPCITEMIDLIST pidl) { return _ILGetFSType(pidl) & PT_FS_COMMON_FLAG; } + // *** IShellFolder methods *** STDMETHOD(ParseDisplayName)(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName, DWORD *pchEaten, PIDLIST_RELATIVE *ppidl, DWORD *pdwAttributes) override; STDMETHOD(EnumObjects)(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList) override; @@ -125,7 +127,7 @@ class CDesktopFolder : } if (ppwszInvalidChars) { - SHStrDupW(INVALID_FILETITLE_CHARACTERSW, ppwszInvalidChars); + return SHStrDupW(INVALID_FILETITLE_CHARACTERSW, ppwszInvalidChars); } return S_OK; } diff --git a/dll/win32/shell32/folders/CDrivesFolder.cpp b/dll/win32/shell32/folders/CDrivesFolder.cpp index 040511f03e918..5fcf9d94a7e6a 100644 --- a/dll/win32/shell32/folders/CDrivesFolder.cpp +++ b/dll/win32/shell32/folders/CDrivesFolder.cpp @@ -78,6 +78,34 @@ static const CLSID* IsRegItem(PCUITEMID_CHILD pidl) return NULL; } +static bool IsRegItem(PCUITEMID_CHILD pidl, REFCLSID clsid) +{ + const CLSID *pClass = IsRegItem(pidl); + return pClass && *pClass == clsid; +} + +static INT8 GetDriveNumber(PCUITEMID_CHILD pidl) +{ + if (!_ILIsDrive(pidl)) + return -1; + BYTE letter = ((PIDLDATA*)pidl->mkid.abID)->u.drive.szDriveName[0]; + BYTE number = (letter | 32) - 'a'; + return number < 26 ? number : -1; +} + +template static T* GetDrivePath(PCUITEMID_CHILD pidl, T *Path) +{ + int number = GetDriveNumber(pidl); + if (number < 0) + return NULL; + Path[0] = 'A' + number; + Path[1] = ':'; + Path[2] = '\\'; + Path[3] = '\0'; + return Path; +} + + BOOL _ILGetDriveType(LPCITEMIDLIST pidl) { WCHAR szDrive[8]; @@ -232,7 +260,13 @@ HRESULT CALLBACK DrivesContextMenuCallback(IShellFolder *psf, return E_FAIL; } nDriveType = GetDriveTypeW(szDrive); - GetVolumeInformationW(szDrive, NULL, 0, NULL, NULL, &dwFlags, NULL, 0); + if (!GetVolumeInformationW(szDrive, NULL, 0, NULL, NULL, &dwFlags, NULL, 0)) + { + if (nDriveType >= DRIVE_REMOTE) + dwFlags = FILE_READ_ONLY_VOLUME; + else + dwFlags = 0; // Assume drive with unknown filesystem, allow format + } // custom command IDs #if 0 // Disabled until our menu building system is fixed @@ -253,7 +287,7 @@ HRESULT CALLBACK DrivesContextMenuCallback(IShellFolder *psf, UINT idCmdFirst = pqcminfo->idCmdFirst; UINT idCmd = 0; - if (!(dwFlags & FILE_READ_ONLY_VOLUME) && nDriveType != DRIVE_REMOTE) + if (!(dwFlags & FILE_READ_ONLY_VOLUME) && nDriveType != DRIVE_REMOTE && cidl == 1) { /* add separator and Format */ idCmd = idCmdFirst + CMDID_FORMAT; @@ -409,7 +443,7 @@ getIconLocationForDrive(IShellFolder *psf, PCITEMID_CHILD pidl, UINT uFlags, } static HRESULT -getLabelForDrive(LPWSTR wszPath, LPWSTR wszLabel) +getLabelForDriveFromAutoRun(PCWSTR wszPath, LPWSTR szLabel, UINT cchMax) { WCHAR wszAutoRunInfPath[MAX_PATH]; WCHAR wszTemp[MAX_PATH]; @@ -423,13 +457,26 @@ getLabelForDrive(LPWSTR wszPath, LPWSTR wszLabel) if (GetPrivateProfileStringW(L"autorun", L"label", NULL, wszTemp, _countof(wszTemp), wszAutoRunInfPath) && wszTemp[0] != 0) { - StringCchCopyW(wszLabel, _countof(wszTemp), wszTemp); + StringCchCopyW(szLabel, cchMax, wszTemp); return S_OK; } return E_FAIL; } +static inline HRESULT GetRawDriveLabel(PCWSTR DrivePath, LPWSTR szLabel, UINT cchMax) +{ + if (GetVolumeInformationW(DrivePath, szLabel, cchMax, NULL, NULL, NULL, NULL, 0)) + return *szLabel ? S_OK : S_FALSE; + return HResultFromWin32(GetLastError()); +} + +static HRESULT GetDriveLabel(PCWSTR DrivePath, LPWSTR szLabel, UINT cchMax) +{ + HRESULT hr = getLabelForDriveFromAutoRun(DrivePath, szLabel, cchMax); + return hr == S_OK ? S_OK : GetRawDriveLabel(DrivePath, szLabel, cchMax); +} + BOOL IsDriveFloppyA(LPCSTR pszDriveRoot); HRESULT CDrivesExtractIcon_CreateInstance(IShellFolder * psf, LPCITEMIDLIST pidl, REFIID riid, LPVOID * ppvOut) @@ -552,16 +599,17 @@ static const shvheader MyComputerSFHeader[] = { static const DWORD dwComputerAttributes = SFGAO_CANRENAME | SFGAO_CANDELETE | SFGAO_HASPROPSHEET | SFGAO_DROPTARGET | - SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_HASSUBFOLDER; + SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_CANLINK; static const DWORD dwControlPanelAttributes = SFGAO_HASSUBFOLDER | SFGAO_FOLDER | SFGAO_CANLINK; static const DWORD dwDriveAttributes = SFGAO_HASSUBFOLDER | SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_FILESYSANCESTOR | - SFGAO_DROPTARGET | SFGAO_HASPROPSHEET | SFGAO_CANRENAME | SFGAO_CANLINK; + SFGAO_DROPTARGET | SFGAO_HASPROPSHEET | SFGAO_CANRENAME | SFGAO_CANLINK | SFGAO_CANCOPY; CDrivesFolder::CDrivesFolder() { pidlRoot = NULL; + m_DriveDisplayMode = -1; } CDrivesFolder::~CDrivesFolder() @@ -611,10 +659,9 @@ HRESULT WINAPI CDrivesFolder::ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLEST pdwAttributes); } - if (lpszDisplayName[0] && - ((L'A' <= lpszDisplayName[0] && lpszDisplayName[0] <= L'Z') || + if (((L'A' <= lpszDisplayName[0] && lpszDisplayName[0] <= L'Z') || (L'a' <= lpszDisplayName[0] && lpszDisplayName[0] <= L'z')) && - lpszDisplayName[1] == L':' && lpszDisplayName[2] == L'\\') + lpszDisplayName[1] == L':' && (lpszDisplayName[2] == L'\\' || !lpszDisplayName[2])) { // "C:\..." WCHAR szRoot[8]; @@ -630,7 +677,7 @@ HRESULT WINAPI CDrivesFolder::ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLEST if (!pidlTemp) return E_OUTOFMEMORY; - if (lpszDisplayName[3]) + if (lpszDisplayName[2] && lpszDisplayName[3]) { CComPtr pChildFolder; hr = BindToObject(pidlTemp, pbc, IID_PPV_ARG(IShellFolder, &pChildFolder)); @@ -841,7 +888,6 @@ HRESULT WINAPI CDrivesFolder::GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY a if (*rgfInOut == 0) *rgfInOut = ~0; - /* FIXME: always add SFGAO_CANLINK */ if(cidl == 0) *rgfInOut &= dwComputerAttributes; else @@ -855,7 +901,7 @@ HRESULT WINAPI CDrivesFolder::GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY a if (_ILGetDriveType(apidl[i]) == DRIVE_CDROM) *rgfInOut &= ~SFGAO_CANRENAME; // CD-ROM drive cannot rename } - else if (_ILIsControlPanel(apidl[i])) + else if (IsRegItem(apidl[i], CLSID_ControlPanel)) { *rgfInOut &= dwControlPanelAttributes; } @@ -948,8 +994,7 @@ HRESULT WINAPI CDrivesFolder::GetUIObjectOf(HWND hwndOwner, */ HRESULT WINAPI CDrivesFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET strRet) { - LPWSTR pszPath; - HRESULT hr = S_OK; + WCHAR szDrive[8]; TRACE("(%p)->(pidl=%p,0x%08x,%p)\n", this, pidl, dwFlags, strRet); pdump (pidl); @@ -965,81 +1010,76 @@ HRESULT WINAPI CDrivesFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFla { return m_regFolder->GetDisplayNameOf(pidl, dwFlags, strRet); } - else if (!_ILIsDrive(pidl)) + else if (!GetDrivePath(pidl, szDrive)) { ERR("Wrong pidl type\n"); return E_INVALIDARG; } - pszPath = (LPWSTR)CoTaskMemAlloc((MAX_PATH + 1) * sizeof(WCHAR)); + PWSTR pszPath = (LPWSTR)CoTaskMemAlloc((MAX_PATH + 1) * sizeof(WCHAR)); if (!pszPath) return E_OUTOFMEMORY; + pszPath[0] = UNICODE_NULL; + szDrive[0] &= ~32; // Always uppercase - pszPath[0] = 0; - - _ILSimpleGetTextW(pidl, pszPath, MAX_PATH); /* append my own path */ /* long view "lw_name (C:)" */ + BOOL bEditLabel = GET_SHGDN_RELATION(dwFlags) == SHGDN_INFOLDER && (dwFlags & SHGDN_FOREDITING); if (!(dwFlags & SHGDN_FORPARSING)) { - WCHAR wszDrive[18] = {0}; - - lstrcpynW(wszDrive, pszPath, 4); - pszPath[0] = L'\0'; - - if (!SUCCEEDED(getLabelForDrive(wszDrive, pszPath))) + if (m_DriveDisplayMode < 0) { - DWORD dwVolumeSerialNumber, dwMaximumComponentLength, dwFileSystemFlags; + DWORD err, type, data, cb = sizeof(data); + err = SHRegGetUSValueW(L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer", + L"ShowDriveLettersFirst", &type, &data, &cb, FALSE, NULL, 0); + m_DriveDisplayMode = (!err && type == REG_DWORD && cb == sizeof(data)) ? (BYTE)data : 0; + } + BOOL bRemoteFirst = m_DriveDisplayMode == 1; + BOOL bNoLetter = m_DriveDisplayMode == 2; + BOOL bAllFirst = m_DriveDisplayMode == 4; + PWSTR pszLabel = pszPath; - GetVolumeInformationW(wszDrive, pszPath, - MAX_PATH - 7, - &dwVolumeSerialNumber, - &dwMaximumComponentLength, &dwFileSystemFlags, NULL, 0); - pszPath[MAX_PATH-1] = L'\0'; + if (!bNoLetter && (bAllFirst || (bRemoteFirst && GetDriveTypeW(szDrive) == DRIVE_REMOTE))) + { + bNoLetter = TRUE; // Handling the letter now, don't append it again later + if (!bEditLabel) + pszLabel += wsprintfW(pszPath, L"(%c:) ", szDrive[0]); + } - if (!wcslen(pszPath)) + if (GetDriveLabel(szDrive, pszLabel, MAX_PATH - 7) != S_OK && !bEditLabel) + { + UINT ResourceId = 0; + switch (GetDriveTypeW(szDrive)) { - UINT DriveType, ResourceId; - DriveType = GetDriveTypeW(wszDrive); - - switch (DriveType) - { - case DRIVE_FIXED: - ResourceId = IDS_DRIVE_FIXED; - break; - case DRIVE_REMOTE: - ResourceId = IDS_DRIVE_NETWORK; - break; - case DRIVE_CDROM: - ResourceId = IDS_DRIVE_CDROM; - break; - default: - ResourceId = 0; - } - - if (ResourceId) - { - dwFileSystemFlags = LoadStringW(shell32_hInstance, ResourceId, pszPath, MAX_PATH); - if (dwFileSystemFlags > MAX_PATH - 7) - pszPath[MAX_PATH-7] = L'\0'; - } + case DRIVE_REMOVABLE: ResourceId = IDS_DRIVE_REMOVABLE; break; // TODO: Floppy (cached) + case DRIVE_FIXED: ResourceId = IDS_DRIVE_FIXED; break; + case DRIVE_REMOTE: ResourceId = IDS_DRIVE_NETWORK; break; + case DRIVE_CDROM: ResourceId = IDS_DRIVE_CDROM; break; + } + if (ResourceId) + { + UINT len = LoadStringW(shell32_hInstance, ResourceId, pszLabel, MAX_PATH - 7); + if (len > MAX_PATH - 7) + pszLabel[MAX_PATH-7] = UNICODE_NULL; } } - wcscat(pszPath, L" ("); - wszDrive[2] = L'\0'; - wcscat(pszPath, wszDrive); - wcscat(pszPath, L")"); + + if (!*pszLabel && !bEditLabel) // No label nor fallback description, use SHGDN_FORPARSING + *pszPath = UNICODE_NULL; + else if (!bNoLetter && !bEditLabel) + wsprintfW(pszPath + wcslen(pszPath), L" (%c:)", szDrive[0]); } - if (SUCCEEDED(hr)) + if (!*pszPath && !bEditLabel) // SHGDN_FORPARSING or failure above (except editing empty label) { - strRet->uType = STRRET_WSTR; - strRet->pOleStr = pszPath; + if (GET_SHGDN_RELATION(dwFlags) == SHGDN_INFOLDER) + szDrive[2] = UNICODE_NULL; // Remove backslash + wcscpy(pszPath, szDrive); } - else - CoTaskMemFree(pszPath); + strRet->uType = STRRET_WSTR; + strRet->pOleStr = pszPath; TRACE("-- (%p)->(%s)\n", this, strRet->uType == STRRET_CSTR ? strRet->cStr : debugstr_w(strRet->pOleStr)); - return hr; + return S_OK; } /************************************************************************** @@ -1057,20 +1097,27 @@ HRESULT WINAPI CDrivesFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFla HRESULT WINAPI CDrivesFolder::SetNameOf(HWND hwndOwner, PCUITEMID_CHILD pidl, LPCOLESTR lpName, DWORD dwFlags, PITEMID_CHILD *pPidlOut) { - WCHAR szName[30]; - if (_ILIsDrive(pidl)) { - if (_ILSimpleGetTextW(pidl, szName, _countof(szName))) - SetVolumeLabelW(szName, lpName); + WCHAR szDrive[8]; + HRESULT hr = GetDrivePath(pidl, szDrive) ? SetDriveLabel(hwndOwner, szDrive, lpName) : E_FAIL; if (pPidlOut) - *pPidlOut = _ILCreateDrive(szName); - return S_OK; + *pPidlOut = SUCCEEDED(hr) ? _ILCreateDrive(szDrive) : NULL; + return hr; } - return m_regFolder->SetNameOf(hwndOwner, pidl, lpName, dwFlags, pPidlOut); } +HRESULT CDrivesFolder::SetDriveLabel(HWND hwndOwner, PCWSTR DrivePath, PCWSTR Label) +{ + HRESULT hr = SetVolumeLabelW(DrivePath, *Label ? Label : NULL) ? S_OK : HResultFromWin32(GetLastError()); + if (SUCCEEDED(hr)) + SHChangeNotify(SHCNE_RENAMEFOLDER, SHCNF_PATHW, DrivePath, DrivePath); // DisplayName changed + else if (hwndOwner) + SHELL_ErrorBox(hwndOwner, hr); + return hr; +} + HRESULT WINAPI CDrivesFolder::GetDefaultSearchGUID(GUID * pguid) { FIXME("(%p)\n", this); diff --git a/dll/win32/shell32/folders/CDrivesFolder.h b/dll/win32/shell32/folders/CDrivesFolder.h index a4222b8836228..74cb2bef4555c 100644 --- a/dll/win32/shell32/folders/CDrivesFolder.h +++ b/dll/win32/shell32/folders/CDrivesFolder.h @@ -36,12 +36,15 @@ class CDrivesFolder : /* both paths are parsible from the desktop */ LPITEMIDLIST pidlRoot; /* absolute pidl */ CComPtr m_regFolder; + INT8 m_DriveDisplayMode; public: CDrivesFolder(); ~CDrivesFolder(); HRESULT WINAPI FinalConstruct(); + static HRESULT SetDriveLabel(HWND hwndOwner, PCWSTR DrivePath, PCWSTR Label); + // IShellFolder STDMETHOD(ParseDisplayName)(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName, DWORD *pchEaten, PIDLIST_RELATIVE *ppidl, DWORD *pdwAttributes) override; STDMETHOD(EnumObjects)(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList) override; diff --git a/dll/win32/shell32/folders/CFSFolder.cpp b/dll/win32/shell32/folders/CFSFolder.cpp index 9ae1f53da1ff9..1a9161c273d94 100644 --- a/dll/win32/shell32/folders/CFSFolder.cpp +++ b/dll/win32/shell32/folders/CFSFolder.cpp @@ -620,7 +620,7 @@ HRESULT SHELL32_GetFSItemAttributes(IShellFolder * psf, LPCITEMIDLIST pidl, LPDW { DWORD dwFileAttributes, dwShellAttributes; - if (!_ILIsFolder(pidl) && !_ILIsValue(pidl)) + if (!_ILIsFolderOrFile(pidl)) { ERR("Got wrong type of pidl!\n"); *pdwAttributes &= SFGAO_CANLINK; @@ -1007,9 +1007,9 @@ HRESULT WINAPI CFSFolder::BindToObject( /* Get the pidl data */ FileStruct* pData = &_ILGetDataPointer(pidl)->u.file; - FileStructW* pDataW = _ILGetFileStructW(pidl); - - if (!pDataW) + WCHAR szNameBuf[MAX_PATH]; + LPCWSTR pszName = GetItemFileName(pidl, szNameBuf, _countof(szNameBuf)); + if (!pszName) { ERR("CFSFolder::BindToObject: Invalid pidl!\n"); return E_INVALIDARG; @@ -1021,7 +1021,7 @@ HRESULT WINAPI CFSFolder::BindToObject( PERSIST_FOLDER_TARGET_INFO pfti = {0}; pfti.dwAttributes = -1; pfti.csidl = -1; - PathCombineW(pfti.szTargetParsingName, m_sPathTarget, pDataW->wszName); + PathCombineW(pfti.szTargetParsingName, m_sPathTarget, pszName); /* Get the CLSID to bind to */ CLSID clsidFolder; @@ -1088,6 +1088,20 @@ HRESULT WINAPI CFSFolder::BindToStorage( return E_NOTIMPL; } +HRESULT CFSFolder::CompareSortFoldersFirst(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2) +{ + BOOL bIsFolder1 = _ILIsFolder(pidl1), bIsFolder2 = _ILIsFolder(pidl2); + // When sorting between a File and a Folder, the Folder gets sorted first + if (bIsFolder1 != bIsFolder2) + { + // ...but only if neither of them were generated by SHSimpleIDListFromPath + // because in that case we cannot tell if it's a file or a folder. + if (pidl1 && IsRealItem(*pidl1) && pidl2 && IsRealItem(*pidl2)) + return MAKE_COMPARE_HRESULT(bIsFolder1 ? -1 : 1); + } + return MAKE_SCODE(SEVERITY_ERROR, FACILITY_SHELL, S_EQUAL); +} + /************************************************************************** * CFSFolder::CompareIDs */ @@ -1096,31 +1110,24 @@ HRESULT WINAPI CFSFolder::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2) { + WCHAR szNameBuf1[MAX_PATH], szNameBuf2[_countof(szNameBuf1)]; + LPCWSTR pszName1 = GetItemFileName(pidl1, szNameBuf1, _countof(szNameBuf1)); + LPCWSTR pszName2 = GetItemFileName(pidl2, szNameBuf2, _countof(szNameBuf2)); + if (!pszName1 || !pszName2 || LOWORD(lParam) >= GENERICSHELLVIEWCOLUMNS) + return E_INVALIDARG; + LPPIDLDATA pData1 = _ILGetDataPointer(pidl1); LPPIDLDATA pData2 = _ILGetDataPointer(pidl2); - FileStructW* pDataW1 = _ILGetFileStructW(pidl1); - FileStructW* pDataW2 = _ILGetFileStructW(pidl2); - BOOL bIsFolder1 = _ILIsFolder(pidl1); - BOOL bIsFolder2 = _ILIsFolder(pidl2); LPWSTR pExtension1, pExtension2; - if (!pDataW1 || !pDataW2 || LOWORD(lParam) >= GENERICSHELLVIEWCOLUMNS) - return E_INVALIDARG; - - /* When sorting between a File and a Folder, the Folder gets sorted first */ - if (bIsFolder1 != bIsFolder2) - { - // ...but only if neither of them were generated by SHSimpleIDListFromPath - // because in that case we cannot tell if it's a file or a folder. - if (IsRealItem(*pidl1) && IsRealItem(*pidl2)) - return MAKE_COMPARE_HRESULT(bIsFolder1 ? -1 : 1); - } - + HRESULT hr = CompareSortFoldersFirst(pidl1, pidl2); + if (SUCCEEDED(hr)) + return hr; int result = 0; switch (LOWORD(lParam)) { case SHFSF_COL_NAME: - result = _wcsicmp(pDataW1->wszName, pDataW2->wszName); + result = _wcsicmp(pszName1, pszName2); break; case SHFSF_COL_SIZE: if (pData1->u.file.dwFileSize > pData2->u.file.dwFileSize) @@ -1131,8 +1138,9 @@ HRESULT WINAPI CFSFolder::CompareIDs(LPARAM lParam, result = 0; break; case SHFSF_COL_TYPE: - pExtension1 = PathFindExtensionW(pDataW1->wszName); - pExtension2 = PathFindExtensionW(pDataW2->wszName); + // FIXME: Compare the type strings from SHGetFileInfo + pExtension1 = PathFindExtensionW(pszName1); + pExtension2 = PathFindExtensionW(pszName2); result = _wcsicmp(pExtension1, pExtension2); break; case SHFSF_COL_MDATE: @@ -1273,7 +1281,7 @@ HRESULT WINAPI CFSFolder::GetAttributesOf(UINT cidl, { LPCITEMIDLIST rpidl = ILFindLastID(m_pidlRoot); - if (_ILIsFolder(rpidl) || _ILIsValue(rpidl)) + if (_ILIsFolderOrFile(rpidl)) { SHELL32_GetFSItemAttributes(this, rpidl, rgfInOut); } @@ -1297,7 +1305,7 @@ HRESULT WINAPI CFSFolder::GetAttributesOf(UINT cidl, while (cidl > 0 && *apidl) { pdump(*apidl); - if(_ILIsFolder(*apidl) || _ILIsValue(*apidl)) + if (_ILIsFolderOrFile(*apidl)) SHELL32_GetFSItemAttributes(this, *apidl, rgfInOut); else ERR("Got an unknown type of pidl!!!\n"); @@ -1549,14 +1557,17 @@ HRESULT WINAPI CFSFolder::SetNameOf( DWORD dwFlags, PITEMID_CHILD *pPidlOut) { - WCHAR szSrc[MAX_PATH + 1], szDest[MAX_PATH + 1]; - BOOL bIsFolder = _ILIsFolder (ILFindLastID (pidl)); + WCHAR szSrc[MAX_PATH + 1], szDest[MAX_PATH + 1], szNameBuf[MAX_PATH]; + BOOL bIsFolder = ItemIsFolder(ILFindLastID(pidl)); TRACE ("(%p)->(%p,pidl=%p,%s,%u,%p)\n", this, hwndOwner, pidl, debugstr_w (lpName), dwFlags, pPidlOut); - FileStructW* pDataW = _ILGetFileStructW(pidl); - if (!pDataW) + if (pPidlOut) + *pPidlOut = NULL; + + LPCWSTR pszName = GetItemFileName(pidl, szNameBuf, _countof(szNameBuf)); + if (!pszName) { ERR("Got garbage pidl:\n"); pdump_always(pidl); @@ -1564,7 +1575,7 @@ HRESULT WINAPI CFSFolder::SetNameOf( } /* build source path */ - PathCombineW(szSrc, m_sPathTarget, pDataW->wszName); // FIXME: PIDLs without wide string + PathCombineW(szSrc, m_sPathTarget, pszName); /* build destination path */ if (dwFlags == SHGDN_NORMAL || dwFlags & SHGDN_INFOLDER) @@ -1587,16 +1598,11 @@ HRESULT WINAPI CFSFolder::SetNameOf( if (pPidlOut) hr = SHILClone(pidl, pPidlOut); } - else if (MoveFileW(szSrc, szDest)) - { - if (pPidlOut) - hr = ParseDisplayName(hwndOwner, NULL, PathFindFileNameW(szDest), NULL, pPidlOut, NULL); - - SHChangeNotify(bIsFolder ? SHCNE_RENAMEFOLDER : SHCNE_RENAMEITEM, SHCNF_PATHW, szSrc, szDest); - } else { - hr = HResultFromWin32(GetLastError()); + hr = SHELL_SingleFileOperation(hwndOwner, FO_RENAME, szSrc, szDest, FOF_SILENT | FOF_ALLOWUNDO, NULL); + if (SUCCEEDED(hr) && pPidlOut) + hr = ParseDisplayName(hwndOwner, NULL, PathFindFileNameW(szDest), NULL, pPidlOut, NULL); } return hr; } @@ -1662,6 +1668,7 @@ HRESULT WINAPI CFSFolder::GetDetailsOf(PCUITEMID_CHILD pidl, } else { + FILETIME ft; hr = S_OK; psd->str.uType = STRRET_WSTR; if (iColumn != SHFSF_COL_NAME) @@ -1683,7 +1690,11 @@ HRESULT WINAPI CFSFolder::GetDetailsOf(PCUITEMID_CHILD pidl, GetItemDescription(pidl, psd->str.pOleStr, MAX_PATH); break; case SHFSF_COL_MDATE: - _ILGetFileDate(pidl, psd->str.pOleStr, MAX_PATH); + if (!_ILGetFileDateTime(pidl, &ft) || FAILED(FormatDateTime(ft, psd->str.pOleStr, MAX_PATH))) + { + *psd->str.pOleStr = UNICODE_NULL; + hr = S_FALSE; + } break; case SHFSF_COL_FATTS: _ILGetFileAttributes(pidl, psd->str.pOleStr, MAX_PATH); @@ -1744,17 +1755,12 @@ HRESULT WINAPI CFSFolder::Initialize(PCIDLIST_ABSOLUTE pidl) m_sPathTarget = NULL; /* set my path */ + HRESULT hr = E_FAIL; if (SHGetPathFromIDListW (pidl, wszTemp)) - { - int len = wcslen(wszTemp); - m_sPathTarget = (WCHAR *)SHAlloc((len + 1) * sizeof(WCHAR)); - if (!m_sPathTarget) - return E_OUTOFMEMORY; - memcpy(m_sPathTarget, wszTemp, (len + 1) * sizeof(WCHAR)); - } + hr = SHStrDupW(wszTemp, &m_sPathTarget); TRACE ("--(%p)->(%s)\n", this, debugstr_w(m_sPathTarget)); - return S_OK; + return hr; } /************************************************************************** @@ -1806,44 +1812,28 @@ HRESULT WINAPI CFSFolder::InitializeEx(IBindCtx * pbc, LPCITEMIDLIST pidlRootx, * the target folder is spezified in csidl OR pidlTargetFolder OR * szTargetParsingName */ + HRESULT hr = E_FAIL; if (ppfti) { if (ppfti->csidl != -1) { - if (SHGetSpecialFolderPathW(0, wszTemp, ppfti->csidl, - ppfti->csidl & CSIDL_FLAG_CREATE)) { - int len = wcslen(wszTemp); - m_sPathTarget = (WCHAR *)SHAlloc((len + 1) * sizeof(WCHAR)); - if (!m_sPathTarget) - return E_OUTOFMEMORY; - memcpy(m_sPathTarget, wszTemp, (len + 1) * sizeof(WCHAR)); - } + BOOL create = ppfti->csidl & CSIDL_FLAG_CREATE; + if (SHGetSpecialFolderPathW(0, wszTemp, ppfti->csidl, create)) + hr = SHStrDupW(wszTemp, &m_sPathTarget); } else if (ppfti->szTargetParsingName[0]) { - int len = wcslen(ppfti->szTargetParsingName); - m_sPathTarget = (WCHAR *)SHAlloc((len + 1) * sizeof(WCHAR)); - if (!m_sPathTarget) - return E_OUTOFMEMORY; - memcpy(m_sPathTarget, ppfti->szTargetParsingName, - (len + 1) * sizeof(WCHAR)); + hr = SHStrDupW(ppfti->szTargetParsingName, &m_sPathTarget); } else if (ppfti->pidlTargetFolder) { if (SHGetPathFromIDListW(ppfti->pidlTargetFolder, wszTemp)) - { - int len = wcslen(wszTemp); - m_sPathTarget = (WCHAR *)SHAlloc((len + 1) * sizeof(WCHAR)); - if (!m_sPathTarget) - return E_OUTOFMEMORY; - memcpy(m_sPathTarget, wszTemp, (len + 1) * sizeof(WCHAR)); - } + hr = SHStrDupW(wszTemp, &m_sPathTarget); } } - TRACE("--(%p)->(target=%s)\n", this, debugstr_w(m_sPathTarget)); pdump(m_pidlRoot); - return (m_sPathTarget) ? S_OK : E_FAIL; + return hr; } HRESULT WINAPI CFSFolder::GetFolderTargetInfo(PERSIST_FOLDER_TARGET_INFO * ppfti) @@ -1923,17 +1913,16 @@ HRESULT CFSFolder::_GetIconHandler(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppvO HRESULT CFSFolder::_CreateShellExtInstance(const CLSID *pclsid, LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppvOut) { HRESULT hr; - WCHAR wszPath[MAX_PATH]; + WCHAR wszPath[MAX_PATH], szNameBuf[MAX_PATH]; - FileStructW* pDataW = _ILGetFileStructW(pidl); - if (!pDataW) + LPCWSTR pszName = GetItemFileName(pidl, szNameBuf, _countof(szNameBuf)); + if (!pszName) { ERR("Got garbage pidl\n"); pdump_always(pidl); return E_INVALIDARG; } - - PathCombineW(wszPath, m_sPathTarget, pDataW->wszName); + PathCombineW(wszPath, m_sPathTarget, pszName); CComPtr pp; hr = SHCoCreateInstance(NULL, pclsid, NULL, IID_PPV_ARG(IPersistFile, &pp)); @@ -2104,3 +2093,28 @@ HRESULT WINAPI CFSFolder::MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam) } return hr; } + +HRESULT CFSFolder::FormatDateTime(const FILETIME &ft, LPWSTR Buf, UINT cchBuf) +{ + FILETIME lft; + SYSTEMTIME time; + FileTimeToLocalFileTime(&ft, &lft); + FileTimeToSystemTime(&lft, &time); + UINT ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &time, NULL, Buf, cchBuf); + if (ret > 0 && ret < cchBuf) + { + /* Append space + time without seconds */ + Buf[ret-1] = ' '; + GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &time, NULL, &Buf[ret], cchBuf - ret); + } + return ret ? S_OK : E_FAIL; +} + +HRESULT CFSFolder::FormatSize(UINT64 size, LPWSTR Buf, UINT cchBuf) +{ + if (StrFormatKBSizeW(size, Buf, cchBuf)) + return S_OK; + if (cchBuf) + *Buf = UNICODE_NULL; + return E_FAIL; +} diff --git a/dll/win32/shell32/folders/CFSFolder.h b/dll/win32/shell32/folders/CFSFolder.h index e3db017578d6d..79f9c2c17e5a1 100644 --- a/dll/win32/shell32/folders/CFSFolder.h +++ b/dll/win32/shell32/folders/CFSFolder.h @@ -130,6 +130,13 @@ class CFSFolder : // Helper functions shared with CDesktopFolder static HRESULT GetFSColumnDetails(UINT iColumn, SHELLDETAILS &sd); static HRESULT GetDefaultFSColumnState(UINT iColumn, SHCOLSTATEF &csFlags); + static HRESULT FormatDateTime(const FILETIME &ft, LPWSTR Buf, UINT cchBuf); + static HRESULT FormatSize(UINT64 size, LPWSTR Buf, UINT cchBuf); + static HRESULT CompareSortFoldersFirst(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2); + static inline int CompareUiStrings(LPCWSTR a, LPCWSTR b) + { + return StrCmpLogicalW(a, b); + } }; #endif /* _CFSFOLDER_H_ */ diff --git a/dll/win32/shell32/folders/CRecycleBin.cpp b/dll/win32/shell32/folders/CRecycleBin.cpp index a9660e216a8c7..5f4e0e0bd2b83 100644 --- a/dll/win32/shell32/folders/CRecycleBin.cpp +++ b/dll/win32/shell32/folders/CRecycleBin.cpp @@ -58,88 +58,258 @@ static const columninfo RecycleBinColumns[] = #define COLUMNS_COUNT 6 -/* - * Recycle Bin folder - */ +// The ROS Recycle Bin PIDL format starts with a NT4/2000 Unicode FS PIDL followed by +// BBITEMDATA and BBITEMFOOTER. This makes it compatible with SHChangeNotify listeners. +#include "pshpack1.h" +#define BBITEMFILETYPE (PT_FS | PT_FS_UNICODE_FLAG | PT_FS_FILE_FLAG) +#define BBITEMFOLDERTYPE (PT_FS | PT_FS_UNICODE_FLAG | PT_FS_FOLDER_FLAG) +struct BBITEMDATA +{ + FILETIME DeletionTime; +#ifdef COLUMN_FATTS + WORD AttribsHi; // Nobody needs this yet +#endif + WORD RecycledPathOffset; + WCHAR OriginalLocation[ANYSIZE_ARRAY]; + // ... @RecycledPathOffset WCHAR RecycledPath[ANYSIZE_ARRAY]; +}; +struct BBITEMFOOTER +{ + enum { ENDSIG = MAKEWORD('K', 'I') }; // "Killed item". MUST have the low bit set so _ILGetFileStructW returns NULL. + WORD DataSize; + WORD EndSignature; +}; +#include "poppack.h" -BOOL WINAPI CBSearchRecycleBin(IN PVOID Context, IN HDELFILE hDeletedFile); +static inline BOOL IsFolder(LPCITEMIDLIST pidl) +{ + return _ILGetFSType(pidl) & PT_FS_FOLDER_FLAG; +} -static PIDLRecycleStruct * _ILGetRecycleStruct(LPCITEMIDLIST pidl); +static BBITEMDATA* ValidateItem(LPCITEMIDLIST pidl) +{ + const UINT minstringsize = sizeof(L"X") + sizeof(""); // PT_FS strings + const UINT minfs = sizeof(WORD) + FIELD_OFFSET(PIDLDATA, u.file.szNames) + minstringsize; + const UINT mindatasize = FIELD_OFFSET(BBITEMDATA, OriginalLocation) + (sizeof(L"C:\\X") * 2); + const UINT minsize = minfs + mindatasize + sizeof(BBITEMFOOTER); + const BYTE type = _ILGetType(pidl); + if ((type == BBITEMFILETYPE || type == BBITEMFOLDERTYPE) && pidl->mkid.cb >= minsize) + { + BBITEMFOOTER *pEnd = (BBITEMFOOTER*)((BYTE*)pidl + pidl->mkid.cb - sizeof(BBITEMFOOTER)); + if (pEnd->EndSignature == BBITEMFOOTER::ENDSIG && pEnd->DataSize >= mindatasize) + return (BBITEMDATA*)((BYTE*)pEnd - pEnd->DataSize); + } + return NULL; +} -typedef struct _SEARCH_CONTEXT +static LPITEMIDLIST CreateItem(LPCWSTR pszTrash, LPCWSTR pszOrig, const DELETED_FILE_INFO &Details) { - PIDLRecycleStruct *pFileDetails; - HDELFILE hDeletedFile; - BOOL bFound; -} SEARCH_CONTEXT, *PSEARCH_CONTEXT; + const BOOL folder = Details.Attributes & FILE_ATTRIBUTE_DIRECTORY; + LPCWSTR pszName = PathFindFileNameW(pszTrash); + SIZE_T ofsName = (SIZE_T)(pszName - pszTrash); + SIZE_T cchName = wcslen(pszName) + 1, cbName = cchName * sizeof(WCHAR); + SIZE_T cbFSNames = cbName + sizeof("") + 1; // Empty short name + 1 for WORD alignment + SIZE_T cbFS = sizeof(WORD) + FIELD_OFFSET(PIDLDATA, u.file.szNames) + cbFSNames; + SIZE_T cchTrash = ofsName + cchName, cbTrash = cchTrash * sizeof(WCHAR); + SIZE_T cchOrig = wcslen(pszOrig) + 1, cbOrig = cchOrig * sizeof(WCHAR); + SIZE_T cbData = FIELD_OFFSET(BBITEMDATA, OriginalLocation) + cbOrig + cbTrash; + SIZE_T cb = cbFS + cbData + sizeof(BBITEMFOOTER); + if (cb > 0xffff) + return NULL; + LPITEMIDLIST pidl = (LPITEMIDLIST)SHAlloc(cb + sizeof(WORD)); + if (!pidl) + return pidl; -HRESULT CRecyclerExtractIcon_CreateInstance( - LPCITEMIDLIST pidl, REFIID riid, LPVOID * ppvOut) + pidl->mkid.cb = cb; + pidl->mkid.abID[0] = folder ? BBITEMFOLDERTYPE : BBITEMFILETYPE; + ILGetNext(pidl)->mkid.cb = 0; // Terminator + FileStruct &fsitem = ((PIDLDATA*)pidl->mkid.abID)->u.file; + fsitem.dummy = 0; + C_ASSERT(sizeof(RECYCLEBINFILESIZETYPE) <= sizeof(fsitem.dwFileSize)); + fsitem.dwFileSize = Details.FileSize; + fsitem.uFileAttribs = LOWORD(Details.Attributes); + FileTimeToDosDateTime(&Details.LastModification, &fsitem.uFileDate, &fsitem.uFileTime); + CopyMemory(fsitem.szNames, pszName, cbName); + LPSTR pszShort = const_cast(&fsitem.szNames[cbName]); + pszShort[0] = '\0'; + pszShort[1] = '\0'; // Fill alignment padding (for ILIsEqual memcmp) + + BBITEMFOOTER *footer = (BBITEMFOOTER*)((BYTE*)pidl + cb - sizeof(BBITEMFOOTER)); + footer->DataSize = cbData; + footer->EndSignature = BBITEMFOOTER::ENDSIG; + + BBITEMDATA *data = (BBITEMDATA*)((BYTE*)footer - footer->DataSize); + data->DeletionTime = Details.DeletionTime; +#ifdef COLUMN_FATTS + data->AttribsHi = HIWORD(Details.Attributes); +#endif + data->RecycledPathOffset = FIELD_OFFSET(BBITEMDATA, OriginalLocation) + cbOrig; + CopyMemory(data->OriginalLocation, pszOrig, cbOrig); + CopyMemory((BYTE*)data + data->RecycledPathOffset, pszTrash, cbTrash); + + assert(!(((SIZE_T)&fsitem.szNames) & 1)); // WORD aligned please + C_ASSERT(!(FIELD_OFFSET(BBITEMDATA, OriginalLocation) & 1)); // WORD aligned please + assert(!(((SIZE_T)data) & 1)); // WORD aligned please + assert(_ILGetFSType(pidl)); + assert(_ILIsPidlSimple(pidl)); + assert(*(WORD*)((BYTE*)pidl + pidl->mkid.cb - sizeof(WORD)) & 1); // ENDSIG bit + assert(_ILGetFileStructW(pidl) == NULL); // Our custom footer is incompatible with WinXP pidl data + assert(ValidateItem(pidl) == data); + return pidl; +} + +static inline UINT GetItemFileSize(LPCITEMIDLIST pidl) { - PIDLRecycleStruct *pFileDetails = _ILGetRecycleStruct(pidl); - if (pFileDetails == NULL) - goto fallback; + return _ILGetFSType(pidl) ? ((PIDLDATA*)pidl->mkid.abID)->u.file.dwFileSize : 0; +} - // Try to obtain the file - SEARCH_CONTEXT Context; - Context.pFileDetails = pFileDetails; - Context.bFound = FALSE; +static inline LPCWSTR GetItemOriginalFullPath(const BBITEMDATA &Data) +{ + return Data.OriginalLocation; +} - EnumerateRecycleBinW(NULL, CBSearchRecycleBin, &Context); - if (Context.bFound) - { - // This should be executed any time, if not, there are some errors in the implementation - IRecycleBinFile* pRecycleFile = (IRecycleBinFile*)Context.hDeletedFile; +static HRESULT GetItemOriginalFolder(const BBITEMDATA &Data, LPWSTR &Out) +{ + HRESULT hr = SHStrDupW(GetItemOriginalFullPath(Data), &Out); + if (SUCCEEDED(hr)) + PathRemoveFileSpecW(Out); + return hr; +} - // Query the interface from the private interface - HRESULT hr = pRecycleFile->QueryInterface(riid, ppvOut); +static LPCWSTR GetItemOriginalFileName(const BBITEMDATA &Data) +{ + return PathFindFileNameW(GetItemOriginalFullPath(Data)); +} - // Close the file handle as we don't need it anymore - CloseRecycleBinHandle(Context.hDeletedFile); +static inline LPCWSTR GetItemRecycledFullPath(const BBITEMDATA &Data) +{ + return (LPCWSTR)((BYTE*)&Data + Data.RecycledPathOffset); +} - return hr; - } +#if 0 // Unused +static inline LPCWSTR GetItemRecycledFileName(LPCITEMIDLIST pidl, const BBITEMDATA &Data) +{ + C_ASSERT(BBITEMFILETYPE & PT_FS_UNICODE_FLAG); + return (LPCWSTR)((LPPIDLDATA)pidl->mkid.abID)->u.file.szNames; +} +#endif -fallback: - // In case the search fails we use a default icon - ERR("Recycler could not retrieve the icon, this shouldn't happen\n"); +static int GetItemDriveNumber(LPCITEMIDLIST pidl) +{ + if (BBITEMDATA *pData = ValidateItem(pidl)) + return PathGetDriveNumberW(GetItemRecycledFullPath(*pData)); + WCHAR buf[MAX_PATH]; + return _ILSimpleGetTextW(pidl, buf, _countof(buf)) ? PathGetDriveNumberW(buf) : -1; +} - CComPtr initIcon; - HRESULT hr = SHCreateDefaultExtractIcon(IID_PPV_ARG(IDefaultExtractIconInit, &initIcon)); - if (FAILED_UNEXPECTEDLY(hr)) - return hr; +static HRESULT GetItemTypeName(PCUITEMID_CHILD pidl, const BBITEMDATA &Data, SHFILEINFOW &shfi) +{ + LPCWSTR path = GetItemRecycledFullPath(Data); + UINT attribs = ((PIDLDATA*)pidl->mkid.abID)->u.file.uFileAttribs; + if (SHGetFileInfoW(path, attribs, &shfi, sizeof(shfi), SHGFI_TYPENAME | SHGFI_USEFILEATTRIBUTES)) + return S_OK; + shfi.szTypeName[0] = UNICODE_NULL; + return E_FAIL; +} - initIcon->SetNormalIcon(swShell32Name, 0); +/* + * Recycle Bin folder + */ - return initIcon->QueryInterface(riid, ppvOut); +static UINT GetDefaultRecycleDriveNumber() +{ + int drive = 0; + WCHAR buf[MAX_PATH]; + if (GetWindowsDirectoryW(buf, _countof(buf))) + drive = PathGetDriveNumberW(buf); + return max(0, drive); } -class CRecycleBinEnum : - public CEnumIDListBase +static inline LPCWSTR GetGlobalRecycleBinPath() { - private: - public: - CRecycleBinEnum(); - ~CRecycleBinEnum(); - HRESULT WINAPI Initialize(DWORD dwFlags); - static BOOL WINAPI CBEnumRecycleBin(IN PVOID Context, IN HDELFILE hDeletedFile); - BOOL WINAPI CBEnumRecycleBin(IN HDELFILE hDeletedFile); + return NULL; +} - BEGIN_COM_MAP(CRecycleBinEnum) - COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList) - END_COM_MAP() -}; +static BOOL IsRecycleBinEmpty(IShellFolder *pSF) +{ + CComPtr spEnumFiles; + HRESULT hr = pSF->EnumObjects(NULL, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &spEnumFiles); + CComHeapPtr spPidl; + ULONG itemcount; + return FAILED(hr) || spEnumFiles->Next(1, &spPidl, &itemcount) != S_OK; +} + +static void CRecycleBin_ChangeNotifyBBItem(_In_ LONG Event, _In_opt_ LPCITEMIDLIST BBItem) +{ + LPITEMIDLIST pidlFolder = SHCloneSpecialIDList(NULL, CSIDL_BITBUCKET, FALSE); + if (!pidlFolder) + return; + if (BBItem) + { + assert(ValidateItem(BBItem)); + if (LPITEMIDLIST pidlFull = ILCombine(pidlFolder, BBItem)) + { + // Send notification for [Desktop][RecycleBin][BBItem] + // FIXME: Windows monitors each RecycleBin FS folder on every drive + // instead of manually sending these? + SHChangeNotify(Event, SHCNF_IDLIST, pidlFull, NULL); + ILFree(pidlFull); + } + } + else + { + SHChangeNotify(Event, SHCNF_IDLIST, pidlFolder, NULL); + } + ILFree(pidlFolder); +} + +EXTERN_C void CRecycleBin_NotifyRecycled(LPCWSTR OrigPath, const WIN32_FIND_DATAW *pFind, + const RECYCLEBINFILEIDENTITY *pFI) +{ + DELETED_FILE_INFO info; + info.LastModification = pFind->ftLastWriteTime; + info.DeletionTime = pFI->DeletionTime; + info.FileSize = pFind->nFileSizeLow; + info.Attributes = pFind->dwFileAttributes; + if (LPITEMIDLIST pidl = CreateItem(pFI->RecycledFullPath, OrigPath, info)) + { + CRecycleBin_ChangeNotifyBBItem(IsFolder(pidl) ? SHCNE_MKDIR : SHCNE_CREATE, pidl); + ILFree(pidl); + } +} + +static void CRecycleBin_NotifyRemovedFromRecycleBin(LPCITEMIDLIST BBItem) +{ + CRecycleBin_ChangeNotifyBBItem(IsFolder(BBItem) ? SHCNE_RMDIR : SHCNE_DELETE, BBItem); +} + +static HRESULT CRecyclerExtractIcon_CreateInstance( + IShellFolder &FSFolder, LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppvOut) +{ + HRESULT hr = FSFolder.GetUIObjectOf(NULL, 1, &pidl, riid, NULL, ppvOut); + if (SUCCEEDED(hr)) + return hr; + + // In case the search fails we use a default icon + ERR("Recycler could not retrieve the icon, this shouldn't happen\n"); + + if (IsFolder(pidl)) + return SHELL_CreateFallbackExtractIconForFolder(riid, ppvOut); + else + return SHELL_CreateFallbackExtractIconForNoAssocFile(riid, ppvOut); +} class CRecycleBinItemContextMenu : public CComObjectRootEx, public IContextMenu2 { private: - LPITEMIDLIST apidl; + PITEMID_CHILD* m_apidl; + UINT m_cidl; public: CRecycleBinItemContextMenu(); - ~CRecycleBinItemContextMenu(); - HRESULT WINAPI Initialize(LPCITEMIDLIST pidl); + virtual ~CRecycleBinItemContextMenu(); + HRESULT WINAPI Initialize(UINT cidl, PCUITEMID_CHILD_ARRAY apidl); // IContextMenu STDMETHOD(QueryContextMenu)(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags) override; @@ -155,63 +325,23 @@ class CRecycleBinItemContextMenu : END_COM_MAP() }; -BOOL WINAPI CBSearchRecycleBin(IN PVOID Context, IN HDELFILE hDeletedFile) -{ - PSEARCH_CONTEXT pContext = (PSEARCH_CONTEXT)Context; - - PDELETED_FILE_DETAILS_W pFileDetails; - DWORD dwSize; - BOOL ret; - - if (!GetDeletedFileDetailsW(hDeletedFile, - 0, - NULL, - &dwSize) && - GetLastError() != ERROR_INSUFFICIENT_BUFFER) - { - ERR("GetDeletedFileDetailsW failed\n"); - return FALSE; - } - - pFileDetails = (DELETED_FILE_DETAILS_W *)SHAlloc(dwSize); - if (!pFileDetails) - { - ERR("No memory\n"); - return FALSE; - } - - if (!GetDeletedFileDetailsW(hDeletedFile, - dwSize, - pFileDetails, - NULL)) - { - ERR("GetDeletedFileDetailsW failed\n"); - SHFree(pFileDetails); - return FALSE; - } - - ret = memcmp(pFileDetails, pContext->pFileDetails, dwSize); - if (!ret) - { - pContext->hDeletedFile = hDeletedFile; - pContext->bFound = TRUE; - } - else - CloseRecycleBinHandle(hDeletedFile); - - SHFree(pFileDetails); - return ret; -} - -static PIDLRecycleStruct * _ILGetRecycleStruct(LPCITEMIDLIST pidl) +class CRecycleBinEnum : + public CEnumIDListBase { - LPPIDLDATA pdata = _ILGetDataPointer(pidl); - - if (pdata && pdata->type == 0x00) - return (PIDLRecycleStruct*) & (pdata->u.crecycle); + public: + CRecycleBinEnum(); + ~CRecycleBinEnum(); + HRESULT WINAPI Initialize(DWORD dwFlags); + BOOL CBEnumRecycleBin(IN HDELFILE hDeletedFile); + static BOOL CALLBACK CBEnumRecycleBin(IN PVOID Context, IN HDELFILE hDeletedFile) + { + return static_cast(Context)->CBEnumRecycleBin(hDeletedFile); + } - return NULL; -} + BEGIN_COM_MAP(CRecycleBinEnum) + COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList) + END_COM_MAP() +}; CRecycleBinEnum::CRecycleBinEnum() { @@ -223,14 +353,7 @@ CRecycleBinEnum::~CRecycleBinEnum() HRESULT WINAPI CRecycleBinEnum::Initialize(DWORD dwFlags) { - WCHAR szDrive[8]; - if (!GetEnvironmentVariableW(L"SystemDrive", szDrive, _countof(szDrive) - 1)) - { - ERR("GetEnvironmentVariableW failed\n"); - return E_FAIL; - } - PathAddBackslashW(szDrive); - + LPCWSTR szDrive = GetGlobalRecycleBinPath(); if (dwFlags & SHCONTF_NONFOLDERS) { TRACE("Starting Enumeration\n"); @@ -248,83 +371,25 @@ HRESULT WINAPI CRecycleBinEnum::Initialize(DWORD dwFlags) return S_OK; } -static LPITEMIDLIST _ILCreateRecycleItem(PDELETED_FILE_DETAILS_W pFileDetails) -{ - PIDLDATA tmp; - LPITEMIDLIST pidl; - PIDLRecycleStruct * p; - int size0 = (char*)&tmp.u.crecycle.szName - (char*)&tmp.u.crecycle; - int size = size0; - - tmp.type = 0x00; - size += (wcslen(pFileDetails->FileName) + 1) * sizeof(WCHAR); - - pidl = (LPITEMIDLIST)SHAlloc(size + 4); - if (!pidl) - return pidl; - - pidl->mkid.cb = size + 2; - memcpy(pidl->mkid.abID, &tmp, 2 + size0); - - p = &((PIDLDATA*)pidl->mkid.abID)->u.crecycle; - RtlCopyMemory(p, pFileDetails, sizeof(DELETED_FILE_DETAILS_W)); - wcscpy(p->szName, pFileDetails->FileName); - *(WORD*)((char*)pidl + (size + 2)) = 0; - return pidl; -} - -BOOL WINAPI CRecycleBinEnum::CBEnumRecycleBin(IN PVOID Context, IN HDELFILE hDeletedFile) -{ - return static_cast(Context)->CBEnumRecycleBin(hDeletedFile); -} - -BOOL WINAPI CRecycleBinEnum::CBEnumRecycleBin(IN HDELFILE hDeletedFile) +BOOL CRecycleBinEnum::CBEnumRecycleBin(IN HDELFILE hDeletedFile) { - PDELETED_FILE_DETAILS_W pFileDetails; - DWORD dwSize; LPITEMIDLIST pidl = NULL; - BOOL ret; - - if (!GetDeletedFileDetailsW(hDeletedFile, - 0, - NULL, - &dwSize) && - GetLastError() != ERROR_INSUFFICIENT_BUFFER) + DELETED_FILE_INFO info; + IRecycleBinFile *pRBF = IRecycleBinFileFromHDELFILE(hDeletedFile); + BOOL ret = SUCCEEDED(pRBF->GetInfo(&info)); + if (ret) { - ERR("GetDeletedFileDetailsW failed\n"); - return FALSE; + pidl = CreateItem(info.RecycledFullPath.String, info.OriginalFullPath.String, info); + ret = pidl != NULL; + FreeRecycleBinString(&info.OriginalFullPath); + FreeRecycleBinString(&info.RecycledFullPath); } - - pFileDetails = (DELETED_FILE_DETAILS_W *)SHAlloc(dwSize); - if (!pFileDetails) + if (pidl) { - ERR("No memory\n"); - return FALSE; + ret = AddToEnumList(pidl); + if (!ret) + ILFree(pidl); } - - if (!GetDeletedFileDetailsW(hDeletedFile, - dwSize, - pFileDetails, - NULL)) - { - ERR("GetDeletedFileDetailsW failed\n"); - SHFree(pFileDetails); - return FALSE; - } - - pidl = _ILCreateRecycleItem(pFileDetails); - if (!pidl) - { - SHFree(pFileDetails); - return FALSE; - } - - ret = AddToEnumList(pidl); - - if (!ret) - SHFree(pidl); - SHFree(pFileDetails); - TRACE("Returning %d\n", ret); CloseRecycleBinHandle(hDeletedFile); return ret; } @@ -335,115 +400,219 @@ BOOL WINAPI CRecycleBinEnum::CBEnumRecycleBin(IN HDELFILE hDeletedFile) CRecycleBinItemContextMenu::CRecycleBinItemContextMenu() { - apidl = NULL; + m_apidl = NULL; + m_cidl = 0; } CRecycleBinItemContextMenu::~CRecycleBinItemContextMenu() { - ILFree(apidl); + _ILFreeaPidl(m_apidl, m_cidl); } -HRESULT WINAPI CRecycleBinItemContextMenu::Initialize(LPCITEMIDLIST pidl) +HRESULT WINAPI CRecycleBinItemContextMenu::Initialize(UINT cidl, PCUITEMID_CHILD_ARRAY apidl) { - apidl = ILClone(pidl); - if (apidl == NULL) + m_apidl = _ILCopyaPidl(apidl, cidl); + if (m_apidl == NULL) return E_OUTOFMEMORY; + m_cidl = cidl; return S_OK; } +enum { IDC_BB_RESTORE = 1, IDC_BB_CUT, IDC_BB_DELETE, IDC_BB_PROPERTIES }; +static const CMVERBMAP g_BBItemVerbMap[] = +{ + { "undelete", IDC_BB_RESTORE }, + { "cut", IDC_BB_CUT }, + { "delete", IDC_BB_DELETE }, + { "properties", IDC_BB_PROPERTIES }, + { NULL } +}; + HRESULT WINAPI CRecycleBinItemContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags) { - WCHAR szBuffer[30] = {0}; - ULONG Count = 1; + UINT idHigh = 0, id; TRACE("(%p)->(hmenu=%p indexmenu=%x cmdfirst=%x cmdlast=%x flags=%x )\n", this, hMenu, indexMenu, idCmdFirst, idCmdLast, uFlags); - if (LoadStringW(shell32_hInstance, IDS_RESTORE, szBuffer, _countof(szBuffer))) + id = idCmdFirst + IDC_BB_RESTORE; + if (_InsertMenuItemW(hMenu, indexMenu, TRUE, id, MFT_STRING, MAKEINTRESOURCEW(IDS_RESTORE), 0)) { - szBuffer[_countof(szBuffer)-1] = L'\0'; - _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + Count, MFT_STRING, szBuffer, MFS_ENABLED); - Count++; + idHigh = max(idHigh, id); + indexMenu++; } - - if (LoadStringW(shell32_hInstance, IDS_CUT, szBuffer, _countof(szBuffer))) + id = idCmdFirst + IDC_BB_CUT; + if (_InsertMenuItemW(hMenu, indexMenu, TRUE, id, MFT_STRING, MAKEINTRESOURCEW(IDS_CUT), MFS_DISABLED)) { - _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + Count++, MFT_SEPARATOR, NULL, MFS_ENABLED); - szBuffer[_countof(szBuffer)-1] = L'\0'; - _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + Count++, MFT_STRING, szBuffer, MFS_ENABLED); + idHigh = max(idHigh, id); + if (_InsertMenuItemW(hMenu, indexMenu++, TRUE, -1, MFT_SEPARATOR, NULL, 0)) + indexMenu++; } - - if (LoadStringW(shell32_hInstance, IDS_DELETE, szBuffer, _countof(szBuffer))) + id = idCmdFirst + IDC_BB_DELETE; + if (_InsertMenuItemW(hMenu, indexMenu, TRUE, id, MFT_STRING, MAKEINTRESOURCEW(IDS_DELETE), 0)) { - szBuffer[_countof(szBuffer)-1] = L'\0'; - _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + Count++, MFT_SEPARATOR, NULL, MFS_ENABLED); - _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + Count++, MFT_STRING, szBuffer, MFS_ENABLED); + idHigh = max(idHigh, id); + if (_InsertMenuItemW(hMenu, indexMenu++, TRUE, -1, MFT_SEPARATOR, NULL, 0)) + indexMenu++; } - - if (LoadStringW(shell32_hInstance, IDS_PROPERTIES, szBuffer, _countof(szBuffer))) + id = idCmdFirst + IDC_BB_PROPERTIES; + if (_InsertMenuItemW(hMenu, indexMenu, TRUE, id, MFT_STRING, MAKEINTRESOURCEW(IDS_PROPERTIES), 0)) { - szBuffer[_countof(szBuffer)-1] = L'\0'; - _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + Count++, MFT_SEPARATOR, NULL, MFS_ENABLED); - _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + Count, MFT_STRING, szBuffer, MFS_DEFAULT); + idHigh = max(idHigh, id); + if (_InsertMenuItemW(hMenu, indexMenu++, TRUE, -1, MFT_SEPARATOR, NULL, 0)) + indexMenu++; } + return idHigh ? MAKE_HRESULT(SEVERITY_SUCCESS, 0, idHigh - idCmdFirst + 1) : S_OK; +} - return MAKE_HRESULT(SEVERITY_SUCCESS, 0, Count); +static BOOL ConfirmDelete(LPCMINVOKECOMMANDINFO lpcmi, UINT cidl, LPCITEMIDLIST pidl) +{ + BBITEMDATA *pData; + if (lpcmi->fMask & CMIC_MASK_FLAG_NO_UI) + { + return TRUE; + } + else if (cidl == 1 && (pData = ValidateItem(pidl)) != NULL) + { + const UINT ask = IsFolder(pidl) ? ASK_DELETE_FOLDER : ASK_DELETE_FILE; + return SHELL_ConfirmYesNoW(lpcmi->hwnd, ask, GetItemOriginalFileName(*pData)); + } + WCHAR buf[42]; + wsprintfW(buf, L"%d", cidl); + return SHELL_ConfirmYesNoW(lpcmi->hwnd, ASK_DELETE_MULTIPLE_ITEM, buf); } -HRESULT WINAPI CRecycleBinItemContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi) +static LPWSTR CreateFileOpStrings(UINT cidl, PCUITEMID_CHILD_ARRAY apidl, BOOL RecycledPath) { - SEARCH_CONTEXT Context; - WCHAR szDrive[8]; + PWSTR mem = NULL, newmem; + for (SIZE_T i = 0, cb = 0, cb2, cbPath; i < cidl; ++i, cb = cb2) + { + BBITEMDATA *pData = ValidateItem(apidl[i]); + if (!pData) + { +fail: + LocalFree(mem); + return NULL; + } + LPCWSTR path = RecycledPath ? GetItemRecycledFullPath(*pData) : GetItemOriginalFullPath(*pData); + cbPath = (lstrlenW(path) + 1) * sizeof(WCHAR); + cb2 = cb + cbPath; + SIZE_T cbTot = cb2 + sizeof(WCHAR); // \0\0 termination + newmem = (PWSTR)(i ? LocalReAlloc(mem, cbTot, LMEM_MOVEABLE) : LocalAlloc(LPTR, cbTot)); + if (!newmem) + goto fail; + mem = newmem; + CopyMemory((char*)mem + cb, path, cbPath); + *(PWSTR)((char*)mem + cb + cbPath) = UNICODE_NULL; + } + return mem; +} - TRACE("(%p)->(invcom=%p verb=%p wnd=%p)\n", this, lpcmi, lpcmi->lpVerb, lpcmi->hwnd); +typedef struct _FILEOPDATA +{ + PCUITEMID_CHILD_ARRAY apidl; + UINT cidl; +} FILEOPDATA; - if (lpcmi->lpVerb == MAKEINTRESOURCEA(1) || lpcmi->lpVerb == MAKEINTRESOURCEA(5)) +static HRESULT CALLBACK FileOpCallback(FILEOPCALLBACKEVENT Event, LPCWSTR Src, LPCWSTR Dst, UINT Attrib, HRESULT hrOp, void *CallerData) +{ + FILEOPDATA &data = *(FILEOPDATA*)CallerData; + if ((Event == FOCE_POSTDELETEITEM || Event == FOCE_POSTMOVEITEM) && SUCCEEDED(hrOp)) { - Context.pFileDetails = _ILGetRecycleStruct(apidl); - Context.bFound = FALSE; - - if (!GetEnvironmentVariableW(L"SystemDrive", szDrive, _countof(szDrive) - 1)) + for (UINT i = 0; i < data.cidl; ++i) { - ERR("GetEnvironmentVariableW failed\n"); - return E_FAIL; + BBITEMDATA *pItem = ValidateItem(data.apidl[i]); + if (pItem && !_wcsicmp(Src, GetItemRecycledFullPath(*pItem))) + { + RECYCLEBINFILEIDENTITY identity = { pItem->DeletionTime, GetItemRecycledFullPath(*pItem) }; + RemoveFromRecycleBinDatabase(&identity); + CRecycleBin_NotifyRemovedFromRecycleBin(data.apidl[i]); + break; + } } - PathAddBackslashW(szDrive); + } + else if (Event == FOCE_FINISHOPERATIONS) + { + CComHeapPtr pidlBB(SHCloneSpecialIDList(NULL, CSIDL_BITBUCKET, FALSE)); + CComPtr pSF; + if (pidlBB && SUCCEEDED(SHBindToObject(NULL, pidlBB, IID_PPV_ARG(IShellFolder, &pSF)))) + { + if (IsRecycleBinEmpty(pSF)) + SHUpdateRecycleBinIcon(); + } + } + return S_OK; +} - EnumerateRecycleBinW(szDrive, CBSearchRecycleBin, (PVOID)&Context); - if (!Context.bFound) - return E_FAIL; +HRESULT WINAPI CRecycleBinItemContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi) +{ + TRACE("(%p)->(invcom=%p verb=%p wnd=%p)\n", this, lpcmi, lpcmi->lpVerb, lpcmi->hwnd); - BOOL ret = TRUE; + int CmdId = SHELL_MapContextMenuVerbToCmdId(lpcmi, g_BBItemVerbMap); - /* restore file */ - if (lpcmi->lpVerb == MAKEINTRESOURCEA(1)) - ret = RestoreFile(Context.hDeletedFile); - /* delete file */ - else - DeleteFileHandleToRecycleBin(Context.hDeletedFile); + // Handle DefView accelerators + if ((SIZE_T)lpcmi->lpVerb == FCIDM_SHVIEW_CUT) + CmdId = IDC_BB_CUT; + if ((SIZE_T)lpcmi->lpVerb == FCIDM_SHVIEW_DELETE) + CmdId = IDC_BB_DELETE; + if ((SIZE_T)lpcmi->lpVerb == FCIDM_SHVIEW_PROPERTIES) + CmdId = IDC_BB_PROPERTIES; - CloseRecycleBinHandle(Context.hDeletedFile); + if (CmdId == IDC_BB_RESTORE || CmdId == IDC_BB_DELETE) + { + HRESULT hr = S_OK; + if (CmdId == IDC_BB_DELETE && !ConfirmDelete(lpcmi, m_cidl, m_apidl[0])) + return S_OK; - return (ret ? S_OK : E_FAIL); + LPWSTR pszzDst = NULL; + LPWSTR pszzSrc = CreateFileOpStrings(m_cidl, m_apidl, TRUE); + if (!pszzSrc) + return E_OUTOFMEMORY; + SHFILEOPSTRUCTW shfos = { lpcmi->hwnd, FO_DELETE, pszzSrc, NULL, FOF_NOCONFIRMMKDIR }; + if (CmdId == IDC_BB_RESTORE) + { + pszzDst = CreateFileOpStrings(m_cidl, m_apidl, FALSE); + if (!pszzDst) + hr = E_OUTOFMEMORY; + shfos.wFunc = FO_MOVE; + shfos.pTo = pszzDst; + shfos.fFlags |= FOF_MULTIDESTFILES; + } + else // IDC_BB_DELETE + { + shfos.fFlags |= FOF_NOCONFIRMATION; + } + if (SUCCEEDED(hr)) + { + if (lpcmi->fMask & CMIC_MASK_FLAG_NO_UI) + shfos.fFlags |= FOF_SILENT | FOF_NOERRORUI | FOF_NOCONFIRMATION; + FILEOPDATA data = { m_apidl, m_cidl }; + int res = SHELL32_FileOperation(&shfos, FileOpCallback, &data); + if (res && res != DE_OPCANCELLED && res != ERROR_CANCELLED) + hr = SHELL_ErrorBox(*lpcmi, E_FAIL); + } + LocalFree(pszzDst); + LocalFree(pszzSrc); + return hr; } - else if (lpcmi->lpVerb == MAKEINTRESOURCEA(3)) + else if (CmdId == IDC_BB_CUT) { FIXME("implement cut\n"); + SHELL_ErrorBox(*lpcmi, ERROR_NOT_SUPPORTED); return E_NOTIMPL; } - else if (lpcmi->lpVerb == MAKEINTRESOURCEA(7)) + else if (CmdId == IDC_BB_PROPERTIES) { FIXME("implement properties\n"); + SHELL_ErrorBox(*lpcmi, ERROR_NOT_SUPPORTED); return E_NOTIMPL; } - - return S_OK; + return E_UNEXPECTED; } HRESULT WINAPI CRecycleBinItemContextMenu::GetCommandString(UINT_PTR idCommand, UINT uFlags, UINT *lpReserved, LPSTR lpszName, UINT uMaxNameLen) { TRACE("(%p)->(idcom=%lx flags=%x %p name=%p len=%x)\n", this, idCommand, uFlags, lpReserved, lpszName, uMaxNameLen); - - return E_FAIL; + return SHELL_GetCommandStringImpl(idCommand, uFlags, lpszName, uMaxNameLen, g_BBItemVerbMap); } HRESULT WINAPI CRecycleBinItemContextMenu::HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam) @@ -456,11 +625,47 @@ HRESULT WINAPI CRecycleBinItemContextMenu::HandleMenuMsg(UINT uMsg, WPARAM wPara CRecycleBin::CRecycleBin() { pidl = NULL; + ZeroMemory(m_pFSFolders, sizeof(m_pFSFolders)); } CRecycleBin::~CRecycleBin() { SHFree(pidl); + for (SIZE_T i = 0; i < _countof(m_pFSFolders); ++i) + { + if (m_pFSFolders[i]) + m_pFSFolders[i]->Release(); + } +} + +IShellFolder* CRecycleBin::GetFSFolderForItem(LPCITEMIDLIST pidl) +{ + int drive = GetItemDriveNumber(pidl); + if (drive < 0) + drive = GetDefaultRecycleDriveNumber(); + if ((UINT)drive >= _countof(m_pFSFolders) && FAILED_UNEXPECTEDLY(E_FAIL)) + return NULL; + + if (!m_pFSFolders[drive]) + { + HRESULT hr; + PERSIST_FOLDER_TARGET_INFO pfti = {}; + if (FAILED_UNEXPECTEDLY(hr = GetRecycleBinPathFromDriveNumber(drive, pfti.szTargetParsingName))) + return NULL; + pfti.dwAttributes = FILE_ATTRIBUTE_DIRECTORY; + pfti.csidl = -1; + CComHeapPtr pidlRoot; + pidlRoot.Attach(SHELL32_CreateSimpleIDListFromPath(pfti.szTargetParsingName, pfti.dwAttributes)); + if (!pidlRoot && FAILED_UNEXPECTEDLY(E_FAIL)) + return NULL; + IShellFolder *psf; + hr = SHELL32_CoCreateInitSF(pidlRoot, &pfti, NULL, &CLSID_ShellFSFolder, IID_PPV_ARG(IShellFolder, &psf)); + if (FAILED(hr)) + return NULL; + m_pFSFolders[drive] = psf; // Reference count is 1 (for the m_pFSFolders cache) + } + m_pFSFolders[drive]->AddRef(); // AddRef for the caller + return m_pFSFolders[drive]; } /************************************************************************* @@ -472,7 +677,7 @@ HRESULT WINAPI CRecycleBin::GetClassID(CLSID *pClassID) TRACE("(%p, %p)\n", this, pClassID); if (pClassID == NULL) return E_INVALIDARG; - memcpy(pClassID, &CLSID_RecycleBin, sizeof(CLSID)); + *pClassID = GetClassID(); return S_OK; } @@ -490,8 +695,7 @@ HRESULT WINAPI CRecycleBin::Initialize(PCIDLIST_ABSOLUTE pidl) HRESULT WINAPI CRecycleBin::GetCurFolder(PIDLIST_ABSOLUTE *ppidl) { TRACE("\n"); - *ppidl = ILClone(pidl); - return S_OK; + return SHILClone((LPCITEMIDLIST)pidl, ppidl); } /************************************************************************* @@ -503,14 +707,7 @@ HRESULT WINAPI CRecycleBin::ParseDisplayName(HWND hwnd, LPBC pbc, ULONG *pdwAttributes) { FIXME("stub\n"); - return E_NOTIMPL; -} - - -PDELETED_FILE_DETAILS_W -UnpackDetailsFromPidl(LPCITEMIDLIST pidl) -{ - return (PDELETED_FILE_DETAILS_W)&pidl->mkid.abID; + return E_NOTIMPL; // FIXME: Parse "D.ext" } HRESULT WINAPI CRecycleBin::EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList) @@ -530,40 +727,82 @@ HRESULT WINAPI CRecycleBin::BindToStorage(PCUIDLIST_RELATIVE pidl, LPBC pbc, REF return E_NOTIMPL; } -HRESULT WINAPI CRecycleBin::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2) +static HRESULT CompareCanonical(const BBITEMDATA &Data1, const BBITEMDATA &Data2) { - PIDLRecycleStruct* pData1 = _ILGetRecycleStruct(pidl1); - PIDLRecycleStruct* pData2 = _ILGetRecycleStruct(pidl2); - LPWSTR pName1, pName2; + // This assumes two files with the same original path cannot be deleted at + // the same time (within the FAT/NTFS FILETIME resolution). + int result = CompareFileTime(&Data1.DeletionTime, &Data2.DeletionTime); + if (result == 0) + result = _wcsicmp(GetItemOriginalFullPath(Data1), GetItemOriginalFullPath(Data2)); + return MAKE_COMPARE_HRESULT(result); +} - if(!pData1 || !pData2 || LOWORD(lParam) >= COLUMNS_COUNT) +HRESULT WINAPI CRecycleBin::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2) +{ + UINT column = UINT(lParam & SHCIDS_COLUMNMASK); + if (column >= COLUMNS_COUNT || !_ILGetFSType(pidl1) || !_ILGetFSType(pidl2)) + return E_INVALIDARG; + BBITEMDATA *pData1 = ValidateItem(pidl1), *pData2 = ValidateItem(pidl2); + if ((!pData1 || !pData2) && column != COLUMN_NAME) return E_INVALIDARG; - SHORT result; - LONGLONG diff; - switch (LOWORD(lParam)) + LPCWSTR pName1, pName2; + FILETIME ft1, ft2; + SHFILEINFOW shfi1, shfi2; + int result; + HRESULT hr = CFSFolder::CompareSortFoldersFirst(pidl1, pidl2); + if (SUCCEEDED(hr)) + return hr; + switch (column) { - case 0: /* Name */ - pName1 = PathFindFileNameW(pData1->szName); - pName2 = PathFindFileNameW(pData2->szName); - result = _wcsicmp(pName1, pName2); - break; - case 1: /* Orig. Location */ - result = _wcsicmp(pData1->szName, pData2->szName); + case COLUMN_NAME: + if (pData1 && pData2) + { + if (lParam & SHCIDS_CANONICALONLY) + return CompareCanonical(*pData1, *pData2); + pName1 = GetItemOriginalFileName(*pData1); + pName2 = GetItemOriginalFileName(*pData2); + result = CFSFolder::CompareUiStrings(pName1, pName2); + } + else + { + // We support comparing names even for non-Recycle items because + // SHChangeNotify can broadcast regular FS items. + if (IShellFolder *pSF = GetFSFolderForItem(pidl1)) + { + hr = pSF->CompareIDs(lParam, pidl1, pidl2); + pSF->Release(); + return hr; + } + return E_INVALIDARG; + } break; - case 2: /* Date Deleted */ + case COLUMN_DELFROM: + if (SUCCEEDED(hr = GetItemOriginalFolder(*pData1, const_cast(pName1)))) + { + if (SUCCEEDED(hr = GetItemOriginalFolder(*pData2, const_cast(pName2)))) + { + result = CFSFolder::CompareUiStrings(pName1, pName2); + SHFree(const_cast(pName2)); + } + SHFree(const_cast(pName1)); + } + return SUCCEEDED(hr) ? MAKE_COMPARE_HRESULT(result) : hr; + case COLUMN_DATEDEL: result = CompareFileTime(&pData1->DeletionTime, &pData2->DeletionTime); break; - case 3: /* Size */ - diff = pData1->FileSize.QuadPart - pData2->FileSize.QuadPart; - return MAKE_COMPARE_HRESULT(diff); - case 4: /* Type */ - pName1 = PathFindExtensionW(pData1->szName); - pName2 = PathFindExtensionW(pData2->szName); - result = _wcsicmp(pName1, pName2); + case COLUMN_SIZE: + result = GetItemFileSize(pidl1) - GetItemFileSize(pidl2); + break; + case COLUMN_TYPE: + GetItemTypeName(pidl1, *pData1, shfi1); + GetItemTypeName(pidl2, *pData2, shfi2); + result = CFSFolder::CompareUiStrings(shfi1.szTypeName, shfi2.szTypeName); break; - case 5: /* Modified */ - result = CompareFileTime(&pData1->LastModification, &pData2->LastModification); + case COLUMN_MTIME: + _ILGetFileDateTime(pidl1, &ft1); + _ILGetFileDateTime(pidl2, &ft2); + result = CompareFileTime(&ft1, &ft2); break; } return MAKE_COMPARE_HRESULT(result); @@ -578,7 +817,6 @@ HRESULT WINAPI CRecycleBin::CreateViewObject(HWND hwndOwner, REFIID riid, void * if (!ppv) return hr; - *ppv = NULL; if (IsEqualIID (riid, IID_IDropTarget)) @@ -587,11 +825,12 @@ HRESULT WINAPI CRecycleBin::CreateViewObject(HWND hwndOwner, REFIID riid, void * } else if (IsEqualIID (riid, IID_IContextMenu) || IsEqualIID (riid, IID_IContextMenu2)) { + m_IsBackgroundMenu = true; hr = this->QueryInterface(riid, ppv); } else if (IsEqualIID (riid, IID_IShellView)) { - SFV_CREATE sfvparams = {sizeof(SFV_CREATE), this}; + SFV_CREATE sfvparams = { sizeof(SFV_CREATE), this }; hr = SHCreateShellFolderView(&sfvparams, (IShellView**)ppv); } else @@ -606,8 +845,26 @@ HRESULT WINAPI CRecycleBin::GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY api SFGAOF *rgfInOut) { TRACE("(%p, %d, {%p, ...}, {%x})\n", this, cidl, apidl ? apidl[0] : NULL, (unsigned int)*rgfInOut); - *rgfInOut &= SFGAO_FOLDER|SFGAO_DROPTARGET|SFGAO_HASPROPSHEET|SFGAO_CANLINK; - return S_OK; + HRESULT hr = S_OK; + const SFGAOF ThisFolder = SFGAO_FOLDER | SFGAO_HASPROPSHEET | SFGAO_DROPTARGET | SFGAO_CANRENAME | SFGAO_CANLINK; + if (!cidl) + { + *rgfInOut &= ThisFolder; + if (SHRestricted(REST_BITBUCKNOPROP)) + *rgfInOut &= ~SFGAO_HASPROPSHEET; + return hr; + } + SFGAOF remain = SFGAO_LINK & *rgfInOut; + *rgfInOut &= remain | SFGAO_HASPROPSHEET | SFGAO_CANDELETE | SFGAO_FILESYSTEM; // TODO: SFGAO_CANMOVE + for (UINT i = 0; (*rgfInOut & remain) && i < cidl && SUCCEEDED(hr); ++i) + { + if (IShellFolder* pSF = GetFSFolderForItem(apidl[i])) + { + hr = pSF->GetAttributesOf(1, &apidl[i], rgfInOut); + pSF->Release(); + } + } + return hr; } HRESULT WINAPI CRecycleBin::GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, @@ -623,14 +880,19 @@ HRESULT WINAPI CRecycleBin::GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_C return hr; *ppv = NULL; + assert(!cidl || (apidl && apidl[0])); if ((IsEqualIID (riid, IID_IContextMenu) || IsEqualIID(riid, IID_IContextMenu2)) && (cidl >= 1)) { - hr = ShellObjectCreatorInit(apidl[0], riid, &pObj); + hr = ShellObjectCreatorInit(cidl, apidl, riid, &pObj); } else if((IsEqualIID(riid, IID_IExtractIconA) || IsEqualIID(riid, IID_IExtractIconW)) && (cidl == 1)) { - hr = CRecyclerExtractIcon_CreateInstance(apidl[0], riid, &pObj); + if (IShellFolder *pSF = GetFSFolderForItem(apidl[0])) + { + hr = CRecyclerExtractIcon_CreateInstance(*pSF, apidl[0], riid, &pObj); + pSF->Release(); + } } else hr = E_NOINTERFACE; @@ -645,33 +907,36 @@ HRESULT WINAPI CRecycleBin::GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_C HRESULT WINAPI CRecycleBin::GetDisplayNameOf(PCUITEMID_CHILD pidl, SHGDNF uFlags, STRRET *pName) { - PIDLRecycleStruct *pFileDetails; - LPWSTR pFileName; - TRACE("(%p, %p, %x, %p)\n", this, pidl, (unsigned int)uFlags, pName); + const BBITEMDATA *pData = ValidateItem(pidl); + if (!pData) + return E_INVALIDARG; - pFileDetails = _ILGetRecycleStruct(pidl); - if (!pFileDetails) + if (IS_SHGDN_FOR_PARSING(uFlags)) { - pName->cStr[0] = 0; - pName->uType = STRRET_CSTR; - return E_INVALIDARG; + LPCWSTR pszName = GetItemRecycledFullPath(*pData); + if (uFlags & SHGDN_INFOLDER) + pszName = PathFindFileNameW(pszName); + pName->pOleStr = SHStrDupW(pszName); } - - pFileName = wcsrchr(pFileDetails->szName, L'\\'); - if (!pFileName) + else { - pName->cStr[0] = 0; - pName->uType = STRRET_CSTR; - return E_UNEXPECTED; + if (uFlags & SHGDN_INFOLDER) + pName->pOleStr = SHStrDupW(GetItemOriginalFileName(*pData)); + else + pName->pOleStr = SHStrDupW(GetItemOriginalFullPath(*pData)); } - pName->pOleStr = StrDupW(pFileName + 1); - if (pName->pOleStr == NULL) - return E_OUTOFMEMORY; - - pName->uType = STRRET_WSTR; - return S_OK; + if (pName->pOleStr) + { + pName->uType = STRRET_WSTR; + if (!IsFolder(pidl)) + SHELL_FS_ProcessDisplayFilename(pName->pOleStr, uFlags); + return S_OK; + } + pName->uType = STRRET_CSTR; + pName->cStr[0] = '\0'; + return E_OUTOFMEMORY; } HRESULT WINAPI CRecycleBin::SetNameOf(HWND hwnd, PCUITEMID_CHILD pidl, LPCOLESTR pszName, @@ -719,33 +984,12 @@ HRESULT WINAPI CRecycleBin::GetDetailsEx(PCUITEMID_CHILD pidl, const SHCOLUMNID return E_NOTIMPL; } -static HRESULT FormatDateTime(LPWSTR buffer, int size, FILETIME * ft) -{ - FILETIME lft; - SYSTEMTIME time; - int ret; - - FileTimeToLocalFileTime(ft, &lft); - FileTimeToSystemTime(&lft, &time); - - ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &time, NULL, buffer, size); - if (ret > 0 && ret < size) - { - /* Append space + time without seconds */ - buffer[ret-1] = ' '; - GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &time, NULL, &buffer[ret], size - ret); - } - - return (ret != 0 ? E_FAIL : S_OK); -} - HRESULT WINAPI CRecycleBin::GetDetailsOf(PCUITEMID_CHILD pidl, UINT iColumn, LPSHELLDETAILS pDetails) { - PIDLRecycleStruct * pFileDetails; + HRESULT hr; + FILETIME ft; + SHFILEINFOW shfi; WCHAR buffer[MAX_PATH]; - WCHAR szTypeName[100]; - LPWSTR pszBackslash; - UINT Length; TRACE("(%p, %p, %d, %p)\n", this, pidl, iColumn, pDetails); if (iColumn >= COLUMNS_COUNT) @@ -759,66 +1003,36 @@ HRESULT WINAPI CRecycleBin::GetDetailsOf(PCUITEMID_CHILD pidl, UINT iColumn, LPS } if (iColumn == COLUMN_NAME) - return GetDisplayNameOf(pidl, SHGDN_NORMAL, &pDetails->str); + return GetDisplayNameOf(pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &pDetails->str); - pFileDetails = _ILGetRecycleStruct(pidl); - if (!pFileDetails && FAILED_UNEXPECTEDLY(E_INVALIDARG)) + const BBITEMDATA *pData = ValidateItem(pidl); + if (!pData && FAILED_UNEXPECTEDLY(E_INVALIDARG)) return E_INVALIDARG; + switch (iColumn) { case COLUMN_DATEDEL: - FormatDateTime(buffer, MAX_PATH, &pFileDetails->DeletionTime); + CFSFolder::FormatDateTime(pData->DeletionTime, buffer, _countof(buffer)); break; case COLUMN_DELFROM: - pszBackslash = wcsrchr(pFileDetails->szName, L'\\'); - if (!pszBackslash) - { - ERR("Filename '%ls' not a valid path?\n", pFileDetails->szName); - Length = 0; - } - else - { - Length = (pszBackslash - pFileDetails->szName); - memcpy((LPVOID)buffer, pFileDetails->szName, Length * sizeof(WCHAR)); - } - buffer[Length] = UNICODE_NULL; - if (buffer[0] && buffer[1] == L':' && !buffer[2]) - { - buffer[2] = L'\\'; - buffer[3] = UNICODE_NULL; - } - break; + if (SUCCEEDED(hr = GetItemOriginalFolder(*pData, pDetails->str.pOleStr))) + pDetails->str.uType = STRRET_WSTR; + return hr; case COLUMN_SIZE: - StrFormatKBSizeW(pFileDetails->FileSize.QuadPart, buffer, MAX_PATH); + *buffer = UNICODE_NULL; + if (!IsFolder(pidl)) + CFSFolder::FormatSize(GetItemFileSize(pidl), buffer, _countof(buffer)); break; case COLUMN_MTIME: - FormatDateTime(buffer, MAX_PATH, &pFileDetails->LastModification); + _ILGetFileDateTime(pidl, &ft); + CFSFolder::FormatDateTime(ft, buffer, _countof(buffer)); break; case COLUMN_TYPE: - { - SEARCH_CONTEXT Context; - Context.pFileDetails = pFileDetails; - Context.bFound = FALSE; - EnumerateRecycleBinW(NULL, CBSearchRecycleBin, (PVOID)&Context); - - if (Context.bFound) - { - GetDeletedFileTypeNameW(Context.hDeletedFile, buffer, _countof(buffer), NULL); - - CloseRecycleBinHandle(Context.hDeletedFile); - } - /* load localized file string */ - else if (LoadStringW(shell32_hInstance, IDS_ANY_FILE, szTypeName, _countof(szTypeName))) - { - StringCchPrintfW(buffer, _countof(buffer), szTypeName, PathFindExtensionW(pFileDetails->szName)); - } - - return SHSetStrRet(&pDetails->str, buffer); - } + GetItemTypeName(pidl, *pData, shfi); + return SHSetStrRet(&pDetails->str, shfi.szTypeName); default: return E_FAIL; } - return SHSetStrRet(&pDetails->str, buffer); } @@ -832,85 +1046,75 @@ HRESULT WINAPI CRecycleBin::MapColumnToSCID(UINT iColumn, SHCOLUMNID *pscid) return S_OK; } -BOOL CRecycleBin::RecycleBinIsEmpty() -{ - CComPtr spEnumFiles; - HRESULT hr = EnumObjects(NULL, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &spEnumFiles); - if (FAILED(hr)) - return TRUE; - CComHeapPtr spPidl; - ULONG itemcount; - return spEnumFiles->Next(1, &spPidl, &itemcount) != S_OK; - } - /************************************************************************* * RecycleBin IContextMenu interface */ -HRESULT WINAPI CRecycleBin::QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags) +enum { IDC_EMPTYRECYCLEBIN = 1, IDC_PROPERTIES }; +static const CMVERBMAP g_BBFolderVerbMap[] = { - WCHAR szBuffer[100]; - MENUITEMINFOW mii; - int id = 1; + { "empty", IDC_EMPTYRECYCLEBIN }, + { "properties", IDC_PROPERTIES }, + { NULL } +}; +HRESULT WINAPI CRecycleBin::QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags) +{ TRACE("QueryContextMenu %p %p %u %u %u %u\n", this, hMenu, indexMenu, idCmdFirst, idCmdLast, uFlags ); if (!hMenu) return E_INVALIDARG; - ZeroMemory(&mii, sizeof(mii)); - mii.cbSize = sizeof(mii); - mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE; - mii.fState = RecycleBinIsEmpty() ? MFS_DISABLED : MFS_ENABLED; - szBuffer[0] = L'\0'; - LoadStringW(shell32_hInstance, IDS_EMPTY_BITBUCKET, szBuffer, _countof(szBuffer)); - mii.dwTypeData = szBuffer; - mii.cch = wcslen(mii.dwTypeData); - mii.wID = idCmdFirst + id++; - mii.fType = MFT_STRING; - iIdEmpty = 1; - - if (!InsertMenuItemW(hMenu, indexMenu, TRUE, &mii)) - return E_FAIL; + UINT idHigh = 0, id; - return MAKE_HRESULT(SEVERITY_SUCCESS, 0, id); + WORD state = IsRecycleBinEmpty(this) ? MFS_DISABLED : MFS_ENABLED; + id = idCmdFirst + IDC_EMPTYRECYCLEBIN; + if (_InsertMenuItemW(hMenu, indexMenu, TRUE, id, MFT_STRING, MAKEINTRESOURCEW(IDS_EMPTY_BITBUCKET), state)) + { + idHigh = max(idHigh, id); + if (m_IsBackgroundMenu && !SHRestricted(REST_BITBUCKNOPROP)) + { + id = idCmdFirst + IDC_PROPERTIES; + if (_InsertMenuItemW(hMenu, ++indexMenu, TRUE, id, MFT_STRING, MAKEINTRESOURCEW(IDS_PROPERTIES), 0)) + { + idHigh = max(idHigh, id); + _InsertMenuItemW(hMenu, indexMenu++, TRUE, -1, MFT_SEPARATOR, NULL, 0); + } + } + } + return idHigh ? MAKE_HRESULT(SEVERITY_SUCCESS, 0, idHigh - idCmdFirst + 1) : S_OK; } HRESULT WINAPI CRecycleBin::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi) { - HRESULT hr; - LPSHELLBROWSER lpSB; - IShellView * lpSV = NULL; - WCHAR szDrive[8]; - - TRACE("%p %p verb %p\n", this, lpcmi, lpcmi->lpVerb); - - if (LOWORD(lpcmi->lpVerb) == iIdEmpty) + TRACE("%p %p verb %p\n", this, lpcmi, lpcmi ? lpcmi->lpVerb : NULL); + int CmdId = SHELL_MapContextMenuVerbToCmdId(lpcmi, g_BBFolderVerbMap); + if (CmdId == IDC_EMPTYRECYCLEBIN) { - if (!GetEnvironmentVariableW(L"SystemDrive", szDrive, _countof(szDrive) - 1)) - { - ERR("GetEnvironmentVariableW failed\n"); - return E_FAIL; - } - PathAddBackslashW(szDrive); - - hr = SHEmptyRecycleBinW(lpcmi->hwnd, szDrive, 0); + HRESULT hr = SHEmptyRecycleBinW(lpcmi->hwnd, NULL, 0); TRACE("result %x\n", hr); if (hr != S_OK) return hr; - - lpSB = (LPSHELLBROWSER)SendMessageA(lpcmi->hwnd, CWM_GETISHELLBROWSER, 0, 0); - if (lpSB && SUCCEEDED(lpSB->QueryActiveShellView(&lpSV))) - lpSV->Refresh(); +#if 0 // This is a nasty hack because lpcmi->hwnd might not be a shell browser. + // Not required with working SHChangeNotify. + CComPtr pSV; + LPSHELLBROWSER lpSB = (LPSHELLBROWSER)SendMessage(lpcmi->hwnd, CWM_GETISHELLBROWSER, 0, 0); + if (lpSB && SUCCEEDED(lpSB->QueryActiveShellView(&pSV))) + pSV->Refresh(); +#endif + return hr; } - return S_OK; + else if (CmdId == IDC_PROPERTIES) + { + return SHELL_ShowItemIDListProperties((LPITEMIDLIST)CSIDL_BITBUCKET); + } + return E_INVALIDARG; } HRESULT WINAPI CRecycleBin::GetCommandString(UINT_PTR idCommand, UINT uFlags, UINT *lpReserved, LPSTR lpszName, UINT uMaxNameLen) { - FIXME("%p %lu %u %p %p %u\n", this, idCommand, uFlags, lpReserved, lpszName, uMaxNameLen); - - return E_NOTIMPL; + TRACE("%p %lu %u %p %p %u\n", this, idCommand, uFlags, lpReserved, lpszName, uMaxNameLen); + return SHELL_GetCommandStringImpl(idCommand, uFlags, lpszName, uMaxNameLen, g_BBFolderVerbMap); } /************************************************************************* @@ -937,6 +1141,7 @@ HRESULT WINAPI CRecycleBin::ReplacePage(EXPPS uPageID, LPFNSVADDPROPSHEETPAGE pf HRESULT WINAPI CRecycleBin::Initialize(PCIDLIST_ABSOLUTE pidlFolder, IDataObject *pdtobj, HKEY hkeyProgID) { TRACE("%p %p %p %p\n", this, pidlFolder, pdtobj, hkeyProgID ); + m_IsBackgroundMenu = false; return S_OK; } @@ -982,7 +1187,7 @@ TRASH_CanTrashFile(LPCWSTR wszPath) swprintf(szBuffer, L"%04X-%04X", LOWORD(VolSerialNumber), HIWORD(VolSerialNumber)); wcscat(szKey, szBuffer); - if (RegCreateKeyExW(HKEY_CURRENT_USER, szKey, 0, NULL, 0, KEY_WRITE, NULL, &hKey, &dwDisposition) != ERROR_SUCCESS) + if (RegCreateKeyExW(HKEY_CURRENT_USER, szKey, 0, NULL, 0, KEY_READ | KEY_WRITE, NULL, &hKey, &dwDisposition) != ERROR_SUCCESS) { ERR("RegCreateKeyExW failed\n"); return FALSE; @@ -996,8 +1201,6 @@ TRASH_CanTrashFile(LPCWSTR wszPath) /* per default unlimited size */ dwSize = -1; RegSetValueExW(hKey, L"MaxCapacity", 0, REG_DWORD, (LPBYTE)&dwSize, sizeof(DWORD)); - RegCloseKey(hKey); - return TRUE; } else { @@ -1005,27 +1208,18 @@ TRASH_CanTrashFile(LPCWSTR wszPath) ret = RegQueryValueExW(hKey, L"NukeOnDelete", NULL, &dwType, (LPBYTE)&dwNukeOnDelete, &dwSize); if (ret != ERROR_SUCCESS) { - if (ret == ERROR_FILE_NOT_FOUND) + dwNukeOnDelete = 0; + if (ret == ERROR_FILE_NOT_FOUND) { /* restore key and enable bitbucket */ - dwNukeOnDelete = 0; RegSetValueExW(hKey, L"NukeOnDelete", 0, REG_DWORD, (LPBYTE)&dwNukeOnDelete, sizeof(DWORD)); } - RegCloseKey(hKey); - return TRUE; } - else if (dwNukeOnDelete) - { - /* do not delete to bitbucket */ - RegCloseKey(hKey); - return FALSE; - } - /* FIXME - * check if bitbucket is full - */ - RegCloseKey(hKey); - return TRUE; } + BOOL bCanTrash = !dwNukeOnDelete; + // FIXME: Check if bitbucket is full (CORE-13743) + RegCloseKey(hKey); + return bCanTrash; } BOOL @@ -1178,7 +1372,7 @@ HRESULT WINAPI SHEmptyRecycleBinW(HWND hwnd, LPCWSTR pszRootPath, DWORD dwFlags) while (penumFiles->Next(1, &pidl, NULL) == S_OK) { count++; - pRecycleBin->GetDisplayNameOf(pidl, SHGDN_NORMAL, &StrRet); + pRecycleBin->GetDisplayNameOf(pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &StrRet); StrRetToBuf(&StrRet, pidl, szBuffer, _countof(szBuffer)); CoTaskMemFree(pidl); } @@ -1228,6 +1422,7 @@ HRESULT WINAPI SHEmptyRecycleBinW(HWND hwnd, LPCWSTR pszRootPath, DWORD dwFlags) if (!ret) return HRESULT_FROM_WIN32(GetLastError()); + CRecycleBin_ChangeNotifyBBItem(SHCNE_UPDATEDIR, NULL); if (!(dwFlags & SHERB_NOSOUND)) { TRASH_PlayEmptyRecycleBinSound(); diff --git a/dll/win32/shell32/folders/CRecycleBin.h b/dll/win32/shell32/folders/CRecycleBin.h index ecf56699447bd..7d676cd687551 100644 --- a/dll/win32/shell32/folders/CRecycleBin.h +++ b/dll/win32/shell32/folders/CRecycleBin.h @@ -37,12 +37,15 @@ class CRecycleBin : { private: LPITEMIDLIST pidl; - INT iIdEmpty; - BOOL RecycleBinIsEmpty(); + IShellFolder *m_pFSFolders[RECYCLEBINMAXDRIVECOUNT]; + bool m_IsBackgroundMenu; + + IShellFolder* GetFSFolderForItem(LPCITEMIDLIST pidl); public: CRecycleBin(); ~CRecycleBin(); + static inline REFCLSID GetClassID() { return CLSID_RecycleBin; } // IPersistFolder STDMETHOD(GetClassID)(CLSID *pClassID) override; diff --git a/dll/win32/shell32/folders/CRegFolder.cpp b/dll/win32/shell32/folders/CRegFolder.cpp index ece1845838ded..efaf4711f8657 100644 --- a/dll/win32/shell32/folders/CRegFolder.cpp +++ b/dll/win32/shell32/folders/CRegFolder.cpp @@ -755,33 +755,35 @@ HRESULT WINAPI CRegFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags, HRESULT WINAPI CRegFolder::SetNameOf(HWND hwndOwner, PCUITEMID_CHILD pidl, /* simple pidl */ LPCOLESTR lpName, DWORD dwFlags, PITEMID_CHILD *pPidlOut) { - GUID const *clsid = _ILGetGUIDPointer (pidl); - LPOLESTR pStr; - HRESULT hr; + GUID const *clsid = IsRegItem(pidl); WCHAR szName[100]; + if (!lpName || (*lpName && IsIllegalFsFileName(lpName))) // Note: Must allow empty name + return E_INVALIDARG; + if (!clsid) { ERR("Pidl is not reg item!\n"); return E_FAIL; } + FormatGUIDKey(szName, _countof(szName), L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\CLSID\\%s", clsid); - hr = StringFromCLSID(*clsid, &pStr); - if (FAILED_UNEXPECTEDLY(hr)) - return hr; - - swprintf(szName, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\CLSID\\%s", pStr); - + BOOL bEmpty = StrIsNullOrEmpty(lpName); // Empty resets to the default name DWORD cbData = (wcslen(lpName) + 1) * sizeof(WCHAR); - LONG res = SHSetValueW(HKEY_CURRENT_USER, szName, NULL, RRF_RT_REG_SZ, lpName, cbData); - - CoTaskMemFree(pStr); + LONG res = bEmpty ? SHDeleteValueW(HKEY_CURRENT_USER, szName, NULL) + : SHSetValueW(HKEY_CURRENT_USER, szName, NULL, RRF_RT_REG_SZ, lpName, cbData); if (res == ERROR_SUCCESS) { - return pPidlOut ? SHILClone(pidl, pPidlOut) : S_OK; + HRESULT hr = pPidlOut ? SHILClone(pidl, pPidlOut) : S_OK; // Copy the PIDL before SHChangeNotify + PIDLIST_ABSOLUTE pidlAbs; + if (SUCCEEDED(SHELL_CreateAbsolutePidl(m_pOuterFolder, pidl, &pidlAbs))) + { + SHChangeNotify(SHCNE_UPDATEITEM, SHCNF_IDLIST, pidlAbs, NULL); + ILFree(pidlAbs); + } + return hr; } - return E_FAIL; } diff --git a/dll/win32/shell32/iconcache.cpp b/dll/win32/shell32/iconcache.cpp index 9fb41f9389c0d..e0d8b179ecb69 100644 --- a/dll/win32/shell32/iconcache.cpp +++ b/dll/win32/shell32/iconcache.cpp @@ -1,21 +1,9 @@ /* - * shell icon cache (SIC) - * - * Copyright 1998, 1999 Juergen Schmied - * - * 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 + * PROJECT: ReactOS shell32 + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Shell Icon Cache (SIC) + * COPYRIGHT: Copyright 1998, 1999 Juergen Schmied + * Copyright 2025 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) */ #include "precomp.h" @@ -39,6 +27,9 @@ static HDPA sic_hdpa = 0; static HIMAGELIST ShellSmallIconList; static HIMAGELIST ShellBigIconList; +INT ShellSmallIconSize = 0; +INT ShellLargeIconSize = 0; +INT ShellIconBPP = 0; // Bits Per Pixel namespace { @@ -52,6 +43,48 @@ CRITICAL_SECTION_DEBUG critsect_debug = CRITICAL_SECTION SHELL32_SicCS = { &critsect_debug, -1, 0, 0, 0, 0 }; } +// Load metric value from registry +static INT +SIC_GetMetricsValue( + _In_ PCWSTR pszValueName, + _In_ INT nDefaultValue) +{ + WCHAR szValue[64]; + DWORD cbValue = sizeof(szValue); + DWORD error = SHGetValueW(HKEY_CURRENT_USER, L"Control Panel\\Desktop\\WindowMetrics", + pszValueName, NULL, szValue, &cbValue); + if (error) + return nDefaultValue; + szValue[_countof(szValue) - 1] = UNICODE_NULL; // Avoid buffer overrun + return _wtoi(szValue); +} + +static INT +SIC_GetLargeIconSize(VOID) +{ + // NOTE: Shell icon size is always square + INT nDefaultSize = GetSystemMetrics(SM_CXICON); + INT nIconSize = SIC_GetMetricsValue(L"Shell Icon Size", nDefaultSize); + return (nIconSize > 0) ? nIconSize : nDefaultSize; +} + +static INT +SIC_GetSmallIconSize(VOID) +{ + // NOTE: Shell icon size is always square + INT nDefaultSize = GetSystemMetrics(SM_CXSMICON); + INT nIconSize = SIC_GetMetricsValue(L"Shell Small Icon Size", nDefaultSize); + return (nIconSize > 0) ? nIconSize : nDefaultSize; +} + +static INT +SIC_GetIconBPP(VOID) // Bits Per Pixel +{ + INT nDefaultBPP = SHGetCurColorRes(); + INT nIconBPP = SIC_GetMetricsValue(L"Shell Icon BPP", nDefaultBPP); + return (nIconBPP > 0) ? nIconBPP : nDefaultBPP; +} + /***************************************************************************** * SIC_CompareEntries * @@ -386,14 +419,15 @@ static INT SIC_IconAppend (LPCWSTR sSourceFile, INT dwSourceIndex, HICON hSmallI */ static INT SIC_LoadIcon (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags) { - HICON hiconLarge=0; - HICON hiconSmall=0; + HICON hiconLarge = NULL, hiconSmall = NULL; UINT ret; - PrivateExtractIconsW(sSourceFile, dwSourceIndex, 32, 32, &hiconLarge, NULL, 1, LR_COPYFROMRESOURCE); - PrivateExtractIconsW(sSourceFile, dwSourceIndex, 16, 16, &hiconSmall, NULL, 1, LR_COPYFROMRESOURCE); + PrivateExtractIconsW(sSourceFile, dwSourceIndex, ShellLargeIconSize, ShellLargeIconSize, + &hiconLarge, NULL, 1, LR_COPYFROMRESOURCE); + PrivateExtractIconsW(sSourceFile, dwSourceIndex, ShellSmallIconSize, ShellSmallIconSize, + &hiconSmall, NULL, 1, LR_COPYFROMRESOURCE); - if ( !hiconLarge || !hiconSmall) + if (!hiconLarge || !hiconSmall) { WARN("failure loading icon %i from %s (%p %p)\n", dwSourceIndex, debugstr_w(sSourceFile), hiconLarge, hiconSmall); if(hiconLarge) DestroyIcon(hiconLarge); @@ -481,9 +515,6 @@ INT SIC_GetIconIndex (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags ) BOOL SIC_Initialize(void) { HICON hSm = NULL, hLg = NULL; - INT cx_small, cy_small; - INT cx_large, cy_large; - HDC hDC; INT bpp; DWORD ilMask; BOOL result = FALSE; @@ -502,16 +533,10 @@ BOOL SIC_Initialize(void) return FALSE; } - hDC = CreateICW(L"DISPLAY", NULL, NULL, NULL); - if (!hDC) - { - ERR("Failed to create information context (error %d)\n", GetLastError()); - goto end; - } - - bpp = GetDeviceCaps(hDC, BITSPIXEL); - DeleteDC(hDC); + ShellSmallIconSize = SIC_GetSmallIconSize(); + ShellLargeIconSize = SIC_GetLargeIconSize(); + bpp = ShellIconBPP = SIC_GetIconBPP(); // Bits Per Pixel if (bpp <= 4) ilMask = ILC_COLOR4; else if (bpp <= 8) @@ -527,27 +552,14 @@ BOOL SIC_Initialize(void) ilMask |= ILC_MASK; - cx_small = GetSystemMetrics(SM_CXSMICON); - cy_small = GetSystemMetrics(SM_CYSMICON); - cx_large = GetSystemMetrics(SM_CXICON); - cy_large = GetSystemMetrics(SM_CYICON); - - ShellSmallIconList = ImageList_Create(cx_small, - cy_small, - ilMask, - 100, - 100); + ShellSmallIconList = ImageList_Create(ShellSmallIconSize, ShellSmallIconSize, ilMask, 100, 100); if (!ShellSmallIconList) { ERR("Failed to create the small icon list.\n"); goto end; } - ShellBigIconList = ImageList_Create(cx_large, - cy_large, - ilMask, - 100, - 100); + ShellBigIconList = ImageList_Create(ShellLargeIconSize, ShellLargeIconSize, ilMask, 100, 100); if (!ShellBigIconList) { ERR("Failed to create the big icon list.\n"); @@ -555,11 +567,8 @@ BOOL SIC_Initialize(void) } /* Load the document icon, which is used as the default if an icon isn't found. */ - hSm = (HICON)LoadImageW(shell32_hInstance, - MAKEINTRESOURCEW(IDI_SHELL_DOCUMENT), - IMAGE_ICON, - cx_small, - cy_small, + hSm = (HICON)LoadImageW(shell32_hInstance, MAKEINTRESOURCEW(IDI_SHELL_DOCUMENT), + IMAGE_ICON, ShellSmallIconSize, ShellSmallIconSize, LR_SHARED | LR_DEFAULTCOLOR); if (!hSm) { @@ -567,11 +576,8 @@ BOOL SIC_Initialize(void) goto end; } - hLg = (HICON)LoadImageW(shell32_hInstance, - MAKEINTRESOURCEW(IDI_SHELL_DOCUMENT), - IMAGE_ICON, - cx_large, - cy_large, + hLg = (HICON)LoadImageW(shell32_hInstance, MAKEINTRESOURCEW(IDI_SHELL_DOCUMENT), + IMAGE_ICON, ShellLargeIconSize, ShellLargeIconSize, LR_SHARED | LR_DEFAULTCOLOR); if (!hLg) { @@ -1013,6 +1019,9 @@ HRESULT WINAPI SHDefExtractIconW(LPCWSTR pszIconFile, int iIndex, UINT uFlags, HICON hIcons[2]; WARN("%s %d 0x%08x %p %p %d, semi-stub\n", debugstr_w(pszIconFile), iIndex, uFlags, phiconLarge, phiconSmall, nIconSize); + if (!nIconSize) + nIconSize = MAKELONG(GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CXSMICON)); + ret = PrivateExtractIconsW(pszIconFile, iIndex, nIconSize, nIconSize, hIcons, NULL, 2, LR_DEFAULTCOLOR); /* FIXME: deal with uFlags parameter which contains GIL_ flags */ if (ret == 0xFFFFFFFF) diff --git a/dll/win32/shell32/lang/bg-BG.rc b/dll/win32/shell32/lang/bg-BG.rc index a6f1ec667379e..4bcc76ca435dc 100644 --- a/dll/win32/shell32/lang/bg-BG.rc +++ b/dll/win32/shell32/lang/bg-BG.rc @@ -604,17 +604,18 @@ BEGIN DEFPUSHBUTTON "&Начало", IDOK, 53, 198, 60, 14 PUSHBUTTON "&Затваряне", IDCANCEL, 118, 198, 60, 14 LTEXT "&Обем:", -1, 7, 6, 169, 9 - COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&Файлова система", -1, 7, 35, 170, 9 - COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8 LTEXT "&Размер на разпределените участъци", -1, 7, 64, 170, 9 - COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Етикет на& тома:", -1, 7, 93, 170, 9 EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL GROUPBOX "&Възможности за оразмеряване", 4610, 7, 121, 170, 49 AUTOCHECKBOX "&Бързо оразмеряване", 28674, 16, 135, 155, 10 AUTOCHECKBOX "&Използване на уплътняване", 28675, 16, 152, 155, 10 + CONTROL "", 30000, "STATIC", SS_ICON | WS_TABSTOP | SS_CENTERIMAGE | SS_NOTIFY, 7, 198, 15, 14 END IDD_CHECK_DISK DIALOGEX 50, 50, 244, 120 @@ -637,8 +638,8 @@ CAPTION "Смяна на значе" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Look for icons in this file:", -1, 7, 7, 179, 10 - PUSHBUTTON "Обзор...", IDC_BUTTON_PATH, 135, 17, 50, 14 EDITTEXT IDC_EDIT_PATH, 7, 17, 123, 14, ES_AUTOHSCROLL + PUSHBUTTON "Обзор...", IDC_BUTTON_PATH, 135, 17, 50, 14 LTEXT "Select an icon from the list below:", -1, 7, 36, 179, 10 LISTBOX IDC_PICKICON_LIST, 7, 47, 181, 122, LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | LBS_DISABLENOSCROLL | WS_HSCROLL | WS_TABSTOP DEFPUSHBUTTON "Добре", IDOK, 81, 179, 50, 14 @@ -998,6 +999,12 @@ BEGIN IDS_OBJECTS "%d Objects" IDS_OBJECTS_SELECTED "%d Objects Selected" + IDS_SEARCH_BROWSEITEM "Обзор..." + + IDS_RECYCLE_CLEANER_DISPLAYNAME "Recycle Bin" + IDS_RECYCLE_CLEANER_DESCRIPTION "The Recycle Bin contains files you have deleted from your computer. These files are not permanently removed until you empty the Recycle Bin." + IDS_RECYCLE_CLEANER_BUTTON_TEXT "&View Files" + IDS_TITLE_MYCOMP "Моят компютър" IDS_TITLE_MYNET "Моята мрежа" IDS_TITLE_BIN_1 "Кошче (пълно)" diff --git a/dll/win32/shell32/lang/ca-ES.rc b/dll/win32/shell32/lang/ca-ES.rc index 518dd4329d67b..020071e5a02aa 100644 --- a/dll/win32/shell32/lang/ca-ES.rc +++ b/dll/win32/shell32/lang/ca-ES.rc @@ -216,7 +216,7 @@ BEGIN LTEXT "Choose the advanced properties you want for this shortcut.", -1, 5, 30, 210, 10 CHECKBOX "Run with different credentials", IDC_SHORTEX_RUN_DIFFERENT, 25, 50, 150, 10 LTEXT "This option can allow you to run the this shortcut as another user, or continue as yourself while protecting your computer and data from unauthorized program activity.", -1, 50, 60, 175, 40 - CHECKBOX "Run in seperate memory space", IDC_SHORTEX_RUN_SEPARATE, 25, 100, 150, 10, WS_DISABLED + CHECKBOX "Run in separate memory space", IDC_SHORTEX_RUN_SEPARATE, 25, 100, 150, 10, WS_DISABLED PUSHBUTTON "OK", IDOK, 63, 124, 50, 15, WS_VISIBLE PUSHBUTTON "Abort", IDCANCEL, 120, 124, 50, 15, WS_VISIBLE END @@ -604,17 +604,18 @@ BEGIN DEFPUSHBUTTON "&Start", IDOK, 53, 198, 60, 14 PUSHBUTTON "&Close", IDCANCEL, 118, 198, 60, 14 LTEXT "Ca&pacity:", -1, 7, 6, 169, 9 - COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&File system", -1, 7, 35, 170, 9 - COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8 LTEXT "&Allocation unit size", -1, 7, 64, 170, 9 - COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Volume &label", -1, 7, 93, 170, 9 EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL GROUPBOX "Format &options", 4610, 7, 121, 170, 49 AUTOCHECKBOX "&Quick Format", 28674, 16, 135, 155, 10 AUTOCHECKBOX "&Enable Compression", 28675, 16, 152, 155, 10 + CONTROL "", 30000, "STATIC", SS_ICON | WS_TABSTOP | SS_CENTERIMAGE | SS_NOTIFY, 7, 198, 15, 14 END IDD_CHECK_DISK DIALOGEX 50, 50, 194, 115 @@ -637,8 +638,8 @@ CAPTION "Change Icon" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Look for icons in this file:", -1, 7, 7, 179, 10 - PUSHBUTTON "Browse...", IDC_BUTTON_PATH, 135, 17, 50, 14 EDITTEXT IDC_EDIT_PATH, 7, 17, 123, 14, ES_AUTOHSCROLL + PUSHBUTTON "Browse...", IDC_BUTTON_PATH, 135, 17, 50, 14 LTEXT "Select an icon from the list below:", -1, 7, 36, 179, 10 LISTBOX IDC_PICKICON_LIST, 7, 47, 181, 122, LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | LBS_DISABLENOSCROLL | WS_HSCROLL | WS_TABSTOP DEFPUSHBUTTON "OK", IDOK, 81, 179, 50, 14 @@ -998,6 +999,12 @@ BEGIN IDS_OBJECTS "%d Objects" IDS_OBJECTS_SELECTED "%d Objects Selected" + IDS_SEARCH_BROWSEITEM "Browse..." + + IDS_RECYCLE_CLEANER_DISPLAYNAME "Recycle Bin" + IDS_RECYCLE_CLEANER_DESCRIPTION "The Recycle Bin contains files you have deleted from your computer. These files are not permanently removed until you empty the Recycle Bin." + IDS_RECYCLE_CLEANER_BUTTON_TEXT "&View Files" + IDS_TITLE_MYCOMP "My Computer" IDS_TITLE_MYNET "My Network Places" IDS_TITLE_BIN_1 "Recycle Bin (full)" diff --git a/dll/win32/shell32/lang/cs-CZ.rc b/dll/win32/shell32/lang/cs-CZ.rc index 744d8c727a76e..2566b76e74257 100644 --- a/dll/win32/shell32/lang/cs-CZ.rc +++ b/dll/win32/shell32/lang/cs-CZ.rc @@ -612,17 +612,18 @@ BEGIN DEFPUSHBUTTON "&Spustit", IDOK, 53, 198, 60, 14 PUSHBUTTON "&Zavřít", IDCANCEL, 118, 198, 60, 14 LTEXT "&Kapacita:", -1, 7, 6, 169, 9 - COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Souborový systé&m", -1, 7, 35, 170, 9 - COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8 LTEXT "&Velikost alokační jednotky", -1, 7, 64, 170, 9 - COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&Jmenovka svazku", -1, 7, 93, 170, 9 EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL GROUPBOX "Možnosti &formátování", 4610, 7, 121, 170, 49 AUTOCHECKBOX "&Rychlé formátování", 28674, 16, 135, 155, 10 AUTOCHECKBOX "&Aktivovat kompresi", 28675, 16, 152, 155, 10 + CONTROL "", 30000, "STATIC", SS_ICON | WS_TABSTOP | SS_CENTERIMAGE | SS_NOTIFY, 7, 198, 15, 14 END IDD_CHECK_DISK DIALOGEX 50, 50, 194, 115 @@ -645,8 +646,8 @@ CAPTION "Změnit ikonu" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Vyhledat ikony v souboru:", -1, 7, 7, 179, 10 - PUSHBUTTON "Procházet...", IDC_BUTTON_PATH, 135, 17, 50, 14 EDITTEXT IDC_EDIT_PATH, 7, 17, 123, 14, ES_AUTOHSCROLL + PUSHBUTTON "Procházet...", IDC_BUTTON_PATH, 135, 17, 50, 14 LTEXT "Vyberte ikonu z následujícího seznamu:", -1, 7, 36, 179, 10 LISTBOX IDC_PICKICON_LIST, 7, 47, 181, 122, LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | LBS_DISABLENOSCROLL | WS_HSCROLL | WS_TABSTOP DEFPUSHBUTTON "OK", IDOK, 81, 179, 50, 14 @@ -1006,6 +1007,12 @@ BEGIN IDS_OBJECTS "Položek: %d" IDS_OBJECTS_SELECTED "Položek vybráno: %d" + IDS_SEARCH_BROWSEITEM "Procházet..." + + IDS_RECYCLE_CLEANER_DISPLAYNAME "Recycle Bin" + IDS_RECYCLE_CLEANER_DESCRIPTION "The Recycle Bin contains files you have deleted from your computer. These files are not permanently removed until you empty the Recycle Bin." + IDS_RECYCLE_CLEANER_BUTTON_TEXT "&View Files" + IDS_TITLE_MYCOMP "Tento počítač" IDS_TITLE_MYNET "Místa v síti" IDS_TITLE_BIN_1 "Koš (plný)" diff --git a/dll/win32/shell32/lang/da-DK.rc b/dll/win32/shell32/lang/da-DK.rc index 7ba29c63939b1..f10d9f279351e 100644 --- a/dll/win32/shell32/lang/da-DK.rc +++ b/dll/win32/shell32/lang/da-DK.rc @@ -223,7 +223,7 @@ BEGIN LTEXT "Choose the advanced properties you want for this shortcut.", -1, 5, 30, 210, 10 CHECKBOX "Run with different credentials", IDC_SHORTEX_RUN_DIFFERENT, 25, 50, 150, 10 LTEXT "This option can allow you to run the this shortcut as another user, or continue as yourself while protecting your computer and data from unauthorized program activity.", -1, 50, 60, 175, 40 - CHECKBOX "Run in seperate memory space", IDC_SHORTEX_RUN_SEPARATE, 25, 100, 150, 10, WS_DISABLED + CHECKBOX "Run in separate memory space", IDC_SHORTEX_RUN_SEPARATE, 25, 100, 150, 10, WS_DISABLED PUSHBUTTON "OK", IDOK, 63, 124, 50, 15, WS_VISIBLE PUSHBUTTON "Abort", IDCANCEL, 120, 124, 50, 15, WS_VISIBLE END @@ -611,17 +611,18 @@ BEGIN DEFPUSHBUTTON "&Start", IDOK, 53, 198, 60, 14 PUSHBUTTON "&Close", IDCANCEL, 118, 198, 60, 14 LTEXT "Ca&pacity:", -1, 7, 6, 169, 9 - COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&File system", -1, 7, 35, 170, 9 - COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8 LTEXT "&Allocation unit size", -1, 7, 64, 170, 9 - COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Volume &label", -1, 7, 93, 170, 9 EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL GROUPBOX "Format &options", 4610, 7, 121, 170, 49 AUTOCHECKBOX "&Quick Format", 28674, 16, 135, 155, 10 AUTOCHECKBOX "&Enable Compression", 28675, 16, 152, 155, 10 + CONTROL "", 30000, "STATIC", SS_ICON | WS_TABSTOP | SS_CENTERIMAGE | SS_NOTIFY, 7, 198, 15, 14 END IDD_CHECK_DISK DIALOGEX 50, 50, 194, 115 @@ -644,8 +645,8 @@ CAPTION "Change Icon" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Look for icons in this file:", -1, 7, 7, 179, 10 - PUSHBUTTON "Browse...", IDC_BUTTON_PATH, 135, 17, 50, 14 EDITTEXT IDC_EDIT_PATH, 7, 17, 123, 14, ES_AUTOHSCROLL + PUSHBUTTON "Browse...", IDC_BUTTON_PATH, 135, 17, 50, 14 LTEXT "Select an icon from the list below:", -1, 7, 36, 179, 10 LISTBOX IDC_PICKICON_LIST, 7, 47, 181, 122, LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | LBS_DISABLENOSCROLL | WS_HSCROLL | WS_TABSTOP DEFPUSHBUTTON "OK", IDOK, 81, 179, 50, 14 @@ -1005,6 +1006,12 @@ BEGIN IDS_OBJECTS "%d Objects" IDS_OBJECTS_SELECTED "%d Objects Selected" + IDS_SEARCH_BROWSEITEM "Gennemse..." + + IDS_RECYCLE_CLEANER_DISPLAYNAME "Recycle Bin" + IDS_RECYCLE_CLEANER_DESCRIPTION "The Recycle Bin contains files you have deleted from your computer. These files are not permanently removed until you empty the Recycle Bin." + IDS_RECYCLE_CLEANER_BUTTON_TEXT "&View Files" + IDS_TITLE_MYCOMP "Min Computer" IDS_TITLE_MYNET "My Network Places" IDS_TITLE_BIN_1 "Recycle Bin (full)" diff --git a/dll/win32/shell32/lang/de-DE.rc b/dll/win32/shell32/lang/de-DE.rc index ecb87154a4ba2..065d250bdb47e 100644 --- a/dll/win32/shell32/lang/de-DE.rc +++ b/dll/win32/shell32/lang/de-DE.rc @@ -604,17 +604,18 @@ BEGIN DEFPUSHBUTTON "&Starten", IDOK, 53, 198, 60, 14 PUSHBUTTON "S&chließen", IDCANCEL, 118, 198, 60, 14 LTEXT "S&peicherkapazität:", -1, 7, 6, 169, 9 - COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&Dateisystem", -1, 7, 35, 170, 9 - COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8 LTEXT "&Größe der Zuordnungseinheiten", -1, 7, 64, 170, 9 - COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Volume&bezeichnung", -1, 7, 93, 170, 9 EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL GROUPBOX "&Formatierungsoptionen", 4610, 7, 121, 170, 49 AUTOCHECKBOX "Sch&nellformatierung", 28674, 16, 135, 155, 10 AUTOCHECKBOX "&Komprimierung aktivieren", 28675, 16, 152, 155, 10 + CONTROL "", 30000, "STATIC", SS_ICON | WS_TABSTOP | SS_CENTERIMAGE | SS_NOTIFY, 7, 198, 15, 14 END IDD_CHECK_DISK DIALOGEX 50, 50, 194, 115 @@ -637,8 +638,8 @@ CAPTION "Anderes Symbol" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Datei nach Symbolen durchsuchen:", -1, 7, 7, 179, 10 - PUSHBUTTON "Durchsuchen...", IDC_BUTTON_PATH, 126, 17, 59, 14 EDITTEXT IDC_EDIT_PATH, 7, 17, 114, 14, ES_AUTOHSCROLL + PUSHBUTTON "Durchsuchen...", IDC_BUTTON_PATH, 126, 17, 59, 14 LTEXT "Wählen Sie ein Symbol aus der folgenden Liste:", -1, 7, 36, 179, 10 LISTBOX IDC_PICKICON_LIST, 7, 47, 181, 122, LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | LBS_DISABLENOSCROLL | WS_HSCROLL | WS_TABSTOP DEFPUSHBUTTON "OK", IDOK, 81, 179, 50, 14 @@ -999,6 +1000,12 @@ BEGIN IDS_OBJECTS "%d Objekte" IDS_OBJECTS_SELECTED "%d Objekte ausgewählt" + IDS_SEARCH_BROWSEITEM "Durchsuchen..." + + IDS_RECYCLE_CLEANER_DISPLAYNAME "Recycle Bin" + IDS_RECYCLE_CLEANER_DESCRIPTION "The Recycle Bin contains files you have deleted from your computer. These files are not permanently removed until you empty the Recycle Bin." + IDS_RECYCLE_CLEANER_BUTTON_TEXT "&View Files" + IDS_TITLE_MYCOMP "Arbeitsplatz" IDS_TITLE_MYNET "Netzwerkumgebung" IDS_TITLE_BIN_1 "Papierkorb (voll)" diff --git a/dll/win32/shell32/lang/el-GR.rc b/dll/win32/shell32/lang/el-GR.rc index e26cab3ff42d2..5a3f7d1c50dfb 100644 --- a/dll/win32/shell32/lang/el-GR.rc +++ b/dll/win32/shell32/lang/el-GR.rc @@ -604,17 +604,18 @@ BEGIN DEFPUSHBUTTON "&Start", IDOK, 53, 198, 60, 14 PUSHBUTTON "&Close", IDCANCEL, 118, 198, 60, 14 LTEXT "Ca&pacity:", -1, 7, 6, 169, 9 - COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&File system", -1, 7, 35, 170, 9 - COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8 LTEXT "&Allocation unit size", -1, 7, 64, 170, 9 - COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Volume &label", -1, 7, 93, 170, 9 EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL GROUPBOX "Format &options", 4610, 7, 121, 170, 49 AUTOCHECKBOX "&Quick Format", 28674, 16, 135, 155, 10 AUTOCHECKBOX "&Enable Compression", 28675, 16, 152, 155, 10 + CONTROL "", 30000, "STATIC", SS_ICON | WS_TABSTOP | SS_CENTERIMAGE | SS_NOTIFY, 7, 198, 15, 14 END IDD_CHECK_DISK DIALOGEX 50, 50, 194, 115 @@ -637,8 +638,8 @@ CAPTION "Change Icon" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Look for icons in this file:", -1, 7, 7, 179, 10 - PUSHBUTTON "Browse...", IDC_BUTTON_PATH, 135, 17, 50, 14 EDITTEXT IDC_EDIT_PATH, 7, 17, 123, 14, ES_AUTOHSCROLL + PUSHBUTTON "Browse...", IDC_BUTTON_PATH, 135, 17, 50, 14 LTEXT "Select an icon from the list below:", -1, 7, 36, 179, 10 LISTBOX IDC_PICKICON_LIST, 7, 47, 181, 122, LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | LBS_DISABLENOSCROLL | WS_HSCROLL | WS_TABSTOP DEFPUSHBUTTON "OK", IDOK, 81, 179, 50, 14 @@ -998,6 +999,12 @@ BEGIN IDS_OBJECTS "%d Objects" IDS_OBJECTS_SELECTED "%d Objects Selected" + IDS_SEARCH_BROWSEITEM "Αναζήτηση..." + + IDS_RECYCLE_CLEANER_DISPLAYNAME "Recycle Bin" + IDS_RECYCLE_CLEANER_DESCRIPTION "The Recycle Bin contains files you have deleted from your computer. These files are not permanently removed until you empty the Recycle Bin." + IDS_RECYCLE_CLEANER_BUTTON_TEXT "&View Files" + IDS_TITLE_MYCOMP "Ο υπολογιστής μου" IDS_TITLE_MYNET "My Network Places" IDS_TITLE_BIN_1 "Κάδος ανακύκλωσης (γεμάτος)" diff --git a/dll/win32/shell32/lang/en-GB.rc b/dll/win32/shell32/lang/en-GB.rc index 7d3e5ef59a8e4..64d99f652f482 100644 --- a/dll/win32/shell32/lang/en-GB.rc +++ b/dll/win32/shell32/lang/en-GB.rc @@ -216,7 +216,7 @@ BEGIN LTEXT "Choose the advanced properties you want for this shortcut.", -1, 5, 30, 210, 10 CHECKBOX "Run with different credentials", IDC_SHORTEX_RUN_DIFFERENT, 25, 50, 150, 10 LTEXT "This option can allow you to run the this shortcut as another user, or continue as yourself while protecting your computer and data from unauthorised program activity.", -1, 50, 60, 175, 40 - CHECKBOX "Run in seperate memory space", IDC_SHORTEX_RUN_SEPARATE, 25, 100, 150, 10, WS_DISABLED + CHECKBOX "Run in separate memory space", IDC_SHORTEX_RUN_SEPARATE, 25, 100, 150, 10, WS_DISABLED PUSHBUTTON "OK", IDOK, 63, 124, 50, 15, WS_VISIBLE PUSHBUTTON "Abort", IDCANCEL, 120, 124, 50, 15, WS_VISIBLE END @@ -604,17 +604,18 @@ BEGIN DEFPUSHBUTTON "&Start", IDOK, 53, 198, 60, 14 PUSHBUTTON "&Close", IDCANCEL, 118, 198, 60, 14 LTEXT "Ca&pacity:", -1, 7, 6, 169, 9 - COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&File system", -1, 7, 35, 170, 9 - COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8 LTEXT "&Allocation unit size", -1, 7, 64, 170, 9 - COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Volume &label", -1, 7, 93, 170, 9 EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL GROUPBOX "Format &options", 4610, 7, 121, 170, 49 AUTOCHECKBOX "&Quick Format", 28674, 16, 135, 155, 10 AUTOCHECKBOX "&Enable Compression", 28675, 16, 152, 155, 10 + CONTROL "", 30000, "STATIC", SS_ICON | WS_TABSTOP | SS_CENTERIMAGE | SS_NOTIFY, 7, 198, 15, 14 END IDD_CHECK_DISK DIALOGEX 50, 50, 194, 115 @@ -637,8 +638,8 @@ CAPTION "Change Icon" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Look for icons in this file:", -1, 7, 7, 179, 10 - PUSHBUTTON "Browse...", IDC_BUTTON_PATH, 135, 17, 50, 14 EDITTEXT IDC_EDIT_PATH, 7, 17, 123, 14, ES_AUTOHSCROLL + PUSHBUTTON "Browse...", IDC_BUTTON_PATH, 135, 17, 50, 14 LTEXT "Select an icon from the list below:", -1, 7, 36, 179, 10 LISTBOX IDC_PICKICON_LIST, 7, 47, 181, 122, LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | LBS_DISABLENOSCROLL | WS_HSCROLL | WS_TABSTOP DEFPUSHBUTTON "OK", IDOK, 81, 179, 50, 14 @@ -998,6 +999,12 @@ BEGIN IDS_OBJECTS "%d Objects" IDS_OBJECTS_SELECTED "%d Objects Selected" + IDS_SEARCH_BROWSEITEM "Browse..." + + IDS_RECYCLE_CLEANER_DISPLAYNAME "Recycle Bin" + IDS_RECYCLE_CLEANER_DESCRIPTION "The Recycle Bin contains files you have deleted from your computer. These files are not permanently removed until you empty the Recycle Bin." + IDS_RECYCLE_CLEANER_BUTTON_TEXT "&View Files" + IDS_TITLE_MYCOMP "My Computer" IDS_TITLE_MYNET "My Network Places" IDS_TITLE_BIN_1 "Recycle Bin (full)" diff --git a/dll/win32/shell32/lang/en-US.rc b/dll/win32/shell32/lang/en-US.rc index e8195754991bb..a61104b21774d 100644 --- a/dll/win32/shell32/lang/en-US.rc +++ b/dll/win32/shell32/lang/en-US.rc @@ -216,7 +216,7 @@ BEGIN LTEXT "Choose the advanced properties you want for this shortcut.", -1, 5, 30, 210, 10 CHECKBOX "Run with different credentials", IDC_SHORTEX_RUN_DIFFERENT, 25, 50, 150, 10 LTEXT "This option can allow you to run the this shortcut as another user, or continue as yourself while protecting your computer and data from unauthorized program activity.", -1, 50, 60, 175, 40 - CHECKBOX "Run in seperate memory space", IDC_SHORTEX_RUN_SEPARATE, 25, 100, 150, 10, WS_DISABLED + CHECKBOX "Run in separate memory space", IDC_SHORTEX_RUN_SEPARATE, 25, 100, 150, 10, WS_DISABLED PUSHBUTTON "OK", IDOK, 63, 124, 50, 15, WS_VISIBLE PUSHBUTTON "Cancel", IDCANCEL, 120, 124, 50, 15, WS_VISIBLE END @@ -604,17 +604,18 @@ BEGIN DEFPUSHBUTTON "&Start", IDOK, 53, 198, 60, 14 PUSHBUTTON "&Close", IDCANCEL, 118, 198, 60, 14 LTEXT "Ca&pacity:", -1, 7, 6, 169, 9 - COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&File system", -1, 7, 35, 170, 9 - COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8 LTEXT "&Allocation unit size", -1, 7, 64, 170, 9 - COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Volume &label", -1, 7, 93, 170, 9 EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL GROUPBOX "Format &options", 4610, 7, 121, 170, 49 AUTOCHECKBOX "&Quick Format", 28674, 16, 135, 155, 10 AUTOCHECKBOX "&Enable Compression", 28675, 16, 152, 155, 10 + CONTROL "", 30000, "STATIC", SS_ICON | WS_TABSTOP | SS_CENTERIMAGE | SS_NOTIFY, 7, 198, 15, 14 END IDD_CHECK_DISK DIALOGEX 50, 50, 194, 115 @@ -637,8 +638,8 @@ CAPTION "Change Icon" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Look for icons in this file:", -1, 7, 7, 179, 10 - PUSHBUTTON "Browse...", IDC_BUTTON_PATH, 135, 17, 50, 14 EDITTEXT IDC_EDIT_PATH, 7, 17, 123, 14, ES_AUTOHSCROLL + PUSHBUTTON "Browse...", IDC_BUTTON_PATH, 135, 17, 50, 14 LTEXT "Select an icon from the list below:", -1, 7, 36, 179, 10 LISTBOX IDC_PICKICON_LIST, 7, 47, 181, 122, LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | LBS_DISABLENOSCROLL | WS_HSCROLL | WS_TABSTOP DEFPUSHBUTTON "OK", IDOK, 81, 179, 50, 14 @@ -998,6 +999,12 @@ BEGIN IDS_OBJECTS "%d Objects" IDS_OBJECTS_SELECTED "%d Objects Selected" + IDS_SEARCH_BROWSEITEM "Browse..." + + IDS_RECYCLE_CLEANER_DISPLAYNAME "Recycle Bin" + IDS_RECYCLE_CLEANER_DESCRIPTION "The Recycle Bin contains files you have deleted from your computer. These files are not permanently removed until you empty the Recycle Bin." + IDS_RECYCLE_CLEANER_BUTTON_TEXT "&View Files" + IDS_TITLE_MYCOMP "My Computer" IDS_TITLE_MYNET "My Network Places" IDS_TITLE_BIN_1 "Recycle Bin (full)" diff --git a/dll/win32/shell32/lang/es-ES.rc b/dll/win32/shell32/lang/es-ES.rc index 0d4e112eada20..cdd0232adad71 100644 --- a/dll/win32/shell32/lang/es-ES.rc +++ b/dll/win32/shell32/lang/es-ES.rc @@ -613,17 +613,18 @@ BEGIN DEFPUSHBUTTON "&Iniciar", IDOK, 53, 198, 60, 14 PUSHBUTTON "&Cerrar", IDCANCEL, 118, 198, 60, 14 LTEXT "C&apacidad:", -1, 7, 6, 169, 9 - COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&Sistema de archivos", -1, 7, 35, 170, 9 - COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8 LTEXT "&Tamaño de unidad de asignación", -1, 7, 64, 170, 9 - COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&Etiqueta del volumen", -1, 7, 93, 170, 9 EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL GROUPBOX "&Opciones de formato", 4610, 7, 121, 170, 49 AUTOCHECKBOX "Formato &rápido", 28674, 16, 135, 155, 10 AUTOCHECKBOX "&Habilitar compresión", 28675, 16, 152, 155, 10 + CONTROL "", 30000, "STATIC", SS_ICON | WS_TABSTOP | SS_CENTERIMAGE | SS_NOTIFY, 7, 198, 15, 14 END IDD_CHECK_DISK DIALOGEX 50, 50, 240, 120 @@ -646,8 +647,8 @@ CAPTION "Cambiar icono" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Buscar íconos en este archivo:", -1, 7, 7, 179, 10 - PUSHBUTTON "Examinar...", IDC_BUTTON_PATH, 135, 17, 50, 14 EDITTEXT IDC_EDIT_PATH, 7, 17, 123, 14, ES_AUTOHSCROLL + PUSHBUTTON "Examinar...", IDC_BUTTON_PATH, 135, 17, 50, 14 LTEXT "Seleccione un ícono de la siguiente lista:", -1, 7, 36, 179, 10 LISTBOX IDC_PICKICON_LIST, 7, 47, 181, 122, LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | LBS_DISABLENOSCROLL | WS_HSCROLL | WS_TABSTOP DEFPUSHBUTTON "Aceptar", IDOK, 81, 179, 50, 14 @@ -1007,6 +1008,12 @@ BEGIN IDS_OBJECTS "%d elementos" IDS_OBJECTS_SELECTED "%d elementos seleccionados" + IDS_SEARCH_BROWSEITEM "Examinar..." + + IDS_RECYCLE_CLEANER_DISPLAYNAME "Recycle Bin" + IDS_RECYCLE_CLEANER_DESCRIPTION "The Recycle Bin contains files you have deleted from your computer. These files are not permanently removed until you empty the Recycle Bin." + IDS_RECYCLE_CLEANER_BUTTON_TEXT "&View Files" + IDS_TITLE_MYCOMP "Mi equipo" IDS_TITLE_MYNET "Mis sitios de red" IDS_TITLE_BIN_1 "Papelera (llena)" diff --git a/dll/win32/shell32/lang/et-EE.rc b/dll/win32/shell32/lang/et-EE.rc index 67324abb2da98..12983b93194f7 100644 --- a/dll/win32/shell32/lang/et-EE.rc +++ b/dll/win32/shell32/lang/et-EE.rc @@ -611,17 +611,18 @@ BEGIN DEFPUSHBUTTON "&Alusta", IDOK, 53, 198, 60, 14 PUSHBUTTON "S&ule", IDCANCEL, 118, 198, 60, 14 LTEXT "&Maht:", -1, 7, 6, 169, 9 - COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&Failisüsteem", -1, 7, 35, 170, 9 - COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8 LTEXT "&Jaotusühiku maht", -1, 7, 64, 170, 9 - COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Draivi &silt", -1, 7, 93, 170, 9 EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL GROUPBOX "&Vormindussuvandid", 4610, 7, 121, 170, 49 AUTOCHECKBOX "Kii&rvorminuds", 28674, 16, 135, 155, 10 AUTOCHECKBOX "L&uba tihendamine", 28675, 16, 152, 155, 10 + CONTROL "", 30000, "STATIC", SS_ICON | WS_TABSTOP | SS_CENTERIMAGE | SS_NOTIFY, 7, 198, 15, 14 END IDD_CHECK_DISK DIALOGEX 50, 50, 194, 115 @@ -644,8 +645,8 @@ CAPTION "Muuda ikooni" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Otsi ikoone sellest failist:", -1, 7, 7, 179, 10 - PUSHBUTTON "Sirvi...", IDC_BUTTON_PATH, 135, 17, 50, 14 EDITTEXT IDC_EDIT_PATH, 7, 17, 123, 14, ES_AUTOHSCROLL + PUSHBUTTON "Sirvi...", IDC_BUTTON_PATH, 135, 17, 50, 14 LTEXT "Vali ikoon alltoodud loendist:", -1, 7, 36, 179, 10 LISTBOX IDC_PICKICON_LIST, 7, 47, 181, 122, LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | LBS_DISABLENOSCROLL | WS_HSCROLL | WS_TABSTOP DEFPUSHBUTTON "OK", IDOK, 81, 179, 50, 14 @@ -1005,6 +1006,12 @@ BEGIN IDS_OBJECTS "%d objekti" IDS_OBJECTS_SELECTED "%d objekti valitud" + IDS_SEARCH_BROWSEITEM "Sirvi..." + + IDS_RECYCLE_CLEANER_DISPLAYNAME "Recycle Bin" + IDS_RECYCLE_CLEANER_DESCRIPTION "The Recycle Bin contains files you have deleted from your computer. These files are not permanently removed until you empty the Recycle Bin." + IDS_RECYCLE_CLEANER_BUTTON_TEXT "&View Files" + IDS_TITLE_MYCOMP "Minu arvuti" IDS_TITLE_MYNET "Minu võrgukohad" IDS_TITLE_BIN_1 "Prügikast (täis)" diff --git a/dll/win32/shell32/lang/eu-ES.rc b/dll/win32/shell32/lang/eu-ES.rc index 0eb4c03261c53..faafc9e732330 100644 --- a/dll/win32/shell32/lang/eu-ES.rc +++ b/dll/win32/shell32/lang/eu-ES.rc @@ -611,17 +611,18 @@ BEGIN DEFPUSHBUTTON "&Hasi", IDOK, 53, 198, 60, 14 PUSHBUTTON "&Itxi", IDCANCEL, 118, 198, 60, 14 LTEXT "&Edukiera:", -1, 7, 6, 169, 9 - COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&Fitxategi-sistema", -1, 7, 35, 170, 9 - COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8 LTEXT "E&sleipen-unitatearen tamaina", -1, 7, 64, 170, 9 - COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&Bolumenaren etiketa", -1, 7, 93, 170, 9 EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL GROUPBOX "F&ormatuaren aukerak", 4610, 7, 121, 170, 49 AUTOCHECKBOX "Bi&zkor formateatu", 28674, 16, 135, 155, 10 AUTOCHECKBOX "&Gaitu konpresioa", 28675, 16, 152, 155, 10 + CONTROL "", 30000, "STATIC", SS_ICON | WS_TABSTOP | SS_CENTERIMAGE | SS_NOTIFY, 7, 198, 15, 14 END IDD_CHECK_DISK DIALOGEX 50, 50, 240, 120 @@ -644,8 +645,8 @@ CAPTION "Aldatu ikonoa" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Bilatu ikonoak fitxategi honetan:", -1, 7, 7, 179, 10 - PUSHBUTTON "&Arakatu...", IDC_BUTTON_PATH, 135, 17, 50, 14 EDITTEXT IDC_EDIT_PATH, 7, 17, 123, 14, ES_AUTOHSCROLL + PUSHBUTTON "&Arakatu...", IDC_BUTTON_PATH, 135, 17, 50, 14 LTEXT "&Hautatu ikono bat beheko zerrendan:", -1, 7, 36, 179, 10 LISTBOX IDC_PICKICON_LIST, 7, 47, 181, 122, LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | LBS_DISABLENOSCROLL | WS_HSCROLL | WS_TABSTOP DEFPUSHBUTTON "Ados", IDOK, 81, 179, 50, 14 @@ -1003,6 +1004,12 @@ BEGIN IDS_OBJECTS "%d elementuak" IDS_OBJECTS_SELECTED "%d elementu hautatuak" + IDS_SEARCH_BROWSEITEM "Arakatu..." + + IDS_RECYCLE_CLEANER_DISPLAYNAME "Recycle Bin" + IDS_RECYCLE_CLEANER_DESCRIPTION "The Recycle Bin contains files you have deleted from your computer. These files are not permanently removed until you empty the Recycle Bin." + IDS_RECYCLE_CLEANER_BUTTON_TEXT "&View Files" + IDS_TITLE_MYCOMP "Ordenagailua" IDS_TITLE_MYNET "Nire sarelekuak" IDS_TITLE_BIN_1 "Zakarrontzia (betea)" diff --git a/dll/win32/shell32/lang/fi-FI.rc b/dll/win32/shell32/lang/fi-FI.rc index 6243ce5615350..327dccdb80e81 100644 --- a/dll/win32/shell32/lang/fi-FI.rc +++ b/dll/win32/shell32/lang/fi-FI.rc @@ -216,7 +216,7 @@ BEGIN LTEXT "Choose the advanced properties you want for this shortcut.", -1, 5, 30, 210, 10 CHECKBOX "Run with different credentials", IDC_SHORTEX_RUN_DIFFERENT, 25, 50, 150, 10 LTEXT "This option can allow you to run the this shortcut as another user, or continue as yourself while protecting your computer and data from unauthorized program activity.", -1, 50, 60, 175, 40 - CHECKBOX "Run in seperate memory space", IDC_SHORTEX_RUN_SEPARATE, 25, 100, 150, 10, WS_DISABLED + CHECKBOX "Run in separate memory space", IDC_SHORTEX_RUN_SEPARATE, 25, 100, 150, 10, WS_DISABLED PUSHBUTTON "OK", IDOK, 63, 124, 50, 15, WS_VISIBLE PUSHBUTTON "Abort", IDCANCEL, 120, 124, 50, 15, WS_VISIBLE END @@ -604,17 +604,18 @@ BEGIN DEFPUSHBUTTON "&Start", IDOK, 53, 198, 60, 14 PUSHBUTTON "&Close", IDCANCEL, 118, 198, 60, 14 LTEXT "Ca&pacity:", -1, 7, 6, 169, 9 - COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&File system", -1, 7, 35, 170, 9 - COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8 LTEXT "&Allocation unit size", -1, 7, 64, 170, 9 - COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Volume &label", -1, 7, 93, 170, 9 EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL GROUPBOX "Format &options", 4610, 7, 121, 170, 49 AUTOCHECKBOX "&Quick Format", 28674, 16, 135, 155, 10 AUTOCHECKBOX "&Enable Compression", 28675, 16, 152, 155, 10 + CONTROL "", 30000, "STATIC", SS_ICON | WS_TABSTOP | SS_CENTERIMAGE | SS_NOTIFY, 7, 198, 15, 14 END IDD_CHECK_DISK DIALOGEX 50, 50, 194, 115 @@ -637,8 +638,8 @@ CAPTION "Change Icon" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Look for icons in this file:", -1, 7, 7, 179, 10 - PUSHBUTTON "Browse...", IDC_BUTTON_PATH, 135, 17, 50, 14 EDITTEXT IDC_EDIT_PATH, 7, 17, 123, 14, ES_AUTOHSCROLL + PUSHBUTTON "Browse...", IDC_BUTTON_PATH, 135, 17, 50, 14 LTEXT "Select an icon from the list below:", -1, 7, 36, 179, 10 LISTBOX IDC_PICKICON_LIST, 7, 47, 181, 122, LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | LBS_DISABLENOSCROLL | WS_HSCROLL | WS_TABSTOP DEFPUSHBUTTON "OK", IDOK, 81, 179, 50, 14 @@ -998,6 +999,12 @@ BEGIN IDS_OBJECTS "%d Objects" IDS_OBJECTS_SELECTED "%d Objects Selected" + IDS_SEARCH_BROWSEITEM "Selaa..." + + IDS_RECYCLE_CLEANER_DISPLAYNAME "Recycle Bin" + IDS_RECYCLE_CLEANER_DESCRIPTION "The Recycle Bin contains files you have deleted from your computer. These files are not permanently removed until you empty the Recycle Bin." + IDS_RECYCLE_CLEANER_BUTTON_TEXT "&View Files" + IDS_TITLE_MYCOMP "Oma Tietokone" IDS_TITLE_MYNET "My Network Places" IDS_TITLE_BIN_1 "Recycle Bin (full)" diff --git a/dll/win32/shell32/lang/fr-FR.rc b/dll/win32/shell32/lang/fr-FR.rc index 0bb74655ef331..c7e91097ee82c 100644 --- a/dll/win32/shell32/lang/fr-FR.rc +++ b/dll/win32/shell32/lang/fr-FR.rc @@ -604,17 +604,18 @@ BEGIN DEFPUSHBUTTON "Démarrer", IDOK, 53, 198, 60, 14 PUSHBUTTON "Fermer", IDCANCEL, 118, 198, 60, 14 LTEXT "Ca&pacité :", -1, 7, 6, 169, 9 - COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Système de fichiers", -1, 7, 35, 170, 9 - COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8 LTEXT "Taille d'unité d'&allocation", -1, 7, 64, 170, 9 - COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Nom du volume", -1, 7, 93, 170, 9 EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL GROUPBOX "&Options de formatage", 4610, 7, 121, 170, 49 AUTOCHECKBOX "Formatage rapide", 28674, 16, 135, 155, 10 AUTOCHECKBOX "Activer la compression", 28675, 16, 152, 155, 10 + CONTROL "", 30000, "STATIC", SS_ICON | WS_TABSTOP | SS_CENTERIMAGE | SS_NOTIFY, 7, 198, 15, 14 END IDD_CHECK_DISK DIALOGEX 50, 50, 244, 115 @@ -637,8 +638,8 @@ CAPTION "Changer l'icône" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Rechercher une icône pour ce fichier :", -1, 7, 7, 179, 10 - PUSHBUTTON "Parcourir...", IDC_BUTTON_PATH, 135, 17, 50, 14 EDITTEXT IDC_EDIT_PATH, 7, 17, 123, 14, ES_AUTOHSCROLL + PUSHBUTTON "Parcourir...", IDC_BUTTON_PATH, 135, 17, 50, 14 LTEXT "Sélectionnez une icône dans la liste ci-dessous :", -1, 7, 36, 179, 10 LISTBOX IDC_PICKICON_LIST, 7, 47, 181, 122, LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | LBS_DISABLENOSCROLL | WS_HSCROLL | WS_TABSTOP DEFPUSHBUTTON "OK", IDOK, 81, 179, 50, 14 @@ -915,7 +916,7 @@ BEGIN IDS_SHELL_ABOUT_AUTHORS "&Auteurs" IDS_SHELL_ABOUT_BACK "< Précédent" - FCIDM_SHVIEW_NEW "Ne&w" /* A menu item with an ampersand */ + FCIDM_SHVIEW_NEW "&Nouveau" FCIDM_SHVIEW_NEWFOLDER "Nouveau d&ossier" FCIDM_SHVIEW_NEWLINK "Nouveau &lien" IDS_FOLDER_OPTIONS "Options du dossier" @@ -998,6 +999,12 @@ BEGIN IDS_OBJECTS "%d objet(s)" IDS_OBJECTS_SELECTED "%d objet(s) sélectionné(s)" + IDS_SEARCH_BROWSEITEM "Parcourir..." + + IDS_RECYCLE_CLEANER_DISPLAYNAME "Recycle Bin" + IDS_RECYCLE_CLEANER_DESCRIPTION "The Recycle Bin contains files you have deleted from your computer. These files are not permanently removed until you empty the Recycle Bin." + IDS_RECYCLE_CLEANER_BUTTON_TEXT "&View Files" + IDS_TITLE_MYCOMP "Poste de travail" IDS_TITLE_MYNET "Mon réseau" IDS_TITLE_BIN_1 "Corbeille (pleine)" diff --git a/dll/win32/shell32/lang/he-IL.rc b/dll/win32/shell32/lang/he-IL.rc index 5f3bd630847dc..bbf80e9447bce 100644 --- a/dll/win32/shell32/lang/he-IL.rc +++ b/dll/win32/shell32/lang/he-IL.rc @@ -611,17 +611,18 @@ BEGIN DEFPUSHBUTTON "&התחלה", IDOK, 53, 198, 60, 14 PUSHBUTTON "&סגירה", IDCANCEL, 118, 198, 60, 14 LTEXT "&קיבולת:", -1, 7, 6, 169, 9 - COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&מערכת קבצים", -1, 7, 35, 170, 9 - COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8 LTEXT "&גודל יחידת הקצאה", -1, 7, 64, 170, 9 - COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&תווית כונן", -1, 7, 93, 170, 9 EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL GROUPBOX "אפשרויות אתחול", 4610, 7, 121, 170, 49 AUTOCHECKBOX "&אתחול מהיר", 28674, 16, 135, 155, 10 AUTOCHECKBOX "אפשר דחיסת קבצים", 28675, 16, 152, 155, 10 + CONTROL "", 30000, "STATIC", SS_ICON | WS_TABSTOP | SS_CENTERIMAGE | SS_NOTIFY, 7, 198, 15, 14 END IDD_CHECK_DISK DIALOGEX 50, 50, 194, 115 @@ -644,8 +645,8 @@ CAPTION "שינוי סמל" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Look for icons in this file:", -1, 7, 7, 179, 10 - PUSHBUTTON "עיון...", IDC_BUTTON_PATH, 135, 17, 50, 14 EDITTEXT IDC_EDIT_PATH, 7, 17, 123, 14, ES_AUTOHSCROLL + PUSHBUTTON "עיון...", IDC_BUTTON_PATH, 135, 17, 50, 14 LTEXT "Select an icon from the list below:", -1, 7, 36, 179, 10 LISTBOX IDC_PICKICON_LIST, 7, 47, 181, 122, LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | LBS_DISABLENOSCROLL | WS_HSCROLL | WS_TABSTOP DEFPUSHBUTTON "אישור", IDOK, 81, 179, 50, 14 @@ -1005,6 +1006,13 @@ BEGIN IDS_OBJECTS "%d פריטים" IDS_OBJECTS_SELECTED "%d פריטים נבחרו" + IDS_SEARCH_BROWSEITEM "עיון..." + + + IDS_RECYCLE_CLEANER_DISPLAYNAME "Recycle Bin" + IDS_RECYCLE_CLEANER_DESCRIPTION "The Recycle Bin contains files you have deleted from your computer. These files are not permanently removed until you empty the Recycle Bin." + IDS_RECYCLE_CLEANER_BUTTON_TEXT "&View Files" + IDS_TITLE_MYCOMP "המחשב שלי" IDS_TITLE_MYNET "מיקומי הרשת שלי" IDS_TITLE_BIN_1 "Recycle Bin (full)" diff --git a/dll/win32/shell32/lang/hi-IN.rc b/dll/win32/shell32/lang/hi-IN.rc index 8a6ed3d42b3b1..49bc606745ad0 100644 --- a/dll/win32/shell32/lang/hi-IN.rc +++ b/dll/win32/shell32/lang/hi-IN.rc @@ -611,17 +611,18 @@ BEGIN DEFPUSHBUTTON "&शुरु करें", IDOK, 53, 198, 60, 14 PUSHBUTTON "&बंद करे", IDCANCEL, 118, 198, 60, 14 LTEXT "&कपेसिटी:", -1, 7, 6, 169, 9 - COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&फाइल सिस्टम", -1, 7, 35, 170, 9 - COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8 LTEXT "&आवंटन यूनिट साइज़", -1, 7, 64, 170, 9 - COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "वोल्यूम &लेबल", -1, 7, 93, 170, 9 EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL GROUPBOX "फार्मेट &विकल्प", 4610, 7, 121, 170, 49 AUTOCHECKBOX "&त्वरित फार्मेट", 28674, 16, 135, 155, 10 AUTOCHECKBOX "कम्प्रेशन &सक्षम करें", 28675, 16, 152, 155, 10 + CONTROL "", 30000, "STATIC", SS_ICON | WS_TABSTOP | SS_CENTERIMAGE | SS_NOTIFY, 7, 198, 15, 14 END IDD_CHECK_DISK DIALOGEX 50, 50, 194, 115 @@ -644,8 +645,8 @@ CAPTION "आइकॉन बदलें" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "इस फ़ाइल में आइकन देखें:", -1, 7, 7, 179, 10 - PUSHBUTTON "ब्राउज...", IDC_BUTTON_PATH, 135, 17, 50, 14 EDITTEXT IDC_EDIT_PATH, 7, 17, 123, 14, ES_AUTOHSCROLL + PUSHBUTTON "ब्राउज...", IDC_BUTTON_PATH, 135, 17, 50, 14 LTEXT "नीचे दी गई सूची में से एक आइकन चुनें:", -1, 7, 36, 179, 10 LISTBOX IDC_PICKICON_LIST, 7, 47, 181, 122, LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | LBS_DISABLENOSCROLL | WS_HSCROLL | WS_TABSTOP DEFPUSHBUTTON "ठीक", IDOK, 81, 179, 50, 14 @@ -1000,6 +1001,12 @@ BEGIN IDS_OBJECTS "%d वस्तुओं" IDS_OBJECTS_SELECTED "%d वस्तुओं का चयन किया" + IDS_SEARCH_BROWSEITEM "ब्राउज़ करें..." + + IDS_RECYCLE_CLEANER_DISPLAYNAME "Recycle Bin" + IDS_RECYCLE_CLEANER_DESCRIPTION "The Recycle Bin contains files you have deleted from your computer. These files are not permanently removed until you empty the Recycle Bin." + IDS_RECYCLE_CLEANER_BUTTON_TEXT "&View Files" + IDS_TITLE_MYCOMP "मेरा कंप्यूटर" IDS_TITLE_MYNET "मेरे नेटवर्क स्थान" IDS_TITLE_BIN_1 "Recycle Bin (full)" diff --git a/dll/win32/shell32/lang/hu-HU.rc b/dll/win32/shell32/lang/hu-HU.rc index dca369f41aa30..45ab97696b940 100644 --- a/dll/win32/shell32/lang/hu-HU.rc +++ b/dll/win32/shell32/lang/hu-HU.rc @@ -604,17 +604,18 @@ BEGIN DEFPUSHBUTTON "&Indítás", IDOK, 53, 198, 60, 14 PUSHBUTTON "&Bezárás", IDCANCEL, 118, 198, 60, 14 LTEXT "&Kapacitás:", -1, 7, 6, 169, 9 - COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&Fájlrendszer", -1, 7, 35, 170, 9 - COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8 LTEXT "Foglalási &egység mérete", -1, 7, 64, 170, 9 - COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Kötet&címke", -1, 7, 93, 170, 9 EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL GROUPBOX "Formázási &beállítások", 4610, 7, 121, 170, 49 AUTOCHECKBOX "&Gyorsformázás", 28674, 16, 135, 155, 10 AUTOCHECKBOX "&Tömörítés engedélyezése", 28675, 16, 152, 155, 10 + CONTROL "", 30000, "STATIC", SS_ICON | WS_TABSTOP | SS_CENTERIMAGE | SS_NOTIFY, 7, 198, 15, 14 END IDD_CHECK_DISK DIALOGEX 50, 50, 194, 115 @@ -637,8 +638,8 @@ CAPTION "Ikoncsere" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Ikonok keresése ebben a fájlban:", -1, 7, 7, 179, 10 - PUSHBUTTON "Tallózás...", IDC_BUTTON_PATH, 135, 17, 50, 14 EDITTEXT IDC_EDIT_PATH, 7, 17, 123, 14, ES_AUTOHSCROLL + PUSHBUTTON "Tallózás...", IDC_BUTTON_PATH, 135, 17, 50, 14 LTEXT "Válasszon egy ikont a listából:", -1, 7, 36, 179, 10 LISTBOX IDC_PICKICON_LIST, 7, 47, 181, 122, LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | LBS_DISABLENOSCROLL | WS_HSCROLL | WS_TABSTOP DEFPUSHBUTTON "OK", IDOK, 81, 179, 50, 14 @@ -997,6 +998,12 @@ BEGIN IDS_OBJECTS "%d elem" IDS_OBJECTS_SELECTED "%d kijelölt elem" + IDS_SEARCH_BROWSEITEM "Böngészés..." + + IDS_RECYCLE_CLEANER_DISPLAYNAME "Recycle Bin" + IDS_RECYCLE_CLEANER_DESCRIPTION "The Recycle Bin contains files you have deleted from your computer. These files are not permanently removed until you empty the Recycle Bin." + IDS_RECYCLE_CLEANER_BUTTON_TEXT "&View Files" + IDS_TITLE_MYCOMP "Számítógép" IDS_TITLE_MYNET "Hálózati helyek" IDS_TITLE_BIN_1 "Lomtár (tele)" diff --git a/dll/win32/shell32/lang/id-ID.rc b/dll/win32/shell32/lang/id-ID.rc index 14851b34ba031..5173e7f0158be 100644 --- a/dll/win32/shell32/lang/id-ID.rc +++ b/dll/win32/shell32/lang/id-ID.rc @@ -604,17 +604,18 @@ BEGIN DEFPUSHBUTTON "&Mulai", IDOK, 53, 198, 60, 14 PUSHBUTTON "&Tutup", IDCANCEL, 118, 198, 60, 14 LTEXT "Ka&pasitas:", -1, 7, 6, 169, 9 - COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&Berkas sistem", -1, 7, 35, 170, 9 - COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8 LTEXT "&Ukuran unit alokasi", -1, 7, 64, 170, 9 - COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&Label volume", -1, 7, 93, 170, 9 EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL GROUPBOX "&Opsi format", 4610, 7, 121, 170, 49 AUTOCHECKBOX "Format &Cepat", 28674, 16, 135, 155, 10 AUTOCHECKBOX "&Hidupkan kompresi", 28675, 16, 152, 155, 10 + CONTROL "", 30000, "STATIC", SS_ICON | WS_TABSTOP | SS_CENTERIMAGE | SS_NOTIFY, 7, 198, 15, 14 END IDD_CHECK_DISK DIALOGEX 50, 50, 194, 115 @@ -637,8 +638,8 @@ CAPTION "Ganti Ikon" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Cari ikon di berkas ini:", -1, 7, 7, 179, 10 - PUSHBUTTON "Jelajah...", IDC_BUTTON_PATH, 135, 17, 50, 14 EDITTEXT IDC_EDIT_PATH, 7, 17, 123, 14, ES_AUTOHSCROLL + PUSHBUTTON "Jelajah...", IDC_BUTTON_PATH, 135, 17, 50, 14 LTEXT "Pilih ikon dari daftar di bawah ini:", -1, 7, 36, 179, 10 LISTBOX IDC_PICKICON_LIST, 7, 47, 181, 122, LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | LBS_DISABLENOSCROLL | WS_HSCROLL | WS_TABSTOP DEFPUSHBUTTON "OK", IDOK, 81, 179, 50, 14 @@ -995,6 +996,12 @@ BEGIN IDS_OBJECTS "%d Obyek" IDS_OBJECTS_SELECTED "%d Obyek terpilih" + IDS_SEARCH_BROWSEITEM "Jelajah..." + + IDS_RECYCLE_CLEANER_DISPLAYNAME "Recycle Bin" + IDS_RECYCLE_CLEANER_DESCRIPTION "The Recycle Bin contains files you have deleted from your computer. These files are not permanently removed until you empty the Recycle Bin." + IDS_RECYCLE_CLEANER_BUTTON_TEXT "&View Files" + IDS_TITLE_MYCOMP "Komputer Saya" IDS_TITLE_MYNET "Tempat Jaringan Saya" IDS_TITLE_BIN_1 "Tampungan Daur Ulang (penuh)" diff --git a/dll/win32/shell32/lang/it-IT.rc b/dll/win32/shell32/lang/it-IT.rc index 2f06fb396383e..0b47c540fdb2e 100644 --- a/dll/win32/shell32/lang/it-IT.rc +++ b/dll/win32/shell32/lang/it-IT.rc @@ -604,17 +604,18 @@ BEGIN DEFPUSHBUTTON "&Inizia", IDOK, 53, 198, 60, 14 PUSHBUTTON "&Chiudi", IDCANCEL, 118, 198, 60, 14 LTEXT "Ca&pacità:", -1, 7, 6, 169, 9 - COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&File system", -1, 7, 35, 170, 9 - COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8 LTEXT "Dimensione dell'unità di &allocazione", -1, 7, 64, 170, 9 - COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&Etichetta del Volume", -1, 7, 93, 170, 9 EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL GROUPBOX "Opzioni di &formattazione", 4610, 7, 121, 170, 49 AUTOCHECKBOX "Formattazione &rapida", 28674, 16, 135, 155, 10 AUTOCHECKBOX "Abilita la &compressione", 28675, 16, 152, 155, 10 + CONTROL "", 30000, "STATIC", SS_ICON | WS_TABSTOP | SS_CENTERIMAGE | SS_NOTIFY, 7, 198, 15, 14 END IDD_CHECK_DISK DIALOGEX 50, 50, 194, 115 @@ -637,8 +638,8 @@ CAPTION "Cambia icona" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Look for icons in this file:", -1, 7, 7, 179, 10 - PUSHBUTTON "Sfoglia...", IDC_BUTTON_PATH, 135, 17, 50, 14 EDITTEXT IDC_EDIT_PATH, 7, 17, 123, 14, ES_AUTOHSCROLL + PUSHBUTTON "Sfoglia...", IDC_BUTTON_PATH, 135, 17, 50, 14 LTEXT "Select an icon from the list below:", -1, 7, 36, 179, 10 LISTBOX IDC_PICKICON_LIST, 7, 47, 181, 122, LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | LBS_DISABLENOSCROLL | WS_HSCROLL | WS_TABSTOP DEFPUSHBUTTON "OK", IDOK, 81, 179, 50, 14 @@ -998,6 +999,12 @@ BEGIN IDS_OBJECTS "%d Oggetti" IDS_OBJECTS_SELECTED "%d Oggetti selezionati" + IDS_SEARCH_BROWSEITEM "Esplora..." + + IDS_RECYCLE_CLEANER_DISPLAYNAME "Recycle Bin" + IDS_RECYCLE_CLEANER_DESCRIPTION "The Recycle Bin contains files you have deleted from your computer. These files are not permanently removed until you empty the Recycle Bin." + IDS_RECYCLE_CLEANER_BUTTON_TEXT "&View Files" + IDS_TITLE_MYCOMP "Risorse del Computer" IDS_TITLE_MYNET "Risorse di rete" IDS_TITLE_BIN_1 "Cestino (pieno)" diff --git a/dll/win32/shell32/lang/ja-JP.rc b/dll/win32/shell32/lang/ja-JP.rc index b400227271500..669ae2cc43684 100644 --- a/dll/win32/shell32/lang/ja-JP.rc +++ b/dll/win32/shell32/lang/ja-JP.rc @@ -604,17 +604,18 @@ BEGIN DEFPUSHBUTTON "開始(&S)", IDOK, 53, 198, 60, 14 PUSHBUTTON "閉じる(&C)", IDCANCEL, 118, 198, 60, 14 LTEXT "容量(&P):", -1, 7, 6, 169, 9 - COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "ファイルシステム(&F)", -1, 7, 35, 170, 9 - COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8 LTEXT "アロケーションユニットサイズ(&A)", -1, 7, 64, 170, 9 - COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "ボリュームラベル(&L)", -1, 7, 93, 170, 9 EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL GROUPBOX "フォーマット オプション(&O)", 4610, 7, 121, 170, 49 AUTOCHECKBOX "クイック フォーマット(&Q)", 28674, 16, 135, 155, 10 AUTOCHECKBOX "圧縮を有効にする(&E)", 28675, 16, 152, 155, 10 + CONTROL "", 30000, "STATIC", SS_ICON | WS_TABSTOP | SS_CENTERIMAGE | SS_NOTIFY, 7, 198, 15, 14 END IDD_CHECK_DISK DIALOGEX 50, 50, 194, 115 @@ -637,8 +638,8 @@ CAPTION "アイコンの変更" FONT 9, "MS UI Gothic", 400, 0, 0x1 BEGIN LTEXT "次のファイルのアイコンを見る:", -1, 7, 7, 185, 10 - PUSHBUTTON "参照...", IDC_BUTTON_PATH, 135, 17, 50, 14 EDITTEXT IDC_EDIT_PATH, 7, 17, 123, 14, ES_AUTOHSCROLL + PUSHBUTTON "参照...", IDC_BUTTON_PATH, 135, 17, 50, 14 LTEXT "以下のリストからアイコンを選択:", -1, 7, 36, 185, 10 LISTBOX IDC_PICKICON_LIST, 7, 47, 181, 122, LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | LBS_DISABLENOSCROLL | WS_HSCROLL | WS_TABSTOP DEFPUSHBUTTON "OK", IDOK, 81, 179, 50, 14 @@ -995,6 +996,12 @@ BEGIN IDS_OBJECTS "%d 個のオブジェクト" IDS_OBJECTS_SELECTED "%d 個のオブジェクトが選択済み" + IDS_SEARCH_BROWSEITEM "参照..." + + IDS_RECYCLE_CLEANER_DISPLAYNAME "Recycle Bin" + IDS_RECYCLE_CLEANER_DESCRIPTION "The Recycle Bin contains files you have deleted from your computer. These files are not permanently removed until you empty the Recycle Bin." + IDS_RECYCLE_CLEANER_BUTTON_TEXT "&View Files" + IDS_TITLE_MYCOMP "マイ コンピュータ" IDS_TITLE_MYNET "マイ ネットワーク" IDS_TITLE_BIN_1 "ごみ箱 (いっぱい)" diff --git a/dll/win32/shell32/lang/ko-KR.rc b/dll/win32/shell32/lang/ko-KR.rc index 2e4478491baa2..d534ab6f98ba8 100644 --- a/dll/win32/shell32/lang/ko-KR.rc +++ b/dll/win32/shell32/lang/ko-KR.rc @@ -223,7 +223,7 @@ BEGIN LTEXT "Choose the advanced properties you want for this shortcut.", -1, 5, 30, 210, 10 CHECKBOX "Run with different credentials", IDC_SHORTEX_RUN_DIFFERENT, 25, 50, 150, 10 LTEXT "This option can allow you to run the this shortcut as another user, or continue as yourself while protecting your computer and data from unauthorized program activity.", -1, 50, 60, 175, 40 - CHECKBOX "Run in seperate memory space", IDC_SHORTEX_RUN_SEPARATE, 25, 100, 150, 10, WS_DISABLED + CHECKBOX "Run in separate memory space", IDC_SHORTEX_RUN_SEPARATE, 25, 100, 150, 10, WS_DISABLED PUSHBUTTON "확인", IDOK, 63, 124, 50, 15, WS_VISIBLE PUSHBUTTON "중단", IDCANCEL, 120, 124, 50, 15, WS_VISIBLE END @@ -611,17 +611,18 @@ BEGIN DEFPUSHBUTTON "&Start", IDOK, 53, 198, 60, 14 PUSHBUTTON "&Close", IDCANCEL, 118, 198, 60, 14 LTEXT "Ca&pacity:", -1, 7, 6, 169, 9 - COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&File system", -1, 7, 35, 170, 9 - COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8 LTEXT "&Allocation unit size", -1, 7, 64, 170, 9 - COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Volume &label", -1, 7, 93, 170, 9 EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL GROUPBOX "Format &options", 4610, 7, 121, 170, 49 AUTOCHECKBOX "&Quick Format", 28674, 16, 135, 155, 10 AUTOCHECKBOX "&Enable Compression", 28675, 16, 152, 155, 10 + CONTROL "", 30000, "STATIC", SS_ICON | WS_TABSTOP | SS_CENTERIMAGE | SS_NOTIFY, 7, 198, 15, 14 END IDD_CHECK_DISK DIALOGEX 50, 50, 194, 115 @@ -644,8 +645,8 @@ CAPTION "아이콘 변경" FONT 9, "굴림", 400, 0, 0x1 BEGIN LTEXT "파일에서 아이콘 찾기(&L):", -1, 7, 7, 179, 10 - PUSHBUTTON "찾아보기(&B)...", IDC_BUTTON_PATH, 135, 17, 50, 14 EDITTEXT IDC_EDIT_PATH, 7, 17, 123, 14, ES_AUTOHSCROLL + PUSHBUTTON "찾아보기(&B)...", IDC_BUTTON_PATH, 135, 17, 50, 14 LTEXT "아래 목록에서 아이콘 선택:", -1, 7, 36, 179, 10 LISTBOX IDC_PICKICON_LIST, 7, 47, 181, 122, LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | LBS_DISABLENOSCROLL | WS_HSCROLL | WS_TABSTOP DEFPUSHBUTTON "확인", IDOK, 81, 179, 50, 14 @@ -1005,6 +1006,12 @@ BEGIN IDS_OBJECTS "%d Objects" IDS_OBJECTS_SELECTED "%d Objects Selected" + IDS_SEARCH_BROWSEITEM "찾아보기..." + + IDS_RECYCLE_CLEANER_DISPLAYNAME "Recycle Bin" + IDS_RECYCLE_CLEANER_DESCRIPTION "The Recycle Bin contains files you have deleted from your computer. These files are not permanently removed until you empty the Recycle Bin." + IDS_RECYCLE_CLEANER_BUTTON_TEXT "&View Files" + IDS_TITLE_MYCOMP "내 컴퓨터" IDS_TITLE_MYNET "내 네트워크 환경" IDS_TITLE_BIN_1 "Recycle Bin (full)" diff --git a/dll/win32/shell32/lang/nl-NL.rc b/dll/win32/shell32/lang/nl-NL.rc index f3c20c78acc43..fa829d2033141 100644 --- a/dll/win32/shell32/lang/nl-NL.rc +++ b/dll/win32/shell32/lang/nl-NL.rc @@ -216,7 +216,7 @@ BEGIN LTEXT "Choose the advanced properties you want for this shortcut.", -1, 5, 30, 210, 10 CHECKBOX "Run with different credentials", IDC_SHORTEX_RUN_DIFFERENT, 25, 50, 150, 10 LTEXT "This option can allow you to run the this shortcut as another user, or continue as yourself while protecting your computer and data from unauthorized program activity.", -1, 50, 60, 175, 40 - CHECKBOX "Run in seperate memory space", IDC_SHORTEX_RUN_SEPARATE, 25, 100, 150, 10, WS_DISABLED + CHECKBOX "Run in separate memory space", IDC_SHORTEX_RUN_SEPARATE, 25, 100, 150, 10, WS_DISABLED PUSHBUTTON "OK", IDOK, 63, 124, 50, 15, WS_VISIBLE PUSHBUTTON "Abort", IDCANCEL, 120, 124, 50, 15, WS_VISIBLE END @@ -604,17 +604,18 @@ BEGIN DEFPUSHBUTTON "&Start", IDOK, 53, 198, 60, 14 PUSHBUTTON "&Close", IDCANCEL, 118, 198, 60, 14 LTEXT "Ca&pacity:", -1, 7, 6, 169, 9 - COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&File system", -1, 7, 35, 170, 9 - COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8 LTEXT "&Allocation unit size", -1, 7, 64, 170, 9 - COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Volume &label", -1, 7, 93, 170, 9 EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL GROUPBOX "Format &options", 4610, 7, 121, 170, 49 AUTOCHECKBOX "&Quick Format", 28674, 16, 135, 155, 10 AUTOCHECKBOX "&Enable Compression", 28675, 16, 152, 155, 10 + CONTROL "", 30000, "STATIC", SS_ICON | WS_TABSTOP | SS_CENTERIMAGE | SS_NOTIFY, 7, 198, 15, 14 END IDD_CHECK_DISK DIALOGEX 50, 50, 194, 115 @@ -637,8 +638,8 @@ CAPTION "Change Icon" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Look for icons in this file:", -1, 7, 7, 179, 10 - PUSHBUTTON "Browse...", IDC_BUTTON_PATH, 135, 17, 50, 14 EDITTEXT IDC_EDIT_PATH, 7, 17, 123, 14, ES_AUTOHSCROLL + PUSHBUTTON "Browse...", IDC_BUTTON_PATH, 135, 17, 50, 14 LTEXT "Select an icon from the list below:", -1, 7, 36, 179, 10 LISTBOX IDC_PICKICON_LIST, 7, 47, 181, 122, LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | LBS_DISABLENOSCROLL | WS_HSCROLL | WS_TABSTOP DEFPUSHBUTTON "OK", IDOK, 81, 179, 50, 14 @@ -998,6 +999,12 @@ BEGIN IDS_OBJECTS "%d Objects" IDS_OBJECTS_SELECTED "%d Objects Selected" + IDS_SEARCH_BROWSEITEM "Bladeren..." + + IDS_RECYCLE_CLEANER_DISPLAYNAME "Recycle Bin" + IDS_RECYCLE_CLEANER_DESCRIPTION "The Recycle Bin contains files you have deleted from your computer. These files are not permanently removed until you empty the Recycle Bin." + IDS_RECYCLE_CLEANER_BUTTON_TEXT "&View Files" + IDS_TITLE_MYCOMP "My Computer" IDS_TITLE_MYNET "My Network Places" IDS_TITLE_BIN_1 "Recycle Bin (full)" diff --git a/dll/win32/shell32/lang/no-NO.rc b/dll/win32/shell32/lang/no-NO.rc index c0f8bd18da81f..e345401bd334f 100644 --- a/dll/win32/shell32/lang/no-NO.rc +++ b/dll/win32/shell32/lang/no-NO.rc @@ -604,17 +604,18 @@ BEGIN DEFPUSHBUTTON "&Start", IDOK, 53, 198, 60, 14 PUSHBUTTON "&Lukk", IDCANCEL, 118, 198, 60, 14 LTEXT "Ka&pasitet:", -1, 7, 6, 169, 9 - COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&Filsystem", -1, 7, 35, 170, 9 - COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8 LTEXT "&Størrelse på tildelingsenheten", -1, 7, 64, 170, 9 - COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Volum&navn", -1, 7, 93, 170, 9 EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL GROUPBOX "Formatterings &valg", 4610, 7, 121, 170, 49 AUTOCHECKBOX "&Rask formattering", 28674, 16, 135, 155, 10 AUTOCHECKBOX "&Utfør komprimering", 28675, 16, 152, 155, 10 + CONTROL "", 30000, "STATIC", SS_ICON | WS_TABSTOP | SS_CENTERIMAGE | SS_NOTIFY, 7, 198, 15, 14 END IDD_CHECK_DISK DIALOGEX 50, 50, 194, 115 @@ -637,8 +638,8 @@ CAPTION "Endre ikon" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Look for icons in this file:", -1, 7, 7, 179, 10 - PUSHBUTTON "Utforsk...", IDC_BUTTON_PATH, 135, 17, 50, 14 EDITTEXT IDC_EDIT_PATH, 7, 17, 123, 14, ES_AUTOHSCROLL + PUSHBUTTON "Utforsk...", IDC_BUTTON_PATH, 135, 17, 50, 14 LTEXT "Select an icon from the list below:", -1, 7, 36, 179, 10 LISTBOX IDC_PICKICON_LIST, 7, 47, 181, 122, LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | LBS_DISABLENOSCROLL | WS_HSCROLL | WS_TABSTOP DEFPUSHBUTTON "OK", IDOK, 81, 179, 50, 14 @@ -998,6 +999,12 @@ BEGIN IDS_OBJECTS "%d Objects" IDS_OBJECTS_SELECTED "%d Objects Selected" + IDS_SEARCH_BROWSEITEM "Bla gjennom..." + + IDS_RECYCLE_CLEANER_DISPLAYNAME "Recycle Bin" + IDS_RECYCLE_CLEANER_DESCRIPTION "The Recycle Bin contains files you have deleted from your computer. These files are not permanently removed until you empty the Recycle Bin." + IDS_RECYCLE_CLEANER_BUTTON_TEXT "&View Files" + IDS_TITLE_MYCOMP "Min datamaskin" IDS_TITLE_MYNET "Mine nettverkssteder" IDS_TITLE_BIN_1 "Papirkurv (full)" diff --git a/dll/win32/shell32/lang/pl-PL.rc b/dll/win32/shell32/lang/pl-PL.rc index e495ffef72bbe..b8a2d20c29989 100644 --- a/dll/win32/shell32/lang/pl-PL.rc +++ b/dll/win32/shell32/lang/pl-PL.rc @@ -613,17 +613,18 @@ BEGIN DEFPUSHBUTTON "&Rozpocznij", IDOK, 53, 198, 60, 14 PUSHBUTTON "&Zamknij", IDCANCEL, 118, 198, 60, 14 LTEXT "&Pojemność:", -1, 7, 6, 169, 9 - COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&System plików", -1, 7, 35, 170, 9 - COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8 LTEXT "R&ozmiar jednostki alokacji", -1, 7, 64, 170, 9 - COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&Etykieta woluminu", -1, 7, 93, 170, 9 EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL GROUPBOX "&Opcje", 4610, 7, 121, 170, 49 AUTOCHECKBOX "Szy&bkie formatowanie", 28674, 16, 135, 155, 10 AUTOCHECKBOX "&Włącz kompresję", 28675, 16, 152, 155, 10 + CONTROL "", 30000, "STATIC", SS_ICON | WS_TABSTOP | SS_CENTERIMAGE | SS_NOTIFY, 7, 198, 15, 14 END IDD_CHECK_DISK DIALOGEX 50, 50, 197, 115 @@ -646,8 +647,8 @@ CAPTION "Zmienianie Ikony" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Szukaj ikon w pliku:", -1, 7, 7, 179, 10 - PUSHBUTTON "Przeglądaj...", IDC_BUTTON_PATH, 135, 17, 50, 14 EDITTEXT IDC_EDIT_PATH, 7, 17, 123, 14, ES_AUTOHSCROLL + PUSHBUTTON "Przeglądaj...", IDC_BUTTON_PATH, 135, 17, 50, 14 LTEXT "Wybierz ikonę z poniższej listy:", -1, 7, 36, 179, 10 LISTBOX IDC_PICKICON_LIST, 7, 47, 181, 122, LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | LBS_DISABLENOSCROLL | WS_HSCROLL | WS_TABSTOP DEFPUSHBUTTON "OK", IDOK, 81, 179, 50, 14 @@ -1007,6 +1008,12 @@ BEGIN IDS_OBJECTS "Elementów: %d" IDS_OBJECTS_SELECTED "Zaznaczonych elementów: %d" + IDS_SEARCH_BROWSEITEM "Przeglądaj..." + + IDS_RECYCLE_CLEANER_DISPLAYNAME "Recycle Bin" + IDS_RECYCLE_CLEANER_DESCRIPTION "The Recycle Bin contains files you have deleted from your computer. These files are not permanently removed until you empty the Recycle Bin." + IDS_RECYCLE_CLEANER_BUTTON_TEXT "&View Files" + IDS_TITLE_MYCOMP "Mój komputer" IDS_TITLE_MYNET "Moje miejsca sieciowe" IDS_TITLE_BIN_1 "Kosz (pełny)" diff --git a/dll/win32/shell32/lang/pt-BR.rc b/dll/win32/shell32/lang/pt-BR.rc index 16d1422681e63..1677d173efb12 100644 --- a/dll/win32/shell32/lang/pt-BR.rc +++ b/dll/win32/shell32/lang/pt-BR.rc @@ -604,17 +604,18 @@ BEGIN DEFPUSHBUTTON "&Iniciar", IDOK, 53, 198, 60, 14 PUSHBUTTON "&Fechar", IDCANCEL, 118, 198, 60, 14 LTEXT "Ca&pacidade:", -1, 7, 6, 169, 9 - COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&File system", -1, 7, 35, 170, 9 - COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8 LTEXT "&Allocation unit size", -1, 7, 64, 170, 9 - COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Volume &label", -1, 7, 93, 170, 9 EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL GROUPBOX "Format &options", 4610, 7, 121, 170, 49 AUTOCHECKBOX "Forma&tação Rápida", 28674, 16, 135, 155, 10 AUTOCHECKBOX "&Habilitar Compressão", 28675, 16, 152, 155, 10 + CONTROL "", 30000, "STATIC", SS_ICON | WS_TABSTOP | SS_CENTERIMAGE | SS_NOTIFY, 7, 198, 15, 14 END IDD_CHECK_DISK DIALOGEX 50, 50, 194, 115 @@ -637,8 +638,8 @@ CAPTION "Alterar Ícone" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Look for icons in this file:", -1, 7, 7, 179, 10 - PUSHBUTTON "Procurar...", IDC_BUTTON_PATH, 135, 17, 50, 14 EDITTEXT IDC_EDIT_PATH, 7, 17, 123, 14, ES_AUTOHSCROLL + PUSHBUTTON "Procurar...", IDC_BUTTON_PATH, 135, 17, 50, 14 LTEXT "Select an icon from the list below:", -1, 7, 36, 179, 10 LISTBOX IDC_PICKICON_LIST, 7, 47, 181, 122, LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | LBS_DISABLENOSCROLL | WS_HSCROLL | WS_TABSTOP DEFPUSHBUTTON "OK", IDOK, 81, 179, 50, 14 @@ -998,6 +999,12 @@ BEGIN IDS_OBJECTS "%d Objects" IDS_OBJECTS_SELECTED "%d Objects Selected" + IDS_SEARCH_BROWSEITEM "Procurar..." + + IDS_RECYCLE_CLEANER_DISPLAYNAME "Recycle Bin" + IDS_RECYCLE_CLEANER_DESCRIPTION "The Recycle Bin contains files you have deleted from your computer. These files are not permanently removed until you empty the Recycle Bin." + IDS_RECYCLE_CLEANER_BUTTON_TEXT "&View Files" + IDS_TITLE_MYCOMP "Meu Computador" IDS_TITLE_MYNET "Meus Locais de Rede" IDS_TITLE_BIN_1 "Lixeira (cheia)" diff --git a/dll/win32/shell32/lang/pt-PT.rc b/dll/win32/shell32/lang/pt-PT.rc index 2ca5756dc8ed2..400c9a6b09b8b 100644 --- a/dll/win32/shell32/lang/pt-PT.rc +++ b/dll/win32/shell32/lang/pt-PT.rc @@ -102,7 +102,7 @@ IDM_DVSELECT MENU BEGIN POPUP "" BEGIN - MENUITEM "Se&lect", 0 + MENUITEM "Se&leccionar", 0 END END @@ -213,7 +213,7 @@ BEGIN LTEXT "C&omentário:", IDC_SHORTCUT_COMMENT, 8, 154, 68, 10 EDITTEXT IDC_SHORTCUT_COMMENT_EDIT, 79, 152, 150, 14, ES_AUTOHSCROLL PUSHBUTTON "&Localizar destino...", IDC_SHORTCUT_FIND, 9, 172, 70, 14, ES_LEFT - PUSHBUTTON "Troc&ar ícone...", IDC_SHORTCUT_CHANGE_ICON, 84, 172, 70, 14, ES_LEFT + PUSHBUTTON "Alter&ar ícone...", IDC_SHORTCUT_CHANGE_ICON, 84, 172, 70, 14, ES_LEFT PUSHBUTTON "A&vançadas...", IDC_SHORTCUT_ADVANCED, 159, 172, 70, 14, ES_LEFT END @@ -256,7 +256,7 @@ BEGIN LTEXT "Atributos:", 14020, 8, 152, 46, 10 AUTOCHECKBOX "&Só de leitura", 14021, 58, 151, 68, 10 AUTOCHECKBOX "&Oculto", 14022, 126, 151, 55, 10 - AUTOCHECKBOX "&Arquivo", 14023, 181, 151, 59, 10 + AUTOCHECKBOX "A&rquivar", 14023, 181, 151, 59, 10 PUSHBUTTON "A&vançadas...", 14028, 158, 170, 70, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP END @@ -272,7 +272,7 @@ BEGIN CONTROL "Ficheiro", 14005, "edit", ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP, 58, 35, 170, 10 LTEXT "Abre com:", 14006, 8, 53, 50, 10 ICON "", 14025, 58, 52, 11, 10, NOT WS_VISIBLE - PUSHBUTTON "&Alterar...", 14024, 168, 50, 60, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP //FIXME: accelerator collision &A. This one is most likely wrong. + PUSHBUTTON "&Alterar...", 14024, 168, 50, 60, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP EDITTEXT 14007, 58, 53, 100, 10, ES_LEFT | ES_READONLY | NOT WS_BORDER | ES_AUTOHSCROLL | NOT WS_TABSTOP LTEXT "", -1, 8, 68, 221, 1, SS_ETCHEDHORZ | WS_CHILD | WS_VISIBLE LTEXT "Localização:", 14008, 8, 75, 45, 10 @@ -292,7 +292,7 @@ BEGIN LTEXT "Atributos:", 14020, 8, 189, 45, 10 AUTOCHECKBOX "&Só de leitura", 14021, 58, 188, 67, 10 AUTOCHECKBOX "&Oculto", 14022, 126, 188, 50, 10 - AUTOCHECKBOX "&Arquivo", 14023, 181, 188, 49, 10 //FIXME: accelerator collision &A. This one is most likely correct. + AUTOCHECKBOX "A&rquivar", 14023, 181, 188, 49, 10 PUSHBUTTON "A&vançadas...", 14028, 180, 185, 50, 15 END @@ -301,7 +301,7 @@ STYLE DS_SHELLFONT | WS_CHILD | WS_CAPTION CAPTION "Versão" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN - LTEXT "Versão do ficheiro:", 14000, 10, 10, 55, 10 //FIXME: text truncation, suggestion: using just "Versão:", maybe in companion with writing "Versão do ficheiro" into the caption, if you think it is not obvious enough already! (Take into consideration how the user reaches that dialog! it is obvious that this is about the files version! + LTEXT "Versão:", 14000, 10, 10, 55, 10 EDITTEXT 14001, 77, 10, 152, 10, ES_LEFT | ES_READONLY | NOT WS_BORDER LTEXT "Descrição:", 14002, 10, 27, 45, 10 EDITTEXT 14003, 77, 27, 152, 10, ES_LEFT | ES_READONLY | NOT WS_BORDER @@ -354,16 +354,16 @@ FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN GROUPBOX "Verificar por erros...", -1, 5, 5, 230, 60 ICON IDI_SHELL_TOOLS_CHKDSK, IDC_STATIC, 13, 25, 21, 20 - LTEXT "Esta opção vai verificar o volume por erros.", -1, 40, 25, 160, 20 + LTEXT "Esta opção irá verificar se existem erros no volume.", -1, 40, 25, 160, 20 PUSHBUTTON "Verificar agora...", 14000, 130, 45, 90, 15 GROUPBOX "Desfragmentação", -1, 5, 65, 230, 60 ICON IDI_SHELL_TOOLS_DEFRAG, IDC_STATIC, 13, 85, 21, 20 - LTEXT "Esta opção vai desfragmentar os ficheiros no volume.", -1, 40, 85, 160, 20 + LTEXT "Esta opção irá desfragmentar os ficheiros contidos no volume.", -1, 40, 85, 160, 20 PUSHBUTTON "Desfragmentar agora...", 14001, 130, 105, 90, 15 GROUPBOX "Cópia de segurança", -1, 5, 130, 230, 60 ICON IDI_SHELL_TOOLS_BACKUP, IDC_STATIC, 13, 150, 21, 20 - LTEXT "Esta opção vai verificar os ficheiros do volume.", -1, 40, 150, 160, 20 - PUSHBUTTON "Criar cópia de Segurança...", 14002, 130, 170, 90, 15 + LTEXT "Esta opção irá fazer uma cópia de segurança dos ficheiros contidos no volume.", -1, 40, 150, 160, 20 + PUSHBUTTON "Criar cópia de segurança...", 14002, 130, 170, 90, 15 END IDD_DRIVE_HARDWARE DIALOGEX 0, 0, 240, 220 @@ -400,11 +400,11 @@ FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN CONTROL "", 14000, "SysListView32", LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | WS_BORDER | WS_TABSTOP, 10, 10, 220, 50 GROUPBOX "Propriedades para as localizações seleccionadas", -1, 10, 72, 220, 70 - RADIOBUTTON "&Tamanho personalizado:", 14001, 20, 90, 92, 10 + RADIOBUTTON "Tamanho &personalizado:", 14001, 20, 90, 92, 10 EDITTEXT 14002, 116, 103, 50, 14, WS_TABSTOP | ES_NUMBER - LTEXT "Tamanho M&áximo(MB):", -1, 20, 105, 75, 10 - RADIOBUTTON "Não mover os ficheiros para a &reciclagem. Apagá-los definitivamente.", 14003, 20, 117, 170, 20, BS_MULTILINE | WS_TABSTOP - AUTOCHECKBOX "&Mostrar ecrâ de confirmação de eliminação", 14004, 20, 155, 140, 10 + LTEXT "&Tamanho máximo(MB):", -1, 20, 105, 75, 10 + RADIOBUTTON "&Não mover os ficheiros para a reciclagem. Apagá-los definitivamente.", 14003, 20, 117, 170, 20, BS_MULTILINE | WS_TABSTOP + AUTOCHECKBOX "&Mostrar caixa de dialogo de confirmação de eliminação", 14004, 20, 155, 188, 10 END IDD_OPEN_WITH DIALOGEX 0, 0, 264, 256 @@ -438,8 +438,8 @@ BEGIN AUTORADIOBUTTON "Abrir cada pasta na sua &janela", IDC_FOLDER_OPTIONS_OWNWINDOW, 40, 82, 210, 10 GROUPBOX "Seleccione a seguinte opção", -1, 7, 110, 249, 64 CONTROL "", IDC_FOLDER_OPTIONS_CLICKICON, "Static", SS_ICON | WS_CHILD | WS_VISIBLE, 14, 120, 21, 20 - AUTORADIOBUTTON "&Click simples para abrir um item", IDC_FOLDER_OPTIONS_SINGLECLICK, 40, 120, 210, 10, WS_TABSTOP | WS_GROUP - AUTORADIOBUTTON "&Duplo-click para abrir um item (um click para seleccionar)", IDC_FOLDER_OPTIONS_DOUBLECLICK, 40, 156, 210, 10 + AUTORADIOBUTTON "&Clique simples para abrir um item", IDC_FOLDER_OPTIONS_SINGLECLICK, 40, 120, 210, 10, WS_TABSTOP | WS_GROUP + AUTORADIOBUTTON "&Duplo-clique para abrir um item (um clique para seleccionar)", IDC_FOLDER_OPTIONS_DOUBLECLICK, 40, 156, 210, 10 AUTORADIOBUTTON "Sublinhar títulos de ícones consistentes com meu &navegador", IDC_FOLDER_OPTIONS_ULBROWSER, 50, 132, 205, 10, WS_TABSTOP | WS_GROUP AUTORADIOBUTTON "Sublinhar títulos de ícones sómente quando &apontados", IDC_FOLDER_OPTIONS_ULPOINT, 50, 144, 200, 10 PUSHBUTTON "&Restaurar predefinições", IDC_FOLDER_OPTIONS_RESTORE, 167, 178, 90, 14 @@ -613,18 +613,19 @@ FONT 8, "MS Shell Dlg" BEGIN DEFPUSHBUTTON "&Iniciar", IDOK, 53, 198, 60, 14 PUSHBUTTON "&Fechar", IDCANCEL, 118, 198, 60, 14 - LTEXT "Capacidade:", -1, 7, 6, 169, 9 //FIXME: needs an accelerator. In the past that was "Ca&pacidade:" and was most likely correct, but the &P is currently blocked by "&Permitir Compressão". Check Windows! - COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + LTEXT "&Capacidade:", -1, 7, 6, 169, 9 + COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&Sistema de ficheiros", -1, 7, 35, 170, 9 - COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8 LTEXT "&Tamanho da unidade de alocação", -1, 7, 64, 170, 9 - COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&Nome do volume", -1, 7, 93, 170, 9 EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL GROUPBOX "&Opções", 4610, 7, 121, 170, 49 - AUTOCHECKBOX "Formatação &Rápida", 28674, 16, 135, 155, 10 - AUTOCHECKBOX "&Permitir Compressão", 28675, 16, 152, 155, 10 + AUTOCHECKBOX "Formatação &rápida", 28674, 16, 135, 155, 10 + AUTOCHECKBOX "&Permitir compressão", 28675, 16, 152, 155, 10 + CONTROL "", 30000, "STATIC", SS_ICON | WS_TABSTOP | SS_CENTERIMAGE | SS_NOTIFY, 7, 198, 15, 14 END IDD_CHECK_DISK DIALOGEX 50, 50, 194, 115 @@ -635,8 +636,8 @@ BEGIN DEFPUSHBUTTON "Iniciar", IDOK, 63, 95, 60, 14 GROUPBOX "Opções verificação do disco", -1, 7, 6, 179, 40 PUSHBUTTON "Cancelar", IDCANCEL, 128, 95, 60, 14 - AUTOCHECKBOX "Corrigir erros do sistema de ficheiros automaticamente", 14000, 12, 15, 155, 10 //FIXME: needs an accel - AUTOCHECKBOX "&Procurar e tentar recuperar sectores danificados", 14001, 12, 30, 165, 10 + AUTOCHECKBOX "&Corrigir erros do sistema automaticamente", 14000, 12, 15, 155, 10 + AUTOCHECKBOX "&Procurar e recuperar sectores danificados", 14001, 12, 30, 165, 10 CONTROL "", 14002, "MSCTLS_PROGRESS32", 16, 7, 50, 179, 8 LTEXT "", 14003, 60, 80, 170, 10 END @@ -647,8 +648,8 @@ CAPTION "Alterar ícone" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Procurar ícones no ficheiro:", -1, 7, 7, 179, 10 - PUSHBUTTON "&Procurar...", IDC_BUTTON_PATH, 135, 17, 50, 14 EDITTEXT IDC_EDIT_PATH, 7, 17, 123, 14, ES_AUTOHSCROLL + PUSHBUTTON "&Procurar...", IDC_BUTTON_PATH, 135, 17, 50, 14 LTEXT "Seleccione um ícone na lista abaixo:", -1, 7, 36, 179, 10 LISTBOX IDC_PICKICON_LIST, 7, 47, 181, 122, LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | LBS_DISABLENOSCROLL | WS_HSCROLL | WS_TABSTOP DEFPUSHBUTTON "OK", IDOK, 81, 179, 50, 14 @@ -665,8 +666,8 @@ BEGIN outra aplicação. Modificar este ficheiro pode danificar o seu\n\ sistema ou torná-lo instável.\n\n\ Tem a certeza que deseja abrir este ficheiro?", IDC_STATIC, 35, 5, 230, 60 - DEFPUSHBUTTON "&Sim", IDYES, 125, 55, 50, 14 - PUSHBUTTON "&Não", IDNO, 180, 55, 50, 14 + DEFPUSHBUTTON "Sim", IDYES, 125, 55, 50, 14 + PUSHBUTTON "Não", IDNO, 180, 55, 50, 14 END IDD_NEWEXTENSION DIALOGEX 0, 0, 260, 75 @@ -873,8 +874,8 @@ BEGIN /* Shortcut property sheet */ IDS_SHORTCUT_RUN_NORMAL "Normal window" - IDS_SHORTCUT_RUN_MIN "Minimized" - IDS_SHORTCUT_RUN_MAX "Maximized" + IDS_SHORTCUT_RUN_MIN "Minimizado" + IDS_SHORTCUT_RUN_MAX "Maximizado" /* Shell folder path default values. See also: dll/win32/userenv/lang */ IDS_PROGRAMS "Menu Iniciar\\Programas" @@ -928,8 +929,8 @@ BEGIN FCIDM_SHVIEW_NEWFOLDER "&Pasta" FCIDM_SHVIEW_NEWLINK "&Atalho" IDS_FOLDER_OPTIONS "Opções das Pastas" - IDS_TASKBAR_OPTIONS "Taskbar and Start Menu" - IDS_TASKBAR_OPTIONS_INFOTIP "Customize the Start Menu and the taskbar, such as the types of items to be displayed and how they should appear." + IDS_TASKBAR_OPTIONS "Barra de tarefas e menu iniciar" + IDS_TASKBAR_OPTIONS_INFOTIP "Personaliza o menu Iniciar e a barra de tarefas, como o tipo de itens a apresentar e o seu aspecto visual." IDS_RECYCLEBIN_LOCATION "Localização da reciclagem" IDS_RECYCLEBIN_DISKSPACE "Espaço disponível" IDS_EMPTY_BITBUCKET "Esvaziar reciclagem" @@ -944,8 +945,8 @@ BEGIN IDS_CANTDISCONNECT "Não foi possível desconectar (Código de erro: %lu)." IDS_NONE "(Nenhum)" - IDS_EXPAND "Exp&and" - IDS_COLLAPSE "Coll&apse" + IDS_EXPAND "Exp&andir" + IDS_COLLAPSE "Col&apsar" /* Friendly File Type Names */ IDS_DIRECTORY "Pasta" @@ -1007,6 +1008,12 @@ BEGIN IDS_OBJECTS "%d Objectos" IDS_OBJECTS_SELECTED "%d Objectos seleccionados" + IDS_SEARCH_BROWSEITEM "Procurar..." + + IDS_RECYCLE_CLEANER_DISPLAYNAME "Recycle Bin" + IDS_RECYCLE_CLEANER_DESCRIPTION "The Recycle Bin contains files you have deleted from your computer. These files are not permanently removed until you empty the Recycle Bin." + IDS_RECYCLE_CLEANER_BUTTON_TEXT "&View Files" + IDS_TITLE_MYCOMP "O Meu Computador" IDS_TITLE_MYNET "Os Meus Locais na Rede" IDS_TITLE_BIN_1 "Reciclagem (cheia)" diff --git a/dll/win32/shell32/lang/ro-RO.rc b/dll/win32/shell32/lang/ro-RO.rc index 35ba49334c8ed..94b92ab418b81 100644 --- a/dll/win32/shell32/lang/ro-RO.rc +++ b/dll/win32/shell32/lang/ro-RO.rc @@ -612,17 +612,18 @@ BEGIN DEFPUSHBUTTON "&Start", IDOK, 53, 198, 60, 14 PUSHBUTTON "Î&nchidere", IDCANCEL, 118, 198, 60, 14 LTEXT "&Capacitate:", -1, 7, 6, 169, 9 - COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Sistem de &fişiere", -1, 7, 35, 170, 9 - COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8 LTEXT "Mărime &unitate de alocare", -1, 7, 64, 170, 9 - COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&Etichetă volum", -1, 7, 93, 170, 9 EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL GROUPBOX "&Opţiuni de formatare", 4610, 7, 121, 170, 49 AUTOCHECKBOX "Formatare &rapidă", 28674, 16, 135, 155, 10 AUTOCHECKBOX "&Activare comprimare", 28675, 16, 152, 155, 10 + CONTROL "", 30000, "STATIC", SS_ICON | WS_TABSTOP | SS_CENTERIMAGE | SS_NOTIFY, 7, 198, 15, 14 END IDD_CHECK_DISK DIALOGEX 50, 50, 194, 115 @@ -645,8 +646,8 @@ CAPTION "Modificare pictogramă" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Căutare pictograme în fişierul:", -1, 7, 7, 179, 10 - PUSHBUTTON "&Răsfoire…", IDC_BUTTON_PATH, 135, 17, 50, 14 EDITTEXT IDC_EDIT_PATH, 7, 17, 123, 14, ES_AUTOHSCROLL + PUSHBUTTON "&Răsfoire…", IDC_BUTTON_PATH, 135, 17, 50, 14 LTEXT "Selectaţi o pictogramă din lista de mai jos:", -1, 7, 36, 179, 10 LISTBOX IDC_PICKICON_LIST, 7, 47, 181, 122, LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | LBS_DISABLENOSCROLL | WS_HSCROLL | WS_TABSTOP DEFPUSHBUTTON "OK", IDOK, 81, 179, 50, 14 @@ -1006,6 +1007,12 @@ BEGIN IDS_OBJECTS "%d Obiecte" IDS_OBJECTS_SELECTED "%d Obiecte selectate" + IDS_SEARCH_BROWSEITEM "Răsfoire..." + + IDS_RECYCLE_CLEANER_DISPLAYNAME "Recycle Bin" + IDS_RECYCLE_CLEANER_DESCRIPTION "The Recycle Bin contains files you have deleted from your computer. These files are not permanently removed until you empty the Recycle Bin." + IDS_RECYCLE_CLEANER_BUTTON_TEXT "&View Files" + IDS_TITLE_MYCOMP "Computerul meu" IDS_TITLE_MYNET "Locaţii în reţea" IDS_TITLE_BIN_1 "Coş de reciclare (plin)" diff --git a/dll/win32/shell32/lang/ru-RU.rc b/dll/win32/shell32/lang/ru-RU.rc index 773dde053f556..ff6ba43915223 100644 --- a/dll/win32/shell32/lang/ru-RU.rc +++ b/dll/win32/shell32/lang/ru-RU.rc @@ -613,17 +613,18 @@ BEGIN DEFPUSHBUTTON "&Начать", IDOK, 53, 198, 60, 14 PUSHBUTTON "&Закрыть", IDCANCEL, 118, 198, 60, 14 LTEXT "&Емкость:", -1, 7, 6, 169, 9 - COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&Файловая система:", -1, 7, 35, 170, 9 - COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8 LTEXT "&Размер кластера:", -1, 7, 64, 170, 9 - COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&Метка тома:", -1, 7, 93, 170, 9 EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL GROUPBOX "&Способы форматирования:", 4610, 7, 121, 170, 49 AUTOCHECKBOX "&Быстрое (очистка оглавления)", 28674, 16, 135, 155, 10 AUTOCHECKBOX "&Использовать сжатие", 28675, 16, 152, 155, 10 + CONTROL "", 30000, "STATIC", SS_ICON | WS_TABSTOP | SS_CENTERIMAGE | SS_NOTIFY, 7, 198, 15, 14 END IDD_CHECK_DISK DIALOGEX 50, 50, 226, 114 @@ -646,8 +647,8 @@ CAPTION "Изменение значка" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Искать значки в этом файле:", -1, 7, 7, 179, 10 - PUSHBUTTON "Обзор...", IDC_BUTTON_PATH, 135, 17, 50, 14 EDITTEXT IDC_EDIT_PATH, 7, 17, 123, 14, ES_AUTOHSCROLL + PUSHBUTTON "Обзор...", IDC_BUTTON_PATH, 135, 17, 50, 14 LTEXT "Выберите значок из списка ниже:", -1, 7, 36, 179, 10 LISTBOX IDC_PICKICON_LIST, 7, 47, 181, 122, LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | LBS_DISABLENOSCROLL | WS_HSCROLL | WS_TABSTOP DEFPUSHBUTTON "OK", IDOK, 81, 179, 50, 14 @@ -1007,6 +1008,12 @@ BEGIN IDS_OBJECTS "Объектов: %d" IDS_OBJECTS_SELECTED "Выделено объектов: %d" + IDS_SEARCH_BROWSEITEM "Обзор..." + + IDS_RECYCLE_CLEANER_DISPLAYNAME "Recycle Bin" + IDS_RECYCLE_CLEANER_DESCRIPTION "The Recycle Bin contains files you have deleted from your computer. These files are not permanently removed until you empty the Recycle Bin." + IDS_RECYCLE_CLEANER_BUTTON_TEXT "&View Files" + IDS_TITLE_MYCOMP "Мой компьютер" IDS_TITLE_MYNET "Сетевое окружение" IDS_TITLE_BIN_1 "Корзина (полная)" diff --git a/dll/win32/shell32/lang/sk-SK.rc b/dll/win32/shell32/lang/sk-SK.rc index 59bb8bf6097cb..f4da6a1a07570 100644 --- a/dll/win32/shell32/lang/sk-SK.rc +++ b/dll/win32/shell32/lang/sk-SK.rc @@ -604,17 +604,18 @@ BEGIN DEFPUSHBUTTON "&Spustiť", IDOK, 53, 198, 60, 14 PUSHBUTTON "&Zavrieť", IDCANCEL, 118, 198, 60, 14 LTEXT "&Kapacita:", -1, 7, 6, 169, 9 - COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Súborový systé&m:", -1, 7, 35, 170, 9 - COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8 LTEXT "&Veľkosť alokačnej jednotky:", -1, 7, 64, 170, 9 - COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&Názov zväzku", -1, 7, 93, 170, 9 EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL GROUPBOX "Možnosti &formátovania", 4610, 7, 121, 170, 49 AUTOCHECKBOX "&Rýchle formátovanie", 28674, 16, 135, 155, 10 AUTOCHECKBOX "Z&apnúť kompresiu", 28675, 16, 152, 155, 10 + CONTROL "", 30000, "STATIC", SS_ICON | WS_TABSTOP | SS_CENTERIMAGE | SS_NOTIFY, 7, 198, 15, 14 END IDD_CHECK_DISK DIALOGEX 50, 50, 194, 115 @@ -637,8 +638,8 @@ CAPTION "Zmena ikony" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Look for icons in this file:", -1, 7, 7, 179, 10 - PUSHBUTTON "&Prehľadávať...", IDC_BUTTON_PATH, 128, 17, 57, 14 EDITTEXT IDC_EDIT_PATH, 7, 17, 117, 14, ES_AUTOHSCROLL + PUSHBUTTON "&Prehľadávať...", IDC_BUTTON_PATH, 128, 17, 57, 14 LTEXT "Select an icon from the list below:", -1, 7, 36, 179, 10 LISTBOX IDC_PICKICON_LIST, 7, 47, 181, 122, LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | LBS_DISABLENOSCROLL | WS_HSCROLL | WS_TABSTOP DEFPUSHBUTTON "OK", IDOK, 81, 179, 50, 14 @@ -998,6 +999,12 @@ BEGIN IDS_OBJECTS "%d Objects" IDS_OBJECTS_SELECTED "%d Objects Selected" + IDS_SEARCH_BROWSEITEM "Prehľadávať..." + + IDS_RECYCLE_CLEANER_DISPLAYNAME "Recycle Bin" + IDS_RECYCLE_CLEANER_DESCRIPTION "The Recycle Bin contains files you have deleted from your computer. These files are not permanently removed until you empty the Recycle Bin." + IDS_RECYCLE_CLEANER_BUTTON_TEXT "&View Files" + IDS_TITLE_MYCOMP "Tento počítač" IDS_TITLE_MYNET "Miesta v sieti" IDS_TITLE_BIN_1 "Kôš (plný)" diff --git a/dll/win32/shell32/lang/sl-SI.rc b/dll/win32/shell32/lang/sl-SI.rc index 516ea2483f233..69e1f20ff3c5d 100644 --- a/dll/win32/shell32/lang/sl-SI.rc +++ b/dll/win32/shell32/lang/sl-SI.rc @@ -216,7 +216,7 @@ BEGIN LTEXT "Choose the advanced properties you want for this shortcut.", -1, 5, 30, 210, 10 CHECKBOX "Run with different credentials", IDC_SHORTEX_RUN_DIFFERENT, 25, 50, 150, 10 LTEXT "This option can allow you to run the this shortcut as another user, or continue as yourself while protecting your computer and data from unauthorized program activity.", -1, 50, 60, 175, 40 - CHECKBOX "Run in seperate memory space", IDC_SHORTEX_RUN_SEPARATE, 25, 100, 150, 10, WS_DISABLED + CHECKBOX "Run in separate memory space", IDC_SHORTEX_RUN_SEPARATE, 25, 100, 150, 10, WS_DISABLED PUSHBUTTON "OK", IDOK, 63, 124, 50, 15, WS_VISIBLE PUSHBUTTON "Abort", IDCANCEL, 120, 124, 50, 15, WS_VISIBLE END @@ -604,17 +604,18 @@ BEGIN DEFPUSHBUTTON "&Start", IDOK, 53, 198, 60, 14 PUSHBUTTON "&Close", IDCANCEL, 118, 198, 60, 14 LTEXT "Ca&pacity:", -1, 7, 6, 169, 9 - COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&File system", -1, 7, 35, 170, 9 - COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8 LTEXT "&Allocation unit size", -1, 7, 64, 170, 9 - COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Volume &label", -1, 7, 93, 170, 9 EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL GROUPBOX "Format &options", 4610, 7, 121, 170, 49 AUTOCHECKBOX "&Quick Format", 28674, 16, 135, 155, 10 AUTOCHECKBOX "&Enable Compression", 28675, 16, 152, 155, 10 + CONTROL "", 30000, "STATIC", SS_ICON | WS_TABSTOP | SS_CENTERIMAGE | SS_NOTIFY, 7, 198, 15, 14 END IDD_CHECK_DISK DIALOGEX 50, 50, 194, 115 @@ -637,8 +638,8 @@ CAPTION "Change Icon" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Look for icons in this file:", -1, 7, 7, 179, 10 - PUSHBUTTON "Browse...", IDC_BUTTON_PATH, 135, 17, 50, 14 EDITTEXT IDC_EDIT_PATH, 7, 17, 123, 14, ES_AUTOHSCROLL + PUSHBUTTON "Browse...", IDC_BUTTON_PATH, 135, 17, 50, 14 LTEXT "Select an icon from the list below:", -1, 7, 36, 179, 10 LISTBOX IDC_PICKICON_LIST, 7, 47, 181, 122, LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | LBS_DISABLENOSCROLL | WS_HSCROLL | WS_TABSTOP DEFPUSHBUTTON "OK", IDOK, 81, 179, 50, 14 @@ -998,6 +999,12 @@ BEGIN IDS_OBJECTS "%d Objects" IDS_OBJECTS_SELECTED "%d Objects Selected" + IDS_SEARCH_BROWSEITEM "Prebrskaj..." + + IDS_RECYCLE_CLEANER_DISPLAYNAME "Recycle Bin" + IDS_RECYCLE_CLEANER_DESCRIPTION "The Recycle Bin contains files you have deleted from your computer. These files are not permanently removed until you empty the Recycle Bin." + IDS_RECYCLE_CLEANER_BUTTON_TEXT "&View Files" + IDS_TITLE_MYCOMP "My Computer" IDS_TITLE_MYNET "My Network Places" IDS_TITLE_BIN_1 "Recycle Bin (full)" diff --git a/dll/win32/shell32/lang/sq-AL.rc b/dll/win32/shell32/lang/sq-AL.rc index fcf87e2f73480..607cd85954e41 100644 --- a/dll/win32/shell32/lang/sq-AL.rc +++ b/dll/win32/shell32/lang/sq-AL.rc @@ -611,17 +611,18 @@ BEGIN DEFPUSHBUTTON "&Fillo", IDOK, 53, 198, 60, 14 PUSHBUTTON "&Mbyll", IDCANCEL, 118, 198, 60, 14 LTEXT "Kapaciteti:", -1, 7, 6, 169, 9 - COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&Dokumente sistemi", -1, 7, 35, 170, 9 - COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8 LTEXT "Madhësia Njësisë Alokimit", -1, 7, 64, 170, 9 - COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&Etiketa volumit", -1, 7, 93, 170, 9 EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL GROUPBOX "&Opsione format", 4610, 7, 121, 170, 49 AUTOCHECKBOX "Format Shpejtë", 28674, 16, 135, 155, 10 AUTOCHECKBOX "Mundëso Kompresimin", 28675, 16, 152, 155, 10 + CONTROL "", 30000, "STATIC", SS_ICON | WS_TABSTOP | SS_CENTERIMAGE | SS_NOTIFY, 7, 198, 15, 14 END IDD_CHECK_DISK DIALOGEX 50, 50, 194, 115 @@ -644,8 +645,8 @@ CAPTION "Ndrysho Ikonë" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Look for icons in this file:", -1, 7, 7, 179, 10 - PUSHBUTTON "Shfleto...", IDC_BUTTON_PATH, 135, 17, 50, 14 EDITTEXT IDC_EDIT_PATH, 7, 17, 123, 14, ES_AUTOHSCROLL + PUSHBUTTON "Shfleto...", IDC_BUTTON_PATH, 135, 17, 50, 14 LTEXT "Select an icon from the list below:", -1, 7, 36, 179, 10 LISTBOX IDC_PICKICON_LIST, 7, 47, 181, 122, LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | LBS_DISABLENOSCROLL | WS_HSCROLL | WS_TABSTOP DEFPUSHBUTTON "OK", IDOK, 81, 179, 50, 14 @@ -1005,6 +1006,12 @@ BEGIN IDS_OBJECTS "%d Objects" IDS_OBJECTS_SELECTED "%d Objects Selected" + IDS_SEARCH_BROWSEITEM "Shfleto..." + + IDS_RECYCLE_CLEANER_DISPLAYNAME "Recycle Bin" + IDS_RECYCLE_CLEANER_DESCRIPTION "The Recycle Bin contains files you have deleted from your computer. These files are not permanently removed until you empty the Recycle Bin." + IDS_RECYCLE_CLEANER_BUTTON_TEXT "&View Files" + IDS_TITLE_MYCOMP "Kompjuteri Im" IDS_TITLE_MYNET "Vendi Rrjetit Tim" IDS_TITLE_BIN_1 "Plehra (plot)" diff --git a/dll/win32/shell32/lang/sv-SE.rc b/dll/win32/shell32/lang/sv-SE.rc index 9d5486e743ded..c591c343c7820 100644 --- a/dll/win32/shell32/lang/sv-SE.rc +++ b/dll/win32/shell32/lang/sv-SE.rc @@ -604,17 +604,18 @@ BEGIN DEFPUSHBUTTON "&Starta", IDOK, 53, 198, 60, 14 PUSHBUTTON "S&täng", IDCANCEL, 118, 198, 60, 14 LTEXT "Ka&pacitet:", -1, 7, 6, 169, 9 - COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&Filsystem", -1, 7, 35, 170, 9 - COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8 LTEXT "&Allokeringsstorlek", -1, 7, 64, 170, 9 - COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Volum&etikett", -1, 7, 93, 170, 9 EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL GROUPBOX "Formaterings&alternativ", 4610, 7, 121, 170, 49 AUTOCHECKBOX "&Snabbformatering", 28674, 16, 135, 155, 10 AUTOCHECKBOX "&Använd komprimering", 28675, 16, 152, 155, 10 + CONTROL "", 30000, "STATIC", SS_ICON | WS_TABSTOP | SS_CENTERIMAGE | SS_NOTIFY, 7, 198, 15, 14 END IDD_CHECK_DISK DIALOGEX 50, 50, 194, 115 @@ -637,8 +638,8 @@ CAPTION "Ändra ikon" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Look for icons in this file:", -1, 7, 7, 179, 10 - PUSHBUTTON "Bläddra...", IDC_BUTTON_PATH, 135, 17, 50, 14 EDITTEXT IDC_EDIT_PATH, 7, 17, 123, 14, ES_AUTOHSCROLL + PUSHBUTTON "Bläddra...", IDC_BUTTON_PATH, 135, 17, 50, 14 LTEXT "Select an icon from the list below:", -1, 7, 36, 179, 10 LISTBOX IDC_PICKICON_LIST, 7, 47, 181, 122, LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | LBS_DISABLENOSCROLL | WS_HSCROLL | WS_TABSTOP DEFPUSHBUTTON "OK", IDOK, 81, 179, 50, 14 @@ -998,6 +999,12 @@ BEGIN IDS_OBJECTS "%d objekt" IDS_OBJECTS_SELECTED "%d markerade objekt" + IDS_SEARCH_BROWSEITEM "Bläddra..." + + IDS_RECYCLE_CLEANER_DISPLAYNAME "Recycle Bin" + IDS_RECYCLE_CLEANER_DESCRIPTION "The Recycle Bin contains files you have deleted from your computer. These files are not permanently removed until you empty the Recycle Bin." + IDS_RECYCLE_CLEANER_BUTTON_TEXT "&View Files" + IDS_TITLE_MYCOMP "Den här datorn" IDS_TITLE_MYNET "Mina nätverksplatser" IDS_TITLE_BIN_1 "Papperskorgen (full)" diff --git a/dll/win32/shell32/lang/tr-TR.rc b/dll/win32/shell32/lang/tr-TR.rc index 2d52e60d51d9c..29ca66b604df1 100644 --- a/dll/win32/shell32/lang/tr-TR.rc +++ b/dll/win32/shell32/lang/tr-TR.rc @@ -613,17 +613,18 @@ BEGIN DEFPUSHBUTTON "&Başlat", IDOK, 53, 198, 60, 14 PUSHBUTTON "&Kapat", IDCANCEL, 118, 198, 60, 14 LTEXT "K&apasite:", -1, 7, 6, 169, 9 - COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&Dosya sistemi", -1, 7, 35, 170, 9 - COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8 LTEXT "Ayı&rma birimi boyutu", -1, 7, 64, 170, 9 - COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Bölü&m etiketi", -1, 7, 93, 170, 9 EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL GROUPBOX "Biçimlendirme seçenekleri", 4610, 7, 121, 170, 49 AUTOCHECKBOX "&Hızlı Biçimlendir", 28674, 16, 135, 155, 10 AUTOCHECKBOX "&Sıkıştırmayı Etkinleştir", 28675, 16, 152, 155, 10 + CONTROL "", 30000, "STATIC", SS_ICON | WS_TABSTOP | SS_CENTERIMAGE | SS_NOTIFY, 7, 198, 15, 14 END IDD_CHECK_DISK DIALOGEX 50, 50, 194, 115 @@ -646,8 +647,8 @@ CAPTION "Simge Değiştir" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Bu dosyadaki simgelere bak:", -1, 7, 7, 179, 10 - PUSHBUTTON "Gözat...", IDC_BUTTON_PATH, 135, 17, 50, 14 EDITTEXT IDC_EDIT_PATH, 7, 17, 123, 14, ES_AUTOHSCROLL + PUSHBUTTON "Gözat...", IDC_BUTTON_PATH, 135, 17, 50, 14 LTEXT "Aşağıdaki listeden bir simge seç:", -1, 7, 36, 179, 10 LISTBOX IDC_PICKICON_LIST, 7, 47, 181, 122, LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | LBS_DISABLENOSCROLL | WS_HSCROLL | WS_TABSTOP DEFPUSHBUTTON "Tamam", IDOK, 81, 179, 50, 14 @@ -1007,6 +1008,12 @@ BEGIN IDS_OBJECTS "%d Nesne" IDS_OBJECTS_SELECTED "%d Nesne Seçili" + IDS_SEARCH_BROWSEITEM "Gözat..." + + IDS_RECYCLE_CLEANER_DISPLAYNAME "Recycle Bin" + IDS_RECYCLE_CLEANER_DESCRIPTION "The Recycle Bin contains files you have deleted from your computer. These files are not permanently removed until you empty the Recycle Bin." + IDS_RECYCLE_CLEANER_BUTTON_TEXT "&View Files" + IDS_TITLE_MYCOMP "Bilgisayarım" IDS_TITLE_MYNET "Ağ Bağlantılarım" IDS_TITLE_BIN_1 "Recycle Bin (full)" diff --git a/dll/win32/shell32/lang/uk-UA.rc b/dll/win32/shell32/lang/uk-UA.rc index 853f4041a02d9..fc1b333f9ffc9 100644 --- a/dll/win32/shell32/lang/uk-UA.rc +++ b/dll/win32/shell32/lang/uk-UA.rc @@ -604,17 +604,18 @@ BEGIN DEFPUSHBUTTON "&Почати", IDOK, 53, 198, 60, 14 PUSHBUTTON "&Закрити", IDCANCEL, 118, 198, 60, 14 LTEXT "&Місткість:", -1, 7, 6, 169, 9 - COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "&Файлова система", -1, 7, 35, 170, 9 - COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8 LTEXT "&Розмір кластера", -1, 7, 64, 170, 9 - COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Мі&тка тому", -1, 7, 93, 170, 9 EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL GROUPBOX "&Способи форматування", 4610, 7, 121, 170, 49 AUTOCHECKBOX "&Швидке (очищення змісту)", 28674, 16, 135, 155, 10 AUTOCHECKBOX "&Використовувати стискання", 28675, 16, 152, 155, 10 + CONTROL "", 30000, "STATIC", SS_ICON | WS_TABSTOP | SS_CENTERIMAGE | SS_NOTIFY, 7, 198, 15, 14 END IDD_CHECK_DISK DIALOGEX 50, 50, 194, 115 @@ -637,8 +638,8 @@ CAPTION "Зміна значка" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Значки в цьому файлі:", -1, 7, 7, 179, 10 - PUSHBUTTON "О&гляд...", IDC_BUTTON_PATH, 135, 17, 50, 14 EDITTEXT IDC_EDIT_PATH, 7, 17, 123, 14, ES_AUTOHSCROLL + PUSHBUTTON "О&гляд...", IDC_BUTTON_PATH, 135, 17, 50, 14 LTEXT "Виберіть значок зі списку нижче:", -1, 7, 36, 179, 10 LISTBOX IDC_PICKICON_LIST, 7, 47, 181, 122, LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | LBS_DISABLENOSCROLL | WS_HSCROLL | WS_TABSTOP DEFPUSHBUTTON "OK", IDOK, 81, 179, 50, 14 @@ -998,6 +999,12 @@ BEGIN IDS_OBJECTS "%d об'єктів" IDS_OBJECTS_SELECTED "Обрано %d об'єктів" + IDS_SEARCH_BROWSEITEM "Огляд..." + + IDS_RECYCLE_CLEANER_DISPLAYNAME "Recycle Bin" + IDS_RECYCLE_CLEANER_DESCRIPTION "The Recycle Bin contains files you have deleted from your computer. These files are not permanently removed until you empty the Recycle Bin." + IDS_RECYCLE_CLEANER_BUTTON_TEXT "&View Files" + IDS_TITLE_MYCOMP "Мій комп'ютер" IDS_TITLE_MYNET "Мережне оточення" IDS_TITLE_BIN_1 "Кошик (повний)" diff --git a/dll/win32/shell32/lang/zh-CN.rc b/dll/win32/shell32/lang/zh-CN.rc index 3d58230cc58c6..35b7d97f35c97 100644 --- a/dll/win32/shell32/lang/zh-CN.rc +++ b/dll/win32/shell32/lang/zh-CN.rc @@ -614,17 +614,18 @@ BEGIN DEFPUSHBUTTON "开始(&S)", IDOK, 53, 198, 60, 14 PUSHBUTTON "关闭(&C)", IDCANCEL, 118, 198, 60, 14 LTEXT "容量(&P):", -1, 7, 6, 169, 9 - COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "文件系统(&F)", -1, 7, 35, 170, 9 - COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8 LTEXT "分配单元大小(&A)", -1, 7, 64, 170, 9 - COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "卷标(&L)", -1, 7, 93, 170, 9 EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL GROUPBOX "格式化选项(&O)", 4610, 7, 121, 170, 49 AUTOCHECKBOX "快速格式化(&Q)", 28674, 16, 135, 155, 10 AUTOCHECKBOX "启用压缩(&E)", 28675, 16, 152, 155, 10 + CONTROL "", 30000, "STATIC", SS_ICON | WS_TABSTOP | SS_CENTERIMAGE | SS_NOTIFY, 7, 198, 15, 14 END IDD_CHECK_DISK DIALOGEX 50, 50, 194, 115 @@ -647,8 +648,8 @@ CAPTION "更改图标" FONT 9, "宋体", 400, 0, 0x1 BEGIN LTEXT "在这个文件中查找图标:", -1, 7, 7, 179, 10 - PUSHBUTTON "浏览...", IDC_BUTTON_PATH, 135, 17, 50, 14 EDITTEXT IDC_EDIT_PATH, 7, 17, 123, 14, ES_AUTOHSCROLL + PUSHBUTTON "浏览...", IDC_BUTTON_PATH, 135, 17, 50, 14 LTEXT "从以下列表选择一个图标:", -1, 7, 36, 179, 10 LISTBOX IDC_PICKICON_LIST, 7, 47, 181, 122, LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | LBS_DISABLENOSCROLL | WS_HSCROLL | WS_TABSTOP DEFPUSHBUTTON "确定", IDOK, 81, 179, 50, 14 @@ -1008,6 +1009,12 @@ BEGIN IDS_OBJECTS "%d 个对象" IDS_OBJECTS_SELECTED "已选中 %d 个对象" + IDS_SEARCH_BROWSEITEM "浏览..." + + IDS_RECYCLE_CLEANER_DISPLAYNAME "Recycle Bin" + IDS_RECYCLE_CLEANER_DESCRIPTION "The Recycle Bin contains files you have deleted from your computer. These files are not permanently removed until you empty the Recycle Bin." + IDS_RECYCLE_CLEANER_BUTTON_TEXT "&View Files" + IDS_TITLE_MYCOMP "我的电脑" IDS_TITLE_MYNET "网上邻居" IDS_TITLE_BIN_1 "回收站(满)" diff --git a/dll/win32/shell32/lang/zh-HK.rc b/dll/win32/shell32/lang/zh-HK.rc index e4700b57e726f..c491f825cd6a6 100644 --- a/dll/win32/shell32/lang/zh-HK.rc +++ b/dll/win32/shell32/lang/zh-HK.rc @@ -612,17 +612,18 @@ BEGIN DEFPUSHBUTTON "開始(&S)", IDOK, 53, 198, 60, 14 PUSHBUTTON "結束(&C)", IDCANCEL, 118, 198, 60, 14 LTEXT "容量(&P):", -1, 7, 6, 169, 9 - COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "檔案系統(&F)", -1, 7, 35, 170, 9 - COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8 LTEXT "配置單位大小(&A)", -1, 7, 64, 170, 9 - COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "磁碟區標籤(&L)", -1, 7, 93, 170, 9 EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL GROUPBOX "格式化選項(&O)", 4610, 7, 121, 170, 49 AUTOCHECKBOX "快速格式化(&Q)", 28674, 16, 135, 155, 10 AUTOCHECKBOX "啟用壓縮(&E)", 28675, 16, 152, 155, 10 + CONTROL "", 30000, "STATIC", SS_ICON | WS_TABSTOP | SS_CENTERIMAGE | SS_NOTIFY, 7, 198, 15, 14 END IDD_CHECK_DISK DIALOGEX 50, 50, 194, 115 @@ -645,8 +646,8 @@ CAPTION "變更圖示" FONT 9, "新細明體", 400, 0, 0x1 BEGIN LTEXT "在這個檔案裡尋找圖示:", -1, 7, 7, 179, 10 - PUSHBUTTON "瀏覽...", IDC_BUTTON_PATH, 135, 17, 50, 14 EDITTEXT IDC_EDIT_PATH, 7, 17, 123, 14, ES_AUTOHSCROLL + PUSHBUTTON "瀏覽...", IDC_BUTTON_PATH, 135, 17, 50, 14 LTEXT "選擇所列出的圖示:", -1, 7, 36, 179, 10 LISTBOX IDC_PICKICON_LIST, 7, 47, 181, 122, LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | LBS_DISABLENOSCROLL | WS_HSCROLL | WS_TABSTOP DEFPUSHBUTTON "確定", IDOK, 81, 179, 50, 14 @@ -1006,6 +1007,12 @@ BEGIN IDS_OBJECTS "%d 個物件" IDS_OBJECTS_SELECTED "已選擇 %d 個物件" + IDS_SEARCH_BROWSEITEM "瀏覽..." + + IDS_RECYCLE_CLEANER_DISPLAYNAME "Recycle Bin" + IDS_RECYCLE_CLEANER_DESCRIPTION "The Recycle Bin contains files you have deleted from your computer. These files are not permanently removed until you empty the Recycle Bin." + IDS_RECYCLE_CLEANER_BUTTON_TEXT "&View Files" + IDS_TITLE_MYCOMP "我的電腦" IDS_TITLE_MYNET "網絡上的芳鄰" IDS_TITLE_BIN_1 "Recycle Bin (full)" diff --git a/dll/win32/shell32/lang/zh-TW.rc b/dll/win32/shell32/lang/zh-TW.rc index 2bc2ea7d49fc3..a31bc153d4d9f 100644 --- a/dll/win32/shell32/lang/zh-TW.rc +++ b/dll/win32/shell32/lang/zh-TW.rc @@ -613,17 +613,18 @@ BEGIN DEFPUSHBUTTON "開始(&S)", IDOK, 53, 198, 60, 14 PUSHBUTTON "結束(&C)", IDCANCEL, 118, 198, 60, 14 LTEXT "容量(&P):", -1, 7, 6, 169, 9 - COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "檔案系統(&F)", -1, 7, 35, 170, 9 - COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8 LTEXT "配置單位大小(&A)", -1, 7, 64, 170, 9 - COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP + COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "磁碟區標籤(&L)", -1, 7, 93, 170, 9 EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL GROUPBOX "格式化選項(&O)", 4610, 7, 121, 170, 49 AUTOCHECKBOX "快速格式化(&Q)", 28674, 16, 135, 155, 10 AUTOCHECKBOX "啟用壓縮(&E)", 28675, 16, 152, 155, 10 + CONTROL "", 30000, "STATIC", SS_ICON | WS_TABSTOP | SS_CENTERIMAGE | SS_NOTIFY, 7, 198, 15, 14 END IDD_CHECK_DISK DIALOGEX 50, 50, 194, 115 @@ -646,8 +647,8 @@ CAPTION "變更圖示" FONT 9, "新細明體", 400, 0, 0x1 BEGIN LTEXT "在這個檔案裡尋找圖示:", -1, 7, 7, 179, 10 - PUSHBUTTON "瀏覽...", IDC_BUTTON_PATH, 135, 17, 50, 14 EDITTEXT IDC_EDIT_PATH, 7, 17, 123, 14, ES_AUTOHSCROLL + PUSHBUTTON "瀏覽...", IDC_BUTTON_PATH, 135, 17, 50, 14 LTEXT "選擇所列出的圖示:", -1, 7, 36, 179, 10 LISTBOX IDC_PICKICON_LIST, 7, 47, 181, 122, LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | LBS_DISABLENOSCROLL | WS_HSCROLL | WS_TABSTOP DEFPUSHBUTTON "確定", IDOK, 81, 179, 50, 14 @@ -1007,6 +1008,12 @@ BEGIN IDS_OBJECTS "%d 個物件" IDS_OBJECTS_SELECTED "已選擇 %d 個物件" + IDS_SEARCH_BROWSEITEM "瀏覽..." + + IDS_RECYCLE_CLEANER_DISPLAYNAME "Recycle Bin" + IDS_RECYCLE_CLEANER_DESCRIPTION "The Recycle Bin contains files you have deleted from your computer. These files are not permanently removed until you empty the Recycle Bin." + IDS_RECYCLE_CLEANER_BUTTON_TEXT "&View Files" + IDS_TITLE_MYCOMP "我的電腦" IDS_TITLE_MYNET "網路上的芳鄰" IDS_TITLE_BIN_1 "Recycle Bin (full)" diff --git a/dll/win32/shell32/precomp.h b/dll/win32/shell32/precomp.h index a28c023d244e0..ea662be14213e 100644 --- a/dll/win32/shell32/precomp.h +++ b/dll/win32/shell32/precomp.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -42,8 +43,8 @@ #include #include -#define SHLWAPI_ISHELLFOLDER_HELPERS #include +#include #include #undef ShellExecute @@ -172,6 +173,8 @@ SHELL32_ShowPropertiesDialog(IDataObject *pdtobj); HRESULT SHELL32_ShowFilesystemItemPropertiesDialogAsync(IDataObject *pDO); HRESULT +SHELL32_ShowFilesystemItemsPropertiesDialogAsync(HWND hOwner, IDataObject *pDO); +HRESULT SHELL32_ShowShellExtensionProperties(const CLSID *pClsid, IDataObject *pDO); HRESULT SHELL_ShowItemIDListProperties(LPCITEMIDLIST pidl); @@ -239,14 +242,6 @@ BOOL Shell_FailForceReturn(_In_ HRESULT hr); EXTERN_C INT Shell_ParseSpecialFolder(_In_ LPCWSTR pszStart, _Out_ LPWSTR *ppch, _Out_ INT *pcch); -HRESULT -Shell_DisplayNameOf( - _In_ IShellFolder *psf, - _In_ LPCITEMIDLIST pidl, - _In_ DWORD dwFlags, - _Out_ LPWSTR pszBuf, - _In_ UINT cchBuf); - EXTERN_C HRESULT SHBindToObject( _In_opt_ IShellFolder *psf, @@ -262,6 +257,12 @@ SHBindToObjectEx( _In_ REFIID riid, _Out_ void **ppvObj); +EXTERN_C HRESULT +SHELL_GetUIObjectOfAbsoluteItem( + _In_opt_ HWND hWnd, + _In_ PCIDLIST_ABSOLUTE pidl, + _In_ REFIID riid, _Out_ void **ppvObj); + DWORD SHGetAttributes(_In_ IShellFolder *psf, _In_ LPCITEMIDLIST pidl, _In_ DWORD dwAttributes); HRESULT SHELL_GetIDListTarget(_In_ LPCITEMIDLIST pidl, _Out_ PIDLIST_ABSOLUTE *ppidl); @@ -287,10 +288,13 @@ BindCtx_RegisterObjectParam( BOOL PathIsDotOrDotDotW(_In_ LPCWSTR pszPath); BOOL PathIsValidElement(_In_ LPCWSTR pszPath); BOOL PathIsDosDevice(_In_ LPCWSTR pszName); +HRESULT SHELL32_GetDllFromRundll32CommandLine(LPCWSTR pszCmd, LPWSTR pszOut, SIZE_T cchMax); HRESULT SHILAppend(_Inout_ LPITEMIDLIST pidl, _Inout_ LPITEMIDLIST *ppidl); +HRESULT DataObject_GetHIDACount(IDataObject *pdo); PIDLIST_ABSOLUTE SHELL_CIDA_ILCloneFull(_In_ const CIDA *pCIDA, _In_ UINT Index); PIDLIST_ABSOLUTE SHELL_DataObject_ILCloneFullItem(_In_ IDataObject *pDO, _In_ UINT Index); +HRESULT SHELL_CloneDataObject(_In_ IDataObject *pDO, _Out_ IDataObject **ppDO); EXTERN_C HRESULT IUnknown_InitializeCommand( @@ -314,4 +318,23 @@ InvokeIExecuteCommandWithDataObject( _In_opt_ LPCMINVOKECOMMANDINFOEX pICI, _In_opt_ IUnknown *pSite); +typedef enum _FILEOPCALLBACKEVENT { + FOCE_STARTOPERATIONS, + FOCE_FINISHOPERATIONS, + FOCE_PREMOVEITEM, + FOCE_POSTMOVEITEM, + FOCE_PRECOPYITEM, + FOCE_POSTCOPYITEM, + FOCE_PREDELETEITEM, + FOCE_POSTDELETEITEM, + FOCE_PRERENAMEITEM, + FOCE_POSTRENAMEITEM, + FOCE_PRENEWITEM, + FOCE_POSTNEWITEM +} FILEOPCALLBACKEVENT; +typedef HRESULT (CALLBACK *FILEOPCALLBACK)(FILEOPCALLBACKEVENT Event, LPCWSTR Source, LPCWSTR Destination, + UINT Attributes, HRESULT hr, void *CallerData); +int SHELL32_FileOperation(LPSHFILEOPSTRUCTW lpFileOp, FILEOPCALLBACK Callback, void *CallerData); +HRESULT SHELL_SingleFileOperation(HWND hWnd, UINT Op, PCWSTR Src, PCWSTR Dest, UINT Flags, PWSTR *ppNewName); + #endif /* _PRECOMP_H__ */ diff --git a/dll/win32/shell32/propsheet.cpp b/dll/win32/shell32/propsheet.cpp index 3fccaa0ac1a01..7768e16c35859 100644 --- a/dll/win32/shell32/propsheet.cpp +++ b/dll/win32/shell32/propsheet.cpp @@ -160,6 +160,41 @@ SHELL32_OpenPropSheet(LPCWSTR pszCaption, HKEY *ahKeys, UINT cKeys, return (Result != -1); } +/************************************************************************* + * SHOpenPropSheetA [SHELL32.707] + * + * @see https://learn.microsoft.com/en-us/windows/win32/api/shlobj/nf-shlobj-shopenpropsheeta + */ +EXTERN_C +BOOL WINAPI +SHOpenPropSheetA( + _In_opt_ LPCSTR pszCaption, + _In_opt_ HKEY *ahKeys, + _In_ UINT cKeys, + _In_ const CLSID *pclsidDefault, + _In_ IDataObject *pDataObject, + _In_opt_ IShellBrowser *pShellBrowser, + _In_opt_ LPCSTR pszStartPage) +{ + CStringW strStartPageW, strCaptionW; + LPCWSTR pszCaptionW = NULL, pszStartPageW = NULL; + + if (pszCaption) + { + strStartPageW = pszCaption; + pszCaptionW = strCaptionW; + } + + if (pszStartPage) + { + strStartPageW = pszStartPage; + pszStartPageW = strStartPageW; + } + + return SHOpenPropSheetW(pszCaptionW, ahKeys, cKeys, pclsidDefault, + pDataObject, pShellBrowser, pszStartPageW); +} + /************************************************************************* * SHOpenPropSheetW [SHELL32.80] * diff --git a/dll/win32/shell32/res/bitmaps/reactos.bmp b/dll/win32/shell32/res/bitmaps/reactos.bmp index 2ec7eeb1772f6..ef1fc5765c858 100644 Binary files a/dll/win32/shell32/res/bitmaps/reactos.bmp and b/dll/win32/shell32/res/bitmaps/reactos.bmp differ diff --git a/dll/win32/shell32/res/rgs/recyclebincleaner.rgs b/dll/win32/shell32/res/rgs/recyclebincleaner.rgs new file mode 100644 index 0000000000000..557c41bd192b1 --- /dev/null +++ b/dll/win32/shell32/res/rgs/recyclebincleaner.rgs @@ -0,0 +1,43 @@ +HKCR +{ + NoRemove CLSID + { + ForceRemove {5ef4af3a-f726-11d0-b8a2-00c04fc309a4} = s 'Recycle bin cleaner' + { + InprocServer32 = s '%MODULE%' + { + val ThreadingModel = s 'Apartment' + } + DefaultIcon = s '%MODULE%,-33' + } + } +} + +HKLM +{ + NoRemove SOFTWARE + { + NoRemove Microsoft + { + NoRemove Windows + { + NoRemove CurrentVersion + { + NoRemove Explorer + { + NoRemove VolumeCaches + { + ForceRemove 'Recycle Bin' = s '{5ef4af3a-f726-11d0-b8a2-00c04fc309a4}' + } + NoRemove MyComputer + { + ForceRemove cleanuppath = e '%%SystemRoot%%\System32\cleanmgr.exe /D %%c' + { + } + } + } + } + } + } + } +} diff --git a/dll/win32/shell32/rgs_res.rc b/dll/win32/shell32/rgs_res.rc index 52ef32b014b24..c80d36b5d7a2e 100644 --- a/dll/win32/shell32/rgs_res.rc +++ b/dll/win32/shell32/rgs_res.rc @@ -33,3 +33,4 @@ IDR_SENDTOMENU REGISTRY "res/rgs/sendtomenu.rgs" IDR_COPYASPATHMENU REGISTRY "res/rgs/copyaspathmenu.rgs" IDR_COPYTOMENU REGISTRY "res/rgs/copytomenu.rgs" IDR_MOVETOMENU REGISTRY "res/rgs/movetomenu.rgs" +IDR_RECYCLEBINCLEANER REGISTRY "res/rgs/recyclebincleaner.rgs" diff --git a/dll/win32/shell32/shell32.spec b/dll/win32/shell32/shell32.spec index 759f4676e944e..58da27c18642b 100644 --- a/dll/win32/shell32/shell32.spec +++ b/dll/win32/shell32/shell32.spec @@ -307,6 +307,7 @@ 307 stdcall SHGetFolderPathW(long long long long ptr) 308 stdcall SHGetIconOverlayIndexA(str long) 309 stdcall SHGetIconOverlayIndexW(wstr long) +@ stdcall -version=0x600+ SHGetIDListFromObject(ptr ptr) 310 stdcall SHGetInstanceExplorer(long) 311 stdcall SHGetMalloc(ptr) 312 stdcall SHGetNewLinkInfo(str str ptr long long) SHGetNewLinkInfoA @@ -317,7 +318,7 @@ 317 stdcall SHGetSpecialFolderLocation(long long ptr) 318 stdcall SHGetSpecialFolderPathA(long ptr long long) 319 stdcall SHGetSpecialFolderPathW(long ptr long long) -320 stdcall SHGetUnreadMailCountW (long wstr long ptr wstr long) +320 stdcall SHGetUnreadMailCountW(ptr wstr ptr ptr ptr long) 321 stdcall SHHelpShortcuts_RunDLL(long long long long) SHHelpShortcuts_RunDLLA 322 stdcall SHHelpShortcuts_RunDLLA(long long long long) 323 stdcall SHHelpShortcuts_RunDLLW(long long long long) @@ -354,7 +355,7 @@ 354 stdcall SheShortenPathW(wstr long) 355 stdcall ShellAboutA(long str str long) 356 stdcall ShellAboutW(long wstr wstr long) -357 stdcall ShellExec_RunDLL(ptr ptr wstr long) +357 stdcall ShellExec_RunDLL(ptr ptr str long) ShellExec_RunDLLA 358 stdcall ShellExec_RunDLLA(ptr ptr str long) 359 stdcall ShellExec_RunDLLW(ptr ptr wstr long) 360 stdcall ShellExecuteA(long str str str str long) @@ -460,8 +461,9 @@ 749 stdcall -noname -version=0x501-0x502 SHGetShellStyleHInstance() 750 stdcall -noname SHGetAttributesFromDataObject(ptr long ptr ptr) 751 stub -noname SHSimulateDropOnClsid -752 stdcall -noname SHGetComputerDisplayNameW(long long long long) +752 stdcall -noname SHGetComputerDisplayNameW(wstr long ptr long) 753 stdcall -noname CheckStagingArea() 754 stub -noname SHLimitInputEditWithFlags 755 stdcall -noname PathIsEqualOrSubFolder(wstr wstr) 756 stub -noname DeleteFileThumbnail +757 stdcall -version=0x600+ DisplayNameOfW(ptr ptr long ptr long) diff --git a/dll/win32/shell32/shelldesktop/CDirectoryWatcher.cpp b/dll/win32/shell32/shelldesktop/CDirectoryWatcher.cpp index 1bb7d80cb303d..d24e1540a6ed9 100644 --- a/dll/win32/shell32/shelldesktop/CDirectoryWatcher.cpp +++ b/dll/win32/shell32/shelldesktop/CDirectoryWatcher.cpp @@ -299,7 +299,8 @@ GetFilterFromEvents(DWORD fEvents) return (FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_CREATION | - FILE_NOTIFY_CHANGE_SIZE); + FILE_NOTIFY_CHANGE_SIZE | + FILE_NOTIFY_CHANGE_ATTRIBUTES); } // Restart a watch by using ReadDirectoryChangesW function diff --git a/dll/win32/shell32/shelldesktop/CDirectoryWatcher.h b/dll/win32/shell32/shelldesktop/CDirectoryWatcher.h index e2733bc3ce236..41f7de244033b 100644 --- a/dll/win32/shell32/shelldesktop/CDirectoryWatcher.h +++ b/dll/win32/shell32/shelldesktop/CDirectoryWatcher.h @@ -9,7 +9,7 @@ #include "CDirectoryList.h" // NOTE: Regard to asynchronous procedure call (APC), please see: -// https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-sleepex +// https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-sleepex class CDirectoryWatcher { diff --git a/dll/win32/shell32/shellmenu/CMenuBand.cpp b/dll/win32/shell32/shellmenu/CMenuBand.cpp index 486f745c6b00e..36c581219845a 100644 --- a/dll/win32/shell32/shellmenu/CMenuBand.cpp +++ b/dll/win32/shell32/shellmenu/CMenuBand.cpp @@ -865,6 +865,7 @@ HRESULT CMenuBand::_TrackContextMenu(IContextMenu * contextMenu, INT x, INT y) cmi.fMask |= CMIC_MASK_SHIFT_DOWN; if (GetKeyState(VK_CONTROL) < 0) cmi.fMask |= CMIC_MASK_CONTROL_DOWN; + cmi.nShow = SW_SHOW; hr = contextMenu->InvokeCommand(&cmi); TRACE("InvokeCommand returned hr=%08x\n", hr); } diff --git a/dll/win32/shell32/shellmenu/CMenuSite.cpp b/dll/win32/shell32/shellmenu/CMenuSite.cpp index 6faf0fabb0cfa..9ccb55d42d59c 100644 --- a/dll/win32/shell32/shellmenu/CMenuSite.cpp +++ b/dll/win32/shell32/shellmenu/CMenuSite.cpp @@ -85,6 +85,9 @@ HRESULT STDMETHODCALLTYPE CMenuSite::AddBand(IUnknown * punk) HRESULT STDMETHODCALLTYPE CMenuSite::EnumBands(UINT uBand, DWORD* pdwBandID) { + if (uBand == UINT(-1)) + return GetBandCount(); + if (uBand != 0) return E_FAIL; diff --git a/dll/win32/shell32/shellmenu/CMenuSite.h b/dll/win32/shell32/shellmenu/CMenuSite.h index 3421e1be3079a..713791390f0e4 100644 --- a/dll/win32/shell32/shellmenu/CMenuSite.h +++ b/dll/win32/shell32/shellmenu/CMenuSite.h @@ -104,4 +104,5 @@ class CMenuSite : private: IUnknown * ToIUnknown() { return static_cast(this); } + UINT GetBandCount() { return m_BandObject ? 1 : 0; } }; diff --git a/dll/win32/shell32/shellmenu/CMergedFolder.h b/dll/win32/shell32/shellmenu/CMergedFolder.h index a30a8cd0c472b..867ea0a4d46ca 100644 --- a/dll/win32/shell32/shellmenu/CMergedFolder.h +++ b/dll/win32/shell32/shellmenu/CMergedFolder.h @@ -52,13 +52,13 @@ class CMergedFolder : public IPersistFolder2, public IItemNameLimits, public IAugmentedShellFolder3 // -- undocumented - //public IShellService, // DEPRECATED IE4 interface: https://msdn.microsoft.com/en-us/library/windows/desktop/bb774870%28v=vs.85%29.aspx + //public IShellService, // DEPRECATED IE4 interface: https://learn.microsoft.com/en-us/windows/win32/api/shdeprecated/nn-shdeprecated-ishellservice //public ITranslateShellChangeNotify,// -- undocumented //public IStorage, //public IPersistPropertyBag, //public IShellIconOverlay, // -- undocumented //public ICompositeFolder, // -- undocumented - //public IItemNameLimits, // https://msdn.microsoft.com/en-us/library/windows/desktop/bb761776%28v=vs.85%29.aspx + //public IItemNameLimits, // https://learn.microsoft.com/en-us/windows/win32/api/shobjidl_core/nn-shobjidl_core-iitemnamelimits { private: CComPtr m_UserLocal; diff --git a/dll/win32/shell32/shellrecyclebin/recyclebin.c b/dll/win32/shell32/shellrecyclebin/recyclebin.c index 88221b0da99cd..890b625ea4bfd 100644 --- a/dll/win32/shell32/shellrecyclebin/recyclebin.c +++ b/dll/win32/shell32/shellrecyclebin/recyclebin.c @@ -12,7 +12,7 @@ BOOL WINAPI CloseRecycleBinHandle( IN HDELFILE hDeletedFile) { - IRecycleBinFile *rbf = (IRecycleBinFile *)hDeletedFile; + IRecycleBinFile *rbf = IRecycleBinFileFromHDELFILE(hDeletedFile); HRESULT hr; TRACE("(%p)\n", hDeletedFile); @@ -90,10 +90,10 @@ DeleteFileToRecycleBinW( } BOOL WINAPI -DeleteFileHandleToRecycleBin( +DeleteFileInRecycleBin( IN HDELFILE hDeletedFile) { - IRecycleBinFile *rbf = (IRecycleBinFile *)hDeletedFile; + IRecycleBinFile *rbf = IRecycleBinFileFromHDELFILE(hDeletedFile); HRESULT hr; TRACE("(%p)\n", hDeletedFile); @@ -231,9 +231,10 @@ EnumerateRecycleBinW( } else if (!SUCCEEDED(hr)) goto cleanup; - if (!pFnCallback(Context, (HANDLE)prbf)) + if (!pFnCallback(Context, (HDELFILE)prbf)) { - hr = HRESULT_FROM_WIN32(GetLastError()); + UINT error = GetLastError(); + hr = HRESULT_FROM_WIN32(error); goto cleanup; } } @@ -252,135 +253,56 @@ EnumerateRecycleBinW( return FALSE; } -BOOL WINAPI -GetDeletedFileTypeNameW( - IN HDELFILE hDeletedFile, - OUT LPWSTR pTypeName, - IN DWORD BufferSize, - OUT LPDWORD RequiredSize OPTIONAL) +typedef struct _BBENUMFILECONTEXT { - IRecycleBinFile *prbf = (IRecycleBinFile *)hDeletedFile; - SIZE_T FinalSize; - - HRESULT hr = IRecycleBinFile_GetTypeName(prbf, BufferSize, pTypeName, &FinalSize); + const RECYCLEBINFILEIDENTITY *pFI; + HDELFILE hDelFile; +} BBENUMFILECONTEXT; - if (SUCCEEDED(hr)) +static BOOL CALLBACK +GetRecycleBinFileHandleCallback(IN PVOID Context, IN HDELFILE hDeletedFile) +{ + BBENUMFILECONTEXT *pCtx = (BBENUMFILECONTEXT*)Context; + IRecycleBinFile *pRBF = IRecycleBinFileFromHDELFILE(hDeletedFile); + if (IRecycleBinFile_IsEqualIdentity(pRBF, pCtx->pFI) == S_OK) { - if (RequiredSize) - *RequiredSize = (DWORD)FinalSize; - - return TRUE; + pCtx->hDelFile = hDeletedFile; + return FALSE; } - if (HRESULT_FACILITY(hr) == FACILITY_WIN32) - SetLastError(HRESULT_CODE(hr)); - else - SetLastError(ERROR_GEN_FAILURE); - return FALSE; + CloseRecycleBinHandle(hDeletedFile); + return TRUE; } -BOOL WINAPI -GetDeletedFileDetailsA( - IN HDELFILE hDeletedFile, - IN DWORD BufferSize, - IN OUT PDELETED_FILE_DETAILS_A FileDetails OPTIONAL, - OUT LPDWORD RequiredSize OPTIONAL) +EXTERN_C HDELFILE +GetRecycleBinFileHandle( + IN LPCWSTR pszRoot OPTIONAL, + IN const RECYCLEBINFILEIDENTITY *pFI) { - PDELETED_FILE_DETAILS_W FileDetailsW = NULL; - DWORD BufferSizeW = 0; - BOOL ret = FALSE; - - TRACE("(%p, %lu, %p, %p)\n", hDeletedFile, BufferSize, FileDetails, RequiredSize); - - if (BufferSize >= FIELD_OFFSET(DELETED_FILE_DETAILS_A, FileName)) - { - BufferSizeW = FIELD_OFFSET(DELETED_FILE_DETAILS_W, FileName) - + (BufferSize - FIELD_OFFSET(DELETED_FILE_DETAILS_A, FileName)) * sizeof(WCHAR); - } - if (FileDetails && BufferSizeW) - { - FileDetailsW = HeapAlloc(GetProcessHeap(), 0, BufferSizeW); - if (!FileDetailsW) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - goto cleanup; - } - } - - ret = GetDeletedFileDetailsW(hDeletedFile, BufferSizeW, FileDetailsW, RequiredSize); - if (!ret) - goto cleanup; - - if (FileDetails) - { - CopyMemory(FileDetails, FileDetailsW, FIELD_OFFSET(DELETED_FILE_DETAILS_A, FileName)); - if (0 == WideCharToMultiByte(CP_ACP, 0, FileDetailsW->FileName, -1, FileDetails->FileName, BufferSize - FIELD_OFFSET(DELETED_FILE_DETAILS_A, FileName), NULL, NULL)) - goto cleanup; - } - ret = TRUE; - -cleanup: - HeapFree(GetProcessHeap(), 0, FileDetailsW); - return ret; + BBENUMFILECONTEXT context = { pFI, NULL }; + EnumerateRecycleBinW(pszRoot, GetRecycleBinFileHandleCallback, &context); + return context.hDelFile; } -BOOL WINAPI -GetDeletedFileDetailsW( - IN HDELFILE hDeletedFile, - IN DWORD BufferSize, - IN OUT PDELETED_FILE_DETAILS_W FileDetails OPTIONAL, - OUT LPDWORD RequiredSize OPTIONAL) +EXTERN_C BOOL +RemoveFromRecycleBinDatabase( + IN const RECYCLEBINFILEIDENTITY *pFI) { - IRecycleBinFile *rbf = (IRecycleBinFile *)hDeletedFile; - HRESULT hr; - SIZE_T NameSize, Needed; - - TRACE("(%p, %lu, %p, %p)\n", hDeletedFile, BufferSize, FileDetails, RequiredSize); - - hr = IRecycleBinFile_GetFileName(rbf, 0, NULL, &NameSize); - if (!SUCCEEDED(hr)) - goto cleanup; - Needed = FIELD_OFFSET(DELETED_FILE_DETAILS_W, FileName) + NameSize; - if (RequiredSize) - *RequiredSize = (DWORD)Needed; - if (Needed > BufferSize) + BOOL ret = FALSE; + HDELFILE hDelFile = GetRecycleBinFileHandle(NULL, pFI); + if (hDelFile) { - hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); - goto cleanup; + IRecycleBinFile *rbf = IRecycleBinFileFromHDELFILE(hDelFile); + ret = SUCCEEDED(IRecycleBinFile_RemoveFromDatabase(rbf)); + CloseRecycleBinHandle(hDelFile); } - hr = IRecycleBinFile_GetFileName(rbf, NameSize, FileDetails->FileName, NULL); - if (!SUCCEEDED(hr)) - goto cleanup; - hr = IRecycleBinFile_GetLastModificationTime(rbf, &FileDetails->LastModification); - if (!SUCCEEDED(hr)) - goto cleanup; - hr = IRecycleBinFile_GetDeletionTime(rbf, &FileDetails->DeletionTime); - if (!SUCCEEDED(hr)) - goto cleanup; - hr = IRecycleBinFile_GetFileSize(rbf, &FileDetails->FileSize); - if (!SUCCEEDED(hr)) - goto cleanup; - hr = IRecycleBinFile_GetPhysicalFileSize(rbf, &FileDetails->PhysicalFileSize); - if (!SUCCEEDED(hr)) - goto cleanup; - hr = IRecycleBinFile_GetAttributes(rbf, &FileDetails->Attributes); - if (!SUCCEEDED(hr)) - goto cleanup; - -cleanup: - if (SUCCEEDED(hr)) - return TRUE; - if (HRESULT_FACILITY(hr) == FACILITY_WIN32) - SetLastError(HRESULT_CODE(hr)); - else - SetLastError(ERROR_GEN_FAILURE); - return FALSE; + return ret; } BOOL WINAPI -RestoreFile( +RestoreFileFromRecycleBin( IN HDELFILE hDeletedFile) { - IRecycleBinFile *rbf = (IRecycleBinFile *)hDeletedFile; + IRecycleBinFile *rbf = IRecycleBinFileFromHDELFILE(hDeletedFile); HRESULT hr; TRACE("(%p)\n", hDeletedFile); @@ -395,7 +317,7 @@ RestoreFile( return FALSE; } -HRESULT WINAPI +EXTERN_C HRESULT GetDefaultRecycleBin( IN LPCWSTR pszVolume OPTIONAL, OUT IRecycleBin **pprb) @@ -425,3 +347,17 @@ GetDefaultRecycleBin( IUnknown_Release(pUnk); return hr; } + +EXTERN_C HRESULT +GetRecycleBinPathFromDriveNumber(UINT Drive, LPWSTR Path) +{ + const WCHAR volume[] = { LOWORD('A' + Drive), ':', '\\', '\0' }; + IRecycleBin *pRB; + HRESULT hr = GetDefaultRecycleBin(volume, &pRB); + if (SUCCEEDED(hr)) + { + hr = IRecycleBin_GetDirectory(pRB, Path); + IRecycleBin_Release(pRB); + } + return hr; +} diff --git a/dll/win32/shell32/shellrecyclebin/recyclebin.h b/dll/win32/shell32/shellrecyclebin/recyclebin.h index a48f49264cf3a..4746d0857ef3d 100644 --- a/dll/win32/shell32/shellrecyclebin/recyclebin.h +++ b/dll/win32/shell32/shellrecyclebin/recyclebin.h @@ -17,48 +17,64 @@ extern "C" { #include #include -#define ANY_SIZE 1 +#define RECYCLEBINMAXDRIVECOUNT 26 /* Structures used by the API Interface */ -typedef struct _DELETED_FILE_DETAILS_A +typedef UINT RECYCLEBINFILESIZETYPE; + +typedef struct _RECYCLEBINFILEIDENTITY { - FILETIME LastModification; - FILETIME DeletionTime; - ULARGE_INTEGER FileSize; - ULARGE_INTEGER PhysicalFileSize; - DWORD Attributes; - CHAR FileName[ANY_SIZE]; -} DELETED_FILE_DETAILS_A, *PDELETED_FILE_DETAILS_A; -typedef struct _DELETED_FILE_DETAILS_W + FILETIME DeletionTime; + LPCWSTR RecycledFullPath; /* "C:\Recycled\Dc1.ext" etc. */ +} RECYCLEBINFILEIDENTITY, *PRECYCLEBINFILEIDENTITY; + +typedef struct _RECYCLEBINSTRING { - FILETIME LastModification; - FILETIME DeletionTime; - ULARGE_INTEGER FileSize; - ULARGE_INTEGER PhysicalFileSize; - DWORD Attributes; - WCHAR FileName[ANY_SIZE]; -} DELETED_FILE_DETAILS_W, *PDELETED_FILE_DETAILS_W; -#ifdef UNICODE -#define DELETED_FILE_DETAILS DELETED_FILE_DETAILS_W -#define PDELETED_FILE_DETAILS PDELETED_FILE_DETAILS_W -#else -#define DELETED_FILE_DETAILS DELETED_FILE_DETAILS_A -#define PDELETED_FILE_DETAILS PDELETED_FILE_DETAILS_A -#endif + LPCWSTR String; + LPWSTR Alloc; +} RECYCLEBINSTRING, *PRECYCLEBINSTRING; + +typedef struct _DELETED_FILE_INFO +{ + FILETIME LastModification; + FILETIME DeletionTime; + RECYCLEBINFILESIZETYPE FileSize; + DWORD Attributes; + RECYCLEBINSTRING OriginalFullPath; + RECYCLEBINSTRING RecycledFullPath; +} DELETED_FILE_INFO, *PDELETED_FILE_INFO; /* Distinct handle type for deleted file/folder */ DECLARE_HANDLE(HDELFILE); +#define IRecycleBinFileFromHDELFILE(hDF) ( (IRecycleBinFile*)(hDF) ) /* API Interface */ +static inline void +FreeRecycleBinString(PRECYCLEBINSTRING pRBS) +{ + SHFree(pRBS->Alloc); + pRBS->String = pRBS->Alloc = NULL; +} + +static inline void +InitializeRecycleBinStringRef(PRECYCLEBINSTRING pRBS, LPCWSTR String) +{ + pRBS->String = String; + pRBS->Alloc = NULL; +} + +EXTERN_C HRESULT +GetRecycleBinPathFromDriveNumber(UINT Drive, LPWSTR Path); + /* Function called for each deleted file in the recycle bin * Context: value given by the caller of the EnumerateRecycleBin function * hDeletedFile: a handle to the deleted file * Returning FALSE stops the enumeration. * Remarks: the handle must be closed with the CloseRecycleBinHandle function */ -typedef BOOL (WINAPI *PENUMERATE_RECYCLEBIN_CALLBACK)(IN PVOID Context, IN HDELFILE hDeletedFile); +typedef BOOL (CALLBACK *PENUMERATE_RECYCLEBIN_CALLBACK)(IN PVOID Context, IN HDELFILE hDeletedFile); /* Closes a file deleted handle. * hDeletedFile: the handle to close @@ -85,13 +101,13 @@ DeleteFileToRecycleBinW( #define DeleteFileToRecycleBin DeleteFileToRecycleBinA #endif -/* Moves a file to the recycle bin. +/* Deletes a file in the recycle bin. * hDeletedFile: handle of the deleted file to delete * Returns TRUE if operation succeeded, FALSE otherwise. * Remark: The handle is obtained in the PENUMERATE_RECYCLEBIN_CALLBACK callback */ BOOL WINAPI -DeleteFileHandleToRecycleBin( +DeleteFileInRecycleBin( IN HDELFILE hDeletedFile); /* Removes all elements contained in a recycle bin @@ -134,38 +150,14 @@ EnumerateRecycleBinW( #define EnumerateRecycleBin EnumerateRecycleBinA #endif -BOOL WINAPI -GetDeletedFileTypeNameW( - IN HDELFILE hDeletedFile, - OUT LPWSTR pTypeName, - IN DWORD BufferSize, - OUT LPDWORD RequiredSize OPTIONAL); - -/* Gets details about a deleted file - * hDeletedFile: handle of the deleted file to get details about - * BufferSize: size of the 'FileDetails' buffer, in bytes - * FileDetails: if the function succeeded, contains details about the deleted file - * RequiredSize: contains the minimal buffer size required to get file information details - * Returns TRUE if operation succeeded, FALSE otherwise. - * Remark: The handle is obtained in the PENUMERATE_RECYCLEBIN_CALLBACK callback - */ -BOOL WINAPI -GetDeletedFileDetailsA( - IN HDELFILE hDeletedFile, - IN DWORD BufferSize, - IN OUT PDELETED_FILE_DETAILS_A FileDetails OPTIONAL, - OUT LPDWORD RequiredSize OPTIONAL); -BOOL WINAPI -GetDeletedFileDetailsW( - IN HDELFILE hDeletedFile, - IN DWORD BufferSize, - IN OUT PDELETED_FILE_DETAILS_W FileDetails OPTIONAL, - OUT LPDWORD RequiredSize OPTIONAL); -#ifdef UNICODE -#define GetDeletedFileDetails GetDeletedFileDetailsW -#else -#define GetDeletedFileDetails GetDeletedFileDetailsA -#endif +EXTERN_C HDELFILE +GetRecycleBinFileHandle( + IN LPCWSTR pszRoot OPTIONAL, + IN const RECYCLEBINFILEIDENTITY *pFI); + +EXTERN_C BOOL +RemoveFromRecycleBinDatabase( + IN const RECYCLEBINFILEIDENTITY *pFI); /* Restores a deleted file * hDeletedFile: handle of the deleted file to restore @@ -173,7 +165,7 @@ GetDeletedFileDetailsW( * Remarks: if the function succeeds, the handle is not valid anymore. */ BOOL WINAPI -RestoreFile( +RestoreFileFromRecycleBin( IN HDELFILE hDeletedFile); /* COM interface */ @@ -189,15 +181,17 @@ DECLARE_INTERFACE_(IRecycleBinFile, IUnknown) STDMETHOD_(ULONG, Release)(THIS) PURE; /* IRecycleBinFile methods */ + STDMETHOD(IsEqualIdentity)(THIS_ const RECYCLEBINFILEIDENTITY *pFI) PURE; + STDMETHOD(GetInfo)(THIS_ PDELETED_FILE_INFO pInfo) PURE; STDMETHOD(GetLastModificationTime)(THIS_ FILETIME *pLastModificationTime) PURE; STDMETHOD(GetDeletionTime)(THIS_ FILETIME *pDeletionTime) PURE; STDMETHOD(GetFileSize)(THIS_ ULARGE_INTEGER *pFileSize) PURE; STDMETHOD(GetPhysicalFileSize)(THIS_ ULARGE_INTEGER *pPhysicalFileSize) PURE; STDMETHOD(GetAttributes)(THIS_ DWORD *pAttributes) PURE; STDMETHOD(GetFileName)(THIS_ SIZE_T BufferSize, LPWSTR Buffer, SIZE_T *RequiredSize) PURE; - STDMETHOD(GetTypeName)(THIS_ SIZE_T BufferSize, LPWSTR Buffer, SIZE_T *RequiredSize) PURE; STDMETHOD(Delete)(THIS) PURE; STDMETHOD(Restore)(THIS) PURE; + STDMETHOD(RemoveFromDatabase)(THIS) PURE; END_INTERFACE }; @@ -233,9 +227,10 @@ DECLARE_INTERFACE_(IRecycleBin, IUnknown) STDMETHOD_(ULONG, Release)(THIS) PURE; /* IRecycleBin methods */ - STDMETHOD(DeleteFile)(THIS_ LPCWSTR szFileName); - STDMETHOD(EmptyRecycleBin)(THIS); - STDMETHOD(EnumObjects)(THIS_ IRecycleBinEnumList **ppEnumList); + STDMETHOD(DeleteFile)(THIS_ LPCWSTR szFileName) PURE; + STDMETHOD(EmptyRecycleBin)(THIS) PURE; + STDMETHOD(EnumObjects)(THIS_ IRecycleBinEnumList **ppEnumList) PURE; + STDMETHOD(GetDirectory)(THIS_ LPWSTR szPath) PURE; END_INTERFACE }; @@ -252,6 +247,10 @@ EXTERN_C const IID IID_IRecycleBin; (This)->lpVtbl->AddRef(This) #define IRecycleBinFile_Release(This) \ (This)->lpVtbl->Release(This) +#define IRecycleBinFile_IsEqualIdentity(This, pFI) \ + (This)->lpVtbl->IsEqualIdentity(This, pFI) +#define IRecycleBinFile_GetInfo(This, pInfo) \ + (This)->lpVtbl->GetInfo(This, pInfo) #define IRecycleBinFile_GetLastModificationTime(This, pLastModificationTime) \ (This)->lpVtbl->GetLastModificationTime(This, pLastModificationTime) #define IRecycleBinFile_GetDeletionTime(This, pDeletionTime) \ @@ -264,12 +263,12 @@ EXTERN_C const IID IID_IRecycleBin; (This)->lpVtbl->GetAttributes(This, pAttributes) #define IRecycleBinFile_GetFileName(This, BufferSize, Buffer, RequiredSize) \ (This)->lpVtbl->GetFileName(This, BufferSize, Buffer, RequiredSize) -#define IRecycleBinFile_GetTypeName(This, BufferSize, Buffer, RequiredSize) \ - (This)->lpVtbl->GetTypeName(This, BufferSize, Buffer, RequiredSize) #define IRecycleBinFile_Delete(This) \ (This)->lpVtbl->Delete(This) #define IRecycleBinFile_Restore(This) \ (This)->lpVtbl->Restore(This) +#define IRecycleBinFile_RemoveFromDatabase(This) \ + (This)->lpVtbl->RemoveFromDatabase(This) #define IRecycleBinEnumList_QueryInterface(This, riid, ppvObject) \ (This)->lpVtbl->QueryInterface(This, riid, ppvObject) @@ -296,13 +295,20 @@ EXTERN_C const IID IID_IRecycleBin; (This)->lpVtbl->EmptyRecycleBin(This) #define IRecycleBin_EnumObjects(This, ppEnumList) \ (This)->lpVtbl->EnumObjects(This, ppEnumList) +#define IRecycleBin_GetDirectory(This, szPath) \ + (This)->lpVtbl->GetDirectory(This, szPath) #endif -HRESULT WINAPI +EXTERN_C HRESULT GetDefaultRecycleBin( IN LPCWSTR pszVolume OPTIONAL, OUT IRecycleBin **pprb); +/* Recycle Bin shell folder internal API */ +void CRecycleBin_NotifyRecycled(LPCWSTR OrigPath, const WIN32_FIND_DATAW *pFind, + const RECYCLEBINFILEIDENTITY *pFI); + + #ifdef __cplusplus } #endif diff --git a/dll/win32/shell32/shellrecyclebin/recyclebin_generic.cpp b/dll/win32/shell32/shellrecyclebin/recyclebin_generic.cpp index a7ad1b00de017..09f561f40b674 100644 --- a/dll/win32/shell32/shellrecyclebin/recyclebin_generic.cpp +++ b/dll/win32/shell32/shellrecyclebin/recyclebin_generic.cpp @@ -23,6 +23,10 @@ class RecycleBinGeneric : public IRecycleBin STDMETHODIMP DeleteFile(LPCWSTR szFileName) override; STDMETHODIMP EmptyRecycleBin() override; STDMETHODIMP EnumObjects(IRecycleBinEnumList **ppEnumList) override; + STDMETHODIMP GetDirectory(LPWSTR szPath) override + { + return E_UNEXPECTED; + } protected: LONG m_ref; @@ -183,3 +187,11 @@ HRESULT RecycleBinGeneric_Constructor(OUT IUnknown **ppUnknown) *ppUnknown = static_cast(pThis); return S_OK; } + +EXTERN_C +BOOL RecycleBinGeneric_IsEqualFileIdentity(const RECYCLEBINFILEIDENTITY *p1, const RECYCLEBINFILEIDENTITY *p2) +{ + return p1->DeletionTime.dwLowDateTime == p2->DeletionTime.dwLowDateTime && + p1->DeletionTime.dwHighDateTime == p2->DeletionTime.dwHighDateTime && + _wcsicmp(p1->RecycledFullPath, p2->RecycledFullPath) == 0; +} diff --git a/dll/win32/shell32/shellrecyclebin/recyclebin_private.h b/dll/win32/shell32/shellrecyclebin/recyclebin_private.h index 42cffd2265665..57e440d389940 100644 --- a/dll/win32/shell32/shellrecyclebin/recyclebin_private.h +++ b/dll/win32/shell32/shellrecyclebin/recyclebin_private.h @@ -13,11 +13,20 @@ #include WINE_DEFAULT_DEBUG_CHANNEL(recyclebin); +#ifdef __cplusplus +static inline HRESULT HResultFromWin32(DWORD hr) +{ + // HRESULT_FROM_WIN32 will evaluate its parameter twice, this function will not. + return HRESULT_FROM_WIN32(hr); +} +#endif + /* Defines */ #define RECYCLE_BIN_DIRECTORY_WITH_ACL L"RECYCLER" #define RECYCLE_BIN_DIRECTORY_WITHOUT_ACL L"RECYCLED" #define RECYCLE_BIN_FILE_NAME L"INFO2" +#define RECYCLE_BIN_FILE_NAME_V1 L"INFO" #define ROUND_UP(N, S) ((( (N) + (S) - 1) / (S) ) * (S) ) @@ -43,6 +52,9 @@ typedef struct _INFO2_HEADER EXTERN_C HRESULT RecycleBinGeneric_Constructor(OUT IUnknown **ppUnknown); +EXTERN_C +BOOL RecycleBinGeneric_IsEqualFileIdentity(const RECYCLEBINFILEIDENTITY *p1, const RECYCLEBINFILEIDENTITY *p2); + /* recyclebin_generic_enumerator.c */ EXTERN_C diff --git a/dll/win32/shell32/shellrecyclebin/recyclebin_v5.cpp b/dll/win32/shell32/shellrecyclebin/recyclebin_v5.cpp index c7009f94d9ddd..08146caca740c 100644 --- a/dll/win32/shell32/shellrecyclebin/recyclebin_v5.cpp +++ b/dll/win32/shell32/shellrecyclebin/recyclebin_v5.cpp @@ -143,6 +143,13 @@ class RecycleBin5 : public IRecycleBin5 STDMETHODIMP DeleteFile(_In_ LPCWSTR szFileName) override; STDMETHODIMP EmptyRecycleBin() override; STDMETHODIMP EnumObjects(_Out_ IRecycleBinEnumList **ppEnumList) override; + STDMETHODIMP GetDirectory(LPWSTR szPath) override + { + if (!m_Folder[0]) + return E_UNEXPECTED; + lstrcpynW(szPath, m_Folder, MAX_PATH); + return S_OK; + } /* IRecycleBin5 interface */ STDMETHODIMP Delete( @@ -151,6 +158,9 @@ class RecycleBin5 : public IRecycleBin5 STDMETHODIMP Restore( _In_ LPCWSTR pDeletedFileName, _In_ DELETED_FILE_RECORD *pDeletedFile) override; + STDMETHODIMP RemoveFromDatabase( + _In_ LPCWSTR pDeletedFileName, + _In_ DELETED_FILE_RECORD *pDeletedFile) override; STDMETHODIMP OnClosing(_In_ IRecycleBinEnumList *prbel) override; protected: @@ -226,6 +236,7 @@ STDMETHODIMP RecycleBin5::DeleteFile(_In_ LPCWSTR szFileName) SYSTEMTIME SystemTime; DWORD ClusterSize, BytesPerSector, SectorsPerCluster; HRESULT hr; + WIN32_FIND_DATAW wfd = {}; TRACE("(%p, %s)\n", this, debugstr_w(szFileName)); @@ -240,7 +251,7 @@ STDMETHODIMP RecycleBin5::DeleteFile(_In_ LPCWSTR szFileName) { if (szFullName) CoTaskMemFree(szFullName); - return HRESULT_FROM_WIN32(GetLastError()); + return HResultFromWin32(GetLastError()); } else if (len < dwBufferLength) break; @@ -257,7 +268,7 @@ STDMETHODIMP RecycleBin5::DeleteFile(_In_ LPCWSTR szFileName) if (dwAttributes == INVALID_FILE_ATTRIBUTES) { CoTaskMemFree(szFullName); - return HRESULT_FROM_WIN32(GetLastError()); + return HResultFromWin32(GetLastError()); } if (dwBufferLength < 2 || szFullName[1] != ':') @@ -270,7 +281,7 @@ STDMETHODIMP RecycleBin5::DeleteFile(_In_ LPCWSTR szFileName) hFile = CreateFileW(szFullName, 0, 0, NULL, OPEN_EXISTING, (dwAttributes & FILE_ATTRIBUTE_DIRECTORY) ? FILE_FLAG_BACKUP_SEMANTICS : 0, NULL); if (hFile == INVALID_HANDLE_VALUE) { - hr = HRESULT_FROM_WIN32(GetLastError()); + hr = HResultFromWin32(GetLastError()); goto cleanup; } @@ -281,7 +292,7 @@ STDMETHODIMP RecycleBin5::DeleteFile(_In_ LPCWSTR szFileName) m_hInfoMapped = CreateFileMappingW(m_hInfo, NULL, PAGE_READWRITE | SEC_COMMIT, 0, 0, NULL); if (!m_hInfoMapped) { - hr = HRESULT_FROM_WIN32(GetLastError()); + hr = HResultFromWin32(GetLastError()); goto cleanup; } @@ -289,7 +300,7 @@ STDMETHODIMP RecycleBin5::DeleteFile(_In_ LPCWSTR szFileName) pHeader = (PINFO2_HEADER)MapViewOfFile(m_hInfoMapped, FILE_MAP_WRITE, 0, 0, 0); if (!pHeader) { - hr = HRESULT_FROM_WIN32(GetLastError()); + hr = HResultFromWin32(GetLastError()); goto cleanup; } @@ -297,7 +308,7 @@ STDMETHODIMP RecycleBin5::DeleteFile(_In_ LPCWSTR szFileName) FileSize.u.LowPart = GetFileSize(m_hInfo, &FileSize.u.HighPart); if (FileSize.u.LowPart < sizeof(INFO2_HEADER)) { - hr = HRESULT_FROM_WIN32(GetLastError()); + hr = HResultFromWin32(GetLastError()); goto cleanup; } dwEntries = (DWORD)((FileSize.QuadPart - sizeof(INFO2_HEADER)) / sizeof(DELETED_FILE_RECORD)) - 1; @@ -307,14 +318,14 @@ STDMETHODIMP RecycleBin5::DeleteFile(_In_ LPCWSTR szFileName) #if 0 if (!GetFileSizeEx(hFile, (PLARGE_INTEGER)&FileSize)) { - hr = HRESULT_FROM_WIN32(GetLastError()); + hr = HResultFromWin32(GetLastError()); goto cleanup; } #else FileSize.u.LowPart = GetFileSize(hFile, &FileSize.u.HighPart); if (FileSize.u.LowPart == INVALID_FILE_SIZE && GetLastError() != NO_ERROR) { - hr = HRESULT_FROM_WIN32(GetLastError()); + hr = HResultFromWin32(GetLastError()); goto cleanup; } #endif @@ -350,7 +361,7 @@ STDMETHODIMP RecycleBin5::DeleteFile(_In_ LPCWSTR szFileName) /* Get cluster size */ if (!GetDiskFreeSpaceW(m_VolumePath, &SectorsPerCluster, &BytesPerSector, NULL, NULL)) { - hr = HRESULT_FROM_WIN32(GetLastError()); + hr = HResultFromWin32(GetLastError()); goto cleanup; } ClusterSize = BytesPerSector * SectorsPerCluster; @@ -359,7 +370,7 @@ STDMETHODIMP RecycleBin5::DeleteFile(_In_ LPCWSTR szFileName) GetSystemTime(&SystemTime); if (!SystemTimeToFileTime(&SystemTime, &pDeletedFile->DeletionTime)) { - hr = HRESULT_FROM_WIN32(GetLastError()); + hr = HResultFromWin32(GetLastError()); goto cleanup; } pDeletedFile->dwPhysicalFileSize = ROUND_UP(FileSize.u.LowPart, ClusterSize); @@ -373,11 +384,21 @@ STDMETHODIMP RecycleBin5::DeleteFile(_In_ LPCWSTR szFileName) goto cleanup; } + wfd.dwFileAttributes = dwAttributes; + wfd.nFileSizeLow = FileSize.u.LowPart; + GetFileTime(hFile, &wfd.ftCreationTime, &wfd.ftLastAccessTime, &wfd.ftLastWriteTime); + /* Move file */ if (MoveFileW(szFullName, DeletedFileName)) hr = S_OK; else - hr = HRESULT_FROM_WIN32(GetLastError()); + hr = HResultFromWin32(GetLastError()); + + if (SUCCEEDED(hr)) + { + RECYCLEBINFILEIDENTITY ident = { pDeletedFile->DeletionTime, DeletedFileName }; + CRecycleBin_NotifyRecycled(szFullName, &wfd, &ident); + } cleanup: if (pHeader) @@ -436,62 +457,38 @@ STDMETHODIMP RecycleBin5::Delete( _In_ LPCWSTR pDeletedFileName, _In_ DELETED_FILE_RECORD *pDeletedFile) { - ULARGE_INTEGER FileSize; - PINFO2_HEADER pHeader; - DELETED_FILE_RECORD *pRecord, *pLast; - DWORD dwEntries, i; TRACE("(%p, %s, %p)\n", this, debugstr_w(pDeletedFileName), pDeletedFile); - if (m_EnumeratorCount != 0) - return HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION); + int res = IntDeleteRecursive(pDeletedFileName); + if (!res) + return HResultFromWin32(GetLastError()); + res = RemoveFromDatabase(pDeletedFileName, pDeletedFile); + if (res == 0) + SHUpdateRecycleBinIcon(); // Full --> Empty + return res; +} - pHeader = (PINFO2_HEADER)MapViewOfFile(m_hInfoMapped, FILE_MAP_WRITE, 0, 0, 0); - if (!pHeader) - return HRESULT_FROM_WIN32(GetLastError()); +STDMETHODIMP RecycleBin5::Restore( + _In_ LPCWSTR pDeletedFileName, + _In_ DELETED_FILE_RECORD *pDeletedFile) +{ - FileSize.u.LowPart = GetFileSize(m_hInfo, &FileSize.u.HighPart); - if (FileSize.u.LowPart == 0) - { - UnmapViewOfFile(pHeader); - return HRESULT_FROM_WIN32(GetLastError()); - } - dwEntries = (DWORD)((FileSize.QuadPart - sizeof(INFO2_HEADER)) / sizeof(DELETED_FILE_RECORD)); + TRACE("(%p, %s, %p)\n", this, debugstr_w(pDeletedFileName), pDeletedFile); - pRecord = (DELETED_FILE_RECORD *)(pHeader + 1); - for (i = 0; i < dwEntries; i++) + int res = SHELL_SingleFileOperation(NULL, FO_MOVE, pDeletedFileName, pDeletedFile->FileNameW, 0); + if (res) { - if (pRecord->dwRecordUniqueId == pDeletedFile->dwRecordUniqueId) - { - /* Delete file */ - if (!IntDeleteRecursive(pDeletedFileName)) - { - UnmapViewOfFile(pHeader); - return HRESULT_FROM_WIN32(GetLastError()); - } - - /* Clear last entry in the file */ - MoveMemory(pRecord, pRecord + 1, (dwEntries - i - 1) * sizeof(DELETED_FILE_RECORD)); - pLast = pRecord + (dwEntries - i - 1); - ZeroMemory(pLast, sizeof(DELETED_FILE_RECORD)); - UnmapViewOfFile(pHeader); - - /* Resize file */ - CloseHandle(m_hInfoMapped); - SetFilePointer(m_hInfo, -(LONG)sizeof(DELETED_FILE_RECORD), NULL, FILE_END); - SetEndOfFile(m_hInfo); - m_hInfoMapped = CreateFileMappingW(m_hInfo, NULL, PAGE_READWRITE | SEC_COMMIT, 0, 0, NULL); - if (!m_hInfoMapped) - return HRESULT_FROM_WIN32(GetLastError()); - return S_OK; - } - pRecord++; + ERR("SHFileOperationW failed with 0x%x\n", res); + return E_FAIL; } - UnmapViewOfFile(pHeader); - return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); + res = RemoveFromDatabase(pDeletedFileName, pDeletedFile); + if (res == 0) + SHUpdateRecycleBinIcon(); // Full --> Empty + return res; } -STDMETHODIMP RecycleBin5::Restore( +STDMETHODIMP RecycleBin5::RemoveFromDatabase( _In_ LPCWSTR pDeletedFileName, _In_ DELETED_FILE_RECORD *pDeletedFile) { @@ -499,7 +496,6 @@ STDMETHODIMP RecycleBin5::Restore( PINFO2_HEADER pHeader; DELETED_FILE_RECORD *pRecord, *pLast; DWORD dwEntries, i; - int res; TRACE("(%p, %s, %p)\n", this, debugstr_w(pDeletedFileName), pDeletedFile); @@ -523,14 +519,6 @@ STDMETHODIMP RecycleBin5::Restore( { if (pRecord->dwRecordUniqueId == pDeletedFile->dwRecordUniqueId) { - res = SHELL_SingleFileOperation(NULL, FO_MOVE, pDeletedFileName, pDeletedFile->FileNameW, 0); - if (res) - { - ERR("SHFileOperationW failed with 0x%x\n", res); - UnmapViewOfFile(pHeader); - return E_FAIL; - } - /* Clear last entry in the file */ MoveMemory(pRecord, pRecord + 1, (dwEntries - i - 1) * sizeof(DELETED_FILE_RECORD)); pLast = pRecord + (dwEntries - i - 1); @@ -543,10 +531,9 @@ STDMETHODIMP RecycleBin5::Restore( SetEndOfFile(m_hInfo); m_hInfoMapped = CreateFileMappingW(m_hInfo, NULL, PAGE_READWRITE | SEC_COMMIT, 0, 0, NULL); if (!m_hInfoMapped) - return HRESULT_FROM_WIN32(GetLastError()); - if (dwEntries == 1) - SHUpdateRecycleBinIcon(); // Full --> Empty - return S_OK; + return HResultFromWin32(GetLastError()); + dwEntries--; + return FAILED((int)dwEntries) ? INT_MAX : dwEntries; } pRecord++; } @@ -572,7 +559,8 @@ RecycleBin5_Create( LPWSTR FileName; /* Pointer into BufferName buffer */ LPCSTR DesktopIniContents = "[.ShellClassInfo]\r\nCLSID={645FF040-5081-101B-9F08-00AA002F954E}\r\n"; INFO2_HEADER Info2Contents[] = { { 5, 0, 0, 0x320, 0 } }; - DWORD BytesToWrite, BytesWritten, Needed; + DWORD BytesToWrite, BytesWritten; + SIZE_T Needed; HANDLE hFile = INVALID_HANDLE_VALUE; HRESULT hr; @@ -636,7 +624,7 @@ RecycleBin5_Create( hr = HRESULT_FROM_WIN32(GetLastError()); goto cleanup; } - BytesToWrite = strlen(DesktopIniContents); + BytesToWrite = (UINT)strlen(DesktopIniContents); if (!WriteFile(hFile, DesktopIniContents, (DWORD)BytesToWrite, &BytesWritten, NULL)) { hr = HRESULT_FROM_WIN32(GetLastError()); diff --git a/dll/win32/shell32/shellrecyclebin/recyclebin_v5.h b/dll/win32/shell32/shellrecyclebin/recyclebin_v5.h index f33b3adbe540c..a55286bc7a25e 100644 --- a/dll/win32/shell32/shellrecyclebin/recyclebin_v5.h +++ b/dll/win32/shell32/shellrecyclebin/recyclebin_v5.h @@ -28,7 +28,7 @@ typedef interface IRecycleBin5 IRecycleBin5; EXTERN_C const IID IID_IRecycleBin5; #define INTERFACE IRecycleBin5 -DECLARE_INTERFACE_(IRecycleBin5, IUnknown) +DECLARE_INTERFACE_(IRecycleBin5, IRecycleBin) { BEGIN_INTERFACE @@ -41,6 +41,7 @@ DECLARE_INTERFACE_(IRecycleBin5, IUnknown) STDMETHOD(DeleteFile)(THIS_ IN LPCWSTR szFileName) PURE; STDMETHOD(EmptyRecycleBin)(THIS); STDMETHOD(EnumObjects)(THIS_ OUT IRecycleBinEnumList **ppEnumList) PURE; + STDMETHOD(GetDirectory)(THIS_ LPWSTR szPath) PURE; /* IRecycleBin5 interface */ STDMETHOD(Delete)( @@ -51,6 +52,10 @@ DECLARE_INTERFACE_(IRecycleBin5, IUnknown) THIS_ IN LPCWSTR pDeletedFileName, IN DELETED_FILE_RECORD *pDeletedFile) PURE; + STDMETHOD(RemoveFromDatabase)( + THIS_ + IN LPCWSTR pDeletedFileName, + IN DELETED_FILE_RECORD *pDeletedFile) PURE; STDMETHOD(OnClosing)( THIS_ IN IRecycleBinEnumList *prbel) PURE; diff --git a/dll/win32/shell32/shellrecyclebin/recyclebin_v5_enumerator.cpp b/dll/win32/shell32/shellrecyclebin/recyclebin_v5_enumerator.cpp index ff2593fe84d40..b9f1ff74a63a2 100644 --- a/dll/win32/shell32/shellrecyclebin/recyclebin_v5_enumerator.cpp +++ b/dll/win32/shell32/shellrecyclebin/recyclebin_v5_enumerator.cpp @@ -28,15 +28,21 @@ class RecycleBin5File : public IRecycleBinFile STDMETHODIMP_(ULONG) Release() override; /* IRecycleBinFile methods */ + STDMETHODIMP IsEqualIdentity(const RECYCLEBINFILEIDENTITY *pFI) override + { + RECYCLEBINFILEIDENTITY self = { m_deletedFile.DeletionTime, m_FullName }; + return RecycleBinGeneric_IsEqualFileIdentity(pFI, &self) ? S_OK : S_FALSE; + } + STDMETHODIMP GetInfo(PDELETED_FILE_INFO pInfo) override; STDMETHODIMP GetLastModificationTime(FILETIME *pLastModificationTime) override; STDMETHODIMP GetDeletionTime(FILETIME *pDeletionTime) override; STDMETHODIMP GetFileSize(ULARGE_INTEGER *pFileSize) override; STDMETHODIMP GetPhysicalFileSize(ULARGE_INTEGER *pPhysicalFileSize) override; STDMETHODIMP GetAttributes(DWORD *pAttributes) override; STDMETHODIMP GetFileName(SIZE_T BufferSize, LPWSTR Buffer, SIZE_T *RequiredSize) override; - STDMETHODIMP GetTypeName(SIZE_T BufferSize, LPWSTR Buffer, SIZE_T *RequiredSize) override; STDMETHODIMP Delete() override; STDMETHODIMP Restore() override; + STDMETHODIMP RemoveFromDatabase() override; protected: LONG m_ref; @@ -53,14 +59,8 @@ STDMETHODIMP RecycleBin5File::QueryInterface(REFIID riid, void **ppvObject) return E_POINTER; if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IRecycleBinFile)) - *ppvObject = static_cast(this); - else if (IsEqualIID(riid, IID_IExtractIconA) || IsEqualIID(riid, IID_IExtractIconW)) { - DWORD dwAttributes; - if (GetAttributes(&dwAttributes) == S_OK) - return SHCreateFileExtractIconW(m_FullName, dwAttributes, riid, ppvObject); - else - return S_FALSE; + *ppvObject = static_cast(this); } else { @@ -94,13 +94,29 @@ STDMETHODIMP_(ULONG) RecycleBin5File::Release() return refCount; } +STDMETHODIMP RecycleBin5File::GetInfo(PDELETED_FILE_INFO pInfo) +{ + HRESULT hr = S_OK; + ULARGE_INTEGER uli; + if (FAILED(GetLastModificationTime(&pInfo->LastModification))) + ZeroMemory(&pInfo->LastModification, sizeof(pInfo->LastModification)); + pInfo->DeletionTime = m_deletedFile.DeletionTime; + C_ASSERT(sizeof(pInfo->FileSize) <= sizeof(UINT)); + pInfo->FileSize = FAILED(GetFileSize(&uli)) ? INVALID_FILE_SIZE : uli.LowPart; + if (FAILED(hr = GetAttributes(&pInfo->Attributes))) + pInfo->Attributes = 0; + InitializeRecycleBinStringRef(&pInfo->OriginalFullPath, m_deletedFile.FileNameW); + InitializeRecycleBinStringRef(&pInfo->RecycledFullPath, m_FullName); + return hr; +} + STDMETHODIMP RecycleBin5File::GetLastModificationTime(FILETIME *pLastModificationTime) { TRACE("(%p, %p)\n", this, pLastModificationTime); DWORD dwAttributes = ::GetFileAttributesW(m_FullName); if (dwAttributes == INVALID_FILE_ATTRIBUTES) - return HRESULT_FROM_WIN32(GetLastError()); + return HResultFromWin32(GetLastError()); HANDLE hFile; hFile = CreateFileW(m_FullName, @@ -112,13 +128,13 @@ STDMETHODIMP RecycleBin5File::GetLastModificationTime(FILETIME *pLastModificatio (dwAttributes & FILE_ATTRIBUTE_DIRECTORY) ? FILE_FLAG_BACKUP_SEMANTICS : 0, NULL); if (hFile == INVALID_HANDLE_VALUE) - return HRESULT_FROM_WIN32(GetLastError()); + return HResultFromWin32(GetLastError()); HRESULT hr; if (GetFileTime(hFile, NULL, NULL, pLastModificationTime)) hr = S_OK; else - hr = HRESULT_FROM_WIN32(GetLastError()); + hr = HResultFromWin32(GetLastError()); CloseHandle(hFile); return hr; } @@ -174,7 +190,7 @@ STDMETHODIMP RecycleBin5File::GetAttributes(DWORD *pAttributes) dwAttributes = GetFileAttributesW(m_FullName); if (dwAttributes == INVALID_FILE_ATTRIBUTES) - return HRESULT_FROM_WIN32(GetLastError()); + return HResultFromWin32(GetLastError()); *pAttributes = dwAttributes; return S_OK; @@ -199,36 +215,6 @@ STDMETHODIMP RecycleBin5File::GetFileName(SIZE_T BufferSize, LPWSTR Buffer, SIZE return S_OK; } -STDMETHODIMP RecycleBin5File::GetTypeName(SIZE_T BufferSize, LPWSTR Buffer, SIZE_T *RequiredSize) -{ - HRESULT hr; - DWORD dwRequired; - DWORD dwAttributes; - SHFILEINFOW shFileInfo; - - TRACE("(%p, %u, %p, %p)\n", this, BufferSize, Buffer, RequiredSize); - - hr = GetAttributes(&dwAttributes); - if (!SUCCEEDED(hr)) - return hr; - - hr = SHGetFileInfoW(m_FullName, dwAttributes, &shFileInfo, sizeof(shFileInfo), SHGFI_TYPENAME | SHGFI_USEFILEATTRIBUTES); - if (!SUCCEEDED(hr)) - return hr; - - dwRequired = (DWORD)(wcslen(shFileInfo.szTypeName) + 1) * sizeof(WCHAR); - if (RequiredSize) - *RequiredSize = dwRequired; - - if (BufferSize == 0 && !Buffer) - return S_OK; - - if (BufferSize < dwRequired) - return E_OUTOFMEMORY; - CopyMemory(Buffer, shFileInfo.szTypeName, dwRequired); - return S_OK; -} - STDMETHODIMP RecycleBin5File::Delete() { TRACE("(%p)\n", this); @@ -241,6 +227,12 @@ STDMETHODIMP RecycleBin5File::Restore() return m_recycleBin->Restore(m_FullName, &m_deletedFile); } +STDMETHODIMP RecycleBin5File::RemoveFromDatabase() +{ + TRACE("(%p)\n", this); + return m_recycleBin->RemoveFromDatabase(m_FullName, &m_deletedFile); +} + RecycleBin5File::RecycleBin5File() : m_ref(1) , m_recycleBin(NULL) @@ -390,7 +382,7 @@ STDMETHODIMP RecycleBin5Enum::Next(DWORD celt, IRecycleBinFile **rgelt, DWORD *p ULARGE_INTEGER FileSize; FileSize.u.LowPart = GetFileSize(m_hInfo, &FileSize.u.HighPart); if (FileSize.u.LowPart == 0) - return HRESULT_FROM_WIN32(GetLastError()); + return HResultFromWin32(GetLastError()); DWORD dwEntries = (DWORD)((FileSize.QuadPart - sizeof(INFO2_HEADER)) / sizeof(DELETED_FILE_RECORD)); @@ -455,7 +447,7 @@ RecycleBin5Enum::Init( m_hInfo = hInfo; m_pInfo = (PINFO2_HEADER)MapViewOfFile(hInfoMapped, FILE_MAP_READ, 0, 0, 0); if (!m_pInfo) - return HRESULT_FROM_WIN32(GetLastError()); + return HResultFromWin32(GetLastError()); if (m_pInfo->dwVersion != 5 || m_pInfo->dwRecordSize != sizeof(DELETED_FILE_RECORD)) return E_FAIL; diff --git a/dll/win32/shell32/shfldr.h b/dll/win32/shell32/shfldr.h index b9cd40128645e..2ab941e494c49 100644 --- a/dll/win32/shell32/shfldr.h +++ b/dll/win32/shell32/shfldr.h @@ -94,6 +94,9 @@ SHELL_GetDefaultFolderEnumSHCONTF(); BOOL SHELL_IncludeItemInFolderEnum(IShellFolder *pSF, PCUITEMID_CHILD pidl, SFGAOF Query, SHCONTF Flags); +HRESULT +SHELL_CreateAbsolutePidl(IShellFolder *pSF, PCUIDLIST_RELATIVE pidlChild, PIDLIST_ABSOLUTE *ppPidl); + HRESULT Shell_NextElement( _Inout_ LPWSTR *ppch, @@ -154,6 +157,11 @@ static __inline int SHELL32_GUIDToStringW (REFGUID guid, LPWSTR str) void SHELL_FS_ProcessDisplayFilename(LPWSTR szPath, DWORD dwFlags); BOOL SHELL_FS_HideExtension(LPCWSTR pwszPath); +static inline BOOL IsIllegalFsFileName(PCWSTR Name) +{ + return StrIsNullOrEmpty(Name) || StrPBrkW(Name, INVALID_FILETITLE_CHARACTERSW); +} + void CloseRegKeyArray(HKEY* array, UINT cKeys); LSTATUS AddClassKeyToArray(const WCHAR* szClass, HKEY* array, UINT* cKeys); LSTATUS AddClsidKeyToArray(REFCLSID clsid, HKEY* array, UINT* cKeys); diff --git a/dll/win32/shell32/shldataobject.cpp b/dll/win32/shell32/shldataobject.cpp index 3a7d651424f0a..0ee78e9f0bf8f 100644 --- a/dll/win32/shell32/shldataobject.cpp +++ b/dll/win32/shell32/shldataobject.cpp @@ -77,8 +77,9 @@ HRESULT WINAPI SHGetAttributesFromDataObject(IDataObject* pDataObject, DWORD dwA data.dwAttributes = rgfInOut & dwQueryAttributes; data.cItems = apidl.GetSize(); - hr = DataObject_SetData(pDataObject, g_DataObjectAttributes, &data, sizeof(data)); - FAILED_UNEXPECTEDLY(hr); + HRESULT hr2; + hr2 = DataObject_SetData(pDataObject, g_DataObjectAttributes, &data, sizeof(data)); + FAILED_UNEXPECTEDLY(hr2); // Report cache failure but don't fail the function } } } @@ -97,6 +98,15 @@ HRESULT WINAPI SHGetAttributesFromDataObject(IDataObject* pDataObject, DWORD dwA return hr; } +HRESULT DataObject_GetHIDACount(IDataObject *pdo) +{ + if (!pdo) + return E_INVALIDARG; + CDataObjectHIDA cida(pdo); + HRESULT hr = cida.hr(); + return SUCCEEDED(hr) ? cida->cidl : hr; +} + PIDLIST_ABSOLUTE SHELL_CIDA_ILCloneFull(_In_ const CIDA *pCIDA, _In_ UINT Index) { if (Index < pCIDA->cidl) @@ -111,3 +121,24 @@ PIDLIST_ABSOLUTE SHELL_DataObject_ILCloneFullItem(_In_ IDataObject *pDO, _In_ UI CDataObjectHIDA cida(pDO); return SUCCEEDED(cida.hr()) ? SHELL_CIDA_ILCloneFull(cida, Index) : NULL; } + +HRESULT SHELL_CloneDataObject(_In_ IDataObject *pDO, _Out_ IDataObject **ppDO) +{ + *ppDO = NULL; + CDataObjectHIDA cida(pDO); + HRESULT hr = cida.hr(); + if (SUCCEEDED(hr)) + { + CCidaChildArrayHelper items(cida); + if (FAILED(hr = items.hr())) + return hr; + hr = SHCreateFileDataObject(HIDA_GetPIDLFolder(cida), cida->cidl, items.GetItems(), NULL, ppDO); + if (SUCCEEDED(hr)) + { + POINT pt; + if (SUCCEEDED(DataObject_GetOffset(pDO, &pt))) + DataObject_SetOffset(*ppDO, &pt); + } + } + return hr; +} diff --git a/dll/win32/shell32/shlexec.cpp b/dll/win32/shell32/shlexec.cpp index 3a665288535d9..6010c4a462067 100644 --- a/dll/win32/shell32/shlexec.cpp +++ b/dll/win32/shell32/shlexec.cpp @@ -197,11 +197,9 @@ static void ParseTildeEffect(PWSTR &res, LPCWSTR &args, DWORD &len, DWORD &used, static BOOL SHELL_ArgifyW(WCHAR* out, DWORD len, const WCHAR* fmt, const WCHAR* lpFile, LPITEMIDLIST pidl, LPCWSTR args, DWORD* out_len, const WCHAR* lpDir) { - WCHAR xlpFile[1024]; BOOL done = FALSE; BOOL found_p1 = FALSE; PWSTR res = out; - PCWSTR cmd; DWORD used = 0; bool tildeEffect = false; @@ -279,20 +277,14 @@ static BOOL SHELL_ArgifyW(WCHAR* out, DWORD len, const WCHAR* fmt, const WCHAR* break; case '1': - if (!done || (*fmt == '1')) + if ((!done || (*fmt == '1')) && lpFile) { - /*FIXME Is the call to SearchPathW() really needed? We already have separated out the parameter string in args. */ - if (SearchPathW(lpDir, lpFile, L".exe", ARRAY_SIZE(xlpFile), xlpFile, NULL)) - cmd = xlpFile; - else - cmd = lpFile; - - SIZE_T cmdlen = wcslen(cmd); - used += cmdlen; + SIZE_T filelen = wcslen(lpFile); + used += filelen; if (used < len) { - wcscpy(res, cmd); - res += cmdlen; + wcscpy(res, lpFile); + res += filelen; } } found_p1 = TRUE; @@ -756,8 +748,10 @@ static UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpVerb, WCHAR wBuffer[256]; /* Used to GetProfileString */ UINT retval = SE_ERR_NOASSOC; WCHAR *tok; /* token pointer */ - WCHAR xlpFile[256]; /* result of SearchPath */ + WCHAR xlpFile[MAX_PATH]; /* result of PathResolve */ DWORD attribs; /* file attributes */ + WCHAR curdir[MAX_PATH]; + const WCHAR *search_paths[3] = {0}; TRACE("%s\n", debugstr_w(lpFile)); @@ -782,17 +776,38 @@ static UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpVerb, return 33; } - if (SearchPathW(lpPath, lpFile, L".exe", ARRAY_SIZE(xlpFile), xlpFile, NULL)) + GetCurrentDirectoryW(ARRAY_SIZE(curdir), curdir); + if (lpPath && *lpPath) { - TRACE("SearchPathW returned non-zero\n"); - lpFile = xlpFile; - /* The file was found in the application-supplied default directory (or the system search path) */ + search_paths[0] = lpPath; + search_paths[1] = curdir; } - else if (lpPath && SearchPathW(NULL, lpFile, L".exe", ARRAY_SIZE(xlpFile), xlpFile, NULL)) + else { - TRACE("SearchPathW returned non-zero\n"); + search_paths[0] = curdir; + } + + lstrcpyW(xlpFile, lpFile); + if (PathResolveW(xlpFile, search_paths, PRF_TRYPROGRAMEXTENSIONS | PRF_VERIFYEXISTS) || + PathFindOnPathW(xlpFile, search_paths)) + { + TRACE("PathResolveW returned non-zero\n"); lpFile = xlpFile; - /* The file was found in one of the directories in the system-wide search path */ + PathRemoveBlanksW(xlpFile); + + /* Clear any trailing periods */ + SIZE_T i = wcslen(xlpFile); + while (i > 0 && xlpFile[i - 1] == '.') + { + xlpFile[--i] = '\0'; + } + + lstrcpyW(lpResult, xlpFile); + /* The file was found in lpPath or one of the directories in the system-wide search path */ + } + else + { + xlpFile[0] = '\0'; } attribs = GetFileAttributesW(lpFile); @@ -932,7 +947,7 @@ static UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpVerb, } } - TRACE("returning %s\n", debugstr_w(lpResult)); + TRACE("returning path %s, retval %d\n", debugstr_w(lpResult), retval); return retval; } @@ -1390,14 +1405,7 @@ static HRESULT shellex_get_dataobj( LPSHELLEXECUTEINFOW sei, CComPtr shf; - LPCITEMIDLIST pidllast = NULL; - HRESULT hr = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &shf), &pidllast); - if (FAILED_UNEXPECTEDLY(hr)) - return hr; - - return shf->GetUIObjectOf(NULL, 1, &pidllast, IID_NULL_PPV_ARG(IDataObject, &dataObj)); + return SHELL_GetUIObjectOfAbsoluteItem(NULL, pidl, IID_PPV_ARG(IDataObject, &dataObj)); } static HRESULT shellex_run_context_menu_default(IShellExtInit *obj, @@ -1453,7 +1461,7 @@ static HRESULT shellex_run_context_menu_default(IShellExtInit *obj, memset(&ici, 0, sizeof ici); ici.cbSize = sizeof ici; - ici.fMask = CMIC_MASK_UNICODE | (sei->fMask & (SEE_MASK_NO_CONSOLE | SEE_MASK_NOASYNC | SEE_MASK_ASYNCOK | SEE_MASK_FLAG_NO_UI)); + ici.fMask = (sei->fMask & SEE_CMIC_COMMON_BASICFLAGS) | CMIC_MASK_UNICODE; ici.nShow = sei->nShow; ici.lpVerb = MAKEINTRESOURCEA(def); ici.hwnd = sei->hwnd; @@ -1582,6 +1590,7 @@ static HRESULT ShellExecute_ContextMenuVerb(LPSHELLEXECUTEINFOW sei) enum { idFirst = 1, idLast = 0x7fff }; HMENU hMenu = CreatePopupMenu(); + // Note: Windows does not pass CMF_EXTENDEDVERBS so "hidden" verbs cannot be executed hr = cm->QueryContextMenu(hMenu, 0, idFirst, idLast, fDefault ? CMF_DEFAULTONLY : 0); if (!FAILED_UNEXPECTEDLY(hr)) { @@ -1785,7 +1794,7 @@ SHELL_InvokePidl( // Invoke a command CMINVOKECOMMANDINFO ici = { sizeof(ici) }; - ici.fMask = (sei->fMask & (SEE_MASK_NO_CONSOLE | SEE_MASK_ASYNCOK | SEE_MASK_FLAG_NO_UI)); + ici.fMask = (sei->fMask & SEE_CMIC_COMMON_BASICFLAGS) & ~CMIC_MASK_UNICODE; // FIXME: Unicode? ici.nShow = sei->nShow; ici.hwnd = sei->hwnd; char szVerb[VERBKEY_CCHMAX]; @@ -2067,10 +2076,10 @@ static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc) if (sei_tmp.fMask & SEE_MASK_IDLIST && (sei_tmp.fMask & SEE_MASK_INVOKEIDLIST) != SEE_MASK_INVOKEIDLIST) { - CComPtr pSEH; - - HRESULT hr = SHBindToParent((LPCITEMIDLIST)sei_tmp.lpIDList, IID_PPV_ARG(IShellExecuteHookW, &pSEH), NULL); + LPCITEMIDLIST pidl = (LPCITEMIDLIST)sei_tmp.lpIDList; + CComPtr pSEH; + HRESULT hr = SHBindToParent(pidl, IID_PPV_ARG(IShellExecuteHookW, &pSEH), NULL); if (SUCCEEDED(hr)) { hr = pSEH->Execute(&sei_tmp); @@ -2078,7 +2087,14 @@ static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc) return TRUE; } - SHGetPathFromIDListW((LPCITEMIDLIST)sei_tmp.lpIDList, wszApplicationName); + hr = SHGetNameAndFlagsW(pidl, SHGDN_FORPARSING, wszApplicationName, dwApplicationNameLen, NULL); + if (FAILED(hr)) + { + if (dwApplicationNameLen) + *wszApplicationName = UNICODE_NULL; + if (!_ILIsDesktop(pidl)) + TRACE("Unable to get PIDL parsing path\n"); + } appKnownSingular = TRUE; TRACE("-- idlist=%p (%s)\n", sei_tmp.lpIDList, debugstr_w(wszApplicationName)); } @@ -2347,6 +2363,8 @@ HINSTANCE WINAPI ShellExecuteA(HWND hWnd, LPCSTR lpVerb, LPCSTR lpFile, sei.dwHotKey = 0; sei.hProcess = 0; + if (!(SHGetAppCompatFlags(SHACF_WIN95SHLEXEC) & SHACF_WIN95SHLEXEC)) + sei.fMask |= SEE_MASK_NOASYNC; ShellExecuteExA(&sei); return sei.hInstApp; } @@ -2485,9 +2503,6 @@ ShellExecuteExW(LPSHELLEXECUTEINFOW sei) /************************************************************************* * ShellExecuteW [SHELL32.294] - * from shellapi.h - * WINSHELLAPI HINSTANCE APIENTRY ShellExecuteW(HWND hwnd, LPCWSTR lpVerb, - * LPCWSTR lpFile, LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd); */ HINSTANCE WINAPI ShellExecuteW(HWND hwnd, LPCWSTR lpVerb, LPCWSTR lpFile, LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd) @@ -2509,7 +2524,9 @@ HINSTANCE WINAPI ShellExecuteW(HWND hwnd, LPCWSTR lpVerb, LPCWSTR lpFile, sei.dwHotKey = 0; sei.hProcess = 0; - SHELL_execute(&sei, SHELL_ExecuteW); + if (!(SHGetAppCompatFlags(SHACF_WIN95SHLEXEC) & SHACF_WIN95SHLEXEC)) + sei.fMask |= SEE_MASK_NOASYNC; + ShellExecuteExW(&sei); return sei.hInstApp; } @@ -2958,3 +2975,210 @@ RealShellExecuteW( lphProcess, 0); } + +/************************************************************************* + * PathProcessCommandW [Internal] + * + * @see https://learn.microsoft.com/en-us/windows/win32/api/shlobj/nf-shlobj-pathprocesscommand + * @see ./wine/shellpath.c + */ +EXTERN_C LONG +PathProcessCommandW( + _In_ PCWSTR pszSrc, + _Out_writes_opt_(dwBuffSize) PWSTR pszDest, + _In_ INT cchDest, + _In_ DWORD dwFlags) +{ + TRACE("%s, %p, %d, 0x%X\n", wine_dbgstr_w(pszSrc), pszDest, cchDest, dwFlags); + + if (!pszSrc) + return -1; + + CStringW szPath; + PCWSTR pchArg = NULL; + + if (*pszSrc == L'"') // Quoted? + { + ++pszSrc; + + PCWSTR pch = wcschr(pszSrc, L'"'); + if (pch) + { + szPath.SetString(pszSrc, pch - pszSrc); + pchArg = pch + 1; + } + else + { + szPath = pszSrc; + } + + if ((dwFlags & PPCF_FORCEQUALIFY) || PathIsRelativeW(szPath)) + { + BOOL ret = PathResolveW(szPath.GetBuffer(MAX_PATH), NULL, PRF_TRYPROGRAMEXTENSIONS); + szPath.ReleaseBuffer(); + if (!ret) + return -1; + } + } + else // Not quoted? + { + BOOL resolved = FALSE; + BOOL resolveRelative = PathIsRelativeW(pszSrc) || (dwFlags & PPCF_FORCEQUALIFY); + INT cchPath = 0; + + for (INT ich = 0; ; ++ich) + { + szPath += pszSrc[ich]; + + if (pszSrc[ich] && pszSrc[ich] != L' ') + continue; + + szPath = szPath.Left(ich); + + if (resolveRelative && + !PathResolveW(szPath.GetBuffer(MAX_PATH), NULL, PRF_TRYPROGRAMEXTENSIONS)) + { + szPath.ReleaseBuffer(); + szPath += pszSrc[ich]; + } + else + { + szPath.ReleaseBuffer(); + + DWORD attrs = GetFileAttributesW(szPath); + if (attrs != INVALID_FILE_ATTRIBUTES && + (!(attrs & FILE_ATTRIBUTE_DIRECTORY) || !(dwFlags & PPCF_NODIRECTORIES))) + { + resolved = TRUE; + pchArg = pszSrc + ich; + + if (!(dwFlags & PPCF_LONGESTPOSSIBLE)) + break; + + cchPath = ich; + break; + } + else if (!resolveRelative) + { + szPath += pszSrc[ich]; + } + } + + if (!szPath[ich]) + { + szPath.ReleaseBuffer(); // Remove excessive '\0' + break; + } + } + + if (!resolved) + return -1; + + if (cchPath && (dwFlags & PPCF_LONGESTPOSSIBLE)) + { + szPath = szPath.Left(cchPath); + pchArg = pszSrc + cchPath; + } + } + + BOOL needsQuoting = (dwFlags & PPCF_ADDQUOTES) && wcschr(szPath, L' '); + CStringW result = needsQuoting ? (L"\"" + szPath + L"\"") : szPath; + + if (pchArg && (dwFlags & PPCF_ADDARGUMENTS)) + result += pchArg; + + LONG requiredSize = result.GetLength() + 1; + if (!pszDest) + return requiredSize; + + if (requiredSize > cchDest || StringCchCopyW(pszDest, cchDest, result) != S_OK) + return -1; + + return requiredSize; +} + +// The common helper of ShellExec_RunDLLA and ShellExec_RunDLLW +static VOID +ShellExec_RunDLL_Helper( + _In_opt_ HWND hwnd, + _In_opt_ HINSTANCE hInstance, + _In_ PCWSTR pszCmdLine, + _In_ INT nCmdShow) +{ + TRACE("(%p, %p, %s, 0x%X)\n", hwnd, hInstance, wine_dbgstr_w(pszCmdLine), nCmdShow); + + if (!pszCmdLine || !*pszCmdLine) + return; + + // '?' enables us to specify the additional mask value + ULONG fNewMask = SEE_MASK_NOASYNC; + if (*pszCmdLine == L'?') // 1st question + { + INT MaskValue; + if (StrToIntExW(pszCmdLine + 1, STIF_SUPPORT_HEX, &MaskValue)) + fNewMask |= MaskValue; + + PCWSTR pch2ndQuestion = StrChrW(pszCmdLine + 1, L'?'); // 2nd question + if (pch2ndQuestion) + pszCmdLine = pch2ndQuestion + 1; + } + + WCHAR szPath[2 * MAX_PATH]; + DWORD dwFlags = PPCF_FORCEQUALIFY | PPCF_INCLUDEARGS | PPCF_ADDQUOTES; + if (PathProcessCommandW(pszCmdLine, szPath, _countof(szPath), dwFlags) == -1) + StrCpyNW(szPath, pszCmdLine, _countof(szPath)); + + // Split arguments from the path + LPWSTR Args = PathGetArgsW(szPath); + if (*Args) + *(Args - 1) = UNICODE_NULL; + + PathUnquoteSpacesW(szPath); + + // Execute + SHELLEXECUTEINFOW execInfo = { sizeof(execInfo) }; + execInfo.fMask = fNewMask; + execInfo.hwnd = hwnd; + execInfo.lpFile = szPath; + execInfo.lpParameters = Args; + execInfo.nShow = nCmdShow; + if (!ShellExecuteExW(&execInfo)) + { + DWORD dwError = GetLastError(); + if (SHELL_InRunDllProcess()) // Is it a RUNDLL process? + ExitProcess(dwError); // Terminate it now + } +} + +/************************************************************************* + * ShellExec_RunDLLA [SHELL32.358] + * + * @see https://www.hexacorn.com/blog/2024/11/30/1-little-known-secret-of-shellexec_rundll/ + */ +EXTERN_C +VOID WINAPI +ShellExec_RunDLLA( + _In_opt_ HWND hwnd, + _In_opt_ HINSTANCE hInstance, + _In_ PCSTR pszCmdLine, + _In_ INT nCmdShow) +{ + CStringW strCmdLine = pszCmdLine; // Keep + ShellExec_RunDLL_Helper(hwnd, hInstance, strCmdLine, nCmdShow); +} + +/************************************************************************* + * ShellExec_RunDLLW [SHELL32.359] + * + * @see https://www.hexacorn.com/blog/2024/11/30/1-little-known-secret-of-shellexec_rundll/ + */ +EXTERN_C +VOID WINAPI +ShellExec_RunDLLW( + _In_opt_ HWND hwnd, + _In_opt_ HINSTANCE hInstance, + _In_ PCWSTR pszCmdLine, + _In_ INT nCmdShow) +{ + ShellExec_RunDLL_Helper(hwnd, hInstance, pszCmdLine, nCmdShow); +} diff --git a/dll/win32/shell32/shlfileop.cpp b/dll/win32/shell32/shlfileop.cpp index f26d54ecc6805..9b8d7b06f6d03 100644 --- a/dll/win32/shell32/shlfileop.cpp +++ b/dll/win32/shell32/shlfileop.cpp @@ -45,6 +45,10 @@ typedef struct ULARGE_INTEGER completedSize; ULARGE_INTEGER totalSize; WCHAR szBuilderString[50]; + FILEOPCALLBACK Callback; + void *CallerCallbackData; + HWND hWndOwner; + BOOL bHasDisplayedError; } FILE_OPERATION; #define ERROR_SHELL_INTERNAL_FILE_NOT_FOUND 1026 @@ -82,6 +86,45 @@ static DWORD move_files(FILE_OPERATION *op, BOOL multiDest, const FILE_LIST *flF DWORD WINAPI _FileOpCountManager(FILE_OPERATION *op, const FILE_LIST *flFrom); static BOOL _FileOpCount(FILE_OPERATION *op, LPWSTR pwszBuf, BOOL bFolder, DWORD *ticks); +static HRESULT SHELL32_FileOpErrorToHResult(int err, BOOL AnyOperationsAborted = FALSE) +{ + enum { de_min = DE_SAMEFILE, de_max = 0xB7 /*DE_ERROR_MAX*/ }; + const bool IsDeErr = (err & ~ERRORONDEST) >= de_min && (err & ~ERRORONDEST) <= de_max; + if (err == DE_OPCANCELLED || AnyOperationsAborted) + return HRESULT_FROM_WIN32(ERROR_CANCELLED); + if (err == DE_ACCESSDENIEDSRC) + return HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED); + if (err == DE_FILENAMETOOLONG) + return HRESULT_FROM_WIN32(ERROR_FILENAME_EXCED_RANGE); + if (err == ERROR_SHELL_INTERNAL_FILE_NOT_FOUND) + return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); + if (err == ERROR_ALREADY_EXISTS) + return HRESULT_FROM_WIN32(err); + return IsDeErr ? E_FAIL : HRESULT_FROM_WIN32(err); +} + +static BOOL CanShowFileOpErrorUI(const SHFILEOPSTRUCTW &fos) +{ + if ((fos.fFlags & FOF_SILENT) && !fos.hwnd) + return FALSE; + return !(fos.fFlags & FOF_NOERRORUI); +} + +static void HandleDesktopIniOp(PCWSTR Path) +{ + // Refresh the parent folder if somebody changes the desktop.ini inside + PCWSTR Name = PathFindFileNameW(Path); + if ((Name[0] | 32) != 'd' || _wcsicmp(Name, L"desktop.ini")) + return; + WCHAR Dir[MAX_PATH]; + if (FAILED_UNEXPECTEDLY(StringCchCopyW(Dir, _countof(Dir), Path))) + return; + PathRemoveFileSpecW(Dir); + if (!(GetFileAttributesW(Dir) & (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_READONLY))) + return; + SHChangeNotify(SHCNE_UPDATEITEM, SHCNF_PATHW, Dir, NULL); +} + /* Confirm dialogs with an optional "Yes To All" as used in file operations confirmations */ struct confirm_msg_info @@ -361,6 +404,32 @@ EXTERN_C HRESULT WINAPI SHIsFileAvailableOffline(LPCWSTR path, LPDWORD status) return E_FAIL; } +static HRESULT FileOpCallback(FILE_OPERATION *op, FILEOPCALLBACKEVENT Event, LPCWSTR Source, + LPCWSTR Destination, UINT Attributes, HRESULT hrOp = S_OK) +{ + if ((Attributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM)) == FILE_ATTRIBUTE_SYSTEM) + { + if (Event == FOCE_POSTDELETEITEM) + HandleDesktopIniOp(Source); + if (Event == FOCE_POSTCOPYITEM) + HandleDesktopIniOp(Destination); + if (Event == FOCE_POSTMOVEITEM || Event == FOCE_POSTRENAMEITEM) + { + HandleDesktopIniOp(Source); + HandleDesktopIniOp(Destination); + } + } + + HRESULT hr = S_OK; + if (op->Callback) + { + hr = op->Callback(Event, Source, Destination, Attributes, hrOp, op->CallerCallbackData); + if (hr == HRESULT_FROM_WIN32(ERROR_CANCELLED)) + op->bCancelled = TRUE; + } + return hr; +} + /************************************************************************** * SHELL_DeleteDirectory() [internal] * @@ -380,7 +449,10 @@ BOOL SHELL_DeleteDirectoryW(FILE_OPERATION *op, LPCWSTR pszDir, BOOL bShowUI) if (hFind == INVALID_HANDLE_VALUE) return FALSE; - if (!bShowUI || (ret = SHELL_ConfirmDialogW(op->req->hwnd, ASK_DELETE_FOLDER, pszDir, NULL))) + if (FAILED(FileOpCallback(op, FOCE_PREDELETEITEM, pszDir, NULL, wfd.dwFileAttributes))) + return FALSE; + + if (!bShowUI || (ret = SHELL_ConfirmDialogW(op->hWndOwner, ASK_DELETE_FOLDER, pszDir, NULL))) { do { @@ -399,6 +471,7 @@ BOOL SHELL_DeleteDirectoryW(FILE_OPERATION *op, LPCWSTR pszDir, BOOL bShowUI) FindClose(hFind); if (ret) ret = (SHNotifyRemoveDirectoryW(pszDir) == ERROR_SUCCESS); + FileOpCallback(op, FOCE_POSTDELETEITEM, pszDir, NULL, wfd.dwFileAttributes, ret ? S_OK : E_FAIL); return ret; } @@ -622,7 +695,11 @@ static DWORD SHNotifyDeleteFileW(FILE_OPERATION *op, LPCWSTR path) tmp.u.HighPart = wfd.nFileSizeHigh; FileSize.QuadPart = tmp.QuadPart; } + UINT attrib = hFile != INVALID_HANDLE_VALUE ? wfd.dwFileAttributes : 0; + BOOL aborted = FAILED(FileOpCallback(op, FOCE_PREDELETEITEM, path, NULL, attrib)); FindClose(hFile); + if (aborted) + return ERROR_CANCELLED; ret = DeleteFileW(path); if (!ret) @@ -633,6 +710,7 @@ static DWORD SHNotifyDeleteFileW(FILE_OPERATION *op, LPCWSTR path) if (SetFileAttributesW(path, dwAttr & ~(FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM))) ret = DeleteFileW(path); } + FileOpCallback(op, FOCE_POSTDELETEITEM, path, NULL, attrib, ret ? S_OK : E_FAIL); if (ret) { // Bit of a hack to make the progress bar move. We don't have progress inside the file, so inform when done. @@ -675,8 +753,8 @@ static DWORD CheckForError(FILE_OPERATION *op, DWORD error, LPCWSTR src) CStringW strTitle, strMask, strText; LPWSTR lpMsgBuffer; - if (error == ERROR_SUCCESS || (op->req->fFlags & (FOF_NOERRORUI | FOF_SILENT))) - goto exit; + if (error == ERROR_SUCCESS || !CanShowFileOpErrorUI(*op->req)) + return error; strTitle.LoadStringW(op->req->wFunc == FO_COPY ? IDS_COPYERRORTITLE : IDS_MOVEERRORTITLE); @@ -692,10 +770,9 @@ static DWORD CheckForError(FILE_OPERATION *op, DWORD error, LPCWSTR src) PathFindFileNameW(src), lpMsgBuffer); - MessageBoxW(op->req->hwnd, strText, strTitle, MB_ICONERROR); + MessageBoxW(op->hWndOwner, strText, strTitle, MB_ICONERROR); LocalFree(lpMsgBuffer); - -exit: + op->bHasDisplayedError++; return error; } @@ -720,34 +797,53 @@ static DWORD SHNotifyMoveFileW(FILE_OPERATION *op, LPCWSTR src, LPCWSTR dest, BO _SetOperationTexts(op, src, dest); + const BOOL IsRen = op->req->wFunc == FO_RENAME; + UINT attrib = GetFileAttributesW(src); + if (attrib == INVALID_FILE_ATTRIBUTES) + attrib = isdir ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL; + if (FAILED(FileOpCallback(op, IsRen ? FOCE_PRERENAMEITEM : FOCE_PREMOVEITEM, src, dest, attrib))) + return ERROR_CANCELLED; + ret = MoveFileWithProgressW(src, dest, SHCopyProgressRoutine, op, MOVEFILE_REPLACE_EXISTING); /* MOVEFILE_REPLACE_EXISTING fails with dirs, so try MoveFile */ if (!ret) ret = MoveFileW(src, dest); + DWORD LastError = GetLastError(); if (!ret) { - DWORD dwAttr; - - dwAttr = SHFindAttrW(dest, FALSE); - if (INVALID_FILE_ATTRIBUTES == dwAttr) - { - /* Source file may be write protected or a system file */ - dwAttr = GetFileAttributesW(src); - if (IsAttrib(dwAttr, FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM)) - if (SetFileAttributesW(src, dwAttr & ~(FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM))) - ret = MoveFileW(src, dest); - } + DWORD dwAttr = SHFindAttrW(dest, FALSE); + if (INVALID_FILE_ATTRIBUTES == dwAttr) + { + /* Source file may be write protected or a system file */ + dwAttr = GetFileAttributesW(src); + if (IsAttrib(dwAttr, FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM)) + { + if (SetFileAttributesW(src, dwAttr & ~(FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM))) + { + ret = MoveFileW(src, dest); + LastError = GetLastError(); + SetFileAttributesW(ret ? dest : src, dwAttr); + } + } + } } + FileOpCallback(op, IsRen ? FOCE_POSTRENAMEITEM : FOCE_POSTMOVEITEM, src, dest, attrib, ret ? S_OK : E_FAIL); if (ret) { - SHChangeNotify(isdir ? SHCNE_MKDIR : SHCNE_CREATE, SHCNF_PATHW, dest, NULL); - SHChangeNotify(isdir ? SHCNE_RMDIR : SHCNE_DELETE, SHCNF_PATHW, src, NULL); + if (IsRen) + { + SHChangeNotify(isdir ? SHCNE_RENAMEFOLDER : SHCNE_RENAMEITEM, SHCNF_PATHW, src, dest); + } + else + { + SHChangeNotify(isdir ? SHCNE_MKDIR : SHCNE_CREATE, SHCNF_PATHW, dest, NULL); + SHChangeNotify(isdir ? SHCNE_RMDIR : SHCNE_DELETE, SHCNF_PATHW, src, NULL); + } return ERROR_SUCCESS; } - - return CheckForError(op, GetLastError(), src); + return CheckForError(op, LastError, src); } static BOOL SHIsCdRom(LPCWSTR path) @@ -790,6 +886,9 @@ static DWORD SHNotifyCopyFileW(FILE_OPERATION *op, LPCWSTR src, LPCWSTR dest, BO /* Destination file may already exist with read only attribute */ attribs = GetFileAttributesW(dest); + if (FAILED(FileOpCallback(op, FOCE_PRECOPYITEM, src, dest, attribs))) + return ERROR_CANCELLED; + if (IsAttrib(attribs, FILE_ATTRIBUTE_READONLY)) SetFileAttributesW(dest, attribs & ~FILE_ATTRIBUTE_READONLY); @@ -803,7 +902,9 @@ static DWORD SHNotifyCopyFileW(FILE_OPERATION *op, LPCWSTR src, LPCWSTR dest, BO } ret = CopyFileExW(src, dest, SHCopyProgressRoutine, op, &op->bCancelled, bFailIfExists); - if (ret) + const DWORD error = ret ? 0 : GetLastError(); + FileOpCallback(op, FOCE_POSTCOPYITEM, src, dest, attribs, HRESULT_FROM_WIN32(error)); + if (!error) { // We are copying from a CD-ROM volume, which is readonly if (SHIsCdRom(src)) @@ -816,8 +917,7 @@ static DWORD SHNotifyCopyFileW(FILE_OPERATION *op, LPCWSTR src, LPCWSTR dest, BO SHChangeNotify(SHCNE_CREATE, SHCNF_PATHW, dest, NULL); return ERROR_SUCCESS; } - - return CheckForError(op, GetLastError(), src); + return CheckForError(op, error, src); } /************************************************************************* @@ -1347,7 +1447,7 @@ static void copy_dir_to_dir(FILE_OPERATION *op, const FILE_ENTRY *feFrom, LPCWST } else if (!(op->req->fFlags & FOF_NOCONFIRMATION)) { - if (!SHELL_ConfirmDialogW(op->req->hwnd, ASK_OVERWRITE_FOLDER, feFrom->szFilename, op)) + if (!SHELL_ConfirmDialogW(op->hWndOwner, ASK_OVERWRITE_FOLDER, feFrom->szFilename, op)) { /* Vista returns an ERROR_CANCELLED even if user pressed "No" */ if (!op->bManyItems) @@ -1388,7 +1488,7 @@ static BOOL copy_file_to_file(FILE_OPERATION *op, const WCHAR *szFrom, const WCH } else if (!(op->req->fFlags & FOF_NOCONFIRMATION)) { - if (!SHELL_ConfirmDialogW(op->req->hwnd, ASK_OVERWRITE_FILE, PathFindFileNameW(szTo), op)) + if (!SHELL_ConfirmDialogW(op->hWndOwner, ASK_OVERWRITE_FILE, PathFindFileNameW(szTo), op)) return FALSE; } } @@ -1600,7 +1700,7 @@ static HRESULT delete_files(FILE_OPERATION *op, const FILE_LIST *flFrom) if (bTrash && SHELL_GetSetting(SSF_NOCONFIRMRECYCLE, fNoConfirmRecycle)) confirm = FALSE; if (confirm || (!bTrash && op->req->fFlags & FOF_WANTNUKEWARNING)) - if (!confirm_delete_list(op->req->hwnd, op->req->fFlags, bTrash, flFrom)) + if (!confirm_delete_list(op->hWndOwner, op->req->fFlags, bTrash, flFrom)) { op->req->fAnyOperationsAborted = TRUE; return 0; @@ -1640,7 +1740,7 @@ static HRESULT delete_files(FILE_OPERATION *op, const FILE_LIST *flFrom) /* Note: Windows silently deletes the file in such a situation, we show a dialog */ if (!(op->req->fFlags & FOF_NOCONFIRMATION) || (op->req->fFlags & FOF_WANTNUKEWARNING)) - bDelete = SHELL_ConfirmDialogW(op->req->hwnd, ASK_CANT_TRASH_ITEM, fileEntry->szFullPath, NULL); + bDelete = SHELL_ConfirmDialogW(op->hWndOwner, ASK_CANT_TRASH_ITEM, fileEntry->szFullPath, NULL); else bDelete = TRUE; @@ -1691,6 +1791,10 @@ static void move_dir_to_dir(FILE_OPERATION *op, const FILE_ENTRY *feFrom, LPCWST if (feFrom->szFilename && IsDotDir(feFrom->szFilename)) return; + UINT attrib = FILE_ATTRIBUTE_DIRECTORY; + if (FAILED(FileOpCallback(op, FOCE_PREMOVEITEM, feFrom->szFullPath, szDestPath, attrib))) + return; + SHNotifyCreateDirectoryW(szDestPath, NULL); PathCombineW(szFrom, feFrom->szFullPath, L"*.*"); @@ -1709,8 +1813,10 @@ static void move_dir_to_dir(FILE_OPERATION *op, const FILE_ENTRY *feFrom, LPCWST destroy_file_list(&flFromNew); destroy_file_list(&flToNew); + BOOL success = FALSE; if (PathIsDirectoryEmptyW(feFrom->szFullPath)) - Win32RemoveDirectoryW(feFrom->szFullPath); + success = Win32RemoveDirectoryW(feFrom->szFullPath); + FileOpCallback(op, FOCE_POSTMOVEITEM, feFrom->szFullPath, szDestPath, attrib, success ? S_OK : E_FAIL); } static BOOL move_file_to_file(FILE_OPERATION *op, const WCHAR *szFrom, const WCHAR *szTo) @@ -1727,7 +1833,7 @@ static BOOL move_file_to_file(FILE_OPERATION *op, const WCHAR *szFrom, const WCH } else if (!(op->req->fFlags & FOF_NOCONFIRMATION)) { - if (!SHELL_ConfirmDialogW(op->req->hwnd, ASK_OVERWRITE_FILE, PathFindFileNameW(szTo), op)) + if (!SHELL_ConfirmDialogW(op->hWndOwner, ASK_OVERWRITE_FILE, PathFindFileNameW(szTo), op)) return FALSE; } } @@ -1889,15 +1995,15 @@ static void check_flags(FILEOP_FLAGS fFlags) #define GET_FILENAME(fe) ((fe)->szFilename[0] ? (fe)->szFilename : (fe)->szFullPath) static DWORD -validate_operation(LPSHFILEOPSTRUCTW lpFileOp, FILE_LIST *flFrom, FILE_LIST *flTo) +validate_operation(FILE_OPERATION &op, FILE_LIST *flFrom, FILE_LIST *flTo) { DWORD i, k, dwNumDest; WCHAR szFrom[MAX_PATH], szTo[MAX_PATH]; CStringW strTitle, strText; const FILE_ENTRY *feFrom; const FILE_ENTRY *feTo; + const SHFILEOPSTRUCTW *lpFileOp = op.req; UINT wFunc = lpFileOp->wFunc; - HWND hwnd = lpFileOp->hwnd; dwNumDest = flTo->dwNumFiles; @@ -1921,7 +2027,7 @@ validate_operation(LPSHFILEOPSTRUCTW lpFileOp, FILE_LIST *flFrom, FILE_LIST *flT if (lstrcmpiW(szFrom, szTo) == 0 && (wFunc == FO_MOVE || !(lpFileOp->fFlags & FOF_RENAMEONCOLLISION))) { - if (!(lpFileOp->fFlags & (FOF_NOERRORUI | FOF_SILENT))) + if (CanShowFileOpErrorUI(*lpFileOp)) { if (wFunc == FO_MOVE) { @@ -1937,7 +2043,8 @@ validate_operation(LPSHFILEOPSTRUCTW lpFileOp, FILE_LIST *flFrom, FILE_LIST *flT strText.Format(IDS_COPYERRORSAME, GET_FILENAME(feFrom)); return ERROR_SUCCESS; } - MessageBoxW(hwnd, strText, strTitle, MB_ICONERROR); + MessageBoxW(op.hWndOwner, strText, strTitle, MB_ICONERROR); + op.bHasDisplayedError++; return DE_SAMEFILE; } return DE_OPCANCELLED; @@ -1957,7 +2064,7 @@ validate_operation(LPSHFILEOPSTRUCTW lpFileOp, FILE_LIST *flFrom, FILE_LIST *flT if (compare == 0) { - if (!(lpFileOp->fFlags & (FOF_NOERRORUI | FOF_SILENT))) + if (CanShowFileOpErrorUI(*lpFileOp)) { if (wFunc == FO_MOVE) { @@ -1969,7 +2076,8 @@ validate_operation(LPSHFILEOPSTRUCTW lpFileOp, FILE_LIST *flFrom, FILE_LIST *flT strTitle.LoadStringW(IDS_COPYERRORTITLE); strText.Format(IDS_COPYERRORSUBFOLDER, GET_FILENAME(feFrom)); } - MessageBoxW(hwnd, strText, strTitle, MB_ICONERROR); + MessageBoxW(op.hWndOwner, strText, strTitle, MB_ICONERROR); + op.bHasDisplayedError++; return DE_DESTSUBTREE; } return DE_OPCANCELLED; @@ -1982,12 +2090,7 @@ validate_operation(LPSHFILEOPSTRUCTW lpFileOp, FILE_LIST *flFrom, FILE_LIST *flT return ERROR_SUCCESS; } -/************************************************************************* - * SHFileOperationW [SHELL32.@] - * - * See SHFileOperationA - */ -int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp) +int SHELL32_FileOperation(LPSHFILEOPSTRUCTW lpFileOp, FILEOPCALLBACK Callback, void *CallerData) { FILE_OPERATION op; FILE_LIST flFrom, flTo; @@ -2017,8 +2120,11 @@ int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp) op.totalSize.QuadPart = 0ull; op.completedSize.QuadPart = 0ull; op.bManyItems = (flFrom.dwNumFiles > 1); + op.Callback = Callback; + op.CallerCallbackData = CallerData; + op.hWndOwner = GetAncestor(lpFileOp->hwnd, GA_ROOT); - ret = validate_operation(lpFileOp, &flFrom, &flTo); + ret = validate_operation(op, &flFrom, &flTo); if (ret) goto cleanup; @@ -2030,11 +2136,13 @@ int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp) if (FAILED(ret)) goto cleanup; - op.progress->StartProgressDialog(op.req->hwnd, NULL, PROGDLG_NORMAL & PROGDLG_AUTOTIME, NULL); + op.progress->StartProgressDialog(op.hWndOwner, NULL, PROGDLG_NORMAL & PROGDLG_AUTOTIME, NULL); _SetOperationTitle(&op); _FileOpCountManager(&op, &flFrom); } + FileOpCallback(&op, FOCE_STARTOPERATIONS, NULL, NULL, 0); + switch (lpFileOp->wFunc) { case FO_COPY: @@ -2069,12 +2177,31 @@ int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp) if (ret == ERROR_CANCELLED) lpFileOp->fAnyOperationsAborted = TRUE; + if (ret == ERROR_SHELL_INTERNAL_FILE_NOT_FOUND && LOBYTE(GetVersion()) >= 6) + ret = ERROR_FILE_NOT_FOUND; + + HRESULT hr = SHELL32_FileOpErrorToHResult(ret); + TRACE("SHFO FINISHOPERATIONS %#x (%d)\n", hr, ret); + FileOpCallback(&op, FOCE_FINISHOPERATIONS, NULL, NULL, 0, hr); + + if (FAILED(hr) && CanShowFileOpErrorUI(*op.req) && !op.bHasDisplayedError) + SHELL_ErrorBox(op.hWndOwner, hr); CoUninitialize(); return ret; } +/************************************************************************* + * SHFileOperationW [SHELL32.@] + * + * See SHFileOperationA + */ +int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp) +{ + return SHELL32_FileOperation(lpFileOp, NULL, NULL); +} + // Used by SHFreeNameMappings static int CALLBACK _DestroyCallback(void *p, void *pData) { @@ -2304,6 +2431,59 @@ EXTERN_C HRESULT WINAPI SHPathPrepareForWriteA(HWND hwnd, IUnknown *modless, LPC return SHPathPrepareForWriteW(hwnd, modless, wpath, flags); } +static PWSTR SHELL_DupSZZ(PCWSTR Input) +{ + SIZE_T len = wcslen(Input), cb = (len + 2) * sizeof(*Input); + PWSTR Output = (PWSTR)SHAlloc(cb); + if (Output) + { + CopyMemory(Output, Input, cb - sizeof(*Input)); + Output[len + 1] = UNICODE_NULL; + } + return Output; +} + +HRESULT SHELL_SingleFileOperation(HWND hWnd, UINT Op, PCWSTR Src, PCWSTR Dest, UINT Flags, PWSTR *ppNewName) +{ + HRESULT hr = S_OK; + if ((Src = SHELL_DupSZZ(Src)) == NULL) + hr = E_OUTOFMEMORY; + if (Dest && (Dest = SHELL_DupSZZ(Dest)) == NULL) + hr = E_OUTOFMEMORY; + + SHFILEOPSTRUCTW fos = { hWnd, Op, Src, Dest, (FILEOP_FLAGS)Flags }; + if (ppNewName) + { + *ppNewName = NULL; + fos.fFlags |= FOF_WANTMAPPINGHANDLE; + } + + if (SUCCEEDED(hr)) + { + int err = SHFileOperationW(&fos); + hr = SHELL32_FileOpErrorToHResult(err, fos.fAnyOperationsAborted); + } + else if (CanShowFileOpErrorUI(fos)) + { + SHELL_ErrorBox(hWnd, hr); + } + SHFree(const_cast(Src)); + SHFree(const_cast(Dest)); + + if (fos.hNameMappings) + { + if (SUCCEEDED(hr) && ppNewName) + { + assert(DSA_GetItemCount((HDSA)fos.hNameMappings) == 1); + SHNAMEMAPPINGW *pMap = (SHNAMEMAPPINGW*)DSA_GetItemPtr((HDSA)fos.hNameMappings, 0); + if ((*ppNewName = SHELL_DupSZZ(pMap->pszNewPath)) == NULL) + hr = S_FALSE; + } + SHFreeNameMappings(fos.hNameMappings); + } + return hr; +} + /* * The two following background operations were modified from filedefext.cpp diff --git a/dll/win32/shell32/shlfolder.cpp b/dll/win32/shell32/shlfolder.cpp index 4e08e19f54f0a..268eadb238a73 100644 --- a/dll/win32/shell32/shlfolder.cpp +++ b/dll/win32/shell32/shlfolder.cpp @@ -54,6 +54,18 @@ BOOL SHELL_IncludeItemInFolderEnum(IShellFolder *pSF, PCUITEMID_CHILD pidl, SFGA return TRUE; } +HRESULT SHELL_CreateAbsolutePidl(IShellFolder *pSF, PCUIDLIST_RELATIVE pidlChild, PIDLIST_ABSOLUTE *ppPidl) +{ + PIDLIST_ABSOLUTE pidlFolder; + HRESULT hr = SHGetIDListFromObject(pSF, &pidlFolder); + if (SUCCEEDED(hr)) + { + hr = SHILCombine(pidlFolder, pidlChild, ppPidl); + ILFree(pidlFolder); + } + return hr; +} + HRESULT Shell_NextElement( _Inout_ LPWSTR *ppch, @@ -509,16 +521,7 @@ SHELL32_ShowPropertiesDialog(IDataObject *pdtobj) { if (!pdtobj) return E_INVALIDARG; - - CDataObjectHIDA cida(pdtobj); - if (FAILED_UNEXPECTEDLY(cida.hr())) - return cida.hr(); - if (cida->cidl > 1) - { - ERR("SHMultiFileProperties is not yet implemented\n"); - return E_FAIL; - } - return SHELL32_ShowFilesystemItemPropertiesDialogAsync(pdtobj); + return SHELL32_ShowFilesystemItemsPropertiesDialogAsync(NULL, pdtobj); } HRESULT diff --git a/dll/win32/shell32/shresdef.h b/dll/win32/shell32/shresdef.h index d4c8422d29adc..676c33c34901d 100644 --- a/dll/win32/shell32/shresdef.h +++ b/dll/win32/shell32/shresdef.h @@ -282,11 +282,22 @@ #define IDS_OBJECTS 6466 #define IDS_OBJECTS_SELECTED 6477 +/* Explorer file search */ +#define IDS_SEARCH_LOCALDRIVES 10241 +#define IDS_SEARCH_BROWSEITEM 10244 + +/* Recycle Bin Cleaner */ +#define IDS_RECYCLE_CLEANER_DISPLAYNAME 10291 +#define IDS_RECYCLE_CLEANER_DESCRIPTION 10292 +#define IDS_RECYCLE_CLEANER_BUTTON_TEXT 10293 + /* Desktop icon titles */ #define IDS_TITLE_MYCOMP 30386 #define IDS_TITLE_MYNET 30387 #define IDS_TITLE_BIN_1 30388 #define IDS_TITLE_BIN_0 30389 +#define IDS_TITLE_BIN 30390 +#define IDS_TITLE_MYFILES 30391 /* Advanced settings */ #define IDS_ADVANCED_FOLDER 30498 @@ -320,13 +331,26 @@ #define IDS_ADVANCED_DISPLAY_RUN 30474 #define IDS_ADVANCED_DISPLAY_ADMINTOOLS 30476 #define IDS_ADVANCED_SMALL_START_MENU 30477 - -#define IDS_NEWEXT_ADVANCED_LEFT 30515 -#define IDS_NEWEXT_ADVANCED_RIGHT 30516 -#define IDS_NEWEXT_NEW 30518 -#define IDS_NEWEXT_SPECIFY_EXT 30519 -#define IDS_NEWEXT_ALREADY_ASSOC 30520 -#define IDS_NEWEXT_EXT_IN_USE 30521 +/* End synchronized */ + +#define IDS_STARTPANELCFG_MYCOMPUTER 30480 +#define IDS_STARTPANELCFG_NETHOOD 30481 +#define IDS_STARTPANELCFG_CONNECTIONSFOLDER 30482 +#define IDS_STARTPANELCFG_RUN 30483 +#define IDS_STARTPANELCFG_HELP 30489 +#define IDS_STARTPANELCFG_DONTDISPLAYITEM 30492 +#define IDS_STARTPANELCFG_PRINTERS 30493 +#define IDS_STARTPANELCFG_ADMINTOOLS 30515 + +#define IDS_SEARCH_RESULTS 30520 // FIXME: Move browseui IDS_SEARCH_RESULTS to shell32 +#define IDS_SEARCH_RESULTS_COMPUTERS 30521 + +#define IDS_NEWEXT_SPECIFY_EXT 10086 +#define IDS_NEWEXT_ALREADY_ASSOC 10100 +#define IDS_NEWEXT_EXT_IN_USE 10101 +#define IDS_NEWEXT_NEW 10105 +#define IDS_NEWEXT_ADVANCED_LEFT 10109 +#define IDS_NEWEXT_ADVANCED_RIGHT 10110 #define IDS_SPECIFY_ACTION 30523 #define IDS_INVALID_PROGRAM 30524 @@ -338,7 +362,7 @@ #define IDS_REMOVE_EXT 30522 #define IDS_NO_ICONS 30529 -#define IDS_FILE_NOT_FOUND 30530 +#define IDS_FILE_NOT_FOUND 30530 // FIXME: "Animations in taskbar" #define IDS_LINK_INVALID 30531 #define IDS_COPYTOMENU 30532 #define IDS_COPYTOTITLE 30533 @@ -347,9 +371,11 @@ #define IDS_MOVETOMENU 30536 #define IDS_MOVETOTITLE 30537 #define IDS_MOVEITEMS 30538 -#define IDS_MOVEBUTTON 30539 +#define IDS_MOVEBUTTON 30539 // FIXME: "Slide open combo boxes" -#define IDS_SYSTEMFOLDER 30540 +#define IDS_SYSTEMFOLDER 30540 // FIXME: "Show translucent selection rectangle" +#define IDS_DESKTOPLABELDROPSHADOW 30541 +#define IDS_FOLDERTYPEBACKGROUNDIMAGE 30543 #define IDS_LOG_OFF_DESC 35000 #define IDS_SWITCH_USER_DESC 35001 @@ -914,3 +940,4 @@ #define IDR_COPYTOMENU 159 #define IDR_MOVETOMENU 160 #define IDR_COPYASPATHMENU 161 +#define IDR_RECYCLEBINCLEANER 162 diff --git a/dll/win32/shell32/stubs.cpp b/dll/win32/shell32/stubs.cpp index 77e674e795f9f..1cdee237d4471 100644 --- a/dll/win32/shell32/stubs.cpp +++ b/dll/win32/shell32/stubs.cpp @@ -14,50 +14,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell); -/* - * Unimplemented - */ -EXTERN_C HRESULT -WINAPI -SHGetUnreadMailCountW(HKEY hKeyUser, - LPCWSTR pszMailAddress, - DWORD *pdwCount, - FILETIME *pFileTime, - LPWSTR pszShellExecuteCommand, - int cchShellExecuteCommand) -{ - FIXME("SHGetUnreadMailCountW() stub\n"); - return E_FAIL; -} - -/* - * Unimplemented - */ -EXTERN_C HRESULT -WINAPI -SHSetUnreadMailCountW(LPCWSTR pszMailAddress, - DWORD dwCount, - LPCWSTR pszShellExecuteCommand) -{ - FIXME("SHSetUnreadMailCountW() stub\n"); - return E_FAIL; -} - -/* - * Unimplemented - */ -EXTERN_C HRESULT -WINAPI -SHEnumerateUnreadMailAccountsW(HKEY user, - DWORD idx, - LPWSTR mailaddress, - INT mailaddresslen) -{ - FIXME("SHEnumerateUnreadMailAccountsW(%p %d %p %d) stub\n", - user, idx, mailaddress, mailaddresslen); - return E_NOTIMPL; -} - /* * Unimplemented */ @@ -128,15 +84,6 @@ SHParseDarwinIDFromCacheW(LPCWSTR lpUnknown1, LPWSTR lpUnknown2) return E_FAIL; } -static HRESULT DataObject_GetHIDACount(IDataObject *pdo) -{ - if (!pdo) - return E_INVALIDARG; - CDataObjectHIDA cida(pdo); - HRESULT hr = cida.hr(); - return SUCCEEDED(hr) ? cida->cidl : hr; -} - /* * Unimplemented */ @@ -263,28 +210,6 @@ RealDriveTypeFlags(INT iDrive, BOOL bUnknown) return 1; } -/* - * Unimplemented - */ -EXTERN_C LPWSTR -WINAPI -StrRStrW(LPWSTR lpSrc, LPWSTR lpLast, LPWSTR lpSearch) -{ - FIXME("StrRStrW() stub\n"); - return NULL; -} - -/* - * Unimplemented - */ -EXTERN_C LPWSTR -WINAPI -StrRStrA(LPSTR lpSrc, LPSTR lpLast, LPSTR lpSearch) -{ - FIXME("StrRStrA() stub\n"); - return NULL; -} - /* * Unimplemented */ @@ -297,36 +222,6 @@ ShellHookProc(INT iCode, WPARAM wParam, LPARAM lParam) return 0; } -/* - * Unimplemented - */ -EXTERN_C VOID -WINAPI -ShellExec_RunDLL(HWND hwnd, HINSTANCE hInstance, LPWSTR pszCmdLine, int nCmdShow) -{ - FIXME("ShellExec_RunDLL() stub\n"); -} - -/* - * Unimplemented - */ -EXTERN_C VOID -WINAPI -ShellExec_RunDLLA(HWND hwnd, HINSTANCE hInstance, LPSTR pszCmdLine, int nCmdShow) -{ - FIXME("ShellExec_RunDLLA() stub\n"); -} - -/* - * Unimplemented - */ -EXTERN_C VOID -WINAPI -ShellExec_RunDLLW(HWND hwnd, HINSTANCE hInstance, LPWSTR pszCmdLine, int nCmdShow) -{ - FIXME("ShellExec_RunDLLW() stub\n"); -} - /* * Unimplemented */ @@ -662,17 +557,6 @@ DDECreatePostNotify(LPVOID lpUnknown) return NULL; } -/* - * Unimplemented - */ -EXTERN_C BOOL -WINAPI -SHIsBadInterfacePtr(LPVOID pv, UINT ucb) -{ - FIXME("SHIsBadInterfacePtr() stub\n"); - return FALSE; -} - /* * Unimplemented */ @@ -896,17 +780,6 @@ SHSetUserPicturePathW(LPCWSTR lpPath, int csidl, LPVOID lpUnknown) return E_FAIL; } -/* - * Unimplemented - */ -EXTERN_C BOOL -WINAPI -SHShouldShowWizards(LPVOID lpUnknown) -{ - FIXME("SHShouldShowWizards() stub\n"); - return FALSE; -} - /* * Unimplemented */ @@ -920,18 +793,6 @@ PathIsSlowW( return FALSE; } -/* - * Unimplemented - */ -EXTERN_C DWORD -WINAPI -SHGetUserDisplayName(LPWSTR lpName, PULONG puSize) -{ - FIXME("SHGetUserDisplayName() stub\n"); - wcscpy(lpName, L"UserName"); - return ERROR_SUCCESS; -} - /* * Unimplemented */ @@ -950,10 +811,3 @@ DWORD WINAPI CheckStagingArea(VOID) /* Called by native explorer */ return 0; } - -EXTERN_C -DWORD WINAPI SHGetComputerDisplayNameW(DWORD param1, DWORD param2, DWORD param3, DWORD param4) -{ - FIXME("SHGetComputerDisplayNameW() stub\n"); - return E_FAIL; -} diff --git a/dll/win32/shell32/utils.cpp b/dll/win32/shell32/utils.cpp index ce2f6f40834bd..e5f8cee941106 100644 --- a/dll/win32/shell32/utils.cpp +++ b/dll/win32/shell32/utils.cpp @@ -6,9 +6,96 @@ */ #include "precomp.h" +#include +#include +#include +#include +#include WINE_DEFAULT_DEBUG_CHANNEL(shell); +static PCSTR StrEndNA(_In_ PCSTR psz, _In_ INT_PTR cch) +{ + PCSTR pch, pchEnd = &psz[cch]; + for (pch = psz; *pch && pch < pchEnd; pch = CharNextA(pch)) + ; + if (pchEnd < pch) // A double-byte character detected at last? + pch -= 2; // The width of a double-byte character is 2 + return pch; +} + +static PCWSTR StrEndNW(_In_ PCWSTR psz, _In_ INT_PTR cch) +{ + PCWSTR pch, pchEnd = &psz[cch]; + for (pch = psz; *pch && pch < pchEnd; ++pch) + ; + return pch; +} + +/************************************************************************* + * StrRStrA [SHELL32.389] + */ +EXTERN_C +PSTR WINAPI +StrRStrA( + _In_ PCSTR pszSrc, + _In_opt_ PCSTR pszLast, + _In_ PCSTR pszSearch) +{ + INT cchSearch = lstrlenA(pszSearch); + + PCSTR pchEnd = pszLast ? pszLast : &pszSrc[lstrlenA(pszSrc)]; + if (pchEnd == pszSrc) + return NULL; + + INT_PTR cchEnd = pchEnd - pszSrc; + for (;;) + { + --pchEnd; + --cchEnd; + if (!pchEnd) + break; + if (!StrCmpNA(pchEnd, pszSearch, cchSearch) && pchEnd == StrEndNA(pszSrc, cchEnd)) + break; + if (pchEnd == pszSrc) + return NULL; + } + + return const_cast(pchEnd); +} + +/************************************************************************* + * StrRStrW [SHELL32.392] + */ +EXTERN_C +PWSTR WINAPI +StrRStrW( + _In_ PCWSTR pszSrc, + _In_opt_ PCWSTR pszLast, + _In_ PCWSTR pszSearch) +{ + INT cchSearch = lstrlenW(pszSearch); + + PCWSTR pchEnd = pszLast ? pszLast : &pszSrc[lstrlenW(pszSrc)]; + if (pchEnd == pszSrc) + return NULL; + + INT_PTR cchEnd = pchEnd - pszSrc; + for (;;) + { + --pchEnd; + --cchEnd; + if (!pchEnd) + break; + if (!StrCmpNW(pchEnd, pszSearch, cchSearch) && pchEnd == StrEndNW(pszSrc, cchEnd)) + break; + if (pchEnd == pszSrc) + return NULL; + } + + return const_cast(pchEnd); +} + HWND CStubWindow32::FindStubWindow(UINT Type, LPCWSTR Path) { @@ -118,6 +205,36 @@ HRESULT SHILAppend(_Inout_ LPITEMIDLIST pidl, _Inout_ LPITEMIDLIST *ppidl) return hr; } +/************************************************************************* + * SHShouldShowWizards [SHELL32.237] + * + * Used by printer and network features. + * @see https://undoc.airesoft.co.uk/shell32.dll/SHShouldShowWizards.php + */ +EXTERN_C +HRESULT WINAPI +SHShouldShowWizards(_In_ IUnknown *pUnknown) +{ + HRESULT hr; + IShellBrowser *pBrowser; + + hr = IUnknown_QueryService(pUnknown, SID_STopWindow, IID_PPV_ARG(IShellBrowser, &pBrowser)); + if (FAILED(hr)) + return hr; + + SHELLSTATE state; + SHGetSetSettings(&state, SSF_WEBVIEW, FALSE); + if (state.fWebView && + !SHRegGetBoolUSValueW(L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", + L"ShowWizardsTEST", FALSE, FALSE)) + { + hr = S_FALSE; + } + + pBrowser->Release(); + return hr; +} + static BOOL OpenEffectiveToken( _In_ DWORD DesiredAccess, @@ -259,8 +376,37 @@ HRESULT SHBindToObject( return SHBindToObjectEx(psf, pidl, NULL, riid, ppvObj); } -HRESULT -Shell_DisplayNameOf( +EXTERN_C HRESULT +SHELL_GetUIObjectOfAbsoluteItem( + _In_opt_ HWND hWnd, + _In_ PCIDLIST_ABSOLUTE pidl, + _In_ REFIID riid, _Out_ void **ppvObj) +{ + if (!ppvObj) + return E_INVALIDARG; + *ppvObj = NULL; + IShellFolder *psf; + PCUITEMID_CHILD pidlChild; + HRESULT hr = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &psf), &pidlChild); + if (SUCCEEDED(hr)) + { + hr = psf->GetUIObjectOf(hWnd, 1, &pidlChild, riid, NULL, ppvObj); + psf->Release(); + if (SUCCEEDED(hr)) + { + if (*ppvObj) + return hr; + hr = E_FAIL; + } + } + return hr; +} + +/*********************************************************************** + * DisplayNameOfW [SHELL32.757] (Vista+) + */ +EXTERN_C HRESULT WINAPI +DisplayNameOfW( _In_ IShellFolder *psf, _In_ LPCITEMIDLIST pidl, _In_ DWORD dwFlags, @@ -349,7 +495,7 @@ SHGetNameAndFlagsW( if (SUCCEEDED(hr)) { if (pszText) - hr = Shell_DisplayNameOf(psfFolder, ppidlLast, dwFlags, pszText, cchBuf); + hr = DisplayNameOfW(psfFolder, ppidlLast, dwFlags, pszText, cchBuf); if (SUCCEEDED(hr)) { @@ -736,6 +882,180 @@ SHCreatePropertyBag(_In_ REFIID riid, _Out_ void **ppvObj) return SHCreatePropertyBagOnMemory(STGM_READWRITE, riid, ppvObj); } +// The helper function for SHGetUnreadMailCountW +static DWORD +SHELL_ReadSingleUnreadMailCount( + _In_ HKEY hKey, + _Out_opt_ PDWORD pdwCount, + _Out_opt_ PFILETIME pFileTime, + _Out_writes_opt_(cchShellExecuteCommand) LPWSTR pszShellExecuteCommand, + _In_ INT cchShellExecuteCommand) +{ + DWORD dwType, dwCount, cbSize = sizeof(dwCount); + DWORD error = SHQueryValueExW(hKey, L"MessageCount", 0, &dwType, &dwCount, &cbSize); + if (error) + return error; + if (pdwCount && dwType == REG_DWORD) + *pdwCount = dwCount; + + FILETIME FileTime; + cbSize = sizeof(FileTime); + error = SHQueryValueExW(hKey, L"TimeStamp", 0, &dwType, &FileTime, &cbSize); + if (error) + return error; + if (pFileTime && dwType == REG_BINARY) + *pFileTime = FileTime; + + WCHAR szName[2 * MAX_PATH]; + cbSize = sizeof(szName); + error = SHQueryValueExW(hKey, L"Application", 0, &dwType, szName, &cbSize); + if (error) + return error; + + if (pszShellExecuteCommand && dwType == REG_SZ && + FAILED(StringCchCopyW(pszShellExecuteCommand, cchShellExecuteCommand, szName))) + { + return ERROR_INSUFFICIENT_BUFFER; + } + + return ERROR_SUCCESS; +} + +/************************************************************************* + * SHGetUnreadMailCountW [SHELL32.320] + * + * @see https://learn.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shgetunreadmailcountw + */ +EXTERN_C +HRESULT WINAPI +SHGetUnreadMailCountW( + _In_opt_ HKEY hKeyUser, + _In_opt_ PCWSTR pszMailAddress, + _Out_opt_ PDWORD pdwCount, + _Inout_opt_ PFILETIME pFileTime, + _Out_writes_opt_(cchShellExecuteCommand) PWSTR pszShellExecuteCommand, + _In_ INT cchShellExecuteCommand) +{ + LSTATUS error; + HKEY hKey; + + if (!hKeyUser) + hKeyUser = HKEY_CURRENT_USER; + + if (pszMailAddress) + { + CStringW strKey = L"Software\\Microsoft\\Windows\\CurrentVersion\\UnreadMail"; + strKey += L'\\'; + strKey += pszMailAddress; + + error = RegOpenKeyExW(hKeyUser, strKey, 0, KEY_QUERY_VALUE, &hKey); + if (error) + return HRESULT_FROM_WIN32(error); + + error = SHELL_ReadSingleUnreadMailCount(hKey, pdwCount, pFileTime, + pszShellExecuteCommand, cchShellExecuteCommand); + } + else + { + if (pszShellExecuteCommand || cchShellExecuteCommand) + return E_INVALIDARG; + + *pdwCount = 0; + + error = RegOpenKeyExW(hKeyUser, L"Software\\Microsoft\\Windows\\CurrentVersion\\UnreadMail", + 0, KEY_ENUMERATE_SUB_KEYS, &hKey); + if (error) + return HRESULT_FROM_WIN32(error); + + for (DWORD dwIndex = 0; !error; ++dwIndex) + { + WCHAR Name[2 * MAX_PATH]; + DWORD cchName = _countof(Name); + FILETIME LastWritten; + error = RegEnumKeyExW(hKey, dwIndex, Name, &cchName, NULL, NULL, NULL, &LastWritten); + if (error) + break; + + HKEY hSubKey; + error = RegOpenKeyExW(hKey, Name, 0, KEY_QUERY_VALUE, &hSubKey); + if (error) + break; + + FILETIME FileTime; + DWORD dwCount; + error = SHELL_ReadSingleUnreadMailCount(hSubKey, &dwCount, &FileTime, NULL, 0); + if (!error && (!pFileTime || CompareFileTime(&FileTime, pFileTime) >= 0)) + *pdwCount += dwCount; + + RegCloseKey(hSubKey); + } + + if (error == ERROR_NO_MORE_ITEMS) + error = ERROR_SUCCESS; + } + + RegCloseKey(hKey); + + return error ? HRESULT_FROM_WIN32(error) : S_OK; +} + +/************************************************************************* + * SHSetUnreadMailCountW [SHELL32.336] + * + * @see https://learn.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shsetunreadmailcountw + */ +EXTERN_C +HRESULT WINAPI +SHSetUnreadMailCountW( + _In_ PCWSTR pszMailAddress, + _In_ DWORD dwCount, + _In_ PCWSTR pszShellExecuteCommand) +{ + CString strKey = L"Software\\Microsoft\\Windows\\CurrentVersion\\UnreadMail\\"; + strKey += pszMailAddress; + + HKEY hKey; + DWORD dwDisposition; + LSTATUS error = RegCreateKeyExW(HKEY_CURRENT_USER, strKey, 0, NULL, 0, KEY_SET_VALUE, NULL, + &hKey, &dwDisposition); + if (error) + return HRESULT_FROM_WIN32(error); + + error = RegSetValueExW(hKey, L"MessageCount", 0, REG_DWORD, (PBYTE)&dwCount, sizeof(dwCount)); + if (error) + { + RegCloseKey(hKey); + return HRESULT_FROM_WIN32(error); + } + + FILETIME FileTime; + GetSystemTimeAsFileTime(&FileTime); + + error = RegSetValueExW(hKey, L"TimeStamp", 0, REG_BINARY, (PBYTE)&FileTime, sizeof(FileTime)); + if (error) + { + RegCloseKey(hKey); + return HRESULT_FROM_WIN32(error); + } + + WCHAR szBuff[2 * MAX_PATH]; + if (!PathUnExpandEnvStringsW(pszShellExecuteCommand, szBuff, _countof(szBuff))) + { + HRESULT hr = StringCchCopyW(szBuff, _countof(szBuff), pszShellExecuteCommand); + if (FAILED_UNEXPECTEDLY(hr)) + { + RegCloseKey(hKey); + return hr; + } + } + + DWORD cbValue = (lstrlenW(szBuff) + 1) * sizeof(WCHAR); + error = RegSetValueExW(hKey, L"Application", 0, REG_SZ, (PBYTE)szBuff, cbValue); + + RegCloseKey(hKey); + return (error ? HRESULT_FROM_WIN32(error) : S_OK); +} + /************************************************************************* * SheRemoveQuotesA (SHELL32.@) */ @@ -784,6 +1104,39 @@ SheRemoveQuotesW(LPWSTR psz) return psz; } +/************************************************************************* + * SHEnumerateUnreadMailAccountsW [SHELL32.287] + * + * @see https://learn.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shenumerateunreadmailaccountsw + */ +EXTERN_C +HRESULT WINAPI +SHEnumerateUnreadMailAccountsW( + _In_opt_ HKEY hKeyUser, + _In_ DWORD dwIndex, + _Out_writes_(cchMailAddress) PWSTR pszMailAddress, + _In_ INT cchMailAddress) +{ + if (!hKeyUser) + hKeyUser = HKEY_CURRENT_USER; + + HKEY hKey; + LSTATUS error = RegOpenKeyExW(hKeyUser, + L"Software\\Microsoft\\Windows\\CurrentVersion\\UnreadMail", + 0, KEY_ENUMERATE_SUB_KEYS, &hKey); + if (error) + return HRESULT_FROM_WIN32(error); + + FILETIME FileTime; + error = RegEnumKeyExW(hKey, dwIndex, pszMailAddress, (PDWORD)&cchMailAddress, NULL, NULL, + NULL, &FileTime); + if (error) + *pszMailAddress = UNICODE_NULL; + + RegCloseKey(hKey); + return error ? HRESULT_FROM_WIN32(error) : S_OK; +} + /************************************************************************* * SHFindComputer [SHELL32.91] * @@ -1090,44 +1443,6 @@ CopyStreamUI( return hr; } -/************************************************************************* - * SHOpenPropSheetA [SHELL32.707] - * - * @see https://learn.microsoft.com/en-us/windows/win32/api/shlobj/nf-shlobj-shopenpropsheeta - */ -EXTERN_C -BOOL WINAPI -SHOpenPropSheetA( - _In_opt_ LPCSTR pszCaption, - _In_opt_ HKEY *ahKeys, - _In_ UINT cKeys, - _In_ const CLSID *pclsidDefault, - _In_ IDataObject *pDataObject, - _In_opt_ IShellBrowser *pShellBrowser, - _In_opt_ LPCSTR pszStartPage) -{ - CStringW strStartPageW, strCaptionW; - LPCWSTR pszCaptionW = NULL, pszStartPageW = NULL; - - TRACE("(%s, %p, %u, %p, %p, %p, %s)", debugstr_a(pszCaption), ahKeys, cKeys, pclsidDefault, - pDataObject, pShellBrowser, debugstr_a(pszStartPage)); - - if (pszCaption) - { - strStartPageW = pszCaption; - pszCaptionW = strCaptionW; - } - - if (pszStartPage) - { - strStartPageW = pszStartPage; - pszStartPageW = strStartPageW; - } - - return SHOpenPropSheetW(pszCaptionW, ahKeys, cKeys, pclsidDefault, - pDataObject, pShellBrowser, pszStartPageW); -} - /************************************************************************* * Activate_RunDLL [SHELL32.105] * @@ -1429,3 +1744,302 @@ GetDfmCmd(_In_ IContextMenu *pCM, _In_ LPCSTR verba) } return MapVerbToDfmCmd(verba); // Returns DFM_CMD_* or 0 } + +HRESULT +SHELL_MapContextMenuVerbToCmdId(LPCMINVOKECOMMANDINFO pICI, const CMVERBMAP *pMap) +{ + LPCSTR pVerbA = pICI->lpVerb; + CHAR buf[MAX_PATH]; + LPCMINVOKECOMMANDINFOEX pICIX = (LPCMINVOKECOMMANDINFOEX)pICI; + if (IsUnicode(*pICIX) && !IS_INTRESOURCE(pICIX->lpVerbW)) + { + if (SHUnicodeToAnsi(pICIX->lpVerbW, buf, _countof(buf))) + pVerbA = buf; + } + + if (IS_INTRESOURCE(pVerbA)) + return LOWORD(pVerbA); + for (SIZE_T i = 0; pMap[i].Verb; ++i) + { + assert(SUCCEEDED((int)(pMap[i].CmdId))); // The id must be >= 0 and ideally in the 0..0x7fff range + if (!lstrcmpiA(pMap[i].Verb, pVerbA) && pVerbA[0]) + return pMap[i].CmdId; + } + return E_FAIL; +} + +static const CMVERBMAP* +FindVerbMapEntry(UINT_PTR CmdId, const CMVERBMAP *pMap) +{ + for (SIZE_T i = 0; pMap[i].Verb; ++i) + { + if (pMap[i].CmdId == CmdId) + return &pMap[i]; + } + return NULL; +} + +HRESULT +SHELL_GetCommandStringImpl(SIZE_T CmdId, UINT uFlags, LPSTR Buf, UINT cchBuf, const CMVERBMAP *pMap) +{ + const CMVERBMAP* pEntry; + switch (uFlags | GCS_UNICODE) + { + case GCS_VALIDATEW: + case GCS_VERBW: + pEntry = FindVerbMapEntry(CmdId, pMap); + if ((uFlags | GCS_UNICODE) == GCS_VERBW) + { + if (!pEntry) + return E_INVALIDARG; + else if (uFlags & GCS_UNICODE) + return SHAnsiToUnicode(pEntry->Verb, (LPWSTR)Buf, cchBuf) ? S_OK : E_FAIL; + else + return StringCchCopyA(Buf, cchBuf, pEntry->Verb); + } + return pEntry ? S_OK : S_FALSE; // GCS_VALIDATE + } + return E_NOTIMPL; +} + +HRESULT +SHELL_CreateShell32DefaultExtractIcon(int IconIndex, REFIID riid, LPVOID *ppvOut) +{ + CComPtr initIcon; + HRESULT hr = SHCreateDefaultExtractIcon(IID_PPV_ARG(IDefaultExtractIconInit, &initIcon)); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + initIcon->SetNormalIcon(swShell32Name, IconIndex); + return initIcon->QueryInterface(riid, ppvOut); +} + +/************************************************************************* + * SHIsBadInterfacePtr [SHELL32.84] + * + * Retired in 6.0 from Windows Vista and higher. + */ +EXTERN_C +BOOL WINAPI +SHIsBadInterfacePtr( + _In_ LPCVOID pv, + _In_ UINT_PTR ucb) +{ + struct CUnknownVtbl + { + HRESULT (STDMETHODCALLTYPE *QueryInterface)(REFIID riid, LPVOID *ppvObj); + ULONG (STDMETHODCALLTYPE *AddRef)(); + ULONG (STDMETHODCALLTYPE *Release)(); + }; + struct CUnknown { CUnknownVtbl *lpVtbl; }; + const CUnknown *punk = reinterpret_cast(pv); + return !punk || IsBadReadPtr(punk, sizeof(punk->lpVtbl)) || + IsBadReadPtr(punk->lpVtbl, ucb) || + IsBadCodePtr((FARPROC)punk->lpVtbl->Release); +} + +/************************************************************************* + * SHGetUserDisplayName [SHELL32.241] + * + * @see https://undoc.airesoft.co.uk/shell32.dll/SHGetUserDisplayName.php + */ +EXTERN_C +HRESULT WINAPI +SHGetUserDisplayName( + _Out_writes_to_(*puSize, *puSize) PWSTR pName, + _Inout_ PULONG puSize) +{ + if (!pName || !puSize) + return E_INVALIDARG; + + if (GetUserNameExW(NameDisplay, pName, puSize)) + return S_OK; + + LONG error = GetLastError(); // for ERROR_NONE_MAPPED + HRESULT hr = HRESULT_FROM_WIN32(error); + + WCHAR UserName[MAX_PATH]; + DWORD cchUserName = _countof(UserName); + if (!GetUserNameW(UserName, &cchUserName)) + return HRESULT_FROM_WIN32(GetLastError()); + + // Was the user name not available in the specified format (NameDisplay)? + if (error == ERROR_NONE_MAPPED) + { + // Try to get the user name by using Network API + PUSER_INFO_2 UserInfo; + DWORD NetError = NetUserGetInfo(NULL, UserName, 2, (PBYTE*)&UserInfo); + if (NetError) + { + hr = HRESULT_FROM_WIN32(NetError); + } + else + { + if (UserInfo->usri2_full_name) + { + hr = StringCchCopyW(pName, *puSize, UserInfo->usri2_full_name); + if (SUCCEEDED(hr)) + { + // Include the NUL-terminator + *puSize = lstrlenW(UserInfo->usri2_full_name) + 1; + } + } + + NetApiBufferFree(UserInfo); + } + } + + if (FAILED(hr)) + { + hr = StringCchCopyW(pName, *puSize, UserName); + if (SUCCEEDED(hr)) + *puSize = cchUserName; + } + + return hr; +} + +// Skip leading backslashes +static PCWSTR +SHELL_SkipServerSlashes( + _In_ PCWSTR pszPath) +{ + PCWSTR pch; + for (pch = pszPath; *pch == L'\\'; ++pch) + ; + return pch; +} + +// The registry key for server computer descriptions cache +#define COMPUTER_DESCRIPTIONS_KEY \ + L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComputerDescriptions" + +// Get server computer description from cache +static HRESULT +SHELL_GetCachedComputerDescription( + _Out_writes_z_(cchDescMax) PWSTR pszDesc, + _In_ DWORD cchDescMax, + _In_ PCWSTR pszServerName) +{ + cchDescMax *= sizeof(WCHAR); + DWORD error = SHGetValueW(HKEY_CURRENT_USER, COMPUTER_DESCRIPTIONS_KEY, + SHELL_SkipServerSlashes(pszServerName), NULL, pszDesc, &cchDescMax); + return HRESULT_FROM_WIN32(error); +} + +// Do cache a server computer description +static VOID +SHELL_CacheComputerDescription( + _In_ PCWSTR pszServerName, + _In_ PCWSTR pszDesc) +{ + if (!pszDesc) + return; + + SIZE_T cbDesc = (wcslen(pszDesc) + 1) * sizeof(WCHAR); + SHSetValueW(HKEY_CURRENT_USER, COMPUTER_DESCRIPTIONS_KEY, + SHELL_SkipServerSlashes(pszServerName), REG_SZ, pszDesc, (DWORD)cbDesc); +} + +// Get real server computer description +static HRESULT +SHELL_GetComputerDescription( + _Out_writes_z_(cchDescMax) PWSTR pszDesc, + _In_ SIZE_T cchDescMax, + _In_ PWSTR pszServerName) +{ + PSERVER_INFO_101 bufptr; + NET_API_STATUS error = NetServerGetInfo(pszServerName, 101, (PBYTE*)&bufptr); + HRESULT hr = (error > 0) ? HRESULT_FROM_WIN32(error) : error; + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + + PCWSTR comment = bufptr->sv101_comment; + if (comment && comment[0]) + StringCchCopyW(pszDesc, cchDescMax, comment); + else + hr = E_FAIL; + + NetApiBufferFree(bufptr); + return hr; +} + +// Build computer display name +static HRESULT +SHELL_BuildDisplayMachineName( + _Out_writes_z_(cchNameMax) PWSTR pszName, + _In_ DWORD cchNameMax, + _In_ PCWSTR pszServerName, + _In_ PCWSTR pszDescription) +{ + if (!pszDescription || !*pszDescription) + return E_FAIL; + + PCWSTR pszFormat = (SHRestricted(REST_ALLOWCOMMENTTOGGLE) ? L"%2 (%1)" : L"%1 (%2)"); + PCWSTR args[] = { pszDescription , SHELL_SkipServerSlashes(pszServerName) }; + return (FormatMessageW(FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_FROM_STRING, + pszFormat, 0, 0, pszName, cchNameMax, (va_list *)args) ? S_OK : E_FAIL); +} + +/************************************************************************* + * SHGetComputerDisplayNameW [SHELL32.752] + */ +EXTERN_C +HRESULT WINAPI +SHGetComputerDisplayNameW( + _In_opt_ PWSTR pszServerName, + _In_ DWORD dwFlags, + _Out_writes_z_(cchNameMax) PWSTR pszName, + _In_ DWORD cchNameMax) +{ + WCHAR szDesc[256], szCompName[MAX_COMPUTERNAME_LENGTH + 1]; + + // If no server name is specified, retrieve the local computer name + if (!pszServerName) + { + // Use computer name as server name + DWORD cchCompName = _countof(szCompName); + if (!GetComputerNameW(szCompName, &cchCompName)) + return E_FAIL; + pszServerName = szCompName; + + // Don't use the cache for the local machine + dwFlags |= SHGCDN_NOCACHE; + } + + // Get computer description from cache if necessary + HRESULT hr = E_FAIL; + if (!(dwFlags & SHGCDN_NOCACHE)) + hr = SHELL_GetCachedComputerDescription(szDesc, _countof(szDesc), pszServerName); + + // Actually retrieve the computer description if it is not in the cache + if (FAILED(hr)) + { + hr = SHELL_GetComputerDescription(szDesc, _countof(szDesc), pszServerName); + if (FAILED(hr)) + szDesc[0] = UNICODE_NULL; + + // Cache the description if necessary + if (!(dwFlags & SHGCDN_NOCACHE)) + SHELL_CacheComputerDescription(pszServerName, szDesc); + } + + // If getting the computer description failed, store the server name only + if (FAILED(hr) || !szDesc[0]) + { + if (dwFlags & SHGCDN_NOSERVERNAME) + return hr; // Bail out if no server name is requested + + StringCchCopyW(pszName, cchNameMax, SHELL_SkipServerSlashes(pszServerName)); + return S_OK; + } + + // If no server name is requested, store the description only + if (dwFlags & SHGCDN_NOSERVERNAME) + { + StringCchCopyW(pszName, cchNameMax, szDesc); + return S_OK; + } + + // Build a string like "Description (SERVERNAME)" + return SHELL_BuildDisplayMachineName(pszName, cchNameMax, pszServerName, szDesc); +} diff --git a/dll/win32/shell32/utils.h b/dll/win32/shell32/utils.h index 92a96888c5d13..809618327178d 100644 --- a/dll/win32/shell32/utils.h +++ b/dll/win32/shell32/utils.h @@ -7,7 +7,39 @@ #pragma once -inline BOOL +#ifndef OPTIONAL_ + #ifdef __cplusplus + #define OPTIONAL_(arg) = arg + #else + #define OPTIONAL_(arg) + #endif +#endif + +#ifdef __cplusplus +static inline LPWSTR +SHStrDupW(LPCWSTR Src) +{ + LPWSTR Dup; + return SUCCEEDED(SHStrDupW(Src, &Dup)) ? Dup : NULL; +} + +static inline UINT +SHELL_ErrorBox(CMINVOKECOMMANDINFO &cmi, UINT Error) +{ + if (cmi.fMask & CMIC_MASK_FLAG_NO_UI) + return Error ? Error : ERROR_INTERNAL_ERROR; + return SHELL_ErrorBox(cmi.hwnd, Error); +} +#endif + +static inline BOOL +IsEqualPersistClassID(IPersist *pPersist, REFCLSID clsid) +{ + CLSID temp; + return pPersist && SUCCEEDED(pPersist->GetClassID(&temp)) && IsEqualCLSID(clsid, temp); +} + +static inline BOOL RegValueExists(HKEY hKey, LPCWSTR Name) { return RegQueryValueExW(hKey, Name, NULL, NULL, NULL, NULL) == ERROR_SUCCESS; @@ -26,17 +58,28 @@ inline DWORD RegSetOrDelete(HKEY hKey, LPCWSTR Name, DWORD Type, LPCVOID Data, DWORD Size) { if (Data) - return RegSetValueExW(hKey, Name, 0, Type, LPBYTE(Data), Size); + return RegSetValueExW(hKey, Name, 0, Type, (LPBYTE)Data, Size); else return RegDeleteValueW(hKey, Name); } -inline DWORD -RegSetString(HKEY hKey, LPCWSTR Name, LPCWSTR Str, DWORD Type = REG_SZ) +static inline DWORD +RegSetString(HKEY hKey, LPCWSTR Name, LPCWSTR Str, DWORD Type OPTIONAL_(REG_SZ)) { - return RegSetValueExW(hKey, Name, 0, Type, LPBYTE(Str), (lstrlenW(Str) + 1) * sizeof(WCHAR)); + return RegSetValueExW(hKey, Name, 0, Type, (LPBYTE)Str, (lstrlenW(Str) + 1) * sizeof(WCHAR)); } +typedef struct +{ + LPCSTR Verb; + WORD CmdId; +} CMVERBMAP; + +HRESULT +SHELL_MapContextMenuVerbToCmdId(LPCMINVOKECOMMANDINFO pICI, const CMVERBMAP *pMap); +HRESULT +SHELL_GetCommandStringImpl(SIZE_T CmdId, UINT uFlags, LPSTR Buf, UINT cchBuf, const CMVERBMAP *pMap); + // SHExtractIconsW is a forward, use this function instead inside shell32 inline HICON SHELL32_SHExtractIcon(LPCWSTR File, int Index, int cx, int cy) @@ -45,3 +88,80 @@ SHELL32_SHExtractIcon(LPCWSTR File, int Index, int cx, int cy) int r = PrivateExtractIconsW(File, Index, cx, cy, &hIco, NULL, 1, 0); return r > 0 ? hIco : NULL; } + +HRESULT +SHELL_CreateShell32DefaultExtractIcon(int IconIndex, REFIID riid, LPVOID *ppvOut); + +static inline HRESULT +SHELL_CreateFallbackExtractIconForFolder(REFIID riid, LPVOID *ppvOut) +{ + const int id = IDI_SHELL_FOLDER; + return SHELL_CreateShell32DefaultExtractIcon(id > 1 ? -id : 0, riid, ppvOut); +} + +static inline HRESULT +SHELL_CreateFallbackExtractIconForNoAssocFile(REFIID riid, LPVOID *ppvOut) +{ + const int id = IDI_SHELL_DOCUMENT; + return SHELL_CreateShell32DefaultExtractIcon(id > 1 ? -id : 0, riid, ppvOut); +} + +#ifdef __cplusplus +struct ClipboardViewerChain +{ + HWND m_hWndNext = HWND_BOTTOM; + + void Unhook(HWND hWnd) + { + if (m_hWndNext != HWND_BOTTOM) + ChangeClipboardChain(hWnd, m_hWndNext); + m_hWndNext = HWND_BOTTOM; + } + + void Hook(HWND hWnd) + { + if (m_hWndNext == HWND_BOTTOM) + m_hWndNext = SetClipboardViewer(hWnd); + } + + LRESULT HandleChangeCBChain(WPARAM wParam, LPARAM lParam) + { + if (m_hWndNext == (HWND)wParam) + return (LRESULT)(m_hWndNext = (HWND)lParam); + else if (m_hWndNext && m_hWndNext != HWND_BOTTOM) + return ::SendMessageW(m_hWndNext, WM_CHANGECBCHAIN, wParam, lParam); + return 0; + } + + LRESULT HandleDrawClipboard(WPARAM wParam, LPARAM lParam) + { + if (m_hWndNext && m_hWndNext != HWND_BOTTOM) + return ::SendMessageW(m_hWndNext, WM_DRAWCLIPBOARD, wParam, lParam); + return 0; + } +}; + +struct CCidaChildArrayHelper +{ + // Note: This just creates an array pointing to the items and has the same lifetime as the CIDA. + // Use _ILCopyCidaToaPidl if you need the items to outlive the CIDA! + explicit CCidaChildArrayHelper(const CIDA *pCida) + { + m_hr = E_OUTOFMEMORY; + m_array = (PCUIDLIST_RELATIVE_ARRAY)SHAlloc(pCida->cidl * sizeof(LPITEMIDLIST)); + if (m_array) + { + m_hr = S_OK; + for (UINT i = 0; i < pCida->cidl; ++i) + *(LPITEMIDLIST*)(&m_array[i]) = (LPITEMIDLIST)HIDA_GetPIDLItem(pCida, i); + } + } + ~CCidaChildArrayHelper() { SHFree((LPITEMIDLIST*)m_array); } + + HRESULT hr() const { return m_hr; } + PCUIDLIST_RELATIVE_ARRAY GetItems() const { return m_array; } + + HRESULT m_hr; + PCUIDLIST_RELATIVE_ARRAY m_array; +}; +#endif // __cplusplus diff --git a/dll/win32/shell32/wine/PolicyData.h b/dll/win32/shell32/wine/PolicyData.h index f106d28fcfd0b..24de8cec9cb0b 100644 --- a/dll/win32/shell32/wine/PolicyData.h +++ b/dll/win32/shell32/wine/PolicyData.h @@ -10,7 +10,7 @@ * NOTE: Up to date as of SHELL32 v6.00 (Win2k3). * References: * https://www.geoffchappell.com/studies/windows/shell/shell32/api/util/restrictions.htm - * https://docs.microsoft.com/en-us/windows/win32/api/shlobj_core/ne-shlobj_core-restrictions + * https://learn.microsoft.com/en-us/windows/win32/api/shlobj_core/ne-shlobj_core-restrictions * https://abi-laboratory.pro/compatibility/Windows_5.0_to_Windows_6.0/x86_64/headers_diff/shell32.dll/diff.html */ diff --git a/dll/win32/shell32/wine/classes.c b/dll/win32/shell32/wine/classes.c index 6138fdac26740..e6f23070c2e37 100644 --- a/dll/win32/shell32/wine/classes.c +++ b/dll/win32/shell32/wine/classes.c @@ -254,7 +254,7 @@ BOOL HCR_RegOpenClassIDKey(REFIID riid, HKEY *hkey) { char xriid[50]; sprintf( xriid, "CLSID\\{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", - riid->Data1, riid->Data2, riid->Data3, + (UINT)riid->Data1, riid->Data2, riid->Data3, riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7] ); diff --git a/dll/win32/shell32/wine/control.c b/dll/win32/shell32/wine/control.c index dbbca6a2e4a3d..b07cda047f490 100644 --- a/dll/win32/shell32/wine/control.c +++ b/dll/win32/shell32/wine/control.c @@ -1104,7 +1104,7 @@ static void Control_DoLaunch(CPanel* panel, HWND hWnd, LPCWSTR wszCmd) } } - if (sp >= applet->count && wszDialogBoxName[0] == L'\0') + if (sp >= applet->count && (wszDialogBoxName[0] == L'\0' || wszDialogBoxName[0] == L'@')) { sp = 0; } diff --git a/dll/win32/shell32/wine/pidl.c b/dll/win32/shell32/wine/pidl.c index de484982b15d0..43511ca40f149 100644 --- a/dll/win32/shell32/wine/pidl.c +++ b/dll/win32/shell32/wine/pidl.c @@ -333,8 +333,10 @@ HRESULT WINAPI ILLoadFromStream (IStream * pStream, LPITEMIDLIST * ppPidl) if (*ppPidl && !pcheck(*ppPidl)) { WARN("Check failed\n"); +#ifndef __REACTOS__ /* We don't know all pidl formats, must allow loading unknown */ SHFree(*ppPidl); *ppPidl = NULL; +#endif } IStream_Release (pStream); @@ -1621,7 +1623,14 @@ HRESULT WINAPI SHGetNameFromIDList(PCIDLIST_ABSOLUTE pidl, SIGDN sigdnName, PWST return ret; } -#ifndef __REACTOS__ +/************************************************************************* + * SHGetItemFromDataObject [SHELL32.@] + */ +HRESULT WINAPI SHGetItemFromDataObject(IDataObject *pdtobj, DATAOBJ_GET_ITEM_FLAGS dwFlags, + REFIID riid, void **ppv) +{ + return E_NOTIMPL; // FIXME +} /************************************************************************* * SHGetIDListFromObject [SHELL32.@] @@ -1699,8 +1708,6 @@ HRESULT WINAPI SHGetIDListFromObject(IUnknown *punk, PIDLIST_ABSOLUTE *ppidl) return ret; } -#endif /* !__REACTOS__ */ - /************************************************************************** * * internal functions @@ -1756,30 +1763,29 @@ LPITEMIDLIST _ILCreateDesktop(void) LPITEMIDLIST _ILCreateMyComputer(void) { TRACE("()\n"); - return _ILCreateGuid(PT_GUID, &CLSID_MyComputer); + return _ILCreateGuid(PT_DESKTOP_REGITEM, &CLSID_MyComputer); } LPITEMIDLIST _ILCreateMyDocuments(void) { TRACE("()\n"); - return _ILCreateGuid(PT_GUID, &CLSID_MyDocuments); + return _ILCreateGuid(PT_DESKTOP_REGITEM, &CLSID_MyDocuments); } LPITEMIDLIST _ILCreateIExplore(void) { TRACE("()\n"); - return _ILCreateGuid(PT_GUID, &CLSID_Internet); + return _ILCreateGuid(PT_DESKTOP_REGITEM, &CLSID_Internet); } LPITEMIDLIST _ILCreateControlPanel(void) { - LPITEMIDLIST parent = _ILCreateGuid(PT_GUID, &CLSID_MyComputer), ret = NULL; + LPITEMIDLIST parent = _ILCreateMyComputer(), ret = NULL; TRACE("()\n"); if (parent) { - LPITEMIDLIST cpl = _ILCreateGuid(PT_SHELLEXT, &CLSID_ControlPanel); - + LPITEMIDLIST cpl = _ILCreateGuid(PT_COMPUTER_REGITEM, &CLSID_ControlPanel); if (cpl) { ret = ILCombine(parent, cpl); @@ -1820,13 +1826,13 @@ LPITEMIDLIST _ILCreatePrinters(void) LPITEMIDLIST _ILCreateNetwork(void) { TRACE("()\n"); - return _ILCreateGuid(PT_GUID, &CLSID_NetworkPlaces); + return _ILCreateGuid(PT_DESKTOP_REGITEM, &CLSID_NetworkPlaces); } LPITEMIDLIST _ILCreateBitBucket(void) { TRACE("()\n"); - return _ILCreateGuid(PT_GUID, &CLSID_RecycleBin); + return _ILCreateGuid(PT_DESKTOP_REGITEM, &CLSID_RecycleBin); } LPITEMIDLIST _ILCreateAdminTools(void) @@ -2030,11 +2036,9 @@ DWORD _ILGetDrive(LPCITEMIDLIST pidl, LPWSTR pOut, UINT uSize) */ BOOL _ILIsUnicode(LPCITEMIDLIST pidl) { - LPPIDLDATA lpPData = _ILGetDataPointer(pidl); - TRACE("(%p)\n",pidl); - return (pidl && lpPData && PT_VALUEW == lpPData->type); + return (_ILGetFSType(pidl) & PT_FS_UNICODE_FLAG) != 0; } BOOL _ILIsDesktop(LPCITEMIDLIST pidl) @@ -2055,28 +2059,6 @@ BOOL _ILIsMyDocuments(LPCITEMIDLIST pidl) return FALSE; } -BOOL _ILIsNetHood(LPCITEMIDLIST pidl) -{ - IID *iid = _ILGetGUIDPointer(pidl); - - TRACE("(%p)\n", pidl); - - if (iid) - return IsEqualIID(iid, &CLSID_NetworkPlaces); - return FALSE; -} - -BOOL _ILIsControlPanel(LPCITEMIDLIST pidl) -{ - IID *iid = _ILGetGUIDPointer(pidl); - - TRACE("(%p)\n", pidl); - - if (iid) - return IsEqualIID(iid, &CLSID_ControlPanel); - return FALSE; -} - BOOL _ILIsMyComputer(LPCITEMIDLIST pidl) { REFIID iid = _ILGetGUIDPointer(pidl); @@ -2112,32 +2094,22 @@ BOOL _ILIsSpecialFolder (LPCITEMIDLIST pidl) BOOL _ILIsDrive(LPCITEMIDLIST pidl) { - LPPIDLDATA lpPData = _ILGetDataPointer(pidl); - - TRACE("(%p)\n",pidl); - - return (pidl && lpPData && (PT_DRIVE == lpPData->type || - PT_DRIVE1 == lpPData->type || - PT_DRIVE2 == lpPData->type || - PT_DRIVE3 == lpPData->type)); + const BYTE type = _ILGetType(pidl); + const BYTE fldrtype = (PT_DRIVE & PT_FOLDERTYPEMASK); + return (type & PT_FOLDERTYPEMASK) == fldrtype && type != PT_COMPUTER_REGITEM; } BOOL _ILIsFolder(LPCITEMIDLIST pidl) { - LPPIDLDATA lpPData = _ILGetDataPointer(pidl); - - TRACE("(%p)\n",pidl); - - return (pidl && lpPData && (PT_FOLDER == lpPData->type || PT_FOLDER1 == lpPData->type)); + /* A folder or a simple PT_FS with a child */ + const BYTE type = _ILGetFSType(pidl); + return (type & PT_FS_FOLDER_FLAG) != 0 || (type == PT_FS && ILGetNext(pidl)); } BOOL _ILIsValue(LPCITEMIDLIST pidl) { - LPPIDLDATA lpPData = _ILGetDataPointer(pidl); - - TRACE("(%p)\n",pidl); - - return (pidl && lpPData && PT_VALUE == lpPData->type); + const BYTE type = _ILGetFSType(pidl); + return type && !(type & PT_FS_FOLDER_FLAG); } BOOL _ILIsCPanelStruct(LPCITEMIDLIST pidl) @@ -2281,6 +2253,9 @@ static LPWSTR _ILGetTextPointerW(LPCITEMIDLIST pidl) if (!pdata) return NULL; + if (_ILGetFSType(pidl) & PT_FS_UNICODE_FLAG) + return (LPWSTR)pdata->u.file.szNames; + switch (pdata->type) { case PT_GUID: @@ -2295,9 +2270,6 @@ static LPWSTR _ILGetTextPointerW(LPCITEMIDLIST pidl) /*return (LPSTR)&(pdata->u.drive.szDriveName);*/ return NULL; - case PT_FOLDER: - case PT_FOLDER1: - case PT_VALUE: case PT_IESPECIAL1: case PT_IESPECIAL2: /*return (LPSTR)&(pdata->u.file.szNames);*/ @@ -2311,9 +2283,6 @@ static LPWSTR _ILGetTextPointerW(LPCITEMIDLIST pidl) /*return (LPSTR)&(pdata->u.network.szNames);*/ return NULL; - case PT_VALUEW: - return (LPWSTR)pdata->u.file.szNames; - #ifdef __REACTOS__ /* r54423 */ case PT_CPLAPPLET: return pdata->u.cpanel.szName; @@ -2332,11 +2301,18 @@ LPSTR _ILGetTextPointer(LPCITEMIDLIST pidl) { /* TRACE(pidl,"(pidl%p)\n", pidl);*/ + PIDLTYPE type; LPPIDLDATA pdata = _ILGetDataPointer(pidl); - if (!pdata) return NULL; + type = _ILGetFSType(pidl); + if (type && !(type & PT_FS_UNICODE_FLAG)) + return pdata->u.file.szNames; + + if (_ILIsDrive(pidl)) + return pdata->u.drive.szDriveName; + switch (pdata->type) { case PT_GUID: @@ -2344,15 +2320,6 @@ LPSTR _ILGetTextPointer(LPCITEMIDLIST pidl) case PT_YAGUID: return NULL; - case PT_DRIVE: - case PT_DRIVE1: - case PT_DRIVE2: - case PT_DRIVE3: - return pdata->u.drive.szDriveName; - - case PT_FOLDER: - case PT_FOLDER1: - case PT_VALUE: case PT_IESPECIAL1: case PT_IESPECIAL2: return pdata->u.file.szNames; @@ -2375,15 +2342,18 @@ static LPSTR _ILGetSTextPointer(LPCITEMIDLIST pidl) { /* TRACE(pidl,"(pidl%p)\n", pidl); */ + PIDLTYPE type; LPPIDLDATA pdata =_ILGetDataPointer(pidl); - if (!pdata) return NULL; - switch (pdata->type) + type = pdata->type; + if (_ILGetFSType(pidl) && !(type & PT_FS_UNICODE_FLAG)) + type = PT_FS; + + switch (type) { - case PT_FOLDER: - case PT_VALUE: + case PT_FS: case PT_IESPECIAL1: case PT_IESPECIAL2: return pdata->u.file.szNames + strlen (pdata->u.file.szNames) + 1; @@ -2439,7 +2409,7 @@ FileStructW* _ILGetFileStructW(LPCITEMIDLIST pidl) { FileStructW *pFileStructW; WORD cbOffset; - if (!(_ILIsValue(pidl) || _ILIsFolder(pidl))) + if (!_ILIsFolderOrFile(pidl)) return NULL; cbOffset = *(const WORD *)((const BYTE *)pidl + pidl->mkid.cb - sizeof(WORD)); @@ -2479,48 +2449,12 @@ FileStructW* _ILGetFileStructW(LPCITEMIDLIST pidl) { */ BOOL _ILGetFileDateTime(LPCITEMIDLIST pidl, FILETIME *pFt) { - LPPIDLDATA pdata = _ILGetDataPointer(pidl); - - if (!pdata) - return FALSE; - - switch (pdata->type) + if (_ILGetFSType(pidl) > PT_FS) /* Only non-simple FS items have a date */ { - case PT_FOLDER: - case PT_VALUE: - DosDateTimeToFileTime(pdata->u.file.uFileDate, pdata->u.file.uFileTime, pFt); - break; - default: - return FALSE; + LPPIDLDATA pdata = _ILGetDataPointer(pidl); + return DosDateTimeToFileTime(pdata->u.file.uFileDate, pdata->u.file.uFileTime, pFt); } - return TRUE; -} - -BOOL _ILGetFileDate(LPCITEMIDLIST pidl, LPWSTR pOut, UINT uOutSize) -{ - FILETIME ft,lft; - SYSTEMTIME time; - BOOL ret; - - if (_ILGetFileDateTime( pidl, &ft )) - { - FileTimeToLocalFileTime(&ft, &lft); - FileTimeToSystemTime (&lft, &time); - - ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &time, NULL, pOut, uOutSize); - if (ret) - { - /* Append space + time without seconds */ - pOut[ret - 1] = L' '; - GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &time, NULL, &pOut[ret], uOutSize - ret); - } - } - else - { - pOut[0] = UNICODE_NULL; - ret = FALSE; - } - return ret; + return FALSE; } /************************************************************************* @@ -2543,15 +2477,13 @@ BOOL _ILGetFileDate(LPCITEMIDLIST pidl, LPWSTR pOut, UINT uOutSize) DWORD _ILGetFileSize(LPCITEMIDLIST pidl, LPWSTR pOut, UINT uOutSize) { LPPIDLDATA pdata = _ILGetDataPointer(pidl); - DWORD dwSize; - if (!pdata) return 0; - switch (pdata->type) + if (_ILGetFSType(pidl) & PT_FS_FILE_FLAG) { - case PT_VALUE: - dwSize = pdata->u.file.dwFileSize; + /* FIXME: Handle INVALID_FILE_SIZE (get size from disk) */ + DWORD dwSize = pdata->u.file.dwFileSize; if (pOut) StrFormatKBSizeW(dwSize, pOut, uOutSize); return dwSize; @@ -2610,24 +2542,13 @@ BOOL _ILGetExtension(LPCITEMIDLIST pidl, LPWSTR pOut, UINT uOutSize) */ DWORD _ILGetFileAttributes(LPCITEMIDLIST pidl, LPWSTR pOut, UINT uOutSize) { - LPPIDLDATA pData = _ILGetDataPointer(pidl); - WORD wAttrib = 0; - int i; - - if (!pData) - return 0; - - switch(pData->type) - { - case PT_FOLDER: - case PT_VALUE: - wAttrib = pData->u.file.uFileAttribs; - break; - } + DWORD wAttrib = 0; + if (_ILGetFSType(pidl)) + wAttrib = _ILGetDataPointer(pidl)->u.file.uFileAttribs; - if(uOutSize >= 6) + if (uOutSize >= 6) { - i=0; + UINT i = 0; if(wAttrib & FILE_ATTRIBUTE_READONLY) pOut[i++] = L'R'; if(wAttrib & FILE_ATTRIBUTE_HIDDEN) diff --git a/dll/win32/shell32/wine/pidl.h b/dll/win32/shell32/wine/pidl.h index 28fff42feb452..0711f3f5a17c9 100644 --- a/dll/win32/shell32/wine/pidl.h +++ b/dll/win32/shell32/wine/pidl.h @@ -108,11 +108,15 @@ extern "C" { #define PT_FOLDERTYPEMASK 0x70 #define PT_DESKTOP_REGITEM 0x1F // => SHDID_ROOT_REGITEM #define PT_COMPUTER_REGITEM 0x2E // => SHDID_COMPUTER_? +#define PT_COMPUTER_DRIVE 0x2F #define PT_FS 0x30 // Win95 SHSimpleIDListFromPath #define PT_FS_FOLDER_FLAG 0x01 #define PT_FS_FILE_FLAG 0x02 #define PT_FS_UNICODE_FLAG 0x04 +#define PT_FS_COMMON_FLAG 0x08 // PT_NET_REGITEM 0x4? // => SHDID_NET_OTHER +#define PT_INTERNET 0x60 +#define PT_INTERNET_URL 0x61 #define PT_CONTROLS_OLDREGITEM 0x70 #define PT_CONTROLS_NEWREGITEM 0x71 #endif @@ -157,16 +161,6 @@ typedef struct tagPIDLPrinterStruct WCHAR szName[1]; } PIDLPrinterStruct; -typedef struct tagPIDLRecycleStruct -{ - FILETIME LastModification; - FILETIME DeletionTime; - ULARGE_INTEGER FileSize; - ULARGE_INTEGER PhysicalFileSize; - DWORD Attributes; - WCHAR szName[1]; -} PIDLRecycleStruct; - #endif /* !__REACTOS__ */ typedef struct tagGUIDStruct @@ -233,7 +227,6 @@ typedef struct tagPIDLDATA #ifdef __REACTOS__ struct tagPIDLFontStruct cfont; struct tagPIDLPrinterStruct cprinter; - struct tagPIDLRecycleStruct crecycle; #endif }u; } PIDLDATA, *LPPIDLDATA; @@ -243,7 +236,6 @@ typedef struct tagPIDLDATA * getting special values from simple pidls */ DWORD _ILSimpleGetTextW (LPCITEMIDLIST pidl, LPWSTR pOut, UINT uOutSize) DECLSPEC_HIDDEN; -BOOL _ILGetFileDate (LPCITEMIDLIST pidl, LPWSTR pOut, UINT uOutSize) DECLSPEC_HIDDEN; DWORD _ILGetFileSize (LPCITEMIDLIST pidl, LPWSTR pOut, UINT uOutSize) DECLSPEC_HIDDEN; BOOL _ILGetExtension (LPCITEMIDLIST pidl, LPWSTR pOut, UINT uOutSize) DECLSPEC_HIDDEN; DWORD _ILGetFileAttributes(LPCITEMIDLIST pidl, LPWSTR pOut, UINT uOutSize) DECLSPEC_HIDDEN; @@ -259,8 +251,7 @@ BOOL _ILIsMyComputer (LPCITEMIDLIST pidl) DECLSPEC_HIDDEN; #ifdef __REACTOS__ BOOL _ILIsMyDocuments (LPCITEMIDLIST pidl); BOOL _ILIsBitBucket (LPCITEMIDLIST pidl); -BOOL _ILIsNetHood (LPCITEMIDLIST pidl); -BOOL _ILIsControlPanel (LPCITEMIDLIST pidl); +#define _ILIsFolderOrFile _ILGetFSType #endif BOOL _ILIsDrive (LPCITEMIDLIST pidl) DECLSPEC_HIDDEN; BOOL _ILIsFolder (LPCITEMIDLIST pidl) DECLSPEC_HIDDEN; diff --git a/dll/win32/shell32/wine/shell32_main.c b/dll/win32/shell32/wine/shell32_main.c index 04967da66d11e..0a24d36e4ec9e 100644 --- a/dll/win32/shell32/wine/shell32_main.c +++ b/dll/win32/shell32/wine/shell32_main.c @@ -607,9 +607,6 @@ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes, if (flags & SHGFI_SELECTED) FIXME("set icon to selected, stub\n"); - if (flags & SHGFI_SHELLICONSIZE) - FIXME("set icon to shell size, stub\n"); - /* get the iconlocation */ if (SUCCEEDED(hr) && (flags & SHGFI_ICONLOCATION )) { @@ -700,16 +697,32 @@ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes, else { UINT ret; - if (flags & SHGFI_SMALLICON) - ret = PrivateExtractIconsW( sTemp,icon_idx, - GetSystemMetrics( SM_CXSMICON ), - GetSystemMetrics( SM_CYSMICON ), - &psfi->hIcon, 0, 1, 0); + INT cxIcon, cyIcon; + + /* Get icon size */ + if (flags & SHGFI_SHELLICONSIZE) + { + if (flags & SHGFI_SMALLICON) + cxIcon = cyIcon = ShellSmallIconSize; + else + cxIcon = cyIcon = ShellLargeIconSize; + } else - ret = PrivateExtractIconsW( sTemp, icon_idx, - GetSystemMetrics( SM_CXICON), - GetSystemMetrics( SM_CYICON), - &psfi->hIcon, 0, 1, 0); + { + if (flags & SHGFI_SMALLICON) + { + cxIcon = GetSystemMetrics(SM_CXSMICON); + cyIcon = GetSystemMetrics(SM_CYSMICON); + } + else + { + cxIcon = GetSystemMetrics(SM_CXICON); + cyIcon = GetSystemMetrics(SM_CYICON); + } + } + + ret = PrivateExtractIconsW(sTemp, icon_idx, cxIcon, cyIcon, + &psfi->hIcon, 0, 1, 0); if (ret != 0 && ret != (UINT)-1) { IconNotYetLoaded=FALSE; diff --git a/dll/win32/shell32/wine/shell32_main.h b/dll/win32/shell32/wine/shell32_main.h index d40e1a164b327..ec6c1f5d01c8b 100644 --- a/dll/win32/shell32/wine/shell32_main.h +++ b/dll/win32/shell32/wine/shell32_main.h @@ -44,6 +44,9 @@ BOOL SIC_Initialize(void); void SIC_Destroy(void) DECLSPEC_HIDDEN; BOOL PidlToSicIndex (IShellFolder * sh, LPCITEMIDLIST pidl, BOOL bBigIcon, UINT uFlags, int * pIndex) DECLSPEC_HIDDEN; INT SIC_GetIconIndex (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags ) DECLSPEC_HIDDEN; +extern INT ShellLargeIconSize; +extern INT ShellSmallIconSize; +extern INT ShellIconBPP; /* Classes Root */ HRESULT HCR_GetProgIdKeyOfExtension(PCWSTR szExtension, PHKEY phKey, BOOL AllowFallback); @@ -73,10 +76,16 @@ BOOL HCR_GetFolderAttributes(LPCITEMIDLIST pidlFolder, LPDWORD dwAttributes) DEC HRESULT SHELL32_AssocGetFSDirectoryDescription(PWSTR Buf, UINT cchBuf); HRESULT SHELL32_AssocGetFileDescription(PCWSTR Name, PWSTR Buf, UINT cchBuf); - DWORD WINAPI ParseFieldA(LPCSTR src, DWORD nField, LPSTR dst, DWORD len) DECLSPEC_HIDDEN; DWORD WINAPI ParseFieldW(LPCWSTR src, DWORD nField, LPWSTR dst, DWORD len) DECLSPEC_HIDDEN; +LONG +PathProcessCommandW( + _In_ PCWSTR pszSrc, + _Out_writes_opt_(dwBuffSize) PWSTR pszDest, + _In_ INT cchDest, + _In_ DWORD dwFlags); + /**************************************************************************** * Class constructors */ @@ -139,7 +148,7 @@ void FreeChangeNotifications(void) DECLSPEC_HIDDEN; BOOL SHELL_DeleteDirectoryW(HWND hwnd, LPCWSTR pwszDir, BOOL bShowUI); BOOL SHELL_ConfirmYesNoW(HWND hWnd, int nKindOfDialog, LPCWSTR szDir); -void WINAPI _InsertMenuItemW (HMENU hmenu, UINT indexMenu, BOOL fByPosition, +BOOL WINAPI _InsertMenuItemW (HMENU hmenu, UINT indexMenu, BOOL fByPosition, UINT wID, UINT fType, LPCWSTR dwTypeData, UINT fState); static __inline BOOL SHELL_OsIsUnicode(void) diff --git a/dll/win32/shell32/wine/shellord.c b/dll/win32/shell32/wine/shellord.c index effe7f55bcd7a..376d96e7b163a 100644 --- a/dll/win32/shell32/wine/shellord.c +++ b/dll/win32/shell32/wine/shellord.c @@ -334,6 +334,7 @@ VOID WINAPI SHGetSetSettings(LPSHELLSTATE lpss, DWORD dwMask, BOOL bSet) else { DWORD read = 0, data, cb, dummy = 0; + DBG_UNREFERENCED_LOCAL_VARIABLE(dummy); if (SHELL_GlobalCounterChanged(&g_ShellStateCounter, SHELL_GCOUNTER_SHELLSTATE)) g_CachedSSF = 0; @@ -1910,7 +1911,7 @@ HRESULT WINAPI SetAppStartingCursor(HWND u, DWORD v) * The SHLoadOLE was called when OLE32.DLL was being loaded to transfer all the * information from the shell32 "mini-COM" to ole32.dll. * - * See http://blogs.msdn.com/oldnewthing/archive/2004/07/05/173226.aspx for a + * See https://devblogs.microsoft.com/oldnewthing/20040705-00/?p=38573 for a * detailed description. * * Under wine ole32.dll is always loaded as it is imported by shlwapi.dll which is diff --git a/dll/win32/shell32/wine/shellpath.c b/dll/win32/shell32/wine/shellpath.c index e55b48b1c339d..3a0b5097622b8 100644 --- a/dll/win32/shell32/wine/shellpath.c +++ b/dll/win32/shell32/wine/shellpath.c @@ -665,6 +665,154 @@ static BOOL PathMakeUniqueNameA( /************************************************************************* * PathMakeUniqueNameW [internal] */ +#ifdef __REACTOS__ +/* https://learn.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-pathmakeuniquename */ +static BOOL PathMakeUniqueNameW( + _Out_ PWSTR pszUniqueName, + _In_ UINT cchMax, + _In_ PCWSTR pszTemplate, + _In_opt_ PCWSTR pszLongPlate, /* Long template */ + _In_opt_ PCWSTR pszDir) +{ + TRACE("%p %u %s %s %s\n", + pszUniqueName, cchMax, debugstr_w(pszTemplate), + debugstr_w(pszLongPlate), debugstr_w(pszDir)); + + if (!cchMax || !pszUniqueName) + return FALSE; + + pszUniqueName[0] = UNICODE_NULL; + + PWSTR pszDest = pszUniqueName; + UINT dirLength = 0; + if (pszDir) + { + if (StringCchCopyW(pszUniqueName, cchMax - 1, pszDir) != S_OK) + return FALSE; + + pszDest = PathAddBackslashW(pszUniqueName); + if (!pszDest) + return FALSE; + + dirLength = lstrlenW(pszDir); + } + + PCWSTR pszTitle = pszLongPlate ? pszLongPlate : pszTemplate; + PCWSTR pchDotExt, formatString = L"%d"; + INT maxCount, cchTitle; + + if ( !pszTitle + || !IsLFNDriveW(pszDir) +#if (NTDDI_VERSION < NTDDI_VISTA) + || pszDir +#endif + ) + { + if (!pszTemplate) + return FALSE; + + pchDotExt = PathFindExtensionW(pszTemplate); + + cchTitle = pchDotExt - pszTemplate; + if (cchTitle > 1) + { + PCWSTR pch = pchDotExt - 1; + while (cchTitle > 1 && (L'0' <= *pch && *pch <= L'9')) + { + --cchTitle; + --pch; + } + } + +#define MSDOS_8DOT3_FILENAME_TITLE_LEN 8 + if (cchTitle > MSDOS_8DOT3_FILENAME_TITLE_LEN - 1) + cchTitle = MSDOS_8DOT3_FILENAME_TITLE_LEN - 1; + + INT extLength = lstrlenW(pchDotExt); + while (cchTitle > 1 && (dirLength + cchTitle + extLength + 1 > (cchMax - 1))) + --cchTitle; + + if (cchTitle <= 0) + maxCount = 1; + else if (cchTitle == 1) + maxCount = 10; + else + maxCount = 100; + + pszTitle = pszTemplate; + } + else + { + PCWSTR openParen = StrChrW(pszTitle, L'('); + if (openParen) + { + while (openParen) + { + PCWSTR pch = openParen + 1; + while (*pch >= L'0' && *pch <= L'9') + ++pch; + + if (*pch == L')') + break; + + openParen = StrChrW(openParen + 1, L'('); + } + + if (openParen) + { + pchDotExt = openParen + 1; + cchTitle = pchDotExt - pszTitle; + } + else + { + pchDotExt = PathFindExtensionW(pszTitle); + cchTitle = pchDotExt - pszTitle; + formatString = L" (%d)"; + } + } + else + { + pchDotExt = PathFindExtensionW(pszTitle); + cchTitle = pchDotExt - pszTitle; + formatString = L" (%d)"; + } + + INT remainingChars = cchMax - (dirLength + cchTitle + (lstrlenW(formatString) - 2)); + if (remainingChars <= 0) + maxCount = 1; + else if (remainingChars == 1) + maxCount = 10; + else if (remainingChars == 2) + maxCount = 100; + else + maxCount = 1000; + } + + if (StringCchCopyNW(pszDest, cchMax - dirLength, pszTitle, cchTitle) != S_OK) + return FALSE; + + PWSTR pchTitle = pszDest + cchTitle; + INT count; + for (count = 1; count < maxCount; ++count) + { + WCHAR tempName[MAX_PATH]; + if (StringCchPrintfW(tempName, _countof(tempName), formatString, count) != S_OK || + StringCchCatW(tempName, _countof(tempName), pchDotExt) != S_OK) + { + return FALSE; + } + + if (StringCchCopyW(pchTitle, cchMax - (pchTitle - pszUniqueName), tempName) != S_OK) + return FALSE; + + if (!PathFileExistsW(pszUniqueName)) + return TRUE; + } + + pszUniqueName[0] = UNICODE_NULL; + return FALSE; +} +#else static BOOL PathMakeUniqueNameW( LPWSTR lpszBuffer, DWORD dwBuffSize, @@ -677,6 +825,7 @@ static BOOL PathMakeUniqueNameW( debugstr_w(lpszLongName), debugstr_w(lpszPathName)); return TRUE; } +#endif /************************************************************************* * PathMakeUniqueName [SHELL32.47] @@ -981,6 +1130,7 @@ static LONG PathProcessCommandA ( return strlen(lpszPath); } +#ifndef __REACTOS__ // See ../shlexec.cpp /************************************************************************* * PathProcessCommandW */ @@ -996,6 +1146,7 @@ static LONG PathProcessCommandW ( if(lpszBuff) strcpyW(lpszBuff, lpszPath); return strlenW(lpszPath); } +#endif /************************************************************************* * PathProcessCommand (SHELL32.653) diff --git a/dll/win32/shfolder/CMakeLists.txt b/dll/win32/shfolder/CMakeLists.txt index 34f08350df24b..1b5ced3e65eaf 100644 --- a/dll/win32/shfolder/CMakeLists.txt +++ b/dll/win32/shfolder/CMakeLists.txt @@ -1,6 +1,4 @@ -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) -add_definitions(-D__WINESRC__) spec2def(shfolder.dll shfolder.spec) list(APPEND SOURCE @@ -13,3 +11,4 @@ target_link_libraries(shfolder wine) add_importlibs(shfolder shell32 kernel32 ntdll) add_dependencies(shfolder psdk) add_cd_file(TARGET shfolder DESTINATION reactos/system32 FOR all) +set_wine_module(shfolder) diff --git a/dll/win32/shimgvw/CMakeLists.txt b/dll/win32/shimgvw/CMakeLists.txt index 1a4589abd43e8..b9b55c4223312 100644 --- a/dll/win32/shimgvw/CMakeLists.txt +++ b/dll/win32/shimgvw/CMakeLists.txt @@ -3,9 +3,11 @@ spec2def(shimgvw.dll shimgvw.spec) list(APPEND SOURCE anime.c + loader.cpp shimgvw.c comsup.c shimgvw.rc + util.c ${CMAKE_CURRENT_BINARY_DIR}/shimgvw_stubs.c ${CMAKE_CURRENT_BINARY_DIR}/shimgvw.def) diff --git a/dll/win32/shimgvw/lang/pt-PT.rc b/dll/win32/shimgvw/lang/pt-PT.rc index d51396c5018bc..c224cd5f3ba65 100644 --- a/dll/win32/shimgvw/lang/pt-PT.rc +++ b/dll/win32/shimgvw/lang/pt-PT.rc @@ -1,6 +1,8 @@ -/* Portuguese Language resource file - * - * Traduzido por: Jose Carlos Jesus 17-01-2020 zecarlos1957@hotmail.com +/* + * PROJECT: ReactOS Picture and Fax Viewer + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Portuguese (Portugal) resource file + * TRANSLATOR: Copyright 2019-2025 Jose Carlos Jesus */ LANGUAGE LANG_PORTUGUESE, SUBLANG_NEUTRAL @@ -9,34 +11,34 @@ STRINGTABLE BEGIN IDS_APPTITLE "Visualizador de imagens e faxes do ReactOS" IDS_SETASDESKBG "Definir como plano de fundo da área de trabalho" - IDS_NOPREVIEW "No preview available." - IDS_PREVIEW "Pre-visualizar" + IDS_NOPREVIEW "Nenhuma pré-visualização disponível." + IDS_PREVIEW "Pré-visualizar" /* Tooltips */ IDS_TOOLTIP_NEXT_PIC "Próxima imagem" IDS_TOOLTIP_PREV_PIC "Imagem anterior" - IDS_TOOLTIP_BEST_FIT "Best fit to window (Ctrl+B)" - IDS_TOOLTIP_REAL_SIZE "Actual size (Ctrl+A)" - IDS_TOOLTIP_SLIDE_SHOW "Start slideshow (F11)" + IDS_TOOLTIP_BEST_FIT "Melhor ajuste à janela(Ctrl+B)" + IDS_TOOLTIP_REAL_SIZE "Tamanho actual (Ctrl+A)" + IDS_TOOLTIP_SLIDE_SHOW "Iniciar apresentação de diapositivos (F11)" IDS_TOOLTIP_ZOOM_IN "Zoom (+)" IDS_TOOLTIP_ZOOM_OUT "Zoom (-)" - IDS_TOOLTIP_ROT_CLOCKW "Girar no sentido dos ponteiros do relógio(Ctrl+K)" - IDS_TOOLTIP_ROT_COUNCW "Girar no sentido anti-horário (Ctrl+L)" - IDS_TOOLTIP_ROT_CWSAVE "Rotate Clockwise and Save (Lossy)" - IDS_TOOLTIP_ROT_CCWSAVE "Rotate Counterclockwise and Save (Lossy)" - IDS_TOOLTIP_DELETE "Delete (DEL)" + IDS_TOOLTIP_ROT_CLOCKW "Girar no sentido dos ponteiros do relógio (Ctrl+K)" + IDS_TOOLTIP_ROT_COUNCW "Girar no sentido contrário aos ponteiros do relógio (Ctrl+L)" + IDS_TOOLTIP_ROT_CWSAVE "Girar no sentido dos ponteiros do relógio e guardar (com perdas)" + IDS_TOOLTIP_ROT_CCWSAVE "Girar no sentido contrário aos ponteiros do relógio e guardar (com perdas)" + IDS_TOOLTIP_DELETE "Eliminar (DEL)" IDS_TOOLTIP_PRINT "Imprimir (Ctrl+P)" IDS_TOOLTIP_SAVEAS "Guardar como... (Ctrl+S)" - IDS_TOOLTIP_MODIFY "Modify (Ctrl+E)" - IDS_TOOLTIP_HELP_TOC "Help topics (F1)" + IDS_TOOLTIP_MODIFY "Modificar (Ctrl+E)" + IDS_TOOLTIP_HELP_TOC "Tópicos da ajuda (F1)" END STRINGTABLE BEGIN - IDS_EMF_FILE "EMF Image" - IDS_GIF_FILE "GIF Image" - IDS_JPG_FILE "JPEG Image" - IDS_BMP_FILE "Bitmap Image" - IDS_PNG_FILE "PNG Image" - IDS_TIF_FILE "TIF Image" - IDS_WMF_FILE "WMF Image" + IDS_EMF_FILE "Imagem EMF" + IDS_GIF_FILE "Imagem GIF" + IDS_JPG_FILE "Imagem JPEG" + IDS_BMP_FILE "Imagem Bitmap" + IDS_PNG_FILE "Imagem PNG" + IDS_TIF_FILE "Imagem TIF" + IDS_WMF_FILE "Imagem WMF" END diff --git a/dll/win32/shimgvw/loader.cpp b/dll/win32/shimgvw/loader.cpp new file mode 100644 index 0000000000000..bde8b12ac133f --- /dev/null +++ b/dll/win32/shimgvw/loader.cpp @@ -0,0 +1,283 @@ +/* + * PROJECT: ReactOS Picture and Fax Viewer + * LICENSE: GPL-2.0 (https://spdx.org/licenses/GPL-2.0) + * PURPOSE: Image file browsing and manipulation + * COPYRIGHT: Copyright 2025 Whindmar Saksit + */ + +#include +#include +#include +using namespace Gdiplus; +#include "shimgvw.h" + +#define HResultFromWin32 SHIMGVW_HResultFromWin32 + +static HRESULT Read(HANDLE hFile, void* Buffer, DWORD Size) +{ + DWORD Transferred; + if (!ReadFile(hFile, Buffer, Size, &Transferred, NULL)) + return HResultFromWin32(GetLastError()); + return Size == Transferred ? S_OK : HResultFromWin32(ERROR_HANDLE_EOF); +} + +struct IMAGESTATS +{ + UINT w, h; + BYTE bpp; +}; + +class BitmapInfoHeader : public BITMAPINFOHEADER +{ +public: + BitmapInfoHeader() {} + BitmapInfoHeader(const void* pbmiHeader) { Initialize(pbmiHeader); } + + void Initialize(const void* pbmiHeader) + { + BITMAPINFOHEADER& bih = *(BITMAPINFOHEADER*)pbmiHeader; + if (bih.biSize >= sizeof(BITMAPINFOHEADER)) + { + CopyMemory(this, &bih, min(bih.biSize, sizeof(*this))); + } + else + { + ZeroMemory(this, sizeof(*this)); + BITMAPCOREHEADER& bch = *(BITMAPCOREHEADER*)pbmiHeader; + if (bih.biSize >= sizeof(BITMAPCOREHEADER)) + { + biSize = bch.bcSize; + biWidth = bch.bcWidth; + biHeight = bch.bcHeight; + biPlanes = bch.bcPlanes; + biBitCount = bch.bcBitCount; + biCompression = BI_RGB; + } + } + } +}; + +#include +union PNGSIGNATURE { UINT64 number; BYTE bytes[8]; }; +struct PNGCHUNKHEADER { UINT length, type; }; +struct PNGCHUNKFOOTER { UINT crc; }; +struct PNGIHDR { UINT w, h; BYTE depth, type, compression, filter, interlace; }; +struct PNGSIGANDIHDR +{ + PNGSIGNATURE sig; + PNGCHUNKHEADER chunkheader; + PNGIHDR ihdr; + PNGCHUNKFOOTER chunkfooter; +}; +struct PNGFOOTER { PNGCHUNKHEADER chunkheader; PNGCHUNKFOOTER footer; }; +#include + +static inline bool IsPngSignature(const void* buffer) +{ + const BYTE* p = (BYTE*)buffer; + return p[0] == 0x89 && p[1] == 'P' && p[2] == 'N' && p[3] == 'G' && + p[4] == 0x0D && p[5] == 0x0A && p[6] == 0x1A && p[7] == 0x0A; +} + +static inline bool IsPngSignature(const void* buffer, SIZE_T size) +{ + return size >= sizeof(PNGSIGNATURE) && IsPngSignature(buffer); +} + +static BYTE GetPngBppFromIHDRData(const void* buffer) +{ + static const BYTE channels[] = { 1, 0, 3, 1, 2, 0, 4 }; + const BYTE* p = (BYTE*)buffer, depth = p[8], type = p[8 + 1]; + return (depth <= 16 && type <= 6) ? channels[type] * depth : 0; +} + +static bool GetInfoFromPng(const void* file, SIZE_T size, IMAGESTATS& info) +{ + C_ASSERT(sizeof(PNGSIGNATURE) == 8); + C_ASSERT(sizeof(PNGSIGANDIHDR) == 8 + (4 + 4 + (4 + 4 + 5) + 4)); + + if (size > sizeof(PNGSIGANDIHDR) + sizeof(PNGFOOTER) && IsPngSignature(file)) + { + const UINT PNGIHDRSIG = 0x52444849; // Note: Big endian + const UINT* chunkhdr = (UINT*)((char*)file + sizeof(PNGSIGNATURE)); + if (BigToHost32(chunkhdr[0]) >= sizeof(PNGIHDR) && chunkhdr[1] == PNGIHDRSIG) + { + info.w = BigToHost32(chunkhdr[2]); + info.h = BigToHost32(chunkhdr[3]); + info.bpp = GetPngBppFromIHDRData(&chunkhdr[2]); + return info.bpp != 0; + } + } + return false; +} + +static bool GetInfoFromBmp(const void* pBitmapInfo, IMAGESTATS& info) +{ + BitmapInfoHeader bih(pBitmapInfo); + info.w = bih.biWidth; + info.h = abs((int)bih.biHeight); + UINT bpp = bih.biBitCount * bih.biPlanes; + info.bpp = LOBYTE(bpp); + return info.w && bpp == info.bpp; +} + +static bool GetInfoFromIcoBmp(const void* pBitmapInfo, IMAGESTATS& info) +{ + bool ret = GetInfoFromBmp(pBitmapInfo, info); + info.h /= 2; // Don't include mask + return ret && info.h; +} + +EXTERN_C PCWSTR GetExtraExtensionsGdipList(VOID) +{ + return L"*.CUR"; // "*.FOO;*.BAR" etc. +} + +static void OverrideFileContent(HGLOBAL& hMem, DWORD& Size) +{ + PBYTE buffer = (PBYTE)GlobalLock(hMem); + if (!buffer) + return; + + // TODO: We could try to load an ICO/PNG/BMP resource from a PE file here into buffer + + // ICO/CUR + struct ICOHDR { WORD Sig, Type, Count; }; + ICOHDR* pIcoHdr = (ICOHDR*)buffer; + if (Size > sizeof(ICOHDR) && !pIcoHdr->Sig && pIcoHdr->Type > 0 && pIcoHdr->Type < 3 && pIcoHdr->Count) + { + const UINT minbmp = sizeof(BITMAPCOREHEADER) + 1, minpng = sizeof(PNGSIGANDIHDR); + const UINT minfile = min(minbmp, minpng), count = pIcoHdr->Count; + struct ICOENTRY { BYTE w, h, pal, null; WORD planes, bpp; UINT size, offset; }; + ICOENTRY* entries = (ICOENTRY*)&pIcoHdr[1]; + if (Size - sizeof(ICOHDR) > (sizeof(ICOENTRY) + minfile) * count) + { + UINT64 best = 0; + int bestindex = -1; + // Inspect all the images and find the "best" image + for (UINT i = 0; i < count; ++i) + { + BOOL valid = FALSE; + IMAGESTATS info; + const BYTE* data = buffer + entries[i].offset; + if (IsPngSignature(data, entries[i].size)) + valid = GetInfoFromPng(data, entries[i].size, info); + else + valid = GetInfoFromIcoBmp(data, info); + + if (valid) + { + // Note: This treats bpp as more important compared to LookupIconIdFromDirectoryEx + UINT64 score = UINT64(info.w) * info.h * info.bpp; + if (score > best) + { + best = score; + bestindex = i; + } + } + } + if (bestindex >= 0) + { + if (pIcoHdr->Type == 2) + { + // GDI+ does not support .cur files, convert to .ico + pIcoHdr->Type = 1; +#if 0 // Because we are already overriding the order, we don't need to correct the ICOENTRY lookup info + for (UINT i = 0; i < count; ++i) + { + BitmapInfoHeader bih; + const BYTE* data = buffer + entries[i].offset; + if (IsPngSignature(data, entries[i].size)) + { + IMAGESTATS info; + if (!GetInfoFromPng(data, entries[i].size, info)) + continue; + bih.biPlanes = 1; + bih.biBitCount = info.bpp; + entries[i].pal = 0; + } + else + { + bih.Initialize(data); + entries[i].pal = bih.biPlanes * bih.biBitCount <= 8 ? bih.biClrUsed : 0; + } + entries[i].planes = (WORD)bih.biPlanes; + entries[i].bpp = (WORD)bih.biBitCount; + } +#endif + } +#if 0 + // Convert to a .ico with a single image + pIcoHdr->Count = 1; + const BYTE* data = buffer + entries[bestindex].offset; + entries[0] = entries[bestindex]; + entries[0].offset = (UINT)UINT_PTR((PBYTE)&entries[1] - buffer); + MoveMemory(buffer + entries[0].offset, data, entries[0].size); + Size = entries[0].offset + entries[0].size; +#else + // Place the best image first, GDI+ will return the first image + ICOENTRY temp = entries[0]; + entries[0] = entries[bestindex]; + entries[bestindex] = temp; +#endif + } + } + } + + GlobalUnlock(hMem); +} + +static HRESULT LoadImageFromStream(IStream* pStream, GpImage** ppImage) +{ + Status status = DllExports::GdipLoadImageFromStream(pStream, ppImage); + return HResultFromGdiplus(status); +} + +static HRESULT LoadImageFromFileHandle(HANDLE hFile, GpImage** ppImage) +{ + DWORD size = GetFileSize(hFile, NULL); + if (!size || size == INVALID_FILE_SIZE) + return HResultFromWin32(ERROR_NOT_SUPPORTED); + + HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, size); + if (!hMem) + return HResultFromWin32(ERROR_OUTOFMEMORY); + HRESULT hr = E_FAIL; + void* buffer = GlobalLock(hMem); + if (buffer) + { + hr = Read(hFile, buffer, size); + GlobalUnlock(hMem); + if (SUCCEEDED(hr)) + { + OverrideFileContent(hMem, size); + IStream* pStream; + if (SUCCEEDED(hr = CreateStreamOnHGlobal(hMem, TRUE, &pStream))) + { + // CreateStreamOnHGlobal does not know the real size, we do + pStream->SetSize(MakeULargeInteger(size)); + hr = LoadImageFromStream(pStream, ppImage); + pStream->Release(); // Calls GlobalFree + return hr; + } + } + } + GlobalFree(hMem); + return hr; +} + +EXTERN_C HRESULT LoadImageFromPath(LPCWSTR Path, GpImage** ppImage) +{ + // NOTE: GdipLoadImageFromFile locks the file. + // Avoid file locking by using GdipLoadImageFromStream and memory stream. + + HANDLE hFile = CreateFileW(Path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE, + NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL); + if (hFile != INVALID_HANDLE_VALUE) + { + HRESULT hr = LoadImageFromFileHandle(hFile, ppImage); + CloseHandle(hFile); + return hr; + } + return HResultFromWin32(GetLastError()); +} diff --git a/dll/win32/shimgvw/resource.h b/dll/win32/shimgvw/resource.h index ec2fbf116bd87..8398a23818e5e 100644 --- a/dll/win32/shimgvw/resource.h +++ b/dll/win32/shimgvw/resource.h @@ -10,6 +10,9 @@ /* Cursors */ #define IDC_HANDDRAG 100 +/* Control IDs */ +#define IDC_TOOLBAR 40 + /* Toolbar images */ #define IDB_PREV_PIC 50 #define IDB_NEXT_PIC 51 @@ -30,6 +33,11 @@ /* ToolBar buttons */ #define IDC_TOOL_BASE 500 +#define IDC_ACCEL_BASE (IDC_TOOL_BASE + 100) /* Accelerator commands not on the toolbar */ + +#define IDC_TOGGLEFULLSCREEN (IDC_ACCEL_BASE + 0) +#define IDC_INCTIMER (IDC_ACCEL_BASE + 1) +#define IDC_DECTIMER (IDC_ACCEL_BASE + 2) #define IDC_PREV_PIC (IDC_TOOL_BASE + 0) #define IDC_NEXT_PIC (IDC_TOOL_BASE + 1) diff --git a/dll/win32/shimgvw/shimgvw.c b/dll/win32/shimgvw/shimgvw.c index 693b499761fb2..d1d5c6b204018 100644 --- a/dll/win32/shimgvw/shimgvw.c +++ b/dll/win32/shimgvw/shimgvw.c @@ -4,6 +4,7 @@ * PURPOSE: Image file browsing and manipulation * COPYRIGHT: Copyright Dmitry Chapyshev (dmitry@reactos.org) * Copyright 2018-2023 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) + * Copyright 2025 Whindmar Saksit */ #include "shimgvw.h" @@ -13,6 +14,9 @@ #include #include +EXTERN_C PCWSTR GetExtraExtensionsGdipList(VOID); +EXTERN_C HRESULT LoadImageFromPath(LPCWSTR Path, GpImage** ppImage); + /* Toolbar image size */ #define TB_IMAGE_WIDTH 16 #define TB_IMAGE_HEIGHT 16 @@ -20,13 +24,17 @@ /* Slide show timer */ #define SLIDESHOW_TIMER_ID 0xFACE #define SLIDESHOW_TIMER_INTERVAL 5000 /* 5 seconds */ +#define HIDECURSOR_TIMER_ID 0xBABE +#define HIDECURSOR_TIMER_TIMEOUT 3000 HINSTANCE g_hInstance = NULL; HWND g_hMainWnd = NULL; HWND g_hwndFullscreen = NULL; SHIMGVW_FILENODE * g_pCurrentFile = NULL; +WCHAR g_szFile[MAX_PATH]; GpImage * g_pImage = NULL; SHIMGVW_SETTINGS g_Settings; +UINT g_ImageId; static const UINT s_ZoomSteps[] = { @@ -109,11 +117,13 @@ typedef struct tagPREVIEW_DATA INT m_xScrollOffset; INT m_yScrollOffset; UINT m_nMouseDownMsg; + UINT m_nTimerInterval; + BOOL m_bHideCursor; POINT m_ptOrigin; - IStream *m_pMemStream; - WCHAR m_szFile[MAX_PATH]; } PREVIEW_DATA, *PPREVIEW_DATA; +static VOID Preview_ToggleSlideShowEx(PPREVIEW_DATA pData, BOOL StartTimer); + static inline PPREVIEW_DATA Preview_GetData(HWND hwnd) { @@ -131,14 +141,34 @@ Preview_RestartTimer(HWND hwnd) { if (!Preview_IsMainWnd(hwnd)) { + PPREVIEW_DATA pData = Preview_GetData(hwnd); KillTimer(hwnd, SLIDESHOW_TIMER_ID); - SetTimer(hwnd, SLIDESHOW_TIMER_ID, SLIDESHOW_TIMER_INTERVAL, NULL); + if (pData->m_nTimerInterval) + SetTimer(hwnd, SLIDESHOW_TIMER_ID, pData->m_nTimerInterval, NULL); + } +} + +static VOID +Preview_ChangeSlideShowTimer(PPREVIEW_DATA pData, BOOL bSlower) +{ + BOOL IsFullscreen = !Preview_IsMainWnd(pData->m_hwnd); + enum { mintime = 1000, maxtime = SLIDESHOW_TIMER_INTERVAL * 3, step = 1000 }; + UINT interval = pData->m_nTimerInterval ? pData->m_nTimerInterval : SLIDESHOW_TIMER_INTERVAL; + if (IsFullscreen) + { + interval = bSlower ? min(interval + step, maxtime) : max(interval - step, mintime); + if (pData->m_nTimerInterval != interval) + { + pData->m_nTimerInterval = interval; + Preview_RestartTimer(pData->m_hwnd); + } } } static VOID -ZoomWnd_UpdateScroll(PPREVIEW_DATA pData, HWND hwnd, BOOL bResetPos) +ZoomWnd_UpdateScroll(PPREVIEW_DATA pData, BOOL bResetPos) { + HWND hwnd = pData->m_hwndZoom; RECT rcClient; UINT ImageWidth, ImageHeight, ZoomedWidth, ZoomedHeight; SCROLLINFO si; @@ -221,10 +251,10 @@ Preview_UpdateZoom(PPREVIEW_DATA pData, UINT NewZoom, BOOL bEnableBestFit, BOOL bEnableZoomOut = (NewZoom > MIN_ZOOM); /* Update toolbar buttons */ - PostMessageW(hToolBar, TB_ENABLEBUTTON, IDC_ZOOM_OUT, bEnableZoomOut); - PostMessageW(hToolBar, TB_ENABLEBUTTON, IDC_ZOOM_IN, bEnableZoomIn); - PostMessageW(hToolBar, TB_ENABLEBUTTON, IDC_BEST_FIT, bEnableBestFit); - PostMessageW(hToolBar, TB_ENABLEBUTTON, IDC_REAL_SIZE, bEnableRealSize); + SendMessageW(hToolBar, TB_ENABLEBUTTON, IDC_BEST_FIT, bEnableBestFit); + SendMessageW(hToolBar, TB_ENABLEBUTTON, IDC_REAL_SIZE, NewZoom != 100); + SendMessageW(hToolBar, TB_ENABLEBUTTON, IDC_ZOOM_IN, bEnableZoomIn); + SendMessageW(hToolBar, TB_ENABLEBUTTON, IDC_ZOOM_OUT, bEnableZoomOut); /* Redraw the display window */ InvalidateRect(pData->m_hwndZoom, NULL, TRUE); @@ -233,7 +263,7 @@ Preview_UpdateZoom(PPREVIEW_DATA pData, UINT NewZoom, BOOL bEnableBestFit, BOOL Preview_RestartTimer(pData->m_hwnd); /* Update scroll info */ - ZoomWnd_UpdateScroll(pData, pData->m_hwndZoom, FALSE); + ZoomWnd_UpdateScroll(pData, FALSE); } static VOID @@ -344,68 +374,23 @@ Preview_pFreeImage(PPREVIEW_DATA pData) GdipDisposeImage(g_pImage); g_pImage = NULL; } - - if (pData->m_pMemStream) - { - pData->m_pMemStream->lpVtbl->Release(pData->m_pMemStream); - pData->m_pMemStream = NULL; - } - - pData->m_szFile[0] = UNICODE_NULL; -} - -IStream* MemStreamFromFile(LPCWSTR pszFileName) -{ - HANDLE hFile; - DWORD dwFileSize, dwRead; - LPBYTE pbMemFile = NULL; - IStream *pStream; - - hFile = CreateFileW(pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, - OPEN_EXISTING, 0, NULL); - if (hFile == INVALID_HANDLE_VALUE) - return NULL; - - dwFileSize = GetFileSize(hFile, NULL); - pbMemFile = QuickAlloc(dwFileSize, FALSE); - if (!dwFileSize || (dwFileSize == INVALID_FILE_SIZE) || !pbMemFile) - { - CloseHandle(hFile); - return NULL; - } - - if (!ReadFile(hFile, pbMemFile, dwFileSize, &dwRead, NULL) || (dwRead != dwFileSize)) - { - QuickFree(pbMemFile); - CloseHandle(hFile); - return NULL; - } - - CloseHandle(hFile); - pStream = SHCreateMemStream(pbMemFile, dwFileSize); - QuickFree(pbMemFile); - return pStream; } static VOID Preview_pLoadImage(PPREVIEW_DATA pData, LPCWSTR szOpenFileName) { + HRESULT hr; + BOOL bCanDel; Preview_pFreeImage(pData); + InvalidateRect(pData->m_hwnd, NULL, FALSE); /* Schedule redraw in case we change to "No preview" */ - pData->m_pMemStream = MemStreamFromFile(szOpenFileName); - if (!pData->m_pMemStream) + GetFullPathNameW(szOpenFileName, _countof(g_szFile), g_szFile, NULL); + hr = LoadImageFromPath(szOpenFileName, &g_pImage); + bCanDel = hr != HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) && hr != HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND); + SendDlgItemMessageW(g_hMainWnd, IDC_TOOLBAR, TB_ENABLEBUTTON, IDC_DELETE, bCanDel); + if (FAILED(hr)) { - DPRINT1("MemStreamFromFile() failed\n"); - Preview_UpdateTitle(pData, NULL); - return; - } - - /* NOTE: GdipLoadImageFromFile locks the file. - Avoid file locking by using GdipLoadImageFromStream and memory stream. */ - GdipLoadImageFromStream(pData->m_pMemStream, &g_pImage); - if (!g_pImage) - { - DPRINT1("GdipLoadImageFromStream() failed\n"); + DPRINT1("GdipLoadImageFromStream() failed, %d\n", hr); Preview_pFreeImage(pData); Preview_UpdateTitle(pData, NULL); return; @@ -413,13 +398,14 @@ Preview_pLoadImage(PPREVIEW_DATA pData, LPCWSTR szOpenFileName) Anime_LoadInfo(&pData->m_Anime); - SHAddToRecentDocs(SHARD_PATHW, szOpenFileName); - GetFullPathNameW(szOpenFileName, _countof(pData->m_szFile), pData->m_szFile, NULL); - /* Reset zoom and redraw display */ Preview_ResetZoom(pData); + SHAddToRecentDocs(SHARD_PATHW, g_szFile); + Preview_UpdateTitle(pData, g_szFile); - Preview_UpdateTitle(pData, szOpenFileName); + ++g_ImageId; + EnableCommandIfVerbExists(g_ImageId, g_hMainWnd, IDC_PRINT, L"print", g_szFile); + EnableCommandIfVerbExists(g_ImageId, g_hMainWnd, IDC_MODIFY, L"edit", g_szFile); } static VOID @@ -575,15 +561,17 @@ Preview_pSaveImageAs(PPREVIEW_DATA pData) static VOID Preview_pPrintImage(PPREVIEW_DATA pData) { - /* FIXME */ + ShellExecuteVerb(g_hMainWnd, L"print", g_szFile, FALSE); } static VOID Preview_UpdateUI(PPREVIEW_DATA pData) { BOOL bEnable = (g_pImage != NULL); - PostMessageW(pData->m_hwndToolBar, TB_ENABLEBUTTON, IDC_SAVEAS, bEnable); - PostMessageW(pData->m_hwndToolBar, TB_ENABLEBUTTON, IDC_PRINT, bEnable); + SendMessageW(pData->m_hwndToolBar, TB_ENABLEBUTTON, IDC_SAVEAS, bEnable); + // These will be validated and enabled later by EnableCommandIfVerbExists + SendMessageW(pData->m_hwndToolBar, TB_ENABLEBUTTON, IDC_PRINT, FALSE); + SendMessageW(pData->m_hwndToolBar, TB_ENABLEBUTTON, IDC_MODIFY, FALSE); } static VOID @@ -592,14 +580,22 @@ Preview_UpdateImage(PPREVIEW_DATA pData) if (!Preview_IsMainWnd(pData->m_hwnd)) Preview_ResetZoom(pData); - ZoomWnd_UpdateScroll(pData, pData->m_hwndZoom, TRUE); + ZoomWnd_UpdateScroll(pData, TRUE); +} + +static VOID +Preview_LoadImage(PPREVIEW_DATA pData, SHIMGVW_FILENODE *pNode) +{ + Preview_pLoadImageFromNode(pData, pNode); + Preview_UpdateImage(pData); + Preview_UpdateUI(pData); } static SHIMGVW_FILENODE* pBuildFileList(LPCWSTR szFirstFile) { HANDLE hFindHandle; - WCHAR *extension; + WCHAR *extension, *buffer; WCHAR szSearchPath[MAX_PATH]; WCHAR szSearchMask[MAX_PATH]; WCHAR szFileTypes[MAX_PATH]; @@ -608,15 +604,19 @@ pBuildFileList(LPCWSTR szFirstFile) SHIMGVW_FILENODE *root = NULL; SHIMGVW_FILENODE *conductor = NULL; ImageCodecInfo *codecInfo; - UINT num; - UINT size; + UINT num = 0, size = 0, ExtraSize = 0; UINT j; + const PCWSTR ExtraExtensions = GetExtraExtensionsGdipList(); + const UINT ExtraCount = ExtraExtensions[0] ? 1 : 0; + if (ExtraCount) + ExtraSize += sizeof(*codecInfo) + (wcslen(ExtraExtensions) + 1) * sizeof(WCHAR); + StringCbCopyW(szSearchPath, sizeof(szSearchPath), szFirstFile); PathRemoveFileSpecW(szSearchPath); GdipGetImageDecodersSize(&num, &size); - codecInfo = QuickAlloc(size, FALSE); + codecInfo = QuickAlloc(size + ExtraSize, FALSE); if (!codecInfo) { DPRINT1("QuickAlloc() failed in pLoadFileList()\n"); @@ -624,6 +624,10 @@ pBuildFileList(LPCWSTR szFirstFile) } GdipGetImageDecoders(num, size, codecInfo); + buffer = (PWSTR)((UINT_PTR)codecInfo + size + (sizeof(*codecInfo) * ExtraCount)); + if (ExtraCount) + codecInfo[num].FilenameExtension = wcscpy(buffer, ExtraExtensions); + num += ExtraCount; root = QuickAlloc(sizeof(SHIMGVW_FILENODE), FALSE); if (!root) @@ -637,6 +641,7 @@ pBuildFileList(LPCWSTR szFirstFile) for (j = 0; j < num; ++j) { + // FIXME: Parse each FilenameExtension list to bypass szFileTypes limit StringCbCopyW(szFileTypes, sizeof(szFileTypes), codecInfo[j].FilenameExtension); extension = wcstok(szFileTypes, L";"); @@ -950,7 +955,7 @@ Preview_CreateToolBar(PPREVIEW_DATA pData) style |= CCS_BOTTOM; hwndToolBar = CreateWindowExW(0, TOOLBARCLASSNAMEW, NULL, style, - 0, 0, 0, 0, pData->m_hwnd, NULL, g_hInstance, NULL); + 0, 0, 0, 0, pData->m_hwnd, (HMENU)IDC_TOOLBAR, g_hInstance, NULL); if (!hwndToolBar) return FALSE; @@ -985,11 +990,24 @@ Preview_EndSlideShow(HWND hwnd) return; KillTimer(hwnd, SLIDESHOW_TIMER_ID); + ShowWindow(g_hMainWnd, SW_SHOW); ShowWindow(hwnd, SW_HIDE); - ShowWindow(g_hMainWnd, SW_SHOWNORMAL); Preview_ResetZoom(Preview_GetData(g_hMainWnd)); } +static VOID +GenerateSetCursor(HWND hwnd, UINT uMsg) +{ + SendMessage(hwnd, WM_SETCURSOR, (WPARAM)hwnd, MAKELONG(HTCLIENT, uMsg)); +} + +static VOID +ZoomWnd_StopHideCursor(PPREVIEW_DATA pData) +{ + pData->m_bHideCursor = FALSE; + KillTimer(pData->m_hwndZoom, HIDECURSOR_TIMER_ID); +} + static VOID ZoomWnd_OnButtonDown(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { @@ -1002,6 +1020,7 @@ ZoomWnd_OnButtonDown(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return; } + ZoomWnd_StopHideCursor(pData); pData->m_nMouseDownMsg = uMsg; pData->m_ptOrigin.x = GET_X_LPARAM(lParam); pData->m_ptOrigin.y = GET_Y_LPARAM(lParam); @@ -1015,6 +1034,13 @@ ZoomWnd_OnMouseMove(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) PPREVIEW_DATA pData = Preview_GetData(hwnd); POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; + if (!Preview_IsMainWnd(pData->m_hwnd)) + { + ZoomWnd_StopHideCursor(pData); + if (!pData->m_nMouseDownMsg) + SetTimer(hwnd, HIDECURSOR_TIMER_ID, HIDECURSOR_TIMER_TIMEOUT, NULL); + } + if (pData->m_nMouseDownMsg == WM_MBUTTONDOWN) { INT x = GetScrollPos(hwnd, SB_HORZ) - (pt.x - pData->m_ptOrigin.x); @@ -1034,6 +1060,12 @@ ZoomWnd_OnSetCursor(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) SetCursor(LoadCursorW(g_hInstance, MAKEINTRESOURCEW(IDC_HANDDRAG))); return TRUE; } + + if (pData->m_bHideCursor) + { + SetCursor(NULL); /* Hide cursor in fullscreen */ + return TRUE; + } return FALSE; } @@ -1041,8 +1073,15 @@ static VOID ZoomWnd_OnButtonUp(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { PPREVIEW_DATA pData = Preview_GetData(hwnd); + BOOL wasdrag = pData->m_nMouseDownMsg == WM_MBUTTONDOWN; + pData->m_nMouseDownMsg = 0; + if (wasdrag) + GenerateSetCursor(hwnd, uMsg); /* Reset to default cursor */ ReleaseCapture(); + + if (!Preview_IsMainWnd(pData->m_hwnd)) + SetTimer(hwnd, HIDECURSOR_TIMER_ID, HIDECURSOR_TIMER_TIMEOUT, NULL); } static VOID @@ -1165,6 +1204,12 @@ ZoomWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case WM_RBUTTONUP: { ZoomWnd_OnButtonUp(hwnd, uMsg, wParam, lParam); + goto doDefault; + } + case WM_LBUTTONDBLCLK: + { + if (Preview_IsMainWnd(pData->m_hwnd)) + Preview_ToggleSlideShowEx(pData, FALSE); break; } case WM_PAINT: @@ -1178,17 +1223,32 @@ ZoomWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) (SHORT)HIWORD(wParam), (UINT)LOWORD(wParam)); break; } + case WM_CONTEXTMENU: + if (Preview_IsMainWnd(pData->m_hwnd) && *g_szFile) + DoShellContextMenuOnFile(hwnd, g_szFile, lParam); + break; case WM_HSCROLL: case WM_VSCROLL: ZoomWnd_OnHVScroll(pData, hwnd, wParam, uMsg == WM_VSCROLL); break; case WM_TIMER: { + if (wParam == HIDECURSOR_TIMER_ID) + { + ZoomWnd_StopHideCursor(pData); + if (IsWindowVisible(hwnd)) + { + pData->m_bHideCursor = TRUE; + GenerateSetCursor(hwnd, uMsg); + } + } if (Anime_OnTimer(&pData->m_Anime, wParam)) + { InvalidateRect(hwnd, NULL, FALSE); + } break; } - default: + default: doDefault: { return DefWindowProcW(hwnd, uMsg, wParam, lParam); } @@ -1249,9 +1309,7 @@ Preview_OnCreate(HWND hwnd, LPCREATESTRUCT pCS) PathUnquoteSpacesW(szFile); g_pCurrentFile = pBuildFileList(szFile); - Preview_pLoadImageFromNode(pData, g_pCurrentFile); - Preview_UpdateImage(pData); - Preview_UpdateUI(pData); + Preview_LoadImage(pData, g_pCurrentFile); } return TRUE; @@ -1298,7 +1356,9 @@ Preview_OnSize(HWND hwnd) MoveWindow(pData->m_hwndZoom, 0, 0, cx, cy - (rc.bottom - rc.top), TRUE); - if (!IsIconic(hwnd)) /* Is it not minimized? */ + if (pData->m_nZoomPercents > 100) + ZoomWnd_UpdateScroll(pData, FALSE); + else if (!IsIconic(hwnd)) /* Is it not minimized? */ Preview_ResetZoom(pData); Preview_OnMoveSize(hwnd); @@ -1313,14 +1373,11 @@ static VOID Preview_Delete(PPREVIEW_DATA pData) { WCHAR szCurFile[MAX_PATH + 1], szNextFile[MAX_PATH]; - HWND hwnd = pData->m_hwnd; - SHFILEOPSTRUCTW FileOp = { hwnd, FO_DELETE }; - - if (!pData->m_szFile[0]) - return; + SHFILEOPSTRUCTW FileOp = { pData->m_hwnd, FO_DELETE }; + UINT error; /* FileOp.pFrom must be double-null-terminated */ - GetFullPathNameW(pData->m_szFile, _countof(szCurFile) - 1, szCurFile, NULL); + GetFullPathNameW(g_szFile, _countof(szCurFile) - 1, szCurFile, NULL); szCurFile[_countof(szCurFile) - 2] = UNICODE_NULL; /* Avoid buffer overrun */ szCurFile[lstrlenW(szCurFile) + 1] = UNICODE_NULL; @@ -1333,46 +1390,26 @@ Preview_Delete(PPREVIEW_DATA pData) /* Confirm file deletion and delete if allowed */ FileOp.pFrom = szCurFile; - FileOp.fFlags = FOF_ALLOWUNDO; - if (SHFileOperationW(&FileOp) != 0) - { - DPRINT("Preview_Delete: SHFileOperationW() failed or canceled\n"); + FileOp.fFlags = GetKeyState(VK_SHIFT) < 0 ? 0 : FOF_ALLOWUNDO; + error = g_szFile[0] ? SHFileOperationW(&FileOp) : ERROR_FILE_NOT_FOUND; + if (error) return; - } /* Reload the file list and go next file */ pFreeFileList(g_pCurrentFile); g_pCurrentFile = pBuildFileList(szNextFile); - Preview_pLoadImageFromNode(pData, g_pCurrentFile); + Preview_LoadImage(pData, g_pCurrentFile); } static VOID Preview_Edit(HWND hwnd) { - SHELLEXECUTEINFOW sei; - PPREVIEW_DATA pData = Preview_GetData(hwnd); - - if (!pData->m_szFile[0]) - return; - - ZeroMemory(&sei, sizeof(sei)); - sei.cbSize = sizeof(sei); - sei.lpVerb = L"edit"; - sei.lpFile = pData->m_szFile; - sei.nShow = SW_SHOWNORMAL; - if (!ShellExecuteExW(&sei)) - { - DPRINT1("Preview_Edit: ShellExecuteExW() failed with code %ld\n", GetLastError()); - } - else - { - // Destroy the window to quit the application - DestroyWindow(hwnd); - } + PPREVIEW_DATA pData = Preview_GetData(g_hMainWnd); + ShellExecuteVerb(pData->m_hwnd, L"edit", g_szFile, TRUE); } static VOID -Preview_ToggleSlideShow(PPREVIEW_DATA pData) +Preview_ToggleSlideShowEx(PPREVIEW_DATA pData, BOOL StartTimer) { if (!IsWindow(g_hwndFullscreen)) { @@ -1385,18 +1422,26 @@ Preview_ToggleSlideShow(PPREVIEW_DATA pData) if (IsWindowVisible(g_hwndFullscreen)) { - ShowWindow(g_hwndFullscreen, SW_HIDE); - ShowWindow(g_hMainWnd, SW_SHOWNORMAL); - KillTimer(g_hwndFullscreen, SLIDESHOW_TIMER_ID); + Preview_EndSlideShow(g_hwndFullscreen); } else { - ShowWindow(g_hMainWnd, SW_HIDE); + PPREVIEW_DATA pSlideData = Preview_GetData(g_hwndFullscreen); + pSlideData->m_nTimerInterval = StartTimer ? SLIDESHOW_TIMER_INTERVAL : 0; ShowWindow(g_hwndFullscreen, SW_SHOWMAXIMIZED); + ShowWindow(g_hMainWnd, SW_HIDE); + Preview_ResetZoom(pSlideData); Preview_RestartTimer(g_hwndFullscreen); + PostMessage(pSlideData->m_hwndZoom, WM_MOUSEMOVE, 0, 0); /* Start hide cursor */ } } +static inline VOID +Preview_ToggleSlideShow(PPREVIEW_DATA pData) +{ + Preview_ToggleSlideShowEx(pData, TRUE); +} + static VOID Preview_GoNextPic(PPREVIEW_DATA pData, BOOL bNext) { @@ -1407,16 +1452,28 @@ Preview_GoNextPic(PPREVIEW_DATA pData, BOOL bNext) g_pCurrentFile = g_pCurrentFile->Next; else g_pCurrentFile = g_pCurrentFile->Prev; - Preview_pLoadImageFromNode(pData, g_pCurrentFile); - Preview_UpdateImage(pData); - Preview_UpdateUI(pData); + Preview_LoadImage(pData, g_pCurrentFile); } } +static HRESULT +IsCommandEnabled(UINT nCmdId) +{ + HWND hToolbar = GetDlgItem(g_hMainWnd, IDC_TOOLBAR); + LRESULT Ok = SendMessageW(hToolbar, TB_ISBUTTONENABLED, nCmdId, 0); + return Ok ? S_OK : SendMessageW(hToolbar, TB_COMMANDTOINDEX, nCmdId, 0) != -1 ? S_FALSE : E_FAIL; +} + static VOID -Preview_OnCommand(HWND hwnd, UINT nCommandID) +Preview_OnCommand(HWND hwnd, WPARAM wParam, LPARAM lParam) { PPREVIEW_DATA pData = Preview_GetData(hwnd); + UINT nCommandID = LOWORD(wParam); + if ((!HIWORD(wParam) || !lParam) && IsCommandEnabled(nCommandID) == S_FALSE) + { + MessageBeep(MB_ICONWARNING); + return; + } switch (nCommandID) { @@ -1452,6 +1509,15 @@ Preview_OnCommand(HWND hwnd, UINT nCommandID) Preview_EndSlideShow(hwnd); break; + case IDC_TOGGLEFULLSCREEN: + Preview_ToggleSlideShowEx(pData, FALSE); + break; + + case IDC_INCTIMER: + case IDC_DECTIMER: + Preview_ChangeSlideShowTimer(pData, nCommandID == IDC_INCTIMER); + break; + default: break; } @@ -1490,7 +1556,7 @@ Preview_OnCommand(HWND hwnd, UINT nCommandID) if (g_pImage) { GdipImageRotateFlip(g_pImage, Rotate270FlipNone); - Preview_pSaveImage(pData, pData->m_szFile); + Preview_pSaveImage(pData, g_szFile); Preview_UpdateImage(pData); } break; @@ -1499,21 +1565,23 @@ Preview_OnCommand(HWND hwnd, UINT nCommandID) if (g_pImage) { GdipImageRotateFlip(g_pImage, Rotate90FlipNone); - Preview_pSaveImage(pData, pData->m_szFile); + Preview_pSaveImage(pData, g_szFile); Preview_UpdateImage(pData); } break; case IDC_DELETE: Preview_Delete(pData); - Preview_UpdateImage(pData); - Preview_UpdateUI(pData); break; case IDC_MODIFY: Preview_Edit(hwnd); break; + case IDC_HELP_TOC: + DisplayHelp(hwnd); + break; + default: break; } @@ -1541,6 +1609,7 @@ Preview_OnDestroy(HWND hwnd) PPREVIEW_DATA pData = Preview_GetData(hwnd); KillTimer(hwnd, SLIDESHOW_TIMER_ID); + KillTimer(hwnd, HIDECURSOR_TIMER_ID); pFreeFileList(g_pCurrentFile); g_pCurrentFile = NULL; @@ -1570,7 +1639,7 @@ Preview_OnDropFiles(HWND hwnd, HDROP hDrop) pFreeFileList(g_pCurrentFile); g_pCurrentFile = pBuildFileList(szFile); - Preview_pLoadImageFromNode(pData, g_pCurrentFile); + Preview_LoadImage(pData, g_pCurrentFile); DragFinish(hDrop); } @@ -1588,7 +1657,7 @@ PreviewWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } case WM_COMMAND: { - Preview_OnCommand(hwnd, LOWORD(wParam)); + Preview_OnCommand(hwnd, wParam, lParam); break; } case WM_NOTIFY: @@ -1629,6 +1698,13 @@ PreviewWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) Preview_OnDestroy(hwnd); break; } + case WM_CONTEXTMENU: + { + PPREVIEW_DATA pData = Preview_GetData(hwnd); + if ((int)lParam == -1) + return ZoomWndProc(pData->m_hwndZoom, uMsg, wParam, lParam); + break; + } case WM_TIMER: { if (wParam == SLIDESHOW_TIMER_ID) @@ -1638,6 +1714,13 @@ PreviewWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } break; } + case WM_UPDATECOMMANDSTATE: + { + PPREVIEW_DATA pData = Preview_GetData(g_hMainWnd); + if (g_ImageId == lParam) + SendMessage(pData->m_hwndToolBar, TB_ENABLEBUTTON, LOWORD(wParam), HIWORD(wParam)); + break; + } default: { return DefWindowProcW(hwnd, uMsg, wParam, lParam); @@ -1659,13 +1742,15 @@ ImageView_Main(HWND hwnd, LPCWSTR szFileName) HACCEL hAccel; HRESULT hrCoInit; INITCOMMONCONTROLSEX Icc = { .dwSize = sizeof(Icc), .dwICC = ICC_WIN95_CLASSES }; + g_szFile[0] = UNICODE_NULL; InitCommonControlsEx(&Icc); + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL); // Give UI higher priority than background threads /* Initialize COM */ - hrCoInit = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); + hrCoInit = OleInitialize(NULL); if (FAILED(hrCoInit)) - DPRINT1("Warning, CoInitializeEx failed with code=%08X\n", (int)hrCoInit); + DPRINT1("Warning, OleInitialize failed with code=%08X\n", (int)hrCoInit); if (!ImageView_LoadSettings()) ImageView_ResetSettings(); @@ -1683,7 +1768,7 @@ ImageView_Main(HWND hwnd, LPCWSTR szFileName) WndClass.style = CS_HREDRAW | CS_VREDRAW; WndClass.hIcon = LoadIconW(g_hInstance, MAKEINTRESOURCEW(IDI_APP_ICON)); WndClass.hCursor = LoadCursorW(NULL, (LPCWSTR)IDC_ARROW); - WndClass.hbrBackground = (HBRUSH)UlongToHandle(COLOR_3DFACE + 1); + WndClass.hbrBackground = GetStockBrush(NULL_BRUSH); /* less flicker */ if (!RegisterClassW(&WndClass)) return -1; WndClass.lpszClassName = WC_ZOOM; @@ -1714,7 +1799,8 @@ ImageView_Main(HWND hwnd, LPCWSTR szFileName) /* Message Loop */ while (GetMessageW(&msg, NULL, 0, 0) > 0) { - if (g_hwndFullscreen && TranslateAcceleratorW(g_hwndFullscreen, hAccel, &msg)) + const HWND hwndFull = g_hwndFullscreen; + if (IsWindowVisible(hwndFull) && TranslateAcceleratorW(hwndFull, hAccel, &msg)) continue; if (TranslateAcceleratorW(hMainWnd, hAccel, &msg)) continue; @@ -1732,7 +1818,7 @@ ImageView_Main(HWND hwnd, LPCWSTR szFileName) /* Release COM resources */ if (SUCCEEDED(hrCoInit)) - CoUninitialize(); + OleUninitialize(); return 0; } diff --git a/dll/win32/shimgvw/shimgvw.h b/dll/win32/shimgvw/shimgvw.h index 776da7f849cec..4f3c741a3edb7 100644 --- a/dll/win32/shimgvw/shimgvw.h +++ b/dll/win32/shimgvw/shimgvw.h @@ -12,6 +12,7 @@ #define _INC_WINDOWS #define COM_NO_WINDOWS_H #define INITGUID +#define COBJMACROS #include #include @@ -23,11 +24,14 @@ #include #include #include +#include #include #include "resource.h" +#define WM_UPDATECOMMANDSTATE (WM_APP + 0) + extern HINSTANCE g_hInstance; extern GpImage *g_pImage; @@ -69,6 +73,12 @@ void Anime_Start(PANIME pAnime, DWORD dwDelay); void Anime_Pause(PANIME pAnime); BOOL Anime_OnTimer(PANIME pAnime, WPARAM wParam); +void DoShellContextMenuOnFile(HWND hwnd, PCWSTR File, LPARAM lParam); +void EnableCommandIfVerbExists(UINT ImageId, HWND hwnd, UINT CmdId, PCWSTR Verb, PCWSTR File); +void ShellExecuteVerb(HWND hwnd, PCWSTR Verb, PCWSTR File, BOOL Quit); +UINT ErrorBox(HWND hwnd, UINT Error); +void DisplayHelp(HWND hwnd); + static inline LPVOID QuickAlloc(SIZE_T cbSize, BOOL bZero) { return HeapAlloc(GetProcessHeap(), (bZero ? HEAP_ZERO_MEMORY : 0), cbSize); @@ -78,3 +88,46 @@ static inline VOID QuickFree(LPVOID ptr) { HeapFree(GetProcessHeap(), 0, ptr); } + +static inline WORD Swap16(WORD v) +{ + return MAKEWORD(HIBYTE(v), LOBYTE(v)); +} + +static inline UINT Swap32(UINT v) +{ + return MAKELONG(Swap16(HIWORD(v)), Swap16(LOWORD(v))); +} + +#ifdef _WIN32 +#define BigToHost32 Swap32 +#endif + +static inline ULARGE_INTEGER MakeULargeInteger(UINT64 value) +{ + ULARGE_INTEGER ret; + ret.QuadPart = value; + return ret; +} + +static inline HRESULT SHIMGVW_HResultFromWin32(DWORD hr) +{ + // HRESULT_FROM_WIN32 will evaluate its parameter twice, this function will not. + return HRESULT_FROM_WIN32(hr); +} + +static inline HRESULT HResultFromGdiplus(Status status) +{ + switch ((UINT)status) + { + case Ok: return S_OK; + case InvalidParameter: return E_INVALIDARG; + case OutOfMemory: return E_OUTOFMEMORY; + case NotImplemented: return HRESULT_FROM_WIN32(ERROR_CALL_NOT_IMPLEMENTED); + case Win32Error: return SHIMGVW_HResultFromWin32(GetLastError()); + case FileNotFound: return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); + case AccessDenied: return HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED); + case UnknownImageFormat: return HRESULT_FROM_WIN32(ERROR_BAD_FORMAT); + } + return E_FAIL; +} diff --git a/dll/win32/shimgvw/shimgvw.rc b/dll/win32/shimgvw/shimgvw.rc index bb46198ded1f6..3efd98fbdb4d0 100644 --- a/dll/win32/shimgvw/shimgvw.rc +++ b/dll/win32/shimgvw/shimgvw.rc @@ -43,13 +43,23 @@ BEGIN "B", IDC_BEST_FIT, VIRTKEY, CONTROL "A", IDC_REAL_SIZE, VIRTKEY, CONTROL VK_F11, IDC_SLIDE_SHOW, VIRTKEY + VK_RETURN, IDC_TOGGLEFULLSCREEN, VIRTKEY, ALT + VK_ADD, IDC_INCTIMER, VIRTKEY, SHIFT + VK_OEM_PLUS, IDC_INCTIMER, VIRTKEY, SHIFT + VK_OEM_MINUS,IDC_DECTIMER, VIRTKEY, SHIFT + VK_SUBTRACT, IDC_DECTIMER, VIRTKEY, SHIFT VK_ADD, IDC_ZOOM_IN, VIRTKEY + VK_ADD, IDC_ZOOM_IN, VIRTKEY, CONTROL + VK_OEM_PLUS, IDC_ZOOM_IN, VIRTKEY + VK_OEM_PLUS, IDC_ZOOM_IN, VIRTKEY, CONTROL VK_SUBTRACT, IDC_ZOOM_OUT, VIRTKEY - VK_OEM_PLUS, IDC_ZOOM_IN, VIRTKEY, SHIFT + VK_SUBTRACT, IDC_ZOOM_OUT, VIRTKEY, CONTROL VK_OEM_MINUS,IDC_ZOOM_OUT, VIRTKEY + VK_OEM_MINUS,IDC_ZOOM_OUT, VIRTKEY, CONTROL "K", IDC_ROT_CLOCKW, VIRTKEY, CONTROL "L", IDC_ROT_COUNCW, VIRTKEY, CONTROL VK_DELETE, IDC_DELETE, VIRTKEY + VK_DELETE, IDC_DELETE, VIRTKEY, SHIFT "P", IDC_PRINT, VIRTKEY, CONTROL "S", IDC_SAVEAS, VIRTKEY, CONTROL "E", IDC_MODIFY, VIRTKEY, CONTROL diff --git a/dll/win32/shimgvw/util.c b/dll/win32/shimgvw/util.c new file mode 100644 index 0000000000000..491e6660ba3fd --- /dev/null +++ b/dll/win32/shimgvw/util.c @@ -0,0 +1,256 @@ +/* + * PROJECT: ReactOS Picture and Fax Viewer + * LICENSE: GPL-2.0 (https://spdx.org/licenses/GPL-2.0) + * PURPOSE: Utility routines + * COPYRIGHT: Copyright 2025 Whindmar Saksit + */ + +#include "shimgvw.h" +#include +#include +#include +#include +#include + +IContextMenu *g_pContextMenu = NULL; + +static int +GetMenuItemIdByPos(HMENU hMenu, UINT Pos) +{ + MENUITEMINFOW mii; + mii.cbSize = FIELD_OFFSET(MENUITEMINFOW, hbmpItem); /* USER32 version agnostic */ + mii.fMask = MIIM_ID; + mii.cch = 0; + return GetMenuItemInfoW(hMenu, Pos, TRUE, &mii) ? mii.wID : -1; +} + +static BOOL +IsMenuSeparator(HMENU hMenu, UINT Pos) +{ + MENUITEMINFOW mii; + mii.cbSize = FIELD_OFFSET(MENUITEMINFOW, hbmpItem); /* USER32 version agnostic */ + mii.fMask = MIIM_FTYPE; + mii.cch = 0; + return GetMenuItemInfoW(hMenu, Pos, TRUE, &mii) && (mii.fType & MFT_SEPARATOR); +} + +static BOOL +IsSelfShellVerb(PCWSTR Assoc, PCWSTR Verb) +{ + WCHAR buf[MAX_PATH * 3]; + DWORD cch = _countof(buf); + HRESULT hr = AssocQueryStringW(ASSOCF_NOTRUNCATE, ASSOCSTR_COMMAND, Assoc, Verb, buf, &cch); + return hr == S_OK && *Assoc == L'.' && StrStrW(buf, L",ImageView_Fullscreen"); +} + +static void +ModifyShellContextMenu(IContextMenu *pCM, HMENU hMenu, UINT CmdIdFirst, PCWSTR Assoc) +{ + HRESULT hr; + for (UINT i = 0, c = GetMenuItemCount(hMenu); i < c; ++i) + { + WCHAR buf[200]; + UINT id = GetMenuItemIdByPos(hMenu, i); + if (id == (UINT)-1) + continue; + + *buf = UNICODE_NULL; + /* Note: We just ask for the wide string because all the items we care about come from shell32 and it handles both */ + hr = IContextMenu_GetCommandString(pCM, id - CmdIdFirst, GCS_VERBW, NULL, (char*)buf, _countof(buf)); + if (SUCCEEDED(hr)) + { + UINT remove = FALSE; + if (IsSelfShellVerb(Assoc, buf)) + ++remove; + else if (!lstrcmpiW(L"cut", buf) || !lstrcmpiW(L"paste", buf) || !lstrcmpiW(L"pastelink", buf) || + !lstrcmpiW(L"delete", buf) || !lstrcmpiW(L"link", buf)) + ++remove; + + if (remove && DeleteMenu(hMenu, i, MF_BYPOSITION)) + { + if (i-- > 0) + { + if (IsMenuSeparator(hMenu, i) && IsMenuSeparator(hMenu, i + 1)) + DeleteMenu(hMenu, i, MF_BYPOSITION); + } + } + } + } + + while (IsMenuSeparator(hMenu, 0) && DeleteMenu(hMenu, 0, MF_BYPOSITION)) {} +} + +static LRESULT CALLBACK +ShellContextMenuWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + LRESULT lRes = 0; + if (FAILED(SHForwardContextMenuMsg((IUnknown*)g_pContextMenu, uMsg, wParam, lParam, &lRes, TRUE))) + lRes = DefWindowProc(hwnd, uMsg, wParam, lParam); + return lRes; +} + +static void +DoShellContextMenu(HWND hwnd, IContextMenu *pCM, PCWSTR File, LPARAM lParam) +{ + enum { first = 1, last = 0x7fff }; + HRESULT hr; + HMENU hMenu = CreatePopupMenu(); + UINT cmf = GetKeyState(VK_SHIFT) < 0 ? CMF_EXTENDEDVERBS : 0; + + POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; + if ((int)lParam == -1) + { + RECT rect; + GetWindowRect(hwnd, &rect); + pt.x = (rect.left + rect.right) / 2; + pt.y = rect.top; + } + + g_pContextMenu = pCM; + hwnd = SHCreateWorkerWindowW(ShellContextMenuWindowProc, hwnd, 0, WS_VISIBLE | WS_CHILD, NULL, 0); + if (!hwnd) + goto die; + hr = IContextMenu_QueryContextMenu(pCM, hMenu, 0, first, last, cmf | CMF_NODEFAULT); + if (SUCCEEDED(hr)) + { + UINT id; + ModifyShellContextMenu(pCM, hMenu, first, PathFindExtensionW(File)); + id = TrackPopupMenuEx(hMenu, TPM_RETURNCMD, pt.x, pt.y, hwnd, NULL); + if (id) + { + UINT flags = (GetKeyState(VK_SHIFT) < 0 ? CMIC_MASK_SHIFT_DOWN : 0) | + (GetKeyState(VK_CONTROL) < 0 ? CMIC_MASK_CONTROL_DOWN : 0); + CMINVOKECOMMANDINFO ici = { sizeof(ici), flags, hwnd, MAKEINTRESOURCEA(id - first) }; + ici.nShow = SW_SHOW; + hr = IContextMenu_InvokeCommand(pCM, &ici); + } + } + DestroyWindow(hwnd); +die: + DestroyMenu(hMenu); + g_pContextMenu = NULL; +} + +HRESULT +GetUIObjectOfPath(HWND hwnd, PCWSTR File, REFIID riid, void **ppv) +{ + HRESULT hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); + IShellFolder *pSF; + PCUITEMID_CHILD pidlItem; + PIDLIST_ABSOLUTE pidl = ILCreateFromPath(File); + *ppv = NULL; + if (pidl && SUCCEEDED(SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &pSF), &pidlItem))) + { + hr = IShellFolder_GetUIObjectOf(pSF, hwnd, 1, &pidlItem, riid, NULL, ppv); + IShellFolder_Release(pSF); + } + SHFree(pidl); + return hr; +} + +void +DoShellContextMenuOnFile(HWND hwnd, PCWSTR File, LPARAM lParam) +{ + IContextMenu *pCM; + HRESULT hr = GetUIObjectOfPath(hwnd, File, IID_PPV_ARG(IContextMenu, &pCM)); + if (SUCCEEDED(hr)) + { + DoShellContextMenu(hwnd, pCM, File, lParam); + IContextMenu_Release(pCM); + } +} + +typedef struct _ENABLECOMMANDDATA +{ + HWND hwnd; + PCWSTR Verb; + UINT CmdId; + UINT ImageId; + WCHAR File[ANYSIZE_ARRAY]; +} ENABLECOMMANDDATA; + +static DWORD CALLBACK +EnableCommandIfVerbExistsProc(LPVOID ThreadParam) +{ + enum { first = 1, last = 0x7fff }; + ENABLECOMMANDDATA *pData = ThreadParam; + IContextMenu *pCM; + HRESULT hr = GetUIObjectOfPath(pData->hwnd, pData->File, IID_PPV_ARG(IContextMenu, &pCM)); + if (SUCCEEDED(hr)) + { + HMENU hMenu = CreatePopupMenu(); + hr = IContextMenu_QueryContextMenu(pCM, hMenu, 0, first, last, CMF_NORMAL); + if (SUCCEEDED(hr)) + { + for (UINT i = 0, c = GetMenuItemCount(hMenu); i < c; ++i) + { + WCHAR buf[200]; + UINT id = GetMenuItemIdByPos(hMenu, i); + if (id == (UINT)-1) + continue; + + *buf = UNICODE_NULL; + hr = IContextMenu_GetCommandString(pCM, id - first, GCS_VERBW, NULL, (char*)buf, _countof(buf)); + if (SUCCEEDED(hr) && !lstrcmpiW(buf, pData->Verb)) + { + PostMessageW(pData->hwnd, WM_UPDATECOMMANDSTATE, MAKELONG(pData->CmdId, TRUE), pData->ImageId); + break; + } + } + } + DestroyMenu(hMenu); + IContextMenu_Release(pCM); + } + SHFree(pData); + return 0; +} + +void +EnableCommandIfVerbExists(UINT ImageId, HWND hwnd, UINT CmdId, PCWSTR Verb, PCWSTR File) +{ + const SIZE_T cch = lstrlenW(File) + 1; + ENABLECOMMANDDATA *pData = SHAlloc(FIELD_OFFSET(ENABLECOMMANDDATA, File[cch])); + if (pData) + { + pData->hwnd = hwnd; + pData->Verb = Verb; // Note: This assumes the string is valid for the lifetime of the thread. + pData->CmdId = CmdId; + pData->ImageId = ImageId; + CopyMemory(pData->File, File, cch * sizeof(*File)); + SHCreateThread(EnableCommandIfVerbExistsProc, pData, CTF_COINIT | CTF_INSIST, NULL); + } +} + +void +ShellExecuteVerb(HWND hwnd, PCWSTR Verb, PCWSTR File, BOOL Quit) +{ + SHELLEXECUTEINFOW sei = { sizeof(sei), SEE_MASK_INVOKEIDLIST | SEE_MASK_ASYNCOK }; + if (!*File) + return; + + sei.hwnd = hwnd; + sei.lpVerb = Verb; + sei.lpFile = File; + sei.nShow = SW_SHOW; + if (!ShellExecuteExW(&sei)) + { + DPRINT1("ShellExecuteExW(%ls, %ls) failed with code %ld\n", Verb, File, GetLastError()); + } + else if (Quit) + { + // Destroy the window to quit the application + DestroyWindow(hwnd); + } +} + +UINT +ErrorBox(HWND hwnd, UINT Error) +{ + return SHELL_ErrorBox(hwnd, Error); +} + +void +DisplayHelp(HWND hwnd) +{ + ErrorBox(hwnd, ERROR_NOT_SUPPORTED); +} diff --git a/dll/win32/shlwapi/lang/de-DE.rc b/dll/win32/shlwapi/lang/de-DE.rc index 4dc8a1513ddb2..e84a4c75452f5 100644 --- a/dll/win32/shlwapi/lang/de-DE.rc +++ b/dll/win32/shlwapi/lang/de-DE.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/shlwapi/lang/fr-FR.rc b/dll/win32/shlwapi/lang/fr-FR.rc index b7b4d317e5394..09b036783732b 100644 --- a/dll/win32/shlwapi/lang/fr-FR.rc +++ b/dll/win32/shlwapi/lang/fr-FR.rc @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/shlwapi/lang/hu-HU.rc b/dll/win32/shlwapi/lang/hu-HU.rc index 8fa7afa1db353..ccc262844d071 100644 --- a/dll/win32/shlwapi/lang/hu-HU.rc +++ b/dll/win32/shlwapi/lang/hu-HU.rc @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/shlwapi/lang/ja-JP.rc b/dll/win32/shlwapi/lang/ja-JP.rc index 50388113a38d3..3a770caecba6c 100644 --- a/dll/win32/shlwapi/lang/ja-JP.rc +++ b/dll/win32/shlwapi/lang/ja-JP.rc @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/shlwapi/lang/lt-LT.rc b/dll/win32/shlwapi/lang/lt-LT.rc index 717c17e94343e..16502562dcc30 100644 --- a/dll/win32/shlwapi/lang/lt-LT.rc +++ b/dll/win32/shlwapi/lang/lt-LT.rc @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_LITHUANIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/shlwapi/lang/pt-PT.rc b/dll/win32/shlwapi/lang/pt-PT.rc index 242b0994dabcf..3f2028b52dec2 100644 --- a/dll/win32/shlwapi/lang/pt-PT.rc +++ b/dll/win32/shlwapi/lang/pt-PT.rc @@ -4,6 +4,7 @@ * Copyright 2004 Marcelo Duarte * Copyright 2006 Américo José Melo * Copyright 2010 Gustavo Henrique Milaré + * Copyright 2019-2025 Jose Carlos Jesus * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,8 +21,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_PORTUGUESE, SUBLANG_NEUTRAL STRINGTABLE @@ -48,8 +47,8 @@ FONT 8, "MS Shell Dlg" LTEXT "", IDS_ERR_USER_MSG2, 15, 5, 28, 20 LTEXT "", IDS_ERR_USER_MSG, 15, 5, 210, 8 CHECKBOX "Não &mostrar esta mensagem novamente", IDC_ERR_DONT_SHOW, 5, 20, 210, 10, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - PUSHBUTTON "&OK", IDOK, 105, 40, 50, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Cancelar", IDCANCEL, 160, 40, 50, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "OK", IDOK, 105, 40, 50, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "Cancelar", IDCANCEL, 160, 40, 50, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "&Sim", IDYES, 105, 40, 50, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "&Não", IDNO, 160, 40, 50, 14, WS_GROUP | WS_TABSTOP } diff --git a/dll/win32/shlwapi/lang/ro-RO.rc b/dll/win32/shlwapi/lang/ro-RO.rc index d31911ba7ec06..c9b7739414cd0 100644 --- a/dll/win32/shlwapi/lang/ro-RO.rc +++ b/dll/win32/shlwapi/lang/ro-RO.rc @@ -21,8 +21,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/shlwapi/lang/ru-RU.rc b/dll/win32/shlwapi/lang/ru-RU.rc index 8e963a0167270..1b1bdd0c69944 100644 --- a/dll/win32/shlwapi/lang/ru-RU.rc +++ b/dll/win32/shlwapi/lang/ru-RU.rc @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/shlwapi/lang/sl-SI.rc b/dll/win32/shlwapi/lang/sl-SI.rc index abcf7e6efc5f5..0e18cd09a4464 100644 --- a/dll/win32/shlwapi/lang/sl-SI.rc +++ b/dll/win32/shlwapi/lang/sl-SI.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/shlwapi/lang/uk-UA.rc b/dll/win32/shlwapi/lang/uk-UA.rc index f4e190975bd9d..8cb3404c4411d 100644 --- a/dll/win32/shlwapi/lang/uk-UA.rc +++ b/dll/win32/shlwapi/lang/uk-UA.rc @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/shlwapi/lang/zh-CN.rc b/dll/win32/shlwapi/lang/zh-CN.rc index 2d6f8d4e92cef..cca4fc59454ce 100644 --- a/dll/win32/shlwapi/lang/zh-CN.rc +++ b/dll/win32/shlwapi/lang/zh-CN.rc @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* Chinese text is encoded in UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED STRINGTABLE diff --git a/dll/win32/shlwapi/lang/zh-TW.rc b/dll/win32/shlwapi/lang/zh-TW.rc index f63a05c64caec..1a774b18e8257 100644 --- a/dll/win32/shlwapi/lang/zh-TW.rc +++ b/dll/win32/shlwapi/lang/zh-TW.rc @@ -21,9 +21,6 @@ * Copyright 2021 Chan Chilung */ -/* Chinese text is encoded in UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL STRINGTABLE diff --git a/dll/win32/shlwapi/ordinal.c b/dll/win32/shlwapi/ordinal.c index f36cb6a6b668c..17223417254d5 100644 --- a/dll/win32/shlwapi/ordinal.c +++ b/dll/win32/shlwapi/ordinal.c @@ -633,7 +633,7 @@ INT WINAPI SHStringFromGUIDA(REFGUID guid, LPSTR lpszDest, INT cchMax) TRACE("(%s,%p,%d)\n", debugstr_guid(guid), lpszDest, cchMax); sprintf(xguid, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", - guid->Data1, guid->Data2, guid->Data3, + (UINT)guid->Data1, guid->Data2, guid->Data3, guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3], guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]); @@ -4106,6 +4106,23 @@ HRESULT WINAPI CLSIDFromStringWrap(LPCWSTR idstr, CLSID *id) */ BOOL WINAPI IsOS(DWORD feature) { +#ifdef __REACTOS__ + OSVERSIONINFOEXA osvi; + DWORD platform, majorv, minorv; + + osvi.dwOSVersionInfoSize = sizeof(osvi); + if (!GetVersionExA((OSVERSIONINFOA*)&osvi)) + { + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA); + if (!GetVersionExA((OSVERSIONINFOA*)&osvi)) + { + ERR("GetVersionEx failed\n"); + return FALSE; + } + osvi.wProductType = VER_NT_WORKSTATION; + osvi.wSuiteMask = 0; + } +#else OSVERSIONINFOA osvi; DWORD platform, majorv, minorv; @@ -4114,7 +4131,7 @@ BOOL WINAPI IsOS(DWORD feature) ERR("GetVersionEx failed\n"); return FALSE; } - +#endif majorv = osvi.dwMajorVersion; minorv = osvi.dwMinorVersion; platform = osvi.dwPlatformId; @@ -4189,7 +4206,11 @@ BOOL WINAPI IsOS(DWORD feature) FIXME("(OS_DOMAINMEMBER) What should we return here?\n"); return TRUE; case OS_ANYSERVER: +#ifdef __REACTOS__ + ISOS_RETURN(osvi.wProductType > VER_NT_WORKSTATION) +#else ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT) +#endif case OS_WOW6432: { BOOL is_wow64; @@ -5414,7 +5435,7 @@ HRESULT VariantChangeTypeForRead(_Inout_ VARIANTARG *pvarg, _In_ VARTYPE vt) if (vt == VT_I1 || vt == VT_I2 || vt == VT_I4) { - if (!StrToIntExW(V_BSTR(&vargTemp), STIF_SUPPORT_HEX, &V_I4(&variTemp))) + if (!StrToIntExW(V_BSTR(&vargTemp), STIF_SUPPORT_HEX, (int*)&V_I4(&variTemp))) goto DoDefault; V_VT(&variTemp) = VT_INT; @@ -5429,7 +5450,7 @@ HRESULT VariantChangeTypeForRead(_Inout_ VARIANTARG *pvarg, _In_ VARTYPE vt) if (vt == VT_UI1 || vt == VT_UI2 || vt == VT_UI4) { - if (!StrToIntExW(V_BSTR(&vargTemp), STIF_SUPPORT_HEX, (LPINT)&V_UI4(&variTemp))) + if (!StrToIntExW(V_BSTR(&vargTemp), STIF_SUPPORT_HEX, (int*)&V_UI4(&variTemp))) goto DoDefault; V_VT(&variTemp) = VT_UINT; @@ -5441,7 +5462,7 @@ HRESULT VariantChangeTypeForRead(_Inout_ VARIANTARG *pvarg, _In_ VARTYPE vt) if (vt == VT_INT || vt == VT_UINT) { - if (!StrToIntExW(V_BSTR(&vargTemp), STIF_SUPPORT_HEX, &V_INT(&variTemp))) + if (!StrToIntExW(V_BSTR(&vargTemp), STIF_SUPPORT_HEX, (int*)&V_INT(&variTemp))) goto DoDefault; V_VT(&variTemp) = VT_UINT; diff --git a/dll/win32/shlwapi/path.c b/dll/win32/shlwapi/path.c index c26263152df61..e2f05cff78a9a 100644 --- a/dll/win32/shlwapi/path.c +++ b/dll/win32/shlwapi/path.c @@ -891,25 +891,28 @@ LPWSTR WINAPI PathRemoveBackslashW( LPWSTR lpszPath ) * RETURNS * Nothing. */ -VOID WINAPI PathRemoveBlanksA(LPSTR lpszPath) +void WINAPI PathRemoveBlanksA(LPSTR pszPath) { - TRACE("(%s)\n", debugstr_a(lpszPath)); + LPSTR start, first; - if(lpszPath && *lpszPath) - { - LPSTR start = lpszPath; + TRACE("(%s)\n", debugstr_a(pszPath)); - while (*lpszPath == ' ') - lpszPath = CharNextA(lpszPath); + if (!pszPath || !*pszPath) + return; + + start = first = pszPath; + + while (*pszPath == ' ') + pszPath = CharNextA(pszPath); - while(*lpszPath) - *start++ = *lpszPath++; + while (*pszPath) + *start++ = *pszPath++; + + if (start != first) + while (start[-1] == ' ') + start--; - if (start != lpszPath) - while (start[-1] == ' ') - start--; *start = '\0'; - } } /************************************************************************* @@ -917,25 +920,28 @@ VOID WINAPI PathRemoveBlanksA(LPSTR lpszPath) * * See PathRemoveBlanksA. */ -VOID WINAPI PathRemoveBlanksW(LPWSTR lpszPath) +void WINAPI PathRemoveBlanksW(LPWSTR pszPath) { - TRACE("(%s)\n", debugstr_w(lpszPath)); + LPWSTR start, first; - if(lpszPath && *lpszPath) - { - LPWSTR start = lpszPath; + TRACE("(%s)\n", debugstr_w(pszPath)); - while (*lpszPath == ' ') - lpszPath++; + if (!pszPath || !*pszPath) + return; - while(*lpszPath) - *start++ = *lpszPath++; + start = first = pszPath; + + while (*pszPath == ' ') + pszPath++; + + while (*pszPath) + *start++ = *pszPath++; + + if (start != first) + while (start[-1] == ' ') + start--; - if (start != lpszPath) - while (start[-1] == ' ') - start--; *start = '\0'; - } } /************************************************************************* @@ -4061,31 +4067,23 @@ LPCWSTR WINAPI PathFindSuffixArrayW(LPCWSTR lpszSuffix, LPCWSTR *lppszArray, int * NOTES * A decorations form is "path[n].ext" where "n" is an optional decimal number. */ -VOID WINAPI PathUndecorateA(LPSTR lpszPath) +void WINAPI PathUndecorateA(LPSTR pszPath) { - TRACE("(%s)\n",debugstr_a(lpszPath)); + char *ext, *skip; - if (lpszPath) - { - LPSTR lpszExt = PathFindExtensionA(lpszPath); - if (lpszExt > lpszPath && lpszExt[-1] == ']') - { - LPSTR lpszSkip = lpszExt - 2; - if (*lpszSkip == '[') - lpszSkip++; /* [] (no number) */ - else - while (lpszSkip > lpszPath && isdigit(lpszSkip[-1])) - lpszSkip--; - if (lpszSkip > lpszPath && lpszSkip[-1] == '[' && lpszSkip[-2] != '\\') - { - /* remove the [n] */ - lpszSkip--; - while (*lpszExt) - *lpszSkip++ = *lpszExt++; - *lpszSkip = '\0'; - } - } - } + TRACE("(%s)\n", debugstr_a(pszPath)); + + if (!pszPath) return; + + ext = PathFindExtensionA(pszPath); + if (ext == pszPath || ext[-1] != ']') return; + + skip = ext - 2; + while (skip > pszPath && '0' <= *skip && *skip <= '9') + skip--; + + if (skip > pszPath && *skip == '[' && skip[-1] != '\\') + memmove(skip, ext, strlen(ext) + 1); } /************************************************************************* @@ -4093,31 +4091,23 @@ VOID WINAPI PathUndecorateA(LPSTR lpszPath) * * See PathUndecorateA. */ -VOID WINAPI PathUndecorateW(LPWSTR lpszPath) +void WINAPI PathUndecorateW(LPWSTR pszPath) { - TRACE("(%s)\n",debugstr_w(lpszPath)); + WCHAR *ext, *skip; - if (lpszPath) - { - LPWSTR lpszExt = PathFindExtensionW(lpszPath); - if (lpszExt > lpszPath && lpszExt[-1] == ']') - { - LPWSTR lpszSkip = lpszExt - 2; - if (*lpszSkip == '[') - lpszSkip++; /* [] (no number) */ - else - while (lpszSkip > lpszPath && isdigitW(lpszSkip[-1])) - lpszSkip--; - if (lpszSkip > lpszPath && lpszSkip[-1] == '[' && lpszSkip[-2] != '\\') - { - /* remove the [n] */ - lpszSkip--; - while (*lpszExt) - *lpszSkip++ = *lpszExt++; - *lpszSkip = '\0'; - } - } - } + TRACE("(%s)\n", debugstr_w(pszPath)); + + if (!pszPath) return; + + ext = PathFindExtensionW(pszPath); + if (ext == pszPath || ext[-1] != ']') return; + + skip = ext - 2; + while (skip > pszPath && '0' <= *skip && *skip <= '9') + skip--; + + if (skip > pszPath && *skip == '[' && skip[-1] != '\\') + memmove(skip, ext, (wcslen(ext) + 1) * sizeof(WCHAR)); } /************************************************************************* diff --git a/dll/win32/shlwapi/string.c b/dll/win32/shlwapi/string.c index dec137a9d677b..7c792d6656411 100644 --- a/dll/win32/shlwapi/string.c +++ b/dll/win32/shlwapi/string.c @@ -883,7 +883,7 @@ int WINAPI StrToIntW(LPCWSTR lpszStr) * the string is treated as a decimal string. A leading '-' is ignored for * hexadecimal numbers. */ -BOOL WINAPI StrToIntExA(LPCSTR lpszStr, DWORD dwFlags, LPINT lpiRet) +BOOL WINAPI StrToIntExA(LPCSTR lpszStr, DWORD dwFlags, int *lpiRet) { LONGLONG li; BOOL bRes; @@ -967,7 +967,7 @@ BOOL WINAPI StrToInt64ExA(LPCSTR lpszStr, DWORD dwFlags, LONGLONG *lpiRet) * * See StrToIntExA. */ -BOOL WINAPI StrToIntExW(LPCWSTR lpszStr, DWORD dwFlags, LPINT lpiRet) +BOOL WINAPI StrToIntExW(LPCWSTR lpszStr, DWORD dwFlags, int *lpiRet) { LONGLONG li; BOOL bRes; diff --git a/dll/win32/shlwapi/utils.cpp b/dll/win32/shlwapi/utils.cpp index 8cfb8ab2d612c..51a881363c71f 100644 --- a/dll/win32/shlwapi/utils.cpp +++ b/dll/win32/shlwapi/utils.cpp @@ -21,15 +21,8 @@ #include #include -/* - * HACK! - */ -#undef IShellFolder_GetDisplayNameOf -#undef IShellFolder_ParseDisplayName -#undef IShellFolder_CompareIDs - -#define SHLWAPI_ISHELLFOLDER_HELPERS /* HACK! */ #include +#include #include diff --git a/dll/win32/slbcsp/CMakeLists.txt b/dll/win32/slbcsp/CMakeLists.txt index b05ac017d900e..06674c1134b9f 100644 --- a/dll/win32/slbcsp/CMakeLists.txt +++ b/dll/win32/slbcsp/CMakeLists.txt @@ -1,6 +1,4 @@ -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) -add_definitions(-D__WINESRC__) spec2def(slbcsp.dll slbcsp.spec) list(APPEND SOURCE @@ -13,3 +11,4 @@ set_module_type(slbcsp win32dll) target_link_libraries(slbcsp wine) add_importlibs(slbcsp msvcrt kernel32 ntdll) add_cd_file(TARGET slbcsp DESTINATION reactos/system32 FOR all) +set_wine_module(slbcsp) diff --git a/dll/win32/slbcsp/main.c b/dll/win32/slbcsp/main.c index 4fd23be6442e4..a1818c0cf21a2 100644 --- a/dll/win32/slbcsp/main.c +++ b/dll/win32/slbcsp/main.c @@ -30,8 +30,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) switch (fdwReason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hinstDLL); break; diff --git a/dll/win32/snmpapi/CMakeLists.txt b/dll/win32/snmpapi/CMakeLists.txt index 32b10f7f93179..2ec76d02dc536 100644 --- a/dll/win32/snmpapi/CMakeLists.txt +++ b/dll/win32/snmpapi/CMakeLists.txt @@ -2,8 +2,6 @@ remove_definitions(-D_WIN32_WINNT=0x502) add_definitions(-D_WIN32_WINNT=0x600) -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(snmpapi.dll snmpapi.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -16,3 +14,4 @@ set_module_type(snmpapi win32dll) target_link_libraries(snmpapi wine) add_importlibs(snmpapi msvcrt kernel32_vista kernel32 ntdll) add_cd_file(TARGET snmpapi DESTINATION reactos/system32 FOR all) +set_wine_module(snmpapi) diff --git a/dll/win32/snmpapi/main.c b/dll/win32/snmpapi/main.c index 3c90ca20ec9f1..9e5eca0d700c8 100644 --- a/dll/win32/snmpapi/main.c +++ b/dll/win32/snmpapi/main.c @@ -123,8 +123,10 @@ BOOL WINAPI DllMain( TRACE("(%p,%d,%p)\n", hInstDLL, fdwReason, lpvReserved); switch(fdwReason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hInstDLL); startTime = GetTickCount64(); diff --git a/dll/win32/softpub/CMakeLists.txt b/dll/win32/softpub/CMakeLists.txt index 3d8676427348e..cfe929ae636aa 100644 --- a/dll/win32/softpub/CMakeLists.txt +++ b/dll/win32/softpub/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(softpub.dll softpub.spec) add_library(softpub MODULE @@ -11,3 +9,4 @@ set_module_type(softpub win32dll ENTRYPOINT 0 ) target_link_libraries(softpub wine) add_importlibs(softpub wintrust) add_cd_file(TARGET softpub DESTINATION reactos/system32 FOR all) +set_wine_module(softpub) diff --git a/dll/win32/stdole2.tlb/CMakeLists.txt b/dll/win32/stdole2.tlb/CMakeLists.txt index 162e10c071394..6edf5211b29c3 100644 --- a/dll/win32/stdole2.tlb/CMakeLists.txt +++ b/dll/win32/stdole2.tlb/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) add_typelib(std_ole_v2.idl) spec2def(stdole2.tlb stdole2.tlb.spec) @@ -13,3 +11,4 @@ add_library(stdole2.tlb MODULE ${SOURCE}) set_module_type(stdole2.tlb module) set_target_properties(stdole2.tlb PROPERTIES SUFFIX "") add_cd_file(TARGET stdole2.tlb DESTINATION reactos/system32 FOR all) +set_wine_module(stdole2.tlb) diff --git a/dll/win32/stdole32.tlb/CMakeLists.txt b/dll/win32/stdole32.tlb/CMakeLists.txt index 59b78f8c03a07..8b249ee9b6a3e 100644 --- a/dll/win32/stdole32.tlb/CMakeLists.txt +++ b/dll/win32/stdole32.tlb/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) add_typelib(std_ole_v1.idl) spec2def(stdole32.tlb stdole32.tlb.spec) @@ -13,3 +11,4 @@ add_library(stdole32.tlb MODULE ${SOURCE}) set_module_type(stdole32.tlb module) set_target_properties(stdole32.tlb PROPERTIES SUFFIX "") add_cd_file(TARGET stdole32.tlb DESTINATION reactos/system32 FOR all) +set_wine_module(stdole32.tlb) diff --git a/dll/win32/sti/CMakeLists.txt b/dll/win32/sti/CMakeLists.txt index 2b5f49b96f71e..ceab06cd3da47 100644 --- a/dll/win32/sti/CMakeLists.txt +++ b/dll/win32/sti/CMakeLists.txt @@ -1,11 +1,9 @@ add_definitions( - -D__WINESRC__ -DENTRY_PREFIX=STI_ -DPROXY_DELEGATION -DWINE_REGISTER_DLL) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(sti.dll sti.spec) add_rpcproxy_files(sti_wia.idl) @@ -29,3 +27,4 @@ target_link_libraries(sti wine uuid ${PSEH_LIB}) add_importlibs(sti ole32 oleaut32 rpcrt4 advapi32 msvcrt kernel32 ntdll) add_pch(sti precomp.h "${PCH_SKIP_SOURCE}") add_cd_file(TARGET sti DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(sti) # CORE-5743: No ARRAY_SIZE and CONST_VTABLE diff --git a/dll/win32/sti/sti_main.c b/dll/win32/sti/sti_main.c index c532ffbd6acb5..8d86f65d6544a 100644 --- a/dll/win32/sti/sti_main.c +++ b/dll/win32/sti/sti_main.c @@ -137,8 +137,10 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved) { TRACE("(0x%p, %d, %p)\n",hInstDLL,fdwReason,lpvReserved); +#ifndef __REACTOS__ if (fdwReason == DLL_WINE_PREATTACH) return FALSE; +#endif return STI_DllMain(hInstDLL, fdwReason, lpvReserved); } diff --git a/dll/win32/sxs/CMakeLists.txt b/dll/win32/sxs/CMakeLists.txt index 6ed421e438499..ab8e6439ec801 100644 --- a/dll/win32/sxs/CMakeLists.txt +++ b/dll/win32/sxs/CMakeLists.txt @@ -1,6 +1,4 @@ -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) -add_definitions(-D__WINESRC__) spec2def(sxs.dll sxs.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -22,3 +20,4 @@ target_link_libraries(sxs wine) add_importlibs(sxs oleaut32 ole32 msvcrt kernel32 ntdll) add_pch(sxs precomp.h "${PCH_SKIP_SOURCE}") add_cd_file(TARGET sxs DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(sxs) # CORE-5743: No ARRAY_SIZE and CONST_VTABLE diff --git a/dll/win32/sxs/sxs.c b/dll/win32/sxs/sxs.c index 5b2db1d997cd4..884987509e147 100644 --- a/dll/win32/sxs/sxs.c +++ b/dll/win32/sxs/sxs.c @@ -36,8 +36,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { switch(fdwReason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls( hinstDLL ); break; diff --git a/dll/win32/syssetup/globals.h b/dll/win32/syssetup/globals.h index 8c020acefb3fd..8112102a0b7d1 100644 --- a/dll/win32/syssetup/globals.h +++ b/dll/win32/syssetup/globals.h @@ -25,11 +25,61 @@ typedef struct _ADMIN_INFO LPWSTR Password; } ADMIN_INFO, *PADMIN_INFO; + +typedef struct _ITEMSDATA +{ + HWND hwndDlg; +} ITEMSDATA, *PITEMSDATA; + +typedef struct _REGISTRATIONNOTIFY +{ + ULONG Progress; + UINT ActivityID; + LPCWSTR CurrentItem; + LPCWSTR ErrorMessage; + UINT MessageID; + DWORD LastError; +} REGISTRATIONNOTIFY, *PREGISTRATIONNOTIFY; + + +#define PM_REGISTRATION_NOTIFY (WM_APP + 1) +/* Private Message used to communicate progress from the background + registration thread to the main thread. + wParam = 0 Registration in progress + = 1 Registration completed + lParam = Pointer to a REGISTRATIONNOTIFY structure */ + +#define PM_ITEM_START (WM_APP + 2) +/* Start of a new Item + wParam = item number + lParam = number of steps */ + +#define PM_ITEM_END (WM_APP + 3) +/* End of a new Item + wParam = unused + lParam = Error Code */ + +#define PM_STEP_START (WM_APP + 4) +#define PM_STEP_END (WM_APP + 5) +#define PM_ITEMS_DONE (WM_APP + 6) + + extern HINSTANCE hDllInstance; extern HINF hSysSetupInf; extern ADMIN_INFO AdminInfo; -BOOL RegisterTypeLibraries (HINF hinf, LPCWSTR szSection); +/* install */ + +BOOL +RegisterTypeLibraries( + _In_ PITEMSDATA pItemsData, + _In_ PREGISTRATIONNOTIFY pNotify, + _In_ HINF hinf, + _In_ LPCWSTR szSection); + +VOID +InstallStartMenuItems( + _In_ PITEMSDATA pItemsData); /* netinstall.c */ diff --git a/dll/win32/syssetup/install.c b/dll/win32/syssetup/install.c index e7ba620479aad..8895e0628c079 100644 --- a/dll/win32/syssetup/install.c +++ b/dll/win32/syssetup/install.c @@ -180,7 +180,13 @@ CreateShortcut( } -static BOOL CreateShortcutsFromSection(HINF hinf, LPWSTR pszSection, LPCWSTR pszFolder) +static BOOL +CreateShortcutsFromSection( + _In_ PITEMSDATA pItemsData, + _In_ PREGISTRATIONNOTIFY pNotify, + _In_ HINF hinf, + _In_ LPWSTR pszSection, + _In_ LPCWSTR pszFolder) { INFCONTEXT Context; DWORD dwFieldCount; @@ -196,6 +202,10 @@ static BOOL CreateShortcutsFromSection(HINF hinf, LPWSTR pszSection, LPCWSTR psz do { + pNotify->Progress++; + + SendMessage(pItemsData->hwndDlg, PM_STEP_START, 0, (LPARAM)pNotify); + dwFieldCount = SetupGetFieldCount(&Context); if (dwFieldCount < 3) continue; @@ -222,12 +232,19 @@ static BOOL CreateShortcutsFromSection(HINF hinf, LPWSTR pszSection, LPCWSTR psz CreateShortcut(pszFolder, szName, szCommand, szDescription, iIconNr, szDirectory, szArgs); + SendMessage(pItemsData->hwndDlg, PM_STEP_END, 0, (LPARAM)pNotify); + } while (SetupFindNextLine(&Context, &Context)); return TRUE; } -static BOOL CreateShortcuts(HINF hinf, LPCWSTR szSection) +static BOOL +CreateShortcuts( + _In_ PITEMSDATA pItemsData, + _In_ PREGISTRATIONNOTIFY pNotify, + _In_ HINF hinf, + _In_ LPCWSTR szSection) { INFCONTEXT Context; WCHAR szPath[MAX_PATH]; @@ -257,7 +274,7 @@ static BOOL CreateShortcuts(HINF hinf, LPCWSTR szSection) if (FAILED(SHGetFolderPathAndSubDirW(NULL, csidl|CSIDL_FLAG_CREATE, (HANDLE)-1, SHGFP_TYPE_DEFAULT, szFolder, szPath))) continue; - CreateShortcutsFromSection(hinf, szFolderSection, szPath); + CreateShortcutsFromSection(pItemsData, pNotify, hinf, szFolderSection, szPath); } while (SetupFindNextLine(&Context, &Context)); @@ -266,6 +283,90 @@ static BOOL CreateShortcuts(HINF hinf, LPCWSTR szSection) return TRUE; } +static LONG +CountShortcuts( + _In_ HINF hinf, + _In_ LPCWSTR szSection) +{ + INFCONTEXT Context; + WCHAR szFolderSection[MAX_PATH]; + LONG Steps = 0; + + if (!SetupFindFirstLine(hinf, szSection, NULL, &Context)) + return FALSE; + + do + { + if (SetupGetFieldCount(&Context) < 2) + continue; + + if (!SetupGetStringFieldW(&Context, 0, szFolderSection, ARRAYSIZE(szFolderSection), NULL)) + continue; + + Steps += SetupGetLineCountW(hinf, szFolderSection); + } while (SetupFindNextLine(&Context, &Context)); + + return Steps; +} + +VOID +InstallStartMenuItems( + _In_ PITEMSDATA pItemsData) +{ + HINF hShortcutsInf1 = INVALID_HANDLE_VALUE; + HINF hShortcutsInf2 = INVALID_HANDLE_VALUE; + LONG Steps = 0; + DWORD LastError = 0; + REGISTRATIONNOTIFY Notify; + + ZeroMemory(&Notify, sizeof(Notify)); + + hShortcutsInf1 = SetupOpenInfFileW(L"shortcuts.inf", + NULL, + INF_STYLE_WIN4, + NULL); + if (hShortcutsInf1 == INVALID_HANDLE_VALUE) + { + DPRINT1("Failed to open shortcuts.inf"); + return; + } + + hShortcutsInf2 = SetupOpenInfFileW(L"rosapps_shortcuts.inf", + NULL, + INF_STYLE_WIN4, + NULL); + + Steps = CountShortcuts(hShortcutsInf1, L"ShortcutFolders"); + if (hShortcutsInf2 != INVALID_HANDLE_VALUE) + Steps += CountShortcuts(hShortcutsInf2, L"ShortcutFolders"); + + SendMessage(pItemsData->hwndDlg, PM_ITEM_START, 1, (LPARAM)Steps); + + if (!CreateShortcuts(pItemsData, &Notify, hShortcutsInf1, L"ShortcutFolders")) + { + DPRINT1("CreateShortcuts() failed"); + goto done; + } + + if (hShortcutsInf2 != INVALID_HANDLE_VALUE) + { + if (!CreateShortcuts(pItemsData, &Notify, hShortcutsInf2, L"ShortcutFolders")) + { + DPRINT1("CreateShortcuts(rosapps) failed"); + goto done; + } + } + +done: + if (hShortcutsInf2 != INVALID_HANDLE_VALUE) + SetupCloseInfFile(hShortcutsInf2); + + if (hShortcutsInf1 != INVALID_HANDLE_VALUE) + SetupCloseInfFile(hShortcutsInf1); + + SendMessage(pItemsData->hwndDlg, PM_ITEM_END, 1, LastError); +} + static VOID CreateTempDir( IN LPCWSTR VarName) @@ -435,7 +536,11 @@ InstallSysSetupInfComponents(VOID) BOOL -RegisterTypeLibraries(HINF hinf, LPCWSTR szSection) +RegisterTypeLibraries( + _In_ PITEMSDATA pItemsData, + _In_ PREGISTRATIONNOTIFY pNotify, + _In_ HINF hinf, + _In_ LPCWSTR szSection) { INFCONTEXT InfContext; BOOL res; @@ -472,6 +577,15 @@ RegisterTypeLibraries(HINF hinf, LPCWSTR szSection) p = PathAddBackslash(szPath); wcscpy(p, szName); + if (pItemsData && pNotify) + { + pNotify->Progress++; + pNotify->CurrentItem = szName; + + DPRINT("RegisterTypeLibraries: Start step %ld\n", pNotify->Progress); + SendMessage(pItemsData->hwndDlg, PM_STEP_START, 0, (LPARAM)pNotify); + } + hmod = LoadLibraryW(szPath); if (hmod == NULL) { @@ -481,6 +595,12 @@ RegisterTypeLibraries(HINF hinf, LPCWSTR szSection) __wine_register_resources(hmod); + if (pItemsData && pNotify) + { + DPRINT("RegisterTypeLibraries: End step %ld\n", pNotify->Progress); + SendMessage(pItemsData->hwndDlg, PM_STEP_END, 0, (LPARAM)pNotify); + } + } while (SetupFindNextLine(&InfContext, &InfContext)); return TRUE; @@ -865,6 +985,61 @@ IsConsoleBoot(VOID) return bConsoleBoot; } +extern VOID +EnableVisualTheme( + _In_opt_ HWND hwndParent, + _In_opt_ PCWSTR ThemeFile); + +/** + * @brief + * Pre-process unattended file to apply early settings. + * + * @param[in] IsInstall + * TRUE if this is ReactOS installation, invoked from InstallReactOS(), + * FALSE if this is run as part of LiveCD, invoked form InstallLiveCD(). + **/ +static VOID +PreprocessUnattend( + _In_ BOOL IsInstall) +{ + WCHAR szPath[MAX_PATH]; + WCHAR szValue[MAX_PATH]; + BOOL bDefaultThemesOff; + + if (IsInstall) + { + /* See also wizard.c!ProcessSetupInf() + * Retrieve the path of the setup INF */ + GetSystemDirectoryW(szPath, _countof(szPath)); + wcscat(szPath, L"\\$winnt$.inf"); + } + else + { + /* See also userinit/livecd.c!RunLiveCD() */ + GetWindowsDirectoryW(szPath, _countof(szPath)); + wcscat(szPath, L"\\unattend.inf"); + } + + /* + * Apply initial default theming + */ + + /* Check whether to use the classic theme (TRUE) instead of the default theme */ + bDefaultThemesOff = FALSE; + if (GetPrivateProfileStringW(L"Shell", L"DefaultThemesOff", L"no", szValue, _countof(szValue), szPath) && *szValue) + bDefaultThemesOff = (_wcsicmp(szValue, L"yes") == 0); + + if (!bDefaultThemesOff) + { + /* Retrieve the complete path to a .theme (or for ReactOS, a .msstyles) file */ + if (!GetPrivateProfileStringW(L"Shell", L"CustomDefaultThemeFile", NULL, szValue, _countof(szValue), szPath) || !*szValue) + bDefaultThemesOff = TRUE; // None specified, fall back to the classic theme. + } + + /* Enable the chosen theme, or use the classic theme */ + EnableVisualTheme(NULL, bDefaultThemesOff ? NULL : szValue); +} + static BOOL CommonInstall(VOID) { @@ -887,7 +1062,7 @@ CommonInstall(VOID) goto Exit; } - if(!InstallSysSetupInfComponents()) + if (!InstallSysSetupInfComponents()) { FatalError("InstallSysSetupInfComponents() failed!\n"); goto Exit; @@ -918,7 +1093,6 @@ CommonInstall(VOID) bResult = TRUE; Exit: - if (bResult == FALSE) { SetupCloseInfFile(hSysSetupInf); @@ -942,6 +1116,7 @@ InstallLiveCD(VOID) PROCESS_INFORMATION ProcessInformation; BOOL bRes; + PreprocessUnattend(FALSE); if (!CommonInstall()) goto error; @@ -970,7 +1145,7 @@ InstallLiveCD(VOID) DPRINT1("SetupInstallFromInfSectionW failed!\n"); } - RegisterTypeLibraries(hSysSetupInf, L"TypeLibraries"); + RegisterTypeLibraries(NULL, NULL, hSysSetupInf, L"TypeLibraries"); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { @@ -1049,19 +1224,19 @@ HotkeyThread(LPVOID Parameter) DPRINT("HotkeyThread start\n"); hotkey = GlobalAddAtomW(L"Setup Shift+F10 Hotkey"); - if (!RegisterHotKey(NULL, hotkey, MOD_SHIFT, VK_F10)) DPRINT1("RegisterHotKey failed with %lu\n", GetLastError()); - while (GetMessage(&msg, NULL, 0, 0)) + while (GetMessageW(&msg, NULL, 0, 0)) { if (msg.hwnd == NULL && msg.message == WM_HOTKEY && msg.wParam == hotkey) { + WCHAR CmdLine[] = L"cmd.exe"; // CreateProcess can modify this buffer. STARTUPINFOW si = { sizeof(si) }; PROCESS_INFORMATION pi; - if (CreateProcessW(L"cmd.exe", - NULL, + if (CreateProcessW(NULL, + CmdLine, NULL, NULL, FALSE, @@ -1393,9 +1568,7 @@ InstallReactOS(VOID) HANDLE token; TOKEN_PRIVILEGES privs; HKEY hKey; - HINF hShortcutsInf; HANDLE hHotkeyThread; - BOOL ret; InitializeSetupActionLog(FALSE); LogItem(NULL, L"Installing ReactOS"); @@ -1461,61 +1634,16 @@ InstallReactOS(VOID) hHotkeyThread = CreateThread(NULL, 0, HotkeyThread, NULL, 0, NULL); + PreprocessUnattend(TRUE); if (!CommonInstall()) return 0; - /* Install the TCP/IP protocol driver */ - ret = InstallNetworkComponent(L"MS_TCPIP"); - if (!ret && GetLastError() != ERROR_FILE_NOT_FOUND) - { - DPRINT("InstallNetworkComponent() failed with error 0x%lx\n", GetLastError()); - } - else - { - /* Start the TCP/IP protocol driver */ - SetupStartService(L"Tcpip", FALSE); - SetupStartService(L"Dhcp", FALSE); - SetupStartService(L"Dnscache", FALSE); - } - InstallWizard(); InstallSecurity(); SetAutoAdminLogon(); - hShortcutsInf = SetupOpenInfFileW(L"shortcuts.inf", - NULL, - INF_STYLE_WIN4, - NULL); - if (hShortcutsInf == INVALID_HANDLE_VALUE) - { - FatalError("Failed to open shortcuts.inf"); - return 0; - } - - if (!CreateShortcuts(hShortcutsInf, L"ShortcutFolders")) - { - FatalError("CreateShortcuts() failed"); - return 0; - } - - SetupCloseInfFile(hShortcutsInf); - - hShortcutsInf = SetupOpenInfFileW(L"rosapps_shortcuts.inf", - NULL, - INF_STYLE_WIN4, - NULL); - if (hShortcutsInf != INVALID_HANDLE_VALUE) - { - if (!CreateShortcuts(hShortcutsInf, L"ShortcutFolders")) - { - FatalError("CreateShortcuts(rosapps) failed"); - return 0; - } - SetupCloseInfFile(hShortcutsInf); - } - SetupCloseInfFile(hSysSetupInf); SetSetupType(0); diff --git a/dll/win32/syssetup/resources/reactos.bmp b/dll/win32/syssetup/resources/reactos.bmp index 2ec7eeb1772f6..ef1fc5765c858 100644 Binary files a/dll/win32/syssetup/resources/reactos.bmp and b/dll/win32/syssetup/resources/reactos.bmp differ diff --git a/dll/win32/syssetup/wizard.c b/dll/win32/syssetup/wizard.c index 491e2504e1221..9ec3d167db715 100644 --- a/dll/win32/syssetup/wizard.c +++ b/dll/win32/syssetup/wizard.c @@ -27,40 +27,13 @@ #define NDEBUG #include -#define PM_REGISTRATION_NOTIFY (WM_APP + 1) -/* Private Message used to communicate progress from the background - registration thread to the main thread. - wParam = 0 Registration in progress - = 1 Registration completed - lParam = Pointer to a REGISTRATIONNOTIFY structure */ - -#define PM_ITEM_START (WM_APP + 2) -#define PM_ITEM_END (WM_APP + 3) -#define PM_STEP_START (WM_APP + 4) -#define PM_STEP_END (WM_APP + 5) -#define PM_ITEMS_DONE (WM_APP + 6) - -typedef struct _REGISTRATIONNOTIFY -{ - ULONG Progress; - UINT ActivityID; - LPCWSTR CurrentItem; - LPCWSTR ErrorMessage; - UINT MessageID; - DWORD LastError; -} REGISTRATIONNOTIFY, *PREGISTRATIONNOTIFY; - -typedef struct _ITEMSDATA -{ - HWND hwndDlg; -} ITEMSDATA, *PITEMSDATA; - typedef struct _REGISTRATIONDATA { HWND hwndDlg; ULONG DllCount; ULONG Registered; PVOID DefaultContext; + PREGISTRATIONNOTIFY pNotify; } REGISTRATIONDATA, *PREGISTRATIONDATA; typedef struct _TIMEZONE_ENTRY @@ -79,7 +52,6 @@ typedef struct _TIMEZONE_ENTRY extern void WINAPI Control_RunDLLW(HWND hWnd, HINSTANCE hInst, LPCWSTR cmd, DWORD nCmdShow); - static VOID CenterWindow(HWND hWnd) { @@ -964,30 +936,35 @@ WriteComputerSettings(WCHAR * ComputerName, HWND hwndDlg) SetAccountsDomainSid(NULL, ComputerName); /* Now we need to set the Hostname */ - lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, - L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", - 0, - KEY_SET_VALUE, - &hKey); - if (lError != ERROR_SUCCESS) - { - DPRINT1("RegOpenKeyExW for Tcpip\\Parameters failed (%08lX)\n", lError); - return TRUE; - } + lError = RegCreateKeyExW(HKEY_LOCAL_MACHINE, + L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", + 0, + NULL, + REG_OPTION_NON_VOLATILE, + KEY_WRITE, + NULL, + &hKey, + NULL); + if (lError == ERROR_SUCCESS) + { + lError = RegSetValueEx(hKey, + L"Hostname", + 0, + REG_SZ, + (LPBYTE)ComputerName, + (wcslen(ComputerName) + 1) * sizeof(WCHAR)); + if (lError != ERROR_SUCCESS) + { + DPRINT1("RegSetValueEx(\"Hostname\") failed (%08lX)\n", lError); + } - lError = RegSetValueEx(hKey, - L"Hostname", - 0, - REG_SZ, - (LPBYTE)ComputerName, - (wcslen(ComputerName) + 1) * sizeof(WCHAR)); - if (lError != ERROR_SUCCESS) + RegCloseKey(hKey); + } + else { - DPRINT1("RegSetValueEx(\"Hostname\") failed (%08lX)\n", lError); + DPRINT1("RegCreateKeyExW for Tcpip\\Parameters failed (%08lX)\n", lError); } - RegCloseKey(hKey); - return TRUE; } @@ -1389,6 +1366,90 @@ RunControlPanelApplet(HWND hwnd, PCWSTR pwszCPLParameters) return TRUE; } + +VOID +EnableVisualTheme( + _In_opt_ HWND hwndParent, + _In_opt_ PCWSTR ThemeFile) +{ + enum { THEME_FILE, STYLE_FILE, UNKNOWN } fType; + WCHAR szPath[MAX_PATH]; // Expanded path of the file to use. + WCHAR szStyleFile[MAX_PATH]; + + fType = THEME_FILE; // Default to Classic theme. + if (ThemeFile) + { + /* Expand the path if possible */ + if (ExpandEnvironmentStringsW(ThemeFile, szPath, _countof(szPath)) != 0) + ThemeFile = szPath; + + /* Determine the file type from its extension */ + fType = UNKNOWN; { + PCWSTR pszExt = wcsrchr(ThemeFile, L'.'); // PathFindExtensionW(ThemeFile); + if (pszExt) + { + if (_wcsicmp(pszExt, L".theme") == 0) + fType = THEME_FILE; + else if (_wcsicmp(pszExt, L".msstyles") == 0) + fType = STYLE_FILE; + } } + if (fType == UNKNOWN) + { + DPRINT1("EnableVisualTheme(): Unknown file '%S'\n", ThemeFile); + return; + } + } + + DPRINT1("Applying visual %s '%S'\n", + (fType == THEME_FILE) ? "theme" : "style", + ThemeFile ? ThemeFile : L"(Classic)"); + +// +// TODO: Use instead uxtheme!SetSystemVisualStyle() once it is implemented, +// https://stackoverflow.com/a/1036903 +// https://pinvoke.net/default.aspx/uxtheme.SetSystemVisualStyle +// or ApplyTheme(NULL, 0, NULL) for restoring the classic theme. +// +// NOTE: The '/Action:ActivateMSTheme' is ReactOS-specific. +// + + if (ThemeFile && (fType == THEME_FILE)) + { + /* Retrieve the visual style specified in the theme file. + * If none, fall back to the classic theme. */ + if (GetPrivateProfileStringW(L"VisualStyles", L"Path", NULL, + szStyleFile, _countof(szStyleFile), ThemeFile) && *szStyleFile) + { + /* Expand the path if possible */ + ThemeFile = szStyleFile; + if (ExpandEnvironmentStringsW(ThemeFile, szPath, _countof(szPath)) != 0) + ThemeFile = szPath; + } + else + { + ThemeFile = NULL; + } + + DPRINT1("--> Applying visual style '%S'\n", + ThemeFile ? ThemeFile : L"(Classic)"); + } + + if (ThemeFile) + { + WCHAR wszParams[1024]; + // FIXME: L"desk.cpl desk,@Appearance" regression, see commit 50d260a7f0 + PCWSTR format = L"desk.cpl,,2 /Action:ActivateMSTheme /file:\"%s\""; + + StringCchPrintfW(wszParams, _countof(wszParams), format, ThemeFile); + RunControlPanelApplet(hwndParent, wszParams); + } + else + { + RunControlPanelApplet(hwndParent, L"desk.cpl,,2 /Action:ActivateMSTheme"); + } +} + + static VOID WriteUserLocale(VOID) { @@ -1949,13 +2010,14 @@ ThemePageDlgProc(HWND hwndDlg, /* Register the imagelist */ ListView_SetImageList(hListView, himl, LVSIL_NORMAL); - /* Transparant background */ + /* Transparent background */ ListView_SetBkColor(hListView, CLR_NONE); ListView_SetTextBkColor(hListView, CLR_NONE); /* Reduce the size between the items */ ListView_SetIconSpacing(hListView, 190, 173); break; } + case WM_NOTIFY: switch (((LPNMHDR)lParam)->code) { @@ -1969,17 +2031,13 @@ ThemePageDlgProc(HWND hwndDlg, if (Themes[iTheme].ThemeFile) { - WCHAR wszParams[1024]; WCHAR wszTheme[MAX_PATH]; - WCHAR* format = L"desk.cpl,,2 /Action:ActivateMSTheme /file:\"%s\""; - SHGetFolderPathAndSubDirW(0, CSIDL_RESOURCES, NULL, SHGFP_TYPE_DEFAULT, Themes[iTheme].ThemeFile, wszTheme); - swprintf(wszParams, format, wszTheme); - RunControlPanelApplet(hwndDlg, wszParams); + EnableVisualTheme(hwndDlg, wszTheme); } else { - RunControlPanelApplet(hwndDlg, L"desk.cpl,,2 /Action:ActivateMSTheme"); + EnableVisualTheme(hwndDlg, Themes[iTheme].ThemeFile); } } break; @@ -2019,7 +2077,6 @@ RegistrationNotificationProc(PVOID Context, UINT_PTR Param2) { PREGISTRATIONDATA RegistrationData; - REGISTRATIONNOTIFY RegistrationNotify; PSP_REGISTER_CONTROL_STATUSW StatusInfo; UINT MessageID; @@ -2029,23 +2086,24 @@ RegistrationNotificationProc(PVOID Context, Notification == SPFILENOTIFY_ENDREGISTRATION) { StatusInfo = (PSP_REGISTER_CONTROL_STATUSW) Param1; - RegistrationNotify.CurrentItem = wcsrchr(StatusInfo->FileName, L'\\'); - if (RegistrationNotify.CurrentItem == NULL) + RegistrationData->pNotify->CurrentItem = wcsrchr(StatusInfo->FileName, L'\\'); + if (RegistrationData->pNotify->CurrentItem == NULL) { - RegistrationNotify.CurrentItem = StatusInfo->FileName; + RegistrationData->pNotify->CurrentItem = StatusInfo->FileName; } else { - RegistrationNotify.CurrentItem++; + RegistrationData->pNotify->CurrentItem++; } if (Notification == SPFILENOTIFY_STARTREGISTRATION) { DPRINT("Received SPFILENOTIFY_STARTREGISTRATION notification for %S\n", StatusInfo->FileName); - RegistrationNotify.ErrorMessage = NULL; - RegistrationNotify.Progress = RegistrationData->Registered; - SendMessage(RegistrationData->hwndDlg, PM_STEP_START, 0, (LPARAM)&RegistrationNotify); + RegistrationData->pNotify->Progress = RegistrationData->Registered; + + DPRINT("RegisterDll: Start step %ld\n", RegistrationData->pNotify->Progress); + SendMessage(RegistrationData->hwndDlg, PM_STEP_START, 0, (LPARAM)RegistrationData->pNotify); } else { @@ -2077,13 +2135,13 @@ RegistrationNotificationProc(PVOID Context, break; } - RegistrationNotify.MessageID = MessageID; - RegistrationNotify.LastError = StatusInfo->Win32Error; + RegistrationData->pNotify->MessageID = MessageID; + RegistrationData->pNotify->LastError = StatusInfo->Win32Error; } else { - RegistrationNotify.MessageID = 0; - RegistrationNotify.LastError = ERROR_SUCCESS; + RegistrationData->pNotify->MessageID = 0; + RegistrationData->pNotify->LastError = ERROR_SUCCESS; } if (RegistrationData->Registered < RegistrationData->DllCount) @@ -2091,8 +2149,9 @@ RegistrationNotificationProc(PVOID Context, RegistrationData->Registered++; } - RegistrationNotify.Progress = RegistrationData->Registered; - SendMessage(RegistrationData->hwndDlg, PM_STEP_END, 0, (LPARAM)&RegistrationNotify); + RegistrationData->pNotify->Progress = RegistrationData->Registered; + DPRINT("RegisterDll: End step %ld\n", RegistrationData->pNotify->Progress); + SendMessage(RegistrationData->hwndDlg, PM_STEP_END, 0, (LPARAM)RegistrationData->pNotify); } return FILEOP_DOIT; @@ -2109,13 +2168,14 @@ RegistrationNotificationProc(PVOID Context, static DWORD RegisterDlls( - PITEMSDATA pItemsData) + _In_ PITEMSDATA pItemsData, + _In_ PREGISTRATIONNOTIFY pNotify) { REGISTRATIONDATA RegistrationData; WCHAR SectionName[512]; INFCONTEXT Context; LONG DllCount = 0; - DWORD LastError = NO_ERROR; + DWORD Error = NO_ERROR; ZeroMemory(&RegistrationData, sizeof(REGISTRATIONDATA)); RegistrationData.hwndDlg = pItemsData->hwndDlg; @@ -2125,7 +2185,7 @@ RegisterDlls( L"RegisterDlls", &Context)) { DPRINT1("No RegistrationPhase2 section found\n"); - return FALSE; + return GetLastError(); } if (!SetupGetStringFieldW(&Context, 1, SectionName, @@ -2133,21 +2193,19 @@ RegisterDlls( NULL)) { DPRINT1("Unable to retrieve section name\n"); - return FALSE; + return GetLastError(); } DllCount = SetupGetLineCountW(hSysSetupInf, SectionName); - DPRINT1("SectionName %S DllCount %ld\n", SectionName, DllCount); + DPRINT("SectionName %S DllCount %ld\n", SectionName, DllCount); if (DllCount < 0) { - SetLastError(STATUS_NOT_FOUND); - return FALSE; + return STATUS_NOT_FOUND; } RegistrationData.DllCount = (ULONG)DllCount; RegistrationData.DefaultContext = SetupInitDefaultQueueCallback(RegistrationData.hwndDlg); - - SendMessage(pItemsData->hwndDlg, PM_ITEM_START, 0, (LPARAM)RegistrationData.DllCount); + RegistrationData.pNotify = pNotify; _SEH2_TRY { @@ -2163,21 +2221,66 @@ RegisterDlls( NULL, NULL)) { - LastError = GetLastError(); + Error = GetLastError(); } } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { DPRINT("Catching exception\n"); - LastError = RtlNtStatusToDosError(_SEH2_GetExceptionCode()); + Error = RtlNtStatusToDosError(_SEH2_GetExceptionCode()); } _SEH2_END; SetupTermDefaultQueueCallback(RegistrationData.DefaultContext); - SendMessage(pItemsData->hwndDlg, PM_ITEM_END, 0, LastError); + return Error; +} - return 0; +static +VOID +RegisterComponents( + PITEMSDATA pItemsData) +{ + WCHAR SectionName[512]; + INFCONTEXT Context; + LONG Steps = 0; + DWORD Error = NO_ERROR; + REGISTRATIONNOTIFY Notify; + + ZeroMemory(&Notify, sizeof(Notify)); + + /* Count the 'RegisterDlls' steps */ + if (!SetupFindFirstLineW(hSysSetupInf, L"RegistrationPhase2", + L"RegisterDlls", &Context)) + { + DPRINT1("No RegistrationPhase2 section found\n"); + return; + } + + if (!SetupGetStringFieldW(&Context, 1, SectionName, + ARRAYSIZE(SectionName), + NULL)) + { + DPRINT1("Unable to retrieve section name\n"); + return; + } + + Steps += SetupGetLineCountW(hSysSetupInf, SectionName); + + /* Count the 'TypeLibratries' steps */ + Steps += SetupGetLineCountW(hSysSetupInf, L"TypeLibraries"); + + /* Start the item */ + DPRINT("Register Components: %ld Steps\n", Steps); + SendMessage(pItemsData->hwndDlg, PM_ITEM_START, 0, (LPARAM)Steps); + + Error = RegisterDlls(pItemsData, &Notify); + if (Error == ERROR_SUCCESS) + RegisterTypeLibraries(pItemsData, &Notify, hSysSetupInf, L"TypeLibraries"); + + /* End the item */ + DPRINT("Register Components: done\n"); + SendMessage(pItemsData->hwndDlg, PM_ITEM_END, 0, Error); } @@ -2193,9 +2296,11 @@ ItemCompletionThread( pItemsData = (PITEMSDATA)Parameter; hwndDlg = pItemsData->hwndDlg; - RegisterDlls(pItemsData); + /* Step 0 - Registering components */ + RegisterComponents(pItemsData); - RegisterTypeLibraries(hSysSetupInf, L"TypeLibraries"); + /* Step 1 - Installing start menu items */ + InstallStartMenuItems(pItemsData); /* FIXME: Add completion steps here! */ @@ -2345,7 +2450,6 @@ ProcessPageDlgProc(HWND hwndDlg, /* Save pointer to the global setup data */ SetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam; SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)SetupData); - ShowWindow(GetDlgItem(hwndDlg, IDC_TASKTEXT2), SW_HIDE); ShowWindow(GetDlgItem(hwndDlg, IDC_TASKTEXT3), SW_HIDE); ShowWindow(GetDlgItem(hwndDlg, IDC_TASKTEXT4), SW_HIDE); break; @@ -2354,12 +2458,15 @@ ProcessPageDlgProc(HWND hwndDlg, switch (((LPNMHDR)lParam)->code) { case PSN_SETACTIVE: + LogItem(L"BEGIN", L"ProcessPage"); + /* Disable the Back and Next buttons */ PropSheet_SetWizButtons(GetParent(hwndDlg), 0); RunItemCompletionThread(hwndDlg); break; case PSN_WIZNEXT: + LogItem(L"END", L"ProcessPage"); break; case PSN_WIZBACK: diff --git a/dll/win32/t2embed/main.c b/dll/win32/t2embed/main.c index e47884611ce36..51be86b5e5096 100644 --- a/dll/win32/t2embed/main.c +++ b/dll/win32/t2embed/main.c @@ -32,8 +32,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { switch (fdwReason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hinstDLL); break; diff --git a/dll/win32/tapi32/CMakeLists.txt b/dll/win32/tapi32/CMakeLists.txt index 3c1d617136fb6..33f2ad410e7f5 100644 --- a/dll/win32/tapi32/CMakeLists.txt +++ b/dll/win32/tapi32/CMakeLists.txt @@ -1,6 +1,4 @@ -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) -add_definitions(-D__WINESRC__) spec2def(tapi32.dll tapi32.spec) list(APPEND SOURCE @@ -20,3 +18,4 @@ target_link_libraries(tapi32 wine) add_importlibs(tapi32 advapi32 msvcrt kernel32 ntdll) add_pch(tapi32 precomp.h SOURCE) add_cd_file(TARGET tapi32 DESTINATION reactos/system32 FOR all) +set_wine_module(tapi32) diff --git a/dll/win32/themeui/themeui.rc b/dll/win32/themeui/themeui.rc index 230cac724d45a..a13fe55052ea7 100644 --- a/dll/win32/themeui/themeui.rc +++ b/dll/win32/themeui/themeui.rc @@ -13,6 +13,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL /* UTF-8 */ #pragma code_page(65001) + #ifdef LANGUAGE_CS_CZ #include "lang/cs-CZ.rc" #endif diff --git a/dll/win32/traffic/CMakeLists.txt b/dll/win32/traffic/CMakeLists.txt index 85625c63e4e14..40889e6f8ecad 100644 --- a/dll/win32/traffic/CMakeLists.txt +++ b/dll/win32/traffic/CMakeLists.txt @@ -1,6 +1,4 @@ -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) -add_definitions(-D__WINESRC__) spec2def(traffic.dll traffic.spec) list(APPEND SOURCE @@ -13,3 +11,4 @@ set_module_type(traffic win32dll) target_link_libraries(traffic wine) add_importlibs(traffic msvcrt kernel32 ntdll) add_cd_file(TARGET traffic DESTINATION reactos/system32 FOR all) +set_wine_module(traffic) diff --git a/dll/win32/traffic/traffic_main.c b/dll/win32/traffic/traffic_main.c index 6b8a9751e194c..210859914de2f 100644 --- a/dll/win32/traffic/traffic_main.c +++ b/dll/win32/traffic/traffic_main.c @@ -32,8 +32,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) switch (fdwReason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hinstDLL); break; diff --git a/dll/win32/twain_32/CMakeLists.txt b/dll/win32/twain_32/CMakeLists.txt index 6a00adfb665a9..8f168ae3f61da 100644 --- a/dll/win32/twain_32/CMakeLists.txt +++ b/dll/win32/twain_32/CMakeLists.txt @@ -1,6 +1,4 @@ -include_directories(BEFORE ${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) -add_definitions(-D__WINESRC__) spec2def(twain_32.dll twain_32.spec) list(APPEND SOURCE @@ -18,3 +16,4 @@ target_link_libraries(twain_32 wine) add_importlibs(twain_32 user32 msvcrt kernel32 ntdll) add_pch(twain_32 precomp.h SOURCE) add_cd_file(TARGET twain_32 DESTINATION reactos FOR all) +set_wine_module(twain_32) diff --git a/dll/win32/ucrtbase/CMakeLists.txt b/dll/win32/ucrtbase/CMakeLists.txt new file mode 100644 index 0000000000000..0cc2d8f34b91d --- /dev/null +++ b/dll/win32/ucrtbase/CMakeLists.txt @@ -0,0 +1,55 @@ + +spec2def(ucrtbase.dll ucrtbase.spec NO_DBG ADD_IMPORTLIB) + +# Hack to replace the old CRT include directory with the UCRT include directory +get_property(INCLUDE_DIRS DIRECTORY . PROPERTY INCLUDE_DIRECTORIES) +list(REMOVE_ITEM INCLUDE_DIRS "${REACTOS_SOURCE_DIR}/sdk/include/crt") +set_property(DIRECTORY . PROPERTY INCLUDE_DIRECTORIES ${INCLUDE_DIRS}) +include_directories(${REACTOS_SOURCE_DIR}/sdk/include/ucrt) + +remove_definitions(-D_CRT_NON_CONFORMING_SWPRINTFS) + +add_compile_definitions( + _UCRT + _CORECRT_BUILD + CRTDLL +) + +add_library(ucrtbase SHARED + printf.c + stubs.c + ucrtbase_stubs.c + ucrtbase.def +) + +if(NOT MSVC) + target_compile_options(ucrtbase PRIVATE -Wno-builtin-declaration-mismatch) +endif() + +if(CMAKE_C_COMPILER_ID STREQUAL "Clang") + # Silence warnings in ucrtbase_stubs.c + target_compile_options(ucrtbase PRIVATE -Wno-incompatible-library-redeclaration) +endif() + +set_entrypoint(ucrtbase __acrt_DllMain 12) + +target_link_libraries(ucrtbase + ucrt + ucrtsupport + vcruntime + wine +) + +# Implicitly link to vcstartup +target_link_libraries(libucrtbase vcstartup) + +if(MSVC) + target_link_libraries(ucrtbase runtmchk) +else() + # For __cxa_guard_acquire / __cxa_guard_release + target_link_libraries(ucrtbase libsupc++) +endif() + +add_importlibs(ucrtbase kernel32 ntdll) + +add_cd_file(TARGET ucrtbase DESTINATION reactos/system32 FOR all) diff --git a/dll/win32/ucrtbase/printf.c b/dll/win32/ucrtbase/printf.c new file mode 100644 index 0000000000000..6823641b8c9a5 --- /dev/null +++ b/dll/win32/ucrtbase/printf.c @@ -0,0 +1,49 @@ +/* + * PROJECT: ReactOS CRT + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: Instantiation of CRT stdio inline functions + * COPYRIGHT: Copyright 2023-2024 Timo Kreuzer + */ + +#define _NO_CRT_STDIO_INLINE +#include + +// These 2 functions are inlined in UCRT headers, but they are referenced by +// external code in the legacy CRT, so we need to provide them as non-inline +// functions here. + +_Success_(return >= 0) +_Check_return_opt_ +int __CRTDECL sprintf( + _Pre_notnull_ _Always_(_Post_z_) char* const _Buffer, + _In_z_ _Printf_format_string_ char const* const _Format, + ...) +{ + int _Result; + va_list _ArgList; + + __crt_va_start(_ArgList, _Format); + + _Result = __stdio_common_vsprintf( + _CRT_INTERNAL_LOCAL_PRINTF_OPTIONS | _CRT_INTERNAL_PRINTF_LEGACY_VSPRINTF_NULL_TERMINATION, + _Buffer, (size_t)-1, _Format, NULL, _ArgList); + + __crt_va_end(_ArgList); + return _Result < 0 ? -1 : _Result; +} + +_Success_(return >= 0) +_Check_return_opt_ +int __CRTDECL _vsnprintf( + _Out_writes_opt_(_BufferCount) _Post_maybez_ char* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Printf_format_string_ char const* const _Format, + va_list _ArgList + ) +{ + int _Result = __stdio_common_vsprintf( + _CRT_INTERNAL_LOCAL_PRINTF_OPTIONS | _CRT_INTERNAL_PRINTF_LEGACY_VSPRINTF_NULL_TERMINATION, + _Buffer, _BufferCount, _Format, NULL, _ArgList); + + return _Result < 0 ? -1 : _Result; +} diff --git a/dll/win32/ucrtbase/stubs.c b/dll/win32/ucrtbase/stubs.c new file mode 100644 index 0000000000000..3758e2af1b106 --- /dev/null +++ b/dll/win32/ucrtbase/stubs.c @@ -0,0 +1,83 @@ + +#include +#include +#include +#define _USE_MATH_DEFINES +#include + +// atexit is needed by libsupc++ +extern int __cdecl _crt_atexit(void (__cdecl*)(void)); +int __cdecl atexit(void (__cdecl* function)(void)) +{ + return _crt_atexit(function); +} + +void* __cdecl operator_new(size_t size) +{ + return malloc(size); +} + +void _cdecl operator_delete(void *mem) +{ + free(mem); +} + +#ifdef _M_IX86 +void _chkesp_failed(void) +{ + __debugbreak(); +} +#endif + +int __cdecl __acrt_initialize_sse2(void) +{ + return 0; +} + +// The following stubs cannot be implemented as stubs by spec2def, because they are intrinsics + +#ifdef _MSC_VER +#pragma warning(disable:4163) // not available as an intrinsic function +#pragma warning(disable:4164) // intrinsic function not declared +#pragma function(fma) +#pragma function(fmaf) +#pragma function(log2) +#pragma function(log2f) +#pragma function(lrint) +#pragma function(lrintf) +#endif + +double fma(double x, double y, double z) +{ + // Simplistic implementation + return (x * y) + z; +} + +float fmaf(float x, float y, float z) +{ + // Simplistic implementation + return (x * y) + z; +} + +double log2(double x) +{ + // Simplistic implementation: log2(x) = log(x) / log(2) + return log(x) * M_LOG2E; +} + +float log2f(float x) +{ + return (float)log2((double)x); +} + +long int lrint(double x) +{ + __debugbreak(); + return 0; +} + +long int lrintf(float x) +{ + __debugbreak(); + return 0; +} diff --git a/dll/win32/ucrtbase/ucrtbase.spec b/dll/win32/ucrtbase/ucrtbase.spec new file mode 100644 index 0000000000000..7f759dd50d268 --- /dev/null +++ b/dll/win32/ucrtbase/ucrtbase.spec @@ -0,0 +1,2675 @@ +@ cdecl -arch=i386 _CIacos() +@ cdecl -arch=i386 _CIasin() +@ cdecl -arch=i386 _CIatan() +@ cdecl -arch=i386 _CIatan2() +@ cdecl -arch=i386 _CIcos() +@ cdecl -arch=i386 _CIcosh() +@ cdecl -arch=i386 _CIexp() +@ cdecl -arch=i386 _CIfmod() +@ cdecl -arch=i386 _CIlog() +@ cdecl -arch=i386 _CIlog10() +@ cdecl -arch=i386 _CIpow() +@ cdecl -arch=i386 _CIsin() +@ cdecl -arch=i386 _CIsinh() +@ cdecl -arch=i386 _CIsqrt() +@ cdecl -arch=i386 _CItan() +@ cdecl -arch=i386 _CItanh() +@ cdecl -stub _Cbuild(ptr double double) +@ stub _Cmulcc +@ stub _Cmulcr +@ cdecl _CreateFrameInfo(ptr ptr) +@ cdecl -dbg _CrtCheckMemory() +@ cdecl -dbg _CrtDbgReport(long str long str str) +@ cdecl -dbg _CrtDbgReportW(long wstr long wstr wstr) +@ cdecl -dbg _CrtDoForAllClientObjects(ptr ptr) +@ cdecl -dbg _CrtDumpMemoryLeaks() +@ cdecl -dbg _CrtGetAllocHook() +@ cdecl -dbg _CrtGetDebugFillThreshold(long) +@ cdecl -dbg _CrtGetDumpClient() +@ cdecl -dbg _CrtGetReportHook() +@ cdecl -dbg _CrtIsMemoryBlock(ptr long ptr ptr ptr) +@ cdecl -dbg _CrtIsValidHeapPointer(ptr) +@ cdecl -dbg _CrtIsValidPointer() # FIXME: params +@ cdecl -dbg _CrtMemCheckpoint() # FIXME: params +@ cdecl -dbg _CrtMemDifference() # FIXME: params +@ cdecl -dbg _CrtMemDumpAllObjectsSince(ptr) +@ cdecl -dbg _CrtMemDumpStatistics() # FIXME: params +@ cdecl -dbg _CrtReportBlockType() # FIXME: params +@ cdecl -dbg _CrtSetAllocHook() # FIXME: params +@ cdecl -dbg _CrtSetBreakAlloc() # FIXME: params +@ cdecl -dbg _CrtSetDbgBlockType() # FIXME: params +@ cdecl -dbg _CrtSetDbgFlag() # FIXME: params +@ cdecl -dbg _CrtSetDebugFillThreshold() # FIXME: params +@ cdecl -dbg _CrtSetDumpClient() # FIXME: params +@ cdecl -dbg _CrtSetReportFile() # FIXME: params +@ cdecl -dbg _CrtSetReportHook() # FIXME: params +@ cdecl -dbg _CrtSetReportHook2() # FIXME: params +@ cdecl -dbg _CrtSetReportHookW2() # FIXME: params +@ cdecl -dbg _CrtSetReportMode() # FIXME: params +@ stdcall _CxxThrowException(ptr ptr) +@ cdecl -arch=i386 -norelay _EH_prolog() +@ cdecl _Exit(long) +@ stub _FCbuild +@ stub _FCmulcc +@ stub _FCmulcr +@ cdecl _FindAndUnlinkFrame(ptr) +@ stub _GetImageBase +@ stub _GetThrowImageBase +@ cdecl _Getdays() +@ cdecl _Getmonths() +@ cdecl _Gettnames() +@ cdecl _IsExceptionObjectToBeDestroyed(ptr) +@ stub _LCbuild +@ stub _LCmulcc +@ stub _LCmulcr +@ stub _SetImageBase +@ stub _SetThrowImageBase +@ stub _NLG_Dispatch2 +@ stub _NLG_Return +@ stub _NLG_Return2 +@ cdecl -stub _SetWinRTOutOfMemoryExceptionCallback(ptr) +@ cdecl _Strftime(ptr long str ptr ptr) +@ cdecl -dbg _VCrtDbgReportA(long ptr str long str str ptr) +@ cdecl -dbg _VCrtDbgReportW(long ptr wstr long wstr wstr ptr) +@ cdecl _W_Getdays() +@ cdecl _W_Getmonths() +@ cdecl _W_Gettnames() +@ cdecl _Wcsftime(ptr long wstr ptr ptr) +@ cdecl __AdjustPointer(ptr ptr) +@ stub __BuildCatchObject +@ stub __BuildCatchObjectHelper +@ cdecl -arch=!i386 __C_specific_handler(ptr long ptr ptr) ntdll.__C_specific_handler +@ cdecl -stub -arch=!i386 __C_specific_handler_noexcept(ptr long ptr ptr) +@ cdecl __CxxDetectRethrow(ptr) +@ cdecl __CxxExceptionFilter(ptr ptr long ptr) +@ cdecl -norelay __CxxFrameHandler(ptr ptr ptr ptr) +@ cdecl -norelay __CxxFrameHandler2(ptr ptr ptr ptr) __CxxFrameHandler +@ cdecl -norelay __CxxFrameHandler3(ptr ptr ptr ptr) __CxxFrameHandler +@ cdecl -stub -arch=x86_64 __CxxFrameHandler4(ptr long ptr ptr) +@ stdcall -arch=i386 __CxxLongjmpUnwind(ptr) +@ cdecl __CxxQueryExceptionSize() +@ cdecl __CxxRegisterExceptionObject(ptr ptr) +@ cdecl __CxxUnregisterExceptionObject(ptr long) +@ cdecl __DestructExceptionObject(ptr) +@ stub __FrameUnwindFilter +@ stub __GetPlatformExceptionInfo +@ stub __NLG_Dispatch2 +@ stub __NLG_Return2 +@ cdecl __RTCastToVoid(ptr) +@ cdecl __RTDynamicCast(ptr long ptr ptr long) +@ cdecl __RTtypeid(ptr) +@ stub __TypeMatch +@ cdecl ___lc_codepage_func() +@ cdecl ___lc_collate_cp_func() +@ cdecl ___lc_locale_name_func() +@ cdecl ___mb_cur_max_func() +@ cdecl ___mb_cur_max_l_func(ptr) +@ cdecl __acrt_iob_func(long) +@ cdecl __conio_common_vcprintf(int64 str ptr ptr) +@ cdecl __conio_common_vcprintf_p(int64 str ptr ptr) +@ cdecl __conio_common_vcprintf_s(int64 str ptr ptr) +@ cdecl __conio_common_vcscanf(int64 str ptr ptr) +@ cdecl __conio_common_vcwprintf(int64 wstr ptr ptr) +@ cdecl __conio_common_vcwprintf_p(int64 wstr ptr ptr) +@ cdecl __conio_common_vcwprintf_s(int64 wstr ptr ptr) +@ cdecl __conio_common_vcwscanf(int64 wstr ptr ptr) +@ cdecl -stub -arch=i386 __control87_2(long long ptr ptr) +@ cdecl __current_exception() +@ cdecl __current_exception_context() +@ cdecl __daylight() +@ cdecl __dcrt_get_wide_environment_from_os() # FIXME: params +@ cdecl __dcrt_initial_narrow_environment() +@ cdecl __doserrno() +@ cdecl __dstbias() +@ cdecl -stub __fpe_flt_rounds() +@ cdecl __fpecode() +@ cdecl __initialize_lconv_for_unsigned_char() +@ cdecl -stub __intrinsic_abnormal_termination() # CHECKME +@ cdecl -stub -norelay __intrinsic_setjmp(ptr) # _setjmp +@ cdecl -stub -arch=!i386 -norelay __intrinsic_setjmpex(ptr ptr) # _setjmpex +@ cdecl __isascii(long) +@ cdecl __iscsym(long) +@ cdecl __iscsymf(long) +@ cdecl __iswcsym(long) +@ cdecl __iswcsymf(long) +@ stdcall -arch=arm __jump_unwind(ptr ptr) ntdll.__jump_unwind +@ cdecl -stub -arch=i386 -norelay __libm_sse2_acos() +@ cdecl -stub -arch=i386 -norelay __libm_sse2_acosf() +@ cdecl -stub -arch=i386 -norelay __libm_sse2_asin() +@ cdecl -stub -arch=i386 -norelay __libm_sse2_asinf() +@ cdecl -stub -arch=i386 -norelay __libm_sse2_atan() +@ cdecl -stub -arch=i386 -norelay __libm_sse2_atan2() +@ cdecl -stub -arch=i386 -norelay __libm_sse2_atanf() +@ cdecl -stub -arch=i386 -norelay __libm_sse2_cos() +@ cdecl -stub -arch=i386 -norelay __libm_sse2_cosf() +@ cdecl -stub -arch=i386 -norelay __libm_sse2_exp() +@ cdecl -stub -arch=i386 -norelay __libm_sse2_expf() +@ cdecl -stub -arch=i386 -norelay __libm_sse2_log() +@ cdecl -stub -arch=i386 -norelay __libm_sse2_log10() +@ cdecl -stub -arch=i386 -norelay __libm_sse2_log10f() +@ cdecl -stub -arch=i386 -norelay __libm_sse2_logf() +@ cdecl -stub -arch=i386 -norelay __libm_sse2_pow() +@ cdecl -stub -arch=i386 -norelay __libm_sse2_powf() +@ cdecl -stub -arch=i386 -norelay __libm_sse2_sin() +@ cdecl -stub -arch=i386 -norelay __libm_sse2_sinf() +@ cdecl -stub -arch=i386 -norelay __libm_sse2_tan() +@ cdecl -stub -arch=i386 -norelay __libm_sse2_tanf() +@ cdecl __p___argc() +@ cdecl __p___argv() +@ cdecl __p___wargv() +@ cdecl __p__acmdln() +@ cdecl __p__commode() +@ cdecl -dbg __p__crtBreakAlloc() +@ cdecl -dbg __p__crtDbgFlag() +@ cdecl __p__environ() +@ cdecl __p__fmode() +@ cdecl __p__mbcasemap() +@ cdecl __p__mbctype() +@ cdecl __p__pgmptr() +@ cdecl __p__wcmdln() +@ cdecl __p__wenviron() +@ cdecl __p__wpgmptr() +@ cdecl __pctype_func() +@ cdecl __processing_throw() +@ cdecl __pwctype_func() +@ cdecl __pxcptinfoptrs() +@ cdecl __report_gsfailure() +@ cdecl __setusermatherr(ptr) +@ cdecl __std_exception_copy(ptr ptr) +@ cdecl __std_exception_destroy(ptr) +@ cdecl __std_terminate() terminate +@ cdecl __std_type_info_compare(ptr ptr) +@ cdecl __std_type_info_destroy_list(ptr) +@ cdecl __std_type_info_hash(ptr) +@ cdecl __std_type_info_name(ptr ptr) +@ cdecl __stdio_common_vfprintf(int64 ptr str ptr ptr) +@ cdecl __stdio_common_vfprintf_p(int64 ptr str ptr ptr) +@ cdecl __stdio_common_vfprintf_s(int64 ptr str ptr ptr) +@ cdecl __stdio_common_vfscanf(int64 ptr str ptr ptr) +@ cdecl __stdio_common_vfwprintf(int64 ptr wstr ptr ptr) +@ cdecl __stdio_common_vfwprintf_p(int64 ptr wstr ptr ptr) +@ cdecl __stdio_common_vfwprintf_s(int64 ptr wstr ptr ptr) +@ cdecl __stdio_common_vfwscanf(int64 ptr wstr ptr ptr) +@ cdecl __stdio_common_vsnprintf_s(int64 ptr long long str ptr ptr) +@ cdecl __stdio_common_vsnwprintf_s(int64 ptr long long wstr ptr ptr) +@ cdecl -norelay __stdio_common_vsprintf(int64 ptr long str ptr ptr) +@ cdecl __stdio_common_vsprintf_p(int64 ptr long str ptr ptr) +@ cdecl __stdio_common_vsprintf_s(int64 ptr long str ptr ptr) +@ cdecl __stdio_common_vsscanf(int64 ptr long str ptr ptr) +@ cdecl __stdio_common_vswprintf(int64 ptr long wstr ptr ptr) +@ cdecl __stdio_common_vswprintf_p(int64 ptr long wstr ptr ptr) +@ cdecl __stdio_common_vswprintf_s(int64 ptr long wstr ptr ptr) +@ cdecl __stdio_common_vswscanf(int64 ptr long wstr ptr ptr) +@ cdecl __strncnt(str long) +@ cdecl __sys_errlist() +@ cdecl __sys_nerr() +@ cdecl __threadhandle() +@ cdecl __threadid() +@ cdecl __timezone() +@ cdecl __toascii(long) +@ cdecl __tzname() +@ cdecl __unDName(ptr str long ptr ptr long) +@ cdecl __unDNameEx(ptr str long ptr ptr ptr long) +@ cdecl __uncaught_exception() +@ cdecl -stub __uncaught_exceptions() +@ cdecl __wcserror(wstr) +@ cdecl __wcserror_s(ptr long wstr) +@ cdecl __wcsncnt(wstr long) +@ cdecl -ret64 _abs64(int64) +@ cdecl _access(str long) +@ cdecl _access_s(str long) +@ cdecl _aligned_free(ptr) +@ cdecl -dbg _aligned_free_dbg(ptr) +@ cdecl _aligned_malloc(long long) +@ cdecl -dbg _aligned_malloc_dbg(long long str long) +@ cdecl _aligned_msize(ptr long long) +@ cdecl -dbg _aligned_msize_dbg(ptr long long) +@ cdecl _aligned_offset_malloc(long long long) +@ cdecl -dbg _aligned_offset_malloc_dbg(long long long str long) +@ cdecl _aligned_offset_realloc(ptr long long long) +@ cdecl -dbg _aligned_offset_realloc_dbg(ptr long long long str long) +@ cdecl _aligned_offset_recalloc(ptr long long long long) +@ cdecl -dbg _aligned_offset_recalloc_dbg(ptr long long long long str long) +@ cdecl _aligned_realloc(ptr long long) +@ cdecl -dbg _aligned_realloc_dbg(ptr long long str long) +@ cdecl _aligned_recalloc(ptr long long long) +@ cdecl -dbg _aligned_recalloc_dbg(ptr long long long str long) +@ cdecl _assert(str str long) +@ cdecl _atodbl(ptr str) +@ cdecl _atodbl_l(ptr str ptr) +@ cdecl _atof_l(str ptr) +@ cdecl _atoflt(ptr str) +@ cdecl _atoflt_l(ptr str ptr) +@ cdecl -ret64 _atoi64(str) +@ cdecl -ret64 _atoi64_l(str ptr) +@ cdecl _atoi_l(str ptr) +@ cdecl _atol_l(str ptr) +@ cdecl _atoldbl(ptr str) +@ cdecl _atoldbl_l(ptr str ptr) +@ cdecl -ret64 _atoll_l(str ptr) +@ cdecl _beep(long long) +@ cdecl _beginthread(ptr long ptr) +@ cdecl _beginthreadex(ptr long ptr ptr long ptr) +@ cdecl _byteswap_uint64(int64) +@ cdecl _byteswap_ulong(long) +@ cdecl _byteswap_ushort(long) +@ cdecl _c_exit() +@ cdecl -stub _cabs(long) +@ cdecl _callnewh(long) +@ cdecl _calloc_base(long long) +@ cdecl -dbg _calloc_dbg(long long long str long) +@ cdecl _cexit() +@ cdecl _cgets(ptr) +@ cdecl _cgets_s(str long ptr) +@ cdecl _cgetws(wstr) +@ cdecl _cgetws_s(wstr long ptr) +@ cdecl _chdir(str) +@ cdecl _chdrive(long) +@ cdecl _chgsign(double) +@ cdecl _chgsignf(float) +@ cdecl -arch=i386 -norelay _chkesp() +@ cdecl _chmod(str long) +@ cdecl _chsize(long long) +@ cdecl _chsize_s(long int64) +@ cdecl -dbg _chvalidator(long long) +@ cdecl -dbg _chvalidator_l(ptr long long) +@ cdecl _clearfp() +@ cdecl _close(long) +@ cdecl _commit(long) +@ cdecl _configthreadlocale(long) +@ cdecl _configure_narrow_argv(long) +@ cdecl _configure_wide_argv(long) +@ cdecl _control87(long long) +@ cdecl _controlfp(long long) +@ cdecl _controlfp_s(ptr long long) +@ cdecl _copysign(double double) +@ cdecl _copysignf(float float) copysignf +@ cdecl _cputs(str) +@ cdecl _cputws(wstr) +@ cdecl _creat(str long) +@ cdecl _create_locale(long str) +@ cdecl _crt_at_quick_exit(ptr) +@ cdecl _crt_atexit(ptr) +@ cdecl -stub _crt_debugger_hook(long) +@ cdecl _ctime32(ptr) +@ cdecl _ctime32_s(str long ptr) +@ cdecl _ctime64(ptr) +@ cdecl _ctime64_s(str long ptr) +@ cdecl _cwait(ptr long long) +@ cdecl -stub _d_int(ptr long) +@ cdecl _dclass(double) +@ cdecl -stub _dexp(ptr double long) +@ cdecl _difftime32(long long) +@ cdecl _difftime64(int64 int64) +@ cdecl -stub _dlog(double long) +@ cdecl -stub _dnorm(ptr) +@ cdecl -stub _dpcomp(double double) +@ cdecl -stub _dpoly(double ptr long) +@ cdecl -stub _dscale(ptr long) +@ cdecl -stub _dsign(double) +@ cdecl -stub _dsin(double long) +@ cdecl _dtest(ptr) +@ cdecl -stub _dunscale(ptr ptr) +@ cdecl _dup(long) +@ cdecl _dup2(long long) +@ cdecl _dupenv_s(ptr ptr str) +@ cdecl -dbg _dupenv_s_dbg(ptr ptr str long ptr long) +@ cdecl _ecvt(double long ptr ptr) +@ cdecl _ecvt_s(str long double long ptr ptr) +@ cdecl _endthread() +@ cdecl _endthreadex(long) +@ cdecl _eof(long) +@ cdecl _errno() +@ cdecl -stub _except1(long long double double long ptr) +@ cdecl -arch=i386 _except_handler2(ptr ptr ptr ptr) +@ cdecl -arch=i386 _except_handler3(ptr ptr ptr ptr) +@ cdecl -arch=i386 _except_handler4_common(ptr ptr ptr ptr ptr ptr) +@ varargs _execl(str str) +@ varargs _execle(str str) +@ varargs _execlp(str str) +@ varargs _execlpe(str str) +@ cdecl _execute_onexit_table(ptr) +@ cdecl _execv(str ptr) +@ cdecl _execve(str ptr ptr) +@ cdecl _execvp(str ptr) +@ cdecl _execvpe(str ptr ptr) +@ cdecl _exit(long) +@ cdecl _expand(ptr long) +@ cdecl -dbg _expand_dbg(ptr long long str long) +@ cdecl _fclose_nolock(ptr) +@ cdecl _fcloseall() +@ cdecl _fcvt(double long ptr ptr) +@ cdecl _fcvt_s(ptr long double long ptr ptr) +@ cdecl -stub _fd_int(ptr long) +@ cdecl _fdclass(float) +@ cdecl -stub _fdexp(ptr float long) +@ cdecl -stub _fdlog(float long) +@ cdecl -stub _fdnorm(ptr) +@ cdecl _fdopen(long str) +@ cdecl -stub _fdpcomp(float float) +@ cdecl -stub _fdpoly(float ptr long) +@ cdecl -stub _fdscale(ptr long) +@ cdecl -stub _fdsign(float) +@ cdecl -stub _fdsin(float long) +@ cdecl _fdtest(ptr) +@ cdecl -stub _fdunscale(ptr ptr) +@ cdecl _fflush_nolock(ptr) +@ cdecl _fgetc_nolock(ptr) +@ cdecl _fgetchar() +@ cdecl _fgetwc_nolock(ptr) +@ cdecl _fgetwchar() +@ cdecl _filelength(long) +@ cdecl -ret64 _filelengthi64(long) +@ cdecl _fileno(ptr) +@ cdecl _findclose(long) +@ cdecl _findfirst32(str ptr) +@ cdecl _findfirst32i64(str ptr) +@ cdecl _findfirst64(str ptr) +@ cdecl _findfirst64i32(str ptr) +@ cdecl _findnext32(long ptr) +@ cdecl _findnext32i64(long ptr) +@ cdecl _findnext64(long ptr) +@ cdecl _findnext64i32(long ptr) +@ cdecl _finite(double) +@ cdecl -stub -arch=!i386 _finitef(float) +@ cdecl _flushall() +@ cdecl _fpclass(double) +@ cdecl -stub -arch=!i386 _fpclassf(float) +@ cdecl _fpieee_flt(long ptr ptr) +@ cdecl -stub _fpreset() +@ cdecl _fputc_nolock(long ptr) +@ cdecl _fputchar(long) +@ cdecl _fputwc_nolock(long ptr) +@ cdecl _fputwchar(long) +@ cdecl _fread_nolock(ptr long long ptr) +@ cdecl _fread_nolock_s(ptr long long long ptr) +@ cdecl _free_base(ptr) +@ cdecl -dbg _free_dbg(ptr long) +@ cdecl _free_locale(ptr) +@ cdecl _fseek_nolock(ptr long long) +@ cdecl _fseeki64(ptr int64 long) +@ cdecl _fseeki64_nolock(ptr int64 long) +@ cdecl _fsopen(str str long) +@ cdecl _fstat32(long ptr) +@ cdecl -arch=win32 -impsym _fstat(long ptr) _fstat32 +@ cdecl _fstat32i64(long ptr) +@ cdecl _fstat64(long ptr) +@ cdecl _fstat64i32(long ptr) +@ cdecl -arch=win64 -impsym _fstat(long ptr) _fstat64i32 +@ cdecl _ftell_nolock(ptr) +@ cdecl -ret64 _ftelli64(ptr) +@ cdecl -ret64 _ftelli64_nolock(ptr) +@ cdecl _ftime32(ptr) +@ cdecl -arch=win32 -impsym _ftime(ptr) _ftime32 +@ cdecl _ftime32_s(ptr) +@ cdecl _ftime64(ptr) +@ cdecl -arch=win64 -impsym _ftime(ptr) _ftime64 +@ cdecl _ftime64_s(ptr) +@ cdecl -arch=i386 -ret64 _ftol() +@ cdecl _fullpath(ptr str long) +@ cdecl -dbg _fullpath_dbg(ptr str long long str long) +@ cdecl _futime32(long ptr) +@ cdecl _futime64(long ptr) +@ cdecl _fwrite_nolock(ptr long long ptr) +@ cdecl _gcvt(double long str) +@ cdecl _gcvt_s(ptr long double long) +@ cdecl -stub -arch=win64 _get_FMA3_enable() +@ cdecl _get_current_locale() +@ cdecl _get_daylight(ptr) +@ cdecl _get_doserrno(ptr) +@ cdecl _get_dstbias(ptr) +@ cdecl _get_errno(ptr) +@ cdecl _get_fmode(ptr) +@ cdecl _get_heap_handle() +@ cdecl _get_initial_narrow_environment() +@ cdecl _get_initial_wide_environment() +@ cdecl _get_invalid_parameter_handler() +@ cdecl _get_narrow_winmain_command_line() +@ cdecl _get_osfhandle(long) +@ cdecl _get_pgmptr(ptr) +@ cdecl _get_printf_count_output() +@ cdecl -stub _get_purecall_handler() +@ cdecl _get_stream_buffer_pointers(ptr ptr ptr ptr) +@ cdecl _get_terminate() +@ cdecl _get_thread_local_invalid_parameter_handler() +@ cdecl _get_timezone(ptr) +@ cdecl _get_tzname(ptr str long long) +@ cdecl _get_unexpected() +@ cdecl _get_wide_winmain_command_line() +@ cdecl _get_wpgmptr(ptr) +@ cdecl _getc_nolock(ptr) _fgetc_nolock +@ cdecl _getch() +@ cdecl _getch_nolock() +@ cdecl _getche() +@ cdecl _getche_nolock() +@ cdecl _getcwd(ptr long) +@ cdecl -dbg _getcwd_dbg(ptr long long str long) +@ cdecl _getdcwd(long ptr long) +@ cdecl -dbg _getdcwd_dbg(long ptr long long str long) +@ cdecl _getdiskfree(long ptr) +@ cdecl _getdllprocaddr(long str long) +@ cdecl _getdrive() +@ cdecl _getdrives() +@ cdecl _getmaxstdio() +@ cdecl _getmbcp() +@ cdecl _getpid() +@ cdecl _getsystime(ptr) +@ cdecl _getw(ptr) +@ cdecl _getwc_nolock(ptr) +@ cdecl _getwch() +@ cdecl _getwch_nolock() +@ cdecl _getwche() +@ cdecl _getwche_nolock() +@ cdecl _getws(ptr) +@ cdecl _getws_s(ptr long) +@ cdecl -arch=i386 _global_unwind2(ptr) +@ cdecl _gmtime32(ptr) +@ cdecl _gmtime32_s(ptr ptr) +@ cdecl _gmtime64(ptr) +@ cdecl _gmtime64_s(ptr ptr) +@ cdecl _heapchk() +@ cdecl _heapmin() +@ cdecl _heapwalk(ptr) +@ cdecl _hypot(double double) +@ cdecl _hypotf(float float) +@ cdecl _i64toa(int64 ptr long) +@ cdecl _i64toa_s(int64 ptr long long) +@ cdecl _i64tow(int64 ptr long) +@ cdecl _i64tow_s(int64 ptr long long) +@ cdecl _initialize_narrow_environment() +@ cdecl _initialize_onexit_table(ptr) +@ cdecl _initialize_wide_environment() +@ cdecl _initterm(ptr ptr) +@ cdecl _initterm_e(ptr ptr) +@ cdecl _invalid_parameter(wstr wstr wstr long long) +@ cdecl _invalid_parameter_noinfo() +@ cdecl _invalid_parameter_noinfo_noreturn() +@ cdecl _invoke_watson(wstr wstr wstr long long) +@ cdecl _is_exception_typeof(ptr ptr) +@ cdecl _isalnum_l(long ptr) +@ cdecl _isalpha_l(long ptr) +@ cdecl _isatty(long) +@ cdecl _isblank_l(long ptr) +@ cdecl _iscntrl_l(long ptr) +@ cdecl _isctype(long long) +@ cdecl _isctype_l(long long ptr) +@ cdecl _isdigit_l(long ptr) +@ cdecl _isgraph_l(long ptr) +@ cdecl _isleadbyte_l(long ptr) +@ cdecl _islower_l(long ptr) +@ cdecl _ismbbalnum(long) +@ cdecl _ismbbalnum_l(long ptr) +@ cdecl _ismbbalpha(long) +@ cdecl _ismbbalpha_l(long ptr) +@ cdecl _ismbbblank(long) +@ cdecl _ismbbblank_l(long ptr) +@ cdecl _ismbbgraph(long) +@ cdecl _ismbbgraph_l(long ptr) +@ cdecl _ismbbkalnum(long) +@ cdecl _ismbbkalnum_l(long ptr) +@ cdecl _ismbbkana(long) +@ cdecl _ismbbkana_l(long ptr) +@ cdecl _ismbbkprint(long) +@ cdecl _ismbbkprint_l(long ptr) +@ cdecl _ismbbkpunct(long) +@ cdecl _ismbbkpunct_l(long ptr) +@ cdecl _ismbblead(long) +@ cdecl _ismbblead_l(long ptr) +@ cdecl _ismbbprint(long) +@ cdecl _ismbbprint_l(long ptr) +@ cdecl _ismbbpunct(long) +@ cdecl _ismbbpunct_l(long ptr) +@ cdecl _ismbbtrail(long) +@ cdecl _ismbbtrail_l(long ptr) +@ cdecl _ismbcalnum(long) +@ cdecl _ismbcalnum_l(long ptr) +@ cdecl _ismbcalpha(long) +@ cdecl _ismbcalpha_l(long ptr) +@ cdecl _ismbcblank(long) +@ cdecl _ismbcblank_l(long ptr) +@ cdecl _ismbcdigit(long) +@ cdecl _ismbcdigit_l(long ptr) +@ cdecl _ismbcgraph(long) +@ cdecl _ismbcgraph_l(long ptr) +@ cdecl _ismbchira(long) +@ cdecl _ismbchira_l(long ptr) +@ cdecl _ismbckata(long) +@ cdecl _ismbckata_l(long ptr) +@ cdecl _ismbcl0(long) +@ cdecl _ismbcl0_l(long ptr) +@ cdecl _ismbcl1(long) +@ cdecl _ismbcl1_l(long ptr) +@ cdecl _ismbcl2(long) +@ cdecl _ismbcl2_l(long ptr) +@ cdecl _ismbclegal(long) +@ cdecl _ismbclegal_l(long ptr) +@ cdecl _ismbclower(long) +@ cdecl _ismbclower_l(long ptr) +@ cdecl _ismbcprint(long) +@ cdecl _ismbcprint_l(long ptr) +@ cdecl _ismbcpunct(long) +@ cdecl _ismbcpunct_l(long ptr) +@ cdecl _ismbcspace(long) +@ cdecl _ismbcspace_l(long ptr) +@ cdecl _ismbcsymbol(long) +@ cdecl _ismbcsymbol_l(long ptr) +@ cdecl _ismbcupper(long) +@ cdecl _ismbcupper_l(long ptr) +@ cdecl _ismbslead(ptr ptr) +@ cdecl _ismbslead_l(ptr ptr ptr) +@ cdecl _ismbstrail(ptr ptr) +@ cdecl _ismbstrail_l(ptr ptr ptr) +@ cdecl _isnan(double) +@ cdecl -stub -arch=x86_64 _isnanf(float) +@ cdecl _isprint_l(long ptr) +@ cdecl _ispunct_l(long ptr) +@ cdecl _isspace_l(long ptr) +@ cdecl _isupper_l(long ptr) +@ cdecl _iswalnum_l(long ptr) +@ cdecl _iswalpha_l(long ptr) +@ cdecl _iswblank_l(long ptr) +@ cdecl _iswcntrl_l(long ptr) +@ cdecl _iswcsym_l(long ptr) +@ cdecl _iswcsymf_l(long ptr) +@ cdecl _iswctype_l(long long ptr) +@ cdecl _iswdigit_l(long ptr) +@ cdecl _iswgraph_l(long ptr) +@ cdecl _iswlower_l(long ptr) +@ cdecl _iswprint_l(long ptr) +@ cdecl _iswpunct_l(long ptr) +@ cdecl _iswspace_l(long ptr) +@ cdecl _iswupper_l(long ptr) +@ cdecl _iswxdigit_l(long ptr) +@ cdecl _isxdigit_l(long ptr) +@ cdecl _itoa(long ptr long) +@ cdecl _itoa_s(long ptr long long) +@ cdecl _itow(long ptr long) +@ cdecl _itow_s(long ptr long long) +@ cdecl _j0(double) +@ cdecl _j1(double) +@ cdecl _jn(long double) +@ cdecl _kbhit() +@ cdecl -stub _ld_int(ptr long) +@ cdecl _ldclass(double) _dclass +@ cdecl _ldexp(ptr double long) _dexp +@ cdecl _ldlog(double long) _dlog +@ cdecl _ldpcomp(double double) _dpcomp +@ cdecl _ldpoly(double ptr long) _dpoly +@ cdecl _ldscale(ptr long) _dscale +@ cdecl _ldsign(double) _dsign +@ cdecl _ldsin(double long) _dsin +@ cdecl _ldtest(ptr) _dtest +@ cdecl _ldunscale(ptr ptr) _dunscale +@ cdecl _lfind(ptr ptr ptr long ptr) +@ cdecl _lfind_s(ptr ptr ptr long ptr ptr) +@ cdecl -stub -arch=i386 -norelay _libm_sse2_acos_precise() #__libm_sse2_acos +@ cdecl -stub -arch=i386 -norelay _libm_sse2_asin_precise() #__libm_sse2_asin +@ cdecl -stub -arch=i386 -norelay _libm_sse2_atan_precise() #__libm_sse2_atan +@ cdecl -stub -arch=i386 -norelay _libm_sse2_cos_precise() #__libm_sse2_cos +@ cdecl -stub -arch=i386 -norelay _libm_sse2_exp_precise() #__libm_sse2_exp +@ cdecl -stub -arch=i386 -norelay _libm_sse2_log10_precise() #__libm_sse2_log10 +@ cdecl -stub -arch=i386 -norelay _libm_sse2_log_precise() #__libm_sse2_log +@ cdecl -stub -arch=i386 -norelay _libm_sse2_pow_precise() #__libm_sse2_pow +@ cdecl -stub -arch=i386 -norelay _libm_sse2_sin_precise() #__libm_sse2_sin +@ cdecl -stub -arch=i386 -norelay _libm_sse2_sqrt_precise() #__libm_sse2_sqrt +@ cdecl -stub -arch=i386 -norelay _libm_sse2_tan_precise() #__libm_sse2_tan +@ cdecl _loaddll(str) +@ cdecl -arch=win64 _local_unwind(ptr ptr) ntdll._local_unwind +@ cdecl -arch=i386 _local_unwind2(ptr long) +@ cdecl -arch=i386 _local_unwind4(ptr ptr long) +@ cdecl _localtime32(ptr) +@ cdecl _localtime32_s(ptr ptr) +@ cdecl _localtime64(ptr) +@ cdecl _localtime64_s(ptr ptr) +@ cdecl _lock_file(ptr) +@ cdecl _lock_locales() +@ cdecl _locking(long long long) +@ cdecl _logb(double) # logb +@ cdecl -arch=!i386 _logbf(float) logbf +@ cdecl -stub -arch=i386 _longjmpex(ptr long) +@ cdecl _lrotl(long long) +@ cdecl _lrotr(long long) +@ cdecl _lsearch(ptr ptr ptr long ptr) +@ cdecl _lsearch_s(ptr ptr ptr long ptr ptr) +@ cdecl _lseek(long long long) +@ cdecl -ret64 _lseeki64(long int64 long) +@ cdecl _ltoa(long ptr long) +@ cdecl _ltoa_s(long ptr long long) +@ cdecl _ltow(long ptr long) +@ cdecl _ltow_s(long ptr long long) +@ cdecl _makepath(ptr str str str str) +@ cdecl _makepath_s(ptr long str str str str) +@ cdecl _malloc_base(long) +@ cdecl -dbg _malloc_dbg(long long str long) +@ cdecl _mbbtombc(long) +@ cdecl _mbbtombc_l(long ptr) +@ cdecl _mbbtype(long long) +@ cdecl _mbbtype_l(long long ptr) +@ extern _mbcasemap +@ cdecl _mbccpy(ptr ptr) +@ cdecl _mbccpy_l(ptr ptr ptr) +@ cdecl _mbccpy_s(ptr long ptr ptr) +@ cdecl _mbccpy_s_l(ptr long ptr ptr ptr) +@ cdecl _mbcjistojms(long) +@ cdecl _mbcjistojms_l(long ptr) +@ cdecl _mbcjmstojis(long) +@ cdecl _mbcjmstojis_l(long ptr) +@ cdecl _mbclen(ptr) +@ cdecl _mbclen_l(ptr ptr) +@ cdecl _mbctohira(long) +@ cdecl _mbctohira_l(long ptr) +@ cdecl _mbctokata(long) +@ cdecl _mbctokata_l(long ptr) +@ cdecl _mbctolower(long) +@ cdecl _mbctolower_l(long ptr) +@ cdecl _mbctombb(long) +@ cdecl _mbctombb_l(long ptr) +@ cdecl _mbctoupper(long) +@ cdecl _mbctoupper_l(long ptr) +@ cdecl _mblen_l(str long ptr) +@ cdecl _mbsbtype(str long) +@ cdecl _mbsbtype_l(str long ptr) +@ cdecl _mbscat_s(ptr long str) +@ cdecl _mbscat_s_l(ptr long str ptr) +@ cdecl _mbschr(str long) +@ cdecl _mbschr_l(str long ptr) +@ cdecl _mbscmp(str str) +@ cdecl _mbscmp_l(str str ptr) +@ cdecl _mbscoll(str str) +@ cdecl _mbscoll_l(str str ptr) +@ cdecl _mbscpy_s(ptr long str) +@ cdecl _mbscpy_s_l(ptr long str ptr) +@ cdecl _mbscspn(str str) +@ cdecl _mbscspn_l(str str ptr) +@ cdecl _mbsdec(ptr ptr) +@ cdecl _mbsdec_l(ptr ptr ptr) +@ cdecl _mbsdup(str) _strdup +@ stub _mbsdup_dbg() # FIXME params +@ cdecl _mbsicmp(str str) +@ cdecl _mbsicmp_l(str str ptr) +@ cdecl _mbsicoll(str str) +@ cdecl _mbsicoll_l(str str ptr) +@ cdecl _mbsinc(str) +@ cdecl _mbsinc_l(str ptr) +@ cdecl _mbslen(str) +@ cdecl _mbslen_l(str ptr) +@ cdecl _mbslwr(str) +@ cdecl _mbslwr_l(str ptr) +@ cdecl _mbslwr_s(str long) +@ cdecl _mbslwr_s_l(str long ptr) +@ cdecl _mbsnbcat(str str long) +@ cdecl _mbsnbcat_l(str str long ptr) +@ cdecl _mbsnbcat_s(str long ptr long) +@ cdecl _mbsnbcat_s_l(str long ptr long ptr) +@ cdecl _mbsnbcmp(str str long) +@ cdecl _mbsnbcmp_l(str str long ptr) +@ cdecl _mbsnbcnt(ptr long) +@ cdecl _mbsnbcnt_l(ptr long ptr) +@ cdecl _mbsnbcoll(str str long) +@ cdecl _mbsnbcoll_l(str str long ptr) +@ cdecl _mbsnbcpy(ptr str long) +@ cdecl _mbsnbcpy_l(ptr str long ptr) +@ cdecl _mbsnbcpy_s(ptr long str long) +@ cdecl _mbsnbcpy_s_l(ptr long str long ptr) +@ cdecl _mbsnbicmp(str str long) +@ cdecl _mbsnbicmp_l(str str long ptr) +@ cdecl _mbsnbicoll(str str long) +@ cdecl _mbsnbicoll_l(str str long ptr) +@ cdecl _mbsnbset(ptr long long) +@ cdecl _mbsnbset_l(ptr long long ptr) +@ cdecl _mbsnbset_s(ptr long long long) +@ cdecl _mbsnbset_s_l(ptr long long long ptr) +@ cdecl _mbsncat(str str long) +@ cdecl _mbsncat_l(str str long ptr) +@ cdecl _mbsncat_s(ptr long str long) +@ cdecl _mbsncat_s_l(ptr long str long ptr) +@ cdecl _mbsnccnt(str long) +@ cdecl _mbsnccnt_l(str long ptr) +@ cdecl _mbsncmp(str str long) +@ cdecl _mbsncmp_l(str str long ptr) +@ cdecl _mbsncoll(str str long) +@ cdecl _mbsncoll_l(str str long ptr) +@ cdecl _mbsncpy(ptr str long) +@ cdecl _mbsncpy_l(ptr str long ptr) +@ cdecl _mbsncpy_s(ptr long str long) +@ cdecl _mbsncpy_s_l(ptr long str long ptr) +@ cdecl _mbsnextc(str) +@ cdecl _mbsnextc_l(str ptr) +@ cdecl _mbsnicmp(str str long) +@ cdecl _mbsnicmp_l(str str long ptr) +@ cdecl _mbsnicoll(str str long) +@ cdecl _mbsnicoll_l(str str long ptr) +@ cdecl _mbsninc(str long) +@ cdecl _mbsninc_l(str long ptr) +@ cdecl _mbsnlen(str long) +@ cdecl _mbsnlen_l(str long ptr) +@ cdecl _mbsnset(ptr long long) +@ cdecl _mbsnset_l(ptr long long ptr) +@ cdecl _mbsnset_s(ptr long long long) +@ cdecl _mbsnset_s_l(ptr long long long ptr) +@ cdecl _mbspbrk(str str) +@ cdecl _mbspbrk_l(str str ptr) +@ cdecl _mbsrchr(str long) +@ cdecl _mbsrchr_l(str long ptr) +@ cdecl _mbsrev(str) +@ cdecl _mbsrev_l(str ptr) +@ cdecl _mbsset(ptr long) +@ cdecl _mbsset_l(ptr long ptr) +@ cdecl _mbsset_s(ptr long long) +@ cdecl _mbsset_s_l(ptr long long ptr) +@ cdecl _mbsspn(str str) +@ cdecl _mbsspn_l(str str ptr) +@ cdecl _mbsspnp(str str) +@ cdecl _mbsspnp_l(str str ptr) +@ cdecl _mbsstr(str str) +@ cdecl _mbsstr_l(str str ptr) +@ cdecl _mbstok(str str) +@ cdecl _mbstok_l(str str ptr) +@ cdecl _mbstok_s(str str ptr) +@ cdecl _mbstok_s_l(str str ptr ptr) +@ cdecl _mbstowcs_l(ptr str long ptr) +@ cdecl _mbstowcs_s_l(ptr ptr long str long ptr) +@ cdecl _mbstrlen(str) +@ cdecl _mbstrlen_l(str ptr) +@ cdecl _mbstrnlen(str long) +@ cdecl _mbstrnlen_l(str long ptr) +@ cdecl _mbsupr(str) +@ cdecl _mbsupr_l(str ptr) +@ cdecl _mbsupr_s(str long) +@ cdecl _mbsupr_s_l(str long ptr) +@ cdecl _mbtowc_l(ptr str long ptr) +@ cdecl _memccpy(ptr ptr long long) +@ cdecl _memicmp(str str long) +@ cdecl _memicmp_l(str str long ptr) +@ cdecl _mkdir(str) +@ cdecl _mkgmtime32(ptr) +@ cdecl _mkgmtime64(ptr) +@ cdecl _mktemp(str) +@ cdecl _mktemp_s(str long) +@ cdecl _mktime32(ptr) +@ cdecl _mktime64(ptr) +@ cdecl _msize(ptr) +@ cdecl -dbg _msize_dbg(ptr long) +@ cdecl _nextafter(double double) nextafter +@ cdecl -arch=x86_64 _nextafterf(float float) nextafterf +@ cdecl -arch=i386 _o__CIacos() _CIacos +@ cdecl -arch=i386 _o__CIasin() _CIasin +@ cdecl -arch=i386 _o__CIatan() _CIatan +@ cdecl -arch=i386 _o__CIatan2() _CIatan2 +@ cdecl -arch=i386 _o__CIcos() _CIcos +@ cdecl -arch=i386 _o__CIcosh() _CIcosh +@ cdecl -arch=i386 _o__CIexp() _CIexp +@ cdecl -arch=i386 _o__CIfmod() _CIfmod +@ cdecl -arch=i386 _o__CIlog() _CIlog +@ cdecl -arch=i386 _o__CIlog10() _CIlog10 +@ cdecl -arch=i386 _o__CIpow() _CIpow +@ cdecl -arch=i386 _o__CIsin() _CIsin +@ cdecl -arch=i386 _o__CIsinh() _CIsinh +@ cdecl -arch=i386 _o__CIsqrt() _CIsqrt +@ cdecl -arch=i386 _o__CItan() _CItan +@ cdecl -arch=i386 _o__CItanh() _CItanh +@ cdecl _o__Getdays() _Getdays +@ cdecl _o__Getmonths() _Getmonths +@ cdecl _o__Gettnames() _Gettnames +@ cdecl _o__Strftime(ptr long str ptr ptr) _Strftime +@ cdecl _o__W_Getdays() _W_Getdays +@ cdecl _o__W_Getmonths() _W_Getmonths +@ cdecl _o__W_Gettnames() _W_Gettnames +@ cdecl _o__Wcsftime(ptr long wstr ptr ptr) _Wcsftime +@ cdecl _o____lc_codepage_func() ___lc_codepage_func +@ cdecl _o____lc_collate_cp_func() ___lc_collate_cp_func +@ cdecl _o____lc_locale_name_func() ___lc_locale_name_func +@ cdecl _o____mb_cur_max_func() ___mb_cur_max_func +@ cdecl _o___acrt_iob_func(long) __acrt_iob_func +@ cdecl _o___conio_common_vcprintf(int64 str ptr ptr) __conio_common_vcprintf +@ cdecl _o___conio_common_vcprintf_p() __conio_common_vcprintf_p # FIXME: params +@ cdecl _o___conio_common_vcprintf_s() __conio_common_vcprintf_s # FIXME: params +@ cdecl _o___conio_common_vcscanf() __conio_common_vcscanf # FIXME: params +@ cdecl _o___conio_common_vcwprintf(int64 wstr ptr ptr) __conio_common_vcwprintf +@ cdecl _o___conio_common_vcwprintf_p() __conio_common_vcwprintf_p # FIXME: params +@ cdecl _o___conio_common_vcwprintf_s() __conio_common_vcwprintf_s # FIXME: params +@ cdecl _o___conio_common_vcwscanf() __conio_common_vcwscanf # FIXME: params +@ cdecl _o___daylight() __daylight +@ cdecl _o___dstbias() __dstbias +@ cdecl _o___fpe_flt_rounds() __fpe_flt_rounds +@ cdecl -arch=i386 -norelay _o___libm_sse2_acos() __libm_sse2_acos +@ cdecl -arch=i386 -norelay _o___libm_sse2_acosf() __libm_sse2_acosf +@ cdecl -arch=i386 -norelay _o___libm_sse2_asin() __libm_sse2_asin +@ cdecl -arch=i386 -norelay _o___libm_sse2_asinf() __libm_sse2_asinf +@ cdecl -arch=i386 -norelay _o___libm_sse2_atan() __libm_sse2_atan +@ cdecl -arch=i386 -norelay _o___libm_sse2_atan2() __libm_sse2_atan2 +@ cdecl -arch=i386 -norelay _o___libm_sse2_atanf() __libm_sse2_atanf +@ cdecl -arch=i386 -norelay _o___libm_sse2_cos() __libm_sse2_cos +@ cdecl -arch=i386 -norelay _o___libm_sse2_cosf() __libm_sse2_cosf +@ cdecl -arch=i386 -norelay _o___libm_sse2_exp() __libm_sse2_exp +@ cdecl -arch=i386 -norelay _o___libm_sse2_expf() __libm_sse2_expf +@ cdecl -arch=i386 -norelay _o___libm_sse2_log() __libm_sse2_log +@ cdecl -arch=i386 -norelay _o___libm_sse2_log10() __libm_sse2_log10 +@ cdecl -arch=i386 -norelay _o___libm_sse2_log10f() __libm_sse2_log10f +@ cdecl -arch=i386 -norelay _o___libm_sse2_logf() __libm_sse2_logf +@ cdecl -arch=i386 -norelay _o___libm_sse2_pow() __libm_sse2_pow +@ cdecl -arch=i386 -norelay _o___libm_sse2_powf() __libm_sse2_powf +@ cdecl -arch=i386 -norelay _o___libm_sse2_sin() __libm_sse2_sin +@ cdecl -arch=i386 -norelay _o___libm_sse2_sinf() __libm_sse2_sinf +@ cdecl -arch=i386 -norelay _o___libm_sse2_tan() __libm_sse2_tan +@ cdecl -arch=i386 -norelay _o___libm_sse2_tanf() __libm_sse2_tanf +@ cdecl _o___p___argc() __p___argc +@ cdecl _o___p___argv() __p___argv +@ cdecl _o___p___wargv() __p___wargv +@ cdecl _o___p__acmdln() __p__acmdln +@ cdecl _o___p__commode() __p__commode +@ cdecl _o___p__environ() __p__environ +@ cdecl _o___p__fmode() __p__fmode +@ cdecl _o___p__mbcasemap() __p__mbcasemap # FIXME: params +@ cdecl _o___p__mbctype() __p__mbctype +@ cdecl _o___p__pgmptr() __p__pgmptr +@ cdecl _o___p__wcmdln() __p__wcmdln +@ cdecl _o___p__wenviron() __p__wenviron +@ cdecl _o___p__wpgmptr() __p__wpgmptr +@ cdecl _o___pctype_func() __pctype_func +@ cdecl _o___pwctype_func() __pwctype_func # FIXME: params +@ cdecl _o___std_exception_copy(ptr ptr) __std_exception_copy +@ cdecl _o___std_exception_destroy(ptr) __std_exception_destroy +@ cdecl _o___std_type_info_destroy_list(ptr) __std_type_info_destroy_list +@ cdecl _o___std_type_info_name(ptr ptr) __std_type_info_name +@ cdecl _o___stdio_common_vfprintf(int64 ptr str ptr ptr) __stdio_common_vfprintf +@ cdecl _o___stdio_common_vfprintf_p(int64 ptr str ptr ptr) __stdio_common_vfprintf_p +@ cdecl _o___stdio_common_vfprintf_s(int64 ptr str ptr ptr) __stdio_common_vfprintf_s +@ cdecl _o___stdio_common_vfscanf(int64 ptr str ptr ptr) __stdio_common_vfscanf +@ cdecl _o___stdio_common_vfwprintf(int64 ptr wstr ptr ptr) __stdio_common_vfwprintf +@ cdecl _o___stdio_common_vfwprintf_p(int64 ptr wstr ptr ptr) __stdio_common_vfwprintf_p +@ cdecl _o___stdio_common_vfwprintf_s(int64 ptr wstr ptr ptr) __stdio_common_vfwprintf_s +@ cdecl _o___stdio_common_vfwscanf(int64 ptr wstr ptr ptr) __stdio_common_vfwscanf +@ cdecl _o___stdio_common_vsnprintf_s(int64 ptr long long str ptr ptr) __stdio_common_vsnprintf_s +@ cdecl _o___stdio_common_vsnwprintf_s(int64 ptr long long wstr ptr ptr) __stdio_common_vsnwprintf_s +@ cdecl _o___stdio_common_vsprintf(int64 ptr long str ptr ptr) __stdio_common_vsprintf +@ cdecl _o___stdio_common_vsprintf_p(int64 ptr long str ptr ptr) __stdio_common_vsprintf_p +@ cdecl _o___stdio_common_vsprintf_s(int64 ptr long str ptr ptr) __stdio_common_vsprintf_s +@ cdecl _o___stdio_common_vsscanf(int64 ptr long str ptr ptr) __stdio_common_vsscanf +@ cdecl _o___stdio_common_vswprintf(int64 ptr long wstr ptr ptr) __stdio_common_vswprintf +@ cdecl _o___stdio_common_vswprintf_p(int64 ptr long wstr ptr ptr) __stdio_common_vswprintf_p +@ cdecl _o___stdio_common_vswprintf_s(int64 ptr long wstr ptr ptr) __stdio_common_vswprintf_s +@ cdecl _o___stdio_common_vswscanf(int64 ptr long wstr ptr ptr) __stdio_common_vswscanf +@ cdecl _o___timezone() __timezone +@ cdecl _o___tzname() __tzname +@ cdecl _o___wcserror(wstr) __wcserror +@ cdecl _o__access(str long) _access +@ cdecl _o__access_s(str long) _access_s +@ cdecl _o__aligned_free(ptr) _aligned_free +@ cdecl _o__aligned_malloc(long long) _aligned_malloc +@ cdecl _o__aligned_msize(ptr long long) _aligned_msize +@ cdecl _o__aligned_offset_malloc(long long long) _aligned_offset_malloc +@ cdecl _o__aligned_offset_realloc(ptr long long long) _aligned_offset_realloc +@ cdecl _o__aligned_offset_recalloc() _aligned_offset_recalloc # FIXME: params +@ cdecl _o__aligned_realloc(ptr long long) _aligned_realloc +@ cdecl _o__aligned_recalloc() _aligned_recalloc # FIXME: params +@ cdecl _o__atodbl(ptr str) _atodbl +@ cdecl _o__atodbl_l(ptr str ptr) _atodbl_l +@ cdecl _o__atof_l(str ptr) _atof_l +@ cdecl _o__atoflt(ptr str) _atoflt +@ cdecl _o__atoflt_l(ptr str ptr) _atoflt_l +@ cdecl -ret64 _o__atoi64(str) _atoi64 +@ cdecl -ret64 _o__atoi64_l(str ptr) _atoi64_l +@ cdecl _o__atoi_l(str ptr) _atoi_l +@ cdecl _o__atol_l(str ptr) _atol_l +@ cdecl _o__atoldbl(ptr str) _atoldbl +@ cdecl _o__atoldbl_l(ptr str ptr) _atoldbl_l +@ cdecl -ret64 _o__atoll_l(str ptr) _atoll_l +@ cdecl _o__beep(long long) _beep +@ cdecl _o__beginthread(ptr long ptr) _beginthread +@ cdecl _o__beginthreadex(ptr long ptr ptr long ptr) _beginthreadex +@ cdecl _o__cabs(long) _cabs +@ cdecl _o__callnewh(long) _callnewh +@ cdecl _o__calloc_base(long long) _calloc_base +@ cdecl _o__cexit() _cexit +@ cdecl _o__cgets(ptr) _cgets +@ cdecl _o__cgets_s() _cgets_s # FIXME: params +@ cdecl _o__cgetws() _cgetws # FIXME: params +@ cdecl _o__cgetws_s() _cgetws_s # FIXME: params +@ cdecl _o__chdir(str) _chdir +@ cdecl _o__chdrive(long) _chdrive +@ cdecl _o__chmod(str long) _chmod +@ cdecl _o__chsize(long long) _chsize +@ cdecl _o__chsize_s(long int64) _chsize_s +@ cdecl _o__close(long) _close +@ cdecl _o__commit(long) _commit +@ cdecl _o__configthreadlocale(long) _configthreadlocale +@ cdecl _o__configure_narrow_argv(long) _configure_narrow_argv +@ cdecl _o__configure_wide_argv(long) _configure_wide_argv +@ cdecl _o__controlfp_s(ptr long long) _controlfp_s +@ cdecl _o__cputs(str) _cputs +@ cdecl _o__cputws(wstr) _cputws +@ cdecl _o__creat(str long) _creat +@ cdecl _o__create_locale(long str) _create_locale +@ cdecl _o__crt_atexit(ptr) _crt_atexit +@ cdecl _o__ctime32_s(str long ptr) _ctime32_s +@ cdecl _o__ctime64_s(str long ptr) _ctime64_s +@ cdecl _o__cwait(ptr long long) _cwait +@ cdecl _o__d_int(ptr long) _d_int +@ cdecl _o__dclass(double) _dclass +@ cdecl _o__difftime32(long long) _difftime32 +@ cdecl _o__difftime64(int64 int64) _difftime64 +@ cdecl _o__dlog(double long) _dlog +@ cdecl _o__dnorm(ptr) _dnorm +@ cdecl _o__dpcomp(double double) _dpcomp +@ cdecl _o__dpoly(double ptr long) _dpoly +@ cdecl _o__dscale(ptr long) _dscale +@ cdecl _o__dsign(double) _dsign +@ cdecl _o__dsin(double long) _dsin +@ cdecl _o__dtest(ptr) _dtest +@ cdecl _o__dunscalee(ptr ptr) _dunscale +@ cdecl _o__dup(long) _dup +@ cdecl _o__dup2(long long) _dup2 +@ cdecl _o__dupenv_s(ptr ptr str) _dupenv_s +@ cdecl _o__ecvt(double long ptr ptr) _ecvt +@ cdecl _o__ecvt_s(str long double long ptr ptr) _ecvt_s +@ cdecl _o__endthread() _endthread +@ cdecl _o__endthreadex(long) _endthreadex +@ cdecl _o__eof(long) _eof +@ cdecl _o__errno() _errno +@ cdecl _o__except1(long long double double long ptr) _except1 +@ cdecl _o__execute_onexit_table(ptr) _execute_onexit_table +@ cdecl _o__execv(str ptr) _execv +@ cdecl _o__execve(str ptr ptr) _execve +@ cdecl _o__execvp(str ptr) _execvp +@ cdecl _o__execvpe(str ptr ptr) _execvpe +@ cdecl _o__exit(long) _exit +@ cdecl _o__expand(ptr long) _expand +@ cdecl _o__fclose_nolock(ptr) _fclose_nolock +@ cdecl _o__fcloseall() _fcloseall +@ cdecl _o__fcvt(double long ptr ptr) _fcvt +@ cdecl _o__fcvt_s(ptr long double long ptr ptr) _fcvt_s +@ cdecl _o__fd_int(ptr long) _fd_int +@ cdecl _o__fdclass(float) _fdclass +@ cdecl _o__fdexp(ptr float long) _fdexp +@ cdecl _o__fdlog(float long) _fdlog +@ cdecl _o__fdopen(long str) _fdopen +@ cdecl _o__fdpcomp(float float) _fdpcomp +@ cdecl _o__fdpoly(float ptr long) _fdpoly +@ cdecl _o__fdscale(ptr long) _fdscale +@ cdecl _o__fdsign(float) _fdsign +@ cdecl _o__fdsin(float long) _fdsin +@ cdecl _o__fflush_nolock(ptr) _fflush_nolock +@ cdecl _o__fgetc_nolock(ptr) _fgetc_nolock +@ cdecl _o__fgetchar() _fgetchar +@ cdecl _o__fgetwc_nolock(ptr) _fgetwc_nolock +@ cdecl _o__fgetwchar() _fgetwchar +@ cdecl _o__filelength(long) _filelength +@ cdecl -ret64 _o__filelengthi64(long) _filelengthi64 +@ cdecl _o__fileno(ptr) _fileno +@ cdecl _o__findclose(long) _findclose +@ cdecl _o__findfirst32(str ptr) _findfirst32 +@ cdecl _o__findfirst32i64() _findfirst32i64 # FIXME: params +@ cdecl _o__findfirst64(str ptr) _findfirst64 +@ cdecl _o__findfirst64i32(str ptr) _findfirst64i32 +@ cdecl _o__findnext32(long ptr) _findnext32 +@ cdecl _o__findnext32i64() _findnext32i64 # FIXME: params +@ cdecl _o__findnext64(long ptr) _findnext64 +@ cdecl _o__findnext64i32(long ptr) _findnext64i32 +@ cdecl _o__flushall() _flushall +@ cdecl _o__fpclass(double) _fpclass +@ cdecl -arch=!i386 _o__fpclassf(float) _fpclassf +@ cdecl _o__fputc_nolock(long ptr) _fputc_nolock +@ cdecl _o__fputchar(long) _fputchar +@ cdecl _o__fputwc_nolock(long ptr) _fputwc_nolock +@ cdecl _o__fputwchar(long) _fputwchar +@ cdecl _o__fread_nolock(ptr long long ptr) _fread_nolock +@ cdecl _o__fread_nolock_s(ptr long long long ptr) _fread_nolock_s +@ cdecl _o__free_base(ptr) _free_base +@ cdecl _o__free_locale(ptr) _free_locale +@ cdecl _o__fseek_nolock(ptr long long) _fseek_nolock +@ cdecl _o__fseeki64(ptr int64 long) _fseeki64 +@ cdecl _o__fseeki64_nolock(ptr int64 long) _fseeki64_nolock +@ cdecl _o__fsopen(str str long) _fsopen +@ cdecl _o__fstat32(long ptr) _fstat32 +@ cdecl _o__fstat32i64(long ptr) _fstat32i64 +@ cdecl _o__fstat64(long ptr) _fstat64 +@ cdecl _o__fstat64i32(long ptr) _fstat64i32 +@ cdecl _o__ftell_nolock(ptr) _ftell_nolock +@ cdecl -ret64 _o__ftelli64(ptr) _ftelli64 +@ cdecl -ret64 _o__ftelli64_nolock(ptr) _ftelli64_nolock +@ cdecl _o__ftime32(ptr) _ftime32 +@ cdecl _o__ftime32_s(ptr) _ftime32_s +@ cdecl _o__ftime64(ptr) _ftime64 +@ cdecl _o__ftime64_s(ptr) _ftime64_s +@ cdecl _o__fullpath(ptr str long) _fullpath +@ cdecl _o__futime32(long ptr) _futime32 +@ cdecl _o__futime64(long ptr) _futime64 +@ cdecl _o__fwrite_nolock(ptr long long ptr) _fwrite_nolock +@ cdecl _o__gcvt(double long str) _gcvt +@ cdecl _o__gcvt_s(ptr long double long) _gcvt_s +@ cdecl _o__get_daylight(ptr) _get_daylight +@ cdecl _o__get_doserrno(ptr) _get_doserrno +@ cdecl _o__get_dstbias(ptr) _get_dstbias +@ cdecl _o__get_errno(ptr) _get_errno +@ cdecl _o__get_fmode(ptr) _get_fmode +@ cdecl _o__get_heap_handle() _get_heap_handle +@ cdecl _o__get_initial_narrow_environment() _get_initial_narrow_environment +@ cdecl _o__get_initial_wide_environment() _get_initial_wide_environment +@ cdecl _o__get_invalid_parameter_handler() _get_invalid_parameter_handler +@ cdecl _o__get_narrow_winmain_command_line() _get_narrow_winmain_command_line +@ cdecl _o__get_osfhandle(long) _get_osfhandle +@ cdecl _o__get_pgmptr(ptr) _get_pgmptr +@ cdecl _o__get_stream_buffer_pointers(ptr ptr ptr ptr) _get_stream_buffer_pointers +@ cdecl _o__get_terminate() _get_terminate +@ cdecl _o__get_thread_local_invalid_parameter_handler() _get_thread_local_invalid_parameter_handler +@ cdecl _o__get_timezone(ptr) _get_timezone +@ cdecl _o__get_tzname(ptr str long long) _get_tzname +@ cdecl _o__get_wide_winmain_command_line() _get_wide_winmain_command_line +@ cdecl _o__get_wpgmptr(ptr) _get_wpgmptr +@ cdecl _o__getc_nolock(ptr) _fgetc_nolock +@ cdecl _o__getch() _getch +@ cdecl _o__getch_nolock() _getch_nolock +@ cdecl _o__getche() _getche +@ cdecl _o__getche_nolock() _getche_nolock +@ cdecl _o__getcwd(str long) _getcwd +@ cdecl _o__getdcwd(long str long) _getdcwd +@ cdecl _o__getdiskfree(long ptr) _getdiskfree +@ cdecl _o__getdllprocaddr(long str long) _getdllprocaddr +@ cdecl _o__getdrive() _getdrive +@ cdecl _o__getdrives() _getdrives # kernel32.GetLogicalDrives +@ cdecl _o__getmbcp() _getmbcp +@ cdecl _o__getsystime() _getsystime # FIXME: params +@ cdecl _o__getw(ptr) _getw +@ cdecl _o__getwc_nolock(ptr) _fgetwc_nolock +@ cdecl _o__getwch() _getwch +@ cdecl _o__getwch_nolock() _getwch_nolock +@ cdecl _o__getwche() _getwche +@ cdecl _o__getwche_nolock() _getwche_nolock +@ cdecl _o__getws(ptr) _getws +@ cdecl _o__getws_s() _getws_s # FIXME: params +@ cdecl _o__gmtime32(ptr) _gmtime32 +@ cdecl _o__gmtime32_s(ptr ptr) _gmtime32_s +@ cdecl _o__gmtime64(ptr) _gmtime64 +@ cdecl _o__gmtime64_s(ptr ptr) _gmtime64_s +@ cdecl _o__heapchk() _heapchk +@ cdecl _o__heapmin() _heapmin +@ cdecl _o__hypot(double double) _hypot +@ cdecl _o__hypotf(float float) _hypotf +@ cdecl _o__i64toa(int64 ptr long) _i64toa +@ cdecl _o__i64toa_s(int64 ptr long long) _i64toa_s +@ cdecl _o__i64tow(int64 ptr long) _i64tow +@ cdecl _o__i64tow_s(int64 ptr long long) _i64tow_s +@ cdecl _o__initialize_narrow_environment() _initialize_narrow_environment +@ cdecl _o__initialize_onexit_table(ptr) _initialize_onexit_table +@ cdecl _o__initialize_wide_environment() _initialize_wide_environment +@ cdecl _o__invalid_parameter_noinfo() _invalid_parameter_noinfo +@ cdecl _o__invalid_parameter_noinfo_noreturn() _invalid_parameter_noinfo_noreturn +@ cdecl _o__isatty(long) _isatty +@ cdecl _o__isctype(long long) _isctype +@ cdecl _o__isctype_l(long long ptr) _isctype_l +@ cdecl _o__isleadbyte_l(long ptr) _isleadbyte_l +@ cdecl _o__ismbbalnum() _ismbbalnum # FIXME: params +@ cdecl _o__ismbbalnum_l() _ismbbalnum_l # FIXME: params +@ cdecl _o__ismbbalpha() _ismbbalpha # FIXME: params +@ cdecl _o__ismbbalpha_l() _ismbbalpha_l # FIXME: params +@ cdecl _o__ismbbblank() _ismbbblank # FIXME: params +@ cdecl _o__ismbbblank_l() _ismbbblank_l # FIXME: params +@ cdecl _o__ismbbgraph() _ismbbgraph # FIXME: params +@ cdecl _o__ismbbgraph_l() _ismbbgraph_l # FIXME: params +@ cdecl _o__ismbbkalnum() _ismbbkalnum # FIXME: params +@ cdecl _o__ismbbkalnum_l() _ismbbkalnum_l # FIXME: params +@ cdecl _o__ismbbkana(long) _ismbbkana +@ cdecl _o__ismbbkana_l(long ptr) _ismbbkana_l +@ cdecl _o__ismbbkprint() _ismbbkprint # FIXME: params +@ cdecl _o__ismbbkprint_l() _ismbbkprint_l # FIXME: params +@ cdecl _o__ismbbkpunct() _ismbbkpunct # FIXME: params +@ cdecl _o__ismbbkpunct_l() _ismbbkpunct_l # FIXME: params +@ cdecl _o__ismbblead(long) _ismbblead +@ cdecl _o__ismbblead_l(long ptr) _ismbblead_l +@ cdecl _o__ismbbprint() _ismbbprint # FIXME: params +@ cdecl _o__ismbbprint_l() _ismbbprint_l # FIXME: params +@ cdecl _o__ismbbpunct() _ismbbpunct # FIXME: params +@ cdecl _o__ismbbpunct_l() _ismbbpunct_l # FIXME: params +@ cdecl _o__ismbbtrail(long) _ismbbtrail +@ cdecl _o__ismbbtrail_l(long ptr) _ismbbtrail_l +@ cdecl _o__ismbcalnum(long) _ismbcalnum +@ cdecl _o__ismbcalnum_l(long ptr) _ismbcalnum_l +@ cdecl _o__ismbcalpha(long) _ismbcalpha +@ cdecl _o__ismbcalpha_l(long ptr) _ismbcalpha_l +@ cdecl _o__ismbcblank() _ismbcblank # FIXME: params +@ cdecl _o__ismbcblank_l() _ismbcblank_l # FIXME: params +@ cdecl _o__ismbcdigit(long) _ismbcdigit +@ cdecl _o__ismbcdigit_l(long ptr) _ismbcdigit_l +@ cdecl _o__ismbcgraph(long) _ismbcgraph +@ cdecl _o__ismbcgraph_l(long ptr) _ismbcgraph_l +@ cdecl _o__ismbchira(long) _ismbchira +@ cdecl _o__ismbchira_l(long ptr) _ismbchira_l +@ cdecl _o__ismbckata(long) _ismbckata +@ cdecl _o__ismbckata_l(long ptr) _ismbckata_l +@ cdecl _o__ismbcl0(long) _ismbcl0 +@ cdecl _o__ismbcl0_l(long ptr) _ismbcl0_l +@ cdecl _o__ismbcl1(long) _ismbcl1 +@ cdecl _o__ismbcl1_l(long ptr) _ismbcl1_l +@ cdecl _o__ismbcl2(long) _ismbcl2 +@ cdecl _o__ismbcl2_l(long ptr) _ismbcl2_l +@ cdecl _o__ismbclegal(long) _ismbclegal +@ cdecl _o__ismbclegal_l(long ptr) _ismbclegal_l +@ cdecl _o__ismbclower() _ismbclower # FIXME: params +@ cdecl _o__ismbclower_l(long ptr) _ismbclower_l +@ cdecl _o__ismbcprint(long) _ismbcprint +@ cdecl _o__ismbcprint_l(long ptr) _ismbcprint_l +@ cdecl _o__ismbcpunct(long) _ismbcpunct +@ cdecl _o__ismbcpunct_l(long ptr) _ismbcpunct_l +@ cdecl _o__ismbcspace(long) _ismbcspace +@ cdecl _o__ismbcspace_l(long ptr) _ismbcspace_l +@ cdecl _o__ismbcsymbol(long) _ismbcsymbol +@ cdecl _o__ismbcsymbol_l(long ptr) _ismbcsymbol_l +@ cdecl _o__ismbcupper(long) _ismbcupper +@ cdecl _o__ismbcupper_l(long ptr) _ismbcupper_l +@ cdecl _o__ismbslead(ptr ptr) _ismbslead +@ cdecl _o__ismbslead_l(ptr ptr ptr) _ismbslead_l +@ cdecl _o__ismbstrail(ptr ptr) _ismbstrail +@ cdecl _o__ismbstrail_l(ptr ptr ptr) _ismbstrail_l +@ cdecl _o__iswctype_l(long long ptr) _iswctype_l +@ cdecl _o__itoa(long ptr long) _itoa +@ cdecl _o__itoa_s(long ptr long long) _itoa_s +@ cdecl _o__itow(long ptr long) _itow +@ cdecl _o__itow_s(long ptr long long) _itow_s +@ cdecl _o__j0(double) _j0 +@ cdecl _o__j1(double) _j1 +@ cdecl _o__jn(long double) _jn +@ cdecl _o__kbhit() _kbhit +@ cdecl _o__ld_int(ptr long) _ld_int +@ cdecl _o__ldclass(double) _dclass +@ cdecl _o__ldexp(ptr double long) _dexp +@ cdecl _o__ldlog(double long) _dlog +@ cdecl _o__ldpcomp(double double) _dpcomp +@ cdecl _o__ldpoly(double ptr long) _dpoly +@ cdecl _o__ldscale(ptr long) _dscale +@ cdecl _o__ldsign(double) _dsign +@ cdecl _o__ldsin(double long) _dsin +@ cdecl _o__ldtest(ptr) _dtest +@ cdecl _o__ldunscale(ptr ptr) _dunscale +@ cdecl _o__lfind(ptr ptr ptr long ptr) _lfind +@ cdecl _o__lfind_s(ptr ptr ptr long ptr ptr) _lfind_s +@ cdecl -arch=i386 -norelay _o__libm_sse2_acos_precise() _libm_sse2_acos_precise +@ cdecl -arch=i386 -norelay _o__libm_sse2_asin_precise() _libm_sse2_asin_precise +@ cdecl -arch=i386 -norelay _o__libm_sse2_atan_precise() _libm_sse2_atan_precise +@ cdecl -arch=i386 -norelay _o__libm_sse2_cos_precise() _libm_sse2_cos_precise +@ cdecl -arch=i386 -norelay _o__libm_sse2_exp_precise() _libm_sse2_exp_precise +@ cdecl -arch=i386 -norelay _o__libm_sse2_log10_precise() _libm_sse2_log10_precise +@ cdecl -arch=i386 -norelay _o__libm_sse2_log_precise() _libm_sse2_log_precise +@ cdecl -arch=i386 -norelay _o__libm_sse2_pow_precise() _libm_sse2_pow_precise +@ cdecl -arch=i386 -norelay _o__libm_sse2_sin_precise() _libm_sse2_sin_precise +@ cdecl -arch=i386 -norelay _o__libm_sse2_sqrt_precise() _libm_sse2_sqrt_precise +@ cdecl -arch=i386 -norelay _o__libm_sse2_tan_precise() _libm_sse2_tan_precise +@ cdecl _o__loaddll(str) _loaddll +@ cdecl _o__localtime32(ptr) _localtime32 +@ cdecl _o__localtime32_s(ptr ptr) _localtime32_s +@ cdecl _o__localtime64(ptr) _localtime64 +@ cdecl _o__localtime64_s(ptr ptr) _localtime64_s +@ cdecl _o__lock_file(ptr) _lock_file +@ cdecl _o__locking(long long long) _locking +@ cdecl _o__logb(double) logb +@ cdecl -arch=!i386 _o__logbf(float) logbf +@ cdecl _o__lsearch(ptr ptr ptr long ptr) _lsearch +@ cdecl _o__lsearch_s() _lsearch_s # FIXME: params +@ cdecl _o__lseek(long long long) _lseek +@ cdecl -ret64 _o__lseeki64(long int64 long) _lseeki64 +@ cdecl _o__ltoa(long ptr long) _ltoa +@ cdecl _o__ltoa_s(long ptr long long) _ltoa_s +@ cdecl _o__ltow(long ptr long) _ltow +@ cdecl _o__ltow_s(long ptr long long) _ltow_s +@ cdecl _o__makepath(ptr str str str str) _makepath +@ cdecl _o__makepath_s(ptr long str str str str) _makepath_s +@ cdecl _o__malloc_base(long) _malloc_base +@ cdecl _o__mbbtombc(long) _mbbtombc +@ cdecl _o__mbbtombc_l(long ptr) _mbbtombc_l +@ cdecl _o__mbbtype(long long) _mbbtype +@ cdecl _o__mbbtype_l(long long ptr) _mbbtype_l +@ cdecl _o__mbccpy(ptr ptr) _mbccpy +@ cdecl _o__mbccpy_l(ptr ptr ptr) _mbccpy_l +@ cdecl _o__mbccpy_s(ptr long ptr ptr) _mbccpy_s +@ cdecl _o__mbccpy_s_l(ptr long ptr ptr ptr) _mbccpy_s_l +@ cdecl _o__mbcjistojms(long) _mbcjistojms +@ cdecl _o__mbcjistojms_l(long ptr) _mbcjistojms_l +@ cdecl _o__mbcjmstojis(long) _mbcjmstojis +@ cdecl _o__mbcjmstojis_l(long ptr) _mbcjmstojis_l +@ cdecl _o__mbclen(ptr) _mbclen +@ cdecl _o__mbclen_l(ptr ptr) _mbclen_l +@ cdecl _o__mbctohira(long) _mbctohira +@ cdecl _o__mbctohira_l(long ptr) _mbctohira_l +@ cdecl _o__mbctokata(long) _mbctokata +@ cdecl _o__mbctokata_l(long ptr) _mbctokata_l +@ cdecl _o__mbctolower(long) _mbctolower +@ cdecl _o__mbctolower_l(long ptr) _mbctolower_l +@ cdecl _o__mbctombb(long) _mbctombb +@ cdecl _o__mbctombb_l(long ptr) _mbctombb_l +@ cdecl _o__mbctoupper(long) _mbctoupper +@ cdecl _o__mbctoupper_l(long ptr) _mbctoupper_l +@ cdecl _o__mblen_l(str long ptr) _mblen_l +@ cdecl _o__mbsbtype(str long) _mbsbtype +@ cdecl _o__mbsbtype_l(str long ptr) _mbsbtype_l +@ cdecl _o__mbscat_s(ptr long str) _mbscat_s +@ cdecl _o__mbscat_s_l(ptr long str ptr) _mbscat_s_l +@ cdecl _o__mbschr(str long) _mbschr +@ cdecl _o__mbschr_l(str long ptr) _mbschr_l +@ cdecl _o__mbscmp(str str) _mbscmp +@ cdecl _o__mbscmp_l(str str ptr) _mbscmp_l +@ cdecl _o__mbscoll(str str) _mbscoll +@ cdecl _o__mbscoll_l(str str ptr) _mbscoll_l +@ cdecl _o__mbscpy_s(ptr long str) _mbscpy_s +@ cdecl _o__mbscpy_s_l(ptr long str ptr) _mbscpy_s_l +@ cdecl _o__mbscspn(str str) _mbscspn +@ cdecl _o__mbscspn_l(str str ptr) _mbscspn_l +@ cdecl _o__mbsdec(ptr ptr) _mbsdec +@ cdecl _o__mbsdec_l(ptr ptr ptr) _mbsdec_l +@ cdecl _o__mbsicmp(str str) _mbsicmp +@ cdecl _o__mbsicmp_l(str str ptr) _mbsicmp_l +@ cdecl _o__mbsicoll(str str) _mbsicoll +@ cdecl _o__mbsicoll_l(str str ptr) _mbsicoll_l +@ cdecl _o__mbsinc(str) _mbsinc +@ cdecl _o__mbsinc_l(str ptr) _mbsinc_l +@ cdecl _o__mbslen(str) _mbslen +@ cdecl _o__mbslen_l(str ptr) _mbslen_l +@ cdecl _o__mbslwr(str) _mbslwr +@ cdecl _o__mbslwr_l(str ptr) _mbslwr_l +@ cdecl _o__mbslwr_s(str long) _mbslwr_s +@ cdecl _o__mbslwr_s_l(str long ptr) _mbslwr_s_l +@ cdecl _o__mbsnbcat(str str long) _mbsnbcat +@ cdecl _o__mbsnbcat_l(str str long ptr) _mbsnbcat_l +@ cdecl _o__mbsnbcat_s(str long ptr long) _mbsnbcat_s +@ cdecl _o__mbsnbcat_s_l(str long ptr long ptr) _mbsnbcat_s_l +@ cdecl _o__mbsnbcmp(str str long) _mbsnbcmp +@ cdecl _o_mbsnbcmp_l(str str long ptr) _mbsnbcmp_l +@ cdecl _o__mbsnbcnt(ptr long) _mbsnbcnt +@ cdecl _o__mbsnbcnt_l(ptr long ptr) _mbsnbcnt_l +@ cdecl _o__mbsnbcoll(str str long) _mbsnbcoll +@ cdecl _o__mbsnbcoll_l(str str long ptr) _mbsnbcoll_l +@ cdecl _o__mbsnbcpy(ptr str long) _mbsnbcpy +@ cdecl _o__mbsnbcpy_l(ptr str long ptr) _mbsnbcpy_l +@ cdecl _o__mbsnbcpy_s(ptr long str long) _mbsnbcpy_s +@ cdecl _o__mbsnbcpy_s_l(ptr long str long ptr) _mbsnbcpy_s_l +@ cdecl _o__mbsnbicmp(str str long) _mbsnbicmp +@ cdecl _o__mbsnbicmp_l(str str long ptr) _mbsnbicmp_l +@ cdecl _o__mbsnbicoll(str str long) _mbsnbicoll +@ cdecl _o__mbsnbicoll_l(str str long ptr) _mbsnbicoll_l +@ cdecl _o__mbsnbset(ptr long long) _mbsnbset +@ cdecl _o__mbsnbset_l(str long long ptr) _mbsnbset_l +@ cdecl _o__mbsnbset_s() _mbsnbset_s # FIXME: params +@ cdecl _o__mbsnbset_s_l() _mbsnbset_s_l # FIXME: params +@ cdecl _o__mbsncat(str str long) _mbsncat +@ cdecl _o__mbsncat_l(str str long ptr) _mbsncat_l +@ cdecl _o__mbsncat_s(ptr long str long) _mbsncat_s +@ cdecl _o__mbsncat_s_l(ptr long str long ptr) _mbsncat_s_l +@ cdecl _o__mbsnccnt(str long) _mbsnccnt +@ cdecl _o__mbsnccnt_l(str long ptr) _mbsnccnt_l +@ cdecl _o__mbsncmp(str str long) _mbsncmp +@ cdecl _o__mbsncmp_l(str str long ptr) _mbsncmp_l +@ cdecl _o__mbsncoll() _mbsncoll # FIXME: params +@ cdecl _o__mbsncoll_l() _mbsncoll_l # FIXME: params +@ cdecl _o__mbsncpy(ptr str long) _mbsncpy +@ cdecl _o__mbsncpy_l(ptr str long ptr) _mbsncpy_l +@ cdecl _o__mbsncpy_s() _mbsncpy_s # FIXME: params +@ cdecl _o__mbsncpy_s_l() _mbsncpy_s_l # FIXME: params +@ cdecl _o__mbsnextc(str) _mbsnextc +@ cdecl _o__mbsnextc_l(str ptr) _mbsnextc_l +@ cdecl _o__mbsnicmp(str str long) _mbsnicmp +@ cdecl _o__mbsnicmp_l(str str long ptr) _mbsnicmp_l +@ cdecl _o__mbsnicoll() _mbsnicoll # FIXME: params +@ cdecl _o__mbsnicoll_l() _mbsnicoll_l # FIXME: params +@ cdecl _o__mbsninc(str long) _mbsninc +@ cdecl _o__mbsninc_l() _mbsninc_l # FIXME: params +@ cdecl _o__mbsnlen(str long) _mbsnlen +@ cdecl _o__mbsnlen_l(str long ptr) _mbsnlen_l +@ cdecl _o__mbsnset(ptr long long) _mbsnset +@ cdecl _o__mbsnset_l(ptr long long ptr) _mbsnset_l +@ cdecl _o__mbsnset_s() _mbsnset_s # FIXME: params +@ cdecl _o__mbsnset_s_l() _mbsnset_s_l # FIXME: params +@ cdecl _o__mbspbrk(str str) _mbspbrk +@ cdecl _o__mbspbrk_l(str str ptr) _mbspbrk_l +@ cdecl _o__mbsrchr(str long) _mbsrchr +@ cdecl _o__mbsrchr_l(str long ptr) _mbsrchr_l +@ cdecl _o__mbsrev(str) _mbsrev +@ cdecl _o__mbsrev_l(str ptr) _mbsrev_l +@ cdecl _o__mbsset(ptr long) _mbsset +@ cdecl _o__mbsset_l(ptr long ptr) _mbsset_l +@ cdecl _o__mbsset_s() _mbsset_s # FIXME: params +@ cdecl _o__mbsset_s_l() _mbsset_s_l # FIXME: params +@ cdecl _o__mbsspn(str str) _mbsspn +@ cdecl _o__mbsspn_l(str str ptr) _mbsspn_l +@ cdecl _o__mbsspnp(str str) _mbsspnp +@ cdecl _o__mbsspnp_l(str str ptr) _mbsspnp_l +@ cdecl _o__mbsstr(str str) _mbsstr +@ cdecl _o__mbsstr_l() _mbsstr_l # FIXME: params +@ cdecl _o__mbstok(str str) _mbstok +@ cdecl _o__mbstok_l(str str ptr) _mbstok_l +@ cdecl _o__mbstok_s(str str ptr) _mbstok_s +@ cdecl _o__mbstok_s_l(str str ptr ptr) _mbstok_s_l +@ cdecl _o__mbstowcs_l(ptr str long ptr) _mbstowcs_l +@ cdecl _o__mbstowcs_s_l(ptr ptr long str long ptr) _mbstowcs_s_l +@ cdecl _o__mbstrlen(str) _mbstrlen +@ cdecl _o__mbstrlen_l(str ptr) _mbstrlen_l +@ cdecl _o__mbstrnlen() _mbstrnlen # FIXME: params +@ cdecl _o__mbstrnlen_l() _mbstrnlen_l # FIXME: params +@ cdecl _o__mbsupr(str) _mbsupr +@ cdecl _o__mbsupr_l(str ptr) _mbsupr_l +@ cdecl _o__mbsupr_s(str long) _mbsupr_s +@ cdecl _o__mbsupr_s_l(str long ptr) _mbsupr_s_l +@ cdecl _o__mbtowc_l(ptr str long ptr) _mbtowc_l +@ cdecl _o__memicmp(str str long) _memicmp +@ cdecl _o__memicmp_l(str str long ptr) _memicmp_l +@ cdecl _o__mkdir(str) _mkdir +@ cdecl _o__mkgmtime32(ptr) _mkgmtime32 +@ cdecl _o__mkgmtime64(ptr) _mkgmtime64 +@ cdecl _o__mktemp(str) _mktemp +@ cdecl _o__mktemp_s(str long) _mktemp_s +@ cdecl _o__mktime32(ptr) _mktime32 +@ cdecl _o__mktime64(ptr) _mktime64 +@ cdecl _o__msize(ptr) _msize +@ cdecl _o__nextafter(double double) nextafter +@ cdecl -arch=x86_64 _o__nextafterf(float float) nextafterf +@ cdecl _o__open_osfhandle(long long) _open_osfhandle +@ cdecl _o__pclose(ptr) _pclose +@ cdecl _o__pipe(ptr long long) _pipe +@ cdecl _o__popen(str str) _popen +@ cdecl _o__purecall() _purecall +@ cdecl _o__putc_nolock(long ptr) _fputc_nolock +@ cdecl _o__putch(long) _putch +@ cdecl _o__putch_nolock(long) _putch_nolock +@ cdecl _o__putenv(str) _putenv +@ cdecl _o__putenv_s(str str) _putenv_s +@ cdecl _o__putw(long ptr) _putw +@ cdecl _o__putwc_nolock(long ptr) _fputwc_nolock +@ cdecl _o__putwch(long) _putwch +@ cdecl _o__putwch_nolock(long) _putwch_nolock +@ cdecl _o__putws(wstr) _putws +@ cdecl _o__read(long ptr long) _read +@ cdecl _o__realloc_base(ptr long) _realloc_base +@ cdecl _o__recalloc(ptr long long) _recalloc +@ cdecl _o__register_onexit_function(ptr ptr) _register_onexit_function +@ cdecl _o__resetstkoflw() _resetstkoflw +@ cdecl _o__rmdir(str) _rmdir +@ cdecl _o__rmtmp() _rmtmp +@ cdecl _o__scalb(double long) scalbn +@ cdecl -arch=x86_64 _o__scalbf(float long) scalbnf +@ cdecl _o__searchenv(str str ptr) _searchenv +@ cdecl _o__searchenv_s(str str ptr long) _searchenv_s +@ cdecl _o__seh_filter_dll(long ptr) _seh_filter_dll # __CppXcptFilter +@ cdecl _o__seh_filter_exe(long ptr) _seh_filter_exe # _XcptFilter +@ cdecl _o__set_abort_behavior(long long) _set_abort_behavior +@ cdecl _o__set_app_type(long) _set_app_type +@ cdecl _o__set_doserrno(long) _set_doserrno +@ cdecl _o__set_errno(long) _set_errno +@ cdecl _o__set_fmode(long) _set_fmode +@ cdecl _o__set_invalid_parameter_handler(ptr) _set_invalid_parameter_handler +@ cdecl _o__set_new_handler(ptr) _set_new_handler +@ cdecl _o__set_new_mode(long) _set_new_mode +@ cdecl _o__set_thread_local_invalid_parameter_handler(ptr) _set_thread_local_invalid_parameter_handler +@ cdecl _o__seterrormode(long) _seterrormode +@ cdecl _o__setmbcp(long) _setmbcp +@ cdecl _o__setmode(long long) _setmode +@ cdecl _o__setsystime() _setsystime # FIXME: params +@ cdecl _o__sleep(long) _sleep +@ varargs _o__sopen(str long long) _sopen +@ cdecl _o__sopen_dispatch(str long long long ptr long) _sopen_dispatch +@ cdecl _o__sopen_s(ptr str long long long) _sopen_s +@ cdecl _o__spawnv(long str ptr) _spawnv +@ cdecl _o__spawnve(long str ptr ptr) _spawnve +@ cdecl _o__spawnvp(long str ptr) _spawnvp +@ cdecl _o__spawnvpe(long str ptr ptr) _spawnvpe +@ cdecl _o__splitpath(str ptr ptr ptr ptr) _splitpath +@ cdecl _o__splitpath_s(str ptr long ptr long ptr long ptr long) _splitpath_s +@ cdecl _o__stat32(str ptr) _stat32 +@ cdecl _o__stat32i64(str ptr) _stat32i64 +@ cdecl _o__stat64(str ptr) _stat64 +@ cdecl _o__stat64i32(str ptr) _stat64i32 +@ cdecl _o__strcoll_l(str str ptr) _strcoll_l +@ cdecl _o__strdate(ptr) _strdate +@ cdecl _o__strdate_s(ptr long) _strdate_s +@ cdecl _o__strdup(str) _strdup +@ cdecl _o__strerror(long) _strerror +@ cdecl _o__strerror_s() _strerror_s # FIXME: params +@ cdecl _o__strftime_l(ptr long str ptr ptr) _strftime_l +@ cdecl _o__stricmp(str str) _stricmp +@ cdecl _o__stricmp_l(str str ptr) _stricmp_l +@ cdecl _o__stricoll(str str) _stricoll +@ cdecl _o__stricoll_l(str str ptr) _stricoll_l +@ cdecl _o__strlwr(str) _strlwr +@ cdecl _o__strlwr_l(str ptr) _strlwr_l +@ cdecl _o__strlwr_s(ptr long) _strlwr_s +@ cdecl _o__strlwr_s_l(ptr long ptr) _strlwr_s_l +@ cdecl _o__strncoll(str str long) _strncoll +@ cdecl _o__strncoll_l(str str long ptr) _strncoll_l +@ cdecl _o__strnicmp(str str long) _strnicmp +@ cdecl _o__strnicmp_l(str str long ptr) _strnicmp_l +@ cdecl _o__strnicoll(str str long) _strnicoll +@ cdecl _o__strnicoll_l(str str long ptr) _strnicoll_l +@ cdecl _o__strnset_s(str long long long) _strnset_s +@ cdecl _o__strset_s() _strset_s # FIXME: params +@ cdecl _o__strtime(ptr) _strtime +@ cdecl _o__strtime_s(ptr long) _strtime_s +@ cdecl _o__strtod_l(str ptr ptr) _strtod_l +@ cdecl _o__strtof_l(str ptr ptr) _strtof_l +@ cdecl -ret64 _o__strtoi64(str ptr long) _strtoi64 +@ cdecl -ret64 _o__strtoi64_l(str ptr long ptr) _strtoi64_l +@ cdecl _o__strtol_l(str ptr long ptr) _strtol_l +@ cdecl _o__strtold_l(str ptr ptr) _strtod_l +@ cdecl -ret64 _o__strtoll_l(str ptr long ptr) _strtoi64_l +@ cdecl -ret64 _o__strtoui64(str ptr long) _strtoui64 +@ cdecl -ret64 _o__strtoui64_l(str ptr long ptr) _strtoui64_l +@ cdecl _o__strtoul_l(str ptr long ptr) _strtoul_l +@ cdecl -ret64 _o__strtoull_l(str ptr long ptr) _strtoui64_l +@ cdecl _o__strupr(str) _strupr +@ cdecl _o__strupr_l(str ptr) _strupr_l +@ cdecl _o__strupr_s(str long) _strupr_s +@ cdecl _o__strupr_s_l(str long ptr) _strupr_s_l +@ cdecl _o__strxfrm_l(ptr str long ptr) _strxfrm_l +@ cdecl _o__swab(str str long) _swab +@ cdecl _o__tell(long) _tell +@ cdecl -ret64 _o__telli64(long) _telli64 +@ cdecl _o__timespec32_get(ptr long) _timespec32_get +@ cdecl _o__timespec64_get(ptr long) _timespec64_get +@ cdecl _o__tolower(long) _tolower +@ cdecl _o__tolower_l(long ptr) _tolower_l +@ cdecl _o__toupper(long) _toupper +@ cdecl _o__toupper_l(long ptr) _toupper_l +@ cdecl _o__towlower_l(long ptr) _towlower_l +@ cdecl _o__towupper_l(long ptr) _towupper_l +@ cdecl _o__tzset() _tzset +@ cdecl _o__ui64toa(int64 ptr long) _ui64toa +@ cdecl _o__ui64toa_s(int64 ptr long long) _ui64toa_s +@ cdecl _o__ui64tow(int64 ptr long) _ui64tow +@ cdecl _o__ui64tow_s(int64 ptr long long) _ui64tow_s +@ cdecl _o__ultoa(long ptr long) _ultoa +@ cdecl _o__ultoa_s(long ptr long long) _ultoa_s +@ cdecl _o__ultow(long ptr long) _ultow +@ cdecl _o__ultow_s(long ptr long long) _ultow_s +@ cdecl _o__umask(long) _umask +@ cdecl _o__umask_s() _umask_s # FIXME: params +@ cdecl _o__ungetc_nolock(long ptr) _ungetc_nolock +@ cdecl _o__ungetch(long) _ungetch +@ cdecl _o__ungetch_nolock(long) _ungetch_nolock +@ cdecl _o__ungetwc_nolock(long ptr) _ungetwc_nolock +@ cdecl _o__ungetwch(long) _ungetwch +@ cdecl _o__ungetwch_nolock(long) _ungetwch_nolock +@ cdecl _o__unlink(str) _unlink +@ cdecl _o__unloaddll(long) _unloaddll +@ cdecl _o__unlock_file(ptr) _unlock_file +@ cdecl _o__utime32(str ptr) _utime32 +@ cdecl _o__utime64(str ptr) _utime64 +@ cdecl _o__waccess(wstr long) _waccess +@ cdecl _o__waccess_s(wstr long) _waccess_s +@ cdecl _o__wasctime(ptr) _wasctime +@ cdecl _o__wasctime_s(ptr long ptr) _wasctime_s +@ cdecl _o__wchdir(wstr) _wchdir +@ cdecl _o__wchmod(wstr long) _wchmod +@ cdecl _o__wcreat(wstr long) _wcreat +@ cdecl _o__wcreate_locale(long wstr) _wcreate_locale +@ cdecl _o__wcscoll_l(wstr wstr ptr) _wcscoll_l +@ cdecl _o__wcsdup(wstr) _wcsdup +@ cdecl _o__wcserror(long) _wcserror +@ cdecl _o__wcserror_s(ptr long long) _wcserror_s +@ cdecl _o__wcsftime_l(ptr long wstr ptr ptr) _wcsftime_l +@ cdecl _o__wcsicmp(wstr wstr) _wcsicmp +@ cdecl _o__wcsicmp_l(wstr wstr ptr) _wcsicmp_l +@ cdecl _o__wcsicoll(wstr wstr) _wcsicoll +@ cdecl _o__wcsicoll_l(wstr wstr ptr) _wcsicoll_l +@ cdecl _o__wcslwr(wstr) _wcslwr +@ cdecl _o__wcslwr_l(wstr ptr) _wcslwr_l +@ cdecl _o__wcslwr_s(wstr long) _wcslwr_s +@ cdecl _o__wcslwr_s_l(wstr long ptr) _wcslwr_s_l +@ cdecl _o__wcsncoll(wstr wstr long) _wcsncoll +@ cdecl _o__wcsncoll_l(wstr wstr long ptr) _wcsncoll_l +@ cdecl _o__wcsnicmp(wstr wstr long) _wcsnicmp +@ cdecl _o__wcsnicmp_l(wstr wstr long ptr) _wcsnicmp_l +@ cdecl _o__wcsnicoll(wstr wstr long) _wcsnicoll +@ cdecl _o__wcsnicoll_l(wstr wstr long ptr) _wcsnicoll_l +@ cdecl _o__wcsnset(wstr long long) _wcsnset +@ cdecl _o__wcsnset_s(wstr long long long) _wcsnset_s +@ cdecl _o__wcsset(wstr long) _wcsset +@ cdecl _o__wcsset_s(wstr long long) _wcsset_s +@ cdecl _o__wcstod_l(wstr ptr ptr) _wcstod_l +@ cdecl _o__wcstof_l(wstr ptr ptr) _wcstof_l +@ cdecl -ret64 _o__wcstoi64(wstr ptr long) _wcstoi64 +@ cdecl -ret64 _o__wcstoi64_l(wstr ptr long ptr) _wcstoi64_l +@ cdecl _o__wcstol_l(wstr ptr long ptr) _wcstol_l +@ cdecl _o__wcstold_l(wstr ptr ptr) _wcstod_l +@ cdecl -ret64 _o__wcstoll_l(wstr ptr long ptr) _wcstoi64_l +@ cdecl _o__wcstombs_l(ptr ptr long ptr) _wcstombs_l +@ cdecl _o__wcstombs_s_l(ptr ptr long wstr long ptr) _wcstombs_s_l +@ cdecl -ret64 _o__wcstoui64(wstr ptr long) _wcstoui64 +@ cdecl -ret64 _o__wcstoui64_l(wstr ptr long ptr) _wcstoui64_l +@ cdecl _o__wcstoul_l(wstr ptr long ptr) _wcstoul_l +@ cdecl -ret64 _o__wcstoull_l(wstr ptr long ptr) _wcstoui64_l +@ cdecl _o__wcsupr(wstr) _wcsupr +@ cdecl _o__wcsupr_l(wstr ptr) _wcsupr_l +@ cdecl _o__wcsupr_s(wstr long) _wcsupr_s +@ cdecl _o__wcsupr_s_l(wstr long ptr) _wcsupr_s_l +@ cdecl _o__wcsxfrm_l(ptr wstr long ptr) _wcsxfrm_l +@ cdecl _o__wctime32(ptr) _wctime32 +@ cdecl _o__wctime32_s(ptr long ptr) _wctime32_s +@ cdecl _o__wctime64(ptr) _wctime64 +@ cdecl _o__wctime64_s(ptr long ptr) _wctime64_s +@ cdecl _o__wctomb_l(ptr long ptr) _wctomb_l +@ cdecl _o__wctomb_s_l(ptr ptr long long ptr) _wctomb_s_l +@ cdecl _o__wdupenv_s(ptr ptr wstr) _wdupenv_s +@ cdecl _o__wexecv(wstr ptr) _wexecv +@ cdecl _o__wexecve(wstr ptr ptr) _wexecve +@ cdecl _o__wexecvp(wstr ptr) _wexecvp +@ cdecl _o__wexecvpe(wstr ptr ptr) _wexecvpe +@ cdecl _o__wfdopen(long wstr) _wfdopen +@ cdecl _o__wfindfirst32(wstr ptr) _wfindfirst32 +@ cdecl _o__wfindfirst32i64() _wfindfirst32i64 # FIXME: params +@ cdecl _o__wfindfirst64(wstr ptr) _wfindfirst64 +@ cdecl _o__wfindfirst64i32(wstr ptr) _wfindfirst64i32 +@ cdecl _o__wfindnext32(long ptr) _wfindnext32 +@ cdecl _o__wfindnext32i64() _wfindnext32i64 # FIXME: params +@ cdecl _o__wfindnext64(long ptr) _wfindnext64 +@ cdecl _o__wfindnext64i32(long ptr) _wfindnext64i32 +@ cdecl _o__wfopen(wstr wstr) _wfopen +@ cdecl _o__wfopen_s(ptr wstr wstr) _wfopen_s +@ cdecl _o__wfreopen(wstr wstr ptr) _wfreopen +@ cdecl _o__wfreopen_s(ptr wstr wstr ptr) _wfreopen_s +@ cdecl _o__wfsopen(wstr wstr long) _wfsopen +@ cdecl _o__wfullpath(ptr wstr long) _wfullpath +@ cdecl _o__wgetcwd(wstr long) _wgetcwd +@ cdecl _o__wgetdcwd(long wstr long) _wgetdcwd +@ cdecl _o__wgetenv(wstr) _wgetenv +@ cdecl _o__wgetenv_s(ptr ptr long wstr) _wgetenv_s +@ cdecl _o__wmakepath(ptr wstr wstr wstr wstr) _wmakepath +@ cdecl _o__wmakepath_s(ptr long wstr wstr wstr wstr) _wmakepath_s +@ cdecl _o__wmkdir(wstr) _wmkdir +@ cdecl _o__wmktemp(wstr) _wmktemp +@ cdecl _o__wmktemp_s(wstr long) _wmktemp_s +@ cdecl _o__wperror(wstr) _wperror +@ cdecl _o__wpopen(wstr wstr) _wpopen +@ cdecl _o__wputenv(wstr) _wputenv +@ cdecl _o__wputenv_s(wstr wstr) _wputenv_s +@ cdecl _o__wremove(wstr) _wremove +@ cdecl _o__wrename(wstr wstr) _wrename +@ cdecl _o__write(long ptr long) _write +@ cdecl _o__wrmdir(wstr) _wrmdir +@ cdecl _o__wsearchenv(wstr wstr ptr) _wsearchenv +@ cdecl _o__wsearchenv_s(wstr wstr ptr long) _wsearchenv_s +@ cdecl _o__wsetlocale(long wstr) _wsetlocale +@ cdecl _o__wsopen_dispatch(wstr long long long ptr long) _wsopen_dispatch +@ cdecl _o__wsopen_s(ptr wstr long long long) _wsopen_s +@ cdecl _o__wspawnv(long wstr ptr) _wspawnv +@ cdecl _o__wspawnve(long wstr ptr ptr) _wspawnve +@ cdecl _o__wspawnvp(long wstr ptr) _wspawnvp +@ cdecl _o__wspawnvpe(long wstr ptr ptr) _wspawnvpe +@ cdecl _o__wsplitpath(wstr ptr ptr ptr ptr) _wsplitpath +@ cdecl _o__wsplitpath_s(wstr ptr long ptr long ptr long ptr long) _wsplitpath_s +@ cdecl _o__wstat32(wstr ptr) _wstat32 +@ cdecl _o__wstat32i64(wstr ptr) _wstat32i64 +@ cdecl _o__wstat64(wstr ptr) _wstat64 +@ cdecl _o__wstat64i32(wstr ptr) _wstat64i32 +@ cdecl _o__wstrdate(ptr) _wstrdate +@ cdecl _o__wstrdate_s(ptr long) _wstrdate_s +@ cdecl _o__wstrtime(ptr) _wstrtime +@ cdecl _o__wstrtime_s(ptr long) _wstrtime_s +@ cdecl _o__wsystem(wstr) _wsystem +@ cdecl _o__wtmpnam_s(ptr long) _wtmpnam_s +@ cdecl _o__wtof(wstr) _wtof +@ cdecl _o__wtof_l(wstr ptr) _wtof_l +@ cdecl _o__wtoi(wstr) _wtoi +@ cdecl -ret64 _o__wtoi64(wstr) _wtoi64 +@ cdecl -ret64 _o__wtoi64_l(wstr ptr) _wtoi64_l +@ cdecl _o__wtoi_l(wstr ptr) _wtoi_l +@ cdecl _o__wtol(wstr) _wtol +@ cdecl _o__wtol_l(wstr ptr) _wtol_l +@ cdecl -ret64 _o__wtoll(wstr) _wtoll +@ cdecl -ret64 _o__wtoll_l(wstr ptr) _wtoll_l +@ cdecl _o__wunlink(wstr) _wunlink +@ cdecl _o__wutime32(wstr ptr) _wutime32 +@ cdecl _o__wutime64(wstr ptr) _wutime64 +@ cdecl _o__y0(double) _y0 +@ cdecl _o__y1(double) _y1 +@ cdecl _o__yn(long double) _yn +@ cdecl _o_abort() abort +@ cdecl _o_acos(double) acos +@ cdecl -arch=!i386 _o_acosf(float) acosf +@ cdecl _o_acosh(double) acosh +@ cdecl _o_acoshf(float) acoshf +@ cdecl _o_acoshl(double) acosh +@ cdecl _o_asctime(ptr) asctime +@ cdecl _o_asctime_s(ptr long ptr) asctime_s +@ cdecl _o_asin(double) asin +@ cdecl -arch=!i386 _o_asinf(float) asinf +@ cdecl _o_asinh(double) asinh +@ cdecl _o_asinhf(float) asinhf +@ cdecl _o_asinhl(double) asinh +@ cdecl _o_atan(double) atan +@ cdecl _o_atan2(double double) atan2 +@ cdecl -arch=!i386 _o_atan2f(float float) atan2f +@ cdecl -arch=!i386 _o_atanf(float) atanf +@ cdecl _o_atanh(double) atanh +@ cdecl _o_atanhf(float) atanhf +@ cdecl _o_atanhl(double) atanh +@ cdecl _o_atof(str) atof +@ cdecl _o_atoi(str) atoi +@ cdecl _o_atol(str) atol +@ cdecl -ret64 _o_atoll(str) atoll +@ cdecl _o_bsearch(ptr ptr long long ptr) bsearch +@ cdecl _o_bsearch_s(ptr ptr long long ptr ptr) bsearch_s +@ cdecl _o_btowc(long) btowc +@ cdecl _o_calloc(long long) calloc +@ cdecl _o_cbrt(double) cbrt +@ cdecl _o_cbrtf(float) cbrtf +@ cdecl _o_ceil(double) ceil +@ cdecl -arch=!i386 _o_ceilf(float) ceilf +@ cdecl _o_clearerr(ptr) clearerr +@ cdecl _o_clearerr_s(ptr) clearerr_s +@ cdecl _o_cos(double) cos +@ cdecl -arch=!i386 _o_cosf(float) cosf +@ cdecl _o_cosh(double) cosh +@ cdecl -arch=!i386 _o_coshf(float) coshf +@ cdecl _o_erf(double) erf +@ cdecl _o_erfc(double) erfc +@ cdecl _o_erfcf(float) erfcf +@ cdecl _o_erfcl(double) erfc +@ cdecl _o_erff(float) erff +@ cdecl _o_erfl(double) erf +@ cdecl _o_exit(long) exit +@ cdecl _o_exp(double) exp +@ cdecl _o_exp2(double) exp2 +@ cdecl _o_exp2f(float) exp2f +@ cdecl _o_exp2l(double) exp2 +@ cdecl -arch=!i386 _o_expf(float) expf +@ cdecl _o_fabs(double) fabs +@ cdecl _o_fclose(ptr) fclose +@ cdecl _o_feof(ptr) feof +@ cdecl _o_ferror(ptr) ferror +@ cdecl _o_fflush(ptr) fflush +@ cdecl _o_fgetc(ptr) fgetc +@ cdecl _o_fgetpos(ptr ptr) fgetpos +@ cdecl _o_fgets(ptr long ptr) fgets +@ cdecl _o_fgetwc(ptr) fgetwc +@ cdecl _o_fgetws(ptr long ptr) fgetws +@ cdecl _o_floor(double) floor +@ cdecl -arch=!i386 _o_floorf(float) floorf +@ cdecl _o_fma(double double double) fma +@ cdecl _o_fmaf(float float float) fmaf +@ cdecl _o_fmal(double double double) fma +@ cdecl _o_fmod(double double) fmod +@ cdecl -arch=!i386 _o_fmodf(float float) fmodf +@ cdecl _o_fopen(str str) fopen +@ cdecl _o_fopen_s(ptr str str) fopen_s +@ cdecl _o_fputc(long ptr) fputc +@ cdecl _o_fputs(str ptr) fputs +@ cdecl _o_fputwc(long ptr) fputwc +@ cdecl _o_fputws(wstr ptr) fputws +@ cdecl _o_fread(ptr long long ptr) fread +@ cdecl _o_fread_s(ptr long long long ptr) fread_s +@ cdecl _o_free(ptr) free +@ cdecl _o_freopen(str str ptr) freopen +@ cdecl _o_freopen_s(ptr str str ptr) freopen_s +@ cdecl _o_frexp(double ptr) frexp +@ cdecl _o_fseek(ptr long long) fseek +@ cdecl _o_fsetpos(ptr ptr) fsetpos +@ cdecl _o_ftell(ptr) ftell +@ cdecl _o_fwrite(ptr long long ptr) fwrite +@ cdecl _o_getc(ptr) getc +@ cdecl _o_getchar() getchar +@ cdecl _o_getenv(str) getenv +@ cdecl _o_getenv_s(ptr ptr long str) getenv_s +@ cdecl _o_gets(str) gets +@ cdecl _o_gets_s(ptr long) gets_s +@ cdecl _o_getwc(ptr) getwc +@ cdecl _o_getwchar() getwchar +@ cdecl _o_hypot(double double) _hypot +@ cdecl _o_is_wctype(long long) iswctype +@ cdecl _o_isalnum(long) isalnum +@ cdecl _o_isalpha(long) isalpha +@ cdecl _o_isblank(long) isblank +@ cdecl _o_iscntrl(long) iscntrl +@ cdecl _o_isdigit(long) isdigit +@ cdecl _o_isgraph(long) isgraph +@ cdecl _o_isleadbyte(long) isleadbyte +@ cdecl _o_islower(long) islower +@ cdecl _o_isprint(long) isprint +@ cdecl _o_ispunct(long) ispunct +@ cdecl _o_isspace(long) isspace +@ cdecl _o_isupper(long) isupper +@ cdecl _o_iswalnum(long) iswalnum +@ cdecl _o_iswalpha(long) iswalpha +@ cdecl _o_iswascii(long) iswascii +@ cdecl _o_iswblank(long) iswblank +@ cdecl _o_iswcntrl(long) iswcntrl +@ cdecl _o_iswctype(long long) iswctype +@ cdecl _o_iswdigit(long) iswdigit +@ cdecl _o_iswgraph(long) iswgraph +@ cdecl _o_iswlower(long) iswlower +@ cdecl _o_iswprint(long) iswprint +@ cdecl _o_iswpunct(long) iswpunct +@ cdecl _o_iswspace(long) iswspace +@ cdecl _o_iswupper(long) iswupper +@ cdecl _o_iswxdigit(long) iswxdigit +@ cdecl _o_isxdigit(long) isxdigit +@ cdecl _o_ldexp(double long) ldexp +@ cdecl _o_lgamma(double) lgamma +@ cdecl _o_lgammaf(float) lgammaf +@ cdecl _o_lgammal(double) lgamma +@ cdecl -ret64 _o_llrint(double) llrint +@ cdecl -ret64 _o_llrintf(float) llrintf +@ cdecl -ret64 _o_llrintl(double) llrint +@ cdecl -ret64 _o_llround(double) llround +@ cdecl -ret64 _o_llroundf(float) llroundf +@ cdecl -ret64 _o_llroundl(double) llround +@ cdecl _o_localeconv() localeconv +@ cdecl _o_log(double) log +@ cdecl _o_log10(double) log10 +@ cdecl -arch=!i386 _o_log10f(float) log10f +@ cdecl _o_log1p(double) log1p +@ cdecl _o_log1pf(float) log1pf +@ cdecl _o_log1pl(double) log1p +@ cdecl _o_log2(double) log2 +@ cdecl _o_log2f(float) log2f +@ cdecl _o_log2l(double) log2 +@ cdecl _o_logb(double) logb +@ cdecl _o_logbf(float) logbf +@ cdecl _o_logbl(double) logb +@ cdecl -arch=!i386 _o_logf(float) logf +@ cdecl _o_lrint(double) lrint +@ cdecl _o_lrintf(float) lrintf +@ cdecl _o_lrintl(double) lrint +@ cdecl _o_lround(double) lround +@ cdecl _o_lroundf(float) lroundf +@ cdecl _o_lroundl(double) lround +@ cdecl _o_malloc(long) malloc +@ cdecl _o_mblen(ptr long) mblen +@ cdecl _o_mbrlen(ptr long ptr) mbrlen +@ cdecl _o_mbrtoc16() mbrtoc16 # FIXME: params +@ cdecl _o_mbrtoc32() mbrtoc32 # FIXME: params +@ cdecl _o_mbrtowc(ptr str long ptr) mbrtowc +@ cdecl _o_mbsrtowcs(ptr ptr long ptr) mbsrtowcs +@ cdecl _o_mbsrtowcs_s(ptr ptr long ptr long ptr) mbsrtowcs_s +@ cdecl _o_mbstowcs(ptr str long) mbstowcs +@ cdecl _o_mbstowcs_s(ptr ptr long str long) mbstowcs_s +@ cdecl _o_mbtowc(ptr str long) mbtowc +@ cdecl _o_memcpy_s(ptr long ptr long) memcpy_s +@ cdecl _o_memset(ptr long long) memset +@ cdecl _o_modf(double ptr) modf +@ cdecl -arch=!i386 _o_modff(float ptr) modff +@ cdecl _o_nan(str) nan +@ cdecl _o_nanf(str) nanf +@ cdecl _o_nanl(str) nan +@ cdecl _o_nearbyint(double) nearbyint +@ cdecl _o_nearbyintf(float) nearbyintf +@ cdecl _o_nearbyintl(double) nearbyint +@ cdecl _o_nextafter(double double) nextafter +@ cdecl _o_nextafterf(float float) nextafterf +@ cdecl _o_nextafterl(double double) nextafter +@ cdecl _o_nexttoward(double double) nexttoward +@ cdecl _o_nexttowardf(float double) nexttowardf +@ cdecl _o_nexttowardl(double double) nexttoward +@ cdecl _o_pow(double double) pow +@ cdecl -arch=!i386 _o_powf(float float) powf +@ cdecl _o_putc(long ptr) putc +@ cdecl _o_putchar(long) putchar +@ cdecl _o_puts(str) puts +@ cdecl _o_putwc(long ptr) fputwc +@ cdecl _o_putwchar(long) _fputwchar +@ cdecl _o_qsort(ptr long long ptr) qsort +@ cdecl _o_qsort_s(ptr long long ptr ptr) qsort_s +@ cdecl _o_raise(long) raise +@ cdecl _o_rand() rand +@ cdecl _o_rand_s(ptr) rand_s +@ cdecl _o_realloc(ptr long) realloc +@ cdecl _o_remainder(double double) remainder +@ cdecl _o_remainderf(float float) remainderf +@ cdecl _o_remainderl(double double) remainder +@ cdecl _o_remove(str) remove +@ cdecl _o_remquo(double double ptr) remquo +@ cdecl _o_remquof(float float ptr) remquof +@ cdecl _o_remquol(double double ptr) remquo +@ cdecl _o_rename(str str) rename +@ cdecl _o_rewind(ptr) rewind +@ cdecl _o_rint(double) rint +@ cdecl _o_rintf(float) rintf +@ cdecl _o_rintl(double) rint +@ cdecl _o_round(double) round +@ cdecl _o_roundf(float) roundf +@ cdecl _o_roundl(double) round +@ cdecl _o_scalbln(double long) scalbn +@ cdecl _o_scalblnf(float long) scalbnf +@ cdecl _o_scalblnl(double long) scalbn +@ cdecl _o_scalbn(double long) scalbn +@ cdecl _o_scalbnf(float long) scalbnf +@ cdecl _o_scalbnl(double long) scalbn +@ cdecl _o_set_terminate(ptr) set_terminate +@ cdecl _o_setbuf(ptr ptr) setbuf +@ cdecl _o_setlocale(long str) setlocale +@ cdecl _o_setvbuf(ptr str long long) setvbuf +@ cdecl _o_sin(double) sin +@ cdecl -arch=!i386 _o_sinf(float) sinf +@ cdecl _o_sinh(double) sinh +@ cdecl -arch=!i386 _o_sinhf(float) sinhf +@ cdecl _o_sqrt(double) sqrt +@ cdecl -arch=!i386 _o_sqrtf(float) sqrtf +@ cdecl _o_srand(long) srand +@ cdecl _o_strcat_s(str long str) strcat_s +@ cdecl _o_strcoll(str str) strcoll +@ cdecl _o_strcpy_s(ptr long str) strcpy_s +@ cdecl _o_strerror(long) strerror +@ cdecl _o_strerror_s(ptr long long) strerror_s +@ cdecl _o_strftime(ptr long str ptr) strftime +@ cdecl _o_strncat_s(str long str long) strncat_s +@ cdecl _o_strncpy_s(ptr long str long) strncpy_s +@ cdecl _o_strtod(str ptr) strtod +@ cdecl _o_strtof(str ptr) strtof +@ cdecl _o_strtok(str str) strtok +@ cdecl _o_strtok_s(ptr str ptr) strtok_s +@ cdecl _o_strtol(str ptr long) strtol +@ cdecl _o_strtold(str ptr) strtod +@ cdecl -ret64 _o_strtoll(str ptr long) _strtoi64 +@ cdecl _o_strtoul(str ptr long) strtoul +@ cdecl -ret64 _o_strtoull(str ptr long) _strtoui64 +@ cdecl _o_system(str) system +@ cdecl _o_tan(double) tan +@ cdecl -arch=!i386 _o_tanf(float) tanf +@ cdecl _o_tanh(double) tanh +@ cdecl -arch=!i386 _o_tanhf(float) tanhf +@ cdecl _o_terminate() terminate +@ cdecl _o_tgamma(double) tgamma +@ cdecl _o_tgammaf(float) tgammaf +@ cdecl _o_tgammal(double) tgamma +@ cdecl _o_tmpfile_s(ptr) tmpfile_s +@ cdecl _o_tmpnam_s(ptr long) tmpnam_s +@ cdecl _o_tolower(long) tolower +@ cdecl _o_toupper(long) toupper +@ cdecl _o_towlower(long) towlower +@ cdecl _o_towupper(long) towupper +@ cdecl _o_ungetc(long ptr) ungetc +@ cdecl _o_ungetwc(long ptr) ungetwc +@ cdecl _o_wcrtomb(ptr long ptr) wcrtomb +@ cdecl _o_wcrtomb_s(ptr ptr long long ptr) wcrtomb_s +@ cdecl _o_wcscat_s(wstr long wstr) wcscat_s +@ cdecl _o_wcscoll(wstr wstr) wcscoll +@ cdecl _o_wcscpy(ptr wstr) wcscpy +@ cdecl _o_wcscpy_s(ptr long wstr) wcscpy_s +@ cdecl _o_wcsftime(ptr long wstr ptr) wcsftime +@ cdecl _o_wcsncat_s(wstr long wstr long) wcsncat_s +@ cdecl _o_wcsncpy_s(ptr long wstr long) wcsncpy_s +@ cdecl _o_wcsrtombs(ptr ptr long ptr) wcsrtombs +@ cdecl _o_wcsrtombs_s(ptr ptr long ptr long ptr) wcsrtombs_s +@ cdecl _o_wcstod(wstr ptr) wcstod +@ cdecl _o_wcstof(ptr ptr) wcstof +@ cdecl _o_wcstok(wstr wstr ptr) wcstok +@ cdecl _o_wcstok_s(ptr wstr ptr) wcstok_s +@ cdecl _o_wcstol(wstr ptr long) wcstol +@ cdecl _o_wcstold(wstr ptr ptr) wcstod +@ cdecl -ret64 _o_wcstoll(wstr ptr long) _wcstoi64 +@ cdecl _o_wcstombs(ptr ptr long) wcstombs +@ cdecl _o_wcstombs_s(ptr ptr long wstr long) wcstombs_s +@ cdecl _o_wcstoul(wstr ptr long) wcstoul +@ cdecl -ret64 _o_wcstoull(wstr ptr long) _wcstoui64 +@ cdecl _o_wctob(long) wctob +@ cdecl _o_wctomb(ptr long) wctomb +@ cdecl _o_wctomb_s(ptr ptr long long) wctomb_s +@ cdecl _o_wmemcpy_s(ptr long ptr long) wmemcpy_s +@ cdecl _o_wmemmove_s(ptr long ptr long) wmemmove_s +@ varargs _open(str long) +@ cdecl _open_osfhandle(long long) +@ cdecl _pclose(ptr) +@ cdecl _pipe(ptr long long) +@ cdecl _popen(str str) +@ cdecl _purecall() +@ cdecl _putc_nolock(long ptr) _fputc_nolock +@ cdecl _putch(long) +@ cdecl _putch_nolock(long) +@ cdecl _putenv(str) +@ cdecl _putenv_s(str str) +@ cdecl _putw(long ptr) +@ cdecl _putwc_nolock(long ptr) _fputwc_nolock +@ cdecl _putwch(long) +@ cdecl _putwch_nolock(long) +@ cdecl _putws(wstr) +@ cdecl _query_app_type() +@ cdecl _query_new_handler() +@ cdecl _query_new_mode() +@ cdecl _read(long ptr long) +@ cdecl _realloc_base(ptr long) +@ cdecl -dbg _realloc_dbg(ptr long long str long) +@ cdecl _recalloc(ptr long long) +@ cdecl -dbg _recalloc_dbg(ptr long long long str long) +@ cdecl _register_onexit_function(ptr ptr) +@ cdecl _register_thread_local_exe_atexit_callback(ptr) +@ cdecl _resetstkoflw() +@ cdecl _rmdir(str) +@ cdecl _rmtmp() +@ cdecl _rotl(long long) +@ cdecl -ret64 _rotl64(int64 long) +@ cdecl _rotr(long long) +@ cdecl -ret64 _rotr64(int64 long) +@ cdecl _scalb(double long) scalbn # double _scalb(double x, long exp); +@ cdecl -arch=x86_64 _scalbf(float long) scalbnf # float _scalbf(float x, long exp); +@ cdecl _searchenv(str str ptr) +@ cdecl _searchenv_s(str str ptr long) +@ cdecl _seh_filter_dll(long ptr) # __CppXcptFilter +@ cdecl _seh_filter_exe(long ptr) # _XcptFilter +@ cdecl -arch=win64 _set_FMA3_enable(long) +@ stdcall -arch=i386 _seh_longjmp_unwind4(ptr) +@ stdcall -arch=i386 _seh_longjmp_unwind(ptr) +@ cdecl -stub -arch=i386 _set_SSE2_enable(long) +@ cdecl _set_abort_behavior(long long) +@ cdecl _set_app_type(long) +@ cdecl _set_controlfp(long long) _controlfp +@ cdecl _set_doserrno(long) +@ cdecl _set_errno(long) +@ cdecl _set_error_mode(long) +@ cdecl _set_fmode(long) +@ cdecl _set_invalid_parameter_handler(ptr) +@ cdecl _set_new_handler(ptr) +@ cdecl _set_new_mode(long) +@ cdecl _set_printf_count_output(long) +@ cdecl _set_purecall_handler(ptr) +@ cdecl _set_se_translator(ptr) +@ cdecl _set_thread_local_invalid_parameter_handler(ptr) +@ cdecl _seterrormode(long) +@ cdecl -arch=i386 -norelay _setjmp3(ptr long) +@ cdecl _setmaxstdio(long) +@ cdecl _setmbcp(long) +@ cdecl _setmode(long long) +@ cdecl _setsystime(ptr long) +@ cdecl _sleep(long) +@ varargs _sopen(str long long) +@ cdecl _sopen_dispatch(str long long long ptr long) +@ cdecl _sopen_s(ptr str long long long) +@ varargs _spawnl(long str str) +@ varargs _spawnle(long str str) +@ varargs _spawnlp(long str str) +@ varargs _spawnlpe(long str str) +@ cdecl _spawnv(long str ptr) +@ cdecl _spawnve(long str ptr ptr) +@ cdecl _spawnvp(long str ptr) +@ cdecl _spawnvpe(long str ptr ptr) +@ cdecl _splitpath(str ptr ptr ptr ptr) +@ cdecl _splitpath_s(str ptr long ptr long ptr long ptr long) +@ cdecl _stat32(str ptr) +@ cdecl -arch=win32 -impsym _stat(ptr) _stat32 +@ cdecl _stat32i64(str ptr) +@ cdecl _stat64(str ptr) +@ cdecl _stat64i32(str ptr) +@ cdecl -arch=win64 -impsym _stat(ptr) _stat64i32 +@ cdecl _statusfp() +@ cdecl -stub -arch=i386 _statusfp2(ptr ptr) +@ cdecl _strcoll_l(str str ptr) +@ cdecl _strdate(ptr) +@ cdecl _strdate_s(ptr long) +@ cdecl _strdup(str) +@ cdecl -dbg _strdup_dbg(str long str long) +@ cdecl _strerror(long) +@ cdecl _strerror_s(str) +@ cdecl _strftime_l(ptr long str ptr ptr) +@ cdecl _stricmp(str str) +@ cdecl _stricmp_l(str str ptr) +@ cdecl _stricoll(str str) +@ cdecl _stricoll_l(str str ptr) +@ cdecl _strlwr(str) +@ cdecl _strlwr_l(str ptr) +@ cdecl _strlwr_s(ptr long) +@ cdecl _strlwr_s_l(ptr long ptr) +@ cdecl _strncoll(str str long) +@ cdecl _strncoll_l(str str long ptr) +@ cdecl _strnicmp(str str long) +@ cdecl _strnicmp_l(str str long ptr) +@ cdecl _strnicoll(str str long) +@ cdecl _strnicoll_l(str str long ptr) +@ cdecl _strnset(str long long) +@ cdecl _strnset_s(str long long long) +@ cdecl _strrev(str) +@ cdecl _strset(ptr long) +@ cdecl _strset_s(ptr long long) +@ cdecl _strtime(ptr) +@ cdecl _strtime_s(ptr long) +@ cdecl _strtod_l(str ptr ptr) +@ cdecl _strtof_l(str ptr ptr) +@ cdecl -ret64 _strtoi64(str ptr long) +@ cdecl -ret64 _strtoi64_l(str ptr long ptr) +@ cdecl -ret64 _strtoimax_l(str ptr long ptr) _strtoi64_l +@ cdecl _strtol_l(str ptr long ptr) +@ cdecl _strtold_l(str ptr ptr) _strtod_l +@ cdecl -ret64 _strtoll_l(str ptr long ptr) _strtoi64_l +@ cdecl -ret64 _strtoui64(str ptr long) +@ cdecl -ret64 _strtoui64_l(str ptr long ptr) +@ cdecl _strtoul_l(str ptr long ptr) +@ cdecl -ret64 _strtoull_l(str ptr long ptr) _strtoui64_l +@ cdecl -ret64 _strtoumax_l(str ptr long ptr) _strtoui64_l +@ cdecl _strupr(str) +@ cdecl _strupr_l(str ptr) +@ cdecl _strupr_s(str long) +@ cdecl _strupr_s_l(str long ptr) +@ cdecl _strxfrm_l(ptr str long ptr) +@ cdecl _swab(str str long) +@ cdecl _tell(long) +@ cdecl -ret64 _telli64(long) +@ cdecl _tempnam(str str) +@ cdecl -dbg _tempnam_dbg(str str long str long) +@ cdecl _time32(ptr) +@ cdecl _time64(ptr) +@ cdecl _timespec32_get(ptr long) +@ cdecl _timespec64_get(ptr long) +@ cdecl _tolower(long) +@ cdecl _tolower_l(long ptr) +@ cdecl _toupper(long) +@ cdecl _toupper_l(long ptr) +@ cdecl _towlower_l(long ptr) +@ cdecl _towupper_l(long ptr) +@ cdecl _tzset() +@ cdecl _ui64toa(int64 ptr long) +@ cdecl _ui64toa_s(int64 ptr long long) +@ cdecl _ui64tow(int64 ptr long) +@ cdecl _ui64tow_s(int64 ptr long long) +@ cdecl _ultoa(long ptr long) +@ cdecl _ultoa_s(long ptr long long) +@ cdecl _ultow(long ptr long) +@ cdecl _ultow_s(long ptr long long) +@ cdecl _umask(long) +@ cdecl _umask_s(long) +@ cdecl _ungetc_nolock(long ptr) +@ cdecl _ungetch(long) +@ cdecl _ungetch_nolock(long) +@ cdecl _ungetwc_nolock(long ptr) +@ cdecl _ungetwch(long) +@ cdecl _ungetwch_nolock(long) +@ cdecl _unlink(str) +@ cdecl _unloaddll(long) +@ cdecl _unlock_file(ptr) +@ cdecl _unlock_locales() +@ cdecl _utime32(str ptr) +@ cdecl -arch=win32 -impsym _utime(str ptr) _utime32 +@ cdecl _utime64(str ptr) +@ cdecl -arch=win64 -impsym _utime(str ptr) _utime64 +@ cdecl _waccess(wstr long) +@ cdecl _waccess_s(wstr long) +@ cdecl _wasctime(ptr) +@ cdecl _wasctime_s(ptr long ptr) +@ cdecl _wassert(wstr wstr long) +@ cdecl _wchdir(wstr) +@ cdecl _wchmod(wstr long) +@ cdecl _wcreat(wstr long) +@ cdecl _wcreate_locale(long wstr) +@ cdecl _wcscoll_l(wstr wstr ptr) +@ cdecl _wcsdup(wstr) +@ cdecl -dbg _wcsdup_dbg(wstr long str long) +@ cdecl _wcserror(long) +@ cdecl _wcserror_s(ptr long long) +@ cdecl _wcsftime_l(ptr long wstr ptr ptr) +@ cdecl _wcsicmp(wstr wstr) +@ cdecl _wcsicmp_l(wstr wstr ptr) +@ cdecl _wcsicoll(wstr wstr) +@ cdecl _wcsicoll_l(wstr wstr ptr) +@ cdecl _wcslwr(wstr) +@ cdecl _wcslwr_l(wstr ptr) +@ cdecl _wcslwr_s(wstr long) +@ cdecl _wcslwr_s_l(wstr long ptr) +@ cdecl _wcsncoll(wstr wstr long) +@ cdecl _wcsncoll_l(wstr wstr long ptr) +@ cdecl _wcsnicmp(wstr wstr long) +@ cdecl _wcsnicmp_l(wstr wstr long ptr) +@ cdecl _wcsnicoll(wstr wstr long) +@ cdecl _wcsnicoll_l(wstr wstr long ptr) +@ cdecl _wcsnset(wstr long long) +@ cdecl _wcsnset_s(wstr long long long) +@ cdecl _wcsrev(wstr) +@ cdecl _wcsset(wstr long) +@ cdecl _wcsset_s(wstr long long) +@ cdecl _wcstod_l(wstr ptr ptr) +@ cdecl _wcstof_l(wstr ptr ptr) +@ cdecl -ret64 _wcstoi64(wstr ptr long) +@ cdecl -ret64 _wcstoi64_l(wstr ptr long ptr) +@ cdecl _wcstoimax_l(wstr ptr long ptr) +@ cdecl _wcstol_l(wstr ptr long ptr) +@ cdecl _wcstold_l(wstr ptr ptr) _wcstod_l +@ cdecl -ret64 _wcstoll_l(wstr ptr long ptr) _wcstoi64_l +@ cdecl _wcstombs_l(ptr ptr long ptr) +@ cdecl _wcstombs_s_l(ptr ptr long wstr long ptr) +@ cdecl -ret64 _wcstoui64(wstr ptr long) +@ cdecl -ret64 _wcstoui64_l(wstr ptr long ptr) +@ cdecl _wcstoul_l(wstr ptr long ptr) +@ cdecl -ret64 _wcstoull_l(wstr ptr long ptr) _wcstoui64_l +@ cdecl _wcstoumax_l(wstr ptr long ptr) +@ cdecl _wcsupr(wstr) +@ cdecl _wcsupr_l(wstr ptr) +@ cdecl _wcsupr_s(wstr long) +@ cdecl _wcsupr_s_l(wstr long ptr) +@ cdecl _wcsxfrm_l(ptr wstr long ptr) +@ cdecl _wctime32(ptr) +@ cdecl _wctime32_s(ptr long ptr) +@ cdecl _wctime64(ptr) +@ cdecl _wctime64_s(ptr long ptr) +@ cdecl _wctomb_l(ptr long ptr) +@ cdecl _wctomb_s_l(ptr ptr long long ptr) +@ extern _wctype +@ cdecl _wdupenv_s(ptr ptr wstr) +@ cdecl -dbg _wdupenv_s_dbg(ptr ptr wstr long str long) +@ varargs _wexecl(wstr wstr) +@ varargs _wexecle(wstr wstr) +@ varargs _wexeclp(wstr wstr) +@ varargs _wexeclpe(wstr wstr) +@ cdecl _wexecv(wstr ptr) +@ cdecl _wexecve(wstr ptr ptr) +@ cdecl _wexecvp(wstr ptr) +@ cdecl _wexecvpe(wstr ptr ptr) +@ cdecl _wfdopen(long wstr) +@ cdecl _wfindfirst32(wstr ptr) +@ cdecl _wfindfirst32i64(wstr ptr) +@ cdecl _wfindfirst64(wstr ptr) +@ cdecl _wfindfirst64i32(wstr ptr) +@ cdecl _wfindnext32(long ptr) +@ cdecl _wfindnext32i64(long ptr) +@ cdecl _wfindnext64(long ptr) +@ cdecl _wfindnext64i32(long ptr) +@ cdecl _wfopen(wstr wstr) +@ cdecl _wfopen_s(ptr wstr wstr) +@ cdecl _wfreopen(wstr wstr ptr) +@ cdecl _wfreopen_s(ptr wstr wstr ptr) +@ cdecl _wfsopen(wstr wstr long) +@ cdecl _wfullpath(ptr wstr long) +@ cdecl -dbg _wfullpath_dbg(ptr wstr long long str long) +@ cdecl _wgetcwd(wstr long) +@ cdecl -dbg _wgetcwd_dbg(ptr long long str long) +@ cdecl _wgetdcwd(long ptr long) +@ cdecl -dbg _wgetdcwd_dbg(long ptr long long str long) +@ cdecl _wgetenv(wstr) +@ cdecl _wgetenv_s(ptr ptr long wstr) +@ cdecl _wmakepath(ptr wstr wstr wstr wstr) +@ cdecl _wmakepath_s(ptr long wstr wstr wstr wstr) +@ cdecl _wmkdir(wstr) +@ cdecl _wmktemp(wstr) +@ cdecl _wmktemp_s(wstr long) +@ varargs _wopen(wstr long) +@ cdecl _wperror(wstr) +@ cdecl _wpopen(wstr wstr) +@ cdecl _wputenv(wstr) +@ cdecl _wputenv_s(wstr wstr) +@ cdecl _wremove(wstr) +@ cdecl _wrename(wstr wstr) +@ cdecl _write(long ptr long) +@ cdecl _wrmdir(wstr) +@ cdecl _wsearchenv(wstr wstr ptr) +@ cdecl _wsearchenv_s(wstr wstr ptr long) +@ cdecl _wsetlocale(long wstr) +@ varargs _wsopen(wstr long long) +@ cdecl _wsopen_dispatch(wstr long long long ptr long) +@ cdecl _wsopen_s(ptr wstr long long long) +@ varargs _wspawnl(long wstr wstr) +@ varargs _wspawnle(long wstr wstr) +@ varargs _wspawnlp(long wstr wstr) +@ varargs _wspawnlpe(long wstr wstr) +@ cdecl _wspawnv(long wstr ptr) +@ cdecl _wspawnve(long wstr ptr ptr) +@ cdecl _wspawnvp(long wstr ptr) +@ cdecl _wspawnvpe(long wstr ptr ptr) +@ cdecl _wsplitpath(wstr ptr ptr ptr ptr) +@ cdecl _wsplitpath_s(wstr ptr long ptr long ptr long ptr long) +@ cdecl _wstat32(wstr ptr) +@ cdecl _wstat32i64(wstr ptr) +@ cdecl _wstat64(wstr ptr) +@ cdecl _wstat64i32(wstr ptr) +@ cdecl _wstrdate(ptr) +@ cdecl _wstrdate_s(ptr long) +@ cdecl _wstrtime(ptr) +@ cdecl _wstrtime_s(ptr long) +@ cdecl _wsystem(wstr) +@ cdecl _wtempnam(wstr wstr) +@ cdecl -dbg _wtempnam_dbg(wstr wstr long str long) +@ cdecl _wtmpnam(ptr) +@ cdecl _wtmpnam_s(ptr long) +@ cdecl _wtof(wstr) +@ cdecl _wtof_l(wstr ptr) +@ cdecl _wtoi(wstr) +@ cdecl -ret64 _wtoi64(wstr) +@ cdecl -ret64 _wtoi64_l(wstr ptr) +@ cdecl _wtoi_l(wstr ptr) +@ cdecl _wtol(wstr) +@ cdecl _wtol_l(wstr ptr) +@ cdecl -ret64 _wtoll(wstr) +@ cdecl -ret64 _wtoll_l(wstr ptr) +@ cdecl _wunlink(wstr) +@ cdecl _wutime32(wstr ptr) +@ cdecl _wutime64(wstr ptr) +@ cdecl _y0(double) +@ cdecl _y1(double) +@ cdecl _yn(long double) +@ cdecl abort() +@ cdecl abs(long) +@ cdecl acos(double) +@ cdecl -arch=!i386 acosf(float) +@ cdecl -stub acosh(double) +@ cdecl -stub acoshf(float) +@ cdecl -stub acoshl(double) +@ cdecl asctime(ptr) +@ cdecl asctime_s(ptr long ptr) +@ cdecl asin(double) +@ cdecl -arch=!i386 asinf(float) +@ cdecl -stub asinh(double) +@ cdecl -stub asinhf(float) +@ cdecl -stub asinhl(double) asinh +@ cdecl atan(double) +@ cdecl atan2(double double) +@ cdecl -arch=!i386 atan2f(float float) +@ cdecl -arch=!i386 atanf(float) +@ cdecl -stub atanh(double) +@ cdecl -stub atanhf(float) +@ cdecl -stub atanhl(double) +@ cdecl atof(str) +@ cdecl atoi(str) +@ cdecl atol(str) +@ cdecl -ret64 atoll(str) +@ cdecl bsearch(ptr ptr long long ptr) +@ cdecl bsearch_s(ptr ptr long long ptr ptr) +@ cdecl btowc(long) +@ cdecl c16rtomb(ptr long ptr) +@ cdecl c32rtomb(ptr long ptr) +@ stub cabs +@ stub cabsf +@ stub cabsl +@ stub cacos +@ stub cacosf +@ stub cacosh +@ stub cacoshf +@ stub cacoshl +@ stub cacosl +@ cdecl calloc(long long) +@ stub carg +@ stub cargf +@ stub cargl +@ stub casin +@ stub casinf +@ stub casinh +@ stub casinhf +@ stub casinhl +@ stub casinl +@ stub catan +@ stub catanf +@ stub catanh +@ stub catanhf +@ stub catanhl +@ stub catanl +@ cdecl -stub cbrt(double) +@ cdecl -stub cbrtf(float) +@ cdecl -stub cbrtl(double) cbrt +@ stub ccos +@ stub ccosf +@ stub ccosh +@ stub ccoshf +@ stub ccoshl +@ stub ccosl +@ cdecl ceil(double) +@ cdecl -arch=!i386 ceilf(float) +@ stub cexp +@ stub cexpf +@ stub cexpl +@ stub cimag +@ stub cimagf +@ stub cimagl +@ cdecl clearerr(ptr) +@ cdecl clearerr_s(ptr) +@ cdecl clock() +@ stub clog +@ stub clog10 +@ stub clog10f +@ stub clog10l +@ stub clogf +@ stub clogl +@ stub conj +@ stub conjf +@ stub conjl +@ cdecl -stub copysign(double double) +@ cdecl -stub copysignf(float float) +@ cdecl -stub copysignl(double double) copysign +@ cdecl cos(double) +@ cdecl -arch=!i386 cosf(float) +@ cdecl cosh(double) +@ cdecl -arch=!i386 coshf(float) +@ stub cpow +@ stub cpowf +@ stub cpowl +@ stub cproj +@ stub cprojf +@ stub cprojl +@ cdecl -stub creal(int128) +@ stub crealf +@ stub creall +@ stub csin +@ stub csinf +@ stub csinh +@ stub csinhf +@ stub csinhl +@ stub csinl +@ stub csqrt +@ stub csqrtf +@ stub csqrtl +@ stub ctan +@ stub ctanf +@ stub ctanh +@ stub ctanhf +@ stub ctanhl +@ stub ctanl +@ cdecl -ret64 div(long long) +@ cdecl -stub erf(double) +@ cdecl -stub erfc(double) +@ cdecl -stub erfcf(float) +@ cdecl -stub erfcl(double) erfc +@ cdecl -stub erff(float) +@ cdecl -stub erfl(double) erf +@ cdecl exit(long) +@ cdecl exp(double) +@ cdecl exp2(double) +@ cdecl exp2f(float) +@ cdecl exp2l(double) exp2 +@ cdecl -arch=!i386 expf(float) +@ cdecl -stub expm1(double) +@ cdecl -stub expm1f(float) +@ cdecl expm1l(double) expm1 +@ cdecl fabs(double) +@ cdecl -stub -arch=arm,arm64 fabsf(float) +@ cdecl fclose(ptr) +@ cdecl -stub fdim(double double) +@ cdecl -stub fdimf(float float) +@ cdecl fdiml(double double) fdim +@ cdecl -stub feclearexcept(long) +@ cdecl -stub fegetenv(ptr) +@ cdecl -stub fegetexceptflag(ptr long) +@ cdecl -stub fegetround() +@ cdecl -stub feholdexcept(ptr) +@ cdecl feof(ptr) +@ cdecl ferror(ptr) +@ cdecl -stub fesetenv(ptr) +@ cdecl -stub fesetexceptflag(ptr long) +@ cdecl -stub fesetround(long) +@ cdecl -stub fetestexcept(long) +@ cdecl fflush(ptr) +@ cdecl fgetc(ptr) +@ cdecl fgetpos(ptr ptr) +@ cdecl fgets(ptr long ptr) +@ cdecl fgetwc(ptr) +@ cdecl fgetws(ptr long ptr) +@ cdecl floor(double) +@ cdecl -arch=!i386 floorf(float) +@ cdecl fma(double double double) +@ cdecl fmaf(float float float) +@ cdecl fmal(double double double) fma +@ cdecl -stub fmax(double double) +@ cdecl -stub fmaxf(float float) +@ cdecl fmaxl(double double) fmax +@ cdecl -stub fmin(double double) +@ cdecl -stub fminf(float float) +@ cdecl fminl(double double) fmin +@ cdecl fmod(double double) +@ cdecl -arch=!i386 fmodf(float float) +@ cdecl fopen(str str) +@ cdecl fopen_s(ptr str str) +@ cdecl fputc(long ptr) +@ cdecl fputs(str ptr) +@ cdecl fputwc(long ptr) +@ cdecl fputws(wstr ptr) +@ cdecl fread(ptr long long ptr) +@ cdecl fread_s(ptr long long long ptr) +@ cdecl free(ptr) +@ cdecl freopen(str str ptr) +@ cdecl freopen_s(ptr str str ptr) +@ cdecl frexp(double ptr) +@ cdecl fseek(ptr long long) +@ cdecl fsetpos(ptr ptr) +@ cdecl ftell(ptr) +@ cdecl fwrite(ptr long long ptr) +@ cdecl getc(ptr) +@ cdecl getchar() +@ cdecl getenv(str) +@ cdecl getenv_s(ptr ptr long str) +@ cdecl gets(str) +@ cdecl gets_s(ptr long) +@ cdecl getwc(ptr) +@ cdecl getwchar() +@ cdecl hypot(double double) _hypot +@ cdecl -stub ilogb(double) +@ cdecl -stub ilogbf(float) +@ cdecl ilogbl(double) ilogb +@ cdecl -ret64 imaxabs(int64) +@ cdecl -ret64 imaxdiv(int64 int64) +@ cdecl is_wctype(long long) +@ cdecl isalnum(long) +@ cdecl isalpha(long) +@ cdecl isblank(long) +@ cdecl iscntrl(long) +@ cdecl isdigit(long) +@ cdecl isgraph(long) +@ cdecl isleadbyte(long) +@ cdecl islower(long) +@ cdecl isprint(long) +@ cdecl ispunct(long) +@ cdecl isspace(long) +@ cdecl isupper(long) +@ cdecl iswalnum(long) +@ cdecl iswalpha(long) +@ cdecl iswascii(long) +@ cdecl iswblank(long) +@ cdecl iswcntrl(long) +@ cdecl iswctype(long long) +@ cdecl iswdigit(long) +@ cdecl iswgraph(long) +@ cdecl iswlower(long) +@ cdecl iswprint(long) +@ cdecl iswpunct(long) +@ cdecl iswspace(long) +@ cdecl iswupper(long) +@ cdecl iswxdigit(long) +@ cdecl isxdigit(long) +@ cdecl labs(long) +@ cdecl ldexp(double long) +@ cdecl -ret64 ldiv(long long) +@ cdecl -stub lgamma(double) +@ cdecl -stub lgammaf(float) +@ cdecl lgammal(double) lgamma +@ cdecl -ret64 llabs(int64) +@ cdecl -norelay lldiv(int64 int64) +@ cdecl -stub -ret64 llrint(double) +@ cdecl -stub -ret64 llrintf(float) +@ cdecl -ret64 llrintl(double) llrint +@ cdecl -stub -ret64 llround(double) +@ cdecl -stub -ret64 llroundf(float) +@ cdecl -ret64 llroundl(double) llround +@ cdecl localeconv() +@ cdecl log(double) +@ cdecl log10(double) +@ cdecl -arch=!i386 log10f(float) +@ cdecl -stub log1p(double) +@ cdecl -stub log1pf(float) +@ cdecl log1pl(double) log1p +@ cdecl log2(double) +@ cdecl log2f(float) +@ cdecl log2l(double) log2 +@ cdecl -stub logb(double) +@ cdecl -stub logbf(float) +@ cdecl logbl(double) logb +@ cdecl -arch=!i386 logf(float) +@ cdecl longjmp(ptr long) +@ cdecl lrint(double) +@ cdecl lrintf(float) +@ cdecl lrintl(double) lrint +@ cdecl -stub lround(double) +@ cdecl -stub lroundf(float) +@ cdecl lroundl(double) lround +@ cdecl malloc(long) +@ cdecl mblen(ptr long) +@ cdecl mbrlen(ptr long ptr) +@ cdecl mbrtoc16(ptr ptr long) +@ cdecl mbrtoc32(ptr ptr long) +@ cdecl mbrtowc(ptr str long ptr) +@ cdecl mbsrtowcs(ptr ptr long ptr) +@ cdecl mbsrtowcs_s(ptr ptr long ptr long ptr) +@ cdecl mbstowcs(ptr str long) +@ cdecl mbstowcs_s(ptr ptr long str long) +@ cdecl mbtowc(ptr str long) +@ cdecl memchr(ptr long long) +@ cdecl memcmp(ptr ptr long) +@ cdecl memcpy(ptr ptr long) +@ cdecl memcpy_s(ptr long ptr long) +@ cdecl memmove(ptr ptr long) +@ cdecl memmove_s(ptr long ptr long) +@ cdecl memset(ptr long long) +@ cdecl modf(double ptr) +@ cdecl -stub -arch=!i386 modff(float ptr) +@ cdecl -stub nan(str) +@ cdecl -stub nanf(str) +@ cdecl nanl(str) nan +@ cdecl -stub nearbyint(double) +@ cdecl -stub nearbyintf(float) +@ cdecl nearbyintl(double) nearbyint +@ cdecl -stub nextafter(double double) +@ cdecl -stub nextafterf(float float) +@ cdecl nextafterl(double double) nextafter +@ cdecl -stub nexttoward(double double) nexttoward +@ cdecl -stub nexttowardf(float double) nexttowardf +@ cdecl nexttowardl(double double) nexttoward +@ stub norm +@ stub normf +@ stub norml +@ cdecl perror(str) +@ cdecl pow(double double) +@ cdecl -arch=!i386 powf(float float) +@ cdecl putc(long ptr) +@ cdecl putchar(long) +@ cdecl puts(str) +@ cdecl putwc(long ptr) fputwc +@ cdecl putwchar(long) _fputwchar +@ cdecl qsort(ptr long long ptr) +@ cdecl qsort_s(ptr long long ptr ptr) +@ cdecl quick_exit(long) +@ cdecl raise(long) +@ cdecl rand() +@ cdecl rand_s(ptr) +@ cdecl realloc(ptr long) +@ cdecl -stub remainder(double double) +@ cdecl -stub remainderf(float float) +@ cdecl remainderl(double double) remainder +@ cdecl remove(str) +@ cdecl -stub remquo(double double ptr) +@ cdecl -stub remquof(float float ptr) +@ cdecl remquol(double double ptr) remquo +@ cdecl rename(str str) +@ cdecl rewind(ptr) +@ cdecl -stub rint(double) +@ cdecl -stub rintf(float) +@ cdecl rintl(double) rint +@ cdecl -stub round(double) +@ cdecl -stub roundf(float) +@ cdecl roundl(double) round +@ cdecl scalbln(double long) scalbn # double scalbln(double x, long exp); +@ cdecl scalblnf(float long) scalbnf # float scalblnf(float x, long exp); +@ cdecl scalblnl(double long) scalbn # long double scalblnl(long double x, long exp); +@ cdecl -stub scalbn(double long) # double scalbn(double x, int exp); +@ cdecl -stub scalbnf(float long) # float scalbnf(float x, int exp); +@ cdecl scalbnl(double long) scalbn # long double scalbnl(long double x, int exp); +@ cdecl set_terminate(ptr) +@ cdecl set_unexpected(ptr) +@ cdecl setbuf(ptr ptr) +@ cdecl -arch=arm,x86_64 -norelay -private setjmp(ptr ptr) _setjmp +@ cdecl setlocale(long str) +@ cdecl setvbuf(ptr str long long) +@ cdecl signal(long long) +@ cdecl sin(double) +@ cdecl -arch=!i386 sinf(float) +@ cdecl sinh(double) +@ cdecl -arch=!i386 sinhf(float) +@ cdecl sqrt(double) +@ cdecl -arch=!i386 sqrtf(float) +@ cdecl srand(long) +@ cdecl strcat(str str) +@ cdecl strcat_s(str long str) +@ cdecl strchr(str long) +@ cdecl strcmp(str str) +@ cdecl strcoll(str str) +@ cdecl strcpy(ptr str) +@ cdecl strcpy_s(ptr long str) +@ cdecl strcspn(str str) +@ cdecl strerror(long) +@ cdecl strerror_s(ptr long long) +@ cdecl strftime(ptr long str ptr) +@ cdecl strlen(str) +@ cdecl strncat(str str long) +@ cdecl strncat_s(str long str long) +@ cdecl strncmp(str str long) +@ cdecl strncpy(ptr str long) +@ cdecl strncpy_s(ptr long str long) +@ cdecl strnlen(str long) +@ cdecl strpbrk(str str) +@ cdecl strrchr(str long) +@ cdecl strspn(str str) +@ cdecl strstr(str str) +@ cdecl strtod(str ptr) +@ cdecl strtof(str ptr) +@ cdecl -ret64 strtoimax(str ptr long) _strtoi64 +@ cdecl strtok(str str) +@ cdecl strtok_s(ptr str ptr) +@ cdecl strtol(str ptr long) +@ cdecl strtold(str ptr) strtod +@ cdecl -ret64 strtoll(str ptr long) _strtoi64 +@ cdecl strtoul(str ptr long) +@ cdecl -ret64 strtoull(str ptr long) _strtoui64 +@ cdecl -ret64 strtoumax(str ptr long) _strtoui64 +@ cdecl strxfrm(ptr str long) +@ cdecl system(str) +@ cdecl tan(double) +@ cdecl -arch=!i386 tanf(float) +@ cdecl tanh(double) +@ cdecl -arch=!i386 tanhf(float) +@ cdecl terminate() +@ cdecl -stub tgamma(double) +@ cdecl -stub tgammaf(float) +@ cdecl tgammal(double) tgamma +@ cdecl tmpfile() +@ cdecl tmpfile_s(ptr) +@ cdecl tmpnam(ptr) +@ cdecl tmpnam_s(ptr long) +@ cdecl tolower(long) +@ cdecl toupper(long) +@ cdecl towctrans(long long) +@ cdecl towlower(long) +@ cdecl towupper(long) +@ cdecl -stub trunc(double) +@ cdecl -stub truncf(float) +@ cdecl truncl(double) trunc +@ stub unexpected +@ cdecl ungetc(long ptr) +@ cdecl ungetwc(long ptr) +@ cdecl wcrtomb(ptr long ptr) +@ cdecl wcrtomb_s(ptr ptr long long ptr) +@ cdecl wcscat(wstr wstr) +@ cdecl wcscat_s(wstr long wstr) +@ cdecl wcschr(wstr long) +@ cdecl wcscmp(wstr wstr) +@ cdecl wcscoll(wstr wstr) +@ cdecl wcscpy(ptr wstr) +@ cdecl wcscpy_s(ptr long wstr) +@ cdecl wcscspn(wstr wstr) +@ cdecl wcsftime(ptr long wstr ptr) +@ cdecl wcslen(wstr) +@ cdecl wcsncat(wstr wstr long) +@ cdecl wcsncat_s(wstr long wstr long) +@ cdecl wcsncmp(wstr wstr long) +@ cdecl wcsncpy(ptr wstr long) +@ cdecl wcsncpy_s(ptr long wstr long) +@ cdecl wcsnlen(wstr long) +@ cdecl wcspbrk(wstr wstr) +@ cdecl wcsrchr(wstr long) +@ cdecl wcsrtombs(ptr ptr long ptr) +@ cdecl wcsrtombs_s(ptr ptr long ptr long ptr) +@ cdecl wcsspn(wstr wstr) +@ cdecl wcsstr(wstr wstr) +@ cdecl wcstod(wstr ptr) +@ cdecl wcstof(ptr ptr) +@ cdecl wcstoimax(wstr ptr long) +@ cdecl wcstok(wstr wstr ptr) +@ cdecl wcstok_s(ptr wstr ptr) +@ cdecl wcstol(wstr ptr long) +@ cdecl wcstold(wstr ptr) wcstod +@ cdecl -ret64 wcstoll(wstr ptr long) _wcstoi64 +@ cdecl wcstombs(ptr ptr long) +@ cdecl wcstombs_s(ptr ptr long wstr long) +@ cdecl wcstoul(wstr ptr long) +@ cdecl -ret64 wcstoull(wstr ptr long) _wcstoui64 +@ cdecl wcstoumax(wstr ptr long) +@ cdecl wcsxfrm(ptr wstr long) +@ cdecl wctob(long) +@ cdecl wctomb(ptr long) +@ cdecl wctomb_s(ptr ptr long long) +@ cdecl wctrans(str) +@ cdecl wctype(str) +@ cdecl wmemcpy_s(ptr long ptr long) +@ cdecl wmemmove_s(ptr long ptr long) diff --git a/dll/win32/updspapi/CMakeLists.txt b/dll/win32/updspapi/CMakeLists.txt index e27c628b3a463..bc6c9b4f5b406 100644 --- a/dll/win32/updspapi/CMakeLists.txt +++ b/dll/win32/updspapi/CMakeLists.txt @@ -1,6 +1,4 @@ -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) -add_definitions(-D__WINESRC__) spec2def(updspapi.dll updspapi.spec) list(APPEND SOURCE @@ -13,3 +11,4 @@ set_module_type(updspapi win32dll) target_link_libraries(updspapi wine) add_importlibs(updspapi setupapi msvcrt kernel32 ntdll) add_cd_file(TARGET updspapi DESTINATION reactos/system32 FOR all) +set_wine_module(updspapi) diff --git a/dll/win32/url/CMakeLists.txt b/dll/win32/url/CMakeLists.txt index 834b7ba87dfaf..05d73bfd7c048 100644 --- a/dll/win32/url/CMakeLists.txt +++ b/dll/win32/url/CMakeLists.txt @@ -1,6 +1,4 @@ -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) -add_definitions(-D__WINESRC__) spec2def(url.dll url.spec) list(APPEND SOURCE @@ -21,3 +19,4 @@ set_module_type(url win32dll) target_link_libraries(url wine) add_importlibs(url shell32 shlwapi msvcrt kernel32 ntdll) add_cd_file(TARGET url DESTINATION reactos/system32 FOR all) +set_wine_module(url) diff --git a/dll/win32/url/url_main.c b/dll/win32/url/url_main.c index aeaba70f2588c..d8dfdaff15b1b 100644 --- a/dll/win32/url/url_main.c +++ b/dll/win32/url/url_main.c @@ -38,8 +38,10 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved ) { switch(reason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls( inst ); break; diff --git a/dll/win32/urlmon/CMakeLists.txt b/dll/win32/urlmon/CMakeLists.txt index 6b5bef1759f64..43d3f7d8c4380 100644 --- a/dll/win32/urlmon/CMakeLists.txt +++ b/dll/win32/urlmon/CMakeLists.txt @@ -1,12 +1,11 @@ add_definitions( - -D__WINESRC__ -D_URLMON_ -DENTRY_PREFIX=URLMON_ -DPROXY_DELEGATION - -DWINE_REGISTER_DLL) + -DWINE_REGISTER_DLL + -DPROXY_CLSID_IS={0x79EAC9F1,0xBAF9,0x11CE,{0x8C,0x82,0x00,0xAA,0x00,0x4B,0xA9,0x0B}}) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(urlmon.dll urlmon.spec ADD_IMPORTLIB) add_rpcproxy_files(urlmon_urlmon.idl) @@ -55,3 +54,4 @@ add_delay_importlibs(urlmon advpack) add_importlibs(urlmon rpcrt4 propsys ole32 oleaut32 shlwapi shell32 wininet user32 advapi32 kernel32_vista msvcrt kernel32 ntdll) add_pch(urlmon precomp.h "${PCH_SKIP_SOURCE}") add_cd_file(TARGET urlmon DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(urlmon) # CORE-5743: No ARRAY_SIZE macro diff --git a/dll/win32/usp10/CMakeLists.txt b/dll/win32/usp10/CMakeLists.txt index 26dbe33ec7115..a9e174e8cc56c 100644 --- a/dll/win32/usp10/CMakeLists.txt +++ b/dll/win32/usp10/CMakeLists.txt @@ -1,6 +1,4 @@ -include_directories(BEFORE ${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) -add_definitions(-D__WINESRC__) spec2def(usp10.dll usp10.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -28,3 +26,4 @@ target_link_libraries(usp10 wine) add_importlibs(usp10 advapi32 user32 gdi32 msvcrt kernel32 ntdll) add_pch(usp10 precomp.h SOURCE) add_cd_file(TARGET usp10 DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(usp10) # CORE-5743: No ARRAY_SIZE macro diff --git a/dll/win32/uxtheme/CMakeLists.txt b/dll/win32/uxtheme/CMakeLists.txt index 92a6f0cb292e1..44ac0cd0eb461 100644 --- a/dll/win32/uxtheme/CMakeLists.txt +++ b/dll/win32/uxtheme/CMakeLists.txt @@ -6,6 +6,7 @@ spec2def(uxtheme.dll uxtheme.spec ADD_IMPORTLIB) list(APPEND SOURCE buffer.c draw.c + errinfo.c main.c metric.c msstyles.c diff --git a/dll/win32/uxtheme/errinfo.c b/dll/win32/uxtheme/errinfo.c new file mode 100644 index 0000000000000..40abe56e8021e --- /dev/null +++ b/dll/win32/uxtheme/errinfo.c @@ -0,0 +1,150 @@ +/* + * PROJECT: ReactOS uxtheme.dll + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: UXTHEME error reporting helpers + * COPYRIGHT: Copyright 2025 Katayama Hirofumi MZ + */ + +#include "uxthemep.h" +#include +#include + +PTMERRINFO +UXTHEME_GetParseErrorInfo(_In_ BOOL bCreate) +{ + PTMERRINFO pErrInfo; + + if (gdwErrorInfoTlsIndex == TLS_OUT_OF_INDEXES) + return NULL; + + pErrInfo = TlsGetValue(gdwErrorInfoTlsIndex); + if (pErrInfo) + return pErrInfo; + + if (bCreate) + { + pErrInfo = LocalAlloc(LPTR, sizeof(*pErrInfo)); + TlsSetValue(gdwErrorInfoTlsIndex, pErrInfo); + } + + return pErrInfo; +} + +VOID +UXTHEME_DeleteParseErrorInfo(VOID) +{ + PTMERRINFO pErrInfo = UXTHEME_GetParseErrorInfo(FALSE); + if (!pErrInfo) + return; + + TlsSetValue(gdwErrorInfoTlsIndex, NULL); + LocalFree(pErrInfo); +} + +static BOOL +UXTHEME_FormatLocalMsg( + _In_ HINSTANCE hInstance, + _In_ UINT uID, + _Out_ LPWSTR pszDest, + _In_ SIZE_T cchDest, + _In_ LPCWSTR pszDrive, + _In_ PTMERRINFO pErrInfo) +{ + WCHAR szFormat[MAX_PATH]; + LPCWSTR args[2] = { pErrInfo->szParam1, pErrInfo->szParam2 }; + + if (!LoadStringW(hInstance, uID, szFormat, _countof(szFormat)) || !szFormat[0]) + return FALSE; + + return FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, + szFormat, 0, 0, pszDest, cchDest, (va_list *)args) != 0; +} + +static HRESULT +UXTHEME_FormatParseMessage( + _In_ PTMERRINFO pErrInfo, + _Out_ LPWSTR pszDest, + _In_ SIZE_T cchDest) +{ + DWORD nID; + HMODULE hMod, hUxTheme; + WCHAR szFullPath[_MAX_PATH]; + WCHAR szDrive[_MAX_DRIVE + 1], szDir[_MAX_DIR], szFileName[_MAX_FNAME], szExt[_MAX_EXT]; + BOOL ret; + HRESULT hr; + + nID = LOWORD(pErrInfo->nID); + if (!GetModuleFileNameW(NULL, szFullPath, _countof(szFullPath))) + return S_OK; + + _wsplitpath(szFullPath, szDrive, szDir, szFileName, szExt); + if (lstrcmpiW(szFileName, L"packthem") == 0) + { + hMod = GetModuleHandleW(NULL); + if (UXTHEME_FormatLocalMsg(hMod, nID, pszDest, cchDest, szDrive, pErrInfo)) + return S_OK; + } + + hUxTheme = LoadLibraryW(L"uxtheme.dll"); + if (!hUxTheme) + return E_FAIL; + + ret = UXTHEME_FormatLocalMsg(hUxTheme, nID, pszDest, cchDest, szDrive, pErrInfo); + hr = (ret ? S_OK : UXTHEME_MakeLastError()); + FreeLibrary(hUxTheme); + + return hr; +} + +// Parser should use this function on failure +HRESULT +UXTHEME_MakeParseError( + _In_ UINT nID, + _In_ LPCWSTR pszParam1, + _In_ LPCWSTR pszParam2, + _In_ LPCWSTR pszFile, + _In_ LPCWSTR pszLine, + _In_ INT nLineNo) +{ + PTMERRINFO pErrInfo = UXTHEME_GetParseErrorInfo(TRUE); + if (pErrInfo) + { + pErrInfo->nID = nID; + pErrInfo->nLineNo = nLineNo; + StringCchCopyW(pErrInfo->szParam1, _countof(pErrInfo->szParam1), pszParam1); + StringCchCopyW(pErrInfo->szParam2, _countof(pErrInfo->szParam2), pszParam2); + StringCchCopyW(pErrInfo->szFile, _countof(pErrInfo->szFile), pszFile); + StringCchCopyW(pErrInfo->szLine, _countof(pErrInfo->szLine), pszLine); + } + return HRESULT_FROM_WIN32(ERROR_UNKNOWN_PROPERTY); +} + +/************************************************************************* + * GetThemeParseErrorInfo (UXTHEME.48) + */ +HRESULT WINAPI +GetThemeParseErrorInfo(_Inout_ PPARSE_ERROR_INFO pInfo) +{ + PTMERRINFO pErrInfo; + HRESULT hr; + + if (!pInfo) + return E_POINTER; + + if (pInfo->cbSize != sizeof(*pInfo)) + return E_INVALIDARG; + + pErrInfo = UXTHEME_GetParseErrorInfo(TRUE); + if (!pErrInfo) + return E_OUTOFMEMORY; + + hr = UXTHEME_FormatParseMessage(pErrInfo, pInfo->szDescription, _countof(pInfo->szDescription)); + if (FAILED(hr)) + return hr; + + pInfo->nID = pErrInfo->nID; + pInfo->nLineNo = pErrInfo->nLineNo; + StringCchCopyW(pInfo->szFile, _countof(pInfo->szFile), pErrInfo->szFile); + StringCchCopyW(pInfo->szLine, _countof(pInfo->szLine), pErrInfo->szLine); + return hr; +} diff --git a/dll/win32/uxtheme/main.c b/dll/win32/uxtheme/main.c index 4eb6eb337615f..9c86347e2bc61 100644 --- a/dll/win32/uxtheme/main.c +++ b/dll/win32/uxtheme/main.c @@ -22,7 +22,6 @@ /***********************************************************************/ -/* For the moment, do nothing here. */ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) { TRACE("%p 0x%x %p: stub\n", hInstDLL, fdwReason, lpv); @@ -32,6 +31,12 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) UXTHEME_InitSystem(hInstDLL); break; case DLL_PROCESS_DETACH: + UXTHEME_UnInitSystem(hInstDLL); + break; + case DLL_THREAD_ATTACH: + break; + case DLL_THREAD_DETACH: + UXTHEME_DeleteParseErrorInfo(); break; } return TRUE; diff --git a/dll/win32/uxtheme/system.c b/dll/win32/uxtheme/system.c index eaf8faf924ca3..c998be4f120e8 100644 --- a/dll/win32/uxtheme/system.c +++ b/dll/win32/uxtheme/system.c @@ -24,6 +24,8 @@ #include #include +DWORD gdwErrorInfoTlsIndex = TLS_OUT_OF_INDEXES; + /*********************************************************************** * Defines and global variables */ @@ -588,6 +590,19 @@ void UXTHEME_InitSystem(HINSTANCE hInst) RtlInitializeHandleTable(0xFFF, sizeof(UXTHEME_HANDLE), &g_UxThemeHandleTable); g_cHandles = 0; + + gdwErrorInfoTlsIndex = TlsAlloc(); +} + +/*********************************************************************** + * UXTHEME_UnInitSystem + */ +void UXTHEME_UnInitSystem(HINSTANCE hInst) +{ + UXTHEME_DeleteParseErrorInfo(); + + TlsFree(gdwErrorInfoTlsIndex); + gdwErrorInfoTlsIndex = TLS_OUT_OF_INDEXES; } /*********************************************************************** diff --git a/dll/win32/uxtheme/uxtheme.spec b/dll/win32/uxtheme/uxtheme.spec index 632cfe84a00a3..17d90eef273aa 100644 --- a/dll/win32/uxtheme/uxtheme.spec +++ b/dll/win32/uxtheme/uxtheme.spec @@ -45,7 +45,7 @@ 45 stdcall -noname ClassicSystemParametersInfoW(long long ptr long) 46 stdcall -noname ClassicAdjustWindowRectEx(ptr long long long) 47 stdcall DrawThemeBackgroundEx(ptr ptr long long ptr ptr) -48 stub -noname GetThemeParseErrorInfo +48 stdcall -noname GetThemeParseErrorInfo(ptr) 49 stdcall GetThemeAppProperties() 50 stdcall GetThemeBackgroundContentRect(ptr ptr long long ptr ptr) 51 stdcall GetThemeBackgroundExtent(ptr ptr long long ptr ptr) diff --git a/dll/win32/uxtheme/uxthemep.h b/dll/win32/uxtheme/uxthemep.h index 5a047d7fcddb7..71c4da68aaa09 100644 --- a/dll/win32/uxtheme/uxthemep.h +++ b/dll/win32/uxtheme/uxthemep.h @@ -90,6 +90,16 @@ typedef struct _THEME_FILE { PTHEME_IMAGE images; } THEME_FILE, *PTHEME_FILE; +typedef struct tagTMERRINFO +{ + UINT nID; + WCHAR szParam1[MAX_PATH]; + WCHAR szParam2[MAX_PATH]; + WCHAR szFile[MAX_PATH]; + WCHAR szLine[MAX_PATH]; + INT nLineNo; +} TMERRINFO, *PTMERRINFO; + typedef struct _UXINI_FILE *PUXINI_FILE; typedef struct _UXTHEME_HANDLE @@ -276,6 +286,7 @@ extern ATOM atWndContext; extern BOOL g_bThemeHooksActive; void UXTHEME_InitSystem(HINSTANCE hInst); +void UXTHEME_UnInitSystem(HINSTANCE hInst); void UXTHEME_LoadTheme(BOOL bLoad); BOOL CALLBACK UXTHEME_broadcast_theme_changed (HWND hWnd, LPARAM enable); @@ -286,4 +297,33 @@ BOOL CALLBACK UXTHEME_broadcast_theme_changed (HWND hWnd, LPARAM enable); /* Full alpha blending */ #define ALPHABLEND_FULL 2 +extern DWORD gdwErrorInfoTlsIndex; + +VOID UXTHEME_DeleteParseErrorInfo(VOID); + +static inline +HRESULT +UXTHEME_MakeError(_In_ LONG error) +{ + if (error < 0) + return (HRESULT)error; + return HRESULT_FROM_WIN32(error); +} + +static inline +HRESULT +UXTHEME_MakeLastError(VOID) +{ + return UXTHEME_MakeError(GetLastError()); +} + +HRESULT +UXTHEME_MakeParseError( + _In_ UINT nID, + _In_ LPCWSTR pszParam1, + _In_ LPCWSTR pszParam2, + _In_ LPCWSTR pszFile, + _In_ LPCWSTR pszLine, + _In_ INT nLineNo); + #endif /* _UXTHEME_PCH_ */ diff --git a/dll/win32/vbscript/CMakeLists.txt b/dll/win32/vbscript/CMakeLists.txt index d6664cd54785b..0fa203090fc17 100644 --- a/dll/win32/vbscript/CMakeLists.txt +++ b/dll/win32/vbscript/CMakeLists.txt @@ -1,6 +1,5 @@ -add_definitions(-D__WINESRC__ -D__ROS_LONG64__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) +add_definitions(-D__ROS_LONG64__) spec2def(vbscript.dll vbscript.spec) list(APPEND SOURCE @@ -50,3 +49,4 @@ add_importlibs(vbscript oleaut32 ole32 user32 msvcrt kernel32 ntdll) add_dependencies(vbscript vbscript_idlheader stdole2) add_pch(vbscript precomp.h "${PCH_SKIP_SOURCE}") add_cd_file(TARGET vbscript DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(vbscript) # CORE-5743: No ARRAY_SIZE and CONST_VTABLE diff --git a/dll/win32/vbscript/vbscript_main.c b/dll/win32/vbscript/vbscript_main.c index 6e6f38675595e..62da59975e318 100644 --- a/dll/win32/vbscript/vbscript_main.c +++ b/dll/win32/vbscript/vbscript_main.c @@ -248,8 +248,10 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) switch(fdwReason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hInstDLL); vbscript_hinstance = hInstDLL; diff --git a/dll/win32/verifier/verifier.c b/dll/win32/verifier/verifier.c index e27f78461039d..446eb45357a49 100644 --- a/dll/win32/verifier/verifier.c +++ b/dll/win32/verifier/verifier.c @@ -87,7 +87,7 @@ BOOL WINAPI DllMain(HANDLE hInstance, DWORD dwReason, LPVOID lpReserved) VOID NTAPI AVrfpDllLoadCallback(PWSTR DllName, PVOID DllBase, SIZE_T DllSize, PVOID Reserved) { PLDR_DATA_TABLE_ENTRY LdrEntry = (PLDR_DATA_TABLE_ENTRY)Reserved; - DbgPrint(PROVIDER_PREFIX ": %ws @ %p: ep: %p\n", DllName, DllBase, LdrEntry->EntryPoint); + DbgPrint(PROVIDER_PREFIX ": loading %ws @ %p: ep: %p\n", DllName, DllBase, LdrEntry->EntryPoint); /* TODO: Hook entrypoint */ } diff --git a/dll/win32/vssapi/CMakeLists.txt b/dll/win32/vssapi/CMakeLists.txt index 744f9da9119aa..04fbbd0af5610 100644 --- a/dll/win32/vssapi/CMakeLists.txt +++ b/dll/win32/vssapi/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(BEFORE ${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(vssapi.dll vssapi.spec) list(APPEND SOURCE @@ -17,3 +15,4 @@ set_module_type(vssapi win32dll) target_link_libraries(vssapi wine) add_importlibs(vssapi msvcrt kernel32 ntdll) add_cd_file(TARGET vssapi DESTINATION reactos/system32 FOR all) +set_wine_module(vssapi) diff --git a/dll/win32/wbemdisp/CMakeLists.txt b/dll/win32/wbemdisp/CMakeLists.txt index 0b6857472ab83..1f9022d006e35 100644 --- a/dll/win32/wbemdisp/CMakeLists.txt +++ b/dll/win32/wbemdisp/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(wbemdisp.dll wbemdisp.spec) list(APPEND SOURCE @@ -32,3 +30,4 @@ add_dependencies(wbemdisp stdole2 wbemdisp_idlheader) add_importlibs(wbemdisp oleaut32 ole32 msvcrt kernel32 ntdll) add_pch(wbemdisp precomp.h "${PCH_SKIP_SOURCE}") add_cd_file(TARGET wbemdisp DESTINATION reactos/system32/wbem FOR all) +set_wine_module_FIXME(wbemdisp) # CORE-5743: No ARRAY_SIZE and CONST_VTABLE diff --git a/dll/win32/wbemdisp/main.c b/dll/win32/wbemdisp/main.c index f434eecb353d1..e64a7d7c5e33a 100644 --- a/dll/win32/wbemdisp/main.c +++ b/dll/win32/wbemdisp/main.c @@ -512,8 +512,10 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved ) switch (reason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: instance = hinst; DisableThreadLibraryCalls( hinst ); diff --git a/dll/win32/wdmaud.drv/mmixer.c b/dll/win32/wdmaud.drv/mmixer.c index f4f0fbd09ef10..47848b9616b46 100644 --- a/dll/win32/wdmaud.drv/mmixer.c +++ b/dll/win32/wdmaud.drv/mmixer.c @@ -349,7 +349,7 @@ WdmAudInitUserModeMixer() DeviceHandle = SetupDiGetClassDevs(&CategoryGuid, NULL, NULL, - DIGCF_DEVICEINTERFACE/* FIXME |DIGCF_PRESENT*/); + DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); if (DeviceHandle == INVALID_HANDLE_VALUE) { diff --git a/dll/win32/windowscodecs/CMakeLists.txt b/dll/win32/windowscodecs/CMakeLists.txt index ee7ff716e3bc3..00e61d0784bfa 100644 --- a/dll/win32/windowscodecs/CMakeLists.txt +++ b/dll/win32/windowscodecs/CMakeLists.txt @@ -1,16 +1,14 @@ add_definitions( - -D__WINESRC__ - -D__ROS_LONG64__ -DENTRY_PREFIX=WIC_ -DPROXY_DELEGATION -DWINE_REGISTER_DLL) remove_definitions(-D_WIN32_WINNT=0x502) +remove_definitions(-D_CRT_NON_CONFORMING_SWPRINTFS) add_definitions(-D_WIN32_WINNT=0x600) include_directories( - BEFORE ${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine ${REACTOS_SOURCE_DIR}/sdk/include/reactos/libs/libjpeg ${REACTOS_SOURCE_DIR}/sdk/include/reactos/libs/zlib ${REACTOS_SOURCE_DIR}/sdk/include/reactos/libs/libpng @@ -27,13 +25,17 @@ list(APPEND SOURCE colorcontext.c colortransform.c converter.c + ddsformat.c + decoder.c + encoder.c fliprotate.c gifformat.c - icnsformat.c icoformat.c imgfactory.c info.c - jpegformat.c + libjpeg.c + libpng.c + libtiff.c main.c metadatahandler.c metadataquery.c @@ -45,8 +47,9 @@ list(APPEND SOURCE scaler.c stream.c tgaformat.c - tiffformat.c - ungif.c) + ungif.c + uuid.c + wincodecs_common.c) if(MSVC) if(ARCH STREQUAL "i386") @@ -79,7 +82,8 @@ if(MSVC) endif() set_module_type(windowscodecs win32dll) -target_link_libraries(windowscodecs wine uuid ${PSEH_LIB}) -add_importlibs(windowscodecs ole32 oleaut32 rpcrt4 shlwapi user32 gdi32 advapi32 advapi32_vista propsys msvcrt kernel32 ntdll) +target_link_libraries(windowscodecs wine uuid ${PSEH_LIB} oldnames) +add_importlibs(windowscodecs libjpeg libpng libtiff ole32 oleaut32 rpcrt4 shlwapi user32 gdi32 advapi32 advapi32_vista propsys msvcrt kernel32 ntdll) add_pch(windowscodecs precomp.h "${PCH_SKIP_SOURCE}") add_cd_file(TARGET windowscodecs DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(windowscodecs) # CORE-5743: No CONST_VTABLE diff --git a/dll/win32/windowscodecs/bitmap.c b/dll/win32/windowscodecs/bitmap.c index 7959da6911da8..dee3f28d5d7e5 100644 --- a/dll/win32/windowscodecs/bitmap.c +++ b/dll/win32/windowscodecs/bitmap.c @@ -17,10 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#ifndef __REACTOS__ -#include "config.h" -#endif - #include #define COBJMACROS @@ -34,6 +30,9 @@ #include "wine/asm.h" #include "wine/debug.h" +#include "initguid.h" +DEFINE_GUID(IID_CMetaBitmapRenderTarget, 0x0ccd7824,0xdc16,0x4d09,0xbc,0xa8,0x6b,0x09,0xc4,0xef,0x55,0x35); + WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); /* WARNING: .NET Media Integration Layer (MIL) directly dereferences @@ -82,11 +81,6 @@ static inline BitmapImpl *impl_from_IMILUnknown1(IMILUnknown1 *iface) return CONTAINING_RECORD(iface, BitmapImpl, IMILUnknown1_iface); } -static inline BitmapImpl *impl_from_IMILUnknown2(IMILUnknown2 *iface) -{ - return CONTAINING_RECORD(iface, BitmapImpl, IMILUnknown2_iface); -} - static inline BitmapLockImpl *impl_from_IWICBitmapLock(IWICBitmapLock *iface) { return CONTAINING_RECORD(iface, BitmapLockImpl, IWICBitmapLock_iface); @@ -155,7 +149,7 @@ static ULONG WINAPI BitmapLockImpl_AddRef(IWICBitmapLock *iface) BitmapLockImpl *This = impl_from_IWICBitmapLock(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -165,13 +159,13 @@ static ULONG WINAPI BitmapLockImpl_Release(IWICBitmapLock *iface) BitmapLockImpl *This = impl_from_IWICBitmapLock(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { BitmapImpl_ReleaseLock(This->parent); IWICBitmap_Release(&This->parent->IWICBitmap_iface); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; @@ -262,7 +256,10 @@ static HRESULT WINAPI BitmapImpl_QueryInterface(IWICBitmap *iface, REFIID iid, } else { - FIXME("unknown interface %s\n", debugstr_guid(iid)); + if (IsEqualIID(&IID_CMetaBitmapRenderTarget, iid)) + WARN("Ignoring interface %s\n", debugstr_guid(iid)); + else + FIXME("unknown interface %s\n", debugstr_guid(iid)); *ppv = NULL; return E_NOINTERFACE; } @@ -276,7 +273,7 @@ static ULONG WINAPI BitmapImpl_AddRef(IWICBitmap *iface) BitmapImpl *This = impl_from_IWICBitmap(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -286,7 +283,7 @@ static ULONG WINAPI BitmapImpl_Release(IWICBitmap *iface) BitmapImpl *This = impl_from_IWICBitmap(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { @@ -296,8 +293,8 @@ static ULONG WINAPI BitmapImpl_Release(IWICBitmap *iface) if (This->view) UnmapViewOfFile(This->view); else - HeapFree(GetProcessHeap(), 0, This->data); - HeapFree(GetProcessHeap(), 0, This); + free(This->data); + free(This); } return ref; @@ -378,7 +375,7 @@ static HRESULT WINAPI BitmapImpl_Lock(IWICBitmap *iface, const WICRect *prcLock, BitmapLockImpl *result; WICRect rc; - TRACE("(%p,%s,%x,%p)\n", iface, debug_wic_rect(prcLock), flags, ppILock); + TRACE("(%p,%s,%lx,%p)\n", iface, debug_wic_rect(prcLock), flags, ppILock); if (!(flags & (WICBitmapLockRead|WICBitmapLockWrite)) || !ppILock) return E_INVALIDARG; @@ -401,13 +398,13 @@ static HRESULT WINAPI BitmapImpl_Lock(IWICBitmap *iface, const WICRect *prcLock, return E_FAIL; } - result = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapLockImpl)); + result = malloc(sizeof(BitmapLockImpl)); if (!result) return E_OUTOFMEMORY; if (!BitmapImpl_AcquireLock(This, flags & WICBitmapLockWrite)) { - HeapFree(GetProcessHeap(), 0, result); + free(result); return WINCODEC_ERR_ALREADYLOCKED; } @@ -605,7 +602,7 @@ static HRESULT WINAPI IMILBitmapImpl_unknown1(IMILBitmap *iface, void **ppv) static HRESULT WINAPI IMILBitmapImpl_Lock(IMILBitmap *iface, const WICRect *rc, DWORD flags, IWICBitmapLock **lock) { BitmapImpl *This = impl_from_IMILBitmap(iface); - TRACE("(%p,%p,%08x,%p)\n", iface, rc, flags, lock); + TRACE("(%p,%p,%08lx,%p)\n", iface, rc, flags, lock); return IWICBitmap_Lock(&This->IWICBitmap_iface, rc, flags, lock); } @@ -675,7 +672,7 @@ static ULONG WINAPI IMILUnknown1Impl_Release(IMILUnknown1 *iface) return IWICBitmap_Release(&This->IWICBitmap_iface); } -DECLSPEC_HIDDEN void WINAPI IMILUnknown1Impl_unknown1(IMILUnknown1 *iface, void *arg) +void WINAPI IMILUnknown1Impl_unknown1(IMILUnknown1 *iface, void *arg) { FIXME("(%p,%p): stub\n", iface, arg); } @@ -686,7 +683,7 @@ static HRESULT WINAPI IMILUnknown1Impl_unknown2(IMILUnknown1 *iface, void *arg1, return E_NOTIMPL; } -DECLSPEC_HIDDEN HRESULT WINAPI IMILUnknown1Impl_unknown3(IMILUnknown1 *iface, void *arg) +HRESULT WINAPI IMILUnknown1Impl_unknown3(IMILUnknown1 *iface, void *arg) { FIXME("(%p,%p): stub\n", iface, arg); return E_NOTIMPL; @@ -716,7 +713,7 @@ static HRESULT WINAPI IMILUnknown1Impl_unknown7(IMILUnknown1 *iface, void *arg) return E_NOTIMPL; } -DECLSPEC_HIDDEN HRESULT WINAPI IMILUnknown1Impl_unknown8(IMILUnknown1 *iface) +HRESULT WINAPI IMILUnknown1Impl_unknown8(IMILUnknown1 *iface) { FIXME("(%p): stub\n", iface); return E_NOTIMPL; @@ -808,13 +805,13 @@ HRESULT BitmapImpl_Create(UINT uiWidth, UINT uiHeight, UINT stride, UINT datasiz if (datasize < stride * uiHeight) return WINCODEC_ERR_INSUFFICIENTBUFFER; if (stride < ((bpp*uiWidth)+7)/8) return E_INVALIDARG; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapImpl)); + This = malloc(sizeof(BitmapImpl)); if (!This) return E_OUTOFMEMORY; if (view) data = (BYTE *)view + offset; - else if (!(data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, datasize))) + else if (!(data = calloc(1, datasize))) { - HeapFree(GetProcessHeap(), 0, This); + free(This); return E_OUTOFMEMORY; } @@ -835,7 +832,11 @@ HRESULT BitmapImpl_Create(UINT uiWidth, UINT uiHeight, UINT stride, UINT datasiz This->bpp = bpp; memcpy(&This->pixelformat, pixelFormat, sizeof(GUID)); This->dpix = This->dpiy = 0.0; +#ifdef __REACTOS__ InitializeCriticalSection(&This->cs); +#else + InitializeCriticalSectionEx(&This->cs, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif This->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": BitmapImpl.lock"); *ppIBitmap = &This->IWICBitmap_iface; diff --git a/dll/win32/windowscodecs/bmpdecode.c b/dll/win32/windowscodecs/bmpdecode.c index 5ee4ac38ccbf1..9eb74b3d7cce2 100644 --- a/dll/win32/windowscodecs/bmpdecode.c +++ b/dll/win32/windowscodecs/bmpdecode.c @@ -16,8 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" - #include #include @@ -226,9 +224,9 @@ static HRESULT WINAPI BmpFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface, int i; count = 1 << bch->bcBitCount; - wiccolors = HeapAlloc(GetProcessHeap(), 0, sizeof(WICColor) * count); + wiccolors = malloc(sizeof(WICColor) * count); tablesize = sizeof(RGBTRIPLE) * count; - bgrcolors = HeapAlloc(GetProcessHeap(), 0, tablesize); + bgrcolors = malloc(tablesize); if (!wiccolors || !bgrcolors) { hr = E_OUTOFMEMORY; @@ -274,7 +272,7 @@ static HRESULT WINAPI BmpFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface, count = min(This->bih.bV5ClrUsed, 1 << This->bih.bV5BitCount); tablesize = sizeof(WICColor) * count; - wiccolors = HeapAlloc(GetProcessHeap(), 0, tablesize); + wiccolors = malloc(tablesize); if (!wiccolors) { hr = E_OUTOFMEMORY; @@ -310,8 +308,8 @@ static HRESULT WINAPI BmpFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface, if (SUCCEEDED(hr)) hr = IWICPalette_InitializeCustom(pIPalette, wiccolors, count); - HeapFree(GetProcessHeap(), 0, wiccolors); - HeapFree(GetProcessHeap(), 0, bgrcolors); + free(wiccolors); + free(bgrcolors); return hr; } @@ -388,7 +386,7 @@ static HRESULT BmpFrameDecode_ReadUncompressed(BmpDecoder* This) bytesperrow = (((width * This->bitsperpixel)+31)/32)*4; datasize = bytesperrow * height; - This->imagedata = HeapAlloc(GetProcessHeap(), 0, datasize); + This->imagedata = malloc(datasize); if (!This->imagedata) return E_OUTOFMEMORY; offbits.QuadPart = This->image_offset; @@ -411,12 +409,45 @@ static HRESULT BmpFrameDecode_ReadUncompressed(BmpDecoder* This) return S_OK; fail: - HeapFree(GetProcessHeap(), 0, This->imagedata); + free(This->imagedata); This->imagedata = NULL; if (SUCCEEDED(hr)) hr = E_FAIL; return hr; } +static HRESULT BmpFrameDecode_ReadABGRasBGR(BmpDecoder* This) +{ + UINT x, y, width, height; + BYTE *pixel; + HRESULT hr; + + hr = IWICBitmapFrameDecode_GetSize(&This->IWICBitmapFrameDecode_iface, &width, &height); + + if (SUCCEEDED(hr)) + { + hr = BmpFrameDecode_ReadUncompressed(This); + } + + if (SUCCEEDED(hr)) + { + for (y = 0; y < height; y++) + { + pixel = This->imagedatastart + This->stride * (INT)y; + + for (x = 0; x < width; x++) + { + pixel[0] = pixel[1]; + pixel[1] = pixel[2]; + pixel[2] = pixel[3]; + pixel[3] = 0; + pixel += 4; + } + } + } + + return hr; +} + static HRESULT BmpFrameDecode_ReadRGB8(BmpDecoder* This) { HRESULT hr; @@ -482,7 +513,7 @@ static HRESULT BmpFrameDecode_ReadRLE8(BmpDecoder* This) else palettesize = 4 * 256; - This->imagedata = HeapAlloc(GetProcessHeap(), 0, datasize); + This->imagedata = malloc(datasize); if (!This->imagedata) { hr = E_OUTOFMEMORY; @@ -578,7 +609,7 @@ static HRESULT BmpFrameDecode_ReadRLE8(BmpDecoder* This) return S_OK; fail: - HeapFree(GetProcessHeap(), 0, This->imagedata); + free(This->imagedata); This->imagedata = NULL; if (SUCCEEDED(hr)) hr = E_FAIL; return hr; @@ -606,7 +637,7 @@ static HRESULT BmpFrameDecode_ReadRLE4(BmpDecoder* This) else palettesize = 4 * 16; - This->imagedata = HeapAlloc(GetProcessHeap(), 0, datasize); + This->imagedata = malloc(datasize); if (!This->imagedata) { hr = E_OUTOFMEMORY; @@ -718,7 +749,7 @@ static HRESULT BmpFrameDecode_ReadRLE4(BmpDecoder* This) return S_OK; fail: - HeapFree(GetProcessHeap(), 0, This->imagedata); + free(This->imagedata); This->imagedata = NULL; if (SUCCEEDED(hr)) hr = E_FAIL; return hr; @@ -744,7 +775,7 @@ static const struct bitfields_format bitfields_formats[] = { {16,0xf800,0x7e0,0x1f,0,&GUID_WICPixelFormat16bppBGR565,BmpFrameDecode_ReadUncompressed}, {32,0xff0000,0xff00,0xff,0,&GUID_WICPixelFormat32bppBGR,BmpFrameDecode_ReadUncompressed}, {32,0xff0000,0xff00,0xff,0xff000000,&GUID_WICPixelFormat32bppBGRA,BmpFrameDecode_ReadUncompressed}, - {32,0xff000000,0xff0000,0xff00,0xff,&GUID_WICPixelFormat32bppRGBA,BmpFrameDecode_ReadUncompressed}, + {32,0xff000000,0xff0000,0xff00,0xff,&GUID_WICPixelFormat32bppBGR,BmpFrameDecode_ReadABGRasBGR}, {32,0xff,0xff00,0xff0000,0,&GUID_WICPixelFormat32bppBGR,BmpFrameDecode_ReadRGB8}, {0} }; @@ -861,7 +892,7 @@ static HRESULT BmpDecoder_ReadHeaders(BmpDecoder* This, IStream *stream) } else /* struct is compatible with BITMAPINFOHEADER */ { - TRACE("bitmap header=%i compression=%i depth=%i\n", This->bih.bV5Size, This->bih.bV5Compression, This->bih.bV5BitCount); + TRACE("bitmap header=%li compression=%li depth=%i\n", This->bih.bV5Size, This->bih.bV5Compression, This->bih.bV5BitCount); switch(This->bih.bV5Compression) { case BI_RGB: @@ -935,7 +966,7 @@ static HRESULT BmpDecoder_ReadHeaders(BmpDecoder* This, IStream *stream) { This->read_data_func = BmpFrameDecode_ReadUncompressed; This->pixelformat = &GUID_WICPixelFormatUndefined; - FIXME("unsupported bitfields type depth=%i red=%x green=%x blue=%x alpha=%x\n", + FIXME("unsupported bitfields type depth=%i red=%lx green=%lx blue=%lx alpha=%lx\n", This->bih.bV5BitCount, This->bih.bV5RedMask, This->bih.bV5GreenMask, This->bih.bV5BlueMask, This->bih.bV5AlphaMask); } break; @@ -944,7 +975,7 @@ static HRESULT BmpDecoder_ReadHeaders(BmpDecoder* This, IStream *stream) This->bitsperpixel = 0; This->read_data_func = BmpFrameDecode_ReadUnsupported; This->pixelformat = &GUID_WICPixelFormatUndefined; - FIXME("unsupported bitmap type header=%i compression=%i depth=%i\n", This->bih.bV5Size, This->bih.bV5Compression, This->bih.bV5BitCount); + FIXME("unsupported bitmap type header=%li compression=%li depth=%i\n", This->bih.bV5Size, This->bih.bV5Compression, This->bih.bV5BitCount); break; } } @@ -999,7 +1030,7 @@ static ULONG WINAPI BmpDecoder_AddRef(IWICBitmapDecoder *iface) BmpDecoder *This = impl_from_IWICBitmapDecoder(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -1009,15 +1040,15 @@ static ULONG WINAPI BmpDecoder_Release(IWICBitmapDecoder *iface) BmpDecoder *This = impl_from_IWICBitmapDecoder(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { if (This->stream) IStream_Release(This->stream); - HeapFree(GetProcessHeap(), 0, This->imagedata); + free(This->imagedata); This->lock.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&This->lock); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; @@ -1155,7 +1186,7 @@ static HRESULT BmpDecoder_Create(int packed, int icoframe, BmpDecoder **ppDecode { BmpDecoder *This; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(BmpDecoder)); + This = malloc(sizeof(BmpDecoder)); if (!This) return E_OUTOFMEMORY; This->IWICBitmapDecoder_iface.lpVtbl = &BmpDecoder_Vtbl; @@ -1164,7 +1195,11 @@ static HRESULT BmpDecoder_Create(int packed, int icoframe, BmpDecoder **ppDecode This->initialized = FALSE; This->stream = NULL; This->imagedata = NULL; +#ifdef __REACTOS__ InitializeCriticalSection(&This->lock); +#else + InitializeCriticalSectionEx(&This->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": BmpDecoder.lock"); This->packed = packed; This->icoframe = icoframe; @@ -1220,7 +1255,8 @@ void BmpDecoder_FindIconMask(BmpDecoder *This, ULONG *mask_offset, int *topdown) if (This->read_data_func == BmpFrameDecode_ReadUncompressed) { /* RGB or BITFIELDS data */ - ULONG width, height, bytesperrow, datasize; + UINT width, height; + ULONG bytesperrow, datasize; IWICBitmapFrameDecode_GetSize(&This->IWICBitmapFrameDecode_iface, &width, &height); bytesperrow = (((width * This->bitsperpixel)+31)/32)*4; datasize = bytesperrow * height; diff --git a/dll/win32/windowscodecs/bmpencode.c b/dll/win32/windowscodecs/bmpencode.c index 3b77517a8d93f..28da4a5e6d221 100644 --- a/dll/win32/windowscodecs/bmpencode.c +++ b/dll/win32/windowscodecs/bmpencode.c @@ -17,8 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" - #include #define COBJMACROS @@ -56,10 +54,7 @@ static const struct bmp_pixelformat formats[] = { {&GUID_WICPixelFormat16bppBGR555, 16, 0, BI_RGB}, {&GUID_WICPixelFormat16bppBGR565, 16, 0, BI_BITFIELDS, 0xf800, 0x7e0, 0x1f, 0}, {&GUID_WICPixelFormat32bppBGR, 32, 0, BI_RGB}, -#if 0 - /* Windows doesn't seem to support this one. */ {&GUID_WICPixelFormat32bppBGRA, 32, 0, BI_BITFIELDS, 0xff0000, 0xff00, 0xff, 0xff000000}, -#endif {NULL} }; @@ -79,8 +74,6 @@ typedef struct BmpFrameEncode { BOOL committed; } BmpFrameEncode; -static const WCHAR wszEnableV5Header32bppBGRA[] = {'E','n','a','b','l','e','V','5','H','e','a','d','e','r','3','2','b','p','p','B','G','R','A',0}; - static inline BmpFrameEncode *impl_from_IWICBitmapFrameEncode(IWICBitmapFrameEncode *iface) { return CONTAINING_RECORD(iface, BmpFrameEncode, IWICBitmapFrameEncode_iface); @@ -114,7 +107,7 @@ static ULONG WINAPI BmpFrameEncode_AddRef(IWICBitmapFrameEncode *iface) BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -124,13 +117,13 @@ static ULONG WINAPI BmpFrameEncode_Release(IWICBitmapFrameEncode *iface) BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { if (This->stream) IStream_Release(This->stream); - HeapFree(GetProcessHeap(), 0, This->bits); - HeapFree(GetProcessHeap(), 0, This); + free(This->bits); + free(This); } return ref; @@ -253,7 +246,7 @@ static HRESULT BmpFrameEncode_AllocateBits(BmpFrameEncode *This) return WINCODEC_ERR_WRONGSTATE; This->stride = (((This->width * This->format->bpp)+31)/32)*4; - This->bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->stride * This->height); + This->bits = calloc(This->stride, This->height); if (!This->bits) return E_OUTOFMEMORY; } @@ -316,7 +309,8 @@ static HRESULT WINAPI BmpFrameEncode_WriteSource(IWICBitmapFrameEncode *iface, if (SUCCEEDED(hr)) { hr = write_source(iface, pIBitmapSource, prc, - This->format->guid, This->format->bpp, This->width, This->height); + This->format->guid, This->format->bpp, !This->colors && This->format->colors, + This->width, This->height); } return hr; @@ -400,10 +394,16 @@ static HRESULT WINAPI BmpFrameEncode_Commit(IWICBitmapFrameEncode *iface) } static HRESULT WINAPI BmpFrameEncode_GetMetadataQueryWriter(IWICBitmapFrameEncode *iface, - IWICMetadataQueryWriter **ppIMetadataQueryWriter) + IWICMetadataQueryWriter **query_writer) { - FIXME("(%p, %p): stub\n", iface, ppIMetadataQueryWriter); - return E_NOTIMPL; + BmpFrameEncode *encoder = impl_from_IWICBitmapFrameEncode(iface); + + TRACE("iface %p, query_writer %p.\n", iface, query_writer); + + if (!encoder->initialized) + return WINCODEC_ERR_NOTINITIALIZED; + + return WINCODEC_ERR_UNSUPPORTEDOPERATION; } static const IWICBitmapFrameEncodeVtbl BmpFrameEncode_Vtbl = { @@ -463,7 +463,7 @@ static ULONG WINAPI BmpEncoder_AddRef(IWICBitmapEncoder *iface) BmpEncoder *This = impl_from_IWICBitmapEncoder(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -473,13 +473,13 @@ static ULONG WINAPI BmpEncoder_Release(IWICBitmapEncoder *iface) BmpEncoder *This = impl_from_IWICBitmapEncoder(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { if (This->stream) IStream_Release(This->stream); if (This->frame) IWICBitmapFrameEncode_Release(&This->frame->IWICBitmapFrameEncode_iface); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; @@ -563,7 +563,7 @@ static HRESULT WINAPI BmpEncoder_CreateNewFrame(IWICBitmapEncoder *iface, HRESULT hr; static const PROPBAG2 opts[1] = { - { PROPBAG2_TYPE_DATA, VT_BOOL, 0, 0, (LPOLESTR)wszEnableV5Header32bppBGRA }, + { PROPBAG2_TYPE_DATA, VT_BOOL, 0, 0, (LPOLESTR)L"EnableV5Header32bppBGRA" }, }; TRACE("(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions); @@ -578,7 +578,7 @@ static HRESULT WINAPI BmpEncoder_CreateNewFrame(IWICBitmapEncoder *iface, if (FAILED(hr)) return hr; } - encode = HeapAlloc(GetProcessHeap(), 0, sizeof(BmpFrameEncode)); + encode = malloc(sizeof(BmpFrameEncode)); if (!encode) { IPropertyBag2_Release(*ppIEncoderOptions); @@ -648,7 +648,7 @@ HRESULT BmpEncoder_CreateInstance(REFIID iid, void** ppv) *ppv = NULL; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(BmpEncoder)); + This = malloc(sizeof(BmpEncoder)); if (!This) return E_OUTOFMEMORY; This->IWICBitmapEncoder_iface.lpVtbl = &BmpEncoder_Vtbl; diff --git a/dll/win32/windowscodecs/clipper.c b/dll/win32/windowscodecs/clipper.c index 02e0d967f5202..b4b2c23ee457e 100644 --- a/dll/win32/windowscodecs/clipper.c +++ b/dll/win32/windowscodecs/clipper.c @@ -72,7 +72,7 @@ static ULONG WINAPI BitmapClipper_AddRef(IWICBitmapClipper *iface) BitmapClipper *This = impl_from_IWICBitmapClipper(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -82,14 +82,14 @@ static ULONG WINAPI BitmapClipper_Release(IWICBitmapClipper *iface) BitmapClipper *This = impl_from_IWICBitmapClipper(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { This->lock.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&This->lock); if (This->source) IWICBitmapSource_Release(This->source); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; @@ -244,13 +244,17 @@ HRESULT BitmapClipper_Create(IWICBitmapClipper **clipper) { BitmapClipper *This; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapClipper)); + This = malloc(sizeof(BitmapClipper)); if (!This) return E_OUTOFMEMORY; This->IWICBitmapClipper_iface.lpVtbl = &BitmapClipper_Vtbl; This->ref = 1; This->source = NULL; +#ifdef __REACTOS__ InitializeCriticalSection(&This->lock); +#else + InitializeCriticalSectionEx(&This->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": BitmapClipper.lock"); *clipper = &This->IWICBitmapClipper_iface; diff --git a/dll/win32/windowscodecs/clsfactory.c b/dll/win32/windowscodecs/clsfactory.c index 2de518a00c1b8..87b77c9c089ae 100644 --- a/dll/win32/windowscodecs/clsfactory.c +++ b/dll/win32/windowscodecs/clsfactory.c @@ -16,8 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" - #include #define COBJMACROS @@ -27,6 +25,8 @@ #include "winreg.h" #include "objbase.h" #include "ocidl.h" +#include "wincodec.h" +#include "wincodecsdk.h" #include "initguid.h" #include "wincodecs_private.h" @@ -35,7 +35,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); -extern HRESULT WINAPI WIC_DllGetClassObject(REFCLSID, REFIID, LPVOID *) DECLSPEC_HIDDEN; +extern HRESULT WINAPI WIC_DllGetClassObject(REFCLSID, REFIID, LPVOID *); typedef struct { REFCLSID classid; @@ -47,6 +47,7 @@ static const classinfo wic_classes[] = { {&CLSID_WICImagingFactory2, ImagingFactory_CreateInstance}, {&CLSID_WICBmpDecoder, BmpDecoder_CreateInstance}, {&CLSID_WICPngDecoder, PngDecoder_CreateInstance}, + {&CLSID_WICPngDecoder2, PngDecoder_CreateInstance}, {&CLSID_WICPngEncoder, PngEncoder_CreateInstance}, {&CLSID_WICBmpEncoder, BmpEncoder_CreateInstance}, {&CLSID_WICGifDecoder, GifDecoder_CreateInstance}, @@ -56,14 +57,17 @@ static const classinfo wic_classes[] = { {&CLSID_WICJpegEncoder, JpegEncoder_CreateInstance}, {&CLSID_WICTiffDecoder, TiffDecoder_CreateInstance}, {&CLSID_WICTiffEncoder, TiffEncoder_CreateInstance}, - {&CLSID_WICIcnsEncoder, IcnsEncoder_CreateInstance}, + {&CLSID_WICDdsDecoder, DdsDecoder_CreateInstance}, + {&CLSID_WICDdsEncoder, DdsEncoder_CreateInstance}, {&CLSID_WICDefaultFormatConverter, FormatConverter_CreateInstance}, {&CLSID_WineTgaDecoder, TgaDecoder_CreateInstance}, {&CLSID_WICUnknownMetadataReader, UnknownMetadataReader_CreateInstance}, {&CLSID_WICIfdMetadataReader, IfdMetadataReader_CreateInstance}, {&CLSID_WICPngChrmMetadataReader, PngChrmReader_CreateInstance}, {&CLSID_WICPngGamaMetadataReader, PngGamaReader_CreateInstance}, + {&CLSID_WICPngHistMetadataReader, PngHistReader_CreateInstance}, {&CLSID_WICPngTextMetadataReader, PngTextReader_CreateInstance}, + {&CLSID_WICPngTimeMetadataReader, PngTimeReader_CreateInstance}, {&CLSID_WICLSDMetadataReader, LSDReader_CreateInstance}, {&CLSID_WICIMDMetadataReader, IMDReader_CreateInstance}, {&CLSID_WICGCEMetadataReader, GCEReader_CreateInstance}, @@ -110,7 +114,7 @@ static ULONG WINAPI ClassFactoryImpl_AddRef(IClassFactory *iface) ClassFactoryImpl *This = impl_from_IClassFactory(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -120,10 +124,10 @@ static ULONG WINAPI ClassFactoryImpl_Release(IClassFactory *iface) ClassFactoryImpl *This = impl_from_IClassFactory(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) - HeapFree(GetProcessHeap(), 0, This); + free(This); return ref; } @@ -161,7 +165,7 @@ static HRESULT ClassFactoryImpl_Constructor(const classinfo *info, REFIID riid, *ppv = NULL; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(ClassFactoryImpl)); + This = malloc(sizeof(ClassFactoryImpl)); if (!This) return E_OUTOFMEMORY; This->IClassFactory_iface.lpVtbl = &ClassFactoryImpl_Vtbl; @@ -201,11 +205,11 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv) else ret = WIC_DllGetClassObject(rclsid, iid, ppv); - TRACE("<-- %08X\n", ret); + TRACE("<-- %08lX\n", ret); return ret; } -HRESULT create_instance(CLSID *clsid, const IID *iid, void **ppv) +HRESULT create_instance(const CLSID *clsid, const IID *iid, void **ppv) { int i; diff --git a/dll/win32/windowscodecs/colorcontext.c b/dll/win32/windowscodecs/colorcontext.c index eb13482cf43ea..a52e4e06eb7dc 100644 --- a/dll/win32/windowscodecs/colorcontext.c +++ b/dll/win32/windowscodecs/colorcontext.c @@ -16,8 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" - #include #define COBJMACROS @@ -74,7 +72,7 @@ static ULONG WINAPI ColorContext_AddRef(IWICColorContext *iface) ColorContext *This = impl_from_IWICColorContext(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -84,12 +82,12 @@ static ULONG WINAPI ColorContext_Release(IWICColorContext *iface) ColorContext *This = impl_from_IWICColorContext(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { - HeapFree(GetProcessHeap(), 0, This->profile); - HeapFree(GetProcessHeap(), 0, This); + free(This->profile); + free(This); } return ref; @@ -118,7 +116,7 @@ static HRESULT load_profile(const WCHAR *filename, BYTE **profile, UINT *len) CloseHandle(handle); return E_FAIL; } - if (!(*profile = HeapAlloc(GetProcessHeap(), 0, size.u.LowPart))) + if (!(*profile = malloc(size.u.LowPart))) { CloseHandle(handle); return E_OUTOFMEMORY; @@ -126,12 +124,12 @@ static HRESULT load_profile(const WCHAR *filename, BYTE **profile, UINT *len) ret = ReadFile(handle, *profile, size.u.LowPart, &count, NULL); CloseHandle(handle); if (!ret) { - HeapFree (GetProcessHeap(),0,*profile); + free(*profile); *profile = NULL; return HRESULT_FROM_WIN32(GetLastError()); } if (count != size.u.LowPart) { - HeapFree (GetProcessHeap(),0,*profile); + free(*profile); *profile = NULL; return E_FAIL; } @@ -156,7 +154,7 @@ static HRESULT WINAPI ColorContext_InitializeFromFilename(IWICColorContext *ifac hr = load_profile(wzFilename, &profile, &len); if (FAILED(hr)) return hr; - HeapFree(GetProcessHeap(), 0, This->profile); + free(This->profile); This->profile = profile; This->profile_len = len; This->type = WICColorContextProfile; @@ -174,10 +172,10 @@ static HRESULT WINAPI ColorContext_InitializeFromMemory(IWICColorContext *iface, if (This->type != WICColorContextUninitialized && This->type != WICColorContextProfile) return WINCODEC_ERR_WRONGSTATE; - if (!(profile = HeapAlloc(GetProcessHeap(), 0, cbBufferSize))) return E_OUTOFMEMORY; + if (!(profile = malloc(cbBufferSize))) return E_OUTOFMEMORY; memcpy(profile, pbBuffer, cbBufferSize); - HeapFree(GetProcessHeap(), 0, This->profile); + free(This->profile); This->profile = profile; This->profile_len = cbBufferSize; This->type = WICColorContextProfile; @@ -261,7 +259,7 @@ HRESULT ColorContext_Create(IWICColorContext **colorcontext) if (!colorcontext) return E_INVALIDARG; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(ColorContext)); + This = malloc(sizeof(ColorContext)); if (!This) return E_OUTOFMEMORY; This->IWICColorContext_iface.lpVtbl = &ColorContext_Vtbl; diff --git a/dll/win32/windowscodecs/colortransform.c b/dll/win32/windowscodecs/colortransform.c index af66c67443d74..9a392d6dc0c04 100644 --- a/dll/win32/windowscodecs/colortransform.c +++ b/dll/win32/windowscodecs/colortransform.c @@ -16,8 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" - #include #define COBJMACROS @@ -72,7 +70,7 @@ static ULONG WINAPI ColorTransform_AddRef(IWICColorTransform *iface) ColorTransform *This = impl_from_IWICColorTransform(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -82,12 +80,12 @@ static ULONG WINAPI ColorTransform_Release(IWICColorTransform *iface) ColorTransform *This = impl_from_IWICColorTransform(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { if (This->dst) IWICBitmapSource_Release(This->dst); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; @@ -177,7 +175,7 @@ HRESULT ColorTransform_Create(IWICColorTransform **colortransform) if (!colortransform) return E_INVALIDARG; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(ColorTransform)); + This = malloc(sizeof(ColorTransform)); if (!This) return E_OUTOFMEMORY; This->IWICColorTransform_iface.lpVtbl = &ColorTransform_Vtbl; diff --git a/dll/win32/windowscodecs/converter.c b/dll/win32/windowscodecs/converter.c index cac2ac1aa5ad9..2156e0aec8f0b 100644 --- a/dll/win32/windowscodecs/converter.c +++ b/dll/win32/windowscodecs/converter.c @@ -17,8 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" - #include #include @@ -30,7 +28,6 @@ #include "wincodecs_private.h" -#include "wine/heap.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); @@ -71,6 +68,7 @@ struct pixelformatinfo { enum pixelformat format; const WICPixelFormatGUID *guid; copyfunc copy_function; + BOOL is_indexed_format; }; typedef struct FormatConverter { @@ -176,7 +174,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe srcstride = (prc->Width+7)/8; srcdatasize = srcstride * prc->Height; - srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); @@ -205,7 +203,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe } } - HeapFree(GetProcessHeap(), 0, srcdata); + free(srcdata); return res; } @@ -243,7 +241,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe srcstride = (prc->Width+3)/4; srcdatasize = srcstride * prc->Height; - srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); @@ -268,7 +266,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe } } - HeapFree(GetProcessHeap(), 0, srcdata); + free(srcdata); return res; } @@ -306,7 +304,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe srcstride = (prc->Width+1)/2; srcdatasize = srcstride * prc->Height; - srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); @@ -329,7 +327,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe } } - HeapFree(GetProcessHeap(), 0, srcdata); + free(srcdata); return res; } @@ -349,7 +347,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe srcstride = prc->Width; srcdatasize = srcstride * prc->Height; - srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); @@ -371,7 +369,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe } } - HeapFree(GetProcessHeap(), 0, srcdata); + free(srcdata); return res; } @@ -405,7 +403,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe srcstride = prc->Width; srcdatasize = srcstride * prc->Height; - srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); @@ -424,7 +422,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe } } - HeapFree(GetProcessHeap(), 0, srcdata); + free(srcdata); return res; } @@ -444,7 +442,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe srcstride = prc->Width * 2; srcdatasize = srcstride * prc->Height; - srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); @@ -467,7 +465,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe } } - HeapFree(GetProcessHeap(), 0, srcdata); + free(srcdata); return res; } @@ -487,7 +485,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe srcstride = 2 * prc->Width; srcdatasize = srcstride * prc->Height; - srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); @@ -515,7 +513,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe } } - HeapFree(GetProcessHeap(), 0, srcdata); + free(srcdata); return res; } @@ -535,7 +533,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe srcstride = 2 * prc->Width; srcdatasize = srcstride * prc->Height; - srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); @@ -563,7 +561,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe } } - HeapFree(GetProcessHeap(), 0, srcdata); + free(srcdata); return res; } @@ -583,7 +581,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe srcstride = 2 * prc->Width; srcdatasize = srcstride * prc->Height; - srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); @@ -611,7 +609,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe } } - HeapFree(GetProcessHeap(), 0, srcdata); + free(srcdata); return res; } @@ -631,7 +629,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe srcstride = 3 * prc->Width; srcdatasize = srcstride * prc->Height; - srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); @@ -654,7 +652,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe } } - HeapFree(GetProcessHeap(), 0, srcdata); + free(srcdata); return res; } @@ -675,7 +673,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe srcstride = 3 * prc->Width; srcdatasize = srcstride * prc->Height; - srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); @@ -702,7 +700,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe } } - HeapFree(GetProcessHeap(), 0, srcdata); + free(srcdata); return res; } @@ -728,7 +726,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe HRESULT res; res = IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer); if (FAILED(res)) return res; - convert_rgba_to_bgra(4, pbBuffer, prc->Width, prc->Height, cbStride); + reverse_bgr8(4, pbBuffer, prc->Width, prc->Height, cbStride); } return S_OK; case format_32bppBGRA: @@ -772,7 +770,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe srcstride = 6 * prc->Width; srcdatasize = srcstride * prc->Height; - srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); @@ -796,7 +794,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe } } - HeapFree(GetProcessHeap(), 0, srcdata); + free(srcdata); return res; } @@ -816,7 +814,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe srcstride = 8 * prc->Width; srcdatasize = srcstride * prc->Height; - srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); @@ -841,7 +839,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe } } - HeapFree(GetProcessHeap(), 0, srcdata); + free(srcdata); return res; } @@ -985,9 +983,9 @@ static HRESULT copypixels_to_32bppPBGRA(struct FormatConverter *This, const WICR BYTE alpha = pbBuffer[cbStride*y+4*x+3]; if (alpha != 255) { - pbBuffer[cbStride*y+4*x] = pbBuffer[cbStride*y+4*x] * alpha / 255; - pbBuffer[cbStride*y+4*x+1] = pbBuffer[cbStride*y+4*x+1] * alpha / 255; - pbBuffer[cbStride*y+4*x+2] = pbBuffer[cbStride*y+4*x+2] * alpha / 255; + pbBuffer[cbStride*y+4*x] = (pbBuffer[cbStride*y+4*x] * alpha + 127) / 255; + pbBuffer[cbStride*y+4*x+1] = (pbBuffer[cbStride*y+4*x+1] * alpha + 127) / 255; + pbBuffer[cbStride*y+4*x+2] = (pbBuffer[cbStride*y+4*x+2] * alpha + 127) / 255; } } } @@ -1018,9 +1016,9 @@ static HRESULT copypixels_to_32bppPRGBA(struct FormatConverter *This, const WICR BYTE alpha = pbBuffer[cbStride*y+4*x+3]; if (alpha != 255) { - pbBuffer[cbStride*y+4*x] = pbBuffer[cbStride*y+4*x] * alpha / 255; - pbBuffer[cbStride*y+4*x+1] = pbBuffer[cbStride*y+4*x+1] * alpha / 255; - pbBuffer[cbStride*y+4*x+2] = pbBuffer[cbStride*y+4*x+2] * alpha / 255; + pbBuffer[cbStride*y+4*x] = (pbBuffer[cbStride*y+4*x] * alpha + 127) / 255; + pbBuffer[cbStride*y+4*x+1] = (pbBuffer[cbStride*y+4*x+1] * alpha + 127) / 255; + pbBuffer[cbStride*y+4*x+2] = (pbBuffer[cbStride*y+4*x+2] * alpha + 127) / 255; } } } @@ -1063,7 +1061,7 @@ static HRESULT copypixels_to_24bppBGR(struct FormatConverter *This, const WICRec srcstride = 4 * prc->Width; srcdatasize = srcstride * prc->Height; - srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); @@ -1107,7 +1105,7 @@ static HRESULT copypixels_to_24bppBGR(struct FormatConverter *This, const WICRec } } - HeapFree(GetProcessHeap(), 0, srcdata); + free(srcdata); return res; } @@ -1122,7 +1120,7 @@ static HRESULT copypixels_to_24bppBGR(struct FormatConverter *This, const WICRec srcstride = 4 * prc->Width; srcdatasize = srcstride * prc->Height; - srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; hr = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); @@ -1149,7 +1147,7 @@ static HRESULT copypixels_to_24bppBGR(struct FormatConverter *This, const WICRec } } - HeapFree(GetProcessHeap(), 0, srcdata); + free(srcdata); return hr; } @@ -1164,7 +1162,7 @@ static HRESULT copypixels_to_24bppBGR(struct FormatConverter *This, const WICRec srcstride = 4 * prc->Width; srcdatasize = srcstride * prc->Height; - srcdata = heap_alloc(srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; hr = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); @@ -1192,7 +1190,7 @@ static HRESULT copypixels_to_24bppBGR(struct FormatConverter *This, const WICRec } } - heap_free(srcdata); + free(srcdata); return hr; } return S_OK; @@ -1238,7 +1236,7 @@ static HRESULT copypixels_to_24bppRGB(struct FormatConverter *This, const WICRec srcstride = 4 * prc->Width; srcdatasize = srcstride * prc->Height; - srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); @@ -1265,7 +1263,7 @@ static HRESULT copypixels_to_24bppRGB(struct FormatConverter *This, const WICRec } } - HeapFree(GetProcessHeap(), 0, srcdata); + free(srcdata); return res; } @@ -1343,7 +1341,7 @@ static HRESULT copypixels_to_8bppGray(struct FormatConverter *This, const WICRec srcstride = 4 * prc->Width; srcdatasize = srcstride * prc->Height; - srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; hr = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); @@ -1365,7 +1363,7 @@ static HRESULT copypixels_to_8bppGray(struct FormatConverter *This, const WICRec } } - HeapFree(GetProcessHeap(), 0, srcdata); + free(srcdata); } return hr; @@ -1377,7 +1375,7 @@ static HRESULT copypixels_to_8bppGray(struct FormatConverter *This, const WICRec srcstride = 3 * prc->Width; srcdatasize = srcstride * prc->Height; - srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; hr = copypixels_to_24bppBGR(This, prc, srcstride, srcdatasize, srcdata, source_format); @@ -1403,7 +1401,7 @@ static HRESULT copypixels_to_8bppGray(struct FormatConverter *This, const WICRec } } - HeapFree(GetProcessHeap(), 0, srcdata); + free(srcdata); return hr; } @@ -1467,7 +1465,7 @@ static HRESULT copypixels_to_8bppIndexed(struct FormatConverter *This, const WIC srcstride = 3 * prc->Width; srcdatasize = srcstride * prc->Height; - srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; hr = copypixels_to_24bppBGR(This, prc, srcstride, srcdatasize, srcdata, source_format); @@ -1490,15 +1488,138 @@ static HRESULT copypixels_to_8bppIndexed(struct FormatConverter *This, const WIC } } - HeapFree(GetProcessHeap(), 0, srcdata); + free(srcdata); return hr; } +static HRESULT copypixels_to_16bppBGRA5551(struct FormatConverter *This, const WICRect *prc, + UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format) +{ + switch (source_format) + { + case format_16bppBGRA5551: + if (prc) + return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer); + return S_OK; + case format_32bppBGRA: + if(prc) + { + HRESULT res; + INT x, y; + BYTE *srcdata; + UINT srcstride, srcdatasize; + const BYTE *srcrow; + const DWORD *srcpixel; + BYTE *dstrow; + DWORD srcval = 0; + WORD *dstpixel; + + int a, r, g, b; + + srcstride = 4 * prc->Width; + srcdatasize = srcstride * prc->Height; + + srcdata = malloc(srcdatasize); + if (!srcdata) return E_OUTOFMEMORY; + + res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); + if(SUCCEEDED(res)) + { + srcrow = srcdata; + dstrow = pbBuffer; + for(y=0; y< prc->Height; y++) { + srcpixel = (const DWORD*)srcrow; + dstpixel = (WORD *)dstrow; + for(x=0; xWidth; x++) { + srcval=*srcpixel++; + a = (srcval & 0xff000000) >> 24; + r = (srcval & 0x00ff0000) >> 16; + g = (srcval & 0x0000ff00) >> 8; + b = (srcval & 0x000000ff); + a = (a >> 7) << 15; + r = (r >> 3) << 10; + g = (g >> 3) << 5; + b = (b >> 3); + *dstpixel++ = (a|r|g|b); + } + srcrow += srcstride; + dstrow += cbStride; + } + } + free(srcdata); + } + return S_OK; + default: + FIXME("Unimplemented conversion path! %d\n", source_format); + return WINCODEC_ERR_UNSUPPORTEDOPERATION; + } +} + +static HRESULT copypixels_to_64bppRGBA(struct FormatConverter *This, const WICRect *prc, + UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format) +{ + HRESULT hr; + + switch (source_format) + { + case format_64bppRGBA: + if (prc) + return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer); + return S_OK; + + case format_48bppRGB: + { + UINT srcstride, srcdatasize; + const USHORT *srcpixel; + const BYTE *srcrow; + USHORT *dstpixel; + BYTE *srcdata; + BYTE *dstrow; + INT x, y; + + if (!prc) + return S_OK; + + srcstride = 6 * prc->Width; + srcdatasize = srcstride * prc->Height; + + srcdata = malloc(srcdatasize); + if (!srcdata) return E_OUTOFMEMORY; + + hr = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); + if (SUCCEEDED(hr)) + { + srcrow = srcdata; + dstrow = pbBuffer; + for (y = 0; y < prc->Height; y++) + { + srcpixel = (USHORT *)srcrow; + dstpixel= (USHORT *)dstrow; + for (x = 0; x < prc->Width; x++) + { + *dstpixel++ = *srcpixel++; + *dstpixel++ = *srcpixel++; + *dstpixel++ = *srcpixel++; + *dstpixel++ = 65535; + } + srcrow += srcstride; + dstrow += cbStride; + } + } + free(srcdata); + return hr; + } + default: + FIXME("Unimplemented conversion path %d.\n", source_format); + return WINCODEC_ERR_UNSUPPORTEDOPERATION; + } +} + static const struct pixelformatinfo supported_formats[] = { - {format_1bppIndexed, &GUID_WICPixelFormat1bppIndexed, NULL}, - {format_2bppIndexed, &GUID_WICPixelFormat2bppIndexed, NULL}, - {format_4bppIndexed, &GUID_WICPixelFormat4bppIndexed, NULL}, - {format_8bppIndexed, &GUID_WICPixelFormat8bppIndexed, copypixels_to_8bppIndexed}, + {format_1bppIndexed, &GUID_WICPixelFormat1bppIndexed, NULL, TRUE}, + {format_2bppIndexed, &GUID_WICPixelFormat2bppIndexed, NULL, TRUE}, + {format_4bppIndexed, &GUID_WICPixelFormat4bppIndexed, NULL, TRUE}, + {format_8bppIndexed, &GUID_WICPixelFormat8bppIndexed, copypixels_to_8bppIndexed, TRUE}, {format_BlackWhite, &GUID_WICPixelFormatBlackWhite, NULL}, {format_2bppGray, &GUID_WICPixelFormat2bppGray, NULL}, {format_4bppGray, &GUID_WICPixelFormat4bppGray, NULL}, @@ -1506,7 +1627,7 @@ static const struct pixelformatinfo supported_formats[] = { {format_16bppGray, &GUID_WICPixelFormat16bppGray, NULL}, {format_16bppBGR555, &GUID_WICPixelFormat16bppBGR555, NULL}, {format_16bppBGR565, &GUID_WICPixelFormat16bppBGR565, NULL}, - {format_16bppBGRA5551, &GUID_WICPixelFormat16bppBGRA5551, NULL}, + {format_16bppBGRA5551, &GUID_WICPixelFormat16bppBGRA5551, copypixels_to_16bppBGRA5551}, {format_24bppBGR, &GUID_WICPixelFormat24bppBGR, copypixels_to_24bppBGR}, {format_24bppRGB, &GUID_WICPixelFormat24bppRGB, copypixels_to_24bppRGB}, {format_32bppGrayFloat, &GUID_WICPixelFormat32bppGrayFloat, copypixels_to_32bppGrayFloat}, @@ -1517,7 +1638,7 @@ static const struct pixelformatinfo supported_formats[] = { {format_32bppPBGRA, &GUID_WICPixelFormat32bppPBGRA, copypixels_to_32bppPBGRA}, {format_32bppPRGBA, &GUID_WICPixelFormat32bppPRGBA, copypixels_to_32bppPRGBA}, {format_48bppRGB, &GUID_WICPixelFormat48bppRGB, NULL}, - {format_64bppRGBA, &GUID_WICPixelFormat64bppRGBA, NULL}, + {format_64bppRGBA, &GUID_WICPixelFormat64bppRGBA, copypixels_to_64bppRGBA}, {format_32bppCMYK, &GUID_WICPixelFormat32bppCMYK, NULL}, {0} }; @@ -1561,7 +1682,7 @@ static ULONG WINAPI FormatConverter_AddRef(IWICFormatConverter *iface) FormatConverter *This = impl_from_IWICFormatConverter(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -1571,7 +1692,7 @@ static ULONG WINAPI FormatConverter_Release(IWICFormatConverter *iface) FormatConverter *This = impl_from_IWICFormatConverter(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { @@ -1579,7 +1700,7 @@ static ULONG WINAPI FormatConverter_Release(IWICFormatConverter *iface) DeleteCriticalSection(&This->lock); if (This->source) IWICBitmapSource_Release(This->source); if (This->palette) IWICPalette_Release(This->palette); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; @@ -1638,12 +1759,7 @@ static HRESULT WINAPI FormatConverter_CopyPalette(IWICFormatConverter *iface, if (!This->palette) { - HRESULT hr; - UINT bpp; - - hr = get_pixelformat_bpp(This->dst_format->guid, &bpp); - if (hr != S_OK) return hr; - if (bpp <= 8) return WINCODEC_ERR_WRONGSTATE; + if (This->dst_format->is_indexed_format) return WINCODEC_ERR_WRONGSTATE; return IWICBitmapSource_CopyPalette(This->source, palette); } @@ -1691,6 +1807,13 @@ static HRESULT WINAPI FormatConverter_Initialize(IWICFormatConverter *iface, TRACE("(%p,%p,%s,%u,%p,%0.3f,%u)\n", iface, source, debugstr_guid(dstFormat), dither, palette, alpha_threshold, palette_type); + dstinfo = get_formatinfo(dstFormat); + if (!dstinfo) + { + FIXME("Unsupported destination format %s\n", debugstr_guid(dstFormat)); + return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; + } + if (!palette) { UINT bpp; @@ -1705,18 +1828,21 @@ static HRESULT WINAPI FormatConverter_Initialize(IWICFormatConverter *iface, case WICBitmapPaletteTypeCustom: IWICPalette_Release(palette); palette = NULL; - if (bpp <= 8) return E_INVALIDARG; + + /* Indexed types require a palette */ + if (dstinfo->is_indexed_format) + return E_INVALIDARG; break; case WICBitmapPaletteTypeMedianCut: { - if (bpp <= 8) + if (dstinfo->is_indexed_format) res = IWICPalette_InitializeFromBitmap(palette, source, 1 << bpp, FALSE); break; } default: - if (bpp <= 8) + if (dstinfo->is_indexed_format) res = IWICPalette_InitializePredefined(palette, palette_type, FALSE); break; } @@ -1749,14 +1875,6 @@ static HRESULT WINAPI FormatConverter_Initialize(IWICFormatConverter *iface, goto end; } - dstinfo = get_formatinfo(dstFormat); - if (!dstinfo) - { - res = WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; - FIXME("Unsupported destination format %s\n", debugstr_guid(dstFormat)); - goto end; - } - if (dstinfo->copy_function) { IWICBitmapSource_AddRef(source); @@ -1841,14 +1959,18 @@ HRESULT FormatConverter_CreateInstance(REFIID iid, void** ppv) *ppv = NULL; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(FormatConverter)); + This = malloc(sizeof(FormatConverter)); if (!This) return E_OUTOFMEMORY; This->IWICFormatConverter_iface.lpVtbl = &FormatConverter_Vtbl; This->ref = 1; This->source = NULL; This->palette = NULL; +#ifdef __REACTOS__ InitializeCriticalSection(&This->lock); +#else + InitializeCriticalSectionEx(&This->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": FormatConverter.lock"); ret = IWICFormatConverter_QueryInterface(&This->IWICFormatConverter_iface, iid, ppv); diff --git a/dll/win32/windowscodecs/ddsformat.c b/dll/win32/windowscodecs/ddsformat.c new file mode 100644 index 0000000000000..680febb0d93f4 --- /dev/null +++ b/dll/win32/windowscodecs/ddsformat.c @@ -0,0 +1,2162 @@ +/* + * Copyright 2020 Ziqing Hui + * + * 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 + * + * + * Note: + * + * Uncompressed image: + * For uncompressed formats, a block is equivalent to a pixel. + * + * Cube map: + * A cube map is equivalent to a 2D texture array which has 6 textures. + * A cube map array is equivalent to a 2D texture array which has cubeCount*6 textures. + */ + +#include + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" + +#include "wincodecs_private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); + +#define DDS_MAGIC 0x20534444 +#ifndef MAKEFOURCC +#define MAKEFOURCC(ch0, ch1, ch2, ch3) \ + ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \ + ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 )) +#endif + +#define GET_RGB565_R(color) ((BYTE)(((color) >> 11) & 0x1F)) +#define GET_RGB565_G(color) ((BYTE)(((color) >> 5) & 0x3F)) +#define GET_RGB565_B(color) ((BYTE)(((color) >> 0) & 0x1F)) +#define MAKE_RGB565(r, g, b) ((WORD)(((BYTE)(r) << 11) | ((BYTE)(g) << 5) | (BYTE)(b))) +#define MAKE_ARGB(a, r, g, b) (((DWORD)(a) << 24) | ((DWORD)(r) << 16) | ((DWORD)(g) << 8) | (DWORD)(b)) + +#define DDPF_ALPHAPIXELS 0x00000001 +#define DDPF_ALPHA 0x00000002 +#define DDPF_FOURCC 0x00000004 +#define DDPF_PALETTEINDEXED8 0x00000020 +#define DDPF_RGB 0x00000040 +#define DDPF_LUMINANCE 0x00020000 +#define DDPF_BUMPDUDV 0x00080000 + +#define DDSCAPS2_CUBEMAP 0x00000200 +#define DDSCAPS2_VOLUME 0x00200000 + +#define DDS_DIMENSION_TEXTURE1D 2 +#define DDS_DIMENSION_TEXTURE2D 3 +#define DDS_DIMENSION_TEXTURE3D 4 + +#define DDS_RESOURCE_MISC_TEXTURECUBE 0x00000004 + +#define DDS_BLOCK_WIDTH 4 +#define DDS_BLOCK_HEIGHT 4 + +typedef struct { + DWORD size; + DWORD flags; + DWORD fourCC; + DWORD rgbBitCount; + DWORD rBitMask; + DWORD gBitMask; + DWORD bBitMask; + DWORD aBitMask; +} DDS_PIXELFORMAT; + +typedef struct { + DWORD size; + DWORD flags; + DWORD height; + DWORD width; + DWORD pitchOrLinearSize; + DWORD depth; + DWORD mipMapCount; + DWORD reserved1[11]; + DDS_PIXELFORMAT ddspf; + DWORD caps; + DWORD caps2; + DWORD caps3; + DWORD caps4; + DWORD reserved2; +} DDS_HEADER; + +typedef struct { + DWORD dxgiFormat; + DWORD resourceDimension; + DWORD miscFlag; + DWORD arraySize; + DWORD miscFlags2; +} DDS_HEADER_DXT10; + +typedef struct dds_info { + UINT width; + UINT height; + UINT depth; + UINT mip_levels; + UINT array_size; + UINT frame_count; + UINT data_offset; + UINT bytes_per_block; /* for uncompressed format, this means bytes per pixel*/ + DXGI_FORMAT format; + WICDdsDimension dimension; + WICDdsAlphaMode alpha_mode; + const GUID *pixel_format; + UINT pixel_format_bpp; +} dds_info; + +typedef struct dds_frame_info { + UINT width; + UINT height; + DXGI_FORMAT format; + UINT bytes_per_block; /* for uncompressed format, this means bytes per pixel*/ + UINT block_width; + UINT block_height; + UINT width_in_blocks; + UINT height_in_blocks; + const GUID *pixel_format; + UINT pixel_format_bpp; +} dds_frame_info; + +typedef struct DdsDecoder { + IWICBitmapDecoder IWICBitmapDecoder_iface; + IWICDdsDecoder IWICDdsDecoder_iface; + IWICWineDecoder IWICWineDecoder_iface; + LONG ref; + BOOL initialized; + IStream *stream; + CRITICAL_SECTION lock; + dds_info info; +} DdsDecoder; + +typedef struct DdsFrameDecode { + IWICBitmapFrameDecode IWICBitmapFrameDecode_iface; + IWICDdsFrameDecode IWICDdsFrameDecode_iface; + LONG ref; + BYTE *block_data; + BYTE *pixel_data; + CRITICAL_SECTION lock; + dds_frame_info info; +} DdsFrameDecode; + +typedef struct DdsEncoder { + IWICBitmapEncoder IWICBitmapEncoder_iface; + IWICDdsEncoder IWICDdsEncoder_iface; + LONG ref; + CRITICAL_SECTION lock; + IStream *stream; + UINT frame_count; + UINT frame_index; + BOOL uncommitted_frame; + BOOL committed; + dds_info info; +} DdsEncoder; + +typedef struct DdsFrameEncode { + IWICBitmapFrameEncode IWICBitmapFrameEncode_iface; + LONG ref; + DdsEncoder *parent; + BOOL initialized; + BOOL frame_created; + UINT width; + UINT height; + double dpi_x; + double dpi_y; +} DdsFrameEncode; + +static struct dds_format { + DDS_PIXELFORMAT pixel_format; + const GUID *wic_format; + UINT wic_format_bpp; + DXGI_FORMAT dxgi_format; +} dds_format_table[] = { + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D', 'X', 'T', '1'), 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormat32bppPBGRA, 32, DXGI_FORMAT_BC1_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D', 'X', 'T', '2'), 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormat32bppPBGRA, 32, DXGI_FORMAT_BC2_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D', 'X', 'T', '3'), 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormat32bppBGRA, 32, DXGI_FORMAT_BC2_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D', 'X', 'T', '4'), 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormat32bppPBGRA, 32, DXGI_FORMAT_BC3_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D', 'X', 'T', '5'), 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormat32bppBGRA, 32, DXGI_FORMAT_BC3_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('B', 'C', '4', 'U'), 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormat32bppBGRA, 32, DXGI_FORMAT_BC4_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('B', 'C', '4', 'S'), 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormat32bppBGRA, 32, DXGI_FORMAT_BC4_SNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('B', 'C', '5', 'U'), 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormat32bppBGRA, 32, DXGI_FORMAT_BC5_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('B', 'C', '5', 'S'), 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormat32bppBGRA, 32, DXGI_FORMAT_BC5_SNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('A', 'T', 'I', '1'), 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormat32bppBGRA, 32, DXGI_FORMAT_BC4_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('A', 'T', 'I', '2'), 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormat32bppBGRA, 32, DXGI_FORMAT_BC5_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('R', 'G', 'B', 'G'), 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormat32bpp4Channels, 32, DXGI_FORMAT_R8G8_B8G8_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('G', 'R', 'G', 'B'), 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormat32bpp4Channels, 32, DXGI_FORMAT_G8R8_G8B8_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D', 'X', '1', '0'), 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormatUndefined, 0, DXGI_FORMAT_UNKNOWN }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, 0x24, 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormat64bppRGBA, 64, DXGI_FORMAT_R16G16B16A16_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, 0x6E, 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormat64bppRGBA, 64, DXGI_FORMAT_R16G16B16A16_SNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, 0x6F, 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormat16bppGrayHalf, 16, DXGI_FORMAT_R16_FLOAT }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, 0x70, 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormatUndefined, 0, DXGI_FORMAT_R16G16_FLOAT }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, 0x71, 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormat64bppRGBAHalf, 64, DXGI_FORMAT_R16G16B16A16_FLOAT }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, 0x72, 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormat32bppGrayFloat, 32, DXGI_FORMAT_R32_FLOAT }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, 0x73, 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormatUndefined, 32, DXGI_FORMAT_R32G32_FLOAT }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, 0x74, 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormat128bppRGBAFloat, 128, DXGI_FORMAT_R32G32B32A32_FLOAT }, + { { sizeof(DDS_PIXELFORMAT), DDPF_RGB, 0, 32, 0xFF,0xFF00,0xFF0000,0xFF000000 }, + &GUID_WICPixelFormat32bppRGBA, 32, DXGI_FORMAT_R8G8B8A8_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_RGB, 0, 32, 0xFF,0xFF00,0xFF0000,0 }, + &GUID_WICPixelFormat32bppRGB, 32, DXGI_FORMAT_UNKNOWN }, + { { sizeof(DDS_PIXELFORMAT), DDPF_RGB, 0, 32, 0xFF0000,0xFF00,0xFF,0xFF000000 }, + &GUID_WICPixelFormat32bppBGRA, 32, DXGI_FORMAT_B8G8R8A8_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_RGB, 0, 32, 0xFF0000,0xFF00,0xFF,0 }, + &GUID_WICPixelFormat32bppBGR, 32, DXGI_FORMAT_B8G8R8X8_UNORM }, + /* The red and blue masks are swapped for DXGI_FORMAT_R10G10B10A2_UNORM. + * For "correct" one, the RGB masks should be 0x3FF,0xFFC00,0x3FF00000. + * see: https://walbourn.github.io/dds-update-and-1010102-problems */ + { { sizeof(DDS_PIXELFORMAT), DDPF_RGB, 0, 32, 0x3FF00000,0xFFC00,0x3FF,0xC0000000 }, + &GUID_WICPixelFormat32bppR10G10B10A2, 32, DXGI_FORMAT_R10G10B10A2_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_RGB, 0, 32, 0x3FF,0xFFC00,0x3FF00000,0xC0000000 }, + &GUID_WICPixelFormat32bppRGBA1010102, 32, DXGI_FORMAT_R10G10B10A2_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_RGB , 0, 32, 0xFFFF,0xFFFF0000,0,0 }, + &GUID_WICPixelFormatUndefined, 0, DXGI_FORMAT_R16G16_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_RGB , 0, 32, 0xFFFFFFFF,0,0,0 }, + &GUID_WICPixelFormat32bppGrayFloat, 32, DXGI_FORMAT_R32_FLOAT }, + { { sizeof(DDS_PIXELFORMAT), DDPF_RGB , 0, 24, 0xFF0000,0x00FF00,0x0000FF,0 }, + &GUID_WICPixelFormat24bppBGR, 24, DXGI_FORMAT_UNKNOWN }, + { { sizeof(DDS_PIXELFORMAT), DDPF_RGB , 0, 24, 0x0000FF,0x00FF00,0xFF0000,0 }, + &GUID_WICPixelFormat24bppRGB, 24, DXGI_FORMAT_UNKNOWN }, + { { sizeof(DDS_PIXELFORMAT), DDPF_RGB, 0, 16, 0xF800,0x7E0,0x1F,0 }, + &GUID_WICPixelFormat16bppBGR565, 16, DXGI_FORMAT_B5G6R5_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_RGB, 0, 16, 0x7C00,0x3E0,0x1F,0 }, + &GUID_WICPixelFormat16bppBGR555, 16, DXGI_FORMAT_UNKNOWN }, + { { sizeof(DDS_PIXELFORMAT), DDPF_RGB, 0, 16, 0x7C00,0x3E0,0x1F,0x8000 }, + &GUID_WICPixelFormat16bppBGRA5551, 16, DXGI_FORMAT_B5G5R5A1_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_RGB, 0, 16, 0xF00,0xF0,0xF,0xF000 }, + &GUID_WICPixelFormatUndefined, 0, DXGI_FORMAT_B4G4R4A4_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_ALPHA, 0, 8, 0,0,0,0xFF }, + &GUID_WICPixelFormat8bppAlpha, 8, DXGI_FORMAT_A8_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_LUMINANCE, 0, 16, 0xFFFF,0,0,0 }, + &GUID_WICPixelFormat16bppGray, 16, DXGI_FORMAT_R16_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_LUMINANCE, 0, 16, 0xFF,0,0,0xFF00 }, + &GUID_WICPixelFormatUndefined, 0, DXGI_FORMAT_R8G8_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_LUMINANCE, 0, 8, 0xFF,0,0,0 }, + &GUID_WICPixelFormat8bppGray, 8, DXGI_FORMAT_R8_UNORM }, + { { 0 }, &GUID_WICPixelFormat8bppAlpha, 8, DXGI_FORMAT_A8_UNORM }, + { { 0 }, &GUID_WICPixelFormat8bppGray, 8, DXGI_FORMAT_R8_UNORM }, + { { 0 }, &GUID_WICPixelFormat16bppGray, 16, DXGI_FORMAT_R16_UNORM }, + { { 0 }, &GUID_WICPixelFormat16bppGrayHalf, 16, DXGI_FORMAT_R16_FLOAT }, + { { 0 }, &GUID_WICPixelFormat16bppBGR565, 16, DXGI_FORMAT_B5G6R5_UNORM }, + { { 0 }, &GUID_WICPixelFormat16bppBGRA5551, 16, DXGI_FORMAT_B5G5R5A1_UNORM }, + { { 0 }, &GUID_WICPixelFormat32bppGrayFloat, 32, DXGI_FORMAT_R32_FLOAT }, + { { 0 }, &GUID_WICPixelFormat32bppRGBA, 32, DXGI_FORMAT_R8G8B8A8_UNORM }, + { { 0 }, &GUID_WICPixelFormat32bppBGRA, 32, DXGI_FORMAT_B8G8R8A8_UNORM }, + { { 0 }, &GUID_WICPixelFormat32bppBGR, 32, DXGI_FORMAT_B8G8R8X8_UNORM }, + { { 0 }, &GUID_WICPixelFormat32bppR10G10B10A2, 32, DXGI_FORMAT_R10G10B10A2_UNORM }, + { { 0 }, &GUID_WICPixelFormat32bppRGBE, 32, DXGI_FORMAT_R9G9B9E5_SHAREDEXP }, + { { 0 }, &GUID_WICPixelFormat32bppRGBA1010102XR, 32, DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM }, + { { 0 }, &GUID_WICPixelFormat64bppRGBA, 64, DXGI_FORMAT_R16G16B16A16_UNORM }, + { { 0 }, &GUID_WICPixelFormat64bppRGBAHalf, 64, DXGI_FORMAT_R16G16B16A16_FLOAT }, + { { 0 }, &GUID_WICPixelFormat96bppRGBFloat, 96, DXGI_FORMAT_R32G32B32_FLOAT }, + { { 0 }, &GUID_WICPixelFormat128bppRGBAFloat, 128, DXGI_FORMAT_R32G32B32A32_FLOAT }, + { { 0 }, &GUID_WICPixelFormatUndefined, 0, DXGI_FORMAT_UNKNOWN } +}; + +static DXGI_FORMAT compressed_formats[] = { + DXGI_FORMAT_BC1_TYPELESS, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM_SRGB, + DXGI_FORMAT_BC2_TYPELESS, DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM_SRGB, + DXGI_FORMAT_BC3_TYPELESS, DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_UNORM_SRGB, + DXGI_FORMAT_BC4_TYPELESS, DXGI_FORMAT_BC4_UNORM, DXGI_FORMAT_BC4_SNORM, + DXGI_FORMAT_BC5_TYPELESS, DXGI_FORMAT_BC5_UNORM, DXGI_FORMAT_BC5_SNORM, + DXGI_FORMAT_BC6H_TYPELESS, DXGI_FORMAT_BC6H_UF16, DXGI_FORMAT_BC6H_SF16, + DXGI_FORMAT_BC7_TYPELESS, DXGI_FORMAT_BC7_UNORM, DXGI_FORMAT_BC7_UNORM_SRGB +}; + +static HRESULT WINAPI DdsDecoder_Dds_GetFrame(IWICDdsDecoder *, UINT, UINT, UINT, IWICBitmapFrameDecode **); + +static DWORD rgb565_to_argb(WORD color, BYTE alpha) +{ + return MAKE_ARGB(alpha, (GET_RGB565_R(color) * 0xFF + 0x0F) / 0x1F, + (GET_RGB565_G(color) * 0xFF + 0x1F) / 0x3F, + (GET_RGB565_B(color) * 0xFF + 0x0F) / 0x1F); +} + +static inline BOOL has_extended_header(DDS_HEADER *header) +{ + return (header->ddspf.flags & DDPF_FOURCC) && + (header->ddspf.fourCC == MAKEFOURCC('D', 'X', '1', '0')); +} + +static WICDdsDimension get_dimension(DDS_HEADER *header, DDS_HEADER_DXT10 *header_dxt10) +{ + if (header_dxt10) { + if (header_dxt10->miscFlag & DDS_RESOURCE_MISC_TEXTURECUBE) return WICDdsTextureCube; + switch (header_dxt10->resourceDimension) + { + case DDS_DIMENSION_TEXTURE1D: return WICDdsTexture1D; + case DDS_DIMENSION_TEXTURE2D: return WICDdsTexture2D; + case DDS_DIMENSION_TEXTURE3D: return WICDdsTexture3D; + default: return WICDdsTexture2D; + } + } else { + if (header->caps2 & DDSCAPS2_CUBEMAP) { + return WICDdsTextureCube; + } else if (header->caps2 & DDSCAPS2_VOLUME) { + return WICDdsTexture3D; + } else { + return WICDdsTexture2D; + } + } +} + +static struct dds_format *get_dds_format(DDS_PIXELFORMAT *pixel_format) +{ + UINT i; + + for (i = 0; i < ARRAY_SIZE(dds_format_table); i++) + { + if ((pixel_format->flags & dds_format_table[i].pixel_format.flags) && + (pixel_format->fourCC == dds_format_table[i].pixel_format.fourCC) && + (pixel_format->rgbBitCount == dds_format_table[i].pixel_format.rgbBitCount) && + (pixel_format->rBitMask == dds_format_table[i].pixel_format.rBitMask) && + (pixel_format->gBitMask == dds_format_table[i].pixel_format.gBitMask) && + (pixel_format->bBitMask == dds_format_table[i].pixel_format.bBitMask) && + (pixel_format->aBitMask == dds_format_table[i].pixel_format.aBitMask)) + return dds_format_table + i; + } + + return dds_format_table + ARRAY_SIZE(dds_format_table) - 1; +} + +static WICDdsAlphaMode get_alpha_mode_from_fourcc(DWORD fourcc) +{ + switch (fourcc) + { + case MAKEFOURCC('D', 'X', 'T', '1'): + case MAKEFOURCC('D', 'X', 'T', '2'): + case MAKEFOURCC('D', 'X', 'T', '4'): + return WICDdsAlphaModePremultiplied; + default: + return WICDdsAlphaModeUnknown; + } +} + +static UINT get_bytes_per_block_from_format(DXGI_FORMAT format) +{ + /* for uncompressed format, return bytes per pixel*/ + switch (format) + { + case DXGI_FORMAT_R8_TYPELESS: + case DXGI_FORMAT_R8_UNORM: + case DXGI_FORMAT_R8_UINT: + case DXGI_FORMAT_R8_SNORM: + case DXGI_FORMAT_R8_SINT: + case DXGI_FORMAT_A8_UNORM: + return 1; + case DXGI_FORMAT_R8G8_TYPELESS: + case DXGI_FORMAT_R8G8_UNORM: + case DXGI_FORMAT_R8G8_UINT: + case DXGI_FORMAT_R8G8_SNORM: + case DXGI_FORMAT_R8G8_SINT: + case DXGI_FORMAT_R16_TYPELESS: + case DXGI_FORMAT_R16_FLOAT: + case DXGI_FORMAT_D16_UNORM: + case DXGI_FORMAT_R16_UNORM: + case DXGI_FORMAT_R16_UINT: + case DXGI_FORMAT_R16_SNORM: + case DXGI_FORMAT_R16_SINT: + case DXGI_FORMAT_B5G6R5_UNORM: + case DXGI_FORMAT_B5G5R5A1_UNORM: + case DXGI_FORMAT_B4G4R4A4_UNORM: + return 2; + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + case DXGI_FORMAT_R10G10B10A2_UNORM: + case DXGI_FORMAT_R10G10B10A2_UINT: + case DXGI_FORMAT_R11G11B10_FLOAT: + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + case DXGI_FORMAT_R8G8B8A8_UNORM: + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + case DXGI_FORMAT_R8G8B8A8_UINT: + case DXGI_FORMAT_R8G8B8A8_SNORM: + case DXGI_FORMAT_R8G8B8A8_SINT: + case DXGI_FORMAT_R16G16_TYPELESS: + case DXGI_FORMAT_R16G16_FLOAT: + case DXGI_FORMAT_R16G16_UNORM: + case DXGI_FORMAT_R16G16_UINT: + case DXGI_FORMAT_R16G16_SNORM: + case DXGI_FORMAT_R16G16_SINT: + case DXGI_FORMAT_R32_TYPELESS: + case DXGI_FORMAT_D32_FLOAT: + case DXGI_FORMAT_R32_FLOAT: + case DXGI_FORMAT_R32_UINT: + case DXGI_FORMAT_R32_SINT: + case DXGI_FORMAT_R24G8_TYPELESS: + case DXGI_FORMAT_D24_UNORM_S8_UINT: + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: + case DXGI_FORMAT_R8G8_B8G8_UNORM: + case DXGI_FORMAT_G8R8_G8B8_UNORM: + case DXGI_FORMAT_B8G8R8A8_UNORM: + case DXGI_FORMAT_B8G8R8X8_UNORM: + case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + case DXGI_FORMAT_B8G8R8X8_TYPELESS: + case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: + return 4; + case DXGI_FORMAT_BC1_UNORM: + case DXGI_FORMAT_BC1_TYPELESS: + case DXGI_FORMAT_BC1_UNORM_SRGB: + case DXGI_FORMAT_BC4_TYPELESS: + case DXGI_FORMAT_BC4_UNORM: + case DXGI_FORMAT_BC4_SNORM: + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + case DXGI_FORMAT_R16G16B16A16_FLOAT: + case DXGI_FORMAT_R16G16B16A16_UNORM: + case DXGI_FORMAT_R16G16B16A16_UINT: + case DXGI_FORMAT_R16G16B16A16_SNORM: + case DXGI_FORMAT_R16G16B16A16_SINT: + case DXGI_FORMAT_R32G32_TYPELESS: + case DXGI_FORMAT_R32G32_FLOAT: + case DXGI_FORMAT_R32G32_UINT: + case DXGI_FORMAT_R32G32_SINT: + case DXGI_FORMAT_R32G8X24_TYPELESS: + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: + return 8; + case DXGI_FORMAT_R32G32B32_TYPELESS: + case DXGI_FORMAT_R32G32B32_FLOAT: + case DXGI_FORMAT_R32G32B32_UINT: + case DXGI_FORMAT_R32G32B32_SINT: + return 12; + case DXGI_FORMAT_BC2_UNORM: + case DXGI_FORMAT_BC2_TYPELESS: + case DXGI_FORMAT_BC2_UNORM_SRGB: + case DXGI_FORMAT_BC3_UNORM: + case DXGI_FORMAT_BC3_TYPELESS: + case DXGI_FORMAT_BC3_UNORM_SRGB: + case DXGI_FORMAT_BC5_TYPELESS: + case DXGI_FORMAT_BC5_UNORM: + case DXGI_FORMAT_BC5_SNORM: + case DXGI_FORMAT_BC6H_TYPELESS: + case DXGI_FORMAT_BC6H_UF16: + case DXGI_FORMAT_BC6H_SF16: + case DXGI_FORMAT_BC7_TYPELESS: + case DXGI_FORMAT_BC7_UNORM: + case DXGI_FORMAT_BC7_UNORM_SRGB: + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + case DXGI_FORMAT_R32G32B32A32_FLOAT: + case DXGI_FORMAT_R32G32B32A32_UINT: + case DXGI_FORMAT_R32G32B32A32_SINT: + return 16; + default: + WARN("DXGI format 0x%x is not supported in DDS decoder\n", format); + return 0; + } +} + +static UINT get_frame_count(UINT depth, UINT mip_levels, UINT array_size, WICDdsDimension dimension) +{ + UINT frame_count, i; + + if (depth == 1) + { + frame_count = mip_levels; + } + else + { + frame_count = 0; + for (i = 0; i < mip_levels; i++) + { + frame_count += depth; + if (depth > 1) depth /= 2; + } + } + + frame_count *= array_size; + if (dimension == WICDdsTextureCube) frame_count *= 6; + + return frame_count; +} + +static void get_frame_dds_index(UINT index, dds_info *info, UINT *array_index, UINT *mip_level, UINT *slice_index) +{ + UINT frame_per_texture, depth; + + if (info->dimension == WICDdsTextureCube) + frame_per_texture = info->mip_levels; + else + frame_per_texture = info->frame_count / info->array_size; + + *array_index = index / frame_per_texture; + *slice_index = index % frame_per_texture; + depth = info->depth; + *mip_level = 0; + while (*slice_index >= depth) + { + *slice_index -= depth; + (*mip_level)++; + if (depth > 1) depth /= 2; + } +} + +static const GUID *dxgi_format_to_wic_format(DXGI_FORMAT dxgi_format) +{ + UINT i; + for (i = 0; i < ARRAY_SIZE(dds_format_table); i++) + { + if (dds_format_table[i].pixel_format.size == 0 && + dds_format_table[i].dxgi_format == dxgi_format) + return dds_format_table[i].wic_format; + } + return &GUID_WICPixelFormatUndefined; +} + +static BOOL is_compressed(DXGI_FORMAT format) +{ + UINT i; + + for (i = 0; i < ARRAY_SIZE(compressed_formats); i++) + { + if (format == compressed_formats[i]) return TRUE; + } + return FALSE; +} + +static void get_dds_info(dds_info* info, DDS_HEADER *header, DDS_HEADER_DXT10 *header_dxt10) +{ + struct dds_format *format_info; + + info->width = header->width; + info->height = header->height; + info->depth = 1; + info->mip_levels = 1; + info->array_size = 1; + if (header->depth) info->depth = header->depth; + if (header->mipMapCount) info->mip_levels = header->mipMapCount; + + if (has_extended_header(header)) { + if (header_dxt10->arraySize) info->array_size = header_dxt10->arraySize; + info->format = header_dxt10->dxgiFormat; + info->dimension = get_dimension(NULL, header_dxt10); + info->alpha_mode = header_dxt10->miscFlags2 & 0x00000008; + info->data_offset = sizeof(DWORD) + sizeof(*header) + sizeof(*header_dxt10); + if (is_compressed(info->format)) { + info->pixel_format = (info->alpha_mode == WICDdsAlphaModePremultiplied) ? + &GUID_WICPixelFormat32bppPBGRA : &GUID_WICPixelFormat32bppBGRA; + info->pixel_format_bpp = 32; + } else { + info->pixel_format = dxgi_format_to_wic_format(info->format); + info->pixel_format_bpp = get_bytes_per_block_from_format(info->format) * 8; + } + } else { + format_info = get_dds_format(&header->ddspf); + info->format = format_info->dxgi_format; + info->dimension = get_dimension(header, NULL); + info->alpha_mode = get_alpha_mode_from_fourcc(header->ddspf.fourCC); + info->data_offset = sizeof(DWORD) + sizeof(*header); + info->pixel_format = format_info->wic_format; + info->pixel_format_bpp = format_info->wic_format_bpp; + } + + if (header->ddspf.flags & (DDPF_RGB | DDPF_ALPHA | DDPF_LUMINANCE)) { + info->bytes_per_block = header->ddspf.rgbBitCount / 8; + } else { + info->bytes_per_block = get_bytes_per_block_from_format(info->format); + } + + info->frame_count = get_frame_count(info->depth, info->mip_levels, info->array_size, info->dimension); +} + +static void decode_block(const BYTE *block_data, UINT block_count, DXGI_FORMAT format, + UINT width, UINT height, DWORD *buffer) +{ + const BYTE *block, *color_indices, *alpha_indices, *alpha_table; + int i, j, x, y, block_x, block_y, color_index, alpha_index; + int block_size, color_offset, color_indices_offset; + WORD color[4], color_value = 0; + BYTE alpha[8], alpha_value = 0; + + if (format == DXGI_FORMAT_BC1_UNORM) { + block_size = 8; + color_offset = 0; + color_indices_offset = 4; + } else { + block_size = 16; + color_offset = 8; + color_indices_offset = 12; + } + block_x = 0; + block_y = 0; + + for (i = 0; i < block_count; i++) + { + block = block_data + i * block_size; + + color[0] = *((WORD *)(block + color_offset)); + color[1] = *((WORD *)(block + color_offset + 2)); + color[2] = MAKE_RGB565(((GET_RGB565_R(color[0]) * 2 + GET_RGB565_R(color[1]) + 1) / 3), + ((GET_RGB565_G(color[0]) * 2 + GET_RGB565_G(color[1]) + 1) / 3), + ((GET_RGB565_B(color[0]) * 2 + GET_RGB565_B(color[1]) + 1) / 3)); + color[3] = MAKE_RGB565(((GET_RGB565_R(color[0]) + GET_RGB565_R(color[1]) * 2 + 1) / 3), + ((GET_RGB565_G(color[0]) + GET_RGB565_G(color[1]) * 2 + 1) / 3), + ((GET_RGB565_B(color[0]) + GET_RGB565_B(color[1]) * 2 + 1) / 3)); + + switch (format) + { + case DXGI_FORMAT_BC1_UNORM: + if (color[0] <= color[1]) { + color[2] = MAKE_RGB565(((GET_RGB565_R(color[0]) + GET_RGB565_R(color[1]) + 1) / 2), + ((GET_RGB565_G(color[0]) + GET_RGB565_G(color[1]) + 1) / 2), + ((GET_RGB565_B(color[0]) + GET_RGB565_B(color[1]) + 1) / 2)); + color[3] = 0; + } + break; + case DXGI_FORMAT_BC2_UNORM: + alpha_table = block; + break; + case DXGI_FORMAT_BC3_UNORM: + alpha[0] = *block; + alpha[1] = *(block + 1); + if (alpha[0] > alpha[1]) { + for (j = 2; j < 8; j++) + { + alpha[j] = (BYTE)((alpha[0] * (8 - j) + alpha[1] * (j - 1) + 3) / 7); + } + } else { + for (j = 2; j < 6; j++) + { + alpha[j] = (BYTE)((alpha[0] * (6 - j) + alpha[1] * (j - 1) + 2) / 5); + } + alpha[6] = 0; + alpha[7] = 0xFF; + } + alpha_indices = block + 2; + break; + default: + break; + } + + color_indices = block + color_indices_offset; + for (j = 0; j < 16; j++) + { + x = block_x + j % 4; + y = block_y + j / 4; + if (x >= width || y >= height) continue; + + color_index = (color_indices[j / 4] >> ((j % 4) * 2)) & 0x3; + color_value = color[color_index]; + + switch (format) + { + case DXGI_FORMAT_BC1_UNORM: + if ((color[0] <= color[1]) && !color_value) { + color_value = 0; + alpha_value = 0; + } else { + alpha_value = 0xFF; + } + break; + case DXGI_FORMAT_BC2_UNORM: + alpha_value = (alpha_table[j / 2] >> (j % 2) * 4) & 0xF; + alpha_value = (BYTE)((alpha_value * 0xFF + 0x7)/ 0xF); + break; + case DXGI_FORMAT_BC3_UNORM: + alpha_index = (*((DWORD *)(alpha_indices + (j / 8) * 3)) >> ((j % 8) * 3)) & 0x7; + alpha_value = alpha[alpha_index]; + break; + default: + break; + } + buffer[x + y * width] = rgb565_to_argb(color_value, alpha_value); + } + + block_x += DDS_BLOCK_WIDTH; + if (block_x >= width) { + block_x = 0; + block_y += DDS_BLOCK_HEIGHT; + } + } +} + +static inline DdsDecoder *impl_from_IWICBitmapDecoder(IWICBitmapDecoder *iface) +{ + return CONTAINING_RECORD(iface, DdsDecoder, IWICBitmapDecoder_iface); +} + +static inline DdsDecoder *impl_from_IWICDdsDecoder(IWICDdsDecoder *iface) +{ + return CONTAINING_RECORD(iface, DdsDecoder, IWICDdsDecoder_iface); +} + +static inline DdsDecoder *impl_from_IWICWineDecoder(IWICWineDecoder *iface) +{ + return CONTAINING_RECORD(iface, DdsDecoder, IWICWineDecoder_iface); +} + +static inline DdsFrameDecode *impl_from_IWICBitmapFrameDecode(IWICBitmapFrameDecode *iface) +{ + return CONTAINING_RECORD(iface, DdsFrameDecode, IWICBitmapFrameDecode_iface); +} + +static inline DdsFrameDecode *impl_from_IWICDdsFrameDecode(IWICDdsFrameDecode *iface) +{ + return CONTAINING_RECORD(iface, DdsFrameDecode, IWICDdsFrameDecode_iface); +} + +static inline DdsEncoder *impl_from_IWICBitmapEncoder(IWICBitmapEncoder *iface) +{ + return CONTAINING_RECORD(iface, DdsEncoder, IWICBitmapEncoder_iface); +} + +static inline DdsEncoder *impl_from_IWICDdsEncoder(IWICDdsEncoder *iface) +{ + return CONTAINING_RECORD(iface, DdsEncoder, IWICDdsEncoder_iface); +} + +static inline DdsFrameEncode *impl_from_IWICBitmapFrameEncode(IWICBitmapFrameEncode *iface) +{ + return CONTAINING_RECORD(iface, DdsFrameEncode, IWICBitmapFrameEncode_iface); +} + +static HRESULT WINAPI DdsFrameDecode_QueryInterface(IWICBitmapFrameDecode *iface, REFIID iid, + void **ppv) +{ + DdsFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); + TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); + + if (!ppv) return E_INVALIDARG; + + if (IsEqualIID(&IID_IUnknown, iid) || + IsEqualIID(&IID_IWICBitmapSource, iid) || + IsEqualIID(&IID_IWICBitmapFrameDecode, iid)) { + *ppv = &This->IWICBitmapFrameDecode_iface; + } else if (IsEqualGUID(&IID_IWICDdsFrameDecode, iid)) { + *ppv = &This->IWICDdsFrameDecode_iface; + } else { + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI DdsFrameDecode_AddRef(IWICBitmapFrameDecode *iface) +{ + DdsFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) refcount=%lu\n", iface, ref); + + return ref; +} + +static ULONG WINAPI DdsFrameDecode_Release(IWICBitmapFrameDecode *iface) +{ + DdsFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) refcount=%lu\n", iface, ref); + + if (ref == 0) { + if (This->pixel_data != This->block_data) free(This->pixel_data); + free(This->block_data); + free(This); + } + + return ref; +} + +static HRESULT WINAPI DdsFrameDecode_GetSize(IWICBitmapFrameDecode *iface, + UINT *puiWidth, UINT *puiHeight) +{ + DdsFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); + + if (!puiWidth || !puiHeight) return E_INVALIDARG; + + *puiWidth = This->info.width; + *puiHeight = This->info.height; + + TRACE("(%p) -> (%d,%d)\n", iface, *puiWidth, *puiHeight); + + return S_OK; +} + +static HRESULT WINAPI DdsFrameDecode_GetPixelFormat(IWICBitmapFrameDecode *iface, + WICPixelFormatGUID *pPixelFormat) +{ + DdsFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); + + if (!pPixelFormat) return E_INVALIDARG; + + *pPixelFormat = *This->info.pixel_format; + + TRACE("(%p) -> %s\n", iface, debugstr_guid(pPixelFormat)); + + return S_OK; +} + +static HRESULT WINAPI DdsFrameDecode_GetResolution(IWICBitmapFrameDecode *iface, + double *pDpiX, double *pDpiY) +{ + FIXME("(%p,%p,%p): stub.\n", iface, pDpiX, pDpiY); + + return E_NOTIMPL; +} + +static HRESULT WINAPI DdsFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface, + IWICPalette *pIPalette) +{ + FIXME("(%p,%p): stub.\n", iface, pIPalette); + + return E_NOTIMPL; +} + +static HRESULT WINAPI DdsFrameDecode_CopyPixels(IWICBitmapFrameDecode *iface, + const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer) +{ + DdsFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); + UINT bpp, frame_stride, frame_size; + INT x, y, width, height; + HRESULT hr; + + TRACE("(%p,%s,%u,%u,%p)\n", iface, debug_wic_rect(prc), cbStride, cbBufferSize, pbBuffer); + + if (!pbBuffer) return E_INVALIDARG; + + bpp = This->info.pixel_format_bpp; + if (!bpp) return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; + + frame_stride = This->info.width * bpp / 8; + frame_size = frame_stride * This->info.height; + if (!prc) { + if (cbStride < frame_stride) return E_INVALIDARG; + if (cbBufferSize < frame_size) return WINCODEC_ERR_INSUFFICIENTBUFFER; + } else { + x = prc->X; + y = prc->Y; + width = prc->Width; + height = prc->Height; + if (x < 0 || y < 0 || width <= 0 || height <= 0 || + x + width > This->info.width || + y + height > This->info.height) { + return E_INVALIDARG; + } + if (cbStride < width * bpp / 8) return E_INVALIDARG; + if (cbBufferSize < cbStride * height) return WINCODEC_ERR_INSUFFICIENTBUFFER; + } + + EnterCriticalSection(&This->lock); + + if (!This->pixel_data) { + if (is_compressed(This->info.format)) { + This->pixel_data = malloc(frame_size); + if (!This->pixel_data) { + hr = E_OUTOFMEMORY; + goto end; + } + decode_block(This->block_data, This->info.width_in_blocks * This->info.height_in_blocks, This->info.format, + This->info.width, This->info.height, (DWORD *)This->pixel_data); + } else { + This->pixel_data = This->block_data; + } + } + + hr = copy_pixels(bpp, This->pixel_data, This->info.width, This->info.height, frame_stride, + prc, cbStride, cbBufferSize, pbBuffer); + +end: + LeaveCriticalSection(&This->lock); + + return hr; +} + +static HRESULT WINAPI DdsFrameDecode_GetMetadataQueryReader(IWICBitmapFrameDecode *iface, + IWICMetadataQueryReader **ppIMetadataQueryReader) +{ + FIXME("(%p,%p): stub.\n", iface, ppIMetadataQueryReader); + + return E_NOTIMPL; +} + +static HRESULT WINAPI DdsFrameDecode_GetColorContexts(IWICBitmapFrameDecode *iface, + UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount) +{ + FIXME("(%p,%u,%p,%p): stub.\n", iface, cCount, ppIColorContexts, pcActualCount); + + return E_NOTIMPL; +} + +static HRESULT WINAPI DdsFrameDecode_GetThumbnail(IWICBitmapFrameDecode *iface, + IWICBitmapSource **ppIThumbnail) +{ + FIXME("(%p,%p): stub.\n", iface, ppIThumbnail); + + return E_NOTIMPL; +} + +static const IWICBitmapFrameDecodeVtbl DdsFrameDecode_Vtbl = { + DdsFrameDecode_QueryInterface, + DdsFrameDecode_AddRef, + DdsFrameDecode_Release, + DdsFrameDecode_GetSize, + DdsFrameDecode_GetPixelFormat, + DdsFrameDecode_GetResolution, + DdsFrameDecode_CopyPalette, + DdsFrameDecode_CopyPixels, + DdsFrameDecode_GetMetadataQueryReader, + DdsFrameDecode_GetColorContexts, + DdsFrameDecode_GetThumbnail +}; + +static HRESULT WINAPI DdsFrameDecode_Dds_QueryInterface(IWICDdsFrameDecode *iface, + REFIID iid, void **ppv) +{ + DdsFrameDecode *This = impl_from_IWICDdsFrameDecode(iface); + return DdsFrameDecode_QueryInterface(&This->IWICBitmapFrameDecode_iface, iid, ppv); +} + +static ULONG WINAPI DdsFrameDecode_Dds_AddRef(IWICDdsFrameDecode *iface) +{ + DdsFrameDecode *This = impl_from_IWICDdsFrameDecode(iface); + return DdsFrameDecode_AddRef(&This->IWICBitmapFrameDecode_iface); +} + +static ULONG WINAPI DdsFrameDecode_Dds_Release(IWICDdsFrameDecode *iface) +{ + DdsFrameDecode *This = impl_from_IWICDdsFrameDecode(iface); + return DdsFrameDecode_Release(&This->IWICBitmapFrameDecode_iface); +} + +static HRESULT WINAPI DdsFrameDecode_Dds_GetSizeInBlocks(IWICDdsFrameDecode *iface, + UINT *widthInBlocks, UINT *heightInBlocks) +{ + DdsFrameDecode *This = impl_from_IWICDdsFrameDecode(iface); + + if (!widthInBlocks || !heightInBlocks) return E_INVALIDARG; + + *widthInBlocks = This->info.width_in_blocks; + *heightInBlocks = This->info.height_in_blocks; + + TRACE("(%p,%p,%p) -> (%d,%d)\n", iface, widthInBlocks, heightInBlocks, *widthInBlocks, *heightInBlocks); + + return S_OK; +} + +static HRESULT WINAPI DdsFrameDecode_Dds_GetFormatInfo(IWICDdsFrameDecode *iface, + WICDdsFormatInfo *formatInfo) +{ + DdsFrameDecode *This = impl_from_IWICDdsFrameDecode(iface); + + if (!formatInfo) return E_INVALIDARG; + + formatInfo->DxgiFormat = This->info.format; + formatInfo->BytesPerBlock = This->info.bytes_per_block; + formatInfo->BlockWidth = This->info.block_width; + formatInfo->BlockHeight = This->info.block_height; + + TRACE("(%p,%p) -> (0x%x,%d,%d,%d)\n", iface, formatInfo, + formatInfo->DxgiFormat, formatInfo->BytesPerBlock, formatInfo->BlockWidth, formatInfo->BlockHeight); + + return S_OK; +} + +static HRESULT WINAPI DdsFrameDecode_Dds_CopyBlocks(IWICDdsFrameDecode *iface, + const WICRect *boundsInBlocks, UINT stride, UINT bufferSize, + BYTE *buffer) +{ + DdsFrameDecode *This = impl_from_IWICDdsFrameDecode(iface); + int x, y, width, height; + UINT bytes_per_block, frame_stride, frame_size; + + TRACE("(%p,%p,%u,%u,%p)\n", iface, boundsInBlocks, stride, bufferSize, buffer); + + if (!buffer) return E_INVALIDARG; + + bytes_per_block = This->info.bytes_per_block; + frame_stride = This->info.width_in_blocks * bytes_per_block; + frame_size = frame_stride * This->info.height_in_blocks; + + if (!boundsInBlocks) { + if (stride < frame_stride) return E_INVALIDARG; + if (bufferSize < frame_size) return E_INVALIDARG; + } else { + x = boundsInBlocks->X; + y = boundsInBlocks->Y; + width = boundsInBlocks->Width; + height = boundsInBlocks->Height; + if (x < 0 || y < 0 || width <= 0 || height <= 0 || + x + width > This->info.width_in_blocks || + y + height > This->info.height_in_blocks) { + return E_INVALIDARG; + } + if (stride < width * bytes_per_block) return E_INVALIDARG; + if (bufferSize < stride * height) return E_INVALIDARG; + } + + return copy_pixels(This->info.bytes_per_block * 8, This->block_data, This->info.width_in_blocks, + This->info.height_in_blocks, frame_stride, boundsInBlocks, stride, bufferSize, buffer); +} + +static const IWICDdsFrameDecodeVtbl DdsFrameDecode_Dds_Vtbl = { + DdsFrameDecode_Dds_QueryInterface, + DdsFrameDecode_Dds_AddRef, + DdsFrameDecode_Dds_Release, + DdsFrameDecode_Dds_GetSizeInBlocks, + DdsFrameDecode_Dds_GetFormatInfo, + DdsFrameDecode_Dds_CopyBlocks +}; + +static HRESULT DdsFrameDecode_CreateInstance(DdsFrameDecode **frame_decode) +{ + DdsFrameDecode *result; + + result = malloc(sizeof(*result)); + if (!result) return E_OUTOFMEMORY; + + result->IWICBitmapFrameDecode_iface.lpVtbl = &DdsFrameDecode_Vtbl; + result->IWICDdsFrameDecode_iface.lpVtbl = &DdsFrameDecode_Dds_Vtbl; + result->ref = 1; +#ifdef __REACTOS__ + InitializeCriticalSection(&result->lock); +#else + InitializeCriticalSectionEx(&result->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif + result->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": DdsFrameDecode.lock"); + + *frame_decode = result; + return S_OK; +} + +static HRESULT WINAPI DdsDecoder_QueryInterface(IWICBitmapDecoder *iface, REFIID iid, + void **ppv) +{ + DdsDecoder *This = impl_from_IWICBitmapDecoder(iface); + TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); + + if (!ppv) return E_INVALIDARG; + + if (IsEqualIID(&IID_IUnknown, iid) || + IsEqualIID(&IID_IWICBitmapDecoder, iid)) { + *ppv = &This->IWICBitmapDecoder_iface; + } else if (IsEqualIID(&IID_IWICDdsDecoder, iid)) { + *ppv = &This->IWICDdsDecoder_iface; + } else if (IsEqualIID(&IID_IWICWineDecoder, iid)) { + *ppv = &This->IWICWineDecoder_iface; + } else { + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI DdsDecoder_AddRef(IWICBitmapDecoder *iface) +{ + DdsDecoder *This = impl_from_IWICBitmapDecoder(iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) refcount=%lu\n", iface, ref); + + return ref; +} + +static ULONG WINAPI DdsDecoder_Release(IWICBitmapDecoder *iface) +{ + DdsDecoder *This = impl_from_IWICBitmapDecoder(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) refcount=%lu\n", iface, ref); + + if (ref == 0) + { + This->lock.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&This->lock); + if (This->stream) IStream_Release(This->stream); + free(This); + } + + return ref; +} + +static HRESULT WINAPI DdsDecoder_QueryCapability(IWICBitmapDecoder *iface, IStream *stream, + DWORD *capability) +{ + FIXME("(%p,%p,%p): stub.\n", iface, stream, capability); + + return E_NOTIMPL; +} + +static HRESULT WINAPI DdsDecoder_Initialize(IWICBitmapDecoder *iface, IStream *pIStream, + WICDecodeOptions cacheOptions) +{ + DdsDecoder *This = impl_from_IWICBitmapDecoder(iface); + HRESULT hr; + + TRACE("(%p,%p,%x)\n", iface, pIStream, cacheOptions); + + EnterCriticalSection(&This->lock); + + hr = IWICWineDecoder_Initialize(&This->IWICWineDecoder_iface, pIStream, cacheOptions); + if (FAILED(hr)) goto end; + + if (This->info.dimension == WICDdsTextureCube || + (This->info.format != DXGI_FORMAT_BC1_UNORM && + This->info.format != DXGI_FORMAT_BC2_UNORM && + This->info.format != DXGI_FORMAT_BC3_UNORM)) { + IStream_Release(pIStream); + This->stream = NULL; + This->initialized = FALSE; + hr = WINCODEC_ERR_BADHEADER; + } + +end: + LeaveCriticalSection(&This->lock); + + return hr; +} + +static HRESULT WINAPI DdsDecoder_GetContainerFormat(IWICBitmapDecoder *iface, + GUID *pguidContainerFormat) +{ + TRACE("(%p,%p)\n", iface, pguidContainerFormat); + + memcpy(pguidContainerFormat, &GUID_ContainerFormatDds, sizeof(GUID)); + + return S_OK; +} + +static HRESULT WINAPI DdsDecoder_GetDecoderInfo(IWICBitmapDecoder *iface, + IWICBitmapDecoderInfo **ppIDecoderInfo) +{ + TRACE("(%p,%p)\n", iface, ppIDecoderInfo); + + return get_decoder_info(&CLSID_WICDdsDecoder, ppIDecoderInfo); +} + +static HRESULT WINAPI DdsDecoder_CopyPalette(IWICBitmapDecoder *iface, + IWICPalette *pIPalette) +{ + TRACE("(%p,%p)\n", iface, pIPalette); + + return WINCODEC_ERR_PALETTEUNAVAILABLE; +} + +static HRESULT WINAPI DdsDecoder_GetMetadataQueryReader(IWICBitmapDecoder *iface, + IWICMetadataQueryReader **ppIMetadataQueryReader) +{ + if (!ppIMetadataQueryReader) return E_INVALIDARG; + + FIXME("(%p,%p)\n", iface, ppIMetadataQueryReader); + + return E_NOTIMPL; +} + +static HRESULT WINAPI DdsDecoder_GetPreview(IWICBitmapDecoder *iface, + IWICBitmapSource **ppIBitmapSource) +{ + TRACE("(%p,%p)\n", iface, ppIBitmapSource); + + return WINCODEC_ERR_UNSUPPORTEDOPERATION; +} + +static HRESULT WINAPI DdsDecoder_GetColorContexts(IWICBitmapDecoder *iface, + UINT cCount, IWICColorContext **ppDdslorContexts, UINT *pcActualCount) +{ + TRACE("(%p,%u,%p,%p)\n", iface, cCount, ppDdslorContexts, pcActualCount); + + return WINCODEC_ERR_UNSUPPORTEDOPERATION; +} + +static HRESULT WINAPI DdsDecoder_GetThumbnail(IWICBitmapDecoder *iface, + IWICBitmapSource **ppIThumbnail) +{ + TRACE("(%p,%p)\n", iface, ppIThumbnail); + + return WINCODEC_ERR_CODECNOTHUMBNAIL; +} + +static HRESULT WINAPI DdsDecoder_GetFrameCount(IWICBitmapDecoder *iface, + UINT *pCount) +{ + DdsDecoder *This = impl_from_IWICBitmapDecoder(iface); + + if (!pCount) return E_INVALIDARG; + if (!This->initialized) return WINCODEC_ERR_WRONGSTATE; + + EnterCriticalSection(&This->lock); + + *pCount = This->info.frame_count; + + LeaveCriticalSection(&This->lock); + + TRACE("(%p) -> %d\n", iface, *pCount); + + return S_OK; +} + +static HRESULT WINAPI DdsDecoder_GetFrame(IWICBitmapDecoder *iface, + UINT index, IWICBitmapFrameDecode **ppIBitmapFrame) +{ + DdsDecoder *This = impl_from_IWICBitmapDecoder(iface); + UINT array_index, mip_level, slice_index; + + TRACE("(%p,%u,%p)\n", iface, index, ppIBitmapFrame); + + if (!ppIBitmapFrame) return E_INVALIDARG; + + EnterCriticalSection(&This->lock); + + if (!This->initialized) { + LeaveCriticalSection(&This->lock); + return WINCODEC_ERR_WRONGSTATE; + } + + get_frame_dds_index(index, &This->info, &array_index, &mip_level, &slice_index); + + LeaveCriticalSection(&This->lock); + + return DdsDecoder_Dds_GetFrame(&This->IWICDdsDecoder_iface, array_index, mip_level, slice_index, ppIBitmapFrame); +} + +static const IWICBitmapDecoderVtbl DdsDecoder_Vtbl = { + DdsDecoder_QueryInterface, + DdsDecoder_AddRef, + DdsDecoder_Release, + DdsDecoder_QueryCapability, + DdsDecoder_Initialize, + DdsDecoder_GetContainerFormat, + DdsDecoder_GetDecoderInfo, + DdsDecoder_CopyPalette, + DdsDecoder_GetMetadataQueryReader, + DdsDecoder_GetPreview, + DdsDecoder_GetColorContexts, + DdsDecoder_GetThumbnail, + DdsDecoder_GetFrameCount, + DdsDecoder_GetFrame +}; + +static HRESULT WINAPI DdsDecoder_Dds_QueryInterface(IWICDdsDecoder *iface, + REFIID iid, void **ppv) +{ + DdsDecoder *This = impl_from_IWICDdsDecoder(iface); + return DdsDecoder_QueryInterface(&This->IWICBitmapDecoder_iface, iid, ppv); +} + +static ULONG WINAPI DdsDecoder_Dds_AddRef(IWICDdsDecoder *iface) +{ + DdsDecoder *This = impl_from_IWICDdsDecoder(iface); + return DdsDecoder_AddRef(&This->IWICBitmapDecoder_iface); +} + +static ULONG WINAPI DdsDecoder_Dds_Release(IWICDdsDecoder *iface) +{ + DdsDecoder *This = impl_from_IWICDdsDecoder(iface); + return DdsDecoder_Release(&This->IWICBitmapDecoder_iface); +} + +static HRESULT WINAPI DdsDecoder_Dds_GetParameters(IWICDdsDecoder *iface, + WICDdsParameters *parameters) +{ + DdsDecoder *This = impl_from_IWICDdsDecoder(iface); + HRESULT hr; + + if (!parameters) return E_INVALIDARG; + + EnterCriticalSection(&This->lock); + + if (!This->initialized) { + hr = WINCODEC_ERR_WRONGSTATE; + goto end; + } + + parameters->Width = This->info.width; + parameters->Height = This->info.height; + parameters->Depth = This->info.depth; + parameters->MipLevels = This->info.mip_levels; + parameters->ArraySize = This->info.array_size; + parameters->DxgiFormat = This->info.format; + parameters->Dimension = This->info.dimension; + parameters->AlphaMode = This->info.alpha_mode; + + TRACE("(%p) -> (%dx%d depth=%d mipLevels=%d arraySize=%d dxgiFormat=0x%x dimension=0x%x alphaMode=0x%x)\n", + iface, parameters->Width, parameters->Height, parameters->Depth, parameters->MipLevels, + parameters->ArraySize, parameters->DxgiFormat, parameters->Dimension, parameters->AlphaMode); + + hr = S_OK; + +end: + LeaveCriticalSection(&This->lock); + + return hr; +} + +static HRESULT WINAPI DdsDecoder_Dds_GetFrame(IWICDdsDecoder *iface, + UINT arrayIndex, UINT mipLevel, UINT sliceIndex, + IWICBitmapFrameDecode **bitmapFrame) +{ + DdsDecoder *This = impl_from_IWICDdsDecoder(iface); + HRESULT hr; + LARGE_INTEGER seek; + UINT width, height, depth, block_width, block_height, width_in_blocks, height_in_blocks, size; + UINT frame_width = 0, frame_height = 0, frame_width_in_blocks = 0, frame_height_in_blocks = 0, frame_size = 0; + UINT bytes_per_block, i; + DWORD bytesread; + DdsFrameDecode *frame_decode = NULL; + + TRACE("(%p,%u,%u,%u,%p)\n", iface, arrayIndex, mipLevel, sliceIndex, bitmapFrame); + + if (!bitmapFrame) return E_INVALIDARG; + + EnterCriticalSection(&This->lock); + + if (!This->initialized) { + hr = WINCODEC_ERR_WRONGSTATE; + goto end; + } + + if ((arrayIndex >= This->info.array_size && This->info.dimension != WICDdsTextureCube) || + (arrayIndex >= This->info.array_size * 6) || + (mipLevel >= This->info.mip_levels) || + (sliceIndex >= This->info.depth)) { + hr = E_INVALIDARG; + goto end; + } + + if (is_compressed(This->info.format)) { + block_width = DDS_BLOCK_WIDTH; + block_height = DDS_BLOCK_HEIGHT; + } else { + block_width = 1; + block_height = 1; + } + bytes_per_block = This->info.bytes_per_block; + seek.QuadPart = This->info.data_offset; + + width = This->info.width; + height = This->info.height; + depth = This->info.depth; + for (i = 0; i < This->info.mip_levels; i++) + { + width_in_blocks = (width + block_width - 1) / block_width; + height_in_blocks = (height + block_height - 1) / block_height; + size = width_in_blocks * height_in_blocks * bytes_per_block; + + if (i < mipLevel) { + seek.QuadPart += size * depth; + } else if (i == mipLevel){ + seek.QuadPart += size * sliceIndex; + frame_width = width; + frame_height = height; + frame_width_in_blocks = width_in_blocks; + frame_height_in_blocks = height_in_blocks; + frame_size = frame_width_in_blocks * frame_height_in_blocks * bytes_per_block; + if (arrayIndex == 0) break; + } + seek.QuadPart += arrayIndex * size * depth; + + if (width > 1) width /= 2; + if (height > 1) height /= 2; + if (depth > 1) depth /= 2; + } + + hr = DdsFrameDecode_CreateInstance(&frame_decode); + if (hr != S_OK) goto end; + frame_decode->info.width = frame_width; + frame_decode->info.height = frame_height; + frame_decode->info.format = This->info.format; + frame_decode->info.bytes_per_block = bytes_per_block; + frame_decode->info.block_width = block_width; + frame_decode->info.block_height = block_height; + frame_decode->info.width_in_blocks = frame_width_in_blocks; + frame_decode->info.height_in_blocks = frame_height_in_blocks; + frame_decode->info.pixel_format = This->info.pixel_format; + frame_decode->info.pixel_format_bpp = This->info.pixel_format_bpp; + frame_decode->block_data = malloc(frame_size); + frame_decode->pixel_data = NULL; + hr = IStream_Seek(This->stream, seek, SEEK_SET, NULL); + if (hr != S_OK) goto end; + hr = IStream_Read(This->stream, frame_decode->block_data, frame_size, &bytesread); + if (hr != S_OK || bytesread != frame_size) { + hr = WINCODEC_ERR_STREAMREAD; + goto end; + } + *bitmapFrame = &frame_decode->IWICBitmapFrameDecode_iface; + + hr = S_OK; + +end: + LeaveCriticalSection(&This->lock); + + if (hr != S_OK && frame_decode) DdsFrameDecode_Release(&frame_decode->IWICBitmapFrameDecode_iface); + + return hr; +} + +static const IWICDdsDecoderVtbl DdsDecoder_Dds_Vtbl = { + DdsDecoder_Dds_QueryInterface, + DdsDecoder_Dds_AddRef, + DdsDecoder_Dds_Release, + DdsDecoder_Dds_GetParameters, + DdsDecoder_Dds_GetFrame +}; + +static HRESULT WINAPI DdsDecoder_Wine_QueryInterface(IWICWineDecoder *iface, REFIID iid, void **ppv) +{ + DdsDecoder *This = impl_from_IWICWineDecoder(iface); + return DdsDecoder_QueryInterface(&This->IWICBitmapDecoder_iface, iid, ppv); +} + +static ULONG WINAPI DdsDecoder_Wine_AddRef(IWICWineDecoder *iface) +{ + DdsDecoder *This = impl_from_IWICWineDecoder(iface); + return DdsDecoder_AddRef(&This->IWICBitmapDecoder_iface); +} + +static ULONG WINAPI DdsDecoder_Wine_Release(IWICWineDecoder *iface) +{ + DdsDecoder *This = impl_from_IWICWineDecoder(iface); + return DdsDecoder_Release(&This->IWICBitmapDecoder_iface); +} + +static HRESULT WINAPI DdsDecoder_Wine_Initialize(IWICWineDecoder *iface, IStream *stream, WICDecodeOptions options) +{ + DdsDecoder *This = impl_from_IWICWineDecoder(iface); + DDS_HEADER_DXT10 header_dxt10; + LARGE_INTEGER seek; + DDS_HEADER header; + ULONG bytesread; + DWORD magic; + HRESULT hr; + + TRACE("(This %p, stream %p, options %#x)\n", iface, stream, options); + + EnterCriticalSection(&This->lock); + + if (This->initialized) { + hr = WINCODEC_ERR_WRONGSTATE; + goto end; + } + + seek.QuadPart = 0; + hr = IStream_Seek(stream, seek, SEEK_SET, NULL); + if (FAILED(hr)) goto end; + + hr = IStream_Read(stream, &magic, sizeof(magic), &bytesread); + if (FAILED(hr)) goto end; + if (bytesread != sizeof(magic)) { + hr = WINCODEC_ERR_STREAMREAD; + goto end; + } + if (magic != DDS_MAGIC) { + hr = WINCODEC_ERR_UNKNOWNIMAGEFORMAT; + goto end; + } + + hr = IStream_Read(stream, &header, sizeof(header), &bytesread); + if (FAILED(hr)) goto end; + if (bytesread != sizeof(header)) { + hr = WINCODEC_ERR_STREAMREAD; + goto end; + } + if (header.size != sizeof(header)) { + hr = WINCODEC_ERR_BADHEADER; + goto end; + } + + if (has_extended_header(&header)) { + hr = IStream_Read(stream, &header_dxt10, sizeof(header_dxt10), &bytesread); + if (FAILED(hr)) goto end; + if (bytesread != sizeof(header_dxt10)) { + hr = WINCODEC_ERR_STREAMREAD; + goto end; + } + } + + get_dds_info(&This->info, &header, &header_dxt10); + + This->initialized = TRUE; + This->stream = stream; + IStream_AddRef(stream); + +end: + LeaveCriticalSection(&This->lock); + + return hr; +} + +static const IWICWineDecoderVtbl DdsDecoder_Wine_Vtbl = { + DdsDecoder_Wine_QueryInterface, + DdsDecoder_Wine_AddRef, + DdsDecoder_Wine_Release, + DdsDecoder_Wine_Initialize +}; + +static HRESULT WINAPI DdsFrameEncode_QueryInterface(IWICBitmapFrameEncode *iface, REFIID iid, void **ppv) +{ + DdsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); + TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); + + if (!ppv) return E_INVALIDARG; + + if (IsEqualIID(&IID_IUnknown, iid) || + IsEqualIID(&IID_IWICBitmapFrameEncode, iid)) + { + *ppv = &This->IWICBitmapFrameEncode_iface; + } + else + { + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI DdsFrameEncode_AddRef(IWICBitmapFrameEncode *iface) +{ + DdsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) refcount=%lu\n", iface, ref); + + return ref; +} + +static ULONG WINAPI DdsFrameEncode_Release(IWICBitmapFrameEncode *iface) +{ + DdsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) refcount=%lu\n", iface, ref); + + if (ref == 0) + { + IWICBitmapEncoder_Release(&This->parent->IWICBitmapEncoder_iface); + free(This); + } + + return ref; +} + +static HRESULT WINAPI DdsFrameEncode_Initialize(IWICBitmapFrameEncode *iface, + IPropertyBag2 *encoderOptions) +{ + DdsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); + HRESULT hr; + + TRACE("(%p,%p)\n", iface, encoderOptions); + if (encoderOptions) FIXME("encoder options are not supported for DDS.\n"); + + EnterCriticalSection(&This->parent->lock); + + if (This->initialized) + { + hr = WINCODEC_ERR_WRONGSTATE; + } + else + { + This->initialized = TRUE; + hr = S_OK; + } + + LeaveCriticalSection(&This->parent->lock); + + return hr; +} + +static HRESULT WINAPI DdsFrameEncode_SetSize(IWICBitmapFrameEncode *iface, + UINT width, UINT height) +{ + DdsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); + HRESULT hr; + + TRACE("(%p,%u,%u)\n", iface, width, height); + + EnterCriticalSection(&This->parent->lock); + + if (!This->initialized || This->frame_created) + { + hr = WINCODEC_ERR_WRONGSTATE; + } + else + { + This->width = width; + This->height = height; + hr = S_OK; + } + + LeaveCriticalSection(&This->parent->lock); + + return hr; +} + +static HRESULT WINAPI DdsFrameEncode_SetResolution(IWICBitmapFrameEncode *iface, + double dpiX, double dpiY) +{ + DdsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); + HRESULT hr; + + TRACE("(%p,%0.2f,%0.2f)\n", iface, dpiX, dpiY); + + EnterCriticalSection(&This->parent->lock); + + if (!This->initialized || This->frame_created) + { + hr = WINCODEC_ERR_WRONGSTATE; + } + else + { + This->dpi_x = dpiX; + This->dpi_y = dpiY; + hr = S_OK; + } + + LeaveCriticalSection(&This->parent->lock); + + return hr; +} + +static HRESULT WINAPI DdsFrameEncode_SetPixelFormat(IWICBitmapFrameEncode *iface, + WICPixelFormatGUID *pixelFormat) +{ + DdsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); + HRESULT hr; + + TRACE("(%p,%s)\n", iface, debugstr_guid(pixelFormat)); + + EnterCriticalSection(&This->parent->lock); + + if (!This->initialized) + { + hr = WINCODEC_ERR_NOTINITIALIZED; + } + else if (This->frame_created) + { + hr = WINCODEC_ERR_WRONGSTATE; + } + else + { + *pixelFormat = GUID_WICPixelFormat32bppBGRA; + hr = S_OK; + } + + LeaveCriticalSection(&This->parent->lock); + + return hr; +} + +static HRESULT WINAPI DdsFrameEncode_SetColorContexts(IWICBitmapFrameEncode *iface, + UINT count, IWICColorContext **colorContext) +{ + FIXME("(%p,%u,%p): stub\n", iface, count, colorContext); + return E_NOTIMPL; +} + +static HRESULT WINAPI DdsFrameEncode_SetPalette(IWICBitmapFrameEncode *iface, + IWICPalette *palette) +{ + FIXME("(%p,%p): stub\n", iface, palette); + return E_NOTIMPL; +} + +static HRESULT WINAPI DdsFrameEncode_SetThumbnail(IWICBitmapFrameEncode *iface, + IWICBitmapSource *thumbnail) +{ + TRACE("(%p,%p)\n", iface, thumbnail); + return WINCODEC_ERR_UNSUPPORTEDOPERATION; +} + +static HRESULT WINAPI DdsFrameEncode_WritePixels(IWICBitmapFrameEncode *iface, + UINT lineCount, UINT stride, UINT bufferSize, BYTE *pixels) +{ + FIXME("(%p,%u,%u,%u,%p): stub\n", iface, lineCount, stride, bufferSize, pixels); + return E_NOTIMPL; +} + +static HRESULT WINAPI DdsFrameEncode_WriteSource(IWICBitmapFrameEncode *iface, + IWICBitmapSource *bitmapSource, WICRect *rc) +{ + FIXME("(%p,%p,%s): stub\n", iface, bitmapSource, debug_wic_rect(rc)); + return E_NOTIMPL; +} + +static HRESULT WINAPI DdsFrameEncode_Commit(IWICBitmapFrameEncode *iface) +{ + FIXME("(%p): stub\n", iface); + return E_NOTIMPL; +} + +static HRESULT WINAPI DdsFrameEncode_GetMetadataQueryWriter(IWICBitmapFrameEncode *iface, + IWICMetadataQueryWriter **metadataQueryWriter) +{ + FIXME("(%p,%p): stub\n", iface, metadataQueryWriter); + return E_NOTIMPL; +} + +static const IWICBitmapFrameEncodeVtbl DdsFrameEncode_Vtbl = { + DdsFrameEncode_QueryInterface, + DdsFrameEncode_AddRef, + DdsFrameEncode_Release, + DdsFrameEncode_Initialize, + DdsFrameEncode_SetSize, + DdsFrameEncode_SetResolution, + DdsFrameEncode_SetPixelFormat, + DdsFrameEncode_SetColorContexts, + DdsFrameEncode_SetPalette, + DdsFrameEncode_SetThumbnail, + DdsFrameEncode_WritePixels, + DdsFrameEncode_WriteSource, + DdsFrameEncode_Commit, + DdsFrameEncode_GetMetadataQueryWriter +}; + +HRESULT DdsDecoder_CreateInstance(REFIID iid, void** ppv) +{ + DdsDecoder *This; + HRESULT ret; + + TRACE("(%s,%p)\n", debugstr_guid(iid), ppv); + + *ppv = NULL; + + This = malloc(sizeof(DdsDecoder)); + if (!This) return E_OUTOFMEMORY; + + This->IWICBitmapDecoder_iface.lpVtbl = &DdsDecoder_Vtbl; + This->IWICDdsDecoder_iface.lpVtbl = &DdsDecoder_Dds_Vtbl; + This->IWICWineDecoder_iface.lpVtbl = &DdsDecoder_Wine_Vtbl; + This->ref = 1; + This->initialized = FALSE; + This->stream = NULL; +#ifdef __REACTOS__ + InitializeCriticalSection(&This->lock); +#else + InitializeCriticalSectionEx(&This->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif + This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": DdsDecoder.lock"); + + ret = IWICBitmapDecoder_QueryInterface(&This->IWICBitmapDecoder_iface, iid, ppv); + IWICBitmapDecoder_Release(&This->IWICBitmapDecoder_iface); + + return ret; +} + +static HRESULT WINAPI DdsEncoder_Dds_QueryInterface(IWICDdsEncoder *iface, REFIID iid, + void **ppv) +{ + DdsEncoder *This = impl_from_IWICDdsEncoder(iface); + return IWICBitmapEncoder_QueryInterface(&This->IWICBitmapEncoder_iface, iid, ppv); +} + +static ULONG WINAPI DdsEncoder_Dds_AddRef(IWICDdsEncoder *iface) +{ + DdsEncoder *This = impl_from_IWICDdsEncoder(iface); + return IWICBitmapEncoder_AddRef(&This->IWICBitmapEncoder_iface); +} + +static ULONG WINAPI DdsEncoder_Dds_Release(IWICDdsEncoder *iface) +{ + DdsEncoder *This = impl_from_IWICDdsEncoder(iface); + return IWICBitmapEncoder_Release(&This->IWICBitmapEncoder_iface); +} + +static HRESULT WINAPI DdsEncoder_Dds_SetParameters(IWICDdsEncoder *iface, + WICDdsParameters *parameters) +{ + DdsEncoder *This = impl_from_IWICDdsEncoder(iface); + HRESULT hr; + + TRACE("(%p,%p)\n", iface, parameters); + + if (!parameters) return E_INVALIDARG; + + EnterCriticalSection(&This->lock); + + if (!This->stream) + { + hr = WINCODEC_ERR_WRONGSTATE; + goto end; + } + + This->info.width = parameters->Width; + This->info.height = parameters->Height; + This->info.depth = parameters->Depth; + This->info.mip_levels = parameters->MipLevels; + This->info.array_size = parameters->ArraySize; + This->info.format = parameters->DxgiFormat; + This->info.dimension = parameters->Dimension; + This->info.alpha_mode = parameters->AlphaMode; + + This->info.bytes_per_block = get_bytes_per_block_from_format(This->info.format); + This->info.frame_count = get_frame_count(This->info.depth, This->info.mip_levels, + This->info.array_size, This->info.dimension); + + hr = S_OK; + +end: + LeaveCriticalSection(&This->lock); + return hr; +} + +static HRESULT WINAPI DdsEncoder_Dds_GetParameters(IWICDdsEncoder *iface, + WICDdsParameters *parameters) +{ + DdsEncoder *This = impl_from_IWICDdsEncoder(iface); + HRESULT hr; + + TRACE("(%p,%p)\n", iface, parameters); + + if (!parameters) return E_INVALIDARG; + + EnterCriticalSection(&This->lock); + + if (!This->stream) + { + hr = WINCODEC_ERR_WRONGSTATE; + goto end; + } + + parameters->Width = This->info.width; + parameters->Height = This->info.height; + parameters->Depth = This->info.depth; + parameters->MipLevels = This->info.mip_levels; + parameters->ArraySize = This->info.array_size; + parameters->DxgiFormat = This->info.format; + parameters->Dimension = This->info.dimension; + parameters->AlphaMode = This->info.alpha_mode; + + TRACE("(%p,%p) -> (%dx%d depth=%u mipLevels=%u arraySize=%u dxgiFormat=%#x dimension=%#x alphaMode=%#x)\n", + iface, parameters, parameters->Width, parameters->Height, parameters->Depth, parameters->MipLevels, + parameters->ArraySize, parameters->DxgiFormat, parameters->Dimension, parameters->AlphaMode); + + hr = S_OK; + +end: + LeaveCriticalSection(&This->lock); + return hr; +} + +static HRESULT WINAPI DdsEncoder_Dds_CreateNewFrame(IWICDdsEncoder *iface, + IWICBitmapFrameEncode **frameEncode, + UINT *arrayIndex, UINT *mipLevel, UINT *sliceIndex) +{ + DdsEncoder *This = impl_from_IWICDdsEncoder(iface); + UINT array_index, mip_level, slice_index; + DdsFrameEncode *result; + HRESULT hr; + + TRACE("(%p,%p,%p,%p,%p)\n", iface, frameEncode, arrayIndex, mipLevel, sliceIndex); + + EnterCriticalSection(&This->lock); + + if (!This->stream || This->committed || This->uncommitted_frame) + { + hr = WINCODEC_ERR_WRONGSTATE; + goto end; + } + + result = malloc(sizeof(*result)); + if (!result) + { + hr = E_OUTOFMEMORY; + goto end; + } + + get_frame_dds_index(This->frame_index, &This->info, &array_index, &mip_level, &slice_index); + if (arrayIndex) *arrayIndex = array_index; + if (mipLevel) *mipLevel = mip_level; + if (sliceIndex) *sliceIndex = slice_index; + + This->frame_index++; + result->IWICBitmapFrameEncode_iface.lpVtbl = &DdsFrameEncode_Vtbl; + result->ref = 1; + result->parent = This; + result->parent->uncommitted_frame = TRUE; + result->initialized = FALSE; + result->frame_created = FALSE; + IWICDdsEncoder_AddRef(iface); + + *frameEncode = &result->IWICBitmapFrameEncode_iface; + hr = S_OK; + +end: + LeaveCriticalSection(&This->lock); + return hr; +} + +static const IWICDdsEncoderVtbl DdsEncoder_Dds_Vtbl = +{ + DdsEncoder_Dds_QueryInterface, + DdsEncoder_Dds_AddRef, + DdsEncoder_Dds_Release, + DdsEncoder_Dds_SetParameters, + DdsEncoder_Dds_GetParameters, + DdsEncoder_Dds_CreateNewFrame +}; + +static HRESULT WINAPI DdsEncoder_QueryInterface(IWICBitmapEncoder *iface, REFIID iid, + void **ppv) +{ + DdsEncoder *This = impl_from_IWICBitmapEncoder(iface); + FIXME("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); + + if (!ppv) return E_INVALIDARG; + + if (IsEqualIID(&IID_IUnknown, iid) || + IsEqualIID(&IID_IWICBitmapEncoder, iid)) { + *ppv = &This->IWICBitmapEncoder_iface; + } else if (IsEqualIID(&IID_IWICDdsEncoder, iid)) { + *ppv = &This->IWICDdsEncoder_iface; + } else { + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI DdsEncoder_AddRef(IWICBitmapEncoder *iface) +{ + DdsEncoder *This = impl_from_IWICBitmapEncoder(iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) refcount=%lu\n", iface, ref); + + return ref; +} + +static ULONG WINAPI DdsEncoder_Release(IWICBitmapEncoder *iface) +{ + DdsEncoder *This = impl_from_IWICBitmapEncoder(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) refcount=%lu\n", iface, ref); + + if (ref == 0) { + This->lock.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&This->lock); + if (This->stream) IStream_Release(This->stream); + free(This); + } + + return ref; +} + +static HRESULT WINAPI DdsEncoder_Initialize(IWICBitmapEncoder *iface, + IStream *stream, WICBitmapEncoderCacheOption cacheOption) +{ + DdsEncoder *This = impl_from_IWICBitmapEncoder(iface); + HRESULT hr; + + TRACE("(%p,%p,%u)\n", iface, stream, cacheOption); + + if (cacheOption != WICBitmapEncoderNoCache) + FIXME("Cache option %#x is not supported.\n", cacheOption); + + if (!stream) return E_INVALIDARG; + + EnterCriticalSection(&This->lock); + + if (This->stream) + { + hr = WINCODEC_ERR_WRONGSTATE; + goto end; + } + + This->stream = stream; + IStream_AddRef(stream); + + This->info.width = 1; + This->info.height = 1; + This->info.depth = 1; + This->info.mip_levels = 1; + This->info.array_size = 1; + This->info.frame_count = 1; + This->info.data_offset = 0; + This->info.bytes_per_block = get_bytes_per_block_from_format(DXGI_FORMAT_BC3_UNORM); + This->info.format = DXGI_FORMAT_BC3_UNORM; + This->info.dimension = WICDdsTexture2D; + This->info.alpha_mode = WICDdsAlphaModeUnknown; + This->info.pixel_format = &GUID_WICPixelFormatUndefined; + This->info.pixel_format_bpp = 0; + + hr = S_OK; + +end: + LeaveCriticalSection(&This->lock); + + return hr; +} + +static HRESULT WINAPI DdsEncoder_GetContainerFormat(IWICBitmapEncoder *iface, GUID *format) +{ + TRACE("(%p,%p)\n", iface, format); + + if (!format) + return E_INVALIDARG; + + memcpy(format, &GUID_ContainerFormatDds, sizeof(*format)); + return S_OK; +} + +static HRESULT WINAPI DdsEncoder_GetEncoderInfo(IWICBitmapEncoder *iface, IWICBitmapEncoderInfo **info) +{ + IWICComponentInfo *comp_info; + HRESULT hr; + + TRACE("%p,%p\n", iface, info); + + if (!info) return E_INVALIDARG; + + hr = CreateComponentInfo(&CLSID_WICDdsEncoder, &comp_info); + if (hr == S_OK) { + hr = IWICComponentInfo_QueryInterface(comp_info, &IID_IWICBitmapEncoderInfo, (void **)info); + IWICComponentInfo_Release(comp_info); + } + return hr; +} + +static HRESULT WINAPI DdsEncoder_SetColorContexts(IWICBitmapEncoder *iface, + UINT cCount, IWICColorContext **ppIColorContext) +{ + FIXME("(%p,%u,%p): stub\n", iface, cCount, ppIColorContext); + return E_NOTIMPL; +} + +static HRESULT WINAPI DdsEncoder_SetPalette(IWICBitmapEncoder *iface, IWICPalette *palette) +{ + DdsEncoder *This = impl_from_IWICBitmapEncoder(iface); + HRESULT hr; + + TRACE("(%p,%p)\n", iface, palette); + + EnterCriticalSection(&This->lock); + + hr = This->stream ? WINCODEC_ERR_UNSUPPORTEDOPERATION : WINCODEC_ERR_NOTINITIALIZED; + + LeaveCriticalSection(&This->lock); + + return hr; +} + +static HRESULT WINAPI DdsEncoder_SetThumbnail(IWICBitmapEncoder *iface, IWICBitmapSource *pIThumbnail) +{ + TRACE("(%p,%p)\n", iface, pIThumbnail); + return WINCODEC_ERR_UNSUPPORTEDOPERATION; +} + +static HRESULT WINAPI DdsEncoder_SetPreview(IWICBitmapEncoder *iface, IWICBitmapSource *pIPreview) +{ + TRACE("(%p,%p)\n", iface, pIPreview); + return WINCODEC_ERR_UNSUPPORTEDOPERATION; +} + +static HRESULT WINAPI DdsEncoder_CreateNewFrame(IWICBitmapEncoder *iface, + IWICBitmapFrameEncode **frameEncode, IPropertyBag2 **encoderOptions) +{ + DdsEncoder *This = impl_from_IWICBitmapEncoder(iface); + + TRACE("(%p,%p,%p)\n", iface, frameEncode, encoderOptions); + + return IWICDdsEncoder_CreateNewFrame(&This->IWICDdsEncoder_iface, frameEncode, NULL, NULL, NULL); +} + +static HRESULT WINAPI DdsEncoder_Commit(IWICBitmapEncoder *iface) +{ + FIXME("(%p): stub\n", iface); + return E_NOTIMPL; +} + +static HRESULT WINAPI DdsEncoder_GetMetadataQueryWriter(IWICBitmapEncoder *iface, + IWICMetadataQueryWriter **ppIMetadataQueryWriter) +{ + FIXME("(%p,%p): stub\n", iface, ppIMetadataQueryWriter); + return E_NOTIMPL; +} + +static const IWICBitmapEncoderVtbl DdsEncoder_Vtbl = { + DdsEncoder_QueryInterface, + DdsEncoder_AddRef, + DdsEncoder_Release, + DdsEncoder_Initialize, + DdsEncoder_GetContainerFormat, + DdsEncoder_GetEncoderInfo, + DdsEncoder_SetColorContexts, + DdsEncoder_SetPalette, + DdsEncoder_SetThumbnail, + DdsEncoder_SetPreview, + DdsEncoder_CreateNewFrame, + DdsEncoder_Commit, + DdsEncoder_GetMetadataQueryWriter +}; + +HRESULT DdsEncoder_CreateInstance( REFIID iid, void **ppv) +{ + DdsEncoder *This; + HRESULT ret; + + TRACE("(%s,%p)\n", debugstr_guid(iid), ppv); + + *ppv = NULL; + + This = malloc(sizeof(DdsEncoder)); + if (!This) return E_OUTOFMEMORY; + + This->IWICBitmapEncoder_iface.lpVtbl = &DdsEncoder_Vtbl; + This->IWICDdsEncoder_iface.lpVtbl = &DdsEncoder_Dds_Vtbl; + This->ref = 1; + This->stream = NULL; + This->frame_count = 0; + This->frame_index = 0; + This->uncommitted_frame = FALSE; + This->committed = FALSE; +#ifdef __REACTOS__ + InitializeCriticalSection(&This->lock); +#else + InitializeCriticalSectionEx(&This->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif + This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": DdsEncoder.lock"); + + ret = IWICBitmapEncoder_QueryInterface(&This->IWICBitmapEncoder_iface, iid, ppv); + IWICBitmapEncoder_Release(&This->IWICBitmapEncoder_iface); + + return ret; +} diff --git a/dll/win32/windowscodecs/decoder.c b/dll/win32/windowscodecs/decoder.c new file mode 100644 index 0000000000000..08fe23e1bf093 --- /dev/null +++ b/dll/win32/windowscodecs/decoder.c @@ -0,0 +1,811 @@ +/* + * Copyright 2020 Esme Povirk + * + * 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 COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" + +#include "wincodecs_private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); + +typedef struct { + IWICBitmapDecoder IWICBitmapDecoder_iface; + LONG ref; + CRITICAL_SECTION lock; /* must be held when stream or decoder is accessed */ + IStream *stream; + struct decoder *decoder; + struct decoder_info decoder_info; + struct decoder_stat file_info; + WICDecodeOptions cache_options; +} CommonDecoder; + +static inline CommonDecoder *impl_from_IWICBitmapDecoder(IWICBitmapDecoder *iface) +{ + return CONTAINING_RECORD(iface, CommonDecoder, IWICBitmapDecoder_iface); +} + +static HRESULT WINAPI CommonDecoder_QueryInterface(IWICBitmapDecoder *iface, REFIID iid, + void **ppv) +{ + CommonDecoder *This = impl_from_IWICBitmapDecoder(iface); + TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); + + if (!ppv) return E_INVALIDARG; + + if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IWICBitmapDecoder, iid)) + { + *ppv = &This->IWICBitmapDecoder_iface; + } + else + { + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI CommonDecoder_AddRef(IWICBitmapDecoder *iface) +{ + CommonDecoder *This = impl_from_IWICBitmapDecoder(iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) refcount=%lu\n", iface, ref); + + return ref; +} + +static ULONG WINAPI CommonDecoder_Release(IWICBitmapDecoder *iface) +{ + CommonDecoder *This = impl_from_IWICBitmapDecoder(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) refcount=%lu\n", iface, ref); + + if (ref == 0) + { + if (This->stream) + IStream_Release(This->stream); + This->lock.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&This->lock); + decoder_destroy(This->decoder); + free(This); + } + + return ref; +} + +static HRESULT WINAPI CommonDecoder_QueryCapability(IWICBitmapDecoder *iface, IStream *stream, + DWORD *capability) +{ + CommonDecoder *This = impl_from_IWICBitmapDecoder(iface); + HRESULT hr; + + TRACE("(%p,%p,%p)\n", iface, stream, capability); + + if (!stream || !capability) return E_INVALIDARG; + + hr = IWICBitmapDecoder_Initialize(iface, stream, WICDecodeMetadataCacheOnDemand); + if (hr != S_OK) return hr; + + *capability = (This->file_info.flags & DECODER_FLAGS_CAPABILITY_MASK); + return S_OK; +} + +static HRESULT WINAPI CommonDecoder_Initialize(IWICBitmapDecoder *iface, IStream *pIStream, + WICDecodeOptions cacheOptions) +{ + CommonDecoder *This = impl_from_IWICBitmapDecoder(iface); + HRESULT hr=S_OK; + + TRACE("(%p,%p,%x)\n", iface, pIStream, cacheOptions); + + EnterCriticalSection(&This->lock); + + if (This->stream) + hr = WINCODEC_ERR_WRONGSTATE; + + if (SUCCEEDED(hr)) + hr = decoder_initialize(This->decoder, pIStream, &This->file_info); + + if (SUCCEEDED(hr)) + { + This->cache_options = cacheOptions; + This->stream = pIStream; + IStream_AddRef(This->stream); + } + + LeaveCriticalSection(&This->lock); + + return hr; +} + +static HRESULT WINAPI CommonDecoder_GetContainerFormat(IWICBitmapDecoder *iface, + GUID *pguidContainerFormat) +{ + CommonDecoder *This = impl_from_IWICBitmapDecoder(iface); + memcpy(pguidContainerFormat, &This->decoder_info.container_format, sizeof(GUID)); + return S_OK; +} + +static HRESULT WINAPI CommonDecoder_GetDecoderInfo(IWICBitmapDecoder *iface, + IWICBitmapDecoderInfo **ppIDecoderInfo) +{ + CommonDecoder *This = impl_from_IWICBitmapDecoder(iface); + TRACE("(%p,%p)\n", iface, ppIDecoderInfo); + + return get_decoder_info(&This->decoder_info.clsid, ppIDecoderInfo); +} + +static HRESULT WINAPI CommonDecoder_CopyPalette(IWICBitmapDecoder *iface, + IWICPalette *palette) +{ + TRACE("(%p,%p)\n", iface, palette); + return WINCODEC_ERR_PALETTEUNAVAILABLE; +} + +static HRESULT WINAPI CommonDecoder_GetMetadataQueryReader(IWICBitmapDecoder *iface, + IWICMetadataQueryReader **reader) +{ + TRACE("(%p,%p)\n", iface, reader); + + if (!reader) return E_INVALIDARG; + + *reader = NULL; + return WINCODEC_ERR_UNSUPPORTEDOPERATION; +} + +static HRESULT WINAPI CommonDecoder_GetPreview(IWICBitmapDecoder *iface, + IWICBitmapSource **ppIBitmapSource) +{ + TRACE("(%p,%p)\n", iface, ppIBitmapSource); + + if (!ppIBitmapSource) return E_INVALIDARG; + + *ppIBitmapSource = NULL; + return WINCODEC_ERR_UNSUPPORTEDOPERATION; +} + +static HRESULT WINAPI CommonDecoder_GetColorContexts(IWICBitmapDecoder *iface, + UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount) +{ + TRACE("(%p,%u,%p,%p)\n", iface, cCount, ppIColorContexts, pcActualCount); + return WINCODEC_ERR_UNSUPPORTEDOPERATION; +} + +static HRESULT WINAPI CommonDecoder_GetThumbnail(IWICBitmapDecoder *iface, + IWICBitmapSource **ppIThumbnail) +{ + TRACE("(%p,%p)\n", iface, ppIThumbnail); + + if (!ppIThumbnail) return E_INVALIDARG; + + *ppIThumbnail = NULL; + return WINCODEC_ERR_CODECNOTHUMBNAIL; +} + +static HRESULT WINAPI CommonDecoder_GetFrameCount(IWICBitmapDecoder *iface, + UINT *pCount) +{ + CommonDecoder *This = impl_from_IWICBitmapDecoder(iface); + if (!pCount) return E_INVALIDARG; + + if (This->stream) + *pCount = This->file_info.frame_count; + else + *pCount = 0; + + return S_OK; +} + +static HRESULT WINAPI CommonDecoder_GetFrame(IWICBitmapDecoder *iface, + UINT index, IWICBitmapFrameDecode **ppIBitmapFrame); + +static const IWICBitmapDecoderVtbl CommonDecoder_Vtbl = { + CommonDecoder_QueryInterface, + CommonDecoder_AddRef, + CommonDecoder_Release, + CommonDecoder_QueryCapability, + CommonDecoder_Initialize, + CommonDecoder_GetContainerFormat, + CommonDecoder_GetDecoderInfo, + CommonDecoder_CopyPalette, + CommonDecoder_GetMetadataQueryReader, + CommonDecoder_GetPreview, + CommonDecoder_GetColorContexts, + CommonDecoder_GetThumbnail, + CommonDecoder_GetFrameCount, + CommonDecoder_GetFrame +}; + +typedef struct { + IWICBitmapFrameDecode IWICBitmapFrameDecode_iface; + IWICMetadataBlockReader IWICMetadataBlockReader_iface; + LONG ref; + CommonDecoder *parent; + DWORD frame; + struct decoder_frame decoder_frame; + BOOL metadata_initialized; + UINT metadata_count; + struct decoder_block* metadata_blocks; +} CommonDecoderFrame; + +static inline CommonDecoderFrame *impl_from_IWICBitmapFrameDecode(IWICBitmapFrameDecode *iface) +{ + return CONTAINING_RECORD(iface, CommonDecoderFrame, IWICBitmapFrameDecode_iface); +} + +static inline CommonDecoderFrame *impl_from_IWICMetadataBlockReader(IWICMetadataBlockReader *iface) +{ + return CONTAINING_RECORD(iface, CommonDecoderFrame, IWICMetadataBlockReader_iface); +} + +static HRESULT WINAPI CommonDecoderFrame_QueryInterface(IWICBitmapFrameDecode *iface, REFIID iid, + void **ppv) +{ + CommonDecoderFrame *This = impl_from_IWICBitmapFrameDecode(iface); + if (!ppv) return E_INVALIDARG; + + if (IsEqualIID(&IID_IUnknown, iid) || + IsEqualIID(&IID_IWICBitmapSource, iid) || + IsEqualIID(&IID_IWICBitmapFrameDecode, iid)) + { + *ppv = &This->IWICBitmapFrameDecode_iface; + } + else if (IsEqualIID(&IID_IWICMetadataBlockReader, iid) && + (This->parent->file_info.flags & WICBitmapDecoderCapabilityCanEnumerateMetadata)) + { + *ppv = &This->IWICMetadataBlockReader_iface; + } + else + { + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI CommonDecoderFrame_AddRef(IWICBitmapFrameDecode *iface) +{ + CommonDecoderFrame *This = impl_from_IWICBitmapFrameDecode(iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) refcount=%lu\n", iface, ref); + + return ref; +} + +static ULONG WINAPI CommonDecoderFrame_Release(IWICBitmapFrameDecode *iface) +{ + CommonDecoderFrame *This = impl_from_IWICBitmapFrameDecode(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) refcount=%lu\n", iface, ref); + + if (ref == 0) + { + IWICBitmapDecoder_Release(&This->parent->IWICBitmapDecoder_iface); + free(This->metadata_blocks); + free(This); + } + + return ref; +} + +static HRESULT WINAPI CommonDecoderFrame_GetSize(IWICBitmapFrameDecode *iface, + UINT *puiWidth, UINT *puiHeight) +{ + CommonDecoderFrame *This = impl_from_IWICBitmapFrameDecode(iface); + + TRACE("(%p,%p,%p)\n", This, puiWidth, puiHeight); + + if (!puiWidth || !puiHeight) + return E_POINTER; + + *puiWidth = This->decoder_frame.width; + *puiHeight = This->decoder_frame.height; + return S_OK; +} + +static HRESULT WINAPI CommonDecoderFrame_GetPixelFormat(IWICBitmapFrameDecode *iface, + WICPixelFormatGUID *pPixelFormat) +{ + CommonDecoderFrame *This = impl_from_IWICBitmapFrameDecode(iface); + + TRACE("(%p,%p)\n", This, pPixelFormat); + + if (!pPixelFormat) + return E_POINTER; + + *pPixelFormat = This->decoder_frame.pixel_format; + return S_OK; +} + +static HRESULT WINAPI CommonDecoderFrame_GetResolution(IWICBitmapFrameDecode *iface, + double *pDpiX, double *pDpiY) +{ + CommonDecoderFrame *This = impl_from_IWICBitmapFrameDecode(iface); + + TRACE("(%p,%p,%p)\n", This, pDpiX, pDpiY); + + if (!pDpiX || !pDpiY) + return E_POINTER; + + *pDpiX = This->decoder_frame.dpix; + *pDpiY = This->decoder_frame.dpiy; + return S_OK; +} + +static HRESULT WINAPI CommonDecoderFrame_CopyPalette(IWICBitmapFrameDecode *iface, + IWICPalette *pIPalette) +{ + CommonDecoderFrame *This = impl_from_IWICBitmapFrameDecode(iface); + HRESULT hr=S_OK; + + TRACE("(%p,%p)\n", iface, pIPalette); + + if (This->decoder_frame.num_colors) + { + hr = IWICPalette_InitializeCustom(pIPalette, This->decoder_frame.palette, This->decoder_frame.num_colors); + } + else + { + hr = WINCODEC_ERR_PALETTEUNAVAILABLE; + } + + return hr; +} + +static HRESULT WINAPI CommonDecoderFrame_CopyPixels(IWICBitmapFrameDecode *iface, + const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer) +{ + CommonDecoderFrame *This = impl_from_IWICBitmapFrameDecode(iface); + HRESULT hr; + UINT bytesperrow; + WICRect rect; + + TRACE("(%p,%s,%u,%u,%p)\n", iface, debug_wic_rect(prc), cbStride, cbBufferSize, pbBuffer); + + if (!pbBuffer) + return E_POINTER; + + if (!prc) + { + rect.X = 0; + rect.Y = 0; + rect.Width = This->decoder_frame.width; + rect.Height = This->decoder_frame.height; + prc = ▭ + } + else + { + if (prc->X < 0 || prc->Y < 0 || + prc->X+prc->Width > This->decoder_frame.width || + prc->Y+prc->Height > This->decoder_frame.height) + return E_INVALIDARG; + } + + bytesperrow = ((This->decoder_frame.bpp * prc->Width)+7)/8; + + if (cbStride < bytesperrow) + return E_INVALIDARG; + + if ((cbStride * (prc->Height-1)) + bytesperrow > cbBufferSize) + return E_INVALIDARG; + + EnterCriticalSection(&This->parent->lock); + + hr = decoder_copy_pixels(This->parent->decoder, This->frame, + prc, cbStride, cbBufferSize, pbBuffer); + + LeaveCriticalSection(&This->parent->lock); + + return hr; +} + +static HRESULT WINAPI CommonDecoderFrame_GetMetadataQueryReader(IWICBitmapFrameDecode *iface, + IWICMetadataQueryReader **ppIMetadataQueryReader) +{ + CommonDecoderFrame *This = impl_from_IWICBitmapFrameDecode(iface); + IWICComponentFactory* factory; + HRESULT hr; + + TRACE("(%p,%p)\n", iface, ppIMetadataQueryReader); + + if (!ppIMetadataQueryReader) + return E_INVALIDARG; + + if (!(This->parent->file_info.flags & WICBitmapDecoderCapabilityCanEnumerateMetadata)) + return WINCODEC_ERR_UNSUPPORTEDOPERATION; + + hr = create_instance(&CLSID_WICImagingFactory, &IID_IWICComponentFactory, (void**)&factory); + + if (SUCCEEDED(hr)) + { + hr = IWICComponentFactory_CreateQueryReaderFromBlockReader(factory, &This->IWICMetadataBlockReader_iface, ppIMetadataQueryReader); + IWICComponentFactory_Release(factory); + } + + if (FAILED(hr)) + *ppIMetadataQueryReader = NULL; + + return hr; +} + +static HRESULT WINAPI CommonDecoderFrame_GetColorContexts(IWICBitmapFrameDecode *iface, + UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount) +{ + CommonDecoderFrame *This = impl_from_IWICBitmapFrameDecode(iface); + HRESULT hr=S_OK; + UINT i; + BYTE *profile; + DWORD profile_len; + + TRACE("(%p,%u,%p,%p)\n", iface, cCount, ppIColorContexts, pcActualCount); + + if (!pcActualCount) return E_INVALIDARG; + + if (This->parent->file_info.flags & DECODER_FLAGS_UNSUPPORTED_COLOR_CONTEXT) + { + FIXME("not supported for %s\n", wine_dbgstr_guid(&This->parent->decoder_info.clsid)); + *pcActualCount = 0; + return WINCODEC_ERR_UNSUPPORTEDOPERATION; + } + + *pcActualCount = This->decoder_frame.num_color_contexts; + + if (This->decoder_frame.num_color_contexts && cCount && ppIColorContexts) + { + if (cCount >= This->decoder_frame.num_color_contexts) + { + EnterCriticalSection(&This->parent->lock); + + for (i=0; idecoder_frame.num_color_contexts; i++) + { + hr = decoder_get_color_context(This->parent->decoder, This->frame, i, + &profile, &profile_len); + if (SUCCEEDED(hr)) + { + hr = IWICColorContext_InitializeFromMemory(ppIColorContexts[i], profile, profile_len); + + free(profile); + } + + if (FAILED(hr)) + break; + } + + LeaveCriticalSection(&This->parent->lock); + } + else + { + hr = E_INVALIDARG; + } + } + + return hr; +} + +static HRESULT WINAPI CommonDecoderFrame_GetThumbnail(IWICBitmapFrameDecode *iface, + IWICBitmapSource **ppIThumbnail) +{ + TRACE("(%p,%p)\n", iface, ppIThumbnail); + + if (!ppIThumbnail) return E_INVALIDARG; + + *ppIThumbnail = NULL; + return WINCODEC_ERR_CODECNOTHUMBNAIL; +} + +static const IWICBitmapFrameDecodeVtbl CommonDecoderFrameVtbl = { + CommonDecoderFrame_QueryInterface, + CommonDecoderFrame_AddRef, + CommonDecoderFrame_Release, + CommonDecoderFrame_GetSize, + CommonDecoderFrame_GetPixelFormat, + CommonDecoderFrame_GetResolution, + CommonDecoderFrame_CopyPalette, + CommonDecoderFrame_CopyPixels, + CommonDecoderFrame_GetMetadataQueryReader, + CommonDecoderFrame_GetColorContexts, + CommonDecoderFrame_GetThumbnail +}; + +static HRESULT WINAPI CommonDecoderFrame_Block_QueryInterface(IWICMetadataBlockReader *iface, REFIID iid, + void **ppv) +{ + CommonDecoderFrame *This = impl_from_IWICMetadataBlockReader(iface); + return IWICBitmapFrameDecode_QueryInterface(&This->IWICBitmapFrameDecode_iface, iid, ppv); +} + +static ULONG WINAPI CommonDecoderFrame_Block_AddRef(IWICMetadataBlockReader *iface) +{ + CommonDecoderFrame *This = impl_from_IWICMetadataBlockReader(iface); + return IWICBitmapFrameDecode_AddRef(&This->IWICBitmapFrameDecode_iface); +} + +static ULONG WINAPI CommonDecoderFrame_Block_Release(IWICMetadataBlockReader *iface) +{ + CommonDecoderFrame *This = impl_from_IWICMetadataBlockReader(iface); + return IWICBitmapFrameDecode_Release(&This->IWICBitmapFrameDecode_iface); +} + +static HRESULT WINAPI CommonDecoderFrame_Block_GetContainerFormat(IWICMetadataBlockReader *iface, + GUID *pguidContainerFormat) +{ + CommonDecoderFrame *This = impl_from_IWICMetadataBlockReader(iface); + if (!pguidContainerFormat) return E_INVALIDARG; + *pguidContainerFormat = This->parent->decoder_info.block_format; + return S_OK; +} + +static HRESULT CommonDecoderFrame_InitializeMetadata(CommonDecoderFrame *This) +{ + HRESULT hr=S_OK; + + if (This->metadata_initialized) + return S_OK; + + EnterCriticalSection(&This->parent->lock); + + if (!This->metadata_initialized) + { + hr = decoder_get_metadata_blocks(This->parent->decoder, This->frame, &This->metadata_count, &This->metadata_blocks); + if (SUCCEEDED(hr)) + This->metadata_initialized = TRUE; + } + + LeaveCriticalSection(&This->parent->lock); + + return hr; +} + +static HRESULT WINAPI CommonDecoderFrame_Block_GetCount(IWICMetadataBlockReader *iface, + UINT *pcCount) +{ + CommonDecoderFrame *This = impl_from_IWICMetadataBlockReader(iface); + HRESULT hr; + + TRACE("%p,%p\n", iface, pcCount); + + if (!pcCount) return E_INVALIDARG; + + hr = CommonDecoderFrame_InitializeMetadata(This); + if (SUCCEEDED(hr)) + *pcCount = This->metadata_count; + + return hr; +} + +static HRESULT WINAPI CommonDecoderFrame_Block_GetReaderByIndex(IWICMetadataBlockReader *iface, + UINT nIndex, IWICMetadataReader **ppIMetadataReader) +{ + CommonDecoderFrame *This = impl_from_IWICMetadataBlockReader(iface); + HRESULT hr; + IWICComponentFactory* factory = NULL; + IWICStream* stream; + + TRACE("%p,%d,%p\n", iface, nIndex, ppIMetadataReader); + + if (!ppIMetadataReader) + return E_INVALIDARG; + + hr = CommonDecoderFrame_InitializeMetadata(This); + + if (SUCCEEDED(hr) && nIndex >= This->metadata_count) + hr = E_INVALIDARG; + + if (SUCCEEDED(hr)) + hr = create_instance(&CLSID_WICImagingFactory, &IID_IWICComponentFactory, (void**)&factory); + + if (SUCCEEDED(hr)) + hr = IWICComponentFactory_CreateStream(factory, &stream); + + if (SUCCEEDED(hr)) + { + if (This->metadata_blocks[nIndex].options & DECODER_BLOCK_FULL_STREAM) + { + LARGE_INTEGER offset; + offset.QuadPart = This->metadata_blocks[nIndex].offset; + + hr = IWICStream_InitializeFromIStream(stream, This->parent->stream); + + if (SUCCEEDED(hr)) + hr = IWICStream_Seek(stream, offset, STREAM_SEEK_SET, NULL); + } + else + { + ULARGE_INTEGER offset, length; + + offset.QuadPart = This->metadata_blocks[nIndex].offset; + length.QuadPart = This->metadata_blocks[nIndex].length; + + hr = IWICStream_InitializeFromIStreamRegion(stream, This->parent->stream, + offset, length); + } + + if (This->metadata_blocks[nIndex].options & DECODER_BLOCK_READER_CLSID) + { + IWICMetadataReader *reader; + IWICPersistStream *persist; + if (SUCCEEDED(hr)) + { + hr = create_instance(&This->metadata_blocks[nIndex].reader_clsid, + &IID_IWICMetadataReader, (void**)&reader); + } + + if (SUCCEEDED(hr)) + { + hr = IWICMetadataReader_QueryInterface(reader, &IID_IWICPersistStream, (void**)&persist); + + if (SUCCEEDED(hr)) + { + hr = IWICPersistStream_LoadEx(persist, (IStream*)stream, NULL, + This->metadata_blocks[nIndex].options & DECODER_BLOCK_OPTION_MASK); + + IWICPersistStream_Release(persist); + } + + if (SUCCEEDED(hr)) + *ppIMetadataReader = reader; + else + IWICMetadataReader_Release(reader); + } + } + else + { + hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory, + &This->parent->decoder_info.block_format, NULL, + This->metadata_blocks[nIndex].options & DECODER_BLOCK_OPTION_MASK, + (IStream*)stream, ppIMetadataReader); + } + + IWICStream_Release(stream); + } + + if (factory) IWICComponentFactory_Release(factory); + + if (FAILED(hr)) + *ppIMetadataReader = NULL; + + return S_OK; +} + +static HRESULT WINAPI CommonDecoderFrame_Block_GetEnumerator(IWICMetadataBlockReader *iface, + IEnumUnknown **ppIEnumMetadata) +{ + FIXME("%p,%p\n", iface, ppIEnumMetadata); + return E_NOTIMPL; +} + +static const IWICMetadataBlockReaderVtbl CommonDecoderFrame_BlockVtbl = { + CommonDecoderFrame_Block_QueryInterface, + CommonDecoderFrame_Block_AddRef, + CommonDecoderFrame_Block_Release, + CommonDecoderFrame_Block_GetContainerFormat, + CommonDecoderFrame_Block_GetCount, + CommonDecoderFrame_Block_GetReaderByIndex, + CommonDecoderFrame_Block_GetEnumerator, +}; + +static HRESULT WINAPI CommonDecoder_GetFrame(IWICBitmapDecoder *iface, + UINT index, IWICBitmapFrameDecode **ppIBitmapFrame) +{ + CommonDecoder *This = impl_from_IWICBitmapDecoder(iface); + HRESULT hr=S_OK; + CommonDecoderFrame *result; + + TRACE("(%p,%u,%p)\n", iface, index, ppIBitmapFrame); + + if (!ppIBitmapFrame) + return E_INVALIDARG; + + EnterCriticalSection(&This->lock); + + if (!This->stream || index >= This->file_info.frame_count) + hr = WINCODEC_ERR_FRAMEMISSING; + + if (SUCCEEDED(hr)) + { + result = malloc(sizeof(*result)); + if (!result) + hr = E_OUTOFMEMORY; + } + + if (SUCCEEDED(hr)) + { + result->IWICBitmapFrameDecode_iface.lpVtbl = &CommonDecoderFrameVtbl; + result->IWICMetadataBlockReader_iface.lpVtbl = &CommonDecoderFrame_BlockVtbl; + result->ref = 1; + result->parent = This; + result->frame = index; + result->metadata_initialized = FALSE; + result->metadata_count = 0; + result->metadata_blocks = NULL; + + hr = decoder_get_frame_info(This->decoder, index, &result->decoder_frame); + + if (SUCCEEDED(hr) && This->cache_options == WICDecodeMetadataCacheOnLoad) + hr = CommonDecoderFrame_InitializeMetadata(result); + + if (FAILED(hr)) + free(result); + } + + LeaveCriticalSection(&This->lock); + + if (SUCCEEDED(hr)) + { + TRACE("-> %ux%u, %u-bit pixelformat=%s res=%f,%f colors=%lu contexts=%lu\n", + result->decoder_frame.width, result->decoder_frame.height, + result->decoder_frame.bpp, wine_dbgstr_guid(&result->decoder_frame.pixel_format), + result->decoder_frame.dpix, result->decoder_frame.dpiy, + result->decoder_frame.num_colors, result->decoder_frame.num_color_contexts); + IWICBitmapDecoder_AddRef(&This->IWICBitmapDecoder_iface); + *ppIBitmapFrame = &result->IWICBitmapFrameDecode_iface; + } + else + { + *ppIBitmapFrame = NULL; + } + + return hr; +} + +HRESULT CommonDecoder_CreateInstance(struct decoder *decoder, + const struct decoder_info *decoder_info, REFIID iid, void** ppv) +{ + CommonDecoder *This; + HRESULT hr; + + TRACE("(%s,%s,%p)\n", debugstr_guid(&decoder_info->clsid), debugstr_guid(iid), ppv); + + This = malloc(sizeof(*This)); + if (!This) + { + decoder_destroy(decoder); + return E_OUTOFMEMORY; + } + + This->IWICBitmapDecoder_iface.lpVtbl = &CommonDecoder_Vtbl; + This->ref = 1; + This->stream = NULL; + This->decoder = decoder; + This->decoder_info = *decoder_info; +#ifdef __REACTOS__ + InitializeCriticalSection(&This->lock); +#else + InitializeCriticalSectionEx(&This->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif + This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": CommonDecoder.lock"); + + hr = IWICBitmapDecoder_QueryInterface(&This->IWICBitmapDecoder_iface, iid, ppv); + IWICBitmapDecoder_Release(&This->IWICBitmapDecoder_iface); + + return hr; +} diff --git a/dll/win32/windowscodecs/encoder.c b/dll/win32/windowscodecs/encoder.c new file mode 100644 index 0000000000000..b2be1f12e1cc9 --- /dev/null +++ b/dll/win32/windowscodecs/encoder.c @@ -0,0 +1,903 @@ +/* + * Copyright 2020 Esme Povirk + * + * 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 COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" + +#include "wincodecs_private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); + +static const PROPBAG2 encoder_option_properties[ENCODER_OPTION_END] = { + { PROPBAG2_TYPE_DATA, VT_BOOL, 0, 0, (LPOLESTR)L"InterlaceOption" }, + { PROPBAG2_TYPE_DATA, VT_UI1, 0, 0, (LPOLESTR)L"FilterOption" }, + { PROPBAG2_TYPE_DATA, VT_UI1, 0, 0, (LPOLESTR)L"TiffCompressionMethod" }, + { PROPBAG2_TYPE_DATA, VT_R4, 0, 0, (LPOLESTR)L"CompressionQuality" }, + { PROPBAG2_TYPE_DATA, VT_R4, 0, 0, (LPOLESTR)L"ImageQuality" }, + { PROPBAG2_TYPE_DATA, VT_UI1, 0, 0, (LPOLESTR)L"BitmapTransform" }, + { PROPBAG2_TYPE_DATA, VT_I4 | VT_ARRAY, 0, 0, (LPOLESTR)L"Luminance" }, + { PROPBAG2_TYPE_DATA, VT_I4 | VT_ARRAY, 0, 0, (LPOLESTR)L"Chrominance" }, + { PROPBAG2_TYPE_DATA, VT_UI1, 0, 0, (LPOLESTR)L"JpegYCrCbSubsampling" }, + { PROPBAG2_TYPE_DATA, VT_BOOL, 0, 0, (LPOLESTR)L"SuppressApp0" } +}; + +typedef struct CommonEncoder { + IWICBitmapEncoder IWICBitmapEncoder_iface; + LONG ref; + CRITICAL_SECTION lock; /* must be held when stream or encoder is accessed */ + IStream *stream; + struct encoder *encoder; + struct encoder_info encoder_info; + UINT frame_count; + BOOL uncommitted_frame; + BOOL committed; +} CommonEncoder; + +typedef struct CommonEncoderFrame { + IWICBitmapFrameEncode IWICBitmapFrameEncode_iface; + IWICMetadataBlockWriter IWICMetadataBlockWriter_iface; + LONG ref; + CommonEncoder *parent; + struct encoder_frame encoder_frame; + BOOL initialized; + BOOL frame_created; + UINT lines_written; + BOOL committed; +} CommonEncoderFrame; + +static inline CommonEncoder *impl_from_IWICBitmapEncoder(IWICBitmapEncoder *iface) +{ + return CONTAINING_RECORD(iface, CommonEncoder, IWICBitmapEncoder_iface); +} + +static inline CommonEncoderFrame *impl_from_IWICBitmapFrameEncode(IWICBitmapFrameEncode *iface) +{ + return CONTAINING_RECORD(iface, CommonEncoderFrame, IWICBitmapFrameEncode_iface); +} + +static inline CommonEncoderFrame *impl_from_IWICMetadataBlockWriter(IWICMetadataBlockWriter *iface) +{ + return CONTAINING_RECORD(iface, CommonEncoderFrame, IWICMetadataBlockWriter_iface); +} + +static HRESULT WINAPI CommonEncoderFrame_QueryInterface(IWICBitmapFrameEncode *iface, REFIID iid, + void **ppv) +{ + CommonEncoderFrame *object = impl_from_IWICBitmapFrameEncode(iface); + TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); + + if (!ppv) return E_INVALIDARG; + + if (IsEqualIID(&IID_IUnknown, iid) || + IsEqualIID(&IID_IWICBitmapFrameEncode, iid)) + { + *ppv = &object->IWICBitmapFrameEncode_iface; + } + else if (object->parent->encoder_info.flags & ENCODER_FLAGS_SUPPORTS_METADATA + && IsEqualIID(&IID_IWICMetadataBlockWriter, iid)) + { + *ppv = &object->IWICMetadataBlockWriter_iface; + } + else + { + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI CommonEncoderFrame_AddRef(IWICBitmapFrameEncode *iface) +{ + CommonEncoderFrame *This = impl_from_IWICBitmapFrameEncode(iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) refcount=%lu\n", iface, ref); + + return ref; +} + +static ULONG WINAPI CommonEncoderFrame_Release(IWICBitmapFrameEncode *iface) +{ + CommonEncoderFrame *This = impl_from_IWICBitmapFrameEncode(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) refcount=%lu\n", iface, ref); + + if (ref == 0) + { + IWICBitmapEncoder_Release(&This->parent->IWICBitmapEncoder_iface); + free(This); + } + + return ref; +} + +static HRESULT WINAPI CommonEncoderFrame_Initialize(IWICBitmapFrameEncode *iface, + IPropertyBag2 *pIEncoderOptions) +{ + CommonEncoderFrame *This = impl_from_IWICBitmapFrameEncode(iface); + HRESULT hr=S_OK; + struct encoder_frame options = {{0}}; + PROPBAG2 opts[7]= {{0}}; + VARIANT opt_values[7]; + HRESULT opt_hres[7]; + DWORD num_opts, i; + + TRACE("(%p,%p)\n", iface, pIEncoderOptions); + + if (pIEncoderOptions) + { + for (i=0; This->parent->encoder_info.encoder_options[i] != ENCODER_OPTION_END; i++) + opts[i] = encoder_option_properties[This->parent->encoder_info.encoder_options[i]]; + num_opts = i; + + hr = IPropertyBag2_Read(pIEncoderOptions, num_opts, opts, NULL, opt_values, opt_hres); + + if (FAILED(hr)) + return hr; + + for (i=0; This->parent->encoder_info.encoder_options[i] != ENCODER_OPTION_END; i++) + { + VARIANT *val = &opt_values[i]; + + switch (This->parent->encoder_info.encoder_options[i]) + { + case ENCODER_OPTION_INTERLACE: + if (V_VT(val) == VT_EMPTY) + options.interlace = FALSE; + else + options.interlace = (V_BOOL(val) != 0); + break; + case ENCODER_OPTION_FILTER: + options.filter = V_UI1(val); + if (options.filter > WICPngFilterAdaptive) + { + WARN("Unrecognized filter option value %lu.\n", options.filter); + options.filter = WICPngFilterUnspecified; + } + break; + default: + break; + } + } + } + else + { + options.interlace = FALSE; + options.filter = WICPngFilterUnspecified; + } + + EnterCriticalSection(&This->parent->lock); + + if (This->initialized) + hr = WINCODEC_ERR_WRONGSTATE; + else + { + This->encoder_frame = options; + This->initialized = TRUE; + } + + LeaveCriticalSection(&This->parent->lock); + + return hr; +} + +static HRESULT WINAPI CommonEncoderFrame_SetSize(IWICBitmapFrameEncode *iface, + UINT uiWidth, UINT uiHeight) +{ + CommonEncoderFrame *This = impl_from_IWICBitmapFrameEncode(iface); + HRESULT hr; + + TRACE("(%p,%u,%u)\n", iface, uiWidth, uiHeight); + + EnterCriticalSection(&This->parent->lock); + + if (This->parent->encoder_info.flags & ENCODER_FLAGS_ICNS_SIZE) + { + if (uiWidth != uiHeight) + { + WARN("cannot generate ICNS icon from %dx%d image\n", uiWidth, uiHeight); + hr = E_INVALIDARG; + goto end; + } + + switch (uiWidth) + { + case 16: + case 32: + case 48: + case 128: + case 256: + case 512: + break; + default: + WARN("cannot generate ICNS icon from %dx%d image\n", uiWidth, uiHeight); + hr = E_INVALIDARG; + goto end; + } + } + + if (!This->initialized || This->frame_created) + { + hr = WINCODEC_ERR_WRONGSTATE; + } + else + { + This->encoder_frame.width = uiWidth; + This->encoder_frame.height = uiHeight; + hr = S_OK; + } + +end: + LeaveCriticalSection(&This->parent->lock); + + return hr; +} + +static HRESULT WINAPI CommonEncoderFrame_SetResolution(IWICBitmapFrameEncode *iface, + double dpiX, double dpiY) +{ + CommonEncoderFrame *This = impl_from_IWICBitmapFrameEncode(iface); + HRESULT hr; + + TRACE("(%p,%0.2f,%0.2f)\n", iface, dpiX, dpiY); + + EnterCriticalSection(&This->parent->lock); + + if (!This->initialized || This->frame_created) + { + hr = WINCODEC_ERR_WRONGSTATE; + } + else + { + This->encoder_frame.dpix = dpiX; + This->encoder_frame.dpiy = dpiY; + hr = S_OK; + } + + LeaveCriticalSection(&This->parent->lock); + + return hr; +} + +static HRESULT WINAPI CommonEncoderFrame_SetPixelFormat(IWICBitmapFrameEncode *iface, + WICPixelFormatGUID *pPixelFormat) +{ + CommonEncoderFrame *This = impl_from_IWICBitmapFrameEncode(iface); + HRESULT hr; + GUID pixel_format; + DWORD bpp; + BOOL indexed; + + TRACE("(%p,%s)\n", iface, debugstr_guid(pPixelFormat)); + + EnterCriticalSection(&This->parent->lock); + + if (!This->initialized || This->frame_created) + { + hr = WINCODEC_ERR_WRONGSTATE; + } + else + { + pixel_format = *pPixelFormat; + hr = encoder_get_supported_format(This->parent->encoder, &pixel_format, &bpp, &indexed); + } + + if (SUCCEEDED(hr)) + { + TRACE("<-- %s bpp=%li indexed=%i\n", wine_dbgstr_guid(&pixel_format), bpp, indexed); + *pPixelFormat = pixel_format; + This->encoder_frame.pixel_format = pixel_format; + This->encoder_frame.bpp = bpp; + This->encoder_frame.indexed = indexed; + } + + LeaveCriticalSection(&This->parent->lock); + + return hr; +} + +static HRESULT WINAPI CommonEncoderFrame_SetColorContexts(IWICBitmapFrameEncode *iface, + UINT cCount, IWICColorContext **ppIColorContext) +{ + FIXME("(%p,%u,%p): stub\n", iface, cCount, ppIColorContext); + return E_NOTIMPL; +} + +static HRESULT WINAPI CommonEncoderFrame_SetPalette(IWICBitmapFrameEncode *iface, + IWICPalette *palette) +{ + CommonEncoderFrame *This = impl_from_IWICBitmapFrameEncode(iface); + HRESULT hr; + + TRACE("(%p,%p)\n", iface, palette); + + if (!palette) + return E_INVALIDARG; + + EnterCriticalSection(&This->parent->lock); + + if (!This->initialized) + hr = WINCODEC_ERR_NOTINITIALIZED; + else if (This->frame_created) + hr = WINCODEC_ERR_WRONGSTATE; + else + hr = IWICPalette_GetColors(palette, 256, This->encoder_frame.palette, + &This->encoder_frame.num_colors); + + LeaveCriticalSection(&This->parent->lock); + + return hr; +} + +static HRESULT WINAPI CommonEncoderFrame_SetThumbnail(IWICBitmapFrameEncode *iface, + IWICBitmapSource *pIThumbnail) +{ + FIXME("(%p,%p): stub\n", iface, pIThumbnail); + return WINCODEC_ERR_UNSUPPORTEDOPERATION; +} + +static HRESULT WINAPI CommonEncoderFrame_WritePixels(IWICBitmapFrameEncode *iface, + UINT lineCount, UINT cbStride, UINT cbBufferSize, BYTE *pbPixels) +{ + CommonEncoderFrame *This = impl_from_IWICBitmapFrameEncode(iface); + HRESULT hr=S_OK; + DWORD required_stride; + + TRACE("(%p,%u,%u,%u,%p)\n", iface, lineCount, cbStride, cbBufferSize, pbPixels); + + EnterCriticalSection(&This->parent->lock); + + if (!This->initialized || !This->encoder_frame.height || !This->encoder_frame.width || + !This->encoder_frame.bpp) + { + LeaveCriticalSection(&This->parent->lock); + return WINCODEC_ERR_WRONGSTATE; + } + + required_stride = (This->encoder_frame.width * This->encoder_frame.bpp + 7)/8; + + if (lineCount == 0 || This->encoder_frame.height - This->lines_written < lineCount || + cbStride < required_stride || cbBufferSize < cbStride * (lineCount - 1) + required_stride || + !pbPixels) + { + LeaveCriticalSection(&This->parent->lock); + return E_INVALIDARG; + } + + if (!This->frame_created) + { + hr = encoder_create_frame(This->parent->encoder, &This->encoder_frame); + if (SUCCEEDED(hr)) + This->frame_created = TRUE; + } + + if (SUCCEEDED(hr)) + { + hr = encoder_write_lines(This->parent->encoder, pbPixels, lineCount, cbStride); + if (SUCCEEDED(hr)) + This->lines_written += lineCount; + } + + LeaveCriticalSection(&This->parent->lock); + + return hr; +} + +static HRESULT WINAPI CommonEncoderFrame_WriteSource(IWICBitmapFrameEncode *iface, + IWICBitmapSource *pIBitmapSource, WICRect *prc) +{ + CommonEncoderFrame *This = impl_from_IWICBitmapFrameEncode(iface); + HRESULT hr; + TRACE("(%p,%p,%s)\n", iface, pIBitmapSource, debug_wic_rect(prc)); + + if (!This->initialized) + return WINCODEC_ERR_WRONGSTATE; + + hr = configure_write_source(iface, pIBitmapSource, prc, + This->encoder_frame.bpp ? &This->encoder_frame.pixel_format : NULL, + This->encoder_frame.width, This->encoder_frame.height, + This->encoder_frame.dpix, This->encoder_frame.dpiy); + + if (SUCCEEDED(hr)) + { + hr = write_source(iface, pIBitmapSource, prc, + &This->encoder_frame.pixel_format, This->encoder_frame.bpp, + !This->encoder_frame.num_colors && This->encoder_frame.indexed, + This->encoder_frame.width, This->encoder_frame.height); + } + + return hr; +} + +static HRESULT WINAPI CommonEncoderFrame_Commit(IWICBitmapFrameEncode *iface) +{ + CommonEncoderFrame *This = impl_from_IWICBitmapFrameEncode(iface); + HRESULT hr; + + TRACE("(%p)\n", iface); + + EnterCriticalSection(&This->parent->lock); + + if (!This->frame_created || This->lines_written != This->encoder_frame.height || + This->committed) + { + hr = WINCODEC_ERR_WRONGSTATE; + } + else + { + hr = encoder_commit_frame(This->parent->encoder); + if (SUCCEEDED(hr)) + { + This->committed = TRUE; + This->parent->uncommitted_frame = FALSE; + } + } + + LeaveCriticalSection(&This->parent->lock); + + return hr; +} + +static HRESULT WINAPI CommonEncoderFrame_GetMetadataQueryWriter(IWICBitmapFrameEncode *iface, + IWICMetadataQueryWriter **ppIMetadataQueryWriter) +{ + CommonEncoderFrame *encoder = impl_from_IWICBitmapFrameEncode(iface); + + TRACE("iface, %p, ppIMetadataQueryWriter %p.\n", iface, ppIMetadataQueryWriter); + + if (!ppIMetadataQueryWriter) + return E_INVALIDARG; + + if (!encoder->initialized) + return WINCODEC_ERR_NOTINITIALIZED; + + if (!(encoder->parent->encoder_info.flags & ENCODER_FLAGS_SUPPORTS_METADATA)) + return WINCODEC_ERR_UNSUPPORTEDOPERATION; + + return MetadataQueryWriter_CreateInstance(&encoder->IWICMetadataBlockWriter_iface, NULL, ppIMetadataQueryWriter); +} + +static const IWICBitmapFrameEncodeVtbl CommonEncoderFrame_Vtbl = { + CommonEncoderFrame_QueryInterface, + CommonEncoderFrame_AddRef, + CommonEncoderFrame_Release, + CommonEncoderFrame_Initialize, + CommonEncoderFrame_SetSize, + CommonEncoderFrame_SetResolution, + CommonEncoderFrame_SetPixelFormat, + CommonEncoderFrame_SetColorContexts, + CommonEncoderFrame_SetPalette, + CommonEncoderFrame_SetThumbnail, + CommonEncoderFrame_WritePixels, + CommonEncoderFrame_WriteSource, + CommonEncoderFrame_Commit, + CommonEncoderFrame_GetMetadataQueryWriter +}; + +static HRESULT WINAPI CommonEncoder_QueryInterface(IWICBitmapEncoder *iface, REFIID iid, + void **ppv) +{ + CommonEncoder *This = impl_from_IWICBitmapEncoder(iface); + TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); + + if (!ppv) return E_INVALIDARG; + + if (IsEqualIID(&IID_IUnknown, iid) || + IsEqualIID(&IID_IWICBitmapEncoder, iid)) + { + *ppv = &This->IWICBitmapEncoder_iface; + } + else + { + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI CommonEncoder_AddRef(IWICBitmapEncoder *iface) +{ + CommonEncoder *This = impl_from_IWICBitmapEncoder(iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) refcount=%lu\n", iface, ref); + + return ref; +} + +static ULONG WINAPI CommonEncoder_Release(IWICBitmapEncoder *iface) +{ + CommonEncoder *This = impl_from_IWICBitmapEncoder(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) refcount=%lu\n", iface, ref); + + if (ref == 0) + { + This->lock.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&This->lock); + if (This->stream) + IStream_Release(This->stream); + encoder_destroy(This->encoder); + free(This); + } + + return ref; +} + +static HRESULT WINAPI CommonEncoder_Initialize(IWICBitmapEncoder *iface, + IStream *pIStream, WICBitmapEncoderCacheOption cacheOption) +{ + CommonEncoder *This = impl_from_IWICBitmapEncoder(iface); + HRESULT hr; + + TRACE("(%p,%p,%u)\n", iface, pIStream, cacheOption); + + if (!pIStream) + return E_POINTER; + + EnterCriticalSection(&This->lock); + + if (This->stream) + { + LeaveCriticalSection(&This->lock); + return WINCODEC_ERR_WRONGSTATE; + } + + hr = encoder_initialize(This->encoder, pIStream); + + if (SUCCEEDED(hr)) + { + This->stream = pIStream; + IStream_AddRef(This->stream); + } + + LeaveCriticalSection(&This->lock); + + return S_OK; +} + +static HRESULT WINAPI CommonEncoder_GetContainerFormat(IWICBitmapEncoder *iface, GUID *format) +{ + CommonEncoder *This = impl_from_IWICBitmapEncoder(iface); + TRACE("(%p,%p)\n", iface, format); + + if (!format) + return E_INVALIDARG; + + memcpy(format, &This->encoder_info.container_format, sizeof(*format)); + return S_OK; +} + +static HRESULT WINAPI CommonEncoder_GetEncoderInfo(IWICBitmapEncoder *iface, IWICBitmapEncoderInfo **info) +{ + CommonEncoder *This = impl_from_IWICBitmapEncoder(iface); + IWICComponentInfo *comp_info; + HRESULT hr; + + TRACE("%p,%p\n", iface, info); + + if (!info) return E_INVALIDARG; + + hr = CreateComponentInfo(&This->encoder_info.clsid, &comp_info); + if (hr == S_OK) + { + hr = IWICComponentInfo_QueryInterface(comp_info, &IID_IWICBitmapEncoderInfo, (void **)info); + IWICComponentInfo_Release(comp_info); + } + return hr; +} + +static HRESULT WINAPI CommonEncoder_SetColorContexts(IWICBitmapEncoder *iface, + UINT cCount, IWICColorContext **ppIColorContext) +{ + FIXME("(%p,%u,%p): stub\n", iface, cCount, ppIColorContext); + return E_NOTIMPL; +} + +static HRESULT WINAPI CommonEncoder_SetPalette(IWICBitmapEncoder *iface, IWICPalette *palette) +{ + CommonEncoder *This = impl_from_IWICBitmapEncoder(iface); + HRESULT hr; + + TRACE("(%p,%p)\n", iface, palette); + + EnterCriticalSection(&This->lock); + + hr = This->stream ? WINCODEC_ERR_UNSUPPORTEDOPERATION : WINCODEC_ERR_NOTINITIALIZED; + + LeaveCriticalSection(&This->lock); + + return hr; +} + +static HRESULT WINAPI CommonEncoder_SetThumbnail(IWICBitmapEncoder *iface, IWICBitmapSource *pIThumbnail) +{ + TRACE("(%p,%p)\n", iface, pIThumbnail); + return WINCODEC_ERR_UNSUPPORTEDOPERATION; +} + +static HRESULT WINAPI CommonEncoder_SetPreview(IWICBitmapEncoder *iface, IWICBitmapSource *pIPreview) +{ + TRACE("(%p,%p)\n", iface, pIPreview); + return WINCODEC_ERR_UNSUPPORTEDOPERATION; +} + +static HRESULT WINAPI CommonEncoderFrame_Block_QueryInterface(IWICMetadataBlockWriter *iface, REFIID iid, void **ppv) +{ + CommonEncoderFrame *encoder = impl_from_IWICMetadataBlockWriter(iface); + + return IWICBitmapFrameEncode_QueryInterface(&encoder->IWICBitmapFrameEncode_iface, iid, ppv); +} + +static ULONG WINAPI CommonEncoderFrame_Block_AddRef(IWICMetadataBlockWriter *iface) +{ + CommonEncoderFrame *encoder = impl_from_IWICMetadataBlockWriter(iface); + + return IWICBitmapFrameEncode_AddRef(&encoder->IWICBitmapFrameEncode_iface); +} + +static ULONG WINAPI CommonEncoderFrame_Block_Release(IWICMetadataBlockWriter *iface) +{ + CommonEncoderFrame *encoder = impl_from_IWICMetadataBlockWriter(iface); + + return IWICBitmapFrameEncode_Release(&encoder->IWICBitmapFrameEncode_iface); +} + +static HRESULT WINAPI CommonEncoderFrame_Block_GetContainerFormat(IWICMetadataBlockWriter *iface, GUID *container_format) +{ + FIXME("iface %p, container_format %p stub.\n", iface, container_format); + + return E_NOTIMPL; +} + +static HRESULT WINAPI CommonEncoderFrame_Block_GetCount(IWICMetadataBlockWriter *iface, UINT *count) +{ + FIXME("iface %p, count %p stub.\n", iface, count); + + return E_NOTIMPL; +} + +static HRESULT WINAPI CommonEncoderFrame_Block_GetReaderByIndex(IWICMetadataBlockWriter *iface, + UINT index, IWICMetadataReader **metadata_reader) +{ + FIXME("iface %p, index %d, metadata_reader %p stub.\n", iface, index, metadata_reader); + + return E_NOTIMPL; +} + +static HRESULT WINAPI CommonEncoderFrame_Block_GetEnumerator(IWICMetadataBlockWriter *iface, IEnumUnknown **enum_metadata) +{ + FIXME("iface %p, ppIEnumMetadata %p stub.\n", iface, enum_metadata); + + return E_NOTIMPL; +} + +static HRESULT WINAPI CommonEncoderFrame_Block_InitializeFromBlockReader(IWICMetadataBlockWriter *iface, + IWICMetadataBlockReader *metadata_block_reader) +{ + FIXME("iface %p, metadata_block_reader %p stub.\n", iface, metadata_block_reader); + + return E_NOTIMPL; +} + +static HRESULT WINAPI CommonEncoderFrame_Block_GetWriterByIndex(IWICMetadataBlockWriter *iface, UINT index, + IWICMetadataWriter **metadata_writer) +{ + FIXME("iface %p, index %u, metadata_writer %p stub.\n", iface, index, metadata_writer); + + return E_NOTIMPL; +} + +static HRESULT WINAPI CommonEncoderFrame_Block_AddWriter(IWICMetadataBlockWriter *iface, IWICMetadataWriter *metadata_writer) +{ + FIXME("iface %p, metadata_writer %p.\n", iface, metadata_writer); + + return E_NOTIMPL; +} + +static HRESULT WINAPI CommonEncoderFrame_Block_SetWriterByIndex(IWICMetadataBlockWriter *iface, UINT index, + IWICMetadataWriter *metadata_writer) +{ + FIXME("iface %p, index %u, metadata_writer %p stub.\n", iface, index, metadata_writer); + + return E_NOTIMPL; +} + +static HRESULT WINAPI CommonEncoderFrame_Block_RemoveWriterByIndex(IWICMetadataBlockWriter *iface, UINT index) +{ + FIXME("iface %p, index %u.\n", iface, index); + + return E_NOTIMPL; +} + +static const IWICMetadataBlockWriterVtbl CommonEncoderFrame_BlockVtbl = +{ + CommonEncoderFrame_Block_QueryInterface, + CommonEncoderFrame_Block_AddRef, + CommonEncoderFrame_Block_Release, + CommonEncoderFrame_Block_GetContainerFormat, + CommonEncoderFrame_Block_GetCount, + CommonEncoderFrame_Block_GetReaderByIndex, + CommonEncoderFrame_Block_GetEnumerator, + CommonEncoderFrame_Block_InitializeFromBlockReader, + CommonEncoderFrame_Block_GetWriterByIndex, + CommonEncoderFrame_Block_AddWriter, + CommonEncoderFrame_Block_SetWriterByIndex, + CommonEncoderFrame_Block_RemoveWriterByIndex, +}; + +static HRESULT WINAPI CommonEncoder_CreateNewFrame(IWICBitmapEncoder *iface, + IWICBitmapFrameEncode **ppIFrameEncode, IPropertyBag2 **ppIEncoderOptions) +{ + CommonEncoder *This = impl_from_IWICBitmapEncoder(iface); + CommonEncoderFrame *result; + HRESULT hr; + DWORD opts_length; + PROPBAG2 opts[6]; + + TRACE("(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions); + + EnterCriticalSection(&This->lock); + + if (This->frame_count != 0 && !(This->encoder_info.flags & ENCODER_FLAGS_MULTI_FRAME)) + { + LeaveCriticalSection(&This->lock); + return WINCODEC_ERR_UNSUPPORTEDOPERATION; + } + + if (!This->stream || This->committed || This->uncommitted_frame) + { + LeaveCriticalSection(&This->lock); + return WINCODEC_ERR_NOTINITIALIZED; + } + + result = calloc(1, sizeof(*result)); + if (!result) + { + LeaveCriticalSection(&This->lock); + return E_OUTOFMEMORY; + } + + result->IWICBitmapFrameEncode_iface.lpVtbl = &CommonEncoderFrame_Vtbl; + result->IWICMetadataBlockWriter_iface.lpVtbl = &CommonEncoderFrame_BlockVtbl; + result->ref = 1; + result->parent = This; + + if (ppIEncoderOptions) + { + for (opts_length = 0; This->encoder_info.encoder_options[opts_length] < ENCODER_OPTION_END; opts_length++) + { + opts[opts_length] = encoder_option_properties[This->encoder_info.encoder_options[opts_length]]; + } + + hr = CreatePropertyBag2(opts, opts_length, ppIEncoderOptions); + if (FAILED(hr)) + { + LeaveCriticalSection(&This->lock); + free(result); + return hr; + } + } + + IWICBitmapEncoder_AddRef(iface); + This->frame_count++; + This->uncommitted_frame = TRUE; + + LeaveCriticalSection(&This->lock); + + *ppIFrameEncode = &result->IWICBitmapFrameEncode_iface; + + return S_OK; +} + +static HRESULT WINAPI CommonEncoder_Commit(IWICBitmapEncoder *iface) +{ + CommonEncoder *This = impl_from_IWICBitmapEncoder(iface); + HRESULT hr; + + TRACE("(%p)\n", iface); + + EnterCriticalSection(&This->lock); + + if (This->committed || This->uncommitted_frame) + hr = WINCODEC_ERR_WRONGSTATE; + else + { + hr = encoder_commit_file(This->encoder); + if (SUCCEEDED(hr)) + This->committed = TRUE; + } + + LeaveCriticalSection(&This->lock); + + return hr; +} + +static HRESULT WINAPI CommonEncoder_GetMetadataQueryWriter(IWICBitmapEncoder *iface, + IWICMetadataQueryWriter **ppIMetadataQueryWriter) +{ + FIXME("(%p,%p): stub\n", iface, ppIMetadataQueryWriter); + return E_NOTIMPL; +} + +static const IWICBitmapEncoderVtbl CommonEncoder_Vtbl = { + CommonEncoder_QueryInterface, + CommonEncoder_AddRef, + CommonEncoder_Release, + CommonEncoder_Initialize, + CommonEncoder_GetContainerFormat, + CommonEncoder_GetEncoderInfo, + CommonEncoder_SetColorContexts, + CommonEncoder_SetPalette, + CommonEncoder_SetThumbnail, + CommonEncoder_SetPreview, + CommonEncoder_CreateNewFrame, + CommonEncoder_Commit, + CommonEncoder_GetMetadataQueryWriter +}; + +HRESULT CommonEncoder_CreateInstance(struct encoder *encoder, + const struct encoder_info *encoder_info, REFIID iid, void** ppv) +{ + CommonEncoder *This; + HRESULT ret; + + TRACE("(%s,%p)\n", debugstr_guid(iid), ppv); + + *ppv = NULL; + + This = malloc(sizeof(CommonEncoder)); + if (!This) + { + encoder_destroy(encoder); + return E_OUTOFMEMORY; + } + + This->IWICBitmapEncoder_iface.lpVtbl = &CommonEncoder_Vtbl; + This->ref = 1; + This->stream = NULL; + This->encoder = encoder; + This->encoder_info = *encoder_info; + This->frame_count = 0; + This->uncommitted_frame = FALSE; + This->committed = FALSE; +#ifdef __REACTOS__ + InitializeCriticalSection(&This->lock); +#else + InitializeCriticalSectionEx(&This->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif + This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": CommonEncoder.lock"); + + ret = IWICBitmapEncoder_QueryInterface(&This->IWICBitmapEncoder_iface, iid, ppv); + IWICBitmapEncoder_Release(&This->IWICBitmapEncoder_iface); + + return ret; +} diff --git a/dll/win32/windowscodecs/fliprotate.c b/dll/win32/windowscodecs/fliprotate.c index 46402237eefd8..cb631637ba116 100644 --- a/dll/win32/windowscodecs/fliprotate.c +++ b/dll/win32/windowscodecs/fliprotate.c @@ -16,8 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" - #include #define COBJMACROS @@ -76,7 +74,7 @@ static ULONG WINAPI FlipRotator_AddRef(IWICBitmapFlipRotator *iface) FlipRotator *This = impl_from_IWICBitmapFlipRotator(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -86,14 +84,14 @@ static ULONG WINAPI FlipRotator_Release(IWICBitmapFlipRotator *iface) FlipRotator *This = impl_from_IWICBitmapFlipRotator(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { This->lock.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&This->lock); if (This->source) IWICBitmapSource_Release(This->source); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; @@ -269,7 +267,7 @@ HRESULT FlipRotator_Create(IWICBitmapFlipRotator **fliprotator) { FlipRotator *This; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(FlipRotator)); + This = malloc(sizeof(FlipRotator)); if (!This) return E_OUTOFMEMORY; This->IWICBitmapFlipRotator_iface.lpVtbl = &FlipRotator_Vtbl; @@ -278,7 +276,11 @@ HRESULT FlipRotator_Create(IWICBitmapFlipRotator **fliprotator) This->flip_x = 0; This->flip_y = 0; This->swap_xy = 0; +#ifdef __REACTOS__ InitializeCriticalSection(&This->lock); +#else + InitializeCriticalSectionEx(&This->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": FlipRotator.lock"); *fliprotator = &This->IWICBitmapFlipRotator_iface; diff --git a/dll/win32/windowscodecs/gifformat.c b/dll/win32/windowscodecs/gifformat.c index d4d23ff6f3c2e..1c9f884bd8cf3 100644 --- a/dll/win32/windowscodecs/gifformat.c +++ b/dll/win32/windowscodecs/gifformat.c @@ -17,23 +17,19 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" - #include #define COBJMACROS -#define NONAMELESSUNION - #include "windef.h" #include "winbase.h" #include "objbase.h" +#include "shlwapi.h" #include "ungif.h" #include "wincodecs_private.h" #include "wine/debug.h" - #ifdef __REACTOS__ #include #endif @@ -74,14 +70,6 @@ struct image_descriptor #include "poppack.h" -static LPWSTR strdupAtoW(const char *src) -{ - int len = MultiByteToWideChar(CP_ACP, 0, src, -1, NULL, 0); - LPWSTR dst = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); - if (dst) MultiByteToWideChar(CP_ACP, 0, src, -1, dst, len); - return dst; -} - static HRESULT load_LSD_metadata(IStream *stream, const GUID *vendor, DWORD options, MetadataItem **items, DWORD *count) { @@ -96,7 +84,7 @@ static HRESULT load_LSD_metadata(IStream *stream, const GUID *vendor, DWORD opti hr = IStream_Read(stream, &lsd_data, sizeof(lsd_data), &bytesread); if (FAILED(hr) || bytesread != sizeof(lsd_data)) return S_OK; - result = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MetadataItem) * 9); + result = calloc(9, sizeof(MetadataItem)); if (!result) return E_OUTOFMEMORY; for (i = 0; i < 9; i++) @@ -107,51 +95,51 @@ static HRESULT load_LSD_metadata(IStream *stream, const GUID *vendor, DWORD opti } result[0].id.vt = VT_LPWSTR; - result[0].id.u.pwszVal = strdupAtoW("Signature"); + SHStrDupW(L"Signature", &result[0].id.pwszVal); result[0].value.vt = VT_UI1|VT_VECTOR; - result[0].value.u.caub.cElems = sizeof(lsd_data.signature); - result[0].value.u.caub.pElems = HeapAlloc(GetProcessHeap(), 0, sizeof(lsd_data.signature)); - memcpy(result[0].value.u.caub.pElems, lsd_data.signature, sizeof(lsd_data.signature)); + result[0].value.caub.cElems = sizeof(lsd_data.signature); + result[0].value.caub.pElems = CoTaskMemAlloc(sizeof(lsd_data.signature)); + memcpy(result[0].value.caub.pElems, lsd_data.signature, sizeof(lsd_data.signature)); result[1].id.vt = VT_LPWSTR; - result[1].id.u.pwszVal = strdupAtoW("Width"); + SHStrDupW(L"Width", &result[1].id.pwszVal); result[1].value.vt = VT_UI2; - result[1].value.u.uiVal = lsd_data.width; + result[1].value.uiVal = lsd_data.width; result[2].id.vt = VT_LPWSTR; - result[2].id.u.pwszVal = strdupAtoW("Height"); + SHStrDupW(L"Height", &result[2].id.pwszVal); result[2].value.vt = VT_UI2; - result[2].value.u.uiVal = lsd_data.height; + result[2].value.uiVal = lsd_data.height; result[3].id.vt = VT_LPWSTR; - result[3].id.u.pwszVal = strdupAtoW("GlobalColorTableFlag"); + SHStrDupW(L"GlobalColorTableFlag", &result[3].id.pwszVal); result[3].value.vt = VT_BOOL; - result[3].value.u.boolVal = (lsd_data.packed >> 7) & 1; + result[3].value.boolVal = (lsd_data.packed >> 7) & 1; result[4].id.vt = VT_LPWSTR; - result[4].id.u.pwszVal = strdupAtoW("ColorResolution"); + SHStrDupW(L"ColorResolution", &result[4].id.pwszVal); result[4].value.vt = VT_UI1; - result[4].value.u.bVal = (lsd_data.packed >> 4) & 7; + result[4].value.bVal = (lsd_data.packed >> 4) & 7; result[5].id.vt = VT_LPWSTR; - result[5].id.u.pwszVal = strdupAtoW("SortFlag"); + SHStrDupW(L"SortFlag", &result[5].id.pwszVal); result[5].value.vt = VT_BOOL; - result[5].value.u.boolVal = (lsd_data.packed >> 3) & 1; + result[5].value.boolVal = (lsd_data.packed >> 3) & 1; result[6].id.vt = VT_LPWSTR; - result[6].id.u.pwszVal = strdupAtoW("GlobalColorTableSize"); + SHStrDupW(L"GlobalColorTableSize", &result[6].id.pwszVal); result[6].value.vt = VT_UI1; - result[6].value.u.bVal = lsd_data.packed & 7; + result[6].value.bVal = lsd_data.packed & 7; result[7].id.vt = VT_LPWSTR; - result[7].id.u.pwszVal = strdupAtoW("BackgroundColorIndex"); + SHStrDupW(L"BackgroundColorIndex", &result[7].id.pwszVal); result[7].value.vt = VT_UI1; - result[7].value.u.bVal = lsd_data.background_color_index; + result[7].value.bVal = lsd_data.background_color_index; result[8].id.vt = VT_LPWSTR; - result[8].id.u.pwszVal = strdupAtoW("PixelAspectRatio"); + SHStrDupW(L"PixelAspectRatio", &result[8].id.pwszVal); result[8].value.vt = VT_UI1; - result[8].value.u.bVal = lsd_data.pixel_aspect_ratio; + result[8].value.bVal = lsd_data.pixel_aspect_ratio; *items = result; *count = 9; @@ -184,7 +172,7 @@ static HRESULT load_IMD_metadata(IStream *stream, const GUID *vendor, DWORD opti hr = IStream_Read(stream, &imd_data, sizeof(imd_data), &bytesread); if (FAILED(hr) || bytesread != sizeof(imd_data)) return S_OK; - result = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MetadataItem) * 8); + result = calloc(8, sizeof(MetadataItem)); if (!result) return E_OUTOFMEMORY; for (i = 0; i < 8; i++) @@ -195,44 +183,44 @@ static HRESULT load_IMD_metadata(IStream *stream, const GUID *vendor, DWORD opti } result[0].id.vt = VT_LPWSTR; - result[0].id.u.pwszVal = strdupAtoW("Left"); + SHStrDupW(L"Left", &result[0].id.pwszVal); result[0].value.vt = VT_UI2; - result[0].value.u.uiVal = imd_data.left; + result[0].value.uiVal = imd_data.left; result[1].id.vt = VT_LPWSTR; - result[1].id.u.pwszVal = strdupAtoW("Top"); + SHStrDupW(L"Top", &result[1].id.pwszVal); result[1].value.vt = VT_UI2; - result[1].value.u.uiVal = imd_data.top; + result[1].value.uiVal = imd_data.top; result[2].id.vt = VT_LPWSTR; - result[2].id.u.pwszVal = strdupAtoW("Width"); + SHStrDupW(L"Width", &result[2].id.pwszVal); result[2].value.vt = VT_UI2; - result[2].value.u.uiVal = imd_data.width; + result[2].value.uiVal = imd_data.width; result[3].id.vt = VT_LPWSTR; - result[3].id.u.pwszVal = strdupAtoW("Height"); + SHStrDupW(L"Height", &result[3].id.pwszVal); result[3].value.vt = VT_UI2; - result[3].value.u.uiVal = imd_data.height; + result[3].value.uiVal = imd_data.height; result[4].id.vt = VT_LPWSTR; - result[4].id.u.pwszVal = strdupAtoW("LocalColorTableFlag"); + SHStrDupW(L"LocalColorTableFlag", &result[4].id.pwszVal); result[4].value.vt = VT_BOOL; - result[4].value.u.boolVal = (imd_data.packed >> 7) & 1; + result[4].value.boolVal = (imd_data.packed >> 7) & 1; result[5].id.vt = VT_LPWSTR; - result[5].id.u.pwszVal = strdupAtoW("InterlaceFlag"); + SHStrDupW(L"InterlaceFlag", &result[5].id.pwszVal); result[5].value.vt = VT_BOOL; - result[5].value.u.boolVal = (imd_data.packed >> 6) & 1; + result[5].value.boolVal = (imd_data.packed >> 6) & 1; result[6].id.vt = VT_LPWSTR; - result[6].id.u.pwszVal = strdupAtoW("SortFlag"); + SHStrDupW(L"SortFlag", &result[6].id.pwszVal); result[6].value.vt = VT_BOOL; - result[6].value.u.boolVal = (imd_data.packed >> 5) & 1; + result[6].value.boolVal = (imd_data.packed >> 5) & 1; result[7].id.vt = VT_LPWSTR; - result[7].id.u.pwszVal = strdupAtoW("LocalColorTableSize"); + SHStrDupW(L"LocalColorTableSize", &result[7].id.pwszVal); result[7].value.vt = VT_UI1; - result[7].value.u.bVal = imd_data.packed & 7; + result[7].value.bVal = imd_data.packed & 7; *items = result; *count = 8; @@ -277,7 +265,7 @@ static HRESULT load_GCE_metadata(IStream *stream, const GUID *vendor, DWORD opti hr = IStream_Read(stream, &gce_data, sizeof(gce_data), &bytesread); if (FAILED(hr) || bytesread != sizeof(gce_data)) return S_OK; - result = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MetadataItem) * 5); + result = calloc(5, sizeof(MetadataItem)); if (!result) return E_OUTOFMEMORY; for (i = 0; i < 5; i++) @@ -288,29 +276,29 @@ static HRESULT load_GCE_metadata(IStream *stream, const GUID *vendor, DWORD opti } result[0].id.vt = VT_LPWSTR; - result[0].id.u.pwszVal = strdupAtoW("Disposal"); + SHStrDupW(L"Disposal", &result[0].id.pwszVal); result[0].value.vt = VT_UI1; - result[0].value.u.bVal = (gce_data.packed >> 2) & 7; + result[0].value.bVal = (gce_data.packed >> 2) & 7; result[1].id.vt = VT_LPWSTR; - result[1].id.u.pwszVal = strdupAtoW("UserInputFlag"); + SHStrDupW(L"UserInputFlag", &result[1].id.pwszVal); result[1].value.vt = VT_BOOL; - result[1].value.u.boolVal = (gce_data.packed >> 1) & 1; + result[1].value.boolVal = (gce_data.packed >> 1) & 1; result[2].id.vt = VT_LPWSTR; - result[2].id.u.pwszVal = strdupAtoW("TransparencyFlag"); + SHStrDupW(L"TransparencyFlag", &result[2].id.pwszVal); result[2].value.vt = VT_BOOL; - result[2].value.u.boolVal = gce_data.packed & 1; + result[2].value.boolVal = gce_data.packed & 1; result[3].id.vt = VT_LPWSTR; - result[3].id.u.pwszVal = strdupAtoW("Delay"); + SHStrDupW(L"Delay", &result[3].id.pwszVal); result[3].value.vt = VT_UI2; - result[3].value.u.uiVal = gce_data.delay; + result[3].value.uiVal = gce_data.delay; result[4].id.vt = VT_LPWSTR; - result[4].id.u.pwszVal = strdupAtoW("TransparentColorIndex"); + SHStrDupW(L"TransparentColorIndex", &result[4].id.pwszVal); result[4].value.vt = VT_UI1; - result[4].value.u.bVal = gce_data.transparent_color_index; + result[4].value.bVal = gce_data.transparent_color_index; *items = result; *count = 5; @@ -365,19 +353,19 @@ static HRESULT load_APE_metadata(IStream *stream, const GUID *vendor, DWORD opti hr = IStream_Read(stream, &subblock_size, sizeof(subblock_size), &bytesread); if (FAILED(hr) || bytesread != sizeof(subblock_size)) { - HeapFree(GetProcessHeap(), 0, data); + CoTaskMemFree(data); return S_OK; } if (!subblock_size) break; if (!data) - data = HeapAlloc(GetProcessHeap(), 0, subblock_size + 1); + data = CoTaskMemAlloc(subblock_size + 1); else { - BYTE *new_data = HeapReAlloc(GetProcessHeap(), 0, data, data_size + subblock_size + 1); + BYTE *new_data = CoTaskMemRealloc(data, data_size + subblock_size + 1); if (!new_data) { - HeapFree(GetProcessHeap(), 0, data); + CoTaskMemFree(data); return S_OK; } data = new_data; @@ -386,16 +374,16 @@ static HRESULT load_APE_metadata(IStream *stream, const GUID *vendor, DWORD opti hr = IStream_Read(stream, data + data_size + 1, subblock_size, &bytesread); if (FAILED(hr) || bytesread != subblock_size) { - HeapFree(GetProcessHeap(), 0, data); + CoTaskMemFree(data); return S_OK; } data_size += subblock_size + 1; } - result = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MetadataItem) * 2); + result = calloc(2, sizeof(MetadataItem)); if (!result) { - HeapFree(GetProcessHeap(), 0, data); + CoTaskMemFree(data); return E_OUTOFMEMORY; } @@ -407,17 +395,17 @@ static HRESULT load_APE_metadata(IStream *stream, const GUID *vendor, DWORD opti } result[0].id.vt = VT_LPWSTR; - result[0].id.u.pwszVal = strdupAtoW("Application"); + SHStrDupW(L"Application", &result[0].id.pwszVal); result[0].value.vt = VT_UI1|VT_VECTOR; - result[0].value.u.caub.cElems = sizeof(ape_data.application); - result[0].value.u.caub.pElems = HeapAlloc(GetProcessHeap(), 0, sizeof(ape_data.application)); - memcpy(result[0].value.u.caub.pElems, ape_data.application, sizeof(ape_data.application)); + result[0].value.caub.cElems = sizeof(ape_data.application); + result[0].value.caub.pElems = CoTaskMemAlloc(sizeof(ape_data.application)); + memcpy(result[0].value.caub.pElems, ape_data.application, sizeof(ape_data.application)); result[1].id.vt = VT_LPWSTR; - result[1].id.u.pwszVal = strdupAtoW("Data"); + SHStrDupW(L"Data", &result[1].id.pwszVal); result[1].value.vt = VT_UI1|VT_VECTOR; - result[1].value.u.caub.cElems = data_size; - result[1].value.u.caub.pElems = data; + result[1].value.caub.cElems = data_size; + result[1].value.caub.pElems = data; *items = result; *count = 2; @@ -469,19 +457,19 @@ static HRESULT load_GifComment_metadata(IStream *stream, const GUID *vendor, DWO hr = IStream_Read(stream, &subblock_size, sizeof(subblock_size), &bytesread); if (FAILED(hr) || bytesread != sizeof(subblock_size)) { - HeapFree(GetProcessHeap(), 0, data); + CoTaskMemFree(data); return S_OK; } if (!subblock_size) break; if (!data) - data = HeapAlloc(GetProcessHeap(), 0, subblock_size + 1); + data = CoTaskMemAlloc(subblock_size + 1); else { - char *new_data = HeapReAlloc(GetProcessHeap(), 0, data, data_size + subblock_size + 1); + char *new_data = CoTaskMemRealloc(data, data_size + subblock_size + 1); if (!new_data) { - HeapFree(GetProcessHeap(), 0, data); + CoTaskMemFree(data); return S_OK; } data = new_data; @@ -489,7 +477,7 @@ static HRESULT load_GifComment_metadata(IStream *stream, const GUID *vendor, DWO hr = IStream_Read(stream, data + data_size, subblock_size, &bytesread); if (FAILED(hr) || bytesread != subblock_size) { - HeapFree(GetProcessHeap(), 0, data); + CoTaskMemFree(data); return S_OK; } data_size += subblock_size; @@ -497,10 +485,10 @@ static HRESULT load_GifComment_metadata(IStream *stream, const GUID *vendor, DWO data[data_size] = 0; - result = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MetadataItem)); + result = calloc(1, sizeof(MetadataItem)); if (!result) { - HeapFree(GetProcessHeap(), 0, data); + CoTaskMemFree(data); return E_OUTOFMEMORY; } @@ -509,9 +497,9 @@ static HRESULT load_GifComment_metadata(IStream *stream, const GUID *vendor, DWO PropVariantInit(&result->value); result->id.vt = VT_LPWSTR; - result->id.u.pwszVal = strdupAtoW("TextEntry"); + SHStrDupW(L"TextEntry", &result->id.pwszVal); result->value.vt = VT_LPSTR; - result->value.u.pszVal = data; + result->value.pszVal = data; *items = result; *count = 1; @@ -652,7 +640,7 @@ static ULONG WINAPI GifFrameDecode_AddRef(IWICBitmapFrameDecode *iface) GifFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -662,12 +650,12 @@ static ULONG WINAPI GifFrameDecode_Release(IWICBitmapFrameDecode *iface) GifFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { IWICBitmapDecoder_Release(&This->parent->IWICBitmapDecoder_iface); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; @@ -707,44 +695,69 @@ static HRESULT WINAPI GifFrameDecode_GetResolution(IWICBitmapFrameDecode *iface, return S_OK; } +static void copy_palette(ColorMapObject *cm, Extensions *extensions, int count, WICColor *colors) +{ + int i; + + if (cm) + { + for (i = 0; i < count; i++) + { + colors[i] = 0xff000000 | /* alpha */ + cm->Colors[i].Red << 16 | + cm->Colors[i].Green << 8 | + cm->Colors[i].Blue; + } + } + else + { + colors[0] = 0xff000000; + colors[1] = 0xffffffff; + for (i = 2; i < count; i++) + colors[i] = 0xff000000; + } + + /* look for the transparent color extension */ + for (i = 0; i < extensions->ExtensionBlockCount; i++) + { + ExtensionBlock *eb = extensions->ExtensionBlocks + i; + if (eb->Function == GRAPHICS_EXT_FUNC_CODE && + eb->ByteCount == 8 && eb->Bytes[3] & 1) + { + int trans = (unsigned char)eb->Bytes[6]; + colors[trans] &= 0xffffff; /* set alpha to 0 */ + break; + } + } +} + static HRESULT WINAPI GifFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface, IWICPalette *pIPalette) { GifFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); WICColor colors[256]; ColorMapObject *cm = This->frame->ImageDesc.ColorMap; - int i, trans; - ExtensionBlock *eb; - TRACE("(%p,%p)\n", iface, pIPalette); + int count; - if (!cm) cm = This->parent->gif->SColorMap; + TRACE("(%p,%p)\n", iface, pIPalette); - if (cm->ColorCount > 256) + if (cm) + count = cm->ColorCount; + else { - ERR("GIF contains %i colors???\n", cm->ColorCount); - return E_FAIL; + cm = This->parent->gif->SColorMap; + count = This->parent->gif->SColorTableSize; } - for (i = 0; i < cm->ColorCount; i++) { - colors[i] = 0xff000000| /* alpha */ - cm->Colors[i].Red << 16| - cm->Colors[i].Green << 8| - cm->Colors[i].Blue; + if (count > 256) + { + ERR("GIF contains %i colors???\n", count); + return E_FAIL; } - /* look for the transparent color extension */ - for (i = 0; i < This->frame->Extensions.ExtensionBlockCount; ++i) { - eb = This->frame->Extensions.ExtensionBlocks + i; - if (eb->Function == GRAPHICS_EXT_FUNC_CODE && eb->ByteCount == 8) { - if (eb->Bytes[3] & 1) { - trans = (unsigned char)eb->Bytes[6]; - colors[trans] &= 0xffffff; /* set alpha to 0 */ - break; - } - } - } + copy_palette(cm, &This->frame->Extensions, count, colors); - return IWICPalette_InitializeCustom(pIPalette, colors, cm->ColorCount); + return IWICPalette_InitializeCustom(pIPalette, colors, count); } static HRESULT copy_interlaced_pixels(const BYTE *srcbuffer, @@ -953,7 +966,10 @@ static HRESULT WINAPI GifFrameDecode_Block_GetReaderByIndex(IWICMetadataBlockRea UINT index, IWICMetadataReader **reader) { GifFrameDecode *This = frame_from_IWICMetadataBlockReader(iface); - int i, gce_index = -1, gce_skipped = 0; + class_constructor constructor; + ExtensionBlock *ext; + const void *data; + int data_size; TRACE("(%p,%u,%p)\n", iface, index, reader); @@ -965,40 +981,27 @@ static HRESULT WINAPI GifFrameDecode_Block_GetReaderByIndex(IWICMetadataBlockRea if (index >= This->frame->Extensions.ExtensionBlockCount + 1) return E_INVALIDARG; - for (i = 0; i < This->frame->Extensions.ExtensionBlockCount; i++) + ext = This->frame->Extensions.ExtensionBlocks + index - 1; + if (ext->Function == GRAPHICS_EXT_FUNC_CODE) { - class_constructor constructor; - const void *data; - int data_size; - - if (index != i + 1 - gce_skipped) continue; - - if (This->frame->Extensions.ExtensionBlocks[i].Function == GRAPHICS_EXT_FUNC_CODE) - { - gce_index = i; - gce_skipped = 1; - continue; - } - else if (This->frame->Extensions.ExtensionBlocks[i].Function == COMMENT_EXT_FUNC_CODE) - { - constructor = GifCommentReader_CreateInstance; - data = This->frame->Extensions.ExtensionBlocks[i].Bytes; - data_size = This->frame->Extensions.ExtensionBlocks[i].ByteCount; - } - else - { - constructor = UnknownMetadataReader_CreateInstance; - data = This->frame->Extensions.ExtensionBlocks[i].Bytes; - data_size = This->frame->Extensions.ExtensionBlocks[i].ByteCount; - } - return create_metadata_reader(data, data_size, constructor, reader); + constructor = GCEReader_CreateInstance; + data = ext->Bytes + 3; + data_size = ext->ByteCount - 4; + } + else if (ext->Function == COMMENT_EXT_FUNC_CODE) + { + constructor = GifCommentReader_CreateInstance; + data = ext->Bytes; + data_size = ext->ByteCount; + } + else + { + constructor = UnknownMetadataReader_CreateInstance; + data = ext->Bytes; + data_size = ext->ByteCount; } - if (gce_index == -1) return E_INVALIDARG; - - return create_metadata_reader(This->frame->Extensions.ExtensionBlocks[gce_index].Bytes + 3, - This->frame->Extensions.ExtensionBlocks[gce_index].ByteCount - 4, - GCEReader_CreateInstance, reader); + return create_metadata_reader(data, data_size, constructor, reader); } static HRESULT WINAPI GifFrameDecode_Block_GetEnumerator(IWICMetadataBlockReader *iface, @@ -1051,7 +1054,7 @@ static ULONG WINAPI GifDecoder_AddRef(IWICBitmapDecoder *iface) GifDecoder *This = impl_from_IWICBitmapDecoder(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -1061,7 +1064,7 @@ static ULONG WINAPI GifDecoder_Release(IWICBitmapDecoder *iface) GifDecoder *This = impl_from_IWICBitmapDecoder(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { @@ -1072,7 +1075,7 @@ static ULONG WINAPI GifDecoder_Release(IWICBitmapDecoder *iface) } This->lock.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&This->lock); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; @@ -1186,8 +1189,7 @@ static HRESULT WINAPI GifDecoder_CopyPalette(IWICBitmapDecoder *iface, IWICPalet GifDecoder *This = impl_from_IWICBitmapDecoder(iface); WICColor colors[256]; ColorMapObject *cm; - int i, trans, count; - ExtensionBlock *eb; + int count; TRACE("(%p,%p)\n", iface, palette); @@ -1195,49 +1197,15 @@ static HRESULT WINAPI GifDecoder_CopyPalette(IWICBitmapDecoder *iface, IWICPalet return WINCODEC_ERR_WRONGSTATE; cm = This->gif->SColorMap; - if (cm) - { - if (cm->ColorCount > 256) - { - ERR("GIF contains invalid number of colors: %d\n", cm->ColorCount); - return E_FAIL; - } + count = This->gif->SColorTableSize; - for (i = 0; i < cm->ColorCount; i++) - { - colors[i] = 0xff000000 | /* alpha */ - cm->Colors[i].Red << 16 | - cm->Colors[i].Green << 8 | - cm->Colors[i].Blue; - } - - count = cm->ColorCount; - } - else + if (count > 256) { - colors[0] = 0xff000000; - colors[1] = 0xffffffff; - - for (i = 2; i < 256; i++) - colors[i] = 0xff000000; - - count = 256; + ERR("GIF contains invalid number of colors: %d\n", count); + return E_FAIL; } - /* look for the transparent color extension */ - for (i = 0; i < This->gif->SavedImages[This->current_frame].Extensions.ExtensionBlockCount; i++) - { - eb = This->gif->SavedImages[This->current_frame].Extensions.ExtensionBlocks + i; - if (eb->Function == GRAPHICS_EXT_FUNC_CODE && eb->ByteCount == 8) - { - if (eb->Bytes[3] & 1) - { - trans = (unsigned char)eb->Bytes[6]; - colors[trans] &= 0xffffff; /* set alpha to 0 */ - break; - } - } - } + copy_palette(cm, &This->gif->SavedImages[This->current_frame].Extensions, count, colors); return IWICPalette_InitializeCustom(palette, colors, count); } @@ -1302,7 +1270,7 @@ static HRESULT WINAPI GifDecoder_GetFrame(IWICBitmapDecoder *iface, if (index >= This->gif->ImageCount) return E_INVALIDARG; - result = HeapAlloc(GetProcessHeap(), 0, sizeof(GifFrameDecode)); + result = malloc(sizeof(GifFrameDecode)); if (!result) return E_OUTOFMEMORY; result->IWICBitmapFrameDecode_iface.lpVtbl = &GifFrameDecode_Vtbl; @@ -1440,7 +1408,7 @@ HRESULT GifDecoder_CreateInstance(REFIID iid, void** ppv) *ppv = NULL; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(GifDecoder)); + This = malloc(sizeof(GifDecoder)); if (!This) return E_OUTOFMEMORY; This->IWICBitmapDecoder_iface.lpVtbl = &GifDecoder_Vtbl; @@ -1450,7 +1418,11 @@ HRESULT GifDecoder_CreateInstance(REFIID iid, void** ppv) This->initialized = FALSE; This->gif = NULL; This->current_frame = 0; +#ifdef __REACTOS__ InitializeCriticalSection(&This->lock); +#else + InitializeCriticalSectionEx(&This->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": GifDecoder.lock"); ret = IWICBitmapDecoder_QueryInterface(&This->IWICBitmapDecoder_iface, iid, ppv); @@ -1479,6 +1451,7 @@ static inline GifEncoder *impl_from_IWICBitmapEncoder(IWICBitmapEncoder *iface) typedef struct GifFrameEncode { IWICBitmapFrameEncode IWICBitmapFrameEncode_iface; + IWICMetadataBlockWriter IWICMetadataBlockWriter_iface; LONG ref; GifEncoder *encoder; BOOL initialized, interlace, committed; @@ -1494,8 +1467,15 @@ static inline GifFrameEncode *impl_from_IWICBitmapFrameEncode(IWICBitmapFrameEnc return CONTAINING_RECORD(iface, GifFrameEncode, IWICBitmapFrameEncode_iface); } +static inline GifFrameEncode *impl_from_IWICMetadataBlockWriter(IWICMetadataBlockWriter *iface) +{ + return CONTAINING_RECORD(iface, GifFrameEncode, IWICMetadataBlockWriter_iface); +} + static HRESULT WINAPI GifFrameEncode_QueryInterface(IWICBitmapFrameEncode *iface, REFIID iid, void **ppv) { + GifFrameEncode *encoder = impl_from_IWICBitmapFrameEncode(iface); + TRACE("%p,%s,%p\n", iface, debugstr_guid(iid), ppv); if (!ppv) return E_INVALIDARG; @@ -1503,13 +1483,20 @@ static HRESULT WINAPI GifFrameEncode_QueryInterface(IWICBitmapFrameEncode *iface if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IWICBitmapFrameEncode, iid)) { - IWICBitmapFrameEncode_AddRef(iface); *ppv = iface; - return S_OK; + } + else if (IsEqualIID(&IID_IWICMetadataBlockWriter, iid)) + { + *ppv = &encoder->IWICMetadataBlockWriter_iface; + } + else + { + *ppv = NULL; + return E_NOINTERFACE; } - *ppv = NULL; - return E_NOINTERFACE; + IUnknown_AddRef((IUnknown *)*ppv); + return S_OK; } static ULONG WINAPI GifFrameEncode_AddRef(IWICBitmapFrameEncode *iface) @@ -1517,7 +1504,7 @@ static ULONG WINAPI GifFrameEncode_AddRef(IWICBitmapFrameEncode *iface) GifFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("%p -> %u\n", iface, ref); + TRACE("%p -> %lu\n", iface, ref); return ref; } @@ -1526,13 +1513,13 @@ static ULONG WINAPI GifFrameEncode_Release(IWICBitmapFrameEncode *iface) GifFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("%p -> %u\n", iface, ref); + TRACE("%p -> %lu\n", iface, ref); if (!ref) { IWICBitmapEncoder_Release(&This->encoder->IWICBitmapEncoder_iface); - HeapFree(GetProcessHeap(), 0, This->image_data); - HeapFree(GetProcessHeap(), 0, This); + free(This->image_data); + free(This); } return ref; @@ -1573,9 +1560,9 @@ static HRESULT WINAPI GifFrameEncode_SetSize(IWICBitmapFrameEncode *iface, UINT if (This->initialized) { - HeapFree(GetProcessHeap(), 0, This->image_data); + free(This->image_data); - This->image_data = HeapAlloc(GetProcessHeap(), 0, width * height); + This->image_data = malloc(width * height); if (This->image_data) { This->width = width; @@ -1731,7 +1718,7 @@ static HRESULT WINAPI GifFrameEncode_WriteSource(IWICBitmapFrameEncode *iface, I hr = configure_write_source(iface, source, rc, format, This->width, This->height, This->xres, This->yres); if (hr == S_OK) - hr = write_source(iface, source, rc, format, 8, This->width, This->height); + hr = write_source(iface, source, rc, format, 8, !This->colors, This->width, This->height); } else hr = WINCODEC_ERR_WRONGSTATE; @@ -2108,8 +2095,17 @@ static HRESULT WINAPI GifFrameEncode_Commit(IWICBitmapFrameEncode *iface) static HRESULT WINAPI GifFrameEncode_GetMetadataQueryWriter(IWICBitmapFrameEncode *iface, IWICMetadataQueryWriter **writer) { - FIXME("%p, %p: stub\n", iface, writer); - return E_NOTIMPL; + GifFrameEncode *encode = impl_from_IWICBitmapFrameEncode(iface); + + TRACE("iface, %p, writer %p.\n", iface, writer); + + if (!writer) + return E_INVALIDARG; + + if (!encode->initialized) + return WINCODEC_ERR_NOTINITIALIZED; + + return MetadataQueryWriter_CreateInstance(&encode->IWICMetadataBlockWriter_iface, NULL, writer); } static const IWICBitmapFrameEncodeVtbl GifFrameEncode_Vtbl = @@ -2153,7 +2149,7 @@ static ULONG WINAPI GifEncoder_AddRef(IWICBitmapEncoder *iface) GifEncoder *This = impl_from_IWICBitmapEncoder(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("%p -> %u\n", iface, ref); + TRACE("%p -> %lu\n", iface, ref); return ref; } @@ -2162,14 +2158,14 @@ static ULONG WINAPI GifEncoder_Release(IWICBitmapEncoder *iface) GifEncoder *This = impl_from_IWICBitmapEncoder(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("%p -> %u\n", iface, ref); + TRACE("%p -> %lu\n", iface, ref); if (!ref) { if (This->stream) IStream_Release(This->stream); This->lock.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&This->lock); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; @@ -2265,6 +2261,109 @@ static HRESULT WINAPI GifEncoder_SetPreview(IWICBitmapEncoder *iface, IWICBitmap return WINCODEC_ERR_UNSUPPORTEDOPERATION; } +static HRESULT WINAPI GifEncoderFrame_Block_QueryInterface(IWICMetadataBlockWriter *iface, REFIID iid, void **ppv) +{ + GifFrameEncode *frame_encoder = impl_from_IWICMetadataBlockWriter(iface); + + return IWICBitmapFrameEncode_QueryInterface(&frame_encoder->IWICBitmapFrameEncode_iface, iid, ppv); +} + +static ULONG WINAPI GifEncoderFrame_Block_AddRef(IWICMetadataBlockWriter *iface) +{ + GifFrameEncode *frame_encoder = impl_from_IWICMetadataBlockWriter(iface); + + return IWICBitmapFrameEncode_AddRef(&frame_encoder->IWICBitmapFrameEncode_iface); +} + +static ULONG WINAPI GifEncoderFrame_Block_Release(IWICMetadataBlockWriter *iface) +{ + GifFrameEncode *frame_encoder = impl_from_IWICMetadataBlockWriter(iface); + + return IWICBitmapFrameEncode_Release(&frame_encoder->IWICBitmapFrameEncode_iface); +} + +static HRESULT WINAPI GifEncoderFrame_Block_GetContainerFormat(IWICMetadataBlockWriter *iface, GUID *container_format) +{ + FIXME("iface %p, container_format %p stub.\n", iface, container_format); + + return E_NOTIMPL; +} + +static HRESULT WINAPI GifEncoderFrame_Block_GetCount(IWICMetadataBlockWriter *iface, UINT *count) +{ + FIXME("iface %p, count %p stub.\n", iface, count); + + return E_NOTIMPL; +} + +static HRESULT WINAPI GifEncoderFrame_Block_GetReaderByIndex(IWICMetadataBlockWriter *iface, + UINT index, IWICMetadataReader **metadata_reader) +{ + FIXME("iface %p, index %d, metadata_reader %p stub.\n", iface, index, metadata_reader); + + return E_NOTIMPL; +} + +static HRESULT WINAPI GifEncoderFrame_Block_GetEnumerator(IWICMetadataBlockWriter *iface, IEnumUnknown **enum_metadata) +{ + FIXME("iface %p, enum_metadata %p stub.\n", iface, enum_metadata); + + return E_NOTIMPL; +} + +static HRESULT WINAPI GifEncoderFrame_Block_InitializeFromBlockReader(IWICMetadataBlockWriter *iface, + IWICMetadataBlockReader *block_reader) +{ + FIXME("iface %p, block_reader %p stub.\n", iface, block_reader); + + return E_NOTIMPL; +} + +static HRESULT WINAPI GifEncoderFrame_Block_GetWriterByIndex(IWICMetadataBlockWriter *iface, UINT index, + IWICMetadataWriter **metadata_writer) +{ + FIXME("iface %p, index %u, metadata_writer %p stub.\n", iface, index, metadata_writer); + + return E_NOTIMPL; +} + +static HRESULT WINAPI GifEncoderFrame_Block_AddWriter(IWICMetadataBlockWriter *iface, IWICMetadataWriter *metadata_writer) +{ + FIXME("iface %p, metadata_writer %p stub.\n", iface, metadata_writer); + + return E_NOTIMPL; +} + +static HRESULT WINAPI GifEncoderFrame_Block_SetWriterByIndex(IWICMetadataBlockWriter *iface, UINT index, + IWICMetadataWriter *metadata_writer) +{ + FIXME("iface %p, index %u, metadata_writer %p stub.\n", iface, index, metadata_writer); + + return E_NOTIMPL; +} + +static HRESULT WINAPI GifEncoderFrame_Block_RemoveWriterByIndex(IWICMetadataBlockWriter *iface, UINT index) +{ + FIXME("iface %p, index %u stub.\n", iface, index); + + return E_NOTIMPL; +} + +static const IWICMetadataBlockWriterVtbl GifFrameEncode_BlockVtbl = { + GifEncoderFrame_Block_QueryInterface, + GifEncoderFrame_Block_AddRef, + GifEncoderFrame_Block_Release, + GifEncoderFrame_Block_GetContainerFormat, + GifEncoderFrame_Block_GetCount, + GifEncoderFrame_Block_GetReaderByIndex, + GifEncoderFrame_Block_GetEnumerator, + GifEncoderFrame_Block_InitializeFromBlockReader, + GifEncoderFrame_Block_GetWriterByIndex, + GifEncoderFrame_Block_AddWriter, + GifEncoderFrame_Block_SetWriterByIndex, + GifEncoderFrame_Block_RemoveWriterByIndex, +}; + static HRESULT WINAPI GifEncoder_CreateNewFrame(IWICBitmapEncoder *iface, IWICBitmapFrameEncode **frame, IPropertyBag2 **options) { GifEncoder *This = impl_from_IWICBitmapEncoder(iface); @@ -2278,12 +2377,14 @@ static HRESULT WINAPI GifEncoder_CreateNewFrame(IWICBitmapEncoder *iface, IWICBi if (This->initialized && !This->committed) { - GifFrameEncode *ret = HeapAlloc(GetProcessHeap(), 0, sizeof(*ret)); + GifFrameEncode *ret = malloc(sizeof(*ret)); if (ret) { This->n_frames++; ret->IWICBitmapFrameEncode_iface.lpVtbl = &GifFrameEncode_Vtbl; + ret->IWICMetadataBlockWriter_iface.lpVtbl = &GifFrameEncode_BlockVtbl; + ret->ref = 1; ret->encoder = This; ret->initialized = FALSE; @@ -2381,13 +2482,17 @@ HRESULT GifEncoder_CreateInstance(REFIID iid, void **ppv) *ppv = NULL; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This)); + This = malloc(sizeof(*This)); if (!This) return E_OUTOFMEMORY; This->IWICBitmapEncoder_iface.lpVtbl = &GifEncoder_Vtbl; This->ref = 1; This->stream = NULL; +#ifdef __REACTOS__ InitializeCriticalSection(&This->lock); +#else + InitializeCriticalSectionEx(&This->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": GifEncoder.lock"); This->initialized = FALSE; This->info_written = FALSE; diff --git a/dll/win32/windowscodecs/icnsformat.c b/dll/win32/windowscodecs/icnsformat.c deleted file mode 100644 index 8194bc508a58d..0000000000000 --- a/dll/win32/windowscodecs/icnsformat.c +++ /dev/null @@ -1,743 +0,0 @@ -/* - * Copyright 2010 Damjan Jovanovic - * - * 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 "config.h" -#include "wine/port.h" - -#include - -#ifdef HAVE_APPLICATIONSERVICES_APPLICATIONSERVICES_H -#define GetCurrentProcess GetCurrentProcess_Mac -#define GetCurrentThread GetCurrentThread_Mac -#define LoadResource LoadResource_Mac -#define AnimatePalette AnimatePalette_Mac -#define EqualRgn EqualRgn_Mac -#define FillRgn FillRgn_Mac -#define FrameRgn FrameRgn_Mac -#define GetPixel GetPixel_Mac -#define InvertRgn InvertRgn_Mac -#define LineTo LineTo_Mac -#define OffsetRgn OffsetRgn_Mac -#define PaintRgn PaintRgn_Mac -#define Polygon Polygon_Mac -#define ResizePalette ResizePalette_Mac -#define SetRectRgn SetRectRgn_Mac -#define EqualRect EqualRect_Mac -#define FillRect FillRect_Mac -#define FrameRect FrameRect_Mac -#define GetCursor GetCursor_Mac -#define InvertRect InvertRect_Mac -#define OffsetRect OffsetRect_Mac -#define PtInRect PtInRect_Mac -#define SetCursor SetCursor_Mac -#define SetRect SetRect_Mac -#define ShowCursor ShowCursor_Mac -#define UnionRect UnionRect_Mac -#include -#undef GetCurrentProcess -#undef GetCurrentThread -#undef LoadResource -#undef AnimatePalette -#undef EqualRgn -#undef FillRgn -#undef FrameRgn -#undef GetPixel -#undef InvertRgn -#undef LineTo -#undef OffsetRgn -#undef PaintRgn -#undef Polygon -#undef ResizePalette -#undef SetRectRgn -#undef EqualRect -#undef FillRect -#undef FrameRect -#undef GetCursor -#undef InvertRect -#undef OffsetRect -#undef PtInRect -#undef SetCursor -#undef SetRect -#undef ShowCursor -#undef UnionRect -#endif - -#define COBJMACROS - -#include "windef.h" -#include "winbase.h" -#include "objbase.h" - -#include "wincodecs_private.h" - -#include "wine/debug.h" -#include "wine/library.h" - -WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); - -#if defined(HAVE_APPLICATIONSERVICES_APPLICATIONSERVICES_H) && \ - MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4 - -typedef struct IcnsEncoder { - IWICBitmapEncoder IWICBitmapEncoder_iface; - LONG ref; - IStream *stream; - IconFamilyHandle icns_family; - BOOL any_frame_committed; - int outstanding_commits; - BOOL committed; - CRITICAL_SECTION lock; -} IcnsEncoder; - -static inline IcnsEncoder *impl_from_IWICBitmapEncoder(IWICBitmapEncoder *iface) -{ - return CONTAINING_RECORD(iface, IcnsEncoder, IWICBitmapEncoder_iface); -} - -typedef struct IcnsFrameEncode { - IWICBitmapFrameEncode IWICBitmapFrameEncode_iface; - IcnsEncoder *encoder; - LONG ref; - BOOL initialized; - UINT size; - OSType icns_type; - BYTE* icns_image; - int lines_written; - BOOL committed; -} IcnsFrameEncode; - -static inline IcnsFrameEncode *impl_from_IWICBitmapFrameEncode(IWICBitmapFrameEncode *iface) -{ - return CONTAINING_RECORD(iface, IcnsFrameEncode, IWICBitmapFrameEncode_iface); -} - -static HRESULT WINAPI IcnsFrameEncode_QueryInterface(IWICBitmapFrameEncode *iface, REFIID iid, - void **ppv) -{ - IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); - - if (!ppv) return E_INVALIDARG; - - if (IsEqualIID(&IID_IUnknown, iid) || - IsEqualIID(&IID_IWICBitmapFrameEncode, iid)) - { - *ppv = &This->IWICBitmapFrameEncode_iface; - } - else - { - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI IcnsFrameEncode_AddRef(IWICBitmapFrameEncode *iface) -{ - IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - ULONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) refcount=%u\n", iface, ref); - - return ref; -} - -static ULONG WINAPI IcnsFrameEncode_Release(IWICBitmapFrameEncode *iface) -{ - IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - ULONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p) refcount=%u\n", iface, ref); - - if (ref == 0) - { - if (!This->committed) - { - EnterCriticalSection(&This->encoder->lock); - This->encoder->outstanding_commits--; - LeaveCriticalSection(&This->encoder->lock); - } - HeapFree(GetProcessHeap(), 0, This->icns_image); - - IWICBitmapEncoder_Release(&This->encoder->IWICBitmapEncoder_iface); - HeapFree(GetProcessHeap(), 0, This); - } - - return ref; -} - -static HRESULT WINAPI IcnsFrameEncode_Initialize(IWICBitmapFrameEncode *iface, - IPropertyBag2 *pIEncoderOptions) -{ - IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - HRESULT hr = S_OK; - - TRACE("(%p,%p)\n", iface, pIEncoderOptions); - - EnterCriticalSection(&This->encoder->lock); - - if (This->initialized) - { - hr = WINCODEC_ERR_WRONGSTATE; - goto end; - } - This->initialized = TRUE; - -end: - LeaveCriticalSection(&This->encoder->lock); - return hr; -} - -static HRESULT WINAPI IcnsFrameEncode_SetSize(IWICBitmapFrameEncode *iface, - UINT uiWidth, UINT uiHeight) -{ - IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - HRESULT hr = S_OK; - - TRACE("(%p,%u,%u)\n", iface, uiWidth, uiHeight); - - EnterCriticalSection(&This->encoder->lock); - - if (!This->initialized || This->icns_image) - { - hr = WINCODEC_ERR_WRONGSTATE; - goto end; - } - - if (uiWidth != uiHeight) - { - WARN("cannot generate ICNS icon from %dx%d image\n", uiWidth, uiHeight); - hr = E_INVALIDARG; - goto end; - } - - switch (uiWidth) - { - case 16: - case 32: - case 48: - case 128: - case 256: - case 512: - break; - default: - WARN("cannot generate ICNS icon from %dx%d image\n", This->size, This->size); - hr = E_INVALIDARG; - goto end; - } - - This->size = uiWidth; - -end: - LeaveCriticalSection(&This->encoder->lock); - return hr; -} - -static HRESULT WINAPI IcnsFrameEncode_SetResolution(IWICBitmapFrameEncode *iface, - double dpiX, double dpiY) -{ - IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - HRESULT hr = S_OK; - - TRACE("(%p,%0.2f,%0.2f)\n", iface, dpiX, dpiY); - - EnterCriticalSection(&This->encoder->lock); - - if (!This->initialized || This->icns_image) - { - hr = WINCODEC_ERR_WRONGSTATE; - goto end; - } - -end: - LeaveCriticalSection(&This->encoder->lock); - return S_OK; -} - -static HRESULT WINAPI IcnsFrameEncode_SetPixelFormat(IWICBitmapFrameEncode *iface, - WICPixelFormatGUID *pPixelFormat) -{ - IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - HRESULT hr = S_OK; - - TRACE("(%p,%s)\n", iface, debugstr_guid(pPixelFormat)); - - EnterCriticalSection(&This->encoder->lock); - - if (!This->initialized || This->icns_image) - { - hr = WINCODEC_ERR_WRONGSTATE; - goto end; - } - - memcpy(pPixelFormat, &GUID_WICPixelFormat32bppBGRA, sizeof(GUID)); - -end: - LeaveCriticalSection(&This->encoder->lock); - return S_OK; -} - -static HRESULT WINAPI IcnsFrameEncode_SetColorContexts(IWICBitmapFrameEncode *iface, - UINT cCount, IWICColorContext **ppIColorContext) -{ - FIXME("(%p,%u,%p): stub\n", iface, cCount, ppIColorContext); - return E_NOTIMPL; -} - -static HRESULT WINAPI IcnsFrameEncode_SetPalette(IWICBitmapFrameEncode *iface, - IWICPalette *pIPalette) -{ - FIXME("(%p,%p): stub\n", iface, pIPalette); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI IcnsFrameEncode_SetThumbnail(IWICBitmapFrameEncode *iface, - IWICBitmapSource *pIThumbnail) -{ - FIXME("(%p,%p): stub\n", iface, pIThumbnail); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI IcnsFrameEncode_WritePixels(IWICBitmapFrameEncode *iface, - UINT lineCount, UINT cbStride, UINT cbBufferSize, BYTE *pbPixels) -{ - IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - HRESULT hr = S_OK; - UINT i; - - TRACE("(%p,%u,%u,%u,%p)\n", iface, lineCount, cbStride, cbBufferSize, pbPixels); - - EnterCriticalSection(&This->encoder->lock); - - if (!This->initialized || !This->size) - { - hr = WINCODEC_ERR_WRONGSTATE; - goto end; - } - if (lineCount == 0 || lineCount + This->lines_written > This->size) - { - hr = E_INVALIDARG; - goto end; - } - - if (!This->icns_image) - { - switch (This->size) - { - case 16: This->icns_type = kIconServices16PixelDataARGB; break; - case 32: This->icns_type = kIconServices32PixelDataARGB; break; - case 48: This->icns_type = kIconServices48PixelDataARGB; break; - case 128: This->icns_type = kIconServices128PixelDataARGB; break; - case 256: This->icns_type = kIconServices256PixelDataARGB; break; - case 512: This->icns_type = kIconServices512PixelDataARGB; break; - default: - WARN("cannot generate ICNS icon from %dx%d image\n", This->size, This->size); - hr = E_INVALIDARG; - goto end; - } - This->icns_image = HeapAlloc(GetProcessHeap(), 0, This->size * This->size * 4); - if (!This->icns_image) - { - WARN("failed to allocate image buffer\n"); - hr = E_FAIL; - goto end; - } - } - - for (i = 0; i < lineCount; i++) - { - BYTE *src_row, *dst_row; - UINT j; - src_row = pbPixels + cbStride * i; - dst_row = This->icns_image + (This->lines_written + i)*(This->size*4); - /* swap bgr -> rgb */ - for (j = 0; j < This->size*4; j += 4) - { - dst_row[j] = src_row[j+3]; - dst_row[j+1] = src_row[j+2]; - dst_row[j+2] = src_row[j+1]; - dst_row[j+3] = src_row[j]; - } - } - This->lines_written += lineCount; - -end: - LeaveCriticalSection(&This->encoder->lock); - return hr; -} - -static HRESULT WINAPI IcnsFrameEncode_WriteSource(IWICBitmapFrameEncode *iface, - IWICBitmapSource *pIBitmapSource, WICRect *prc) -{ - IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - HRESULT hr; - - TRACE("(%p,%p,%s)\n", iface, pIBitmapSource, debug_wic_rect(prc)); - - if (!This->initialized) - return WINCODEC_ERR_WRONGSTATE; - - hr = configure_write_source(iface, pIBitmapSource, prc, - &GUID_WICPixelFormat32bppBGRA, This->size, This->size, - 1.0, 1.0); - - if (SUCCEEDED(hr)) - { - hr = write_source(iface, pIBitmapSource, prc, - &GUID_WICPixelFormat32bppBGRA, 32, This->size, This->size); - } - - return hr; -} - -static HRESULT WINAPI IcnsFrameEncode_Commit(IWICBitmapFrameEncode *iface) -{ - IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - Handle handle; - OSErr ret; - HRESULT hr = S_OK; - - TRACE("(%p)\n", iface); - - EnterCriticalSection(&This->encoder->lock); - - if (!This->icns_image || This->lines_written != This->size || This->committed) - { - hr = WINCODEC_ERR_WRONGSTATE; - goto end; - } - - ret = PtrToHand(This->icns_image, &handle, This->size * This->size * 4); - if (ret != noErr || !handle) - { - WARN("PtrToHand failed with error %d\n", ret); - hr = E_FAIL; - goto end; - } - - ret = SetIconFamilyData(This->encoder->icns_family, This->icns_type, handle); - DisposeHandle(handle); - - if (ret != noErr) - { - WARN("SetIconFamilyData failed for image with error %d\n", ret); - hr = E_FAIL; - goto end; - } - - This->committed = TRUE; - This->encoder->any_frame_committed = TRUE; - This->encoder->outstanding_commits--; - -end: - LeaveCriticalSection(&This->encoder->lock); - return hr; -} - -static HRESULT WINAPI IcnsFrameEncode_GetMetadataQueryWriter(IWICBitmapFrameEncode *iface, - IWICMetadataQueryWriter **ppIMetadataQueryWriter) -{ - FIXME("(%p, %p): stub\n", iface, ppIMetadataQueryWriter); - return E_NOTIMPL; -} - -static const IWICBitmapFrameEncodeVtbl IcnsEncoder_FrameVtbl = { - IcnsFrameEncode_QueryInterface, - IcnsFrameEncode_AddRef, - IcnsFrameEncode_Release, - IcnsFrameEncode_Initialize, - IcnsFrameEncode_SetSize, - IcnsFrameEncode_SetResolution, - IcnsFrameEncode_SetPixelFormat, - IcnsFrameEncode_SetColorContexts, - IcnsFrameEncode_SetPalette, - IcnsFrameEncode_SetThumbnail, - IcnsFrameEncode_WritePixels, - IcnsFrameEncode_WriteSource, - IcnsFrameEncode_Commit, - IcnsFrameEncode_GetMetadataQueryWriter -}; - -static HRESULT WINAPI IcnsEncoder_QueryInterface(IWICBitmapEncoder *iface, REFIID iid, - void **ppv) -{ - IcnsEncoder *This = impl_from_IWICBitmapEncoder(iface); - TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); - - if (!ppv) return E_INVALIDARG; - - if (IsEqualIID(&IID_IUnknown, iid) || - IsEqualIID(&IID_IWICBitmapEncoder, iid)) - { - *ppv = &This->IWICBitmapEncoder_iface; - } - else - { - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI IcnsEncoder_AddRef(IWICBitmapEncoder *iface) -{ - IcnsEncoder *This = impl_from_IWICBitmapEncoder(iface); - ULONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) refcount=%u\n", iface, ref); - - return ref; -} - -static ULONG WINAPI IcnsEncoder_Release(IWICBitmapEncoder *iface) -{ - IcnsEncoder *This = impl_from_IWICBitmapEncoder(iface); - ULONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p) refcount=%u\n", iface, ref); - - if (ref == 0) - { - This->lock.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&This->lock); - if (This->icns_family) - DisposeHandle((Handle)This->icns_family); - if (This->stream) - IStream_Release(This->stream); - HeapFree(GetProcessHeap(), 0, This); - } - - return ref; -} - -static HRESULT WINAPI IcnsEncoder_Initialize(IWICBitmapEncoder *iface, - IStream *pIStream, WICBitmapEncoderCacheOption cacheOption) -{ - IcnsEncoder *This = impl_from_IWICBitmapEncoder(iface); - HRESULT hr = S_OK; - - TRACE("(%p,%p,%u)\n", iface, pIStream, cacheOption); - - EnterCriticalSection(&This->lock); - - if (This->icns_family) - { - hr = WINCODEC_ERR_WRONGSTATE; - goto end; - } - This->icns_family = (IconFamilyHandle)NewHandle(0); - if (!This->icns_family) - { - WARN("error creating icns family\n"); - hr = E_FAIL; - goto end; - } - IStream_AddRef(pIStream); - This->stream = pIStream; - -end: - LeaveCriticalSection(&This->lock); - - return hr; -} - -static HRESULT WINAPI IcnsEncoder_GetContainerFormat(IWICBitmapEncoder *iface, - GUID *pguidContainerFormat) -{ - FIXME("(%p,%s): stub\n", iface, debugstr_guid(pguidContainerFormat)); - return E_NOTIMPL; -} - -static HRESULT WINAPI IcnsEncoder_GetEncoderInfo(IWICBitmapEncoder *iface, - IWICBitmapEncoderInfo **ppIEncoderInfo) -{ - FIXME("(%p,%p): stub\n", iface, ppIEncoderInfo); - return E_NOTIMPL; -} - -static HRESULT WINAPI IcnsEncoder_SetColorContexts(IWICBitmapEncoder *iface, - UINT cCount, IWICColorContext **ppIColorContext) -{ - FIXME("(%p,%u,%p): stub\n", iface, cCount, ppIColorContext); - return E_NOTIMPL; -} - -static HRESULT WINAPI IcnsEncoder_SetPalette(IWICBitmapEncoder *iface, IWICPalette *pIPalette) -{ - TRACE("(%p,%p)\n", iface, pIPalette); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI IcnsEncoder_SetThumbnail(IWICBitmapEncoder *iface, IWICBitmapSource *pIThumbnail) -{ - TRACE("(%p,%p)\n", iface, pIThumbnail); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI IcnsEncoder_SetPreview(IWICBitmapEncoder *iface, IWICBitmapSource *pIPreview) -{ - TRACE("(%p,%p)\n", iface, pIPreview); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI IcnsEncoder_CreateNewFrame(IWICBitmapEncoder *iface, - IWICBitmapFrameEncode **ppIFrameEncode, IPropertyBag2 **ppIEncoderOptions) -{ - IcnsEncoder *This = impl_from_IWICBitmapEncoder(iface); - HRESULT hr = S_OK; - IcnsFrameEncode *frameEncode = NULL; - - TRACE("(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions); - - EnterCriticalSection(&This->lock); - - if (!This->icns_family) - { - hr = WINCODEC_ERR_NOTINITIALIZED; - goto end; - } - - if (ppIEncoderOptions) - { - hr = CreatePropertyBag2(NULL, 0, ppIEncoderOptions); - if (FAILED(hr)) - goto end; - } - - frameEncode = HeapAlloc(GetProcessHeap(), 0, sizeof(IcnsFrameEncode)); - if (frameEncode == NULL) - { - hr = E_OUTOFMEMORY; - goto end; - } - frameEncode->IWICBitmapFrameEncode_iface.lpVtbl = &IcnsEncoder_FrameVtbl; - frameEncode->encoder = This; - frameEncode->ref = 1; - frameEncode->initialized = FALSE; - frameEncode->size = 0; - frameEncode->icns_image = NULL; - frameEncode->lines_written = 0; - frameEncode->committed = FALSE; - *ppIFrameEncode = &frameEncode->IWICBitmapFrameEncode_iface; - This->outstanding_commits++; - IWICBitmapEncoder_AddRef(&This->IWICBitmapEncoder_iface); - -end: - LeaveCriticalSection(&This->lock); - - return hr; -} - -static HRESULT WINAPI IcnsEncoder_Commit(IWICBitmapEncoder *iface) -{ - IcnsEncoder *This = impl_from_IWICBitmapEncoder(iface); - size_t buffer_size; - HRESULT hr = S_OK; - ULONG byteswritten; - - TRACE("(%p)\n", iface); - - EnterCriticalSection(&This->lock); - - if (!This->any_frame_committed || This->outstanding_commits > 0 || This->committed) - { - hr = WINCODEC_ERR_WRONGSTATE; - goto end; - } - - buffer_size = GetHandleSize((Handle)This->icns_family); - hr = IStream_Write(This->stream, *This->icns_family, buffer_size, &byteswritten); - if (FAILED(hr) || byteswritten != buffer_size) - { - WARN("writing file failed, hr = 0x%08X\n", hr); - hr = E_FAIL; - goto end; - } - - This->committed = TRUE; - -end: - LeaveCriticalSection(&This->lock); - return hr; -} - -static HRESULT WINAPI IcnsEncoder_GetMetadataQueryWriter(IWICBitmapEncoder *iface, - IWICMetadataQueryWriter **ppIMetadataQueryWriter) -{ - FIXME("(%p,%p): stub\n", iface, ppIMetadataQueryWriter); - return E_NOTIMPL; -} - -static const IWICBitmapEncoderVtbl IcnsEncoder_Vtbl = { - IcnsEncoder_QueryInterface, - IcnsEncoder_AddRef, - IcnsEncoder_Release, - IcnsEncoder_Initialize, - IcnsEncoder_GetContainerFormat, - IcnsEncoder_GetEncoderInfo, - IcnsEncoder_SetColorContexts, - IcnsEncoder_SetPalette, - IcnsEncoder_SetThumbnail, - IcnsEncoder_SetPreview, - IcnsEncoder_CreateNewFrame, - IcnsEncoder_Commit, - IcnsEncoder_GetMetadataQueryWriter -}; - -HRESULT IcnsEncoder_CreateInstance(REFIID iid, void** ppv) -{ - IcnsEncoder *This; - HRESULT ret; - - TRACE("(%s,%p)\n", debugstr_guid(iid), ppv); - - *ppv = NULL; - - This = HeapAlloc(GetProcessHeap(), 0, sizeof(IcnsEncoder)); - if (!This) return E_OUTOFMEMORY; - - This->IWICBitmapEncoder_iface.lpVtbl = &IcnsEncoder_Vtbl; - This->ref = 1; - This->stream = NULL; - This->icns_family = NULL; - This->any_frame_committed = FALSE; - This->outstanding_commits = 0; - This->committed = FALSE; - InitializeCriticalSection(&This->lock); - This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IcnsEncoder.lock"); - - ret = IWICBitmapEncoder_QueryInterface(&This->IWICBitmapEncoder_iface, iid, ppv); - IWICBitmapEncoder_Release(&This->IWICBitmapEncoder_iface); - - return ret; -} - -#else /* !defined(HAVE_APPLICATIONSERVICES_APPLICATIONSERVICES_H) || - MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4 */ - -HRESULT IcnsEncoder_CreateInstance(REFIID iid, void** ppv) -{ - ERR("Trying to save ICNS picture, but ICNS support is not compiled in.\n"); - return E_FAIL; -} - -#endif diff --git a/dll/win32/windowscodecs/icoformat.c b/dll/win32/windowscodecs/icoformat.c index d2a6196cd077b..f4f01dd176764 100644 --- a/dll/win32/windowscodecs/icoformat.c +++ b/dll/win32/windowscodecs/icoformat.c @@ -16,8 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" - #include #define COBJMACROS @@ -111,7 +109,7 @@ static ULONG WINAPI IcoFrameDecode_AddRef(IWICBitmapFrameDecode *iface) IcoFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -121,12 +119,12 @@ static ULONG WINAPI IcoFrameDecode_Release(IWICBitmapFrameDecode *iface) IcoFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { - HeapFree(GetProcessHeap(), 0, This->bits); - HeapFree(GetProcessHeap(), 0, This); + free(This->bits); + free(This); } return ref; @@ -249,7 +247,7 @@ static HRESULT ReadIcoDib(IStream *stream, IcoFrameDecode *result) if (SUCCEEDED(hr)) { - result->bits = HeapAlloc(GetProcessHeap(), 0, result->width * result->height * 4); + result->bits = malloc(result->width * result->height * 4); if (!result->bits) hr = E_OUTOFMEMORY; } @@ -338,7 +336,7 @@ static HRESULT ReadIcoDib(IStream *stream, IcoFrameDecode *result) if (SUCCEEDED(hr)) { - tempdata = HeapAlloc(GetProcessHeap(), 0, andBytes); + tempdata = malloc(andBytes); if (!tempdata) hr = E_OUTOFMEMORY; } @@ -378,7 +376,7 @@ static HRESULT ReadIcoDib(IStream *stream, IcoFrameDecode *result) } } - HeapFree(GetProcessHeap(), 0, tempdata); + free(tempdata); } } @@ -414,7 +412,7 @@ static HRESULT ReadIcoPng(IStream *stream, IcoFrameDecode *result) hr = IWICBitmapFrameDecode_GetResolution(sourceFrame, &result->dpiX, &result->dpiY); if (FAILED(hr)) goto end; - result->bits = HeapAlloc(GetProcessHeap(), 0, 4 * result->width * result->height); + result->bits = malloc(4 * result->width * result->height); if (result->bits == NULL) { hr = E_OUTOFMEMORY; @@ -465,7 +463,7 @@ static ULONG WINAPI IcoDecoder_AddRef(IWICBitmapDecoder *iface) IcoDecoder *This = impl_from_IWICBitmapDecoder(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -475,14 +473,14 @@ static ULONG WINAPI IcoDecoder_Release(IWICBitmapDecoder *iface) IcoDecoder *This = impl_from_IWICBitmapDecoder(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { This->lock.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&This->lock); if (This->stream) IStream_Release(This->stream); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; @@ -547,7 +545,7 @@ static HRESULT WINAPI IcoDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p hr = IStream_Stat(pIStream, &statstg, STATFLAG_NONAME); if (FAILED(hr)) { - WARN("Stat() failed, hr %#x.\n", hr); + WARN("Stat() failed, hr %#lx.\n", hr); goto end; } @@ -670,7 +668,7 @@ static HRESULT WINAPI IcoDecoder_GetFrame(IWICBitmapDecoder *iface, goto fail; } - result = HeapAlloc(GetProcessHeap(), 0, sizeof(IcoFrameDecode)); + result = malloc(sizeof(IcoFrameDecode)); if (!result) { hr = E_OUTOFMEMORY; @@ -716,7 +714,7 @@ static HRESULT WINAPI IcoDecoder_GetFrame(IWICBitmapDecoder *iface, hr = ReadIcoPng((IStream*)substream, result); break; default: - FIXME("Unrecognized ICO frame magic: %x\n", magic); + FIXME("Unrecognized ICO frame magic: %lx\n", magic); hr = E_FAIL; break; } @@ -732,10 +730,10 @@ static HRESULT WINAPI IcoDecoder_GetFrame(IWICBitmapDecoder *iface, fail: LeaveCriticalSection(&This->lock); - HeapFree(GetProcessHeap(), 0, result); + free(result); if (substream) IWICStream_Release(substream); if (SUCCEEDED(hr)) hr = E_FAIL; - TRACE("<-- %x\n", hr); + TRACE("<-- %lx\n", hr); return hr; } @@ -765,14 +763,18 @@ HRESULT IcoDecoder_CreateInstance(REFIID iid, void** ppv) *ppv = NULL; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(IcoDecoder)); + This = malloc(sizeof(IcoDecoder)); if (!This) return E_OUTOFMEMORY; This->IWICBitmapDecoder_iface.lpVtbl = &IcoDecoder_Vtbl; This->ref = 1; This->stream = NULL; This->initialized = FALSE; +#ifdef __REACTOS__ InitializeCriticalSection(&This->lock); +#else + InitializeCriticalSectionEx(&This->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IcoDecoder.lock"); ret = IWICBitmapDecoder_QueryInterface(&This->IWICBitmapDecoder_iface, iid, ppv); diff --git a/dll/win32/windowscodecs/imgfactory.c b/dll/win32/windowscodecs/imgfactory.c index e127e405570c5..84a46303c9504 100644 --- a/dll/win32/windowscodecs/imgfactory.c +++ b/dll/win32/windowscodecs/imgfactory.c @@ -17,8 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" - #include #include @@ -85,7 +83,7 @@ static ULONG WINAPI ImagingFactory_AddRef(IWICImagingFactory2 *iface) ImagingFactory *This = impl_from_IWICImagingFactory2(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -95,10 +93,10 @@ static ULONG WINAPI ImagingFactory_Release(IWICImagingFactory2 *iface) ImagingFactory *This = impl_from_IWICImagingFactory2(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) - HeapFree(GetProcessHeap(), 0, This); + free(This); return ref; } @@ -111,7 +109,7 @@ static HRESULT WINAPI ImagingFactory_CreateDecoderFromFilename( IWICStream *stream; HRESULT hr; - TRACE("(%p,%s,%s,%u,%u,%p)\n", iface, debugstr_w(wzFilename), + TRACE("(%p,%s,%s,%lu,%u,%p)\n", iface, debugstr_w(wzFilename), debugstr_guid(pguidVendor), dwDesiredAccess, metadataOptions, ppIDecoder); hr = StreamImpl_Create(&stream); @@ -134,76 +132,74 @@ static HRESULT WINAPI ImagingFactory_CreateDecoderFromFilename( static HRESULT find_decoder(IStream *pIStream, const GUID *pguidVendor, WICDecodeOptions metadataOptions, IWICBitmapDecoder **decoder) { - IEnumUnknown *enumdecoders; - IUnknown *unkdecoderinfo; - IWICBitmapDecoderInfo *decoderinfo; + IEnumUnknown *enumdecoders = NULL; + IUnknown *unkdecoderinfo = NULL; GUID vendor; - HRESULT res; + HRESULT res, res_wine; ULONG num_fetched; - BOOL matches; + BOOL matches, found; *decoder = NULL; res = CreateComponentEnumerator(WICDecoder, WICComponentEnumerateDefault, &enumdecoders); if (FAILED(res)) return res; - while (!*decoder) + found = FALSE; + while (IEnumUnknown_Next(enumdecoders, 1, &unkdecoderinfo, &num_fetched) == S_OK) { - res = IEnumUnknown_Next(enumdecoders, 1, &unkdecoderinfo, &num_fetched); - - if (res == S_OK) - { - res = IUnknown_QueryInterface(unkdecoderinfo, &IID_IWICBitmapDecoderInfo, (void**)&decoderinfo); + IWICBitmapDecoderInfo *decoderinfo = NULL; + IWICWineDecoder *wine_decoder = NULL; - if (SUCCEEDED(res)) - { - if (pguidVendor) - { - res = IWICBitmapDecoderInfo_GetVendorGUID(decoderinfo, &vendor); - if (FAILED(res) || !IsEqualIID(&vendor, pguidVendor)) - { - IWICBitmapDecoderInfo_Release(decoderinfo); - IUnknown_Release(unkdecoderinfo); - continue; - } - } + res = IUnknown_QueryInterface(unkdecoderinfo, &IID_IWICBitmapDecoderInfo, (void**)&decoderinfo); + if (FAILED(res)) goto next; - res = IWICBitmapDecoderInfo_MatchesPattern(decoderinfo, pIStream, &matches); + if (pguidVendor) + { + res = IWICBitmapDecoderInfo_GetVendorGUID(decoderinfo, &vendor); + if (FAILED(res) || !IsEqualIID(&vendor, pguidVendor)) goto next; + } - if (SUCCEEDED(res) && matches) - { - res = IWICBitmapDecoderInfo_CreateInstance(decoderinfo, decoder); + res = IWICBitmapDecoderInfo_MatchesPattern(decoderinfo, pIStream, &matches); + if (FAILED(res) || !matches) goto next; - /* FIXME: should use QueryCapability to choose a decoder */ + res = IWICBitmapDecoderInfo_CreateInstance(decoderinfo, decoder); + if (FAILED(res)) goto next; - if (SUCCEEDED(res)) - { - res = IWICBitmapDecoder_Initialize(*decoder, pIStream, metadataOptions); + /* FIXME: should use QueryCapability to choose a decoder */ - if (FAILED(res)) - { - IWICBitmapDecoder_Release(*decoder); - IWICBitmapDecoderInfo_Release(decoderinfo); - IUnknown_Release(unkdecoderinfo); - IEnumUnknown_Release(enumdecoders); - *decoder = NULL; - return res; - } - } - } + found = TRUE; + res = IWICBitmapDecoder_Initialize(*decoder, pIStream, metadataOptions); + if (FAILED(res)) + { + res_wine = IWICBitmapDecoder_QueryInterface(*decoder, &IID_IWICWineDecoder, (void **)&wine_decoder); + if (FAILED(res_wine)) + { + IWICBitmapDecoder_Release(*decoder); + *decoder = NULL; + goto next; + } - IWICBitmapDecoderInfo_Release(decoderinfo); + res_wine = IWICWineDecoder_Initialize(wine_decoder, pIStream, metadataOptions); + if (FAILED(res_wine)) + { + IWICBitmapDecoder_Release(*decoder); + *decoder = NULL; + goto next; } - IUnknown_Release(unkdecoderinfo); + res = res_wine; } - else - break; + + next: + if (wine_decoder) IWICWineDecoder_Release(wine_decoder); + if (decoderinfo) IWICBitmapDecoderInfo_Release(decoderinfo); + IUnknown_Release(unkdecoderinfo); + if (found) break; } IEnumUnknown_Release(enumdecoders); - - return WINCODEC_ERR_COMPONENTNOTFOUND; + if (!found) res = WINCODEC_ERR_COMPONENTNOTFOUND; + return res; } static HRESULT WINAPI ImagingFactory_CreateDecoderFromStream( @@ -234,13 +230,13 @@ static HRESULT WINAPI ImagingFactory_CreateDecoderFromStream( BYTE data[4]; ULONG bytesread; - WARN("failed to load from a stream %#x\n", res); + WARN("failed to load from a stream %#lx\n", res); seek.QuadPart = 0; if (IStream_Seek(pIStream, seek, STREAM_SEEK_SET, NULL) == S_OK) { if (IStream_Read(pIStream, data, 4, &bytesread) == S_OK) - WARN("first %i bytes of stream=%x %x %x %x\n", bytesread, data[0], data[1], data[2], data[3]); + WARN("first %li bytes of stream=%x %x %x %x\n", bytesread, data[0], data[1], data[2], data[3]); } } *ppIDecoder = NULL; @@ -255,7 +251,7 @@ static HRESULT WINAPI ImagingFactory_CreateDecoderFromFileHandle( IWICStream *stream; HRESULT hr; - TRACE("(%p,%lx,%s,%u,%p)\n", iface, hFile, debugstr_guid(pguidVendor), + TRACE("(%p,%Ix,%s,%u,%p)\n", iface, hFile, debugstr_guid(pguidVendor), metadataOptions, ppIDecoder); hr = StreamImpl_Create(&stream); @@ -713,7 +709,7 @@ static BOOL get_16bpp_format(HBITMAP hbm, WICPixelFormatGUID *format) } else { - FIXME("unrecognized bitfields %x,%x,%x\n", bmh.bV4RedMask, + FIXME("unrecognized bitfields %lx,%lx,%lx\n", bmh.bV4RedMask, bmh.bV4GreenMask, bmh.bV4BlueMask); ret = FALSE; } @@ -798,7 +794,11 @@ static HRESULT WINAPI ImagingFactory_CreateBitmapFromHBITMAP(IWICImagingFactory2 { BYTE *buffer; HDC hdc; +#ifdef __REACTOS__ char bmibuf[FIELD_OFFSET(BITMAPINFO, bmiColors) + 256 * sizeof(RGBQUAD)]; +#else + char bmibuf[FIELD_OFFSET(BITMAPINFO, bmiColors[256])]; +#endif BITMAPINFO *bmi = (BITMAPINFO *)bmibuf; IWICBitmapLock_GetDataPointer(lock, &size, &buffer); @@ -905,16 +905,14 @@ static HRESULT WINAPI ImagingFactory_CreateBitmapFromHICON(IWICImagingFactory2 * if (bm.bmBitsPixel == 32) { /* If any pixel has a non-zero alpha, ignore hbmMask */ - bits = (DWORD *)buffer; - for (x = 0; x < width && !has_alpha; x++, bits++) + DWORD *ptr = (DWORD *)buffer; + DWORD *end = ptr + width * height; + while (ptr != end) { - for (y = 0; y < height; y++) + if (*ptr++ & 0xff000000) { - if (*bits & 0xff000000) - { - has_alpha = TRUE; - break; - } + has_alpha = TRUE; + break; } } } @@ -930,7 +928,7 @@ static HRESULT WINAPI ImagingFactory_CreateBitmapFromHICON(IWICImagingFactory2 * { BYTE *mask; - mask = HeapAlloc(GetProcessHeap(), 0, size); + mask = malloc(size); if (!mask) { IWICBitmapLock_Release(lock); @@ -957,7 +955,7 @@ static HRESULT WINAPI ImagingFactory_CreateBitmapFromHICON(IWICImagingFactory2 * } } - HeapFree(GetProcessHeap(), 0, mask); + free(mask); } else { @@ -985,7 +983,7 @@ static HRESULT WINAPI ImagingFactory_CreateBitmapFromHICON(IWICImagingFactory2 * static HRESULT WINAPI ImagingFactory_CreateComponentEnumerator(IWICImagingFactory2 *iface, DWORD componentTypes, DWORD options, IEnumUnknown **ppIEnumUnknown) { - TRACE("(%p,%u,%u,%p)\n", iface, componentTypes, options, ppIEnumUnknown); + TRACE("(%p,%lu,%lu,%p)\n", iface, componentTypes, options, ppIEnumUnknown); return CreateComponentEnumerator(componentTypes, options, ppIEnumUnknown); } @@ -1254,146 +1252,280 @@ static HRESULT WINAPI ComponentFactory_CreateQueryWriterFromReader(IWICComponent return IWICImagingFactory2_CreateQueryWriterFromReader(&This->IWICImagingFactory2_iface, reader, vendor, writer); } -static HRESULT WINAPI ComponentFactory_CreateMetadataReader(IWICComponentFactory *iface, - REFGUID format, const GUID *vendor, DWORD options, IStream *stream, IWICMetadataReader **reader) +enum iterator_result { - FIXME("%p,%s,%s,%x,%p,%p: stub\n", iface, debugstr_guid(format), debugstr_guid(vendor), - options, stream, reader); - return E_NOTIMPL; -} + ITER_SKIP, + ITER_DONE, +}; -static HRESULT WINAPI ComponentFactory_CreateMetadataReaderFromContainer(IWICComponentFactory *iface, - REFGUID format, const GUID *vendor, DWORD options, IStream *stream, IWICMetadataReader **reader) +struct iterator_context { - HRESULT hr; - IEnumUnknown *enumreaders; - IUnknown *unkreaderinfo; + const GUID *format; + const GUID *vendor; + DWORD options; + IStream *stream; + + void **result; +}; + +typedef enum iterator_result (*iterator_func)(IUnknown *item, struct iterator_context *context); + +static enum iterator_result create_metadata_reader_from_container_iterator(IUnknown *item, + struct iterator_context *context) +{ + IWICPersistStream *persist_stream = NULL; IWICMetadataReaderInfo *readerinfo; - IWICPersistStream *wicpersiststream; - ULONG num_fetched; - GUID decoder_vendor; + IWICMetadataReader *reader = NULL; + LARGE_INTEGER zero = {{0}}; BOOL matches; - LARGE_INTEGER zero; - - TRACE("%p,%s,%s,%x,%p,%p\n", iface, debugstr_guid(format), debugstr_guid(vendor), - options, stream, reader); + HRESULT hr; + GUID guid; - if (!format || !stream || !reader) - return E_INVALIDARG; + if (FAILED(IUnknown_QueryInterface(item, &IID_IWICMetadataReaderInfo, (void **)&readerinfo))) + return ITER_SKIP; - zero.QuadPart = 0; + if (context->vendor) + { + hr = IWICMetadataReaderInfo_GetVendorGUID(readerinfo, &guid); - hr = CreateComponentEnumerator(WICMetadataReader, WICComponentEnumerateDefault, &enumreaders); - if (FAILED(hr)) return hr; + if (FAILED(hr) || !IsEqualIID(context->vendor, &guid)) + { + IWICMetadataReaderInfo_Release(readerinfo); + return ITER_SKIP; + } + } - *reader = NULL; + hr = IWICMetadataReaderInfo_MatchesPattern(readerinfo, context->format, context->stream, &matches); -start: - while (!*reader) + if (SUCCEEDED(hr) && matches) { - hr = IEnumUnknown_Next(enumreaders, 1, &unkreaderinfo, &num_fetched); + hr = IStream_Seek(context->stream, zero, STREAM_SEEK_SET, NULL); - if (hr == S_OK) - { - hr = IUnknown_QueryInterface(unkreaderinfo, &IID_IWICMetadataReaderInfo, (void**)&readerinfo); + if (SUCCEEDED(hr)) + hr = IWICMetadataReaderInfo_CreateInstance(readerinfo, &reader); - if (SUCCEEDED(hr)) - { - if (vendor) - { - hr = IWICMetadataReaderInfo_GetVendorGUID(readerinfo, &decoder_vendor); + if (SUCCEEDED(hr)) + hr = IWICMetadataReader_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist_stream); - if (FAILED(hr) || !IsEqualIID(vendor, &decoder_vendor)) - { - IWICMetadataReaderInfo_Release(readerinfo); - IUnknown_Release(unkreaderinfo); - continue; - } - } + if (SUCCEEDED(hr)) + hr = IWICPersistStream_LoadEx(persist_stream, context->stream, context->vendor, + context->options & WICPersistOptionMask); - hr = IWICMetadataReaderInfo_MatchesPattern(readerinfo, format, stream, &matches); + if (persist_stream) + IWICPersistStream_Release(persist_stream); - if (SUCCEEDED(hr) && matches) - { - hr = IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL); + if (SUCCEEDED(hr)) + { + *context->result = reader; + IWICMetadataReaderInfo_Release(readerinfo); + return ITER_DONE; + } - if (SUCCEEDED(hr)) - hr = IWICMetadataReaderInfo_CreateInstance(readerinfo, reader); + if (reader) + IWICMetadataReader_Release(reader); + } - if (SUCCEEDED(hr)) - { - hr = IWICMetadataReader_QueryInterface(*reader, &IID_IWICPersistStream, (void**)&wicpersiststream); + IWICMetadataReaderInfo_Release(readerinfo); - if (SUCCEEDED(hr)) - { - hr = IWICPersistStream_LoadEx(wicpersiststream, - stream, vendor, options & WICPersistOptionMask); + return ITER_SKIP; +} - IWICPersistStream_Release(wicpersiststream); - } +static enum iterator_result create_metadata_reader_iterator(IUnknown *item, + struct iterator_context *context) +{ + IWICPersistStream *persist_stream = NULL; + IWICMetadataReaderInfo *readerinfo; + IWICMetadataReader *reader = NULL; + LARGE_INTEGER zero = {{0}}; + HRESULT hr; + GUID guid; - if (FAILED(hr)) - { - IWICMetadataReader_Release(*reader); - *reader = NULL; - } - } - } + if (FAILED(IUnknown_QueryInterface(item, &IID_IWICMetadataReaderInfo, (void **)&readerinfo))) + return ITER_SKIP; - IUnknown_Release(readerinfo); - } + if (context->vendor) + { + hr = IWICMetadataReaderInfo_GetVendorGUID(readerinfo, &guid); - IUnknown_Release(unkreaderinfo); + if (FAILED(hr) || !IsEqualIID(context->vendor, &guid)) + { + IWICMetadataReaderInfo_Release(readerinfo); + return ITER_SKIP; } - else - break; } - if (!*reader && vendor) + hr = IWICMetadataReaderInfo_GetMetadataFormat(readerinfo, &guid); + + if (FAILED(hr) || !IsEqualIID(context->format, &guid)) { - vendor = NULL; - IEnumUnknown_Reset(enumreaders); - goto start; + IWICMetadataReaderInfo_Release(readerinfo); + return ITER_SKIP; } - IEnumUnknown_Release(enumreaders); + if (SUCCEEDED(hr)) + hr = IWICMetadataReaderInfo_CreateInstance(readerinfo, &reader); - if (!*reader && !(options & WICMetadataCreationFailUnknown)) + IWICMetadataReaderInfo_Release(readerinfo); + + if (context->stream) { - hr = IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL); + if (SUCCEEDED(hr)) + hr = IStream_Seek(context->stream, zero, STREAM_SEEK_SET, NULL); if (SUCCEEDED(hr)) - hr = UnknownMetadataReader_CreateInstance(&IID_IWICMetadataReader, (void**)reader); + hr = IWICMetadataReader_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist_stream); if (SUCCEEDED(hr)) - { - hr = IWICMetadataReader_QueryInterface(*reader, &IID_IWICPersistStream, (void**)&wicpersiststream); + hr = IWICPersistStream_LoadEx(persist_stream, context->stream, context->vendor, + context->options & WICPersistOptionMask); - if (SUCCEEDED(hr)) - { - hr = IWICPersistStream_LoadEx(wicpersiststream, stream, NULL, options & WICPersistOptionMask); + if (persist_stream) + IWICPersistStream_Release(persist_stream); + } - IWICPersistStream_Release(wicpersiststream); - } + if (SUCCEEDED(hr)) + { + *context->result = reader; + return ITER_DONE; + } - if (FAILED(hr)) - { - IWICMetadataReader_Release(*reader); - *reader = NULL; - } - } + if (reader) + IWICMetadataReader_Release(reader); + + return ITER_SKIP; +} + +static HRESULT foreach_component(DWORD mask, iterator_func func, struct iterator_context *context) +{ + enum iterator_result ret; + IEnumUnknown *enumerator; + IUnknown *item; + HRESULT hr; + + if (FAILED(hr = CreateComponentEnumerator(mask, WICComponentEnumerateDefault, &enumerator))) + return hr; + + while (IEnumUnknown_Next(enumerator, 1, &item, NULL) == S_OK) + { + *context->result = NULL; + + ret = func(item, context); + IUnknown_Release(item); + + if (ret == ITER_SKIP) + continue; + + break; } - if (*reader) - return S_OK; - else - return WINCODEC_ERR_COMPONENTNOTFOUND; + IEnumUnknown_Release(enumerator); + + return *context->result ? S_OK : WINCODEC_ERR_COMPONENTNOTFOUND; +} + +static HRESULT create_unknown_metadata_reader(IStream *stream, DWORD options, IWICMetadataReader **reader) +{ + IWICPersistStream *persist_stream = NULL; + LARGE_INTEGER zero = {{0}}; + HRESULT hr; + + hr = IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL); + + if (SUCCEEDED(hr)) + hr = UnknownMetadataReader_CreateInstance(&IID_IWICMetadataReader, (void **)reader); + + if (SUCCEEDED(hr)) + hr = IWICMetadataReader_QueryInterface(*reader, &IID_IWICPersistStream, (void **)&persist_stream); + + if (SUCCEEDED(hr)) + hr = IWICPersistStream_LoadEx(persist_stream, stream, NULL, options & WICPersistOptionMask); + + if (persist_stream) + IWICPersistStream_Release(persist_stream); + + if (FAILED(hr)) + { + IWICMetadataReader_Release(*reader); + *reader = NULL; + } + + return hr; +} + +static HRESULT WINAPI ComponentFactory_CreateMetadataReader(IWICComponentFactory *iface, + REFGUID format, const GUID *vendor, DWORD options, IStream *stream, IWICMetadataReader **reader) +{ + struct iterator_context context = { 0 }; + HRESULT hr; + + TRACE("%p,%s,%s,%lx,%p,%p\n", iface, debugstr_guid(format), debugstr_guid(vendor), + options, stream, reader); + + if (!format || !reader) + return E_INVALIDARG; + + context.format = format; + context.vendor = vendor; + context.options = options; + context.stream = stream; + context.result = (void **)reader; + + hr = foreach_component(WICMetadataReader, create_metadata_reader_iterator, &context); + + if (FAILED(hr) && vendor) + { + context.vendor = NULL; + hr = foreach_component(WICMetadataReader, create_metadata_reader_iterator, &context); + } + + if (FAILED(hr)) + WARN("Failed to create a metadata reader instance, hr %#lx.\n", hr); + + if (!*reader && !(options & WICMetadataCreationFailUnknown)) + hr = create_unknown_metadata_reader(stream, options, reader); + + return *reader ? S_OK : WINCODEC_ERR_COMPONENTNOTFOUND; +} + +static HRESULT WINAPI ComponentFactory_CreateMetadataReaderFromContainer(IWICComponentFactory *iface, + REFGUID format, const GUID *vendor, DWORD options, IStream *stream, IWICMetadataReader **reader) +{ + struct iterator_context context = { 0 }; + HRESULT hr; + + TRACE("%p,%s,%s,%lx,%p,%p\n", iface, debugstr_guid(format), debugstr_guid(vendor), + options, stream, reader); + + if (!format || !stream || !reader) + return E_INVALIDARG; + + context.format = format; + context.vendor = vendor; + context.options = options; + context.stream = stream; + context.result = (void **)reader; + + hr = foreach_component(WICMetadataReader, create_metadata_reader_from_container_iterator, &context); + + if (FAILED(hr) && vendor) + { + context.vendor = NULL; + hr = foreach_component(WICMetadataReader, create_metadata_reader_from_container_iterator, &context); + } + + if (FAILED(hr)) + WARN("Failed to create a metadata reader instance, hr %#lx.\n", hr); + + if (!*reader && !(options & WICMetadataCreationFailUnknown)) + hr = create_unknown_metadata_reader(stream, options, reader); + + return *reader ? S_OK : WINCODEC_ERR_COMPONENTNOTFOUND; } static HRESULT WINAPI ComponentFactory_CreateMetadataWriter(IWICComponentFactory *iface, REFGUID format, const GUID *vendor, DWORD options, IWICMetadataWriter **writer) { - FIXME("%p,%s,%s,%x,%p: stub\n", iface, debugstr_guid(format), debugstr_guid(vendor), options, writer); + FIXME("%p,%s,%s,%lx,%p: stub\n", iface, debugstr_guid(format), debugstr_guid(vendor), options, writer); return E_NOTIMPL; } @@ -1418,8 +1550,12 @@ static HRESULT WINAPI ComponentFactory_CreateQueryReaderFromBlockReader(IWICComp static HRESULT WINAPI ComponentFactory_CreateQueryWriterFromBlockWriter(IWICComponentFactory *iface, IWICMetadataBlockWriter *block_writer, IWICMetadataQueryWriter **query_writer) { - FIXME("%p,%p,%p: stub\n", iface, block_writer, query_writer); - return E_NOTIMPL; + TRACE("%p,%p,%p\n", iface, block_writer, query_writer); + + if (!block_writer || !query_writer) + return E_INVALIDARG; + + return MetadataQueryWriter_CreateInstance(block_writer, NULL, query_writer); } static HRESULT WINAPI ComponentFactory_CreateEncoderPropertyBag(IWICComponentFactory *iface, @@ -1476,7 +1612,7 @@ HRESULT ImagingFactory_CreateInstance(REFIID iid, void** ppv) *ppv = NULL; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This)); + This = malloc(sizeof(*This)); if (!This) return E_OUTOFMEMORY; This->IWICImagingFactory2_iface.lpVtbl = &ImagingFactory_Vtbl; diff --git a/dll/win32/windowscodecs/info.c b/dll/win32/windowscodecs/info.c index 8c8157445f9f6..db091dfc1e21a 100644 --- a/dll/win32/windowscodecs/info.c +++ b/dll/win32/windowscodecs/info.c @@ -17,8 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" - #include #define COBJMACROS @@ -31,33 +29,11 @@ #include "wincodecs_private.h" #include "wine/debug.h" -#include "wine/unicode.h" #include "wine/list.h" #include "wine/rbtree.h" -#include "wine/heap.h" WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); -static const WCHAR mimetypes_valuename[] = {'M','i','m','e','T','y','p','e','s',0}; -static const WCHAR author_valuename[] = {'A','u','t','h','o','r',0}; -static const WCHAR friendlyname_valuename[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0}; -static const WCHAR pixelformats_keyname[] = {'P','i','x','e','l','F','o','r','m','a','t','s',0}; -static const WCHAR formats_keyname[] = {'F','o','r','m','a','t','s',0}; -static const WCHAR containerformat_valuename[] = {'C','o','n','t','a','i','n','e','r','F','o','r','m','a','t',0}; -static const WCHAR metadataformat_valuename[] = {'M','e','t','a','d','a','t','a','F','o','r','m','a','t',0}; -static const WCHAR vendor_valuename[] = {'V','e','n','d','o','r',0}; -static const WCHAR version_valuename[] = {'V','e','r','s','i','o','n',0}; -static const WCHAR specversion_valuename[] = {'S','p','e','c','V','e','r','s','i','o','n',0}; -static const WCHAR bitsperpixel_valuename[] = {'B','i','t','L','e','n','g','t','h',0}; -static const WCHAR channelcount_valuename[] = {'C','h','a','n','n','e','l','C','o','u','n','t',0}; -static const WCHAR channelmasks_keyname[] = {'C','h','a','n','n','e','l','M','a','s','k','s',0}; -static const WCHAR numericrepresentation_valuename[] = {'N','u','m','e','r','i','c','R','e','p','r','e','s','e','n','t','a','t','i','o','n',0}; -static const WCHAR supportstransparency_valuename[] = {'S','u','p','p','o','r','t','s','T','r','a','n','s','p','a','r','e','n','c','y',0}; -static const WCHAR requiresfullstream_valuename[] = {'R','e','q','u','i','r','e','s','F','u','l','l','S','t','r','e','a','m',0}; -static const WCHAR supportspadding_valuename[] = {'S','u','p','p','o','r','t','s','P','a','d','d','i','n','g',0}; -static const WCHAR fileextensions_valuename[] = {'F','i','l','e','E','x','t','e','n','s','i','o','n','s',0}; -static const WCHAR containers_keyname[] = {'C','o','n','t','a','i','n','e','r','s',0}; - typedef struct { IWICComponentInfo IWICComponentInfo_iface; LONG ref; @@ -74,8 +50,7 @@ static HRESULT ComponentInfo_GetStringValue(HKEY classkey, LPCWSTR value, if (!actual_size) return E_INVALIDARG; - ret = RegGetValueW(classkey, NULL, value, RRF_RT_REG_SZ|RRF_NOEXPAND, NULL, - buffer, &cbdata); + ret = RegQueryValueExW(classkey, value, 0, NULL, (void *)buffer, &cbdata); if (ret == ERROR_FILE_NOT_FOUND) { @@ -124,8 +99,8 @@ static HRESULT ComponentInfo_GetGUIDValue(HKEY classkey, LPCWSTR value, return hr; } -static HRESULT ComponentInfo_GetDWORDValue(HKEY classkey, LPCWSTR value, - DWORD *result) +static HRESULT ComponentInfo_GetUINTValue(HKEY classkey, LPCWSTR value, + void *result) { LONG ret; DWORD cbdata = sizeof(DWORD); @@ -138,7 +113,7 @@ static HRESULT ComponentInfo_GetDWORDValue(HKEY classkey, LPCWSTR value, if (ret == ERROR_FILE_NOT_FOUND) { - *result = 0; + *(UINT *)result = 0; return S_OK; } @@ -202,7 +177,7 @@ static HRESULT ComponentInfo_GetGuidList(HKEY classkey, LPCWSTR subkeyname, } else { - ret = RegQueryInfoKeyW(subkey, NULL, NULL, NULL, actual_size, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + ret = RegQueryInfoKeyW(subkey, NULL, NULL, NULL, (DWORD *)actual_size, NULL, NULL, NULL, NULL, NULL, NULL, NULL); if (ret != ERROR_SUCCESS) hr = HRESULT_FROM_WIN32(ret); } @@ -255,7 +230,7 @@ static ULONG WINAPI BitmapDecoderInfo_AddRef(IWICBitmapDecoderInfo *iface) BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface); ULONG ref = InterlockedIncrement(&This->base.ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -265,13 +240,13 @@ static ULONG WINAPI BitmapDecoderInfo_Release(IWICBitmapDecoderInfo *iface) BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface); ULONG ref = InterlockedDecrement(&This->base.ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { RegCloseKey(This->classkey); - heap_free(This->patterns); - HeapFree(GetProcessHeap(), 0, This); + free(This->patterns); + free(This); } return ref; @@ -311,8 +286,7 @@ static HRESULT WINAPI BitmapDecoderInfo_GetAuthor(IWICBitmapDecoderInfo *iface, TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, author_valuename, - cchAuthor, wzAuthor, pcchActual); + return ComponentInfo_GetStringValue(This->classkey, L"Author", cchAuthor, wzAuthor, pcchActual); } static HRESULT WINAPI BitmapDecoderInfo_GetVendorGUID(IWICBitmapDecoderInfo *iface, GUID *pguidVendor) @@ -321,7 +295,7 @@ static HRESULT WINAPI BitmapDecoderInfo_GetVendorGUID(IWICBitmapDecoderInfo *ifa TRACE("(%p,%p)\n", iface, pguidVendor); - return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor); + return ComponentInfo_GetGUIDValue(This->classkey, L"Vendor", pguidVendor); } static HRESULT WINAPI BitmapDecoderInfo_GetVersion(IWICBitmapDecoderInfo *iface, UINT cchVersion, @@ -331,7 +305,7 @@ static HRESULT WINAPI BitmapDecoderInfo_GetVersion(IWICBitmapDecoderInfo *iface, TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, version_valuename, + return ComponentInfo_GetStringValue(This->classkey, L"Version", cchVersion, wzVersion, pcchActual); } @@ -342,7 +316,7 @@ static HRESULT WINAPI BitmapDecoderInfo_GetSpecVersion(IWICBitmapDecoderInfo *if TRACE("(%p,%u,%p,%p)\n", iface, cchSpecVersion, wzSpecVersion, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, specversion_valuename, + return ComponentInfo_GetStringValue(This->classkey, L"SpecVersion", cchSpecVersion, wzSpecVersion, pcchActual); } @@ -353,7 +327,7 @@ static HRESULT WINAPI BitmapDecoderInfo_GetFriendlyName(IWICBitmapDecoderInfo *i TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename, + return ComponentInfo_GetStringValue(This->classkey, L"FriendlyName", cchFriendlyName, wzFriendlyName, pcchActual); } @@ -362,7 +336,7 @@ static HRESULT WINAPI BitmapDecoderInfo_GetContainerFormat(IWICBitmapDecoderInfo { BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface); TRACE("(%p,%p)\n", iface, pguidContainerFormat); - return ComponentInfo_GetGUIDValue(This->classkey, containerformat_valuename, pguidContainerFormat); + return ComponentInfo_GetGUIDValue(This->classkey, L"ContainerFormat", pguidContainerFormat); } static HRESULT WINAPI BitmapDecoderInfo_GetPixelFormats(IWICBitmapDecoderInfo *iface, @@ -370,7 +344,7 @@ static HRESULT WINAPI BitmapDecoderInfo_GetPixelFormats(IWICBitmapDecoderInfo *i { BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface); TRACE("(%p,%u,%p,%p)\n", iface, cFormats, pguidPixelFormats, pcActual); - return ComponentInfo_GetGuidList(This->classkey, formats_keyname, cFormats, pguidPixelFormats, pcActual); + return ComponentInfo_GetGuidList(This->classkey, L"Formats", cFormats, pguidPixelFormats, pcActual); } static HRESULT WINAPI BitmapDecoderInfo_GetColorManagementVersion(IWICBitmapDecoderInfo *iface, @@ -401,7 +375,7 @@ static HRESULT WINAPI BitmapDecoderInfo_GetMimeTypes(IWICBitmapDecoderInfo *ifac TRACE("(%p,%u,%p,%p)\n", iface, cchMimeTypes, wzMimeTypes, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, mimetypes_valuename, + return ComponentInfo_GetStringValue(This->classkey, L"MimeTypes", cchMimeTypes, wzMimeTypes, pcchActual); } @@ -412,7 +386,7 @@ static HRESULT WINAPI BitmapDecoderInfo_GetFileExtensions(IWICBitmapDecoderInfo TRACE("(%p,%u,%p,%p)\n", iface, cchFileExtensions, wzFileExtensions, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, fileextensions_valuename, + return ComponentInfo_GetStringValue(This->classkey, L"FileExtensions", cchFileExtensions, wzFileExtensions, pcchActual); } @@ -489,9 +463,9 @@ static HRESULT WINAPI BitmapDecoderInfo_MatchesPattern(IWICBitmapDecoderInfo *if { if (datasize < This->patterns[i].Length) { - HeapFree(GetProcessHeap(), 0, data); + free(data); datasize = This->patterns[i].Length; - data = HeapAlloc(GetProcessHeap(), 0, This->patterns[i].Length); + data = malloc(This->patterns[i].Length); if (!data) { hr = E_OUTOFMEMORY; @@ -531,7 +505,7 @@ static HRESULT WINAPI BitmapDecoderInfo_MatchesPattern(IWICBitmapDecoderInfo *if *pfMatches = FALSE; } - HeapFree(GetProcessHeap(), 0, data); + free(data); return hr; } @@ -576,23 +550,17 @@ static const IWICBitmapDecoderInfoVtbl BitmapDecoderInfo_Vtbl = { static void read_bitmap_patterns(BitmapDecoderInfo *info) { - UINT pattern_count=0, patterns_size=0; + DWORD pattern_count=0; + UINT patterns_size=0; WCHAR subkeyname[11]; LONG res; HKEY patternskey, patternkey; - static const WCHAR uintformatW[] = {'%','u',0}; - static const WCHAR patternsW[] = {'P','a','t','t','e','r','n','s',0}; - static const WCHAR positionW[] = {'P','o','s','i','t','i','o','n',0}; - static const WCHAR lengthW[] = {'L','e','n','g','t','h',0}; - static const WCHAR patternW[] = {'P','a','t','t','e','r','n',0}; - static const WCHAR maskW[] = {'M','a','s','k',0}; - static const WCHAR endofstreamW[] = {'E','n','d','O','f','S','t','r','e','a','m',0}; UINT i; WICBitmapPattern *patterns; BYTE *patterns_ptr; DWORD length, valuesize; - res = RegOpenKeyExW(info->classkey, patternsW, 0, KEY_READ, &patternskey); + res = RegOpenKeyExW(info->classkey, L"Patterns", 0, KEY_READ, &patternskey); if (res != ERROR_SUCCESS) return; res = RegQueryInfoKeyW(patternskey, NULL, NULL, NULL, &pattern_count, NULL, NULL, NULL, NULL, NULL, NULL, NULL); @@ -603,7 +571,7 @@ static void read_bitmap_patterns(BitmapDecoderInfo *info) } patterns_size = pattern_count * sizeof(WICBitmapPattern); - patterns = heap_alloc(patterns_size); + patterns = malloc(patterns_size); if (!patterns) { RegCloseKey(patternskey); @@ -612,34 +580,34 @@ static void read_bitmap_patterns(BitmapDecoderInfo *info) for (i=0; res == ERROR_SUCCESS && i < pattern_count; i++) { - snprintfW(subkeyname, 11, uintformatW, i); + swprintf(subkeyname, 11, L"%u", i); res = RegOpenKeyExW(patternskey, subkeyname, 0, KEY_READ, &patternkey); if (res != ERROR_SUCCESS) break; valuesize = sizeof(ULONG); - res = RegGetValueW(patternkey, NULL, lengthW, RRF_RT_DWORD, NULL, &length, &valuesize); + res = RegGetValueW(patternkey, NULL, L"Length", RRF_RT_DWORD, NULL, &length, &valuesize); if (res == ERROR_SUCCESS) { patterns_size += length*2; patterns[i].Length = length; valuesize = sizeof(BOOL); - res = RegGetValueW(patternkey, NULL, endofstreamW, RRF_RT_DWORD, NULL, + res = RegGetValueW(patternkey, NULL, L"EndOfStream", RRF_RT_DWORD, NULL, &patterns[i].EndOfStream, &valuesize); if (res) patterns[i].EndOfStream = 0; patterns[i].Position.QuadPart = 0; valuesize = sizeof(ULARGE_INTEGER); - res = RegGetValueW(patternkey, NULL, positionW, RRF_RT_DWORD|RRF_RT_QWORD, NULL, + res = RegGetValueW(patternkey, NULL, L"Position", RRF_RT_DWORD|RRF_RT_QWORD, NULL, &patterns[i].Position, &valuesize); } RegCloseKey(patternkey); } - if (res != ERROR_SUCCESS || !(patterns_ptr = heap_realloc(patterns, patterns_size))) + if (res != ERROR_SUCCESS || !(patterns_ptr = realloc(patterns, patterns_size))) { - heap_free(patterns); + free(patterns); RegCloseKey(patternskey); return; } @@ -648,14 +616,14 @@ static void read_bitmap_patterns(BitmapDecoderInfo *info) for (i=0; res == ERROR_SUCCESS && i < pattern_count; i++) { - snprintfW(subkeyname, 11, uintformatW, i); + swprintf(subkeyname, 11, L"%u", i); res = RegOpenKeyExW(patternskey, subkeyname, 0, KEY_READ, &patternkey); if (res != ERROR_SUCCESS) break; length = patterns[i].Length; patterns[i].Pattern = patterns_ptr; valuesize = length; - res = RegGetValueW(patternkey, NULL, patternW, RRF_RT_REG_BINARY, NULL, + res = RegGetValueW(patternkey, NULL, L"Pattern", RRF_RT_REG_BINARY, NULL, patterns[i].Pattern, &valuesize); patterns_ptr += length; @@ -663,7 +631,7 @@ static void read_bitmap_patterns(BitmapDecoderInfo *info) { patterns[i].Mask = patterns_ptr; valuesize = length; - res = RegGetValueW(patternkey, NULL, maskW, RRF_RT_REG_BINARY, NULL, + res = RegGetValueW(patternkey, NULL, L"Mask", RRF_RT_REG_BINARY, NULL, patterns[i].Mask, &valuesize); patterns_ptr += length; } @@ -675,7 +643,7 @@ static void read_bitmap_patterns(BitmapDecoderInfo *info) if (res != ERROR_SUCCESS) { - heap_free(patterns); + free(patterns); return; } @@ -688,7 +656,7 @@ static HRESULT BitmapDecoderInfo_Constructor(HKEY classkey, REFCLSID clsid, Comp { BitmapDecoderInfo *This; - This = heap_alloc_zero(sizeof(BitmapDecoderInfo)); + This = calloc(1, sizeof(BitmapDecoderInfo)); if (!This) { RegCloseKey(classkey); @@ -746,7 +714,7 @@ static ULONG WINAPI BitmapEncoderInfo_AddRef(IWICBitmapEncoderInfo *iface) BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface); ULONG ref = InterlockedIncrement(&This->base.ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -756,12 +724,12 @@ static ULONG WINAPI BitmapEncoderInfo_Release(IWICBitmapEncoderInfo *iface) BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface); ULONG ref = InterlockedDecrement(&This->base.ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { RegCloseKey(This->classkey); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; @@ -801,8 +769,7 @@ static HRESULT WINAPI BitmapEncoderInfo_GetAuthor(IWICBitmapEncoderInfo *iface, TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, author_valuename, - cchAuthor, wzAuthor, pcchActual); + return ComponentInfo_GetStringValue(This->classkey, L"Author", cchAuthor, wzAuthor, pcchActual); } static HRESULT WINAPI BitmapEncoderInfo_GetVendorGUID(IWICBitmapEncoderInfo *iface, GUID *pguidVendor) @@ -811,7 +778,7 @@ static HRESULT WINAPI BitmapEncoderInfo_GetVendorGUID(IWICBitmapEncoderInfo *ifa TRACE("(%p,%p)\n", iface, pguidVendor); - return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor); + return ComponentInfo_GetGUIDValue(This->classkey, L"Vendor", pguidVendor); } static HRESULT WINAPI BitmapEncoderInfo_GetVersion(IWICBitmapEncoderInfo *iface, UINT cchVersion, @@ -821,7 +788,7 @@ static HRESULT WINAPI BitmapEncoderInfo_GetVersion(IWICBitmapEncoderInfo *iface, TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, version_valuename, + return ComponentInfo_GetStringValue(This->classkey, L"Version", cchVersion, wzVersion, pcchActual); } @@ -832,7 +799,7 @@ static HRESULT WINAPI BitmapEncoderInfo_GetSpecVersion(IWICBitmapEncoderInfo *if TRACE("(%p,%u,%p,%p)\n", iface, cchSpecVersion, wzSpecVersion, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, specversion_valuename, + return ComponentInfo_GetStringValue(This->classkey, L"SpecVersion", cchSpecVersion, wzSpecVersion, pcchActual); } @@ -843,7 +810,7 @@ static HRESULT WINAPI BitmapEncoderInfo_GetFriendlyName(IWICBitmapEncoderInfo *i TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename, + return ComponentInfo_GetStringValue(This->classkey, L"FriendlyName", cchFriendlyName, wzFriendlyName, pcchActual); } @@ -852,7 +819,7 @@ static HRESULT WINAPI BitmapEncoderInfo_GetContainerFormat(IWICBitmapEncoderInfo { BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface); TRACE("(%p,%p)\n", iface, pguidContainerFormat); - return ComponentInfo_GetGUIDValue(This->classkey, containerformat_valuename, pguidContainerFormat); + return ComponentInfo_GetGUIDValue(This->classkey, L"ContainerFormat", pguidContainerFormat); } static HRESULT WINAPI BitmapEncoderInfo_GetPixelFormats(IWICBitmapEncoderInfo *iface, @@ -860,7 +827,7 @@ static HRESULT WINAPI BitmapEncoderInfo_GetPixelFormats(IWICBitmapEncoderInfo *i { BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface); TRACE("(%p,%u,%p,%p)\n", iface, cFormats, pguidPixelFormats, pcActual); - return ComponentInfo_GetGuidList(This->classkey, formats_keyname, cFormats, pguidPixelFormats, pcActual); + return ComponentInfo_GetGuidList(This->classkey, L"Formats", cFormats, pguidPixelFormats, pcActual); } static HRESULT WINAPI BitmapEncoderInfo_GetColorManagementVersion(IWICBitmapEncoderInfo *iface, @@ -891,7 +858,7 @@ static HRESULT WINAPI BitmapEncoderInfo_GetMimeTypes(IWICBitmapEncoderInfo *ifac TRACE("(%p,%u,%p,%p)\n", iface, cchMimeTypes, wzMimeTypes, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, mimetypes_valuename, + return ComponentInfo_GetStringValue(This->classkey, L"MimeTypes", cchMimeTypes, wzMimeTypes, pcchActual); } @@ -902,7 +869,7 @@ static HRESULT WINAPI BitmapEncoderInfo_GetFileExtensions(IWICBitmapEncoderInfo TRACE("(%p,%u,%p,%p)\n", iface, cchFileExtensions, wzFileExtensions, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, fileextensions_valuename, + return ComponentInfo_GetStringValue(This->classkey, L"FileExtensions", cchFileExtensions, wzFileExtensions, pcchActual); } @@ -982,7 +949,7 @@ static HRESULT BitmapEncoderInfo_Constructor(HKEY classkey, REFCLSID clsid, Comp { BitmapEncoderInfo *This; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapEncoderInfo)); + This = malloc(sizeof(BitmapEncoderInfo)); if (!This) { RegCloseKey(classkey); @@ -1037,7 +1004,7 @@ static ULONG WINAPI FormatConverterInfo_AddRef(IWICFormatConverterInfo *iface) FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface); ULONG ref = InterlockedIncrement(&This->base.ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -1047,12 +1014,12 @@ static ULONG WINAPI FormatConverterInfo_Release(IWICFormatConverterInfo *iface) FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface); ULONG ref = InterlockedDecrement(&This->base.ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { RegCloseKey(This->classkey); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; @@ -1092,8 +1059,7 @@ static HRESULT WINAPI FormatConverterInfo_GetAuthor(IWICFormatConverterInfo *ifa TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, author_valuename, - cchAuthor, wzAuthor, pcchActual); + return ComponentInfo_GetStringValue(This->classkey, L"Author", cchAuthor, wzAuthor, pcchActual); } static HRESULT WINAPI FormatConverterInfo_GetVendorGUID(IWICFormatConverterInfo *iface, GUID *pguidVendor) @@ -1102,7 +1068,7 @@ static HRESULT WINAPI FormatConverterInfo_GetVendorGUID(IWICFormatConverterInfo TRACE("(%p,%p)\n", iface, pguidVendor); - return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor); + return ComponentInfo_GetGUIDValue(This->classkey, L"Vendor", pguidVendor); } static HRESULT WINAPI FormatConverterInfo_GetVersion(IWICFormatConverterInfo *iface, UINT cchVersion, @@ -1112,7 +1078,7 @@ static HRESULT WINAPI FormatConverterInfo_GetVersion(IWICFormatConverterInfo *if TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, version_valuename, + return ComponentInfo_GetStringValue(This->classkey, L"Version", cchVersion, wzVersion, pcchActual); } @@ -1123,7 +1089,7 @@ static HRESULT WINAPI FormatConverterInfo_GetSpecVersion(IWICFormatConverterInfo TRACE("(%p,%u,%p,%p)\n", iface, cchSpecVersion, wzSpecVersion, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, specversion_valuename, + return ComponentInfo_GetStringValue(This->classkey, L"SpecVersion", cchSpecVersion, wzSpecVersion, pcchActual); } @@ -1134,7 +1100,7 @@ static HRESULT WINAPI FormatConverterInfo_GetFriendlyName(IWICFormatConverterInf TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename, + return ComponentInfo_GetStringValue(This->classkey, L"FriendlyName", cchFriendlyName, wzFriendlyName, pcchActual); } @@ -1165,7 +1131,7 @@ static BOOL ConverterSupportsFormat(IWICFormatConverterInfo *iface, const WCHAR /* Avoid testing using IWICFormatConverter_GetPixelFormats because that would be O(n). A registry test should do better. */ - res = RegOpenKeyExW(This->classkey, pixelformats_keyname, 0, KEY_READ, &formats_key); + res = RegOpenKeyExW(This->classkey, L"PixelFormats", 0, KEY_READ, &formats_key); if (res != ERROR_SUCCESS) return FALSE; res = RegOpenKeyExW(formats_key, formatguid, 0, KEY_READ, &guid_key); @@ -1196,7 +1162,7 @@ static HRESULT FormatConverterInfo_Constructor(HKEY classkey, REFCLSID clsid, Co { FormatConverterInfo *This; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(FormatConverterInfo)); + This = malloc(sizeof(FormatConverterInfo)); if (!This) { RegCloseKey(classkey); @@ -1252,7 +1218,7 @@ static ULONG WINAPI PixelFormatInfo_AddRef(IWICPixelFormatInfo2 *iface) PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface); ULONG ref = InterlockedIncrement(&This->base.ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -1262,12 +1228,12 @@ static ULONG WINAPI PixelFormatInfo_Release(IWICPixelFormatInfo2 *iface) PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface); ULONG ref = InterlockedDecrement(&This->base.ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { RegCloseKey(This->classkey); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; @@ -1314,8 +1280,7 @@ static HRESULT WINAPI PixelFormatInfo_GetAuthor(IWICPixelFormatInfo2 *iface, UIN TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, author_valuename, - cchAuthor, wzAuthor, pcchActual); + return ComponentInfo_GetStringValue(This->classkey, L"Author", cchAuthor, wzAuthor, pcchActual); } static HRESULT WINAPI PixelFormatInfo_GetVendorGUID(IWICPixelFormatInfo2 *iface, GUID *pguidVendor) @@ -1324,7 +1289,7 @@ static HRESULT WINAPI PixelFormatInfo_GetVendorGUID(IWICPixelFormatInfo2 *iface, TRACE("(%p,%p)\n", iface, pguidVendor); - return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor); + return ComponentInfo_GetGUIDValue(This->classkey, L"Vendor", pguidVendor); } static HRESULT WINAPI PixelFormatInfo_GetVersion(IWICPixelFormatInfo2 *iface, UINT cchVersion, @@ -1334,7 +1299,7 @@ static HRESULT WINAPI PixelFormatInfo_GetVersion(IWICPixelFormatInfo2 *iface, UI TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, version_valuename, + return ComponentInfo_GetStringValue(This->classkey, L"Version", cchVersion, wzVersion, pcchActual); } @@ -1345,7 +1310,7 @@ static HRESULT WINAPI PixelFormatInfo_GetSpecVersion(IWICPixelFormatInfo2 *iface TRACE("(%p,%u,%p,%p)\n", iface, cchSpecVersion, wzSpecVersion, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, specversion_valuename, + return ComponentInfo_GetStringValue(This->classkey, L"SpecVersion", cchSpecVersion, wzSpecVersion, pcchActual); } @@ -1356,7 +1321,7 @@ static HRESULT WINAPI PixelFormatInfo_GetFriendlyName(IWICPixelFormatInfo2 *ifac TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename, + return ComponentInfo_GetStringValue(This->classkey, L"FriendlyName", cchFriendlyName, wzFriendlyName, pcchActual); } @@ -1387,7 +1352,7 @@ static HRESULT WINAPI PixelFormatInfo_GetBitsPerPixel(IWICPixelFormatInfo2 *ifac TRACE("(%p,%p)\n", iface, puiBitsPerPixel); - return ComponentInfo_GetDWORDValue(This->classkey, bitsperpixel_valuename, puiBitsPerPixel); + return ComponentInfo_GetUINTValue(This->classkey, L"BitLength", puiBitsPerPixel); } static HRESULT WINAPI PixelFormatInfo_GetChannelCount(IWICPixelFormatInfo2 *iface, @@ -1397,13 +1362,12 @@ static HRESULT WINAPI PixelFormatInfo_GetChannelCount(IWICPixelFormatInfo2 *ifac TRACE("(%p,%p)\n", iface, puiChannelCount); - return ComponentInfo_GetDWORDValue(This->classkey, channelcount_valuename, puiChannelCount); + return ComponentInfo_GetUINTValue(This->classkey, L"ChannelCount", puiChannelCount); } static HRESULT WINAPI PixelFormatInfo_GetChannelMask(IWICPixelFormatInfo2 *iface, UINT uiChannelIndex, UINT cbMaskBuffer, BYTE *pbMaskBuffer, UINT *pcbActual) { - static const WCHAR uintformatW[] = {'%','u',0}; PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface); UINT channel_count; HRESULT hr; @@ -1423,11 +1387,11 @@ static HRESULT WINAPI PixelFormatInfo_GetChannelMask(IWICPixelFormatInfo2 *iface if (SUCCEEDED(hr)) { - snprintfW(valuename, 11, uintformatW, uiChannelIndex); + swprintf(valuename, 11, L"%u", uiChannelIndex); cbData = cbMaskBuffer; - ret = RegGetValueW(This->classkey, channelmasks_keyname, valuename, RRF_RT_REG_BINARY, NULL, pbMaskBuffer, &cbData); + ret = RegGetValueW(This->classkey, L"ChannelMasks", valuename, RRF_RT_REG_BINARY, NULL, pbMaskBuffer, &cbData); if (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA) *pcbActual = cbData; @@ -1448,7 +1412,7 @@ static HRESULT WINAPI PixelFormatInfo_SupportsTransparency(IWICPixelFormatInfo2 TRACE("(%p,%p)\n", iface, pfSupportsTransparency); - return ComponentInfo_GetDWORDValue(This->classkey, supportstransparency_valuename, (DWORD*)pfSupportsTransparency); + return ComponentInfo_GetUINTValue(This->classkey, L"SupportsTransparency", pfSupportsTransparency); } static HRESULT WINAPI PixelFormatInfo_GetNumericRepresentation(IWICPixelFormatInfo2 *iface, @@ -1458,7 +1422,7 @@ static HRESULT WINAPI PixelFormatInfo_GetNumericRepresentation(IWICPixelFormatIn TRACE("(%p,%p)\n", iface, pNumericRepresentation); - return ComponentInfo_GetDWORDValue(This->classkey, numericrepresentation_valuename, pNumericRepresentation); + return ComponentInfo_GetUINTValue(This->classkey, L"NumericRepresentation", pNumericRepresentation); } static const IWICPixelFormatInfo2Vtbl PixelFormatInfo_Vtbl = { @@ -1486,7 +1450,7 @@ static HRESULT PixelFormatInfo_Constructor(HKEY classkey, REFCLSID clsid, Compon { PixelFormatInfo *This; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(PixelFormatInfo)); + This = malloc(sizeof(PixelFormatInfo)); if (!This) { RegCloseKey(classkey); @@ -1565,7 +1529,7 @@ static ULONG WINAPI MetadataReaderInfo_AddRef(IWICMetadataReaderInfo *iface) MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface); ULONG ref = InterlockedIncrement(&This->base.ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -1574,17 +1538,17 @@ static ULONG WINAPI MetadataReaderInfo_Release(IWICMetadataReaderInfo *iface) MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface); ULONG ref = InterlockedDecrement(&This->base.ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (!ref) { unsigned i; RegCloseKey(This->classkey); for (i = 0; i < This->container_count; i++) - heap_free(This->containers[i].patterns); - heap_free(This->containers); - heap_free(This->container_formats); - HeapFree(GetProcessHeap(), 0, This); + free(This->containers[i].patterns); + free(This->containers); + free(This->container_formats); + free(This); } return ref; } @@ -1625,8 +1589,7 @@ static HRESULT WINAPI MetadataReaderInfo_GetAuthor(IWICMetadataReaderInfo *iface TRACE("(%p,%u,%p,%p)\n", iface, length, author, actual_length); - return ComponentInfo_GetStringValue(This->classkey, author_valuename, - length, author, actual_length); + return ComponentInfo_GetStringValue(This->classkey, L"Author", length, author, actual_length); } static HRESULT WINAPI MetadataReaderInfo_GetVendorGUID(IWICMetadataReaderInfo *iface, @@ -1636,7 +1599,7 @@ static HRESULT WINAPI MetadataReaderInfo_GetVendorGUID(IWICMetadataReaderInfo *i TRACE("(%p,%p)\n", iface, vendor); - return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, vendor); + return ComponentInfo_GetGUIDValue(This->classkey, L"Vendor", vendor); } static HRESULT WINAPI MetadataReaderInfo_GetVersion(IWICMetadataReaderInfo *iface, @@ -1646,8 +1609,7 @@ static HRESULT WINAPI MetadataReaderInfo_GetVersion(IWICMetadataReaderInfo *ifac TRACE("(%p,%u,%p,%p)\n", iface, length, version, actual_length); - return ComponentInfo_GetStringValue(This->classkey, version_valuename, - length, version, actual_length); + return ComponentInfo_GetStringValue(This->classkey, L"Version", length, version, actual_length); } static HRESULT WINAPI MetadataReaderInfo_GetSpecVersion(IWICMetadataReaderInfo *iface, @@ -1657,7 +1619,7 @@ static HRESULT WINAPI MetadataReaderInfo_GetSpecVersion(IWICMetadataReaderInfo * TRACE("(%p,%u,%p,%p)\n", iface, length, version, actual_length); - return ComponentInfo_GetStringValue(This->classkey, specversion_valuename, + return ComponentInfo_GetStringValue(This->classkey, L"SpecVersion", length, version, actual_length); } @@ -1668,7 +1630,7 @@ static HRESULT WINAPI MetadataReaderInfo_GetFriendlyName(IWICMetadataReaderInfo TRACE("(%p,%u,%p,%p)\n", iface, length, name, actual_length); - return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename, + return ComponentInfo_GetStringValue(This->classkey, L"FriendlyName", length, name, actual_length); } @@ -1677,7 +1639,7 @@ static HRESULT WINAPI MetadataReaderInfo_GetMetadataFormat(IWICMetadataReaderInf { MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface); TRACE("(%p,%p)\n", iface, format); - return ComponentInfo_GetGUIDValue(This->classkey, metadataformat_valuename, format); + return ComponentInfo_GetGUIDValue(This->classkey, L"MetadataFormat", format); } static HRESULT WINAPI MetadataReaderInfo_GetContainerFormats(IWICMetadataReaderInfo *iface, @@ -1695,7 +1657,7 @@ static HRESULT WINAPI MetadataReaderInfo_GetContainerFormats(IWICMetadataReaderI { if (This->container_count && length < This->container_count) return WINCODEC_ERR_INSUFFICIENTBUFFER; - memcpy(formats, This->container_formats, This->container_count); + memcpy(formats, This->container_formats, This->container_count * sizeof(*formats)); } return S_OK; } @@ -1719,7 +1681,7 @@ static HRESULT WINAPI MetadataReaderInfo_DoesRequireFullStream(IWICMetadataReade { MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface); TRACE("(%p,%p)\n", iface, param); - return ComponentInfo_GetDWORDValue(This->classkey, requiresfullstream_valuename, (DWORD *)param); + return ComponentInfo_GetUINTValue(This->classkey, L"RequiresFullStream", param); } static HRESULT WINAPI MetadataReaderInfo_DoesSupportPadding(IWICMetadataReaderInfo *iface, @@ -1727,7 +1689,7 @@ static HRESULT WINAPI MetadataReaderInfo_DoesSupportPadding(IWICMetadataReaderIn { MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface); TRACE("(%p,%p)\n", iface, param); - return ComponentInfo_GetDWORDValue(This->classkey, supportspadding_valuename, (DWORD *)param); + return ComponentInfo_GetUINTValue(This->classkey, L"SupportsPadding", param); } static HRESULT WINAPI MetadataReaderInfo_DoesRequireFixedSize(IWICMetadataReaderInfo *iface, @@ -1783,9 +1745,9 @@ static HRESULT WINAPI MetadataReaderInfo_MatchesPattern(IWICMetadataReaderInfo * { if (datasize < container->patterns[i].Length) { - HeapFree(GetProcessHeap(), 0, data); + free(data); datasize = container->patterns[i].Length; - data = HeapAlloc(GetProcessHeap(), 0, container->patterns[i].Length); + data = malloc(container->patterns[i].Length); if (!data) { hr = E_OUTOFMEMORY; @@ -1821,7 +1783,7 @@ static HRESULT WINAPI MetadataReaderInfo_MatchesPattern(IWICMetadataReaderInfo * *matches = FALSE; } - HeapFree(GetProcessHeap(), 0, data); + free(data); return hr; } @@ -1863,21 +1825,17 @@ static const IWICMetadataReaderInfoVtbl MetadataReaderInfo_Vtbl = { static void read_metadata_patterns(MetadataReaderInfo *info, GUID *container_guid, struct metadata_container *container) { - UINT pattern_count=0, patterns_size=0; + DWORD pattern_count=0; + UINT patterns_size=0; WCHAR subkeyname[11], guidkeyname[39]; LONG res; HKEY containers_key, guid_key, patternkey; - static const WCHAR uintformatW[] = {'%','u',0}; - static const WCHAR patternW[] = {'P','a','t','t','e','r','n',0}; - static const WCHAR positionW[] = {'P','o','s','i','t','i','o','n',0}; - static const WCHAR maskW[] = {'M','a','s','k',0}; - static const WCHAR dataoffsetW[] = {'D','a','t','a','O','f','f','s','e','t',0}; UINT i; WICMetadataPattern *patterns; BYTE *patterns_ptr; DWORD length, valuesize; - res = RegOpenKeyExW(info->classkey, containers_keyname, 0, KEY_READ, &containers_key); + res = RegOpenKeyExW(info->classkey, L"Containers", 0, KEY_READ, &containers_key); if (res != ERROR_SUCCESS) return; StringFromGUID2(container_guid, guidkeyname, 39); @@ -1894,7 +1852,7 @@ static void read_metadata_patterns(MetadataReaderInfo *info, GUID *container_gui } patterns_size = pattern_count * sizeof(WICMetadataPattern); - patterns = heap_alloc(patterns_size); + patterns = malloc(patterns_size); if (!patterns) { RegCloseKey(guid_key); @@ -1903,33 +1861,33 @@ static void read_metadata_patterns(MetadataReaderInfo *info, GUID *container_gui for (i=0; res == ERROR_SUCCESS && i < pattern_count; i++) { - snprintfW(subkeyname, 11, uintformatW, i); + swprintf(subkeyname, 11, L"%u", i); res = RegOpenKeyExW(guid_key, subkeyname, 0, KEY_READ, &patternkey); if (res != ERROR_SUCCESS) break; - res = RegGetValueW(patternkey, NULL, patternW, RRF_RT_REG_BINARY, NULL, NULL, &length); + res = RegGetValueW(patternkey, NULL, L"Pattern", RRF_RT_REG_BINARY, NULL, NULL, &length); if (res == ERROR_SUCCESS) { patterns_size += length*2; patterns[i].Length = length; valuesize = sizeof(DWORD64); - res = RegGetValueW(patternkey, NULL, dataoffsetW, RRF_RT_DWORD|RRF_RT_QWORD, NULL, + res = RegGetValueW(patternkey, NULL, L"DataOffset", RRF_RT_DWORD|RRF_RT_QWORD, NULL, &patterns[i].DataOffset, &valuesize); if (res) patterns[i].DataOffset.QuadPart = 0; patterns[i].Position.QuadPart = 0; valuesize = sizeof(DWORD64); - res = RegGetValueW(patternkey, NULL, positionW, RRF_RT_DWORD|RRF_RT_QWORD, NULL, + res = RegGetValueW(patternkey, NULL, L"Position", RRF_RT_DWORD|RRF_RT_QWORD, NULL, &patterns[i].Position, &valuesize); } RegCloseKey(patternkey); } - if (res != ERROR_SUCCESS || !(patterns_ptr = heap_realloc(patterns, patterns_size))) + if (res != ERROR_SUCCESS || !(patterns_ptr = realloc(patterns, patterns_size))) { - heap_free(patterns); + free(patterns); RegCloseKey(guid_key); return; } @@ -1938,14 +1896,14 @@ static void read_metadata_patterns(MetadataReaderInfo *info, GUID *container_gui for (i=0; res == ERROR_SUCCESS && i < pattern_count; i++) { - snprintfW(subkeyname, 11, uintformatW, i); + swprintf(subkeyname, 11, L"%u", i); res = RegOpenKeyExW(guid_key, subkeyname, 0, KEY_READ, &patternkey); if (res != ERROR_SUCCESS) break; length = patterns[i].Length; patterns[i].Pattern = patterns_ptr; valuesize = length; - res = RegGetValueW(patternkey, NULL, patternW, RRF_RT_REG_BINARY, NULL, + res = RegGetValueW(patternkey, NULL, L"Pattern", RRF_RT_REG_BINARY, NULL, patterns[i].Pattern, &valuesize); patterns_ptr += length; @@ -1953,7 +1911,7 @@ static void read_metadata_patterns(MetadataReaderInfo *info, GUID *container_gui { patterns[i].Mask = patterns_ptr; valuesize = length; - res = RegGetValueW(patternkey, NULL, maskW, RRF_RT_REG_BINARY, NULL, + res = RegGetValueW(patternkey, NULL, L"Mask", RRF_RT_REG_BINARY, NULL, patterns[i].Mask, &valuesize); patterns_ptr += length; } @@ -1965,7 +1923,7 @@ static void read_metadata_patterns(MetadataReaderInfo *info, GUID *container_gui if (res != ERROR_SUCCESS) { - heap_free(patterns); + free(patterns); return; } @@ -1980,17 +1938,17 @@ static BOOL read_metadata_info(MetadataReaderInfo *info) GUID *formats; HRESULT hr; - hr = ComponentInfo_GetGuidList(info->classkey, containers_keyname, 0, NULL, &format_count); + hr = ComponentInfo_GetGuidList(info->classkey, L"Containers", 0, NULL, &format_count); if (FAILED(hr)) return TRUE; - formats = heap_calloc(format_count, sizeof(*formats)); + formats = calloc(format_count, sizeof(*formats)); if (!formats) return FALSE; - hr = ComponentInfo_GetGuidList(info->classkey, containers_keyname, format_count, formats, + hr = ComponentInfo_GetGuidList(info->classkey, L"Containers", format_count, formats, &format_count); if (FAILED(hr)) { - heap_free(formats); + free(formats); return FALSE; } @@ -2001,7 +1959,7 @@ static BOOL read_metadata_info(MetadataReaderInfo *info) { unsigned i; - info->containers = heap_calloc(format_count, sizeof(*info->containers)); + info->containers = calloc(format_count, sizeof(*info->containers)); if (!info->containers) return FALSE; for (i = 0; i < format_count; i++) @@ -2015,7 +1973,7 @@ static HRESULT MetadataReaderInfo_Constructor(HKEY classkey, REFCLSID clsid, Com { MetadataReaderInfo *This; - This = heap_alloc_zero(sizeof(*This)); + This = calloc(1, sizeof(*This)); if (!This) { RegCloseKey(classkey); @@ -2037,9 +1995,6 @@ static HRESULT MetadataReaderInfo_Constructor(HKEY classkey, REFCLSID clsid, Com return S_OK; } -static const WCHAR clsid_keyname[] = {'C','L','S','I','D',0}; -static const WCHAR instance_keyname[] = {'I','n','s','t','a','n','c','e',0}; - struct category { WICComponentType type; const GUID *catid; @@ -2097,7 +2052,7 @@ HRESULT CreateComponentInfo(REFCLSID clsid, IWICComponentInfo **ppIInfo) return S_OK; } - res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, KEY_READ, &clsidkey); + res = RegOpenKeyExW(HKEY_CLASSES_ROOT, L"CLSID", 0, KEY_READ, &clsidkey); if (res != ERROR_SUCCESS) { LeaveCriticalSection(&component_info_cache_cs); @@ -2110,7 +2065,7 @@ HRESULT CreateComponentInfo(REFCLSID clsid, IWICComponentInfo **ppIInfo) res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &catidkey); if (res == ERROR_SUCCESS) { - res = RegOpenKeyExW(catidkey, instance_keyname, 0, KEY_READ, &instancekey); + res = RegOpenKeyExW(catidkey, L"Instance", 0, KEY_READ, &instancekey); if (res == ERROR_SUCCESS) { StringFromGUID2(clsid, guidstring, 39); @@ -2223,7 +2178,7 @@ static ULONG WINAPI ComponentEnum_AddRef(IEnumUnknown *iface) ComponentEnum *This = impl_from_IEnumUnknown(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -2234,7 +2189,7 @@ static ULONG WINAPI ComponentEnum_Release(IEnumUnknown *iface) ULONG ref = InterlockedDecrement(&This->ref); ComponentEnumItem *cursor, *cursor2; - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { @@ -2242,11 +2197,11 @@ static ULONG WINAPI ComponentEnum_Release(IEnumUnknown *iface) { IUnknown_Release(cursor->unk); list_remove(&cursor->entry); - HeapFree(GetProcessHeap(), 0, cursor); + free(cursor); } This->lock.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&This->lock); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; @@ -2260,7 +2215,7 @@ static HRESULT WINAPI ComponentEnum_Next(IEnumUnknown *iface, ULONG celt, ComponentEnumItem *item; HRESULT hr=S_OK; - TRACE("(%p,%u,%p,%p)\n", iface, celt, rgelt, pceltFetched); + TRACE("(%p,%lu,%p,%p)\n", iface, celt, rgelt, pceltFetched); EnterCriticalSection(&This->lock); while (num_fetchedlock); for (i=0; iref = 1; new_enum->cursor = NULL; list_init(&new_enum->objects); +#ifdef __REACTOS__ InitializeCriticalSection(&new_enum->lock); +#else + InitializeCriticalSectionEx(&new_enum->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif new_enum->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ComponentEnum.lock"); EnterCriticalSection(&This->lock); @@ -2344,7 +2303,7 @@ static HRESULT WINAPI ComponentEnum_Clone(IEnumUnknown *iface, IEnumUnknown **pp LIST_FOR_EACH_ENTRY(old_item, &This->objects, ComponentEnumItem, entry) { - new_item = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnumItem)); + new_item = malloc(sizeof(ComponentEnumItem)); if (!new_item) { ret = E_OUTOFMEMORY; @@ -2389,13 +2348,13 @@ HRESULT CreateComponentEnumerator(DWORD componentTypes, DWORD options, IEnumUnkn HRESULT hr=S_OK; CLSID clsid; - if (options) FIXME("ignoring flags %x\n", options); + if (options) FIXME("ignoring flags %lx\n", options); - res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, KEY_READ, &clsidkey); + res = RegOpenKeyExW(HKEY_CLASSES_ROOT, L"CLSID", 0, KEY_READ, &clsidkey); if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res); - This = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnum)); + This = malloc(sizeof(ComponentEnum)); if (!This) { RegCloseKey(clsidkey); @@ -2405,7 +2364,11 @@ HRESULT CreateComponentEnumerator(DWORD componentTypes, DWORD options, IEnumUnkn This->IEnumUnknown_iface.lpVtbl = &ComponentEnumVtbl; This->ref = 1; list_init(&This->objects); +#ifdef __REACTOS__ InitializeCriticalSection(&This->lock); +#else + InitializeCriticalSectionEx(&This->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ComponentEnum.lock"); for (category=categories; category->type && hr == S_OK; category++) @@ -2415,7 +2378,7 @@ HRESULT CreateComponentEnumerator(DWORD componentTypes, DWORD options, IEnumUnkn res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &catidkey); if (res == ERROR_SUCCESS) { - res = RegOpenKeyExW(catidkey, instance_keyname, 0, KEY_READ, &instancekey); + res = RegOpenKeyExW(catidkey, L"Instance", 0, KEY_READ, &instancekey); if (res == ERROR_SUCCESS) { i=0; @@ -2425,7 +2388,7 @@ HRESULT CreateComponentEnumerator(DWORD componentTypes, DWORD options, IEnumUnkn res = RegEnumKeyExW(instancekey, i, guidstring, &guidstring_size, NULL, NULL, NULL, NULL); if (res != ERROR_SUCCESS) break; - item = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnumItem)); + item = malloc(sizeof(ComponentEnumItem)); if (!item) { hr = E_OUTOFMEMORY; break; } hr = CLSIDFromString(guidstring, &clsid); @@ -2438,7 +2401,7 @@ HRESULT CreateComponentEnumerator(DWORD componentTypes, DWORD options, IEnumUnkn if (FAILED(hr)) { - HeapFree(GetProcessHeap(), 0, item); + free(item); hr = S_OK; } } diff --git a/dll/win32/windowscodecs/jpegformat.c b/dll/win32/windowscodecs/jpegformat.c deleted file mode 100644 index 1df898f28c702..0000000000000 --- a/dll/win32/windowscodecs/jpegformat.c +++ /dev/null @@ -1,1562 +0,0 @@ -/* - * Copyright 2009 Vincent Povirk 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 "config.h" -#include "wine/port.h" - -#ifdef HAVE_UNISTD_H -# include -#endif -#include -#include -#include -#include - -#ifdef SONAME_LIBJPEG -/* This is a hack, so jpeglib.h does not redefine INT32 and the like*/ -#define XMD_H -#define UINT8 JPEG_UINT8 -#define UINT16 JPEG_UINT16 -#define boolean jpeg_boolean -#undef HAVE_STDLIB_H -# include -#undef HAVE_STDLIB_H -#define HAVE_STDLIB_H 1 -#undef UINT8 -#undef UINT16 -#undef boolean -#endif - -#define COBJMACROS - -#include "windef.h" -#include "winbase.h" -#include "objbase.h" - -#include "wincodecs_private.h" - -#include "wine/heap.h" -#include "wine/debug.h" -#include "wine/library.h" - -WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); - -#ifdef SONAME_LIBJPEG -WINE_DECLARE_DEBUG_CHANNEL(jpeg); - -static void *libjpeg_handle; - -static const WCHAR wszImageQuality[] = {'I','m','a','g','e','Q','u','a','l','i','t','y',0}; -static const WCHAR wszBitmapTransform[] = {'B','i','t','m','a','p','T','r','a','n','s','f','o','r','m',0}; -static const WCHAR wszLuminance[] = {'L','u','m','i','n','a','n','c','e',0}; -static const WCHAR wszChrominance[] = {'C','h','r','o','m','i','n','a','n','c','e',0}; -static const WCHAR wszJpegYCrCbSubsampling[] = {'J','p','e','g','Y','C','r','C','b','S','u','b','s','a','m','p','l','i','n','g',0}; -static const WCHAR wszSuppressApp0[] = {'S','u','p','p','r','e','s','s','A','p','p','0',0}; - -#define MAKE_FUNCPTR(f) static typeof(f) * p##f -MAKE_FUNCPTR(jpeg_CreateCompress); -MAKE_FUNCPTR(jpeg_CreateDecompress); -MAKE_FUNCPTR(jpeg_destroy_compress); -MAKE_FUNCPTR(jpeg_destroy_decompress); -MAKE_FUNCPTR(jpeg_finish_compress); -MAKE_FUNCPTR(jpeg_read_header); -MAKE_FUNCPTR(jpeg_read_scanlines); -MAKE_FUNCPTR(jpeg_resync_to_restart); -MAKE_FUNCPTR(jpeg_set_defaults); -MAKE_FUNCPTR(jpeg_start_compress); -MAKE_FUNCPTR(jpeg_start_decompress); -MAKE_FUNCPTR(jpeg_std_error); -MAKE_FUNCPTR(jpeg_write_scanlines); -#undef MAKE_FUNCPTR - -static void *load_libjpeg(void) -{ - if((libjpeg_handle = wine_dlopen(SONAME_LIBJPEG, RTLD_NOW, NULL, 0)) != NULL) { - -#define LOAD_FUNCPTR(f) \ - if((p##f = wine_dlsym(libjpeg_handle, #f, NULL, 0)) == NULL) { \ - libjpeg_handle = NULL; \ - return NULL; \ - } - - LOAD_FUNCPTR(jpeg_CreateCompress); - LOAD_FUNCPTR(jpeg_CreateDecompress); - LOAD_FUNCPTR(jpeg_destroy_compress); - LOAD_FUNCPTR(jpeg_destroy_decompress); - LOAD_FUNCPTR(jpeg_finish_compress); - LOAD_FUNCPTR(jpeg_read_header); - LOAD_FUNCPTR(jpeg_read_scanlines); - LOAD_FUNCPTR(jpeg_resync_to_restart); - LOAD_FUNCPTR(jpeg_set_defaults); - LOAD_FUNCPTR(jpeg_start_compress); - LOAD_FUNCPTR(jpeg_start_decompress); - LOAD_FUNCPTR(jpeg_std_error); - LOAD_FUNCPTR(jpeg_write_scanlines); -#undef LOAD_FUNCPTR - } - return libjpeg_handle; -} - -static void error_exit_fn(j_common_ptr cinfo) -{ - char message[JMSG_LENGTH_MAX]; - if (ERR_ON(jpeg)) - { - cinfo->err->format_message(cinfo, message); - ERR_(jpeg)("%s\n", message); - } - longjmp(*(jmp_buf*)cinfo->client_data, 1); -} - -static void emit_message_fn(j_common_ptr cinfo, int msg_level) -{ - char message[JMSG_LENGTH_MAX]; - - if (msg_level < 0 && ERR_ON(jpeg)) - { - cinfo->err->format_message(cinfo, message); - ERR_(jpeg)("%s\n", message); - } - else if (msg_level == 0 && WARN_ON(jpeg)) - { - cinfo->err->format_message(cinfo, message); - WARN_(jpeg)("%s\n", message); - } - else if (msg_level > 0 && TRACE_ON(jpeg)) - { - cinfo->err->format_message(cinfo, message); - TRACE_(jpeg)("%s\n", message); - } -} - -typedef struct { - IWICBitmapDecoder IWICBitmapDecoder_iface; - IWICBitmapFrameDecode IWICBitmapFrameDecode_iface; - IWICMetadataBlockReader IWICMetadataBlockReader_iface; - LONG ref; - BOOL initialized; - BOOL cinfo_initialized; - IStream *stream; - struct jpeg_decompress_struct cinfo; - struct jpeg_error_mgr jerr; - struct jpeg_source_mgr source_mgr; - BYTE source_buffer[1024]; - UINT bpp, stride; - BYTE *image_data; - CRITICAL_SECTION lock; -} JpegDecoder; - -static inline JpegDecoder *impl_from_IWICBitmapDecoder(IWICBitmapDecoder *iface) -{ - return CONTAINING_RECORD(iface, JpegDecoder, IWICBitmapDecoder_iface); -} - -static inline JpegDecoder *impl_from_IWICBitmapFrameDecode(IWICBitmapFrameDecode *iface) -{ - return CONTAINING_RECORD(iface, JpegDecoder, IWICBitmapFrameDecode_iface); -} - -static inline JpegDecoder *decoder_from_decompress(j_decompress_ptr decompress) -{ - return CONTAINING_RECORD(decompress, JpegDecoder, cinfo); -} - -static inline JpegDecoder *impl_from_IWICMetadataBlockReader(IWICMetadataBlockReader *iface) -{ - return CONTAINING_RECORD(iface, JpegDecoder, IWICMetadataBlockReader_iface); -} - -static HRESULT WINAPI JpegDecoder_QueryInterface(IWICBitmapDecoder *iface, REFIID iid, - void **ppv) -{ - JpegDecoder *This = impl_from_IWICBitmapDecoder(iface); - TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); - - if (!ppv) return E_INVALIDARG; - - if (IsEqualIID(&IID_IUnknown, iid) || - IsEqualIID(&IID_IWICBitmapDecoder, iid)) - { - *ppv = &This->IWICBitmapDecoder_iface; - } - else - { - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI JpegDecoder_AddRef(IWICBitmapDecoder *iface) -{ - JpegDecoder *This = impl_from_IWICBitmapDecoder(iface); - ULONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) refcount=%u\n", iface, ref); - - return ref; -} - -static ULONG WINAPI JpegDecoder_Release(IWICBitmapDecoder *iface) -{ - JpegDecoder *This = impl_from_IWICBitmapDecoder(iface); - ULONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p) refcount=%u\n", iface, ref); - - if (ref == 0) - { - This->lock.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&This->lock); - if (This->cinfo_initialized) pjpeg_destroy_decompress(&This->cinfo); - if (This->stream) IStream_Release(This->stream); - HeapFree(GetProcessHeap(), 0, This->image_data); - HeapFree(GetProcessHeap(), 0, This); - } - - return ref; -} - -static HRESULT WINAPI JpegDecoder_QueryCapability(IWICBitmapDecoder *iface, IStream *stream, - DWORD *capability) -{ - HRESULT hr; - - TRACE("(%p,%p,%p)\n", iface, stream, capability); - - if (!stream || !capability) return E_INVALIDARG; - - hr = IWICBitmapDecoder_Initialize(iface, stream, WICDecodeMetadataCacheOnDemand); - if (hr != S_OK) return hr; - - *capability = WICBitmapDecoderCapabilityCanDecodeAllImages | - WICBitmapDecoderCapabilityCanDecodeSomeImages; - /* FIXME: WICBitmapDecoderCapabilityCanEnumerateMetadata */ - return S_OK; -} - -static void source_mgr_init_source(j_decompress_ptr cinfo) -{ -} - -static jpeg_boolean source_mgr_fill_input_buffer(j_decompress_ptr cinfo) -{ - JpegDecoder *This = decoder_from_decompress(cinfo); - HRESULT hr; - ULONG bytesread; - - hr = IStream_Read(This->stream, This->source_buffer, 1024, &bytesread); - - if (FAILED(hr) || bytesread == 0) - { - return FALSE; - } - else - { - This->source_mgr.next_input_byte = This->source_buffer; - This->source_mgr.bytes_in_buffer = bytesread; - return TRUE; - } -} - -static void source_mgr_skip_input_data(j_decompress_ptr cinfo, long num_bytes) -{ - JpegDecoder *This = decoder_from_decompress(cinfo); - LARGE_INTEGER seek; - - if (num_bytes > This->source_mgr.bytes_in_buffer) - { - seek.QuadPart = num_bytes - This->source_mgr.bytes_in_buffer; - IStream_Seek(This->stream, seek, STREAM_SEEK_CUR, NULL); - This->source_mgr.bytes_in_buffer = 0; - } - else if (num_bytes > 0) - { - This->source_mgr.next_input_byte += num_bytes; - This->source_mgr.bytes_in_buffer -= num_bytes; - } -} - -static void source_mgr_term_source(j_decompress_ptr cinfo) -{ -} - -static HRESULT WINAPI JpegDecoder_Initialize(IWICBitmapDecoder *iface, IStream *pIStream, - WICDecodeOptions cacheOptions) -{ - JpegDecoder *This = impl_from_IWICBitmapDecoder(iface); - int ret; - LARGE_INTEGER seek; - jmp_buf jmpbuf; - UINT data_size, i; - - TRACE("(%p,%p,%u)\n", iface, pIStream, cacheOptions); - - EnterCriticalSection(&This->lock); - - if (This->cinfo_initialized) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - pjpeg_std_error(&This->jerr); - - This->jerr.error_exit = error_exit_fn; - This->jerr.emit_message = emit_message_fn; - - This->cinfo.err = &This->jerr; - - This->cinfo.client_data = jmpbuf; - - if (setjmp(jmpbuf)) - { - LeaveCriticalSection(&This->lock); - return E_FAIL; - } - - pjpeg_CreateDecompress(&This->cinfo, JPEG_LIB_VERSION, sizeof(struct jpeg_decompress_struct)); - - This->cinfo_initialized = TRUE; - - This->stream = pIStream; - IStream_AddRef(pIStream); - - seek.QuadPart = 0; - IStream_Seek(This->stream, seek, STREAM_SEEK_SET, NULL); - - This->source_mgr.bytes_in_buffer = 0; - This->source_mgr.init_source = source_mgr_init_source; - This->source_mgr.fill_input_buffer = source_mgr_fill_input_buffer; - This->source_mgr.skip_input_data = source_mgr_skip_input_data; - This->source_mgr.resync_to_restart = pjpeg_resync_to_restart; - This->source_mgr.term_source = source_mgr_term_source; - - This->cinfo.src = &This->source_mgr; - - ret = pjpeg_read_header(&This->cinfo, TRUE); - - if (ret != JPEG_HEADER_OK) { - WARN("Jpeg image in stream has bad format, read header returned %d.\n",ret); - LeaveCriticalSection(&This->lock); - return E_FAIL; - } - - switch (This->cinfo.jpeg_color_space) - { - case JCS_GRAYSCALE: - This->cinfo.out_color_space = JCS_GRAYSCALE; - break; - case JCS_RGB: - case JCS_YCbCr: - This->cinfo.out_color_space = JCS_RGB; - break; - case JCS_CMYK: - case JCS_YCCK: - This->cinfo.out_color_space = JCS_CMYK; - break; - default: - ERR("Unknown JPEG color space %i\n", This->cinfo.jpeg_color_space); - LeaveCriticalSection(&This->lock); - return E_FAIL; - } - - if (!pjpeg_start_decompress(&This->cinfo)) - { - ERR("jpeg_start_decompress failed\n"); - LeaveCriticalSection(&This->lock); - return E_FAIL; - } - - if (This->cinfo.out_color_space == JCS_GRAYSCALE) This->bpp = 8; - else if (This->cinfo.out_color_space == JCS_CMYK) This->bpp = 32; - else This->bpp = 24; - - This->stride = (This->bpp * This->cinfo.output_width + 7) / 8; - data_size = This->stride * This->cinfo.output_height; - - This->image_data = heap_alloc(data_size); - if (!This->image_data) - { - LeaveCriticalSection(&This->lock); - return E_OUTOFMEMORY; - } - - while (This->cinfo.output_scanline < This->cinfo.output_height) - { - UINT first_scanline = This->cinfo.output_scanline; - UINT max_rows; - JSAMPROW out_rows[4]; - JDIMENSION ret; - - max_rows = min(This->cinfo.output_height-first_scanline, 4); - for (i=0; iimage_data + This->stride * (first_scanline+i); - - ret = pjpeg_read_scanlines(&This->cinfo, out_rows, max_rows); - if (ret == 0) - { - ERR("read_scanlines failed\n"); - LeaveCriticalSection(&This->lock); - return E_FAIL; - } - } - - if (This->bpp == 24) - { - /* libjpeg gives us RGB data and we want BGR, so byteswap the data */ - reverse_bgr8(3, This->image_data, - This->cinfo.output_width, This->cinfo.output_height, - This->stride); - } - - if (This->cinfo.out_color_space == JCS_CMYK && This->cinfo.saw_Adobe_marker) - { - /* Adobe JPEG's have inverted CMYK data. */ - for (i=0; iimage_data[i] ^= 0xff; - } - - This->initialized = TRUE; - - LeaveCriticalSection(&This->lock); - - return S_OK; -} - -static HRESULT WINAPI JpegDecoder_GetContainerFormat(IWICBitmapDecoder *iface, - GUID *pguidContainerFormat) -{ - memcpy(pguidContainerFormat, &GUID_ContainerFormatJpeg, sizeof(GUID)); - return S_OK; -} - -static HRESULT WINAPI JpegDecoder_GetDecoderInfo(IWICBitmapDecoder *iface, - IWICBitmapDecoderInfo **ppIDecoderInfo) -{ - TRACE("(%p,%p)\n", iface, ppIDecoderInfo); - - return get_decoder_info(&CLSID_WICJpegDecoder, ppIDecoderInfo); -} - -static HRESULT WINAPI JpegDecoder_CopyPalette(IWICBitmapDecoder *iface, - IWICPalette *pIPalette) -{ - TRACE("(%p,%p)\n", iface, pIPalette); - - return WINCODEC_ERR_PALETTEUNAVAILABLE; -} - -static HRESULT WINAPI JpegDecoder_GetMetadataQueryReader(IWICBitmapDecoder *iface, - IWICMetadataQueryReader **reader) -{ - TRACE("(%p,%p)\n", iface, reader); - - if (!reader) return E_INVALIDARG; - - *reader = NULL; - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI JpegDecoder_GetPreview(IWICBitmapDecoder *iface, - IWICBitmapSource **ppIBitmapSource) -{ - FIXME("(%p,%p): stub\n", iface, ppIBitmapSource); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI JpegDecoder_GetColorContexts(IWICBitmapDecoder *iface, - UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount) -{ - FIXME("(%p,%u,%p,%p): stub\n", iface, cCount, ppIColorContexts, pcActualCount); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI JpegDecoder_GetThumbnail(IWICBitmapDecoder *iface, - IWICBitmapSource **ppIThumbnail) -{ - FIXME("(%p,%p): stub\n", iface, ppIThumbnail); - return WINCODEC_ERR_CODECNOTHUMBNAIL; -} - -static HRESULT WINAPI JpegDecoder_GetFrameCount(IWICBitmapDecoder *iface, - UINT *pCount) -{ - if (!pCount) return E_INVALIDARG; - - *pCount = 1; - return S_OK; -} - -static HRESULT WINAPI JpegDecoder_GetFrame(IWICBitmapDecoder *iface, - UINT index, IWICBitmapFrameDecode **ppIBitmapFrame) -{ - JpegDecoder *This = impl_from_IWICBitmapDecoder(iface); - TRACE("(%p,%u,%p)\n", iface, index, ppIBitmapFrame); - - if (!This->initialized) return WINCODEC_ERR_FRAMEMISSING; - - if (index != 0) return E_INVALIDARG; - - IWICBitmapDecoder_AddRef(iface); - *ppIBitmapFrame = &This->IWICBitmapFrameDecode_iface; - - return S_OK; -} - -static const IWICBitmapDecoderVtbl JpegDecoder_Vtbl = { - JpegDecoder_QueryInterface, - JpegDecoder_AddRef, - JpegDecoder_Release, - JpegDecoder_QueryCapability, - JpegDecoder_Initialize, - JpegDecoder_GetContainerFormat, - JpegDecoder_GetDecoderInfo, - JpegDecoder_CopyPalette, - JpegDecoder_GetMetadataQueryReader, - JpegDecoder_GetPreview, - JpegDecoder_GetColorContexts, - JpegDecoder_GetThumbnail, - JpegDecoder_GetFrameCount, - JpegDecoder_GetFrame -}; - -static HRESULT WINAPI JpegDecoder_Frame_QueryInterface(IWICBitmapFrameDecode *iface, REFIID iid, - void **ppv) -{ - JpegDecoder *This = impl_from_IWICBitmapFrameDecode(iface); - - TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); - - if (!ppv) return E_INVALIDARG; - - if (IsEqualIID(&IID_IUnknown, iid) || - IsEqualIID(&IID_IWICBitmapSource, iid) || - IsEqualIID(&IID_IWICBitmapFrameDecode, iid)) - { - *ppv = &This->IWICBitmapFrameDecode_iface; - } - else - { - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI JpegDecoder_Frame_AddRef(IWICBitmapFrameDecode *iface) -{ - JpegDecoder *This = impl_from_IWICBitmapFrameDecode(iface); - return IWICBitmapDecoder_AddRef(&This->IWICBitmapDecoder_iface); -} - -static ULONG WINAPI JpegDecoder_Frame_Release(IWICBitmapFrameDecode *iface) -{ - JpegDecoder *This = impl_from_IWICBitmapFrameDecode(iface); - return IWICBitmapDecoder_Release(&This->IWICBitmapDecoder_iface); -} - -static HRESULT WINAPI JpegDecoder_Frame_GetSize(IWICBitmapFrameDecode *iface, - UINT *puiWidth, UINT *puiHeight) -{ - JpegDecoder *This = impl_from_IWICBitmapFrameDecode(iface); - *puiWidth = This->cinfo.output_width; - *puiHeight = This->cinfo.output_height; - TRACE("(%p)->(%u,%u)\n", iface, *puiWidth, *puiHeight); - return S_OK; -} - -static HRESULT WINAPI JpegDecoder_Frame_GetPixelFormat(IWICBitmapFrameDecode *iface, - WICPixelFormatGUID *pPixelFormat) -{ - JpegDecoder *This = impl_from_IWICBitmapFrameDecode(iface); - TRACE("(%p,%p)\n", iface, pPixelFormat); - if (This->cinfo.out_color_space == JCS_RGB) - memcpy(pPixelFormat, &GUID_WICPixelFormat24bppBGR, sizeof(GUID)); - else if (This->cinfo.out_color_space == JCS_CMYK) - memcpy(pPixelFormat, &GUID_WICPixelFormat32bppCMYK, sizeof(GUID)); - else /* This->cinfo.out_color_space == JCS_GRAYSCALE */ - memcpy(pPixelFormat, &GUID_WICPixelFormat8bppGray, sizeof(GUID)); - return S_OK; -} - -static HRESULT WINAPI JpegDecoder_Frame_GetResolution(IWICBitmapFrameDecode *iface, - double *pDpiX, double *pDpiY) -{ - JpegDecoder *This = impl_from_IWICBitmapFrameDecode(iface); - - EnterCriticalSection(&This->lock); - - switch (This->cinfo.density_unit) - { - case 2: /* pixels per centimeter */ - *pDpiX = This->cinfo.X_density * 2.54; - *pDpiY = This->cinfo.Y_density * 2.54; - break; - - case 1: /* pixels per inch */ - *pDpiX = This->cinfo.X_density; - *pDpiY = This->cinfo.Y_density; - break; - - case 0: /* unknown */ - default: - *pDpiX = 96.0; - *pDpiY = 96.0; - break; - } - - LeaveCriticalSection(&This->lock); - - TRACE("(%p)->(%0.2f,%0.2f)\n", iface, *pDpiX, *pDpiY); - - return S_OK; -} - -static HRESULT WINAPI JpegDecoder_Frame_CopyPalette(IWICBitmapFrameDecode *iface, - IWICPalette *pIPalette) -{ - FIXME("(%p,%p): stub\n", iface, pIPalette); - return E_NOTIMPL; -} - -static HRESULT WINAPI JpegDecoder_Frame_CopyPixels(IWICBitmapFrameDecode *iface, - const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer) -{ - JpegDecoder *This = impl_from_IWICBitmapFrameDecode(iface); - - TRACE("(%p,%s,%u,%u,%p)\n", iface, debug_wic_rect(prc), cbStride, cbBufferSize, pbBuffer); - - return copy_pixels(This->bpp, This->image_data, - This->cinfo.output_width, This->cinfo.output_height, This->stride, - prc, cbStride, cbBufferSize, pbBuffer); -} - -static HRESULT WINAPI JpegDecoder_Frame_GetMetadataQueryReader(IWICBitmapFrameDecode *iface, - IWICMetadataQueryReader **ppIMetadataQueryReader) -{ - JpegDecoder *This = impl_from_IWICBitmapFrameDecode(iface); - - TRACE("(%p,%p)\n", iface, ppIMetadataQueryReader); - - if (!ppIMetadataQueryReader) - return E_INVALIDARG; - - return MetadataQueryReader_CreateInstance(&This->IWICMetadataBlockReader_iface, NULL, ppIMetadataQueryReader); -} - -static HRESULT WINAPI JpegDecoder_Frame_GetColorContexts(IWICBitmapFrameDecode *iface, - UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount) -{ - FIXME("(%p,%u,%p,%p): stub\n", iface, cCount, ppIColorContexts, pcActualCount); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI JpegDecoder_Frame_GetThumbnail(IWICBitmapFrameDecode *iface, - IWICBitmapSource **ppIThumbnail) -{ - FIXME("(%p,%p): stub\n", iface, ppIThumbnail); - return WINCODEC_ERR_CODECNOTHUMBNAIL; -} - -static const IWICBitmapFrameDecodeVtbl JpegDecoder_Frame_Vtbl = { - JpegDecoder_Frame_QueryInterface, - JpegDecoder_Frame_AddRef, - JpegDecoder_Frame_Release, - JpegDecoder_Frame_GetSize, - JpegDecoder_Frame_GetPixelFormat, - JpegDecoder_Frame_GetResolution, - JpegDecoder_Frame_CopyPalette, - JpegDecoder_Frame_CopyPixels, - JpegDecoder_Frame_GetMetadataQueryReader, - JpegDecoder_Frame_GetColorContexts, - JpegDecoder_Frame_GetThumbnail -}; - -static HRESULT WINAPI JpegDecoder_Block_QueryInterface(IWICMetadataBlockReader *iface, REFIID iid, - void **ppv) -{ - JpegDecoder *This = impl_from_IWICMetadataBlockReader(iface); - return IWICBitmapFrameDecode_QueryInterface(&This->IWICBitmapFrameDecode_iface, iid, ppv); -} - -static ULONG WINAPI JpegDecoder_Block_AddRef(IWICMetadataBlockReader *iface) -{ - JpegDecoder *This = impl_from_IWICMetadataBlockReader(iface); - return IWICBitmapDecoder_AddRef(&This->IWICBitmapDecoder_iface); -} - -static ULONG WINAPI JpegDecoder_Block_Release(IWICMetadataBlockReader *iface) -{ - JpegDecoder *This = impl_from_IWICMetadataBlockReader(iface); - return IWICBitmapDecoder_Release(&This->IWICBitmapDecoder_iface); -} - -static HRESULT WINAPI JpegDecoder_Block_GetContainerFormat(IWICMetadataBlockReader *iface, - GUID *pguidContainerFormat) -{ - TRACE("%p,%p\n", iface, pguidContainerFormat); - - if (!pguidContainerFormat) return E_INVALIDARG; - - memcpy(pguidContainerFormat, &GUID_ContainerFormatJpeg, sizeof(GUID)); - - return S_OK; -} - -static HRESULT WINAPI JpegDecoder_Block_GetCount(IWICMetadataBlockReader *iface, - UINT *pcCount) -{ - FIXME("%p,%p\n", iface, pcCount); - - if (!pcCount) return E_INVALIDARG; - - *pcCount = 0; - - return S_OK; -} - -static HRESULT WINAPI JpegDecoder_Block_GetReaderByIndex(IWICMetadataBlockReader *iface, - UINT nIndex, IWICMetadataReader **ppIMetadataReader) -{ - FIXME("%p,%d,%p\n", iface, nIndex, ppIMetadataReader); - return E_INVALIDARG; -} - -static HRESULT WINAPI JpegDecoder_Block_GetEnumerator(IWICMetadataBlockReader *iface, - IEnumUnknown **ppIEnumMetadata) -{ - FIXME("%p,%p\n", iface, ppIEnumMetadata); - return E_NOTIMPL; -} - -static const IWICMetadataBlockReaderVtbl JpegDecoder_Block_Vtbl = { - JpegDecoder_Block_QueryInterface, - JpegDecoder_Block_AddRef, - JpegDecoder_Block_Release, - JpegDecoder_Block_GetContainerFormat, - JpegDecoder_Block_GetCount, - JpegDecoder_Block_GetReaderByIndex, - JpegDecoder_Block_GetEnumerator, -}; - -HRESULT JpegDecoder_CreateInstance(REFIID iid, void** ppv) -{ - JpegDecoder *This; - HRESULT ret; - - TRACE("(%s,%p)\n", debugstr_guid(iid), ppv); - - if (!libjpeg_handle && !load_libjpeg()) - { - ERR("Failed reading JPEG because unable to find %s\n", SONAME_LIBJPEG); - return E_FAIL; - } - - *ppv = NULL; - - This = HeapAlloc(GetProcessHeap(), 0, sizeof(JpegDecoder)); - if (!This) return E_OUTOFMEMORY; - - This->IWICBitmapDecoder_iface.lpVtbl = &JpegDecoder_Vtbl; - This->IWICBitmapFrameDecode_iface.lpVtbl = &JpegDecoder_Frame_Vtbl; - This->IWICMetadataBlockReader_iface.lpVtbl = &JpegDecoder_Block_Vtbl; - This->ref = 1; - This->initialized = FALSE; - This->cinfo_initialized = FALSE; - This->stream = NULL; - This->image_data = NULL; - InitializeCriticalSection(&This->lock); - This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": JpegDecoder.lock"); - - ret = IWICBitmapDecoder_QueryInterface(&This->IWICBitmapDecoder_iface, iid, ppv); - IWICBitmapDecoder_Release(&This->IWICBitmapDecoder_iface); - - return ret; -} - -typedef struct jpeg_compress_format { - const WICPixelFormatGUID *guid; - int bpp; - int num_components; - J_COLOR_SPACE color_space; - int swap_rgb; -} jpeg_compress_format; - -static const jpeg_compress_format compress_formats[] = { - { &GUID_WICPixelFormat24bppBGR, 24, 3, JCS_RGB, 1 }, - { &GUID_WICPixelFormat32bppCMYK, 32, 4, JCS_CMYK }, - { &GUID_WICPixelFormat8bppGray, 8, 1, JCS_GRAYSCALE }, - { 0 } -}; - -typedef struct JpegEncoder { - IWICBitmapEncoder IWICBitmapEncoder_iface; - IWICBitmapFrameEncode IWICBitmapFrameEncode_iface; - LONG ref; - struct jpeg_compress_struct cinfo; - struct jpeg_error_mgr jerr; - struct jpeg_destination_mgr dest_mgr; - BOOL initialized; - int frame_count; - BOOL frame_initialized; - BOOL started_compress; - int lines_written; - BOOL frame_committed; - BOOL committed; - UINT width, height; - double xres, yres; - const jpeg_compress_format *format; - IStream *stream; - WICColor palette[256]; - UINT colors; - CRITICAL_SECTION lock; - BYTE dest_buffer[1024]; -} JpegEncoder; - -static inline JpegEncoder *impl_from_IWICBitmapEncoder(IWICBitmapEncoder *iface) -{ - return CONTAINING_RECORD(iface, JpegEncoder, IWICBitmapEncoder_iface); -} - -static inline JpegEncoder *impl_from_IWICBitmapFrameEncode(IWICBitmapFrameEncode *iface) -{ - return CONTAINING_RECORD(iface, JpegEncoder, IWICBitmapFrameEncode_iface); -} - -static inline JpegEncoder *encoder_from_compress(j_compress_ptr compress) -{ - return CONTAINING_RECORD(compress, JpegEncoder, cinfo); -} - -static void dest_mgr_init_destination(j_compress_ptr cinfo) -{ - JpegEncoder *This = encoder_from_compress(cinfo); - - This->dest_mgr.next_output_byte = This->dest_buffer; - This->dest_mgr.free_in_buffer = sizeof(This->dest_buffer); -} - -static jpeg_boolean dest_mgr_empty_output_buffer(j_compress_ptr cinfo) -{ - JpegEncoder *This = encoder_from_compress(cinfo); - HRESULT hr; - ULONG byteswritten; - - hr = IStream_Write(This->stream, This->dest_buffer, - sizeof(This->dest_buffer), &byteswritten); - - if (hr != S_OK || byteswritten == 0) - { - ERR("Failed writing data, hr=%x\n", hr); - return FALSE; - } - - This->dest_mgr.next_output_byte = This->dest_buffer; - This->dest_mgr.free_in_buffer = sizeof(This->dest_buffer); - return TRUE; -} - -static void dest_mgr_term_destination(j_compress_ptr cinfo) -{ - JpegEncoder *This = encoder_from_compress(cinfo); - ULONG byteswritten; - HRESULT hr; - - if (This->dest_mgr.free_in_buffer != sizeof(This->dest_buffer)) - { - hr = IStream_Write(This->stream, This->dest_buffer, - sizeof(This->dest_buffer) - This->dest_mgr.free_in_buffer, &byteswritten); - - if (hr != S_OK || byteswritten == 0) - ERR("Failed writing data, hr=%x\n", hr); - } -} - -static HRESULT WINAPI JpegEncoder_Frame_QueryInterface(IWICBitmapFrameEncode *iface, REFIID iid, - void **ppv) -{ - JpegEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); - - if (!ppv) return E_INVALIDARG; - - if (IsEqualIID(&IID_IUnknown, iid) || - IsEqualIID(&IID_IWICBitmapFrameEncode, iid)) - { - *ppv = &This->IWICBitmapFrameEncode_iface; - } - else - { - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI JpegEncoder_Frame_AddRef(IWICBitmapFrameEncode *iface) -{ - JpegEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - return IWICBitmapEncoder_AddRef(&This->IWICBitmapEncoder_iface); -} - -static ULONG WINAPI JpegEncoder_Frame_Release(IWICBitmapFrameEncode *iface) -{ - JpegEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - return IWICBitmapEncoder_Release(&This->IWICBitmapEncoder_iface); -} - -static HRESULT WINAPI JpegEncoder_Frame_Initialize(IWICBitmapFrameEncode *iface, - IPropertyBag2 *pIEncoderOptions) -{ - JpegEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - TRACE("(%p,%p)\n", iface, pIEncoderOptions); - - EnterCriticalSection(&This->lock); - - if (This->frame_initialized) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - This->frame_initialized = TRUE; - - LeaveCriticalSection(&This->lock); - - return S_OK; -} - -static HRESULT WINAPI JpegEncoder_Frame_SetSize(IWICBitmapFrameEncode *iface, - UINT uiWidth, UINT uiHeight) -{ - JpegEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - TRACE("(%p,%u,%u)\n", iface, uiWidth, uiHeight); - - EnterCriticalSection(&This->lock); - - if (!This->frame_initialized || This->started_compress) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - This->width = uiWidth; - This->height = uiHeight; - - LeaveCriticalSection(&This->lock); - - return S_OK; -} - -static HRESULT WINAPI JpegEncoder_Frame_SetResolution(IWICBitmapFrameEncode *iface, - double dpiX, double dpiY) -{ - JpegEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - TRACE("(%p,%0.2f,%0.2f)\n", iface, dpiX, dpiY); - - EnterCriticalSection(&This->lock); - - if (!This->frame_initialized || This->started_compress) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - This->xres = dpiX; - This->yres = dpiY; - - LeaveCriticalSection(&This->lock); - - return S_OK; -} - -static HRESULT WINAPI JpegEncoder_Frame_SetPixelFormat(IWICBitmapFrameEncode *iface, - WICPixelFormatGUID *pPixelFormat) -{ - JpegEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - int i; - TRACE("(%p,%s)\n", iface, debugstr_guid(pPixelFormat)); - - EnterCriticalSection(&This->lock); - - if (!This->frame_initialized || This->started_compress) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - for (i=0; compress_formats[i].guid; i++) - { - if (memcmp(compress_formats[i].guid, pPixelFormat, sizeof(GUID)) == 0) - break; - } - - if (!compress_formats[i].guid) i = 0; - - This->format = &compress_formats[i]; - memcpy(pPixelFormat, This->format->guid, sizeof(GUID)); - - LeaveCriticalSection(&This->lock); - - return S_OK; -} - -static HRESULT WINAPI JpegEncoder_Frame_SetColorContexts(IWICBitmapFrameEncode *iface, - UINT cCount, IWICColorContext **ppIColorContext) -{ - FIXME("(%p,%u,%p): stub\n", iface, cCount, ppIColorContext); - return E_NOTIMPL; -} - -static HRESULT WINAPI JpegEncoder_Frame_SetPalette(IWICBitmapFrameEncode *iface, - IWICPalette *palette) -{ - JpegEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - HRESULT hr; - - TRACE("(%p,%p)\n", iface, palette); - - if (!palette) return E_INVALIDARG; - - EnterCriticalSection(&This->lock); - - if (This->frame_initialized) - hr = IWICPalette_GetColors(palette, 256, This->palette, &This->colors); - else - hr = WINCODEC_ERR_NOTINITIALIZED; - - LeaveCriticalSection(&This->lock); - return hr; -} - -static HRESULT WINAPI JpegEncoder_Frame_SetThumbnail(IWICBitmapFrameEncode *iface, - IWICBitmapSource *pIThumbnail) -{ - FIXME("(%p,%p): stub\n", iface, pIThumbnail); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI JpegEncoder_Frame_WritePixels(IWICBitmapFrameEncode *iface, - UINT lineCount, UINT cbStride, UINT cbBufferSize, BYTE *pbPixels) -{ - JpegEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - jmp_buf jmpbuf; - BYTE *swapped_data = NULL, *current_row; - UINT line; - int row_size; - TRACE("(%p,%u,%u,%u,%p)\n", iface, lineCount, cbStride, cbBufferSize, pbPixels); - - EnterCriticalSection(&This->lock); - - if (!This->frame_initialized || !This->width || !This->height || !This->format) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - if (lineCount == 0 || lineCount + This->lines_written > This->height) - { - LeaveCriticalSection(&This->lock); - return E_INVALIDARG; - } - - /* set up setjmp/longjmp error handling */ - if (setjmp(jmpbuf)) - { - LeaveCriticalSection(&This->lock); - HeapFree(GetProcessHeap(), 0, swapped_data); - return E_FAIL; - } - This->cinfo.client_data = jmpbuf; - - if (!This->started_compress) - { - This->cinfo.image_width = This->width; - This->cinfo.image_height = This->height; - This->cinfo.input_components = This->format->num_components; - This->cinfo.in_color_space = This->format->color_space; - - pjpeg_set_defaults(&This->cinfo); - - if (This->xres != 0.0 && This->yres != 0.0) - { - This->cinfo.density_unit = 1; /* dots per inch */ - This->cinfo.X_density = This->xres; - This->cinfo.Y_density = This->yres; - } - - pjpeg_start_compress(&This->cinfo, TRUE); - - This->started_compress = TRUE; - } - - row_size = This->format->bpp / 8 * This->width; - - if (This->format->swap_rgb) - { - swapped_data = HeapAlloc(GetProcessHeap(), 0, row_size); - if (!swapped_data) - { - LeaveCriticalSection(&This->lock); - return E_OUTOFMEMORY; - } - } - - for (line=0; line < lineCount; line++) - { - if (This->format->swap_rgb) - { - UINT x; - - memcpy(swapped_data, pbPixels + (cbStride * line), row_size); - - for (x=0; x < This->width; x++) - { - BYTE b; - - b = swapped_data[x*3]; - swapped_data[x*3] = swapped_data[x*3+2]; - swapped_data[x*3+2] = b; - } - - current_row = swapped_data; - } - else - current_row = pbPixels + (cbStride * line); - - if (!pjpeg_write_scanlines(&This->cinfo, ¤t_row, 1)) - { - ERR("failed writing scanlines\n"); - LeaveCriticalSection(&This->lock); - HeapFree(GetProcessHeap(), 0, swapped_data); - return E_FAIL; - } - - This->lines_written++; - } - - LeaveCriticalSection(&This->lock); - HeapFree(GetProcessHeap(), 0, swapped_data); - - return S_OK; -} - -static HRESULT WINAPI JpegEncoder_Frame_WriteSource(IWICBitmapFrameEncode *iface, - IWICBitmapSource *pIBitmapSource, WICRect *prc) -{ - JpegEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - HRESULT hr; - TRACE("(%p,%p,%s)\n", iface, pIBitmapSource, debug_wic_rect(prc)); - - if (!This->frame_initialized) - return WINCODEC_ERR_WRONGSTATE; - - hr = configure_write_source(iface, pIBitmapSource, prc, - This->format ? This->format->guid : NULL, This->width, This->height, - This->xres, This->yres); - - if (SUCCEEDED(hr)) - { - hr = write_source(iface, pIBitmapSource, prc, - This->format->guid, This->format->bpp, This->width, This->height); - } - - return hr; -} - -static HRESULT WINAPI JpegEncoder_Frame_Commit(IWICBitmapFrameEncode *iface) -{ - JpegEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - jmp_buf jmpbuf; - TRACE("(%p)\n", iface); - - EnterCriticalSection(&This->lock); - - if (!This->started_compress || This->lines_written != This->height || This->frame_committed) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - /* set up setjmp/longjmp error handling */ - if (setjmp(jmpbuf)) - { - LeaveCriticalSection(&This->lock); - return E_FAIL; - } - This->cinfo.client_data = jmpbuf; - - pjpeg_finish_compress(&This->cinfo); - - This->frame_committed = TRUE; - - LeaveCriticalSection(&This->lock); - - return S_OK; -} - -static HRESULT WINAPI JpegEncoder_Frame_GetMetadataQueryWriter(IWICBitmapFrameEncode *iface, - IWICMetadataQueryWriter **ppIMetadataQueryWriter) -{ - FIXME("(%p, %p): stub\n", iface, ppIMetadataQueryWriter); - return E_NOTIMPL; -} - -static const IWICBitmapFrameEncodeVtbl JpegEncoder_FrameVtbl = { - JpegEncoder_Frame_QueryInterface, - JpegEncoder_Frame_AddRef, - JpegEncoder_Frame_Release, - JpegEncoder_Frame_Initialize, - JpegEncoder_Frame_SetSize, - JpegEncoder_Frame_SetResolution, - JpegEncoder_Frame_SetPixelFormat, - JpegEncoder_Frame_SetColorContexts, - JpegEncoder_Frame_SetPalette, - JpegEncoder_Frame_SetThumbnail, - JpegEncoder_Frame_WritePixels, - JpegEncoder_Frame_WriteSource, - JpegEncoder_Frame_Commit, - JpegEncoder_Frame_GetMetadataQueryWriter -}; - -static HRESULT WINAPI JpegEncoder_QueryInterface(IWICBitmapEncoder *iface, REFIID iid, - void **ppv) -{ - JpegEncoder *This = impl_from_IWICBitmapEncoder(iface); - TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); - - if (!ppv) return E_INVALIDARG; - - if (IsEqualIID(&IID_IUnknown, iid) || - IsEqualIID(&IID_IWICBitmapEncoder, iid)) - { - *ppv = &This->IWICBitmapEncoder_iface; - } - else - { - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI JpegEncoder_AddRef(IWICBitmapEncoder *iface) -{ - JpegEncoder *This = impl_from_IWICBitmapEncoder(iface); - ULONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) refcount=%u\n", iface, ref); - - return ref; -} - -static ULONG WINAPI JpegEncoder_Release(IWICBitmapEncoder *iface) -{ - JpegEncoder *This = impl_from_IWICBitmapEncoder(iface); - ULONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p) refcount=%u\n", iface, ref); - - if (ref == 0) - { - This->lock.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&This->lock); - if (This->initialized) pjpeg_destroy_compress(&This->cinfo); - if (This->stream) IStream_Release(This->stream); - HeapFree(GetProcessHeap(), 0, This); - } - - return ref; -} - -static HRESULT WINAPI JpegEncoder_Initialize(IWICBitmapEncoder *iface, - IStream *pIStream, WICBitmapEncoderCacheOption cacheOption) -{ - JpegEncoder *This = impl_from_IWICBitmapEncoder(iface); - jmp_buf jmpbuf; - - TRACE("(%p,%p,%u)\n", iface, pIStream, cacheOption); - - EnterCriticalSection(&This->lock); - - if (This->initialized) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - pjpeg_std_error(&This->jerr); - - This->jerr.error_exit = error_exit_fn; - This->jerr.emit_message = emit_message_fn; - - This->cinfo.err = &This->jerr; - - This->cinfo.client_data = jmpbuf; - - if (setjmp(jmpbuf)) - { - LeaveCriticalSection(&This->lock); - return E_FAIL; - } - - pjpeg_CreateCompress(&This->cinfo, JPEG_LIB_VERSION, sizeof(struct jpeg_compress_struct)); - - This->stream = pIStream; - IStream_AddRef(pIStream); - - This->dest_mgr.next_output_byte = This->dest_buffer; - This->dest_mgr.free_in_buffer = sizeof(This->dest_buffer); - - This->dest_mgr.init_destination = dest_mgr_init_destination; - This->dest_mgr.empty_output_buffer = dest_mgr_empty_output_buffer; - This->dest_mgr.term_destination = dest_mgr_term_destination; - - This->cinfo.dest = &This->dest_mgr; - - This->initialized = TRUE; - - LeaveCriticalSection(&This->lock); - - return S_OK; -} - -static HRESULT WINAPI JpegEncoder_GetContainerFormat(IWICBitmapEncoder *iface, GUID *format) -{ - TRACE("(%p,%p)\n", iface, format); - - if (!format) - return E_INVALIDARG; - - memcpy(format, &GUID_ContainerFormatJpeg, sizeof(*format)); - return S_OK; -} - -static HRESULT WINAPI JpegEncoder_GetEncoderInfo(IWICBitmapEncoder *iface, IWICBitmapEncoderInfo **info) -{ - IWICComponentInfo *comp_info; - HRESULT hr; - - TRACE("%p,%p\n", iface, info); - - if (!info) return E_INVALIDARG; - - hr = CreateComponentInfo(&CLSID_WICJpegEncoder, &comp_info); - if (hr == S_OK) - { - hr = IWICComponentInfo_QueryInterface(comp_info, &IID_IWICBitmapEncoderInfo, (void **)info); - IWICComponentInfo_Release(comp_info); - } - return hr; -} - -static HRESULT WINAPI JpegEncoder_SetColorContexts(IWICBitmapEncoder *iface, - UINT cCount, IWICColorContext **ppIColorContext) -{ - FIXME("(%p,%u,%p): stub\n", iface, cCount, ppIColorContext); - return E_NOTIMPL; -} - -static HRESULT WINAPI JpegEncoder_SetPalette(IWICBitmapEncoder *iface, IWICPalette *pIPalette) -{ - JpegEncoder *This = impl_from_IWICBitmapEncoder(iface); - HRESULT hr; - - TRACE("(%p,%p)\n", iface, pIPalette); - - EnterCriticalSection(&This->lock); - - hr = This->initialized ? WINCODEC_ERR_UNSUPPORTEDOPERATION : WINCODEC_ERR_NOTINITIALIZED; - - LeaveCriticalSection(&This->lock); - - return hr; -} - -static HRESULT WINAPI JpegEncoder_SetThumbnail(IWICBitmapEncoder *iface, IWICBitmapSource *pIThumbnail) -{ - TRACE("(%p,%p)\n", iface, pIThumbnail); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI JpegEncoder_SetPreview(IWICBitmapEncoder *iface, IWICBitmapSource *pIPreview) -{ - TRACE("(%p,%p)\n", iface, pIPreview); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI JpegEncoder_CreateNewFrame(IWICBitmapEncoder *iface, - IWICBitmapFrameEncode **ppIFrameEncode, IPropertyBag2 **ppIEncoderOptions) -{ - JpegEncoder *This = impl_from_IWICBitmapEncoder(iface); - HRESULT hr; - static const PROPBAG2 opts[6] = - { - { PROPBAG2_TYPE_DATA, VT_R4, 0, 0, (LPOLESTR)wszImageQuality }, - { PROPBAG2_TYPE_DATA, VT_UI1, 0, 0, (LPOLESTR)wszBitmapTransform }, - { PROPBAG2_TYPE_DATA, VT_I4 | VT_ARRAY, 0, 0, (LPOLESTR)wszLuminance }, - { PROPBAG2_TYPE_DATA, VT_I4 | VT_ARRAY, 0, 0, (LPOLESTR)wszChrominance }, - { PROPBAG2_TYPE_DATA, VT_UI1, 0, 0, (LPOLESTR)wszJpegYCrCbSubsampling }, - { PROPBAG2_TYPE_DATA, VT_BOOL, 0, 0, (LPOLESTR)wszSuppressApp0 }, - }; - - TRACE("(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions); - - EnterCriticalSection(&This->lock); - - if (This->frame_count != 0) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; - } - - if (!This->initialized) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_NOTINITIALIZED; - } - - if (ppIEncoderOptions) - { - hr = CreatePropertyBag2(opts, ARRAY_SIZE(opts), ppIEncoderOptions); - if (FAILED(hr)) - { - LeaveCriticalSection(&This->lock); - return hr; - } - } - - This->frame_count = 1; - - LeaveCriticalSection(&This->lock); - - IWICBitmapEncoder_AddRef(iface); - *ppIFrameEncode = &This->IWICBitmapFrameEncode_iface; - - return S_OK; -} - -static HRESULT WINAPI JpegEncoder_Commit(IWICBitmapEncoder *iface) -{ - JpegEncoder *This = impl_from_IWICBitmapEncoder(iface); - TRACE("(%p)\n", iface); - - EnterCriticalSection(&This->lock); - - if (!This->frame_committed || This->committed) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - This->committed = TRUE; - - LeaveCriticalSection(&This->lock); - - return S_OK; -} - -static HRESULT WINAPI JpegEncoder_GetMetadataQueryWriter(IWICBitmapEncoder *iface, - IWICMetadataQueryWriter **ppIMetadataQueryWriter) -{ - FIXME("(%p,%p): stub\n", iface, ppIMetadataQueryWriter); - return E_NOTIMPL; -} - -static const IWICBitmapEncoderVtbl JpegEncoder_Vtbl = { - JpegEncoder_QueryInterface, - JpegEncoder_AddRef, - JpegEncoder_Release, - JpegEncoder_Initialize, - JpegEncoder_GetContainerFormat, - JpegEncoder_GetEncoderInfo, - JpegEncoder_SetColorContexts, - JpegEncoder_SetPalette, - JpegEncoder_SetThumbnail, - JpegEncoder_SetPreview, - JpegEncoder_CreateNewFrame, - JpegEncoder_Commit, - JpegEncoder_GetMetadataQueryWriter -}; - -HRESULT JpegEncoder_CreateInstance(REFIID iid, void** ppv) -{ - JpegEncoder *This; - HRESULT ret; - - TRACE("(%s,%p)\n", debugstr_guid(iid), ppv); - - *ppv = NULL; - - if (!libjpeg_handle && !load_libjpeg()) - { - ERR("Failed writing JPEG because unable to find %s\n",SONAME_LIBJPEG); - return E_FAIL; - } - - This = HeapAlloc(GetProcessHeap(), 0, sizeof(JpegEncoder)); - if (!This) return E_OUTOFMEMORY; - - This->IWICBitmapEncoder_iface.lpVtbl = &JpegEncoder_Vtbl; - This->IWICBitmapFrameEncode_iface.lpVtbl = &JpegEncoder_FrameVtbl; - This->ref = 1; - This->initialized = FALSE; - This->frame_count = 0; - This->frame_initialized = FALSE; - This->started_compress = FALSE; - This->lines_written = 0; - This->frame_committed = FALSE; - This->committed = FALSE; - This->width = This->height = 0; - This->xres = This->yres = 0.0; - This->format = NULL; - This->stream = NULL; - This->colors = 0; - InitializeCriticalSection(&This->lock); - This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": JpegEncoder.lock"); - - ret = IWICBitmapEncoder_QueryInterface(&This->IWICBitmapEncoder_iface, iid, ppv); - IWICBitmapEncoder_Release(&This->IWICBitmapEncoder_iface); - - return ret; -} - -#else /* !defined(SONAME_LIBJPEG) */ - -HRESULT JpegDecoder_CreateInstance(REFIID iid, void** ppv) -{ - ERR("Trying to load JPEG picture, but JPEG support is not compiled in.\n"); - return E_FAIL; -} - -HRESULT JpegEncoder_CreateInstance(REFIID iid, void** ppv) -{ - ERR("Trying to save JPEG picture, but JPEG support is not compiled in.\n"); - return E_FAIL; -} - -#endif diff --git a/dll/win32/windowscodecs/libjpeg.c b/dll/win32/windowscodecs/libjpeg.c new file mode 100644 index 0000000000000..22903ae4340e3 --- /dev/null +++ b/dll/win32/windowscodecs/libjpeg.c @@ -0,0 +1,662 @@ +/* + * Copyright 2009 Vincent Povirk 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 +#include +#include +#include +#include +#include + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winternl.h" +#include "winbase.h" +#include "objbase.h" + +#include "wincodecs_private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); +WINE_DECLARE_DEBUG_CHANNEL(jpeg); + +static void error_exit_fn(j_common_ptr cinfo) +{ + char message[JMSG_LENGTH_MAX]; + if (ERR_ON(jpeg)) + { + cinfo->err->format_message(cinfo, message); + ERR_(jpeg)("%s\n", message); + } + longjmp(*(jmp_buf*)cinfo->client_data, 1); +} + +static void emit_message_fn(j_common_ptr cinfo, int msg_level) +{ + char message[JMSG_LENGTH_MAX]; + + if (msg_level < 0 && ERR_ON(jpeg)) + { + cinfo->err->format_message(cinfo, message); + ERR_(jpeg)("%s\n", message); + } + else if (msg_level == 0 && WARN_ON(jpeg)) + { + cinfo->err->format_message(cinfo, message); + WARN_(jpeg)("%s\n", message); + } + else if (msg_level > 0 && TRACE_ON(jpeg)) + { + cinfo->err->format_message(cinfo, message); + TRACE_(jpeg)("%s\n", message); + } +} + +struct jpeg_decoder { + struct decoder decoder; + struct decoder_frame frame; + BOOL cinfo_initialized; + IStream *stream; + struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr jerr; + struct jpeg_source_mgr source_mgr; + BYTE source_buffer[1024]; + UINT stride; + BYTE *image_data; +}; + +static inline struct jpeg_decoder *impl_from_decoder(struct decoder* iface) +{ + return CONTAINING_RECORD(iface, struct jpeg_decoder, decoder); +} + +static inline struct jpeg_decoder *decoder_from_decompress(j_decompress_ptr decompress) +{ + return CONTAINING_RECORD(decompress, struct jpeg_decoder, cinfo); +} + +static void CDECL jpeg_decoder_destroy(struct decoder* iface) +{ + struct jpeg_decoder *This = impl_from_decoder(iface); + + if (This->cinfo_initialized) jpeg_destroy_decompress(&This->cinfo); + free(This->image_data); + free(This); +} + +static void source_mgr_init_source(j_decompress_ptr cinfo) +{ +} + +static boolean source_mgr_fill_input_buffer(j_decompress_ptr cinfo) +{ + struct jpeg_decoder *This = decoder_from_decompress(cinfo); + HRESULT hr; + ULONG bytesread; + + hr = stream_read(This->stream, This->source_buffer, 1024, &bytesread); + + if (FAILED(hr) || bytesread == 0) + { + return FALSE; + } + else + { + This->source_mgr.next_input_byte = This->source_buffer; + This->source_mgr.bytes_in_buffer = bytesread; + return TRUE; + } +} + +static void source_mgr_skip_input_data(j_decompress_ptr cinfo, long num_bytes) +{ + struct jpeg_decoder *This = decoder_from_decompress(cinfo); + + if (num_bytes > This->source_mgr.bytes_in_buffer) + { + stream_seek(This->stream, num_bytes - This->source_mgr.bytes_in_buffer, STREAM_SEEK_CUR, NULL); + This->source_mgr.bytes_in_buffer = 0; + } + else if (num_bytes > 0) + { + This->source_mgr.next_input_byte += num_bytes; + This->source_mgr.bytes_in_buffer -= num_bytes; + } +} + +static void source_mgr_term_source(j_decompress_ptr cinfo) +{ +} + +static HRESULT CDECL jpeg_decoder_initialize(struct decoder* iface, IStream *stream, struct decoder_stat *st) +{ + struct jpeg_decoder *This = impl_from_decoder(iface); + int ret; + jmp_buf jmpbuf; + UINT data_size, i; + + if (This->cinfo_initialized) + return WINCODEC_ERR_WRONGSTATE; + + jpeg_std_error(&This->jerr); + + This->jerr.error_exit = error_exit_fn; + This->jerr.emit_message = emit_message_fn; + + This->cinfo.err = &This->jerr; + + This->cinfo.client_data = jmpbuf; + + if (setjmp(jmpbuf)) + return E_FAIL; + + jpeg_CreateDecompress(&This->cinfo, JPEG_LIB_VERSION, sizeof(struct jpeg_decompress_struct)); + + This->cinfo_initialized = TRUE; + + This->stream = stream; + + stream_seek(This->stream, 0, STREAM_SEEK_SET, NULL); + + This->source_mgr.bytes_in_buffer = 0; + This->source_mgr.init_source = source_mgr_init_source; + This->source_mgr.fill_input_buffer = source_mgr_fill_input_buffer; + This->source_mgr.skip_input_data = source_mgr_skip_input_data; + This->source_mgr.resync_to_restart = jpeg_resync_to_restart; + This->source_mgr.term_source = source_mgr_term_source; + + This->cinfo.src = &This->source_mgr; + + ret = jpeg_read_header(&This->cinfo, TRUE); + + if (ret != JPEG_HEADER_OK) { + WARN("Jpeg image in stream has bad format, read header returned %d.\n",ret); + return E_FAIL; + } + + switch (This->cinfo.jpeg_color_space) + { + case JCS_GRAYSCALE: + This->cinfo.out_color_space = JCS_GRAYSCALE; + This->frame.bpp = 8; + This->frame.pixel_format = GUID_WICPixelFormat8bppGray; + break; + case JCS_RGB: + case JCS_YCbCr: + This->cinfo.out_color_space = JCS_RGB; + This->frame.bpp = 24; + This->frame.pixel_format = GUID_WICPixelFormat24bppBGR; + break; + case JCS_CMYK: + case JCS_YCCK: + This->cinfo.out_color_space = JCS_CMYK; + This->frame.bpp = 32; + This->frame.pixel_format = GUID_WICPixelFormat32bppCMYK; + break; + default: + ERR("Unknown JPEG color space %i\n", This->cinfo.jpeg_color_space); + return E_FAIL; + } + + if (!jpeg_start_decompress(&This->cinfo)) + { + ERR("jpeg_start_decompress failed\n"); + return E_FAIL; + } + + This->frame.width = This->cinfo.output_width; + This->frame.height = This->cinfo.output_height; + + switch (This->cinfo.density_unit) + { + case 2: /* pixels per centimeter */ + This->frame.dpix = This->cinfo.X_density * 2.54; + This->frame.dpiy = This->cinfo.Y_density * 2.54; + break; + + case 1: /* pixels per inch */ + This->frame.dpix = This->cinfo.X_density; + This->frame.dpiy = This->cinfo.Y_density; + break; + + case 0: /* unknown */ + default: + This->frame.dpix = This->frame.dpiy = 96.0; + break; + } + + This->frame.num_color_contexts = 0; + This->frame.num_colors = 0; + + This->stride = (This->frame.bpp * This->cinfo.output_width + 7) / 8; + data_size = This->stride * This->cinfo.output_height; + + if (data_size / This->stride < This->cinfo.output_height) + /* overflow in multiplication */ + return E_OUTOFMEMORY; + + This->image_data = malloc(data_size); + if (!This->image_data) + return E_OUTOFMEMORY; + + while (This->cinfo.output_scanline < This->cinfo.output_height) + { + UINT first_scanline = This->cinfo.output_scanline; + UINT max_rows; + JSAMPROW out_rows[4]; + JDIMENSION ret; + + max_rows = min(This->cinfo.output_height-first_scanline, 4); + for (i=0; iimage_data + This->stride * (first_scanline+i); + + ret = jpeg_read_scanlines(&This->cinfo, out_rows, max_rows); + if (ret == 0) + { + ERR("read_scanlines failed\n"); + return E_FAIL; + } + } + + if (This->frame.bpp == 24) + { + /* libjpeg gives us RGB data and we want BGR, so byteswap the data */ + reverse_bgr8(3, This->image_data, + This->cinfo.output_width, This->cinfo.output_height, + This->stride); + } + + if (This->cinfo.out_color_space == JCS_CMYK && This->cinfo.saw_Adobe_marker) + { + /* Adobe JPEG's have inverted CMYK data. */ + for (i=0; iimage_data[i] ^= 0xff; + } + + st->frame_count = 1; + st->flags = WICBitmapDecoderCapabilityCanDecodeAllImages | + WICBitmapDecoderCapabilityCanDecodeSomeImages | + WICBitmapDecoderCapabilityCanEnumerateMetadata | + DECODER_FLAGS_UNSUPPORTED_COLOR_CONTEXT; + return S_OK; +} + +static HRESULT CDECL jpeg_decoder_get_frame_info(struct decoder* iface, UINT frame, struct decoder_frame *info) +{ + struct jpeg_decoder *This = impl_from_decoder(iface); + *info = This->frame; + return S_OK; +} + +static HRESULT CDECL jpeg_decoder_copy_pixels(struct decoder* iface, UINT frame, + const WICRect *prc, UINT stride, UINT buffersize, BYTE *buffer) +{ + struct jpeg_decoder *This = impl_from_decoder(iface); + return copy_pixels(This->frame.bpp, This->image_data, + This->frame.width, This->frame.height, This->stride, + prc, stride, buffersize, buffer); +} + +static HRESULT CDECL jpeg_decoder_get_metadata_blocks(struct decoder* iface, UINT frame, + UINT *count, struct decoder_block **blocks) +{ + FIXME("stub\n"); + *count = 0; + *blocks = NULL; + return S_OK; +} + +static HRESULT CDECL jpeg_decoder_get_color_context(struct decoder* This, UINT frame, UINT num, + BYTE **data, DWORD *datasize) +{ + /* This should never be called because we report 0 color contexts and the unsupported flag. */ + FIXME("stub\n"); + return E_NOTIMPL; +} + +static const struct decoder_funcs jpeg_decoder_vtable = { + jpeg_decoder_initialize, + jpeg_decoder_get_frame_info, + jpeg_decoder_copy_pixels, + jpeg_decoder_get_metadata_blocks, + jpeg_decoder_get_color_context, + jpeg_decoder_destroy +}; + +HRESULT CDECL jpeg_decoder_create(struct decoder_info *info, struct decoder **result) +{ + struct jpeg_decoder *This; + + This = malloc(sizeof(struct jpeg_decoder)); + if (!This) return E_OUTOFMEMORY; + + This->decoder.vtable = &jpeg_decoder_vtable; + This->cinfo_initialized = FALSE; + This->stream = NULL; + This->image_data = NULL; + *result = &This->decoder; + + info->container_format = GUID_ContainerFormatJpeg; + info->block_format = GUID_ContainerFormatJpeg; + info->clsid = CLSID_WICJpegDecoder; + + return S_OK; +} + +typedef struct jpeg_compress_format { + const WICPixelFormatGUID *guid; + int bpp; + int num_components; + J_COLOR_SPACE color_space; + int swap_rgb; +} jpeg_compress_format; + +static const jpeg_compress_format compress_formats[] = { + { &GUID_WICPixelFormat24bppBGR, 24, 3, JCS_RGB, 1 }, + { &GUID_WICPixelFormat32bppCMYK, 32, 4, JCS_CMYK }, + { &GUID_WICPixelFormat8bppGray, 8, 1, JCS_GRAYSCALE }, + { 0 } +}; + +struct jpeg_encoder +{ + struct encoder encoder; + IStream *stream; + BOOL cinfo_initialized; + struct jpeg_compress_struct cinfo; + struct jpeg_error_mgr jerr; + struct jpeg_destination_mgr dest_mgr; + struct encoder_frame encoder_frame; + const jpeg_compress_format *format; + BYTE dest_buffer[1024]; +}; + +static inline struct jpeg_encoder *impl_from_encoder(struct encoder* iface) +{ + return CONTAINING_RECORD(iface, struct jpeg_encoder, encoder); +} + +static inline struct jpeg_encoder *encoder_from_compress(j_compress_ptr compress) +{ + return CONTAINING_RECORD(compress, struct jpeg_encoder, cinfo); +} + +static void dest_mgr_init_destination(j_compress_ptr cinfo) +{ + struct jpeg_encoder *This = encoder_from_compress(cinfo); + + This->dest_mgr.next_output_byte = This->dest_buffer; + This->dest_mgr.free_in_buffer = sizeof(This->dest_buffer); +} + +static boolean dest_mgr_empty_output_buffer(j_compress_ptr cinfo) +{ + struct jpeg_encoder *This = encoder_from_compress(cinfo); + HRESULT hr; + ULONG byteswritten; + + hr = stream_write(This->stream, This->dest_buffer, + sizeof(This->dest_buffer), &byteswritten); + + if (hr != S_OK || byteswritten == 0) + { + ERR("Failed writing data, hr=%lx\n", hr); + return FALSE; + } + + This->dest_mgr.next_output_byte = This->dest_buffer; + This->dest_mgr.free_in_buffer = sizeof(This->dest_buffer); + return TRUE; +} + +static void dest_mgr_term_destination(j_compress_ptr cinfo) +{ + struct jpeg_encoder *This = encoder_from_compress(cinfo); + ULONG byteswritten; + HRESULT hr; + + if (This->dest_mgr.free_in_buffer != sizeof(This->dest_buffer)) + { + hr = stream_write(This->stream, This->dest_buffer, + sizeof(This->dest_buffer) - This->dest_mgr.free_in_buffer, &byteswritten); + + if (hr != S_OK || byteswritten == 0) + ERR("Failed writing data, hr=%lx\n", hr); + } +} + +static HRESULT CDECL jpeg_encoder_initialize(struct encoder* iface, IStream *stream) +{ + struct jpeg_encoder *This = impl_from_encoder(iface); + jmp_buf jmpbuf; + + jpeg_std_error(&This->jerr); + + This->jerr.error_exit = error_exit_fn; + This->jerr.emit_message = emit_message_fn; + + This->cinfo.err = &This->jerr; + + This->cinfo.client_data = jmpbuf; + + if (setjmp(jmpbuf)) + return E_FAIL; + + jpeg_CreateCompress(&This->cinfo, JPEG_LIB_VERSION, sizeof(struct jpeg_compress_struct)); + + This->stream = stream; + + This->dest_mgr.next_output_byte = This->dest_buffer; + This->dest_mgr.free_in_buffer = sizeof(This->dest_buffer); + + This->dest_mgr.init_destination = dest_mgr_init_destination; + This->dest_mgr.empty_output_buffer = dest_mgr_empty_output_buffer; + This->dest_mgr.term_destination = dest_mgr_term_destination; + + This->cinfo.dest = &This->dest_mgr; + + This->cinfo_initialized = TRUE; + + return S_OK; +} + +static HRESULT CDECL jpeg_encoder_get_supported_format(struct encoder* iface, GUID *pixel_format, + DWORD *bpp, BOOL *indexed) +{ + int i; + + for (i=0; compress_formats[i].guid; i++) + { + if (memcmp(compress_formats[i].guid, pixel_format, sizeof(GUID)) == 0) + break; + } + + if (!compress_formats[i].guid) i = 0; + + *pixel_format = *compress_formats[i].guid; + *bpp = compress_formats[i].bpp; + *indexed = FALSE; + + return S_OK; +} + +static HRESULT CDECL jpeg_encoder_create_frame(struct encoder* iface, const struct encoder_frame *frame) +{ + struct jpeg_encoder *This = impl_from_encoder(iface); + jmp_buf jmpbuf; + int i; + + This->encoder_frame = *frame; + + if (setjmp(jmpbuf)) + return E_FAIL; + + This->cinfo.client_data = jmpbuf; + + for (i=0; compress_formats[i].guid; i++) + { + if (memcmp(compress_formats[i].guid, &frame->pixel_format, sizeof(GUID)) == 0) + break; + } + This->format = &compress_formats[i]; + + This->cinfo.image_width = frame->width; + This->cinfo.image_height = frame->height; + This->cinfo.input_components = This->format->num_components; + This->cinfo.in_color_space = This->format->color_space; + + jpeg_set_defaults(&This->cinfo); + + if (frame->dpix != 0.0 && frame->dpiy != 0.0) + { + This->cinfo.density_unit = 1; /* dots per inch */ + This->cinfo.X_density = frame->dpix; + This->cinfo.Y_density = frame->dpiy; + } + + jpeg_start_compress(&This->cinfo, TRUE); + + return S_OK; +} + +static HRESULT CDECL jpeg_encoder_write_lines(struct encoder* iface, BYTE *data, + DWORD line_count, DWORD stride) +{ + struct jpeg_encoder *This = impl_from_encoder(iface); + jmp_buf jmpbuf; + BYTE *swapped_data = NULL, *current_row; + UINT line; + int row_size; + + if (setjmp(jmpbuf)) + { + free(swapped_data); + return E_FAIL; + } + + This->cinfo.client_data = jmpbuf; + + row_size = This->format->bpp / 8 * This->encoder_frame.width; + + if (This->format->swap_rgb) + { + swapped_data = malloc(row_size); + if (!swapped_data) + return E_OUTOFMEMORY; + } + + for (line=0; line < line_count; line++) + { + if (This->format->swap_rgb) + { + UINT x; + + memcpy(swapped_data, data + (stride * line), row_size); + + for (x=0; x < This->encoder_frame.width; x++) + { + BYTE b; + + b = swapped_data[x*3]; + swapped_data[x*3] = swapped_data[x*3+2]; + swapped_data[x*3+2] = b; + } + + current_row = swapped_data; + } + else + current_row = data + (stride * line); + + if (!jpeg_write_scanlines(&This->cinfo, ¤t_row, 1)) + { + ERR("failed writing scanlines\n"); + free(swapped_data); + return E_FAIL; + } + } + + free(swapped_data); + + return S_OK; +} + +static HRESULT CDECL jpeg_encoder_commit_frame(struct encoder* iface) +{ + struct jpeg_encoder *This = impl_from_encoder(iface); + jmp_buf jmpbuf; + + if (setjmp(jmpbuf)) + return E_FAIL; + + This->cinfo.client_data = jmpbuf; + + jpeg_finish_compress(&This->cinfo); + + return S_OK; +} + +static HRESULT CDECL jpeg_encoder_commit_file(struct encoder* iface) +{ + return S_OK; +} + +static void CDECL jpeg_encoder_destroy(struct encoder* iface) +{ + struct jpeg_encoder *This = impl_from_encoder(iface); + if (This->cinfo_initialized) + jpeg_destroy_compress(&This->cinfo); + free(This); +}; + +static const struct encoder_funcs jpeg_encoder_vtable = { + jpeg_encoder_initialize, + jpeg_encoder_get_supported_format, + jpeg_encoder_create_frame, + jpeg_encoder_write_lines, + jpeg_encoder_commit_frame, + jpeg_encoder_commit_file, + jpeg_encoder_destroy +}; + +HRESULT CDECL jpeg_encoder_create(struct encoder_info *info, struct encoder **result) +{ + struct jpeg_encoder *This; + + This = malloc(sizeof(struct jpeg_encoder)); + if (!This) return E_OUTOFMEMORY; + + This->encoder.vtable = &jpeg_encoder_vtable; + This->stream = NULL; + This->cinfo_initialized = FALSE; + *result = &This->encoder; + + info->flags = ENCODER_FLAGS_SUPPORTS_METADATA; + info->container_format = GUID_ContainerFormatJpeg; + info->clsid = CLSID_WICJpegEncoder; + info->encoder_options[0] = ENCODER_OPTION_IMAGE_QUALITY; + info->encoder_options[1] = ENCODER_OPTION_BITMAP_TRANSFORM; + info->encoder_options[2] = ENCODER_OPTION_LUMINANCE; + info->encoder_options[3] = ENCODER_OPTION_CHROMINANCE; + info->encoder_options[4] = ENCODER_OPTION_YCRCB_SUBSAMPLING; + info->encoder_options[5] = ENCODER_OPTION_SUPPRESS_APP0; + info->encoder_options[6] = ENCODER_OPTION_END; + + return S_OK; +} diff --git a/dll/win32/windowscodecs/libpng.c b/dll/win32/windowscodecs/libpng.c new file mode 100644 index 0000000000000..137a8e15e3311 --- /dev/null +++ b/dll/win32/windowscodecs/libpng.c @@ -0,0 +1,842 @@ +/* + * Copyright 2016 Dmitry Timoshkov + * Copyright 2020 Esme Povirk + * + * 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 +#include + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winternl.h" +#include "winbase.h" +#include "objbase.h" + +#include "wincodecs_private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); + +struct png_decoder +{ + struct decoder decoder; + IStream *stream; + struct decoder_frame decoder_frame; + UINT stride; + BYTE *image_bits; + BYTE *color_profile; + DWORD color_profile_len; +}; + +static inline struct png_decoder *impl_from_decoder(struct decoder* iface) +{ + return CONTAINING_RECORD(iface, struct png_decoder, decoder); +} + +static void user_read_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + IStream *stream = png_get_io_ptr(png_ptr); + HRESULT hr; + ULONG bytesread; + + hr = stream_read(stream, data, length, &bytesread); + if (FAILED(hr) || bytesread != length) + { + png_error(png_ptr, "failed reading data"); + } +} + +static HRESULT CDECL png_decoder_initialize(struct decoder *iface, IStream *stream, struct decoder_stat *st) +{ + struct png_decoder *This = impl_from_decoder(iface); + png_structp png_ptr; + png_infop info_ptr; + HRESULT hr = E_FAIL; + int color_type, bit_depth; + png_bytep trans; + int num_trans; + png_uint_32 transparency; + png_color_16p trans_values; + png_uint_32 ret, xres, yres; + int unit_type; + png_colorp png_palette; + int num_palette; + int i; + UINT image_size; + png_bytep *row_pointers=NULL; + png_charp cp_name; + png_bytep cp_profile; + png_uint_32 cp_len; + int cp_compression; + + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (!png_ptr) + { + return E_FAIL; + } + + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) + { + png_destroy_read_struct(&png_ptr, NULL, NULL); + return E_FAIL; + } + + /* set up setjmp/longjmp error handling */ + if (setjmp(png_jmpbuf(png_ptr))) + { + hr = WINCODEC_ERR_UNKNOWNIMAGEFORMAT; + goto end; + } + png_set_crc_action(png_ptr, PNG_CRC_QUIET_USE, PNG_CRC_QUIET_USE); + png_set_chunk_malloc_max(png_ptr, 0); + + /* seek to the start of the stream */ + hr = stream_seek(stream, 0, STREAM_SEEK_SET, NULL); + if (FAILED(hr)) + { + goto end; + } + + /* set up custom i/o handling */ + png_set_read_fn(png_ptr, stream, user_read_data); + + /* read the header */ + png_read_info(png_ptr, info_ptr); + + /* choose a pixel format */ + color_type = png_get_color_type(png_ptr, info_ptr); + bit_depth = png_get_bit_depth(png_ptr, info_ptr); + + /* PNGs with bit-depth greater than 8 are network byte order. Windows does not expect this. */ + if (bit_depth > 8) + png_set_swap(png_ptr); + + /* check for color-keyed alpha */ + transparency = png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, &trans_values); + if (!transparency) + num_trans = 0; + + if (transparency && (color_type == PNG_COLOR_TYPE_RGB || + (color_type == PNG_COLOR_TYPE_GRAY && bit_depth == 16))) + { + /* expand to RGBA */ + if (color_type == PNG_COLOR_TYPE_GRAY) + png_set_gray_to_rgb(png_ptr); + png_set_tRNS_to_alpha(png_ptr); + color_type = PNG_COLOR_TYPE_RGB_ALPHA; + } + + switch (color_type) + { + case PNG_COLOR_TYPE_GRAY_ALPHA: + /* WIC does not support grayscale alpha formats so use RGBA */ + png_set_gray_to_rgb(png_ptr); + /* fall through */ + case PNG_COLOR_TYPE_RGB_ALPHA: + This->decoder_frame.bpp = bit_depth * 4; + switch (bit_depth) + { + case 8: + png_set_bgr(png_ptr); + This->decoder_frame.pixel_format = GUID_WICPixelFormat32bppBGRA; + break; + case 16: This->decoder_frame.pixel_format = GUID_WICPixelFormat64bppRGBA; break; + default: + ERR("invalid RGBA bit depth: %i\n", bit_depth); + hr = E_FAIL; + goto end; + } + break; + case PNG_COLOR_TYPE_GRAY: + This->decoder_frame.bpp = bit_depth; + if (!transparency) + { + switch (bit_depth) + { + case 1: This->decoder_frame.pixel_format = GUID_WICPixelFormatBlackWhite; break; + case 2: This->decoder_frame.pixel_format = GUID_WICPixelFormat2bppGray; break; + case 4: This->decoder_frame.pixel_format = GUID_WICPixelFormat4bppGray; break; + case 8: This->decoder_frame.pixel_format = GUID_WICPixelFormat8bppGray; break; + case 16: This->decoder_frame.pixel_format = GUID_WICPixelFormat16bppGray; break; + default: + ERR("invalid grayscale bit depth: %i\n", bit_depth); + hr = E_FAIL; + goto end; + } + break; + } + /* else fall through */ + case PNG_COLOR_TYPE_PALETTE: + This->decoder_frame.bpp = bit_depth; + switch (bit_depth) + { + case 1: This->decoder_frame.pixel_format = GUID_WICPixelFormat1bppIndexed; break; + case 2: This->decoder_frame.pixel_format = GUID_WICPixelFormat2bppIndexed; break; + case 4: This->decoder_frame.pixel_format = GUID_WICPixelFormat4bppIndexed; break; + case 8: This->decoder_frame.pixel_format = GUID_WICPixelFormat8bppIndexed; break; + default: + ERR("invalid indexed color bit depth: %i\n", bit_depth); + hr = E_FAIL; + goto end; + } + break; + case PNG_COLOR_TYPE_RGB: + This->decoder_frame.bpp = bit_depth * 3; + switch (bit_depth) + { + case 8: + png_set_bgr(png_ptr); + This->decoder_frame.pixel_format = GUID_WICPixelFormat24bppBGR; + break; + case 16: This->decoder_frame.pixel_format = GUID_WICPixelFormat48bppRGB; break; + default: + ERR("invalid RGB color bit depth: %i\n", bit_depth); + hr = E_FAIL; + goto end; + } + break; + default: + ERR("invalid color type %i\n", color_type); + hr = E_FAIL; + goto end; + } + + This->decoder_frame.width = png_get_image_width(png_ptr, info_ptr); + This->decoder_frame.height = png_get_image_height(png_ptr, info_ptr); + + ret = png_get_pHYs(png_ptr, info_ptr, &xres, &yres, &unit_type); + + if (ret && unit_type == PNG_RESOLUTION_METER) + { + This->decoder_frame.dpix = xres * 0.0254; + This->decoder_frame.dpiy = yres * 0.0254; + } + else + { + WARN("no pHYs block present\n"); + This->decoder_frame.dpix = This->decoder_frame.dpiy = 96.0; + } + + ret = png_get_iCCP(png_ptr, info_ptr, &cp_name, &cp_compression, &cp_profile, &cp_len); + if (ret) + { + This->decoder_frame.num_color_contexts = 1; + This->color_profile_len = cp_len; + This->color_profile = malloc(cp_len); + if (!This->color_profile) + { + hr = E_OUTOFMEMORY; + goto end; + } + memcpy(This->color_profile, cp_profile, cp_len); + } + else + This->decoder_frame.num_color_contexts = 0; + + if (color_type == PNG_COLOR_TYPE_PALETTE) + { + ret = png_get_PLTE(png_ptr, info_ptr, &png_palette, &num_palette); + if (!ret) + { + ERR("paletted image with no PLTE chunk\n"); + hr = E_FAIL; + goto end; + } + + if (num_palette > 256) + { + ERR("palette has %i colors?!\n", num_palette); + hr = E_FAIL; + goto end; + } + + This->decoder_frame.num_colors = num_palette; + for (i=0; idecoder_frame.palette[i] = (alpha << 24 | + png_palette[i].red << 16| + png_palette[i].green << 8| + png_palette[i].blue); + } + } + else if (color_type == PNG_COLOR_TYPE_GRAY && transparency && bit_depth <= 8) { + num_palette = 1 << bit_depth; + + This->decoder_frame.num_colors = num_palette; + for (i=0; idecoder_frame.palette[i] = (alpha << 24 | val << 16 | val << 8 | val); + } + } + else + { + This->decoder_frame.num_colors = 0; + } + + This->stride = (This->decoder_frame.width * This->decoder_frame.bpp + 7) / 8; + image_size = This->stride * This->decoder_frame.height; + + This->image_bits = malloc(image_size); + if (!This->image_bits) + { + hr = E_OUTOFMEMORY; + goto end; + } + + row_pointers = malloc(sizeof(png_bytep)*This->decoder_frame.height); + if (!row_pointers) + { + hr = E_OUTOFMEMORY; + goto end; + } + + for (i=0; idecoder_frame.height; i++) + row_pointers[i] = This->image_bits + i * This->stride; + + png_read_image(png_ptr, row_pointers); + + free(row_pointers); + row_pointers = NULL; + + /* png_read_end intentionally not called to not seek to the end of the file */ + + st->flags = WICBitmapDecoderCapabilityCanDecodeAllImages | + WICBitmapDecoderCapabilityCanDecodeSomeImages | + WICBitmapDecoderCapabilityCanEnumerateMetadata; + st->frame_count = 1; + + This->stream = stream; + + hr = S_OK; + +end: + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + free(row_pointers); + if (FAILED(hr)) + { + free(This->image_bits); + This->image_bits = NULL; + free(This->color_profile); + This->color_profile = NULL; + } + return hr; +} + +static HRESULT CDECL png_decoder_get_frame_info(struct decoder *iface, UINT frame, struct decoder_frame *info) +{ + struct png_decoder *This = impl_from_decoder(iface); + *info = This->decoder_frame; + return S_OK; +} + +static HRESULT CDECL png_decoder_copy_pixels(struct decoder *iface, UINT frame, + const WICRect *prc, UINT stride, UINT buffersize, BYTE *buffer) +{ + struct png_decoder *This = impl_from_decoder(iface); + + return copy_pixels(This->decoder_frame.bpp, This->image_bits, + This->decoder_frame.width, This->decoder_frame.height, This->stride, + prc, stride, buffersize, buffer); +} + +static HRESULT CDECL png_decoder_get_metadata_blocks(struct decoder* iface, + UINT frame, UINT *count, struct decoder_block **blocks) +{ + struct png_decoder *This = impl_from_decoder(iface); + HRESULT hr; + struct decoder_block *result = NULL; + ULONGLONG seek; + BYTE chunk_type[4]; + ULONG chunk_size; + ULONGLONG chunk_start; + ULONG metadata_blocks_size = 0; + + seek = 8; + *count = 0; + + do + { + hr = stream_seek(This->stream, seek, STREAM_SEEK_SET, &chunk_start); + if (FAILED(hr)) goto end; + + hr = read_png_chunk(This->stream, chunk_type, NULL, &chunk_size); + if (FAILED(hr)) goto end; + + if (chunk_type[0] >= 'a' && chunk_type[0] <= 'z' && + memcmp(chunk_type, "tRNS", 4) && memcmp(chunk_type, "pHYs", 4)) + { + /* This chunk is considered metadata. */ + if (*count == metadata_blocks_size) + { + struct decoder_block *new_metadata_blocks; + ULONG new_metadata_blocks_size; + + new_metadata_blocks_size = 4 + metadata_blocks_size * 2; + new_metadata_blocks = malloc(new_metadata_blocks_size * sizeof(*new_metadata_blocks)); + + if (!new_metadata_blocks) + { + hr = E_OUTOFMEMORY; + goto end; + } + + memcpy(new_metadata_blocks, result, + *count * sizeof(*new_metadata_blocks)); + + free(result); + result = new_metadata_blocks; + metadata_blocks_size = new_metadata_blocks_size; + } + + result[*count].offset = chunk_start; + result[*count].length = chunk_size + 12; + result[*count].options = WICMetadataCreationAllowUnknown; + (*count)++; + } + + seek = chunk_start + chunk_size + 12; /* skip data and CRC */ + } while (memcmp(chunk_type, "IEND", 4)); + +end: + if (SUCCEEDED(hr)) + { + *blocks = result; + } + else + { + *count = 0; + *blocks = NULL; + free(result); + } + return hr; +} + +static HRESULT CDECL png_decoder_get_color_context(struct decoder* iface, UINT frame, UINT num, + BYTE **data, DWORD *datasize) +{ + struct png_decoder *This = impl_from_decoder(iface); + + *data = malloc(This->color_profile_len); + *datasize = This->color_profile_len; + + if (!*data) + return E_OUTOFMEMORY; + + memcpy(*data, This->color_profile, This->color_profile_len); + + return S_OK; +} + +static void CDECL png_decoder_destroy(struct decoder* iface) +{ + struct png_decoder *This = impl_from_decoder(iface); + + free(This->image_bits); + free(This->color_profile); + free(This); +} + +static const struct decoder_funcs png_decoder_vtable = { + png_decoder_initialize, + png_decoder_get_frame_info, + png_decoder_copy_pixels, + png_decoder_get_metadata_blocks, + png_decoder_get_color_context, + png_decoder_destroy +}; + +HRESULT CDECL png_decoder_create(struct decoder_info *info, struct decoder **result) +{ + struct png_decoder *This; + + This = malloc(sizeof(*This)); + + if (!This) + { + return E_OUTOFMEMORY; + } + + This->decoder.vtable = &png_decoder_vtable; + This->image_bits = NULL; + This->color_profile = NULL; + *result = &This->decoder; + + info->container_format = GUID_ContainerFormatPng; + info->block_format = GUID_ContainerFormatPng; + info->clsid = CLSID_WICPngDecoder; + + return S_OK; +} + +struct png_pixelformat { + const WICPixelFormatGUID *guid; + UINT bpp; + int bit_depth; + int color_type; + BOOL remove_filler; + BOOL swap_rgb; +}; + +static const struct png_pixelformat formats[] = { + {&GUID_WICPixelFormat32bppBGRA, 32, 8, PNG_COLOR_TYPE_RGB_ALPHA, 0, 1}, + {&GUID_WICPixelFormat24bppBGR, 24, 8, PNG_COLOR_TYPE_RGB, 0, 1}, + {&GUID_WICPixelFormatBlackWhite, 1, 1, PNG_COLOR_TYPE_GRAY, 0, 0}, + {&GUID_WICPixelFormat2bppGray, 2, 2, PNG_COLOR_TYPE_GRAY, 0, 0}, + {&GUID_WICPixelFormat4bppGray, 4, 4, PNG_COLOR_TYPE_GRAY, 0, 0}, + {&GUID_WICPixelFormat8bppGray, 8, 8, PNG_COLOR_TYPE_GRAY, 0, 0}, + {&GUID_WICPixelFormat16bppGray, 16, 16, PNG_COLOR_TYPE_GRAY, 0, 0}, + {&GUID_WICPixelFormat32bppBGR, 32, 8, PNG_COLOR_TYPE_RGB, 1, 1}, + {&GUID_WICPixelFormat48bppRGB, 48, 16, PNG_COLOR_TYPE_RGB, 0, 0}, + {&GUID_WICPixelFormat64bppRGBA, 64, 16, PNG_COLOR_TYPE_RGB_ALPHA, 0, 0}, + {&GUID_WICPixelFormat1bppIndexed, 1, 1, PNG_COLOR_TYPE_PALETTE, 0, 0}, + {&GUID_WICPixelFormat2bppIndexed, 2, 2, PNG_COLOR_TYPE_PALETTE, 0, 0}, + {&GUID_WICPixelFormat4bppIndexed, 4, 4, PNG_COLOR_TYPE_PALETTE, 0, 0}, + {&GUID_WICPixelFormat8bppIndexed, 8, 8, PNG_COLOR_TYPE_PALETTE, 0, 0}, + {NULL}, +}; + +struct png_encoder +{ + struct encoder encoder; + IStream *stream; + png_structp png_ptr; + png_infop info_ptr; + struct encoder_frame encoder_frame; + const struct png_pixelformat *format; + BYTE *data; + UINT stride; + UINT passes; + UINT lines_written; +}; + +static inline struct png_encoder *impl_from_encoder(struct encoder* iface) +{ + return CONTAINING_RECORD(iface, struct png_encoder, encoder); +} + +static void user_write_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + struct png_encoder *This = png_get_io_ptr(png_ptr); + HRESULT hr; + ULONG byteswritten; + + hr = stream_write(This->stream, data, length, &byteswritten); + if (FAILED(hr) || byteswritten != length) + { + png_error(png_ptr, "failed writing data"); + } +} + +static void user_flush(png_structp png_ptr) +{ +} + +static HRESULT CDECL png_encoder_initialize(struct encoder *encoder, IStream *stream) +{ + struct png_encoder *This = impl_from_encoder(encoder); + + TRACE("(%p,%p)\n", encoder, stream); + + /* initialize libpng */ + This->png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (!This->png_ptr) + return E_FAIL; + + This->info_ptr = png_create_info_struct(This->png_ptr); + if (!This->info_ptr) + { + png_destroy_write_struct(&This->png_ptr, NULL); + This->png_ptr = NULL; + return E_FAIL; + } + + This->stream = stream; + + /* set up setjmp/longjmp error handling */ + if (setjmp(png_jmpbuf(This->png_ptr))) + { + png_destroy_write_struct(&This->png_ptr, &This->info_ptr); + This->png_ptr = NULL; + This->stream = NULL; + return E_FAIL; + } + + /* set up custom i/o handling */ + png_set_write_fn(This->png_ptr, This, user_write_data, user_flush); + + return S_OK; +} + +static HRESULT CDECL png_encoder_get_supported_format(struct encoder* iface, GUID *pixel_format, DWORD *bpp, BOOL *indexed) +{ + int i; + + for (i=0; formats[i].guid; i++) + { + if (memcmp(formats[i].guid, pixel_format, sizeof(GUID)) == 0) + break; + } + + if (!formats[i].guid) + i = 0; + + *pixel_format = *formats[i].guid; + *bpp = formats[i].bpp; + *indexed = (formats[i].color_type == PNG_COLOR_TYPE_PALETTE); + + return S_OK; +} + +static HRESULT CDECL png_encoder_create_frame(struct encoder *encoder, const struct encoder_frame *encoder_frame) +{ + struct png_encoder *This = impl_from_encoder(encoder); + int i; + + for (i=0; formats[i].guid; i++) + { + if (memcmp(formats[i].guid, &encoder_frame->pixel_format, sizeof(GUID)) == 0) + { + This->format = &formats[i]; + break; + } + } + + if (!formats[i].guid) + { + ERR("invalid pixel format %s\n", wine_dbgstr_guid(&encoder_frame->pixel_format)); + return E_FAIL; + } + + /* set up setjmp/longjmp error handling */ + if (setjmp(png_jmpbuf(This->png_ptr))) + return E_FAIL; + + This->encoder_frame = *encoder_frame; + This->lines_written = 0; + + if (encoder_frame->interlace) + { + /* libpng requires us to write all data multiple times in this case. */ + This->stride = (This->format->bpp * encoder_frame->width + 7)/8; + This->data = malloc(encoder_frame->height * This->stride); + if (!This->data) + return E_OUTOFMEMORY; + } + + /* Tell PNG we need to byte swap if writing a >8-bpp image */ + if (This->format->bit_depth > 8) + png_set_swap(This->png_ptr); + + png_set_IHDR(This->png_ptr, This->info_ptr, encoder_frame->width, encoder_frame->height, + This->format->bit_depth, This->format->color_type, + encoder_frame->interlace ? PNG_INTERLACE_ADAM7 : PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + + if (encoder_frame->dpix != 0.0 && encoder_frame->dpiy != 0.0) + { + png_set_pHYs(This->png_ptr, This->info_ptr, (encoder_frame->dpix+0.0127) / 0.0254, + (encoder_frame->dpiy+0.0127) / 0.0254, PNG_RESOLUTION_METER); + } + + if (This->format->color_type == PNG_COLOR_TYPE_PALETTE && encoder_frame->num_colors) + { + png_color png_palette[256]; + png_byte trans[256]; + UINT i, num_trans = 0, colors; + + /* Newer libpng versions don't accept larger palettes than the declared + * bit depth, so we need to generate the palette of the correct length. + */ + colors = min(encoder_frame->num_colors, 1 << This->format->bit_depth); + + for (i = 0; i < colors; i++) + { + png_palette[i].red = (encoder_frame->palette[i] >> 16) & 0xff; + png_palette[i].green = (encoder_frame->palette[i] >> 8) & 0xff; + png_palette[i].blue = encoder_frame->palette[i] & 0xff; + trans[i] = (encoder_frame->palette[i] >> 24) & 0xff; + if (trans[i] != 0xff) + num_trans = i+1; + } + + png_set_PLTE(This->png_ptr, This->info_ptr, png_palette, colors); + + if (num_trans) + png_set_tRNS(This->png_ptr, This->info_ptr, trans, num_trans, NULL); + } + + png_write_info(This->png_ptr, This->info_ptr); + + if (This->format->remove_filler) + png_set_filler(This->png_ptr, 0, PNG_FILLER_AFTER); + + if (This->format->swap_rgb) + png_set_bgr(This->png_ptr); + + if (encoder_frame->interlace) + This->passes = png_set_interlace_handling(This->png_ptr); + + if (encoder_frame->filter != WICPngFilterUnspecified) + { + static const int png_filter_map[] = + { + /* WICPngFilterUnspecified */ PNG_NO_FILTERS, + /* WICPngFilterNone */ PNG_FILTER_NONE, + /* WICPngFilterSub */ PNG_FILTER_SUB, + /* WICPngFilterUp */ PNG_FILTER_UP, + /* WICPngFilterAverage */ PNG_FILTER_AVG, + /* WICPngFilterPaeth */ PNG_FILTER_PAETH, + /* WICPngFilterAdaptive */ PNG_ALL_FILTERS, + }; + + png_set_filter(This->png_ptr, 0, png_filter_map[encoder_frame->filter]); + } + + return S_OK; +} + +static HRESULT CDECL png_encoder_write_lines(struct encoder* encoder, BYTE *data, DWORD line_count, DWORD stride) +{ + struct png_encoder *This = impl_from_encoder(encoder); + png_byte **row_pointers=NULL; + UINT i; + + if (This->encoder_frame.interlace) + { + /* Just store the data so we can write it in multiple passes in Commit. */ + for (i=0; idata + This->stride * (This->lines_written + i), + data + stride * i, + This->stride); + + This->lines_written += line_count; + + return S_OK; + } + + /* set up setjmp/longjmp error handling */ + if (setjmp(png_jmpbuf(This->png_ptr))) + { + free(row_pointers); + return E_FAIL; + } + + row_pointers = malloc(line_count * sizeof(png_byte*)); + if (!row_pointers) + return E_OUTOFMEMORY; + + for (i=0; ipng_ptr, row_pointers, line_count); + This->lines_written += line_count; + + free(row_pointers); + + return S_OK; +} + +static HRESULT CDECL png_encoder_commit_frame(struct encoder *encoder) +{ + struct png_encoder *This = impl_from_encoder(encoder); + png_byte **row_pointers=NULL; + + /* set up setjmp/longjmp error handling */ + if (setjmp(png_jmpbuf(This->png_ptr))) + { + free(row_pointers); + return E_FAIL; + } + + if (This->encoder_frame.interlace) + { + int i; + + row_pointers = malloc(This->encoder_frame.height * sizeof(png_byte*)); + if (!row_pointers) + return E_OUTOFMEMORY; + + for (i=0; iencoder_frame.height; i++) + row_pointers[i] = This->data + This->stride * i; + + for (i=0; ipasses; i++) + png_write_rows(This->png_ptr, row_pointers, This->encoder_frame.height); + } + + png_write_end(This->png_ptr, This->info_ptr); + + free(row_pointers); + + return S_OK; +} + +static HRESULT CDECL png_encoder_commit_file(struct encoder *encoder) +{ + return S_OK; +} + +static void CDECL png_encoder_destroy(struct encoder *encoder) +{ + struct png_encoder *This = impl_from_encoder(encoder); + if (This->png_ptr) + png_destroy_write_struct(&This->png_ptr, &This->info_ptr); + free(This->data); + free(This); +} + +static const struct encoder_funcs png_encoder_vtable = { + png_encoder_initialize, + png_encoder_get_supported_format, + png_encoder_create_frame, + png_encoder_write_lines, + png_encoder_commit_frame, + png_encoder_commit_file, + png_encoder_destroy +}; + +HRESULT CDECL png_encoder_create(struct encoder_info *info, struct encoder **result) +{ + struct png_encoder *This; + + This = malloc(sizeof(*This)); + + if (!This) + { + return E_OUTOFMEMORY; + } + + This->encoder.vtable = &png_encoder_vtable; + This->png_ptr = NULL; + This->info_ptr = NULL; + This->data = NULL; + *result = &This->encoder; + + info->flags = ENCODER_FLAGS_SUPPORTS_METADATA; + info->container_format = GUID_ContainerFormatPng; + info->clsid = CLSID_WICPngEncoder; + info->encoder_options[0] = ENCODER_OPTION_INTERLACE; + info->encoder_options[1] = ENCODER_OPTION_FILTER; + info->encoder_options[2] = ENCODER_OPTION_END; + + return S_OK; +} diff --git a/dll/win32/windowscodecs/libtiff.c b/dll/win32/windowscodecs/libtiff.c new file mode 100644 index 0000000000000..9db707f82cbc0 --- /dev/null +++ b/dll/win32/windowscodecs/libtiff.c @@ -0,0 +1,1352 @@ +/* + * Copyright 2010 Vincent Povirk for CodeWeavers + * Copyright 2016 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 +#include +#include +#include + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winternl.h" +#include "winbase.h" +#include "objbase.h" + +#include "wincodecs_private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); +#ifdef __REACTOS__ +#include "wine/library.h" +extern int isfinite(double x); +static void tiff_error_handler( const char *module, const char *format, va_list args ) +{ + +} +static void tiff_warning_handler( const char *module, const char *format, va_list args ) +{ + +} +#else +WINE_DECLARE_DEBUG_CHANNEL(tiff); + +static void tiff_error_handler( const char *module, const char *format, va_list args ) +{ + if (!ERR_ON(tiff)) return; + if (__wine_dbg_vlog( __WINE_DBCL_ERR, &__wine_dbch_tiff, module, format, args ) != -1) + __wine_dbg_output( "\n" ); +} + +static void tiff_warning_handler( const char *module, const char *format, va_list args ) +{ + if (!WARN_ON(tiff)) return; + if (__wine_dbg_vlog( __WINE_DBCL_WARN, &__wine_dbch_tiff, module, format, args ) != -1) + __wine_dbg_output( "\n" ); +} +#endif + +static tsize_t tiff_stream_read(thandle_t client_data, tdata_t data, tsize_t size) +{ + IStream *stream = (IStream*)client_data; + ULONG bytes_read; + HRESULT hr; + + hr = stream_read(stream, data, size, &bytes_read); + if (FAILED(hr)) bytes_read = 0; + return bytes_read; +} + +static tsize_t tiff_stream_write(thandle_t client_data, tdata_t data, tsize_t size) +{ + IStream *stream = (IStream*)client_data; + ULONG bytes_written; + HRESULT hr; + + hr = stream_write(stream, data, size, &bytes_written); + if (FAILED(hr)) bytes_written = 0; + return bytes_written; +} + +static toff_t tiff_stream_seek(thandle_t client_data, toff_t offset, int whence) +{ + IStream *stream = (IStream*)client_data; + DWORD origin; + ULONGLONG new_position; + HRESULT hr; + + switch (whence) + { + case SEEK_SET: + origin = STREAM_SEEK_SET; + break; + case SEEK_CUR: + origin = STREAM_SEEK_CUR; + break; + case SEEK_END: + origin = STREAM_SEEK_END; + break; + default: + ERR("unknown whence value %i\n", whence); + return -1; + } + + hr = stream_seek(stream, offset, origin, &new_position); + if (SUCCEEDED(hr)) return new_position; + else return -1; +} + +static int tiff_stream_close(thandle_t client_data) +{ + /* Caller is responsible for releasing the stream object. */ + return 0; +} + +static toff_t tiff_stream_size(thandle_t client_data) +{ + IStream *stream = (IStream*)client_data; + ULONGLONG size; + HRESULT hr; + + hr = stream_getsize(stream, &size); + + if (SUCCEEDED(hr)) return size; + else return -1; +} + +static int tiff_stream_map(thandle_t client_data, tdata_t *addr, toff_t *size) +{ + /* Cannot mmap streams */ + return 0; +} + +static void tiff_stream_unmap(thandle_t client_data, tdata_t addr, toff_t size) +{ + /* No need to ever do this, since we can't map things. */ +} + +static TIFF* tiff_open_stream(IStream *stream, const char *mode) +{ + stream_seek(stream, 0, STREAM_SEEK_SET, NULL); + + return TIFFClientOpen("", mode, stream, tiff_stream_read, + tiff_stream_write, (void *)tiff_stream_seek, tiff_stream_close, + (void *)tiff_stream_size, (void *)tiff_stream_map, (void *)tiff_stream_unmap); +} + +typedef struct { + struct decoder_frame frame; + int bps; + int samples; + int source_bpp; + int planar; + int indexed; + int reverse_bgr; + int invert_grayscale; + UINT tile_width, tile_height; + UINT tile_stride; + UINT tile_size; + int tiled; + UINT tiles_across; +} tiff_decode_info; + +struct tiff_decoder +{ + struct decoder decoder; + IStream *stream; + TIFF *tiff; + DWORD frame_count; + DWORD cached_frame; + tiff_decode_info cached_decode_info; + INT cached_tile_x, cached_tile_y; + BYTE *cached_tile; +}; + +static inline struct tiff_decoder *impl_from_decoder(struct decoder* iface) +{ + return CONTAINING_RECORD(iface, struct tiff_decoder, decoder); +} + +static HRESULT tiff_get_decode_info(TIFF *tiff, tiff_decode_info *decode_info) +{ + uint16_t photometric, bps, samples, planar; + uint16_t extra_sample_count, extra_sample, *extra_samples; + uint16_t *red, *green, *blue; + UINT resolution_unit; + float xres=0.0, yres=0.0; + int ret, i; + const BYTE *profile; + UINT len; + + decode_info->indexed = 0; + decode_info->reverse_bgr = 0; + decode_info->invert_grayscale = 0; + decode_info->tiled = 0; + decode_info->source_bpp = 0; + + ret = TIFFGetField(tiff, TIFFTAG_PHOTOMETRIC, &photometric); + if (!ret) + { + WARN("missing PhotometricInterpretation tag\n"); + return E_FAIL; + } + + ret = TIFFGetField(tiff, TIFFTAG_BITSPERSAMPLE, &bps); + if (!ret) bps = 1; + decode_info->bps = bps; + + ret = TIFFGetField(tiff, TIFFTAG_SAMPLESPERPIXEL, &samples); + if (!ret) samples = 1; + decode_info->samples = samples; + + if (samples == 1) + planar = 1; + else + { + ret = TIFFGetField(tiff, TIFFTAG_PLANARCONFIG, &planar); + if (!ret) planar = 1; + if (planar != 1) + { + FIXME("unhandled planar configuration %u\n", planar); + return E_FAIL; + } + } + decode_info->planar = planar; + + TRACE("planar %u, photometric %u, samples %u, bps %u\n", planar, photometric, samples, bps); + + switch(photometric) + { + case 0: /* WhiteIsZero */ + decode_info->invert_grayscale = 1; + /* fall through */ + case 1: /* BlackIsZero */ + if (samples == 2) + { + ret = TIFFGetField(tiff, TIFFTAG_EXTRASAMPLES, &extra_sample_count, &extra_samples); + if (!ret) + { + extra_sample_count = 1; + extra_sample = 0; + extra_samples = &extra_sample; + } + } + else if (samples != 1) + { + FIXME("unhandled %dbpp sample count %u\n", bps, samples); + return E_FAIL; + } + + decode_info->frame.bpp = bps * samples; + decode_info->source_bpp = decode_info->frame.bpp; + switch (bps) + { + case 1: + if (samples != 1) + { + FIXME("unhandled 1bpp sample count %u\n", samples); + return E_FAIL; + } + decode_info->frame.pixel_format = GUID_WICPixelFormatBlackWhite; + break; + case 4: + if (samples != 1) + { + FIXME("unhandled 4bpp grayscale sample count %u\n", samples); + return E_FAIL; + } + decode_info->frame.pixel_format = GUID_WICPixelFormat4bppGray; + break; + case 8: + if (samples == 1) + decode_info->frame.pixel_format = GUID_WICPixelFormat8bppGray; + else + { + decode_info->frame.bpp = 32; + + switch(extra_samples[0]) + { + case 1: /* Associated (pre-multiplied) alpha data */ + decode_info->frame.pixel_format = GUID_WICPixelFormat32bppPBGRA; + break; + case 0: /* Unspecified data */ + case 2: /* Unassociated alpha data */ + decode_info->frame.pixel_format = GUID_WICPixelFormat32bppBGRA; + break; + default: + FIXME("unhandled extra sample type %u\n", extra_samples[0]); + return E_FAIL; + } + } + break; + case 16: + if (samples != 1) + { + FIXME("unhandled 16bpp grayscale sample count %u\n", samples); + return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; + } + decode_info->frame.pixel_format = GUID_WICPixelFormat16bppGray; + break; + case 32: + if (samples != 1) + { + FIXME("unhandled 32bpp grayscale sample count %u\n", samples); + return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; + } + decode_info->frame.pixel_format = GUID_WICPixelFormat32bppGrayFloat; + break; + default: + WARN("unhandled greyscale bit count %u\n", bps); + return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; + } + break; + case 2: /* RGB */ + if (samples == 4) + { + ret = TIFFGetField(tiff, TIFFTAG_EXTRASAMPLES, &extra_sample_count, &extra_samples); + if (!ret) + { + extra_sample_count = 1; + extra_sample = 0; + extra_samples = &extra_sample; + } + } + else if (samples != 3) + { + FIXME("unhandled RGB sample count %u\n", samples); + return E_FAIL; + } + + decode_info->frame.bpp = max(bps, 8) * samples; + decode_info->source_bpp = bps * samples; + switch(bps) + { + case 1: + case 4: + case 8: + decode_info->reverse_bgr = 1; + if (samples == 3) + decode_info->frame.pixel_format = GUID_WICPixelFormat24bppBGR; + else + switch(extra_samples[0]) + { + case 1: /* Associated (pre-multiplied) alpha data */ + decode_info->frame.pixel_format = GUID_WICPixelFormat32bppPBGRA; + break; + case 0: /* Unspecified data */ + case 2: /* Unassociated alpha data */ + decode_info->frame.pixel_format = GUID_WICPixelFormat32bppBGRA; + break; + default: + FIXME("unhandled extra sample type %i\n", extra_samples[0]); + return E_FAIL; + } + break; + case 16: + if (samples == 3) + decode_info->frame.pixel_format = GUID_WICPixelFormat48bppRGB; + else + switch(extra_samples[0]) + { + case 1: /* Associated (pre-multiplied) alpha data */ + decode_info->frame.pixel_format = GUID_WICPixelFormat64bppPRGBA; + break; + case 0: /* Unspecified data */ + case 2: /* Unassociated alpha data */ + decode_info->frame.pixel_format = GUID_WICPixelFormat64bppRGBA; + break; + default: + FIXME("unhandled extra sample type %i\n", extra_samples[0]); + return E_FAIL; + } + break; + case 32: + if (samples == 3) + decode_info->frame.pixel_format = GUID_WICPixelFormat96bppRGBFloat; + else + switch(extra_samples[0]) + { + case 1: /* Associated (pre-multiplied) alpha data */ + decode_info->frame.pixel_format = GUID_WICPixelFormat128bppPRGBAFloat; + break; + case 0: /* Unspecified data */ + case 2: /* Unassociated alpha data */ + decode_info->frame.pixel_format = GUID_WICPixelFormat128bppRGBAFloat; + break; + default: + FIXME("unhandled extra sample type %i\n", extra_samples[0]); + return E_FAIL; + } + break; + default: + WARN("unhandled RGB bit count %u\n", bps); + return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; + } + break; + case 3: /* RGB Palette */ + if (samples != 1) + { + FIXME("unhandled indexed sample count %u\n", samples); + return E_FAIL; + } + + decode_info->indexed = 1; + decode_info->frame.bpp = bps; + switch (bps) + { + case 1: + decode_info->frame.pixel_format = GUID_WICPixelFormat1bppIndexed; + break; + case 2: + decode_info->frame.pixel_format = GUID_WICPixelFormat2bppIndexed; + break; + case 4: + decode_info->frame.pixel_format = GUID_WICPixelFormat4bppIndexed; + break; + case 8: + decode_info->frame.pixel_format = GUID_WICPixelFormat8bppIndexed; + break; + default: + FIXME("unhandled indexed bit count %u\n", bps); + return E_NOTIMPL; + } + break; + + case 5: /* Separated */ + if (samples != 4) + { + FIXME("unhandled Separated sample count %u\n", samples); + return E_FAIL; + } + + decode_info->frame.bpp = bps * samples; + switch(bps) + { + case 8: + decode_info->frame.pixel_format = GUID_WICPixelFormat32bppCMYK; + break; + case 16: + decode_info->frame.pixel_format = GUID_WICPixelFormat64bppCMYK; + break; + + default: + WARN("unhandled Separated bit count %u\n", bps); + return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; + } + break; + + case 4: /* Transparency mask */ + case 6: /* YCbCr */ + case 8: /* CIELab */ + default: + FIXME("unhandled PhotometricInterpretation %u\n", photometric); + return E_FAIL; + } + + ret = TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &decode_info->frame.width); + if (!ret) + { + WARN("missing image width\n"); + return E_FAIL; + } + + ret = TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &decode_info->frame.height); + if (!ret) + { + WARN("missing image length\n"); + return E_FAIL; + } + + if ((ret = TIFFGetField(tiff, TIFFTAG_TILEWIDTH, &decode_info->tile_width))) + { + decode_info->tiled = 1; + + ret = TIFFGetField(tiff, TIFFTAG_TILELENGTH, &decode_info->tile_height); + if (!ret) + { + WARN("missing tile height\n"); + return E_FAIL; + } + + decode_info->tile_stride = ((decode_info->frame.bpp * decode_info->tile_width + 7)/8); + decode_info->tile_size = decode_info->tile_height * decode_info->tile_stride; + decode_info->tiles_across = (decode_info->frame.width + decode_info->tile_width - 1) / decode_info->tile_width; + } + else if ((ret = TIFFGetField(tiff, TIFFTAG_ROWSPERSTRIP, &decode_info->tile_height))) + { + if (decode_info->tile_height > decode_info->frame.height) + decode_info->tile_height = decode_info->frame.height; + decode_info->tile_width = decode_info->frame.width; + decode_info->tile_stride = ((decode_info->frame.bpp * decode_info->tile_width + 7)/8); + decode_info->tile_size = decode_info->tile_height * decode_info->tile_stride; + } + else + { + /* Some broken TIFF files have a single strip and lack the RowsPerStrip tag */ + decode_info->tile_height = decode_info->frame.height; + decode_info->tile_width = decode_info->frame.width; + decode_info->tile_stride = ((decode_info->frame.bpp * decode_info->tile_width + 7)/8); + decode_info->tile_size = decode_info->tile_height * decode_info->tile_stride; + } + + resolution_unit = 0; + TIFFGetField(tiff, TIFFTAG_RESOLUTIONUNIT, &resolution_unit); + + ret = TIFFGetField(tiff, TIFFTAG_XRESOLUTION, &xres); + if (!ret) + { + WARN("missing X resolution\n"); + } + /* Emulate the behavior of current libtiff versions (libtiff commit a39f6131) + * yielding 0 instead of INFINITY for IFD_RATIONAL fields with denominator 0. */ + if (!isfinite(xres)) + { + xres = 0.0; + } + + ret = TIFFGetField(tiff, TIFFTAG_YRESOLUTION, &yres); + if (!ret) + { + WARN("missing Y resolution\n"); + } + if (!isfinite(yres)) + { + yres = 0.0; + } + + if (xres == 0.0 || yres == 0.0) + { + decode_info->frame.dpix = decode_info->frame.dpiy = 96.0; + } + else + { + switch (resolution_unit) + { + default: + FIXME("unknown resolution unit %i\n", resolution_unit); + /* fall through */ + case 0: /* Not set */ + case 1: /* Relative measurements */ + case 2: /* Inch */ + decode_info->frame.dpix = xres; + decode_info->frame.dpiy = yres; + break; + case 3: /* Centimeter */ + decode_info->frame.dpix = xres * 2.54; + decode_info->frame.dpiy = yres * 2.54; + break; + } + } + + if (decode_info->indexed && + TIFFGetField(tiff, TIFFTAG_COLORMAP, &red, &green, &blue)) + { + decode_info->frame.num_colors = 1 << decode_info->bps; + for (i=0; iframe.num_colors; i++) + { + decode_info->frame.palette[i] = 0xff000000 | + ((red[i]<<8) & 0xff0000) | + (green[i] & 0xff00) | + ((blue[i]>>8) & 0xff); + } + } + else + { + decode_info->frame.num_colors = 0; + } + + if (TIFFGetField(tiff, TIFFTAG_ICCPROFILE, &len, &profile)) + decode_info->frame.num_color_contexts = 1; + else + decode_info->frame.num_color_contexts = 0; + + return S_OK; +} + +static HRESULT CDECL tiff_decoder_initialize(struct decoder* iface, IStream *stream, struct decoder_stat *st) +{ + struct tiff_decoder *This = impl_from_decoder(iface); + HRESULT hr; + + This->tiff = tiff_open_stream(stream, "r"); + if (!This->tiff) + return E_FAIL; + + This->frame_count = TIFFNumberOfDirectories(This->tiff); + This->cached_frame = 0; + hr = tiff_get_decode_info(This->tiff, &This->cached_decode_info); + if (FAILED(hr)) + goto fail; + + st->frame_count = This->frame_count; + st->flags = WICBitmapDecoderCapabilityCanDecodeAllImages | + WICBitmapDecoderCapabilityCanDecodeSomeImages | + WICBitmapDecoderCapabilityCanEnumerateMetadata; + return S_OK; + +fail: + TIFFClose(This->tiff); + This->tiff = NULL; + return hr; +} + +static HRESULT tiff_decoder_select_frame(struct tiff_decoder* This, DWORD frame) +{ + HRESULT hr; + UINT prev_tile_size; + int res; + + if (frame >= This->frame_count) + return E_INVALIDARG; + + if (This->cached_frame == frame) + return S_OK; + + prev_tile_size = This->cached_tile ? This->cached_decode_info.tile_size : 0; + + res = TIFFSetDirectory(This->tiff, frame); + if (!res) + return E_INVALIDARG; + + hr = tiff_get_decode_info(This->tiff, &This->cached_decode_info); + + This->cached_tile_x = -1; + + if (SUCCEEDED(hr)) + { + This->cached_frame = frame; + if (This->cached_decode_info.tile_size > prev_tile_size) + { + free(This->cached_tile); + This->cached_tile = NULL; + } + } + else + { + /* Set an invalid value to ensure we'll refresh cached_decode_info before using it. */ + This->cached_frame = This->frame_count; + free(This->cached_tile); + This->cached_tile = NULL; + } + + return hr; +} + +static HRESULT CDECL tiff_decoder_get_frame_info(struct decoder* iface, UINT frame, struct decoder_frame *info) +{ + struct tiff_decoder *This = impl_from_decoder(iface); + HRESULT hr; + + hr = tiff_decoder_select_frame(This, frame); + if (SUCCEEDED(hr)) + { + *info = This->cached_decode_info.frame; + } + + return hr; +} + +static HRESULT tiff_decoder_read_tile(struct tiff_decoder *This, UINT tile_x, UINT tile_y) +{ + tsize_t ret; + int swap_bytes; + tiff_decode_info *info = &This->cached_decode_info; + + swap_bytes = TIFFIsByteSwapped(This->tiff); + + if (info->tiled) + ret = TIFFReadEncodedTile(This->tiff, tile_x + tile_y * info->tiles_across, This->cached_tile, info->tile_size); + else + ret = TIFFReadEncodedStrip(This->tiff, tile_y, This->cached_tile, info->tile_size); + + if (ret == -1) + return E_FAIL; + + /* 3bps RGB */ + if (info->source_bpp == 3 && info->samples == 3 && info->frame.bpp == 24) + { + BYTE *srcdata, *src, *dst; + DWORD x, y, count, width_bytes = (info->tile_width * 3 + 7) / 8; + + count = width_bytes * info->tile_height; + + srcdata = malloc(count); + if (!srcdata) return E_OUTOFMEMORY; + memcpy(srcdata, This->cached_tile, count); + + for (y = 0; y < info->tile_height; y++) + { + src = srcdata + y * width_bytes; + dst = This->cached_tile + y * info->tile_width * 3; + + for (x = 0; x < info->tile_width; x += 8) + { + dst[2] = (src[0] & 0x80) ? 0xff : 0; /* R */ + dst[1] = (src[0] & 0x40) ? 0xff : 0; /* G */ + dst[0] = (src[0] & 0x20) ? 0xff : 0; /* B */ + if (x + 1 < info->tile_width) + { + dst[5] = (src[0] & 0x10) ? 0xff : 0; /* R */ + dst[4] = (src[0] & 0x08) ? 0xff : 0; /* G */ + dst[3] = (src[0] & 0x04) ? 0xff : 0; /* B */ + } + if (x + 2 < info->tile_width) + { + dst[8] = (src[0] & 0x02) ? 0xff : 0; /* R */ + dst[7] = (src[0] & 0x01) ? 0xff : 0; /* G */ + dst[6] = (src[1] & 0x80) ? 0xff : 0; /* B */ + } + if (x + 3 < info->tile_width) + { + dst[11] = (src[1] & 0x40) ? 0xff : 0; /* R */ + dst[10] = (src[1] & 0x20) ? 0xff : 0; /* G */ + dst[9] = (src[1] & 0x10) ? 0xff : 0; /* B */ + } + if (x + 4 < info->tile_width) + { + dst[14] = (src[1] & 0x08) ? 0xff : 0; /* R */ + dst[13] = (src[1] & 0x04) ? 0xff : 0; /* G */ + dst[12] = (src[1] & 0x02) ? 0xff : 0; /* B */ + } + if (x + 5 < info->tile_width) + { + dst[17] = (src[1] & 0x01) ? 0xff : 0; /* R */ + dst[16] = (src[2] & 0x80) ? 0xff : 0; /* G */ + dst[15] = (src[2] & 0x40) ? 0xff : 0; /* B */ + } + if (x + 6 < info->tile_width) + { + dst[20] = (src[2] & 0x20) ? 0xff : 0; /* R */ + dst[19] = (src[2] & 0x10) ? 0xff : 0; /* G */ + dst[18] = (src[2] & 0x08) ? 0xff : 0; /* B */ + } + if (x + 7 < info->tile_width) + { + dst[23] = (src[2] & 0x04) ? 0xff : 0; /* R */ + dst[22] = (src[2] & 0x02) ? 0xff : 0; /* G */ + dst[21] = (src[2] & 0x01) ? 0xff : 0; /* B */ + } + src += 3; + dst += 24; + } + } + + free(srcdata); + } + /* 12bps RGB */ + else if (info->source_bpp == 12 && info->samples == 3 && info->frame.bpp == 24) + { + BYTE *srcdata, *src, *dst; + DWORD x, y, count, width_bytes = (info->tile_width * 12 + 7) / 8; + + count = width_bytes * info->tile_height; + + srcdata = malloc(count); + if (!srcdata) return E_OUTOFMEMORY; + memcpy(srcdata, This->cached_tile, count); + + for (y = 0; y < info->tile_height; y++) + { + src = srcdata + y * width_bytes; + dst = This->cached_tile + y * info->tile_width * 3; + + for (x = 0; x < info->tile_width; x += 2) + { + dst[0] = ((src[1] & 0xf0) >> 4) * 17; /* B */ + dst[1] = (src[0] & 0x0f) * 17; /* G */ + dst[2] = ((src[0] & 0xf0) >> 4) * 17; /* R */ + if (x + 1 < info->tile_width) + { + dst[5] = (src[1] & 0x0f) * 17; /* B */ + dst[4] = ((src[2] & 0xf0) >> 4) * 17; /* G */ + dst[3] = (src[2] & 0x0f) * 17; /* R */ + } + src += 3; + dst += 6; + } + } + + free(srcdata); + } + /* 4bps RGBA */ + else if (info->source_bpp == 4 && info->samples == 4 && info->frame.bpp == 32) + { + BYTE *srcdata, *src, *dst; + DWORD x, y, count, width_bytes = (info->tile_width * 3 + 7) / 8; + + count = width_bytes * info->tile_height; + + srcdata = malloc(count); + if (!srcdata) return E_OUTOFMEMORY; + memcpy(srcdata, This->cached_tile, count); + + for (y = 0; y < info->tile_height; y++) + { + src = srcdata + y * width_bytes; + dst = This->cached_tile + y * info->tile_width * 4; + + /* 1 source byte expands to 2 BGRA samples */ + + for (x = 0; x < info->tile_width; x += 2) + { + dst[0] = (src[0] & 0x20) ? 0xff : 0; /* B */ + dst[1] = (src[0] & 0x40) ? 0xff : 0; /* G */ + dst[2] = (src[0] & 0x80) ? 0xff : 0; /* R */ + dst[3] = (src[0] & 0x10) ? 0xff : 0; /* A */ + if (x + 1 < info->tile_width) + { + dst[4] = (src[0] & 0x02) ? 0xff : 0; /* B */ + dst[5] = (src[0] & 0x04) ? 0xff : 0; /* G */ + dst[6] = (src[0] & 0x08) ? 0xff : 0; /* R */ + dst[7] = (src[0] & 0x01) ? 0xff : 0; /* A */ + } + src++; + dst += 8; + } + } + + free(srcdata); + } + /* 16bps RGBA */ + else if (info->source_bpp == 16 && info->samples == 4 && info->frame.bpp == 32) + { + BYTE *srcdata, *src, *dst; + DWORD x, y, count, width_bytes = (info->tile_width * 12 + 7) / 8; + + count = width_bytes * info->tile_height; + + srcdata = malloc(count); + if (!srcdata) return E_OUTOFMEMORY; + memcpy(srcdata, This->cached_tile, count); + + for (y = 0; y < info->tile_height; y++) + { + src = srcdata + y * width_bytes; + dst = This->cached_tile + y * info->tile_width * 4; + + for (x = 0; x < info->tile_width; x++) + { + dst[0] = ((src[1] & 0xf0) >> 4) * 17; /* B */ + dst[1] = (src[0] & 0x0f) * 17; /* G */ + dst[2] = ((src[0] & 0xf0) >> 4) * 17; /* R */ + dst[3] = (src[1] & 0x0f) * 17; /* A */ + src += 2; + dst += 4; + } + } + + free(srcdata); + } + /* 8bpp grayscale with extra alpha */ + else if (info->source_bpp == 16 && info->samples == 2 && info->frame.bpp == 32) + { + BYTE *src; + DWORD *dst, count = info->tile_width * info->tile_height; + + src = This->cached_tile + info->tile_width * info->tile_height * 2 - 2; + dst = (DWORD *)(This->cached_tile + info->tile_size - 4); + + while (count--) + { + *dst-- = src[0] | (src[0] << 8) | (src[0] << 16) | (src[1] << 24); + src -= 2; + } + } + + if (info->reverse_bgr) + { + if (info->bps == 8) + { + UINT sample_count = info->samples; + + reverse_bgr8(sample_count, This->cached_tile, info->tile_width, + info->tile_height, info->tile_width * sample_count); + } + } + + if (swap_bytes && info->bps > 8) + { + UINT row, i, samples_per_row; + BYTE *sample, temp; + + samples_per_row = info->tile_width * info->samples; + + switch(info->bps) + { + case 16: + for (row=0; rowtile_height; row++) + { + sample = This->cached_tile + row * info->tile_stride; + for (i=0; ibps); + return E_FAIL; + } + } + + if (info->invert_grayscale) + { + BYTE *byte, *end; + + if (info->samples != 1) + { + ERR("cannot invert grayscale image with %u samples\n", info->samples); + return E_FAIL; + } + + end = This->cached_tile+info->tile_size; + + for (byte = This->cached_tile; byte != end; byte++) + *byte = ~(*byte); + } + + This->cached_tile_x = tile_x; + This->cached_tile_y = tile_y; + + return S_OK; +} + +static HRESULT CDECL tiff_decoder_copy_pixels(struct decoder* iface, UINT frame, + const WICRect *prc, UINT stride, UINT buffersize, BYTE *buffer) +{ + struct tiff_decoder *This = impl_from_decoder(iface); + HRESULT hr; + UINT min_tile_x, max_tile_x, min_tile_y, max_tile_y; + UINT tile_x, tile_y; + BYTE *dst_tilepos; + WICRect rc; + tiff_decode_info *info = &This->cached_decode_info; + + hr = tiff_decoder_select_frame(This, frame); + if (FAILED(hr)) + return hr; + + if (!This->cached_tile) + { + This->cached_tile = malloc(info->tile_size); + if (!This->cached_tile) + return E_OUTOFMEMORY; + } + + min_tile_x = prc->X / info->tile_width; + min_tile_y = prc->Y / info->tile_height; + max_tile_x = (prc->X+prc->Width-1) / info->tile_width; + max_tile_y = (prc->Y+prc->Height-1) / info->tile_height; + + for (tile_x=min_tile_x; tile_x <= max_tile_x; tile_x++) + { + for (tile_y=min_tile_y; tile_y <= max_tile_y; tile_y++) + { + if (tile_x != This->cached_tile_x || tile_y != This->cached_tile_y) + { + hr = tiff_decoder_read_tile(This, tile_x, tile_y); + } + + if (SUCCEEDED(hr)) + { + if (prc->X < tile_x * info->tile_width) + rc.X = 0; + else + rc.X = prc->X - tile_x * info->tile_width; + + if (prc->Y < tile_y * info->tile_height) + rc.Y = 0; + else + rc.Y = prc->Y - tile_y * info->tile_height; + + if (prc->X+prc->Width > (tile_x+1) * info->tile_width) + rc.Width = info->tile_width - rc.X; + else if (prc->X < tile_x * info->tile_width) + rc.Width = prc->Width + prc->X - tile_x * info->tile_width; + else + rc.Width = prc->Width; + + if (prc->Y+prc->Height > (tile_y+1) * info->tile_height) + rc.Height = info->tile_height - rc.Y; + else if (prc->Y < tile_y * info->tile_height) + rc.Height = prc->Height + prc->Y - tile_y * info->tile_height; + else + rc.Height = prc->Height; + + dst_tilepos = buffer + (stride * ((rc.Y + tile_y * info->tile_height) - prc->Y)) + + ((info->frame.bpp * ((rc.X + tile_x * info->tile_width) - prc->X) + 7) / 8); + + hr = copy_pixels(info->frame.bpp, This->cached_tile, + info->tile_width, info->tile_height, info->tile_stride, + &rc, stride, buffersize, dst_tilepos); + } + + if (FAILED(hr)) + { + TRACE("<-- 0x%lx\n", hr); + return hr; + } + } + } + + return S_OK; +} + +static HRESULT CDECL tiff_decoder_get_color_context(struct decoder *iface, + UINT frame, UINT num, BYTE **data, DWORD *datasize) +{ + struct tiff_decoder *This = impl_from_decoder(iface); + const BYTE *profile; + UINT len; + HRESULT hr; + + hr = tiff_decoder_select_frame(This, frame); + if (FAILED(hr)) + return hr; + + if (!TIFFGetField(This->tiff, TIFFTAG_ICCPROFILE, &len, &profile)) + { + return E_UNEXPECTED; + } + + *datasize = len; + *data = malloc(len); + if (!*data) + return E_OUTOFMEMORY; + + memcpy(*data, profile, len); + + return S_OK; +} + +static HRESULT CDECL tiff_decoder_get_metadata_blocks(struct decoder *iface, + UINT frame, UINT *count, struct decoder_block **blocks) +{ + struct tiff_decoder *This = impl_from_decoder(iface); + HRESULT hr; + BOOL byte_swapped; + struct decoder_block result; + + hr = tiff_decoder_select_frame(This, frame); + if (FAILED(hr)) + return hr; + + *count = 1; + + result.offset = TIFFCurrentDirOffset(This->tiff); + result.length = 0; + + byte_swapped = TIFFIsByteSwapped(This->tiff); +#ifdef WORDS_BIGENDIAN + result.options = byte_swapped ? WICPersistOptionLittleEndian : WICPersistOptionBigEndian; +#else + result.options = byte_swapped ? WICPersistOptionBigEndian : WICPersistOptionLittleEndian; +#endif + result.options |= WICPersistOptionNoCacheStream|DECODER_BLOCK_FULL_STREAM|DECODER_BLOCK_READER_CLSID; + result.reader_clsid = CLSID_WICIfdMetadataReader; + + *blocks = malloc(sizeof(**blocks)); + **blocks = result; + + return S_OK; +} + +static void CDECL tiff_decoder_destroy(struct decoder* iface) +{ + struct tiff_decoder *This = impl_from_decoder(iface); + if (This->tiff) TIFFClose(This->tiff); + free(This->cached_tile); + free(This); +} + +static const struct decoder_funcs tiff_decoder_vtable = { + tiff_decoder_initialize, + tiff_decoder_get_frame_info, + tiff_decoder_copy_pixels, + tiff_decoder_get_metadata_blocks, + tiff_decoder_get_color_context, + tiff_decoder_destroy +}; + +HRESULT CDECL tiff_decoder_create(struct decoder_info *info, struct decoder **result) +{ + struct tiff_decoder *This; + + This = malloc(sizeof(*This)); + if (!This) return E_OUTOFMEMORY; + + This->decoder.vtable = &tiff_decoder_vtable; + This->tiff = NULL; + This->cached_tile = NULL; + This->cached_tile_x = -1; + *result = &This->decoder; + + info->container_format = GUID_ContainerFormatTiff; + info->block_format = GUID_ContainerFormatTiff; + info->clsid = CLSID_WICTiffDecoder; + + TIFFSetErrorHandler( tiff_error_handler ); + TIFFSetWarningHandler( tiff_warning_handler ); + return S_OK; +} + +struct tiff_encode_format { + const WICPixelFormatGUID *guid; + int photometric; + int bps; + int samples; + int bpp; + int extra_sample; + int extra_sample_type; + int reverse_bgr; + int indexed; +}; + +static const struct tiff_encode_format formats[] = { + {&GUID_WICPixelFormat24bppBGR, 2, 8, 3, 24, 0, 0, 1}, + {&GUID_WICPixelFormat24bppRGB, 2, 8, 3, 24, 0, 0, 0}, + {&GUID_WICPixelFormatBlackWhite, 1, 1, 1, 1, 0, 0, 0}, + {&GUID_WICPixelFormat4bppGray, 1, 4, 1, 4, 0, 0, 0}, + {&GUID_WICPixelFormat8bppGray, 1, 8, 1, 8, 0, 0, 0}, + {&GUID_WICPixelFormat32bppBGRA, 2, 8, 4, 32, 1, 2, 1}, + {&GUID_WICPixelFormat32bppPBGRA, 2, 8, 4, 32, 1, 1, 1}, + {&GUID_WICPixelFormat48bppRGB, 2, 16, 3, 48, 0, 0, 0}, + {&GUID_WICPixelFormat64bppRGBA, 2, 16, 4, 64, 1, 2, 0}, + {&GUID_WICPixelFormat64bppPRGBA, 2, 16, 4, 64, 1, 1, 0}, + {&GUID_WICPixelFormat1bppIndexed, 3, 1, 1, 1, 0, 0, 0, 1}, + {&GUID_WICPixelFormat4bppIndexed, 3, 4, 1, 4, 0, 0, 0, 1}, + {&GUID_WICPixelFormat8bppIndexed, 3, 8, 1, 8, 0, 0, 0, 1}, + {0} +}; + +typedef struct tiff_encoder { + struct encoder encoder; + TIFF *tiff; + const struct tiff_encode_format *format; + struct encoder_frame encoder_frame; + DWORD num_frames; + DWORD lines_written; +} tiff_encoder; + +static inline struct tiff_encoder *impl_from_encoder(struct encoder* iface) +{ + return CONTAINING_RECORD(iface, struct tiff_encoder, encoder); +} + +static HRESULT CDECL tiff_encoder_initialize(struct encoder* iface, IStream *stream) +{ + struct tiff_encoder* This = impl_from_encoder(iface); + TIFF *tiff; + + tiff = tiff_open_stream(stream, "w"); + + if (!tiff) + return E_FAIL; + + This->tiff = tiff; + + return S_OK; +} + +static HRESULT CDECL tiff_encoder_get_supported_format(struct encoder *iface, + GUID *pixel_format, DWORD *bpp, BOOL *indexed) +{ + int i; + + if (IsEqualGUID(pixel_format, &GUID_WICPixelFormat2bppIndexed)) + *pixel_format = GUID_WICPixelFormat4bppIndexed; + + for (i=0; formats[i].guid; i++) + { + if (IsEqualGUID(formats[i].guid, pixel_format)) + break; + } + + if (!formats[i].guid) i = 0; + + *pixel_format = *formats[i].guid; + *bpp = formats[i].bpp; + *indexed = formats[i].indexed; + + return S_OK; +} + +static HRESULT CDECL tiff_encoder_create_frame(struct encoder* iface, const struct encoder_frame *frame) +{ + struct tiff_encoder* This = impl_from_encoder(iface); + int i; + + if (This->num_frames != 0) + TIFFWriteDirectory(This->tiff); + + This->num_frames++; + This->lines_written = 0; + This->encoder_frame = *frame; + + for (i=0; formats[i].guid; i++) + { + if (IsEqualGUID(formats[i].guid, &frame->pixel_format)) + break; + } + + This->format = &formats[i]; + + TIFFSetField(This->tiff, TIFFTAG_PHOTOMETRIC, (uint16_t)This->format->photometric); + TIFFSetField(This->tiff, TIFFTAG_PLANARCONFIG, (uint16_t)1); + TIFFSetField(This->tiff, TIFFTAG_BITSPERSAMPLE, (uint16_t)This->format->bps); + TIFFSetField(This->tiff, TIFFTAG_SAMPLESPERPIXEL, (uint16_t)This->format->samples); + + if (This->format->extra_sample) + { + uint16_t extra_samples; + extra_samples = This->format->extra_sample_type; + + TIFFSetField(This->tiff, TIFFTAG_EXTRASAMPLES, (uint16_t)1, &extra_samples); + } + + TIFFSetField(This->tiff, TIFFTAG_IMAGEWIDTH, (uint32_t)frame->width); + TIFFSetField(This->tiff, TIFFTAG_IMAGELENGTH, (uint32_t)frame->height); + + if (frame->dpix != 0.0 && frame->dpiy != 0.0) + { + TIFFSetField(This->tiff, TIFFTAG_RESOLUTIONUNIT, (uint16_t)2); /* Inch */ + TIFFSetField(This->tiff, TIFFTAG_XRESOLUTION, (float)frame->dpix); + TIFFSetField(This->tiff, TIFFTAG_YRESOLUTION, (float)frame->dpiy); + } + + if (This->format->bpp <= 8 && frame->num_colors && This->format->indexed) + { + uint16_t red[256], green[256], blue[256]; + UINT i; + + for (i = 0; i < frame->num_colors; i++) + { + red[i] = (frame->palette[i] >> 8) & 0xff00; + green[i] = frame->palette[i] & 0xff00; + blue[i] = (frame->palette[i] << 8) & 0xff00; + } + + TIFFSetField(This->tiff, TIFFTAG_COLORMAP, red, green, blue); + } + + return S_OK; +} + +static HRESULT CDECL tiff_encoder_write_lines(struct encoder* iface, + BYTE *data, DWORD line_count, DWORD stride) +{ + struct tiff_encoder* This = impl_from_encoder(iface); + BYTE *row_data, *swapped_data = NULL; + UINT i, j, line_size; + + line_size = ((This->encoder_frame.width * This->format->bpp)+7)/8; + + if (This->format->reverse_bgr) + { + swapped_data = malloc(line_size); + if (!swapped_data) + return E_OUTOFMEMORY; + } + + for (i=0; iformat->reverse_bgr && This->format->bps == 8) + { + memcpy(swapped_data, row_data, line_size); + for (j=0; jformat->samples) + { + BYTE temp; + temp = swapped_data[j]; + swapped_data[j] = swapped_data[j+2]; + swapped_data[j+2] = temp; + } + row_data = swapped_data; + } + + TIFFWriteScanline(This->tiff, (tdata_t)row_data, i+This->lines_written, 0); + } + + This->lines_written += line_count; + + return S_OK; +} + +static HRESULT CDECL tiff_encoder_commit_frame(struct encoder* iface) +{ + return S_OK; +} + +static HRESULT CDECL tiff_encoder_commit_file(struct encoder* iface) +{ + struct tiff_encoder* This = impl_from_encoder(iface); + + TIFFClose(This->tiff); + This->tiff = NULL; + + return S_OK; +} + +static void CDECL tiff_encoder_destroy(struct encoder* iface) +{ + struct tiff_encoder *This = impl_from_encoder(iface); + + if (This->tiff) TIFFClose(This->tiff); + free(This); +} + +static const struct encoder_funcs tiff_encoder_vtable = { + tiff_encoder_initialize, + tiff_encoder_get_supported_format, + tiff_encoder_create_frame, + tiff_encoder_write_lines, + tiff_encoder_commit_frame, + tiff_encoder_commit_file, + tiff_encoder_destroy +}; + +HRESULT CDECL tiff_encoder_create(struct encoder_info *info, struct encoder **result) +{ + struct tiff_encoder *This; + + This = malloc(sizeof(*This)); + if (!This) return E_OUTOFMEMORY; + + This->encoder.vtable = &tiff_encoder_vtable; + This->tiff = NULL; + This->num_frames = 0; + + info->flags = ENCODER_FLAGS_MULTI_FRAME | ENCODER_FLAGS_SUPPORTS_METADATA; + info->container_format = GUID_ContainerFormatTiff; + info->clsid = CLSID_WICTiffEncoder; + info->encoder_options[0] = ENCODER_OPTION_COMPRESSION_METHOD; + info->encoder_options[1] = ENCODER_OPTION_COMPRESSION_QUALITY; + info->encoder_options[2] = ENCODER_OPTION_END; + + *result = &This->encoder; + + TIFFSetErrorHandler( tiff_error_handler ); + TIFFSetWarningHandler( tiff_warning_handler ); + return S_OK; +} diff --git a/dll/win32/windowscodecs/main.c b/dll/win32/windowscodecs/main.c index 751f46251333e..aa542483c20f9 100644 --- a/dll/win32/windowscodecs/main.c +++ b/dll/win32/windowscodecs/main.c @@ -18,21 +18,21 @@ #define COBJMACROS -#include "config.h" #include #include "windef.h" #include "winbase.h" +#include "winternl.h" #include "objbase.h" #include "wincodecs_private.h" #include "wine/debug.h" -WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); +extern BOOL WINAPI WIC_DllMain(HINSTANCE, DWORD, LPVOID); -extern BOOL WINAPI WIC_DllMain(HINSTANCE, DWORD, LPVOID) DECLSPEC_HIDDEN; +HMODULE windowscodecs_module = 0; BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { @@ -41,8 +41,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hinstDLL); + windowscodecs_module = hinstDLL; break; case DLL_PROCESS_DETACH: + if (lpvReserved) break; ReleaseComponentInfos(); break; } @@ -50,225 +52,89 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) return WIC_DllMain(hinstDLL, fdwReason, lpvReserved); } +#ifdef __REACTOS__ HRESULT WINAPI DllCanUnloadNow(void) { return S_FALSE; } +#endif -HRESULT copy_pixels(UINT bpp, const BYTE *srcbuffer, - UINT srcwidth, UINT srcheight, INT srcstride, - const WICRect *rc, UINT dststride, UINT dstbuffersize, BYTE *dstbuffer) +HRESULT get_pixelformat_bpp(const GUID *pixelformat, UINT *bpp) { - UINT bytesperrow; - UINT row_offset; /* number of bits into the source rows where the data starts */ - WICRect rect; + HRESULT hr; + IWICComponentInfo *info; + IWICPixelFormatInfo *formatinfo; - if (!rc) - { - rect.X = 0; - rect.Y = 0; - rect.Width = srcwidth; - rect.Height = srcheight; - rc = ▭ - } - else + hr = CreateComponentInfo(pixelformat, &info); + if (SUCCEEDED(hr)) { - if (rc->X < 0 || rc->Y < 0 || rc->X+rc->Width > srcwidth || rc->Y+rc->Height > srcheight) - return E_INVALIDARG; - } - - bytesperrow = ((bpp * rc->Width)+7)/8; + hr = IWICComponentInfo_QueryInterface(info, &IID_IWICPixelFormatInfo, (void**)&formatinfo); - if (dststride < bytesperrow) - return E_INVALIDARG; + if (SUCCEEDED(hr)) + { + hr = IWICPixelFormatInfo_GetBitsPerPixel(formatinfo, bpp); - if ((dststride * (rc->Height-1)) + bytesperrow > dstbuffersize) - return E_INVALIDARG; + IWICPixelFormatInfo_Release(formatinfo); + } - /* if the whole bitmap is copied and the buffer format matches then it's a matter of a single memcpy */ - if (rc->X == 0 && rc->Y == 0 && rc->Width == srcwidth && rc->Height == srcheight && - srcstride == dststride && srcstride == bytesperrow) - { - memcpy(dstbuffer, srcbuffer, srcstride * srcheight); - return S_OK; + IWICComponentInfo_Release(info); } - row_offset = rc->X * bpp; - - if (row_offset % 8 == 0) - { - /* everything lines up on a byte boundary */ - INT row; - const BYTE *src; - BYTE *dst; - - src = srcbuffer + (row_offset / 8) + srcstride * rc->Y; - dst = dstbuffer; - for (row=0; row < rc->Height; row++) - { - memcpy(dst, src, bytesperrow); - src += srcstride; - dst += dststride; - } - return S_OK; - } - else - { - /* we have to do a weird bitwise copy. eww. */ - FIXME("cannot reliably copy bitmap data if bpp < 8\n"); - return E_FAIL; - } + return hr; } -HRESULT configure_write_source(IWICBitmapFrameEncode *iface, - IWICBitmapSource *source, const WICRect *prc, - const WICPixelFormatGUID *format, - INT width, INT height, double xres, double yres) +HRESULT TiffDecoder_CreateInstance(REFIID iid, void** ppv) { - HRESULT hr = S_OK; - - if (width == 0 || height == 0) - return WINCODEC_ERR_WRONGSTATE; - - if (!format) - { - WICPixelFormatGUID src_format; - - hr = IWICBitmapSource_GetPixelFormat(source, &src_format); - if (FAILED(hr)) return hr; + HRESULT hr; + struct decoder *decoder; + struct decoder_info decoder_info; - hr = IWICBitmapFrameEncode_SetPixelFormat(iface, &src_format); - if (FAILED(hr)) return hr; - } + hr = tiff_decoder_create(&decoder_info, &decoder); - if (xres == 0.0 || yres == 0.0) - { - hr = IWICBitmapSource_GetResolution(source, &xres, &yres); - if (FAILED(hr)) return hr; - hr = IWICBitmapFrameEncode_SetResolution(iface, xres, yres); - if (FAILED(hr)) return hr; - } + if (SUCCEEDED(hr)) + hr = CommonDecoder_CreateInstance(decoder, &decoder_info, iid, ppv); return hr; } -HRESULT write_source(IWICBitmapFrameEncode *iface, - IWICBitmapSource *source, const WICRect *prc, - const WICPixelFormatGUID *format, UINT bpp, - INT width, INT height) +HRESULT TiffEncoder_CreateInstance(REFIID iid, void** ppv) { - IWICBitmapSource *converted_source; - HRESULT hr=S_OK; - WICRect rc; - UINT stride; - BYTE* pixeldata; - - if (!prc) - { - UINT src_width, src_height; - hr = IWICBitmapSource_GetSize(source, &src_width, &src_height); - if (FAILED(hr)) return hr; - rc.X = 0; - rc.Y = 0; - rc.Width = src_width; - rc.Height = src_height; - prc = &rc; - } - - if (prc->Width != width || prc->Height <= 0) - return E_INVALIDARG; - - hr = WICConvertBitmapSource(format, source, &converted_source); - if (FAILED(hr)) - { - ERR("Failed to convert source, target format %s, %#x\n", debugstr_guid(format), hr); - return E_NOTIMPL; - } - - stride = (bpp * width + 7)/8; - - pixeldata = HeapAlloc(GetProcessHeap(), 0, stride * prc->Height); - if (!pixeldata) - { - IWICBitmapSource_Release(converted_source); - return E_OUTOFMEMORY; - } + HRESULT hr; + struct encoder *encoder; + struct encoder_info encoder_info; - hr = IWICBitmapSource_CopyPixels(converted_source, prc, stride, - stride*prc->Height, pixeldata); + hr = tiff_encoder_create(&encoder_info, &encoder); if (SUCCEEDED(hr)) - { - hr = IWICBitmapFrameEncode_WritePixels(iface, prc->Height, stride, - stride*prc->Height, pixeldata); - } - - HeapFree(GetProcessHeap(), 0, pixeldata); - IWICBitmapSource_Release(converted_source); + hr = CommonEncoder_CreateInstance(encoder, &encoder_info, iid, ppv); return hr; } -void reverse_bgr8(UINT bytesperpixel, LPBYTE bits, UINT width, UINT height, INT stride) +HRESULT JpegDecoder_CreateInstance(REFIID iid, void** ppv) { - UINT x, y; - BYTE *pixel, temp; - - for (y=0; y #include #define COBJMACROS -#define NONAMELESSUNION - #include "windef.h" #include "winbase.h" -#include "wine/winternl.h" +#include "winternl.h" #include "objbase.h" #include "propvarutil.h" @@ -41,6 +37,7 @@ typedef struct MetadataHandler { IWICMetadataWriter IWICMetadataWriter_iface; LONG ref; IWICPersistStream IWICPersistStream_iface; + IWICStreamProvider IWICStreamProvider_iface; const MetadataHandlerVtbl *vtable; MetadataItem *items; DWORD item_count; @@ -57,6 +54,11 @@ static inline MetadataHandler *impl_from_IWICPersistStream(IWICPersistStream *if return CONTAINING_RECORD(iface, MetadataHandler, IWICPersistStream_iface); } +static inline MetadataHandler *impl_from_IWICStreamProvider(IWICStreamProvider *iface) +{ + return CONTAINING_RECORD(iface, MetadataHandler, IWICStreamProvider_iface); +} + static void MetadataHandler_FreeItems(MetadataHandler *This) { DWORD i; @@ -68,7 +70,9 @@ static void MetadataHandler_FreeItems(MetadataHandler *This) PropVariantClear(&This->items[i].value); } - HeapFree(GetProcessHeap(), 0, This->items); + free(This->items); + This->items = NULL; + This->item_count = 0; } static HRESULT MetadataHandlerEnum_Create(MetadataHandler *parent, DWORD index, @@ -94,6 +98,10 @@ static HRESULT WINAPI MetadataHandler_QueryInterface(IWICMetadataWriter *iface, { *ppv = &This->IWICPersistStream_iface; } + else if (IsEqualIID(&IID_IWICStreamProvider, iid)) + { + *ppv = &This->IWICStreamProvider_iface; + } else { *ppv = NULL; @@ -109,7 +117,7 @@ static ULONG WINAPI MetadataHandler_AddRef(IWICMetadataWriter *iface) MetadataHandler *This = impl_from_IWICMetadataWriter(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -119,14 +127,14 @@ static ULONG WINAPI MetadataHandler_Release(IWICMetadataWriter *iface) MetadataHandler *This = impl_from_IWICMetadataWriter(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { MetadataHandler_FreeItems(This); This->lock.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&This->lock); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; @@ -349,19 +357,22 @@ static HRESULT WINAPI MetadataHandler_GetSizeMax(IWICPersistStream *iface, } static HRESULT WINAPI MetadataHandler_LoadEx(IWICPersistStream *iface, - IStream *pIStream, const GUID *pguidPreferredVendor, DWORD dwPersistOptions) + IStream *stream, const GUID *pguidPreferredVendor, DWORD dwPersistOptions) { MetadataHandler *This = impl_from_IWICPersistStream(iface); - HRESULT hr; + HRESULT hr = S_OK; MetadataItem *new_items=NULL; DWORD item_count=0; - TRACE("(%p,%p,%s,%x)\n", iface, pIStream, debugstr_guid(pguidPreferredVendor), dwPersistOptions); + TRACE("(%p,%p,%s,%lx)\n", iface, stream, debugstr_guid(pguidPreferredVendor), dwPersistOptions); EnterCriticalSection(&This->lock); - hr = This->vtable->fnLoad(pIStream, pguidPreferredVendor, dwPersistOptions, - &new_items, &item_count); + if (stream) + { + hr = This->vtable->fnLoad(stream, pguidPreferredVendor, dwPersistOptions, + &new_items, &item_count); + } if (SUCCEEDED(hr)) { @@ -378,7 +389,7 @@ static HRESULT WINAPI MetadataHandler_LoadEx(IWICPersistStream *iface, static HRESULT WINAPI MetadataHandler_SaveEx(IWICPersistStream *iface, IStream *pIStream, DWORD dwPersistOptions, BOOL fClearDirty) { - FIXME("(%p,%p,%x,%i): stub\n", iface, pIStream, dwPersistOptions, fClearDirty); + FIXME("(%p,%p,%lx,%i): stub\n", iface, pIStream, dwPersistOptions, fClearDirty); return E_NOTIMPL; } @@ -395,6 +406,63 @@ static const IWICPersistStreamVtbl MetadataHandler_PersistStream_Vtbl = { MetadataHandler_SaveEx }; +static HRESULT WINAPI metadatahandler_stream_provider_QueryInterface(IWICStreamProvider *iface, REFIID iid, void **ppv) +{ + MetadataHandler *handler = impl_from_IWICStreamProvider(iface); + return IWICMetadataWriter_QueryInterface(&handler->IWICMetadataWriter_iface, iid, ppv); +} + +static ULONG WINAPI metadatahandler_stream_provider_AddRef(IWICStreamProvider *iface) +{ + MetadataHandler *handler = impl_from_IWICStreamProvider(iface); + return IWICMetadataWriter_AddRef(&handler->IWICMetadataWriter_iface); +} + +static ULONG WINAPI metadatahandler_stream_provider_Release(IWICStreamProvider *iface) +{ + MetadataHandler *handler = impl_from_IWICStreamProvider(iface); + return IWICMetadataWriter_Release(&handler->IWICMetadataWriter_iface); +} + +static HRESULT WINAPI metadatahandler_stream_provider_GetStream(IWICStreamProvider *iface, IStream **stream) +{ + FIXME("%p, %p stub\n", iface, stream); + + return E_NOTIMPL; +} + +static HRESULT WINAPI metadatahandler_stream_provider_GetPersistOptions(IWICStreamProvider *iface, DWORD *options) +{ + FIXME("%p, %p stub\n", iface, options); + + return E_NOTIMPL; +} + +static HRESULT WINAPI metadatahandler_stream_provider_GetPreferredVendorGUID(IWICStreamProvider *iface, GUID *guid) +{ + FIXME("%p, %p stub\n", iface, guid); + + return E_NOTIMPL; +} + +static HRESULT WINAPI metadatahandler_stream_provider_RefreshStream(IWICStreamProvider *iface) +{ + FIXME("%p stub\n", iface); + + return E_NOTIMPL; +} + +static const IWICStreamProviderVtbl MetadataHandler_StreamProvider_Vtbl = +{ + metadatahandler_stream_provider_QueryInterface, + metadatahandler_stream_provider_AddRef, + metadatahandler_stream_provider_Release, + metadatahandler_stream_provider_GetStream, + metadatahandler_stream_provider_GetPersistOptions, + metadatahandler_stream_provider_GetPreferredVendorGUID, + metadatahandler_stream_provider_RefreshStream, +}; + HRESULT MetadataReader_Create(const MetadataHandlerVtbl *vtable, REFIID iid, void** ppv) { MetadataHandler *This; @@ -404,17 +472,22 @@ HRESULT MetadataReader_Create(const MetadataHandlerVtbl *vtable, REFIID iid, voi *ppv = NULL; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(MetadataHandler)); + This = malloc(sizeof(MetadataHandler)); if (!This) return E_OUTOFMEMORY; This->IWICMetadataWriter_iface.lpVtbl = &MetadataHandler_Vtbl; This->IWICPersistStream_iface.lpVtbl = &MetadataHandler_PersistStream_Vtbl; + This->IWICStreamProvider_iface.lpVtbl = &MetadataHandler_StreamProvider_Vtbl; This->ref = 1; This->vtable = vtable; This->items = NULL; This->item_count = 0; +#ifdef __REACTOS__ InitializeCriticalSection(&This->lock); +#else + InitializeCriticalSectionEx(&This->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": MetadataHandler.lock"); hr = IWICMetadataWriter_QueryInterface(&This->IWICMetadataWriter_iface, iid, ppv); @@ -464,7 +537,7 @@ static ULONG WINAPI MetadataHandlerEnum_AddRef(IWICEnumMetadataItem *iface) MetadataHandlerEnum *This = impl_from_IWICEnumMetadataItem(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -474,12 +547,12 @@ static ULONG WINAPI MetadataHandlerEnum_Release(IWICEnumMetadataItem *iface) MetadataHandlerEnum *This = impl_from_IWICEnumMetadataItem(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { IWICMetadataWriter_Release(&This->parent->IWICMetadataWriter_iface); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; @@ -493,8 +566,12 @@ static HRESULT WINAPI MetadataHandlerEnum_Next(IWICEnumMetadataItem *iface, ULONG new_index; HRESULT hr=S_FALSE; ULONG i; + ULONG fetched; + + TRACE("(%p,%li)\n", iface, celt); - TRACE("(%p,%i)\n", iface, celt); + if (!pceltFetched) + pceltFetched = &fetched; EnterCriticalSection(&This->parent->lock); @@ -594,7 +671,7 @@ static HRESULT MetadataHandlerEnum_Create(MetadataHandler *parent, DWORD index, *ppIEnumMetadataItem = NULL; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(MetadataHandlerEnum)); + This = malloc(sizeof(MetadataHandlerEnum)); if (!This) return E_OUTOFMEMORY; IWICMetadataWriter_AddRef(&parent->IWICMetadataWriter_iface); @@ -624,21 +701,21 @@ static HRESULT LoadUnknownMetadata(IStream *input, const GUID *preferred_vendor, if (FAILED(hr)) return hr; - data = HeapAlloc(GetProcessHeap(), 0, stat.cbSize.QuadPart); + data = CoTaskMemAlloc(stat.cbSize.QuadPart); if (!data) return E_OUTOFMEMORY; hr = IStream_Read(input, data, stat.cbSize.QuadPart, &bytesread); if (bytesread != stat.cbSize.QuadPart) hr = E_FAIL; if (hr != S_OK) { - HeapFree(GetProcessHeap(), 0, data); + CoTaskMemFree(data); return hr; } - result = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MetadataItem)); + result = calloc(1, sizeof(MetadataItem)); if (!result) { - HeapFree(GetProcessHeap(), 0, data); + CoTaskMemFree(data); return E_OUTOFMEMORY; } @@ -647,8 +724,8 @@ static HRESULT LoadUnknownMetadata(IStream *input, const GUID *preferred_vendor, PropVariantInit(&result[0].value); result[0].value.vt = VT_BLOB; - result[0].value.u.blob.cbSize = bytesread; - result[0].value.u.blob.pBlobData = data; + result[0].value.blob.cbSize = bytesread; + result[0].value.blob.pBlobData = data; *items = result; *item_count = 1; @@ -718,15 +795,15 @@ static int tag_to_vt(SHORT tag) static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, MetadataItem *item, BOOL native_byte_order) { - ULONG count, value, i; + ULONG count, value, i, bytesread; SHORT type; LARGE_INTEGER pos; HRESULT hr; item->schema.vt = VT_EMPTY; item->id.vt = VT_UI2; - item->id.u.uiVal = entry->id; - SWAP_USHORT(item->id.u.uiVal); + item->id.uiVal = entry->id; + SWAP_USHORT(item->id.uiVal); count = entry->count; SWAP_ULONG(count); @@ -747,33 +824,34 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, const BYTE *data = (const BYTE *)&entry->value; if (count == 1) - item->value.u.bVal = data[0]; + item->value.bVal = data[0]; else { item->value.vt |= VT_VECTOR; - item->value.u.caub.cElems = count; - item->value.u.caub.pElems = HeapAlloc(GetProcessHeap(), 0, count); - memcpy(item->value.u.caub.pElems, data, count); + item->value.caub.cElems = count; + item->value.caub.pElems = CoTaskMemAlloc(count); + memcpy(item->value.caub.pElems, data, count); } break; } item->value.vt |= VT_VECTOR; - item->value.u.caub.cElems = count; - item->value.u.caub.pElems = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count); - if (!item->value.u.caub.pElems) return E_OUTOFMEMORY; + item->value.caub.cElems = count; + item->value.caub.pElems = CoTaskMemAlloc(count); + if (!item->value.caub.pElems) return E_OUTOFMEMORY; pos.QuadPart = value; hr = IStream_Seek(input, pos, SEEK_SET, NULL); if (FAILED(hr)) { - HeapFree(GetProcessHeap(), 0, item->value.u.caub.pElems); + CoTaskMemFree(item->value.caub.pElems); return hr; } - hr = IStream_Read(input, item->value.u.caub.pElems, count, NULL); - if (FAILED(hr)) + hr = IStream_Read(input, item->value.caub.pElems, count, &bytesread); + if (bytesread != count) hr = E_FAIL; + if (hr != S_OK) { - HeapFree(GetProcessHeap(), 0, item->value.u.caub.pElems); + CoTaskMemFree(item->value.caub.pElems); return hr; } break; @@ -787,41 +865,42 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, if (count == 1) { - item->value.u.uiVal = data[0]; - SWAP_USHORT(item->value.u.uiVal); + item->value.uiVal = data[0]; + SWAP_USHORT(item->value.uiVal); } else { item->value.vt |= VT_VECTOR; - item->value.u.caui.cElems = count; - item->value.u.caui.pElems = HeapAlloc(GetProcessHeap(), 0, count * 2); - memcpy(item->value.u.caui.pElems, data, count * 2); + item->value.caui.cElems = count; + item->value.caui.pElems = CoTaskMemAlloc(count * 2); + memcpy(item->value.caui.pElems, data, count * 2); for (i = 0; i < count; i++) - SWAP_USHORT(item->value.u.caui.pElems[i]); + SWAP_USHORT(item->value.caui.pElems[i]); } break; } item->value.vt |= VT_VECTOR; - item->value.u.caui.cElems = count; - item->value.u.caui.pElems = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count * 2); - if (!item->value.u.caui.pElems) return E_OUTOFMEMORY; + item->value.caui.cElems = count; + item->value.caui.pElems = CoTaskMemAlloc(count * 2); + if (!item->value.caui.pElems) return E_OUTOFMEMORY; pos.QuadPart = value; hr = IStream_Seek(input, pos, SEEK_SET, NULL); if (FAILED(hr)) { - HeapFree(GetProcessHeap(), 0, item->value.u.caui.pElems); + CoTaskMemFree(item->value.caui.pElems); return hr; } - hr = IStream_Read(input, item->value.u.caui.pElems, count * 2, NULL); - if (FAILED(hr)) + hr = IStream_Read(input, item->value.caui.pElems, count * 2, &bytesread); + if (bytesread != count * 2) hr = E_FAIL; + if (hr != S_OK) { - HeapFree(GetProcessHeap(), 0, item->value.u.caui.pElems); + CoTaskMemFree(item->value.caui.pElems); return hr; } for (i = 0; i < count; i++) - SWAP_USHORT(item->value.u.caui.pElems[i]); + SWAP_USHORT(item->value.caui.pElems[i]); break; case IFD_LONG: case IFD_SLONG: @@ -830,30 +909,31 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, if (count == 1) { - item->value.u.ulVal = value; + item->value.ulVal = value; break; } item->value.vt |= VT_VECTOR; - item->value.u.caul.cElems = count; - item->value.u.caul.pElems = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count * 4); - if (!item->value.u.caul.pElems) return E_OUTOFMEMORY; + item->value.caul.cElems = count; + item->value.caul.pElems = CoTaskMemAlloc(count * 4); + if (!item->value.caul.pElems) return E_OUTOFMEMORY; pos.QuadPart = value; hr = IStream_Seek(input, pos, SEEK_SET, NULL); if (FAILED(hr)) { - HeapFree(GetProcessHeap(), 0, item->value.u.caul.pElems); + CoTaskMemFree(item->value.caul.pElems); return hr; } - hr = IStream_Read(input, item->value.u.caul.pElems, count * 4, NULL); - if (FAILED(hr)) + hr = IStream_Read(input, item->value.caul.pElems, count * 4, &bytesread); + if (bytesread != count * 4) hr = E_FAIL; + if (hr != S_OK) { - HeapFree(GetProcessHeap(), 0, item->value.u.caul.pElems); + CoTaskMemFree(item->value.caul.pElems); return hr; } for (i = 0; i < count; i++) - SWAP_ULONG(item->value.u.caul.pElems[i]); + SWAP_ULONG(item->value.caul.pElems[i]); break; case IFD_RATIONAL: case IFD_SRATIONAL: @@ -873,61 +953,63 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, hr = IStream_Seek(input, pos, SEEK_SET, NULL); if (FAILED(hr)) return hr; - hr = IStream_Read(input, &ull, sizeof(ull), NULL); + hr = IStream_Read(input, &ull, sizeof(ull), &bytesread); + if (bytesread != sizeof(ull)) hr = E_FAIL; if (hr != S_OK) return hr; - item->value.u.uhVal.QuadPart = ull; + item->value.uhVal.QuadPart = ull; if (type == IFD_DOUBLE) - SWAP_ULONGLONG(item->value.u.uhVal.QuadPart); + SWAP_ULONGLONG(item->value.uhVal.QuadPart); else { - SWAP_ULONG(item->value.u.uhVal.u.LowPart); - SWAP_ULONG(item->value.u.uhVal.u.HighPart); + SWAP_ULONG(item->value.uhVal.LowPart); + SWAP_ULONG(item->value.uhVal.HighPart); } break; } else { item->value.vt |= VT_VECTOR; - item->value.u.cauh.cElems = count; - item->value.u.cauh.pElems = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count * 8); - if (!item->value.u.cauh.pElems) return E_OUTOFMEMORY; + item->value.cauh.cElems = count; + item->value.cauh.pElems = CoTaskMemAlloc(count * 8); + if (!item->value.cauh.pElems) return E_OUTOFMEMORY; pos.QuadPart = value; hr = IStream_Seek(input, pos, SEEK_SET, NULL); if (FAILED(hr)) { - HeapFree(GetProcessHeap(), 0, item->value.u.cauh.pElems); + CoTaskMemFree(item->value.cauh.pElems); return hr; } - hr = IStream_Read(input, item->value.u.cauh.pElems, count * 8, NULL); - if (FAILED(hr)) + hr = IStream_Read(input, item->value.cauh.pElems, count * 8, &bytesread); + if (bytesread != count * 8) hr = E_FAIL; + if (hr != S_OK) { - HeapFree(GetProcessHeap(), 0, item->value.u.cauh.pElems); + CoTaskMemFree(item->value.cauh.pElems); return hr; } for (i = 0; i < count; i++) { if (type == IFD_DOUBLE) - SWAP_ULONGLONG(item->value.u.cauh.pElems[i].QuadPart); + SWAP_ULONGLONG(item->value.cauh.pElems[i].QuadPart); else { - SWAP_ULONG(item->value.u.cauh.pElems[i].u.LowPart); - SWAP_ULONG(item->value.u.cauh.pElems[i].u.HighPart); + SWAP_ULONG(item->value.cauh.pElems[i].LowPart); + SWAP_ULONG(item->value.cauh.pElems[i].HighPart); } } } break; case IFD_ASCII: - item->value.u.pszVal = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count + 1); - if (!item->value.u.pszVal) return E_OUTOFMEMORY; + item->value.pszVal = CoTaskMemAlloc(count + 1); + if (!item->value.pszVal) return E_OUTOFMEMORY; if (count <= 4) { const char *data = (const char *)&entry->value; - memcpy(item->value.u.pszVal, data, count); - item->value.u.pszVal[count] = 0; + memcpy(item->value.pszVal, data, count); + item->value.pszVal[count] = 0; break; } @@ -935,16 +1017,17 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, hr = IStream_Seek(input, pos, SEEK_SET, NULL); if (FAILED(hr)) { - HeapFree(GetProcessHeap(), 0, item->value.u.pszVal); + CoTaskMemFree(item->value.pszVal); return hr; } - hr = IStream_Read(input, item->value.u.pszVal, count, NULL); - if (FAILED(hr)) + hr = IStream_Read(input, item->value.pszVal, count, &bytesread); + if (bytesread != count) hr = E_FAIL; + if (hr != S_OK) { - HeapFree(GetProcessHeap(), 0, item->value.u.pszVal); + CoTaskMemFree(item->value.pszVal); return hr; } - item->value.u.pszVal[count] = 0; + item->value.pszVal[count] = 0; break; case IFD_UNDEFINED: if (!count) @@ -954,15 +1037,15 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, break; } - item->value.u.blob.pBlobData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count); - if (!item->value.u.blob.pBlobData) return E_OUTOFMEMORY; + item->value.blob.pBlobData = CoTaskMemAlloc(count); + if (!item->value.blob.pBlobData) return E_OUTOFMEMORY; - item->value.u.blob.cbSize = count; + item->value.blob.cbSize = count; if (count <= 4) { const char *data = (const char *)&entry->value; - memcpy(item->value.u.blob.pBlobData, data, count); + memcpy(item->value.blob.pBlobData, data, count); break; } @@ -970,18 +1053,19 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, hr = IStream_Seek(input, pos, SEEK_SET, NULL); if (FAILED(hr)) { - HeapFree(GetProcessHeap(), 0, item->value.u.blob.pBlobData); + CoTaskMemFree(item->value.blob.pBlobData); return hr; } - hr = IStream_Read(input, item->value.u.blob.pBlobData, count, NULL); - if (FAILED(hr)) + hr = IStream_Read(input, item->value.blob.pBlobData, count, &bytesread); + if (bytesread != count) hr = E_FAIL; + if (hr != S_OK) { - HeapFree(GetProcessHeap(), 0, item->value.u.blob.pBlobData); + CoTaskMemFree(item->value.blob.pBlobData); return hr; } break; default: - FIXME("loading field of type %d, count %u is not implemented\n", type, count); + FIXME("loading field of type %d, count %lu is not implemented\n", type, count); break; } return S_OK; @@ -1012,14 +1096,14 @@ static HRESULT LoadIfdMetadata(IStream *input, const GUID *preferred_vendor, SWAP_USHORT(count); - entry = HeapAlloc(GetProcessHeap(), 0, count * sizeof(*entry)); + entry = malloc(count * sizeof(*entry)); if (!entry) return E_OUTOFMEMORY; hr = IStream_Read(input, entry, count * sizeof(*entry), &bytesread); if (bytesread != count * sizeof(*entry)) hr = E_FAIL; if (hr != S_OK) { - HeapFree(GetProcessHeap(), 0, entry); + free(entry); return hr; } @@ -1054,14 +1138,14 @@ static HRESULT LoadIfdMetadata(IStream *input, const GUID *preferred_vendor, if (hr != S_OK || i == 4096) { - HeapFree(GetProcessHeap(), 0, entry); + free(entry); return WINCODEC_ERR_BADMETADATAHEADER; } - result = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count * sizeof(*result)); + result = calloc(count, sizeof(*result)); if (!result) { - HeapFree(GetProcessHeap(), 0, entry); + free(entry); return E_OUTOFMEMORY; } @@ -1070,13 +1154,13 @@ static HRESULT LoadIfdMetadata(IStream *input, const GUID *preferred_vendor, hr = load_IFD_entry(input, &entry[i], &result[i], native_byte_order); if (FAILED(hr)) { - HeapFree(GetProcessHeap(), 0, entry); - HeapFree(GetProcessHeap(), 0, result); + free(entry); + free(result); return hr; } } - HeapFree(GetProcessHeap(), 0, entry); + free(entry); *items = result; *item_count = count; @@ -1094,3 +1178,4 @@ HRESULT IfdMetadataReader_CreateInstance(REFIID iid, void **ppv) { return MetadataReader_Create(&IfdMetadataReader_Vtbl, iid, ppv); } + diff --git a/dll/win32/windowscodecs/metadataquery.c b/dll/win32/windowscodecs/metadataquery.c index 79340427547aa..d0d27bdd0fb2a 100644 --- a/dll/win32/windowscodecs/metadataquery.c +++ b/dll/win32/windowscodecs/metadataquery.c @@ -17,13 +17,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" - #include +#include #define COBJMACROS -#define NONAMELESSUNION - #include "windef.h" #include "winbase.h" #include "objbase.h" @@ -75,7 +72,7 @@ static ULONG WINAPI mqr_AddRef(IWICMetadataQueryReader *iface) { QueryReader *This = impl_from_IWICMetadataQueryReader(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", This, ref); + TRACE("(%p) refcount=%lu\n", This, ref); return ref; } @@ -83,12 +80,12 @@ static ULONG WINAPI mqr_Release(IWICMetadataQueryReader *iface) { QueryReader *This = impl_from_IWICMetadataQueryReader(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", This, ref); + TRACE("(%p) refcount=%lu\n", This, ref); if (!ref) { IWICMetadataBlockReader_Release(This->block); - HeapFree(GetProcessHeap(), 0, This->root); - HeapFree(GetProcessHeap(), 0, This); + free(This->root); + free(This); } return ref; } @@ -104,7 +101,6 @@ static HRESULT WINAPI mqr_GetContainerFormat(IWICMetadataQueryReader *iface, GUI static HRESULT WINAPI mqr_GetLocation(IWICMetadataQueryReader *iface, UINT len, WCHAR *location, UINT *ret_len) { - static const WCHAR rootW[] = { '/',0 }; QueryReader *This = impl_from_IWICMetadataQueryReader(iface); const WCHAR *root; UINT actual_len; @@ -113,7 +109,7 @@ static HRESULT WINAPI mqr_GetLocation(IWICMetadataQueryReader *iface, UINT len, if (!ret_len) return E_INVALIDARG; - root = This->root ? This->root : rootW; + root = This->root ? This->root : L"/"; actual_len = lstrlenW(root) + 1; if (location) @@ -201,7 +197,7 @@ static HRESULT get_token(struct string_t *elem, PROPVARIANT *id, PROPVARIANT *sc if (start[1] < '0' || start[1] > '9') return DISP_E_TYPEMISMATCH; - *idx = strtolW(start + 1, &idx_end, 10); + *idx = wcstol(start + 1, &idx_end, 10); if (idx_end > elem->str + elem->len) return WINCODEC_ERR_INVALIDQUERYREQUEST; if (*idx_end != ']') return WINCODEC_ERR_INVALIDQUERYREQUEST; if (*idx < 0) return WINCODEC_ERR_INVALIDQUERYREQUEST; @@ -212,7 +208,7 @@ static HRESULT get_token(struct string_t *elem, PROPVARIANT *id, PROPVARIANT *sc hr = get_token(&next_elem, id, schema, idx); if (hr != S_OK) { - TRACE("get_token error %#x\n", hr); + TRACE("get_token error %#lx\n", hr); return hr; } elem->len = (end - start) + next_elem.len; @@ -225,7 +221,7 @@ static HRESULT get_token(struct string_t *elem, PROPVARIANT *id, PROPVARIANT *sc VARTYPE vt; PROPVARIANT next_token; - end = memchrW(start + 1, '=', elem->len - 1); + end = wmemchr(start + 1, '=', elem->len - 1); if (!end) return WINCODEC_ERR_INVALIDQUERYREQUEST; if (end > elem->str + elem->len) return WINCODEC_ERR_INVALIDQUERYREQUEST; @@ -236,10 +232,10 @@ static HRESULT get_token(struct string_t *elem, PROPVARIANT *id, PROPVARIANT *sc if (vt == VT_ILLEGAL) return WINCODEC_ERR_WRONGSTATE; next_token.vt = VT_BSTR; - next_token.u.bstrVal = SysAllocStringLen(NULL, elem->len - (end - start) + 1); - if (!next_token.u.bstrVal) return E_OUTOFMEMORY; + next_token.bstrVal = SysAllocStringLen(NULL, elem->len - (end - start) + 1); + if (!next_token.bstrVal) return E_OUTOFMEMORY; - bstr = next_token.u.bstrVal; + bstr = next_token.bstrVal; end++; while (*end && *end != '}' && end - start < elem->len) @@ -253,19 +249,19 @@ static HRESULT get_token(struct string_t *elem, PROPVARIANT *id, PROPVARIANT *sc return WINCODEC_ERR_INVALIDQUERYREQUEST; } *bstr = 0; - TRACE("schema/id %s\n", wine_dbgstr_w(next_token.u.bstrVal)); + TRACE("schema/id %s\n", wine_dbgstr_w(next_token.bstrVal)); if (vt == VT_CLSID) { id->vt = VT_CLSID; - id->u.puuid = CoTaskMemAlloc(sizeof(GUID)); - if (!id->u.puuid) + id->puuid = CoTaskMemAlloc(sizeof(GUID)); + if (!id->puuid) { PropVariantClear(&next_token); return E_OUTOFMEMORY; } - hr = UuidFromStringW(next_token.u.bstrVal, id->u.puuid); + hr = UuidFromStringW(next_token.bstrVal, id->puuid); } else hr = PropVariantChangeType(id, &next_token, 0, vt); @@ -288,7 +284,7 @@ static HRESULT get_token(struct string_t *elem, PROPVARIANT *id, PROPVARIANT *sc hr = get_token(&next_elem, &next_id, &next_schema, &next_idx); if (hr != S_OK) { - TRACE("get_token error %#x\n", hr); + TRACE("get_token error %#lx\n", hr); return hr; } elem->len = (end - start + 1) + next_elem.len; @@ -312,10 +308,10 @@ static HRESULT get_token(struct string_t *elem, PROPVARIANT *id, PROPVARIANT *sc return S_OK; } - end = memchrW(start, '/', elem->len); + end = wmemchr(start, '/', elem->len); if (!end) end = start + elem->len; - p = memchrW(start, ':', end - start); + p = wmemchr(start, ':', end - start); if (p) { next_elem.str = p + 1; @@ -327,10 +323,10 @@ static HRESULT get_token(struct string_t *elem, PROPVARIANT *id, PROPVARIANT *sc elem->len = end - start; id->vt = VT_BSTR; - id->u.bstrVal = SysAllocStringLen(NULL, elem->len + 1); - if (!id->u.bstrVal) return E_OUTOFMEMORY; + id->bstrVal = SysAllocStringLen(NULL, elem->len + 1); + if (!id->bstrVal) return E_OUTOFMEMORY; - bstr = id->u.bstrVal; + bstr = id->bstrVal; p = elem->str; while (p - elem->str < elem->len) { @@ -348,7 +344,7 @@ static HRESULT get_token(struct string_t *elem, PROPVARIANT *id, PROPVARIANT *sc hr = get_token(&next_elem, &next_id, &next_schema, &next_idx); if (hr != S_OK) { - TRACE("get_token error %#x\n", hr); + TRACE("get_token error %#lx\n", hr); PropVariantClear(id); PropVariantClear(schema); return hr; @@ -430,16 +426,16 @@ static HRESULT get_next_reader(IWICMetadataReader *reader, UINT index, if (index) { schema.vt = VT_UI2; - schema.u.uiVal = index; + schema.uiVal = index; } id.vt = VT_CLSID; - id.u.puuid = guid; + id.puuid = guid; hr = IWICMetadataReader_GetValue(reader, &schema, &id, &value); if (hr != S_OK) return hr; if (value.vt == VT_UNKNOWN) - hr = IUnknown_QueryInterface(value.u.punkVal, &IID_IWICMetadataReader, (void **)new_reader); + hr = IUnknown_QueryInterface(value.punkVal, &IID_IWICMetadataReader, (void **)new_reader); else hr = WINCODEC_ERR_UNEXPECTEDMETADATATYPE; @@ -463,7 +459,7 @@ static HRESULT WINAPI mqr_GetMetadataByName(IWICMetadataQueryReader *iface, LPCW len = lstrlenW(query) + 1; if (This->root) len += lstrlenW(This->root); - full_query = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + full_query = malloc(len * sizeof(WCHAR)); full_query[0] = 0; if (This->root) lstrcpyW(full_query, This->root); @@ -493,7 +489,7 @@ static HRESULT WINAPI mqr_GetMetadataByName(IWICMetadataQueryReader *iface, LPCW hr = get_token(&elem, &tk_id, &tk_schema, &index); if (hr != S_OK) { - WARN("get_token error %#x\n", hr); + WARN("get_token error %#lx\n", hr); break; } TRACE("parsed %d characters: %s, index %d\n", elem.len, wine_dbgstr_wn(elem.str, elem.len), index); @@ -501,7 +497,7 @@ static HRESULT WINAPI mqr_GetMetadataByName(IWICMetadataQueryReader *iface, LPCW if (!elem.len) break; - if (tk_id.vt == VT_CLSID || (tk_id.vt == VT_BSTR && WICMapShortNameToGuid(tk_id.u.bstrVal, &guid) == S_OK)) + if (tk_id.vt == VT_CLSID || (tk_id.vt == VT_BSTR && WICMapShortNameToGuid(tk_id.bstrVal, &guid) == S_OK)) { WCHAR *root; @@ -511,7 +507,7 @@ static HRESULT WINAPI mqr_GetMetadataByName(IWICMetadataQueryReader *iface, LPCW PropVariantClear(&tk_schema); } - if (tk_id.vt == VT_CLSID) guid = *tk_id.u.puuid; + if (tk_id.vt == VT_CLSID) guid = *tk_id.puuid; if (reader) { @@ -536,7 +532,7 @@ static HRESULT WINAPI mqr_GetMetadataByName(IWICMetadataQueryReader *iface, LPCW PropVariantClear(&new_value); new_value.vt = VT_UNKNOWN; - hr = MetadataQueryReader_CreateInstance(This->block, root, (IWICMetadataQueryReader **)&new_value.u.punkVal); + hr = MetadataQueryReader_CreateInstance(This->block, root, (IWICMetadataQueryReader **)&new_value.punkVal); SysFreeString(root); if (hr != S_OK) break; } @@ -556,9 +552,9 @@ static HRESULT WINAPI mqr_GetMetadataByName(IWICMetadataQueryReader *iface, LPCW if (hr != S_OK) break; schema.vt = VT_LPWSTR; - schema.u.pwszVal = (LPWSTR)map_shortname_to_schema(&guid, tk_schema.u.bstrVal); - if (!schema.u.pwszVal) - schema.u.pwszVal = tk_schema.u.bstrVal; + schema.pwszVal = (LPWSTR)map_shortname_to_schema(&guid, tk_schema.bstrVal); + if (!schema.pwszVal) + schema.pwszVal = tk_schema.bstrVal; } else schema = tk_schema; @@ -566,7 +562,7 @@ static HRESULT WINAPI mqr_GetMetadataByName(IWICMetadataQueryReader *iface, LPCW if (tk_id.vt == VT_BSTR) { id.vt = VT_LPWSTR; - id.u.pwszVal = tk_id.u.bstrVal; + id.pwszVal = tk_id.bstrVal; } else id = tk_id; @@ -593,19 +589,131 @@ static HRESULT WINAPI mqr_GetMetadataByName(IWICMetadataQueryReader *iface, LPCW else PropVariantClear(&new_value); - HeapFree(GetProcessHeap(), 0, full_query); + free(full_query); return hr; } -static HRESULT WINAPI mqr_GetEnumerator(IWICMetadataQueryReader *iface, - IEnumString **ppIEnumString) +struct string_enumerator { - QueryReader *This = impl_from_IWICMetadataQueryReader(iface); - FIXME("(%p,%p)\n", This, ppIEnumString); + IEnumString IEnumString_iface; + LONG ref; +}; + +static struct string_enumerator *impl_from_IEnumString(IEnumString *iface) +{ + return CONTAINING_RECORD(iface, struct string_enumerator, IEnumString_iface); +} + +static HRESULT WINAPI string_enumerator_QueryInterface(IEnumString *iface, REFIID riid, void **ppv) +{ + struct string_enumerator *this = impl_from_IEnumString(iface); + + TRACE("iface %p, riid %s, ppv %p.\n", iface, debugstr_guid(riid), ppv); + + if (IsEqualGUID(riid, &IID_IEnumString) || IsEqualGUID(riid, &IID_IUnknown)) + *ppv = &this->IEnumString_iface; + else + { + WARN("Unknown riid %s.\n", debugstr_guid(riid)); + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef(&this->IEnumString_iface); + return S_OK; +} + +static ULONG WINAPI string_enumerator_AddRef(IEnumString *iface) +{ + struct string_enumerator *this = impl_from_IEnumString(iface); + ULONG ref = InterlockedIncrement(&this->ref); + + TRACE("iface %p, ref %lu.\n", iface, ref); + + return ref; +} + +static ULONG WINAPI string_enumerator_Release(IEnumString *iface) +{ + struct string_enumerator *this = impl_from_IEnumString(iface); + ULONG ref = InterlockedDecrement(&this->ref); + + TRACE("iface %p, ref %lu.\n", iface, ref); + + if (!ref) + free(this); + + return ref; +} + +static HRESULT WINAPI string_enumerator_Next(IEnumString *iface, ULONG count, LPOLESTR *strings, ULONG *ret) +{ + FIXME("iface %p, count %lu, strings %p, ret %p stub.\n", iface, count, strings, ret); + + if (!strings || !ret) + return E_INVALIDARG; + + *ret = 0; + return count ? S_FALSE : S_OK; +} + +static HRESULT WINAPI string_enumerator_Reset(IEnumString *iface) +{ + TRACE("iface %p.\n", iface); + + return S_OK; +} + +static HRESULT WINAPI string_enumerator_Skip(IEnumString *iface, ULONG count) +{ + FIXME("iface %p, count %lu stub.\n", iface, count); + + return count ? S_FALSE : S_OK; +} + +static HRESULT WINAPI string_enumerator_Clone(IEnumString *iface, IEnumString **out) +{ + FIXME("iface %p, out %p stub.\n", iface, out); + + *out = NULL; return E_NOTIMPL; } +static const IEnumStringVtbl string_enumerator_vtbl = +{ + string_enumerator_QueryInterface, + string_enumerator_AddRef, + string_enumerator_Release, + string_enumerator_Next, + string_enumerator_Skip, + string_enumerator_Reset, + string_enumerator_Clone +}; + +static HRESULT string_enumerator_create(IEnumString **enum_string) +{ + struct string_enumerator *object; + + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; + + object->IEnumString_iface.lpVtbl = &string_enumerator_vtbl; + object->ref = 1; + + *enum_string = &object->IEnumString_iface; + + return S_OK; +} + +static HRESULT WINAPI mqr_GetEnumerator(IWICMetadataQueryReader *iface, + IEnumString **enum_string) +{ + TRACE("iface %p, enum_string %p.\n", iface, enum_string); + + return string_enumerator_create(enum_string); +} + static IWICMetadataQueryReaderVtbl mqr_vtbl = { mqr_QueryInterface, mqr_AddRef, @@ -620,7 +728,7 @@ HRESULT MetadataQueryReader_CreateInstance(IWICMetadataBlockReader *mbr, const W { QueryReader *obj; - obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*obj)); + obj = calloc(1, sizeof(*obj)); if (!obj) return E_OUTOFMEMORY; @@ -630,57 +738,152 @@ HRESULT MetadataQueryReader_CreateInstance(IWICMetadataBlockReader *mbr, const W IWICMetadataBlockReader_AddRef(mbr); obj->block = mbr; - obj->root = root ? heap_strdupW(root) : NULL; + obj->root = wcsdup(root); *out = &obj->IWICMetadataQueryReader_iface; return S_OK; } -static const WCHAR bmpW[] = { 'b','m','p',0 }; -static const WCHAR pngW[] = { 'p','n','g',0 }; -static const WCHAR icoW[] = { 'i','c','o',0 }; -static const WCHAR jpgW[] = { 'j','p','g',0 }; -static const WCHAR tiffW[] = { 't','i','f','f',0 }; -static const WCHAR gifW[] = { 'g','i','f',0 }; -static const WCHAR wmphotoW[] = { 'w','m','p','h','o','t','o',0 }; -static const WCHAR unknownW[] = { 'u','n','k','n','o','w','n',0 }; -static const WCHAR ifdW[] = { 'i','f','d',0 }; -static const WCHAR subW[] = { 's','u','b',0 }; -static const WCHAR exifW[] = { 'e','x','i','f',0 }; -static const WCHAR gpsW[] = { 'g','p','s',0 }; -static const WCHAR interopW[] = { 'i','n','t','e','r','o','p',0 }; -static const WCHAR app0W[] = { 'a','p','p','0',0 }; -static const WCHAR app1W[] = { 'a','p','p','1',0 }; -static const WCHAR app13W[] = { 'a','p','p','1','3',0 }; -static const WCHAR iptcW[] = { 'i','p','t','c',0 }; -static const WCHAR irbW[] = { 'i','r','b',0 }; -static const WCHAR _8bimiptcW[] = { '8','b','i','m','i','p','t','c',0 }; -static const WCHAR _8bimResInfoW[] = { '8','b','i','m','R','e','s','I','n','f','o',0 }; -static const WCHAR _8bimiptcdigestW[] = { '8','b','i','m','i','p','t','c','d','i','g','e','s','t',0 }; -static const WCHAR xmpW[] = { 'x','m','p',0 }; -static const WCHAR thumbW[] = { 't','h','u','m','b',0 }; -static const WCHAR tEXtW[] = { 't','E','X','t',0 }; -static const WCHAR xmpstructW[] = { 'x','m','p','s','t','r','u','c','t',0 }; -static const WCHAR xmpbagW[] = { 'x','m','p','b','a','g',0 }; -static const WCHAR xmpseqW[] = { 'x','m','p','s','e','q',0 }; -static const WCHAR xmpaltW[] = { 'x','m','p','a','l','t',0 }; -static const WCHAR logscrdescW[] = { 'l','o','g','s','c','r','d','e','s','c',0 }; -static const WCHAR imgdescW[] = { 'i','m','g','d','e','s','c',0 }; -static const WCHAR grctlextW[] = { 'g','r','c','t','l','e','x','t',0 }; -static const WCHAR appextW[] = { 'a','p','p','e','x','t',0 }; -static const WCHAR chrominanceW[] = { 'c','h','r','o','m','i','n','a','n','c','e',0 }; -static const WCHAR luminanceW[] = { 'l','u','m','i','n','a','n','c','e',0 }; -static const WCHAR comW[] = { 'c','o','m',0 }; -static const WCHAR commentextW[] = { 'c','o','m','m','e','n','t','e','x','t',0 }; -static const WCHAR gAMAW[] = { 'g','A','M','A',0 }; -static const WCHAR bKGDW[] = { 'b','K','G','D',0 }; -static const WCHAR iTXtW[] = { 'i','T','X','t',0 }; -static const WCHAR cHRMW[] = { 'c','H','R','M',0 }; -static const WCHAR hISTW[] = { 'h','I','S','T',0 }; -static const WCHAR iCCPW[] = { 'i','C','C','P',0 }; -static const WCHAR sRGBW[] = { 's','R','G','B',0 }; -static const WCHAR tIMEW[] = { 't','I','M','E',0 }; +typedef struct +{ + IWICMetadataQueryWriter IWICMetadataQueryWriter_iface; + LONG ref; + IWICMetadataBlockWriter *block; + WCHAR *root; +} +QueryWriter; + +static inline QueryWriter *impl_from_IWICMetadataQueryWriter(IWICMetadataQueryWriter *iface) +{ + return CONTAINING_RECORD(iface, QueryWriter, IWICMetadataQueryWriter_iface); +} + +static HRESULT WINAPI mqw_QueryInterface(IWICMetadataQueryWriter *iface, REFIID riid, + void **object) +{ + QueryWriter *writer = impl_from_IWICMetadataQueryWriter(iface); + + TRACE("writer %p, riid %s, object %p.\n", writer, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_IUnknown) + || IsEqualGUID(riid, &IID_IWICMetadataQueryWriter) + || IsEqualGUID(riid, &IID_IWICMetadataQueryReader)) + *object = &writer->IWICMetadataQueryWriter_iface; + else + *object = NULL; + + if (*object) + { + IUnknown_AddRef((IUnknown *)*object); + return S_OK; + } + + return E_NOINTERFACE; +} + +static ULONG WINAPI mqw_AddRef(IWICMetadataQueryWriter *iface) +{ + QueryWriter *writer = impl_from_IWICMetadataQueryWriter(iface); + ULONG ref = InterlockedIncrement(&writer->ref); + + TRACE("writer %p, refcount=%lu\n", writer, ref); + + return ref; +} + +static ULONG WINAPI mqw_Release(IWICMetadataQueryWriter *iface) +{ + QueryWriter *writer = impl_from_IWICMetadataQueryWriter(iface); + ULONG ref = InterlockedDecrement(&writer->ref); + + TRACE("writer %p, refcount=%lu.\n", writer, ref); + + if (!ref) + { + IWICMetadataBlockWriter_Release(writer->block); + free(writer->root); + free(writer); + } + return ref; +} + +static HRESULT WINAPI mqw_GetContainerFormat(IWICMetadataQueryWriter *iface, GUID *container_format) +{ + FIXME("iface %p, container_format %p stub.\n", iface, container_format); + + return E_NOTIMPL; +} + +static HRESULT WINAPI mqw_GetEnumerator(IWICMetadataQueryWriter *iface, IEnumString **enum_string) +{ + TRACE("iface %p, enum_string %p.\n", iface, enum_string); + + return string_enumerator_create(enum_string); +} + +static HRESULT WINAPI mqw_GetLocation(IWICMetadataQueryWriter *iface, UINT max_length, WCHAR *namespace, UINT *actual_length) +{ + FIXME("iface %p, max_length %u, namespace %s, actual_length %p stub.\n", + iface, max_length, debugstr_w(namespace), actual_length); + + return E_NOTIMPL; +} + +static HRESULT WINAPI mqw_GetMetadataByName(IWICMetadataQueryWriter *iface, LPCWSTR name, PROPVARIANT *value) +{ + FIXME("name %s, value %p stub.\n", debugstr_w(name), value); + + return E_NOTIMPL; +} + +static HRESULT WINAPI mqw_SetMetadataByName(IWICMetadataQueryWriter *iface, LPCWSTR name, const PROPVARIANT *value) +{ + FIXME("iface %p, name %s, value %p stub.\n", iface, debugstr_w(name), value); + + return S_OK; +} + +static HRESULT WINAPI mqw_RemoveMetadataByName(IWICMetadataQueryWriter *iface, LPCWSTR name) +{ + FIXME("iface %p, name %s stub.\n", iface, debugstr_w(name)); + + return E_NOTIMPL; +} + +static const IWICMetadataQueryWriterVtbl mqw_vtbl = +{ + mqw_QueryInterface, + mqw_AddRef, + mqw_Release, + mqw_GetContainerFormat, + mqw_GetLocation, + mqw_GetMetadataByName, + mqw_GetEnumerator, + mqw_SetMetadataByName, + mqw_RemoveMetadataByName, +}; + +HRESULT MetadataQueryWriter_CreateInstance(IWICMetadataBlockWriter *mbw, const WCHAR *root, IWICMetadataQueryWriter **out) +{ + QueryWriter *obj; + + obj = calloc(1, sizeof(*obj)); + if (!obj) + return E_OUTOFMEMORY; + + obj->IWICMetadataQueryWriter_iface.lpVtbl = &mqw_vtbl; + obj->ref = 1; + + IWICMetadataBlockWriter_AddRef(mbw); + obj->block = mbw; + + obj->root = wcsdup(root); + + *out = &obj->IWICMetadataQueryWriter_iface; + + return S_OK; +} static const struct { @@ -688,50 +891,50 @@ static const struct const WCHAR *name; } guid2name[] = { - { &GUID_ContainerFormatBmp, bmpW }, - { &GUID_ContainerFormatPng, pngW }, - { &GUID_ContainerFormatIco, icoW }, - { &GUID_ContainerFormatJpeg, jpgW }, - { &GUID_ContainerFormatTiff, tiffW }, - { &GUID_ContainerFormatGif, gifW }, - { &GUID_ContainerFormatWmp, wmphotoW }, - { &GUID_MetadataFormatUnknown, unknownW }, - { &GUID_MetadataFormatIfd, ifdW }, - { &GUID_MetadataFormatSubIfd, subW }, - { &GUID_MetadataFormatExif, exifW }, - { &GUID_MetadataFormatGps, gpsW }, - { &GUID_MetadataFormatInterop, interopW }, - { &GUID_MetadataFormatApp0, app0W }, - { &GUID_MetadataFormatApp1, app1W }, - { &GUID_MetadataFormatApp13, app13W }, - { &GUID_MetadataFormatIPTC, iptcW }, - { &GUID_MetadataFormatIRB, irbW }, - { &GUID_MetadataFormat8BIMIPTC, _8bimiptcW }, - { &GUID_MetadataFormat8BIMResolutionInfo, _8bimResInfoW }, - { &GUID_MetadataFormat8BIMIPTCDigest, _8bimiptcdigestW }, - { &GUID_MetadataFormatXMP, xmpW }, - { &GUID_MetadataFormatThumbnail, thumbW }, - { &GUID_MetadataFormatChunktEXt, tEXtW }, - { &GUID_MetadataFormatXMPStruct, xmpstructW }, - { &GUID_MetadataFormatXMPBag, xmpbagW }, - { &GUID_MetadataFormatXMPSeq, xmpseqW }, - { &GUID_MetadataFormatXMPAlt, xmpaltW }, - { &GUID_MetadataFormatLSD, logscrdescW }, - { &GUID_MetadataFormatIMD, imgdescW }, - { &GUID_MetadataFormatGCE, grctlextW }, - { &GUID_MetadataFormatAPE, appextW }, - { &GUID_MetadataFormatJpegChrominance, chrominanceW }, - { &GUID_MetadataFormatJpegLuminance, luminanceW }, - { &GUID_MetadataFormatJpegComment, comW }, - { &GUID_MetadataFormatGifComment, commentextW }, - { &GUID_MetadataFormatChunkgAMA, gAMAW }, - { &GUID_MetadataFormatChunkbKGD, bKGDW }, - { &GUID_MetadataFormatChunkiTXt, iTXtW }, - { &GUID_MetadataFormatChunkcHRM, cHRMW }, - { &GUID_MetadataFormatChunkhIST, hISTW }, - { &GUID_MetadataFormatChunkiCCP, iCCPW }, - { &GUID_MetadataFormatChunksRGB, sRGBW }, - { &GUID_MetadataFormatChunktIME, tIMEW } + { &GUID_ContainerFormatBmp, L"bmp" }, + { &GUID_ContainerFormatPng, L"png" }, + { &GUID_ContainerFormatIco, L"ico" }, + { &GUID_ContainerFormatJpeg, L"jpg" }, + { &GUID_ContainerFormatTiff, L"tiff" }, + { &GUID_ContainerFormatGif, L"gif" }, + { &GUID_ContainerFormatWmp, L"wmphoto" }, + { &GUID_MetadataFormatUnknown, L"unknown" }, + { &GUID_MetadataFormatIfd, L"ifd" }, + { &GUID_MetadataFormatSubIfd, L"sub" }, + { &GUID_MetadataFormatExif, L"exif" }, + { &GUID_MetadataFormatGps, L"gps" }, + { &GUID_MetadataFormatInterop, L"interop" }, + { &GUID_MetadataFormatApp0, L"app0" }, + { &GUID_MetadataFormatApp1, L"app1" }, + { &GUID_MetadataFormatApp13, L"app13" }, + { &GUID_MetadataFormatIPTC, L"iptc" }, + { &GUID_MetadataFormatIRB, L"irb" }, + { &GUID_MetadataFormat8BIMIPTC, L"8bimiptc" }, + { &GUID_MetadataFormat8BIMResolutionInfo, L"8bimResInfo" }, + { &GUID_MetadataFormat8BIMIPTCDigest, L"8bimiptcdigest" }, + { &GUID_MetadataFormatXMP, L"xmp" }, + { &GUID_MetadataFormatThumbnail, L"thumb" }, + { &GUID_MetadataFormatChunktEXt, L"tEXt" }, + { &GUID_MetadataFormatXMPStruct, L"xmpstruct" }, + { &GUID_MetadataFormatXMPBag, L"xmpbag" }, + { &GUID_MetadataFormatXMPSeq, L"xmpseq" }, + { &GUID_MetadataFormatXMPAlt, L"xmpalt" }, + { &GUID_MetadataFormatLSD, L"logscrdesc" }, + { &GUID_MetadataFormatIMD, L"imgdesc" }, + { &GUID_MetadataFormatGCE, L"grctlext" }, + { &GUID_MetadataFormatAPE, L"appext" }, + { &GUID_MetadataFormatJpegChrominance, L"chrominance" }, + { &GUID_MetadataFormatJpegLuminance, L"luminance" }, + { &GUID_MetadataFormatJpegComment, L"com" }, + { &GUID_MetadataFormatGifComment, L"commentext" }, + { &GUID_MetadataFormatChunkgAMA, L"gAMA" }, + { &GUID_MetadataFormatChunkbKGD, L"bKGD" }, + { &GUID_MetadataFormatChunkiTXt, L"iTXt" }, + { &GUID_MetadataFormatChunkcHRM, L"cHRM" }, + { &GUID_MetadataFormatChunkhIST, L"hIST" }, + { &GUID_MetadataFormatChunkiCCP, L"iCCP" }, + { &GUID_MetadataFormatChunksRGB, L"sRGB" }, + { &GUID_MetadataFormatChunktIME, L"tIME" } }; HRESULT WINAPI WICMapGuidToShortName(REFGUID guid, UINT len, WCHAR *name, UINT *ret_len) @@ -785,91 +988,38 @@ HRESULT WINAPI WICMapShortNameToGuid(PCWSTR name, GUID *guid) return WINCODEC_ERR_PROPERTYNOTFOUND; } -static const WCHAR rdf[] = { 'r','d','f',0 }; -static const WCHAR rdf_scheme[] = { 'h','t','t','p',':','/','/','w','w','w','.','w','3','.','o','r','g','/','1','9','9','9','/','0','2','/','2','2','-','r','d','f','-','s','y','n','t','a','x','-','n','s','#',0 }; -static const WCHAR dc[] = { 'd','c',0 }; -static const WCHAR dc_scheme[] = { 'h','t','t','p',':','/','/','p','u','r','l','.','o','r','g','/','d','c','/','e','l','e','m','e','n','t','s','/','1','.','1','/',0 }; -static const WCHAR xmp[] = { 'x','m','p',0 }; -static const WCHAR xmp_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/',0 }; -static const WCHAR xmpidq[] = { 'x','m','p','i','d','q',0 }; -static const WCHAR xmpidq_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','m','p','/','I','d','e','n','t','i','f','i','e','r','/','q','u','a','l','/','1','.','0','/',0 }; -static const WCHAR xmpRights[] = { 'x','m','p','R','i','g','h','t','s',0 }; -static const WCHAR xmpRights_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','r','i','g','h','t','s','/',0 }; -static const WCHAR xmpMM[] = { 'x','m','p','M','M',0 }; -static const WCHAR xmpMM_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','m','m','/',0 }; -static const WCHAR xmpBJ[] = { 'x','m','p','B','J',0 }; -static const WCHAR xmpBJ_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','b','j','/',0 }; -static const WCHAR xmpTPg[] = { 'x','m','p','T','P','g',0 }; -static const WCHAR xmpTPg_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','t','/','p','g','/',0 }; -static const WCHAR pdf[] = { 'p','d','f',0 }; -static const WCHAR pdf_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','p','d','f','/','1','.','3','/',0 }; -static const WCHAR photoshop[] = { 'p','h','o','t','o','s','h','o','p',0 }; -static const WCHAR photoshop_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','p','h','o','t','o','s','h','o','p','/','1','.','0','/',0 }; -static const WCHAR tiff[] = { 't','i','f','f',0 }; -static const WCHAR tiff_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','t','i','f','f','/','1','.','0','/',0 }; -static const WCHAR exif[] = { 'e','x','i','f',0 }; -static const WCHAR exif_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','e','x','i','f','/','1','.','0','/',0 }; -static const WCHAR stDim[] = { 's','t','D','i','m',0 }; -static const WCHAR stDim_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','s','T','y','p','e','/','D','i','m','e','n','s','i','o','n','s','#',0 }; -static const WCHAR xapGImg[] = { 'x','a','p','G','I','m','g',0 }; -static const WCHAR xapGImg_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','g','/','i','m','g','/',0 }; -static const WCHAR stEvt[] = { 's','t','E','v','t',0 }; -static const WCHAR stEvt_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','s','T','y','p','e','/','R','e','s','o','u','r','c','e','E','v','e','n','t','#',0 }; -static const WCHAR stRef[] = { 's','t','R','e','f',0 }; -static const WCHAR stRef_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','s','T','y','p','e','/','R','e','s','o','u','r','c','e','R','e','f','#',0 }; -static const WCHAR stVer[] = { 's','t','V','e','r',0 }; -static const WCHAR stVer_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','s','T','y','p','e','/','V','e','r','s','i','o','n','#',0 }; -static const WCHAR stJob[] = { 's','t','J','o','b',0 }; -static const WCHAR stJob_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','s','T','y','p','e','/','J','o','b','#',0 }; -static const WCHAR aux[] = { 'a','u','x',0 }; -static const WCHAR aux_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','e','x','i','f','/','1','.','0','/','a','u','x','/',0 }; -static const WCHAR crs[] = { 'c','r','s',0 }; -static const WCHAR crs_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','c','a','m','e','r','a','-','r','a','w','-','s','e','t','t','i','n','g','s','/','1','.','0','/',0 }; -static const WCHAR xmpDM[] = { 'x','m','p','D','M',0 }; -static const WCHAR xmpDM_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','m','p','/','1','.','0','/','D','y','n','a','m','i','c','M','e','d','i','a','/',0 }; -static const WCHAR Iptc4xmpCore[] = { 'I','p','t','c','4','x','m','p','C','o','r','e',0 }; -static const WCHAR Iptc4xmpCore_scheme[] = { 'h','t','t','p',':','/','/','i','p','t','c','.','o','r','g','/','s','t','d','/','I','p','t','c','4','x','m','p','C','o','r','e','/','1','.','0','/','x','m','l','n','s','/',0 }; -static const WCHAR MicrosoftPhoto[] = { 'M','i','c','r','o','s','o','f','t','P','h','o','t','o',0 }; -static const WCHAR MicrosoftPhoto_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','m','i','c','r','o','s','o','f','t','.','c','o','m','/','p','h','o','t','o','/','1','.','0','/',0 }; -static const WCHAR MP[] = { 'M','P',0 }; -static const WCHAR MP_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','m','i','c','r','o','s','o','f','t','.','c','o','m','/','p','h','o','t','o','/','1','.','2','/',0 }; -static const WCHAR MPRI[] = { 'M','P','R','I',0 }; -static const WCHAR MPRI_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','m','i','c','r','o','s','o','f','t','.','c','o','m','/','p','h','o','t','o','/','1','.','2','/','t','/','R','e','g','i','o','n','I','n','f','o','#',0 }; -static const WCHAR MPReg[] = { 'M','P','R','e','g',0 }; -static const WCHAR MPReg_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','m','i','c','r','o','s','o','f','t','.','c','o','m','/','p','h','o','t','o','/','1','.','2','/','t','/','R','e','g','i','o','n','#',0 }; - static const struct { const WCHAR *name; const WCHAR *schema; } name2schema[] = { - { rdf, rdf_scheme }, - { dc, dc_scheme }, - { xmp, xmp_scheme }, - { xmpidq, xmpidq_scheme }, - { xmpRights, xmpRights_scheme }, - { xmpMM, xmpMM_scheme }, - { xmpBJ, xmpBJ_scheme }, - { xmpTPg, xmpTPg_scheme }, - { pdf, pdf_scheme }, - { photoshop, photoshop_scheme }, - { tiff, tiff_scheme }, - { exif, exif_scheme }, - { stDim, stDim_scheme }, - { xapGImg, xapGImg_scheme }, - { stEvt, stEvt_scheme }, - { stRef, stRef_scheme }, - { stVer, stVer_scheme }, - { stJob, stJob_scheme }, - { aux, aux_scheme }, - { crs, crs_scheme }, - { xmpDM, xmpDM_scheme }, - { Iptc4xmpCore, Iptc4xmpCore_scheme }, - { MicrosoftPhoto, MicrosoftPhoto_scheme }, - { MP, MP_scheme }, - { MPRI, MPRI_scheme }, - { MPReg, MPReg_scheme } + { L"rdf", L"http://www.w3.org/1999/02/22-rdf-syntax-ns#" }, + { L"dc", L"http://purl.org/dc/elements/1.1/" }, + { L"xmp", L"http://ns.adobe.com/xap/1.0/" }, + { L"xmpidq", L"http://ns.adobe.com/xmp/Identifier/qual/1.0/" }, + { L"xmpRights", L"http://ns.adobe.com/xap/1.0/rights/" }, + { L"xmpMM", L"http://ns.adobe.com/xap/1.0/mm/" }, + { L"xmpBJ", L"http://ns.adobe.com/xap/1.0/bj/" }, + { L"xmpTPg", L"http://ns.adobe.com/xap/1.0/t/pg/" }, + { L"pdf", L"http://ns.adobe.com/pdf/1.3/" }, + { L"photoshop", L"http://ns.adobe.com/photoshop/1.0/" }, + { L"tiff", L"http://ns.adobe.com/tiff/1.0/" }, + { L"exif", L"http://ns.adobe.com/exif/1.0/" }, + { L"stDim", L"http://ns.adobe.com/xap/1.0/sType/Dimensions#" }, + { L"xapGImg", L"http://ns.adobe.com/xap/1.0/g/img/" }, + { L"stEvt", L"http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" }, + { L"stRef", L"http://ns.adobe.com/xap/1.0/sType/ResourceRef#" }, + { L"stVer", L"http://ns.adobe.com/xap/1.0/sType/Version#" }, + { L"stJob", L"http://ns.adobe.com/xap/1.0/sType/Job#" }, + { L"aux", L"http://ns.adobe.com/exif/1.0/aux/" }, + { L"crs", L"http://ns.adobe.com/camera-raw-settings/1.0/" }, + { L"xmpDM", L"http://ns.adobe.com/xmp/1.0/DynamicMedia/" }, + { L"Iptc4xmpCore", L"http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/" }, + { L"MicrosoftPhoto", L"http://ns.microsoft.com/photo/1.0/" }, + { L"MP", L"http://ns.microsoft.com/photo/1.2/" }, + { L"MPRI", L"http://ns.microsoft.com/photo/1.2/t/RegionInfo#" }, + { L"MPReg", L"http://ns.microsoft.com/photo/1.2/t/Region#" } }; static const WCHAR *map_shortname_to_schema(const GUID *format, const WCHAR *name) @@ -885,7 +1035,7 @@ static const WCHAR *map_shortname_to_schema(const GUID *format, const WCHAR *nam for (i = 0; i < ARRAY_SIZE(name2schema); i++) { - if (!lstrcmpW(name2schema[i].name, name)) + if (!wcscmp(name2schema[i].name, name)) return name2schema[i].schema; } @@ -910,7 +1060,7 @@ HRESULT WINAPI WICMapSchemaToName(REFGUID format, LPWSTR schema, UINT len, WCHAR for (i = 0; i < ARRAY_SIZE(name2schema); i++) { - if (!lstrcmpW(name2schema[i].schema, schema)) + if (!wcscmp(name2schema[i].schema, schema)) { if (name) { diff --git a/dll/win32/windowscodecs/palette.c b/dll/win32/windowscodecs/palette.c index f99cbe00fd1dd..b45d4f30c97c5 100644 --- a/dll/win32/windowscodecs/palette.c +++ b/dll/win32/windowscodecs/palette.c @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" - #include #define COBJMACROS @@ -76,7 +74,7 @@ static ULONG WINAPI PaletteImpl_AddRef(IWICPalette *iface) PaletteImpl *This = impl_from_IWICPalette(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -86,14 +84,14 @@ static ULONG WINAPI PaletteImpl_Release(IWICPalette *iface) PaletteImpl *This = impl_from_IWICPalette(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { This->lock.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&This->lock); - HeapFree(GetProcessHeap(), 0, This->colors); - HeapFree(GetProcessHeap(), 0, This); + free(This->colors); + free(This); } return ref; @@ -105,7 +103,7 @@ static WICColor *generate_gray16_palette(UINT *count) UINT i; *count = 16; - entries = HeapAlloc(GetProcessHeap(), 0, 16 * sizeof(WICColor)); + entries = malloc(16 * sizeof(WICColor)); if (!entries) return NULL; for (i = 0; i < 16; i++) @@ -122,7 +120,7 @@ static WICColor *generate_gray256_palette(UINT *count) UINT i; *count = 256; - entries = HeapAlloc(GetProcessHeap(), 0, 256 * sizeof(WICColor)); + entries = malloc(256 * sizeof(WICColor)); if (!entries) return NULL; for (i = 0; i < 256; i++) @@ -139,7 +137,7 @@ static WICColor *generate_halftone8_palette(UINT *count, BOOL add_transparent) UINT i; *count = add_transparent ? 17 : 16; - entries = HeapAlloc(GetProcessHeap(), 0, *count * sizeof(WICColor)); + entries = malloc(*count * sizeof(WICColor)); if (!entries) return NULL; for (i = 0; i < 8; i++) @@ -170,7 +168,7 @@ static WICColor *generate_halftone27_palette(UINT *count, BOOL add_transparent) UINT i; *count = add_transparent ? 29 : 28; - entries = HeapAlloc(GetProcessHeap(), 0, *count * sizeof(WICColor)); + entries = malloc(*count * sizeof(WICColor)); if (!entries) return NULL; for (i = 0; i < 27; i++) @@ -195,7 +193,7 @@ static WICColor *generate_halftone64_palette(UINT *count, BOOL add_transparent) UINT i; *count = add_transparent ? 73 : 72; - entries = HeapAlloc(GetProcessHeap(), 0, *count * sizeof(WICColor)); + entries = malloc(*count * sizeof(WICColor)); if (!entries) return NULL; for (i = 0; i < 64; i++) @@ -227,7 +225,7 @@ static WICColor *generate_halftone125_palette(UINT *count, BOOL add_transparent) UINT i; *count = add_transparent ? 127 : 126; - entries = HeapAlloc(GetProcessHeap(), 0, *count * sizeof(WICColor)); + entries = malloc(*count * sizeof(WICColor)); if (!entries) return NULL; for (i = 0; i < 125; i++) @@ -252,7 +250,7 @@ static WICColor *generate_halftone216_palette(UINT *count, BOOL add_transparent) UINT i; *count = add_transparent ? 225 : 224; - entries = HeapAlloc(GetProcessHeap(), 0, *count * sizeof(WICColor)); + entries = malloc(*count * sizeof(WICColor)); if (!entries) return NULL; for (i = 0; i < 216; i++) @@ -284,7 +282,7 @@ static WICColor *generate_halftone252_palette(UINT *count, BOOL add_transparent) UINT i; *count = add_transparent ? 253 : 252; - entries = HeapAlloc(GetProcessHeap(), 0, *count * sizeof(WICColor)); + entries = malloc(*count * sizeof(WICColor)); if (!entries) return NULL; for (i = 0; i < 252; i++) @@ -309,7 +307,7 @@ static WICColor *generate_halftone256_palette(UINT *count, BOOL add_transparent) UINT i; *count = 256; - entries = HeapAlloc(GetProcessHeap(), 0, 256 * sizeof(WICColor)); + entries = malloc(256 * sizeof(WICColor)); if (!entries) return NULL; for (i = 0; i < 256; i++) @@ -341,7 +339,7 @@ static HRESULT WINAPI PaletteImpl_InitializePredefined(IWICPalette *iface, { case WICBitmapPaletteTypeFixedBW: count = 2; - colors = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WICColor)); + colors = malloc(count * sizeof(WICColor)); if (!colors) return E_OUTOFMEMORY; colors[0] = 0xff000000; colors[1] = 0xffffffff; @@ -349,7 +347,7 @@ static HRESULT WINAPI PaletteImpl_InitializePredefined(IWICPalette *iface, case WICBitmapPaletteTypeFixedGray4: count = 4; - colors = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WICColor)); + colors = malloc(count * sizeof(WICColor)); if (!colors) return E_OUTOFMEMORY; colors[0] = 0xff000000; colors[1] = 0xff555555; @@ -408,7 +406,7 @@ static HRESULT WINAPI PaletteImpl_InitializePredefined(IWICPalette *iface, } EnterCriticalSection(&This->lock); - HeapFree(GetProcessHeap(), 0, This->colors); + free(This->colors); This->colors = colors; This->count = count; This->type = type; @@ -432,13 +430,13 @@ static HRESULT WINAPI PaletteImpl_InitializeCustom(IWICPalette *iface, else { if (!pColors) return E_INVALIDARG; - new_colors = HeapAlloc(GetProcessHeap(), 0, sizeof(WICColor) * colorCount); + new_colors = malloc(sizeof(WICColor) * colorCount); if (!new_colors) return E_OUTOFMEMORY; memcpy(new_colors, pColors, sizeof(WICColor) * colorCount); } EnterCriticalSection(&This->lock); - HeapFree(GetProcessHeap(), 0, This->colors); + free(This->colors); This->colors = new_colors; This->count = colorCount; This->type = WICBitmapPaletteTypeCustom; @@ -614,7 +612,7 @@ static int median_cut(unsigned char *image, unsigned int width, unsigned int hei struct box *b1, *b2; int numboxes, i; - if (!(h = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*h)))) + if (!(h = calloc(1, sizeof(*h)))) return 0; for (y = 0; y < height; y++) @@ -643,7 +641,7 @@ static int median_cut(unsigned char *image, unsigned int width, unsigned int hei for (i = 0; i < numboxes; i++) colors[i] = box_color(h, &boxes[i]); - HeapFree(GetProcessHeap(), 0, h); + free(h); return numboxes; } @@ -681,7 +679,7 @@ static HRESULT WINAPI PaletteImpl_InitializeFromBitmap(IWICPalette *palette, else rgb24_source = source; - hr = ImagingFactory_CreateInstance(&IID_IWICImagingFactory, (void **)&factory); + hr = create_instance(&CLSID_WICImagingFactory, &IID_IWICImagingFactory, (void **)&factory); if (hr != S_OK) goto fail; hr = IWICImagingFactory_CreateBitmapFromSource(factory, rgb24_source, WICBitmapCacheOnLoad, &rgb24_bitmap); @@ -741,18 +739,18 @@ static HRESULT WINAPI PaletteImpl_InitializeFromPalette(IWICPalette *iface, if (hr != S_OK) return hr; if (count) { - colors = HeapAlloc(GetProcessHeap(), 0, sizeof(WICColor) * count); + colors = malloc(sizeof(WICColor) * count); if (!colors) return E_OUTOFMEMORY; hr = IWICPalette_GetColors(source, count, colors, &count); if (hr != S_OK) { - HeapFree(GetProcessHeap(), 0, colors); + free(colors); return hr; } } EnterCriticalSection(&This->lock); - HeapFree(GetProcessHeap(), 0, This->colors); + free(This->colors); This->colors = colors; This->count = count; This->type = type; @@ -900,7 +898,7 @@ HRESULT PaletteImpl_Create(IWICPalette **palette) { PaletteImpl *This; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(PaletteImpl)); + This = malloc(sizeof(PaletteImpl)); if (!This) return E_OUTOFMEMORY; This->IWICPalette_iface.lpVtbl = &PaletteImpl_Vtbl; @@ -908,7 +906,11 @@ HRESULT PaletteImpl_Create(IWICPalette **palette) This->count = 0; This->colors = NULL; This->type = WICBitmapPaletteTypeCustom; +#ifdef __REACTOS__ InitializeCriticalSection(&This->lock); +#else + InitializeCriticalSectionEx(&This->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PaletteImpl.lock"); *palette = &This->IWICPalette_iface; diff --git a/dll/win32/windowscodecs/pngformat.c b/dll/win32/windowscodecs/pngformat.c index c0e272e86f0aa..0e69671c9b83a 100644 --- a/dll/win32/windowscodecs/pngformat.c +++ b/dll/win32/windowscodecs/pngformat.c @@ -17,73 +17,27 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" -#include "wine/port.h" - #include -#ifdef HAVE_PNG_H -#include -#endif - -#define NONAMELESSUNION #define COBJMACROS #include "windef.h" #include "winbase.h" #include "objbase.h" +#include "shlwapi.h" #include "wincodecs_private.h" #include "wine/debug.h" -#include "wine/library.h" -WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); - -static inline ULONG read_ulong_be(BYTE* data) +static inline USHORT read_ushort_be(BYTE* data) { - return data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; + return data[0] << 8 | data[1]; } -static HRESULT read_png_chunk(IStream *stream, BYTE *type, BYTE **data, ULONG *data_size) +static inline ULONG read_ulong_be(BYTE* data) { - BYTE header[8]; - HRESULT hr; - ULONG bytesread; - - hr = IStream_Read(stream, header, 8, &bytesread); - if (FAILED(hr) || bytesread < 8) - { - if (SUCCEEDED(hr)) - hr = E_FAIL; - return hr; - } - - *data_size = read_ulong_be(&header[0]); - - memcpy(type, &header[4], 4); - - if (data) - { - *data = HeapAlloc(GetProcessHeap(), 0, *data_size); - if (!*data) - return E_OUTOFMEMORY; - - hr = IStream_Read(stream, *data, *data_size, &bytesread); - - if (FAILED(hr) || bytesread < *data_size) - { - if (SUCCEEDED(hr)) - hr = E_FAIL; - HeapFree(GetProcessHeap(), 0, *data); - *data = NULL; - return hr; - } - - /* Windows ignores CRC of the chunk */ - } - - return S_OK; + return data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; } static HRESULT LoadTextMetadata(IStream *stream, const GUID *preferred_vendor, @@ -107,21 +61,21 @@ static HRESULT LoadTextMetadata(IStream *stream, const GUID *preferred_vendor, if (!name_end_ptr || name_len > 79) { - HeapFree(GetProcessHeap(), 0, data); + free(data); return E_FAIL; } value_len = data_size - name_len - 1; - result = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MetadataItem)); - name = HeapAlloc(GetProcessHeap(), 0, name_len + 1); - value = HeapAlloc(GetProcessHeap(), 0, value_len + 1); + result = calloc(1, sizeof(MetadataItem)); + name = CoTaskMemAlloc(name_len + 1); + value = CoTaskMemAlloc(value_len + 1); if (!result || !name || !value) { - HeapFree(GetProcessHeap(), 0, data); - HeapFree(GetProcessHeap(), 0, result); - HeapFree(GetProcessHeap(), 0, name); - HeapFree(GetProcessHeap(), 0, value); + free(data); + free(result); + CoTaskMemFree(name); + CoTaskMemFree(value); return E_OUTOFMEMORY; } @@ -134,14 +88,14 @@ static HRESULT LoadTextMetadata(IStream *stream, const GUID *preferred_vendor, value[value_len] = 0; result[0].id.vt = VT_LPSTR; - result[0].id.u.pszVal = name; + result[0].id.pszVal = name; result[0].value.vt = VT_LPSTR; - result[0].value.u.pszVal = value; + result[0].value.pszVal = value; *items = result; *item_count = 1; - HeapFree(GetProcessHeap(), 0, data); + free(data); return S_OK; } @@ -165,7 +119,6 @@ static HRESULT LoadGamaMetadata(IStream *stream, const GUID *preferred_vendor, BYTE *data; ULONG data_size; ULONG gamma; - static const WCHAR ImageGamma[] = {'I','m','a','g','e','G','a','m','m','a',0}; LPWSTR name; MetadataItem *result; @@ -174,20 +127,20 @@ static HRESULT LoadGamaMetadata(IStream *stream, const GUID *preferred_vendor, if (data_size < 4) { - HeapFree(GetProcessHeap(), 0, data); + free(data); return E_FAIL; } gamma = read_ulong_be(data); - HeapFree(GetProcessHeap(), 0, data); + free(data); - result = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MetadataItem)); - name = HeapAlloc(GetProcessHeap(), 0, sizeof(ImageGamma)); + result = calloc(1, sizeof(MetadataItem)); + SHStrDupW(L"ImageGamma", &name); if (!result || !name) { - HeapFree(GetProcessHeap(), 0, result); - HeapFree(GetProcessHeap(), 0, name); + free(result); + CoTaskMemFree(name); return E_OUTOFMEMORY; } @@ -195,12 +148,10 @@ static HRESULT LoadGamaMetadata(IStream *stream, const GUID *preferred_vendor, PropVariantInit(&result[0].id); PropVariantInit(&result[0].value); - memcpy(name, ImageGamma, sizeof(ImageGamma)); - result[0].id.vt = VT_LPWSTR; - result[0].id.u.pwszVal = name; + result[0].id.pwszVal = name; result[0].value.vt = VT_UI4; - result[0].value.u.ulVal = gamma; + result[0].value.ulVal = gamma; *items = result; *item_count = 1; @@ -227,14 +178,14 @@ static HRESULT LoadChrmMetadata(IStream *stream, const GUID *preferred_vendor, BYTE *data; ULONG data_size; static const WCHAR names[8][12] = { - {'W','h','i','t','e','P','o','i','n','t','X',0}, - {'W','h','i','t','e','P','o','i','n','t','Y',0}, - {'R','e','d','X',0}, - {'R','e','d','Y',0}, - {'G','r','e','e','n','X',0}, - {'G','r','e','e','n','Y',0}, - {'B','l','u','e','X',0}, - {'B','l','u','e','Y',0}, + L"WhitePointX", + L"WhitePointY", + L"RedX", + L"RedY", + L"GreenX", + L"GreenY", + L"BlueX", + L"BlueY", }; LPWSTR dyn_names[8] = {0}; MetadataItem *result; @@ -245,22 +196,22 @@ static HRESULT LoadChrmMetadata(IStream *stream, const GUID *preferred_vendor, if (data_size < 32) { - HeapFree(GetProcessHeap(), 0, data); + free(data); return E_FAIL; } - result = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MetadataItem)*8); + result = calloc(8, sizeof(MetadataItem)); for (i=0; i<8; i++) { - dyn_names[i] = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(lstrlenW(names[i])+1)); + SHStrDupW(names[i], &dyn_names[i]); if (!dyn_names[i]) break; } if (!result || i < 8) { - HeapFree(GetProcessHeap(), 0, result); + free(result); for (i=0; i<8; i++) - HeapFree(GetProcessHeap(), 0, dyn_names[i]); - HeapFree(GetProcessHeap(), 0, data); + CoTaskMemFree(dyn_names[i]); + free(data); return E_OUTOFMEMORY; } @@ -270,18 +221,17 @@ static HRESULT LoadChrmMetadata(IStream *stream, const GUID *preferred_vendor, PropVariantInit(&result[i].id); result[i].id.vt = VT_LPWSTR; - result[i].id.u.pwszVal = dyn_names[i]; - lstrcpyW(dyn_names[i], names[i]); + result[i].id.pwszVal = dyn_names[i]; PropVariantInit(&result[i].value); result[i].value.vt = VT_UI4; - result[i].value.u.ulVal = read_ulong_be(&data[i*4]); + result[i].value.ulVal = read_ulong_be(&data[i*4]); } *items = result; *item_count = 8; - HeapFree(GetProcessHeap(), 0, data); + free(data); return S_OK; } @@ -297,1904 +247,179 @@ HRESULT PngChrmReader_CreateInstance(REFIID iid, void** ppv) return MetadataReader_Create(&ChrmReader_Vtbl, iid, ppv); } -#ifdef SONAME_LIBPNG - -static void *libpng_handle; -#define MAKE_FUNCPTR(f) static typeof(f) * p##f -MAKE_FUNCPTR(png_create_read_struct); -MAKE_FUNCPTR(png_create_info_struct); -MAKE_FUNCPTR(png_create_write_struct); -MAKE_FUNCPTR(png_destroy_read_struct); -MAKE_FUNCPTR(png_destroy_write_struct); -MAKE_FUNCPTR(png_error); -MAKE_FUNCPTR(png_get_bit_depth); -MAKE_FUNCPTR(png_get_color_type); -MAKE_FUNCPTR(png_get_error_ptr); -MAKE_FUNCPTR(png_get_iCCP); -MAKE_FUNCPTR(png_get_image_height); -MAKE_FUNCPTR(png_get_image_width); -MAKE_FUNCPTR(png_get_io_ptr); -MAKE_FUNCPTR(png_get_pHYs); -MAKE_FUNCPTR(png_get_PLTE); -MAKE_FUNCPTR(png_get_tRNS); -MAKE_FUNCPTR(png_set_bgr); -MAKE_FUNCPTR(png_set_crc_action); -MAKE_FUNCPTR(png_set_error_fn); -MAKE_FUNCPTR(png_set_filler); -MAKE_FUNCPTR(png_set_filter); -MAKE_FUNCPTR(png_set_gray_to_rgb); -MAKE_FUNCPTR(png_set_interlace_handling); -MAKE_FUNCPTR(png_set_IHDR); -MAKE_FUNCPTR(png_set_pHYs); -MAKE_FUNCPTR(png_set_PLTE); -MAKE_FUNCPTR(png_set_read_fn); -MAKE_FUNCPTR(png_set_strip_16); -MAKE_FUNCPTR(png_set_tRNS); -MAKE_FUNCPTR(png_set_tRNS_to_alpha); -MAKE_FUNCPTR(png_set_write_fn); -MAKE_FUNCPTR(png_set_swap); -MAKE_FUNCPTR(png_read_end); -MAKE_FUNCPTR(png_read_image); -MAKE_FUNCPTR(png_read_info); -MAKE_FUNCPTR(png_write_end); -MAKE_FUNCPTR(png_write_info); -MAKE_FUNCPTR(png_write_rows); -#undef MAKE_FUNCPTR - -static CRITICAL_SECTION init_png_cs; -static CRITICAL_SECTION_DEBUG init_png_cs_debug = -{ - 0, 0, &init_png_cs, - { &init_png_cs_debug.ProcessLocksList, - &init_png_cs_debug.ProcessLocksList }, - 0, 0, { (DWORD_PTR)(__FILE__ ": init_png_cs") } -}; -static CRITICAL_SECTION init_png_cs = { &init_png_cs_debug, -1, 0, 0, 0, 0 }; - -static const WCHAR wszPngInterlaceOption[] = {'I','n','t','e','r','l','a','c','e','O','p','t','i','o','n',0}; -static const WCHAR wszPngFilterOption[] = {'F','i','l','t','e','r','O','p','t','i','o','n',0}; - -static void *load_libpng(void) -{ - void *result; - - EnterCriticalSection(&init_png_cs); - - if(!libpng_handle && (libpng_handle = wine_dlopen(SONAME_LIBPNG, RTLD_NOW, NULL, 0)) != NULL) { - -#define LOAD_FUNCPTR(f) \ - if((p##f = wine_dlsym(libpng_handle, #f, NULL, 0)) == NULL) { \ - libpng_handle = NULL; \ - LeaveCriticalSection(&init_png_cs); \ - return NULL; \ - } - LOAD_FUNCPTR(png_create_read_struct); - LOAD_FUNCPTR(png_create_info_struct); - LOAD_FUNCPTR(png_create_write_struct); - LOAD_FUNCPTR(png_destroy_read_struct); - LOAD_FUNCPTR(png_destroy_write_struct); - LOAD_FUNCPTR(png_error); - LOAD_FUNCPTR(png_get_bit_depth); - LOAD_FUNCPTR(png_get_color_type); - LOAD_FUNCPTR(png_get_error_ptr); - LOAD_FUNCPTR(png_get_iCCP); - LOAD_FUNCPTR(png_get_image_height); - LOAD_FUNCPTR(png_get_image_width); - LOAD_FUNCPTR(png_get_io_ptr); - LOAD_FUNCPTR(png_get_pHYs); - LOAD_FUNCPTR(png_get_PLTE); - LOAD_FUNCPTR(png_get_tRNS); - LOAD_FUNCPTR(png_set_bgr); - LOAD_FUNCPTR(png_set_crc_action); - LOAD_FUNCPTR(png_set_error_fn); - LOAD_FUNCPTR(png_set_filler); - LOAD_FUNCPTR(png_set_filter); - LOAD_FUNCPTR(png_set_gray_to_rgb); - LOAD_FUNCPTR(png_set_interlace_handling); - LOAD_FUNCPTR(png_set_IHDR); - LOAD_FUNCPTR(png_set_pHYs); - LOAD_FUNCPTR(png_set_PLTE); - LOAD_FUNCPTR(png_set_read_fn); - LOAD_FUNCPTR(png_set_strip_16); - LOAD_FUNCPTR(png_set_tRNS); - LOAD_FUNCPTR(png_set_tRNS_to_alpha); - LOAD_FUNCPTR(png_set_write_fn); - LOAD_FUNCPTR(png_set_swap); - LOAD_FUNCPTR(png_read_end); - LOAD_FUNCPTR(png_read_image); - LOAD_FUNCPTR(png_read_info); - LOAD_FUNCPTR(png_write_end); - LOAD_FUNCPTR(png_write_info); - LOAD_FUNCPTR(png_write_rows); - -#undef LOAD_FUNCPTR - } - - result = libpng_handle; - - LeaveCriticalSection(&init_png_cs); - - return result; -} - -static void user_error_fn(png_structp png_ptr, png_const_charp error_message) -{ - jmp_buf *pjmpbuf; - - /* This uses setjmp/longjmp just like the default. We can't use the - * default because there's no way to access the jmp buffer in the png_struct - * that works in 1.2 and 1.4 and allows us to dynamically load libpng. */ - WARN("PNG error: %s\n", debugstr_a(error_message)); - pjmpbuf = ppng_get_error_ptr(png_ptr); - longjmp(*pjmpbuf, 1); -} - -static void user_warning_fn(png_structp png_ptr, png_const_charp warning_message) -{ - WARN("PNG warning: %s\n", debugstr_a(warning_message)); -} - -typedef struct { - ULARGE_INTEGER ofs, len; - IWICMetadataReader* reader; -} metadata_block_info; - -typedef struct { - IWICBitmapDecoder IWICBitmapDecoder_iface; - IWICBitmapFrameDecode IWICBitmapFrameDecode_iface; - IWICMetadataBlockReader IWICMetadataBlockReader_iface; - LONG ref; - IStream *stream; - png_structp png_ptr; - png_infop info_ptr; - png_infop end_info; - BOOL initialized; - int bpp; - int width, height; - UINT stride; - const WICPixelFormatGUID *format; - BYTE *image_bits; - CRITICAL_SECTION lock; /* must be held when png structures are accessed or initialized is set */ - ULONG metadata_count; - metadata_block_info* metadata_blocks; -} PngDecoder; - -static inline PngDecoder *impl_from_IWICBitmapDecoder(IWICBitmapDecoder *iface) -{ - return CONTAINING_RECORD(iface, PngDecoder, IWICBitmapDecoder_iface); -} - -static inline PngDecoder *impl_from_IWICBitmapFrameDecode(IWICBitmapFrameDecode *iface) -{ - return CONTAINING_RECORD(iface, PngDecoder, IWICBitmapFrameDecode_iface); -} - -static inline PngDecoder *impl_from_IWICMetadataBlockReader(IWICMetadataBlockReader *iface) -{ - return CONTAINING_RECORD(iface, PngDecoder, IWICMetadataBlockReader_iface); -} - -static const IWICBitmapFrameDecodeVtbl PngDecoder_FrameVtbl; - -static HRESULT WINAPI PngDecoder_QueryInterface(IWICBitmapDecoder *iface, REFIID iid, - void **ppv) +static HRESULT LoadHistMetadata(IStream *stream, const GUID *preferred_vendor, + DWORD persist_options, MetadataItem **items, DWORD *item_count) { - PngDecoder *This = impl_from_IWICBitmapDecoder(iface); - TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); + HRESULT hr; + BYTE type[4]; + BYTE *data; + ULONG data_size, element_count, i; + LPWSTR name; + MetadataItem *result; + USHORT *elements; - if (!ppv) return E_INVALIDARG; + hr = read_png_chunk(stream, type, &data, &data_size); + if (FAILED(hr)) return hr; - if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IWICBitmapDecoder, iid)) - { - *ppv = &This->IWICBitmapDecoder_iface; - } - else + element_count = data_size / 2; + elements = CoTaskMemAlloc(element_count * sizeof(USHORT)); + if (!elements) { - *ppv = NULL; - return E_NOINTERFACE; + free(data); + return E_OUTOFMEMORY; } + for (i = 0; i < element_count; i++) + elements[i] = read_ushort_be(data + i * 2); - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI PngDecoder_AddRef(IWICBitmapDecoder *iface) -{ - PngDecoder *This = impl_from_IWICBitmapDecoder(iface); - ULONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) refcount=%u\n", iface, ref); - - return ref; -} + free(data); -static ULONG WINAPI PngDecoder_Release(IWICBitmapDecoder *iface) -{ - PngDecoder *This = impl_from_IWICBitmapDecoder(iface); - ULONG ref = InterlockedDecrement(&This->ref); - ULONG i; - - TRACE("(%p) refcount=%u\n", iface, ref); - - if (ref == 0) - { - if (This->stream) - IStream_Release(This->stream); - if (This->png_ptr) - ppng_destroy_read_struct(&This->png_ptr, &This->info_ptr, &This->end_info); - This->lock.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&This->lock); - HeapFree(GetProcessHeap(), 0, This->image_bits); - for (i=0; imetadata_count; i++) - { - if (This->metadata_blocks[i].reader) - IWICMetadataReader_Release(This->metadata_blocks[i].reader); - } - HeapFree(GetProcessHeap(), 0, This->metadata_blocks); - HeapFree(GetProcessHeap(), 0, This); + result = calloc(1, sizeof(MetadataItem)); + SHStrDupW(L"Frequencies", &name); + if (!result || !name) { + free(result); + CoTaskMemFree(name); + CoTaskMemFree(elements); + return E_OUTOFMEMORY; } - return ref; -} - -static HRESULT WINAPI PngDecoder_QueryCapability(IWICBitmapDecoder *iface, IStream *stream, - DWORD *capability) -{ - HRESULT hr; + PropVariantInit(&result[0].schema); + PropVariantInit(&result[0].id); + PropVariantInit(&result[0].value); - TRACE("(%p,%p,%p)\n", iface, stream, capability); + result[0].id.vt = VT_LPWSTR; + result[0].id.pwszVal = name; - if (!stream || !capability) return E_INVALIDARG; + result[0].value.vt = VT_UI2|VT_VECTOR; + result[0].value.caui.cElems = element_count; + result[0].value.caui.pElems = elements; - hr = IWICBitmapDecoder_Initialize(iface, stream, WICDecodeMetadataCacheOnDemand); - if (hr != S_OK) return hr; + *items = result; + *item_count = 1; - *capability = WICBitmapDecoderCapabilityCanDecodeAllImages | - WICBitmapDecoderCapabilityCanDecodeSomeImages; - /* FIXME: WICBitmapDecoderCapabilityCanEnumerateMetadata */ return S_OK; } -static void user_read_data(png_structp png_ptr, png_bytep data, png_size_t length) -{ - IStream *stream = ppng_get_io_ptr(png_ptr); - HRESULT hr; - ULONG bytesread; +static const MetadataHandlerVtbl HistReader_Vtbl = { + 0, + &CLSID_WICPngHistMetadataReader, + LoadHistMetadata +}; - hr = IStream_Read(stream, data, length, &bytesread); - if (FAILED(hr) || bytesread != length) - { - ppng_error(png_ptr, "failed reading data"); - } +HRESULT PngHistReader_CreateInstance(REFIID iid, void** ppv) +{ + return MetadataReader_Create(&HistReader_Vtbl, iid, ppv); } -static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *pIStream, - WICDecodeOptions cacheOptions) +static HRESULT LoadTimeMetadata(IStream *stream, const GUID *preferred_vendor, + DWORD persist_options, MetadataItem **items, DWORD *item_count) { - PngDecoder *This = impl_from_IWICBitmapDecoder(iface); - LARGE_INTEGER seek; - HRESULT hr=S_OK; - png_bytep *row_pointers=NULL; - UINT image_size; - UINT i; - int color_type, bit_depth; - png_bytep trans; - int num_trans; - png_uint_32 transparency; - png_color_16p trans_values; - jmp_buf jmpbuf; - BYTE chunk_type[4]; - ULONG chunk_size; - ULARGE_INTEGER chunk_start; - ULONG metadata_blocks_size = 0; - - TRACE("(%p,%p,%x)\n", iface, pIStream, cacheOptions); - - EnterCriticalSection(&This->lock); - - /* initialize libpng */ - This->png_ptr = ppng_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (!This->png_ptr) - { - hr = E_FAIL; - goto end; - } - - This->info_ptr = ppng_create_info_struct(This->png_ptr); - if (!This->info_ptr) - { - ppng_destroy_read_struct(&This->png_ptr, NULL, NULL); - This->png_ptr = NULL; - hr = E_FAIL; - goto end; - } - - This->end_info = ppng_create_info_struct(This->png_ptr); - if (!This->end_info) - { - ppng_destroy_read_struct(&This->png_ptr, &This->info_ptr, NULL); - This->png_ptr = NULL; - hr = E_FAIL; - goto end; - } - - /* set up setjmp/longjmp error handling */ - if (setjmp(jmpbuf)) - { - ppng_destroy_read_struct(&This->png_ptr, &This->info_ptr, &This->end_info); - This->png_ptr = NULL; - hr = WINCODEC_ERR_UNKNOWNIMAGEFORMAT; - goto end; - } - ppng_set_error_fn(This->png_ptr, jmpbuf, user_error_fn, user_warning_fn); - ppng_set_crc_action(This->png_ptr, PNG_CRC_QUIET_USE, PNG_CRC_QUIET_USE); - - /* seek to the start of the stream */ - seek.QuadPart = 0; - hr = IStream_Seek(pIStream, seek, STREAM_SEEK_SET, NULL); - if (FAILED(hr)) goto end; - - /* set up custom i/o handling */ - ppng_set_read_fn(This->png_ptr, pIStream, user_read_data); - - /* read the header */ - ppng_read_info(This->png_ptr, This->info_ptr); - - /* choose a pixel format */ - color_type = ppng_get_color_type(This->png_ptr, This->info_ptr); - bit_depth = ppng_get_bit_depth(This->png_ptr, This->info_ptr); - - /* PNGs with bit-depth greater than 8 are network byte order. Windows does not expect this. */ - if (bit_depth > 8) - ppng_set_swap(This->png_ptr); + HRESULT hr; + BYTE type[4]; + BYTE *data; + ULONG data_size, i; + MetadataItem *result; + static const WCHAR *names[6] = + { + L"Year", + L"Month", + L"Day", + L"Hour", + L"Minute", + L"Second", + }; + LPWSTR id_values[6] = {0}; - /* check for color-keyed alpha */ - transparency = ppng_get_tRNS(This->png_ptr, This->info_ptr, &trans, &num_trans, &trans_values); - if (transparency && (color_type == PNG_COLOR_TYPE_RGB || - (color_type == PNG_COLOR_TYPE_GRAY && bit_depth == 16))) - { - /* expand to RGBA */ - if (color_type == PNG_COLOR_TYPE_GRAY) - ppng_set_gray_to_rgb(This->png_ptr); - ppng_set_tRNS_to_alpha(This->png_ptr); - color_type = PNG_COLOR_TYPE_RGB_ALPHA; - } + hr = read_png_chunk(stream, type, &data, &data_size); + if (FAILED(hr)) return hr; - switch (color_type) + if (data_size != 7) { - case PNG_COLOR_TYPE_GRAY_ALPHA: - /* WIC does not support grayscale alpha formats so use RGBA */ - ppng_set_gray_to_rgb(This->png_ptr); - /* fall through */ - case PNG_COLOR_TYPE_RGB_ALPHA: - This->bpp = bit_depth * 4; - switch (bit_depth) - { - case 8: - ppng_set_bgr(This->png_ptr); - This->format = &GUID_WICPixelFormat32bppBGRA; - break; - case 16: This->format = &GUID_WICPixelFormat64bppRGBA; break; - default: - ERR("invalid RGBA bit depth: %i\n", bit_depth); - hr = E_FAIL; - goto end; - } - break; - case PNG_COLOR_TYPE_GRAY: - This->bpp = bit_depth; - if (!transparency) - { - switch (bit_depth) - { - case 1: This->format = &GUID_WICPixelFormatBlackWhite; break; - case 2: This->format = &GUID_WICPixelFormat2bppGray; break; - case 4: This->format = &GUID_WICPixelFormat4bppGray; break; - case 8: This->format = &GUID_WICPixelFormat8bppGray; break; - case 16: This->format = &GUID_WICPixelFormat16bppGray; break; - default: - ERR("invalid grayscale bit depth: %i\n", bit_depth); - hr = E_FAIL; - goto end; - } - break; - } - /* else fall through */ - case PNG_COLOR_TYPE_PALETTE: - This->bpp = bit_depth; - switch (bit_depth) - { - case 1: This->format = &GUID_WICPixelFormat1bppIndexed; break; - case 2: This->format = &GUID_WICPixelFormat2bppIndexed; break; - case 4: This->format = &GUID_WICPixelFormat4bppIndexed; break; - case 8: This->format = &GUID_WICPixelFormat8bppIndexed; break; - default: - ERR("invalid indexed color bit depth: %i\n", bit_depth); - hr = E_FAIL; - goto end; - } - break; - case PNG_COLOR_TYPE_RGB: - This->bpp = bit_depth * 3; - switch (bit_depth) - { - case 8: - ppng_set_bgr(This->png_ptr); - This->format = &GUID_WICPixelFormat24bppBGR; - break; - case 16: This->format = &GUID_WICPixelFormat48bppRGB; break; - default: - ERR("invalid RGB color bit depth: %i\n", bit_depth); - hr = E_FAIL; - goto end; - } - break; - default: - ERR("invalid color type %i\n", color_type); - hr = E_FAIL; - goto end; + free(data); + return E_FAIL; } - /* read the image data */ - This->width = ppng_get_image_width(This->png_ptr, This->info_ptr); - This->height = ppng_get_image_height(This->png_ptr, This->info_ptr); - This->stride = (This->width * This->bpp + 7) / 8; - image_size = This->stride * This->height; - - This->image_bits = HeapAlloc(GetProcessHeap(), 0, image_size); - if (!This->image_bits) + result = calloc(6, sizeof(MetadataItem)); + for (i = 0; i < 6; i++) { - hr = E_OUTOFMEMORY; - goto end; + SHStrDupW(names[i], &id_values[i]); + if (!id_values[i]) break; } - - row_pointers = HeapAlloc(GetProcessHeap(), 0, sizeof(png_bytep)*This->height); - if (!row_pointers) + if (!result || i < 6) { - hr = E_OUTOFMEMORY; - goto end; + free(result); + for (i = 0; i < 6; i++) + CoTaskMemFree(id_values[i]); + free(data); + return E_OUTOFMEMORY; } - for (i=0; iheight; i++) - row_pointers[i] = This->image_bits + i * This->stride; - - ppng_read_image(This->png_ptr, row_pointers); - - HeapFree(GetProcessHeap(), 0, row_pointers); - row_pointers = NULL; - - ppng_read_end(This->png_ptr, This->end_info); - - /* Find the metadata chunks in the file. */ - seek.QuadPart = 8; - - do + for (i = 0; i < 6; i++) { - hr = IStream_Seek(pIStream, seek, STREAM_SEEK_SET, &chunk_start); - if (FAILED(hr)) goto end; - - hr = read_png_chunk(pIStream, chunk_type, NULL, &chunk_size); - if (FAILED(hr)) goto end; - - if (chunk_type[0] >= 'a' && chunk_type[0] <= 'z' && - memcmp(chunk_type, "tRNS", 4) && memcmp(chunk_type, "pHYs", 4)) - { - /* This chunk is considered metadata. */ - if (This->metadata_count == metadata_blocks_size) - { - metadata_block_info* new_metadata_blocks; - ULONG new_metadata_blocks_size; - - new_metadata_blocks_size = 4 + metadata_blocks_size * 2; - new_metadata_blocks = HeapAlloc(GetProcessHeap(), 0, - new_metadata_blocks_size * sizeof(*new_metadata_blocks)); - - if (!new_metadata_blocks) - { - hr = E_OUTOFMEMORY; - goto end; - } - - memcpy(new_metadata_blocks, This->metadata_blocks, - This->metadata_count * sizeof(*new_metadata_blocks)); - - HeapFree(GetProcessHeap(), 0, This->metadata_blocks); - This->metadata_blocks = new_metadata_blocks; - metadata_blocks_size = new_metadata_blocks_size; - } - - This->metadata_blocks[This->metadata_count].ofs = chunk_start; - This->metadata_blocks[This->metadata_count].len.QuadPart = chunk_size + 12; - This->metadata_blocks[This->metadata_count].reader = NULL; - This->metadata_count++; - } - - seek.QuadPart = chunk_start.QuadPart + chunk_size + 12; /* skip data and CRC */ - } while (memcmp(chunk_type, "IEND", 4)); - - This->stream = pIStream; - IStream_AddRef(This->stream); - - This->initialized = TRUE; - -end: - LeaveCriticalSection(&This->lock); - - HeapFree(GetProcessHeap(), 0, row_pointers); - - return hr; -} - -static HRESULT WINAPI PngDecoder_GetContainerFormat(IWICBitmapDecoder *iface, - GUID *pguidContainerFormat) -{ - memcpy(pguidContainerFormat, &GUID_ContainerFormatPng, sizeof(GUID)); - return S_OK; -} - -static HRESULT WINAPI PngDecoder_GetDecoderInfo(IWICBitmapDecoder *iface, - IWICBitmapDecoderInfo **ppIDecoderInfo) -{ - TRACE("(%p,%p)\n", iface, ppIDecoderInfo); - - return get_decoder_info(&CLSID_WICPngDecoder, ppIDecoderInfo); -} - -static HRESULT WINAPI PngDecoder_CopyPalette(IWICBitmapDecoder *iface, - IWICPalette *palette) -{ - TRACE("(%p,%p)\n", iface, palette); - return WINCODEC_ERR_PALETTEUNAVAILABLE; -} - -static HRESULT WINAPI PngDecoder_GetMetadataQueryReader(IWICBitmapDecoder *iface, - IWICMetadataQueryReader **reader) -{ - TRACE("(%p,%p)\n", iface, reader); - - if (!reader) return E_INVALIDARG; - - *reader = NULL; - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI PngDecoder_GetPreview(IWICBitmapDecoder *iface, - IWICBitmapSource **ppIBitmapSource) -{ - TRACE("(%p,%p)\n", iface, ppIBitmapSource); - - if (!ppIBitmapSource) return E_INVALIDARG; - - *ppIBitmapSource = NULL; - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI PngDecoder_GetColorContexts(IWICBitmapDecoder *iface, - UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount) -{ - TRACE("(%p,%u,%p,%p)\n", iface, cCount, ppIColorContexts, pcActualCount); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI PngDecoder_GetThumbnail(IWICBitmapDecoder *iface, - IWICBitmapSource **ppIThumbnail) -{ - TRACE("(%p,%p)\n", iface, ppIThumbnail); - - if (!ppIThumbnail) return E_INVALIDARG; - - *ppIThumbnail = NULL; - return WINCODEC_ERR_CODECNOTHUMBNAIL; -} - -static HRESULT WINAPI PngDecoder_GetFrameCount(IWICBitmapDecoder *iface, - UINT *pCount) -{ - if (!pCount) return E_INVALIDARG; - - *pCount = 1; - return S_OK; -} - -static HRESULT WINAPI PngDecoder_GetFrame(IWICBitmapDecoder *iface, - UINT index, IWICBitmapFrameDecode **ppIBitmapFrame) -{ - PngDecoder *This = impl_from_IWICBitmapDecoder(iface); - TRACE("(%p,%u,%p)\n", iface, index, ppIBitmapFrame); - - if (!This->initialized) return WINCODEC_ERR_FRAMEMISSING; + PropVariantInit(&result[i].schema); + PropVariantInit(&result[i].id); + PropVariantInit(&result[i].value); - if (index != 0) return E_INVALIDARG; + result[i].id.vt = VT_LPWSTR; + result[i].id.pwszVal = id_values[i]; + } + + result[0].value.vt = VT_UI2; + result[0].value.uiVal = read_ushort_be(data); + result[1].value.vt = VT_UI1; + result[1].value.bVal = data[2]; + result[2].value.vt = VT_UI1; + result[2].value.bVal = data[3]; + result[3].value.vt = VT_UI1; + result[3].value.bVal = data[4]; + result[4].value.vt = VT_UI1; + result[4].value.bVal = data[5]; + result[5].value.vt = VT_UI1; + result[5].value.bVal = data[6]; - IWICBitmapDecoder_AddRef(iface); + *items = result; + *item_count = 6; - *ppIBitmapFrame = &This->IWICBitmapFrameDecode_iface; + free(data); return S_OK; } -static const IWICBitmapDecoderVtbl PngDecoder_Vtbl = { - PngDecoder_QueryInterface, - PngDecoder_AddRef, - PngDecoder_Release, - PngDecoder_QueryCapability, - PngDecoder_Initialize, - PngDecoder_GetContainerFormat, - PngDecoder_GetDecoderInfo, - PngDecoder_CopyPalette, - PngDecoder_GetMetadataQueryReader, - PngDecoder_GetPreview, - PngDecoder_GetColorContexts, - PngDecoder_GetThumbnail, - PngDecoder_GetFrameCount, - PngDecoder_GetFrame +static const MetadataHandlerVtbl TimeReader_Vtbl = { + 0, + &CLSID_WICPngTimeMetadataReader, + LoadTimeMetadata }; -static HRESULT WINAPI PngDecoder_Frame_QueryInterface(IWICBitmapFrameDecode *iface, REFIID iid, - void **ppv) -{ - PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface); - if (!ppv) return E_INVALIDARG; - - if (IsEqualIID(&IID_IUnknown, iid) || - IsEqualIID(&IID_IWICBitmapSource, iid) || - IsEqualIID(&IID_IWICBitmapFrameDecode, iid)) - { - *ppv = &This->IWICBitmapFrameDecode_iface; - } - else if (IsEqualIID(&IID_IWICMetadataBlockReader, iid)) - { - *ppv = &This->IWICMetadataBlockReader_iface; - } - else - { - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI PngDecoder_Frame_AddRef(IWICBitmapFrameDecode *iface) -{ - PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface); - return IWICBitmapDecoder_AddRef(&This->IWICBitmapDecoder_iface); -} - -static ULONG WINAPI PngDecoder_Frame_Release(IWICBitmapFrameDecode *iface) -{ - PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface); - return IWICBitmapDecoder_Release(&This->IWICBitmapDecoder_iface); -} - -static HRESULT WINAPI PngDecoder_Frame_GetSize(IWICBitmapFrameDecode *iface, - UINT *puiWidth, UINT *puiHeight) -{ - PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface); - *puiWidth = This->width; - *puiHeight = This->height; - TRACE("(%p)->(%u,%u)\n", iface, *puiWidth, *puiHeight); - return S_OK; -} - -static HRESULT WINAPI PngDecoder_Frame_GetPixelFormat(IWICBitmapFrameDecode *iface, - WICPixelFormatGUID *pPixelFormat) -{ - PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface); - TRACE("(%p,%p)\n", iface, pPixelFormat); - - memcpy(pPixelFormat, This->format, sizeof(GUID)); - - return S_OK; -} - -static HRESULT WINAPI PngDecoder_Frame_GetResolution(IWICBitmapFrameDecode *iface, - double *pDpiX, double *pDpiY) +HRESULT PngTimeReader_CreateInstance(REFIID iid, void** ppv) { - PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface); - png_uint_32 ret, xres, yres; - int unit_type; - - EnterCriticalSection(&This->lock); - - ret = ppng_get_pHYs(This->png_ptr, This->info_ptr, &xres, &yres, &unit_type); - - if (ret && unit_type == PNG_RESOLUTION_METER) - { - *pDpiX = xres * 0.0254; - *pDpiY = yres * 0.0254; - } - else - { - WARN("no pHYs block present\n"); - *pDpiX = *pDpiY = 96.0; - } - - LeaveCriticalSection(&This->lock); - - TRACE("(%p)->(%0.2f,%0.2f)\n", iface, *pDpiX, *pDpiY); - - return S_OK; + return MetadataReader_Create(&TimeReader_Vtbl, iid, ppv); } -static HRESULT WINAPI PngDecoder_Frame_CopyPalette(IWICBitmapFrameDecode *iface, - IWICPalette *pIPalette) +HRESULT PngDecoder_CreateInstance(REFIID iid, void** ppv) { - PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface); - png_uint_32 ret, color_type, bit_depth; - png_colorp png_palette; - int num_palette; - WICColor palette[256]; - png_bytep trans_alpha; - int num_trans; - png_color_16p trans_values; - int i; - HRESULT hr=S_OK; - - TRACE("(%p,%p)\n", iface, pIPalette); - - EnterCriticalSection(&This->lock); - - color_type = ppng_get_color_type(This->png_ptr, This->info_ptr); - bit_depth = ppng_get_bit_depth(This->png_ptr, This->info_ptr); - - if (color_type == PNG_COLOR_TYPE_PALETTE) - { - ret = ppng_get_PLTE(This->png_ptr, This->info_ptr, &png_palette, &num_palette); - if (!ret) - { - hr = WINCODEC_ERR_PALETTEUNAVAILABLE; - goto end; - } - - if (num_palette > 256) - { - ERR("palette has %i colors?!\n", num_palette); - hr = E_FAIL; - goto end; - } - - ret = ppng_get_tRNS(This->png_ptr, This->info_ptr, &trans_alpha, &num_trans, &trans_values); - if (!ret) num_trans = 0; - - for (i=0; ipng_ptr, This->info_ptr, &trans_alpha, &num_trans, &trans_values); - - if (!ret) - { - hr = WINCODEC_ERR_PALETTEUNAVAILABLE; - goto end; - } - - num_palette = 1 << bit_depth; - - for (i=0; ilock); + hr = png_decoder_create(&decoder_info, &decoder); if (SUCCEEDED(hr)) - hr = IWICPalette_InitializeCustom(pIPalette, palette, num_palette); + hr = CommonDecoder_CreateInstance(decoder, &decoder_info, iid, ppv); return hr; } -static HRESULT WINAPI PngDecoder_Frame_CopyPixels(IWICBitmapFrameDecode *iface, - const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer) -{ - PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface); - TRACE("(%p,%s,%u,%u,%p)\n", iface, debug_wic_rect(prc), cbStride, cbBufferSize, pbBuffer); - - return copy_pixels(This->bpp, This->image_bits, - This->width, This->height, This->stride, - prc, cbStride, cbBufferSize, pbBuffer); -} - -static HRESULT WINAPI PngDecoder_Frame_GetMetadataQueryReader(IWICBitmapFrameDecode *iface, - IWICMetadataQueryReader **ppIMetadataQueryReader) -{ - PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface); - - TRACE("(%p,%p)\n", iface, ppIMetadataQueryReader); - - if (!ppIMetadataQueryReader) - return E_INVALIDARG; - - return MetadataQueryReader_CreateInstance(&This->IWICMetadataBlockReader_iface, NULL, ppIMetadataQueryReader); -} - -static HRESULT WINAPI PngDecoder_Frame_GetColorContexts(IWICBitmapFrameDecode *iface, - UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount) +HRESULT PngEncoder_CreateInstance(REFIID iid, void** ppv) { - PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface); - png_charp name; - BYTE *profile; - png_uint_32 len; - int compression_type; HRESULT hr; + struct encoder *encoder; + struct encoder_info encoder_info; - TRACE("(%p,%u,%p,%p)\n", iface, cCount, ppIColorContexts, pcActualCount); - - if (!pcActualCount) return E_INVALIDARG; - - EnterCriticalSection(&This->lock); + hr = png_encoder_create(&encoder_info, &encoder); - if (ppng_get_iCCP(This->png_ptr, This->info_ptr, &name, &compression_type, (void *)&profile, &len)) - { - if (cCount && ppIColorContexts) - { - hr = IWICColorContext_InitializeFromMemory(*ppIColorContexts, profile, len); - if (FAILED(hr)) - { - LeaveCriticalSection(&This->lock); - return hr; - } - } - *pcActualCount = 1; - } - else - *pcActualCount = 0; - - LeaveCriticalSection(&This->lock); + if (SUCCEEDED(hr)) + hr = CommonEncoder_CreateInstance(encoder, &encoder_info, iid, ppv); - return S_OK; + return hr; } - -static HRESULT WINAPI PngDecoder_Frame_GetThumbnail(IWICBitmapFrameDecode *iface, - IWICBitmapSource **ppIThumbnail) -{ - TRACE("(%p,%p)\n", iface, ppIThumbnail); - - if (!ppIThumbnail) return E_INVALIDARG; - - *ppIThumbnail = NULL; - return WINCODEC_ERR_CODECNOTHUMBNAIL; -} - -static const IWICBitmapFrameDecodeVtbl PngDecoder_FrameVtbl = { - PngDecoder_Frame_QueryInterface, - PngDecoder_Frame_AddRef, - PngDecoder_Frame_Release, - PngDecoder_Frame_GetSize, - PngDecoder_Frame_GetPixelFormat, - PngDecoder_Frame_GetResolution, - PngDecoder_Frame_CopyPalette, - PngDecoder_Frame_CopyPixels, - PngDecoder_Frame_GetMetadataQueryReader, - PngDecoder_Frame_GetColorContexts, - PngDecoder_Frame_GetThumbnail -}; - -static HRESULT WINAPI PngDecoder_Block_QueryInterface(IWICMetadataBlockReader *iface, REFIID iid, - void **ppv) -{ - PngDecoder *This = impl_from_IWICMetadataBlockReader(iface); - return IWICBitmapFrameDecode_QueryInterface(&This->IWICBitmapFrameDecode_iface, iid, ppv); -} - -static ULONG WINAPI PngDecoder_Block_AddRef(IWICMetadataBlockReader *iface) -{ - PngDecoder *This = impl_from_IWICMetadataBlockReader(iface); - return IWICBitmapDecoder_AddRef(&This->IWICBitmapDecoder_iface); -} - -static ULONG WINAPI PngDecoder_Block_Release(IWICMetadataBlockReader *iface) -{ - PngDecoder *This = impl_from_IWICMetadataBlockReader(iface); - return IWICBitmapDecoder_Release(&This->IWICBitmapDecoder_iface); -} - -static HRESULT WINAPI PngDecoder_Block_GetContainerFormat(IWICMetadataBlockReader *iface, - GUID *pguidContainerFormat) -{ - if (!pguidContainerFormat) return E_INVALIDARG; - memcpy(pguidContainerFormat, &GUID_ContainerFormatPng, sizeof(GUID)); - return S_OK; -} - -static HRESULT WINAPI PngDecoder_Block_GetCount(IWICMetadataBlockReader *iface, - UINT *pcCount) -{ - PngDecoder *This = impl_from_IWICMetadataBlockReader(iface); - - TRACE("%p,%p\n", iface, pcCount); - - if (!pcCount) return E_INVALIDARG; - - *pcCount = This->metadata_count; - - return S_OK; -} - -static HRESULT WINAPI PngDecoder_Block_GetReaderByIndex(IWICMetadataBlockReader *iface, - UINT nIndex, IWICMetadataReader **ppIMetadataReader) -{ - PngDecoder *This = impl_from_IWICMetadataBlockReader(iface); - HRESULT hr; - IWICComponentFactory* factory; - IWICStream* stream; - - TRACE("%p,%d,%p\n", iface, nIndex, ppIMetadataReader); - - if (nIndex >= This->metadata_count || !ppIMetadataReader) - return E_INVALIDARG; - - if (!This->metadata_blocks[nIndex].reader) - { - hr = StreamImpl_Create(&stream); - - if (SUCCEEDED(hr)) - { - hr = IWICStream_InitializeFromIStreamRegion(stream, This->stream, - This->metadata_blocks[nIndex].ofs, This->metadata_blocks[nIndex].len); - - if (SUCCEEDED(hr)) - hr = ImagingFactory_CreateInstance(&IID_IWICComponentFactory, (void**)&factory); - - if (SUCCEEDED(hr)) - { - hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory, - &GUID_ContainerFormatPng, NULL, WICMetadataCreationAllowUnknown, - (IStream*)stream, &This->metadata_blocks[nIndex].reader); - - IWICComponentFactory_Release(factory); - } - - IWICStream_Release(stream); - } - - if (FAILED(hr)) - { - *ppIMetadataReader = NULL; - return hr; - } - } - - *ppIMetadataReader = This->metadata_blocks[nIndex].reader; - IWICMetadataReader_AddRef(*ppIMetadataReader); - - return S_OK; -} - -static HRESULT WINAPI PngDecoder_Block_GetEnumerator(IWICMetadataBlockReader *iface, - IEnumUnknown **ppIEnumMetadata) -{ - FIXME("%p,%p\n", iface, ppIEnumMetadata); - return E_NOTIMPL; -} - -static const IWICMetadataBlockReaderVtbl PngDecoder_BlockVtbl = { - PngDecoder_Block_QueryInterface, - PngDecoder_Block_AddRef, - PngDecoder_Block_Release, - PngDecoder_Block_GetContainerFormat, - PngDecoder_Block_GetCount, - PngDecoder_Block_GetReaderByIndex, - PngDecoder_Block_GetEnumerator, -}; - -HRESULT PngDecoder_CreateInstance(REFIID iid, void** ppv) -{ - PngDecoder *This; - HRESULT ret; - - TRACE("(%s,%p)\n", debugstr_guid(iid), ppv); - - *ppv = NULL; - - if (!load_libpng()) - { - ERR("Failed reading PNG because unable to find %s\n",SONAME_LIBPNG); - return E_FAIL; - } - - This = HeapAlloc(GetProcessHeap(), 0, sizeof(PngDecoder)); - if (!This) return E_OUTOFMEMORY; - - This->IWICBitmapDecoder_iface.lpVtbl = &PngDecoder_Vtbl; - This->IWICBitmapFrameDecode_iface.lpVtbl = &PngDecoder_FrameVtbl; - This->IWICMetadataBlockReader_iface.lpVtbl = &PngDecoder_BlockVtbl; - This->ref = 1; - This->png_ptr = NULL; - This->info_ptr = NULL; - This->end_info = NULL; - This->stream = NULL; - This->initialized = FALSE; - This->image_bits = NULL; - InitializeCriticalSection(&This->lock); - This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PngDecoder.lock"); - This->metadata_count = 0; - This->metadata_blocks = NULL; - - ret = IWICBitmapDecoder_QueryInterface(&This->IWICBitmapDecoder_iface, iid, ppv); - IWICBitmapDecoder_Release(&This->IWICBitmapDecoder_iface); - - return ret; -} - -struct png_pixelformat { - const WICPixelFormatGUID *guid; - UINT bpp; - int bit_depth; - int color_type; - BOOL remove_filler; - BOOL swap_rgb; -}; - -static const struct png_pixelformat formats[] = { - {&GUID_WICPixelFormat32bppBGRA, 32, 8, PNG_COLOR_TYPE_RGB_ALPHA, 0, 1}, - {&GUID_WICPixelFormat24bppBGR, 24, 8, PNG_COLOR_TYPE_RGB, 0, 1}, - {&GUID_WICPixelFormatBlackWhite, 1, 1, PNG_COLOR_TYPE_GRAY, 0, 0}, - {&GUID_WICPixelFormat2bppGray, 2, 2, PNG_COLOR_TYPE_GRAY, 0, 0}, - {&GUID_WICPixelFormat4bppGray, 4, 4, PNG_COLOR_TYPE_GRAY, 0, 0}, - {&GUID_WICPixelFormat8bppGray, 8, 8, PNG_COLOR_TYPE_GRAY, 0, 0}, - {&GUID_WICPixelFormat16bppGray, 16, 16, PNG_COLOR_TYPE_GRAY, 0, 0}, - {&GUID_WICPixelFormat32bppBGR, 32, 8, PNG_COLOR_TYPE_RGB, 1, 1}, - {&GUID_WICPixelFormat48bppRGB, 48, 16, PNG_COLOR_TYPE_RGB, 0, 0}, - {&GUID_WICPixelFormat64bppRGBA, 64, 16, PNG_COLOR_TYPE_RGB_ALPHA, 0, 0}, - {&GUID_WICPixelFormat1bppIndexed, 1, 1, PNG_COLOR_TYPE_PALETTE, 0, 0}, - {&GUID_WICPixelFormat2bppIndexed, 2, 2, PNG_COLOR_TYPE_PALETTE, 0, 0}, - {&GUID_WICPixelFormat4bppIndexed, 4, 4, PNG_COLOR_TYPE_PALETTE, 0, 0}, - {&GUID_WICPixelFormat8bppIndexed, 8, 8, PNG_COLOR_TYPE_PALETTE, 0, 0}, - {NULL}, -}; - -typedef struct PngEncoder { - IWICBitmapEncoder IWICBitmapEncoder_iface; - IWICBitmapFrameEncode IWICBitmapFrameEncode_iface; - LONG ref; - IStream *stream; - png_structp png_ptr; - png_infop info_ptr; - UINT frame_count; - BOOL frame_initialized; - const struct png_pixelformat *format; - BOOL info_written; - UINT width, height; - double xres, yres; - UINT lines_written; - BOOL frame_committed; - BOOL committed; - CRITICAL_SECTION lock; - BOOL interlace; - WICPngFilterOption filter; - BYTE *data; - UINT stride; - UINT passes; - WICColor palette[256]; - UINT colors; -} PngEncoder; - -static inline PngEncoder *impl_from_IWICBitmapEncoder(IWICBitmapEncoder *iface) -{ - return CONTAINING_RECORD(iface, PngEncoder, IWICBitmapEncoder_iface); -} - -static inline PngEncoder *impl_from_IWICBitmapFrameEncode(IWICBitmapFrameEncode *iface) -{ - return CONTAINING_RECORD(iface, PngEncoder, IWICBitmapFrameEncode_iface); -} - -static HRESULT WINAPI PngFrameEncode_QueryInterface(IWICBitmapFrameEncode *iface, REFIID iid, - void **ppv) -{ - PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); - - if (!ppv) return E_INVALIDARG; - - if (IsEqualIID(&IID_IUnknown, iid) || - IsEqualIID(&IID_IWICBitmapFrameEncode, iid)) - { - *ppv = &This->IWICBitmapFrameEncode_iface; - } - else - { - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI PngFrameEncode_AddRef(IWICBitmapFrameEncode *iface) -{ - PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - return IWICBitmapEncoder_AddRef(&This->IWICBitmapEncoder_iface); -} - -static ULONG WINAPI PngFrameEncode_Release(IWICBitmapFrameEncode *iface) -{ - PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - return IWICBitmapEncoder_Release(&This->IWICBitmapEncoder_iface); -} - -static HRESULT WINAPI PngFrameEncode_Initialize(IWICBitmapFrameEncode *iface, - IPropertyBag2 *pIEncoderOptions) -{ - PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - WICPngFilterOption filter; - BOOL interlace; - PROPBAG2 opts[2]= {{0}}; - VARIANT opt_values[2]; - HRESULT opt_hres[2]; - HRESULT hr; - - TRACE("(%p,%p)\n", iface, pIEncoderOptions); - - opts[0].pstrName = (LPOLESTR)wszPngInterlaceOption; - opts[0].vt = VT_BOOL; - opts[1].pstrName = (LPOLESTR)wszPngFilterOption; - opts[1].vt = VT_UI1; - - if (pIEncoderOptions) - { - hr = IPropertyBag2_Read(pIEncoderOptions, ARRAY_SIZE(opts), opts, NULL, opt_values, opt_hres); - - if (FAILED(hr)) - return hr; - - if (V_VT(&opt_values[0]) == VT_EMPTY) - interlace = FALSE; - else - interlace = (V_BOOL(&opt_values[0]) != 0); - - filter = V_UI1(&opt_values[1]); - if (filter > WICPngFilterAdaptive) - { - WARN("Unrecognized filter option value %u.\n", filter); - filter = WICPngFilterUnspecified; - } - } - else - { - interlace = FALSE; - filter = WICPngFilterUnspecified; - } - - EnterCriticalSection(&This->lock); - - if (This->frame_initialized) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - This->interlace = interlace; - This->filter = filter; - - This->frame_initialized = TRUE; - - LeaveCriticalSection(&This->lock); - - return S_OK; -} - -static HRESULT WINAPI PngFrameEncode_SetSize(IWICBitmapFrameEncode *iface, - UINT uiWidth, UINT uiHeight) -{ - PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - TRACE("(%p,%u,%u)\n", iface, uiWidth, uiHeight); - - EnterCriticalSection(&This->lock); - - if (!This->frame_initialized || This->info_written) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - This->width = uiWidth; - This->height = uiHeight; - - LeaveCriticalSection(&This->lock); - - return S_OK; -} - -static HRESULT WINAPI PngFrameEncode_SetResolution(IWICBitmapFrameEncode *iface, - double dpiX, double dpiY) -{ - PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - TRACE("(%p,%0.2f,%0.2f)\n", iface, dpiX, dpiY); - - EnterCriticalSection(&This->lock); - - if (!This->frame_initialized || This->info_written) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - This->xres = dpiX; - This->yres = dpiY; - - LeaveCriticalSection(&This->lock); - - return S_OK; -} - -static HRESULT WINAPI PngFrameEncode_SetPixelFormat(IWICBitmapFrameEncode *iface, - WICPixelFormatGUID *pPixelFormat) -{ - PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - int i; - TRACE("(%p,%s)\n", iface, debugstr_guid(pPixelFormat)); - - EnterCriticalSection(&This->lock); - - if (!This->frame_initialized || This->info_written) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - for (i=0; formats[i].guid; i++) - { - if (memcmp(formats[i].guid, pPixelFormat, sizeof(GUID)) == 0) - break; - } - - if (!formats[i].guid) i = 0; - - This->format = &formats[i]; - memcpy(pPixelFormat, This->format->guid, sizeof(GUID)); - - LeaveCriticalSection(&This->lock); - - return S_OK; -} - -static HRESULT WINAPI PngFrameEncode_SetColorContexts(IWICBitmapFrameEncode *iface, - UINT cCount, IWICColorContext **ppIColorContext) -{ - FIXME("(%p,%u,%p): stub\n", iface, cCount, ppIColorContext); - return E_NOTIMPL; -} - -static HRESULT WINAPI PngFrameEncode_SetPalette(IWICBitmapFrameEncode *iface, - IWICPalette *palette) -{ - PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - HRESULT hr; - - TRACE("(%p,%p)\n", iface, palette); - - if (!palette) return E_INVALIDARG; - - EnterCriticalSection(&This->lock); - - if (This->frame_initialized) - hr = IWICPalette_GetColors(palette, 256, This->palette, &This->colors); - else - hr = WINCODEC_ERR_NOTINITIALIZED; - - LeaveCriticalSection(&This->lock); - return hr; -} - -static HRESULT WINAPI PngFrameEncode_SetThumbnail(IWICBitmapFrameEncode *iface, - IWICBitmapSource *pIThumbnail) -{ - FIXME("(%p,%p): stub\n", iface, pIThumbnail); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI PngFrameEncode_WritePixels(IWICBitmapFrameEncode *iface, - UINT lineCount, UINT cbStride, UINT cbBufferSize, BYTE *pbPixels) -{ - PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - png_byte **row_pointers=NULL; - UINT i; - jmp_buf jmpbuf; - TRACE("(%p,%u,%u,%u,%p)\n", iface, lineCount, cbStride, cbBufferSize, pbPixels); - - EnterCriticalSection(&This->lock); - - if (!This->frame_initialized || !This->width || !This->height || !This->format) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - if (lineCount == 0 || lineCount + This->lines_written > This->height) - { - LeaveCriticalSection(&This->lock); - return E_INVALIDARG; - } - - /* set up setjmp/longjmp error handling */ - if (setjmp(jmpbuf)) - { - LeaveCriticalSection(&This->lock); - HeapFree(GetProcessHeap(), 0, row_pointers); - return E_FAIL; - } - ppng_set_error_fn(This->png_ptr, jmpbuf, user_error_fn, user_warning_fn); - - if (!This->info_written) - { - if (This->interlace) - { - /* libpng requires us to write all data multiple times in this case. */ - This->stride = (This->format->bpp * This->width + 7)/8; - This->data = HeapAlloc(GetProcessHeap(), 0, This->height * This->stride); - if (!This->data) - { - LeaveCriticalSection(&This->lock); - return E_OUTOFMEMORY; - } - } - - /* Tell PNG we need to byte swap if writing a >8-bpp image */ - if (This->format->bit_depth > 8) - ppng_set_swap(This->png_ptr); - - ppng_set_IHDR(This->png_ptr, This->info_ptr, This->width, This->height, - This->format->bit_depth, This->format->color_type, - This->interlace ? PNG_INTERLACE_ADAM7 : PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); - - if (This->xres != 0.0 && This->yres != 0.0) - { - ppng_set_pHYs(This->png_ptr, This->info_ptr, (This->xres+0.0127) / 0.0254, - (This->yres+0.0127) / 0.0254, PNG_RESOLUTION_METER); - } - - if (This->format->color_type == PNG_COLOR_TYPE_PALETTE && This->colors) - { - png_color png_palette[256]; - png_byte trans[256]; - UINT i, num_trans = 0, colors; - - /* Newer libpng versions don't accept larger palettes than the declared - * bit depth, so we need to generate the palette of the correct length. - */ - colors = min(This->colors, 1 << This->format->bit_depth); - - for (i = 0; i < colors; i++) - { - png_palette[i].red = (This->palette[i] >> 16) & 0xff; - png_palette[i].green = (This->palette[i] >> 8) & 0xff; - png_palette[i].blue = This->palette[i] & 0xff; - trans[i] = (This->palette[i] >> 24) & 0xff; - if (trans[i] != 0xff) - num_trans = i+1; - } - - ppng_set_PLTE(This->png_ptr, This->info_ptr, png_palette, colors); - - if (num_trans) - ppng_set_tRNS(This->png_ptr, This->info_ptr, trans, num_trans, NULL); - } - - ppng_write_info(This->png_ptr, This->info_ptr); - - if (This->format->remove_filler) - ppng_set_filler(This->png_ptr, 0, PNG_FILLER_AFTER); - - if (This->format->swap_rgb) - ppng_set_bgr(This->png_ptr); - - if (This->interlace) - This->passes = ppng_set_interlace_handling(This->png_ptr); - - if (This->filter != WICPngFilterUnspecified) - { - static const int png_filter_map[] = - { - /* WICPngFilterUnspecified */ PNG_NO_FILTERS, - /* WICPngFilterNone */ PNG_FILTER_NONE, - /* WICPngFilterSub */ PNG_FILTER_SUB, - /* WICPngFilterUp */ PNG_FILTER_UP, - /* WICPngFilterAverage */ PNG_FILTER_AVG, - /* WICPngFilterPaeth */ PNG_FILTER_PAETH, - /* WICPngFilterAdaptive */ PNG_ALL_FILTERS, - }; - - ppng_set_filter(This->png_ptr, 0, png_filter_map[This->filter]); - } - - This->info_written = TRUE; - } - - if (This->interlace) - { - /* Just store the data so we can write it in multiple passes in Commit. */ - for (i=0; idata + This->stride * (This->lines_written + i), - pbPixels + cbStride * i, - This->stride); - - This->lines_written += lineCount; - - LeaveCriticalSection(&This->lock); - return S_OK; - } - - row_pointers = HeapAlloc(GetProcessHeap(), 0, lineCount * sizeof(png_byte*)); - if (!row_pointers) - { - LeaveCriticalSection(&This->lock); - return E_OUTOFMEMORY; - } - - for (i=0; ipng_ptr, row_pointers, lineCount); - This->lines_written += lineCount; - - LeaveCriticalSection(&This->lock); - - HeapFree(GetProcessHeap(), 0, row_pointers); - - return S_OK; -} - -static HRESULT WINAPI PngFrameEncode_WriteSource(IWICBitmapFrameEncode *iface, - IWICBitmapSource *pIBitmapSource, WICRect *prc) -{ - PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - HRESULT hr; - TRACE("(%p,%p,%s)\n", iface, pIBitmapSource, debug_wic_rect(prc)); - - if (!This->frame_initialized) - return WINCODEC_ERR_WRONGSTATE; - - hr = configure_write_source(iface, pIBitmapSource, prc, - This->format ? This->format->guid : NULL, This->width, This->height, - This->xres, This->yres); - - if (SUCCEEDED(hr)) - { - hr = write_source(iface, pIBitmapSource, prc, - This->format->guid, This->format->bpp, This->width, This->height); - } - - return hr; -} - -static HRESULT WINAPI PngFrameEncode_Commit(IWICBitmapFrameEncode *iface) -{ - PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - png_byte **row_pointers=NULL; - jmp_buf jmpbuf; - TRACE("(%p)\n", iface); - - EnterCriticalSection(&This->lock); - - if (!This->info_written || This->lines_written != This->height || This->frame_committed) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - /* set up setjmp/longjmp error handling */ - if (setjmp(jmpbuf)) - { - LeaveCriticalSection(&This->lock); - HeapFree(GetProcessHeap(), 0, row_pointers); - return E_FAIL; - } - ppng_set_error_fn(This->png_ptr, jmpbuf, user_error_fn, user_warning_fn); - - if (This->interlace) - { - int i; - - row_pointers = HeapAlloc(GetProcessHeap(), 0, This->height * sizeof(png_byte*)); - if (!row_pointers) - { - LeaveCriticalSection(&This->lock); - return E_OUTOFMEMORY; - } - - for (i=0; iheight; i++) - row_pointers[i] = This->data + This->stride * i; - - for (i=0; ipasses; i++) - ppng_write_rows(This->png_ptr, row_pointers, This->height); - } - - ppng_write_end(This->png_ptr, This->info_ptr); - - This->frame_committed = TRUE; - - HeapFree(GetProcessHeap(), 0, row_pointers); - - LeaveCriticalSection(&This->lock); - - return S_OK; -} - -static HRESULT WINAPI PngFrameEncode_GetMetadataQueryWriter(IWICBitmapFrameEncode *iface, - IWICMetadataQueryWriter **ppIMetadataQueryWriter) -{ - FIXME("(%p, %p): stub\n", iface, ppIMetadataQueryWriter); - return E_NOTIMPL; -} - -static const IWICBitmapFrameEncodeVtbl PngEncoder_FrameVtbl = { - PngFrameEncode_QueryInterface, - PngFrameEncode_AddRef, - PngFrameEncode_Release, - PngFrameEncode_Initialize, - PngFrameEncode_SetSize, - PngFrameEncode_SetResolution, - PngFrameEncode_SetPixelFormat, - PngFrameEncode_SetColorContexts, - PngFrameEncode_SetPalette, - PngFrameEncode_SetThumbnail, - PngFrameEncode_WritePixels, - PngFrameEncode_WriteSource, - PngFrameEncode_Commit, - PngFrameEncode_GetMetadataQueryWriter -}; - -static HRESULT WINAPI PngEncoder_QueryInterface(IWICBitmapEncoder *iface, REFIID iid, - void **ppv) -{ - PngEncoder *This = impl_from_IWICBitmapEncoder(iface); - TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); - - if (!ppv) return E_INVALIDARG; - - if (IsEqualIID(&IID_IUnknown, iid) || - IsEqualIID(&IID_IWICBitmapEncoder, iid)) - { - *ppv = &This->IWICBitmapEncoder_iface; - } - else - { - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI PngEncoder_AddRef(IWICBitmapEncoder *iface) -{ - PngEncoder *This = impl_from_IWICBitmapEncoder(iface); - ULONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) refcount=%u\n", iface, ref); - - return ref; -} - -static ULONG WINAPI PngEncoder_Release(IWICBitmapEncoder *iface) -{ - PngEncoder *This = impl_from_IWICBitmapEncoder(iface); - ULONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p) refcount=%u\n", iface, ref); - - if (ref == 0) - { - This->lock.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&This->lock); - if (This->png_ptr) - ppng_destroy_write_struct(&This->png_ptr, &This->info_ptr); - if (This->stream) - IStream_Release(This->stream); - HeapFree(GetProcessHeap(), 0, This->data); - HeapFree(GetProcessHeap(), 0, This); - } - - return ref; -} - -static void user_write_data(png_structp png_ptr, png_bytep data, png_size_t length) -{ - PngEncoder *This = ppng_get_io_ptr(png_ptr); - HRESULT hr; - ULONG byteswritten; - - hr = IStream_Write(This->stream, data, length, &byteswritten); - if (FAILED(hr) || byteswritten != length) - { - ppng_error(png_ptr, "failed writing data"); - } -} - -static void user_flush(png_structp png_ptr) -{ -} - -static HRESULT WINAPI PngEncoder_Initialize(IWICBitmapEncoder *iface, - IStream *pIStream, WICBitmapEncoderCacheOption cacheOption) -{ - PngEncoder *This = impl_from_IWICBitmapEncoder(iface); - jmp_buf jmpbuf; - - TRACE("(%p,%p,%u)\n", iface, pIStream, cacheOption); - - EnterCriticalSection(&This->lock); - - if (This->png_ptr) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - /* initialize libpng */ - This->png_ptr = ppng_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (!This->png_ptr) - { - LeaveCriticalSection(&This->lock); - return E_FAIL; - } - - This->info_ptr = ppng_create_info_struct(This->png_ptr); - if (!This->info_ptr) - { - ppng_destroy_write_struct(&This->png_ptr, NULL); - This->png_ptr = NULL; - LeaveCriticalSection(&This->lock); - return E_FAIL; - } - - IStream_AddRef(pIStream); - This->stream = pIStream; - - /* set up setjmp/longjmp error handling */ - if (setjmp(jmpbuf)) - { - ppng_destroy_write_struct(&This->png_ptr, &This->info_ptr); - This->png_ptr = NULL; - IStream_Release(This->stream); - This->stream = NULL; - LeaveCriticalSection(&This->lock); - return E_FAIL; - } - ppng_set_error_fn(This->png_ptr, jmpbuf, user_error_fn, user_warning_fn); - - /* set up custom i/o handling */ - ppng_set_write_fn(This->png_ptr, This, user_write_data, user_flush); - - LeaveCriticalSection(&This->lock); - - return S_OK; -} - -static HRESULT WINAPI PngEncoder_GetContainerFormat(IWICBitmapEncoder *iface, GUID *format) -{ - TRACE("(%p,%p)\n", iface, format); - - if (!format) - return E_INVALIDARG; - - memcpy(format, &GUID_ContainerFormatPng, sizeof(*format)); - return S_OK; -} - -static HRESULT WINAPI PngEncoder_GetEncoderInfo(IWICBitmapEncoder *iface, IWICBitmapEncoderInfo **info) -{ - IWICComponentInfo *comp_info; - HRESULT hr; - - TRACE("%p,%p\n", iface, info); - - if (!info) return E_INVALIDARG; - - hr = CreateComponentInfo(&CLSID_WICPngEncoder, &comp_info); - if (hr == S_OK) - { - hr = IWICComponentInfo_QueryInterface(comp_info, &IID_IWICBitmapEncoderInfo, (void **)info); - IWICComponentInfo_Release(comp_info); - } - return hr; -} - -static HRESULT WINAPI PngEncoder_SetColorContexts(IWICBitmapEncoder *iface, - UINT cCount, IWICColorContext **ppIColorContext) -{ - FIXME("(%p,%u,%p): stub\n", iface, cCount, ppIColorContext); - return E_NOTIMPL; -} - -static HRESULT WINAPI PngEncoder_SetPalette(IWICBitmapEncoder *iface, IWICPalette *palette) -{ - PngEncoder *This = impl_from_IWICBitmapEncoder(iface); - HRESULT hr; - - TRACE("(%p,%p)\n", iface, palette); - - EnterCriticalSection(&This->lock); - - hr = This->stream ? WINCODEC_ERR_UNSUPPORTEDOPERATION : WINCODEC_ERR_NOTINITIALIZED; - - LeaveCriticalSection(&This->lock); - - return hr; -} - -static HRESULT WINAPI PngEncoder_SetThumbnail(IWICBitmapEncoder *iface, IWICBitmapSource *pIThumbnail) -{ - TRACE("(%p,%p)\n", iface, pIThumbnail); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI PngEncoder_SetPreview(IWICBitmapEncoder *iface, IWICBitmapSource *pIPreview) -{ - TRACE("(%p,%p)\n", iface, pIPreview); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI PngEncoder_CreateNewFrame(IWICBitmapEncoder *iface, - IWICBitmapFrameEncode **ppIFrameEncode, IPropertyBag2 **ppIEncoderOptions) -{ - PngEncoder *This = impl_from_IWICBitmapEncoder(iface); - HRESULT hr; - static const PROPBAG2 opts[2] = - { - { PROPBAG2_TYPE_DATA, VT_BOOL, 0, 0, (LPOLESTR)wszPngInterlaceOption }, - { PROPBAG2_TYPE_DATA, VT_UI1, 0, 0, (LPOLESTR)wszPngFilterOption }, - }; - - TRACE("(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions); - - EnterCriticalSection(&This->lock); - - if (This->frame_count != 0) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; - } - - if (!This->stream) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_NOTINITIALIZED; - } - - if (ppIEncoderOptions) - { - hr = CreatePropertyBag2(opts, ARRAY_SIZE(opts), ppIEncoderOptions); - if (FAILED(hr)) - { - LeaveCriticalSection(&This->lock); - return hr; - } - } - - This->frame_count = 1; - - LeaveCriticalSection(&This->lock); - - IWICBitmapEncoder_AddRef(iface); - *ppIFrameEncode = &This->IWICBitmapFrameEncode_iface; - - return S_OK; -} - -static HRESULT WINAPI PngEncoder_Commit(IWICBitmapEncoder *iface) -{ - PngEncoder *This = impl_from_IWICBitmapEncoder(iface); - TRACE("(%p)\n", iface); - - EnterCriticalSection(&This->lock); - - if (!This->frame_committed || This->committed) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - This->committed = TRUE; - - LeaveCriticalSection(&This->lock); - - return S_OK; -} - -static HRESULT WINAPI PngEncoder_GetMetadataQueryWriter(IWICBitmapEncoder *iface, - IWICMetadataQueryWriter **ppIMetadataQueryWriter) -{ - FIXME("(%p,%p): stub\n", iface, ppIMetadataQueryWriter); - return E_NOTIMPL; -} - -static const IWICBitmapEncoderVtbl PngEncoder_Vtbl = { - PngEncoder_QueryInterface, - PngEncoder_AddRef, - PngEncoder_Release, - PngEncoder_Initialize, - PngEncoder_GetContainerFormat, - PngEncoder_GetEncoderInfo, - PngEncoder_SetColorContexts, - PngEncoder_SetPalette, - PngEncoder_SetThumbnail, - PngEncoder_SetPreview, - PngEncoder_CreateNewFrame, - PngEncoder_Commit, - PngEncoder_GetMetadataQueryWriter -}; - -HRESULT PngEncoder_CreateInstance(REFIID iid, void** ppv) -{ - PngEncoder *This; - HRESULT ret; - - TRACE("(%s,%p)\n", debugstr_guid(iid), ppv); - - *ppv = NULL; - - if (!load_libpng()) - { - ERR("Failed writing PNG because unable to find %s\n",SONAME_LIBPNG); - return E_FAIL; - } - - This = HeapAlloc(GetProcessHeap(), 0, sizeof(PngEncoder)); - if (!This) return E_OUTOFMEMORY; - - This->IWICBitmapEncoder_iface.lpVtbl = &PngEncoder_Vtbl; - This->IWICBitmapFrameEncode_iface.lpVtbl = &PngEncoder_FrameVtbl; - This->ref = 1; - This->png_ptr = NULL; - This->info_ptr = NULL; - This->stream = NULL; - This->frame_count = 0; - This->frame_initialized = FALSE; - This->format = NULL; - This->info_written = FALSE; - This->width = 0; - This->height = 0; - This->xres = 0.0; - This->yres = 0.0; - This->lines_written = 0; - This->frame_committed = FALSE; - This->committed = FALSE; - This->data = NULL; - This->colors = 0; - InitializeCriticalSection(&This->lock); - This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PngEncoder.lock"); - - ret = IWICBitmapEncoder_QueryInterface(&This->IWICBitmapEncoder_iface, iid, ppv); - IWICBitmapEncoder_Release(&This->IWICBitmapEncoder_iface); - - return ret; -} - -#else /* !HAVE_PNG_H */ - -HRESULT PngDecoder_CreateInstance(REFIID iid, void** ppv) -{ - ERR("Trying to load PNG picture, but PNG support is not compiled in.\n"); - return E_FAIL; -} - -HRESULT PngEncoder_CreateInstance(REFIID iid, void** ppv) -{ - ERR("Trying to save PNG picture, but PNG support is not compiled in.\n"); - return E_FAIL; -} - -#endif diff --git a/dll/win32/windowscodecs/precomp.h b/dll/win32/windowscodecs/precomp.h index 0d0ac5c7af705..39b7e62233215 100644 --- a/dll/win32/windowscodecs/precomp.h +++ b/dll/win32/windowscodecs/precomp.h @@ -9,8 +9,6 @@ #define COM_NO_WINDOWS_H #define COBJMACROS -#define NONAMELESSUNION -#define NONAMELESSSTRUCT #include #include @@ -18,6 +16,7 @@ #include #include #include +#include #include "wincodecs_private.h" diff --git a/dll/win32/windowscodecs/propertybag.c b/dll/win32/windowscodecs/propertybag.c index e9d1af9670d43..c91995b143edd 100644 --- a/dll/win32/windowscodecs/propertybag.c +++ b/dll/win32/windowscodecs/propertybag.c @@ -17,8 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" - #include #define COBJMACROS @@ -26,7 +24,6 @@ #include "windef.h" #include "winbase.h" #include "objbase.h" -#include "wine/unicode.h" #include "wincodecs_private.h" @@ -75,7 +72,7 @@ static ULONG WINAPI PropertyBag_AddRef(IPropertyBag2 *iface) PropertyBag *This = impl_from_IPropertyBag2(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -85,7 +82,7 @@ static ULONG WINAPI PropertyBag_Release(IPropertyBag2 *iface) PropertyBag *This = impl_from_IPropertyBag2(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { @@ -99,9 +96,9 @@ static ULONG WINAPI PropertyBag_Release(IPropertyBag2 *iface) } } - HeapFree(GetProcessHeap(), 0, This->properties); - HeapFree(GetProcessHeap(), 0, This->values); - HeapFree(GetProcessHeap(), 0, This); + free(This->properties); + free(This->values); + free(This); } return ref; @@ -117,7 +114,7 @@ static LONG find_item(PropertyBag *This, LPCOLESTR name) for (i=0; i < This->prop_count; i++) { - if (strcmpW(name, This->properties[i].pstrName) == 0) + if (wcscmp(name, This->properties[i].pstrName) == 0) return i; } @@ -131,7 +128,7 @@ static HRESULT WINAPI PropertyBag_Read(IPropertyBag2 *iface, ULONG cProperties, ULONG i; PropertyBag *This = impl_from_IPropertyBag2(iface); - TRACE("(%p,%u,%p,%p,%p,%p)\n", iface, cProperties, pPropBag, pErrLog, pvarValue, phrError); + TRACE("(%p,%lu,%p,%p,%p,%p)\n", iface, cProperties, pPropBag, pErrLog, pvarValue, phrError); for (i=0; i < cProperties; i++) { @@ -166,7 +163,7 @@ static HRESULT WINAPI PropertyBag_Write(IPropertyBag2 *iface, ULONG cProperties, ULONG i; PropertyBag *This = impl_from_IPropertyBag2(iface); - TRACE("(%p,%u,%p,%p)\n", iface, cProperties, pPropBag, pvarValue); + TRACE("(%p,%lu,%p,%p)\n", iface, cProperties, pPropBag, pvarValue); for (i=0; i < cProperties; i++) { @@ -220,11 +217,11 @@ static HRESULT copy_propbag2(PROPBAG2 *dest, const PROPBAG2 *src) dest->dwHint = src->dwHint; dest->dwType = src->dwType; dest->vt = src->vt; - dest->pstrName = CoTaskMemAlloc((strlenW(src->pstrName)+1) * sizeof(WCHAR)); + dest->pstrName = CoTaskMemAlloc((lstrlenW(src->pstrName)+1) * sizeof(WCHAR)); if(!dest->pstrName) return E_OUTOFMEMORY; - strcpyW(dest->pstrName, src->pstrName); + lstrcpyW(dest->pstrName, src->pstrName); return S_OK; } @@ -236,7 +233,7 @@ static HRESULT WINAPI PropertyBag_GetPropertyInfo(IPropertyBag2 *iface, ULONG iP ULONG i; PropertyBag *This = impl_from_IPropertyBag2(iface); - TRACE("(%p,%u,%u,%p,%p)\n", iface, iProperty, cProperties, pPropBag, pcProperties); + TRACE("(%p,%lu,%lu,%p,%p)\n", iface, iProperty, cProperties, pPropBag, pcProperties); if (iProperty >= This->prop_count && iProperty > 0) return WINCODEC_ERR_VALUEOUTOFRANGE; @@ -263,7 +260,7 @@ static HRESULT WINAPI PropertyBag_GetPropertyInfo(IPropertyBag2 *iface, ULONG iP static HRESULT WINAPI PropertyBag_LoadObject(IPropertyBag2 *iface, LPCOLESTR pstrName, DWORD dwHint, IUnknown *pUnkObject, IErrorLog *pErrLog) { - FIXME("(%p,%s,%u,%p,%p): stub\n", iface, debugstr_w(pstrName), dwHint, pUnkObject, pErrLog); + FIXME("(%p,%s,%lu,%p,%p): stub\n", iface, debugstr_w(pstrName), dwHint, pUnkObject, pErrLog); return E_NOTIMPL; } @@ -285,7 +282,7 @@ HRESULT CreatePropertyBag2(const PROPBAG2 *options, UINT count, HRESULT res = S_OK; PropertyBag *This; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(PropertyBag)); + This = malloc(sizeof(PropertyBag)); if (!This) return E_OUTOFMEMORY; This->IPropertyBag2_iface.lpVtbl = &PropertyBag_Vtbl; @@ -299,8 +296,8 @@ HRESULT CreatePropertyBag2(const PROPBAG2 *options, UINT count, } else { - This->properties = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PROPBAG2)*count); - This->values = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(VARIANT)*count); + This->properties = calloc(count, sizeof(PROPBAG2)); + This->values = calloc(count, sizeof(VARIANT)); if (!This->properties || !This->values) res = E_OUTOFMEMORY; diff --git a/dll/win32/windowscodecs/proxy.c b/dll/win32/windowscodecs/proxy.c index 34b618e8d9123..35d67db1e3edd 100644 --- a/dll/win32/windowscodecs/proxy.c +++ b/dll/win32/windowscodecs/proxy.c @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" - #include #define COBJMACROS diff --git a/dll/win32/windowscodecs/regsvr.c b/dll/win32/windowscodecs/regsvr.c index 158329dd845d7..c74fcecb3a2cc 100644 --- a/dll/win32/windowscodecs/regsvr.c +++ b/dll/win32/windowscodecs/regsvr.c @@ -31,7 +31,6 @@ #include "ocidl.h" #include "wine/debug.h" -#include "wine/unicode.h" #include "wincodecs_private.h" @@ -148,37 +147,36 @@ static HRESULT unregister_pixelformats(struct regsvr_pixelformat const *list); /*********************************************************************** * static string constants */ -static const WCHAR clsid_keyname[] = { - 'C', 'L', 'S', 'I', 'D', 0 }; +static const WCHAR clsid_keyname[] = L"CLSID"; static const char author_valuename[] = "Author"; static const char friendlyname_valuename[] = "FriendlyName"; -static const WCHAR vendor_valuename[] = {'V','e','n','d','o','r',0}; -static const WCHAR containerformat_valuename[] = {'C','o','n','t','a','i','n','e','r','F','o','r','m','a','t',0}; +static const WCHAR vendor_valuename[] = L"Vendor"; +static const WCHAR containerformat_valuename[] = L"ContainerFormat"; static const char version_valuename[] = "Version"; static const char mimetypes_valuename[] = "MimeTypes"; static const char extensions_valuename[] = "FileExtensions"; -static const WCHAR formats_keyname[] = {'F','o','r','m','a','t','s',0}; -static const WCHAR patterns_keyname[] = {'P','a','t','t','e','r','n','s',0}; -static const WCHAR instance_keyname[] = {'I','n','s','t','a','n','c','e',0}; -static const WCHAR clsid_valuename[] = {'C','L','S','I','D',0}; +static const WCHAR formats_keyname[] = L"Formats"; +static const WCHAR patterns_keyname[] = L"Patterns"; +static const WCHAR instance_keyname[] = L"Instance"; +static const WCHAR clsid_valuename[] = L"CLSID"; static const char length_valuename[] = "Length"; static const char position_valuename[] = "Position"; static const char pattern_valuename[] = "Pattern"; static const char mask_valuename[] = "Mask"; static const char endofstream_valuename[] = "EndOfStream"; -static const WCHAR pixelformats_keyname[] = {'P','i','x','e','l','F','o','r','m','a','t','s',0}; -static const WCHAR metadataformat_valuename[] = {'M','e','t','a','d','a','t','a','F','o','r','m','a','t',0}; +static const WCHAR pixelformats_keyname[] = L"PixelFormats"; +static const WCHAR metadataformat_valuename[] = L"MetadataFormat"; static const char specversion_valuename[] = "SpecVersion"; static const char requiresfullstream_valuename[] = "RequiresFullStream"; static const char supportspadding_valuename[] = "SupportsPadding"; static const char requiresfixedsize_valuename[] = "FixedSize"; -static const WCHAR containers_keyname[] = {'C','o','n','t','a','i','n','e','r','s',0}; +static const WCHAR containers_keyname[] = L"Containers"; static const char dataoffset_valuename[] = "DataOffset"; static const char bitsperpixel_valuename[] = "BitLength"; static const char channelcount_valuename[] = "ChannelCount"; static const char numericrepresentation_valuename[] = "NumericRepresentation"; static const char supportstransparency_valuename[] = "SupportsTransparency"; -static const WCHAR channelmasks_keyname[] = {'C','h','a','n','n','e','l','M','a','s','k','s',0}; +static const WCHAR channelmasks_keyname[] = L"ChannelMasks"; /*********************************************************************** * register_decoders @@ -306,8 +304,7 @@ static HRESULT register_decoders(struct regsvr_decoder const *list) for (i=0; list->patterns[i].length; i++) { HKEY pattern_key; - static const WCHAR int_format[] = {'%','i',0}; - snprintfW(buf, 39, int_format, i); + swprintf(buf, 39, L"%i", i); res = RegCreateKeyExW(patterns_key, buf, 0, NULL, 0, KEY_READ | KEY_WRITE, NULL, &pattern_key, NULL); if (res != ERROR_SUCCESS) break; @@ -852,8 +849,7 @@ static HRESULT register_metadatareaders(struct regsvr_metadatareader const *list for (i=0; container->patterns[i].length; i++) { HKEY pattern_key; - static const WCHAR int_format[] = {'%','i',0}; - snprintfW(buf, 39, int_format, i); + swprintf(buf, 39, L"%i", i); res = RegCreateKeyExW(format_key, buf, 0, NULL, 0, KEY_READ | KEY_WRITE, NULL, &pattern_key, NULL); if (res != ERROR_SUCCESS) break; @@ -1032,7 +1028,6 @@ static HRESULT register_pixelformats(struct regsvr_pixelformat const *list) if (res != ERROR_SUCCESS) goto error_close_clsid_key; if (list->channelmasks) { - static const WCHAR valuename_format[] = {'%','d',0}; HKEY masks_key; UINT i, mask_size; WCHAR mask_valuename[11]; @@ -1044,7 +1039,7 @@ static HRESULT register_pixelformats(struct regsvr_pixelformat const *list) if (res != ERROR_SUCCESS) goto error_close_clsid_key; for (i=0; i < list->channelcount; i++) { - sprintfW(mask_valuename, valuename_format, i); + swprintf(mask_valuename, ARRAY_SIZE(mask_valuename), L"%d", i); res = RegSetValueExW(masks_key, mask_valuename, 0, REG_BINARY, list->channelmasks[i], mask_size); if (res != ERROR_SUCCESS) break; @@ -1140,6 +1135,18 @@ static struct decoder_pattern const bmp_patterns[] = { {0} }; +static const BYTE dds_magic[] = "DDS "; + +static GUID const * const dds_formats[] = { + &GUID_WICPixelFormat32bppBGRA, + NULL +}; + +static struct decoder_pattern const dds_patterns[] = { + {4,0,dds_magic,mask_all,0}, + {0} +}; + static const BYTE gif87a_magic[6] = "GIF87a"; static const BYTE gif89a_magic[6] = "GIF89a"; @@ -1180,6 +1187,48 @@ static struct decoder_pattern const jpeg_patterns[] = { {0} }; +static const BYTE wmp_magic_v0[] = {0x49, 0x49, 0xbc, 0x00}; +static const BYTE wmp_magic_v1[] = {0x49, 0x49, 0xbc, 0x01}; + +static GUID const * const wmp_formats[] = { + &GUID_WICPixelFormat128bppRGBAFixedPoint, + &GUID_WICPixelFormat128bppRGBAFloat, + &GUID_WICPixelFormat128bppRGBFloat, + &GUID_WICPixelFormat16bppBGR555, + &GUID_WICPixelFormat16bppBGR565, + &GUID_WICPixelFormat16bppGray, + &GUID_WICPixelFormat16bppGrayFixedPoint, + &GUID_WICPixelFormat16bppGrayHalf, + &GUID_WICPixelFormat24bppBGR, + &GUID_WICPixelFormat24bppRGB, + &GUID_WICPixelFormat32bppBGR, + &GUID_WICPixelFormat32bppBGR101010, + &GUID_WICPixelFormat32bppBGRA, + &GUID_WICPixelFormat32bppCMYK, + &GUID_WICPixelFormat32bppGrayFixedPoint, + &GUID_WICPixelFormat32bppGrayFloat, + &GUID_WICPixelFormat32bppRGBE, + &GUID_WICPixelFormat40bppCMYKAlpha, + &GUID_WICPixelFormat48bppRGB, + &GUID_WICPixelFormat48bppRGBFixedPoint, + &GUID_WICPixelFormat48bppRGBHalf, + &GUID_WICPixelFormat64bppCMYK, + &GUID_WICPixelFormat64bppRGBA, + &GUID_WICPixelFormat64bppRGBAFixedPoint, + &GUID_WICPixelFormat64bppRGBAHalf, + &GUID_WICPixelFormat80bppCMYKAlpha, + &GUID_WICPixelFormat8bppGray, + &GUID_WICPixelFormat96bppRGBFixedPoint, + &GUID_WICPixelFormatBlackWhite, + NULL +}; + +static struct decoder_pattern const wmp_patterns[] = { + {4,0,wmp_magic_v0,mask_all,0}, + {4,0,wmp_magic_v1,mask_all,0}, + {0} +}; + static const BYTE png_magic[] = {137,80,78,71,13,10,26,10}; static GUID const * const png_formats[] = { @@ -1226,7 +1275,9 @@ static GUID const * const tiff_decode_formats[] = { &GUID_WICPixelFormat64bppPRGBA, &GUID_WICPixelFormat32bppCMYK, &GUID_WICPixelFormat64bppCMYK, + &GUID_WICPixelFormat96bppRGBFloat, &GUID_WICPixelFormat128bppRGBAFloat, + &GUID_WICPixelFormat128bppPRGBAFloat, NULL }; @@ -1278,6 +1329,17 @@ static struct regsvr_decoder const decoder_list[] = { bmp_formats, bmp_patterns }, + { &CLSID_WICDdsDecoder, + "The Wine Project", + "DDS Decoder", + "1.0.0.0", + &GUID_VendorMicrosoft, + &GUID_ContainerFormatDds, + "image/vnd.ms-dds", + ".dds", + dds_formats, + dds_patterns + }, { &CLSID_WICGifDecoder, "The Wine Project", "GIF Decoder", @@ -1311,6 +1373,17 @@ static struct regsvr_decoder const decoder_list[] = { jpeg_formats, jpeg_patterns }, + { &CLSID_WICWmpDecoder, + "The Wine Project", + "JPEG-XR Decoder", + "1.0.0.0", + &GUID_VendorMicrosoft, + &GUID_ContainerFormatWmp, + "image/jxr", + ".jxr;.hdp;.wdp", + wmp_formats, + wmp_patterns + }, { &CLSID_WICPngDecoder, "The Wine Project", "PNG Decoder", @@ -1393,11 +1466,6 @@ static GUID const * const tiff_encode_formats[] = { NULL }; -static GUID const * const icns_encode_formats[] = { - &GUID_WICPixelFormat32bppBGRA, - NULL -}; - static struct regsvr_encoder const encoder_list[] = { { &CLSID_WICBmpEncoder, "The Wine Project", @@ -1449,16 +1517,6 @@ static struct regsvr_encoder const encoder_list[] = { ".tif;.tiff", tiff_encode_formats }, - { &CLSID_WICIcnsEncoder, - "The Wine Project", - "ICNS Encoder", - "1.0.0.0", - &GUID_VendorWine, - NULL, /* no container format guid */ - "image/icns", - ".icns", - icns_encode_formats - }, { NULL } /* list terminator */ }; @@ -1562,6 +1620,36 @@ static const struct reader_containers pngchrm_containers[] = { { NULL } /* list terminator */ }; +static const BYTE hIST[] = "hIST"; + +static const struct metadata_pattern pnghist_metadata_pattern[] = { + { 4, 4, hIST, mask_all, 4 }, + { 0 } +}; + +static const struct reader_containers pnghist_containers[] = { + { + &GUID_ContainerFormatPng, + pnghist_metadata_pattern + }, + { NULL } /* list terminator */ +}; + +static const BYTE tIME[] = "tIME"; + +static const struct metadata_pattern pngtime_metadata_pattern[] = { + { 4, 4, tIME, mask_all, 4 }, + { 0 } +}; + +static const struct reader_containers pngtime_containers[] = { + { + &GUID_ContainerFormatPng, + pngtime_metadata_pattern + }, + { NULL } /* list terminator */ +}; + static const struct metadata_pattern lsd_metadata_patterns[] = { { 0, 6, gif87a_magic, mask_all, 0 }, { 0, 6, gif89a_magic, mask_all, 0 }, @@ -1677,6 +1765,16 @@ static struct regsvr_metadatareader const metadatareader_list[] = { 0, 0, 0, pnggama_containers }, + { &CLSID_WICPngHistMetadataReader, + "The Wine Project", + "Chunk hIST Reader", + "1.0.0.0", + "1.0.0.0", + &GUID_VendorMicrosoft, + &GUID_MetadataFormatChunkhIST, + 0, 0, 0, + pnghist_containers + }, { &CLSID_WICPngTextMetadataReader, "The Wine Project", "Chunk tEXt Reader", @@ -1687,6 +1785,16 @@ static struct regsvr_metadatareader const metadatareader_list[] = { 0, 0, 0, pngtext_containers }, + { &CLSID_WICPngTimeMetadataReader, + "The Wine Project", + "Chunk tIME Reader", + "1.0.0.0", + "1.0.0.0", + &GUID_VendorMicrosoft, + &GUID_MetadataFormatChunktIME, + 0, 0, 0, + pngtime_containers + }, { &CLSID_WICLSDMetadataReader, "The Wine Project", "Logical Screen Descriptor Reader", @@ -1756,6 +1864,10 @@ static BYTE const channel_mask_16bit4[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, static BYTE const channel_mask_32bit[] = { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }; +static BYTE const channel_mask_96bit1[] = { 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; +static BYTE const channel_mask_96bit2[] = { 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00 }; +static BYTE const channel_mask_96bit3[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff }; + static BYTE const channel_mask_128bit1[] = { 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; static BYTE const channel_mask_128bit2[] = { 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; static BYTE const channel_mask_128bit3[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00 }; @@ -1778,6 +1890,7 @@ static BYTE const * const channel_masks_16bit[] = { channel_mask_16bit, channel_mask_16bit2, channel_mask_16bit3, channel_mask_16bit4}; static BYTE const * const channel_masks_32bit[] = { channel_mask_32bit }; +static BYTE const * const channel_masks_96bit[] = { channel_mask_96bit1, channel_mask_96bit2, channel_mask_96bit3 }; static BYTE const * const channel_masks_128bit[] = { channel_mask_128bit1, channel_mask_128bit2, channel_mask_128bit3, channel_mask_128bit4 }; static BYTE const * const channel_masks_BGRA5551[] = { channel_mask_5bit, @@ -2073,6 +2186,17 @@ static struct regsvr_pixelformat const pixelformat_list[] = { WICPixelFormatNumericRepresentationUnsignedInteger, 0 }, + { &GUID_WICPixelFormat96bppRGBFloat, + "The Wine Project", + "96bpp RGBFloat", + NULL, /* no version */ + &GUID_VendorMicrosoft, + 96, /* bitsperpixel */ + 3, /* channel count */ + channel_masks_96bit, + WICPixelFormatNumericRepresentationFloat, + 0 + }, { &GUID_WICPixelFormat128bppRGBAFloat, "The Wine Project", "128bpp RGBAFloat", @@ -2084,6 +2208,17 @@ static struct regsvr_pixelformat const pixelformat_list[] = { WICPixelFormatNumericRepresentationFloat, 1 }, + { &GUID_WICPixelFormat128bppPRGBAFloat, + "The Wine Project", + "128bpp PRGBAFloat", + NULL, /* no version */ + &GUID_VendorMicrosoft, + 128, /* bitsperpixel */ + 4, /* channel count */ + channel_masks_128bit, + WICPixelFormatNumericRepresentationFloat, + 1 + }, { NULL } /* list terminator */ }; @@ -2185,8 +2320,8 @@ static HRESULT unregister_categories(const struct regsvr_category *list) return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; } -extern HRESULT WINAPI WIC_DllRegisterServer(void) DECLSPEC_HIDDEN; -extern HRESULT WINAPI WIC_DllUnregisterServer(void) DECLSPEC_HIDDEN; +extern HRESULT WINAPI WIC_DllRegisterServer(void); +extern HRESULT WINAPI WIC_DllUnregisterServer(void); HRESULT WINAPI DllRegisterServer(void) { diff --git a/dll/win32/windowscodecs/scaler.c b/dll/win32/windowscodecs/scaler.c index d6e56d096ea4c..ab68debffa01d 100644 --- a/dll/win32/windowscodecs/scaler.c +++ b/dll/win32/windowscodecs/scaler.c @@ -17,8 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" - #include #define COBJMACROS @@ -91,7 +89,7 @@ static ULONG WINAPI BitmapScaler_AddRef(IWICBitmapScaler *iface) BitmapScaler *This = impl_from_IWICBitmapScaler(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -101,14 +99,14 @@ static ULONG WINAPI BitmapScaler_Release(IWICBitmapScaler *iface) BitmapScaler *This = impl_from_IWICBitmapScaler(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { This->lock.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&This->lock); if (This->source) IWICBitmapSource_Release(This->source); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; @@ -253,7 +251,7 @@ static HRESULT WINAPI BitmapScaler_CopyPixels(IWICBitmapScaler *iface, goto end; } - if ((cbStride * dest_rect.Height) > cbBufferSize) + if (cbStride * (dest_rect.Height - 1) + bytesperrow > cbBufferSize) { hr = E_INVALIDARG; goto end; @@ -279,13 +277,13 @@ static HRESULT WINAPI BitmapScaler_CopyPixels(IWICBitmapScaler *iface, src_bytesperrow = (src_rect.Width * This->bpp + 7)/8; buffer_size = src_bytesperrow * src_rect.Height; - src_rows = HeapAlloc(GetProcessHeap(), 0, sizeof(BYTE*) * src_rect.Height); - src_bits = HeapAlloc(GetProcessHeap(), 0, buffer_size); + src_rows = malloc(sizeof(BYTE*) * src_rect.Height); + src_bits = malloc(buffer_size); if (!src_rows || !src_bits) { - HeapFree(GetProcessHeap(), 0, src_rows); - HeapFree(GetProcessHeap(), 0, src_bits); + free(src_rows); + free(src_bits); hr = E_OUTOFMEMORY; goto end; } @@ -305,8 +303,8 @@ static HRESULT WINAPI BitmapScaler_CopyPixels(IWICBitmapScaler *iface, } } - HeapFree(GetProcessHeap(), 0, src_rows); - HeapFree(GetProcessHeap(), 0, src_bits); + free(src_rows); + free(src_bits); end: LeaveCriticalSection(&This->lock); @@ -516,7 +514,7 @@ HRESULT BitmapScaler_Create(IWICBitmapScaler **scaler) { BitmapScaler *This; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapScaler)); + This = malloc(sizeof(BitmapScaler)); if (!This) return E_OUTOFMEMORY; This->IWICBitmapScaler_iface.lpVtbl = &BitmapScaler_Vtbl; @@ -529,7 +527,11 @@ HRESULT BitmapScaler_Create(IWICBitmapScaler **scaler) This->src_height = 0; This->mode = 0; This->bpp = 0; +#ifdef __REACTOS__ InitializeCriticalSection(&This->lock); +#else + InitializeCriticalSectionEx(&This->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": BitmapScaler.lock"); *scaler = &This->IWICBitmapScaler_iface; diff --git a/dll/win32/windowscodecs/stream.c b/dll/win32/windowscodecs/stream.c index 366d11b1116ab..03b124c08c9a3 100644 --- a/dll/win32/windowscodecs/stream.c +++ b/dll/win32/windowscodecs/stream.c @@ -76,7 +76,7 @@ static ULONG WINAPI StreamOnMemory_AddRef(IStream *iface) StreamOnMemory *This = StreamOnMemory_from_IStream(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -86,12 +86,12 @@ static ULONG WINAPI StreamOnMemory_Release(IStream *iface) StreamOnMemory *This = StreamOnMemory_from_IStream(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { This->lock.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&This->lock); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; } @@ -102,7 +102,7 @@ static HRESULT WINAPI StreamOnMemory_Read(IStream *iface, StreamOnMemory *This = StreamOnMemory_from_IStream(iface); ULONG uBytesRead; - TRACE("(%p, %p, %u, %p)\n", This, pv, cb, pcbRead); + TRACE("(%p, %p, %lu, %p)\n", This, pv, cb, pcbRead); if (!pv) return E_INVALIDARG; @@ -123,7 +123,7 @@ static HRESULT WINAPI StreamOnMemory_Write(IStream *iface, StreamOnMemory *This = StreamOnMemory_from_IStream(iface); HRESULT hr; - TRACE("(%p, %p, %u, %p)\n", This, pv, cb, pcbWritten); + TRACE("(%p, %p, %lu, %p)\n", This, pv, cb, pcbWritten); if (!pv) return E_INVALIDARG; @@ -149,7 +149,7 @@ static HRESULT WINAPI StreamOnMemory_Seek(IStream *iface, LARGE_INTEGER NewPosition; HRESULT hr=S_OK; - TRACE("(%p, %s, %d, %p)\n", This, wine_dbgstr_longlong(dlibMove.QuadPart), dwOrigin, plibNewPosition); + TRACE("(%p, %s, %ld, %p)\n", This, wine_dbgstr_longlong(dlibMove.QuadPart), dwOrigin, plibNewPosition); EnterCriticalSection(&This->lock); if (dwOrigin == STREAM_SEEK_SET) NewPosition.QuadPart = dlibMove.QuadPart; @@ -189,12 +189,11 @@ static HRESULT WINAPI StreamOnMemory_CopyTo(IStream *iface, return E_NOTIMPL; } -/* Commit isn't implemented in the native windowscodecs DLL either */ static HRESULT WINAPI StreamOnMemory_Commit(IStream *iface, DWORD grfCommitFlags) { - TRACE("(%p, %#x)\n", iface, grfCommitFlags); - return E_NOTIMPL; + TRACE("(%p, %#lx)\n", iface, grfCommitFlags); + return S_OK; } /* Revert isn't implemented in the native windowscodecs DLL either */ @@ -208,7 +207,7 @@ static HRESULT WINAPI StreamOnMemory_Revert(IStream *iface) static HRESULT WINAPI StreamOnMemory_LockRegion(IStream *iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) { - TRACE("(%p, %s, %s, %d)\n", iface, wine_dbgstr_longlong(libOffset.QuadPart), + TRACE("(%p, %s, %s, %ld)\n", iface, wine_dbgstr_longlong(libOffset.QuadPart), wine_dbgstr_longlong(cb.QuadPart), dwLockType); return E_NOTIMPL; } @@ -217,7 +216,7 @@ static HRESULT WINAPI StreamOnMemory_LockRegion(IStream *iface, static HRESULT WINAPI StreamOnMemory_UnlockRegion(IStream *iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) { - TRACE("(%p, %s, %s, %d)\n", iface, wine_dbgstr_longlong(libOffset.QuadPart), + TRACE("(%p, %s, %s, %ld)\n", iface, wine_dbgstr_longlong(libOffset.QuadPart), wine_dbgstr_longlong(cb.QuadPart), dwLockType); return E_NOTIMPL; } @@ -226,7 +225,7 @@ static HRESULT WINAPI StreamOnMemory_Stat(IStream *iface, STATSTG *pstatstg, DWORD grfStatFlag) { StreamOnMemory *This = StreamOnMemory_from_IStream(iface); - TRACE("(%p, %p, %#x)\n", This, pstatstg, grfStatFlag); + TRACE("(%p, %p, %#lx)\n", This, pstatstg, grfStatFlag); if (!pstatstg) return E_INVALIDARG; @@ -311,7 +310,7 @@ static ULONG WINAPI StreamOnFileHandle_AddRef(IStream *iface) StreamOnFileHandle *This = StreamOnFileHandle_from_IStream(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -321,13 +320,13 @@ static ULONG WINAPI StreamOnFileHandle_Release(IStream *iface) StreamOnFileHandle *This = StreamOnFileHandle_from_IStream(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { IWICStream_Release(This->stream); UnmapViewOfFile(This->mem); CloseHandle(This->map); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; } @@ -336,7 +335,7 @@ static HRESULT WINAPI StreamOnFileHandle_Read(IStream *iface, void *pv, ULONG cb, ULONG *pcbRead) { StreamOnFileHandle *This = StreamOnFileHandle_from_IStream(iface); - TRACE("(%p, %p, %u, %p)\n", This, pv, cb, pcbRead); + TRACE("(%p, %p, %lu, %p)\n", This, pv, cb, pcbRead); return IWICStream_Read(This->stream, pv, cb, pcbRead); } @@ -344,7 +343,7 @@ static HRESULT WINAPI StreamOnFileHandle_Read(IStream *iface, static HRESULT WINAPI StreamOnFileHandle_Write(IStream *iface, void const *pv, ULONG cb, ULONG *pcbWritten) { - ERR("(%p, %p, %u, %p)\n", iface, pv, cb, pcbWritten); + ERR("(%p, %p, %lu, %p)\n", iface, pv, cb, pcbWritten); return HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED); } @@ -352,7 +351,7 @@ static HRESULT WINAPI StreamOnFileHandle_Seek(IStream *iface, LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition) { StreamOnFileHandle *This = StreamOnFileHandle_from_IStream(iface); - TRACE("(%p, %s, %d, %p)\n", This, wine_dbgstr_longlong(dlibMove.QuadPart), dwOrigin, plibNewPosition); + TRACE("(%p, %s, %ld, %p)\n", This, wine_dbgstr_longlong(dlibMove.QuadPart), dwOrigin, plibNewPosition); return IWICStream_Seek(This->stream, dlibMove, dwOrigin, plibNewPosition); } @@ -374,8 +373,8 @@ static HRESULT WINAPI StreamOnFileHandle_CopyTo(IStream *iface, static HRESULT WINAPI StreamOnFileHandle_Commit(IStream *iface, DWORD grfCommitFlags) { - TRACE("(%p, %#x)\n", iface, grfCommitFlags); - return E_NOTIMPL; + TRACE("(%p, %#lx)\n", iface, grfCommitFlags); + return S_OK; } static HRESULT WINAPI StreamOnFileHandle_Revert(IStream *iface) @@ -387,7 +386,7 @@ static HRESULT WINAPI StreamOnFileHandle_Revert(IStream *iface) static HRESULT WINAPI StreamOnFileHandle_LockRegion(IStream *iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) { - TRACE("(%p, %s, %s, %d)\n", iface, wine_dbgstr_longlong(libOffset.QuadPart), + TRACE("(%p, %s, %s, %ld)\n", iface, wine_dbgstr_longlong(libOffset.QuadPart), wine_dbgstr_longlong(cb.QuadPart), dwLockType); return E_NOTIMPL; } @@ -395,7 +394,7 @@ static HRESULT WINAPI StreamOnFileHandle_LockRegion(IStream *iface, static HRESULT WINAPI StreamOnFileHandle_UnlockRegion(IStream *iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) { - TRACE("(%p, %s, %s, %d)\n", iface, wine_dbgstr_longlong(libOffset.QuadPart), + TRACE("(%p, %s, %s, %ld)\n", iface, wine_dbgstr_longlong(libOffset.QuadPart), wine_dbgstr_longlong(cb.QuadPart), dwLockType); return E_NOTIMPL; } @@ -404,7 +403,7 @@ static HRESULT WINAPI StreamOnFileHandle_Stat(IStream *iface, STATSTG *pstatstg, DWORD grfStatFlag) { StreamOnFileHandle *This = StreamOnFileHandle_from_IStream(iface); - TRACE("(%p, %p, %#x)\n", This, pstatstg, grfStatFlag); + TRACE("(%p, %p, %#lx)\n", This, pstatstg, grfStatFlag); return IWICStream_Stat(This->stream, pstatstg, grfStatFlag); } @@ -486,7 +485,7 @@ static ULONG WINAPI StreamOnStreamRange_AddRef(IStream *iface) StreamOnStreamRange *This = StreamOnStreamRange_from_IStream(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -496,13 +495,13 @@ static ULONG WINAPI StreamOnStreamRange_Release(IStream *iface) StreamOnStreamRange *This = StreamOnStreamRange_from_IStream(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { This->lock.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&This->lock); IStream_Release(This->stream); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; } @@ -516,7 +515,7 @@ static HRESULT WINAPI StreamOnStreamRange_Read(IStream *iface, ULARGE_INTEGER OldPosition; LARGE_INTEGER SetPosition; - TRACE("(%p, %p, %u, %p)\n", This, pv, cb, pcbRead); + TRACE("(%p, %p, %lu, %p)\n", This, pv, cb, pcbRead); if (!pv) return E_INVALIDARG; @@ -559,7 +558,7 @@ static HRESULT WINAPI StreamOnStreamRange_Write(IStream *iface, ULARGE_INTEGER OldPosition; LARGE_INTEGER SetPosition; ULONG uBytesWritten=0; - TRACE("(%p, %p, %u, %p)\n", This, pv, cb, pcbWritten); + TRACE("(%p, %p, %lu, %p)\n", This, pv, cb, pcbWritten); if (!pv) return E_INVALIDARG; @@ -601,7 +600,7 @@ static HRESULT WINAPI StreamOnStreamRange_Seek(IStream *iface, ULARGE_INTEGER NewPosition, actual_size; HRESULT hr=S_OK; STATSTG statstg; - TRACE("(%p, %s, %d, %p)\n", This, wine_dbgstr_longlong(dlibMove.QuadPart), dwOrigin, plibNewPosition); + TRACE("(%p, %s, %ld, %p)\n", This, wine_dbgstr_longlong(dlibMove.QuadPart), dwOrigin, plibNewPosition); EnterCriticalSection(&This->lock); actual_size = This->max_size; @@ -655,8 +654,9 @@ static HRESULT WINAPI StreamOnStreamRange_CopyTo(IStream *iface, static HRESULT WINAPI StreamOnStreamRange_Commit(IStream *iface, DWORD grfCommitFlags) { - TRACE("(%p, %#x)\n", iface, grfCommitFlags); - return E_NOTIMPL; + StreamOnStreamRange *This = StreamOnStreamRange_from_IStream(iface); + TRACE("(%p, %#lx)\n", This, grfCommitFlags); + return IStream_Commit(This->stream, grfCommitFlags); } /* Revert isn't implemented in the native windowscodecs DLL either */ @@ -670,7 +670,7 @@ static HRESULT WINAPI StreamOnStreamRange_Revert(IStream *iface) static HRESULT WINAPI StreamOnStreamRange_LockRegion(IStream *iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) { - TRACE("(%p, %s, %s, %d)\n", iface, wine_dbgstr_longlong(libOffset.QuadPart), + TRACE("(%p, %s, %s, %ld)\n", iface, wine_dbgstr_longlong(libOffset.QuadPart), wine_dbgstr_longlong(cb.QuadPart), dwLockType); return E_NOTIMPL; } @@ -679,7 +679,7 @@ static HRESULT WINAPI StreamOnStreamRange_LockRegion(IStream *iface, static HRESULT WINAPI StreamOnStreamRange_UnlockRegion(IStream *iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) { - TRACE("(%p, %s, %s, %d)\n", iface, wine_dbgstr_longlong(libOffset.QuadPart), + TRACE("(%p, %s, %s, %ld)\n", iface, wine_dbgstr_longlong(libOffset.QuadPart), wine_dbgstr_longlong(cb.QuadPart), dwLockType); return E_NOTIMPL; } @@ -689,7 +689,7 @@ static HRESULT WINAPI StreamOnStreamRange_Stat(IStream *iface, { StreamOnStreamRange *This = StreamOnStreamRange_from_IStream(iface); HRESULT hr; - TRACE("(%p, %p, %#x)\n", This, pstatstg, grfStatFlag); + TRACE("(%p, %p, %#lx)\n", This, pstatstg, grfStatFlag); if (!pstatstg) return E_INVALIDARG; @@ -781,7 +781,7 @@ static ULONG WINAPI IWICStreamImpl_AddRef(IWICStream *iface) IWICStreamImpl *This = impl_from_IWICStream(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -791,11 +791,11 @@ static ULONG WINAPI IWICStreamImpl_Release(IWICStream *iface) IWICStreamImpl *This = impl_from_IWICStream(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { if (This->pStream) IStream_Release(This->pStream); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; } @@ -804,7 +804,7 @@ static HRESULT WINAPI IWICStreamImpl_Read(IWICStream *iface, void *pv, ULONG cb, ULONG *pcbRead) { IWICStreamImpl *This = impl_from_IWICStream(iface); - TRACE("(%p, %p, %u, %p)\n", This, pv, cb, pcbRead); + TRACE("(%p, %p, %lu, %p)\n", This, pv, cb, pcbRead); if (!This->pStream) return WINCODEC_ERR_NOTINITIALIZED; return IStream_Read(This->pStream, pv, cb, pcbRead); @@ -814,7 +814,7 @@ static HRESULT WINAPI IWICStreamImpl_Write(IWICStream *iface, void const *pv, ULONG cb, ULONG *pcbWritten) { IWICStreamImpl *This = impl_from_IWICStream(iface); - TRACE("(%p, %p, %u, %p)\n", This, pv, cb, pcbWritten); + TRACE("(%p, %p, %lu, %p)\n", This, pv, cb, pcbWritten); if (!This->pStream) return WINCODEC_ERR_NOTINITIALIZED; return IStream_Write(This->pStream, pv, cb, pcbWritten); @@ -824,7 +824,7 @@ static HRESULT WINAPI IWICStreamImpl_Seek(IWICStream *iface, LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition) { IWICStreamImpl *This = impl_from_IWICStream(iface); - TRACE("(%p, %s, %d, %p)\n", This, wine_dbgstr_longlong(dlibMove.QuadPart), + TRACE("(%p, %s, %ld, %p)\n", This, wine_dbgstr_longlong(dlibMove.QuadPart), dwOrigin, plibNewPosition); if (!This->pStream) return WINCODEC_ERR_NOTINITIALIZED; @@ -855,7 +855,7 @@ static HRESULT WINAPI IWICStreamImpl_Commit(IWICStream *iface, DWORD grfCommitFlags) { IWICStreamImpl *This = impl_from_IWICStream(iface); - TRACE("(%p, %#x)\n", This, grfCommitFlags); + TRACE("(%p, %#lx)\n", This, grfCommitFlags); if (!This->pStream) return WINCODEC_ERR_NOTINITIALIZED; return IStream_Commit(This->pStream, grfCommitFlags); @@ -874,7 +874,7 @@ static HRESULT WINAPI IWICStreamImpl_LockRegion(IWICStream *iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) { IWICStreamImpl *This = impl_from_IWICStream(iface); - TRACE("(%p, %s, %s, %d)\n", This, wine_dbgstr_longlong(libOffset.QuadPart), + TRACE("(%p, %s, %s, %ld)\n", This, wine_dbgstr_longlong(libOffset.QuadPart), wine_dbgstr_longlong(cb.QuadPart), dwLockType); if (!This->pStream) return WINCODEC_ERR_NOTINITIALIZED; @@ -885,7 +885,7 @@ static HRESULT WINAPI IWICStreamImpl_UnlockRegion(IWICStream *iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) { IWICStreamImpl *This = impl_from_IWICStream(iface); - TRACE("(%p, %s, %s, %d)\n", This, wine_dbgstr_longlong(libOffset.QuadPart), + TRACE("(%p, %s, %s, %ld)\n", This, wine_dbgstr_longlong(libOffset.QuadPart), wine_dbgstr_longlong(cb.QuadPart), dwLockType); if (!This->pStream) return WINCODEC_ERR_NOTINITIALIZED; @@ -896,7 +896,7 @@ static HRESULT WINAPI IWICStreamImpl_Stat(IWICStream *iface, STATSTG *pstatstg, DWORD grfStatFlag) { IWICStreamImpl *This = impl_from_IWICStream(iface); - TRACE("(%p, %p, %#x)\n", This, pstatstg, grfStatFlag); + TRACE("(%p, %p, %#lx)\n", This, pstatstg, grfStatFlag); if (!This->pStream) return WINCODEC_ERR_NOTINITIALIZED; return IStream_Stat(This->pStream, pstatstg, grfStatFlag); @@ -942,7 +942,7 @@ static HRESULT WINAPI IWICStreamImpl_InitializeFromFilename(IWICStream *iface, DWORD dwMode; IStream *stream; - TRACE("(%p, %s, %u)\n", iface, debugstr_w(wzFileName), dwDesiredAccess); + TRACE("(%p, %s, %lu)\n", iface, debugstr_w(wzFileName), dwDesiredAccess); if (This->pStream) return WINCODEC_ERR_WRONGSTATE; @@ -989,12 +989,12 @@ static HRESULT WINAPI IWICStreamImpl_InitializeFromMemory(IWICStream *iface, { IWICStreamImpl *This = impl_from_IWICStream(iface); StreamOnMemory *pObject; - TRACE("(%p, %p, %u)\n", iface, pbBuffer, cbBufferSize); + TRACE("(%p, %p, %lu)\n", iface, pbBuffer, cbBufferSize); if (!pbBuffer) return E_INVALIDARG; if (This->pStream) return WINCODEC_ERR_WRONGSTATE; - pObject = HeapAlloc(GetProcessHeap(), 0, sizeof(StreamOnMemory)); + pObject = malloc(sizeof(StreamOnMemory)); if (!pObject) return E_OUTOFMEMORY; pObject->IStream_iface.lpVtbl = &StreamOnMemory_Vtbl; @@ -1002,7 +1002,11 @@ static HRESULT WINAPI IWICStreamImpl_InitializeFromMemory(IWICStream *iface, pObject->pbMemory = pbBuffer; pObject->dwMemsize = cbBufferSize; pObject->dwCurPos = 0; +#ifdef __REACTOS__ InitializeCriticalSection(&pObject->lock); +#else + InitializeCriticalSectionEx(&pObject->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif pObject->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": StreamOnMemory.lock"); if (InterlockedCompareExchangePointer((void**)&This->pStream, pObject, NULL)) @@ -1058,7 +1062,7 @@ HRESULT stream_initialize_from_filehandle(IWICStream *iface, HANDLE file) hr = IWICStreamImpl_InitializeFromMemory(stream, mem, size.u.LowPart); if (FAILED(hr)) goto error; - pObject = HeapAlloc(GetProcessHeap(), 0, sizeof(StreamOnFileHandle)); + pObject = malloc(sizeof(StreamOnFileHandle)); if (!pObject) { hr = E_OUTOFMEMORY; @@ -1097,7 +1101,7 @@ static HRESULT WINAPI IWICStreamImpl_InitializeFromIStreamRegion(IWICStream *ifa if (!pIStream) return E_INVALIDARG; if (This->pStream) return WINCODEC_ERR_WRONGSTATE; - pObject = HeapAlloc(GetProcessHeap(), 0, sizeof(StreamOnStreamRange)); + pObject = malloc(sizeof(StreamOnStreamRange)); if (!pObject) return E_OUTOFMEMORY; pObject->IStream_iface.lpVtbl = &StreamOnStreamRange_Vtbl; @@ -1107,7 +1111,11 @@ static HRESULT WINAPI IWICStreamImpl_InitializeFromIStreamRegion(IWICStream *ifa pObject->pos.QuadPart = 0; pObject->offset = ulOffset; pObject->max_size = ulMaxSize; +#ifdef __REACTOS__ InitializeCriticalSection(&pObject->lock); +#else + InitializeCriticalSectionEx(&pObject->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif pObject->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": StreamOnStreamRange.lock"); if (InterlockedCompareExchangePointer((void**)&This->pStream, pObject, NULL)) @@ -1153,7 +1161,7 @@ HRESULT StreamImpl_Create(IWICStream **stream) if( !stream ) return E_INVALIDARG; - pObject = HeapAlloc(GetProcessHeap(), 0, sizeof(IWICStreamImpl)); + pObject = malloc(sizeof(IWICStreamImpl)); if( !pObject ) { *stream = NULL; return E_OUTOFMEMORY; diff --git a/dll/win32/windowscodecs/tgaformat.c b/dll/win32/windowscodecs/tgaformat.c index 72c9baa016837..1d2731bb3f5ab 100644 --- a/dll/win32/windowscodecs/tgaformat.c +++ b/dll/win32/windowscodecs/tgaformat.c @@ -16,9 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" -#include "wine/port.h" - #include #define COBJMACROS @@ -30,7 +27,6 @@ #include "wincodecs_private.h" #include "wine/debug.h" -#include "wine/library.h" WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); @@ -156,7 +152,7 @@ static ULONG WINAPI TgaDecoder_AddRef(IWICBitmapDecoder *iface) TgaDecoder *This = impl_from_IWICBitmapDecoder(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -166,7 +162,7 @@ static ULONG WINAPI TgaDecoder_Release(IWICBitmapDecoder *iface) TgaDecoder *This = impl_from_IWICBitmapDecoder(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { @@ -174,8 +170,8 @@ static ULONG WINAPI TgaDecoder_Release(IWICBitmapDecoder *iface) DeleteCriticalSection(&This->lock); if (This->stream) IStream_Release(This->stream); - HeapFree(GetProcessHeap(), 0, This->imagebits); - HeapFree(GetProcessHeap(), 0, This); + free(This->imagebits); + free(This); } return ref; @@ -226,7 +222,7 @@ static HRESULT WINAPI TgaDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p hr = IStream_Read(pIStream, &This->header, sizeof(tga_header), &bytesread); if (SUCCEEDED(hr) && bytesread != sizeof(tga_header)) { - TRACE("got only %u bytes\n", bytesread); + TRACE("got only %lu bytes\n", bytesread); hr = E_FAIL; } if (FAILED(hr)) goto end; @@ -298,7 +294,7 @@ static HRESULT WINAPI TgaDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p hr = IStream_Read(pIStream, &footer, sizeof(tga_footer), &bytesread); if (SUCCEEDED(hr) && bytesread != sizeof(tga_footer)) { - TRACE("got only %u footer bytes\n", bytesread); + TRACE("got only %lu footer bytes\n", bytesread); hr = E_FAIL; } @@ -330,7 +326,7 @@ static HRESULT WINAPI TgaDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p hr = IStream_Read(pIStream, &This->extension_area, sizeof(tga_extension_area), &bytesread); if (SUCCEEDED(hr) && bytesread != sizeof(tga_extension_area)) { - TRACE("got only %u extension area bytes\n", bytesread); + TRACE("got only %lu extension area bytes\n", bytesread); hr = E_FAIL; } if (SUCCEEDED(hr) && This->extension_area.size < 495) @@ -627,7 +623,7 @@ static HRESULT WINAPI TgaDecoder_Frame_CopyPalette(IWICBitmapFrameDecode *iface, return E_FAIL; } - colormap_data = HeapAlloc(GetProcessHeap(), 0, This->colormap_length); + colormap_data = malloc(This->colormap_length); if (!colormap_data) return E_OUTOFMEMORY; wcolormap_data = (WORD*)colormap_data; @@ -643,7 +639,7 @@ static HRESULT WINAPI TgaDecoder_Frame_CopyPalette(IWICBitmapFrameDecode *iface, hr = IStream_Read(This->stream, colormap_data, This->colormap_length, &bytesread); if (SUCCEEDED(hr) && bytesread != This->colormap_length) { - WARN("expected %i bytes in colormap, got %i\n", This->colormap_length, bytesread); + WARN("expected %li bytes in colormap, got %li\n", This->colormap_length, bytesread); hr = E_FAIL; } } @@ -747,7 +743,7 @@ static HRESULT WINAPI TgaDecoder_Frame_CopyPalette(IWICBitmapFrameDecode *iface, } } - HeapFree(GetProcessHeap(), 0, colormap_data); + free(colormap_data); if (SUCCEEDED(hr)) hr = IWICPalette_InitializeCustom(pIPalette, colors, 256); @@ -835,7 +831,7 @@ static HRESULT TgaDecoder_ReadImage(TgaDecoder *This) if (SUCCEEDED(hr)) { datasize = This->header.width * This->header.height * (This->header.depth / 8); - This->imagebits = HeapAlloc(GetProcessHeap(), 0, datasize); + This->imagebits = malloc(datasize); if (!This->imagebits) hr = E_OUTOFMEMORY; } @@ -874,7 +870,7 @@ static HRESULT TgaDecoder_ReadImage(TgaDecoder *This) } else { - HeapFree(GetProcessHeap(), 0, This->imagebits); + free(This->imagebits); This->imagebits = NULL; } } @@ -948,7 +944,7 @@ HRESULT TgaDecoder_CreateInstance(REFIID iid, void** ppv) *ppv = NULL; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(TgaDecoder)); + This = malloc(sizeof(TgaDecoder)); if (!This) return E_OUTOFMEMORY; This->IWICBitmapDecoder_iface.lpVtbl = &TgaDecoder_Vtbl; @@ -957,7 +953,11 @@ HRESULT TgaDecoder_CreateInstance(REFIID iid, void** ppv) This->initialized = FALSE; This->stream = NULL; This->imagebits = NULL; +#ifdef __REACTOS__ InitializeCriticalSection(&This->lock); +#else + InitializeCriticalSectionEx(&This->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": TgaDecoder.lock"); ret = IWICBitmapDecoder_QueryInterface(&This->IWICBitmapDecoder_iface, iid, ppv); diff --git a/dll/win32/windowscodecs/tiffformat.c b/dll/win32/windowscodecs/tiffformat.c deleted file mode 100644 index b3d32eec61165..0000000000000 --- a/dll/win32/windowscodecs/tiffformat.c +++ /dev/null @@ -1,2385 +0,0 @@ -/* - * Copyright 2010 Vincent Povirk for CodeWeavers - * Copyright 2016 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 "config.h" -#include "wine/port.h" - -#include -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_TIFFIO_H -#include -#endif - -#define COBJMACROS - -#include "windef.h" -#include "winbase.h" -#include "objbase.h" - -#include "wincodecs_private.h" - -#include "wine/debug.h" -#include "wine/library.h" - -WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); - -#ifdef SONAME_LIBTIFF - -/* Workaround for broken libtiff 4.x headers on some 64-bit hosts which - * define TIFF_UINT64_T/toff_t as 32-bit for 32-bit builds, while they - * are supposed to be always 64-bit. - * TIFF_UINT64_T doesn't exist in libtiff 3.x, it was introduced in 4.x. - */ -#ifdef TIFF_UINT64_T -# undef toff_t -# define toff_t UINT64 -#endif - -static CRITICAL_SECTION init_tiff_cs; -static CRITICAL_SECTION_DEBUG init_tiff_cs_debug = -{ - 0, 0, &init_tiff_cs, - { &init_tiff_cs_debug.ProcessLocksList, - &init_tiff_cs_debug.ProcessLocksList }, - 0, 0, { (DWORD_PTR)(__FILE__ ": init_tiff_cs") } -}; -static CRITICAL_SECTION init_tiff_cs = { &init_tiff_cs_debug, -1, 0, 0, 0, 0 }; - -static const WCHAR wszTiffCompressionMethod[] = {'T','i','f','f','C','o','m','p','r','e','s','s','i','o','n','M','e','t','h','o','d',0}; -static const WCHAR wszCompressionQuality[] = {'C','o','m','p','r','e','s','s','i','o','n','Q','u','a','l','i','t','y',0}; - -static void *libtiff_handle; -#define MAKE_FUNCPTR(f) static typeof(f) * p##f -MAKE_FUNCPTR(TIFFClientOpen); -MAKE_FUNCPTR(TIFFClose); -MAKE_FUNCPTR(TIFFCurrentDirOffset); -MAKE_FUNCPTR(TIFFGetField); -MAKE_FUNCPTR(TIFFIsByteSwapped); -MAKE_FUNCPTR(TIFFNumberOfDirectories); -MAKE_FUNCPTR(TIFFReadDirectory); -MAKE_FUNCPTR(TIFFReadEncodedStrip); -MAKE_FUNCPTR(TIFFReadEncodedTile); -MAKE_FUNCPTR(TIFFSetDirectory); -MAKE_FUNCPTR(TIFFSetField); -MAKE_FUNCPTR(TIFFWriteDirectory); -MAKE_FUNCPTR(TIFFWriteScanline); -#undef MAKE_FUNCPTR - -static void *load_libtiff(void) -{ - void *result; - - EnterCriticalSection(&init_tiff_cs); - - if (!libtiff_handle && - (libtiff_handle = wine_dlopen(SONAME_LIBTIFF, RTLD_NOW, NULL, 0)) != NULL) - { - void * (*pTIFFSetWarningHandler)(void *); - void * (*pTIFFSetWarningHandlerExt)(void *); - -#define LOAD_FUNCPTR(f) \ - if((p##f = wine_dlsym(libtiff_handle, #f, NULL, 0)) == NULL) { \ - ERR("failed to load symbol %s\n", #f); \ - libtiff_handle = NULL; \ - LeaveCriticalSection(&init_tiff_cs); \ - return NULL; \ - } - LOAD_FUNCPTR(TIFFClientOpen); - LOAD_FUNCPTR(TIFFClose); - LOAD_FUNCPTR(TIFFCurrentDirOffset); - LOAD_FUNCPTR(TIFFGetField); - LOAD_FUNCPTR(TIFFIsByteSwapped); - LOAD_FUNCPTR(TIFFNumberOfDirectories); - LOAD_FUNCPTR(TIFFReadDirectory); - LOAD_FUNCPTR(TIFFReadEncodedStrip); - LOAD_FUNCPTR(TIFFReadEncodedTile); - LOAD_FUNCPTR(TIFFSetDirectory); - LOAD_FUNCPTR(TIFFSetField); - LOAD_FUNCPTR(TIFFWriteDirectory); - LOAD_FUNCPTR(TIFFWriteScanline); -#undef LOAD_FUNCPTR - - if ((pTIFFSetWarningHandler = wine_dlsym(libtiff_handle, "TIFFSetWarningHandler", NULL, 0))) - pTIFFSetWarningHandler(NULL); - if ((pTIFFSetWarningHandlerExt = wine_dlsym(libtiff_handle, "TIFFSetWarningHandlerExt", NULL, 0))) - pTIFFSetWarningHandlerExt(NULL); - } - - result = libtiff_handle; - - LeaveCriticalSection(&init_tiff_cs); - return result; -} - -static tsize_t tiff_stream_read(thandle_t client_data, tdata_t data, tsize_t size) -{ - IStream *stream = (IStream*)client_data; - ULONG bytes_read; - HRESULT hr; - - hr = IStream_Read(stream, data, size, &bytes_read); - if (FAILED(hr)) bytes_read = 0; - return bytes_read; -} - -static tsize_t tiff_stream_write(thandle_t client_data, tdata_t data, tsize_t size) -{ - IStream *stream = (IStream*)client_data; - ULONG bytes_written; - HRESULT hr; - - hr = IStream_Write(stream, data, size, &bytes_written); - if (FAILED(hr)) bytes_written = 0; - return bytes_written; -} - -static toff_t tiff_stream_seek(thandle_t client_data, toff_t offset, int whence) -{ - IStream *stream = (IStream*)client_data; - LARGE_INTEGER move; - DWORD origin; - ULARGE_INTEGER new_position; - HRESULT hr; - - move.QuadPart = offset; - switch (whence) - { - case SEEK_SET: - origin = STREAM_SEEK_SET; - break; - case SEEK_CUR: - origin = STREAM_SEEK_CUR; - break; - case SEEK_END: - origin = STREAM_SEEK_END; - break; - default: - ERR("unknown whence value %i\n", whence); - return -1; - } - - hr = IStream_Seek(stream, move, origin, &new_position); - if (SUCCEEDED(hr)) return new_position.QuadPart; - else return -1; -} - -static int tiff_stream_close(thandle_t client_data) -{ - /* Caller is responsible for releasing the stream object. */ - return 0; -} - -static toff_t tiff_stream_size(thandle_t client_data) -{ - IStream *stream = (IStream*)client_data; - STATSTG statstg; - HRESULT hr; - - hr = IStream_Stat(stream, &statstg, STATFLAG_NONAME); - - if (SUCCEEDED(hr)) return statstg.cbSize.QuadPart; - else return -1; -} - -static int tiff_stream_map(thandle_t client_data, tdata_t *addr, toff_t *size) -{ - /* Cannot mmap streams */ - return 0; -} - -static void tiff_stream_unmap(thandle_t client_data, tdata_t addr, toff_t size) -{ - /* No need to ever do this, since we can't map things. */ -} - -static TIFF* tiff_open_stream(IStream *stream, const char *mode) -{ - LARGE_INTEGER zero; - - zero.QuadPart = 0; - IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL); - - return pTIFFClientOpen("", mode, stream, tiff_stream_read, - tiff_stream_write, (void *)tiff_stream_seek, tiff_stream_close, - (void *)tiff_stream_size, (void *)tiff_stream_map, (void *)tiff_stream_unmap); -} - -typedef struct { - IWICBitmapDecoder IWICBitmapDecoder_iface; - LONG ref; - IStream *stream; - CRITICAL_SECTION lock; /* Must be held when tiff is used or initialized is set */ - TIFF *tiff; - BOOL initialized; -} TiffDecoder; - -typedef struct { - const WICPixelFormatGUID *format; - int bps; - int samples; - int bpp, source_bpp; - int planar; - int indexed; - int reverse_bgr; - int invert_grayscale; - UINT width, height; - UINT tile_width, tile_height; - UINT tile_stride; - UINT tile_size; - int tiled; - UINT tiles_across; - UINT resolution_unit; - float xres, yres; -} tiff_decode_info; - -typedef struct { - IWICBitmapFrameDecode IWICBitmapFrameDecode_iface; - IWICMetadataBlockReader IWICMetadataBlockReader_iface; - LONG ref; - TiffDecoder *parent; - UINT index; - tiff_decode_info decode_info; - INT cached_tile_x, cached_tile_y; - BYTE *cached_tile; -} TiffFrameDecode; - -static const IWICBitmapFrameDecodeVtbl TiffFrameDecode_Vtbl; -static const IWICMetadataBlockReaderVtbl TiffFrameDecode_BlockVtbl; - -static inline TiffDecoder *impl_from_IWICBitmapDecoder(IWICBitmapDecoder *iface) -{ - return CONTAINING_RECORD(iface, TiffDecoder, IWICBitmapDecoder_iface); -} - -static inline TiffFrameDecode *impl_from_IWICBitmapFrameDecode(IWICBitmapFrameDecode *iface) -{ - return CONTAINING_RECORD(iface, TiffFrameDecode, IWICBitmapFrameDecode_iface); -} - -static inline TiffFrameDecode *impl_from_IWICMetadataBlockReader(IWICMetadataBlockReader *iface) -{ - return CONTAINING_RECORD(iface, TiffFrameDecode, IWICMetadataBlockReader_iface); -} - -static HRESULT tiff_get_decode_info(TIFF *tiff, tiff_decode_info *decode_info) -{ - uint16 photometric, bps, samples, planar; - uint16 extra_sample_count, extra_sample, *extra_samples; - int ret; - - decode_info->indexed = 0; - decode_info->reverse_bgr = 0; - decode_info->invert_grayscale = 0; - decode_info->tiled = 0; - decode_info->source_bpp = 0; - - ret = pTIFFGetField(tiff, TIFFTAG_PHOTOMETRIC, &photometric); - if (!ret) - { - WARN("missing PhotometricInterpretation tag\n"); - return E_FAIL; - } - - ret = pTIFFGetField(tiff, TIFFTAG_BITSPERSAMPLE, &bps); - if (!ret) bps = 1; - decode_info->bps = bps; - - ret = pTIFFGetField(tiff, TIFFTAG_SAMPLESPERPIXEL, &samples); - if (!ret) samples = 1; - decode_info->samples = samples; - - if (samples == 1) - planar = 1; - else - { - ret = pTIFFGetField(tiff, TIFFTAG_PLANARCONFIG, &planar); - if (!ret) planar = 1; - if (planar != 1) - { - FIXME("unhandled planar configuration %u\n", planar); - return E_FAIL; - } - } - decode_info->planar = planar; - - TRACE("planar %u, photometric %u, samples %u, bps %u\n", planar, photometric, samples, bps); - - switch(photometric) - { - case 0: /* WhiteIsZero */ - decode_info->invert_grayscale = 1; - /* fall through */ - case 1: /* BlackIsZero */ - if (samples == 2) - { - ret = pTIFFGetField(tiff, TIFFTAG_EXTRASAMPLES, &extra_sample_count, &extra_samples); - if (!ret) - { - extra_sample_count = 1; - extra_sample = 0; - extra_samples = &extra_sample; - } - } - else if (samples != 1) - { - FIXME("unhandled %dbpp sample count %u\n", bps, samples); - return E_FAIL; - } - - decode_info->bpp = bps * samples; - decode_info->source_bpp = decode_info->bpp; - switch (bps) - { - case 1: - if (samples != 1) - { - FIXME("unhandled 1bpp sample count %u\n", samples); - return E_FAIL; - } - decode_info->format = &GUID_WICPixelFormatBlackWhite; - break; - case 4: - if (samples != 1) - { - FIXME("unhandled 4bpp grayscale sample count %u\n", samples); - return E_FAIL; - } - decode_info->format = &GUID_WICPixelFormat4bppGray; - break; - case 8: - if (samples == 1) - decode_info->format = &GUID_WICPixelFormat8bppGray; - else - { - decode_info->bpp = 32; - - switch(extra_samples[0]) - { - case 1: /* Associated (pre-multiplied) alpha data */ - decode_info->format = &GUID_WICPixelFormat32bppPBGRA; - break; - case 0: /* Unspecified data */ - case 2: /* Unassociated alpha data */ - decode_info->format = &GUID_WICPixelFormat32bppBGRA; - break; - default: - FIXME("unhandled extra sample type %u\n", extra_samples[0]); - return E_FAIL; - } - } - break; - case 16: - if (samples != 1) - { - FIXME("unhandled 16bpp grayscale sample count %u\n", samples); - return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; - } - decode_info->format = &GUID_WICPixelFormat16bppGray; - break; - case 32: - if (samples != 1) - { - FIXME("unhandled 32bpp grayscale sample count %u\n", samples); - return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; - } - decode_info->format = &GUID_WICPixelFormat32bppGrayFloat; - break; - default: - WARN("unhandled greyscale bit count %u\n", bps); - return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; - } - break; - case 2: /* RGB */ - if (samples == 4) - { - ret = pTIFFGetField(tiff, TIFFTAG_EXTRASAMPLES, &extra_sample_count, &extra_samples); - if (!ret) - { - extra_sample_count = 1; - extra_sample = 0; - extra_samples = &extra_sample; - } - } - else if (samples != 3) - { - FIXME("unhandled RGB sample count %u\n", samples); - return E_FAIL; - } - - decode_info->bpp = max(bps, 8) * samples; - decode_info->source_bpp = bps * samples; - switch(bps) - { - case 1: - case 4: - case 8: - decode_info->reverse_bgr = 1; - if (samples == 3) - decode_info->format = &GUID_WICPixelFormat24bppBGR; - else - switch(extra_samples[0]) - { - case 1: /* Associated (pre-multiplied) alpha data */ - decode_info->format = &GUID_WICPixelFormat32bppPBGRA; - break; - case 0: /* Unspecified data */ - case 2: /* Unassociated alpha data */ - decode_info->format = &GUID_WICPixelFormat32bppBGRA; - break; - default: - FIXME("unhandled extra sample type %i\n", extra_samples[0]); - return E_FAIL; - } - break; - case 16: - if (samples == 3) - decode_info->format = &GUID_WICPixelFormat48bppRGB; - else - switch(extra_samples[0]) - { - case 1: /* Associated (pre-multiplied) alpha data */ - decode_info->format = &GUID_WICPixelFormat64bppPRGBA; - break; - case 0: /* Unspecified data */ - case 2: /* Unassociated alpha data */ - decode_info->format = &GUID_WICPixelFormat64bppRGBA; - break; - default: - FIXME("unhandled extra sample type %i\n", extra_samples[0]); - return E_FAIL; - } - break; - case 32: - if (samples != 4) - { - FIXME("unhandled 32bpp RGB sample count %u\n", samples); - return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; - } - decode_info->format = &GUID_WICPixelFormat128bppRGBAFloat; - break; - default: - WARN("unhandled RGB bit count %u\n", bps); - return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; - } - break; - case 3: /* RGB Palette */ - if (samples != 1) - { - FIXME("unhandled indexed sample count %u\n", samples); - return E_FAIL; - } - - decode_info->indexed = 1; - decode_info->bpp = bps; - switch (bps) - { - case 1: - decode_info->format = &GUID_WICPixelFormat1bppIndexed; - break; - case 2: - decode_info->format = &GUID_WICPixelFormat2bppIndexed; - break; - case 4: - decode_info->format = &GUID_WICPixelFormat4bppIndexed; - break; - case 8: - decode_info->format = &GUID_WICPixelFormat8bppIndexed; - break; - default: - FIXME("unhandled indexed bit count %u\n", bps); - return E_NOTIMPL; - } - break; - - case 5: /* Separated */ - if (samples != 4) - { - FIXME("unhandled Separated sample count %u\n", samples); - return E_FAIL; - } - - decode_info->bpp = bps * samples; - switch(bps) - { - case 8: - decode_info->format = &GUID_WICPixelFormat32bppCMYK; - break; - case 16: - decode_info->format = &GUID_WICPixelFormat64bppCMYK; - break; - - default: - WARN("unhandled Separated bit count %u\n", bps); - return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; - } - break; - - case 4: /* Transparency mask */ - case 6: /* YCbCr */ - case 8: /* CIELab */ - default: - FIXME("unhandled PhotometricInterpretation %u\n", photometric); - return E_FAIL; - } - - ret = pTIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &decode_info->width); - if (!ret) - { - WARN("missing image width\n"); - return E_FAIL; - } - - ret = pTIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &decode_info->height); - if (!ret) - { - WARN("missing image length\n"); - return E_FAIL; - } - - if ((ret = pTIFFGetField(tiff, TIFFTAG_TILEWIDTH, &decode_info->tile_width))) - { - decode_info->tiled = 1; - - ret = pTIFFGetField(tiff, TIFFTAG_TILELENGTH, &decode_info->tile_height); - if (!ret) - { - WARN("missing tile height\n"); - return E_FAIL; - } - - decode_info->tile_stride = ((decode_info->bpp * decode_info->tile_width + 7)/8); - decode_info->tile_size = decode_info->tile_height * decode_info->tile_stride; - decode_info->tiles_across = (decode_info->width + decode_info->tile_width - 1) / decode_info->tile_width; - } - else if ((ret = pTIFFGetField(tiff, TIFFTAG_ROWSPERSTRIP, &decode_info->tile_height))) - { - if (decode_info->tile_height > decode_info->height) - decode_info->tile_height = decode_info->height; - decode_info->tile_width = decode_info->width; - decode_info->tile_stride = ((decode_info->bpp * decode_info->tile_width + 7)/8); - decode_info->tile_size = decode_info->tile_height * decode_info->tile_stride; - } - else - { - /* Some broken TIFF files have a single strip and lack the RowsPerStrip tag */ - decode_info->tile_height = decode_info->height; - decode_info->tile_width = decode_info->width; - decode_info->tile_stride = ((decode_info->bpp * decode_info->tile_width + 7)/8); - decode_info->tile_size = decode_info->tile_height * decode_info->tile_stride; - } - - decode_info->resolution_unit = 0; - pTIFFGetField(tiff, TIFFTAG_RESOLUTIONUNIT, &decode_info->resolution_unit); - - ret = pTIFFGetField(tiff, TIFFTAG_XRESOLUTION, &decode_info->xres); - if (!ret) - { - WARN("missing X resolution\n"); - } - /* Emulate the behavior of current libtiff versions (libtiff commit a39f6131) - * yielding 0 instead of INFINITY for IFD_RATIONAL fields with denominator 0. */ - if (!isfinite(decode_info->xres)) - { - decode_info->xres = 0.0; - } - - ret = pTIFFGetField(tiff, TIFFTAG_YRESOLUTION, &decode_info->yres); - if (!ret) - { - WARN("missing Y resolution\n"); - } - if (!isfinite(decode_info->yres)) - { - decode_info->yres = 0.0; - } - - return S_OK; -} - -static HRESULT WINAPI TiffDecoder_QueryInterface(IWICBitmapDecoder *iface, REFIID iid, - void **ppv) -{ - TiffDecoder *This = impl_from_IWICBitmapDecoder(iface); - TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); - - if (!ppv) return E_INVALIDARG; - - if (IsEqualIID(&IID_IUnknown, iid) || - IsEqualIID(&IID_IWICBitmapDecoder, iid)) - { - *ppv = &This->IWICBitmapDecoder_iface; - } - else - { - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI TiffDecoder_AddRef(IWICBitmapDecoder *iface) -{ - TiffDecoder *This = impl_from_IWICBitmapDecoder(iface); - ULONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) refcount=%u\n", iface, ref); - - return ref; -} - -static ULONG WINAPI TiffDecoder_Release(IWICBitmapDecoder *iface) -{ - TiffDecoder *This = impl_from_IWICBitmapDecoder(iface); - ULONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p) refcount=%u\n", iface, ref); - - if (ref == 0) - { - if (This->tiff) pTIFFClose(This->tiff); - if (This->stream) IStream_Release(This->stream); - This->lock.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&This->lock); - HeapFree(GetProcessHeap(), 0, This); - } - - return ref; -} - -static HRESULT WINAPI TiffDecoder_QueryCapability(IWICBitmapDecoder *iface, IStream *stream, - DWORD *capability) -{ - HRESULT hr; - - TRACE("(%p,%p,%p)\n", iface, stream, capability); - - if (!stream || !capability) return E_INVALIDARG; - - hr = IWICBitmapDecoder_Initialize(iface, stream, WICDecodeMetadataCacheOnDemand); - if (hr != S_OK) return hr; - - *capability = WICBitmapDecoderCapabilityCanDecodeAllImages | - WICBitmapDecoderCapabilityCanDecodeSomeImages | - WICBitmapDecoderCapabilityCanEnumerateMetadata; - return S_OK; -} - -static HRESULT WINAPI TiffDecoder_Initialize(IWICBitmapDecoder *iface, IStream *pIStream, - WICDecodeOptions cacheOptions) -{ - TiffDecoder *This = impl_from_IWICBitmapDecoder(iface); - TIFF *tiff; - tiff_decode_info decode_info; - HRESULT hr=S_OK; - - TRACE("(%p,%p,%x)\n", iface, pIStream, cacheOptions); - - EnterCriticalSection(&This->lock); - - if (This->initialized) - { - hr = WINCODEC_ERR_WRONGSTATE; - goto exit; - } - - tiff = tiff_open_stream(pIStream, "r"); - if (!tiff) - { - hr = E_FAIL; - goto exit; - } - - /* make sure that TIFF format is supported */ - hr = tiff_get_decode_info(tiff, &decode_info); - if (hr != S_OK) - { - pTIFFClose(tiff); - goto exit; - } - - This->tiff = tiff; - This->stream = pIStream; - IStream_AddRef(pIStream); - This->initialized = TRUE; - -exit: - LeaveCriticalSection(&This->lock); - return hr; -} - -static HRESULT WINAPI TiffDecoder_GetContainerFormat(IWICBitmapDecoder *iface, - GUID *pguidContainerFormat) -{ - if (!pguidContainerFormat) return E_INVALIDARG; - - memcpy(pguidContainerFormat, &GUID_ContainerFormatTiff, sizeof(GUID)); - return S_OK; -} - -static HRESULT WINAPI TiffDecoder_GetDecoderInfo(IWICBitmapDecoder *iface, - IWICBitmapDecoderInfo **ppIDecoderInfo) -{ - TRACE("(%p,%p)\n", iface, ppIDecoderInfo); - - return get_decoder_info(&CLSID_WICTiffDecoder, ppIDecoderInfo); -} - -static HRESULT WINAPI TiffDecoder_CopyPalette(IWICBitmapDecoder *iface, - IWICPalette *palette) -{ - TRACE("(%p,%p)\n", iface, palette); - return WINCODEC_ERR_PALETTEUNAVAILABLE; -} - -static HRESULT WINAPI TiffDecoder_GetMetadataQueryReader(IWICBitmapDecoder *iface, - IWICMetadataQueryReader **ppIMetadataQueryReader) -{ - TRACE("(%p,%p)\n", iface, ppIMetadataQueryReader); - - if (!ppIMetadataQueryReader) return E_INVALIDARG; - - *ppIMetadataQueryReader = NULL; - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI TiffDecoder_GetPreview(IWICBitmapDecoder *iface, - IWICBitmapSource **ppIBitmapSource) -{ - TRACE("(%p,%p)\n", iface, ppIBitmapSource); - - if (!ppIBitmapSource) return E_INVALIDARG; - - *ppIBitmapSource = NULL; - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI TiffDecoder_GetColorContexts(IWICBitmapDecoder *iface, - UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount) -{ - FIXME("(%p,%u,%p,%p)\n", iface, cCount, ppIColorContexts, pcActualCount); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI TiffDecoder_GetThumbnail(IWICBitmapDecoder *iface, - IWICBitmapSource **ppIThumbnail) -{ - TRACE("(%p,%p)\n", iface, ppIThumbnail); - - if (!ppIThumbnail) return E_INVALIDARG; - - *ppIThumbnail = NULL; - return WINCODEC_ERR_CODECNOTHUMBNAIL; -} - -static HRESULT WINAPI TiffDecoder_GetFrameCount(IWICBitmapDecoder *iface, - UINT *pCount) -{ - TiffDecoder *This = impl_from_IWICBitmapDecoder(iface); - - if (!pCount) return E_INVALIDARG; - - EnterCriticalSection(&This->lock); - *pCount = This->tiff ? pTIFFNumberOfDirectories(This->tiff) : 0; - LeaveCriticalSection(&This->lock); - - TRACE("(%p) <-- %i\n", iface, *pCount); - - return S_OK; -} - -static HRESULT WINAPI TiffDecoder_GetFrame(IWICBitmapDecoder *iface, - UINT index, IWICBitmapFrameDecode **ppIBitmapFrame) -{ - TiffDecoder *This = impl_from_IWICBitmapDecoder(iface); - TiffFrameDecode *result; - int res; - tiff_decode_info decode_info; - HRESULT hr; - - TRACE("(%p,%u,%p)\n", iface, index, ppIBitmapFrame); - - if (!This->tiff) - return WINCODEC_ERR_FRAMEMISSING; - - EnterCriticalSection(&This->lock); - res = pTIFFSetDirectory(This->tiff, index); - if (!res) hr = E_INVALIDARG; - else hr = tiff_get_decode_info(This->tiff, &decode_info); - LeaveCriticalSection(&This->lock); - - if (SUCCEEDED(hr)) - { - result = HeapAlloc(GetProcessHeap(), 0, sizeof(TiffFrameDecode)); - - if (result) - { - result->IWICBitmapFrameDecode_iface.lpVtbl = &TiffFrameDecode_Vtbl; - result->IWICMetadataBlockReader_iface.lpVtbl = &TiffFrameDecode_BlockVtbl; - result->ref = 1; - result->parent = This; - IWICBitmapDecoder_AddRef(iface); - result->index = index; - result->decode_info = decode_info; - result->cached_tile_x = -1; - result->cached_tile = HeapAlloc(GetProcessHeap(), 0, decode_info.tile_size); - - if (result->cached_tile) - *ppIBitmapFrame = &result->IWICBitmapFrameDecode_iface; - else - { - hr = E_OUTOFMEMORY; - IWICBitmapFrameDecode_Release(&result->IWICBitmapFrameDecode_iface); - } - } - else hr = E_OUTOFMEMORY; - } - - if (FAILED(hr)) *ppIBitmapFrame = NULL; - - return hr; -} - -static const IWICBitmapDecoderVtbl TiffDecoder_Vtbl = { - TiffDecoder_QueryInterface, - TiffDecoder_AddRef, - TiffDecoder_Release, - TiffDecoder_QueryCapability, - TiffDecoder_Initialize, - TiffDecoder_GetContainerFormat, - TiffDecoder_GetDecoderInfo, - TiffDecoder_CopyPalette, - TiffDecoder_GetMetadataQueryReader, - TiffDecoder_GetPreview, - TiffDecoder_GetColorContexts, - TiffDecoder_GetThumbnail, - TiffDecoder_GetFrameCount, - TiffDecoder_GetFrame -}; - -static HRESULT WINAPI TiffFrameDecode_QueryInterface(IWICBitmapFrameDecode *iface, REFIID iid, - void **ppv) -{ - TiffFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); - TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); - - if (!ppv) return E_INVALIDARG; - - if (IsEqualIID(&IID_IUnknown, iid) || - IsEqualIID(&IID_IWICBitmapSource, iid) || - IsEqualIID(&IID_IWICBitmapFrameDecode, iid)) - { - *ppv = &This->IWICBitmapFrameDecode_iface; - } - else if (IsEqualIID(&IID_IWICMetadataBlockReader, iid)) - { - *ppv = &This->IWICMetadataBlockReader_iface; - } - else - { - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI TiffFrameDecode_AddRef(IWICBitmapFrameDecode *iface) -{ - TiffFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); - ULONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) refcount=%u\n", iface, ref); - - return ref; -} - -static ULONG WINAPI TiffFrameDecode_Release(IWICBitmapFrameDecode *iface) -{ - TiffFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); - ULONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p) refcount=%u\n", iface, ref); - - if (ref == 0) - { - IWICBitmapDecoder_Release(&This->parent->IWICBitmapDecoder_iface); - HeapFree(GetProcessHeap(), 0, This->cached_tile); - HeapFree(GetProcessHeap(), 0, This); - } - - return ref; -} - -static HRESULT WINAPI TiffFrameDecode_GetSize(IWICBitmapFrameDecode *iface, - UINT *puiWidth, UINT *puiHeight) -{ - TiffFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); - - *puiWidth = This->decode_info.width; - *puiHeight = This->decode_info.height; - - TRACE("(%p) <-- %ux%u\n", iface, *puiWidth, *puiHeight); - - return S_OK; -} - -static HRESULT WINAPI TiffFrameDecode_GetPixelFormat(IWICBitmapFrameDecode *iface, - WICPixelFormatGUID *pPixelFormat) -{ - TiffFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); - - memcpy(pPixelFormat, This->decode_info.format, sizeof(GUID)); - - TRACE("(%p) <-- %s\n", This, debugstr_guid(This->decode_info.format)); - - return S_OK; -} - -static HRESULT WINAPI TiffFrameDecode_GetResolution(IWICBitmapFrameDecode *iface, - double *pDpiX, double *pDpiY) -{ - TiffFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); - - if (This->decode_info.xres == 0 || This->decode_info.yres == 0) - { - *pDpiX = *pDpiY = 96.0; - } - else - { - switch (This->decode_info.resolution_unit) - { - default: - FIXME("unknown resolution unit %i\n", This->decode_info.resolution_unit); - /* fall through */ - case 0: /* Not set */ - case 1: /* Relative measurements */ - case 2: /* Inch */ - *pDpiX = This->decode_info.xres; - *pDpiY = This->decode_info.yres; - break; - case 3: /* Centimeter */ - *pDpiX = This->decode_info.xres * 2.54; - *pDpiY = This->decode_info.yres * 2.54; - break; - } - } - - TRACE("(%p) <-- %f,%f unit=%i\n", iface, *pDpiX, *pDpiY, This->decode_info.resolution_unit); - - return S_OK; -} - -static HRESULT WINAPI TiffFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface, - IWICPalette *pIPalette) -{ - TiffFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); - uint16 *red, *green, *blue; - WICColor colors[256]; - int color_count, ret, i; - - TRACE("(%p,%p)\n", iface, pIPalette); - - color_count = 1<decode_info.bps; - - EnterCriticalSection(&This->parent->lock); - ret = pTIFFGetField(This->parent->tiff, TIFFTAG_COLORMAP, &red, &green, &blue); - LeaveCriticalSection(&This->parent->lock); - - if (!ret) - { - WARN("Couldn't read color map\n"); - return WINCODEC_ERR_PALETTEUNAVAILABLE; - } - - for (i=0; i>8) & 0xff); - } - - return IWICPalette_InitializeCustom(pIPalette, colors, color_count); -} - -static HRESULT TiffFrameDecode_ReadTile(TiffFrameDecode *This, UINT tile_x, UINT tile_y) -{ - tsize_t ret; - int swap_bytes; - - swap_bytes = pTIFFIsByteSwapped(This->parent->tiff); - - ret = pTIFFSetDirectory(This->parent->tiff, This->index); - if (ret == -1) - return E_FAIL; - - if (This->decode_info.tiled) - ret = pTIFFReadEncodedTile(This->parent->tiff, tile_x + tile_y * This->decode_info.tiles_across, This->cached_tile, This->decode_info.tile_size); - else - ret = pTIFFReadEncodedStrip(This->parent->tiff, tile_y, This->cached_tile, This->decode_info.tile_size); - - if (ret == -1) - return E_FAIL; - - /* 3bpp RGB */ - if (This->decode_info.source_bpp == 3 && This->decode_info.samples == 3 && This->decode_info.bpp == 24) - { - BYTE *srcdata, *src, *dst; - DWORD x, y, count, width_bytes = (This->decode_info.tile_width * 3 + 7) / 8; - - count = width_bytes * This->decode_info.tile_height; - - srcdata = HeapAlloc(GetProcessHeap(), 0, count); - if (!srcdata) return E_OUTOFMEMORY; - memcpy(srcdata, This->cached_tile, count); - - for (y = 0; y < This->decode_info.tile_height; y++) - { - src = srcdata + y * width_bytes; - dst = This->cached_tile + y * This->decode_info.tile_width * 3; - - for (x = 0; x < This->decode_info.tile_width; x += 8) - { - dst[2] = (src[0] & 0x80) ? 0xff : 0; /* R */ - dst[1] = (src[0] & 0x40) ? 0xff : 0; /* G */ - dst[0] = (src[0] & 0x20) ? 0xff : 0; /* B */ - if (x + 1 < This->decode_info.tile_width) - { - dst[5] = (src[0] & 0x10) ? 0xff : 0; /* R */ - dst[4] = (src[0] & 0x08) ? 0xff : 0; /* G */ - dst[3] = (src[0] & 0x04) ? 0xff : 0; /* B */ - } - if (x + 2 < This->decode_info.tile_width) - { - dst[8] = (src[0] & 0x02) ? 0xff : 0; /* R */ - dst[7] = (src[0] & 0x01) ? 0xff : 0; /* G */ - dst[6] = (src[1] & 0x80) ? 0xff : 0; /* B */ - } - if (x + 3 < This->decode_info.tile_width) - { - dst[11] = (src[1] & 0x40) ? 0xff : 0; /* R */ - dst[10] = (src[1] & 0x20) ? 0xff : 0; /* G */ - dst[9] = (src[1] & 0x10) ? 0xff : 0; /* B */ - } - if (x + 4 < This->decode_info.tile_width) - { - dst[14] = (src[1] & 0x08) ? 0xff : 0; /* R */ - dst[13] = (src[1] & 0x04) ? 0xff : 0; /* G */ - dst[12] = (src[1] & 0x02) ? 0xff : 0; /* B */ - } - if (x + 5 < This->decode_info.tile_width) - { - dst[17] = (src[1] & 0x01) ? 0xff : 0; /* R */ - dst[16] = (src[2] & 0x80) ? 0xff : 0; /* G */ - dst[15] = (src[2] & 0x40) ? 0xff : 0; /* B */ - } - if (x + 6 < This->decode_info.tile_width) - { - dst[20] = (src[2] & 0x20) ? 0xff : 0; /* R */ - dst[19] = (src[2] & 0x10) ? 0xff : 0; /* G */ - dst[18] = (src[2] & 0x08) ? 0xff : 0; /* B */ - } - if (x + 7 < This->decode_info.tile_width) - { - dst[23] = (src[2] & 0x04) ? 0xff : 0; /* R */ - dst[22] = (src[2] & 0x02) ? 0xff : 0; /* G */ - dst[21] = (src[2] & 0x01) ? 0xff : 0; /* B */ - } - src += 3; - dst += 24; - } - } - - HeapFree(GetProcessHeap(), 0, srcdata); - } - /* 12bpp RGB */ - else if (This->decode_info.source_bpp == 12 && This->decode_info.samples == 3 && This->decode_info.bpp == 24) - { - BYTE *srcdata, *src, *dst; - DWORD x, y, count, width_bytes = (This->decode_info.tile_width * 12 + 7) / 8; - - count = width_bytes * This->decode_info.tile_height; - - srcdata = HeapAlloc(GetProcessHeap(), 0, count); - if (!srcdata) return E_OUTOFMEMORY; - memcpy(srcdata, This->cached_tile, count); - - for (y = 0; y < This->decode_info.tile_height; y++) - { - src = srcdata + y * width_bytes; - dst = This->cached_tile + y * This->decode_info.tile_width * 3; - - for (x = 0; x < This->decode_info.tile_width; x += 2) - { - dst[0] = ((src[1] & 0xf0) >> 4) * 17; /* B */ - dst[1] = (src[0] & 0x0f) * 17; /* G */ - dst[2] = ((src[0] & 0xf0) >> 4) * 17; /* R */ - if (x + 1 < This->decode_info.tile_width) - { - dst[5] = (src[1] & 0x0f) * 17; /* B */ - dst[4] = ((src[2] & 0xf0) >> 4) * 17; /* G */ - dst[3] = (src[2] & 0x0f) * 17; /* R */ - } - src += 3; - dst += 6; - } - } - - HeapFree(GetProcessHeap(), 0, srcdata); - } - /* 4bps RGBA */ - else if (This->decode_info.source_bpp == 4 && This->decode_info.samples == 4 && This->decode_info.bpp == 32) - { - BYTE *srcdata, *src, *dst; - DWORD x, y, count, width_bytes = (This->decode_info.tile_width * 3 + 7) / 8; - - count = width_bytes * This->decode_info.tile_height; - - srcdata = HeapAlloc(GetProcessHeap(), 0, count); - if (!srcdata) return E_OUTOFMEMORY; - memcpy(srcdata, This->cached_tile, count); - - for (y = 0; y < This->decode_info.tile_height; y++) - { - src = srcdata + y * width_bytes; - dst = This->cached_tile + y * This->decode_info.tile_width * 4; - - /* 1 source byte expands to 2 BGRA samples */ - - for (x = 0; x < This->decode_info.tile_width; x += 2) - { - dst[0] = (src[0] & 0x20) ? 0xff : 0; /* B */ - dst[1] = (src[0] & 0x40) ? 0xff : 0; /* G */ - dst[2] = (src[0] & 0x80) ? 0xff : 0; /* R */ - dst[3] = (src[0] & 0x10) ? 0xff : 0; /* A */ - if (x + 1 < This->decode_info.tile_width) - { - dst[4] = (src[0] & 0x02) ? 0xff : 0; /* B */ - dst[5] = (src[0] & 0x04) ? 0xff : 0; /* G */ - dst[6] = (src[0] & 0x08) ? 0xff : 0; /* R */ - dst[7] = (src[0] & 0x01) ? 0xff : 0; /* A */ - } - src++; - dst += 8; - } - } - - HeapFree(GetProcessHeap(), 0, srcdata); - } - /* 16bpp RGBA */ - else if (This->decode_info.source_bpp == 16 && This->decode_info.samples == 4 && This->decode_info.bpp == 32) - { - BYTE *src, *dst; - DWORD count = This->decode_info.tile_width * This->decode_info.tile_height; - - src = This->cached_tile + count * 2; - dst = This->cached_tile + This->decode_info.tile_size; - - while (count--) - { - BYTE b[2]; - - src -= 2; - dst -= 4; - - b[0] = src[0]; - b[1] = src[1]; - - dst[0] = ((b[1] & 0xf0) >> 4) * 17; /* B */ - dst[1] = (b[0] & 0x0f) * 17; /* G */ - dst[2] = ((b[0] & 0xf0) >> 4) * 17; /* R */ - dst[3] = (b[1] & 0x0f) * 17; /* A */ - } - } - /* 8bpp grayscale with extra alpha */ - else if (This->decode_info.source_bpp == 16 && This->decode_info.samples == 2 && This->decode_info.bpp == 32) - { - BYTE *src; - DWORD *dst, count = This->decode_info.tile_width * This->decode_info.tile_height; - - src = This->cached_tile + This->decode_info.tile_width * This->decode_info.tile_height * 2 - 2; - dst = (DWORD *)(This->cached_tile + This->decode_info.tile_size - 4); - - while (count--) - { - *dst-- = src[0] | (src[0] << 8) | (src[0] << 16) | (src[1] << 24); - src -= 2; - } - } - - if (This->decode_info.reverse_bgr) - { - if (This->decode_info.bps == 8) - { - UINT sample_count = This->decode_info.samples; - - reverse_bgr8(sample_count, This->cached_tile, This->decode_info.tile_width, - This->decode_info.tile_height, This->decode_info.tile_width * sample_count); - } - } - - if (swap_bytes && This->decode_info.bps > 8) - { - UINT row, i, samples_per_row; - BYTE *sample, temp; - - samples_per_row = This->decode_info.tile_width * This->decode_info.samples; - - switch(This->decode_info.bps) - { - case 16: - for (row=0; rowdecode_info.tile_height; row++) - { - sample = This->cached_tile + row * This->decode_info.tile_stride; - for (i=0; idecode_info.bps); - return E_FAIL; - } - } - - if (This->decode_info.invert_grayscale) - { - BYTE *byte, *end; - - if (This->decode_info.samples != 1) - { - ERR("cannot invert grayscale image with %u samples\n", This->decode_info.samples); - return E_FAIL; - } - - end = This->cached_tile+This->decode_info.tile_size; - - for (byte = This->cached_tile; byte != end; byte++) - *byte = ~(*byte); - } - - This->cached_tile_x = tile_x; - This->cached_tile_y = tile_y; - - return S_OK; -} - -static HRESULT WINAPI TiffFrameDecode_CopyPixels(IWICBitmapFrameDecode *iface, - const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer) -{ - TiffFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); - UINT min_tile_x, max_tile_x, min_tile_y, max_tile_y; - UINT tile_x, tile_y; - WICRect rc; - HRESULT hr=S_OK; - BYTE *dst_tilepos; - UINT bytesperrow; - WICRect rect; - - TRACE("(%p,%s,%u,%u,%p)\n", iface, debug_wic_rect(prc), cbStride, cbBufferSize, pbBuffer); - - if (!prc) - { - rect.X = 0; - rect.Y = 0; - rect.Width = This->decode_info.width; - rect.Height = This->decode_info.height; - prc = ▭ - } - else - { - if (prc->X < 0 || prc->Y < 0 || prc->X+prc->Width > This->decode_info.width || - prc->Y+prc->Height > This->decode_info.height) - return E_INVALIDARG; - } - - bytesperrow = ((This->decode_info.bpp * prc->Width)+7)/8; - - if (cbStride < bytesperrow) - return E_INVALIDARG; - - if ((cbStride * (prc->Height-1)) + bytesperrow > cbBufferSize) - return E_INVALIDARG; - - min_tile_x = prc->X / This->decode_info.tile_width; - min_tile_y = prc->Y / This->decode_info.tile_height; - max_tile_x = (prc->X+prc->Width-1) / This->decode_info.tile_width; - max_tile_y = (prc->Y+prc->Height-1) / This->decode_info.tile_height; - - EnterCriticalSection(&This->parent->lock); - - for (tile_x=min_tile_x; tile_x <= max_tile_x; tile_x++) - { - for (tile_y=min_tile_y; tile_y <= max_tile_y; tile_y++) - { - if (tile_x != This->cached_tile_x || tile_y != This->cached_tile_y) - { - hr = TiffFrameDecode_ReadTile(This, tile_x, tile_y); - } - - if (SUCCEEDED(hr)) - { - if (prc->X < tile_x * This->decode_info.tile_width) - rc.X = 0; - else - rc.X = prc->X - tile_x * This->decode_info.tile_width; - - if (prc->Y < tile_y * This->decode_info.tile_height) - rc.Y = 0; - else - rc.Y = prc->Y - tile_y * This->decode_info.tile_height; - - if (prc->X+prc->Width > (tile_x+1) * This->decode_info.tile_width) - rc.Width = This->decode_info.tile_width - rc.X; - else if (prc->X < tile_x * This->decode_info.tile_width) - rc.Width = prc->Width + prc->X - tile_x * This->decode_info.tile_width; - else - rc.Width = prc->Width; - - if (prc->Y+prc->Height > (tile_y+1) * This->decode_info.tile_height) - rc.Height = This->decode_info.tile_height - rc.Y; - else if (prc->Y < tile_y * This->decode_info.tile_height) - rc.Height = prc->Height + prc->Y - tile_y * This->decode_info.tile_height; - else - rc.Height = prc->Height; - - dst_tilepos = pbBuffer + (cbStride * ((rc.Y + tile_y * This->decode_info.tile_height) - prc->Y)) + - ((This->decode_info.bpp * ((rc.X + tile_x * This->decode_info.tile_width) - prc->X) + 7) / 8); - - hr = copy_pixels(This->decode_info.bpp, This->cached_tile, - This->decode_info.tile_width, This->decode_info.tile_height, This->decode_info.tile_stride, - &rc, cbStride, cbBufferSize, dst_tilepos); - } - - if (FAILED(hr)) - { - LeaveCriticalSection(&This->parent->lock); - TRACE("<-- 0x%x\n", hr); - return hr; - } - } - } - - LeaveCriticalSection(&This->parent->lock); - - return S_OK; -} - -static HRESULT WINAPI TiffFrameDecode_GetMetadataQueryReader(IWICBitmapFrameDecode *iface, - IWICMetadataQueryReader **ppIMetadataQueryReader) -{ - TiffFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); - - TRACE("(%p,%p)\n", iface, ppIMetadataQueryReader); - - if (!ppIMetadataQueryReader) - return E_INVALIDARG; - - return MetadataQueryReader_CreateInstance(&This->IWICMetadataBlockReader_iface, NULL, ppIMetadataQueryReader); -} - -static HRESULT WINAPI TiffFrameDecode_GetColorContexts(IWICBitmapFrameDecode *iface, - UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount) -{ - TiffFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); - const BYTE *profile; - UINT len; - HRESULT hr; - - TRACE("(%p,%u,%p,%p)\n", iface, cCount, ppIColorContexts, pcActualCount); - - EnterCriticalSection(&This->parent->lock); - - if (pTIFFGetField(This->parent->tiff, TIFFTAG_ICCPROFILE, &len, &profile)) - { - if (cCount && ppIColorContexts) - { - hr = IWICColorContext_InitializeFromMemory(*ppIColorContexts, profile, len); - if (FAILED(hr)) - { - LeaveCriticalSection(&This->parent->lock); - return hr; - } - } - *pcActualCount = 1; - } - else - *pcActualCount = 0; - - LeaveCriticalSection(&This->parent->lock); - - return S_OK; -} - -static HRESULT WINAPI TiffFrameDecode_GetThumbnail(IWICBitmapFrameDecode *iface, - IWICBitmapSource **ppIThumbnail) -{ - TRACE("(%p,%p)\n", iface, ppIThumbnail); - - if (!ppIThumbnail) return E_INVALIDARG; - - *ppIThumbnail = NULL; - return WINCODEC_ERR_CODECNOTHUMBNAIL; -} - -static const IWICBitmapFrameDecodeVtbl TiffFrameDecode_Vtbl = { - TiffFrameDecode_QueryInterface, - TiffFrameDecode_AddRef, - TiffFrameDecode_Release, - TiffFrameDecode_GetSize, - TiffFrameDecode_GetPixelFormat, - TiffFrameDecode_GetResolution, - TiffFrameDecode_CopyPalette, - TiffFrameDecode_CopyPixels, - TiffFrameDecode_GetMetadataQueryReader, - TiffFrameDecode_GetColorContexts, - TiffFrameDecode_GetThumbnail -}; - -static HRESULT WINAPI TiffFrameDecode_Block_QueryInterface(IWICMetadataBlockReader *iface, - REFIID iid, void **ppv) -{ - TiffFrameDecode *This = impl_from_IWICMetadataBlockReader(iface); - return IWICBitmapFrameDecode_QueryInterface(&This->IWICBitmapFrameDecode_iface, iid, ppv); -} - -static ULONG WINAPI TiffFrameDecode_Block_AddRef(IWICMetadataBlockReader *iface) -{ - TiffFrameDecode *This = impl_from_IWICMetadataBlockReader(iface); - return IWICBitmapFrameDecode_AddRef(&This->IWICBitmapFrameDecode_iface); -} - -static ULONG WINAPI TiffFrameDecode_Block_Release(IWICMetadataBlockReader *iface) -{ - TiffFrameDecode *This = impl_from_IWICMetadataBlockReader(iface); - return IWICBitmapFrameDecode_Release(&This->IWICBitmapFrameDecode_iface); -} - -static HRESULT WINAPI TiffFrameDecode_Block_GetContainerFormat(IWICMetadataBlockReader *iface, - GUID *guid) -{ - TRACE("(%p,%p)\n", iface, guid); - - if (!guid) return E_INVALIDARG; - - *guid = GUID_ContainerFormatTiff; - return S_OK; -} - -static HRESULT WINAPI TiffFrameDecode_Block_GetCount(IWICMetadataBlockReader *iface, - UINT *count) -{ - TRACE("%p,%p\n", iface, count); - - if (!count) return E_INVALIDARG; - - *count = 1; - return S_OK; -} - -static HRESULT create_metadata_reader(TiffFrameDecode *This, IWICMetadataReader **reader) -{ - HRESULT hr; - LARGE_INTEGER dir_offset; - IWICMetadataReader *metadata_reader; - IWICPersistStream *persist; - - /* FIXME: Use IWICComponentFactory_CreateMetadataReader once it's implemented */ - - hr = IfdMetadataReader_CreateInstance(&IID_IWICMetadataReader, (void **)&metadata_reader); - if (FAILED(hr)) return hr; - - hr = IWICMetadataReader_QueryInterface(metadata_reader, &IID_IWICPersistStream, (void **)&persist); - if (FAILED(hr)) - { - IWICMetadataReader_Release(metadata_reader); - return hr; - } - - EnterCriticalSection(&This->parent->lock); - - dir_offset.QuadPart = pTIFFCurrentDirOffset(This->parent->tiff); - hr = IStream_Seek(This->parent->stream, dir_offset, STREAM_SEEK_SET, NULL); - if (SUCCEEDED(hr)) - { - BOOL byte_swapped = pTIFFIsByteSwapped(This->parent->tiff); -#ifdef WORDS_BIGENDIAN - DWORD persist_options = byte_swapped ? WICPersistOptionLittleEndian : WICPersistOptionBigEndian; -#else - DWORD persist_options = byte_swapped ? WICPersistOptionBigEndian : WICPersistOptionLittleEndian; -#endif - persist_options |= WICPersistOptionNoCacheStream; - hr = IWICPersistStream_LoadEx(persist, This->parent->stream, NULL, persist_options); - if (FAILED(hr)) - ERR("IWICPersistStream_LoadEx error %#x\n", hr); - } - - LeaveCriticalSection(&This->parent->lock); - - IWICPersistStream_Release(persist); - - if (FAILED(hr)) - { - IWICMetadataReader_Release(metadata_reader); - return hr; - } - - *reader = metadata_reader; - return S_OK; -} - -static HRESULT WINAPI TiffFrameDecode_Block_GetReaderByIndex(IWICMetadataBlockReader *iface, - UINT index, IWICMetadataReader **reader) -{ - TiffFrameDecode *This = impl_from_IWICMetadataBlockReader(iface); - - TRACE("(%p,%u,%p)\n", iface, index, reader); - - if (!reader || index != 0) return E_INVALIDARG; - - return create_metadata_reader(This, reader); -} - -static HRESULT WINAPI TiffFrameDecode_Block_GetEnumerator(IWICMetadataBlockReader *iface, - IEnumUnknown **enum_metadata) -{ - FIXME("(%p,%p): stub\n", iface, enum_metadata); - return E_NOTIMPL; -} - -static const IWICMetadataBlockReaderVtbl TiffFrameDecode_BlockVtbl = -{ - TiffFrameDecode_Block_QueryInterface, - TiffFrameDecode_Block_AddRef, - TiffFrameDecode_Block_Release, - TiffFrameDecode_Block_GetContainerFormat, - TiffFrameDecode_Block_GetCount, - TiffFrameDecode_Block_GetReaderByIndex, - TiffFrameDecode_Block_GetEnumerator -}; - -HRESULT TiffDecoder_CreateInstance(REFIID iid, void** ppv) -{ - HRESULT ret; - TiffDecoder *This; - - TRACE("(%s,%p)\n", debugstr_guid(iid), ppv); - - *ppv = NULL; - - if (!load_libtiff()) - { - ERR("Failed reading TIFF because unable to load %s\n",SONAME_LIBTIFF); - return E_FAIL; - } - - This = HeapAlloc(GetProcessHeap(), 0, sizeof(TiffDecoder)); - if (!This) return E_OUTOFMEMORY; - - This->IWICBitmapDecoder_iface.lpVtbl = &TiffDecoder_Vtbl; - This->ref = 1; - This->stream = NULL; - InitializeCriticalSection(&This->lock); - This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": TiffDecoder.lock"); - This->tiff = NULL; - This->initialized = FALSE; - - ret = IWICBitmapDecoder_QueryInterface(&This->IWICBitmapDecoder_iface, iid, ppv); - IWICBitmapDecoder_Release(&This->IWICBitmapDecoder_iface); - - return ret; -} - -struct tiff_encode_format { - const WICPixelFormatGUID *guid; - int photometric; - int bps; - int samples; - int bpp; - int extra_sample; - int extra_sample_type; - int reverse_bgr; -}; - -static const struct tiff_encode_format formats[] = { - {&GUID_WICPixelFormat24bppBGR, 2, 8, 3, 24, 0, 0, 1}, - {&GUID_WICPixelFormat24bppRGB, 2, 8, 3, 24, 0, 0, 0}, - {&GUID_WICPixelFormatBlackWhite, 1, 1, 1, 1, 0, 0, 0}, - {&GUID_WICPixelFormat4bppGray, 1, 4, 1, 4, 0, 0, 0}, - {&GUID_WICPixelFormat8bppGray, 1, 8, 1, 8, 0, 0, 0}, - {&GUID_WICPixelFormat32bppBGRA, 2, 8, 4, 32, 1, 2, 1}, - {&GUID_WICPixelFormat32bppPBGRA, 2, 8, 4, 32, 1, 1, 1}, - {&GUID_WICPixelFormat48bppRGB, 2, 16, 3, 48, 0, 0, 0}, - {&GUID_WICPixelFormat64bppRGBA, 2, 16, 4, 64, 1, 2, 0}, - {&GUID_WICPixelFormat64bppPRGBA, 2, 16, 4, 64, 1, 1, 0}, - {&GUID_WICPixelFormat1bppIndexed, 3, 1, 1, 1, 0, 0, 0}, - {&GUID_WICPixelFormat4bppIndexed, 3, 4, 1, 4, 0, 0, 0}, - {&GUID_WICPixelFormat8bppIndexed, 3, 8, 1, 8, 0, 0, 0}, - {0} -}; - -typedef struct TiffEncoder { - IWICBitmapEncoder IWICBitmapEncoder_iface; - LONG ref; - IStream *stream; - CRITICAL_SECTION lock; /* Must be held when tiff is used or fields below are set */ - TIFF *tiff; - BOOL initialized; - BOOL committed; - ULONG num_frames; - ULONG num_frames_committed; -} TiffEncoder; - -static inline TiffEncoder *impl_from_IWICBitmapEncoder(IWICBitmapEncoder *iface) -{ - return CONTAINING_RECORD(iface, TiffEncoder, IWICBitmapEncoder_iface); -} - -typedef struct TiffFrameEncode { - IWICBitmapFrameEncode IWICBitmapFrameEncode_iface; - LONG ref; - TiffEncoder *parent; - /* fields below are protected by parent->lock */ - BOOL initialized; - BOOL info_written; - BOOL committed; - const struct tiff_encode_format *format; - UINT width, height; - double xres, yres; - UINT lines_written; - WICColor palette[256]; - UINT colors; -} TiffFrameEncode; - -static inline TiffFrameEncode *impl_from_IWICBitmapFrameEncode(IWICBitmapFrameEncode *iface) -{ - return CONTAINING_RECORD(iface, TiffFrameEncode, IWICBitmapFrameEncode_iface); -} - -static HRESULT WINAPI TiffFrameEncode_QueryInterface(IWICBitmapFrameEncode *iface, REFIID iid, - void **ppv) -{ - TiffFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); - - if (!ppv) return E_INVALIDARG; - - if (IsEqualIID(&IID_IUnknown, iid) || - IsEqualIID(&IID_IWICBitmapFrameEncode, iid)) - { - *ppv = &This->IWICBitmapFrameEncode_iface; - } - else - { - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI TiffFrameEncode_AddRef(IWICBitmapFrameEncode *iface) -{ - TiffFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - ULONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) refcount=%u\n", iface, ref); - - return ref; -} - -static ULONG WINAPI TiffFrameEncode_Release(IWICBitmapFrameEncode *iface) -{ - TiffFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - ULONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p) refcount=%u\n", iface, ref); - - if (ref == 0) - { - IWICBitmapEncoder_Release(&This->parent->IWICBitmapEncoder_iface); - HeapFree(GetProcessHeap(), 0, This); - } - - return ref; -} - -static HRESULT WINAPI TiffFrameEncode_Initialize(IWICBitmapFrameEncode *iface, - IPropertyBag2 *pIEncoderOptions) -{ - TiffFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - TRACE("(%p,%p)\n", iface, pIEncoderOptions); - - EnterCriticalSection(&This->parent->lock); - - if (This->initialized) - { - LeaveCriticalSection(&This->parent->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - This->initialized = TRUE; - - LeaveCriticalSection(&This->parent->lock); - - return S_OK; -} - -static HRESULT WINAPI TiffFrameEncode_SetSize(IWICBitmapFrameEncode *iface, - UINT uiWidth, UINT uiHeight) -{ - TiffFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - TRACE("(%p,%u,%u)\n", iface, uiWidth, uiHeight); - - EnterCriticalSection(&This->parent->lock); - - if (!This->initialized || This->info_written) - { - LeaveCriticalSection(&This->parent->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - This->width = uiWidth; - This->height = uiHeight; - - LeaveCriticalSection(&This->parent->lock); - - return S_OK; -} - -static HRESULT WINAPI TiffFrameEncode_SetResolution(IWICBitmapFrameEncode *iface, - double dpiX, double dpiY) -{ - TiffFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - TRACE("(%p,%0.2f,%0.2f)\n", iface, dpiX, dpiY); - - EnterCriticalSection(&This->parent->lock); - - if (!This->initialized || This->info_written) - { - LeaveCriticalSection(&This->parent->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - This->xres = dpiX; - This->yres = dpiY; - - LeaveCriticalSection(&This->parent->lock); - - return S_OK; -} - -static HRESULT WINAPI TiffFrameEncode_SetPixelFormat(IWICBitmapFrameEncode *iface, - WICPixelFormatGUID *pPixelFormat) -{ - TiffFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - int i; - - TRACE("(%p,%s)\n", iface, debugstr_guid(pPixelFormat)); - - EnterCriticalSection(&This->parent->lock); - - if (!This->initialized || This->info_written) - { - LeaveCriticalSection(&This->parent->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - if (IsEqualGUID(pPixelFormat, &GUID_WICPixelFormat2bppIndexed)) - *pPixelFormat = GUID_WICPixelFormat4bppIndexed; - - for (i=0; formats[i].guid; i++) - { - if (IsEqualGUID(formats[i].guid, pPixelFormat)) - break; - } - - if (!formats[i].guid) i = 0; - - This->format = &formats[i]; - memcpy(pPixelFormat, This->format->guid, sizeof(GUID)); - - LeaveCriticalSection(&This->parent->lock); - - return S_OK; -} - -static HRESULT WINAPI TiffFrameEncode_SetColorContexts(IWICBitmapFrameEncode *iface, - UINT cCount, IWICColorContext **ppIColorContext) -{ - FIXME("(%p,%u,%p): stub\n", iface, cCount, ppIColorContext); - return E_NOTIMPL; -} - -static HRESULT WINAPI TiffFrameEncode_SetPalette(IWICBitmapFrameEncode *iface, - IWICPalette *palette) -{ - TiffFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - HRESULT hr; - - TRACE("(%p,%p)\n", iface, palette); - - if (!palette) return E_INVALIDARG; - - EnterCriticalSection(&This->parent->lock); - - if (This->initialized) - hr = IWICPalette_GetColors(palette, 256, This->palette, &This->colors); - else - hr = WINCODEC_ERR_NOTINITIALIZED; - - LeaveCriticalSection(&This->parent->lock); - return hr; -} - -static HRESULT WINAPI TiffFrameEncode_SetThumbnail(IWICBitmapFrameEncode *iface, - IWICBitmapSource *pIThumbnail) -{ - FIXME("(%p,%p): stub\n", iface, pIThumbnail); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI TiffFrameEncode_WritePixels(IWICBitmapFrameEncode *iface, - UINT lineCount, UINT cbStride, UINT cbBufferSize, BYTE *pbPixels) -{ - TiffFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - BYTE *row_data, *swapped_data = NULL; - UINT i, j, line_size; - - TRACE("(%p,%u,%u,%u,%p)\n", iface, lineCount, cbStride, cbBufferSize, pbPixels); - - EnterCriticalSection(&This->parent->lock); - - if (!This->initialized || !This->width || !This->height || !This->format) - { - LeaveCriticalSection(&This->parent->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - if (lineCount == 0 || lineCount + This->lines_written > This->height) - { - LeaveCriticalSection(&This->parent->lock); - return E_INVALIDARG; - } - - line_size = ((This->width * This->format->bpp)+7)/8; - - if (This->format->reverse_bgr) - { - swapped_data = HeapAlloc(GetProcessHeap(), 0, line_size); - if (!swapped_data) - { - LeaveCriticalSection(&This->parent->lock); - return E_OUTOFMEMORY; - } - } - - if (!This->info_written) - { - pTIFFSetField(This->parent->tiff, TIFFTAG_PHOTOMETRIC, (uint16)This->format->photometric); - pTIFFSetField(This->parent->tiff, TIFFTAG_PLANARCONFIG, (uint16)1); - pTIFFSetField(This->parent->tiff, TIFFTAG_BITSPERSAMPLE, (uint16)This->format->bps); - pTIFFSetField(This->parent->tiff, TIFFTAG_SAMPLESPERPIXEL, (uint16)This->format->samples); - - if (This->format->extra_sample) - { - uint16 extra_samples; - extra_samples = This->format->extra_sample_type; - - pTIFFSetField(This->parent->tiff, TIFFTAG_EXTRASAMPLES, (uint16)1, &extra_samples); - } - - pTIFFSetField(This->parent->tiff, TIFFTAG_IMAGEWIDTH, (uint32)This->width); - pTIFFSetField(This->parent->tiff, TIFFTAG_IMAGELENGTH, (uint32)This->height); - - if (This->xres != 0.0 && This->yres != 0.0) - { - pTIFFSetField(This->parent->tiff, TIFFTAG_RESOLUTIONUNIT, (uint16)2); /* Inch */ - pTIFFSetField(This->parent->tiff, TIFFTAG_XRESOLUTION, (float)This->xres); - pTIFFSetField(This->parent->tiff, TIFFTAG_YRESOLUTION, (float)This->yres); - } - - if (This->format->bpp <= 8 && This->colors && !IsEqualGUID(This->format->guid, &GUID_WICPixelFormatBlackWhite)) - { - uint16 red[256], green[256], blue[256]; - UINT i; - - for (i = 0; i < This->colors; i++) - { - red[i] = (This->palette[i] >> 8) & 0xff00; - green[i] = This->palette[i] & 0xff00; - blue[i] = (This->palette[i] << 8) & 0xff00; - } - - pTIFFSetField(This->parent->tiff, TIFFTAG_COLORMAP, red, green, blue); - } - - This->info_written = TRUE; - } - - for (i=0; iformat->reverse_bgr && This->format->bps == 8) - { - memcpy(swapped_data, row_data, line_size); - for (j=0; jformat->samples) - { - BYTE temp; - temp = swapped_data[j]; - swapped_data[j] = swapped_data[j+2]; - swapped_data[j+2] = temp; - } - row_data = swapped_data; - } - - pTIFFWriteScanline(This->parent->tiff, (tdata_t)row_data, i+This->lines_written, 0); - } - - This->lines_written += lineCount; - - LeaveCriticalSection(&This->parent->lock); - - HeapFree(GetProcessHeap(), 0, swapped_data); - - return S_OK; -} - -static HRESULT WINAPI TiffFrameEncode_WriteSource(IWICBitmapFrameEncode *iface, - IWICBitmapSource *pIBitmapSource, WICRect *prc) -{ - TiffFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - HRESULT hr; - - TRACE("(%p,%p,%s)\n", iface, pIBitmapSource, debug_wic_rect(prc)); - - if (!This->initialized) - return WINCODEC_ERR_WRONGSTATE; - - hr = configure_write_source(iface, pIBitmapSource, prc, - This->format ? This->format->guid : NULL, This->width, This->height, - This->xres, This->yres); - - if (SUCCEEDED(hr)) - { - hr = write_source(iface, pIBitmapSource, prc, - This->format->guid, This->format->bpp, This->width, This->height); - } - - return hr; -} - -static HRESULT WINAPI TiffFrameEncode_Commit(IWICBitmapFrameEncode *iface) -{ - TiffFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - - TRACE("(%p)\n", iface); - - EnterCriticalSection(&This->parent->lock); - - if (!This->info_written || This->lines_written != This->height || This->committed) - { - LeaveCriticalSection(&This->parent->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - /* libtiff will commit the data when creating a new frame or closing the file */ - - This->committed = TRUE; - This->parent->num_frames_committed++; - - LeaveCriticalSection(&This->parent->lock); - - return S_OK; -} - -static HRESULT WINAPI TiffFrameEncode_GetMetadataQueryWriter(IWICBitmapFrameEncode *iface, - IWICMetadataQueryWriter **ppIMetadataQueryWriter) -{ - FIXME("(%p, %p): stub\n", iface, ppIMetadataQueryWriter); - return E_NOTIMPL; -} - -static const IWICBitmapFrameEncodeVtbl TiffFrameEncode_Vtbl = { - TiffFrameEncode_QueryInterface, - TiffFrameEncode_AddRef, - TiffFrameEncode_Release, - TiffFrameEncode_Initialize, - TiffFrameEncode_SetSize, - TiffFrameEncode_SetResolution, - TiffFrameEncode_SetPixelFormat, - TiffFrameEncode_SetColorContexts, - TiffFrameEncode_SetPalette, - TiffFrameEncode_SetThumbnail, - TiffFrameEncode_WritePixels, - TiffFrameEncode_WriteSource, - TiffFrameEncode_Commit, - TiffFrameEncode_GetMetadataQueryWriter -}; - -static HRESULT WINAPI TiffEncoder_QueryInterface(IWICBitmapEncoder *iface, REFIID iid, - void **ppv) -{ - TiffEncoder *This = impl_from_IWICBitmapEncoder(iface); - TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); - - if (!ppv) return E_INVALIDARG; - - if (IsEqualIID(&IID_IUnknown, iid) || - IsEqualIID(&IID_IWICBitmapEncoder, iid)) - { - *ppv = &This->IWICBitmapEncoder_iface; - } - else - { - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI TiffEncoder_AddRef(IWICBitmapEncoder *iface) -{ - TiffEncoder *This = impl_from_IWICBitmapEncoder(iface); - ULONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) refcount=%u\n", iface, ref); - - return ref; -} - -static ULONG WINAPI TiffEncoder_Release(IWICBitmapEncoder *iface) -{ - TiffEncoder *This = impl_from_IWICBitmapEncoder(iface); - ULONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p) refcount=%u\n", iface, ref); - - if (ref == 0) - { - if (This->tiff) pTIFFClose(This->tiff); - if (This->stream) IStream_Release(This->stream); - This->lock.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&This->lock); - HeapFree(GetProcessHeap(), 0, This); - } - - return ref; -} - -static HRESULT WINAPI TiffEncoder_Initialize(IWICBitmapEncoder *iface, - IStream *pIStream, WICBitmapEncoderCacheOption cacheOption) -{ - TiffEncoder *This = impl_from_IWICBitmapEncoder(iface); - TIFF *tiff; - HRESULT hr=S_OK; - - TRACE("(%p,%p,%u)\n", iface, pIStream, cacheOption); - - EnterCriticalSection(&This->lock); - - if (This->initialized || This->committed) - { - hr = WINCODEC_ERR_WRONGSTATE; - goto exit; - } - - tiff = tiff_open_stream(pIStream, "w"); - - if (!tiff) - { - hr = E_FAIL; - goto exit; - } - - This->tiff = tiff; - This->stream = pIStream; - IStream_AddRef(pIStream); - This->initialized = TRUE; - -exit: - LeaveCriticalSection(&This->lock); - return hr; -} - -static HRESULT WINAPI TiffEncoder_GetContainerFormat(IWICBitmapEncoder *iface, - GUID *pguidContainerFormat) -{ - TRACE("(%p,%p)\n", iface, pguidContainerFormat); - - if (!pguidContainerFormat) - return E_INVALIDARG; - - memcpy(pguidContainerFormat, &GUID_ContainerFormatTiff, sizeof(GUID)); - return S_OK; -} - -static HRESULT WINAPI TiffEncoder_GetEncoderInfo(IWICBitmapEncoder *iface, IWICBitmapEncoderInfo **info) -{ - IWICComponentInfo *comp_info; - HRESULT hr; - - TRACE("%p,%p\n", iface, info); - - if (!info) return E_INVALIDARG; - - hr = CreateComponentInfo(&CLSID_WICTiffEncoder, &comp_info); - if (hr == S_OK) - { - hr = IWICComponentInfo_QueryInterface(comp_info, &IID_IWICBitmapEncoderInfo, (void **)info); - IWICComponentInfo_Release(comp_info); - } - return hr; -} - -static HRESULT WINAPI TiffEncoder_SetColorContexts(IWICBitmapEncoder *iface, - UINT cCount, IWICColorContext **ppIColorContext) -{ - FIXME("(%p,%u,%p): stub\n", iface, cCount, ppIColorContext); - return E_NOTIMPL; -} - -static HRESULT WINAPI TiffEncoder_SetPalette(IWICBitmapEncoder *iface, IWICPalette *palette) -{ - TiffEncoder *This = impl_from_IWICBitmapEncoder(iface); - HRESULT hr; - - TRACE("(%p,%p)\n", iface, palette); - - EnterCriticalSection(&This->lock); - - hr = This->stream ? WINCODEC_ERR_UNSUPPORTEDOPERATION : WINCODEC_ERR_NOTINITIALIZED; - - LeaveCriticalSection(&This->lock); - - return hr; -} - -static HRESULT WINAPI TiffEncoder_SetThumbnail(IWICBitmapEncoder *iface, IWICBitmapSource *pIThumbnail) -{ - TRACE("(%p,%p)\n", iface, pIThumbnail); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI TiffEncoder_SetPreview(IWICBitmapEncoder *iface, IWICBitmapSource *pIPreview) -{ - TRACE("(%p,%p)\n", iface, pIPreview); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI TiffEncoder_CreateNewFrame(IWICBitmapEncoder *iface, - IWICBitmapFrameEncode **ppIFrameEncode, IPropertyBag2 **ppIEncoderOptions) -{ - TiffEncoder *This = impl_from_IWICBitmapEncoder(iface); - TiffFrameEncode *result; - static const PROPBAG2 opts[2] = - { - { PROPBAG2_TYPE_DATA, VT_UI1, 0, 0, (LPOLESTR)wszTiffCompressionMethod }, - { PROPBAG2_TYPE_DATA, VT_R4, 0, 0, (LPOLESTR)wszCompressionQuality }, - }; - HRESULT hr=S_OK; - - TRACE("(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions); - - EnterCriticalSection(&This->lock); - - if (!This->initialized || This->committed) - { - hr = WINCODEC_ERR_WRONGSTATE; - } - else if (This->num_frames != This->num_frames_committed) - { - FIXME("New frame created before previous frame was committed\n"); - hr = E_FAIL; - } - - if (ppIEncoderOptions && SUCCEEDED(hr)) - { - hr = CreatePropertyBag2(opts, ARRAY_SIZE(opts), ppIEncoderOptions); - if (SUCCEEDED(hr)) - { - VARIANT v; - VariantInit(&v); - V_VT(&v) = VT_UI1; - V_UI1(&v) = WICTiffCompressionDontCare; - hr = IPropertyBag2_Write(*ppIEncoderOptions, 1, (PROPBAG2 *)opts, &v); - VariantClear(&v); - if (FAILED(hr)) - { - IPropertyBag2_Release(*ppIEncoderOptions); - *ppIEncoderOptions = NULL; - } - } - } - - if (SUCCEEDED(hr)) - { - result = HeapAlloc(GetProcessHeap(), 0, sizeof(*result)); - - if (result) - { - result->IWICBitmapFrameEncode_iface.lpVtbl = &TiffFrameEncode_Vtbl; - result->ref = 1; - result->parent = This; - result->initialized = FALSE; - result->info_written = FALSE; - result->committed = FALSE; - result->format = NULL; - result->width = 0; - result->height = 0; - result->xres = 0.0; - result->yres = 0.0; - result->lines_written = 0; - result->colors = 0; - - IWICBitmapEncoder_AddRef(iface); - *ppIFrameEncode = &result->IWICBitmapFrameEncode_iface; - - if (This->num_frames != 0) - pTIFFWriteDirectory(This->tiff); - - This->num_frames++; - } - else - hr = E_OUTOFMEMORY; - - if (FAILED(hr)) - { - IPropertyBag2_Release(*ppIEncoderOptions); - *ppIEncoderOptions = NULL; - } - } - - LeaveCriticalSection(&This->lock); - - return hr; -} - -static HRESULT WINAPI TiffEncoder_Commit(IWICBitmapEncoder *iface) -{ - TiffEncoder *This = impl_from_IWICBitmapEncoder(iface); - - TRACE("(%p)\n", iface); - - EnterCriticalSection(&This->lock); - - if (!This->initialized || This->committed) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - pTIFFClose(This->tiff); - IStream_Release(This->stream); - This->stream = NULL; - This->tiff = NULL; - - This->committed = TRUE; - - LeaveCriticalSection(&This->lock); - - return S_OK; -} - -static HRESULT WINAPI TiffEncoder_GetMetadataQueryWriter(IWICBitmapEncoder *iface, - IWICMetadataQueryWriter **ppIMetadataQueryWriter) -{ - FIXME("(%p,%p): stub\n", iface, ppIMetadataQueryWriter); - return E_NOTIMPL; -} - -static const IWICBitmapEncoderVtbl TiffEncoder_Vtbl = { - TiffEncoder_QueryInterface, - TiffEncoder_AddRef, - TiffEncoder_Release, - TiffEncoder_Initialize, - TiffEncoder_GetContainerFormat, - TiffEncoder_GetEncoderInfo, - TiffEncoder_SetColorContexts, - TiffEncoder_SetPalette, - TiffEncoder_SetThumbnail, - TiffEncoder_SetPreview, - TiffEncoder_CreateNewFrame, - TiffEncoder_Commit, - TiffEncoder_GetMetadataQueryWriter -}; - -HRESULT TiffEncoder_CreateInstance(REFIID iid, void** ppv) -{ - TiffEncoder *This; - HRESULT ret; - - TRACE("(%s,%p)\n", debugstr_guid(iid), ppv); - - *ppv = NULL; - - if (!load_libtiff()) - { - ERR("Failed writing TIFF because unable to load %s\n",SONAME_LIBTIFF); - return E_FAIL; - } - - This = HeapAlloc(GetProcessHeap(), 0, sizeof(TiffEncoder)); - if (!This) return E_OUTOFMEMORY; - - This->IWICBitmapEncoder_iface.lpVtbl = &TiffEncoder_Vtbl; - This->ref = 1; - This->stream = NULL; - InitializeCriticalSection(&This->lock); - This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": TiffEncoder.lock"); - This->tiff = NULL; - This->initialized = FALSE; - This->num_frames = 0; - This->num_frames_committed = 0; - This->committed = FALSE; - - ret = IWICBitmapEncoder_QueryInterface(&This->IWICBitmapEncoder_iface, iid, ppv); - IWICBitmapEncoder_Release(&This->IWICBitmapEncoder_iface); - - return ret; -} - -#else /* !SONAME_LIBTIFF */ - -HRESULT TiffDecoder_CreateInstance(REFIID iid, void** ppv) -{ - ERR("Trying to load TIFF picture, but Wine was compiled without TIFF support.\n"); - return E_FAIL; -} - -HRESULT TiffEncoder_CreateInstance(REFIID iid, void** ppv) -{ - ERR("Trying to save TIFF picture, but Wine was compiled without TIFF support.\n"); - return E_FAIL; -} - -#endif diff --git a/dll/win32/windowscodecs/ungif.c b/dll/win32/windowscodecs/ungif.c index c6711c8e24cb1..63aa02427c68a 100644 --- a/dll/win32/windowscodecs/ungif.c +++ b/dll/win32/windowscodecs/ungif.c @@ -58,26 +58,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); -static void *ungif_alloc( size_t sz ) -{ - return HeapAlloc( GetProcessHeap(), 0, sz ); -} - -static void *ungif_calloc( size_t num, size_t sz ) -{ - return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, num*sz ); -} - -static void *ungif_realloc( void *ptr, size_t sz ) -{ - return HeapReAlloc( GetProcessHeap(), 0, ptr, sz ); -} - -static void ungif_free( void *ptr ) -{ - HeapFree( GetProcessHeap(), 0, ptr ); -} - #define LZ_MAX_CODE 4095 /* Biggest code possible in 12 bits. */ #define LZ_BITS 12 @@ -154,14 +134,14 @@ MakeMapObject(int ColorCount, return NULL; } - Object = ungif_alloc(sizeof(ColorMapObject)); + Object = malloc(sizeof(ColorMapObject)); if (Object == NULL) { return NULL; } - Object->Colors = ungif_calloc(ColorCount, sizeof(GifColorType)); + Object->Colors = calloc(ColorCount, sizeof(GifColorType)); if (Object->Colors == NULL) { - ungif_free(Object); + free(Object); return NULL; } @@ -182,8 +162,8 @@ static void FreeMapObject(ColorMapObject * Object) { if (Object != NULL) { - ungif_free(Object->Colors); - ungif_free(Object); + free(Object->Colors); + free(Object); /*** FIXME: * When we are willing to break API we need to make this function * FreeMapObject(ColorMapObject **Object) @@ -200,12 +180,9 @@ AddExtensionBlock(Extensions *New, ExtensionBlock *ep; - if (New->ExtensionBlocks == NULL) - New->ExtensionBlocks = ungif_alloc(sizeof(ExtensionBlock)); - else - New->ExtensionBlocks = ungif_realloc(New->ExtensionBlocks, - sizeof(ExtensionBlock) * - (New->ExtensionBlockCount + 1)); + New->ExtensionBlocks = realloc(New->ExtensionBlocks, + sizeof(ExtensionBlock) * + (New->ExtensionBlockCount + 1)); if (New->ExtensionBlocks == NULL) return (GIF_ERROR); @@ -213,7 +190,7 @@ AddExtensionBlock(Extensions *New, ep = &New->ExtensionBlocks[New->ExtensionBlockCount++]; ep->ByteCount=Len + 3; - ep->Bytes = ungif_alloc(ep->ByteCount + 3); + ep->Bytes = malloc(ep->ByteCount + 3); if (ep->Bytes == NULL) return (GIF_ERROR); @@ -242,7 +219,7 @@ AppendExtensionBlock(Extensions *New, ep = &New->ExtensionBlocks[New->ExtensionBlockCount - 1]; - ep->Bytes = ungif_realloc(ep->Bytes, ep->ByteCount + Len + 1); + ep->Bytes = realloc(ep->Bytes, ep->ByteCount + Len + 1); if (ep->Bytes == NULL) return (GIF_ERROR); @@ -266,8 +243,8 @@ FreeExtension(Extensions *Extensions) } for (ep = Extensions->ExtensionBlocks; ep < (Extensions->ExtensionBlocks + Extensions->ExtensionBlockCount); ep++) - ungif_free(ep->Bytes); - ungif_free(Extensions->ExtensionBlocks); + free(ep->Bytes); + free(Extensions->ExtensionBlocks); Extensions->ExtensionBlocks = NULL; } @@ -290,12 +267,12 @@ FreeSavedImages(GifFileType * GifFile) { sp->ImageDesc.ColorMap = NULL; } - ungif_free(sp->RasterBits); + free(sp->RasterBits); if (sp->Extensions.ExtensionBlocks) FreeExtension(&sp->Extensions); } - ungif_free(GifFile->SavedImages); + free(GifFile->SavedImages); GifFile->SavedImages=NULL; } @@ -320,6 +297,7 @@ DGifGetScreenDesc(GifFileType * GifFile) { GifFile->SColorResolution = (((Buf[0] & 0x70) + 1) >> 4) + 1; SortFlag = (Buf[0] & 0x08) != 0; BitsPerPixel = (Buf[0] & 0x07) + 1; + GifFile->SColorTableSize = 1 << BitsPerPixel; GifFile->SBackGroundColor = Buf[1]; GifFile->SAspectRatio = Buf[2]; if (Buf[0] & 0x80) { /* Do we have global color map? */ @@ -431,16 +409,10 @@ DGifGetImageDesc(GifFileType * GifFile) { GifFile->Image.ColorMap = NULL; } - if (GifFile->SavedImages) { - if ((GifFile->SavedImages = ungif_realloc(GifFile->SavedImages, - sizeof(SavedImage) * - (GifFile->ImageCount + 1))) == NULL) { - return GIF_ERROR; - } - } else { - if ((GifFile->SavedImages = ungif_alloc(sizeof(SavedImage))) == NULL) { - return GIF_ERROR; - } + if ((GifFile->SavedImages = realloc(GifFile->SavedImages, + sizeof(SavedImage) * + (GifFile->ImageCount + 1))) == NULL) { + return GIF_ERROR; } sp = &GifFile->SavedImages[GifFile->ImageCount]; @@ -460,8 +432,7 @@ DGifGetImageDesc(GifFileType * GifFile) { GifFile->ImageCount++; - Private->PixelCount = (long)GifFile->Image.Width * - (long)GifFile->Image.Height; + Private->PixelCount = GifFile->Image.Width * GifFile->Image.Height; DGifSetupDecompress(GifFile); /* Reset decompress algorithm parameters. */ @@ -896,7 +867,7 @@ DGifSlurp(GifFileType * GifFile) { sp = &GifFile->SavedImages[GifFile->ImageCount - 1]; ImageSize = sp->ImageDesc.Width * sp->ImageDesc.Height; - sp->RasterBits = ungif_alloc(ImageSize * sizeof(GifPixelType)); + sp->RasterBits = malloc(ImageSize * sizeof(GifPixelType)); if (sp->RasterBits == NULL) { return GIF_ERROR; } @@ -997,16 +968,16 @@ DGifOpen(void *userData, GifFileType *GifFile; GifFilePrivateType *Private; - GifFile = ungif_alloc(sizeof(GifFileType)); + GifFile = malloc(sizeof(GifFileType)); if (GifFile == NULL) { return NULL; } memset(GifFile, '\0', sizeof(GifFileType)); - Private = ungif_alloc(sizeof(GifFilePrivateType)); + Private = malloc(sizeof(GifFilePrivateType)); if (!Private) { - ungif_free(GifFile); + free(GifFile); return NULL; } @@ -1017,8 +988,8 @@ DGifOpen(void *userData, /* Lets see if this is a GIF file: */ if (READ(GifFile, Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) { - ungif_free(Private); - ungif_free(GifFile); + free(Private); + free(GifFile); return NULL; } @@ -1026,14 +997,14 @@ DGifOpen(void *userData, * something more useful with it. */ Buf[GIF_STAMP_LEN] = 0; if (memcmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) { - ungif_free(Private); - ungif_free(GifFile); + free(Private); + free(GifFile); return NULL; } if (DGifGetScreenDesc(GifFile) == GIF_ERROR) { - ungif_free(Private); - ungif_free(GifFile); + free(Private); + free(GifFile); return NULL; } @@ -1063,7 +1034,7 @@ DGifCloseFile(GifFileType * GifFile) { GifFile->SColorMap = NULL; } - ungif_free(Private); + free(Private); Private = NULL; if (GifFile->SavedImages) { @@ -1073,7 +1044,7 @@ DGifCloseFile(GifFileType * GifFile) { FreeExtension(&GifFile->Extensions); - ungif_free(GifFile); + free(GifFile); return GIF_OK; } diff --git a/dll/win32/windowscodecs/ungif.h b/dll/win32/windowscodecs/ungif.h index 6caa600bbf2ef..f61a7eb1e16b1 100644 --- a/dll/win32/windowscodecs/ungif.h +++ b/dll/win32/windowscodecs/ungif.h @@ -114,6 +114,7 @@ typedef struct { typedef struct GifFileType { GifWord SWidth, SHeight, /* Screen dimensions. */ SColorResolution, /* How many colors can we generate? */ + SColorTableSize, /* Calculated color table size, even if not present */ SBackGroundColor, /* I hope you understand this one... */ SAspectRatio; /* Pixel aspect ratio, in 1/64 units, starting at 1:4. */ ColorMapObject *SColorMap; /* NULL if not exists. */ @@ -144,9 +145,9 @@ typedef int (*InputFunc) (GifFileType *, GifByteType *, int); #define APPLICATION_EXT_FUNC_CODE 0xff /* application block */ /* public interface to ungif.c */ -int DGifSlurp(GifFileType * GifFile) DECLSPEC_HIDDEN; -GifFileType *DGifOpen(void *userPtr, InputFunc readFunc) DECLSPEC_HIDDEN; -int DGifCloseFile(GifFileType * GifFile) DECLSPEC_HIDDEN; +int DGifSlurp(GifFileType * GifFile); +GifFileType *DGifOpen(void *userPtr, InputFunc readFunc); +int DGifCloseFile(GifFileType * GifFile); #define D_GIF_ERR_OPEN_FAILED 101 /* And DGif possible errors. */ #define D_GIF_ERR_READ_FAILED 102 diff --git a/dll/win32/windowscodecs/uuid.c b/dll/win32/windowscodecs/uuid.c new file mode 100644 index 0000000000000..74de280634459 --- /dev/null +++ b/dll/win32/windowscodecs/uuid.c @@ -0,0 +1,36 @@ +/* + * Copyright 2009 Vincent Povirk for CodeWeavers + * Copyright 2020 Jacek Caban 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 + */ + +#if 0 +#pragma makedep implib +#endif + +#include "windows.h" +#include "ocidl.h" +#include "propidl.h" +#include "initguid.h" +#include "wincodec.h" +#include "wincodecsdk.h" + +DEFINE_GUID(IID_IMILBitmap,0xb1784d3f,0x8115,0x4763,0x13,0xaa,0x32,0xed,0xdb,0x68,0x29,0x4a); +DEFINE_GUID(IID_IMILBitmapSource,0x7543696a,0xbc8d,0x46b0,0x5f,0x81,0x8d,0x95,0x72,0x89,0x72,0xbe); +DEFINE_GUID(IID_IMILBitmapLock,0xa67b2b53,0x8fa1,0x4155,0x8f,0x64,0x0c,0x24,0x7a,0x8f,0x84,0xcd); +DEFINE_GUID(IID_IMILBitmapScaler,0xa767b0f0,0x1c8c,0x4aef,0x56,0x8f,0xad,0xf9,0x6d,0xcf,0xd5,0xcb); +DEFINE_GUID(IID_IMILFormatConverter,0x7e2a746f,0x25c5,0x4851,0xb3,0xaf,0x44,0x3b,0x79,0x63,0x9e,0xc0); +DEFINE_GUID(IID_IMILPalette,0xca8e206f,0xf22c,0x4af7,0x6f,0xba,0x7b,0xed,0x5e,0xb1,0xc9,0x2f); diff --git a/dll/win32/windowscodecs/wincodecs_common.c b/dll/win32/windowscodecs/wincodecs_common.c new file mode 100644 index 0000000000000..8da1bfed20ccc --- /dev/null +++ b/dll/win32/windowscodecs/wincodecs_common.c @@ -0,0 +1,211 @@ +/* + * wincodecs_common.c - Functions shared with other WIC libraries. + * + * Copyright 2020 Esme Povirk + * + * 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 + */ + +#define COBJMACROS + +#include + +#include "windef.h" +#include "winbase.h" +#include "winternl.h" +#include "objbase.h" + +#include "wincodecs_private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); + +#include "wincodecs_common.h" + +HRESULT configure_write_source(IWICBitmapFrameEncode *iface, + IWICBitmapSource *source, const WICRect *prc, + const WICPixelFormatGUID *format, + INT width, INT height, double xres, double yres) +{ + UINT src_width, src_height; + HRESULT hr = S_OK; + + if (width == 0 && height == 0) + { + if (prc) + { + if (prc->Width <= 0 || prc->Height <= 0) return E_INVALIDARG; + width = prc->Width; + height = prc->Height; + } + else + { + hr = IWICBitmapSource_GetSize(source, &src_width, &src_height); + if (FAILED(hr)) return hr; + if (src_width == 0 || src_height == 0) return E_INVALIDARG; + width = src_width; + height = src_height; + } + hr = IWICBitmapFrameEncode_SetSize(iface, (UINT)width, (UINT)height); + if (FAILED(hr)) return hr; + } + if (width == 0 || height == 0) return E_INVALIDARG; + + if (!format) + { + WICPixelFormatGUID src_format; + + hr = IWICBitmapSource_GetPixelFormat(source, &src_format); + if (FAILED(hr)) return hr; + + hr = IWICBitmapFrameEncode_SetPixelFormat(iface, &src_format); + if (FAILED(hr)) return hr; + } + + if (xres == 0.0 || yres == 0.0) + { + hr = IWICBitmapSource_GetResolution(source, &xres, &yres); + if (FAILED(hr)) return hr; + hr = IWICBitmapFrameEncode_SetResolution(iface, xres, yres); + if (FAILED(hr)) return hr; + } + + return hr; +} + +HRESULT write_source(IWICBitmapFrameEncode *iface, + IWICBitmapSource *source, const WICRect *prc, + const WICPixelFormatGUID *format, UINT bpp, BOOL need_palette, + INT width, INT height) +{ + IWICBitmapSource *converted_source; + HRESULT hr=S_OK; + WICRect rc; + UINT stride; + BYTE* pixeldata; + + if (!prc) + { + UINT src_width, src_height; + hr = IWICBitmapSource_GetSize(source, &src_width, &src_height); + if (FAILED(hr)) return hr; + rc.X = 0; + rc.Y = 0; + rc.Width = src_width; + rc.Height = src_height; + prc = &rc; + } + + if (prc->Width != width || prc->Height <= 0) + return E_INVALIDARG; + + hr = WICConvertBitmapSource(format, source, &converted_source); + if (FAILED(hr)) + { + ERR("Failed to convert source, target format %s, %#lx\n", debugstr_guid(format), hr); + return E_NOTIMPL; + } + + if (need_palette) + { + IWICImagingFactory *factory; + IWICPalette *palette; + + hr = create_instance(&CLSID_WICImagingFactory, &IID_IWICImagingFactory, (void**)&factory); + + if (SUCCEEDED(hr)) + { + hr = IWICImagingFactory_CreatePalette(factory, &palette); + IWICImagingFactory_Release(factory); + } + + if (SUCCEEDED(hr)) + { + hr = IWICBitmapSource_CopyPalette(converted_source, palette); + + if (SUCCEEDED(hr)) + hr = IWICBitmapFrameEncode_SetPalette(iface, palette); + + IWICPalette_Release(palette); + } + + if (FAILED(hr)) + { + IWICBitmapSource_Release(converted_source); + return hr; + } + } + + stride = (bpp * width + 7)/8; + + pixeldata = malloc(stride * prc->Height); + if (!pixeldata) + { + IWICBitmapSource_Release(converted_source); + return E_OUTOFMEMORY; + } + + hr = IWICBitmapSource_CopyPixels(converted_source, prc, stride, + stride*prc->Height, pixeldata); + + if (SUCCEEDED(hr)) + { + hr = IWICBitmapFrameEncode_WritePixels(iface, prc->Height, stride, + stride*prc->Height, pixeldata); + } + + free(pixeldata); + IWICBitmapSource_Release(converted_source); + + return hr; +} + +HRESULT CDECL stream_getsize(IStream *stream, ULONGLONG *size) +{ + STATSTG statstg; + HRESULT hr; + + hr = IStream_Stat(stream, &statstg, STATFLAG_NONAME); + + if (SUCCEEDED(hr)) + *size = statstg.cbSize.QuadPart; + + return hr; +} + +HRESULT CDECL stream_read(IStream *stream, void *buffer, ULONG read, ULONG *bytes_read) +{ + return IStream_Read(stream, buffer, read, bytes_read); +} + +HRESULT CDECL stream_seek(IStream *stream, LONGLONG ofs, DWORD origin, ULONGLONG *new_position) +{ + HRESULT hr; + LARGE_INTEGER ofs_large; + ULARGE_INTEGER pos_large; + + ofs_large.QuadPart = ofs; + hr = IStream_Seek(stream, ofs_large, origin, &pos_large); + if (new_position) + *new_position = pos_large.QuadPart; + + return hr; +} + +HRESULT CDECL stream_write(IStream *stream, const void *buffer, ULONG write, ULONG *bytes_written) +{ + return IStream_Write(stream, buffer, write, bytes_written); +} diff --git a/dll/win32/windowscodecs/wincodecs_common.h b/dll/win32/windowscodecs/wincodecs_common.h new file mode 100644 index 0000000000000..dcccdc2e5f163 --- /dev/null +++ b/dll/win32/windowscodecs/wincodecs_common.h @@ -0,0 +1,214 @@ +/* + * Copyright 2020 Esme Povirk + * + * 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 + */ + +HRESULT CDECL decoder_initialize(struct decoder *decoder, IStream *stream, struct decoder_stat *st) +{ + return decoder->vtable->initialize(decoder, stream, st); +} + +HRESULT CDECL decoder_get_frame_info(struct decoder *decoder, UINT frame, struct decoder_frame *info) +{ + return decoder->vtable->get_frame_info(decoder, frame, info); +} + +HRESULT CDECL decoder_copy_pixels(struct decoder *decoder, UINT frame, + const WICRect *prc, UINT stride, UINT buffersize, BYTE *buffer) +{ + return decoder->vtable->copy_pixels(decoder, frame, prc, stride, buffersize, buffer); +} + +HRESULT CDECL decoder_get_metadata_blocks(struct decoder *decoder, UINT frame, UINT *count, struct decoder_block **blocks) +{ + return decoder->vtable->get_metadata_blocks(decoder, frame, count, blocks); +} + +HRESULT CDECL decoder_get_color_context(struct decoder *decoder, UINT frame, + UINT num, BYTE **data, DWORD *datasize) +{ + return decoder->vtable->get_color_context(decoder, frame, num, data, datasize); +} + +void CDECL decoder_destroy(struct decoder *decoder) +{ + decoder->vtable->destroy(decoder); +} + +HRESULT CDECL encoder_initialize(struct encoder *encoder, IStream *stream) +{ + return encoder->vtable->initialize(encoder, stream); +} + +HRESULT CDECL encoder_get_supported_format(struct encoder* encoder, GUID *pixel_format, DWORD *bpp, BOOL *indexed) +{ + return encoder->vtable->get_supported_format(encoder, pixel_format, bpp, indexed); +} + +HRESULT CDECL encoder_create_frame(struct encoder* encoder, const struct encoder_frame *frame) +{ + return encoder->vtable->create_frame(encoder, frame); +} + +HRESULT CDECL encoder_write_lines(struct encoder* encoder, BYTE *data, DWORD line_count, DWORD stride) +{ + return encoder->vtable->write_lines(encoder, data, line_count, stride); +} + +HRESULT CDECL encoder_commit_frame(struct encoder* encoder) +{ + return encoder->vtable->commit_frame(encoder); +} + +HRESULT CDECL encoder_commit_file(struct encoder* encoder) +{ + return encoder->vtable->commit_file(encoder); +} + +void CDECL encoder_destroy(struct encoder *encoder) +{ + encoder->vtable->destroy(encoder); +} + +HRESULT copy_pixels(UINT bpp, const BYTE *srcbuffer, + UINT srcwidth, UINT srcheight, INT srcstride, + const WICRect *rc, UINT dststride, UINT dstbuffersize, BYTE *dstbuffer) +{ + UINT bytesperrow; + UINT row_offset; /* number of bits into the source rows where the data starts */ + WICRect rect; + + if (!rc) + { + rect.X = 0; + rect.Y = 0; + rect.Width = srcwidth; + rect.Height = srcheight; + rc = ▭ + } + else + { + if (rc->X < 0 || rc->Y < 0 || rc->X+rc->Width > srcwidth || rc->Y+rc->Height > srcheight) + return E_INVALIDARG; + } + + bytesperrow = ((bpp * rc->Width)+7)/8; + + if (dststride < bytesperrow) + return E_INVALIDARG; + + if ((dststride * (rc->Height-1)) + bytesperrow > dstbuffersize) + return E_INVALIDARG; + + /* if the whole bitmap is copied and the buffer format matches then it's a matter of a single memcpy */ + if (rc->X == 0 && rc->Y == 0 && rc->Width == srcwidth && rc->Height == srcheight && + srcstride == dststride && srcstride == bytesperrow) + { + memcpy(dstbuffer, srcbuffer, srcstride * srcheight); + return S_OK; + } + + row_offset = rc->X * bpp; + + if (row_offset % 8 == 0) + { + /* everything lines up on a byte boundary */ + INT row; + const BYTE *src; + BYTE *dst; + + src = srcbuffer + (row_offset / 8) + srcstride * rc->Y; + dst = dstbuffer; + for (row=0; row < rc->Height; row++) + { + memcpy(dst, src, bytesperrow); + src += srcstride; + dst += dststride; + } + return S_OK; + } + else + { + /* we have to do a weird bitwise copy. eww. */ + FIXME("cannot reliably copy bitmap data if bpp < 8\n"); + return E_FAIL; + } +} + +static inline ULONG read_ulong_be(BYTE* data) +{ + return data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; +} + +HRESULT read_png_chunk(IStream *stream, BYTE *type, BYTE **data, ULONG *data_size) +{ + BYTE header[8]; + HRESULT hr; + ULONG bytesread; + + hr = stream_read(stream, header, 8, &bytesread); + if (FAILED(hr) || bytesread < 8) + { + if (SUCCEEDED(hr)) + hr = E_FAIL; + return hr; + } + + *data_size = read_ulong_be(&header[0]); + + memcpy(type, &header[4], 4); + + if (data) + { + *data = malloc(*data_size); + if (!*data) + return E_OUTOFMEMORY; + + hr = stream_read(stream, *data, *data_size, &bytesread); + + if (FAILED(hr) || bytesread < *data_size) + { + if (SUCCEEDED(hr)) + hr = E_FAIL; + free(*data); + *data = NULL; + return hr; + } + + /* Windows ignores CRC of the chunk */ + } + + return S_OK; +} + +void reverse_bgr8(UINT bytesperpixel, LPBYTE bits, UINT width, UINT height, INT stride) +{ + UINT x, y; + BYTE *pixel, temp; + + for (y=0; y +#endif -DEFINE_GUID(CLSID_WICIcnsEncoder, 0x312fb6f1,0xb767,0x409d,0x8a,0x6d,0x0f,0xc1,0x54,0xd4,0xf0,0x5c); +DEFINE_GUID(CLSID_WineTgaDecoder, 0xb11fc79a,0x67cc,0x43e6,0xa9,0xce,0xe3,0xd5,0x49,0x45,0xd3,0x04); DEFINE_GUID(GUID_WineContainerFormatTga, 0x0c44fda1,0xa5c5,0x4298,0x96,0x85,0x47,0x3f,0xc1,0x7c,0xd3,0x22); DEFINE_GUID(GUID_VendorWine, 0xddf46da1,0x7dc1,0x404e,0x98,0xf2,0xef,0xa4,0x8d,0xfc,0x95,0x0a); -DEFINE_GUID(IID_IMILBitmap,0xb1784d3f,0x8115,0x4763,0x13,0xaa,0x32,0xed,0xdb,0x68,0x29,0x4a); -DEFINE_GUID(IID_IMILBitmapSource,0x7543696a,0xbc8d,0x46b0,0x5f,0x81,0x8d,0x95,0x72,0x89,0x72,0xbe); -DEFINE_GUID(IID_IMILBitmapLock,0xa67b2b53,0x8fa1,0x4155,0x8f,0x64,0x0c,0x24,0x7a,0x8f,0x84,0xcd); -DEFINE_GUID(IID_IMILBitmapScaler,0xa767b0f0,0x1c8c,0x4aef,0x56,0x8f,0xad,0xf9,0x6d,0xcf,0xd5,0xcb); -DEFINE_GUID(IID_IMILFormatConverter,0x7e2a746f,0x25c5,0x4851,0xb3,0xaf,0x44,0x3b,0x79,0x63,0x9e,0xc0); -DEFINE_GUID(IID_IMILPalette,0xca8e206f,0xf22c,0x4af7,0x6f,0xba,0x7b,0xed,0x5e,0xb1,0xc9,0x2f); +#ifdef __REACTOS__ +extern const GUID IID_IMILBitmap; +extern const GUID IID_IMILBitmapSource; +extern const GUID IID_IMILBitmapLock; +extern const GUID IID_IMILBitmapScaler; +extern const GUID IID_IMILFormatConverter; +extern const GUID IID_IMILPalette; +#else +extern IID IID_IMILBitmap; +extern IID IID_IMILBitmapSource; +extern IID IID_IMILBitmapLock; +extern IID IID_IMILBitmapScaler; +extern IID IID_IMILFormatConverter; +extern IID IID_IMILPalette; +#endif #define INTERFACE IMILBitmapSource DECLARE_INTERFACE_(IMILBitmapSource,IUnknown) @@ -108,18 +118,27 @@ DECLARE_INTERFACE_(IMILUnknown1,IUnknown) STDMETHOD_(ULONG,AddRef)(THIS) PURE; STDMETHOD_(ULONG,Release)(THIS) PURE; /*** thiscall method ***/ + #ifdef __REACTOS__ STDMETHOD_(void,unknown1)(THIS_ void*) PURE; - /*** stdcall ***/ + #else + THISCALLMETHOD_(void,unknown1)(THIS_ void*) PURE; + #endif STDMETHOD_(HRESULT,unknown2)(THIS_ void*, void*) PURE; - /*** thiscall method ***/ + #ifdef __REACTOS__ STDMETHOD_(HRESULT,unknown3)(THIS_ void*) PURE; - /*** stdcall ***/ + #else + THISCALLMETHOD_(HRESULT,unknown3)(THIS_ void*) PURE; + #endif STDMETHOD_(HRESULT,unknown4)(THIS_ void*) PURE; STDMETHOD_(HRESULT,unknown5)(THIS_ void*) PURE; STDMETHOD_(HRESULT,unknown6)(THIS_ DWORD64) PURE; STDMETHOD_(HRESULT,unknown7)(THIS_ void*) PURE; + #ifdef __REACTOS__ /*** thiscall method ***/ STDMETHOD_(HRESULT,unknown8)(THIS) PURE; + #else + THISCALLMETHOD_(HRESULT,unknown8)(THIS) PURE; + #endif }; #undef INTERFACE @@ -137,70 +156,70 @@ DECLARE_INTERFACE_(IMILUnknown2,IUnknown) }; #undef INTERFACE -HRESULT create_instance(CLSID *clsid, const IID *iid, void **ppv) DECLSPEC_HIDDEN; +HRESULT create_instance(const CLSID *clsid, const IID *iid, void **ppv); typedef HRESULT(*class_constructor)(REFIID,void**); -extern HRESULT FormatConverter_CreateInstance(REFIID riid, void** ppv) DECLSPEC_HIDDEN; -extern HRESULT ImagingFactory_CreateInstance(REFIID riid, void** ppv) DECLSPEC_HIDDEN; -extern HRESULT BmpDecoder_CreateInstance(REFIID riid, void** ppv) DECLSPEC_HIDDEN; -extern HRESULT PngDecoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; -extern HRESULT PngEncoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; -extern HRESULT BmpEncoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; -extern HRESULT DibDecoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; -extern HRESULT GifDecoder_CreateInstance(REFIID riid, void** ppv) DECLSPEC_HIDDEN; -extern HRESULT GifEncoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; -extern HRESULT IcoDecoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; -extern HRESULT JpegDecoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; -extern HRESULT JpegEncoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; -extern HRESULT TiffDecoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; -extern HRESULT TiffEncoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; -extern HRESULT IcnsEncoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; -extern HRESULT TgaDecoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; +extern HRESULT FormatConverter_CreateInstance(REFIID riid, void** ppv); +extern HRESULT ImagingFactory_CreateInstance(REFIID riid, void** ppv); +extern HRESULT BmpDecoder_CreateInstance(REFIID riid, void** ppv); +extern HRESULT PngDecoder_CreateInstance(REFIID iid, void** ppv); +extern HRESULT PngEncoder_CreateInstance(REFIID iid, void** ppv); +extern HRESULT BmpEncoder_CreateInstance(REFIID iid, void** ppv); +extern HRESULT DibDecoder_CreateInstance(REFIID iid, void** ppv); +extern HRESULT GifDecoder_CreateInstance(REFIID riid, void** ppv); +extern HRESULT GifEncoder_CreateInstance(REFIID iid, void** ppv); +extern HRESULT IcoDecoder_CreateInstance(REFIID iid, void** ppv); +extern HRESULT JpegDecoder_CreateInstance(REFIID iid, void** ppv); +extern HRESULT JpegEncoder_CreateInstance(REFIID iid, void** ppv); +extern HRESULT TiffDecoder_CreateInstance(REFIID iid, void** ppv); +extern HRESULT TiffEncoder_CreateInstance(REFIID iid, void** ppv); +extern HRESULT TgaDecoder_CreateInstance(REFIID iid, void** ppv); +extern HRESULT DdsDecoder_CreateInstance(REFIID iid, void** ppv); +extern HRESULT DdsEncoder_CreateInstance(REFIID iid, void** ppv); extern HRESULT BitmapImpl_Create(UINT uiWidth, UINT uiHeight, UINT stride, UINT datasize, void *view, UINT offset, REFWICPixelFormatGUID pixelFormat, WICBitmapCreateCacheOption option, - IWICBitmap **ppIBitmap) DECLSPEC_HIDDEN; -extern HRESULT BitmapScaler_Create(IWICBitmapScaler **scaler) DECLSPEC_HIDDEN; -extern HRESULT FlipRotator_Create(IWICBitmapFlipRotator **fliprotator) DECLSPEC_HIDDEN; -extern HRESULT PaletteImpl_Create(IWICPalette **palette) DECLSPEC_HIDDEN; -extern HRESULT StreamImpl_Create(IWICStream **stream) DECLSPEC_HIDDEN; -extern HRESULT ColorContext_Create(IWICColorContext **context) DECLSPEC_HIDDEN; -extern HRESULT ColorTransform_Create(IWICColorTransform **transform) DECLSPEC_HIDDEN; -extern HRESULT BitmapClipper_Create(IWICBitmapClipper **clipper) DECLSPEC_HIDDEN; + IWICBitmap **ppIBitmap); +extern HRESULT BitmapScaler_Create(IWICBitmapScaler **scaler); +extern HRESULT FlipRotator_Create(IWICBitmapFlipRotator **fliprotator); +extern HRESULT PaletteImpl_Create(IWICPalette **palette); +extern HRESULT StreamImpl_Create(IWICStream **stream); +extern HRESULT ColorContext_Create(IWICColorContext **context); +extern HRESULT ColorTransform_Create(IWICColorTransform **transform); +extern HRESULT BitmapClipper_Create(IWICBitmapClipper **clipper); extern HRESULT copy_pixels(UINT bpp, const BYTE *srcbuffer, UINT srcwidth, UINT srcheight, INT srcstride, - const WICRect *rc, UINT dststride, UINT dstbuffersize, BYTE *dstbuffer) DECLSPEC_HIDDEN; + const WICRect *rc, UINT dststride, UINT dstbuffersize, BYTE *dstbuffer); extern HRESULT configure_write_source(IWICBitmapFrameEncode *iface, IWICBitmapSource *source, const WICRect *prc, const WICPixelFormatGUID *format, - INT width, INT height, double xres, double yres) DECLSPEC_HIDDEN; + INT width, INT height, double xres, double yres); extern HRESULT write_source(IWICBitmapFrameEncode *iface, IWICBitmapSource *source, const WICRect *prc, - const WICPixelFormatGUID *format, UINT bpp, - INT width, INT height) DECLSPEC_HIDDEN; + const WICPixelFormatGUID *format, UINT bpp, BOOL need_palette, + INT width, INT height); -extern void reverse_bgr8(UINT bytesperpixel, LPBYTE bits, UINT width, UINT height, INT stride) DECLSPEC_HIDDEN; -extern void convert_rgba_to_bgra(UINT bytesperpixel, LPBYTE bits, UINT width, UINT height, INT stride) DECLSPEC_HIDDEN; +extern void reverse_bgr8(UINT bytesperpixel, LPBYTE bits, UINT width, UINT height, INT stride); -extern HRESULT get_pixelformat_bpp(const GUID *pixelformat, UINT *bpp) DECLSPEC_HIDDEN; +extern HRESULT get_pixelformat_bpp(const GUID *pixelformat, UINT *bpp); extern HRESULT CreatePropertyBag2(const PROPBAG2 *options, UINT count, - IPropertyBag2 **property) DECLSPEC_HIDDEN; + IPropertyBag2 **property); -extern HRESULT CreateComponentInfo(REFCLSID clsid, IWICComponentInfo **ppIInfo) DECLSPEC_HIDDEN; -extern void ReleaseComponentInfos(void) DECLSPEC_HIDDEN; -extern HRESULT CreateComponentEnumerator(DWORD componentTypes, DWORD options, IEnumUnknown **ppIEnumUnknown) DECLSPEC_HIDDEN; -extern HRESULT get_decoder_info(REFCLSID clsid, IWICBitmapDecoderInfo **info) DECLSPEC_HIDDEN; +extern HRESULT CreateComponentInfo(REFCLSID clsid, IWICComponentInfo **ppIInfo); +extern void ReleaseComponentInfos(void); +extern HRESULT CreateComponentEnumerator(DWORD componentTypes, DWORD options, IEnumUnknown **ppIEnumUnknown); +extern HRESULT get_decoder_info(REFCLSID clsid, IWICBitmapDecoderInfo **info); typedef struct BmpDecoder BmpDecoder; -extern HRESULT IcoDibDecoder_CreateInstance(BmpDecoder **ppDecoder) DECLSPEC_HIDDEN; -extern void BmpDecoder_GetWICDecoder(BmpDecoder *This, IWICBitmapDecoder **ppDecoder) DECLSPEC_HIDDEN; -extern void BmpDecoder_FindIconMask(BmpDecoder *This, ULONG *mask_offset, int *topdown) DECLSPEC_HIDDEN; +extern HRESULT IcoDibDecoder_CreateInstance(BmpDecoder **ppDecoder); +extern void BmpDecoder_GetWICDecoder(BmpDecoder *This, IWICBitmapDecoder **ppDecoder); +extern void BmpDecoder_FindIconMask(BmpDecoder *This, ULONG *mask_offset, int *topdown); typedef struct _MetadataItem { @@ -221,30 +240,23 @@ typedef struct _MetadataHandlerVtbl ULARGE_INTEGER *size); } MetadataHandlerVtbl; -extern HRESULT MetadataReader_Create(const MetadataHandlerVtbl *vtable, REFIID iid, void** ppv) DECLSPEC_HIDDEN; - -extern HRESULT UnknownMetadataReader_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; -extern HRESULT IfdMetadataReader_CreateInstance(REFIID iid, void **ppv) DECLSPEC_HIDDEN; -extern HRESULT PngChrmReader_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; -extern HRESULT PngGamaReader_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; -extern HRESULT PngTextReader_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; -extern HRESULT LSDReader_CreateInstance(REFIID iid, void **ppv) DECLSPEC_HIDDEN; -extern HRESULT IMDReader_CreateInstance(REFIID iid, void **ppv) DECLSPEC_HIDDEN; -extern HRESULT GCEReader_CreateInstance(REFIID iid, void **ppv) DECLSPEC_HIDDEN; -extern HRESULT APEReader_CreateInstance(REFIID iid, void **ppv) DECLSPEC_HIDDEN; -extern HRESULT GifCommentReader_CreateInstance(REFIID iid, void **ppv) DECLSPEC_HIDDEN; -extern HRESULT MetadataQueryReader_CreateInstance(IWICMetadataBlockReader *, const WCHAR *, IWICMetadataQueryReader **) DECLSPEC_HIDDEN; -extern HRESULT stream_initialize_from_filehandle(IWICStream *iface, HANDLE hfile) DECLSPEC_HIDDEN; - -static inline WCHAR *heap_strdupW(const WCHAR *src) -{ - WCHAR *dst; - SIZE_T len; - if (!src) return NULL; - len = (strlenW(src) + 1) * sizeof(WCHAR); - if ((dst = HeapAlloc(GetProcessHeap(), 0, len))) memcpy(dst, src, len); - return dst; -} +extern HRESULT MetadataReader_Create(const MetadataHandlerVtbl *vtable, REFIID iid, void** ppv); + +extern HRESULT UnknownMetadataReader_CreateInstance(REFIID iid, void** ppv); +extern HRESULT IfdMetadataReader_CreateInstance(REFIID iid, void **ppv); +extern HRESULT PngChrmReader_CreateInstance(REFIID iid, void** ppv); +extern HRESULT PngGamaReader_CreateInstance(REFIID iid, void** ppv); +extern HRESULT PngHistReader_CreateInstance(REFIID iid, void** ppv); +extern HRESULT PngTextReader_CreateInstance(REFIID iid, void** ppv); +extern HRESULT PngTimeReader_CreateInstance(REFIID iid, void** ppv); +extern HRESULT LSDReader_CreateInstance(REFIID iid, void **ppv); +extern HRESULT IMDReader_CreateInstance(REFIID iid, void **ppv); +extern HRESULT GCEReader_CreateInstance(REFIID iid, void **ppv); +extern HRESULT APEReader_CreateInstance(REFIID iid, void **ppv); +extern HRESULT GifCommentReader_CreateInstance(REFIID iid, void **ppv); +extern HRESULT MetadataQueryReader_CreateInstance(IWICMetadataBlockReader *, const WCHAR *, IWICMetadataQueryReader **); +extern HRESULT MetadataQueryWriter_CreateInstance(IWICMetadataBlockWriter *, const WCHAR *, IWICMetadataQueryWriter **); +extern HRESULT stream_initialize_from_filehandle(IWICStream *iface, HANDLE hfile); static inline const char *debug_wic_rect(const WICRect *rect) { @@ -252,4 +264,165 @@ static inline const char *debug_wic_rect(const WICRect *rect) return wine_dbg_sprintf("(%u,%u)-(%u,%u)", rect->X, rect->Y, rect->Width, rect->Height); } +extern HMODULE windowscodecs_module; + +HRESULT read_png_chunk(IStream *stream, BYTE *type, BYTE **data, ULONG *data_size); + +struct decoder_funcs; + +struct decoder_info +{ + GUID container_format; + GUID block_format; + CLSID clsid; +}; + +#define DECODER_FLAGS_CAPABILITY_MASK 0x1f +#define DECODER_FLAGS_UNSUPPORTED_COLOR_CONTEXT 0x80000000 + +struct decoder_stat +{ + DWORD flags; + UINT frame_count; +}; + +struct decoder_frame +{ + CLSID pixel_format; + UINT width, height; + UINT bpp; + DOUBLE dpix, dpiy; + DWORD num_color_contexts; + DWORD num_colors; + WICColor palette[256]; +}; + +#define DECODER_BLOCK_OPTION_MASK 0x0001000F +#define DECODER_BLOCK_FULL_STREAM 0x80000000 +#define DECODER_BLOCK_READER_CLSID 0x40000000 +struct decoder_block +{ + ULONGLONG offset; + ULONGLONG length; + DWORD options; + GUID reader_clsid; +}; + +struct decoder +{ + const struct decoder_funcs *vtable; +}; + +struct decoder_funcs +{ + HRESULT (CDECL *initialize)(struct decoder* This, IStream *stream, struct decoder_stat *st); + HRESULT (CDECL *get_frame_info)(struct decoder* This, UINT frame, struct decoder_frame *info); + HRESULT (CDECL *copy_pixels)(struct decoder* This, UINT frame, const WICRect *prc, + UINT stride, UINT buffersize, BYTE *buffer); + HRESULT (CDECL *get_metadata_blocks)(struct decoder* This, UINT frame, UINT *count, + struct decoder_block **blocks); + HRESULT (CDECL *get_color_context)(struct decoder* This, UINT frame, UINT num, + BYTE **data, DWORD *datasize); + void (CDECL *destroy)(struct decoder* This); +}; + +HRESULT CDECL stream_getsize(IStream *stream, ULONGLONG *size); +HRESULT CDECL stream_read(IStream *stream, void *buffer, ULONG read, ULONG *bytes_read); +HRESULT CDECL stream_seek(IStream *stream, LONGLONG ofs, DWORD origin, ULONGLONG *new_position); +HRESULT CDECL stream_write(IStream *stream, const void *buffer, ULONG write, ULONG *bytes_written); + +HRESULT CDECL decoder_create(const CLSID *decoder_clsid, struct decoder_info *info, struct decoder **result); +HRESULT CDECL decoder_initialize(struct decoder *This, IStream *stream, struct decoder_stat *st); +HRESULT CDECL decoder_get_frame_info(struct decoder* This, UINT frame, struct decoder_frame *info); +HRESULT CDECL decoder_copy_pixels(struct decoder* This, UINT frame, const WICRect *prc, + UINT stride, UINT buffersize, BYTE *buffer); +HRESULT CDECL decoder_get_metadata_blocks(struct decoder* This, UINT frame, UINT *count, + struct decoder_block **blocks); +HRESULT CDECL decoder_get_color_context(struct decoder* This, UINT frame, UINT num, + BYTE **data, DWORD *datasize); +void CDECL decoder_destroy(struct decoder *This); + +struct encoder_funcs; + +/* sync with encoder_option_properties */ +enum encoder_option +{ + ENCODER_OPTION_INTERLACE, + ENCODER_OPTION_FILTER, + ENCODER_OPTION_COMPRESSION_METHOD, + ENCODER_OPTION_COMPRESSION_QUALITY, + ENCODER_OPTION_IMAGE_QUALITY, + ENCODER_OPTION_BITMAP_TRANSFORM, + ENCODER_OPTION_LUMINANCE, + ENCODER_OPTION_CHROMINANCE, + ENCODER_OPTION_YCRCB_SUBSAMPLING, + ENCODER_OPTION_SUPPRESS_APP0, + ENCODER_OPTION_END +}; + +#define ENCODER_FLAGS_MULTI_FRAME 0x1 +#define ENCODER_FLAGS_ICNS_SIZE 0x2 +#define ENCODER_FLAGS_SUPPORTS_METADATA 0x4 + +struct encoder_info +{ + DWORD flags; + GUID container_format; + CLSID clsid; + DWORD encoder_options[7]; +}; + +struct encoder_frame +{ + GUID pixel_format; + UINT width, height; + UINT bpp; + BOOL indexed; + DOUBLE dpix, dpiy; + UINT num_colors; + WICColor palette[256]; + /* encoder options */ + BOOL interlace; + DWORD filter; +}; + +struct encoder +{ + const struct encoder_funcs *vtable; +}; + +struct encoder_funcs +{ + HRESULT (CDECL *initialize)(struct encoder* This, IStream *stream); + HRESULT (CDECL *get_supported_format)(struct encoder* This, GUID *pixel_format, DWORD *bpp, BOOL *indexed); + HRESULT (CDECL *create_frame)(struct encoder* This, const struct encoder_frame *frame); + HRESULT (CDECL *write_lines)(struct encoder* This, BYTE *data, DWORD line_count, DWORD stride); + HRESULT (CDECL *commit_frame)(struct encoder* This); + HRESULT (CDECL *commit_file)(struct encoder* This); + void (CDECL *destroy)(struct encoder* This); +}; + +HRESULT CDECL encoder_initialize(struct encoder* This, IStream *stream); +HRESULT CDECL encoder_get_supported_format(struct encoder* This, GUID *pixel_format, DWORD *bpp, BOOL *indexed); +HRESULT CDECL encoder_create_frame(struct encoder* This, const struct encoder_frame *frame); +HRESULT CDECL encoder_write_lines(struct encoder* This, BYTE *data, DWORD line_count, DWORD stride); +HRESULT CDECL encoder_commit_frame(struct encoder* This); +HRESULT CDECL encoder_commit_file(struct encoder* This); +void CDECL encoder_destroy(struct encoder* This); + +HRESULT CDECL png_decoder_create(struct decoder_info *info, struct decoder **result); +HRESULT CDECL tiff_decoder_create(struct decoder_info *info, struct decoder **result); +HRESULT CDECL jpeg_decoder_create(struct decoder_info *info, struct decoder **result); + +HRESULT CDECL png_encoder_create(struct encoder_info *info, struct encoder **result); +HRESULT CDECL tiff_encoder_create(struct encoder_info *info, struct encoder **result); +HRESULT CDECL jpeg_encoder_create(struct encoder_info *info, struct encoder **result); +HRESULT CDECL icns_encoder_create(struct encoder_info *info, struct encoder **result); + +extern HRESULT CommonDecoder_CreateInstance(struct decoder *decoder, + const struct decoder_info *decoder_info, REFIID iid, void** ppv); + +extern HRESULT CommonEncoder_CreateInstance(struct encoder *encoder, + const struct encoder_info *encoder_info, REFIID iid, void** ppv); + #endif /* WINCODECS_PRIVATE_H */ diff --git a/dll/win32/windowscodecs/windowscodecs_wincodec.idl b/dll/win32/windowscodecs/windowscodecs_wincodec.idl index fec63d04e13ec..f47684890c1bc 100644 --- a/dll/win32/windowscodecs/windowscodecs_wincodec.idl +++ b/dll/win32/windowscodecs/windowscodecs_wincodec.idl @@ -25,7 +25,7 @@ threading(both), uuid(00000301-a8f2-4877-ba0a-fd2b6645fb94) /* IWICFormatConverter */ ] -coclass PSFactoryBuffer { interface IFactoryBuffer; } +coclass PSFactoryBuffer { interface IPSFactoryBuffer; } [ helpstring("WIC Imaging Factory"), @@ -119,11 +119,18 @@ coclass WICTiffDecoder { interface IWICBitmapDecoder; } coclass WICTiffEncoder { interface IWICBitmapEncoder; } [ - helpstring("WIC ICNS Encoder"), + helpstring("WIC DDS Decoder"), threading(both), - uuid(312fb6f1-b767-409d-8a6d-0fc154d4f05c) + uuid(9053699f-a341-429d-9e90-ee437cf80c73) ] -coclass WICIcnsEncoder { interface IWICBitmapEncoder; } +coclass WICDdsDecoder { interface IWICBitmapDecoder; } + +[ + helpstring("WIC DDS Encoder"), + threading(both), + uuid(a61dde94-66ce-4ac1-881b-71680588895e) +] +coclass WICDdsEncoder { interface IWICBitmapEncoder; } [ helpstring("WIC Default Format Converter"), @@ -151,7 +158,7 @@ coclass WICUnknownMetadataReader { interface IWICMetadataReader; } threading(both), uuid(8f914656-9d0a-4eb2-9019-0bf96d8a9ee6) ] -coclass WICIfdMetadataReader { interface IWICIfdMetadataReader; } +coclass WICIfdMetadataReader { interface IWICMetadataReader; } [ helpstring("WIC Png cHRM Metadata Reader"), @@ -167,13 +174,28 @@ coclass WICPngChrmMetadataReader { interface IWICMetadataReader; } ] coclass WICPngGamaMetadataReader { interface IWICMetadataReader; } +[ + helpstring("WIC Png hIST Metadata Reader"), + threading(both), + uuid(877a0bb7-a313-4491-87b5-2e6d0594f520) +] +coclass WICPngHistMetadataReader { interface IWICMetadataReader; } + [ helpstring("WIC Png tEXt Metadata Reader"), threading(both), uuid(4b59afcc-b8c3-408a-b670-89e5fab6fda7) + ] coclass WICPngTextMetadataReader { interface IWICMetadataReader; } +[ + helpstring("WIC Png tIME Metadata Reader"), + threading(both), + uuid(d94edf02-efe5-4f0d-85c8-f5a68b3000b1) +] +coclass WICPngTimeMetadataReader { interface IWICMetadataReader; } + [ helpstring("WIC LSD Metadata Reader"), threading(both), diff --git a/dll/win32/windowscodecsext/CMakeLists.txt b/dll/win32/windowscodecsext/CMakeLists.txt index da3505e34fa14..7d2faed43e457 100644 --- a/dll/win32/windowscodecsext/CMakeLists.txt +++ b/dll/win32/windowscodecsext/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(windowscodecsext.dll windowscodecsext.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -12,3 +10,4 @@ set_module_type(windowscodecsext win32dll) target_link_libraries(windowscodecsext wine) add_importlibs(windowscodecsext ole32 msvcrt kernel32 ntdll) add_cd_file(TARGET windowscodecsext DESTINATION reactos/system32 FOR all) +set_wine_module(windowscodecsext) diff --git a/dll/win32/windowscodecsext/main.c b/dll/win32/windowscodecsext/main.c index 8835a313e83f7..3f2be235f180a 100644 --- a/dll/win32/windowscodecsext/main.c +++ b/dll/win32/windowscodecsext/main.c @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" - #include #define COBJMACROS @@ -32,22 +30,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); -BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) -{ - TRACE("(%p, %u, %p)\n", instance, reason, reserved); - - switch (reason) - { - case DLL_WINE_PREATTACH: - return FALSE; /* prefer native version */ - case DLL_PROCESS_ATTACH: - DisableThreadLibraryCalls(instance); - break; - } - - return TRUE; -} - /****************************************************************** * DllGetClassObject */ diff --git a/dll/win32/winemp3.acm/CMakeLists.txt b/dll/win32/winemp3.acm/CMakeLists.txt index 4d428baa456ca..917f4927a372d 100644 --- a/dll/win32/winemp3.acm/CMakeLists.txt +++ b/dll/win32/winemp3.acm/CMakeLists.txt @@ -1,10 +1,8 @@ add_definitions( - -D__WINESRC__ -DWIN32) include_directories( - ${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine ${REACTOS_SOURCE_DIR}/sdk/include/reactos/libs/libmpg123) spec2def(winemp3.acm winemp3.acm.spec) @@ -18,3 +16,4 @@ set_target_properties(winemp3.acm PROPERTIES SUFFIX "") target_link_libraries(winemp3.acm wine libmpg123 oldnames) add_importlibs(winemp3.acm shlwapi winmm user32 msvcrt kernel32 ntdll) add_cd_file(TARGET winemp3.acm DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(winemp3.acm) # CORE-5743: No ARRAY_SIZE macro diff --git a/dll/win32/winhttp/CMakeLists.txt b/dll/win32/winhttp/CMakeLists.txt index 184ca8604e642..bac4baaaa173c 100644 --- a/dll/win32/winhttp/CMakeLists.txt +++ b/dll/win32/winhttp/CMakeLists.txt @@ -3,10 +3,8 @@ remove_definitions(-D_WIN32_WINNT=0x502) add_definitions(-D_WIN32_WINNT=0x600) add_definitions( - -D__WINESRC__ -D_WINE) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(winhttp.dll winhttp.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -34,3 +32,4 @@ add_importlibs(winhttp user32 advapi32 ws2_32 jsproxy kernel32_vista msvcrt kern add_dependencies(winhttp stdole2) add_pch(winhttp precomp.h SOURCE) add_cd_file(TARGET winhttp DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(winhttp) # CORE-5743: No ARRAY_SIZE macro diff --git a/dll/win32/wininet/CMakeLists.txt b/dll/win32/wininet/CMakeLists.txt index 73449f9f8b446..3f49477e6ecf1 100644 --- a/dll/win32/wininet/CMakeLists.txt +++ b/dll/win32/wininet/CMakeLists.txt @@ -7,8 +7,8 @@ add_definitions( -D_WIN32_WINNT=0x600) add_definitions( - -D__WINESRC__ - -D_WINE) + -D_WINE + -D__ROS_LONG64__) spec2def(wininet.dll wininet.spec ADD_IMPORTLIB) @@ -28,7 +28,6 @@ list(APPEND PCH_SKIP_SOURCE ${CMAKE_CURRENT_BINARY_DIR}/wininet_stubs.c) add_library(wininet_inflate OBJECT inflate.c) -target_include_directories(wininet_inflate BEFORE PRIVATE ${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) add_dependencies(wininet_inflate psdk) add_library(wininet MODULE @@ -50,3 +49,4 @@ add_delay_importlibs(wininet secur32 crypt32 cryptui iphlpapi dhcpcsvc) add_importlibs(wininet mpr shlwapi shell32 user32 advapi32 ws2_32 normaliz kernel32_vista msvcrt kernel32 ntdll) add_pch(wininet precomp.h "${PCH_SKIP_SOURCE}") add_cd_file(TARGET wininet DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(wininet) # CORE-5743: No ARRAY_SIZE macro diff --git a/dll/win32/wininet/lang/wininet_Da.rc b/dll/win32/wininet/lang/wininet_Da.rc index 1411bfd1fcfa7..e857efdfadefc 100644 --- a/dll/win32/wininet/lang/wininet_Da.rc +++ b/dll/win32/wininet/lang/wininet_Da.rc @@ -17,8 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_DANISH, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/wininet/lang/wininet_De.rc b/dll/win32/wininet/lang/wininet_De.rc index eae9240f2c85a..9f89bcd121e5f 100644 --- a/dll/win32/wininet/lang/wininet_De.rc +++ b/dll/win32/wininet/lang/wininet_De.rc @@ -17,8 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/wininet/lang/wininet_Fr.rc b/dll/win32/wininet/lang/wininet_Fr.rc index 5e6adfd01a537..3679ff4d7e637 100644 --- a/dll/win32/wininet/lang/wininet_Fr.rc +++ b/dll/win32/wininet/lang/wininet_Fr.rc @@ -22,9 +22,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/wininet/lang/wininet_He.rc b/dll/win32/wininet/lang/wininet_He.rc index a663f624fbbcf..5a606f45861d9 100644 --- a/dll/win32/wininet/lang/wininet_He.rc +++ b/dll/win32/wininet/lang/wininet_He.rc @@ -17,8 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_HEBREW, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/wininet/lang/wininet_Hu.rc b/dll/win32/wininet/lang/wininet_Hu.rc index 0f7becb9ffcc6..67b4b580450a8 100644 --- a/dll/win32/wininet/lang/wininet_Hu.rc +++ b/dll/win32/wininet/lang/wininet_Hu.rc @@ -16,9 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/wininet/lang/wininet_It.rc b/dll/win32/wininet/lang/wininet_It.rc index 859c1eb08429a..1e84d85484b7f 100644 --- a/dll/win32/wininet/lang/wininet_It.rc +++ b/dll/win32/wininet/lang/wininet_It.rc @@ -19,9 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/wininet/lang/wininet_Ja.rc b/dll/win32/wininet/lang/wininet_Ja.rc index a00db74a3a2e0..76307e748ed42 100644 --- a/dll/win32/wininet/lang/wininet_Ja.rc +++ b/dll/win32/wininet/lang/wininet_Ja.rc @@ -16,9 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/wininet/lang/wininet_Ko.rc b/dll/win32/wininet/lang/wininet_Ko.rc index 266143045a0dd..f12b6d495dfff 100644 --- a/dll/win32/wininet/lang/wininet_Ko.rc +++ b/dll/win32/wininet/lang/wininet_Ko.rc @@ -17,8 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/wininet/lang/wininet_Lt.rc b/dll/win32/wininet/lang/wininet_Lt.rc index 1b7e8427970c6..316baf4ae78c6 100644 --- a/dll/win32/wininet/lang/wininet_Lt.rc +++ b/dll/win32/wininet/lang/wininet_Lt.rc @@ -16,9 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_LITHUANIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/wininet/lang/wininet_Nl.rc b/dll/win32/wininet/lang/wininet_Nl.rc index 5f8c432495c41..000cd8f75ca2e 100644 --- a/dll/win32/wininet/lang/wininet_Nl.rc +++ b/dll/win32/wininet/lang/wininet_Nl.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/wininet/lang/wininet_No.rc b/dll/win32/wininet/lang/wininet_No.rc index b0c3e2fc9e871..ed921f882563e 100644 --- a/dll/win32/wininet/lang/wininet_No.rc +++ b/dll/win32/wininet/lang/wininet_No.rc @@ -16,8 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL STRINGTABLE diff --git a/dll/win32/wininet/lang/wininet_Pt.rc b/dll/win32/wininet/lang/wininet_Pt.rc index 83f2878151def..19be6402f9b7f 100644 --- a/dll/win32/wininet/lang/wininet_Pt.rc +++ b/dll/win32/wininet/lang/wininet_Pt.rc @@ -19,8 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN STRINGTABLE diff --git a/dll/win32/wininet/lang/wininet_Ro.rc b/dll/win32/wininet/lang/wininet_Ro.rc index 186e7724fed9d..5ac07610f20d8 100644 --- a/dll/win32/wininet/lang/wininet_Ro.rc +++ b/dll/win32/wininet/lang/wininet_Ro.rc @@ -19,8 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/wininet/lang/wininet_Ru.rc b/dll/win32/wininet/lang/wininet_Ru.rc index 14b5363db9329..5fe5709cbd8e6 100644 --- a/dll/win32/wininet/lang/wininet_Ru.rc +++ b/dll/win32/wininet/lang/wininet_Ru.rc @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/wininet/lang/wininet_Si.rc b/dll/win32/wininet/lang/wininet_Si.rc index b70d7adbf1bd7..8a01513c5c7e1 100644 --- a/dll/win32/wininet/lang/wininet_Si.rc +++ b/dll/win32/wininet/lang/wininet_Si.rc @@ -16,8 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/wininet/lang/wininet_Sr.rc b/dll/win32/wininet/lang/wininet_Sr.rc index 19ee56ac774d7..473e9636b6521 100644 --- a/dll/win32/wininet/lang/wininet_Sr.rc +++ b/dll/win32/wininet/lang/wininet_Sr.rc @@ -17,8 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_SERBIAN, SUBLANG_SERBIAN_CYRILLIC STRINGTABLE diff --git a/dll/win32/wininet/lang/wininet_Uk.rc b/dll/win32/wininet/lang/wininet_Uk.rc index 7aab43df6e6e5..3519902e335eb 100644 --- a/dll/win32/wininet/lang/wininet_Uk.rc +++ b/dll/win32/wininet/lang/wininet_Uk.rc @@ -19,9 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/wininet/lang/wininet_Zh.rc b/dll/win32/wininet/lang/wininet_Zh.rc index 32db03edefff1..3d4d81f244745 100644 --- a/dll/win32/wininet/lang/wininet_Zh.rc +++ b/dll/win32/wininet/lang/wininet_Zh.rc @@ -20,9 +20,6 @@ * Copyright 2021 Chan Chilung */ -/* Chinese text is encoded in UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED STRINGTABLE diff --git a/dll/win32/winmm/CMakeLists.txt b/dll/win32/winmm/CMakeLists.txt index aca0942d4be1e..2566277f94d7e 100644 --- a/dll/win32/winmm/CMakeLists.txt +++ b/dll/win32/winmm/CMakeLists.txt @@ -30,7 +30,7 @@ endif() set_module_type(winmm win32dll) target_link_libraries(winmm wine ${PSEH_LIB} oldnames) -add_importlibs(winmm advapi32 user32 msvcrt kernel32 ntdll) +add_importlibs(winmm userenv advapi32 user32 msvcrt kernel32 ntdll) add_pch(winmm winemm.h SOURCE) add_cd_file(TARGET winmm DESTINATION reactos/system32 FOR all) diff --git a/dll/win32/winmm/lang/winmm_Br.rc b/dll/win32/winmm/lang/winmm_Br.rc index 9d09bef1c0cd8..59542df69672e 100644 --- a/dll/win32/winmm/lang/winmm_Br.rc +++ b/dll/win32/winmm/lang/winmm_Br.rc @@ -17,7 +17,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -STRINGTABLE LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN +LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN + +STRINGTABLE BEGIN /* MMSYS errors */ diff --git a/dll/win32/winmm/lang/winmm_Cs.rc b/dll/win32/winmm/lang/winmm_Cs.rc index da219c68b7d95..b164619ec570d 100644 --- a/dll/win32/winmm/lang/winmm_Cs.rc +++ b/dll/win32/winmm/lang/winmm_Cs.rc @@ -18,7 +18,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -STRINGTABLE LANGUAGE LANG_CZECH, SUBLANG_DEFAULT +LANGUAGE LANG_CZECH, SUBLANG_DEFAULT + +STRINGTABLE BEGIN /* MMSYS errors */ diff --git a/dll/win32/winmm/lang/winmm_De.rc b/dll/win32/winmm/lang/winmm_De.rc index 5fbcd5e26eea3..1748b31cafc5c 100644 --- a/dll/win32/winmm/lang/winmm_De.rc +++ b/dll/win32/winmm/lang/winmm_De.rc @@ -16,7 +16,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -STRINGTABLE LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL +LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL + +STRINGTABLE BEGIN /* MMSYS errors */ diff --git a/dll/win32/winmm/lang/winmm_En.rc b/dll/win32/winmm/lang/winmm_En.rc index 3fb0f7c81942a..fb3dd8381b692 100644 --- a/dll/win32/winmm/lang/winmm_En.rc +++ b/dll/win32/winmm/lang/winmm_En.rc @@ -16,7 +16,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -STRINGTABLE LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +STRINGTABLE BEGIN /* MMSYS errors */ diff --git a/dll/win32/winmm/lang/winmm_Es.rc b/dll/win32/winmm/lang/winmm_Es.rc index 5308abdf222c5..7218f3d8ce948 100644 --- a/dll/win32/winmm/lang/winmm_Es.rc +++ b/dll/win32/winmm/lang/winmm_Es.rc @@ -17,7 +17,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -STRINGTABLE LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL +LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL + +STRINGTABLE BEGIN /* MMSYS errors */ diff --git a/dll/win32/winmm/lang/winmm_Hu.rc b/dll/win32/winmm/lang/winmm_Hu.rc index 05cf8155a865c..0e9e7dd9d8a2d 100644 --- a/dll/win32/winmm/lang/winmm_Hu.rc +++ b/dll/win32/winmm/lang/winmm_Hu.rc @@ -17,7 +17,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -STRINGTABLE LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT +LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT + +STRINGTABLE BEGIN /* MMSYS errors */ diff --git a/dll/win32/winmm/lang/winmm_Id.rc b/dll/win32/winmm/lang/winmm_Id.rc index de3560952c849..6cc8deb5d535a 100644 --- a/dll/win32/winmm/lang/winmm_Id.rc +++ b/dll/win32/winmm/lang/winmm_Id.rc @@ -16,8 +16,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -STRINGTABLE LANGUAGE LANG_INDONESIAN, SUBLANG_DEFAULT +LANGUAGE LANG_INDONESIAN, SUBLANG_DEFAULT +STRINGTABLE BEGIN /* MMSYS errors */ diff --git a/dll/win32/winmm/lang/winmm_It.rc b/dll/win32/winmm/lang/winmm_It.rc index c9cad247d7824..c595c8328a118 100644 --- a/dll/win32/winmm/lang/winmm_It.rc +++ b/dll/win32/winmm/lang/winmm_It.rc @@ -17,7 +17,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -STRINGTABLE LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL +LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL + +STRINGTABLE BEGIN /* MMSYS errors */ diff --git a/dll/win32/winmm/lang/winmm_Ja.rc b/dll/win32/winmm/lang/winmm_Ja.rc index e208d91f0da7e..27a9da7542bfc 100644 --- a/dll/win32/winmm/lang/winmm_Ja.rc +++ b/dll/win32/winmm/lang/winmm_Ja.rc @@ -16,7 +16,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -STRINGTABLE LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT +LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT + +STRINGTABLE BEGIN /* MMSYS errors */ diff --git a/dll/win32/winmm/lang/winmm_Nl.rc b/dll/win32/winmm/lang/winmm_Nl.rc index f8b6305da06e9..2d615c8ea1f88 100644 --- a/dll/win32/winmm/lang/winmm_Nl.rc +++ b/dll/win32/winmm/lang/winmm_Nl.rc @@ -16,7 +16,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -STRINGTABLE LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL +LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL + +STRINGTABLE BEGIN /* MMSYS errors */ diff --git a/dll/win32/winmm/lang/winmm_No.rc b/dll/win32/winmm/lang/winmm_No.rc index 07c6cf9b7ec93..1373fd48816a0 100644 --- a/dll/win32/winmm/lang/winmm_No.rc +++ b/dll/win32/winmm/lang/winmm_No.rc @@ -20,7 +20,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -STRINGTABLE LANGUAGE LANG_NORWEGIAN, SUBLANG_NEUTRAL +LANGUAGE LANG_NORWEGIAN, SUBLANG_NEUTRAL + +STRINGTABLE BEGIN /* MMSYS errors */ diff --git a/dll/win32/winmm/lang/winmm_Pl.rc b/dll/win32/winmm/lang/winmm_Pl.rc index 1b707d57713cc..58aec5c81efdb 100644 --- a/dll/win32/winmm/lang/winmm_Pl.rc +++ b/dll/win32/winmm/lang/winmm_Pl.rc @@ -16,7 +16,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -STRINGTABLE LANGUAGE LANG_POLISH, SUBLANG_DEFAULT +LANGUAGE LANG_POLISH, SUBLANG_DEFAULT + +STRINGTABLE BEGIN /* MMSYS errors */ diff --git a/dll/win32/winmm/lang/winmm_Pt.rc b/dll/win32/winmm/lang/winmm_Pt.rc index 0daf89bc4fc20..ad884b656e9e8 100644 --- a/dll/win32/winmm/lang/winmm_Pt.rc +++ b/dll/win32/winmm/lang/winmm_Pt.rc @@ -17,7 +17,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -STRINGTABLE LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_PORTUGAL +LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_PORTUGAL + +STRINGTABLE BEGIN /* MMSYS errors */ diff --git a/dll/win32/winmm/lang/winmm_Ro.rc b/dll/win32/winmm/lang/winmm_Ro.rc index ca900da23bde9..bd8cf96586440 100644 --- a/dll/win32/winmm/lang/winmm_Ro.rc +++ b/dll/win32/winmm/lang/winmm_Ro.rc @@ -18,7 +18,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -STRINGTABLE LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL +LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL + +STRINGTABLE BEGIN /* MMSYS errors */ diff --git a/dll/win32/winmm/lang/winmm_Ru.rc b/dll/win32/winmm/lang/winmm_Ru.rc index 1a8eb1f11d335..9e717eb5d751d 100644 --- a/dll/win32/winmm/lang/winmm_Ru.rc +++ b/dll/win32/winmm/lang/winmm_Ru.rc @@ -15,12 +15,12 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -/* UTF-8 */ -#pragma code_page(65001) +/* translation by Zahar Hodoley (mail: zaharh@mail.ru) */ -STRINGTABLE LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT -BEGIN +LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT +STRINGTABLE +BEGIN /* MMSYS errors */ MMSYSERR_NOERROR, "Нет ошибки." @@ -127,5 +127,3 @@ MCIERR_SEQ_PORTUNSPECIFIED, "В системе не указан текущий MCIERR_SEQ_TIMER, "Все таймеры мультимедиа используются другими приложениями. Закройте одно из этих приложений и попробуйте заново." END - -/* translation by Zahar Hodoley (mail: zaharh@mail.ru) */ diff --git a/dll/win32/winmm/lang/winmm_Si.rc b/dll/win32/winmm/lang/winmm_Si.rc index 3cfce8d6e183f..b6a3ce9c22f7f 100644 --- a/dll/win32/winmm/lang/winmm_Si.rc +++ b/dll/win32/winmm/lang/winmm_Si.rc @@ -17,7 +17,9 @@ * */ -STRINGTABLE LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT +LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT + +STRINGTABLE BEGIN /* MMSYS errors */ diff --git a/dll/win32/winmm/lang/winmm_Sk.rc b/dll/win32/winmm/lang/winmm_Sk.rc index 85af82f4c1db9..8ae469b6b44b6 100644 --- a/dll/win32/winmm/lang/winmm_Sk.rc +++ b/dll/win32/winmm/lang/winmm_Sk.rc @@ -16,7 +16,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -STRINGTABLE LANGUAGE LANG_SLOVAK, SUBLANG_DEFAULT +LANGUAGE LANG_SLOVAK, SUBLANG_DEFAULT + +STRINGTABLE BEGIN /* MMSYS errors */ diff --git a/dll/win32/winmm/lang/winmm_Sq.rc b/dll/win32/winmm/lang/winmm_Sq.rc index e173ec0858a0f..d1fb4d1de8480 100644 --- a/dll/win32/winmm/lang/winmm_Sq.rc +++ b/dll/win32/winmm/lang/winmm_Sq.rc @@ -16,7 +16,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -STRINGTABLE LANGUAGE LANG_ALBANIAN, SUBLANG_NEUTRAL +LANGUAGE LANG_ALBANIAN, SUBLANG_NEUTRAL + +STRINGTABLE BEGIN /* MMSYS errors */ diff --git a/dll/win32/winmm/lang/winmm_Tr.rc b/dll/win32/winmm/lang/winmm_Tr.rc index d4e905daa6c9d..1a99691829543 100644 --- a/dll/win32/winmm/lang/winmm_Tr.rc +++ b/dll/win32/winmm/lang/winmm_Tr.rc @@ -16,7 +16,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -STRINGTABLE LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT +LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT + +STRINGTABLE BEGIN /* MMSYS errors */ diff --git a/dll/win32/winmm/lang/winmm_Uk.rc b/dll/win32/winmm/lang/winmm_Uk.rc index df1c46fe4296d..58f58a184f065 100644 --- a/dll/win32/winmm/lang/winmm_Uk.rc +++ b/dll/win32/winmm/lang/winmm_Uk.rc @@ -16,10 +16,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -/* UTF-8 */ -#pragma code_page(65001) +LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT -STRINGTABLE LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT +STRINGTABLE BEGIN /* MMSYS errors */ diff --git a/dll/win32/winmm/lang/winmm_Zh.rc b/dll/win32/winmm/lang/winmm_Zh.rc index 318d1fd1f9f13..4e39d592d7c47 100644 --- a/dll/win32/winmm/lang/winmm_Zh.rc +++ b/dll/win32/winmm/lang/winmm_Zh.rc @@ -19,10 +19,9 @@ * Copyright 2021 Chan Chilung */ -/* Chinese text is encoded in UTF-8 */ -#pragma code_page(65001) +LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED -STRINGTABLE LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED +STRINGTABLE BEGIN /* MMSYS errors */ @@ -128,9 +127,12 @@ MCIERR_SEQ_PORT_MISCERROR, "用指定的端口时出错。" MCIERR_SEQ_PORT_NONEXISTENT, "在系统上没有安装指定的 MIDI 设备。使用控制面板中的驱动程序选项来安装一个 MIDI 设备。" MCIERR_SEQ_PORTUNSPECIFIED, "系统没有指定当前 MIDI 端口。" MCIERR_SEQ_TIMER, "所有多媒体定时器正在被其他应用程序使用。退出这些应用程序;然后,再试一次。" + END -STRINGTABLE LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL +LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL + +STRINGTABLE BEGIN /* MMSYS errors */ @@ -236,4 +238,5 @@ MCIERR_SEQ_PORT_MISCERROR, "指定的連接埠發生了錯誤。" MCIERR_SEQ_PORT_NONEXISTENT, "指定的 MIDI 裝置未安裝到系統上。請使用控制臺中的「驅動程式」選項以安裝 MIDI 裝置。" MCIERR_SEQ_PORTUNSPECIFIED, "系統尚未指定目前的 MIDI 連接埠。" MCIERR_SEQ_TIMER, "所有多媒體計時器正被其他應用程式使用中。請結束其中某一個應用程式,然後再試一次。" + END diff --git a/dll/win32/winmm/playsound.c b/dll/win32/winmm/playsound.c index df532f05cfd9f..991299a0a7fc8 100644 --- a/dll/win32/winmm/playsound.c +++ b/dll/win32/winmm/playsound.c @@ -26,6 +26,7 @@ #include "winemm.h" #include +#include WINE_DEFAULT_DEBUG_CHANNEL(winmm); @@ -39,6 +40,61 @@ typedef struct tagWINE_PLAYSOUND static WINE_PLAYSOUND *PlaySoundCurrent; static BOOL bPlaySoundStop; +/* An impersonation-aware equivalent of ExpandEnvironmentStringsW */ +static DWORD PlaySound_ExpandEnvironmentStrings(LPCWSTR lpSrc, LPWSTR lpDst, DWORD nSize) +{ + HANDLE hToken; + DWORD dwError; + DWORD dwLength = 0; + + if (!OpenThreadToken(GetCurrentThread(), + TOKEN_QUERY | TOKEN_IMPERSONATE | TOKEN_DUPLICATE, + TRUE, + &hToken)) + { + dwError = GetLastError(); + + if (dwError == ERROR_NO_TOKEN) + { + /* We are not impersonating, forward this to ExpandEnvironmentStrings */ + return ExpandEnvironmentStringsW(lpSrc, lpDst, nSize); + } + + ERR("OpenThreadToken failed (0x%x)\n", dwError); + return 0; + } + + if (!ExpandEnvironmentStringsForUserW(hToken, lpSrc, lpDst, nSize)) + { + dwError = GetLastError(); + + if (dwError == ERROR_INSUFFICIENT_BUFFER || nSize == 0) + { + /* The buffer is too small, find the required buffer size. + * NOTE: ExpandEnvironmentStringsForUser doesn't support retrieving buffer size. */ + WCHAR szExpanded[1024]; + + if (ExpandEnvironmentStringsForUserW(hToken, lpSrc, szExpanded, ARRAY_SIZE(szExpanded))) + { + /* We success, return the required buffer size */ + dwLength = lstrlenW(szExpanded) + 1; + goto Cleanup; + } + } + + ERR("ExpandEnvironmentStringsForUser failed (0x%x)\n", dwError); + } + else + { + /* We success, return the size of the string */ + dwLength = lstrlenW(lpDst) + 1; + } + +Cleanup: + CloseHandle(hToken); + return dwLength; +} + static HMMIO get_mmioFromFile(LPCWSTR lpszName) { HMMIO ret; @@ -158,7 +214,7 @@ static HMMIO get_mmioFromProfile(UINT uFlags, LPCWSTR lpszName) if (type == REG_EXPAND_SZ) { - count = ExpandEnvironmentStringsW(str, NULL, 0); + count = PlaySound_ExpandEnvironmentStrings(str, NULL, 0); if (count == 0) goto None; @@ -166,7 +222,7 @@ static HMMIO get_mmioFromProfile(UINT uFlags, LPCWSTR lpszName) if (!pszSnd) goto None; - if (ExpandEnvironmentStringsW(str, pszSnd, count) == 0) + if (PlaySound_ExpandEnvironmentStrings(str, pszSnd, count) == 0) { HeapFree(GetProcessHeap(), 0, pszSnd); goto None; diff --git a/dll/win32/winscard/CMakeLists.txt b/dll/win32/winscard/CMakeLists.txt index 7c3cf89a5e61c..237f7d0687eaf 100644 --- a/dll/win32/winscard/CMakeLists.txt +++ b/dll/win32/winscard/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(BEFORE ${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(winscard.dll winscard.spec) list(APPEND SOURCE @@ -19,3 +17,4 @@ target_link_libraries(winscard wine) add_importlibs(winscard msvcrt kernel32 ntdll) add_pch(winscard precomp.h SOURCE) add_cd_file(TARGET winscard DESTINATION reactos/system32 FOR all) +set_wine_module(winscard) diff --git a/dll/win32/winsta/query.c b/dll/win32/winsta/query.c index fb9d9ad40729d..7aab5044455d2 100644 --- a/dll/win32/winsta/query.c +++ b/dll/win32/winsta/query.c @@ -29,7 +29,7 @@ WINSTAAPI WinStationQueryInformationA(HANDLE hServer, } /* -http://msdn2.microsoft.com/En-US/library/aa383827.aspx +https://learn.microsoft.com/en-us/previous-versions//aa383827(v=vs.85) */ BOOLEAN WINSTAAPI diff --git a/dll/win32/wintrust/CMakeLists.txt b/dll/win32/wintrust/CMakeLists.txt index c6ee5b0133847..b5de35526d1d8 100644 --- a/dll/win32/wintrust/CMakeLists.txt +++ b/dll/win32/wintrust/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(BEFORE ${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(wintrust.dll wintrust.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -30,3 +28,4 @@ add_delay_importlibs(wintrust cryptui) add_importlibs(wintrust imagehlp crypt32 user32 advapi32 msvcrt kernel32 ntdll) add_pch(wintrust precomp.h SOURCE) add_cd_file(TARGET wintrust DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(wintrust) # CORE-5743: No ARRAY_SIZE macro diff --git a/dll/win32/wldap32/CMakeLists.txt b/dll/win32/wldap32/CMakeLists.txt index 4a94f6bc3c9f3..ca36449c20f4c 100644 --- a/dll/win32/wldap32/CMakeLists.txt +++ b/dll/win32/wldap32/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(wldap32.dll wldap32.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -39,3 +37,4 @@ target_link_libraries(wldap32 wine) add_importlibs(wldap32 user32 msvcrt kernel32 ntdll) add_pch(wldap32 precomp.h "${PCH_SKIP_SOURCE}") add_cd_file(TARGET wldap32 DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(wldap32) # CORE-5743: No ARRAY_SIZE macro diff --git a/dll/win32/wldap32/lang/wldap32_De.rc b/dll/win32/wldap32/lang/wldap32_De.rc index 5743b84d0b2f0..da90079942bff 100644 --- a/dll/win32/wldap32/lang/wldap32_De.rc +++ b/dll/win32/wldap32/lang/wldap32_De.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/wldap32/lang/wldap32_Fr.rc b/dll/win32/wldap32/lang/wldap32_Fr.rc index ff5d1a59c0188..0c7c52a8c8e23 100644 --- a/dll/win32/wldap32/lang/wldap32_Fr.rc +++ b/dll/win32/wldap32/lang/wldap32_Fr.rc @@ -19,9 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/wldap32/lang/wldap32_Hu.rc b/dll/win32/wldap32/lang/wldap32_Hu.rc index deb45bd862eaa..ba4e63ded4bd1 100644 --- a/dll/win32/wldap32/lang/wldap32_Hu.rc +++ b/dll/win32/wldap32/lang/wldap32_Hu.rc @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/wldap32/lang/wldap32_It.rc b/dll/win32/wldap32/lang/wldap32_It.rc index 6b032ab3c44fe..bf775f7483169 100644 --- a/dll/win32/wldap32/lang/wldap32_It.rc +++ b/dll/win32/wldap32/lang/wldap32_It.rc @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/*UTF-8*/ -#pragma code_page(65001) - LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/wldap32/lang/wldap32_Lt.rc b/dll/win32/wldap32/lang/wldap32_Lt.rc index 8527c357bb6b6..a9fecbec256df 100644 --- a/dll/win32/wldap32/lang/wldap32_Lt.rc +++ b/dll/win32/wldap32/lang/wldap32_Lt.rc @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_LITHUANIAN, SUBLANG_NEUTRAL STRINGTABLE diff --git a/dll/win32/wldap32/lang/wldap32_Pt.rc b/dll/win32/wldap32/lang/wldap32_Pt.rc index fd95c104af8c5..6015b533ee2d5 100644 --- a/dll/win32/wldap32/lang/wldap32_Pt.rc +++ b/dll/win32/wldap32/lang/wldap32_Pt.rc @@ -19,8 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#pragma code_page(65001) - LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN STRINGTABLE diff --git a/dll/win32/wldap32/lang/wldap32_Ro.rc b/dll/win32/wldap32/lang/wldap32_Ro.rc index fe05b0e6ceac0..c916b1a1a4263 100644 --- a/dll/win32/wldap32/lang/wldap32_Ro.rc +++ b/dll/win32/wldap32/lang/wldap32_Ro.rc @@ -21,8 +21,6 @@ LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL -#pragma code_page(65001) - STRINGTABLE { 0 "Succes" diff --git a/dll/win32/wldap32/lang/wldap32_Ru.rc b/dll/win32/wldap32/lang/wldap32_Ru.rc index eeb2d612c8dd1..8032c26601fe1 100644 --- a/dll/win32/wldap32/lang/wldap32_Ru.rc +++ b/dll/win32/wldap32/lang/wldap32_Ru.rc @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/wldap32/lang/wldap32_Uk.rc b/dll/win32/wldap32/lang/wldap32_Uk.rc index f5665acff2430..678f20119bd1e 100644 --- a/dll/win32/wldap32/lang/wldap32_Uk.rc +++ b/dll/win32/wldap32/lang/wldap32_Uk.rc @@ -20,9 +20,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT STRINGTABLE diff --git a/dll/win32/wldap32/lang/wldap32_Zh.rc b/dll/win32/wldap32/lang/wldap32_Zh.rc index cc556548f1887..e40d6b501781a 100644 --- a/dll/win32/wldap32/lang/wldap32_Zh.rc +++ b/dll/win32/wldap32/lang/wldap32_Zh.rc @@ -21,9 +21,6 @@ * Copyright 2021 Chan Chilung */ -/* Chinese text is encoded in UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED STRINGTABLE diff --git a/dll/win32/wmiutils/CMakeLists.txt b/dll/win32/wmiutils/CMakeLists.txt index 01df1c8e3c082..17660182720f7 100644 --- a/dll/win32/wmiutils/CMakeLists.txt +++ b/dll/win32/wmiutils/CMakeLists.txt @@ -1,7 +1,4 @@ -add_definitions(-D__WINESRC__) - -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(wmiutils.dll wmiutils.spec) list(APPEND SOURCE @@ -15,3 +12,4 @@ set_module_type(wmiutils win32dll) target_link_libraries(wmiutils wine) add_importlibs(wmiutils oleaut32 msvcrt kernel32 ntdll) add_cd_file(TARGET wmiutils DESTINATION reactos/system32/wbem FOR all) +set_wine_module_FIXME(wmiutils) # CORE-5743: No CONST_VTABLE diff --git a/dll/win32/wmiutils/main.c b/dll/win32/wmiutils/main.c index 9befe016bd4e0..c060f4b1c01fa 100644 --- a/dll/win32/wmiutils/main.c +++ b/dll/win32/wmiutils/main.c @@ -117,8 +117,10 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID lpv ) { switch(reason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: instance = hinst; DisableThreadLibraryCalls( hinst ); diff --git a/dll/win32/wmvcore/CMakeLists.txt b/dll/win32/wmvcore/CMakeLists.txt index 09cc647fc2af9..ac71e301d1294 100644 --- a/dll/win32/wmvcore/CMakeLists.txt +++ b/dll/win32/wmvcore/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(wmvcore.dll wmvcore.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -15,3 +13,4 @@ set_module_type(wmvcore win32dll) target_link_libraries(wmvcore wine) add_importlibs(wmvcore msvcrt kernel32 ntdll) add_cd_file(TARGET wmvcore DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(wmvcore) # CORE-5743: No CONST_VTABLE diff --git a/dll/win32/wmvcore/wmvcore_main.c b/dll/win32/wmvcore/wmvcore_main.c index af23ab88b8a93..6b6a4975e1669 100644 --- a/dll/win32/wmvcore/wmvcore_main.c +++ b/dll/win32/wmvcore/wmvcore_main.c @@ -31,8 +31,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) switch (fdwReason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hinstDLL); break; diff --git a/dll/win32/wshom.ocx/CMakeLists.txt b/dll/win32/wshom.ocx/CMakeLists.txt index 98c2d8ad479da..b72b00c4b44da 100644 --- a/dll/win32/wshom.ocx/CMakeLists.txt +++ b/dll/win32/wshom.ocx/CMakeLists.txt @@ -1,10 +1,7 @@ -add_definitions(-D__WINESRC__) - remove_definitions(-D_WIN32_WINNT=0x502) add_definitions(-D_WIN32_WINNT=0x600) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(wshom.ocx wshom.ocx.spec) add_idl_headers(wshom_idlheader wshom.idl) add_typelib(wshom.idl) @@ -34,3 +31,4 @@ add_importlibs(wshom oleaut32 ole32 shell32 advapi32 advapi32_vista user32 msvcr add_dependencies(wshom stdole2 wshom_idlheader) add_pch(wshom precomp.h "${PCH_SKIP_SOURCE}") add_cd_file(TARGET wshom DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(wshom) # CORE-5743: No ARRAY_SIZE and CONST_VTABLE diff --git a/dll/win32/wshom.ocx/wshom_main.c b/dll/win32/wshom.ocx/wshom_main.c index a44b44ce8f4a9..ce97c88772e8f 100644 --- a/dll/win32/wshom.ocx/wshom_main.c +++ b/dll/win32/wshom.ocx/wshom_main.c @@ -222,8 +222,10 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) switch(fdwReason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: wshom_instance = hInstDLL; DisableThreadLibraryCalls(wshom_instance); diff --git a/dll/win32/wuapi/CMakeLists.txt b/dll/win32/wuapi/CMakeLists.txt index 470d013c60f55..714835dccc4c5 100644 --- a/dll/win32/wuapi/CMakeLists.txt +++ b/dll/win32/wuapi/CMakeLists.txt @@ -1,9 +1,7 @@ add_definitions( - -D__WINESRC__ -DCOM_NO_WINDOWS_H) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(wuapi.dll wuapi.spec) list(APPEND SOURCE @@ -30,3 +28,4 @@ add_importlibs(wuapi msvcrt kernel32 ntdll) add_dependencies(wuapi stdole2) # wuapi_tlb.tlb needs stdole2.tlb add_pch(wuapi precomp.h SOURCE) add_cd_file(TARGET wuapi DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(wuapi) # CORE-5743: No CONST_VTABLE diff --git a/dll/win32/wuapi/main.c b/dll/win32/wuapi/main.c index c2ed95ed42b19..8bd38dcc85d7b 100644 --- a/dll/win32/wuapi/main.c +++ b/dll/win32/wuapi/main.c @@ -118,8 +118,10 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID lpv ) { switch(reason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: instance = hinst; DisableThreadLibraryCalls( hinst ); diff --git a/dll/win32/xinput1_1/CMakeLists.txt b/dll/win32/xinput1_1/CMakeLists.txt index fd0b3483c7b65..61a01e04c9e5f 100644 --- a/dll/win32/xinput1_1/CMakeLists.txt +++ b/dll/win32/xinput1_1/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(xinput1_1.dll xinput1_1.spec) list(APPEND SOURCE @@ -11,3 +9,4 @@ add_library(xinput1_1 MODULE ${SOURCE} version.rc) set_module_type(xinput1_1 win32dll) add_importlibs(xinput1_1 xinput1_3 msvcrt kernel32) add_cd_file(TARGET xinput1_1 DESTINATION reactos/system32 FOR all) +set_wine_module(xinput1_1) diff --git a/dll/win32/xinput1_1/xinput1_1_main.c b/dll/win32/xinput1_1/xinput1_1_main.c index 04c4261a6fe96..36421d2ce59ae 100644 --- a/dll/win32/xinput1_1/xinput1_1_main.c +++ b/dll/win32/xinput1_1/xinput1_1_main.c @@ -27,8 +27,10 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved) { switch(reason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(inst); break; diff --git a/dll/win32/xinput1_2/CMakeLists.txt b/dll/win32/xinput1_2/CMakeLists.txt index 20ad05be6e45b..bae99a90ff964 100644 --- a/dll/win32/xinput1_2/CMakeLists.txt +++ b/dll/win32/xinput1_2/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(xinput1_2.dll xinput1_2.spec) list(APPEND SOURCE @@ -11,3 +9,4 @@ add_library(xinput1_2 MODULE ${SOURCE} version.rc) set_module_type(xinput1_2 win32dll) add_importlibs(xinput1_2 xinput1_3 msvcrt kernel32) add_cd_file(TARGET xinput1_2 DESTINATION reactos/system32 FOR all) +set_wine_module(xinput1_2) diff --git a/dll/win32/xinput1_2/xinput1_2_main.c b/dll/win32/xinput1_2/xinput1_2_main.c index 04c4261a6fe96..36421d2ce59ae 100644 --- a/dll/win32/xinput1_2/xinput1_2_main.c +++ b/dll/win32/xinput1_2/xinput1_2_main.c @@ -27,8 +27,10 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved) { switch(reason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(inst); break; diff --git a/dll/win32/xinput1_3/CMakeLists.txt b/dll/win32/xinput1_3/CMakeLists.txt index 9f0aa7255021a..7d9e8a6ac5fbc 100644 --- a/dll/win32/xinput1_3/CMakeLists.txt +++ b/dll/win32/xinput1_3/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(xinput1_3.dll xinput1_3.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -12,3 +10,4 @@ set_module_type(xinput1_3 win32dll) target_link_libraries(xinput1_3 wine) add_importlibs(xinput1_3 msvcrt kernel32 ntdll) add_cd_file(TARGET xinput1_3 DESTINATION reactos/system32 FOR all) +set_wine_module(xinput1_3) diff --git a/dll/win32/xinput9_1_0/CMakeLists.txt b/dll/win32/xinput9_1_0/CMakeLists.txt index c41d07a46c24e..e3920886def3f 100644 --- a/dll/win32/xinput9_1_0/CMakeLists.txt +++ b/dll/win32/xinput9_1_0/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(xinput9_1_0.dll xinput9_1_0.spec) list(APPEND SOURCE @@ -11,3 +9,4 @@ add_library(xinput9_1_0 MODULE ${SOURCE} version.rc) set_module_type(xinput9_1_0 win32dll) add_importlibs(xinput9_1_0 msvcrt kernel32 xinput1_3) add_cd_file(TARGET xinput9_1_0 DESTINATION reactos/system32 FOR all) +set_wine_module(xinput9_1_0) diff --git a/dll/win32/xinput9_1_0/xinput9_1_0_main.c b/dll/win32/xinput9_1_0/xinput9_1_0_main.c index 04c4261a6fe96..36421d2ce59ae 100644 --- a/dll/win32/xinput9_1_0/xinput9_1_0_main.c +++ b/dll/win32/xinput9_1_0/xinput9_1_0_main.c @@ -27,8 +27,10 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved) { switch(reason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(inst); break; diff --git a/dll/win32/xmllite/CMakeLists.txt b/dll/win32/xmllite/CMakeLists.txt index ed7dbc8c388f2..faf19328bdbb2 100644 --- a/dll/win32/xmllite/CMakeLists.txt +++ b/dll/win32/xmllite/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(xmllite.dll xmllite.spec ADD_IMPORTLIB) list(APPEND SOURCE @@ -25,3 +23,4 @@ target_link_libraries(xmllite uuid wine oldnames) add_importlibs(xmllite msvcrt kernel32 ntdll) add_pch(xmllite precomp.h SOURCE) add_cd_file(TARGET xmllite DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(xmllite) # CORE-5743: No ARRAY_SIZE and CONST_VTABLE diff --git a/dll/win32/xmllite/xmllite_main.c b/dll/win32/xmllite/xmllite_main.c index 63838a99f75a4..6315e3df668ad 100644 --- a/dll/win32/xmllite/xmllite_main.c +++ b/dll/win32/xmllite/xmllite_main.c @@ -34,8 +34,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) switch (fdwReason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hinstDLL); break; diff --git a/dll/win32/xolehlp/CMakeLists.txt b/dll/win32/xolehlp/CMakeLists.txt index 6e0a97fcae65a..05e6b7982c697 100644 --- a/dll/win32/xolehlp/CMakeLists.txt +++ b/dll/win32/xolehlp/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-D__WINESRC__) -include_directories(BEFORE ${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(xolehlp.dll xolehlp.spec) list(APPEND SOURCE @@ -13,3 +11,4 @@ set_module_type(xolehlp win32dll) target_link_libraries(xolehlp adsiid uuid wine) add_importlibs(xolehlp msvcrt kernel32 ntdll) add_cd_file(TARGET xolehlp DESTINATION reactos/system32 FOR all) +set_wine_module_FIXME(xolehlp) # CORE-5743: No ARRAY_SIZE and CONST_VTABLE diff --git a/dll/win32/xolehlp/xolehlp.c b/dll/win32/xolehlp/xolehlp.c index 2a741f4914e5c..c5fde8d531507 100644 --- a/dll/win32/xolehlp/xolehlp.c +++ b/dll/win32/xolehlp/xolehlp.c @@ -637,8 +637,10 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved ) switch (reason) { +#ifndef __REACTOS__ case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ +#endif case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls( hinst ); break; diff --git a/dll/wow64/CMakeLists.txt b/dll/wow64/CMakeLists.txt new file mode 100644 index 0000000000000..a3aef839e6637 --- /dev/null +++ b/dll/wow64/CMakeLists.txt @@ -0,0 +1,33 @@ +add_definitions(-D_WOW64_) +spec2def(wow64.dll def/wow64.spec ADD_IMPORTLIB) + +add_asm_files(wow64_asm srasm.S exception.S) +add_library(wow64 MODULE + entrypoint.c + exception.c + wow64.c + wine/registry.c + wine/struct32.h + wine/file.c + wine/security.c + wine/system.c + wine/syscall.c + wine/sync.c + wine/virtual.c + ros_wow64_private.h + entrypoint.h + ${wow64_asm} + ${CMAKE_CURRENT_BINARY_DIR}/wow64.def + ${CMAKE_CURRENT_BINARY_DIR}/wow64_stubs.c) + +set_module_type(wow64 win32dll UNICODE ENTRYPOINT DllMain 12) +############################################# +## HACK FOR MSVC COMPILATION WITH win32dll ## +set_subsystem(wow64 console) +################# END HACK ################# + +# FIXME: force a base address below 4 GiB, this one was chosen arbitrarily +set_image_base(wow64 0xFF000000) +add_importlibs(wow64 ntdll) + +add_cd_file(TARGET wow64 DESTINATION reactos/system32 FOR all) diff --git a/dll/wow64/def/wow64.spec b/dll/wow64/def/wow64.spec new file mode 100644 index 0000000000000..12e5f85dbbf62 --- /dev/null +++ b/dll/wow64/def/wow64.spec @@ -0,0 +1,33 @@ +@ stub Wow64AllocThreadHeap +@ stub Wow64AllocateHeap +@ stdcall Wow64AllocateTemp(long) +# @ stdcall Wow64ApcRoutine(long long long ptr) +@ stub Wow64ApcRoutine +@ stub Wow64CheckIfNXEnabled +@ stub Wow64EmulateAtlThunk +@ stub Wow64FreeHeap +@ stub Wow64FreeThreadHeap +@ stub Wow64GetWow64ImageOption +@ stub Wow64IsControlFlowGuardEnforced +@ stub Wow64IsStackExtentsCheckEnforced +@ stdcall Wow64KiUserCallbackDispatcher(long ptr long ptr ptr) +@ stdcall Wow64LdrpInitialize(ptr) +@ stub Wow64LogPrint +@ stub Wow64NotifyUnsimulateComplete +@ stdcall Wow64PassExceptionToGuest(ptr) +# @ stub Wow64PassExceptionToGuest +@ stub Wow64PrepareForDebuggerAttach +# @ stdcall -norelay Wow64PrepareForException(ptr ptr) +@ stub Wow64PrepareForException +# @ stdcall Wow64ProcessPendingCrossProcessItems() +@ stub Wow64ProcessPendingCrossProcessItems +# @ stdcall Wow64RaiseException(long ptr) +@ stub Wow64RaiseException +@ stub Wow64ShallowThunkAllocObjectAttributes32TO64_FNC +@ stub Wow64ShallowThunkAllocSecurityQualityOfService32TO64_FNC +@ stub Wow64ShallowThunkSIZE_T32TO64 +@ stub Wow64ShallowThunkSIZE_T64TO32 +@ stub Wow64SuspendLocalThread +@ stdcall -norelay Wow64SystemServiceEx(long ptr) +@ stub Wow64ValidateUserCallTarget +@ stub Wow64ValidateUserCallTargetFilter diff --git a/dll/wow64/entrypoint.c b/dll/wow64/entrypoint.c new file mode 100644 index 0000000000000..63852a0264610 --- /dev/null +++ b/dll/wow64/entrypoint.c @@ -0,0 +1,498 @@ +#include "entrypoint.h" + +typedef enum _FIXUP +{ + Fix32To64, + Fix64To32 +} FIXUP; + +typedef struct _ENTRYPOINT_TRANSLATION +{ + LPCWSTR LibraryName32; + LPCWSTR LibraryName64; + LPCSTR SymbolName64; + LPCSTR SymbolName32; + ULONG_PTR SymbolAddress64; + ULONG SymbolAddress32; + NTSTATUS (*ContextFixup)(HANDLE hProcess, PCONTEXT, PI386_CONTEXT, FIXUP); +} ENTRYPOINT_TRANSLATION, *PENTRYPOINT_TRANSLATION; + +static +NTSTATUS +Wow64FixupNativeEntrypoint(HANDLE hProcess, PCONTEXT pContext); + +static +NTSTATUS +FixupStartupThunks(HANDLE hProcess, + PCONTEXT pContext, + PI386_CONTEXT pContext32, + FIXUP fixup); + +static ENTRYPOINT_TRANSLATION EntrypointTranslations[] = +{ + { + L"kernel32.dll", L"kernel32.dll", + "BaseProcessStart", "BaseProcessStartThunk", + 0, 0, + FixupStartupThunks + }, + { + L"kernel32.dll", L"kernel32.dll", + "BaseThreadStart", "BaseThreadStartupThunk", + 0, 0, + FixupStartupThunks + } +}; + +static +NTSTATUS +Wow64MapSelectedTranslationDll(IN LPCWSTR Name, + IN OPTIONAL LPCWSTR PrevName, + IN LPCWSTR Directory, + IN OUT PHANDLE phSection, + IN OUT PVOID* Base) +{ + HANDLE hFile; + NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + SIZE_T ViewSize = 0; + PVOID ViewBase = NULL; + /* TODO/FIXME: Grow the buffer if needed. */ + WCHAR PathBuffer[MAX_PATH] = { 0 }; + UNICODE_STRING Path; + IO_STATUS_BLOCK IoStatusBlock = { 0 }; + + if (PrevName == NULL) + { + PrevName = L""; + } + + if (wcscmp(Name, PrevName) != 0) + { + wcscpy(PathBuffer, Directory); + wcscat(PathBuffer, L"\\"); + wcscat(PathBuffer, Name); + + Path.Buffer = PathBuffer; + Path.MaximumLength = sizeof(PathBuffer); + Path.Length = (USHORT)wcslen(PathBuffer) * sizeof(WCHAR); + ASSERT(Path.Length <= Path.MaximumLength); + + if (*phSection != NULL) + { + NtUnmapViewOfSection(NtCurrentProcess(), *Base); + NtClose(*phSection); + } + + InitializeObjectAttributes(&ObjectAttributes, + &Path, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = NtOpenFile(&hFile, + SYNCHRONIZE | FILE_EXECUTE | FILE_READ_DATA, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ | FILE_SHARE_DELETE, + FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + Status = NtCreateSection(phSection, + SECTION_MAP_READ | SECTION_MAP_EXECUTE | + SECTION_MAP_WRITE | SECTION_QUERY, + NULL, + NULL, + PAGE_EXECUTE, + SEC_IMAGE, + hFile); + if (!NT_SUCCESS(Status)) + { + NtClose(hFile); + return Status; + } + + NtClose(hFile); + + Status = NtMapViewOfSection(*phSection, + NtCurrentProcess(), + &ViewBase, + 0, + 0, + NULL, + &ViewSize, + ViewShare, + 0, + PAGE_READWRITE); + if (!NT_SUCCESS(Status)) + { + *Base = NULL; + return Status; + } + + *Base = ViewBase; + } + + return STATUS_SUCCESS; +} + +static +NTSTATUS +Wow64FindDllExport(PVOID DllBase, + LPCSTR ImportName, + PVOID* Result) +{ + PIMAGE_EXPORT_DIRECTORY ExportDir; + ULONG ExportDirSize; + + const UINT16* OrdinalTable; + const ULONG* NameTable; + const ULONG* AddressTable; + UINT16 Ordinal; + LPCSTR Name; + + ULONG i; + + /* Get the pointer to the export directory */ + ExportDir = RtlImageDirectoryEntryToData(DllBase, + TRUE, + IMAGE_DIRECTORY_ENTRY_EXPORT, + &ExportDirSize); + + if (!ExportDir) + { + return STATUS_PROCEDURE_NOT_FOUND; + } + + NameTable = (PVOID)(ExportDir->AddressOfNames + (ULONG_PTR)DllBase); + OrdinalTable = (PVOID)(ExportDir->AddressOfNameOrdinals + (ULONG_PTR)DllBase); + AddressTable = (PVOID)(ExportDir->AddressOfFunctions + (ULONG_PTR)DllBase); + + Ordinal = 0; + + for (i = 0; i < ExportDir->NumberOfNames; i++) + { + Name = (LPCSTR)(NameTable[i] + (ULONG_PTR)DllBase); + + if (strcmp(Name, ImportName) == 0) + { + Ordinal = OrdinalTable[i]; + *Result = (PVOID)((ULONG_PTR)DllBase + AddressTable[Ordinal]); + + return STATUS_SUCCESS; + } + } + + return STATUS_PROCEDURE_NOT_FOUND; +} + +NTSTATUS +Wow64InitEntrypointTranslation(VOID) +{ + SIZE_T i = 0; + PENTRYPOINT_TRANSLATION pTranslation; + NTSTATUS Status; + UNICODE_STRING UnexpanedSysRoot = RTL_CONSTANT_STRING(L"%SystemRoot%"); + UNICODE_STRING SystemRootString; + WCHAR Buffer[MAX_PATH] = { 0 }; + + PVOID Temp; + + PVOID Base32 = NULL, Base64 = NULL; + + LPCWSTR PrevName32 = NULL, PrevName64 = NULL; + WCHAR Directory32[MAX_PATH], Directory64[MAX_PATH]; + + /* Get the Windows directory */ + RtlInitEmptyUnicodeString(&SystemRootString, Buffer, sizeof(Buffer)); + Status = RtlExpandEnvironmentStrings_U(NULL, + &UnexpanedSysRoot, + &SystemRootString, + NULL); + if (!NT_SUCCESS(Status)) + { + return Status; + } + +#ifndef TMP_WOW_DIR + wcscpy(Directory32, L"\\??\\"); + wcscat(Directory32, Buffer); + wcscat(Directory32, L"\\SysWOW64"); +#else + wcscpy(Directory32, L"\\??\\" TMP_WOW_DIR); +#endif + + wcscpy(Directory64, L"\\??\\"); + wcscat(Directory64, Buffer); + wcscat(Directory64, L"\\System32"); + + DPRINT1("Translation directories %ls and %ls\n", Directory32, Directory64); + + HANDLE hCurrentSection32 = NULL, hCurrentSection64 = NULL; + + for (i = 0; i < _countof(EntrypointTranslations); i++) + { + pTranslation = &EntrypointTranslations[i]; + + Status = Wow64MapSelectedTranslationDll(pTranslation->LibraryName32, + PrevName32, + Directory32, + &hCurrentSection32, + &Base32); + if (!NT_SUCCESS(Status)) + { + break; + } + + Status = Wow64MapSelectedTranslationDll(pTranslation->LibraryName64, + PrevName64, + Directory64, + &hCurrentSection64, + &Base64); + if (!NT_SUCCESS(Status)) + { + break; + } + + + Status = Wow64FindDllExport(Base32, + pTranslation->SymbolName32, + &Temp); + if (!NT_SUCCESS(Status)) + { + DPRINT1("WOW64 Entrypoint Translation Warning: %s not found in 32-bit %ls\n", + pTranslation->SymbolName32, pTranslation->LibraryName32); + continue; + } + pTranslation->SymbolAddress32 = PtrToUlong(Temp); + + Status = Wow64FindDllExport(Base64, + pTranslation->SymbolName64, + &Temp); + if (!NT_SUCCESS(Status)) + { + DPRINT1("WOW64 Entrypoint Translation Warning: %s not found in 64-bit %ls\n", + pTranslation->SymbolName64, pTranslation->LibraryName64); + continue; + } + pTranslation->SymbolAddress64 = (ULONG_PTR)Temp; + + DPRINT("Translating %ls!%s=%llX <-> %ls!%s=%lX\n", + pTranslation->LibraryName64, + pTranslation->SymbolName64, + pTranslation->SymbolAddress64, + pTranslation->LibraryName32, + pTranslation->SymbolName32, + pTranslation->SymbolAddress32); + + PrevName32 = pTranslation->LibraryName32; + PrevName64 = pTranslation->LibraryName64; + } + + if (hCurrentSection32 != NULL) + { + NtUnmapViewOfSection(NtCurrentProcess(), Base32); + NtClose(hCurrentSection32); + } + if (hCurrentSection64 != NULL) + { + NtUnmapViewOfSection(NtCurrentProcess(), Base64); + NtClose(hCurrentSection64); + } + + return Status; +} + +NTSTATUS +Wow64TranslateEntrypoint32To64(IN HANDLE hProcess, + OUT PCONTEXT pContext, + IN PI386_CONTEXT pContext32) +{ + SIZE_T i; + PENTRYPOINT_TRANSLATION pTranslation; + NTSTATUS Status; + + for (i = 0; i < _countof(EntrypointTranslations); i++) + { + pTranslation = &EntrypointTranslations[i]; + + if (pTranslation->SymbolAddress32 == pContext32->Eip) + { + if (pTranslation->ContextFixup != NULL) + { + Status = pTranslation->ContextFixup(hProcess, + pContext, + pContext32, + Fix32To64); + if (!NT_SUCCESS(Status)) + { + return Status; + } + } + + pContext->Rip = pTranslation->SymbolAddress64; + return STATUS_SUCCESS; + } + } + + pContext->Rip = pContext32->Eip; + return STATUS_SUCCESS; +} + +NTSTATUS +Wow64TranslateEntrypoint64To32(IN HANDLE hProcess, + OUT PI386_CONTEXT pContext32, + IN PCONTEXT pContext) +{ + SIZE_T i; + NTSTATUS Status; + PENTRYPOINT_TRANSLATION pTranslation; + + for (i = 0; i < _countof(EntrypointTranslations); i++) + { + pTranslation = &EntrypointTranslations[i]; + + if (pTranslation->SymbolAddress64 == pContext->Rip) + { + if (pTranslation->ContextFixup != NULL) + { + Status = pTranslation->ContextFixup(hProcess, + pContext, + pContext32, + Fix64To32); + if (!NT_SUCCESS(Status)) + { + return Status; + } + } + + pContext32->Eip = pTranslation->SymbolAddress32; + return STATUS_SUCCESS; + } + } + + pContext32->Eip = pContext->Rip; + return STATUS_SUCCESS; +} + +static +NTSTATUS +FixupStartupThunks(HANDLE hProcess, + PCONTEXT pContext, + PI386_CONTEXT pContext32, + FIXUP fixup) +{ + NTSTATUS Status; + + switch (fixup) + { + case Fix32To64: + pContext->Rcx = pContext32->Eax; + pContext->Rdx = pContext32->Ebx; + pContext->SegCs = 0x33; + pContext->Rsp &= (~0xFULL); + pContext->Rsp -= 8; + + /* Manually fixup the entrypoint; see wow64_NtQuerySection */ + if (pContext->Rcx == 0x81231234) + { + Status = Wow64FixupNativeEntrypoint(hProcess, pContext); + if (!NT_SUCCESS(Status)) + { + return Status; + } + } + + break; + case Fix64To32: + pContext32->Eax = pContext->Rcx; + pContext32->Ebx = pContext->Rdx; + pContext32->SegCs = 0x23; + break; + } + + return STATUS_SUCCESS; +} + +static +NTSTATUS +Wow64FixupNativeEntrypoint(HANDLE hProcess, PCONTEXT pContext) +{ + PROCESS_BASIC_INFORMATION Info; + NTSTATUS Status; + PPEB RemotePeb; + ULONG_PTR BaseAddress; + ULONG eLfanew; + ULONG_PTR NtHeaders; + WORD OptionalHeaderMagic; + DWORD EntrypointRva; + + __debugbreak(); + + /* Get the remote PEB */ + Status = NtQueryInformationProcess(hProcess, + ProcessBasicInformation, + &Info, + sizeof(Info), + NULL); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + RemotePeb = Info.PebBaseAddress; + + /* Get the remote base address */ + Status = NtReadVirtualMemory(hProcess, + &RemotePeb->ImageBaseAddress, + &BaseAddress, + sizeof(BaseAddress), + NULL); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + /* Find NT headers */ + Status = NtReadVirtualMemory(hProcess, + &((PIMAGE_DOS_HEADER)BaseAddress)->e_lfanew, + &eLfanew, + sizeof(eLfanew), + NULL); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + NtHeaders = BaseAddress + eLfanew; + + /* Validate the image */ + Status = NtReadVirtualMemory(hProcess, + &((PIMAGE_NT_HEADERS64)NtHeaders)->OptionalHeader.Magic, + &OptionalHeaderMagic, + sizeof(OptionalHeaderMagic), + NULL); + if (!NT_SUCCESS(Status)) + { + return Status; + } + ASSERT(OptionalHeaderMagic == IMAGE_NT_OPTIONAL_HDR64_MAGIC); + + Status = NtReadVirtualMemory(hProcess, + &((PIMAGE_NT_HEADERS64)NtHeaders)->OptionalHeader. + AddressOfEntryPoint, + &EntrypointRva, + sizeof(EntrypointRva), + NULL); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + pContext->Rcx = BaseAddress + EntrypointRva; + + return STATUS_SUCCESS; +} \ No newline at end of file diff --git a/dll/wow64/entrypoint.h b/dll/wow64/entrypoint.h new file mode 100644 index 0000000000000..bc5af94748cb8 --- /dev/null +++ b/dll/wow64/entrypoint.h @@ -0,0 +1,16 @@ +#pragma once + +#include "ros_wow64_private.h" + +NTSTATUS +Wow64InitEntrypointTranslation(VOID); + +NTSTATUS +Wow64TranslateEntrypoint32To64(IN HANDLE hProcess, + OUT PCONTEXT pContext, + IN PI386_CONTEXT pContext32); + +NTSTATUS +Wow64TranslateEntrypoint64To32(IN HANDLE hProcess, + OUT PI386_CONTEXT pContext32, + IN PCONTEXT pContext); \ No newline at end of file diff --git a/dll/wow64/exception.S b/dll/wow64/exception.S new file mode 100644 index 0000000000000..6e6524544f40d --- /dev/null +++ b/dll/wow64/exception.S @@ -0,0 +1,4 @@ +.code + + +END \ No newline at end of file diff --git a/dll/wow64/exception.c b/dll/wow64/exception.c new file mode 100644 index 0000000000000..562c34ec914c1 --- /dev/null +++ b/dll/wow64/exception.c @@ -0,0 +1,98 @@ +/* + * Wine WOW64 ReactOS port + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: wow64.dll + * FILE: dll/wow64/exception.c + * PROGRAMMER: Marcin Jabłoński + */ + +#include "ros_wow64_private.h" + +LONG +Wow64UnhandledExceptionHandler(IN PEXCEPTION_POINTERS ExceptionInfo); + +BOOLEAN +Wow64PassExceptionToGuest(IN PCONTEXT Context, + IN PEXCEPTION_RECORD ExceptionRecord) +{ + EXCEPTION_POINTERS exceptionInfo; + + exceptionInfo.ContextRecord = Context; + exceptionInfo.ExceptionRecord = ExceptionRecord; + + Wow64UnhandledExceptionHandler(&exceptionInfo); + + ASSERT(FALSE); + return FALSE; +} + +NTSTATUS +WINAPI +wow64_NtRaiseException(UINT* pArgs) +{ + PEXCEPTION_RECORD32 pRecord32 = get_ptr(&pArgs); + PI386_CONTEXT pContext32 = get_ptr(&pArgs); + BOOLEAN FirstChance = get_ulong(&pArgs); + + __debugbreak(); + + EXCEPTION_RECORD Record; + CONTEXT Context; + + Record.ExceptionCode = pRecord32->ExceptionCode; + Record.ExceptionFlags = pRecord32->ExceptionFlags; + Record.ExceptionRecord = UlongToPtr(pRecord32->ExceptionRecord); + Record.ExceptionAddress = UlongToPtr(pRecord32->ExceptionAddress); + Record.NumberParameters = pRecord32->NumberParameters; + + Wow64CopyContext32To64(&Context, pContext32); + + for (int i = 0; i < EXCEPTION_MAXIMUM_PARAMETERS; i++) + { + Record.ExceptionInformation[i] = pRecord32->ExceptionInformation[i]; + } + + if (FirstChance == FALSE) + { + DPRINT1("Unhandled 32-bit exception in a WOW64 process.\n"); + __debugbreak(); + } + + return NtRaiseException(&Record, &Context, FirstChance); +} + +LONG +Wow64UnhandledExceptionHandler(IN PEXCEPTION_POINTERS ExceptionInfo) +{ + ULONG i; + EXCEPTION_RECORD32 Record32; + I386_CONTEXT Context32; + PCONTEXT pContext; + PEXCEPTION_RECORD pRecord; + + ULONG DispatcherArgs[2]; + + pRecord = ExceptionInfo->ExceptionRecord; + pContext = ExceptionInfo->ContextRecord; + + Record32.ExceptionCode = pRecord->ExceptionCode; + Record32.ExceptionFlags = pRecord->ExceptionFlags; + Record32.ExceptionRecord = PtrToUlong(pRecord->ExceptionRecord); + Record32.ExceptionAddress = PtrToUlong(pRecord->ExceptionAddress); + Record32.NumberParameters = pRecord->NumberParameters; + + for (i = 0; i < Record32.NumberParameters; i++) + { + Record32.ExceptionInformation[i] = pRecord->ExceptionInformation[i]; + } + + Wow64CopyContext64To32(&Context32, pContext); + + DispatcherArgs[0] = PtrToUlong(&Record32); + DispatcherArgs[1] = PtrToUlong(&Context32); + + Jump32(PtrToUlong(NtDll32KiUserExceptionDispatcher), 2, DispatcherArgs); + + return EXCEPTION_EXECUTE_HANDLER; +} \ No newline at end of file diff --git a/dll/wow64/ros_wow64_private.h b/dll/wow64/ros_wow64_private.h new file mode 100644 index 0000000000000..43cbc9bf9aa30 --- /dev/null +++ b/dll/wow64/ros_wow64_private.h @@ -0,0 +1,674 @@ +/* + * WoW64 private definitions + * + * Copyright 2021 Alexandre Julliard + * Copyright 2025 Marcin Jabłoński + * + * 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 + */ + +#pragma once + +/* FIXME: for now, the WOW64 directory path is hardcoded. */ +#define TMP_WOW_DIR L"D:" + +#define WIN32_NO_STATUS +#include +#include +#include +#include +#include "wine/struct32.h" + +#include + +#define WOW64_TLS_CPURESERVED 1 +#define WOW64_TLS_TEMPLIST 3 +#define WOW64_TLS_USERCALLBACKDATA 5 +#define WOW64_TLS_APCLIST 7 +#define WOW64_TLS_FILESYSREDIR 8 +#define WOW64_TLS_WOW64INFO 10 +#define WOW64_TLS_MAX_NUMBER 19 + +/* FIXME: Whatever Wine uses treats %u as something else than DPRINT1. + * Don't print, so this doesn't crash (this shouldn't crash either way, but for + * some reason, SEH fails to RtlUnwindEx: investigate) */ +// #define FIXME(...) do { DPRINT1(__VA_ARGS__); __debugbreak(); } while(0); +#define FIXME(...) do { __debugbreak(); (void)(__VA_ARGS__); } while(0); + +static inline ULONG get_ulong( UINT **args ) { return *(*args)++; } +static inline HANDLE get_handle( UINT **args ) { return UlongToHandle( *(*args)++ ); } +static inline void *get_ptr( UINT **args ) { return ULongToPtr( *(*args)++ ); } + +extern ULONG_PTR highest_user_address; +extern ULONG_PTR default_zero_bits; + +extern PVOID NtDll32LdrpRoutine; +extern PVOID NtDll32KiUserExceptionDispatcher; + +static ULONG_PTR args_alignment = 4; +static USHORT current_machine = IMAGE_FILE_MACHINE_I386; +static USHORT native_machine = IMAGE_FILE_MACHINE_AMD64; + +#define WINE_WOW_IMPL_CASE(name) case Num ## name: {\ + NTSTATUS WINAPI wow64_Nt ## name (UINT* pArgs); \ + status = wow64_Nt ## name (pArgs); \ + break; } + +unsigned long __readfsdword(unsigned long); + +#pragma section(".text") + +__declspec(allocate(".text")) +static unsigned char FarReturn64Impl[] = +{ + 0x48, /* REX.W */ + 0xCB /* retf*/ +}; + +__declspec(allocate(".text")) +static unsigned char FarReturn32Impl[] = +{ + 0xCB /* retf */ +}; + +__declspec(allocate(".text")) +static unsigned char Enter32Impl[] = +{ + 0x48, 0x89, 0xCC, /* mov rsp, rcx */ + 0x48, /* REX.W */ + 0xCB /* retf*/ +}; + +NTSTATUS +WINAPI +Wow64KiUserCallbackDispatcher(ULONG nCallback, + PVOID IN pArgs, + ULONG nArgLen, + PVOID* OUT ppReturn, + PULONG OUT pnRetLen); + +/* header for Wow64AllocTemp blocks; probably not the right layout */ +struct mem_header +{ + struct mem_header *next; + void *__pad; + BYTE data[1]; +}; + +PVOID +WINAPI +Wow64AllocateTemp(SIZE_T size); + +VOID +Wow64FreeTempData(VOID); + +/* TODO: Refactor, all of this could be done in a cleaner way */ +static +ULONG_PTR +CallOrJump32(ULONG Address, ULONG nArgc, PULONG Args, BOOL bJump) +{ +#define MAX_ARGS 32 +#pragma pack(push, 1) + struct Enter32 + { + ULONG_PTR Rip32; + ULONG_PTR SegCs32; + ULONG FarReturn32; + ULONG Arguments[0]; + }; + + struct Leave32 + { + ULONG Rip64; + ULONG SegCs64; + }; + + typedef ULONG_PTR(*Enter32ImplType)(struct Enter32* enter); + + Enter32ImplType pfnEnter32 = (Enter32ImplType)Enter32Impl; + struct Leave32* leave; + struct Enter32* enter; + + /* Skip the return address for jumps */ + nArgc -= bJump; + + BYTE StackBuffer[sizeof(struct Enter32) + sizeof(struct Leave32) + MAX_ARGS * sizeof(ULONG)]; + + leave = (struct Leave32*)(StackBuffer + sizeof(StackBuffer) - sizeof(*leave)); + enter = (struct Enter32*)(StackBuffer + sizeof(StackBuffer) - sizeof(*leave) + - sizeof(*enter) - sizeof(ULONG) * nArgc); +#pragma pack(pop) + + ASSERT(nArgc <= MAX_ARGS); + + if (!bJump) + { + enter->FarReturn32 = PtrToUlong(FarReturn32Impl); + } + + for (int i = 0; i < nArgc + bJump; i++) + { + (enter->Arguments - bJump)[i] = Args[i]; + } + + enter->Rip32 = (ULONG_PTR) Address; + enter->SegCs32 = 0x23; + + leave->Rip64 = PtrToUlong(_ReturnAddress()); + leave->SegCs64 = 0x33; + + pfnEnter32(enter); + + /* We should never get here. */ + ASSERT(FALSE); + return 0; +#undef MAX_ARGS +} + +static inline Call32(ULONG Addr, ULONG nArgc, PULONG Args) +{ + return CallOrJump32(Addr, nArgc, Args, FALSE); +} + +static inline Jump32(ULONG Addr, ULONG nArgc, PULONG Args) +{ + return CallOrJump32(Addr, nArgc, Args, TRUE); +} + +static inline PTEB32 NtCurrentTeb32() +{ + return (PTEB32)(ULONG_PTR)__readfsdword(0x18); +} + +static inline PPEB32 NtCurrentPeb32() +{ + return (PPEB32)UlongToPtr(NtCurrentTeb32()->ProcessEnvironmentBlock); +} + +struct object_attr64 +{ + OBJECT_ATTRIBUTES attr; + UNICODE_STRING str; + SECURITY_DESCRIPTOR sd; +}; + +struct user_callback_frame +{ + struct user_callback_frame *prev_frame; + struct mem_header *temp_list; + void **ret_ptr; + ULONG *ret_len; + NTSTATUS status; + jmp_buf jmpbuf; +}; + +typedef struct user_callback_frame USER_CALLBACK_FRAME, *PUSER_CALLBACK_FRAME; +typedef OBJECT_ATTRIBUTES32 *POBJECT_ATTRIBUTES32; + +typedef struct tagSYSTEM_SERVICE_TABLE +{ + ULONG_PTR *ServiceTable; + ULONG_PTR *CounterTable; + ULONG_PTR ServiceLimit; + BYTE *ArgumentTable; +} SYSTEM_SERVICE_TABLE, *PSYSTEM_SERVICE_TABLE; + +typedef struct _I386_FLOATING_SAVE_AREA +{ + DWORD ControlWord; + DWORD StatusWord; + DWORD TagWord; + DWORD ErrorOffset; + DWORD ErrorSelector; + DWORD DataOffset; + DWORD DataSelector; + BYTE RegisterArea[80]; + DWORD Cr0NpxState; +} I386_FLOATING_SAVE_AREA, *PI386_FLOATING_SAVE_AREA; + +#include "pshpack4.h" +typedef struct _I386_CONTEXT +{ + ULONG ContextFlags; + ULONG Dr0; + ULONG Dr1; + ULONG Dr2; + ULONG Dr3; + ULONG Dr6; + ULONG Dr7; + I386_FLOATING_SAVE_AREA FloatSave; + ULONG SegGs; + ULONG SegFs; + ULONG SegEs; + ULONG SegDs; + ULONG Edi; + ULONG Esi; + ULONG Ebx; + ULONG Edx; + ULONG Ecx; + ULONG Eax; + ULONG Ebp; + ULONG Eip; + ULONG SegCs; + ULONG EFlags; + ULONG Esp; + ULONG SegSs; + UCHAR ExtendedRegisters[512]; +} I386_CONTEXT, *PI386_CONTEXT; +C_ASSERT(sizeof(I386_CONTEXT) == 716); +#include "poppack.h" + +typedef struct _WOW64_PATH_REDIRECTION +{ + UNICODE_STRING From; + UNICODE_STRING To; +} WOW64_PATH_REDIRECTION, *PWOW64_PATH_REDIRECTION; + +static +BOOLEAN +RedirectPath(const WOW64_PATH_REDIRECTION* Redirection, + POBJECT_ATTRIBUTES ObjectAttributes) +{ + PUNICODE_STRING ObjectName = ObjectAttributes->ObjectName; + const UNICODE_STRING* FromUnexpanded = &Redirection->From; + const UNICODE_STRING* ToUnexpanded = &Redirection->To; + + NTSTATUS Status; + + UNICODE_STRING From, To; + WCHAR FromBuffer[MAX_PATH] = { 0 }; + WCHAR ToBuffer[MAX_PATH] = { 0 }; + + PUNICODE_STRING Buffer = NULL; + USHORT NewLength; + + RtlInitEmptyUnicodeString(&To, ToBuffer, sizeof(ToBuffer)); + Status = RtlExpandEnvironmentStrings_U(NULL, + (PUNICODE_STRING)ToUnexpanded, + &To, + NULL); + ASSERT(NT_SUCCESS(Status)); + + RtlInitEmptyUnicodeString(&From, FromBuffer, sizeof(FromBuffer)); + Status = RtlExpandEnvironmentStrings_U(NULL, + (PUNICODE_STRING)FromUnexpanded, + &From, + NULL); + ASSERT(NT_SUCCESS(Status)); + + NewLength = ObjectName->Length - From.Length + To.Length; + + Buffer = Wow64AllocateTemp(sizeof(*Buffer) + NewLength); + ASSERT(Buffer != NULL); + + Buffer->Buffer = (PWCHAR)(((ULONG_PTR)Buffer) + sizeof(*Buffer)); + + if (_wcsnicmp(ObjectName->Buffer, From.Buffer, From.Length / sizeof(WCHAR)) == 0) + { + Buffer->Length = NewLength; + + RtlCopyMemory(Buffer->Buffer, To.Buffer, To.Length); + + RtlCopyMemory(Buffer->Buffer + To.Length / sizeof(WCHAR), + ObjectName->Buffer + From.Length / sizeof(WCHAR), + ObjectName->Length - From.Length); + + ObjectAttributes->ObjectName = Buffer; + return TRUE; + } + return FALSE; +} + +static BOOLEAN GetFileRedirect(OBJECT_ATTRIBUTES* attr) +{ + if (PtrToUlong(NtCurrentTeb()->TlsSlots[WOW64_TLS_FILESYSREDIR]) == 0) + { + return FALSE; + } + + static const WOW64_PATH_REDIRECTION Redirections[] = + { + /* TODO: system directory shouldn't be hardcoded here */ +#define REDIRECTION(From, To) { RTL_CONSTANT_STRING(From), RTL_CONSTANT_STRING(To) } +#ifdef TMP_WOW_DIR + REDIRECTION(L"\\??\\%SystemRoot%\\system32", L"\\??\\" TMP_WOW_DIR), +#else + REDIRECTION(L"\\??\\%SystemRoot%\\system32", L"\\??\\%SystemRoot%\\SysWOW64"), +#endif + REDIRECTION(L"\\KnownDlls", L"\\KnownDlls32") +#undef REDIRECTION + }; + + size_t i; + PUNICODE_STRING ObjectName = attr->ObjectName; + + if (!attr || !ObjectName || !ObjectName->Buffer) + { + return FALSE; + } + + for (i = 0; i < sizeof(Redirections) / sizeof(*Redirections); i++) + { + if (RedirectPath(&Redirections[i], attr)) + { + return TRUE; + } + } + + return FALSE; +} + +typedef struct _THREAD_BASIC_INFORMATION32 +{ + LONG ExitStatus; + ULONG TebBaseAddress; + CLIENT_ID32 ClientId; + ULONG AffinityMask; + LONG Priority; + LONG BasePriority; +} THREAD_BASIC_INFORMATION32, *PTHREAD_BASIC_INFORMATION32; + +typedef struct _INITIAL_TEB32 +{ + ULONG PreviousStackBase; + ULONG PreviousStackLimit; + ULONG StackBase; + ULONG StackLimit; + ULONG AllocatedStackBase; +} INITIAL_TEB32, *PINITIAL_TEB32; + +typedef IO_STATUS_BLOCK32 *PIO_STATUS_BLOCK32; + +static inline void * +apc_32to64(ULONG func) +{ + /* UNIMPLEMENTED */ + if (func) + { + DPRINT1("Warning: WOW64 APCs are unimplemented\n"); + } + + return NULL; +} + +static inline void * +apc_param_32to64(ULONG func, ULONG context) +{ + if (!func) + return ULongToPtr(context); + return (void *)(ULONG_PTR)(((ULONG64)func << 32) | context); +} + +static inline IO_STATUS_BLOCK *iosb_32to64( IO_STATUS_BLOCK *io, IO_STATUS_BLOCK32 *io32 ) +{ + if (!io32) return NULL; + io->Pointer = io32; + return io; +} + +static inline void put_iosb( IO_STATUS_BLOCK32 *io32, const IO_STATUS_BLOCK *io ) +{ + +} + +static BOOL is_process_wow64( HANDLE handle ) +{ + ULONG_PTR info; + + if (handle == NtCurrentProcess()) return TRUE; + if (NtQueryInformationProcess( handle, ProcessWow64Information, &info, sizeof(info), NULL )) + return FALSE; + return !!info; +} + +static inline ULONG_PTR get_zero_bits( ULONG_PTR zero_bits ) +{ + return zero_bits ? zero_bits : default_zero_bits; +} + +static inline ULONG64 get_ulong64( UINT **args ) +{ + ULONG64 ret; + + *args = (UINT *)(((ULONG_PTR)*args + args_alignment - 1) & ~(args_alignment - 1)); + ret = *(ULONG64 *)*args; + *args += 2; + return ret; +} + +static inline void **addr_32to64( void **addr, ULONG *addr32 ) +{ + if (!addr32) return NULL; + *addr = ULongToPtr( *addr32 ); + return addr; +} + +static inline SIZE_T *size_32to64( SIZE_T *size, ULONG *size32 ) +{ + if (!size32) return NULL; + *size = *size32; + return size; +} + +static inline UNICODE_STRING *unicode_str_32to64( UNICODE_STRING *str, const UNICODE_STRING32 *str32 ) +{ + if (!str32) return NULL; + str->Length = str32->Length; + str->MaximumLength = str32->MaximumLength; + str->Buffer = ULongToPtr( str32->Buffer ); + return str; +} + +static inline CLIENT_ID *client_id_32to64( CLIENT_ID *id, const CLIENT_ID32 *id32 ) +{ + if (!id32) return NULL; + id->UniqueProcess = LongToHandle( id32->UniqueProcess ); + id->UniqueThread = LongToHandle( id32->UniqueThread ); + return id; +} + +static inline SECURITY_DESCRIPTOR *secdesc_32to64( SECURITY_DESCRIPTOR *out, const SECURITY_DESCRIPTOR *in ) +{ + /* relative descr has the same layout for 32 and 64 */ + const SECURITY_DESCRIPTOR_RELATIVE *sd = (const SECURITY_DESCRIPTOR_RELATIVE *)in; + + if (!in) return NULL; + out->Revision = sd->Revision; + out->Sbz1 = sd->Sbz1; + out->Control = sd->Control & ~SE_SELF_RELATIVE; + if (sd->Control & SE_SELF_RELATIVE) + { + out->Owner = sd->Owner ? (PSID)((BYTE *)sd + sd->Owner) : NULL; + out->Group = sd->Group ? (PSID)((BYTE *)sd + sd->Group) : NULL; + out->Sacl = ((sd->Control & SE_SACL_PRESENT) && sd->Sacl) ? (PSID)((BYTE *)sd + sd->Sacl) : NULL; + out->Dacl = ((sd->Control & SE_DACL_PRESENT) && sd->Dacl) ? (PSID)((BYTE *)sd + sd->Dacl) : NULL; + } + else + { + out->Owner = ULongToPtr( sd->Owner ); + out->Group = ULongToPtr( sd->Group ); + out->Sacl = (sd->Control & SE_SACL_PRESENT) ? ULongToPtr( sd->Sacl ) : NULL; + out->Dacl = (sd->Control & SE_DACL_PRESENT) ? ULongToPtr( sd->Dacl ) : NULL; + } + return out; +} + +static inline OBJECT_ATTRIBUTES *objattr_32to64( struct object_attr64 *out, const OBJECT_ATTRIBUTES32 *in ) +{ + memset( out, 0, sizeof(*out) ); + if (!in) return NULL; + if (in->Length != sizeof(*in)) return &out->attr; + + out->attr.Length = sizeof(out->attr); + out->attr.RootDirectory = LongToHandle( in->RootDirectory ); + out->attr.Attributes = in->Attributes; + out->attr.ObjectName = unicode_str_32to64( &out->str, ULongToPtr( in->ObjectName )); + out->attr.SecurityQualityOfService = ULongToPtr( in->SecurityQualityOfService ); + out->attr.SecurityDescriptor = secdesc_32to64( &out->sd, ULongToPtr( in->SecurityDescriptor )); + return &out->attr; +} + +static inline OBJECT_ATTRIBUTES* +RosWow64RedirObjAttributes(struct object_attr64 *out, + const OBJECT_ATTRIBUTES32 *in) +{ + OBJECT_ATTRIBUTES *attr = objattr_32to64(out, in); + + if (attr) + { + GetFileRedirect(attr); + } + return attr; +} + +#define objattr_32to64_redirect(out, in) RosWow64RedirObjAttributes(out, in) + +#define FIXME_DECLARE_TMP_BUF1 \ + WCHAR tmpBuf[MAX_PATH]; \ + UNICODE_STRING tmpStr;\ + tmpStr.Buffer = tmpBuf;\ + tmpStr.Length = 0;\ + tmpStr.MaximumLength = sizeof(tmpBuf)\ + +static inline TOKEN_USER *token_user_32to64( TOKEN_USER *out, const TOKEN_USER32 *in ) +{ + out->User.Sid = ULongToPtr( in->User.Sid ); + out->User.Attributes = in->User.Attributes; + return out; +} + +static inline TOKEN_OWNER *token_owner_32to64( TOKEN_OWNER *out, const TOKEN_OWNER32 *in ) +{ + out->Owner = ULongToPtr( in->Owner ); + return out; +} + +static inline TOKEN_PRIMARY_GROUP *token_primary_group_32to64( TOKEN_PRIMARY_GROUP *out, const TOKEN_PRIMARY_GROUP32 *in ) +{ + out->PrimaryGroup = ULongToPtr( in->PrimaryGroup ); + return out; +} + +static inline TOKEN_DEFAULT_DACL *token_default_dacl_32to64( TOKEN_DEFAULT_DACL *out, const TOKEN_DEFAULT_DACL32 *in ) +{ + out->DefaultDacl = ULongToPtr( in->DefaultDacl ); + return out; +} + +static inline void put_handle( ULONG *handle32, HANDLE handle ) +{ + *handle32 = HandleToULong( handle ); +} + +static inline void put_addr( ULONG *addr32, void *addr ) +{ + if (addr != (PVOID)(ULONG_PTR)PtrToUlong(addr)) + __debugbreak(); + if (addr32) *addr32 = PtrToUlong( addr ); +} + +static inline void put_size( ULONG *size32, SIZE_T size ) +{ + if (size32) *size32 = min( size, MAXDWORD ); +} + +static inline void put_client_id( CLIENT_ID32 *id32, const CLIENT_ID *id ) +{ + if (!id32) return; + id32->UniqueProcess = HandleToLong( id->UniqueProcess ); + id32->UniqueThread = HandleToLong( id->UniqueThread ); +} + +extern void put_section_image_info( SECTION_IMAGE_INFORMATION32 *info32, + const SECTION_IMAGE_INFORMATION *info ); + +static void put_vm_counters( VM_COUNTERS_EX32 *info32, const VM_COUNTERS_EX *info, + ULONG size ) +{ + info32->PeakVirtualSize = info->PeakVirtualSize; + info32->VirtualSize = info->VirtualSize; + info32->PageFaultCount = info->PageFaultCount; + info32->PeakWorkingSetSize = info->PeakWorkingSetSize; + info32->WorkingSetSize = info->WorkingSetSize; + info32->QuotaPeakPagedPoolUsage = info->QuotaPeakPagedPoolUsage; + info32->QuotaPagedPoolUsage = info->QuotaPagedPoolUsage; + info32->QuotaPeakNonPagedPoolUsage = info->QuotaPeakNonPagedPoolUsage; + info32->QuotaNonPagedPoolUsage = info->QuotaNonPagedPoolUsage; + info32->PagefileUsage = info->PagefileUsage; + info32->PeakPagefileUsage = info->PeakPagefileUsage; + if (size == sizeof(VM_COUNTERS_EX32)) info32->PrivateUsage = info->PrivateUsage; +} + +static +PPORT_VIEW +PortView32To64(PPORT_VIEW portView64, + PPORT_VIEW32 portView32) +{ + portView64->Length = sizeof(*portView64); + portView64->SectionHandle = UlongToHandle(portView32->SectionHandle); + portView64->SectionOffset = portView32->SectionOffset; + portView64->ViewSize = portView32->ViewSize; + portView64->ViewBase = UlongToPtr(portView32->ViewBase); + portView64->ViewRemoteBase = UlongToPtr(portView32->ViewRemoteBase); + + return portView64; +} + +static +PREMOTE_PORT_VIEW +RemotePortView32To64(PREMOTE_PORT_VIEW portView64, + PREMOTE_PORT_VIEW32 portView32) +{ + portView64->Length = sizeof(*portView64); + portView64->ViewSize = portView32->ViewSize; + portView64->ViewBase = UlongToPtr(portView32->ViewBase); + + return portView64; +} + +static +PPORT_VIEW32 +PortView64To32(PPORT_VIEW32 portView32, + PPORT_VIEW portView64) +{ + portView32->Length = sizeof(*portView32); + portView32->SectionHandle = HandleToULong(portView64->SectionHandle); + portView32->SectionOffset = portView64->SectionOffset; + portView32->ViewSize = portView64->ViewSize; + portView32->ViewBase = PtrToUlong(portView64->ViewBase); + portView32->ViewRemoteBase = PtrToUlong(portView64->ViewRemoteBase); + + return portView32; +} + +static +PREMOTE_PORT_VIEW32 +RemotePortView64To32(PREMOTE_PORT_VIEW32 portView32, + PREMOTE_PORT_VIEW portView64) +{ + portView32->Length = sizeof(*portView32); + portView32->ViewSize = portView64->ViewSize; + portView32->ViewBase = PtrToUlong(portView64->ViewBase); + + return portView32; +} + +VOID +Wow64CopyContext32To64(PCONTEXT pContext, + PI386_CONTEXT pContext32); + +VOID +Wow64CopyContext64To32(PI386_CONTEXT pContext32, + PCONTEXT pContext); \ No newline at end of file diff --git a/dll/wow64/srasm.S b/dll/wow64/srasm.S new file mode 100644 index 0000000000000..f987948d6de8b --- /dev/null +++ b/dll/wow64/srasm.S @@ -0,0 +1,50 @@ +.code + +PUBLIC __readfsdword +__readfsdword: + mov eax, fs:[rcx] + ret + +PUBLIC EnterApc32 +EnterApc32: + push r12 + mov r12, rsp + + sub rsp, rdx + + push rdi + push rsi + + mov rsi, rcx + mov rcx, rdx + lea rdi, [rsp + 16] + cld + rep movsb + + pop rsi + pop rdi + + lea rcx, [return32] + mov [rsp + 16], rcx + + db 48h + retf +return32: + call l +l: + pop rax + add eax, return64 - l + push 33h + push rax + retf +return64: + mov rsp, r12 + pop r12 + ret + +PUBLIC SetupFs +SetupFs: + mov fs, rcx + ret + +END \ No newline at end of file diff --git a/dll/wow64/sysfuncnum.h b/dll/wow64/sysfuncnum.h new file mode 100644 index 0000000000000..798794b9d074b --- /dev/null +++ b/dll/wow64/sysfuncnum.h @@ -0,0 +1,300 @@ +#pragma once +#define NumAcceptConnectPort 0 +#define NumAccessCheck 1 +#define NumAccessCheckAndAuditAlarm 2 +#define NumAccessCheckByType 3 +#define NumAccessCheckByTypeAndAuditAlarm 4 +#define NumAccessCheckByTypeResultList 5 +#define NumAccessCheckByTypeResultListAndAuditAlarm 6 +#define NumAccessCheckByTypeResultListAndAuditAlarmByHandle 7 +#define NumAddAtom 8 +#define NumAddBootEntry 9 +#define NumAddDriverEntry 10 +#define NumAdjustGroupsToken 11 +#define NumAdjustPrivilegesToken 12 +#define NumAlertResumeThread 13 +#define NumAlertThread 14 +#define NumAllocateLocallyUniqueId 15 +#define NumAllocateUserPhysicalPages 16 +#define NumAllocateUuids 17 +#define NumAllocateVirtualMemory 18 +#define NumApphelpCacheControl 19 +#define NumAreMappedFilesTheSame 20 +#define NumAssignProcessToJobObject 21 +#define NumCallbackReturn 22 +#define NumCancelDeviceWakeupRequest 23 +#define NumCancelIoFile 24 +#define NumCancelTimer 25 +#define NumClearEvent 26 +#define NumClose 27 +#define NumCloseObjectAuditAlarm 28 +#define NumCompactKeys 29 +#define NumCompareTokens 30 +#define NumCompleteConnectPort 31 +#define NumCompressKey 32 +#define NumConnectPort 33 +#define NumContinue 34 +#define NumCreateDebugObject 35 +#define NumCreateDirectoryObject 36 +#define NumCreateEvent 37 +#define NumCreateEventPair 38 +#define NumCreateFile 39 +#define NumCreateIoCompletion 40 +#define NumCreateJobObject 41 +#define NumCreateJobSet 42 +#define NumCreateKey 43 +#define NumCreateMailslotFile 44 +#define NumCreateMutant 45 +#define NumCreateNamedPipeFile 46 +#define NumCreatePagingFile 47 +#define NumCreatePort 48 +#define NumCreateProcess 49 +#define NumCreateProcessEx 50 +#define NumCreateProfile 51 +#define NumCreateSection 52 +#define NumCreateSemaphore 53 +#define NumCreateSymbolicLinkObject 54 +#define NumCreateThread 55 +#define NumCreateTimer 56 +#define NumCreateToken 57 +#define NumCreateWaitablePort 58 +#define NumDebugActiveProcess 59 +#define NumDebugContinue 60 +#define NumDelayExecution 61 +#define NumDeleteAtom 62 +#define NumDeleteBootEntry 63 +#define NumDeleteDriverEntry 64 +#define NumDeleteFile 65 +#define NumDeleteKey 66 +#define NumDeleteObjectAuditAlarm 67 +#define NumDeleteValueKey 68 +#define NumDeviceIoControlFile 69 +#define NumDisplayString 70 +#define NumDuplicateObject 71 +#define NumDuplicateToken 72 +#define NumEnumerateBootEntries 73 +#define NumEnumerateDriverEntries 74 +#define NumEnumerateKey 75 +#define NumEnumerateSystemEnvironmentValuesEx 76 +#define NumEnumerateValueKey 77 +#define NumExtendSection 78 +#define NumFilterToken 79 +#define NumFindAtom 80 +#define NumFlushBuffersFile 81 +#define NumFlushInstructionCache 82 +#define NumFlushKey 83 +#define NumFlushVirtualMemory 84 +#define NumFlushWriteBuffer 85 +#define NumFreeUserPhysicalPages 86 +#define NumFreeVirtualMemory 87 +#define NumFsControlFile 88 +#define NumGetContextThread 89 +#define NumGetDevicePowerState 90 +#define NumGetPlugPlayEvent 91 +#define NumGetWriteWatch 92 +#define NumImpersonateAnonymousToken 93 +#define NumImpersonateClientOfPort 94 +#define NumImpersonateThread 95 +#define NumInitializeRegistry 96 +#define NumInitiatePowerAction 97 +#define NumIsProcessInJob 98 +#define NumIsSystemResumeAutomatic 99 +#define NumListenPort 100 +#define NumLoadDriver 101 +#define NumLoadKey 102 +#define NumLoadKey2 103 +#define NumLoadKeyEx 104 +#define NumLockFile 105 +#define NumLockProductActivationKeys 106 +#define NumLockRegistryKey 107 +#define NumLockVirtualMemory 108 +#define NumMakePermanentObject 109 +#define NumMakeTemporaryObject 110 +#define NumMapUserPhysicalPages 111 +#define NumMapUserPhysicalPagesScatter 112 +#define NumMapViewOfSection 113 +#define NumModifyBootEntry 114 +#define NumModifyDriverEntry 115 +#define NumNotifyChangeDirectoryFile 116 +#define NumNotifyChangeKey 117 +#define NumNotifyChangeMultipleKeys 118 +#define NumOpenDirectoryObject 119 +#define NumOpenEvent 120 +#define NumOpenEventPair 121 +#define NumOpenFile 122 +#define NumOpenIoCompletion 123 +#define NumOpenJobObject 124 +#define NumOpenKey 125 +#define NumOpenMutant 126 +#define NumOpenObjectAuditAlarm 127 +#define NumOpenProcess 128 +#define NumOpenProcessToken 129 +#define NumOpenProcessTokenEx 130 +#define NumOpenSection 131 +#define NumOpenSemaphore 132 +#define NumOpenSymbolicLinkObject 133 +#define NumOpenThread 134 +#define NumOpenThreadToken 135 +#define NumOpenThreadTokenEx 136 +#define NumOpenTimer 137 +#define NumPlugPlayControl 138 +#define NumPowerInformation 139 +#define NumPrivilegeCheck 140 +#define NumPrivilegeObjectAuditAlarm 141 +#define NumPrivilegedServiceAuditAlarm 142 +#define NumProtectVirtualMemory 143 +#define NumPulseEvent 144 +#define NumQueryAttributesFile 145 +#define NumQueryBootEntryOrder 146 +#define NumQueryBootOptions 147 +#define NumQueryDebugFilterState 148 +#define NumQueryDefaultLocale 149 +#define NumQueryDefaultUILanguage 150 +#define NumQueryDirectoryFile 151 +#define NumQueryDirectoryObject 152 +#define NumQueryDriverEntryOrder 153 +#define NumQueryEaFile 154 +#define NumQueryEvent 155 +#define NumQueryFullAttributesFile 156 +#define NumQueryInformationAtom 157 +#define NumQueryInformationFile 158 +#define NumQueryInformationJobObject 159 +#define NumQueryInformationPort 160 +#define NumQueryInformationProcess 161 +#define NumQueryInformationThread 162 +#define NumQueryInformationToken 163 +#define NumQueryInstallUILanguage 164 +#define NumQueryIntervalProfile 165 +#define NumQueryIoCompletion 166 +#define NumQueryKey 167 +#define NumQueryMultipleValueKey 168 +#define NumQueryMutant 169 +#define NumQueryObject 170 +#define NumQueryOpenSubKeys 171 +#define NumQueryOpenSubKeysEx 172 +#define NumQueryPerformanceCounter 173 +#define NumQueryQuotaInformationFile 174 +#define NumQuerySection 175 +#define NumQuerySecurityObject 176 +#define NumQuerySemaphore 177 +#define NumQuerySymbolicLinkObject 178 +#define NumQuerySystemEnvironmentValue 179 +#define NumQuerySystemEnvironmentValueEx 180 +#define NumQuerySystemInformation 181 +#define NumQuerySystemTime 182 +#define NumQueryTimer 183 +#define NumQueryTimerResolution 184 +#define NumQueryValueKey 185 +#define NumQueryVirtualMemory 186 +#define NumQueryVolumeInformationFile 187 +#define NumQueueApcThread 188 +#define NumRaiseException 189 +#define NumRaiseHardError 190 +#define NumReadFile 191 +#define NumReadFileScatter 192 +#define NumReadRequestData 193 +#define NumReadVirtualMemory 194 +#define NumRegisterThreadTerminatePort 195 +#define NumReleaseMutant 196 +#define NumReleaseSemaphore 197 +#define NumRemoveIoCompletion 198 +#define NumRemoveProcessDebug 199 +#define NumRenameKey 200 +#define NumReplaceKey 201 +#define NumReplyPort 202 +#define NumReplyWaitReceivePort 203 +#define NumReplyWaitReceivePortEx 204 +#define NumReplyWaitReplyPort 205 +#define NumRequestDeviceWakeup 206 +#define NumRequestPort 207 +#define NumRequestWaitReplyPort 208 +#define NumRequestWakeupLatency 209 +#define NumResetEvent 210 +#define NumResetWriteWatch 211 +#define NumRestoreKey 212 +#define NumResumeProcess 213 +#define NumResumeThread 214 +#define NumSaveKey 215 +#define NumSaveKeyEx 216 +#define NumSaveMergedKeys 217 +#define NumSecureConnectPort 218 +#define NumSetBootEntryOrder 219 +#define NumSetBootOptions 220 +#define NumSetContextThread 221 +#define NumSetDebugFilterState 222 +#define NumSetDefaultHardErrorPort 223 +#define NumSetDefaultLocale 224 +#define NumSetDefaultUILanguage 225 +#define NumSetDriverEntryOrder 226 +#define NumSetEaFile 227 +#define NumSetEvent 228 +#define NumSetEventBoostPriority 229 +#define NumSetHighEventPair 230 +#define NumSetHighWaitLowEventPair 231 +#define NumSetInformationDebugObject 232 +#define NumSetInformationFile 233 +#define NumSetInformationJobObject 234 +#define NumSetInformationKey 235 +#define NumSetInformationObject 236 +#define NumSetInformationProcess 237 +#define NumSetInformationThread 238 +#define NumSetInformationToken 239 +#define NumSetIntervalProfile 240 +#define NumSetIoCompletion 241 +#define NumSetLdtEntries 242 +#define NumSetLowEventPair 243 +#define NumSetLowWaitHighEventPair 244 +#define NumSetQuotaInformationFile 245 +#define NumSetSecurityObject 246 +#define NumSetSystemEnvironmentValue 247 +#define NumSetSystemEnvironmentValueEx 248 +#define NumSetSystemInformation 249 +#define NumSetSystemPowerState 250 +#define NumSetSystemTime 251 +#define NumSetThreadExecutionState 252 +#define NumSetTimer 253 +#define NumSetTimerResolution 254 +#define NumSetUuidSeed 255 +#define NumSetValueKey 256 +#define NumSetVolumeInformationFile 257 +#define NumShutdownSystem 258 +#define NumSignalAndWaitForSingleObject 259 +#define NumStartProfile 260 +#define NumStopProfile 261 +#define NumSuspendProcess 262 +#define NumSuspendThread 263 +#define NumSystemDebugControl 264 +#define NumTerminateJobObject 265 +#define NumTerminateProcess 266 +#define NumTerminateThread 267 +#define NumTestAlert 268 +#define NumTraceEvent 269 +#define NumTranslateFilePath 270 +#define NumUnloadDriver 271 +#define NumUnloadKey 272 +#define NumUnloadKey2 273 +#define NumUnloadKeyEx 274 +#define NumUnlockFile 275 +#define NumUnlockVirtualMemory 276 +#define NumUnmapViewOfSection 277 +#define NumVdmControl 278 +#define NumWaitForDebugEvent 279 +#define NumWaitForMultipleObjects 280 +#define NumWaitForSingleObject 281 +#define NumWaitHighEventPair 282 +#define NumWaitLowEventPair 283 +#define NumWriteFile 284 +#define NumWriteFileGather 285 +#define NumWriteRequestData 286 +#define NumWriteVirtualMemory 287 +#define NumYieldExecution 288 +#define NumCreateKeyedEvent 289 +#define NumOpenKeyedEvent 290 +#define NumReleaseKeyedEvent 291 +#define NumWaitForKeyedEvent 292 +#define NumQueryPortInformationProcess 293 +#define NumGetCurrentProcessorNumber 294 +#define NumWaitForMultipleObjects32 295 +#define NumWow64AllocateVirtualMemory64 296 +#define NumWow64ReadVirtualMemory64 297 +#define NumWow64WriteVirtualMemory64 298 \ No newline at end of file diff --git a/dll/wow64/wine/file.c b/dll/wow64/wine/file.c new file mode 100644 index 0000000000000..868b5bdc4d508 --- /dev/null +++ b/dll/wow64/wine/file.c @@ -0,0 +1,803 @@ +/* + * WoW64 file functions + * + * Copyright 2021 Alexandre Julliard + * Copyright 2025 Marcin Jabłoński + * + * 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 "ros_wow64_private.h" + +/* StatusBlock64->Pointer is cleared by the kernel when doing async IO */ +typedef struct _WOW64_IOSB_STORAGE +{ + IO_STATUS_BLOCK StatusBlock64; + struct _WOW64_IOSB_STORAGE* Next; +} WOW64_IOSB_STORAGE, *PWOW64_IOSB_STORAGE; + +static LONG IosbStorageChainSize = 1; +static WOW64_IOSB_STORAGE IosbStorageHead = { {0, 0}, NULL }; + +static +PIO_STATUS_BLOCK +AppendIosbStorage(PWOW64_IOSB_STORAGE Current, + PIO_STATUS_BLOCK32 StatusBlock32, + PWOW64_IOSB_STORAGE* Result) +{ + LONG Size; + PWOW64_IOSB_STORAGE NewBlock = RtlAllocateHeap(RtlGetProcessHeap(), + 0, + sizeof(*NewBlock)); + + NewBlock->StatusBlock64.Pointer = StatusBlock32; + NewBlock->Next = NULL; + + while (InterlockedCompareExchangePointer(&Current->Next, + NewBlock, + NULL) != NULL) + { + Current = Current->Next; + } + + Size = InterlockedIncrement(&IosbStorageChainSize); + DPRINT1("Appended IOSB Storage %p, chain length: %ld\n", NewBlock, Size); + + *Result = NewBlock; + return &NewBlock->StatusBlock64; +} + +static +PIO_STATUS_BLOCK +AllocIosbStorage(PIO_STATUS_BLOCK32 StatusBlock32, + PWOW64_IOSB_STORAGE* Result) +{ + PWOW64_IOSB_STORAGE Current = &IosbStorageHead; + + while (TRUE) + { + if (InterlockedCompareExchangePointer(&Current->StatusBlock64.Pointer, + StatusBlock32, + NULL) == NULL) + { + *Result = Current; + return &Current->StatusBlock64; + } + + if (Current->Next == NULL) + { + return AppendIosbStorage(Current, StatusBlock32, Result); + } + + Current = Current->Next; + } +} + +static +void +FreeIosbStorage(PWOW64_IOSB_STORAGE Storage, + PIO_STATUS_BLOCK32 StatusBlock32, + NTSTATUS Status) +{ + if (Status != STATUS_PENDING && Storage->StatusBlock64.Pointer != NULL) + { + StatusBlock32->Information = Storage->StatusBlock64.Information; + StatusBlock32->Status = Storage->StatusBlock64.Status; + + Storage->StatusBlock64.Pointer = NULL; + return; + } +} + +/********************************************************************** + * wow64_NtCancelIoFile + */ +NTSTATUS WINAPI wow64_NtCancelIoFile(UINT *args) +{ + HANDLE handle = get_handle(&args); + IO_STATUS_BLOCK32 *io32 = get_ptr(&args); + + PWOW64_IOSB_STORAGE IosbStorage; + NTSTATUS status; + + status = NtCancelIoFile(handle, AllocIosbStorage(io32, &IosbStorage)); + FreeIosbStorage(IosbStorage, io32, status); + + return status; +} + +/********************************************************************** + * wow64_NtCreateFile + */ +NTSTATUS WINAPI wow64_NtCreateFile(UINT *args) +{ + ULONG *handle_ptr = get_ptr(&args); + ACCESS_MASK access = get_ulong(&args); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr(&args); + IO_STATUS_BLOCK32 *io32 = get_ptr(&args); + LARGE_INTEGER *alloc_size = get_ptr(&args); + ULONG attributes = get_ulong(&args); + ULONG sharing = get_ulong(&args); + ULONG disposition = get_ulong(&args); + ULONG options = get_ulong(&args); + void *ea_buffer = get_ptr(&args); + ULONG ea_length = get_ulong(&args); + + struct object_attr64 attr; + PWOW64_IOSB_STORAGE IosbStorage; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtCreateFile(&handle, access, objattr_32to64_redirect(&attr, attr32), + AllocIosbStorage(io32, &IosbStorage), alloc_size, attributes, + sharing, disposition, options, ea_buffer, ea_length); + put_handle(handle_ptr, handle); + FreeIosbStorage(IosbStorage, io32, status); + + return status; +} + + +/********************************************************************** + * wow64_NtCreateMailslotFile + */ +NTSTATUS WINAPI wow64_NtCreateMailslotFile(UINT *args) +{ + ULONG *handle_ptr = get_ptr(&args); + ACCESS_MASK access = get_ulong(&args); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr(&args); + IO_STATUS_BLOCK32 *io32 = get_ptr(&args); + ULONG options = get_ulong(&args); + ULONG quota = get_ulong(&args); + ULONG msg_size = get_ulong(&args); + LARGE_INTEGER *timeout = get_ptr(&args); + + struct object_attr64 attr; + PWOW64_IOSB_STORAGE IosbStorage; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtCreateMailslotFile(&handle, access, objattr_32to64(&attr, attr32), + AllocIosbStorage(io32, &IosbStorage), options, quota, msg_size, timeout); + put_handle(handle_ptr, handle); + FreeIosbStorage(IosbStorage, io32, status); + + return status; +} + + +/********************************************************************** + * wow64_NtCreateNamedPipeFile + */ +NTSTATUS WINAPI wow64_NtCreateNamedPipeFile(UINT *args) +{ + ULONG *handle_ptr = get_ptr(&args); + ACCESS_MASK access = get_ulong(&args); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr(&args); + IO_STATUS_BLOCK32 *io32 = get_ptr(&args); + ULONG sharing = get_ulong(&args); + ULONG dispo = get_ulong(&args); + ULONG options = get_ulong(&args); + ULONG pipe_type = get_ulong(&args); + ULONG read_mode = get_ulong(&args); + ULONG completion_mode = get_ulong(&args); + ULONG max_inst = get_ulong(&args); + ULONG inbound_quota = get_ulong(&args); + ULONG outbound_quota = get_ulong(&args); + LARGE_INTEGER *timeout = get_ptr(&args); + + struct object_attr64 attr; + PWOW64_IOSB_STORAGE IosbStorage; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtCreateNamedPipeFile(&handle, access, objattr_32to64(&attr, attr32), + AllocIosbStorage(io32, &IosbStorage), sharing, dispo, options, + pipe_type, read_mode, completion_mode, max_inst, + inbound_quota, outbound_quota, timeout); + put_handle(handle_ptr, handle); + FreeIosbStorage(IosbStorage, io32, status); + + return status; +} + + +/********************************************************************** + * wow64_NtCreatePagingFile + */ +NTSTATUS WINAPI wow64_NtCreatePagingFile(UINT *args) +{ + UNICODE_STRING32 *str32 = get_ptr(&args); + LARGE_INTEGER *min_size = get_ptr(&args); + LARGE_INTEGER *max_size = get_ptr(&args); + ULONG actual_size = get_ulong(&args); + + UNICODE_STRING str; + + return NtCreatePagingFile(unicode_str_32to64(&str, str32), min_size, max_size, actual_size); +} + + +/********************************************************************** + * wow64_NtDeleteFile + */ +NTSTATUS WINAPI wow64_NtDeleteFile(UINT *args) +{ + OBJECT_ATTRIBUTES32 *attr32 = get_ptr(&args); + + struct object_attr64 attr; + + return NtDeleteFile(objattr_32to64_redirect(&attr, attr32)); +} + + +/********************************************************************** + * wow64_NtDeviceIoControlFile + */ +NTSTATUS WINAPI wow64_NtDeviceIoControlFile(UINT *args) +{ + HANDLE handle = get_handle(&args); + HANDLE event = get_handle(&args); + ULONG apc = get_ulong(&args); + ULONG apc_param = get_ulong(&args); + IO_STATUS_BLOCK32 *io32 = get_ptr(&args); + ULONG code = get_ulong(&args); + void *in_buf = get_ptr(&args); + ULONG in_len = get_ulong(&args); + void *out_buf = get_ptr(&args); + ULONG out_len = get_ulong(&args); + + PWOW64_IOSB_STORAGE IosbStorage; + NTSTATUS status; + + status = NtDeviceIoControlFile(handle, event, apc_32to64(apc), apc_param_32to64(apc, apc_param), + AllocIosbStorage(io32, &IosbStorage), code, in_buf, in_len, out_buf, out_len); + FreeIosbStorage(IosbStorage, io32, status); + + return status; +} + + +/********************************************************************** + * wow64_NtFlushBuffersFile + */ +NTSTATUS WINAPI wow64_NtFlushBuffersFile(UINT *args) +{ + HANDLE handle = get_handle(&args); + IO_STATUS_BLOCK32 *io32 = get_ptr(&args); + + PWOW64_IOSB_STORAGE IosbStorage; + NTSTATUS status; + + status = NtFlushBuffersFile(handle, AllocIosbStorage(io32, &IosbStorage)); + FreeIosbStorage(IosbStorage, io32, status); + + return status; +} + + +/********************************************************************** + * wow64_NtFsControlFile + */ +NTSTATUS WINAPI wow64_NtFsControlFile(UINT *args) +{ + HANDLE handle = get_handle(&args); + HANDLE event = get_handle(&args); + ULONG apc = get_ulong(&args); + ULONG apc_param = get_ulong(&args); + IO_STATUS_BLOCK32 *io32 = get_ptr(&args); + ULONG code = get_ulong(&args); + void *in_buf = get_ptr(&args); + ULONG in_len = get_ulong(&args); + void *out_buf = get_ptr(&args); + ULONG out_len = get_ulong(&args); + + PWOW64_IOSB_STORAGE IosbStorage; + NTSTATUS status; + + status = NtFsControlFile(handle, event, apc_32to64(apc), apc_param_32to64(apc, apc_param), + AllocIosbStorage(io32, &IosbStorage), code, in_buf, in_len, out_buf, out_len); + FreeIosbStorage(IosbStorage, io32, status); + + return status; +} + + +/********************************************************************** + * wow64_NtLockFile + */ +NTSTATUS WINAPI wow64_NtLockFile(UINT *args) +{ + HANDLE handle = get_handle(&args); + HANDLE event = get_handle(&args); + ULONG apc = get_ulong(&args); + ULONG apc_param = get_ulong(&args); + IO_STATUS_BLOCK32 *io32 = get_ptr(&args); + LARGE_INTEGER *offset = get_ptr(&args); + LARGE_INTEGER *count = get_ptr(&args); + ULONG key = get_ulong(&args); + + BOOLEAN dont_wait = get_ulong(&args); + BOOLEAN exclusive = get_ulong(&args); + + PWOW64_IOSB_STORAGE IosbStorage; + NTSTATUS status; + + status = NtLockFile(handle, event, apc_32to64(apc), apc_param_32to64(apc, apc_param), + AllocIosbStorage(io32, &IosbStorage), offset, count, key, dont_wait, exclusive); + FreeIosbStorage(IosbStorage, io32, status); + + return status; +} + + +/********************************************************************** + * wow64_NtNotifyChangeDirectoryFile + */ +NTSTATUS WINAPI wow64_NtNotifyChangeDirectoryFile(UINT *args) +{ + HANDLE handle = get_handle(&args); + HANDLE event = get_handle(&args); + ULONG apc = get_ulong(&args); + ULONG apc_param = get_ulong(&args); + IO_STATUS_BLOCK32 *io32 = get_ptr(&args); + void *buffer = get_ptr(&args); + ULONG len = get_ulong(&args); + ULONG filter = get_ulong(&args); + BOOLEAN subtree = get_ulong(&args); + + PWOW64_IOSB_STORAGE IosbStorage; + NTSTATUS status; + + status = NtNotifyChangeDirectoryFile(handle, event, apc_32to64(apc), + apc_param_32to64(apc, apc_param), AllocIosbStorage(io32, &IosbStorage), + buffer, len, filter, subtree); + FreeIosbStorage(IosbStorage, io32, status); + + return status; +} + + +/********************************************************************** + * wow64_NtOpenFile + */ +NTSTATUS WINAPI wow64_NtOpenFile(UINT *args) +{ + ULONG *handle_ptr = get_ptr(&args); + ACCESS_MASK access = get_ulong(&args); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr(&args); + IO_STATUS_BLOCK32 *io32 = get_ptr(&args); + ULONG sharing = get_ulong(&args); + ULONG options = get_ulong(&args); + + struct object_attr64 attr; + PWOW64_IOSB_STORAGE IosbStorage; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtOpenFile(&handle, access, objattr_32to64_redirect(&attr, attr32), + AllocIosbStorage(io32, &IosbStorage), sharing, options); + + put_handle(handle_ptr, handle); + FreeIosbStorage(IosbStorage, io32, status); + + return status; +} + + +/********************************************************************** + * wow64_NtQueryAttributesFile + */ +NTSTATUS WINAPI wow64_NtQueryAttributesFile(UINT *args) +{ + OBJECT_ATTRIBUTES32 *attr32 = get_ptr(&args); + FILE_BASIC_INFORMATION *info = get_ptr(&args); + + struct object_attr64 attr; + + return NtQueryAttributesFile(objattr_32to64_redirect(&attr, attr32), info); +} + + +/********************************************************************** + * wow64_NtQueryDirectoryFile + */ +NTSTATUS WINAPI wow64_NtQueryDirectoryFile(UINT *args) +{ + HANDLE handle = get_handle(&args); + HANDLE event = get_handle(&args); + ULONG apc = get_ulong(&args); + ULONG apc_param = get_ulong(&args); + IO_STATUS_BLOCK32 *io32 = get_ptr(&args); + void *buffer = get_ptr(&args); + ULONG len = get_ulong(&args); + FILE_INFORMATION_CLASS class = get_ulong(&args); + BOOLEAN single_entry = get_ulong(&args); + UNICODE_STRING32 *mask32 = get_ptr(&args); + BOOLEAN restart_scan = get_ulong(&args); + + UNICODE_STRING mask; + PWOW64_IOSB_STORAGE IosbStorage; + NTSTATUS status; + + status = NtQueryDirectoryFile(handle, event, apc_32to64(apc), apc_param_32to64(apc, apc_param), + AllocIosbStorage(io32, &IosbStorage), buffer, len, class, single_entry, + unicode_str_32to64(&mask, mask32), restart_scan); + FreeIosbStorage(IosbStorage, io32, status); + + return status; +} + + +/********************************************************************** + * wow64_NtQueryEaFile + */ +NTSTATUS WINAPI wow64_NtQueryEaFile(UINT *args) +{ + HANDLE handle = get_handle(&args); + IO_STATUS_BLOCK32 *io32 = get_ptr(&args); + void *buffer = get_ptr(&args); + ULONG len = get_ulong(&args); + BOOLEAN single_entry = get_ulong(&args); + void *list = get_ptr(&args); + ULONG list_len = get_ulong(&args); + ULONG *index = get_ptr(&args); + BOOLEAN restart = get_ulong(&args); + + PWOW64_IOSB_STORAGE IosbStorage; + NTSTATUS status; + + status = NtQueryEaFile(handle, AllocIosbStorage(io32, &IosbStorage), buffer, len, + single_entry, list, list_len, index, restart); + FreeIosbStorage(IosbStorage, io32, status); + + return status; +} + + +/********************************************************************** + * wow64_NtQueryFullAttributesFile + */ +NTSTATUS WINAPI wow64_NtQueryFullAttributesFile(UINT *args) +{ + OBJECT_ATTRIBUTES32 *attr32 = get_ptr(&args); + FILE_NETWORK_OPEN_INFORMATION *info = get_ptr(&args); + + struct object_attr64 attr; + + return NtQueryFullAttributesFile(objattr_32to64_redirect(&attr, attr32), info); +} + + +/********************************************************************** + * wow64_NtQueryInformationFile + */ +NTSTATUS WINAPI wow64_NtQueryInformationFile(UINT *args) +{ + HANDLE handle = get_handle(&args); + IO_STATUS_BLOCK32 *io32 = get_ptr(&args); + void *info = get_ptr(&args); + ULONG len = get_ulong(&args); + FILE_INFORMATION_CLASS class = get_ulong(&args); + + PWOW64_IOSB_STORAGE IosbStorage; + NTSTATUS status; + + status = NtQueryInformationFile(handle, AllocIosbStorage(io32, &IosbStorage), info, len, class); + FreeIosbStorage(IosbStorage, io32, status); + + return status; +} + + +/********************************************************************** + * wow64_NtQueryVolumeInformationFile + */ +NTSTATUS WINAPI wow64_NtQueryVolumeInformationFile(UINT *args) +{ + HANDLE handle = get_handle(&args); + IO_STATUS_BLOCK32 *io32 = get_ptr(&args); + void *buffer = get_ptr(&args); + ULONG len = get_ulong(&args); + FS_INFORMATION_CLASS class = get_ulong(&args); + + PWOW64_IOSB_STORAGE IosbStorage; + NTSTATUS status; + + status = NtQueryVolumeInformationFile(handle, AllocIosbStorage(io32, &IosbStorage), buffer, len, class); + FreeIosbStorage(IosbStorage, io32, status); + + return status; +} + + +/********************************************************************** + * wow64_NtReadFile + */ +NTSTATUS WINAPI wow64_NtReadFile(UINT *args) +{ + HANDLE handle = get_handle(&args); + HANDLE event = get_handle(&args); + ULONG apc = get_ulong(&args); + ULONG apc_param = get_ulong(&args); + IO_STATUS_BLOCK32 *io32 = get_ptr(&args); + void *buffer = get_ptr(&args); + ULONG len = get_ulong(&args); + LARGE_INTEGER *offset = get_ptr(&args); + ULONG *key = get_ptr(&args); + + PWOW64_IOSB_STORAGE IosbStorage; + NTSTATUS status; + + status = NtReadFile(handle, event, apc_32to64(apc), apc_param_32to64(apc, apc_param), + AllocIosbStorage(io32, &IosbStorage), buffer, len, offset, key); + + FreeIosbStorage(IosbStorage, io32, status); + + return status; +} + + +/********************************************************************** + * wow64_NtReadFileScatter + */ +NTSTATUS WINAPI wow64_NtReadFileScatter(UINT *args) +{ + HANDLE handle = get_handle(&args); + HANDLE event = get_handle(&args); + ULONG apc = get_ulong(&args); + ULONG apc_param = get_ulong(&args); + IO_STATUS_BLOCK32 *io32 = get_ptr(&args); + FILE_SEGMENT_ELEMENT *segments = get_ptr(&args); + ULONG len = get_ulong(&args); + LARGE_INTEGER *offset = get_ptr(&args); + ULONG *key = get_ptr(&args); + + PWOW64_IOSB_STORAGE IosbStorage; + NTSTATUS status; + + status = NtReadFileScatter(handle, event, apc_32to64(apc), apc_param_32to64(apc, apc_param), + AllocIosbStorage(io32, &IosbStorage), segments, len, offset, key); + FreeIosbStorage(IosbStorage, io32, status); + + return status; +} + + +/********************************************************************** + * wow64_NtRemoveIoCompletion + */ +NTSTATUS WINAPI wow64_NtRemoveIoCompletion(UINT *args) +{ + HANDLE handle = get_handle(&args); + ULONG *key_ptr = get_ptr(&args); + ULONG *value_ptr = get_ptr(&args); + IO_STATUS_BLOCK32 *io32 = get_ptr(&args); + LARGE_INTEGER *timeout = get_ptr(&args); + + PWOW64_IOSB_STORAGE IosbStorage; + PVOID key, value; + NTSTATUS status; + + status = NtRemoveIoCompletion(handle, &key, &value, AllocIosbStorage(io32, &IosbStorage), timeout); + if (!status) + { + *key_ptr = PtrToUlong(key); + *value_ptr = PtrToUlong(value); + } + FreeIosbStorage(IosbStorage, io32, status); + + return status; +} + + +/********************************************************************** + * wow64_NtSetEaFile + */ +NTSTATUS WINAPI wow64_NtSetEaFile(UINT *args) +{ + HANDLE handle = get_handle(&args); + IO_STATUS_BLOCK32 *io32 = get_ptr(&args); + void *ptr = get_ptr(&args); + ULONG len = get_ulong(&args); + + PWOW64_IOSB_STORAGE IosbStorage; + NTSTATUS status; + + status = NtSetEaFile(handle, AllocIosbStorage(io32, &IosbStorage), ptr, len); + FreeIosbStorage(IosbStorage, io32, status); + + return status; +} + + +/********************************************************************** + * wow64_NtSetInformationFile + */ +NTSTATUS WINAPI wow64_NtSetInformationFile(UINT *args) +{ + HANDLE handle = get_handle(&args); + IO_STATUS_BLOCK32 *io32 = get_ptr(&args); + void *ptr = get_ptr(&args); + ULONG len = get_ulong(&args); + FILE_INFORMATION_CLASS class = get_ulong(&args); + + PWOW64_IOSB_STORAGE IosbStorage; + NTSTATUS status; + + switch (class) + { + case FileBasicInformation: /* FILE_BASIC_INFORMATION */ + case FilePositionInformation: /* FILE_POSITION_INFORMATION */ + case FileEndOfFileInformation: /* FILE_END_OF_FILE_INFORMATION */ + case FilePipeInformation: /* FILE_PIPE_INFORMATION */ + case FileMailslotSetInformation: /* FILE_MAILSLOT_SET_INFORMATION */ + case FileIoCompletionNotificationInformation: /* FILE_IO_COMPLETION_NOTIFICATION_INFORMATION */ + case FileIoPriorityHintInformation: /* FILE_IO_PRIORITY_HINT_INFO */ + case FileValidDataLengthInformation: /* FILE_VALID_DATA_LENGTH_INFORMATION */ + case FileDispositionInformation: /* FILE_DISPOSITION_INFORMATION */ + case FileDispositionInformationEx: /* FILE_DISPOSITION_INFORMATION_EX */ + case FileAllocationInformation: /* FILE_ALLOCATION_INFORMATION */ + status = NtSetInformationFile(handle, AllocIosbStorage(io32, &IosbStorage), ptr, len, class); + break; + + case FileRenameInformation: /* FILE_RENAME_INFORMATION */ + case FileRenameInformationEx: /* FILE_RENAME_INFORMATION */ + case FileLinkInformation: /* FILE_LINK_INFORMATION */ + case FileLinkInformationEx: /* FILE_LINK_INFORMATION */ + if (len >= sizeof(FILE_RENAME_INFORMATION32)) + { + OBJECT_ATTRIBUTES attr; + UNICODE_STRING name; + FILE_RENAME_INFORMATION32 *info32 = ptr; + FILE_RENAME_INFORMATION *info; + ULONG size; + + name.Buffer = info32->FileName; + name.Length = info32->FileNameLength; + InitializeObjectAttributes(&attr, &name, 0, LongToHandle(info32->RootDirectory), 0); + GetFileRedirect(&attr); + size = offsetof(FILE_RENAME_INFORMATION, FileName[name.Length/sizeof(WCHAR)]); + info = Wow64AllocateTemp(size); + info->ReplaceIfExists = info32->Flags; + info->RootDirectory = attr.RootDirectory; + info->FileNameLength = name.Length; + memcpy(info->FileName, name.Buffer, info->FileNameLength); + status = NtSetInformationFile(handle, AllocIosbStorage(io32, &IosbStorage), info, size, class); + } + else status = IosbStorage->StatusBlock64.Status = STATUS_INVALID_PARAMETER_3; + break; + + case FileCompletionInformation: /* FILE_COMPLETION_INFORMATION */ + if (len >= sizeof(FILE_COMPLETION_INFORMATION32)) + { + FILE_COMPLETION_INFORMATION32 *info32 = ptr; + FILE_COMPLETION_INFORMATION info; + + info.Port = LongToHandle(info32->CompletionPort); + info.Key = UlongToPtr(info32->CompletionKey); + status = NtSetInformationFile(handle, AllocIosbStorage(io32, &IosbStorage), &info, sizeof(info), class); + } + else status = IosbStorage->StatusBlock64.Status = STATUS_INVALID_PARAMETER_3; + break; + + default: + FIXME("unsupported class %u\n", class); + status = IosbStorage->StatusBlock64.Status = STATUS_INVALID_INFO_CLASS; + break; + } + FreeIosbStorage(IosbStorage, io32, status); + + return status; +} + + +/********************************************************************** + * wow64_NtSetVolumeInformationFile + */ +NTSTATUS WINAPI wow64_NtSetVolumeInformationFile(UINT *args) +{ + HANDLE handle = get_handle(&args); + IO_STATUS_BLOCK32 *io32 = get_ptr(&args); + void *ptr = get_ptr(&args); + ULONG len = get_ulong(&args); + FS_INFORMATION_CLASS class = get_ulong(&args); + + PWOW64_IOSB_STORAGE IosbStorage; + NTSTATUS status; + + status = NtSetVolumeInformationFile(handle, AllocIosbStorage(io32, &IosbStorage), ptr, len, class); + FreeIosbStorage(IosbStorage, io32, status); + + return status; +} + + +/********************************************************************** + * wow64_NtUnlockFile + */ +NTSTATUS WINAPI wow64_NtUnlockFile(UINT *args) +{ + HANDLE handle = get_handle(&args); + IO_STATUS_BLOCK32 *io32 = get_ptr(&args); + LARGE_INTEGER *offset = get_ptr(&args); + LARGE_INTEGER *count = get_ptr(&args); + ULONG key = get_ulong(&args); + + PWOW64_IOSB_STORAGE IosbStorage; + NTSTATUS status; + + status = NtUnlockFile(handle, AllocIosbStorage(io32, &IosbStorage), offset, count, key); + FreeIosbStorage(IosbStorage, io32, status); + + return status; +} + + +/********************************************************************** + * wow64_NtWriteFile + */ +NTSTATUS WINAPI wow64_NtWriteFile(UINT *args) +{ + HANDLE handle = get_handle(&args); + HANDLE event = get_handle(&args); + ULONG apc = get_ulong(&args); + ULONG apc_param = get_ulong(&args); + IO_STATUS_BLOCK32 *io32 = get_ptr(&args); + void *buffer = get_ptr(&args); + ULONG len = get_ulong(&args); + LARGE_INTEGER *offset = get_ptr(&args); + ULONG *key = get_ptr(&args); + + PWOW64_IOSB_STORAGE IosbStorage; + NTSTATUS status; + + status = NtWriteFile(handle, event, apc_32to64(apc), apc_param_32to64(apc, apc_param), + AllocIosbStorage(io32, &IosbStorage), buffer, len, offset, key); + FreeIosbStorage(IosbStorage, io32, status); + + return status; +} + + +/********************************************************************** + * wow64_NtWriteFileGather + */ +NTSTATUS WINAPI wow64_NtWriteFileGather(UINT *args) +{ + HANDLE handle = get_handle(&args); + HANDLE event = get_handle(&args); + ULONG apc = get_ulong(&args); + ULONG apc_param = get_ulong(&args); + IO_STATUS_BLOCK32 *io32 = get_ptr(&args); + FILE_SEGMENT_ELEMENT *segments = get_ptr(&args); + ULONG len = get_ulong(&args); + LARGE_INTEGER *offset = get_ptr(&args); + ULONG *key = get_ptr(&args); + + PWOW64_IOSB_STORAGE IosbStorage; + NTSTATUS status; + + status = NtWriteFileGather(handle, event, apc_32to64(apc), apc_param_32to64(apc, apc_param), + AllocIosbStorage(io32, &IosbStorage), segments, len, offset, key); + FreeIosbStorage(IosbStorage, io32, status); + + return status; +} diff --git a/dll/wow64/wine/registry.c b/dll/wow64/wine/registry.c new file mode 100644 index 0000000000000..2ab1b2a5d204e --- /dev/null +++ b/dll/wow64/wine/registry.c @@ -0,0 +1,507 @@ +/* + * WoW64 registry functions + * + * Copyright 2021 Alexandre Julliard + * Copyright 2025 Marcin Jabłoński + * + * 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 + */ +#ifndef __REACTOS__ +#include + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "winnt.h" +#include "winternl.h" +#include "wow64_private.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wow); +#endif + +#ifdef __REACTOS__ +#include "ros_wow64_private.h" +#endif + +/********************************************************************** + * wow64_NtCreateKey + */ +NTSTATUS WINAPI wow64_NtCreateKey( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + ULONG index = get_ulong( &args ); + UNICODE_STRING32 *class32 = get_ptr( &args ); + ULONG options = get_ulong( &args ); + ULONG *dispos = get_ptr( &args ); + + struct object_attr64 attr; + UNICODE_STRING class; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtCreateKey( &handle, access, objattr_32to64( &attr, attr32 ), index, + unicode_str_32to64( &class, class32 ), options, dispos ); + put_handle( handle_ptr, handle ); + return status; +} + +#ifndef __REACTOS__ +/********************************************************************** + * wow64_NtCreateKeyTransacted + */ +NTSTATUS WINAPI wow64_NtCreateKeyTransacted( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + ULONG index = get_ulong( &args ); + UNICODE_STRING32 *class32 = get_ptr( &args ); + ULONG options = get_ulong( &args ); + HANDLE transacted = get_handle( &args ); + ULONG *dispos = get_ptr( &args ); + + struct object_attr64 attr; + UNICODE_STRING class; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtCreateKeyTransacted( &handle, access, objattr_32to64( &attr, attr32 ), index, + unicode_str_32to64( &class, class32 ), options, transacted, dispos ); + put_handle( handle_ptr, handle ); + return status; +} +#endif + +/********************************************************************** + * wow64_NtDeleteKey + */ +NTSTATUS WINAPI wow64_NtDeleteKey( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + + return NtDeleteKey( handle ); +} + + +/********************************************************************** + * wow64_NtDeleteValueKey + */ +NTSTATUS WINAPI wow64_NtDeleteValueKey( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + UNICODE_STRING32 *str32 = get_ptr( &args ); + + UNICODE_STRING str; + + return NtDeleteValueKey( handle, unicode_str_32to64( &str, str32 )); +} + + +/********************************************************************** + * wow64_NtEnumerateKey + */ +NTSTATUS WINAPI wow64_NtEnumerateKey( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + ULONG index = get_ulong( &args ); + KEY_INFORMATION_CLASS class = get_ulong( &args ); + void *ptr = get_ptr( &args ); + ULONG len = get_ulong( &args ); + ULONG *retlen = get_ptr( &args ); + + return NtEnumerateKey( handle, index, class, ptr, len, retlen ); +} + + +/********************************************************************** + * wow64_NtEnumerateValueKey + */ +NTSTATUS WINAPI wow64_NtEnumerateValueKey( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + ULONG index = get_ulong( &args ); + KEY_VALUE_INFORMATION_CLASS class = get_ulong( &args ); + void *ptr = get_ptr( &args ); + ULONG len = get_ulong( &args ); + ULONG *retlen = get_ptr( &args ); + + return NtEnumerateValueKey( handle, index, class, ptr, len, retlen ); +} + + +/********************************************************************** + * wow64_NtFlushKey + */ +NTSTATUS WINAPI wow64_NtFlushKey( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + + return NtFlushKey( handle ); +} + + +/********************************************************************** + * wow64_NtLoadKey + */ +NTSTATUS WINAPI wow64_NtLoadKey( UINT *args ) +{ + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + OBJECT_ATTRIBUTES32 *file32 = get_ptr( &args ); + + struct object_attr64 attr, file; + + return NtLoadKey( objattr_32to64( &attr, attr32 ), objattr_32to64( &file, file32 )); +} + + +/********************************************************************** + * wow64_NtLoadKey2 + */ +NTSTATUS WINAPI wow64_NtLoadKey2( UINT *args ) +{ + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + OBJECT_ATTRIBUTES32 *file32 = get_ptr( &args ); + ULONG flags = get_ulong( &args ); + + struct object_attr64 attr, file; + + return NtLoadKey2( objattr_32to64( &attr, attr32 ), objattr_32to64( &file, file32 ), flags ); +} + +#ifndef __REACTOS__ +/* FIXME: ReactOS doesn't have as many args as this, is this from some future NT version? */ + +/********************************************************************** + * wow64_NtLoadKeyEx + */ +NTSTATUS WINAPI wow64_NtLoadKeyEx( UINT *args ) +{ + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + OBJECT_ATTRIBUTES32 *file32 = get_ptr( &args ); + ULONG flags = get_ulong( &args ); + HANDLE trustkey = get_handle( &args ); + HANDLE event = get_handle( &args ); + ACCESS_MASK desired_access = get_ulong( &args ); + HANDLE *rootkey = get_ptr( &args ); + IO_STATUS_BLOCK32 *io32 = get_ptr( &args ); + + struct object_attr64 attr, file; + IO_STATUS_BLOCK io; + NTSTATUS status; + + status = NtLoadKeyEx( objattr_32to64( &attr, attr32 ), objattr_32to64( &file, file32 ), flags, + trustkey, event, desired_access, rootkey, iosb_32to64( &io, io32 ) ); + put_iosb( io32, &io ); + return status; +} +#endif + +/********************************************************************** + * wow64_NtNotifyChangeKey + */ +NTSTATUS WINAPI wow64_NtNotifyChangeKey( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + HANDLE event = get_handle( &args ); + ULONG apc = get_ulong( &args ); + ULONG apc_param = get_ulong( &args ); + IO_STATUS_BLOCK32 *io32 = get_ptr( &args ); + ULONG filter = get_ulong( &args ); + BOOLEAN subtree = get_ulong( &args ); + void *buffer = get_ptr( &args ); + ULONG len = get_ulong( &args ); + BOOLEAN async = get_ulong( &args ); + + IO_STATUS_BLOCK io; + NTSTATUS status; + + status = NtNotifyChangeKey( handle, event, apc_32to64( apc ), apc_param_32to64( apc, apc_param ), + iosb_32to64( &io, io32 ), filter, subtree, buffer, len, async ); + put_iosb( io32, &io ); + return status; +} + + +/********************************************************************** + * wow64_NtNotifyChangeMultipleKeys + */ +NTSTATUS WINAPI wow64_NtNotifyChangeMultipleKeys( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + ULONG count = get_ulong( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + HANDLE event = get_handle( &args ); + ULONG apc = get_ulong( &args ); + ULONG apc_param = get_ulong( &args ); + IO_STATUS_BLOCK32 *io32 = get_ptr( &args ); + ULONG filter = get_ulong( &args ); + BOOLEAN subtree = get_ulong( &args ); + void *buffer = get_ptr( &args ); + ULONG len = get_ulong( &args ); + BOOLEAN async = get_ulong( &args ); + + struct object_attr64 attr; + IO_STATUS_BLOCK io; + NTSTATUS status; + + status = NtNotifyChangeMultipleKeys( handle, count, objattr_32to64( &attr, attr32 ), event, + apc_32to64( apc ), apc_param_32to64( apc, apc_param ), + iosb_32to64( &io, io32 ), filter, subtree, buffer, len, async ); + put_iosb( io32, &io ); + return status; +} + + +/********************************************************************** + * wow64_NtOpenKey + */ +NTSTATUS WINAPI wow64_NtOpenKey( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + + struct object_attr64 attr; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtOpenKey( &handle, access, objattr_32to64( &attr, attr32 )); + put_handle( handle_ptr, handle ); + return status; +} + +#ifndef __REACTOS__ +/********************************************************************** + * wow64_NtOpenKeyEx + */ +NTSTATUS WINAPI wow64_NtOpenKeyEx( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + ULONG options = get_ulong( &args ); + + struct object_attr64 attr; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtOpenKeyEx( &handle, access, objattr_32to64( &attr, attr32 ), options ); + put_handle( handle_ptr, handle ); + return status; +} + + +/********************************************************************** + * wow64_NtOpenKeyTransacted + */ +NTSTATUS WINAPI wow64_NtOpenKeyTransacted( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + HANDLE transaction = get_handle( &args ); + + struct object_attr64 attr; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtOpenKeyTransacted( &handle, access, objattr_32to64( &attr, attr32 ), transaction ); + put_handle( handle_ptr, handle ); + return status; +} + + +/********************************************************************** + * wow64_NtOpenKeyTransactedEx + */ +NTSTATUS WINAPI wow64_NtOpenKeyTransactedEx( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + ULONG options = get_ulong( &args ); + HANDLE transaction = get_handle( &args ); + + struct object_attr64 attr; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtOpenKeyTransactedEx( &handle, access, objattr_32to64( &attr, attr32 ), options, transaction ); + put_handle( handle_ptr, handle ); + return status; +} +#endif + +/********************************************************************** + * wow64_NtQueryKey + */ +NTSTATUS WINAPI wow64_NtQueryKey( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + KEY_INFORMATION_CLASS class = get_ulong( &args ); + void *info = get_ptr( &args ); + ULONG len = get_ulong( &args ); + ULONG *retlen = get_ptr( &args ); + + return NtQueryKey( handle, class, info, len, retlen ); +} + +#ifndef __REACTOS__ +/********************************************************************** + * wow64_NtQueryMultipleValueKey + */ +NTSTATUS WINAPI wow64_NtQueryMultipleValueKey( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + KEY_MULTIPLE_VALUE_INFORMATION *info = get_ptr( &args ); + ULONG count = get_ulong( &args ); + void *ptr = get_ptr( &args ); + ULONG len = get_ulong( &args ); + ULONG *retlen = get_ptr( &args ); + + FIXME( "%p %p %lu %p %lu %p: stub\n", handle, info, count, ptr, len, retlen ); + return STATUS_SUCCESS; +} +#endif + +/********************************************************************** + * wow64_NtQueryValueKey + */ +NTSTATUS WINAPI wow64_NtQueryValueKey( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + UNICODE_STRING32 *str32 = get_ptr( &args ); + KEY_VALUE_INFORMATION_CLASS class = get_ulong( &args ); + void *ptr = get_ptr( &args ); + ULONG len = get_ulong( &args ); + ULONG *retlen = get_ptr( &args ); + + UNICODE_STRING str; + + return NtQueryValueKey( handle, unicode_str_32to64( &str, str32 ), class, ptr, len, retlen ); +} + + +/********************************************************************** + * wow64_NtRenameKey + */ +NTSTATUS WINAPI wow64_NtRenameKey( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + UNICODE_STRING32 *str32 = get_ptr( &args ); + + UNICODE_STRING str; + + return NtRenameKey( handle, unicode_str_32to64( &str, str32 )); +} + + +/********************************************************************** + * wow64_NtReplaceKey + */ +NTSTATUS WINAPI wow64_NtReplaceKey( UINT *args ) +{ + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + HANDLE handle = get_handle( &args ); + OBJECT_ATTRIBUTES32 *replace32 = get_ptr( &args ); + + struct object_attr64 attr, replace; + + return NtReplaceKey( objattr_32to64( &attr, attr32 ), handle, objattr_32to64( &replace, replace32 )); +} + + +/********************************************************************** + * wow64_NtRestoreKey + */ +NTSTATUS WINAPI wow64_NtRestoreKey( UINT *args ) +{ + HANDLE key = get_handle( &args ); + HANDLE file = get_handle( &args ); + ULONG flags = get_ulong( &args ); + + return NtRestoreKey( key, file, flags ); +} + + +/********************************************************************** + * wow64_NtSaveKey + */ +NTSTATUS WINAPI wow64_NtSaveKey( UINT *args ) +{ + HANDLE key = get_handle( &args ); + HANDLE file = get_handle( &args ); + + return NtSaveKey( key, file ); +} + + +/********************************************************************** + * wow64_NtSetInformationKey + */ +NTSTATUS WINAPI wow64_NtSetInformationKey( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + int class = get_ulong( &args ); + void *info = get_ptr( &args ); + ULONG len = get_ulong( &args ); + + return NtSetInformationKey( handle, class, info, len ); +} + + +/********************************************************************** + * wow64_NtSetValueKey + */ +NTSTATUS WINAPI wow64_NtSetValueKey( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + const UNICODE_STRING32 *str32 = get_ptr( &args ); + ULONG index = get_ulong( &args ); + ULONG type = get_ulong( &args ); + const void *data = get_ptr( &args ); + ULONG count = get_ulong( &args ); + + UNICODE_STRING str; + +#ifdef __REACTOS__ + return NtSetValueKey( handle, unicode_str_32to64( &str, str32 ), index, type, (void*)data, count ); +#else + return NtSetValueKey( handle, unicode_str_32to64( &str, str32 ), index, type, data, count ); +#endif +} + + +/********************************************************************** + * wow64_NtUnloadKey + */ +NTSTATUS WINAPI wow64_NtUnloadKey( UINT *args ) +{ + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + + struct object_attr64 attr; + + return NtUnloadKey( objattr_32to64( &attr, attr32 )); +} diff --git a/dll/wow64/wine/security.c b/dll/wow64/wine/security.c new file mode 100644 index 0000000000000..202eb943a8ba1 --- /dev/null +++ b/dll/wow64/wine/security.c @@ -0,0 +1,576 @@ +/* + * WoW64 security functions + * + * Copyright 2021 Alexandre Julliard + * + * 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 + */ + +#ifndef __REACTOS__ +#include + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "winnt.h" +#include "winternl.h" +#include "wow64_private.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wow); +#endif + +#ifdef __REACTOS__ +#include "ros_wow64_private.h" +#endif + +static TOKEN_GROUPS *token_groups_32to64( const TOKEN_GROUPS32 *groups32 ) +{ + TOKEN_GROUPS *groups; + ULONG i; + + if (!groups32) return NULL; + groups = Wow64AllocateTemp( offsetof( TOKEN_GROUPS, Groups[groups32->GroupCount] )); + groups->GroupCount = groups32->GroupCount; + for (i = 0; i < groups->GroupCount; i++) + { + groups->Groups[i].Sid = ULongToPtr( groups32->Groups[i].Sid ); + groups->Groups[i].Attributes = groups32->Groups[i].Attributes; + } + return groups; +} + + +/********************************************************************** + * wow64_NtAccessCheck + */ +NTSTATUS WINAPI wow64_NtAccessCheck( UINT *args ) +{ + SECURITY_DESCRIPTOR *sd32 = get_ptr( &args ); + HANDLE handle = get_handle( &args ); + ACCESS_MASK access = get_ulong( &args ); + GENERIC_MAPPING *mapping = get_ptr( &args ); + PRIVILEGE_SET *privs = get_ptr( &args ); + ULONG *retlen = get_ptr( &args ); + ACCESS_MASK *access_granted = get_ptr( &args ); + NTSTATUS *access_status = get_ptr( &args ); + + SECURITY_DESCRIPTOR sd; + + return NtAccessCheck( secdesc_32to64( &sd, sd32 ), handle, access, mapping, + privs, retlen, access_granted, access_status ); +} + +#ifndef __REACTOS__ +/********************************************************************** + * wow64_NtAccessCheckAndAuditAlarm + */ +NTSTATUS WINAPI wow64_NtAccessCheckAndAuditAlarm( UINT *args ) +{ + UNICODE_STRING32 *subsystem32 = get_ptr( &args ); + HANDLE handle = get_handle( &args ); + UNICODE_STRING32 *typename32 = get_ptr( &args ); + UNICODE_STRING32 *objname32 = get_ptr( &args ); + SECURITY_DESCRIPTOR *sd32 = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args ); + GENERIC_MAPPING *mapping = get_ptr( &args ); + BOOLEAN creation = get_ulong( &args ); + ACCESS_MASK *access_granted = get_ptr( &args ); + BOOLEAN *access_status = get_ptr( &args ); + BOOLEAN *onclose = get_ptr( &args ); + + UNICODE_STRING subsystem, typename, objname; + SECURITY_DESCRIPTOR sd; + + return NtAccessCheckAndAuditAlarm( unicode_str_32to64( &subsystem, subsystem32 ), handle, + unicode_str_32to64( &typename, typename32 ), + unicode_str_32to64( &objname, objname32 ), + secdesc_32to64( &sd, sd32 ), access, mapping, creation, + access_granted, access_status, onclose ); +} +#endif + +/********************************************************************** + * wow64_NtAdjustGroupsToken + */ +NTSTATUS WINAPI wow64_NtAdjustGroupsToken( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + BOOLEAN reset = get_ulong( &args ); + TOKEN_GROUPS32 *groups = get_ptr( &args ); + ULONG len = get_ulong( &args ); + TOKEN_GROUPS32 *prev = get_ptr( &args ); + ULONG *retlen = get_ptr( &args ); + + FIXME( "%p %d %p %lu %p %p\n", handle, reset, groups, len, prev, retlen ); + return STATUS_NOT_IMPLEMENTED; +} + + +/********************************************************************** + * wow64_NtAdjustPrivilegesToken + */ +NTSTATUS WINAPI wow64_NtAdjustPrivilegesToken( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + BOOLEAN disable = get_ulong( &args ); + TOKEN_PRIVILEGES *privs = get_ptr( &args ); + ULONG len = get_ulong( &args ); + TOKEN_PRIVILEGES *prev = get_ptr( &args ); + ULONG *retlen = get_ptr( &args ); + + return NtAdjustPrivilegesToken( handle, disable, privs, len, prev, retlen ); +} + + +#ifndef __REACTOS__ +/********************************************************************** + * wow64_NtCreateLowBoxToken + */ +NTSTATUS WINAPI wow64_NtCreateLowBoxToken( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + HANDLE token = get_handle( &args ); + ACCESS_MASK access = get_ulong( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + SID *sid = get_ptr( &args ); + ULONG count = get_ulong( &args ); + SID_AND_ATTRIBUTES32 *capabilities32 = get_ptr( &args ); + ULONG handle_count = get_ulong( &args ); + ULONG *handles32 = get_ptr( &args ); + + FIXME( "%p %p %lx %p %p %lu %p %lu %p: stub\n", + handle_ptr, token, access, attr32, sid, count, capabilities32, handle_count, handles32 ); + + *handle_ptr = 0; + return STATUS_SUCCESS; +} +#endif + + +/********************************************************************** + * wow64_NtCreateToken + */ +NTSTATUS WINAPI wow64_NtCreateToken( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + TOKEN_TYPE type = get_ulong( &args ); + LUID *luid = get_ptr( &args ); + LARGE_INTEGER *expire = get_ptr( &args ); + TOKEN_USER32 *user32 = get_ptr( &args ); + TOKEN_GROUPS32 *groups32 = get_ptr( &args ); + TOKEN_PRIVILEGES *privs = get_ptr( &args ); + TOKEN_OWNER32 *owner32 = get_ptr( &args ); + TOKEN_PRIMARY_GROUP32 *group32 = get_ptr( &args ); + TOKEN_DEFAULT_DACL32 *dacl32 = get_ptr( &args ); + TOKEN_SOURCE *source = get_ptr( &args ); + + struct object_attr64 attr; + TOKEN_USER user; + TOKEN_OWNER owner; + TOKEN_PRIMARY_GROUP group; + TOKEN_DEFAULT_DACL dacl; + HANDLE handle = 0; + NTSTATUS status; + + status = NtCreateToken( &handle, access, objattr_32to64( &attr, attr32 ), type, luid, expire, + token_user_32to64( &user, user32 ), token_groups_32to64( groups32 ), privs, + token_owner_32to64( &owner, owner32 ), token_primary_group_32to64( &group, group32 ), + token_default_dacl_32to64( &dacl, dacl32 ), source ); + put_handle( handle_ptr, handle ); + return status; +} + + +/********************************************************************** + * wow64_NtDuplicateToken + */ +NTSTATUS WINAPI wow64_NtDuplicateToken( UINT *args ) +{ + HANDLE token = get_handle( &args ); + ACCESS_MASK access = get_ulong( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + BOOLEAN effective_only = get_ulong( &args ); + TOKEN_TYPE type = get_ulong( &args ); + ULONG *handle_ptr = get_ptr( &args ); + + struct object_attr64 attr; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtDuplicateToken( token, access, objattr_32to64( &attr, attr32 ), effective_only, type, &handle ); + put_handle( handle_ptr, handle ); + return status; +} + + +/********************************************************************** + * wow64_NtFilterToken + */ +NTSTATUS WINAPI wow64_NtFilterToken( UINT *args ) +{ + HANDLE token = get_handle( &args ); + ULONG flags = get_ulong( &args ); + TOKEN_GROUPS32 *disable_sids32 = get_ptr( &args ); + TOKEN_PRIVILEGES *privs = get_ptr( &args ); + TOKEN_GROUPS32 *restrict_sids32 = get_ptr( &args ); + ULONG *handle_ptr = get_ptr( &args ); + + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtFilterToken( token, flags, token_groups_32to64( disable_sids32 ), privs, + token_groups_32to64( restrict_sids32 ), &handle ); + put_handle( handle_ptr, handle ); + return status; +} + + +/********************************************************************** + * wow64_NtCompareTokens + */ +NTSTATUS WINAPI wow64_NtCompareTokens( UINT *args ) +{ + HANDLE first = get_handle( &args ); + HANDLE second = get_handle( &args ); + BOOLEAN *equal = get_ptr( &args ); + + return NtCompareTokens( first, second, equal ); +} + +/********************************************************************** + * wow64_NtImpersonateAnonymousToken + */ +NTSTATUS WINAPI wow64_NtImpersonateAnonymousToken( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + + return NtImpersonateAnonymousToken( handle ); +} + + +/********************************************************************** + * wow64_NtOpenProcessToken + */ +NTSTATUS WINAPI wow64_NtOpenProcessToken( UINT *args ) +{ + HANDLE process = get_handle( &args ); + ACCESS_MASK access = get_ulong( &args ); + ULONG *handle_ptr = get_ptr( &args ); + + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtOpenProcessToken( process, access, &handle ); + put_handle( handle_ptr, handle ); + return status; +} + + +/********************************************************************** + * wow64_NtOpenProcessTokenEx + */ +NTSTATUS WINAPI wow64_NtOpenProcessTokenEx( UINT *args ) +{ + HANDLE process = get_handle( &args ); + ACCESS_MASK access = get_ulong( &args ); + ULONG attributes = get_ulong( &args ); + ULONG *handle_ptr = get_ptr( &args ); + + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtOpenProcessTokenEx( process, access, attributes, &handle ); + put_handle( handle_ptr, handle ); + return status; +} + + +/********************************************************************** + * wow64_NtOpenThreadToken + */ +NTSTATUS WINAPI wow64_NtOpenThreadToken( UINT *args ) +{ + HANDLE thread = get_handle( &args ); + ACCESS_MASK access = get_ulong( &args ); + BOOLEAN self = get_ulong( &args ); + ULONG *handle_ptr = get_ptr( &args ); + + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtOpenThreadToken( thread, access, self, &handle ); + put_handle( handle_ptr, handle ); + return status; +} + + +/********************************************************************** + * wow64_NtOpenThreadTokenEx + */ +NTSTATUS WINAPI wow64_NtOpenThreadTokenEx( UINT *args ) +{ + HANDLE thread = get_handle( &args ); + ACCESS_MASK access = get_ulong( &args ); + BOOLEAN self = get_ulong( &args ); + ULONG attributes = get_ulong( &args ); + ULONG *handle_ptr = get_ptr( &args ); + + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtOpenThreadTokenEx( thread, access, self, attributes, &handle ); + put_handle( handle_ptr, handle ); + return status; +} + + +/********************************************************************** + * wow64_NtPrivilegeCheck + */ +NTSTATUS WINAPI wow64_NtPrivilegeCheck( UINT *args ) +{ + HANDLE token = get_handle( &args ); + PRIVILEGE_SET *privs = get_ptr( &args ); + BOOLEAN *res = get_ptr( &args ); + + return NtPrivilegeCheck( token, privs, res ); +} + + +/********************************************************************** + * wow64_NtQueryInformationToken + */ +NTSTATUS WINAPI wow64_NtQueryInformationToken( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + TOKEN_INFORMATION_CLASS class = get_ulong( &args ); + void *info = get_ptr( &args ); + ULONG len = get_ulong( &args ); + ULONG *retlen = get_ptr( &args ); + + NTSTATUS status; + ULONG ret_size, sid_len; + + switch (class) + { + case TokenPrivileges: /* TOKEN_PRIVILEGES */ + case TokenImpersonationLevel: /* SECURITY_IMPERSONATION_LEVEL */ + case TokenStatistics: /* TOKEN_STATISTICS */ + case TokenType: /* TOKEN_TYPE */ + case TokenElevationType: /* TOKEN_ELEVATION_TYPE */ + case TokenElevation: /* TOKEN_ELEVATION */ + case TokenSessionId: /* ULONG */ + case TokenVirtualizationEnabled: /* ULONG */ + case TokenUIAccess: /* ULONG */ + case TokenIsAppContainer: /* ULONG */ + /* nothing to map */ + return NtQueryInformationToken( handle, class, info, len, retlen ); + + case TokenUser: /* TOKEN_USER + SID */ + case TokenIntegrityLevel: /* TOKEN_MANDATORY_LABEL + SID */ + { + ULONG_PTR buffer[(sizeof(TOKEN_USER) + SECURITY_MAX_SID_SIZE) / sizeof(ULONG_PTR)]; + TOKEN_USER *user = (TOKEN_USER *)buffer; + TOKEN_USER32 *user32 = info; + SID *sid; + + status = NtQueryInformationToken( handle, class, &buffer, sizeof(buffer), &ret_size ); + if (status) return status; + sid = user->User.Sid; + sid_len = offsetof( SID, SubAuthority[sid->SubAuthorityCount] ); + if (len >= sizeof(*user32) + sid_len) + { + user32->User.Sid = PtrToUlong( user32 + 1 ); + user32->User.Attributes = user->User.Attributes; + memcpy( user32 + 1, sid, sid_len ); + } + else status = STATUS_BUFFER_TOO_SMALL; + if (retlen) *retlen = sizeof(*user32) + sid_len; + return status; + } + + case TokenOwner: /* TOKEN_OWNER + SID */ + case TokenPrimaryGroup: /* TOKEN_PRIMARY_GROUP + SID */ + case TokenAppContainerSid: /* TOKEN_APPCONTAINER_INFORMATION + SID */ + { + ULONG_PTR buffer[(sizeof(TOKEN_OWNER) + SECURITY_MAX_SID_SIZE) / sizeof(ULONG_PTR)]; + TOKEN_OWNER *owner = (TOKEN_OWNER *)buffer; + TOKEN_OWNER32 *owner32 = info; + SID *sid; + + status = NtQueryInformationToken( handle, class, &buffer, sizeof(buffer), &ret_size ); + if (status) return status; + sid = owner->Owner; + sid_len = offsetof( SID, SubAuthority[sid->SubAuthorityCount] ); + if (len >= sizeof(*owner32) + sid_len) + { + owner32->Owner = PtrToUlong( owner32 + 1 ); + memcpy( owner32 + 1, sid, sid_len ); + } + else status = STATUS_BUFFER_TOO_SMALL; + if (retlen) *retlen = sizeof(*owner32) + sid_len; + return status; + } + + case TokenGroups: /* TOKEN_GROUPS */ + case TokenLogonSid: /* TOKEN_GROUPS */ + { + TOKEN_GROUPS32 *groups32 = info; + TOKEN_GROUPS *groups; + ULONG i, group_len, group32_len; + + status = NtQueryInformationToken( handle, class, NULL, 0, &ret_size ); + if (status != STATUS_BUFFER_TOO_SMALL) return status; + groups = Wow64AllocateTemp( ret_size ); + status = NtQueryInformationToken( handle, class, groups, ret_size, &ret_size ); + if (status) return status; + group_len = offsetof( TOKEN_GROUPS, Groups[groups->GroupCount] ); + group32_len = offsetof( TOKEN_GROUPS32, Groups[groups->GroupCount] ); + sid_len = ret_size - group_len; + ret_size = group32_len + sid_len; + if (len >= ret_size) + { + SID *sid = (SID *)((char *)groups + group_len); + SID *sid32 = (SID *)((char *)groups32 + group32_len); + + memcpy( sid32, sid, sid_len ); + groups32->GroupCount = groups->GroupCount; + for (i = 0; i < groups->GroupCount; i++) + { + groups32->Groups[i].Sid = PtrToUlong(sid32) + ((char *)groups->Groups[i].Sid - (char *)sid); + groups32->Groups[i].Attributes = groups->Groups[i].Attributes; + } + } + else status = STATUS_BUFFER_TOO_SMALL; + if (retlen) *retlen = ret_size; + return status; + } + + case TokenDefaultDacl: /* TOKEN_DEFAULT_DACL + ACL */ + { + ULONG size = len + sizeof(TOKEN_DEFAULT_DACL) - sizeof(TOKEN_DEFAULT_DACL32); + TOKEN_DEFAULT_DACL32 *dacl32 = info; + TOKEN_DEFAULT_DACL *dacl = Wow64AllocateTemp( size ); + + status = NtQueryInformationToken( handle, class, dacl, size, &ret_size ); + if (!status) + { + dacl32->DefaultDacl = dacl->DefaultDacl ? PtrToUlong( dacl32 + 1 ) : 0; + if (dacl->DefaultDacl) memcpy( dacl32 + 1, dacl->DefaultDacl, ret_size - sizeof(*dacl) ); + } + if (retlen) *retlen = ret_size + sizeof(*dacl32) - sizeof(*dacl); + return status; + } + + case TokenLinkedToken: /* TOKEN_LINKED_TOKEN */ + { + TOKEN_LINKED_TOKEN link; + + status = NtQueryInformationToken( handle, class, &link, sizeof(link), &ret_size ); + if (!status) *(ULONG *)info = HandleToLong( link.LinkedToken ); + if (retlen) *retlen = sizeof(ULONG); + return status; + } + + default: + FIXME( "unsupported class %u\n", class ); + return STATUS_INVALID_INFO_CLASS; + } +} + + +/********************************************************************** + * wow64_NtQuerySecurityObject + */ +NTSTATUS WINAPI wow64_NtQuerySecurityObject( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + SECURITY_INFORMATION info = get_ulong( &args ); + SECURITY_DESCRIPTOR *sd = get_ptr( &args ); + ULONG len = get_ulong( &args ); + ULONG *retlen = get_ptr( &args ); + + /* returned descriptor is always SE_SELF_RELATIVE, no mapping needed */ + return NtQuerySecurityObject( handle, info, sd, len, retlen ); +} + + +/********************************************************************** + * wow64_NtSetInformationToken + */ +NTSTATUS WINAPI wow64_NtSetInformationToken( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + TOKEN_INFORMATION_CLASS class = get_ulong( &args ); + void *ptr = get_ptr( &args ); + ULONG len = get_ulong( &args ); + + switch (class) + { + case TokenIntegrityLevel: /* TOKEN_MANDATORY_LABEL */ + if (len >= sizeof(TOKEN_MANDATORY_LABEL32)) + { + TOKEN_MANDATORY_LABEL32 *label32 = ptr; + TOKEN_MANDATORY_LABEL label; + + label.Label.Sid = ULongToPtr( label32->Label.Sid ); + label.Label.Attributes = label32->Label.Attributes; + return NtSetInformationToken( handle, class, &label, sizeof(label) ); + } + else return STATUS_INFO_LENGTH_MISMATCH; + + case TokenSessionId: /* ULONG */ + return NtSetInformationToken( handle, class, ptr, len ); + + case TokenDefaultDacl: /* TOKEN_DEFAULT_DACL */ + if (len >= sizeof(TOKEN_DEFAULT_DACL32)) + { + TOKEN_DEFAULT_DACL32 *dacl32 = ptr; + TOKEN_DEFAULT_DACL dacl = { ULongToPtr( dacl32->DefaultDacl ) }; + + return NtSetInformationToken( handle, class, &dacl, sizeof(dacl) ); + } + else return STATUS_INFO_LENGTH_MISMATCH; + + default: + FIXME( "unsupported class %u\n", class ); + return STATUS_NOT_IMPLEMENTED; + } +} + + +/********************************************************************** + * wow64_NtSetSecurityObject + */ +NTSTATUS WINAPI wow64_NtSetSecurityObject( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + SECURITY_INFORMATION info = get_ulong( &args ); + SECURITY_DESCRIPTOR *sd32 = get_ptr( &args ); + + SECURITY_DESCRIPTOR sd; + + return NtSetSecurityObject( handle, info, secdesc_32to64( &sd, sd32 )); +} \ No newline at end of file diff --git a/dll/wow64/wine/struct32.h b/dll/wow64/wine/struct32.h new file mode 100644 index 0000000000000..f121285fc5df2 --- /dev/null +++ b/dll/wow64/wine/struct32.h @@ -0,0 +1,958 @@ +/* + * 32-bit version of ntdll structures + * + * Copyright 2021 Alexandre Julliard + * Copyright 2025 Marcin Jabłoński + * + * 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 + */ + +#ifndef __WOW64_STRUCT32_H +#define __WOW64_STRUCT32_H + +typedef struct +{ + ULONG Length; + ULONG RootDirectory; + ULONG ObjectName; + ULONG Attributes; + ULONG SecurityDescriptor; + ULONG SecurityQualityOfService; +} OBJECT_ATTRIBUTES32; + +typedef struct +{ + union + { + NTSTATUS Status; + ULONG Pointer; + }; + ULONG Information; +} IO_STATUS_BLOCK32; + +typedef struct +{ + UNICODE_STRING32 Name; +} OBJECT_NAME_INFORMATION32; + +typedef struct +{ + UNICODE_STRING32 TypeName; + ULONG TotalNumberOfObjects; + ULONG TotalNumberOfHandles; + ULONG TotalPagedPoolUsage; + ULONG TotalNonPagedPoolUsage; + ULONG TotalNamePoolUsage; + ULONG TotalHandleTableUsage; + ULONG HighWaterNumberOfObjects; + ULONG HighWaterNumberOfHandles; + ULONG HighWaterPagedPoolUsage; + ULONG HighWaterNonPagedPoolUsage; + ULONG HighWaterNamePoolUsage; + ULONG HighWaterHandleTableUsage; + ULONG InvalidAttributes; + GENERIC_MAPPING GenericMapping; + ULONG ValidAccessMask; + BOOLEAN SecurityRequired; + BOOLEAN MaintainHandleCount; +#ifndef __REACTOS__ + UCHAR TypeIndex; + CHAR ReservedByte; +#endif + ULONG PoolType; + ULONG DefaultPagedPoolCharge; + ULONG DefaultNonPagedPoolCharge; +} OBJECT_TYPE_INFORMATION32; + +#ifndef __REACTOS__ +/* FIXME: this does not compile */ +typedef struct +{ + CONTEXT_CHUNK All; + CONTEXT_CHUNK Legacy; + CONTEXT_CHUNK XState; +} CONTEXT_EX32; +#endif + +typedef struct +{ + UNICODE_STRING32 ObjectName; + UNICODE_STRING32 ObjectTypeName; +} DIRECTORY_BASIC_INFORMATION32; + +typedef struct +{ + ULONG CompletionPort; + ULONG CompletionKey; +} FILE_COMPLETION_INFORMATION32; + +typedef struct +{ + ULONG CompletionKey; + ULONG CompletionValue; + IO_STATUS_BLOCK32 IoStatusBlock; +} FILE_IO_COMPLETION_INFORMATION32; + +typedef struct +{ + union + { + BOOLEAN ReplaceIfExists; + ULONG Flags; + }; + ULONG RootDirectory; + ULONG FileNameLength; + WCHAR FileName[1]; +} FILE_RENAME_INFORMATION32; + +typedef struct +{ + ULONG Mask; + WORD Group; + WORD Reserved[3]; +} GROUP_AFFINITY32; + +typedef struct +{ + DWORD NumberOfAssignedProcesses; + DWORD NumberOfProcessIdsInList; + ULONG ProcessIdList[1]; +} JOBOBJECT_BASIC_PROCESS_ID_LIST32; + +typedef struct +{ + LARGE_INTEGER PerProcessUserTimeLimit; + LARGE_INTEGER PerJobUserTimeLimit; + DWORD LimitFlags; + ULONG MinimumWorkingSetSize; + ULONG MaximumWorkingSetSize; + DWORD ActiveProcessLimit; + ULONG Affinity; + DWORD PriorityClass; + DWORD SchedulingClass; +} JOBOBJECT_BASIC_LIMIT_INFORMATION32; + +typedef struct +{ + JOBOBJECT_BASIC_LIMIT_INFORMATION32 BasicLimitInformation; + IO_COUNTERS IoInfo; + ULONG ProcessMemoryLimit; + ULONG JobMemoryLimit; + ULONG PeakProcessMemoryUsed; + ULONG PeakJobMemoryUsed; +} JOBOBJECT_EXTENDED_LIMIT_INFORMATION32; + +typedef struct +{ + ULONG CompletionKey; + LONG CompletionPort; +} JOBOBJECT_ASSOCIATE_COMPLETION_PORT32; + +typedef struct +{ + ULONG BaseAddress; + ULONG AllocationBase; + DWORD AllocationProtect; + ULONG RegionSize; + DWORD State; + DWORD Protect; + DWORD Type; +} MEMORY_BASIC_INFORMATION32; + +typedef struct +{ + ULONG AllocationBase; + ULONG AllocationProtect; + ULONG RegionType; + ULONG RegionSize; + ULONG CommitSize; + ULONG PartitionId; + ULONG NodePreference; +} MEMORY_REGION_INFORMATION32; + +typedef struct +{ + UNICODE_STRING32 SectionFileName; +} MEMORY_SECTION_NAME32; + +typedef union +{ + ULONG Flags; + struct { + ULONG Valid : 1; + ULONG ShareCount : 3; + ULONG Win32Protection : 11; + ULONG Shared : 1; + ULONG Node : 6; + ULONG Locked : 1; + ULONG LargePage : 1; + }; +} MEMORY_WORKING_SET_EX_BLOCK32; + +typedef struct +{ + ULONG VirtualAddress; + MEMORY_WORKING_SET_EX_BLOCK32 VirtualAttributes; +} MEMORY_WORKING_SET_EX_INFORMATION32; + +typedef struct +{ + ULONG ImageBase; + ULONG SizeOfImage; + union + { + ULONG ImageFlags; + struct + { + ULONG ImagePartialMap : 1; + ULONG ImageNotExecutable : 1; + ULONG ImageSigningLevel : 4; + ULONG Reserved : 26; + }; + }; +} MEMORY_IMAGE_INFORMATION32; + +typedef struct +{ + NTSTATUS ExitStatus; + ULONG PebBaseAddress; + ULONG AffinityMask; + LONG BasePriority; + ULONG UniqueProcessId; + ULONG InheritedFromUniqueProcessId; +} PROCESS_BASIC_INFORMATION32; + +typedef struct +{ + ULONG ReserveSize; + ULONG ZeroBits; + ULONG StackBase; +} PROCESS_STACK_ALLOCATION_INFORMATION32; + +typedef struct +{ + ULONG PreferredNode; + ULONG Reserved0; + ULONG Reserved1; + ULONG Reserved2; + PROCESS_STACK_ALLOCATION_INFORMATION32 AllocInfo; +} PROCESS_STACK_ALLOCATION_INFORMATION_EX32; + +#ifndef __REACTOS__ +/* FIXME: this does not compile */ +typedef struct +{ + ULONG Size; + PS_CREATE_STATE State; + union + { + struct + { + ULONG InitFlags; + ACCESS_MASK AdditionalFileAccess; + } InitState; + struct + { + ULONG FileHandle; + } FailSection; + struct + { + USHORT DllCharacteristics; + } ExeFormat; + struct + { + ULONG IFEOKey; + } ExeName; + struct + { + ULONG OutputFlags; + ULONG FileHandle; + ULONG SectionHandle; + ULONGLONG UserProcessParametersNative; + ULONG UserProcessParametersWow64; + ULONG CurrentParameterFlags; + ULONGLONG PebAddressNative; + ULONG PebAddressWow64; + ULONGLONG ManifestAddress; + ULONG ManifestSize; + } SuccessState; + }; +} PS_CREATE_INFO32; +#endif + +typedef struct +{ + ULONG Attribute; + ULONG Size; + ULONG Value; + ULONG ReturnLength; +} PS_ATTRIBUTE32; + +typedef struct +{ + ULONG TotalLength; + PS_ATTRIBUTE32 Attributes[1]; +} PS_ATTRIBUTE_LIST32; + +typedef struct +{ + ULONG Section; + ULONG MappedBaseAddress; + ULONG ImageBaseAddress; + ULONG ImageSize; + ULONG Flags; + USHORT LoadOrderIndex; + USHORT InitOrderIndex; + USHORT LoadCount; + USHORT NameOffset; +#ifndef __REACTOS__ +/* FIXME: this does not compile */ + BYTE Name[MAXIMUM_FILENAME_LENGTH]; +#else + BYTE Name[MAX_PATH /* ??? */ ]; +#endif +} RTL_PROCESS_MODULE_INFORMATION32; + +typedef struct +{ + ULONG ModulesCount; + RTL_PROCESS_MODULE_INFORMATION32 Modules[1]; +} RTL_PROCESS_MODULES32; + +typedef struct +{ + USHORT NextOffset; + RTL_PROCESS_MODULE_INFORMATION32 BaseInfo; + ULONG ImageCheckSum; + ULONG TimeDateStamp; + ULONG DefaultBase; +} RTL_PROCESS_MODULE_INFORMATION_EX32; + +typedef struct +{ + ULONG BaseAddress; + ULONG Attributes; + LARGE_INTEGER Size; +} SECTION_BASIC_INFORMATION32; + +typedef struct +{ + ULONG TransferAddress; + ULONG ZeroBits; + ULONG MaximumStackSize; + ULONG CommittedStackSize; + ULONG SubSystemType; + USHORT MinorSubsystemVersion; + USHORT MajorSubsystemVersion; +#ifndef __REACTOS__ + USHORT MajorOperatingSystemVersion; + USHORT MinorOperatingSystemVersion; +#else + ULONG GpValue; +#endif + USHORT ImageCharacteristics; + USHORT DllCharacteristics; + USHORT Machine; + BOOLEAN ImageContainsCode; +#if (NTDDI_VERSION >= NTDDI_LONGHORN) + UCHAR ImageFlags; +#else + BOOLEAN Spare1; +#endif + ULONG LoaderFlags; + ULONG ImageFileSize; +#if (NTDDI_VERSION >= NTDDI_LONGHORN) + ULONG CheckSum; +#else + ULONG Reserved[1]; +#endif +} SECTION_IMAGE_INFORMATION32; + +typedef struct +{ + ULONG Sid; + DWORD Attributes; +} SID_AND_ATTRIBUTES32; + +typedef struct +{ + SID_AND_ATTRIBUTES32 Label; +} TOKEN_MANDATORY_LABEL32; + +typedef struct +{ + ULONG DefaultDacl; +} TOKEN_DEFAULT_DACL32; + +typedef struct +{ + DWORD GroupCount; + SID_AND_ATTRIBUTES32 Groups[1]; +} TOKEN_GROUPS32; + +typedef struct +{ + ULONG Owner; +} TOKEN_OWNER32; + +typedef struct +{ + ULONG PrimaryGroup; +} TOKEN_PRIMARY_GROUP32; + +typedef struct +{ + SID_AND_ATTRIBUTES32 User; +} TOKEN_USER32; + +#ifndef __REACTOS__ +/* FIXME: this does not compile */ +typedef struct +{ + NTSTATUS ExitStatus; + ULONG TebBaseAddress; + CLIENT_ID32 ClientId; + ULONG AffinityMask; + LONG Priority; + LONG BasePriority; +} THREAD_BASIC_INFORMATION32; +#endif + +typedef struct +{ + UNICODE_STRING32 ThreadName; +} THREAD_NAME_INFORMATION32; + +typedef struct +{ + ULONG PeakVirtualSize; + ULONG VirtualSize; + ULONG PageFaultCount; + ULONG PeakWorkingSetSize; + ULONG WorkingSetSize; + ULONG QuotaPeakPagedPoolUsage; + ULONG QuotaPagedPoolUsage; + ULONG QuotaPeakNonPagedPoolUsage; + ULONG QuotaNonPagedPoolUsage; + ULONG PagefileUsage; + ULONG PeakPagefileUsage; +} VM_COUNTERS32; + +typedef struct +{ + ULONG PeakVirtualSize; + ULONG VirtualSize; + ULONG PageFaultCount; + ULONG PeakWorkingSetSize; + ULONG WorkingSetSize; + ULONG QuotaPeakPagedPoolUsage; + ULONG QuotaPagedPoolUsage; + ULONG QuotaPeakNonPagedPoolUsage; + ULONG QuotaNonPagedPoolUsage; + ULONG PagefileUsage; + ULONG PeakPagefileUsage; + ULONG PrivateUsage; +} VM_COUNTERS_EX32; + +typedef struct +{ + DBG_STATE NewState; + CLIENT_ID32 AppClientId; + union + { + struct + { + EXCEPTION_RECORD32 ExceptionRecord; + ULONG FirstChance; + } Exception; + struct + { + ULONG HandleToThread; + struct + { + ULONG SubSystemKey; + ULONG StartAddress; + } NewThread; + } CreateThread; + struct + { + ULONG HandleToProcess; + ULONG HandleToThread; + struct + { + ULONG SubSystemKey; + ULONG FileHandle; + ULONG BaseOfImage; + ULONG DebugInfoFileOffset; + ULONG DebugInfoSize; + struct + { + ULONG SubSystemKey; + ULONG StartAddress; + } InitialThread; + } NewProcess; + } CreateProcessInfo; + struct + { + NTSTATUS ExitStatus; + } ExitProcess, ExitThread; + struct + { + ULONG FileHandle; + ULONG BaseOfDll; + ULONG DebugInfoFileOffset; + ULONG DebugInfoSize; + ULONG NamePointer; + } LoadDll; + struct + { + ULONG BaseAddress; + } UnloadDll; + } StateInfo; +} DBGUI_WAIT_STATE_CHANGE32; + +typedef struct +{ + ULONG unknown; + ULONG KeMaximumIncrement; + ULONG PageSize; + ULONG MmNumberOfPhysicalPages; + ULONG MmLowestPhysicalPage; + ULONG MmHighestPhysicalPage; + ULONG AllocationGranularity; + ULONG LowestUserAddress; + ULONG HighestUserAddress; + ULONG ActiveProcessorsAffinityMask; + BYTE NumberOfProcessors; +} SYSTEM_BASIC_INFORMATION32; + +typedef struct +{ + ULONG CurrentSize; + ULONG PeakSize; + ULONG PageFaultCount; + ULONG MinimumWorkingSet; + ULONG MaximumWorkingSet; + ULONG CurrentSizeIncludingTransitionInPages; + ULONG PeakSizeIncludingTransitionInPages; + ULONG TransitionRePurposeCount; + ULONG Flags; +} SYSTEM_CACHE_INFORMATION32; + +typedef struct +{ + ULONG ProcessId; + UNICODE_STRING32 ImageName; +} SYSTEM_PROCESS_ID_INFORMATION32; + +typedef struct +{ + ULONG OwnerPid; + BYTE ObjectType; + BYTE HandleFlags; + USHORT HandleValue; + ULONG ObjectPointer; + ULONG AccessMask; +} SYSTEM_HANDLE_ENTRY32; + +typedef struct +{ + ULONG Count; + SYSTEM_HANDLE_ENTRY32 Handle[1]; +} SYSTEM_HANDLE_INFORMATION32; + +typedef struct +{ + ULONG RegistryQuotaAllowed; + ULONG RegistryQuotaUsed; +#ifndef __REACTOS__ + ULONG Reserved1; +#else + ULONG PagedPoolSize; +#endif +} SYSTEM_REGISTRY_QUOTA_INFORMATION32; + +typedef struct +{ + ULONG Object; + ULONG UniqueProcessId; + ULONG HandleValue; + ULONG GrantedAccess; + USHORT CreatorBackTraceIndex; + USHORT ObjectTypeIndex; + ULONG HandleAttributes; + ULONG Reserved; +} SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX32; + +typedef struct +{ + ULONG NumberOfHandles; + ULONG Reserved; + SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX32 Handles[1]; +} SYSTEM_HANDLE_INFORMATION_EX32; + +typedef struct +{ + ULONG ProcessorMask; + LOGICAL_PROCESSOR_RELATIONSHIP Relationship; + union + { + struct + { + BYTE Flags; + } ProcessorCore; + struct + { + DWORD NodeNumber; + } NumaNode; + CACHE_DESCRIPTOR Cache; + ULONGLONG Reserved[2]; + }; +} SYSTEM_LOGICAL_PROCESSOR_INFORMATION32; + +typedef struct +{ + BYTE Flags; + BYTE EfficiencyClass; + BYTE Reserved[20]; + WORD GroupCount; + GROUP_AFFINITY32 GroupMask[ANYSIZE_ARRAY]; +} PROCESSOR_RELATIONSHIP32; + +typedef struct +{ + DWORD NodeNumber; + BYTE Reserved[20]; + GROUP_AFFINITY32 GroupMask; +} NUMA_NODE_RELATIONSHIP32; + +typedef struct +{ + BYTE Level; + BYTE Associativity; + WORD LineSize; + DWORD CacheSize; + PROCESSOR_CACHE_TYPE Type; + BYTE Reserved[20]; + GROUP_AFFINITY32 GroupMask; +} CACHE_RELATIONSHIP32; + +typedef struct +{ + BYTE MaximumProcessorCount; + BYTE ActiveProcessorCount; + BYTE Reserved[38]; + ULONG ActiveProcessorMask; +} PROCESSOR_GROUP_INFO32; + +typedef struct +{ + WORD MaximumGroupCount; + WORD ActiveGroupCount; + BYTE Reserved[20]; + PROCESSOR_GROUP_INFO32 GroupInfo[ANYSIZE_ARRAY]; +} GROUP_RELATIONSHIP32; + +typedef struct +{ + LOGICAL_PROCESSOR_RELATIONSHIP Relationship; + DWORD Size; + union + { + PROCESSOR_RELATIONSHIP32 Processor; + NUMA_NODE_RELATIONSHIP32 NumaNode; + CACHE_RELATIONSHIP32 Cache; + GROUP_RELATIONSHIP32 Group; + }; +} SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX32; + +typedef struct +{ + LARGE_INTEGER KernelTime; + LARGE_INTEGER UserTime; + LARGE_INTEGER CreateTime; + DWORD dwTickCount; + ULONG StartAddress; + CLIENT_ID32 ClientId; + DWORD dwCurrentPriority; + DWORD dwBasePriority; + DWORD dwContextSwitches; + DWORD dwThreadState; + DWORD dwWaitReason; + DWORD dwUnknown; +} SYSTEM_THREAD_INFORMATION32; + +typedef struct +{ + ULONG NextEntryOffset; + DWORD dwThreadCount; + LARGE_INTEGER WorkingSetPrivateSize; + ULONG HardFaultCount; + ULONG NumberOfThreadsHighWatermark; + ULONGLONG CycleTime; + LARGE_INTEGER CreationTime; + LARGE_INTEGER UserTime; + LARGE_INTEGER KernelTime; + UNICODE_STRING32 ProcessName; + DWORD dwBasePriority; + ULONG UniqueProcessId; + ULONG ParentProcessId; + ULONG HandleCount; + ULONG SessionId; + ULONG UniqueProcessKey; + VM_COUNTERS_EX32 vmCounters; + IO_COUNTERS ioCounters; + SYSTEM_THREAD_INFORMATION32 ti[1]; +} SYSTEM_PROCESS_INFORMATION32; + +typedef struct +{ + SYSTEM_THREAD_INFORMATION32 ThreadInfo; + ULONG StackBase; + ULONG StackLimit; + ULONG Win32StartAddress; + ULONG TebBase; + ULONG Reserved2; + ULONG Reserved3; + ULONG Reserved4; +} SYSTEM_EXTENDED_THREAD_INFORMATION32; + +typedef struct +{ + ULONG VirtualAddress; + ULONG NumberOfBytes; +} MEMORY_RANGE_ENTRY32; + +typedef struct +{ + ULONG LowestStartingAddress; + ULONG HighestEndingAddress; + ULONG Alignment; +} MEM_ADDRESS_REQUIREMENTS32; + +#ifndef __REACTOS__ +/* FIXME: this does not compile */ +typedef struct DECLSPEC_ALIGN(8) +{ + struct + { + DWORD64 Type : MEM_EXTENDED_PARAMETER_TYPE_BITS; + DWORD64 Reserved : 64 - MEM_EXTENDED_PARAMETER_TYPE_BITS; + }; + union + { + DWORD64 ULong64; + ULONG Pointer; + ULONG Size; + ULONG Handle; + ULONG ULong; + }; +} MEM_EXTENDED_PARAMETER32; +#endif + +typedef struct +{ + ULONG Token; + ULONG Thread; +} PROCESS_ACCESS_TOKEN32; + +typedef struct +{ + ULONG PagedPoolLimit; + ULONG NonPagedPoolLimit; + ULONG MinimumWorkingSetSize; + ULONG MaximumWorkingSetSize; + ULONG PagefileLimit; + LARGE_INTEGER TimeLimit; +} QUOTA_LIMITS32; + +#ifdef __REACTOS__ + +typedef struct _CPTABLEINFO32 +{ + USHORT CodePage; + USHORT MaximumCharacterSize; + USHORT DefaultChar; + USHORT UniDefaultChar; + USHORT TransDefaultChar; + USHORT TransUniDefaultChar; + USHORT DBCSCodePage; + UCHAR LeadByte[MAXIMUM_LEADBYTES]; + ULONG MultiByteTable; + ULONG WideCharTable; + ULONG DBCSRanges; + ULONG DBCSOffsets; +} CPTABLEINFO32, *PCPTABLEINFO32; + +typedef struct _NLSTABLEINFO32 +{ + CPTABLEINFO32 OemTableInfo; + CPTABLEINFO32 AnsiTableInfo; + ULONG UpperCaseTable; + ULONG LowerCaseTable; +} NLSTABLEINFO32, *PNLSTABLEINFO32; + +typedef struct _PORT_VIEW32 +{ + ULONG Length; + ULONG SectionHandle; + ULONG SectionOffset; + ULONG ViewSize; + ULONG ViewBase; + ULONG ViewRemoteBase; +} PORT_VIEW32, *PPORT_VIEW32; + +typedef struct _REMOTE_PORT_VIEW32 +{ + ULONG Length; + ULONG ViewSize; + ULONG ViewBase; +} REMOTE_PORT_VIEW32, *PREMOTE_PORT_VIEW32; + +typedef struct _CURDIR32 +{ + UNICODE_STRING32 DosPath; + ULONG Handle; +} CURDIR32, *PCURDIR32; + +typedef struct _RTL_DRIVE_LETTER_CURDIR32 +{ + USHORT Flags; + USHORT Length; + ULONG TimeStamp; + UNICODE_STRING32 DosPath; +} RTL_DRIVE_LETTER_CURDIR32, *PRTL_DRIVE_LETTER_CURDIR32; + +typedef struct _RTL_USER_PROCESS_PARAMETERS32 +{ + ULONG MaximumLength; + ULONG Length; + ULONG Flags; + ULONG DebugFlags; + ULONG ConsoleHandle; + ULONG ConsoleFlags; + ULONG StandardInput; + ULONG StandardOutput; + ULONG StandardError; + CURDIR32 CurrentDirectory; + UNICODE_STRING32 DllPath; + UNICODE_STRING32 ImagePathName; + UNICODE_STRING32 CommandLine; + ULONG Environment; + ULONG StartingX; + ULONG StartingY; + ULONG CountX; + ULONG CountY; + ULONG CountCharsX; + ULONG CountCharsY; + ULONG FillAttribute; + ULONG WindowFlags; + ULONG ShowWindowFlags; + UNICODE_STRING32 WindowTitle; + UNICODE_STRING32 DesktopInfo; + UNICODE_STRING32 ShellInfo; + UNICODE_STRING32 RuntimeData; + RTL_DRIVE_LETTER_CURDIR32 CurrentDirectories[RTL_MAX_DRIVE_LETTERS]; +#if (NTDDI_VERSION >= NTDDI_LONGHORN) + ULONG EnvironmentSize; +#endif +#if (NTDDI_VERSION >= NTDDI_WIN7) + ULONG EnvironmentVersion; +#endif +} RTL_USER_PROCESS_PARAMETERS32, *PRTL_USER_PROCESS_PARAMETERS32; + +typedef struct _PROCESS_DEVICEMAP_INFORMATION32 +{ + union + { + struct + { + ULONG DirectoryHandle; + } Set; + struct + { + ULONG DriveMap; + UCHAR DriveType[32]; + } Query; + }; +} PROCESS_DEVICEMAP_INFORMATION32, *PPROCESS_DEVICEMAP_INFORMATION32; + +typedef struct _CURDIR64 +{ + UNICODE_STRING64 DosPath; + UINT64 Handle; +} CURDIR64, *PCURDIR64; + +typedef struct _RTL_DRIVE_LETTER_CURDIR64 +{ + USHORT Flags; + USHORT Length; + ULONG TimeStamp; + UNICODE_STRING64 DosPath; +} RTL_DRIVE_LETTER_CURDIR64, *PRTL_DRIVE_LETTER_CURDIR64; + +typedef struct _RTL_USER_PROCESS_PARAMETERS64 +{ + ULONG MaximumLength; + ULONG Length; + ULONG Flags; + ULONG DebugFlags; + UINT64 ConsoleHandle; + ULONG ConsoleFlags; + UINT64 StandardInput; + UINT64 StandardOutput; + UINT64 StandardError; + CURDIR64 CurrentDirectory; + UNICODE_STRING64 DllPath; + UNICODE_STRING64 ImagePathName; + UNICODE_STRING64 CommandLine; + UINT64 Environment; + ULONG StartingX; + ULONG StartingY; + ULONG CountX; + ULONG CountY; + ULONG CountCharsX; + ULONG CountCharsY; + ULONG FillAttribute; + ULONG WindowFlags; + ULONG ShowWindowFlags; + UNICODE_STRING64 WindowTitle; + UNICODE_STRING64 DesktopInfo; + UNICODE_STRING64 ShellInfo; + UNICODE_STRING64 RuntimeData; + RTL_DRIVE_LETTER_CURDIR64 CurrentDirectories[RTL_MAX_DRIVE_LETTERS]; +#if (NTDDI_VERSION >= NTDDI_LONGHORN) + UINT64 EnvironmentSize; +#endif +#if (NTDDI_VERSION >= NTDDI_WIN7) + UINT64 EnvironmentVersion; +#endif +} RTL_USER_PROCESS_PARAMETERS64, *PRTL_USER_PROCESS_PARAMETERS64; + +#ifdef _WIN64 +C_ASSERT(sizeof(RTL_USER_PROCESS_PARAMETERS64) == sizeof(RTL_USER_PROCESS_PARAMETERS)); +#else +C_ASSERT(sizeof(RTL_USER_PROCESS_PARAMETERS32) == sizeof(RTL_USER_PROCESS_PARAMETERS)); +#endif + +typedef struct _APPHELP_CACHE_SERVICE_LOOKUP32 +{ + UNICODE_STRING32 ImageName; + ULONG ImageHandle; +} APPHELP_CACHE_SERVICE_LOOKUP32, *PAPPHELP_CACHE_SERVICE_LOOKUP32; + +#endif /* __REACTOS__ */ + +#endif /* __WOW64_STRUCT32_H */ diff --git a/dll/wow64/wine/sync.c b/dll/wow64/wine/sync.c new file mode 100644 index 0000000000000..f1d533f2b9ed0 --- /dev/null +++ b/dll/wow64/wine/sync.c @@ -0,0 +1,1963 @@ +/* + * WoW64 synchronization objects and functions + * + * Copyright 2021 Alexandre Julliard + * Copyright 2025 Marcin Jabłoński + * + * 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 + */ + +#ifndef __REACTOS__ +#include + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "winnt.h" +#include "winternl.h" +#include "wow64_private.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wow); +#else +#include "ros_wow64_private.h" + +#define objattr_32to64 objattr_32to64_redirect + +#endif + + +static void put_object_type_info( OBJECT_TYPE_INFORMATION32 *info32, const OBJECT_TYPE_INFORMATION *info ) +{ + if (info->TypeName.Length) + { + memcpy( info32 + 1, info->TypeName.Buffer, info->TypeName.Length + sizeof(WCHAR) ); + info32->TypeName.Length = info->TypeName.Length; + info32->TypeName.MaximumLength = info->TypeName.Length + sizeof(WCHAR); + info32->TypeName.Buffer = PtrToUlong( info32 + 1 ); + } + else memset( &info32->TypeName, 0, sizeof(info32->TypeName) ); + info32->TotalNumberOfObjects = info->TotalNumberOfObjects; + info32->TotalNumberOfHandles = info->TotalNumberOfHandles; + info32->TotalPagedPoolUsage = info->TotalPagedPoolUsage; + info32->TotalNonPagedPoolUsage = info->TotalNonPagedPoolUsage; + info32->TotalNamePoolUsage = info->TotalNamePoolUsage; + info32->TotalHandleTableUsage = info->TotalHandleTableUsage; + info32->HighWaterNumberOfObjects = info->HighWaterNumberOfObjects; + info32->HighWaterNumberOfHandles = info->HighWaterNumberOfHandles; + info32->HighWaterPagedPoolUsage = info->HighWaterPagedPoolUsage; + info32->HighWaterNonPagedPoolUsage = info->HighWaterNonPagedPoolUsage; + info32->HighWaterNamePoolUsage = info->HighWaterNamePoolUsage; + info32->HighWaterHandleTableUsage = info->HighWaterHandleTableUsage; + info32->InvalidAttributes = info->InvalidAttributes; + info32->GenericMapping = info->GenericMapping; + info32->ValidAccessMask = info->ValidAccessMask; + info32->SecurityRequired = info->SecurityRequired; + info32->MaintainHandleCount = info->MaintainHandleCount; +#ifndef __REACTOS__ + info32->TypeIndex = info->TypeIndex; + info32->ReservedByte = info->ReservedByte; +#endif + info32->PoolType = info->PoolType; + info32->DefaultPagedPoolCharge = info->DefaultPagedPoolCharge; + info32->DefaultNonPagedPoolCharge = info->DefaultNonPagedPoolCharge; +} + + +static JOBOBJECT_BASIC_LIMIT_INFORMATION *job_basic_limit_info_32to64( JOBOBJECT_BASIC_LIMIT_INFORMATION *out, + const JOBOBJECT_BASIC_LIMIT_INFORMATION32 *in ) +{ + out->PerProcessUserTimeLimit = in->PerProcessUserTimeLimit; + out->PerJobUserTimeLimit = in->PerJobUserTimeLimit; + out->LimitFlags = in->LimitFlags; + out->MinimumWorkingSetSize = in->MinimumWorkingSetSize; + out->MaximumWorkingSetSize = in->MaximumWorkingSetSize; + out->ActiveProcessLimit = in->ActiveProcessLimit; + out->Affinity = in->Affinity; + out->PriorityClass = in->PriorityClass; + out->SchedulingClass = in->SchedulingClass; + return out; +} + + +static void put_job_basic_limit_info( JOBOBJECT_BASIC_LIMIT_INFORMATION32 *info32, + const JOBOBJECT_BASIC_LIMIT_INFORMATION *info ) +{ + info32->PerProcessUserTimeLimit = info->PerProcessUserTimeLimit; + info32->PerJobUserTimeLimit = info->PerJobUserTimeLimit; + info32->LimitFlags = info->LimitFlags; + info32->MinimumWorkingSetSize = info->MinimumWorkingSetSize; + info32->MaximumWorkingSetSize = info->MaximumWorkingSetSize; + info32->ActiveProcessLimit = info->ActiveProcessLimit; + info32->Affinity = info->Affinity; + info32->PriorityClass = info->PriorityClass; + info32->SchedulingClass = info->SchedulingClass; +} + + +void put_section_image_info( SECTION_IMAGE_INFORMATION32 *info32, const SECTION_IMAGE_INFORMATION *info ) +{ + if (info->Machine == IMAGE_FILE_MACHINE_AMD64 || info->Machine == IMAGE_FILE_MACHINE_ARM64) + { + info32->TransferAddress = 0x81231234; /* sic */ + info32->MaximumStackSize = 0x100000; + info32->CommittedStackSize = 0x10000; + } + else + { + info32->TransferAddress = PtrToUlong( info->TransferAddress ); + info32->MaximumStackSize = info->MaximumStackSize; + info32->CommittedStackSize = info->CommittedStackSize; + } + + info32->ZeroBits = info->ZeroBits; + info32->SubSystemType = info->SubSystemType; +#ifndef __REACTOS__ + info32->MinorSubsystemVersion = info->MinorSubsystemVersion; + info32->MajorSubsystemVersion = info->MajorSubsystemVersion; + info32->MajorOperatingSystemVersion = info->MajorOperatingSystemVersion; + info32->MinorOperatingSystemVersion = info->MinorOperatingSystemVersion; + info32->ImageCharacteristics = info->ImageCharacteristics; + info32->DllCharacteristics = info->DllCharacteristics; + info32->Machine = info->Machine; + info32->ImageContainsCode = info->ImageContainsCode; + info32->ImageFlags = info->ImageFlags; + info32->LoaderFlags = info->LoaderFlags; + info32->ImageFileSize = info->ImageFileSize; + info32->CheckSum = info->CheckSum; +#else + info32->MinorSubsystemVersion = info->SubSystemMinorVersion; + info32->MajorSubsystemVersion = info->SubSystemMajorVersion; + info32->GpValue = info->GpValue; + info32->ImageCharacteristics = info->ImageCharacteristics; + info32->DllCharacteristics = info->DllCharacteristics; + info32->Machine = info->Machine; + info32->ImageContainsCode = info->ImageContainsCode; +#if (NTDDI_VERSION >= NTDDI_LONGHORN) + info32->ImageFlags = info->ImageFlags; +#endif + info32->LoaderFlags = info->LoaderFlags; + info32->ImageFileSize = info->ImageFileSize; +#endif +} + + +#ifndef __REACTOS__ +/********************************************************************** + * wow64_NtAcceptConnectPort + */ +NTSTATUS WINAPI wow64_NtAcceptConnectPort( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + ULONG id = get_ulong( &args ); + LPC_MESSAGE *msg = get_ptr( &args ); + BOOLEAN accept = get_ulong( &args ); + LPC_SECTION_WRITE *write = get_ptr( &args ); + LPC_SECTION_READ *read = get_ptr( &args ); + + FIXME( "%p %lu %p %u %p %p: stub\n", handle_ptr, id, msg, accept, write, read ); + return STATUS_NOT_IMPLEMENTED; +} +#endif + + +/********************************************************************** + * wow64_NtCancelTimer + */ +NTSTATUS WINAPI wow64_NtCancelTimer( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + BOOLEAN *state = get_ptr( &args ); + + return NtCancelTimer( handle, state ); +} + + +/********************************************************************** + * wow64_NtClearEvent + */ +NTSTATUS WINAPI wow64_NtClearEvent( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + + return NtClearEvent( handle ); +} + + +#ifndef __REACTOS__ +/********************************************************************** + * wow64_NtCompareObjects + */ +NTSTATUS WINAPI wow64_NtCompareObjects( UINT *args ) +{ + HANDLE first = get_handle( &args ); + HANDLE second = get_handle( &args ); + + return NtCompareObjects( first, second ); +} +#endif + + +/********************************************************************** + * wow64_NtCompleteConnectPort + */ +NTSTATUS WINAPI wow64_NtCompleteConnectPort( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + + return NtCompleteConnectPort( handle ); +} + + +#ifndef __REACTOS__ +/********************************************************************** + * wow64_NtConnectPort + */ +NTSTATUS WINAPI wow64_NtConnectPort( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + UNICODE_STRING32 *name32 = get_ptr( &args ); + SECURITY_QUALITY_OF_SERVICE *qos = get_ptr( &args ); + LPC_SECTION_WRITE *write = get_ptr( &args ); + LPC_SECTION_READ *read = get_ptr( &args ); + ULONG *max_len = get_ptr( &args ); + void *info = get_ptr( &args ); + ULONG *info_len = get_ptr( &args ); + + FIXME( "%p %p %p %p %p %p %p %p: stub\n", + handle_ptr, name32, qos, write, read, max_len, info, info_len ); + return STATUS_NOT_IMPLEMENTED; +} +#endif + + +/********************************************************************** + * wow64_NtCreateDebugObject + */ +NTSTATUS WINAPI wow64_NtCreateDebugObject( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + ULONG flags = get_ulong( &args ); + + struct object_attr64 attr; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtCreateDebugObject( &handle, access, objattr_32to64( &attr, attr32 ), flags ); + put_handle( handle_ptr, handle ); + return status; +} + + +/********************************************************************** + * wow64_NtCreateDirectoryObject + */ +NTSTATUS WINAPI wow64_NtCreateDirectoryObject( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + + struct object_attr64 attr; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtCreateDirectoryObject( &handle, access, objattr_32to64( &attr, attr32 )); + put_handle( handle_ptr, handle ); + return status; +} + + +/********************************************************************** + * wow64_NtCreateEvent + */ +NTSTATUS WINAPI wow64_NtCreateEvent( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + EVENT_TYPE type = get_ulong( &args ); + BOOLEAN state = get_ulong( &args ); + + struct object_attr64 attr; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtCreateEvent( &handle, access, objattr_32to64( &attr, attr32 ), type, state ); + put_handle( handle_ptr, handle ); + return status; +} + + +/********************************************************************** + * wow64_NtCreateIoCompletion + */ +NTSTATUS WINAPI wow64_NtCreateIoCompletion( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + ULONG threads = get_ulong( &args ); + + struct object_attr64 attr; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtCreateIoCompletion( &handle, access, objattr_32to64( &attr, attr32 ), threads ); + put_handle( handle_ptr, handle ); + return status; +} + + +/********************************************************************** + * wow64_NtCreateJobObject + */ +NTSTATUS WINAPI wow64_NtCreateJobObject( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + + struct object_attr64 attr; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtCreateJobObject( &handle, access, objattr_32to64( &attr, attr32 )); + put_handle( handle_ptr, handle ); + return status; +} + + +/********************************************************************** + * wow64_NtCreateKeyedEvent + */ +NTSTATUS WINAPI wow64_NtCreateKeyedEvent( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + ULONG flags = get_ulong( &args ); + + struct object_attr64 attr; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtCreateKeyedEvent( &handle, access, objattr_32to64( &attr, attr32 ), flags ); + put_handle( handle_ptr, handle ); + return status; +} + + +/********************************************************************** + * wow64_NtCreateMutant + */ +NTSTATUS WINAPI wow64_NtCreateMutant( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + BOOLEAN owned = get_ulong( &args ); + + struct object_attr64 attr; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtCreateMutant( &handle, access, objattr_32to64( &attr, attr32 ), owned ); + put_handle( handle_ptr, handle ); + return status; +} + + +/********************************************************************** + * wow64_NtCreatePort + */ +NTSTATUS WINAPI wow64_NtCreatePort( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + ULONG info_len = get_ulong( &args ); + ULONG data_len = get_ulong( &args ); +#ifndef __REACTOS__ + ULONG *reserved = get_ptr( &args ); +#else + ULONG reserved = get_ulong( &args ); +#endif + + struct object_attr64 attr; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtCreatePort( &handle, objattr_32to64( &attr, attr32 ), info_len, data_len, reserved ); + put_handle( handle_ptr, handle ); + return status; +} + + +/********************************************************************** + * wow64_NtCreateSection + */ +NTSTATUS WINAPI wow64_NtCreateSection( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); +#ifndef __REACTOS__ + const LARGE_INTEGER *size = get_ptr( &args ); +#else + LARGE_INTEGER *size = get_ptr( &args ); +#endif + ULONG protect = get_ulong( &args ); + ULONG flags = get_ulong( &args ); + HANDLE file = get_handle( &args ); + + struct object_attr64 attr; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtCreateSection( &handle, access, objattr_32to64( &attr, attr32 ), size, protect, flags, file ); + put_handle( handle_ptr, handle ); + return status; +} + + +/********************************************************************** + * wow64_NtCreateSemaphore + */ +NTSTATUS WINAPI wow64_NtCreateSemaphore( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + LONG initial = get_ulong( &args ); + LONG max = get_ulong( &args ); + + struct object_attr64 attr; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtCreateSemaphore( &handle, access, objattr_32to64( &attr, attr32 ), initial, max ); + put_handle( handle_ptr, handle ); + return status; +} + + +/********************************************************************** + * wow64_NtCreateSymbolicLinkObject + */ +NTSTATUS WINAPI wow64_NtCreateSymbolicLinkObject( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + UNICODE_STRING32 *target32 = get_ptr( &args ); + + struct object_attr64 attr; + UNICODE_STRING target; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtCreateSymbolicLinkObject( &handle, access, objattr_32to64( &attr, attr32 ), + unicode_str_32to64( &target, target32 )); + put_handle( handle_ptr, handle ); + return status; +} + + +/********************************************************************** + * wow64_NtCreateTimer + */ +NTSTATUS WINAPI wow64_NtCreateTimer( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + TIMER_TYPE type = get_ulong( &args ); + + struct object_attr64 attr; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtCreateTimer( &handle, access, objattr_32to64( &attr, attr32 ), type ); + put_handle( handle_ptr, handle ); + return status; +} + + +/********************************************************************** + * wow64_NtDebugContinue + */ +NTSTATUS WINAPI wow64_NtDebugContinue( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + CLIENT_ID32 *id32 = get_ptr( &args ); + NTSTATUS status = get_ulong( &args ); + + CLIENT_ID id; + + return NtDebugContinue( handle, client_id_32to64( &id, id32 ), status ); +} + + +/********************************************************************** + * wow64_NtDelayExecution + */ +NTSTATUS WINAPI wow64_NtDelayExecution( UINT *args ) +{ + BOOLEAN alertable = get_ulong( &args ); +#ifndef __REACTOS__ + const LARGE_INTEGER *timeout = get_ptr( &args ); +#else + LARGE_INTEGER *timeout = get_ptr( &args ); +#endif + + return NtDelayExecution( alertable, timeout ); +} + + +/********************************************************************** + * wow64_NtDuplicateObject + */ +NTSTATUS WINAPI wow64_NtDuplicateObject( UINT *args ) +{ + HANDLE source_process = get_handle( &args ); + HANDLE source_handle = get_handle( &args ); + HANDLE dest_process = get_handle( &args ); + ULONG *handle_ptr = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args ); + ULONG attributes = get_ulong( &args ); + ULONG options = get_ulong( &args ); + + HANDLE handle = 0; + NTSTATUS status; + + if (handle_ptr) *handle_ptr = 0; + status = NtDuplicateObject( source_process, source_handle, dest_process, &handle, + access, attributes, options ); + if (handle_ptr) put_handle( handle_ptr, handle ); + return status; +} + + +#ifndef __REACTOS__ +/********************************************************************** + * wow64_NtListenPort + */ +NTSTATUS WINAPI wow64_NtListenPort( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + LPC_MESSAGE *msg = get_ptr( &args ); + + FIXME( "%p %p: stub\n", handle, msg ); + return STATUS_NOT_IMPLEMENTED; +} +#endif + + +/********************************************************************** + * wow64_NtMakePermanentObject + */ +NTSTATUS WINAPI wow64_NtMakePermanentObject( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + + return NtMakePermanentObject( handle ); +} + + +/********************************************************************** + * wow64_NtMakeTemporaryObject + */ +NTSTATUS WINAPI wow64_NtMakeTemporaryObject( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + + return NtMakeTemporaryObject( handle ); +} + + +/********************************************************************** + * wow64_NtOpenDirectoryObject + */ +NTSTATUS WINAPI wow64_NtOpenDirectoryObject( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + + struct object_attr64 attr; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtOpenDirectoryObject( &handle, access, objattr_32to64( &attr, attr32 )); + put_handle( handle_ptr, handle ); + return status; +} + + +/********************************************************************** + * wow64_NtOpenEvent + */ +NTSTATUS WINAPI wow64_NtOpenEvent( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + + struct object_attr64 attr; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtOpenEvent( &handle, access, objattr_32to64( &attr, attr32 )); + put_handle( handle_ptr, handle ); + return status; +} + + +/********************************************************************** + * wow64_NtOpenIoCompletion + */ +NTSTATUS WINAPI wow64_NtOpenIoCompletion( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + + struct object_attr64 attr; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtOpenIoCompletion( &handle, access, objattr_32to64( &attr, attr32 )); + put_handle( handle_ptr, handle ); + return status; +} + + +/********************************************************************** + * wow64_NtOpenJobObject + */ +NTSTATUS WINAPI wow64_NtOpenJobObject( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + + struct object_attr64 attr; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtOpenJobObject( &handle, access, objattr_32to64( &attr, attr32 )); + put_handle( handle_ptr, handle ); + return status; +} + + +/********************************************************************** + * wow64_NtOpenKeyedEvent + */ +NTSTATUS WINAPI wow64_NtOpenKeyedEvent( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + + struct object_attr64 attr; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtOpenKeyedEvent( &handle, access, objattr_32to64( &attr, attr32 )); + put_handle( handle_ptr, handle ); + return status; +} + + +/********************************************************************** + * wow64_NtOpenMutant + */ +NTSTATUS WINAPI wow64_NtOpenMutant( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + + struct object_attr64 attr; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtOpenMutant( &handle, access, objattr_32to64( &attr, attr32 )); + put_handle( handle_ptr, handle ); + return status; +} + + +/********************************************************************** + * wow64_NtOpenSection + */ +NTSTATUS WINAPI wow64_NtOpenSection( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + + struct object_attr64 attr; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + + status = NtOpenSection( &handle, access, objattr_32to64( &attr, attr32 )); + + put_handle( handle_ptr, handle ); + return status; +} + + +/********************************************************************** + * wow64_NtOpenSemaphore + */ +NTSTATUS WINAPI wow64_NtOpenSemaphore( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + + struct object_attr64 attr; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtOpenSemaphore( &handle, access, objattr_32to64( &attr, attr32 )); + put_handle( handle_ptr, handle ); + return status; +} + + +/********************************************************************** + * wow64_NtOpenSymbolicLinkObject + */ +NTSTATUS WINAPI wow64_NtOpenSymbolicLinkObject( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + + struct object_attr64 attr; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtOpenSymbolicLinkObject( &handle, access, objattr_32to64( &attr, attr32 )); + put_handle( handle_ptr, handle ); + return status; +} + + +/********************************************************************** + * wow64_NtOpenTimer + */ +NTSTATUS WINAPI wow64_NtOpenTimer( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + + struct object_attr64 attr; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtOpenTimer( &handle, access, objattr_32to64( &attr, attr32 )); + put_handle( handle_ptr, handle ); + return status; +} + + +/********************************************************************** + * wow64_NtPulseEvent + */ +NTSTATUS WINAPI wow64_NtPulseEvent( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + LONG *prev_state = get_ptr( &args ); + + return NtPulseEvent( handle, prev_state ); +} + +/* FIXME */ +#ifndef __REACTOS__ +/********************************************************************** + * wow64_NtQueryDirectoryObject + */ +NTSTATUS WINAPI wow64_NtQueryDirectoryObject( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + DIRECTORY_BASIC_INFORMATION32 *info32 = get_ptr( &args ); + ULONG size32 = get_ulong( &args ); + BOOLEAN single_entry = get_ulong( &args ); + BOOLEAN restart = get_ulong( &args ); + ULONG *context = get_ptr( &args ); + ULONG *retlen = get_ptr( &args ); + ULONG retsize; + + NTSTATUS status; + DIRECTORY_BASIC_INFORMATION *info; + ULONG size = size32 + 2 * sizeof(*info) - 2 * sizeof(*info32); + + info = Wow64AllocateTemp( size ); + status = NtQueryDirectoryObject( handle, info, size, single_entry, restart, context, &retsize ); + if (NT_SUCCESS(status)) + { + unsigned int i, count, used_size, used_count, strpool_head, validsize = min( size, retsize ); + + used_count = 0; + used_size = sizeof(*info32); /* "null terminator" entry */ + for (count = 0; + sizeof(*info) * (count + 1) <= validsize && info[count].ObjectName.MaximumLength; + count++) + { + unsigned int entry_size = sizeof(*info32) + + info[count].ObjectName.MaximumLength + + info[count].ObjectTypeName.MaximumLength; + + if (used_size + entry_size <= size32) + { + used_count++; + used_size += entry_size; + } + } + + if (used_count != count) + { + ERR( "64bit dir list (%u+%lu bytes, %u entries) truncated for 32bit buffer (%u+%lu bytes, %u entries)\n", + validsize, size - validsize, count, used_size, size32 - min( size32, used_size ), used_count ); + + if (!status) status = STATUS_MORE_ENTRIES; + *context -= count - used_count; + } + + /* + * Avoid making strpool_head a pointer, since it can point beyond end + * of the buffer. Out-of-bounds pointers trigger undefined behavior + * just by existing, even when they are never dereferenced. + */ + strpool_head = sizeof(*info32) * (used_count + 1); /* after the "null terminator" entry */ + for (i = 0; i < used_count; i++) + { + info32[i].ObjectName.Buffer = PtrToUlong( (char *)info32 + strpool_head ); + info32[i].ObjectName.Length = info[i].ObjectName.Length; + info32[i].ObjectName.MaximumLength = info[i].ObjectName.MaximumLength; + memcpy( (char *)info32 + strpool_head, info[i].ObjectName.Buffer, info[i].ObjectName.MaximumLength ); + strpool_head += info[i].ObjectName.MaximumLength; + + info32[i].ObjectTypeName.Buffer = PtrToUlong( (char *)info32 + strpool_head ); + info32[i].ObjectTypeName.Length = info[i].ObjectTypeName.Length; + info32[i].ObjectTypeName.MaximumLength = info[i].ObjectTypeName.MaximumLength; + memcpy( (char *)info32 + strpool_head, info[i].ObjectTypeName.Buffer, info[i].ObjectTypeName.MaximumLength ); + strpool_head += info[i].ObjectTypeName.MaximumLength; + } + + if (size32 >= sizeof(*info32)) + memset( &info32[used_count], 0, sizeof(info32[used_count]) ); + + if (retlen) *retlen = strpool_head; + } + else if (retlen && status == STATUS_BUFFER_TOO_SMALL) + *retlen = retsize - 2 * sizeof(*info) + 2 * sizeof(*info32); + else if (retlen && status == STATUS_NO_MORE_ENTRIES) + *retlen = 0; + return status; +} +#endif + + +/********************************************************************** + * wow64_NtQueryEvent + */ +NTSTATUS WINAPI wow64_NtQueryEvent( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + EVENT_INFORMATION_CLASS class = get_ulong( &args ); + void *info = get_ptr( &args ); + ULONG len = get_ulong( &args ); + ULONG *retlen = get_ptr( &args ); + + return NtQueryEvent( handle, class, info, len, retlen ); +} + + +/********************************************************************** + * wow64_NtQueryInformationJobObject + */ +NTSTATUS WINAPI wow64_NtQueryInformationJobObject( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + JOBOBJECTINFOCLASS class = get_ulong( &args ); + void *ptr = get_ptr( &args ); + ULONG len = get_ulong( &args ); + ULONG *retlen = get_ptr( &args ); + + NTSTATUS status; + + switch (class) + { + case JobObjectBasicAccountingInformation: /* JOBOBJECT_BASIC_ACCOUNTING_INFORMATION */ + return NtQueryInformationJobObject( handle, class, ptr, len, retlen ); + + case JobObjectBasicLimitInformation: /* JOBOBJECT_BASIC_LIMIT_INFORMATION */ + if (len >= sizeof(JOBOBJECT_BASIC_LIMIT_INFORMATION32)) + { + JOBOBJECT_BASIC_LIMIT_INFORMATION32 *info32 = ptr; + JOBOBJECT_BASIC_LIMIT_INFORMATION info; + + status = NtQueryInformationJobObject( handle, class, &info, sizeof(info), NULL ); + if (!status) put_job_basic_limit_info( info32, &info ); + if (retlen) *retlen = sizeof(*info32); + return status; + } + else return STATUS_INFO_LENGTH_MISMATCH; + + case JobObjectBasicProcessIdList: /* JOBOBJECT_BASIC_PROCESS_ID_LIST */ + if (len >= sizeof(JOBOBJECT_BASIC_PROCESS_ID_LIST32)) + { + JOBOBJECT_BASIC_PROCESS_ID_LIST32 *info32 = ptr; + JOBOBJECT_BASIC_PROCESS_ID_LIST *info; + ULONG i, count, size; + + count = (len - offsetof( JOBOBJECT_BASIC_PROCESS_ID_LIST32, ProcessIdList )) / sizeof(info32->ProcessIdList[0]); + size = offsetof( JOBOBJECT_BASIC_PROCESS_ID_LIST, ProcessIdList[count] ); + info = Wow64AllocateTemp( size ); + status = NtQueryInformationJobObject( handle, class, info, size, NULL ); + if (!status) + { + info32->NumberOfAssignedProcesses = info->NumberOfAssignedProcesses; + info32->NumberOfProcessIdsInList = info->NumberOfProcessIdsInList; + for (i = 0; i < info->NumberOfProcessIdsInList; i++) + info32->ProcessIdList[i] = info->ProcessIdList[i]; + if (retlen) *retlen = offsetof( JOBOBJECT_BASIC_PROCESS_ID_LIST32, ProcessIdList[i] ); + } + return status; + } + else return STATUS_INFO_LENGTH_MISMATCH; + + case JobObjectExtendedLimitInformation: /* JOBOBJECT_EXTENDED_LIMIT_INFORMATION */ + if (len >= sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION32)) + { + JOBOBJECT_EXTENDED_LIMIT_INFORMATION32 *info32 = ptr; + JOBOBJECT_EXTENDED_LIMIT_INFORMATION info; + + status = NtQueryInformationJobObject( handle, class, &info, sizeof(info), NULL ); + if (!status) + { + put_job_basic_limit_info( &info32->BasicLimitInformation, &info.BasicLimitInformation ); + info32->IoInfo = info.IoInfo; + info32->ProcessMemoryLimit = info.ProcessMemoryLimit; + info32->JobMemoryLimit = info.JobMemoryLimit; + info32->PeakProcessMemoryUsed = info.PeakProcessMemoryUsed; + info32->PeakJobMemoryUsed = info.PeakJobMemoryUsed; + } + if (retlen) *retlen = sizeof(*info32); + return status; + } + else return STATUS_INFO_LENGTH_MISMATCH; + + default: + if (class >= MaxJobObjectInfoClass) return STATUS_INVALID_PARAMETER; + FIXME( "unsupported class %u\n", class ); + return STATUS_NOT_IMPLEMENTED; + } +} + + +/********************************************************************** + * wow64_NtQueryIoCompletion + */ +NTSTATUS WINAPI wow64_NtQueryIoCompletion( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + IO_COMPLETION_INFORMATION_CLASS class = get_ulong( &args ); + void *info = get_ptr( &args ); + ULONG len = get_ulong( &args ); + ULONG *retlen = get_ptr( &args ); + + return NtQueryIoCompletion( handle, class, info, len, retlen ); +} + + +/********************************************************************** + * wow64_NtQueryMutant + */ +NTSTATUS WINAPI wow64_NtQueryMutant( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + MUTANT_INFORMATION_CLASS class = get_ulong( &args ); + void *info = get_ptr( &args ); + ULONG len = get_ulong( &args ); + ULONG *retlen = get_ptr( &args ); + + return NtQueryMutant( handle, class, info, len, retlen ); +} + + +/********************************************************************** + * wow64_NtQueryObject + */ +NTSTATUS WINAPI wow64_NtQueryObject( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + OBJECT_INFORMATION_CLASS class = get_ulong( &args ); + void *ptr = get_ptr( &args ); + ULONG len = get_ulong( &args ); + ULONG *retlen = get_ptr( &args ); + + NTSTATUS status; + ULONG ret_size; + + switch (class) + { + case ObjectBasicInformation: /* OBJECT_BASIC_INFORMATION */ + case ObjectHandleFlagInformation: /* OBJECT_HANDLE_FLAG_INFORMATION */ + return NtQueryObject( handle, class, ptr, len, retlen ); + + case ObjectNameInformation: /* OBJECT_NAME_INFORMATION */ + { + ULONG size = len + sizeof(OBJECT_NAME_INFORMATION) - sizeof(OBJECT_NAME_INFORMATION32); + OBJECT_NAME_INFORMATION32 *info32 = ptr; + OBJECT_NAME_INFORMATION *info = Wow64AllocateTemp( size ); + + if (!(status = NtQueryObject( handle, class, info, size, &ret_size ))) + { + if (len >= sizeof(*info32) + info->Name.MaximumLength) + { + if (info->Name.Length) + { + memcpy( info32 + 1, info->Name.Buffer, info->Name.Length + sizeof(WCHAR) ); + info32->Name.Length = info->Name.Length; + info32->Name.MaximumLength = info->Name.Length + sizeof(WCHAR); + info32->Name.Buffer = PtrToUlong( info32 + 1 ); + } + else memset( &info32->Name, 0, sizeof(info32->Name) ); + } + else status = STATUS_INFO_LENGTH_MISMATCH; + if (retlen) *retlen = sizeof(*info32) + info->Name.MaximumLength; + } + else if (status == STATUS_INFO_LENGTH_MISMATCH || status == STATUS_BUFFER_OVERFLOW) + { + if (retlen) *retlen = ret_size - sizeof(*info) + sizeof(*info32); + } + return status; + } + + case ObjectTypeInformation: /* OBJECT_TYPE_INFORMATION */ + { + ULONG_PTR buffer[(sizeof(OBJECT_TYPE_INFORMATION) + 64) / sizeof(ULONG_PTR)]; + OBJECT_TYPE_INFORMATION *info = (OBJECT_TYPE_INFORMATION *)buffer; + OBJECT_TYPE_INFORMATION32 *info32 = ptr; + + if (!(status = NtQueryObject( handle, class, info, sizeof(buffer), NULL ))) + { + if (len >= sizeof(*info32) + info->TypeName.MaximumLength) + put_object_type_info( info32, info ); + else + status = STATUS_INFO_LENGTH_MISMATCH; + if (retlen) *retlen = sizeof(*info32) + info->TypeName.Length + sizeof(WCHAR); + } + return status; + } + + case ObjectTypesInformation: /* OBJECT_TYPES_INFORMATION */ + { +#ifndef __REACTOS__ + OBJECT_TYPES_INFORMATION *info, *info32 = ptr; +#else + OBJECT_ALL_TYPES_INFORMATION *info, *info32 = ptr; +#endif + /* assume at most 32 types, with an average 16-char name */ + ULONG ret_size, size = 32 * (sizeof(OBJECT_TYPE_INFORMATION) + 16 * sizeof(WCHAR)); + + info = Wow64AllocateTemp( size ); + if (!(status = NtQueryObject( handle, class, info, size, &ret_size ))) + { + OBJECT_TYPE_INFORMATION *type; + OBJECT_TYPE_INFORMATION32 *type32; + ULONG align = TYPE_ALIGNMENT( OBJECT_TYPE_INFORMATION ) - 1; + ULONG align32 = TYPE_ALIGNMENT( OBJECT_TYPE_INFORMATION32 ) - 1; + ULONG i, pos = (sizeof(*info) + align) & ~align, pos32 = (sizeof(*info32) + align32) & ~align32; + + if (pos32 <= len) info32->NumberOfTypes = info->NumberOfTypes; + for (i = 0; i < info->NumberOfTypes; i++) + { + type = (OBJECT_TYPE_INFORMATION *)((char *)info + pos); + type32 = (OBJECT_TYPE_INFORMATION32 *)((char *)ptr + pos32); + pos += sizeof(*type) + ((type->TypeName.MaximumLength + align) & ~align); + pos32 += sizeof(*type32) + ((type->TypeName.MaximumLength + align32) & ~align32); + if (pos32 <= len) put_object_type_info( type32, type ); + } + if (pos32 > len) status = STATUS_INFO_LENGTH_MISMATCH; + if (retlen) *retlen = pos32; + } + return status; + } + + default: + FIXME( "unsupported class %u\n", class ); + return STATUS_NOT_IMPLEMENTED; + } +} + + +/********************************************************************** + * wow64_NtQueryPerformanceCounter + */ +NTSTATUS WINAPI wow64_NtQueryPerformanceCounter( UINT *args ) +{ + LARGE_INTEGER *counter = get_ptr( &args ); + LARGE_INTEGER *frequency = get_ptr( &args ); + + return NtQueryPerformanceCounter( counter, frequency ); +} + + +/********************************************************************** + * wow64_NtQuerySection + */ +NTSTATUS WINAPI wow64_NtQuerySection( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + SECTION_INFORMATION_CLASS class = get_ulong( &args ); + void *ptr = get_ptr( &args ); + SIZE_T size = get_ulong( &args ); + ULONG *ret_ptr = get_ptr( &args ); + + NTSTATUS status; + SIZE_T ret_size = 0; + + switch (class) + { + case SectionBasicInformation: + { + SECTION_BASIC_INFORMATION info; + SECTION_BASIC_INFORMATION32 *info32 = ptr; + + if (size < sizeof(*info32)) return STATUS_INFO_LENGTH_MISMATCH; + if (!(status = NtQuerySection( handle, class, &info, sizeof(info), &ret_size ))) + { + info32->BaseAddress = PtrToUlong( info.BaseAddress ); + info32->Attributes = info.Attributes; + info32->Size = info.Size; + ret_size = sizeof(*info32); + } + break; + } + case SectionImageInformation: + { + SECTION_IMAGE_INFORMATION info; + SECTION_IMAGE_INFORMATION32 *info32 = ptr; + + if (size < sizeof(*info32)) return STATUS_INFO_LENGTH_MISMATCH; + if (!(status = NtQuerySection( handle, class, &info, sizeof(info), &ret_size ))) + { + put_section_image_info( info32, &info ); + ret_size = sizeof(*info32); + } + break; + } + default: + FIXME( "class %u not implemented\n", class ); + return STATUS_NOT_IMPLEMENTED; + } + put_size( ret_ptr, ret_size ); + return status; +} + + +/********************************************************************** + * wow64_NtQuerySemaphore + */ +NTSTATUS WINAPI wow64_NtQuerySemaphore( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + SEMAPHORE_INFORMATION_CLASS class = get_ulong( &args ); + void *info = get_ptr( &args ); + ULONG len = get_ulong( &args ); + ULONG *retlen = get_ptr( &args ); + + return NtQuerySemaphore( handle, class, info, len, retlen ); +} + + +/********************************************************************** + * wow64_NtQuerySymbolicLinkObject + */ +NTSTATUS WINAPI wow64_NtQuerySymbolicLinkObject( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + UNICODE_STRING32 *target32 = get_ptr( &args ); + ULONG *retlen = get_ptr( &args ); + + UNICODE_STRING target; + NTSTATUS status; + + status = NtQuerySymbolicLinkObject( handle, unicode_str_32to64( &target, target32 ), retlen ); + if (!status) target32->Length = target.Length; + return status; +} + + +/********************************************************************** + * wow64_NtQueryTimer + */ +NTSTATUS WINAPI wow64_NtQueryTimer( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + TIMER_INFORMATION_CLASS class = get_ulong( &args ); + void *info = get_ptr( &args ); + ULONG len = get_ulong( &args ); + ULONG *retlen = get_ptr( &args ); + + return NtQueryTimer( handle, class, info, len, retlen ); +} + + +/********************************************************************** + * wow64_NtQueryTimerResolution + */ +NTSTATUS WINAPI wow64_NtQueryTimerResolution( UINT *args ) +{ + ULONG *min_res = get_ptr( &args ); + ULONG *max_res = get_ptr( &args ); + ULONG *current_res = get_ptr( &args ); + + return NtQueryTimerResolution( min_res, max_res, current_res ); +} + + +/********************************************************************** + * wow64_NtRegisterThreadTerminatePort + */ +NTSTATUS WINAPI wow64_NtRegisterThreadTerminatePort( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + + return NtRegisterThreadTerminatePort( handle ); +} + + +/********************************************************************** + * wow64_NtReleaseKeyedEvent + */ +NTSTATUS WINAPI wow64_NtReleaseKeyedEvent( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + void *key = get_ptr( &args ); + BOOLEAN alertable = get_ulong( &args ); +#ifndef __REACTOS__ + const LARGE_INTEGER *timeout = get_ptr( &args ); +#else + LARGE_INTEGER *timeout = get_ptr( &args ); +#endif + + return NtReleaseKeyedEvent( handle, key, alertable, timeout ); +} + + +/********************************************************************** + * wow64_NtReleaseMutant + */ +NTSTATUS WINAPI wow64_NtReleaseMutant( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + LONG *prev_count = get_ptr( &args ); + + return NtReleaseMutant( handle, prev_count ); +} + + +/********************************************************************** + * wow64_NtReleaseSemaphore + */ +NTSTATUS WINAPI wow64_NtReleaseSemaphore( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + ULONG count = get_ulong( &args ); + ULONG *previous = get_ptr( &args ); + + return NtReleaseSemaphore( handle, count, previous ); +} + + +/********************************************************************** + * wow64_NtReplyWaitReceivePort + */ +NTSTATUS WINAPI wow64_NtReplyWaitReceivePort( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + ULONG *id = get_ptr( &args ); +#ifndef __REACTOS__ + LPC_MESSAGE *reply = get_ptr( &args ); + LPC_MESSAGE *msg = get_ptr( &args ); + + FIXME( "%p %p %p %p: stub\n", handle, id, reply, msg ); + return STATUS_NOT_IMPLEMENTED; +#else + PVOID reply = get_ptr( &args ); + PVOID msg = get_ptr( &args ); + + PVOID id64 = ULongToPtr(*id); + NTSTATUS status; + + status = NtReplyWaitReceivePort(handle, &id64, reply, msg); + *id = PtrToUlong(id64); + return status; +#endif +} + + +/********************************************************************** + * wow64_NtRequestWaitReplyPort + */ +NTSTATUS WINAPI wow64_NtRequestWaitReplyPort( UINT *args ) +{ + HANDLE handle = get_handle( &args ); +#ifndef __REACTOS__ + LPC_MESSAGE *msg_in = get_ptr( &args ); + LPC_MESSAGE *msg_out = get_ptr( &args ); + + FIXME( "%p %p %p: stub\n", handle, msg_in, msg_out ); + return STATUS_NOT_IMPLEMENTED; +#else + PVOID msg_in = get_ptr( &args ); + PVOID msg_out = get_ptr( &args ); + return NtRequestWaitReplyPort(handle, msg_in, msg_out); +#endif +} + + +/********************************************************************** + * wow64_NtResetEvent + */ +NTSTATUS WINAPI wow64_NtResetEvent( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + LONG *prev_state = get_ptr( &args ); + + return NtResetEvent( handle, prev_state ); +} + + +/********************************************************************** + * wow64_NtSecureConnectPort + */ +NTSTATUS WINAPI wow64_NtSecureConnectPort( UINT *args ) +{ +#ifndef __REACTOS__ + ULONG *handle_ptr = get_ptr( &args ); + UNICODE_STRING32 *name32 = get_ptr( &args ); + SECURITY_QUALITY_OF_SERVICE *qos = get_ptr( &args ); + LPC_SECTION_WRITE *write = get_ptr( &args ); + SID *sid = get_ptr( &args ); + LPC_SECTION_READ *read = get_ptr( &args ); + ULONG *max_len = get_ptr( &args ); + void *info = get_ptr( &args ); + ULONG *info_len = get_ptr( &args ); + + FIXME( "%p %p %p %p %p %p %p %p %p: stub\n", + handle_ptr, name32, qos, write, sid, read, max_len, info, info_len ); + return STATUS_NOT_IMPLEMENTED; +#else + /* + OUT PHANDLE PortHandle, + IN PUNICODE_STRING PortName, + IN PSECURITY_QUALITY_OF_SERVICE SecurityQos, + IN OUT PPORT_VIEW ClientView OPTIONAL, + IN PSID ServerSid OPTIONAL, + IN OUT PREMOTE_PORT_VIEW ServerView OPTIONAL, + OUT PULONG MaxMessageLength OPTIONAL, + IN OUT PVOID ConnectionInformation OPTIONAL, + IN OUT PULONG ConnectionInformationLength OPTIONAL + */ + + ULONG *PortHandle = get_ptr(&args); + UNICODE_STRING32 *PortName32 = get_ptr(&args); + PSECURITY_QUALITY_OF_SERVICE SecurityQos = get_ptr(&args); + PORT_VIEW *ClientView = get_ptr(&args); + SID* ServerSid = get_ptr(&args); + REMOTE_PORT_VIEW *SecureView = get_ptr(&args); + PULONG MaxMessageLength = get_ptr(&args); + PVOID ConnectionInformation = get_ptr(&args); + PULONG ConnectionInformationLength = get_ptr(&args); + + NTSTATUS status; + + HANDLE result; + WCHAR buffer[MAX_PATH]; + UNICODE_STRING portName; + portName.MaximumLength = sizeof(buffer); + portName.Buffer = buffer; + + unicode_str_32to64(&portName, PortName32); + + DPRINT("Port name %ls\n", portName.Buffer); + + status = NtSecureConnectPort(&result, + &portName, + SecurityQos, + ClientView, + ServerSid, + SecureView, + MaxMessageLength, + ConnectionInformation, + ConnectionInformationLength); + + *PortHandle = HandleToULong(result); + + DPRINT("SecureConnectPort: %lX\n", status); + return status; +#endif +} + + + +/********************************************************************** + * wow64_NtSetEvent + */ +NTSTATUS WINAPI wow64_NtSetEvent( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + LONG *prev_state = get_ptr( &args ); + + return NtSetEvent( handle, prev_state ); +} + + +/********************************************************************** + * wow64_NtSetInformationDebugObject + */ +NTSTATUS WINAPI wow64_NtSetInformationDebugObject( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + DEBUGOBJECTINFOCLASS class = get_ulong( &args ); + void *ptr = get_ptr( &args ); + ULONG len = get_ulong( &args ); + ULONG *retlen = get_ptr( &args ); + + return NtSetInformationDebugObject( handle, class, ptr, len, retlen ); +} + + +/********************************************************************** + * wow64_NtSetInformationJobObject + */ +NTSTATUS WINAPI wow64_NtSetInformationJobObject( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + JOBOBJECTINFOCLASS class = get_ulong( &args ); + void *ptr = get_ptr( &args ); + ULONG len = get_ulong( &args ); + + switch (class) + { + case JobObjectBasicLimitInformation: /* JOBOBJECT_BASIC_LIMIT_INFORMATION */ + if (len == sizeof(JOBOBJECT_BASIC_LIMIT_INFORMATION32)) + { + JOBOBJECT_BASIC_LIMIT_INFORMATION info; + + return NtSetInformationJobObject( handle, class, job_basic_limit_info_32to64( &info, ptr ), + sizeof(info) ); + } + else return STATUS_INVALID_PARAMETER; + + case JobObjectBasicUIRestrictions: + FIXME( "unsupported class JobObjectBasicUIRestrictions\n" ); + return STATUS_SUCCESS; + + case JobObjectAssociateCompletionPortInformation: /* JOBOBJECT_ASSOCIATE_COMPLETION_PORT */ + if (len == sizeof(JOBOBJECT_ASSOCIATE_COMPLETION_PORT32)) + { + JOBOBJECT_ASSOCIATE_COMPLETION_PORT32 *info32 = ptr; + JOBOBJECT_ASSOCIATE_COMPLETION_PORT info; + + info.CompletionKey = ULongToPtr( info32->CompletionKey ); + info.CompletionPort = LongToHandle( info32->CompletionPort ); + return NtSetInformationJobObject( handle, class, &info, sizeof(info) ); + } + else return STATUS_INVALID_PARAMETER; + + case JobObjectExtendedLimitInformation: /* JOBOBJECT_EXTENDED_LIMIT_INFORMATION */ + if (len == sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION32)) + { + JOBOBJECT_EXTENDED_LIMIT_INFORMATION32 *info32 = ptr; + JOBOBJECT_EXTENDED_LIMIT_INFORMATION info; + + info.IoInfo = info32->IoInfo; + info.ProcessMemoryLimit = info32->ProcessMemoryLimit; + info.JobMemoryLimit = info32->JobMemoryLimit; + info.PeakProcessMemoryUsed = info32->PeakProcessMemoryUsed; + info.PeakJobMemoryUsed = info32->PeakJobMemoryUsed; + return NtSetInformationJobObject( handle, class, + job_basic_limit_info_32to64( &info.BasicLimitInformation, + &info32->BasicLimitInformation ), + sizeof(info) ); + } + else return STATUS_INVALID_PARAMETER; + + default: + if (class >= MaxJobObjectInfoClass) return STATUS_INVALID_PARAMETER; + FIXME( "unsupported class %u\n", class ); + return STATUS_NOT_IMPLEMENTED; + } +} + + +/********************************************************************** + * wow64_NtSetInformationObject + */ +NTSTATUS WINAPI wow64_NtSetInformationObject( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + OBJECT_INFORMATION_CLASS class = get_ulong( &args ); + void *ptr = get_ptr( &args ); + ULONG len = get_ulong( &args ); + + switch (class) + { + case ObjectHandleFlagInformation: /* OBJECT_HANDLE_FLAG_INFORMATION */ + return NtSetInformationObject( handle, class, ptr, len ); + + default: + FIXME( "unsupported class %u\n", class ); + return STATUS_NOT_IMPLEMENTED; + } +} + + +/********************************************************************** + * wow64_NtSetIoCompletion + */ +NTSTATUS WINAPI wow64_NtSetIoCompletion( UINT *args ) +{ + HANDLE handle = get_handle( &args ); +#ifndef __REACTOS__ + ULONG_PTR key = get_ulong( &args ); + ULONG_PTR value = get_ulong( &args ); +#else + PVOID key = get_ptr( &args ); + PVOID value = get_ptr( &args ); +#endif + NTSTATUS status = get_ulong( &args ); + SIZE_T count = get_ulong( &args ); + + return NtSetIoCompletion( handle, key, value, status, count ); +} + + +#ifndef __REACTOS__ +/********************************************************************** + * wow64_NtSetIoCompletionEx + */ +NTSTATUS WINAPI wow64_NtSetIoCompletionEx( UINT *args ) +{ + HANDLE completion_handle = get_handle( &args ); + HANDLE completion_reserve_handle = get_handle( &args ); + ULONG_PTR key = get_ulong( &args ); + ULONG_PTR value = get_ulong( &args ); + NTSTATUS status = get_ulong( &args ); + SIZE_T count = get_ulong( &args ); + + return NtSetIoCompletionEx( completion_handle, completion_reserve_handle, key, value, status, count ); +} +#endif + + +/********************************************************************** + * wow64_NtSetTimer + */ +NTSTATUS WINAPI wow64_NtSetTimer( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + LARGE_INTEGER *when = get_ptr( &args ); + ULONG apc = get_ulong( &args ); + ULONG apc_param = get_ulong( &args ); + BOOLEAN resume = get_ulong( &args ); + ULONG period = get_ulong( &args ); + BOOLEAN *state = get_ptr( &args ); + + return NtSetTimer( handle, when, apc_32to64( apc ), apc_param_32to64( apc, apc_param ), + resume, period, state ); +} + + +/********************************************************************** + * wow64_NtSetTimerResolution + */ +NTSTATUS WINAPI wow64_NtSetTimerResolution( UINT *args ) +{ + ULONG res = get_ulong( &args ); + BOOLEAN set = get_ulong( &args ); + ULONG *current_res = get_ptr( &args ); + + return NtSetTimerResolution( res, set, current_res ); +} + + +/********************************************************************** + * wow64_NtSignalAndWaitForSingleObject + */ +NTSTATUS WINAPI wow64_NtSignalAndWaitForSingleObject( UINT *args ) +{ + HANDLE signal = get_handle( &args ); + HANDLE wait = get_handle( &args ); + BOOLEAN alertable = get_ulong( &args ); +#ifndef __REACTOS__ + const LARGE_INTEGER *timeout = get_ptr( &args ); +#else + LARGE_INTEGER *timeout = get_ptr( &args ); +#endif + + return NtSignalAndWaitForSingleObject( signal, wait, alertable, timeout ); +} + + +/********************************************************************** + * wow64_NtTerminateJobObject + */ +NTSTATUS WINAPI wow64_NtTerminateJobObject( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + NTSTATUS status = get_ulong( &args ); + + return NtTerminateJobObject( handle, status ); +} + + +/********************************************************************** + * wow64_NtTestAlert + */ +NTSTATUS WINAPI wow64_NtTestAlert( UINT *args ) +{ + return NtTestAlert(); +} + + +#ifndef __REACTOS__ +/********************************************************************** + * wow64_NtTraceControl + */ +NTSTATUS WINAPI wow64_NtTraceControl( UINT *args ) +{ + ULONG code = get_ulong( &args ); + void *inbuf = get_ptr( &args ); + ULONG inbuf_len = get_ulong( &args ); + void *outbuf = get_ptr( &args ); + ULONG outbuf_len = get_ulong( &args ); + ULONG *size = get_ptr( &args ); + + return NtTraceControl( code, inbuf, inbuf_len, outbuf, outbuf_len, size ); +} + + +/********************************************************************** + * wow64_NtWaitForAlertByThreadId + */ +NTSTATUS WINAPI wow64_NtWaitForAlertByThreadId( UINT *args ) +{ + const void *address = get_ptr( &args ); + const LARGE_INTEGER *timeout = get_ptr( &args ); + + return NtWaitForAlertByThreadId( address, timeout ); +} +#endif + + +/* helper to wow64_NtWaitForDebugEvent; retrieve machine from PE image */ +static NTSTATUS get_image_machine( HANDLE handle, USHORT *machine ) +{ + IMAGE_DOS_HEADER dos_hdr; + IMAGE_NT_HEADERS nt_hdr; + IO_STATUS_BLOCK iosb; + LARGE_INTEGER offset; + FILE_POSITION_INFORMATION pos_info; + NTSTATUS status; + + offset.QuadPart = 0; + status = NtReadFile( handle, NULL, NULL, NULL, + &iosb, &dos_hdr, sizeof(dos_hdr), &offset, NULL ); + if (!status) + { + offset.QuadPart = dos_hdr.e_lfanew; + status = NtReadFile( handle, NULL, NULL, NULL, &iosb, + &nt_hdr, FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader), &offset, NULL ); + if (!status) + *machine = nt_hdr.FileHeader.Machine; + /* Reset file pos at beginning of file */ + pos_info.CurrentByteOffset.QuadPart = 0; + NtSetInformationFile( handle, &iosb, &pos_info, sizeof(pos_info), FilePositionInformation ); + } + return status; +} + +/* helper to wow64_NtWaitForDebugEvent; only pass debug events for current machine */ +static BOOL filter_out_state_change( HANDLE handle, DBGUI_WAIT_STATE_CHANGE *state ) +{ + BOOL filter_out; + + switch (state->NewState) + { + case DbgLoadDllStateChange: + filter_out = ((ULONG64)state->StateInfo.LoadDll.BaseOfDll >> 32) != 0; + if (!filter_out) + { + USHORT machine; + filter_out = !get_image_machine( state->StateInfo.LoadDll.FileHandle, &machine) && machine != current_machine; + } + break; + case DbgUnloadDllStateChange: + filter_out = ((ULONG_PTR)state->StateInfo.UnloadDll.BaseAddress >> 32) != 0; + break; + default: + filter_out = FALSE; + break; + } + if (filter_out) + { + if (state->NewState == DbgLoadDllStateChange) + NtClose( state->StateInfo.LoadDll.FileHandle ); + NtDebugContinue( handle, &state->AppClientId, DBG_CONTINUE ); + } + return filter_out; +} + + +/********************************************************************** + * wow64_NtWaitForDebugEvent + */ +NTSTATUS WINAPI wow64_NtWaitForDebugEvent( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + BOOLEAN alertable = get_ulong( &args ); + LARGE_INTEGER *timeout = get_ptr( &args ); + DBGUI_WAIT_STATE_CHANGE32 *state32 = get_ptr( &args ); + + ULONG i; + DBGUI_WAIT_STATE_CHANGE state; + NTSTATUS status; + + do + { + status = NtWaitForDebugEvent( handle, alertable, timeout, &state ); + } while (!status && filter_out_state_change( handle, &state )); + + if (!status) + { + state32->NewState = state.NewState; + state32->AppClientId.UniqueProcess = HandleToULong( state.AppClientId.UniqueProcess ); + state32->AppClientId.UniqueThread = HandleToULong( state.AppClientId.UniqueThread ); + switch (state.NewState) + { +#define COPY_ULONG(field) state32->StateInfo.field = state.StateInfo.field +#define COPY_PTR(field) state32->StateInfo.field = PtrToUlong( state.StateInfo.field ) + case DbgCreateThreadStateChange: + COPY_PTR( CreateThread.HandleToThread ); + COPY_PTR( CreateThread.NewThread.StartAddress ); + COPY_ULONG( CreateThread.NewThread.SubSystemKey ); + break; + case DbgCreateProcessStateChange: + COPY_PTR( CreateProcessInfo.HandleToProcess ); + COPY_PTR( CreateProcessInfo.HandleToThread ); + COPY_PTR( CreateProcessInfo.NewProcess.FileHandle ); + COPY_PTR( CreateProcessInfo.NewProcess.BaseOfImage ); + COPY_PTR( CreateProcessInfo.NewProcess.InitialThread.StartAddress ); + COPY_ULONG( CreateProcessInfo.NewProcess.InitialThread.SubSystemKey ); + COPY_ULONG( CreateProcessInfo.NewProcess.DebugInfoFileOffset ); + COPY_ULONG( CreateProcessInfo.NewProcess.DebugInfoSize ); + break; + case DbgExitThreadStateChange: + case DbgExitProcessStateChange: + COPY_ULONG( ExitThread.ExitStatus ); + break; + case DbgExceptionStateChange: + case DbgBreakpointStateChange: + case DbgSingleStepStateChange: + COPY_ULONG( Exception.FirstChance ); + COPY_ULONG( Exception.ExceptionRecord.ExceptionCode ); + COPY_ULONG( Exception.ExceptionRecord.ExceptionFlags ); + COPY_ULONG( Exception.ExceptionRecord.NumberParameters ); + COPY_PTR( Exception.ExceptionRecord.ExceptionRecord ); + COPY_PTR( Exception.ExceptionRecord.ExceptionAddress ); + for (i = 0; i < state.StateInfo.Exception.ExceptionRecord.NumberParameters; i++) + COPY_ULONG( Exception.ExceptionRecord.ExceptionInformation[i] ); + break; + case DbgLoadDllStateChange: + COPY_PTR( LoadDll.FileHandle ); + COPY_PTR( LoadDll.BaseOfDll ); + COPY_ULONG( LoadDll.DebugInfoFileOffset ); + COPY_ULONG( LoadDll.DebugInfoSize ); + COPY_PTR( LoadDll.NamePointer ); + break; + case DbgUnloadDllStateChange: + COPY_PTR( UnloadDll.BaseAddress ); + break; + default: + break; + } +#undef COPY_ULONG +#undef COPY_PTR + } + return status; +} + + +/********************************************************************** + * wow64_NtWaitForKeyedEvent + */ +NTSTATUS WINAPI wow64_NtWaitForKeyedEvent( UINT *args ) +{ + HANDLE handle = get_handle( &args ); +#ifndef __REACTOS__ + const void *key = get_ptr( &args ); + BOOLEAN alertable = get_ulong( &args ); + const LARGE_INTEGER *timeout = get_ptr( &args ); +#else + void *key = get_ptr( &args ); + BOOLEAN alertable = get_ulong( &args ); + LARGE_INTEGER *timeout = get_ptr( &args ); +#endif + + return NtWaitForKeyedEvent( handle, key, alertable, timeout ); +} + + +/********************************************************************** + * wow64_NtWaitForMultipleObjects + */ +NTSTATUS WINAPI wow64_NtWaitForMultipleObjects( UINT *args ) +{ + DWORD count = get_ulong( &args ); + LONG *handles_ptr = get_ptr( &args ); + BOOLEAN wait_any = get_ulong( &args ); + BOOLEAN alertable = get_ulong( &args ); +#ifndef __REACTOS__ + const LARGE_INTEGER *timeout = get_ptr( &args ); +#else + LARGE_INTEGER *timeout = get_ptr( &args ); +#endif + + HANDLE handles[MAXIMUM_WAIT_OBJECTS]; + DWORD i; + + for (i = 0; i < count && i < MAXIMUM_WAIT_OBJECTS; i++) handles[i] = LongToHandle( handles_ptr[i] ); + return NtWaitForMultipleObjects( count, handles, wait_any, alertable, timeout ); +} + + +/********************************************************************** + * wow64_NtWaitForSingleObject + */ +NTSTATUS WINAPI wow64_NtWaitForSingleObject( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + BOOLEAN alertable = get_ulong( &args ); +#ifndef __REACTOS__ + const LARGE_INTEGER *timeout = get_ptr( &args ); +#else + LARGE_INTEGER *timeout = get_ptr( &args ); +#endif + + return NtWaitForSingleObject( handle, alertable, timeout ); +} + + +/********************************************************************** + * wow64_NtYieldExecution + */ +NTSTATUS WINAPI wow64_NtYieldExecution( UINT *args ) +{ + return NtYieldExecution(); +} + + +#ifndef __REACTOS__ +/********************************************************************** + * wow64_NtCreateTransaction + */ +NTSTATUS WINAPI wow64_NtCreateTransaction( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + GUID *guid = get_ptr( &args ); + HANDLE tm = get_handle( &args ); + ULONG options = get_ulong( &args ); + ULONG isol_level = get_ulong( &args ); + ULONG isol_flags = get_ulong( &args ); + LARGE_INTEGER *timeout = get_ptr( &args ); + UNICODE_STRING32 *desc32 = get_ptr( &args ); + + struct object_attr64 attr; + UNICODE_STRING desc; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtCreateTransaction( &handle, access, objattr_32to64( &attr, attr32 ), guid, tm, options, + isol_level, isol_flags, timeout, unicode_str_32to64( &desc, desc32 )); + put_handle( handle_ptr, handle ); + + return status; +} + + +/********************************************************************** + * wow64_NtCommitTransaction + */ +NTSTATUS WINAPI wow64_NtCommitTransaction( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + BOOLEAN wait = get_ulong( &args ); + + return NtCommitTransaction( handle, wait ); +} + + +/********************************************************************** + * wow64_NtRollbackTransaction + */ +NTSTATUS WINAPI wow64_NtRollbackTransaction( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + BOOLEAN wait = get_ulong( &args ); + + return NtRollbackTransaction( handle, wait ); +} +#endif diff --git a/dll/wow64/wine/syscall.c b/dll/wow64/wine/syscall.c new file mode 100644 index 0000000000000..bed6dc95959aa --- /dev/null +++ b/dll/wow64/wine/syscall.c @@ -0,0 +1,1563 @@ +/* + * WoW64 syscall wrapping + * + * Copyright 2021 Alexandre Julliard + * Copyright 2025 Marcin Jabłoński + * + * 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 +#include + +#ifndef __REACTOS__ +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "winnt.h" +#include "winternl.h" +#include "rtlsupportapi.h" +#include "wine/unixlib.h" +#include "wine/asm.h" +#include "wow64_private.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wow); + +USHORT native_machine = 0; +USHORT current_machine = 0; +ULONG_PTR args_alignment = 0; +ULONG_PTR highest_user_address = 0x7ffeffff; +ULONG_PTR default_zero_bits = 0x7fffffff; +#else +#include "ros_wow64_private.h" +ULONG_PTR highest_user_address = 0x7ffeffff; +ULONG_PTR default_zero_bits = 32; + +#ifdef __REACTOS__ +#define GetProcessHeap() RtlGetProcessHeap() +#endif + +#endif + +#ifndef __REACTOS__ +typedef NTSTATUS (WINAPI *syscall_thunk)( UINT *args ); + +static const syscall_thunk syscall_thunks[] = +{ +#define SYSCALL_ENTRY(id,name,args) wow64_ ## name, + ALL_SYSCALLS32 +#undef SYSCALL_ENTRY +}; + +static BYTE syscall_args[ARRAY_SIZE(syscall_thunks)] = +{ +#define SYSCALL_ENTRY(id,name,args) args, + ALL_SYSCALLS32 +#undef SYSCALL_ENTRY +}; + +static SYSTEM_SERVICE_TABLE syscall_tables[4] = +{ + { (ULONG_PTR *)syscall_thunks, NULL, ARRAY_SIZE(syscall_thunks), syscall_args } +}; + +/* header for Wow64AllocTemp blocks; probably not the right layout */ +struct mem_header +{ + struct mem_header *next; + void *__pad; + BYTE data[1]; +}; + +/* stack frame for user callbacks */ +struct user_callback_frame +{ + struct user_callback_frame *prev_frame; + struct mem_header *temp_list; + void **ret_ptr; + ULONG *ret_len; + NTSTATUS status; + jmp_buf jmpbuf; +}; + +/* stack frame for user APCs */ +struct user_apc_frame +{ + struct user_apc_frame *prev_frame; + CONTEXT *context; + void *wow_context; +}; + +SYSTEM_DLL_INIT_BLOCK *pLdrSystemDllInitBlock = NULL; + +static WOW64INFO *wow64info; + +/* cpu backend dll functions */ +/* the function prototypes most likely differ from Windows */ +static void * (WINAPI *pBTCpuGetBopCode)(void); +static NTSTATUS (WINAPI *pBTCpuGetContext)(HANDLE,HANDLE,void *,void *); +static BOOLEAN (WINAPI *pBTCpuIsProcessorFeaturePresent)(UINT); +static void (WINAPI *pBTCpuProcessInit)(void); +static NTSTATUS (WINAPI *pBTCpuSetContext)(HANDLE,HANDLE,void *,void *); +static void (WINAPI *pBTCpuThreadInit)(void); +static void (WINAPI *pBTCpuSimulate)(void) __attribute__((used)); +static void * (WINAPI *p__wine_get_unix_opcode)(void); +static void * (WINAPI *pKiRaiseUserExceptionDispatcher)(void); +void (WINAPI *pBTCpuFlushInstructionCache2)( const void *, SIZE_T ) = NULL; +void (WINAPI *pBTCpuFlushInstructionCacheHeavy)( const void *, SIZE_T ) = NULL; +NTSTATUS (WINAPI *pBTCpuNotifyMapViewOfSection)( void *, void *, void *, SIZE_T, ULONG, ULONG ) = NULL; +void (WINAPI *pBTCpuNotifyMemoryAlloc)( void *, SIZE_T, ULONG, ULONG, BOOL, NTSTATUS ) = NULL; +void (WINAPI *pBTCpuNotifyMemoryDirty)( void *, SIZE_T ) = NULL; +void (WINAPI *pBTCpuNotifyMemoryFree)( void *, SIZE_T, ULONG, BOOL, NTSTATUS ) = NULL; +void (WINAPI *pBTCpuNotifyMemoryProtect)( void *, SIZE_T, ULONG, BOOL, NTSTATUS ) = NULL; +void (WINAPI *pBTCpuNotifyReadFile)( HANDLE, void *, SIZE_T, BOOL, NTSTATUS ) = NULL; +void (WINAPI *pBTCpuNotifyUnmapViewOfSection)( void *, BOOL, NTSTATUS ) = NULL; +NTSTATUS (WINAPI *pBTCpuResetToConsistentState)( EXCEPTION_POINTERS * ) = NULL; +void (WINAPI *pBTCpuUpdateProcessorInformation)( SYSTEM_CPU_INFORMATION * ) = NULL; +void (WINAPI *pBTCpuProcessTerm)( HANDLE, BOOL, NTSTATUS ) = NULL; +void (WINAPI *pBTCpuThreadTerm)( HANDLE, LONG ) = NULL; + +BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, void *reserved ) +{ + if (reason == DLL_PROCESS_ATTACH) LdrDisableThreadCalloutsForDll( inst ); + return TRUE; +} + +void __cdecl __wine_spec_unimplemented_stub( const char *module, const char *function ) +{ + EXCEPTION_RECORD record; + + record.ExceptionCode = EXCEPTION_WINE_STUB; + record.ExceptionFlags = EXCEPTION_NONCONTINUABLE; + record.ExceptionRecord = NULL; + record.ExceptionAddress = __wine_spec_unimplemented_stub; + record.NumberParameters = 2; + record.ExceptionInformation[0] = (ULONG_PTR)module; + record.ExceptionInformation[1] = (ULONG_PTR)function; + for (;;) RtlRaiseException( &record ); +} + + +static EXCEPTION_RECORD *exception_record_32to64( const EXCEPTION_RECORD32 *rec32 ) +{ + EXCEPTION_RECORD *rec; + unsigned int i; + + rec = Wow64AllocateTemp( sizeof(*rec) ); + rec->ExceptionCode = rec32->ExceptionCode; + rec->ExceptionFlags = rec32->ExceptionFlags; + rec->ExceptionRecord = rec32->ExceptionRecord ? exception_record_32to64( ULongToPtr(rec32->ExceptionRecord) ) : NULL; + rec->ExceptionAddress = ULongToPtr( rec32->ExceptionAddress ); + rec->NumberParameters = rec32->NumberParameters; + for (i = 0; i < EXCEPTION_MAXIMUM_PARAMETERS; i++) + rec->ExceptionInformation[i] = rec32->ExceptionInformation[i]; + return rec; +} + + +static void exception_record_64to32( EXCEPTION_RECORD32 *rec32, const EXCEPTION_RECORD *rec ) +{ + unsigned int i; + + rec32->ExceptionCode = rec->ExceptionCode; + rec32->ExceptionFlags = rec->ExceptionFlags; + rec32->ExceptionRecord = PtrToUlong( rec->ExceptionRecord ); + rec32->ExceptionAddress = PtrToUlong( rec->ExceptionAddress ); + rec32->NumberParameters = rec->NumberParameters; + for (i = 0; i < rec->NumberParameters; i++) + rec32->ExceptionInformation[i] = rec->ExceptionInformation[i]; +} + + +static NTSTATUS get_context_return_value( void *wow_context ) +{ + switch (current_machine) + { + case IMAGE_FILE_MACHINE_I386: + return ((I386_CONTEXT *)wow_context)->Eax; + case IMAGE_FILE_MACHINE_ARMNT: + return ((ARM_CONTEXT *)wow_context)->R0; + } + return 0; +} + + +/********************************************************************** + * call_user_exception_dispatcher + */ +static void __attribute__((used)) call_user_exception_dispatcher( EXCEPTION_RECORD32 *rec, void *ctx32_ptr, + void *ctx64_ptr ) +{ + switch (current_machine) + { + case IMAGE_FILE_MACHINE_I386: + { + /* stack layout when calling 32-bit KiUserExceptionDispatcher */ + struct exc_stack_layout32 + { + ULONG rec_ptr; /* 000 */ + ULONG context_ptr; /* 004 */ + EXCEPTION_RECORD32 rec; /* 008 */ + I386_CONTEXT context; /* 058 */ + } *stack; + I386_CONTEXT ctx = { CONTEXT_I386_ALL }; + CONTEXT_EX *context_ex, *src_ex = NULL; + ULONG flags, context_length; + + C_ASSERT( offsetof(struct exc_stack_layout32, context) == 0x58 ); + + pBTCpuGetContext( GetCurrentThread(), GetCurrentProcess(), NULL, &ctx ); + + if (ctx32_ptr) + { + I386_CONTEXT *ctx32 = ctx32_ptr; + + if ((ctx32->ContextFlags & CONTEXT_I386_XSTATE) == CONTEXT_I386_XSTATE) + src_ex = (CONTEXT_EX *)(ctx32 + 1); + } + else if (native_machine == IMAGE_FILE_MACHINE_AMD64) + { + AMD64_CONTEXT *ctx64 = ctx64_ptr; + + if ((ctx64->ContextFlags & CONTEXT_AMD64_FLOATING_POINT) == CONTEXT_AMD64_FLOATING_POINT) + memcpy( ctx.ExtendedRegisters, &ctx64->FltSave, sizeof(ctx.ExtendedRegisters) ); + if ((ctx64->ContextFlags & CONTEXT_AMD64_XSTATE) == CONTEXT_AMD64_XSTATE) + src_ex = (CONTEXT_EX *)(ctx64 + 1); + } + + flags = ctx.ContextFlags; + if (src_ex) flags |= CONTEXT_I386_XSTATE; + + RtlGetExtendedContextLength( flags, &context_length ); + + stack = (struct exc_stack_layout32 *)ULongToPtr( (ctx.Esp - offsetof(struct exc_stack_layout32, context) - context_length) & ~3 ); + stack->rec_ptr = PtrToUlong( &stack->rec ); + stack->context_ptr = PtrToUlong( &stack->context ); + stack->rec = *rec; + stack->context = ctx; + RtlInitializeExtendedContext( &stack->context, flags, &context_ex ); + if (src_ex) RtlCopyExtendedContext( context_ex, WOW64_CONTEXT_XSTATE, src_ex ); + + /* adjust Eip for breakpoints in software emulation (hardware exceptions already adjust Rip) */ + if (rec->ExceptionCode == EXCEPTION_BREAKPOINT && (wow64info->CpuFlags & WOW64_CPUFLAGS_SOFTWARE)) + stack->context.Eip--; + + ctx.Esp = PtrToUlong( stack ); + ctx.Eip = pLdrSystemDllInitBlock->pKiUserExceptionDispatcher; + ctx.EFlags &= ~(0x100|0x400|0x40000); + ctx.ContextFlags = CONTEXT_I386_CONTROL; + pBTCpuSetContext( GetCurrentThread(), GetCurrentProcess(), NULL, &ctx ); + + TRACE( "exception %08lx dispatcher %08lx stack %08lx eip %08lx\n", + rec->ExceptionCode, ctx.Eip, ctx.Esp, stack->context.Eip ); + } + break; + + case IMAGE_FILE_MACHINE_ARMNT: + { + struct stack_layout + { + ARM_CONTEXT context; + EXCEPTION_RECORD32 rec; + } *stack; + ARM_CONTEXT ctx = { CONTEXT_ARM_ALL }; + + pBTCpuGetContext( GetCurrentThread(), GetCurrentProcess(), NULL, &ctx ); + stack = (struct stack_layout *)(ULONG_PTR)(ctx.Sp & ~3) - 1; + stack->rec = *rec; + stack->context = ctx; + + ctx.R0 = PtrToUlong( &stack->rec ); /* first arg for KiUserExceptionDispatcher */ + ctx.R1 = PtrToUlong( &stack->context ); /* second arg for KiUserExceptionDispatcher */ + ctx.Sp = PtrToUlong( stack ); + ctx.Pc = pLdrSystemDllInitBlock->pKiUserExceptionDispatcher; + if (ctx.Pc & 1) ctx.Cpsr |= 0x20; + else ctx.Cpsr &= ~0x20; + ctx.ContextFlags = CONTEXT_ARM_FULL; + pBTCpuSetContext( GetCurrentThread(), GetCurrentProcess(), NULL, &ctx ); + + TRACE( "exception %08lx dispatcher %08lx stack %08lx pc %08lx\n", + rec->ExceptionCode, ctx.Pc, ctx.Sp, stack->context.Sp ); + } + break; + } +} + + +/********************************************************************** + * call_raise_user_exception_dispatcher + */ +static void __attribute__((used)) call_raise_user_exception_dispatcher( ULONG code ) +{ + NtCurrentTeb32()->ExceptionCode = code; + + switch (current_machine) + { + case IMAGE_FILE_MACHINE_I386: + { + I386_CONTEXT ctx; + + ctx.ContextFlags = CONTEXT_I386_CONTROL; + pBTCpuGetContext( GetCurrentThread(), GetCurrentProcess(), NULL, &ctx ); + ctx.Esp -= sizeof(ULONG); + *(ULONG *)ULongToPtr( ctx.Esp ) = ctx.Eip; + ctx.Eip = (ULONG_PTR)pKiRaiseUserExceptionDispatcher; + pBTCpuSetContext( GetCurrentThread(), GetCurrentProcess(), NULL, &ctx ); + } + break; + + case IMAGE_FILE_MACHINE_ARMNT: + { + ARM_CONTEXT ctx; + + ctx.ContextFlags = CONTEXT_ARM_CONTROL; + pBTCpuGetContext( GetCurrentThread(), GetCurrentProcess(), NULL, &ctx ); + ctx.Pc = (ULONG_PTR)pKiRaiseUserExceptionDispatcher; + pBTCpuSetContext( GetCurrentThread(), GetCurrentProcess(), NULL, &ctx ); + } + break; + } +} + + +/* based on RtlRaiseException: call NtRaiseException with context setup to return to caller */ +void WINAPI raise_exception( EXCEPTION_RECORD32 *rec32, void *ctx32, + BOOL first_chance, EXCEPTION_RECORD *rec ); +#ifdef __aarch64__ +__ASM_GLOBAL_FUNC( raise_exception, + "sub sp, sp, #0x390\n\t" /* sizeof(context) */ + ".seh_stackalloc 0x390\n\t" + "stp x29, x30, [sp, #-48]!\n\t" + ".seh_save_fplr_x 48\n\t" + ".seh_endprologue\n\t" + ".seh_handler raise_exception_handler, @except\n\t" + "stp x0, x1, [sp, #16]\n\t" + "stp x2, x3, [sp, #32]\n\t" + "add x0, sp, #48\n\t" + "bl RtlCaptureContext\n\t" + "add x1, sp, #48\n\t" /* context */ + "adr x2, 1f\n\t" /* return address */ + "str x2, [x1, #0x108]\n\t" /* context->Pc */ + "ldp x2, x0, [sp, #32]\n\t" /* first_chance, rec */ + "bl NtRaiseException\n" + "raise_exception_ret:\n\t" + "ldp x0, x1, [sp, #16]\n\t" /* rec32, ctx32 */ + "add x2, sp, #48\n\t" /* context */ + "bl call_user_exception_dispatcher\n" + "1:\tnop\n\t" + "ldp x29, x30, [sp], #48\n\t" + "add sp, sp, #0x390\n\t" + "ret" ) +__ASM_GLOBAL_FUNC( raise_exception_handler, + "stp x29, x30, [sp, #-16]!\n\t" + ".seh_save_fplr_x 16\n\t" + ".seh_endprologue\n\t" + "ldr w4, [x0, #4]\n\t" /* record->ExceptionFlags */ + "tst w4, #6\n\t" /* EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND */ + "b.ne 1f\n\t" + "mov x2, x0\n\t" /* rec */ + "mov x0, x1\n\t" /* frame */ + "adr x1, raise_exception_ret\n\t" + "bl RtlUnwind\n" + "1:\tmov w0, #1\n\t" /* ExceptionContinueSearch */ + "ldp x29, x30, [sp], #16\n\t" + "ret" ) +#else +__ASM_GLOBAL_FUNC( raise_exception, + "sub $0x4d8,%rsp\n\t" /* sizeof(context) + alignment */ + ".seh_stackalloc 0x4d8\n\t" + ".seh_endprologue\n\t" + ".seh_handler raise_exception_handler, @except\n\t" + "movq %rcx,0x4e0(%rsp)\n\t" + "movq %rdx,0x4e8(%rsp)\n\t" + "movq %r8,0x4f0(%rsp)\n\t" + "movq %r9,0x4f8(%rsp)\n\t" + "movq %rsp,%rcx\n\t" + "call RtlCaptureContext\n\t" + "movq %rsp,%rdx\n\t" /* context */ + "leaq 1f(%rip),%rax\n\t" /* return address */ + "movq %rax,0xf8(%rdx)\n\t" /* context->Rip */ + "movq 0x4f8(%rsp),%rcx\n\t" /* rec */ + "movq 0x4f0(%rsp),%r8\n\t" /* first_chance */ + "call NtRaiseException\n" + "raise_exception_ret:\n\t" + "mov 0x4e0(%rsp),%rcx\n\t" /* rec32 */ + "mov 0x4e8(%rsp),%rdx\n\t" /* ctx32 */ + "movq %rsp,%r8\n\t" /* context */ + "call call_user_exception_dispatcher\n" + "1:\tnop\n\t" + "add $0x4d8,%rsp\n\t" + "ret" ) +__ASM_GLOBAL_FUNC( raise_exception_handler, + "sub $0x28,%rsp\n\t" + ".seh_stackalloc 0x28\n\t" + ".seh_endprologue\n\t" + "movq %rcx,%r8\n\t" /* rec */ + "movq %rdx,%rcx\n\t" /* frame */ + "leaq raise_exception_ret(%rip),%rdx\n\t" + "call RtlUnwind\n\t" + "int3" ) +#endif +#endif + +/********************************************************************** + * wow64_NtAddAtom + */ +NTSTATUS WINAPI wow64_NtAddAtom( UINT *args ) +{ +#ifndef __REACTOS__ + const WCHAR *name = get_ptr( &args ); +#else + WCHAR *name = get_ptr( &args ); +#endif + ULONG len = get_ulong( &args ); + RTL_ATOM *atom = get_ptr( &args ); + + return NtAddAtom( name, len, atom ); +} + + +/********************************************************************** + * wow64_NtAllocateLocallyUniqueId + */ +NTSTATUS WINAPI wow64_NtAllocateLocallyUniqueId( UINT *args ) +{ + LUID *luid = get_ptr( &args ); + + return NtAllocateLocallyUniqueId( luid ); +} + +#ifndef __REACTOS__ +/********************************************************************** + * wow64_NtAllocateReserveObject + */ +NTSTATUS WINAPI wow64_NtAllocateReserveObject( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + MEMORY_RESERVE_OBJECT_TYPE type = get_ulong( &args ); + NTSTATUS status; + + struct object_attr64 attr; + HANDLE handle = 0; + + status = NtAllocateReserveObject( &handle, objattr_32to64( &attr, attr32 ), type ); + put_handle( handle_ptr, handle ); + return status; +} +#endif + +/********************************************************************** + * wow64_NtAllocateUuids + */ +NTSTATUS WINAPI wow64_NtAllocateUuids( UINT *args ) +{ + ULARGE_INTEGER *time = get_ptr( &args ); + ULONG *delta = get_ptr( &args ); + ULONG *sequence = get_ptr( &args ); + UCHAR *seed = get_ptr( &args ); + + return NtAllocateUuids( time, delta, sequence, seed ); +} + + +/*********************************************************************** + * wow64_NtCallbackReturn + */ +NTSTATUS WINAPI wow64_NtCallbackReturn( UINT *args ) +{ + void *ret_ptr = get_ptr( &args ); + ULONG ret_len = get_ulong( &args ); + NTSTATUS status = get_ulong( &args ); + + struct user_callback_frame *frame = NtCurrentTeb()->TlsSlots[WOW64_TLS_USERCALLBACKDATA]; + + if (!frame) return STATUS_NO_CALLBACK_ACTIVE; + + *frame->ret_ptr = ret_ptr; + *frame->ret_len = ret_len; + frame->status = status; + longjmp( frame->jmpbuf, 1 ); + return STATUS_SUCCESS; +} + + +/********************************************************************** + * wow64_NtClose + */ +NTSTATUS WINAPI wow64_NtClose( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + + return NtClose( handle ); +} + + +#ifndef __REACTOS__ +/********************************************************************** + * wow64_NtContinueEx + */ +NTSTATUS WINAPI wow64_NtContinueEx( UINT *args ) +{ + void *context = get_ptr( &args ); + KCONTINUE_ARGUMENT *cont_args = get_ptr( &args ); + + NTSTATUS status = get_context_return_value( context ); + struct user_apc_frame *frame = NtCurrentTeb()->TlsSlots[WOW64_TLS_APCLIST]; + BOOL alertable; + + pBTCpuSetContext( GetCurrentThread(), GetCurrentProcess(), NULL, context ); + + while (frame && frame->wow_context != context) frame = frame->prev_frame; + NtCurrentTeb()->TlsSlots[WOW64_TLS_APCLIST] = frame ? frame->prev_frame : NULL; + if (frame) NtContinueEx( frame->context, cont_args ); + + if ((UINT_PTR)cont_args > 0xff) + alertable = cont_args->ContinueFlags & KCONTINUE_FLAG_TEST_ALERT; + else + alertable = !!cont_args; + + if (alertable) NtTestAlert(); + return status; +} + +/********************************************************************** + * wow64_NtContinue + */ +NTSTATUS WINAPI wow64_NtContinue( UINT *args ) +{ + return wow64_NtContinueEx( args ); +} +#endif + + +/********************************************************************** + * wow64_NtDeleteAtom + */ +NTSTATUS WINAPI wow64_NtDeleteAtom( UINT *args ) +{ + RTL_ATOM atom = get_ulong( &args ); + + return NtDeleteAtom( atom ); +} + + +/********************************************************************** + * wow64_NtFindAtom + */ +NTSTATUS WINAPI wow64_NtFindAtom( UINT *args ) +{ +#ifndef __REACTOS__ + const WCHAR *name = get_ptr( &args ); +#else + WCHAR *name = get_ptr( &args ); +#endif + ULONG len = get_ulong( &args ); + RTL_ATOM *atom = get_ptr( &args ); + + return NtFindAtom( name, len, atom ); +} + + +#ifndef __REACTOS__ +/********************************************************************** + * wow64_NtGetContextThread + */ +NTSTATUS WINAPI wow64_NtGetContextThread( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + WOW64_CONTEXT *context = get_ptr( &args ); + + return RtlWow64GetThreadContext( handle, context ); +} +#endif + + +/********************************************************************** + * wow64_NtGetCurrentProcessorNumber + */ +NTSTATUS WINAPI wow64_NtGetCurrentProcessorNumber( UINT *args ) +{ + return NtGetCurrentProcessorNumber(); +} + + +/********************************************************************** + * wow64_NtQueryDefaultLocale + */ +NTSTATUS WINAPI wow64_NtQueryDefaultLocale( UINT *args ) +{ + BOOLEAN user = get_ulong( &args ); + LCID *lcid = get_ptr( &args ); + + return NtQueryDefaultLocale( user, lcid ); +} + + +/********************************************************************** + * wow64_NtQueryDefaultUILanguage + */ +NTSTATUS WINAPI wow64_NtQueryDefaultUILanguage( UINT *args ) +{ + LANGID *lang = get_ptr( &args ); + + return NtQueryDefaultUILanguage( lang ); +} + + +/********************************************************************** + * wow64_NtQueryInformationAtom + */ +NTSTATUS WINAPI wow64_NtQueryInformationAtom( UINT *args ) +{ + RTL_ATOM atom = get_ulong( &args ); + ATOM_INFORMATION_CLASS class = get_ulong( &args ); + void *info = get_ptr( &args ); + ULONG len = get_ulong( &args ); + ULONG *retlen = get_ptr( &args ); + + if (class != AtomBasicInformation) FIXME( "class %u not supported\n", class ); + return NtQueryInformationAtom( atom, class, info, len, retlen ); +} + + +/********************************************************************** + * wow64_NtQueryInstallUILanguage + */ +NTSTATUS WINAPI wow64_NtQueryInstallUILanguage( UINT *args ) +{ + LANGID *lang = get_ptr( &args ); + + return NtQueryInstallUILanguage( lang ); +} + +#ifndef __REACTOS__ +/********************************************************************** + * wow64_NtRaiseException + */ +NTSTATUS WINAPI wow64_NtRaiseException( UINT *args ) +{ + EXCEPTION_RECORD32 *rec32 = get_ptr( &args ); + void *context32 = get_ptr( &args ); + BOOL first_chance = get_ulong( &args ); + + pBTCpuSetContext( GetCurrentThread(), GetCurrentProcess(), NULL, context32 ); + raise_exception( rec32, context32, first_chance, exception_record_32to64( rec32 )); + return STATUS_SUCCESS; +} + +/********************************************************************** + * wow64_NtSetContextThread + */ +NTSTATUS WINAPI wow64_NtSetContextThread( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + WOW64_CONTEXT *context = get_ptr( &args ); + + return RtlWow64SetThreadContext( handle, context ); +} +#endif + + +/********************************************************************** + * wow64_NtSetDebugFilterState + */ +NTSTATUS WINAPI wow64_NtSetDebugFilterState( UINT *args ) +{ + ULONG component_id = get_ulong( &args ); + ULONG level = get_ulong( &args ); + BOOLEAN state = get_ulong( &args ); + + return NtSetDebugFilterState( component_id, level, state ); +} + + +/********************************************************************** + * wow64_NtSetDefaultLocale + */ +NTSTATUS WINAPI wow64_NtSetDefaultLocale( UINT *args ) +{ + BOOLEAN user = get_ulong( &args ); + LCID lcid = get_ulong( &args ); + + return NtSetDefaultLocale( user, lcid ); +} + + +/********************************************************************** + * wow64_NtSetDefaultUILanguage + */ +NTSTATUS WINAPI wow64_NtSetDefaultUILanguage( UINT *args ) +{ + LANGID lang = get_ulong( &args ); + + return NtSetDefaultUILanguage( lang ); +} + +#ifndef __REACTOS__ +/********************************************************************** + * wow64_NtWow64IsProcessorFeaturePresent + */ +NTSTATUS WINAPI wow64_NtWow64IsProcessorFeaturePresent( UINT *args ) +{ + UINT feature = get_ulong( &args ); + + return pBTCpuIsProcessorFeaturePresent && pBTCpuIsProcessorFeaturePresent( feature ); +} +#endif + +#ifndef __REACTOS__ +/********************************************************************** + * init_image_mapping + */ +void init_image_mapping( HMODULE module ) +{ + ULONG *ptr = RtlFindExportedRoutineByName( module, "Wow64Transition" ); + + if (ptr) *ptr = PtrToUlong( pBTCpuGetBopCode() ); +} + + +/********************************************************************** + * load_64bit_module + */ +static HMODULE load_64bit_module( const WCHAR *name ) +{ + NTSTATUS status; + HMODULE module; + UNICODE_STRING str; + WCHAR path[MAX_PATH]; + const WCHAR *dir = get_machine_wow64_dir( IMAGE_FILE_MACHINE_TARGET_HOST ); + + swprintf( path, MAX_PATH, L"%s\\%s", dir, name ); + RtlInitUnicodeString( &str, path ); + if ((status = LdrLoadDll( dir, 0, &str, &module ))) + { + ERR( "failed to load dll %lx\n", status ); + NtTerminateProcess( GetCurrentProcess(), status ); + } + return module; +} + + +/********************************************************************** + * get_cpu_dll_name + */ +static const WCHAR *get_cpu_dll_name(void) +{ + static ULONG buffer[32]; + KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)buffer; + OBJECT_ATTRIBUTES attr; + UNICODE_STRING nameW; + const WCHAR *ret; + HANDLE key; + ULONG size; + + switch (current_machine) + { + case IMAGE_FILE_MACHINE_I386: + RtlInitUnicodeString( &nameW, L"\\Registry\\Machine\\Software\\Microsoft\\Wow64\\x86" ); + ret = (native_machine == IMAGE_FILE_MACHINE_ARM64 ? L"xtajit.dll" : L"wow64cpu.dll"); + break; + case IMAGE_FILE_MACHINE_ARMNT: + RtlInitUnicodeString( &nameW, L"\\Registry\\Machine\\Software\\Microsoft\\Wow64\\arm" ); + ret = L"wowarmhw.dll"; + break; + default: + ERR( "unsupported machine %04x\n", current_machine ); + RtlExitUserProcess( 1 ); + } + InitializeObjectAttributes( &attr, &nameW, OBJ_CASE_INSENSITIVE, 0, NULL ); + if (NtOpenKey( &key, KEY_READ | KEY_WOW64_64KEY, &attr )) return ret; + RtlInitUnicodeString( &nameW, L"" ); + size = sizeof(buffer) - sizeof(WCHAR); + if (!NtQueryValueKey( key, &nameW, KeyValuePartialInformation, buffer, size, &size ) && info->Type == REG_SZ) + { + ((WCHAR *)info->Data)[info->DataLength / sizeof(WCHAR)] = 0; + ret = (WCHAR *)info->Data; + } + NtClose( key ); + return ret; +} + + +/********************************************************************** + * create_cross_process_work_list + */ +static NTSTATUS create_cross_process_work_list( WOW64INFO *wow64info ) +{ + SIZE_T map_size = 0x4000; + LARGE_INTEGER size; + NTSTATUS status; + HANDLE section; + CROSS_PROCESS_WORK_LIST *list = NULL; + CROSS_PROCESS_WORK_ENTRY *end; + UINT i; + + size.QuadPart = map_size; + status = NtCreateSection( §ion, SECTION_ALL_ACCESS, NULL, &size, PAGE_READWRITE, SEC_COMMIT, 0 ); + if (status) return status; + status = NtMapViewOfSection( section, GetCurrentProcess(), (void **)&list, default_zero_bits, 0, NULL, + &map_size, ViewShare, MEM_TOP_DOWN, PAGE_READWRITE ); + if (status) + { + NtClose( section ); + return status; + } + + end = (CROSS_PROCESS_WORK_ENTRY *)((char *)list + map_size); + for (i = 0; list->entries + i + 1 <= end; i++) + RtlWow64PushCrossProcessWorkOntoFreeList( &list->free_list, &list->entries[i] ); + + wow64info->SectionHandle = (ULONG_PTR)section; + wow64info->CrossProcessWorkList = (ULONG_PTR)list; + return STATUS_SUCCESS; +} + + +/********************************************************************** + * process_init + */ +static DWORD WINAPI process_init( RTL_RUN_ONCE *once, void *param, void **context ) +{ + PEB32 *peb32; + HMODULE module; + UNICODE_STRING str = RTL_CONSTANT_STRING( L"ntdll.dll" ); + SYSTEM_BASIC_INFORMATION info; + ULONG *p__wine_syscall_dispatcher, *p__wine_unix_call_dispatcher; + const SYSTEM_SERVICE_TABLE *psdwhwin32; + + RtlWow64GetProcessMachines( GetCurrentProcess(), ¤t_machine, &native_machine ); + if (!current_machine) current_machine = native_machine; + args_alignment = (current_machine == IMAGE_FILE_MACHINE_I386) ? sizeof(ULONG) : sizeof(ULONG64); + NtQuerySystemInformation( SystemEmulationBasicInformation, &info, sizeof(info), NULL ); + highest_user_address = (ULONG_PTR)info.HighestUserAddress; + default_zero_bits = (ULONG_PTR)info.HighestUserAddress | 0x7fffffff; + NtQueryInformationProcess( GetCurrentProcess(), ProcessWow64Information, &peb32, sizeof(peb32), NULL ); + wow64info = (WOW64INFO *)(peb32 + 1); + wow64info->NativeSystemPageSize = 0x1000; + wow64info->NativeMachineType = native_machine; + wow64info->EmulatedMachineType = current_machine; + NtCurrentTeb()->TlsSlots[WOW64_TLS_WOW64INFO] = wow64info; + +#define GET_PTR(name) p ## name = RtlFindExportedRoutineByName( module, #name ) + + LdrGetDllHandle( NULL, 0, &str, &module ); + GET_PTR( LdrSystemDllInitBlock ); + + module = load_64bit_module( get_cpu_dll_name() ); + GET_PTR( BTCpuGetBopCode ); + GET_PTR( BTCpuGetContext ); + GET_PTR( BTCpuIsProcessorFeaturePresent ); + GET_PTR( BTCpuProcessInit ); + GET_PTR( BTCpuThreadInit ); + GET_PTR( BTCpuResetToConsistentState ); + GET_PTR( BTCpuSetContext ); + GET_PTR( BTCpuSimulate ); + GET_PTR( BTCpuFlushInstructionCache2 ); + GET_PTR( BTCpuFlushInstructionCacheHeavy ); + GET_PTR( BTCpuNotifyMapViewOfSection ); + GET_PTR( BTCpuNotifyMemoryAlloc ); + GET_PTR( BTCpuNotifyMemoryDirty ); + GET_PTR( BTCpuNotifyMemoryFree ); + GET_PTR( BTCpuNotifyMemoryProtect ); + GET_PTR( BTCpuNotifyReadFile ); + GET_PTR( BTCpuNotifyUnmapViewOfSection ); + GET_PTR( BTCpuUpdateProcessorInformation ); + GET_PTR( BTCpuProcessTerm ); + GET_PTR( BTCpuThreadTerm ); + GET_PTR( __wine_get_unix_opcode ); + + module = load_64bit_module( L"wow64win.dll" ); + GET_PTR( sdwhwin32 ); + syscall_tables[1] = *psdwhwin32; + + pBTCpuProcessInit(); + + module = (HMODULE)(ULONG_PTR)pLdrSystemDllInitBlock->ntdll_handle; + init_image_mapping( module ); + GET_PTR( KiRaiseUserExceptionDispatcher ); + GET_PTR( __wine_syscall_dispatcher ); + GET_PTR( __wine_unix_call_dispatcher ); + + *p__wine_syscall_dispatcher = PtrToUlong( pBTCpuGetBopCode() ); + *p__wine_unix_call_dispatcher = PtrToUlong( p__wine_get_unix_opcode() ); + + if (wow64info->CpuFlags & WOW64_CPUFLAGS_SOFTWARE) create_cross_process_work_list( wow64info ); + + init_file_redirects(); + return TRUE; + +#undef GET_PTR +} + + +/********************************************************************** + * thread_init + */ +static void thread_init(void) +{ + NtCurrentTeb32()->WOW32Reserved = PtrToUlong( pBTCpuGetBopCode() ); + NtCurrentTeb()->TlsSlots[WOW64_TLS_WOW64INFO] = wow64info; + if (pBTCpuThreadInit) pBTCpuThreadInit(); + + /* update initial context to jump to 32-bit LdrInitializeThunk (cf. 32-bit call_init_thunk) */ + switch (current_machine) + { + case IMAGE_FILE_MACHINE_I386: + { + I386_CONTEXT *ctx_ptr, ctx = { CONTEXT_I386_FULL }; + ULONG *stack; + + pBTCpuGetContext( GetCurrentThread(), GetCurrentProcess(), NULL, &ctx ); + ctx_ptr = (I386_CONTEXT *)ULongToPtr( ctx.Esp ) - 1; + *ctx_ptr = ctx; + stack = (ULONG *)ctx_ptr; + *(--stack) = 0; + *(--stack) = 0; + *(--stack) = 0; + *(--stack) = PtrToUlong( ctx_ptr ); + *(--stack) = 0xdeadbabe; + ctx.Esp = PtrToUlong( stack ); + ctx.Eip = pLdrSystemDllInitBlock->pLdrInitializeThunk; + pBTCpuSetContext( GetCurrentThread(), GetCurrentProcess(), NULL, &ctx ); + } + break; + + case IMAGE_FILE_MACHINE_ARMNT: + { + ARM_CONTEXT *ctx_ptr, ctx = { CONTEXT_ARM_FULL }; + + pBTCpuGetContext( GetCurrentThread(), GetCurrentProcess(), NULL, &ctx ); + ctx_ptr = (ARM_CONTEXT *)ULongToPtr( ctx.Sp & ~15 ) - 1; + *ctx_ptr = ctx; + + ctx.R0 = PtrToUlong( ctx_ptr ); + ctx.Sp = PtrToUlong( ctx_ptr ); + ctx.Pc = pLdrSystemDllInitBlock->pLdrInitializeThunk; + pBTCpuSetContext( GetCurrentThread(), GetCurrentProcess(), NULL, &ctx ); + } + break; + + default: + ERR( "not supported machine %x\n", current_machine ); + NtTerminateProcess( GetCurrentProcess(), STATUS_INVALID_IMAGE_FORMAT ); + } +} +#endif + +/********************************************************************** + * free_temp_data + */ +#ifndef __REACTOS__ +static void free_temp_data(void) +#else +VOID +Wow64FreeTempData(VOID) +#endif +{ + struct mem_header *next, *mem; + + for (mem = NtCurrentTeb()->TlsSlots[WOW64_TLS_TEMPLIST]; mem; mem = next) + { + next = mem->next; + RtlFreeHeap( GetProcessHeap(), 0, mem ); + } + NtCurrentTeb()->TlsSlots[WOW64_TLS_TEMPLIST] = NULL; +} + + +#ifndef __REACTOS__ +/********************************************************************** + * wow64_syscall + */ +#ifdef __aarch64__ +NTSTATUS wow64_syscall( UINT *args, ULONG_PTR thunk ); +__ASM_GLOBAL_FUNC( wow64_syscall, + "stp x29, x30, [sp, #-16]!\n\t" + ".seh_save_fplr_x 16\n\t" + ".seh_endprologue\n\t" + ".seh_handler wow64_syscall_handler, @except\n" + "blr x1\n\t" + "b 1f\n" + "wow64_syscall_ret:\n\t" + "eor w1, w0, #0xc0000000\n\t" + "cmp w1, #8\n\t" /* STATUS_INVALID_HANDLE */ + "b.ne 1f\n\t" + "bl call_raise_user_exception_dispatcher\n" + "1:\tldp x29, x30, [sp], #16\n\t" + "ret" ) +__ASM_GLOBAL_FUNC( wow64_syscall_handler, + "stp x29, x30, [sp, #-16]!\n\t" + ".seh_save_fplr_x 16\n\t" + ".seh_endprologue\n\t" + "ldr w4, [x0, #4]\n\t" /* record->ExceptionFlags */ + "tst w4, #6\n\t" /* EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND */ + "b.ne 1f\n\t" + "mov x2, x0\n\t" /* record */ + "mov x0, x1\n\t" /* frame */ + "adr x1, wow64_syscall_ret\n\t" /* target */ + "ldr w3, [x2]\n\t" /* retval = record->ExceptionCode */ + "bl RtlUnwind\n\t" + "1:\tmov w0, #1\n\t" /* ExceptionContinueSearch */ + "ldp x29, x30, [sp], #16\n\t" + "ret" ) +#else +NTSTATUS wow64_syscall( UINT *args, ULONG_PTR thunk ); +__ASM_GLOBAL_FUNC( wow64_syscall, + "subq $0x28, %rsp\n\t" + ".seh_stackalloc 0x28\n\t" + ".seh_endprologue\n\t" + ".seh_handler wow64_syscall_handler, @except\n\t" + "call *%rdx\n\t" + "jmp 1f\n" + "wow64_syscall_ret:\n\t" + "cmpl $0xc0000008,%eax\n\t" /* STATUS_INVALID_HANDLE */ + "jne 1f\n\t" + "movl %eax,%ecx\n\t" + "call call_raise_user_exception_dispatcher\n" + "1:\taddq $0x28, %rsp\n\t" + "ret" ) +__ASM_GLOBAL_FUNC( wow64_syscall_handler, + "subq $0x28,%rsp\n\t" + ".seh_stackalloc 0x28\n\t" + ".seh_endprologue\n\t" + "movl (%rcx),%r9d\n\t" /* retval = rec->ExceptionCode */ + "movq %rcx,%r8\n\t" /* rec */ + "movq %rdx,%rcx\n\t" /* frame */ + "leaq wow64_syscall_ret(%rip),%rdx\n\t" + "call RtlUnwind\n\t" + "int3" ) +#endif + + +/********************************************************************** + * Wow64SystemServiceEx (wow64.@) + */ +NTSTATUS WINAPI Wow64SystemServiceEx( UINT num, UINT *args ) +{ + NTSTATUS status; + UINT id = num & 0xfff; + const SYSTEM_SERVICE_TABLE *table = &syscall_tables[(num >> 12) & 3]; + + if (id >= table->ServiceLimit) + { + ERR( "unsupported syscall %04x\n", num ); + return STATUS_INVALID_SYSTEM_SERVICE; + } + status = wow64_syscall( args, table->ServiceTable[id] ); + free_temp_data(); + return status; +} + + +/********************************************************************** + * cpu_simulate + */ +#ifdef __aarch64__ +extern void DECLSPEC_NORETURN cpu_simulate(void); +__ASM_GLOBAL_FUNC( cpu_simulate, + "stp x29, x30, [sp, #-16]!\n\t" + ".seh_save_fplr_x 16\n\t" + ".seh_endprologue\n\t" + ".seh_handler cpu_simulate_handler, @except\n" + ".Lcpu_simulate_loop:\n\t" + "adrp x16, pBTCpuSimulate\n\t" + "ldr x16, [x16, :lo12:pBTCpuSimulate]\n\t" + "blr x16\n\t" + "b .Lcpu_simulate_loop" ) +__ASM_GLOBAL_FUNC( cpu_simulate_handler, + "stp x29, x30, [sp, #-48]!\n\t" + ".seh_save_fplr_x 48\n\t" + "stp x19, x20, [sp, #16]\n\t" + ".seh_save_regp x19, 16\n\t" + ".seh_endprologue\n\t" + "mov x19, x0\n\t" /* record */ + "mov x20, x1\n\t" /* frame */ + "ldr w4, [x0, #4]\n\t" /* record->ExceptionFlags */ + "tst w4, #6\n\t" /* EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND */ + "b.ne 1f\n\t" + "stp x0, x2, [sp, #32]\n\t" /* record, context */ + "add x0, sp, #32\n\t" + "bl Wow64PassExceptionToGuest\n\t" + "mov x0, x20\n\t" /* frame */ + "adr x1, .Lcpu_simulate_loop\n\t" /* target */ + "mov x2, x19\n\t" /* record */ + "bl RtlUnwind\n\t" + "1:\tmov w0, #1\n\t" /* ExceptionContinueSearch */ + "ldp x19, x20, [sp, #16]\n\t" + "ldp x29, x30, [sp], #48\n\t" + "ret" ) +#else +extern void DECLSPEC_NORETURN cpu_simulate(void); +__ASM_GLOBAL_FUNC( cpu_simulate, + "subq $0x28, %rsp\n\t" + ".seh_stackalloc 0x28\n\t" + ".seh_endprologue\n\t" + ".seh_handler cpu_simulate_handler, @except\n\t" + ".Lcpu_simulate_loop:\n\t" + "call *pBTCpuSimulate(%rip)\n\t" + "jmp .Lcpu_simulate_loop" ) +__ASM_GLOBAL_FUNC( cpu_simulate_handler, + "subq $0x38, %rsp\n\t" + ".seh_stackalloc 0x38\n\t" + ".seh_endprologue\n\t" + "movq %rcx,%rsi\n\t" /* record */ + "movq %rcx,0x20(%rsp)\n\t" + "movq %rdx,%rdi\n\t" /* frame */ + "movq %r8,0x28(%rsp)\n\t" /* context */ + "leaq 0x20(%rsp),%rcx\n\t" + "call Wow64PassExceptionToGuest\n\t" + "movq %rdi,%rcx\n\t" /* frame */ + "leaq .Lcpu_simulate_loop(%rip), %rdx\n\t" /* target */ + "movq %rsi,%r8\n\t" /* record */ + "call RtlUnwind\n\t" + "int3" ) +#endif +#endif + + +/********************************************************************** + * Wow64AllocateTemp (wow64.@) + * + * FIXME: probably not 100% compatible. + */ +void * WINAPI Wow64AllocateTemp( SIZE_T size ) +{ + struct mem_header *mem; + + if (!(mem = RtlAllocateHeap( GetProcessHeap(), 0, offsetof( struct mem_header, data[size] )))) + return NULL; + mem->next = NtCurrentTeb()->TlsSlots[WOW64_TLS_TEMPLIST]; + NtCurrentTeb()->TlsSlots[WOW64_TLS_TEMPLIST] = mem; + return mem->data; +} + + +#ifndef __REACTOS__ +/********************************************************************** + * Wow64ApcRoutine (wow64.@) + */ +void WINAPI Wow64ApcRoutine( ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, CONTEXT *context ) +{ + struct user_apc_frame frame; + + frame.prev_frame = NtCurrentTeb()->TlsSlots[WOW64_TLS_APCLIST]; + frame.context = context; + NtCurrentTeb()->TlsSlots[WOW64_TLS_APCLIST] = &frame; + + /* cf. 32-bit call_user_apc_dispatcher */ + switch (current_machine) + { + case IMAGE_FILE_MACHINE_I386: + { + /* stack layout when calling 32-bit KiUserApcDispatcher */ + struct apc_stack_layout32 + { + ULONG func; /* 000 */ + UINT arg1; /* 004 */ + UINT arg2; /* 008 */ + UINT arg3; /* 00c */ + UINT alertable; /* 010 */ + I386_CONTEXT context; /* 014 */ + CONTEXT_EX32 xctx; /* 2e0 */ + UINT unk2[4]; /* 2f8 */ + } *stack; + I386_CONTEXT ctx = { CONTEXT_I386_FULL }; + + C_ASSERT( offsetof(struct apc_stack_layout32, context) == 0x14 ); + C_ASSERT( sizeof(struct apc_stack_layout32) == 0x308 ); + + pBTCpuGetContext( GetCurrentThread(), GetCurrentProcess(), NULL, &ctx ); + + stack = (struct apc_stack_layout32 *)ULongToPtr( ctx.Esp & ~3 ) - 1; + stack->func = arg1 >> 32; + stack->arg1 = arg1; + stack->arg2 = arg2; + stack->arg3 = arg3; + stack->alertable = TRUE; + stack->context = ctx; + stack->xctx.Legacy.Offset = -(LONG)sizeof(stack->context); + stack->xctx.Legacy.Length = sizeof(stack->context); + stack->xctx.All.Offset = -(LONG)sizeof(stack->context); + stack->xctx.All.Length = sizeof(stack->context) + sizeof(stack->xctx); + stack->xctx.XState.Offset = 25; + stack->xctx.XState.Length = 0; + + ctx.Esp = PtrToUlong( stack ); + ctx.Eip = pLdrSystemDllInitBlock->pKiUserApcDispatcher; + frame.wow_context = &stack->context; + pBTCpuSetContext( GetCurrentThread(), GetCurrentProcess(), NULL, &ctx ); + cpu_simulate(); + } + break; + + case IMAGE_FILE_MACHINE_ARMNT: + { + struct apc_stack_layout + { + ULONG func; + ULONG align[3]; + ARM_CONTEXT context; + } *stack; + ARM_CONTEXT ctx = { CONTEXT_ARM_FULL }; + + pBTCpuGetContext( GetCurrentThread(), GetCurrentProcess(), NULL, &ctx ); + stack = (struct apc_stack_layout *)ULongToPtr( ctx.Sp & ~15 ) - 1; + stack->func = arg1 >> 32; + stack->context = ctx; + ctx.Sp = PtrToUlong( stack ); + ctx.Pc = pLdrSystemDllInitBlock->pKiUserApcDispatcher; + ctx.R0 = PtrToUlong( &stack->context ); + ctx.R1 = arg1; + ctx.R2 = arg2; + ctx.R3 = arg3; + frame.wow_context = &stack->context; + pBTCpuSetContext( GetCurrentThread(), GetCurrentProcess(), NULL, &ctx ); + cpu_simulate(); + } + break; + } +} + +/********************************************************************** + * Wow64KiUserCallbackDispatcher (wow64.@) + */ +NTSTATUS WINAPI Wow64KiUserCallbackDispatcher( ULONG id, void *args, ULONG len, + void **ret_ptr, ULONG *ret_len ) +{ + WOW64_CPURESERVED *cpu = NtCurrentTeb()->TlsSlots[WOW64_TLS_CPURESERVED]; + TEB32 *teb32 = NtCurrentTeb32(); + ULONG teb_frame = teb32->Tib.ExceptionList; + struct user_callback_frame frame; + USHORT flags = cpu->Flags; + + frame.prev_frame = NtCurrentTeb()->TlsSlots[WOW64_TLS_USERCALLBACKDATA]; + frame.temp_list = NtCurrentTeb()->TlsSlots[WOW64_TLS_TEMPLIST]; + frame.ret_ptr = ret_ptr; + frame.ret_len = ret_len; + + NtCurrentTeb()->TlsSlots[WOW64_TLS_USERCALLBACKDATA] = &frame; + NtCurrentTeb()->TlsSlots[WOW64_TLS_TEMPLIST] = NULL; + + /* cf. 32-bit KeUserModeCallback */ + switch (current_machine) + { + case IMAGE_FILE_MACHINE_I386: + { + /* stack layout when calling 32-bit KiUserCallbackDispatcher */ + struct callback_stack_layout32 + { + ULONG eip; /* 000 */ + ULONG id; /* 004 */ + ULONG args; /* 008 */ + ULONG len; /* 00c */ + ULONG unk[2]; /* 010 */ + ULONG esp; /* 018 */ + BYTE args_data[0]; /* 01c */ + } *stack; + I386_CONTEXT orig_ctx, ctx = { CONTEXT_I386_FULL }; + + C_ASSERT( sizeof(struct callback_stack_layout32) == 0x1c ); + + pBTCpuGetContext( GetCurrentThread(), GetCurrentProcess(), NULL, &ctx ); + orig_ctx = ctx; + + stack = ULongToPtr( (ctx.Esp - offsetof(struct callback_stack_layout32,args_data[len])) & ~15 ); + stack->eip = ctx.Eip; + stack->id = id; + stack->args = PtrToUlong( stack->args_data ); + stack->len = len; + stack->esp = ctx.Esp; + memcpy( stack->args_data, args, len ); + + ctx.Esp = PtrToUlong( stack ); + ctx.Eip = pLdrSystemDllInitBlock->pKiUserCallbackDispatcher; + pBTCpuSetContext( GetCurrentThread(), GetCurrentProcess(), NULL, &ctx ); + + if (!setjmp( frame.jmpbuf )) + cpu_simulate(); + else + pBTCpuSetContext( GetCurrentThread(), GetCurrentProcess(), NULL, &orig_ctx ); + } + break; + + case IMAGE_FILE_MACHINE_ARMNT: + { + ARM_CONTEXT orig_ctx, ctx = { CONTEXT_ARM_FULL }; + void *args_data; + + pBTCpuGetContext( GetCurrentThread(), GetCurrentProcess(), NULL, &ctx ); + orig_ctx = ctx; + + args_data = ULongToPtr( (ctx.Sp - len) & ~15 ); + memcpy( args_data, args, len ); + + ctx.R0 = id; + ctx.R1 = PtrToUlong( args_data ); + ctx.R2 = len; + ctx.Sp = PtrToUlong( args_data ); + ctx.Pc = pLdrSystemDllInitBlock->pKiUserCallbackDispatcher; + pBTCpuSetContext( GetCurrentThread(), GetCurrentProcess(), NULL, &ctx ); + + if (!setjmp( frame.jmpbuf )) + cpu_simulate(); + else + pBTCpuSetContext( GetCurrentThread(), GetCurrentProcess(), NULL, &orig_ctx ); + } + break; + } + + teb32->Tib.ExceptionList = teb_frame; + NtCurrentTeb()->TlsSlots[WOW64_TLS_USERCALLBACKDATA] = frame.prev_frame; + NtCurrentTeb()->TlsSlots[WOW64_TLS_TEMPLIST] = frame.temp_list; + cpu->Flags = flags; + return frame.status; +} + + +/********************************************************************** + * Wow64LdrpInitialize (wow64.@) + */ +void WINAPI Wow64LdrpInitialize( CONTEXT *context ) +{ + static RTL_RUN_ONCE init_done; + + RtlRunOnceExecuteOnce( &init_done, process_init, NULL, NULL ); + thread_init(); + cpu_simulate(); +} + + +/********************************************************************** + * Wow64PrepareForException (wow64.@) + */ +#ifdef __x86_64__ +__ASM_GLOBAL_FUNC( Wow64PrepareForException, + "sub $0x38,%rsp\n\t" + "mov %rcx,%r10\n\t" /* rec */ + "movw %cs,%ax\n\t" + "cmpw %ax,0x38(%rdx)\n\t" /* context->SegCs */ + "je 1f\n\t" /* already in 64-bit mode? */ + /* copy arguments to 64-bit stack */ + "mov %rsp,%rsi\n\t" + "mov 0x98(%rdx),%rcx\n\t" /* context->Rsp */ + "sub %rsi,%rcx\n\t" /* stack size */ + "sub %rcx,%r14\n\t" /* reserve same size on 64-bit stack */ + "and $~0x0f,%r14\n\t" + "mov %r14,%rdi\n\t" + "shr $3,%rcx\n\t" + "rep; movsq\n\t" + /* update arguments to point to the new stack */ + "mov %r14,%rax\n\t" + "sub %rsp,%rax\n\t" + "add %rax,%r10\n\t" /* rec */ + "add %rax,%rdx\n\t" /* context */ + /* switch to 64-bit stack */ + "mov %r14,%rsp\n" + /* build EXCEPTION_POINTERS structure and call BTCpuResetToConsistentState */ + "1:\tlea 0x20(%rsp),%rcx\n\t" /* pointers */ + "mov %r10,(%rcx)\n\t" /* rec */ + "mov %rdx,8(%rcx)\n\t" /* context */ + "mov " __ASM_NAME("pBTCpuResetToConsistentState") "(%rip),%rax\n\t" + "call *%rax\n\t" + "add $0x38,%rsp\n\t" + "ret" ) +#else +void WINAPI Wow64PrepareForException( EXCEPTION_RECORD *rec, CONTEXT *context ) +{ + EXCEPTION_POINTERS ptrs = { rec, context }; + + pBTCpuResetToConsistentState( &ptrs ); +} +#endif + + +/********************************************************************** + * Wow64PassExceptionToGuest (wow64.@) + */ +void WINAPI Wow64PassExceptionToGuest( EXCEPTION_POINTERS *ptrs ) +{ + EXCEPTION_RECORD32 rec32; + + exception_record_64to32( &rec32, ptrs->ExceptionRecord ); + call_user_exception_dispatcher( &rec32, NULL, ptrs->ContextRecord ); +} + + +/********************************************************************** + * Wow64ProcessPendingCrossProcessItems (wow64.@) + */ +void WINAPI Wow64ProcessPendingCrossProcessItems(void) +{ + CROSS_PROCESS_WORK_LIST *list = (void *)wow64info->CrossProcessWorkList; + CROSS_PROCESS_WORK_ENTRY *entry; + BOOLEAN flush = FALSE; + UINT next; + + if (!list) return; + entry = RtlWow64PopAllCrossProcessWorkFromWorkList( &list->work_list, &flush ); + + if (flush) + { + if (pBTCpuFlushInstructionCacheHeavy) pBTCpuFlushInstructionCacheHeavy( NULL, 0 ); + while (entry) + { + next = entry->next; + RtlWow64PushCrossProcessWorkOntoFreeList( &list->free_list, entry ); + entry = next ? CROSS_PROCESS_LIST_ENTRY( &list->work_list, next ) : NULL; + } + return; + } + + while (entry) + { + switch (entry->id) + { + case CrossProcessPreVirtualAlloc: + case CrossProcessPostVirtualAlloc: + if (!pBTCpuNotifyMemoryAlloc) break; + pBTCpuNotifyMemoryAlloc( (void *)entry->addr, entry->size, entry->args[0], entry->args[1], + entry->id == CrossProcessPostVirtualAlloc, entry->args[2] ); + break; + case CrossProcessPreVirtualFree: + case CrossProcessPostVirtualFree: + if (!pBTCpuNotifyMemoryFree) break; + pBTCpuNotifyMemoryFree( (void *)entry->addr, entry->size, entry->args[0], + entry->id == CrossProcessPostVirtualFree, entry->args[1] ); + break; + case CrossProcessPreVirtualProtect: + case CrossProcessPostVirtualProtect: + if (!pBTCpuNotifyMemoryProtect) break; + pBTCpuNotifyMemoryProtect( (void *)entry->addr, entry->size, entry->args[0], + entry->id == CrossProcessPostVirtualProtect, entry->args[1] ); + break; + case CrossProcessFlushCache: + if (!pBTCpuFlushInstructionCache2) break; + pBTCpuFlushInstructionCache2( (void *)entry->addr, entry->size ); + break; + case CrossProcessFlushCacheHeavy: + if (!pBTCpuFlushInstructionCacheHeavy) break; + pBTCpuFlushInstructionCacheHeavy( (void *)entry->addr, entry->size ); + break; + case CrossProcessMemoryWrite: + if (!pBTCpuNotifyMemoryDirty) break; + pBTCpuNotifyMemoryDirty( (void *)entry->addr, entry->size ); + break; + } + next = entry->next; + RtlWow64PushCrossProcessWorkOntoFreeList( &list->free_list, entry ); + entry = next ? CROSS_PROCESS_LIST_ENTRY( &list->work_list, next ) : NULL; + } +} + + +/********************************************************************** + * Wow64RaiseException (wow64.@) + */ +NTSTATUS WINAPI Wow64RaiseException( int code, EXCEPTION_RECORD *rec ) +{ + EXCEPTION_RECORD32 rec32; + BOOL first_chance = TRUE; + union + { + I386_CONTEXT i386; + ARM_CONTEXT arm; + } ctx32 = { 0 }; + + switch (current_machine) + { + case IMAGE_FILE_MACHINE_I386: + { + EXCEPTION_RECORD int_rec = { 0 }; + + ctx32.i386.ContextFlags = CONTEXT_I386_ALL; + pBTCpuGetContext( GetCurrentThread(), GetCurrentProcess(), NULL, &ctx32.i386 ); + if (code == -1) break; + int_rec.ExceptionAddress = (void *)(ULONG_PTR)ctx32.i386.Eip; + switch (code) + { + case 0x00: /* division by zero */ + int_rec.ExceptionCode = EXCEPTION_INT_DIVIDE_BY_ZERO; + break; + case 0x01: /* single-step */ + ctx32.i386.EFlags &= ~0x100; + pBTCpuSetContext( GetCurrentThread(), GetCurrentProcess(), NULL, &ctx32.i386 ); + int_rec.ExceptionCode = EXCEPTION_SINGLE_STEP; + break; + case 0x03: /* breakpoint */ + int_rec.ExceptionCode = EXCEPTION_BREAKPOINT; + int_rec.ExceptionAddress = (void *)(ULONG_PTR)(ctx32.i386.Eip - 1); + int_rec.NumberParameters = 1; + break; + case 0x04: /* overflow */ + int_rec.ExceptionCode = EXCEPTION_INT_OVERFLOW; + break; + case 0x05: /* array bounds */ + int_rec.ExceptionCode = EXCEPTION_ARRAY_BOUNDS_EXCEEDED; + break; + case 0x06: /* invalid opcode */ + int_rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION; + break; + case 0x09: /* coprocessor segment overrun */ + int_rec.ExceptionCode = EXCEPTION_FLT_INVALID_OPERATION; + break; + case 0x0c: /* stack fault */ + int_rec.ExceptionCode = EXCEPTION_STACK_OVERFLOW; + break; + case 0x0d: /* general protection fault */ + int_rec.ExceptionCode = EXCEPTION_PRIV_INSTRUCTION; + break; + case 0x29: /* __fastfail */ + int_rec.ExceptionCode = STATUS_STACK_BUFFER_OVERRUN; + int_rec.ExceptionFlags = EXCEPTION_NONCONTINUABLE; + int_rec.NumberParameters = 1; + int_rec.ExceptionInformation[0] = ctx32.i386.Ecx; + first_chance = FALSE; + break; + case 0x2d: /* debug service */ + ctx32.i386.Eip += 3; + pBTCpuSetContext( GetCurrentThread(), GetCurrentProcess(), NULL, &ctx32.i386 ); + int_rec.ExceptionCode = EXCEPTION_BREAKPOINT; + int_rec.ExceptionAddress = (void *)(ULONG_PTR)ctx32.i386.Eip; + int_rec.NumberParameters = 1; + int_rec.ExceptionInformation[0] = ctx32.i386.Eax; + break; + default: + int_rec.ExceptionCode = EXCEPTION_ACCESS_VIOLATION; + int_rec.ExceptionAddress = (void *)(ULONG_PTR)ctx32.i386.Eip; + int_rec.NumberParameters = 2; + int_rec.ExceptionInformation[1] = 0xffffffff; + break; + } + *rec = int_rec; + break; + } + + case IMAGE_FILE_MACHINE_ARMNT: + ctx32.arm.ContextFlags = CONTEXT_ARM_ALL; + pBTCpuGetContext( GetCurrentThread(), GetCurrentProcess(), NULL, &ctx32.arm ); + break; + } + + exception_record_64to32( &rec32, rec ); + raise_exception( &rec32, &ctx32, first_chance, rec ); + + return STATUS_SUCCESS; +} + +#endif diff --git a/dll/wow64/wine/system.c b/dll/wow64/wine/system.c new file mode 100644 index 0000000000000..0474b513037f3 --- /dev/null +++ b/dll/wow64/wine/system.c @@ -0,0 +1,1050 @@ +/* + * WoW64 system functions + * + * Copyright 2021 Alexandre Julliard + * Copyright 2025 Marcin Jabłoński + * + * 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 + */ +#ifndef __REACTOS__ +#include + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "winnt.h" +#include "winternl.h" +#include "wow64_private.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wow); +#else +#include "ros_wow64_private.h" +#endif + +static void put_system_basic_information( SYSTEM_BASIC_INFORMATION32 *info32, + const SYSTEM_BASIC_INFORMATION *info ) +{ +#ifndef __REACTOS__ + info32->unknown = info->unknown; + info32->KeMaximumIncrement = info->KeMaximumIncrement; + info32->PageSize = info->PageSize; + info32->MmNumberOfPhysicalPages = info->MmNumberOfPhysicalPages; + info32->MmLowestPhysicalPage = info->MmLowestPhysicalPage; + info32->MmHighestPhysicalPage = info->MmHighestPhysicalPage; + info32->AllocationGranularity = info->AllocationGranularity; + info32->LowestUserAddress = PtrToUlong( info->LowestUserAddress ); + info32->HighestUserAddress = PtrToUlong( info->HighestUserAddress ); + info32->ActiveProcessorsAffinityMask = info->ActiveProcessorsAffinityMask; + info32->NumberOfProcessors = info->NumberOfProcessors; +#else + info32->unknown = info->Reserved; + info32->KeMaximumIncrement = info->TimerResolution; + info32->PageSize = info->PageSize; + info32->MmNumberOfPhysicalPages = info->NumberOfPhysicalPages; + info32->MmLowestPhysicalPage = info->LowestPhysicalPageNumber; + info32->MmHighestPhysicalPage = info->HighestPhysicalPageNumber; + info32->AllocationGranularity = info->AllocationGranularity; + info32->LowestUserAddress = (ULONG)info->MinimumUserModeAddress; + info32->HighestUserAddress = (ULONG)info->MaximumUserModeAddress; + info32->ActiveProcessorsAffinityMask = info->ActiveProcessorsAffinityMask; + info32->NumberOfProcessors = info->NumberOfProcessors; +#endif +} + + +static void put_group_affinity( GROUP_AFFINITY32 *info32, const GROUP_AFFINITY *info ) +{ + info32->Mask = info->Mask; + info32->Group = info->Group; +} + + +static void put_logical_proc_info_ex( SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX32 *info32, + const SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *info ) +{ + ULONG i; + + info32->Relationship = info->Relationship; + info32->Size = offsetof( SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX32, Processor ); + switch (info->Relationship) + { + case RelationProcessorCore: + case RelationProcessorPackage: + info32->Processor.Flags = info->Processor.Flags; +#ifndef __REACTOS__ + info32->Processor.EfficiencyClass = info->Processor.EfficiencyClass; +#endif + info32->Processor.GroupCount = info->Processor.GroupCount; + for (i = 0; i < info->Processor.GroupCount; i++) + put_group_affinity( &info32->Processor.GroupMask[i], &info->Processor.GroupMask[i] ); + info32->Size += offsetof( PROCESSOR_RELATIONSHIP32, GroupMask[i] ); + break; + case RelationNumaNode: + info32->NumaNode.NodeNumber = info->NumaNode.NodeNumber; + put_group_affinity( &info32->NumaNode.GroupMask, &info->NumaNode.GroupMask ); + info32->Size += sizeof(info32->NumaNode); + break; + case RelationCache: + info32->Cache.Level = info->Cache.Level; + info32->Cache.Associativity = info->Cache.Associativity; + info32->Cache.LineSize = info->Cache.LineSize; + info32->Cache.CacheSize = info->Cache.CacheSize; + info32->Cache.Type = info->Cache.Type; + put_group_affinity( &info32->Cache.GroupMask, &info->Cache.GroupMask ); + info32->Size += sizeof(info32->Cache); + break; + case RelationGroup: + info32->Group.MaximumGroupCount = info->Group.MaximumGroupCount; + info32->Group.ActiveGroupCount = info->Group.ActiveGroupCount; + for (i = 0; i < info->Group.MaximumGroupCount; i++) + { + info32->Group.GroupInfo[i].MaximumProcessorCount = info->Group.GroupInfo[i].MaximumProcessorCount; + info32->Group.GroupInfo[i].ActiveProcessorCount = info->Group.GroupInfo[i].ActiveProcessorCount; + info32->Group.GroupInfo[i].ActiveProcessorMask = info->Group.GroupInfo[i].ActiveProcessorMask; + } + info32->Size += offsetof( GROUP_RELATIONSHIP32, GroupInfo[i] ); + break; + default: + break; + } +} + +static NTSTATUS put_system_proc_info( SYSTEM_PROCESS_INFORMATION32 *info32, + const SYSTEM_PROCESS_INFORMATION *info, + BOOL ext_info, ULONG len, ULONG *retlen ) +{ + ULONG inpos = 0, outpos = 0, i; + SYSTEM_PROCESS_INFORMATION32 *prev = NULL; +#ifndef __REACTOS__ + ULONG ti_size = (ext_info ? sizeof(SYSTEM_EXTENDED_THREAD_INFORMATION) : sizeof(SYSTEM_THREAD_INFORMATION)); + ULONG ti_size32 = (ext_info ? sizeof(SYSTEM_EXTENDED_THREAD_INFORMATION32) : sizeof(SYSTEM_THREAD_INFORMATION32)); +#endif + + for (;;) + { +#ifndef __REACTOS__ + SYSTEM_EXTENDED_THREAD_INFORMATION *ti; + SYSTEM_EXTENDED_THREAD_INFORMATION32 *ti32; +#endif + SYSTEM_PROCESS_INFORMATION *proc = (SYSTEM_PROCESS_INFORMATION *)((char *)info + inpos); + SYSTEM_PROCESS_INFORMATION32 *proc32 = (SYSTEM_PROCESS_INFORMATION32 *)((char *)info32 + outpos); +#ifndef __REACTOS__ + ULONG proc_len = offsetof( SYSTEM_PROCESS_INFORMATION32, ti ) + proc->dwThreadCount * ti_size32; +#else + (VOID) i; + ULONG proc_len = offsetof(SYSTEM_PROCESS_INFORMATION32, ti); +#endif + +#ifndef __REACTOS__ + if (outpos + proc_len + proc->ProcessName.MaximumLength <= len) +#else + if (outpos + proc_len + proc->ImageName.MaximumLength <= len) +#endif + { + memset( proc32, 0, proc_len ); + +#ifndef __REACTOS__ + proc32->dwThreadCount = proc->dwThreadCount; +#else + proc32->dwThreadCount = proc->NumberOfThreads; +#endif + proc32->WorkingSetPrivateSize = proc->WorkingSetPrivateSize; + proc32->HardFaultCount = proc->HardFaultCount; + proc32->NumberOfThreadsHighWatermark = proc->NumberOfThreadsHighWatermark; + proc32->CycleTime = proc->CycleTime; +#ifndef __REACTOS__ + proc32->CreationTime = proc->CreationTime; +#else + proc32->CreationTime = proc->CreateTime; +#endif + proc32->UserTime = proc->UserTime; + proc32->KernelTime = proc->KernelTime; +#ifndef __REACTOS__ + proc32->ProcessName.Length = proc->ProcessName.Length; + proc32->ProcessName.MaximumLength = proc->ProcessName.MaximumLength; +#else + proc32->ProcessName.Length = proc->ImageName.Length; + proc32->ProcessName.MaximumLength = proc->ImageName.MaximumLength; +#endif + proc32->ProcessName.Buffer = PtrToUlong( (char *)proc32 + proc_len ); +#ifndef __REACTOS__ + proc32->dwBasePriority = proc->dwBasePriority; + proc32->UniqueProcessId = HandleToULong( proc->UniqueProcessId ); + proc32->ParentProcessId = HandleToULong( proc->ParentProcessId ); +#else + proc32->dwBasePriority = proc->BasePriority; + proc32->UniqueProcessId = HandleToULong(proc->UniqueProcessId); + proc32->ParentProcessId = HandleToULong(proc->InheritedFromUniqueProcessId); +#endif + proc32->HandleCount = proc->HandleCount; + proc32->SessionId = proc->SessionId; + put_vm_counters(&proc32->vmCounters, (VM_COUNTERS_EX*)&proc->PeakVirtualSize, sizeof(proc32->vmCounters)); +#ifndef __REACTOS__ + proc32->UniqueProcessKey = proc->UniqueProcessKey; + proc32->ioCounters = proc->ioCounters; + put_vm_counters( &proc32->vmCounters, &proc->vmCounters, sizeof(proc32->vmCounters) ); +#endif +#ifndef __REACTOS__ + for (i = 0; i < proc->dwThreadCount; i++) + { + ti = (SYSTEM_EXTENDED_THREAD_INFORMATION *)((char *)proc->ti + i * ti_size); + ti32 = (SYSTEM_EXTENDED_THREAD_INFORMATION32 *)((char *)proc32->ti + i * ti_size32); + ti32->ThreadInfo.KernelTime = ti->ThreadInfo.KernelTime; + ti32->ThreadInfo.UserTime = ti->ThreadInfo.UserTime; + ti32->ThreadInfo.CreateTime = ti->ThreadInfo.CreateTime; + ti32->ThreadInfo.dwTickCount = ti->ThreadInfo.dwTickCount; + ti32->ThreadInfo.StartAddress = PtrToUlong( ti->ThreadInfo.StartAddress ); + ti32->ThreadInfo.dwCurrentPriority = ti->ThreadInfo.dwCurrentPriority; + ti32->ThreadInfo.dwBasePriority = ti->ThreadInfo.dwBasePriority; + ti32->ThreadInfo.dwContextSwitches = ti->ThreadInfo.dwContextSwitches; + ti32->ThreadInfo.dwThreadState = ti->ThreadInfo.dwThreadState; + ti32->ThreadInfo.dwWaitReason = ti->ThreadInfo.dwWaitReason; + put_client_id( &ti32->ThreadInfo.ClientId, &ti->ThreadInfo.ClientId ); + if (ext_info) + { + ti32->StackBase = PtrToUlong( ti->StackBase ); + ti32->StackLimit = PtrToUlong( ti->StackLimit ); + ti32->Win32StartAddress = PtrToUlong( ti->Win32StartAddress ); + ti32->TebBase = PtrToUlong( ti->TebBase ); + ti32->Reserved2 = ti->Reserved2; + ti32->Reserved3 = ti->Reserved3; + ti32->Reserved4 = ti->Reserved4; + } + } +#endif + +#ifndef __REACTOS__ + memcpy( (char *)proc32 + proc_len, proc->ProcessName.Buffer, + proc->ProcessName.MaximumLength ); +#else + memcpy((char *)proc32 + proc_len, proc->ImageName.Buffer, proc->ImageName.MaximumLength); +#endif + + if (prev) prev->NextEntryOffset = (char *)proc32 - (char *)prev; + prev = proc32; + } + +#ifndef __REACTOS__ + outpos += proc_len + proc->ProcessName.MaximumLength; +#else + outpos += proc_len + proc->ImageName.MaximumLength; +#endif + inpos += proc->NextEntryOffset; + if (!proc->NextEntryOffset) break; + } + if (retlen) *retlen = outpos; + if (outpos <= len) return STATUS_SUCCESS; + else return STATUS_INFO_LENGTH_MISMATCH; +} + +/********************************************************************** + * wow64_NtDisplayString + */ +NTSTATUS WINAPI wow64_NtDisplayString( UINT *args ) +{ + const UNICODE_STRING32 *str32 = get_ptr( &args ); + + UNICODE_STRING str; + + return NtDisplayString( unicode_str_32to64( &str, str32 )); +} + + +/********************************************************************** + * wow64_NtInitiatePowerAction + */ +NTSTATUS WINAPI wow64_NtInitiatePowerAction( UINT *args ) +{ + POWER_ACTION action = get_ulong( &args ); + SYSTEM_POWER_STATE state = get_ulong( &args ); + ULONG flags = get_ulong( &args ); + BOOLEAN async = get_ulong( &args ); + + return NtInitiatePowerAction( action, state, flags, async ); +} + + +/********************************************************************** + * wow64_NtLoadDriver + */ +NTSTATUS WINAPI wow64_NtLoadDriver( UINT *args ) +{ + UNICODE_STRING32 *str32 = get_ptr( &args ); + + UNICODE_STRING str; + + return NtLoadDriver( unicode_str_32to64( &str, str32 )); +} + + +/********************************************************************** + * wow64_NtPowerInformation + */ +NTSTATUS WINAPI wow64_NtPowerInformation( UINT *args ) +{ + POWER_INFORMATION_LEVEL level = get_ulong( &args ); + void *in_buf = get_ptr( &args ); + ULONG in_len = get_ulong( &args ); + void *out_buf = get_ptr( &args ); + ULONG out_len = get_ulong( &args ); + + switch (level) + { + case SystemPowerCapabilities: /* SYSTEM_POWER_CAPABILITIES */ + case SystemBatteryState: /* SYSTEM_BATTERY_STATE */ + case SystemExecutionState: /* ULONG */ + case ProcessorInformation: /* PROCESSOR_POWER_INFORMATION */ + return NtPowerInformation( level, in_buf, in_len, out_buf, out_len ); + + default: + FIXME( "unsupported level %u\n", level ); + return STATUS_NOT_IMPLEMENTED; + } +} + +#ifndef __REACTOS__ +/********************************************************************** + * wow64_NtQueryLicenseValue + */ +NTSTATUS WINAPI wow64_NtQueryLicenseValue( UINT *args ) +{ + UNICODE_STRING32 *str32 = get_ptr( &args ); + ULONG *type = get_ptr( &args ); + void *buffer = get_ptr( &args ); + ULONG len = get_ulong( &args ); + ULONG *retlen = get_ptr( &args ); + + UNICODE_STRING str; + + return NtQueryLicenseValue( unicode_str_32to64( &str, str32 ), type, buffer, len, retlen ); +} +#endif + +/********************************************************************** + * wow64_NtQuerySystemEnvironmentValue + */ +NTSTATUS WINAPI wow64_NtQuerySystemEnvironmentValue( UINT *args ) +{ + UNICODE_STRING32 *str32 = get_ptr( &args ); + WCHAR *buffer = get_ptr( &args ); + ULONG len = get_ulong( &args ); + ULONG *retlen = get_ptr( &args ); + + UNICODE_STRING str; + + return NtQuerySystemEnvironmentValue( unicode_str_32to64( &str, str32 ), buffer, len, retlen ); +} + + +/********************************************************************** + * wow64_NtQuerySystemEnvironmentValueEx + */ +NTSTATUS WINAPI wow64_NtQuerySystemEnvironmentValueEx( UINT *args ) +{ + UNICODE_STRING32 *str32 = get_ptr( &args ); + GUID *vendor = get_ptr( &args ); + void *buffer = get_ptr( &args ); + ULONG *retlen = get_ptr( &args ); + ULONG *attrib = get_ptr( &args ); + + UNICODE_STRING str; + + return NtQuerySystemEnvironmentValueEx( unicode_str_32to64( &str, str32 ), + vendor, buffer, retlen, attrib ); +} + + +/********************************************************************** + * wow64_NtQuerySystemInformation + */ +NTSTATUS WINAPI wow64_NtQuerySystemInformation( UINT *args ) +{ + SYSTEM_INFORMATION_CLASS class = get_ulong( &args ); + void *ptr = get_ptr( &args ); + ULONG len = get_ulong( &args ); + ULONG *retlen = get_ptr( &args ); + + NTSTATUS status; + + switch (class) + { + case SystemPerformanceInformation: /* SYSTEM_PERFORMANCE_INFORMATION */ + case SystemTimeOfDayInformation: /* SYSTEM_TIMEOFDAY_INFORMATION */ + case SystemProcessorPerformanceInformation: /* SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION */ + case SystemInterruptInformation: /* SYSTEM_INTERRUPT_INFORMATION */ + case SystemTimeAdjustmentInformation: /* SYSTEM_TIME_ADJUSTMENT_QUERY */ + case SystemKernelDebuggerInformation: /* SYSTEM_KERNEL_DEBUGGER_INFORMATION */ + case SystemCurrentTimeZoneInformation: /* RTL_TIME_ZONE_INFORMATION */ + case SystemRecommendedSharedDataAlignment: /* ULONG */ + case SystemFirmwareTableInformation: /* SYSTEM_FIRMWARE_TABLE_INFORMATION */ + case SystemProcessorIdleCycleTimeInformation: /* ULONG64[] */ +#ifndef __REACTOS__ + case SystemDynamicTimeZoneInformation: /* RTL_DYNAMIC_TIME_ZONE_INFORMATION */ + case SystemCodeIntegrityInformation: /* SYSTEM_CODEINTEGRITY_INFORMATION */ + case SystemKernelDebuggerInformationEx: /* SYSTEM_KERNEL_DEBUGGER_INFORMATION_EX */ + case SystemCpuSetInformation: /* SYSTEM_CPU_SET_INFORMATION */ + case SystemProcessorBrandString: /* char[] */ + case SystemProcessorFeaturesInformation: /* SYSTEM_PROCESSOR_FEATURES_INFORMATION */ + case SystemWineVersionInformation: /* char[] */ +#else + case SystemProcessorInformation: +#endif + return NtQuerySystemInformation( class, ptr, len, retlen ); + +#ifndef __REACTOS__ + /* FIXME */ + case SystemCpuInformation: /* SYSTEM_CPU_INFORMATION */ + case SystemEmulationProcessorInformation: /* SYSTEM_CPU_INFORMATION */ + status = NtQuerySystemInformation( SystemEmulationProcessorInformation, ptr, len, retlen ); + if (!status && pBTCpuUpdateProcessorInformation) pBTCpuUpdateProcessorInformation( ptr ); + return status; +#endif + + case SystemBasicInformation: /* SYSTEM_BASIC_INFORMATION */ + case SystemEmulationBasicInformation: /* SYSTEM_BASIC_INFORMATION */ + if (len == sizeof(SYSTEM_BASIC_INFORMATION32)) + { + SYSTEM_BASIC_INFORMATION info; + SYSTEM_BASIC_INFORMATION32 *info32 = ptr; + + if (!(status = NtQuerySystemInformation( SystemEmulationBasicInformation, &info, sizeof(info), NULL ))) + put_system_basic_information( info32, &info ); + } + else status = STATUS_INFO_LENGTH_MISMATCH; + if (retlen) *retlen = sizeof(SYSTEM_BASIC_INFORMATION32); + return status; + + /* FIXME */ + case SystemProcessInformation: /* SYSTEM_PROCESS_INFORMATION */ + case SystemExtendedProcessInformation: /* SYSTEM_PROCESS_INFORMATION */ + { + ULONG size = len * 2, retsize; + SYSTEM_PROCESS_INFORMATION *info = Wow64AllocateTemp( size ); + + status = NtQuerySystemInformation( class, info, size, &retsize ); + if (status) + { + if (status == STATUS_INFO_LENGTH_MISMATCH && retlen) *retlen = retsize; + return status; + } + return put_system_proc_info( ptr, info, class == SystemExtendedProcessInformation, len, retlen ); + } + +#ifndef __REACTOS__ + case SystemModuleInformation: /* RTL_PROCESS_MODULES */ + if (len >= sizeof(RTL_PROCESS_MODULES32)) + { + RTL_PROCESS_MODULES *info; + RTL_PROCESS_MODULES32 *info32 = ptr; + ULONG count = (len - offsetof( RTL_PROCESS_MODULES32, Modules )) / sizeof(info32->Modules[0]); + ULONG i, size = offsetof( RTL_PROCESS_MODULES, Modules[count] ); + + info = Wow64AllocateTemp( size ); + if (!(status = NtQuerySystemInformation( class, info, size, retlen ))) + { + info32->ModulesCount = info->ModulesCount; + for (i = 0; i < info->ModulesCount; i++) + { + info32->Modules[i].Section = HandleToULong( info->Modules[i].Section ); + info32->Modules[i].MappedBaseAddress = 0; + info32->Modules[i].ImageBaseAddress = 0; + info32->Modules[i].ImageSize = info->Modules[i].ImageSize; + info32->Modules[i].Flags = info->Modules[i].Flags; + info32->Modules[i].LoadOrderIndex = info->Modules[i].LoadOrderIndex; + info32->Modules[i].InitOrderIndex = info->Modules[i].InitOrderIndex; + info32->Modules[i].LoadCount = info->Modules[i].LoadCount; + info32->Modules[i].NameOffset = info->Modules[i].NameOffset; + strcpy( (char *)info32->Modules[i].Name, (char *)info->Modules[i].Name ); + } + } + } + else status = NtQuerySystemInformation( class, NULL, 0, retlen ); + + if (retlen) + { + ULONG count = (*retlen - offsetof(RTL_PROCESS_MODULES, Modules)) / sizeof(RTL_PROCESS_MODULE_INFORMATION32); + *retlen = offsetof( RTL_PROCESS_MODULES32, Modules[count] ); + } + return status; + + case SystemProcessIdInformation: /* SYSTEM_PROCESS_ID_INFORMATION */ + { + SYSTEM_PROCESS_ID_INFORMATION32 *info32 = ptr; + SYSTEM_PROCESS_ID_INFORMATION info; + + if (retlen) *retlen = sizeof(*info32); + if (len < sizeof(*info32)) return STATUS_INFO_LENGTH_MISMATCH; + + info.ProcessId = info32->ProcessId; + unicode_str_32to64( &info.ImageName, &info32->ImageName ); + if (!(status = NtQuerySystemInformation( class, &info, sizeof(info), NULL ))) + { + info32->ImageName.MaximumLength = info.ImageName.MaximumLength; + info32->ImageName.Length = info.ImageName.Length; + } + return status; + } +#endif + case SystemHandleInformation: /* SYSTEM_HANDLE_INFORMATION */ + if (len >= sizeof(SYSTEM_HANDLE_INFORMATION32)) + { + SYSTEM_HANDLE_INFORMATION *info; + SYSTEM_HANDLE_INFORMATION32 *info32 = ptr; + ULONG count = (len - offsetof(SYSTEM_HANDLE_INFORMATION32, Handle)) / sizeof(SYSTEM_HANDLE_ENTRY32); + ULONG i, size = offsetof( SYSTEM_HANDLE_INFORMATION, Handles[count] ); + + info = Wow64AllocateTemp( size ); +#ifndef __REACTOS__ + if (!(status = NtQuerySystemInformation(class, info, size, retlen))) + { + info32->Count = info->Count; + for (i = 0; i < info->Count; i++) + { + info32->Handle[i].OwnerPid = info->Handle[i].OwnerPid; + info32->Handle[i].ObjectType = info->Handle[i].ObjectType; + info32->Handle[i].HandleFlags = info->Handle[i].HandleFlags; + info32->Handle[i].HandleValue = info->Handle[i].HandleValue; + info32->Handle[i].ObjectPointer = PtrToUlong( info->Handle[i].ObjectPointer ); + info32->Handle[i].AccessMask = info->Handle[i].AccessMask; + } + } +#else + status = NtQuerySystemInformation(class, info, size, retlen); + /* NtQuertSystemInformation can return STATUS_INFO_LENGTH_MISMATCH if less handles + are requested than there are in the system. We should still copy data for + the number of handles we did manage to capture. */ + if (NT_SUCCESS(status) || status == STATUS_INFO_LENGTH_MISMATCH) + { + info32->Count = info->NumberOfHandles; + for (i = 0; i < min(count, info->NumberOfHandles); i++) + { + info32->Handle[i].OwnerPid = info->Handles[i].UniqueProcessId; + info32->Handle[i].ObjectType = info->Handles[i].ObjectTypeIndex; + info32->Handle[i].HandleFlags = info->Handles[i].HandleAttributes; + info32->Handle[i].HandleValue = info->Handles[i].HandleValue; + info32->Handle[i].ObjectPointer = PtrToUlong( info->Handles[i].Object ); + info32->Handle[i].AccessMask = info->Handles[i].GrantedAccess; + } + } +#endif + if (retlen) + { +#ifndef __REACTOS__ + ULONG count = (*retlen - offsetof(SYSTEM_HANDLE_INFORMATION, Handle)) / sizeof(SYSTEM_HANDLE_ENTRY); +#else + ULONG count = (*retlen - offsetof(SYSTEM_HANDLE_INFORMATION, Handles)) / sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO); +#endif + *retlen = offsetof( SYSTEM_HANDLE_INFORMATION32, Handle[count] ); + } + return status; + } + else return STATUS_INFO_LENGTH_MISMATCH; + case SystemFileCacheInformation: /* SYSTEM_CACHE_INFORMATION */ + if (len >= sizeof(SYSTEM_CACHE_INFORMATION32)) + { +#ifndef __REACTOS__ + SYSTEM_CACHE_INFORMATION info; +#else + SYSTEM_FILECACHE_INFORMATION info; +#endif + SYSTEM_CACHE_INFORMATION32 *info32 = ptr; + + if (!(status = NtQuerySystemInformation( class, &info, sizeof(info), NULL ))) + { + info32->CurrentSize = info.CurrentSize; + info32->PeakSize = info.PeakSize; + info32->PageFaultCount = info.PageFaultCount; + info32->MinimumWorkingSet = info.MinimumWorkingSet; + info32->MaximumWorkingSet = info.MaximumWorkingSet; + info32->CurrentSizeIncludingTransitionInPages = info.CurrentSizeIncludingTransitionInPages; + info32->PeakSizeIncludingTransitionInPages = info.PeakSizeIncludingTransitionInPages; + info32->TransitionRePurposeCount = info.TransitionRePurposeCount; + info32->Flags = info.Flags; + } + } + else status = STATUS_INFO_LENGTH_MISMATCH; + if (retlen) *retlen = sizeof(SYSTEM_CACHE_INFORMATION32); + return status; + case SystemRegistryQuotaInformation: /* SYSTEM_REGISTRY_QUOTA_INFORMATION */ + if (len >= sizeof(SYSTEM_REGISTRY_QUOTA_INFORMATION32)) + { + SYSTEM_REGISTRY_QUOTA_INFORMATION info; + SYSTEM_REGISTRY_QUOTA_INFORMATION32 *info32 = ptr; + + if (!(status = NtQuerySystemInformation( class, &info, sizeof(info), NULL ))) + { + info32->RegistryQuotaAllowed = info.RegistryQuotaAllowed; + info32->RegistryQuotaUsed = info.RegistryQuotaUsed; +#ifndef __REACTOS__ + info32->Reserved1 = PtrToUlong( info.Reserved1 ); +#else + info32->PagedPoolSize = info.PagedPoolSize; +#endif + } + } + else status = STATUS_INFO_LENGTH_MISMATCH; + if (retlen) *retlen = sizeof(SYSTEM_REGISTRY_QUOTA_INFORMATION32); + return status; + + case SystemExtendedHandleInformation: /* SYSTEM_HANDLE_INFORMATION_EX */ + if (len >= sizeof(SYSTEM_HANDLE_INFORMATION_EX32)) + { + SYSTEM_HANDLE_INFORMATION_EX *info; + SYSTEM_HANDLE_INFORMATION_EX32 *info32 = ptr; + ULONG count = (len - offsetof(SYSTEM_HANDLE_INFORMATION_EX32, Handles)) / sizeof(info32->Handles[0]); +#ifndef __REACTOS__ + ULONG i, size = offsetof( SYSTEM_HANDLE_INFORMATION_EX, Handles[count] ); +#else + ULONG i, size = offsetof( SYSTEM_HANDLE_INFORMATION_EX, Handle[count] ); +#endif + + if (!ptr) return STATUS_ACCESS_VIOLATION; + info = Wow64AllocateTemp( size ); + if (!(status = NtQuerySystemInformation( class, info, size, retlen ))) + { +#ifndef __REACTOS__ + info32->NumberOfHandles = info->NumberOfHandles; +#else + info32->NumberOfHandles = info->Count; +#endif + info32->Reserved = info->Reserved; +#ifndef __REACTOS__ + for (i = 0; i < info->NumberOfHandles; i++) + { + info32->Handles[i].Object = PtrToUlong( info->Handles[i].Object ); + info32->Handles[i].UniqueProcessId = info->Handles[i].UniqueProcessId; + info32->Handles[i].HandleValue = info->Handles[i].HandleValue; + info32->Handles[i].GrantedAccess = info->Handles[i].GrantedAccess; + info32->Handles[i].CreatorBackTraceIndex = info->Handles[i].CreatorBackTraceIndex; + info32->Handles[i].ObjectTypeIndex = info->Handles[i].ObjectTypeIndex; + info32->Handles[i].HandleAttributes = info->Handles[i].HandleAttributes; + info32->Handles[i].Reserved = info->Handles[i].Reserved; + } +#else + for (i = 0; i < info->Count; i++) + { + info32->Handles[i].Object = PtrToUlong( info->Handle[i].Object ); + info32->Handles[i].UniqueProcessId = info->Handle[i].UniqueProcessId; + info32->Handles[i].HandleValue = info->Handle[i].HandleValue; + info32->Handles[i].GrantedAccess = info->Handle[i].GrantedAccess; + info32->Handles[i].CreatorBackTraceIndex = info->Handle[i].CreatorBackTraceIndex; + info32->Handles[i].ObjectTypeIndex = info->Handle[i].ObjectTypeIndex; + info32->Handles[i].HandleAttributes = info->Handle[i].HandleAttributes; + info32->Handles[i].Reserved = info->Handle[i].Reserved; + } +#endif + } + if (retlen) + { +#ifndef __REACTOS__ + ULONG count = (*retlen - offsetof(SYSTEM_HANDLE_INFORMATION_EX, Handles)) / sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX); +#else + ULONG count = (*retlen - offsetof(SYSTEM_HANDLE_INFORMATION_EX, Handle)) / sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX); +#endif + *retlen = offsetof( SYSTEM_HANDLE_INFORMATION_EX32, Handles[count] ); + } + return status; + } + else return STATUS_INFO_LENGTH_MISMATCH; + + case SystemLogicalProcessorInformation: /* SYSTEM_LOGICAL_PROCESSOR_INFORMATION */ + { + SYSTEM_LOGICAL_PROCESSOR_INFORMATION *info; + SYSTEM_LOGICAL_PROCESSOR_INFORMATION32 *info32 = ptr; + ULONG i, size, count; + + info = Wow64AllocateTemp( len * 2 ); + status = NtQuerySystemInformation( class, info, len * 2, &size ); + if (status && status != STATUS_INFO_LENGTH_MISMATCH) return status; + count = size / sizeof(*info); + if (!status && len >= count * sizeof(*info32)) + { + for (i = 0; i < count; i++) + { + info32[i].ProcessorMask = info[i].ProcessorMask; + info32[i].Relationship = info[i].Relationship; + info32[i].Reserved[0] = info[i].Reserved[0]; + info32[i].Reserved[1] = info[i].Reserved[1]; + } + } + else status = STATUS_INFO_LENGTH_MISMATCH; + if (retlen) *retlen = count * sizeof(*info32); + return status; + } + + case SystemModuleInformationEx: /* RTL_PROCESS_MODULE_INFORMATION_EX */ + if (len >= sizeof(RTL_PROCESS_MODULE_INFORMATION_EX) + sizeof(USHORT)) + { + RTL_PROCESS_MODULE_INFORMATION_EX *info; + RTL_PROCESS_MODULE_INFORMATION_EX32 *info32 = ptr; + ULONG count = (len - sizeof(info32->NextOffset)) / sizeof(*info32); + ULONG i, size = count * sizeof(*info) + sizeof(info->NextOffset); + + info = Wow64AllocateTemp( size ); + if (!(status = NtQuerySystemInformation( class, info, size, retlen ))) + { + RTL_PROCESS_MODULE_INFORMATION_EX *mod = info; + for (i = 0; mod->NextOffset; i++) + { + info32[i].NextOffset = sizeof(*info32); +#ifndef __REACTOS__ + info32[i].BaseInfo.Section = HandleToULong( mod->BaseInfo.Section ); +#else + info32[i].BaseInfo.Section = mod->BaseInfo.Section; +#endif + info32[i].BaseInfo.MappedBaseAddress = 0; + info32[i].BaseInfo.ImageBaseAddress = 0; + info32[i].BaseInfo.ImageSize = mod->BaseInfo.ImageSize; + info32[i].BaseInfo.Flags = mod->BaseInfo.Flags; + info32[i].BaseInfo.LoadOrderIndex = mod->BaseInfo.LoadOrderIndex; + info32[i].BaseInfo.InitOrderIndex = mod->BaseInfo.InitOrderIndex; + info32[i].BaseInfo.LoadCount = mod->BaseInfo.LoadCount; +#ifndef __REACTOS__ + info32[i].BaseInfo.NameOffset = mod->BaseInfo.NameOffset; +#else + info32[i].BaseInfo.NameOffset = mod->BaseInfo.OffsetToFileName; +#endif + info32[i].ImageCheckSum = mod->ImageCheckSum; + info32[i].TimeDateStamp = mod->TimeDateStamp; + info32[i].DefaultBase = 0; +#ifndef __REACTOS__ + strcpy( (char *)info32[i].BaseInfo.Name, (char *)mod->BaseInfo.Name ); +#else + strcpy( (char *)info32[i].BaseInfo.Name, (char *)mod->BaseInfo.FullPathName ); +#endif + mod = (RTL_PROCESS_MODULE_INFORMATION_EX *)((char *)mod + mod->NextOffset); + } + info32[i].NextOffset = 0; + } + } + else status = NtQuerySystemInformation( class, NULL, 0, retlen ); + + if (retlen) + { + ULONG count = (*retlen - sizeof(USHORT)) / sizeof(RTL_PROCESS_MODULE_INFORMATION_EX); + *retlen = count * sizeof(RTL_PROCESS_MODULE_INFORMATION_EX32) + sizeof(USHORT); + } + return status; + +#ifndef __REACTOS__ + case SystemNativeBasicInformation: + return STATUS_INVALID_INFO_CLASS; +#endif + +#ifdef __REACTOS__ + case SystemRangeStartInformation: + { + ULONG *pRangeStart32 = ptr; + ULONG_PTR rangeStart; + + if (retlen) *retlen = sizeof(*pRangeStart32); + if (len < sizeof(*pRangeStart32)) return STATUS_INFO_LENGTH_MISMATCH; + + rangeStart = *pRangeStart32; + + if (!(status = NtQuerySystemInformation( class, &rangeStart, sizeof(rangeStart), NULL ))) + { + if (rangeStart > ULONG_MAX) + { + rangeStart = ULONG_MAX; + } + *pRangeStart32 = (ULONG) rangeStart; + } + return status; + } +#endif + + default: + FIXME( "unsupported class %u\n", class ); + return STATUS_INVALID_INFO_CLASS; + } +} + +#ifndef __REACTOS__ +/********************************************************************** + * wow64_NtQuerySystemInformationEx + */ +NTSTATUS WINAPI wow64_NtQuerySystemInformationEx( UINT *args ) +{ + SYSTEM_INFORMATION_CLASS class = get_ulong( &args ); + void *query = get_ptr( &args ); + ULONG query_len = get_ulong( &args ); + void *ptr = get_ptr( &args ); + ULONG len = get_ulong( &args ); + ULONG *retlen = get_ptr( &args ); + + HANDLE handle; + NTSTATUS status; + + switch (class) + { + case SystemProcessorIdleCycleTimeInformation: + return NtQuerySystemInformationEx( class, query, query_len, ptr, len, retlen ); + case SystemLogicalProcessorInformationEx: /* SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX */ + { + SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX32 *ex32, *info32 = ptr; + SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *ex, *info; + ULONG size, size32, pos = 0, pos32 = 0; + + if (!query || query_len < sizeof(LONG)) return STATUS_INVALID_PARAMETER; + handle = LongToHandle( *(LONG *)query ); + status = NtQuerySystemInformationEx( class, &handle, sizeof(handle), NULL, 0, &size ); + if (status != STATUS_INFO_LENGTH_MISMATCH) return status; + info = Wow64AllocateTemp( size ); + status = NtQuerySystemInformationEx( class, &handle, sizeof(handle), info, size, &size ); + if (!status) + { + for (pos = pos32 = 0; pos < size; pos += ex->Size, pos32 += size32) + { + ex = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)((char *)info + pos); + ex32 = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX32 *)((char *)info32 + pos32); + + switch (ex->Relationship) + { + case RelationProcessorCore: + case RelationProcessorPackage: + size32 = offsetof( SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX32, + Processor.GroupMask[ex->Processor.GroupCount] ); + break; + case RelationNumaNode: + size32 = offsetof( SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX32, NumaNode ) + sizeof( ex32->NumaNode ); + break; + case RelationCache: + size32 = offsetof( SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX32, Cache ) + sizeof( ex32->Cache ); + break; + case RelationGroup: + size32 = offsetof( SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX32, + Group.GroupInfo[ex->Group.MaximumGroupCount] ); + break; + default: + size32 = 0; + continue; + } + if (pos32 + size32 <= len) put_logical_proc_info_ex( ex32, ex ); + } + if (pos32 > len) status = STATUS_INFO_LENGTH_MISMATCH; + size = pos32; + } + if (retlen) *retlen = size; + return status; + } + case SystemCpuSetInformation: /* SYSTEM_CPU_SET_INFORMATION */ + case SystemSupportedProcessorArchitectures: /* SYSTEM_SUPPORTED_PROCESSOR_ARCHITECTURES_INFORMATION */ + if (!query || query_len < sizeof(LONG)) return STATUS_INVALID_PARAMETER; + handle = LongToHandle( *(LONG *)query ); + return NtQuerySystemInformationEx( class, &handle, sizeof(handle), ptr, len, retlen ); + default: + FIXME( "unsupported class %u\n", class ); + return STATUS_INVALID_INFO_CLASS; + } +} +#endif + +/********************************************************************** + * wow64_NtQuerySystemTime + */ +NTSTATUS WINAPI wow64_NtQuerySystemTime( UINT *args ) +{ + LARGE_INTEGER *time = get_ptr( &args ); + + return NtQuerySystemTime( time ); +} + + +/********************************************************************** + * wow64_NtRaiseHardError + */ +NTSTATUS WINAPI wow64_NtRaiseHardError( UINT *args ) +{ + NTSTATUS status = get_ulong( &args ); + ULONG count = get_ulong( &args ); + ULONG params_mask = get_ulong( &args ); + ULONG *params = get_ptr( &args ); + HARDERROR_RESPONSE_OPTION option = get_ulong( &args ); + HARDERROR_RESPONSE *response = get_ptr( &args ); +#ifdef __REACTOS__ + ULONG_PTR *HardErrorParameters; + int i; +#endif + +#ifndef __REACTOS__ + FIXME( "%08lx %lu %lx %p %u %p: stub\n", status, count, params_mask, params, option, response ); + assert(FALSE); + return STATUS_NOT_IMPLEMENTED; +#else + HardErrorParameters = Wow64AllocateTemp(count * sizeof(*HardErrorParameters)); + for (i = 0; i < count; i++) + { + HardErrorParameters[i] = params[i]; + } + + return NtRaiseHardError(status, + count, + params_mask, + HardErrorParameters, + option, + (PULONG)response); +#endif +} + + +/********************************************************************** + * wow64_NtSetIntervalProfile + */ +NTSTATUS WINAPI wow64_NtSetIntervalProfile( UINT *args ) +{ + ULONG interval = get_ulong( &args ); + KPROFILE_SOURCE source = get_ulong( &args ); + + return NtSetIntervalProfile( interval, source ); +} + + +/********************************************************************** + * wow64_NtSetSystemInformation + */ +NTSTATUS WINAPI wow64_NtSetSystemInformation( UINT *args ) +{ + SYSTEM_INFORMATION_CLASS class = get_ulong( &args ); + void *info = get_ptr( &args ); + ULONG len = get_ulong( &args ); + +#ifdef __REACTOS__ + /* FIXME???? */ +#endif + return NtSetSystemInformation( class, info, len ); +} + + +/********************************************************************** + * wow64_NtSetSystemTime + */ +NTSTATUS WINAPI wow64_NtSetSystemTime( UINT *args ) +{ +#ifndef __REACTOS__ + const LARGE_INTEGER *new = get_ptr( &args ); +#else + LARGE_INTEGER *new = get_ptr( &args ); +#endif + LARGE_INTEGER *old = get_ptr( &args ); + + return NtSetSystemTime( new, old ); +} + + +/********************************************************************** + * wow64_NtShutdownSystem + */ +NTSTATUS WINAPI wow64_NtShutdownSystem( UINT *args ) +{ + SHUTDOWN_ACTION action = get_ulong( &args ); + + return NtShutdownSystem( action ); +} + + +/********************************************************************** + * wow64_NtSystemDebugControl + */ +NTSTATUS WINAPI wow64_NtSystemDebugControl( UINT *args ) +{ + SYSDBG_COMMAND command = get_ulong( &args ); + void *in_buf = get_ptr( &args ); + ULONG in_len = get_ulong( &args ); + void *out_buf = get_ptr( &args ); + ULONG out_len = get_ulong( &args ); + ULONG *retlen = get_ptr( &args ); + + switch (command) + { + case SysDbgBreakPoint: + case SysDbgEnableKernelDebugger: + case SysDbgDisableKernelDebugger: + case SysDbgGetAutoKdEnable: + case SysDbgSetAutoKdEnable: + case SysDbgGetPrintBufferSize: + case SysDbgSetPrintBufferSize: + case SysDbgGetKdUmExceptionEnable: + case SysDbgSetKdUmExceptionEnable: + case SysDbgGetTriageDump: + case SysDbgGetKdBlockEnable: + case SysDbgSetKdBlockEnable: +#ifndef __REACTOS__ + case SysDbgRegisterForUmBreakInfo: + case SysDbgGetUmBreakPid: + case SysDbgClearUmBreakPid: + case SysDbgGetUmAttachPid: + case SysDbgClearUmAttachPid: +#endif + return NtSystemDebugControl( command, in_buf, in_len, out_buf, out_len, retlen ); + + default: + return STATUS_NOT_IMPLEMENTED; /* not implemented on Windows either */ + } +} + + +/********************************************************************** + * wow64_NtUnloadDriver + */ +NTSTATUS WINAPI wow64_NtUnloadDriver( UINT *args ) +{ + UNICODE_STRING32 *str32 = get_ptr( &args ); + + UNICODE_STRING str; + + return NtUnloadDriver( unicode_str_32to64( &str, str32 )); +} + +#ifndef __REACTOS__ +/********************************************************************** + * wow64_NtWow64GetNativeSystemInformation + */ +NTSTATUS WINAPI wow64_NtWow64GetNativeSystemInformation( UINT *args ) +{ + ULONG class = get_ulong( &args ); + void *ptr = get_ptr( &args ); + ULONG len = get_ulong( &args ); + ULONG *retlen = get_ptr( &args ); + + NTSTATUS status; + + switch (class) + { + case SystemBasicInformation: + case SystemEmulationBasicInformation: + if (len == sizeof(SYSTEM_BASIC_INFORMATION32)) + { + SYSTEM_BASIC_INFORMATION info; + SYSTEM_BASIC_INFORMATION32 *info32 = ptr; + + if (!(status = NtQuerySystemInformation( class, &info, sizeof(info), NULL ))) + put_system_basic_information( info32, &info ); + } + else status = STATUS_INFO_LENGTH_MISMATCH; + if (retlen) *retlen = sizeof(SYSTEM_BASIC_INFORMATION32); + return status; + case SystemCpuInformation: + case SystemEmulationProcessorInformation: + case SystemNativeBasicInformation: + return NtQuerySystemInformation( class, ptr, len, retlen ); + + default: + return STATUS_INVALID_INFO_CLASS; + } +} +#endif diff --git a/dll/wow64/wine/virtual.c b/dll/wow64/wine/virtual.c new file mode 100644 index 0000000000000..e7796fcfff035 --- /dev/null +++ b/dll/wow64/wine/virtual.c @@ -0,0 +1,969 @@ +/* + * WoW64 virtual memory functions + * + * Copyright 2021 Alexandre Julliard + * Copyright 2025 Marcin Jabłoński + * + * 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 + */ +#ifndef __REACTOS__ +#include + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "winnt.h" +#include "winternl.h" +#include "winioctl.h" +#include "wow64_private.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wow); +#else +#include "ros_wow64_private.h" +#endif + +#ifndef __REACTOS__ +static BOOL WINAPIV send_cross_process_notification( HANDLE process, UINT id, const void *addr, SIZE_T size, + int nb_args, ... ) +{ + CROSS_PROCESS_WORK_LIST *list; + CROSS_PROCESS_WORK_ENTRY *entry; + void *unused; + HANDLE section; + va_list args; + int i; + + RtlOpenCrossProcessEmulatorWorkConnection( process, §ion, (void **)&list ); + if (!list) return FALSE; + if ((entry = RtlWow64PopCrossProcessWorkFromFreeList( &list->free_list ))) + { + entry->id = id; + entry->addr = (ULONG_PTR)addr; + entry->size = size; + if (nb_args) + { + va_start( args, nb_args ); + for (i = 0; i < nb_args; i++) entry->args[i] = va_arg( args, int ); + va_end( args ); + } + RtlWow64PushCrossProcessWorkOntoWorkList( &list->work_list, entry, &unused ); + } + NtUnmapViewOfSection( GetCurrentProcess(), list ); + NtClose( section ); + return TRUE; +} + +static MEMORY_RANGE_ENTRY *memory_range_entry_array_32to64( const MEMORY_RANGE_ENTRY32 *addresses32, + ULONG count ) +{ + MEMORY_RANGE_ENTRY *addresses = Wow64AllocateTemp( sizeof(MEMORY_RANGE_ENTRY) * count ); + ULONG i; + + for (i = 0; i < count; i++) + { + addresses[i].VirtualAddress = ULongToPtr( addresses32[i].VirtualAddress ); + addresses[i].NumberOfBytes = addresses32[i].NumberOfBytes; + } + + return addresses; +} + +static NTSTATUS mem_extended_parameters_32to64( MEM_EXTENDED_PARAMETER **ret_params, + const MEM_EXTENDED_PARAMETER32 *params32, ULONG *count, + BOOL set_limit ) +{ + ULONG i; + MEM_EXTENDED_PARAMETER *params; + MEM_ADDRESS_REQUIREMENTS *req; + MEM_ADDRESS_REQUIREMENTS32 *req32 = NULL; + + if (*count && !params32) return STATUS_INVALID_PARAMETER; + + params = Wow64AllocateTemp( (*count + 1) * sizeof(*params) + sizeof(*req) ); + req = (MEM_ADDRESS_REQUIREMENTS *)(params + *count + 1); + + for (i = 0; i < *count; i++) + { + params[i].Type = params32[i].Type; + params[i].Reserved = 0; + switch (params[i].Type) + { + case MemExtendedParameterAddressRequirements: + req32 = ULongToPtr( params32[i].Pointer ); + params[i].Pointer = req; + break; + case MemExtendedParameterAttributeFlags: + case MemExtendedParameterNumaNode: + case MemExtendedParameterImageMachine: + params[i].ULong = params32[i].ULong; + break; + case MemExtendedParameterPartitionHandle: + case MemExtendedParameterUserPhysicalHandle: + params[i].Handle = ULongToHandle( params32[i].Handle ); + break; + } + } + + if (req32) + { + if (req32->HighestEndingAddress > highest_user_address) return STATUS_INVALID_PARAMETER; + req->LowestStartingAddress = ULongToPtr( req32->LowestStartingAddress ); + req->HighestEndingAddress = ULongToPtr( req32->HighestEndingAddress ); + req->Alignment = req32->Alignment; + } + else if (set_limit) + { + req->LowestStartingAddress = NULL; + req->HighestEndingAddress = (void *)highest_user_address; + req->Alignment = 0; + + params[i].Type = MemExtendedParameterAddressRequirements; + params[i].Reserved = 0; + params[i].Pointer = req; + *count = i + 1; + } + *ret_params = params; + return STATUS_SUCCESS; +} +#endif + +/********************************************************************** + * wow64_NtAllocateVirtualMemory + */ +NTSTATUS WINAPI wow64_NtAllocateVirtualMemory( UINT *args ) +{ + HANDLE process = get_handle( &args ); + ULONG *addr32 = get_ptr( &args ); + ULONG_PTR zero_bits = get_ulong( &args ); + ULONG *size32 = get_ptr( &args ); + ULONG type = get_ulong( &args ); + ULONG protect = get_ulong( &args ); + + void *addr = ULongToPtr( *addr32 ); + SIZE_T size = *size32; +#ifndef __REACTOS__ + BOOL is_current = RtlIsCurrentProcess( process ); +#endif + NTSTATUS status; + + if (!addr && (type & MEM_COMMIT)) type |= MEM_RESERVE; + +#ifndef __REACTOS__ + if (!is_current) send_cross_process_notification( process, CrossProcessPreVirtualAlloc, + addr, size, 3, type, protect, 0 ); + else if (pBTCpuNotifyMemoryAlloc) pBTCpuNotifyMemoryAlloc( addr, size, type, protect, FALSE, 0 ); +#endif + + status = NtAllocateVirtualMemory( process, &addr, get_zero_bits( zero_bits ), &size, type, protect ); + +#ifndef __REACTOS__ + if (!is_current) send_cross_process_notification( process, CrossProcessPostVirtualAlloc, + addr, size, 3, type, protect, status ); + else if (pBTCpuNotifyMemoryAlloc) pBTCpuNotifyMemoryAlloc( addr, size, type, protect, TRUE, status ); +#endif + + if (!status) + { + put_addr( addr32, addr ); + put_size( size32, size ); + } + return status; +} + +#ifndef __REACTOS__ +/********************************************************************** + * wow64_NtAllocateVirtualMemoryEx + */ +NTSTATUS WINAPI wow64_NtAllocateVirtualMemoryEx( UINT *args ) +{ + HANDLE process = get_handle( &args ); + ULONG *addr32 = get_ptr( &args ); + ULONG *size32 = get_ptr( &args ); + ULONG type = get_ulong( &args ); + ULONG protect = get_ulong( &args ); + MEM_EXTENDED_PARAMETER32 *params32 = get_ptr( &args ); + ULONG count = get_ulong( &args ); + + void *addr = ULongToPtr( *addr32 ); + SIZE_T size = *size32; + NTSTATUS status; + MEM_EXTENDED_PARAMETER *params64; + BOOL is_current = RtlIsCurrentProcess( process ); + BOOL set_limit = (!*addr32 && is_current); + + if (!addr) type |= MEM_RESERVE; + + if ((status = mem_extended_parameters_32to64( ¶ms64, params32, &count, set_limit ))) return status; + + if (!is_current) send_cross_process_notification( process, CrossProcessPreVirtualAlloc, + addr, size, 3, type, protect, 0 ); + else if (pBTCpuNotifyMemoryAlloc) pBTCpuNotifyMemoryAlloc( addr, size, type, protect, FALSE, 0 ); + + status = NtAllocateVirtualMemoryEx( process, &addr, &size, type, protect, params64, count ); + + if (!is_current) send_cross_process_notification( process, CrossProcessPostVirtualAlloc, + addr, size, 3, type, protect, status ); + else if (pBTCpuNotifyMemoryAlloc) pBTCpuNotifyMemoryAlloc( addr, size, type, protect, TRUE, status ); + + if (!status) + { + put_addr( addr32, addr ); + put_size( size32, size ); + } + return status; +} +#endif + +/********************************************************************** + * wow64_NtAreMappedFilesTheSame + */ +NTSTATUS WINAPI wow64_NtAreMappedFilesTheSame( UINT *args ) +{ + void *ptr1 = get_ptr( &args ); + void *ptr2 = get_ptr( &args ); + + return NtAreMappedFilesTheSame( ptr1, ptr2 ); +} + + +/********************************************************************** + * wow64_NtFlushInstructionCache + */ +NTSTATUS WINAPI wow64_NtFlushInstructionCache( UINT *args ) +{ + HANDLE process = get_handle( &args ); +#ifndef __REACTOS__ + const void *addr = get_ptr( &args ); +#else + void *addr = get_ptr( &args ); +#endif + SIZE_T size = get_ulong( &args ); +#ifndef __REACTOS__ + if (RtlIsCurrentProcess( process )) + { + if (pBTCpuFlushInstructionCache2) pBTCpuFlushInstructionCache2( addr, size ); + } + else send_cross_process_notification( process, CrossProcessFlushCache, addr, size, 0 ); +#endif + return NtFlushInstructionCache( process, addr, size ); +} + + +/********************************************************************** + * wow64_NtFlushVirtualMemory + */ +NTSTATUS WINAPI wow64_NtFlushVirtualMemory( UINT *args ) +{ + HANDLE process = get_handle( &args ); + ULONG *addr32 = get_ptr( &args ); + ULONG *size32 = get_ptr( &args ); +#ifndef __REACTOS__ + ULONG unknown = get_ulong( &args ); +#else + IO_STATUS_BLOCK32* pIosb32 = get_ptr(&args); + IO_STATUS_BLOCK iosb64 = { 0 }; + iosb_32to64(&iosb64, pIosb32); +#endif + + void *addr; + SIZE_T size; + NTSTATUS status; + +#ifndef __REACTOS__ + status = NtFlushVirtualMemory( process, (const void **)addr_32to64( &addr, addr32 ), + size_32to64( &size, size32 ), unknown ); +#else + status = NtFlushVirtualMemory(process, (void **)addr_32to64(&addr, addr32), + size_32to64(&size, size32), &iosb64); +#endif + + if (!status) + { + put_addr( addr32, addr ); + put_size( size32, size ); + } + return status; +} + + +/********************************************************************** + * wow64_NtFreeVirtualMemory + */ +NTSTATUS WINAPI wow64_NtFreeVirtualMemory( UINT *args ) +{ + HANDLE process = get_handle( &args ); + ULONG *addr32 = get_ptr( &args ); + ULONG *size32 = get_ptr( &args ); + ULONG type = get_ulong( &args ); + + void *addr = ULongToPtr( *addr32 ); + SIZE_T size = *size32; +#ifndef __REACTOS__ + BOOL is_current = RtlIsCurrentProcess( process ); +#endif + NTSTATUS status; + +#ifndef __REACTOS__ + if (!is_current) send_cross_process_notification( process, CrossProcessPreVirtualFree, + addr, size, 2, type, 0 ); + else if (pBTCpuNotifyMemoryFree) pBTCpuNotifyMemoryFree( addr, size, type, FALSE, 0 ); +#endif + + status = NtFreeVirtualMemory( process, &addr, &size, type ); + +#ifndef __REACTOS__ + if (!is_current) send_cross_process_notification( process, CrossProcessPostVirtualFree, + addr, size, 2, type, status ); + else if (pBTCpuNotifyMemoryFree) pBTCpuNotifyMemoryFree( addr, size, type, TRUE, status ); +#endif + if (!status) + { + put_addr( addr32, addr ); + put_size( size32, size ); + } + return status; +} + + +#ifndef __REACTOS__ +/********************************************************************** + * wow64_NtGetNlsSectionPtr + */ +NTSTATUS WINAPI wow64_NtGetNlsSectionPtr( UINT *args ) +{ + ULONG type = get_ulong( &args ); + ULONG id = get_ulong( &args ); + void *unknown = get_ptr( &args ); + ULONG *addr32 = get_ptr( &args ); + ULONG *size32 = get_ptr( &args ); + + void *addr; + SIZE_T size; + NTSTATUS status; + + status = NtGetNlsSectionPtr( type, id, unknown, addr_32to64( &addr, addr32 ), + size_32to64( &size, size32 )); + if (!status) + { + put_addr( addr32, addr ); + put_size( size32, size ); + } + return status; +} +#endif + +/********************************************************************** + * wow64_NtGetWriteWatch + */ +NTSTATUS WINAPI wow64_NtGetWriteWatch( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + ULONG flags = get_ulong( &args ); + void *base = get_ptr( &args ); + SIZE_T size = get_ulong( &args ); + ULONG *addr_ptr = get_ptr( &args ); + ULONG *count_ptr = get_ptr( &args ); + ULONG *granularity = get_ptr( &args ); + + ULONG_PTR i, count = *count_ptr; + void **addresses; + NTSTATUS status; + + if (!count || !size) return STATUS_INVALID_PARAMETER; + if (flags & ~WRITE_WATCH_FLAG_RESET) return STATUS_INVALID_PARAMETER; + if (!addr_ptr) return STATUS_ACCESS_VIOLATION; + + addresses = Wow64AllocateTemp( count * sizeof(*addresses) ); + if (!(status = NtGetWriteWatch( handle, flags, base, size, addresses, &count, granularity ))) + { + for (i = 0; i < count; i++) addr_ptr[i] = PtrToUlong( addresses[i] ); + *count_ptr = count; + } + return status; +} + +#ifndef __REACTOS__ +/********************************************************************** + * wow64_NtInitializeNlsFiles + */ +NTSTATUS WINAPI wow64_NtInitializeNlsFiles( UINT *args ) +{ + ULONG *addr32 = get_ptr( &args ); + LCID *lcid = get_ptr( &args ); + LARGE_INTEGER *size = get_ptr( &args ); + + void *addr; + NTSTATUS status; + + status = NtInitializeNlsFiles( addr_32to64( &addr, addr32 ), lcid, size ); + if (!status) put_addr( addr32, addr ); + return status; +} +#endif + +/********************************************************************** + * wow64_NtLockVirtualMemory + */ +NTSTATUS WINAPI wow64_NtLockVirtualMemory( UINT *args ) +{ + HANDLE process = get_handle( &args ); + ULONG *addr32 = get_ptr( &args ); + ULONG *size32 = get_ptr( &args ); + ULONG unknown = get_ulong( &args ); + + void *addr; + SIZE_T size; + NTSTATUS status; + + status = NtLockVirtualMemory( process, addr_32to64( &addr, addr32 ), + size_32to64( &size, size32 ), unknown ); + if (!status) + { + put_addr( addr32, addr ); + put_size( size32, size ); + } + return status; +} + +#ifndef __REACTOS__ +static void notify_map_view_of_section( HANDLE handle, void *addr, SIZE_T size, ULONG alloc, + ULONG protect, NTSTATUS *ret_status ) +{ + SECTION_IMAGE_INFORMATION info; + NTSTATUS status; + + if (!NtCurrentTeb()->Tib.ArbitraryUserPointer) return; + if (NtQuerySection( handle, SectionImageInformation, &info, sizeof(info), NULL )) return; + if (info.Machine != current_machine) return; + init_image_mapping( addr ); + if (!pBTCpuNotifyMapViewOfSection) return; + status = pBTCpuNotifyMapViewOfSection( NULL, addr, NULL, size, alloc, protect ); + if (NT_SUCCESS(status)) return; + NtUnmapViewOfSection( GetCurrentProcess(), addr ); + *ret_status = status; +} +#endif + +/********************************************************************** + * wow64_NtMapViewOfSection + */ +NTSTATUS WINAPI wow64_NtMapViewOfSection( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + HANDLE process = get_handle( &args ); + ULONG *addr32 = get_ptr( &args ); + ULONG_PTR zero_bits = get_ulong( &args ); + SIZE_T commit = get_ulong( &args ); +#ifndef __REACTOS__ + const LARGE_INTEGER *offset = get_ptr( &args ); +#else + LARGE_INTEGER *offset = get_ptr( &args ); +#endif + ULONG *size32 = get_ptr( &args ); + SECTION_INHERIT inherit = get_ulong( &args ); + ULONG alloc = get_ulong( &args ); + ULONG protect = get_ulong( &args ); + + void *addr; + SIZE_T size; + NTSTATUS status; +#ifndef __REACTOS__ + void *prev = NtCurrentTeb()->Tib.ArbitraryUserPointer; +#else + void *prev = NtCurrentTeb()->NtTib.ArbitraryUserPointer; +#endif + +#ifndef __REACTOS__ + NtCurrentTeb()->Tib.ArbitraryUserPointer = ULongToPtr( NtCurrentTeb32()->Tib.ArbitraryUserPointer ); +#else + NtCurrentTeb()->NtTib.ArbitraryUserPointer = ULongToPtr( NtCurrentTeb32()->NtTib.ArbitraryUserPointer ); +#endif + status = NtMapViewOfSection( handle, process, addr_32to64( &addr, addr32 ), get_zero_bits( zero_bits ), + commit, offset, size_32to64( &size, size32 ), inherit, alloc, protect ); + if (NT_SUCCESS(status)) + { + put_addr( addr32, addr ); + put_size( size32, size ); +#ifndef __REACTOS__ + if (RtlIsCurrentProcess( process )) + notify_map_view_of_section( handle, addr, size, alloc, protect, &status ); +#endif + } +#ifndef __REACTOS__ + NtCurrentTeb()->Tib.ArbitraryUserPointer = prev; +#else + NtCurrentTeb()->NtTib.ArbitraryUserPointer = prev; +#endif + return status; +} + +#ifndef __REACTOS__ +/********************************************************************** + * wow64_NtMapViewOfSectionEx + */ +NTSTATUS WINAPI wow64_NtMapViewOfSectionEx( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + HANDLE process = get_handle( &args ); + ULONG *addr32 = get_ptr( &args ); + const LARGE_INTEGER *offset = get_ptr( &args ); + ULONG *size32 = get_ptr( &args ); + ULONG alloc = get_ulong( &args ); + ULONG protect = get_ulong( &args ); + MEM_EXTENDED_PARAMETER32 *params32 = get_ptr( &args ); + ULONG count = get_ulong( &args ); + + void *addr; + SIZE_T size; + NTSTATUS status; + MEM_EXTENDED_PARAMETER *params64; + BOOL is_current = RtlIsCurrentProcess( process ); + BOOL set_limit = (!*addr32 && is_current); + void *prev = NtCurrentTeb()->Tib.ArbitraryUserPointer; + + if ((status = mem_extended_parameters_32to64( ¶ms64, params32, &count, set_limit ))) return status; + + NtCurrentTeb()->Tib.ArbitraryUserPointer = ULongToPtr( NtCurrentTeb32()->Tib.ArbitraryUserPointer ); + status = NtMapViewOfSectionEx( handle, process, addr_32to64( &addr, addr32 ), offset, + size_32to64( &size, size32 ), alloc, protect, params64, count ); + if (NT_SUCCESS(status)) + { + put_addr( addr32, addr ); + put_size( size32, size ); + if (is_current) notify_map_view_of_section( handle, addr, size, alloc, protect, &status ); + } + NtCurrentTeb()->Tib.ArbitraryUserPointer = prev; + return status; +} +#endif + +/********************************************************************** + * wow64_NtProtectVirtualMemory + */ +NTSTATUS WINAPI wow64_NtProtectVirtualMemory( UINT *args ) +{ + HANDLE process = get_handle( &args ); + ULONG *addr32 = get_ptr( &args ); + ULONG *size32 = get_ptr( &args ); + ULONG new_prot = get_ulong( &args ); + ULONG *old_prot = get_ptr( &args ); + + void *addr = ULongToPtr( *addr32 ); + SIZE_T size = *size32; +#ifndef __REACTOS__ + BOOL is_current = RtlIsCurrentProcess( process ); +#endif + NTSTATUS status; + +#ifndef __REACTOS__ + if (!is_current) send_cross_process_notification( process, CrossProcessPreVirtualProtect, + addr, size, 2, new_prot, 0 ); + else if (pBTCpuNotifyMemoryProtect) pBTCpuNotifyMemoryProtect( addr, size, new_prot, FALSE, 0 ); +#endif + + status = NtProtectVirtualMemory( process, &addr, &size, new_prot, old_prot ); + +#ifndef __REACTOS__ + if (!is_current) send_cross_process_notification( process, CrossProcessPostVirtualProtect, + addr, size, 2, new_prot, status ); + else if (pBTCpuNotifyMemoryProtect) pBTCpuNotifyMemoryProtect( addr, size, new_prot, TRUE, status ); +#endif + + if (!status) + { + put_addr( addr32, addr ); + put_size( size32, size ); + } + return status; +} + + +/********************************************************************** + * wow64_NtQueryVirtualMemory + */ +NTSTATUS WINAPI wow64_NtQueryVirtualMemory( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + void *addr = get_ptr( &args ); + MEMORY_INFORMATION_CLASS class = get_ulong( &args ); + void *ptr = get_ptr( &args ); + ULONG len = get_ulong( &args ); + ULONG *retlen = get_ptr( &args ); + + SIZE_T res_len = 0; + NTSTATUS status; + + switch (class) + { + case MemoryBasicInformation: /* MEMORY_BASIC_INFORMATION */ + if (len < sizeof(MEMORY_BASIC_INFORMATION32)) + status = STATUS_INFO_LENGTH_MISMATCH; + else if ((ULONG_PTR)addr > highest_user_address) + status = STATUS_INVALID_PARAMETER; + else + { + MEMORY_BASIC_INFORMATION info; + MEMORY_BASIC_INFORMATION32 *info32 = ptr; + + if (!(status = NtQueryVirtualMemory( handle, addr, class, &info, sizeof(info), &res_len ))) + { + info32->BaseAddress = PtrToUlong( info.BaseAddress ); + info32->AllocationBase = PtrToUlong( info.AllocationBase ); + info32->AllocationProtect = info.AllocationProtect; + info32->RegionSize = info.RegionSize; + info32->State = info.State; + info32->Protect = info.Protect; + info32->Type = info.Type; + if ((ULONG_PTR)info.BaseAddress + info.RegionSize > highest_user_address) + info32->RegionSize = highest_user_address - (ULONG_PTR)info.BaseAddress + 1; + } + } + res_len = sizeof(MEMORY_BASIC_INFORMATION32); + break; + +#ifndef __REACTOS__ + case MemoryMappedFilenameInformation: /* MEMORY_SECTION_NAME */ + { + MEMORY_SECTION_NAME *info; + MEMORY_SECTION_NAME32 *info32 = ptr; + SIZE_T size = len + sizeof(*info) - sizeof(*info32); + + info = Wow64AllocateTemp( size ); + if (!(status = NtQueryVirtualMemory( handle, addr, class, info, size, &res_len ))) + { + info32->SectionFileName.Length = info->SectionFileName.Length; + info32->SectionFileName.MaximumLength = info->SectionFileName.MaximumLength; + info32->SectionFileName.Buffer = PtrToUlong( info32 + 1 ); + memcpy( info32 + 1, info->SectionFileName.Buffer, info->SectionFileName.MaximumLength ); + } + res_len += sizeof(*info32) - sizeof(*info); + break; + } + + case MemoryRegionInformation: /* MEMORY_REGION_INFORMATION */ + { + if (len < sizeof(MEMORY_REGION_INFORMATION32)) + status = STATUS_INFO_LENGTH_MISMATCH; + else if ((ULONG_PTR)addr > highest_user_address) + status = STATUS_INVALID_PARAMETER; + else + { + MEMORY_REGION_INFORMATION info; + MEMORY_REGION_INFORMATION32 *info32 = ptr; + + if (!(status = NtQueryVirtualMemory( handle, addr, class, &info, sizeof(info), &res_len ))) + { + info32->AllocationBase = PtrToUlong( info.AllocationBase ); + info32->AllocationProtect = info.AllocationProtect; + info32->RegionType = info.RegionType; + info32->RegionSize = info.RegionSize; + info32->CommitSize = info.CommitSize; + info32->PartitionId = info.PartitionId; + info32->NodePreference = info.NodePreference; + if ((ULONG_PTR)info.AllocationBase + info.RegionSize > highest_user_address) + info32->RegionSize = highest_user_address - (ULONG_PTR)info.AllocationBase + 1; + } + } + res_len = sizeof(MEMORY_REGION_INFORMATION32); + break; + } + + case MemoryWorkingSetExInformation: /* MEMORY_WORKING_SET_EX_INFORMATION */ + { + MEMORY_WORKING_SET_EX_INFORMATION32 *info32 = ptr; + MEMORY_WORKING_SET_EX_INFORMATION *info; + ULONG i, count = len / sizeof(*info32); + + if (len < sizeof(*info32)) return STATUS_INFO_LENGTH_MISMATCH; + + info = Wow64AllocateTemp( count * sizeof(*info) ); + for (i = 0; i < count; i++) info[i].VirtualAddress = ULongToPtr( info32[i].VirtualAddress ); + if (!(status = NtQueryVirtualMemory( handle, addr, class, info, count * sizeof(*info), &res_len ))) + { + count = res_len / sizeof(*info); + for (i = 0; i < count; i++) info32[i].VirtualAttributes.Flags = info[i].VirtualAttributes.Flags; + res_len = count * sizeof(*info32); + } + break; + } + + case MemoryImageInformation: /* MEMORY_IMAGE_INFORMATION */ + { + if (len < sizeof(MEMORY_IMAGE_INFORMATION32)) return STATUS_INFO_LENGTH_MISMATCH; + + if ((ULONG_PTR)addr > highest_user_address) status = STATUS_INVALID_PARAMETER; + else + { + MEMORY_IMAGE_INFORMATION info; + MEMORY_IMAGE_INFORMATION32 *info32 = ptr; + + if (!(status = NtQueryVirtualMemory( handle, addr, class, &info, sizeof(info), &res_len ))) + { + info32->ImageBase = PtrToUlong( info.ImageBase ); + info32->SizeOfImage = info.SizeOfImage; + info32->ImageFlags = info.ImageFlags; + } + } + res_len = sizeof(MEMORY_IMAGE_INFORMATION32); + break; + } + + case MemoryWineUnixWow64Funcs: + return STATUS_INVALID_INFO_CLASS; + + case MemoryWineUnixFuncs: + status = NtQueryVirtualMemory( handle, addr, MemoryWineUnixWow64Funcs, ptr, len, &res_len ); + break; +#endif + + default: + FIXME( "unsupported class %u\n", class ); + return STATUS_INVALID_INFO_CLASS; + } + if (!status || status == STATUS_INFO_LENGTH_MISMATCH) put_size( retlen, res_len ); + return status; +} + + +/********************************************************************** + * wow64_NtReadVirtualMemory + */ +NTSTATUS WINAPI wow64_NtReadVirtualMemory( UINT *args ) +{ + HANDLE process = get_handle( &args ); +#ifndef __REACTOS__ + const void *addr = get_ptr( &args ); +#else + void *addr = get_ptr( &args ); +#endif + void *buffer = get_ptr( &args ); + SIZE_T size = get_ulong( &args ); + ULONG *retlen = get_ptr( &args ); + + SIZE_T ret_size; + NTSTATUS status; + + status = NtReadVirtualMemory( process, addr, buffer, size, &ret_size ); + put_size( retlen, ret_size ); + return status; +} + + +/********************************************************************** + * wow64_NtResetWriteWatch + */ +NTSTATUS WINAPI wow64_NtResetWriteWatch( UINT *args ) +{ + HANDLE process = get_handle( &args ); + void *base = get_ptr( &args ); + SIZE_T size = get_ulong( &args ); + + return NtResetWriteWatch( process, base, size ); +} + + +#ifndef __REACTOS__ +/********************************************************************** + * wow64_NtSetInformationVirtualMemory + */ +NTSTATUS WINAPI wow64_NtSetInformationVirtualMemory( UINT *args ) +{ + HANDLE process = get_handle( &args ); + VIRTUAL_MEMORY_INFORMATION_CLASS info_class = get_ulong( &args ); + ULONG count = get_ulong( &args ); + MEMORY_RANGE_ENTRY32 *addresses32 = get_ptr( &args ); + PVOID ptr = get_ptr( &args ); + ULONG len = get_ulong( &args ); + + MEMORY_RANGE_ENTRY *addresses; + + if (!count) return STATUS_INVALID_PARAMETER_3; + addresses = memory_range_entry_array_32to64( addresses32, count ); + + switch (info_class) + { + case VmPrefetchInformation: + break; + default: + FIXME( "(%p,info_class=%u,%lu,%p,%p,%lu): not implemented\n", + process, info_class, count, addresses32, ptr, len ); + return STATUS_INVALID_PARAMETER_2; + } + + return NtSetInformationVirtualMemory( process, info_class, count, addresses, ptr, len ); +} + + +/********************************************************************** + * wow64_NtSetLdtEntries + */ +NTSTATUS WINAPI wow64_NtSetLdtEntries( UINT *args ) +{ + ULONG sel1 = get_ulong( &args ); + ULONG entry1_low = get_ulong( &args ); + ULONG entry1_high = get_ulong( &args ); + ULONG sel2 = get_ulong( &args ); + ULONG entry2_low = get_ulong( &args ); + ULONG entry2_high = get_ulong( &args ); + + FIXME( "%04lx %08lx %08lx %04lx %08lx %08lx: stub\n", + sel1, entry1_low, entry1_high, sel2, entry2_low, entry2_high ); + return STATUS_NOT_IMPLEMENTED; +} +#endif + +/********************************************************************** + * wow64_NtUnlockVirtualMemory + */ +NTSTATUS WINAPI wow64_NtUnlockVirtualMemory( UINT *args ) +{ + HANDLE process = get_handle( &args ); + ULONG *addr32 = get_ptr( &args ); + ULONG *size32 = get_ptr( &args ); + ULONG unknown = get_ulong( &args ); + + void *addr; + SIZE_T size; + NTSTATUS status; + + status = NtUnlockVirtualMemory( process, addr_32to64( &addr, addr32 ), + size_32to64( &size, size32 ), unknown ); + if (!status) + { + put_addr( addr32, addr ); + put_size( size32, size ); + } + return status; +} + + +/********************************************************************** + * wow64_NtUnmapViewOfSection + */ +NTSTATUS WINAPI wow64_NtUnmapViewOfSection( UINT *args ) +{ + HANDLE process = get_handle( &args ); + void *addr = get_ptr( &args ); + +#ifndef __REACTOS__ + BOOL is_current = RtlIsCurrentProcess( process ); +#endif + NTSTATUS status; + +#ifndef __REACTOS__ + if (is_current && pBTCpuNotifyUnmapViewOfSection) pBTCpuNotifyUnmapViewOfSection( addr, FALSE, 0 ); +#endif + status = NtUnmapViewOfSection( process, addr ); +#ifndef __REACTOS__ + if (is_current && pBTCpuNotifyUnmapViewOfSection) pBTCpuNotifyUnmapViewOfSection( addr, TRUE, status ); +#endif + return status; +} + +#ifndef __REACTOS__ +/********************************************************************** + * wow64_NtUnmapViewOfSectionEx + */ +NTSTATUS WINAPI wow64_NtUnmapViewOfSectionEx( UINT *args ) +{ + HANDLE process = get_handle( &args ); + void *addr = get_ptr( &args ); + ULONG flags = get_ulong( &args ); + + BOOL is_current = RtlIsCurrentProcess( process ); + NTSTATUS status; + + if (is_current && pBTCpuNotifyUnmapViewOfSection) pBTCpuNotifyUnmapViewOfSection( addr, FALSE, 0 ); + status = NtUnmapViewOfSectionEx( process, addr, flags ); + if (is_current && pBTCpuNotifyUnmapViewOfSection) pBTCpuNotifyUnmapViewOfSection( addr, TRUE, status ); + return status; +} +#endif + +/********************************************************************** + * wow64_NtWow64AllocateVirtualMemory64 + */ +NTSTATUS WINAPI wow64_NtWow64AllocateVirtualMemory64( UINT *args ) +{ + HANDLE process = get_handle( &args ); + void **addr = get_ptr( &args ); + ULONG_PTR zero_bits = get_ulong64( &args ); + SIZE_T *size = get_ptr( &args ); + ULONG type = get_ulong( &args ); + ULONG protect = get_ulong( &args ); + + return NtAllocateVirtualMemory( process, addr, zero_bits, size, type, protect ); +} + + +/********************************************************************** + * wow64_NtWow64ReadVirtualMemory64 + */ +NTSTATUS WINAPI wow64_NtWow64ReadVirtualMemory64( UINT *args ) +{ + HANDLE process = get_handle( &args ); + void *addr = (void *)(ULONG_PTR)get_ulong64( &args ); + void *buffer = get_ptr( &args ); + SIZE_T size = get_ulong64( &args ); + SIZE_T *ret_size = get_ptr( &args ); + + return NtReadVirtualMemory( process, addr, buffer, size, ret_size ); +} + + +/********************************************************************** + * wow64_NtWow64WriteVirtualMemory64 + */ +NTSTATUS WINAPI wow64_NtWow64WriteVirtualMemory64( UINT *args ) +{ + HANDLE process = get_handle( &args ); + void *addr = (void *)(ULONG_PTR)get_ulong64( &args ); +#ifdef __REACTOS__ +#define const +#endif + const void *buffer = get_ptr( &args ); +#ifdef __REACTOS__ +#undef const +#endif + SIZE_T size = get_ulong64( &args ); + SIZE_T *ret_size = get_ptr( &args ); + + return NtWriteVirtualMemory( process, addr, buffer, size, ret_size ); +} + +/********************************************************************** + * wow64_NtWriteVirtualMemory + */ +NTSTATUS WINAPI wow64_NtWriteVirtualMemory( UINT *args ) +{ + HANDLE process = get_handle( &args ); + void *addr = get_ptr( &args ); +#ifndef __REACTOS__ + const void *buffer = get_ptr( &args ); +#else + void *buffer = get_ptr( &args ); +#endif + SIZE_T size = get_ulong( &args ); + ULONG *retlen = get_ptr( &args ); + + SIZE_T ret_size; + NTSTATUS status; + + status = NtWriteVirtualMemory( process, addr, buffer, size, &ret_size ); + put_size( retlen, ret_size ); + return status; +} diff --git a/dll/wow64/wow64.c b/dll/wow64/wow64.c new file mode 100644 index 0000000000000..144afef90b532 --- /dev/null +++ b/dll/wow64/wow64.c @@ -0,0 +1,1336 @@ +/* + * Wine WOW64 ReactOS port + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: wow64.dll + * FILE: dll/wow64/wow64.c + * PROGRAMMER: Marcin Jabłoński + */ + +#include "ros_wow64_private.h" +#include "sysfuncnum.h" +#include + +//#define NDEBUG +#include + +#include "entrypoint.h" + +typedef MEMORY_BASIC_INFORMATION32 *PMEMORY_BASIC_INFORMATION32; + +/* PEB Data */ +static USHORT UnicodeCopy[2048]; /* ??? */ +static UCHAR AnsiCopy[65536], OemCopy[65536]; /* ??? */ +static ULONG_PTR FixmeProcessHeaps[100]; /* FIXME */ +static BYTE UnicodeData[8192]; /* ??? */ + +static PNLSTABLEINFO32 UnicodeNlsTable = (PVOID)&UnicodeData; +static PCPTABLEINFO32 AnsiCpTable; +static PCPTABLEINFO32 OemCpTable; + +static UNICODE_STRING NtDll32Str = RTL_CONSTANT_STRING(L"" TMP_WOW_DIR L"\\ntdll.dll"); +static ANSI_STRING ImportLdrInitializeThunkStr = RTL_CONSTANT_STRING("LdrInitializeThunk"); +static ANSI_STRING ImportUserExceptionDispatcherStr = RTL_CONSTANT_STRING("KiUserExceptionDispatcher"); +static PVOID NtDll32 = NULL; + +static UNICODE_STRING Kernel32Str = RTL_CONSTANT_STRING(L"" TMP_WOW_DIR L"\\kernel32.dll"); +static ANSI_STRING ImportBaseStr = RTL_CONSTANT_STRING("Base"); + +PVOID NtDll32LdrpRoutine = NULL; +PVOID NtDll32KiUserExceptionDispatcher = NULL; + +void SetupFs(ULONG_PTR segSelector); +void EnterApc32(PVOID pEnterCtx, SIZE_T cbCtxSize); +__declspec(dllexport) void WINAPI Wow64LdrpInitialize(PCONTEXT pContext); + +/* FIXME: this is an incomplete implementation */ +VOID +Wow64CopyContext32To64(PCONTEXT pContext, + PI386_CONTEXT pContext32) +{ + RtlZeroMemory(pContext, sizeof(*pContext)); + pContext->ContextFlags = CONTEXT_FULL; + pContext->Rip = pContext32->Eip; + pContext->Rax = pContext32->Eax; + pContext->Rbx = pContext32->Ebx; + pContext->Rcx = pContext32->Ecx; + pContext->Rdx = pContext32->Edx; + pContext->Rsp = pContext32->Esp; + pContext->Rbp = pContext32->Ebp; + pContext->Rsi = pContext32->Esi; + pContext->Rdi = pContext32->Edi; + pContext->EFlags = pContext32->EFlags; + pContext->SegCs = pContext32->SegCs; + pContext->SegDs = pContext32->SegDs; + pContext->SegEs = pContext32->SegEs; + pContext->SegFs = pContext32->SegFs; + pContext->SegGs = pContext32->SegGs; + pContext->SegSs = pContext32->SegSs; + pContext->MxCsr = INITIAL_MXCSR; +} + +VOID +Wow64CopyContext64To32(PI386_CONTEXT pContext32, + PCONTEXT pContext) +{ + pContext32->Eip = pContext->Rip; + pContext32->Eax = pContext->Rax; + pContext32->Ebx = pContext->Rbx; + pContext32->Ecx = pContext->Rcx; + pContext32->Edx = pContext->Rdx; + pContext32->Esi = pContext->Rdi; + pContext32->Edi = pContext->Rsi; + pContext32->Ebp = pContext->Rbp; + pContext32->Esp = pContext->Rsp; + pContext32->SegCs = pContext->SegCs; + pContext32->SegDs = pContext->SegDs; + pContext32->SegEs = pContext->SegEs; + pContext32->SegFs = pContext->SegFs; + pContext32->SegGs = pContext->SegGs; + pContext32->SegSs = pContext->SegSs; + pContext32->EFlags = pContext->EFlags; + pContext32->ContextFlags = pContext->ContextFlags; +} + +/* From wine/dlls/ntdll/unix/env.c */ +static inline void dup_unicode_string( const UNICODE_STRING *src, WCHAR **dst, UNICODE_STRING32 *str ) +{ + if (!src->Buffer) return; + str->Buffer = PtrToUlong( *dst ); + str->Length = src->Length; + str->MaximumLength = src->MaximumLength; + memcpy( *dst, src->Buffer, src->MaximumLength ); + *dst += (src->MaximumLength + 1) / sizeof(WCHAR); +} + +static void *build_wow64_parameters( const RTL_USER_PROCESS_PARAMETERS *params ) +{ + RTL_USER_PROCESS_PARAMETERS32 *wow64_params = NULL; + + NTSTATUS status; + WCHAR *dst; + SIZE_T size = (sizeof(*wow64_params) + + params->CurrentDirectory.DosPath.MaximumLength + + params->DllPath.MaximumLength + + params->ImagePathName.MaximumLength + + params->CommandLine.MaximumLength + + params->WindowTitle.MaximumLength + + params->DesktopInfo.MaximumLength + + params->ShellInfo.MaximumLength + + ((params->RuntimeData.MaximumLength + 1) & ~1)) + + wcslen(params->Environment) * sizeof(*params->Environment); + + status = NtAllocateVirtualMemory( NtCurrentProcess(), (void **)&wow64_params, 32, &size, + MEM_COMMIT, PAGE_READWRITE ); + ASSERT( !status ); + + wow64_params->MaximumLength = size; + wow64_params->Length = size; + wow64_params->Flags = params->Flags; + wow64_params->DebugFlags = params->DebugFlags; + wow64_params->ConsoleHandle = HandleToULong( params->ConsoleHandle ); + wow64_params->ConsoleFlags = params->ConsoleFlags; + wow64_params->StandardInput = HandleToULong( params->StandardInput ); + wow64_params->StandardOutput = HandleToULong( params->StandardOutput ); + wow64_params->StandardError = HandleToULong( params->StandardError ); + wow64_params->StartingX = params->StartingX; + wow64_params->StartingY = params->StartingY; + wow64_params->CountX = params->CountX; + wow64_params->CountY = params->CountY; + wow64_params->CountCharsX = params->CountCharsX; + wow64_params->CountCharsY = params->CountCharsY; + wow64_params->FillAttribute = params->FillAttribute; + wow64_params->WindowFlags = params->WindowFlags; + wow64_params->ShowWindowFlags = params->ShowWindowFlags; + + dst = (WCHAR *)(wow64_params + 1); + dup_unicode_string( ¶ms->CurrentDirectory.DosPath, &dst, &wow64_params->CurrentDirectory.DosPath ); + dup_unicode_string( ¶ms->DllPath, &dst, &wow64_params->DllPath ); + dup_unicode_string( ¶ms->ImagePathName, &dst, &wow64_params->ImagePathName ); + dup_unicode_string( ¶ms->CommandLine, &dst, &wow64_params->CommandLine ); + dup_unicode_string( ¶ms->WindowTitle, &dst, &wow64_params->WindowTitle ); + dup_unicode_string( ¶ms->DesktopInfo, &dst, &wow64_params->DesktopInfo ); + dup_unicode_string( ¶ms->ShellInfo, &dst, &wow64_params->ShellInfo ); + dup_unicode_string( ¶ms->RuntimeData, &dst, &wow64_params->RuntimeData ); + + DPRINT1("WOW64: Converting native process parameters for image '%wZ', command line '%wZ'\n", + ¶ms->ImagePathName, + ¶ms->CommandLine); + + wow64_params->Environment = PtrToUlong( params->Environment ); + //DPRINT1("Original enviroment %ls\n", params->Environment); + //memcpy(dst, params->Environment, wcslen(params->Environment) * sizeof(*params->Environment)); + return wow64_params; +} + +NTSTATUS WINAPI wow64_NtQueryInformationProcess( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + PROCESSINFOCLASS class = get_ulong( &args ); + void *ptr = get_ptr( &args ); + ULONG len = get_ulong( &args ); + ULONG *retlen = get_ptr( &args ); + + NTSTATUS status; + + switch (class) + { + case ProcessBasicInformation: /* PROCESS_BASIC_INFORMATION */ + if (len == sizeof(PROCESS_BASIC_INFORMATION32)) + { + PROCESS_BASIC_INFORMATION info; + PROCESS_BASIC_INFORMATION32 *info32 = ptr; + + if (!(status = NtQueryInformationProcess( handle, class, &info, sizeof(info), NULL ))) + { + if (is_process_wow64( handle )) + info32->PebBaseAddress = PtrToUlong( info.PebBaseAddress ) + 0x1000; + else + info32->PebBaseAddress = 0; + info32->ExitStatus = info.ExitStatus; + info32->AffinityMask = info.AffinityMask; + info32->BasePriority = info.BasePriority; + info32->UniqueProcessId = info.UniqueProcessId; + info32->InheritedFromUniqueProcessId = info.InheritedFromUniqueProcessId; + if (retlen) *retlen = sizeof(*info32); + } + return status; + } + if (retlen) *retlen = sizeof(PROCESS_BASIC_INFORMATION32); + return STATUS_INFO_LENGTH_MISMATCH; + + case ProcessIoCounters: /* IO_COUNTERS */ + case ProcessTimes: /* KERNEL_USER_TIMES */ + case ProcessDefaultHardErrorMode: /* ULONG */ + case ProcessPriorityClass: /* PROCESS_PRIORITY_CLASS */ + case ProcessHandleCount: /* ULONG */ + case ProcessSessionInformation: /* ULONG */ + case ProcessDebugFlags: /* ULONG */ + case ProcessExecuteFlags: /* ULONG */ + case ProcessCookie: /* ULONG */ + case ProcessCycleTime: /* PROCESS_CYCLE_TIME_INFORMATION */ +#ifdef __REACTOS__ + case ProcessDeviceMap: + case ProcessBreakOnTermination: +#endif + /* FIXME: check buffer alignment */ + return NtQueryInformationProcess( handle, class, ptr, len, retlen ); + + case ProcessQuotaLimits: /* QUOTA_LIMITS */ + if (len == sizeof(QUOTA_LIMITS32)) + { + QUOTA_LIMITS info; + QUOTA_LIMITS32 *info32 = ptr; + + if (!(status = NtQueryInformationProcess( handle, class, &info, sizeof(info), NULL ))) + { + info32->PagedPoolLimit = info.PagedPoolLimit; + info32->NonPagedPoolLimit = info.NonPagedPoolLimit; + info32->MinimumWorkingSetSize = info.MinimumWorkingSetSize; + info32->MaximumWorkingSetSize = info.MaximumWorkingSetSize; + info32->PagefileLimit = info.PagefileLimit; + info32->TimeLimit = info.TimeLimit; + if (retlen) *retlen = len; + } + return status; + } + if (retlen) *retlen = sizeof(QUOTA_LIMITS32); + return STATUS_INFO_LENGTH_MISMATCH; + + case ProcessVmCounters: /* VM_COUNTERS_EX */ + if (len == sizeof(VM_COUNTERS32) || len == sizeof(VM_COUNTERS_EX32)) + { + VM_COUNTERS_EX info; + VM_COUNTERS_EX32 *info32 = ptr; + + if (!(status = NtQueryInformationProcess( handle, class, &info, sizeof(info), NULL ))) + { + put_vm_counters( info32, &info, len ); + if (retlen) *retlen = len; + } + return status; + } + if (retlen) *retlen = sizeof(VM_COUNTERS_EX32); + return STATUS_INFO_LENGTH_MISMATCH; + + case ProcessDebugPort: /* ULONG_PTR */ + case ProcessAffinityMask: /* ULONG_PTR */ + case ProcessWow64Information: /* ULONG_PTR */ + case ProcessDebugObjectHandle: /* HANDLE */ + if (len == sizeof(ULONG)) + { + ULONG_PTR data; + + if (!(status = NtQueryInformationProcess( handle, class, &data, sizeof(data), NULL ))) + { + *(ULONG *)ptr = data; + if (retlen) *retlen = sizeof(ULONG); + } + else if (status == STATUS_PORT_NOT_SET) + { + *(ULONG *)ptr = 0; + if (retlen) *retlen = sizeof(ULONG); + } + return status; + } + return STATUS_INFO_LENGTH_MISMATCH; + + case ProcessImageFileName: + case ProcessImageFileNameWin32: /* UNICODE_STRING + string */ + { + ULONG retsize, size = len + sizeof(UNICODE_STRING) - sizeof(UNICODE_STRING32); + UNICODE_STRING *str = Wow64AllocateTemp( size ); + UNICODE_STRING32 *str32 = ptr; + + if (!(status = NtQueryInformationProcess( handle, class, str, size, &retsize ))) + { + str32->Length = str->Length; + str32->MaximumLength = str->MaximumLength; + str32->Buffer = PtrToUlong( str32 + 1 ); + memcpy( str32 + 1, str->Buffer, str->MaximumLength ); + } + if (retlen) *retlen = retsize + sizeof(UNICODE_STRING32) - sizeof(UNICODE_STRING); + return status; + } + + case ProcessImageInformation: /* SECTION_IMAGE_INFORMATION */ + if (len == sizeof(SECTION_IMAGE_INFORMATION32)) + { + SECTION_IMAGE_INFORMATION info; + SECTION_IMAGE_INFORMATION32 *info32 = ptr; + + if (!(status = NtQueryInformationProcess( handle, class, &info, sizeof(info), NULL ))) + { + put_section_image_info( info32, &info ); + if (retlen) *retlen = sizeof(*info32); + } + return status; + } + if (retlen) *retlen = sizeof(SECTION_IMAGE_INFORMATION32); + return STATUS_INFO_LENGTH_MISMATCH; +#ifndef __REACTOS__ + case ProcessWineLdtCopy: + return STATUS_NOT_IMPLEMENTED; +#endif + default: + FIXME( "unsupported class %u\n", class ); + return STATUS_INVALID_INFO_CLASS; + } +} + +static +NTSTATUS +Wow64WinHandler(ULONG syscallNum, + ULONG* pArgs) +{ + ANSI_STRING ImportStr = RTL_CONSTANT_STRING("sdwhwin32"); + static PSYSTEM_SERVICE_TABLE pServiceTable = NULL; + static PVOID Wow64WinDll = NULL; + UNICODE_STRING Wow64WinDllStr = RTL_CONSTANT_STRING(L"wow64win.dll"); + NTSTATUS Status; + + ULONG_PTR *HandlerTable = NULL; + NTSTATUS (*Service)(ULONG* pArgs) = NULL; + + static const char* mapping[] = + { +#define SVC_(name, argc) ""#name , +#include "../../../win32ss/w32ksvc32.h" +#undef SVC_ + }; + + /* Make sure wow64win.dll is loaded. */ + if (pServiceTable == NULL) + { + Status = LdrLoadDll(NULL, 0, &Wow64WinDllStr, &Wow64WinDll); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Couldn't load wow64win.dll.\n"); + return Status; + } + + Status = LdrGetProcedureAddress(Wow64WinDll, + &ImportStr, + 0, + (PVOID*)&pServiceTable); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Couldn't find %hs in wow64win.dll.\n", ImportStr.Buffer); + ASSERT(FALSE); + } + + DPRINT1("Loaded service table %p from %p.\n", pServiceTable, Wow64WinDll); + } + + HandlerTable = pServiceTable->ServiceTable; + if (HandlerTable == NULL) + { + DPRINT1("Wow64Win service table is empty.\n"); + return STATUS_NOT_IMPLEMENTED; + } + + if (HandlerTable[syscallNum] == 0) + { + DPRINT1("Wow64Win service table doesn't define service %lX:%s.\n", + syscallNum, mapping[syscallNum]); + return STATUS_NOT_IMPLEMENTED; + } + +#if 0 + if (pServiceTable->ArgumentTable != NULL) + { + if (pServiceTable->ArgumentTable[syscallNum] != numArgs) + { + DPRINT1("WARNING: Wow64Win service expects a different number of " + "arguments than %d for %lX:%s.\n", + numArgs, syscallNum, mapping[syscallNum]); + } + } +#endif + + Service = (PVOID)HandlerTable[syscallNum]; + return Service(pArgs); +} + +NTSTATUS +WINAPI +Wow64SystemServiceEx(ULONG syscallNum, + ULONG* pArgs) +{ + NTSTATUS status; + + static const char* mapping[] = + { +#define SVC_(name, argc) ""#name , +#include "../../../ntoskrnl/include/sysfuncs.h" +#undef SVC_ + }; + + status = STATUS_NOT_IMPLEMENTED; + +#if 0 + if (syscallNum < sizeof(mapping) / sizeof(*mapping)) + { + DPRINT1("[Syscall %lX:%hs]\n", syscallNum, mapping[syscallNum]); + } +#endif + + switch (syscallNum) + { + /* file.c */ + WINE_WOW_IMPL_CASE(CancelIoFile); + WINE_WOW_IMPL_CASE(CreateFile); + WINE_WOW_IMPL_CASE(CreateMailslotFile); + WINE_WOW_IMPL_CASE(CreateNamedPipeFile); + WINE_WOW_IMPL_CASE(CreatePagingFile); + WINE_WOW_IMPL_CASE(DeleteFile); + WINE_WOW_IMPL_CASE(DeviceIoControlFile); + WINE_WOW_IMPL_CASE(FlushBuffersFile); + WINE_WOW_IMPL_CASE(FsControlFile); + WINE_WOW_IMPL_CASE(LockFile); + WINE_WOW_IMPL_CASE(NotifyChangeDirectoryFile); + WINE_WOW_IMPL_CASE(OpenFile); + WINE_WOW_IMPL_CASE(QueryAttributesFile); + WINE_WOW_IMPL_CASE(QueryDirectoryFile); + WINE_WOW_IMPL_CASE(QueryEaFile); + WINE_WOW_IMPL_CASE(QueryFullAttributesFile); + WINE_WOW_IMPL_CASE(QueryInformationFile); + WINE_WOW_IMPL_CASE(QueryVolumeInformationFile); + WINE_WOW_IMPL_CASE(ReadFile); + WINE_WOW_IMPL_CASE(ReadFileScatter); + WINE_WOW_IMPL_CASE(RemoveIoCompletion); + WINE_WOW_IMPL_CASE(SetEaFile); + WINE_WOW_IMPL_CASE(SetInformationFile); + WINE_WOW_IMPL_CASE(SetVolumeInformationFile); + WINE_WOW_IMPL_CASE(UnlockFile); + WINE_WOW_IMPL_CASE(WriteFile); + WINE_WOW_IMPL_CASE(WriteFileGather); + + /* registry.c */ + WINE_WOW_IMPL_CASE(QuerySystemInformation); + WINE_WOW_IMPL_CASE(OpenKey); + WINE_WOW_IMPL_CASE(QueryValueKey); + WINE_WOW_IMPL_CASE(QueryKey); + WINE_WOW_IMPL_CASE(DeleteValueKey); + WINE_WOW_IMPL_CASE(CreateKey); + WINE_WOW_IMPL_CASE(DeleteKey); + WINE_WOW_IMPL_CASE(EnumerateKey); + WINE_WOW_IMPL_CASE(EnumerateValueKey); + WINE_WOW_IMPL_CASE(SetValueKey); + + /* security.c */ + WINE_WOW_IMPL_CASE(AccessCheck); + WINE_WOW_IMPL_CASE(AdjustGroupsToken); + WINE_WOW_IMPL_CASE(AdjustPrivilegesToken); + WINE_WOW_IMPL_CASE(CreateToken); + WINE_WOW_IMPL_CASE(FilterToken); + WINE_WOW_IMPL_CASE(DuplicateToken); + WINE_WOW_IMPL_CASE(CompareTokens); + WINE_WOW_IMPL_CASE(ImpersonateAnonymousToken); + WINE_WOW_IMPL_CASE(OpenProcessToken); + WINE_WOW_IMPL_CASE(OpenProcessTokenEx); + WINE_WOW_IMPL_CASE(OpenThreadToken); + WINE_WOW_IMPL_CASE(OpenThreadTokenEx); + WINE_WOW_IMPL_CASE(PrivilegeCheck); + WINE_WOW_IMPL_CASE(QueryInformationToken); + WINE_WOW_IMPL_CASE(QuerySecurityObject); + WINE_WOW_IMPL_CASE(SetInformationToken); + WINE_WOW_IMPL_CASE(SetSecurityObject); + + /* system.c */ + WINE_WOW_IMPL_CASE(PowerInformation); + WINE_WOW_IMPL_CASE(QuerySystemEnvironmentValue); + WINE_WOW_IMPL_CASE(QuerySystemEnvironmentValueEx); + WINE_WOW_IMPL_CASE(LoadDriver); + WINE_WOW_IMPL_CASE(DisplayString); + WINE_WOW_IMPL_CASE(InitiatePowerAction); + WINE_WOW_IMPL_CASE(QuerySystemTime); + WINE_WOW_IMPL_CASE(RaiseHardError); + WINE_WOW_IMPL_CASE(SetIntervalProfile); + WINE_WOW_IMPL_CASE(ShutdownSystem); + WINE_WOW_IMPL_CASE(SetSystemInformation); + WINE_WOW_IMPL_CASE(SetSystemTime); + WINE_WOW_IMPL_CASE(SystemDebugControl); + WINE_WOW_IMPL_CASE(UnloadDriver); + + /* sync.c */ + WINE_WOW_IMPL_CASE(CancelTimer); + WINE_WOW_IMPL_CASE(ClearEvent); + WINE_WOW_IMPL_CASE(CompleteConnectPort); + WINE_WOW_IMPL_CASE(CreateDebugObject); + WINE_WOW_IMPL_CASE(CreateDirectoryObject); + WINE_WOW_IMPL_CASE(CreateEvent); + WINE_WOW_IMPL_CASE(CreateIoCompletion); + WINE_WOW_IMPL_CASE(CreateJobObject); + WINE_WOW_IMPL_CASE(CreateKeyedEvent); + WINE_WOW_IMPL_CASE(CreateMutant); + WINE_WOW_IMPL_CASE(CreatePort); + WINE_WOW_IMPL_CASE(CreateSection); + WINE_WOW_IMPL_CASE(CreateSemaphore); + WINE_WOW_IMPL_CASE(CreateSymbolicLinkObject); + WINE_WOW_IMPL_CASE(CreateTimer); + WINE_WOW_IMPL_CASE(DebugContinue); + WINE_WOW_IMPL_CASE(DelayExecution); + WINE_WOW_IMPL_CASE(DuplicateObject); + WINE_WOW_IMPL_CASE(MakePermanentObject); + WINE_WOW_IMPL_CASE(MakeTemporaryObject); + WINE_WOW_IMPL_CASE(OpenDirectoryObject); + WINE_WOW_IMPL_CASE(OpenEvent); + WINE_WOW_IMPL_CASE(OpenIoCompletion); + WINE_WOW_IMPL_CASE(OpenJobObject); + WINE_WOW_IMPL_CASE(OpenKeyedEvent); + WINE_WOW_IMPL_CASE(OpenMutant); + WINE_WOW_IMPL_CASE(OpenSection); + WINE_WOW_IMPL_CASE(OpenSemaphore); + WINE_WOW_IMPL_CASE(OpenSymbolicLinkObject); + WINE_WOW_IMPL_CASE(OpenTimer); + WINE_WOW_IMPL_CASE(PulseEvent); + WINE_WOW_IMPL_CASE(QueryEvent); + WINE_WOW_IMPL_CASE(QueryInformationJobObject); + WINE_WOW_IMPL_CASE(QueryIoCompletion); + WINE_WOW_IMPL_CASE(QueryMutant); + WINE_WOW_IMPL_CASE(QueryObject); + WINE_WOW_IMPL_CASE(QueryPerformanceCounter); + WINE_WOW_IMPL_CASE(QuerySection); + WINE_WOW_IMPL_CASE(QuerySemaphore); + WINE_WOW_IMPL_CASE(QuerySymbolicLinkObject); + WINE_WOW_IMPL_CASE(QueryTimer); + WINE_WOW_IMPL_CASE(QueryTimerResolution); + WINE_WOW_IMPL_CASE(RegisterThreadTerminatePort); + WINE_WOW_IMPL_CASE(ReleaseKeyedEvent); + WINE_WOW_IMPL_CASE(ReleaseMutant); + WINE_WOW_IMPL_CASE(ReleaseSemaphore); + WINE_WOW_IMPL_CASE(ReplyWaitReceivePort); + WINE_WOW_IMPL_CASE(RequestWaitReplyPort); + WINE_WOW_IMPL_CASE(ResetEvent); + WINE_WOW_IMPL_CASE(SetEvent); + WINE_WOW_IMPL_CASE(SetInformationDebugObject); + WINE_WOW_IMPL_CASE(SetInformationJobObject); + WINE_WOW_IMPL_CASE(SetInformationObject); + WINE_WOW_IMPL_CASE(SetIoCompletion); + WINE_WOW_IMPL_CASE(SecureConnectPort); + WINE_WOW_IMPL_CASE(SetTimer); + WINE_WOW_IMPL_CASE(SetTimerResolution); + WINE_WOW_IMPL_CASE(SignalAndWaitForSingleObject); + WINE_WOW_IMPL_CASE(TerminateJobObject); + WINE_WOW_IMPL_CASE(TestAlert); + WINE_WOW_IMPL_CASE(WaitForDebugEvent); + WINE_WOW_IMPL_CASE(WaitForKeyedEvent); + WINE_WOW_IMPL_CASE(WaitForMultipleObjects); + WINE_WOW_IMPL_CASE(WaitForSingleObject); + WINE_WOW_IMPL_CASE(YieldExecution); + + /* syscall.c */ + WINE_WOW_IMPL_CASE(AddAtom); + WINE_WOW_IMPL_CASE(AllocateLocallyUniqueId); + WINE_WOW_IMPL_CASE(AllocateUuids); + WINE_WOW_IMPL_CASE(CallbackReturn); + WINE_WOW_IMPL_CASE(Close); + WINE_WOW_IMPL_CASE(Continue); + WINE_WOW_IMPL_CASE(DeleteAtom); + WINE_WOW_IMPL_CASE(FindAtom); + WINE_WOW_IMPL_CASE(GetCurrentProcessorNumber); + WINE_WOW_IMPL_CASE(QueryDefaultLocale); + WINE_WOW_IMPL_CASE(QueryDefaultUILanguage); + WINE_WOW_IMPL_CASE(QueryInformationAtom); + WINE_WOW_IMPL_CASE(QueryInstallUILanguage); + WINE_WOW_IMPL_CASE(RaiseException); + WINE_WOW_IMPL_CASE(SetDebugFilterState); + WINE_WOW_IMPL_CASE(SetDefaultLocale); + WINE_WOW_IMPL_CASE(SetDefaultUILanguage); + + /* virtual.c */ + WINE_WOW_IMPL_CASE(AllocateVirtualMemory); + WINE_WOW_IMPL_CASE(AreMappedFilesTheSame); + WINE_WOW_IMPL_CASE(FlushInstructionCache); + WINE_WOW_IMPL_CASE(FlushVirtualMemory); + WINE_WOW_IMPL_CASE(FreeVirtualMemory); + WINE_WOW_IMPL_CASE(GetWriteWatch); + WINE_WOW_IMPL_CASE(LockVirtualMemory); + WINE_WOW_IMPL_CASE(MapViewOfSection); + WINE_WOW_IMPL_CASE(ProtectVirtualMemory); + WINE_WOW_IMPL_CASE(QueryVirtualMemory); + WINE_WOW_IMPL_CASE(Wow64AllocateVirtualMemory64); + WINE_WOW_IMPL_CASE(Wow64ReadVirtualMemory64); + WINE_WOW_IMPL_CASE(Wow64WriteVirtualMemory64); + WINE_WOW_IMPL_CASE(ReadVirtualMemory); + WINE_WOW_IMPL_CASE(ResetWriteWatch); + WINE_WOW_IMPL_CASE(UnlockVirtualMemory); + WINE_WOW_IMPL_CASE(UnmapViewOfSection); + WINE_WOW_IMPL_CASE(WriteVirtualMemory); + + /* wow64.c */ + WINE_WOW_IMPL_CASE(OpenProcess); + WINE_WOW_IMPL_CASE(OpenThread); + WINE_WOW_IMPL_CASE(CreateThread); + WINE_WOW_IMPL_CASE(CreateProcess); + WINE_WOW_IMPL_CASE(CreateProcessEx); + WINE_WOW_IMPL_CASE(QueryInformationThread); + WINE_WOW_IMPL_CASE(QueryInformationProcess); + WINE_WOW_IMPL_CASE(SetInformationProcess); + WINE_WOW_IMPL_CASE(ResumeThread); + WINE_WOW_IMPL_CASE(ApphelpCacheControl); + WINE_WOW_IMPL_CASE(SuspendThread); + WINE_WOW_IMPL_CASE(GetContextThread); + + case NumTerminateThread: + { + HANDLE hThread = get_handle(&pArgs); + ULONG uCode = get_ulong(&pArgs); + + DPRINT1("Terminating thread %p with a WOW64 call from %p\n", hThread, NtCurrentProcess()); + + status = NtTerminateThread(hThread, uCode); + break; + } + case NumTerminateProcess: + { + HANDLE hProcess = get_handle(&pArgs); + ULONG uCode = get_ulong(&pArgs); + + DPRINT1("Terminating process %p with a WOW64 call from %p\n", hProcess, NtCurrentProcess()); + + status = NtTerminateProcess(hProcess, uCode); + break; + } + case NumQueryDebugFilterState: + { + ULONG u1 = get_ulong(&pArgs); + ULONG u2 = get_ulong(&pArgs); + status = NtQueryDebugFilterState(u1, u2); + break; + } + + default: + { + if (syscallNum >= 0x1000) + { + status = Wow64WinHandler(syscallNum - 0x1000, pArgs); + Wow64FreeTempData(); + return status; + } + + if (syscallNum < sizeof(mapping) / sizeof(*mapping)) + { + DPRINT1("[Syscall %lX:%hs] ", syscallNum, mapping[syscallNum]); + } + else + { + DPRINT1("[Syscall %lX:???] ", syscallNum); + } + DPRINT1("WARNING: Unhandled 32-bit syscall 0x%lX(args at %p)\n", syscallNum, pArgs); + status = STATUS_NOT_IMPLEMENTED; + } + } + + Wow64FreeTempData(); + return status; +} + +WINAPI +NTSTATUS +wow64_NtOpenProcess(UINT* pArgs) +{ + ULONG* pProcessHandle32 = get_ptr(&pArgs); + ACCESS_MASK DesiredAcces = get_ulong(&pArgs); + POBJECT_ATTRIBUTES32 pObjectAttributes32 = get_ptr(&pArgs); + PCLIENT_ID32 pClientId32 = get_ptr(&pArgs); + + CLIENT_ID ClientId; + struct object_attr64 ObjectAttributes; + NTSTATUS Status; + + HANDLE ProcessHandle; + + if (pProcessHandle32 == NULL) + { + return STATUS_INVALID_PARAMETER; + } + + Status = NtOpenProcess(&ProcessHandle, + DesiredAcces, + objattr_32to64(&ObjectAttributes, pObjectAttributes32), + client_id_32to64(&ClientId, pClientId32)); + + if (NT_SUCCESS(Status)) + { + *pProcessHandle32 = HandleToULong(ProcessHandle); + } + + return Status; +} + +WINAPI +NTSTATUS +wow64_NtOpenThread(UINT* pArgs) +{ + PULONG pThreadHandle32 = get_ptr(&pArgs); + ACCESS_MASK DesiredAcces = get_ulong(&pArgs); + POBJECT_ATTRIBUTES32 pObjectAttributes32 = get_ptr(&pArgs); + PCLIENT_ID32 pClientId32 = get_ptr(&pArgs); + + CLIENT_ID ClientId; + struct object_attr64 ObjectAttributes; + NTSTATUS Status; + + HANDLE ThreadHandle; + + if (pThreadHandle32 == NULL) + { + return STATUS_INVALID_PARAMETER; + } + + Status = NtOpenThread(&ThreadHandle, + DesiredAcces, + objattr_32to64(&ObjectAttributes, pObjectAttributes32), + client_id_32to64(&ClientId, pClientId32)); + + if (NT_SUCCESS(Status)) + { + *pThreadHandle32 = HandleToULong(ThreadHandle); + } + + return Status; +} + +NTSTATUS +WINAPI +wow64_NtContinue(UINT *pArgs) +{ + CONTEXT Context; + + PI386_CONTEXT pContext32 = get_ptr(&pArgs); + BOOLEAN bRasieAlert = get_ulong(&pArgs); + + /* TODO: APC handling here? + Wine has an implementation, port from there maybe. */ + + Wow64CopyContext32To64(&Context, pContext32); + + return NtContinue(&Context, bRasieAlert); +} + +static +NTSTATUS +NTAPI +wow64_NtCreateThread(UINT* pArgs) +{ + PULONG phThread32 = get_ptr(&pArgs); + ACCESS_MASK DesiredAccess = get_ulong(&pArgs); + POBJECT_ATTRIBUTES32 pObjectAttributes32 = get_ptr(&pArgs); + HANDLE hProcess = get_handle(&pArgs); + PCLIENT_ID32 pClientId32 = get_ptr(&pArgs); + PI386_CONTEXT pContext32 = get_ptr(&pArgs); + PINITIAL_TEB32 pInitialTeb = get_ptr(&pArgs); + BOOLEAN bCreateSuspended = get_ulong(&pArgs); + + CLIENT_ID ClientId; + struct object_attr64 ObjAttr; + INITIAL_TEB InitialTeb; + CONTEXT Context; + NTSTATUS Status; + HANDLE hThread; + + InitialTeb.AllocatedStackBase = UlongToPtr(pInitialTeb->AllocatedStackBase); + InitialTeb.PreviousStackBase = UlongToPtr(pInitialTeb->PreviousStackBase); + InitialTeb.PreviousStackLimit = UlongToPtr(pInitialTeb->PreviousStackLimit); + InitialTeb.StackBase = UlongToPtr(pInitialTeb->StackBase); + InitialTeb.StackLimit = UlongToPtr(pInitialTeb->StackLimit); + + /* Convert the context to 64-bit */ + Wow64CopyContext32To64(&Context, pContext32); + + Context.SegSs = 0x2b; + Context.SegEs = 0x2b; + Context.SegDs = 0x2b; + Context.SegFs = 0x53; + Context.SegGs = 0x2b; + Context.SegCs = 0x23; + + Status = Wow64TranslateEntrypoint32To64(hProcess, &Context, pContext32); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + Status = NtCreateThread(&hThread, + DesiredAccess, + objattr_32to64(&ObjAttr, + pObjectAttributes32), + hProcess, + &ClientId, + &Context, + &InitialTeb, + bCreateSuspended); + + pClientId32->UniqueProcess = HandleToUlong(ClientId.UniqueProcess); + pClientId32->UniqueThread = HandleToUlong(ClientId.UniqueThread); + *phThread32 = HandleToUlong(hThread); + + return Status; +} + +NTSTATUS +NTAPI +wow64_NtCreateProcessEx(UINT *pArgs) +{ + HANDLE hProcessHandle; + + PULONG phProcessHandle32 = get_ptr(&pArgs); + ACCESS_MASK DesiredAccess = get_ulong(&pArgs); + POBJECT_ATTRIBUTES32 pObjectAttributes32 = get_ptr(&pArgs); + HANDLE hParentProcess = get_handle(&pArgs); + ULONG ulFlags = get_ulong(&pArgs); + HANDLE hSectionHandle = get_handle(&pArgs); + HANDLE hDebugPort = get_handle(&pArgs); + HANDLE hExceptionPort = get_handle(&pArgs); + BOOLEAN bInJob = get_ulong(&pArgs); + + struct object_attr64 attr; + + NTSTATUS Status; + + Status = NtCreateProcessEx(&hProcessHandle, + DesiredAccess, + objattr_32to64(&attr, pObjectAttributes32), + hParentProcess, + ulFlags, + hSectionHandle, + hDebugPort, + hExceptionPort, + bInJob); + if (NT_SUCCESS(Status)) + { + NtCurrentTeb32()->NtTib.ArbitraryUserPointer = + PtrToUlong(NtCurrentTeb()->NtTib.ArbitraryUserPointer); + *phProcessHandle32 = HandleToUlong(hProcessHandle); + } + + return Status; +} + +NTSTATUS +NTAPI +wow64_NtCreateProcess(UINT *pArgs) +{ + HANDLE hProcessHandle; + + PULONG phProcessHandle32 = get_ptr(&pArgs); + ACCESS_MASK DesiredAccess = get_ulong(&pArgs); + POBJECT_ATTRIBUTES32 pObjectAttributes32 = get_ptr(&pArgs); + HANDLE hParentProcess = get_handle(&pArgs); + ULONG ulFlags = get_ulong(&pArgs); + HANDLE hSectionHandle = get_handle(&pArgs); + HANDLE hDebugPort = get_handle(&pArgs); + HANDLE hExceptionPort = get_handle(&pArgs); + + struct object_attr64 attr; + + NTSTATUS Status; + + Status = NtCreateProcess(&hProcessHandle, + DesiredAccess, + objattr_32to64(&attr, pObjectAttributes32), + hParentProcess, + ulFlags, + hSectionHandle, + hDebugPort, + hExceptionPort); + if (NT_SUCCESS(Status)) + { + NtCurrentTeb32()->NtTib.ArbitraryUserPointer = + PtrToUlong(NtCurrentTeb()->NtTib.ArbitraryUserPointer); + *phProcessHandle32 = HandleToUlong(hProcessHandle); + } + + return Status; +} + +NTSTATUS +NTAPI +wow64_NtResumeThread(UINT* pArgs) +{ + HANDLE hThread = get_handle(&pArgs); + PULONG pSuspendCount = get_ptr(&pArgs); + + return NtResumeThread(hThread, pSuspendCount); +} + +NTSTATUS +NTAPI +wow64_NtSuspendThread(UINT* pArgs) +{ + HANDLE hThread = get_handle(&pArgs); + PULONG pSuspendCount = get_ptr(&pArgs); + + return NtSuspendThread(hThread, pSuspendCount); +} + +NTSTATUS +NTAPI +wow64_NtGetContextThread(UINT *pArgs) +{ + CONTEXT Context64; + PI386_CONTEXT pContext32; + NTSTATUS Status; + + HANDLE hThread = get_handle(&pArgs); + pContext32 = get_ptr(&pArgs); + + Context64.ContextFlags = CONTEXT_AMD64 | (pContext32->ContextFlags & 0xFFFF); + + Status = NtGetContextThread(hThread, &Context64); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + Wow64CopyContext64To32(pContext32, &Context64); + pContext32->ContextFlags &= 0xFFFF; + pContext32->ContextFlags |= 0x10000; + return STATUS_SUCCESS; +} + +/********************************************************************** + * NtSetInformationProcess + * + * @implemented + */ +NTSTATUS +NTAPI +wow64_NtSetInformationProcess(UINT* pArgs) +{ + HANDLE Handle = get_handle(&pArgs); + PROCESSINFOCLASS Class = get_ulong(&pArgs); + PVOID Information = get_ptr(&pArgs); + ULONG Length = get_ulong(&pArgs); + + switch (Class) + { + case ProcessIoCounters: /* IO_COUNTERS */ + case ProcessTimes: /* KERNEL_USER_TIMES */ + case ProcessDefaultHardErrorMode: /* ULONG */ + case ProcessPriorityClass: /* PROCESS_PRIORITY_CLASS */ + case ProcessHandleCount: /* ULONG */ + case ProcessSessionInformation: /* ULONG */ + case ProcessDebugFlags: /* ULONG */ + case ProcessExecuteFlags: /* ULONG */ + case ProcessCookie: /* ULONG */ + case ProcessCycleTime: /* PROCESS_CYCLE_TIME_INFORMATION */ + return NtSetInformationProcess(Handle, Class, Information, Length); + default: + /* UNIMPLEMENTED */ + __debugbreak(); + return STATUS_NOT_IMPLEMENTED; + } + + return STATUS_SUCCESS; +} + + +/********************************************************************** + * wow64_NtApphelpCacheControl + * + * @implemented + */ +NTSTATUS +NTAPI +wow64_NtApphelpCacheControl(UINT* pArgs) +{ + APPHELP_CACHE_SERVICE_LOOKUP ServiceData; + + APPHELPCACHESERVICECLASS Service = get_ulong(&pArgs); + PAPPHELP_CACHE_SERVICE_LOOKUP32 ServiceData32 = get_ptr(&pArgs); + + ServiceData.ImageHandle = UlongToHandle(ServiceData32->ImageHandle); + unicode_str_32to64(&ServiceData.ImageName, &ServiceData32->ImageName); + + return NtApphelpCacheControl(Service, &ServiceData); +} + +NTSTATUS +NTAPI +wow64_NtQueryInformationThread(UINT* pArgs) +{ + HANDLE hThread = get_handle(&pArgs); + THREADINFOCLASS InfoClass = get_ulong(&pArgs); + PVOID pThreadInfo32 = get_ptr(&pArgs); + ULONG uInfoLength32 = get_ulong(&pArgs); + PULONG pRetLen32 = get_ptr(&pArgs); + + ULONG RetLen = 0; + NTSTATUS Status; + + switch (InfoClass) + { + case ThreadBasicInformation: + { + THREAD_BASIC_INFORMATION BasicInfo; + PTHREAD_BASIC_INFORMATION32 pBasicInfo32 = pThreadInfo32; + + if (uInfoLength32 < sizeof(*pBasicInfo32)) + { + return STATUS_BUFFER_TOO_SMALL; + } + + Status = NtQueryInformationThread(hThread, + InfoClass, + &BasicInfo, + sizeof(BasicInfo), + &RetLen); + + if (!NT_SUCCESS(Status)) + { + return Status; + } + + pBasicInfo32->AffinityMask = BasicInfo.AffinityMask; + pBasicInfo32->BasePriority = BasicInfo.BasePriority; + pBasicInfo32->ClientId.UniqueProcess = + HandleToUlong(BasicInfo.ClientId.UniqueProcess); + pBasicInfo32->ClientId.UniqueThread = + HandleToUlong(BasicInfo.ClientId.UniqueThread); + pBasicInfo32->ExitStatus = BasicInfo.ExitStatus; + pBasicInfo32->Priority = BasicInfo.Priority; + /* FIXME */ + pBasicInfo32->TebBaseAddress = + ROUND_TO_PAGES((ULONG_PTR)((PTEB)BasicInfo.TebBaseAddress + 1)); + + if (pRetLen32 != NULL) + { + *pRetLen32 = sizeof(*pBasicInfo32); + } + + return Status; + } + case ThreadAmILastThread: + return NtQueryInformationThread(hThread, + InfoClass, + pThreadInfo32, + uInfoLength32, + pRetLen32); + /* TODO */ + } + + DPRINT1("Invalid class %X given to " __FUNCTION__ ", investigate. \n", InfoClass); + return STATUS_INVALID_INFO_CLASS; +} + +BOOL +WINAPI +DllMain(HANDLE hDll, + DWORD dwReason, + LPVOID lpReserved) +{ + return TRUE; +} + +static +PULONG +GetKernelCallbackTable32() +{ + return UlongToPtr(NtCurrentPeb32()->KernelCallbackTable); +} + +NTSTATUS +WINAPI +Wow64KiUserCallbackDispatcher(ULONG nCallback, + PVOID IN pArgs, + ULONG nArgLen, + PVOID* OUT ppReturn, + PULONG OUT pnRetLen) +{ + USER_CALLBACK_FRAME frame; + ULONG Args64[2]; + + Args64[0] = PtrToUlong(pArgs); + Args64[1] = nArgLen; + + frame.prev_frame = NtCurrentTeb()->TlsSlots[WOW64_TLS_USERCALLBACKDATA]; + frame.temp_list = NtCurrentTeb()->TlsSlots[WOW64_TLS_TEMPLIST]; + frame.ret_ptr = ppReturn; + frame.ret_len = pnRetLen; + frame.temp_list = NULL; + + NtCurrentTeb()->TlsSlots[WOW64_TLS_USERCALLBACKDATA] = &frame; + NtCurrentTeb()->TlsSlots[WOW64_TLS_TEMPLIST] = NULL; + + if (!setjmp(frame.jmpbuf)) + { + Call32(GetKernelCallbackTable32()[nCallback], 2, Args64); + } + + NtCurrentTeb()->TlsSlots[WOW64_TLS_USERCALLBACKDATA] = frame.prev_frame; + NtCurrentTeb()->TlsSlots[WOW64_TLS_TEMPLIST] = frame.temp_list; + return frame.status; +} + +static +VOID +SetupNls(PPEB Peb, + PPEB32 WowPeb) +{ + /* CHECKME */ + WowPeb->OemCodePageData = PtrToUlong(&OemCopy); + WowPeb->AnsiCodePageData = PtrToUlong(&AnsiCopy); + WowPeb->UnicodeCaseTableData = PtrToUlong(&UnicodeCopy); + RtlCopyMemory(&OemCopy, Peb->OemCodePageData, sizeof(OemCopy)); + RtlCopyMemory(&AnsiCopy, Peb->AnsiCodePageData, sizeof(AnsiCopy)); + RtlCopyMemory(&UnicodeCopy, Peb->UnicodeCaseTableData, sizeof(UnicodeCopy)); +} + +static +VOID +Wow64InitProcess(PCONTEXT pContext) +{ + NTSTATUS Status; + PPEB32 WowPeb = NULL; + PRTL_USER_PROCESS_PARAMETERS32 ProcParams32 = NULL; + PPEB Peb = NtCurrentPeb(); + IMAGE_NT_HEADERS32 *NtHeaders = NULL; + + Status = Wow64InitEntrypointTranslation(); + ASSERT(NT_SUCCESS(Status)); + + NtHeaders = (IMAGE_NT_HEADERS32 *)RtlImageNtHeader(Peb->ImageBaseAddress); + + Status = LdrLoadDll(L"" TMP_WOW_DIR L"\\ntdll.dll", 0, &NtDll32Str, &NtDll32); + if (!NT_SUCCESS(Status)) + { + DPRINT1("32 bit NTDLL.DLL could not be loaded.\n"); + ASSERT(FALSE); + } + + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessWow64Information, + &WowPeb, + sizeof(WowPeb), + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Getting PEB32 info failed: %lx\n", Status); + ASSERT(FALSE); + } + + ProcParams32 = build_wow64_parameters(Peb->ProcessParameters); + WowPeb->ProcessParameters = PtrToUlong(ProcParams32); + + /* FIXME: hack for process heaps */ + WowPeb->MaximumNumberOfHeaps = sizeof(FixmeProcessHeaps) / sizeof(*FixmeProcessHeaps); + WowPeb->ProcessHeaps = PtrToUlong(FixmeProcessHeaps); + + WowPeb->ImageBaseAddress = PtrToUlong(Peb->ImageBaseAddress); + + /* PEB OS Version Data */ + WowPeb->OSMajorVersion = Peb->OSMajorVersion; + WowPeb->OSMinorVersion = Peb->OSMinorVersion; + WowPeb->OSBuildNumber = Peb->OSBuildNumber; + WowPeb->OSPlatformId = Peb->OSPlatformId; + + WowPeb->NtGlobalFlag = Peb->NtGlobalFlag; + + WowPeb->CriticalSectionTimeout = Peb->CriticalSectionTimeout; + WowPeb->NumberOfProcessors = Peb->NumberOfProcessors; + + /* Set up codepage translation data */ + SetupNls(Peb, WowPeb); + + /* Change image path name */ + ProcParams32->ImagePathName.Buffer = PtrToUlong(Peb->ProcessParameters->ImagePathName.Buffer); + ProcParams32->ImagePathName.Length = Peb->ProcessParameters->ImagePathName.Length; + ProcParams32->ImagePathName.MaximumLength = Peb->ProcessParameters->ImagePathName.MaximumLength; + ProcParams32->Flags |= RTL_USER_PROCESS_PARAMETERS_NORMALIZED; + + Status = LdrGetProcedureAddress(NtDll32, + &ImportLdrInitializeThunkStr, + 0, + &NtDll32LdrpRoutine); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Couldn't find LdrInitializeThunk in 32-bit ntdll.dll.\n"); + ASSERT(FALSE); + } + + Status = LdrGetProcedureAddress(NtDll32, + &ImportUserExceptionDispatcherStr, + 0, + &NtDll32KiUserExceptionDispatcher); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Couldn't find KiUserExceptionDispatcher in 32-bit ntdll.dll.\n"); + ASSERT(FALSE); + } + + DPRINT("Getting init function ptr %p\n", NtDll32LdrpRoutine); +} + +LONG +Wow64UnhandledExceptionHandler(IN PEXCEPTION_POINTERS ExceptionInfo); + +static +NTSTATUS +Wow64Trampoline(PCONTEXT pContext) +{ + NTSTATUS Status; + +#pragma pack(push, 1) + struct + { + ULONG_PTR ApcRoutine; + ULONG_PTR SegCs; + ULONG RetAddress32; + ULONG ApcContext; + ULONG SystemArgument1; + ULONG SystemArgument2; + I386_CONTEXT Context32; + } EnterApc32Stack; +#pragma pack(pop) + + Wow64CopyContext64To32(&EnterApc32Stack.Context32, pContext); + Status = Wow64TranslateEntrypoint64To32(NtCurrentProcess(), + &EnterApc32Stack.Context32, + pContext); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + EnterApc32Stack.ApcRoutine = (ULONG_PTR)NtDll32LdrpRoutine; + EnterApc32Stack.SegCs = 0x23; + EnterApc32Stack.RetAddress32 = 0; + EnterApc32Stack.ApcContext = PtrToUlong(&EnterApc32Stack.Context32); + EnterApc32Stack.SystemArgument1 = PtrToUlong(NtDll32); + EnterApc32Stack.SystemArgument2 = 0; + + _SEH2_TRY + { + EnterApc32(&EnterApc32Stack, sizeof(EnterApc32Stack)); + } + _SEH2_EXCEPT(Wow64UnhandledExceptionHandler(_SEH2_GetExceptionInformation())) + { + + } + + Wow64CopyContext32To64(pContext, &EnterApc32Stack.Context32); + return STATUS_SUCCESS; +} + +static +VOID +Wow64InitThread(PCONTEXT pContext) +{ + NTSTATUS Status; + PTEB32 WowTeb = NULL; + PPEB32 WowPeb = NULL; + PTEB Teb = NtCurrentTeb(); + + WowTeb = (PTEB32)ROUND_TO_PAGES((ULONG_PTR)(Teb + 1)); + + DPRINT1("WOW64 TEB %p, TEB %p\n", WowTeb, Teb); + + WowTeb->NtTib.Self = PtrToUlong(WowTeb); + + WowTeb->NtTib.StackLimit = PtrToUlong(Teb->NtTib.StackLimit); + WowTeb->NtTib.StackBase = PtrToUlong(Teb->NtTib.StackBase); + WowTeb->NtTib.ExceptionList = PtrToUlong(EXCEPTION_CHAIN_END); + WowTeb->NtTib.Version = Teb->NtTib.Version; + + WowTeb->StaticUnicodeString.Length = 0; + WowTeb->StaticUnicodeString.MaximumLength = sizeof(WowTeb->StaticUnicodeBuffer); + WowTeb->StaticUnicodeString.Buffer = PtrToUlong(WowTeb->StaticUnicodeBuffer); + + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessWow64Information, + &WowPeb, + sizeof(WowPeb), + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT("Getting Wow64 info failed: %lx\n", Status); + ASSERT(FALSE); + } + + WowTeb->ProcessEnvironmentBlock = PtrToUlong(WowPeb); + + /* Point the FS segment register to the CMTEB entry in the GDT */ + SetupFs(0x0053); + + /* CMTEB GDT entry's fields are set on thread context switches, make sure + correct values are loaded before executing. */ + while(NtYieldExecution() == STATUS_NO_YIELD_PERFORMED); + + /* Initialize WOW64 TLS entries in the 64-bit TEB */ + NtCurrentTeb()->TlsSlots[WOW64_TLS_TEMPLIST] = NULL; + NtCurrentTeb()->TlsSlots[WOW64_TLS_APCLIST] = NULL; + NtCurrentTeb()->TlsSlots[WOW64_TLS_USERCALLBACKDATA] = NULL; + NtCurrentTeb()->TlsSlots[WOW64_TLS_FILESYSREDIR] = (PVOID)TRUE; + + /* Make sure the handler routine pointer fits into the 32-bit TEB */ + ASSERT((((ULONG_PTR)Wow64SystemServiceEx) & ~0xFFFFFFFF) == 0); + WowTeb->WOW32Reserved = PtrToUlong(Wow64SystemServiceEx); + + WowTeb->ClientId.UniqueProcess = HandleToULong(Teb->ClientId.UniqueProcess); + WowTeb->ClientId.UniqueThread = HandleToULong(Teb->ClientId.UniqueThread); + + DPRINT1("Wow64 thread client id: %X:%X\n", WowTeb->ClientId.UniqueProcess, WowTeb->ClientId.UniqueThread); + + Status = Wow64Trampoline(pContext); + ASSERT(NT_SUCCESS(Status)); +} + +void +WINAPI +Wow64LdrpInitialize(PCONTEXT pContext) +{ + static LONG ProcessInitialized = 0; + + if (InterlockedCompareExchange(&ProcessInitialized, + 1, + 0) == 0) + { + __debugbreak(); + Wow64InitProcess(pContext); + } + + Wow64InitThread(pContext); +} diff --git a/dll/wow64win/CMakeLists.txt b/dll/wow64win/CMakeLists.txt new file mode 100644 index 0000000000000..6d4971df37967 --- /dev/null +++ b/dll/wow64win/CMakeLists.txt @@ -0,0 +1,14 @@ +add_definitions(-D_DLL -D__USE_CRTIMP) +include_directories(${REACTOS_SOURCE_DIR}/win32ss/include) +add_library(wow64win MODULE gdi.c syscall.c user_ros.c user.c) + +set_module_type(wow64win win32dll UNICODE ENTRYPOINT DllMain 12) +############################################# +## HACK FOR MSVC COMPILATION WITH win32dll ## +set_subsystem(wow64win console) +################# END HACK ################# + +target_link_libraries(wow64win win32ksys) +add_importlibs(wow64win ntdll wow64) +add_dependencies(wow64win xdk) +add_cd_file(TARGET wow64win DESTINATION reactos/system32 FOR all) diff --git a/dll/wow64win/callback32.h b/dll/wow64win/callback32.h new file mode 100644 index 0000000000000..bffb0d4a07ddd --- /dev/null +++ b/dll/wow64win/callback32.h @@ -0,0 +1,72 @@ +/* + * Wine WOW64 ReactOS port + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: wow64win.dll + * FILE: dll/wow64win/callback32.h + * PROGRAMMER: Marcin Jabłoński + */ + +#pragma once + +typedef struct _WINDOWPROC_CALLBACK_ARGUMENTS32 +{ + ULONG Proc; + ULONG IsAnsiProc; + ULONG Wnd; + UINT Msg; + ULONG wParam; + ULONG lParam; + INT lParamBufferSize; + ULONG Result; +} WINDOWPROC_CALLBACK_ARGUMENTS32, *PWINDOWPROC_CALLBACK_ARGUMENTS32; + +typedef struct _EVENTPROC_CALLBACK_ARGUMENTS32 +{ + ULONG hook; + DWORD event; + ULONG hwnd; + LONG idObject; + LONG idChild; + DWORD dwEventThread; + DWORD dwmsEventTime; + ULONG Proc; + INT Mod; + ULONG offPfn; +} EVENTPROC_CALLBACK_ARGUMENTS32, *PEVENTPROC_CALLBACK_ARGUMENTS32; + +typedef struct _LOADMENU_CALLBACK_ARGUMENTS32 +{ + ULONG hModule; + ULONG InterSource; + WCHAR MenuName[1]; +} LOADMENU_CALLBACK_ARGUMENTS32, *PLOADMENU_CALLBACK_ARGUMENTS32; + +typedef struct _COPYIMAGE_CALLBACK_ARGUMENTS32 +{ + ULONG hImage; + UINT uType; + int cxDesired; + int cyDesired; + UINT fuFlags; +} COPYIMAGE_CALLBACK_ARGUMENTS32, *PCOPYIMAGE_CALLBACK_ARGUMENTS32; + +typedef struct _CLIENT_LOAD_LIBRARY_ARGUMENTS32 +{ + UNICODE_STRING32 strLibraryName; + UNICODE_STRING32 strInitFuncName; + BOOL Unload; + BOOL ApiHook; +} CLIENT_LOAD_LIBRARY_ARGUMENTS32, *PCLIENT_LOAD_LIBRARY_ARGUMENTS32; + +typedef struct _LPK_CALLBACK_ARGUMENTS32 +{ + ULONG lpString; + ULONG hdc; + INT x; + INT y; + UINT flags; + RECT rect; + UINT count; + BOOL bRect; +} LPK_CALLBACK_ARGUMENTS32, *PLPK_CALLBACK_ARGUMENTS32; diff --git a/dll/wow64win/gdi.c b/dll/wow64win/gdi.c new file mode 100644 index 0000000000000..44535936fe3e9 --- /dev/null +++ b/dll/wow64win/gdi.c @@ -0,0 +1,2940 @@ +/* + * WoW64 GDI functions + * + * Copyright 2021 Jacek Caban for CodeWeavers + * Copyright 2025 Marcin Jabłoński + * + * 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 + +#ifndef __REACTOS__ +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "ntgdi.h" +#include "ddk/d3dkmthk.h" +#include "wow64win_private.h" +#else + +#include "wow64win_private.h" + +/* FIXME */ +#define NTGDI_OBJ_EXTPEN GDI_OBJECT_TYPE_EXTPEN +#define NTGDI_OBJ_PEN GDI_OBJECT_TYPE_PEN +#define NTGDI_OBJ_BITMAP GDI_OBJECT_TYPE_BITMAP +#define NTGDI_HANDLE_TYPE_MASK GDI_HANDLE_TYPE_MASK + +/* FIXME */ +#define const + +#endif + + +typedef struct +{ + INT bmType; + INT bmWidth; + INT bmHeight; + INT bmWidthBytes; + WORD bmPlanes; + WORD bmBitsPixel; + ULONG bmBits; +} BITMAP32; + +typedef struct +{ + DWORD elpPenStyle; + DWORD elpWidth; + UINT elpBrushStyle; + COLORREF elpColor; + ULONG elpHatch; + DWORD elpNumEntries; + DWORD elpStyleEntry[1]; +} EXTLOGPEN32; + +typedef struct +{ + UINT otmSize; + TEXTMETRICW otmTextMetrics; + BYTE otmFiller; + PANOSE otmPanoseNumber; + UINT otmfsSelection; + UINT otmfsType; + INT otmsCharSlopeRise; + INT otmsCharSlopeRun; + INT otmItalicAngle; + UINT otmEMSquare; + INT otmAscent; + INT otmDescent; + UINT otmLineGap; + UINT otmsCapEmHeight; + UINT otmsXHeight; + RECT otmrcFontBox; + INT otmMacAscent; + INT otmMacDescent; + UINT otmMacLineGap; + UINT otmusMinimumPPEM; + POINT otmptSubscriptSize; + POINT otmptSubscriptOffset; + POINT otmptSuperscriptSize; + POINT otmptSuperscriptOffset; + UINT otmsStrikeoutSize; + INT otmsStrikeoutPosition; + INT otmsUnderscoreSize; + INT otmsUnderscorePosition; + ULONG otmpFamilyName; + ULONG otmpFaceName; + ULONG otmpStyleName; + ULONG otmpFullName; +} OUTLINETEXTMETRIC32; + + +static DWORD gdi_handle_type( HGDIOBJ obj ) +{ + unsigned int handle = HandleToUlong( obj ); + return handle & NTGDI_HANDLE_TYPE_MASK; +} + +NTSTATUS WINAPI wow64_NtGdiAbortDoc( UINT *args ) +{ + HDC hdc = get_handle( &args ); + + return NtGdiAbortDoc( hdc ); +} + +NTSTATUS WINAPI wow64_NtGdiAbortPath( UINT *args ) +{ + HDC hdc = get_handle( &args ); + + return NtGdiAbortPath( hdc ); +} + +NTSTATUS WINAPI wow64_NtGdiAddFontMemResourceEx( UINT *args ) +{ + void *ptr = get_ptr( &args ); + DWORD size = get_ulong( &args ); + void *dv = get_ptr( &args ); + ULONG dv_size = get_ulong( &args ); + DWORD *count = get_ptr( &args ); + + return HandleToUlong( NtGdiAddFontMemResourceEx( ptr, size, dv, dv_size, count )); +} + +NTSTATUS WINAPI wow64_NtGdiAddFontResourceW( UINT *args ) +{ + const WCHAR *str = get_ptr( &args ); + ULONG size = get_ulong( &args ); + ULONG files = get_ulong( &args ); + DWORD flags = get_ulong( &args ); + DWORD tid = get_ulong( &args ); + void *dv = get_ptr( &args ); + + return NtGdiAddFontResourceW( str, size, files, flags, tid, dv ); +} + +NTSTATUS WINAPI wow64_NtGdiAlphaBlend( UINT *args ) +{ + HDC hdc_dst = get_handle( &args ); + int x_dst = get_ulong( &args ); + int y_dst = get_ulong( &args ); + int width_dst = get_ulong( &args ); + int height_dst = get_ulong( &args ); + HDC hdc_src = get_handle( &args ); + int x_src = get_ulong( &args ); + int y_src = get_ulong( &args ); + int width_src = get_ulong( &args ); + int height_src = get_ulong( &args ); +#ifndef __REACTOS__ + DWORD blend_function = get_ulong( &args ); +#else + DWORD blend_function_ulong = get_ulong( &args ); + BLENDFUNCTION blend_function = *((BLENDFUNCTION*)&blend_function_ulong); +#endif + HANDLE xform = get_handle( &args ); + + return NtGdiAlphaBlend( hdc_dst, x_dst, y_dst, width_dst, height_dst, hdc_src, + x_src, y_src, width_src, height_src, blend_function, xform ); +} + +NTSTATUS WINAPI wow64_NtGdiAngleArc( UINT *args ) +{ + HDC hdc = get_handle( &args ); + INT x = get_ulong( &args ); + INT y = get_ulong( &args ); + DWORD radius = get_ulong( &args ); + DWORD start_angle = get_ulong( &args ); + DWORD sweep_angle = get_ulong( &args ); + + return NtGdiAngleArc( hdc, x, y, radius, start_angle, sweep_angle ); +} + +NTSTATUS WINAPI wow64_NtGdiArcInternal( UINT *args ) +{ + UINT type = get_ulong( &args ); + HDC hdc = get_handle( &args ); + INT left = get_ulong( &args ); + INT top = get_ulong( &args ); + INT right = get_ulong( &args ); + INT bottom = get_ulong( &args ); + INT xstart = get_ulong( &args ); + INT ystart = get_ulong( &args ); + INT xend = get_ulong( &args ); + INT yend = get_ulong( &args ); + + return NtGdiArcInternal( type, hdc, left, top, right, bottom, xstart, ystart, xend, yend ); +} + +NTSTATUS WINAPI wow64_NtGdiBeginPath( UINT *args ) +{ + HDC hdc = get_handle( &args ); + + return NtGdiBeginPath( hdc ); +} + +NTSTATUS WINAPI wow64_NtGdiBitBlt( UINT *args ) +{ + HDC hdc_dst = get_handle( &args ); + INT x_dst = get_ulong( &args ); + INT y_dst = get_ulong( &args ); + INT width = get_ulong( &args ); + INT height = get_ulong( &args ); + HDC hdc_src = get_handle( &args ); + INT x_src = get_ulong( &args ); + INT y_src = get_ulong( &args ); + DWORD rop = get_ulong( &args ); + DWORD bk_color = get_ulong( &args ); + FLONG fl = get_ulong( &args ); + + return NtGdiBitBlt( hdc_dst, x_dst, y_dst, width, height, hdc_src, + x_src, y_src, rop, bk_color, fl ); +} + +NTSTATUS WINAPI wow64_NtGdiCloseFigure( UINT *args ) +{ + HDC hdc = get_handle( &args ); + + return NtGdiCloseFigure( hdc ); +} + +NTSTATUS WINAPI wow64_NtGdiCombineRgn( UINT *args ) +{ + HRGN dest = get_handle( &args ); + HRGN src1 = get_handle( &args ); + HRGN src2 = get_handle( &args ); + INT mode = get_ulong( &args ); + + return NtGdiCombineRgn( dest, src1, src2, mode ); +} + +NTSTATUS WINAPI wow64_NtGdiComputeXformCoefficients( UINT *args ) +{ + HDC hdc = get_handle( &args ); + + return NtGdiComputeXformCoefficients( hdc ); +} + +NTSTATUS WINAPI wow64_NtGdiCreateBitmap( UINT *args ) +{ + INT width = get_ulong( &args ); + INT height = get_ulong( &args ); + UINT planes = get_ulong( &args ); + UINT bpp = get_ulong( &args ); + const void *bits = get_ptr( &args ); + + return HandleToUlong( NtGdiCreateBitmap( width, height, planes, bpp, bits )); +} + +NTSTATUS WINAPI wow64_NtGdiCreateClientObj( UINT *args ) +{ + ULONG type = get_ulong( &args ); + + return HandleToUlong( NtGdiCreateClientObj( type )); +} + +NTSTATUS WINAPI wow64_NtGdiCreateCompatibleBitmap( UINT *args ) +{ + HDC hdc = get_handle( &args ); + INT width = get_ulong( &args ); + INT height = get_ulong( &args ); + + return HandleToUlong( NtGdiCreateCompatibleBitmap( hdc, width, height )); +} + +NTSTATUS WINAPI wow64_NtGdiCreateCompatibleDC( UINT *args ) +{ + HDC hdc = get_handle( &args ); + + return HandleToUlong( NtGdiCreateCompatibleDC( hdc )); +} + +NTSTATUS WINAPI wow64_NtGdiCreateDIBBrush( UINT *args ) +{ + const void *data = get_ptr( &args ); + UINT coloruse = get_ulong( &args ); + UINT size = get_ulong( &args ); + BOOL is_8x8 = get_ulong( &args ); + BOOL pen = get_ulong( &args ); + const void *client = get_ptr( &args ); + + return HandleToUlong( NtGdiCreateDIBBrush( data, coloruse, size, is_8x8, pen, client )); +} + +NTSTATUS WINAPI wow64_NtGdiCreateDIBSection( UINT *args ) +{ + HDC hdc = get_handle( &args ); + HANDLE section = get_handle( &args ); + DWORD offset = get_ulong( &args ); + const BITMAPINFO *bmi = get_ptr( &args ); + UINT usage = get_ulong( &args ); + UINT header_size = get_ulong( &args ); + ULONG flags = get_ulong( &args ); + ULONG_PTR color_space = get_ulong( &args ); + void *bits32 = get_ptr( &args ); + + void *bits; + HBITMAP ret; + + ret = NtGdiCreateDIBSection( hdc, section, offset, bmi, usage, header_size, + flags, color_space, addr_32to64( &bits, bits32 )); + put_addr( bits32, bits ); + return HandleToUlong( ret ); +} + +NTSTATUS WINAPI wow64_NtGdiCreateDIBitmapInternal( UINT *args ) +{ + HDC hdc = get_handle( &args ); + INT width = get_ulong( &args ); + INT height = get_ulong( &args ); + DWORD init = get_ulong( &args ); + const void *bits = get_ptr( &args ); + const BITMAPINFO *data = get_ptr( &args ); + UINT coloruse = get_ulong( &args ); + UINT max_info = get_ulong( &args ); + UINT max_bits = get_ulong( &args ); + ULONG flags = get_ulong( &args ); + HANDLE xform = get_handle( &args ); + + HBITMAP ret = NtGdiCreateDIBitmapInternal( hdc, width, height, init, bits, data, + coloruse, max_info, max_bits, flags, xform ); + return HandleToUlong( ret ); +} + +NTSTATUS WINAPI wow64_NtGdiCreateEllipticRgn( UINT *args ) +{ + INT left = get_ulong( &args ); + INT top = get_ulong( &args ); + INT right = get_ulong( &args ); + INT bottom = get_ulong( &args ); + + return HandleToUlong( NtGdiCreateEllipticRgn( left, top, right, bottom )); +} + +NTSTATUS WINAPI wow64_NtGdiCreateHalftonePalette( UINT *args ) +{ + HDC hdc = get_handle( &args ); + + return HandleToUlong( NtGdiCreateHalftonePalette( hdc )); +} + +NTSTATUS WINAPI wow64_NtGdiCreateHatchBrushInternal( UINT *args ) +{ + INT style = get_ulong( &args ); + COLORREF color = get_ulong( &args ); + BOOL pen = get_ulong( &args ); + + return HandleToULong( NtGdiCreateHatchBrushInternal( style, color, pen )); +} + +NTSTATUS WINAPI wow64_NtGdiCreateMetafileDC( UINT *args ) +{ + HDC hdc = get_handle( &args ); + + return HandleToUlong( NtGdiCreateMetafileDC( hdc )); +} + +NTSTATUS WINAPI wow64_NtGdiCreatePaletteInternal( UINT *args ) +{ + const LOGPALETTE *palette = get_ptr( &args ); + UINT count = get_ulong( &args ); + + return HandleToUlong( NtGdiCreatePaletteInternal( palette, count )); +} + +NTSTATUS WINAPI wow64_NtGdiCreatePatternBrushInternal( UINT *args ) +{ + HBITMAP hbitmap = get_handle( &args ); + BOOL pen = get_ulong( &args ); + BOOL is_8x8 = get_ulong( &args ); + + return HandleToUlong( NtGdiCreatePatternBrushInternal( hbitmap, pen, is_8x8 )); +} + +NTSTATUS WINAPI wow64_NtGdiCreatePen( UINT *args ) +{ + INT style = get_ulong( &args ); + INT width = get_ulong( &args ); + COLORREF color = get_ulong( &args ); + HBRUSH brush = get_handle( &args ); + + return HandleToUlong( NtGdiCreatePen( style, width, color, brush )); +} + +NTSTATUS WINAPI wow64_NtGdiCreateRectRgn( UINT *args ) +{ + INT left = get_ulong( &args ); + INT top = get_ulong( &args ); + INT right = get_ulong( &args ); + INT bottom = get_ulong( &args ); + + return HandleToUlong( NtGdiCreateRectRgn( left, top, right, bottom )); +} + +NTSTATUS WINAPI wow64_NtGdiCreateRoundRectRgn( UINT *args ) +{ + INT left = get_ulong( &args ); + INT top = get_ulong( &args ); + INT right = get_ulong( &args ); + INT bottom = get_ulong( &args ); + INT ellipse_width = get_ulong( &args ); + INT ellipse_height = get_ulong( &args ); + + return HandleToUlong( NtGdiCreateRoundRectRgn( left, top, right, bottom, + ellipse_width, ellipse_height )); +} + +NTSTATUS WINAPI wow64_NtGdiCreateSolidBrush( UINT *args ) +{ + COLORREF color = get_ulong( &args ); + HBRUSH brush = get_handle( &args ); + + return HandleToUlong( NtGdiCreateSolidBrush( color, brush )); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtGdiDdDDICheckVidPnExclusiveOwnership( UINT *args ) +{ + const D3DKMT_CHECKVIDPNEXCLUSIVEOWNERSHIP *desc = get_ptr( &args ); + + return NtGdiDdDDICheckVidPnExclusiveOwnership( desc ); +} + +NTSTATUS WINAPI wow64_NtGdiDdDDICloseAdapter( UINT *args ) +{ + const D3DKMT_CLOSEADAPTER *desc = get_ptr( &args ); + + return NtGdiDdDDICloseAdapter( desc ); +} + +NTSTATUS WINAPI wow64_NtGdiDdDDICreateAllocation( UINT *args ) +{ + struct + { + D3DKMT_HANDLE hAllocation; + ULONG pSystemMem; + ULONG pPrivateDriverData; + UINT PrivateDriverDataSize; + D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId; + union + { + struct + { + UINT Primary : 1; + UINT Stereo : 1; + UINT Reserved : 30; + }; + UINT Value; + } Flags; + } *allocs32; + typedef struct + { + ULONG Size; + } D3DKMT_STANDARDALLOCATION_EXISTINGHEAP32; + struct + { + D3DKMT_STANDARDALLOCATIONTYPE Type; + union + { + D3DKMT_STANDARDALLOCATION_EXISTINGHEAP32 ExistingHeapData; + }; + D3DKMT_CREATESTANDARDALLOCATIONFLAGS Flags; + } *standard32; + struct + { + D3DKMT_HANDLE hDevice; + D3DKMT_HANDLE hResource; + D3DKMT_HANDLE hGlobalShare; + ULONG pPrivateRuntimeData; + UINT PrivateRuntimeDataSize; + union + { + ULONG pStandardAllocation; + ULONG pPrivateDriverData; + }; + UINT PrivateDriverDataSize; + UINT NumAllocations; + ULONG pAllocationInfo; + D3DKMT_CREATEALLOCATIONFLAGS Flags; + HANDLE hPrivateRuntimeResourceHandle; + } *desc32 = get_ptr( &args ); + D3DKMT_CREATESTANDARDALLOCATION standard; + D3DKMT_CREATEALLOCATION desc; + NTSTATUS status; + UINT i; + + desc.hDevice = desc32->hDevice; + desc.hResource = desc32->hResource; + desc.pPrivateRuntimeData = UlongToPtr( desc32->pPrivateRuntimeData ); + desc.PrivateRuntimeDataSize = desc32->PrivateRuntimeDataSize; + if (!desc32->Flags.StandardAllocation) + { + desc.pPrivateDriverData = UlongToPtr( desc32->pPrivateDriverData ); + desc.PrivateDriverDataSize = desc32->PrivateDriverDataSize; + } + else + { + standard32 = UlongToPtr( desc32->pStandardAllocation ); + standard.Type = standard32->Type; + standard.ExistingHeapData.Size = standard32->ExistingHeapData.Size; + standard.Flags = standard32->Flags; + + desc.pStandardAllocation = &standard; + desc.PrivateDriverDataSize = sizeof(standard); + } + desc.NumAllocations = desc32->NumAllocations; + desc.pAllocationInfo = NULL; + if (desc32->pAllocationInfo && desc32->NumAllocations) + { + if (!(desc.pAllocationInfo = Wow64AllocateTemp( desc32->NumAllocations + sizeof(*desc.pAllocationInfo) ))) + return STATUS_NO_MEMORY; + + allocs32 = UlongToPtr( desc32->pAllocationInfo ); + for (i = 0; i < desc32->NumAllocations; i++) + { + desc.pAllocationInfo[i].hAllocation = allocs32->hAllocation; + desc.pAllocationInfo[i].pSystemMem = UlongToPtr( allocs32->pSystemMem ); + desc.pAllocationInfo[i].pPrivateDriverData = UlongToPtr( allocs32->pPrivateDriverData ); + desc.pAllocationInfo[i].PrivateDriverDataSize = allocs32->PrivateDriverDataSize; + desc.pAllocationInfo[i].VidPnSourceId = allocs32->VidPnSourceId; + desc.pAllocationInfo[i].Flags.Value = allocs32->Flags.Value; + } + } + desc.Flags = desc32->Flags; + desc.hPrivateRuntimeResourceHandle = desc32->hPrivateRuntimeResourceHandle; + + status = NtGdiDdDDICreateAllocation( &desc ); + desc.hResource = desc32->hResource; + desc.hGlobalShare = desc32->hGlobalShare; + return status; +} + +NTSTATUS WINAPI wow64_NtGdiDdDDICreateAllocation2( UINT *args ) +{ + struct + { + D3DKMT_HANDLE hAllocation; + ULONG pSystemMem; + ULONG pPrivateDriverData; + UINT PrivateDriverDataSize; + D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId; + union + { + struct + { + UINT Primary : 1; + UINT Stereo : 1; + UINT OverridePriority : 1; + UINT Reserved : 29; + }; + UINT Value; + } Flags; + D3DGPU_VIRTUAL_ADDRESS GpuVirtualAddress; + ULONG Priority; + ULONG Reserved[5]; + } *allocs32 = NULL; + typedef struct + { + ULONG Size; + } D3DKMT_STANDARDALLOCATION_EXISTINGHEAP32; + struct + { + D3DKMT_STANDARDALLOCATIONTYPE Type; + union + { + D3DKMT_STANDARDALLOCATION_EXISTINGHEAP32 ExistingHeapData; + }; + D3DKMT_CREATESTANDARDALLOCATIONFLAGS Flags; + } *standard32; + struct + { + D3DKMT_HANDLE hDevice; + D3DKMT_HANDLE hResource; + D3DKMT_HANDLE hGlobalShare; + ULONG pPrivateRuntimeData; + UINT PrivateRuntimeDataSize; + union + { + ULONG pStandardAllocation; + ULONG pPrivateDriverData; + }; + UINT PrivateDriverDataSize; + UINT NumAllocations; + ULONG pAllocationInfo2; + D3DKMT_CREATEALLOCATIONFLAGS Flags; + HANDLE hPrivateRuntimeResourceHandle; + } *desc32 = get_ptr( &args ); + D3DKMT_CREATESTANDARDALLOCATION standard; + D3DKMT_CREATEALLOCATION desc; + NTSTATUS status; + UINT i; + + desc.hDevice = desc32->hDevice; + desc.hResource = desc32->hResource; + desc.pPrivateRuntimeData = UlongToPtr( desc32->pPrivateRuntimeData ); + desc.PrivateRuntimeDataSize = desc32->PrivateRuntimeDataSize; + if (!desc32->Flags.StandardAllocation) + { + desc.pPrivateDriverData = UlongToPtr( desc32->pPrivateDriverData ); + desc.PrivateDriverDataSize = desc32->PrivateDriverDataSize; + } + else + { + standard32 = UlongToPtr( desc32->pStandardAllocation ); + standard.Type = standard32->Type; + standard.ExistingHeapData.Size = standard32->ExistingHeapData.Size; + standard.Flags = standard32->Flags; + + desc.pStandardAllocation = &standard; + desc.PrivateDriverDataSize = sizeof(standard); + } + desc.NumAllocations = desc32->NumAllocations; + desc.pAllocationInfo2 = NULL; + if (desc32->pAllocationInfo2 && desc32->NumAllocations) + { + if (!(desc.pAllocationInfo2 = Wow64AllocateTemp( desc32->NumAllocations + sizeof(*desc.pAllocationInfo2) ))) + return STATUS_NO_MEMORY; + + allocs32 = UlongToPtr( desc32->pAllocationInfo2 ); + for (i = 0; i < desc32->NumAllocations; i++) + { + desc.pAllocationInfo2[i].hAllocation = allocs32->hAllocation; + desc.pAllocationInfo2[i].pSystemMem = UlongToPtr( allocs32->pSystemMem ); + desc.pAllocationInfo2[i].pPrivateDriverData = UlongToPtr( allocs32->pPrivateDriverData ); + desc.pAllocationInfo2[i].PrivateDriverDataSize = allocs32->PrivateDriverDataSize; + desc.pAllocationInfo2[i].VidPnSourceId = allocs32->VidPnSourceId; + desc.pAllocationInfo2[i].Flags.Value = allocs32->Flags.Value; + desc.pAllocationInfo2[i].Priority = allocs32->Priority; + } + } + desc.Flags = desc32->Flags; + desc.hPrivateRuntimeResourceHandle = desc32->hPrivateRuntimeResourceHandle; + + status = NtGdiDdDDICreateAllocation( &desc ); + desc.hResource = desc32->hResource; + desc.hGlobalShare = desc32->hGlobalShare; + for (i = 0; desc32->pAllocationInfo2 && i < desc32->NumAllocations; i++) + allocs32->GpuVirtualAddress = desc.pAllocationInfo2[i].GpuVirtualAddress; + return status; +} + +NTSTATUS WINAPI wow64_NtGdiDdDDICreateDCFromMemory( UINT *args ) +{ + struct _D3DKMT_CREATEDCFROMMEMORY + { + ULONG pMemory; + D3DDDIFORMAT Format; + UINT Width; + UINT Height; + UINT Pitch; + ULONG hDeviceDc; + ULONG pColorTable; + ULONG hDc; + ULONG hBitmap; + } *desc32 = get_ptr( &args ); + + D3DKMT_CREATEDCFROMMEMORY desc; + NTSTATUS status; + + if (!desc32) return STATUS_INVALID_PARAMETER; + desc.pMemory = UlongToPtr( desc32->pMemory ); + desc.Format = desc32->Format; + desc.Width = desc32->Width; + desc.Height = desc32->Height; + desc.Pitch = desc32->Pitch; + desc.hDeviceDc = UlongToHandle( desc32->hDeviceDc ); + desc.pColorTable = UlongToPtr( desc32->pColorTable ); + + if (!(status = NtGdiDdDDICreateDCFromMemory( &desc ))) + { + desc32->hDc = HandleToUlong( desc.hDc ); + desc32->hBitmap = HandleToUlong( desc.hBitmap ); + } + return status; +} + +NTSTATUS WINAPI wow64_NtGdiDdDDICreateDevice( UINT *args ) +{ + struct + { + D3DKMT_HANDLE hAdapter; + D3DKMT_CREATEDEVICEFLAGS Flags; + D3DKMT_HANDLE hDevice; + ULONG pCommandBuffer; + UINT CommandBufferSize; + ULONG pAllocationList; + UINT AllocationListSize; + ULONG pPatchLocationList; + UINT PatchLocationListSize; + } *desc32 = get_ptr( &args ); + + D3DKMT_CREATEDEVICE desc; + NTSTATUS status; + + if (!desc32) return STATUS_INVALID_PARAMETER; + desc.hAdapter = desc32->hAdapter; + desc.Flags = desc32->Flags; + desc.pCommandBuffer = UlongToPtr( desc32->pCommandBuffer ); + desc.CommandBufferSize = desc32->CommandBufferSize; + desc.pAllocationList = UlongToPtr( desc32->pAllocationList ); + desc.AllocationListSize = desc32->AllocationListSize; + desc.pPatchLocationList = UlongToPtr( desc32->pPatchLocationList ); + desc.PatchLocationListSize = desc32->PatchLocationListSize; + if (!(status = NtGdiDdDDICreateDevice( &desc ))) + desc32->hDevice = desc.hDevice; + return status; +} + +NTSTATUS WINAPI wow64_NtGdiDdDDICreateKeyedMutex( UINT *args ) +{ + D3DKMT_CREATEKEYEDMUTEX *desc = get_ptr( &args ); + return NtGdiDdDDICreateKeyedMutex( desc ); +} + +NTSTATUS WINAPI wow64_NtGdiDdDDICreateKeyedMutex2( UINT *args ) +{ + struct + { + UINT64 InitialValue; + D3DKMT_HANDLE hSharedHandle; + D3DKMT_HANDLE hKeyedMutex; + ULONG pPrivateRuntimeData; + UINT PrivateRuntimeDataSize; + D3DKMT_CREATEKEYEDMUTEX2_FLAGS Flags; + } *desc32 = get_ptr( &args ); + D3DKMT_CREATEKEYEDMUTEX2 desc; + NTSTATUS status; + + desc.InitialValue = desc32->InitialValue; + desc.hSharedHandle = desc32->hSharedHandle; + desc.pPrivateRuntimeData = ULongToPtr( desc32->pPrivateRuntimeData ); + desc.PrivateRuntimeDataSize = desc32->PrivateRuntimeDataSize; + desc.Flags = desc32->Flags; + status = NtGdiDdDDICreateKeyedMutex2( &desc ); + desc32->hKeyedMutex = desc.hKeyedMutex; + return status; +} + +NTSTATUS WINAPI wow64_NtGdiDdDDICreateSynchronizationObject( UINT *args ) +{ + D3DKMT_CREATESYNCHRONIZATIONOBJECT *desc = get_ptr( &args ); + return NtGdiDdDDICreateSynchronizationObject( desc ); +} + +NTSTATUS WINAPI wow64_NtGdiDdDDICreateSynchronizationObject2( UINT *args ) +{ + D3DKMT_CREATESYNCHRONIZATIONOBJECT2 *desc = get_ptr( &args ); + + if (desc->Info.Type == D3DDDI_CPU_NOTIFICATION) + { + ULONG event = HandleToUlong( desc->Info.CPUNotification.Event ); + desc->Info.CPUNotification.Event = UlongToHandle( event ); + } + + return NtGdiDdDDICreateSynchronizationObject2( desc ); +} + +NTSTATUS WINAPI wow64_NtGdiDdDDIDestroyAllocation( UINT *args ) +{ + struct + { + D3DKMT_HANDLE hDevice; + D3DKMT_HANDLE hResource; + ULONG phAllocationList; + UINT AllocationCount; + } *desc32 = get_ptr( &args ); + D3DKMT_DESTROYALLOCATION desc; + + desc.hDevice = desc32->hDevice; + desc.hResource = desc32->hResource; + desc.phAllocationList = ULongToPtr( desc32->phAllocationList ); + desc.AllocationCount = desc32->AllocationCount; + return NtGdiDdDDIDestroyAllocation( &desc ); +} + +NTSTATUS WINAPI wow64_NtGdiDdDDIDestroyAllocation2( UINT *args ) +{ + struct + { + D3DKMT_HANDLE hDevice; + D3DKMT_HANDLE hResource; + ULONG phAllocationList; + UINT AllocationCount; + D3DDDICB_DESTROYALLOCATION2FLAGS Flags; + } *desc32 = get_ptr( &args ); + D3DKMT_DESTROYALLOCATION2 desc; + + desc.hDevice = desc32->hDevice; + desc.hResource = desc32->hResource; + desc.phAllocationList = ULongToPtr( desc32->phAllocationList ); + desc.AllocationCount = desc32->AllocationCount; + desc.Flags = desc32->Flags; + return NtGdiDdDDIDestroyAllocation2( &desc ); +} + +NTSTATUS WINAPI wow64_NtGdiDdDDIDestroyDCFromMemory( UINT *args ) +{ + const struct + { + ULONG hDc; + ULONG hBitmap; + } *desc32 = get_ptr( &args ); + D3DKMT_DESTROYDCFROMMEMORY desc; + + if (!desc32) return STATUS_INVALID_PARAMETER; + desc.hDc = UlongToHandle( desc32->hDc ); + desc.hBitmap = UlongToHandle( desc32->hBitmap ); + + return NtGdiDdDDIDestroyDCFromMemory( &desc ); +} + +NTSTATUS WINAPI wow64_NtGdiDdDDIDestroyDevice( UINT *args ) +{ + const D3DKMT_DESTROYDEVICE *desc = get_ptr( &args ); + + return NtGdiDdDDIDestroyDevice( desc ); +} + +NTSTATUS WINAPI wow64_NtGdiDdDDIDestroyKeyedMutex( UINT *args ) +{ + D3DKMT_DESTROYKEYEDMUTEX *desc = get_ptr( &args ); + return NtGdiDdDDIDestroyKeyedMutex( desc ); +} + +NTSTATUS WINAPI wow64_NtGdiDdDDIDestroySynchronizationObject( UINT *args ) +{ + D3DKMT_DESTROYSYNCHRONIZATIONOBJECT *desc = get_ptr( &args ); + return NtGdiDdDDIDestroySynchronizationObject( desc ); +} + +NTSTATUS WINAPI wow64_NtGdiDdDDIEnumAdapters( UINT *args ) +{ + D3DKMT_ENUMADAPTERS *desc = get_ptr( &args ); + + return NtGdiDdDDIEnumAdapters( desc ); +} + +NTSTATUS WINAPI wow64_NtGdiDdDDIEnumAdapters2( UINT *args ) +{ + struct + { + ULONG NumAdapters; + ULONG pAdapters; + } *desc32 = get_ptr( &args ); + D3DKMT_ENUMADAPTERS2 desc; + NTSTATUS status; + + if (!desc32) return STATUS_INVALID_PARAMETER; + + desc.NumAdapters = desc32->NumAdapters; + desc.pAdapters = UlongToPtr( desc32->pAdapters ); + + status = NtGdiDdDDIEnumAdapters2( &desc ); + + desc32->NumAdapters = desc.NumAdapters; + + return status; +} + +NTSTATUS WINAPI wow64_NtGdiDdDDIEscape( UINT *args ) +{ + const struct + { + D3DKMT_HANDLE hAdapter; + D3DKMT_HANDLE hDevice; + D3DKMT_ESCAPETYPE Type; + D3DDDI_ESCAPEFLAGS Flags; + ULONG pPrivateDriverData; + UINT PrivateDriverDataSize; + D3DKMT_HANDLE hContext; + } *desc32 = get_ptr( &args ); + D3DKMT_ESCAPE desc; + + if (!desc32) return STATUS_INVALID_PARAMETER; + desc.hAdapter = desc32->hAdapter; + desc.hDevice = desc32->hDevice; + desc.Type = desc32->Type; + desc.Flags = desc32->Flags; + desc.pPrivateDriverData = UlongToPtr( desc32->pPrivateDriverData ); + desc.PrivateDriverDataSize = desc32->PrivateDriverDataSize; + desc.hContext = desc32->hContext; + + return NtGdiDdDDIEscape( &desc ); +} + +NTSTATUS WINAPI wow64_NtGdiDdDDIOpenAdapterFromDeviceName( UINT *args ) +{ + struct _D3DKMT_OPENADAPTERFROMDEVICENAME + { + ULONG pDeviceName; + D3DKMT_HANDLE hAdapter; + LUID AdapterLuid; + } *desc32 = get_ptr( &args ); + D3DKMT_OPENADAPTERFROMDEVICENAME desc; + NTSTATUS status; + + if (!desc32) return STATUS_INVALID_PARAMETER; + desc.pDeviceName = UlongToPtr( desc32->pDeviceName ); + + if (!(status = NtGdiDdDDIOpenAdapterFromDeviceName( &desc ))) + { + desc32->hAdapter = desc.hAdapter; + desc32->AdapterLuid = desc.AdapterLuid; + } + return status; +} + +NTSTATUS WINAPI wow64_NtGdiDdDDIOpenAdapterFromHdc( UINT *args ) +{ + struct + { + ULONG hDc; + D3DKMT_HANDLE hAdapter; + LUID AdapterLuid; + D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId; + } *desc32 = get_ptr( &args ); + + D3DKMT_OPENADAPTERFROMHDC desc; + NTSTATUS status; + + if (!desc32) return STATUS_INVALID_PARAMETER; + desc.hDc = UlongToHandle( desc32->hDc ); + if (!(status = NtGdiDdDDIOpenAdapterFromHdc( &desc ))) + { + desc32->hAdapter = desc.hAdapter; + desc32->AdapterLuid = desc.AdapterLuid; + desc32->VidPnSourceId = desc.VidPnSourceId; + } + return status; +} + +NTSTATUS WINAPI wow64_NtGdiDdDDIOpenAdapterFromLuid( UINT *args ) +{ + D3DKMT_OPENADAPTERFROMLUID *desc = get_ptr( &args ); + + return NtGdiDdDDIOpenAdapterFromLuid( desc ); +} + +NTSTATUS WINAPI wow64_NtGdiDdDDIOpenKeyedMutex( UINT *args ) +{ + D3DKMT_OPENKEYEDMUTEX *desc = get_ptr( &args ); + return NtGdiDdDDIOpenKeyedMutex( desc ); +} + +NTSTATUS WINAPI wow64_NtGdiDdDDIOpenKeyedMutex2( UINT *args ) +{ + struct + { + D3DKMT_HANDLE hSharedHandle; + D3DKMT_HANDLE hKeyedMutex; + ULONG pPrivateRuntimeData; + UINT PrivateRuntimeDataSize; + } *desc32 = get_ptr( &args ); + D3DKMT_OPENKEYEDMUTEX2 desc; + NTSTATUS status; + + desc.hSharedHandle = desc32->hSharedHandle; + desc.pPrivateRuntimeData = UlongToPtr( desc32->pPrivateRuntimeData ); + desc.PrivateRuntimeDataSize = desc32->PrivateRuntimeDataSize; + status = NtGdiDdDDIOpenKeyedMutex2( &desc ); + desc32->hKeyedMutex = desc.hKeyedMutex; + return status; +} + +NTSTATUS WINAPI wow64_NtGdiDdDDIOpenKeyedMutexFromNtHandle( UINT *args ) +{ + struct + { + ULONG hNtHandle; + D3DKMT_HANDLE hKeyedMutex; + ULONG pPrivateRuntimeData; + UINT PrivateRuntimeDataSize; + } *desc32 = get_ptr( &args ); + D3DKMT_OPENKEYEDMUTEXFROMNTHANDLE desc; + NTSTATUS status; + + desc.hNtHandle = UlongToHandle( desc32->hNtHandle ); + desc.pPrivateRuntimeData = UlongToPtr( desc32->pPrivateRuntimeData ); + desc.PrivateRuntimeDataSize = desc32->PrivateRuntimeDataSize; + status = NtGdiDdDDIOpenKeyedMutexFromNtHandle( &desc ); + desc32->hKeyedMutex = desc.hKeyedMutex; + return status; +} + +NTSTATUS WINAPI wow64_NtGdiDdDDIOpenResource( UINT *args ) +{ + struct + { + D3DKMT_HANDLE hAllocation; + ULONG pPrivateDriverData; + UINT PrivateDriverDataSize; + } *allocs32; + struct + { + D3DKMT_HANDLE hDevice; + D3DKMT_HANDLE hGlobalShare; + UINT NumAllocations; + ULONG pOpenAllocationInfo; + ULONG pPrivateRuntimeData; + UINT PrivateRuntimeDataSize; + ULONG pResourcePrivateDriverData; + UINT ResourcePrivateDriverDataSize; + ULONG pTotalPrivateDriverDataBuffer; + UINT TotalPrivateDriverDataBufferSize; + D3DKMT_HANDLE hResource; + } *desc32 = get_ptr( &args ); + D3DKMT_OPENRESOURCE desc; + NTSTATUS status; + UINT i; + + desc.hDevice = desc32->hDevice; + desc.hGlobalShare = desc32->hGlobalShare; + desc.NumAllocations = desc32->NumAllocations; + desc.pOpenAllocationInfo = NULL; + if (desc32->pOpenAllocationInfo && desc32->NumAllocations) + { + if (!(desc.pOpenAllocationInfo = Wow64AllocateTemp( desc32->NumAllocations + sizeof(*desc.pOpenAllocationInfo) ))) + return STATUS_NO_MEMORY; + + allocs32 = UlongToPtr( desc32->pOpenAllocationInfo ); + for (i = 0; i < desc32->NumAllocations; i++) + { + desc.pOpenAllocationInfo[i].hAllocation = allocs32->hAllocation; + desc.pOpenAllocationInfo[i].pPrivateDriverData = UlongToPtr( allocs32->pPrivateDriverData ); + desc.pOpenAllocationInfo[i].PrivateDriverDataSize = allocs32->PrivateDriverDataSize; + } + } + desc.PrivateRuntimeDataSize = desc32->PrivateRuntimeDataSize; + desc.pPrivateRuntimeData = UlongToPtr( desc32->pPrivateRuntimeData ); + desc.ResourcePrivateDriverDataSize = desc32->ResourcePrivateDriverDataSize; + desc.pResourcePrivateDriverData = UlongToPtr( desc32->pResourcePrivateDriverData ); + desc.TotalPrivateDriverDataBufferSize = desc32->TotalPrivateDriverDataBufferSize; + desc.pTotalPrivateDriverDataBuffer = UlongToPtr( desc32->pTotalPrivateDriverDataBuffer ); + + status = NtGdiDdDDIOpenResource( &desc ); + desc32->TotalPrivateDriverDataBufferSize = desc.TotalPrivateDriverDataBufferSize; + desc32->hResource = desc.hResource; + return status; +} + +NTSTATUS WINAPI wow64_NtGdiDdDDIOpenResource2( UINT *args ) +{ + struct + { + D3DKMT_HANDLE hAllocation; + ULONG pPrivateDriverData; + UINT PrivateDriverDataSize; + D3DGPU_VIRTUAL_ADDRESS GpuVirtualAddress; + ULONG Reserved[6]; + } *allocs32 = NULL; + struct + { + D3DKMT_HANDLE hDevice; + D3DKMT_HANDLE hGlobalShare; + UINT NumAllocations; + ULONG pOpenAllocationInfo2; + ULONG pPrivateRuntimeData; + UINT PrivateRuntimeDataSize; + ULONG pResourcePrivateDriverData; + UINT ResourcePrivateDriverDataSize; + ULONG pTotalPrivateDriverDataBuffer; + UINT TotalPrivateDriverDataBufferSize; + D3DKMT_HANDLE hResource; + } *desc32 = get_ptr( &args ); + D3DKMT_OPENRESOURCE desc; + NTSTATUS status; + UINT i; + + desc.hDevice = desc32->hDevice; + desc.hGlobalShare = desc32->hGlobalShare; + desc.NumAllocations = desc32->NumAllocations; + desc.pOpenAllocationInfo2 = NULL; + if (desc32->pOpenAllocationInfo2 && desc32->NumAllocations) + { + if (!(desc.pOpenAllocationInfo2 = Wow64AllocateTemp( desc32->NumAllocations + sizeof(*desc.pOpenAllocationInfo2) ))) + return STATUS_NO_MEMORY; + + allocs32 = UlongToPtr( desc32->pOpenAllocationInfo2 ); + for (i = 0; i < desc32->NumAllocations; i++) + { + desc.pOpenAllocationInfo2[i].hAllocation = allocs32->hAllocation; + desc.pOpenAllocationInfo2[i].pPrivateDriverData = UlongToPtr( allocs32->pPrivateDriverData ); + desc.pOpenAllocationInfo2[i].PrivateDriverDataSize = allocs32->PrivateDriverDataSize; + } + } + desc.PrivateRuntimeDataSize = desc32->PrivateRuntimeDataSize; + desc.pPrivateRuntimeData = UlongToPtr( desc32->pPrivateRuntimeData ); + desc.ResourcePrivateDriverDataSize = desc32->ResourcePrivateDriverDataSize; + desc.pResourcePrivateDriverData = UlongToPtr( desc32->pResourcePrivateDriverData ); + desc.TotalPrivateDriverDataBufferSize = desc32->TotalPrivateDriverDataBufferSize; + desc.pTotalPrivateDriverDataBuffer = UlongToPtr( desc32->pTotalPrivateDriverDataBuffer ); + + status = NtGdiDdDDIOpenResource2( &desc ); + desc32->TotalPrivateDriverDataBufferSize = desc.TotalPrivateDriverDataBufferSize; + desc32->hResource = desc.hResource; + for (i = 0; desc32->pOpenAllocationInfo2 && i < desc32->NumAllocations; i++) + allocs32->GpuVirtualAddress = desc.pOpenAllocationInfo2[i].GpuVirtualAddress; + return status; +} + +NTSTATUS WINAPI wow64_NtGdiDdDDIOpenResourceFromNtHandle( UINT *args ) +{ + struct + { + D3DKMT_HANDLE hAllocation; + ULONG pPrivateDriverData; + UINT PrivateDriverDataSize; + D3DGPU_VIRTUAL_ADDRESS GpuVirtualAddress; + ULONG Reserved[6]; + } *allocs32 = NULL; + struct + { + D3DKMT_HANDLE hDevice; + ULONG hNtHandle; + UINT NumAllocations; + ULONG pOpenAllocationInfo2; + UINT PrivateRuntimeDataSize; + ULONG pPrivateRuntimeData; + UINT ResourcePrivateDriverDataSize; + ULONG pResourcePrivateDriverData; + UINT TotalPrivateDriverDataBufferSize; + ULONG pTotalPrivateDriverDataBuffer; + D3DKMT_HANDLE hResource; + D3DKMT_HANDLE hKeyedMutex; + ULONG pKeyedMutexPrivateRuntimeData; + UINT KeyedMutexPrivateRuntimeDataSize; + D3DKMT_HANDLE hSyncObject; + } *desc32 = get_ptr( &args ); + D3DKMT_OPENRESOURCEFROMNTHANDLE desc; + NTSTATUS status; + UINT i; + + desc.hDevice = desc32->hDevice; + desc.hNtHandle = UlongToHandle( desc32->hNtHandle ); + desc.NumAllocations = desc32->NumAllocations; + desc.pOpenAllocationInfo2 = NULL; + if (desc32->pOpenAllocationInfo2 && desc32->NumAllocations) + { + if (!(desc.pOpenAllocationInfo2 = Wow64AllocateTemp( desc32->NumAllocations + sizeof(*desc.pOpenAllocationInfo2) ))) + return STATUS_NO_MEMORY; + + allocs32 = UlongToPtr( desc32->pOpenAllocationInfo2 ); + for (i = 0; i < desc32->NumAllocations; i++) + { + desc.pOpenAllocationInfo2[i].hAllocation = allocs32->hAllocation; + desc.pOpenAllocationInfo2[i].pPrivateDriverData = UlongToPtr( allocs32->pPrivateDriverData ); + desc.pOpenAllocationInfo2[i].PrivateDriverDataSize = allocs32->PrivateDriverDataSize; + } + } + desc.PrivateRuntimeDataSize = desc32->PrivateRuntimeDataSize; + desc.pPrivateRuntimeData = UlongToPtr( desc32->pPrivateRuntimeData ); + desc.ResourcePrivateDriverDataSize = desc32->ResourcePrivateDriverDataSize; + desc.pResourcePrivateDriverData = UlongToPtr( desc32->pResourcePrivateDriverData ); + desc.TotalPrivateDriverDataBufferSize = desc32->TotalPrivateDriverDataBufferSize; + desc.pTotalPrivateDriverDataBuffer = UlongToPtr( desc32->pTotalPrivateDriverDataBuffer ); + desc.pKeyedMutexPrivateRuntimeData = UlongToPtr( desc32->pKeyedMutexPrivateRuntimeData ); + desc.KeyedMutexPrivateRuntimeDataSize = desc32->KeyedMutexPrivateRuntimeDataSize; + + status = NtGdiDdDDIOpenResourceFromNtHandle( &desc ); + desc32->TotalPrivateDriverDataBufferSize = desc.TotalPrivateDriverDataBufferSize; + desc32->hResource = desc.hResource; + desc32->hKeyedMutex = desc.hKeyedMutex; + desc32->hSyncObject = desc.hSyncObject; + for (i = 0; desc32->pOpenAllocationInfo2 && i < desc32->NumAllocations; i++) + allocs32->GpuVirtualAddress = desc.pOpenAllocationInfo2[i].GpuVirtualAddress; + return status; +} + +NTSTATUS WINAPI wow64_NtGdiDdDDIOpenSyncObjectFromNtHandle( UINT *args ) +{ + struct + { + ULONG hNtHandle; + D3DKMT_HANDLE hSyncObject; + } *desc32 = get_ptr( &args ); + D3DKMT_OPENSYNCOBJECTFROMNTHANDLE desc; + NTSTATUS status; + + desc.hNtHandle = UlongToHandle( desc32->hNtHandle ); + status = NtGdiDdDDIOpenSyncObjectFromNtHandle( &desc ); + desc32->hSyncObject = desc.hSyncObject; + return status; +} + +NTSTATUS WINAPI wow64_NtGdiDdDDIOpenSyncObjectFromNtHandle2( UINT *args ) +{ + struct + { + ULONG hNtHandle; + D3DKMT_HANDLE hDevice; + D3DDDI_SYNCHRONIZATIONOBJECT_FLAGS Flags; + D3DKMT_HANDLE hSyncObject; + union + { + struct + { + ULONG FenceValueCPUVirtualAddress; + D3DGPU_VIRTUAL_ADDRESS FenceValueGPUVirtualAddress; + UINT EngineAffinity; + } MonitoredFence; + UINT64 Reserved[8]; + }; + } *desc32 = get_ptr( &args ); + D3DKMT_OPENSYNCOBJECTFROMNTHANDLE2 desc; + NTSTATUS status; + + desc.hNtHandle = ULongToHandle( desc32->hNtHandle ); + desc.hDevice = desc32->hDevice; + desc.Flags = desc32->Flags; + desc.MonitoredFence.EngineAffinity = desc32->MonitoredFence.EngineAffinity; + + status = NtGdiDdDDIOpenSyncObjectFromNtHandle2( &desc ); + desc32->MonitoredFence.FenceValueCPUVirtualAddress = PtrToUlong( desc.MonitoredFence.FenceValueCPUVirtualAddress ); + desc32->MonitoredFence.FenceValueGPUVirtualAddress = desc.MonitoredFence.FenceValueGPUVirtualAddress; + desc32->hSyncObject = desc.hSyncObject; + return status; +} + +NTSTATUS WINAPI wow64_NtGdiDdDDIOpenSyncObjectNtHandleFromName( UINT *args ) +{ + struct + { + DWORD dwDesiredAccess; + ULONG pObjAttrib; + ULONG hNtHandle; + } *desc32 = get_ptr( &args ); + D3DKMT_OPENSYNCOBJECTNTHANDLEFROMNAME desc; + struct object_attr64 attr; + NTSTATUS status; + + desc.dwDesiredAccess = desc32->dwDesiredAccess; + desc.pObjAttrib = objattr_32to64( &attr, UlongToPtr( desc32->pObjAttrib ) ); + status = NtGdiDdDDIOpenSyncObjectNtHandleFromName( &desc ); + desc32->hNtHandle = HandleToUlong( desc.hNtHandle ); + return status; +} + +NTSTATUS WINAPI wow64_NtGdiDdDDIOpenSynchronizationObject( UINT *args ) +{ + D3DKMT_OPENSYNCHRONIZATIONOBJECT *desc = get_ptr( &args ); + return NtGdiDdDDIOpenSynchronizationObject( desc ); +} + +NTSTATUS WINAPI wow64_NtGdiDdDDIQueryAdapterInfo( UINT *args ) +{ + struct _D3DKMT_QUERYADAPTERINFO + { + D3DKMT_HANDLE hAdapter; + KMTQUERYADAPTERINFOTYPE Type; + ULONG pPrivateDriverData; + UINT PrivateDriverDataSize; + } *desc32 = get_ptr( &args ); + D3DKMT_QUERYADAPTERINFO desc; + + if (!desc32) return STATUS_INVALID_PARAMETER; + + desc.hAdapter = desc32->hAdapter; + desc.Type = desc32->Type; + desc.pPrivateDriverData = UlongToPtr( desc32->pPrivateDriverData ); + desc.PrivateDriverDataSize = desc32->PrivateDriverDataSize; + + return NtGdiDdDDIQueryAdapterInfo( &desc ); +} + +NTSTATUS WINAPI wow64_NtGdiDdDDIQueryResourceInfo( UINT *args ) +{ + struct + { + D3DKMT_HANDLE hDevice; + D3DKMT_HANDLE hGlobalShare; + ULONG pPrivateRuntimeData; + UINT PrivateRuntimeDataSize; + UINT TotalPrivateDriverDataSize; + UINT ResourcePrivateDriverDataSize; + UINT NumAllocations; + } *desc32 = get_ptr( &args ); + D3DKMT_QUERYRESOURCEINFO desc; + NTSTATUS status; + + desc.hDevice = desc32->hDevice; + desc.hGlobalShare = desc32->hGlobalShare; + desc.pPrivateRuntimeData = UlongToPtr( desc32->pPrivateRuntimeData ); + desc.PrivateRuntimeDataSize = desc32->PrivateRuntimeDataSize; + status = NtGdiDdDDIQueryResourceInfo( &desc ); + desc32->PrivateRuntimeDataSize = desc.PrivateRuntimeDataSize; + desc32->TotalPrivateDriverDataSize = desc.TotalPrivateDriverDataSize; + desc32->ResourcePrivateDriverDataSize = desc.ResourcePrivateDriverDataSize; + desc32->NumAllocations = desc.NumAllocations; + return status; +} + +NTSTATUS WINAPI wow64_NtGdiDdDDIQueryResourceInfoFromNtHandle( UINT *args ) +{ + struct + { + D3DKMT_HANDLE hDevice; + ULONG hNtHandle; + ULONG pPrivateRuntimeData; + UINT PrivateRuntimeDataSize; + UINT TotalPrivateDriverDataSize; + UINT ResourcePrivateDriverDataSize; + UINT NumAllocations; + } *desc32 = get_ptr( &args ); + D3DKMT_QUERYRESOURCEINFOFROMNTHANDLE desc; + NTSTATUS status; + + desc.hDevice = desc32->hDevice; + desc.hNtHandle = UlongToHandle( desc32->hNtHandle ); + desc.pPrivateRuntimeData = UlongToPtr( desc32->pPrivateRuntimeData ); + desc.PrivateRuntimeDataSize = desc32->PrivateRuntimeDataSize; + status = NtGdiDdDDIQueryResourceInfoFromNtHandle( &desc ); + desc32->PrivateRuntimeDataSize = desc.PrivateRuntimeDataSize; + desc32->TotalPrivateDriverDataSize = desc.TotalPrivateDriverDataSize; + desc32->ResourcePrivateDriverDataSize = desc.ResourcePrivateDriverDataSize; + desc32->NumAllocations = desc.NumAllocations; + return status; +} + +NTSTATUS WINAPI wow64_NtGdiDdDDIQueryStatistics( UINT *args ) +{ + D3DKMT_QUERYSTATISTICS *stats = get_ptr( &args ); + + return NtGdiDdDDIQueryStatistics( stats ); +} + +NTSTATUS WINAPI wow64_NtGdiDdDDIQueryVideoMemoryInfo( UINT *args ) +{ + struct _D3DKMT_QUERYVIDEOMEMORYINFO + { + ULONG hProcess; + D3DKMT_HANDLE hAdapter; + D3DKMT_MEMORY_SEGMENT_GROUP MemorySegmentGroup; + UINT64 Budget; + UINT64 CurrentUsage; + UINT64 CurrentReservation; + UINT64 AvailableForReservation; + UINT PhysicalAdapterIndex; + } *desc32 = get_ptr( &args ); + D3DKMT_QUERYVIDEOMEMORYINFO desc; + NTSTATUS status; + + if (!desc32) return STATUS_INVALID_PARAMETER; + desc.hProcess = LongToHandle( desc32->hProcess ); + desc.hAdapter = desc32->hAdapter; + desc.MemorySegmentGroup = desc32->MemorySegmentGroup; + desc.PhysicalAdapterIndex = desc32->PhysicalAdapterIndex; + + if (!(status = NtGdiDdDDIQueryVideoMemoryInfo( &desc ))) + { + desc32->Budget = desc.Budget; + desc32->CurrentUsage = desc.CurrentUsage; + desc32->CurrentReservation = desc.CurrentReservation; + desc32->AvailableForReservation = desc.AvailableForReservation; + } + return status; +} + +NTSTATUS WINAPI wow64_NtGdiDdDDISetQueuedLimit( UINT *args ) +{ + D3DKMT_SETQUEUEDLIMIT *desc = get_ptr( &args ); + + return NtGdiDdDDISetQueuedLimit( desc ); +} + +NTSTATUS WINAPI wow64_NtGdiDdDDISetVidPnSourceOwner( UINT *args ) +{ + const struct + { + D3DKMT_HANDLE hDevice; + ULONG pType; + ULONG pVidPnSourceId; + UINT VidPnSourceCount; + } *desc32 = get_ptr( &args ); + D3DKMT_SETVIDPNSOURCEOWNER desc; + + if (!desc32) return STATUS_INVALID_PARAMETER; + desc.hDevice = desc32->hDevice; + desc.pType = UlongToPtr( desc32->pType ); + desc.pVidPnSourceId = UlongToPtr( desc32->pVidPnSourceId ); + desc.VidPnSourceCount = desc32->VidPnSourceCount; + + return NtGdiDdDDISetVidPnSourceOwner( &desc ); +} + +NTSTATUS WINAPI wow64_NtGdiDdDDIShareObjects( UINT *args ) +{ + UINT count = get_ulong( &args ); + D3DKMT_HANDLE *handles = get_ptr( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + UINT access = get_ulong( &args ); + ULONG *handle_ptr = get_ptr( &args ); + + struct object_attr64 attr; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtGdiDdDDIShareObjects( count, handles, objattr_32to64( &attr, attr32 ), access, &handle ); + *handle_ptr = HandleToULong( handle ); + return status; +} +#endif + +NTSTATUS WINAPI wow64_NtGdiDeleteClientObj( UINT *args ) +{ + HGDIOBJ obj = get_handle( &args ); + + return NtGdiDeleteClientObj( obj ); +} + +NTSTATUS WINAPI wow64_NtGdiDeleteObjectApp( UINT *args ) +{ + HGDIOBJ obj = get_handle( &args ); + + return NtGdiDeleteObjectApp( obj ); +} + +NTSTATUS WINAPI wow64_NtGdiDescribePixelFormat( UINT *args ) +{ + HDC hdc = get_handle( &args ); + INT format = get_ulong( &args ); + UINT size = get_ulong( &args ); + PIXELFORMATDESCRIPTOR *descr = get_ptr( &args ); + + return NtGdiDescribePixelFormat( hdc, format, size, descr ); +} + +NTSTATUS WINAPI wow64_NtGdiDoPalette( UINT *args ) +{ + HGDIOBJ handle = get_handle( &args ); + WORD start = get_ulong( &args ); + WORD count = get_ulong( &args ); + void *entries = get_ptr( &args ); + DWORD func = get_ulong( &args ); + BOOL inbound = get_ulong( &args ); + + return NtGdiDoPalette( handle, start, count, entries, func, inbound ); +} + +NTSTATUS WINAPI wow64_NtGdiDrawStream( UINT *args ) +{ + HDC hdc = get_handle( &args ); + ULONG in = get_ulong( &args ); + void *pvin = get_ptr( &args ); + + return NtGdiDrawStream( hdc, in, pvin ); +} + +NTSTATUS WINAPI wow64_NtGdiEllipse( UINT *args ) +{ + HDC hdc = get_handle( &args ); + INT left = get_ulong( &args ); + INT top = get_ulong( &args ); + INT right = get_ulong( &args ); + INT bottom = get_ulong( &args ); + + return NtGdiEllipse( hdc, left, top, right, bottom ); +} + +NTSTATUS WINAPI wow64_NtGdiEndDoc( UINT *args ) +{ + HDC hdc = get_handle( &args ); + + return NtGdiEndDoc( hdc ); +} + +NTSTATUS WINAPI wow64_NtGdiEndPage( UINT *args ) +{ + HDC hdc = get_handle( &args ); + + return NtGdiEndPage( hdc ); +} + +NTSTATUS WINAPI wow64_NtGdiEndPath( UINT *args ) +{ + HDC hdc = get_handle( &args ); + + return NtGdiEndPath( hdc ); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtGdiEnumFonts( UINT *args ) +{ + HDC hdc = get_handle( &args ); + ULONG type = get_ulong( &args ); + ULONG win32_compat = get_ulong( &args ); + ULONG face_name_len = get_ulong( &args ); + const WCHAR *face_name = get_ptr( &args ); + ULONG charset = get_ulong( &args ); + ULONG *count = get_ptr( &args ); + void *buf = get_ptr( &args ); + + return NtGdiEnumFonts( hdc, type, win32_compat, face_name_len, face_name, charset, count, buf ); +} +#endif + +NTSTATUS WINAPI wow64_NtGdiExcludeClipRect( UINT *args ) +{ + HDC hdc = get_handle( &args ); + INT left = get_ulong( &args ); + INT top = get_ulong( &args ); + INT right = get_ulong( &args ); + INT bottom = get_ulong( &args ); + + return NtGdiExcludeClipRect( hdc, left, top, right, bottom ); +} + +NTSTATUS WINAPI wow64_NtGdiEqualRgn( UINT *args ) +{ + HRGN hrgn1 = get_handle( &args ); + HRGN hrgn2 = get_handle( &args ); + + return NtGdiEqualRgn( hrgn1, hrgn2 ); +} + +NTSTATUS WINAPI wow64_NtGdiExtCreatePen( UINT *args ) +{ + DWORD style = get_ulong( &args ); + DWORD width = get_ulong( &args ); + ULONG brush_style = get_ulong( &args ); + ULONG color = get_ulong( &args ); + ULONG_PTR client_hatch = get_ulong( &args ); + ULONG_PTR hatch = get_ulong( &args ); + DWORD style_count = get_ulong( &args ); + const DWORD *style_bits = get_ptr( &args ); + ULONG dib_size = get_ulong( &args ); + BOOL old_style = get_ulong( &args ); + HBRUSH brush = get_handle( &args ); + + return HandleToUlong( NtGdiExtCreatePen( style, width, brush_style, color, client_hatch, + hatch, style_count, style_bits, dib_size, + old_style, brush )); +} + +NTSTATUS WINAPI wow64_NtGdiExtCreateRegion( UINT *args ) +{ + const XFORM *xform = get_ptr( &args ); + DWORD count = get_ulong( &args ); + const RGNDATA *data = get_ptr( &args ); + + return HandleToUlong( NtGdiExtCreateRegion( xform, count, data )); +} + +NTSTATUS WINAPI wow64_NtGdiExtEscape( UINT *args ) +{ + HDC hdc = get_handle( &args ); + WCHAR *driver = get_ptr( &args ); + INT driver_id = get_ulong( &args ); + INT escape = get_ulong( &args ); + INT input_size = get_ulong( &args ); + const char *input = get_ptr( &args ); + INT output_size = get_ulong( &args ); + char *output = get_ptr( &args ); + + return NtGdiExtEscape( hdc, driver, driver_id, escape, input_size, input, output_size, output ); +} + +NTSTATUS WINAPI wow64_NtGdiExtFloodFill( UINT *args ) +{ + HDC hdc = get_handle( &args ); + INT x = get_ulong( &args ); + INT y = get_ulong( &args ); + COLORREF color = get_ulong( &args ); + UINT type = get_ulong( &args ); + + return NtGdiExtFloodFill( hdc, x, y, color, type ); +} + +NTSTATUS WINAPI wow64_NtGdiExtGetObjectW( UINT *args ) +{ + HGDIOBJ handle = get_handle( &args ); + INT count = get_ulong( &args ); + void *buffer = get_ptr( &args ); + + switch (gdi_handle_type( handle )) + { + case NTGDI_OBJ_BITMAP: + { + BITMAP32 *bitmap32 = buffer; + struct + { + BITMAP32 dsBm; + BITMAPINFOHEADER dsBmih; + DWORD dsBitfields[3]; + ULONG dshSection; + DWORD dsOffset; + } *dib32 = buffer; + DIBSECTION dib; + int ret; + + if (buffer) + { + if (count < sizeof(*bitmap32)) return 0; + count = count < sizeof(*dib32) ? sizeof(BITMAP) : sizeof(DIBSECTION); + } + + if (!(ret = NtGdiExtGetObjectW( handle, count, buffer ? &dib : NULL ))) return 0; + + if (bitmap32) + { + bitmap32->bmType = dib.dsBm.bmType; + bitmap32->bmWidth = dib.dsBm.bmWidth; + bitmap32->bmHeight = dib.dsBm.bmHeight; + bitmap32->bmWidthBytes = dib.dsBm.bmWidthBytes; + bitmap32->bmPlanes = dib.dsBm.bmPlanes; + bitmap32->bmBitsPixel = dib.dsBm.bmBitsPixel; + bitmap32->bmBits = PtrToUlong( dib.dsBm.bmBits ); + } + if (ret != sizeof(dib)) return sizeof(*bitmap32); + + if (dib32) + { + dib32->dsBmih = dib.dsBmih; + dib32->dsBitfields[0] = dib.dsBitfields[0]; + dib32->dsBitfields[1] = dib.dsBitfields[1]; + dib32->dsBitfields[2] = dib.dsBitfields[2]; + dib32->dshSection = HandleToUlong( dib.dshSection ); + dib32->dsOffset = dib.dsOffset; + } + return sizeof(*dib32); + } + + case NTGDI_OBJ_PEN: + case NTGDI_OBJ_EXTPEN: + { + EXTLOGPEN32 *pen32 = buffer; + EXTLOGPEN *pen = NULL; + + if (count == sizeof(LOGPEN) || (buffer && !HIWORD( buffer ))) + return NtGdiExtGetObjectW( handle, count, buffer ); + + if (pen32 && count && !(pen = Wow64AllocateTemp( count + sizeof(ULONG) ))) return 0; + count = NtGdiExtGetObjectW( handle, count + sizeof(ULONG), pen ); + + if (count == sizeof(LOGPEN)) + { + if (buffer) memcpy( buffer, pen, count ); + } + else if (count) + { + if (pen32) + { + pen32->elpPenStyle = pen->elpPenStyle; + pen32->elpWidth = pen->elpWidth; + pen32->elpBrushStyle = pen->elpBrushStyle; + pen32->elpColor = pen->elpColor; + pen32->elpHatch = pen->elpHatch; + pen32->elpNumEntries = pen->elpNumEntries; + } + count -= FIELD_OFFSET( EXTLOGPEN, elpStyleEntry ); + if (count && pen32) memcpy( pen32->elpStyleEntry, pen->elpStyleEntry, count ); + count += FIELD_OFFSET( EXTLOGPEN32, elpStyleEntry ); + } + return count; + } + + default: + return NtGdiExtGetObjectW( handle, count, buffer ); + } +} + +NTSTATUS WINAPI wow64_NtGdiExtSelectClipRgn( UINT *args ) +{ + HDC hdc = get_handle( &args ); + HRGN region = get_handle( &args ); + INT mode = get_ulong( &args ); + + return NtGdiExtSelectClipRgn( hdc, region, mode ); +} + +NTSTATUS WINAPI wow64_NtGdiExtTextOutW( UINT *args ) +{ + HDC hdc = get_handle( &args ); + INT x = get_ulong( &args ); + INT y = get_ulong( &args ); + UINT flags = get_ulong( &args ); + const RECT *rect = get_ptr( &args ); + const WCHAR *str = get_ptr( &args ); + UINT count = get_ulong( &args ); + const INT *dx = get_ptr( &args ); + DWORD cp = get_ulong( &args ); + + return NtGdiExtTextOutW( hdc, x, y, flags, rect, str, count, dx, cp ); +} + +NTSTATUS WINAPI wow64_NtGdiFillPath( UINT *args ) +{ + HDC hdc = get_handle( &args ); + + return NtGdiFillPath( hdc ); +} + +NTSTATUS WINAPI wow64_NtGdiFillRgn( UINT *args ) +{ + HDC hdc = get_handle( &args ); + HRGN hrgn = get_handle( &args ); + HBRUSH hbrush = get_handle( &args ); + + return NtGdiFillRgn( hdc, hrgn, hbrush ); +} + +NTSTATUS WINAPI wow64_NtGdiFlattenPath( UINT *args ) +{ + HDC hdc = get_handle( &args ); + + return NtGdiFlattenPath( hdc ); +} + +NTSTATUS WINAPI wow64_NtGdiFlush( UINT *args ) +{ + return NtGdiFlush(); +} + +NTSTATUS WINAPI wow64_NtGdiFontIsLinked( UINT *args ) +{ + HDC hdc = get_handle( &args ); + + return NtGdiFontIsLinked( hdc ); +} + +NTSTATUS WINAPI wow64_NtGdiFrameRgn( UINT *args ) +{ + HDC hdc = get_handle( &args ); + HRGN hrgn = get_handle( &args ); + HBRUSH brush = get_handle( &args ); + INT width = get_ulong( &args ); + INT height = get_ulong( &args ); + + return NtGdiFrameRgn( hdc, hrgn, brush, width, height ); +} + +NTSTATUS WINAPI wow64_NtGdiGetAndSetDCDword( UINT *args ) +{ + HDC hdc = get_handle( &args ); + UINT method = get_ulong( &args ); + DWORD value = get_ulong( &args ); + DWORD *result = get_ptr( &args ); + + return NtGdiGetAndSetDCDword( hdc, method, value, result ); +} + +NTSTATUS WINAPI wow64_NtGdiGetAppClipBox( UINT *args ) +{ + HDC hdc = get_handle( &args ); + RECT *rect = get_ptr( &args ); + + return NtGdiGetAppClipBox( hdc, rect ); +} + +NTSTATUS WINAPI wow64_NtGdiGetBitmapBits( UINT *args ) +{ + HBITMAP bitmap = get_handle( &args ); + LONG count = get_ulong( &args ); + void *bits = get_ptr( &args ); + + return NtGdiGetBitmapBits( bitmap, count, bits ); +} + +NTSTATUS WINAPI wow64_NtGdiGetBitmapDimension( UINT *args ) +{ + HBITMAP bitmap = get_handle( &args ); + SIZE *size = get_ptr( &args ); + + return NtGdiGetBitmapDimension( bitmap, size ); +} + +NTSTATUS WINAPI wow64_NtGdiGetBoundsRect( UINT *args ) +{ + HDC hdc = get_handle( &args ); + RECT *rect = get_ptr( &args ); + UINT flags = get_ulong( &args ); + + return NtGdiGetBoundsRect( hdc, rect, flags ); +} + +NTSTATUS WINAPI wow64_NtGdiGetCharABCWidthsW( UINT *args ) +{ + HDC hdc = get_handle( &args ); + UINT first = get_ulong( &args ); + UINT last = get_ulong( &args ); + WCHAR *chars = get_ptr( &args ); + ULONG flags = get_ulong( &args ); + void *buffer = get_ptr( &args ); + + return NtGdiGetCharABCWidthsW( hdc, first, last, chars, flags, buffer ); +} + +NTSTATUS WINAPI wow64_NtGdiGetCharWidthW( UINT *args ) +{ + HDC hdc = get_handle( &args ); + UINT first_char = get_ulong( &args ); + UINT last_char = get_ulong( &args ); + WCHAR *chars = get_ptr( &args ); + ULONG flags = get_ulong( &args ); + void *buffer = get_ptr( &args ); + + return NtGdiGetCharWidthW( hdc, first_char, last_char, chars, flags, buffer ); +} + +NTSTATUS WINAPI wow64_NtGdiGetCharWidthInfo( UINT *args ) +{ + HDC hdc = get_handle( &args ); +#ifndef __REACTOS__ + struct char_width_info *info = get_ptr( &args ); +#else + PCHWIDTHINFO info = get_ptr( &args ); +#endif + + return NtGdiGetCharWidthInfo( hdc, info ); +} + +NTSTATUS WINAPI wow64_NtGdiGetColorAdjustment( UINT *args ) +{ + HDC hdc = get_handle( &args ); + COLORADJUSTMENT *ca = get_ptr( &args ); + + return NtGdiGetColorAdjustment( hdc, ca ); +} + +NTSTATUS WINAPI wow64_NtGdiGetDCDword( UINT *args ) +{ + HDC hdc = get_handle( &args ); + UINT method = get_ulong( &args ); + DWORD *result = get_ptr( &args ); + + return NtGdiGetDCDword( hdc, method, result ); +} + +NTSTATUS WINAPI wow64_NtGdiGetDCObject( UINT *args ) +{ + HDC hdc = get_handle( &args ); + UINT type = get_ulong( &args ); + + return HandleToUlong( NtGdiGetDCObject( hdc, type )); +} + +NTSTATUS WINAPI wow64_NtGdiGetDCPoint( UINT *args ) +{ + HDC hdc = get_handle( &args ); + UINT method = get_ulong( &args ); +#ifndef __REACTOS__ + POINT *result = get_ptr( &args ); +#else + PPOINTL result = get_ptr( &args ); +#endif + + return NtGdiGetDCPoint( hdc, method, result ); +} + +NTSTATUS WINAPI wow64_NtGdiGetDIBitsInternal( UINT *args ) +{ + HDC hdc = get_handle( &args ); + HBITMAP hbitmap = get_handle( &args ); + UINT startscan = get_ulong( &args ); + UINT lines = get_ulong( &args ); + void *bits = get_ptr( &args ); + BITMAPINFO *info = get_ptr( &args ); + UINT coloruse = get_ulong( &args ); + UINT max_bits = get_ulong( &args ); + UINT max_info = get_ulong( &args ); + + return NtGdiGetDIBitsInternal( hdc, hbitmap, startscan, lines, bits, info, coloruse, + max_bits, max_info ); +} + +NTSTATUS WINAPI wow64_NtGdiGetDeviceCaps( UINT *args ) +{ + HDC hdc = get_handle( &args ); + INT cap = get_ulong( &args ); + + return NtGdiGetDeviceCaps( hdc, cap ); +} + +NTSTATUS WINAPI wow64_NtGdiGetDeviceGammaRamp( UINT *args ) +{ + HDC hdc = get_handle( &args ); + void *ptr = get_ptr( &args ); + + return NtGdiGetDeviceGammaRamp( hdc, ptr ); +} + +NTSTATUS WINAPI wow64_NtGdiGetFontData( UINT *args ) +{ + HDC hdc = get_handle( &args ); + DWORD table = get_ulong( &args ); + DWORD offset = get_ulong( &args ); + void *buffer = get_ptr( &args ); + DWORD length = get_ulong( &args ); + + return NtGdiGetFontData( hdc, table, offset, buffer, length ); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtGdiGetFontFileData( UINT *args ) +{ + DWORD instance_id = get_ulong( &args ); + DWORD file_index = get_ulong( &args ); + UINT64 *offset = get_ptr( &args ); + void *buff = get_ptr( &args ); + SIZE_T buff_size = get_ulong( &args ); + + return NtGdiGetFontFileData( instance_id, file_index, offset, buff, buff_size ); +} + +NTSTATUS WINAPI wow64_NtGdiGetFontFileInfo( UINT *args ) +{ + DWORD instance_id = get_ulong( &args ); + DWORD file_index = get_ulong( &args ); + struct font_fileinfo *info = get_ptr( &args ); + SIZE_T size = get_ulong( &args ); + ULONG *needed32 = get_ptr( &args ); + + SIZE_T needed; + BOOL ret; + + ret = NtGdiGetFontFileInfo( instance_id, file_index, info, size, size_32to64( &needed, needed32 )); + put_size( needed32, needed ); + return ret; +} +#endif + +NTSTATUS WINAPI wow64_NtGdiGetFontUnicodeRanges( UINT *args ) +{ + HDC hdc = get_handle( &args ); + GLYPHSET *lpgs = get_ptr( &args ); + + return NtGdiGetFontUnicodeRanges( hdc, lpgs ); +} + +NTSTATUS WINAPI wow64_NtGdiGetGlyphIndicesW( UINT *args ) +{ + HDC hdc = get_handle( &args ); + const WCHAR *str = get_ptr( &args ); + INT count = get_ulong( &args ); + WORD *indices = get_ptr( &args ); + DWORD flags = get_ulong( &args ); + + return NtGdiGetGlyphIndicesW( hdc, str, count, indices, flags ); +} + +NTSTATUS WINAPI wow64_NtGdiGetGlyphOutline( UINT *args ) +{ + HDC hdc = get_handle( &args ); + UINT ch = get_ulong( &args ); + UINT format = get_ulong( &args ); + GLYPHMETRICS *metrics = get_ptr( &args ); + DWORD size = get_ulong( &args ); + void *buffer = get_ptr( &args ); + const MAT2 *mat2 = get_ptr( &args ); + BOOL ignore_rotation = get_ulong( &args ); + + return NtGdiGetGlyphOutline( hdc, ch, format, metrics, size, buffer, mat2, ignore_rotation ); +} + +NTSTATUS WINAPI wow64_NtGdiGetKerningPairs( UINT *args ) +{ + HDC hdc = get_handle( &args ); + DWORD count = get_ulong( &args ); + KERNINGPAIR *kern_pair = get_ptr( &args ); + + return NtGdiGetKerningPairs( hdc, count, kern_pair ); +} + +NTSTATUS WINAPI wow64_NtGdiGetNearestColor( UINT *args ) +{ + HDC hdc = get_handle( &args ); + COLORREF color = get_ulong( &args ); + + return NtGdiGetNearestColor( hdc, color ); +} + +NTSTATUS WINAPI wow64_NtGdiGetNearestPaletteIndex( UINT *args ) +{ + HPALETTE hpalette = get_handle( &args ); + COLORREF color = get_ulong( &args ); + + return NtGdiGetNearestPaletteIndex( hpalette, color ); +} + +NTSTATUS WINAPI wow64_NtGdiGetOutlineTextMetricsInternalW( UINT *args ) +{ + HDC hdc = get_handle( &args ); + UINT size = get_ulong( &args ); + OUTLINETEXTMETRIC32 *otm32 = get_ptr( &args ); +#ifndef __REACTOS__ + ULONG opts = get_ulong( &args ); +#else + TMDIFF * opts = get_ptr( &args ); +#endif + + OUTLINETEXTMETRICW *otm, otm_buf; + UINT ret, size64; + static const size_t otm_size_diff = sizeof(*otm) - sizeof(*otm32); + + if (!otm32) + { + size64 = 0; + otm = NULL; + } + else if (size <= sizeof(*otm32)) + { + size64 = sizeof(otm_buf); + otm = &otm_buf; + } + else + { + size64 = size + otm_size_diff; + if (!(otm = Wow64AllocateTemp( size64 ))) return 0; + } + + if (!(ret = NtGdiGetOutlineTextMetricsInternalW( hdc, size64, otm, opts ))) return 0; + + if (otm32) + { + OUTLINETEXTMETRIC32 out; + + memcpy( &out, otm, FIELD_OFFSET( OUTLINETEXTMETRIC32, otmpFamilyName )); + if (out.otmSize >= sizeof(*otm)) out.otmSize -= otm_size_diff; + + if (!otm->otmpFamilyName) out.otmpFamilyName = 0; + else out.otmpFamilyName = PtrToUlong( otm->otmpFamilyName ) - otm_size_diff; + + if (!otm->otmpFaceName) out.otmpFaceName = 0; + else out.otmpFaceName = PtrToUlong( otm->otmpFaceName ) - otm_size_diff; + + if (!otm->otmpStyleName) out.otmpStyleName = 0; + else out.otmpStyleName = PtrToUlong( otm->otmpStyleName ) - otm_size_diff; + + if (!otm->otmpFullName) out.otmpFullName = 0; + else out.otmpFullName = PtrToUlong( otm->otmpFullName ) - otm_size_diff; + + memcpy( otm32, &out, min( size, sizeof(out) )); + if (ret > sizeof(*otm)) memcpy( otm32 + 1, otm + 1, ret - sizeof(*otm) ); + } + + return ret >= sizeof(*otm) ? ret - otm_size_diff : ret; +} + +NTSTATUS WINAPI wow64_NtGdiGetPath( UINT *args ) +{ + HDC hdc = get_handle( &args ); + POINT *points = get_ptr( &args ); + BYTE *types = get_ptr( &args ); + INT size = get_ulong( &args ); + + return NtGdiGetPath( hdc, points, types, size ); +} + +NTSTATUS WINAPI wow64_NtGdiGetPixel( UINT *args ) +{ + HDC hdc = get_handle( &args ); + INT x = get_ulong( &args ); + INT y = get_ulong( &args ); + + return NtGdiGetPixel( hdc, x, y ); +} + +NTSTATUS WINAPI wow64_NtGdiGetRandomRgn( UINT *args ) +{ + HDC hdc = get_handle( &args ); + HRGN region = get_handle( &args ); + INT code = get_ulong( &args ); + + return NtGdiGetRandomRgn( hdc, region, code ); +} + +NTSTATUS WINAPI wow64_NtGdiGetRasterizerCaps( UINT *args ) +{ + RASTERIZER_STATUS *status = get_ptr( &args ); + UINT size = get_ulong( &args ); + + return NtGdiGetRasterizerCaps( status, size ); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtGdiGetRealizationInfo( UINT *args ) +{ + HDC hdc = get_handle( &args ); + struct font_realization_info *info = get_ptr( &args ); + + return NtGdiGetRealizationInfo( hdc, info ); +} +#endif + +NTSTATUS WINAPI wow64_NtGdiGetRegionData( UINT *args ) +{ + HRGN hrgn = get_ptr( &args ); + DWORD count = get_ulong( &args ); + RGNDATA *data = get_ptr( &args ); + + return NtGdiGetRegionData( hrgn, count, data ); +} + +NTSTATUS WINAPI wow64_NtGdiGetTextCharsetInfo( UINT *args ) +{ + HDC hdc = get_ptr( &args ); + FONTSIGNATURE *fs = get_ptr( &args ); + DWORD flags = get_ulong( &args ); + + return NtGdiGetTextCharsetInfo( hdc, fs, flags ); +} + +NTSTATUS WINAPI wow64_NtGdiGetTextExtentExW( UINT *args ) +{ + HDC hdc = get_handle( &args ); + const WCHAR *str = get_ptr( &args ); + INT count = get_ulong( &args ); + INT max_ext = get_ulong( &args ); + INT *nfit = get_ptr( &args ); + INT *dxs = get_ptr( &args ); + SIZE *size = get_ptr( &args ); + UINT flags = get_ulong( &args ); + + return NtGdiGetTextExtentExW( hdc, str, count, max_ext, nfit, dxs, size, flags ); +} + +#ifdef __REACTOS__ + +BOOL +WINAPI +wow64_NtGdiGetTextExtent(UINT *args) +{ + HDC hdc = get_handle(&args); + const WCHAR *str = get_ptr(&args); + INT count = get_ulong(&args); + SIZE *size = get_ptr(&args); + UINT flags = get_ulong(&args); + + return NtGdiGetTextExtent(hdc, str, count, size, flags); +} + +#endif + +NTSTATUS WINAPI wow64_NtGdiGetTextFaceW( UINT *args ) +{ + HDC hdc = get_handle( &args ); + INT count = get_ulong( &args ); + WCHAR *name = get_ptr( &args ); + BOOL alias_name = get_ulong( &args ); + + return NtGdiGetTextFaceW( hdc, count, name, alias_name ); +} + +NTSTATUS WINAPI wow64_NtGdiGetTextMetricsW( UINT *args ) +{ + HDC hdc = get_handle( &args ); +#ifndef __REACTOS__ + TEXTMETRICW *metrics = get_ptr( &args ); +#else + TMW_INTERNAL *metrics = get_ptr( &args ); +#endif + ULONG flags = get_ulong( &args ); + + return NtGdiGetTextMetricsW( hdc, metrics, flags ); +} + +NTSTATUS WINAPI wow64_NtGdiGradientFill( UINT *args ) +{ + HDC hdc = get_handle( &args ); + TRIVERTEX *vert_array = get_ptr( &args ); + ULONG nvert = get_ulong( &args ); + void *grad_array = get_ptr( &args ); + ULONG ngrad = get_ulong( &args ); + ULONG mode = get_ulong( &args ); + + return NtGdiGradientFill( hdc, vert_array, nvert, grad_array, ngrad, mode ); +} + +NTSTATUS WINAPI wow64_NtGdiIcmBrushInfo( UINT *args ) +{ + HDC hdc = get_handle( &args ); + HBRUSH handle = get_handle( &args ); + BITMAPINFO *info = get_ptr( &args ); + void *bits = get_ptr( &args ); + ULONG *bits_size = get_ptr( &args ); + UINT *usage = get_ptr( &args ); + BOOL *unk = get_ptr( &args ); + UINT mode = get_ulong( &args ); + + return NtGdiIcmBrushInfo( hdc, handle, info, bits, bits_size, usage, unk, mode ); +} + +NTSTATUS WINAPI wow64_NtGdiInvertRgn( UINT *args ) +{ + HDC hdc = get_handle( &args ); + HRGN hrgn = get_handle( &args ); + + return NtGdiInvertRgn( hdc, hrgn ); +} + +NTSTATUS WINAPI wow64_NtGdiLineTo( UINT *args ) +{ + HDC hdc = get_handle( &args ); + INT x = get_ulong( &args ); + INT y = get_ulong( &args ); + + return NtGdiLineTo( hdc, x, y ); +} + +NTSTATUS WINAPI wow64_NtGdiMaskBlt( UINT *args ) +{ + HDC hdc = get_handle( &args ); + INT x_dst = get_ulong( &args ); + INT y_dst = get_ulong( &args ); + INT width_dst = get_ulong( &args ); + INT height_dst = get_ulong( &args ); + HDC hdc_src = get_handle( &args ); + INT x_src = get_ulong( &args ); + INT y_src = get_ulong( &args ); + HBITMAP mask = get_handle( &args ); + INT x_mask = get_ulong( &args ); + INT y_mask = get_ulong( &args ); + DWORD rop = get_ulong( &args ); + DWORD bk_color = get_ulong( &args ); + + return NtGdiMaskBlt( hdc, x_dst, y_dst, width_dst, height_dst, hdc_src, + x_src, y_src, mask, x_mask, y_mask, rop, bk_color ); +} + +NTSTATUS WINAPI wow64_NtGdiModifyWorldTransform( UINT *args ) +{ + HDC hdc = get_handle( &args ); + const XFORM *xform = get_ptr( &args ); + DWORD mode = get_ulong( &args ); + + return NtGdiModifyWorldTransform( hdc, xform, mode ); +} + +NTSTATUS WINAPI wow64_NtGdiMoveTo( UINT *args ) +{ + HDC hdc = get_handle( &args ); + INT x = get_ulong( &args ); + INT y = get_ulong( &args ); + POINT *pt = get_ptr( &args ); + + return NtGdiMoveTo( hdc, x, y, pt ); +} + +NTSTATUS WINAPI wow64_NtGdiPolyDraw( UINT *args ) +{ + HDC hdc = get_handle( &args ); + const POINT *points = get_ptr( &args ); + const BYTE *types = get_ptr( &args ); + DWORD count = get_ulong( &args ); + + return NtGdiPolyDraw( hdc, points, types, count ); +} + +NTSTATUS WINAPI wow64_NtGdiPolyPolyDraw( UINT *args ) +{ + HDC hdc = get_handle( &args ); + const POINT *points = get_ptr( &args ); + const ULONG *counts = get_ptr( &args ); + DWORD count = get_ulong( &args ); + UINT function = get_ulong( &args ); + + return NtGdiPolyPolyDraw( hdc, points, counts, count, function ); +} + +NTSTATUS WINAPI wow64_NtGdiRectangle( UINT *args ) +{ + HDC hdc = get_handle( &args ); + INT left = get_ulong( &args ); + INT top = get_ulong( &args ); + INT right = get_ulong( &args ); + INT bottom = get_ulong( &args ); + + return NtGdiRectangle( hdc, left, top, right, bottom ); +} + +NTSTATUS WINAPI wow64_NtGdiResetDC( UINT *args ) +{ + HDC hdc = get_handle( &args ); + const DEVMODEW *devmode = get_ptr( &args ); + BOOL *banding = get_ptr( &args ); + DRIVER_INFO_2W *driver_info = get_ptr( &args ); + void *dev = get_ptr( &args ); + + return NtGdiResetDC( hdc, devmode, banding, driver_info, dev ); +} + +NTSTATUS WINAPI wow64_NtGdiResizePalette( UINT *args ) +{ + HPALETTE palette = get_handle( &args ); + UINT count = get_ulong( &args ); + + return NtGdiResizePalette( palette, count ); +} + +NTSTATUS WINAPI wow64_NtGdiRestoreDC( UINT *args ) +{ + HDC hdc = get_handle( &args ); + INT level = get_ulong( &args ); + + return NtGdiRestoreDC( hdc, level ); +} + +NTSTATUS WINAPI wow64_NtGdiGetRgnBox( UINT *args ) +{ + HRGN hrgn = get_handle( &args ); + RECT *rect = get_ptr( &args ); + + return NtGdiGetRgnBox( hrgn, rect ); +} + +NTSTATUS WINAPI wow64_NtGdiRoundRect( UINT *args ) +{ + HDC hdc = get_handle( &args ); + INT left = get_ulong( &args ); + INT top = get_ulong( &args ); + INT right = get_ulong( &args ); + INT bottom = get_ulong( &args ); + INT ell_width = get_ulong( &args ); + INT ell_height = get_ulong( &args ); + + return NtGdiRoundRect( hdc, left, top, right, bottom, ell_width, ell_height ); +} + +NTSTATUS WINAPI wow64_NtGdiGetSpoolMessage( UINT *args ) +{ +#ifndef __REACTOS__ + void *ptr1 = get_ptr( &args ); + DWORD data2 = get_ulong( &args ); + void *ptr3 = get_ptr( &args ); + DWORD data4 = get_ulong( &args ); +#else + DWORD ptr1 = get_ulong( &args ); + DWORD data2 = get_ulong( &args ); + DWORD ptr3 = get_ulong( &args ); + DWORD data4 = get_ulong( &args ); +#endif + + return NtGdiGetSpoolMessage( ptr1, data2, ptr3, data4 ); +} + +NTSTATUS WINAPI wow64_NtGdiGetSystemPaletteUse( UINT *args ) +{ + HDC hdc = get_handle( &args ); + + return NtGdiGetSystemPaletteUse( hdc ); +} + +NTSTATUS WINAPI wow64_NtGdiGetTransform( UINT *args ) +{ + HDC hdc = get_handle( &args ); + DWORD which = get_ulong( &args ); + XFORM *xform = get_ptr( &args ); + + return NtGdiGetTransform( hdc, which, xform ); +} + +NTSTATUS WINAPI wow64_NtGdiHfontCreate( UINT *args ) +{ + const void *logfont = get_ptr( &args ); + ULONG unk2 = get_ulong( &args ); + ULONG unk3 = get_ulong( &args ); + ULONG unk4 = get_ulong( &args ); + void *data = get_ptr( &args ); + + return HandleToUlong( NtGdiHfontCreate( logfont, unk2, unk3, unk4, data )); +} + +NTSTATUS WINAPI wow64_NtGdiInitSpool( UINT *args ) +{ + return NtGdiInitSpool(); +} + +NTSTATUS WINAPI wow64_NtGdiIntersectClipRect( UINT *args ) +{ + HDC hdc = get_handle( &args ); + INT left = get_ulong( &args ); + INT top = get_ulong( &args ); + INT right = get_ulong( &args ); + INT bottom = get_ulong( &args ); + + return NtGdiIntersectClipRect( hdc, left, top, right, bottom ); +} + +NTSTATUS WINAPI wow64_NtGdiOffsetClipRgn( UINT *args ) +{ + HDC hdc = get_handle( &args ); + INT x = get_ulong( &args ); + INT y = get_ulong( &args ); + + return NtGdiOffsetClipRgn( hdc, x, y ); +} + +NTSTATUS WINAPI wow64_NtGdiOffsetRgn( UINT *args ) +{ + HRGN hrgn = get_handle( &args ); + INT x = get_ulong( &args ); + INT y = get_ulong( &args ); + + return NtGdiOffsetRgn( hrgn, x, y ); +} + +NTSTATUS WINAPI wow64_NtGdiOpenDCW( UINT *args ) +{ + UNICODE_STRING32 *device32 = get_ptr( &args ); + const DEVMODEW *devmode = get_ptr( &args ); + UNICODE_STRING32 *output32 = get_ptr( &args ); + ULONG type = get_ulong( &args ); + BOOL is_display = get_ulong( &args ); + HANDLE hspool = get_handle( &args ); +#ifndef __REACTOS__ + DRIVER_INFO_2W *driver_info = get_ptr( &args ); + void *pdev = get_ptr( &args ); +#else + DRIVER_INFO_2W32 *driver_info32 = get_ptr( &args ); + DRIVER_INFO_2W driverInfo; +#endif + + UNICODE_STRING device, output; + HDC ret = NtGdiOpenDCW( unicode_str_32to64( &device, device32 ), devmode, + unicode_str_32to64( &output, output32 ), type, +#ifndef __REACTOS__ + is_display, hspool, driver_info, pdev ); +#else + is_display, hspool, DriverInfo2W32To64(&driverInfo, driver_info32)); + + DriverInfo2W64To32(&driverInfo, driver_info32); +#endif + return HandleToUlong( ret ); +} + +NTSTATUS WINAPI wow64_NtGdiPatBlt( UINT *args ) +{ + HDC hdc = get_handle( &args ); + INT left = get_ulong( &args ); + INT top = get_ulong( &args ); + INT width = get_ulong( &args ); + INT height = get_ulong( &args ); + DWORD rop = get_ulong( &args ); + + return NtGdiPatBlt( hdc, left, top, width, height, rop ); +} + +NTSTATUS WINAPI wow64_NtGdiPathToRegion( UINT *args ) +{ + HDC hdc = get_handle( &args ); + + return HandleToUlong( NtGdiPathToRegion( hdc )); +} + +NTSTATUS WINAPI wow64_NtGdiPlgBlt( UINT *args ) +{ + HDC hdc = get_handle( &args ); + const POINT *point = get_ptr( &args ); + HDC hdc_src = get_handle( &args ); + INT x_src = get_ulong( &args ); + INT y_src = get_ulong( &args ); + INT width = get_ulong( &args ); + INT height = get_ulong( &args ); + HBITMAP mask = get_handle( &args ); + INT x_mask = get_ulong( &args ); + INT y_mask = get_ulong( &args ); + DWORD bk_color = get_ulong( &args ); + + return NtGdiPlgBlt( hdc, point, hdc_src, x_src, y_src, width, height, + mask, x_mask, y_mask, bk_color ); +} + +NTSTATUS WINAPI wow64_NtGdiPtInRegion( UINT *args ) +{ + HRGN hrgn = get_handle( &args ); + INT x = get_ulong( &args ); + INT y = get_ulong( &args ); + + return NtGdiPtInRegion( hrgn, x, y ); +} + +NTSTATUS WINAPI wow64_NtGdiPtVisible( UINT *args ) +{ + HDC hdc = get_handle( &args ); + INT x = get_ulong( &args ); + INT y = get_ulong( &args ); + + return NtGdiPtVisible( hdc, x, y ); +} + +NTSTATUS WINAPI wow64_NtGdiRectInRegion( UINT *args ) +{ + HRGN hrgn = get_handle( &args ); + const RECT *rect = get_ptr( &args ); + + return NtGdiRectInRegion( hrgn, rect ); +} + +NTSTATUS WINAPI wow64_NtGdiRectVisible( UINT *args ) +{ + HDC hdc = get_handle( &args ); + const RECT *rect = get_ptr( &args ); + + return NtGdiRectVisible( hdc, rect ); +} + +NTSTATUS WINAPI wow64_NtGdiRemoveFontMemResourceEx( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + + return NtGdiRemoveFontMemResourceEx( handle ); +} + +NTSTATUS WINAPI wow64_NtGdiRemoveFontResourceW( UINT *args ) +{ + const WCHAR *str = get_ptr( &args ); + ULONG size = get_ulong( &args ); + ULONG files = get_ulong( &args ); + DWORD flags = get_ulong( &args ); + DWORD tid = get_ulong( &args ); + void *dv = get_ptr( &args ); + + return NtGdiRemoveFontResourceW( str, size, files, flags, tid, dv ); +} + +NTSTATUS WINAPI wow64_NtGdiSaveDC( UINT *args ) +{ + HDC hdc = get_handle( &args ); + + return NtGdiSaveDC( hdc ); +} + +NTSTATUS WINAPI wow64_NtGdiScaleViewportExtEx( UINT *args ) +{ + HDC hdc = get_handle( &args ); + INT x_num = get_ulong( &args ); + INT x_denom = get_ulong( &args ); + INT y_num = get_ulong( &args ); + INT y_denom = get_ulong( &args ); + SIZE *size = get_ptr( &args ); + + return NtGdiScaleViewportExtEx( hdc, x_num, x_denom, y_num, y_denom, size ); +} + +NTSTATUS WINAPI wow64_NtGdiScaleWindowExtEx( UINT *args ) +{ + HDC hdc = get_handle( &args ); + INT x_num = get_ulong( &args ); + INT x_denom = get_ulong( &args ); + INT y_num = get_ulong( &args ); + INT y_denom = get_ulong( &args ); + SIZE *size = get_ptr( &args ); + + return NtGdiScaleWindowExtEx( hdc, x_num, x_denom, y_num, y_denom, size ); +} + +NTSTATUS WINAPI wow64_NtGdiSelectBitmap( UINT *args ) +{ + HDC hdc = get_handle( &args ); + HGDIOBJ handle = get_handle( &args ); + + return HandleToUlong( NtGdiSelectBitmap( hdc, handle )); +} + +NTSTATUS WINAPI wow64_NtGdiSelectBrush( UINT *args ) +{ + HDC hdc = get_handle( &args ); + HGDIOBJ handle = get_handle( &args ); + + return HandleToUlong( NtGdiSelectBrush( hdc, handle )); +} + +NTSTATUS WINAPI wow64_NtGdiSelectClipPath( UINT *args ) +{ + HDC hdc = get_handle( &args ); + INT mode = get_ulong( &args ); + + return NtGdiSelectClipPath( hdc, mode ); +} + +NTSTATUS WINAPI wow64_NtGdiSelectFont( UINT *args ) +{ + HDC hdc = get_handle( &args ); + HGDIOBJ handle = get_handle( &args ); + + return HandleToUlong( NtGdiSelectFont( hdc, handle )); +} + +NTSTATUS WINAPI wow64_NtGdiSelectPen( UINT *args ) +{ + HDC hdc = get_handle( &args ); + HGDIOBJ handle = get_handle( &args ); + + return HandleToUlong( NtGdiSelectPen( hdc, handle )); +} + +NTSTATUS WINAPI wow64_NtGdiSetBitmapBits( UINT *args ) +{ + HBITMAP hbitmap = get_handle( &args ); + LONG count = get_ulong( &args ); + const void *bits = get_ptr( &args ); + + return NtGdiSetBitmapBits( hbitmap, count, bits ); +} + +NTSTATUS WINAPI wow64_NtGdiSetBitmapDimension( UINT *args ) +{ + HBITMAP hbitmap = get_handle( &args ); + INT x = get_ulong( &args ); + INT y = get_ulong( &args ); + SIZE *prev_size = get_ptr( &args ); + + return NtGdiSetBitmapDimension( hbitmap, x, y, prev_size ); +} + +NTSTATUS WINAPI wow64_NtGdiSetBoundsRect( UINT *args ) +{ + HDC hdc = get_handle( &args ); + const RECT *rect = get_ptr( &args ); + UINT flags = get_ulong( &args ); + + return NtGdiSetBoundsRect( hdc, rect, flags ); +} + +NTSTATUS WINAPI wow64_NtGdiSetBrushOrg( UINT *args ) +{ + HDC hdc = get_handle( &args ); + INT x = get_ulong( &args ); + INT y = get_ulong( &args ); + POINT *prev_org = get_ptr( &args ); + + return NtGdiSetBrushOrg( hdc, x, y, prev_org ); +} + +NTSTATUS WINAPI wow64_NtGdiSetColorAdjustment( UINT *args ) +{ + HDC hdc = get_handle( &args ); + const COLORADJUSTMENT *ca = get_ptr( &args ); + + return NtGdiSetColorAdjustment( hdc, ca ); +} + +NTSTATUS WINAPI wow64_NtGdiSetDIBitsToDeviceInternal( UINT *args ) +{ + HDC hdc = get_handle( &args ); + INT x_dst = get_ulong( &args ); + INT y_dst = get_ulong( &args ); + DWORD cx = get_ulong( &args ); + DWORD cy = get_ulong( &args ); + INT x_src = get_ulong( &args ); + INT y_src = get_ulong( &args ); + UINT startscan = get_ulong( &args ); + UINT lines = get_ulong( &args ); + const void *bits = get_ptr( &args ); + const BITMAPINFO *bmi = get_ptr( &args ); + UINT coloruse = get_ulong( &args ); + UINT max_bits = get_ulong( &args ); + UINT max_info = get_ulong( &args ); + BOOL xform_coords = get_ulong( &args ); + HANDLE xform = get_handle( &args ); + + return NtGdiSetDIBitsToDeviceInternal( hdc, x_dst, y_dst, cx, cy, x_src, y_src, + startscan, lines, bits, bmi, coloruse, + max_bits, max_info, xform_coords, xform ); +} + +NTSTATUS WINAPI wow64_NtGdiSetDeviceGammaRamp( UINT *args ) +{ + HDC hdc = get_handle( &args ); + void *ptr = get_ptr( &args ); + + return NtGdiSetDeviceGammaRamp( hdc, ptr ); +} + +NTSTATUS WINAPI wow64_NtGdiSetLayout( UINT *args ) +{ + HDC hdc = get_handle( &args ); + LONG wox = get_ulong( &args ); + DWORD layout = get_ulong( &args ); + + return NtGdiSetLayout( hdc, wox, layout ); +} + +NTSTATUS WINAPI wow64_NtGdiSetMagicColors( UINT *args ) +{ + HDC hdc = get_handle( &args ); +#ifndef __REACTOS__ + DWORD magic = get_ulong( &args ); +#else + DWORD magic_ulong = get_ulong( &args ); + PALETTEENTRY magic = *((PALETTEENTRY*)&magic_ulong); +#endif + ULONG index = get_ulong( &args ); + + return NtGdiSetMagicColors( hdc, magic, index ); +} + +NTSTATUS WINAPI wow64_NtGdiSetMetaRgn( UINT *args ) +{ + HDC hdc = get_handle( &args ); + + return NtGdiSetMetaRgn( hdc ); +} + +NTSTATUS WINAPI wow64_NtGdiSetPixel( UINT *args ) +{ + HDC hdc = get_handle( &args ); + INT x = get_ulong( &args ); + INT y = get_ulong( &args ); + COLORREF color = get_ulong( &args ); + + return NtGdiSetPixel( hdc, x, y, color ); +} + +NTSTATUS WINAPI wow64_NtGdiSetPixelFormat( UINT *args ) +{ + HDC hdc = get_handle( &args ); + INT format = get_ulong( &args ); + + return NtGdiSetPixelFormat( hdc, format ); +} + +NTSTATUS WINAPI wow64_NtGdiSetRectRgn( UINT *args ) +{ + HRGN hrgn = get_handle( &args ); + INT left = get_ulong( &args ); + INT top = get_ulong( &args ); + INT right = get_ulong( &args ); + INT bottom = get_ulong( &args ); + + return NtGdiSetRectRgn( hrgn, left, top, right, bottom ); +} + +NTSTATUS WINAPI wow64_NtGdiSetSystemPaletteUse( UINT *args ) +{ + HDC hdc = get_handle( &args ); + UINT use = get_ulong( &args ); + + return NtGdiSetSystemPaletteUse( hdc, use ); +} + +NTSTATUS WINAPI wow64_NtGdiSetTextJustification( UINT *args ) +{ + HDC hdc = get_handle( &args ); + INT extra = get_ulong( &args ); + INT breaks = get_ulong( &args ); + + return NtGdiSetTextJustification( hdc, extra, breaks ); +} + +NTSTATUS WINAPI wow64_NtGdiSetVirtualResolution( UINT *args ) +{ + HDC hdc = get_handle( &args ); + DWORD horz_res = get_ulong( &args ); + DWORD vert_res = get_ulong( &args ); + DWORD horz_size = get_ulong( &args ); + DWORD vert_size = get_ulong( &args ); + + return NtGdiSetVirtualResolution( hdc, horz_res, vert_res, horz_size, vert_size ); +} + +NTSTATUS WINAPI wow64_NtGdiStartDoc( UINT *args ) +{ + HDC hdc = get_handle( &args ); + const struct + { + INT cbSize; + ULONG lpszDocName; + ULONG lpszOutput; + ULONG lpszDatatype; + DWORD fwType; + } *doc32 = get_ptr( &args ); + BOOL *banding = get_ptr( &args ); + INT job = get_ulong( &args ); + + DOCINFOW doc; + doc.cbSize = sizeof(doc); + doc.lpszDocName = UlongToPtr( doc32->lpszDocName ); + doc.lpszOutput = UlongToPtr( doc32->lpszOutput ); + doc.lpszDatatype = UlongToPtr( doc32->lpszDatatype ); + doc.fwType = doc32->fwType; + + return NtGdiStartDoc( hdc, &doc, banding, job ); +} + +NTSTATUS WINAPI wow64_NtGdiStartPage( UINT *args ) +{ + HDC hdc = get_handle( &args ); + + return NtGdiStartPage( hdc ); +} + +NTSTATUS WINAPI wow64_NtGdiStretchBlt( UINT *args ) +{ + HDC hdc = get_handle( &args ); + INT x_dst = get_ulong( &args ); + INT y_dst = get_ulong( &args ); + INT width_dst = get_ulong( &args ); + INT height_dst = get_ulong( &args ); + HDC hdc_src = get_handle( &args ); + INT x_src = get_ulong( &args ); + INT y_src = get_ulong( &args ); + INT width_src = get_ulong( &args ); + INT height_src = get_ulong( &args ); + DWORD rop = get_ulong( &args ); + COLORREF bk_color = get_ulong( &args ); + + return NtGdiStretchBlt( hdc, x_dst, y_dst, width_dst, height_dst, hdc_src, + x_src, y_src, width_src, height_src, rop, bk_color ); +} + +NTSTATUS WINAPI wow64_NtGdiStretchDIBitsInternal( UINT *args ) +{ + HDC hdc = get_handle( &args ); + INT x_dst = get_ulong( &args ); + INT y_dst = get_ulong( &args ); + INT width_dst = get_ulong( &args ); + INT height_dst = get_ulong( &args ); + INT x_src = get_ulong( &args ); + INT y_src = get_ulong( &args ); + INT width_src = get_ulong( &args ); + INT height_src = get_ulong( &args ); + const void *bits = get_ptr( &args ); + const BITMAPINFO *bmi = get_ptr( &args ); + UINT coloruse = get_ulong( &args ); + DWORD rop = get_ulong( &args ); + UINT max_info = get_ulong( &args ); + UINT max_bits = get_ulong( &args ); + HANDLE xform = get_handle( &args ); + + return NtGdiStretchDIBitsInternal( hdc, x_dst, y_dst, width_dst, height_dst, + x_src, y_src, width_src, height_src, bits, bmi, + coloruse, rop, max_info, max_bits, xform ); +} + +NTSTATUS WINAPI wow64_NtGdiStrokeAndFillPath( UINT *args ) +{ + HDC hdc = get_handle( &args ); + + return NtGdiStrokeAndFillPath( hdc ); +} + +NTSTATUS WINAPI wow64_NtGdiStrokePath( UINT *args ) +{ + HDC hdc = get_handle( &args ); + + return NtGdiStrokePath( hdc ); +} + +NTSTATUS WINAPI wow64_NtGdiSwapBuffers( UINT *args ) +{ + HDC hdc = get_handle( &args ); + + return NtGdiSwapBuffers( hdc ); +} + +NTSTATUS WINAPI wow64_NtGdiTransparentBlt( UINT *args ) +{ + HDC hdc = get_handle( &args ); + int x_dst = get_ulong( &args ); + int y_dst = get_ulong( &args ); + int width_dst = get_ulong( &args ); + int height_dst = get_ulong( &args ); + HDC hdc_src = get_handle( &args ); + int x_src = get_ulong( &args ); + int y_src = get_ulong( &args ); + int width_src = get_ulong( &args ); + int height_src = get_ulong( &args ); + UINT color = get_ulong( &args ); + + return NtGdiTransparentBlt( hdc, x_dst, y_dst, width_dst, height_dst, hdc_src, + x_src, y_src, width_src, height_src, color ); +} + +NTSTATUS WINAPI wow64_NtGdiTransformPoints( UINT *args ) +{ + HDC hdc = get_handle( &args ); + const POINT *points_in = get_ptr( &args ); + POINT *points_out = get_ptr( &args ); + INT count = get_ulong( &args ); + UINT mode = get_ulong( &args ); + + return NtGdiTransformPoints( hdc, points_in, points_out, count, mode ); +} + +NTSTATUS WINAPI wow64_NtGdiUnrealizeObject( UINT *args ) +{ + HGDIOBJ obj = get_handle( &args ); + + return NtGdiUnrealizeObject( obj ); +} + +NTSTATUS WINAPI wow64_NtGdiUpdateColors( UINT *args ) +{ + HDC hdc = get_handle( &args ); + + return NtGdiUpdateColors( hdc ); +} + +NTSTATUS WINAPI wow64_NtGdiWidenPath( UINT *args ) +{ + HDC hdc = get_handle( &args ); + + return NtGdiWidenPath( hdc ); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64___wine_get_icm_profile( UINT *args ) +{ + HDC hdc = get_handle( &args ); + BOOL allow_default = get_ulong( &args ); + DWORD *size = get_ptr( &args ); + WCHAR *filename = get_ptr( &args ); + + return __wine_get_icm_profile( hdc, allow_default, size, filename ); +} + +NTSTATUS WINAPI wow64___wine_get_file_outline_text_metric( UINT *args ) +{ + const WCHAR *path = get_ptr( &args ); + TEXTMETRICW *otm = get_ptr( &args ); + UINT *em_square = get_ptr( &args ); + WCHAR *face_name = get_ptr( &args ); + + return __wine_get_file_outline_text_metric( path, otm, em_square, face_name ); +} +#else + +HANDLE +WINAPI +wow64_NtGdiGetStockObject(ULONG* pArgs) +{ + INT Type = get_ulong(&pArgs); + + return NtGdiGetStockObject(Type); +} + +#endif \ No newline at end of file diff --git a/dll/wow64win/syscall.c b/dll/wow64win/syscall.c new file mode 100644 index 0000000000000..34c9f2b354084 --- /dev/null +++ b/dll/wow64win/syscall.c @@ -0,0 +1,357 @@ +/* + * WoW64 syscall wrapping + * + * Copyright 2021 Alexandre Julliard + * Copyright 2025 Marcin Jabłoński + * + * 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 + */ + +#ifndef __REACTOS__ +#include + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "winnt.h" +#include "winternl.h" +#endif +#include "wow64win_private.h" + +#ifdef __REACTOS__ +#define SVC_(name,numArgs) extern NTSTATUS WINAPI wow64_Nt ## name( UINT *args ); +#include "../../../win32ss/w32ksvc32.h" +#undef SVC_ + +#define SVC_(name,numArgs) static int Num ## name = __COUNTER__; +#include "../../../win32ss/w32ksvc32.h" +#undef SVC_ + +static NTSTATUS wow64win_Unimplemented(UINT* pArgs) +{ + DPRINT1("UNIMPLEMENTED SYSCALL\n"); + return STATUS_NOT_IMPLEMENTED; +} +#endif + +#ifndef __REACTOS__ +static void * const win32_syscalls[] = +#else +static void* win32_syscalls[] = +#endif +{ +#ifdef __REACTOS__ +#define SVC_(name, argc) NULL, +#include "../../../win32ss/w32ksvc32.h" +#undef SVC_ +#else +#define SYSCALL_ENTRY(id,name,args) wow64_ ## name, + ALL_SYSCALLS32 +#undef SYSCALL_ENTRY +#endif +}; + +#ifdef __REACTOS__ +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(*x)) +#endif + +static BYTE arguments[ARRAY_SIZE(win32_syscalls)] = +{ +#ifdef __REACTOS__ +#define SVC_(name, argc) argc, +#include "../../../win32ss/w32ksvc32.h" +#undef SVC_ +#else +#define SYSCALL_ENTRY(id,name,args) args, + ALL_SYSCALLS32 +#undef SYSCALL_ENTRY +#endif +}; + +#ifdef __REACTOS__ +__declspec(dllexport) +#endif +const SYSTEM_SERVICE_TABLE sdwhwin32 = +{ + (ULONG_PTR *)win32_syscalls, + NULL, + ARRAY_SIZE(win32_syscalls), + arguments +}; + +#ifdef __REACTOS__ + +__declspec(allocate(".text")) +static unsigned char ReadFsDwordImpl[] = +{ + 0x64, 0x8B, 0x01, /* mov eax, fs:[rcx] */ + 0xC3 /* ret */ +}; + +ULONG __readfsdword(ULONG x) +{ + typedef ULONG(*__readfsdwordImplType)(ULONG); + return ((__readfsdwordImplType)ReadFsDwordImpl)(x); +} + +PSERVERINFO g_ServerInfo = NULL; + +static BOOL wow64_NtGdiInit(UINT* pArgs) +{ + return NtGdiInit(); +} + +static VOID InitServiceTable(VOID) +{ +#define IMPLEMENT_SERVICE(name) do { win32_syscalls[Num ## name] = (PVOID*)wow64_Nt ## name; } while(0) + + IMPLEMENT_SERVICE(UserProcessConnect); + IMPLEMENT_SERVICE(UserInitializeClientPfnArrays); + IMPLEMENT_SERVICE(GdiInit); + IMPLEMENT_SERVICE(GdiCreateBitmap); + IMPLEMENT_SERVICE(GdiCreateCompatibleDC); + IMPLEMENT_SERVICE(GdiDeleteObjectApp); + IMPLEMENT_SERVICE(UserCallNoParam); + IMPLEMENT_SERVICE(UserCallOneParam); + IMPLEMENT_SERVICE(UserCallHwndLock); + IMPLEMENT_SERVICE(UserGetThreadState); + IMPLEMENT_SERVICE(UserGetMessage); + IMPLEMENT_SERVICE(UserMessageCall); + IMPLEMENT_SERVICE(UserRegisterClassExWOW); + IMPLEMENT_SERVICE(UserGetClassInfo); + IMPLEMENT_SERVICE(UserCreateWindowEx); + IMPLEMENT_SERVICE(UserShowWindow); + IMPLEMENT_SERVICE(UserGetMessage); + IMPLEMENT_SERVICE(UserDispatchMessage); + IMPLEMENT_SERVICE(UserFindExistingCursorIcon); + IMPLEMENT_SERVICE(UserBeginPaint); + IMPLEMENT_SERVICE(UserEndPaint); + IMPLEMENT_SERVICE(GdiPatBlt); + IMPLEMENT_SERVICE(UserSetFocus); + IMPLEMENT_SERVICE(GdiSelectBitmap); + IMPLEMENT_SERVICE(GdiStretchDIBitsInternal); + IMPLEMENT_SERVICE(GdiSetDIBitsToDeviceInternal); + IMPLEMENT_SERVICE(GdiGetDeviceCaps); + IMPLEMENT_SERVICE(GdiCreateCompatibleBitmap); + IMPLEMENT_SERVICE(GdiGetAppClipBox); + IMPLEMENT_SERVICE(GdiFlush); + IMPLEMENT_SERVICE(UserDestroyWindow); + IMPLEMENT_SERVICE(UserThunkedMenuItemInfo); + IMPLEMENT_SERVICE(GdiCreateSolidBrush); + IMPLEMENT_SERVICE(UserGetAtomName); + IMPLEMENT_SERVICE(GdiGetTextMetricsW); + IMPLEMENT_SERVICE(GdiHfontCreate); + IMPLEMENT_SERVICE(UserGetDC); + IMPLEMENT_SERVICE(GdiSelectFont); + IMPLEMENT_SERVICE(UserCallHwndParam); + IMPLEMENT_SERVICE(UserCallHwnd); + IMPLEMENT_SERVICE(UserSetWindowLong); + IMPLEMENT_SERVICE(UserSetWindowLongPtr); + IMPLEMENT_SERVICE(UserBuildHwndList); + IMPLEMENT_SERVICE(UserCallTwoParam); + IMPLEMENT_SERVICE(UserSetWindowFNID); + IMPLEMENT_SERVICE(UserDefSetText); + IMPLEMENT_SERVICE(UserGetClassName); + IMPLEMENT_SERVICE(GdiTransformPoints); + IMPLEMENT_SERVICE(GdiGetOutlineTextMetricsInternalW); + IMPLEMENT_SERVICE(GdiCreatePatternBrushInternal); + IMPLEMENT_SERVICE(UserGetDoubleClickTime); + IMPLEMENT_SERVICE(GdiEllipse); + IMPLEMENT_SERVICE(GdiMaskBlt); + IMPLEMENT_SERVICE(GdiExtGetObjectW); + IMPLEMENT_SERVICE(GdiGetTextExtent); + IMPLEMENT_SERVICE(UserInternalGetWindowText); + IMPLEMENT_SERVICE(GdiSetPixel); + IMPLEMENT_SERVICE(GdiGetPixel); + IMPLEMENT_SERVICE(GdiExtFloodFill); + IMPLEMENT_SERVICE(GdiTransparentBlt); + IMPLEMENT_SERVICE(UserDrawIconEx); + IMPLEMENT_SERVICE(GdiPolyPolyDraw); + IMPLEMENT_SERVICE(GdiGetStockObject); + IMPLEMENT_SERVICE(GdiGetFontData); + IMPLEMENT_SERVICE(GdiOpenDCW); + IMPLEMENT_SERVICE(GdiGetDCObject); + IMPLEMENT_SERVICE(GdiGetDCforBitmap); + IMPLEMENT_SERVICE(GdiGetCharABCWidthsW); + IMPLEMENT_SERVICE(GdiGetGlyphIndicesW); + IMPLEMENT_SERVICE(GdiGetTransform); + IMPLEMENT_SERVICE(GdiGetRandomRgn); + IMPLEMENT_SERVICE(GdiIntersectClipRect); + IMPLEMENT_SERVICE(GdiCreateRectRgn); + IMPLEMENT_SERVICE(GdiExtTextOutW); + IMPLEMENT_SERVICE(GdiExtSelectClipRgn); + IMPLEMENT_SERVICE(GdiCreateDIBitmapInternal); + IMPLEMENT_SERVICE(UserSetClassWord); + IMPLEMENT_SERVICE(UserSetClassLong); + IMPLEMENT_SERVICE(UserSetCapture); + IMPLEMENT_SERVICE(UserSetActiveWindow); + IMPLEMENT_SERVICE(UserGetControlBrush); + IMPLEMENT_SERVICE(GdiGetTextExtentExW); + IMPLEMENT_SERVICE(UserSystemParametersInfo); + IMPLEMENT_SERVICE(UserTrackMouseEvent); + IMPLEMENT_SERVICE(GdiRectangle); + IMPLEMENT_SERVICE(UserShowScrollBar); + IMPLEMENT_SERVICE(UserSetScrollInfo); + IMPLEMENT_SERVICE(GdiBitBlt); + IMPLEMENT_SERVICE(UserGetDCEx); + IMPLEMENT_SERVICE(UserSetParent); + IMPLEMENT_SERVICE(UserSetWindowPos); + IMPLEMENT_SERVICE(UserDestroyMenu); + IMPLEMENT_SERVICE(GdiSetLayout); + IMPLEMENT_SERVICE(GdiGetCharWidthW); + IMPLEMENT_SERVICE(UserAlterWindowStyle); + IMPLEMENT_SERVICE(UserSetWindowRgn); + IMPLEMENT_SERVICE(UserHideCaret); + IMPLEMENT_SERVICE(UserScrollWindowEx); + IMPLEMENT_SERVICE(UserGetScrollBarInfo); + IMPLEMENT_SERVICE(UserHiliteMenuItem); + IMPLEMENT_SERVICE(UserGetScrollBarInfo); + IMPLEMENT_SERVICE(UserSBGetParms); + IMPLEMENT_SERVICE(UserPeekMessage); + IMPLEMENT_SERVICE(GdiCreatePen); + IMPLEMENT_SERVICE(UserGetIconSize); + IMPLEMENT_SERVICE(GdiLineTo); + IMPLEMENT_SERVICE(UserSetScrollBarInfo); + IMPLEMENT_SERVICE(UserSetCursorIconData); + IMPLEMENT_SERVICE(UserMapVirtualKeyEx); + IMPLEMENT_SERVICE(UserToUnicodeEx); + IMPLEMENT_SERVICE(UserGetKeyboardState); + IMPLEMENT_SERVICE(UserPostMessage); + IMPLEMENT_SERVICE(UserTranslateMessage); + IMPLEMENT_SERVICE(UserGetAsyncKeyState); + IMPLEMENT_SERVICE(UserGetAncestor); + IMPLEMENT_SERVICE(UserTranslateAccelerator); + IMPLEMENT_SERVICE(UserPrintWindow); + IMPLEMENT_SERVICE(UserPostThreadMessage); + IMPLEMENT_SERVICE(UserIsClipboardFormatAvailable); + IMPLEMENT_SERVICE(UserOpenClipboard); + IMPLEMENT_SERVICE(UserMonitorFromRect); + IMPLEMENT_SERVICE(UserGetMonitorInfo); + IMPLEMENT_SERVICE(UserSetMenu); + IMPLEMENT_SERVICE(UserDestroyCursor); + IMPLEMENT_SERVICE(UserCreateCaret); + IMPLEMENT_SERVICE(UserMoveWindow); + IMPLEMENT_SERVICE(UserRedrawWindow); + IMPLEMENT_SERVICE(UserEnableMenuItem); + IMPLEMENT_SERVICE(UserShowCaret); + IMPLEMENT_SERVICE(UserInvalidateRect); + IMPLEMENT_SERVICE(UserInvalidateRgn); + IMPLEMENT_SERVICE(UserSetProp); + IMPLEMENT_SERVICE(UserGetIconInfo); + IMPLEMENT_SERVICE(UserSetCursor); + IMPLEMENT_SERVICE(UserSetWindowPlacement); + IMPLEMENT_SERVICE(UserGetWindowPlacement); + IMPLEMENT_SERVICE(UserGetKeyState); + IMPLEMENT_SERVICE(GdiRectVisible); + IMPLEMENT_SERVICE(UserKillTimer); + IMPLEMENT_SERVICE(UserSetTimer); + IMPLEMENT_SERVICE(UserDeferWindowPos); + IMPLEMENT_SERVICE(GdiGetDIBitsInternal); + IMPLEMENT_SERVICE(GdiCreateDIBSection); + IMPLEMENT_SERVICE(UserMonitorFromWindow); + IMPLEMENT_SERVICE(GdiAlphaBlend); + IMPLEMENT_SERVICE(UserCreateAcceleratorTable); + IMPLEMENT_SERVICE(UserGetControlColor); + IMPLEMENT_SERVICE(UserDragDetect); + IMPLEMENT_SERVICE(UserDragObject); + IMPLEMENT_SERVICE(UserDrawCaptionTemp); + IMPLEMENT_SERVICE(UserDrawMenuBarTemp); + IMPLEMENT_SERVICE(UserEmptyClipboard); + IMPLEMENT_SERVICE(UserEnableMenuItem); + IMPLEMENT_SERVICE(UserEnableScrollBar); + IMPLEMENT_SERVICE(UserEndDeferWindowPosEx); + IMPLEMENT_SERVICE(UserEndMenu); + IMPLEMENT_SERVICE(GdiStretchBlt); + IMPLEMENT_SERVICE(UserFindWindowEx); + IMPLEMENT_SERVICE(UserDeleteMenu); + IMPLEMENT_SERVICE(UserRemoveMenu); + IMPLEMENT_SERVICE(GdiSaveDC); + IMPLEMENT_SERVICE(GdiRestoreDC); + IMPLEMENT_SERVICE(UserRemoveProp); + IMPLEMENT_SERVICE(UserEnumDisplaySettings); + IMPLEMENT_SERVICE(GdiExcludeClipRect); + IMPLEMENT_SERVICE(UserRegisterWindowMessage); + IMPLEMENT_SERVICE(UserQueryWindow); + IMPLEMENT_SERVICE(UserGetGuiResources); + IMPLEMENT_SERVICE(UserCheckMenuItem); + IMPLEMENT_SERVICE(UserShowWindowAsync); + IMPLEMENT_SERVICE(GdiExtCreatePen); + IMPLEMENT_SERVICE(UserWindowFromPoint); + IMPLEMENT_SERVICE(UserSetClipboardData); + IMPLEMENT_SERVICE(UserGetClipboardData); + IMPLEMENT_SERVICE(UserCreateLocalMemHandle); + IMPLEMENT_SERVICE(UserCloseClipboard); + IMPLEMENT_SERVICE(UserConvertMemHandle); + IMPLEMENT_SERVICE(UserClipCursor); + IMPLEMENT_SERVICE(UserCloseClipboard); + IMPLEMENT_SERVICE(UserCloseDesktop); + IMPLEMENT_SERVICE(UserCloseWindowStation); + IMPLEMENT_SERVICE(GdiGetTextCharsetInfo); + IMPLEMENT_SERVICE(UserSelectPalette); + IMPLEMENT_SERVICE(UserTrackPopupMenuEx); + IMPLEMENT_SERVICE(GdiGetDeviceGammaRamp); + IMPLEMENT_SERVICE(UserGetKeyboardLayoutName); + IMPLEMENT_SERVICE(UserLoadKeyboardLayoutEx); + IMPLEMENT_SERVICE(UserSetImeHotKey); + IMPLEMENT_SERVICE(UserGetKeyboardLayoutList); + IMPLEMENT_SERVICE(UserEnumDisplayDevices); + IMPLEMENT_SERVICE(UserEnumDisplayMonitors); + IMPLEMENT_SERVICE(GdiGetFontFamilyInfo); + IMPLEMENT_SERVICE(GdiModifyWorldTransform); + IMPLEMENT_SERVICE(GdiGetGlyphOutline); + IMPLEMENT_SERVICE(GdiGetRegionData); + IMPLEMENT_SERVICE(UserWaitMessage); + IMPLEMENT_SERVICE(GdiOffsetRgn); + IMPLEMENT_SERVICE(UserGetUpdateRect); + IMPLEMENT_SERVICE(GdiCombineRgn); + IMPLEMENT_SERVICE(GdiSetBrushOrg); + IMPLEMENT_SERVICE(UserGetCaretBlinkTime); + IMPLEMENT_SERVICE(UserGetGUIThreadInfo); + IMPLEMENT_SERVICE(UserSetKeyboardState); + IMPLEMENT_SERVICE(UserFlashWindowEx); + IMPLEMENT_SERVICE(UserGetUpdateRgn); + IMPLEMENT_SERVICE(UserUnregisterClass); + IMPLEMENT_SERVICE(UserDestroyAcceleratorTable); + IMPLEMENT_SERVICE(UserGetSystemMenu); + IMPLEMENT_SERVICE(UserGetForegroundWindow); + IMPLEMENT_SERVICE(UserSetThreadState); + IMPLEMENT_SERVICE(UserGetComboBoxInfo); + IMPLEMENT_SERVICE(UserGetWindowDC); + IMPLEMENT_SERVICE(GdiGetCharSet); + IMPLEMENT_SERVICE(GdiExtCreateRegion); + IMPLEMENT_SERVICE(GdiExtCreatePen); + IMPLEMENT_SERVICE(UserUnhookWindowsHookEx); + IMPLEMENT_SERVICE(GdiAddFontMemResourceEx); + IMPLEMENT_SERVICE(UserUnregisterHotKey); + IMPLEMENT_SERVICE(UserUnhookWinEvent); + IMPLEMENT_SERVICE(UserUpdateLayeredWindow); +#undef IMPLEMENT_SERVICE +} + +#endif + +BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, void *reserved ) +{ + if (reason != DLL_PROCESS_ATTACH) return TRUE; +#ifndef __REACTOS__ + LdrDisableThreadCalloutsForDll( inst ); + NtCurrentTeb()->Peb->KernelCallbackTable = user_callbacks; +#else + NtCurrentPeb()->KernelCallbackTable = UserCallbacks; + InitServiceTable(); +#endif + return TRUE; +} diff --git a/dll/wow64win/user.c b/dll/wow64win/user.c new file mode 100644 index 0000000000000..9fab8c219df2b --- /dev/null +++ b/dll/wow64win/user.c @@ -0,0 +1,5350 @@ +/* + * WoW64 User functions + * + * Copyright 2021 Jacek Caban for CodeWeavers + * Copyright 2025 Marcin Jabłoński + * + * 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 + +#ifndef __REACTOS__ +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "ntuser.h" +#include "shellapi.h" +#include "wow64win_private.h" +#include "wine/debug.h" + +#else + +#include "wow64win_private.h" +#include "../../../win32ss/include/callback.h" + +#endif + + +WINE_DEFAULT_DEBUG_CHANNEL(wow); + +#ifndef __REACTOS__ + +typedef struct +{ + DWORD cbSize; + DWORD fMask; + DWORD dwStyle; + UINT cyMax; + ULONG hbrBack; + DWORD dwContextHelpID; + ULONG dwMenuData; +} MENUINFO32; + +typedef struct +{ + UINT cbSize; + UINT fMask; + UINT fType; + UINT fState; + UINT wID; + UINT32 hSubMenu; + UINT32 hbmpChecked; + UINT32 hbmpUnchecked; + UINT32 dwItemData; + UINT32 dwTypeData; + UINT cch; + UINT32 hbmpItem; +} MENUITEMINFOW32; + +typedef struct +{ + UINT32 hwnd; + UINT message; + UINT32 wParam; + UINT32 lParam; + DWORD time; + POINT pt; +} MSG32; + +typedef struct +{ + DWORD dwType; + DWORD dwSize; + UINT32 hDevice; + UINT32 wParam; +} RAWINPUTHEADER32; + +typedef struct +{ + USHORT usUsagePage; + USHORT usUsage; + DWORD dwFlags; + UINT32 hwndTarget; +} RAWINPUTDEVICE32; + +typedef struct +{ + UINT32 hDevice; + DWORD dwType; +} RAWINPUTDEVICELIST32; + +typedef struct +{ + LONG dx; + LONG dy; + DWORD mouseData; + DWORD dwFlags; + DWORD time; + ULONG dwExtraInfo; +} MOUSEINPUT32; + +typedef struct +{ + WORD wVk; + WORD wScan; + DWORD dwFlags; + DWORD time; + ULONG dwExtraInfo; +} KEYBDINPUT32; + +typedef struct +{ + DWORD type; + union + { + MOUSEINPUT32 mi; + KEYBDINPUT32 ki; + HARDWAREINPUT hi; + } DUMMYUNIONNAME; +} INPUT32; + +typedef struct +{ + int x; + int y; + DWORD time; + ULONG dwExtraInfo; +} MOUSEMOVEPOINT32; + +typedef struct +{ + UINT32 hdc; + BOOL fErase; + RECT rcPaint; + BOOL fRestore; + BOOL fIncUpdate; + BYTE rgbReserved[32]; +} PAINTSTRUCT32; + +typedef struct +{ + ULONG lpCreateParams; + ULONG hInstance; + ULONG hMenu; + ULONG hwndParent; + INT cy; + INT cx; + INT y; + INT x; + LONG style; + ULONG lpszName; + ULONG lpszClass; + DWORD dwExStyle; +} CREATESTRUCT32; + +typedef struct +{ + ULONG szClass; + ULONG szTitle; + ULONG hOwner; + INT x; + INT y; + INT cx; + INT cy; + DWORD style; + ULONG lParam; +} MDICREATESTRUCT32; + +typedef struct +{ + ULONG hmenuIn; + ULONG hmenuNext; + ULONG hwndNext; +} MDINEXTMENU32; + +typedef struct +{ + LONG lResult; + LONG lParam; + LONG wParam; + DWORD message; + ULONG hwnd; +} CWPRETSTRUCT32; + +typedef struct +{ + ULONG hwnd; + ULONG hwndInsertAfter; + INT x; + INT y; + INT cx; + INT cy; + UINT flags; +} WINDOWPOS32; + +typedef struct +{ + RECT rgrc[3]; + ULONG lppos; +} NCCALCSIZE_PARAMS32; + +typedef struct +{ + UINT CtlType; + UINT CtlID; + ULONG hwndItem; + UINT itemID1; + ULONG itemData1; + UINT itemID2; + ULONG itemData2; + DWORD dwLocaleId; +} COMPAREITEMSTRUCT32; + +typedef struct +{ + ULONG dwData; + DWORD cbData; + ULONG lpData; +} COPYDATASTRUCT32; + +typedef struct +{ + UINT cbSize; + INT iContextType; + INT iCtrlId; + ULONG hItemHandle; + DWORD dwContextId; + POINT MousePos; +} HELPINFO32; + +typedef struct +{ + UINT CtlType; + UINT CtlID; + UINT itemID; + UINT itemWidth; + UINT itemHeight; + ULONG itemData; +} MEASUREITEMSTRUCT32; + +typedef struct +{ + UINT CtlType; + UINT CtlID; + UINT itemID; + UINT itemAction; + UINT itemState; + ULONG hwndItem; + ULONG hDC; + RECT rcItem; + ULONG itemData; +} DRAWITEMSTRUCT32; + +typedef struct +{ + DWORD cbSize; + RECT rcItem; + RECT rcButton; + DWORD stateButton; + ULONG hwndCombo; + ULONG hwndItem; + ULONG hwndList; +} COMBOBOXINFO32; + +typedef struct +{ + ULONG lParam; + ULONG wParam; + UINT message; + ULONG hwnd; +} CWPSTRUCT32; + +typedef struct +{ + POINT pt; + ULONG hwnd; + UINT wHitTestCode; + ULONG dwExtraInfo; + DWORD mouseData; +} MOUSEHOOKSTRUCTEX32; + +typedef struct +{ + POINT pt; + DWORD mouseData; + DWORD flags; + DWORD time; + ULONG dwExtraInfo; +} MSLLHOOKSTRUCT32; + +typedef struct +{ + DWORD vkCode; + DWORD scanCode; + DWORD flags; + DWORD time; + ULONG dwExtraInfo; +} KBDLLHOOKSTRUCT32; + +typedef struct +{ + UINT message; + UINT paramL; + UINT paramH; + DWORD time; + ULONG hwnd; +} EVENTMSG32; + +typedef struct +{ + BOOL fMouse; + ULONG hWndActive; +} CBTACTIVATESTRUCT32; + +typedef struct +{ + UINT CtlType; + UINT CtlID; + UINT itemID; + ULONG hwndItem; + ULONG itemData; +} DELETEITEMSTRUCT32; + +typedef struct +{ + UINT cbSize; + UINT style; + ULONG lpfnWndProc; + INT cbClsExtra; + INT cbWndExtra; + ULONG hInstance; + ULONG hIcon; + ULONG hCursor; + ULONG hbrBackground; + ULONG lpszMenuName; + ULONG lpszClassName; + ULONG hIconSm; +} WNDCLASSEXW32; +#endif + +struct client_menu_name32 +{ + ULONG nameA; + ULONG nameW; + ULONG nameUS; +}; + +#ifndef __REACTOS__ +struct win_proc_params32 +{ + ULONG func; + ULONG hwnd; + UINT msg; + ULONG wparam; + ULONG lparam; + BOOL ansi; + BOOL ansi_dst; + enum wm_char_mapping mapping; + ULONG dpi_context; + ULONG procA; + ULONG procW; +}; + +struct win_hook_params32 +{ + ULONG proc; + ULONG handle; + DWORD pid; + DWORD tid; + int id; + int code; + ULONG wparam; + ULONG lparam; + BOOL prev_unicode; + BOOL next_unicode; + WCHAR module[1]; +}; + +struct win_event_hook_params32 +{ + DWORD event; + ULONG hwnd; + LONG object_id; + LONG child_id; + ULONG handle; + DWORD tid; + DWORD time; + ULONG proc; + WCHAR module[MAX_PATH]; +}; + +struct draw_text_params32 +{ + ULONG hdc; + int count; + RECT rect; + UINT flags; + WCHAR str[1]; +}; + +struct unpack_dde_message_params32 +{ + ULONG hwnd; + UINT message; + LONG wparam; + LONG lparam; + char data[1]; +}; +#endif + +static MSG *msg_32to64( MSG *msg, const MSG32 *msg32 ) +{ + if (!msg32) return NULL; + + msg->hwnd = LongToHandle( msg32->hwnd ); + msg->message = msg32->message; + msg->wParam = msg32->wParam; + msg->lParam = msg32->lParam; + msg->time = msg32->time; + msg->pt = msg32->pt; + return msg; +} + +static MSG32 *msg_64to32( const MSG *msg64, MSG32 *msg32 ) +{ + MSG32 msg; + + if (!msg32) return NULL; + + msg.hwnd = HandleToLong( msg64->hwnd ); + msg.message = msg64->message; + msg.wParam = msg64->wParam; + msg.lParam = msg64->lParam; + msg.time = msg64->time; + msg.pt = msg64->pt; + memcpy( msg32, &msg, sizeof(msg) ); + return msg32; +} + +#ifndef __REACTOS__ +static struct client_menu_name *client_menu_name_32to64( struct client_menu_name *name, + const struct client_menu_name32 *name32 ) +{ + if (!name32) return NULL; + name->nameA = UlongToPtr( name32->nameA ); + name->nameW = UlongToPtr( name32->nameW ); + name->nameUS = UlongToPtr( name32->nameUS ); + return name; +} + +static struct client_menu_name32 *client_menu_name_64to32( const struct client_menu_name *name64, + struct client_menu_name32 *name32 ) +{ + if (name32) + { + struct client_menu_name32 name; + name.nameA = PtrToUlong( name64->nameA ); + name.nameW = PtrToUlong( name64->nameW ); + name.nameUS = PtrToUlong( name64->nameUS ); + memcpy( name32, &name, sizeof(name) ); + } + return name32; +} +#else +static PCLSMENUNAME client_menu_name_32to64( PCLSMENUNAME name, + const struct client_menu_name32 *name32, + UNICODE_STRING* pusMenuName) +{ + if (!name32) return NULL; + name->pszClientAnsiMenuName = UlongToPtr( name32->nameA ); + name->pwszClientUnicodeMenuName = UlongToPtr( name32->nameW ); + name->pusMenuName = unicode_str_32to64(pusMenuName, UlongToPtr(name32->nameUS)); + return name; +} + +static struct client_menu_name32 *client_menu_name_64to32( const CLSMENUNAME *name64, + struct client_menu_name32 *name32 ) +{ + if (name32) + { + struct client_menu_name32 name; + name.nameA = PtrToUlong( name64->pszClientAnsiMenuName ); + name.nameW = PtrToUlong( name64->pwszClientUnicodeMenuName ); + name.nameUS = PtrToUlong( name64->pusMenuName ); + memcpy( name32, &name, sizeof(name) ); + } + return name32; +} +#endif + +#ifndef __REACTOS__ +static void win_proc_params_64to32( const struct win_proc_params *src, struct win_proc_params32 *dst ) +{ + struct win_proc_params32 params; + + params.func = PtrToUlong( src->func ); + params.hwnd = HandleToUlong( src->hwnd ); + params.msg = src->msg; + params.wparam = src->wparam; + params.lparam = src->lparam; + params.ansi = src->ansi; + params.ansi_dst = src->ansi_dst; + params.mapping = src->mapping; + params.dpi_context = src->dpi_context; + params.procA = PtrToUlong( src->procA ); + params.procW = PtrToUlong( src->procW ); + memcpy( dst, ¶ms, sizeof(params) ); +} +#else +VOID +WndProcParams64To32(PWINDOWPROC_CALLBACK_ARGUMENTS CallbackArgs, + PWINDOWPROC_CALLBACK_ARGUMENTS32 Arguments32); + +VOID +WndProcParams32To64(PWINDOWPROC_CALLBACK_ARGUMENTS OutArguments, + PWINDOWPROC_CALLBACK_ARGUMENTS32 CallbackArgs); +#endif + +static void createstruct_32to64( const CREATESTRUCT32 *from, CREATESTRUCTW *to ) + +{ + to->lpCreateParams = UlongToPtr( from->lpCreateParams ); + to->hInstance = UlongToPtr( from->hInstance ); + to->hMenu = LongToHandle( from->hMenu ); + to->hwndParent = LongToHandle( from->hwndParent ); + to->cy = from->cy; + to->cx = from->cx; + to->y = from->y; + to->x = from->x; + to->style = from->style; + to->dwExStyle = from->dwExStyle; + to->lpszName = UlongToPtr( from->lpszName ); + to->lpszClass = UlongToPtr( from->lpszClass ); +} + +static void createstruct_64to32( const CREATESTRUCTW *from, CREATESTRUCT32 *to ) +{ + CREATESTRUCT32 cs; + + cs.lpCreateParams = PtrToUlong( from->lpCreateParams ); + cs.hInstance = PtrToUlong( from->hInstance ); + cs.hMenu = HandleToUlong( from->hMenu ); + cs.hwndParent = HandleToUlong( from->hwndParent ); + cs.cy = from->cy; + cs.cx = from->cx; + cs.y = from->y; + cs.x = from->x; + cs.style = from->style; + cs.lpszName = PtrToUlong( from->lpszName ); + cs.lpszClass = PtrToUlong( from->lpszClass ); + cs.dwExStyle = from->dwExStyle; + memcpy( to, &cs, sizeof(cs) ); +} + +static void winpos_32to64( WINDOWPOS *dst, const WINDOWPOS32 *src ) +{ + dst->hwnd = LongToHandle( src->hwnd ); + dst->hwndInsertAfter = LongToHandle( src->hwndInsertAfter ); + dst->x = src->x; + dst->y = src->y; + dst->cx = src->cx; + dst->cy = src->cy; + dst->flags = src->flags; +} + +static void winpos_64to32( const WINDOWPOS *src, WINDOWPOS32 *dst ) +{ + WINDOWPOS32 wp; + + wp.hwnd = HandleToUlong( src->hwnd ); + wp.hwndInsertAfter = HandleToUlong( src->hwndInsertAfter ); + wp.x = src->x; + wp.y = src->y; + wp.cx = src->cx; + wp.cy = src->cy; + wp.flags = src->flags; + memcpy( dst, &wp, sizeof(wp) ); +} + +static PAINTSTRUCT *paintstruct_32to64( PAINTSTRUCT *ps, const PAINTSTRUCT32 *ps32 ) +{ + if (!ps32) return NULL; + ps->hdc = ULongToHandle( ps32->hdc ); + ps->fErase = ps32->fErase; + ps->rcPaint = ps32->rcPaint; + ps->fRestore = ps32->fRestore; + ps->fIncUpdate = ps32->fIncUpdate; + return ps; +} + +#ifndef __REACTOS__ +static MOUSEHOOKSTRUCTEX32 *mousehookstruct_64to32( const MOUSEHOOKSTRUCTEX *hook64, + MOUSEHOOKSTRUCTEX32 *hook32 ) +{ + MOUSEHOOKSTRUCTEX32 hook; + + if (!hook64) return NULL; + +#ifndef __REACTOS__ + hook.pt = hook64->pt; + hook.hwnd = HandleToUlong( hook64->hwnd ); + hook.wHitTestCode = hook64->wHitTestCode; + hook.dwExtraInfo = hook64->dwExtraInfo; + hook.mouseData = hook64->mouseData; + memcpy( hook32, &hook, sizeof(hook) ); +#else + const MOUSEHOOKSTRUCT* hook64cast = (const MOUSEHOOKSTRUCT*)hook64; + + hook.pt = hook64cast->pt; + hook.hwnd = HandleToUlong( hook64cast->hwnd ); + hook.wHitTestCode = hook64cast->wHitTestCode; + hook.dwExtraInfo = hook64cast->dwExtraInfo; + hook.mouseData = hook64->mouseData; + memcpy( hook32, &hook, sizeof(hook) ); +#endif + return hook32; +} + +static NTSTATUS dispatch_callback( ULONG id, void *args, ULONG len ) +{ + void *ret_ptr; + ULONG ret_len; + NTSTATUS status = Wow64KiUserCallbackDispatcher( id, args, len, &ret_ptr, &ret_len ); + return NtCallbackReturn( ret_ptr, ret_len, status ); +} + +static NTSTATUS WINAPI wow64_NtUserCallEnumDisplayMonitor( void *arg, ULONG size ) +{ + struct enum_display_monitor_params *params = arg; + struct + { + ULONG proc; + ULONG monitor; + ULONG hdc; + RECT rect; + ULONG lparam; + } params32; + + params32.proc = PtrToUlong( params->proc ); + params32.monitor = HandleToUlong( params->monitor ); + params32.hdc = HandleToUlong( params->hdc ); + params32.rect = params->rect; + params32.lparam = params->lparam; + return dispatch_callback( NtUserCallEnumDisplayMonitor, ¶ms32, sizeof(params32) ); +} + +static NTSTATUS WINAPI wow64_NtUserCallSendAsyncCallback( void *arg, ULONG size ) +{ + struct send_async_params *params = arg; + struct + { + ULONG callback; + ULONG hwnd; + UINT msg; + ULONG data; + ULONG result; + } params32; + + params32.callback = PtrToUlong( params->callback ); + params32.hwnd = HandleToUlong( params->hwnd ); + params32.msg = params->msg; + params32.data = params->data; + params32.result = params->result; + return dispatch_callback( NtUserCallSendAsyncCallback, ¶ms32, sizeof(params32) ); +} + +static NTSTATUS WINAPI wow64_NtUserCallWinEventHook( void *arg, ULONG size ) +{ + struct win_event_hook_params *params = arg; + struct win_event_hook_params32 params32; + + params32.event = params->event; + params32.hwnd = HandleToUlong( params->hwnd ); + params32.object_id = params->object_id; + params32.child_id = params->child_id; + params32.handle = HandleToUlong( params->handle ); + params32.tid = params->tid; + params32.time = params->time; + params32.proc = PtrToUlong( params->proc ); + + size -= FIELD_OFFSET( struct win_event_hook_params, module ); + if (size) memcpy( params32.module, params->module, size ); + return dispatch_callback( NtUserCallWinEventHook, ¶ms32, + FIELD_OFFSET( struct win_event_hook_params32, module ) + size); +} +#endif + +static size_t packed_message_64to32( UINT message, WPARAM wparam, + const void *params64, void *params32, size_t size ) +{ + if (!size) return 0; + + switch (message) + { + case WM_NCCREATE: + case WM_CREATE: + { + CREATESTRUCT32 *cs32 = params32; + const CREATESTRUCTW *cs64 = params64; + + createstruct_64to32( cs64, cs32 ); + size -= sizeof(*cs64); +#ifndef __REACTOS__ + if (size) memmove( cs32 + 1, cs64 + 1, size ); +#else + if (size) + { + memmove(cs32 + 1, cs64 + 1, size); + cs32->lpszClass -= sizeof(*cs64) - sizeof(*cs32); + cs32->lpszName -= sizeof(*cs64) - sizeof(*cs32); + } +#endif + return sizeof(*cs32) + size; + } + + case WM_NCCALCSIZE: + if (wparam) + { + NCCALCSIZE_PARAMS32 ncp32; + const NCCALCSIZE_PARAMS *ncp64 = params64; + + ncp32.rgrc[0] = ncp64->rgrc[0]; + ncp32.rgrc[1] = ncp64->rgrc[1]; + ncp32.rgrc[2] = ncp64->rgrc[2]; + winpos_64to32( (const WINDOWPOS *)(ncp64 + 1), + (WINDOWPOS32 *)((const char *)params32 + sizeof(ncp32)) ); + memcpy( params32, &ncp32, sizeof(ncp32) ); + return sizeof(ncp32) + sizeof(WINDOWPOS32); + } + break; + + case WM_DRAWITEM: + { + DRAWITEMSTRUCT32 dis32; + const DRAWITEMSTRUCT *dis64 = params64; + + dis32.CtlType = dis64->CtlType; + dis32.CtlID = dis64->CtlID; + dis32.itemID = dis64->itemID; + dis32.itemAction = dis64->itemAction; + dis32.itemState = dis64->itemState; + dis32.hwndItem = HandleToLong( dis64->hwndItem ); + dis32.hDC = HandleToUlong( dis64->hDC ); + dis32.itemData = dis64->itemData; + dis32.rcItem.left = dis64->rcItem.left; + dis32.rcItem.top = dis64->rcItem.top; + dis32.rcItem.right = dis64->rcItem.right; + dis32.rcItem.bottom = dis64->rcItem.bottom; + memcpy( params32, &dis32, sizeof(dis32) ); + return sizeof(dis32); + } + + case WM_MEASUREITEM: + { + MEASUREITEMSTRUCT32 mis32; + const MEASUREITEMSTRUCT *mis64 = params64; + + mis32.CtlType = mis64->CtlType; + mis32.CtlID = mis64->CtlID; + mis32.itemID = mis64->itemID; + mis32.itemWidth = mis64->itemWidth; + mis32.itemHeight = mis64->itemHeight; + mis32.itemData = mis64->itemData; + memcpy( params32, &mis32, sizeof(mis32) ); + return sizeof(mis32); + } + + case WM_DELETEITEM: + { + DELETEITEMSTRUCT32 dis32; + const DELETEITEMSTRUCT *dis64 = params64; + + dis32.CtlType = dis64->CtlType; + dis32.CtlID = dis64->CtlID; + dis32.itemID = dis64->itemID; + dis32.hwndItem = HandleToLong( dis64->hwndItem ); + dis32.itemData = dis64->itemData; + memcpy( params32, &dis32, sizeof(dis32) ); + return sizeof(dis32); + } + + case WM_COMPAREITEM: + { + COMPAREITEMSTRUCT32 cis32; + const COMPAREITEMSTRUCT *cis64 = params64; + + cis32.CtlType = cis64->CtlType; + cis32.CtlID = cis64->CtlID; + cis32.hwndItem = HandleToLong( cis64->hwndItem ); + cis32.itemID1 = cis64->itemID1; + cis32.itemData1 = cis64->itemData1; + cis32.itemID2 = cis64->itemID2; + cis32.itemData2 = cis64->itemData2; + cis32.dwLocaleId = cis64->dwLocaleId; + memcpy( params32, &cis32, sizeof(cis32) ); + return sizeof(cis32); + } + + case WM_WINDOWPOSCHANGING: + case WM_WINDOWPOSCHANGED: + winpos_64to32( params64, params32 ); + return sizeof(WINDOWPOS32); + + case WM_COPYDATA: + { + COPYDATASTRUCT32 cds32; + const COPYDATASTRUCT *cds64 = params64; + + cds32.dwData = cds64->dwData; + cds32.cbData = cds64->cbData; + cds32.lpData = PtrToUlong( cds64->lpData ); + memcpy( params32, &cds32, sizeof(cds32) ); + size -= sizeof(cds32); + if (size) memmove( (char *)params32 + sizeof(cds32), cds64 + 1, size ); + return sizeof(cds32) + size; + } + case WM_HELP: + { + HELPINFO32 hi32; + const HELPINFO *hi64 = params64; + + hi32.cbSize = sizeof(hi32); + hi32.iContextType = hi64->iContextType; + hi32.iCtrlId = hi64->iCtrlId; + hi32.hItemHandle = HandleToLong( hi64->hItemHandle ); + hi32.dwContextId = hi64->dwContextId; + hi32.MousePos = hi64->MousePos; + memcpy( params32, &hi32, sizeof(hi32) ); + return sizeof(hi32); + } + + case WM_GETDLGCODE: + msg_64to32( params64, params32 ); + return sizeof(MSG32); + + case WM_NEXTMENU: + { + MDINEXTMENU32 *next32 = params32; + const MDINEXTMENU *next64 = params64; + + next32->hmenuIn = HandleToLong( next64->hmenuIn ); + next32->hmenuNext = HandleToLong( next64->hmenuNext ); + next32->hwndNext = HandleToLong( next64->hwndNext ); + return sizeof(*next32); + } + + case WM_MDICREATE: + { + MDICREATESTRUCT32 mcs32; + const MDICREATESTRUCTW *mcs64 = params64; + + mcs32.szClass = PtrToUlong( mcs64->szClass ); + mcs32.szTitle = PtrToUlong( mcs64->szTitle ); + mcs32.hOwner = HandleToLong( mcs64->hOwner ); + mcs32.x = mcs64->x; + mcs32.y = mcs64->y; + mcs32.cx = mcs64->cx; + mcs32.cy = mcs64->cy; + mcs32.style = mcs64->style; + mcs32.lParam = mcs64->lParam; + size -= sizeof(*mcs64); + if (size) memmove( (char *)params32 + sizeof(mcs32), mcs64 + 1, size ); + memcpy( params32, &mcs32, sizeof(mcs32) ); + return sizeof(mcs32) + size; + } + + case CB_GETCOMBOBOXINFO: + { + COMBOBOXINFO32 ci32; + const COMBOBOXINFO *ci64 = params64; + + ci32.cbSize = sizeof(ci32); + ci32.rcItem = ci64->rcItem; + ci32.rcButton = ci64->rcButton; + ci32.stateButton = ci64->stateButton; + ci32.hwndCombo = HandleToLong( ci64->hwndCombo ); + ci32.hwndItem = HandleToLong( ci64->hwndItem ); + ci32.hwndList = HandleToLong( ci64->hwndList ); + memcpy( params32, &ci32, sizeof(ci32) ); + return sizeof(ci32); + } + } + + memmove( params32, params64, size ); + return size; +} + +#ifndef __REACTOS__ +static size_t packed_result_32to64( UINT message, WPARAM wparam, const void *params32, + size_t size, void *params64 ) +#else +static size_t packed_message_32to64(UINT message, + WPARAM wparam, + void *params64, + const void *params32, + size_t size) +#endif +{ + if (!size) return 0; + + switch (message) + { + case WM_NCCREATE: + case WM_CREATE: + if (size >= sizeof(CREATESTRUCT32)) + { + const CREATESTRUCT32 *cs32 = params32; +#ifndef __REACTOS__ + CREATESTRUCTW *cs64 = params64; +#else + /* Due to how it was implemented in Wine, these fields could + overlap! ReactOS returns the same address it was given for WndProc, + so fields of these structures do overlap. This goes for all the + cases here. */ + CREATESTRUCT cs64Data; + CREATESTRUCT *cs64 = &cs64Data, *outCs64 = params64; +#endif + + cs64->lpCreateParams = UlongToPtr( cs32->lpCreateParams ); + cs64->hInstance = UlongToPtr( cs32->hInstance ); + cs64->hMenu = LongToHandle( cs32->hMenu ); + cs64->hwndParent = LongToHandle( cs32->hwndParent ); + cs64->cy = cs32->cy; + cs64->cx = cs32->cx; + cs64->y = cs32->y; + cs64->x = cs32->x; + cs64->style = cs32->style; + cs64->dwExStyle = cs32->dwExStyle; +#ifdef __REACTOS__ + *outCs64 = cs64Data; +#endif + return sizeof(*cs64); + } + break; + + case WM_NCCALCSIZE: + if (wparam) + { + const NCCALCSIZE_PARAMS32 *ncp32 = params32; +#ifndef __REACTOS__ + NCCALCSIZE_PARAMS *ncp64 = params64; +#else + NCCALCSIZE_PARAMS ncp64Data, *ncp64 = &ncp64Data, *outNcp64 = params64; + WINDOWPOS32 windowPos32 = *(const WINDOWPOS32 *)(ncp32 + 1); +#endif + ncp64->rgrc[0] = ncp32->rgrc[0]; + ncp64->rgrc[1] = ncp32->rgrc[1]; + ncp64->rgrc[2] = ncp32->rgrc[2]; +#ifndef __REACTOS__ + winpos_32to64( (WINDOWPOS *)(ncp64 + 1), (const WINDOWPOS32 *)(ncp32 + 1) ); +#else + winpos_32to64((WINDOWPOS *)(outNcp64 + 1), &windowPos32); + *outNcp64 = ncp64Data; +#endif + return sizeof(*ncp64) + sizeof(WINDOWPOS); + } + break; + + case WM_MEASUREITEM: + { + const MEASUREITEMSTRUCT32 *mis32 = params32; +#ifndef __REACTOS__ + MEASUREITEMSTRUCT *mis64 = params64; +#else + MEASUREITEMSTRUCT mis64Data, *mis64 = &mis64Data, *outMis64 = params64; +#endif + + mis64->CtlType = mis32->CtlType; + mis64->CtlID = mis32->CtlID; + mis64->itemID = mis32->itemID; + mis64->itemWidth = mis32->itemWidth; + mis64->itemHeight = mis32->itemHeight; + mis64->itemData = mis32->itemData; +#ifdef __REACTOS__ + *outMis64 = mis64Data; +#endif + return sizeof(*mis64); + } + + case WM_WINDOWPOSCHANGING: + case WM_WINDOWPOSCHANGED: +#ifndef __REACTOS__ + winpos_32to64( params64, params32 ); + return sizeof(WINDOWPOS); +#else + WINDOWPOS wpos64, *outWpos64 = params64; + winpos_32to64(&wpos64, params32); + *outWpos64 = wpos64; + return sizeof(WINDOWPOS); +#endif + + case WM_NEXTMENU: + { + const MDINEXTMENU32 *next32 = params32; +#ifndef __REACTOS__ + MDINEXTMENU *next64 = params64; +#else + MDINEXTMENU next64Data, *next64 = &next64Data, *outNext64 = params64; +#endif + + next64->hmenuIn = LongToHandle( next32->hmenuIn ); + next64->hmenuNext = LongToHandle( next32->hmenuNext ); + next64->hwndNext = LongToHandle( next32->hwndNext ); +#ifdef __REACTOS__ + *outNext64 = next64Data; +#endif + return sizeof(*next64); + } + + case CB_GETCOMBOBOXINFO: + { + const COMBOBOXINFO32 *ci32 = params32; +#ifndef __REACTOS__ + COMBOBOXINFO *ci64 = params64; +#else + COMBOBOXINFO ci64Data, *ci64 = &ci64Data, *outCi64 = params64; +#endif + + ci64->cbSize = sizeof(*ci32); + ci64->rcItem = ci32->rcItem; + ci64->rcButton = ci32->rcButton; + ci64->stateButton = ci32->stateButton; + ci64->hwndCombo = LongToHandle( ci32->hwndCombo ); + ci64->hwndItem = LongToHandle( ci32->hwndItem ); + ci64->hwndList = LongToHandle( ci32->hwndList ); +#ifdef __REACTOS__ + *outCi64 = ci64Data; +#endif + return sizeof(*ci64); + } + + case WM_GETTEXT: + case WM_ASKCBFORMATNAME: + case WM_GETMINMAXINFO: + case WM_STYLECHANGING: + case SBM_SETSCROLLINFO: + case SBM_GETSCROLLINFO: + case SBM_GETSCROLLBARINFO: + case EM_GETSEL: + case SBM_GETRANGE: + case CB_GETEDITSEL: + case EM_SETRECT: + case EM_GETRECT: + case EM_SETRECTNP: + case LB_GETITEMRECT: + case CB_GETDROPPEDCONTROLRECT: + case EM_GETLINE: + case CB_GETLBTEXT: + case LB_GETTEXT: + case LB_GETSELITEMS: + case WM_SIZING: + case WM_MOVING: + case WM_MDIGETACTIVE: + break; + + default: + return 0; + } + +#ifndef __REACTOS__ + if (size) memcpy( params64, params32, size ); +#else + /* Parameter buffers most likely overlap because of how this was + implemented in Wine */ + if (size) memmove(params64, params32, size); +#endif + return size; +} + +NTSTATUS WINAPI wow64_NtUserCallWinProc( void *arg, ULONG size ) +{ +#ifndef __REACTOS__ + struct win_proc_params *params = arg; + struct win_proc_params32 *params32 = arg; +#else + PWINDOWPROC_CALLBACK_ARGUMENTS params = arg; + PWINDOWPROC_CALLBACK_ARGUMENTS32 params32 = arg; +#endif + size_t lparam_size = 0, offset32 = sizeof(*params32); +#ifndef __REACTOS__ + LRESULT result = 0; +#endif + void *ret_ptr; + ULONG ret_len; + NTSTATUS status; + +#ifndef __REACTOS__ + win_proc_params_64to32( params, params32 ); +#else + WndProcParams64To32(params, params32); +#endif + if (size > sizeof(*params)) + { + const size_t offset64 = (sizeof(*params) + 15) & ~15; + offset32 = (offset32 + 15) & ~15; +#ifndef __REACTOS__ + lparam_size = packed_message_64to32( params32->msg, params32->wparam, +#else + lparam_size = packed_message_64to32( params32->Msg, params32->wParam, +#endif + (char *)params + offset64, + (char *)params32 + offset32, + size - offset64 ); + } + +#ifndef __REACTOS__ + status = Wow64KiUserCallbackDispatcher( NtUserCallWinProc, params32, +#else + if (params32->lParamBufferSize >= 0) + { + params32->lParamBufferSize = lparam_size; + } + + status = Wow64KiUserCallbackDispatcher( NumUser32CallWindowProcFromKernel, params32, +#endif + offset32 + lparam_size, + &ret_ptr, &ret_len ); + +#ifndef __REACTOS__ + if (ret_len >= sizeof(LONG)) + { + LRESULT *result_ptr = arg; + result = *(LONG *)ret_ptr; + ret_len = packed_result_32to64( params32->msg, params32->wparam, (LONG *)ret_ptr + 1, + ret_len - sizeof(LONG), result_ptr + 1 ); + *result_ptr = result; + return NtCallbackReturn( result_ptr, sizeof(*result_ptr) + ret_len, status ); + } + + return NtCallbackReturn( &result, sizeof(result), status ); +#else + const size_t offset64 = (sizeof(*params) + 15) & ~15; + ret_len = packed_message_32to64(params32->Msg, params32->wParam, + (char *)params + offset64, + (char *)params32 + offset32, + size - offset64); + + ret_len += offset64; + + WndProcParams32To64(params, params32); + + return NtCallbackReturn(ret_ptr, ret_len, status); +#endif +} + +#ifndef __REACTOS__ +static UINT hook_lparam_64to32( int id, int code, const void *lp, size_t size, void *lp32 ) +{ + if (!size) return 0; + + switch (id) + { + case WH_SYSMSGFILTER: + case WH_MSGFILTER: + case WH_GETMESSAGE: + msg_64to32( lp, lp32 ); + return sizeof(MSG32); + + case WH_CBT: + switch (code) + { + case HCBT_CREATEWND: + return packed_message_64to32( WM_CREATE, 0, lp, lp32, size ); + + case HCBT_ACTIVATE: + { + const CBTACTIVATESTRUCT *cbt = lp; + CBTACTIVATESTRUCT32 cbt32; + cbt32.fMouse = cbt->fMouse; + cbt32.hWndActive = HandleToUlong( cbt->hWndActive ); + memcpy( lp32, &cbt32, sizeof(cbt32) ); + return sizeof(cbt32); + } + + case HCBT_CLICKSKIPPED: + mousehookstruct_64to32( lp, lp32 ); + return sizeof(MOUSEHOOKSTRUCTEX32); + } + break; + + case WH_CALLWNDPROC: + { + const CWPSTRUCT *cwp = lp; + CWPSTRUCT32 cwp32; + cwp32.lParam = cwp->lParam; + cwp32.wParam = cwp->wParam; + cwp32.message = cwp->message; + cwp32.hwnd = HandleToUlong( cwp->hwnd ); + memcpy( lp32, &cwp32, sizeof(cwp32) ); + if (size > sizeof(*cwp)) + { + const size_t offset64 = (sizeof(*cwp) + 15) & ~15; + const size_t offset32 = (sizeof(cwp32) + 15) & ~15; + size = packed_message_64to32( cwp32.message, cwp32.wParam, + (const char *)lp + offset64, + (char *)lp32 + offset32, size - offset64 ); + return offset32 + size; + } + return sizeof(cwp32); + } + + case WH_CALLWNDPROCRET: + { + const CWPRETSTRUCT *cwpret = lp; + CWPRETSTRUCT32 cwpret32; + cwpret32.lResult = cwpret->lResult; + cwpret32.lParam = cwpret->lParam; + cwpret32.wParam = cwpret->wParam; + cwpret32.message = cwpret->message; + cwpret32.hwnd = HandleToUlong( cwpret->hwnd ); + memcpy( lp32, &cwpret32, sizeof(cwpret32) ); + if (size > sizeof(*cwpret)) + { + const size_t offset64 = (sizeof(*cwpret) + 15) & ~15; + const size_t offset32 = (sizeof(cwpret32) + 15) & ~15; + size = packed_message_64to32( cwpret32.message, cwpret32.wParam, + (const char *)lp + offset64, + (char *)lp32 + offset32, size - offset64 ); + return offset32 + size; + } + return sizeof(cwpret32); + } + + case WH_MOUSE: + mousehookstruct_64to32( lp, lp32 ); + return sizeof(MOUSEHOOKSTRUCTEX32); + + case WH_MOUSE_LL: + { + const MSLLHOOKSTRUCT *hook = lp; + MSLLHOOKSTRUCT32 hook32; + hook32.pt = hook->pt; + hook32.mouseData = hook->mouseData; + hook32.flags = hook->flags; + hook32.time = hook->time; + hook32.dwExtraInfo = hook->dwExtraInfo; + memcpy( lp32, &hook32, sizeof(hook32) ); + return sizeof(hook32); + } + + case WH_KEYBOARD_LL: + { + const KBDLLHOOKSTRUCT *hook = lp; + KBDLLHOOKSTRUCT32 hook32; + hook32.vkCode = hook->vkCode; + hook32.scanCode = hook->scanCode; + hook32.flags = hook->flags; + hook32.time = hook->time; + hook32.dwExtraInfo = hook->dwExtraInfo; + memcpy( lp32, &hook32, sizeof(hook32) ); + return sizeof(hook32); + } + + case WH_JOURNALRECORD: + { + const EVENTMSG *event = lp; + EVENTMSG32 event32; + + event32.message = event->message; + event32.paramL = event->paramL; + event32.paramH = event->paramH; + event32.time = event->time; + event32.hwnd = HandleToUlong( event->hwnd ); + memcpy( lp32, &event32, sizeof(event32) ); + return sizeof(event32); + } + } + + memmove( lp32, lp, size ); + return size; +} + +#ifndef __REACTOS__ +static NTSTATUS WINAPI wow64_NtUserCallWindowsHook( void *arg, ULONG size ) +{ + struct win_hook_params *params = arg; + struct win_hook_params32 params32; + UINT module_len, size32, offset; + void *ret_ptr; + LRESULT *result_ptr = arg; + ULONG ret_len, ret_size = 0; + NTSTATUS status; + + module_len = wcslen( params->module ); + size32 = FIELD_OFFSET( struct win_hook_params32, module[module_len + 1] ); + offset = FIELD_OFFSET( struct win_hook_params, module[module_len + 1] ); + + params32.proc = PtrToUlong( params->proc ); + params32.handle = HandleToUlong( params->handle ); + params32.pid = params->pid; + params32.tid = params->tid; + params32.id = params->id; + params32.code = params->code; + params32.wparam = params->wparam; + params32.lparam = params->lparam; + params32.prev_unicode = params->prev_unicode; + params32.next_unicode = params->next_unicode; + memcpy( arg, ¶ms32, FIELD_OFFSET( struct win_hook_params32, module )); + memmove( ((struct win_hook_params32 *)arg)->module, params->module, + (module_len + 1) * sizeof(WCHAR) ); + + if (size > offset) + { + size32 = (size32 + 15) & ~15; + offset = (offset + 15) & ~15; + size32 += hook_lparam_64to32( params32.id, params32.code, (char *)params + offset, + size - offset, (char *)arg + size32 ); + } + + status = Wow64KiUserCallbackDispatcher( NtUserCallWindowsHook, arg, size32, &ret_ptr, &ret_len ); + if (status || ret_len < sizeof(LONG)) return status; + + switch (params32.id) + { + case WH_SYSMSGFILTER: + case WH_MSGFILTER: + case WH_GETMESSAGE: + if (ret_len == sizeof(MSG32) + sizeof(LONG)) + { + msg_32to64( (MSG *)(result_ptr + 1), (MSG32 *)((LONG *)ret_ptr + 1) ); + ret_size = sizeof(MSG); + } + break; + } + *result_ptr = *(LONG *)ret_ptr; + return NtCallbackReturn( result_ptr, sizeof(*result_ptr) + ret_size, status ); +} + +static NTSTATUS WINAPI wow64_NtUserCopyImage( void *arg, ULONG size ) +{ + struct copy_image_params *params = arg; + void *ret_ptr; + ULONG ret_len; + NTSTATUS status; + struct + { + ULONG hwnd; + UINT type; + INT dx; + INT dy; + UINT flags; + } params32; + + params32.hwnd = HandleToUlong( params->hwnd ); + params32.type = params->type; + params32.dx = params->dx; + params32.dy = params->dy; + params32.flags = params->flags; + status = Wow64KiUserCallbackDispatcher( NtUserCopyImage, ¶ms32, sizeof(params32), + &ret_ptr, &ret_len ); + if (!status && ret_len == sizeof(ULONG)) + { + HANDLE handle = ULongToHandle( *(ULONG *)ret_ptr ); + return NtCallbackReturn( &handle, sizeof(handle), status ); + } + return status; +} + +static NTSTATUS WINAPI wow64_NtUserDrawNonClientButton( void *arg, ULONG size ) +{ + struct draw_non_client_button_params *params = arg; + struct + { + ULONG hwnd; + ULONG hdc; + enum NONCLIENT_BUTTON_TYPE type; + RECT rect; + BOOL down; + BOOL grayed; + } params32; + + params32.hwnd = HandleToUlong( params->hwnd ); + params32.hdc = HandleToUlong( params->hdc ); + params32.type = params->type; + params32.rect = params->rect; + params32.down = params->down; + params32.grayed = params->grayed; + return dispatch_callback( NtUserDrawNonClientButton, ¶ms32, sizeof(params32) ); +} + +static NTSTATUS WINAPI wow64_NtUserDrawScrollBar( void *arg, ULONG size ) +{ + struct draw_scroll_bar_params *params = arg; + struct + { + ULONG hwnd; + ULONG hdc; + INT bar; + UINT hit_test; + struct + { + ULONG win; + INT bar; + INT thumb_pos; + INT thumb_val; + BOOL vertical; + enum SCROLL_HITTEST hit_test; + } tracking_info; + BOOL arrows; + BOOL interior; + RECT rect; + UINT enable_flags; + INT arrow_size; + INT thumb_pos; + INT thumb_size; + BOOL vertical; + } params32; + + params32.hwnd = HandleToUlong( params->hwnd ); + params32.hdc = HandleToUlong( params->hdc ); + params32.bar = params->bar; + params32.hit_test = params->hit_test; + params32.tracking_info.win = HandleToUlong( params->tracking_info.win ); + params32.tracking_info.bar = params->tracking_info.bar; + params32.tracking_info.thumb_pos = params->tracking_info.thumb_pos; + params32.tracking_info.thumb_val = params->tracking_info.thumb_val; + params32.tracking_info.vertical = params->tracking_info.vertical; + params32.tracking_info.hit_test = params->tracking_info.hit_test; + params32.arrows = params->arrows; + params32.interior = params->interior; + params32.rect = params->rect; + params32.enable_flags = params->enable_flags; + params32.arrow_size = params->arrow_size; + params32.thumb_pos = params->thumb_pos; + params32.thumb_size = params->thumb_size; + params32.vertical = params->vertical; + return dispatch_callback( NtUserDrawScrollBar, ¶ms32, sizeof(params32) ); +} + +static NTSTATUS WINAPI wow64_NtUserDrawText( void *arg, ULONG size ) +{ + struct draw_text_params *params = arg; + struct draw_text_params32 *params32; + ULONG offset = offsetof( struct draw_text_params, str ) - offsetof( struct draw_text_params32, str ); + + params32 = (struct draw_text_params32 *)((char *)params + offset); + params32->flags = params->flags; + params32->rect = params->rect; + params32->count = params->count; + params32->hdc = HandleToUlong( params->hdc ); + return dispatch_callback( NtUserDrawText, params32, size - offset ); +} +#endif + +static NTSTATUS WINAPI wow64_NtUserFreeCachedClipboardData( void *arg, ULONG size ) +{ + struct free_cached_data_params *params = arg; + struct + { + UINT format; + ULONG handle; + } params32; + + params32.format = params->format; + params32.handle = HandleToUlong( params->handle ); + return dispatch_callback( NtUserFreeCachedClipboardData, ¶ms32, sizeof(params32) ); +} + +static NTSTATUS WINAPI wow64_NtUserImmProcessKey( void *arg, ULONG size ) +{ + struct imm_process_key_params *params = arg; + struct + { + ULONG hwnd; + ULONG hkl; + UINT vkey; + ULONG key_data; + } params32; + + params32.hwnd = HandleToUlong( params->hwnd ); + params32.hkl = HandleToUlong( params->hkl ); + params32.vkey = params->vkey; + params32.key_data = params->key_data; + return dispatch_callback( NtUserImmProcessKey, ¶ms32, sizeof(params32) ); +} + +static NTSTATUS WINAPI wow64_NtUserImmTranslateMessage( void *arg, ULONG size ) +{ + struct imm_translate_message_params *params = arg; + struct + { + LONG hwnd; + UINT msg; + LONG wparam; + LONG key_data; + } params32; + + params32.hwnd = HandleToLong( params->hwnd ); + params32.msg = params->msg; + params32.wparam = params->wparam; + params32.key_data = params->key_data; + return dispatch_callback( NtUserImmTranslateMessage, ¶ms32, sizeof(params32) ); +} + +static NTSTATUS WINAPI wow64_NtUserInitBuiltinClasses( void *arg, ULONG size ) +{ + return dispatch_callback( NtUserInitBuiltinClasses, arg, size ); +} + +static NTSTATUS WINAPI wow64_NtUserLoadDriver( void *arg, ULONG size ) +{ + return dispatch_callback( NtUserLoadDriver, arg, size ); +} + +static NTSTATUS WINAPI wow64_NtUserLoadImage( void *arg, ULONG size ) +{ + struct load_image_params *params = arg; + void *ret_ptr; + ULONG ret_len; + NTSTATUS status; + struct + { + ULONG hinst; + ULONG name; + UINT type; + INT dx; + INT dy; + UINT flags; + } params32; + + params32.hinst = PtrToUlong( params->hinst ); + params32.name = PtrToUlong( params->name ); + params32.type = params->type; + params32.dx = params->dx; + params32.dy = params->dy; + params32.flags = params->flags; + status = Wow64KiUserCallbackDispatcher( NtUserLoadImage, ¶ms32, sizeof(params32), + &ret_ptr, &ret_len ); + if (!status && ret_len == sizeof(ULONG)) + { + HANDLE handle = ULongToHandle( *(ULONG *)ret_ptr ); + return NtCallbackReturn( &handle, sizeof(handle), status ); + } + return status; +} + +static NTSTATUS WINAPI wow64_NtUserLoadSysMenu( void *arg, ULONG size ) +{ + void *ret_ptr; + ULONG ret_len; + NTSTATUS status; + + status = Wow64KiUserCallbackDispatcher( NtUserLoadSysMenu, arg, size, &ret_ptr, &ret_len ); + if (!status && ret_len == sizeof(ULONG)) + { + HMENU menu = ULongToHandle( *(ULONG *)ret_ptr ); + return NtCallbackReturn( &menu, sizeof(menu), status ); + } + return status; +} + +static NTSTATUS WINAPI wow64_NtUserPostDDEMessage( void *arg, ULONG size ) +{ + struct post_dde_message_params *params = arg; + struct + { + ULONG hwnd; + UINT msg; + LONG wparam; + LONG lparam; + DWORD dest_tid; + DWORD type; + } params32; + + params32.hwnd = HandleToUlong( params->hwnd ); + params32.msg = params->msg; + params32.wparam = params->wparam; + params32.lparam = params->lparam; + params32.dest_tid = params->dest_tid; + params32.type = params->type; + return dispatch_callback( NtUserPostDDEMessage, ¶ms32, sizeof(params32) ); +} + +static NTSTATUS WINAPI wow64_NtUserRenderSynthesizedFormat( void *arg, ULONG size ) +{ + return dispatch_callback( NtUserRenderSynthesizedFormat, arg, size ); +} + +static NTSTATUS WINAPI wow64_NtUserUnpackDDEMessage( void *arg, ULONG size ) +{ + struct unpack_dde_message_params *params = arg; + struct unpack_dde_message_params32 *params32; + struct unpack_dde_message_result result; + struct + { + LONG wparam; + LONG lparam; + } *result32; + ULONG ret_len; + NTSTATUS status; + + size -= FIELD_OFFSET( struct unpack_dde_message_params, data ); + if (!(params32 = Wow64AllocateTemp( FIELD_OFFSET( struct unpack_dde_message_params32, data[size] )))) + return STATUS_NO_MEMORY; + + params32->hwnd = HandleToUlong( params->hwnd ); + params32->message = params->message; + params32->wparam = params->wparam; + params32->lparam = params->lparam; + if (size) memcpy( params32->data, params->data, size ); + size = FIELD_OFFSET( struct unpack_dde_message_params32, data[size] ); + + status = Wow64KiUserCallbackDispatcher( NtUserUnpackDDEMessage, params32, size, (void **)&result32, &ret_len ); + if (!status && ret_len == sizeof(*result32)) + { + result.wparam = result32->wparam; + result.lparam = result32->lparam; + return NtCallbackReturn( &result, sizeof(result), status ); + } + return status; +} + +static NTSTATUS WINAPI wow64_NtUserCallDispatchCallback( void *arg, ULONG size ) +{ + return dispatch_callback( NtUserCallDispatchCallback, arg, size ); +} + +ntuser_callback user_callbacks[] = +{ + /* user32 callbacks */ + wow64_NtUserCallDispatchCallback, + wow64_NtUserCallEnumDisplayMonitor, + wow64_NtUserCallSendAsyncCallback, + wow64_NtUserCallWinEventHook, + wow64_NtUserCallWinProc, + wow64_NtUserCallWindowsHook, + wow64_NtUserCopyImage, + wow64_NtUserDrawNonClientButton, + wow64_NtUserDrawScrollBar, + wow64_NtUserDrawText, + wow64_NtUserFreeCachedClipboardData, + wow64_NtUserImmProcessKey, + wow64_NtUserImmTranslateMessage, + wow64_NtUserInitBuiltinClasses, + wow64_NtUserLoadDriver, + wow64_NtUserLoadImage, + wow64_NtUserLoadSysMenu, + wow64_NtUserPostDDEMessage, + wow64_NtUserRenderSynthesizedFormat, + wow64_NtUserUnpackDDEMessage, +}; + +C_ASSERT( ARRAYSIZE(user_callbacks) == NtUserCallCount ); + +NTSTATUS WINAPI wow64_NtUserActivateKeyboardLayout( UINT *args ) +{ + HKL layout = get_handle( &args ); + UINT flags = get_ulong( &args ); + + return HandleToUlong( NtUserActivateKeyboardLayout( layout, flags )); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserAddClipboardFormatListener( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + + return NtUserAddClipboardFormatListener( hwnd ); +} +#endif + +NTSTATUS WINAPI wow64_NtUserAssociateInputContext( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + HIMC ctx = get_handle( &args ); + ULONG flags = get_ulong( &args ); + + return NtUserAssociateInputContext( hwnd, ctx, flags ); +} + +NTSTATUS WINAPI wow64_NtUserAttachThreadInput( UINT *args ) +{ + DWORD from = get_ulong( &args ); + DWORD to = get_ulong( &args ); + BOOL attach = get_ulong( &args ); + + return NtUserAttachThreadInput( from, to, attach ); +} +#endif + +NTSTATUS WINAPI wow64_NtUserBeginPaint( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + PAINTSTRUCT32 *ps32 = get_ptr( &args ); + + PAINTSTRUCT ps; + HDC ret; + + ret = NtUserBeginPaint( hwnd, ps32 ? & ps : NULL ); + if (ret && ps32) + { + ps32->hdc = HandleToUlong( ps.hdc ); + ps32->fErase = ps.fErase; + ps32->rcPaint = ps.rcPaint; + } + return HandleToUlong( ret ); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserBuildHimcList( UINT *args ) +{ + ULONG thread_id = get_ulong( &args ); + ULONG count = get_ulong( &args ); + UINT32 *buffer32 = get_ptr( &args ); + UINT *size = get_ptr( &args ); + + HIMC *buffer = NULL; + ULONG i; + NTSTATUS status; + + if (buffer32 && !(buffer = Wow64AllocateTemp( count * sizeof(*buffer) ))) + return STATUS_NO_MEMORY; + + if ((status = NtUserBuildHimcList( thread_id, count, buffer, size ))) return status; + + for (i = 0; i < *size; i++) buffer32[i] = HandleToUlong( buffer[i] ); + return status; +} + +NTSTATUS WINAPI wow64_NtUserBuildHwndList( UINT *args ) +{ + HDESK desktop = get_handle( &args ); + ULONG unk2 = get_ulong( &args ); + ULONG unk3 = get_ulong( &args ); + ULONG unk4 = get_ulong( &args ); + ULONG thread_id = get_ulong( &args ); + ULONG count = get_ulong( &args ); + UINT32 *buffer32 = get_ptr( &args ); + ULONG *size = get_ptr( &args ); + + HWND *buffer; + ULONG i; + NTSTATUS status; + + if (!(buffer = Wow64AllocateTemp( count * sizeof(*buffer) ))) return STATUS_NO_MEMORY; + + if ((status = NtUserBuildHwndList( desktop, unk2, unk3, unk4, thread_id, count, buffer, size ))) + return status; + + for (i = 0; i < *size; i++) + buffer32[i] = HandleToUlong( buffer[i] ); + return status; +} +#endif + +NTSTATUS WINAPI wow64_NtUserCallHwnd( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + DWORD code = get_ulong( &args ); + + return NtUserCallHwnd( hwnd, code ); +} + +NTSTATUS WINAPI wow64_NtUserCallHwndParam( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + DWORD_PTR param = get_ulong( &args ); + DWORD code = get_ulong( &args ); + + switch (code) + { +#ifndef __REACTOS__ + case NtUserCallHwndParam_GetScrollInfo: + { + struct + { + int bar; + ULONG info; + } *info32 = UlongToPtr( param ); + struct get_scroll_info_params info; + + info.bar = info32->bar; + info.info = UlongToPtr( info32->info ); + return NtUserCallHwndParam( hwnd, (UINT_PTR)&info, code ); + } + + case NtUserCallHwndParam_GetWindowRects: + { + struct + { + ULONG rect; + BOOL client; + UINT dpi; + } *params32 = UlongToPtr( param ); + struct get_window_rects_params params; + + params.rect = UlongToPtr( params32->rect ); + params.client = params32->client; + params.dpi = params32->dpi; + return NtUserCallHwndParam( hwnd, (UINT_PTR)¶ms, code ); + } + + case NtUserCallHwndParam_MapWindowPoints: + { + struct + { + ULONG hwnd_to; + ULONG points; + UINT count; + UINT dpi; + } *params32 = UlongToPtr( param ); + struct map_window_points_params params; + + params.hwnd_to = LongToHandle( params32->hwnd_to ); + params.points = UlongToPtr( params32->points ); + params.count = params32->count; + params.dpi = params32->dpi; + return NtUserCallHwndParam( hwnd, (UINT_PTR)¶ms, code ); + } + + case NtUserCallHwndParam_SendHardwareInput: + { + struct + { + UINT flags; + ULONG input; + ULONG lparam; + } *params32 = UlongToPtr( param ); + struct send_hardware_input_params params; + + params.flags = params32->flags; + params.input = UlongToPtr( params32->input ); + params.lparam = params32->lparam; + return NtUserCallHwndParam( hwnd, (UINT_PTR)¶ms, code ); + } +#endif + default: + return NtUserCallHwndParam( hwnd, param, code ); + } +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserCallMsgFilter( UINT *args ) +{ + MSG32 *msg32 = get_ptr( &args ); + INT code = get_ulong( &args ); + MSG msg; + BOOL ret; + + ret = NtUserCallMsgFilter( msg_32to64( &msg, msg32 ), code ); + msg_64to32( &msg, msg32 ); + return ret; +} + +NTSTATUS WINAPI wow64_NtUserCallNextHookEx( UINT *args ) +{ + HHOOK hhook = get_handle( &args ); + INT code = get_ulong( &args ); + WPARAM wparam = get_ulong( &args ); + LPARAM lparam = get_ulong( &args ); + + return NtUserCallNextHookEx( hhook, code, wparam, lparam ); +} +#endif + +NTSTATUS WINAPI wow64_NtUserCallNoParam( UINT *args ) +{ + ULONG code = get_ulong( &args ); + + return NtUserCallNoParam( code ); +} + +NTSTATUS WINAPI wow64_NtUserCallOneParam( UINT *args ) +{ + ULONG_PTR arg = get_ulong( &args ); + ULONG code = get_ulong( &args ); + + return NtUserCallOneParam( arg, code ); +} + +NTSTATUS WINAPI wow64_NtUserCallTwoParam( UINT *args ) +{ + ULONG_PTR arg1 = get_ulong( &args ); + ULONG_PTR arg2 = get_ulong( &args ); + ULONG code = get_ulong( &args ); + + switch (code) + { +#ifndef __REACTOS__ + case NtUserCallTwoParam_GetMenuInfo: + { + MENUINFO32 *info32 = UlongToPtr( arg2 ); + MENUINFO info; + + if (!info32 || info32->cbSize != sizeof(*info32)) + { + set_last_error32( ERROR_INVALID_PARAMETER ); + return FALSE; + } + + info.cbSize = sizeof(info); + info.fMask = info32->fMask; + if (!NtUserCallTwoParam( arg1, (UINT_PTR)&info, code )) return FALSE; + if (info.fMask & MIM_BACKGROUND) info32->hbrBack = HandleToUlong( info.hbrBack ); + if (info.fMask & MIM_HELPID) info32->dwContextHelpID = info.dwContextHelpID; + if (info.fMask & MIM_MAXHEIGHT) info32->cyMax = info.cyMax; + if (info.fMask & MIM_MENUDATA) info32->dwMenuData = info.dwMenuData; + if (info.fMask & MIM_STYLE) info32->dwStyle = info.dwStyle; + return TRUE; + } +#endif + default: + return NtUserCallTwoParam( arg1, arg2, code ); + } +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserChangeClipboardChain( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + HWND next = get_handle( &args ); + + return NtUserChangeClipboardChain( hwnd, next ); +} + +NTSTATUS WINAPI wow64_NtUserChangeDisplaySettings( UINT *args ) +{ + UNICODE_STRING32 *devname32 = get_ptr( &args ); + DEVMODEW *devmode = get_ptr( &args ); + HWND hwnd = get_handle( &args ); + DWORD flags = get_ulong( &args ); + void *lparam = get_ptr( &args ); + + UNICODE_STRING devname; + + return NtUserChangeDisplaySettings( unicode_str_32to64( &devname, devname32 ), + devmode, hwnd, flags, lparam ); +} +#endif + +NTSTATUS WINAPI wow64_NtUserCheckMenuItem( UINT *args ) +{ + HMENU handle = get_handle( &args ); + UINT id = get_ulong( &args ); + UINT flags = get_ulong( &args ); + + return NtUserCheckMenuItem( handle, id, flags ); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserChildWindowFromPointEx( UINT *args ) +{ + HWND parent = get_handle( &args ); + LONG x = get_ulong( &args ); + LONG y = get_ulong( &args ); + UINT flags = get_ulong( &args ); + + return HandleToUlong( NtUserChildWindowFromPointEx( parent, x, y, flags )); +} +#endif + +NTSTATUS WINAPI wow64_NtUserClipCursor( UINT *args ) +{ +#ifndef __REACTOS__ + const RECT *rect = get_ptr( &args ); +#else + RECT *rect = get_ptr(&args); +#endif + + return NtUserClipCursor( rect ); +} + +NTSTATUS WINAPI wow64_NtUserCloseClipboard( UINT *args ) +{ + return NtUserCloseClipboard(); +} + +NTSTATUS WINAPI wow64_NtUserCloseDesktop( UINT *args ) +{ + HDESK handle = get_handle( &args ); + + return NtUserCloseDesktop( handle ); +} + +NTSTATUS WINAPI wow64_NtUserCloseWindowStation( UINT *args ) +{ + HWINSTA handle = get_handle( &args ); + + return NtUserCloseWindowStation( handle ); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserCopyAcceleratorTable( UINT *args ) +{ + HACCEL src = get_handle( &args ); + ACCEL *dst = get_ptr( &args ); + INT count = get_ulong( &args ); + + return NtUserCopyAcceleratorTable( src, dst, count ); +} + +NTSTATUS WINAPI wow64_NtUserCountClipboardFormats( UINT *args ) +{ + return NtUserCountClipboardFormats(); +} +#endif + +NTSTATUS WINAPI wow64_NtUserCreateAcceleratorTable( UINT *args ) +{ + ACCEL *table = get_ptr( &args ); + INT count = get_ulong( &args ); + + return HandleToUlong( NtUserCreateAcceleratorTable( table, count )); +} + +NTSTATUS WINAPI wow64_NtUserCreateCaret( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + HBITMAP bitmap = get_handle( &args ); + int width = get_ulong( &args ); + int height = get_ulong( &args ); + + return NtUserCreateCaret( hwnd, bitmap, width, height ); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserCreateDesktopEx( UINT *args ) +{ + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + UNICODE_STRING32 *device32 = get_ptr( &args ); + DEVMODEW *devmode = get_ptr( &args ); + DWORD flags = get_ulong( &args ); + ACCESS_MASK access = get_ulong( &args ); + ULONG heap_size = get_ulong( &args ); + + struct object_attr64 attr; + UNICODE_STRING device; + HANDLE ret; + + ret = NtUserCreateDesktopEx( objattr_32to64( &attr, attr32 ), + unicode_str_32to64( &device, device32 ), + devmode, flags, access, heap_size ); + return HandleToUlong( ret ); +} + +NTSTATUS WINAPI wow64_NtUserCreateInputContext( UINT *args ) +{ + UINT_PTR client_ptr = get_ulong( &args ); + + return HandleToUlong( NtUserCreateInputContext( client_ptr )); +} +#endif + +NTSTATUS WINAPI wow64_NtUserCreateWindowEx( UINT *args ) +{ + DWORD ex_style = get_ulong( &args ); +#ifndef __REACTOS__ + UNICODE_STRING32 *class_name32 = get_ptr( &args ); + UNICODE_STRING32 *version32 = get_ptr( &args ); + UNICODE_STRING32 *window_name32 = get_ptr( &args ); +#else + LARGE_STRING32* plstrClassName32 = get_ptr(&args); + LARGE_STRING32* plstrVersion32 = get_ptr(&args); + LARGE_STRING32* plstrWindowName32 = get_ptr(&args); +#endif + DWORD style = get_ulong( &args ); + int x = get_ulong( &args ); + int y = get_ulong( &args ); + int width = get_ulong( &args ); + int height = get_ulong( &args ); + HWND parent = get_handle( &args ); + HMENU menu = get_handle( &args ); + HINSTANCE instance = get_ptr( &args ); + void *params = get_ptr( &args ); + DWORD flags = get_ulong( &args ); +#ifndef __REACTOS__ + HINSTANCE client_instance = get_ptr( &args ); + DWORD unk = get_ulong( &args ); + BOOL ansi = get_ulong( &args ); +#else + PVOID pCtx = get_ptr( &args ); +#endif + +#ifndef __REACTOS__ + UNICODE_STRING class_name, version, window_name; +#else + LARGE_STRING lstrClassName, lstrWindowName, lstrVersion; +#endif + HWND ret; + + ret = NtUserCreateWindowEx( ex_style, +#ifndef __REACTOS__ + unicode_str_32to64( &class_name, class_name32 ), + unicode_str_32to64( &version, version32 ), + unicode_str_32to64( &window_name, window_name32 ), +#else + large_str_32to64(&lstrClassName, plstrClassName32), + large_str_32to64(&lstrVersion, plstrVersion32), + large_str_32to64(&lstrWindowName, plstrWindowName32), +#endif + style, x, y, width, height, parent, menu, +#ifndef __REACTOS__ + instance, params, flags, client_instance, unk, ansi ); +#else + instance, params, flags, pCtx); +#endif + return HandleToUlong( ret ); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserCreateWindowStation( UINT *args ) +{ + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args ); + ULONG arg3 = get_ulong( &args ); + ULONG arg4 = get_ulong( &args ); + ULONG arg5 = get_ulong( &args ); + ULONG arg6 = get_ulong( &args ); + ULONG arg7 = get_ulong( &args ); + + struct object_attr64 attr; + + return HandleToUlong( NtUserCreateWindowStation( objattr_32to64( &attr, attr32 ), access, + arg3, arg4, arg5, arg6, arg7 )); +} + +NTSTATUS WINAPI wow64_NtUserDeferWindowPosAndBand( UINT *args ) +{ + HDWP hdwp = get_handle( &args ); + HWND hwnd = get_handle( &args ); + HWND after = get_handle( &args ); + INT x = get_ulong( &args ); + INT y = get_ulong( &args ); + INT cx = get_ulong( &args ); + INT cy = get_ulong( &args ); + UINT flags = get_ulong( &args ); + UINT unk1 = get_ulong( &args ); + UINT unk2 = get_ulong( &args ); + + HDWP ret = NtUserDeferWindowPosAndBand( hdwp, hwnd, after, x, y, cx, cy, flags, unk1, unk2 ); + return HandleToUlong( ret ); +} +#endif + +NTSTATUS WINAPI wow64_NtUserDeleteMenu( UINT *args ) +{ + HMENU menu = get_handle( &args ); + UINT id = get_ulong( &args ); + UINT flags = get_ulong( &args ); + + return NtUserDeleteMenu( menu, id, flags ); +} + +NTSTATUS WINAPI wow64_NtUserDestroyAcceleratorTable( UINT *args ) +{ + HACCEL handle = get_handle( &args ); + + return NtUserDestroyAcceleratorTable( handle ); +} + +NTSTATUS WINAPI wow64_NtUserDestroyCursor( UINT *args ) +{ + HCURSOR cursor = get_handle( &args ); + ULONG arg = get_ulong( &args ); + + return NtUserDestroyCursor( cursor, arg ); +} + +NTSTATUS WINAPI wow64_NtUserDestroyInputContext( UINT *args ) +{ + HIMC handle = get_handle( &args ); + + return NtUserDestroyInputContext( handle ); +} + +NTSTATUS WINAPI wow64_NtUserDestroyMenu( UINT *args ) +{ + HMENU handle = get_handle( &args ); + + return NtUserDestroyMenu( handle ); +} + +NTSTATUS WINAPI wow64_NtUserDestroyWindow( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + + return NtUserDestroyWindow( hwnd ); +} + +NTSTATUS WINAPI wow64_NtUserDisableThreadIme( UINT *args ) +{ + DWORD thread_id = get_ulong( &args ); + + return NtUserDisableThreadIme( thread_id ); +} + +NTSTATUS WINAPI wow64_NtUserDispatchMessage( UINT *args ) +{ + const MSG32 *msg32 = get_ptr( &args ); + MSG msg; + + return NtUserDispatchMessage( msg_32to64( &msg, msg32 )); +} + +NTSTATUS WINAPI wow64_NtUserDragDetect( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + int x = get_ulong( &args ); + int y = get_ulong( &args ); + +#ifndef __REACTOS__ + return NtUserDragDetect( hwnd, x, y ); +#else + POINT p; + p.x = x; + p.y = y; + + return NtUserDragDetect(hwnd, p); +#endif +} + +NTSTATUS WINAPI wow64_NtUserDragObject( UINT *args ) +{ + HWND parent = get_handle( &args ); + HWND hwnd = get_handle( &args ); + UINT fmt = get_ulong( &args ); + ULONG_PTR data = get_ulong( &args ); + HCURSOR hcursor = get_handle( &args ); + + return NtUserDragObject( parent, hwnd, fmt, data, hcursor ); +} + +NTSTATUS WINAPI wow64_NtUserDrawCaptionTemp( UINT *args ) +{ +#ifdef __REACTOS__ +#define const +#endif + HWND hwnd = get_handle( &args ); + HDC hdc = get_handle( &args ); + const RECT *rect = get_ptr( &args ); + HFONT font = get_handle( &args ); + HICON icon = get_handle( &args ); +#ifndef __REACTOS__ + const WCHAR *str = get_ptr( &args ); +#else + PUNICODE_STRING32 str = get_ptr(&args); + UNICODE_STRING str64; +#endif + UINT flags = get_ulong( &args ); +#ifdef __REACTOS__ +#undef const +#endif + +#ifndef __REACTOS__ + return NtUserDrawCaptionTemp( hwnd, hdc, rect, font, icon, str, flags ); +#else + return NtUserDrawCaptionTemp( hwnd, hdc, rect, font, icon, unicode_str_32to64(&str64, str), flags ); +#endif +} + +NTSTATUS WINAPI wow64_NtUserDrawIconEx( UINT *args ) +{ + HDC hdc = get_handle( &args ); + int x0 = get_ulong( &args ); + int y0 = get_ulong( &args ); + HICON icon = get_handle( &args ); + int width = get_ulong( &args ); + int height = get_ulong( &args ); + UINT istep = get_ulong( &args ); + HBRUSH hbr = get_handle( &args ); + UINT flags = get_ulong( &args ); +#ifdef __REACTOS__ + BOOL bMetaHDC = get_ulong( &args ); + typedef struct _DRAWICONEXDATA32 + { + ULONG hbmMask; + ULONG hbmColor; + int cx; + int cy; + } DRAWICONEXDATA32, *PDRAWICONEXDATA32; + PDRAWICONEXDATA32 pDIXData32 = get_ptr( &args ); + + DRAWICONEXDATA DIXData; + + if (pDIXData32 != NULL) + { + DIXData.hbmMask = UlongToHandle(pDIXData32->hbmMask); + DIXData.hbmColor = UlongToHandle(pDIXData32->hbmColor); + DIXData.cx = pDIXData32->cx; + DIXData.cy = pDIXData32->cy; + } + + return NtUserDrawIconEx(hdc, + x0, + y0, + icon, + width, + height, + istep, + hbr, + flags, + bMetaHDC, + (pDIXData32 == NULL) ? NULL : &DIXData); +#else + + return NtUserDrawIconEx( hdc, x0, y0, icon, width, height, istep, hbr, flags ); +#endif +} + +NTSTATUS WINAPI wow64_NtUserDrawMenuBarTemp( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + HDC hdc = get_handle( &args ); + RECT *rect = get_ptr( &args ); + HMENU handle = get_handle( &args ); + HFONT font = get_handle( &args ); + + return NtUserDrawMenuBarTemp( hwnd, hdc, rect, handle, font ); +} + +NTSTATUS WINAPI wow64_NtUserEmptyClipboard( UINT *args ) +{ + return NtUserEmptyClipboard(); +} + +NTSTATUS WINAPI wow64_NtUserEnableMenuItem( UINT *args ) +{ + HMENU handle = get_handle( &args ); + UINT id = get_ulong( &args ); + UINT flags = get_ulong( &args ); + + return NtUserEnableMenuItem( handle, id, flags ); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserEnableMouseInPointer( UINT *args ) +{ + UINT enable = get_ulong( &args ); + + return NtUserEnableMouseInPointer( enable ); +} +#endif + +NTSTATUS WINAPI wow64_NtUserEnableScrollBar( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + UINT bar = get_ulong( &args ); + UINT flags = get_ulong( &args ); + + return NtUserEnableScrollBar( hwnd, bar, flags ); +} + +NTSTATUS WINAPI wow64_NtUserEndDeferWindowPosEx( UINT *args ) +{ + HDWP hdwp = get_handle( &args ); + BOOL async = get_ulong( &args ); + + return NtUserEndDeferWindowPosEx( hdwp, async ); +} + +NTSTATUS WINAPI wow64_NtUserEndMenu( UINT *args ) +{ + return NtUserEndMenu(); +} + +NTSTATUS WINAPI wow64_NtUserEndPaint( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + const PAINTSTRUCT32 *ps32 = get_ptr( &args ); + PAINTSTRUCT ps; + + return NtUserEndPaint( hwnd, paintstruct_32to64( &ps, ps32 )); +} + +NTSTATUS WINAPI wow64_NtUserEnumDisplayDevices( UINT *args ) +{ + UNICODE_STRING32 *device32 = get_ptr( &args ); + DWORD index = get_ulong( &args ); + DISPLAY_DEVICEW *info = get_ptr( &args ); + DWORD flags = get_ulong( &args ); + + UNICODE_STRING device; + + return NtUserEnumDisplayDevices( unicode_str_32to64( &device, device32 ), index, info, flags ); +} + +NTSTATUS WINAPI wow64_NtUserEnumDisplayMonitors( UINT *args ) +{ +#ifndef __REACTOS__ + HDC hdc = get_handle( &args ); + RECT *rect = get_ptr( &args ); + MONITORENUMPROC proc = get_ptr( &args ); + LPARAM lp = get_ulong( &args ); + + return NtUserEnumDisplayMonitors( hdc, rect, proc, lp ); +#else + HDC hDC = get_handle(&args); + LPCRECT pRect = get_ptr(&args); + PULONG ahMonitorList32 = get_ptr(&args); + LPRECT monitorRectList = get_ptr(&args); + DWORD listSize = get_ulong(&args); + HMONITOR* ahMonitorList; + INT iCount, i; + + ahMonitorList = Wow64AllocateTemp(listSize * sizeof(*ahMonitorList)); + + iCount = NtUserEnumDisplayMonitors(hDC, pRect, ahMonitorList, monitorRectList, listSize); + for (i = 0; i < iCount; i++) + { + ahMonitorList32[i] = HandleToUlong(ahMonitorList[i]); + } + + return iCount; +#endif +} + +NTSTATUS WINAPI wow64_NtUserEnumDisplaySettings( UINT *args ) +{ + UNICODE_STRING32 *device32 = get_ptr( &args ); + DWORD mode = get_ulong( &args ); + DEVMODEW *dev_mode = get_ptr( &args ); + DWORD flags = get_ulong( &args ); + + UNICODE_STRING device; + + return NtUserEnumDisplaySettings( unicode_str_32to64( &device, device32 ), + mode, dev_mode, flags ); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserExcludeUpdateRgn( UINT *args ) +{ + HDC hdc = get_handle( &args ); + HWND hwnd = get_handle( &args ); + + return NtUserExcludeUpdateRgn( hdc, hwnd ); +} +#endif + +NTSTATUS WINAPI wow64_NtUserFindExistingCursorIcon( UINT *args ) +{ + UNICODE_STRING32 *module32 = get_ptr( &args ); + UNICODE_STRING32 *res_name32 = get_ptr( &args ); + void *desc = get_ptr( &args ); + + UNICODE_STRING module; + UNICODE_STRING res_name; + HICON ret; + + ret = NtUserFindExistingCursorIcon( unicode_str_32to64( &module, module32 ), + unicode_str_32to64( &res_name, res_name32 ), desc ); + return HandleToUlong( ret ); +} + +NTSTATUS WINAPI wow64_NtUserFindWindowEx( UINT *args ) +{ + HWND parent = get_handle( &args ); + HWND child = get_handle( &args ); + UNICODE_STRING32 *class32 = get_ptr( &args ); + UNICODE_STRING32 *title32 = get_ptr( &args ); + ULONG unk = get_ulong( &args ); + + UNICODE_STRING class, title; + HWND ret; + + ret = NtUserFindWindowEx( parent, child, unicode_str_32to64( &class, class32 ), + unicode_str_32to64( &title, title32 ), unk ); + return HandleToUlong( ret ); +} + + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserFlashWindowEx( UINT *args ) +{ + struct + { + UINT cbSize; + ULONG hwnd; + DWORD dwFlags; + UINT uCount; + DWORD dwTimeout; + } *info32 = get_ptr( &args ); + + FLASHWINFO info; + + if (!info32) + { + set_last_error32( ERROR_NOACCESS ); + return FALSE; + } + + if (info32->cbSize != sizeof(*info32)) + { + set_last_error32( ERROR_INVALID_PARAMETER ); + return FALSE; + } + + info.cbSize = sizeof(info); + info.hwnd = LongToHandle( info32->hwnd ); + info.dwFlags = info32->dwFlags; + info.uCount = info32->uCount; + info.dwTimeout = info32->dwTimeout; + return NtUserFlashWindowEx( &info ); +} +#endif + +NTSTATUS WINAPI wow64_NtUserGetAncestor( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + UINT type = get_ulong( &args ); + + return HandleToUlong( NtUserGetAncestor( hwnd, type )); +} + +NTSTATUS WINAPI wow64_NtUserGetAsyncKeyState( UINT *args ) +{ + INT key = get_ulong( &args ); + + return NtUserGetAsyncKeyState( key ); +} + +NTSTATUS WINAPI wow64_NtUserGetAtomName( UINT *args ) +{ + ATOM atom = get_ulong( &args ); + UNICODE_STRING32 *str32 = get_ptr( &args ); + + UNICODE_STRING str; + + return NtUserGetAtomName( atom, unicode_str_32to64( &str, str32 )); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserGetCaretBlinkTime( UINT *args ) +{ + return NtUserGetCaretBlinkTime(); +} + +NTSTATUS WINAPI wow64_NtUserGetCaretPos( UINT *args ) +{ + POINT *pt = get_ptr( &args ); + + return NtUserGetCaretPos( pt ); +} + +NTSTATUS WINAPI wow64_NtUserGetClassInfoEx( UINT *args ) +{ + HINSTANCE instance = get_ptr( &args ); + UNICODE_STRING32 *name32 = get_ptr( &args ); + WNDCLASSEXW32 *wc32 = get_ptr( &args ); + struct client_menu_name32 *client_name32 = get_ptr( &args ); + BOOL ansi = get_ulong( &args ); + + struct client_menu_name client_name; + UNICODE_STRING name; + WNDCLASSEXW wc; + ATOM ret; + + wc.cbSize = sizeof(wc); + if (!(ret = NtUserGetClassInfoEx( instance, unicode_str_32to64( &name, name32 ), &wc, + &client_name, ansi ))) + return 0; + + wc32->style = wc.style; + wc32->lpfnWndProc = PtrToUlong( wc.lpfnWndProc ); + wc32->cbClsExtra = wc.cbClsExtra; + wc32->cbWndExtra = wc.cbWndExtra; + wc32->hInstance = PtrToUlong( wc.hInstance ); + wc32->hIcon = HandleToUlong( wc.hIcon ); + wc32->hCursor = HandleToUlong( wc.hCursor ); + wc32->hbrBackground = HandleToUlong( wc.hbrBackground ); + wc32->lpszMenuName = PtrToUlong( wc.lpszMenuName ); + wc32->lpszClassName = PtrToUlong( wc.lpszClassName ); + wc32->hIconSm = HandleToUlong( wc.hIconSm ); + + client_menu_name_64to32( &client_name, client_name32 ); + return ret; +} +#endif + +NTSTATUS WINAPI wow64_NtUserGetClassName( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + BOOL real = get_ulong( &args ); + UNICODE_STRING32 *str32 = get_ptr( &args ); + + UNICODE_STRING str; + + return NtUserGetClassName( hwnd, real, unicode_str_32to64( &str, str32 )); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserGetClipboardData( UINT *args ) +{ + UINT format = get_ulong( &args ); + struct + { + UINT32 data; + UINT32 size; + UINT32 data_size; + UINT seqno; + BOOL data_only; + } *params32 = get_ptr( &args ); + + struct get_clipboard_params params; + HANDLE ret; + + params.data = UlongToPtr( params32->data ); + params.size = params32->size; + params.data_size = params32->data_size; + params.data_only = params32->data_only; + + ret = NtUserGetClipboardData( format, ¶ms ); + + params32->size = params.size; + params32->data_size = params.data_size; + params32->seqno = params.seqno; + return HandleToUlong( ret ); +} + +NTSTATUS WINAPI wow64_NtUserGetClipboardFormatName( UINT *args ) +{ + UINT format = get_ulong( &args ); + WCHAR *buffer = get_ptr( &args ); + INT maxlen = get_ulong( &args ); + + return NtUserGetClipboardFormatName( format, buffer, maxlen ); +} + +NTSTATUS WINAPI wow64_NtUserGetClipboardOwner( UINT *args ) +{ + return HandleToUlong( NtUserGetClipboardOwner() ); +} + +NTSTATUS WINAPI wow64_NtUserGetClipboardSequenceNumber( UINT *args ) +{ + return NtUserGetClipboardSequenceNumber(); +} + +NTSTATUS WINAPI wow64_NtUserGetClipboardViewer( UINT *args ) +{ + return HandleToUlong( NtUserGetClipboardViewer() ); +} + +NTSTATUS WINAPI wow64_NtUserGetCursor( UINT *args ) +{ + return HandleToUlong( NtUserGetCursor() ); +} + +NTSTATUS WINAPI wow64_NtUserGetCursorFrameInfo( UINT *args ) +{ + HCURSOR cursor = get_ptr( &args ); + DWORD istep = get_ulong( &args ); + DWORD *rate_jiffies = get_ptr( &args ); + DWORD *num_steps = get_ptr( &args ); + + return HandleToUlong( NtUserGetCursorFrameInfo( cursor, istep, rate_jiffies, num_steps )); +} + +NTSTATUS WINAPI wow64_NtUserGetCursorInfo( UINT *args ) +{ + struct + { + DWORD cbSize; + DWORD flags; + ULONG hCursor; + POINT ptScreenPos; + } *info32 = get_ptr( &args ); + CURSORINFO info; + + if (!info32) return FALSE; + info.cbSize = sizeof(info); + if (!NtUserGetCursorInfo( &info )) return FALSE; + info32->flags = info.flags; + info32->hCursor = HandleToUlong( info.hCursor ); + info32->ptScreenPos = info.ptScreenPos; + return TRUE; +} +#endif + +NTSTATUS WINAPI wow64_NtUserGetDC( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + + return HandleToUlong( NtUserGetDC( hwnd )); +} + +NTSTATUS WINAPI wow64_NtUserGetDCEx( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + HRGN clip_rgn = get_handle( &args ); + DWORD flags = get_ulong( &args ); + + return HandleToUlong( NtUserGetDCEx( hwnd, clip_rgn, flags )); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserGetDisplayConfigBufferSizes( UINT *args ) +{ + UINT32 flags = get_ulong( &args ); + UINT32 *num_path_info = get_ptr( &args ); + UINT32 *num_mode_info = get_ptr( &args ); + + return NtUserGetDisplayConfigBufferSizes( flags, num_path_info, num_mode_info ); +} +#endif + +NTSTATUS WINAPI wow64_NtUserGetDoubleClickTime( UINT *args ) +{ + return NtUserGetDoubleClickTime(); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserGetDpiForMonitor( UINT *args ) +{ + HMONITOR monitor = get_handle( &args ); + UINT type = get_ulong( &args ); + UINT *x = get_ptr( &args ); + UINT *y = get_ptr( &args ); + + return NtUserGetDpiForMonitor( monitor, type, x, y ); +} + +NTSTATUS WINAPI wow64_NtUserGetForegroundWindow( UINT *args ) +{ + return HandleToUlong( NtUserGetForegroundWindow() ); +} + +NTSTATUS WINAPI wow64_NtUserGetGUIThreadInfo( UINT *args ) +{ + DWORD id = get_ulong( &args ); + struct + { + DWORD cbSize; + DWORD flags; + ULONG hwndActive; + ULONG hwndFocus; + ULONG hwndCapture; + ULONG hwndMenuOwner; + ULONG hwndMoveSize; + ULONG hwndCaret; + RECT rcCaret; + } *info32 = get_ptr( &args ); + GUITHREADINFO info; + + if (info32->cbSize != sizeof(*info32)) + { + set_last_error32( ERROR_INVALID_PARAMETER ); + return FALSE; + } + + info.cbSize = sizeof(info); + if (!NtUserGetGUIThreadInfo( id, &info )) return FALSE; + info32->flags = info.flags; + info32->hwndActive = HandleToUlong( info.hwndActive ); + info32->hwndFocus = HandleToUlong( info.hwndFocus ); + info32->hwndCapture = HandleToUlong( info.hwndCapture ); + info32->hwndMenuOwner = HandleToUlong( info.hwndMenuOwner ); + info32->hwndMoveSize = HandleToUlong( info.hwndMoveSize ); + info32->hwndCaret = HandleToUlong( info.hwndCaret ); + info32->rcCaret = info.rcCaret; + return TRUE; +} +#endif + +NTSTATUS WINAPI wow64_NtUserGetIconInfo( UINT *args ) +{ + HICON icon = get_handle( &args ); + struct + { + BOOL fIcon; + DWORD xHotspot; + DWORD yHotspot; + UINT32 hbmMask; + UINT32 hbmColor; + } *info32 = get_ptr( &args ); + UNICODE_STRING32 *module32 = get_ptr( &args ); + UNICODE_STRING32 *res_name32 = get_ptr( &args ); + DWORD *bpp = get_ptr( &args ); + LONG unk = get_ulong( &args ); + + ICONINFO info; + UNICODE_STRING module, res_name; + + if (!NtUserGetIconInfo( icon, &info, unicode_str_32to64( &module, module32 ), + unicode_str_32to64( &res_name, res_name32 ), bpp, unk )) + return FALSE; + +#ifdef __REACTOS__ + if (info32 != NULL) + { +#endif + info32->fIcon = info.fIcon; + info32->xHotspot = info.xHotspot; + info32->yHotspot = info.yHotspot; + info32->hbmMask = HandleToUlong( info.hbmMask ); + info32->hbmColor = HandleToUlong( info.hbmColor ); +#ifdef __REACTOS__ + } +#endif + if (module32) + { + module32->Buffer = PtrToUlong( module.Buffer ); + module32->Length = module.Length; + } + if (res_name32) + { + res_name32->Buffer = PtrToUlong( res_name.Buffer ); + res_name32->Length = res_name.Length; + } + return TRUE; +} + +NTSTATUS WINAPI wow64_NtUserGetIconSize( UINT *args ) +{ + HICON handle = get_handle( &args ); + UINT step = get_ulong( &args ); + LONG *width = get_ptr( &args ); + LONG *height = get_ptr( &args ); + + return NtUserGetIconSize( handle, step, width, height ); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserGetInternalWindowPos( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + RECT *rect = get_ptr( &args ); + POINT *pt = get_ptr( &args ); + + return NtUserGetInternalWindowPos( hwnd, rect, pt ); +} + +NTSTATUS WINAPI wow64_NtUserGetKeyNameText( UINT *args ) +{ + LONG lparam = get_ulong( &args ); + WCHAR *buffer = get_ptr( &args ); + INT size = get_ulong( &args ); + + return NtUserGetKeyNameText( lparam, buffer, size ); +} +#endif + +NTSTATUS WINAPI wow64_NtUserGetKeyState( UINT *args ) +{ + INT vkey = get_ulong( &args ); + + return NtUserGetKeyState( vkey ); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserGetKeyboardLayout( UINT *args ) +{ + DWORD tid = get_ulong( &args ); + + return HandleToUlong( NtUserGetKeyboardLayout( tid )); +} +#endif + +NTSTATUS WINAPI wow64_NtUserGetKeyboardLayoutList( UINT *args ) +{ + INT size = get_ulong( &args ); + UINT32 *layouts32 = get_ptr( &args ); + HKL *layouts = NULL; + UINT ret, i; + + if (layouts32 && size && !(layouts = Wow64AllocateTemp( size * sizeof(*layouts) ))) + return 0; + + ret = NtUserGetKeyboardLayoutList( size, layouts ); + if (layouts) + for (i = 0; i < ret; i++) layouts32[i] = HandleToUlong( layouts[i] ); + return ret; +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserGetKeyboardLayoutName( UINT *args ) +{ + WCHAR *name = get_ptr( &args ); + + return NtUserGetKeyboardLayoutName( name ); +} + +#endif + +NTSTATUS WINAPI wow64_NtUserGetKeyboardState( UINT *args ) +{ + BYTE *state = get_ptr( &args ); + + return NtUserGetKeyboardState( state ); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserGetLayeredWindowAttributes( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + COLORREF *key = get_ptr( &args ); + BYTE *alpha = get_ptr( &args ); + DWORD *flags = get_ptr( &args ); + + return NtUserGetLayeredWindowAttributes( hwnd, key, alpha, flags ); +} + +NTSTATUS WINAPI wow64_NtUserGetMenuBarInfo( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + LONG id = get_ulong( &args ); + LONG item = get_ulong( &args ); + struct + { + DWORD cbSize; + RECT rcBar; + ULONG hMenu; + ULONG hwndMenu; + BOOL fBarFocused:1; + BOOL fFocused:1; + } *info32 = get_ptr( &args ); + + MENUBARINFO info; + + if (info32->cbSize != sizeof(*info32)) + { + set_last_error32( ERROR_INVALID_PARAMETER ); + return FALSE; + } + + info.cbSize = sizeof(info); + if (!NtUserGetMenuBarInfo( hwnd, id, item, &info )) return FALSE; + info32->rcBar = info.rcBar; + info32->hMenu = HandleToUlong( info.hMenu ); + info32->hwndMenu = HandleToUlong( info.hwndMenu ); + info32->fBarFocused = info.fBarFocused; + info32->fFocused = info.fFocused; + return TRUE; +} + +NTSTATUS WINAPI wow64_NtUserGetMenuItemRect( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + HMENU handle = get_handle( &args ); + UINT item = get_ulong( &args ); + RECT *rect = get_ptr( &args ); + + return NtUserGetMenuItemRect( hwnd, handle, item, rect ); +} +#endif + +NTSTATUS WINAPI wow64_NtUserGetMessage( UINT *args ) +{ + MSG32 *msg32 = get_ptr( &args ); + HWND hwnd = get_handle( &args ); + UINT first = get_ulong( &args ); + UINT last = get_ulong( &args ); + MSG msg; + int ret; + + ret = NtUserGetMessage( &msg, hwnd, first, last ); + if (ret != -1) msg_64to32( &msg, msg32 ); + return ret; +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserGetMouseMovePointsEx( UINT *args ) +{ + UINT size = get_ulong( &args ); + MOUSEMOVEPOINT32 *ptin32 = get_ptr( &args ); + MOUSEMOVEPOINT32 *ptout32 = get_ptr( &args ); + int count = get_ulong( &args ); + DWORD resolution = get_ulong( &args ); + + MOUSEMOVEPOINT ptin[64], ptout[64]; + int ret, i; + + if (size != sizeof(MOUSEMOVEPOINT32) || count < 0 || count > ARRAYSIZE( ptin )) + { + set_last_error32( ERROR_INVALID_PARAMETER ); + return -1; + } + + if (!ptin32 || (!ptout32 && count)) + { + set_last_error32( ERROR_NOACCESS ); + return -1; + } + + for (i = 0; i < count; i++) + { + ptin[i].x = ptin32[i].x; + ptin[i].y = ptin32[i].y; + ptin[i].time = ptin32[i].time; + ptin[i].dwExtraInfo = ptin32[i].dwExtraInfo; + } + + ret = NtUserGetMouseMovePointsEx( sizeof(MOUSEMOVEPOINT), ptin, ptout, count, resolution ); + + for (i = 0; i < ret; i++) + { + ptout32[i].x = ptout[i].x; + ptout32[i].y = ptout[i].y; + ptout32[i].time = ptout[i].time; + ptout32[i].dwExtraInfo = ptout[i].dwExtraInfo; + } + + return ret; +} + +NTSTATUS WINAPI wow64_NtUserGetObjectInformation( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + INT index = get_ulong( &args ); + void *info = get_ptr( &args ); + DWORD len = get_ulong( &args ); + DWORD *needed = get_ptr( &args ); + + return NtUserGetObjectInformation( handle, index, info, len, needed ); +} + +NTSTATUS WINAPI wow64_NtUserGetOpenClipboardWindow( UINT *args ) +{ + return HandleToUlong( NtUserGetOpenClipboardWindow() ); +} + +NTSTATUS WINAPI wow64_NtUserGetPointerInfoList( UINT *args ) +{ + UINT id = get_ulong( &args ); + UINT type = get_ulong( &args ); + UINT unk0 = get_ulong( &args ); + UINT unk1 = get_ulong( &args ); + UINT size = get_ulong( &args ); + void *entry_count = get_ptr( &args ); + void *pointer_count = get_ptr( &args ); + void *pointer_info = get_ptr( &args ); + + return NtUserGetPointerInfoList( id, type, unk0, unk1, size, entry_count, pointer_count, pointer_info ); +} + +NTSTATUS WINAPI wow64_NtUserGetPriorityClipboardFormat( UINT *args ) +{ + UINT *list = get_ptr( &args ); + INT count = get_ulong( &args ); + + return NtUserGetPriorityClipboardFormat( list, count ); +} + +NTSTATUS WINAPI wow64_NtUserGetProcessDpiAwarenessContext( UINT *args ) +{ + HANDLE process = get_handle( &args ); + + return NtUserGetProcessDpiAwarenessContext( process ); +} + +NTSTATUS WINAPI wow64_NtUserGetProcessWindowStation( UINT *args ) +{ + return HandleToUlong( NtUserGetProcessWindowStation() ); +} + +NTSTATUS WINAPI wow64_NtUserGetProp( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + const WCHAR *str = get_ptr( &args ); + + return HandleToUlong( NtUserGetProp( hwnd, str )); +} + +NTSTATUS WINAPI wow64_NtUserGetQueueStatus( UINT *args ) +{ + UINT flags = get_ulong( &args ); + + return NtUserGetQueueStatus( flags ); +} + +NTSTATUS WINAPI wow64_NtUserGetRawInputBuffer( UINT *args ) +{ + RAWINPUT *data = get_ptr( &args ); + UINT *data_size = get_ptr( &args ); + UINT header_size = get_ulong( &args ); + + if (header_size != sizeof(RAWINPUTHEADER32)) + { + set_last_error32( ERROR_INVALID_PARAMETER ); + return ~0u; + } + + /* RAWINPUT has different sizes on 32-bit and 64-bit, but no translation is + * done. The function actually returns different structures depending on + * whether it's operating under WoW64 or not. */ + return NtUserGetRawInputBuffer( data, data_size, sizeof(RAWINPUTHEADER) ); +} + +NTSTATUS WINAPI wow64_NtUserGetRawInputData( UINT *args ) +{ + HRAWINPUT handle = get_handle( &args ); + UINT command = get_ulong( &args ); + void *data = get_ptr( &args ); + UINT *data_size = get_ptr( &args ); + UINT header_size = get_ulong( &args ); + + if (header_size != sizeof(RAWINPUTHEADER32)) + { + set_last_error32( ERROR_INVALID_PARAMETER ); + return ~0u; + } + + switch (command) + { + case RID_INPUT: + if (data) + { + UINT data_size64, body_size, ret; + RAWINPUTHEADER32 *data32 = data; + RAWINPUTHEADER *data64 = NULL; + + data_size64 = *data_size + sizeof(RAWINPUTHEADER); + if (!(data64 = Wow64AllocateTemp( data_size64 ))) + { + set_last_error32( STATUS_NO_MEMORY ); + return ~0u; + } + + ret = NtUserGetRawInputData( handle, command, data64, &data_size64, sizeof(RAWINPUTHEADER) ); + if (ret == ~0u) return ret; + + body_size = ret - sizeof(RAWINPUTHEADER); + if (*data_size < sizeof(RAWINPUTHEADER32) + body_size) + { + set_last_error32( ERROR_INSUFFICIENT_BUFFER ); + return ~0u; + } + + data32->dwType = data64->dwType; + data32->dwSize = sizeof(RAWINPUTHEADER32) + body_size; + data32->hDevice = (UINT_PTR)data64->hDevice; + data32->wParam = data64->wParam; + memcpy( data32 + 1, data64 + 1, body_size ); + return sizeof(RAWINPUTHEADER32) + body_size; + } + else + { + UINT data_size64, ret; + + ret = NtUserGetRawInputData( handle, command, NULL, &data_size64, sizeof(RAWINPUTHEADER) ); + if (ret == ~0u) return ret; + *data_size = data_size64 - sizeof(RAWINPUTHEADER) + sizeof(RAWINPUTHEADER32); + return 0; + } + + case RID_HEADER: + { + UINT data_size64 = sizeof(RAWINPUTHEADER); + RAWINPUTHEADER32 *data32 = data; + RAWINPUTHEADER data64; + UINT ret; + + if (!data) + { + *data_size = sizeof(RAWINPUTHEADER32); + return 0; + } + + if (*data_size < sizeof(RAWINPUTHEADER32)) + { + set_last_error32( ERROR_INSUFFICIENT_BUFFER ); + return ~0u; + } + + ret = NtUserGetRawInputData( handle, command, &data64, &data_size64, sizeof(RAWINPUTHEADER) ); + if (ret == ~0u) return ret; + data32->dwType = data64.dwType; + data32->dwSize = data64.dwSize - sizeof(RAWINPUTHEADER) + sizeof(RAWINPUTHEADER32); + data32->hDevice = (UINT_PTR)data64.hDevice; + data32->wParam = data64.wParam; + return sizeof(RAWINPUTHEADER32); + } + + default: + set_last_error32( ERROR_INVALID_PARAMETER ); + return ~0u; + } +} + +NTSTATUS WINAPI wow64_NtUserGetRawInputDeviceInfo( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + UINT command = get_ulong( &args ); + void *data = get_ptr( &args ); + UINT *data_size = get_ptr( &args ); + + return NtUserGetRawInputDeviceInfo( handle, command, data, data_size ); +} + +NTSTATUS WINAPI wow64_NtUserGetRawInputDeviceList( UINT *args ) +{ + RAWINPUTDEVICELIST32 *devices32 = get_ptr( &args ); + UINT *count = get_ptr( &args ); + UINT size = get_ulong( &args ); + + if (size != sizeof(RAWINPUTDEVICELIST32)) + { + set_last_error32( ERROR_INVALID_PARAMETER ); + return ~0u; + } + + if (devices32) + { + RAWINPUTDEVICELIST *devices64; + unsigned int ret, i; + + if (!(devices64 = Wow64AllocateTemp( (*count) * sizeof(*devices64) ))) + { + set_last_error32( ERROR_NOT_ENOUGH_MEMORY ); + return ~0u; + } + + ret = NtUserGetRawInputDeviceList( devices64, count, sizeof(RAWINPUTDEVICELIST) ); + if (ret == ~0u) return ret; + + for (i = 0; i < *count; ++i) + { + devices32[i].hDevice = (UINT_PTR)devices64[i].hDevice; + devices32[i].dwType = devices64[i].dwType; + } + return ret; + } + else + { + return NtUserGetRawInputDeviceList( NULL, count, sizeof(RAWINPUTDEVICELIST) ); + } +} + +NTSTATUS WINAPI wow64_NtUserRealChildWindowFromPoint( UINT *args ) +{ + HWND parent = get_handle( &args ); + LONG x = get_ulong( &args ); + LONG y = get_ulong( &args ); + + return HandleToUlong( NtUserRealChildWindowFromPoint( parent, x, y )); +} +#endif + +NTSTATUS WINAPI wow64_NtUserRegisterClassExWOW( UINT *args ) +{ + const WNDCLASSEXW32 *wc32 = get_ptr( &args ); + UNICODE_STRING32 *name32 = get_ptr( &args ); + UNICODE_STRING32 *version32 = get_ptr( &args ); + struct client_menu_name32 *client_name32 = get_ptr( &args ); + DWORD fnid = get_ulong( &args ); + DWORD flags = get_ulong( &args ); + DWORD *wow = get_ptr( &args ); + +#ifndef __REACTOS__ + struct client_menu_name client_name; +#else + UNICODE_STRING usMenuName; + CLSMENUNAME client_name; +#endif + UNICODE_STRING name, version; + WNDCLASSEXW wc; + + if (wc32->cbSize != sizeof(*wc32)) + { + /* FIXME */ +#ifndef __REACTOS__ + set_last_error32( ERROR_INVALID_PARAMETER ); +#endif + return 0; + } + + wc.cbSize = sizeof(wc); + wc.style = wc32->style; + wc.lpfnWndProc = UlongToPtr( wc32->lpfnWndProc ); + wc.cbClsExtra = wc32->cbClsExtra; + wc.cbWndExtra = wc32->cbWndExtra; + wc.hInstance = UlongToPtr( wc32->hInstance ); + wc.hIcon = LongToHandle( wc32->hIcon ); + wc.hCursor = LongToHandle( wc32->hCursor ); + wc.hbrBackground = UlongToHandle( wc32->hbrBackground ); + wc.lpszMenuName = UlongToPtr( wc32->lpszMenuName ); + wc.lpszClassName = UlongToPtr( wc32->lpszClassName ); + wc.hIconSm = LongToHandle( wc32->hIconSm ); + + return NtUserRegisterClassExWOW( &wc, + unicode_str_32to64( &name, name32 ), + unicode_str_32to64( &version, version32 ), + client_menu_name_32to64( &client_name, client_name32, &usMenuName ), + fnid, flags, wow ); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserGetRegisteredRawInputDevices( UINT *args ) +{ + RAWINPUTDEVICE32 *devices32 = get_ptr( &args ); + UINT *count = get_ptr( &args ); + UINT size = get_ulong( &args ); + + if (size != sizeof(RAWINPUTDEVICE32)) + { + set_last_error32( ERROR_INVALID_PARAMETER ); + return ~0u; + } + + if (devices32) + { + RAWINPUTDEVICE *devices64; + unsigned int ret, i; + + if (!(devices64 = Wow64AllocateTemp( (*count) * sizeof(*devices64) ))) + { + set_last_error32( ERROR_NOT_ENOUGH_MEMORY ); + return ~0u; + } + + ret = NtUserGetRegisteredRawInputDevices( devices64, count, sizeof(RAWINPUTDEVICE) ); + if (ret == ~0u) return ret; + + for (i = 0; i < *count; ++i) + { + devices32[i].usUsagePage = devices64[i].usUsagePage; + devices32[i].usUsage = devices64[i].usUsage; + devices32[i].dwFlags = devices64[i].dwFlags; + devices32[i].hwndTarget = (ULONG_PTR)devices64[i].hwndTarget; + } + return ret; + } + else + { + return NtUserGetRegisteredRawInputDevices( NULL, count, sizeof(RAWINPUTDEVICE) ); + } +} +#endif + +NTSTATUS WINAPI wow64_NtUserGetScrollBarInfo( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + LONG id = get_ulong( &args ); + SCROLLBARINFO *info = get_ptr( &args ); + + return NtUserGetScrollBarInfo( hwnd, id, info ); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserGetSystemDpiForProcess( UINT *args ) +{ + HANDLE process = get_handle( &args ); + + return NtUserGetSystemDpiForProcess( process ); +} + +NTSTATUS WINAPI wow64_NtUserGetSystemMenu( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + BOOL revert = get_ulong( &args ); + + return HandleToUlong( NtUserGetSystemMenu( hwnd, revert )); +} + +NTSTATUS WINAPI wow64_NtUserGetThreadDesktop( UINT *args ) +{ + DWORD thread = get_ulong( &args ); + + return HandleToUlong( NtUserGetThreadDesktop( thread )); +} + +NTSTATUS WINAPI wow64_NtUserGetTitleBarInfo( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + TITLEBARINFO *info = get_ptr( &args ); + + return NtUserGetTitleBarInfo( hwnd, info ); +} + +NTSTATUS WINAPI wow64_NtUserGetUpdateRect( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + RECT *rect = get_ptr( &args ); + BOOL erase = get_ulong( &args ); + + return NtUserGetUpdateRect( hwnd, rect, erase ); +} + +NTSTATUS WINAPI wow64_NtUserGetUpdateRgn( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + HRGN hrgn = get_handle( &args ); + BOOL erase = get_ulong( &args ); + + return NtUserGetUpdateRgn( hwnd, hrgn, erase ); +} + +NTSTATUS WINAPI wow64_NtUserGetUpdatedClipboardFormats( UINT *args ) +{ + UINT *formats = get_ptr( &args ); + UINT size = get_ulong( &args ); + UINT *out_size = get_ptr( &args ); + + return NtUserGetUpdatedClipboardFormats( formats, size, out_size ); +} +#endif + +NTSTATUS WINAPI wow64_NtUserGetWindowDC( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + + return HandleToUlong( NtUserGetWindowDC( hwnd )); +} + +NTSTATUS WINAPI wow64_NtUserGetWindowPlacement( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + WINDOWPLACEMENT *placement = get_ptr( &args ); + + return NtUserGetWindowPlacement( hwnd, placement ); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserGetWindowRgnEx( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + HRGN hrgn = get_handle( &args ); + UINT unk = get_ulong( &args ); + + return NtUserGetWindowRgnEx( hwnd, hrgn, unk ); +} +#endif + +NTSTATUS WINAPI wow64_NtUserHideCaret( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + + return NtUserHideCaret( hwnd ); +} + +NTSTATUS WINAPI wow64_NtUserHiliteMenuItem( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + HMENU handle = get_handle( &args ); + UINT item = get_ulong( &args ); + UINT hilite = get_ulong( &args ); + + return NtUserHiliteMenuItem( hwnd, handle, item, hilite ); +} + +#ifndef __REACTOS__ + +struct user_client_procs32 +{ + ULONG pButtonWndProc; + ULONG pComboWndProc; + ULONG pDefWindowProc; + ULONG pDefDlgProc; + ULONG pEditWndProc; + ULONG pListBoxWndProc; + ULONG pMDIClientWndProc; + ULONG pScrollBarWndProc; + ULONG pStaticWndProc; + ULONG pImeWndProc; + ULONG pDesktopWndProc; + ULONG pIconTitleWndProc; + ULONG pPopupMenuWndProc; + ULONG pMessageWndProc; +}; + +static struct user_client_procs *user_client_procs_32to64( struct user_client_procs *procs, + const struct user_client_procs32 *procs32 ) +{ + if (!procs32) return NULL; + +#ifndef __REACTOS__ + procs->pButtonWndProc = UlongToPtr( procs32->pButtonWndProc ); + procs->pComboWndProc = UlongToPtr( procs32->pComboWndProc ); + procs->pDefWindowProc = UlongToPtr( procs32->pDefWindowProc ); + procs->pDefDlgProc = UlongToPtr( procs32->pDefDlgProc ); + procs->pEditWndProc = UlongToPtr( procs32->pEditWndProc ); + procs->pListBoxWndProc = UlongToPtr( procs32->pListBoxWndProc ); + procs->pMDIClientWndProc = UlongToPtr( procs32->pMDIClientWndProc ); + procs->pScrollBarWndProc = UlongToPtr( procs32->pScrollBarWndProc ); + procs->pStaticWndProc = UlongToPtr( procs32->pStaticWndProc ); + procs->pImeWndProc = UlongToPtr( procs32->pImeWndProc ); + procs->pDesktopWndProc = UlongToPtr( procs32->pDesktopWndProc ); + procs->pIconTitleWndProc = UlongToPtr( procs32->pIconTitleWndProc ); + procs->pPopupMenuWndProc = UlongToPtr( procs32->pPopupMenuWndProc ); + procs->pMessageWndProc = UlongToPtr( procs32->pMessageWndProc ); +#else + procs->pfnScrollBarWndProc = UlongToPtr(procs32->pfnScrollBarWndProc); + procs->pfnTitleWndProc = UlongToPtr(procs32->pfnTitleWndProc); + procs->pfnMenuWndProc = UlongToPtr(procs32->pfnMenuWndProc); + procs->pfnDesktopWndProc = UlongToPtr(procs32->pfnDesktopWndProc); + procs->pfnDefWindowProc = UlongToPtr(procs32->pfnDefWindowProc); + procs->pfnMessageWindowProc = UlongToPtr(procs32->pfnMessageWindowProc); + procs->pfnSwitchWindowProc = UlongToPtr(procs32->pfnSwitchWindowProc); + procs->pfnButtonWndProc = UlongToPtr(procs32->pfnButtonWndProc); + procs->pfnComboBoxWndProc = UlongToPtr(procs32->pfnComboBoxWndProc); + procs->pfnComboListBoxProc = UlongToPtr(procs32->pfnComboListBoxProc); + procs->pfnDialogWndProc = UlongToPtr(procs32->pfnDialogWndProc); + procs->pfnEditWndProc = UlongToPtr(procs32->pfnEditWndProc); + procs->pfnListBoxWndProc = UlongToPtr(procs32->pfnListBoxWndProc); + procs->pfnMDIClientWndProc = UlongToPtr(procs32->pfnMDIClientWndProc); + procs->pfnStaticWndProc = UlongToPtr(procs32->pfnStaticWndProc); + procs->pfnImeWndProc = UlongToPtr(procs32->pfnImeWndProc); + procs->pfnGhostWndProc = UlongToPtr(procs32->pfnGhostWndProc); + procs->pfnHkINLPCWPSTRUCT = UlongToPtr(procs32->pfnHkINLPCWPSTRUCT); + procs->pfnHkINLPCWPRETSTRUCT = UlongToPtr(procs32->pfnHkINLPCWPRETSTRUCT); + procs->pfnDispatchHook = UlongToPtr(procs32->pfnDispatchHook); + procs->pfnDispatchDefWindowProc = UlongToPtr(procs32->pfnDispatchDefWindowProc); + procs->pfnDispatchMessage = UlongToPtr(procs32->pfnDispatchMessage); + procs->pfnMDIActivateDlgProc = UlongToPtr(procs32->pfnMDIActivateDlgProc); +#endif + return procs; +} + +NTSTATUS WINAPI wow64_NtUserInitializeClientPfnArrays( UINT *args ) +{ + const struct user_client_procs32 *procsA32 = get_ptr( &args ); + const struct user_client_procs32 *procsW32 = get_ptr( &args ); + void *workers = get_ptr( &args ); + HINSTANCE user_module = get_ptr( &args ); + + struct user_client_procs procsA, procsW; + return NtUserInitializeClientPfnArrays( user_client_procs_32to64( &procsA, procsA32 ), + user_client_procs_32to64( &procsW, procsW32 ), + workers, user_module ); +} +#endif + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserInternalGetWindowIcon( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + UINT type = get_ulong( &args ); + + return HandleToUlong( NtUserInternalGetWindowIcon( hwnd, type )); +} +#endif + +NTSTATUS WINAPI wow64_NtUserInternalGetWindowText( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + WCHAR *text = get_ptr( &args ); + INT count = get_ulong( &args ); + + return NtUserInternalGetWindowText( hwnd, text, count ); +} + +NTSTATUS WINAPI wow64_NtUserInvalidateRect( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + const RECT *rect = get_ptr( &args ); + BOOL erase = get_ulong( &args ); + + return NtUserInvalidateRect( hwnd, rect, erase ); +} + +NTSTATUS WINAPI wow64_NtUserInvalidateRgn( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + HRGN hrgn = get_handle( &args ); + BOOL erase = get_ulong( &args ); + + return NtUserInvalidateRgn( hwnd, hrgn, erase ); +} + +NTSTATUS WINAPI wow64_NtUserIsClipboardFormatAvailable( UINT *args ) +{ + UINT format = get_ulong( &args ); + + return NtUserIsClipboardFormatAvailable( format ); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserIsMouseInPointerEnabled( UINT *args ) +{ + return NtUserIsMouseInPointerEnabled(); +} +#endif + +NTSTATUS WINAPI wow64_NtUserKillTimer( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + UINT_PTR id = get_ulong( &args ); + + return NtUserKillTimer( hwnd, id ); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserLockWindowUpdate( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + + return NtUserLockWindowUpdate( hwnd ); +} + +NTSTATUS WINAPI wow64_NtUserLogicalToPerMonitorDPIPhysicalPoint( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + POINT *pt = get_ptr( &args ); + + return NtUserLogicalToPerMonitorDPIPhysicalPoint( hwnd, pt ); +} +#endif + +NTSTATUS WINAPI wow64_NtUserMapVirtualKeyEx( UINT *args ) +{ + UINT code = get_ulong( &args ); + UINT type = get_ulong( &args ); +#ifdef __REACTOS__ + DWORD keyboardId = get_ulong( &args ); +#endif + HKL layout = get_handle( &args ); + +#ifndef __REACTOS__ + return NtUserMapVirtualKeyEx( code, type, layout ); +#else + return NtUserMapVirtualKeyEx(code, type, keyboardId, layout); +#endif +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserMenuItemFromPoint( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + HMENU handle = get_handle( &args ); + int x = get_ulong( &args ); + int y = get_ulong( &args ); + + return NtUserMenuItemFromPoint( hwnd, handle, x, y ); +} +#endif + +#define NtUserMessageCall(hWnd, Msg, wParam, lParam, pResult, dwType, bAnsi) \ + NtUserMessageCall(hWnd, Msg, wParam, lParam, (ULONG_PTR)pResult, dwType, bAnsi) + +static LRESULT message_call_32to64( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, + void *result_info, DWORD type, BOOL ansi ) +{ + LRESULT ret = 0; + + switch (msg) + { + case WM_NCCREATE: + case WM_CREATE: + if (lparam) + { + CREATESTRUCT32 *cs32 = (void *)lparam; + CREATESTRUCTW cs; + + createstruct_32to64( cs32, &cs ); + ret = NtUserMessageCall( hwnd, msg, wparam, (LPARAM)&cs, result_info, type, ansi ); + cs32->lpCreateParams = PtrToUlong( cs.lpCreateParams ); + cs32->hInstance = PtrToUlong( cs.hInstance ); + cs32->hMenu = HandleToLong( cs.hMenu ); + cs32->hwndParent = HandleToLong( cs.hwndParent ); + cs32->cy = cs.cy; + cs32->cx = cs.cx; + cs32->y = cs.y; + cs32->x = cs.x; + cs32->style = cs.style; + cs32->dwExStyle = cs.dwExStyle; + return ret; + } + return NtUserMessageCall( hwnd, msg, wparam, lparam, result_info, type, ansi ); + + case WM_MDICREATE: + { + MDICREATESTRUCT32 *cs32 = (void *)lparam; + MDICREATESTRUCTW cs; + + cs.szClass = UlongToPtr( cs32->szClass ); + cs.szTitle = UlongToPtr( cs32->szTitle ); + cs.hOwner = LongToHandle( cs32->hOwner ); + cs.x = cs32->x; + cs.y = cs32->y; + cs.cx = cs32->cx; + cs.cy = cs32->cy; + cs.style = cs32->style; + cs.lParam = cs32->lParam; + + return NtUserMessageCall( hwnd, msg, wparam, (LPARAM)&cs, result_info, type, ansi ); + } + + case WM_WINDOWPOSCHANGING: + case WM_WINDOWPOSCHANGED: + { + WINDOWPOS32 *winpos32 = (void *)lparam; + WINDOWPOS winpos; + + winpos_32to64( &winpos, winpos32 ); + ret = NtUserMessageCall( hwnd, msg, wparam, (LPARAM)&winpos, result_info, type, ansi ); + winpos_64to32( &winpos, winpos32 ); + return ret; + } + + case WM_NCCALCSIZE: + if (wparam) + { + NCCALCSIZE_PARAMS32 *params32 = (void *)lparam; + NCCALCSIZE_PARAMS params; + WINDOWPOS winpos; + + params.rgrc[0] = params32->rgrc[0]; + params.rgrc[1] = params32->rgrc[1]; + params.rgrc[2] = params32->rgrc[2]; + params.lppos = &winpos; + winpos_32to64( &winpos, UlongToPtr( params32->lppos )); + ret = NtUserMessageCall( hwnd, msg, wparam, (LPARAM)¶ms, result_info, type, ansi ); + params32->rgrc[0] = params.rgrc[0]; + params32->rgrc[1] = params.rgrc[1]; + params32->rgrc[2] = params.rgrc[2]; + winpos_64to32( &winpos, UlongToPtr( params32->lppos )); + return ret; + } + return NtUserMessageCall( hwnd, msg, wparam, lparam, result_info, type, ansi ); + + case WM_COMPAREITEM: + { + COMPAREITEMSTRUCT32 *cis32 = (void *)lparam; + COMPAREITEMSTRUCT cis; + + cis.CtlType = cis32->CtlType; + cis.CtlID = cis32->CtlID; + cis.hwndItem = LongToHandle( cis32->hwndItem ); + cis.itemID1 = cis32->itemID1; + cis.itemData1 = cis32->itemData1; + cis.itemID2 = cis32->itemID2; + cis.itemData2 = cis32->itemData2; + cis.dwLocaleId = cis32->dwLocaleId; + return NtUserMessageCall( hwnd, msg, wparam, (LPARAM)&cis, result_info, type, ansi ); + } + + case WM_DELETEITEM: + { + DELETEITEMSTRUCT32 *dis32 = (void *)lparam; + DELETEITEMSTRUCT dis; + + dis.CtlType = dis32->CtlType; + dis.CtlID = dis32->CtlID; + dis.itemID = dis32->itemID; + dis.hwndItem = LongToHandle( dis32->hwndItem ); + dis.itemData = dis32->itemData; + return NtUserMessageCall( hwnd, msg, wparam, (LPARAM)&dis, result_info, type, ansi ); + } + + case WM_MEASUREITEM: + { + MEASUREITEMSTRUCT32 *mis32 = (void *)lparam; + MEASUREITEMSTRUCT mis; + + mis.CtlType = mis32->CtlType; + mis.CtlID = mis32->CtlID; + mis.itemID = mis32->itemID; + mis.itemWidth = mis32->itemWidth; + mis.itemHeight = mis32->itemHeight; + mis.itemData = mis32->itemData; + ret = NtUserMessageCall( hwnd, msg, wparam, (LPARAM)&mis, result_info, type, ansi ); + mis32->CtlType = mis.CtlType; + mis32->CtlID = mis.CtlID; + mis32->itemID = mis.itemID; + mis32->itemWidth = mis.itemWidth; + mis32->itemHeight = mis.itemHeight; + mis32->itemData = mis.itemData; + return ret; + } + + case WM_DRAWITEM: + { + DRAWITEMSTRUCT32 *dis32 = (void *)lparam; + DRAWITEMSTRUCT dis; + + dis.CtlType = dis32->CtlType; + dis.CtlID = dis32->CtlID; + dis.itemID = dis32->itemID; + dis.itemAction = dis32->itemAction; + dis.itemState = dis32->itemState; + dis.hwndItem = LongToHandle( dis32->hwndItem ); + dis.hDC = LongToHandle( dis32->hDC ); + dis.itemData = dis32->itemData; + dis.rcItem.left = dis32->rcItem.left; + dis.rcItem.top = dis32->rcItem.top; + dis.rcItem.right = dis32->rcItem.right; + dis.rcItem.bottom = dis32->rcItem.bottom; + return NtUserMessageCall( hwnd, msg, wparam, (LPARAM)&dis, result_info, type, ansi ); + } + + case WM_COPYDATA: + { + COPYDATASTRUCT32 *cds32 = (void *)lparam; + COPYDATASTRUCT cds; + + cds.dwData = cds32->dwData; + cds.cbData = cds32->cbData; + cds.lpData = UlongToPtr( cds32->lpData ); + return NtUserMessageCall( hwnd, msg, wparam, (LPARAM)&cds, result_info, type, ansi ); + } + + case WM_HELP: + { + HELPINFO32 *hi32 = (void *)lparam; + HELPINFO hi64; + + hi64.cbSize = sizeof(hi64); + hi64.iContextType = hi32->iContextType; + hi64.iCtrlId = hi32->iCtrlId; + hi64.hItemHandle = LongToHandle( hi32->hItemHandle ); + hi64.dwContextId = hi32->dwContextId; + hi64.MousePos = hi32->MousePos; + return NtUserMessageCall( hwnd, msg, wparam, (LPARAM)&hi64, result_info, type, ansi ); + } + + case WM_GETDLGCODE: + if (lparam) + { + MSG32 *msg32 = (MSG32 *)lparam; + MSG msg64; + + return NtUserMessageCall( hwnd, msg, wparam, (LPARAM)msg_32to64( &msg64, msg32 ), + result_info, type, ansi ); + } + return NtUserMessageCall( hwnd, msg, wparam, lparam, result_info, type, ansi ); + + case WM_NEXTMENU: + { + MDINEXTMENU32 *next32 = (void *)lparam; + MDINEXTMENU next; + + next.hmenuIn = LongToHandle( next32->hmenuIn ); + next.hmenuNext = LongToHandle( next32->hmenuNext ); + next.hwndNext = LongToHandle( next32->hwndNext ); + ret = NtUserMessageCall( hwnd, msg, wparam, (LPARAM)&next, result_info, type, ansi ); + next32->hmenuIn = HandleToLong( next.hmenuIn ); + next32->hmenuNext = HandleToLong( next.hmenuNext ); + next32->hwndNext = HandleToLong( next.hwndNext ); + return ret; + } + + case WM_PAINTCLIPBOARD: + { + PAINTSTRUCT ps; + + paintstruct_32to64( &ps, (PAINTSTRUCT32 *)lparam ); + return NtUserMessageCall( hwnd, msg, wparam, (LPARAM)&ps, result_info, type, ansi ); + } + + case CB_GETCOMBOBOXINFO: + { + COMBOBOXINFO32 *ci32 = (COMBOBOXINFO32 *)lparam; + COMBOBOXINFO ci; + + ci.cbSize = ci32->cbSize; + ci.rcItem = ci32->rcItem; + ci.rcButton = ci32->rcButton; + ci.stateButton = ci32->stateButton; + ci.hwndCombo = LongToHandle( ci32->hwndCombo ); + ci.hwndItem = LongToHandle( ci32->hwndItem ); + ci.hwndList = LongToHandle( ci32->hwndList ); + ret = NtUserMessageCall( hwnd, msg, wparam, (LPARAM)&ci, result_info, type, ansi ); + ci32->cbSize = ci.cbSize; + ci32->rcItem = ci.rcItem; + ci32->rcButton = ci.rcButton; + ci32->stateButton = ci.stateButton; + ci32->hwndCombo = HandleToLong( ci.hwndCombo ); + ci32->hwndItem = HandleToLong( ci.hwndItem ); + ci32->hwndList = HandleToLong( ci.hwndList ); + return ret; + } + + default: + return NtUserMessageCall( hwnd, msg, wparam, lparam, result_info, type, ansi ); + } +} + +NTSTATUS WINAPI wow64_NtUserMessageCall( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + UINT msg = get_ulong( &args ); + LONG wparam = get_ulong( &args ); + LONG lparam = get_ulong( &args ); + void *result_info = get_ptr( &args ); + UINT type = get_ulong ( &args ); + BOOL ansi = get_ulong( &args ); + + switch (type) + { +#ifndef __REACTOS__ + case NtUserGetDispatchParams: + case NtUserCallWindowProc: + { + struct win_proc_params32 *params32 = result_info; + struct win_proc_params params; + + if (type == NtUserCallWindowProc) params.func = UlongToPtr( params32->func ); + + if (!NtUserMessageCall( hwnd, msg, wparam, lparam, ¶ms, type, ansi )) + return FALSE; + + win_proc_params_64to32( ¶ms, params32 ); + return TRUE; + } + + case NtUserSendMessage: + { + struct win_proc_params32 *params32 = result_info; + + if (params32) + { + struct win_proc_params params; + NTSTATUS ret; + + params.hwnd = 0; + ret = message_call_32to64( hwnd, msg, wparam, lparam, ¶ms, type, ansi ); + if (params.hwnd) win_proc_params_64to32( ¶ms, params32 ); + return ret; + } + + return message_call_32to64( hwnd, msg, wparam, lparam, result_info, type, ansi ); + } + + case NtUserSendMessageTimeout: + { + struct + { + UINT flags; + UINT timeout; + DWORD result; + } *params32 = result_info; + struct send_message_timeout_params params; + LRESULT ret; + + params.flags = params32->flags; + params.timeout = params32->timeout; + ret = message_call_32to64( hwnd, msg, wparam, lparam, ¶ms, type, ansi ); + params32->result = params.result; + return ret; + } + + case NtUserSendMessageCallback: + { + struct + { + ULONG callback; + ULONG data; + } *params32 = result_info; + struct send_message_callback_params params; + + params.callback = UlongToPtr( params32->callback ); + params.data = params32->data; + return message_call_32to64( hwnd, msg, wparam, lparam, ¶ms, type, ansi ); + } + + case NtUserSpyGetMsgName: + /* no argument conversion */ + return NtUserMessageCall( hwnd, msg, wparam, lparam, result_info, type, ansi ); + + case NtUserImeDriverCall: + { + struct + { + ULONG himc; + ULONG state; + ULONG compstr; + } *params32 = result_info; + struct ime_driver_call_params params; + if (msg == WINE_IME_POST_UPDATE) ERR( "Unexpected WINE_IME_POST_UPDATE message\n" ); + params.himc = UlongToPtr( params32->himc ); + params.state = UlongToPtr( params32->state ); + params.compstr = UlongToPtr( params32->compstr ); + return NtUserMessageCall( hwnd, msg, wparam, lparam, ¶ms, type, ansi ); + } + + case NtUserSystemTrayCall: + switch (msg) + { + case WINE_SYSTRAY_NOTIFY_ICON: + { + struct + { + DWORD cbSize; + ULONG hWnd; + UINT uID; + UINT uFlags; + UINT uCallbackMessage; + ULONG hIcon; + WCHAR szTip[128]; + DWORD dwState; + DWORD dwStateMask; + WCHAR szInfo[256]; + UINT uTimeout; + WCHAR szInfoTitle[64]; + DWORD dwInfoFlags; + GUID guidItem; + ULONG hBalloonIcon; + } *params32 = result_info; + + NOTIFYICONDATAW params = {.cbSize = sizeof(params)}; + params.hWnd = UlongToHandle( params32->hWnd ); + params.uID = params32->uID; + params.uFlags = params32->uFlags; + params.uCallbackMessage = params32->uCallbackMessage; + params.hIcon = UlongToHandle( params32->hIcon ); + if (params.uFlags & NIF_TIP) wcscpy( params.szTip, params32->szTip ); + params.dwState = params32->dwState; + params.dwStateMask = params32->dwStateMask; + + if (params.uFlags & NIF_INFO) + { + wcscpy( params.szInfoTitle, params32->szInfoTitle ); + wcscpy( params.szInfo, params32->szInfo ); + params.uTimeout = params32->uTimeout; + params.dwInfoFlags = params32->dwInfoFlags; + } + + params.guidItem = params32->guidItem; + params.hBalloonIcon = UlongToHandle( params32->hBalloonIcon ); + + return NtUserMessageCall( hwnd, msg, wparam, lparam, ¶ms, type, ansi ); + } + default: + return NtUserMessageCall( hwnd, msg, wparam, lparam, result_info, type, ansi ); + } +#endif + case FNID_SENDMESSAGEWTOOPTION: + { + struct + { + UINT uFlags; + UINT uTimeout; + DWORD Result; + } *Params32 = result_info; + + DOSENDMESSAGE Params; + LRESULT Ret; + + Params.uFlags = Params32->uFlags; + Params.uTimeout = Params32->uTimeout; + Ret = message_call_32to64(hwnd, msg, wparam, lparam, &Params, type, ansi); + Params32->Result = Params.Result; + return Ret; + } + } +#ifndef __REACTOS__ + return message_call_32to64( hwnd, msg, wparam, lparam, result_info, type, ansi ); +#else + /* FIXME */ + BYTE bigStupidBuffer[256]; + NTSTATUS Status = message_call_32to64(hwnd, msg, wparam, lparam, bigStupidBuffer, type, ansi); + RtlCopyMemory(result_info, bigStupidBuffer, 4); + return Status; +#endif +} + +NTSTATUS WINAPI wow64_NtUserMoveWindow( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + INT x = get_ulong( &args ); + INT y = get_ulong( &args ); + INT cx = get_ulong( &args ); + INT cy = get_ulong( &args ); + BOOL repaint = get_ulong( &args ); + + return NtUserMoveWindow( hwnd, x, y, cx, cy, repaint ); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserMsgWaitForMultipleObjectsEx( UINT *args ) +{ + DWORD count = get_ulong( &args ); + const ULONG *handles32 = get_ptr( &args ); + DWORD timeout = get_ulong( &args ); + DWORD mask = get_ulong( &args ); + DWORD flags = get_ulong( &args ); + + HANDLE handles[MAXIMUM_WAIT_OBJECTS]; + unsigned int i; + + if (count > ARRAYSIZE(handles)) + { + set_last_error32( ERROR_INVALID_PARAMETER ); + return WAIT_FAILED; + } + for (i = 0; i < count; i++) handles[i] = LongToHandle( handles32[i] ); + + return NtUserMsgWaitForMultipleObjectsEx( count, handles, timeout, mask, flags ); +} + +NTSTATUS WINAPI wow64_NtUserNotifyIMEStatus( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + ULONG status = get_ulong( &args ); + + NtUserNotifyIMEStatus( hwnd, status ); + return 0; +} + +NTSTATUS WINAPI wow64_NtUserNotifyWinEvent( UINT *args ) +{ + DWORD event = get_ulong( &args ); + HWND hwnd = get_handle( &args ); + LONG object_id = get_ulong( &args ); + LONG child_id = get_ulong( &args ); + + NtUserNotifyWinEvent( event, hwnd, object_id, child_id ); + return 0; +} +#endif + +NTSTATUS WINAPI wow64_NtUserOpenClipboard( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + ULONG unk = get_ulong( &args ); + + return NtUserOpenClipboard( hwnd, unk ); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserOpenDesktop( UINT *args ) +{ + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + DWORD flags = get_ulong( &args ); + ACCESS_MASK access = get_ulong( &args ); + + struct object_attr64 attr; + HANDLE ret; + + ret = NtUserOpenDesktop( objattr_32to64( &attr, attr32 ), flags, access ); + return HandleToUlong( ret ); +} + +NTSTATUS WINAPI wow64_NtUserOpenInputDesktop( UINT *args ) +{ + DWORD flags = get_ulong( &args ); + BOOL inherit = get_ulong( &args ); + ACCESS_MASK access = get_ulong( &args ); + + return HandleToUlong( NtUserOpenInputDesktop( flags, inherit, access )); +} + +NTSTATUS WINAPI wow64_NtUserOpenWindowStation( UINT *args ) +{ + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args ); + + struct object_attr64 attr; + + return HandleToUlong( NtUserOpenWindowStation( objattr_32to64( &attr, attr32 ), access )); +} +#endif + +NTSTATUS WINAPI wow64_NtUserPeekMessage( UINT *args ) +{ + MSG32 *msg32 = get_ptr( &args ); + HWND hwnd = get_handle( &args ); + UINT first = get_ulong( &args ); + UINT last = get_ulong( &args ); + UINT flags = get_ulong( &args ); + MSG msg; + + if (!NtUserPeekMessage( msg32 ? &msg : NULL, hwnd, first, last, flags )) return FALSE; + msg_64to32( &msg, msg32 ); + return TRUE; +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserPerMonitorDPIPhysicalToLogicalPoint( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + POINT *pt = get_ptr( &args ); + + return NtUserPerMonitorDPIPhysicalToLogicalPoint( hwnd, pt ); +} +#endif + +NTSTATUS WINAPI wow64_NtUserPostMessage( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + UINT msg = get_ulong( &args ); + WPARAM wparam = get_ulong( &args ); + LPARAM lparam = get_ulong( &args ); + + return NtUserPostMessage( hwnd, msg, wparam, lparam ); +} + +NTSTATUS WINAPI wow64_NtUserPostThreadMessage( UINT *args ) +{ + DWORD thread = get_ulong( &args ); + UINT msg = get_ulong( &args ); + WPARAM wparam = get_ulong( &args ); + LPARAM lparam = get_ulong( &args ); + + return NtUserPostThreadMessage( thread, msg, wparam, lparam ); +} + +NTSTATUS WINAPI wow64_NtUserPrintWindow( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + HDC hdc = get_handle( &args ); + UINT flags = get_ulong( &args ); + + return NtUserPrintWindow( hwnd, hdc, flags ); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserQueryDisplayConfig( UINT *args ) +{ + UINT32 flags = get_ulong( &args ); + UINT32 *paths_count = get_ptr( &args ); + DISPLAYCONFIG_PATH_INFO *paths = get_ptr( &args ); + UINT32 *modes_count = get_ptr( &args ); + DISPLAYCONFIG_MODE_INFO *modes = get_ptr( &args ); + DISPLAYCONFIG_TOPOLOGY_ID *topology_id = get_ptr( &args ); + + return NtUserQueryDisplayConfig( flags, paths_count, paths, modes_count, modes, topology_id ); +} +#endif + +NTSTATUS WINAPI wow64_NtUserQueryInputContext( UINT *args ) +{ + HIMC handle = get_handle( &args ); + UINT attr = get_ulong( &args ); + + return NtUserQueryInputContext( handle, attr ); +} + +NTSTATUS WINAPI wow64_NtUserRedrawWindow( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + const RECT *rect = get_ptr( &args ); + HRGN hrgn = get_handle( &args ); + UINT flags = get_ulong( &args ); + + return NtUserRedrawWindow( hwnd, rect, hrgn, flags ); +} + +NTSTATUS WINAPI wow64_NtUserRegisterHotKey( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + INT id = get_ulong( &args ); + UINT modifiers = get_ulong( &args ); + UINT vk = get_ulong( &args ); + + return NtUserRegisterHotKey( hwnd, id, modifiers, vk ); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserRegisterRawInputDevices( UINT *args ) +{ + const RAWINPUTDEVICE32 *devices32 = get_ptr( &args ); + UINT count = get_ulong( &args ); + UINT size = get_ulong( &args ); + + RAWINPUTDEVICE *devices64; + unsigned int i; + + if (size != sizeof(RAWINPUTDEVICE32)) + { + set_last_error32( ERROR_INVALID_PARAMETER ); + return FALSE; + } + + if (!(devices64 = Wow64AllocateTemp( count * sizeof(*devices64) ))) + { + set_last_error32( ERROR_NOT_ENOUGH_MEMORY ); + return FALSE; + } + + for (i = 0; i < count; ++i) + { + devices64[i].usUsagePage = devices32[i].usUsagePage; + devices64[i].usUsage = devices32[i].usUsage; + devices64[i].dwFlags = devices32[i].dwFlags; + devices64[i].hwndTarget = UlongToPtr( devices32[i].hwndTarget ); + } + + return NtUserRegisterRawInputDevices( devices64, count, sizeof(*devices64) ); +} + +NTSTATUS WINAPI wow64_NtUserReleaseDC( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + HDC hdc = get_handle( &args ); + + return NtUserReleaseDC( hwnd, hdc ); +} + +NTSTATUS WINAPI wow64_NtUserRemoveClipboardFormatListener( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + + return NtUserRemoveClipboardFormatListener( hwnd ); +} +#endif + +NTSTATUS WINAPI wow64_NtUserRemoveMenu( UINT *args ) +{ + HMENU handle = get_handle( &args ); + UINT id = get_ulong( &args ); + UINT flags = get_ulong( &args ); + + return NtUserRemoveMenu( handle, id, flags ); +} + +NTSTATUS WINAPI wow64_NtUserRemoveProp( UINT *args ) +{ + HWND hwnd = get_handle( &args ); +#ifndef __REACTOS__ + const WCHAR *str = get_ptr( &args ); +#else + ATOM str = get_ulong(&args); +#endif + + return HandleToUlong( NtUserRemoveProp( hwnd, str )); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserScrollDC( UINT *args ) +{ + HDC hdc = get_handle( &args ); + INT dx = get_ulong( &args ); + INT dy = get_ulong( &args ); + const RECT *scroll = get_ptr( &args ); + const RECT *clip = get_ptr( &args ); + HRGN ret_update_rgn = get_handle( &args ); + RECT *update_rect = get_ptr( &args ); + + return NtUserScrollDC( hdc, dx, dy, scroll, clip, ret_update_rgn, update_rect ); +} +#endif + +NTSTATUS WINAPI wow64_NtUserScrollWindowEx( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + INT dx = get_ulong( &args ); + INT dy = get_ulong( &args ); + const RECT *rect = get_ptr( &args ); + const RECT *clip_rect = get_ptr( &args ); + HRGN update_rgn = get_handle( &args ); + RECT *update_rect = get_ptr( &args ); + UINT flags = get_ulong( &args ); + + return NtUserScrollWindowEx( hwnd, dx, dy, rect, clip_rect, update_rgn, update_rect, flags ); +} + +NTSTATUS WINAPI wow64_NtUserSelectPalette( UINT *args ) +{ + HDC hdc = get_handle( &args ); + HPALETTE hpal = get_handle( &args ); + WORD bkg = get_ulong( &args ); + + return HandleToUlong( NtUserSelectPalette( hdc, hpal, bkg )); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserSendInput( UINT *args ) +{ + UINT count = get_ulong( &args ); + INPUT32 *inputs32 = get_ptr( &args ); + int size = get_ulong( &args ); + + INPUT *inputs = NULL; + unsigned int i; + + if (size != sizeof(*inputs32) || !count) + { + set_last_error32( ERROR_INVALID_PARAMETER ); + return 0; + } + + if (!inputs32) + { + set_last_error32( ERROR_NOACCESS ); + return 0; + } + + if (count && !(inputs = Wow64AllocateTemp( count * sizeof(*inputs) ))) + return 0; + + for (i = 0; i < count; i++) + { + inputs[i].type = inputs32[i].type; + switch (inputs[i].type) + { + case INPUT_MOUSE: + inputs[i].mi.dx = inputs32[i].mi.dx; + inputs[i].mi.dy = inputs32[i].mi.dy; + inputs[i].mi.mouseData = inputs32[i].mi.mouseData; + inputs[i].mi.dwFlags = inputs32[i].mi.dwFlags; + inputs[i].mi.time = inputs32[i].mi.time; + inputs[i].mi.dwExtraInfo = inputs32[i].mi.dwExtraInfo; + break; + case INPUT_KEYBOARD: + inputs[i].ki.wVk = inputs32[i].ki.wVk; + inputs[i].ki.wScan = inputs32[i].ki.wScan; + inputs[i].ki.dwFlags = inputs32[i].ki.dwFlags; + inputs[i].ki.time = inputs32[i].ki.time; + inputs[i].ki.dwExtraInfo = inputs32[i].ki.dwExtraInfo; + break; + case INPUT_HARDWARE: + inputs[i].hi = inputs32[i].hi; + break; + } + } + + return NtUserSendInput( count, inputs, sizeof(*inputs) ); +} +#endif + +NTSTATUS WINAPI wow64_NtUserSetActiveWindow( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + + return HandleToUlong( NtUserSetActiveWindow( hwnd )); +} + +NTSTATUS WINAPI wow64_NtUserSetCapture( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + + return HandleToUlong( NtUserSetCapture( hwnd )); +} + +NTSTATUS WINAPI wow64_NtUserSetClassLong( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + INT offset = get_ulong( &args ); + LONG newval = get_ulong( &args ); + BOOL ansi = get_ulong( &args ); + + return NtUserSetClassLong( hwnd, offset, newval, ansi ); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserSetClassLongPtr( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + INT offset = get_ulong( &args ); + LONG_PTR newval = get_ulong( &args ); + BOOL ansi = get_ulong( &args ); + + if (offset == GCLP_MENUNAME) + { + struct client_menu_name menu_name; + struct client_menu_name32 *menu_name32 = UlongToPtr( newval ); + NtUserSetClassLongPtr( hwnd, offset, + (UINT_PTR)client_menu_name_32to64( &menu_name, menu_name32 ), ansi ); + client_menu_name_64to32( &menu_name, menu_name32 ); + return 0; + } + + return NtUserSetClassLongPtr( hwnd, offset, newval, ansi ); +} +#endif + +NTSTATUS WINAPI wow64_NtUserSetClassWord( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + INT offset = get_ulong( &args ); + WORD newval = get_ulong( &args ); + + return NtUserSetClassWord( hwnd, offset, newval ); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserSetClipboardData( UINT *args ) +{ + UINT format = get_ulong( &args ); + HANDLE handle = get_handle( &args ); + struct + { + UINT32 data; + UINT32 size; + BOOL cache_only; + UINT seqno; + } *params32 = get_ptr( &args ); + + struct set_clipboard_params params; + params.data = UlongToPtr( params32->data ); + params.size = params32->size; + params.cache_only = params32->cache_only; + params.seqno = params32->seqno; + + return NtUserSetClipboardData( format, handle, ¶ms ); +} + +NTSTATUS WINAPI wow64_NtUserSetClipboardViewer( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + + return HandleToUlong( NtUserSetClipboardViewer( hwnd )); +} +#endif + +NTSTATUS WINAPI wow64_NtUserSetCursor( UINT *args ) +{ + HCURSOR cursor = get_handle( &args ); + + return HandleToUlong( NtUserSetCursor( cursor )); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserSetCursorIconData( UINT *args ) +{ + HCURSOR cursor = get_handle( &args ); + UNICODE_STRING32 *module32 = get_ptr( &args ); + UNICODE_STRING32 *res_name32 = get_ptr( &args ); + struct + { + UINT flags; + UINT num_steps; + UINT num_frames; + UINT delay; + ULONG frames; + ULONG frame_seq; + ULONG frame_rates; + ULONG rsrc; + } *desc32 = get_ptr( &args ); + struct + { + UINT width; + UINT height; + ULONG color; + ULONG alpha; + ULONG mask; + POINT hotspot; + } *frames32 = UlongToPtr( desc32->frames ); + + UNICODE_STRING module, res_name; + struct cursoricon_desc desc; + UINT i, num_frames; + + num_frames = max( desc32->num_frames, 1 ); + if (!(desc.frames = Wow64AllocateTemp( num_frames * sizeof(*desc.frames) ))) return FALSE; + desc.flags = desc32->flags; + desc.num_steps = desc32->num_steps; + desc.num_frames = desc32->num_frames; + desc.delay = desc32->delay; + desc.frame_seq = UlongToPtr( desc32->frame_seq ); + desc.frame_rates = UlongToPtr( desc32->frame_rates ); + desc.rsrc = UlongToPtr( desc32->rsrc ); + + for (i = 0; i < num_frames; i++) + { + desc.frames[i].width = frames32[i].width; + desc.frames[i].height = frames32[i].height; + desc.frames[i].color = UlongToHandle( frames32[i].color ); + desc.frames[i].alpha = UlongToHandle( frames32[i].alpha ); + desc.frames[i].mask = UlongToHandle( frames32[i].mask ); + desc.frames[i].hotspot = frames32[i].hotspot; + } + + return NtUserSetCursorIconData( cursor, unicode_str_32to64( &module, module32 ), + unicode_str_32to64( &res_name, res_name32), &desc ); +} + +NTSTATUS WINAPI wow64_NtUserSetCursorPos( UINT *args ) +{ + INT x = get_ulong( &args ); + INT y = get_ulong( &args ); + + return NtUserSetCursorPos( x, y ); +} +#endif + +NTSTATUS WINAPI wow64_NtUserSetFocus( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + + return HandleToUlong( NtUserSetFocus( hwnd )); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserSetInternalWindowPos( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + UINT cmd = get_ulong( &args ); + RECT *rect = get_ptr( &args ); + POINT *pt = get_ptr( &args ); + + NtUserSetInternalWindowPos( hwnd, cmd, rect, pt ); + return 0; +} + +NTSTATUS WINAPI wow64_NtUserSetKeyboardState( UINT *args ) +{ + BYTE *state = get_ptr( &args ); + + return NtUserSetKeyboardState( state ); +} + +NTSTATUS WINAPI wow64_NtUserSetLayeredWindowAttributes( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + COLORREF key = get_ulong( &args ); + BYTE alpha = get_ulong( &args ); + DWORD flags = get_ulong( &args ); + + return NtUserSetLayeredWindowAttributes( hwnd, key, alpha, flags ); +} +#endif + +NTSTATUS WINAPI wow64_NtUserSetMenu( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + HMENU menu = get_handle( &args ); +#ifndef __REACTOS__ + + return NtUserSetMenu( hwnd, menu ); +#else + BOOLEAN flag = get_ulong(&args); + + return NtUserSetMenu(hwnd, menu, flag); +#endif +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserSetMenuContextHelpId( UINT *args ) +{ + HMENU menu = get_handle( &args ); + DWORD id = get_ulong( &args ); + + return NtUserSetMenuContextHelpId( menu, id ); +} + +NTSTATUS WINAPI wow64_NtUserSetMenuDefaultItem( UINT *args ) +{ + HMENU handle = get_handle( &args ); + UINT item = get_ulong( &args ); + UINT bypos = get_ulong( &args ); + + return NtUserSetMenuDefaultItem( handle, item, bypos ); +} + +NTSTATUS WINAPI wow64_NtUserSetObjectInformation( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + INT index = get_ulong( &args ); + void *info = get_ptr( &args ); + DWORD len = get_ulong( &args ); + + return NtUserSetObjectInformation( handle, index, info, len ); +} +#endif + +NTSTATUS WINAPI wow64_NtUserSetParent( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + HWND parent = get_handle( &args ); + + return HandleToUlong( NtUserSetParent( hwnd, parent )); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserSetProcessDpiAwarenessContext( UINT *args ) +{ + ULONG awareness = get_ulong( &args ); + ULONG unknown = get_ulong( &args ); + + return NtUserSetProcessDpiAwarenessContext( awareness, unknown ); +} + +NTSTATUS WINAPI wow64_NtUserSetProcessWindowStation( UINT *args ) +{ + HWINSTA handle = get_handle( &args ); + + return NtUserSetProcessWindowStation( handle ); +} +#endif + +NTSTATUS WINAPI wow64_NtUserSetProp( UINT *args ) +{ + HWND hwnd = get_handle( &args ); +#ifndef __REACTOS__ + const WCHAR *str = get_ptr( &args ); +#else + ATOM str = get_ulong(&args); +#endif + HANDLE handle = get_handle( &args ); + + return NtUserSetProp( hwnd, str, handle ); +} + +NTSTATUS WINAPI wow64_NtUserSetScrollInfo( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + INT bar = get_ulong( &args ); + const SCROLLINFO *info = get_ptr( &args ); + BOOL redraw = get_ulong( &args ); + + return NtUserSetScrollInfo( hwnd, bar, info, redraw ); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserSetShellWindowEx( UINT *args ) +{ + HWND shell = get_handle( &args ); + HWND list_view = get_handle( &args ); + + return NtUserSetShellWindowEx( shell, list_view ); +} + +NTSTATUS WINAPI wow64_NtUserSetSysColors( UINT *args ) +{ + INT count = get_ulong( &args ); + const INT *colors = get_ptr( &args ); + const COLORREF *values = get_ptr( &args ); + + return NtUserSetSysColors( count, colors, values ); +} + +NTSTATUS WINAPI wow64_NtUserSetSystemMenu( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + HMENU menu = get_handle( &args ); + + return NtUserSetSystemMenu( hwnd, menu ); +} + +NTSTATUS WINAPI wow64_NtUserSetSystemTimer( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + UINT_PTR id = get_ulong( &args ); + UINT timeout = get_ulong( &args ); + + return NtUserSetSystemTimer( hwnd, id, timeout ); +} + +NTSTATUS WINAPI wow64_NtUserSetThreadDesktop( UINT *args ) +{ + HDESK handle = get_handle( &args ); + + return NtUserSetThreadDesktop( handle ); +} +#endif + +NTSTATUS WINAPI wow64_NtUserSetTimer( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + UINT_PTR id = get_ulong( &args ); + UINT timeout = get_ulong( &args ); + TIMERPROC proc = get_ptr( &args ); +#ifndef __REACTOS__ + ULONG tolerance = get_ulong( &args ); + + return NtUserSetTimer( hwnd, id, timeout, proc, tolerance ); +#else + return NtUserSetTimer( hwnd, id, timeout, proc ); +#endif +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserSetWinEventHook( UINT *args ) +{ + DWORD event_min = get_ulong( &args ); + DWORD event_max = get_ulong( &args ); + HMODULE inst = get_ptr( &args ); + UNICODE_STRING32 *module32 = get_ptr( &args ); + WINEVENTPROC proc = get_ptr(&args ); + DWORD pid = get_ulong( &args ); + DWORD tid = get_ulong( &args ); + DWORD flags = get_ulong( &args ); + UNICODE_STRING module; + HWINEVENTHOOK ret; + + ret = NtUserSetWinEventHook( event_min, event_max, inst, + unicode_str_32to64( &module, module32 ), + proc, pid, tid, flags ); + return HandleToUlong( ret ); +} +#endif + +NTSTATUS WINAPI wow64_NtUserSetWindowLong( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + INT offset = get_ulong( &args ); + LONG newval = get_ulong( &args ); + BOOL ansi = get_ulong( &args ); + + switch (offset) + { + case GWLP_HINSTANCE: + case GWLP_WNDPROC: + return NtUserSetWindowLongPtr( hwnd, offset, (ULONG)newval, ansi ); + } + + return NtUserSetWindowLong( hwnd, offset, newval, ansi ); +} + +NTSTATUS WINAPI wow64_NtUserSetWindowLongPtr( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + INT offset = get_ulong( &args ); + LONG_PTR newval = get_ulong( &args ); + BOOL ansi = get_ulong( &args ); + + return NtUserSetWindowLongPtr( hwnd, offset, newval, ansi ); +} + +NTSTATUS WINAPI wow64_NtUserSetWindowPlacement( UINT *args ) +{ + HWND hwnd = get_handle( &args ); +#ifndef __REACTOS__ + const WINDOWPLACEMENT *wpl = get_ptr( &args ); +#else + WINDOWPLACEMENT *wpl = get_ptr(&args); +#endif + + return NtUserSetWindowPlacement( hwnd, wpl ); +} + +NTSTATUS WINAPI wow64_NtUserSetWindowPos( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + HWND after = get_handle( &args ); + INT x = get_ulong( &args ); + INT y = get_ulong( &args ); + INT cx = get_ulong( &args ); + INT cy = get_ulong( &args ); + UINT flags = get_ulong( &args ); + + return NtUserSetWindowPos( hwnd, after, x, y, cx, cy, flags ); +} + +NTSTATUS WINAPI wow64_NtUserSetWindowRgn( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + HRGN hrgn = get_handle( &args ); + BOOL redraw = get_ulong( &args ); + + return NtUserSetWindowRgn( hwnd, hrgn, redraw ); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserSetWindowWord( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + INT offset = get_ulong( &args ); + WORD newval = get_ulong( &args ); + + return NtUserSetWindowWord( hwnd, offset, newval ); +} + +NTSTATUS WINAPI wow64_NtUserSetWindowsHookEx( UINT *args ) +{ + HINSTANCE inst = get_ptr( &args ); + UNICODE_STRING32 *module32 = get_ptr( &args ); + DWORD tid = get_ulong( &args ); + INT id = get_ulong( &args ); + HOOKPROC proc = get_ptr( &args ); + BOOL ansi = get_ulong( &args ); + UNICODE_STRING module; + HHOOK ret; + + ret = NtUserSetWindowsHookEx( inst, unicode_str_32to64( &module, module32 ), + tid, id, proc, ansi ); + return HandleToUlong( ret ); +} +#endif + +NTSTATUS WINAPI wow64_NtUserShowCaret( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + + return NtUserShowCaret( hwnd ); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserShowCursor( UINT *args ) +{ + BOOL show = get_ulong( &args ); + + return NtUserShowCursor( show ); +} +#endif + +NTSTATUS WINAPI wow64_NtUserShowScrollBar( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + INT bar = get_ulong( &args ); + BOOL show = get_ulong( &args ); + + return NtUserShowScrollBar( hwnd, bar, show ); +} + +NTSTATUS WINAPI wow64_NtUserShowWindow( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + INT cmd = get_ulong( &args ); + + return NtUserShowWindow( hwnd, cmd ); +} + +NTSTATUS WINAPI wow64_NtUserShowWindowAsync( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + INT cmd = get_ulong( &args ); + + return NtUserShowWindowAsync( hwnd, cmd ); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserSwitchDesktop( UINT *args ) +{ + HDESK handle = get_handle( &args ); + + return NtUserSwitchDesktop( handle ); +} +#endif + +NTSTATUS WINAPI wow64_NtUserSystemParametersInfo( UINT *args ) +{ + UINT action = get_ulong( &args ); + UINT val = get_ulong( &args ); + void *ptr = get_ptr( &args ); + UINT winini = get_ulong( &args ); + + switch (action) + { + case SPI_GETSERIALKEYS: + if (ptr) + { + struct + { + UINT cbSize; + DWORD dwFlags; + ULONG lpszActivePort; + ULONG lpszPort; + UINT iBaudRate; + UINT iPortState; + UINT iActive; + } *keys32 = ptr; + SERIALKEYSW keys; + + if (keys32->cbSize != sizeof(*keys32)) return FALSE; + keys.cbSize = sizeof(keys); + if (!NtUserSystemParametersInfo( action, val, &keys, winini )) return FALSE; + keys32->dwFlags = keys.dwFlags; + keys32->lpszActivePort = PtrToUlong( keys.lpszActivePort ); + keys32->lpszPort = PtrToUlong( keys.lpszPort ); + keys32->iBaudRate = keys.iBaudRate; + keys32->iPortState = keys.iPortState; + keys32->iActive = keys.iActive; + return TRUE; + } + break; + + case SPI_GETSOUNDSENTRY: + if (ptr) + { + struct + { + UINT cbSize; + DWORD dwFlags; + DWORD iFSTextEffect; + DWORD iFSTextEffectMSec; + DWORD iFSTextEffectColorBits; + DWORD iFSGrafEffect; + DWORD iFSGrafEffectMSec; + DWORD iFSGrafEffectColor; + DWORD iWindowsEffect; + DWORD iWindowsEffectMSec; + ULONG lpszWindowsEffectDLL; + DWORD iWindowsEffectOrdinal; + } *entry32 = ptr; + SOUNDSENTRYW entry; + + if (entry32->cbSize != sizeof(*entry32)) return FALSE; + entry.cbSize = sizeof(entry); + if (!NtUserSystemParametersInfo( action, val, &entry, winini )) return FALSE; + entry32->dwFlags = entry.dwFlags; + entry32->iFSTextEffect = entry.iFSTextEffect; + entry32->iFSTextEffectMSec = entry.iFSTextEffectMSec; + entry32->iFSTextEffectColorBits = entry.iFSTextEffectColorBits; + entry32->iFSGrafEffect = entry.iFSGrafEffect; + entry32->iFSGrafEffectMSec = entry.iFSGrafEffectMSec; + entry32->iFSGrafEffectColor = entry.iFSGrafEffectColor; + entry32->iWindowsEffect = entry.iWindowsEffect; + entry32->iWindowsEffectMSec = entry.iWindowsEffectMSec; + entry32->lpszWindowsEffectDLL = PtrToUlong( entry.lpszWindowsEffectDLL ); + entry32->iWindowsEffectOrdinal = entry.iWindowsEffectOrdinal; + return TRUE; + } + break; + + case SPI_GETHIGHCONTRAST: + if (ptr) + { + struct + { + UINT cbSize; + DWORD dwFlags; + ULONG lpszDefaultScheme; + } *info32 = ptr; + HIGHCONTRASTW info; + + if (info32->cbSize != sizeof(*info32)) return FALSE; + info.cbSize = sizeof(info); + if (!NtUserSystemParametersInfo( action, val, &info, winini )) return FALSE; + info32->dwFlags = info.dwFlags; + info32->lpszDefaultScheme = PtrToUlong( info.lpszDefaultScheme ); + return TRUE; + } + break; + } + + return NtUserSystemParametersInfo( action, val, ptr, winini ); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserSystemParametersInfoForDpi( UINT *args ) +{ + UINT action = get_ulong( &args ); + UINT val = get_ulong( &args ); + void *ptr = get_ptr( &args ); + UINT winini = get_ulong( &args ); + UINT dpi = get_ulong( &args ); + + return NtUserSystemParametersInfoForDpi( action, val, ptr, winini, dpi ); +} + +NTSTATUS WINAPI wow64_NtUserThunkedMenuInfo( UINT *args ) +{ + HMENU menu = get_handle( &args ); + MENUINFO32 *info32 = get_ptr( &args ); + MENUINFO info; + + if (info32) + { + info.cbSize = sizeof(info); + info.fMask = info32->fMask; + info.dwStyle = info32->dwStyle; + info.cyMax = info32->cyMax; + info.hbrBack = UlongToHandle( info32->hbrBack ); + info.dwContextHelpID = info32->dwContextHelpID; + info.dwMenuData = info32->dwMenuData; + } + + return NtUserThunkedMenuInfo( menu, info32 ? &info : NULL ); +} +#endif + +NTSTATUS WINAPI wow64_NtUserThunkedMenuItemInfo( UINT *args ) +{ + HMENU handle = get_handle( &args ); + UINT pos = get_ulong( &args ); + UINT flags = get_ulong( &args ); + UINT method = get_ulong( &args ); + MENUITEMINFOW32 *info32 = get_ptr( &args ); + UNICODE_STRING32 *str32 = get_ptr( &args ); + MENUITEMINFOW info = { sizeof(info) }, *info_ptr; + UNICODE_STRING str; + UINT ret; + + if (info32) + { + info.cbSize = sizeof(info); + info.fMask = info32->fMask; +#ifndef __REACTOS__ + switch (method) + { + case NtUserSetMenuItemInfo: + case NtUserInsertMenuItem: +#else + if (method) + { +#endif + info.fType = info32->fType; + info.fState = info32->fState; + info.wID = info32->wID; + info.hSubMenu = LongToHandle( info32->hSubMenu ); + info.hbmpChecked = UlongToHandle( info32->hbmpChecked ); + info.hbmpUnchecked = UlongToHandle( info32->hbmpUnchecked ); + info.dwItemData = info32->dwItemData; + info.dwTypeData = UlongToPtr( info32->dwTypeData ); + info.cch = info32->cch; + info.hbmpItem = UlongToHandle( info32->hbmpItem ); +#ifndef __REACTOS__ + break; + case NtUserCheckMenuRadioItem: + info.cch = info32->cch; + break; + case NtUserGetMenuItemInfoA: + case NtUserGetMenuItemInfoW: +#else + } + else + { +#endif + info.dwTypeData = UlongToPtr( info32->dwTypeData ); + info.cch = info32->cch; +#ifndef __REACTOS__ + break; + } +#else + } +#endif + info_ptr = &info; + } + else info_ptr = NULL; + + ret = NtUserThunkedMenuItemInfo( handle, pos, flags, method, info_ptr, + unicode_str_32to64( &str, str32 )); + + if (info_ptr) + { +#ifndef __REACTOS__ + switch (method) + { + case NtUserGetMenuItemInfoA: + case NtUserGetMenuItemInfoW: +#else + if (method) + { +#endif + if (info.fMask & (MIIM_TYPE | MIIM_STRING | MIIM_FTYPE)) + info32->fType = info.fType; + if (info.fMask & (MIIM_TYPE | MIIM_BITMAP)) + info32->hbmpItem = HandleToUlong( info.hbmpItem ); + if (info.fMask & (MIIM_TYPE | MIIM_STRING)) + { + info32->dwTypeData = (UINT_PTR)info.dwTypeData; + info32->cch = info.cch; + } + if (info.fMask & MIIM_STATE) info32->fState = info.fState; + if (info.fMask & MIIM_ID) info32->wID = info.wID; + info32->hSubMenu = HandleToUlong( info.hSubMenu ); + if (info.fMask & MIIM_CHECKMARKS) + { + info32->hbmpChecked = HandleToUlong( info.hbmpChecked ); + info32->hbmpUnchecked = HandleToUlong( info.hbmpUnchecked ); + } + if (info.fMask & MIIM_DATA) info32->dwItemData = info.dwItemData; +#ifndef __REACTOS__ + break; + } +#else + } +#endif + } + + return ret; +} + +NTSTATUS WINAPI wow64_NtUserToUnicodeEx( UINT *args ) +{ + UINT virt = get_ulong( &args ); + UINT scan = get_ulong( &args ); +#ifndef __REACTOS__ + const BYTE *state = get_ptr( &args ); +#else + BYTE *state = get_ptr( &args ); +#endif + WCHAR *str = get_ptr( &args ); + int size = get_ulong( &args ); + UINT flags = get_ulong( &args ); + HKL layout = get_handle( &args ); + + return NtUserToUnicodeEx( virt, scan, state, str, size, flags, layout ); +} + +NTSTATUS WINAPI wow64_NtUserTrackMouseEvent( UINT *args ) +{ + struct + { + DWORD cbSize; + DWORD dwFlags; + UINT32 hwndTrack; + DWORD dwHoverTime; + } *info32 = get_ptr( &args ); + TRACKMOUSEEVENT info; + BOOL ret; + + if (info32->cbSize != sizeof(*info32)) + { + set_last_error32( ERROR_INVALID_PARAMETER ); + return FALSE; + } + + info.cbSize = sizeof(info); + info.dwFlags = info32->dwFlags; + info.hwndTrack = LongToHandle( info32->hwndTrack ); + info.dwHoverTime = info32->dwHoverTime; + ret = NtUserTrackMouseEvent( &info ); + info32->dwFlags = info.dwFlags; + info32->hwndTrack = HandleToUlong( info.hwndTrack ); + info32->dwHoverTime = info.dwHoverTime; + return ret; +} + +NTSTATUS WINAPI wow64_NtUserTrackPopupMenuEx( UINT *args ) +{ + HMENU handle = get_handle( &args ); + UINT flags = get_ulong( &args ); + int x = get_ulong( &args ); + int y = get_ulong( &args ); + HWND hwnd = get_handle( &args ); + TPMPARAMS *params = get_ptr( &args ); + + return NtUserTrackPopupMenuEx( handle, flags, x, y, hwnd, params ); +} + +NTSTATUS WINAPI wow64_NtUserTranslateAccelerator( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + HACCEL accel = get_handle( &args ); + MSG32 *msg32 = get_ptr( &args ); + + MSG msg; + + return NtUserTranslateAccelerator( hwnd, accel, msg_32to64( &msg, msg32 )); +} + +NTSTATUS WINAPI wow64_NtUserTranslateMessage( UINT *args ) +{ + const MSG32 *msg32 = get_ptr( &args ); + UINT flags = get_ulong( &args ); + MSG msg; + + return NtUserTranslateMessage( msg_32to64( &msg, msg32 ), flags ); +} + +NTSTATUS WINAPI wow64_NtUserUnhookWinEvent( UINT *args ) +{ + HWINEVENTHOOK handle = get_handle( &args ); + + return NtUserUnhookWinEvent( handle ); +} + +NTSTATUS WINAPI wow64_NtUserUnhookWindowsHookEx( UINT *args ) +{ + HHOOK handle = get_handle( &args ); + + return NtUserUnhookWindowsHookEx( handle ); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserUnregisterClass( UINT *args ) +{ + UNICODE_STRING32 *name32 = get_ptr( &args ); + HINSTANCE instance = get_ptr( &args ); + struct client_menu_name32 *menu_name32 = get_ptr( &args ); + + UNICODE_STRING name; + struct client_menu_name menu_name; + BOOL ret; + + ret = NtUserUnregisterClass( unicode_str_32to64( &name, name32 ), instance, &menu_name ); + if (ret) client_menu_name_64to32( &menu_name, menu_name32 ); + return ret; +} +#endif + +NTSTATUS WINAPI wow64_NtUserUnregisterHotKey( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + int id = get_ulong( &args ); + + return NtUserUnregisterHotKey( hwnd, id ); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserUpdateInputContext( UINT *args ) +{ + HIMC handle = get_handle( &args ); + UINT attr = get_ulong( &args ); + UINT_PTR value = get_ulong( &args ); + + return NtUserUpdateInputContext( handle, attr, value ); +} +#endif + +NTSTATUS WINAPI wow64_NtUserUpdateLayeredWindow( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + HDC hdc_dst = get_handle( &args ); +#ifndef __REACTOS__ + const POINT *pts_dst = get_ptr( &args ); + const SIZE *size = get_ptr( &args ); + HDC hdc_src = get_handle( &args ); + const POINT *pts_src = get_ptr( &args ); + COLORREF key = get_ulong( &args ); + const BLENDFUNCTION *blend = get_ptr( &args ); + DWORD flags = get_ulong( &args ); + const RECT *dirty = get_ptr( &args ); +#else + POINT *pts_dst = get_ptr( &args ); + SIZE *size = get_ptr( &args ); + HDC hdc_src = get_handle( &args ); + POINT *pts_src = get_ptr( &args ); + COLORREF key = get_ulong( &args ); + BLENDFUNCTION *blend = get_ptr( &args ); + DWORD flags = get_ulong( &args ); + RECT *dirty = get_ptr( &args ); +#endif + + return NtUserUpdateLayeredWindow( hwnd, hdc_dst, pts_dst, size, hdc_src, pts_src, + key, blend, flags, dirty ); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserValidateRect( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + const RECT *rect = get_ptr( &args ); + + return NtUserValidateRect( hwnd, rect ); +} + +NTSTATUS WINAPI wow64_NtUserVkKeyScanEx( UINT *args ) +{ + WCHAR chr = get_ulong( &args ); + HKL layout = get_handle( &args ); + + return NtUserVkKeyScanEx( chr, layout ); +} + +NTSTATUS WINAPI wow64_NtUserWaitForInputIdle( UINT *args ) +{ + HANDLE process = get_handle( &args ); + DWORD timeout = get_ulong( &args ); + BOOL wow = get_ulong( &args ); + + return NtUserWaitForInputIdle( process, timeout, wow ); +} + +NTSTATUS WINAPI wow64_NtUserWaitMessage( UINT *args ) +{ + return NtUserWaitMessage(); +} + +NTSTATUS WINAPI wow64_NtUserWindowFromDC( UINT *args ) +{ + HDC hdc = get_handle( &args ); + + return HandleToUlong( NtUserWindowFromDC( hdc )); +} +#endif + +NTSTATUS WINAPI wow64_NtUserWindowFromPoint( UINT *args ) +{ + LONG x = get_ulong( &args ); + LONG y = get_ulong( &args ); + + return HandleToUlong( NtUserWindowFromPoint( x, y )); +} + +#ifndef __REACTOS__ +NTSTATUS WINAPI wow64_NtUserDisplayConfigGetDeviceInfo( UINT *args ) +{ + DISPLAYCONFIG_DEVICE_INFO_HEADER *packet = get_ptr( &args ); + + return NtUserDisplayConfigGetDeviceInfo( packet ); +} +#endif diff --git a/dll/wow64win/user_ros.c b/dll/wow64win/user_ros.c new file mode 100644 index 0000000000000..cf85b23abc35a --- /dev/null +++ b/dll/wow64win/user_ros.c @@ -0,0 +1,1073 @@ +/* + * Wine WOW64 ReactOS port + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: wow64win.dll + * FILE: dll/wow64win/user_ros.c + * PROGRAMMER: Marcin Jabłoński + */ + +#include "wow64win_private.h" +#include + +#include +#pragma intrinsic(_ReturnAddress) + +#include "../../../win32ss/include/callback.h" + +#define DEFINE_USER32_CALLBACK(id, value, fn) NTSTATUS WINAPI wow64win_Nt ## fn (PVOID, ULONG); +#include "../../../win32ss/include/u32cb.h" +#undef DEFINE_USER32_CALLBACK + +NTSTATUS WINAPI (*UserCallbacks[])(PVOID Arguments, ULONG ArgumentLength) = +{ +#define DEFINE_USER32_CALLBACK(id, value, fn) wow64win_Nt ## fn, +#include "../../../win32ss/include/u32cb.h" +#undef DEFINE_USER32_CALLBACK +}; + +static ULONG hUser32 = 0; +static PFNCLIENT apfnClientProcs32W; +static PFNCLIENT apfnClientProcs32A; + +static MSG32 *msg_64to32( const MSG *msg64, MSG32 *msg32 ) +{ + MSG32 msg; + + if (!msg32) return NULL; + + msg.hwnd = HandleToLong( msg64->hwnd ); + msg.message = msg64->message; + msg.wParam = msg64->wParam; + msg.lParam = msg64->lParam; + msg.time = msg64->time; + msg.pt = msg64->pt; + memcpy( msg32, &msg, sizeof(msg) ); + return msg32; +} + +NTSTATUS WINAPI wow64_NtUserProcessConnect(UINT* pArgs) +{ + HANDLE ProcessHandle = get_handle(&pArgs); + PUSERCONNECT pUserConnect = get_ptr(&pArgs); + ULONG Size = get_ulong(&pArgs); + /* Copy the memory manually to prevent the kernel complaining about + misaligned memory. */ + USERCONNECT UserConnect; + + NTSTATUS Status; + + if (Size != sizeof(USERCONNECT) || pUserConnect == NULL) + { + return STATUS_UNSUCCESSFUL; + } + + Status = NtUserProcessConnect(ProcessHandle, &UserConnect, sizeof(UserConnect)); + + g_ServerInfo = UserConnect.siClient.psi; + + *pUserConnect = UserConnect; + return Status; +} + +/* FIXME: HACK: It is very unlikely that this is how Windows implements this. + Maybe Windows loads 64-bit user32.dll, so it can run native WndProcs? + + Is there even a guarantee, that we can't get a 64 bit WndProc from places + other than PFNCLIENT tables? */ +static +ULONG +Translate64WndProc(WNDPROC WndProc, BOOLEAN bIsAnsi) +{ + const WNDPROC* ClientA = (WNDPROC*)&g_ServerInfo->apfnClientA; + const WNDPROC* ClientW = (WNDPROC*)&g_ServerInfo->apfnClientW; + const WNDPROC* ClientA32 = (WNDPROC*)&apfnClientProcs32A; + const WNDPROC* ClientW32 = (WNDPROC*)&apfnClientProcs32W; + const WNDPROC* Client32 = bIsAnsi ? ((WNDPROC*)&apfnClientProcs32A) : ((WNDPROC*)&apfnClientProcs32W); + + const size_t nWndProcsInClient = sizeof(PFNCLIENT) / sizeof(WNDPROC); + int i; + + for (i = 0; i < nWndProcsInClient; i++) + { + if (ClientA[i] == WndProc || ClientW[i] == WndProc) + { + return PtrToUlong(Client32[i]); + } + + if (ClientA32[i] == WndProc || ClientW32[i] == WndProc) + { + return PtrToUlong(Client32[i]); + } + } + + /* No mapping found - return as is. */ + return PtrToUlong(WndProc); +} + +VOID +WndProcParams64To32(PWINDOWPROC_CALLBACK_ARGUMENTS CallbackArgs, + PWINDOWPROC_CALLBACK_ARGUMENTS32 Arguments32) +{ + Arguments32->Proc = Translate64WndProc(CallbackArgs->Proc, CallbackArgs->IsAnsiProc); + Arguments32->IsAnsiProc = CallbackArgs->IsAnsiProc; + Arguments32->Wnd = HandleToUlong(CallbackArgs->Wnd); + Arguments32->Msg = CallbackArgs->Msg; + Arguments32->wParam = CallbackArgs->wParam; + Arguments32->lParam = (ULONG)CallbackArgs->lParam; + Arguments32->lParamBufferSize = CallbackArgs->lParamBufferSize; + Arguments32->Result = CallbackArgs->Result; +} + +VOID +WndProcParams32To64(PWINDOWPROC_CALLBACK_ARGUMENTS OutArguments, + PWINDOWPROC_CALLBACK_ARGUMENTS32 CallbackArgs) +{ + WINDOWPROC_CALLBACK_ARGUMENTS Data = { 0 }, *Arguments = &Data; + + Arguments->Proc = UlongToPtr(CallbackArgs->Proc); + Arguments->IsAnsiProc = CallbackArgs->IsAnsiProc; + Arguments->Wnd = UlongToHandle(CallbackArgs->Wnd); + Arguments->Msg = CallbackArgs->Msg; + Arguments->wParam = CallbackArgs->wParam; + Arguments->lParam = CallbackArgs->lParam; + Arguments->lParamBufferSize = CallbackArgs->lParamBufferSize; + Arguments->Result = CallbackArgs->Result; + + *OutArguments = *Arguments; +} + +NTSTATUS +WINAPI +wow64win_NtUser32CallWindowProcFromKernel(PVOID Arguments, ULONG ArgumentLength) +{ + return wow64_NtUserCallWinProc(Arguments, ArgumentLength); +} + +NTSTATUS +WINAPI +wow64win_NtUser32CallSendAsyncProcForKernel(PVOID Arguments, ULONG ArgumentLength) +{ + DPRINT1("UNHANDLED USER CALLBACK " __FILE__ ":%d\n", __LINE__); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +WINAPI +wow64win_NtUser32LoadSysMenuTemplateForKernel(PVOID Arguments, ULONG ArgumentLength) +{ + DPRINT1("UNHANDLED USER CALLBACK " __FILE__ ":%d\n", __LINE__); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +WINAPI +wow64win_NtUser32SetupDefaultCursors(PVOID Arguments, ULONG ArgumentLength) +{ + DPRINT1("UNHANDLED USER CALLBACK " __FILE__ ":%d\n", __LINE__); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +WINAPI +wow64win_NtUser32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength) +{ + DPRINT1("UNHANDLED USER CALLBACK " __FILE__ ":%d\n", __LINE__); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +WINAPI +wow64win_NtUser32CallEventProcFromKernel(PVOID Arguments, ULONG ArgumentLength) +{ + DPRINT1("UNHANDLED USER CALLBACK " __FILE__ ":%d\n", __LINE__); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +WINAPI +wow64win_NtUser32CallLoadMenuFromKernel(PVOID Arguments, ULONG ArgumentLength) +{ + PLOADMENU_CALLBACK_ARGUMENTS pLoadMenu; + PLOADMENU_CALLBACK_ARGUMENTS32 pLoadMenu32; + NTSTATUS Status; + PVOID pResult; + ULONG nRetLen = 0; + + pLoadMenu = Arguments; + pLoadMenu32 = Arguments; + + C_ASSERT(sizeof(*pLoadMenu) > sizeof(*pLoadMenu32)); + + if (ArgumentLength < sizeof(*pLoadMenu)) + { + return STATUS_UNSUCCESSFUL; + } + + /* FIXME: check if pLoadMenu->hModule really is 64-bit USER32 */ + if ((ULONG_PTR)pLoadMenu->hModule & 0xFFFFFFFF00000000) + { + pLoadMenu32->hModule = hUser32; + } + else + { + pLoadMenu32->hModule = HandleToUlong(pLoadMenu->hModule); + } + + pLoadMenu32->InterSource = PtrToUlong(pLoadMenu->InterSource); + memcpy(pLoadMenu32->MenuName, + pLoadMenu->MenuName, ArgumentLength + - sizeof(pLoadMenu->InterSource) + - sizeof(pLoadMenu->hModule)); + + Status = Wow64KiUserCallbackDispatcher(NumUser32CallLoadMenuFromKernel, + pLoadMenu32, + ArgumentLength - (sizeof(*pLoadMenu) - sizeof(*pLoadMenu32)), + &pResult, + &nRetLen); + + return NtCallbackReturn(pResult, nRetLen, Status); +} + +NTSTATUS +WINAPI +wow64win_NtUser32CallClientThreadSetupFromKernel(PVOID Arguments, ULONG ArgumentLength) +{ + ULONG nRetLen = 0; + PVOID pResult; + NTSTATUS Status; + struct _CLIENTINFO32* pClientInfo32; + PCLIENTINFO pClientInfo; + + Status = Wow64KiUserCallbackDispatcher(NumUser32CallClientThreadSetupFromKernel, + Arguments, + ArgumentLength, + &pResult, + &nRetLen); + + + NtCurrentPeb32()->GdiSharedHandleTable = PtrToUlong(NtCurrentPeb()->GdiSharedHandleTable); + NtCurrentPeb32()->GdiDCAttributeList = NtCurrentPeb()->GdiDCAttributeList; + + pClientInfo = (PCLIENTINFO) &NtCurrentTeb()->Win32ClientInfo; + pClientInfo32 = (PCLIENTINFO32) &NtCurrentTeb32()->Win32ClientInfo; + + pClientInfo32->CI_flags = pClientInfo->CI_flags; + pClientInfo32->cSpins = pClientInfo->cSpins; + pClientInfo32->dwExpWinVer = pClientInfo->dwExpWinVer; + pClientInfo32->dwCompatFlags = pClientInfo->dwCompatFlags; + pClientInfo32->dwCompatFlags2 = pClientInfo->dwCompatFlags2; + pClientInfo32->dwTIFlags = pClientInfo->dwTIFlags; + pClientInfo32->pDeskInfo = PtrToUlong(pClientInfo->pDeskInfo); + pClientInfo32->ulClientDelta = pClientInfo->ulClientDelta; + pClientInfo32->phkCurrent = PtrToUlong(pClientInfo->phkCurrent); + pClientInfo32->fsHooks = pClientInfo->fsHooks; + pClientInfo32->CallbackWnd[0] = HandleToUlong(pClientInfo->CallbackWnd.hWnd); + pClientInfo32->CallbackWnd[1] = PtrToUlong(pClientInfo->CallbackWnd.pWnd); + pClientInfo32->dwHookCurrent = pClientInfo->dwHookCurrent; + pClientInfo32->cInDDEMLCallback = pClientInfo->cInDDEMLCallback; + pClientInfo32->pClientThreadInfo = PtrToUlong(pClientInfo->pClientThreadInfo); + pClientInfo32->dwHookData = pClientInfo->dwHookData; + pClientInfo32->dwKeyCache = pClientInfo->dwKeyCache; + + RtlCopyMemory(pClientInfo32->afKeyState, + pClientInfo->afKeyState, + sizeof(pClientInfo32->afKeyState)); + + pClientInfo32->dwAsyncKeyCache = pClientInfo->dwAsyncKeyCache; + + RtlCopyMemory(pClientInfo32->afAsyncKeyState, + pClientInfo->afAsyncKeyState, + sizeof(pClientInfo32->afAsyncKeyState)); + + RtlCopyMemory(pClientInfo32->afAsyncKeyStateRecentDow, + pClientInfo->afAsyncKeyStateRecentDow, + sizeof(pClientInfo32->afAsyncKeyStateRecentDow)); + + pClientInfo32->hKL = HandleToUlong(pClientInfo->hKL); + pClientInfo32->CodePage = pClientInfo->CodePage; + pClientInfo32->achDbcsCF[0] = pClientInfo->achDbcsCF[0]; + pClientInfo32->achDbcsCF[1] = pClientInfo->achDbcsCF[1]; + + msg_64to32(&pClientInfo->msgDbcsCB, &pClientInfo32->msgDbcsCB); + + pClientInfo32->lpdwRegisteredClasses = PtrToUlong(pClientInfo->lpdwRegisteredClasses); + pClientInfo32->ppi = PtrToUlong(pClientInfo->ppi); + + return Status; +} + +NTSTATUS +WINAPI +wow64win_NtUser32CallClientLoadLibraryFromKernel(PVOID Arguments, ULONG ArgumentLength) +{ + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +WINAPI +wow64win_NtUser32CallGetCharsetInfo(PVOID Arguments, ULONG ArgumentLength) +{ + DPRINT1("UNHANDLED USER CALLBACK " __FILE__ ":%d\n", __LINE__); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +WINAPI +wow64win_NtUser32CallCopyImageFromKernel(PVOID Arguments, ULONG ArgumentLength) +{ + PCOPYIMAGE_CALLBACK_ARGUMENTS32 pCommon32 = Arguments; + COPYIMAGE_CALLBACK_ARGUMENTS Common; + + NTSTATUS Status; + ULONG nRetLen = 0; + PVOID pResult; + + Common.hImage = UlongToHandle(pCommon32->hImage); + Common.uType = pCommon32->uType; + Common.cxDesired = pCommon32->cxDesired; + Common.cyDesired = pCommon32->cyDesired; + Common.fuFlags = pCommon32->fuFlags; + + Status = Wow64KiUserCallbackDispatcher(NumUser32CallCopyImageFromKernel, + &Common, + sizeof(Common), + &pResult, + &nRetLen); + + return NtCallbackReturn(pResult, nRetLen, Status); +} + +NTSTATUS +WINAPI +wow64win_NtUser32CallSetWndIconsFromKernel(PVOID Arguments, ULONG ArgumentLength) +{ + DPRINT1("UNHANDLED USER CALLBACK " __FILE__ ":%d\n", __LINE__); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +WINAPI +wow64win_NtUser32DeliverUserAPC(PVOID Arguments, ULONG ArgumentLength) +{ + DPRINT1("UNHANDLED USER CALLBACK " __FILE__ ":%d\n", __LINE__); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +WINAPI +wow64win_NtUser32CallDDEPostFromKernel(PVOID Arguments, ULONG ArgumentLength) +{ + DPRINT1("UNHANDLED USER CALLBACK " __FILE__ ":%d\n", __LINE__); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +WINAPI +wow64win_NtUser32CallDDEGetFromKernel(PVOID Arguments, ULONG ArgumentLength) +{ + DPRINT1("UNHANDLED USER CALLBACK " __FILE__ ":%d\n", __LINE__); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +WINAPI +wow64win_NtUser32CallOBMFromKernel(PVOID Arguments, ULONG ArgumentLength) +{ + DPRINT1("UNHANDLED USER CALLBACK " __FILE__ ":%d\n", __LINE__); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +WINAPI +wow64win_NtUser32CallLPKFromKernel(PVOID Arguments, ULONG ArgumentLength) +{ + PLPK_CALLBACK_ARGUMENTS32 pLpk32; + PLPK_CALLBACK_ARGUMENTS pLpk64; + + NTSTATUS Status; + PVOID pResult; + ULONG nRetLen; + + pLpk32 = (PLPK_CALLBACK_ARGUMENTS32)Arguments; + pLpk64 = (PLPK_CALLBACK_ARGUMENTS)Arguments; + + pLpk32->lpString = PtrToUlong(pLpk64->lpString); + pLpk32->hdc = HandleToUlong(pLpk64->hdc); + pLpk32->x = pLpk64->x; + pLpk32->y = pLpk64->y; + pLpk32->flags = pLpk64->flags; + pLpk32->rect = pLpk64->rect; + pLpk32->count = pLpk64->count; + pLpk32->bRect = pLpk64->bRect; + + Status = Wow64KiUserCallbackDispatcher(NumUser32CallLPKFromKernel, + pLpk32, + ArgumentLength, + &pResult, + &nRetLen); + + return NtCallbackReturn(pResult, nRetLen, Status); +} + +NTSTATUS +WINAPI +wow64win_NtUser32CallUMPDFromKernel(PVOID Arguments, ULONG ArgumentLength) +{ + DPRINT1("UNHANDLED USER CALLBACK " __FILE__ ":%d\n", __LINE__); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +WINAPI +wow64win_NtUser32CallImmProcessKeyFromKernel(PVOID Arguments, ULONG ArgumentLength) +{ + DPRINT1("UNHANDLED USER CALLBACK " __FILE__ ":%d\n", __LINE__); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +WINAPI +wow64win_NtUser32CallImmLoadLayoutFromKernel(PVOID Arguments, ULONG ArgumentLength) +{ + DPRINT1("UNHANDLED USER CALLBACK " __FILE__ ":%d\n", __LINE__); + return STATUS_NOT_IMPLEMENTED; +} + +ATOM +WINAPI +wow64_NtUserGetClassInfo(UINT* pArgs) +{ + HINSTANCE hInstance = get_ptr(&pArgs); + UNICODE_STRING32* ClassName32 = get_ptr(&pArgs); + WNDCLASSEXW32* lpWndClassEx32 = get_ptr(&pArgs); + ULONG *ppszMenuName32 = get_ptr(&pArgs); + BOOL bAnsi = get_ulong(&pArgs); + + UNICODE_STRING ClassName = { 0 }; + LPWSTR pszMenuName = NULL; + WNDCLASSEXW wndClassEx = { 0 }; + + ATOM Atom; + + wndClassEx.cbSize = sizeof(wndClassEx); + + Atom = NtUserGetClassInfo(hInstance, + unicode_str_32to64( &ClassName, ClassName32 ), + &wndClassEx, + &pszMenuName, + bAnsi); + if (Atom == 0) + { + return Atom; + } + + lpWndClassEx32->style = wndClassEx.style; + lpWndClassEx32->lpfnWndProc = PtrToUlong(wndClassEx.lpfnWndProc); + lpWndClassEx32->cbClsExtra = wndClassEx.cbClsExtra; + lpWndClassEx32->cbWndExtra = wndClassEx.cbWndExtra; + lpWndClassEx32->hInstance = PtrToUlong(wndClassEx.hInstance); + lpWndClassEx32->hIcon = HandleToUlong(wndClassEx.hIcon); + lpWndClassEx32->hCursor = HandleToUlong(wndClassEx.hCursor); + lpWndClassEx32->hbrBackground = HandleToUlong(wndClassEx.hbrBackground); + lpWndClassEx32->lpszMenuName = PtrToUlong(wndClassEx.lpszMenuName); + lpWndClassEx32->lpszClassName = PtrToUlong(wndClassEx.lpszClassName); + lpWndClassEx32->hIconSm = HandleToUlong(wndClassEx.hIconSm); + + if (ppszMenuName32 != NULL) + { + *ppszMenuName32 = PtrToUlong(pszMenuName); + } + + return Atom; +} + +NTSTATUS +WINAPI +wow64_NtUserCallHwndLock(UINT *pArgs) +{ + HWND hWnd = get_handle(&pArgs); + DWORD Code = get_ulong(&pArgs); + + return NtUserCallHwndLock(hWnd, Code); +} + +ULONG_PTR +WINAPI +wow64_NtUserGetThreadState(UINT *pArgs) +{ + DWORD Routine = get_ulong(&pArgs); + + NTSTATUS Status = NtUserGetThreadState(Routine); + + NtCurrentTeb32()->Win32ThreadInfo = PtrToUlong(NtCurrentTeb()->Win32ThreadInfo); + return Status; +} + +NTSTATUS +WINAPI +wow64_NtUserInitializeClientPfnArrays(UINT *pArgs) +{ + PPFNCLIENT pProcsA32 = get_ptr(&pArgs); + PPFNCLIENT pProcsW32 = get_ptr(&pArgs); + PVOID pWorkers = get_ptr(&pArgs); + + hUser32 = get_ulong(&pArgs); + + apfnClientProcs32A = *pProcsA32; + apfnClientProcs32W = *pProcsW32; + + UNREFERENCED_PARAMETER(pWorkers); + + /* Do not bother with calling win32k - highly unlikely that a WOW64 process + is the first one to call this, so this syscall is essentialy a no-op + anyway. */ + return STATUS_SUCCESS; +} + +NTSTATUS +WINAPI +wow64_NtUserBuildHwndList(UINT *pArgs) +{ + HDESK hDesktop = get_handle(&pArgs); + HWND hParent = get_handle(&pArgs); + BOOLEAN bChildren = get_ulong(&pArgs); + ULONG dwThreadId = get_ulong(&pArgs); + ULONG cHwnd = get_ulong(&pArgs); + ULONG *phwndList32 = get_ptr(&pArgs); + ULONG *pcHwndNeeded = get_ptr(&pArgs); + + HWND *phwndList = NULL; + ULONG i; + NTSTATUS Status; + + if (phwndList32 != NULL) + { + phwndList = Wow64AllocateTemp(cHwnd * sizeof(*phwndList)); + } + + Status = NtUserBuildHwndList(hDesktop, + hParent, + bChildren, + dwThreadId, + cHwnd, + phwndList, + pcHwndNeeded); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + if (phwndList32 != NULL) + { + for (i = 0; i < *pcHwndNeeded; i++) + { + phwndList32[i] = HandleToUlong(phwndList[i]); + } + } + + return Status; +} + +BOOL +WINAPI +wow64_NtUserSetWindowFNID(ULONG* pArgs) +{ + HANDLE hWnd = get_handle(&pArgs); + WORD fnId = get_ulong(&pArgs); + + return NtUserSetWindowFNID(hWnd, fnId); +} + +BOOL +WINAPI +wow64_NtUserDefSetText(ULONG* pArgs) +{ + HWND hWnd = get_handle(&pArgs); + PLARGE_STRING32 pWindowText32 = get_ptr(&pArgs); + + LARGE_STRING WindowText; + + return NtUserDefSetText(hWnd, large_str_32to64(&WindowText, pWindowText32)); +} + +HBRUSH +WINAPI +wow64_NtUserGetControlColor(ULONG *pArgs) +{ + HWND hwndParent = get_handle(&pArgs); + HWND hwnd = get_handle(&pArgs); + HDC hdc = get_handle(&pArgs); + UINT CtlMsg = get_ulong(&pArgs); + + return NtUserGetControlColor(hwndParent, hwnd, hdc, CtlMsg); +} + +HBRUSH +WINAPI +wow64_NtUserGetControlBrush(ULONG *pArgs) +{ + HWND hwnd = get_handle(&pArgs); + HDC hdc = get_handle(&pArgs); + UINT CtlMsg = get_ulong(&pArgs); + + return NtUserGetControlBrush(hwnd, hdc, CtlMsg); +} + +NTSTATUS +WINAPI +wow64_NtUserAlterWindowStyle(ULONG* pArgs) +{ + HWND hWnd = get_handle(&pArgs); + DWORD Index = get_ulong(&pArgs); + LONG NewValue = get_ulong(&pArgs); + + return NtUserAlterWindowStyle(hWnd, Index, NewValue); +} + +NTSTATUS +WINAPI +wow64_NtUserSetCursorIconData(UINT *pArgs) +{ + HCURSOR hCursor = get_handle(&pArgs); + PUNICODE_STRING32 pusModule32 = get_ptr(&pArgs); + PUNICODE_STRING32 pusResName32 = get_ptr(&pArgs); + PCURSORDATA32 pCursorData32 = get_ptr(&pArgs); + + UNICODE_STRING usModule, usResName; + CURSORDATA CursorData; + + CursorData.lpName = UlongToPtr(pCursorData32->lpName); + CursorData.lpModName = UlongToPtr(pCursorData32->lpModName); + CursorData.rt = pCursorData32->rt; + CursorData.dummy = pCursorData32->dummy; + CursorData.CURSORF_flags = pCursorData32->CURSORF_flags; + CursorData.xHotspot = pCursorData32->xHotspot; + CursorData.yHotspot = pCursorData32->yHotspot; + CursorData.hbmMask = UlongToHandle(pCursorData32->hbmMask); + CursorData.hbmColor = UlongToHandle(pCursorData32->hbmColor); + CursorData.hbmAlpha = UlongToHandle(pCursorData32->hbmAlpha); + CursorData.rcBounds = pCursorData32->rcBounds; + CursorData.hbmUserAlpha = UlongToHandle(pCursorData32->hbmUserAlpha); + CursorData.bpp = pCursorData32->bpp; + CursorData.cx = pCursorData32->cx; + CursorData.cy = pCursorData32->cy; + CursorData.cpcur = pCursorData32->cpcur; + CursorData.cicur = pCursorData32->cicur; + CursorData.aspcur = UlongToPtr(pCursorData32->aspcur); + CursorData.aicur = UlongToPtr(pCursorData32->aicur); + CursorData.ajifRate = UlongToPtr(pCursorData32->ajifRate); + CursorData.iicur = pCursorData32->iicur; + + return NtUserSetCursorIconData(hCursor, + unicode_str_32to64(&usModule, pusModule32), + unicode_str_32to64(&usResName, pusResName32), + &CursorData); +} + +HMONITOR +WINAPI +wow64_NtUserMonitorFromRect(UINT *pArgs) +{ + LPCRECT pRect = get_ptr(&pArgs); + DWORD dwFlags = get_ulong(&pArgs); + + return NtUserMonitorFromRect(pRect, dwFlags); +} + +NTSTATUS +WINAPI +wow64_NtUserGetMonitorInfo(UINT *pArgs) +{ + HANDLE hMonitor = get_handle(&pArgs); + LPMONITORINFO lpMi = get_ptr(&pArgs); + + return NtUserGetMonitorInfo(hMonitor, lpMi); +} + +NTSTATUS +WINAPI +wow64_NtUserSetScrollBarInfo(UINT *pArgs) +{ + HWND hWnd = get_handle(&pArgs); + LONG id = get_ulong(&pArgs); + SETSCROLLBARINFO *pInfo = get_ptr(&pArgs); + + return NtUserSetScrollBarInfo(hWnd, id, pInfo); +} + +BOOL +WINAPI +wow64_NtUserSBGetParms(UINT *pArgs) +{ + HWND hWnd = get_handle(&pArgs); + int fnBar = get_ulong(&pArgs); + PSBDATA pSBData = get_ptr(&pArgs); + LPSCROLLINFO lpSi = get_ptr(&pArgs); + + return NtUserSBGetParms(hWnd, fnBar, pSBData, lpSi); +} + +HMONITOR +NTAPI +wow64_NtUserMonitorFromWindow(UINT *pArgs) +{ + HWND hWnd = get_handle(&pArgs); + DWORD dwFlags = get_ulong(&pArgs); + + return NtUserMonitorFromWindow(hWnd, dwFlags); +} + +ULONG +WINAPI +wow64_NtUserDeferWindowPos(UINT *pArgs) +{ + HDWP WinPosInfo = get_handle(&pArgs); + HWND Wnd = get_handle(&pArgs); + HWND WndInsertAfter = get_handle(&pArgs); + int x = get_ulong(&pArgs); + int y = get_ulong(&pArgs); + int cx = get_ulong(&pArgs); + int cy = get_ulong(&pArgs); + UINT Flags = get_ulong(&pArgs); + HDWP Result; + + Result = NtUserDeferWindowPos(WinPosInfo, + Wnd, + WndInsertAfter, + x, + y, + cx, + cy, + Flags); + + return HandleToUlong(Result); +} + +UINT +NTAPI +wow64_NtUserRegisterWindowMessage(UINT* pArgs) +{ + PUNICODE_STRING32 pMessageName32 = get_ptr(&pArgs); + UNICODE_STRING MessageName; + + return NtUserRegisterWindowMessage(unicode_str_32to64(&MessageName, + pMessageName32)); +} + +DWORD +NTAPI +wow64_NtUserQueryWindow(UINT* pArgs) +{ + HANDLE hWindow = get_handle(&pArgs); + DWORD nIndex = get_ulong(&pArgs); + + return (DWORD)NtUserQueryWindow(hWindow, nIndex); +} + +NTSTATUS +NTAPI +wow64_NtUserGetGuiResources(UINT* pArgs) +{ + HANDLE hProcess = get_handle(&pArgs); + DWORD uiFlags = get_ulong(&pArgs); + + return NtUserGetGuiResources(hProcess, uiFlags); +} + +HANDLE +NTAPI +wow64_NtUserGetClipboardData(UINT *pArgs) +{ + ULONG ulFormat = get_ulong(&pArgs); + PGETCLIPBDATA32 pClipData32 = get_ptr(&pArgs); + + GETCLIPBDATA ClipData = { 0 }; + HANDLE Result; + + ClipData.uFmtRet = pClipData32->uFmtRet; + ClipData.fGlobalHandle = pClipData32->fGlobalHandle; + ClipData.hLocale = UlongToHandle(pClipData32->hLocale); + + Result = NtUserGetClipboardData(ulFormat, &ClipData); + + pClipData32->uFmtRet = ClipData.uFmtRet; + pClipData32->fGlobalHandle = ClipData.fGlobalHandle; + pClipData32->hLocale = HandleToUlong(ClipData.hLocale); + + return Result; +} + +HANDLE +NTAPI +wow64_NtUserSetClipboardData(UINT *pArgs) +{ + ULONG ulFormat = get_ulong(&pArgs); + HANDLE hMem = get_handle(&pArgs); + PSETCLIPBDATA pClipData = get_ptr(&pArgs); + + return NtUserSetClipboardData(ulFormat, hMem, pClipData); +} + +NTSTATUS +NTAPI +wow64_NtUserCreateLocalMemHandle(UINT* pArgs) +{ + HANDLE hMem = get_handle(&pArgs); + PVOID pData32 = get_ptr(&pArgs); + DWORD cbData32 = get_ulong(&pArgs); + PDWORD32 pcbData = get_ptr(&pArgs); + + return NtUserCreateLocalMemHandle(hMem, pData32, cbData32, pcbData); +} + +HANDLE +NTAPI +wow64_NtUserConvertMemHandle(UINT* pArgs) +{ + PVOID pData = get_ptr(&pArgs); + DWORD cbData = get_ulong(&pArgs); + + return NtUserConvertMemHandle(pData, cbData); +} + +HDC +WINAPI +wow64_NtGdiGetDCforBitmap(UINT *pArgs) +{ + HBITMAP hBitmap = get_handle(&pArgs); + + return NtGdiGetDCforBitmap(hBitmap); +} + +NTSTATUS +WINAPI +wow64_NtUserGetKeyboardLayoutName(UINT *pArgs) +{ + PUNICODE_STRING32 pName32 = get_ptr(&pArgs); + UNICODE_STRING Name; + + return NtUserGetKeyboardLayoutName(unicode_str_32to64(&Name, pName32)); +} + +NTSTATUS +WINAPI +wow64_NtUserSetImeHotKey(UINT *pArgs) +{ + DWORD dwHotkeyId = get_ulong(&pArgs); + UINT uModifiers = get_ulong(&pArgs); + UINT uVirtualKey = get_ulong(&pArgs); + HKL hKl = get_handle(&pArgs); + DWORD dwAction = get_ulong(&pArgs); + + return NtUserSetImeHotKey(dwHotkeyId, uModifiers, uVirtualKey, hKl, dwAction); +} + +HKL +WINAPI +wow64_NtUserLoadKeyboardLayoutEx(UINT *pArgs) +{ + HANDLE hFile = get_handle(&pArgs); + DWORD offTable = get_ulong(&pArgs); + PVOID pTables = get_ptr(&pArgs); + HKL hOldKl = get_handle(&pArgs); + PUNICODE_STRING32 pusKLID32 = get_ptr(&pArgs); + DWORD dwNewKl = get_ulong(&pArgs); + UINT Flags = get_ulong(&pArgs); + + UNICODE_STRING usKLID; + + return NtUserLoadKeyboardLayoutEx(hFile, offTable, pTables, hOldKl, + unicode_str_32to64(&usKLID, pusKLID32), + dwNewKl, Flags); +} + +LONG +NTAPI +wow64_NtGdiGetFontFamilyInfo(UINT *pArgs) +{ + HDC hDc = get_handle(&pArgs); + /* The memory layout of below types seems to be the same for 32-bit and 64-bit */ + const LOGFONTW *pLogFont = get_ptr(&pArgs); + PFONTFAMILYINFO pInfo = get_ptr(&pArgs); + PLONG pInfoCount = get_ptr(&pArgs); + + return NtGdiGetFontFamilyInfo(hDc, pLogFont, pInfo, pInfoCount); +} + +BOOL +NTAPI +wow64_NtUserWaitMessage(UINT *pArgs) +{ + return NtUserWaitMessage(); +} + +BOOL +NTAPI +wow64_NtUserGetUpdateRgn(UINT *pArgs) +{ + HWND hWnd = get_handle(&pArgs); + HRGN hRgn = get_handle(&pArgs); + BOOL bErase = get_ulong(&pArgs); + + return NtUserGetUpdateRgn(hWnd, hRgn, bErase); +} + +BOOL +NTAPI +wow64_NtUserGetUpdateRect(UINT *pArgs) +{ + HWND hWnd = get_handle(&pArgs); + LPRECT pUnsafeRect = get_ptr(&pArgs); + BOOL bErase = get_ulong(&pArgs); + + return NtUserGetUpdateRect(hWnd, pUnsafeRect, bErase); +} + +UINT +NTAPI +wow64_NtUserGetCaretBlinkTime(UINT* pArgs) +{ + return NtUserGetCaretBlinkTime(); +} + +BOOL +NTAPI +wow64_NtUserGetGUIThreadInfo(UINT* pArgs) +{ + DWORD idThread = get_ulong(&pArgs); + PGUITHREADINFO32 lpGui32 = get_ptr(&pArgs); + GUITHREADINFO Gui; + + Gui.cbSize = sizeof(Gui); + Gui.flags = lpGui32->flags; + + if (!NtUserGetGUIThreadInfo(idThread, &Gui)) + { + return FALSE; + } + + lpGui32->cbSize = Gui.cbSize; + lpGui32->flags = Gui.flags; + lpGui32->hwndActive = HandleToUlong(Gui.hwndActive); + lpGui32->hwndFocus = HandleToUlong(Gui.hwndFocus); + lpGui32->hwndCapture = HandleToUlong(Gui.hwndCapture); + lpGui32->hwndMenuOwner = HandleToUlong(Gui.hwndMenuOwner); + lpGui32->hwndMoveSize = HandleToUlong(Gui.hwndMoveSize); + lpGui32->hwndCaret = HandleToUlong(Gui.hwndCaret); + lpGui32->rcCaret = Gui.rcCaret; + + return TRUE; +} + +BOOL +NTAPI +wow64_NtUserSetKeyboardState(UINT* pArgs) +{ + LPBYTE lpKeyState = get_ptr(&pArgs); + + return NtUserSetKeyboardState(lpKeyState); +} + +BOOL +NTAPI +wow64_NtUserFlashWindowEx(UINT* pArgs) +{ + PFLASHWINFO32 pFlashInfo32 = get_ptr(&pArgs); + FLASHWINFO FlashInfo; + + FlashInfo.cbSize = sizeof(FlashInfo); + FlashInfo.hwnd = UlongToHandle(pFlashInfo32->hwnd); + FlashInfo.dwFlags = pFlashInfo32->dwFlags; + FlashInfo.uCount = pFlashInfo32->uCount; + FlashInfo.dwTimeout = pFlashInfo32->dwTimeout; + + return NtUserFlashWindowEx(&FlashInfo); +} + +BOOL +NTAPI +wow64_NtUserUnregisterClass(UINT* pArgs) +{ + PUNICODE_STRING32 pClassName32 = get_ptr(&pArgs); + HINSTANCE hInstance = get_handle(&pArgs); + PCLSMENUNAME32 pClassMenuName32 = get_ptr(&pArgs);; + + UNICODE_STRING ClassName; + CLSMENUNAME ClassMenuName; + + if (!NtUserUnregisterClass(unicode_str_32to64(&ClassName, pClassName32), + hInstance, + &ClassMenuName)) + { + return FALSE; + } + + pClassMenuName32->pszClientAnsiMenuName = PtrToUlong(ClassMenuName.pszClientAnsiMenuName); + pClassMenuName32->pwszClientUnicodeMenuName = PtrToUlong(ClassMenuName.pwszClientUnicodeMenuName); + pClassMenuName32->pusMenuName = PtrToUlong(ClassMenuName.pusMenuName); + + return TRUE; +} + +ULONG +NTAPI +wow64_NtUserGetSystemMenu(UINT* pArgs) +{ + HWND hWnd = get_handle(&pArgs); + BOOL bRevert = get_ulong(&pArgs); + + return HandleToUlong(NtUserGetSystemMenu(hWnd, bRevert)); +} + +ULONG +NTAPI +wow64_NtUserGetForegroundWindow(UINT* pArgs) +{ + return HandleToUlong(NtUserGetForegroundWindow()); +} + +DWORD +NTAPI +wow64_NtUserSetThreadState(UINT* pArgs) +{ + DWORD dwSet = get_ulong(&pArgs); + DWORD dwFlags = get_ulong(&pArgs); + + return NtUserSetThreadState(dwSet, dwFlags); +} + +BOOL +NTAPI +wow64_NtUserGetComboBoxInfo(UINT* pArgs) +{ + HWND hWnd = get_handle(&pArgs); + PCOMBOBOXINFO32 pcbi32 = get_ptr(&pArgs); + COMBOBOXINFO cbi; + + cbi.cbSize = sizeof(cbi); + + if (!NtUserGetComboBoxInfo(hWnd, &cbi)) + { + return FALSE; + } + + pcbi32->rcItem = cbi.rcItem; + pcbi32->rcButton = cbi.rcButton; + pcbi32->stateButton = cbi.stateButton; + pcbi32->hwndCombo = HandleToUlong(cbi.hwndCombo); + pcbi32->hwndItem = HandleToUlong(cbi.hwndItem); + pcbi32->hwndList = HandleToUlong(cbi.hwndList); + + return TRUE; +} + + +DWORD +NTAPI +wow64_NtGdiGetCharSet(UINT* pArgs) +{ + HDC hDc = get_handle(&pArgs); + + return NtGdiGetCharSet(hDc); +} \ No newline at end of file diff --git a/dll/wow64win/wow64win_private.h b/dll/wow64win/wow64win_private.h new file mode 100644 index 0000000000000..9303694fca793 --- /dev/null +++ b/dll/wow64win/wow64win_private.h @@ -0,0 +1,673 @@ +/* + * WoW64 private definitions + * + * Copyright 2021 Alexandre Julliard + * Copyright 2025 Marcin Jabłoński + * + * 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 + */ + +#ifndef __WOW64WIN_PRIVATE_H +#define __WOW64WIN_PRIVATE_H + +#ifdef __REACTOS__ +#define WIN32_NO_STATUS +#include +#include + +/* SDK/DDK/NDK Headers. */ +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +/* Public Win32K Headers */ +#include +#include +#include +#include + +#define IS_ATOM(x) \ + (((ULONG_PTR)(x) > 0x0) && ((ULONG_PTR)(x) < 0x10000)) + +extern NTSTATUS WINAPI (*UserCallbacks[])(PVOID Arguments, ULONG ArgumentLength); +NTSTATUS WINAPI wow64_NtUserCallWinProc( void *arg, ULONG size ); + +#define DEFINE_USER32_CALLBACK(id, value, fn) static const ULONG Num ## fn = value; +#include "u32cb.h" +#undef DEFINE_USER32_CALLBACK + +#endif + +#ifndef __REACTOS__ +#include "../win32u/win32syscalls.h" +#include "ntuser.h" + +#define SYSCALL_ENTRY(id,name,_args) extern NTSTATUS WINAPI wow64_ ## name( UINT *args ); +ALL_SYSCALLS32 +#undef SYSCALL_ENTRY + +extern ntuser_callback user_callbacks[]; + +struct object_attr64 +{ + OBJECT_ATTRIBUTES attr; + UNICODE_STRING str; + SECURITY_DESCRIPTOR sd; +}; + +typedef struct +{ + ULONG Length; + ULONG RootDirectory; + ULONG ObjectName; + ULONG Attributes; + ULONG SecurityDescriptor; + ULONG SecurityQualityOfService; +} OBJECT_ATTRIBUTES32; + +static inline ULONG get_ulong( UINT **args ) { return *(*args)++; } +static inline HANDLE get_handle( UINT **args ) { return LongToHandle( *(*args)++ ); } +static inline void *get_ptr( UINT **args ) { return ULongToPtr( *(*args)++ ); } + +static inline void **addr_32to64( void **addr, ULONG *addr32 ) +{ + if (!addr32) return NULL; + *addr = ULongToPtr( *addr32 ); + return addr; +} + +static inline SIZE_T *size_32to64( SIZE_T *size, ULONG *size32 ) +{ + if (!size32) return NULL; + *size = *size32; + return size; +} + +static inline void put_addr( ULONG *addr32, void *addr ) +{ + if (addr32) *addr32 = PtrToUlong( addr ); +} + +static inline void put_size( ULONG *size32, SIZE_T size ) +{ + if (size32) *size32 = min( size, MAXDWORD ); +} + +static inline UNICODE_STRING *unicode_str_32to64( UNICODE_STRING *str, const UNICODE_STRING32 *str32 ) +{ + if (!str32) return NULL; + str->Length = str32->Length; + str->MaximumLength = str32->MaximumLength; + str->Buffer = ULongToPtr( str32->Buffer ); + return str; +} + +static inline SECURITY_DESCRIPTOR *secdesc_32to64( SECURITY_DESCRIPTOR *out, const SECURITY_DESCRIPTOR *in ) +{ + /* relative descr has the same layout for 32 and 64 */ + const SECURITY_DESCRIPTOR_RELATIVE *sd = (const SECURITY_DESCRIPTOR_RELATIVE *)in; + + if (!in) return NULL; + out->Revision = sd->Revision; + out->Sbz1 = sd->Sbz1; + out->Control = sd->Control & ~SE_SELF_RELATIVE; + if (sd->Control & SE_SELF_RELATIVE) + { + if (sd->Owner) out->Owner = (PSID)((BYTE *)sd + sd->Owner); + if (sd->Group) out->Group = (PSID)((BYTE *)sd + sd->Group); + if ((sd->Control & SE_SACL_PRESENT) && sd->Sacl) out->Sacl = (PSID)((BYTE *)sd + sd->Sacl); + if ((sd->Control & SE_DACL_PRESENT) && sd->Dacl) out->Dacl = (PSID)((BYTE *)sd + sd->Dacl); + } + else + { + out->Owner = ULongToPtr( sd->Owner ); + out->Group = ULongToPtr( sd->Group ); + if (sd->Control & SE_SACL_PRESENT) out->Sacl = ULongToPtr( sd->Sacl ); + if (sd->Control & SE_DACL_PRESENT) out->Dacl = ULongToPtr( sd->Dacl ); + } + return out; +} + +static inline OBJECT_ATTRIBUTES *objattr_32to64( struct object_attr64 *out, const OBJECT_ATTRIBUTES32 *in ) +{ + memset( out, 0, sizeof(*out) ); + if (!in) return NULL; + if (in->Length != sizeof(*in)) return &out->attr; + + out->attr.Length = sizeof(out->attr); + out->attr.RootDirectory = LongToHandle( in->RootDirectory ); + out->attr.Attributes = in->Attributes; + out->attr.ObjectName = unicode_str_32to64( &out->str, ULongToPtr( in->ObjectName )); + out->attr.SecurityQualityOfService = ULongToPtr( in->SecurityQualityOfService ); + out->attr.SecurityDescriptor = secdesc_32to64( &out->sd, ULongToPtr( in->SecurityDescriptor )); + return &out->attr; +} + +static inline void set_last_error32( DWORD err ) +{ + TEB *teb = NtCurrentTeb(); + TEB32 *teb32 = (TEB32 *)((char *)teb + teb->WowTebOffset); + teb32->LastErrorValue = err; +} + +#else + +#include "../wow64/ros_wow64_private.h" + +static HANDLE UlongToHandleNoSignExtend(ULONG ulong) +{ + if ((LONG)ulong == -1L) + { + return INVALID_HANDLE_VALUE; + } + else if (ulong == HandleToUlong(HWND_MESSAGE)) + { + return HWND_MESSAGE; + } + else if (ulong == HandleToUlong(HWND_NOTOPMOST)) + { + return HWND_NOTOPMOST; + } + return (HANDLE)(ULONG_PTR)ulong; +} + +#define UlongToHandle(ulong) UlongToHandleNoSignExtend(ulong) +#define get_handle(ppArgs) UlongToHandle(get_ulong(ppArgs)) + +typedef struct +{ + DWORD cbSize; + DWORD fMask; + DWORD dwStyle; + UINT cyMax; + ULONG hbrBack; + DWORD dwContextHelpID; + ULONG dwMenuData; +} MENUINFO32; + +typedef struct +{ + UINT cbSize; + UINT fMask; + UINT fType; + UINT fState; + UINT wID; + UINT32 hSubMenu; + UINT32 hbmpChecked; + UINT32 hbmpUnchecked; + UINT32 dwItemData; + UINT32 dwTypeData; + UINT cch; + UINT32 hbmpItem; +} MENUITEMINFOW32; + +typedef struct +{ + UINT32 hwnd; + UINT message; + UINT32 wParam; + UINT32 lParam; + DWORD time; + POINT pt; +} MSG32; + +typedef struct +{ + DWORD dwType; + DWORD dwSize; + UINT32 hDevice; + UINT32 wParam; +} RAWINPUTHEADER32; + +typedef struct +{ + USHORT usUsagePage; + USHORT usUsage; + DWORD dwFlags; + UINT32 hwndTarget; +} RAWINPUTDEVICE32; + +typedef struct +{ + UINT32 hDevice; + DWORD dwType; +} RAWINPUTDEVICELIST32; + +typedef struct +{ + LONG dx; + LONG dy; + DWORD mouseData; + DWORD dwFlags; + DWORD time; + ULONG dwExtraInfo; +} MOUSEINPUT32; + +typedef struct +{ + WORD wVk; + WORD wScan; + DWORD dwFlags; + DWORD time; + ULONG dwExtraInfo; +} KEYBDINPUT32; + +typedef struct +{ + DWORD type; + union + { + MOUSEINPUT32 mi; + KEYBDINPUT32 ki; + HARDWAREINPUT hi; + } DUMMYUNIONNAME; +} INPUT32; + +typedef struct +{ + int x; + int y; + DWORD time; + ULONG dwExtraInfo; +} MOUSEMOVEPOINT32; + +typedef struct +{ + UINT32 hdc; + BOOL fErase; + RECT rcPaint; + BOOL fRestore; + BOOL fIncUpdate; + BYTE rgbReserved[32]; +} PAINTSTRUCT32; + +typedef struct +{ + ULONG lpCreateParams; + ULONG hInstance; + ULONG hMenu; + ULONG hwndParent; + INT cy; + INT cx; + INT y; + INT x; + LONG style; + ULONG lpszName; + ULONG lpszClass; + DWORD dwExStyle; +} CREATESTRUCT32; + +typedef struct +{ + ULONG szClass; + ULONG szTitle; + ULONG hOwner; + INT x; + INT y; + INT cx; + INT cy; + DWORD style; + ULONG lParam; +} MDICREATESTRUCT32; + +typedef struct +{ + ULONG hmenuIn; + ULONG hmenuNext; + ULONG hwndNext; +} MDINEXTMENU32; + +typedef struct +{ + LONG lResult; + LONG lParam; + LONG wParam; + DWORD message; + ULONG hwnd; +} CWPRETSTRUCT32; + +typedef struct +{ + ULONG hwnd; + ULONG hwndInsertAfter; + INT x; + INT y; + INT cx; + INT cy; + UINT flags; +} WINDOWPOS32; + +typedef struct +{ + RECT rgrc[3]; + ULONG lppos; +} NCCALCSIZE_PARAMS32; + +typedef struct +{ + UINT CtlType; + UINT CtlID; + ULONG hwndItem; + UINT itemID1; + ULONG itemData1; + UINT itemID2; + ULONG itemData2; + DWORD dwLocaleId; +} COMPAREITEMSTRUCT32; + +typedef struct +{ + ULONG dwData; + DWORD cbData; + ULONG lpData; +} COPYDATASTRUCT32; + +typedef struct +{ + UINT cbSize; + INT iContextType; + INT iCtrlId; + ULONG hItemHandle; + DWORD dwContextId; + POINT MousePos; +} HELPINFO32; + +typedef struct +{ + UINT CtlType; + UINT CtlID; + UINT itemID; + UINT itemWidth; + UINT itemHeight; + ULONG itemData; +} MEASUREITEMSTRUCT32; + +typedef struct +{ + UINT CtlType; + UINT CtlID; + UINT itemID; + UINT itemAction; + UINT itemState; + ULONG hwndItem; + ULONG hDC; + RECT rcItem; + ULONG itemData; +} DRAWITEMSTRUCT32; + +typedef struct tagCOMBOBOXINFO32 +{ + DWORD cbSize; + RECT rcItem; + RECT rcButton; + DWORD stateButton; + ULONG hwndCombo; + ULONG hwndItem; + ULONG hwndList; +} COMBOBOXINFO32,*PCOMBOBOXINFO32, *LPCOMBOBOXINFO32; + +typedef struct +{ + ULONG lParam; + ULONG wParam; + UINT message; + ULONG hwnd; +} CWPSTRUCT32; + +typedef struct +{ + POINT pt; + ULONG hwnd; + UINT wHitTestCode; + ULONG dwExtraInfo; + DWORD mouseData; +} MOUSEHOOKSTRUCTEX32; + +typedef struct +{ + POINT pt; + DWORD mouseData; + DWORD flags; + DWORD time; + ULONG dwExtraInfo; +} MSLLHOOKSTRUCT32; + +typedef struct +{ + DWORD vkCode; + DWORD scanCode; + DWORD flags; + DWORD time; + ULONG dwExtraInfo; +} KBDLLHOOKSTRUCT32; + +typedef struct +{ + UINT message; + UINT paramL; + UINT paramH; + DWORD time; + ULONG hwnd; +} EVENTMSG32; + +typedef struct +{ + BOOL fMouse; + ULONG hWndActive; +} CBTACTIVATESTRUCT32; + +typedef struct +{ + UINT CtlType; + UINT CtlID; + UINT itemID; + ULONG hwndItem; + ULONG itemData; +} DELETEITEMSTRUCT32; + +typedef struct +{ + UINT cbSize; + UINT style; + ULONG lpfnWndProc; + INT cbClsExtra; + INT cbWndExtra; + ULONG hInstance; + ULONG hIcon; + ULONG hCursor; + ULONG hbrBackground; + ULONG lpszMenuName; + ULONG lpszClassName; + ULONG hIconSm; +} WNDCLASSEXW32; + +typedef struct _CLIENTINFO32 +{ + ULONG CI_flags; + ULONG cSpins; + DWORD dwExpWinVer; + DWORD dwCompatFlags; + DWORD dwCompatFlags2; + DWORD dwTIFlags; + ULONG pDeskInfo; + ULONG ulClientDelta; + ULONG phkCurrent; + ULONG fsHooks; + ULONG CallbackWnd[2]; + DWORD dwHookCurrent; + INT cInDDEMLCallback; + ULONG pClientThreadInfo; + ULONG dwHookData; + DWORD dwKeyCache; + BYTE afKeyState[8]; + DWORD dwAsyncKeyCache; + BYTE afAsyncKeyState[8]; + BYTE afAsyncKeyStateRecentDow[8]; + ULONG hKL; + USHORT CodePage; + UCHAR achDbcsCF[2]; + MSG32 msgDbcsCB; + ULONG lpdwRegisteredClasses; + ULONG Win32ClientInfo3[26]; + ULONG ppi; +} CLIENTINFO32, *PCLIENTINFO32; + +C_ASSERT(sizeof(CLIENTINFO32) == 61 * sizeof(ULONG)); + +typedef struct _CURSORDATA32 +{ + ULONG lpName; + ULONG lpModName; + USHORT rt; + USHORT dummy; + ULONG CURSORF_flags; + SHORT xHotspot; + SHORT yHotspot; + ULONG hbmMask; + ULONG hbmColor; + ULONG hbmAlpha; + RECT rcBounds; + ULONG hbmUserAlpha; + ULONG bpp; + ULONG cx; + ULONG cy; + UINT cpcur; + UINT cicur; + ULONG aspcur; + ULONG aicur; + ULONG ajifRate; + UINT iicur; +} CURSORDATA32, *PCURSORDATA32; + +typedef struct _LARGE_STRING32 +{ + ULONG Length; + ULONG MaximumLength:31; + ULONG bAnsi:1; + ULONG Buffer; +} LARGE_STRING32, *PLARGE_STRING32; + +static inline LARGE_STRING *large_str_32to64( LARGE_STRING *str, const LARGE_STRING32 *str32 ) +{ + if (!str32) return NULL; + if (IS_ATOM(str32)) return (PVOID)str32; + str->Length = str32->Length; + str->MaximumLength = str32->MaximumLength; + str->bAnsi = str32->bAnsi; + str->Buffer = ULongToPtr( str32->Buffer ); + return str; +} + +typedef struct _DRIVER_INFO_2W32 +{ + DWORD cVersion; + ULONG pName; + ULONG pEnvironment; + ULONG pDriverPath; + ULONG pDataFile; + ULONG pConfigFile; +} DRIVER_INFO_2W32, *PDRIVER_INFO_2W32; + +static +inline +PDRIVER_INFO_2W +DriverInfo2W32To64(PDRIVER_INFO_2W pDriverInfo64, + const DRIVER_INFO_2W32* pDriverInfo32) +{ + pDriverInfo64->cVersion = pDriverInfo32->cVersion; + pDriverInfo64->pName = UlongToPtr(pDriverInfo32->pName); + pDriverInfo64->pEnvironment = UlongToPtr(pDriverInfo32->pEnvironment); + pDriverInfo64->pDriverPath = UlongToPtr(pDriverInfo32->pDriverPath); + pDriverInfo64->pDataFile = UlongToPtr(pDriverInfo32->pDataFile); + pDriverInfo64->pConfigFile = UlongToPtr(pDriverInfo32->pConfigFile); + + return pDriverInfo64; +} + +static +inline +PDRIVER_INFO_2W32 +DriverInfo2W64To32(const DRIVER_INFO_2W* pDriverInfo64, + PDRIVER_INFO_2W32 pDriverInfo32) +{ + pDriverInfo32->cVersion = pDriverInfo64->cVersion; + pDriverInfo32->pName = PtrToUlong(pDriverInfo64->pName); + pDriverInfo32->pEnvironment = PtrToUlong(pDriverInfo64->pEnvironment); + pDriverInfo32->pDriverPath = PtrToUlong(pDriverInfo64->pDriverPath); + pDriverInfo32->pDataFile = PtrToUlong(pDriverInfo64->pDataFile); + pDriverInfo32->pConfigFile = PtrToUlong(pDriverInfo64->pConfigFile); + + return pDriverInfo32; +} + +static inline void set_last_error32(DWORD err) +{ + NtCurrentTeb32()->LastErrorValue = err; +} + +#include "callback32.h" + +extern PSERVERINFO g_ServerInfo; + +typedef struct tagGETCLIPBDATA32 +{ + UINT uFmtRet; + BOOL fGlobalHandle; + union + { + ULONG hLocale; + ULONG hPalette; + }; +} GETCLIPBDATA32, *PGETCLIPBDATA32; + +typedef struct tagGUITHREADINFO32 +{ + DWORD cbSize; + DWORD flags; + ULONG hwndActive; + ULONG hwndFocus; + ULONG hwndCapture; + ULONG hwndMenuOwner; + ULONG hwndMoveSize; + ULONG hwndCaret; + RECT rcCaret; +} GUITHREADINFO32, *PGUITHREADINFO32, *LPGUITHREADINFO32; + +typedef struct +{ + UINT cbSize; + ULONG hwnd; + DWORD dwFlags; + UINT uCount; + DWORD dwTimeout; +} FLASHWINFO32, *PFLASHWINFO32; + +typedef struct _CLSMENUNAME32 +{ + ULONG pszClientAnsiMenuName; + ULONG pwszClientUnicodeMenuName; + ULONG pusMenuName; +} CLSMENUNAME32, *PCLSMENUNAME32; + +#endif /* __REACTOS__ */ +#endif /* __WOW64WIN_PRIVATE_H */ diff --git a/drivers/CMakeLists.txt b/drivers/CMakeLists.txt index f9022a69dc78b..5a0879f4c1a5c 100644 --- a/drivers/CMakeLists.txt +++ b/drivers/CMakeLists.txt @@ -1,6 +1,7 @@ PROJECT(Drivers) +add_subdirectory(acpi) add_subdirectory(base) add_subdirectory(battery) add_subdirectory(bluetooth) diff --git a/drivers/acpi/CMakeLists.txt b/drivers/acpi/CMakeLists.txt new file mode 100644 index 0000000000000..1f630a0770c1b --- /dev/null +++ b/drivers/acpi/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(cmbatt) diff --git a/drivers/bus/acpi/cmbatt/CMakeLists.txt b/drivers/acpi/cmbatt/CMakeLists.txt similarity index 100% rename from drivers/bus/acpi/cmbatt/CMakeLists.txt rename to drivers/acpi/cmbatt/CMakeLists.txt diff --git a/drivers/bus/acpi/cmbatt/cmbatt.c b/drivers/acpi/cmbatt/cmbatt.c similarity index 77% rename from drivers/bus/acpi/cmbatt/cmbatt.c rename to drivers/acpi/cmbatt/cmbatt.c index 3935a9c8150e7..dd01f8b22bec6 100644 --- a/drivers/bus/acpi/cmbatt/cmbatt.c +++ b/drivers/acpi/cmbatt/cmbatt.c @@ -273,41 +273,277 @@ CmBattUnload(IN PDRIVER_OBJECT DriverObject) } } +/** + * @brief + * Retrieves the static information of the battery. + * + * @param[in] DeviceExtension + * A pointer to a Control Method (CM) battery device extension. + * It is used for debugging purposes. + * + * @param[out] UseBix + * A pointer to a boolean value, returned to caller. This can return + * TRUE if this machine supports the _BIX method, FALSE otherwise. + * + * @param[out] BattInfo + * A pointer to a structure that contains the static info of the + * battery. ONLY ONE type of information is filled. See Remarks. + * + * @return + * Returns STATUS_INSUFFICIENT_RESOURCES if there is no enough + * memory to allocate for the static info buffer. Returns + * STATUS_SUCCESS if the operation has succeeded. Otherwise an + * error NTSTATUS code is returned. + * + * @remarks + * It is important to note that a machine can only support one method, + * _BIX or _BIF. Starting with ACPI 4.0, _BIF has become deprecated. + * The caller MUST INSPECT the boolean value, ExtendedData, in order + * to determine if the machine has returned the extended information + * data or not. + */ +static NTSTATUS -NTAPI -CmBattVerifyStaticInfo(PCMBATT_DEVICE_EXTENSION DeviceExtension, - ULONG BatteryTag) +CmBattGetBattStaticInfo( + _In_ PCMBATT_DEVICE_EXTENSION DeviceExtension, + _Out_ PBOOLEAN UseBix, + _Outptr_ PACPI_BATT_STATIC_INFO *BattInfo) { - ACPI_BIF_DATA BifData; - PBATTERY_INFORMATION Info = &DeviceExtension->BatteryInformation; NTSTATUS Status; + ACPI_BIF_DATA BifData; + ACPI_BIX_DATA BixData; + PACPI_BATT_STATIC_INFO Info; + + /* Allocate pool space for the static information */ + Info = ExAllocatePoolZero(PagedPool, + sizeof(*Info), + CMBATT_BATT_STATIC_INFO_TAG); + if (Info == NULL) + { + return STATUS_INSUFFICIENT_RESOURCES; + } - Status = CmBattGetBifData(DeviceExtension, &BifData); - if (NT_SUCCESS(Status)) + /* Assume this machine supports the _BIX method */ + *UseBix = TRUE; + + /* Retrieve extended battery static info from _BIX method */ + Status = CmBattGetBixData(DeviceExtension, &BixData); + if (!NT_SUCCESS(Status)) { - RtlZeroMemory(Info, sizeof(*Info)); - Info->Capabilities = BATTERY_SYSTEM_BATTERY; - Info->Technology = BifData.BatteryTechnology; - RtlCopyMemory(Info->Chemistry, BifData.BatteryType, 4); - // FIXME: take from _BIX method: Info->CycleCount - DeviceExtension->BifData = BifData; + /* + * It failed. This can be expected because not every machine supports + * _BIX, especially the older machines which do not support ACPI 4.0. + * Fallback to _BIF at this point. + */ + Status = CmBattGetBifData(DeviceExtension, &BifData); + if (!NT_SUCCESS(Status)) + { + /* That failed too, time to punt */ + ExFreePoolWithTag(Info, CMBATT_BATT_STATIC_INFO_TAG); + return Status; + } + + /* Acknowledge the caller it will be going to use _BIF */ + *UseBix = FALSE; + Info->BifData = BifData; + } + else + { + Info->BixData = BixData; + } + + /* Return the battery static info to caller */ + Info->ExtendedData = *UseBix; + *BattInfo = Info; + return Status; +} + +/** + * @brief + * Verifies the extended battery information (_BIX) and translates + * such data to the BATTERY_INFORMATION structure. + * + * @param[in] DeviceExtension + * A pointer to a Control Method (CM) battery device extension. + * It is used to gather _BIX data. + * + * @param[in,out] Info + * A pointer to a structure of which this function fills in + * battery information that can be by other battery miniport + * drivers, such as the Composite Battery driver. + */ +static +VOID +CmBattVerifyBixData( + _In_ PCMBATT_DEVICE_EXTENSION DeviceExtension, + _Inout_ PBATTERY_INFORMATION Info) +{ + ULONG DesignVoltage; + ACPI_BIX_DATA BixData = DeviceExtension->BattInfo.BixData; - if (BifData.PowerUnit == 1) + /* Copy the battery info data */ + Info->Technology = BixData.BatteryTechnology; + Info->CycleCount = BixData.CycleCount; + RtlCopyMemory(Info->Chemistry, BixData.BatteryType, 4); + + /* Check if the power stats are reported in ampere or watts */ + if (BixData.PowerUnit == ACPI_BATT_POWER_UNIT_AMPS) + { + /* + * We have got power stats in milli-ampere but ReactOS expects the values + * to be reported in milli-watts, so we have to convert them. + * In order to do so we must expect the design voltage of the battery + * is not unknown. + */ + DesignVoltage = BixData.DesignVoltage; + if ((DesignVoltage != BATTERY_UNKNOWN_VOLTAGE) && (DesignVoltage != 0)) { - DPRINT1("FIXME: need to convert mAh into mWh\n"); + /* Convert the design capacity */ + Info->DesignedCapacity = CONVERT_BATT_INFO(BixData.DesignCapacity, DesignVoltage); + + /* Convert the full charged capacity */ + Info->FullChargedCapacity = CONVERT_BATT_INFO(BixData.LastFullCapacity, DesignVoltage); + + /* Convert the low capacity alarm (DefaultAlert1) */ + Info->DefaultAlert1 = CONVERT_BATT_INFO(BixData.DesignCapacityLow, DesignVoltage); + + /* Convert the designed capacity warning alarm (DefaultAlert2) */ + Info->DefaultAlert2 = CONVERT_BATT_INFO(BixData.DesignCapacityWarning, DesignVoltage); + } + else + { + /* + * Without knowing the nominal designed voltage of the battery + * we cannot determine the power consumption of this battery. + */ Info->DesignedCapacity = BATTERY_UNKNOWN_CAPACITY; Info->FullChargedCapacity = BATTERY_UNKNOWN_CAPACITY; Info->DefaultAlert1 = BATTERY_UNKNOWN_CAPACITY; Info->DefaultAlert2 = BATTERY_UNKNOWN_CAPACITY; } + } + else + { + /* The stats are in milli-watts, use them directly */ + Info->DesignedCapacity = BixData.DesignCapacity; + Info->FullChargedCapacity = BixData.LastFullCapacity; + Info->DefaultAlert1 = BixData.DesignCapacityLow; + Info->DefaultAlert2 = BixData.DesignCapacityWarning; + } +} + +/** + * @brief + * Verifies the battery information (_BIF) and translates + * such data to the BATTERY_INFORMATION structure. + * + * @param[in] DeviceExtension + * A pointer to a Control Method (CM) battery device extension. + * It is used to gather _BIF data. + * + * @param[in,out] Info + * A pointer to a structure of which this function fills in + * battery information that can be by other battery miniport + * drivers, such as the Composite Battery driver. + */ +static +VOID +CmBattVerifyBifData( + _In_ PCMBATT_DEVICE_EXTENSION DeviceExtension, + _Inout_ PBATTERY_INFORMATION Info) +{ + ULONG DesignVoltage; + ACPI_BIF_DATA BifData = DeviceExtension->BattInfo.BifData; + + /* Copy the battery info data, CycleCount is not supported in _BIF */ + Info->Technology = BifData.BatteryTechnology; + Info->CycleCount = 0; + RtlCopyMemory(Info->Chemistry, BifData.BatteryType, 4); + + /* Check if the power stats are reported in ampere or watts */ + if (BifData.PowerUnit == ACPI_BATT_POWER_UNIT_AMPS) + { + /* + * We have got power stats in milli-ampere but ReactOS expects the values + * to be reported in milli-watts, so we have to convert them. + * In order to do so we must expect the design voltage of the battery + * is not unknown. + */ + DesignVoltage = BifData.DesignVoltage; + if ((DesignVoltage != BATTERY_UNKNOWN_VOLTAGE) && (DesignVoltage != 0)) + { + /* Convert the design capacity */ + Info->DesignedCapacity = CONVERT_BATT_INFO(BifData.DesignCapacity, DesignVoltage); + + /* Convert the full charged capacity */ + Info->FullChargedCapacity = CONVERT_BATT_INFO(BifData.LastFullCapacity, DesignVoltage); + + /* Convert the low capacity alarm (DefaultAlert1) */ + Info->DefaultAlert1 = CONVERT_BATT_INFO(BifData.DesignCapacityLow, DesignVoltage); + + /* Convert the designed capacity warning alarm (DefaultAlert2) */ + Info->DefaultAlert2 = CONVERT_BATT_INFO(BifData.DesignCapacityWarning, DesignVoltage); + } else { - Info->DesignedCapacity = BifData.DesignCapacity; - Info->FullChargedCapacity = BifData.LastFullCapacity; - Info->DefaultAlert1 = BifData.DesignCapacityLow; - Info->DefaultAlert2 = BifData.DesignCapacityWarning; + /* + * Without knowing the nominal designed voltage of the battery + * we cannot determine the power consumption of this battery. + */ + Info->DesignedCapacity = BATTERY_UNKNOWN_CAPACITY; + Info->FullChargedCapacity = BATTERY_UNKNOWN_CAPACITY; + Info->DefaultAlert1 = BATTERY_UNKNOWN_CAPACITY; + Info->DefaultAlert2 = BATTERY_UNKNOWN_CAPACITY; } } + else + { + /* The stats are in milli-watts, use them directly */ + Info->DesignedCapacity = BifData.DesignCapacity; + Info->FullChargedCapacity = BifData.LastFullCapacity; + Info->DefaultAlert1 = BifData.DesignCapacityLow; + Info->DefaultAlert2 = BifData.DesignCapacityWarning; + } +} + +NTSTATUS +NTAPI +CmBattVerifyStaticInfo( + _Inout_ PCMBATT_DEVICE_EXTENSION DeviceExtension, + _In_ ULONG BatteryTag) +{ + NTSTATUS Status; + BOOLEAN UseBix; + PACPI_BATT_STATIC_INFO BattInfo; + PBATTERY_INFORMATION Info = &DeviceExtension->BatteryInformation; + + /* FIXME: This function is not fully implemented, more checks need to be implemented */ + UNREFERENCED_PARAMETER(BatteryTag); + + /* Retrieve the battery static info */ + Status = CmBattGetBattStaticInfo(DeviceExtension, &UseBix, &BattInfo); + if (NT_SUCCESS(Status)) + { + /* Initialize the battery information data */ + RtlZeroMemory(Info, sizeof(*Info)); + Info->Capabilities = BATTERY_SYSTEM_BATTERY; + + /* Copy the static information to the device extension of the battery */ + RtlCopyMemory(&DeviceExtension->BattInfo, BattInfo, sizeof(*BattInfo)); + + /* Check if the data from _BIX has to be used or not */ + if (UseBix) + { + CmBattVerifyBixData(DeviceExtension, Info); + } + else + { + CmBattVerifyBifData(DeviceExtension, Info); + } + + /* Free the static information buffer as we already copied it */ + ExFreePoolWithTag(BattInfo, CMBATT_BATT_STATIC_INFO_TAG); + } return Status; } @@ -499,20 +735,44 @@ CmBattIoctl(IN PDEVICE_OBJECT DeviceObject, } break; - case IOCTL_BATTERY_QUERY_BIF: + case IOCTL_BATTERY_QUERY_BIF_BIX: - /* Data is 1060 bytes long */ - if (OutputBufferLength == sizeof(ACPI_BIF_DATA)) + /* Return the battery static information to the caller depending on the supported ACPI method */ + if (DeviceExtension->BattInfo.ExtendedData) { - /* Query it */ - Status = CmBattGetBifData(DeviceExtension, - Irp->AssociatedIrp.SystemBuffer); - if (NT_SUCCESS(Status)) Irp->IoStatus.Information = sizeof(ACPI_BIF_DATA); + if (OutputBufferLength == sizeof(ACPI_BIX_DATA)) + { + /* Query it */ + Status = CmBattGetBixData(DeviceExtension, + Irp->AssociatedIrp.SystemBuffer); + if (NT_SUCCESS(Status)) + { + Irp->IoStatus.Information = sizeof(ACPI_BIX_DATA); + } + } + else + { + /* Buffer size invalid */ + Status = STATUS_INVALID_BUFFER_SIZE; + } } else { - /* Buffer size invalid */ - Status = STATUS_INVALID_BUFFER_SIZE; + if (OutputBufferLength == sizeof(ACPI_BIF_DATA)) + { + /* Query it */ + Status = CmBattGetBifData(DeviceExtension, + Irp->AssociatedIrp.SystemBuffer); + if (NT_SUCCESS(Status)) + { + Irp->IoStatus.Information = sizeof(ACPI_BIF_DATA); + } + } + else + { + /* Buffer size invalid */ + Status = STATUS_INVALID_BUFFER_SIZE; + } } break; @@ -668,7 +928,7 @@ CmBattSetStatusNotify(IN PCMBATT_DEVICE_EXTENSION DeviceExtension, { NTSTATUS Status; ACPI_BST_DATA BstData; - ULONG Capacity, NewTripPoint, TripPoint, DesignVoltage; + ULONG PowerUnit, Capacity, NewTripPoint, TripPoint, DesignVoltage; BOOLEAN Charging; PAGED_CODE(); if (CmBattDebug & (CMBATT_ACPI_WARNING | CMBATT_GENERIC_INFO)) @@ -707,11 +967,22 @@ CmBattSetStatusNotify(IN PCMBATT_DEVICE_EXTENSION DeviceExtension, NewTripPoint = BatteryNotify->LowCapacity; } + /* Is this machine supporting _BIX or _BIF? */ + if (DeviceExtension->BattInfo.ExtendedData) + { + PowerUnit = DeviceExtension->BattInfo.BixData.PowerUnit; + DesignVoltage = DeviceExtension->BattInfo.BixData.DesignVoltage; + } + else + { + PowerUnit = DeviceExtension->BattInfo.BifData.PowerUnit; + DesignVoltage = DeviceExtension->BattInfo.BifData.DesignVoltage; + } + /* Do we have data in Amps or Watts? */ - if (DeviceExtension->BifData.PowerUnit == ACPI_BATT_POWER_UNIT_AMPS) + if (PowerUnit == ACPI_BATT_POWER_UNIT_AMPS) { /* We need the voltage to do the conversion */ - DesignVoltage = DeviceExtension->BifData.DesignVoltage; if ((DesignVoltage != BATTERY_UNKNOWN_VOLTAGE) && (DesignVoltage)) { /* Convert from mAh into Ah */ @@ -814,7 +1085,9 @@ CmBattGetBatteryStatus(IN PCMBATT_DEVICE_EXTENSION DeviceExtension, { ULONG PsrData = 0; NTSTATUS Status; + BOOLEAN WasDischarging; ULONG BstState; + ULONG PowerUnit; ULONG DesignVoltage, PresentRate, RemainingCapacity; PAGED_CODE(); if (CmBattDebug & CMBATT_GENERIC_INFO) @@ -841,6 +1114,9 @@ CmBattGetBatteryStatus(IN PCMBATT_DEVICE_EXTENSION DeviceExtension, return Status; } + /* Remember if the battery was discharging at the time of querying new status */ + WasDischarging = !!(DeviceExtension->State & BATTERY_DISCHARGING); + /* Clear current BST information */ DeviceExtension->State = 0; DeviceExtension->RemainingCapacity = 0; @@ -863,9 +1139,9 @@ CmBattGetBatteryStatus(IN PCMBATT_DEVICE_EXTENSION DeviceExtension, { /* Set power state and check if it just started discharging now */ DeviceExtension->State |= BATTERY_DISCHARGING; - if (!(DeviceExtension->State & ACPI_BATT_STAT_DISCHARG)) + if (!WasDischarging) { - /* Remember the time when the state changed */ + /* The battery is discharging now and not before, remember the time when the state changed */ DeviceExtension->InterruptTime = KeQueryInterruptTime(); } } @@ -915,13 +1191,24 @@ CmBattGetBatteryStatus(IN PCMBATT_DEVICE_EXTENSION DeviceExtension, DbgPrint("CmBattGetBatteryStatus: AC adapter is NOT connected\n"); } + /* Is this machine supporting _BIX or _BIF? */ + if (DeviceExtension->BattInfo.ExtendedData) + { + PowerUnit = DeviceExtension->BattInfo.BixData.PowerUnit; + DesignVoltage = DeviceExtension->BattInfo.BixData.DesignVoltage; + } + else + { + PowerUnit = DeviceExtension->BattInfo.BifData.PowerUnit; + DesignVoltage = DeviceExtension->BattInfo.BifData.DesignVoltage; + } + /* Get some data we'll need */ - DesignVoltage = DeviceExtension->BifData.DesignVoltage; PresentRate = DeviceExtension->BstData.PresentRate; RemainingCapacity = DeviceExtension->BstData.RemainingCapacity; /* Check if we have battery data in Watts instead of Amps */ - if (DeviceExtension->BifData.PowerUnit == ACPI_BATT_POWER_UNIT_WATTS) + if (PowerUnit == ACPI_BATT_POWER_UNIT_WATTS) { /* Get the data from the BST */ DeviceExtension->RemainingCapacity = RemainingCapacity; @@ -939,7 +1226,7 @@ CmBattGetBatteryStatus(IN PCMBATT_DEVICE_EXTENSION DeviceExtension, } } } - else if ((DesignVoltage != CM_UNKNOWN_VALUE) && (DesignVoltage)) + else if ((DesignVoltage != CM_UNKNOWN_VALUE) && (DesignVoltage != 0)) // Same as doing PowerUnit == ACPI_BATT_POWER_UNIT_AMPS { /* We have voltage data, what about capacity? */ if (RemainingCapacity == CM_UNKNOWN_VALUE) @@ -1080,8 +1367,8 @@ CmBattQueryInformation(IN PCMBATT_DEVICE_EXTENSION FdoExtension, case BatteryEstimatedTime: - /* Check if it's been more than 2 1/2 minutes since the last change */ - if ((KeQueryInterruptTime() - 150000000) > (FdoExtension->InterruptTime)) + /* Check if it's been more than 15 seconds since the last change */ + if (KeQueryInterruptTime() > (FdoExtension->InterruptTime + CMBATT_DISCHARGE_TIME)) { /* Get new battery status */ CmBattGetBatteryStatus(FdoExtension, FdoExtension->Tag); @@ -1096,6 +1383,9 @@ CmBattQueryInformation(IN PCMBATT_DEVICE_EXTENSION FdoExtension, /* Grab the remaining capacity */ RemainingCapacity = FdoExtension->RemainingCapacity; + /* Default time to unknown if we fail the request later */ + RemainingTime = BATTERY_UNKNOWN_TIME; + /* See if we don't know one or the other */ if ((Rate == BATTERY_UNKNOWN_RATE) || (RemainingCapacity == BATTERY_UNKNOWN_CAPACITY)) @@ -1127,7 +1417,7 @@ CmBattQueryInformation(IN PCMBATT_DEVICE_EXTENSION FdoExtension, else { /* We have data, but is it valid? */ - if (RemainingCapacity > 0x123456) + if (RemainingCapacity > CMBATT_CAPACITY_BOGUS) { /* The capacity seems bogus, so don't use it */ if (CmBattDebug & CMBATT_ACPI_WARNING) @@ -1140,6 +1430,10 @@ CmBattQueryInformation(IN PCMBATT_DEVICE_EXTENSION FdoExtension, } } } + else + { + RemainingTime = BATTERY_UNKNOWN_TIME; + } /* Return the remaining time */ QueryData = &RemainingTime; @@ -1149,7 +1443,14 @@ CmBattQueryInformation(IN PCMBATT_DEVICE_EXTENSION FdoExtension, case BatteryDeviceName: /* Build the model number string */ - RtlInitAnsiString(&TempString, FdoExtension->BifData.ModelNumber); + if (FdoExtension->BattInfo.ExtendedData) + { + RtlInitAnsiString(&TempString, FdoExtension->BattInfo.BixData.ModelNumber); + } + else + { + RtlInitAnsiString(&TempString, FdoExtension->BattInfo.BifData.ModelNumber); + } /* Convert it to Unicode */ InfoString.Buffer = InfoBuffer; @@ -1171,7 +1472,14 @@ CmBattQueryInformation(IN PCMBATT_DEVICE_EXTENSION FdoExtension, case BatteryManufactureName: /* Build the OEM info string */ - RtlInitAnsiString(&TempString, FdoExtension->BifData.OemInfo); + if (FdoExtension->BattInfo.ExtendedData) + { + RtlInitAnsiString(&TempString, FdoExtension->BattInfo.BixData.OemInfo); + } + else + { + RtlInitAnsiString(&TempString, FdoExtension->BattInfo.BifData.OemInfo); + } /* Convert it to Unicode */ InfoString.Buffer = InfoBuffer; @@ -1186,7 +1494,14 @@ CmBattQueryInformation(IN PCMBATT_DEVICE_EXTENSION FdoExtension, case BatteryUniqueID: /* Build the serial number string */ - RtlInitAnsiString(&TempString, FdoExtension->BifData.SerialNumber); + if (FdoExtension->BattInfo.ExtendedData) + { + RtlInitAnsiString(&TempString, FdoExtension->BattInfo.BixData.SerialNumber); + } + else + { + RtlInitAnsiString(&TempString, FdoExtension->BattInfo.BifData.SerialNumber); + } /* Convert it to Unicode */ InfoString.Buffer = InfoBuffer; @@ -1198,10 +1513,18 @@ CmBattQueryInformation(IN PCMBATT_DEVICE_EXTENSION FdoExtension, TempString2.MaximumLength = sizeof(TempBuffer); /* Check if there's an OEM string */ - if (FdoExtension->BifData.OemInfo[0]) + if ((FdoExtension->BattInfo.ExtendedData && FdoExtension->BattInfo.BixData.OemInfo[0]) || + FdoExtension->BattInfo.BifData.OemInfo[0]) { /* Build the OEM info string */ - RtlInitAnsiString(&TempString, FdoExtension->BifData.OemInfo); + if (FdoExtension->BattInfo.ExtendedData) + { + RtlInitAnsiString(&TempString, FdoExtension->BattInfo.BixData.OemInfo); + } + else + { + RtlInitAnsiString(&TempString, FdoExtension->BattInfo.BifData.OemInfo); + } /* Convert it to Unicode and append it */ RtlAnsiStringToUnicodeString(&TempString2, &TempString, 0); @@ -1209,7 +1532,14 @@ CmBattQueryInformation(IN PCMBATT_DEVICE_EXTENSION FdoExtension, } /* Build the model number string */ - RtlInitAnsiString(&TempString, FdoExtension->BifData.ModelNumber); + if (FdoExtension->BattInfo.ExtendedData) + { + RtlInitAnsiString(&TempString, FdoExtension->BattInfo.BixData.ModelNumber); + } + else + { + RtlInitAnsiString(&TempString, FdoExtension->BattInfo.BifData.ModelNumber); + } /* Convert it to Unicode and append it */ RtlAnsiStringToUnicodeString(&TempString2, &TempString, 0); diff --git a/drivers/bus/acpi/cmbatt/cmbatt.h b/drivers/acpi/cmbatt/cmbatt.h similarity index 76% rename from drivers/bus/acpi/cmbatt/cmbatt.h rename to drivers/acpi/cmbatt/cmbatt.h index bb130208763f5..4a2ec81acd384 100644 --- a/drivers/bus/acpi/cmbatt/cmbatt.h +++ b/drivers/acpi/cmbatt/cmbatt.h @@ -26,7 +26,7 @@ #define IOCTL_BATTERY_SET_TRIP_POINT \ CTL_CODE(FILE_DEVICE_BATTERY, 0x104, METHOD_BUFFERED, FILE_READ_ACCESS) // 0x294410 -#define IOCTL_BATTERY_QUERY_BIF \ +#define IOCTL_BATTERY_QUERY_BIF_BIX \ CTL_CODE(FILE_DEVICE_BATTERY, 0x105, METHOD_BUFFERED, FILE_READ_ACCESS) // 0x294414 #define IOCTL_BATTERY_QUERY_BST \ @@ -42,6 +42,18 @@ #define CMBATT_PNP_ENTRY_EXIT 0x200 #define CMBATT_ACPI_ASSERT 0x400 +// +// Constant used to determine if the battery was discharging +// for over 15 seconds since last time the AC adapter got unplugged. +// +#define CMBATT_DISCHARGE_TIME 150000000 + +// +// Bogus constant used to determine if the remaining battery capacity +// overflows which is returned by the hardware. +// +#define CMBATT_CAPACITY_BOGUS 0x100000 + typedef enum _CMBATT_EXTENSION_TYPE { CmBattAcAdapter, @@ -67,6 +79,13 @@ typedef enum _CMBATT_EXTENSION_TYPE #define CM_MAX_VALUE 0x7FFFFFFF #define CM_UNKNOWN_VALUE 0xFFFFFFFF +#define CONVERT_MAH_TO_MWH(mA, Volts) (((mA) * (Volts) + 500) / 1000) + +#define CONVERT_BATT_INFO(Capacity, DesignVoltage) \ + (((Capacity) != BATTERY_UNKNOWN_CAPACITY) \ + ? CONVERT_MAH_TO_MWH((Capacity), (DesignVoltage)) \ + : BATTERY_UNKNOWN_CAPACITY) + typedef struct _ACPI_BST_DATA { ULONG State; @@ -78,6 +97,8 @@ typedef struct _ACPI_BST_DATA #define ACPI_BATT_POWER_UNIT_WATTS 0x0 #define ACPI_BATT_POWER_UNIT_AMPS 0x1 +#define ASCIIZ_MAX_LENGTH 256 + typedef struct _ACPI_BIF_DATA { ULONG PowerUnit; @@ -89,12 +110,46 @@ typedef struct _ACPI_BIF_DATA ULONG DesignCapacityLow; ULONG BatteryCapacityGranularity1; ULONG BatteryCapacityGranularity2; - CHAR ModelNumber[256]; - CHAR SerialNumber[256]; - CHAR BatteryType[256]; - CHAR OemInfo[256]; + CHAR ModelNumber[ASCIIZ_MAX_LENGTH]; + CHAR SerialNumber[ASCIIZ_MAX_LENGTH]; + CHAR BatteryType[ASCIIZ_MAX_LENGTH]; + CHAR OemInfo[ASCIIZ_MAX_LENGTH]; } ACPI_BIF_DATA, *PACPI_BIF_DATA; +typedef struct _ACPI_BIX_DATA +{ + ULONG Revision; + ULONG PowerUnit; + ULONG DesignCapacity; + ULONG LastFullCapacity; + ULONG BatteryTechnology; + ULONG DesignVoltage; + ULONG DesignCapacityWarning; + ULONG DesignCapacityLow; + ULONG CycleCount; + ULONG Accuracy; + ULONG MaxSampleTime; + ULONG MinSampleTime; + ULONG MaxAverageInterval; + ULONG MinAverageInterval; + ULONG BatteryCapacityGranularity1; + ULONG BatteryCapacityGranularity2; + CHAR ModelNumber[ASCIIZ_MAX_LENGTH]; + CHAR SerialNumber[ASCIIZ_MAX_LENGTH]; + CHAR BatteryType[ASCIIZ_MAX_LENGTH]; + CHAR OemInfo[ASCIIZ_MAX_LENGTH]; + ULONG SwapCapability; +} ACPI_BIX_DATA, *PACPI_BIX_DATA; + +typedef struct _ACPI_BATT_STATIC_INFO +{ + ACPI_BIF_DATA BifData; + ACPI_BIX_DATA BixData; + BOOLEAN ExtendedData; +} ACPI_BATT_STATIC_INFO, *PACPI_BATT_STATIC_INFO; + +#define CMBATT_BATT_STATIC_INFO_TAG 'nItS' + #define CMBATT_AR_NOTIFY 0x01 #define CMBATT_AR_INSERT 0x02 #define CMBATT_AR_REMOVE 0x04 @@ -125,7 +180,7 @@ typedef struct _CMBATT_DEVICE_EXTENSION ULONG TagData; ULONG Tag; ACPI_BST_DATA BstData; - ACPI_BIF_DATA BifData; + ACPI_BATT_STATIC_INFO BattInfo; ULONG Id; ULONG State; ULONG RemainingCapacity; @@ -196,6 +251,13 @@ CmBattGetBifData( PACPI_BIF_DATA BifData ); +NTSTATUS +NTAPI +CmBattGetBixData( + _In_ PCMBATT_DEVICE_EXTENSION DeviceExtension, + _Out_ PACPI_BIX_DATA BixData +); + NTSTATUS NTAPI CmBattSetTripPpoint( diff --git a/drivers/bus/acpi/cmbatt/cmbatt.rc b/drivers/acpi/cmbatt/cmbatt.rc similarity index 100% rename from drivers/bus/acpi/cmbatt/cmbatt.rc rename to drivers/acpi/cmbatt/cmbatt.rc diff --git a/drivers/bus/acpi/cmbatt/cmbpnp.c b/drivers/acpi/cmbatt/cmbpnp.c similarity index 100% rename from drivers/bus/acpi/cmbatt/cmbpnp.c rename to drivers/acpi/cmbatt/cmbpnp.c diff --git a/drivers/bus/acpi/cmbatt/cmbwmi.c b/drivers/acpi/cmbatt/cmbwmi.c similarity index 100% rename from drivers/bus/acpi/cmbatt/cmbwmi.c rename to drivers/acpi/cmbatt/cmbwmi.c diff --git a/drivers/bus/acpi/cmbatt/cmexec.c b/drivers/acpi/cmbatt/cmexec.c similarity index 85% rename from drivers/bus/acpi/cmbatt/cmexec.c rename to drivers/acpi/cmbatt/cmexec.c index b1d294ae9ef4d..6caf314617cd3 100644 --- a/drivers/bus/acpi/cmbatt/cmexec.c +++ b/drivers/acpi/cmbatt/cmexec.c @@ -300,7 +300,7 @@ CmBattGetStaData(IN PDEVICE_OBJECT DeviceObject, ASSERT(StaData != NULL); *StaData = 0; - /* Request the _PSR method */ + /* Request the _STA method */ *(PULONG)InputBuffer.MethodName = 'ATS_'; InputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE; @@ -346,7 +346,7 @@ CmBattGetUniqueId(IN PDEVICE_OBJECT DeviceObject, ASSERT(UniqueId != NULL); *UniqueId = 0; - /* Request the _PSR method */ + /* Request the _UID method */ *(PULONG)InputBuffer.MethodName = 'DIU_'; InputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE; @@ -445,6 +445,70 @@ CmBattGetBifData(PCMBATT_DEVICE_EXTENSION DeviceExtension, RTL_NUMBER_OF(BifFields)); } +/** + * @brief + * Retrieves the eXtended static battery information from the + * ACPI _BIX method. + * + * @param[in] DeviceExtension + * A pointer to a Control Method (CM) battery device extension. + * It is used to send the ACPI method evaluation operation + * to the ACPI driver of which it is attached to this CM battery. + * + * @param[out] BixData + * A pointer to a structure that contains the _BIX data fields, + * returned to caller. + * + * @return + * Returns STATUS_SUCCESS if the operation has succeeded successfully, + * otherwise a failure NTSTATUS code is returned. + */ +NTSTATUS +NTAPI +CmBattGetBixData( + _In_ PCMBATT_DEVICE_EXTENSION DeviceExtension, + _Out_ PACPI_BIX_DATA BixData) +{ + ACPI_PACKAGE_FIELD BixFields[] = { + { "Revision", FALSE, &BixData->Revision }, + { "PowerUnit", FALSE, &BixData->PowerUnit }, + { "DesignCapacity", FALSE, &BixData->DesignCapacity }, + { "LastFullCapacity", FALSE, &BixData->LastFullCapacity }, + { "BatteryTechnology", FALSE, &BixData->BatteryTechnology }, + { "DesignVoltage", FALSE, &BixData->DesignVoltage }, + { "DesignCapacityWarning", FALSE, &BixData->DesignCapacityWarning }, + { "DesignCapacityLow", FALSE, &BixData->DesignCapacityLow }, + { "CycleCount", FALSE, &BixData->CycleCount }, + { "Accuracy", FALSE, &BixData->Accuracy }, + { "MaxSampleTime", FALSE, &BixData->MaxSampleTime }, + { "MinSampleTime", FALSE, &BixData->MinSampleTime }, + { "MaxAverageInterval", FALSE, &BixData->MaxAverageInterval }, + { "MinAverageInterval", FALSE, &BixData->MinAverageInterval }, + { "BatteryCapacityGranularity1", FALSE, &BixData->BatteryCapacityGranularity1 }, + { "BatteryCapacityGranularity2", FALSE, &BixData->BatteryCapacityGranularity2 }, + { "ModelNumber", TRUE, &BixData->ModelNumber }, + { "SerialNumber", TRUE, &BixData->SerialNumber }, + { "BatteryType", TRUE, &BixData->BatteryType }, + { "OemInfo", TRUE, &BixData->OemInfo }, + { "SwapCapability", FALSE, &BixData->SwapCapability }, + }; + PAGED_CODE(); + + if (CmBattDebug & CMBATT_ACPI_ENTRY_EXIT) + { + DbgPrint("CmBattGetBixData: Buffer (0x%x) Device %x Tid %x\n", + BixData, DeviceExtension->DeviceId, KeGetCurrentThread()); + } + + /* Request the ACPI driver to get the _BIX data for us */ + return CmBattCallAcpiPackage("CmBattGetBifData", + DeviceExtension, + 'XIB_', + 512, + BixFields, + RTL_NUMBER_OF(BixFields)); +} + NTSTATUS NTAPI CmBattGetBstData(PCMBATT_DEVICE_EXTENSION DeviceExtension, diff --git a/drivers/bus/acpi/cmbatt/guid.c b/drivers/acpi/cmbatt/guid.c similarity index 100% rename from drivers/bus/acpi/cmbatt/guid.c rename to drivers/acpi/cmbatt/guid.c diff --git a/drivers/base/bootvid/fontdata.c b/drivers/base/bootvid/fontdata.c index f0e4523c48e1b..c258394ea43fa 100644 --- a/drivers/base/bootvid/fontdata.c +++ b/drivers/base/bootvid/fontdata.c @@ -10,7 +10,7 @@ // // The character generator is in natural order, top of char is first element. // The used font is 8x13 from plan 9, copyright Markus Kuhn. -// Available from http://mirtchovski.com/p9/fonts/ +// Available from https://web.archive.org/web/20210510052051/http://mirtchovski.com/p9/fonts/ // FontData Array generated by bootvid_font_generator. // UCHAR VidpFontData[256 * BOOTCHAR_HEIGHT] = diff --git a/drivers/base/kdcom/kddll.c b/drivers/base/kdcom/kddll.c index 7bae16d7c7e48..038c3f7bd6412 100644 --- a/drivers/base/kdcom/kddll.c +++ b/drivers/base/kdcom/kddll.c @@ -22,7 +22,7 @@ ULONG RemotePacketId = INITIAL_PACKET_ID; * \param Buffer Pointer to the packet data. * \param Length Length of data in bytes. * \return The calculated checksum. - * \sa http://www.vista-xp.co.uk/forums/technical-reference-library/2540-basics-debugging.html + * \sa http://www.vista-xp.co.uk/forums/technical-reference-library/2540-basics-debugging.html (DEAD_LINK) */ ULONG NTAPI diff --git a/drivers/battery/CMakeLists.txt b/drivers/battery/CMakeLists.txt index 1a3ce8142914b..2f949902ebca8 100644 --- a/drivers/battery/CMakeLists.txt +++ b/drivers/battery/CMakeLists.txt @@ -1,2 +1,3 @@ add_subdirectory(battc) +add_subdirectory(compbatt) diff --git a/drivers/battery/battc/battc.c b/drivers/battery/battc/battc.c index dd08a9cd956c2..e724f720b5fb4 100644 --- a/drivers/battery/battc/battc.c +++ b/drivers/battery/battc/battc.c @@ -76,11 +76,13 @@ BatteryClassQueryWmiDataBlock(PVOID ClassData, BCLASSAPI NTSTATUS NTAPI -BatteryClassStatusNotify(PVOID ClassData) +BatteryClassStatusNotify( + _In_ PVOID ClassData) { PBATTERY_CLASS_DATA BattClass; PBATTERY_WAIT_STATUS BattWait; BATTERY_STATUS BattStatus; + ULONG Tag; NTSTATUS Status; DPRINT("Received battery status notification from %p\n", ClassData); @@ -99,7 +101,14 @@ BatteryClassStatusNotify(PVOID ClassData) { case EVENT_BATTERY_TAG: ExReleaseFastMutex(&BattClass->Mutex); - DPRINT1("Waiting for battery is UNIMPLEMENTED!\n"); + Status = BattClass->MiniportInfo.QueryTag(BattClass->MiniportInfo.Context, + &Tag); + if (!NT_SUCCESS(Status)) + return Status; + + ExAcquireFastMutex(&BattClass->Mutex); + KeSetEvent(&BattClass->WaitEvent, IO_NO_INCREMENT, FALSE); + ExReleaseFastMutex(&BattClass->Mutex); break; case EVENT_BATTERY_STATUS: @@ -223,7 +232,7 @@ BatteryClassIoctl(PVOID ClassData, WaitTime = IrpSp->Parameters.DeviceIoControl.InputBufferLength == sizeof(ULONG) ? *(PULONG)Irp->AssociatedIrp.SystemBuffer : 0; - Timeout.QuadPart = Int32x32To64(WaitTime, -1000); + Timeout.QuadPart = Int32x32To64(WaitTime, -10000); Status = BattClass->MiniportInfo.QueryTag(BattClass->MiniportInfo.Context, (PULONG)Irp->AssociatedIrp.SystemBuffer); @@ -272,7 +281,7 @@ BatteryClassIoctl(PVOID ClassData, BattWait = *(PBATTERY_WAIT_STATUS)Irp->AssociatedIrp.SystemBuffer; - Timeout.QuadPart = Int32x32To64(BattWait.Timeout, -1000); + Timeout.QuadPart = Int32x32To64(BattWait.Timeout, -10000); BattStatus = Irp->AssociatedIrp.SystemBuffer; Status = BattClass->MiniportInfo.QueryStatus(BattClass->MiniportInfo.Context, diff --git a/drivers/bus/acpi/compbatt/CMakeLists.txt b/drivers/battery/compbatt/CMakeLists.txt similarity index 100% rename from drivers/bus/acpi/compbatt/CMakeLists.txt rename to drivers/battery/compbatt/CMakeLists.txt diff --git a/drivers/battery/compbatt/compbatt.c b/drivers/battery/compbatt/compbatt.c new file mode 100644 index 0000000000000..3edb3fb78a8a2 --- /dev/null +++ b/drivers/battery/compbatt/compbatt.c @@ -0,0 +1,1788 @@ +/* + * PROJECT: ReactOS Composite Battery Driver + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: Main Initialization Code and IRP Handling + * COPYRIGHT: Copyright 2010 ReactOS Portable Systems Group + * Copyright 2024 George Bișoc + */ + +/* INCLUDES *******************************************************************/ + +#include "compbatt.h" + +#include + +/* GLOBALS ********************************************************************/ + +ULONG CompBattDebug; + +/* FUNCTIONS ******************************************************************/ + +NTSTATUS +NTAPI +CompBattOpenClose( + _In_ PDEVICE_OBJECT DeviceObject, + _In_ PIRP Irp) +{ + PAGED_CODE(); + if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: ENTERING OpenClose\n"); + + /* Complete the IRP with success */ + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + /* Return success */ + if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: Exiting OpenClose\n"); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +CompBattSystemControl( + _In_ PDEVICE_OBJECT DeviceObject, + _In_ PIRP Irp) +{ + PCOMPBATT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; + NTSTATUS Status; + PAGED_CODE(); + if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: ENTERING System Control\n"); + + /* Are we attached yet? */ + if (DeviceExtension->AttachedDevice) + { + /* Send it up the stack */ + IoSkipCurrentIrpStackLocation(Irp); + Status = IoCallDriver(DeviceExtension->AttachedDevice, Irp); + } + else + { + /* We don't support WMI */ + Status = STATUS_NOT_SUPPORTED; + Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + } + + /* Return status */ + return Status; +} + +/** + * @brief + * Queues a work item thread worker which is bound to the individual + * CM (Control Method) ACPI battery to handle the IRP. + * + * @param[in] DeviceObject + * A pointer to a device object, this parameter is unused. + * + * @param[in] Irp + * A pointer to an I/O request packet. It is used to gather the I/O stack + * location which contains the data of the individual battery. + * + * @param[in] Context + * An aribtrary pointer that points to context data, this paramater + * is unused. + * + * @return + * Returns STATUS_MORE_PROCESSING_REQUIRED to indicate the I/O request + * is still in action, therefore the IRP is not freed. + */ +NTSTATUS +NTAPI +CompBattMonitorIrpComplete( + _In_ PDEVICE_OBJECT DeviceObject, + _In_ PIRP Irp, + _In_ PVOID Context) +{ + PIO_STACK_LOCATION IoStackLocation; + PCOMPBATT_BATTERY_DATA BatteryData; + + /* We do not care about the device object */ + UNREFERENCED_PARAMETER(DeviceObject); + + /* Grab the composite battery data from the I/O stack packet */ + IoStackLocation = IoGetCurrentIrpStackLocation(Irp); + BatteryData = IoStackLocation->Parameters.Others.Argument2; + + /* Request the IRP complete worker to do the deed */ + ExQueueWorkItem(&BatteryData->WorkItem, DelayedWorkQueue); + return STATUS_MORE_PROCESSING_REQUIRED; +} + +/** + * @brief + * The brains of the battery IRP worker. It monitors the state of the + * IRP as well as sends the IRP down the device stack to gather battery + * related data, such tag and status. It also serves as the I/O + * completion routine of which it elaborates the gathered data. + * + * @param[in] BatteryData + * A pointer to battery data of an individual battery that contains + * the IRP to be send down the device stack. + */ +VOID +NTAPI +CompBattMonitorIrpCompleteWorker( + _In_ PCOMPBATT_BATTERY_DATA BatteryData) +{ + NTSTATUS Status; + PIRP Irp; + UCHAR Mode; + ULONG PrevPowerState; + PDEVICE_OBJECT DeviceObject; + BATTERY_STATUS BatteryStatus; + PIO_STACK_LOCATION IoStackLocation; + PCOMPBATT_DEVICE_EXTENSION DeviceExtension; + + /* Cache the necessary battery data */ + Irp = BatteryData->Irp; + DeviceObject = BatteryData->DeviceObject; + IoStackLocation = IoGetCurrentIrpStackLocation(Irp); + DeviceExtension = IoStackLocation->Parameters.Others.Argument1; + + /* Switch to the next stack as we have to setup the control function data there */ + IoStackLocation = IoGetNextIrpStackLocation(Irp); + + /* Has the I/O composite battery request succeeded? */ + Status = Irp->IoStatus.Status; + if (!NT_SUCCESS(Status) && Status != STATUS_CANCELLED) + { + /* + * This battery is being removed from the composite, perform + * cleanups and do not inquire I/O requests again on this battery. + */ + if (Status == STATUS_DEVICE_REMOVED) + { + if (CompBattDebug & COMPBATT_DEBUG_WARN) + DbgPrint("CompBatt: Battery (0x%p) is being removed from composite battery\n", BatteryData); + + IoFreeIrp(Irp); + CompBattRemoveBattery(&BatteryData->BatteryName, DeviceExtension); + return; + } + + /* + * This is the first time a battery is being added into the composite + * (we understand that if Status was STATUS_DEVICE_NOT_CONNECTED). + * We must invalidate the composite tag and request a recalculation + * of the battery tag. + */ + if (CompBattDebug & COMPBATT_DEBUG_WARN) + DbgPrint("CompBatt: Battery arrived for first time or disappeared (Status 0x%08lx)\n", Status); + + BatteryData->Tag = BATTERY_TAG_INVALID; + + /* + * Invalidate the last read status interrupt time as well since the last + * battery status data no longer applies. Same for the composite battery + * as well. + */ + BatteryData->InterruptTime = 0; + DeviceExtension->InterruptTime = 0; + + /* Notify Battery Class the battery status incurs in a change */ + BatteryClassStatusNotify(DeviceExtension->ClassData); + + /* Setup the necessary I/O data to query the battery tag */ + IoStackLocation->Parameters.DeviceIoControl.IoControlCode = IOCTL_BATTERY_QUERY_TAG; + IoStackLocation->Parameters.DeviceIoControl.InputBufferLength = sizeof(ULONG); + IoStackLocation->Parameters.DeviceIoControl.OutputBufferLength = sizeof(ULONG); + BatteryData->Mode = COMPBATT_QUERY_TAG; + BatteryData->WorkerBuffer.WorkerTag = 0xFFFFFFFF; + + /* Dispatch our request now to the battery's driver */ + goto DispatchRequest; + } + + /* Our I/O request has been completed successfully, check what did we get */ + Mode = BatteryData->Mode; + switch (Mode) + { + case COMPBATT_QUERY_TAG: + { + /* + * This battery has just gotten a tag, acknowledge the composite battery + * about that so it can recalculate its own composite tag. + */ + if (CompBattDebug & COMPBATT_DEBUG_WARN) + DbgPrint("CompBatt: Battery (Device 0x%p) has a tag of %lu\n", DeviceObject, BatteryData->WorkerBuffer.WorkerTag); + + /* Ensure the battery tag is not bogus, getting a tag of 0 is illegal */ + ASSERT(BatteryData->WorkerBuffer.WorkerTag != 0); + + /* Assign the battery tag */ + BatteryData->Tag = BatteryData->WorkerBuffer.WorkerTag; + BatteryData->Flags |= COMPBATT_TAG_ASSIGNED; + + /* Punt the composite battery flags, as the previous cached data no longer applies */ + DeviceExtension->Flags = 0; + + /* Notify the Battery Class driver this battery has got a tag */ + BatteryClassStatusNotify(DeviceExtension->ClassData); + break; + } + + case COMPBATT_READ_STATUS: + { + /* + * Read the battery status only if the IRP has not been cancelled, + * otherwise the request must be re-issued again. This typically + * happens if the wait values are in conflict which it might + * end up in inconsistent battery status results. + */ + if (Status != STATUS_CANCELLED && !Irp->Cancel) + { + /* + * If we reach here then the battery has entered into a change of + * power state or its charge capacity has changed. + */ + if (CompBattDebug & COMPBATT_DEBUG_WARN) + DbgPrint("CompBatt: Battery state (Device 0x%p) has changed\n", DeviceObject); + + /* Copy the battery status of this battery */ + RtlCopyMemory(&BatteryData->BatteryStatus, + &BatteryData->WorkerBuffer.WorkerStatus, + sizeof(BatteryData->BatteryStatus)); + + /* Update the interrupt time as this is the most recent read of the battery status */ + BatteryData->InterruptTime = KeQueryInterruptTime(); + + /* + * Ensure we have not gotten unknown capacities while we waited for new + * battery status. The battery might have malfunctioned or something. + */ + if (BatteryData->WorkerBuffer.WorkerStatus.Capacity == BATTERY_UNKNOWN_CAPACITY) + { + /* We do not know the capacity of this battery, default the low and high capacities */ + BatteryData->WaitStatus.LowCapacity = BATTERY_UNKNOWN_CAPACITY; + BatteryData->WaitStatus.HighCapacity = BATTERY_UNKNOWN_CAPACITY; + } + else + { + /* We know the capacity, adjust the low and high capacities accordingly */ + if (BatteryData->WaitStatus.LowCapacity > + BatteryData->WorkerBuffer.WorkerStatus.Capacity) + { + BatteryData->WaitStatus.LowCapacity = BatteryData->WorkerBuffer.WorkerStatus.Capacity; + } + + if (BatteryData->WaitStatus.HighCapacity < + BatteryData->WorkerBuffer.WorkerStatus.Capacity) + { + BatteryData->WaitStatus.HighCapacity = BatteryData->WorkerBuffer.WorkerStatus.Capacity; + } + } + + /* Copy the current last read power state for the next wait */ + BatteryData->WaitStatus.PowerState = BatteryData->WorkerBuffer.WorkerStatus.PowerState; + + /* + * Cache the previous power state of the composite battery and invalidate + * the last computed battery status interrupt time. This is because, + * logically, this specific battery incurred in a state change therefore + * the previous composite status is no longer consistent. + */ + PrevPowerState = DeviceExtension->BatteryStatus.PowerState; + DeviceExtension->InterruptTime = 0; + + /* Compute a new battery status for the composite battery */ + Status = CompBattQueryStatus(DeviceExtension, + DeviceExtension->Tag, + &BatteryStatus); + + /* Print out the current battery status of the composite to the debugger */ + if ((CompBattDebug & COMPBATT_DEBUG_INFO) && NT_SUCCESS(Status)) + DbgPrint("CompBatt: Latest composite battery status\n" + " PowerState -> 0x%lx\n" + " Capacity -> %u\n" + " Voltage -> %u\n" + " Rate -> %d\n", + BatteryStatus.PowerState, + BatteryStatus.Capacity, + BatteryStatus.Voltage, + BatteryStatus.Rate); + + /* + * Now determine whether should we notify the Battery Class driver due to + * changes in power state settings in the composite battery. This could + * happen in two following conditions: + * + * 1. The status notify flag was set for the respective power notification + * settings, and the composite battery incurred in a change of such + * settings. In this case we have to probe the current settings that + * they have changed. + * + * 2. The status notify flag was not set, therefore we do not know the + * exact configuration of the notification settings. We only care that + * the power state has changed at this point. + * + * Why do we have to do this is because we have to warn the Battery Class + * about the data that has changed. + */ + if (!(DeviceExtension->Flags & COMPBATT_STATUS_NOTIFY_SET)) + { + if (PrevPowerState != DeviceExtension->BatteryStatus.PowerState) + { + /* The previous power state is no longer valid, notify Battery Class */ + BatteryClassStatusNotify(DeviceExtension->ClassData); + } + } + else + { + /* + * Unlike the condition above, we check for power state change against + * the current notify wait set since the notify set flag bit is assigned. + */ + if (DeviceExtension->WaitNotifyStatus.PowerState != DeviceExtension->BatteryStatus.PowerState || + DeviceExtension->WaitNotifyStatus.LowCapacity > DeviceExtension->BatteryStatus.Capacity || + DeviceExtension->WaitNotifyStatus.HighCapacity < DeviceExtension->BatteryStatus.Capacity) + { + /* The following configuration settings have changed, notify Battery Class */ + BatteryClassStatusNotify(DeviceExtension->ClassData); + } + } + } + + break; + } + + default: + { + ASSERTMSG("CompBatt: BAD!!! WE SHOULD NOT BE HERE!\n", FALSE); + UNREACHABLE; + } + } + + /* Setup the necessary data to read battery status */ + BatteryData->WaitStatus.BatteryTag = BatteryData->Tag; + BatteryData->WaitStatus.Timeout = 3000; // FIXME: Hardcoded (wait for 3 seconds) because we do not have ACPI notifications implemented yet... + + RtlCopyMemory(&BatteryData->WorkerBuffer.WorkerWaitStatus, + &BatteryData->WaitStatus, + sizeof(BatteryData->WaitStatus)); + + IoStackLocation->Parameters.DeviceIoControl.IoControlCode = IOCTL_BATTERY_QUERY_STATUS; + IoStackLocation->Parameters.DeviceIoControl.InputBufferLength = sizeof(BatteryData->WorkerBuffer.WorkerWaitStatus); + IoStackLocation->Parameters.DeviceIoControl.OutputBufferLength = sizeof(BatteryData->WorkerBuffer.WorkerStatus); + BatteryData->Mode = COMPBATT_READ_STATUS; + +DispatchRequest: + /* Setup the system buffer to that of the battery data which it will hold the returned data */ + IoStackLocation->MajorFunction = IRP_MJ_DEVICE_CONTROL; + Irp->AssociatedIrp.SystemBuffer = &BatteryData->WorkerBuffer; + Irp->Cancel = FALSE; + Irp->PendingReturned = FALSE; + + /* Setup the worker completion routine which it will invoke the worker later on */ + IoSetCompletionRoutine(Irp, + CompBattMonitorIrpComplete, + NULL, + TRUE, + TRUE, + TRUE); + + /* Dispatch the I/O request now */ + IoCallDriver(DeviceObject, Irp); +} + +VOID +NTAPI +CompBattRecalculateTag( + _In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension) +{ + PCOMPBATT_BATTERY_DATA BatteryData; + ULONG Tag; + PLIST_ENTRY ListHead, NextEntry; + if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: ENTERING CompBattRecalculateTag\n"); + + /* Loop the battery list */ + ExAcquireFastMutex(&DeviceExtension->Lock); + ListHead = &DeviceExtension->BatteryList; + NextEntry = ListHead->Flink; + while (NextEntry != ListHead) + { + /* Get the battery information and check if it has a tag */ + BatteryData = CONTAINING_RECORD(NextEntry, COMPBATT_BATTERY_DATA, BatteryLink); + if (BatteryData->Flags & COMPBATT_TAG_ASSIGNED) + { + /* Generate the next tag and exit */ + Tag = DeviceExtension->NextTag; + DeviceExtension->Flags |= COMPBATT_TAG_ASSIGNED; + DeviceExtension->Tag = Tag; + DeviceExtension->NextTag = Tag + 1; + break; + } + + /* No tag for this device extension, clear it */ + DeviceExtension->Tag = BATTERY_TAG_INVALID; + NextEntry = NextEntry->Flink; + } + + /* We're done */ + ExReleaseFastMutex(&DeviceExtension->Lock); + if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: EXITING CompBattRecalculateTag\n"); +} + +NTSTATUS +NTAPI +CompBattIoctl( + _In_ PDEVICE_OBJECT DeviceObject, + _In_ PIRP Irp) +{ + PCOMPBATT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; + NTSTATUS Status; + if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: ENTERING Ioctl\n"); + + /* Let the class driver handle it */ + Status = BatteryClassIoctl(DeviceExtension->ClassData, Irp); + if (Status == STATUS_NOT_SUPPORTED) + { + /* It failed, try the next driver up the stack */ + Irp->IoStatus.Status = Status; + IoSkipCurrentIrpStackLocation(Irp); + Status = IoCallDriver(DeviceExtension->AttachedDevice, Irp); + } + + /* Return status */ + if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: EXITING Ioctl\n"); + return Status; +} + +NTSTATUS +NTAPI +CompBattQueryTag( + _In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension, + _Out_ PULONG Tag) +{ + NTSTATUS Status; + PAGED_CODE(); + if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: ENTERING QueryTag\n"); + + /* Was a tag assigned? */ + if (!(DeviceExtension->Flags & COMPBATT_TAG_ASSIGNED)) + { + /* Assign one */ + CompBattRecalculateTag(DeviceExtension); + } + + /* Do we have a tag now? */ + if ((DeviceExtension->Flags & COMPBATT_TAG_ASSIGNED) && DeviceExtension->Tag != BATTERY_TAG_INVALID) + { + /* Return the tag */ + *Tag = DeviceExtension->Tag; + Status = STATUS_SUCCESS; + } + else + { + /* No tag */ + *Tag = BATTERY_TAG_INVALID; + Status = STATUS_NO_SUCH_DEVICE; + } + + /* Return status */ + if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: EXITING QueryTag\n"); + return Status; +} + +NTSTATUS +NTAPI +CompBattDisableStatusNotify( + _In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension) +{ + PCOMPBATT_BATTERY_DATA BatteryData; + PLIST_ENTRY ListHead, NextEntry; + if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: ENTERING DisableStatusNotify\n"); + + /* Loop the battery list */ + ExAcquireFastMutex(&DeviceExtension->Lock); + ListHead = &DeviceExtension->BatteryList; + NextEntry = ListHead->Flink; + while (NextEntry != ListHead) + { + /* Get the battery information and clear capacity data */ + BatteryData = CONTAINING_RECORD(NextEntry, COMPBATT_BATTERY_DATA, BatteryLink); + BatteryData->WaitStatus.LowCapacity = 0; + BatteryData->WaitStatus.HighCapacity = 0x7FFFFFFF; + NextEntry = NextEntry->Flink; + } + + /* Done */ + ExReleaseFastMutex(&DeviceExtension->Lock); + if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: EXITING DisableStatusNotify\n"); + return STATUS_SUCCESS; +} + +/** + * @brief + * Calculates the total discharging/charging rate flow of each individual + * battery linked with the composite battery and determines whether at + * least one battery is behaving improperly. + * + * @param[in] DeviceExtension + * A pointer to a device extension which describes the composite battery + * itself. It is used to gather each connected battery in the list with + * the composite battery. + * + * @param[out] TotalRate + * A pointer returned to caller that describes the total accumulated + * rate flow of all batteries. + * + * @param[out] BatteriesCount + * A pointer returned to caller that describes the batteries present. + * + * @return + * Returns TRUE if at least one battery is behaving improperly, FALSE + * otherwise. This is determined by the fact if a battery has a negative + * rate but is charging, or if it has a positive rate but is discharging. + */ +static +BOOLEAN +CompBattCalculateTotalRateAndLinkedBatteries( + _In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension, + _Out_ PULONG TotalRate, + _Out_ PULONG BatteriesCount) +{ + PCOMPBATT_BATTERY_DATA BatteryData; + PLIST_ENTRY ListHead, NextEntry; + BOOLEAN BadBattery = FALSE; + ULONG LinkedBatteries = 0; + ULONG BadBatteriesCount = 0; + ULONG ComputedRate = 0; + + /* Loop over the linked batteries and sum up the total capacity rate */ + ExAcquireFastMutex(&DeviceExtension->Lock); + ListHead = &DeviceExtension->BatteryList; + for (NextEntry = ListHead->Flink; + NextEntry != ListHead; + NextEntry = NextEntry->Flink) + { + /* Acquire the remove lock so this battery does not disappear under us */ + BatteryData = CONTAINING_RECORD(NextEntry, COMPBATT_BATTERY_DATA, BatteryLink); + if (!NT_SUCCESS(IoAcquireRemoveLock(&BatteryData->RemoveLock, BatteryData->Irp))) + continue; + + /* + * Ensure this battery has a valid tag and that its rate capacity + * is not unknown. Reject unknown rates when calculating the total rate. + */ + if ((BatteryData->Tag != BATTERY_TAG_INVALID) && + (BatteryData->BatteryStatus.Rate != BATTERY_UNKNOWN_RATE)) + { + /* + * Now the ultimate judgement for this battery is to determine + * if the battery behaves optimally based on its current power + * state it is and the rate flow of the battery. + * + * If the rate flow is positive the battery is receiving power + * which increases the chemical potential energy as electrons + * move around, THIS MEANS the battery is CHARGING. If the rate + * flow is negative the battery cells are producing way less + * electrical energy, thus the battery is DISCHARGING. + * + * A consistent battery is a battery of which power state matches + * the rate flow. If that were the case, then we have found a bad + * battery. The worst case is that a battery is physically damanged. + */ + if ((BatteryData->BatteryStatus.PowerState & BATTERY_DISCHARGING) && + (BatteryData->BatteryStatus.Rate >= 0)) + { + if (CompBattDebug & COMPBATT_DEBUG_WARN) + DbgPrint("CompBatt: The battery is discharging but in reality it is charging... (Rate %d)\n", + BatteryData->BatteryStatus.Rate); + + BadBattery = TRUE; + BadBatteriesCount++; + } + + if ((BatteryData->BatteryStatus.PowerState & BATTERY_CHARGING) && + (BatteryData->BatteryStatus.Rate <= 0)) + { + if (CompBattDebug & COMPBATT_DEBUG_WARN) + DbgPrint("CompBatt: The battery is charging but in reality it is discharging... (Rate %d)\n", + BatteryData->BatteryStatus.Rate); + + BadBattery = TRUE; + BadBatteriesCount++; + } + + if (((BatteryData->BatteryStatus.PowerState & (BATTERY_CHARGING | BATTERY_DISCHARGING)) == 0) && + (BatteryData->BatteryStatus.Rate != 0)) + { + if (CompBattDebug & COMPBATT_DEBUG_WARN) + DbgPrint("CompBatt: The battery is neither charging or discharging but has a contradicting rate... (Rate %d)\n", + BatteryData->BatteryStatus.Rate); + + BadBattery = TRUE; + BadBatteriesCount++; + } + + /* + * Sum up the rate of this battery to make up the total, even if that means + * the battery may have incosistent rate. This is because it is still a linked + * battery to the composite battery and it is used to power up the system nonetheless. + */ + ComputedRate += BatteryData->BatteryStatus.Rate; + } + + /* We are done with this individual battery */ + LinkedBatteries++; + IoReleaseRemoveLock(&BatteryData->RemoveLock, BatteryData->Irp); + } + + /* Release the lock as we are no longer poking through the batteries list */ + ExReleaseFastMutex(&DeviceExtension->Lock); + + /* Print out the total count of bad batteries we have found */ + if (BadBatteriesCount > 0) + { + if (CompBattDebug & COMPBATT_DEBUG_WARN) + DbgPrint("CompBatt: %lu bad batteries have been found!\n", BadBatteriesCount); + } + + *TotalRate = ComputedRate; + *BatteriesCount = LinkedBatteries; + return BadBattery; +} + +/** + * @brief + * Sets a new configuration battery wait status settings of each battery. + * The purpose of this is so that the composite battery gets notified + * of new battery status as if it was a single battery. + * + * @param[in] DeviceExtension + * A pointer to a device extension which describes the composite battery + * itself. It is used to gather each connected battery in the list with + * the composite battery. + * + * @param[in] BatteryTag + * A battery tag supplied by the caller. This is typically the tag of + * the composite battery which is used to check against the cached tag + * of the composite battery if it has changed or not. + * + * @param[in] BatteryNotify + * A pointer to a structure filled with battery notification settings, + * supplied by the caller. It is used as the new values for the + * configuration wait settings. + * + * @return + * Returns STATUS_NO_SUCH_DEVICE if the supplied battery tag does not match + * with that of the cached composite battery's tag or if the composite + * battery currently does not have a tag assigned. Otherwise STATUS_SUCCESS + * is returned. + */ +NTSTATUS +NTAPI +CompBattSetStatusNotify( + _In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension, + _In_ ULONG BatteryTag, + _In_ PBATTERY_NOTIFY BatteryNotify) +{ + NTSTATUS Status; + BOOLEAN BadBattery; + ULONG TotalRate; + ULONG BatteriesCount; + ULONG HighestCapacity; + ULONG LowCapDifference, HighCapDifference, LowDelta, HighDelta; + BATTERY_STATUS BatteryStatus; + PCOMPBATT_BATTERY_DATA BatteryData; + PLIST_ENTRY ListHead, NextEntry; + + /* + * The caller wants to set new status notification settings but the composite + * battery does not have a valid tag assigned, or the tag does not actually match. + */ + if (!(DeviceExtension->Flags & COMPBATT_TAG_ASSIGNED) || + (DeviceExtension->Tag != BatteryTag)) + { + if (CompBattDebug & COMPBATT_DEBUG_WARN) + DbgPrint("CompBatt: Composite battery tag not assigned or not matching (Tag -> %lu, Composite Tag -> %lu)\n", + BatteryTag, DeviceExtension->Tag); + + return STATUS_NO_SUCH_DEVICE; + } + + /* + * Before we are setting up new status wait notification points we need to + * refresh the composite status so that we get to know what values should be + * set for the current notification wait status. + */ + Status = CompBattQueryStatus(DeviceExtension, + BatteryTag, + &BatteryStatus); + if (!NT_SUCCESS(Status)) + { + if (CompBattDebug & COMPBATT_DEBUG_ERR) + DbgPrint("CompBatt: Failed to refresh composite battery's status (Status 0x%08lx)\n", Status); + + return Status; + } + + /* Print out battery status data that has been polled */ + if (CompBattDebug & COMPBATT_DEBUG_INFO) + DbgPrint("CompBatt: Latest composite battery status (when setting notify status)\n" + " PowerState -> 0x%lx\n" + " Capacity -> %u\n" + " Voltage -> %u\n" + " Rate -> %d\n", + BatteryStatus.PowerState, + BatteryStatus.Capacity, + BatteryStatus.Voltage, + BatteryStatus.Rate); + + /* Calculate the high and low capacity differences based on the real summed capacity of the composite */ + LowCapDifference = DeviceExtension->BatteryStatus.Capacity - BatteryNotify->LowCapacity; + HighCapDifference = BatteryNotify->HighCapacity - DeviceExtension->BatteryStatus.Capacity; + + /* Cache the notification parameters provided for later usage when polling for battery status */ + DeviceExtension->WaitNotifyStatus.PowerState = BatteryNotify->PowerState; + DeviceExtension->WaitNotifyStatus.LowCapacity = BatteryNotify->LowCapacity; + DeviceExtension->WaitNotifyStatus.HighCapacity = BatteryNotify->HighCapacity; + + /* Toggle the valid notify flag as these are the newer notification settings */ + DeviceExtension->Flags |= COMPBATT_STATUS_NOTIFY_SET; + + /* + * Get the number of currently linked batteries to composite and total rate, + * we will use these counters later to determine the wait values for each + * individual battery. + */ + BadBattery = CompBattCalculateTotalRateAndLinkedBatteries(DeviceExtension, + &TotalRate, + &BatteriesCount); + + /* + * Of course we have to be sure that we have at least one battery linked + * with the composite battery at this time of getting invoked to set new + * notification wait settings. + */ + ASSERT(BatteriesCount != 0); + + /* Walk over the linked batteries list and set up new wait configuration settings */ + ExAcquireFastMutex(&DeviceExtension->Lock); + ListHead = &DeviceExtension->BatteryList; + for (NextEntry = ListHead->Flink; + NextEntry != ListHead; + NextEntry = NextEntry->Flink) + { + /* Acquire the remove lock so this battery does not disappear under us */ + BatteryData = CONTAINING_RECORD(NextEntry, COMPBATT_BATTERY_DATA, BatteryLink); + if (!NT_SUCCESS(IoAcquireRemoveLock(&BatteryData->RemoveLock, BatteryData->Irp))) + continue; + + /* Now release the device lock since the battery can't go away */ + ExReleaseFastMutex(&DeviceExtension->Lock); + + /* Make sure this battery has a tag before setting new wait values */ + if (BatteryData->Tag != BATTERY_TAG_INVALID) + { + /* + * And also make sure this battery does not have an unknown + * capacity, we cannot set up new configuration wait settings + * based on that. Default the low and high wait capacities. + */ + if (BatteryData->BatteryStatus.Capacity != BATTERY_UNKNOWN_CAPACITY) + { + /* + * Calculate the low capacity wait setting. If at least one + * bad battery was found while we computed the total composite + * rate, then divide the difference between the total batteries. + * Otherwise compute the battery deltas of the composite based + * on total summed capacity rate. Otherwise if the total rate + * is 0, then the real wait low and high capacities will be on + * par with the real capacity. + */ + if (BadBattery) + { + LowDelta = LowCapDifference / BatteriesCount; + HighDelta = HighCapDifference / BatteriesCount; + } + else + { + if (TotalRate) + { + LowDelta = COMPUTE_BATT_CAP_DELTA(LowCapDifference, BatteryData, TotalRate); + HighDelta = COMPUTE_BATT_CAP_DELTA(HighCapDifference, BatteryData, TotalRate); + } + else + { + LowDelta = 0; + HighDelta = 0; + } + } + + /* + * Assign the wait low capacity setting ONLY if the battery delta + * is not high. Otherwise it has overflowed and we cannot use that + * for low capacity, of which we have to default it to 0. + */ + if (BatteryData->BatteryStatus.Capacity > LowDelta) + { + BatteryData->WaitStatus.LowCapacity = BatteryData->BatteryStatus.Capacity - LowDelta; + } + else + { + BatteryData->WaitStatus.LowCapacity = COMPBATT_WAIT_MIN_LOW_CAPACITY; + } + + /* + * Assign the wait high capacity setting ONLY if the real capacity + * is not above the maximum highest capacity constant. + */ + HighestCapacity = COMPBATT_WAIT_MAX_HIGH_CAPACITY - HighDelta; + if (HighestCapacity < BatteryData->BatteryStatus.Capacity) + { + BatteryData->WaitStatus.HighCapacity = HighestCapacity; + } + else + { + BatteryData->WaitStatus.HighCapacity = BatteryData->BatteryStatus.Capacity + HighDelta; + } + + /* + * We have set up the wait values but they are in conflict with the + * ones set up by the IRP complete worker. We have to cancel the IRP + * so the worker will copy our wait configuration values. + */ + if ((BatteryData->Mode == COMPBATT_READ_STATUS) && + (BatteryData->WaitStatus.PowerState != BatteryData->WorkerBuffer.WorkerWaitStatus.PowerState || + BatteryData->WaitStatus.LowCapacity != BatteryData->WorkerBuffer.WorkerWaitStatus.LowCapacity || + BatteryData->WaitStatus.HighCapacity != BatteryData->WorkerBuffer.WorkerWaitStatus.HighCapacity)) + { + if (CompBattDebug & COMPBATT_DEBUG_INFO) + DbgPrint("CompBatt: Configuration wait values are in conflict\n" + " BatteryData->WaitStatus.PowerState -> 0x%lx\n" + " BatteryData->WorkerBuffer.WorkerWaitStatus.PowerState -> 0x%lx\n" + " BatteryData->WaitStatus.LowCapacity -> %u\n" + " BatteryData->WorkerBuffer.WorkerWaitStatus.LowCapacity -> %u\n" + " BatteryData->WaitStatus.HighCapacity -> %u\n" + " BatteryData->WorkerBuffer.WorkerWaitStatus.HighCapacity -> %u\n", + BatteryData->WaitStatus.PowerState, + BatteryData->WorkerBuffer.WorkerWaitStatus.PowerState, + BatteryData->WaitStatus.LowCapacity, + BatteryData->WorkerBuffer.WorkerWaitStatus.LowCapacity, + BatteryData->WaitStatus.HighCapacity, + BatteryData->WorkerBuffer.WorkerWaitStatus.HighCapacity); + + IoCancelIrp(BatteryData->Irp); + } + } + else + { + BatteryData->WaitStatus.LowCapacity = BATTERY_UNKNOWN_CAPACITY; + BatteryData->WaitStatus.HighCapacity = BATTERY_UNKNOWN_CAPACITY; + } + } + + /* We are done with this battery */ + ExAcquireFastMutex(&DeviceExtension->Lock); + IoReleaseRemoveLock(&BatteryData->RemoveLock, BatteryData->Irp); + } + + /* Release the lock as we are no longer poking through the batteries list */ + ExReleaseFastMutex(&DeviceExtension->Lock); + + /* Ensure the composite battery did not incur in drastic changes of tag */ + if (!(DeviceExtension->Flags & COMPBATT_TAG_ASSIGNED) || + (DeviceExtension->Tag != BatteryTag)) + { + /* + * Either the last battery was removed (in this case the composite is no + * longer existing) or a battery was removed of which the whole battery + * information must be recomputed and such. + */ + if (CompBattDebug & COMPBATT_DEBUG_WARN) + DbgPrint("CompBatt: Last battery or a battery was removed, the whole composite data must be recomputed\n"); + + return STATUS_NO_SUCH_DEVICE; + } + + return STATUS_SUCCESS; +} + +/** + * @brief + * Queries the battery status of each individiual connected battery with + * the composite battery and combines all the retrieved data as one + * single battery status for the composite battery. + * + * @param[in] DeviceExtension + * A pointer to a device extension which describes the composite battery + * itself. It is used to gather each connected battery in the list with + * the composite battery. + * + * @param[in] Tag + * A battery tag supplied by the caller. This is typically the tag of + * the composite battery which is used to check against the cached tag + * of the composite battery if it has changed or not. + * + * @param[out] BatteryStatus + * A pointer to a battery status that contains the combined data, returned + * to the caller. It serves as the battery status for the composite battery. + * + * @return + * Returns STATUS_NO_SUCH_DEVICE if the supplied battery tag does not match + * with that of the cached composite battery's tag or if the composite + * battery currently does not have a tag assigned. Otherwise STATUS_SUCCESS + * is returned, which it will also return success if the composite battery's + * cached battery status is fresh which indicates it has already been computed. + */ +NTSTATUS +NTAPI +CompBattQueryStatus( + _In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension, + _In_ ULONG Tag, + _Out_ PBATTERY_STATUS BatteryStatus) +{ + PCOMPBATT_BATTERY_DATA BatteryData; + BATTERY_WAIT_STATUS Wait; + PLIST_ENTRY ListHead, NextEntry; + ULONGLONG LastReadTime, CurrentReadTime; + NTSTATUS Status = STATUS_SUCCESS; + + /* + * The caller wants to update the composite battery status but the composite + * itself does not have a valid tag assigned, or the tag does not actually match. + */ + if (!(DeviceExtension->Flags & COMPBATT_TAG_ASSIGNED) || + (DeviceExtension->Tag != Tag)) + { + if (CompBattDebug & COMPBATT_DEBUG_WARN) + DbgPrint("CompBatt: Composite battery tag not assigned or not matching (Tag -> %lu, Composite Tag -> %lu)\n", + Tag, DeviceExtension->Tag); + + return STATUS_NO_SUCH_DEVICE; + } + + /* Initialize the status and wait fields with zeros */ + RtlZeroMemory(BatteryStatus, sizeof(*BatteryStatus)); + RtlZeroMemory(&Wait, sizeof(Wait)); + + /* + * The battery status was already updated when the caller queried for new + * status. We do not need to update the status again for no reason. + * Just give them the data outright. + */ + CurrentReadTime = KeQueryInterruptTime(); + LastReadTime = CurrentReadTime - DeviceExtension->InterruptTime; + if (LastReadTime < COMPBATT_FRESH_STATUS_TIME) + { + if (CompBattDebug & COMPBATT_DEBUG_WARN) + DbgPrint("CompBatt: Composite battery status data is fresh, no need to update it again\n"); + + RtlCopyMemory(BatteryStatus, &DeviceExtension->BatteryStatus, sizeof(BATTERY_STATUS)); + return STATUS_SUCCESS; + } + + /* + * Initialize the battery status context with unknown defaults, until we get + * to retrieve the real data from each battery and compute the exact status. + * Assume the system is powered by AC source for now until we find out it is + * not the case. + */ + BatteryStatus->PowerState = BATTERY_POWER_ON_LINE; + BatteryStatus->Capacity = BATTERY_UNKNOWN_CAPACITY; + BatteryStatus->Voltage = BATTERY_UNKNOWN_VOLTAGE; + BatteryStatus->Rate = BATTERY_UNKNOWN_RATE; + + /* Iterate over all the present linked batteries and retrieve their status */ + ExAcquireFastMutex(&DeviceExtension->Lock); + ListHead = &DeviceExtension->BatteryList; + for (NextEntry = ListHead->Flink; + NextEntry != ListHead; + NextEntry = NextEntry->Flink) + { + /* Acquire the remove lock so this battery does not disappear under us */ + BatteryData = CONTAINING_RECORD(NextEntry, COMPBATT_BATTERY_DATA, BatteryLink); + if (!NT_SUCCESS(IoAcquireRemoveLock(&BatteryData->RemoveLock, BatteryData->Irp))) + continue; + + /* Now release the device lock since the battery can't go away */ + ExReleaseFastMutex(&DeviceExtension->Lock); + + /* Setup the battery tag for the status wait which is needed to send off the IOCTL */ + Wait.BatteryTag = BatteryData->Tag; + + /* Make sure this battery has a tag before we send off the IOCTL */ + if (BatteryData->Tag != BATTERY_TAG_INVALID) + { + /* Only query new battery status data if it is no longer fresh */ + LastReadTime = CurrentReadTime - BatteryData->InterruptTime; + if (LastReadTime > COMPBATT_FRESH_STATUS_TIME) + { + RtlZeroMemory(&BatteryData->BatteryStatus, + sizeof(BatteryData->BatteryStatus)); + Status = BatteryIoctl(IOCTL_BATTERY_QUERY_STATUS, + BatteryData->DeviceObject, + &Wait, + sizeof(Wait), + &BatteryData->BatteryStatus, + sizeof(BatteryData->BatteryStatus), + FALSE); + if (!NT_SUCCESS(Status)) + { + /* + * If the device is being suddenly removed then we must invalidate + * both this battery and composite tags. + */ + if (Status == STATUS_DEVICE_REMOVED) + { + Status = STATUS_NO_SUCH_DEVICE; + } + + ExAcquireFastMutex(&DeviceExtension->Lock); + IoReleaseRemoveLock(&BatteryData->RemoveLock, BatteryData->Irp); + break; + } + + /* Update the timestamp of the current read of battery status */ + BatteryData->InterruptTime = CurrentReadTime; + } + + /* + * Now it is time to combine the data into the composite status. + * The battery is either charging or discharging. AC is present + * only if the charger supplies current to all batteries. And + * the composite is deemed as critical if at least one battery + * is discharging and it is in crtitical state. + */ + BatteryStatus->PowerState |= (BatteryData->BatteryStatus.PowerState & (BATTERY_CHARGING | BATTERY_DISCHARGING)); + BatteryStatus->PowerState &= (BatteryData->BatteryStatus.PowerState | ~BATTERY_POWER_ON_LINE); + if ((BatteryData->BatteryStatus.PowerState & BATTERY_CRITICAL) && + (BatteryData->BatteryStatus.PowerState & BATTERY_DISCHARGING)) + { + BatteryStatus->PowerState |= BATTERY_CRITICAL; + } + + /* Add up the battery capacity if it is not unknown */ + if (BatteryData->BatteryStatus.Capacity != BATTERY_UNKNOWN_CAPACITY) + { + if (BatteryStatus->Capacity != BATTERY_UNKNOWN_CAPACITY) + { + BatteryStatus->Capacity += BatteryData->BatteryStatus.Capacity; + } + else + { + BatteryStatus->Capacity = BatteryData->BatteryStatus.Capacity; + } + } + + /* Always pick up the greatest voltage for the composite battery */ + if (BatteryData->BatteryStatus.Voltage != BATTERY_UNKNOWN_VOLTAGE) + { + if (BatteryStatus->Voltage != BATTERY_UNKNOWN_VOLTAGE) + { + BatteryStatus->Voltage = max(BatteryStatus->Voltage, + BatteryData->BatteryStatus.Voltage); + } + else + { + BatteryStatus->Voltage = BatteryData->BatteryStatus.Voltage; + } + } + + /* Add up the battery discharge rate if it is not unknown */ + if (BatteryData->BatteryStatus.Rate != BATTERY_UNKNOWN_RATE) + { + if (BatteryStatus->Rate != BATTERY_UNKNOWN_RATE) + { + BatteryStatus->Rate += BatteryData->BatteryStatus.Rate; + } + else + { + BatteryStatus->Rate = BatteryData->BatteryStatus.Rate; + } + } + } + + /* We are done combining data from this battery */ + ExAcquireFastMutex(&DeviceExtension->Lock); + IoReleaseRemoveLock(&BatteryData->RemoveLock, BatteryData->Irp); + } + + /* Release the lock as we are no longer poking through the batteries list */ + ExReleaseFastMutex(&DeviceExtension->Lock); + + /* Ensure the composite battery did not incur in drastic changes of tag */ + if (!(DeviceExtension->Flags & COMPBATT_TAG_ASSIGNED) || + (DeviceExtension->Tag != Tag)) + { + /* + * Either the last battery was removed (in this case the composite is no + * longer existing) or a battery was removed of which the whole battery + * information must be recomputed and such. + */ + if (CompBattDebug & COMPBATT_DEBUG_WARN) + DbgPrint("CompBatt: Last battery or a battery was removed, the whole composite data must be recomputed\n"); + + return STATUS_NO_SUCH_DEVICE; + } + + /* + * If there is a battery that is charging while another one discharging, + * then tell the caller the composite battery is actually discharging. + * This is less likely to happen on a multi-battery system like laptops + * as the charger would provide electricity to all the batteries. + * Perhaps the most likely case scenario would be if the system were + * to be powered by a UPS. + */ + if ((BatteryStatus->PowerState & BATTERY_CHARGING) && + (BatteryStatus->PowerState & BATTERY_DISCHARGING)) + { + BatteryStatus->PowerState &= ~BATTERY_CHARGING; + } + + /* Copy the combined status information to the composite battery */ + if (NT_SUCCESS(Status)) + { + RtlCopyMemory(&DeviceExtension->BatteryStatus, + BatteryStatus, + sizeof(DeviceExtension->BatteryStatus)); + + /* Update the last read battery status timestamp as well */ + DeviceExtension->InterruptTime = CurrentReadTime; + } + + return Status; +} + +NTSTATUS +NTAPI +CompBattGetBatteryInformation( + _Out_ PBATTERY_INFORMATION BatteryInfo, + _In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension) +{ + NTSTATUS Status = STATUS_SUCCESS; + BATTERY_QUERY_INFORMATION InputBuffer; + PCOMPBATT_BATTERY_DATA BatteryData; + PLIST_ENTRY ListHead, NextEntry; + if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: ENTERING GetBatteryInformation\n"); + + /* Set defaults */ + BatteryInfo->DefaultAlert1 = 0; + BatteryInfo->DefaultAlert2 = 0; + BatteryInfo->CriticalBias = 0; + + /* Loop the battery list */ + ExAcquireFastMutex(&DeviceExtension->Lock); + ListHead = &DeviceExtension->BatteryList; + NextEntry = ListHead->Flink; + while (NextEntry != ListHead) + { + /* Try to acquire the remove lock */ + BatteryData = CONTAINING_RECORD(NextEntry, COMPBATT_BATTERY_DATA, BatteryLink); + if (NT_SUCCESS(IoAcquireRemoveLock(&BatteryData->RemoveLock, BatteryData->Irp))) + { + /* Now release the device lock since the battery can't go away */ + ExReleaseFastMutex(&DeviceExtension->Lock); + + /* Build the query */ + InputBuffer.BatteryTag = BatteryData->Tag; + InputBuffer.InformationLevel = BatteryInformation; + InputBuffer.AtRate = 0; + + /* Make sure the battery has a tag */ + if (BatteryData->Tag != BATTERY_TAG_INVALID) + { + /* Do we already have the data? */ + if (!(BatteryData->Flags & COMPBATT_BATTERY_INFORMATION_PRESENT)) + { + /* Send the IOCTL to query the information */ + RtlZeroMemory(&BatteryData->BatteryInformation, + sizeof(BatteryData->BatteryInformation)); + Status = BatteryIoctl(IOCTL_BATTERY_QUERY_INFORMATION, + BatteryData->DeviceObject, + &InputBuffer, + sizeof(InputBuffer), + &BatteryData->BatteryInformation, + sizeof(BatteryData->BatteryInformation), + FALSE); + if (!NT_SUCCESS(Status)) + { + /* Fail if the query had a problem */ + if (Status == STATUS_DEVICE_REMOVED) Status = STATUS_NO_SUCH_DEVICE; + ExAcquireFastMutex(&DeviceExtension->Lock); + IoReleaseRemoveLock(&BatteryData->RemoveLock, BatteryData->Irp); + break; + } + + /* Next time we can use the static copy */ + BatteryData->Flags |= COMPBATT_BATTERY_INFORMATION_PRESENT; + if (CompBattDebug & COMPBATT_DEBUG_INFO) + DbgPrint("CompBattGetBatteryInformation: Read individual BATTERY_INFORMATION\n" + "-------- Capabilities = %x\n-------- Technology = %x\n" + "-------- Chemistry[4] = %x\n-------- DesignedCapacity = %x\n" + "-------- FullChargedCapacity = %x\n-------- DefaultAlert1 = %x\n" + "-------- DefaultAlert2 = %x\n-------- CriticalBias = %x\n" + "-------- CycleCount = %x\n", + BatteryData->BatteryInformation.Capabilities, + BatteryData->BatteryInformation.Technology, + BatteryData->BatteryInformation.Chemistry, + BatteryData->BatteryInformation.DesignedCapacity, + BatteryData->BatteryInformation.FullChargedCapacity, + BatteryData->BatteryInformation.DefaultAlert1, + BatteryData->BatteryInformation.DefaultAlert2, + BatteryData->BatteryInformation.CriticalBias, + BatteryData->BatteryInformation.CycleCount); + } + + /* Combine capabilities */ + BatteryInfo->Capabilities |= BatteryData->BatteryInformation.Capabilities; + + /* Add-on capacity */ + if (BatteryData->BatteryInformation.DesignedCapacity != BATTERY_UNKNOWN_CAPACITY) + { + BatteryInfo->DesignedCapacity += BatteryData->BatteryInformation.DesignedCapacity; + } + + /* Add on fully charged capacity */ + if (BatteryData->BatteryInformation.FullChargedCapacity != BATTERY_UNKNOWN_CAPACITY) + { + BatteryInfo->FullChargedCapacity += BatteryData->BatteryInformation.FullChargedCapacity; + } + + /* Choose the highest alert */ + BatteryInfo->DefaultAlert1 = max(BatteryInfo->DefaultAlert1, + BatteryData->BatteryInformation.DefaultAlert1); + + /* Choose the highest alert */ + BatteryInfo->DefaultAlert2 = max(BatteryInfo->DefaultAlert2, + BatteryData->BatteryInformation.DefaultAlert2); + + /* Choose the highest critical bias */ + BatteryInfo->CriticalBias = max(BatteryInfo->CriticalBias, + BatteryData->BatteryInformation.CriticalBias); + } + + /* Re-acquire the device extension lock and release the remove lock */ + ExAcquireFastMutex(&DeviceExtension->Lock); + IoReleaseRemoveLock(&BatteryData->RemoveLock, BatteryData->Irp); + } + + /* Next entry */ + NextEntry = NextEntry->Flink; + } + + /* We are done with the list, check if the information was queried okay */ + ExReleaseFastMutex(&DeviceExtension->Lock); + if (NT_SUCCESS(Status)) + { + /* If there's no fully charged capacity, use the design capacity */ + if (!BatteryInfo->FullChargedCapacity) + { + BatteryInfo->FullChargedCapacity = BatteryInfo->DesignedCapacity; + } + + /* Print out final combined data */ + if (CompBattDebug & COMPBATT_DEBUG_INFO) + DbgPrint("CompBattGetBatteryInformation: Returning BATTERY_INFORMATION\n" + "-------- Capabilities = %x\n-------- Technology = %x\n" + "-------- Chemistry[4] = %x\n-------- DesignedCapacity = %x\n" + "-------- FullChargedCapacity = %x\n-------- DefaultAlert1 = %x\n" + "-------- DefaultAlert2 = %x\n-------- CriticalBias = %x\n" + "-------- CycleCount = %x\n", + BatteryInfo->Capabilities, + BatteryInfo->Technology, + BatteryInfo->Chemistry, + BatteryInfo->DesignedCapacity, + BatteryInfo->FullChargedCapacity, + BatteryInfo->DefaultAlert1, + BatteryInfo->DefaultAlert2, + BatteryInfo->CriticalBias, + BatteryInfo->CycleCount); + + /* Copy the data into the device extension */ + RtlCopyMemory(&DeviceExtension->BatteryInformation, + BatteryInfo, + sizeof(DeviceExtension->BatteryInformation)); + DeviceExtension->Flags |= COMPBATT_BATTERY_INFORMATION_PRESENT; + } + + /* We are done */ + if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: EXITING GetBatteryInformation\n"); + return Status; +} + +NTSTATUS +NTAPI +CompBattGetBatteryGranularity( + _Out_ PBATTERY_REPORTING_SCALE ReportingScale, + _In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension) +{ + NTSTATUS Status = STATUS_SUCCESS; + BATTERY_QUERY_INFORMATION InputBuffer; + PCOMPBATT_BATTERY_DATA BatteryData; + BATTERY_REPORTING_SCALE BatteryScale[4]; + PLIST_ENTRY ListHead, NextEntry; + ULONG i; + if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: ENTERING GetBatteryGranularity\n"); + + /* Set defaults */ + ReportingScale[0].Granularity = -1; + ReportingScale[1].Granularity = -1; + ReportingScale[2].Granularity = -1; + ReportingScale[3].Granularity = -1; + + /* Loop the battery list */ + ExAcquireFastMutex(&DeviceExtension->Lock); + ListHead = &DeviceExtension->BatteryList; + NextEntry = ListHead->Flink; + while (NextEntry != ListHead) + { + /* Try to acquire the remove lock */ + BatteryData = CONTAINING_RECORD(NextEntry, COMPBATT_BATTERY_DATA, BatteryLink); + if (NT_SUCCESS(IoAcquireRemoveLock(&BatteryData->RemoveLock, BatteryData->Irp))) + { + /* Now release the device lock since the battery can't go away */ + ExReleaseFastMutex(&DeviceExtension->Lock); + + /* Build the query */ + InputBuffer.BatteryTag = BatteryData->Tag; + InputBuffer.InformationLevel = BatteryGranularityInformation; + + /* Make sure the battery has a tag */ + if (BatteryData->Tag != BATTERY_TAG_INVALID) + { + /* Send the IOCTL to query the information */ + RtlZeroMemory(&BatteryData->BatteryInformation, + sizeof(BatteryData->BatteryInformation)); + Status = BatteryIoctl(IOCTL_BATTERY_QUERY_INFORMATION, + BatteryData->DeviceObject, + &InputBuffer, + sizeof(InputBuffer), + &BatteryScale, + sizeof(BatteryScale), + FALSE); + if (!NT_SUCCESS(Status)) + { + /* Fail if the query had a problem */ + ExAcquireFastMutex(&DeviceExtension->Lock); + IoReleaseRemoveLock(&BatteryData->RemoveLock, BatteryData->Irp); + break; + } + + /* Loop all 4 scales */ + for (i = 0; i < 4; i++) + { + /* Check for valid granularity */ + if (BatteryScale[i].Granularity) + { + /* If it's smaller, use it instead */ + ReportingScale[i].Granularity = min(BatteryScale[i].Granularity, + ReportingScale[i].Granularity); + } + + } + } + + /* Re-acquire the device extension lock and release the remove lock */ + ExAcquireFastMutex(&DeviceExtension->Lock); + IoReleaseRemoveLock(&BatteryData->RemoveLock, BatteryData->Irp); + } + + /* Next entry */ + NextEntry = NextEntry->Flink; + } + + /* All done */ + ExReleaseFastMutex(&DeviceExtension->Lock); + if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: EXITING GetBatteryGranularity\n"); + return STATUS_SUCCESS; +} + +/** + * @brief + * Calculates the "At Rate" flow of the composite battery based on the + * sum of all connected batteries, in order to retrieve the precise + * battery time estimation. + * + * @param[in] DeviceExtension + * A pointer to a device extension which describes the composite battery + * itself. It is used to gather each connected battery in the list with + * the composite battery. + * + * @return + * Returns the computed "At Rate" flow to the caller. + */ +static +LONG +CompBattCalculateAtRateTime( + _In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension) +{ + NTSTATUS Status; + PCOMPBATT_BATTERY_DATA BatteryData; + BATTERY_QUERY_INFORMATION QueryInformation; + PLIST_ENTRY ListHead, NextEntry; + ULONG Time; + LONG ComputedAtRate = 0; + + /* Walk over the linked batteries list to poll for "At Rate" value of each battery */ + ExAcquireFastMutex(&DeviceExtension->Lock); + ListHead = &DeviceExtension->BatteryList; + for (NextEntry = ListHead->Flink; + NextEntry != ListHead; + NextEntry = NextEntry->Flink) + { + /* Acquire the remove lock so this battery does not disappear under us */ + BatteryData = CONTAINING_RECORD(NextEntry, COMPBATT_BATTERY_DATA, BatteryLink); + if (!NT_SUCCESS(IoAcquireRemoveLock(&BatteryData->RemoveLock, BatteryData->Irp))) + continue; + + /* Now release the device lock since the battery can't go away */ + ExReleaseFastMutex(&DeviceExtension->Lock); + + /* Build the necessary information in order to query the battery estimated time */ + QueryInformation.BatteryTag = BatteryData->Tag; + QueryInformation.InformationLevel = BatteryEstimatedTime; + QueryInformation.AtRate = 0; + + /* Make sure this battery has a valid tag before issuing the IOCTL */ + if (BatteryData->Tag != BATTERY_TAG_INVALID) + { + /* + * Now it is time to issue the IOCTL to the battery device. + * We are calculating the "At Rate" counter based on each linked + * battery that is discharging, one at a time. This ensures + * that when we will actually retrieve the estimation time of each + * individual battery and sum it all up as one time for the composite + * battery, that the estimated time is accurate enough. + */ + Status = BatteryIoctl(IOCTL_BATTERY_QUERY_INFORMATION, + BatteryData->DeviceObject, + &QueryInformation, + sizeof(QueryInformation), + &Time, + sizeof(Time), + FALSE); + if (NT_SUCCESS(Status)) + { + if ((Time != 0) && (Time != BATTERY_UNKNOWN_TIME)) + { + ComputedAtRate -= COMPUTE_ATRATE_DRAIN(BatteryData, Time); + } + } + } + + /* We are done with this battery */ + ExAcquireFastMutex(&DeviceExtension->Lock); + IoReleaseRemoveLock(&BatteryData->RemoveLock, BatteryData->Irp); + } + + /* Release the lock as we are no longer poking through the batteries list */ + ExReleaseFastMutex(&DeviceExtension->Lock); + return ComputedAtRate; +} + +/** + * @brief + * Retrieves the estimated time of the composite battery based on the + * power drain rate of all the batteries present in the system. + * + * @param[out] Time + * A pointer to the computed estimated time of the composite battery, + * returned to caller. Note that if there are not any batteries that + * are draining power, or if the system is powered by external AC source, + * the estimated time is unknown + * + * @param[in] DeviceExtension + * A pointer to a device extension which describes the composite battery + * itself. It is used to gather each connected battery in the list with + * the composite battery. + * + * @return + * Returns STATUS_NO_SUCH_DEVICE if the supplied battery tag does not match + * with that of the cached composite battery's tag or if the composite + * battery currently does not have a tag assigned. Otherwise STATUS_SUCCESS + * is returned. + */ +NTSTATUS +NTAPI +CompBattGetEstimatedTime( + _Out_ PULONG Time, + _In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension) +{ + NTSTATUS Status; + PCOMPBATT_BATTERY_DATA BatteryData; + BATTERY_STATUS BatteryStatus; + BATTERY_QUERY_INFORMATION QueryInformation; + PLIST_ENTRY ListHead, NextEntry; + ULONG ReturnedTime; + LONG ComputedAtRate; + + /* Assume the battery time is not estimated yet */ + *Time = BATTERY_UNKNOWN_TIME; + + /* + * Before we are querying the composite estimated battery time we must + * refresh the battery status cache if we have not done it so. + */ + Status = CompBattQueryStatus(DeviceExtension, + DeviceExtension->Tag, + &BatteryStatus); + if (!NT_SUCCESS(Status)) + { + if (CompBattDebug & COMPBATT_DEBUG_ERR) + DbgPrint("CompBatt: Failed to refresh composite battery's status (Status 0x%08lx)\n", Status); + + return Status; + } + + /* Print out battery status data that has been polled */ + if (CompBattDebug & COMPBATT_DEBUG_INFO) + DbgPrint("CompBatt: Latest composite battery status (when querying for estimated time)\n" + " PowerState -> 0x%lx\n" + " Capacity -> %u\n" + " Voltage -> %u\n" + " Rate -> %d\n", + BatteryStatus.PowerState, + BatteryStatus.Capacity, + BatteryStatus.Voltage, + BatteryStatus.Rate); + + /* + * If the batteries are not being discharged and the system is directly + * being powered by external AC source then it makes no sense to + * compute the battery estimated time because that construct is for + * WHEN the system is powered directly from batteries and it drains power. + */ + if (DeviceExtension->BatteryStatus.PowerState & BATTERY_POWER_ON_LINE) + { + if (CompBattDebug & COMPBATT_DEBUG_WARN) + { + DbgPrint("CompBatt: The system is powered by AC source, estimated time is not available\n"); + } + + return STATUS_SUCCESS; + } + + /* Determine the draining "At Rate" counter for all batteries */ + ComputedAtRate = CompBattCalculateAtRateTime(DeviceExtension); + + /* + * A rate of 0 indicates none of the batteries that are linked with + * the composite are being drained therefore we cannot estimate the + * run time of the composite as it is not discharging. + */ + if (ComputedAtRate == 0) + { + if (CompBattDebug & COMPBATT_DEBUG_WARN) + DbgPrint("CompBatt: No battery is discharging and no power is being drained, cannot estimate the run time\n"); + + return STATUS_SUCCESS; + } + + /* Walk over the linked batteries list and determine the exact estimated time */ + ExAcquireFastMutex(&DeviceExtension->Lock); + ListHead = &DeviceExtension->BatteryList; + for (NextEntry = ListHead->Flink; + NextEntry != ListHead; + NextEntry = NextEntry->Flink) + { + /* Acquire the remove lock so this battery does not disappear under us */ + BatteryData = CONTAINING_RECORD(NextEntry, COMPBATT_BATTERY_DATA, BatteryLink); + if (!NT_SUCCESS(IoAcquireRemoveLock(&BatteryData->RemoveLock, BatteryData->Irp))) + continue; + + /* Now release the device lock since the battery can't go away */ + ExReleaseFastMutex(&DeviceExtension->Lock); + + /* Build the necessary information in order to query the battery estimated time */ + QueryInformation.BatteryTag = BatteryData->Tag; + QueryInformation.InformationLevel = BatteryEstimatedTime; + QueryInformation.AtRate = ComputedAtRate; + + /* Make sure this battery has a valid tag before issuing the IOCTL */ + if (BatteryData->Tag != BATTERY_TAG_INVALID) + { + Status = BatteryIoctl(IOCTL_BATTERY_QUERY_INFORMATION, + BatteryData->DeviceObject, + &QueryInformation, + sizeof(QueryInformation), + &ReturnedTime, + sizeof(ReturnedTime), + FALSE); + if (!NT_SUCCESS(Status)) + { + /* + * If the device is being suddenly removed then we must invalidate + * both this battery and composite tags. + */ + if (Status == STATUS_DEVICE_REMOVED) + { + Status = STATUS_NO_SUCH_DEVICE; + } + + ExAcquireFastMutex(&DeviceExtension->Lock); + IoReleaseRemoveLock(&BatteryData->RemoveLock, BatteryData->Irp); + + /* + * In other places we are ceasing the execution of the loop but + * here we want to continue looking for other linked batteries. + * This is because we are querying for the estimated battery time + * at the time the last battery status was valid. Also bear in + * mind IOCTL_BATTERY_QUERY_INFORMATION with InformationLevel as + * BatteryEstimatedTime might not be a valid request supported + * by this battery. + */ + continue; + } + + /* Now sum up the estimated battery time */ + if (ReturnedTime != BATTERY_UNKNOWN_TIME) + { + if (*Time != BATTERY_UNKNOWN_TIME) + { + *Time += ReturnedTime; + } + else + { + *Time = ReturnedTime; + } + } + } + + /* We are done with this battery */ + ExAcquireFastMutex(&DeviceExtension->Lock); + IoReleaseRemoveLock(&BatteryData->RemoveLock, BatteryData->Irp); + } + + /* Release the lock as we are no longer poking through the batteries list */ + ExReleaseFastMutex(&DeviceExtension->Lock); + return Status; +} + +NTSTATUS +NTAPI +CompBattQueryInformation( + _In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension, + _In_ ULONG Tag, + _In_ BATTERY_QUERY_INFORMATION_LEVEL InfoLevel, + _In_opt_ LONG AtRate, + _In_ PVOID Buffer, + _In_ ULONG BufferLength, + _Out_ PULONG ReturnedLength) +{ + BATTERY_INFORMATION BatteryInfo; + BATTERY_REPORTING_SCALE BatteryGranularity[4]; + PWCHAR BatteryName = L"Composite Battery"; + //BATTERY_MANUFACTURE_DATE Date; + ULONG Dummy, Time; + PVOID QueryData = NULL; + ULONG QueryLength = 0; + NTSTATUS Status = STATUS_SUCCESS; + PAGED_CODE(); + if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: ENTERING QueryInformation\n"); + + /* Check for valid/correct tag */ + if ((Tag != DeviceExtension->Tag) || + (!(DeviceExtension->Flags & COMPBATT_TAG_ASSIGNED))) + { + /* Not right, so fail */ + return STATUS_NO_SUCH_DEVICE; + } + + /* Check what caller wants */ + switch (InfoLevel) + { + case BatteryInformation: + + /* Query combined battery information */ + RtlZeroMemory(&BatteryInfo, sizeof(BatteryInfo)); + Status = CompBattGetBatteryInformation(&BatteryInfo, DeviceExtension); + if (NT_SUCCESS(Status)) + { + /* Return the data if successful */ + QueryData = &BatteryInfo; + QueryLength = sizeof(BatteryInfo); + } + break; + + case BatteryGranularityInformation: + + /* Query combined granularity information */ + RtlZeroMemory(&BatteryGranularity, sizeof(BatteryGranularity)); + Status = CompBattGetBatteryGranularity(BatteryGranularity, DeviceExtension); + if (NT_SUCCESS(Status)) + { + /* Return the data if successful */ + QueryLength = sizeof(BatteryGranularity); + QueryData = &BatteryGranularity; + } + break; + + case BatteryEstimatedTime: + + /* Query combined time estimate information */ + RtlZeroMemory(&Time, sizeof(Time)); + Status = CompBattGetEstimatedTime(&Time, DeviceExtension); + if (NT_SUCCESS(Status)) + { + /* Return the data if successful */ + QueryLength = sizeof(Time); + QueryData = &Time; + } + break; + + case BatteryManufactureName: + case BatteryDeviceName: + + /* Return the static buffer */ + QueryData = BatteryName; + QueryLength = sizeof(L"Composite Battery"); + break; + + case BatteryManufactureDate: + + /* Static data */ + //Date.Day = 26; + //Date.Month = 06; + //Date.Year = 1997; + break; + + case BatteryTemperature: + case BatteryUniqueID: + + /* Return zero */ + Dummy = 0; + QueryData = &Dummy; + QueryLength = sizeof(Dummy); + break; + + default: + /* Everything else is unknown */ + Status = STATUS_INVALID_PARAMETER; + break; + } + + /* Return the required length and check if the caller supplied enough */ + *ReturnedLength = QueryLength; + if (BufferLength < QueryLength) Status = STATUS_BUFFER_TOO_SMALL; + + /* Copy the data if there's enough space and it exists */ + if ((NT_SUCCESS(Status)) && (QueryData)) RtlCopyMemory(Buffer, QueryData, QueryLength); + + /* Return function result */ + if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: EXITING QueryInformation\n"); + return Status; +} + +NTSTATUS +NTAPI +DriverEntry( + _In_ PDRIVER_OBJECT DriverObject, + _In_ PUNICODE_STRING RegistryPath) +{ + /* Register add device routine */ + DriverObject->DriverExtension->AddDevice = CompBattAddDevice; + + /* Register other handlers */ + DriverObject->MajorFunction[IRP_MJ_CREATE] = CompBattOpenClose; + DriverObject->MajorFunction[IRP_MJ_CLOSE] = CompBattOpenClose; + DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = CompBattIoctl; + DriverObject->MajorFunction[IRP_MJ_POWER] = CompBattPowerDispatch; + DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = CompBattSystemControl; + DriverObject->MajorFunction[IRP_MJ_PNP] = CompBattPnpDispatch; + return STATUS_SUCCESS; +} + +/* EOF */ diff --git a/drivers/battery/compbatt/compbatt.h b/drivers/battery/compbatt/compbatt.h new file mode 100644 index 0000000000000..58f812c5fd7b6 --- /dev/null +++ b/drivers/battery/compbatt/compbatt.h @@ -0,0 +1,329 @@ +/* + * PROJECT: ReactOS Composite Battery Driver + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: Composite battery main header file + * COPYRIGHT: Copyright 2010 ReactOS Portable Systems Group + * Copyright 2024 George Bișoc + */ + +/* INCLUDES *******************************************************************/ + +#ifndef _COMPBATT_PCH_ +#define _COMPBATT_PCH_ + +#include +#include + +/* DEFINES ********************************************************************/ + +// +// I/O remove lock allocate tag +// +#define COMPBATT_TAG 'aBoC' + +// +// Composite battery flags +// +#define COMPBATT_BATTERY_INFORMATION_PRESENT 0x04 +#define COMPBATT_STATUS_NOTIFY_SET 0x10 +#define COMPBATT_TAG_ASSIGNED 0x80 + +// +// IRP complete worker mode states +// +#define COMPBATT_QUERY_TAG 1 +#define COMPBATT_READ_STATUS 2 + +// +// Low/High capacity wait constants +// +#define COMPBATT_WAIT_MIN_LOW_CAPACITY 0 +#define COMPBATT_WAIT_MAX_HIGH_CAPACITY 0x7FFFFFFF + +// +// One hour in seconds, used to calculate the total rate of each battery for time estimation +// +#define COMPBATT_ATRATE_HOUR_IN_SECS 3600 + +// +// Time constant of which the battery status data is considered fresh (50000000 * 100ns == 5s) +// +#define COMPBATT_FRESH_STATUS_TIME 50000000 + +// +// Macro that calculates the delta of a battery's capacity +// +#define COMPUTE_BATT_CAP_DELTA(LowDiff, Batt, TotalRate) \ + ((ULONG)(((LONGLONG)LowDiff * (Batt)->BatteryStatus.Rate) / TotalRate)) + +// +// Macro that calculates the "At Rate" time drain of the battery +// +#define COMPUTE_ATRATE_DRAIN(Batt, Time) \ + ((LONG)((Batt)->BatteryStatus.Capacity) * COMPBATT_ATRATE_HOUR_IN_SECS / Time) + +// +// Composite battery debug levels +// +#define COMPBATT_DEBUG_INFO 0x1 +#define COMPBATT_DEBUG_TRACE 0x2 +#define COMPBATT_DEBUG_WARN 0x4 +#define COMPBATT_DEBUG_ERR 0x10 +#define COMPBATT_DEBUG_ALL_LEVELS (COMPBATT_DEBUG_INFO | COMPBATT_DEBUG_TRACE | COMPBATT_DEBUG_WARN | COMPBATT_DEBUG_ERR) + +/* STRUCTURES *****************************************************************/ + +// +// Individual ACPI battery data +// +typedef struct _COMPBATT_BATTERY_DATA +{ + /* The linked battery with the Composite Battery */ + LIST_ENTRY BatteryLink; + + /* I/O remove lock which protects the battery from being removed */ + IO_REMOVE_LOCK RemoveLock; + + /* + * The associated device object (usually CMBATT) and the I/O battery packet + * which is used to transport and gather battery data. + */ + PDEVICE_OBJECT DeviceObject; + PIRP Irp; + + /* + * The Executive work item, which serves as a worker item for the + * IRP battery monitor worker. + */ + WORK_QUEUE_ITEM WorkItem; + + /* + * Execution state mode of the individual battery. Only two modes are valid: + * + * COMPBATT_QUERY_TAG - The battery is currently waiting for a tag to get assigned; + * COMPBATT_READ_STATUS - The battery is querying battery status. + */ + UCHAR Mode; + + /* + * The battery wait configuration settings, set up by the SetStatusNotify method. + * These values are used to instruct CMBATT when the battery status should be retrieved. + */ + BATTERY_WAIT_STATUS WaitStatus; + + /* + * A union that serves as the buffer which holds battery monitor IRP data, specifically + * managed by CompBattMonitorIrpCompleteWorker, to avoid allocating separate memory pools. + */ + union + { + BATTERY_WAIT_STATUS WorkerWaitStatus; + BATTERY_STATUS WorkerStatus; + ULONG WorkerTag; + } WorkerBuffer; + + /* The ID of the battery that associates the identification of this battery */ + ULONG Tag; + + /* + * The battery flags that govern the behavior of the battery. The valid flags are: + * + * COMPBATT_BATTERY_INFORMATION_PRESENT - The static battery information ha been + * queried. Re-querying such information is not needed. + * + * COMPBATT_STATUS_NOTIFY_SET - The current notification wait settings are valid. + * + * COMPBATT_TAG_ASSIGNED - The battery has a tag assigned and it can be read. + */ + ULONG Flags; + + /* The static battery information and battery status */ + BATTERY_INFORMATION BatteryInformation; + BATTERY_STATUS BatteryStatus; + + /* The interrupt time of which the battery status was last read */ + ULONGLONG InterruptTime; + + /* A uniquely given name of the battery that associates it */ + UNICODE_STRING BatteryName; +} COMPBATT_BATTERY_DATA, *PCOMPBATT_BATTERY_DATA; + +// +// Composite battery device extension data +// +typedef struct _COMPBATT_DEVICE_EXTENSION +{ + /* + * The class data initialized and used by Battery Class. It contains information + * such as miniport data used for registration and communication between the + * Composite Battery and Battery Class, wait and context events, etc. + */ + PVOID ClassData; + + /* + * The successor computed tag. This field is used when there are more upcoming + * batteries to be connected with the Composite Battery, of which the tag is + * incremented by 1 by each new battery that is connected. + */ + ULONG NextTag; + + /* A list of linked batteries connected with the Composite Battery */ + LIST_ENTRY BatteryList; + + /* A mutex lock which ensures proper synchronization of Composite Battery operations */ + FAST_MUTEX Lock; + + /* The ID of the Composite Battery */ + ULONG Tag; + + /* + * The battery flags that govern the behavior of the battery. The valid flags are: + * + * COMPBATT_BATTERY_INFORMATION_PRESENT - The static battery information has been + * queried. Re-querying such information is not needed. + * + * COMPBATT_STATUS_NOTIFY_SET - The current notification wait settings are valid. + * + * COMPBATT_TAG_ASSIGNED - The battery has a tag assigned and it can be read. + */ + ULONG Flags; + + /* + * The Composite Battery static information, status and wait status settings. + * Note that both the battery information and status are combined, based upon + * the individual information and status of each linked battery. + */ + BATTERY_INFORMATION BatteryInformation; + BATTERY_STATUS BatteryStatus; + BATTERY_WAIT_STATUS WaitNotifyStatus; + + /* The interrupt time of which the battery status was last read */ + ULONGLONG InterruptTime; + + /* + * The physical device object that associates the Composite Battery and + * the attached device, typically the ACPI driver. + */ + PDEVICE_OBJECT AttachedDevice; + PDEVICE_OBJECT DeviceObject; + + /* The notification entry that identifies the registered I/O PnP notification */ + PVOID NotificationEntry; +} COMPBATT_DEVICE_EXTENSION, *PCOMPBATT_DEVICE_EXTENSION; + +/* PROTOTYPES *****************************************************************/ + +NTSTATUS +NTAPI +CompBattAddDevice( + _In_ PDRIVER_OBJECT DriverObject, + _In_ PDEVICE_OBJECT PdoDeviceObject +); + +NTSTATUS +NTAPI +CompBattPowerDispatch( + _In_ PDEVICE_OBJECT DeviceObject, + _In_ PIRP Irp +); + +NTSTATUS +NTAPI +CompBattPnpDispatch( + _In_ PDEVICE_OBJECT DeviceObject, + _In_ PIRP Irp +); + +NTSTATUS +NTAPI +CompBattQueryInformation( + _In_ PCOMPBATT_DEVICE_EXTENSION FdoExtension, + _In_ ULONG Tag, + _In_ BATTERY_QUERY_INFORMATION_LEVEL InfoLevel, + _In_opt_ LONG AtRate, + _In_ PVOID Buffer, + _In_ ULONG BufferLength, + _Out_ PULONG ReturnedLength +); + +NTSTATUS +NTAPI +CompBattQueryStatus( + _In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension, + _In_ ULONG Tag, + _Out_ PBATTERY_STATUS BatteryStatus +); + +NTSTATUS +NTAPI +CompBattGetEstimatedTime( + _Out_ PULONG Time, + _In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension +); + +NTSTATUS +NTAPI +CompBattSetStatusNotify( + _In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension, + _In_ ULONG BatteryTag, + _In_ PBATTERY_NOTIFY BatteryNotify +); + +NTSTATUS +NTAPI +CompBattDisableStatusNotify( + _In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension +); + +NTSTATUS +NTAPI +CompBattQueryTag( + _In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension, + _Out_ PULONG Tag +); + +NTSTATUS +NTAPI +CompBattMonitorIrpComplete( + _In_ PDEVICE_OBJECT DeviceObject, + _In_ PIRP Irp, + _In_ PVOID Context +); + +VOID +NTAPI +CompBattMonitorIrpCompleteWorker( + _In_ PCOMPBATT_BATTERY_DATA BatteryData +); + +NTSTATUS +NTAPI +CompBattGetDeviceObjectPointer( + _In_ PUNICODE_STRING DeviceName, + _In_ ACCESS_MASK DesiredAccess, + _Out_ PFILE_OBJECT *FileObject, + _Out_ PDEVICE_OBJECT *DeviceObject +); + +NTSTATUS +NTAPI +BatteryIoctl( + _In_ ULONG IoControlCode, + _In_ PDEVICE_OBJECT DeviceObject, + _In_ PVOID InputBuffer, + _In_ ULONG InputBufferLength, + _Out_ PVOID OutputBuffer, + _Inout_ ULONG OutputBufferLength, + _In_ BOOLEAN InternalDeviceIoControl +); + +NTSTATUS +NTAPI +CompBattRemoveBattery( + _In_ PUNICODE_STRING BatteryName, + _In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension +); + +extern ULONG CompBattDebug; + +#endif /* _COMPBATT_PCH_ */ diff --git a/drivers/bus/acpi/compbatt/compbatt.rc b/drivers/battery/compbatt/compbatt.rc similarity index 100% rename from drivers/bus/acpi/compbatt/compbatt.rc rename to drivers/battery/compbatt/compbatt.rc diff --git a/drivers/bus/acpi/compbatt/compmisc.c b/drivers/battery/compbatt/compmisc.c similarity index 73% rename from drivers/bus/acpi/compbatt/compmisc.c rename to drivers/battery/compbatt/compmisc.c index e84a25127060f..6a6cec14056c7 100644 --- a/drivers/bus/acpi/compbatt/compmisc.c +++ b/drivers/battery/compbatt/compmisc.c @@ -1,9 +1,8 @@ /* - * PROJECT: ReactOS Composite Battery Driver - * LICENSE: BSD - See COPYING.ARM in the top level directory - * FILE: boot/drivers/bus/acpi/compbatt/compmisc.c - * PURPOSE: Miscellaneous Support Routines - * PROGRAMMERS: ReactOS Portable Systems Group + * PROJECT: ReactOS Composite Battery Driver + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: Miscellaneous Support Routines + * COPYRIGHT: Copyright 2010 ReactOS Portable Systems Group */ /* INCLUDES *******************************************************************/ @@ -14,20 +13,21 @@ NTSTATUS NTAPI -BatteryIoctl(IN ULONG IoControlCode, - IN PDEVICE_OBJECT DeviceObject, - IN PVOID InputBuffer, - IN ULONG InputBufferLength, - IN PVOID OutputBuffer, - IN ULONG OutputBufferLength, - IN BOOLEAN InternalDeviceIoControl) +BatteryIoctl( + _In_ ULONG IoControlCode, + _In_ PDEVICE_OBJECT DeviceObject, + _In_ PVOID InputBuffer, + _In_ ULONG InputBufferLength, + _Out_ PVOID OutputBuffer, + _Inout_ ULONG OutputBufferLength, + _In_ BOOLEAN InternalDeviceIoControl) { IO_STATUS_BLOCK IoStatusBlock; KEVENT Event; NTSTATUS Status; PIRP Irp; PAGED_CODE(); - if (CompBattDebug & 0x100) DbgPrint("CompBatt: ENTERING BatteryIoctl\n"); + if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: ENTERING BatteryIoctl\n"); /* Initialize the event and IRP */ KeInitializeEvent(&Event, SynchronizationEvent, 0); @@ -52,16 +52,16 @@ BatteryIoctl(IN ULONG IoControlCode, } /* Print failure */ - if (!(NT_SUCCESS(Status)) && (CompBattDebug & 8)) + if (!(NT_SUCCESS(Status)) && (CompBattDebug & COMPBATT_DEBUG_ERR)) DbgPrint("BatteryIoctl: Irp failed - %x\n", Status); /* Done */ - if (CompBattDebug & 0x100) DbgPrint("CompBatt: EXITING BatteryIoctl\n"); + if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: EXITING BatteryIoctl\n"); } else { /* Out of memory */ - if (CompBattDebug & 8) DbgPrint("BatteryIoctl: couldn't create Irp\n"); + if (CompBattDebug & COMPBATT_DEBUG_ERR) DbgPrint("BatteryIoctl: couldn't create Irp\n"); Status = STATUS_INSUFFICIENT_RESOURCES; } @@ -71,10 +71,11 @@ BatteryIoctl(IN ULONG IoControlCode, NTSTATUS NTAPI -CompBattGetDeviceObjectPointer(IN PUNICODE_STRING DeviceName, - IN ACCESS_MASK DesiredAccess, - OUT PFILE_OBJECT *FileObject, - OUT PDEVICE_OBJECT *DeviceObject) +CompBattGetDeviceObjectPointer( + _In_ PUNICODE_STRING DeviceName, + _In_ ACCESS_MASK DesiredAccess, + _Out_ PFILE_OBJECT *FileObject, + _Out_ PDEVICE_OBJECT *DeviceObject) { NTSTATUS Status; OBJECT_ATTRIBUTES ObjectAttributes; diff --git a/drivers/bus/acpi/compbatt/comppnp.c b/drivers/battery/compbatt/comppnp.c similarity index 82% rename from drivers/bus/acpi/compbatt/comppnp.c rename to drivers/battery/compbatt/comppnp.c index 141ec2ebbe4ac..4e456d065f874 100644 --- a/drivers/bus/acpi/compbatt/comppnp.c +++ b/drivers/battery/compbatt/comppnp.c @@ -1,9 +1,8 @@ /* - * PROJECT: ReactOS Composite Battery Driver - * LICENSE: BSD - See COPYING.ARM in the top level directory - * FILE: boot/drivers/bus/acpi/compbatt/comppnp.c - * PURPOSE: Plug-and-Play IOCTL/IRP Handling - * PROGRAMMERS: ReactOS Portable Systems Group + * PROJECT: ReactOS Composite Battery Driver + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: Plug-and-Play IOCTL/IRP Handling + * COPYRIGHT: Copyright 2010 ReactOS Portable Systems Group */ /* INCLUDES *******************************************************************/ @@ -16,11 +15,12 @@ NTSTATUS NTAPI -CompBattPowerDispatch(IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) +CompBattPowerDispatch( + _In_ PDEVICE_OBJECT DeviceObject, + _In_ PIRP Irp) { PCOMPBATT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; - if (CompBattDebug & 1) DbgPrint("CompBatt: PowerDispatch received power IRP.\n"); + if (CompBattDebug & COMPBATT_DEBUG_WARN) DbgPrint("CompBatt: PowerDispatch received power IRP.\n"); /* Start the next IRP */ PoStartNextPowerIrp(Irp); @@ -32,12 +32,13 @@ CompBattPowerDispatch(IN PDEVICE_OBJECT DeviceObject, PCOMPBATT_BATTERY_DATA NTAPI -RemoveBatteryFromList(IN PCUNICODE_STRING BatteryName, - IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension) +RemoveBatteryFromList( + _In_ PCUNICODE_STRING BatteryName, + _In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension) { PLIST_ENTRY ListHead, NextEntry; PCOMPBATT_BATTERY_DATA BatteryData; - if (CompBattDebug & 1) + if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: ENTERING RemoveBatteryFromList\n"); /* Loop the battery list */ @@ -68,19 +69,20 @@ RemoveBatteryFromList(IN PCUNICODE_STRING BatteryName, /* Done */ ExReleaseFastMutex(&DeviceExtension->Lock); - if (CompBattDebug & 1) DbgPrint("CompBatt: EXITING RemoveBatteryFromList\n"); + if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: EXITING RemoveBatteryFromList\n"); return NULL; } BOOLEAN NTAPI -IsBatteryAlreadyOnList(IN PCUNICODE_STRING BatteryName, - IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension) +IsBatteryAlreadyOnList( + _In_ PCUNICODE_STRING BatteryName, + _In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension) { PLIST_ENTRY ListHead, NextEntry; PCOMPBATT_BATTERY_DATA BatteryData; BOOLEAN Found = FALSE; - if (CompBattDebug & 1) + if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: ENTERING IsBatteryAlreadyOnList\n"); /* Loop the battery list */ @@ -104,14 +106,15 @@ IsBatteryAlreadyOnList(IN PCUNICODE_STRING BatteryName, /* Release the lock and return search status */ ExReleaseFastMutex(&DeviceExtension->Lock); - if (CompBattDebug & 1) DbgPrint("CompBatt: EXITING IsBatteryAlreadyOnList\n"); + if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: EXITING IsBatteryAlreadyOnList\n"); return Found; } NTSTATUS NTAPI -CompBattAddNewBattery(IN PUNICODE_STRING BatteryName, - IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension) +CompBattAddNewBattery( + _In_ PUNICODE_STRING BatteryName, + _In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension) { NTSTATUS Status = STATUS_SUCCESS; PCOMPBATT_BATTERY_DATA BatteryData; @@ -119,7 +122,7 @@ CompBattAddNewBattery(IN PUNICODE_STRING BatteryName, PIO_STACK_LOCATION IoStackLocation; PFILE_OBJECT FileObject; PAGED_CODE(); - if (CompBattDebug & 1) + if (CompBattDebug & COMPBATT_DEBUG_WARN) DbgPrint("CompBatt: ENTERING AddNewBattery \"%w\" \n", BatteryName->Buffer); /* Is this a new battery? */ @@ -165,7 +168,6 @@ CompBattAddNewBattery(IN PUNICODE_STRING BatteryName, /* Set IRP data */ IoSetNextIrpStackLocation(Irp); Irp->IoStatus.Status = STATUS_DEVICE_NOT_CONNECTED; - BatteryData->WaitFlag = 0; /* Insert this battery in the list */ ExAcquireFastMutex(&DeviceExtension->Lock); @@ -174,25 +176,25 @@ CompBattAddNewBattery(IN PUNICODE_STRING BatteryName, ExReleaseFastMutex(&DeviceExtension->Lock); /* Initialize the work item and delete lock */ - IoInitializeRemoveLock(&BatteryData->RemoveLock, 0, 0, 0); + IoInitializeRemoveLock(&BatteryData->RemoveLock, COMPBATT_TAG, 0, 0); ExInitializeWorkItem(&BatteryData->WorkItem, (PVOID)CompBattMonitorIrpCompleteWorker, BatteryData); /* Setup the IRP work entry */ - CompBattMonitorIrpComplete(BatteryData->DeviceObject, Irp, 0); + CompBattMonitorIrpComplete(BatteryData->DeviceObject, Irp, NULL); Status = STATUS_SUCCESS; } else { /* Fail, no memory */ - if (CompBattDebug & 8) + if (CompBattDebug & COMPBATT_DEBUG_ERR) DbgPrint("CompBatt: Couldn't allocate new battery Irp\n"); Status = STATUS_INSUFFICIENT_RESOURCES; ObDereferenceObject(BatteryData->DeviceObject); } } - else if (CompBattDebug & 8) + else if (CompBattDebug & COMPBATT_DEBUG_ERR) { /* Fail */ DbgPrint("CompBattAddNewBattery: Failed to get device Object. status = %lx\n", @@ -208,24 +210,25 @@ CompBattAddNewBattery(IN PUNICODE_STRING BatteryName, else { /* Fail, no memory */ - if (CompBattDebug & 8) + if (CompBattDebug & COMPBATT_DEBUG_ERR) DbgPrint("CompBatt: Couldn't allocate new battery node\n"); Status = STATUS_INSUFFICIENT_RESOURCES; } } /* We're done */ - if (CompBattDebug & 1) DbgPrint("CompBatt: EXITING AddNewBattery\n"); + if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: EXITING AddNewBattery\n"); return Status; } NTSTATUS NTAPI -CompBattRemoveBattery(IN PCUNICODE_STRING BatteryName, - IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension) +CompBattRemoveBattery( + _In_ PUNICODE_STRING BatteryName, + _In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension) { PCOMPBATT_BATTERY_DATA BatteryData; - if (CompBattDebug & 1) DbgPrint("CompBatt: RemoveBattery\n"); + if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: RemoveBattery\n"); /* Remove the entry */ BatteryData = RemoveBatteryFromList(BatteryName, DeviceExtension); @@ -246,13 +249,14 @@ CompBattRemoveBattery(IN PCUNICODE_STRING BatteryName, NTSTATUS NTAPI -CompBattGetBatteries(IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension) +CompBattGetBatteries( + _In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension) { PWCHAR p; NTSTATUS Status; PWCHAR LinkList; UNICODE_STRING LinkString; - if (CompBattDebug & 1) DbgPrint("CompBatt: ENTERING GetBatteries\n"); + if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: ENTERING GetBatteries\n"); /* Get all battery links */ Status = IoGetDeviceInterfaces(&GUID_DEVICE_BATTERY, NULL, 0, &LinkList); @@ -274,54 +278,56 @@ CompBattGetBatteries(IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension) /* Parsing complete, clean up buffer */ ExFreePool(LinkList); } - else if (CompBattDebug & 8) + else if (CompBattDebug & COMPBATT_DEBUG_ERR) { /* Fail */ DbgPrint("CompBatt: Couldn't get list of batteries\n"); } /* Done */ - if (CompBattDebug & 1) DbgPrint("CompBatt: EXITING GetBatteries\n"); + if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: EXITING GetBatteries\n"); return Status; } NTSTATUS NTAPI -CompBattPnpEventHandler(IN PDEVICE_INTERFACE_CHANGE_NOTIFICATION Notification, - IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension) +CompBattPnpEventHandler( + _In_ PDEVICE_INTERFACE_CHANGE_NOTIFICATION Notification, + _In_ PCOMPBATT_DEVICE_EXTENSION DeviceExtension) { - if (CompBattDebug & 1) DbgPrint("CompBatt: ENTERING PnpEventHandler\n"); - if (CompBattDebug & 2) DbgPrint("CompBatt: Received device interface change notification\n"); + if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: ENTERING PnpEventHandler\n"); + if (CompBattDebug & COMPBATT_DEBUG_WARN) DbgPrint("CompBatt: Received device interface change notification\n"); /* Check what happened */ if (IsEqualGUIDAligned(&Notification->Event, &GUID_DEVICE_INTERFACE_ARRIVAL)) { /* Add the new battery */ - if (CompBattDebug & 2) + if (CompBattDebug & COMPBATT_DEBUG_WARN) DbgPrint("CompBatt: Received notification of battery arrival\n"); CompBattAddNewBattery(Notification->SymbolicLinkName, DeviceExtension); } else if (IsEqualGUIDAligned(&Notification->Event, &GUID_DEVICE_INTERFACE_REMOVAL)) { /* Don't do anything */ - if (CompBattDebug & 2) + if (CompBattDebug & COMPBATT_DEBUG_WARN) DbgPrint("CompBatt: Received notification of battery removal\n"); } else { /* Shouldn't happen */ - if (CompBattDebug & 2) DbgPrint("CompBatt: Received unhandled PnP event\n"); + if (CompBattDebug & COMPBATT_DEBUG_WARN) DbgPrint("CompBatt: Received unhandled PnP event\n"); } /* Done, return success */ - if (CompBattDebug & 1) DbgPrint("CompBatt: EXITING PnpEventHandler\n"); + if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: EXITING PnpEventHandler\n"); return STATUS_SUCCESS; } NTSTATUS NTAPI -CompBattAddDevice(IN PDRIVER_OBJECT DriverObject, - IN PDEVICE_OBJECT PdoDeviceObject) +CompBattAddDevice( + _In_ PDRIVER_OBJECT DriverObject, + _In_ PDEVICE_OBJECT PdoDeviceObject) { NTSTATUS Status; UNICODE_STRING DeviceName; @@ -329,7 +335,7 @@ CompBattAddDevice(IN PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT DeviceObject; UNICODE_STRING SymbolicLinkName; BATTERY_MINIPORT_INFO MiniportInfo; - if (CompBattDebug & 2) DbgPrint("CompBatt: Got an AddDevice - %x\n", PdoDeviceObject); + if (CompBattDebug & COMPBATT_DEBUG_WARN) DbgPrint("CompBatt: Got an AddDevice - %x\n", PdoDeviceObject); /* Create the device */ RtlInitUnicodeString(&DeviceName, L"\\Device\\CompositeBattery"); @@ -357,7 +363,7 @@ CompBattAddDevice(IN PDRIVER_OBJECT DriverObject, if (!DeviceExtension->AttachedDevice) { /* Fail */ - if (CompBattDebug & 8) + if (CompBattDebug & COMPBATT_DEBUG_ERR) DbgPrint("CompBattAddDevice: Could not attach to LowerDevice.\n"); IoDeleteDevice(DeviceObject); return STATUS_UNSUCCESSFUL; @@ -403,13 +409,14 @@ CompBattAddDevice(IN PDRIVER_OBJECT DriverObject, NTSTATUS NTAPI -CompBattPnpDispatch(IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) +CompBattPnpDispatch( + _In_ PDEVICE_OBJECT DeviceObject, + _In_ PIRP Irp) { PIO_STACK_LOCATION IoStackLocation = IoGetCurrentIrpStackLocation(Irp); NTSTATUS Status; PCOMPBATT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; - if (CompBattDebug & 1) DbgPrint("CompBatt: ENTERING PnpDispatch\n"); + if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: ENTERING PnpDispatch\n"); /* Set default error */ Status = STATUS_NOT_SUPPORTED; @@ -430,14 +437,14 @@ CompBattPnpDispatch(IN PDEVICE_OBJECT DeviceObject, if (NT_SUCCESS(Status)) { /* Now go get the batteries */ - if (CompBattDebug & 2) + if (CompBattDebug & COMPBATT_DEBUG_WARN) DbgPrint("CompBatt: Successfully registered for PnP notification\n"); Status = CompBattGetBatteries(DeviceExtension); } else { /* We failed */ - if (CompBattDebug & 8) + if (CompBattDebug & COMPBATT_DEBUG_ERR) DbgPrint("CompBatt: Couldn't register for PnP notification - %x\n", Status); } @@ -491,7 +498,7 @@ CompBattPnpDispatch(IN PDEVICE_OBJECT DeviceObject, } /* Release the remove lock and return status */ - if (CompBattDebug & 1) DbgPrint("CompBatt: EXITING PnpDispatch\n"); + if (CompBattDebug & COMPBATT_DEBUG_TRACE) DbgPrint("CompBatt: EXITING PnpDispatch\n"); return Status; } diff --git a/drivers/bus/acpi/compbatt/guid.c b/drivers/battery/compbatt/guid.c similarity index 100% rename from drivers/bus/acpi/compbatt/guid.c rename to drivers/battery/compbatt/guid.c diff --git a/drivers/bus/acpi/CMakeLists.txt b/drivers/bus/acpi/CMakeLists.txt index 3535cf5604c1a..f56afd97228cb 100644 --- a/drivers/bus/acpi/CMakeLists.txt +++ b/drivers/bus/acpi/CMakeLists.txt @@ -209,6 +209,3 @@ add_importlibs(acpi ntoskrnl hal) add_pch(acpi precomp.h ACPI_SOURCE) add_cd_file(TARGET acpi DESTINATION reactos/system32/drivers NO_CAB FOR all) add_driver_inf(acpi acpi.inf) - -add_subdirectory(cmbatt) -add_subdirectory(compbatt) diff --git a/drivers/bus/acpi/compbatt/compbatt.c b/drivers/bus/acpi/compbatt/compbatt.c deleted file mode 100644 index 2c947910c2949..0000000000000 --- a/drivers/bus/acpi/compbatt/compbatt.c +++ /dev/null @@ -1,612 +0,0 @@ -/* - * PROJECT: ReactOS Composite Battery Driver - * LICENSE: BSD - See COPYING.ARM in the top level directory - * FILE: boot/drivers/bus/acpi/compbatt/compbatt.c - * PURPOSE: Main Initialization Code and IRP Handling - * PROGRAMMERS: ReactOS Portable Systems Group - */ - -/* INCLUDES *******************************************************************/ - -#include "compbatt.h" - -#include - -/* GLOBALS ********************************************************************/ - -ULONG CompBattDebug; - -/* FUNCTIONS ******************************************************************/ - -NTSTATUS -NTAPI -CompBattOpenClose(IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PAGED_CODE(); - if (CompBattDebug & 0x100) DbgPrint("CompBatt: ENTERING OpenClose\n"); - - /* Complete the IRP with success */ - Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - /* Return success */ - if (CompBattDebug & 0x100) DbgPrint("CompBatt: Exiting OpenClose\n"); - return STATUS_SUCCESS; -} - -NTSTATUS -NTAPI -CompBattSystemControl(IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PCOMPBATT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; - NTSTATUS Status; - PAGED_CODE(); - if (CompBattDebug & 1) DbgPrint("CompBatt: ENTERING System Control\n"); - - /* Are we attached yet? */ - if (DeviceExtension->AttachedDevice) - { - /* Send it up the stack */ - IoSkipCurrentIrpStackLocation(Irp); - Status = IoCallDriver(DeviceExtension->AttachedDevice, Irp); - } - else - { - /* We don't support WMI */ - Status = STATUS_NOT_SUPPORTED; - Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - } - - /* Return status */ - return Status; -} - -NTSTATUS -NTAPI -CompBattMonitorIrpComplete(IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - IN PKEVENT Event) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -NTAPI -CompBattMonitorIrpCompleteWorker(IN PCOMPBATT_BATTERY_DATA BatteryData) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - -VOID -NTAPI -CompBattRecalculateTag(IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension) -{ - PCOMPBATT_BATTERY_DATA BatteryData; - ULONG Tag; - PLIST_ENTRY ListHead, NextEntry; - if (CompBattDebug & 0x100) DbgPrint("CompBatt: ENTERING CompBattRecalculateTag\n"); - - /* Loop the battery list */ - ExAcquireFastMutex(&DeviceExtension->Lock); - ListHead = &DeviceExtension->BatteryList; - NextEntry = ListHead->Flink; - while (NextEntry != ListHead) - { - /* Get the battery information and check if it has a tag */ - BatteryData = CONTAINING_RECORD(NextEntry, COMPBATT_BATTERY_DATA, BatteryLink); - if (BatteryData->Flags & COMPBATT_TAG_ASSIGNED) - { - /* Generate the next tag and exit */ - Tag = DeviceExtension->NextTag; - DeviceExtension->Flags |= COMPBATT_TAG_ASSIGNED; - DeviceExtension->Tag = Tag; - DeviceExtension->NextTag = Tag + 1; - break; - } - - /* No tag for this device extension, clear it */ - DeviceExtension->Tag = BATTERY_TAG_INVALID; - NextEntry = NextEntry->Flink; - } - - /* We're done */ - ExReleaseFastMutex(&DeviceExtension->Lock); - if (CompBattDebug & 0x100) DbgPrint("CompBatt: EXITING CompBattRecalculateTag\n"); -} - -NTSTATUS -NTAPI -CompBattIoctl(IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PCOMPBATT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; - NTSTATUS Status; - if (CompBattDebug & 1) DbgPrint("CompBatt: ENTERING Ioctl\n"); - - /* Let the class driver handle it */ - Status = BatteryClassIoctl(DeviceExtension->ClassData, Irp); - if (Status == STATUS_NOT_SUPPORTED) - { - /* It failed, try the next driver up the stack */ - Irp->IoStatus.Status = Status; - IoSkipCurrentIrpStackLocation(Irp); - Status = IoCallDriver(DeviceExtension->AttachedDevice, Irp); - } - - /* Return status */ - if (CompBattDebug & 1) DbgPrint("CompBatt: EXITING Ioctl\n"); - return Status; -} - -NTSTATUS -NTAPI -CompBattQueryTag(IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension, - OUT PULONG Tag) -{ - NTSTATUS Status; - PAGED_CODE(); - if (CompBattDebug & 0x100) DbgPrint("CompBatt: ENTERING QueryTag\n"); - - /* Was a tag assigned? */ - if (!(DeviceExtension->Flags & COMPBATT_TAG_ASSIGNED)) - { - /* Assign one */ - CompBattRecalculateTag(DeviceExtension); - } - - /* Do we have a tag now? */ - if ((DeviceExtension->Flags & COMPBATT_TAG_ASSIGNED) && DeviceExtension->Tag != BATTERY_TAG_INVALID) - { - /* Return the tag */ - *Tag = DeviceExtension->Tag; - Status = STATUS_SUCCESS; - } - else - { - /* No tag */ - *Tag = BATTERY_TAG_INVALID; - Status = STATUS_NO_SUCH_DEVICE; - } - - /* Return status */ - if (CompBattDebug & 0x100) DbgPrint("CompBatt: EXITING QueryTag\n"); - return Status; -} - -NTSTATUS -NTAPI -CompBattDisableStatusNotify(IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension) -{ - PCOMPBATT_BATTERY_DATA BatteryData; - PLIST_ENTRY ListHead, NextEntry; - if (CompBattDebug & 0x100) DbgPrint("CompBatt: ENTERING DisableStatusNotify\n"); - - /* Loop the battery list */ - ExAcquireFastMutex(&DeviceExtension->Lock); - ListHead = &DeviceExtension->BatteryList; - NextEntry = ListHead->Flink; - while (NextEntry != ListHead) - { - /* Get the battery information and clear capacity data */ - BatteryData = CONTAINING_RECORD(NextEntry, COMPBATT_BATTERY_DATA, BatteryLink); - BatteryData->WaitStatus.LowCapacity = 0; - BatteryData->WaitStatus.HighCapacity = 0x7FFFFFFF; - NextEntry = NextEntry->Flink; - } - - /* Done */ - ExReleaseFastMutex(&DeviceExtension->Lock); - if (CompBattDebug & 0x100) DbgPrint("CompBatt: EXITING DisableStatusNotify\n"); - return STATUS_SUCCESS; -} - -NTSTATUS -NTAPI -CompBattSetStatusNotify(IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension, - IN ULONG BatteryTag, - IN PBATTERY_NOTIFY BatteryNotify) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -NTAPI -CompBattQueryStatus(IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension, - IN ULONG Tag, - IN PBATTERY_STATUS BatteryStatus) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -NTAPI -CompBattGetBatteryInformation(OUT PBATTERY_INFORMATION BatteryInfo, - IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension) -{ - NTSTATUS Status = STATUS_SUCCESS; - BATTERY_QUERY_INFORMATION InputBuffer; - PCOMPBATT_BATTERY_DATA BatteryData; - PLIST_ENTRY ListHead, NextEntry; - if (CompBattDebug & 1) DbgPrint("CompBatt: ENTERING GetBatteryInformation\n"); - - /* Set defaults */ - BatteryInfo->DefaultAlert1 = 0; - BatteryInfo->DefaultAlert2 = 0; - BatteryInfo->CriticalBias = 0; - - /* Loop the battery list */ - ExAcquireFastMutex(&DeviceExtension->Lock); - ListHead = &DeviceExtension->BatteryList; - NextEntry = ListHead->Flink; - while (NextEntry != ListHead) - { - /* Try to acquire the remove lock */ - BatteryData = CONTAINING_RECORD(NextEntry, COMPBATT_BATTERY_DATA, BatteryLink); - if (NT_SUCCESS(IoAcquireRemoveLock(&BatteryData->RemoveLock, 0))) - { - /* Now release the device lock since the battery can't go away */ - ExReleaseFastMutex(&DeviceExtension->Lock); - - /* Build the query */ - InputBuffer.BatteryTag = BatteryData->Tag; - InputBuffer.InformationLevel = BatteryInformation; - InputBuffer.AtRate = 0; - - /* Make sure the battery has a tag */ - if (BatteryData->Tag != BATTERY_TAG_INVALID) - { - /* Do we already have the data? */ - if (!(BatteryData->Flags & COMPBATT_BATTERY_INFORMATION_PRESENT)) - { - /* Send the IOCTL to query the information */ - RtlZeroMemory(&BatteryData->BatteryInformation, - sizeof(BatteryData->BatteryInformation)); - Status = BatteryIoctl(IOCTL_BATTERY_QUERY_INFORMATION, - BatteryData->DeviceObject, - &InputBuffer, - sizeof(InputBuffer), - &BatteryData->BatteryInformation, - sizeof(BatteryData->BatteryInformation), - 0); - if (!NT_SUCCESS(Status)) - { - /* Fail if the query had a problem */ - if (Status == STATUS_DEVICE_REMOVED) Status = STATUS_NO_SUCH_DEVICE; - ExAcquireFastMutex(&DeviceExtension->Lock); - IoReleaseRemoveLock(&BatteryData->RemoveLock, 0); - break; - } - - /* Next time we can use the static copy */ - BatteryData->Flags |= COMPBATT_BATTERY_INFORMATION_PRESENT; - if (CompBattDebug & 2) - DbgPrint("CompBattGetBatteryInformation: Read individual BATTERY_INFORMATION\n" - "-------- Capabilities = %x\n-------- Technology = %x\n" - "-------- Chemistry[4] = %x\n-------- DesignedCapacity = %x\n" - "-------- FullChargedCapacity = %x\n-------- DefaultAlert1 = %x\n" - "-------- DefaultAlert2 = %x\n-------- CriticalBias = %x\n" - "-------- CycleCount = %x\n", - BatteryData->BatteryInformation.Capabilities, - BatteryData->BatteryInformation.Technology, - BatteryData->BatteryInformation.Chemistry, - BatteryData->BatteryInformation.DesignedCapacity, - BatteryData->BatteryInformation.FullChargedCapacity, - BatteryData->BatteryInformation.DefaultAlert1, - BatteryData->BatteryInformation.DefaultAlert2, - BatteryData->BatteryInformation.CriticalBias, - BatteryData->BatteryInformation.CycleCount); - } - - /* Combine capabilities */ - BatteryInfo->Capabilities |= BatteryData->BatteryInformation.Capabilities; - - /* Add-on capacity */ - if (BatteryData->BatteryInformation.DesignedCapacity != BATTERY_UNKNOWN_CAPACITY) - { - BatteryInfo->DesignedCapacity += BatteryData->BatteryInformation.DesignedCapacity; - } - - /* Add on fully charged capacity */ - if (BatteryData->BatteryInformation.FullChargedCapacity != BATTERY_UNKNOWN_CAPACITY) - { - BatteryInfo->FullChargedCapacity += BatteryData->BatteryInformation.FullChargedCapacity; - } - - /* Choose the highest alert */ - BatteryInfo->DefaultAlert1 = max(BatteryInfo->DefaultAlert1, - BatteryData->BatteryInformation.DefaultAlert1); - - /* Choose the highest alert */ - BatteryInfo->DefaultAlert2 = max(BatteryInfo->DefaultAlert2, - BatteryData->BatteryInformation.DefaultAlert2); - - /* Choose the highest critical bias */ - BatteryInfo->CriticalBias = max(BatteryInfo->CriticalBias, - BatteryData->BatteryInformation.CriticalBias); - } - - /* Re-acquire the device extension lock and release the remove lock */ - ExAcquireFastMutex(&DeviceExtension->Lock); - IoReleaseRemoveLock(&BatteryData->RemoveLock, 0); - } - - /* Next entry */ - NextEntry = NextEntry->Flink; - } - - /* We are done with the list, check if the information was queried okay */ - ExReleaseFastMutex(&DeviceExtension->Lock); - if (NT_SUCCESS(Status)) - { - /* If there's no fully charged capacity, use the design capacity */ - if (!BatteryInfo->FullChargedCapacity) - { - BatteryInfo->FullChargedCapacity = BatteryInfo->DesignedCapacity; - } - - /* Print out final combined data */ - if (CompBattDebug & 2) - DbgPrint("CompBattGetBatteryInformation: Returning BATTERY_INFORMATION\n" - "-------- Capabilities = %x\n-------- Technology = %x\n" - "-------- Chemistry[4] = %x\n-------- DesignedCapacity = %x\n" - "-------- FullChargedCapacity = %x\n-------- DefaultAlert1 = %x\n" - "-------- DefaultAlert2 = %x\n-------- CriticalBias = %x\n" - "-------- CycleCount = %x\n", - BatteryInfo->Capabilities, - BatteryInfo->Technology, - BatteryInfo->Chemistry, - BatteryInfo->DesignedCapacity, - BatteryInfo->FullChargedCapacity, - BatteryInfo->DefaultAlert1, - BatteryInfo->DefaultAlert2, - BatteryInfo->CriticalBias, - BatteryInfo->CycleCount); - - /* Copy the data into the device extension */ - RtlCopyMemory(&DeviceExtension->BatteryInformation, - BatteryInfo, - sizeof(DeviceExtension->BatteryInformation)); - DeviceExtension->Flags |= COMPBATT_BATTERY_INFORMATION_PRESENT; - } - - /* We are done */ - if (CompBattDebug & 1) DbgPrint("CompBatt: EXITING GetBatteryInformation\n"); - return Status; -} - -NTSTATUS -NTAPI -CompBattGetBatteryGranularity(OUT PBATTERY_REPORTING_SCALE ReportingScale, - IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension) -{ - NTSTATUS Status = STATUS_SUCCESS; - BATTERY_QUERY_INFORMATION InputBuffer; - PCOMPBATT_BATTERY_DATA BatteryData; - BATTERY_REPORTING_SCALE BatteryScale[4]; - PLIST_ENTRY ListHead, NextEntry; - ULONG i; - if (CompBattDebug & 1) DbgPrint("CompBatt: ENTERING GetBatteryGranularity\n"); - - /* Set defaults */ - ReportingScale[0].Granularity = -1; - ReportingScale[1].Granularity = -1; - ReportingScale[2].Granularity = -1; - ReportingScale[3].Granularity = -1; - - /* Loop the battery list */ - ExAcquireFastMutex(&DeviceExtension->Lock); - ListHead = &DeviceExtension->BatteryList; - NextEntry = ListHead->Flink; - while (NextEntry != ListHead) - { - /* Try to acquire the remove lock */ - BatteryData = CONTAINING_RECORD(NextEntry, COMPBATT_BATTERY_DATA, BatteryLink); - if (NT_SUCCESS(IoAcquireRemoveLock(&BatteryData->RemoveLock, 0))) - { - /* Now release the device lock since the battery can't go away */ - ExReleaseFastMutex(&DeviceExtension->Lock); - - /* Build the query */ - InputBuffer.BatteryTag = BatteryData->Tag; - InputBuffer.InformationLevel = BatteryGranularityInformation; - - /* Make sure the battery has a tag */ - if (BatteryData->Tag != BATTERY_TAG_INVALID) - { - /* Send the IOCTL to query the information */ - RtlZeroMemory(&BatteryData->BatteryInformation, - sizeof(BatteryData->BatteryInformation)); - Status = BatteryIoctl(IOCTL_BATTERY_QUERY_INFORMATION, - BatteryData->DeviceObject, - &InputBuffer, - sizeof(InputBuffer), - &BatteryScale, - sizeof(BatteryScale), - 0); - if (!NT_SUCCESS(Status)) - { - /* Fail if the query had a problem */ - ExAcquireFastMutex(&DeviceExtension->Lock); - IoReleaseRemoveLock(&BatteryData->RemoveLock, 0); - break; - } - - /* Loop all 4 scales */ - for (i = 0; i < 4; i++) - { - /* Check for valid granularity */ - if (BatteryScale[i].Granularity) - { - /* If it's smaller, use it instead */ - ReportingScale[i].Granularity = min(BatteryScale[i].Granularity, - ReportingScale[i].Granularity); - } - - } - } - - /* Re-acquire the device extension lock and release the remove lock */ - ExAcquireFastMutex(&DeviceExtension->Lock); - IoReleaseRemoveLock(&BatteryData->RemoveLock, 0); - } - - /* Next entry */ - NextEntry = NextEntry->Flink; - } - - /* All done */ - ExReleaseFastMutex(&DeviceExtension->Lock); - if (CompBattDebug & 1) DbgPrint("CompBatt: EXITING GetBatteryGranularity\n"); - return STATUS_SUCCESS; -} - -NTSTATUS -NTAPI -CompBattGetEstimatedTime(OUT PULONG Time, - IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -NTAPI -CompBattQueryInformation(IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension, - IN ULONG Tag, - IN BATTERY_QUERY_INFORMATION_LEVEL InfoLevel, - IN OPTIONAL LONG AtRate, - IN PVOID Buffer, - IN ULONG BufferLength, - OUT PULONG ReturnedLength) -{ - BATTERY_INFORMATION BatteryInfo; - BATTERY_REPORTING_SCALE BatteryGranularity[4]; - PWCHAR BatteryName = L"Composite Battery"; - //BATTERY_MANUFACTURE_DATE Date; - ULONG Dummy, Time; - PVOID QueryData = NULL; - ULONG QueryLength = 0; - NTSTATUS Status = STATUS_SUCCESS; - PAGED_CODE(); - if (CompBattDebug & 1) DbgPrint("CompBatt: ENTERING QueryInformation\n"); - - /* Check for valid/correct tag */ - if ((Tag != DeviceExtension->Tag) || - (!(DeviceExtension->Flags & COMPBATT_TAG_ASSIGNED))) - { - /* Not right, so fail */ - return STATUS_NO_SUCH_DEVICE; - } - - /* Check what caller wants */ - switch (InfoLevel) - { - case BatteryInformation: - - /* Query combined battery information */ - RtlZeroMemory(&BatteryInfo, sizeof(BatteryInfo)); - Status = CompBattGetBatteryInformation(&BatteryInfo, DeviceExtension); - if (NT_SUCCESS(Status)) - { - /* Return the data if successful */ - QueryData = &BatteryInfo; - QueryLength = sizeof(BatteryInfo); - } - break; - - case BatteryGranularityInformation: - - /* Query combined granularity information */ - RtlZeroMemory(&BatteryGranularity, sizeof(BatteryGranularity)); - Status = CompBattGetBatteryGranularity(BatteryGranularity, DeviceExtension); - if (NT_SUCCESS(Status)) - { - /* Return the data if successful */ - QueryLength = sizeof(BatteryGranularity); - QueryData = &BatteryGranularity; - } - break; - - case BatteryEstimatedTime: - - /* Query combined time estimate information */ - RtlZeroMemory(&Time, sizeof(Time)); - Status = CompBattGetEstimatedTime(&Time, DeviceExtension); - if (NT_SUCCESS(Status)) - { - /* Return the data if successful */ - QueryLength = sizeof(Time); - QueryData = &Time; - } - break; - - case BatteryManufactureName: - case BatteryDeviceName: - - /* Return the static buffer */ - QueryData = BatteryName; - QueryLength = sizeof(L"Composite Battery"); - break; - - case BatteryManufactureDate: - - /* Static data */ - //Date.Day = 26; - //Date.Month = 06; - //Date.Year = 1997; - break; - - case BatteryTemperature: - case BatteryUniqueID: - - /* Return zero */ - Dummy = 0; - QueryData = &Dummy; - QueryLength = sizeof(Dummy); - break; - - default: - /* Everything else is unknown */ - Status = STATUS_INVALID_PARAMETER; - break; - } - - /* Return the required length and check if the caller supplied enough */ - *ReturnedLength = QueryLength; - if (BufferLength < QueryLength) Status = STATUS_BUFFER_TOO_SMALL; - - /* Copy the data if there's enough space and it exists */ - if ((NT_SUCCESS(Status)) && (QueryData)) RtlCopyMemory(Buffer, QueryData, QueryLength); - - /* Return function result */ - if (CompBattDebug & 1) DbgPrint("CompBatt: EXITING QueryInformation\n"); - return Status; -} - -NTSTATUS -NTAPI -DriverEntry(IN PDRIVER_OBJECT DriverObject, - IN PUNICODE_STRING RegistryPath) -{ - /* Register add device routine */ - DriverObject->DriverExtension->AddDevice = CompBattAddDevice; - - /* Register other handlers */ - DriverObject->MajorFunction[IRP_MJ_CREATE] = CompBattOpenClose; - DriverObject->MajorFunction[IRP_MJ_CLOSE] = CompBattOpenClose; - DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = CompBattIoctl; - DriverObject->MajorFunction[IRP_MJ_POWER] = CompBattPowerDispatch; - DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = CompBattSystemControl; - DriverObject->MajorFunction[IRP_MJ_PNP] = CompBattPnpDispatch; - return STATUS_SUCCESS; -} - -/* EOF */ diff --git a/drivers/bus/acpi/compbatt/compbatt.h b/drivers/bus/acpi/compbatt/compbatt.h deleted file mode 100644 index 950e5a5f7dda3..0000000000000 --- a/drivers/bus/acpi/compbatt/compbatt.h +++ /dev/null @@ -1,158 +0,0 @@ -/* - * PROJECT: ReactOS Composite Battery Driver - * LICENSE: BSD - See COPYING.ARM in the top level directory - * FILE: boot/drivers/bus/acpi/compbatt/compbatt.h - * PURPOSE: Main Header File - * PROGRAMMERS: ReactOS Portable Systems Group - */ - -#ifndef _COMPBATT_PCH_ -#define _COMPBATT_PCH_ - -#include -#include - -#define COMPBATT_BATTERY_INFORMATION_PRESENT 0x04 -#define COMPBATT_TAG_ASSIGNED 0x80 - -typedef struct _COMPBATT_BATTERY_DATA -{ - LIST_ENTRY BatteryLink; - IO_REMOVE_LOCK RemoveLock; - PDEVICE_OBJECT DeviceObject; - PIRP Irp; - WORK_QUEUE_ITEM WorkItem; - BOOLEAN WaitFlag; - BATTERY_WAIT_STATUS WaitStatus; - union - { - BATTERY_WAIT_STATUS WorkerWaitStatus; - BATTERY_STATUS WorkerStatus; - }; - ULONG Tag; - ULONG Flags; - BATTERY_INFORMATION BatteryInformation; - BATTERY_STATUS BatteryStatus; - ULONGLONG InterruptTime; - UNICODE_STRING BatteryName; -} COMPBATT_BATTERY_DATA, *PCOMPBATT_BATTERY_DATA; - -typedef struct _COMPBATT_DEVICE_EXTENSION -{ - PVOID ClassData; - ULONG NextTag; - LIST_ENTRY BatteryList; - FAST_MUTEX Lock; - ULONG Tag; - ULONG Flags; - BATTERY_INFORMATION BatteryInformation; - BATTERY_STATUS BatteryStatus; - ULONGLONG InterruptTime; - POWER_STATE PowerState; - ULONG LowCapacity; - ULONG HighCapacity; - PDEVICE_OBJECT AttachedDevice; - PDEVICE_OBJECT DeviceObject; - PVOID NotificationEntry; -} COMPBATT_DEVICE_EXTENSION, *PCOMPBATT_DEVICE_EXTENSION; - -NTSTATUS -NTAPI -CompBattAddDevice( - IN PDRIVER_OBJECT DriverObject, - IN PDEVICE_OBJECT PdoDeviceObject -); - -NTSTATUS -NTAPI -CompBattPowerDispatch( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp -); - -NTSTATUS -NTAPI -CompBattPnpDispatch( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp -); - -NTSTATUS -NTAPI -CompBattQueryInformation( - IN PCOMPBATT_DEVICE_EXTENSION FdoExtension, - IN ULONG Tag, - IN BATTERY_QUERY_INFORMATION_LEVEL InfoLevel, - IN OPTIONAL LONG AtRate, - IN PVOID Buffer, - IN ULONG BufferLength, - OUT PULONG ReturnedLength -); - -NTSTATUS -NTAPI -CompBattQueryStatus( - IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension, - IN ULONG Tag, - IN PBATTERY_STATUS BatteryStatus -); - -NTSTATUS -NTAPI -CompBattSetStatusNotify( - IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension, - IN ULONG BatteryTag, - IN PBATTERY_NOTIFY BatteryNotify -); - -NTSTATUS -NTAPI -CompBattDisableStatusNotify( - IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension -); - -NTSTATUS -NTAPI -CompBattQueryTag( - IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension, - OUT PULONG Tag -); - -NTSTATUS -NTAPI -CompBattMonitorIrpComplete( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - IN PKEVENT Event -); - -NTSTATUS -NTAPI -CompBattMonitorIrpCompleteWorker( - IN PCOMPBATT_BATTERY_DATA BatteryData -); - -NTSTATUS -NTAPI -CompBattGetDeviceObjectPointer( - IN PUNICODE_STRING DeviceName, - IN ACCESS_MASK DesiredAccess, - OUT PFILE_OBJECT *FileObject, - OUT PDEVICE_OBJECT *DeviceObject -); - -NTSTATUS -NTAPI -BatteryIoctl( - IN ULONG IoControlCode, - IN PDEVICE_OBJECT DeviceObject, - IN PVOID InputBuffer, - IN ULONG InputBufferLength, - IN PVOID OutputBuffer, - IN ULONG OutputBufferLength, - IN BOOLEAN InternalDeviceIoControl -); - -extern ULONG CompBattDebug; - -#endif /* _COMPBATT_PCH_ */ diff --git a/drivers/bus/pcix/pci/id.c b/drivers/bus/pcix/pci/id.c index 5fd872013969c..e8da4f101b99c 100644 --- a/drivers/bus/pcix/pci/id.c +++ b/drivers/bus/pcix/pci/id.c @@ -31,8 +31,8 @@ PciGetDescriptionMessage(IN ULONG Identifier, /* Find the message identifier in the message table */ MessageString.Buffer = NULL; Status = RtlFindMessage(PciDriverObject->DriverStart, - 11, // RT_MESSAGETABLE - LANG_NEUTRAL, + RT_MESSAGETABLE, + MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), Identifier, &Entry); if (!NT_SUCCESS(Status)) return NULL; diff --git a/drivers/crypto/ksecdd/random.c b/drivers/crypto/ksecdd/random.c index 53ed1e8866442..a8d8a2170fd2f 100644 --- a/drivers/crypto/ksecdd/random.c +++ b/drivers/crypto/ksecdd/random.c @@ -85,7 +85,7 @@ KsecReadMachineSpecificCounters( } /*! - * \see http://blogs.msdn.com/b/michael_howard/archive/2005/01/14/353379.aspx + * \see http://blogs.msdn.com/b/michael_howard/archive/2005/01/14/353379.aspx (DEAD_LINK) */ NTSTATUS NTAPI diff --git a/drivers/filesystems/btrfs/zstd/compiler.h b/drivers/filesystems/btrfs/zstd/compiler.h index 95e9483521d4f..6cae0415ca32f 100644 --- a/drivers/filesystems/btrfs/zstd/compiler.h +++ b/drivers/filesystems/btrfs/zstd/compiler.h @@ -111,7 +111,7 @@ # define PREFETCH_L2(ptr) (void)(ptr) /* disabled */ #else # if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_I86)) /* _mm_prefetch() is not defined outside of x86/x64 */ -# include /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */ +# include /* https://learn.microsoft.com/fr-fr/previous-versions/visualstudio/visual-studio-2008/84szxsww(v=vs.90) */ # define PREFETCH_L1(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T0) # define PREFETCH_L2(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T1) # elif defined(__aarch64__) diff --git a/drivers/filesystems/fastfat/create.c b/drivers/filesystems/fastfat/create.c index fa9b651e36403..cf2cf85e4c5d7 100644 --- a/drivers/filesystems/fastfat/create.c +++ b/drivers/filesystems/fastfat/create.c @@ -2356,7 +2356,7 @@ Return Value: if ((CreateDisposition != FILE_OPEN) && (CreateDisposition != FILE_OPEN_IF)) { - try_return( Iosb.Status = STATUS_ACCESS_DENIED ); + try_return( Status = STATUS_ACCESS_DENIED ); } // @@ -2389,7 +2389,7 @@ Return Value: if (!FlagOn(ShareAccess, FILE_SHARE_READ) && !FatIsHandleCountZero( IrpContext, Vcb )) { - try_return( Iosb.Status = STATUS_SHARING_VIOLATION ); + try_return( Status = STATUS_SHARING_VIOLATION ); } // @@ -2412,14 +2412,14 @@ Return Value: if (Vcb->OpenFileCount != 0) { - try_return( Iosb.Status = STATUS_SHARING_VIOLATION ); + try_return( Status = STATUS_SHARING_VIOLATION ); } } else { if (Vcb->ReadOnlyCount != Vcb->OpenFileCount) { - try_return( Iosb.Status = STATUS_SHARING_VIOLATION ); + try_return( Status = STATUS_SHARING_VIOLATION ); } } @@ -2487,13 +2487,13 @@ Return Value: if (Vcb->DirectAccessOpenCount > 0) { - if (!NT_SUCCESS(Iosb.Status = IoCheckShareAccess( *DesiredAccess, + if (!NT_SUCCESS(Status = IoCheckShareAccess( *DesiredAccess, ShareAccess, FileObject, &Vcb->ShareAccess, TRUE ))) { - try_return( Iosb.Status ); + try_return( NOTHING ); } } else { @@ -2546,7 +2546,7 @@ Return Value: // And set our status to success // - Iosb.Status = STATUS_SUCCESS; + Status = STATUS_SUCCESS; Iosb.Information = FILE_OPENED; try_exit: NOTHING; @@ -2558,7 +2558,7 @@ Return Value: // If this is an abnormal termination then undo our work // - if (_SEH2_AbnormalTermination() || !NT_SUCCESS(Iosb.Status)) { + if (_SEH2_AbnormalTermination() || !NT_SUCCESS(Status)) { if (UnwindCounts) { Vcb->DirectAccessOpenCount -= 1; @@ -2570,9 +2570,10 @@ Return Value: if (UnwindVolumeLock) { Vcb->VcbState &= ~VCB_STATE_FLAG_LOCKED; } } - DebugTrace(-1, Dbg, "FatOpenVolume -> Iosb.Status = %08lx\n", Iosb.Status); + DebugTrace(-1, Dbg, "FatOpenVolume -> Iosb.Status = %08lx\n", Status); } _SEH2_END; + Iosb.Status = Status; return Iosb; } diff --git a/drivers/filesystems/udfs/CMakeLists.txt b/drivers/filesystems/udfs/CMakeLists.txt index b1bfdd9db84c0..6fcfba012efa6 100644 --- a/drivers/filesystems/udfs/CMakeLists.txt +++ b/drivers/filesystems/udfs/CMakeLists.txt @@ -25,7 +25,7 @@ list(APPEND SOURCE mem.cpp misc.cpp namesup.cpp - pnp.cpp + #pnp.cpp read.cpp secursup.cpp shutdown.cpp diff --git a/drivers/input/i8042prt/README.txt b/drivers/input/i8042prt/README.txt index 16bb6c791fb1e..664b947f1bb72 100644 --- a/drivers/input/i8042prt/README.txt +++ b/drivers/input/i8042prt/README.txt @@ -70,7 +70,7 @@ Links: Here's a link describing most of the registry settings: -http://www.microsoft.com/resources/documentation/Windows/2000/server/reskit/en-us/Default.asp?url=/resources/documentation/Windows/2000/server/reskit/en-us/regentry/31493.asp +http://www.microsoft.com/resources/documentation/Windows/2000/server/reskit/en-us/Default.asp?url=/resources/documentation/Windows/2000/server/reskit/en-us/regentry/31493.asp (DEAD_LINK) PS/2 protocol documentation: diff --git a/drivers/input/i8042prt/keyboard.c b/drivers/input/i8042prt/keyboard.c index e33ec89659b93..a1727b7c45a10 100644 --- a/drivers/input/i8042prt/keyboard.c +++ b/drivers/input/i8042prt/keyboard.c @@ -202,7 +202,7 @@ i8042PowerWorkItem( __analysis_assume(Context != NULL); DeviceExtension = Context; - /* See http://blogs.msdn.com/doronh/archive/2006/09/08/746961.aspx */ + /* See https://learn.microsoft.com/en-us/archive/blogs/doronh/how-ps2-and-hid-keyboads-report-power-button-events */ /* Register GUID_DEVICE_SYS_BUTTON interface and report capability */ if (DeviceExtension->NewCaps != DeviceExtension->ReportedCaps) diff --git a/drivers/input/i8042prt/registry.c b/drivers/input/i8042prt/registry.c index 48b6ebfd234fa..9a675daa7427d 100644 --- a/drivers/input/i8042prt/registry.c +++ b/drivers/input/i8042prt/registry.c @@ -55,105 +55,105 @@ ReadRegistryEntries( Parameters[0].Flags = RTL_QUERY_REGISTRY_SUBKEY; Parameters[0].Name = L"Parameters"; - Parameters[1].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[1].Flags = RTL_QUERY_REGISTRY_DIRECT; Parameters[1].Name = L"KeyboardDataQueueSize"; Parameters[1].EntryContext = &Settings->KeyboardDataQueueSize; Parameters[1].DefaultType = REG_DWORD; Parameters[1].DefaultData = &DefaultKeyboardDataQueueSize; Parameters[1].DefaultLength = sizeof(ULONG); - Parameters[2].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[2].Flags = RTL_QUERY_REGISTRY_DIRECT; Parameters[2].Name = L"KeyboardDeviceBaseName"; Parameters[2].EntryContext = &Settings->KeyboardDeviceBaseName; Parameters[2].DefaultType = REG_SZ; Parameters[2].DefaultData = (PVOID)DefaultKeyboardDeviceBaseName; Parameters[2].DefaultLength = 0; - Parameters[3].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[3].Flags = RTL_QUERY_REGISTRY_DIRECT; Parameters[3].Name = L"MouseDataQueueSize"; Parameters[3].EntryContext = &Settings->MouseDataQueueSize; Parameters[3].DefaultType = REG_DWORD; Parameters[3].DefaultData = &DefaultMouseDataQueueSize; Parameters[3].DefaultLength = sizeof(ULONG); - Parameters[4].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[4].Flags = RTL_QUERY_REGISTRY_DIRECT; Parameters[4].Name = L"MouseResolution"; Parameters[4].EntryContext = &Settings->MouseResolution; Parameters[4].DefaultType = REG_DWORD; Parameters[4].DefaultData = &DefaultMouseResolution; Parameters[4].DefaultLength = sizeof(ULONG); - Parameters[5].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[5].Flags = RTL_QUERY_REGISTRY_DIRECT; Parameters[5].Name = L"MouseSynchIn100ns"; Parameters[5].EntryContext = &Settings->MouseSynchIn100ns; Parameters[5].DefaultType = REG_DWORD; Parameters[5].DefaultData = &DefaultMouseSynchIn100ns; Parameters[5].DefaultLength = sizeof(ULONG); - Parameters[6].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[6].Flags = RTL_QUERY_REGISTRY_DIRECT; Parameters[6].Name = L"NumberOfButtons"; Parameters[6].EntryContext = &Settings->NumberOfButtons; Parameters[6].DefaultType = REG_DWORD; Parameters[6].DefaultData = &DefaultNumberOfButtons; Parameters[6].DefaultLength = sizeof(ULONG); - Parameters[7].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[7].Flags = RTL_QUERY_REGISTRY_DIRECT; Parameters[7].Name = L"PointerDeviceBaseName"; Parameters[7].EntryContext = &Settings->PointerDeviceBaseName; Parameters[7].DefaultType = REG_SZ; Parameters[7].DefaultData = (PVOID)DefaultPointerDeviceBaseName; Parameters[7].DefaultLength = 0; - Parameters[8].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[8].Flags = RTL_QUERY_REGISTRY_DIRECT; Parameters[8].Name = L"PollStatusIterations"; Parameters[8].EntryContext = &Settings->PollStatusIterations; Parameters[8].DefaultType = REG_DWORD; Parameters[8].DefaultData = &DefaultPollStatusIterations; Parameters[8].DefaultLength = sizeof(ULONG); - Parameters[9].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[9].Flags = RTL_QUERY_REGISTRY_DIRECT; Parameters[9].Name = L"OverrideKeyboardType"; Parameters[9].EntryContext = &Settings->OverrideKeyboardType; Parameters[9].DefaultType = REG_DWORD; Parameters[9].DefaultData = &DefaultOverrideKeyboardType; Parameters[9].DefaultLength = sizeof(ULONG); - Parameters[10].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[10].Flags = RTL_QUERY_REGISTRY_DIRECT; Parameters[10].Name = L"OverrideKeyboardSubtype"; Parameters[10].EntryContext = &Settings->OverrideKeyboardSubtype; Parameters[10].DefaultType = REG_DWORD; Parameters[10].DefaultData = &DefaultOverrideKeyboardSubtype; Parameters[10].DefaultLength = sizeof(ULONG); - Parameters[11].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[11].Flags = RTL_QUERY_REGISTRY_DIRECT; Parameters[11].Name = L"PollingIterations"; Parameters[11].EntryContext = &Settings->PollingIterations; Parameters[11].DefaultType = REG_DWORD; Parameters[11].DefaultData = &DefaultPollingIterations; Parameters[11].DefaultLength = sizeof(ULONG); - Parameters[12].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[12].Flags = RTL_QUERY_REGISTRY_DIRECT; Parameters[12].Name = L"PollingIterationsMaximum"; Parameters[12].EntryContext = &Settings->PollingIterationsMaximum; Parameters[12].DefaultType = REG_DWORD; Parameters[12].DefaultData = &DefaultPollingIterationsMaximum; Parameters[12].DefaultLength = sizeof(ULONG); - Parameters[13].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[13].Flags = RTL_QUERY_REGISTRY_DIRECT; Parameters[13].Name = L"ResendIterations"; Parameters[13].EntryContext = &Settings->ResendIterations; Parameters[13].DefaultType = REG_DWORD; Parameters[13].DefaultData = &DefaultResendIterations; Parameters[13].DefaultLength = sizeof(ULONG); - Parameters[14].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[14].Flags = RTL_QUERY_REGISTRY_DIRECT; Parameters[14].Name = L"SampleRate"; Parameters[14].EntryContext = &Settings->SampleRate; Parameters[14].DefaultType = REG_DWORD; Parameters[14].DefaultData = &DefaultSampleRate; Parameters[14].DefaultLength = sizeof(ULONG); - Parameters[15].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[15].Flags = RTL_QUERY_REGISTRY_DIRECT; Parameters[15].Name = L"CrashOnCtrlScroll"; Parameters[15].EntryContext = &Settings->CrashOnCtrlScroll; Parameters[15].DefaultType = REG_DWORD; @@ -161,7 +161,7 @@ ReadRegistryEntries( Parameters[15].DefaultLength = sizeof(ULONG); Status = RtlQueryRegistryValues( - RTL_REGISTRY_ABSOLUTE, + RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL, RegistryPath->Buffer, Parameters, NULL, diff --git a/drivers/input/kbdclass/kbdclass.c b/drivers/input/kbdclass/kbdclass.c index ccf83532aaf6c..357eb581cd115 100644 --- a/drivers/input/kbdclass/kbdclass.c +++ b/drivers/input/kbdclass/kbdclass.c @@ -254,21 +254,21 @@ ReadRegistryEntries( RtlZeroMemory(Parameters, sizeof(Parameters)); - Parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT; Parameters[0].Name = L"ConnectMultiplePorts"; Parameters[0].EntryContext = &DriverExtension->ConnectMultiplePorts; Parameters[0].DefaultType = REG_DWORD; Parameters[0].DefaultData = &DefaultConnectMultiplePorts; Parameters[0].DefaultLength = sizeof(ULONG); - Parameters[1].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[1].Flags = RTL_QUERY_REGISTRY_DIRECT; Parameters[1].Name = L"KeyboardDataQueueSize"; Parameters[1].EntryContext = &DriverExtension->DataQueueSize; Parameters[1].DefaultType = REG_DWORD; Parameters[1].DefaultData = &DefaultDataQueueSize; Parameters[1].DefaultLength = sizeof(ULONG); - Parameters[2].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[2].Flags = RTL_QUERY_REGISTRY_DIRECT; Parameters[2].Name = L"KeyboardDeviceBaseName"; Parameters[2].EntryContext = &DriverExtension->DeviceBaseName; Parameters[2].DefaultType = REG_SZ; @@ -276,7 +276,7 @@ ReadRegistryEntries( Parameters[2].DefaultLength = 0; Status = RtlQueryRegistryValues( - RTL_REGISTRY_ABSOLUTE, + RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL, ParametersRegistryKey.Buffer, Parameters, NULL, diff --git a/drivers/input/mouclass/mouclass.c b/drivers/input/mouclass/mouclass.c index f84dcc30238c2..81e1e38618dce 100644 --- a/drivers/input/mouclass/mouclass.c +++ b/drivers/input/mouclass/mouclass.c @@ -221,21 +221,21 @@ ReadRegistryEntries( RtlZeroMemory(Parameters, sizeof(Parameters)); - Parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT; Parameters[0].Name = L"ConnectMultiplePorts"; Parameters[0].EntryContext = &DriverExtension->ConnectMultiplePorts; Parameters[0].DefaultType = REG_DWORD; Parameters[0].DefaultData = &DefaultConnectMultiplePorts; Parameters[0].DefaultLength = sizeof(ULONG); - Parameters[1].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[1].Flags = RTL_QUERY_REGISTRY_DIRECT; Parameters[1].Name = L"MouseDataQueueSize"; Parameters[1].EntryContext = &DriverExtension->DataQueueSize; Parameters[1].DefaultType = REG_DWORD; Parameters[1].DefaultData = &DefaultDataQueueSize; Parameters[1].DefaultLength = sizeof(ULONG); - Parameters[2].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[2].Flags = RTL_QUERY_REGISTRY_DIRECT; Parameters[2].Name = L"PointerDeviceBaseName"; Parameters[2].EntryContext = &DriverExtension->DeviceBaseName; Parameters[2].DefaultType = REG_SZ; @@ -243,7 +243,7 @@ ReadRegistryEntries( Parameters[2].DefaultLength = 0; Status = RtlQueryRegistryValues( - RTL_REGISTRY_ABSOLUTE, + RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL, ParametersRegistryKey.Buffer, Parameters, NULL, diff --git a/drivers/input/sermouse/sermouse.c b/drivers/input/sermouse/sermouse.c index c7e8b789a4691..9b4868133d7af 100644 --- a/drivers/input/sermouse/sermouse.c +++ b/drivers/input/sermouse/sermouse.c @@ -56,7 +56,7 @@ ReadRegistryEntries( RtlZeroMemory(Parameters, sizeof(Parameters)); - Parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT; Parameters[0].Name = L"NumberOfButtons"; Parameters[0].EntryContext = &DriverExtension->NumberOfButtons; Parameters[0].DefaultType = REG_DWORD; @@ -64,7 +64,7 @@ ReadRegistryEntries( Parameters[0].DefaultLength = sizeof(ULONG); Status = RtlQueryRegistryValues( - RTL_REGISTRY_ABSOLUTE, + RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL, ParametersRegistryKey.Buffer, Parameters, NULL, diff --git a/drivers/ksfilter/ks/image.c b/drivers/ksfilter/ks/image.c index c35728fea92bd..a34cbaa4661da 100644 --- a/drivers/ksfilter/ks/image.c +++ b/drivers/ksfilter/ks/image.c @@ -38,7 +38,7 @@ KsLoadResource( /* set up resource info */ ResourceInfo.Type = ResourceType; ResourceInfo.Name = ResourceName; - ResourceInfo.Language = 0; + ResourceInfo.Language = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL); _SEH2_TRY { diff --git a/drivers/ksfilter/ks/kcom.c b/drivers/ksfilter/ks/kcom.c index 2d020affaf0e0..7ec423c73c006 100644 --- a/drivers/ksfilter/ks/kcom.c +++ b/drivers/ksfilter/ks/kcom.c @@ -14,7 +14,7 @@ const GUID IID_IUnknown = {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x46}}; -/* http://msdn2.microsoft.com/en-us/library/ms809781.aspx */ +/* http://msdn2.microsoft.com/en-us/library/ms809781.aspx (DEAD_LINK) */ COMDDKAPI NTSTATUS NTAPI KoCreateInstance( IN REFCLSID ClassId, @@ -52,7 +52,7 @@ KoCreateInstance( to the appropriate device. Useful references: - http://www.freelists.org/archives/wdmaudiodev/01-2003/msg00023.html + https://www.freelists.org/post/wdmaudiodev/Need-audio-driver-deivce-interface-registration-help TODO */ diff --git a/drivers/multimedia/audio/sndblst.old/card.c b/drivers/multimedia/audio/sndblst.old/card.c index 267d55f592cb7..bc984de7f695f 100644 --- a/drivers/multimedia/audio/sndblst.old/card.c +++ b/drivers/multimedia/audio/sndblst.old/card.c @@ -1,7 +1,7 @@ /* Sound card operations - http://www.cae.wisc.edu/~brodskye/sb16doc/sb16doc.html + https://web.archive.org/web/20120415213248/http://homepages.cae.wisc.edu/~brodskye/sb16doc/sb16doc.html */ #include diff --git a/drivers/network/afd/afd/lock.c b/drivers/network/afd/afd/lock.c index aed7b8120ac04..ac04356488b4f 100644 --- a/drivers/network/afd/afd/lock.c +++ b/drivers/network/afd/afd/lock.c @@ -36,7 +36,6 @@ PVOID LockRequest( PIRP Irp, ASSERT(IrpSp->Parameters.DeviceIoControl.Type3InputBuffer); ASSERT(IrpSp->Parameters.DeviceIoControl.InputBufferLength); - Irp->MdlAddress = IoAllocateMdl( IrpSp->Parameters.DeviceIoControl.Type3InputBuffer, IrpSp->Parameters.DeviceIoControl.InputBufferLength, @@ -205,7 +204,9 @@ VOID UnlockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp ) PAFD_WSABUF LockBuffers( PAFD_WSABUF Buf, UINT Count, PVOID AddressBuf, PINT AddressLen, BOOLEAN Write, BOOLEAN LockAddress, - KPROCESSOR_MODE LockMode) { + KPROCESSOR_MODE LockMode, + BOOLEAN Wow64Is32Bit) +{ UINT i; /* Copy the buffer array so we don't lose it */ UINT Lock = LockAddress ? 2 : 0; @@ -222,7 +223,21 @@ PAFD_WSABUF LockBuffers( PAFD_WSABUF Buf, UINT Count, MapBuf = (PAFD_MAPBUF)(NewBuf + Count + Lock); _SEH2_TRY { - RtlCopyMemory( NewBuf, Buf, sizeof(AFD_WSABUF) * Count ); +#ifdef _WIN64 + if (Wow64Is32Bit) + { + for (i = 0; i < Count; i++) + { + NewBuf[i].buf = (PVOID)(ULONG_PTR)((PAFD_WSABUF32)Buf)[i].buf; + NewBuf[i].len = ((PAFD_WSABUF32)Buf)[i].len; + } + } + else +#endif + { + RtlCopyMemory(NewBuf, Buf, sizeof(AFD_WSABUF) * Count); + } + if( LockAddress ) { if (AddressBuf && AddressLen) { NewBuf[Count].buf = AddressBuf; @@ -307,37 +322,60 @@ VOID UnlockBuffers( PAFD_WSABUF Buf, UINT Count, BOOL Address ) { /* Produce a kernel-land handle array with handles replaced by object * pointers. This will allow the system to do proper alerting */ -PAFD_HANDLE LockHandles( PAFD_HANDLE HandleArray, UINT HandleCount ) { +PAFD_HANDLE LockHandles(PAFD_HANDLE HandleArray, + UINT HandleCount, + BOOLEAN Wow64Is32Bit) +{ UINT i; NTSTATUS Status = STATUS_SUCCESS; +#ifdef _WIN64 + PAFD_HANDLE32 HandleArray32 = (PAFD_HANDLE32)HandleArray; +#endif + SOCKET handle; PAFD_HANDLE FileObjects = ExAllocatePoolWithTag(NonPagedPool, HandleCount * sizeof(AFD_HANDLE), TAG_AFD_POLL_HANDLE); - for( i = 0; FileObjects && i < HandleCount; i++ ) { + for( i = 0; FileObjects && i < HandleCount; i++ ) + { +#ifdef _WIN64 + if (Wow64Is32Bit) + { + handle = HandleArray32[i].Handle; + FileObjects[i].Events = HandleArray32[i].Events; + } + else +#endif + { + handle = HandleArray[i].Handle; + FileObjects[i].Events = HandleArray[i].Events; + } + FileObjects[i].Status = 0; - FileObjects[i].Events = HandleArray[i].Events; FileObjects[i].Handle = 0; - if( !HandleArray[i].Handle ) continue; - if( NT_SUCCESS(Status) ) { - Status = ObReferenceObjectByHandle - ( (PVOID)HandleArray[i].Handle, - FILE_ALL_ACCESS, - NULL, - KernelMode, - (PVOID*)&FileObjects[i].Handle, - NULL ); + + if(!handle) continue; + + if(NT_SUCCESS(Status)) + { + Status = ObReferenceObjectByHandle((PVOID)handle, + FILE_ALL_ACCESS, + NULL, + KernelMode, + (PVOID*)&FileObjects[i].Handle, + NULL); } - if( !NT_SUCCESS(Status) ) + if(!NT_SUCCESS(Status)) { AFD_DbgPrint(MIN_TRACE,("Failed to reference handles (0x%x)\n", Status)); FileObjects[i].Handle = 0; } } - if( !NT_SUCCESS(Status) ) { + if(!NT_SUCCESS(Status)) + { UnlockHandles( FileObjects, HandleCount ); return NULL; } @@ -438,4 +476,4 @@ NTSTATUS LeaveIrpUntilLater( PAFD_FCB FCB, PIRP Irp, UINT Function ) { SocketStateUnlock( FCB ); return Status; -} +} \ No newline at end of file diff --git a/drivers/network/afd/afd/main.c b/drivers/network/afd/afd/main.c index 5466aa9036aee..70e053510e87d 100644 --- a/drivers/network/afd/afd/main.c +++ b/drivers/network/afd/afd/main.c @@ -1170,8 +1170,8 @@ CleanupPendingIrp(PAFD_FCB FCB, PIRP Irp, PIO_STACK_LOCATION IrpSp, PAFD_ACTIVE_ ASSERT(Poll); PollReq = Irp->AssociatedIrp.SystemBuffer; - ZeroEvents(PollReq->Handles, PollReq->HandleCount); - SignalSocket(Poll, NULL, PollReq, STATUS_CANCELLED); + ZeroEvents(PollReq, IoIs32bitProcess(Irp)); + SignalSocket(Poll, NULL, Poll->AfdHandles, PollReq, STATUS_CANCELLED); } } } diff --git a/drivers/network/afd/afd/read.c b/drivers/network/afd/afd/read.c index bcc8e37f43cba..0cdddc49f66e6 100644 --- a/drivers/network/afd/afd/read.c +++ b/drivers/network/afd/afd/read.c @@ -418,6 +418,9 @@ AfdConnectedSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp, PFILE_OBJECT FileObject = IrpSp->FileObject; PAFD_FCB FCB = FileObject->FsContext; PAFD_RECV_INFO RecvReq; +#ifdef _WIN64 + PAFD_RECV_INFO32 RecvReq32; +#endif UINT TotalBytesCopied = 0; PAFD_STORED_DATAGRAM DatagramRecv; PLIST_ENTRY ListEntry; @@ -445,12 +448,49 @@ AfdConnectedSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp, return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY, Irp, 0 ); - AFD_DbgPrint(MID_TRACE,("Recv flags %x\n", RecvReq->AfdFlags)); +#ifdef _WIN64 + if ((IrpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL || + IrpSp->MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL) && + IoIs32bitProcess(Irp)) + { + RecvReq32 = (PAFD_RECV_INFO32)RecvReq; + RecvReq = ExAllocatePoolWithTag(NonPagedPool, + sizeof(*RecvReq), + TAG_AFD_DATA_BUFFER); - RecvReq->BufferArray = LockBuffers( RecvReq->BufferArray, - RecvReq->BufferCount, - NULL, NULL, - TRUE, FALSE, LockMode ); + if (!RecvReq) + { + return UnlockAndMaybeComplete(FCB, + STATUS_NO_MEMORY, + Irp, 0); + } + + RecvReq->BufferCount = RecvReq32->BufferCount; + RecvReq->BufferArray = UlongToPtr(RecvReq32->BufferArray); + RecvReq->AfdFlags = RecvReq32->AfdFlags; + RecvReq->TdiFlags = RecvReq32->TdiFlags; + + Irp->Tail.Overlay.DriverContext[0] = RecvReq; + + ExFreePoolWithTag(RecvReq32, TAG_AFD_DATA_BUFFER); + + AFD_DbgPrint(MID_TRACE,("Recv flags %x\n", RecvReq->AfdFlags)); + + RecvReq->BufferArray = LockBuffers(RecvReq->BufferArray, + RecvReq->BufferCount, + NULL, NULL, + FALSE, FALSE, LockMode, + TRUE); + } + else +#endif + { + RecvReq->BufferArray = LockBuffers(RecvReq->BufferArray, + RecvReq->BufferCount, + NULL, NULL, + TRUE, FALSE, LockMode, + FALSE); + } if( !RecvReq->BufferArray ) { return UnlockAndMaybeComplete( FCB, STATUS_ACCESS_VIOLATION, @@ -733,7 +773,8 @@ AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp, RecvReq->BufferCount, RecvReq->Address, RecvReq->AddressLength, - TRUE, TRUE, LockMode ); + TRUE, TRUE, LockMode, + IoIs32bitProcess(Irp)); if( !RecvReq->BufferArray ) { /* access violation in userspace */ return UnlockAndMaybeComplete(FCB, STATUS_ACCESS_VIOLATION, Irp, 0); diff --git a/drivers/network/afd/afd/select.c b/drivers/network/afd/afd/select.c index 6c8e5a279dac6..2aed8bf8b8ec7 100644 --- a/drivers/network/afd/afd/select.c +++ b/drivers/network/afd/afd/select.c @@ -31,60 +31,98 @@ static VOID PrintEvents( ULONG Events ) { #endif } -static VOID CopyBackStatus( PAFD_HANDLE HandleArray, - UINT HandleCount ) { +VOID ZeroEvents(PAFD_POLL_INFO PollReq, + BOOLEAN Wow64Is32Bit) +{ UINT i; +#ifdef _WIN64 + PAFD_POLL_INFO32 PollReq32 = (PVOID)PollReq; - for( i = 0; i < HandleCount; i++ ) { - HandleArray[i].Events = HandleArray[i].Status; - HandleArray[i].Status = 0; + if (Wow64Is32Bit) + { + for(i = 0; i < PollReq32->HandleCount; i++) + { + PollReq32->Handles[i].Status = 0; + PollReq32->Handles[i].Events = 0; + } + + return; } -} - -VOID ZeroEvents( PAFD_HANDLE HandleArray, - UINT HandleCount ) { - UINT i; - - for( i = 0; i < HandleCount; i++ ) { - HandleArray[i].Status = 0; - HandleArray[i].Events = 0; +#endif + + for(i = 0; i < PollReq->HandleCount; i++) + { + PollReq->Handles[i].Status = 0; + PollReq->Handles[i].Events = 0; } } /* you must pass either Poll OR Irp */ -VOID SignalSocket( - PAFD_ACTIVE_POLL Poll OPTIONAL, - PIRP _Irp OPTIONAL, - PAFD_POLL_INFO PollReq, - NTSTATUS Status - ) +VOID SignalSocket(PAFD_ACTIVE_POLL Poll OPTIONAL, + PIRP _Irp OPTIONAL, + PAFD_HANDLE AfdHandles, + PAFD_POLL_INFO PollReq, + NTSTATUS Status) { +#ifdef _WIN64 + PAFD_POLL_INFO32 PollReq32 = (PVOID)PollReq; +#endif UINT i; + ULONG HandleCount; PIRP Irp = _Irp ? _Irp : Poll->Irp; AFD_DbgPrint(MID_TRACE,("Called (Status %x)\n", Status)); if (Poll) { + ASSERT(Poll->AfdHandles == AfdHandles); + KeCancelTimer( &Poll->Timer ); RemoveEntryList( &Poll->ListEntry ); ExFreePoolWithTag(Poll, TAG_AFD_ACTIVE_POLL); } Irp->IoStatus.Status = Status; - Irp->IoStatus.Information = - FIELD_OFFSET(AFD_POLL_INFO, Handles) + sizeof(AFD_HANDLE) * PollReq->HandleCount; - CopyBackStatus( PollReq->Handles, - PollReq->HandleCount ); - for( i = 0; i < PollReq->HandleCount; i++ ) { - AFD_DbgPrint - (MAX_TRACE, - ("Handle(%x): Got %x,%x\n", - PollReq->Handles[i].Handle, - PollReq->Handles[i].Events, - PollReq->Handles[i].Status)); +#ifdef _WIN64 + if (IoIs32bitProcess(Irp)) + { + HandleCount = PollReq32->HandleCount; + + Irp->IoStatus.Information = + FIELD_OFFSET(AFD_POLL_INFO32, Handles) + sizeof(AFD_HANDLE32) * PollReq32->HandleCount; + + for(i = 0; i < PollReq32->HandleCount; i++) + { + PollReq32->Handles[i].Events = PollReq32->Handles[i].Status; + PollReq32->Handles[i].Status = 0; + + AFD_DbgPrint(MAX_TRACE, ("Handle(%x): Got %x,%x\n", + PollReq32->Handles[i].Handle, + PollReq32->Handles[i].Events, + PollReq32->Handles[i].Status)); + } } - UnlockHandles( AFD_HANDLES(PollReq), PollReq->HandleCount ); + else +#endif + { + HandleCount = PollReq->HandleCount; + + Irp->IoStatus.Information = + FIELD_OFFSET(AFD_POLL_INFO, Handles) + sizeof(AFD_HANDLE) * PollReq->HandleCount; + + for(i = 0; i < PollReq->HandleCount; i++) + { + PollReq->Handles[i].Events = PollReq->Handles[i].Status; + PollReq->Handles[i].Status = 0; + + AFD_DbgPrint(MAX_TRACE, ("Handle(%x): Got %x,%x\n", + PollReq->Handles[i].Handle, + PollReq->Handles[i].Events, + PollReq->Handles[i].Status)); + } + } + + UnlockHandles(AfdHandles, HandleCount); if( Irp->MdlAddress ) UnlockRequest( Irp, IoGetCurrentIrpStackLocation( Irp ) ); AFD_DbgPrint(MID_TRACE,("Completing\n")); (void)IoSetCancelRoutine(Irp, NULL); @@ -113,10 +151,10 @@ static VOID NTAPI SelectTimeout( PKDPC Dpc, DeviceExt = Poll->DeviceExt; PollReq = Irp->AssociatedIrp.SystemBuffer; - ZeroEvents( PollReq->Handles, PollReq->HandleCount ); + ZeroEvents(PollReq, IoIs32bitProcess(Irp)); KeAcquireSpinLock( &DeviceExt->Lock, &OldIrql ); - SignalSocket( Poll, NULL, PollReq, STATUS_TIMEOUT ); + SignalSocket(Poll, NULL, Poll->AfdHandles, PollReq, STATUS_TIMEOUT); KeReleaseSpinLock( &DeviceExt->Lock, OldIrql ); AFD_DbgPrint(MID_TRACE,("Timeout\n")); @@ -143,15 +181,15 @@ VOID KillSelectsForFCB( PAFD_DEVICE_EXTENSION DeviceExt, ListEntry = ListEntry->Flink; Irp = Poll->Irp; PollReq = Irp->AssociatedIrp.SystemBuffer; - HandleArray = AFD_HANDLES(PollReq); + HandleArray = Poll->AfdHandles; for( i = 0; i < PollReq->HandleCount; i++ ) { AFD_DbgPrint(MAX_TRACE,("Req: %u, This %p\n", HandleArray[i].Handle, FileObject)); if( (PVOID)HandleArray[i].Handle == FileObject && (!OnlyExclusive || (OnlyExclusive && Poll->Exclusive)) ) { - ZeroEvents( PollReq->Handles, PollReq->HandleCount ); - SignalSocket( Poll, NULL, PollReq, STATUS_CANCELLED ); + ZeroEvents(PollReq, IoIs32bitProcess(Irp)); + SignalSocket( Poll, NULL, Poll->AfdHandles, PollReq, STATUS_CANCELLED ); } } } @@ -168,62 +206,112 @@ AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp, PAFD_FCB FCB; PFILE_OBJECT FileObject; PAFD_POLL_INFO PollReq = Irp->AssociatedIrp.SystemBuffer; + PAFD_HANDLE AfdHandles = NULL; +#ifdef _WIN64 + PAFD_POLL_INFO32 PollReq32 = Irp->AssociatedIrp.SystemBuffer; +#endif PAFD_DEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension; KIRQL OldIrql; UINT i, Signalled = 0; - ULONG Exclusive = PollReq->Exclusive; - + ULONG Exclusive; + ULONG HandleCount; + UNREFERENCED_PARAMETER(IrpSp); - AFD_DbgPrint(MID_TRACE,("Called (HandleCount %u Timeout %d)\n", - PollReq->HandleCount, - (INT)(PollReq->Timeout.QuadPart))); - - SET_AFD_HANDLES(PollReq, - LockHandles( PollReq->Handles, PollReq->HandleCount )); - - if( !AFD_HANDLES(PollReq) ) { +#ifdef _WIN64 + if (IoIs32bitProcess(Irp)) + { + Exclusive = PollReq32->Exclusive; + HandleCount = PollReq32->HandleCount; + + AFD_DbgPrint(MID_TRACE, ("Called (HandleCount %u Timeout %d)\n", + PollReq32->HandleCount, + (INT)(PollReq32->Timeout.QuadPart))); + + AfdHandles = LockHandles((PVOID)PollReq32->Handles, PollReq->HandleCount, TRUE); + } + else +#endif + { + Exclusive = PollReq->Exclusive; + HandleCount = PollReq->HandleCount; + + AFD_DbgPrint(MID_TRACE, ("Called (HandleCount %u Timeout %d)\n", + PollReq->HandleCount, + (INT)(PollReq->Timeout.QuadPart))); + + AfdHandles = LockHandles(PollReq->Handles, PollReq->HandleCount, FALSE); + } + + if(!AfdHandles) + { Irp->IoStatus.Status = STATUS_NO_MEMORY; Irp->IoStatus.Information = 0; IoCompleteRequest( Irp, IO_NETWORK_INCREMENT ); return STATUS_NO_MEMORY; } - if( Exclusive ) { - for( i = 0; i < PollReq->HandleCount; i++ ) { - if( !AFD_HANDLES(PollReq)[i].Handle ) continue; + if(Exclusive) + { + for(i = 0; i < HandleCount; i++) + { + if(!AfdHandles[i].Handle) continue; - KillSelectsForFCB( DeviceExt, - (PFILE_OBJECT)AFD_HANDLES(PollReq)[i].Handle, - TRUE ); + KillSelectsForFCB(DeviceExt, + (PFILE_OBJECT)AfdHandles[i].Handle, + TRUE); } } - KeAcquireSpinLock( &DeviceExt->Lock, &OldIrql ); + KeAcquireSpinLock(&DeviceExt->Lock, &OldIrql); - for( i = 0; i < PollReq->HandleCount; i++ ) { - if( !AFD_HANDLES(PollReq)[i].Handle ) continue; + for(i = 0; i < HandleCount; i++) + { + if(!AfdHandles[i].Handle) continue; - FileObject = (PFILE_OBJECT)AFD_HANDLES(PollReq)[i].Handle; + FileObject = (PFILE_OBJECT)AfdHandles[i].Handle; FCB = FileObject->FsContext; - AFD_DbgPrint(MID_TRACE, ("AFD: Select Events: ")); - PrintEvents( PollReq->Handles[i].Events ); - AFD_DbgPrint(MID_TRACE,("\n")); - - PollReq->Handles[i].Status = - PollReq->Handles[i].Events & FCB->PollState; - if( PollReq->Handles[i].Status ) { - AFD_DbgPrint(MID_TRACE,("Signalling %p with %x\n", - FCB, FCB->PollState)); - Signalled++; +#ifdef _WIN64 + if (IoIs32bitProcess(Irp)) + { + AFD_DbgPrint(MID_TRACE, ("AFD: Select Events: ")); + PrintEvents(PollReq32->Handles[i].Events); + AFD_DbgPrint(MID_TRACE,("\n")); + + PollReq32->Handles[i].Status = + PollReq32->Handles[i].Events & FCB->PollState; + + if(PollReq32->Handles[i].Status) + { + AFD_DbgPrint(MID_TRACE,("Signalling %p with %x\n", + FCB, FCB->PollState)); + Signalled++; + } + } + else +#endif + { + AFD_DbgPrint(MID_TRACE, ("AFD: Select Events: ")); + PrintEvents(PollReq->Handles[i].Events); + AFD_DbgPrint(MID_TRACE,("\n")); + + PollReq->Handles[i].Status = + PollReq->Handles[i].Events & FCB->PollState; + + if(PollReq->Handles[i].Status) + { + AFD_DbgPrint(MID_TRACE,("Signalling %p with %x\n", + FCB, FCB->PollState)); + Signalled++; + } } } if( Signalled ) { Status = STATUS_SUCCESS; Irp->IoStatus.Status = Status; - SignalSocket( NULL, Irp, PollReq, Status ); + SignalSocket( NULL, Irp, AfdHandles, PollReq, Status ); } else { PAFD_ACTIVE_POLL Poll = NULL; @@ -236,6 +324,7 @@ AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp, Poll->Irp = Irp; Poll->DeviceExt = DeviceExt; Poll->Exclusive = Exclusive; + Poll->AfdHandles = AfdHandles; KeInitializeTimerEx( &Poll->Timer, NotificationTimer ); @@ -243,8 +332,17 @@ AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp, InsertTailList( &DeviceExt->Polls, &Poll->ListEntry ); - KeSetTimer( &Poll->Timer, PollReq->Timeout, &Poll->TimeoutDpc ); - +#ifdef _WIN64 + if (IoIs32bitProcess(Irp)) + { + KeSetTimer(&Poll->Timer, PollReq32->Timeout, &Poll->TimeoutDpc); + } + else +#endif + { + KeSetTimer(&Poll->Timer, PollReq->Timeout, &Poll->TimeoutDpc); + } + Status = STATUS_PENDING; IoMarkIrpPending( Irp ); (void)IoSetCancelRoutine(Irp, AfdCancelHandler); @@ -384,20 +482,41 @@ static BOOLEAN UpdatePollWithFCB( PAFD_ACTIVE_POLL Poll, PFILE_OBJECT FileObject PAFD_FCB FCB; UINT Signalled = 0; PAFD_POLL_INFO PollReq = Poll->Irp->AssociatedIrp.SystemBuffer; +#ifdef _WIN64 + PAFD_POLL_INFO32 PollReq32 = Poll->Irp->AssociatedIrp.SystemBuffer; +#endif + + PAFD_HANDLE AfdHandles = Poll->AfdHandles; ASSERT( KeGetCurrentIrql() == DISPATCH_LEVEL ); for( i = 0; i < PollReq->HandleCount; i++ ) { - if( !AFD_HANDLES(PollReq)[i].Handle ) continue; + if( !AfdHandles[i].Handle ) continue; - FileObject = (PFILE_OBJECT)AFD_HANDLES(PollReq)[i].Handle; + FileObject = (PFILE_OBJECT)AfdHandles[i].Handle; FCB = FileObject->FsContext; - PollReq->Handles[i].Status = PollReq->Handles[i].Events & FCB->PollState; - if( PollReq->Handles[i].Status ) { - AFD_DbgPrint(MID_TRACE,("Signalling %p with %x\n", - FCB, FCB->PollState)); - Signalled++; +#ifdef _WIN64 + if (IoIs32bitProcess(Poll->Irp)) + { + PollReq32->Handles[i].Status = PollReq32->Handles[i].Events & FCB->PollState; + if(PollReq32->Handles[i].Status) + { + AFD_DbgPrint(MID_TRACE,("Signalling %p with %x\n", + FCB, FCB->PollState)); + Signalled++; + } + } + else +#endif + { + PollReq->Handles[i].Status = PollReq->Handles[i].Events & FCB->PollState; + if(PollReq->Handles[i].Status) + { + AFD_DbgPrint(MID_TRACE,("Signalling %p with %x\n", + FCB, FCB->PollState)); + Signalled++; + } } } @@ -435,7 +554,7 @@ VOID PollReeval( PAFD_DEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject ) { if( UpdatePollWithFCB( Poll, FileObject ) ) { ThePollEnt = ThePollEnt->Flink; AFD_DbgPrint(MID_TRACE,("Signalling socket\n")); - SignalSocket( Poll, NULL, PollReq, STATUS_SUCCESS ); + SignalSocket( Poll, NULL, Poll->AfdHandles, PollReq, STATUS_SUCCESS ); } else ThePollEnt = ThePollEnt->Flink; } diff --git a/drivers/network/afd/afd/write.c b/drivers/network/afd/afd/write.c index 29ad9501b73b4..6894d4c64fa2d 100644 --- a/drivers/network/afd/afd/write.c +++ b/drivers/network/afd/afd/write.c @@ -325,6 +325,160 @@ static NTSTATUS NTAPI PacketSocketSendComplete return STATUS_SUCCESS; } +#ifdef _WIN64 +static +NTSTATUS +AfdConvert32BitUdpWrite(PIRP Irp, + PAFD_SEND_INFO_UDP32 SendReq32, + PAFD_SEND_INFO_UDP* pOutSendReq) +{ + PAFD_SEND_INFO_UDP SendReq; + + SendReq = ExAllocatePoolWithTag(NonPagedPool, + sizeof(*SendReq), + TAG_AFD_DATA_BUFFER); + if (!SendReq) + { + return STATUS_NO_MEMORY; + } + + SendReq->BufferCount = SendReq32->BufferCount; + SendReq->BufferArray = UlongToPtr(SendReq32->BufferArray); + SendReq->AfdFlags = SendReq32->AfdFlags; + + SendReq->TdiRequest.SendDatagramInformation = + UlongToPtr(SendReq32->TdiRequest.SendDatagramInformation); + + SendReq->TdiRequest.Request.Handle.AddressHandle = + UlongToPtr(SendReq32->TdiRequest.Request.Handle.AddressHandle); + + SendReq->TdiRequest.Request.RequestNotifyObject = + UlongToPtr(SendReq32->TdiRequest.Request.RequestNotifyObject); + + SendReq->TdiRequest.Request.RequestContext = + UlongToPtr(SendReq32->TdiRequest.Request.RequestContext); + + SendReq->TdiRequest.Request.TdiStatus = SendReq32->TdiRequest.Request.TdiStatus; + + SendReq->TdiConnection.UserDataLength = SendReq32->TdiConnection.UserDataLength; + SendReq->TdiConnection.UserData = UlongToPtr(SendReq32->TdiConnection.UserData); + + SendReq->TdiConnection.OptionsLength = SendReq32->TdiConnection.OptionsLength; + SendReq->TdiConnection.Options = UlongToPtr(SendReq32->TdiConnection.Options); + + SendReq->TdiConnection.RemoteAddressLength = SendReq32->TdiConnection.RemoteAddressLength; + SendReq->TdiConnection.RemoteAddress = UlongToPtr(SendReq32->TdiConnection.RemoteAddress); + + Irp->Tail.Overlay.DriverContext[0] = SendReq; + *pOutSendReq = SendReq; + + ExFreePoolWithTag(SendReq32, TAG_AFD_DATA_BUFFER); + return STATUS_SUCCESS; +} +#endif + +static +NTSTATUS +AfdConnectedSocketWriteDataUdp(PAFD_FCB FCB, + PDEVICE_OBJECT DeviceObject, PIRP Irp, + PIO_STACK_LOCATION IrpSp, BOOLEAN Short) +{ + PAFD_SEND_INFO_UDP SendReq; + PTDI_CONNECTION_INFORMATION TargetAddress; + KPROCESSOR_MODE LockMode; + NTSTATUS Status; + + /* Check that the socket is bound */ + if (FCB->State != SOCKET_STATE_BOUND || !FCB->RemoteAddress) + { + AFD_DbgPrint(MIN_TRACE,("Invalid parameter\n")); + return UnlockAndMaybeComplete(FCB, + STATUS_INVALID_PARAMETER, + Irp, + 0); + } + + if (!(SendReq = LockRequest(Irp, IrpSp, FALSE, &LockMode))) + { + return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0); + } + +#ifdef _WIN64 + if ((IrpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL || + IrpSp->MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL) && + IoIs32bitProcess(Irp)) + { + Status = AfdConvert32BitUdpWrite(Irp, (PAFD_SEND_INFO_UDP32)SendReq, &SendReq); + if (!NT_SUCCESS(Status)) + { + return UnlockAndMaybeComplete(FCB, Status, Irp, 0); + } + + SendReq->BufferArray = LockBuffers(SendReq->BufferArray, + SendReq->BufferCount, + NULL, NULL, + FALSE, FALSE, LockMode, + TRUE); + } + else +#endif + { + /* Must lock buffers before handing off user data */ + SendReq->BufferArray = LockBuffers(SendReq->BufferArray, + SendReq->BufferCount, + NULL, NULL, + FALSE, FALSE, LockMode, + FALSE); + } + + if(!SendReq->BufferArray) + { + return UnlockAndMaybeComplete(FCB, + STATUS_ACCESS_VIOLATION, + Irp, + 0); + } + + Status = TdiBuildConnectionInfo(&TargetAddress, FCB->RemoteAddress); + + if (!NT_SUCCESS(Status)) + { + UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE); + return UnlockAndMaybeComplete(FCB, Status, Irp, 0); + } + + FCB->PollState &= ~AFD_EVENT_SEND; + + Status = QueueUserModeIrp(FCB, Irp, FUNCTION_SEND); + if (Status == STATUS_PENDING) + { + Status = TdiSendDatagram(&FCB->SendIrp.InFlightRequest, + FCB->AddressFile.Object, + SendReq->BufferArray[0].buf, + SendReq->BufferArray[0].len, + TargetAddress, + PacketSocketSendComplete, + FCB); + + if (Status != STATUS_PENDING) + { + NT_VERIFY(RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]) == &Irp->Tail.Overlay.ListEntry); + Irp->IoStatus.Status = Status; + Irp->IoStatus.Information = 0; + (void)IoSetCancelRoutine(Irp, NULL); + UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE); + UnlockRequest(Irp, IoGetCurrentIrpStackLocation(Irp)); + IoCompleteRequest(Irp, IO_NETWORK_INCREMENT); + } + } + + ExFreePoolWithTag(TargetAddress, TAG_AFD_TDI_CONNECTION_INFORMATION); + + SocketStateUnlock(FCB); + + return STATUS_PENDING; +} + NTSTATUS NTAPI AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp, BOOLEAN Short) { @@ -332,6 +486,9 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp, PFILE_OBJECT FileObject = IrpSp->FileObject; PAFD_FCB FCB = FileObject->FsContext; PAFD_SEND_INFO SendReq; +#ifdef _WIN64 + PAFD_SEND_INFO32 SendReq32 = NULL; +#endif UINT TotalBytesCopied = 0, i, SpaceAvail = 0, BytesCopied, SendLength; KPROCESSOR_MODE LockMode; @@ -344,71 +501,9 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp, FCB->EventSelectDisabled &= ~AFD_EVENT_SEND; - if( FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS ) + if(FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS) { - PAFD_SEND_INFO_UDP SendReq; - PTDI_CONNECTION_INFORMATION TargetAddress; - - /* Check that the socket is bound */ - if( FCB->State != SOCKET_STATE_BOUND || !FCB->RemoteAddress ) - { - AFD_DbgPrint(MIN_TRACE,("Invalid parameter\n")); - return UnlockAndMaybeComplete( FCB, STATUS_INVALID_PARAMETER, Irp, - 0 ); - } - - if( !(SendReq = LockRequest( Irp, IrpSp, FALSE, &LockMode )) ) - return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY, Irp, 0 ); - - /* Must lock buffers before handing off user data */ - SendReq->BufferArray = LockBuffers( SendReq->BufferArray, - SendReq->BufferCount, - NULL, NULL, - FALSE, FALSE, LockMode ); - - if( !SendReq->BufferArray ) { - return UnlockAndMaybeComplete( FCB, STATUS_ACCESS_VIOLATION, - Irp, 0 ); - } - - Status = TdiBuildConnectionInfo( &TargetAddress, FCB->RemoteAddress ); - - if( NT_SUCCESS(Status) ) { - FCB->PollState &= ~AFD_EVENT_SEND; - - Status = QueueUserModeIrp(FCB, Irp, FUNCTION_SEND); - if (Status == STATUS_PENDING) - { - Status = TdiSendDatagram(&FCB->SendIrp.InFlightRequest, - FCB->AddressFile.Object, - SendReq->BufferArray[0].buf, - SendReq->BufferArray[0].len, - TargetAddress, - PacketSocketSendComplete, - FCB); - if (Status != STATUS_PENDING) - { - NT_VERIFY(RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]) == &Irp->Tail.Overlay.ListEntry); - Irp->IoStatus.Status = Status; - Irp->IoStatus.Information = 0; - (void)IoSetCancelRoutine(Irp, NULL); - UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE); - UnlockRequest(Irp, IoGetCurrentIrpStackLocation(Irp)); - IoCompleteRequest(Irp, IO_NETWORK_INCREMENT); - } - } - - ExFreePoolWithTag(TargetAddress, TAG_AFD_TDI_CONNECTION_INFORMATION); - - SocketStateUnlock(FCB); - - return STATUS_PENDING; - } - else - { - UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE); - return UnlockAndMaybeComplete( FCB, Status, Irp, 0 ); - } + return AfdConnectedSocketWriteDataUdp(FCB, DeviceObject, Irp, IrpSp, Short); } if (FCB->PollState & AFD_EVENT_CLOSE) @@ -438,12 +533,49 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp, if( !(SendReq = LockRequest( Irp, IrpSp, FALSE, &LockMode )) ) return UnlockAndMaybeComplete ( FCB, STATUS_NO_MEMORY, Irp, 0 ); + +#ifdef _WIN64 + if ((IrpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL || + IrpSp->MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL) && + IoIs32bitProcess(Irp)) + { + SendReq32 = (PAFD_SEND_INFO32)SendReq; + SendReq = ExAllocatePoolWithTag(NonPagedPool, + sizeof(*SendReq), + TAG_AFD_DATA_BUFFER); - SendReq->BufferArray = LockBuffers( SendReq->BufferArray, - SendReq->BufferCount, - NULL, NULL, - FALSE, FALSE, LockMode ); + if (!SendReq) + { + return UnlockAndMaybeComplete(FCB, + STATUS_NO_MEMORY, + Irp, 0); + } + SendReq->BufferCount = SendReq32->BufferCount; + SendReq->BufferArray = UlongToPtr(SendReq32->BufferArray); + SendReq->AfdFlags = SendReq32->AfdFlags; + SendReq->TdiFlags = SendReq32->TdiFlags; + + Irp->Tail.Overlay.DriverContext[0] = SendReq; + + ExFreePoolWithTag(SendReq32, TAG_AFD_DATA_BUFFER); + + SendReq->BufferArray = LockBuffers(SendReq->BufferArray, + SendReq->BufferCount, + NULL, NULL, + FALSE, FALSE, LockMode, + TRUE); + } + else +#endif + { + SendReq->BufferArray = LockBuffers(SendReq->BufferArray, + SendReq->BufferCount, + NULL, NULL, + FALSE, FALSE, LockMode, + FALSE); + } + if( !SendReq->BufferArray ) { return UnlockAndMaybeComplete( FCB, STATUS_ACCESS_VIOLATION, Irp, 0 ); @@ -569,6 +701,7 @@ AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp, PAFD_FCB FCB = FileObject->FsContext; PAFD_SEND_INFO_UDP SendReq; KPROCESSOR_MODE LockMode; + BOOLEAN Convert32Bit = FALSE; UNREFERENCED_PARAMETER(DeviceObject); @@ -595,6 +728,21 @@ AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp, if( !(SendReq = LockRequest( Irp, IrpSp, FALSE, &LockMode )) ) return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0); +#ifdef _WIN64 + if ((IrpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL || + IrpSp->MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL) && + IoIs32bitProcess(Irp)) + { + Status = AfdConvert32BitUdpWrite(Irp, (PAFD_SEND_INFO_UDP32)SendReq, &SendReq); + Convert32Bit = TRUE; + + if (!NT_SUCCESS(Status)) + { + return UnlockAndMaybeComplete(FCB, Status, Irp, 0); + } + } +#endif + if (FCB->State == SOCKET_STATE_CREATED) { if (FCB->LocalAddress) @@ -621,7 +769,8 @@ AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp, SendReq->BufferArray = LockBuffers( SendReq->BufferArray, SendReq->BufferCount, NULL, NULL, - FALSE, FALSE, LockMode ); + FALSE, FALSE, LockMode, + Convert32Bit ); if( !SendReq->BufferArray ) return UnlockAndMaybeComplete( FCB, STATUS_ACCESS_VIOLATION, diff --git a/drivers/network/afd/include/afd.h b/drivers/network/afd/include/afd.h index 2ddfcf4ad2d25..046e5f5a12e52 100644 --- a/drivers/network/afd/include/afd.h +++ b/drivers/network/afd/include/afd.h @@ -23,6 +23,14 @@ #include #include +#ifdef _WIN64 +#define EXPLICIT_32BIT +#include +#undef EXPLICIT_32BIT +#else +#define IoIs32bitProcess(irp) FALSE +#endif + #include "tdi_proto.h" #include "tdiconn.h" #include "debug.h" @@ -96,12 +104,6 @@ typedef struct IPADDR_ENTRY { * for ancillary data on packet * requests. */ -/* XXX This is a hack we should clean up later - * We do this in order to get some storage for the locked handle table - * Maybe I'll use some tail item in the irp instead */ -#define AFD_HANDLES(x) ((PAFD_HANDLE)(x)->Exclusive) -#define SET_AFD_HANDLES(x,y) (((x)->Exclusive) = (ULONG_PTR)(y)) - typedef struct _AFD_MAPBUF { PVOID BufferAddress; PMDL Mdl; @@ -121,6 +123,7 @@ typedef struct _AFD_ACTIVE_POLL { KTIMER Timer; PKEVENT EventObject; BOOLEAN Exclusive; + PAFD_HANDLE AfdHandles; } AFD_ACTIVE_POLL, *PAFD_ACTIVE_POLL; typedef struct _IRP_LIST { @@ -278,10 +281,11 @@ NTSTATUS AfdAccept( PDEVICE_OBJECT DeviceObject, PIRP Irp, /* lock.c */ -PAFD_WSABUF LockBuffers( PAFD_WSABUF Buf, UINT Count, - PVOID AddressBuf, PINT AddressLen, - BOOLEAN Write, BOOLEAN LockAddress, - KPROCESSOR_MODE LockMode ); +PAFD_WSABUF LockBuffers(PAFD_WSABUF Buf, UINT Count, + PVOID AddressBuf, PINT AddressLen, + BOOLEAN Write, BOOLEAN LockAddress, + KPROCESSOR_MODE LockMode, + BOOLEAN Wow64Is32Bit); VOID UnlockBuffers( PAFD_WSABUF Buf, UINT Count, BOOL Address ); BOOLEAN SocketAcquireStateLock( PAFD_FCB FCB ); NTSTATUS NTAPI UnlockAndMaybeComplete @@ -289,7 +293,7 @@ NTSTATUS NTAPI UnlockAndMaybeComplete UINT Information ); VOID SocketStateUnlock( PAFD_FCB FCB ); NTSTATUS LostSocket( PIRP Irp ); -PAFD_HANDLE LockHandles( PAFD_HANDLE HandleArray, UINT HandleCount ); +PAFD_HANDLE LockHandles(PAFD_HANDLE HandleArray, UINT HandleCount, BOOLEAN Wow64Is32Bit); VOID UnlockHandles( PAFD_HANDLE HandleArray, UINT HandleCount ); PVOID LockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp, BOOLEAN Output, KPROCESSOR_MODE *LockMode ); VOID UnlockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp ); @@ -331,10 +335,10 @@ AfdEnumEvents( PDEVICE_OBJECT DeviceObject, PIRP Irp, VOID PollReeval( PAFD_DEVICE_EXTENSION DeviceObject, PFILE_OBJECT FileObject ); VOID KillSelectsForFCB( PAFD_DEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, BOOLEAN ExclusiveOnly ); -VOID ZeroEvents( PAFD_HANDLE HandleArray, - UINT HandleCount ); +VOID ZeroEvents(PAFD_POLL_INFO PollReq, + BOOLEAN Wow64Is32Bit); VOID SignalSocket( - PAFD_ACTIVE_POLL Poll OPTIONAL, PIRP _Irp OPTIONAL, + PAFD_ACTIVE_POLL Poll OPTIONAL, PIRP _Irp OPTIONAL, PAFD_HANDLE AfdHandles, PAFD_POLL_INFO PollReq, NTSTATUS Status); /* tdi.c */ diff --git a/drivers/network/dd/e1000/nete1000.inf b/drivers/network/dd/e1000/nete1000.inf index 7ae4df0d4f195..2540412a129d2 100644 --- a/drivers/network/dd/e1000/nete1000.inf +++ b/drivers/network/dd/e1000/nete1000.inf @@ -61,11 +61,17 @@ DefaultDestDir = 12 [E1000_Inst.ndi.NT] Characteristics = 0x4 ; NCF_PHYSICAL BusType = 5 ; PCIBus +AddReg = E1000_AddReg.NT CopyFiles = E1000_CopyFiles.NT [E1000_CopyFiles.NT] e1000.sys +[E1000_AddReg.NT] +HKR, Ndi, Service, 0, "e1000" +HKR, Ndi\Interfaces, UpperRange, 0, "ndis5" +HKR, Ndi\Interfaces, LowerRange, 0, "ethernet" + [E1000_Inst.ndi.NT.Services] AddService = e1000, 0x00000002, E1000_Service_Inst diff --git a/drivers/network/dd/ne2000/netne.inf b/drivers/network/dd/ne2000/netne.inf index 208e6c49a2969..01a07793207ac 100644 --- a/drivers/network/dd/ne2000/netne.inf +++ b/drivers/network/dd/ne2000/netne.inf @@ -42,6 +42,9 @@ CopyFiles = NE2000_CopyFiles.NT [NE2000_AddReg.NT] HKR,,Port,0x00000000,"c100" HKR,,Irq,0x00000000,"B" +HKR, Ndi, Service, 0, "ne2000" +HKR, Ndi\Interfaces, UpperRange, 0, "ndis5" +HKR, Ndi\Interfaces, LowerRange, 0, "ethernet" [NE2000_CopyFiles.NT] ne2000.sys diff --git a/drivers/network/dd/pcnet/netamd.inf b/drivers/network/dd/pcnet/netamd.inf index 5792ffd58d379..0ac4fd6f7fe2b 100644 --- a/drivers/network/dd/pcnet/netamd.inf +++ b/drivers/network/dd/pcnet/netamd.inf @@ -39,6 +39,9 @@ HKR,,LED2,,"10000" HKR,,LED3,,"10000" HKR,,MPMODE,,"0" HKR,,TP,,"1" +HKR, Ndi, Service, 0, "PCNet" +HKR, Ndi\Interfaces, UpperRange, 0, "ndis5" +HKR, Ndi\Interfaces, LowerRange, 0, "ethernet" [PCNet_CopyFiles.NT] pcnet.sys diff --git a/drivers/network/dd/rtl8139/netrtl.inf b/drivers/network/dd/rtl8139/netrtl.inf index 461376d408d0e..5ffbe9283c03b 100644 --- a/drivers/network/dd/rtl8139/netrtl.inf +++ b/drivers/network/dd/rtl8139/netrtl.inf @@ -43,11 +43,17 @@ DefaultDestDir = 12 [RTL8139_Inst.ndi.NT] Characteristics = 0x4 ; NCF_PHYSICAL BusType = 5 ; PCIBus +AddReg = RTL8139_AddReg.NT CopyFiles = RTL8139_CopyFiles.NT [RTL8139_CopyFiles.NT] rtl8139.sys +[RTL8139_AddReg.NT] +HKR, Ndi, Service, 0, "rtl8139" +HKR, Ndi\Interfaces, UpperRange, 0, "ndis5" +HKR, Ndi\Interfaces, LowerRange, 0, "ethernet" + [RTL8139_Inst.ndi.NT.Services] AddService = rtl8139, 0x00000002, RTL8139_Service_Inst diff --git a/drivers/network/tcpip/tcpip/dispatch.c b/drivers/network/tcpip/tcpip/dispatch.c index 375c0bc5fd5e4..e2444abbde739 100644 --- a/drivers/network/tcpip/tcpip/dispatch.c +++ b/drivers/network/tcpip/tcpip/dispatch.c @@ -1295,6 +1295,17 @@ VOID DispTdiQueryInformationExComplete( QueryContext = (PTI_QUERY_CONTEXT)Context; if (NT_SUCCESS(Status)) { +#ifdef _WIN64 + if (IoIs32bitProcess(QueryContext->Irp)) + { + CopyBufferToBufferChain( + QueryContext->InputMdl, + FIELD_OFFSET(TCP_REQUEST_QUERY_INFORMATION_EX32, Context), + (PCHAR)&((TCP_REQUEST_QUERY_INFORMATION_EX32*)&QueryContext->QueryInfo)->Context, + CONTEXT_SIZE); + } + else +#endif CopyBufferToBufferChain( QueryContext->InputMdl, FIELD_OFFSET(TCP_REQUEST_QUERY_INFORMATION_EX, Context), @@ -1328,7 +1339,7 @@ NTSTATUS DispTdiQueryInformationEx( * Status of operation */ { - PTCP_REQUEST_QUERY_INFORMATION_EX InputBuffer; + PVOID InputBuffer; PTRANSPORT_CONTEXT TranContext; PTI_QUERY_CONTEXT QueryContext; PVOID OutputBuffer; @@ -1341,6 +1352,7 @@ NTSTATUS DispTdiQueryInformationEx( PMDL InputMdl = NULL; PMDL OutputMdl = NULL; NTSTATUS Status = STATUS_SUCCESS; + SIZE_T ValidInputLength = sizeof(TCP_REQUEST_QUERY_INFORMATION_EX); TI_DbgPrint(DEBUG_IRP, ("Called.\n")); @@ -1367,8 +1379,15 @@ NTSTATUS DispTdiQueryInformationEx( InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength; OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength; +#ifdef _WIN64 + if (IoIs32bitProcess(Irp)) + { + ValidInputLength = sizeof(TCP_REQUEST_QUERY_INFORMATION_EX32); + } +#endif + /* Validate parameters */ - if ((InputBufferLength == sizeof(TCP_REQUEST_QUERY_INFORMATION_EX)) && + if ((InputBufferLength == ValidInputLength) && (OutputBufferLength != 0)) { InputBuffer = (PTCP_REQUEST_QUERY_INFORMATION_EX) @@ -1379,7 +1398,7 @@ NTSTATUS DispTdiQueryInformationEx( if (QueryContext) { _SEH2_TRY { InputMdl = IoAllocateMdl(InputBuffer, - sizeof(TCP_REQUEST_QUERY_INFORMATION_EX), + ValidInputLength, FALSE, TRUE, NULL); OutputMdl = IoAllocateMdl(OutputBuffer, @@ -1397,8 +1416,10 @@ NTSTATUS DispTdiQueryInformationEx( OutputMdlLocked = TRUE; + ASSERT(ValidInputLength <= sizeof(QueryContext->QueryInfo)); + RtlCopyMemory(&QueryContext->QueryInfo, - InputBuffer, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX)); + InputBuffer, ValidInputLength); } else Status = STATUS_INSUFFICIENT_RESOURCES; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { @@ -1441,57 +1462,61 @@ NTSTATUS DispTdiQueryInformationEx( ExFreePoolWithTag(QueryContext, QUERY_CONTEXT_TAG); } else Status = STATUS_INSUFFICIENT_RESOURCES; - } else if( InputBufferLength == - sizeof(TCP_REQUEST_QUERY_INFORMATION_EX) ) { - /* Handle the case where the user is probing the buffer for length */ - TI_DbgPrint(MAX_TRACE, ("InputBufferLength %d OutputBufferLength %d\n", - InputBufferLength, OutputBufferLength)); + } + else if(InputBufferLength == ValidInputLength) + { + /* Handle the case where the user is probing the buffer for length */ + TI_DbgPrint(MAX_TRACE, ("InputBufferLength %d OutputBufferLength %d\n", + InputBufferLength, OutputBufferLength)); + InputBuffer = (PTCP_REQUEST_QUERY_INFORMATION_EX) IrpSp->Parameters.DeviceIoControl.Type3InputBuffer; - Size = 0; + Size = 0; QueryContext = ExAllocatePoolWithTag(NonPagedPool, sizeof(TI_QUERY_CONTEXT), QUERY_CONTEXT_TAG); if (!QueryContext) return STATUS_INSUFFICIENT_RESOURCES; - _SEH2_TRY { - InputMdl = IoAllocateMdl(InputBuffer, - sizeof(TCP_REQUEST_QUERY_INFORMATION_EX), - FALSE, TRUE, NULL); - - MmProbeAndLockPages(InputMdl, Irp->RequestorMode, - IoModifyAccess); - - InputMdlLocked = TRUE; - Status = STATUS_SUCCESS; - } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - TI_DbgPrint(MAX_TRACE, ("Failed to acquire client buffer\n")); - Status = _SEH2_GetExceptionCode(); - } _SEH2_END; - - if( !NT_SUCCESS(Status) || !InputMdl ) { - if( InputMdl ) IoFreeMdl( InputMdl ); - ExFreePoolWithTag(QueryContext, QUERY_CONTEXT_TAG); - return Status; - } - - RtlCopyMemory(&QueryContext->QueryInfo, - InputBuffer, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX)); - - QueryContext->Irp = Irp; - QueryContext->InputMdl = InputMdl; - QueryContext->OutputMdl = NULL; - - Request.RequestNotifyObject = DispTdiQueryInformationExComplete; - Request.RequestContext = QueryContext; - Status = InfoTdiQueryInformationEx(&Request, - &QueryContext->QueryInfo.ID, - NULL, - &Size, - &QueryContext->QueryInfo.Context); - DispTdiQueryInformationExComplete(QueryContext, Status, Size); - TI_DbgPrint(MAX_TRACE, ("Leaving. Status = (0x%X)\n", Status)); - } else Status = STATUS_INVALID_PARAMETER; + _SEH2_TRY { + InputMdl = IoAllocateMdl(InputBuffer, + ValidInputLength, + FALSE, TRUE, NULL); + + MmProbeAndLockPages(InputMdl, Irp->RequestorMode, + IoModifyAccess); + + InputMdlLocked = TRUE; + Status = STATUS_SUCCESS; + } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { + TI_DbgPrint(MAX_TRACE, ("Failed to acquire client buffer\n")); + Status = _SEH2_GetExceptionCode(); + } _SEH2_END; + + if( !NT_SUCCESS(Status) || !InputMdl ) { + if( InputMdl ) IoFreeMdl( InputMdl ); + ExFreePoolWithTag(QueryContext, QUERY_CONTEXT_TAG); + return Status; + } + + ASSERT(ValidInputLength <= sizeof(QueryContext->QueryInfo)); + RtlCopyMemory(&QueryContext->QueryInfo, + InputBuffer, ValidInputLength); + + QueryContext->Irp = Irp; + QueryContext->InputMdl = InputMdl; + QueryContext->OutputMdl = NULL; + + Request.RequestNotifyObject = DispTdiQueryInformationExComplete; + Request.RequestContext = QueryContext; + Status = InfoTdiQueryInformationEx(&Request, + &QueryContext->QueryInfo.ID, + NULL, + &Size, + &QueryContext->QueryInfo.Context); + DispTdiQueryInformationExComplete(QueryContext, Status, Size); + TI_DbgPrint(MAX_TRACE, ("Leaving. Status = (0x%X)\n", Status)); + } + else Status = STATUS_INVALID_PARAMETER; TI_DbgPrint(MIN_TRACE, ("Leaving. Status = (0x%X)\n", Status)); diff --git a/drivers/sac/driver/sacdrv.h b/drivers/sac/driver/sacdrv.h index 9c44671985fd8..035376d244ebc 100644 --- a/drivers/sac/driver/sacdrv.h +++ b/drivers/sac/driver/sacdrv.h @@ -1479,7 +1479,7 @@ typedef enum _VT_ANSI_ATTRIBUTES // // The following site is a good reference on VT100/ANSI escape codes -// http://www.termsys.demon.co.uk/vtansi.htm +// https://web.archive.org/web/20190503084310/http://www.termsys.demon.co.uk/vtansi.htm // #define VT_ANSI_ESCAPE L'\x1B' #define VT_ANSI_COMMAND L'[' diff --git a/drivers/sac/driver/util.c b/drivers/sac/driver/util.c index 0e0722f47948e..7f6e7956629b9 100644 --- a/drivers/sac/driver/util.c +++ b/drivers/sac/driver/util.c @@ -294,10 +294,10 @@ PreloadGlobalMessageTable(IN PVOID ImageBase) TotalLength = 0; for (MessageId = 1; MessageId != SAC_MAX_MESSAGES; MessageId++) { - /* Find this message ID in the string table*/ + /* Find this message in the message table */ Status2 = RtlFindMessage(ImageBase, - 11, - LANG_NEUTRAL, + RT_MESSAGETABLE, + MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), MessageId, &MessageEntry); if (NT_SUCCESS(Status2)) @@ -339,10 +339,10 @@ PreloadGlobalMessageTable(IN PVOID ImageBase) /* Now loop over our entries again */ for (i = 0, MessageId = 1; MessageId != SAC_MAX_MESSAGES; MessageId++) { - /* Make sure the message is still there...! */ + /* Make sure the message is still there! */ Status2 = RtlFindMessage(ImageBase, - 11, - LANG_NEUTRAL, + RT_MESSAGETABLE, + MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), MessageId, &MessageEntry); if (NT_SUCCESS(Status2)) diff --git a/drivers/serial/serial/devctrl.c b/drivers/serial/serial/devctrl.c index 74b81395c3458..76f2d8f95ce01 100644 --- a/drivers/serial/serial/devctrl.c +++ b/drivers/serial/serial/devctrl.c @@ -302,7 +302,7 @@ SerialDeviceControl( SerialGetUserBuffers(Irp, IoControlCode, &BufferIn, &BufferOut); /* FIXME: need to probe buffers */ - /* FIXME: see http://www.osronline.com/ddkx/serial/serref_61bm.htm */ + /* FIXME: see https://web.archive.org/web/20101020230420/http://www.osronline.com/ddkx/serial/serref_61bm.htm */ switch (IoControlCode) { case IOCTL_SERIAL_CLEAR_STATS: diff --git a/drivers/storage/floppy/floppy/floppy.h b/drivers/storage/floppy/floppy/floppy.h index 3dfd7c6316095..a0c23130a9980 100644 --- a/drivers/storage/floppy/floppy/floppy.h +++ b/drivers/storage/floppy/floppy/floppy.h @@ -107,7 +107,7 @@ StopMotor(PCONTROLLER_INFO ControllerInfo); /* * MEDIA TYPES * - * This table was found at http://www.nondot.org/sabre/os/files/Disk/FloppyMediaIDs.txt. + * This table was found at https://web.archive.org/web/20021207232702/http://www.nondot.org/sabre/os/files/Disk/FloppyMediaIDs.txt . * Thanks to raster@indirect.com for this information. * * Format Size Cyls Heads Sec/Trk FATs Sec/FAT Sec/Root Media diff --git a/drivers/storage/floppy/floppy/hardware.h b/drivers/storage/floppy/floppy/hardware.h index 21b1340d9c9a5..3b397dc503a51 100644 --- a/drivers/storage/floppy/floppy/hardware.h +++ b/drivers/storage/floppy/floppy/hardware.h @@ -24,7 +24,7 @@ * 15-Feb-2004 vizzini - Created * * NOTES: - * - Baesd on http://www.nondot.org/sabre/os/files/Disk/FLOPPY.TXT + * - Baesd on https://web.archive.org/web/20120130065947/http://www.nondot.org/sabre/os/files/Disk/FLOPPY.TXT * - Some information taken from Intel 82077AA data sheet (order #290166-007) * - Some definitions are PS/2-Specific; others include the original NEC PD765 * - Other information gathered from the comments in the NT 3.5 floppy driver diff --git a/drivers/storage/ide/uniata/scsi.h b/drivers/storage/ide/uniata/scsi.h index 9d85cf14d59bb..9a599114da3a5 100644 --- a/drivers/storage/ide/uniata/scsi.h +++ b/drivers/storage/ide/uniata/scsi.h @@ -1433,7 +1433,13 @@ typedef struct _READ_CAPACITY16_DATA { UCHAR Prot_EN:1; UCHAR RTO_EN:1; UCHAR Reserved:6; +#ifdef __REACTOS__ + /* In ReactOS SDK sizeof(READ_CAPACITY16_DATA) == 32. + * Fixes CORE-19696 memory corruption on SCSIOP_SERVICE_ACTION16. */ + UCHAR Reserved1[19]; +#else UCHAR Reserved1[20]; +#endif } READ_CAPACITY16_DATA, *PREAD_CAPACITY16_DATA; // CD ROM Read Table Of Contents (TOC) structures diff --git a/drivers/storage/mountmgr/device.c b/drivers/storage/mountmgr/device.c index ca8ed5c139569..7000d4a4218c5 100644 --- a/drivers/storage/mountmgr/device.c +++ b/drivers/storage/mountmgr/device.c @@ -637,7 +637,8 @@ MountMgrNextDriveLetter(IN PDEVICE_EXTENSION DeviceExtension, } DriveLetterTarget = (PMOUNTMGR_DRIVE_LETTER_TARGET)Irp->AssociatedIrp.SystemBuffer; - if (DriveLetterTarget->DeviceNameLength + sizeof(USHORT) > Stack->Parameters.DeviceIoControl.InputBufferLength) + if (FIELD_OFFSET(MOUNTMGR_DRIVE_LETTER_TARGET, DeviceName) + DriveLetterTarget->DeviceNameLength > + Stack->Parameters.DeviceIoControl.InputBufferLength) { return STATUS_INVALID_PARAMETER; } @@ -819,6 +820,7 @@ MountMgrQueryDosVolumePath(IN PDEVICE_EXTENSION DeviceExtension, PLIST_ENTRY SymlinksEntry; UNICODE_STRING SymbolicName; PMOUNTMGR_TARGET_NAME Target; + PMOUNTMGR_VOLUME_PATHS Output; PWSTR DeviceString, OldBuffer; USHORT DeviceLength, OldLength; PDEVICE_INFORMATION DeviceInformation; @@ -841,20 +843,20 @@ MountMgrQueryDosVolumePath(IN PDEVICE_EXTENSION DeviceExtension, } /* Validate the entry structure size */ - if ((FIELD_OFFSET(MOUNTMGR_TARGET_NAME, DeviceNameLength) + Target->DeviceNameLength) > + if (FIELD_OFFSET(MOUNTMGR_TARGET_NAME, DeviceName) + Target->DeviceNameLength > Stack->Parameters.DeviceIoControl.InputBufferLength) { return STATUS_INVALID_PARAMETER; } /* Ensure we can at least return needed size */ - if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG)) + if (Stack->Parameters.DeviceIoControl.OutputBufferLength < FIELD_OFFSET(MOUNTMGR_VOLUME_PATHS, MultiSz)) { return STATUS_INVALID_PARAMETER; } /* Construct string for query */ - SymbolicName.Length = Target->DeviceNameLength; + SymbolicName.Length = SymbolicName.MaximumLength = Target->DeviceNameLength; SymbolicName.Buffer = Target->DeviceName; @@ -885,20 +887,16 @@ MountMgrQueryDosVolumePath(IN PDEVICE_EXTENSION DeviceExtension, } } - /* We didn't find, break */ - if (SymlinksEntry == &(DeviceInformation->SymbolicLinksListHead)) - { - return STATUS_NOT_FOUND; - } + /* If we've found a device via drive letter, do default processing */ + if (SymlinksEntry != &(DeviceInformation->SymbolicLinksListHead)) + break; - /* It doesn't have associated device, go to fallback method */ + /* If it doesn't have an associated device, go to fallback method */ if (IsListEmpty(&DeviceInformation->AssociatedDevicesHead)) - { goto TryWithVolumeName; - } /* Create a string with the information about the device */ - AssociatedDevice = CONTAINING_RECORD(&(DeviceInformation->SymbolicLinksListHead), ASSOCIATED_DEVICE_ENTRY, AssociatedDevicesEntry); + AssociatedDevice = CONTAINING_RECORD(&(DeviceInformation->AssociatedDevicesHead), ASSOCIATED_DEVICE_ENTRY, AssociatedDevicesEntry); OldLength = DeviceLength; OldBuffer = DeviceString; DeviceLength += AssociatedDevice->String.Length; @@ -965,6 +963,7 @@ MountMgrQueryDosVolumePath(IN PDEVICE_EXTENSION DeviceExtension, if (DeviceString) { FreePool(DeviceString); + DeviceString = NULL; DeviceLength = 0; } @@ -992,46 +991,46 @@ MountMgrQueryDosVolumePath(IN PDEVICE_EXTENSION DeviceExtension, } RtlCopyMemory(DeviceString, SymlinkInformation->Name.Buffer, DeviceLength); - /* Ensure we are in the right namespace; [1] can be ? */ + /* Ensure we are in the Win32 namespace; [1] can be '?' */ DeviceString[1] = L'\\'; } } - /* If we found something */ - if (DeviceString) - { - /* At least, we will return our length */ - ((PMOUNTMGR_VOLUME_PATHS)Irp->AssociatedIrp.SystemBuffer)->MultiSzLength = DeviceLength; - /* MOUNTMGR_VOLUME_PATHS is a string + a ULONG */ - Irp->IoStatus.Information = DeviceLength + sizeof(ULONG); + /* If we didn't find something, fail */ + if (!DeviceString) + return STATUS_NOT_FOUND; - /* If we have enough room for copying the string */ - if (sizeof(ULONG) + DeviceLength <= Stack->Parameters.DeviceIoControl.OutputBufferLength) - { - /* Copy it */ - if (DeviceLength) - { - RtlCopyMemory(((PMOUNTMGR_VOLUME_PATHS)Irp->AssociatedIrp.SystemBuffer)->MultiSz, DeviceString, DeviceLength); - } + /* Get the output buffer */ + Output = (PMOUNTMGR_VOLUME_PATHS)Irp->AssociatedIrp.SystemBuffer; - /* And double zero at its end - this is needed in case of multiple paths which are separated by a single 0 */ - FreePool(DeviceString); - ((PMOUNTMGR_VOLUME_PATHS)Irp->AssociatedIrp.SystemBuffer)->MultiSz[DeviceLength / sizeof(WCHAR)] = 0; - ((PMOUNTMGR_VOLUME_PATHS)Irp->AssociatedIrp.SystemBuffer)->MultiSz[DeviceLength / sizeof(WCHAR) + 1] = 0; + /* At least, we will return our length */ + Output->MultiSzLength = DeviceLength + 2 * sizeof(UNICODE_NULL); + Irp->IoStatus.Information = FIELD_OFFSET(MOUNTMGR_VOLUME_PATHS, MultiSz) + Output->MultiSzLength; - return STATUS_SUCCESS; - } - else + /* If we have enough room for copying the string */ + if (Irp->IoStatus.Information <= Stack->Parameters.DeviceIoControl.OutputBufferLength) + { + /* Copy it */ + if (DeviceLength) { - /* Just return appropriate size and leave */ - FreePool(DeviceString); - Irp->IoStatus.Information = sizeof(ULONG); - return STATUS_BUFFER_OVERFLOW; + RtlCopyMemory(Output->MultiSz, DeviceString, DeviceLength); } - } - /* Fail */ - return STATUS_NOT_FOUND; + /* And double-NUL at its end - this is needed in case of + * multiple paths which are separated by a single NUL */ + FreePool(DeviceString); + Output->MultiSz[DeviceLength / sizeof(WCHAR)] = UNICODE_NULL; + Output->MultiSz[DeviceLength / sizeof(WCHAR) + 1] = UNICODE_NULL; + + return STATUS_SUCCESS; + } + else + { + /* Just return the size needed and leave */ + FreePool(DeviceString); + Irp->IoStatus.Information = FIELD_OFFSET(MOUNTMGR_VOLUME_PATHS, MultiSz); + return STATUS_BUFFER_OVERFLOW; + } } /* @@ -1467,20 +1466,21 @@ MountMgrQueryDosVolumePaths(IN PDEVICE_EXTENSION DeviceExtension, } /* Validate the entry structure size */ - if (Target->DeviceNameLength + FIELD_OFFSET(MOUNTMGR_TARGET_NAME, DeviceName) > Stack->Parameters.DeviceIoControl.InputBufferLength) + if (FIELD_OFFSET(MOUNTMGR_TARGET_NAME, DeviceName) + Target->DeviceNameLength > + Stack->Parameters.DeviceIoControl.InputBufferLength) { return STATUS_INVALID_PARAMETER; } /* Ensure we can at least return needed size */ - if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG)) + if (Stack->Parameters.DeviceIoControl.OutputBufferLength < FIELD_OFFSET(MOUNTMGR_VOLUME_PATHS, MultiSz)) { return STATUS_INVALID_PARAMETER; } /* Construct string for query */ - SymbolicName.Length = Target->DeviceNameLength; - SymbolicName.MaximumLength = Target->DeviceNameLength + sizeof(UNICODE_NULL); + SymbolicName.Length = + SymbolicName.MaximumLength = Target->DeviceNameLength; SymbolicName.Buffer = Target->DeviceName; /* Find device with our info */ @@ -1557,19 +1557,19 @@ MountMgrQueryDosVolumePaths(IN PDEVICE_EXTENSION DeviceExtension, MountMgrNotifyNameChange(DeviceExtension, &SymbolicName, FALSE); } - /* Get output buffer */ + /* Get the output buffer */ Output = (PMOUNTMGR_VOLUME_PATHS)Irp->AssociatedIrp.SystemBuffer; /* Set required size */ Output->MultiSzLength = Paths->MultiSzLength; /* Compute total length */ - OutputLength = Output->MultiSzLength + sizeof(ULONG); + OutputLength = FIELD_OFFSET(MOUNTMGR_VOLUME_PATHS, MultiSz) + Output->MultiSzLength; - /* If it cannot fit, just return need size and quit */ + /* If it cannot fit, just return the size needed and leave */ if (OutputLength > Stack->Parameters.DeviceIoControl.OutputBufferLength) { - Irp->IoStatus.Information = sizeof(ULONG); + Irp->IoStatus.Information = FIELD_OFFSET(MOUNTMGR_VOLUME_PATHS, MultiSz); FreePool(Paths); return STATUS_BUFFER_OVERFLOW; } @@ -1603,7 +1603,8 @@ MountMgrKeepLinksWhenOffline(IN PDEVICE_EXTENSION DeviceExtension, } Target = (PMOUNTMGR_TARGET_NAME)Irp->AssociatedIrp.SystemBuffer; - if (Target->DeviceNameLength + sizeof(USHORT) > Stack->Parameters.DeviceIoControl.InputBufferLength) + if (FIELD_OFFSET(MOUNTMGR_TARGET_NAME, DeviceName) + Target->DeviceNameLength > + Stack->Parameters.DeviceIoControl.InputBufferLength) { return STATUS_INVALID_PARAMETER; } @@ -1647,7 +1648,8 @@ MountMgrVolumeArrivalNotification(IN PDEVICE_EXTENSION DeviceExtension, } Target = (PMOUNTMGR_TARGET_NAME)Irp->AssociatedIrp.SystemBuffer; - if (Target->DeviceNameLength + sizeof(USHORT) > Stack->Parameters.DeviceIoControl.InputBufferLength) + if (FIELD_OFFSET(MOUNTMGR_TARGET_NAME, DeviceName) + Target->DeviceNameLength > + Stack->Parameters.DeviceIoControl.InputBufferLength) { return STATUS_INVALID_PARAMETER; } diff --git a/drivers/storage/mountmgr/mountmgr.c b/drivers/storage/mountmgr/mountmgr.c index 4e1552791bc5f..6603df3f53b58 100644 --- a/drivers/storage/mountmgr/mountmgr.c +++ b/drivers/storage/mountmgr/mountmgr.c @@ -995,7 +995,7 @@ MountMgrMountedDeviceArrival(IN PDEVICE_EXTENSION DeviceExtension, FreePool(UniqueId); FreePool(TargetDeviceName.Buffer); - FreePool(DeviceInformation->DeviceName.Buffer); + FreePool(DeviceInformation->SymbolicName.Buffer); FreePool(DeviceInformation); KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE); diff --git a/drivers/storage/partmgr/partition.c b/drivers/storage/partmgr/partition.c index c7763027951a0..3551898389fa6 100644 --- a/drivers/storage/partmgr/partition.c +++ b/drivers/storage/partmgr/partition.c @@ -27,21 +27,29 @@ PartitionCreateDevice( UNICODE_STRING deviceName; UINT32 volumeNum; - // create the device object - volumeNum = HarddiskVolumeNextId++; swprintf(nameBuf, L"\\Device\\HarddiskVolume%lu", volumeNum); RtlCreateUnicodeString(&deviceName, nameBuf); + /* + * Create the partition/volume device object. + * + * Due to the fact we are also a (basic) volume manager, this device is + * ALSO a volume device. Because of this, we need to assign it a device + * name, and a specific device type for IoCreateDevice() to create a VPB + * for this device, so that a filesystem can be mounted on it. + * Once we get a separate volume manager, this partition DO can become + * anonymous, have a different device type, and without any associated VPB. + * (The attached volume, on the contrary, would require a VPB.) + */ PDEVICE_OBJECT partitionDevice; NTSTATUS status = IoCreateDevice(FDObject->DriverObject, sizeof(PARTITION_EXTENSION), &deviceName, - FILE_DEVICE_DISK, + FILE_DEVICE_DISK, // FILE_DEVICE_MASS_STORAGE, FILE_DEVICE_SECURE_OPEN, FALSE, &partitionDevice); - if (!NT_SUCCESS(status)) { ERR("Unable to create device object %wZ\n", &deviceName); @@ -53,6 +61,13 @@ PartitionCreateDevice( PPARTITION_EXTENSION partExt = partitionDevice->DeviceExtension; RtlZeroMemory(partExt, sizeof(*partExt)); + partExt->DeviceObject = partitionDevice; + partExt->LowerDevice = FDObject; + + // NOTE: See comment above. + // PFDO_EXTENSION fdoExtension = FDObject->DeviceExtension; + // partitionDevice->DeviceType = /*fdoExtension->LowerDevice*/FDObject->DeviceType; + partitionDevice->StackSize = FDObject->StackSize; partitionDevice->Flags |= DO_DIRECT_IO; @@ -78,13 +93,10 @@ PartitionCreateDevice( partExt->DetectedNumber = PdoNumber; // counts only partitions with PDO created partExt->VolumeNumber = volumeNum; - partExt->DeviceObject = partitionDevice; - partExt->LowerDevice = FDObject; - + // The device is initialized partitionDevice->Flags &= ~DO_DEVICE_INITIALIZING; *PDO = partitionDevice; - return status; } @@ -136,11 +148,9 @@ PartitionHandleStartDevice( return status; } + INFO("Partition interface %wZ\n", &interfaceName); PartExt->PartitionInterfaceName = interfaceName; status = IoSetDeviceInterfaceState(&interfaceName, TRUE); - - INFO("Partition interface %wZ\n", &interfaceName); - if (!NT_SUCCESS(status)) { RtlFreeUnicodeString(&interfaceName); @@ -157,11 +167,9 @@ PartitionHandleStartDevice( return status; } + INFO("Volume interface %wZ\n", &interfaceName); PartExt->VolumeInterfaceName = interfaceName; status = IoSetDeviceInterfaceState(&interfaceName, TRUE); - - INFO("Volume interface %wZ\n", &interfaceName); - if (!NT_SUCCESS(status)) { RtlFreeUnicodeString(&interfaceName); @@ -772,6 +780,27 @@ PartitionHandleDeviceControl( status = STATUS_SUCCESS; break; } + case IOCTL_STORAGE_GET_DEVICE_NUMBER: + { + PSTORAGE_DEVICE_NUMBER deviceNumber = Irp->AssociatedIrp.SystemBuffer; + if (!VerifyIrpOutBufferSize(Irp, sizeof(*deviceNumber))) + { + status = STATUS_BUFFER_TOO_SMALL; + break; + } + + PartMgrAcquireLayoutLock(fdoExtension); + + deviceNumber->DeviceType = partExt->DeviceObject->DeviceType; + deviceNumber->DeviceNumber = fdoExtension->DiskData.DeviceNumber; + deviceNumber->PartitionNumber = partExt->DetectedNumber; + + PartMgrReleaseLayoutLock(fdoExtension); + + status = STATUS_SUCCESS; + Irp->IoStatus.Information = sizeof(*deviceNumber); + break; + } case IOCTL_STORAGE_MEDIA_REMOVAL: { return ForwardIrpAndForget(DeviceObject, Irp); diff --git a/drivers/storage/partmgr/partmgr.c b/drivers/storage/partmgr/partmgr.c index 8d3a175d91ab1..5b79d8238987c 100644 --- a/drivers/storage/partmgr/partmgr.c +++ b/drivers/storage/partmgr/partmgr.c @@ -340,7 +340,6 @@ PartMgrUpdatePartitionDevices( pdoNumber, NewLayout->PartitionStyle, &partitionDevice); - if (!NT_SUCCESS(status)) { partEntry->PartitionNumber = 0; @@ -948,8 +947,8 @@ FdoHandleStartDevice( _In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp) { - // obtain the disk device number - // this is not expected to change thus not in PartMgrRefreshDiskData + // Obtain the disk device number. + // It is not expected to change, thus not in PartMgrRefreshDiskData(). STORAGE_DEVICE_NUMBER deviceNumber; NTSTATUS status = IssueSyncIoControlRequest(IOCTL_STORAGE_GET_DEVICE_NUMBER, FdoExtension->LowerDevice, @@ -965,25 +964,22 @@ FdoHandleStartDevice( FdoExtension->DiskData.DeviceNumber = deviceNumber.DeviceNumber; - // register the disk interface - // partmgr.sys from Windows 8.1 also registers a mysterious GUID_DEVINTERFACE_HIDDEN_DISK here + // Register the disk interface. + // partmgr.sys from Windows 8.1 also registers a mysterious GUID_DEVINTERFACE_HIDDEN_DISK here. UNICODE_STRING interfaceName; status = IoRegisterDeviceInterface(FdoExtension->PhysicalDiskDO, &GUID_DEVINTERFACE_DISK, NULL, &interfaceName); - if(!NT_SUCCESS(status)) { ERR("Failed to register GUID_DEVINTERFACE_DISK, status %x\n", status); return status; } + INFO("Disk interface %wZ\n", &interfaceName); FdoExtension->DiskInterfaceName = interfaceName; status = IoSetDeviceInterfaceState(&interfaceName, TRUE); - - INFO("Disk interface %wZ\n", &interfaceName); - if (!NT_SUCCESS(status)) { RtlFreeUnicodeString(&interfaceName); @@ -1186,14 +1182,20 @@ PartMgrAddDevice( PAGED_CODE(); + /* + * Create the disk FDO. Use FILE_DEVICE_MASS_STORAGE type (or any other + * one that is NOT FILE_DEVICE_[DISK|VIRTUAL_DISK|CD_ROM|TAPE]), so that + * IoCreateDevice() doesn't automatically create a VPB for this device, + * even if we will later want this device to inherit the type of the + * underlying PDO which can have any of the types mentioned above. + */ NTSTATUS status = IoCreateDevice(DriverObject, sizeof(FDO_EXTENSION), - 0, - FILE_DEVICE_BUS_EXTENDER, + NULL, + FILE_DEVICE_MASS_STORAGE, FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN, FALSE, &deviceObject); - if (!NT_SUCCESS(status)) { ERR("Failed to create FDO 0x%x\n", status); @@ -1206,21 +1208,22 @@ PartMgrAddDevice( deviceExtension->IsFDO = TRUE; deviceExtension->DeviceObject = deviceObject; deviceExtension->LowerDevice = IoAttachDeviceToDeviceStack(deviceObject, PhysicalDeviceObject); - deviceExtension->PhysicalDiskDO = PhysicalDeviceObject; - KeInitializeEvent(&deviceExtension->SyncEvent, SynchronizationEvent, TRUE); - - // the the attaching failed if (!deviceExtension->LowerDevice) { + // The attachment failed IoDeleteDevice(deviceObject); - return STATUS_DEVICE_REMOVED; } + deviceExtension->PhysicalDiskDO = PhysicalDeviceObject; + KeInitializeEvent(&deviceExtension->SyncEvent, SynchronizationEvent, TRUE); + + // Update now the device type with the actual underlying device type + deviceObject->DeviceType = deviceExtension->LowerDevice->DeviceType; + deviceObject->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE; - // device is initialized + // The device is initialized deviceObject->Flags &= ~DO_DEVICE_INITIALIZING; - return STATUS_SUCCESS; } diff --git a/drivers/storage/port/scsiport/scsitypes.h b/drivers/storage/port/scsiport/scsitypes.h index 984c6db4e7acb..ef4f5c35023c0 100644 --- a/drivers/storage/port/scsiport/scsitypes.h +++ b/drivers/storage/port/scsiport/scsitypes.h @@ -1,6 +1,6 @@ -// see https://docs.microsoft.com/en-us/windows-hardware/drivers/install/identifiers-for-scsi-devices -// and https://docs.microsoft.com/en-us/windows-hardware/drivers/install/identifiers-for-ide-devices +// see https://learn.microsoft.com/en-us/windows-hardware/drivers/install/identifiers-for-scsi-devices +// and https://learn.microsoft.com/en-us/windows-hardware/drivers/install/identifiers-for-ide-devices FORCEINLINE PCSTR diff --git a/drivers/storage/port/storahci/storahci.c b/drivers/storage/port/storahci/storahci.c index bf4c96d04c18d..27cdc461acf97 100644 --- a/drivers/storage/port/storahci/storahci.c +++ b/drivers/storage/port/storahci/storahci.c @@ -806,7 +806,7 @@ AhciHwStartIo ( { case SRB_FUNCTION_PNP: { - // https://msdn.microsoft.com/windows/hardware/drivers/storage/handling-srb-function-pnp + // https://learn.microsoft.com/en-us/previous-versions/windows/drivers/storage/handling-srb-function-pnp // If the function member of an SRB is set to SRB_FUNCTION_PNP, // the SRB is a structure of type SCSI_PNP_REQUEST_BLOCK. @@ -843,7 +843,7 @@ AhciHwStartIo ( break; case SRB_FUNCTION_EXECUTE_SCSI: { - // https://msdn.microsoft.com/en-us/windows/hardware/drivers/storage/handling-srb-function-execute-scsi + // https://learn.microsoft.com/en-us/previous-versions/windows/drivers/storage/handling-srb-function-execute-scsi // On receipt of an SRB_FUNCTION_EXECUTE_SCSI request, a miniport driver's HwScsiStartIo // routine does the following: // diff --git a/drivers/storage/port/storahci/storahci.h b/drivers/storage/port/storahci/storahci.h index 40c08f2f4626f..f7be2f680cbdf 100644 --- a/drivers/storage/port/storahci/storahci.h +++ b/drivers/storage/port/storahci/storahci.h @@ -34,7 +34,7 @@ // section 3.1.2 #define AHCI_Global_HBA_CAP_S64A (1 << 31) -// FIS Types : http://wiki.osdev.org/AHCI +// FIS Types : https://wiki.osdev.org/AHCI #define FIS_TYPE_REG_H2D 0x27 // Register FIS - host to device #define FIS_TYPE_REG_D2H 0x34 // Register FIS - device to host #define FIS_TYPE_DMA_ACT 0x39 // DMA activate FIS - device to host diff --git a/drivers/usb/usbccgp/fdo.c b/drivers/usb/usbccgp/fdo.c index 833893b35098f..ea48824233a56 100644 --- a/drivers/usb/usbccgp/fdo.c +++ b/drivers/usb/usbccgp/fdo.c @@ -189,8 +189,15 @@ FDO_CreateChildPdo( } /* Create pdo for each function */ - for(Index = 0; Index < FDODeviceExtension->FunctionDescriptorCount; Index++) + for (Index = 0; Index < FDODeviceExtension->FunctionDescriptorCount; Index++) { + if (FDODeviceExtension->FunctionDescriptor[Index].NumberOfInterfaces == 0) + { + // Ignore invalid devices + DPRINT1("[USBCCGP] Found descriptor with 0 interfaces\n"); + continue; + } + /* Create the PDO */ Status = IoCreateDevice(FDODeviceExtension->DriverObject, sizeof(PDO_DEVICE_EXTENSION), diff --git a/drivers/usb/usbccgp/function.c b/drivers/usb/usbccgp/function.c index 63817c53728f9..a738edb052cd0 100644 --- a/drivers/usb/usbccgp/function.c +++ b/drivers/usb/usbccgp/function.c @@ -607,10 +607,10 @@ NTSTATUS USBCCGP_LegacyEnum( IN PDEVICE_OBJECT DeviceObject) { - ULONG Index; + ULONG Index, SubIndex; PFDO_DEVICE_EXTENSION FDODeviceExtension; NTSTATUS Status = STATUS_SUCCESS; - PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor; + PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor, NextInterfaceDescriptor; // // get device extension @@ -639,7 +639,7 @@ USBCCGP_LegacyEnum( // // init function descriptors // - FDODeviceExtension->FunctionDescriptorCount = 0; + FDODeviceExtension->FunctionDescriptorCount = FDODeviceExtension->ConfigurationDescriptor->bNumInterfaces; for (Index = 0; Index < FDODeviceExtension->ConfigurationDescriptor->bNumInterfaces; Index++) { // get interface descriptor @@ -654,24 +654,66 @@ USBCCGP_LegacyEnum( return STATUS_UNSUCCESSFUL; } - // - // init function descriptor - // - FDODeviceExtension->FunctionDescriptor[Index].FunctionNumber = Index; - FDODeviceExtension->FunctionDescriptor[Index].NumberOfInterfaces = 1; - FDODeviceExtension->FunctionDescriptor[Index].InterfaceDescriptorList = AllocateItem(NonPagedPool, sizeof(PUSB_INTERFACE_DESCRIPTOR) * 1); - if (!FDODeviceExtension->FunctionDescriptor[Index].InterfaceDescriptorList) + SubIndex = 0; + if (InterfaceDescriptor->bInterfaceClass == USB_DEVICE_CLASS_AUDIO) { + // AUDIO CLASS lets group all audio interfaces together + // + // init function descriptor + // + FDODeviceExtension->FunctionDescriptor[Index].FunctionNumber = Index; + FDODeviceExtension->FunctionDescriptor[Index].NumberOfInterfaces = 1; + FDODeviceExtension->FunctionDescriptor[Index].InterfaceDescriptorList = AllocateItem(NonPagedPool, sizeof(PUSB_INTERFACE_DESCRIPTOR) * FDODeviceExtension->ConfigurationDescriptor->bNumInterfaces); + if (!FDODeviceExtension->FunctionDescriptor[Index].InterfaceDescriptorList) + { + // + // no memory + // + FreeItem(FDODeviceExtension->FunctionDescriptor); + FDODeviceExtension->FunctionDescriptor = NULL; + FDODeviceExtension->FunctionDescriptorCount = 0; + return STATUS_INSUFFICIENT_RESOURCES; + } + // - // no memory + // store interface descriptor // - return STATUS_INSUFFICIENT_RESOURCES; + FDODeviceExtension->FunctionDescriptor[Index].InterfaceDescriptorList[SubIndex] = InterfaceDescriptor; + while (TRUE) + { + NextInterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(FDODeviceExtension->ConfigurationDescriptor, FDODeviceExtension->ConfigurationDescriptor, Index + SubIndex + 1, 0, -1, -1, -1); + if (!NextInterfaceDescriptor || NextInterfaceDescriptor->bInterfaceClass != USB_DEVICE_CLASS_AUDIO) + { + // end of collection + break; + } + SubIndex++; + ASSERT(SubIndex < FDODeviceExtension->ConfigurationDescriptor->bNumInterfaces); + FDODeviceExtension->FunctionDescriptor[Index].NumberOfInterfaces++; + FDODeviceExtension->FunctionDescriptor[Index].InterfaceDescriptorList[SubIndex] = NextInterfaceDescriptor; + } } + else + { + // + // init function descriptor + // + FDODeviceExtension->FunctionDescriptor[Index].FunctionNumber = Index; + FDODeviceExtension->FunctionDescriptor[Index].NumberOfInterfaces = 1; + FDODeviceExtension->FunctionDescriptor[Index].InterfaceDescriptorList = AllocateItem(NonPagedPool, sizeof(PUSB_INTERFACE_DESCRIPTOR)); + if (!FDODeviceExtension->FunctionDescriptor[Index].InterfaceDescriptorList) + { + // + // no memory + // + return STATUS_INSUFFICIENT_RESOURCES; + } - // - // store interface descriptor - // - FDODeviceExtension->FunctionDescriptor[Index].InterfaceDescriptorList[0] = InterfaceDescriptor; + // + // store interface descriptor + // + FDODeviceExtension->FunctionDescriptor[Index].InterfaceDescriptorList[0] = InterfaceDescriptor; + } // // now init the device ids @@ -685,11 +727,10 @@ USBCCGP_LegacyEnum( DPRINT1("[USBCCGP] Failed to init ids with %lx\n", Status); return Status; } - // - // store function count + // increment interface count // - FDODeviceExtension->FunctionDescriptorCount++; + Index += SubIndex; } // @@ -734,7 +775,7 @@ USBCCGP_EnumWithAudioLegacy( DPRINT1("Index %lu Descriptor %p\n", Index, InterfaceDescriptor); ASSERT(InterfaceDescriptor); - if (InterfaceDescriptor->bInterfaceClass != 0x1) + if (InterfaceDescriptor->bInterfaceClass != USB_DEVICE_CLASS_AUDIO) { // // collection contains non audio class diff --git a/drivers/usb/usbccgp/pdo.c b/drivers/usb/usbccgp/pdo.c index da73ed12ba6b4..514c441f74a8c 100644 --- a/drivers/usb/usbccgp/pdo.c +++ b/drivers/usb/usbccgp/pdo.c @@ -769,7 +769,8 @@ USBCCGP_PDOSelectConfiguration( Entry = NULL; do { - DPRINT1("[USBCCGP] SelectConfiguration Function %x InterfaceNumber %x Alternative %x Length %lu InterfaceInformation->Length %lu\n", PDODeviceExtension->FunctionDescriptor->FunctionNumber, InterfaceInformation->InterfaceNumber, InterfaceInformation->AlternateSetting, Length, InterfaceInformation->Length); + DPRINT1("[USBCCGP] SelectConfiguration Function %x InterfaceNumber %x Alternative %x Length %lu InterfaceInformation->Length %lu\n", + PDODeviceExtension->FunctionDescriptor->FunctionNumber, InterfaceInformation->InterfaceNumber, InterfaceInformation->AlternateSetting, Length, InterfaceInformation->Length); ASSERT(InterfaceInformation->Length); // // search for the interface in the local interface list diff --git a/drivers/usb/usbccgp/usbccgp.h b/drivers/usb/usbccgp/usbccgp.h index 04ce3493336d8..994df91cda139 100644 --- a/drivers/usb/usbccgp/usbccgp.h +++ b/drivers/usb/usbccgp/usbccgp.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include diff --git a/drivers/usb/usbport/endpoint.c b/drivers/usb/usbport/endpoint.c index 1a8d77e362c1c..699dac246708e 100644 --- a/drivers/usb/usbport/endpoint.c +++ b/drivers/usb/usbport/endpoint.c @@ -778,12 +778,13 @@ USBPORT_OpenPipe(IN PDEVICE_OBJECT FdoDevice, USBPORT_ENDPOINT_REQUIREMENTS EndpointRequirements = {0}; PUSBPORT_COMMON_BUFFER_HEADER HeaderBuffer; MPSTATUS MpStatus; - USBD_STATUS USBDStatus; + USBD_STATUS USBDStatus = USBD_STATUS_SUCCESS; NTSTATUS Status; KIRQL OldIrql; USHORT MaxPacketSize; USHORT AdditionalTransaction; BOOLEAN IsAllocatedBandwidth; + ULONG RetryCount; DPRINT1("USBPORT_OpenPipe: DeviceHandle - %p, FdoDevice - %p, PipeHandle - %p\n", DeviceHandle, @@ -1074,7 +1075,8 @@ USBPORT_OpenPipe(IN PDEVICE_OBJECT FdoDevice, KeReleaseSpinLock(&Endpoint->EndpointSpinLock, Endpoint->EndpointOldIrql); - while (TRUE) + /* Wait maximum 1 second for the endpoint to be active */ + for (RetryCount = 0; RetryCount < 1000; RetryCount++) { KeAcquireSpinLock(&Endpoint->EndpointSpinLock, &Endpoint->EndpointOldIrql); @@ -1091,6 +1093,11 @@ USBPORT_OpenPipe(IN PDEVICE_OBJECT FdoDevice, USBPORT_Wait(FdoDevice, 1); // 1 msec. } + if (State != USBPORT_ENDPOINT_ACTIVE) + { + DPRINT1("Timeout State %x\n", State); + USBDStatus = USBD_STATUS_TIMEOUT; + } } } else @@ -1103,10 +1110,6 @@ USBPORT_OpenPipe(IN PDEVICE_OBJECT FdoDevice, { USBDStatus = USBD_STATUS_INSUFFICIENT_RESOURCES; } - else - { - USBDStatus = USBD_STATUS_SUCCESS; - } } if (UsbdStatus) diff --git a/drivers/wdm/audio/drivers/CMIDriver/CMakeLists.txt b/drivers/wdm/audio/drivers/CMIDriver/CMakeLists.txt index 609babac1f4e4..e3fb6783068a6 100644 --- a/drivers/wdm/audio/drivers/CMIDriver/CMakeLists.txt +++ b/drivers/wdm/audio/drivers/CMIDriver/CMakeLists.txt @@ -30,6 +30,10 @@ if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") target_compile_options(cmipci PRIVATE -Wno-write-strings -Wno-switch) endif() +if(CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_compile_options(cmipci PRIVATE -Wno-enum-constexpr-conversion) +endif() + add_pch(cmipci precomp.h "${PCH_SKIP_SOURCE}") add_cd_file(TARGET cmipci DESTINATION reactos/system32/drivers FOR all) diff --git a/hal/halarm/generic/halinit.c b/hal/halarm/generic/halinit.c index 24836de2a2370..76adb5c16810a 100644 --- a/hal/halarm/generic/halinit.c +++ b/hal/halarm/generic/halinit.c @@ -16,20 +16,21 @@ /* PRIVATE FUNCTIONS **********************************************************/ +static +CODE_SEG("INIT") VOID -NTAPI -HalpGetParameters(IN PLOADER_PARAMETER_BLOCK LoaderBlock) +HalpGetParameters( + _In_ PLOADER_PARAMETER_BLOCK LoaderBlock) { - PCHAR CommandLine; - /* Make sure we have a loader block and command line */ - if ((LoaderBlock) && (LoaderBlock->LoadOptions)) + if (LoaderBlock && LoaderBlock->LoadOptions) { /* Read the command line */ - CommandLine = LoaderBlock->LoadOptions; + PCSTR CommandLine = LoaderBlock->LoadOptions; /* Check for initial breakpoint */ - if (strstr(CommandLine, "BREAK")) DbgBreakPoint(); + if (strstr(CommandLine, "BREAK")) + DbgBreakPoint(); } } @@ -38,15 +39,17 @@ HalpGetParameters(IN PLOADER_PARAMETER_BLOCK LoaderBlock) /* * @implemented */ +CODE_SEG("INIT") BOOLEAN NTAPI -HalInitSystem(IN ULONG BootPhase, - IN PLOADER_PARAMETER_BLOCK LoaderBlock) +HalInitSystem( + _In_ ULONG BootPhase, + _In_ PLOADER_PARAMETER_BLOCK LoaderBlock) { PKPRCB Prcb = KeGetCurrentPrcb(); /* Check the boot phase */ - if (!BootPhase) + if (BootPhase == 0) { /* Get command-line parameters */ HalpGetParameters(LoaderBlock); diff --git a/hal/halx86/apic/apic.c b/hal/halx86/apic/apic.c index ae2c2e5a4abeb..d98288b81e5f7 100644 --- a/hal/halx86/apic/apic.c +++ b/hal/halx86/apic/apic.c @@ -5,9 +5,9 @@ * PURPOSE: HAL APIC Management and Control Code * PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org) * REFERENCES: https://web.archive.org/web/20190407074221/http://www.joseflores.com/docs/ExploringIrql.html - * http://www.codeproject.com/KB/system/soviet_kernel_hack.aspx - * http://bbs.unixmap.net/thread-2022-1-1.html - * https://www.codemachine.com/article_interruptdispatching.html + * https://www.codeproject.com/KB/system/soviet_kernel_hack.aspx + * http://bbs.unixmap.net/thread-2022-1-1.html (DEAD_LINK) + * https://codemachine.com/articles/interrupt_dispatching.html * https://www.osronline.com/article.cfm%5Earticle=211.htm */ @@ -743,7 +743,6 @@ HalDisableSystemInterrupt( IOApicWrite(IOAPIC_REDTBL + 2 * Index, ReDirReg.Long0); } -#ifndef _M_AMD64 BOOLEAN NTAPI HalBeginSystemInterrupt( @@ -826,6 +825,7 @@ HalEndSystemInterrupt( /* IRQL MANAGEMENT ************************************************************/ +#ifndef _M_AMD64 KIRQL NTAPI KeGetCurrentIrql(VOID) diff --git a/hal/halx86/apic/halinit.c b/hal/halx86/apic/halinit.c index 7658f3d5074ad..8274fd5482492 100644 --- a/hal/halx86/apic/halinit.c +++ b/hal/halx86/apic/halinit.c @@ -58,6 +58,14 @@ HalpInitPhase0(IN PLOADER_PARAMETER_BLOCK LoaderBlock) CLOCK2_LEVEL, HalpClockInterrupt, Latched); + + /* Enable profile interrupt handler */ + HalpEnableInterruptHandler(IDT_DEVICE, + 0, + APIC_PROFILE_VECTOR, + PROFILE_LEVEL, + HalpProfileInterrupt, + Latched); } VOID diff --git a/hal/halx86/apic/rtctimer.c b/hal/halx86/apic/rtctimer.c index 5bdf6bf93c961..2f603077cda07 100644 --- a/hal/halx86/apic/rtctimer.c +++ b/hal/halx86/apic/rtctimer.c @@ -6,7 +6,7 @@ * PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org) * REFERENCES: https://wiki.osdev.org/RTC * https://forum.osdev.org/viewtopic.php?f=13&t=20825&start=0 - * http://www.bioscentral.com/misc/cmosmap.htm + * https://web.archive.org/web/20240119203005/http://www.bioscentral.com/misc/cmosmap.htm */ /* INCLUDES *******************************************************************/ @@ -156,7 +156,10 @@ HalpClockInterruptHandler(IN PKTRAP_FRAME TrapFrame) if (!HalBeginSystemInterrupt(CLOCK_LEVEL, APIC_CLOCK_VECTOR, &Irql)) { /* Spurious, just end the interrupt */ +#ifdef _M_IX86 KiEoiHelper(TrapFrame); +#endif + return; } /* Read register C, so that the next interrupt can happen */ @@ -188,6 +191,9 @@ HalpClockInterruptHandler(IN PKTRAP_FRAME TrapFrame) /* Update the system time -- on x86 the kernel will exit this trap */ KeUpdateSystemTime(TrapFrame, LastIncrement, Irql); + + /* End the interrupt */ + KiEndInterrupt(Irql, TrapFrame); } VOID @@ -207,7 +213,10 @@ HalpClockIpiHandler(IN PKTRAP_FRAME TrapFrame) if (!HalBeginSystemInterrupt(CLOCK_LEVEL, CLOCK_IPI_VECTOR, &Irql)) { /* Spurious, just end the interrupt */ +#ifdef _M_IX86 KiEoiHelper(TrapFrame); +#endif + return; } /* Call the kernel to update runtimes */ diff --git a/hal/halx86/generic/halinit.c b/hal/halx86/generic/halinit.c index be32ed7644dd3..22561c199310e 100644 --- a/hal/halx86/generic/halinit.c +++ b/hal/halx86/generic/halinit.c @@ -14,28 +14,38 @@ /* GLOBALS *******************************************************************/ +//#ifdef CONFIG_SMP // FIXME: Reenable conditional once HAL is consistently compiled for SMP mode +BOOLEAN HalpOnlyBootProcessor; +//#endif BOOLEAN HalpPciLockSettings; /* PRIVATE FUNCTIONS *********************************************************/ +static CODE_SEG("INIT") VOID -NTAPI -HalpGetParameters(IN PLOADER_PARAMETER_BLOCK LoaderBlock) +HalpGetParameters( + _In_ PLOADER_PARAMETER_BLOCK LoaderBlock) { - PCHAR CommandLine; - /* Make sure we have a loader block and command line */ - if ((LoaderBlock) && (LoaderBlock->LoadOptions)) + if (LoaderBlock && LoaderBlock->LoadOptions) { /* Read the command line */ - CommandLine = LoaderBlock->LoadOptions; + PCSTR CommandLine = LoaderBlock->LoadOptions; + +//#ifdef CONFIG_SMP // FIXME: Reenable conditional once HAL is consistently compiled for SMP mode + /* Check whether we should only start one CPU */ + if (strstr(CommandLine, "ONECPU")) + HalpOnlyBootProcessor = TRUE; +//#endif /* Check if PCI is locked */ - if (strstr(CommandLine, "PCILOCK")) HalpPciLockSettings = TRUE; + if (strstr(CommandLine, "PCILOCK")) + HalpPciLockSettings = TRUE; /* Check for initial breakpoint */ - if (strstr(CommandLine, "BREAK")) DbgBreakPoint(); + if (strstr(CommandLine, "BREAK")) + DbgBreakPoint(); } } @@ -70,8 +80,9 @@ HalInitializeProcessor( CODE_SEG("INIT") BOOLEAN NTAPI -HalInitSystem(IN ULONG BootPhase, - IN PLOADER_PARAMETER_BLOCK LoaderBlock) +HalInitSystem( + _In_ ULONG BootPhase, + _In_ PLOADER_PARAMETER_BLOCK LoaderBlock) { PKPRCB Prcb = KeGetCurrentPrcb(); NTSTATUS Status; @@ -79,7 +90,7 @@ HalInitSystem(IN ULONG BootPhase, /* Check the boot phase */ if (BootPhase == 0) { - /* Phase 0... save bus type */ + /* Save bus type */ HalpBusType = LoaderBlock->u.I386.MachineType & 0xFF; /* Get command-line parameters */ diff --git a/hal/halx86/include/halp.h b/hal/halx86/include/halp.h index c1ee6a67cae9b..5c323ffbc02ee 100644 --- a/hal/halx86/include/halp.h +++ b/hal/halx86/include/halp.h @@ -586,10 +586,22 @@ HalInitializeBios( #ifdef _M_AMD64 #define KfLowerIrql KeLowerIrql #define KiEnterInterruptTrap(TrapFrame) /* We do all neccessary in asm code */ -#define KiEoiHelper(TrapFrame) return /* Just return to the caller */ -#define HalBeginSystemInterrupt(Irql, Vector, OldIrql) ((*(OldIrql) = PASSIVE_LEVEL), TRUE) #endif // _M_AMD64 +#ifdef _MINIHAL_ +#if defined(_M_IX86) || defined(_M_AMD64) +/* Use intrinsics for IA-32 and amd64 */ +#include + +#define READ_PORT_BUFFER_UCHAR(port, buffer, count) __inbytestring(H2I(port), buffer, count) +#define READ_PORT_BUFFER_USHORT(port, buffer, count) __inwordstring(H2I(port), buffer, count) +#define READ_PORT_BUFFER_ULONG(port, buffer, count) __indwordstring(H2I(port), buffer, count) +#define WRITE_PORT_BUFFER_UCHAR(port, buffer, count) __outbytestring(H2I(port), buffer, count) +#define WRITE_PORT_BUFFER_USHORT(port, buffer, count) __outwordstring(H2I(port), buffer, count) +#define WRITE_PORT_BUFFER_ULONG(port, buffer, count) __outdwordstring(H2I(port), buffer, count) +#endif +#endif + extern BOOLEAN HalpNMIInProgress; extern ADDRESS_USAGE HalpDefaultIoSpace; diff --git a/hal/halx86/minihal/CMakeLists.txt b/hal/halx86/minihal/CMakeLists.txt index d446bf3cc7b32..13faf2ee5fcc9 100644 --- a/hal/halx86/minihal/CMakeLists.txt +++ b/hal/halx86/minihal/CMakeLists.txt @@ -1,6 +1,10 @@ +# We need to define this here, because the target definitions are not +# passed to CL, when preprocessing the asm files on MSVC builds. +# See CORE-19847 +add_definitions(-D_MINIHAL_) + list(APPEND MINI_HAL_SOURCE - ../generic/portio.c ../legacy/bus/bushndlr.c ../legacy/bus/cmosbus.c ../legacy/bus/isabus.c @@ -39,6 +43,6 @@ endif() add_asm_files(mini_hal_asm ../generic/systimer.S) add_library(mini_hal ${MINI_HAL_SOURCE} ${mini_hal_asm}) -target_compile_definitions(mini_hal PRIVATE _MINIHAL_ _BLDR_ _NTSYSTEM_) +target_compile_definitions(mini_hal PRIVATE _BLDR_ _NTSYSTEM_) add_dependencies(mini_hal psdk bugcodes asm) add_pch(mini_hal ../include/hal.h MINI_HAL_SOURCE) diff --git a/hal/halx86/smp/i386/spinup.c b/hal/halx86/smp/i386/spinup.c index 12fbea168cb35..359cc30d657d0 100644 --- a/hal/halx86/smp/i386/spinup.c +++ b/hal/halx86/smp/i386/spinup.c @@ -16,6 +16,8 @@ /* GLOBALS *******************************************************************/ +extern BOOLEAN HalpOnlyBootProcessor; + extern PPROCESSOR_IDENTITY HalpProcessorIdentity; extern PHYSICAL_ADDRESS HalpLowStubPhysicalAddress; extern PVOID HalpLowStub; @@ -88,6 +90,11 @@ HalStartNextProcessor( _In_ PLOADER_PARAMETER_BLOCK LoaderBlock, _In_ PKPROCESSOR_STATE ProcessorState) { + /* Bail out if we only use the boot CPU */ + if (HalpOnlyBootProcessor) + return FALSE; + + /* Bail out if we have started all available CPUs */ if (HalpStartedProcessorCount == HalpApicInfoTable.ProcessorCount) return FALSE; diff --git a/media/doc/3rd Party Files.txt b/media/doc/3rd Party Files.txt index e8ae9ad70ade9..6266f7b09b5a2 100644 --- a/media/doc/3rd Party Files.txt +++ b/media/doc/3rd Party Files.txt @@ -31,18 +31,21 @@ Path: dll/3rdparty/libjpeg Used Version: 9d License: custom, BSD-like URL: http://www.ijg.org/ +Modifications: added .spec file Title: libpng Path: dll/3rdparty/libpng Used Version: 1.6.39 License: PNG Reference Library version 2 URL: http://libpng.sourceforge.net/ +Modifications: added .spec file Title: libtiff Path: dll/3rdparty/libtiff Used Version: 4.1.0 License: libtiff (https://spdx.org/licenses/libtiff.html) URL: http://www.simplesystems.org/libtiff/ +Modifications: added .spec file Title: Libxslt Path: dll/3rdparty/libxslt @@ -217,9 +220,9 @@ URL: https://savannah.nongnu.org/projects/lwip/ Title: FreeType Path: sdk/lib/3rdparty/freetype -Used Version: 2.9.0 +Used Version: 2.10.0 License: FTL (https://spdx.org/licenses/FTL.html) -URL: http://www.freetype.org +URL: https://freetype.org/ Title: dosfstools Path: sdk/lib/fslib/vfatlib/check diff --git a/media/doc/WINESYNC.txt b/media/doc/WINESYNC.txt index bf5b76bfb551e..3ca038f04d046 100644 --- a/media/doc/WINESYNC.txt +++ b/media/doc/WINESYNC.txt @@ -160,7 +160,7 @@ dll/win32/pdh # Synced to WineStaging-4.18 dll/win32/pidgen # Synced to WineStaging-4.18 dll/win32/powrprof # Forked at Wine-1.0rc5 dll/win32/printui # Synced to WineStaging-4.18 -dll/win32/propsys # Synced to WineStaging-4.18 +dll/win32/propsys # Synced to Wine-10.0 dll/win32/pstorec # Synced to WineStaging-3.3 dll/win32/qmgr # Synced to WineStaging-4.18 dll/win32/qmgrprxy # Synced to WineStaging-2.9 @@ -168,7 +168,7 @@ dll/win32/query # Synced to WineStaging-4.18 dll/win32/rasapi32 # Synced to WineStaging-3.3 dll/win32/regapi # Synced to WineStaging-5.7 dll/win32/resutils # Synced to WineStaging-3.3 -dll/win32/riched20 # Synced to WineStaging-4.18 +dll/win32/riched20 # Synced to Wine-6.10 dll/win32/riched32 # Synced to WineStaging-3.3 dll/win32/rpcrt4 # Synced to WineStaging-4.18 dll/win32/rsabase # Synced to WineStaging-3.3 @@ -206,8 +206,8 @@ dll/win32/version # Synced to WineStaging-4.18 dll/win32/vssapi # Synced to WineStaging-4.18 dll/win32/wbemdisp # Synced to WineStaging-4.18 dll/win32/wbemprox # Synced to WineStaging-4.18 -dll/win32/windowscodecs # Synced to WineStaging-4.18 -dll/win32/windowscodecsext # Synced to WineStaging-2.9 +dll/win32/windowscodecs # Synced to Wine-10.0 +dll/win32/windowscodecsext # Synced to Wine-10.0 dll/win32/winemp3.acm # Synced to WineStaging-4.18 dll/win32/wing32 # Synced to WineStaging-3.3 dll/win32/winhttp # Synced to WineStaging-4.18 @@ -267,9 +267,8 @@ check Wine current sources first as it may already be fixed. sdk/lib/3rdparty/strmbase # Synced to WineStaging-3.3 -sdk/lib/rtl/actctx.c # Synced to wine-5.18 -sdk/lib/rtl/timerqueue.c # Synced to wine-5.18 -sdk/lib/rtl/wait.c # Synced to wine-5.18 +sdk/lib/rtl/actctx.c # Synced to Wine-5.18 +sdk/lib/rtl/threadpool.c # Synced to Wine-9.7 advapi32 - dll/win32/advapi32/wine/cred.c # Synced to WineStaging-3.3 @@ -362,6 +361,9 @@ user32 - win32ss/user/user32/windows/text.c # Forked (lstr.c) win32ss/user/user32/windows/winpos.c # Forked + win32ss/user/user32_vista/input.c # Synced to Wine-10.0 + win32ss/user/user32_vista/misc.c # Synced to Wine-10.0 + win32ss/user/user32_vista/win.c # Synced to Wine-10.0 schannel.c dll/win32/schannel/schannel_wine.c # synced to wine-1.7.17 (secur32/schannel.c) dll/win32/schannel/secur32_wine.c # partial sync to wine-1.7.17 (secur32/secur32.c) diff --git a/media/fonts/ssee1255.fon b/media/fonts/ssee1255.fon index 87c4b6319fdeb..cadb9272ba1ce 100644 Binary files a/media/fonts/ssee1255.fon and b/media/fonts/ssee1255.fon differ diff --git a/media/fonts/ssee1256.fon b/media/fonts/ssee1256.fon index 8e3804388e89f..bf6198a73c685 100644 Binary files a/media/fonts/ssee1256.fon and b/media/fonts/ssee1256.fon differ diff --git a/media/fonts/ssee1257.fon b/media/fonts/ssee1257.fon index 65c819512ec7d..42e512576af60 100644 Binary files a/media/fonts/ssee1257.fon and b/media/fonts/ssee1257.fon differ diff --git a/media/fonts/ssee874.fon b/media/fonts/ssee874.fon index 4f6db4f0a9e0d..44877c4b05764 100644 Binary files a/media/fonts/ssee874.fon and b/media/fonts/ssee874.fon differ diff --git a/media/fonts/sserife.fon b/media/fonts/sserife.fon index 264757092cb8c..0216f63548df1 100644 Binary files a/media/fonts/sserife.fon and b/media/fonts/sserife.fon differ diff --git a/media/fonts/sserifeg.fon b/media/fonts/sserifeg.fon index fd7d539e7848c..b9e0cf4a2e5a3 100644 Binary files a/media/fonts/sserifeg.fon and b/media/fonts/sserifeg.fon differ diff --git a/media/fonts/sserifer.fon b/media/fonts/sserifer.fon index 600d9fe251d1b..e54b8a4822be6 100644 Binary files a/media/fonts/sserifer.fon and b/media/fonts/sserifer.fon differ diff --git a/media/fonts/sserifet.fon b/media/fonts/sserifet.fon index 6aa8dc2ddc977..801f75844f729 100644 Binary files a/media/fonts/sserifet.fon and b/media/fonts/sserifet.fon differ diff --git a/media/inf/CMakeLists.txt b/media/inf/CMakeLists.txt index 3d67b82f841f1..054f64c018033 100644 --- a/media/inf/CMakeLists.txt +++ b/media/inf/CMakeLists.txt @@ -18,6 +18,7 @@ list(APPEND INF_FILES machine.inf monitor.inf msmouse.inf + ndisuio.inf NET_NIC.inf nettcpip.inf ports.inf diff --git a/media/inf/ndisuio.inf b/media/inf/ndisuio.inf new file mode 100644 index 0000000000000..0439cfb700672 --- /dev/null +++ b/media/inf/ndisuio.inf @@ -0,0 +1,60 @@ +; NDISUIO.INF + +; Installation file for the NDIS Usermode I/O Protocol + +[Version] +Signature = "$Windows NT$" +;Signature = "$ReactOS$" +LayoutFile = layout.inf +Class = NetTrans +ClassGUID = {4D36E975-E325-11CE-BFC1-08002BE10318} +Provider = %ReactOS% +DriverVer = 04/12/2006,1.00 + +[Manufacturer] +%ReactOS% = ReactOS + +[ReactOS] +%NDISUIO_DisplayName% = Install, MS_NDISUIO + +;--------------------------- NDISUIO DRIVER ----------------------------- + +[Install] +Characteristics = 0x28 +AddReg = Inst_Ndi +CopyFiles = CopyFiles_Sys + +[Inst_Ndi.NT] +HKR,"Ndi","HelpText",0x00000000,"%NDISUIO_HelpText%" +HKR,"Ndi","Service",0x00000000,"Ndisuio" +HKR,"Ndi\Interfaces","UpperRange",0x00000000,"noupper" +HKR,"Ndi\Interfaces","LowerRange",0x00000000,"ndis4,ndis5" + +[Install.Services] +AddService = Ndisuio, , NDISUIO_Service_Inst + +[NDISUIO_Service_Inst] +DisplayName = "%NDISUIO_DisplayName%" +Description = "%NDISUIO_DisplayName%" +ServiceType = 1 +StartType = 1 +ErrorControl = 1 +ServiceBinary = %12%\ndisuio.sys +LoadOrderGroup = NDIS + +[CopyFiles_Sys] +ndisuio.sys + +;-------------------------------- STRINGS ------------------------------- + +[Strings] +; Non-localizable +ReactOS = "ReactOS Project" + +; Localizable +NDISUIO_DisplayName = "NDIS Usermode I/O Protocol" +NDISUIO_HelpText = "A driver that supports the NDIS Usermode I/O Protocol." + +[Strings.0409] +NDISUIO_DisplayName = "NDIS Benutzermodus E/A Protokoll" +NDISUIO_HelpText = "Ein Treiber, der das NDIS Benutzermodus E/A Protokoll unterstützt." diff --git a/media/inf/syssetup.inf b/media/inf/syssetup.inf index 1ef4a04bc3dd3..5f12090cba105 100644 --- a/media/inf/syssetup.inf +++ b/media/inf/syssetup.inf @@ -20,7 +20,6 @@ machine.inf monitor.inf msmouse.inf NET_NIC.inf -nettcpip.inf ports.inf scsi.inf unknown.inf diff --git a/media/sounds/CMakeLists.txt b/media/sounds/CMakeLists.txt index 03da1c51adce1..952de0b9353e0 100644 --- a/media/sounds/CMakeLists.txt +++ b/media/sounds/CMakeLists.txt @@ -1,5 +1,5 @@ add_cd_file(FILE ${CMAKE_CURRENT_SOURCE_DIR}/ReactOS_Critical_Stop.wav DESTINATION reactos/media FOR all) -add_cd_file(FILE ${CMAKE_CURRENT_SOURCE_DIR}/ReactOS_LogOn.wav DESTINATION reactos/media FOR all) +add_cd_file(FILE ${CMAKE_CURRENT_SOURCE_DIR}/ReactOS_Startup.wav DESTINATION reactos/media FOR all) add_cd_file(FILE ${CMAKE_CURRENT_SOURCE_DIR}/ReactOS_Notify.wav DESTINATION reactos/media FOR all) add_cd_file(FILE ${CMAKE_CURRENT_SOURCE_DIR}/ReactOS_Recycle.wav DESTINATION reactos/media FOR all) diff --git a/media/sounds/ReactOS_LogOn.wav b/media/sounds/ReactOS_Startup.wav similarity index 100% rename from media/sounds/ReactOS_LogOn.wav rename to media/sounds/ReactOS_Startup.wav diff --git a/media/themes/Blackshade/blackshade.msstyles/blackshade.rc b/media/themes/Blackshade/blackshade.msstyles/blackshade.rc index cc2fbe0ef80f8..8aaff97d4be52 100644 --- a/media/themes/Blackshade/blackshade.msstyles/blackshade.rc +++ b/media/themes/Blackshade/blackshade.msstyles/blackshade.rc @@ -181,6 +181,7 @@ NORMAL_IE_PERSONALBARMENU_BMP BITMAP "bitmaps/dummy.bmp" NORMAL_NORMALGROUPCOLLAPSE_BMP BITMAP "bitmaps/dummy.bmp" NORMAL_NORMALGROUPEXPAND_BMP BITMAP "bitmaps/dummy.bmp" +/* UTF-8 */ #pragma code_page(65001) #ifdef LANGUAGE_DE_DE diff --git a/media/themes/Lautus/lautus.msstyles/lautus.rc b/media/themes/Lautus/lautus.msstyles/lautus.rc index 0a464970291a8..304f7a381b4ef 100644 --- a/media/themes/Lautus/lautus.msstyles/lautus.rc +++ b/media/themes/Lautus/lautus.msstyles/lautus.rc @@ -197,6 +197,7 @@ NORMAL_IE_PERSONALBARMENU_BMP BITMAP "bitmaps/dummy.bmp" NORMAL_NORMALGROUPCOLLAPSE_BMP BITMAP "bitmaps/dummy.bmp" NORMAL_NORMALGROUPEXPAND_BMP BITMAP "bitmaps/dummy.bmp" +/* UTF-8 */ #pragma code_page(65001) #ifdef LANGUAGE_CS_CZ diff --git a/media/themes/Lunar/lunar.msstyles/lunar.rc b/media/themes/Lunar/lunar.msstyles/lunar.rc index 1b0236bf0b233..b9a91d6bf7e5b 100644 --- a/media/themes/Lunar/lunar.msstyles/lunar.rc +++ b/media/themes/Lunar/lunar.msstyles/lunar.rc @@ -176,6 +176,7 @@ NORMAL_IE_PERSONALBARMENU_BMP BITMAP "bitmaps/dummy.bmp" NORMAL_NORMALGROUPCOLLAPSE_BMP BITMAP "bitmaps/dummy.bmp" NORMAL_NORMALGROUPEXPAND_BMP BITMAP "bitmaps/dummy.bmp" +/* UTF-8 */ #pragma code_page(65001) #ifdef LANGUAGE_CS_CZ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_CHECKBOX13.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_CHECKBOX13.bmp index 805c1491c042d..41defdd95c795 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_CHECKBOX13.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_CHECKBOX13.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_CHECKBOX16.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_CHECKBOX16.bmp index 03c3a5a121f29..c38e0efea21b4 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_CHECKBOX16.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_CHECKBOX16.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_CHECKBOX25.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_CHECKBOX25.bmp index 346bd18b8fcb7..c2492c3176fa2 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_CHECKBOX25.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_CHECKBOX25.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_EXPLORERBARTOOLBARBUTTONS.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_EXPLORERBARTOOLBARBUTTONS.bmp index 5888461ebe8bd..f14d005932220 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_EXPLORERBARTOOLBARBUTTONS.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_EXPLORERBARTOOLBARBUTTONS.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_EXPLORERBARTOOLBARBUTTONSSPLIT.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_EXPLORERBARTOOLBARBUTTONSSPLIT.bmp index 4ede86ebe0b9c..24cced5511319 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_EXPLORERBARTOOLBARBUTTONSSPLIT.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_EXPLORERBARTOOLBARBUTTONSSPLIT.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_EXPLORERBARTOOLBARBUTTONSSPLITDROPDOWN.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_EXPLORERBARTOOLBARBUTTONSSPLITDROPDOWN.bmp index 55b77ffc388be..637d30fcf68c7 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_EXPLORERBARTOOLBARBUTTONSSPLITDROPDOWN.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_EXPLORERBARTOOLBARBUTTONSSPLITDROPDOWN.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_LISTVIEWHEADER.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_LISTVIEWHEADER.bmp index 0ef05d968b206..951eda3794bc3 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_LISTVIEWHEADER.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_LISTVIEWHEADER.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_LISTVIEWHEADERBACKGROUND.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_LISTVIEWHEADERBACKGROUND.bmp index 43135e8bdf6b7..a885fcb1929d7 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_LISTVIEWHEADERBACKGROUND.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_LISTVIEWHEADERBACKGROUND.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_PLACEBARBUTTONS.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_PLACEBARBUTTONS.bmp index 1a02a536115dd..ddf5c5d15d7ba 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_PLACEBARBUTTONS.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_PLACEBARBUTTONS.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_PROGRESSTRACK.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_PROGRESSTRACK.bmp index 9c7a9531de939..a92ecc31841bc 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_PROGRESSTRACK.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_PROGRESSTRACK.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_PROGRESSTRACKVERT.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_PROGRESSTRACKVERT.bmp index 599d3884a138f..834a5b8df6e3c 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_PROGRESSTRACKVERT.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_PROGRESSTRACKVERT.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_RADIOBUTTON13.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_RADIOBUTTON13.bmp index fb04f5944d10d..34f1839d6ab00 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_RADIOBUTTON13.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_RADIOBUTTON13.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_SPINBUTTONBACKGROUNDDOWN.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_SPINBUTTONBACKGROUNDDOWN.bmp index 7d1af69944df5..b0b999ce68e4a 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_SPINBUTTONBACKGROUNDDOWN.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_SPINBUTTONBACKGROUNDDOWN.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_SPINBUTTONBACKGROUNDLEFT.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_SPINBUTTONBACKGROUNDLEFT.bmp index fcbf995e72660..e670ac501f984 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_SPINBUTTONBACKGROUNDLEFT.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_SPINBUTTONBACKGROUNDLEFT.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_SPINBUTTONBACKGROUNDRIGHT.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_SPINBUTTONBACKGROUNDRIGHT.bmp index d688e83fceef9..c9dcc07b3f6fa 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_SPINBUTTONBACKGROUNDRIGHT.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_SPINBUTTONBACKGROUNDRIGHT.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_SPINBUTTONBACKGROUNDUP.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_SPINBUTTONBACKGROUNDUP.bmp index 233f13310718d..116858b2f3b8e 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_SPINBUTTONBACKGROUNDUP.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_SPINBUTTONBACKGROUNDUP.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_SPINDOWNGLYPH.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_SPINDOWNGLYPH.bmp index b8e28c54c8d28..f8fe1e1f005a9 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_SPINDOWNGLYPH.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_SPINDOWNGLYPH.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_SPINLEFTGLYPH.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_SPINLEFTGLYPH.bmp index da3c072d81b37..f3576b54d85c8 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_SPINLEFTGLYPH.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_SPINLEFTGLYPH.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_SPINRIGHTGLYPH.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_SPINRIGHTGLYPH.bmp index 3c924e92d9a2e..33133af99f842 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_SPINRIGHTGLYPH.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_SPINRIGHTGLYPH.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_SPINUPGLYPH.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_SPINUPGLYPH.bmp index ac976922bd35f..0ca8d15b8883d 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_SPINUPGLYPH.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_SPINUPGLYPH.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TABITEM.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TABITEM.bmp index 9e039c70b4cf6..c8edbfd5ace98 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TABITEM.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TABITEM.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TABITEMBOTH.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TABITEMBOTH.bmp index 9fe7a5f77f205..c8edbfd5ace98 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TABITEMBOTH.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TABITEMBOTH.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TABITEMLEFT.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TABITEMLEFT.bmp index 4fa99935b35e5..2dc212b529eb0 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TABITEMLEFT.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TABITEMLEFT.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TABITEMRIGHT.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TABITEMRIGHT.bmp index f7b4a01546633..7597601607541 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TABITEMRIGHT.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TABITEMRIGHT.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TABITEMTOP.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TABITEMTOP.bmp index 4a6d4049298cf..c8edbfd5ace98 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TABITEMTOP.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TABITEMTOP.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TABITEMTOPBOTH.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TABITEMTOPBOTH.bmp index 92473af5aecf5..c8edbfd5ace98 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TABITEMTOPBOTH.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TABITEMTOPBOTH.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TABITEMTOPLEFT.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TABITEMTOPLEFT.bmp index b038a795a8d28..2dc212b529eb0 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TABITEMTOPLEFT.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TABITEMTOPLEFT.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TABITEMTOPRIGHT.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TABITEMTOPRIGHT.bmp index 92473af5aecf5..7597601607541 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TABITEMTOPRIGHT.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TABITEMTOPRIGHT.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TASKBANDBUTTONVERTICAL.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TASKBANDBUTTONVERTICAL.bmp index b1b30aac4fd0d..a6cce18e94921 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TASKBANDBUTTONVERTICAL.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TASKBANDBUTTONVERTICAL.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TASKBANDFLASHBUTTON.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TASKBANDFLASHBUTTON.bmp index 13f8c7eabcf27..78ef2df73e12e 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TASKBANDFLASHBUTTON.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TASKBANDFLASHBUTTON.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TASKBANDSCROLLARROWS.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TASKBANDSCROLLARROWS.bmp index 28ff67af7cc61..4da4c42471cfa 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TASKBANDSCROLLARROWS.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TASKBANDSCROLLARROWS.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TASKBANDSCROLLSHAFTHORIZONTAL.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TASKBANDSCROLLSHAFTHORIZONTAL.bmp index 269e6ae3043f5..112873e8b081a 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TASKBANDSCROLLSHAFTHORIZONTAL.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TASKBANDSCROLLSHAFTHORIZONTAL.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TASKBANDSCROLLSHAFTVERTICAL.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TASKBANDSCROLLSHAFTVERTICAL.bmp index 7330949f3a68d..c162d591a6113 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TASKBANDSCROLLSHAFTVERTICAL.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TASKBANDSCROLLSHAFTVERTICAL.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TASKBANDSCROLLTHUMBHORIZONTAL.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TASKBANDSCROLLTHUMBHORIZONTAL.bmp index 8ced93149769b..885355fe3d0d8 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TASKBANDSCROLLTHUMBHORIZONTAL.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TASKBANDSCROLLTHUMBHORIZONTAL.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TASKBANDSCROLLTHUMBVERTICAL.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TASKBANDSCROLLTHUMBVERTICAL.bmp index 0174ac3c4c9e1..3a600f74889e0 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TASKBANDSCROLLTHUMBVERTICAL.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TASKBANDSCROLLTHUMBVERTICAL.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TASKBARSIZINGBARBOTTOM.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TASKBARSIZINGBARBOTTOM.bmp index f7d9b90c5235a..842d2431ef19f 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TASKBARSIZINGBARBOTTOM.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TASKBARSIZINGBARBOTTOM.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TOOLBARBUTTONS.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TOOLBARBUTTONS.bmp index d56e2229fe581..b0490900363a5 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TOOLBARBUTTONS.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TOOLBARBUTTONS.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TOOLBARBUTTONSSPLIT.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TOOLBARBUTTONSSPLIT.bmp index 3f59a20bd486c..fdae43feeec2e 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TOOLBARBUTTONSSPLIT.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TOOLBARBUTTONSSPLIT.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TOOLBARBUTTONSSPLITDROPDOWN.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TOOLBARBUTTONSSPLITDROPDOWN.bmp index 2df902d84598d..b41e582d1cb31 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TOOLBARBUTTONSSPLITDROPDOWN.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TOOLBARBUTTONSSPLITDROPDOWN.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARDOWN13.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARDOWN13.bmp index 367fa1bdd9572..25fcffe1c1630 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARDOWN13.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARDOWN13.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARDOWN16.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARDOWN16.bmp index d714c2dce589e..c0950feb39e86 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARDOWN16.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARDOWN16.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARDOWN25.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARDOWN25.bmp index 3b34cde2ed6ed..b08983adc69cf 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARDOWN25.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARDOWN25.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARHORIZONTAL.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARHORIZONTAL.bmp index c6ea57b81cfa0..4d2f395100a94 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARHORIZONTAL.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARHORIZONTAL.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARLEFT13.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARLEFT13.bmp index d6d7e6105642c..bbadab676f8bd 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARLEFT13.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARLEFT13.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARLEFT16.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARLEFT16.bmp index 9f340d109cb1e..48be61cd2d966 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARLEFT16.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARLEFT16.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARLEFT25.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARLEFT25.bmp index 9a47c92f171a1..b16c575eea68f 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARLEFT25.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARLEFT25.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARRIGHT13.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARRIGHT13.bmp index 6bbfba4415b9e..82e9671c63ee1 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARRIGHT13.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARRIGHT13.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARRIGHT16.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARRIGHT16.bmp index 3c00e7bd5caa0..50406eded3666 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARRIGHT16.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARRIGHT16.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARRIGHT25.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARRIGHT25.bmp index e89bb211cddcd..1aa7e3e9737b2 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARRIGHT25.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARRIGHT25.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARUP13.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARUP13.bmp index d3effbb3d85f1..98c2ed4bb4ea6 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARUP13.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARUP13.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARUP16.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARUP16.bmp index 8f9a613cc5189..cfeb6522fbb69 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARUP16.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARUP16.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARUP25.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARUP25.bmp index 67acb26ba7be9..d69d4ff6f5ea2 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARUP25.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARUP25.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARVERTICAL.bmp b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARVERTICAL.bmp index cacb0df37f95a..9075a5263ae4f 100644 Binary files a/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARVERTICAL.bmp and b/media/themes/Mizu/mizu.msstyles/bitmaps/NORMAL_TRACKBARVERTICAL.bmp differ diff --git a/media/themes/Mizu/mizu.msstyles/mizu.rc b/media/themes/Mizu/mizu.msstyles/mizu.rc index db738797849f5..1522e96bc806b 100644 --- a/media/themes/Mizu/mizu.msstyles/mizu.rc +++ b/media/themes/Mizu/mizu.msstyles/mizu.rc @@ -183,6 +183,7 @@ NORMAL_IE_PERSONALBARMENU_BMP BITMAP "bitmaps/dummy.bmp" NORMAL_NORMALGROUPCOLLAPSE_BMP BITMAP "bitmaps/dummy.bmp" NORMAL_NORMALGROUPEXPAND_BMP BITMAP "bitmaps/dummy.bmp" +/* UTF-8 */ #pragma code_page(65001) #ifdef LANGUAGE_CS_CZ diff --git a/media/themes/Modern/modern.msstyles/modern.rc b/media/themes/Modern/modern.msstyles/modern.rc index 166a8d8b617f9..d065c17ef91b2 100644 --- a/media/themes/Modern/modern.msstyles/modern.rc +++ b/media/themes/Modern/modern.msstyles/modern.rc @@ -406,8 +406,9 @@ DARK_TREEEXPANDCOLLAPSE15_BMP BITMAP "bitmaps/Dark/DARK_TREEEXPANDCOLLAPSE15.bm DARK_TREEEXPANDCOLLAPSE_BMP BITMAP "bitmaps/Dark/DARK_TREEEXPANDCOLLAPSE.bmp" DARK_USERTILEBACKGROUND_BMP BITMAP "bitmaps/Dark/DARK_USERTILEBACKGROUND.bmp" - +/* UTF-8 */ #pragma code_page(65001) + #ifdef LANGUAGE_CS_CZ #include "lang/cs-CZ.rc" #endif diff --git a/modules/rosapps/applications/devutils/CMakeLists.txt b/modules/rosapps/applications/devutils/CMakeLists.txt index 446fbc1ea74d4..2ffa876e181c3 100644 --- a/modules/rosapps/applications/devutils/CMakeLists.txt +++ b/modules/rosapps/applications/devutils/CMakeLists.txt @@ -3,6 +3,7 @@ add_subdirectory(createspec) add_subdirectory(gdb2) add_subdirectory(gdihv) add_subdirectory(genguid) +add_subdirectory(lnktool) add_subdirectory(nls2txt) add_subdirectory(shimdbg) add_subdirectory(shimtest_ros) diff --git a/modules/rosapps/applications/devutils/createspec/createspec.c b/modules/rosapps/applications/devutils/createspec/createspec.c index 9f5de70a4a771..4873d7ae9a1c3 100644 --- a/modules/rosapps/applications/devutils/createspec/createspec.c +++ b/modules/rosapps/applications/devutils/createspec/createspec.c @@ -1,7 +1,7 @@ /* - Info: - http://stackoverflow.com/questions/32251638/dbghelp-get-full-symbol-signature-function-name-parameters-types - - http://www.debuginfo.com/articles/dbghelptypeinfo.html + - https://www.debuginfo.com/articles/dbghelptypeinfo.html - TODO: - Dump usage - Test for dbghelp + symsrv and warn if not working diff --git a/modules/rosapps/applications/devutils/lnktool/CMakeLists.txt b/modules/rosapps/applications/devutils/lnktool/CMakeLists.txt new file mode 100644 index 0000000000000..009f746e742c3 --- /dev/null +++ b/modules/rosapps/applications/devutils/lnktool/CMakeLists.txt @@ -0,0 +1,7 @@ + +add_executable(lnktool lnktool.cpp lnktool.rc) + +set_module_type(lnktool win32cui UNICODE) +target_link_libraries(lnktool uuid) +add_importlibs(lnktool ole32 comctl32 shell32 shlwapi advapi32 user32 msvcrt kernel32) +add_cd_file(TARGET lnktool DESTINATION reactos/system32 FOR all) diff --git a/modules/rosapps/applications/devutils/lnktool/lnktool.cpp b/modules/rosapps/applications/devutils/lnktool/lnktool.cpp new file mode 100644 index 0000000000000..32499fcdf07c6 --- /dev/null +++ b/modules/rosapps/applications/devutils/lnktool/lnktool.cpp @@ -0,0 +1,874 @@ +/* + * PROJECT: lnktool + * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) + * PURPOSE: ShellLink (.lnk) utility + * COPYRIGHT: Copyright 2025 Whindmar Saksit + */ + +#define INDENT " " +static const char g_Usage[] = "" + "lnktool [Options]\n" + "\n" + "Create Options:\n" + "/Pidl \n" + "/Path \n" + "/Icon \n" + "/Arguments \n" + "/RelativePath \n" + "/WorkingDir \n" + "/Comment \n" + "/ShowCmd \n" + "/SpecialFolderOffset \n" + "/AddExp \n" + "/AddExpIcon \n" + "/RemoveExpIcon\n" // Removes the EXP_SZ_ICON block and flag + "/AddSLDF \n" + "/RemoveSLDF \n"; + +#include +#include +#include +#include +#include // For shellutils.h (sprintf) +#include +#include +#include // SHELL_LINK_HEADER + +enum { slgp_relativepriority = 0x08 }; +#define PT_DESKTOP_REGITEM 0x1F +#define PT_COMPUTER_REGITEM 0x2E +#define PT_FS 0x30 +#define PT_FS_UNICODE_FLAG 0x04 + +static const struct { UINT Flag; PCSTR Name; } g_SLDF[] = +{ + { SLDF_HAS_ID_LIST, "IDLIST" }, + { SLDF_HAS_LINK_INFO, "LINKINFO" }, + { SLDF_HAS_NAME, "NAME" }, + { SLDF_HAS_RELPATH, "RELPATH" }, + { SLDF_HAS_WORKINGDIR, "WORKINGDIR" }, + { SLDF_HAS_ARGS, "ARGS" }, + { SLDF_HAS_ICONLOCATION, "ICONLOCATION" }, + { SLDF_UNICODE, "UNICODE" }, + { SLDF_FORCE_NO_LINKINFO, "FORCE_NO_LINKINFO" }, + { SLDF_HAS_EXP_SZ, "EXP_SZ" }, + { SLDF_RUN_IN_SEPARATE, "RUN_IN_SEPARATE" }, + { 0x00000800, "LOGO3ID" }, + { SLDF_HAS_DARWINID, "DARWINID" }, + { SLDF_RUNAS_USER, "RUNAS_USER" }, + { SLDF_HAS_EXP_ICON_SZ, "EXP_ICON_SZ" }, + { SLDF_NO_PIDL_ALIAS, "NO_PIDL_ALIAS" }, + { SLDF_FORCE_UNCNAME, "FORCE_UNCNAME" }, + { SLDF_RUN_WITH_SHIMLAYER, "RUN_WITH_SHIMLAYER" }, + { 0x00040000, "FORCE_NO_LINKTRACK" }, + { 0x00080000, "ENABLE_TARGET_METADATA" }, + { 0x00100000, "DISABLE_LINK_PATH_TRACKING" }, + { 0x00200000, "DISABLE_KNOWNFOLDER_RELATIVE_TRACKING" }, + { 0x00400000, "NO_KF_ALIAS" }, + { 0x00800000, "ALLOW_LINK_TO_LINK" }, + { 0x01000000, "UNALIAS_ON_SAVE" }, + { 0x02000000, "PREFER_ENVIRONMENT_PATH" }, + { 0x04000000, "KEEP_LOCAL_IDLIST_FOR_UNC_TARGET" }, + { 0x08000000, "PERSIST_VOLUME_ID_RELATIVE" }, +}; + +static const struct { UINT Flag; PCSTR Name; } g_DBSig[] = +{ + { EXP_SZ_LINK_SIG, "SZ_LINK" }, + { EXP_SZ_ICON_SIG, "SZ_ICON" }, + { EXP_SPECIAL_FOLDER_SIG, "SPECIALFOLDER" }, + { EXP_TRACKER_SIG, "TRACKER" }, + { 0xA0000009, "PROPERTYSTORAGE" }, + { EXP_KNOWN_FOLDER_SIG, "KNOWNFOLDER" }, + { EXP_VISTA_ID_LIST_SIG, "VISTAPIDL" }, +}; + +static LONG StrToNum(PCWSTR in) +{ + PWCHAR end; + LONG v = wcstol(in, &end, 0); + if (v == LONG_MAX) + v = wcstoul(in, &end, 0); + return (end > in) ? v : 0; +} + +template +static UINT MapToNumber(PCWSTR Name, const T &Map) +{ + CHAR buf[200]; + WideCharToMultiByte(CP_ACP, 0, Name, -1, buf, _countof(buf), NULL, NULL); + buf[_countof(buf) - 1] = ANSI_NULL; + for (UINT i = 0; i < _countof(Map); ++i) + { + if (!StrCmpIA(buf, Map[i].Name)) + return Map[i].Flag; + } + return StrToNum(Name); +} + +template +static PCSTR MapToName(UINT Value, const T &Map, PCSTR Fallback = NULL) +{ + for (UINT i = 0; i < _countof(Map); ++i) + { + if (Map[i].Flag == Value) + return Map[i].Name; + } + return Fallback; +} + +#define GetSLDF(Name) MapToNumber((Name), g_SLDF) +#define GetDatablockSignature(Name) MapToNumber((Name), g_DBSig) + +static int ErrMsg(int Error) +{ + WCHAR buf[400]; + for (UINT e = Error, cch; ;) + { + lstrcpynW(buf, L"?", _countof(buf)); + cch = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, e, 0, buf, _countof(buf), NULL); + while (cch && buf[cch - 1] <= ' ') + buf[--cch] = UNICODE_NULL; // Remove trailing newlines + if (cch || HIWORD(e) != HIWORD(HRESULT_FROM_WIN32(1))) + break; + e = HRESULT_CODE(e); // "WIN32_FROM_HRESULT" + } + wprintf(Error < 0 ? L"Error 0x%.8X %s\n" : L"Error %d %s\n", Error, buf); + return Error; +} + +static int SuccessOrReportError(int Error) +{ + return Error ? ErrMsg(Error) : Error; +} + +static inline HRESULT Seek(IStream *pStrm, int Move, int Origin = FILE_CURRENT, ULARGE_INTEGER *pNewPos = NULL) +{ + LARGE_INTEGER Pos; + Pos.QuadPart = Move; + return pStrm->Seek(Pos, Origin, pNewPos); +} + +static HRESULT IL_LoadFromStream(IStream *pStrm, PIDLIST_ABSOLUTE *ppidl) +{ + HMODULE hShell32 = LoadLibraryA("SHELL32"); + HRESULT (WINAPI*ILLFS)(IStream*, PIDLIST_ABSOLUTE*); + (FARPROC&)ILLFS = GetProcAddress(hShell32, (char*)26); // NT5 + if (!ILLFS) + (FARPROC&)ILLFS = GetProcAddress(hShell32, (char*)846); // NT6 + return ILLFS(pStrm, ppidl); +} + +static HRESULT SHParseName(PCWSTR Path, PIDLIST_ABSOLUTE *ppidl) +{ + HMODULE hShell32 = LoadLibraryA("SHELL32"); + int (WINAPI*SHPDN)(PCWSTR, void*, PIDLIST_ABSOLUTE*, UINT, UINT*); + (FARPROC&)SHPDN = GetProcAddress(hShell32, "SHParseDisplayName"); + if (SHPDN) + return SHPDN(Path, NULL, ppidl, 0, NULL); + return SHILCreateFromPath(Path, ppidl, NULL); +} + +static HRESULT SHParseNameEx(PCWSTR Path, PIDLIST_ABSOLUTE *ppidl, bool Simple) +{ + if (!Simple) + return SHParseName(Path, ppidl); + *ppidl = SHSimpleIDListFromPath(Path); + return *ppidl ? S_OK : E_FAIL; +} + +static INT_PTR SHGetPidlInfo(LPCITEMIDLIST pidl, SHFILEINFOW &shfi, UINT Flags, UINT Depth = 0) +{ + LPITEMIDLIST pidlDup = NULL, pidlChild; + if (Depth > 0) + { + if ((pidl = pidlDup = pidlChild = ILClone(pidl)) == NULL) + return 0; + while (Depth--) + { + if (LPITEMIDLIST pidlNext = ILGetNext(pidlChild)) + pidlChild = pidlNext; + } + pidlChild->mkid.cb = 0; + } + INT_PTR ret = SHGetFileInfoW((PWSTR)pidl, 0, &shfi, sizeof(shfi), Flags | SHGFI_PIDL); + ILFree(pidlDup); + return ret; +} + +static void PrintOffsetString(PCSTR Name, LPCVOID Base, UINT Min, UINT Ansi, UINT Unicode, PCSTR Indent = "") +{ + if (Unicode && Unicode >= Min) + wprintf(L"%hs%hs=%ls", Indent, Name, (PWSTR)((BYTE*)Base + Unicode)); + else + wprintf(L"%hs%hs=%hs", Indent, Name, Ansi >= Min ? (char*)Base + Ansi : ""); + wprintf(L"\n"); // Separate function call in case the (untrusted) input ends with a DEL character +} + +static void Print(PCSTR Name, REFGUID Guid, PCSTR Indent = "") +{ + WCHAR Buffer[39]; + StringFromGUID2(Guid, Buffer, _countof(Buffer)); + wprintf(L"%hs%hs=%ls\n", Indent, Name, Buffer); +} + +template +static void DumpFlags(V Value, T *pInfo, UINT Count, PCSTR Prefix = NULL) +{ + if (!Prefix) + Prefix = ""; + for (SIZE_T i = 0; i < Count; ++i) + { + if (Value & pInfo[i].Flag) + wprintf(L"%hs%#.8x:%hs\n", Prefix, pInfo[i].Flag, const_cast(pInfo[i].Name)); + Value &= ~pInfo[i].Flag; + } + if (Value) + wprintf(L"%hs%#.8x:%hs\n", Prefix, Value, "?"); +} + +static void Dump(LPITEMIDLIST pidl, PCSTR Heading = NULL) +{ + struct GUIDPIDL { WORD cb; BYTE Type, Unknown; GUID guid; }; + struct DRIVE { BYTE cb1, cb2, Type; char Name[4]; BYTE Unk[18]; }; + struct FS95 { WORD cb; BYTE Type, Unknown, Data[4+2+2+2]; char Name[1]; }; + if (Heading) + wprintf(L"%hs ", Heading); + if (!pidl || !pidl->mkid.cb) + wprintf(L"[Desktop (%hs)]", pidl ? "Empty" : "NULL"); + for (UINT i = 0; pidl && pidl->mkid.cb; ++i, pidl = ILGetNext(pidl)) + { + SHFILEINFOW shfi; + PWSTR buf = shfi.szDisplayName; + GUIDPIDL *pidlGUID = (GUIDPIDL*)pidl; + UINT cb = pidl->mkid.cb; + UINT type = cb >= 3 ? (pidlGUID->Type & ~0x80) : 0, folder = type & 0x70; + if (i) + wprintf(L" "); + if (cb < 3) + { + wprintf(L"[? %ub]", cb); + } + else if (i == 0 && cb == sizeof(GUIDPIDL) && type == PT_DESKTOP_REGITEM) guiditem: + { + if (!SHGetPidlInfo(pidl, shfi, SHGFI_DISPLAYNAME, 1)) + StringFromGUID2(*(GUID*)((char*)pidl + cb - 16), buf, 39); + wprintf(L"[%.2X %ub %s]", pidl->mkid.abID[0], cb, buf); + } + else if (i == 1 && cb == sizeof(GUIDPIDL) && type == PT_COMPUTER_REGITEM) + { + goto guiditem; + } + else if (i == 1 && cb == sizeof(DRIVE) && folder == 0x20) + { + DRIVE *p = (DRIVE*)pidl; + wprintf(L"[%.2X %ub \"%.3hs\"]", p->Type, cb, p->Name); + } + else if (cb > FIELD_OFFSET(FS95, Name) && folder == PT_FS) + { + FS95 *p = (FS95*)pidl; + const BOOL wide = type & PT_FS_UNICODE_FLAG; + wprintf(wide ? L"[%.2X %ub \"%.256ls\"]" : L"[%.2X %ub \"%.256hs\"]", p->Type, cb, p->Name); + } + else + { + wprintf(L"[%.2X %ub ?]", pidl->mkid.abID[0], cb); + } + } + wprintf(L"\n"); +} + +static HRESULT Save(IShellLink *pSL, PCWSTR LnkPath) +{ + HRESULT hr; + IPersistFile *pPF; + if (SUCCEEDED(hr = pSL->QueryInterface(IID_PPV_ARG(IPersistFile, &pPF)))) + { + if (SUCCEEDED(hr = pPF->Save(LnkPath, FALSE)) && hr != S_OK) + hr = E_FAIL; + pPF->Release(); + } + return hr; +} + +static HRESULT Load(IUnknown *pUnk, IStream *pStream) +{ + IPersistStream *pPS; + HRESULT hr = pUnk->QueryInterface(IID_PPV_ARG(IPersistStream, &pPS)); + if (SUCCEEDED(hr)) + { + hr = pPS->Load(pStream); + pPS->Release(); + } + return hr; +} + +static HRESULT Open(PCWSTR Path, IStream **ppStream, IShellLink **ppLink, UINT Mode = STGM_READ) +{ + if (Mode & (STGM_WRITE | STGM_READWRITE)) + Mode = (Mode & ~STGM_WRITE) | STGM_READWRITE | STGM_SHARE_DENY_WRITE; + else + Mode |= STGM_READ | STGM_SHARE_DENY_NONE; + IStream *pStream; + HRESULT hr = SHCreateStreamOnFileW(Path, Mode, &pStream); + if (SUCCEEDED(hr) && ppLink) + { + hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IShellLink, ppLink)); + if (SUCCEEDED(hr) && !(Mode & STGM_CREATE)) + { + if (FAILED(hr = Load(*ppLink, pStream))) + { + (*ppLink)->Release(); + *ppLink = NULL; + } + IStream_Reset(pStream); + } + } + + if (SUCCEEDED(hr) && ppStream) + *ppStream = pStream; + else if (pStream) + pStream->Release(); + return hr; +} + +#define FreeBlock SHFree +static inline LPDATABLOCK_HEADER NextBlock(LPDATABLOCK_HEADER pdbh) +{ + return (LPDATABLOCK_HEADER)((char*)pdbh + pdbh->cbSize); +} + +template +static HRESULT ReadBlock(IStream *pStream, T **ppData = NULL) +{ + DWORD cb = 0; + HRESULT hr = IStream_Read(pStream, &cb, sizeof(cb)); + if (SUCCEEDED(hr)) + { + UINT Remain = cb - min(sizeof(DWORD), cb); + if (!ppData) + return Seek(pStream, Remain); + *ppData = (T*)SHAlloc(Remain + sizeof(DWORD)); + if (!*ppData) + return E_OUTOFMEMORY; + ((DATABLOCK_HEADER*)*ppData)->cbSize = cb; + if (SUCCEEDED(hr = IStream_Read(pStream, &((DATABLOCK_HEADER*)*ppData)->dwSignature, Remain))) + return cb; + } + return hr; +} + +struct DataBlockEnum +{ + DataBlockEnum(LPDATABLOCK_HEADER pHead) : m_It(pHead) {} + + LPDATABLOCK_HEADER Get() + { + if (m_It && m_It->cbSize >= FIELD_OFFSET(DATABLOCK_HEADER, dwSignature)) + return m_It + (m_It->dwSignature == ~0UL); // SHFindDataBlock compatible + return NULL; + } + void Next() + { + if (m_It && m_It->cbSize) + m_It = NextBlock(m_It); + } + LPDATABLOCK_HEADER m_It; +}; + +static HRESULT ReadAndDumpString(PCSTR Name, UINT Id, const SHELL_LINK_HEADER &slh, IStream *pStream) +{ + if (!(Id & slh.dwFlags)) + return S_OK; + WORD cch; + HRESULT hr = IStream_Read(pStream, &cch, sizeof(cch)); + if (FAILED(hr)) + return hr; + UINT cb = (UINT)cch * ((slh.dwFlags & SLDF_UNICODE) ? sizeof(WCHAR) : sizeof(CHAR)); + void *data = SHAlloc(cb); + if (!data) + return E_OUTOFMEMORY; + if (FAILED(hr = IStream_Read(pStream, data, cb))) + return hr; + if (slh.dwFlags & SLDF_UNICODE) + wprintf(L"%hs=%.*ls\n", Name, cch, (PWSTR)data); + else + wprintf(L"%hs=%.*hs\n", Name, cch, (PCSTR)data); + SHFree(data); + return S_OK; +} + +static HRESULT DumpCommand(PCWSTR Path) +{ + IStream *pStream; + HRESULT hr = Open(Path, &pStream, NULL); + if (FAILED(hr)) + return hr; + + LPITEMIDLIST pidl; + SHELL_LINK_HEADER slh; + if (SUCCEEDED(hr = IStream_Read(pStream, &slh, sizeof(slh)))) + { + #define DUMPSLH(name, fmt, field) wprintf(L"%hs=" fmt L"\n", (name), (slh).field) + DUMPSLH("Flags", L"%#.8x", dwFlags); + DumpFlags(slh.dwFlags, g_SLDF, _countof(g_SLDF), INDENT); + DUMPSLH("FileAttributes", L"%#.8x", dwFileAttributes); + DUMPSLH("Size", L"%u", nFileSizeLow); + DUMPSLH("IconIndex", L"%d", nIconIndex); + DUMPSLH("ShowCommand", L"%d", nShowCommand); + DUMPSLH("HotKey", L"%#.4x", wHotKey); + + if (SUCCEEDED(hr) && (slh.dwFlags & SLDF_HAS_ID_LIST)) + { + if (SUCCEEDED(hr = IL_LoadFromStream(pStream, &pidl))) + { + Dump(pidl, "PIDL:"); + ILFree(pidl); + } + } + if (SUCCEEDED(hr) && (slh.dwFlags & SLDF_HAS_LINK_INFO)) + { + int offset; + SHELL_LINK_INFOW *p; + if ((hr = ReadBlock(pStream, &p)) >= (signed)sizeof(SHELL_LINK_INFOA)) + { + wprintf(L"%hs:\n", "LINKINFO"); + wprintf(L"%hs%hs=%#.8x\n", INDENT, "Flags", p->dwFlags); + if (p->dwFlags & SLI_VALID_LOCAL) + { + if (p->cbVolumeIDOffset) + { + SHELL_LINK_INFO_VOLUME_IDW *pVol = (SHELL_LINK_INFO_VOLUME_IDW*)((char*)p + p->cbVolumeIDOffset); + wprintf(L"%hs%hs=%d\n", INDENT, "DriveType", pVol->dwDriveType); + wprintf(L"%hs%hs=%#.8x\n", INDENT, "Serial", pVol->nDriveSerialNumber); + offset = pVol->cbVolumeLabelOffset == 0x14 ? pVol->cbVolumeLabelUnicodeOffset : 0; + if (offset || pVol->cbVolumeLabelOffset != 0x14) // 0x14 from [MS-SHLLINK] documentation + PrintOffsetString("Label", pVol, 0x10, pVol->cbVolumeLabelOffset, offset, INDENT); + } + offset = p->cbHeaderSize >= sizeof(SHELL_LINK_INFOW) ? p->cbCommonPathSuffixUnicodeOffset : 0; + PrintOffsetString("CommonSuffix", p, sizeof(SHELL_LINK_INFOA), p->cbCommonPathSuffixOffset, offset, INDENT); + + offset = p->cbHeaderSize >= sizeof(SHELL_LINK_INFOW) ? p->cbLocalBasePathUnicodeOffset : 0; + PrintOffsetString("LocalBase", p, sizeof(SHELL_LINK_INFOA), p->cbLocalBasePathOffset, offset, INDENT); + } + SHELL_LINK_INFO_CNR_LINKW *pCNR = (SHELL_LINK_INFO_CNR_LINKW*)((char*)p + p->cbCommonNetworkRelativeLinkOffset); + if ((p->dwFlags & SLI_VALID_NETWORK) && p->cbCommonNetworkRelativeLinkOffset) + { + wprintf(L"%hs%hs=%#.8x\n", INDENT, "CNR", pCNR->dwFlags); + wprintf(L"%hs%hs=%#.8x\n", INDENT, "Provider", pCNR->dwNetworkProviderType); // WNNC_NET_* + + offset = pCNR->cbNetNameOffset > 0x14 ? pCNR->cbNetNameUnicodeOffset : 0; + PrintOffsetString("NetName", pCNR, sizeof(SHELL_LINK_INFO_CNR_LINKA), pCNR->cbNetNameOffset, offset, INDENT); + + offset = pCNR->cbNetNameOffset > 0x14 ? pCNR->cbDeviceNameUnicodeOffset : 0; + if (pCNR->dwFlags & SLI_CNR_VALID_DEVICE) + PrintOffsetString("DeviceName", pCNR, sizeof(SHELL_LINK_INFO_CNR_LINKA), pCNR->cbDeviceNameOffset, offset, INDENT); + } + FreeBlock(p); + } + } + if (SUCCEEDED(hr)) + hr = ReadAndDumpString("NAME", SLDF_HAS_NAME, slh, pStream); + if (SUCCEEDED(hr)) + hr = ReadAndDumpString("RELPATH", SLDF_HAS_RELPATH, slh, pStream); + if (SUCCEEDED(hr)) + hr = ReadAndDumpString("WORKINGDIR", SLDF_HAS_WORKINGDIR, slh, pStream); + if (SUCCEEDED(hr)) + hr = ReadAndDumpString("ARGS", SLDF_HAS_ARGS, slh, pStream); + if (SUCCEEDED(hr)) + hr = ReadAndDumpString("ICONLOCATION", SLDF_HAS_ICONLOCATION, slh, pStream); + + LPDATABLOCK_HEADER pDBListHead, pDBH; + if (SUCCEEDED(hr) && SUCCEEDED(hr = SHReadDataBlockList(pStream, &pDBListHead))) + { + for (DataBlockEnum it(pDBListHead); (pDBH = it.Get()) != NULL; it.Next()) + { + PCSTR SigName = MapToName(pDBH->dwSignature, g_DBSig, NULL); + wprintf(L"DataBlock: %.8X %ub", pDBH->dwSignature, pDBH->cbSize); + void *pFirstMember = ((EXP_SZ_LINK*)pDBH)->szTarget; + if (pDBH->dwSignature == EXP_SZ_LINK_SIG && pDBH->cbSize > FIELD_OFFSET(EXP_SZ_LINK, szwTarget)) + { + wprintf(L" %hs\n", "SZ_LINK"); + printdbpaths: + EXP_SZ_LINK *p = (EXP_SZ_LINK*)pDBH; + wprintf(L"%hs%hs=%.260hs\n", INDENT, "Ansi", p->szTarget); + wprintf(L"%hs%hs=%.260ls\n", INDENT, "Wide", p->szwTarget); + } + else if (pDBH->dwSignature == EXP_SZ_ICON_SIG && pDBH->cbSize > FIELD_OFFSET(EXP_SZ_LINK, szwTarget)) + { + wprintf(L" %hs\n", "SZ_ICON/LOGO3"); + goto printdbpaths; + } + else if (pDBH->dwSignature == EXP_DARWIN_ID_SIG && pDBH->cbSize == sizeof(EXP_DARWIN_LINK)) + { + wprintf(L" %hs\n", "DARWIN_LINK"); + goto printdbpaths; + } + else if (pDBH->dwSignature == NT_CONSOLE_PROPS_SIG && pDBH->cbSize >= sizeof(NT_CONSOLE_PROPS)) + { + wprintf(L" %hs\n", "NT_CONSOLE_PROPS"); + NT_CONSOLE_PROPS *p = (NT_CONSOLE_PROPS*)pDBH; + wprintf(L"%hsInsert=%d Quick=%d %ls\n", INDENT, p->bInsertMode, p->bQuickEdit, p->FaceName); + } + else if (pDBH->dwSignature == EXP_SPECIAL_FOLDER_SIG && pDBH->cbSize == sizeof(EXP_SPECIAL_FOLDER)) + { + wprintf(L" %hs\n", SigName); + EXP_SPECIAL_FOLDER *p = (EXP_SPECIAL_FOLDER*)pDBH; + wprintf(L"%hsCSIDL=%#x Offset=%#x\n", INDENT, p->idSpecialFolder, p->cbOffset); + } + else if (pDBH->dwSignature == EXP_TRACKER_SIG) + { + wprintf(L" %hs\n", SigName); + EXP_TRACKER *p = (EXP_TRACKER*)pDBH; + UINT len = FIELD_OFFSET(EXP_TRACKER, nLength) + p->nLength; + if (len >= FIELD_OFFSET(EXP_TRACKER, szMachineID)) + wprintf(L"%hsVersion=%d\n", INDENT, p->nVersion); + if (len >= FIELD_OFFSET(EXP_TRACKER, guidDroidVolume)) + wprintf(L"%hsMachine=%hs\n", INDENT, p->szMachineID); + if (len >= FIELD_OFFSET(EXP_TRACKER, guidDroidObject)) + Print("Volume", p->guidDroidVolume, INDENT); + if (len >= FIELD_OFFSET(EXP_TRACKER, guidDroidBirthVolume)) + Print("Object", p->guidDroidObject, INDENT); + if (len >= FIELD_OFFSET(EXP_TRACKER, guidDroidBirthObject)) + Print("BirthVolume", p->guidDroidBirthVolume, INDENT); + if (len >= sizeof(EXP_TRACKER)) + Print("BirthObject", p->guidDroidBirthObject, INDENT); + } + else if (pDBH->dwSignature == EXP_SHIM_SIG) + { + wprintf(L" %hs\n", SigName ? SigName : "SHIM"); + wprintf(L"%hs%ls\n", INDENT, (PWSTR)pFirstMember); + } + else if (pDBH->dwSignature == EXP_VISTA_ID_LIST_SIG && pDBH->cbSize >= 8 + 2) + { + wprintf(L" %hs\n", SigName); + Dump((LPITEMIDLIST)pFirstMember, INDENT + 1); + } + else + { + wprintf(SigName ? L" %hs\n" : L"\n", SigName); + } + } + SHFreeDataBlockList(pDBListHead); + } + } + pStream->Release(); + + // Now dump using the API + HRESULT hr2; + WCHAR buf[MAX_PATH * 2]; + IShellLink *pSL; + if (FAILED(hr2 = Open(Path, NULL, &pSL))) + return hr2; + wprintf(L"\n"); + + if (SUCCEEDED(hr2 = pSL->GetIDList(&pidl))) + { + Dump(pidl, "GetIDList:"); + ILFree(pidl); + } + else + { + wprintf(L"%hs: %#x\n", "GetIDList", hr2); + } + + static const BYTE GetPathFlags[] = { 0, SLGP_SHORTPATH, SLGP_RAWPATH, slgp_relativepriority }; + for (UINT i = 0; i < _countof(GetPathFlags); ++i) + { + if (SUCCEEDED(hr2 = pSL->GetPath(buf, _countof(buf), NULL, GetPathFlags[i]))) + wprintf(L"GetPath(%#.2x): %ls\n", GetPathFlags[i], buf); + else + wprintf(L"GetPath(%#.2x): %#x\n", GetPathFlags[i], hr2); + } + + if (SUCCEEDED(hr2 = pSL->GetWorkingDirectory(buf, _countof(buf)))) + wprintf(L"%hs: %ls\n", "GetWorkingDirectory", buf); + else + wprintf(L"%hs: %#x\n", "GetWorkingDirectory", hr2); + + if (SUCCEEDED(hr2 = pSL->GetArguments(buf, _countof(buf)))) + wprintf(L"%hs: %ls\n", "GetArguments", buf); + else + wprintf(L"%hs: %#x\n", "GetArguments", hr2); + + if (SUCCEEDED(hr2 = pSL->GetDescription(buf, _countof(buf)))) + wprintf(L"%hs: %ls\n", "GetDescription", buf); + else + wprintf(L"%hs: %#x\n", "GetDescription", hr2); + + int index = 123456789; + if (SUCCEEDED(hr2 = pSL->GetIconLocation(buf, _countof(buf), &index))) + wprintf(L"%hs: %ls,%d\n", "GetIconLocation", buf, index); + else + wprintf(L"%hs: %#x\n", "GetIconLocation", hr2); + + IExtractIconW *pEI; + if (SUCCEEDED(pSL->QueryInterface(IID_PPV_ARG(IExtractIconW, &pEI)))) + { + index = 123456789; + UINT flags = 0; + if (SUCCEEDED(hr2 = pEI->GetIconLocation(0, buf, _countof(buf), &index, &flags))) + wprintf(L"%hs: %#x %ls,%d %#.4x\n", "EI:GetIconLocation", hr2, buf, index, flags); + else + wprintf(L"%hs: %#x %#.4x\n", "EI:GetIconLocation", hr2, flags); + pEI->Release(); + } + + pSL->Release(); + return hr; +} + +#define RemoveSLDF(pSL, Flag) RemoveDatablock((pSL), 0, (Flag)) +#define AddSLDF(pSL, Flag) RemoveDatablock((pSL), 0, 0, (Flag)) + +static HRESULT RemoveDatablock(IShellLinkW *pSL, UINT Signature, UINT KillFlag = 0, UINT AddFlag = 0) +{ + IShellLinkDataList *pSLDL; + HRESULT hr = pSL->QueryInterface(IID_PPV_ARG(IShellLinkDataList, &pSLDL)); + if (SUCCEEDED(hr)) + { + if (Signature) + hr = pSLDL->RemoveDataBlock(Signature); + DWORD OrgFlags; + if ((AddFlag | KillFlag) && SUCCEEDED(pSLDL->GetFlags(&OrgFlags))) + pSLDL->SetFlags((OrgFlags & ~KillFlag) | AddFlag); + pSLDL->Release(); + } + return hr; +} + +template +static HRESULT AddDataBlock(IShellLinkW *pSL, T &DataBlock) +{ + IShellLinkDataList *pSLDL; + HRESULT hr = pSL->QueryInterface(IID_PPV_ARG(IShellLinkDataList, &pSLDL)); + if (SUCCEEDED(hr)) + { + hr = pSLDL->AddDataBlock(&DataBlock); + pSLDL->Release(); + } + return hr; +} + +static BOOL TryGetUpdatedPidl(IShellLinkW *pSL, PIDLIST_ABSOLUTE &pidl) +{ + PIDLIST_ABSOLUTE pidlNew; + if (pSL->GetIDList(&pidlNew) == S_OK) + { + ILFree(pidl); + pidl = pidlNew; + } + return pidl != NULL; +} + +static HRESULT CreateCommand(PCWSTR LnkPath, UINT argc, WCHAR **argv) +{ + IShellLinkW *pSL; + HRESULT hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IShellLinkW, &pSL)); + if (FAILED(hr)) + return hr; + + UINT TargetCount = 0, DumpResult = 0, ForceAddSLDF = 0, ForceRemoveSLDF = 0; + PIDLIST_ABSOLUTE pidlTarget = NULL; + for (UINT i = 0; i < argc && SUCCEEDED(hr); ++i) + { + hr = E_INVALIDARG; + if (!StrCmpIW(argv[i], L"/Pidl") && i + 1 < argc) + { + bool Simple = !StrCmpIW(argv[i + 1], L"/Force") && i + 2 < argc && ++i; + if (SUCCEEDED(hr = SHParseNameEx(argv[++i], &pidlTarget, Simple))) + TargetCount += SUCCEEDED(hr = pSL->SetIDList(pidlTarget)); + } + else if (!StrCmpIW(argv[i], L"/Path") && i + 1 < argc) + { + TargetCount += SUCCEEDED(hr = pSL->SetPath(argv[++i])); + } + else if (!StrCmpIW(argv[i], L"/Icon") && i + 1 < argc) + { + int index = PathParseIconLocation(argv[++i]); + hr = pSL->SetIconLocation(argv[i], index); + } + else if (!StrCmpIW(argv[i], L"/Arguments") && i + 1 < argc) + { + hr = pSL->SetArguments(argv[++i]); + } + else if (!StrCmpIW(argv[i], L"/RelativePath") && i + 1 < argc) + { + hr = pSL->SetRelativePath(argv[++i], 0); + } + else if (!StrCmpIW(argv[i], L"/WorkingDir") && i + 1 < argc) + { + hr = pSL->SetWorkingDirectory(argv[++i]); + } + else if (!StrCmpIW(argv[i], L"/Comment") && i + 1 < argc) + { + hr = pSL->SetDescription(argv[++i]); + } + else if (!StrCmpIW(argv[i], L"/ShowCmd") && i + 1 < argc) + { + if (int sw = StrToNum(argv[++i])) // Don't allow SW_HIDE + hr = pSL->SetShowCmd(sw); + } + else if (!StrCmpIW(argv[i], L"/AddExp") && ++i < argc) + { + EXP_SZ_LINK db = { sizeof(db), EXP_SZ_LINK_SIG }; + WideCharToMultiByte(CP_ACP, 0, argv[i], -1, db.szTarget, _countof(db.szTarget), NULL, NULL); + lstrcpynW(db.szwTarget, argv[i], _countof(db.szwTarget)); + if (SUCCEEDED(hr = AddDataBlock(pSL, db))) + TargetCount += SUCCEEDED(hr = AddSLDF(pSL, SLDF_HAS_EXP_SZ)); + } + else if (!StrCmpIW(argv[i], L"/AddExpIcon") && ++i < argc) + { + EXP_SZ_LINK db = { sizeof(db), EXP_SZ_ICON_SIG }; + WideCharToMultiByte(CP_ACP, 0, argv[i], -1, db.szTarget, _countof(db.szTarget), NULL, NULL); + lstrcpynW(db.szwTarget, argv[i], _countof(db.szwTarget)); + if (SUCCEEDED(hr = AddDataBlock(pSL, db))) + hr = AddSLDF(pSL, SLDF_HAS_EXP_ICON_SZ); + } + else if (!StrCmpIW(argv[i], L"/RemoveExpIcon")) + { + hr = RemoveDatablock(pSL, EXP_SZ_ICON_SIG, SLDF_HAS_EXP_ICON_SZ); + } + else if (!StrCmpIW(argv[i], L"/SpecialFolderOffset") && i + 2 < argc) + { + EXP_SPECIAL_FOLDER db = { sizeof(db), EXP_SPECIAL_FOLDER_SIG }; + if ((db.idSpecialFolder = StrToNum(argv[++i])) == 0) + { + if (!StrCmpIW(argv[i], L"Windows")) + db.idSpecialFolder = CSIDL_WINDOWS; + if (!StrCmpIW(argv[i], L"System")) + db.idSpecialFolder = CSIDL_SYSTEM; + } + db.cbOffset = StrToNum(argv[++i]); + if ((signed)db.cbOffset < 0 && TryGetUpdatedPidl(pSL, pidlTarget)) + { + UINT i = 0, c = -(signed)db.cbOffset; + db.cbOffset = 0; + for (PIDLIST_ABSOLUTE pidl = pidlTarget; i < c && pidl->mkid.cb; ++i, pidl = ILGetNext(pidl)) + db.cbOffset += pidl->mkid.cb; + } + hr = AddDataBlock(pSL, db); + } + else if (!StrCmpIW(argv[i], L"/RemoveDatablock")) + { + if (UINT sig = GetDatablockSignature(argv[++i])) + hr = RemoveDatablock(pSL, sig); + } + else if (!StrCmpIW(argv[i], L"/AddSLDF") && i + 1 < argc) + { + bool Force = !StrCmpIW(argv[i + 1], L"/Force") && i + 2 < argc && ++i; + UINT Flag = GetSLDF(argv[++i]); + if (Flag > SLDF_UNICODE) + hr = AddSLDF(pSL, Flag); + if (Force) + ForceAddSLDF |= Flag; + } + else if (!StrCmpIW(argv[i], L"/RemoveSLDF") && i + 1 < argc) + { + bool Force = !StrCmpIW(argv[i + 1], L"/Force") && i + 2 < argc && ++i; + UINT Flag = GetSLDF(argv[++i]); + if (Flag) + hr = RemoveSLDF(pSL, Flag); + if (Force) + ForceRemoveSLDF |= Flag; + } + else if (!StrCmpIW(argv[i], L"/Dump")) + { + DumpResult++; + hr = S_OK; + } + else if (!StrCmpIW(argv[i], L"/ForceCreate")) + { + TargetCount++; + hr = S_OK; + } + else + { + wprintf(L"%hsUnable to parse \"%ls\"!\n", "Error: ", argv[i]); + } + } + + if (SUCCEEDED(hr)) + { + if (TargetCount) + { + if (SUCCEEDED(hr = Save(pSL, LnkPath)) && (ForceAddSLDF | ForceRemoveSLDF)) + { + IStream *pStream; + if (SUCCEEDED(Open(LnkPath, &pStream, NULL, STGM_READWRITE))) + { + SHELL_LINK_HEADER slh; + if (SUCCEEDED(IStream_Read(pStream, &slh, sizeof(slh)))) + { + slh.dwFlags = (slh.dwFlags & ~ForceRemoveSLDF) | ForceAddSLDF; + if (SUCCEEDED(Seek(pStream, 0, FILE_BEGIN))) + IStream_Write(pStream, &slh, sizeof(slh)); + } + pStream->Release(); + } + } + } + else + { + hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); + } + + if (SUCCEEDED(hr) && DumpResult) + DumpCommand(LnkPath); + } + pSL->Release(); + ILFree(pidlTarget); + return hr; +} + +static HRESULT RemoveDatablockCommand(PCWSTR LnkPath, UINT argc, WCHAR **argv) +{ + IShellLink *pSL; + HRESULT hr = Open(LnkPath, NULL, &pSL, STGM_READWRITE); + if (FAILED(hr)) + return hr; + + hr = E_INVALIDARG; + for (UINT i = 0; i < argc; ++i) + { + UINT Sig = GetDatablockSignature(argv[i]); + if (!Sig) + { + hr = E_INVALIDARG; + break; + } + hr = RemoveDatablock(pSL, Sig); + } + + if (SUCCEEDED(hr)) + hr = Save(pSL, LnkPath); + pSL->Release(); + return hr; +} + +static int ProcessCommandLine(int argc, WCHAR **argv) +{ + if (argc < 3) + { + wprintf(L"%hs", g_Usage); + return argc < 2 ? 0 : ERROR_INVALID_PARAMETER; + } + + if (!StrCmpIW(argv[1], L"Dump")) + return SuccessOrReportError(DumpCommand(argv[2])); + if (!StrCmpIW(argv[1], L"Create")) + return SuccessOrReportError(CreateCommand(argv[2], argc - 3, &argv[3])); + if (!StrCmpIW(argv[1], L"RemoveDatablock")) + return SuccessOrReportError(RemoveDatablockCommand(argv[2], argc - 3, &argv[3])); + + return SuccessOrReportError(ERROR_INVALID_PARAMETER); +} + +EXTERN_C int wmain(int argc, WCHAR **argv) +{ + HRESULT hrInit = OleInitialize(NULL); + int result = ProcessCommandLine(argc, argv); + if (SUCCEEDED(hrInit)) + OleUninitialize(); + return result; +} diff --git a/modules/rosapps/applications/devutils/lnktool/lnktool.rc b/modules/rosapps/applications/devutils/lnktool/lnktool.rc new file mode 100644 index 0000000000000..fceb662389fe7 --- /dev/null +++ b/modules/rosapps/applications/devutils/lnktool/lnktool.rc @@ -0,0 +1,9 @@ +#include +#include + +#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Shell Link Utility" +#define REACTOS_STR_INTERNAL_NAME "lnktool" +#define REACTOS_STR_ORIGINAL_FILENAME "lnktool.exe" +#include + +#include diff --git a/modules/rosapps/applications/devutils/vgafontedit/lang/ro-RO.rc b/modules/rosapps/applications/devutils/vgafontedit/lang/ro-RO.rc index 8c18c22973fb7..cd36a4ddcc43a 100644 --- a/modules/rosapps/applications/devutils/vgafontedit/lang/ro-RO.rc +++ b/modules/rosapps/applications/devutils/vgafontedit/lang/ro-RO.rc @@ -2,34 +2,34 @@ * PROJECT: ReactOS VGA Font Editor * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) * PURPOSE: Romanian resource file - * TRANSLATORS: Copyright 2008 Ștefan Fulea - * Copyright 2023 Andrei Miloiu + * TRANSLATORS: Copyright 2014-2018 Ștefan Fulea + * Copyright 2023-2024 Andrei Miloiu */ LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL IDD_ABOUT DIALOGEX 10, 10, 130, 62 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -CAPTION "About" +CAPTION "Despre" FONT 8, "MS Shell Dlg" BEGIN ICON IDI_MAIN, IDC_STATIC, 10, 10, 20, 20 LTEXT "Editor de font VGA ReactOS", IDC_STATIC, 37, 10, 93, 10 LTEXT "Drept de autor 2008 Colin Finck", IDC_STATIC, 37, 20, 93, 10 - DEFPUSHBUTTON "Î&nchide", IDCANCEL, 40, 44, 55, 15 + DEFPUSHBUTTON "Î&nchidere", IDCANCEL, 40, 44, 55, 15 END IDD_EDITGLYPH DIALOGEX 32768, 32768, 246, 197 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Editare glifă" +CAPTION "Editare a glifei" FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_EDIT_GLYPH_TOOLBOX, TOOLBARCLASSNAMEA, CCS_NODIVIDER | CCS_NORESIZE, 5, 5, 24, 82 CONTROL "", IDC_EDIT_GLYPH_EDIT, EDIT_GLYPH_EDIT_CLASSW, 0, 39, 5, 160, 160 CONTROL "", IDC_EDIT_GLYPH_PREVIEW, EDIT_GLYPH_PREVIEW_CLASSW, 0, 209, 5, 32, 32 - DEFPUSHBUTTON "Con&firmă", IDOK, 48, 177, 70, 14 - PUSHBUTTON "A&nulează", IDCANCEL, 125, 177, 70, 14 + DEFPUSHBUTTON "OK", IDOK, 48, 177, 70, 14 + PUSHBUTTON "Revocare", IDCANCEL, 125, 177, 70, 14 END IDM_MAINMENU MENU @@ -40,31 +40,31 @@ BEGIN MENUITEM "&Deschidere…\tCtrl+O", ID_FILE_OPEN MENUITEM "În&chide", ID_FILE_CLOSE MENUITEM SEPARATOR - MENUITEM "Sal&vează\tCtrl+S", ID_FILE_SAVE - MENUITEM "Salvea&ză ca…", ID_FILE_SAVE_AS + MENUITEM "&Salvare\tCtrl+S", ID_FILE_SAVE + MENUITEM "S&alvare ca…", ID_FILE_SAVE_AS MENUITEM SEPARATOR MENUITEM "I&eșire\tAlt+F4", ID_FILE_EXIT END POPUP "&Editare" BEGIN - MENUITEM "&Copiază\tCtrl+C", ID_EDIT_COPY - MENUITEM "&Lipește\tCtrl+V", ID_EDIT_PASTE + MENUITEM "&Copiere\tCtrl+C", ID_EDIT_COPY + MENUITEM "&Lipire\tCtrl+V", ID_EDIT_PASTE MENUITEM SEPARATOR - MENUITEM "&Editare glifă…", ID_EDIT_GLYPH + MENUITEM "&Editare a glifei…", ID_EDIT_GLYPH END POPUP "Fe&restre" BEGIN - MENUITEM "Aranjare în &cascadă", ID_WINDOW_CASCADE - MENUITEM "Aranjări &orizontale", ID_WINDOW_TILE_HORZ - MENUITEM "Aranjări &verticale", ID_WINDOW_TILE_VERT - MENUITEM "&Aranjează pictograme", ID_WINDOW_ARRANGE + MENUITEM "&Cascadă", ID_WINDOW_CASCADE + MENUITEM "Dale &orizontale", ID_WINDOW_TILE_HORZ + MENUITEM "Dale &verticale", ID_WINDOW_TILE_VERT + MENUITEM "&Aranjare a pictogramelor", ID_WINDOW_ARRANGE MENUITEM SEPARATOR - MENUITEM "&Următoarea\tCtrl+F6", ID_WINDOW_NEXT + MENUITEM "&Următorul\tCtrl+F6", ID_WINDOW_NEXT END - POPUP "&?" + POPUP "&Ajutor" BEGIN MENUITEM "&Despre…", ID_HELP_ABOUT END @@ -72,22 +72,22 @@ END STRINGTABLE BEGIN - IDS_OPENFILTER, "Toate formatele compatibile (*.bin,*.psf)|*.bin;*.psf|Fișiere de font binar (*.bin)|*.bin|Fonturi (de versiune 1) PC Screen (*.psf)|*.psf|" - IDS_SAVEFILTER, "Fișiere de font binar (*.bin)|*.bin|" + IDS_OPENFILTER, "Toate formatele compatibile (*.bin,*.psf)|*.bin;*.psf|Fișiere de font binare (*.bin)|*.bin|Fonturi pentru ecranul PC Versiunea 1 (*.psf)|*.psf|" + IDS_SAVEFILTER, "Fișiere de font binare (*.bin)|*.bin|" IDS_OPENERROR, "Eroare la deschiderea fișierului! (Număr de eroare %1!u!)" IDS_READERROR, "Eroare la citirea fișierului! (Număr de eroare %1!u!)" IDS_WRITEERROR, "Eroare la scrierea fișierului! (Număr de eroare %1!u!)" IDS_UNSUPPORTEDFORMAT, "Format de fișier incompatibil!" IDS_UNSUPPORTEDPSF, "Format incompatibil de font PSF! Posibilitățile editorului se limitează la fonturile 8x8 fără moduri speciale." IDS_DOCNAME, "Font %1!u!" - IDS_SAVEPROMPT, "Modificările în fișierul „%1” încă nu au fost salvate.\n\nDoriți salvarea lor?" - IDS_APPTITLE, "Editor de font VGA ReactOS" - IDS_CLOSEEDIT, "Închideți mai întâi toate ferestrele de editare!" + IDS_SAVEPROMPT, "Fișierul ""%1"" a fost modificat, dar nu salvat.\n\nDoriți salvarea lor?" + IDS_APPTITLE, "Editorul de font VGA ReactOS" + IDS_CLOSEEDIT, "Închideți mai întâi toate ferestrele de Editare deschise!" IDS_TOOLTIP_NEW, "Nou" - IDS_TOOLTIP_OPEN, "Deschide" - IDS_TOOLTIP_SAVE, "Salvează" - IDS_TOOLTIP_EDIT_GLYPH, "Editează glifă" - IDS_TOOLTIP_COPY, "Copiază" - IDS_TOOLTIP_PASTE, "Lipește" + IDS_TOOLTIP_OPEN, "Deschidere" + IDS_TOOLTIP_SAVE, "Salvare" + IDS_TOOLTIP_EDIT_GLYPH, "Editare a glifei" + IDS_TOOLTIP_COPY, "Copiere" + IDS_TOOLTIP_PASTE, "Lipire" END diff --git a/modules/rosapps/applications/explorer-old/shell/entries.cpp b/modules/rosapps/applications/explorer-old/shell/entries.cpp index b79ac1949ade7..6b55949648466 100644 --- a/modules/rosapps/applications/explorer-old/shell/entries.cpp +++ b/modules/rosapps/applications/explorer-old/shell/entries.cpp @@ -456,7 +456,7 @@ BOOL Entry::launch_entry(HWND hwnd, UINT nCmdShow) // local replacement implementation for SHBindToParent() - // (derived from http://www.geocities.com/SiliconValley/2060/articles/shell-helpers.html) + // (derived from https://web.archive.org/web/20021105062620/http://www.geocities.com/SiliconValley/2060/articles/shell-helpers.html) static HRESULT my_SHBindToParent(LPCITEMIDLIST pidl, REFIID riid, VOID** ppv, LPCITEMIDLIST* ppidlLast) { HRESULT hr; diff --git a/modules/rosapps/applications/explorer-old/shell/fatfs.cpp b/modules/rosapps/applications/explorer-old/shell/fatfs.cpp index 5cd237280bf1f..fbfb3e832be3f 100644 --- a/modules/rosapps/applications/explorer-old/shell/fatfs.cpp +++ b/modules/rosapps/applications/explorer-old/shell/fatfs.cpp @@ -141,7 +141,7 @@ void FATDirectory::read_directory(int scan_flags) s = (const char*)p->Ent->B; // no change of the pointer, just to avoid overung warnings in code checkers // read long file name - TCHAR lname[] = {s[1], s[3], s[5], s[7], s[9], s[14], s[16], s[18], s[20], s[22], s[24], s[28], s[30]}; + char lname[] = {s[1], s[3], s[5], s[7], s[9], s[14], s[16], s[18], s[20], s[22], s[24], s[28], s[30]}; long_name = String(lname, 13) + long_name; } @@ -397,7 +397,7 @@ bool FATDirectory::read_dir() } } - buf->dat[0] = 0; // Endekennzeichen fr Rekurs setzen + buf->dat[0] = 0; // Endekennzeichen für Rekurs setzen } return true; diff --git a/modules/rosapps/applications/net/niclist/niclist.c b/modules/rosapps/applications/net/niclist/niclist.c index d4eec53cb465c..7dad3ad5e6e0e 100644 --- a/modules/rosapps/applications/net/niclist/niclist.c +++ b/modules/rosapps/applications/net/niclist/niclist.c @@ -9,7 +9,7 @@ */ /* For this program and for win32 ethernet, the winpcap library is required. - Download it from http://netgroup-serv.polito.it/winpcap. + Download it from https://web.archive.org/web/20040404215544/http://winpcap.polito.it/ . */ #ifdef MSC_VER #define WIN32_LEAN_AND_MEAN @@ -55,7 +55,7 @@ int main(int argc, char **argv) PacketGetVersion = (PCHAR (*)(VOID))GetProcAddress(hPacket, "PacketGetVersion"); } else { printf("Could not load WinPCap driver! for more information goto:\n"); - printf ("http://netgroup-serv.polito.it/winpcap\n"); + printf ("https://web.archive.org/web/20040404215544/http://winpcap.polito.it/\n"); return 1; } if (!(PacketLibraryVersion = PacketGetVersion())) { diff --git a/modules/rosapps/applications/net/tsclient/rdesktop/disk.c b/modules/rosapps/applications/net/tsclient/rdesktop/disk.c index 22f4114291e08..289aacfefff83 100644 --- a/modules/rosapps/applications/net/tsclient/rdesktop/disk.c +++ b/modules/rosapps/applications/net/tsclient/rdesktop/disk.c @@ -820,7 +820,7 @@ disk_set_information(RDPCLIENT * This, NTHANDLE handle, uint32 info_class, STREA FileDispositionInformation requests with DeleteFile set to FALSE should unschedule the delete. See - http://www.osronline.com/article.cfm?article=245. */ + https://www.osronline.com/article.cfm%5earticle=245.htm . */ in_uint32_le(in, delete_on_close); diff --git a/modules/rosapps/applications/net/tsclient/rdesktop/doc/lspci-channel.txt b/modules/rosapps/applications/net/tsclient/rdesktop/doc/lspci-channel.txt index 78645171e2a21..2b0ba3a6e4526 100644 --- a/modules/rosapps/applications/net/tsclient/rdesktop/doc/lspci-channel.txt +++ b/modules/rosapps/applications/net/tsclient/rdesktop/doc/lspci-channel.txt @@ -34,6 +34,6 @@ To enable to lspci virtual channel, run rdesktop with "-r lspci". References ========== -http://www.microsoft.com/msj/1099/terminal/terminal.aspx -http://msdn.microsoft.com/library/default.asp?url=/library/en-us/termserv/termserv/terminal_services_virtual_channels.asp +https://web.archive.org/web/20170905024329/http://www.microsoft.com/msj/1099/terminal/terminal.aspx +http://msdn.microsoft.com/library/default.asp?url=/library/en-us/termserv/termserv/terminal_services_virtual_channels.asp (DEAD_LINK) diff --git a/modules/rosapps/applications/net/tsclient/rdesktop/ewmhints.c b/modules/rosapps/applications/net/tsclient/rdesktop/ewmhints.c index e0b2e0aa59fe5..a0405d4c62a8b 100644 --- a/modules/rosapps/applications/net/tsclient/rdesktop/ewmhints.c +++ b/modules/rosapps/applications/net/tsclient/rdesktop/ewmhints.c @@ -2,7 +2,7 @@ rdesktop: A Remote Desktop Protocol client. Support functions for Extended Window Manager Hints, - http://www.freedesktop.org/wiki/Standards_2fwm_2dspec + https://web.archive.org/web/20060831082811/http://www.freedesktop.org/wiki/Standards_2fwm_2dspec Copyright (C) Peter Astrand 2005 diff --git a/modules/rosapps/applications/net/tsclient/rdesktop/mppc.c b/modules/rosapps/applications/net/tsclient/rdesktop/mppc.c index c5077356ed00f..208b304818ea1 100644 --- a/modules/rosapps/applications/net/tsclient/rdesktop/mppc.c +++ b/modules/rosapps/applications/net/tsclient/rdesktop/mppc.c @@ -50,7 +50,7 @@ /* patented for another couple of years. */ /* more information is available in */ -/* http://www.ietf.org/ietf/IPR/hifn-ipr-draft-friend-tls-lzs-compression.txt */ +/* https://web.archive.org/web/20231203135154/https://www.ietf.org/ietf-ftp/ietf/IPR/hifn-ipr-draft-friend-tls-lzs-compression.txt */ int mppc_expand(RDPCLIENT * This, uint8 * data, uint32 clen, uint8 ctype, uint32 * roff, uint32 * rlen) diff --git a/modules/rosapps/applications/net/tsclient/rdesktop/rdpdr.c b/modules/rosapps/applications/net/tsclient/rdesktop/rdpdr.c index dc6102b80dfa8..af5f8aaa38896 100644 --- a/modules/rosapps/applications/net/tsclient/rdesktop/rdpdr.c +++ b/modules/rosapps/applications/net/tsclient/rdesktop/rdpdr.c @@ -20,13 +20,13 @@ /* Here are some resources, for your IRP hacking pleasure: - http://cvs.sourceforge.net/viewcvs.py/mingw/w32api/include/ddk/winddk.h?view=markup + http://cvs.sourceforge.net/viewcvs.py/mingw/w32api/include/ddk/winddk.h?view=markup (DEAD_LINK) - http://win32.mvps.org/ntfs/streams.cpp + https://web.archive.org/web/20150616195443/http://win32.mvps.org/ntfs/streams.cpp http://www.acc.umu.se/~bosse/ntifs.h - http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/File/ + https://web.archive.org/web/20060430092752/http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/File/ http://us1.samba.org/samba/ftp/specs/smb-nt01.txt diff --git a/modules/rosapps/applications/net/tsclient/rdesktop/secure.c b/modules/rosapps/applications/net/tsclient/rdesktop/secure.c index 0653ea79bf69a..12f5a8e0d142e 100644 --- a/modules/rosapps/applications/net/tsclient/rdesktop/secure.c +++ b/modules/rosapps/applications/net/tsclient/rdesktop/secure.c @@ -425,7 +425,7 @@ sec_out_mcs_data(RDPCLIENT * This, STREAM s, wchar_t * hostname) out_uint8s(s, 30 - hostlen); /* See - http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceddk40/html/cxtsksupportingremotedesktopprotocol.asp */ + http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceddk40/html/cxtsksupportingremotedesktopprotocol.asp (DEAD_LINK) */ out_uint32_le(s, This->keyboard_type); out_uint32_le(s, This->keyboard_subtype); out_uint32_le(s, This->keyboard_functionkeys); diff --git a/modules/rosapps/applications/net/tsclient/rdesktop/xclip.c b/modules/rosapps/applications/net/tsclient/rdesktop/xclip.c index 1e8999f67c5a5..c056a0ef2422c 100644 --- a/modules/rosapps/applications/net/tsclient/rdesktop/xclip.c +++ b/modules/rosapps/applications/net/tsclient/rdesktop/xclip.c @@ -29,7 +29,7 @@ HTML: http://tronche.com/gui/x/icccm/ PDF: http://ftp.xfree86.org/pub/XFree86/4.5.0/doc/PDF/icccm.pdf - MSDN: Clipboard Formats - http://msdn.microsoft.com/library/en-us/winui/winui/windowsuserinterface/dataexchange/clipboard/clipboardformats.asp + https://web.archive.org/web/20080103082730/http://msdn2.microsoft.com/en-us/library/ms649013.aspx */ #ifdef HAVE_ICONV diff --git a/modules/rosapps/applications/notevil/notevil.rc b/modules/rosapps/applications/notevil/notevil.rc index cb36ff75b18d8..24840bd832469 100644 --- a/modules/rosapps/applications/notevil/notevil.rc +++ b/modules/rosapps/applications/notevil/notevil.rc @@ -24,7 +24,7 @@ /* UTF-8 */ #pragma code_page(65001) -STRINGTABLE MOVEABLE +STRINGTABLE BEGIN 1, "Aleksandar Andrejevic" 2, "Aleksey Bragin" @@ -43,7 +43,7 @@ BEGIN 15, "Brandon Turner" END -STRINGTABLE MOVEABLE +STRINGTABLE BEGIN 16, "Brian Palmer" 17, "Cameron M. Gutman" @@ -64,7 +64,7 @@ BEGIN 32, "Edijs Kolesnikovics" END -STRINGTABLE MOVEABLE +STRINGTABLE BEGIN 33, "Emanuele Aliberti" 34, "Eric Kohl" @@ -83,7 +83,7 @@ BEGIN 47, "Guido de Jong" END -STRINGTABLE MOVEABLE +STRINGTABLE BEGIN 48, "Gunnar Andre' Dalsnes" 49, "Hans Kremer" @@ -102,7 +102,7 @@ BEGIN 62, "Jeffrey Morlan" END -STRINGTABLE MOVEABLE +STRINGTABLE BEGIN 63, "Jens Collin" 64, "Jérôme Gardou" @@ -123,7 +123,7 @@ BEGIN 79, "Marc Piulachs" END -STRINGTABLE MOVEABLE +STRINGTABLE BEGIN 80, "Mark Tempel" 81, "Mark Weaver" @@ -142,7 +142,7 @@ BEGIN 94, "Neeraj Yadav" END -STRINGTABLE MOVEABLE +STRINGTABLE BEGIN 95, "Olaf Siejka" 96, "Oleg Dubinskij" @@ -162,7 +162,7 @@ BEGIN 110, "Samuel Serapión" END -STRINGTABLE MOVEABLE +STRINGTABLE BEGIN 111, "Saveliy Tretiakov" 112, "Sebastian Gasiorek" diff --git a/modules/rosapps/applications/screensavers/blankscr/lang/bg-BG.rc b/modules/rosapps/applications/screensavers/blankscr/lang/bg-BG.rc index 3024d41f1bc40..be118c30ed801 100644 --- a/modules/rosapps/applications/screensavers/blankscr/lang/bg-BG.rc +++ b/modules/rosapps/applications/screensavers/blankscr/lang/bg-BG.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_BULGARIAN, SUBLANG_DEFAULT -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Blank" IDS_TEXT "Няма възможност за настройки." diff --git a/modules/rosapps/applications/screensavers/blankscr/lang/de-DE.rc b/modules/rosapps/applications/screensavers/blankscr/lang/de-DE.rc index 7c0d2452389d5..da90fbe1f7b77 100644 --- a/modules/rosapps/applications/screensavers/blankscr/lang/de-DE.rc +++ b/modules/rosapps/applications/screensavers/blankscr/lang/de-DE.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Schwarzer Bildschirm" IDS_TEXT "Keine Einstellungen notwendig." diff --git a/modules/rosapps/applications/screensavers/blankscr/lang/en-US.rc b/modules/rosapps/applications/screensavers/blankscr/lang/en-US.rc index 078bac53e8cbb..4cb31045a3b69 100644 --- a/modules/rosapps/applications/screensavers/blankscr/lang/en-US.rc +++ b/modules/rosapps/applications/screensavers/blankscr/lang/en-US.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Blank screen" IDS_TEXT "No options need to be set." diff --git a/modules/rosapps/applications/screensavers/blankscr/lang/es-ES.rc b/modules/rosapps/applications/screensavers/blankscr/lang/es-ES.rc index ffcd986707a73..c28d25fb0cdd4 100644 --- a/modules/rosapps/applications/screensavers/blankscr/lang/es-ES.rc +++ b/modules/rosapps/applications/screensavers/blankscr/lang/es-ES.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "En blanco" IDS_TEXT "Ninguna opción necesita ser configurada." diff --git a/modules/rosapps/applications/screensavers/blankscr/lang/fr-FR.rc b/modules/rosapps/applications/screensavers/blankscr/lang/fr-FR.rc index 71b013f1a1b09..9af20ffaf1a55 100644 --- a/modules/rosapps/applications/screensavers/blankscr/lang/fr-FR.rc +++ b/modules/rosapps/applications/screensavers/blankscr/lang/fr-FR.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Vide" IDS_TEXT "Il n'y a aucune option à définir." diff --git a/modules/rosapps/applications/screensavers/blankscr/lang/it-IT.rc b/modules/rosapps/applications/screensavers/blankscr/lang/it-IT.rc index 0a2ff10a2140d..468b4775d8159 100644 --- a/modules/rosapps/applications/screensavers/blankscr/lang/it-IT.rc +++ b/modules/rosapps/applications/screensavers/blankscr/lang/it-IT.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Schermo nero" IDS_TEXT "Non ci sono opzioni da impostare." diff --git a/modules/rosapps/applications/screensavers/blankscr/lang/lt-LT.rc b/modules/rosapps/applications/screensavers/blankscr/lang/lt-LT.rc index 713e3c80b0c83..ca91793ee39fa 100644 --- a/modules/rosapps/applications/screensavers/blankscr/lang/lt-LT.rc +++ b/modules/rosapps/applications/screensavers/blankscr/lang/lt-LT.rc @@ -9,7 +9,7 @@ LANGUAGE LANG_LITHUANIAN, SUBLANG_DEFAULT -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Tuščias" IDS_TEXT "Nėra keičiamų parametrų." diff --git a/modules/rosapps/applications/screensavers/blankscr/lang/nl-NL.rc b/modules/rosapps/applications/screensavers/blankscr/lang/nl-NL.rc index 6008bd7c4ebc3..dd765f8a12514 100644 --- a/modules/rosapps/applications/screensavers/blankscr/lang/nl-NL.rc +++ b/modules/rosapps/applications/screensavers/blankscr/lang/nl-NL.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Blank" IDS_TEXT "Geen dingen om in te stellen." diff --git a/modules/rosapps/applications/screensavers/blankscr/lang/no-NO.rc b/modules/rosapps/applications/screensavers/blankscr/lang/no-NO.rc index bd4eaa1a56ea7..99103e3375bd8 100644 --- a/modules/rosapps/applications/screensavers/blankscr/lang/no-NO.rc +++ b/modules/rosapps/applications/screensavers/blankscr/lang/no-NO.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_NORWEGIAN, SUBLANG_NEUTRAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Tom skjerm" IDS_TEXT "Ingen valg trenger å settes." diff --git a/modules/rosapps/applications/screensavers/blankscr/lang/pl-PL.rc b/modules/rosapps/applications/screensavers/blankscr/lang/pl-PL.rc index 88ff617fb50f9..9f96672ef1fe6 100644 --- a/modules/rosapps/applications/screensavers/blankscr/lang/pl-PL.rc +++ b/modules/rosapps/applications/screensavers/blankscr/lang/pl-PL.rc @@ -7,7 +7,7 @@ LANGUAGE LANG_POLISH, SUBLANG_DEFAULT -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Puste" IDS_TEXT "Brak opcji do ustawiania." diff --git a/modules/rosapps/applications/screensavers/blankscr/lang/ro-RO.rc b/modules/rosapps/applications/screensavers/blankscr/lang/ro-RO.rc index c0e34e20dbbdc..282c8f56810e7 100644 --- a/modules/rosapps/applications/screensavers/blankscr/lang/ro-RO.rc +++ b/modules/rosapps/applications/screensavers/blankscr/lang/ro-RO.rc @@ -8,9 +8,7 @@ LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL -#pragma code_page(65001) - -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Ecran gol (animație de inactivitate)" IDS_TEXT "Nu este necesară stabilirea de opțiuni." diff --git a/modules/rosapps/applications/screensavers/blankscr/lang/ru-RU.rc b/modules/rosapps/applications/screensavers/blankscr/lang/ru-RU.rc index 7b7dd145ecd40..0ccaa35eeee47 100644 --- a/modules/rosapps/applications/screensavers/blankscr/lang/ru-RU.rc +++ b/modules/rosapps/applications/screensavers/blankscr/lang/ru-RU.rc @@ -8,7 +8,7 @@ LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Заставка ""Пустой экран""" IDS_TEXT "Эта заставка не имеет настраиваемых параметров." diff --git a/modules/rosapps/applications/screensavers/blankscr/lang/sk-SK.rc b/modules/rosapps/applications/screensavers/blankscr/lang/sk-SK.rc index ec1ae29a99cc2..abdbc5c42012b 100644 --- a/modules/rosapps/applications/screensavers/blankscr/lang/sk-SK.rc +++ b/modules/rosapps/applications/screensavers/blankscr/lang/sk-SK.rc @@ -4,7 +4,7 @@ LANGUAGE LANG_SLOVAK, SUBLANG_DEFAULT -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Blank" IDS_TEXT "Nie sú potrebné žiadne nastavenia." diff --git a/modules/rosapps/applications/screensavers/blankscr/lang/tr-TR.rc b/modules/rosapps/applications/screensavers/blankscr/lang/tr-TR.rc index 52754a1681bd1..0e5904868c2f9 100644 --- a/modules/rosapps/applications/screensavers/blankscr/lang/tr-TR.rc +++ b/modules/rosapps/applications/screensavers/blankscr/lang/tr-TR.rc @@ -7,7 +7,7 @@ LANGUAGE LANG_TURKISH, SUBLANG_NEUTRAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Boş ekran" IDS_TEXT "Hiçbir seçeneğin ayarlanması gerekmez." diff --git a/modules/rosapps/applications/screensavers/blankscr/lang/uk-UA.rc b/modules/rosapps/applications/screensavers/blankscr/lang/uk-UA.rc index bab25b297f541..69d0e92012dac 100644 --- a/modules/rosapps/applications/screensavers/blankscr/lang/uk-UA.rc +++ b/modules/rosapps/applications/screensavers/blankscr/lang/uk-UA.rc @@ -8,7 +8,7 @@ LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Порожньо" IDS_TEXT "Ця заставка не має налаштовуваних параметрів." diff --git a/modules/rosapps/applications/screensavers/blankscr/lang/zh-CN.rc b/modules/rosapps/applications/screensavers/blankscr/lang/zh-CN.rc index 0fdae152b3711..79ae6f45fc21e 100644 --- a/modules/rosapps/applications/screensavers/blankscr/lang/zh-CN.rc +++ b/modules/rosapps/applications/screensavers/blankscr/lang/zh-CN.rc @@ -2,7 +2,7 @@ LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "空白屏幕" IDS_TEXT "没有需要设置的选项。" diff --git a/modules/rosapps/applications/screensavers/blankscr/lang/zh-HK.rc b/modules/rosapps/applications/screensavers/blankscr/lang/zh-HK.rc index eb3023298fb7d..a99425b47054e 100644 --- a/modules/rosapps/applications/screensavers/blankscr/lang/zh-HK.rc +++ b/modules/rosapps/applications/screensavers/blankscr/lang/zh-HK.rc @@ -7,7 +7,7 @@ LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_HONGKONG -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "空白螢幕" IDS_TEXT "沒有可設定的選項。" diff --git a/modules/rosapps/applications/screensavers/blankscr/lang/zh-TW.rc b/modules/rosapps/applications/screensavers/blankscr/lang/zh-TW.rc index 3458789197c5f..2de75773dda18 100644 --- a/modules/rosapps/applications/screensavers/blankscr/lang/zh-TW.rc +++ b/modules/rosapps/applications/screensavers/blankscr/lang/zh-TW.rc @@ -7,7 +7,7 @@ LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "空白螢幕" IDS_TEXT "沒有可設定的選項。" diff --git a/modules/rosapps/applications/screensavers/blankscr/scrnsave.rc b/modules/rosapps/applications/screensavers/blankscr/scrnsave.rc index cb34fae774d37..e843c42366ed3 100644 --- a/modules/rosapps/applications/screensavers/blankscr/scrnsave.rc +++ b/modules/rosapps/applications/screensavers/blankscr/scrnsave.rc @@ -4,12 +4,12 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL -IDI_ICON ICON DISCARDABLE "res/icon_blankscr.ico" +IDI_ICON ICON "res/icon_blankscr.ico" #define REACTOS_VERSION_DLL -#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Default ScreenSaver\0" -#define REACTOS_STR_INTERNAL_NAME "scrnsave\0" -#define REACTOS_STR_ORIGINAL_FILENAME "scrnsave.scr\0" +#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Default ScreenSaver" +#define REACTOS_STR_INTERNAL_NAME "scrnsave" +#define REACTOS_STR_ORIGINAL_FILENAME "scrnsave.scr" #include #include diff --git a/modules/rosapps/applications/screensavers/butterflies/butterflies.rc b/modules/rosapps/applications/screensavers/butterflies/butterflies.rc index 36962cc10122c..943ea78bab578 100644 --- a/modules/rosapps/applications/screensavers/butterflies/butterflies.rc +++ b/modules/rosapps/applications/screensavers/butterflies/butterflies.rc @@ -4,9 +4,9 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL #define REACTOS_VERSION_DLL -#define REACTOS_STR_FILE_DESCRIPTION "Butterflies ScreenSaver\0" -#define REACTOS_STR_INTERNAL_NAME "butterflies\0" -#define REACTOS_STR_ORIGINAL_FILENAME "butterflies.scr\0" +#define REACTOS_STR_FILE_DESCRIPTION "Butterflies ScreenSaver" +#define REACTOS_STR_INTERNAL_NAME "butterflies" +#define REACTOS_STR_ORIGINAL_FILENAME "butterflies.scr" #include IDI_ICON ICON "res/icon_butterflies.ico" diff --git a/modules/rosapps/applications/screensavers/butterflies/lang/bg-BG.rc b/modules/rosapps/applications/screensavers/butterflies/lang/bg-BG.rc index 57b3701914faf..e56781d023fa9 100644 --- a/modules/rosapps/applications/screensavers/butterflies/lang/bg-BG.rc +++ b/modules/rosapps/applications/screensavers/butterflies/lang/bg-BG.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_BULGARIAN, SUBLANG_DEFAULT -IDD_DLG_SCREEN DIALOGEX DISCARDABLE 0, 0, 172, 57 +IDD_DLG_SCREEN DIALOGEX 0, 0, 172, 57 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Екранен предпазител с пеперуди" FONT 8, "MS Shell Dlg" @@ -12,7 +12,7 @@ BEGIN PUSHBUTTON "За",IDABOUT,115,35,50,14 END -IDD_DLG_ABOUT DIALOGEX DISCARDABLE 0, 0, 149, 79 +IDD_DLG_ABOUT DIALOGEX 0, 0, 149, 79 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "За" FONT 8, "MS Shell Dlg" @@ -28,7 +28,7 @@ BEGIN NOT WS_GROUP END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Butterflies ScreenSaver" END diff --git a/modules/rosapps/applications/screensavers/butterflies/lang/de-DE.rc b/modules/rosapps/applications/screensavers/butterflies/lang/de-DE.rc index 2a9cba82a3ec5..0207848b0bf87 100644 --- a/modules/rosapps/applications/screensavers/butterflies/lang/de-DE.rc +++ b/modules/rosapps/applications/screensavers/butterflies/lang/de-DE.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL -IDD_DLG_SCREEN DIALOGEX DISCARDABLE 0, 0, 172, 57 +IDD_DLG_SCREEN DIALOGEX 0, 0, 172, 57 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Schmetterlinge Einstellungen" FONT 8, "MS Shell Dlg" @@ -12,7 +12,7 @@ BEGIN PUSHBUTTON "Über",IDABOUT,115,35,50,14 END -IDD_DLG_ABOUT DIALOGEX DISCARDABLE 0, 0, 149, 79 +IDD_DLG_ABOUT DIALOGEX 0, 0, 149, 79 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Über" FONT 8, "MS Shell Dlg" @@ -28,7 +28,7 @@ BEGIN NOT WS_GROUP END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Butterflies Bildschirmschoner" END diff --git a/modules/rosapps/applications/screensavers/butterflies/lang/en-US.rc b/modules/rosapps/applications/screensavers/butterflies/lang/en-US.rc index 011607810e632..1724c4571ad69 100644 --- a/modules/rosapps/applications/screensavers/butterflies/lang/en-US.rc +++ b/modules/rosapps/applications/screensavers/butterflies/lang/en-US.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -IDD_DLG_SCREEN DIALOGEX DISCARDABLE 0, 0, 172, 57 +IDD_DLG_SCREEN DIALOGEX 0, 0, 172, 57 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Butterflies ScreenSaver Settings" FONT 8, "MS Shell Dlg" @@ -12,7 +12,7 @@ BEGIN PUSHBUTTON "About",IDABOUT,115,35,50,14 END -IDD_DLG_ABOUT DIALOGEX DISCARDABLE 0, 0, 149, 79 +IDD_DLG_ABOUT DIALOGEX 0, 0, 149, 79 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "About" FONT 8, "MS Shell Dlg" @@ -28,7 +28,7 @@ BEGIN NOT WS_GROUP END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Butterflies ScreenSaver" END diff --git a/modules/rosapps/applications/screensavers/butterflies/lang/es-ES.rc b/modules/rosapps/applications/screensavers/butterflies/lang/es-ES.rc index 03f19130b676c..05fde1103b13a 100644 --- a/modules/rosapps/applications/screensavers/butterflies/lang/es-ES.rc +++ b/modules/rosapps/applications/screensavers/butterflies/lang/es-ES.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL -IDD_DLG_SCREEN DIALOGEX DISCARDABLE 0, 0, 172, 57 +IDD_DLG_SCREEN DIALOGEX 0, 0, 172, 57 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Configuración del Salvapantallas de Mariposas" FONT 8, "MS Shell Dlg" @@ -12,7 +12,7 @@ BEGIN PUSHBUTTON "Acerca de",IDABOUT,115,35,50,14 END -IDD_DLG_ABOUT DIALOGEX DISCARDABLE 0, 0, 149, 79 +IDD_DLG_ABOUT DIALOGEX 0, 0, 149, 79 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Acerca de" FONT 8, "MS Shell Dlg" @@ -28,7 +28,7 @@ BEGIN NOT WS_GROUP END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Salvapantallas de Mariposas revoloteando" END diff --git a/modules/rosapps/applications/screensavers/butterflies/lang/fr-FR.rc b/modules/rosapps/applications/screensavers/butterflies/lang/fr-FR.rc index 13f0998fee4eb..6332326bc5456 100644 --- a/modules/rosapps/applications/screensavers/butterflies/lang/fr-FR.rc +++ b/modules/rosapps/applications/screensavers/butterflies/lang/fr-FR.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL -IDD_DLG_SCREEN DIALOGEX DISCARDABLE 0, 0, 172, 57 +IDD_DLG_SCREEN DIALOGEX 0, 0, 172, 57 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Configuration de l'écran de veille de papillons" FONT 8, "MS Shell Dlg" @@ -12,7 +12,7 @@ BEGIN PUSHBUTTON "À propos de",IDABOUT,115,35,50,14 END -IDD_DLG_ABOUT DIALOGEX DISCARDABLE 0, 0, 149, 79 +IDD_DLG_ABOUT DIALOGEX 0, 0, 149, 79 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "À propos de" FONT 8, "MS Shell Dlg" @@ -28,7 +28,7 @@ BEGIN NOT WS_GROUP END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Écran de veille de papillons" END diff --git a/modules/rosapps/applications/screensavers/butterflies/lang/it-IT.rc b/modules/rosapps/applications/screensavers/butterflies/lang/it-IT.rc index 5e9b02ce71d76..d4d7856fe1fe0 100644 --- a/modules/rosapps/applications/screensavers/butterflies/lang/it-IT.rc +++ b/modules/rosapps/applications/screensavers/butterflies/lang/it-IT.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL -IDD_DLG_SCREEN DIALOGEX DISCARDABLE 0, 0, 172, 57 +IDD_DLG_SCREEN DIALOGEX 0, 0, 172, 57 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Impostazioni salvaschermo" FONT 8, "MS Shell Dlg" @@ -12,7 +12,7 @@ BEGIN PUSHBUTTON "Informazioni",IDABOUT,115,35,50,14 END -IDD_DLG_ABOUT DIALOGEX DISCARDABLE 0, 0, 149, 79 +IDD_DLG_ABOUT DIALOGEX 0, 0, 149, 79 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Informazioni" FONT 8, "MS Shell Dlg" @@ -28,7 +28,7 @@ BEGIN NOT WS_GROUP END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Salvaschermo Farfalle" END diff --git a/modules/rosapps/applications/screensavers/butterflies/lang/lt-LT.rc b/modules/rosapps/applications/screensavers/butterflies/lang/lt-LT.rc index 10380a7dffa82..339779ff1d151 100644 --- a/modules/rosapps/applications/screensavers/butterflies/lang/lt-LT.rc +++ b/modules/rosapps/applications/screensavers/butterflies/lang/lt-LT.rc @@ -9,7 +9,7 @@ LANGUAGE LANG_LITHUANIAN, SUBLANG_DEFAULT -IDD_DLG_SCREEN DIALOGEX DISCARDABLE 0, 0, 172, 57 +IDD_DLG_SCREEN DIALOGEX 0, 0, 172, 57 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Ekrano užsklandos nustatymai" FONT 8, "MS Shell Dlg" @@ -21,7 +21,7 @@ BEGIN PUSHBUTTON "Apie",IDABOUT,115,35,50,14 END -IDD_DLG_ABOUT DIALOGEX DISCARDABLE 0, 0, 149, 79 +IDD_DLG_ABOUT DIALOGEX 0, 0, 149, 79 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Apie" FONT 8, "MS Shell Dlg" @@ -37,7 +37,7 @@ BEGIN NOT WS_GROUP END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Drugeliai" END diff --git a/modules/rosapps/applications/screensavers/butterflies/lang/no-NO.rc b/modules/rosapps/applications/screensavers/butterflies/lang/no-NO.rc index a129375254a63..9f5449e5b5955 100644 --- a/modules/rosapps/applications/screensavers/butterflies/lang/no-NO.rc +++ b/modules/rosapps/applications/screensavers/butterflies/lang/no-NO.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_NORWEGIAN, SUBLANG_NEUTRAL -IDD_DLG_SCREEN DIALOGEX DISCARDABLE 0, 0, 172, 57 +IDD_DLG_SCREEN DIALOGEX 0, 0, 172, 57 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Sommerfugl skjermsparer innstilling" FONT 8, "MS Shell Dlg" @@ -12,7 +12,7 @@ BEGIN PUSHBUTTON "Om",IDABOUT,115,35,50,14 END -IDD_DLG_ABOUT DIALOGEX DISCARDABLE 0, 0, 149, 79 +IDD_DLG_ABOUT DIALOGEX 0, 0, 149, 79 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Om" FONT 8, "MS Shell Dlg" @@ -28,7 +28,7 @@ BEGIN NOT WS_GROUP END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Sommerfugl skjermsparer" END diff --git a/modules/rosapps/applications/screensavers/butterflies/lang/pl-PL.rc b/modules/rosapps/applications/screensavers/butterflies/lang/pl-PL.rc index 0d5eb4213e395..9fca4c612831a 100644 --- a/modules/rosapps/applications/screensavers/butterflies/lang/pl-PL.rc +++ b/modules/rosapps/applications/screensavers/butterflies/lang/pl-PL.rc @@ -7,7 +7,7 @@ LANGUAGE LANG_POLISH, SUBLANG_DEFAULT -IDD_DLG_SCREEN DIALOGEX DISCARDABLE 0, 0, 172, 57 +IDD_DLG_SCREEN DIALOGEX 0, 0, 172, 57 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Ustawienia wygaszacza Motylki" FONT 8, "MS Shell Dlg" @@ -19,7 +19,7 @@ BEGIN PUSHBUTTON "O programie",IDABOUT,115,35,50,14 END -IDD_DLG_ABOUT DIALOGEX DISCARDABLE 0, 0, 149, 79 +IDD_DLG_ABOUT DIALOGEX 0, 0, 149, 79 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "O programie" FONT 8, "MS Shell Dlg" @@ -35,7 +35,7 @@ BEGIN NOT WS_GROUP END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Motylki" END diff --git a/modules/rosapps/applications/screensavers/butterflies/lang/ro-RO.rc b/modules/rosapps/applications/screensavers/butterflies/lang/ro-RO.rc index add5f7b6da779..d03a964334abd 100644 --- a/modules/rosapps/applications/screensavers/butterflies/lang/ro-RO.rc +++ b/modules/rosapps/applications/screensavers/butterflies/lang/ro-RO.rc @@ -1,44 +1,42 @@ /* - * PROJECT: ReactOS Butterflies ScreenSaver - * LICENSE: GPL - See COPYING in the top level directory - * FILE: rosapps/applications/screensavers/butterflies/lang/ro-RO.rc - * PURPOSE: Romanian Language File for Butterflies ScreenSaver - * TRANSLATOR: Ștefan Fulea (stefan dot fulea at mail dot com) + * PROJECT: Butterflies ScreenSaver + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Romanian resource file + * TRANSLATORS: Copyright 2011-2018 Ștefan Fulea + * Copyright 2024-2025 Andrei Miloiu */ LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL -#pragma code_page(65001) - -IDD_DLG_SCREEN DIALOGEX DISCARDABLE 0, 0, 172, 57 +IDD_DLG_SCREEN DIALOGEX 0, 0, 172, 57 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Oprțiuni animație de inactivitate Fluturi" +CAPTION "Setări pentru economizorul de ecran Fluturi" FONT 8, "MS Shell Dlg" BEGIN - DEFPUSHBUTTON "Con&firmă",IDOK,7,35,50,14 - PUSHBUTTON "A&nulează",IDCANCEL,61,35,50,14 + DEFPUSHBUTTON "OK",IDOK,7,35,50,14 + PUSHBUTTON "Revocare",IDCANCEL,61,35,50,14 CONTROL "&Rotește Fluturi",ROTATE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,56,15,70,8 - PUSHBUTTON "&Despre…",IDABOUT,115,35,50,14 + PUSHBUTTON "&Despre",IDABOUT,115,35,50,14 END -IDD_DLG_ABOUT DIALOGEX DISCARDABLE 0, 0, 149, 79 +IDD_DLG_ABOUT DIALOGEX 0, 0, 149, 79 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Despre" FONT 8, "MS Shell Dlg" BEGIN - DEFPUSHBUTTON "Î&nchide",IDOK,48,58,56,14 - CTEXT "Animație de inactivitate Fluturi",IDC_STATIC,7,7,135,9 + DEFPUSHBUTTON "OK",IDOK,48,58,56,14 + CTEXT "Economizorul de ecran Fluturi",IDC_STATIC,7,7,135,9 CTEXT "Versiune demonstrativă de: NeHe ",IDC_STATIC,7,20,135,8 CTEXT "http://nehe.gamedev.net",WEBPAGE1,7,29,135,8,SS_NOTIFY | NOT WS_GROUP - CTEXT "Animație de inactivitate de: tHaPuTeR",IDC_STATIC,7,38,135,8,NOT + CTEXT "Economizor de ecran de: tHaPuTeR",IDC_STATIC,7,38,135,8,NOT WS_GROUP CTEXT "http://www.thaputer.com",WEBPAGE2,7,47,135,8,SS_NOTIFY | NOT WS_GROUP END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN - IDS_DESCRIPTION "Fluturi (animație de inactivitate)" + IDS_DESCRIPTION "Economizorul de ecran Fluturi" END diff --git a/modules/rosapps/applications/screensavers/butterflies/lang/ru-RU.rc b/modules/rosapps/applications/screensavers/butterflies/lang/ru-RU.rc index af14eab3c8ac0..daf636b8656f5 100644 --- a/modules/rosapps/applications/screensavers/butterflies/lang/ru-RU.rc +++ b/modules/rosapps/applications/screensavers/butterflies/lang/ru-RU.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT -IDD_DLG_SCREEN DIALOGEX DISCARDABLE 0, 0, 172, 57 +IDD_DLG_SCREEN DIALOGEX 0, 0, 172, 57 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Параметры заставки ""Бабочки""" FONT 8, "MS Shell Dlg" @@ -12,7 +12,7 @@ BEGIN PUSHBUTTON "О программе",IDABOUT,115,35,50,14 END -IDD_DLG_ABOUT DIALOGEX DISCARDABLE 0, 0, 149, 79 +IDD_DLG_ABOUT DIALOGEX 0, 0, 149, 79 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "" FONT 8, "MS Shell Dlg" @@ -28,7 +28,7 @@ BEGIN NOT WS_GROUP END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Заставка ""Бабочки""" END diff --git a/modules/rosapps/applications/screensavers/butterflies/lang/sk-SK.rc b/modules/rosapps/applications/screensavers/butterflies/lang/sk-SK.rc index 75df4308f3fb6..8677f487a2b68 100644 --- a/modules/rosapps/applications/screensavers/butterflies/lang/sk-SK.rc +++ b/modules/rosapps/applications/screensavers/butterflies/lang/sk-SK.rc @@ -4,7 +4,7 @@ LANGUAGE LANG_SLOVAK, SUBLANG_DEFAULT -IDD_DLG_SCREEN DIALOGEX DISCARDABLE 0, 0, 172, 57 +IDD_DLG_SCREEN DIALOGEX 0, 0, 172, 57 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Nastavenie šetriča obrazovky Motýle" FONT 8, "MS Shell Dlg" @@ -16,7 +16,7 @@ BEGIN PUSHBUTTON "Čo je ...",IDABOUT,115,35,50,14 END -IDD_DLG_ABOUT DIALOGEX DISCARDABLE 0, 0, 149, 79 +IDD_DLG_ABOUT DIALOGEX 0, 0, 149, 79 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Čo je ..." FONT 8, "MS Shell Dlg" @@ -32,7 +32,7 @@ BEGIN NOT WS_GROUP END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Motýle - šetrič obrazovky" END diff --git a/modules/rosapps/applications/screensavers/butterflies/lang/tr-TR.rc b/modules/rosapps/applications/screensavers/butterflies/lang/tr-TR.rc index 44c5d9646aaa8..ad3355bc55391 100644 --- a/modules/rosapps/applications/screensavers/butterflies/lang/tr-TR.rc +++ b/modules/rosapps/applications/screensavers/butterflies/lang/tr-TR.rc @@ -7,7 +7,7 @@ LANGUAGE LANG_TURKISH, SUBLANG_NEUTRAL -IDD_DLG_SCREEN DIALOGEX DISCARDABLE 0, 0, 172, 57 +IDD_DLG_SCREEN DIALOGEX 0, 0, 172, 57 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Kelebekler Ekran Koruyucusu Ayarları" FONT 8, "MS Shell Dlg" @@ -19,7 +19,7 @@ BEGIN PUSHBUTTON "Hakkında",IDABOUT,115,35,50,14 END -IDD_DLG_ABOUT DIALOGEX DISCARDABLE 0, 0, 149, 79 +IDD_DLG_ABOUT DIALOGEX 0, 0, 149, 79 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Hakkında" FONT 8, "MS Shell Dlg" @@ -35,7 +35,7 @@ BEGIN NOT WS_GROUP END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Kelebekler Ekran Koruyucusu" END diff --git a/modules/rosapps/applications/screensavers/butterflies/lang/uk-UA.rc b/modules/rosapps/applications/screensavers/butterflies/lang/uk-UA.rc index 44a76d171ec72..4cc84b6322ec1 100644 --- a/modules/rosapps/applications/screensavers/butterflies/lang/uk-UA.rc +++ b/modules/rosapps/applications/screensavers/butterflies/lang/uk-UA.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT -IDD_DLG_SCREEN DIALOGEX DISCARDABLE 0, 0, 172, 57 +IDD_DLG_SCREEN DIALOGEX 0, 0, 172, 57 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Параметри заставки ""Метелики""" FONT 8, "MS Shell Dlg" @@ -12,7 +12,7 @@ BEGIN PUSHBUTTON "Про",IDABOUT,115,35,50,14 END -IDD_DLG_ABOUT DIALOGEX DISCARDABLE 0, 0, 149, 79 +IDD_DLG_ABOUT DIALOGEX 0, 0, 149, 79 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Про" FONT 8, "MS Shell Dlg" @@ -28,7 +28,7 @@ BEGIN NOT WS_GROUP END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Заставка ""Метелики""" END diff --git a/modules/rosapps/applications/screensavers/butterflies/lang/zh-CN.rc b/modules/rosapps/applications/screensavers/butterflies/lang/zh-CN.rc index ea949fd25affd..07f4f2f8ad7f5 100644 --- a/modules/rosapps/applications/screensavers/butterflies/lang/zh-CN.rc +++ b/modules/rosapps/applications/screensavers/butterflies/lang/zh-CN.rc @@ -2,7 +2,7 @@ LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED -IDD_DLG_SCREEN DIALOGEX DISCARDABLE 0, 0, 172, 57 +IDD_DLG_SCREEN DIALOGEX 0, 0, 172, 57 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "蝴蝶屏幕保护程序设置" FONT 9, "宋体" @@ -14,7 +14,7 @@ BEGIN PUSHBUTTON "关于",IDABOUT,115,35,50,14 END -IDD_DLG_ABOUT DIALOGEX DISCARDABLE 0, 0, 149, 79 +IDD_DLG_ABOUT DIALOGEX 0, 0, 149, 79 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "关于" FONT 9, "宋体" @@ -30,7 +30,7 @@ BEGIN NOT WS_GROUP END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "蝴蝶屏幕保护程序" END diff --git a/modules/rosapps/applications/screensavers/butterflies/lang/zh-HK.rc b/modules/rosapps/applications/screensavers/butterflies/lang/zh-HK.rc index a22854e80b279..c7c95780b1144 100644 --- a/modules/rosapps/applications/screensavers/butterflies/lang/zh-HK.rc +++ b/modules/rosapps/applications/screensavers/butterflies/lang/zh-HK.rc @@ -7,7 +7,7 @@ LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_HONGKONG -IDD_DLG_SCREEN DIALOGEX DISCARDABLE 0, 0, 172, 57 +IDD_DLG_SCREEN DIALOGEX 0, 0, 172, 57 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "蝴蝶螢幕保護程式設定" FONT 9, "新細明體" @@ -19,7 +19,7 @@ BEGIN PUSHBUTTON "關於",IDABOUT,115,35,50,14 END -IDD_DLG_ABOUT DIALOGEX DISCARDABLE 0, 0, 149, 79 +IDD_DLG_ABOUT DIALOGEX 0, 0, 149, 79 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "關於" FONT 9, "新細明體" @@ -35,7 +35,7 @@ BEGIN NOT WS_GROUP END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "蝴蝶螢幕保護程式" END diff --git a/modules/rosapps/applications/screensavers/butterflies/lang/zh-TW.rc b/modules/rosapps/applications/screensavers/butterflies/lang/zh-TW.rc index 83d2ea00b192d..3ee86ab4d8635 100644 --- a/modules/rosapps/applications/screensavers/butterflies/lang/zh-TW.rc +++ b/modules/rosapps/applications/screensavers/butterflies/lang/zh-TW.rc @@ -7,7 +7,7 @@ LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL -IDD_DLG_SCREEN DIALOGEX DISCARDABLE 0, 0, 172, 57 +IDD_DLG_SCREEN DIALOGEX 0, 0, 172, 57 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "蝴蝶螢幕保護程式設定" FONT 9, "新細明體" @@ -19,7 +19,7 @@ BEGIN PUSHBUTTON "關於",IDABOUT,115,35,50,14 END -IDD_DLG_ABOUT DIALOGEX DISCARDABLE 0, 0, 149, 79 +IDD_DLG_ABOUT DIALOGEX 0, 0, 149, 79 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "關於" FONT 9, "新細明體" @@ -35,7 +35,7 @@ BEGIN NOT WS_GROUP END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "蝴蝶螢幕保護程式" END diff --git a/modules/rosapps/applications/screensavers/circles/circles.rc b/modules/rosapps/applications/screensavers/circles/circles.rc index 6e858536e06d5..5b920a17799b6 100644 --- a/modules/rosapps/applications/screensavers/circles/circles.rc +++ b/modules/rosapps/applications/screensavers/circles/circles.rc @@ -4,12 +4,12 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL -IDI_ICON ICON DISCARDABLE "res/icon_circles.ico" +IDI_ICON ICON "res/icon_circles.ico" #define REACTOS_VERSION_DLL -#define REACTOS_STR_FILE_DESCRIPTION "Circles ScreenSaver\0" -#define REACTOS_STR_INTERNAL_NAME "circles\0" -#define REACTOS_STR_ORIGINAL_FILENAME "circles.scr\0" +#define REACTOS_STR_FILE_DESCRIPTION "Circles ScreenSaver" +#define REACTOS_STR_INTERNAL_NAME "circles" +#define REACTOS_STR_ORIGINAL_FILENAME "circles.scr" #include diff --git a/modules/rosapps/applications/screensavers/circles/lang/de-DE.rc b/modules/rosapps/applications/screensavers/circles/lang/de-DE.rc index 227a74d17a458..fe404e28d0306 100644 --- a/modules/rosapps/applications/screensavers/circles/lang/de-DE.rc +++ b/modules/rosapps/applications/screensavers/circles/lang/de-DE.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Kreise" IDS_TEXT "Keine Einstellungen notwendig." diff --git a/modules/rosapps/applications/screensavers/circles/lang/en-US.rc b/modules/rosapps/applications/screensavers/circles/lang/en-US.rc index 231497fd03c43..8d4c12e860028 100644 --- a/modules/rosapps/applications/screensavers/circles/lang/en-US.rc +++ b/modules/rosapps/applications/screensavers/circles/lang/en-US.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Circles" IDS_TEXT "No options need to be set." diff --git a/modules/rosapps/applications/screensavers/circles/lang/es-ES.rc b/modules/rosapps/applications/screensavers/circles/lang/es-ES.rc index ac01f2a19d62e..81a91e41a113b 100644 --- a/modules/rosapps/applications/screensavers/circles/lang/es-ES.rc +++ b/modules/rosapps/applications/screensavers/circles/lang/es-ES.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Círculos" IDS_TEXT "Ninguna opción necesita ser configurada." diff --git a/modules/rosapps/applications/screensavers/circles/lang/fr-FR.rc b/modules/rosapps/applications/screensavers/circles/lang/fr-FR.rc index 94130ba64e762..cae1f1e72528f 100644 --- a/modules/rosapps/applications/screensavers/circles/lang/fr-FR.rc +++ b/modules/rosapps/applications/screensavers/circles/lang/fr-FR.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Cercles" IDS_TEXT "Il n'y a aucune option à définir." diff --git a/modules/rosapps/applications/screensavers/circles/lang/it-IT.rc b/modules/rosapps/applications/screensavers/circles/lang/it-IT.rc index d497837f57bf7..9d3072711ec26 100644 --- a/modules/rosapps/applications/screensavers/circles/lang/it-IT.rc +++ b/modules/rosapps/applications/screensavers/circles/lang/it-IT.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Cerchi" IDS_TEXT "Non ci sono opzioni da impostare." diff --git a/modules/rosapps/applications/screensavers/circles/lang/no-NO.rc b/modules/rosapps/applications/screensavers/circles/lang/no-NO.rc index ff5e94109a37e..efe8f9c634809 100644 --- a/modules/rosapps/applications/screensavers/circles/lang/no-NO.rc +++ b/modules/rosapps/applications/screensavers/circles/lang/no-NO.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_NORWEGIAN, SUBLANG_NEUTRAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Sirkeler" IDS_TEXT "Ingen valg trenges å settes." diff --git a/modules/rosapps/applications/screensavers/circles/lang/pl-PL.rc b/modules/rosapps/applications/screensavers/circles/lang/pl-PL.rc index b4d8b1ad23d50..20259c2db5c41 100644 --- a/modules/rosapps/applications/screensavers/circles/lang/pl-PL.rc +++ b/modules/rosapps/applications/screensavers/circles/lang/pl-PL.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_POLISH, SUBLANG_DEFAULT -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Kółka" IDS_TEXT "Brak opcji do ustawiania." diff --git a/modules/rosapps/applications/screensavers/circles/lang/ro-RO.rc b/modules/rosapps/applications/screensavers/circles/lang/ro-RO.rc index 230556ad54d39..e1c6594102cc3 100644 --- a/modules/rosapps/applications/screensavers/circles/lang/ro-RO.rc +++ b/modules/rosapps/applications/screensavers/circles/lang/ro-RO.rc @@ -8,9 +8,7 @@ LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL -#pragma code_page(65001) - -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Cercuri (animație de inactivitate)" IDS_TEXT "Nu este necesară stabilirea de opțiuni." diff --git a/modules/rosapps/applications/screensavers/circles/lang/ru-RU.rc b/modules/rosapps/applications/screensavers/circles/lang/ru-RU.rc index 17a01722b7c35..0508119b383e8 100644 --- a/modules/rosapps/applications/screensavers/circles/lang/ru-RU.rc +++ b/modules/rosapps/applications/screensavers/circles/lang/ru-RU.rc @@ -8,7 +8,7 @@ LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Заставка ""Круги""" IDS_TEXT "Эта заставка не имеет настраиваемых параметров." diff --git a/modules/rosapps/applications/screensavers/circles/lang/sk-SK.rc b/modules/rosapps/applications/screensavers/circles/lang/sk-SK.rc index 40e6f120e64fb..2bfbd0f3ba8b4 100644 --- a/modules/rosapps/applications/screensavers/circles/lang/sk-SK.rc +++ b/modules/rosapps/applications/screensavers/circles/lang/sk-SK.rc @@ -4,7 +4,7 @@ LANGUAGE LANG_SLOVAK, SUBLANG_DEFAULT -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Kruhy" IDS_TEXT "Nie sú potrebné žiadne nastavenia." diff --git a/modules/rosapps/applications/screensavers/circles/lang/tr-TR.rc b/modules/rosapps/applications/screensavers/circles/lang/tr-TR.rc index 76b81e8be7df7..c7e2b7fff29d4 100644 --- a/modules/rosapps/applications/screensavers/circles/lang/tr-TR.rc +++ b/modules/rosapps/applications/screensavers/circles/lang/tr-TR.rc @@ -7,7 +7,7 @@ LANGUAGE LANG_TURKISH, SUBLANG_NEUTRAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Çemberler" IDS_TEXT "Hiçbir seçeneğin ayarlanması gerekmez." diff --git a/modules/rosapps/applications/screensavers/circles/lang/uk-UA.rc b/modules/rosapps/applications/screensavers/circles/lang/uk-UA.rc index 876a582fe76dc..72b6d917699c7 100644 --- a/modules/rosapps/applications/screensavers/circles/lang/uk-UA.rc +++ b/modules/rosapps/applications/screensavers/circles/lang/uk-UA.rc @@ -8,7 +8,7 @@ LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Заставка ""Кола""" IDS_TEXT "Ця заставка не має налаштовуваних параметрів." diff --git a/modules/rosapps/applications/screensavers/circles/lang/zh-CN.rc b/modules/rosapps/applications/screensavers/circles/lang/zh-CN.rc index 676df289c24be..26a1386fd348a 100644 --- a/modules/rosapps/applications/screensavers/circles/lang/zh-CN.rc +++ b/modules/rosapps/applications/screensavers/circles/lang/zh-CN.rc @@ -2,7 +2,7 @@ LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "圆圈" IDS_TEXT "没有需要设置的选项。" diff --git a/modules/rosapps/applications/screensavers/circles/lang/zh-HK.rc b/modules/rosapps/applications/screensavers/circles/lang/zh-HK.rc index bf08667dd8522..e72c3a13caf2f 100644 --- a/modules/rosapps/applications/screensavers/circles/lang/zh-HK.rc +++ b/modules/rosapps/applications/screensavers/circles/lang/zh-HK.rc @@ -7,7 +7,7 @@ LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_HONGKONG -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "圓形" IDS_TEXT "沒有可設定的選項。" diff --git a/modules/rosapps/applications/screensavers/circles/lang/zh-TW.rc b/modules/rosapps/applications/screensavers/circles/lang/zh-TW.rc index 19983968d78a2..42992555755df 100644 --- a/modules/rosapps/applications/screensavers/circles/lang/zh-TW.rc +++ b/modules/rosapps/applications/screensavers/circles/lang/zh-TW.rc @@ -7,7 +7,7 @@ LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "圓形" IDS_TEXT "沒有可設定的選項。" diff --git a/modules/rosapps/applications/screensavers/cylfrac/cylfrac.rc b/modules/rosapps/applications/screensavers/cylfrac/cylfrac.rc index 4d481dbc74328..95decd17185c4 100644 --- a/modules/rosapps/applications/screensavers/cylfrac/cylfrac.rc +++ b/modules/rosapps/applications/screensavers/cylfrac/cylfrac.rc @@ -4,12 +4,12 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL -IDI_ICON ICON DISCARDABLE "res/icon_cylfrac.ico" +IDI_ICON ICON "res/icon_cylfrac.ico" #define REACTOS_VERSION_DLL -#define REACTOS_STR_FILE_DESCRIPTION "Cylinders fractal ScreenSaver\0" -#define REACTOS_STR_INTERNAL_NAME "cylfrac\0" -#define REACTOS_STR_ORIGINAL_FILENAME "cylfrac.scr\0" +#define REACTOS_STR_FILE_DESCRIPTION "Cylinders fractal ScreenSaver" +#define REACTOS_STR_INTERNAL_NAME "cylfrac" +#define REACTOS_STR_ORIGINAL_FILENAME "cylfrac.scr" #include diff --git a/modules/rosapps/applications/screensavers/cylfrac/lang/bg-BG.rc b/modules/rosapps/applications/screensavers/cylfrac/lang/bg-BG.rc index 41ff6b3336f46..b9ff60aee585a 100644 --- a/modules/rosapps/applications/screensavers/cylfrac/lang/bg-BG.rc +++ b/modules/rosapps/applications/screensavers/cylfrac/lang/bg-BG.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_BULGARIAN, SUBLANG_DEFAULT -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Цилиндрични фрактали" IDS_TITLE "За" diff --git a/modules/rosapps/applications/screensavers/cylfrac/lang/de-DE.rc b/modules/rosapps/applications/screensavers/cylfrac/lang/de-DE.rc index 99b0cbf849cac..841ef9b4cbfc1 100644 --- a/modules/rosapps/applications/screensavers/cylfrac/lang/de-DE.rc +++ b/modules/rosapps/applications/screensavers/cylfrac/lang/de-DE.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Cylinders Fractal" IDS_TITLE "Über" diff --git a/modules/rosapps/applications/screensavers/cylfrac/lang/en-US.rc b/modules/rosapps/applications/screensavers/cylfrac/lang/en-US.rc index dbdfceaff8084..f257d54b5f24e 100644 --- a/modules/rosapps/applications/screensavers/cylfrac/lang/en-US.rc +++ b/modules/rosapps/applications/screensavers/cylfrac/lang/en-US.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Cylinders fractal" IDS_TITLE "About" diff --git a/modules/rosapps/applications/screensavers/cylfrac/lang/es-ES.rc b/modules/rosapps/applications/screensavers/cylfrac/lang/es-ES.rc index 15d0fc362346c..c94e8866c08c9 100644 --- a/modules/rosapps/applications/screensavers/cylfrac/lang/es-ES.rc +++ b/modules/rosapps/applications/screensavers/cylfrac/lang/es-ES.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Cilindros fractales" IDS_TITLE "Acerca de" diff --git a/modules/rosapps/applications/screensavers/cylfrac/lang/fr-FR.rc b/modules/rosapps/applications/screensavers/cylfrac/lang/fr-FR.rc index c5a3ef84bfe47..7d41feb40494b 100644 --- a/modules/rosapps/applications/screensavers/cylfrac/lang/fr-FR.rc +++ b/modules/rosapps/applications/screensavers/cylfrac/lang/fr-FR.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Fractale de cylindres" IDS_TITLE "À propos de" diff --git a/modules/rosapps/applications/screensavers/cylfrac/lang/it-IT.rc b/modules/rosapps/applications/screensavers/cylfrac/lang/it-IT.rc index 93a3c580624e1..a0735703ec9c5 100644 --- a/modules/rosapps/applications/screensavers/cylfrac/lang/it-IT.rc +++ b/modules/rosapps/applications/screensavers/cylfrac/lang/it-IT.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Cilindri frattali" IDS_TITLE "Informazioni" diff --git a/modules/rosapps/applications/screensavers/cylfrac/lang/lt-LT.rc b/modules/rosapps/applications/screensavers/cylfrac/lang/lt-LT.rc index 6be189e584ddd..78ff23a3a9ca3 100644 --- a/modules/rosapps/applications/screensavers/cylfrac/lang/lt-LT.rc +++ b/modules/rosapps/applications/screensavers/cylfrac/lang/lt-LT.rc @@ -9,7 +9,7 @@ LANGUAGE LANG_LITHUANIAN, SUBLANG_DEFAULT -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Cilindrinis fraktalas" IDS_TITLE "Apie" diff --git a/modules/rosapps/applications/screensavers/cylfrac/lang/nl-NL.rc b/modules/rosapps/applications/screensavers/cylfrac/lang/nl-NL.rc index 5f3ccde36ee7c..ca0940c833088 100644 --- a/modules/rosapps/applications/screensavers/cylfrac/lang/nl-NL.rc +++ b/modules/rosapps/applications/screensavers/cylfrac/lang/nl-NL.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Cylinders fractal" IDS_TITLE "Informatie" diff --git a/modules/rosapps/applications/screensavers/cylfrac/lang/no-NO.rc b/modules/rosapps/applications/screensavers/cylfrac/lang/no-NO.rc index 9f75d33207f07..6d642cda6beb3 100644 --- a/modules/rosapps/applications/screensavers/cylfrac/lang/no-NO.rc +++ b/modules/rosapps/applications/screensavers/cylfrac/lang/no-NO.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_NORWEGIAN, SUBLANG_NEUTRAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Sylindere fraktal" IDS_TITLE "Om" diff --git a/modules/rosapps/applications/screensavers/cylfrac/lang/pl-PL.rc b/modules/rosapps/applications/screensavers/cylfrac/lang/pl-PL.rc index c9aca2a3af39e..1b2e28a1e9fe5 100644 --- a/modules/rosapps/applications/screensavers/cylfrac/lang/pl-PL.rc +++ b/modules/rosapps/applications/screensavers/cylfrac/lang/pl-PL.rc @@ -7,7 +7,7 @@ LANGUAGE LANG_POLISH, SUBLANG_DEFAULT -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Fraktale cylindryczne" IDS_TITLE "O programie" diff --git a/modules/rosapps/applications/screensavers/cylfrac/lang/ro-RO.rc b/modules/rosapps/applications/screensavers/cylfrac/lang/ro-RO.rc index 6b3c7f7097167..3117f343c15a4 100644 --- a/modules/rosapps/applications/screensavers/cylfrac/lang/ro-RO.rc +++ b/modules/rosapps/applications/screensavers/cylfrac/lang/ro-RO.rc @@ -8,7 +8,7 @@ LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Fractal cilindri (animație de inactivitate)" IDS_TITLE "Despre" diff --git a/modules/rosapps/applications/screensavers/cylfrac/lang/ru-RU.rc b/modules/rosapps/applications/screensavers/cylfrac/lang/ru-RU.rc index e4aaac37f2c5c..b9fe58e720472 100644 --- a/modules/rosapps/applications/screensavers/cylfrac/lang/ru-RU.rc +++ b/modules/rosapps/applications/screensavers/cylfrac/lang/ru-RU.rc @@ -8,7 +8,7 @@ LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Заставка ""Cylinders fractal""" IDS_TITLE "О программе" diff --git a/modules/rosapps/applications/screensavers/cylfrac/lang/sk-SK.rc b/modules/rosapps/applications/screensavers/cylfrac/lang/sk-SK.rc index c51d15ec1c42d..a069abe8e02b5 100644 --- a/modules/rosapps/applications/screensavers/cylfrac/lang/sk-SK.rc +++ b/modules/rosapps/applications/screensavers/cylfrac/lang/sk-SK.rc @@ -4,7 +4,7 @@ LANGUAGE LANG_SLOVAK, SUBLANG_DEFAULT -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Cylinders fractal" IDS_TITLE "Čo je ..." diff --git a/modules/rosapps/applications/screensavers/cylfrac/lang/tr-TR.rc b/modules/rosapps/applications/screensavers/cylfrac/lang/tr-TR.rc index 649531d309fa1..9ef096a469646 100644 --- a/modules/rosapps/applications/screensavers/cylfrac/lang/tr-TR.rc +++ b/modules/rosapps/applications/screensavers/cylfrac/lang/tr-TR.rc @@ -7,7 +7,7 @@ LANGUAGE LANG_TURKISH, SUBLANG_NEUTRAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Silindirik Fractaller" IDS_TITLE "Hakkında" diff --git a/modules/rosapps/applications/screensavers/cylfrac/lang/uk-UA.rc b/modules/rosapps/applications/screensavers/cylfrac/lang/uk-UA.rc index 2f08a0f2dddb9..10ec907ff48b3 100644 --- a/modules/rosapps/applications/screensavers/cylfrac/lang/uk-UA.rc +++ b/modules/rosapps/applications/screensavers/cylfrac/lang/uk-UA.rc @@ -8,7 +8,7 @@ LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Заставка ""Cylinders fractal""" IDS_TITLE "Про" diff --git a/modules/rosapps/applications/screensavers/cylfrac/lang/zh-CN.rc b/modules/rosapps/applications/screensavers/cylfrac/lang/zh-CN.rc index 585473ad4c992..86996b478d21e 100644 --- a/modules/rosapps/applications/screensavers/cylfrac/lang/zh-CN.rc +++ b/modules/rosapps/applications/screensavers/cylfrac/lang/zh-CN.rc @@ -2,7 +2,7 @@ LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "圆筒形" IDS_TITLE "关于" diff --git a/modules/rosapps/applications/screensavers/cylfrac/lang/zh-HK.rc b/modules/rosapps/applications/screensavers/cylfrac/lang/zh-HK.rc index 33c68f79fd3ef..1a3f0bd3b9ee5 100644 --- a/modules/rosapps/applications/screensavers/cylfrac/lang/zh-HK.rc +++ b/modules/rosapps/applications/screensavers/cylfrac/lang/zh-HK.rc @@ -7,7 +7,7 @@ LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_HONGKONG -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "分形圓筒" IDS_TITLE "關於" diff --git a/modules/rosapps/applications/screensavers/cylfrac/lang/zh-TW.rc b/modules/rosapps/applications/screensavers/cylfrac/lang/zh-TW.rc index 50586a2e98b19..37c71e4a56ff0 100644 --- a/modules/rosapps/applications/screensavers/cylfrac/lang/zh-TW.rc +++ b/modules/rosapps/applications/screensavers/cylfrac/lang/zh-TW.rc @@ -7,7 +7,7 @@ LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "分形圓筒" IDS_TITLE "關於" diff --git a/modules/rosapps/applications/screensavers/matrix/Permission.txt b/modules/rosapps/applications/screensavers/matrix/Permission.txt index 55f0910f7c003..1765276fb532d 100644 --- a/modules/rosapps/applications/screensavers/matrix/Permission.txt +++ b/modules/rosapps/applications/screensavers/matrix/Permission.txt @@ -5,7 +5,7 @@ Matrrix2 screensaver for ReactOS Freeware Copyright J Brown 2003 -Updates at http://www.catch22.net +Updates at https://www.catch22.net/ ******************************************/ diff --git a/modules/rosapps/applications/screensavers/matrix/lang/bg-BG.rc b/modules/rosapps/applications/screensavers/matrix/lang/bg-BG.rc index 435f7f1a53e81..327a8388f7930 100644 --- a/modules/rosapps/applications/screensavers/matrix/lang/bg-BG.rc +++ b/modules/rosapps/applications/screensavers/matrix/lang/bg-BG.rc @@ -1,8 +1,7 @@ -#include "resource.h" LANGUAGE LANG_BULGARIAN, SUBLANG_DEFAULT -IDD_CONFIG DIALOGEX DISCARDABLE 0, 0, 340, 183 +IDD_CONFIG DIALOGEX 0, 0, 340, 183 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Настройка на екранен предпазител Matrix" FONT 8, "MS Shell Dlg" @@ -47,7 +46,7 @@ BEGIN 158,75,18 END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Екранен предпазител Matrix" END diff --git a/modules/rosapps/applications/screensavers/matrix/lang/de-DE.rc b/modules/rosapps/applications/screensavers/matrix/lang/de-DE.rc index 101e574cbb337..2c92fafddd2cf 100644 --- a/modules/rosapps/applications/screensavers/matrix/lang/de-DE.rc +++ b/modules/rosapps/applications/screensavers/matrix/lang/de-DE.rc @@ -1,8 +1,7 @@ -#include "resource.h" LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL -IDD_CONFIG DIALOGEX DISCARDABLE 0, 0, 340, 183 +IDD_CONFIG DIALOGEX 0, 0, 340, 183 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Matrix Bildschirmschoner-Konfiguration" FONT 8, "MS Shell Dlg" @@ -46,7 +45,7 @@ BEGIN CTEXT "Matrix ScreenSaver www.catch22.org.uk",IDC_ABOUT,143, 158, 75, 18 END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Matrix Bildschirmschoner" END diff --git a/modules/rosapps/applications/screensavers/matrix/lang/en-US.rc b/modules/rosapps/applications/screensavers/matrix/lang/en-US.rc index 79a316197831d..5af32c58a9a4c 100644 --- a/modules/rosapps/applications/screensavers/matrix/lang/en-US.rc +++ b/modules/rosapps/applications/screensavers/matrix/lang/en-US.rc @@ -1,8 +1,7 @@ -#include "resource.h" LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -IDD_CONFIG DIALOGEX DISCARDABLE 0, 0, 340, 183 +IDD_CONFIG DIALOGEX 0, 0, 340, 183 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Matrix ScreenSaver Configuration" FONT 8, "MS Shell Dlg" @@ -47,7 +46,7 @@ BEGIN 158,75,18 END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Matrix ScreenSaver" END diff --git a/modules/rosapps/applications/screensavers/matrix/lang/es-ES.rc b/modules/rosapps/applications/screensavers/matrix/lang/es-ES.rc index 9652d2c55a6a8..f9cfc3f8787a2 100644 --- a/modules/rosapps/applications/screensavers/matrix/lang/es-ES.rc +++ b/modules/rosapps/applications/screensavers/matrix/lang/es-ES.rc @@ -1,8 +1,7 @@ -#include "resource.h" LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL -IDD_CONFIG DIALOGEX DISCARDABLE 0, 0, 340, 183 +IDD_CONFIG DIALOGEX 0, 0, 340, 183 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Configuración del Salvapantallas Matrix" FONT 8, "MS Shell Dlg" @@ -47,7 +46,7 @@ BEGIN 158,75,18 END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Salvapantallas Matrix" END diff --git a/modules/rosapps/applications/screensavers/matrix/lang/fr-FR.rc b/modules/rosapps/applications/screensavers/matrix/lang/fr-FR.rc index de8a38c478cdf..a2cf1e65434f0 100644 --- a/modules/rosapps/applications/screensavers/matrix/lang/fr-FR.rc +++ b/modules/rosapps/applications/screensavers/matrix/lang/fr-FR.rc @@ -1,8 +1,7 @@ -#include "resource.h" LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL -IDD_CONFIG DIALOGEX DISCARDABLE 0, 0, 340, 183 +IDD_CONFIG DIALOGEX 0, 0, 340, 183 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Configuration de l'écran de veille Matrix" FONT 8, "MS Shell Dlg" @@ -47,7 +46,7 @@ BEGIN 158,75,18 END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Écran de veille Matrix" END diff --git a/modules/rosapps/applications/screensavers/matrix/lang/lt-LT.rc b/modules/rosapps/applications/screensavers/matrix/lang/lt-LT.rc index 3e0208f4d6cb9..f8accdce481f8 100644 --- a/modules/rosapps/applications/screensavers/matrix/lang/lt-LT.rc +++ b/modules/rosapps/applications/screensavers/matrix/lang/lt-LT.rc @@ -7,11 +7,9 @@ * DATE: 2007-12-02 */ -#include "resource.h" - LANGUAGE LANG_LITHUANIAN, SUBLANG_DEFAULT -IDD_CONFIG DIALOGEX DISCARDABLE 0, 0, 340, 183 +IDD_CONFIG DIALOGEX 0, 0, 340, 183 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Ekrano užsklandos nustatymai" FONT 8, "MS Shell Dlg" @@ -56,7 +54,7 @@ BEGIN 151,75,25 END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Matrica" END diff --git a/modules/rosapps/applications/screensavers/matrix/lang/nl-NL.rc b/modules/rosapps/applications/screensavers/matrix/lang/nl-NL.rc index e2ba43ff3b831..bec66a70bf97a 100644 --- a/modules/rosapps/applications/screensavers/matrix/lang/nl-NL.rc +++ b/modules/rosapps/applications/screensavers/matrix/lang/nl-NL.rc @@ -1,8 +1,7 @@ -#include "resource.h" LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL -IDD_CONFIG DIALOGEX DISCARDABLE 0, 0, 340, 183 +IDD_CONFIG DIALOGEX 0, 0, 340, 183 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Matrix Schermbeveiliging Configuratie" FONT 8, "MS Shell Dlg" @@ -47,7 +46,7 @@ BEGIN 158,75,18 END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Matrix Schermbeveiliging" END diff --git a/modules/rosapps/applications/screensavers/matrix/lang/no-NO.rc b/modules/rosapps/applications/screensavers/matrix/lang/no-NO.rc index c16698ea5597a..41b3a1e8c8058 100644 --- a/modules/rosapps/applications/screensavers/matrix/lang/no-NO.rc +++ b/modules/rosapps/applications/screensavers/matrix/lang/no-NO.rc @@ -1,8 +1,7 @@ -#include "resource.h" LANGUAGE LANG_NORWEGIAN, SUBLANG_NEUTRAL -IDD_CONFIG DIALOGEX DISCARDABLE 0, 0, 340, 183 +IDD_CONFIG DIALOGEX 0, 0, 340, 183 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Matrix Skjermsparer konfigurasjon" FONT 8, "MS Shell Dlg" @@ -47,7 +46,7 @@ BEGIN 158,75,18 END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Matrix Skjermsparer" END diff --git a/modules/rosapps/applications/screensavers/matrix/lang/pl-PL.rc b/modules/rosapps/applications/screensavers/matrix/lang/pl-PL.rc index b0b7e58aa6fa8..860c44d35702a 100644 --- a/modules/rosapps/applications/screensavers/matrix/lang/pl-PL.rc +++ b/modules/rosapps/applications/screensavers/matrix/lang/pl-PL.rc @@ -1,5 +1,3 @@ -#include "resource.h" - /* * translated by Caemyr - Olaf Siejka (Feb, 2008) * Use ReactOS forum PM or IRC to contact me @@ -9,7 +7,7 @@ LANGUAGE LANG_POLISH, SUBLANG_DEFAULT -IDD_CONFIG DIALOGEX DISCARDABLE 0, 0, 340, 183 +IDD_CONFIG DIALOGEX 0, 0, 340, 183 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Konfiguracja wygaszacza Matrix" FONT 8, "MS Shell Dlg" @@ -54,7 +52,7 @@ BEGIN 158,75,18 END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Matrix" END diff --git a/modules/rosapps/applications/screensavers/matrix/lang/ro-RO.rc b/modules/rosapps/applications/screensavers/matrix/lang/ro-RO.rc index 96f3204720829..6310bcd183d46 100644 --- a/modules/rosapps/applications/screensavers/matrix/lang/ro-RO.rc +++ b/modules/rosapps/applications/screensavers/matrix/lang/ro-RO.rc @@ -6,13 +6,9 @@ * Copyright 2023-2024 Andrei Miloiu */ -#include "resource.h" - LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL -#pragma code_page(65001) - -IDD_CONFIG DIALOGEX DISCARDABLE 0, 0, 340, 183 +IDD_CONFIG DIALOGEX 0, 0, 340, 183 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Setări pentru economizorul de ecran Matrix" FONT 8, "MS Shell Dlg" @@ -57,7 +53,7 @@ BEGIN 158,75,18 END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Economizorul de ecran Matrix" END diff --git a/modules/rosapps/applications/screensavers/matrix/lang/ru-RU.rc b/modules/rosapps/applications/screensavers/matrix/lang/ru-RU.rc index 49a4c27a17f2b..d2f3b22d7120c 100644 --- a/modules/rosapps/applications/screensavers/matrix/lang/ru-RU.rc +++ b/modules/rosapps/applications/screensavers/matrix/lang/ru-RU.rc @@ -6,11 +6,9 @@ * TRANSLATOR: Sergey Stopkin */ -#include "resource.h" - LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT -IDD_CONFIG DIALOGEX DISCARDABLE 0, 0, 340, 183 +IDD_CONFIG DIALOGEX 0, 0, 340, 183 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Параметры заставки ""Матрица""" FONT 8, "MS Shell Dlg" @@ -55,7 +53,7 @@ BEGIN 158,75,18 END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Заставка ""Матрица""" END diff --git a/modules/rosapps/applications/screensavers/matrix/lang/sk-SK.rc b/modules/rosapps/applications/screensavers/matrix/lang/sk-SK.rc index 96205f9e2c141..533fae2722172 100644 --- a/modules/rosapps/applications/screensavers/matrix/lang/sk-SK.rc +++ b/modules/rosapps/applications/screensavers/matrix/lang/sk-SK.rc @@ -6,11 +6,9 @@ * DATE OF TR: 25-07-2007 */ -#include "resource.h" - LANGUAGE LANG_SLOVAK, SUBLANG_DEFAULT -IDD_CONFIG DIALOGEX DISCARDABLE 0, 0, 340, 183 +IDD_CONFIG DIALOGEX 0, 0, 340, 183 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Nastavenie šetriča obrazovky Matrix" FONT 8, "MS Shell Dlg" @@ -55,7 +53,7 @@ BEGIN PUSHBUTTON "Zrušiť",IDCANCEL,283,162,50,14 END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Matrix - šetrič obrazovky" END diff --git a/modules/rosapps/applications/screensavers/matrix/lang/th-TH.rc b/modules/rosapps/applications/screensavers/matrix/lang/th-TH.rc index 58523fbe8535f..2d2e243bb762d 100644 --- a/modules/rosapps/applications/screensavers/matrix/lang/th-TH.rc +++ b/modules/rosapps/applications/screensavers/matrix/lang/th-TH.rc @@ -1,8 +1,7 @@ -#include "resource.h" LANGUAGE LANG_THAI, SUBLANG_DEFAULT -IDD_CONFIG DIALOGEX DISCARDABLE 0, 0, 340, 183 +IDD_CONFIG DIALOGEX 0, 0, 340, 183 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Matrix ScreenSaver Configuration" FONT 8, "MS Shell Dlg" @@ -47,7 +46,7 @@ BEGIN 158,75,18 END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Matrix ScreenSaver" END diff --git a/modules/rosapps/applications/screensavers/matrix/lang/tr-TR.rc b/modules/rosapps/applications/screensavers/matrix/lang/tr-TR.rc index 229a1e02a9f69..ef95c6c0e4fbd 100644 --- a/modules/rosapps/applications/screensavers/matrix/lang/tr-TR.rc +++ b/modules/rosapps/applications/screensavers/matrix/lang/tr-TR.rc @@ -5,11 +5,9 @@ * TRANSLATOR: Copyright 2022 Süleyman Poyraz */ -#include "resource.h" - LANGUAGE LANG_TURKISH, SUBLANG_NEUTRAL -IDD_CONFIG DIALOGEX DISCARDABLE 0, 0, 340, 183 +IDD_CONFIG DIALOGEX 0, 0, 340, 183 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Matrix Ekran Koruyucusu Yapılandırması" FONT 8, "MS Shell Dlg" @@ -54,7 +52,7 @@ BEGIN 158,75,18 END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Matrix Ekran Koruyucu" END diff --git a/modules/rosapps/applications/screensavers/matrix/lang/uk-UA.rc b/modules/rosapps/applications/screensavers/matrix/lang/uk-UA.rc index b2b3089d08eb3..b251f75259999 100644 --- a/modules/rosapps/applications/screensavers/matrix/lang/uk-UA.rc +++ b/modules/rosapps/applications/screensavers/matrix/lang/uk-UA.rc @@ -6,11 +6,9 @@ * TRANSLATOR: Artem Reznikov */ -#include "resource.h" - LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT -IDD_CONFIG DIALOGEX DISCARDABLE 0, 0, 340, 183 +IDD_CONFIG DIALOGEX 0, 0, 340, 183 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Параметри заставки ""Матриця""" FONT 8, "MS Shell Dlg" @@ -55,7 +53,7 @@ BEGIN 158,75,18 END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Заставка ""Матриця""" END diff --git a/modules/rosapps/applications/screensavers/matrix/lang/zh-CN.rc b/modules/rosapps/applications/screensavers/matrix/lang/zh-CN.rc index 8e2421ce379a8..2ac9bc5f878ff 100644 --- a/modules/rosapps/applications/screensavers/matrix/lang/zh-CN.rc +++ b/modules/rosapps/applications/screensavers/matrix/lang/zh-CN.rc @@ -1,10 +1,8 @@ /* Simplified Chinese translation by Henry Tang Ih 2015 (henrytang2@hotmail.com) */ -#include "resource.h" - LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED -IDD_CONFIG DIALOGEX DISCARDABLE 0, 0, 340, 183 +IDD_CONFIG DIALOGEX 0, 0, 340, 183 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Matrix 屏幕保护程序配置" FONT 9, "宋体" @@ -49,7 +47,7 @@ BEGIN 158,75,18 END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Matrix 屏幕保护" END diff --git a/modules/rosapps/applications/screensavers/matrix/lang/zh-HK.rc b/modules/rosapps/applications/screensavers/matrix/lang/zh-HK.rc index c49e46b20a676..037f4c94f4b1b 100644 --- a/modules/rosapps/applications/screensavers/matrix/lang/zh-HK.rc +++ b/modules/rosapps/applications/screensavers/matrix/lang/zh-HK.rc @@ -5,11 +5,9 @@ * TRANSLATORS: Copyright 2021 Chan Chilung */ -#include "resource.h" - LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_HONGKONG -IDD_CONFIG DIALOGEX DISCARDABLE 0, 0, 340, 183 +IDD_CONFIG DIALOGEX 0, 0, 340, 183 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "矩陣螢幕保護程式設定" FONT 9, "新細明體" @@ -54,7 +52,7 @@ BEGIN 158,75,18 END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "矩陣螢幕保護程式" END diff --git a/modules/rosapps/applications/screensavers/matrix/lang/zh-TW.rc b/modules/rosapps/applications/screensavers/matrix/lang/zh-TW.rc index d5cf0efd1c7ad..daebf6f9f061c 100644 --- a/modules/rosapps/applications/screensavers/matrix/lang/zh-TW.rc +++ b/modules/rosapps/applications/screensavers/matrix/lang/zh-TW.rc @@ -5,11 +5,9 @@ * TRANSLATORS: Copyright 2021 Chan Chilung */ -#include "resource.h" - LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL -IDD_CONFIG DIALOGEX DISCARDABLE 0, 0, 340, 183 +IDD_CONFIG DIALOGEX 0, 0, 340, 183 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "矩陣螢幕保護程式設定" FONT 9, "新細明體" @@ -54,7 +52,7 @@ BEGIN 158,75,18 END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "矩陣螢幕保護程式" END diff --git a/modules/rosapps/applications/screensavers/matrix/rsrc.rc b/modules/rosapps/applications/screensavers/matrix/rsrc.rc index 4873f85b92374..ba3ca56db8171 100644 --- a/modules/rosapps/applications/screensavers/matrix/rsrc.rc +++ b/modules/rosapps/applications/screensavers/matrix/rsrc.rc @@ -3,9 +3,9 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL -IDB_BITMAP1 BITMAP DISCARDABLE "matrix.bmp" -IDC_BLANKCURSOR CURSOR DISCARDABLE "cursor1.cur" -IDI_ICON1 ICON DISCARDABLE "icon1.ico" +IDB_BITMAP1 BITMAP "matrix.bmp" +IDC_BLANKCURSOR CURSOR "cursor1.cur" +IDI_ICON1 ICON "icon1.ico" #include diff --git a/modules/rosapps/applications/screensavers/mazescr/lang/de-DE.rc b/modules/rosapps/applications/screensavers/mazescr/lang/de-DE.rc index cce0c41bb9931..1da7a75e43c94 100644 --- a/modules/rosapps/applications/screensavers/mazescr/lang/de-DE.rc +++ b/modules/rosapps/applications/screensavers/mazescr/lang/de-DE.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL -IDD_DLG_SCREEN DIALOGEX DISCARDABLE 0, 0, 276, 112 +IDD_DLG_SCREEN DIALOGEX 0, 0, 276, 112 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Labyrinth Bildschirmschoner Einstellungen" FONT 8, "MS Shell Dlg" @@ -22,7 +22,7 @@ BEGIN PUSHBUTTON "Über",IDABOUT,167,91,50,14 END -IDD_DLG_ABOUT DIALOGEX DISCARDABLE 0, 0, 229, 121 +IDD_DLG_ABOUT DIALOGEX 0, 0, 229, 121 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Über" FONT 8, "MS Shell Dlg" @@ -39,7 +39,7 @@ BEGIN DEFPUSHBUTTON "OK",IDOK,87,100,56,14 END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Labyrinth Bildschirmschoner" END diff --git a/modules/rosapps/applications/screensavers/mazescr/lang/en-US.rc b/modules/rosapps/applications/screensavers/mazescr/lang/en-US.rc index a2adcbe48db99..31653825a9372 100644 --- a/modules/rosapps/applications/screensavers/mazescr/lang/en-US.rc +++ b/modules/rosapps/applications/screensavers/mazescr/lang/en-US.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -IDD_DLG_SCREEN DIALOGEX DISCARDABLE 0, 0, 276, 112 +IDD_DLG_SCREEN DIALOGEX 0, 0, 276, 112 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Maze ScreenSaver Settings" FONT 8, "MS Shell Dlg" @@ -22,7 +22,7 @@ BEGIN PUSHBUTTON "About",IDABOUT,167,91,50,14 END -IDD_DLG_ABOUT DIALOGEX DISCARDABLE 0, 0, 229, 121 +IDD_DLG_ABOUT DIALOGEX 0, 0, 229, 121 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "About" FONT 8, "MS Shell Dlg" @@ -39,7 +39,7 @@ BEGIN DEFPUSHBUTTON "OK",IDOK,87,100,56,14 END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Maze Screensaver" END diff --git a/modules/rosapps/applications/screensavers/mazescr/lang/es-ES.rc b/modules/rosapps/applications/screensavers/mazescr/lang/es-ES.rc index f0b5003dfe790..01fd68da74112 100644 --- a/modules/rosapps/applications/screensavers/mazescr/lang/es-ES.rc +++ b/modules/rosapps/applications/screensavers/mazescr/lang/es-ES.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL -IDD_DLG_SCREEN DIALOGEX DISCARDABLE 0, 0, 276, 112 +IDD_DLG_SCREEN DIALOGEX 0, 0, 276, 112 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Configuración del Salvapantallas Maze" FONT 8, "MS Shell Dlg" @@ -22,7 +22,7 @@ BEGIN PUSHBUTTON "Acerca de",IDABOUT,167,91,50,14 END -IDD_DLG_ABOUT DIALOGEX DISCARDABLE 0, 0, 229, 121 +IDD_DLG_ABOUT DIALOGEX 0, 0, 229, 121 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Acerca de" FONT 8, "MS Shell Dlg" @@ -39,7 +39,7 @@ BEGIN DEFPUSHBUTTON "OK",IDOK,87,100,56,14 END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Salvapantallas Maze" END diff --git a/modules/rosapps/applications/screensavers/mazescr/lang/pl-PL.rc b/modules/rosapps/applications/screensavers/mazescr/lang/pl-PL.rc index b84fbb924fa00..203c4cf356863 100644 --- a/modules/rosapps/applications/screensavers/mazescr/lang/pl-PL.rc +++ b/modules/rosapps/applications/screensavers/mazescr/lang/pl-PL.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_POLISH, SUBLANG_DEFAULT -IDD_DLG_SCREEN DIALOGEX DISCARDABLE 0, 0, 276, 112 +IDD_DLG_SCREEN DIALOGEX 0, 0, 276, 112 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Ustawienia wygaszacza Maze" FONT 8, "MS Shell Dlg" @@ -22,7 +22,7 @@ BEGIN PUSHBUTTON "O wygaszaczu",IDABOUT,167,91,50,14 END -IDD_DLG_ABOUT DIALOGEX DISCARDABLE 0, 0, 229, 121 +IDD_DLG_ABOUT DIALOGEX 0, 0, 229, 121 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "O wygaszaczu" FONT 8, "MS Shell Dlg" @@ -39,7 +39,7 @@ BEGIN DEFPUSHBUTTON "OK",IDOK,87,100,56,14 END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Wygaszacz Maze" END diff --git a/modules/rosapps/applications/screensavers/mazescr/lang/ro-RO.rc b/modules/rosapps/applications/screensavers/mazescr/lang/ro-RO.rc index 8e898130f828c..b943181d4f16f 100644 --- a/modules/rosapps/applications/screensavers/mazescr/lang/ro-RO.rc +++ b/modules/rosapps/applications/screensavers/mazescr/lang/ro-RO.rc @@ -1,47 +1,53 @@ -/* Translator: Ștefan Fulea (stefan dot fulea at mail dot com) */ + /* + * PROJECT: Maze ScreenSaver + * LICENSE: HPND (https://spdx.org/licenses/HPND) + * PURPOSE: Romanian resource file + * TRANSLATORS: Copyright 2011-2018 Ștefan Fulea + * Copyright 2024 Andrei Miloiu + */ LANGUAGE LANG_ROMANIAN, SUBLANG_DEFAULT -IDD_DLG_SCREEN DIALOGEX DISCARDABLE 0, 0, 276, 112 +IDD_DLG_SCREEN DIALOGEX 0, 0, 276, 112 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Configurație animație de inactivitate „Labirint”" +CAPTION "Setări pentru economizorul de ecran Labirint" FONT 8, "MS Shell Dlg" BEGIN - LTEXT "Mărime labirint:",IDC_STATIC,7,7,90,12,SS_CENTERIMAGE + LTEXT "Mărimea Labirintului:",IDC_STATIC,7,7,90,12,SS_CENTERIMAGE CONTROL "Slider1",IDC_SLIDER_SIZE,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,101,7,140,12 CTEXT "Static",IDC_TEXT_SIZE,245,7,24,12,SS_CENTERIMAGE,WS_EX_STATICEDGE - LTEXT "Timp ante-rezolvare:",IDC_STATIC,7,28,90,12,SS_CENTERIMAGE + LTEXT "Înt. pre-rezolvare:",IDC_STATIC,7,28,90,12,SS_CENTERIMAGE CONTROL "Slider2",IDC_SLIDER_PRESD,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,101,28,140,12 CTEXT "Static",IDC_TEXT_PRESD,245,28,24,12,SS_CENTERIMAGE,WS_EX_STATICEDGE - LTEXT "Timp post-rezolvare:",IDC_STATIC,7,49,90,12,SS_CENTERIMAGE + LTEXT "Înt. după rezolvare:",IDC_STATIC,7,49,90,12,SS_CENTERIMAGE CONTROL "Slider3",IDC_SLIDER_POSTSD,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,101,49,140,12 CTEXT "Static",IDC_TEXT_POSTSD,245,49,24,12,SS_CENTERIMAGE,WS_EX_STATICEDGE - LTEXT "Timp de rezolvare:",IDC_STATIC,7,70,90,12,SS_CENTERIMAGE + LTEXT "Întârz. rezolvare:",IDC_STATIC,7,70,90,12,SS_CENTERIMAGE CONTROL "Slider4",IDC_SLIDER_SD,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,101,70,140,12 CTEXT "Static",IDC_TEXT_SD,245,70,24,12,SS_CENTERIMAGE,WS_EX_STATICEDGE - DEFPUSHBUTTON "Con&firmă",IDOK,59,91,50,14 - PUSHBUTTON "A&nulează",IDCANCEL,113,91,50,14 + DEFPUSHBUTTON "OK",IDOK,59,91,50,14 + PUSHBUTTON "Revocare",IDCANCEL,113,91,50,14 PUSHBUTTON "&Despre",IDABOUT,167,91,50,14 END -IDD_DLG_ABOUT DIALOGEX DISCARDABLE 0, 0, 229, 121 +IDD_DLG_ABOUT DIALOGEX 0, 0, 229, 121 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Despre" FONT 8, "MS Shell Dlg" BEGIN - CTEXT "Animație de inactivitate „Labirint” versiune 1.0",IDC_STATIC,7,7,215,9 + CTEXT "Economizorul de ecran Labirint” versiune 1.0",IDC_STATIC,7,7,215,9 LTEXT "[06-21-85] Martin Weiss - Cod Original",IDC_STATIC,7,20,215,8 - LTEXT "[01-29-88] Dave Lemke - Specializare pentru X11",IDC_STATIC,7,29,215,8 - LTEXT "[10-04-88] Richard Hess - Generalizare de la X11",IDC_STATIC,7,38,215,8 + LTEXT "[01-29-88] Dave Lemke - Spart pentru X11",IDC_STATIC,7,29,215,8 + LTEXT "[10-04-88] Richard Hess - Nespart de la X11",IDC_STATIC,7,38,215,8 LTEXT "[03-03-93] Jim Randell - Generalizare de la X11",IDC_STATIC,7,47,215,8 - LTEXT "[03-07-93] Jamie Zawinski - Refactorizare și alte îmbunătățiri",IDC_STATIC,7,56,215,8 - LTEXT "[10-08-94] Ge van Geldorp - Portat în Windows",IDC_STATIC,7,65,215,8 - LTEXT "[08-15-03] Ge van Geldorp - Portat în ReactOS",IDC_STATIC,7,74,215,8 - CTEXT "R.I.P. Ge van Geldorp, we miss you!",IDC_STATIC,7,87,215,10,SS_SUNKEN - DEFPUSHBUTTON "Î&nchide",IDOK,87,100,56,14 + LTEXT "[03-07-93] Jamie Zawinski - Curățenie și ordine a codului",IDC_STATIC,7,56,215,8 + LTEXT "[10-08-94] Ge van Geldorp - Portat pe Windows",IDC_STATIC,7,65,215,8 + LTEXT "[08-15-03] Ge van Geldorp - Portat pe ReactOS",IDC_STATIC,7,74,215,8 + CTEXT "R.I.P. Ge van Geldorp, ne e dor de tine!",IDC_STATIC,7,87,215,10,SS_SUNKEN + DEFPUSHBUTTON "OK",IDOK,87,100,56,14 END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN - IDS_DESCRIPTION "Labirint (animație de inactivitate)" + IDS_DESCRIPTION "Economizorul de ecran Labirint" END diff --git a/modules/rosapps/applications/screensavers/mazescr/lang/ru-RU.rc b/modules/rosapps/applications/screensavers/mazescr/lang/ru-RU.rc index 8a5e7a4e2f253..0b68a18050329 100644 --- a/modules/rosapps/applications/screensavers/mazescr/lang/ru-RU.rc +++ b/modules/rosapps/applications/screensavers/mazescr/lang/ru-RU.rc @@ -8,7 +8,7 @@ LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT -IDD_DLG_SCREEN DIALOGEX DISCARDABLE 0, 0, 276, 112 +IDD_DLG_SCREEN DIALOGEX 0, 0, 276, 112 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Maze ScreenSaver Settings" FONT 8, "MS Shell Dlg" @@ -30,7 +30,7 @@ BEGIN PUSHBUTTON "О программе",IDABOUT,167,91,50,14 END -IDD_DLG_ABOUT DIALOGEX DISCARDABLE 0, 0, 229, 121 +IDD_DLG_ABOUT DIALOGEX 0, 0, 229, 121 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "О заставке ""Лабиринт""" FONT 8, "MS Shell Dlg" @@ -47,7 +47,7 @@ BEGIN DEFPUSHBUTTON "OK",IDOK,87,100,56,14 END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Заставка ""Лабиринт""" END diff --git a/modules/rosapps/applications/screensavers/mazescr/lang/tr-TR.rc b/modules/rosapps/applications/screensavers/mazescr/lang/tr-TR.rc index 350b92c88928c..999ab4bbaa4e2 100644 --- a/modules/rosapps/applications/screensavers/mazescr/lang/tr-TR.rc +++ b/modules/rosapps/applications/screensavers/mazescr/lang/tr-TR.rc @@ -7,7 +7,7 @@ LANGUAGE LANG_TURKISH, SUBLANG_NEUTRAL -IDD_DLG_SCREEN DIALOGEX DISCARDABLE 0, 0, 276, 112 +IDD_DLG_SCREEN DIALOGEX 0, 0, 276, 112 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Labirent Ekran Koruyucusu Ayarları" FONT 8, "MS Shell Dlg" @@ -29,7 +29,7 @@ BEGIN PUSHBUTTON "Hakkında",IDABOUT,167,91,50,14 END -IDD_DLG_ABOUT DIALOGEX DISCARDABLE 0, 0, 229, 121 +IDD_DLG_ABOUT DIALOGEX 0, 0, 229, 121 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Hakkında" FONT 8, "MS Shell Dlg" @@ -46,7 +46,7 @@ BEGIN DEFPUSHBUTTON "OK",IDOK,87,100,56,14 END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Labirent Ekran Koruyucusu" END diff --git a/modules/rosapps/applications/screensavers/mazescr/lang/zh-CN.rc b/modules/rosapps/applications/screensavers/mazescr/lang/zh-CN.rc index c00d9bdca75cc..e4f4ba8be5ee0 100644 --- a/modules/rosapps/applications/screensavers/mazescr/lang/zh-CN.rc +++ b/modules/rosapps/applications/screensavers/mazescr/lang/zh-CN.rc @@ -2,7 +2,7 @@ LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED -IDD_DLG_SCREEN DIALOGEX DISCARDABLE 0, 0, 276, 112 +IDD_DLG_SCREEN DIALOGEX 0, 0, 276, 112 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "迷宫屏幕保护程序设置" FONT 9, "宋体" @@ -24,7 +24,7 @@ BEGIN PUSHBUTTON "关于",IDABOUT,167,91,50,14 END -IDD_DLG_ABOUT DIALOGEX DISCARDABLE 0, 0, 229, 121 +IDD_DLG_ABOUT DIALOGEX 0, 0, 229, 121 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "关于" FONT 9, "宋体" @@ -41,7 +41,7 @@ BEGIN DEFPUSHBUTTON "确定",IDOK,87,100,56,14 END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "迷宫的屏幕保护程序" END diff --git a/modules/rosapps/applications/screensavers/mazescr/lang/zh-HK.rc b/modules/rosapps/applications/screensavers/mazescr/lang/zh-HK.rc index 1fd38af03a3d9..f8a10a06619b8 100644 --- a/modules/rosapps/applications/screensavers/mazescr/lang/zh-HK.rc +++ b/modules/rosapps/applications/screensavers/mazescr/lang/zh-HK.rc @@ -7,7 +7,7 @@ LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_HONGKONG -IDD_DLG_SCREEN DIALOGEX DISCARDABLE 0, 0, 276, 112 +IDD_DLG_SCREEN DIALOGEX 0, 0, 276, 112 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "迷宮螢幕保護程式設定" FONT 9, "新細明體" @@ -29,7 +29,7 @@ BEGIN PUSHBUTTON "關於",IDABOUT,167,91,50,14 END -IDD_DLG_ABOUT DIALOGEX DISCARDABLE 0, 0, 229, 121 +IDD_DLG_ABOUT DIALOGEX 0, 0, 229, 121 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "關於" FONT 9, "新細明體" @@ -46,7 +46,7 @@ BEGIN DEFPUSHBUTTON "確定",IDOK,87,100,56,14 END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "迷宮螢幕保護程式" END diff --git a/modules/rosapps/applications/screensavers/mazescr/lang/zh-TW.rc b/modules/rosapps/applications/screensavers/mazescr/lang/zh-TW.rc index 237ad523a7016..b2bedc8849cb1 100644 --- a/modules/rosapps/applications/screensavers/mazescr/lang/zh-TW.rc +++ b/modules/rosapps/applications/screensavers/mazescr/lang/zh-TW.rc @@ -7,7 +7,7 @@ LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL -IDD_DLG_SCREEN DIALOGEX DISCARDABLE 0, 0, 276, 112 +IDD_DLG_SCREEN DIALOGEX 0, 0, 276, 112 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "迷宮螢幕保護程式設定" FONT 9, "新細明體" @@ -29,7 +29,7 @@ BEGIN PUSHBUTTON "關於",IDABOUT,167,91,50,14 END -IDD_DLG_ABOUT DIALOGEX DISCARDABLE 0, 0, 229, 121 +IDD_DLG_ABOUT DIALOGEX 0, 0, 229, 121 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "關於" FONT 9, "新細明體" @@ -46,7 +46,7 @@ BEGIN DEFPUSHBUTTON "確定",IDOK,87,100,56,14 END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "迷宮螢幕保護程式" END diff --git a/modules/rosapps/applications/screensavers/mazescr/maze.rc b/modules/rosapps/applications/screensavers/mazescr/maze.rc index 087c5216d4dd5..bc7ba9d8287e4 100644 --- a/modules/rosapps/applications/screensavers/mazescr/maze.rc +++ b/modules/rosapps/applications/screensavers/mazescr/maze.rc @@ -3,12 +3,12 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL -IDI_ICON ICON DISCARDABLE "res/icon_mazescr.ico" +IDI_ICON ICON "res/icon_mazescr.ico" #define REACTOS_VERSION_DLL -#define REACTOS_STR_FILE_DESCRIPTION "Maze ScreenSaver\0" -#define REACTOS_STR_INTERNAL_NAME "Maze\0" -#define REACTOS_STR_ORIGINAL_FILENAME "mazescr.scr\0" +#define REACTOS_STR_FILE_DESCRIPTION "Maze ScreenSaver" +#define REACTOS_STR_INTERNAL_NAME "Maze" +#define REACTOS_STR_ORIGINAL_FILENAME "mazescr.scr" #include diff --git a/modules/rosapps/applications/screensavers/ssstars/lang/de-DE.rc b/modules/rosapps/applications/screensavers/ssstars/lang/de-DE.rc index 3ac92d56d6bbc..d346de8c34c4a 100644 --- a/modules/rosapps/applications/screensavers/ssstars/lang/de-DE.rc +++ b/modules/rosapps/applications/screensavers/ssstars/lang/de-DE.rc @@ -41,7 +41,7 @@ END // String Tables -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Starfield" IDS_ROTATION_NONE "Keine" diff --git a/modules/rosapps/applications/screensavers/ssstars/lang/en-US.rc b/modules/rosapps/applications/screensavers/ssstars/lang/en-US.rc index a1658e2335d38..b8cd923396448 100644 --- a/modules/rosapps/applications/screensavers/ssstars/lang/en-US.rc +++ b/modules/rosapps/applications/screensavers/ssstars/lang/en-US.rc @@ -41,7 +41,7 @@ END // String Tables -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Starfield" IDS_ROTATION_NONE "None" diff --git a/modules/rosapps/applications/screensavers/ssstars/lang/es-ES.rc b/modules/rosapps/applications/screensavers/ssstars/lang/es-ES.rc index c873e7b420d20..cf62675831ef2 100644 --- a/modules/rosapps/applications/screensavers/ssstars/lang/es-ES.rc +++ b/modules/rosapps/applications/screensavers/ssstars/lang/es-ES.rc @@ -49,7 +49,7 @@ END // String Tables -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Starfield" IDS_ROTATION_NONE "Ninguna" diff --git a/modules/rosapps/applications/screensavers/ssstars/lang/it-IT.rc b/modules/rosapps/applications/screensavers/ssstars/lang/it-IT.rc index 56593997252b4..d966903243663 100644 --- a/modules/rosapps/applications/screensavers/ssstars/lang/it-IT.rc +++ b/modules/rosapps/applications/screensavers/ssstars/lang/it-IT.rc @@ -41,7 +41,7 @@ END // String Tables -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Campo stellare" IDS_ROTATION_NONE "Nessuna" diff --git a/modules/rosapps/applications/screensavers/ssstars/lang/pl-PL.rc b/modules/rosapps/applications/screensavers/ssstars/lang/pl-PL.rc index 6edb7277db250..b3e7552af8e0e 100644 --- a/modules/rosapps/applications/screensavers/ssstars/lang/pl-PL.rc +++ b/modules/rosapps/applications/screensavers/ssstars/lang/pl-PL.rc @@ -41,7 +41,7 @@ END // String Tables -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Gwiezdne pole" IDS_ROTATION_NONE "brak" diff --git a/modules/rosapps/applications/screensavers/ssstars/lang/ro-RO.rc b/modules/rosapps/applications/screensavers/ssstars/lang/ro-RO.rc index 37ebf55ebd613..a7ad0751f4b46 100644 --- a/modules/rosapps/applications/screensavers/ssstars/lang/ro-RO.rc +++ b/modules/rosapps/applications/screensavers/ssstars/lang/ro-RO.rc @@ -49,7 +49,7 @@ END // String Tables -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Cer înstelat" IDS_ROTATION_NONE "Niciuna" diff --git a/modules/rosapps/applications/screensavers/ssstars/lang/ru-RU.rc b/modules/rosapps/applications/screensavers/ssstars/lang/ru-RU.rc index 75571c1d9e02d..083df5c3f799f 100644 --- a/modules/rosapps/applications/screensavers/ssstars/lang/ru-RU.rc +++ b/modules/rosapps/applications/screensavers/ssstars/lang/ru-RU.rc @@ -41,7 +41,7 @@ END // String Tables -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Звёздное поле" IDS_ROTATION_NONE "Отсутствует" diff --git a/modules/rosapps/applications/screensavers/ssstars/lang/tr-TR.rc b/modules/rosapps/applications/screensavers/ssstars/lang/tr-TR.rc index 8f13df29c8ee5..7761a060f26c4 100644 --- a/modules/rosapps/applications/screensavers/ssstars/lang/tr-TR.rc +++ b/modules/rosapps/applications/screensavers/ssstars/lang/tr-TR.rc @@ -48,7 +48,7 @@ END // String Tables -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Starfield" IDS_ROTATION_NONE "Hiçbiri" diff --git a/modules/rosapps/applications/screensavers/ssstars/lang/zh-CN.rc b/modules/rosapps/applications/screensavers/ssstars/lang/zh-CN.rc index 4b188fde66362..df09e0efa7456 100644 --- a/modules/rosapps/applications/screensavers/ssstars/lang/zh-CN.rc +++ b/modules/rosapps/applications/screensavers/ssstars/lang/zh-CN.rc @@ -43,7 +43,7 @@ END // String Tables -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "星空" IDS_ROTATION_NONE "无" diff --git a/modules/rosapps/applications/screensavers/ssstars/lang/zh-HK.rc b/modules/rosapps/applications/screensavers/ssstars/lang/zh-HK.rc index e7ba222cadb6f..9ee94ad85ade4 100644 --- a/modules/rosapps/applications/screensavers/ssstars/lang/zh-HK.rc +++ b/modules/rosapps/applications/screensavers/ssstars/lang/zh-HK.rc @@ -48,7 +48,7 @@ END // String Tables -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "恒星" IDS_ROTATION_NONE "無" diff --git a/modules/rosapps/applications/screensavers/ssstars/lang/zh-TW.rc b/modules/rosapps/applications/screensavers/ssstars/lang/zh-TW.rc index 879c8d15f08dc..20e7fcb49cf28 100644 --- a/modules/rosapps/applications/screensavers/ssstars/lang/zh-TW.rc +++ b/modules/rosapps/applications/screensavers/ssstars/lang/zh-TW.rc @@ -48,7 +48,7 @@ END // String Tables -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "恒星" IDS_ROTATION_NONE "無" diff --git a/modules/rosapps/applications/screensavers/ssstars/resource.rc b/modules/rosapps/applications/screensavers/ssstars/resource.rc index aea361e3eca17..78ee7984fcef6 100644 --- a/modules/rosapps/applications/screensavers/ssstars/resource.rc +++ b/modules/rosapps/applications/screensavers/ssstars/resource.rc @@ -32,12 +32,11 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL // Icons -IDI_STARFIELD ICON DISCARDABLE "res/icon_stars.ico" +IDI_STARFIELD ICON "res/icon_stars.ico" // Bitmap - -IDB_COSMOS BITMAP DISCARDABLE "res/cosmicfractal.bmp" -IDB_STAR BITMAP DISCARDABLE "res/star.bmp" +IDB_COSMOS BITMAP "res/cosmicfractal.bmp" +IDB_STAR BITMAP "res/star.bmp" #include diff --git a/modules/rosapps/applications/screensavers/starfield/lang/bg-BG.rc b/modules/rosapps/applications/screensavers/starfield/lang/bg-BG.rc index cdde641501857..8f6c6099b4c91 100644 --- a/modules/rosapps/applications/screensavers/starfield/lang/bg-BG.rc +++ b/modules/rosapps/applications/screensavers/starfield/lang/bg-BG.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_BULGARIAN, SUBLANG_DEFAULT -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Екранен предпазител „Зведно поле”" IDS_TITLE "За" diff --git a/modules/rosapps/applications/screensavers/starfield/lang/de-DE.rc b/modules/rosapps/applications/screensavers/starfield/lang/de-DE.rc index 0581b8d298bb4..688c15d1a9be9 100644 --- a/modules/rosapps/applications/screensavers/starfield/lang/de-DE.rc +++ b/modules/rosapps/applications/screensavers/starfield/lang/de-DE.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Starfield Bildschirmschoner" IDS_TITLE "Über" diff --git a/modules/rosapps/applications/screensavers/starfield/lang/en-US.rc b/modules/rosapps/applications/screensavers/starfield/lang/en-US.rc index 1d2ad6d545dcd..0bfaebf983571 100644 --- a/modules/rosapps/applications/screensavers/starfield/lang/en-US.rc +++ b/modules/rosapps/applications/screensavers/starfield/lang/en-US.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Starfield ScreenSaver" IDS_TITLE "About" diff --git a/modules/rosapps/applications/screensavers/starfield/lang/es-ES.rc b/modules/rosapps/applications/screensavers/starfield/lang/es-ES.rc index a68dbd0849100..e138f24ad7b14 100644 --- a/modules/rosapps/applications/screensavers/starfield/lang/es-ES.rc +++ b/modules/rosapps/applications/screensavers/starfield/lang/es-ES.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Salvapantallas Campo de estrellas" IDS_TITLE "Acerca de" diff --git a/modules/rosapps/applications/screensavers/starfield/lang/fr-FR.rc b/modules/rosapps/applications/screensavers/starfield/lang/fr-FR.rc index 9440ea462dfb5..aba28f7c45e39 100644 --- a/modules/rosapps/applications/screensavers/starfield/lang/fr-FR.rc +++ b/modules/rosapps/applications/screensavers/starfield/lang/fr-FR.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Écran de veille Champ d'étoile" IDS_TITLE "À propos de" diff --git a/modules/rosapps/applications/screensavers/starfield/lang/it-IT.rc b/modules/rosapps/applications/screensavers/starfield/lang/it-IT.rc index 51b00dd72f1c5..108d01c3d9779 100644 --- a/modules/rosapps/applications/screensavers/starfield/lang/it-IT.rc +++ b/modules/rosapps/applications/screensavers/starfield/lang/it-IT.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Salvaschermo Campo stellare" IDS_TITLE "Informazioni" diff --git a/modules/rosapps/applications/screensavers/starfield/lang/lt-LT.rc b/modules/rosapps/applications/screensavers/starfield/lang/lt-LT.rc index ad6d9b98c1898..bbcbcf0dd9a28 100644 --- a/modules/rosapps/applications/screensavers/starfield/lang/lt-LT.rc +++ b/modules/rosapps/applications/screensavers/starfield/lang/lt-LT.rc @@ -9,7 +9,7 @@ LANGUAGE LANG_LITHUANIAN, SUBLANG_DEFAULT -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Žvaigždžių laukas" IDS_TITLE "Apie" diff --git a/modules/rosapps/applications/screensavers/starfield/lang/nl-NL.rc b/modules/rosapps/applications/screensavers/starfield/lang/nl-NL.rc index 67e77c1e1bbe3..b49793f214996 100644 --- a/modules/rosapps/applications/screensavers/starfield/lang/nl-NL.rc +++ b/modules/rosapps/applications/screensavers/starfield/lang/nl-NL.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Sterren Schermbeveiliging" IDS_TITLE "Informatie" diff --git a/modules/rosapps/applications/screensavers/starfield/lang/no-NO.rc b/modules/rosapps/applications/screensavers/starfield/lang/no-NO.rc index aab31683af034..64c37da7a1362 100644 --- a/modules/rosapps/applications/screensavers/starfield/lang/no-NO.rc +++ b/modules/rosapps/applications/screensavers/starfield/lang/no-NO.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_NORWEGIAN, SUBLANG_NEUTRAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Starfield Skjermsparer" IDS_TITLE "Om" diff --git a/modules/rosapps/applications/screensavers/starfield/lang/pl-PL.rc b/modules/rosapps/applications/screensavers/starfield/lang/pl-PL.rc index 3b4f09df42632..ad243d1b3077c 100644 --- a/modules/rosapps/applications/screensavers/starfield/lang/pl-PL.rc +++ b/modules/rosapps/applications/screensavers/starfield/lang/pl-PL.rc @@ -7,7 +7,7 @@ LANGUAGE LANG_POLISH, SUBLANG_DEFAULT -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Wygaszacz Gwiazdy" IDS_TITLE "O programie" diff --git a/modules/rosapps/applications/screensavers/starfield/lang/ro-RO.rc b/modules/rosapps/applications/screensavers/starfield/lang/ro-RO.rc index e1e5c2952b089..b8d6dcaa11aaf 100644 --- a/modules/rosapps/applications/screensavers/starfield/lang/ro-RO.rc +++ b/modules/rosapps/applications/screensavers/starfield/lang/ro-RO.rc @@ -8,9 +8,7 @@ LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL -#pragma code_page(65001) - -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Câmp de stele (animație de inactivitate)" IDS_TITLE "Despre…" diff --git a/modules/rosapps/applications/screensavers/starfield/lang/sk-SK.rc b/modules/rosapps/applications/screensavers/starfield/lang/sk-SK.rc index 30777798a45f2..98ea09d8ea770 100644 --- a/modules/rosapps/applications/screensavers/starfield/lang/sk-SK.rc +++ b/modules/rosapps/applications/screensavers/starfield/lang/sk-SK.rc @@ -4,7 +4,7 @@ LANGUAGE LANG_SLOVAK, SUBLANG_DEFAULT -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Hviezdne pole - šetrič obrazovky" IDS_TITLE "Čo je ..." diff --git a/modules/rosapps/applications/screensavers/starfield/lang/tr-TR.rc b/modules/rosapps/applications/screensavers/starfield/lang/tr-TR.rc index d4a27fd6e9d4a..2bee6fc2e6a27 100644 --- a/modules/rosapps/applications/screensavers/starfield/lang/tr-TR.rc +++ b/modules/rosapps/applications/screensavers/starfield/lang/tr-TR.rc @@ -7,7 +7,7 @@ LANGUAGE LANG_TURKISH, SUBLANG_NEUTRAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Starfield Ekran Koruyucu" IDS_TITLE "Hakkında" diff --git a/modules/rosapps/applications/screensavers/starfield/lang/uk-UA.rc b/modules/rosapps/applications/screensavers/starfield/lang/uk-UA.rc index beed22b4b8871..0d9ff8388d298 100644 --- a/modules/rosapps/applications/screensavers/starfield/lang/uk-UA.rc +++ b/modules/rosapps/applications/screensavers/starfield/lang/uk-UA.rc @@ -8,7 +8,7 @@ LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "Заставка ""Зоряне поле""" IDS_TITLE "Про" diff --git a/modules/rosapps/applications/screensavers/starfield/lang/zh-CN.rc b/modules/rosapps/applications/screensavers/starfield/lang/zh-CN.rc index a26e4d2f0a02c..0d2da2f3db481 100644 --- a/modules/rosapps/applications/screensavers/starfield/lang/zh-CN.rc +++ b/modules/rosapps/applications/screensavers/starfield/lang/zh-CN.rc @@ -2,7 +2,7 @@ LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "星空屏幕保护程序" IDS_TITLE "关于" diff --git a/modules/rosapps/applications/screensavers/starfield/lang/zh-HK.rc b/modules/rosapps/applications/screensavers/starfield/lang/zh-HK.rc index e1bd725376047..d0c95926a0bf1 100644 --- a/modules/rosapps/applications/screensavers/starfield/lang/zh-HK.rc +++ b/modules/rosapps/applications/screensavers/starfield/lang/zh-HK.rc @@ -7,7 +7,7 @@ LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_HONGKONG -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "星空螢幕保護程式" IDS_TITLE "關於" diff --git a/modules/rosapps/applications/screensavers/starfield/lang/zh-TW.rc b/modules/rosapps/applications/screensavers/starfield/lang/zh-TW.rc index c0a3b70afb3bf..fc26fd17aaa44 100644 --- a/modules/rosapps/applications/screensavers/starfield/lang/zh-TW.rc +++ b/modules/rosapps/applications/screensavers/starfield/lang/zh-TW.rc @@ -7,7 +7,7 @@ LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DESCRIPTION "星空螢幕保護程式" IDS_TITLE "關於" diff --git a/modules/rosapps/applications/screensavers/starfield/starfield.rc b/modules/rosapps/applications/screensavers/starfield/starfield.rc index 01960d9058d46..ed4a9d63976fe 100644 --- a/modules/rosapps/applications/screensavers/starfield/starfield.rc +++ b/modules/rosapps/applications/screensavers/starfield/starfield.rc @@ -4,12 +4,12 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL -IDI_ICON ICON DISCARDABLE "res/icon_starfield.ico" +IDI_ICON ICON "res/icon_starfield.ico" #define REACTOS_VERSION_DLL -#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Starfield ScreenSaver\0" -#define REACTOS_STR_INTERNAL_NAME "starfield\0" -#define REACTOS_STR_ORIGINAL_FILENAME "starfield.scr\0" +#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Starfield ScreenSaver" +#define REACTOS_STR_INTERNAL_NAME "starfield" +#define REACTOS_STR_ORIGINAL_FILENAME "starfield.scr" #include diff --git a/modules/rosapps/applications/sysutils/ctm/ctm.rc b/modules/rosapps/applications/sysutils/ctm/ctm.rc index 3ba39784ae325..86323fbc8ccf6 100644 --- a/modules/rosapps/applications/sysutils/ctm/ctm.rc +++ b/modules/rosapps/applications/sysutils/ctm/ctm.rc @@ -2,10 +2,10 @@ #include #include "resource.h" -#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Console Task Manager\0" -#define REACTOS_STR_INTERNAL_NAME "ctm\0" -#define REACTOS_STR_ORIGINAL_FILENAME "ctm.exe\0" -#define REACTOS_STR_ORIGINAL_COPYRIGHT "2003, Aleksey Bragin\0" +#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Console Task Manager" +#define REACTOS_STR_INTERNAL_NAME "ctm" +#define REACTOS_STR_ORIGINAL_FILENAME "ctm.exe" +#define REACTOS_STR_ORIGINAL_COPYRIGHT "2003, Aleksey Bragin" #include /* UTF-8 */ diff --git a/modules/rosapps/applications/sysutils/ctm/lang/de-DE.rc b/modules/rosapps/applications/sysutils/ctm/lang/de-DE.rc index 0704362d071f4..aa571cd91a804 100644 --- a/modules/rosapps/applications/sysutils/ctm/lang/de-DE.rc +++ b/modules/rosapps/applications/sysutils/ctm/lang/de-DE.rc @@ -2,7 +2,7 @@ LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_APP_TITLE "Console TaskManager von Aleksey Bragin " @@ -11,7 +11,7 @@ BEGIN IDS_COLUMN_PID "PID " IDS_COLUMN_CPU "CPU" IDS_COLUMN_MEM "Speicher" - IDS_COLUMN_MEM_UNIT "KB" + IDS_COLUMN_MEM_UNIT "KB" IDS_COLUMN_PF "Seitenfehler" IDS_IDLE_PROCESS "Leerlaufprozess" diff --git a/modules/rosapps/applications/sysutils/ctm/lang/el-GR.rc b/modules/rosapps/applications/sysutils/ctm/lang/el-GR.rc index 3c685af2c8de6..1ec97a598f1fa 100644 --- a/modules/rosapps/applications/sysutils/ctm/lang/el-GR.rc +++ b/modules/rosapps/applications/sysutils/ctm/lang/el-GR.rc @@ -2,7 +2,7 @@ LANGUAGE LANG_GREEK, SUBLANG_DEFAULT -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_APP_TITLE "Console TaskManager by Aleksey Bragin " @@ -11,7 +11,7 @@ BEGIN IDS_COLUMN_PID "PID " IDS_COLUMN_CPU "CPU" IDS_COLUMN_MEM "Χρήση μνήμης" - IDS_COLUMN_MEM_UNIT "KB" + IDS_COLUMN_MEM_UNIT "KB" IDS_COLUMN_PF "Page Faults" IDS_IDLE_PROCESS "Αδρανής διαδικασία" diff --git a/modules/rosapps/applications/sysutils/ctm/lang/en-US.rc b/modules/rosapps/applications/sysutils/ctm/lang/en-US.rc index d96b5c18dce8b..a7a0d299df138 100644 --- a/modules/rosapps/applications/sysutils/ctm/lang/en-US.rc +++ b/modules/rosapps/applications/sysutils/ctm/lang/en-US.rc @@ -2,7 +2,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_APP_TITLE "Console TaskManager by Aleksey Bragin " @@ -11,7 +11,7 @@ BEGIN IDS_COLUMN_PID "PID " IDS_COLUMN_CPU "CPU" IDS_COLUMN_MEM "Mem Usage" - IDS_COLUMN_MEM_UNIT "KB" + IDS_COLUMN_MEM_UNIT "KB" IDS_COLUMN_PF "Page Faults" IDS_IDLE_PROCESS "System Idle Process" diff --git a/modules/rosapps/applications/sysutils/ctm/lang/es-ES.rc b/modules/rosapps/applications/sysutils/ctm/lang/es-ES.rc index 2bfa1447b7763..60001a0f8e464 100644 --- a/modules/rosapps/applications/sysutils/ctm/lang/es-ES.rc +++ b/modules/rosapps/applications/sysutils/ctm/lang/es-ES.rc @@ -2,7 +2,7 @@ LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_APP_TITLE "Administrador de tareas de la Consola por Aleksey Bragin " @@ -11,7 +11,7 @@ BEGIN IDS_COLUMN_PID "PID " IDS_COLUMN_CPU "CPU" IDS_COLUMN_MEM "Uso Memor." - IDS_COLUMN_MEM_UNIT "KB" + IDS_COLUMN_MEM_UNIT "KB" IDS_COLUMN_PF "Fallos de paginación" IDS_IDLE_PROCESS "Proceso inactivo del sistema" diff --git a/modules/rosapps/applications/sysutils/ctm/lang/fr-FR.rc b/modules/rosapps/applications/sysutils/ctm/lang/fr-FR.rc index 87203fe2ddfb8..86d87b9d723a9 100644 --- a/modules/rosapps/applications/sysutils/ctm/lang/fr-FR.rc +++ b/modules/rosapps/applications/sysutils/ctm/lang/fr-FR.rc @@ -2,7 +2,7 @@ LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_APP_TITLE "Console TaskManager par Aleksey Bragin " @@ -11,7 +11,7 @@ BEGIN IDS_COLUMN_PID "PID " IDS_COLUMN_CPU "CPU" IDS_COLUMN_MEM "Util. mém" - IDS_COLUMN_MEM_UNIT "KO" + IDS_COLUMN_MEM_UNIT "KO" IDS_COLUMN_PF "Défauts de page" IDS_IDLE_PROCESS "Processus inactif du système" diff --git a/modules/rosapps/applications/sysutils/ctm/lang/no-NO.rc b/modules/rosapps/applications/sysutils/ctm/lang/no-NO.rc index f18f06695a497..c94ea13c86b3a 100644 --- a/modules/rosapps/applications/sysutils/ctm/lang/no-NO.rc +++ b/modules/rosapps/applications/sysutils/ctm/lang/no-NO.rc @@ -2,7 +2,7 @@ LANGUAGE LANG_NORWEGIAN, SUBLANG_NEUTRAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_APP_TITLE "Konsoll oppgavebehandler av Aleksey Bragin " @@ -11,7 +11,7 @@ BEGIN IDS_COLUMN_PID "PID " IDS_COLUMN_CPU "Prosesor" IDS_COLUMN_MEM "Minnebruk" - IDS_COLUMN_MEM_UNIT "KB" + IDS_COLUMN_MEM_UNIT "KB" IDS_COLUMN_PF "Page Faults" IDS_IDLE_PROCESS "System Idle Process" diff --git a/modules/rosapps/applications/sysutils/ctm/lang/pl-PL.rc b/modules/rosapps/applications/sysutils/ctm/lang/pl-PL.rc index 1ea61476b40bb..ac15f56bdf6b3 100644 --- a/modules/rosapps/applications/sysutils/ctm/lang/pl-PL.rc +++ b/modules/rosapps/applications/sysutils/ctm/lang/pl-PL.rc @@ -2,7 +2,7 @@ LANGUAGE LANG_POLISH, SUBLANG_DEFAULT -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_APP_TITLE "Console TaskManager by Aleksey Bragin " @@ -11,7 +11,7 @@ BEGIN IDS_COLUMN_PID "PID " IDS_COLUMN_CPU "CPU" IDS_COLUMN_MEM "Użycie pamięci" - IDS_COLUMN_MEM_UNIT "KB" + IDS_COLUMN_MEM_UNIT "KB" IDS_COLUMN_PF "Błędy strony" IDS_IDLE_PROCESS "Proces bezczynności systemu" diff --git a/modules/rosapps/applications/sysutils/ctm/lang/ro-RO.rc b/modules/rosapps/applications/sysutils/ctm/lang/ro-RO.rc index 708e1c71e33c3..cdc1bc1e522cf 100644 --- a/modules/rosapps/applications/sysutils/ctm/lang/ro-RO.rc +++ b/modules/rosapps/applications/sysutils/ctm/lang/ro-RO.rc @@ -8,9 +8,7 @@ LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL -#pragma code_page(65001) - -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_APP_TITLE "Gestionar de activități consolă v0.1 de Aleksey Bragin " @@ -19,7 +17,7 @@ BEGIN IDS_COLUMN_PID "IDP " IDS_COLUMN_CPU "UCP" IDS_COLUMN_MEM "Uz memor." - IDS_COLUMN_MEM_UNIT "ko" + IDS_COLUMN_MEM_UNIT "ko" IDS_COLUMN_PF "Er. de pag." IDS_IDLE_PROCESS "Proces de inactivitate sistem" diff --git a/modules/rosapps/applications/sysutils/ctm/lang/ru-RU.rc b/modules/rosapps/applications/sysutils/ctm/lang/ru-RU.rc index d21c59dde677a..c98159041e877 100644 --- a/modules/rosapps/applications/sysutils/ctm/lang/ru-RU.rc +++ b/modules/rosapps/applications/sysutils/ctm/lang/ru-RU.rc @@ -2,7 +2,7 @@ LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_APP_TITLE "Консольный Диспетчер задач от Алексея Брагина " diff --git a/modules/rosapps/applications/sysutils/ctm/lang/uk-UA.rc b/modules/rosapps/applications/sysutils/ctm/lang/uk-UA.rc index 0441acfb82bfd..856e7032e633b 100644 --- a/modules/rosapps/applications/sysutils/ctm/lang/uk-UA.rc +++ b/modules/rosapps/applications/sysutils/ctm/lang/uk-UA.rc @@ -8,7 +8,7 @@ LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_APP_TITLE "Консольний Диспетчер завдань від Aleksey Bragin " @@ -17,7 +17,7 @@ BEGIN IDS_COLUMN_PID "PID " IDS_COLUMN_CPU "CPU" IDS_COLUMN_MEM "Використання пам'яті" - IDS_COLUMN_MEM_UNIT "KB" + IDS_COLUMN_MEM_UNIT "KB" IDS_COLUMN_PF "Помилок сторінки" IDS_IDLE_PROCESS "Недіяння системи" diff --git a/modules/rosapps/applications/sysutils/ctm/lang/zh-TW.rc b/modules/rosapps/applications/sysutils/ctm/lang/zh-TW.rc index ba074604436fc..f76fa04dd4bf9 100644 --- a/modules/rosapps/applications/sysutils/ctm/lang/zh-TW.rc +++ b/modules/rosapps/applications/sysutils/ctm/lang/zh-TW.rc @@ -2,7 +2,7 @@ LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_APP_TITLE "主控台工作管理員,由 Aleksey Bragin 開發" diff --git a/modules/rosapps/applications/sysutils/fontsub/fontsub_res.rc b/modules/rosapps/applications/sysutils/fontsub/fontsub_res.rc index 0feaed8017d19..d054576ed59bc 100644 --- a/modules/rosapps/applications/sysutils/fontsub/fontsub_res.rc +++ b/modules/rosapps/applications/sysutils/fontsub/fontsub_res.rc @@ -20,15 +20,15 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL #define REACTOS_STR_ORIGINAL_FILENAME "fontsub.exe" #include -/* UTF-8 */ -#pragma code_page(65001) - 1 ICON "fontsub.ico" 2 BITMAP "up.bmp" 3 BITMAP "down.bmp" 4 BITMAP "nil.bmp" +/* UTF-8 */ +#pragma code_page(65001) + #ifdef LANGUAGE_DE_DE #include "lang/de-DE.rc" #endif diff --git a/modules/rosapps/applications/sysutils/fontsub/lang/de-DE.rc b/modules/rosapps/applications/sysutils/fontsub/lang/de-DE.rc index a967b49f5646d..6c14c6cb81096 100644 --- a/modules/rosapps/applications/sysutils/fontsub/lang/de-DE.rc +++ b/modules/rosapps/applications/sysutils/fontsub/lang/de-DE.rc @@ -8,9 +8,6 @@ * work. If not, see . */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL 1 MENU diff --git a/modules/rosapps/applications/sysutils/fontsub/lang/en-US.rc b/modules/rosapps/applications/sysutils/fontsub/lang/en-US.rc index 780e0f8b58392..9c6e10ece55b2 100644 --- a/modules/rosapps/applications/sysutils/fontsub/lang/en-US.rc +++ b/modules/rosapps/applications/sysutils/fontsub/lang/en-US.rc @@ -8,9 +8,6 @@ * work. If not, see . */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 1 MENU diff --git a/modules/rosapps/applications/sysutils/fontsub/lang/es-ES.rc b/modules/rosapps/applications/sysutils/fontsub/lang/es-ES.rc index 2b1c2ecd69994..d187c346b6df9 100644 --- a/modules/rosapps/applications/sysutils/fontsub/lang/es-ES.rc +++ b/modules/rosapps/applications/sysutils/fontsub/lang/es-ES.rc @@ -10,9 +10,6 @@ * Translation: Julen Urizar Compains */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL 1 MENU diff --git a/modules/rosapps/applications/sysutils/fontsub/lang/ja-JP.rc b/modules/rosapps/applications/sysutils/fontsub/lang/ja-JP.rc index 012bce71d3031..03d460e78926e 100644 --- a/modules/rosapps/applications/sysutils/fontsub/lang/ja-JP.rc +++ b/modules/rosapps/applications/sysutils/fontsub/lang/ja-JP.rc @@ -8,9 +8,6 @@ * work. If not, see . */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT 1 MENU diff --git a/modules/rosapps/applications/sysutils/fontsub/lang/pl-PL.rc b/modules/rosapps/applications/sysutils/fontsub/lang/pl-PL.rc index 05dbb31093f46..6bc10b03f2470 100644 --- a/modules/rosapps/applications/sysutils/fontsub/lang/pl-PL.rc +++ b/modules/rosapps/applications/sysutils/fontsub/lang/pl-PL.rc @@ -8,9 +8,6 @@ * work. If not, see . */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_POLISH, SUBLANG_DEFAULT 1 MENU diff --git a/modules/rosapps/applications/sysutils/fontsub/lang/ru-RU.rc b/modules/rosapps/applications/sysutils/fontsub/lang/ru-RU.rc index ab6258e087f09..0057ee28e0da0 100644 --- a/modules/rosapps/applications/sysutils/fontsub/lang/ru-RU.rc +++ b/modules/rosapps/applications/sysutils/fontsub/lang/ru-RU.rc @@ -8,9 +8,6 @@ * work. If not, see . */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT 1 MENU diff --git a/modules/rosapps/applications/sysutils/fontsub/lang/tr-TR.rc b/modules/rosapps/applications/sysutils/fontsub/lang/tr-TR.rc index 06a49d97abe02..f36f4becbc333 100644 --- a/modules/rosapps/applications/sysutils/fontsub/lang/tr-TR.rc +++ b/modules/rosapps/applications/sysutils/fontsub/lang/tr-TR.rc @@ -5,9 +5,6 @@ * TRANSLATOR: Copyright 2022 Süleyman Poyraz */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_TURKISH, SUBLANG_NEUTRAL 1 MENU diff --git a/modules/rosapps/applications/sysutils/fontsub/lang/zh-CN.rc b/modules/rosapps/applications/sysutils/fontsub/lang/zh-CN.rc index 8a732f5dc2968..b851148c15fbe 100644 --- a/modules/rosapps/applications/sysutils/fontsub/lang/zh-CN.rc +++ b/modules/rosapps/applications/sysutils/fontsub/lang/zh-CN.rc @@ -8,9 +8,6 @@ * work. If not, see . */ -/* UTF-8 */ -#pragma code_page(65001) - /* Translated by Luke Luo on 2018-11-13 */ LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED diff --git a/modules/rosapps/applications/sysutils/fontsub/lang/zh-HK.rc b/modules/rosapps/applications/sysutils/fontsub/lang/zh-HK.rc index e592bc5613bc8..0dc8bcb7a67f7 100644 --- a/modules/rosapps/applications/sysutils/fontsub/lang/zh-HK.rc +++ b/modules/rosapps/applications/sysutils/fontsub/lang/zh-HK.rc @@ -6,9 +6,6 @@ * REFERENCES: Chinese (Traditional) resource file */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_HONGKONG 1 MENU diff --git a/modules/rosapps/applications/sysutils/fontsub/lang/zh-TW.rc b/modules/rosapps/applications/sysutils/fontsub/lang/zh-TW.rc index 34fef3f833ee4..d6f3e0361fbed 100644 --- a/modules/rosapps/applications/sysutils/fontsub/lang/zh-TW.rc +++ b/modules/rosapps/applications/sysutils/fontsub/lang/zh-TW.rc @@ -6,9 +6,6 @@ * Copyright 2021 Chan Chilung */ -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL 1 MENU diff --git a/modules/rosapps/applications/sysutils/systeminfo/lang/de-DE.rc b/modules/rosapps/applications/sysutils/systeminfo/lang/de-DE.rc index d6d37a98fe8ea..71e60e5bd7029 100644 --- a/modules/rosapps/applications/sysutils/systeminfo/lang/de-DE.rc +++ b/modules/rosapps/applications/sysutils/systeminfo/lang/de-DE.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_USAGE, "SYSTEMINFO [/S System [/U Benutzername [/P [Passwort]]]] [/FO Format] [/NH]\n\n\ diff --git a/modules/rosapps/applications/sysutils/systeminfo/lang/en-US.rc b/modules/rosapps/applications/sysutils/systeminfo/lang/en-US.rc index d603471ba8a5d..f1beb5a29d6d7 100644 --- a/modules/rosapps/applications/sysutils/systeminfo/lang/en-US.rc +++ b/modules/rosapps/applications/sysutils/systeminfo/lang/en-US.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_USAGE, "SYSTEMINFO [/S system [/U username [/P [password]]]] [/FO format] [/NH]\n\n\ diff --git a/modules/rosapps/applications/sysutils/systeminfo/lang/es-ES.rc b/modules/rosapps/applications/sysutils/systeminfo/lang/es-ES.rc index d0a60d4f3eb56..4b352a983bfb2 100644 --- a/modules/rosapps/applications/sysutils/systeminfo/lang/es-ES.rc +++ b/modules/rosapps/applications/sysutils/systeminfo/lang/es-ES.rc @@ -6,7 +6,7 @@ LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_USAGE, "SYSTEMINFO [/S sistema [/U usuario [/P [contraseña]]]] [/FO formato] [/NH]\n\n\ diff --git a/modules/rosapps/applications/sysutils/systeminfo/lang/fr-FR.rc b/modules/rosapps/applications/sysutils/systeminfo/lang/fr-FR.rc index cc751f12f964e..39586d24559db 100644 --- a/modules/rosapps/applications/sysutils/systeminfo/lang/fr-FR.rc +++ b/modules/rosapps/applications/sysutils/systeminfo/lang/fr-FR.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_USAGE "SYSTEMINFO [/S système [/U utilisateur [/P [motdepasse]]]] [/FO format] [/NH]\n\n\ diff --git a/modules/rosapps/applications/sysutils/systeminfo/lang/it-IT.rc b/modules/rosapps/applications/sysutils/systeminfo/lang/it-IT.rc index 400d1d2a4e6b5..1c4d0c4071d16 100644 --- a/modules/rosapps/applications/sysutils/systeminfo/lang/it-IT.rc +++ b/modules/rosapps/applications/sysutils/systeminfo/lang/it-IT.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_USAGE, "SYSTEMINFO [/S sistema [/U nomeutente [/P [password]]]] [/FO formato] [/NH]\n\n\ diff --git a/modules/rosapps/applications/sysutils/systeminfo/lang/no-NO.rc b/modules/rosapps/applications/sysutils/systeminfo/lang/no-NO.rc index 6d5370d3445fa..840bf5198f148 100644 --- a/modules/rosapps/applications/sysutils/systeminfo/lang/no-NO.rc +++ b/modules/rosapps/applications/sysutils/systeminfo/lang/no-NO.rc @@ -1,6 +1,6 @@ LANGUAGE LANG_NORWEGIAN, SUBLANG_NEUTRAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_USAGE, "SYSTEMINFO [/S system [/U brukernavn [/P [passord]]]] [/FO format] [/NH]\n\n\ diff --git a/modules/rosapps/applications/sysutils/systeminfo/lang/pl-PL.rc b/modules/rosapps/applications/sysutils/systeminfo/lang/pl-PL.rc index 499684413d0c0..f1ba3279fe4ad 100644 --- a/modules/rosapps/applications/sysutils/systeminfo/lang/pl-PL.rc +++ b/modules/rosapps/applications/sysutils/systeminfo/lang/pl-PL.rc @@ -7,7 +7,7 @@ LANGUAGE LANG_POLISH, SUBLANG_DEFAULT -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_USAGE, "SYSTEMINFO [/S system [/U nazwa użytkownika [/P [hasło]]]] [/FO format] [/NH]\n\n\ diff --git a/modules/rosapps/applications/sysutils/systeminfo/lang/ro-RO.rc b/modules/rosapps/applications/sysutils/systeminfo/lang/ro-RO.rc index cd5737604e016..647dcd090abf1 100644 --- a/modules/rosapps/applications/sysutils/systeminfo/lang/ro-RO.rc +++ b/modules/rosapps/applications/sysutils/systeminfo/lang/ro-RO.rc @@ -8,7 +8,7 @@ LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_USAGE, "SYSTEMINFO [/S sistem [/U nume [/P [parolă]]]] [/FO format] [/NH]\n\n\ diff --git a/modules/rosapps/applications/sysutils/systeminfo/lang/ru-RU.rc b/modules/rosapps/applications/sysutils/systeminfo/lang/ru-RU.rc index ffce71e3a403e..5b53f1ee8e2ed 100644 --- a/modules/rosapps/applications/sysutils/systeminfo/lang/ru-RU.rc +++ b/modules/rosapps/applications/sysutils/systeminfo/lang/ru-RU.rc @@ -8,7 +8,7 @@ LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_USAGE, "SYSTEMINFO [/S система [/U имяПользователя [/P [пароль]]]] [/FO формат] [/NH]\n\n\ diff --git a/modules/rosapps/applications/sysutils/systeminfo/lang/sk-SK.rc b/modules/rosapps/applications/sysutils/systeminfo/lang/sk-SK.rc index 04163646ddbb6..0e45f8452f8c7 100644 --- a/modules/rosapps/applications/sysutils/systeminfo/lang/sk-SK.rc +++ b/modules/rosapps/applications/sysutils/systeminfo/lang/sk-SK.rc @@ -4,7 +4,7 @@ LANGUAGE LANG_SLOVAK, SUBLANG_DEFAULT -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_USAGE, "SYSTEMINFO [/S syst‚m [/U pou§._meno [/P [heslo]]]] [/FO form t] [/NH]\n\n\ diff --git a/modules/rosapps/applications/sysutils/systeminfo/lang/tr-TR.rc b/modules/rosapps/applications/sysutils/systeminfo/lang/tr-TR.rc index 19e4005ebbc4a..f3ca6797e32b0 100644 --- a/modules/rosapps/applications/sysutils/systeminfo/lang/tr-TR.rc +++ b/modules/rosapps/applications/sysutils/systeminfo/lang/tr-TR.rc @@ -7,7 +7,7 @@ LANGUAGE LANG_TURKISH, SUBLANG_NEUTRAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_USAGE, "SYSTEMINFO [/S sistem [/U kullanici_adi [/P [sifre]]]] [/FO format] [/NH]\n\n\ diff --git a/modules/rosapps/applications/sysutils/systeminfo/lang/uk-UA.rc b/modules/rosapps/applications/sysutils/systeminfo/lang/uk-UA.rc index cae4845e492f3..a601bce2ea0c1 100644 --- a/modules/rosapps/applications/sysutils/systeminfo/lang/uk-UA.rc +++ b/modules/rosapps/applications/sysutils/systeminfo/lang/uk-UA.rc @@ -8,7 +8,7 @@ LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_USAGE, "SYSTEMINFO [/S система [/U користувач [/P [пароль]]]] [/FO формат] [/NH]\n\n\ diff --git a/modules/rosapps/applications/sysutils/systeminfo/lang/zh-CN.rc b/modules/rosapps/applications/sysutils/systeminfo/lang/zh-CN.rc index b11a359b25030..a285d95602008 100644 --- a/modules/rosapps/applications/sysutils/systeminfo/lang/zh-CN.rc +++ b/modules/rosapps/applications/sysutils/systeminfo/lang/zh-CN.rc @@ -7,7 +7,7 @@ LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_USAGE, "SYSTEMINFO [/S system [/U username [/P [password]]]] [/FO format] [/NH]\n\n\ diff --git a/modules/rosapps/applications/sysutils/systeminfo/lang/zh-TW.rc b/modules/rosapps/applications/sysutils/systeminfo/lang/zh-TW.rc index 8c8dac3e090cc..af26041ba8877 100644 --- a/modules/rosapps/applications/sysutils/systeminfo/lang/zh-TW.rc +++ b/modules/rosapps/applications/sysutils/systeminfo/lang/zh-TW.rc @@ -7,7 +7,7 @@ LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_USAGE, "SYSTEMINFO [/S system [/U username [/P [password]]]] [/FO format] [/NH]\n\n\ diff --git a/modules/rosapps/demos/maze/maze.rc b/modules/rosapps/demos/maze/maze.rc index c1614c45be143..da1dc87f9cb76 100644 --- a/modules/rosapps/demos/maze/maze.rc +++ b/modules/rosapps/demos/maze/maze.rc @@ -6,7 +6,7 @@ #define REACTOS_STR_ORIGINAL_FILENAME "maze.exe" #include -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN idsAppName "Screen Saver.Maze" END diff --git a/modules/rosapps/drivers/green/misc.c b/modules/rosapps/drivers/green/misc.c index b467146a742fd..50b84755bbf4c 100644 --- a/modules/rosapps/drivers/green/misc.c +++ b/modules/rosapps/drivers/green/misc.c @@ -85,18 +85,18 @@ ReadRegistryEntries( RtlZeroMemory(Parameters, sizeof(Parameters)); - Parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT; + Parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED; Parameters[0].Name = L"AttachedDevice"; Parameters[0].EntryContext = &DriverExtension->AttachedDeviceName; - Parameters[1].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[1].Flags = RTL_QUERY_REGISTRY_DIRECT; Parameters[1].Name = L"DeviceReported"; Parameters[1].EntryContext = &DriverExtension->DeviceReported; Parameters[1].DefaultType = REG_DWORD; Parameters[1].DefaultData = &DefaultDeviceReported; Parameters[1].DefaultLength = sizeof(ULONG); - Parameters[2].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[2].Flags = RTL_QUERY_REGISTRY_DIRECT; Parameters[2].Name = L"SampleRate"; Parameters[2].EntryContext = &DriverExtension->SampleRate; Parameters[2].DefaultType = REG_DWORD; @@ -104,7 +104,7 @@ ReadRegistryEntries( Parameters[2].DefaultLength = sizeof(ULONG); Status = RtlQueryRegistryValues( - RTL_REGISTRY_ABSOLUTE, + RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL, ParametersRegistryKey.Buffer, Parameters, NULL, diff --git a/modules/rosapps/lib/vfdlib/vfdlib.rc b/modules/rosapps/lib/vfdlib/vfdlib.rc index 561407e5e81e3..31073ef38daf4 100644 --- a/modules/rosapps/lib/vfdlib/vfdlib.rc +++ b/modules/rosapps/lib/vfdlib/vfdlib.rc @@ -13,7 +13,7 @@ #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// -// ƭ resources +// resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) #ifdef _WIN32 @@ -199,7 +199,7 @@ IDI_VFD_ICON ICON DISCARDABLE "res/vfd.ico" IDI_IMAGE_ICON ICON DISCARDABLE "res/image.ico" IDI_CONFIG_ICON ICON DISCARDABLE "res/config.ico" #endif -#endif // ƭ resources +#endif // resources ///////////////////////////////////////////////////////////////////////////// diff --git a/modules/rosapps/templates/dialog/dialog.rc b/modules/rosapps/templates/dialog/dialog.rc index e1eba836bcd3f..1c965a9533d48 100644 --- a/modules/rosapps/templates/dialog/dialog.rc +++ b/modules/rosapps/templates/dialog/dialog.rc @@ -1,14 +1,14 @@ #include #include "resource.h" -#define REACTOS_STR_FILE_DESCRIPTION "Tab Control Test\0" -#define REACTOS_STR_INTERNAL_NAME "template_dialog\0" -#define REACTOS_STR_ORIGINAL_FILENAME "template_dialog.exe\0" +#define REACTOS_STR_FILE_DESCRIPTION "Tab Control Test" +#define REACTOS_STR_INTERNAL_NAME "template_dialog" +#define REACTOS_STR_ORIGINAL_FILENAME "template_dialog.exe" #include LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL -IDD_TABBED_DIALOG DIALOGEX DISCARDABLE 0, 0, 243, 230 +IDD_TABBED_DIALOG DIALOGEX 0, 0, 243, 230 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "TabTest Dialog" FONT 8, "MS Shell Dlg" @@ -18,7 +18,7 @@ BEGIN CONTROL "Tab1",IDC_TAB,"SysTabControl32",0x0,7,7,229,190 END -IDD_PAGE1 DIALOGEX DISCARDABLE 10, 20, 180, 144 +IDD_PAGE1 DIALOGEX 10, 20, 180, 144 STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN FONT 8, "MS Shell Dlg" BEGIN @@ -27,7 +27,7 @@ BEGIN LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP END -IDD_PAGE2 DIALOGEX DISCARDABLE 10, 20, 180, 144 +IDD_PAGE2 DIALOGEX 10, 20, 180, 144 STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN FONT 8, "MS Shell Dlg" BEGIN @@ -35,7 +35,7 @@ BEGIN WS_TABSTOP,26,48,123,9 END -IDD_PAGE3 DIALOGEX DISCARDABLE 10, 20, 180, 144 +IDD_PAGE3 DIALOGEX 10, 20, 180, 144 STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN FONT 8, "MS Shell Dlg" BEGIN diff --git a/modules/rosapps/templates/mdi/mdi.rc b/modules/rosapps/templates/mdi/mdi.rc index 4b78b4c59679d..7b6a1cb97e7f2 100644 --- a/modules/rosapps/templates/mdi/mdi.rc +++ b/modules/rosapps/templates/mdi/mdi.rc @@ -1,23 +1,23 @@ #include "resource.h" #include -#define REACTOS_STR_FILE_DESCRIPTION "ReactOS MDI Sample Application by Robert Dickenson\0" -#define REACTOS_STR_INTERNAL_NAME "mdi\0" -#define REACTOS_STR_ORIGINAL_FILENAME "mdi.exe\0" -#define REACTOS_STR_ORIGINAL_COPYRIGHT "Copyright © 2002 Robert Dickenson\0" +#define REACTOS_STR_FILE_DESCRIPTION "ReactOS MDI Sample Application by Robert Dickenson" +#define REACTOS_STR_INTERNAL_NAME "mdi" +#define REACTOS_STR_ORIGINAL_FILENAME "mdi.exe" +#define REACTOS_STR_ORIGINAL_COPYRIGHT "Copyright © 2002 Robert Dickenson" #include LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL /* Icons */ -IDI_MDI_APP ICON DISCARDABLE "res/mdi.ico" -IDI_SMALL ICON DISCARDABLE "res/small.ico" +IDI_MDI_APP ICON "res/mdi.ico" +IDI_SMALL ICON "res/small.ico" /* Bitmaps */ -IDB_TOOLBAR BITMAP DISCARDABLE "res/toolbar.bmp" -IDB_IMAGES BITMAP DISCARDABLE "res/images.bmp" +IDB_TOOLBAR BITMAP "res/toolbar.bmp" +IDB_IMAGES BITMAP "res/images.bmp" -IDC_MDI_APP MENU DISCARDABLE +IDC_MDI_APP MENU BEGIN POPUP "&File" BEGIN @@ -59,7 +59,7 @@ BEGIN END END -IDD_DIALOG1 DIALOGEX DISCARDABLE 0, 0, 186, 95 +IDD_DIALOG1 DIALOGEX 0, 0, 186, 95 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Dialog" FONT 8, "MS Shell Dlg" @@ -68,7 +68,7 @@ BEGIN PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14 END -IDD_ABOUTBOX DIALOGEX DISCARDABLE 22, 17, 230, 75 +IDD_ABOUTBOX DIALOGEX 22, 17, 230, 75 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU CAPTION "About" FONT 8, "MS Shell Dlg" @@ -80,7 +80,7 @@ BEGIN DEFPUSHBUTTON "OK",IDOK,195,6,30,11,WS_GROUP END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_APP_TITLE "ReactOS Application" diff --git a/modules/rosapps/templates/old_wordpad/lang/bg-BG.rc b/modules/rosapps/templates/old_wordpad/lang/bg-BG.rc index 3fcea1ed6be4a..00eb88eaba708 100644 --- a/modules/rosapps/templates/old_wordpad/lang/bg-BG.rc +++ b/modules/rosapps/templates/old_wordpad/lang/bg-BG.rc @@ -108,14 +108,14 @@ BEGIN END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_LICENSE "This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.\r\n\r\nThis program 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 General Public License for more details.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." IDS_DEFAULT_NAME "Документ %1!u!" IDS_READY " Готов." END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DOC_TYPE_RICH_TEXT "Обогатен словесен документ (RTF)" IDS_DOC_TYPE_UNICODE_TEXT "Словесен документ" @@ -125,7 +125,7 @@ END /* Tooltips */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_NEW "Нов" IDS_TOOLTIP_OPEN "Отваряне" @@ -140,7 +140,7 @@ BEGIN END /* Hints */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_NEW " Създава нов документ." diff --git a/modules/rosapps/templates/old_wordpad/lang/de-DE.rc b/modules/rosapps/templates/old_wordpad/lang/de-DE.rc index a2c21b9ee1fe5..9cdb50b3c1f7b 100644 --- a/modules/rosapps/templates/old_wordpad/lang/de-DE.rc +++ b/modules/rosapps/templates/old_wordpad/lang/de-DE.rc @@ -108,14 +108,14 @@ BEGIN END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_LICENSE "Dieses Programm ist kostenlos; Sie können es frei verteilen mit od. ohne Änderungen unter der GNU Lesser General Public License wie es von der Free Software Foundation veröffentlicht wurde; entweder Version 2.1 der Lizenz, oder eine spätere Version (ihrer Wahl).\r\n\r\nThis program 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 General Public License for more details.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." IDS_DEFAULT_NAME "Dokument %1!u!" IDS_READY " Fertig." END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DOC_TYPE_RICH_TEXT "Rich Text-Dokument" IDS_DOC_TYPE_UNICODE_TEXT "Text-Dokument" @@ -125,7 +125,7 @@ END /* Tooltips */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_NEW "Neu" IDS_TOOLTIP_OPEN "Öffnen" @@ -140,7 +140,7 @@ BEGIN END /* Hints */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_NEW " Erstellt iin neues Dokument." diff --git a/modules/rosapps/templates/old_wordpad/lang/el-GR.rc b/modules/rosapps/templates/old_wordpad/lang/el-GR.rc index 92563fa6cc818..052185c3f89d1 100644 --- a/modules/rosapps/templates/old_wordpad/lang/el-GR.rc +++ b/modules/rosapps/templates/old_wordpad/lang/el-GR.rc @@ -108,14 +108,14 @@ BEGIN END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_LICENSE "This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.\r\n\r\nThis program 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 General Public License for more details.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." IDS_DEFAULT_NAME "Έγγραφο %1!u!" IDS_READY " Έτοιμο." END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DOC_TYPE_RICH_TEXT "Μορφή εμπλουτισμένου κειμένου" IDS_DOC_TYPE_UNICODE_TEXT "Έγγραφα κειμένου Unicode" @@ -125,7 +125,7 @@ END /* Tooltips */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_NEW "Νέο" IDS_TOOLTIP_OPEN "Άνοιγμα" @@ -140,7 +140,7 @@ BEGIN END /* Hints */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_NEW " Δημιοργεί ένα νέο έγγραφο." diff --git a/modules/rosapps/templates/old_wordpad/lang/en-US.rc b/modules/rosapps/templates/old_wordpad/lang/en-US.rc index 8d64f37f5a8be..a66404c1fdaae 100644 --- a/modules/rosapps/templates/old_wordpad/lang/en-US.rc +++ b/modules/rosapps/templates/old_wordpad/lang/en-US.rc @@ -108,14 +108,14 @@ BEGIN END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_LICENSE "This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.\r\n\r\nThis program 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 General Public License for more details.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." IDS_DEFAULT_NAME "Document %1!u!" IDS_READY " Ready." END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DOC_TYPE_RICH_TEXT "Rich Text Document" IDS_DOC_TYPE_UNICODE_TEXT "Text Document" @@ -125,7 +125,7 @@ END /* Tooltips */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_NEW "New" IDS_TOOLTIP_OPEN "Open" @@ -140,7 +140,7 @@ BEGIN END /* Hints */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_NEW " Creates a new document." diff --git a/modules/rosapps/templates/old_wordpad/lang/fi-FI.rc b/modules/rosapps/templates/old_wordpad/lang/fi-FI.rc index b10b4ca5e14be..2f13db41776f2 100644 --- a/modules/rosapps/templates/old_wordpad/lang/fi-FI.rc +++ b/modules/rosapps/templates/old_wordpad/lang/fi-FI.rc @@ -108,14 +108,14 @@ BEGIN END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_LICENSE "This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.\r\n\r\nThis program 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 General Public License for more details.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." IDS_DEFAULT_NAME "Document %1!u!" IDS_READY " Ready." END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DOC_TYPE_RICH_TEXT "RTF-tiedosto" IDS_DOC_TYPE_UNICODE_TEXT "Tekstitiedosto" @@ -125,7 +125,7 @@ END /* Tooltips */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_NEW "Uusi" IDS_TOOLTIP_OPEN "Avaa" @@ -140,7 +140,7 @@ BEGIN END /* Hints */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_NEW " Luo uuden asiakirjan." diff --git a/modules/rosapps/templates/old_wordpad/lang/fr-FR.rc b/modules/rosapps/templates/old_wordpad/lang/fr-FR.rc index 15c812c9f7a5d..1430267edbe48 100644 --- a/modules/rosapps/templates/old_wordpad/lang/fr-FR.rc +++ b/modules/rosapps/templates/old_wordpad/lang/fr-FR.rc @@ -108,14 +108,14 @@ BEGIN END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_LICENSE "Ce programme est un logiciel libre; vous pouvez le redistribuer et/ou le modifier tout en respectant les termes de la ""GNU General Public License"" publiée par la Free Software Foundation; dans sa version 2 (ou selon votre préférence) toute version suivante.\r\n\r\nCe programme est distribué dans l'espoir qu'il sera utile, cependant SANS GARANTIE D'AUCUNE SORTE; sans même une garantie implicite de COMMERCIABILITE ou DE CONFORMITE A UNE UTILISATION PARTICULIERE. \r\n\r\nVoir la Licence Publique Générale GNU pour plus de détails. Vous devriez avoir reçu un exemplaire de la Licence Publique Générale GNU avec ce programme ; si ce n'est pas le cas, écrivez à la Free Software Foundation Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA." IDS_DEFAULT_NAME "Document %1!u!" IDS_READY " Prêt." END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DOC_TYPE_RICH_TEXT "Document RTF" IDS_DOC_TYPE_UNICODE_TEXT "Document texte" @@ -125,7 +125,7 @@ END /* Tooltips */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_NEW "Nouveau" IDS_TOOLTIP_OPEN "Ouvrir" @@ -140,7 +140,7 @@ BEGIN END /* Hints */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_NEW " Crée un nouveau document." diff --git a/modules/rosapps/templates/old_wordpad/lang/it-IT.rc b/modules/rosapps/templates/old_wordpad/lang/it-IT.rc index 7c1c84fe6668c..4c2e4fe3fd757 100644 --- a/modules/rosapps/templates/old_wordpad/lang/it-IT.rc +++ b/modules/rosapps/templates/old_wordpad/lang/it-IT.rc @@ -108,14 +108,14 @@ BEGIN END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_LICENSE "Questo programma è software libero; puoi distribuirlo e/o modificarlo nei termini di licenza di 'GNU General Public License' come pubblicata dalla 'Free Software Foundation'; entrambe le versioni 2 della Licenza, o (a vostra scelta) qualunque versione successiva.\r\n\r\nQuesto programma è distribuito con l'augurio che sia utile, ma PRIVO DI OGNI GARANZIA; privo anche della garanzia implicita di COMMERCIABILITÀ o UTILIZZABILITÀ PER UNO SPECIFICO USO. Vedi la 'GNU General Public License' per ulteriori dettagli.\r\n\r\nVoi dovreste aver ricevuto una copia della 'GNU General Public License' assieme a questo programma; se non è cosi' scrivete a 'Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA'." IDS_DEFAULT_NAME "Documento %1!u!" IDS_READY " Pronto." END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DOC_TYPE_RICH_TEXT "Documento 'Rich Text'" IDS_DOC_TYPE_UNICODE_TEXT "Testo" @@ -125,7 +125,7 @@ END /* Tooltips */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_NEW "Nuovo" IDS_TOOLTIP_OPEN "Apri" @@ -140,7 +140,7 @@ BEGIN END /* Hints */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_NEW " Crea un nuovo documento." diff --git a/modules/rosapps/templates/old_wordpad/lang/nl-NL.rc b/modules/rosapps/templates/old_wordpad/lang/nl-NL.rc index 0dd541ac1ace2..7bd0f7314ce54 100644 --- a/modules/rosapps/templates/old_wordpad/lang/nl-NL.rc +++ b/modules/rosapps/templates/old_wordpad/lang/nl-NL.rc @@ -108,14 +108,14 @@ BEGIN END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_LICENSE "This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.\r\n\r\nThis program 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 General Public License for more details.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." IDS_DEFAULT_NAME "Document %1!u!" IDS_READY " Ready." END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DOC_TYPE_RICH_TEXT "Rich Text Document" IDS_DOC_TYPE_UNICODE_TEXT "Text Document" @@ -125,7 +125,7 @@ END /* Tooltips */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_NEW "Nieuw" IDS_TOOLTIP_OPEN "Openen" @@ -140,7 +140,7 @@ BEGIN END /* Hints */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_NEW " Een nieuw document maken." diff --git a/modules/rosapps/templates/old_wordpad/lang/no-NO.rc b/modules/rosapps/templates/old_wordpad/lang/no-NO.rc index 4d98815e7061e..ae3fd33438231 100644 --- a/modules/rosapps/templates/old_wordpad/lang/no-NO.rc +++ b/modules/rosapps/templates/old_wordpad/lang/no-NO.rc @@ -108,14 +108,14 @@ BEGIN END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_LICENSE "Dette programmet er gratis programvare; du kan distribuere det og/eller endre det under betingelsene av GNU General Public License som er utgitt av Free Software Foundation; version 2 av lisensen, eller (etter din mening) alle senere versjoner.\r\n\r\nDette programmet er utgitt i håp for at det skal kunne brukes, men DET ER INGEN GARANTIER; uten heller forutsatt garantier av SALGBARHET eller SIKKETHET FOR EN ENKELTHET FORMÅL. Se på GNU General Public Lisensen for mere detaljer.\r\n\r\nDu skal ha motatt en kopi av GNU General Public Lisensen sammen med denne programmet; hvis du ikke har motatt det, skriv til Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." IDS_DEFAULT_NAME "Dokument %1!u!" IDS_READY " Klar." END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DOC_TYPE_RICH_TEXT "Rik tekst dokument" IDS_DOC_TYPE_UNICODE_TEXT "Tekst dokument" @@ -125,7 +125,7 @@ END /* Tooltips */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_NEW "Ny" IDS_TOOLTIP_OPEN "Åpen" @@ -140,7 +140,7 @@ BEGIN END /* Hints */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_NEW " Opprette et nytt dokument." diff --git a/modules/rosapps/templates/old_wordpad/lang/pl-PL.rc b/modules/rosapps/templates/old_wordpad/lang/pl-PL.rc index dbd6432bd759a..5b464c685b59a 100644 --- a/modules/rosapps/templates/old_wordpad/lang/pl-PL.rc +++ b/modules/rosapps/templates/old_wordpad/lang/pl-PL.rc @@ -113,14 +113,14 @@ BEGIN END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_LICENSE "Niniejszy program jest wolnym oprogramowaniem; możesz go rozprowadzać dalej i/lub modyfikować na warunkach Powszechnej Licencji Publicznej GNU, wydanej przez Fundację Wolnego Oprogramowania - według wersji 2 tej Licencji lub (według Twojego wyboru) którejś z późniejszych wersji.\r\n\r\nNiniejszy program rozpowszechniany jest z nadzieją, iż będzie on użyteczny - jednak BEZ JAKIEJKOLWIEK GWARANCJI, nawet domyślnej gwarancji PRZYDATNOŚCI HANDLOWEJ albo PRZYDATNOŚCI DO OKREŚLONYCH ZASTOSOWAŃ. W celu uzyskania bliższych informacji sięgnij do Powszechnej Licencji Publicznej GNU.\r\n\r\nZ pewnością wraz z niniejszym programem otrzymałeś też egzemplarz Powszechnej Licencji Publicznej GNU (GNU General Public License); jeśli nie - napisz do Free Software Foundation, Inc., 59 Temple Place, Fifth Floor, Boston, MA 02110-1301 USA." IDS_DEFAULT_NAME "Dokument %1!u!" IDS_READY " Gotowy." END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DOC_TYPE_RICH_TEXT "Dokument sformatowany" IDS_DOC_TYPE_UNICODE_TEXT "Dokument tekstowy" @@ -130,7 +130,7 @@ END /* Tooltips */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_NEW "Nowy" IDS_TOOLTIP_OPEN "Otwórz" @@ -145,7 +145,7 @@ BEGIN END /* Hints */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_NEW " Tworzy nowy dokument." diff --git a/modules/rosapps/templates/old_wordpad/lang/ru-RU.rc b/modules/rosapps/templates/old_wordpad/lang/ru-RU.rc index 6f44446421b3d..123c88a1c7f65 100644 --- a/modules/rosapps/templates/old_wordpad/lang/ru-RU.rc +++ b/modules/rosapps/templates/old_wordpad/lang/ru-RU.rc @@ -110,14 +110,14 @@ BEGIN END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_LICENSE "Эта программа является свободно распространяемой; Вы можете распространять ее повторно и (или) изменять, соблюдая условия Открытого лицензионного соглашения GNU, опубликованного Фондом свободно распространяемого программного обеспечения; либо редакции 2 Соглашения, либо (на ваше усмотрение) любой редакции, выпущенной позже.\r\n\r\nЭта программа распространяется в надежде на то, что она окажется полезной, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, включая подразумеваемую гарантию КАЧЕСТВА либо ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробности содержатся в Открытом лицензионном соглашении GNU.\r\n\r\nВместе с этой программой должен распространяться экземпляр Открытого лицензионного соглашения GNU, если он отсутствует, сообщите об этом в Фонд свободно распространяемого программного обеспечения (Free Software Foundation, Inc.), 675 Mass Ave, Cambridge, MA 02139, USA." IDS_DEFAULT_NAME "Документ %1!u!" IDS_READY " Готово." END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DOC_TYPE_RICH_TEXT "Документ в формате RTF" IDS_DOC_TYPE_UNICODE_TEXT "Текстовый документ" @@ -127,7 +127,7 @@ END /* Tooltips */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_NEW "Новый" IDS_TOOLTIP_OPEN "Открыть" @@ -142,7 +142,7 @@ BEGIN END /* Подсказки */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_NEW " Создать новый документ." diff --git a/modules/rosapps/templates/old_wordpad/lang/th-TH.rc b/modules/rosapps/templates/old_wordpad/lang/th-TH.rc index 18aab5d444bf9..a819f724ca50c 100644 --- a/modules/rosapps/templates/old_wordpad/lang/th-TH.rc +++ b/modules/rosapps/templates/old_wordpad/lang/th-TH.rc @@ -129,14 +129,14 @@ BEGIN END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_LICENSE "This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.\r\n\r\nThis program 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 General Public License for more details.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." IDS_DEFAULT_NAME "เอกสาร %1!u!" IDS_READY " เสร็จแล้ว." END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DOC_TYPE_RICH_TEXT "Rich Text Document" IDS_DOC_TYPE_UNICODE_TEXT "Text Document" @@ -146,7 +146,7 @@ END /* Tooltips */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_NEW "ใหม่" IDS_TOOLTIP_OPEN "เปิด" @@ -161,7 +161,7 @@ BEGIN END /* Hints */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_NEW " สร้างเอกสารใหม่" diff --git a/modules/rosapps/templates/old_wordpad/lang/uk-UA.rc b/modules/rosapps/templates/old_wordpad/lang/uk-UA.rc index 7d54c371b8bff..c8bb44a619178 100644 --- a/modules/rosapps/templates/old_wordpad/lang/uk-UA.rc +++ b/modules/rosapps/templates/old_wordpad/lang/uk-UA.rc @@ -116,14 +116,14 @@ BEGIN END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_LICENSE "This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.\r\n\r\nThis program 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 General Public License for more details.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." IDS_DEFAULT_NAME "Документ %1!u!" IDS_READY " Виконано." END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DOC_TYPE_RICH_TEXT "Документ у форматі RTF" IDS_DOC_TYPE_UNICODE_TEXT "Текстовий документ" @@ -133,7 +133,7 @@ END /* Tooltips */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_NEW "Створити" IDS_TOOLTIP_OPEN "Відкрити" @@ -148,7 +148,7 @@ BEGIN END /* Hints */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_NEW " Створення нового документа." diff --git a/modules/rosapps/templates/old_wordpad/lang/zh-CN.rc b/modules/rosapps/templates/old_wordpad/lang/zh-CN.rc index a409826b61dba..e007f8eec2694 100644 --- a/modules/rosapps/templates/old_wordpad/lang/zh-CN.rc +++ b/modules/rosapps/templates/old_wordpad/lang/zh-CN.rc @@ -117,14 +117,14 @@ BEGIN END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_LICENSE "本程序为自由软件; 您可以根据自由软件基金会发布的 GNU 通用公共许可证的第 2 版,或(根据您的选择)任何更高版本的条款进行重新分发和修改它。\r\n\r\n本程序的发布是希望它有用,但没有任何担保; 甚至没有适销性或特定用途适用性的暗示保证。 有关详细信息,请参阅 GNU 通用公共许可证。\r\n\r\n您应该已收到 GNU 通用公共许可证的副本以及本程序; 如果没有,请写信给 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA。" IDS_DEFAULT_NAME "文档 %1!u!" IDS_READY " 准备就绪。" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_DOC_TYPE_RICH_TEXT "RTF 文档" IDS_DOC_TYPE_UNICODE_TEXT "文本文档" @@ -134,7 +134,7 @@ END /* Tooltips */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_TOOLTIP_NEW "新建" IDS_TOOLTIP_OPEN "打开" @@ -149,7 +149,7 @@ BEGIN END /* Hints */ -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_HINT_BLANK " " IDS_HINT_NEW " 创建新文档。" diff --git a/modules/rosapps/templates/old_wordpad/rsrc.rc b/modules/rosapps/templates/old_wordpad/rsrc.rc index 95dc22737386c..43fc40b63fa77 100644 --- a/modules/rosapps/templates/old_wordpad/rsrc.rc +++ b/modules/rosapps/templates/old_wordpad/rsrc.rc @@ -9,7 +9,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL #define REACTOS_STR_ORIGINAL_FILENAME "editor.exe" //#include -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_APPNAME "Editor" IDS_VERSION "v0.1" @@ -18,7 +18,7 @@ END IDI_ICON ICON "res/wordpad.ico" /* main toolbar icons */ -IDB_TEXTTOOLBAR BITMAP DISCARDABLE "res/toolbar.bmp" +IDB_TEXTTOOLBAR BITMAP "res/toolbar.bmp" #include diff --git a/modules/rostests/apitests/CMakeLists.txt b/modules/rostests/apitests/CMakeLists.txt index 17a36e94d2314..5b29c633dce1d 100644 --- a/modules/rostests/apitests/CMakeLists.txt +++ b/modules/rostests/apitests/CMakeLists.txt @@ -19,6 +19,7 @@ if (NOT USE_DUMMY_PSEH) add_subdirectory(compiler) endif() add_subdirectory(crt) +add_subdirectory(crypt32) add_subdirectory(dbghelp) add_subdirectory(dciman32) add_subdirectory(dnsapi) @@ -39,6 +40,7 @@ add_subdirectory(netshell) add_subdirectory(ntdll) add_subdirectory(ole32) add_subdirectory(opengl32) +add_subdirectory(partmgr) add_subdirectory(pefile) add_subdirectory(powrprof) add_subdirectory(rtl) diff --git a/modules/rostests/apitests/advapi32/eventlog.c b/modules/rostests/apitests/advapi32/eventlog.c index d7860a9887fe2..da54ea3a31435 100644 --- a/modules/rostests/apitests/advapi32/eventlog.c +++ b/modules/rostests/apitests/advapi32/eventlog.c @@ -25,7 +25,7 @@ START_TEST(eventlog) /* * Tests for the different RPC boundaries on Windows. * See also the "ReportEvent" API on MSDN, section "Return value", at: - * https://msdn.microsoft.com/en-us/library/windows/desktop/aa363679(v=vs.85).aspx + * https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-reporteventa * for more details. */ { 0xF000, { {TRUE, ERROR_SUCCESS}, {TRUE , ERROR_SUCCESS} } }, diff --git a/modules/rostests/apitests/browseui/IACLCustomMRU.cpp b/modules/rostests/apitests/browseui/IACLCustomMRU.cpp index 3627a8f35918f..8d721589ef8d5 100644 --- a/modules/rostests/apitests/browseui/IACLCustomMRU.cpp +++ b/modules/rostests/apitests/browseui/IACLCustomMRU.cpp @@ -39,7 +39,7 @@ static const WCHAR szTestPath[] = L"TESTPATH_BROWSEUI_APITEST"; #undef INTERFACE #define INTERFACE IACLCustomMRU -/* based on https://msdn.microsoft.com/en-gb/library/windows/desktop/bb776380(v=vs.85).aspx */ +/* based on https://learn.microsoft.com/en-us/previous-versions/windows/desktop/legacy/bb776380(v=vs.85) */ DECLARE_INTERFACE_IID_(IACLCustomMRU, IUnknown, "F729FC5E-8769-4F3E-BDB2-D7B50FD2275B") { // *** IUnknown methods *** diff --git a/modules/rostests/apitests/browseui/SHExplorerParseCmdLine.c b/modules/rostests/apitests/browseui/SHExplorerParseCmdLine.c index 652c481fbcaf0..8567193274324 100644 --- a/modules/rostests/apitests/browseui/SHExplorerParseCmdLine.c +++ b/modules/rostests/apitests/browseui/SHExplorerParseCmdLine.c @@ -260,8 +260,28 @@ _Out_opt_ PUINT PWriteEnd) } } +static WCHAR s_szSystem32[MAX_PATH]; +static WCHAR s_szDriveCSelectSystem32[MAX_PATH]; +static WCHAR s_szSlashSelectSystem32[MAX_PATH]; +static WCHAR s_szEqualSlashSelectSystem32[MAX_PATH]; + START_TEST(SHExplorerParseCmdLine) { + // "C:\\Windows\\system32" + GetSystemDirectoryW(s_szSystem32, _countof(s_szSystem32)); + + // "c:\\=/select=c:\\windows\\system32" + StringCchCopyW(s_szDriveCSelectSystem32, _countof(s_szDriveCSelectSystem32), L"c:\\=/select="); + StringCchCatW(s_szDriveCSelectSystem32, _countof(s_szDriveCSelectSystem32), s_szSystem32); + + // "/select=c:\\windows\\system32" + StringCchCopyW(s_szSlashSelectSystem32, _countof(s_szSlashSelectSystem32), L"/select="); + StringCchCatW(s_szSlashSelectSystem32, _countof(s_szSlashSelectSystem32), s_szSystem32); + + // "=/select=c:\\windows\\system32" + StringCchCopyW(s_szEqualSlashSelectSystem32, _countof(s_szEqualSlashSelectSystem32), L"=/select="); + StringCchCatW(s_szEqualSlashSelectSystem32, _countof(s_szEqualSlashSelectSystem32), s_szSystem32); + static struct { INT TestLine; @@ -390,9 +410,9 @@ START_TEST(SHExplorerParseCmdLine) { __LINE__, L"/select=c:\\Program files", TRUE, PIDL_IS_PATH, 0x00000200, NULL, L"C:\\Program Files" }, { __LINE__, L"=,/select,c:\\", TRUE, PIDL_IS_PATH, 0x00000240, NULL, L"C:\\" }, { __LINE__, L"/select,c:\\,=", TRUE, CSIDL_DRIVES, 0x00000240 }, - { __LINE__, L"c:\\=/select=c:\\windows\\system32", TRUE, PIDL_IS_PATH, 0x00000240, NULL, L"C:\\WINDOWS\\system32" }, - { __LINE__, L"/select=c:\\windows\\system32", TRUE, PIDL_IS_PATH, 0x00000200, NULL, L"C:\\WINDOWS\\system32" }, - { __LINE__, L"=/select=c:\\windows\\system32", TRUE, PIDL_IS_PATH, 0x00000240, NULL, L"C:\\WINDOWS\\system32" }, + { __LINE__, s_szDriveCSelectSystem32, TRUE, PIDL_IS_PATH, 0x00000240, NULL, s_szSystem32 }, + { __LINE__, s_szSlashSelectSystem32, TRUE, PIDL_IS_PATH, 0x00000200, NULL, s_szSystem32 }, + { __LINE__, s_szEqualSlashSelectSystem32, TRUE, PIDL_IS_PATH, 0x00000240, NULL, s_szSystem32 }, { __LINE__, L"/e,=", TRUE, CSIDL_DRIVES, 0x00000208 }, { __LINE__, L"/e=", TRUE, CSIDL_DRIVES, 0x00000200 }, { __LINE__, L"/e=\"", TRUE, CSIDL_DRIVES, 0x00000200 }, diff --git a/modules/rostests/apitests/comctl32/CMakeLists.txt b/modules/rostests/apitests/comctl32/CMakeLists.txt index d3d11b9be7718..2198b4d9fe7a3 100644 --- a/modules/rostests/apitests/comctl32/CMakeLists.txt +++ b/modules/rostests/apitests/comctl32/CMakeLists.txt @@ -1,5 +1,5 @@ -add_executable(comctl32_apitest button.c propsheet.c toolbar.c testlist.c ../include/msgtrace.c comctl32_apitest.rc) +add_executable(comctl32_apitest button.c imagelist.c propsheet.c toolbar.c testlist.c ../include/msgtrace.c comctl32_apitest.rc) target_link_libraries(comctl32_apitest wine) set_module_type(comctl32_apitest win32cui) add_importlibs(comctl32_apitest uxtheme comctl32 user32 gdi32 msvcrt kernel32 ntdll) diff --git a/modules/rostests/apitests/comctl32/imagelist.c b/modules/rostests/apitests/comctl32/imagelist.c new file mode 100644 index 0000000000000..967ce2755e83e --- /dev/null +++ b/modules/rostests/apitests/comctl32/imagelist.c @@ -0,0 +1,152 @@ +/* + * PROJECT: ReactOS API Tests + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Test for imagelist + * COPYRIGHT: Copyright 2024 Whindmar Saksit + */ + +#include "wine/test.h" +#include +#include +#include +#include + +#define WinVerMajor() LOBYTE(GetVersion()) + +#define ILC_COLORMASK 0xfe +#define IL_IMGSIZE 16 + +static BOOL IL_IsValid(HIMAGELIST himl) +{ + int w = -42, h; + if (!himl || IsBadReadPtr(himl, sizeof(void*))) + return FALSE; + return ImageList_GetIconSize(himl, &w, &h) && w != -42; +} + +static HRESULT IL_Destroy(HIMAGELIST himl) +{ + if (himl && !IL_IsValid(himl)) + return E_INVALIDARG; + return ImageList_Destroy(himl) ? S_OK : S_FALSE; +} + +static inline HIMAGELIST IL_Create(UINT flags) +{ + return ImageList_Create(IL_IMGSIZE, IL_IMGSIZE, flags, 1, 0); +} + +static UINT IL_CalculateOtherBpp(UINT ilc) +{ + UINT bpp = (ilc & ILC_COLORMASK) == ILC_COLOR32 ? ILC_COLOR16 : ILC_COLOR32; + return (ilc & ~ILC_COLORMASK) | bpp; +} + +static BOOL IL_AddImagesForTest(HIMAGELIST himl) +{ + int idx = -1; + HINSTANCE hInst = LoadLibraryW(L"USER32"); + if (!hInst) + return FALSE; + HICON hIco = (HICON)LoadImage(hInst, MAKEINTRESOURCE(100), /* Windows */ + IMAGE_ICON, IL_IMGSIZE, IL_IMGSIZE, 0); + if (!hIco) + hIco = (HICON)LoadImage(hInst, MAKEINTRESOURCE(32512), /* ReactOS */ + IMAGE_ICON, IL_IMGSIZE, IL_IMGSIZE, 0); + + if (hIco) + { + idx = ImageList_AddIcon(himl, hIco); + DestroyIcon(hIco); + } + FreeLibrary(hInst); + return idx != -1; +} + +static void Test_SystemIL(void) +{ + const UINT flags = ILC_COLOR16 | ILC_MASK; + HIMAGELIST himl; + + himl = IL_Create(flags); + ok(IL_Destroy(himl) == S_OK && !IL_IsValid(himl), "Can destroy normal\n"); + + /* You can (sometimes) destroy a system imagelist! + * On Win9x it destroys it for all processes according to + * https://sporks.space/2021/09/18/notes-on-the-system-image-list/ and + * https://www.catch22.net/tuts/win32/system-image-list/ + */ + himl = IL_Create(flags | ILC_SYSTEM); + if (WinVerMajor() >= 6) + ok(IL_Destroy(himl) == S_FALSE && IL_IsValid(himl), "Can't destroy system\n"); + else + ok(IL_Destroy(himl) == S_OK && !IL_IsValid(himl), "Can destroy system\n"); +} + +static void Test_Flags(void) +{ + const UINT flags = ILC_COLOR16 | ILC_MASK; + UINT flagsIn, flagsOut; + HIMAGELIST himl; + + himl = IL_Create(flagsIn = flags); + flagsOut = ImageList_GetFlags(himl); + if (himl ? TRUE : (skip("Could not initialize\n"), FALSE)) + { + ok((flagsOut & ILC_COLORMASK) == (flagsIn & ILC_COLORMASK), "ILC_COLOR\n"); + ok(!(flagsOut & ILC_SYSTEM), "!ILC_SYSTEM\n"); + + ok(IL_AddImagesForTest(himl), "Initialize\n"); + flagsIn = IL_CalculateOtherBpp(flagsIn); + ok(ImageList_SetFlags(himl, flagsIn), "Can change BPP\n"); + ok(ImageList_GetImageCount(himl) == 0, "SetFlags deletes all images\n"); + + ok(IL_AddImagesForTest(himl), "Initialize\n"); + ok(ImageList_SetFlags(himl, ImageList_GetFlags(himl)), "Can set same flags\n"); + if (WinVerMajor() >= 6) + { + ok(ImageList_GetImageCount(himl) != 0, "SetFlags does not delete with same flags\n"); + ok(ImageList_SetFlags(himl, flagsIn ^ ILC_SYSTEM), "Can change ILC_SYSTEM\n"); + } + else + { + ok(ImageList_GetImageCount(himl) == 0, "SetFlags deletes all images even with same flags\n"); + ok(!ImageList_SetFlags(himl, flagsIn ^ ILC_SYSTEM), "Can't change ILC_SYSTEM\n"); + } + + IL_Destroy(himl); + } + + himl = IL_Create(flagsIn = flags | ILC_SYSTEM); + flagsOut = ImageList_GetFlags(himl); + if (himl ? TRUE : (skip("Could not initialize\n"), FALSE)) + { + ok((flagsOut & ILC_SYSTEM), "ILC_SYSTEM\n"); /* Flag is not hidden */ + + ok(IL_AddImagesForTest(himl), "Initialize\n"); + + flagsIn = IL_CalculateOtherBpp(flagsIn); + ok(ImageList_SetFlags(himl, flagsIn), "Can change BPP\n"); + ok(ImageList_GetImageCount(himl) == 0, "SetFlags deletes all images\n"); + + ok(IL_AddImagesForTest(himl), "Initialize\n"); + ok(ImageList_SetFlags(himl, ImageList_GetFlags(himl)), "Can set same flags\n"); + if (WinVerMajor() >= 6) + { + ok(ImageList_SetFlags(himl, flagsIn ^ ILC_SYSTEM), "Can change ILC_SYSTEM\n"); + } + else + { + ok(!ImageList_SetFlags(himl, flagsIn ^ ILC_SYSTEM), "Can't change ILC_SYSTEM\n"); + } + + IL_Destroy(himl); + } +} + +START_TEST(ImageListApi) +{ + InitCommonControls(); + Test_SystemIL(); + Test_Flags(); +} diff --git a/modules/rostests/apitests/comctl32/testlist.c b/modules/rostests/apitests/comctl32/testlist.c index da44fe7e3fba8..f914fc5159325 100644 --- a/modules/rostests/apitests/comctl32/testlist.c +++ b/modules/rostests/apitests/comctl32/testlist.c @@ -2,12 +2,14 @@ #include extern void func_button(void); +extern void func_ImageListApi(void); extern void func_propsheet(void); extern void func_toolbar(void); const struct test winetest_testlist[] = { { "buttonv6", func_button }, + { "ImageListApi", func_ImageListApi }, { "propsheetv6", func_propsheet }, { "toolbarv6", func_toolbar }, { 0, 0 } diff --git a/modules/rostests/apitests/crypt32/CMakeLists.txt b/modules/rostests/apitests/crypt32/CMakeLists.txt new file mode 100644 index 0000000000000..a34bee9de0c40 --- /dev/null +++ b/modules/rostests/apitests/crypt32/CMakeLists.txt @@ -0,0 +1,10 @@ + +list(APPEND SOURCE + CertEnumSystemStoreLocation.c + testlist.c) + +add_executable(crypt32_apitest ${SOURCE}) +target_link_libraries(crypt32_apitest wine ${PSEH_LIB}) +set_module_type(crypt32_apitest win32cui) +add_importlibs(crypt32_apitest crypt32 msvcrt kernel32 ntdll) +add_rostests_file(TARGET crypt32_apitest) diff --git a/modules/rostests/apitests/crypt32/CertEnumSystemStoreLocation.c b/modules/rostests/apitests/crypt32/CertEnumSystemStoreLocation.c new file mode 100644 index 0000000000000..9dbd781b9df35 --- /dev/null +++ b/modules/rostests/apitests/crypt32/CertEnumSystemStoreLocation.c @@ -0,0 +1,74 @@ +/* + * PROJECT: ReactOS API Tests + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: Test for CertEnumSystemStoreLocation + * COPYRIGHT: Copyright 2025 Ratin Gao + */ + +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + +#include +#include +#include + +#define ARG_CONTEXT ((PVOID)(ULONG_PTR)0x12345678) + +typedef struct _CERT_SYSTEM_STORE_LOCATION +{ + DWORD dwFlags; + PCWSTR pwszStoreLocation; +} CERT_SYSTEM_STORE_LOCATION, * PCERT_SYSTEM_STORE_LOCATION; + +static const CERT_SYSTEM_STORE_LOCATION g_SystemStoreLocations[] = { + { CERT_SYSTEM_STORE_CURRENT_USER, L"CurrentUser" }, + { CERT_SYSTEM_STORE_LOCAL_MACHINE, L"LocalMachine" }, + { CERT_SYSTEM_STORE_CURRENT_SERVICE, L"CurrentService" }, + { CERT_SYSTEM_STORE_SERVICES, L"Services" }, + { CERT_SYSTEM_STORE_USERS, L"Users" }, + { CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY, L"CurrentUserGroupPolicy" }, + { CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY, L"LocalMachineGroupPolicy" }, + { CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE, L"LocalMachineEnterprise" }, +}; + +static ULONG g_Index = 0; + +static +BOOL +WINAPI +CertEnumSystemStoreLocationCallback( + _In_ LPCWSTR pwszStoreLocation, + _In_ DWORD dwFlags, + _Reserved_ void* pvReserved, + _Inout_opt_ void* pvArg) +{ + ok(pvReserved == NULL, "pvReserved is not NULL\n"); + ok(pvArg == ARG_CONTEXT, "pvArg incorrect\n"); + + if (g_Index < ARRAYSIZE(g_SystemStoreLocations)) + { + ok(dwFlags == g_SystemStoreLocations[g_Index].dwFlags, "#%lu dwFlags incorrect\n", g_Index); + ok(wcscmp(pwszStoreLocation, g_SystemStoreLocations[g_Index].pwszStoreLocation) == 0, + "#%lu pwszStoreLocation incorrect\n", + g_Index); + } + + g_Index++; + return TRUE; +} + +START_TEST(CertEnumSystemStoreLocation) +{ + BOOL bRet; + + /* dwFlags should be 0, otherwise fail with E_INVALIDARG */ + bRet = CertEnumSystemStoreLocation(1, ARG_CONTEXT, CertEnumSystemStoreLocationCallback); + ok(bRet == FALSE && GetLastError() == E_INVALIDARG, + "CertEnumSystemStoreLocation should failed with E_INVALIDARG when dwFlags is not 0\n"); + + /* Start enumeration */ + bRet = CertEnumSystemStoreLocation(0, ARG_CONTEXT, CertEnumSystemStoreLocationCallback); + ok(bRet != FALSE, "CertEnumSystemStoreLocation failed with 0x%08lX\n", GetLastError()); + ok(g_Index >= ARRAYSIZE(g_SystemStoreLocations), "Count of enumerated item incorrect\n"); +} diff --git a/modules/rostests/apitests/crypt32/testlist.c b/modules/rostests/apitests/crypt32/testlist.c new file mode 100644 index 0000000000000..45a8a29d11868 --- /dev/null +++ b/modules/rostests/apitests/crypt32/testlist.c @@ -0,0 +1,13 @@ +#define __ROS_LONG64__ + +#define STANDALONE +#include + +extern void func_CertEnumSystemStoreLocation(void); + +const struct test winetest_testlist[] = +{ + { "CertEnumSystemStoreLocation", func_CertEnumSystemStoreLocation }, + + { 0, 0 } +}; diff --git a/modules/rostests/apitests/gdi32/CreateDIBPatternBrush.c b/modules/rostests/apitests/gdi32/CreateDIBPatternBrush.c index 6ac5da0b3d332..bc58c3a3e7a77 100644 --- a/modules/rostests/apitests/gdi32/CreateDIBPatternBrush.c +++ b/modules/rostests/apitests/gdi32/CreateDIBPatternBrush.c @@ -9,7 +9,7 @@ #include "init.h" -/* New color use parameter. See support.microsoft.com/kb/kbview/108497 */ +/* New color use parameter. See https://www.betaarchive.com/wiki/index.php?title=Microsoft_KB_Archive/108497 */ #define DIB_PAL_INDICES 2 void Test_CreateDIBPatternBrush() diff --git a/modules/rostests/apitests/imm32/resource.rc b/modules/rostests/apitests/imm32/resource.rc index c01bc75b2da58..a74712ad9dd27 100644 --- a/modules/rostests/apitests/imm32/resource.rc +++ b/modules/rostests/apitests/imm32/resource.rc @@ -1,6 +1,8 @@ #include #include -#pragma code_page(65001) /* UTF-8 */ + +/* UTF-8 */ +#pragma code_page(65001) LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT diff --git a/modules/rostests/apitests/include/apitest.h b/modules/rostests/apitests/include/apitest.h index 9a627e49560e5..18cd1ac0da7b9 100644 --- a/modules/rostests/apitests/include/apitest.h +++ b/modules/rostests/apitests/include/apitest.h @@ -12,7 +12,6 @@ #define InvalidPointer ((PVOID)0x5555555555555555ULL) // #define InvalidPointer ((PVOID)0x0123456789ABCDEFULL) -#ifdef __USE_PSEH2__ #include #define StartSeh() \ @@ -32,24 +31,6 @@ "Exception 0x%08lx, expected 0x%08lx\n", \ ExceptionStatus, (ExpectedStatus)); \ } -#else -#define StartSeh() \ -{ \ - NTSTATUS ExceptionStatus = STATUS_SUCCESS; \ - __try \ - { - -#define EndSeh(ExpectedStatus) \ - } \ - __except(EXCEPTION_EXECUTE_HANDLER) \ - { \ - ExceptionStatus = GetExceptionCode(); \ - } \ - ok(ExceptionStatus == (ExpectedStatus), \ - "Exception 0x%08lx, expected 0x%08lx\n", \ - ExceptionStatus, (ExpectedStatus)); \ -} -#endif #define ok_hr(status, expected) ok_hex(status, expected) #define ok_hr_(file, line, status, expected) ok_hex_(file, line, status, expected) diff --git a/modules/rostests/apitests/mountmgr/CMakeLists.txt b/modules/rostests/apitests/mountmgr/CMakeLists.txt index 4c499c26a9820..c53e4d79aff40 100644 --- a/modules/rostests/apitests/mountmgr/CMakeLists.txt +++ b/modules/rostests/apitests/mountmgr/CMakeLists.txt @@ -1,6 +1,8 @@ list(APPEND SOURCE - QueryPoints.c) + QueryDosVolumePaths.c + QueryPoints.c + utils.c) list(APPEND PCH_SKIP_SOURCE testlist.c) @@ -9,9 +11,8 @@ add_executable(mountmgr_apitest ${SOURCE} ${PCH_SKIP_SOURCE}) +add_pch(mountmgr_apitest precomp.h "${PCH_SKIP_SOURCE}") target_link_libraries(mountmgr_apitest wine ${PSEH_LIB}) set_module_type(mountmgr_apitest win32cui) add_importlibs(mountmgr_apitest msvcrt kernel32 ntdll) -# TODO: Enable this when we get more than one source file to justify its use -#add_pch(mountmgr_apitest precomp.h "${PCH_SKIP_SOURCE}") add_rostests_file(TARGET mountmgr_apitest) diff --git a/modules/rostests/apitests/mountmgr/QueryDosVolumePaths.c b/modules/rostests/apitests/mountmgr/QueryDosVolumePaths.c new file mode 100644 index 0000000000000..e7103b121e7c9 --- /dev/null +++ b/modules/rostests/apitests/mountmgr/QueryDosVolumePaths.c @@ -0,0 +1,635 @@ +/* + * PROJECT: ReactOS API Tests + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Test for IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH(S) + * COPYRIGHT: Copyright 2025 Hermès Bélusca-Maïto + */ + +#include "precomp.h" + + +/** + * @brief + * Invokes either IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH or + * IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATHS for testing, given + * the volume device name, and returns an allocated volume + * paths buffer. This buffer must be freed by the caller via + * RtlFreeHeap(RtlGetProcessHeap(), ...) . + * + * These IOCTLs return both the drive letter (if any) and the + * volume GUID symlink path, as well as any other file-system + * mount reparse points linking to the volume. + **/ +static VOID +Call_QueryDosVolume_Path_Paths( + _In_ HANDLE MountMgrHandle, + _In_ PCWSTR NtVolumeName, + _In_ ULONG IoctlPathOrPaths, + _Out_ PMOUNTMGR_VOLUME_PATHS* pVolumePathPtr) +{ + NTSTATUS Status; + ULONG Length; + IO_STATUS_BLOCK IoStatusBlock; + UNICODE_STRING VolumeName; + MOUNTMGR_VOLUME_PATHS VolumePath; + PMOUNTMGR_VOLUME_PATHS VolumePathPtr; + ULONG DeviceNameLength; + /* + * This variable is used to query the device name. + * It's based on MOUNTMGR_TARGET_NAME (mountmgr.h). + * Doing it this way prevents memory allocation. + * The device name won't be longer. + */ + struct + { + USHORT NameLength; + WCHAR DeviceName[256]; + } DeviceName; + + + *pVolumePathPtr = NULL; + + /* First, build the corresponding device name */ + RtlInitUnicodeString(&VolumeName, NtVolumeName); + DeviceName.NameLength = VolumeName.Length; + RtlCopyMemory(&DeviceName.DeviceName, VolumeName.Buffer, VolumeName.Length); + DeviceNameLength = FIELD_OFFSET(MOUNTMGR_TARGET_NAME, DeviceName) + DeviceName.NameLength; + + /* Now, query the MountMgr for the DOS path(s) */ + Status = NtDeviceIoControlFile(MountMgrHandle, + NULL, NULL, NULL, + &IoStatusBlock, + IoctlPathOrPaths, + &DeviceName, DeviceNameLength, + &VolumePath, sizeof(VolumePath)); + + /* Check for unsupported device */ + if (Status == STATUS_NO_MEDIA_IN_DEVICE || Status == STATUS_INVALID_DEVICE_REQUEST) + { + skip("Device '%S': Doesn't support MountMgr queries, Status 0x%08lx\n", + NtVolumeName, Status); + return; + } + + /* The only tolerated failure here is buffer too small, which is expected */ + ok(NT_SUCCESS(Status) || (Status == STATUS_BUFFER_OVERFLOW), + "Device '%S': IOCTL 0x%lx failed unexpectedly, Status 0x%08lx\n", + NtVolumeName, IoctlPathOrPaths, Status); + if (!NT_SUCCESS(Status) && (Status != STATUS_BUFFER_OVERFLOW)) + { + skip("Device '%S': Wrong Status\n", NtVolumeName); + return; + } + + /* Compute the needed size to store the DOS path(s). + * Even if MOUNTMGR_VOLUME_PATHS allows bigger name lengths + * than MAXUSHORT, we can't use them, because we have to return + * this in an UNICODE_STRING that stores length in a USHORT. */ + Length = sizeof(VolumePath) + VolumePath.MultiSzLength; + ok(Length <= MAXUSHORT, + "Device '%S': DOS volume path too large: %lu\n", + NtVolumeName, Length); + if (Length > MAXUSHORT) + { + skip("Device '%S': Wrong Length\n", NtVolumeName); + return; + } + + /* Allocate the buffer and fill it with test pattern */ + VolumePathPtr = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length); + if (!VolumePathPtr) + { + skip("Device '%S': Failed to allocate buffer with size %lu)\n", + NtVolumeName, Length); + return; + } + RtlFillMemory(VolumePathPtr, Length, 0xCC); + + /* Re-query the DOS path(s) with the proper size */ + Status = NtDeviceIoControlFile(MountMgrHandle, + NULL, NULL, NULL, + &IoStatusBlock, + IoctlPathOrPaths, + &DeviceName, DeviceNameLength, + VolumePathPtr, Length); + ok(NT_SUCCESS(Status), + "Device '%S': IOCTL 0x%lx failed unexpectedly, Status 0x%08lx\n", + NtVolumeName, IoctlPathOrPaths, Status); + + if (winetest_debug > 1) + { + trace("Buffer:\n"); + DumpBuffer(VolumePathPtr, Length); + printf("\n"); + } + + /* Return the buffer */ + *pVolumePathPtr = VolumePathPtr; +} + +/** + * @brief + * Invokes IOCTL_MOUNTMGR_QUERY_POINTS for testing, given + * the volume device name, and returns an allocated mount + * points buffer. This buffer must be freed by the caller + * via RtlFreeHeap(RtlGetProcessHeap(), ...) . + * + * This IOCTL only returns both the drive letter (if any) + * and the volume GUID symlink path, but does NOT return + * file-system mount reparse points. + **/ +static VOID +Call_QueryPoints( + _In_ HANDLE MountMgrHandle, + _In_ PCWSTR NtVolumeName, + _Out_ PMOUNTMGR_MOUNT_POINTS* pMountPointsPtr) +{ + NTSTATUS Status; + ULONG Length; + IO_STATUS_BLOCK IoStatusBlock; + UNICODE_STRING VolumeName; + MOUNTMGR_MOUNT_POINTS MountPoints; + PMOUNTMGR_MOUNT_POINTS MountPointsPtr; + /* + * This variable is used to query the device name. + * It's based on MOUNTMGR_MOUNT_POINT (mountmgr.h). + * Doing it this way prevents memory allocation. + * The device name won't be longer. + */ + struct + { + MOUNTMGR_MOUNT_POINT; + WCHAR DeviceName[256]; + } DeviceName; + + + *pMountPointsPtr = NULL; + + /* First, build the corresponding device name */ + RtlInitUnicodeString(&VolumeName, NtVolumeName); + DeviceName.SymbolicLinkNameOffset = DeviceName.UniqueIdOffset = 0; + DeviceName.SymbolicLinkNameLength = DeviceName.UniqueIdLength = 0; + DeviceName.DeviceNameOffset = ((ULONG_PTR)&DeviceName.DeviceName - (ULONG_PTR)&DeviceName); + DeviceName.DeviceNameLength = VolumeName.Length; + RtlCopyMemory(&DeviceName.DeviceName, VolumeName.Buffer, VolumeName.Length); + + /* Now, query the MountMgr for the mount points */ + Status = NtDeviceIoControlFile(MountMgrHandle, + NULL, NULL, NULL, + &IoStatusBlock, + IOCTL_MOUNTMGR_QUERY_POINTS, + &DeviceName, sizeof(DeviceName), + &MountPoints, sizeof(MountPoints)); + + /* Check for unsupported device */ + if (Status == STATUS_NO_MEDIA_IN_DEVICE || Status == STATUS_INVALID_DEVICE_REQUEST) + { + skip("Device '%S': Doesn't support MountMgr queries, Status 0x%08lx\n", + NtVolumeName, Status); + return; + } + + /* The only tolerated failure here is buffer too small, which is expected */ + ok(NT_SUCCESS(Status) || (Status == STATUS_BUFFER_OVERFLOW), + "Device '%S': IOCTL 0x%lx failed unexpectedly, Status 0x%08lx\n", + NtVolumeName, IOCTL_MOUNTMGR_QUERY_POINTS, Status); + if (!NT_SUCCESS(Status) && (Status != STATUS_BUFFER_OVERFLOW)) + { + skip("Device '%S': Wrong Status\n", NtVolumeName); + return; + } + + /* Compute the needed size to retrieve the mount points */ + Length = MountPoints.Size; + + /* Allocate the buffer and fill it with test pattern */ + MountPointsPtr = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length); + if (!MountPointsPtr) + { + skip("Device '%S': Failed to allocate buffer with size %lu)\n", + NtVolumeName, Length); + return; + } + RtlFillMemory(MountPointsPtr, Length, 0xCC); + + /* Re-query the mount points with the proper size */ + Status = NtDeviceIoControlFile(MountMgrHandle, + NULL, NULL, NULL, + &IoStatusBlock, + IOCTL_MOUNTMGR_QUERY_POINTS, + &DeviceName, sizeof(DeviceName), + MountPointsPtr, Length); + ok(NT_SUCCESS(Status), + "Device '%S': IOCTL 0x%lx failed unexpectedly, Status 0x%08lx\n", + NtVolumeName, IOCTL_MOUNTMGR_QUERY_POINTS, Status); + + if (winetest_debug > 1) + { + trace("IOCTL_MOUNTMGR_QUERY_POINTS returned:\n" + " Size: %lu\n" + " NumberOfMountPoints: %lu\n", + MountPointsPtr->Size, + MountPointsPtr->NumberOfMountPoints); + + trace("Buffer:\n"); + DumpBuffer(MountPointsPtr, Length); + printf("\n"); + } + + /* Return the buffer */ + *pMountPointsPtr = MountPointsPtr; +} + + +#define IS_DRIVE_LETTER_PFX(s) \ + ((s)->Length >= 2*sizeof(WCHAR) && (s)->Buffer[0] >= 'A' && \ + (s)->Buffer[0] <= 'Z' && (s)->Buffer[1] == ':') + +/* Differs from MOUNTMGR_IS_DRIVE_LETTER(): no '\DosDevices\' accounted for */ +#define IS_DRIVE_LETTER(s) \ + (IS_DRIVE_LETTER_PFX(s) && (s)->Length == 2*sizeof(WCHAR)) + + +/** + * @brief Tests the output of IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH. + **/ +static VOID +Test_QueryDosVolumePath( + _In_ PCWSTR NtVolumeName, + _In_ PMOUNTMGR_VOLUME_PATHS VolumePath) +{ + UNICODE_STRING DosPath; + + UNREFERENCED_PARAMETER(NtVolumeName); + + /* The VolumePath should contain one NUL-terminated string (always there?), + * plus one final NUL-terminator */ + ok(VolumePath->MultiSzLength >= 2 * sizeof(UNICODE_NULL), + "DOS volume path string too short (length: %lu)\n", + VolumePath->MultiSzLength / sizeof(WCHAR)); + ok(VolumePath->MultiSz[VolumePath->MultiSzLength / sizeof(WCHAR) - 2] == UNICODE_NULL, + "Missing NUL-terminator (2)\n"); + ok(VolumePath->MultiSz[VolumePath->MultiSzLength / sizeof(WCHAR) - 1] == UNICODE_NULL, + "Missing NUL-terminator (1)\n"); + + /* Build the result string */ + // RtlInitUnicodeString(&DosPath, VolumePath->MultiSz); + DosPath.Length = (USHORT)VolumePath->MultiSzLength - 2 * sizeof(UNICODE_NULL); + DosPath.MaximumLength = DosPath.Length + sizeof(UNICODE_NULL); + DosPath.Buffer = VolumePath->MultiSz; + + /* The returned DOS path is either a drive letter (*WITHOUT* any + * '\DosDevices\' prefix present) or a Win32 file-system reparse point + * path, or a volume GUID name in Win32 format, i.e. prefixed by '\\?\' */ + ok(IS_DRIVE_LETTER_PFX(&DosPath) || MOUNTMGR_IS_DOS_VOLUME_NAME(&DosPath), + "Invalid DOS volume path returned '%s'\n", wine_dbgstr_us(&DosPath)); +} + +/** + * @brief Tests the output of IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATHS. + **/ +static VOID +Test_QueryDosVolumePaths( + _In_ PCWSTR NtVolumeName, + _In_ PMOUNTMGR_VOLUME_PATHS VolumePaths, + _In_opt_ PMOUNTMGR_VOLUME_PATHS VolumePath) +{ + UNICODE_STRING DosPath; + PCWSTR pMountPoint; + + /* The VolumePaths should contain zero or more NUL-terminated strings, + * plus one final NUL-terminator */ + + ok(VolumePaths->MultiSzLength >= sizeof(UNICODE_NULL), + "DOS volume path string too short (length: %lu)\n", + VolumePaths->MultiSzLength / sizeof(WCHAR)); + + /* Check for correct double-NUL-termination, if there is at least one string */ + if (VolumePaths->MultiSzLength >= 2 * sizeof(UNICODE_NULL), + VolumePaths->MultiSz[0] != UNICODE_NULL) + { + ok(VolumePaths->MultiSz[VolumePaths->MultiSzLength / sizeof(WCHAR) - 2] == UNICODE_NULL, + "Missing NUL-terminator (2)\n"); + } + /* Check for the final NUL-terminator */ + ok(VolumePaths->MultiSz[VolumePaths->MultiSzLength / sizeof(WCHAR) - 1] == UNICODE_NULL, + "Missing NUL-terminator (1)\n"); + + if (winetest_debug > 1) + { + trace("\n%S =>\n", NtVolumeName); + for (pMountPoint = VolumePaths->MultiSz; *pMountPoint; + pMountPoint += wcslen(pMountPoint) + 1) + { + printf(" '%S'\n", pMountPoint); + } + printf("\n"); + } + + for (pMountPoint = VolumePaths->MultiSz; *pMountPoint; + pMountPoint += wcslen(pMountPoint) + 1) + { + /* The returned DOS path is either a drive letter (*WITHOUT* any + * '\DosDevices\' prefix present) or a Win32 file-system reparse point + * path, or a volume GUID name in Win32 format, i.e. prefixed by '\\?\' */ + RtlInitUnicodeString(&DosPath, pMountPoint); + ok(IS_DRIVE_LETTER_PFX(&DosPath) || MOUNTMGR_IS_DOS_VOLUME_NAME(&DosPath), + "Invalid DOS volume path returned '%s'\n", wine_dbgstr_us(&DosPath)); + } + + /* + * If provided, verify that the single VolumePath is found at the + * first position in the volume paths list, *IF* this is a DOS path; + * otherwise if it's a Volume{GUID} path, this means there is no + * DOS path associated, and none is listed in the volume paths list. + */ + if (VolumePath) + { + RtlInitUnicodeString(&DosPath, VolumePath->MultiSz); + if (IS_DRIVE_LETTER_PFX(&DosPath)) + { + /* + * The single path is a DOS path (single drive letter or Win32 + * file-system reparse point path). It has to be listed first + * in the volume paths list. + */ + UNICODE_STRING FirstPath; + BOOLEAN AreEqual; + + ok(VolumePaths->MultiSzLength >= 2 * sizeof(UNICODE_NULL), + "DOS VolumePaths list isn't long enough\n"); + ok(*VolumePaths->MultiSz != UNICODE_NULL, + "Empty DOS VolumePaths list\n"); + + RtlInitUnicodeString(&FirstPath, VolumePaths->MultiSz); + AreEqual = RtlEqualUnicodeString(&DosPath, &FirstPath, FALSE); + ok(AreEqual, "DOS paths '%s' and '%s' are not the same!\n", + wine_dbgstr_us(&DosPath), wine_dbgstr_us(&FirstPath)); + } + else if (MOUNTMGR_IS_DOS_VOLUME_NAME(&DosPath)) + { + /* + * The single "DOS" path is actually a volume name. This means + * that it wasn't really mounted, and the volume paths list must + * be empty. It contains only the last NUL-terminator. + */ + ok(VolumePaths->MultiSzLength == sizeof(UNICODE_NULL), + "DOS VolumePaths list isn't 1 WCHAR long\n"); + ok(*VolumePaths->MultiSz == UNICODE_NULL, + "Non-empty DOS VolumePaths list\n"); + } + else + { + /* The volume path is invalid (shouldn't happen) */ + ok(FALSE, "Invalid DOS volume path returned '%s'\n", wine_dbgstr_us(&DosPath)); + } + } +} + +static BOOLEAN +doesPathExistInMountPoints( + _In_ PMOUNTMGR_MOUNT_POINTS MountPoints, + _In_ PUNICODE_STRING DosPath) +{ + UNICODE_STRING DosDevicesPrefix = RTL_CONSTANT_STRING(L"\\DosDevices\\"); + ULONG i; + BOOLEAN IsDosVolName; + BOOLEAN Found = FALSE; + + IsDosVolName = MOUNTMGR_IS_DOS_VOLUME_NAME(DosPath); + /* Temporarily patch \\?\ to \??\ in DosPath for comparison */ + if (IsDosVolName) + DosPath->Buffer[1] = L'?'; + + for (i = 0; i < MountPoints->NumberOfMountPoints; ++i) + { + UNICODE_STRING SymLink; + + SymLink.Length = SymLink.MaximumLength = MountPoints->MountPoints[i].SymbolicLinkNameLength; + SymLink.Buffer = (PWCHAR)((ULONG_PTR)MountPoints + MountPoints->MountPoints[i].SymbolicLinkNameOffset); + + if (IS_DRIVE_LETTER(DosPath)) + { + if (RtlPrefixUnicodeString(&DosDevicesPrefix, &SymLink, FALSE)) + { + /* Advance past the prefix */ + SymLink.Length -= DosDevicesPrefix.Length; + SymLink.MaximumLength -= DosDevicesPrefix.Length; + SymLink.Buffer += DosDevicesPrefix.Length / sizeof(WCHAR); + + Found = RtlEqualUnicodeString(DosPath, &SymLink, FALSE); + } + } + else if (/*MOUNTMGR_IS_DOS_VOLUME_NAME(DosPath) ||*/ // See above + MOUNTMGR_IS_NT_VOLUME_NAME(DosPath)) + { + Found = RtlEqualUnicodeString(DosPath, &SymLink, FALSE); + } + else + { + /* Just test for simple string comparison, the path should not be found */ + Found = RtlEqualUnicodeString(DosPath, &SymLink, FALSE); + } + + /* Stop searching if we've found something */ + if (Found) + break; + } + + /* Revert \??\ back to \\?\ */ + if (IsDosVolName) + DosPath->Buffer[1] = L'\\'; + + return Found; +} + +/** + * @brief Tests the output of IOCTL_MOUNTMGR_QUERY_POINTS. + **/ +static VOID +Test_QueryPoints( + _In_ PCWSTR NtVolumeName, + _In_ PMOUNTMGR_MOUNT_POINTS MountPoints, + _In_opt_ PMOUNTMGR_VOLUME_PATHS VolumePath, + _In_opt_ PMOUNTMGR_VOLUME_PATHS VolumePaths) +{ + UNICODE_STRING DosPath; + PCWSTR pMountPoint; + BOOLEAN ExpectedFound, Found; + + if (winetest_debug > 1) + { + ULONG i; + trace("\n%S =>\n", NtVolumeName); + for (i = 0; i < MountPoints->NumberOfMountPoints; ++i) + { + UNICODE_STRING DevName, SymLink; + + DevName.Length = DevName.MaximumLength = MountPoints->MountPoints[i].DeviceNameLength; + DevName.Buffer = (PWCHAR)((ULONG_PTR)MountPoints + MountPoints->MountPoints[i].DeviceNameOffset); + + SymLink.Length = SymLink.MaximumLength = MountPoints->MountPoints[i].SymbolicLinkNameLength; + SymLink.Buffer = (PWCHAR)((ULONG_PTR)MountPoints + MountPoints->MountPoints[i].SymbolicLinkNameOffset); + + printf(" '%s' -- '%s'\n", wine_dbgstr_us(&DevName), wine_dbgstr_us(&SymLink)); + } + printf("\n"); + } + + /* + * The Win32 file-system reparse point paths are NOT listed amongst + * the mount points. Only the drive letter and the volume GUID name + * are, but in an NT format (using '\DosDevices\' or '\??\' prefixes). + */ + + if (VolumePath) + { + /* VolumePath can either be a drive letter (usual case), a Win32 + * reparse point path (if the volume is mounted only with these), + * or a volume GUID name (if the volume is NOT mounted). */ + RtlInitUnicodeString(&DosPath, VolumePath->MultiSz); + ExpectedFound = (IS_DRIVE_LETTER(&DosPath) || MOUNTMGR_IS_DOS_VOLUME_NAME(&DosPath)); + Found = doesPathExistInMountPoints(MountPoints, &DosPath); + ok(Found == ExpectedFound, + "DOS path '%s' %sfound in the mount points list, expected %sto be found\n", + wine_dbgstr_us(&DosPath), Found ? "" : "NOT ", ExpectedFound ? "" : "NOT "); + } + + if (VolumePaths) + { + /* VolumePaths only contains a drive letter (usual case) or a Win32 + * reparse point path (if the volume is mounted only with these). + * If the volume is NOT mounted, VolumePaths does not list the + * volume GUID name, contrary to VolumePath. */ + for (pMountPoint = VolumePaths->MultiSz; *pMountPoint; + pMountPoint += wcslen(pMountPoint) + 1) + { + /* Only the drive letter (but NOT the volume GUID name!) can be found in the list */ + RtlInitUnicodeString(&DosPath, pMountPoint); + ExpectedFound = IS_DRIVE_LETTER(&DosPath); + Found = doesPathExistInMountPoints(MountPoints, &DosPath); + ok(Found == ExpectedFound, + "DOS path '%s' %sfound in the mount points list, expected %sto be found\n", + wine_dbgstr_us(&DosPath), Found ? "" : "NOT ", ExpectedFound ? "" : "NOT "); + } + } +} + +/** + * @brief + * Tests the consistency of IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH, + * IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATHS and IOCTL_MOUNTMGR_QUERY_POINTS. + **/ +static VOID +Test_QueryDosVolumePathAndPaths( + _In_ HANDLE MountMgrHandle, + _In_ PCWSTR NtVolumeName) +{ + PMOUNTMGR_VOLUME_PATHS VolumePath = NULL; + PMOUNTMGR_VOLUME_PATHS VolumePaths = NULL; + PMOUNTMGR_MOUNT_POINTS MountPoints = NULL; + + if (winetest_debug > 1) + trace("%S\n", NtVolumeName); + + Call_QueryDosVolume_Path_Paths(MountMgrHandle, + NtVolumeName, + IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH, + &VolumePath); + if (VolumePath) + Test_QueryDosVolumePath(NtVolumeName, VolumePath); + else + skip("Device '%S': IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH failed\n", NtVolumeName); + + Call_QueryDosVolume_Path_Paths(MountMgrHandle, + NtVolumeName, + IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATHS, + &VolumePaths); + if (VolumePaths) + Test_QueryDosVolumePaths(NtVolumeName, VolumePaths, VolumePath); + else + skip("Device '%S': IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATHS failed\n", NtVolumeName); + + Call_QueryPoints(MountMgrHandle, NtVolumeName, &MountPoints); + if (MountPoints) + Test_QueryPoints(NtVolumeName, MountPoints, VolumePath, VolumePaths); + else + skip("Device '%S': IOCTL_MOUNTMGR_QUERY_POINTS failed\n", NtVolumeName); + + if (MountPoints) + RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints); + if (VolumePaths) + RtlFreeHeap(RtlGetProcessHeap(), 0, VolumePaths); + if (VolumePath) + RtlFreeHeap(RtlGetProcessHeap(), 0, VolumePath); +} + + +START_TEST(QueryDosVolumePaths) +{ + HANDLE MountMgrHandle; + HANDLE hFindVolume; + WCHAR szVolumeName[MAX_PATH]; + + MountMgrHandle = GetMountMgrHandle(FILE_READ_ATTRIBUTES); + if (!MountMgrHandle) + { + win_skip("MountMgr unavailable: %lu\n", GetLastError()); + return; + } + + hFindVolume = FindFirstVolumeW(szVolumeName, _countof(szVolumeName)); + if (hFindVolume == INVALID_HANDLE_VALUE) + goto otherTests; + do + { + UNICODE_STRING VolumeName; + USHORT Length; + + /* + * The Win32 FindFirst/NextVolumeW() functions convert the '\??\' + * prefix in '\??\Volume{...}' to '\\?\' and append a trailing + * backslash. Test this behaviour. + * + * NOTE: these functions actively filter out anything that is NOT + * '\??\Volume{...}' returned from IOCTL_MOUNTMGR_QUERY_POINTS. + * Thus, it also excludes mount-points specified as drive letters, + * like '\DosDevices\C:' . + */ + + RtlInitUnicodeString(&VolumeName, szVolumeName); + Length = VolumeName.Length / sizeof(WCHAR); + ok(Length >= 1 && VolumeName.Buffer[Length - 1] == L'\\', + "No trailing backslash found\n"); + + /* Remove the trailing backslash */ + if (Length >= 1) + { + VolumeName.Length -= sizeof(WCHAR); + if (szVolumeName[Length - 1] == L'\\') + szVolumeName[Length - 1] = UNICODE_NULL; + } + + ok(MOUNTMGR_IS_DOS_VOLUME_NAME(&VolumeName), + "Invalid DOS volume path returned '%s'\n", wine_dbgstr_us(&VolumeName)); + + /* Patch '\\?\' back to '\??\' to convert to an NT path */ + if (szVolumeName[0] == L'\\' && szVolumeName[1] == L'\\' && + szVolumeName[2] == L'?' && szVolumeName[3] == L'\\') + { + szVolumeName[1] = L'?'; + } + + Test_QueryDosVolumePathAndPaths(MountMgrHandle, szVolumeName); + } while (FindNextVolumeW(hFindVolume, szVolumeName, _countof(szVolumeName))); + FindVolumeClose(hFindVolume); + +otherTests: + /* Test the drive containing SystemRoot */ + wcscpy(szVolumeName, L"\\DosDevices\\?:"); + szVolumeName[sizeof("\\DosDevices\\")-1] = SharedUserData->NtSystemRoot[0]; + Test_QueryDosVolumePathAndPaths(MountMgrHandle, szVolumeName); + + /* We are done */ + CloseHandle(MountMgrHandle); +} diff --git a/modules/rostests/apitests/mountmgr/QueryPoints.c b/modules/rostests/apitests/mountmgr/QueryPoints.c index a56b14966062c..a34e27f8ca466 100644 --- a/modules/rostests/apitests/mountmgr/QueryPoints.c +++ b/modules/rostests/apitests/mountmgr/QueryPoints.c @@ -1,68 +1,75 @@ /* - * PROJECT: ReactOS api tests - * LICENSE: GPLv2+ - See COPYING in the top level directory - * PURPOSE: Test for QueryPoints IOCTL - * PROGRAMMER: Pierre Schweitzer + * PROJECT: ReactOS API Tests + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Test for IOCTL_MOUNTMGR_QUERY_POINTS + * COPYRIGHT: Copyright 2019 Pierre Schweitzer */ #include "precomp.h" VOID -TraceMountPoint(PMOUNTMGR_MOUNT_POINTS MountPoints, - PMOUNTMGR_MOUNT_POINT MountPoint) +TraceMountPoint( + _In_ const MOUNTMGR_MOUNT_POINTS* MountPoints, + _In_ const MOUNTMGR_MOUNT_POINT* MountPoint) { trace("MountPoint: %p\n", MountPoint); trace("\tSymbolicOffset: %ld\n", MountPoint->SymbolicLinkNameOffset); - trace("\tSymbolicLinkName: %.*S\n", MountPoint->SymbolicLinkNameLength / sizeof(WCHAR), (PWSTR)((ULONG_PTR)MountPoints + MountPoint->SymbolicLinkNameOffset)); + trace("\tSymbolicLinkName: %.*S\n", + MountPoint->SymbolicLinkNameLength / sizeof(WCHAR), + (PWCHAR)((ULONG_PTR)MountPoints + MountPoint->SymbolicLinkNameOffset)); trace("\tDeviceOffset: %ld\n", MountPoint->DeviceNameOffset); - trace("\tDeviceName: %.*S\n", MountPoint->DeviceNameLength / sizeof(WCHAR), (PWSTR)((ULONG_PTR)MountPoints + MountPoint->DeviceNameOffset)); + trace("\tDeviceName: %.*S\n", + MountPoint->DeviceNameLength / sizeof(WCHAR), + (PWCHAR)((ULONG_PTR)MountPoints + MountPoint->DeviceNameOffset)); } START_TEST(QueryPoints) { BOOL Ret; HANDLE MountMgrHandle; - DWORD BytesReturned, Drives, i; - struct { + DWORD LastError, BytesReturned, Drives, i; + struct + { MOUNTMGR_MOUNT_POINT; - WCHAR Buffer[sizeof(L"\\DosDevice\\A:")]; + WCHAR Buffer[sizeof("\\DosDevice\\A:")]; } SinglePoint; MOUNTMGR_MOUNT_POINTS MountPoints; PMOUNTMGR_MOUNT_POINTS AllocatedPoints; - MountMgrHandle = CreateFileW(MOUNTMGR_DOS_DEVICE_NAME, 0, - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, - OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, - INVALID_HANDLE_VALUE); - if (MountMgrHandle == INVALID_HANDLE_VALUE) + MountMgrHandle = GetMountMgrHandle(FILE_READ_ATTRIBUTES); + if (!MountMgrHandle) { - win_skip("MountMgr unavailable: %lx\n", GetLastError()); + win_skip("MountMgr unavailable: %lu\n", GetLastError()); return; } ZeroMemory(&SinglePoint, sizeof(SinglePoint)); + /* Retrieve the size needed to enumerate all the existing mount points */ Ret = DeviceIoControl(MountMgrHandle, IOCTL_MOUNTMGR_QUERY_POINTS, - &SinglePoint, sizeof(MOUNTMGR_MOUNT_POINT), - &MountPoints, sizeof(MOUNTMGR_MOUNT_POINTS), + &SinglePoint, sizeof(MOUNTMGR_MOUNT_POINT), // Size without the string. + &MountPoints, sizeof(MountPoints), &BytesReturned, NULL); - ok(Ret == FALSE, "IOCTL unexpectedly succeed\n"); - ok(GetLastError() == ERROR_MORE_DATA, "Unexcepted failure: %lx\n", GetLastError()); + LastError = GetLastError(); + ok(Ret == FALSE, "IOCTL unexpectedly succeeded\n"); + ok(LastError == ERROR_MORE_DATA, "Unexpected failure: %lu\n", LastError); + /* Allocate a suitably-sized buffer for the mount points */ AllocatedPoints = RtlAllocateHeap(RtlGetProcessHeap(), 0, MountPoints.Size); if (AllocatedPoints == NULL) { - win_skip("Insufficiant memory\n"); + skip("Insufficient memory\n"); } else { AllocatedPoints->NumberOfMountPoints = 0; + /* Retrieve the list of all the existing mount points */ Ret = DeviceIoControl(MountMgrHandle, IOCTL_MOUNTMGR_QUERY_POINTS, - &SinglePoint, sizeof(MOUNTMGR_MOUNT_POINT), + &SinglePoint, sizeof(MOUNTMGR_MOUNT_POINT), // Size without the string. AllocatedPoints, MountPoints.Size, &BytesReturned, NULL); - ok(Ret == TRUE, "IOCTL unexpectedly failed %lx\n", GetLastError()); + ok(Ret == TRUE, "IOCTL unexpectedly failed: %lu\n", GetLastError()); for (i = 0; i < AllocatedPoints->NumberOfMountPoints; ++i) { @@ -72,40 +79,37 @@ START_TEST(QueryPoints) RtlFreeHeap(RtlGetProcessHeap(), 0, AllocatedPoints); } + /* Now, find the first unused drive letter */ Drives = GetLogicalDrives(); if (Drives == 0) { - win_skip("Drives map unavailable: %lx\n", GetLastError()); + skip("Drives map unavailable: %lu\n", GetLastError()); goto Done; } - - for (i = 0; i < 26; i++) + for (i = 0; i <= 'Z'-'A'; ++i) { if (!(Drives & (1 << i))) - { break; - } } - - if (i == 26) + if (i > 'Z'-'A') { - win_skip("All the drive letters are in use, skipping\n"); + skip("All the drive letters are in use, skipping\n"); goto Done; } - SinglePoint.SymbolicLinkNameOffset = sizeof(MOUNTMGR_MOUNT_POINT); - SinglePoint.SymbolicLinkNameLength = sizeof(L"\\DosDevice\\A:") - sizeof(UNICODE_NULL); - StringCbPrintfW((PWSTR)((ULONG_PTR)&SinglePoint + sizeof(MOUNTMGR_MOUNT_POINT)), - sizeof(L"\\DosDevice\\A:"), - L"\\DosDevice\\%C:", - i + L'A'); + /* Check that this drive letter is not an existing mount point */ + SinglePoint.SymbolicLinkNameOffset = ((ULONG_PTR)&SinglePoint.Buffer - (ULONG_PTR)&SinglePoint); + SinglePoint.SymbolicLinkNameLength = sizeof(SinglePoint.Buffer) - sizeof(UNICODE_NULL); + StringCbPrintfW(SinglePoint.Buffer, sizeof(SinglePoint.Buffer), + L"\\DosDevice\\%C:", L'A' + i); Ret = DeviceIoControl(MountMgrHandle, IOCTL_MOUNTMGR_QUERY_POINTS, &SinglePoint, sizeof(SinglePoint), - &MountPoints, sizeof(MOUNTMGR_MOUNT_POINTS), + &MountPoints, sizeof(MountPoints), &BytesReturned, NULL); - ok(Ret == FALSE, "IOCTL unexpectedly succeed\n"); - ok(GetLastError() == ERROR_FILE_NOT_FOUND, "Unexcepted failure: %lx\n", GetLastError()); + LastError = GetLastError(); + ok(Ret == FALSE, "IOCTL unexpectedly succeeded\n"); + ok(LastError == ERROR_FILE_NOT_FOUND, "Unexpected failure: %lu\n", LastError); Done: CloseHandle(MountMgrHandle); diff --git a/modules/rostests/apitests/mountmgr/precomp.h b/modules/rostests/apitests/mountmgr/precomp.h index 33509fb80830a..8414c0d9ce17f 100644 --- a/modules/rostests/apitests/mountmgr/precomp.h +++ b/modules/rostests/apitests/mountmgr/precomp.h @@ -1,12 +1,34 @@ -#ifndef _MOUNTMGR_APITEST_PRECOMP_H_ -#define _MOUNTMGR_APITEST_PRECOMP_H_ +/* + * PROJECT: ReactOS API Tests + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Precompiled header + * COPYRIGHT: Copyright 2019 Pierre Schweitzer + * Copyright 2025 Hermès Bélusca-Maïto + */ -#define WIN32_NO_STATUS +#pragma once +#define WIN32_NO_STATUS #include -#include -#include -#include + +#define NTOS_MODE_USER +#include #include -#endif /* _MOUNTMGR_APITEST_PRECOMP_H_ */ +#include +#include + +/* utils.c */ + +LPCSTR wine_dbgstr_us(const UNICODE_STRING *us); + +HANDLE +GetMountMgrHandle( + _In_ ACCESS_MASK DesiredAccess); + +VOID +DumpBuffer( + _In_ PVOID Buffer, + _In_ ULONG Length); + +/* EOF */ diff --git a/modules/rostests/apitests/mountmgr/testlist.c b/modules/rostests/apitests/mountmgr/testlist.c index ab7c0921a2656..9c96445bbcd8d 100644 --- a/modules/rostests/apitests/mountmgr/testlist.c +++ b/modules/rostests/apitests/mountmgr/testlist.c @@ -1,10 +1,12 @@ #define STANDALONE #include +extern void func_QueryDosVolumePaths(void); extern void func_QueryPoints(void); const struct test winetest_testlist[] = { + { "QueryDosVolumePaths", func_QueryDosVolumePaths }, { "QueryPoints", func_QueryPoints }, { 0, 0 } }; diff --git a/modules/rostests/apitests/mountmgr/utils.c b/modules/rostests/apitests/mountmgr/utils.c new file mode 100644 index 0000000000000..10f4b527f1628 --- /dev/null +++ b/modules/rostests/apitests/mountmgr/utils.c @@ -0,0 +1,103 @@ +/* + * PROJECT: ReactOS API Tests + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Utility functions + * COPYRIGHT: Copyright 2025 Hermès Bélusca-Maïto + */ + +#include "precomp.h" + +LPCSTR wine_dbgstr_us(const UNICODE_STRING *us) +{ + if (!us) return "(null)"; + return wine_dbgstr_wn(us->Buffer, us->Length / sizeof(WCHAR)); +} + +/** + * @brief + * Retrieves a handle to the MountMgr controlling device. + * The handle should be closed with NtClose() once it is no longer in use. + **/ +HANDLE +GetMountMgrHandle( + _In_ ACCESS_MASK DesiredAccess) +{ + NTSTATUS Status; + UNICODE_STRING MountMgrDevice; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + HANDLE MountMgrHandle = NULL; + + RtlInitUnicodeString(&MountMgrDevice, MOUNTMGR_DEVICE_NAME); + InitializeObjectAttributes(&ObjectAttributes, + &MountMgrDevice, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtOpenFile(&MountMgrHandle, + DesiredAccess | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_SYNCHRONOUS_IO_NONALERT); + if (!NT_SUCCESS(Status)) + { + winetest_print("NtOpenFile(%s) failed, Status 0x%08lx\n", + wine_dbgstr_us(&MountMgrDevice), Status); + } + + return MountMgrHandle; +} + +VOID +DumpBuffer( + _In_ PVOID Buffer, + _In_ ULONG Length) +{ +#define LINE_SIZE (75 + 2) + ULONG i; + PBYTE Ptr1, Ptr2; + CHAR LineBuffer[LINE_SIZE]; + PCHAR Line; + ULONG LineSize; + + Ptr1 = Ptr2 = Buffer; + while ((ULONG_PTR)Buffer + Length - (ULONG_PTR)Ptr1 > 0) + { + Ptr1 = Ptr2; + Line = LineBuffer; + + /* Print the address */ + Line += _snprintf(Line, LINE_SIZE + LineBuffer - Line, "%08Ix ", (ULONG_PTR)Ptr1); + + /* Print up to 16 bytes... */ + + /* ... in hexadecimal form first... */ + i = 0; + while (i++ <= 0x0F && ((ULONG_PTR)Buffer + Length - (ULONG_PTR)Ptr1 > 0)) + { + Line += _snprintf(Line, LINE_SIZE + LineBuffer - Line, " %02x", *Ptr1); + ++Ptr1; + } + + /* ... align with spaces if needed... */ + RtlFillMemory(Line, (0x0F + 2 - i) * 3 + 2, ' '); + Line += (0x0F + 2 - i) * 3 + 2; + + /* ... then in character form. */ + i = 0; + while (i++ <= 0x0F && ((ULONG_PTR)Buffer + Length - (ULONG_PTR)Ptr2 > 0)) + { + *Line++ = ((*Ptr2 >= 0x20 && *Ptr2 <= 0x7E) || (*Ptr2 >= 0x80 && *Ptr2 < 0xFF) ? *Ptr2 : '.'); + ++Ptr2; + } + + /* Newline */ + *Line++ = '\r'; + *Line++ = '\n'; + + /* Finally display the line */ + LineSize = Line - LineBuffer; + printf("%.*s", (int)LineSize, LineBuffer); + } +} diff --git a/modules/rostests/apitests/msvcrt/ieee.c b/modules/rostests/apitests/msvcrt/ieee.c index 426d8db6416ab..8142e4c69d472 100644 --- a/modules/rostests/apitests/msvcrt/ieee.c +++ b/modules/rostests/apitests/msvcrt/ieee.c @@ -3,7 +3,7 @@ * LICENSE: GPL - See COPYING in the top level directory * PURPOSE: Tests for IEEE floatting-point functions * PROGRAMMER: Pierre Schweitzer (pierre@reactos.org) - * REFERENCES: http://msdn.microsoft.com/en-US/library/h7zkk1bz%28v=VS.80%29.aspx + * REFERENCES: https://web.archive.org/web/20151223002427/http://msdn.microsoft.com/en-US/library/h7zkk1bz(v=VS.80).aspx */ #include diff --git a/modules/rostests/apitests/netshell/NcIsValidConnectionName.c b/modules/rostests/apitests/netshell/NcIsValidConnectionName.c index 041f1dfd074f7..443b4bc388d0e 100644 --- a/modules/rostests/apitests/netshell/NcIsValidConnectionName.c +++ b/modules/rostests/apitests/netshell/NcIsValidConnectionName.c @@ -16,7 +16,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* Documentation: https://msdn.microsoft.com/en-us/library/windows/desktop/aa366197%28v=vs.85%29.aspx */ +/* Documentation: https://learn.microsoft.com/en-us/windows/win32/api/netcon/nf-netcon-ncisvalidconnectionname */ #include diff --git a/modules/rostests/apitests/ntdll/CMakeLists.txt b/modules/rostests/apitests/ntdll/CMakeLists.txt index 6f956813680f1..74843c8a116ff 100644 --- a/modules/rostests/apitests/ntdll/CMakeLists.txt +++ b/modules/rostests/apitests/ntdll/CMakeLists.txt @@ -1,11 +1,14 @@ add_subdirectory(load_notifications) +add_subdirectory(empty_dll) include_directories($) +include_directories($) include_directories(${REACTOS_SOURCE_DIR}/ntoskrnl/include) spec2def(ntdll_apitest.exe ntdll_apitest.spec) list(APPEND SOURCE + DllLoadNotification.c LdrEnumResources.c LdrLoadDll.c load_notifications.c @@ -22,6 +25,7 @@ list(APPEND SOURCE NtContinue.c NtCreateFile.c NtCreateKey.c + NtCreateProfile.c NtCreateThread.c NtDeleteKey.c NtDuplicateObject.c @@ -41,6 +45,7 @@ list(APPEND SOURCE NtQueryInformationThread.c NtQueryInformationToken.c NtQueryKey.c + NtQueryObject.c NtQueryOpenSubKeys.c NtQuerySystemEnvironmentValue.c NtQuerySystemInformation.c @@ -55,6 +60,7 @@ list(APPEND SOURCE NtSetInformationToken.c NtSetValueKey.c NtSetVolumeInformationFile.c + NtStartProfile.c NtUnloadDriver.c NtWriteFile.c probelib.c @@ -86,6 +92,7 @@ list(APPEND SOURCE RtlImageDirectoryEntryToData.c RtlImageRvaToVa.c RtlIsNameLegalDOS8Dot3.c + RtlLocale.c RtlMemoryStream.c RtlMultipleAllocateHeap.c RtlNtPathNameToDosPathName.c @@ -117,6 +124,7 @@ list(APPEND PCH_SKIP_SOURCE testlist.c) add_rc_deps(testdata.rc ${CMAKE_CURRENT_BINARY_DIR}/load_notifications/load_notifications.dll) +add_rc_deps(testdata.rc ${CMAKE_CURRENT_BINARY_DIR}/empty_dll/empty_dll.dll) add_executable(ntdll_apitest ${SOURCE} @@ -134,10 +142,13 @@ target_link_libraries(ntdll_apitest rtl_test_lib wine uuid ${PSEH_LIB}) set_module_type(ntdll_apitest win32cui) add_importlibs(ntdll_apitest msvcrt advapi32 kernel32 ntdll) add_pch(ntdll_apitest precomp.h "${PCH_SKIP_SOURCE}") -add_dependencies(ntdll_apitest load_notifications) +add_dependencies(ntdll_apitest load_notifications empty_dll) if(NOT MSVC) - set_source_files_properties(RtlGetFullPathName_UstrEx.c PROPERTIES COMPILE_OPTIONS "-Wno-format") + set_source_files_properties( + RtlGetFullPathName_UstrEx.c + RtlLocale.c + PROPERTIES COMPILE_OPTIONS "-Wno-format") endif() add_rostests_file(TARGET ntdll_apitest) diff --git a/modules/rostests/apitests/ntdll/DllLoadNotification.c b/modules/rostests/apitests/ntdll/DllLoadNotification.c new file mode 100644 index 0000000000000..30ed50e38a330 --- /dev/null +++ b/modules/rostests/apitests/ntdll/DllLoadNotification.c @@ -0,0 +1,235 @@ +/* + * PROJECT: ReactOS API Tests + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: Test for DLL Load Notification API + * COPYRIGHT: Copyright 2024 Ratin Gao + */ + +#define UNICODE + +#include "precomp.h" + +#include + +static WCHAR g_szDllPath[MAX_PATH]; +static UNICODE_STRING g_usDllPath; +static UNICODE_STRING g_usDllName; +static volatile LONG g_lDllLoadCount = 0; + +typedef +NTSTATUS +NTAPI +FN_LdrRegisterDllNotification( + _In_ ULONG Flags, + _In_ PLDR_DLL_NOTIFICATION_FUNCTION NotificationFunction, + _In_opt_ PVOID Context, + _Out_ PVOID* Cookie); + +typedef +NTSTATUS +NTAPI +FN_LdrUnregisterDllNotification( + _In_ PVOID Cookie); + +static BOOL ExtractResource( + _In_z_ PCWSTR SavePath, + _In_ PCWSTR ResourceType, + _In_ PCWSTR ResourceName) +{ + BOOL bSuccess; + DWORD dwWritten, dwSize; + HGLOBAL hGlobal; + LPVOID pData; + HANDLE hFile; + HRSRC hRsrc; + + /* Load resource */ + if ((hRsrc = FindResourceW(NULL, ResourceName, ResourceType)) == NULL || + (dwSize = SizeofResource(NULL, hRsrc)) == 0 || + (hGlobal = LoadResource(NULL, hRsrc)) == NULL || + (pData = LockResource(hGlobal)) == NULL) + { + return FALSE; + } + + /* Save to file */ + hFile = CreateFileW(SavePath, + GENERIC_WRITE, + FILE_SHARE_READ, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + if (hFile == INVALID_HANDLE_VALUE) + { + return FALSE; + } + bSuccess = WriteFile(hFile, pData, dwSize, &dwWritten, NULL); + CloseHandle(hFile); + if (!bSuccess) + { + return FALSE; + } + else if (dwWritten != dwSize) + { + trace("Extract resource failed, written size (%lu) is not actual size (%lu)\n", dwWritten, dwSize); + DeleteFileW(SavePath); + SetLastError(ERROR_INCORRECT_SIZE); + return FALSE; + } + return TRUE; +} + +static VOID NTAPI DllLoadCallback( + _In_ ULONG NotificationReason, + _In_ PCLDR_DLL_NOTIFICATION_DATA NotificationData, + _In_opt_ PVOID Context) +{ + LONG lRet; + HMODULE* phNotifiedDllBase = Context; + + /* + * Verify the data, + * NotificationData->Loaded and NotificationData->Unloaded currently are the same. + */ + + /* Verify the FullDllName and BaseDllName */ + ok_eq_ulong(NotificationData->Loaded.Flags, 0UL); + lRet = RtlCompareUnicodeString(NotificationData->Loaded.FullDllName, + (PCUNICODE_STRING)&g_usDllPath, + TRUE); + ok_eq_long(lRet, 0L); + lRet = RtlCompareUnicodeString(NotificationData->Loaded.BaseDllName, + (PCUNICODE_STRING)&g_usDllName, + TRUE); + ok_eq_long(lRet, 0L); + + /* + * Verify SizeOfImage and read SizeOfImage from PE header, + * make sure the DLL is not unmapped, the memory is still accessible. + */ + ok_eq_ulong(NotificationData->Loaded.SizeOfImage, + RtlImageNtHeader(NotificationData->Loaded.DllBase)->OptionalHeader.SizeOfImage); + + /* Reason can be load or unload */ + ok(NotificationReason == LDR_DLL_NOTIFICATION_REASON_LOADED || + NotificationReason == LDR_DLL_NOTIFICATION_REASON_UNLOADED, "Incorrect NotificationReason\n"); + if (NotificationReason == LDR_DLL_NOTIFICATION_REASON_LOADED) + { + *phNotifiedDllBase = NotificationData->Loaded.DllBase; + InterlockedIncrement(&g_lDllLoadCount); + } + else if (NotificationReason == LDR_DLL_NOTIFICATION_REASON_UNLOADED) + { + InterlockedDecrement(&g_lDllLoadCount); + } +} + +START_TEST(DllLoadNotification) +{ + WCHAR szTempPath[MAX_PATH]; + PCWSTR pszDllName; + HMODULE hNtDll, hTestDll, hNotifiedDllBase; + FN_LdrRegisterDllNotification* pfnLdrRegisterDllNotification; + FN_LdrUnregisterDllNotification* pfnLdrUnregisterDllNotification; + NTSTATUS Status; + PVOID Cookie1, Cookie2; + + /* Load functions */ + hNtDll = GetModuleHandleW(L"ntdll.dll"); + if (hNtDll == NULL) + { + skip("GetModuleHandleW for ntdll failed with 0x%08lX\n", GetLastError()); + return; + } + pfnLdrRegisterDllNotification = (FN_LdrRegisterDllNotification*)GetProcAddress(hNtDll, "LdrRegisterDllNotification"); + pfnLdrUnregisterDllNotification = (FN_LdrUnregisterDllNotification*)GetProcAddress(hNtDll, "LdrUnregisterDllNotification"); + if (!pfnLdrRegisterDllNotification || !pfnLdrUnregisterDllNotification) + { + skip("ntdll.dll!Ldr[Un]RegisterDllNotification not found\n"); + return; + } + + /* Extract DLL to temp directory */ + if (!GetTempPathW(ARRAYSIZE(szTempPath), szTempPath)) + { + skip("GetTempPathW failed with 0x%08lX\n", GetLastError()); + return; + } + if (GetTempFileNameW(szTempPath, L"DLN", 0, g_szDllPath) == 0) + { + skip("GetTempFileNameW failed with 0x%08lX\n", GetLastError()); + return; + } + RtlInitUnicodeString(&g_usDllPath, g_szDllPath); + pszDllName = wcsrchr(g_szDllPath, L'\\') + 1; + if (pszDllName == NULL) + { + skip("Find file name of %ls failed\n", g_szDllPath); + return; + } + RtlInitUnicodeString(&g_usDllName, pszDllName); + if (!ExtractResource(g_szDllPath, RT_RCDATA, MAKEINTRESOURCEW(102))) + { + skip("ExtractResource failed with 0x%08lX\n", GetLastError()); + return; + } + + /* Register DLL load notification callback */ + hNotifiedDllBase = NULL; + Cookie1 = NULL; + Cookie2 = NULL; + Status = pfnLdrRegisterDllNotification(0, DllLoadCallback, &hNotifiedDllBase, &Cookie1); + ok_eq_bool(NT_SUCCESS(Status), TRUE); + ok(Cookie1 != NULL, "Cookie1 is NULL\n"); + + /* Register the callback again is valid */ + Status = pfnLdrRegisterDllNotification(0, DllLoadCallback, &hNotifiedDllBase, &Cookie2); + ok_eq_bool(NT_SUCCESS(Status), TRUE); + ok(Cookie2 != NULL, "Cookie2 is NULL\n"); + + /* Load the test DLL */ + hTestDll = LoadLibraryW(g_szDllPath); + if (!hTestDll) + { + skip("LoadLibraryW failed with 0x%08lX\n", GetLastError()); + goto _exit; + } + + /* Verify the Dll base received in callback and returned via context */ + ok_eq_pointer(hNotifiedDllBase, hTestDll); + + /* The count should be 2 because the callback was registered twice */ + ok_eq_long(g_lDllLoadCount, 2L); + + /* + * Callback will not be triggered because following + * load and unload actions change the DLL reference count only + */ + LoadLibraryW(g_szDllPath); + ok_eq_long(g_lDllLoadCount, 2L); + FreeLibrary(hTestDll); + ok_eq_long(g_lDllLoadCount, 2L); + + /* Unregister the callback once */ + Status = pfnLdrUnregisterDllNotification(Cookie1); + ok_eq_bool(NT_SUCCESS(Status), TRUE); + + /* Unload the test DLL */ + if (FreeLibrary(hTestDll)) + { + /* The count will decrease 1 because the last callback still there */ + ok_eq_long(g_lDllLoadCount, 1L); + } + else + { + skip("FreeLibrary failed with 0x%08lX\n", GetLastError()); + } + + /* Unregister the last callback */ + Status = pfnLdrUnregisterDllNotification(Cookie2); + ok_eq_bool(NT_SUCCESS(Status), TRUE); + +_exit: + DeleteFileW(g_szDllPath); +} diff --git a/modules/rostests/apitests/ntdll/NtCreateProfile.c b/modules/rostests/apitests/ntdll/NtCreateProfile.c new file mode 100644 index 0000000000000..3b0bf2cbf856d --- /dev/null +++ b/modules/rostests/apitests/ntdll/NtCreateProfile.c @@ -0,0 +1,356 @@ +/* + * PROJECT: ReactOS API Tests + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Test for NtCreateProfile + * COPYRIGHT: Copyright 2021 Thomas Faber (thomas.faber@reactos.org) + */ + +#include "precomp.h" + +#define SIZEOF_MDL (5 * sizeof(PVOID) + 2 * sizeof(ULONG)) +typedef ULONG_PTR PFN_NUMBER; +/* Maximum size that can be described by an MDL on 2003 and earlier */ +#define MAX_MDL_BUFFER_SIZE ((MAXUSHORT - SIZEOF_MDL) / sizeof(PFN_NUMBER) * PAGE_SIZE + PAGE_SIZE - 1) + +#define broken(cond) (strcmp(winetest_platform, "windows") ? 0 : cond) + +static BOOL IsWow64; + +static +void +TestParameterValidation(void) +{ + NTSTATUS Status; + HANDLE ProfileHandle; + + Status = NtCreateProfile(NULL, + NULL, + NULL, + 0, + 0, + NULL, + 0, + ProfileTime, + 1); + ok_hex(Status, STATUS_INVALID_PARAMETER_7); + + /* For addresses below 0x10000, there's a special check for BufferSize<4 -- on x86 only */ + { + Status = NtCreateProfile(NULL, + NULL, + (PVOID)(ULONG_PTR)0xFFFF, + 0, + 0, + NULL, + 3, + ProfileTime, + 1); + if (sizeof(PVOID) > sizeof(ULONG) || IsWow64) + { + ok_hex(Status, STATUS_INVALID_PARAMETER); + } + else + { + ok_hex(Status, STATUS_INVALID_PARAMETER_7); + } + + /* Increasing the pointer gets us past this */ + Status = NtCreateProfile(NULL, + NULL, + (PVOID)(ULONG_PTR)0x10000, + 0, + 0, + NULL, + 3, + ProfileTime, + 1); + ok_hex(Status, STATUS_INVALID_PARAMETER); + + /* So does increasing the size */ + Status = NtCreateProfile(NULL, + NULL, + (PVOID)(ULONG_PTR)0xFFFF, + 0, + 0, + NULL, + 4, + ProfileTime, + 1); + ok_hex(Status, STATUS_INVALID_PARAMETER); + + /* ... or, specifying a bucket size */ + Status = NtCreateProfile(NULL, + NULL, + (PVOID)(ULONG_PTR)0xFFFF, + 0, + 1, + NULL, + 4, + ProfileTime, + 1); + ok_hex(Status, STATUS_INVALID_PARAMETER); + } + + /* Bucket sizes less than two or larger than 31 are invalid */ + { + Status = NtCreateProfile(NULL, + NULL, + (PVOID)(ULONG_PTR)0x10000, + 0x80000000, + 1, + NULL, + 1, + ProfileTime, + 1); + ok_hex(Status, STATUS_INVALID_PARAMETER); + + Status = NtCreateProfile(NULL, + NULL, + (PVOID)(ULONG_PTR)0x10000, + 0x80000000, + 32, + NULL, + 1, + ProfileTime, + 1); + ok_hex(Status, STATUS_INVALID_PARAMETER); + + /* But 2 and 31 are valid */ + Status = NtCreateProfile(NULL, + NULL, + (PVOID)(ULONG_PTR)0x10000, + 0x80000000, + 2, + NULL, + 1, + ProfileTime, + 1); + ok_hex(Status, STATUS_BUFFER_TOO_SMALL); + + Status = NtCreateProfile(NULL, + NULL, + (PVOID)(ULONG_PTR)0x10000, + 0x80000000, + 31, + NULL, + 1, + ProfileTime, + 1); + ok_hex(Status, STATUS_BUFFER_TOO_SMALL); + } + + /* RangeSize validation has its own function */ + + /* RangeBase+RangeSize can overflow into kernel space, but can't wrap around. + * Note that a Wow64 test will never achieve overflow. + */ + { + Status = NtCreateProfile(NULL, + NULL, + (PVOID)(ULONG_PTR)0x10000, + SIZE_MAX / 2, + 31, + NULL, + 0x80000000, + ProfileTime, + 1); + ok_hex(Status, (sizeof(PVOID) == 8) ? STATUS_BUFFER_TOO_SMALL : STATUS_ACCESS_VIOLATION); + + Status = NtCreateProfile(NULL, + NULL, + (PVOID)(ULONG_PTR)0x10000, + SIZE_MAX - 0x10000, + 31, + NULL, + 0x80000000, + ProfileTime, + 1); + ok_hex(Status, (sizeof(PVOID) == 8) ? STATUS_BUFFER_TOO_SMALL : STATUS_ACCESS_VIOLATION); + + Status = NtCreateProfile(NULL, + NULL, + (PVOID)(ULONG_PTR)0x10000, + SIZE_MAX - 0x10000 + 1, + 31, + NULL, + 0x80000000, + ProfileTime, + 1); + ok_hex(Status, (sizeof(PVOID) == 8) ? STATUS_BUFFER_TOO_SMALL : + IsWow64 ? STATUS_ACCESS_VIOLATION : + STATUS_BUFFER_OVERFLOW); + + Status = NtCreateProfile(NULL, + NULL, + (PVOID)(ULONG_PTR)0x10000, + SIZE_MAX, + 31, + NULL, + 0x80000000, + ProfileTime, + 1); + ok_hex(Status, (sizeof(PVOID) == 8) ? STATUS_BUFFER_TOO_SMALL : + IsWow64 ? STATUS_ACCESS_VIOLATION : + STATUS_BUFFER_OVERFLOW); + } + + /* Handle is probed first and requires no alignment, buffer requires ULONG alignment */ + { + ULONG Buffer[1]; + + Status = NtCreateProfile((PHANDLE)(ULONG_PTR)1, + (HANDLE)(ULONG_PTR)1, + (PVOID)(ULONG_PTR)0x10002, + 0x1000, + 31, + (PVOID)(ULONG_PTR)2, + sizeof(ULONG), + ProfileTime, + 1); + ok_hex(Status, STATUS_ACCESS_VIOLATION); + + Status = NtCreateProfile(&ProfileHandle, + (HANDLE)(ULONG_PTR)1, + (PVOID)(ULONG_PTR)0x10000, + 0x1000, + 31, + (PVOID)(ULONG_PTR)2, + sizeof(ULONG), + ProfileTime, + 1); + ok_hex(Status, STATUS_DATATYPE_MISALIGNMENT); + + Status = NtCreateProfile(&ProfileHandle, + (HANDLE)(ULONG_PTR)1, + (PVOID)(ULONG_PTR)0x10000, + 0x1000, + 31, + (PVOID)(ULONG_PTR)4, + sizeof(ULONG), + ProfileTime, + 1); + ok_hex(Status, STATUS_ACCESS_VIOLATION); + + Status = NtCreateProfile(&ProfileHandle, + (HANDLE)(ULONG_PTR)1, + (PVOID)(ULONG_PTR)0x10000, + 0x1000, + 31, + Buffer, + sizeof(ULONG), + ProfileTime, + 1); + ok_hex(Status, STATUS_INVALID_HANDLE); + } +} + +/* There are bugs in this validation all the way through early Win10. + * Therefore we test this more thoroughly. + * See https://www.geoffchappell.com/studies/windows/km/ntoskrnl/api/ex/profile/bugdemo.htm + */ +static +void +TestBufferSizeValidation(void) +{ + static const struct + { + INT Line; + SIZE_T RangeSize; + ULONG BucketSize; + ULONG BufferSize; + NTSTATUS ExpectedStatus; + NTSTATUS BrokenStatus; + } Tests[] = + { + /* RangeSize=(1 << BucketSize) means we'll need exactly one ULONG */ + { __LINE__, 0x4, 2, sizeof(ULONG) - 1, STATUS_BUFFER_TOO_SMALL }, + { __LINE__, 0x4, 2, sizeof(ULONG), STATUS_ACCESS_VIOLATION }, + { __LINE__, 0x8, 3, sizeof(ULONG) - 1, STATUS_BUFFER_TOO_SMALL }, + { __LINE__, 0x8, 3, sizeof(ULONG), STATUS_ACCESS_VIOLATION }, + { __LINE__, 0x400, 10, sizeof(ULONG) - 1, STATUS_BUFFER_TOO_SMALL }, + { __LINE__, 0x400, 10, sizeof(ULONG), STATUS_ACCESS_VIOLATION }, + { __LINE__, 0x40000000, 30, sizeof(ULONG) - 1, STATUS_BUFFER_TOO_SMALL }, + { __LINE__, 0x40000000, 30, sizeof(ULONG), STATUS_ACCESS_VIOLATION }, + { __LINE__, 0x80000000, 31, sizeof(ULONG) - 1, STATUS_BUFFER_TOO_SMALL }, + { __LINE__, 0x80000000, 31, sizeof(ULONG), STATUS_ACCESS_VIOLATION }, + + /* RangeSize<(1 << BucketSize) also means we'll need one ULONG. + * However, old Windows versions get this wrong. + */ + { __LINE__, 3, 2, sizeof(ULONG) - 1, STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION }, + { __LINE__, 3, 2, sizeof(ULONG), STATUS_ACCESS_VIOLATION }, + { __LINE__, 1, 2, sizeof(ULONG) - 1, STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION }, + + /* Various sizes to show that the bug allows buffers that are a quarter of a bucket too big. */ + { __LINE__, 8, 3, sizeof(ULONG), STATUS_ACCESS_VIOLATION }, + { __LINE__, 9, 3, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION }, + { __LINE__, 10, 3, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL }, + + { __LINE__, 16, 4, sizeof(ULONG), STATUS_ACCESS_VIOLATION }, + { __LINE__, 17, 4, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION }, + { __LINE__, 18, 4, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION }, + { __LINE__, 19, 4, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION }, + { __LINE__, 20, 4, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL }, + + { __LINE__, 32, 5, sizeof(ULONG), STATUS_ACCESS_VIOLATION }, + { __LINE__, 33, 5, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION }, + { __LINE__, 39, 5, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION }, + { __LINE__, 40, 5, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL }, + + { __LINE__, 256, 8, sizeof(ULONG), STATUS_ACCESS_VIOLATION }, + { __LINE__, 257, 8, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION }, + { __LINE__, 319, 8, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION }, + { __LINE__, 320, 8, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL }, + + { __LINE__, 256, 8, sizeof(ULONG), STATUS_ACCESS_VIOLATION }, + { __LINE__, 257, 8, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION }, + { __LINE__, 319, 8, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION }, + { __LINE__, 320, 8, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL }, + + { __LINE__, 0x80000000, 31, sizeof(ULONG), STATUS_ACCESS_VIOLATION }, + { __LINE__, 0x80000001, 31, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION }, + { __LINE__, 0xBFFFFFFF, 31, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION }, + { __LINE__, 0xA0000000, 31, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL }, + + /* Nothing checks against the max MDL size */ + { __LINE__, 3, 2, MAX_MDL_BUFFER_SIZE, STATUS_ACCESS_VIOLATION }, + { __LINE__, 3, 2, MAX_MDL_BUFFER_SIZE + 1, STATUS_ACCESS_VIOLATION }, + { __LINE__, 3, 2, (MAX_MDL_BUFFER_SIZE + 1) * 2, STATUS_ACCESS_VIOLATION }, + + }; + NTSTATUS Status; + ULONG i; + + for (i = 0; i < RTL_NUMBER_OF(Tests); i++) + { + Status = NtCreateProfile(NULL, + NULL, + (PVOID)(ULONG_PTR)0x10000, + Tests[i].RangeSize, + Tests[i].BucketSize, + NULL, + Tests[i].BufferSize, + ProfileTime, + 1); + if (Tests[i].BrokenStatus) + { + ok(Status == Tests[i].ExpectedStatus || + broken(Status == Tests[i].BrokenStatus), + "[L%d] For RangeSize 0x%Ix, BucketSize %lu, BufferSize %lu, expected 0x%lx, got 0x%lx\n", + Tests[i].Line, Tests[i].RangeSize, Tests[i].BucketSize, Tests[i].BufferSize, Tests[i].ExpectedStatus, Status); + } + else + { + ok(Status == Tests[i].ExpectedStatus, + "[L%d] For RangeSize 0x%Ix, BucketSize %lu, BufferSize %lu, expected 0x%lx, got 0x%lx\n", + Tests[i].Line, Tests[i].RangeSize, Tests[i].BucketSize, Tests[i].BufferSize, Tests[i].ExpectedStatus, Status); + } + } +} + +START_TEST(NtCreateProfile) +{ + IsWow64Process(GetCurrentProcess(), &IsWow64); + TestParameterValidation(); + TestBufferSizeValidation(); +} diff --git a/modules/rostests/apitests/ntdll/NtQueryInformationProcess.c b/modules/rostests/apitests/ntdll/NtQueryInformationProcess.c index 9469d4d492c06..43ac4c7f4240a 100644 --- a/modules/rostests/apitests/ntdll/NtQueryInformationProcess.c +++ b/modules/rostests/apitests/ntdll/NtQueryInformationProcess.c @@ -186,6 +186,345 @@ Test_ProcessTimes(void) #undef SPIN_TIME } +static +void +Test_ProcessBasicInformation(void) +{ + NTSTATUS Status; + ULONG Length; + PROCESS_BASIC_INFORMATION BasicInfo; + + /* Everything is NULL */ + Status = NtQueryInformationProcess(NULL, + ProcessBasicInformation, + NULL, + 0, + NULL); + ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH); + + /* Right size, invalid process handle */ + Status = NtQueryInformationProcess(NULL, + ProcessBasicInformation, + NULL, + sizeof(BasicInfo), + NULL); + ok_hex(Status, STATUS_INVALID_HANDLE); + + /* Valid process handle, no buffer */ + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessBasicInformation, + NULL, + 0, + NULL); + ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH); + + /* Unaligned buffer, wrong size */ + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessBasicInformation, + (PVOID)2, + 0, + NULL); + ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH); + + /* Unaligned buffer, correct size */ + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessBasicInformation, + (PVOID)2, + sizeof(BasicInfo), + NULL); + ok_hex(Status, STATUS_DATATYPE_MISALIGNMENT); + + /* Buffer too small */ + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessBasicInformation, + NULL, + sizeof(BasicInfo) - 1, + NULL); + ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH); + + /* Right buffer size but NULL pointer */ + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessBasicInformation, + NULL, + sizeof(BasicInfo), + NULL); + ok_hex(Status, STATUS_ACCESS_VIOLATION); + + /* Buffer too large */ + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessBasicInformation, + NULL, + sizeof(BasicInfo) + 1, + NULL); + ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH); + + /* Buffer too small, ask for length */ + Length = 0x55555555; + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessBasicInformation, + NULL, + sizeof(BasicInfo) - 1, + &Length); + ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH); + ok_dec(Length, 0x55555555); + + /* Valid parameters, no return length */ + RtlFillMemory(&BasicInfo, sizeof(BasicInfo), 0x55); + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessBasicInformation, + &BasicInfo, + sizeof(BasicInfo), + NULL); + ok_hex(Status, STATUS_SUCCESS); + + /* Trace the returned data (1) */ + trace("[1] BasicInfo.ExitStatus = %lx\n", BasicInfo.ExitStatus); + trace("[1] BasicInfo.PebBaseAddress = %p\n", BasicInfo.PebBaseAddress); + trace("[1] BasicInfo.AffinityMask = %Ix\n", BasicInfo.AffinityMask); + trace("[1] BasicInfo.BasePriority = %ld\n", BasicInfo.BasePriority); + trace("[1] BasicInfo.UniqueProcessId = %Iu\n", BasicInfo.UniqueProcessId); + trace("[1] BasicInfo.InheritedFromUniqueProcessId = %Iu\n", BasicInfo.InheritedFromUniqueProcessId); + + /* Again, this time with a return length */ + Length = 0x55555555; + RtlFillMemory(&BasicInfo, sizeof(BasicInfo), 0x55); + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessBasicInformation, + &BasicInfo, + sizeof(BasicInfo), + &Length); + ok_hex(Status, STATUS_SUCCESS); + ok_dec(Length, sizeof(BasicInfo)); + + /* Trace the returned data (2) */ + trace("[2] BasicInfo.ExitStatus = %lx\n", BasicInfo.ExitStatus); + trace("[2] BasicInfo.PebBaseAddress = %p\n", BasicInfo.PebBaseAddress); + trace("[2] BasicInfo.AffinityMask = %Ix\n", BasicInfo.AffinityMask); + trace("[2] BasicInfo.BasePriority = %ld\n", BasicInfo.BasePriority); + trace("[2] BasicInfo.UniqueProcessId = %Iu\n", BasicInfo.UniqueProcessId); + trace("[2] BasicInfo.InheritedFromUniqueProcessId = %Iu\n", BasicInfo.InheritedFromUniqueProcessId); +} + +static +void +Test_ProcessQuotaLimits(void) +{ + NTSTATUS Status; + ULONG Length; + QUOTA_LIMITS QuotaLimits; + + /* Everything is NULL */ + Status = NtQueryInformationProcess(NULL, + ProcessQuotaLimits, + NULL, + 0, + NULL); + ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH); + + /* Right size, invalid process handle */ + Status = NtQueryInformationProcess(NULL, + ProcessQuotaLimits, + NULL, + sizeof(QuotaLimits), + NULL); + ok_hex(Status, STATUS_INVALID_HANDLE); + + /* Valid process handle, no buffer */ + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessQuotaLimits, + NULL, + 0, + NULL); + ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH); + + /* Unaligned buffer, wrong size */ + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessQuotaLimits, + (PVOID)2, + 0, + NULL); + ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH); + + /* Unaligned buffer, correct size */ + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessQuotaLimits, + (PVOID)2, + sizeof(QuotaLimits), + NULL); + ok_hex(Status, STATUS_DATATYPE_MISALIGNMENT); + + /* Buffer too small */ + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessQuotaLimits, + NULL, + sizeof(QuotaLimits) - 1, + NULL); + ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH); + + /* Right buffer size but NULL pointer */ + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessQuotaLimits, + NULL, + sizeof(QuotaLimits), + NULL); + ok_hex(Status, STATUS_ACCESS_VIOLATION); + + /* Buffer too large */ + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessQuotaLimits, + NULL, + sizeof(QuotaLimits) + 1, + NULL); + ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH); + + /* Buffer too small, ask for length */ + Length = 0x55555555; + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessQuotaLimits, + NULL, + sizeof(QuotaLimits) - 1, + &Length); + ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH); + ok_dec(Length, 0x55555555); + + /* Valid parameters, no return length */ + RtlFillMemory(&QuotaLimits, sizeof(QuotaLimits), 0x55); + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessQuotaLimits, + &QuotaLimits, + sizeof(QuotaLimits), + NULL); + ok_hex(Status, STATUS_SUCCESS); + + /* Trace the returned data (1) */ + trace("[1] QuotaLimits.PagedPoolLimit = %Iu\n", QuotaLimits.PagedPoolLimit); + trace("[1] QuotaLimits.NonPagedPoolLimit = %Iu\n", QuotaLimits.NonPagedPoolLimit); + trace("[1] QuotaLimits.MinimumWorkingSetSize = %Iu\n", QuotaLimits.MinimumWorkingSetSize); + trace("[1] QuotaLimits.MaximumWorkingSetSize = %Iu\n", QuotaLimits.MaximumWorkingSetSize); + trace("[1] QuotaLimits.PagefileLimit = %Iu\n", QuotaLimits.PagefileLimit); + trace("[1] QuotaLimits.TimeLimit = %I64d\n", QuotaLimits.TimeLimit.QuadPart); + + /* Again, this time with a return length */ + Length = 0x55555555; + RtlFillMemory(&QuotaLimits, sizeof(QuotaLimits), 0x55); + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessQuotaLimits, + &QuotaLimits, + sizeof(QuotaLimits), + &Length); + ok_hex(Status, STATUS_SUCCESS); + ok_dec(Length, sizeof(QuotaLimits)); + + /* Trace the returned data (2) */ + trace("[2] QuotaLimits.PagedPoolLimit = %Iu\n", QuotaLimits.PagedPoolLimit); + trace("[2] QuotaLimits.NonPagedPoolLimit = %Iu\n", QuotaLimits.NonPagedPoolLimit); + trace("[2] QuotaLimits.MinimumWorkingSetSize = %Iu\n", QuotaLimits.MinimumWorkingSetSize); + trace("[2] QuotaLimits.MaximumWorkingSetSize = %Iu\n", QuotaLimits.MaximumWorkingSetSize); + trace("[2] QuotaLimits.PagefileLimit = %Iu\n", QuotaLimits.PagefileLimit); + trace("[2] QuotaLimits.TimeLimit = %I64d\n", QuotaLimits.TimeLimit.QuadPart); +} + +static +void +Test_ProcessQuotaLimitsEx(void) +{ + NTSTATUS Status; + ULONG Length; + QUOTA_LIMITS_EX QuotaLimitsEx; + + /* Right size, invalid process handle */ + Status = NtQueryInformationProcess(NULL, + ProcessQuotaLimits, + NULL, + sizeof(QuotaLimitsEx), + NULL); + ok_hex(Status, STATUS_INVALID_HANDLE); + + /* Unaligned buffer, correct size */ + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessQuotaLimits, + (PVOID)2, + sizeof(QuotaLimitsEx), + NULL); + ok_hex(Status, STATUS_DATATYPE_MISALIGNMENT); + + /* Buffer too small */ + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessQuotaLimits, + NULL, + sizeof(QuotaLimitsEx) - 1, + NULL); + ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH); + + /* Right buffer size but NULL pointer */ + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessQuotaLimits, + NULL, + sizeof(QuotaLimitsEx), + NULL); + ok_hex(Status, STATUS_ACCESS_VIOLATION); + + /* Buffer too large */ + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessQuotaLimits, + NULL, + sizeof(QuotaLimitsEx) + 1, + NULL); + ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH); + + /* Buffer too small, ask for length */ + Length = 0x55555555; + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessQuotaLimits, + NULL, + sizeof(QuotaLimitsEx) - 1, + &Length); + ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH); + ok_dec(Length, 0x55555555); + + /* Valid parameters, no return length */ + RtlFillMemory(&QuotaLimitsEx, sizeof(QuotaLimitsEx), 0x55); + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessQuotaLimits, + &QuotaLimitsEx, + sizeof(QuotaLimitsEx), + NULL); + ok_hex(Status, STATUS_SUCCESS); + + /* Trace the returned data (1) */ + trace("[1] QuotaLimitsEx.PagedPoolLimit = %Iu\n", QuotaLimitsEx.PagedPoolLimit); + trace("[1] QuotaLimitsEx.NonPagedPoolLimit = %Iu\n", QuotaLimitsEx.NonPagedPoolLimit); + trace("[1] QuotaLimitsEx.MinimumWorkingSetSize = %Iu\n", QuotaLimitsEx.MinimumWorkingSetSize); + trace("[1] QuotaLimitsEx.MaximumWorkingSetSize = %Iu\n", QuotaLimitsEx.MaximumWorkingSetSize); + trace("[1] QuotaLimitsEx.PagefileLimit = %Iu\n", QuotaLimitsEx.PagefileLimit); + trace("[1] QuotaLimitsEx.TimeLimit = %I64d\n", QuotaLimitsEx.TimeLimit.QuadPart); + //trace("[1] QuotaLimitsEx.WorkingSetLimit = %Iu\n", QuotaLimitsEx.WorkingSetLimit); // Not used on Win2k3 + trace("[1] QuotaLimitsEx.Flags = %lx\n", QuotaLimitsEx.Flags); + trace("[1] QuotaLimitsEx.CpuRateLimit.RateData = %lx\n", QuotaLimitsEx.CpuRateLimit.RateData); + + /* Again, this time with a return length */ + Length = 0x55555555; + RtlFillMemory(&QuotaLimitsEx, sizeof(QuotaLimitsEx), 0x55); + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessQuotaLimits, + &QuotaLimitsEx, + sizeof(QuotaLimitsEx), + &Length); + ok_hex(Status, STATUS_SUCCESS); + ok_dec(Length, sizeof(QuotaLimitsEx)); + + /* Trace the returned data (2) */ + trace("[2] QuotaLimitsEx.PagedPoolLimit = %Iu\n", QuotaLimitsEx.PagedPoolLimit); + trace("[2] QuotaLimitsEx.NonPagedPoolLimit = %Iu\n", QuotaLimitsEx.NonPagedPoolLimit); + trace("[2] QuotaLimitsEx.MinimumWorkingSetSize = %Iu\n", QuotaLimitsEx.MinimumWorkingSetSize); + trace("[2] QuotaLimitsEx.MaximumWorkingSetSize = %Iu\n", QuotaLimitsEx.MaximumWorkingSetSize); + trace("[2] QuotaLimitsEx.PagefileLimit = %Iu\n", QuotaLimitsEx.PagefileLimit); + trace("[2] QuotaLimitsEx.TimeLimit = %I64d\n", QuotaLimitsEx.TimeLimit.QuadPart); + //trace("[2] QuotaLimitsEx.WorkingSetLimit = %Iu\n", QuotaLimitsEx.WorkingSetLimit); // Not used on Win2k3 + trace("[2] QuotaLimitsEx.Flags = %lx\n", QuotaLimitsEx.Flags); + trace("[2] QuotaLimitsEx.CpuRateLimit.RateData = %lx\n", QuotaLimitsEx.CpuRateLimit.RateData); +} + static void Test_ProcessPriorityClassAlignment(void) @@ -376,6 +715,9 @@ START_TEST(NtQueryInformationProcess) ok_hex(Status, STATUS_SUCCESS); Test_ProcessTimes(); + Test_ProcessBasicInformation(); + Test_ProcessQuotaLimits(); + Test_ProcessQuotaLimitsEx(); Test_ProcessPriorityClassAlignment(); Test_ProcessWx86Information(); Test_ProcQueryAlignmentProbe(); diff --git a/modules/rostests/apitests/ntdll/NtQueryObject.c b/modules/rostests/apitests/ntdll/NtQueryObject.c new file mode 100644 index 0000000000000..8ee7157cfcdbf --- /dev/null +++ b/modules/rostests/apitests/ntdll/NtQueryObject.c @@ -0,0 +1,107 @@ +/* + * PROJECT: ReactOS API Tests + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Test for NtQueryObject + * COPYRIGHT: Copyright 2024 Hermès Bélusca-Maïto + */ + +#include "precomp.h" + +/* Flags combination allowing all the read, write and delete share modes. + * Currently similar to FILE_SHARE_VALID_FLAGS. */ +#define FILE_SHARE_ALL \ + (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE) + +/* Adapted from kmtests/ntos_ob/ObQuery.c!ObjectNameInformationTests(). + * Please sync both tests in case you add or remove new features. */ +START_TEST(NtQueryObject) +{ + ULONG g_OsVersion = + SharedUserData->NtMajorVersion << 8 | SharedUserData->NtMinorVersion; + + NTSTATUS Status; + HANDLE DeviceHandle; + UNICODE_STRING DeviceName; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + + ULONG BufferSize1, BufferSize2, BufferSize3; + struct { OBJECT_NAME_INFORMATION; WCHAR Buffer[MAX_PATH]; } ObjectNameBuffer; + PUNICODE_STRING ObjectName = &ObjectNameBuffer.Name; + + /* Test the drive containing SystemRoot */ + WCHAR NtDeviceName[] = L"\\DosDevices\\?:"; + NtDeviceName[sizeof("\\DosDevices\\")-1] = SharedUserData->NtSystemRoot[0]; + + /* Open a handle to the device */ + RtlInitUnicodeString(&DeviceName, NtDeviceName); + InitializeObjectAttributes(&ObjectAttributes, + &DeviceName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtOpenFile(&DeviceHandle, + FILE_READ_ATTRIBUTES | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_ALL, + FILE_SYNCHRONOUS_IO_NONALERT); + ok_ntstatus(Status, STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + { + skip("Device '%S': Opening failed\n", NtDeviceName); + return; + } + + /* Invoke ObjectNameInformation that retrieves the canonical device name */ + Status = NtQueryObject(DeviceHandle, + ObjectNameInformation, + &ObjectNameBuffer, + 0, + &BufferSize1); + ok_ntstatus(Status, STATUS_INFO_LENGTH_MISMATCH); + + Status = NtQueryObject(DeviceHandle, + ObjectNameInformation, + &ObjectNameBuffer, + sizeof(OBJECT_NAME_INFORMATION), + &BufferSize2); + ok_ntstatus(Status, STATUS_BUFFER_OVERFLOW); + + Status = NtQueryObject(DeviceHandle, + ObjectNameInformation, + &ObjectNameBuffer, + sizeof(ObjectNameBuffer), + &BufferSize3); + ok_ntstatus(Status, STATUS_SUCCESS); + + NtClose(DeviceHandle); + + /* Compare the returned buffer sizes */ + + /* The returned size behaviour changed (when NtQueryObject()'s + * input Length is zero) between Windows <= 2003 and Vista+ */ + if (g_OsVersion < _WIN32_WINNT_VISTA) + ok_eq_ulong(BufferSize1, (ULONG)sizeof(OBJECT_NAME_INFORMATION)); + else + ok_eq_ulong(BufferSize1, (ULONG)sizeof(OBJECT_NAME_INFORMATION) + ObjectName->MaximumLength); + + ok_eq_ulong(BufferSize2, BufferSize3); + ok_eq_ulong(BufferSize3, (ULONG)sizeof(OBJECT_NAME_INFORMATION) + ObjectName->MaximumLength); + + /* Test the name buffer */ + ok(ObjectName->Length > 0, "ObjectName->Length == %hu, expected > 0\n", ObjectName->Length); + ok_eq_uint(ObjectName->MaximumLength, ObjectName->Length + sizeof(WCHAR)); + ok(ObjectName->Buffer[ObjectName->Length / sizeof(WCHAR)] == UNICODE_NULL, + "UNICODE_NULL not found at end of ObjectName->Buffer\n"); + if (ObjectName->Buffer[ObjectName->Length / sizeof(WCHAR)] != UNICODE_NULL) + { + skip("ObjectName->Buffer string length check skipped\n"); + return; + } + /* Verify that ObjectName->Length doesn't count extra NUL-terminators */ + { + SIZE_T strLen = wcslen(ObjectName->Buffer) * sizeof(WCHAR); + ok_eq_size(strLen, (SIZE_T)ObjectName->Length); + } +} diff --git a/modules/rostests/apitests/ntdll/NtStartProfile.c b/modules/rostests/apitests/ntdll/NtStartProfile.c new file mode 100644 index 0000000000000..56f66eedd7d79 --- /dev/null +++ b/modules/rostests/apitests/ntdll/NtStartProfile.c @@ -0,0 +1,143 @@ +/* + * PROJECT: ReactOS API Tests + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Test for NtStartProfile + * COPYRIGHT: Copyright 2021 Thomas Faber (thomas.faber@reactos.org) + */ + +#include "precomp.h" +#include + +#define SIZEOF_MDL (5 * sizeof(PVOID) + 2 * sizeof(ULONG)) +typedef ULONG_PTR PFN_NUMBER; +/* Maximum size that can be described by an MDL on 2003 and earlier */ +#define MAX_MDL_BUFFER_SIZE ((MAXUSHORT - SIZEOF_MDL) / sizeof(PFN_NUMBER) * PAGE_SIZE + PAGE_SIZE - 1) + +static BOOL IsWow64; +static KAFFINITY SystemAffinityMask; +static ULONG DummyBuffer[4096]; + +/* The "Buffer[Offset]++;" should likely be within 128 bytes of the start + * of the function on any architecture we support + */ +#define LOOP_FUNCTION_SIZE_SHIFT 7 +#define LOOP_FUNCTION_SIZE (1UL << LOOP_FUNCTION_SIZE_SHIFT) +C_ASSERT(LOOP_FUNCTION_SIZE == 128); +typedef void LOOP_FUNCTION(volatile ULONG *, ULONG, ULONG); +static +void +LoopFunction( + _Inout_updates_all_(BufferSize) volatile ULONG *Buffer, + _In_ ULONG BufferSizeInElements, + _In_ ULONG LoopCount) +{ + ULONG i; + ULONG Offset; + + for (i = 0; i < LoopCount; i++) + { + for (Offset = 0; Offset < BufferSizeInElements; Offset++) + { + Buffer[Offset]++; + } + } +} + +static +void +ProfileLoopFunction( + _In_ LOOP_FUNCTION *Function, + _Out_writes_bytes_(BufferSize) PULONG Buffer, + _In_ ULONG BufferSize, + _In_range_(0, BufferSize / sizeof(ULONG)) ULONG BufferOffset + ) +{ + NTSTATUS Status; + HANDLE ProfileHandle; + ULONG Buffer1Value; + + Status = NtCreateProfile(&ProfileHandle, + NtCurrentProcess(), + (PVOID)((ULONG_PTR)Function - LOOP_FUNCTION_SIZE), + 3 * LOOP_FUNCTION_SIZE, + LOOP_FUNCTION_SIZE_SHIFT, + Buffer, + BufferSize, + ProfileTime, + SystemAffinityMask); + ok_hex(Status, STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + { + skip("Failed to create profile\n"); + return; + } + + Status = NtStartProfile(ProfileHandle); + ok_hex(Status, STATUS_SUCCESS); + + /* Can't validate Buffer contents here, since we don't know what's next to our function */ + + /* + * This takes around 10-12 seconds on my machine, which is not ideal. + * But on my Win2003 VM it only results in counts of 10-12, + * which means we can't really make it shorter. + */ + + /* Run a long loop */ + Function(DummyBuffer, + RTL_NUMBER_OF(DummyBuffer), + 1000000); + + /* The buffer should get live updates */ + Buffer1Value = Buffer[BufferOffset]; + ok(Buffer1Value != 0, "Buffer[%lu] = %lu\n", BufferOffset, Buffer1Value); + + /* Run a shorter loop, we should see a smaller increase */ + Function(DummyBuffer, + RTL_NUMBER_OF(DummyBuffer), + 200000); + + ok(Buffer[BufferOffset] > Buffer1Value, + "Buffer[%lu] = %lu, expected more than %lu\n", + BufferOffset, Buffer[BufferOffset], Buffer1Value); + + Status = NtStopProfile(ProfileHandle); + ok_hex(Status, STATUS_SUCCESS); + + /* The expectation is that Buffer[BufferOffset] is somewhere around 20% larger than Buffer1Value. + * Allow anywhere from one more count to twice as many to make the test robust. + */ + ok(Buffer[BufferOffset] > Buffer1Value, + "Buffer[%lu] = %lu, expected more than %lu\n", BufferOffset, Buffer[BufferOffset], Buffer1Value); + ok(Buffer[BufferOffset] < 2 * Buffer1Value, + "Buffer[%lu] = %lu, expected less than %lu\n", BufferOffset, Buffer[BufferOffset], 2 * Buffer1Value); + + trace("Buffer1Value = %lu\n", Buffer1Value); + trace("Buffer[%lu] = %lu\n", BufferOffset - 1, Buffer[BufferOffset - 1]); + trace("Buffer[%lu] = %lu\n", BufferOffset, Buffer[BufferOffset]); + trace("Buffer[%lu] = %lu\n", BufferOffset + 1, Buffer[BufferOffset + 1]); + + Status = NtClose(ProfileHandle); + ok_hex(Status, STATUS_SUCCESS); +} + +START_TEST(NtStartProfile) +{ + NTSTATUS Status; + ULONG StackBuffer[3] = { 0 }; + DWORD_PTR ProcessAffinityMask; + + IsWow64Process(GetCurrentProcess(), &IsWow64); + + GetProcessAffinityMask(GetCurrentProcess(), &ProcessAffinityMask, &SystemAffinityMask); + + /* Parameter validation is pretty simple... */ + Status = NtStartProfile(NULL); + ok_hex(Status, STATUS_INVALID_HANDLE); + + /* Do an actual simple profile */ + ProfileLoopFunction(LoopFunction, + StackBuffer, + sizeof(StackBuffer), + 1); +} diff --git a/modules/rostests/apitests/ntdll/RtlDosSearchPath_Ustr.c b/modules/rostests/apitests/ntdll/RtlDosSearchPath_Ustr.c index 29794bf4e8d16..e6eb386cc297c 100644 --- a/modules/rostests/apitests/ntdll/RtlDosSearchPath_Ustr.c +++ b/modules/rostests/apitests/ntdll/RtlDosSearchPath_Ustr.c @@ -210,4 +210,23 @@ START_TEST(RtlDosSearchPath_Ustr) ok_eq_pointer(FullNameOut, NULL); ok_eq_ulong(FilePartSize, 0UL); ok_eq_ulong(LengthNeeded, 0UL); + + /* Buffer overflow test + * length(longDirName) + length(longFileName) + length(ext) = MAX_PATH + */ + RtlInitUnicodeString(&PathString, L"C:\\Program Files\\Very_long_test_path_which_can_trigger_heap_overflow_test_1234567890______________________________________________________AB"); + RtlInitUnicodeString(&FileNameString, L"this_is_long_file_name_for_checking______________________________________________________________________________CD"); + RtlInitUnicodeString(&ExtensionString, L".txt"); + StartSeh() + Status = RtlDosSearchPath_Ustr(0, + &PathString, + &FileNameString, + &ExtensionString, + &CallerBuffer, + &DynamicString, + &FullNameOut, + &FilePartSize, + &LengthNeeded); + ok_eq_hex(Status, STATUS_NO_SUCH_FILE); + EndSeh(STATUS_SUCCESS); } diff --git a/modules/rostests/apitests/ntdll/RtlGetNtProductType.c b/modules/rostests/apitests/ntdll/RtlGetNtProductType.c index 03ac8238e0710..29051810ec28b 100644 --- a/modules/rostests/apitests/ntdll/RtlGetNtProductType.c +++ b/modules/rostests/apitests/ntdll/RtlGetNtProductType.c @@ -91,7 +91,7 @@ ChangeNtProductType(DWORD NtProductType) } else { - ok(FALSE, "Passed invalid product type to CHangeNtProduct: %lu", NtProductType); + ok(FALSE, "Passed invalid product type to ChangeNtProduct: %lu", NtProductType); } Result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, @@ -129,6 +129,19 @@ START_TEST(RtlGetNtProductType) DWORD ProductNtType; NT_PRODUCT_TYPE ProductType = NtProductWinNt, ProductType2; + /* Remove ReportAsWorkstation override during tests */ + DWORD ReportAsWorkstation = 0xbaadf00d; + HKEY hKey; + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\ReactOS\\Settings\\Version", + 0, KEY_READ | KEY_WRITE, &hKey) == ERROR_SUCCESS) + { + DWORD cb = sizeof(DWORD); + if (RegQueryValueExW(hKey, L"ReportAsWorkstation", NULL, NULL, (PBYTE)&ReportAsWorkstation, &cb)) + ReportAsWorkstation = 0xbaadf00d; + RegDeleteValueW(hKey, L"ReportAsWorkstation"); + RegCloseKey(hKey); + } + /* * Wrap the call in SEH. This ensures the testcase won't crash but also * it proves to us that RtlGetNtProductType() throws an exception if a NULL @@ -164,4 +177,14 @@ START_TEST(RtlGetNtProductType) ok_long(ProductType2, ProductType); ok_char(ChangeNtProductType(ProductType), TRUE); + + + /* Restore ReportAsWorkstation */ + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\ReactOS\\Settings\\Version", + 0, KEY_WRITE, &hKey) == ERROR_SUCCESS) + { + if (ReportAsWorkstation != 0xbaadf00d) + RegSetValueExW(hKey, L"ReportAsWorkstation", 0, REG_DWORD, (PBYTE)&ReportAsWorkstation, sizeof(DWORD)); + RegCloseKey(hKey); + } } diff --git a/modules/rostests/apitests/ntdll/RtlLocale.c b/modules/rostests/apitests/ntdll/RtlLocale.c new file mode 100644 index 0000000000000..fde82c7e123d5 --- /dev/null +++ b/modules/rostests/apitests/ntdll/RtlLocale.c @@ -0,0 +1,1038 @@ +/* + * PROJECT: ReactOS api tests + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: Tests for Rtl LCID functions + * COPYRIGHT: Copyright 2025 Timo Kreuzer + */ + +#include "precomp.h" +#include + +typedef +NTSTATUS +NTAPI +FN_RtlConvertLCIDToString( + _In_ LCID LcidValue, + _In_ ULONG Base, + _In_ ULONG Padding, + _Out_writes_(Size) PWSTR pResultBuf, + _In_ ULONG Size); + +typedef +BOOLEAN +NTAPI +FN_RtlCultureNameToLCID( + _In_ PUNICODE_STRING String, + _Out_ PLCID Lcid); + +typedef +BOOLEAN +NTAPI +FN_RtlLCIDToCultureName( + _In_ LCID Lcid, + _Inout_ PUNICODE_STRING String); + +typedef +NTSTATUS +NTAPI +FN_RtlLcidToLocaleName( + _In_ LCID Lcid, + _Inout_ PUNICODE_STRING LocaleName, + _In_ ULONG Flags, + _In_ BOOLEAN AllocateDestinationString); + +typedef +NTSTATUS +NTAPI +FN_RtlLocaleNameToLcid( + _In_ PWSTR LocaleName, + _Out_ PLCID Lcid, + _In_ ULONG Flags); + +FN_RtlConvertLCIDToString* pRtlConvertLCIDToString; +FN_RtlCultureNameToLCID* pRtlCultureNameToLCID; +FN_RtlLCIDToCultureName* pRtlLCIDToCultureName; +FN_RtlLcidToLocaleName* pRtlLcidToLocaleName; +FN_RtlLocaleNameToLcid* pRtlLocaleNameToLcid; + +#define FL_LOCALE 0x00000001 +#define FL_CULTURE 0x00000002 +#define FL_BOTH 0x00000003 +#define FL_ALT_NAME 0x00000004 + +typedef struct _LCID_TEST_ENTRY +{ + ULONG Line; + LCID Lcid; + PCWSTR CultureName; + ULONG Flags; +} LCID_TEST_ENTRY; + +#define TEST(Lcid, CultureName, Flags) { __LINE__, Lcid, CultureName, Flags } + +// +// For documentation see https://winprotocoldoc.z19.web.core.windows.net/MS-LCID/%5bMS-LCID%5d.pdf +// The comments are based on the comments in the document, they might not apply in all cases. +// +static LCID_TEST_ENTRY Tests[] = +{ + TEST(0x0000, NULL, 0), + TEST(0x0001, L"ar", FL_CULTURE), + TEST(0x0002, L"bg", FL_CULTURE), + TEST(0x0003, L"ca", FL_CULTURE), + TEST(0x0004, L"zh-Hans", FL_CULTURE), + TEST(0x0005, L"cs", FL_CULTURE), + TEST(0x0006, L"da", FL_CULTURE), + TEST(0x0007, L"de", FL_CULTURE), + TEST(0x0008, L"el", FL_CULTURE), + TEST(0x0009, L"en", FL_CULTURE), + TEST(0x000A, L"es", FL_CULTURE), + TEST(0x000B, L"fi", FL_CULTURE), + TEST(0x000C, L"fr", FL_CULTURE), + TEST(0x000D, L"he", FL_CULTURE), + TEST(0x000E, L"hu", FL_CULTURE), + TEST(0x000F, L"is", FL_CULTURE), + TEST(0x0010, L"it", FL_CULTURE), + TEST(0x0011, L"ja", FL_CULTURE), + TEST(0x0012, L"ko", FL_CULTURE), + TEST(0x0013, L"nl", FL_CULTURE), + TEST(0x0014, L"no", FL_CULTURE), + TEST(0x0015, L"pl", FL_CULTURE), + TEST(0x0016, L"pt", FL_CULTURE), + TEST(0x0017, L"rm", FL_CULTURE), + TEST(0x0018, L"ro", FL_CULTURE), + TEST(0x0019, L"ru", FL_CULTURE), + TEST(0x001A, L"hr", FL_CULTURE), + TEST(0x001B, L"sk", FL_CULTURE), + TEST(0x001C, L"sq", FL_CULTURE), + TEST(0x001D, L"sv", FL_CULTURE), + TEST(0x001E, L"th", FL_CULTURE), + TEST(0x001F, L"tr", FL_CULTURE), + TEST(0x0020, L"ur", FL_CULTURE), + TEST(0x0021, L"id", FL_CULTURE), + TEST(0x0022, L"uk", FL_CULTURE), + TEST(0x0023, L"be", FL_CULTURE), + TEST(0x0024, L"sl", FL_CULTURE), + TEST(0x0025, L"et", FL_CULTURE), + TEST(0x0026, L"lv", FL_CULTURE), + TEST(0x0027, L"lt", FL_CULTURE), + TEST(0x0028, L"tg", FL_CULTURE), + TEST(0x0029, L"fa", FL_CULTURE), + TEST(0x002A, L"vi", FL_CULTURE), + TEST(0x002B, L"hy", FL_CULTURE), + TEST(0x002C, L"az", FL_CULTURE), + TEST(0x002D, L"eu", FL_CULTURE), + TEST(0x002E, L"hsb", FL_CULTURE), + TEST(0x002F, L"mk", FL_CULTURE), + TEST(0x0030, L"st", FL_CULTURE), + TEST(0x0031, L"ts", FL_CULTURE), + TEST(0x0032, L"tn", FL_CULTURE), + TEST(0x0033, L"ve", FL_CULTURE), + TEST(0x0034, L"xh", FL_CULTURE), + TEST(0x0035, L"zu", FL_CULTURE), + TEST(0x0036, L"af", FL_CULTURE), + TEST(0x0037, L"ka", FL_CULTURE), + TEST(0x0038, L"fo", FL_CULTURE), + TEST(0x0039, L"hi", FL_CULTURE), + TEST(0x003A, L"mt", FL_CULTURE), + TEST(0x003B, L"se", FL_CULTURE), + TEST(0x003C, L"ga", FL_CULTURE), + TEST(0x003D, L"yi", FL_CULTURE), // reserved + TEST(0x003E, L"ms", FL_CULTURE), + TEST(0x003F, L"kk", FL_CULTURE), + TEST(0x003F, L"Kk-Cyrl", FL_CULTURE | FL_ALT_NAME), // reserved, see LCID 0x783F + TEST(0x0040, L"ky", FL_CULTURE), + TEST(0x0041, L"sw", FL_CULTURE), + TEST(0x0042, L"tk", FL_CULTURE), + TEST(0x0043, L"uz", FL_CULTURE), + TEST(0x0044, L"tt", FL_CULTURE), + TEST(0x0045, L"bn", FL_CULTURE), + TEST(0x0046, L"pa", FL_CULTURE), + TEST(0x0047, L"gu", FL_CULTURE), + TEST(0x0048, L"or", FL_CULTURE), + TEST(0x0049, L"ta", FL_CULTURE), + TEST(0x004A, L"te", FL_CULTURE), + TEST(0x004B, L"kn", FL_CULTURE), + TEST(0x004C, L"ml", FL_CULTURE), + TEST(0x004D, L"as", FL_CULTURE), + TEST(0x004E, L"mr", FL_CULTURE), + TEST(0x004F, L"sa", FL_CULTURE), + TEST(0x0050, L"mn", FL_CULTURE), + TEST(0x0051, L"bo", FL_CULTURE), + TEST(0x0052, L"cy", FL_CULTURE), + TEST(0x0053, L"km", FL_CULTURE), + TEST(0x0054, L"lo", FL_CULTURE), + TEST(0x0055, L"my", FL_CULTURE), + TEST(0x0056, L"gl", FL_CULTURE), + TEST(0x0057, L"kok", FL_CULTURE), + TEST(0x0058, L"mni", FL_CULTURE), // reserved + TEST(0x0059, L"sd", FL_CULTURE), + TEST(0x005A, L"syr", FL_CULTURE), + TEST(0x005B, L"si", FL_CULTURE), + TEST(0x005C, L"chr", FL_CULTURE), + TEST(0x005D, L"iu", FL_CULTURE), + TEST(0x005E, L"am", FL_CULTURE), + TEST(0x005F, L"tzm", FL_CULTURE), + TEST(0x0060, L"ks", FL_CULTURE), + TEST(0x0061, L"ne", FL_CULTURE), + TEST(0x0062, L"fy", FL_CULTURE), + TEST(0x0063, L"ps", FL_CULTURE), + TEST(0x0064, L"fil", FL_CULTURE), + TEST(0x0065, L"dv", FL_CULTURE), + TEST(0x0066, L"bin", FL_CULTURE), // reserved + TEST(0x0067, L"ff", FL_CULTURE), + TEST(0x0068, L"ha", FL_CULTURE), + TEST(0x0069, L"ibb", FL_CULTURE), // reserved + TEST(0x006A, L"yo", FL_CULTURE), + TEST(0x006B, L"quz", FL_CULTURE), + TEST(0x006C, L"nso", FL_CULTURE), + TEST(0x006D, L"ba", FL_CULTURE), + TEST(0x006E, L"lb", FL_CULTURE), + TEST(0x006F, L"kl", FL_CULTURE), + TEST(0x0070, L"ig", FL_CULTURE), + TEST(0x0071, L"kr", FL_CULTURE), // reserved + TEST(0x0072, L"om", FL_CULTURE), + TEST(0x0073, L"ti", FL_CULTURE), + TEST(0x0074, L"gn", FL_CULTURE), + TEST(0x0075, L"haw", FL_CULTURE), + TEST(0x0076, L"la", FL_CULTURE), // reserved + TEST(0x0077, L"so", FL_CULTURE), // reserved + TEST(0x0078, L"ii", FL_CULTURE), + TEST(0x0079, L"pap", FL_CULTURE), // reserved + TEST(0x007A, L"arn", FL_CULTURE), + TEST(0x007B, NULL, 0), // Neither defined nor reserved + TEST(0x007C, L"moh", FL_CULTURE), + TEST(0x007D, NULL, 0), // Neither defined nor reserved + TEST(0x007E, L"br", FL_CULTURE), + //TEST(0x007F, L"", FL_BOTH), // CULTURE_INVARIANT + TEST(0x0080, L"ug", FL_CULTURE), + TEST(0x0081, L"mi", FL_CULTURE), + TEST(0x0082, L"oc", FL_CULTURE), + TEST(0x0083, L"co", FL_CULTURE), + TEST(0x0084, L"gsw", FL_CULTURE), + TEST(0x0085, L"sah", FL_CULTURE), + TEST(0x0086, L"quc", FL_CULTURE), // Doc says qut, see LCID 0x0093 + TEST(0x0086, L"qut", FL_CULTURE | FL_ALT_NAME), + TEST(0x0087, L"rw", FL_CULTURE), + TEST(0x0088, L"wo", FL_CULTURE), + TEST(0x0089, NULL, 0), // Neither defined nor reserved + TEST(0x008A, NULL, 0), // Neither defined nor reserved + TEST(0x008B, NULL, 0), // Neither defined nor reserved + TEST(0x008C, L"prs", FL_CULTURE), + TEST(0x008D, NULL, 0), // Neither defined nor reserved + TEST(0x008E, NULL, 0), // Neither defined nor reserved + TEST(0x008F, NULL, 0), // Neither defined nor reserved + TEST(0x0090, NULL, 0), // Neither defined nor reserved + TEST(0x0091, L"gd", FL_CULTURE), + TEST(0x0092, L"ku", FL_CULTURE), + TEST(0x0093, NULL, 0), // reserved, quc, see LCID 0x0086 + TEST(0x0401, L"ar-SA", FL_BOTH), + TEST(0x0402, L"bg-BG", FL_BOTH), + TEST(0x0403, L"ca-ES", FL_BOTH), + TEST(0x0404, L"zh-TW", FL_BOTH), + TEST(0x0405, L"cs-CZ", FL_BOTH), + TEST(0x0406, L"da-DK", FL_BOTH), + TEST(0x0407, L"de-DE", FL_BOTH), + TEST(0x0408, L"el-GR", FL_BOTH), + TEST(0x0409, L"en-US", FL_BOTH), + TEST(0x040A, L"es-ES_tradnl", FL_BOTH), + TEST(0x040B, L"fi-FI", FL_BOTH), + TEST(0x040C, L"fr-FR", FL_BOTH), + TEST(0x040D, L"he-IL", FL_BOTH), + TEST(0x040E, L"hu-HU", FL_BOTH), + TEST(0x040F, L"is-IS", FL_BOTH), + TEST(0x0410, L"it-IT", FL_BOTH), + TEST(0x0411, L"ja-JP", FL_BOTH), + TEST(0x0412, L"ko-KR", FL_BOTH), + TEST(0x0413, L"nl-NL", FL_BOTH), + TEST(0x0414, L"nb-NO", FL_BOTH), + TEST(0x0415, L"pl-PL", FL_BOTH), + TEST(0x0416, L"pt-BR", FL_BOTH), + TEST(0x0417, L"rm-CH", FL_BOTH), + TEST(0x0418, L"ro-RO", FL_BOTH), + TEST(0x0419, L"ru-RU", FL_BOTH), + TEST(0x041A, L"hr-HR", FL_BOTH), + TEST(0x041B, L"sk-SK", FL_BOTH), + TEST(0x041C, L"sq-AL", FL_BOTH), + TEST(0x041D, L"sv-SE", FL_BOTH), + TEST(0x041E, L"th-TH", FL_BOTH), + TEST(0x041F, L"tr-TR", FL_BOTH), + TEST(0x0420, L"ur-PK", FL_BOTH), + TEST(0x0421, L"id-ID", FL_BOTH), + TEST(0x0422, L"uk-UA", FL_BOTH), + TEST(0x0423, L"be-BY", FL_BOTH), + TEST(0x0424, L"sl-SI", FL_BOTH), + TEST(0x0425, L"et-EE", FL_BOTH), + TEST(0x0426, L"lv-LV", FL_BOTH), + TEST(0x0427, L"lt-LT", FL_BOTH), + TEST(0x0428, L"tg-Cyrl-TJ", FL_BOTH), + TEST(0x0429, L"fa-IR", FL_BOTH), + TEST(0x042A, L"vi-VN", FL_BOTH), + TEST(0x042B, L"hy-AM", FL_BOTH), + TEST(0x042C, L"az-Latn-AZ", FL_BOTH), + TEST(0x042D, L"eu-ES", FL_BOTH), + TEST(0x042E, L"hsb-DE", FL_BOTH), + TEST(0x042F, L"mk-MK", FL_BOTH), + TEST(0x0430, L"st-ZA", FL_BOTH), + TEST(0x0431, L"ts-ZA", FL_BOTH), + TEST(0x0432, L"tn-ZA", FL_BOTH), + TEST(0x0433, L"ve-ZA", FL_BOTH), + TEST(0x0434, L"xh-ZA", FL_BOTH), + TEST(0x0435, L"zu-ZA", FL_BOTH), + TEST(0x0436, L"af-ZA", FL_BOTH), + TEST(0x0437, L"ka-GE", FL_BOTH), + TEST(0x0438, L"fo-FO", FL_BOTH), + TEST(0x0439, L"hi-IN", FL_BOTH), + TEST(0x043A, L"mt-MT", FL_BOTH), + TEST(0x043B, L"se-NO", FL_BOTH), + TEST(0x043D, L"yi-001", FL_BOTH), + TEST(0x043E, L"ms-MY", FL_BOTH), + TEST(0x043F, L"kk-KZ", FL_BOTH), + TEST(0x0440, L"ky-KG", FL_BOTH), + TEST(0x0441, L"sw-KE", FL_BOTH), + TEST(0x0442, L"tk-TM", FL_BOTH), + TEST(0x0443, L"uz-Latn-UZ", FL_BOTH), + TEST(0x0444, L"tt-RU", FL_BOTH), + TEST(0x0445, L"bn-IN", FL_BOTH), + TEST(0x0446, L"pa-IN", FL_BOTH), + TEST(0x0447, L"gu-IN", FL_BOTH), + TEST(0x0448, L"or-IN", FL_BOTH), + TEST(0x0449, L"ta-IN", FL_BOTH), + TEST(0x044A, L"te-IN", FL_BOTH), + TEST(0x044B, L"kn-IN", FL_BOTH), + TEST(0x044C, L"ml-IN", FL_BOTH), + TEST(0x044D, L"as-IN", FL_BOTH), + TEST(0x044E, L"mr-IN", FL_BOTH), + TEST(0x044F, L"sa-IN", FL_BOTH), + TEST(0x0450, L"mn-MN", FL_BOTH), + TEST(0x0451, L"bo-CN", FL_BOTH), + TEST(0x0452, L"cy-GB", FL_BOTH), + TEST(0x0453, L"km-KH", FL_BOTH), + TEST(0x0454, L"lo-LA", FL_BOTH), + TEST(0x0455, L"my-MM", FL_BOTH), + TEST(0x0456, L"gl-ES", FL_BOTH), + TEST(0x0457, L"kok-IN", FL_BOTH), + TEST(0x0458, L"mni-IN", FL_BOTH), // reserved + TEST(0x0459, L"sd-Deva-IN", FL_BOTH), // reserved + TEST(0x045A, L"syr-SY", FL_BOTH), + TEST(0x045B, L"si-LK", FL_BOTH), + TEST(0x045C, L"chr-Cher-US", FL_BOTH), + TEST(0x045D, L"iu-Cans-CA", FL_BOTH), + TEST(0x045E, L"am-ET", FL_BOTH), + TEST(0x045F, L"tzm-Arab-MA", FL_BOTH), + TEST(0x0460, L"ks-Arab", FL_CULTURE), + TEST(0x0461, L"ne-NP", FL_BOTH), + TEST(0x0462, L"fy-NL", FL_BOTH), + TEST(0x0463, L"ps-AF", FL_BOTH), + TEST(0x0464, L"fil-PH", FL_BOTH), + TEST(0x0465, L"dv-MV", FL_BOTH), + TEST(0x0466, L"bin-NG", FL_BOTH), // reserved + TEST(0x0467, L"ff-Latn-NG", FL_BOTH), + TEST(0x0467, L"ff-NG", FL_BOTH | FL_ALT_NAME), + TEST(0x0468, L"ha-Latn-NG", FL_BOTH), + TEST(0x0469, L"ibb-NG", FL_BOTH), // reserved + TEST(0x046A, L"yo-NG", FL_BOTH), + TEST(0x046B, L"quz-BO", FL_BOTH), + TEST(0x046C, L"nso-ZA", FL_BOTH), + TEST(0x046D, L"ba-RU", FL_BOTH), + TEST(0x046E, L"lb-LU", FL_BOTH), + TEST(0x046F, L"kl-GL", FL_BOTH), + TEST(0x0470, L"ig-NG", FL_BOTH), + TEST(0x0471, L"kr-Latn-NG", FL_BOTH), + TEST(0x0472, L"om-ET", FL_BOTH), + TEST(0x0473, L"ti-ET", FL_BOTH), + TEST(0x0474, L"gn-PY", FL_BOTH), + TEST(0x0475, L"haw-US", FL_BOTH), + TEST(0x0476, L"la-001", FL_BOTH), // Doc says la-VA + TEST(0x0477, L"so-SO", FL_BOTH), + TEST(0x0478, L"ii-CN", FL_BOTH), + TEST(0x0479, L"pap-029", FL_BOTH), // reserved + TEST(0x047A, L"arn-CL", FL_BOTH), + TEST(0x047C, L"moh-CA", FL_BOTH), + TEST(0x047E, L"br-FR", FL_BOTH), + TEST(0x0480, L"ug-CN", FL_BOTH), + TEST(0x0481, L"mi-NZ", FL_BOTH), + TEST(0x0482, L"oc-FR", FL_BOTH), + TEST(0x0483, L"co-FR", FL_BOTH), + TEST(0x0484, L"gsw-FR", FL_BOTH), + TEST(0x0485, L"sah-RU", FL_BOTH), + TEST(0x0486, L"quc-Latn-GT", FL_BOTH), // reserved, Doc says qut-GT + TEST(0x0486, L"qut-GT", FL_BOTH | FL_ALT_NAME), + TEST(0x0487, L"rw-RW", FL_BOTH), + TEST(0x0488, L"wo-SN", FL_BOTH), + TEST(0x048C, L"prs-AF", FL_BOTH), + TEST(0x048D, L"plt-MG", 0), // reserved, plt-MG + TEST(0x048E, L"zh-yue-HK", 0), // reserved, zh-yue-HK + TEST(0x048F, L"tdd-Tale-CN", 0), // reserved, tdd-Tale-CN + TEST(0x0490, L"khb-Talu-CN", 0), // reserved, khb-Talu-CN + TEST(0x0491, L"gd-GB", FL_BOTH), + TEST(0x0492, L"ku-Arab-IQ", FL_BOTH), + TEST(0x0493, L"khb-Talu-CN", 0), // reserved, quc-CO + //TEST(0x0501, L"qps-ploc", FL_BOTH), // Needs special handling + TEST(0x05FE, L"qps-ploca", FL_BOTH), + TEST(0x0801, L"ar-IQ", FL_BOTH), + TEST(0x0803, L"ca-ES-valencia", FL_BOTH), + TEST(0x0804, L"zh-CN", FL_BOTH), + TEST(0x0807, L"de-CH", FL_BOTH), + TEST(0x0809, L"en-GB", FL_BOTH), + TEST(0x080A, L"es-MX", FL_BOTH), + TEST(0x080C, L"fr-BE", FL_BOTH), + TEST(0x0810, L"it-CH", FL_BOTH), + TEST(0x0811, L"ja-Ploc-JP", 0), // reserved, ja-Ploc-JP + TEST(0x0813, L"nl-BE", FL_BOTH), + TEST(0x0814, L"nn-NO", FL_BOTH), + TEST(0x0816, L"pt-PT", FL_BOTH), + TEST(0x0818, L"ro-MD", FL_BOTH), + TEST(0x0819, L"ru-MD", FL_BOTH), + TEST(0x081A, L"sr-Latn-CS", FL_BOTH), + TEST(0x081D, L"sv-FI", FL_BOTH), + TEST(0x0820, L"ur-IN", FL_BOTH), + TEST(0x0827, NULL, 0), // Neither defined nor reserved + TEST(0x082C, L"az-Cyrl-AZ", FL_BOTH), // reserved + TEST(0x082E, L"dsb-DE", FL_BOTH), + TEST(0x0832, L"tn-BW", FL_BOTH), + TEST(0x083B, L"se-SE", FL_BOTH), + TEST(0x083C, L"ga-IE", FL_BOTH), + TEST(0x083E, L"ms-BN", FL_BOTH), + TEST(0x083F, NULL, 0), // reserved, kk-Latn-KZ + TEST(0x0843, L"uz-Cyrl-UZ", FL_BOTH), // reserved + TEST(0x0845, L"bn-BD", FL_BOTH), + TEST(0x0846, L"pa-Arab-PK", FL_BOTH), + TEST(0x0849, L"ta-LK", FL_BOTH), + TEST(0x0850, L"mn-Mong-CN", FL_BOTH), // reserved + TEST(0x0851, NULL, 0), // reserved, bo-BT, + TEST(0x0859, L"sd-Arab-PK", FL_BOTH), + TEST(0x085D, L"iu-Latn-CA", FL_BOTH), + TEST(0x085F, L"tzm-Latn-DZ", FL_BOTH), + TEST(0x0860, L"ks-Deva-IN", FL_BOTH), + TEST(0x0861, L"ne-IN", FL_BOTH), + TEST(0x0867, L"ff-Latn-SN", FL_BOTH), + TEST(0x086B, L"quz-EC", FL_BOTH), + TEST(0x0873, L"ti-ER", FL_BOTH), + TEST(0x09FF, L"qps-plocm", FL_BOTH), + //TEST(0x0C00, NULL, 0),// Locale without assigned LCID if the current user default locale. See section 2.2.1. + TEST(0x0C01, L"ar-EG", FL_BOTH), + TEST(0x0C04, L"zh-HK", FL_BOTH), + TEST(0x0C07, L"de-AT", FL_BOTH), + TEST(0x0C09, L"en-AU", FL_BOTH), + TEST(0x0C0A, L"es-ES", FL_BOTH), + TEST(0x0C0C, L"fr-CA", FL_BOTH), + TEST(0x0C1A, L"sr-Cyrl-CS", FL_BOTH), + TEST(0x0C3B, L"se-FI", FL_BOTH), + TEST(0x0C50, L"mn-Mong-MN", FL_BOTH), + TEST(0x0C51, L"dz-BT", FL_BOTH), + TEST(0x0C5F, L"Tmz-MA", 0), // reserved, Tmz-MA + TEST(0x0C6b, L"quz-PE", FL_BOTH), + TEST(0x1000, NULL, 0), // Locale without assigned LCID if the current user default locale. See section 2.2.1. + TEST(0x1001, L"ar-LY", FL_BOTH), + TEST(0x1004, L"zh-SG", FL_BOTH), + TEST(0x1007, L"de-LU", FL_BOTH), + TEST(0x1009, L"en-CA", FL_BOTH), + TEST(0x100A, L"es-GT", FL_BOTH), + TEST(0x100C, L"fr-CH", FL_BOTH), + TEST(0x101A, L"hr-BA", FL_BOTH), + TEST(0x103B, L"smj-NO", FL_BOTH), + TEST(0x105F, L"tzm-Tfng-MA", FL_BOTH), + //TEST(0x1400, NULL, 0), + TEST(0x1401, L"ar-DZ", FL_BOTH), + TEST(0x1404, L"zh-MO", FL_BOTH), + TEST(0x1407, L"de-LI", FL_BOTH), + TEST(0x1409, L"en-NZ", FL_BOTH), + TEST(0x140A, L"es-CR", FL_BOTH), + TEST(0x140C, L"fr-LU", FL_BOTH), + TEST(0x141A, L"bs-Latn-BA", FL_BOTH), + TEST(0x143B, L"smj-SE", FL_BOTH), + TEST(0x1801, L"ar-MA", FL_BOTH), + TEST(0x1809, L"en-IE", FL_BOTH), + TEST(0x180A, L"es-PA", FL_BOTH), + TEST(0x180C, L"fr-MC", FL_BOTH), + TEST(0x181A, L"sr-Latn-BA", FL_BOTH), + TEST(0x183B, L"sma-NO", FL_BOTH), + TEST(0x1C01, L"ar-TN", FL_BOTH), + TEST(0x1C09, L"en-ZA", FL_BOTH), + TEST(0x1C0A, L"es-DO", FL_BOTH), + TEST(0x1C0C, L"fr-029", FL_BOTH), + TEST(0x1C1A, L"sr-Cyrl-BA", FL_BOTH), + TEST(0x1C3B, L"sma-SE", FL_BOTH), + TEST(0x2000, NULL, 0), // Unassigned LCID locale temporarily assigned to LCID 0x3000. See section 2.2.1. + TEST(0x2001, L"ar-OM", FL_BOTH), + TEST(0x2008, NULL, 0), // Neither defined nor reserved + TEST(0x2009, L"en-JM", FL_BOTH), + TEST(0x200A, L"es-VE", FL_BOTH), + TEST(0x200C, L"fr-RE", FL_BOTH), + TEST(0x201A, L"bs-Cyrl-BA", FL_BOTH), + TEST(0x203B, L"sms-FI", FL_BOTH), + TEST(0x2400, NULL, 0), // Unassigned LCID locale temporarily assigned to LCID 0x3000. See section 2.2.1. + TEST(0x2401, L"ar-YE", FL_BOTH), + TEST(0x2409, L"en-029", FL_BOTH), // reserved + TEST(0x240A, L"es-CO", FL_BOTH), + TEST(0x240C, L"fr-CD", FL_BOTH), + TEST(0x241A, L"sr-Latn-RS", FL_BOTH), + TEST(0x243B, L"smn-FI", FL_BOTH), + TEST(0x2800, NULL, 0), // Unassigned LCID locale temporarily assigned to LCID 0x3000. See section 2.2.1. + TEST(0x2801, L"ar-SY", FL_BOTH), + TEST(0x2809, L"en-BZ", FL_BOTH), + TEST(0x280A, L"es-PE", FL_BOTH), + TEST(0x280C, L"fr-SN", FL_BOTH), + TEST(0x281A, L"sr-Cyrl-RS", FL_BOTH), + TEST(0x2C00, NULL, 0), // Unassigned LCID locale temporarily assigned to LCID 0x3000. See section 2.2.1. + TEST(0x2C01, L"ar-JO", FL_BOTH), + TEST(0x2C09, L"en-TT", FL_BOTH), + TEST(0x2C0A, L"es-AR", FL_BOTH), + TEST(0x2C0C, L"fr-CM", FL_BOTH), + TEST(0x2C1A, L"sr-Latn-ME", FL_BOTH), + TEST(0x3000, NULL, 0), // Unassigned LCID locale temporarily assigned to LCID 0x3000. See section 2.2.1. + TEST(0x3001, L"ar-LB", FL_BOTH), + TEST(0x3009, L"en-ZW", FL_BOTH), + TEST(0x300A, L"es-EC", FL_BOTH), + TEST(0x300C, L"fr-CI", FL_BOTH), + TEST(0x301A, L"sr-Cyrl-ME", FL_BOTH), + TEST(0x3400, NULL, 0), // Unassigned LCID locale temporarily assigned to LCID 0x3000. See section 2.2.1. + TEST(0x3401, L"ar-KW", FL_BOTH), + TEST(0x3409, L"en-PH", FL_BOTH), + TEST(0x340A, L"es-CL", FL_BOTH), + TEST(0x340C, L"fr-ML", FL_BOTH), + TEST(0x3800, NULL, 0), // Unassigned LCID locale temporarily assigned to LCID 0x3000. See section 2.2.1. + TEST(0x3801, L"ar-AE", FL_BOTH), + TEST(0x3809, L"en-ID", FL_BOTH), // reserved + TEST(0x380A, L"es-UY", FL_BOTH), + TEST(0x380C, L"fr-MA", FL_BOTH), + TEST(0x3C00, NULL, 0), // Unassigned LCID locale temporarily assigned to LCID 0x3000. See section 2.2.1. + TEST(0x3C01, L"ar-BH", FL_BOTH), + TEST(0x3C09, L"en-HK", FL_BOTH), + TEST(0x3C0A, L"es-PY", FL_BOTH), + TEST(0x3C0C, L"fr-HT", FL_BOTH), + TEST(0x4000, NULL, 0), // Unassigned LCID locale temporarily assigned to LCID 0x3000. See section 2.2.1. + TEST(0x4001, L"ar-QA", FL_BOTH), + TEST(0x4009, L"en-IN", FL_BOTH), + TEST(0x400A, L"es-BO", FL_BOTH), + TEST(0x4400, NULL, 0), // Unassigned LCID locale temporarily assigned to LCID 0x3000. See section 2.2.1. + TEST(0x4401, L"ar-Ploc-SA", 0), // reserved, ar-Ploc-SA + TEST(0x4409, L"en-MY", FL_BOTH), + TEST(0x440A, L"es-SV", FL_BOTH), + TEST(0x4800, NULL, 0), // Unassigned LCID locale temporarily assigned to LCID 0x3000. See section 2.2.1. + TEST(0x4801, L"ar-145", 0), // reserved, ar-145 + TEST(0x4809, L"en-SG", FL_BOTH), + TEST(0x480A, L"es-HN", FL_BOTH), + TEST(0x4C00, NULL, 0), // Unassigned LCID locale temporarily assigned to LCID 0x3000. See section 2.2.1. + TEST(0x4C09, L"en-AE", FL_BOTH), + TEST(0x4C0A, L"es-NI", FL_BOTH), + TEST(0x5009, L"en-BH", 0), // reserved + TEST(0x500A, L"es-PR", FL_BOTH), + TEST(0x5409, L"en-EG", 0), // reserved + TEST(0x540A, L"es-US", FL_BOTH), + TEST(0x5809, L"en-JO", 0), // reserved + TEST(0x580A, L"es-419", FL_BOTH),// reserved + TEST(0x5C09, L"en-KW", 0), // reserved + TEST(0x5C0A, L"es-CU", FL_BOTH), + TEST(0x6009, L"en-TR", 0), // reserved + TEST(0x6409, L"en-YE", 0), // reserved + TEST(0x641A, L"bs-Cyrl", FL_CULTURE), + TEST(0x681A, L"bs-Latn", FL_CULTURE), + TEST(0x6C1A, L"sr-Cyrl", FL_CULTURE), + TEST(0x701A, L"sr-Latn", FL_CULTURE), + TEST(0x703B, L"smn", FL_CULTURE), + TEST(0x742C, L"az-Cyrl", FL_CULTURE), + TEST(0x743B, L"sms", FL_CULTURE), + TEST(0x7804, L"zh", FL_CULTURE), + TEST(0x7814, L"nn", FL_CULTURE), + TEST(0x781A, L"bs", FL_CULTURE), + TEST(0x782C, L"az-Latn", FL_CULTURE), + TEST(0x783B, L"sma", FL_CULTURE), + //TEST(0x783F, L"kk-Cyrl", FL_BOTH), // reserved, see LCID 0x003F + TEST(0x7843, L"uz-Cyrl", FL_CULTURE), + TEST(0x7850, L"mn-Cyrl", FL_CULTURE), + TEST(0x785D, L"iu-Cans", FL_CULTURE), + TEST(0x785F, L"tzm-Tfng", FL_CULTURE), + TEST(0x7C04, L"zh-Hant", FL_CULTURE), + TEST(0x7C14, L"nb", FL_CULTURE), + TEST(0x7C1A, L"sr", FL_CULTURE), + TEST(0x7C28, L"tg-Cyrl", FL_CULTURE), + TEST(0x7C2E, L"dsb", FL_CULTURE), + TEST(0x7C3B, L"smj", FL_CULTURE), + TEST(0x7C3F, L"kk-Latn", 0), // reserved + TEST(0x7C43, L"uz-Latn", FL_CULTURE), + TEST(0x7C46, L"pa-Arab", FL_CULTURE), + TEST(0x7C50, L"mn-Mong", FL_CULTURE), + TEST(0x7C59, L"sd-Arab", FL_CULTURE), + TEST(0x7C5C, L"chr-Cher", FL_CULTURE), + TEST(0x7C5D, L"iu-Latn", FL_CULTURE), + TEST(0x7C5F, L"tzm-Latn", FL_CULTURE), + TEST(0x7C67, L"ff-Latn", FL_CULTURE), + TEST(0x7C68, L"ha-Latn", FL_CULTURE), + TEST(0x7C92, L"ku-Arab", FL_CULTURE), + TEST(0xF2EE, NULL, 0), // reserved + TEST(0xE40C, L"fr-015", 0), // reserved + TEST(0xEEEE, NULL, 0), // reserved + + // Alternative sorting + TEST(0x10407, L"de-DE_phoneb", FL_BOTH), + TEST(0x1040E, L"hu-HU_technl", FL_BOTH), + TEST(0x10437, L"ka-GE_modern", FL_BOTH), + TEST(0x20804, L"zh-CN_stroke", FL_BOTH), + TEST(0x21004, L"zh-SG_stroke", FL_BOTH), + TEST(0x30404, L"zh-TW_pronun", FL_BOTH), + TEST(0x40404, L"zh-TW_radstr", FL_BOTH), + TEST(0x40411, L"ja-JP_radstr", FL_BOTH), + TEST(0x40C04, L"zh-HK_radstr", FL_BOTH), + TEST(0x41404, L"zh-MO_radstr", FL_BOTH), + + // Some invalid sorting flags + TEST(0x10804, NULL, 0), + TEST(0x20404, NULL, 0), + +}; + +static BOOLEAN Init(void) +{ + HMODULE hmod = GetModuleHandleA("ntdll.dll"); + + // Initialize function pointers + pRtlConvertLCIDToString = (FN_RtlConvertLCIDToString*)GetProcAddress(hmod, "RtlConvertLCIDToString"); + pRtlCultureNameToLCID = (FN_RtlCultureNameToLCID*)GetProcAddress(hmod, "RtlCultureNameToLCID"); + pRtlLCIDToCultureName = (FN_RtlLCIDToCultureName*)GetProcAddress(hmod, "RtlLCIDToCultureName"); + pRtlLcidToLocaleName = (FN_RtlLcidToLocaleName*)GetProcAddress(hmod, "RtlLcidToLocaleName"); + pRtlLocaleNameToLcid = (FN_RtlLocaleNameToLcid*)GetProcAddress(hmod, "RtlLocaleNameToLcid"); + if (!pRtlConvertLCIDToString || + !pRtlCultureNameToLCID || + !pRtlLCIDToCultureName || + !pRtlLcidToLocaleName || + !pRtlLocaleNameToLcid) + { + skip("Function not found\n"); + return FALSE; + } + + return TRUE; +} + +static void Test_RtlCultureNameToLCID(void) +{ + UNICODE_STRING CultureName; + WCHAR Buffer[100]; + BOOLEAN Result, ExpectedResult;; + LCID Lcid, ExpectedLcid; + + // Test valid CultureName + Lcid = 0xDEADBEEF; + RtlInitUnicodeString(&CultureName, L"en-US"); + Result = pRtlCultureNameToLCID(&CultureName, &Lcid); + ok_eq_bool(Result, TRUE); + ok_eq_hex(Lcid, 0x0409); + + // Test wrongly capatalized CultureName + Lcid = 0xDEADBEEF; + RtlInitUnicodeString(&CultureName, L"eN-uS"); + Result = pRtlCultureNameToLCID(&CultureName, &Lcid); + ok_eq_bool(Result, TRUE); + ok_eq_hex(Lcid, 0x0409); + + // Test not nullterminated buffer + Lcid = 0xDEADBEEF; + wcscpy(Buffer, L"en-US"); + RtlInitUnicodeString(&CultureName, Buffer); + Buffer[5] = L'X'; + Result = pRtlCultureNameToLCID(&CultureName, &Lcid); + ok_eq_bool(Result, TRUE); + ok_eq_hex(Lcid, 0x0409); + + // Test NULL Lcid + Lcid = 0xDEADBEEF; + RtlInitUnicodeString(&CultureName, L"en-US"); + Result = pRtlCultureNameToLCID(&CultureName, NULL); + ok_eq_bool(Result, FALSE); + ok_eq_hex(Lcid, 0xDEADBEEF); + + // Test NULL CultureName + Lcid = 0xDEADBEEF; + Result = pRtlCultureNameToLCID(NULL, &Lcid); + ok_eq_bool(Result, FALSE); + ok_eq_hex(Lcid, 0xDEADBEEF); + + // Test NULL CultureName buffer + Lcid = 0xDEADBEEF; + RtlInitEmptyUnicodeString(&CultureName, NULL, 0); + Result = pRtlCultureNameToLCID(&CultureName, &Lcid); + ok_eq_bool(Result, FALSE); + ok_eq_hex(Lcid, 0xDEADBEEF); + + // Test empty CultureName + Lcid = 0xDEADBEEF; + RtlInitUnicodeString(&CultureName, L""); + Result = pRtlCultureNameToLCID(&CultureName, &Lcid); + ok_eq_bool(Result, FALSE); + ok_eq_hex(Lcid, 0xDEADBEEF); + + // Test invalid CultureName + Lcid = 0xDEADBEEF; + RtlInitUnicodeString(&CultureName, L"en-UX"); + Result = pRtlCultureNameToLCID(&CultureName, &Lcid); + ok_eq_bool(Result, FALSE); + ok_eq_hex(Lcid, 0xDEADBEEF); + + // Process the test entries + for (ULONG i = 0; i < ARRAYSIZE(Tests); i++) + { + ExpectedResult = (Tests[i].Flags & FL_CULTURE) ? TRUE : FALSE; + ExpectedLcid = (Tests[i].Flags & FL_CULTURE) ? Tests[i].Lcid : 0xDEADBEEF; + + RtlInitUnicodeString(&CultureName, Tests[i].CultureName); + Lcid = 0xDEADBEEF; + Result = pRtlCultureNameToLCID(&CultureName, &Lcid); + ok(Result == ExpectedResult, + "Line %lu: Result = %u, expected %u failed\n", + Tests[i].Line, + Result, + ExpectedResult); + ok(Lcid == ExpectedLcid, + "Line %lu: Lcid = 0x%08lX, expected 0x%08lX\n", + Tests[i].Line, Lcid, Tests[i].Lcid); + } +} + +static void Test_RtlLCIDToCultureName(void) +{ + UNICODE_STRING CultureName, ExpectedCultureName; + WCHAR Buffer[100]; + BOOLEAN Result, ExpectedResult, Equal; + + // Test NULL CultureName + Result = pRtlLCIDToCultureName(0x0409, NULL); + ok_eq_bool(Result, FALSE); + + // Test NULL CultureName buffer + RtlInitEmptyUnicodeString(&CultureName, NULL, 0); + Result = pRtlLCIDToCultureName(0x0409, &CultureName); + ok_eq_bool(Result, FALSE); + + // Test 0 sized CultureName buffer + RtlInitEmptyUnicodeString(&CultureName, Buffer, 0); + Result = pRtlLCIDToCultureName(0x0409, &CultureName); + ok_eq_bool(Result, FALSE); + + // Test too small CultureName buffer + RtlInitEmptyUnicodeString(&CultureName, Buffer, 10); + Result = pRtlLCIDToCultureName(0x0409, &CultureName); + ok_eq_bool(Result, FALSE); + + // Test valid CultureName buffer + RtlInitEmptyUnicodeString(&CultureName, Buffer, 12); + Result = pRtlLCIDToCultureName(0x0409, &CultureName); + ok_eq_bool(Result, TRUE); + ok_eq_wstr(CultureName.Buffer, L"en-US"); + + // Test invalid LCID + RtlInitEmptyUnicodeString(&CultureName, Buffer, 12); + Result = pRtlLCIDToCultureName(0x0469, &CultureName); + ok_eq_bool(Result, FALSE); + + // Process the test entries + for (ULONG i = 0; i < ARRAYSIZE(Tests); i++) + { + if (Tests[i].Flags & FL_ALT_NAME) + { + continue; + } + + ExpectedResult = (Tests[i].Flags & FL_CULTURE) ? TRUE : FALSE; + RtlInitEmptyUnicodeString(&CultureName, Buffer, sizeof(Buffer)); + RtlInitUnicodeString(&ExpectedCultureName, Tests[i].CultureName); + Result = pRtlLCIDToCultureName(Tests[i].Lcid, &CultureName); + ok(Result == ExpectedResult, + "Line %lu, Lcid 0x%lx: Result == %u, expected %u\n", + Tests[i].Line, Tests[i].Lcid, Result, ExpectedResult); + if (Result) + { + Equal = RtlEqualUnicodeString(&CultureName, &ExpectedCultureName, FALSE); + ok(Equal, "Line %lu, Lcid 0x%lx: CultureName = '%wZ', expected '%wZ'\n", + Tests[i].Line, Tests[i].Lcid, &CultureName, &ExpectedCultureName); + } + } +} + +static void Test_RtlLocaleNameToLcid(void) +{ + LCID Lcid; + NTSTATUS Status, ExpectedStatus; + LCID ExpectedLcid; + + // Test valid LocaleName + Lcid = 0xDEADBEEF; + Status = pRtlLocaleNameToLcid(L"en-US", &Lcid, 0); + ok_ntstatus(Status, STATUS_SUCCESS); + ok_eq_hex(Lcid, 0x0409); + + // Test wrongly capatalized LocaleName + Lcid = 0xDEADBEEF; + Status = pRtlLocaleNameToLcid(L"eN-uS", &Lcid, 0); + ok_ntstatus(Status, STATUS_SUCCESS); + ok_eq_hex(Lcid, 0x0409); + + // Test extended unicode chars + Lcid = 0xDEADBEEF; + Status = pRtlLocaleNameToLcid(L"\x1165n-US", &Lcid, 0); + ok_ntstatus(Status, STATUS_INVALID_PARAMETER_1); + ok_eq_hex(Lcid, 0xDEADBEEF); + + // Test NULL LocaleName + Lcid = 0xDEADBEEF; + Status = pRtlLocaleNameToLcid(NULL, &Lcid, 0); + ok_ntstatus(Status, STATUS_INVALID_PARAMETER_1); + ok_eq_hex(Lcid, 0xDEADBEEF); + + // Test empty LocaleName + Lcid = 0xDEADBEEF; + Status = pRtlLocaleNameToLcid(L"", &Lcid, 0); + ok_ntstatus(Status, STATUS_SUCCESS); + ok_eq_hex(Lcid, LOCALE_INVARIANT); + + // Test invalid LocaleName + Lcid = 0xDEADBEEF; + Status = pRtlLocaleNameToLcid(L"en-UX", &Lcid, 0); + ok_ntstatus(Status, STATUS_INVALID_PARAMETER_1); + ok_eq_hex(Lcid, 0xDEADBEEF); + + // Test NULL Lcid + Lcid = 0xDEADBEEF; + Status = pRtlLocaleNameToLcid(L"en-US", NULL, 0); + ok_ntstatus(Status, STATUS_INVALID_PARAMETER_2); + ok_eq_hex(Lcid, 0xDEADBEEF); + + // Test flags + Status = pRtlLocaleNameToLcid(L"en-US", &Lcid, 0x1); + ok_ntstatus(Status, STATUS_SUCCESS); + Status = pRtlLocaleNameToLcid(L"en-US", &Lcid, 0x2); + ok_ntstatus(Status, STATUS_SUCCESS); + Status = pRtlLocaleNameToLcid(L"en-US", &Lcid, 0x3); + ok_ntstatus(Status, STATUS_SUCCESS); + Status = pRtlLocaleNameToLcid(L"en-US", &Lcid, 0x4); + ok_ntstatus(Status, STATUS_INVALID_PARAMETER_3); + Status = pRtlLocaleNameToLcid(L"en-US", &Lcid, 0x8); + ok_ntstatus(Status, STATUS_INVALID_PARAMETER_3); + + // Test NULL LocaleName and NULL Lcid + Lcid = 0xDEADBEEF; + Status = pRtlLocaleNameToLcid(NULL, NULL, 0); + ok_ntstatus(Status, STATUS_INVALID_PARAMETER_1); + ok_eq_hex(Lcid, 0xDEADBEEF); + + // Test invalid LocaleName and NULL Lcid + Lcid = 0xDEADBEEF; + Status = pRtlLocaleNameToLcid(L"en-UX", NULL, 0); + ok_ntstatus(Status, STATUS_INVALID_PARAMETER_2); + ok_eq_hex(Lcid, 0xDEADBEEF); + + // Test NULL Lcid and invalid flags + Lcid = 0xDEADBEEF; + Status = pRtlLocaleNameToLcid(L"en-US", NULL, 0x8); + ok_ntstatus(Status, STATUS_INVALID_PARAMETER_2); + ok_eq_hex(Lcid, 0xDEADBEEF); + + // Test empty LocaleName + Lcid = 0xDEADBEEF; + Status = pRtlLocaleNameToLcid(L"", &Lcid, 0); + ok_ntstatus(Status, STATUS_SUCCESS); + ok_eq_hex(Lcid, 0x7F); + + // Process the test entries + for (ULONG i = 0; i < ARRAYSIZE(Tests); i++) + { + // No flags + ExpectedStatus = (Tests[i].Flags & FL_LOCALE) ? STATUS_SUCCESS : STATUS_INVALID_PARAMETER_1; + ExpectedLcid = (Tests[i].Flags & FL_LOCALE) ? Tests[i].Lcid : 0xDEADBEEF; + Lcid = 0xDEADBEEF; + Status = pRtlLocaleNameToLcid((PWSTR)Tests[i].CultureName, &Lcid, 0); + ok(Status == ExpectedStatus, + "Line %lu: Status == 0x%lx, expected 0x%lx\n", + Tests[i].Line, Status, ExpectedStatus); + ok(Lcid == ExpectedLcid, + "Line %lu: Lcid == 0x%08X, expected 0x%08X\n", + Tests[i].Line, Lcid, ExpectedLcid); + + // Flags = 0x2 + ExpectedStatus = (Tests[i].Flags & FL_BOTH) ? STATUS_SUCCESS : STATUS_INVALID_PARAMETER_1; + ExpectedLcid = (Tests[i].Flags & FL_BOTH) ? Tests[i].Lcid : 0xDEADBEEF; + Lcid = 0xDEADBEEF; + Status = pRtlLocaleNameToLcid((PWSTR)Tests[i].CultureName, &Lcid, 0x2); + ok(Status == ExpectedStatus, + "Line %lu: Status == 0x%lx, expected 0x%lx\n", + Tests[i].Line, Status, ExpectedStatus); + ok(Lcid == ExpectedLcid, + "Line %lu: Lcid == 0x%08X, expected 0x%08X\n", + Tests[i].Line, Lcid, ExpectedLcid); + } +} + +static void Test_RtlLcidToLocaleName(void) +{ + UNICODE_STRING LocaleName, ExpectedLocaleName; + WCHAR Buffer[100]; + NTSTATUS Status, ExpectedStatus; + BOOLEAN Equal; + LCID Lcid; + + // Test valid parameters + RtlInitEmptyUnicodeString(&LocaleName, Buffer, sizeof(Buffer)); + Status = pRtlLcidToLocaleName(0x0409, &LocaleName, 0, FALSE); + ok_ntstatus(Status, STATUS_SUCCESS); + ok(memcmp(Buffer, L"en-US", 12) == 0, "Expected null-terminated 'en-US', got %wZ\n", &LocaleName); + + // Test invalid LCIDs + Status = pRtlLcidToLocaleName(0xF2EE, &LocaleName, 0, FALSE); + ok_ntstatus(Status, STATUS_INVALID_PARAMETER_1); + Status = pRtlLcidToLocaleName(0x100409, &LocaleName, 0, FALSE); + ok_ntstatus(Status, STATUS_INVALID_PARAMETER_1); + + // Test reserved LCID + Status = pRtlLcidToLocaleName(0x048E, &LocaleName, 0, FALSE); + ok_ntstatus(Status, STATUS_INVALID_PARAMETER_1); + + // Test NULL LocaleName + Status = pRtlLcidToLocaleName(0x0409, NULL, 0, FALSE); + ok_ntstatus(Status, STATUS_INVALID_PARAMETER_2); + + // Test NULL LocaleName buffer + RtlInitEmptyUnicodeString(&LocaleName, NULL, 0); + Status = pRtlLcidToLocaleName(0x0409, &LocaleName, 0, FALSE); + ok_ntstatus(Status, STATUS_INVALID_PARAMETER_2); + + // Test invalid buffer size + RtlInitEmptyUnicodeString(&LocaleName, Buffer, sizeof(Buffer)); + LocaleName.Length = sizeof(Buffer) + 8; + Status = pRtlLcidToLocaleName(0x0409, &LocaleName, 0, FALSE); + ok_ntstatus(Status, STATUS_SUCCESS); + + // Test flags + Status = pRtlLcidToLocaleName(0x0409, &LocaleName, 0x1, FALSE); + ok_ntstatus(Status, STATUS_INVALID_PARAMETER_3); + Status = pRtlLcidToLocaleName(0x0409, &LocaleName, 0x2, FALSE); + ok_ntstatus(Status, STATUS_SUCCESS); + Status = pRtlLcidToLocaleName(0x0409, &LocaleName, 0x4, FALSE); + ok_ntstatus(Status, STATUS_INVALID_PARAMETER_3); + Status = pRtlLcidToLocaleName(0x0409, &LocaleName, 0x8, FALSE); + ok_ntstatus(Status, STATUS_INVALID_PARAMETER_3); + Status = pRtlLcidToLocaleName(0x0409, &LocaleName, 0x08000000, FALSE); // LOCALE_ALLOW_NEUTRAL_NAMES + ok_ntstatus(Status, STATUS_INVALID_PARAMETER_3); + + // Test invalid LCID and NULL buffer + RtlInitEmptyUnicodeString(&LocaleName, NULL, 0); + Status = pRtlLcidToLocaleName(0xF2EE, &LocaleName, 0, FALSE); + ok_ntstatus(Status, STATUS_INVALID_PARAMETER_2); + + // Test reserved LCID and NULL buffer + Status = pRtlLcidToLocaleName(0x048E, &LocaleName, 0, FALSE); + ok_ntstatus(Status, STATUS_INVALID_PARAMETER_2); + + // Test reserved LCID and invalid flags + RtlInitEmptyUnicodeString(&LocaleName, Buffer, sizeof(Buffer)); + Status = pRtlLcidToLocaleName(0x048E, &LocaleName, 0x8, FALSE); + ok_ntstatus(Status, STATUS_INVALID_PARAMETER_3); + + // Test invalid flags and NULL buffer + RtlInitEmptyUnicodeString(&LocaleName, NULL, 0); + Status = pRtlLcidToLocaleName(0x0409, &LocaleName, 0x8, FALSE); + ok_ntstatus(Status, STATUS_INVALID_PARAMETER_3); + + // Test 0 sized LocaleName buffer + RtlInitEmptyUnicodeString(&LocaleName, Buffer, 0); + Status = pRtlLcidToLocaleName(0x0409, &LocaleName, 0, FALSE); + ok_ntstatus(Status, STATUS_BUFFER_TOO_SMALL); + + // Test too small LocaleName buffer + RtlInitEmptyUnicodeString(&LocaleName, Buffer, 10); + Buffer[0] = L'@'; + Status = pRtlLcidToLocaleName(0x0409, &LocaleName, 0, FALSE); + ok_ntstatus(Status, STATUS_BUFFER_TOO_SMALL); + ok(Buffer[0] == L'@', "Buffer should not be modified\n"); + + // Test LOCALE_INVARIANT (0x007F) + RtlInitEmptyUnicodeString(&LocaleName, Buffer, sizeof(Buffer)); + Status = pRtlLcidToLocaleName(LOCALE_INVARIANT, &LocaleName, 0, FALSE); + ok_ntstatus(Status, STATUS_SUCCESS); + ok(Buffer[0] == L'\0', "Buffer should be empty\n"); + + // Test LOCALE_USER_DEFAULT (0x0400) + Status = pRtlLcidToLocaleName(LOCALE_USER_DEFAULT, &LocaleName, 0, FALSE); + ok_ntstatus(Status, STATUS_SUCCESS); + Status = pRtlLocaleNameToLcid(Buffer, &Lcid, 0); + ok_ntstatus(Status, STATUS_SUCCESS); + ok_eq_hex(Lcid, GetUserDefaultLCID()); + + // Test LOCALE_SYSTEM_DEFAULT (0x0800) + Status = pRtlLcidToLocaleName(LOCALE_SYSTEM_DEFAULT, &LocaleName, 0, FALSE); + ok_ntstatus(Status, STATUS_SUCCESS); + Status = pRtlLocaleNameToLcid(Buffer, &Lcid, 0); + ok_ntstatus(Status, STATUS_SUCCESS); + ok_eq_hex(Lcid, GetSystemDefaultLCID()); + + // Test LOCALE_CUSTOM_DEFAULT (0x0C00) + Status = pRtlLcidToLocaleName(LOCALE_CUSTOM_DEFAULT, &LocaleName, 0, FALSE); + ok_ntstatus(Status, STATUS_SUCCESS); + + // Test LOCALE_CUSTOM_UNSPECIFIED (0x1000) + Status = pRtlLcidToLocaleName(LOCALE_CUSTOM_UNSPECIFIED, &LocaleName, 0, FALSE); + ok_ntstatus(Status, STATUS_INVALID_PARAMETER_1); + Status = pRtlLcidToLocaleName(LOCALE_CUSTOM_UNSPECIFIED, &LocaleName, 0x2, FALSE); + ok_ntstatus(Status, STATUS_INVALID_PARAMETER_1); + + // Test LOCALE_CUSTOM_UI_DEFAULT (0x1400) + Status = pRtlLcidToLocaleName(LOCALE_CUSTOM_UI_DEFAULT, &LocaleName, 0, FALSE); + ok_ntstatus(Status, STATUS_UNSUCCESSFUL); + Status = pRtlLcidToLocaleName(LOCALE_CUSTOM_UI_DEFAULT, &LocaleName, 0x2, FALSE); + ok_ntstatus(Status, STATUS_UNSUCCESSFUL); + + // Test LOCALE_CUSTOM_UNSPECIFIED (0x1000) + Status = pRtlLcidToLocaleName(LOCALE_CUSTOM_UNSPECIFIED, &LocaleName, 0, FALSE); + ok_ntstatus(Status, STATUS_INVALID_PARAMETER_1); + + // Process the test entries + for (ULONG i = 0; i < ARRAYSIZE(Tests); i++) + { + if (Tests[i].Flags & FL_ALT_NAME) + { + continue; + } + + RtlInitEmptyUnicodeString(&LocaleName, Buffer, sizeof(Buffer)); + RtlInitUnicodeString(&ExpectedLocaleName, Tests[i].CultureName); + + /* First test with Flags == 0 */ + ExpectedStatus = (Tests[i].Flags & FL_LOCALE) ? STATUS_SUCCESS : STATUS_INVALID_PARAMETER_1; + Status = pRtlLcidToLocaleName(Tests[i].Lcid, &LocaleName, 0, FALSE); + ok(Status == ExpectedStatus, + "Line %lu, Lcid 0x%lx: Status == 0x%lx, expected 0x%lx\n", + Tests[i].Line, Tests[i].Lcid, Status, ExpectedStatus); + if (NT_SUCCESS(Status)) + { + Equal = RtlEqualUnicodeString(&LocaleName, &ExpectedLocaleName, TRUE); + ok(Equal, "Line %lu, Lcid 0x%lx: LocaleName == '%wZ', expected '%wZ'\n", + Tests[i].Line, Tests[i].Lcid, &LocaleName, &ExpectedLocaleName); + } + + /* Test with Flags == 2 */ + ExpectedStatus = (Tests[i].Flags & FL_BOTH) ? STATUS_SUCCESS : STATUS_INVALID_PARAMETER_1; + Status = pRtlLcidToLocaleName(Tests[i].Lcid, &LocaleName, 2, FALSE); + ok(Status == ExpectedStatus, + "Line %lu, Lcid 0x%lx: Status == 0x%lx, expected 0x%lx\n", + Tests[i].Line, Tests[i].Lcid, Status, ExpectedStatus); + if (NT_SUCCESS(Status)) + { + Equal = RtlEqualUnicodeString(&LocaleName, &ExpectedLocaleName, FALSE); + ok(Equal, "Line %lu, Lcid 0x%lx: LocaleName == '%wZ', expected '%wZ'\n", + Tests[i].Line, Tests[i].Lcid, &LocaleName, &ExpectedLocaleName); + } + } +} + +START_TEST(RtlLocale) +{ + if (!Init()) + { + return; + } + + Test_RtlCultureNameToLCID(); + Test_RtlLCIDToCultureName(); + Test_RtlLocaleNameToLcid(); + Test_RtlLcidToLocaleName(); +} diff --git a/modules/rostests/apitests/ntdll/RtlQueryTimeZoneInfo.c b/modules/rostests/apitests/ntdll/RtlQueryTimeZoneInfo.c index cd645a4c5a759..ed2d8d12876ac 100644 --- a/modules/rostests/apitests/ntdll/RtlQueryTimeZoneInfo.c +++ b/modules/rostests/apitests/ntdll/RtlQueryTimeZoneInfo.c @@ -30,7 +30,7 @@ typedef struct _RTL_SYSTEM_TIME { /* * RTL_TIME_ZONE_INFORMATION is the same as the TIME_ZONE_INFORMATION structure * defined in winbase.h, however we need to define RTL_TIME_ZONE_INFORMATION - * seperately here so we don't depend on winbase.h. + * separately here so we don't depend on winbase.h. * This is used by RtlQueryTimeZoneInformation and RtlSetTimeZoneInformation. */ typedef struct _RTL_TIME_ZONE_INFORMATION { diff --git a/modules/rostests/apitests/ntdll/empty_dll/CMakeLists.txt b/modules/rostests/apitests/ntdll/empty_dll/CMakeLists.txt new file mode 100644 index 0000000000000..36513ed6703d7 --- /dev/null +++ b/modules/rostests/apitests/ntdll/empty_dll/CMakeLists.txt @@ -0,0 +1,6 @@ + +add_library(empty_dll MODULE empty_dll.c) +set_module_type(empty_dll win32dll ENTRYPOINT DllMain 12) +add_importlibs(empty_dll kernel32 ntdll) +add_dependencies(empty_dll psdk) +add_rostests_file(TARGET empty_dll) diff --git a/modules/rostests/apitests/ntdll/empty_dll/empty_dll.c b/modules/rostests/apitests/ntdll/empty_dll/empty_dll.c new file mode 100644 index 0000000000000..ddd4be786a8d1 --- /dev/null +++ b/modules/rostests/apitests/ntdll/empty_dll/empty_dll.c @@ -0,0 +1,11 @@ +#include + +BOOL +WINAPI +DllMain( + _In_ HINSTANCE hinstDLL, + _In_ DWORD fdwReason, + _In_ LPVOID lpvReserved) +{ + return TRUE; +} diff --git a/modules/rostests/apitests/ntdll/testdata.rc b/modules/rostests/apitests/ntdll/testdata.rc index 3c16769902c9e..3937c7302ef97 100644 --- a/modules/rostests/apitests/ntdll/testdata.rc +++ b/modules/rostests/apitests/ntdll/testdata.rc @@ -1,2 +1,3 @@ 101 10 "load_notifications.dll" +102 10 "empty_dll.dll" diff --git a/modules/rostests/apitests/ntdll/testlist.c b/modules/rostests/apitests/ntdll/testlist.c index 10cc0d987dad7..d7c8de7fc4b42 100644 --- a/modules/rostests/apitests/ntdll/testlist.c +++ b/modules/rostests/apitests/ntdll/testlist.c @@ -3,6 +3,7 @@ #define STANDALONE #include +extern void func_DllLoadNotification(void); extern void func_LdrEnumResources(void); extern void func_LdrLoadDll(void); extern void func_load_notifications(void); @@ -18,6 +19,7 @@ extern void func_NtCompareTokens(void); extern void func_NtContinue(void); extern void func_NtCreateFile(void); extern void func_NtCreateKey(void); +extern void func_NtCreateProfile(void); extern void func_NtCreateThread(void); extern void func_NtDeleteKey(void); extern void func_NtDuplicateObject(void); @@ -37,6 +39,7 @@ extern void func_NtQueryInformationProcess(void); extern void func_NtQueryInformationThread(void); extern void func_NtQueryInformationToken(void); extern void func_NtQueryKey(void); +extern void func_NtQueryObject(void); extern void func_NtQueryOpenSubKeys(void); extern void func_NtQuerySystemEnvironmentValue(void); extern void func_NtQuerySystemInformation(void); @@ -51,6 +54,7 @@ extern void func_NtSetInformationThread(void); extern void func_NtSetInformationToken(void); extern void func_NtSetValueKey(void); extern void func_NtSetVolumeInformationFile(void); +extern void func_NtStartProfile(void); extern void func_NtSystemInformation(void); extern void func_NtUnloadDriver(void); extern void func_NtWriteFile(void); @@ -84,6 +88,7 @@ extern void func_RtlImageDirectoryEntryToData(void); extern void func_RtlImageRvaToVa(void); extern void func_RtlIntSafe(void); extern void func_RtlIsNameLegalDOS8Dot3(void); +extern void func_RtlLocale(void); extern void func_RtlMemoryStream(void); extern void func_RtlMultipleAllocateHeap(void); extern void func_RtlNtPathNameToDosPathName(void); @@ -106,6 +111,7 @@ extern void func_UserModeException(void); const struct test winetest_testlist[] = { + { "DllLoadNotification", func_DllLoadNotification }, { "LdrEnumResources", func_LdrEnumResources }, { "LdrLoadDll", func_LdrLoadDll }, { "load_notifications", func_load_notifications }, @@ -121,6 +127,7 @@ const struct test winetest_testlist[] = { "NtContinue", func_NtContinue }, { "NtCreateFile", func_NtCreateFile }, { "NtCreateKey", func_NtCreateKey }, + { "NtCreateProfile", func_NtCreateProfile }, { "NtCreateThread", func_NtCreateThread }, { "NtDeleteKey", func_NtDeleteKey }, { "NtDuplicateObject", func_NtDuplicateObject }, @@ -140,6 +147,7 @@ const struct test winetest_testlist[] = { "NtQueryInformationThread", func_NtQueryInformationThread }, { "NtQueryInformationToken", func_NtQueryInformationToken }, { "NtQueryKey", func_NtQueryKey }, + { "NtQueryObject", func_NtQueryObject }, { "NtQueryOpenSubKeys", func_NtQueryOpenSubKeys }, { "NtQuerySystemEnvironmentValue", func_NtQuerySystemEnvironmentValue }, { "NtQuerySystemInformation", func_NtQuerySystemInformation }, @@ -154,6 +162,7 @@ const struct test winetest_testlist[] = { "NtSetInformationToken", func_NtSetInformationToken }, { "NtSetValueKey", func_NtSetValueKey}, { "NtSetVolumeInformationFile", func_NtSetVolumeInformationFile }, + { "NtStartProfile", func_NtStartProfile }, { "NtSystemInformation", func_NtSystemInformation }, { "NtUnloadDriver", func_NtUnloadDriver }, { "NtWriteFile", func_NtWriteFile }, @@ -186,6 +195,7 @@ const struct test winetest_testlist[] = { "RtlImageRvaToVa", func_RtlImageRvaToVa }, { "RtlIntSafe", func_RtlIntSafe }, { "RtlIsNameLegalDOS8Dot3", func_RtlIsNameLegalDOS8Dot3 }, + { "RtlLocale", func_RtlLocale }, { "RtlMemoryStream", func_RtlMemoryStream }, { "RtlMultipleAllocateHeap", func_RtlMultipleAllocateHeap }, { "RtlNtPathNameToDosPathName", func_RtlNtPathNameToDosPathName }, diff --git a/modules/rostests/apitests/partmgr/CMakeLists.txt b/modules/rostests/apitests/partmgr/CMakeLists.txt new file mode 100644 index 0000000000000..32684f3252eb8 --- /dev/null +++ b/modules/rostests/apitests/partmgr/CMakeLists.txt @@ -0,0 +1,17 @@ + +list(APPEND SOURCE + StorDeviceNumber.c) + +list(APPEND PCH_SKIP_SOURCE + testlist.c) + +add_executable(partmgr_apitest + ${SOURCE} + ${PCH_SKIP_SOURCE}) + +target_link_libraries(partmgr_apitest wine ${PSEH_LIB}) +set_module_type(partmgr_apitest win32cui) +add_importlibs(partmgr_apitest msvcrt kernel32 ntdll) +# TODO: Enable this when we get more than one source file to justify its use +#add_pch(partmgr_apitest precomp.h "${PCH_SKIP_SOURCE}") +add_rostests_file(TARGET partmgr_apitest) diff --git a/modules/rostests/apitests/partmgr/StorDeviceNumber.c b/modules/rostests/apitests/partmgr/StorDeviceNumber.c new file mode 100644 index 0000000000000..8407b0475f285 --- /dev/null +++ b/modules/rostests/apitests/partmgr/StorDeviceNumber.c @@ -0,0 +1,306 @@ +/* + * PROJECT: ReactOS API Tests + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Test for IOCTL_STORAGE_GET_DEVICE_NUMBER + * COPYRIGHT: Copyright 2024 Hermès Bélusca-Maïto + */ + +#include "precomp.h" +#include + +static LPCSTR wine_dbgstr_us(const UNICODE_STRING *us) +{ + if (!us) return "(null)"; + return wine_dbgstr_wn(us->Buffer, us->Length / sizeof(WCHAR)); +} + +/* Flags combination allowing all the read, write and delete share modes. + * Currently similar to FILE_SHARE_VALID_FLAGS. */ +#define FILE_SHARE_ALL \ + (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE) + +static BOOLEAN +Test_Device_StorDeviceNumber( + _In_ PCWSTR NtDeviceName) +{ + BOOLEAN Success = FALSE; // Suppose failure. + NTSTATUS Status; + HANDLE DeviceHandle1 = NULL, DeviceHandle2 = NULL; + FILE_FS_DEVICE_INFORMATION DeviceInfo; + STORAGE_DEVICE_NUMBER DeviceNumber; + UNICODE_STRING DeviceName; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + WCHAR NtLegacyDeviceName[MAX_PATH]; + + ULONG BufferSize; + struct { OBJECT_NAME_INFORMATION; WCHAR Buffer[MAX_PATH]; } DeviceName1Buffer; + PUNICODE_STRING DeviceName1 = &DeviceName1Buffer.Name; + struct { OBJECT_NAME_INFORMATION; WCHAR Buffer[MAX_PATH]; } DeviceName2Buffer; + PUNICODE_STRING DeviceName2 = &DeviceName2Buffer.Name; + + /* Open a handle to the device */ + RtlInitUnicodeString(&DeviceName, NtDeviceName); + InitializeObjectAttributes(&ObjectAttributes, + &DeviceName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtOpenFile(&DeviceHandle1, + FILE_READ_ATTRIBUTES | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_ALL, + /* FILE_NON_DIRECTORY_FILE | */ FILE_SYNCHRONOUS_IO_NONALERT); + ok_ntstatus(Status, STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + { + skip("Device '%s': Opening failed\n", wine_dbgstr_us(&DeviceName)); + goto Quit; + } + + /* Verify the device information before proceeding further */ + Status = NtQueryVolumeInformationFile(DeviceHandle1, + &IoStatusBlock, + &DeviceInfo, + sizeof(DeviceInfo), + FileFsDeviceInformation); + ok_ntstatus(Status, STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + { + skip("FileFsDeviceInformation('%s') failed, Status 0x%08lx\n", + wine_dbgstr_us(&DeviceName), Status); + goto Quit; + } + + /* Ignore volumes that are NOT on usual disks */ + switch (DeviceInfo.DeviceType) + { + /* Testable devices */ + case FILE_DEVICE_CD_ROM: + // case FILE_DEVICE_CD_ROM_FILE_SYSTEM: + case FILE_DEVICE_DISK: + // case FILE_DEVICE_DISK_FILE_SYSTEM: + // case FILE_DEVICE_NETWORK: + // case FILE_DEVICE_NETWORK_FILE_SYSTEM: + case FILE_DEVICE_VIRTUAL_DISK: + break; + + /* Untestable devices */ + default: + skip("Device '%s': Cannot test, device type %lu\n", + wine_dbgstr_us(&DeviceName), DeviceInfo.DeviceType); + goto Quit; + } +#if 0 + if (DeviceInfo.DeviceType != FILE_DEVICE_DISK && + DeviceInfo.DeviceType != FILE_DEVICE_VIRTUAL_DISK && + DeviceInfo.DeviceType != FILE_DEVICE_CD_ROM) + { + skip("Device '%s': Cannot test, device type %lu\n", + wine_dbgstr_us(&DeviceName), DeviceInfo.DeviceType); + goto Quit; + } +#endif + + /* + * Retrieve the storage device number. + * Note that this call is unsupported if this is a dynamic volume. + * NOTE: Usually fails for floppy disks. + */ + Status = NtDeviceIoControlFile(DeviceHandle1, + NULL, NULL, NULL, + &IoStatusBlock, + IOCTL_STORAGE_GET_DEVICE_NUMBER, + NULL, 0, + &DeviceNumber, sizeof(DeviceNumber)); + if (!NT_SUCCESS(Status)) + { + skip("Device '%s': Couldn't retrieve disk number\n", wine_dbgstr_us(&DeviceName)); + goto Quit; + } + ok(DeviceNumber.DeviceType == DeviceInfo.DeviceType, + "Device '%s': Device type mismatch\n", wine_dbgstr_us(&DeviceName)); + + /* NOTE: this value is set to 0xFFFFFFFF (-1) for the disks that + * represent the physical paths of a multipath I/O (MPIO) disk. */ + ok(DeviceNumber.DeviceNumber != ULONG_MAX, + "Device '%s': Invalid disk number reported\n", wine_dbgstr_us(&DeviceName)); + if (DeviceNumber.DeviceNumber == ULONG_MAX) + goto Quit; + + switch (DeviceInfo.DeviceType) + { + /* Testable devices */ + case FILE_DEVICE_CD_ROM: + // case FILE_DEVICE_CD_ROM_FILE_SYSTEM: + { + /* CD-ROMs don't have partitions, their partition number is -1 */ + ok(DeviceNumber.PartitionNumber == ULONG_MAX, + "Device '%s': Invalid partition number (%lu) reported, expected ULONG_MAX (-1)\n", + wine_dbgstr_us(&DeviceName), DeviceNumber.PartitionNumber); + + /* Map to an NT device name */ + RtlStringCchPrintfW(NtLegacyDeviceName, _countof(NtLegacyDeviceName), + L"\\Device\\CdRom%lu", + DeviceNumber.DeviceNumber); + break; + } + + case FILE_DEVICE_DISK: + // case FILE_DEVICE_DISK_FILE_SYSTEM: + case FILE_DEVICE_VIRTUAL_DISK: + { + /* Check whether this is a floppy or a partitionable device */ + if (DeviceInfo.Characteristics & FILE_FLOPPY_DISKETTE) + { + /* Floppies don't have partitions, their partition number is -1 */ + ok(DeviceNumber.PartitionNumber == ULONG_MAX, + "Device '%s': Invalid partition number (%lu) reported, expected ULONG_MAX (-1)\n", + wine_dbgstr_us(&DeviceName), DeviceNumber.PartitionNumber); + + /* Map to an NT device name */ + RtlStringCchPrintfW(NtLegacyDeviceName, _countof(NtLegacyDeviceName), + L"\\Device\\Floppy%lu", + DeviceNumber.DeviceNumber); + } + else + { + /* The device is partitionable, so it must have a valid partition number */ + ok(DeviceNumber.PartitionNumber != ULONG_MAX, + "Device '%s': Invalid partition number (%lu) reported; unpartitionable device?\n", + wine_dbgstr_us(&DeviceName), DeviceNumber.PartitionNumber); + if (DeviceNumber.PartitionNumber == ULONG_MAX) + goto Quit; + + /* Map to an NT device name */ + RtlStringCchPrintfW(NtLegacyDeviceName, _countof(NtLegacyDeviceName), + L"\\Device\\Harddisk%lu\\Partition%lu", + DeviceNumber.DeviceNumber, DeviceNumber.PartitionNumber); + } + break; + } + + /* Untestable devices */ + default: + skip("Device '%s': Cannot test, device type %lu\n", + wine_dbgstr_us(&DeviceName), DeviceInfo.DeviceType); + goto Quit; + } + + /* Open the device using the legacy path */ + RtlInitUnicodeString(&DeviceName, NtLegacyDeviceName); + InitializeObjectAttributes(&ObjectAttributes, + &DeviceName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtOpenFile(&DeviceHandle2, + FILE_READ_ATTRIBUTES | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_ALL, + /* FILE_NON_DIRECTORY_FILE | */ FILE_SYNCHRONOUS_IO_NONALERT); + ok_ntstatus(Status, STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + { + skip("Device '%s': Opening failed\n", wine_dbgstr_us(&DeviceName)); + goto Quit; + } + + /* + * Verify whether both retrieved handles refer to the same device. + * Since we're not running on Windows 10, we cannot use kernel32!CompareObjectHandles() + * or ntdll!NtCompareObjects(), therefore we have to rely on comparing + * whether the devices referred by both handles have the same canonical name. + */ + Status = NtQueryObject(DeviceHandle1, + ObjectNameInformation, + &DeviceName1Buffer, + sizeof(DeviceName1Buffer), + &BufferSize); + ok_ntstatus(Status, STATUS_SUCCESS); + + Status = NtQueryObject(DeviceHandle2, + ObjectNameInformation, + &DeviceName2Buffer, + sizeof(DeviceName2Buffer), + &BufferSize); + ok_ntstatus(Status, STATUS_SUCCESS); + + Success = RtlEqualUnicodeString(DeviceName1, DeviceName2, FALSE); + ok(Success, "Devices '%s' and '%s' are not the same!\n", + wine_dbgstr_us(DeviceName1), wine_dbgstr_us(DeviceName2)); + +Quit: + /* Cleanup */ + if (DeviceHandle2) + NtClose(DeviceHandle2); + if (DeviceHandle1) + NtClose(DeviceHandle1); + + return Success; +} + +static BOOLEAN +Test_Drive_StorDeviceNumber( + _In_ WCHAR Drive) +{ + WCHAR NtDeviceName[] = L"\\DosDevices\\?:"; + NtDeviceName[sizeof("\\DosDevices\\")-1] = Drive; + return Test_Device_StorDeviceNumber(NtDeviceName); +} + +START_TEST(StorDeviceNumber) +{ + DWORD Drives; + UCHAR i; + + /* Enumerate existing testable drives */ + Drives = GetLogicalDrives(); + if (Drives == 0) + { + skip("Drives map unavailable, error 0x%lx\n", GetLastError()); + goto otherTests; + } + for (i = 0; i <= 'Z'-'A'; ++i) + { + WCHAR DriveName[] = L"?:\\"; + UINT DriveType; + + /* Skip non-existing drives */ + if (!(Drives & (1 << i))) + continue; + + /* Retrieve the drive type and see whether we can test it */ + DriveName[0] = L'A' + i; + DriveType = GetDriveTypeW(DriveName); + + switch (DriveType) + { + case DRIVE_REMOVABLE: + case DRIVE_FIXED: + case DRIVE_CDROM: + case DRIVE_RAMDISK: + { + Test_Drive_StorDeviceNumber(L'A' + i); + break; + } + + case DRIVE_UNKNOWN: + case DRIVE_NO_ROOT_DIR: + case DRIVE_REMOTE: + default: + /* Unhandled drive type, just skip it silently */ + trace("Drive %c with unhandled type %u\n", 'A' + i, DriveType); + break; + } + } + +otherTests: + /* Test the drive containing SystemRoot */ + Test_Drive_StorDeviceNumber(SharedUserData->NtSystemRoot[0]); + + /* Test \??\PhysicalDrive0, if it exists */ + Test_Device_StorDeviceNumber(L"\\??\\PhysicalDrive0"); +} diff --git a/modules/rostests/apitests/partmgr/precomp.h b/modules/rostests/apitests/partmgr/precomp.h new file mode 100644 index 0000000000000..fc5eaa9b38b80 --- /dev/null +++ b/modules/rostests/apitests/partmgr/precomp.h @@ -0,0 +1,20 @@ +/* + * PROJECT: ReactOS API Tests + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Precompiled header + * COPYRIGHT: Copyright 2024 Hermès Bélusca-Maïto + */ + +#pragma once + +#define WIN32_NO_STATUS +#include + +#define NTOS_MODE_USER +#include +#include +#include + +#include + +/* EOF */ diff --git a/modules/rostests/apitests/partmgr/testlist.c b/modules/rostests/apitests/partmgr/testlist.c new file mode 100644 index 0000000000000..01ad0e3a04a9d --- /dev/null +++ b/modules/rostests/apitests/partmgr/testlist.c @@ -0,0 +1,10 @@ +#define STANDALONE +#include + +extern void func_StorDeviceNumber(void); + +const struct test winetest_testlist[] = +{ + { "StorDeviceNumber", func_StorDeviceNumber }, + { 0, 0 } +}; diff --git a/modules/rostests/apitests/rtl/ldrstubs.c b/modules/rostests/apitests/rtl/ldrstubs.c index c04ac0837bbfe..63616fb755369 100644 --- a/modules/rostests/apitests/rtl/ldrstubs.c +++ b/modules/rostests/apitests/rtl/ldrstubs.c @@ -15,3 +15,8 @@ LdrpInitializeProcessCompat(PVOID pProcessActctx, PVOID* pOldShimData) { } +VOID NTAPI +AVrfInternalHeapFreeNotification(PVOID AllocationBase, SIZE_T AllocationSize) +{ + /* Stub for linking against rtl */ +} diff --git a/modules/rostests/apitests/shdocvw/CMakeLists.txt b/modules/rostests/apitests/shdocvw/CMakeLists.txt index 3f4c6324b57a7..69531225073c6 100644 --- a/modules/rostests/apitests/shdocvw/CMakeLists.txt +++ b/modules/rostests/apitests/shdocvw/CMakeLists.txt @@ -1,6 +1,7 @@ list(APPEND SOURCE MRUList.cpp + WinList.cpp testlist.c) add_executable(shdocvw_apitest ${SOURCE}) diff --git a/modules/rostests/apitests/shdocvw/WinList.cpp b/modules/rostests/apitests/shdocvw/WinList.cpp new file mode 100644 index 0000000000000..e8a9eeb69caec --- /dev/null +++ b/modules/rostests/apitests/shdocvw/WinList.cpp @@ -0,0 +1,157 @@ +/* + * PROJECT: ReactOS api tests + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Tests for shdocvw!WinList_* functions + * COPYRIGHT: Copyright 2025 Katayama Hirofumi MZ + */ + +#include +#include + +typedef BOOL (WINAPI *FN_WinList_Init)(VOID); +typedef VOID (WINAPI *FN_WinList_Terminate)(VOID); +typedef IShellWindows* (WINAPI *FN_WinList_GetShellWindows)(BOOL); + +static FN_WinList_Init g_pWinList_Init = NULL; +static FN_WinList_Terminate g_pWinList_Terminate = NULL; +static FN_WinList_GetShellWindows g_pWinList_GetShellWindows = NULL; + +static VOID +TEST_WinList_GetShellWindows(VOID) +{ + BOOL bInited = g_pWinList_Init && g_pWinList_Init(); + ok_int(bInited, FALSE); // WinList_Init should fail because this process is not explorer.exe + + IShellWindows *pShellWindows1 = g_pWinList_GetShellWindows(FALSE); + trace("%p\n", pShellWindows1); + ok(pShellWindows1 != NULL, "pShellWindows1 was null\n"); + + IShellWindows *pShellWindows2 = g_pWinList_GetShellWindows(FALSE); + trace("%p\n", pShellWindows2); + ok(pShellWindows2 != NULL, "pShellWindows2 was null\n"); + + IShellWindows *pShellWindows3 = g_pWinList_GetShellWindows(TRUE); + trace("%p\n", pShellWindows3); + ok(pShellWindows3 != NULL, "pShellWindows3 was null\n"); + + ok_ptr(pShellWindows1, pShellWindows2); + ok_ptr(pShellWindows2, pShellWindows3); + + if (pShellWindows1) + { + LONG nCount = -1; + HRESULT hr = pShellWindows1->get_Count(&nCount); + ok_hex(hr, S_OK); + ok(nCount >= 0, "nCount was %ld\n", nCount); + trace("%ld\n", nCount); + + pShellWindows1->Release(); + } + else + { + ok_int(TRUE, FALSE); + ok_int(TRUE, FALSE); + } + + if (pShellWindows2) + pShellWindows2->Release(); + + if (pShellWindows3) + pShellWindows3->Release(); + + if (bInited && g_pWinList_Terminate) + g_pWinList_Terminate(); +} + +static VOID +TEST_WinList_Mix(VOID) +{ + IShellWindows *pShellWindows1 = g_pWinList_GetShellWindows(FALSE); + trace("%p\n", pShellWindows1); + ok(pShellWindows1 != NULL, "pShellWindows1 was null\n"); + + IShellWindows *pShellWindows2 = NULL; + CoCreateInstance(CLSID_ShellWindows, NULL, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER, + IID_IShellWindows, (LPVOID *)&pShellWindows2); + ok(pShellWindows2 != NULL, "pShellWindows2 was null\n"); + + ok_ptr(pShellWindows1, pShellWindows2); + + if (pShellWindows1) + pShellWindows1->Release(); + if (pShellWindows2) + pShellWindows2->Release(); +} + +static VOID +TEST_SHDOCVW_WinList(VOID) +{ + HINSTANCE hSHDOCVW = LoadLibraryW(L"shdocvw.dll"); + if (!hSHDOCVW) + { + skip("shdocvw.dll not loaded\n"); + return; + } + + g_pWinList_Init = (FN_WinList_Init)GetProcAddress(hSHDOCVW, MAKEINTRESOURCEA(110)); + g_pWinList_Terminate = (FN_WinList_Terminate)GetProcAddress(hSHDOCVW, MAKEINTRESOURCEA(111)); + g_pWinList_GetShellWindows = (FN_WinList_GetShellWindows)GetProcAddress(hSHDOCVW, MAKEINTRESOURCEA(179)); + if (!g_pWinList_Init || !g_pWinList_Terminate || !g_pWinList_GetShellWindows) + { + skip("Some WinList_* functions not found: %p %p %p\n", + g_pWinList_Init, g_pWinList_Terminate, g_pWinList_GetShellWindows); + } + else + { + TEST_WinList_GetShellWindows(); + TEST_WinList_Mix(); + } + + FreeLibrary(hSHDOCVW); +} + +static VOID +TEST_CLSID_ShellWindows(VOID) +{ + IShellWindows *pShellWindows1 = NULL; + CoCreateInstance(CLSID_ShellWindows, NULL, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER, + IID_IShellWindows, (LPVOID *)&pShellWindows1); + ok(pShellWindows1 != NULL, "pShellWindows1 was null\n"); + + IShellWindows *pShellWindows2 = NULL; + CoCreateInstance(CLSID_ShellWindows, NULL, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER, + IID_IShellWindows, (LPVOID *)&pShellWindows2); + ok(pShellWindows2 != NULL, "pShellWindows2 was null\n"); + + ok_ptr(pShellWindows1, pShellWindows2); + + if (pShellWindows1) + { + LONG nCount = -1; + HRESULT hr = pShellWindows1->get_Count(&nCount); + ok_hex(hr, S_OK); + ok(nCount >= 0, "nCount was %ld\n", nCount); + trace("%ld\n", nCount); + + pShellWindows1->Release(); + } + else + { + ok_int(TRUE, FALSE); + ok_int(TRUE, FALSE); + } + + if (pShellWindows2) + pShellWindows2->Release(); +} + +START_TEST(WinList) +{ + HRESULT hrCoInit = CoInitialize(NULL); + + TEST_SHDOCVW_WinList(); + TEST_CLSID_ShellWindows(); + + if (SUCCEEDED(hrCoInit)) + CoUninitialize(); +} diff --git a/modules/rostests/apitests/shdocvw/testlist.c b/modules/rostests/apitests/shdocvw/testlist.c index 1a34744c0df4c..725ec0861532b 100644 --- a/modules/rostests/apitests/shdocvw/testlist.c +++ b/modules/rostests/apitests/shdocvw/testlist.c @@ -2,9 +2,11 @@ #include extern void func_MRUList(void); +extern void func_WinList(void); const struct test winetest_testlist[] = { { "MRUList", func_MRUList }, + { "WinList", func_WinList }, { 0, 0 } }; diff --git a/modules/rostests/apitests/shell32/CMakeLists.txt b/modules/rostests/apitests/shell32/CMakeLists.txt index 2a90a0e009df0..bea3f3ea27197 100644 --- a/modules/rostests/apitests/shell32/CMakeLists.txt +++ b/modules/rostests/apitests/shell32/CMakeLists.txt @@ -24,6 +24,8 @@ list(APPEND SOURCE OpenAs_RunDLL.cpp PathIsEqualOrSubFolder.cpp PathIsTemporary.cpp + PathMakeUniqueName.cpp + PathProcessCommand.cpp PathResolve.cpp RealShellExecuteEx.cpp SHAppBarMessage.cpp @@ -31,9 +33,15 @@ list(APPEND SOURCE SHCreateDataObject.cpp SHCreateFileDataObject.cpp SHCreateFileExtractIconW.cpp + SHGetComputerDisplayNameW.cpp + SHGetUnreadMailCountW.cpp + SHIsBadInterfacePtr.cpp SHParseDisplayName.cpp SHRestricted.cpp + SHShouldShowWizards.cpp + SHEnumerateUnreadMailAccountsW.cpp She.cpp + ShellExec_RunDLL.cpp ShellExecCmdLine.cpp ShellExecuteEx.cpp ShellExecuteW.cpp @@ -41,7 +49,10 @@ list(APPEND SOURCE ShellInfo.cpp ShellState.cpp SHGetAttributesFromDataObject.cpp + SHGetUserDisplayName.cpp SHLimitInputEdit.cpp + SHSetUnreadMailCountW.cpp + StrRStr.cpp menu.cpp shelltest.cpp) diff --git a/modules/rostests/apitests/shell32/ExtractIconEx.cpp b/modules/rostests/apitests/shell32/ExtractIconEx.cpp index 244081199f36b..d8e9fd4b564a0 100644 --- a/modules/rostests/apitests/shell32/ExtractIconEx.cpp +++ b/modules/rostests/apitests/shell32/ExtractIconEx.cpp @@ -9,6 +9,28 @@ #include "shelltest.h" #include +EXTERN_C BOOL WINAPI SHAreIconsEqual(HICON hIcon1, HICON hIcon2); + +static void SafeDestroyIcon(HICON hIco) +{ + if (hIco) + DestroyIcon(hIco); +} + +static UINT GetIcoSize(HICON hIco) +{ + ICONINFO info; + if (!GetIconInfo(hIco, &info)) + return 0; + + BITMAP bm; + if (!GetObject(info.hbmColor ? info.hbmColor : info.hbmMask, sizeof(bm), &bm)) + bm.bmWidth = 0; + DeleteObject(info.hbmMask); + DeleteObject(info.hbmColor); + return bm.bmWidth; +} + typedef struct { PCWSTR pszFilePath; @@ -122,3 +144,66 @@ START_TEST(ExtractIconEx) DeleteFileA(FileName[0]); DeleteFileA(FileName[1]); } + +static HRESULT SHDEI(LPCWSTR pszIconFile, int Index = 0, UINT GIL = 0, UINT Size = 0) +{ + HICON hIco = NULL; + HRESULT hr = SHDefExtractIcon(pszIconFile, Index, GIL, &hIco, NULL, Size); + if (hr == S_OK) + { + hr = GetIcoSize(hIco); + SafeDestroyIcon(hIco); + } + return hr; +} + +START_TEST(SHDefExtractIcon) +{ + HRESULT hr; + int SysBigIconSize = GetSystemMetrics(SM_CXICON); + + // Modern Windows requires the system image list to be initialized for GIL_SIMULATEDOC to work! + SHFILEINFOW shfi; + SHGetFileInfoW(L"x", 0, &shfi, sizeof(shfi), SHGFI_SYSICONINDEX | SHGFI_USEFILEATTRIBUTES); + + WCHAR path[MAX_PATH]; + GetSystemDirectoryW(path, _countof(path)); + PathAppendW(path, L"user32.dll"); + int index = 1; + + ok(SHDEI(path, index, 0, 0) == SysBigIconSize, "0 size must match GetSystemMetrics\n"); + ok(SHDEI(path, index, 0, SysBigIconSize * 2) == SysBigIconSize * 2, "Resize failed\n"); + + HICON hIcoLarge, hIcoSmall; + if (SHDefExtractIcon(path, index, 0, &hIcoLarge, &hIcoSmall, 0) != S_OK) + hIcoLarge = hIcoSmall = NULL; + ok(hIcoLarge && hIcoSmall && !SHAreIconsEqual(hIcoLarge, hIcoSmall), "Large+Small failed\n"); + SafeDestroyIcon(hIcoLarge); + SafeDestroyIcon(hIcoSmall); + + static const int sizes[] = { 0, SysBigIconSize * 2 }; + for (UINT i = 0; i < _countof(sizes); ++i) + { + HICON hIcoNormal, hIcoSimDoc; + if (FAILED(hr = SHDefExtractIcon(path, index, 0, &hIcoNormal, NULL, sizes[i]))) + hIcoNormal = NULL; + if (FAILED(hr = SHDefExtractIcon(path, index, GIL_SIMULATEDOC, &hIcoSimDoc, NULL, sizes[i]))) + hIcoSimDoc = NULL; + ok(hIcoNormal && hIcoSimDoc && !SHAreIconsEqual(hIcoNormal, hIcoSimDoc), "GIL_SIMULATEDOC failed\n"); + SafeDestroyIcon(hIcoNormal); + SafeDestroyIcon(hIcoSimDoc); + } + + GetTempPathW(_countof(path), path); + GetTempFileNameW(path, L"TEST", 0, path); + ok(SHDEI(path) == S_FALSE, "Empty file should return S_FALSE\n"); + HANDLE hFile = CreateFileW(path, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL); + if (hFile != INVALID_HANDLE_VALUE) + { + DWORD io; + WriteFile(hFile, "!", 1, &io, NULL); + CloseHandle(hFile); + ok(SHDEI(path) == S_FALSE, "File without icons should return S_FALSE\n"); + } + DeleteFile(path); +} diff --git a/modules/rostests/apitests/shell32/ItemIDList.cpp b/modules/rostests/apitests/shell32/ItemIDList.cpp index 02c4e694bd6a7..14d9f551d471c 100644 --- a/modules/rostests/apitests/shell32/ItemIDList.cpp +++ b/modules/rostests/apitests/shell32/ItemIDList.cpp @@ -12,6 +12,7 @@ enum { DIRBIT = 1, FILEBIT = 2, PT_COMPUTER_REGITEM = 0x2E, + PT_INTERNET_URL = 0x61, }; static BYTE GetPIDLType(LPCITEMIDLIST pidl) @@ -48,6 +49,15 @@ static int FileStruct_Att(LPCITEMIDLIST pidl) return p ? p->att : (UINT(1) << 31); } +static HRESULT GetDisplayNameOf(IShellFolder *pSF, LPCITEMIDLIST pidl, UINT Flags, PWSTR Buf, UINT Cap) +{ + STRRET sr; + HRESULT hr = pSF->GetDisplayNameOf(pidl, Flags, &sr); + if (SUCCEEDED(hr)) + hr = StrRetToBufW(&sr, pidl, Buf, Cap); + return hr; +} + #define TEST_CLSID(pidl, type, offset, clsid) \ do { \ ok_long(GetPIDLType(pidl), (type)); \ @@ -195,6 +205,7 @@ START_TEST(ILCreateFromPath) START_TEST(PIDL) { + CCoInit ComInit; LPITEMIDLIST pidl; pidl = SHCloneSpecialIDList(NULL, CSIDL_DRIVES, FALSE); @@ -210,6 +221,29 @@ START_TEST(PIDL) else skip("?\n"); ILFree(pidl); + + + CComPtr pInternet; + HRESULT hr = SHCoCreateInstance(NULL, &CLSID_Internet, NULL, IID_PPV_ARG(IShellFolder, &pInternet)); + if (SUCCEEDED(hr)) + { + PCWSTR pszUrl = L"http://example.com/page?query&foo=bar"; + PIDLIST_RELATIVE pidlUrl; + hr = pInternet->ParseDisplayName(NULL, NULL, const_cast(pszUrl), NULL, &pidlUrl, NULL); + ok_long(hr, S_OK); + if (hr == S_OK) + { + ok_int(pidlUrl->mkid.abID[0], PT_INTERNET_URL); + WCHAR buf[MAX_PATH]; + hr = GetDisplayNameOf(pInternet, pidlUrl, SHGDN_FORPARSING, buf, _countof(buf)); + ok_long(hr, S_OK); + if (SUCCEEDED(hr)) + { + ok(!lstrcmpiW(buf, pszUrl), "FORPARSING must match URL\n"); + } + ILFree(pidlUrl); + } + } } START_TEST(ILIsEqual) diff --git a/modules/rostests/apitests/shell32/PathMakeUniqueName.cpp b/modules/rostests/apitests/shell32/PathMakeUniqueName.cpp new file mode 100644 index 0000000000000..abd0c7bed117c --- /dev/null +++ b/modules/rostests/apitests/shell32/PathMakeUniqueName.cpp @@ -0,0 +1,119 @@ +/* + * PROJECT: ReactOS api tests + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Tests for PathMakeUniqueName + * COPYRIGHT: Copyright 2025 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) + */ + +#include "shelltest.h" +#include +#include + +#define ok_wstri(x, y) \ + ok(_wcsicmp(x, y) == 0, "Wrong string. Expected '%S', got '%S'\n", y, x) + +/* IsLFNDriveW */ +typedef BOOL (WINAPI *FN_IsLFNDriveW)(LPCWSTR); + +START_TEST(PathMakeUniqueName) +{ + WCHAR szPath[MAX_PATH], szCurDir[MAX_PATH], szTempDir[MAX_PATH]; + BOOL result, bUseLong = FALSE; + FN_IsLFNDriveW pIsLFNDriveW = + (FN_IsLFNDriveW)GetProcAddress(GetModuleHandleW(L"shell32"), MAKEINTRESOURCEA(42)); + + // Move to temporary folder + GetCurrentDirectoryW(_countof(szCurDir), szCurDir); + GetEnvironmentVariableW(L"TEMP", szTempDir, _countof(szTempDir)); + SetCurrentDirectoryW(szTempDir); + + if (pIsLFNDriveW) + bUseLong = pIsLFNDriveW(szTempDir) && IsWindowsVistaOrGreater(); + trace("bUseLong: %d\n", bUseLong); + + DeleteFileW(L"test.txt"); + + // Test 1: Basic operation + szPath[0] = UNICODE_NULL; + result = PathMakeUniqueName(szPath, _countof(szPath), L"test.txt", NULL, NULL); + ok_int(result, TRUE); + ok_wstri(szPath, L"test (1).txt"); + + // Test 2: Specify directory + szPath[0] = UNICODE_NULL; + result = PathMakeUniqueName(szPath, _countof(szPath), L"test.txt", NULL, L"."); + ok_int(result, TRUE); + ok_wstri(szPath, (bUseLong ? L".\\test (1).txt" : L".\\test1.txt")); + + // Test 3: Duplicated filename + CreateFileW(L"test.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + szPath[0] = UNICODE_NULL; + result = PathMakeUniqueName(szPath, _countof(szPath), L"test.txt", NULL, NULL); + ok_int(result, TRUE); + ok_wstri(szPath, L"test (1).txt"); + DeleteFileW(L"test.txt"); + + // Build long name + WCHAR longName[MAX_PATH + 32]; + for (auto& ch : longName) + ch = L'A'; + longName[_countof(longName) - 10] = UNICODE_NULL; + lstrcatW(longName, L".txt"); + + // Test 4: Long filename + result = PathMakeUniqueName(szPath, _countof(szPath), longName, NULL, NULL); + szPath[0] = UNICODE_NULL; + ok_int(result, FALSE); + ok_wstri(szPath, L""); + + // Test 5: Invalid parameter + szPath[0] = UNICODE_NULL; + result = PathMakeUniqueName(NULL, 0, L"test.txt", NULL, NULL); + ok_int(result, FALSE); + + // Test 6: Template and longplate + szPath[0] = UNICODE_NULL; + result = PathMakeUniqueName(szPath, _countof(szPath), L"template.txt", L"longplate.txt", NULL); + ok_int(result, TRUE); + ok_wstri(szPath, L"longplate (1).txt"); + + // Test 7: Template only + szPath[0] = UNICODE_NULL; + result = PathMakeUniqueName(szPath, _countof(szPath), L"template.txt", NULL, NULL); + ok_int(result, TRUE); + ok_wstri(szPath, L"template (1).txt"); + + // Test 8: Folder and duplicated filename + CreateFileW(L".\\temp\\test.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + szPath[0] = UNICODE_NULL; + result = PathMakeUniqueName(szPath, _countof(szPath), L"test.txt", NULL, L"."); + ok_int(result, TRUE); + ok_wstri(szPath, (bUseLong ? L".\\test (1).txt" : L".\\test1.txt")); + DeleteFileW(L".\\test.txt"); + + // Test 9: Test extension + CreateFileW(L".\\test.hoge", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + szPath[0] = UNICODE_NULL; + result = PathMakeUniqueName(szPath, _countof(szPath), L"test.hoge", NULL, L"."); + ok_int(result, TRUE); + ok_wstri(szPath, (bUseLong ? L".\\test (1).hoge" : L".\\test1.hoge")); + DeleteFileW(L".\\test.hoge"); + + // Test 10: Folder in folder + CreateDirectoryW(L".\\hoge", NULL); + szPath[0] = UNICODE_NULL; + result = PathMakeUniqueName(szPath, _countof(szPath), L"test.txt", NULL, L".\\hoge"); + ok_int(result, TRUE); + ok_wstri(szPath, (bUseLong ? L".\\hoge\\test (1).txt" : L".\\hoge\\test1.txt")); + RemoveDirectoryW(L".\\hoge"); + + // Test 11: File in folder + CreateFileW(L".\\hoge.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + szPath[0] = UNICODE_NULL; + result = PathMakeUniqueName(szPath, _countof(szPath), L"test.txt", NULL, L"."); + ok_int(result, TRUE); + ok_wstri(szPath, (bUseLong ? L".\\test (1).txt" : L".\\test1.txt")); + DeleteFileW(L".\\hoge.txt"); + + SetCurrentDirectoryW(szCurDir); +} diff --git a/modules/rostests/apitests/shell32/PathProcessCommand.cpp b/modules/rostests/apitests/shell32/PathProcessCommand.cpp new file mode 100644 index 0000000000000..aa401b01cfe32 --- /dev/null +++ b/modules/rostests/apitests/shell32/PathProcessCommand.cpp @@ -0,0 +1,144 @@ +/* + * PROJECT: ReactOS API tests + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Tests for PathProcessCommand + * COPYRIGHT: Copyright 2025 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) + */ + +#include "shelltest.h" +#include + +#define ok_wstri(x, y) \ + ok(_wcsicmp(x, y) == 0, "Wrong string. Expected '%S', got '%S'\n", y, x) + +typedef LONG (WINAPI *FN_PathProcessCommand)(LPCWSTR, LPWSTR, INT, DWORD); + +static FN_PathProcessCommand s_PathProcessCommand = NULL; + +static void +Test_PathProcessCommand(void) +{ + WCHAR buffer[MAX_PATH], szCalcExe[MAX_PATH]; + LONG result; + FILE *fout; + WCHAR szCurDir[MAX_PATH]; + WCHAR szFull1[MAX_PATH], szFull2[MAX_PATH], szFull3[MAX_PATH], szFull4[MAX_PATH]; + WCHAR szFull5[MAX_PATH]; + + fout = _wfopen(L"_Test.exe", L"wb"); + fclose(fout); + fout = _wfopen(L"test with spaces.exe", L"wb"); + fclose(fout); + + GetFullPathNameW(L".", _countof(szCurDir), szCurDir, NULL); + GetShortPathNameW(szCurDir, szCurDir, _countof(szCurDir)); + + lstrcpynW(szFull1, szCurDir, _countof(szFull1)); + lstrcpynW(szFull2, szCurDir, _countof(szFull2)); + lstrcpynW(szFull4, szCurDir, _countof(szFull4)); + lstrcpynW(szFull5, szCurDir, _countof(szFull5)); + + lstrcatW(szFull1, L"\\_Test.exe"); + lstrcatW(szFull2, L"\\test with spaces.exe"); + wsprintfW(szFull3, L"\"%s\"", szFull2); + lstrcatW(szFull4, L"\\_Test.exe arg1 arg2"); + lstrcatW(szFull5, L"\\_TestDir.exe"); + + CreateDirectoryW(L"_TestDir.exe", NULL); + + // Test case 1: Basic functionality (no flags) + lstrcpynW(buffer, L"<>", _countof(buffer)); + result = s_PathProcessCommand(L"_Test", buffer, _countof(buffer), 0); + ok_int(result, lstrlenW(szFull1) + 1); + ok_wstri(buffer, szFull1); + + // Test case 2: Quoted path + lstrcpynW(buffer, L"<>", _countof(buffer)); + result = s_PathProcessCommand(L"\"test with spaces\"", buffer, _countof(buffer), 0); + ok_int(result, lstrlenW(szFull2) + 1); + ok_wstri(buffer, szFull2); + + // Test case 3: Add quotes flag + lstrcpynW(buffer, L"<>", _countof(buffer)); + result = s_PathProcessCommand(L"test with spaces", buffer, _countof(buffer), PPCF_ADDQUOTES); + ok_int(result, lstrlenW(szFull3) + 1); + ok_wstri(buffer, szFull3); + + // Test case 4: Add arguments flag + lstrcpynW(buffer, L"<>", _countof(buffer)); + result = s_PathProcessCommand(L"_Test arg1 arg2", buffer, _countof(buffer), PPCF_ADDARGUMENTS); + ok_int(result, lstrlenW(szFull4) + 1); + ok_wstri(buffer, szFull4); + + // calc.exe + GetSystemDirectoryW(szCalcExe, _countof(szCalcExe)); + PathAppendW(szCalcExe, L"calc.exe"); + + // Test case 5: Longest possible flag + lstrcpynW(buffer, L"<>", _countof(buffer)); + result = s_PathProcessCommand(szCalcExe, buffer, _countof(buffer), PPCF_LONGESTPOSSIBLE); + ok_int(result, lstrlenW(szCalcExe) + 1); + ok_wstri(buffer, szCalcExe); + + // Test case 6: Buffer too small + lstrcpynW(buffer, L"<>", _countof(buffer)); + result = s_PathProcessCommand(L"_Test.exe", buffer, 5, 0); + ok_int(result, -1); + ok_wstri(buffer, L"<>"); + + // Test case 7: Null input path + lstrcpynW(buffer, L"<>", _countof(buffer)); + result = s_PathProcessCommand(NULL, buffer, _countof(buffer), 0); + ok_int(result, -1); + ok_wstri(buffer, L"<>"); + + // Test case 8: Relative path resolution + lstrcpynW(buffer, L"<>", _countof(buffer)); + result = s_PathProcessCommand(L"_Test.exe", buffer, _countof(buffer), PPCF_FORCEQUALIFY); + ok_int(result, lstrlenW(szFull1) + 1); + ok_wstri(buffer, szFull1); + + // Test case 9: No directories + lstrcpynW(buffer, L"<>", _countof(buffer)); + result = s_PathProcessCommand(L"_TestDir.exe", buffer, _countof(buffer), PPCF_NODIRECTORIES); + ok_int(result, -1); + ok_wstri(buffer, L"<>"); + + // Test case 10: With directories + lstrcpynW(buffer, L"<>", _countof(buffer)); + result = s_PathProcessCommand(L"_TestDir.exe", buffer, _countof(buffer), 0); + ok_int(result, lstrlenW(szFull5) + 1); + ok_wstri(buffer, szFull5); + + RemoveDirectoryW(L"_TestDir.exe"); + DeleteFileW(L"_Test.exe"); + DeleteFileW(L"test with spaces.exe"); +} + +START_TEST(PathProcessCommand) +{ + WCHAR szCurDir[MAX_PATH], szTempDir[MAX_PATH]; + + s_PathProcessCommand = (FN_PathProcessCommand) + GetProcAddress(GetModuleHandleW(L"shell32"), "PathProcessCommand"); + if (!s_PathProcessCommand) + { + s_PathProcessCommand = (FN_PathProcessCommand) + GetProcAddress(GetModuleHandleW(L"shell32"), MAKEINTRESOURCEA(653)); + } + if (!s_PathProcessCommand) + { + skip("PathProcessCommand not found\n"); + return; + } + + GetCurrentDirectoryW(_countof(szCurDir), szCurDir); + GetEnvironmentVariableW(L"TEMP", szTempDir, _countof(szTempDir)); + SetCurrentDirectoryW(szTempDir); + + SetEnvironmentVariableW(L"PATH", szTempDir); + + Test_PathProcessCommand(); + + SetCurrentDirectoryW(szCurDir); +} diff --git a/modules/rostests/apitests/shell32/SHEnumerateUnreadMailAccountsW.cpp b/modules/rostests/apitests/shell32/SHEnumerateUnreadMailAccountsW.cpp new file mode 100644 index 0000000000000..5abc2df9a44aa --- /dev/null +++ b/modules/rostests/apitests/shell32/SHEnumerateUnreadMailAccountsW.cpp @@ -0,0 +1,33 @@ +/* + * PROJECT: ReactOS API tests + * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) + * PURPOSE: Test for SHEnumerateUnreadMailAccountsW + * COPYRIGHT: Copyright 2025 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) + */ + +#include "shelltest.h" + +START_TEST(SHEnumerateUnreadMailAccountsW) +{ + HRESULT hr; + WCHAR szMailAddress[MAX_PATH]; + HKEY hKey; + LSTATUS error; + DWORD dwDisposition; + + error = RegCreateKeyExW(HKEY_CURRENT_USER, + L"Software\\Microsoft\\Windows\\CurrentVersion\\UnreadMail\\example.com", + 0, NULL, 0, KEY_WRITE, NULL, &hKey, &dwDisposition); + ok_long(error, ERROR_SUCCESS); + + szMailAddress[0] = UNICODE_NULL; + hr = SHEnumerateUnreadMailAccountsW(NULL, 0, szMailAddress, _countof(szMailAddress)); + ok_hex(hr, S_OK); + ok(szMailAddress[0] != UNICODE_NULL, "szMailAddress was empty\n"); + + if (dwDisposition == REG_CREATED_NEW_KEY) + { + RegDeleteKeyW(HKEY_CURRENT_USER, + L"Software\\Microsoft\\Windows\\CurrentVersion\\UnreadMail\\example.com"); + } +} diff --git a/modules/rostests/apitests/shell32/SHGetComputerDisplayNameW.cpp b/modules/rostests/apitests/shell32/SHGetComputerDisplayNameW.cpp new file mode 100644 index 0000000000000..e4d6f49f1b84d --- /dev/null +++ b/modules/rostests/apitests/shell32/SHGetComputerDisplayNameW.cpp @@ -0,0 +1,159 @@ +/* + * PROJECT: ReactOS API Tests + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Tests for SHGetComputerDisplayNameW + * COPYRIGHT: Copyright 2025 Katayama Hirofumi MZ + */ + +#include "shelltest.h" +#include +#include +#include +#include + +typedef HRESULT (WINAPI *FN_SHGetComputerDisplayNameW)(PWSTR, DWORD, PWSTR, DWORD); +typedef NET_API_STATUS (WINAPI *FN_NetServerGetInfo)(LPWSTR, DWORD, PBYTE*); +typedef NET_API_STATUS (WINAPI *FN_NetApiBufferFree)(PVOID); + +static FN_SHGetComputerDisplayNameW s_pSHGetComputerDisplayNameW = NULL; +static FN_NetServerGetInfo s_pNetServerGetInfo = NULL; +static FN_NetApiBufferFree s_pNetApiBufferFree = NULL; + +#define COMPUTER_DESCRIPTIONS_KEY \ + L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComputerDescriptions" + +static PCWSTR +SHELL_SkipServerSlashes( + _In_ PCWSTR pszPath) +{ + PCWSTR pch; + for (pch = pszPath; *pch == L'\\'; ++pch) + ; + return pch; +} + +static VOID +SHELL_CacheComputerDescription( + _In_ PCWSTR pszServerName, + _In_ PCWSTR pszDesc) +{ + if (!pszDesc) + return; + + SIZE_T cbDesc = (wcslen(pszDesc) + 1) * sizeof(WCHAR); + SHSetValueW(HKEY_CURRENT_USER, COMPUTER_DESCRIPTIONS_KEY, + SHELL_SkipServerSlashes(pszServerName), REG_SZ, pszDesc, (DWORD)cbDesc); +} + +static HRESULT +SHELL_GetCachedComputerDescription( + _Out_writes_z_(cchDescMax) PWSTR pszDesc, + _In_ DWORD cchDescMax, + _In_ PCWSTR pszServerName) +{ + cchDescMax *= sizeof(WCHAR); + DWORD error = SHGetValueW(HKEY_CURRENT_USER, COMPUTER_DESCRIPTIONS_KEY, + SHELL_SkipServerSlashes(pszServerName), NULL, pszDesc, &cchDescMax); + return HRESULT_FROM_WIN32(error); +} + +static HRESULT +SHELL_BuildDisplayMachineName( + _Out_writes_z_(cchNameMax) PWSTR pszName, + _In_ DWORD cchNameMax, + _In_ PCWSTR pszServerName, + _In_ PCWSTR pszDescription) +{ + if (!pszDescription || !*pszDescription) + return E_FAIL; + + PCWSTR pszFormat = (SHRestricted(REST_ALLOWCOMMENTTOGGLE) ? L"%2 (%1)" : L"%1 (%2)"); + PCWSTR args[] = { pszDescription , SHELL_SkipServerSlashes(pszServerName) }; + return (FormatMessageW(FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_FROM_STRING, + pszFormat, 0, 0, pszName, cchNameMax, (va_list *)args) ? S_OK : E_FAIL); +} + +static VOID +TEST_SHGetComputerDisplayNameW(VOID) +{ + WCHAR szCompName[MAX_COMPUTERNAME_LENGTH + 1], szDesc[256], szDisplayName[MAX_PATH]; + WCHAR szName[MAX_PATH], szServerName[] = L"DummyServerName"; + + DWORD cchCompName = _countof(szCompName); + BOOL ret = GetComputerNameW(szCompName, &cchCompName); + ok_int(ret, TRUE); + trace("%s\n", wine_dbgstr_w(szCompName)); + + SHELL_CacheComputerDescription(szServerName, L"DummyDescription"); + + HRESULT hr = SHELL_GetCachedComputerDescription(szDesc, _countof(szDesc), szServerName); + if (FAILED(hr)) + szDesc[0] = UNICODE_NULL; + trace("%s\n", wine_dbgstr_w(szDesc)); + + StringCchCopyW(szDisplayName, _countof(szDisplayName), L"@"); + hr = s_pSHGetComputerDisplayNameW(NULL, SHGCDN_NOCACHE, szDisplayName, _countof(szDisplayName)); + ok_hex(hr, S_OK); + trace("%s\n", wine_dbgstr_w(szDisplayName)); + ok_wstr(szDisplayName, szCompName); + + StringCchCopyW(szDisplayName, _countof(szDisplayName), L"@"); + hr = s_pSHGetComputerDisplayNameW(szServerName, 0, szDisplayName, _countof(szDisplayName)); + ok_hex(hr, S_OK); + trace("%s\n", wine_dbgstr_w(szServerName)); + ok_wstr(szServerName, L"DummyServerName"); + + hr = SHELL_BuildDisplayMachineName(szName, _countof(szName), szServerName, szDesc); + ok_hex(hr, S_OK); + + trace("%s\n", wine_dbgstr_w(szDisplayName)); + trace("%s\n", wine_dbgstr_w(szName)); + ok_wstr(szDisplayName, szName); + + // Delete registry value + HKEY hKey; + LSTATUS error = RegOpenKeyExW(HKEY_CURRENT_USER, COMPUTER_DESCRIPTIONS_KEY, 0, KEY_WRITE, &hKey); + if (error == ERROR_SUCCESS) + { + RegDeleteValueW(hKey, L"DummyServerName"); + RegCloseKey(hKey); + } +} + +START_TEST(SHGetComputerDisplayNameW) +{ + if (IsWindowsVistaOrGreater()) + { + skip("Tests on Vista+ will cause exception\n"); + return; + } + + HINSTANCE hShell32 = GetModuleHandleW(L"shell32.dll"); + s_pSHGetComputerDisplayNameW = + (FN_SHGetComputerDisplayNameW)GetProcAddress(hShell32, MAKEINTRESOURCEA(752)); + if (!s_pSHGetComputerDisplayNameW) + { + skip("SHGetComputerDisplayNameW not found\n"); + return; + } + + HINSTANCE hNetApi32 = LoadLibraryW(L"netapi32.dll"); + if (!hNetApi32) + { + skip("netapi32.dll not found\n"); + return; + } + + s_pNetServerGetInfo = (FN_NetServerGetInfo)GetProcAddress(hNetApi32, "NetServerGetInfo"); + s_pNetApiBufferFree = (FN_NetApiBufferFree)GetProcAddress(hNetApi32, "NetApiBufferFree"); + if (!s_pNetServerGetInfo || !s_pNetApiBufferFree) + { + skip("NetServerGetInfo or NetApiBufferFree not found\n"); + FreeLibrary(hNetApi32); + return; + } + + TEST_SHGetComputerDisplayNameW(); + + FreeLibrary(hNetApi32); +} diff --git a/modules/rostests/apitests/shell32/SHGetUnreadMailCountW.cpp b/modules/rostests/apitests/shell32/SHGetUnreadMailCountW.cpp new file mode 100644 index 0000000000000..a669cbe1269b8 --- /dev/null +++ b/modules/rostests/apitests/shell32/SHGetUnreadMailCountW.cpp @@ -0,0 +1,81 @@ +/* + * PROJECT: ReactOS API tests + * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) + * PURPOSE: Test for SHGetUnreadMailCountW + * COPYRIGHT: Copyright 2025 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) + */ + +#include "shelltest.h" + +static VOID SetUnreadMailInfo(PDWORD pdwDisposition) +{ + HKEY hKey; + LSTATUS error = RegCreateKeyExW( + HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\UnreadMail\\example.com", + 0, NULL, 0, KEY_WRITE, NULL, &hKey, pdwDisposition); + ok_long(error, ERROR_SUCCESS); + + DWORD dwCount = 1; + error = SHSetValueW(hKey, NULL, L"MessageCount", REG_DWORD, &dwCount, sizeof(dwCount)); + ok_long(error, ERROR_SUCCESS); + + FILETIME FileTime; + GetSystemTimeAsFileTime(&FileTime); + error = SHSetValueW(hKey, NULL, L"TimeStamp", REG_BINARY, &FileTime, sizeof(FileTime)); + ok_long(error, ERROR_SUCCESS); + + LPCWSTR pszApp = L"MyMailerApp"; + DWORD cbValue = (lstrlenW(pszApp) + 1) * sizeof(WCHAR); + error = SHSetValueW(hKey, NULL, L"Application", REG_SZ, pszApp, cbValue); + ok_long(error, ERROR_SUCCESS); + + RegCloseKey(hKey); +} + +START_TEST(SHGetUnreadMailCountW) +{ + HRESULT hr; + + DWORD dwDisposition; + SetUnreadMailInfo(&dwDisposition); + + hr = SHGetUnreadMailCountW(NULL, L"example.com", NULL, NULL, NULL, 0); + ok_hex(hr, S_OK); + + FILETIME FileTime; + ZeroMemory(&FileTime, sizeof(FileTime)); + hr = SHGetUnreadMailCountW(HKEY_CURRENT_USER, L"example.com", NULL, &FileTime, NULL, 0); + ok_hex(hr, S_OK); + ok(FileTime.dwHighDateTime != 0, "FileTime.dwHighDateTime was zero\n"); + + DWORD dwCount = 0; + ZeroMemory(&FileTime, sizeof(FileTime)); + hr = SHGetUnreadMailCountW(NULL, NULL, &dwCount, &FileTime, NULL, 0); + ok_hex(hr, S_OK); + ok_long(dwCount, 1); + ok_long(FileTime.dwHighDateTime, 0); + + dwCount = 0; + hr = SHGetUnreadMailCountW(NULL, L"example.com", &dwCount, NULL, NULL, 0); + ok_hex(hr, S_OK); + ok_long(dwCount, 1); + + hr = SHGetUnreadMailCountW(NULL, NULL, &dwCount, NULL, NULL, 0); + ok_hex(hr, S_OK); + + WCHAR szAppName[MAX_PATH]; + dwCount = 0; + hr = SHGetUnreadMailCountW(NULL, NULL, &dwCount, NULL, szAppName, _countof(szAppName)); + ok_hex(hr, E_INVALIDARG); + ok_long(dwCount, 0); + + hr = SHGetUnreadMailCountW(NULL, L"example.com", NULL, NULL, szAppName, _countof(szAppName)); + ok_hex(hr, S_OK); + ok_wstr(szAppName, L"MyMailerApp"); + + if (dwDisposition == REG_CREATED_NEW_KEY) + { + RegDeleteKeyW(HKEY_CURRENT_USER, + L"Software\\Microsoft\\Windows\\CurrentVersion\\UnreadMail\\example.com"); + } +} diff --git a/modules/rostests/apitests/shell32/SHGetUserDisplayName.cpp b/modules/rostests/apitests/shell32/SHGetUserDisplayName.cpp new file mode 100644 index 0000000000000..ed2fcc37587e7 --- /dev/null +++ b/modules/rostests/apitests/shell32/SHGetUserDisplayName.cpp @@ -0,0 +1,30 @@ +/* + * PROJECT: ReactOS API tests + * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) + * PURPOSE: Test for SHGetUserDisplayName + * COPYRIGHT: Copyright 2025 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) + */ + +#include "shelltest.h" +#include + +START_TEST(SHGetUserDisplayName) +{ + HRESULT hr; + WCHAR szBuf[MAX_PATH]; + ULONG cchBuf; + + hr = SHGetUserDisplayName(NULL, NULL); + ok_hex(hr, E_INVALIDARG); + + hr = SHGetUserDisplayName(szBuf, NULL); + ok_hex(hr, E_INVALIDARG); + + cchBuf = _countof(szBuf); + hr = SHGetUserDisplayName(NULL, &cchBuf); + ok_hex(hr, E_INVALIDARG); + + cchBuf = _countof(szBuf); + hr = SHGetUserDisplayName(szBuf, &cchBuf); + ok_hex(hr, S_OK); +} diff --git a/modules/rostests/apitests/shell32/SHIsBadInterfacePtr.cpp b/modules/rostests/apitests/shell32/SHIsBadInterfacePtr.cpp new file mode 100644 index 0000000000000..d90ad1dfb0120 --- /dev/null +++ b/modules/rostests/apitests/shell32/SHIsBadInterfacePtr.cpp @@ -0,0 +1,53 @@ +/* + * PROJECT: ReactOS API tests + * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) + * PURPOSE: Test for SHIsBadInterfacePtr + * COPYRIGHT: Copyright 2025 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) + */ + +#include "shelltest.h" +#include + +typedef BOOL (WINAPI *FN_SHIsBadInterfacePtr)(LPCVOID, UINT_PTR); + +static HRESULT STDMETHODCALLTYPE dummy_QueryInterface(REFIID riid, LPVOID *ppvObj) { return S_OK; } +static ULONG STDMETHODCALLTYPE dummy_AddRef() { return S_OK; } +static ULONG STDMETHODCALLTYPE dummy_Release() { return S_OK; } + +START_TEST(SHIsBadInterfacePtr) +{ + struct CUnknownVtbl + { + HRESULT (STDMETHODCALLTYPE *QueryInterface)(REFIID riid, LPVOID *ppvObj); + ULONG (STDMETHODCALLTYPE *AddRef)(); + ULONG (STDMETHODCALLTYPE *Release)(); + }; + struct CUnknown { CUnknownVtbl *lpVtbl; }; + + BOOL ret; + FN_SHIsBadInterfacePtr SHIsBadInterfacePtr = + (FN_SHIsBadInterfacePtr)GetProcAddress(GetModuleHandleW(L"shell32"), MAKEINTRESOURCEA(84)); + + if (!SHIsBadInterfacePtr) + { + skip("There is no SHIsBadInterfacePtr\n"); + return; + } + + ret = SHIsBadInterfacePtr(NULL, 1); + ok_int(ret, TRUE); + + CUnknown unk1 = { NULL }; + ret = SHIsBadInterfacePtr(&unk1, 1); + ok_int(ret, TRUE); + + CUnknownVtbl vtbl1 = { dummy_QueryInterface, dummy_AddRef, NULL }; + CUnknown unk2 = { &vtbl1 }; + ret = SHIsBadInterfacePtr(&unk2, 1); + ok_int(ret, TRUE); + + CUnknownVtbl vtbl2 = { dummy_QueryInterface, dummy_AddRef, dummy_Release }; + CUnknown unk3 = { &vtbl2 }; + ret = SHIsBadInterfacePtr(&unk3, 1); + ok_int(ret, FALSE); +} diff --git a/modules/rostests/apitests/shell32/SHSetUnreadMailCountW.cpp b/modules/rostests/apitests/shell32/SHSetUnreadMailCountW.cpp new file mode 100644 index 0000000000000..413ecb34335fc --- /dev/null +++ b/modules/rostests/apitests/shell32/SHSetUnreadMailCountW.cpp @@ -0,0 +1,58 @@ +/* + * PROJECT: ReactOS API tests + * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) + * PURPOSE: Test for SHSetUnreadMailCountW + * COPYRIGHT: Copyright 2025 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) + */ + +#include "shelltest.h" + +START_TEST(SHSetUnreadMailCountW) +{ + HKEY hKey; + LSTATUS error; + DWORD dwDisposition; + error = RegCreateKeyExW(HKEY_CURRENT_USER, + L"Software\\Microsoft\\Windows\\CurrentVersion\\UnreadMail\\example.com", + 0, NULL, 0, KEY_WRITE, NULL, &hKey, &dwDisposition); + ok_long(error, ERROR_SUCCESS); + RegCloseKey(hKey); + + HRESULT hr = SHSetUnreadMailCountW(L"example.com", 1, L"MyMailerApp"); + ok_hex(hr, S_OK); + + error = RegOpenKeyExW(HKEY_CURRENT_USER, + L"Software\\Microsoft\\Windows\\CurrentVersion\\UnreadMail\\example.com", + 0, + KEY_READ, + &hKey); + ok_long(error, ERROR_SUCCESS); + + DWORD dwValue, cbValue = sizeof(dwValue); + error = RegQueryValueExW(hKey, L"MessageCount", NULL, NULL, (PBYTE)&dwValue, &cbValue); + ok_long(error, ERROR_SUCCESS); + ok_long(dwValue, 1); + + FILETIME FileTime; + cbValue = sizeof(FileTime); + error = RegQueryValueExW(hKey, L"TimeStamp", NULL, NULL, (PBYTE)&FileTime, &cbValue); + ok_long(error, ERROR_SUCCESS); + ok(FileTime.dwHighDateTime != 0, "FileTime.dwHighDateTime was zero\n"); + + WCHAR szValue[MAX_PATH]; + cbValue = sizeof(szValue); + error = RegQueryValueExW(hKey, L"Application", NULL, NULL, (PBYTE)szValue, &cbValue); + ok_long(error, ERROR_SUCCESS); + ok_wstr(szValue, L"MyMailerApp"); + + RegCloseKey(hKey); + + hr = SHSetUnreadMailCountW(L"example.com", 0, L"MyMailerApp"); + ok_hex(hr, S_OK); + + if (dwDisposition == REG_CREATED_NEW_KEY) + { + RegDeleteKeyW(HKEY_CURRENT_USER, + L"Software\\Microsoft\\Windows\\CurrentVersion\\UnreadMail\\example.com"); + } +} diff --git a/modules/rostests/apitests/shell32/SHShouldShowWizards.cpp b/modules/rostests/apitests/shell32/SHShouldShowWizards.cpp new file mode 100644 index 0000000000000..07b2f5846e381 --- /dev/null +++ b/modules/rostests/apitests/shell32/SHShouldShowWizards.cpp @@ -0,0 +1,123 @@ +/* + * PROJECT: ReactOS API tests + * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) + * PURPOSE: Test for SHShouldShowWizards + * COPYRIGHT: Copyright 2025 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) + */ + +#include "shelltest.h" +#include +#include + +class CDummyClass + : public IServiceProvider + , public IShellBrowser +{ +public: + CDummyClass() { } + + IUnknown *GetUnknown() + { + return static_cast(this); + } + + // *** IUnknown methods *** + STDMETHODIMP QueryInterface(REFIID riid, VOID **ppvObj) override + { + if (riid == IID_IUnknown || riid == IID_IServiceProvider) + { + AddRef(); + *ppvObj = static_cast(this); + return S_OK; + } + return E_NOINTERFACE; + } + STDMETHODIMP_(ULONG) AddRef() override + { + return 1; + } + STDMETHODIMP_(ULONG) Release() override + { + return 1; + } + + // *** IOleWindow methods *** + STDMETHODIMP GetWindow(HWND *phwnd) override { return E_NOTIMPL; } + STDMETHODIMP ContextSensitiveHelp(BOOL fEnterMode) override { return E_NOTIMPL; } + + // *** IShellBrowser methods *** + STDMETHODIMP InsertMenusSB(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths) override { return E_NOTIMPL; } + STDMETHODIMP SetMenuSB(HMENU hmenuShared, HOLEMENU holemenuRes, HWND hwndActiveObject) override { return E_NOTIMPL; } + STDMETHODIMP RemoveMenusSB(HMENU hmenuShared) override { return E_NOTIMPL; } + STDMETHODIMP SetStatusTextSB(LPCOLESTR pszStatusText) override { return E_NOTIMPL; } + STDMETHODIMP EnableModelessSB(BOOL fEnable) override { return E_NOTIMPL; } + STDMETHODIMP TranslateAcceleratorSB(MSG *pmsg, WORD wID) override { return E_NOTIMPL; } + STDMETHODIMP BrowseObject(LPCITEMIDLIST pidl, UINT wFlags) override { return E_NOTIMPL; } + STDMETHODIMP GetViewStateStream(DWORD grfMode, IStream **ppStrm) override { return E_NOTIMPL; } + STDMETHODIMP GetControlWindow(UINT id, HWND *lphwnd) override { return E_NOTIMPL; } + STDMETHODIMP SendControlMsg(UINT id, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pret) override { return E_NOTIMPL; } + STDMETHODIMP QueryActiveShellView(struct IShellView **ppshv) override { return E_NOTIMPL; } + STDMETHODIMP OnViewWindowActive(struct IShellView *ppshv) override { return E_NOTIMPL; } + STDMETHODIMP SetToolbarItems(LPTBBUTTON lpButtons, UINT nButtons, UINT uFlags) override { return E_NOTIMPL; } + + // *** IServiceProvider methods *** + STDMETHODIMP QueryService(REFGUID guidService, REFIID riid, void **ppvObject) override + { + if (riid == IID_IShellBrowser) + { + AddRef(); + *ppvObject = static_cast(this); + return S_OK; + } + return E_FAIL; + } +}; + +static VOID SetShowWizardsTEST(BOOL bValue) +{ + DWORD dwValue = bValue; + SHRegSetUSValueW(L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", + L"ShowWizardsTEST", REG_DWORD, &dwValue, sizeof(dwValue), SHREGSET_FORCE_HKCU); +} + +START_TEST(SHShouldShowWizards) +{ + // Save old values + SHELLSTATE state; + SHGetSetSettings(&state, SSF_WEBVIEW, FALSE); + BOOL bOldWebView = state.fWebView; + BOOL bOldTestValue = SHRegGetBoolUSValueW( + L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", + L"ShowWizardsTEST", + FALSE, + FALSE); + + CDummyClass dummy; + HRESULT hr; + const BOOL bVistaPlus = IsWindowsVistaOrGreater(); + + state.fWebView = FALSE; + SHGetSetSettings(&state, SSF_WEBVIEW, TRUE); + SetShowWizardsTEST(FALSE); + hr = SHShouldShowWizards(dummy.GetUnknown()); + ok_hex(hr, bVistaPlus ? S_FALSE : S_OK); + + SetShowWizardsTEST(TRUE); + hr = SHShouldShowWizards(dummy.GetUnknown()); + ok_hex(hr, bVistaPlus ? S_FALSE : S_OK); + + state.fWebView = TRUE; + SHGetSetSettings(&state, SSF_WEBVIEW, TRUE); + SetShowWizardsTEST(FALSE); + hr = SHShouldShowWizards(dummy.GetUnknown()); + ok_hex(hr, S_FALSE); + + SetShowWizardsTEST(TRUE); + hr = SHShouldShowWizards(dummy.GetUnknown()); + ok_hex(hr, bVistaPlus ? S_FALSE : S_OK); + + // Restore old values + state.fWebView = bOldWebView; + SHGetSetSettings(&state, SSF_WEBVIEW, TRUE); + SetShowWizardsTEST(bOldTestValue); +} diff --git a/modules/rostests/apitests/shell32/ShellExec_RunDLL.cpp b/modules/rostests/apitests/shell32/ShellExec_RunDLL.cpp new file mode 100644 index 0000000000000..bea1d8b0682c8 --- /dev/null +++ b/modules/rostests/apitests/shell32/ShellExec_RunDLL.cpp @@ -0,0 +1,61 @@ +/* + * PROJECT: ReactOS API tests + * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) + * PURPOSE: Test for ShellExec_RunDLL + * COPYRIGHT: Copyright 2025 Katayama Hirofumi MZ + */ + +#include "shelltest.h" +#include "closewnd.h" +#include + +static WINDOW_LIST s_List1, s_List2; + +static VOID TEST_ShellExec_RunDLL(VOID) +{ + ShellExec_RunDLL(NULL, NULL, "?0?notepad.exe", SW_SHOWNORMAL); +} + +static VOID TEST_ShellExec_RunDLLA(VOID) +{ + ShellExec_RunDLLA(NULL, NULL, "?0?notepad.exe", SW_SHOWNORMAL); +} + +static VOID TEST_ShellExec_RunDLLW(VOID) +{ + ShellExec_RunDLLW(NULL, NULL, L"?0?notepad.exe", SW_SHOWNORMAL); +} + +static VOID CleanupWindowList(VOID) +{ + GetWindowListForClose(&s_List2); + CloseNewWindows(&s_List1, &s_List2); + FreeWindowList(&s_List1); + FreeWindowList(&s_List2); +} + +START_TEST(ShellExec_RunDLL) +{ + HWND hwndNotepad; + + GetWindowList(&s_List1); + TEST_ShellExec_RunDLL(); + Sleep(1000); + hwndNotepad = FindWindowW(L"Notepad", NULL); + ok(hwndNotepad != NULL, "Notepad not found\n"); + CleanupWindowList(); + + GetWindowList(&s_List1); + TEST_ShellExec_RunDLLA(); + Sleep(1000); + hwndNotepad = FindWindowW(L"Notepad", NULL); + ok(hwndNotepad != NULL, "Notepad not found\n"); + CleanupWindowList(); + + GetWindowList(&s_List1); + TEST_ShellExec_RunDLLW(); + Sleep(1000); + hwndNotepad = FindWindowW(L"Notepad", NULL); + ok(hwndNotepad != NULL, "Notepad not found\n"); + CleanupWindowList(); +} diff --git a/modules/rostests/apitests/shell32/StrRStr.cpp b/modules/rostests/apitests/shell32/StrRStr.cpp new file mode 100644 index 0000000000000..a78181f791f96 --- /dev/null +++ b/modules/rostests/apitests/shell32/StrRStr.cpp @@ -0,0 +1,97 @@ +/* + * PROJECT: ReactOS API tests + * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) + * PURPOSE: Test for StrRStrA/W + * COPYRIGHT: Copyright 2025 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) + */ + +#include "shelltest.h" +#include + +typedef PSTR (WINAPI *FN_StrRStrA)(PCSTR, PCSTR, PCSTR pszSearch); +typedef PWSTR (WINAPI *FN_StrRStrW)(PCWSTR, PCWSTR, PCWSTR pszSearch); + +static VOID TEST_StrRStrA(VOID) +{ + PCSTR psz, pch; + PSTR ret; + FN_StrRStrA StrRStrA = (FN_StrRStrA)GetProcAddress(GetModuleHandleW(L"shell32"), MAKEINTRESOURCEA(389)); + + if (!StrRStrA) + { + skip("StrRStrA not found\n"); + return; + } + + psz = "ABCBC"; + ret = StrRStrA(psz, NULL, "BC"); + ok_ptr(ret, psz + 3); + + psz = "ABCBC"; + pch = &psz[2]; + ret = StrRStrA(psz, pch, "BC"); + ok_ptr(ret, &psz[1]); + + psz = "ABCBC"; + ret = StrRStrA(psz, psz, "BC"); + ok(!ret, "ret was '%s'\n", ret); + + psz = "ABCBC"; + pch = &psz[lstrlenA(psz)]; + ret = StrRStrA(psz, pch, "BC"); + ok_ptr(ret, psz + 3); +} + +static VOID TEST_StrRStrW(VOID) +{ + PCWSTR psz, pch; + PWSTR ret; + FN_StrRStrW StrRStrW = (FN_StrRStrW)GetProcAddress(GetModuleHandleW(L"shell32"), MAKEINTRESOURCEA(392)); + + if (!StrRStrW) + { + skip("StrRStrW not found\n"); + return; + } + + psz = L"ABCBC"; + ret = StrRStrW(psz, NULL, L"BC"); + ok_ptr(ret, psz + 3); + + psz = L"ABCBC"; + pch = &psz[2]; + ret = StrRStrW(psz, pch, L"BC"); + ok_ptr(ret, &psz[1]); + + psz = L"ABCBC"; + ret = StrRStrW(psz, psz, L"BC"); + ok(!ret, "ret was '%S'\n", ret); + + psz = L"ABCBC"; + pch = &psz[lstrlenW(psz)]; + ret = StrRStrW(psz, pch, L"BC"); + ok_ptr(ret, psz + 3); +} + +static BOOL IsWindowsServer2003SP2OrGreater(VOID) +{ + return IsWindowsVersionOrGreater(5, 2, 2); +} + +START_TEST(StrRStr) +{ + if (IsWindowsVistaOrGreater()) + { + skip("Vista+\n"); + return; + } + + if (!IsWindowsServer2003SP2OrGreater()) + { + skip("Before 2K3 SP3\n"); + return; + } + + TEST_StrRStrA(); + TEST_StrRStrW(); +} diff --git a/modules/rostests/apitests/shell32/shelltest.cpp b/modules/rostests/apitests/shell32/shelltest.cpp index 65f0d42eeffce..ed49c8b94ef99 100644 --- a/modules/rostests/apitests/shell32/shelltest.cpp +++ b/modules/rostests/apitests/shell32/shelltest.cpp @@ -1,6 +1,6 @@ #include "shelltest.h" -// + Adapted from https://blogs.msdn.microsoft.com/oldnewthing/20130503-00/?p=4463/ +// + Adapted from https://devblogs.microsoft.com/oldnewthing/20130503-00/?p=4463 // In short: We want to create an IDLIST from an item that does not exist, // so we have to provide WIN32_FIND_DATAW in a bind context. // If we don't, the FS will be queried, and we do not get a valid IDLIST for a non-existing path. @@ -92,4 +92,4 @@ PathToIDList(LPCWSTR pszPath, ITEMIDLIST** ppidl) } } -// - Adapted from https://blogs.msdn.microsoft.com/oldnewthing/20130503-00/?p=4463/ +// - Adapted from https://devblogs.microsoft.com/oldnewthing/20130503-00/?p=4463 diff --git a/modules/rostests/apitests/shell32/testlist.c b/modules/rostests/apitests/shell32/testlist.c index ff06c5a5dc6a8..8df6bbc00b690 100644 --- a/modules/rostests/apitests/shell32/testlist.c +++ b/modules/rostests/apitests/shell32/testlist.c @@ -26,6 +26,8 @@ extern void func_menu(void); extern void func_OpenAs_RunDLL(void); extern void func_PathIsEqualOrSubFolder(void); extern void func_PathIsTemporary(void); +extern void func_PathMakeUniqueName(void); +extern void func_PathProcessCommand(void); extern void func_PathResolve(void); extern void func_PIDL(void); extern void func_RealShellExecuteEx(void); @@ -34,18 +36,28 @@ extern void func_SHChangeNotify(void); extern void func_SHCreateDataObject(void); extern void func_SHCreateFileDataObject(void); extern void func_SHCreateFileExtractIconW(void); +extern void func_SHDefExtractIcon(void); +extern void func_SHEnumerateUnreadMailAccountsW(void); extern void func_She(void); +extern void func_ShellExec_RunDLL(void); extern void func_ShellExecCmdLine(void); extern void func_ShellExecuteEx(void); extern void func_ShellExecuteW(void); extern void func_ShellHook(void); extern void func_ShellState(void); extern void func_SHGetAttributesFromDataObject(void); +extern void func_SHGetComputerDisplayNameW(void); extern void func_SHGetFileInfo(void); +extern void func_SHGetUnreadMailCountW(void); +extern void func_SHGetUserDisplayName(void); +extern void func_SHIsBadInterfacePtr(void); extern void func_SHLimitInputEdit(void); extern void func_SHParseDisplayName(void); +extern void func_SHShouldShowWizards(void); extern void func_SHSimpleIDListFromPath(void); extern void func_SHRestricted(void); +extern void func_SHSetUnreadMailCountW(void); +extern void func_StrRStr(void); const struct test winetest_testlist[] = { @@ -72,6 +84,8 @@ const struct test winetest_testlist[] = { "OpenAs_RunDLL", func_OpenAs_RunDLL }, { "PathIsEqualOrSubFolder", func_PathIsEqualOrSubFolder }, { "PathIsTemporary", func_PathIsTemporary }, + { "PathMakeUniqueName", func_PathMakeUniqueName }, + { "PathProcessCommand", func_PathProcessCommand }, { "PathResolve", func_PathResolve }, { "PIDL", func_PIDL }, { "RealShellExecuteEx", func_RealShellExecuteEx }, @@ -80,18 +94,28 @@ const struct test winetest_testlist[] = { "SHCreateDataObject", func_SHCreateDataObject }, { "SHCreateFileDataObject", func_SHCreateFileDataObject }, { "SHCreateFileExtractIconW", func_SHCreateFileExtractIconW }, + { "SHDefExtractIcon", func_SHDefExtractIcon }, + { "SHEnumerateUnreadMailAccountsW", func_SHEnumerateUnreadMailAccountsW }, { "She", func_She }, + { "ShellExec_RunDLL", func_ShellExec_RunDLL }, { "ShellExecCmdLine", func_ShellExecCmdLine }, { "ShellExecuteEx", func_ShellExecuteEx }, { "ShellExecuteW", func_ShellExecuteW }, { "ShellHook", func_ShellHook }, { "ShellState", func_ShellState }, { "SHGetAttributesFromDataObject", func_SHGetAttributesFromDataObject }, + { "SHGetComputerDisplayNameW", func_SHGetComputerDisplayNameW }, { "SHGetFileInfo", func_SHGetFileInfo }, + { "SHGetUnreadMailCountW", func_SHGetUnreadMailCountW }, + { "SHGetUserDisplayName", func_SHGetUserDisplayName }, + { "SHIsBadInterfacePtr", func_SHIsBadInterfacePtr }, { "SHLimitInputEdit", func_SHLimitInputEdit }, { "SHParseDisplayName", func_SHParseDisplayName }, + { "SHShouldShowWizards", func_SHShouldShowWizards }, { "SHSimpleIDListFromPath", func_SHSimpleIDListFromPath }, { "SHRestricted", func_SHRestricted }, + { "SHSetUnreadMailCountW", func_SHSetUnreadMailCountW }, + { "StrRStr", func_StrRStr }, { 0, 0 } }; diff --git a/modules/rostests/apitests/shlwapi/IShellFolderHelpers.cpp b/modules/rostests/apitests/shlwapi/IShellFolderHelpers.cpp index 588ef3f329cba..0a94af1c3e77e 100644 --- a/modules/rostests/apitests/shlwapi/IShellFolderHelpers.cpp +++ b/modules/rostests/apitests/shlwapi/IShellFolderHelpers.cpp @@ -10,8 +10,8 @@ #include #include -#define SHLWAPI_ISHELLFOLDER_HELPERS #include +#include static INT s_nStep = 0; diff --git a/modules/rostests/apitests/shlwapi/PathIsUNC.c b/modules/rostests/apitests/shlwapi/PathIsUNC.c index 3b9d7868b2a98..d4aef57717c95 100644 --- a/modules/rostests/apitests/shlwapi/PathIsUNC.c +++ b/modules/rostests/apitests/shlwapi/PathIsUNC.c @@ -16,7 +16,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* Documentation: https://msdn.microsoft.com/en-us/library/windows/desktop/bb773712(v=vs.85).aspx */ +/* Documentation: https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-pathisunca */ #include #include diff --git a/modules/rostests/apitests/shlwapi/PathIsUNCServer.c b/modules/rostests/apitests/shlwapi/PathIsUNCServer.c index 8827d7de3c8b6..140e06a097f91 100644 --- a/modules/rostests/apitests/shlwapi/PathIsUNCServer.c +++ b/modules/rostests/apitests/shlwapi/PathIsUNCServer.c @@ -16,7 +16,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* Documentation: https://msdn.microsoft.com/en-us/library/windows/desktop/bb773722(v=vs.85).aspx */ +/* Documentation: https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-pathisuncservera */ #include #include diff --git a/modules/rostests/apitests/shlwapi/PathIsUNCServerShare.c b/modules/rostests/apitests/shlwapi/PathIsUNCServerShare.c index f4f1f863f8dbf..313627ced9c5a 100644 --- a/modules/rostests/apitests/shlwapi/PathIsUNCServerShare.c +++ b/modules/rostests/apitests/shlwapi/PathIsUNCServerShare.c @@ -16,7 +16,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* Documentation: https://msdn.microsoft.com/en-us/library/windows/desktop/bb773723(v=vs.85).aspx */ +/* Documentation: https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-pathisuncserversharea */ #include #include diff --git a/modules/rostests/apitests/shlwapi/StrFormatByteSizeW.c b/modules/rostests/apitests/shlwapi/StrFormatByteSizeW.c index 5127676c47db8..6c8f84a9f0970 100644 --- a/modules/rostests/apitests/shlwapi/StrFormatByteSizeW.c +++ b/modules/rostests/apitests/shlwapi/StrFormatByteSizeW.c @@ -16,7 +16,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* Documentation: https://msdn.microsoft.com/en-us/library/windows/desktop/bb759975(v=vs.85).aspx */ +/* Documentation: https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-strformatbytesizew */ #include #include diff --git a/modules/rostests/apitests/user32/CopyImage.c b/modules/rostests/apitests/user32/CopyImage.c index bad7c472f4fed..2280b20a6ba9c 100644 --- a/modules/rostests/apitests/user32/CopyImage.c +++ b/modules/rostests/apitests/user32/CopyImage.c @@ -3,6 +3,7 @@ * LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+) * PURPOSE: Test for SetFocus/GetFocus/GetGUIThreadInfo * COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ +* Copyright 2024 Doug Lyons */ #include "precomp.h" @@ -76,9 +77,61 @@ Test_CopyImage_Flags(UINT uType) DeleteObject(hImage); } +static VOID +Test_CopyImage_hImage_NULL(void) +{ + HANDLE hImg; + DWORD LastError; + + /* Test NULL HANDLE return and GetLastError return. */ + SetLastError(0xdeadbeef); + hImg = CopyImage(NULL, IMAGE_ICON, 16, 16, LR_COPYFROMRESOURCE); + LastError = GetLastError(); + ok(LastError == ERROR_INVALID_CURSOR_HANDLE, "Wrong error 0x%08lx returned\n", LastError); + ok(!hImg, "Image returned should have been NULL, hImg was %p\n", hImg); + + SetLastError(0xdeadbeef); + hImg = CopyImage(NULL, IMAGE_BITMAP, 16, 16, LR_COPYFROMRESOURCE); + LastError = GetLastError(); + ok(LastError == ERROR_INVALID_HANDLE, "Wrong error 0x%08lx returned\n", LastError); + ok(!hImg, "Image returned should have been NULL, hImg was %p\n", hImg); + + + SetLastError(0xdeadbeef); + hImg = CopyImage(NULL, IMAGE_CURSOR, 16, 16, LR_COPYFROMRESOURCE); + LastError = GetLastError(); + ok(LastError == ERROR_INVALID_CURSOR_HANDLE, "Wrong error 0x%08lx returned\n", LastError); + ok(!hImg, "Image returned should have been NULL, hImg was %p\n", hImg); + + /* Test bad Flags for Invalid Parameter return */ + SetLastError(0xdeadbeef); + /* 0x80000000 is an invalid flag value */ + hImg = CopyImage(NULL, IMAGE_BITMAP, 16, 16, 0x80000000); + LastError = GetLastError(); + ok(LastError == ERROR_INVALID_PARAMETER, "Wrong error 0x%08lx returned\n", LastError); + ok(!hImg, "Image returned should have been NULL, hImg was %p\n", hImg); + + /* Test bad Type (5) GetLastError return value. Not Icon, Cursor, or Bitmap. */ + SetLastError(0xdeadbeef); + hImg = CopyImage(NULL, 5, 16, 16, LR_COPYFROMRESOURCE); + LastError = GetLastError(); + ok(LastError == ERROR_INVALID_PARAMETER, "Wrong error 0x%08lx returned\n", LastError); + ok(!hImg, "Image returned should have been NULL, hImg was %p\n", hImg); + + /* Test bad type (5) GetLastError return value with good HANDLE */ + hImg = CreateTestImage(IMAGE_ICON); + SetLastError(0xdeadbeef); + hImg = CopyImage(hImg, 5, 16, 16, LR_COPYFROMRESOURCE); + LastError = GetLastError(); + ok(LastError == ERROR_INVALID_PARAMETER, "Wrong error 0x%08lx returned\n", LastError); + ok(!hImg, "Image returned should have been NULL, hImg was %p\n", hImg); + DeleteObject(hImg); +} + START_TEST(CopyImage) { Test_CopyImage_Flags(IMAGE_BITMAP); Test_CopyImage_Flags(IMAGE_CURSOR); Test_CopyImage_Flags(IMAGE_ICON); + Test_CopyImage_hImage_NULL(); } diff --git a/modules/rostests/apitests/user32/PrivateExtractIcons.c b/modules/rostests/apitests/user32/PrivateExtractIcons.c index aff24a195ed98..8b63aa714a5a7 100644 --- a/modules/rostests/apitests/user32/PrivateExtractIcons.c +++ b/modules/rostests/apitests/user32/PrivateExtractIcons.c @@ -8,6 +8,20 @@ #include "precomp.h" #include +#include + +BOOL IsValidIcon(HICON hIco) +{ + ICONINFO info = { 0 }; + + if (!hIco || !GetIconInfo(hIco, &info)) + return FALSE; + + DeleteObject(info.hbmMask); + if (info.hbmColor) + DeleteObject(info.hbmColor); + return TRUE; +} BOOL FileExists(PCWSTR FileName) { @@ -110,11 +124,14 @@ static struct {L"%temp%\\cpimg2e.exe", IDR_EXE_NORMAL} }; +void TestPairExtraction(void); + START_TEST(PrivateExtractIcons) { HICON ahIcon; UINT i, aIconId, cIcons, cIcoTotal; WCHAR PathBuffer[MAX_PATH]; + UINT Shell32WinIcoCount = IsWindowsVistaOrGreater() ? 326 : 239; /* 239 on W2K3SP2, 326 on Win10 */ /* Extract icons */ for (i = 0; i < _countof(IconFiles); ++i) @@ -125,6 +142,8 @@ START_TEST(PrivateExtractIcons) goto Cleanup; } + TestPairExtraction(); + for (i = 0; i < _countof(IconTests); ++i) { /* Get total number of icon groups in file. @@ -132,7 +151,7 @@ START_TEST(PrivateExtractIcons) * two NULLs for the Icon Handle and Count to be set. */ cIcoTotal = PrivateExtractIconsW(IconTests[i].FilePath, 0, 16, 16, NULL, NULL, 0, 0); ok((i == 3 ? - cIcoTotal > 232 && cIcoTotal < 240 : /* shell32 case: ROS has 233, W2K2SP2 has 239 icon groups. */ + cIcoTotal > 232 && cIcoTotal <= Shell32WinIcoCount : /* shell32 case: ROS has 233, Windows has >= 239 icon groups. */ cIcoTotal == IconTests[i].cTotalIcons), "PrivateExtractIconsW(%u): " "got %u, expected %u\n", i, cIcoTotal, IconTests[i].cTotalIcons); @@ -167,3 +186,67 @@ START_TEST(PrivateExtractIcons) DeleteFileW(PathBuffer); } } + +static const struct tagPAIRSTESTS +{ + BYTE InCount; + BYTE UseHigh; // Extract a pair (high and low word sizes) + BYTE Library; + BYTE ReturnNT5; + BYTE CountNT5; + BYTE ReturnNT6; + BYTE CountNT6; +} g_pairs[] = +{ + { 0, 0, 0, 1, 1, 1, 1 }, + { 0, 0, 1, 0, 0, 0, 0 }, + { 0, 1, 0, 1, 2, 1, 2 }, + { 0, 1, 1, 0, 0, 0, 0 }, + { 1, 0, 0, 1, 1, 1, 1 }, + { 1, 0, 1, 1, 1, 1, 1 }, + { 1, 1, 0, 1, 2, 1, 2 }, + { 1, 1, 1, 2, 2, 0, 0 }, + { 2, 0, 0, 1, 1, 1, 1 }, + { 2, 0, 1, 2, 2, 2, 2 }, + { 2, 1, 0, 1, 2, 1, 2 }, + { 2, 1, 1, 2, 2, 2, 2 }, // This is the only way to extract a pair from a PE on NT6! + { 3, 0, 0, 1, 1, 1, 1 }, + { 3, 0, 1, 3, 3, 3, 3 }, + { 3, 1, 0, 1, 2, 1, 2 }, + { 3, 1, 1, 4, 4, 0, 0 }, + { 4, 0, 0, 1, 1, 1, 1 }, + { 4, 0, 1, 4, 4, 4, 4 }, + { 4, 1, 0, 1, 2, 1, 2 }, + { 4, 1, 1, 4, 4, 4, 4 } +}; + +void TestPairExtraction(void) +{ + const HICON hInvalidIcon = (HICON)(INT_PTR)-2; + const BOOL IsNT6 = IsWindowsVistaOrGreater(); + for (UINT i = 0; i < _countof(g_pairs); ++i) + { + UINT j, Count, ExpectedCount; + int RetVal, ExpectedRet; + UINT IcoSize = MAKELONG(32, g_pairs[i].UseHigh ? 16 : 0); + PCWSTR pszPath = g_pairs[i].Library ? L"%SystemRoot%\\system32\\shell32.dll" : L"%temp%\\sysicon.ico"; + HICON hIcons[8]; + for (j = 0; j < _countof(hIcons); ++j) + hIcons[j] = hInvalidIcon; + + RetVal = PrivateExtractIconsW(pszPath, 0, IcoSize, IcoSize, hIcons, NULL, g_pairs[i].InCount, 0); + for (j = 0, Count = 0; j < _countof(hIcons); ++j) + { + if (hIcons[j] != hInvalidIcon && IsValidIcon(hIcons[j])) + { + DestroyIcon(hIcons[j]); + ++Count; + } + } + + ExpectedRet = !IsNT6 ? g_pairs[i].ReturnNT5 : g_pairs[i].ReturnNT6; + ExpectedCount = !IsNT6 ? g_pairs[i].CountNT5 : g_pairs[i].CountNT6; + ok(RetVal == ExpectedRet, "Test %u: RetVal must be %d but got %d\n", i, ExpectedRet, RetVal); + ok(Count == ExpectedCount, "Test %u: Count must be %u but got %u\n", i, ExpectedCount, Count); + } +} diff --git a/modules/rostests/apitests/user32/RedrawWindow.c b/modules/rostests/apitests/user32/RedrawWindow.c index c5ce8d333f42a..a36b6291e2a87 100644 --- a/modules/rostests/apitests/user32/RedrawWindow.c +++ b/modules/rostests/apitests/user32/RedrawWindow.c @@ -34,7 +34,7 @@ WndProc( return DefWindowProcW(hWnd, message, wParam, lParam); } -void GetMessageRedrawWindowTest() +void GetMessageRedrawWindowTest(void) { HWND hWnd; MSG msg; @@ -52,9 +52,9 @@ void GetMessageRedrawWindowTest() ShowWindow(hWnd, SW_SHOW); - while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) + while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) { - DispatchMessageA( &msg ); + DispatchMessageW(&msg); } ok(got_paint == TRUE, "Did not process WM_PAINT message\n"); @@ -66,7 +66,7 @@ void GetMessageRedrawWindowTest() ok(ret == TRUE, "RedrawWindow failed\n"); i = 0; - while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) + while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) { RECORD_MESSAGE(1, msg.message, POST, 0, 0); if (msg.message == WM_PAINT) @@ -79,7 +79,7 @@ void GetMessageRedrawWindowTest() } if (msg.message != WM_PAINT || i >= 10) { - DispatchMessageA( &msg ); + DispatchMessageW(&msg); } } @@ -136,12 +136,13 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return 0; } } - return DefWindowProc(hwnd, uMsg, wParam, lParam); + return DefWindowProcW(hwnd, uMsg, wParam, lParam); } LRESULT CALLBACK ChildWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { - switch (uMsg) { + switch (uMsg) + { case WM_SYNCPAINT: { PAINTSTRUCT ps; @@ -168,7 +169,7 @@ LRESULT CALLBACK ChildWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lPa return 0; } } - return DefWindowProc(hwnd, uMsg, wParam, lParam); + return DefWindowProcW(hwnd, uMsg, wParam, lParam); } typedef struct STRUCT_TestRedrawWindow @@ -223,10 +224,10 @@ void ServeSomeMessages(int messageTime, int messageCount) startTime = GetTickCount(); while (GetTickCount() - startTime < messageTime * messageCount) { - if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + if (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); - DispatchMessage(&msg); + DispatchMessageW(&msg); } else { @@ -235,7 +236,8 @@ void ServeSomeMessages(int messageTime, int messageCount) } } -void TestRedrawWindow(STRUCT_TestRedrawWindow* ptestRW) { +void TestRedrawWindow(STRUCT_TestRedrawWindow* ptestRW) +{ DWORD style; int width; int height; @@ -252,7 +254,7 @@ void TestRedrawWindow(STRUCT_TestRedrawWindow* ptestRW) { wc.hInstance = GetModuleHandle(NULL); wc.lpszClassName = ptestRW->testName; RegisterClassW(&wc); - RECT rectWin = { 0, 0, 800, 600 }; + RECT rectWin = { 0, 0, 700, 500 }; style = WS_OVERLAPPEDWINDOW; AdjustWindowRectEx(&rectWin, style, FALSE, 0); width = rectWin.right - rectWin.left; @@ -261,6 +263,7 @@ void TestRedrawWindow(STRUCT_TestRedrawWindow* ptestRW) { CW_USEDEFAULT, CW_USEDEFAULT, width, height, NULL, NULL, GetModuleHandle(NULL), NULL); if (hwnd == NULL) return; + MoveWindow(hwnd, 10, 10, width, height, TRUE); ShowWindow(hwnd, SW_SHOW); if(!ptestRW->testChild) @@ -285,10 +288,12 @@ void TestRedrawWindow(STRUCT_TestRedrawWindow* ptestRW) { GetModuleHandle(NULL), NULL ); + if (hChildWnd == NULL) + return; } HDC hdc = GetDC(hwnd); - RECT drect = { 0, 0, 800, 600 }; + RECT drect = { 0, 0, 700, 500 }; DrawContent(hdc, &drect, RGB(255, 0, 0)); ReleaseDC(hwnd, hdc); @@ -298,7 +303,7 @@ void TestRedrawWindow(STRUCT_TestRedrawWindow* ptestRW) { RgnUpdate = CreateRectRgn(ptestRW->regRect.left, ptestRW->regRect.top, ptestRW->regRect.right, ptestRW->regRect.bottom); } - prect=NULL; + prect = NULL; if (ptestRW->useRect) { prect = &ptestRW->rectRect; @@ -337,7 +342,8 @@ void TestRedrawWindow(STRUCT_TestRedrawWindow* ptestRW) { ptestRW->resultWmNcPaint = resultWmNcPaint; ptestRW->resultPaintIndex = paintIndex; - if (RgnUpdate) DeleteObject(RgnUpdate); + if (RgnUpdate) + DeleteObject(RgnUpdate); if (hChildWnd != NULL) DestroyWindow(hChildWnd); @@ -425,14 +431,7 @@ UINT TestRedrawWindow2(STRUCT_TestRedrawWindow* ptestRW, STRUCT_TestRedrawWindow return countErrors; } -void InitRect(RECT *rect, int left, int top, int right, int bottom) { - rect->left = left; - rect->top = top; - rect->right = right; - rect->bottom = bottom; -} - -void FlagsRedrawWindowTest() +void FlagsRedrawWindowTest(void) { STRUCT_TestRedrawWindow testRW; STRUCT_TestRedrawWindowCompare testRWcompare; @@ -440,19 +439,22 @@ void FlagsRedrawWindowTest() testRW.testPixelPre1x = 50; testRW.testPixelPre1y = 50; testRW.testPixelPre2x = 50; - testRW.testPixelPre2y = 550; + testRW.testPixelPre2y = 400; testRW.testPixelPost1x = 50; testRW.testPixelPost1y = 50; testRW.testPixelPost2x = 50; - testRW.testPixelPost2y = 550; + testRW.testPixelPost2y = 400; + + trace("Screen Width/Height (%dx%d)\n", + GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)); // RDW_ERASE tests testRW.testName = L"Test1"; testRW.flags = 0; testRW.useRegion = TRUE; - InitRect(&testRW.regRect, 0, 500, 800, 600); + SetRect(&testRW.regRect, 0, 300, 700, 500); testRW.useRect = FALSE; - InitRect(&testRW.rectRect, 0, 0, 200, 200); + SetRect(&testRW.rectRect, 0, 0, 200, 200); testRW.forcePaint = TRUE; testRW.testChild = FALSE; @@ -460,7 +462,7 @@ void FlagsRedrawWindowTest() testRWcompare.resultColorPre2 = 0x000000FF; testRWcompare.resultColorPost1 = 0x000000FF; testRWcompare.resultColorPost2 = 0x000000FF; - InitRect(&testRWcompare.resultUpdateRect, 0, 0, 200, 200); + SetRect(&testRWcompare.resultUpdateRect, 0, 0, 200, 200); testRWcompare.resultNeedsUpdate = FALSE; testRWcompare.resultWmEraseGnd = FALSE; testRWcompare.resultWmNcPaint = FALSE; @@ -470,9 +472,9 @@ void FlagsRedrawWindowTest() testRW.testName = L"Test2"; testRW.flags = RDW_ERASE; testRW.useRegion = TRUE; - InitRect(&testRW.regRect, 0, 500, 800, 600); + SetRect(&testRW.regRect, 0, 300, 700, 500); testRW.useRect = FALSE; - InitRect(&testRW.rectRect, 0, 0, 200, 200); + SetRect(&testRW.rectRect, 0, 0, 200, 200); testRW.forcePaint = TRUE; testRW.testChild = FALSE; @@ -480,7 +482,7 @@ void FlagsRedrawWindowTest() testRWcompare.resultColorPre2 = 0x000000FF; testRWcompare.resultColorPost1 = 0x000000FF; testRWcompare.resultColorPost2 = 0x000000FF; - InitRect(&testRWcompare.resultUpdateRect, 0, 0, 200, 200); + SetRect(&testRWcompare.resultUpdateRect, 0, 0, 200, 200); testRWcompare.resultNeedsUpdate = FALSE; testRWcompare.resultWmEraseGnd = FALSE; testRWcompare.resultWmNcPaint = FALSE; @@ -490,9 +492,9 @@ void FlagsRedrawWindowTest() testRW.testName = L"Test3"; testRW.flags = RDW_INVALIDATE; testRW.useRegion = TRUE; - InitRect(&testRW.regRect, 0, 500, 800, 600); + SetRect(&testRW.regRect, 0, 300, 700, 500); testRW.useRect = FALSE; - InitRect(&testRW.rectRect, 0, 0, 200, 200); + SetRect(&testRW.rectRect, 0, 0, 200, 200); testRW.forcePaint = TRUE; testRW.testChild = FALSE; @@ -500,7 +502,7 @@ void FlagsRedrawWindowTest() testRWcompare.resultColorPre2 = 0x000000FF; testRWcompare.resultColorPost1 = 0x000000FF; testRWcompare.resultColorPost2 = 0x0000FF00; - InitRect(&testRWcompare.resultUpdateRect, 0, 500, 800, 600); + SetRect(&testRWcompare.resultUpdateRect, 0, 300, 700, 500); testRWcompare.resultNeedsUpdate = TRUE; testRWcompare.resultWmEraseGnd = FALSE; testRWcompare.resultWmNcPaint = FALSE; @@ -510,9 +512,9 @@ void FlagsRedrawWindowTest() testRW.testName = L"Test4"; testRW.flags = RDW_INVALIDATE | RDW_ERASE; testRW.useRegion = TRUE; - InitRect(&testRW.regRect, 0, 500, 800, 600); + SetRect(&testRW.regRect, 0, 300, 700, 500); testRW.useRect = FALSE; - InitRect(&testRW.rectRect, 0, 0, 200, 200); + SetRect(&testRW.rectRect, 0, 0, 200, 200); testRW.forcePaint = TRUE; testRW.testChild = FALSE; @@ -520,7 +522,7 @@ void FlagsRedrawWindowTest() testRWcompare.resultColorPre2 = 0x000000FF; testRWcompare.resultColorPost1 = 0x000000FF; testRWcompare.resultColorPost2 = 0x0000FF00; - InitRect(&testRWcompare.resultUpdateRect, 0, 500, 800, 600); + SetRect(&testRWcompare.resultUpdateRect, 0, 300, 700, 500); testRWcompare.resultNeedsUpdate = TRUE; testRWcompare.resultWmEraseGnd = TRUE; testRWcompare.resultWmNcPaint = FALSE; @@ -531,9 +533,9 @@ void FlagsRedrawWindowTest() testRW.testName = L"Test5"; testRW.flags = RDW_FRAME; testRW.useRegion = TRUE; - InitRect(&testRW.regRect, 0, 500, 800, 600); + SetRect(&testRW.regRect, 0, 300, 700, 500); testRW.useRect = FALSE; - InitRect(&testRW.rectRect, 0, 0, 200, 200); + SetRect(&testRW.rectRect, 0, 0, 200, 200); testRW.forcePaint = TRUE; testRW.testChild = FALSE; @@ -541,7 +543,7 @@ void FlagsRedrawWindowTest() testRWcompare.resultColorPre2 = 0x000000FF; testRWcompare.resultColorPost1 = 0x000000FF; testRWcompare.resultColorPost2 = 0x000000FF; - InitRect(&testRWcompare.resultUpdateRect, 0, 500, 800, 600); + SetRect(&testRWcompare.resultUpdateRect, 0, 300, 700, 500); testRWcompare.resultNeedsUpdate = FALSE; testRWcompare.resultWmEraseGnd = FALSE; testRWcompare.resultWmNcPaint = FALSE; @@ -551,9 +553,9 @@ void FlagsRedrawWindowTest() testRW.testName = L"Test6"; testRW.flags = RDW_INVALIDATE | RDW_FRAME; testRW.useRegion = TRUE; - InitRect(&testRW.regRect, 0, 500, 800, 600); + SetRect(&testRW.regRect, 0, 300, 700, 500); testRW.useRect = FALSE; - InitRect(&testRW.rectRect, 0, 0, 200, 200); + SetRect(&testRW.rectRect, 0, 0, 200, 200); testRW.forcePaint = TRUE; testRW.testChild = FALSE; @@ -561,7 +563,7 @@ void FlagsRedrawWindowTest() testRWcompare.resultColorPre2 = 0x000000FF; testRWcompare.resultColorPost1 = 0x000000FF; testRWcompare.resultColorPost2 = 0x0000FF00; - InitRect(&testRWcompare.resultUpdateRect, 0, 500, 800, 600); + SetRect(&testRWcompare.resultUpdateRect, 0, 300, 700, 500); testRWcompare.resultNeedsUpdate = TRUE; testRWcompare.resultWmEraseGnd = FALSE; testRWcompare.resultWmNcPaint = TRUE; @@ -572,9 +574,9 @@ void FlagsRedrawWindowTest() testRW.testName = L"Test7"; testRW.flags = RDW_INTERNALPAINT; testRW.useRegion = TRUE; - InitRect(&testRW.regRect, 0, 500, 800, 600); + SetRect(&testRW.regRect, 0, 300, 700, 500); testRW.useRect = FALSE; - InitRect(&testRW.rectRect, 0, 0, 200, 200); + SetRect(&testRW.rectRect, 0, 0, 200, 200); testRW.forcePaint = TRUE; testRW.testChild = FALSE; @@ -582,7 +584,7 @@ void FlagsRedrawWindowTest() testRWcompare.resultColorPre2 = 0x000000FF; testRWcompare.resultColorPost1 = 0x000000FF; testRWcompare.resultColorPost2 = 0x000000FF; - InitRect(&testRWcompare.resultUpdateRect, 0, 500, 800, 600); + SetRect(&testRWcompare.resultUpdateRect, 0, 300, 700, 500); testRWcompare.resultNeedsUpdate = FALSE; testRWcompare.resultWmEraseGnd = FALSE; testRWcompare.resultWmNcPaint = FALSE; @@ -592,9 +594,9 @@ void FlagsRedrawWindowTest() testRW.testName = L"Test8"; testRW.flags = RDW_INVALIDATE | RDW_INTERNALPAINT; testRW.useRegion = TRUE; - InitRect(&testRW.regRect, 0, 500, 800, 600); + SetRect(&testRW.regRect, 0, 300, 700, 500); testRW.useRect = FALSE; - InitRect(&testRW.rectRect, 0, 0, 200, 200); + SetRect(&testRW.rectRect, 0, 0, 200, 200); testRW.forcePaint = TRUE; testRW.testChild = FALSE; @@ -602,7 +604,7 @@ void FlagsRedrawWindowTest() testRWcompare.resultColorPre2 = 0x000000FF; testRWcompare.resultColorPost1 = 0x000000FF; testRWcompare.resultColorPost2 = 0x0000FF00; - InitRect(&testRWcompare.resultUpdateRect, 0, 500, 800, 600); + SetRect(&testRWcompare.resultUpdateRect, 0, 300, 700, 500); testRWcompare.resultNeedsUpdate = TRUE; testRWcompare.resultWmEraseGnd = FALSE; testRWcompare.resultWmNcPaint = FALSE; @@ -613,9 +615,9 @@ void FlagsRedrawWindowTest() testRW.testName = L"Test9"; testRW.flags = RDW_NOERASE; testRW.useRegion = TRUE; - InitRect(&testRW.regRect, 0, 500, 800, 600); + SetRect(&testRW.regRect, 0, 300, 700, 500); testRW.useRect = FALSE; - InitRect(&testRW.rectRect, 0, 0, 200, 200); + SetRect(&testRW.rectRect, 0, 0, 200, 200); testRW.forcePaint = TRUE; testRW.testChild = FALSE; @@ -623,7 +625,7 @@ void FlagsRedrawWindowTest() testRWcompare.resultColorPre2 = 0x000000FF; testRWcompare.resultColorPost1 = 0x000000FF; testRWcompare.resultColorPost2 = 0x000000FF; - InitRect(&testRWcompare.resultUpdateRect, 0, 500, 800, 600); + SetRect(&testRWcompare.resultUpdateRect, 0, 300, 700, 500); testRWcompare.resultNeedsUpdate = FALSE; testRWcompare.resultWmEraseGnd = FALSE; testRWcompare.resultWmNcPaint = FALSE; @@ -633,9 +635,9 @@ void FlagsRedrawWindowTest() testRW.testName = L"Test10"; testRW.flags = RDW_INVALIDATE | RDW_NOERASE; testRW.useRegion = TRUE; - InitRect(&testRW.regRect, 0, 500, 800, 600); + SetRect(&testRW.regRect, 0, 300, 700, 500); testRW.useRect = FALSE; - InitRect(&testRW.rectRect, 0, 0, 200, 200); + SetRect(&testRW.rectRect, 0, 0, 200, 200); testRW.forcePaint = TRUE; testRW.testChild = FALSE; @@ -643,7 +645,7 @@ void FlagsRedrawWindowTest() testRWcompare.resultColorPre2 = 0x000000FF; testRWcompare.resultColorPost1 = 0x000000FF; testRWcompare.resultColorPost2 = 0x0000FF00; - InitRect(&testRWcompare.resultUpdateRect, 0, 500, 800, 600); + SetRect(&testRWcompare.resultUpdateRect, 0, 300, 700, 500); testRWcompare.resultNeedsUpdate = TRUE; testRWcompare.resultWmEraseGnd = FALSE; testRWcompare.resultWmNcPaint = FALSE; @@ -653,9 +655,9 @@ void FlagsRedrawWindowTest() testRW.testName = L"Test11"; testRW.flags = RDW_NOERASE | RDW_ERASE; testRW.useRegion = TRUE; - InitRect(&testRW.regRect, 0, 500, 800, 600); + SetRect(&testRW.regRect, 0, 300, 700, 500); testRW.useRect = FALSE; - InitRect(&testRW.rectRect, 0, 0, 200, 200); + SetRect(&testRW.rectRect, 0, 0, 200, 200); testRW.forcePaint = TRUE; testRW.testChild = FALSE; @@ -663,7 +665,7 @@ void FlagsRedrawWindowTest() testRWcompare.resultColorPre2 = 0x000000FF; testRWcompare.resultColorPost1 = 0x000000FF; testRWcompare.resultColorPost2 = 0x000000FF; - InitRect(&testRWcompare.resultUpdateRect, 0, 500, 800, 600); + SetRect(&testRWcompare.resultUpdateRect, 0, 300, 700, 500); testRWcompare.resultNeedsUpdate = FALSE; testRWcompare.resultWmEraseGnd = FALSE; testRWcompare.resultWmNcPaint = FALSE; @@ -673,9 +675,9 @@ void FlagsRedrawWindowTest() testRW.testName = L"Test12"; testRW.flags = RDW_INVALIDATE | RDW_NOERASE | RDW_ERASE; testRW.useRegion = TRUE; - InitRect(&testRW.regRect, 0, 500, 800, 600); + SetRect(&testRW.regRect, 0, 300, 700, 500); testRW.useRect = FALSE; - InitRect(&testRW.rectRect, 0, 0, 200, 200); + SetRect(&testRW.rectRect, 0, 0, 200, 200); testRW.forcePaint = TRUE; testRW.testChild = FALSE; @@ -683,7 +685,7 @@ void FlagsRedrawWindowTest() testRWcompare.resultColorPre2 = 0x000000FF; testRWcompare.resultColorPost1 = 0x000000FF; testRWcompare.resultColorPost2 = 0x0000FF00; - InitRect(&testRWcompare.resultUpdateRect, 0, 500, 800, 600); + SetRect(&testRWcompare.resultUpdateRect, 0, 300, 700, 500); testRWcompare.resultNeedsUpdate = TRUE; testRWcompare.resultWmEraseGnd = TRUE; testRWcompare.resultWmNcPaint = FALSE; @@ -694,9 +696,9 @@ void FlagsRedrawWindowTest() testRW.testName = L"Test13"; testRW.flags = RDW_NOFRAME; testRW.useRegion = TRUE; - InitRect(&testRW.regRect, 0, 500, 800, 600); + SetRect(&testRW.regRect, 0, 300, 700, 500); testRW.useRect = FALSE; - InitRect(&testRW.rectRect, 0, 0, 200, 200); + SetRect(&testRW.rectRect, 0, 0, 200, 200); testRW.forcePaint = TRUE; testRW.testChild = FALSE; @@ -704,7 +706,7 @@ void FlagsRedrawWindowTest() testRWcompare.resultColorPre2 = 0x000000FF; testRWcompare.resultColorPost1 = 0x000000FF; testRWcompare.resultColorPost2 = 0x000000FF; - InitRect(&testRWcompare.resultUpdateRect, 0, 500, 800, 600); + SetRect(&testRWcompare.resultUpdateRect, 0, 300, 700, 500); testRWcompare.resultNeedsUpdate = FALSE; testRWcompare.resultWmEraseGnd = FALSE; testRWcompare.resultWmNcPaint = FALSE; @@ -714,9 +716,9 @@ void FlagsRedrawWindowTest() testRW.testName = L"Test14"; testRW.flags = RDW_INVALIDATE | RDW_NOFRAME; testRW.useRegion = TRUE; - InitRect(&testRW.regRect, 0, 500, 800, 600); + SetRect(&testRW.regRect, 0, 300, 700, 500); testRW.useRect = FALSE; - InitRect(&testRW.rectRect, 0, 0, 200, 200); + SetRect(&testRW.rectRect, 0, 0, 200, 200); testRW.forcePaint = TRUE; testRW.testChild = FALSE; @@ -724,7 +726,7 @@ void FlagsRedrawWindowTest() testRWcompare.resultColorPre2 = 0x000000FF; testRWcompare.resultColorPost1 = 0x000000FF; testRWcompare.resultColorPost2 = 0x0000FF00; - InitRect(&testRWcompare.resultUpdateRect, 0, 500, 800, 600); + SetRect(&testRWcompare.resultUpdateRect, 0, 300, 700, 500); testRWcompare.resultNeedsUpdate = TRUE; testRWcompare.resultWmEraseGnd = FALSE; testRWcompare.resultWmNcPaint = FALSE; @@ -734,9 +736,9 @@ void FlagsRedrawWindowTest() testRW.testName = L"Test15"; testRW.flags = RDW_INVALIDATE | RDW_VALIDATE | RDW_NOFRAME; testRW.useRegion = TRUE; - InitRect(&testRW.regRect, 0, 500, 800, 600); + SetRect(&testRW.regRect, 0, 300, 700, 500); testRW.useRect = FALSE; - InitRect(&testRW.rectRect, 0, 0, 200, 200); + SetRect(&testRW.rectRect, 0, 0, 200, 200); testRW.forcePaint = TRUE; testRW.testChild = FALSE; @@ -744,7 +746,7 @@ void FlagsRedrawWindowTest() testRWcompare.resultColorPre2 = 0x000000FF; testRWcompare.resultColorPost1 = 0x000000FF; testRWcompare.resultColorPost2 = 0x0000FF00; - InitRect(&testRWcompare.resultUpdateRect, 0, 500, 800, 600); + SetRect(&testRWcompare.resultUpdateRect, 0, 300, 700, 500); testRWcompare.resultNeedsUpdate = TRUE; testRWcompare.resultWmEraseGnd = FALSE; testRWcompare.resultWmNcPaint = FALSE; @@ -754,9 +756,9 @@ void FlagsRedrawWindowTest() testRW.testName = L"Test16"; testRW.flags = RDW_VALIDATE | RDW_NOFRAME; testRW.useRegion = TRUE; - InitRect(&testRW.regRect, 0, 500, 800, 600); + SetRect(&testRW.regRect, 0, 300, 700, 500); testRW.useRect = FALSE; - InitRect(&testRW.rectRect, 0, 0, 200, 200); + SetRect(&testRW.rectRect, 0, 0, 200, 200); testRW.forcePaint = TRUE; testRW.testChild = FALSE; @@ -764,7 +766,7 @@ void FlagsRedrawWindowTest() testRWcompare.resultColorPre2 = 0x000000FF; testRWcompare.resultColorPost1 = 0x000000FF; testRWcompare.resultColorPost2 = 0x000000FF; - InitRect(&testRWcompare.resultUpdateRect, 0, 500, 800, 600); + SetRect(&testRWcompare.resultUpdateRect, 0, 300, 700, 500); testRWcompare.resultNeedsUpdate = FALSE; testRWcompare.resultWmEraseGnd = FALSE; testRWcompare.resultWmNcPaint = FALSE; @@ -775,9 +777,9 @@ void FlagsRedrawWindowTest() testRW.testName = L"Test17"; testRW.flags = RDW_NOINTERNALPAINT; testRW.useRegion = TRUE; - InitRect(&testRW.regRect, 0, 500, 800, 600); + SetRect(&testRW.regRect, 0, 300, 700, 500); testRW.useRect = FALSE; - InitRect(&testRW.rectRect, 0, 0, 200, 200); + SetRect(&testRW.rectRect, 0, 0, 200, 200); testRW.forcePaint = TRUE; testRW.testChild = FALSE; @@ -785,7 +787,7 @@ void FlagsRedrawWindowTest() testRWcompare.resultColorPre2 = 0x000000FF; testRWcompare.resultColorPost1 = 0x000000FF; testRWcompare.resultColorPost2 = 0x000000FF; - InitRect(&testRWcompare.resultUpdateRect, 0, 500, 800, 600); + SetRect(&testRWcompare.resultUpdateRect, 0, 300, 700, 500); testRWcompare.resultNeedsUpdate = FALSE; testRWcompare.resultWmEraseGnd = FALSE; testRWcompare.resultWmNcPaint = FALSE; @@ -795,9 +797,9 @@ void FlagsRedrawWindowTest() testRW.testName = L"Test18"; testRW.flags = RDW_INVALIDATE | RDW_NOINTERNALPAINT; testRW.useRegion = TRUE; - InitRect(&testRW.regRect, 0, 500, 800, 600); + SetRect(&testRW.regRect, 0, 300, 700, 500); testRW.useRect = FALSE; - InitRect(&testRW.rectRect, 0, 0, 200, 200); + SetRect(&testRW.rectRect, 0, 0, 200, 200); testRW.forcePaint = TRUE; testRW.testChild = FALSE; @@ -805,7 +807,7 @@ void FlagsRedrawWindowTest() testRWcompare.resultColorPre2 = 0x000000FF; testRWcompare.resultColorPost1 = 0x000000FF; testRWcompare.resultColorPost2 = 0x0000FF00; - InitRect(&testRWcompare.resultUpdateRect, 0, 500, 800, 600); + SetRect(&testRWcompare.resultUpdateRect, 0, 300, 700, 500); testRWcompare.resultNeedsUpdate = TRUE; testRWcompare.resultWmEraseGnd = FALSE; testRWcompare.resultWmNcPaint = FALSE; @@ -815,9 +817,9 @@ void FlagsRedrawWindowTest() testRW.testName = L"Test19"; testRW.flags = RDW_VALIDATE | RDW_NOINTERNALPAINT; testRW.useRegion = TRUE; - InitRect(&testRW.regRect, 0, 500, 800, 600); + SetRect(&testRW.regRect, 0, 300, 700, 500); testRW.useRect = FALSE; - InitRect(&testRW.rectRect, 0, 0, 200, 200); + SetRect(&testRW.rectRect, 0, 0, 200, 200); testRW.forcePaint = TRUE; testRW.testChild = FALSE; @@ -825,7 +827,7 @@ void FlagsRedrawWindowTest() testRWcompare.resultColorPre2 = 0x000000FF; testRWcompare.resultColorPost1 = 0x000000FF; testRWcompare.resultColorPost2 = 0x000000FF; - InitRect(&testRWcompare.resultUpdateRect, 0, 500, 800, 600); + SetRect(&testRWcompare.resultUpdateRect, 0, 300, 700, 500); testRWcompare.resultNeedsUpdate = FALSE; testRWcompare.resultWmEraseGnd = FALSE; testRWcompare.resultWmNcPaint = FALSE; @@ -836,9 +838,9 @@ void FlagsRedrawWindowTest() testRW.testName = L"Test20"; testRW.flags = RDW_ERASENOW; testRW.useRegion = TRUE; - InitRect(&testRW.regRect, 0, 500, 800, 600); + SetRect(&testRW.regRect, 0, 300, 700, 500); testRW.useRect = FALSE; - InitRect(&testRW.rectRect, 0, 0, 200, 200); + SetRect(&testRW.rectRect, 0, 0, 200, 200); testRW.forcePaint = TRUE; testRW.testChild = FALSE; @@ -846,7 +848,7 @@ void FlagsRedrawWindowTest() testRWcompare.resultColorPre2 = 0x000000FF; testRWcompare.resultColorPost1 = 0x000000FF; testRWcompare.resultColorPost2 = 0x000000FF; - InitRect(&testRWcompare.resultUpdateRect, 0, 500, 800, 600); + SetRect(&testRWcompare.resultUpdateRect, 0, 300, 700, 500); testRWcompare.resultNeedsUpdate = FALSE; testRWcompare.resultWmEraseGnd = FALSE; testRWcompare.resultWmNcPaint = FALSE; @@ -856,9 +858,9 @@ void FlagsRedrawWindowTest() testRW.testName = L"Test21"; testRW.flags = RDW_INVALIDATE | RDW_ERASENOW; testRW.useRegion = TRUE; - InitRect(&testRW.regRect, 0, 500, 800, 600); + SetRect(&testRW.regRect, 0, 300, 700, 500); testRW.useRect = FALSE; - InitRect(&testRW.rectRect, 0, 0, 200, 200); + SetRect(&testRW.rectRect, 0, 0, 200, 200); testRW.forcePaint = TRUE; testRW.testChild = FALSE; @@ -866,7 +868,7 @@ void FlagsRedrawWindowTest() testRWcompare.resultColorPre2 = 0x000000FF; testRWcompare.resultColorPost1 = 0x000000FF; testRWcompare.resultColorPost2 = 0x0000FF00; - InitRect(&testRWcompare.resultUpdateRect, 0, 500, 800, 600); + SetRect(&testRWcompare.resultUpdateRect, 0, 300, 700, 500); testRWcompare.resultNeedsUpdate = TRUE; testRWcompare.resultWmEraseGnd = FALSE; testRWcompare.resultWmNcPaint = FALSE; @@ -876,9 +878,9 @@ void FlagsRedrawWindowTest() testRW.testName = L"Test22"; testRW.flags = RDW_VALIDATE | RDW_ERASENOW; testRW.useRegion = TRUE; - InitRect(&testRW.regRect, 0, 500, 800, 600); + SetRect(&testRW.regRect, 0, 300, 700, 500); testRW.useRect = FALSE; - InitRect(&testRW.rectRect, 0, 0, 200, 200); + SetRect(&testRW.rectRect, 0, 0, 200, 200); testRW.forcePaint = TRUE; testRW.testChild = FALSE; @@ -886,7 +888,7 @@ void FlagsRedrawWindowTest() testRWcompare.resultColorPre2 = 0x000000FF; testRWcompare.resultColorPost1 = 0x000000FF; testRWcompare.resultColorPost2 = 0x000000FF; - InitRect(&testRWcompare.resultUpdateRect, 0, 500, 800, 600); + SetRect(&testRWcompare.resultUpdateRect, 0, 300, 700, 500); testRWcompare.resultNeedsUpdate = FALSE; testRWcompare.resultWmEraseGnd = FALSE; testRWcompare.resultWmNcPaint = FALSE; @@ -897,9 +899,9 @@ void FlagsRedrawWindowTest() testRW.testName = L"Test23"; testRW.flags = RDW_UPDATENOW; testRW.useRegion = TRUE; - InitRect(&testRW.regRect, 0, 500, 800, 600); + SetRect(&testRW.regRect, 0, 300, 700, 500); testRW.useRect = FALSE; - InitRect(&testRW.rectRect, 0, 0, 200, 200); + SetRect(&testRW.rectRect, 0, 0, 200, 200); testRW.forcePaint = TRUE; testRW.testChild = FALSE; @@ -907,7 +909,7 @@ void FlagsRedrawWindowTest() testRWcompare.resultColorPre2 = 0x000000FF; testRWcompare.resultColorPost1 = 0x000000FF; testRWcompare.resultColorPost2 = 0x000000FF; - InitRect(&testRWcompare.resultUpdateRect, 0, 500, 800, 600); + SetRect(&testRWcompare.resultUpdateRect, 0, 300, 700, 500); testRWcompare.resultNeedsUpdate = FALSE; testRWcompare.resultWmEraseGnd = FALSE; testRWcompare.resultWmNcPaint = FALSE; @@ -917,9 +919,9 @@ void FlagsRedrawWindowTest() testRW.testName = L"Test24"; testRW.flags = RDW_INVALIDATE | RDW_UPDATENOW; testRW.useRegion = TRUE; - InitRect(&testRW.regRect, 0, 500, 800, 600); + SetRect(&testRW.regRect, 0, 300, 700, 500); testRW.useRect = FALSE; - InitRect(&testRW.rectRect, 0, 0, 200, 200); + SetRect(&testRW.rectRect, 0, 0, 200, 200); testRW.forcePaint = TRUE; testRW.testChild = FALSE; @@ -927,7 +929,7 @@ void FlagsRedrawWindowTest() testRWcompare.resultColorPre2 = 0x0000FF00; testRWcompare.resultColorPost1 = 0x000000FF; testRWcompare.resultColorPost2 = 0x0000FF00; - InitRect(&testRWcompare.resultUpdateRect, 0, 500, 800, 600); + SetRect(&testRWcompare.resultUpdateRect, 0, 300, 700, 500); testRWcompare.resultNeedsUpdate = FALSE; testRWcompare.resultWmEraseGnd = FALSE; testRWcompare.resultWmNcPaint = FALSE; @@ -937,9 +939,9 @@ void FlagsRedrawWindowTest() testRW.testName = L"Test25"; testRW.flags = RDW_VALIDATE | RDW_UPDATENOW; testRW.useRegion = TRUE; - InitRect(&testRW.regRect, 0, 500, 800, 600); + SetRect(&testRW.regRect, 0, 300, 700, 500); testRW.useRect = FALSE; - InitRect(&testRW.rectRect, 0, 0, 200, 200); + SetRect(&testRW.rectRect, 0, 0, 200, 200); testRW.forcePaint = TRUE; testRW.testChild = FALSE; @@ -947,7 +949,7 @@ void FlagsRedrawWindowTest() testRWcompare.resultColorPre2 = 0x000000FF; testRWcompare.resultColorPost1 = 0x000000FF; testRWcompare.resultColorPost2 = 0x000000FF; - InitRect(&testRWcompare.resultUpdateRect, 0, 500, 800, 600); + SetRect(&testRWcompare.resultUpdateRect, 0, 300, 700, 500); testRWcompare.resultNeedsUpdate = FALSE; testRWcompare.resultWmEraseGnd = FALSE; testRWcompare.resultWmNcPaint = FALSE; @@ -958,9 +960,9 @@ void FlagsRedrawWindowTest() testRW.testName = L"Test26"; testRW.flags = RDW_NOCHILDREN; testRW.useRegion = FALSE; - InitRect(&testRW.regRect, 0, 500, 800, 600); + SetRect(&testRW.regRect, 0, 300, 700, 500); testRW.useRect = FALSE; - InitRect(&testRW.rectRect, 0, 0, 200, 200); + SetRect(&testRW.rectRect, 0, 0, 200, 200); testRW.forcePaint = TRUE; testRW.testChild = TRUE; @@ -968,7 +970,7 @@ void FlagsRedrawWindowTest() testRWcompare.resultColorPre2 = 0x0000FF00; testRWcompare.resultColorPost1 = 0x00FF0000; testRWcompare.resultColorPost2 = 0x0000FF00; - InitRect(&testRWcompare.resultUpdateRect, 0, 500, 800, 600); + SetRect(&testRWcompare.resultUpdateRect, 0, 300, 700, 500); testRWcompare.resultNeedsUpdate = FALSE; testRWcompare.resultWmEraseGnd = FALSE; testRWcompare.resultWmNcPaint = FALSE; @@ -978,9 +980,9 @@ void FlagsRedrawWindowTest() testRW.testName = L"Test27"; testRW.flags = RDW_INVALIDATE | RDW_NOCHILDREN; testRW.useRegion = FALSE; - InitRect(&testRW.regRect, 0, 500, 800, 600); + SetRect(&testRW.regRect, 0, 300, 700, 500); testRW.useRect = FALSE; - InitRect(&testRW.rectRect, 0, 0, 200, 200); + SetRect(&testRW.rectRect, 0, 0, 200, 200); testRW.forcePaint = TRUE; testRW.testChild = TRUE; @@ -988,7 +990,7 @@ void FlagsRedrawWindowTest() testRWcompare.resultColorPre2 = 0x0000FF00; testRWcompare.resultColorPost1 = 0x0000FF00; testRWcompare.resultColorPost2 = 0x0000FF00; - InitRect(&testRWcompare.resultUpdateRect, 0, 500, 800, 600); + SetRect(&testRWcompare.resultUpdateRect, 0, 300, 700, 500); testRWcompare.resultNeedsUpdate = FALSE; testRWcompare.resultWmEraseGnd = FALSE; testRWcompare.resultWmNcPaint = FALSE; @@ -998,9 +1000,9 @@ void FlagsRedrawWindowTest() testRW.testName = L"Test28"; testRW.flags = RDW_VALIDATE | RDW_NOCHILDREN; testRW.useRegion = FALSE; - InitRect(&testRW.regRect, 0, 500, 800, 600); + SetRect(&testRW.regRect, 0, 300, 700, 500); testRW.useRect = FALSE; - InitRect(&testRW.rectRect, 0, 0, 200, 200); + SetRect(&testRW.rectRect, 0, 0, 200, 200); testRW.forcePaint = TRUE; testRW.testChild = TRUE; @@ -1008,7 +1010,7 @@ void FlagsRedrawWindowTest() testRWcompare.resultColorPre2 = 0x0000FF00; testRWcompare.resultColorPost1 = 0x00FF0000; testRWcompare.resultColorPost2 = 0x0000FF00; - InitRect(&testRWcompare.resultUpdateRect, 0, 500, 800, 600); + SetRect(&testRWcompare.resultUpdateRect, 0, 300, 700, 500); testRWcompare.resultNeedsUpdate = FALSE; testRWcompare.resultWmEraseGnd = FALSE; testRWcompare.resultWmNcPaint = FALSE; @@ -1018,9 +1020,9 @@ void FlagsRedrawWindowTest() testRW.testName = L"Test29"; testRW.flags = RDW_ALLCHILDREN; testRW.useRegion = FALSE; - InitRect(&testRW.regRect, 0, 500, 800, 600); + SetRect(&testRW.regRect, 0, 300, 700, 500); testRW.useRect = FALSE; - InitRect(&testRW.rectRect, 0, 0, 200, 200); + SetRect(&testRW.rectRect, 0, 0, 200, 200); testRW.forcePaint = TRUE; testRW.testChild = TRUE; @@ -1028,7 +1030,7 @@ void FlagsRedrawWindowTest() testRWcompare.resultColorPre2 = 0x0000FF00; testRWcompare.resultColorPost1 = 0x00FF0000; testRWcompare.resultColorPost2 = 0x0000FF00; - InitRect(&testRWcompare.resultUpdateRect, 0, 500, 800, 600); + SetRect(&testRWcompare.resultUpdateRect, 0, 300, 700, 500); testRWcompare.resultNeedsUpdate = FALSE; testRWcompare.resultWmEraseGnd = FALSE; testRWcompare.resultWmNcPaint = FALSE; @@ -1038,9 +1040,9 @@ void FlagsRedrawWindowTest() testRW.testName = L"Test30"; testRW.flags = RDW_INVALIDATE | RDW_ALLCHILDREN; testRW.useRegion = FALSE; - InitRect(&testRW.regRect, 0, 500, 800, 600); + SetRect(&testRW.regRect, 0, 300, 700, 500); testRW.useRect = FALSE; - InitRect(&testRW.rectRect, 0, 0, 200, 200); + SetRect(&testRW.rectRect, 0, 0, 200, 200); testRW.forcePaint = TRUE; testRW.testChild = TRUE; @@ -1048,7 +1050,7 @@ void FlagsRedrawWindowTest() testRWcompare.resultColorPre2 = 0x0000FF00; testRWcompare.resultColorPre1 = 0x00FF0000; testRWcompare.resultColorPost2 = 0x0000FF00; - InitRect(&testRWcompare.resultUpdateRect, 0, 500, 800, 600); + SetRect(&testRWcompare.resultUpdateRect, 0, 300, 700, 500); testRWcompare.resultNeedsUpdate = FALSE; testRWcompare.resultWmEraseGnd = FALSE; testRWcompare.resultWmNcPaint = FALSE; @@ -1058,9 +1060,9 @@ void FlagsRedrawWindowTest() testRW.testName = L"Test31"; testRW.flags = RDW_VALIDATE | RDW_ALLCHILDREN; testRW.useRegion = FALSE; - InitRect(&testRW.regRect, 0, 500, 800, 600); + SetRect(&testRW.regRect, 0, 300, 700, 500); testRW.useRect = FALSE; - InitRect(&testRW.rectRect, 0, 0, 200, 200); + SetRect(&testRW.rectRect, 0, 0, 200, 200); testRW.forcePaint = TRUE; testRW.testChild = TRUE; @@ -1068,7 +1070,7 @@ void FlagsRedrawWindowTest() testRWcompare.resultColorPre2 = 0x0000FF00; testRWcompare.resultColorPost1 = 0x00FF0000; testRWcompare.resultColorPost2 = 0x0000FF00; - InitRect(&testRWcompare.resultUpdateRect, 0, 500, 800, 600); + SetRect(&testRWcompare.resultUpdateRect, 0, 300, 700, 500); testRWcompare.resultNeedsUpdate = FALSE; testRWcompare.resultWmEraseGnd = FALSE; testRWcompare.resultWmNcPaint = FALSE; @@ -1078,9 +1080,9 @@ void FlagsRedrawWindowTest() testRW.testName = L"Test32"; testRW.flags = RDW_NOCHILDREN; testRW.useRegion = TRUE; - InitRect(&testRW.regRect, 0, 500, 800, 600); + SetRect(&testRW.regRect, 0, 300, 700, 500); testRW.useRect = FALSE; - InitRect(&testRW.rectRect, 0, 0, 200, 200); + SetRect(&testRW.rectRect, 0, 0, 200, 200); testRW.forcePaint = TRUE; testRW.testChild = TRUE; @@ -1088,7 +1090,7 @@ void FlagsRedrawWindowTest() testRWcompare.resultColorPre2 = 0x0000FF00; testRWcompare.resultColorPost1 = 0x00FF0000; testRWcompare.resultColorPost2 = 0x0000FF00; - InitRect(&testRWcompare.resultUpdateRect, 0, 500, 800, 600); + SetRect(&testRWcompare.resultUpdateRect, 0, 300, 700, 500); testRWcompare.resultNeedsUpdate = FALSE; testRWcompare.resultWmEraseGnd = FALSE; testRWcompare.resultWmNcPaint = FALSE; @@ -1098,9 +1100,9 @@ void FlagsRedrawWindowTest() testRW.testName = L"Test33"; testRW.flags = RDW_INVALIDATE | RDW_NOCHILDREN; testRW.useRegion = TRUE; - InitRect(&testRW.regRect, 0, 500, 800, 600); + SetRect(&testRW.regRect, 0, 300, 700, 500); testRW.useRect = FALSE; - InitRect(&testRW.rectRect, 0, 0, 200, 200); + SetRect(&testRW.rectRect, 0, 0, 200, 200); testRW.forcePaint = TRUE; testRW.testChild = TRUE; @@ -1108,7 +1110,7 @@ void FlagsRedrawWindowTest() testRWcompare.resultColorPre2 = 0x0000FF00; testRWcompare.resultColorPre1 = 0x00FF0000; testRWcompare.resultColorPost2 = 0x0000FF00; - InitRect(&testRWcompare.resultUpdateRect, 0, 500, 800, 600); + SetRect(&testRWcompare.resultUpdateRect, 0, 300, 700, 500); testRWcompare.resultNeedsUpdate = FALSE; testRWcompare.resultWmEraseGnd = FALSE; testRWcompare.resultWmNcPaint = FALSE; @@ -1118,9 +1120,9 @@ void FlagsRedrawWindowTest() testRW.testName = L"Test34"; testRW.flags = RDW_VALIDATE | RDW_NOCHILDREN; testRW.useRegion = TRUE; - InitRect(&testRW.regRect, 0, 500, 800, 600); + SetRect(&testRW.regRect, 0, 300, 700, 500); testRW.useRect = FALSE; - InitRect(&testRW.rectRect, 0, 0, 200, 200); + SetRect(&testRW.rectRect, 0, 0, 200, 200); testRW.forcePaint = TRUE; testRW.testChild = TRUE; @@ -1128,7 +1130,7 @@ void FlagsRedrawWindowTest() testRWcompare.resultColorPre2 = 0x0000FF00; testRWcompare.resultColorPost1 = 0x00FF0000; testRWcompare.resultColorPost2 = 0x0000FF00; - InitRect(&testRWcompare.resultUpdateRect, 0, 500, 800, 600); + SetRect(&testRWcompare.resultUpdateRect, 0, 300, 700, 500); testRWcompare.resultNeedsUpdate = FALSE; testRWcompare.resultWmEraseGnd = FALSE; testRWcompare.resultWmNcPaint = FALSE; @@ -1139,9 +1141,9 @@ void FlagsRedrawWindowTest() testRW.testName = L"Test35"; testRW.flags = 0; testRW.useRegion = FALSE; - InitRect(&testRW.regRect, 0, 500, 800, 600); + SetRect(&testRW.regRect, 0, 300, 700, 500); testRW.useRect = TRUE; - InitRect(&testRW.rectRect, 0, 500, 800, 600); + SetRect(&testRW.rectRect, 0, 300, 700, 500); testRW.forcePaint = TRUE; testRW.testChild = FALSE; @@ -1149,7 +1151,7 @@ void FlagsRedrawWindowTest() testRWcompare.resultColorPre2 = 0x000000FF; testRWcompare.resultColorPost1 = 0x000000FF; testRWcompare.resultColorPost2 = 0x000000FF; - InitRect(&testRWcompare.resultUpdateRect, 0, 0, 200, 200); + SetRect(&testRWcompare.resultUpdateRect, 0, 0, 200, 200); testRWcompare.resultNeedsUpdate = FALSE; testRWcompare.resultWmEraseGnd = FALSE; testRWcompare.resultWmNcPaint = FALSE; @@ -1159,9 +1161,9 @@ void FlagsRedrawWindowTest() testRW.testName = L"Test36"; testRW.flags = RDW_INVALIDATE | RDW_ERASENOW; testRW.useRegion = FALSE; - InitRect(&testRW.regRect, 0, 500, 800, 600); + SetRect(&testRW.regRect, 0, 300, 700, 500); testRW.useRect = TRUE; - InitRect(&testRW.rectRect, 0, 500, 800, 600); + SetRect(&testRW.rectRect, 0, 300, 700, 500); testRW.forcePaint = TRUE; testRW.testChild = FALSE; @@ -1169,7 +1171,7 @@ void FlagsRedrawWindowTest() testRWcompare.resultColorPre2 = 0x000000FF; testRWcompare.resultColorPost1 = 0x000000FF; testRWcompare.resultColorPost2 = 0x0000FF00; - InitRect(&testRWcompare.resultUpdateRect, 0, 500, 800, 600); + SetRect(&testRWcompare.resultUpdateRect, 0, 300, 700, 500); testRWcompare.resultNeedsUpdate = TRUE; testRWcompare.resultWmEraseGnd = FALSE; testRWcompare.resultWmNcPaint = FALSE; diff --git a/modules/rostests/apitests/user32/keybd_event.c b/modules/rostests/apitests/user32/keybd_event.c index 39475e883ae01..d5b132fabd299 100644 --- a/modules/rostests/apitests/user32/keybd_event.c +++ b/modules/rostests/apitests/user32/keybd_event.c @@ -20,7 +20,7 @@ static void testScancodeExtendedKey(BYTE wVk, BYTE scanCode) ok(!(winKeyState & 0x8000), "VK=%x should be detected as key up.\n", wVk); } -/* https://docs.microsoft.com/en-us/windows/win32/inputdev/about-keyboard-input#extended-key-flag */ +/* https://learn.microsoft.com/en-us/windows/win32/inputdev/about-keyboard-input#extended-key-flag */ START_TEST(keybd_event) { testScancodeExtendedKey(VK_RWIN, 0x5C); diff --git a/modules/rostests/apitests/uxtheme/CMakeLists.txt b/modules/rostests/apitests/uxtheme/CMakeLists.txt index ccb6706977901..0af753947672d 100644 --- a/modules/rostests/apitests/uxtheme/CMakeLists.txt +++ b/modules/rostests/apitests/uxtheme/CMakeLists.txt @@ -2,6 +2,7 @@ list(APPEND SOURCE CloseThemeData.c DrawThemeParentBackground.c + GetThemeParseErrorInfo.c SetWindowTheme.c SetThemeAppProperties.c ../include/msgtrace.c diff --git a/modules/rostests/apitests/uxtheme/GetThemeParseErrorInfo.c b/modules/rostests/apitests/uxtheme/GetThemeParseErrorInfo.c new file mode 100644 index 0000000000000..4d54c226ea7fc --- /dev/null +++ b/modules/rostests/apitests/uxtheme/GetThemeParseErrorInfo.c @@ -0,0 +1,92 @@ +/* + * PROJECT: ReactOS API tests + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Tests for GetThemeParseErrorInfo + * COPYRIGHT: Copyright 2025 Katayama Hirofumi MZ + */ + +#include +#include +#include +#include +#include +#include + +typedef HRESULT (WINAPI *FN_GetThemeParseErrorInfo)(PPARSE_ERROR_INFO); +typedef HRESULT (WINAPI *FN_ParseThemeIniFile)(LPCWSTR, LPWSTR, PARSETHEMEINIFILEPROC, LPVOID); + +static BOOL CALLBACK +ParseThemeIniFileProc( + DWORD dwType, + LPWSTR pszParam1, + LPWSTR pszParam2, + LPWSTR pszParam3, + DWORD dwParam, + LPVOID lpData) +{ + return TRUE; +} + +START_TEST(GetThemeParseErrorInfo) +{ + HRESULT hr; + PARSE_ERROR_INFO Info; + WCHAR szPath[MAX_PATH]; + + FN_GetThemeParseErrorInfo GetThemeParseErrorInfo = + (FN_GetThemeParseErrorInfo)GetProcAddress(GetModuleHandleW(L"uxtheme.dll"), MAKEINTRESOURCEA(48)); + if (!GetThemeParseErrorInfo) + { + skip("No GetThemeParseErrorInfo found\n"); + return; + } + + hr = GetThemeParseErrorInfo(NULL); + ok_hex(hr, E_POINTER); + + ZeroMemory(&Info, sizeof(Info)); + hr = GetThemeParseErrorInfo(&Info); + ok_hex(hr, E_INVALIDARG); + + ZeroMemory(&Info, sizeof(Info)); + Info.cbSize = sizeof(Info); + hr = GetThemeParseErrorInfo(&Info); + ok_hex(hr, HRESULT_FROM_WIN32(ERROR_RESOURCE_NAME_NOT_FOUND)); + + FN_ParseThemeIniFile ParseThemeIniFile = + (FN_ParseThemeIniFile)GetProcAddress(GetModuleHandleW(L"uxtheme.dll"), MAKEINTRESOURCEA(11)); + if (!ParseThemeIniFile) + { + skip("No ParseThemeIniFile found\n"); + return; + } + + FILE *fout = _wfopen(L"invalid.ini", L"wb"); + fprintf(fout, "[InvalidKey]\n"); + fprintf(fout, "InvalidValueName=InvalidValue\n"); + fclose(fout); + + hr = ParseThemeIniFile(L"invalid.ini", szPath, ParseThemeIniFileProc, NULL); + ok_hex(hr, HRESULT_FROM_WIN32(ERROR_UNKNOWN_PROPERTY)); + + _wremove(L"invalid.ini"); + + ZeroMemory(&Info, sizeof(Info)); + Info.cbSize = sizeof(Info); + Info.szDescription[0] = L'@'; + Info.szDescription[MAX_PATH] = L'@'; + Info.szFile[0] = L'@'; + Info.szLine[0] = L'@'; + hr = GetThemeParseErrorInfo(&Info); + ok_hex(hr, S_OK); + ok_int(Info.nID, 160); + + ok(Info.szDescription[0] != UNICODE_NULL, "Info.szDescription was empty\n"); + ok(Info.szDescription[0] != L'@', "Info.szDescription had no change\n"); + trace("szDescription: %s\n", wine_dbgstr_w(Info.szDescription)); // "Must be Primitive, enum, or type: InvalidValueName" + + ok_int(Info.szDescription[MAX_PATH], L'@'); + ok_wstr(Info.szFile, L"invalid.ini"); + ok_wstr(Info.szLine, L"InvalidValueName=InvalidValue"); + ok_int(Info.nLineNo, 2); +} diff --git a/modules/rostests/apitests/uxtheme/testlist.c b/modules/rostests/apitests/uxtheme/testlist.c index 0ecc2b98943c9..c3260d8499e7d 100644 --- a/modules/rostests/apitests/uxtheme/testlist.c +++ b/modules/rostests/apitests/uxtheme/testlist.c @@ -5,6 +5,7 @@ extern void func_CloseThemeData(void); extern void func_DrawThemeParentBackground(void); +extern void func_GetThemeParseErrorInfo(void); extern void func_SetThemeAppProperties(void); extern void func_SetWindowTheme(void); @@ -12,6 +13,7 @@ const struct test winetest_testlist[] = { { "CloseThemeData", func_CloseThemeData }, { "DrawThemeParentBackground", func_DrawThemeParentBackground }, + { "GetThemeParseErrorInfo", func_GetThemeParseErrorInfo }, { "SetWindowTheme", func_SetWindowTheme }, { "SetThemeAppProperties", func_SetThemeAppProperties }, { 0, 0 } diff --git a/modules/rostests/drivers/ntoskrnl/IoEaTest.cpp b/modules/rostests/drivers/ntoskrnl/IoEaTest.cpp index 83d4f77e45f55..103e326a71562 100644 --- a/modules/rostests/drivers/ntoskrnl/IoEaTest.cpp +++ b/modules/rostests/drivers/ntoskrnl/IoEaTest.cpp @@ -63,7 +63,7 @@ IoCheckEaBufferValidityROS(IN PFILE_FULL_EA_INFORMATION EaBuffer, else { /* - From MSDN (http://msdn2.microsoft.com/en-us/library/ms795740.aspx). + From MSDN (http://msdn2.microsoft.com/en-us/library/ms795740.aspx (DEAD_LINK)). For all entries except the last, the value of NextEntryOffset must be greater than zero and must fall on a ULONG boundary. */ @@ -350,7 +350,7 @@ int _tmain(int argc, _TCHAR* argv[]) printf("8.) Test : *********************\n"); /* Here WinEaBuffer->NextEntryOffset test : STATUS_SUCCESS when NextEntryOffset=0 else STATUS_EA_LIST_INCONSISTENT when NextEntryOffset = 28 = 8+8+9 ((WinEaBuffer->EaNameLength+WinEaBuffer->EaNameLength+9)+3)&0xFFFFFFFC then ErrorOffset 28 */ - /* From the MSDN (http://msdn2.microsoft.com/en-us/library/ms795740.aspx). For all entries except the last, the value of NextEntryOffset must be greater than zero and must fall on a ULONG boundary.*/ + /* From the MSDN (http://msdn2.microsoft.com/en-us/library/ms795740.aspx (DEAD_LINK)). For all entries except the last, the value of NextEntryOffset must be greater than zero and must fall on a ULONG boundary.*/ for (i=0;iNextEntryOffset test wrong strlen: STATUS_SUCCESS NextEntryOffset=0 & NextEntryOffset = 28 = 8+8+9 ((WinEaBuffer->EaNameLength+WinEaBuffer->EaNameLength+9)+3)&0xFFFFFFFC */ - /* From the MSDN (http://msdn2.microsoft.com/en-us/library/ms795740.aspx). For all entries except the last, the value of NextEntryOffset must be greater than zero and must fall on a ULONG boundary.*/ + /* From the MSDN (http://msdn2.microsoft.com/en-us/library/ms795740.aspx (DEAD_LINK)). For all entries except the last, the value of NextEntryOffset must be greater than zero and must fall on a ULONG boundary.*/ for (i=0;iNextEntryOffset test wrong strlen: STATUS_SUCCESS NextEntryOffset=0 & NextEntryOffset = 28 = 8+8+9 ((WinEaBuffer->EaNameLength+WinEaBuffer->EaNameLength+9)+3)&0xFFFFFFFC */ - /* From the MSDN (http://msdn2.microsoft.com/en-us/library/ms795740.aspx). For all entries except the last, the value of NextEntryOffset must be greater than zero and must fall on a ULONG boundary.*/ + /* From the MSDN (http://msdn2.microsoft.com/en-us/library/ms795740.aspx (DEAD_LINK)). For all entries except the last, the value of NextEntryOffset must be greater than zero and must fall on a ULONG boundary.*/ for (i=0;iGetPrivateData(guid, &dummy, &size) == DDERR_EXPIRED); - // TODO: Test for DDSPD_IUNKNOWNPOINTER (see http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/ddraw7/directdraw7/ddref_5qyf.asp) + // TODO: Test for DDSPD_IUNKNOWNPOINTER (see http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/ddraw7/directdraw7/ddref_5qyf.asp (DEAD_LINK)) Surface->Release(); return TRUE; diff --git a/modules/rostests/kmtests/CMakeLists.txt b/modules/rostests/kmtests/CMakeLists.txt index 40c710f0a468c..373ffb887c38a 100644 --- a/modules/rostests/kmtests/CMakeLists.txt +++ b/modules/rostests/kmtests/CMakeLists.txt @@ -80,6 +80,7 @@ list(APPEND KMTEST_DRV_SOURCE ntos_io/IoIrp.c ntos_io/IoMdl.c ntos_io/IoVolume.c + ntos_kd/KdSystemDebugControl.c ntos_ke/KeApc.c ntos_ke/KeDevQueue.c ntos_ke/KeDpc.c @@ -164,6 +165,7 @@ list(APPEND KMTEST_SOURCE ntos_io/IoCreateFile_user.c ntos_io/IoDeviceObject_user.c ntos_io/IoReadWrite_user.c + ntos_kd/NtSystemDebugControl.c ntos_mm/MmMapLockedPagesSpecifyCache_user.c ntos_mm/NtCreateSection_user.c ntos_po/PoIrp_user.c diff --git a/modules/rostests/kmtests/include/kmt_test.h b/modules/rostests/kmtests/include/kmt_test.h index 2f0315a48b586..1e265c9a05aa7 100644 --- a/modules/rostests/kmtests/include/kmt_test.h +++ b/modules/rostests/kmtests/include/kmt_test.h @@ -186,7 +186,7 @@ DWORD KmtSendBufferToDriver(IN DWORD ControlCode, IN OUT PVOID Buffer OPTIONAL, DWORD KmtFltCreateService(_In_z_ PCWSTR ServiceName, _In_z_ PCWSTR DisplayName, _Out_ SC_HANDLE *ServiceHandle); DWORD KmtFltDeleteService(_In_opt_z_ PCWSTR ServiceName, _Inout_ SC_HANDLE *ServiceHandle); DWORD KmtFltAddAltitude(_In_z_ LPWSTR Altitude); -DWORD KmtFltLoadDriver(_In_ BOOLEAN EnableDriverLoadPrivlege, _In_ BOOLEAN RestartIfRunning, _In_ BOOLEAN ConnectComms, _Out_ HANDLE *hPort); +DWORD KmtFltLoadDriver(_In_ BOOLEAN EnableDriverLoadPrivilege, _In_ BOOLEAN RestartIfRunning, _In_ BOOLEAN ConnectComms, _Out_ HANDLE *hPort); DWORD KmtFltUnloadDriver(_In_ HANDLE *hPort, _In_ BOOLEAN DisonnectComms); DWORD KmtFltConnectComms(_Out_ HANDLE *hPort); DWORD KmtFltDisconnectComms(_In_ HANDLE hPort); diff --git a/modules/rostests/kmtests/kmtest/fltsupport.c b/modules/rostests/kmtests/kmtest/fltsupport.c index ae0cb05abb495..19868018d4781 100644 --- a/modules/rostests/kmtests/kmtest/fltsupport.c +++ b/modules/rostests/kmtests/kmtest/fltsupport.c @@ -11,6 +11,7 @@ #include "kmtest.h" #include +#include #include #include @@ -25,10 +26,6 @@ KmtpCreateService( IN DWORD ServiceType, OUT SC_HANDLE *ServiceHandle); -DWORD EnablePrivilegeInCurrentProcess( - _In_z_ LPWSTR lpPrivName, - _In_ BOOL bEnable); - // move to a shared location typedef struct _KMTFLT_MESSAGE_HEADER { @@ -110,7 +107,7 @@ KmtFltDeleteService( */ DWORD KmtFltLoadDriver( - _In_ BOOLEAN EnableDriverLoadPrivlege, + _In_ BOOLEAN EnableDriverLoadPrivilege, _In_ BOOLEAN RestartIfRunning, _In_ BOOLEAN ConnectComms, _Out_ HANDLE *hPort @@ -118,13 +115,16 @@ KmtFltLoadDriver( { DWORD Error; - if (EnableDriverLoadPrivlege) + if (EnableDriverLoadPrivilege) { - Error = EnablePrivilegeInCurrentProcess(SE_LOAD_DRIVER_NAME , TRUE); + BOOLEAN WasEnabled; + Error = RtlNtStatusToDosError(RtlAdjustPrivilege( + SE_LOAD_DRIVER_PRIVILEGE, + TRUE, + FALSE, // Enable in current process. + &WasEnabled)); if (Error) - { return Error; - } } Error = KmtFltLoad(TestServiceName); @@ -141,14 +141,10 @@ KmtFltLoadDriver( } if (Error) - { return Error; - } if (ConnectComms) - { Error = KmtFltConnectComms(hPort); - } return Error; } @@ -524,63 +520,3 @@ KmtFltAddAltitude( return Error; } - -/* -* Private functions, not meant for use in kmtests -*/ - -DWORD EnablePrivilege( - _In_ HANDLE hToken, - _In_z_ LPWSTR lpPrivName, - _In_ BOOL bEnable) -{ - TOKEN_PRIVILEGES TokenPrivileges; - LUID luid; - BOOL bSuccess; - DWORD dwError = ERROR_SUCCESS; - - /* Get the luid for this privilege */ - if (!LookupPrivilegeValueW(NULL, lpPrivName, &luid)) - return GetLastError(); - - /* Setup the struct with the priv info */ - TokenPrivileges.PrivilegeCount = 1; - TokenPrivileges.Privileges[0].Luid = luid; - TokenPrivileges.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : 0; - - /* Enable the privilege info in the token */ - bSuccess = AdjustTokenPrivileges(hToken, - FALSE, - &TokenPrivileges, - sizeof(TOKEN_PRIVILEGES), - NULL, - NULL); - if (bSuccess == FALSE) dwError = GetLastError(); - - /* return status */ - return dwError; -} - -DWORD EnablePrivilegeInCurrentProcess( - _In_z_ LPWSTR lpPrivName, - _In_ BOOL bEnable) -{ - HANDLE hToken; - BOOL bSuccess; - DWORD dwError = ERROR_SUCCESS; - - /* Get a handle to our token */ - bSuccess = OpenProcessToken(GetCurrentProcess(), - TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, - &hToken); - if (bSuccess == FALSE) return GetLastError(); - - /* Enable the privilege in the agent token */ - dwError = EnablePrivilege(hToken, lpPrivName, bEnable); - - /* We're done with this now */ - CloseHandle(hToken); - - /* return status */ - return dwError; -} diff --git a/modules/rostests/kmtests/kmtest/kmtest.h b/modules/rostests/kmtests/kmtest/kmtest.h index a32d41c0546f4..2a6c9ef22165c 100644 --- a/modules/rostests/kmtests/kmtest/kmtest.h +++ b/modules/rostests/kmtests/kmtest/kmtest.h @@ -126,6 +126,6 @@ KmtFltDeleteService( DWORD KmtFltCloseService( _Inout_ SC_HANDLE *ServiceHandle); -#endif /* KMT_FILTER_DRIVER */ +#endif /* KMT_FLT_USER_MODE */ #endif /* !defined _KMTESTS_H_ */ diff --git a/modules/rostests/kmtests/kmtest/testlist.c b/modules/rostests/kmtests/kmtest/testlist.c index 60ab4bb4534b1..34e387c43f40b 100644 --- a/modules/rostests/kmtests/kmtest/testlist.c +++ b/modules/rostests/kmtests/kmtest/testlist.c @@ -23,6 +23,7 @@ KMT_TESTFUNC Test_IoDeviceObject; KMT_TESTFUNC Test_IoReadWrite; KMT_TESTFUNC Test_MmMapLockedPagesSpecifyCache; KMT_TESTFUNC Test_NtCreateSection; +KMT_TESTFUNC Test_NtSystemDebugControl; KMT_TESTFUNC Test_PoIrp; KMT_TESTFUNC Test_RtlAvlTree; KMT_TESTFUNC Test_RtlCaptureContext; @@ -58,6 +59,7 @@ const KMT_TEST TestList[] = { "IoReadWrite", Test_IoReadWrite }, { "MmMapLockedPagesSpecifyCache", Test_MmMapLockedPagesSpecifyCache }, { "NtCreateSection", Test_NtCreateSection }, + { "NtSystemDebugControl", Test_NtSystemDebugControl }, { "PoIrp", Test_PoIrp }, { "RtlAvlTree", Test_RtlAvlTree }, { "RtlException", Test_RtlException }, diff --git a/modules/rostests/kmtests/kmtest_drv/testlist.c b/modules/rostests/kmtests/kmtest_drv/testlist.c index 9ef992257ee08..b863bcf7b0464 100644 --- a/modules/rostests/kmtests/kmtest_drv/testlist.c +++ b/modules/rostests/kmtests/kmtest_drv/testlist.c @@ -35,6 +35,7 @@ KMT_TESTFUNC Test_IoInterrupt; KMT_TESTFUNC Test_IoIrp; KMT_TESTFUNC Test_IoMdl; KMT_TESTFUNC Test_IoVolume; +KMT_TESTFUNC Test_KdSystemDebugControl; KMT_TESTFUNC Test_KeApc; KMT_TESTFUNC Test_KeDeviceQueue; KMT_TESTFUNC Test_KeDpc; @@ -118,6 +119,7 @@ const KMT_TEST TestList[] = { "IoIrp", Test_IoIrp }, { "IoMdl", Test_IoMdl }, { "IoVolume", Test_IoVolume }, + { "KdSystemDebugControl", Test_KdSystemDebugControl }, { "KeApc", Test_KeApc }, { "KeDeviceQueue", Test_KeDeviceQueue }, { "KeDpc", Test_KeDpc }, diff --git a/modules/rostests/kmtests/ntos_io/IoDeviceInterface.c b/modules/rostests/kmtests/ntos_io/IoDeviceInterface.c index 58f15cb6c758e..846c43901c626 100644 --- a/modules/rostests/kmtests/ntos_io/IoDeviceInterface.c +++ b/modules/rostests/kmtests/ntos_io/IoDeviceInterface.c @@ -1,11 +1,14 @@ /* - * PROJECT: ReactOS kernel-mode tests - * LICENSE: LGPLv2+ - See COPYING.LIB in the top level directory - * PURPOSE: Kernel-Mode Test Suite Device Interface functions test - * PROGRAMMER: Filip Navara + * PROJECT: ReactOS kernel-mode tests + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Test for Device Interface functions + * COPYRIGHT: Copyright 2011 Filip Navara + * Copyright 2011-2015 Thomas Faber + * Copyright 2021 Mark Jansen + * Copyright 2021-2024 Oleg Dubinskiy */ -/* TODO: what's with the prototypes at the top, what's with the if-ed out part? Doesn't process most results */ +/* TODO: Add IoRegisterDeviceInterface testcase */ #include #include @@ -13,113 +16,176 @@ #define NDEBUG #include -#if 0 -NTSTATUS -(NTAPI *IoGetDeviceInterfaces_Func)( - IN CONST GUID *InterfaceClassGuid, - IN PDEVICE_OBJECT PhysicalDeviceObject OPTIONAL, - IN ULONG Flags, - OUT PWSTR *SymbolicLinkList); - -NTSTATUS NTAPI -ReactOS_IoGetDeviceInterfaces( - IN CONST GUID *InterfaceClassGuid, - IN PDEVICE_OBJECT PhysicalDeviceObject OPTIONAL, - IN ULONG Flags, - OUT PWSTR *SymbolicLinkList); -#endif /* 0 */ - -static VOID DeviceInterfaceTest_Func() +/* Predefined GUIDs are required for IoGetDeviceInterfaceAlias and IoOpenDeviceInterfaceRegistryKey. + * Only they can provide the aliases and the needed subkeys, unlike manually declared test GUIDs. + * Since IoRegisterDeviceInterface testcase is missing, it is not possible to register the new device interface + * and get an alias/key handle of it using this test. */ +/* Invalid GUID */ +static const GUID GUID_NULL = {0x00000000L, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; +/* From our ks.h */ +static const GUID KSCATEGORY_BRIDGE = {0x085AFF00L, 0x62CE, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; +static const GUID KSCATEGORY_CAPTURE = {0x65E8773DL, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; +static const GUID KSCATEGORY_COMMUNICATIONSTRANSFORM = {0xCF1DDA2CL, 0x9743, 0x11D0, {0xA3, 0xEE, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; +static const GUID KSCATEGORY_DATACOMPRESSOR = {0x1E84C900L, 0x7E70, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; +static const GUID KSCATEGORY_DATADECOMPRESSOR = {0x2721AE20L, 0x7E70, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; +static const GUID KSCATEGORY_DATATRANSFORM = {0x2EB07EA0L, 0x7E70, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; +static const GUID KSCATEGORY_FILESYSTEM = {0x760FED5EL, 0x9357, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; +static const GUID KSCATEGORY_INTERFACETRANSFORM = {0xCF1DDA2DL, 0x9743, 0x11D0, {0xA3, 0xEE, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; +static const GUID KSCATEGORY_MEDIUMTRANSFORM = {0xCF1DDA2EL, 0x9743, 0x11D0, {0xA3, 0xEE, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; +static const GUID KSCATEGORY_MIXER = {0xAD809C00L, 0x7B88, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; +static const GUID KSCATEGORY_RENDER = {0x65E8773EL, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; +static const GUID KSCATEGORY_SPLITTER = {0x0A4252A0L, 0x7E70, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; + +static const GUID* Types[] = { - NTSTATUS Status; - PWSTR SymbolicLinkList; - PWSTR SymbolicLinkListPtr; - GUID Guid = {0x378de44c, 0x56ef, 0x11d1, {0xbc, 0x8c, 0x00, 0xa0, 0xc9, 0x14, 0x05, 0xdd}}; - - Status = IoGetDeviceInterfaces( - &Guid, - NULL, - 0, - &SymbolicLinkList); - - ok(NT_SUCCESS(Status), - "IoGetDeviceInterfaces failed with status 0x%X\n", - (unsigned int)Status); - if (!NT_SUCCESS(Status)) - { - return; - } - - DPRINT("IoGetDeviceInterfaces results:\n"); - for (SymbolicLinkListPtr = SymbolicLinkList; - SymbolicLinkListPtr[0] != 0 && SymbolicLinkListPtr[1] != 0; - SymbolicLinkListPtr += wcslen(SymbolicLinkListPtr) + 1) - { - DPRINT1("Symbolic Link: %S\n", SymbolicLinkListPtr); - } - -#if 0 - DPRINT("[PnP Test] Trying to get aliases\n"); - - for (SymbolicLinkListPtr = SymbolicLinkList; - SymbolicLinkListPtr[0] != 0 && SymbolicLinkListPtr[1] != 0; - SymbolicLinkListPtr += wcslen(SymbolicLinkListPtr) + 1) - { - UNICODE_STRING SymbolicLink; - UNICODE_STRING AliasSymbolicLink; - - SymbolicLink.Buffer = SymbolicLinkListPtr; - SymbolicLink.Length = SymbolicLink.MaximumLength = wcslen(SymbolicLinkListPtr); - RtlInitUnicodeString(&AliasSymbolicLink, NULL); - IoGetDeviceInterfaceAlias( - &SymbolicLink, - &AliasGuid, - &AliasSymbolicLink); - if (AliasSymbolicLink.Buffer != NULL) - { - DPRINT("[PnP Test] Original: %S\n", SymbolicLinkListPtr); - DPRINT("[PnP Test] Alias: %S\n", AliasSymbolicLink.Buffer); - } - } -#endif - - ExFreePool(SymbolicLinkList); + &GUID_NULL, + &KSCATEGORY_BRIDGE, + &KSCATEGORY_CAPTURE, + &KSCATEGORY_COMMUNICATIONSTRANSFORM, + &KSCATEGORY_DATACOMPRESSOR, + &KSCATEGORY_DATADECOMPRESSOR, + &KSCATEGORY_DATATRANSFORM, + &KSCATEGORY_FILESYSTEM, + &KSCATEGORY_INTERFACETRANSFORM, + &KSCATEGORY_MEDIUMTRANSFORM, + &KSCATEGORY_MIXER, + &KSCATEGORY_RENDER, + &KSCATEGORY_SPLITTER, +}; + +static +VOID +Test_IoOpenDeviceInterfaceRegistryKey( + _In_opt_ PCWSTR SymbolicLink) +{ + UNICODE_STRING KeyName, SymbolicLinkName; + HANDLE DeviceInterfaceKey; + NTSTATUS Status; + size_t n; + + RtlInitUnicodeString(&SymbolicLinkName, SymbolicLink); + RtlInitUnicodeString(&KeyName, L"ReactOS_kmtest"); + + /* It's okay to call this from a user process's thread */ + Status = IoOpenDeviceInterfaceRegistryKey(&SymbolicLinkName, KEY_CREATE_SUB_KEY, &DeviceInterfaceKey); + + if (skip(NT_SUCCESS(Status), "IoOpenDeviceInterfaceRegistryKey() failed: 0x%lx\n", Status)) + return; + + trace("IoOpenDeviceInterfaceRegistryKey() success: 0x%p\n", DeviceInterfaceKey); + + for (n = 0; n < RTL_NUMBER_OF(Types); ++n) + { + HANDLE DeviceInterfaceSubKey; + OBJECT_ATTRIBUTES ObjectAttributes; + + /* Try to create the non-volatile subkey to check whether the parent key is volatile */ + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, + DeviceInterfaceKey, + NULL); + Status = ZwCreateKey(&DeviceInterfaceSubKey, + KEY_WRITE, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_NON_VOLATILE, + NULL); + + if (skip(NT_SUCCESS(Status), "ZwCreateKey() failed to create a subkey: %d 0x%lx\n", n, Status)) + continue; + + trace("ZwCreateKey(): successfully created subkey: %d 0x%p\n", n, DeviceInterfaceSubKey); + + ZwDeleteKey(DeviceInterfaceSubKey); + ZwClose(DeviceInterfaceSubKey); + } + + ZwClose(DeviceInterfaceKey); } static VOID -Test_IoRegisterDeviceInterface(VOID) +Test_IoGetDeviceInterfaceAlias( + _In_opt_ PCWSTR SymbolicLink) { - GUID Guid = {0x378de44c, 0x56ef, 0x11d1, {0xbc, 0x8c, 0x00, 0xa0, 0xc9, 0x14, 0x05, 0xdd}}; - DEVICE_OBJECT DeviceObject; - EXTENDED_DEVOBJ_EXTENSION DeviceObjectExtension; - DEVICE_NODE DeviceNode; UNICODE_STRING SymbolicLinkName; - NTSTATUS Status; + size_t n; + + RtlInitUnicodeString(&SymbolicLinkName, SymbolicLink); + + for (n = 0; n < RTL_NUMBER_OF(Types); ++n) + { + UNICODE_STRING AliasSymbolicLinkName; + NTSTATUS Status = IoGetDeviceInterfaceAlias(&SymbolicLinkName, Types[n], &AliasSymbolicLinkName); - RtlInitUnicodeString(&SymbolicLinkName, L""); + if (skip(NT_SUCCESS(Status), "IoGetDeviceInterfaceAlias(): fail: %d 0x%x\n", n, Status)) + continue; - // Prepare our surrogate of a Device Object - DeviceObject.DeviceObjectExtension = (PDEVOBJ_EXTENSION)&DeviceObjectExtension; + trace("IoGetDeviceInterfaceAlias(): success: %d %wZ\n", n, &AliasSymbolicLinkName); + + /* Test IoOpenDeviceInterfaceRegistryKey with alias symbolic link too */ + Test_IoOpenDeviceInterfaceRegistryKey(AliasSymbolicLinkName.Buffer); + + RtlFreeUnicodeString(&AliasSymbolicLinkName); + } +} - // 1. DeviceNode = NULL - DeviceObjectExtension.DeviceNode = NULL; - Status = IoRegisterDeviceInterface(&DeviceObject, &Guid, NULL, - &SymbolicLinkName); +static +VOID +Test_IoSetDeviceInterfaceState( + _In_opt_ PCWSTR SymbolicLink) +{ + UNICODE_STRING SymbolicLinkName; + size_t n; - ok(Status == STATUS_INVALID_DEVICE_REQUEST, - "IoRegisterDeviceInterface returned 0x%08lX\n", Status); + RtlInitUnicodeString(&SymbolicLinkName, SymbolicLink); - // 2. DeviceNode->InstancePath is of a null length - DeviceObjectExtension.DeviceNode = &DeviceNode; - DeviceNode.InstancePath.Length = 0; - Status = IoRegisterDeviceInterface(&DeviceObject, &Guid, NULL, - &SymbolicLinkName); + for (n = 0; n < RTL_NUMBER_OF(Types); ++n) + { + NTSTATUS Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); - ok(Status == STATUS_INVALID_DEVICE_REQUEST, - "IoRegisterDeviceInterface returned 0x%08lX\n", Status); + if (skip(NT_SUCCESS(Status), "IoSetDeviceInterfaceState(): failed to enable interface: %d 0x%x\n", n, Status)) + continue; - DeviceInterfaceTest_Func(); + trace("IoSetDeviceInterfaceState(): successfully enabled interface: %d %wZ\n", n, &SymbolicLinkName); + } +} + +static +VOID +Test_IoGetDeviceInterfaces( + _In_ const GUID* Guid) +{ + NTSTATUS Status; + PZZWSTR SymbolicLinkList; + PWSTR SymbolicLink; + UNICODE_STRING GuidString; + + Status = IoGetDeviceInterfaces(Guid, NULL, DEVICE_INTERFACE_INCLUDE_NONACTIVE, &SymbolicLinkList); + + RtlStringFromGUID(Guid, &GuidString); + if (skip(NT_SUCCESS(Status), "IoGetDeviceInterfaces failed with status 0x%x for '%wZ'\n", Status, &GuidString)) + { + RtlFreeUnicodeString(&GuidString); + return; + } + + trace("IoGetDeviceInterfaces '%wZ' results:\n", &GuidString); + RtlFreeUnicodeString(&GuidString); + + for (SymbolicLink = SymbolicLinkList; + SymbolicLink[0] != UNICODE_NULL; + SymbolicLink += wcslen(SymbolicLink) + 1) + { + trace("Symbolic Link: %S\n", SymbolicLink); + Test_IoGetDeviceInterfaceAlias(SymbolicLink); + Test_IoOpenDeviceInterfaceRegistryKey(SymbolicLink); + Test_IoSetDeviceInterfaceState(SymbolicLink); + } + + ExFreePool(SymbolicLinkList); } static UCHAR NotificationContext; @@ -181,112 +247,16 @@ Test_IoRegisterPlugPlayNotification(VOID) } } -static -VOID -Test_IoSetDeviceInterface(VOID) +START_TEST(IoDeviceInterface) { - NTSTATUS Status; - UNICODE_STRING SymbolicLinkName; - PWCHAR Buffer; - ULONG BufferSize; - - /* Invalid prefix or GUID */ - KmtStartSeh() - Status = IoSetDeviceInterfaceState(NULL, TRUE); - KmtEndSeh(STATUS_SUCCESS) - ok_eq_hex(Status, STATUS_INVALID_PARAMETER); - - RtlInitEmptyUnicodeString(&SymbolicLinkName, NULL, 0); - KmtStartSeh() - Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); - KmtEndSeh(STATUS_SUCCESS) - ok_eq_hex(Status, STATUS_INVALID_PARAMETER); - - RtlInitUnicodeString(&SymbolicLinkName, L"\\??"); - KmtStartSeh() - Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); - KmtEndSeh(STATUS_SUCCESS) - ok_eq_hex(Status, STATUS_INVALID_PARAMETER); - - RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\"); - KmtStartSeh() - Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); - KmtEndSeh(STATUS_SUCCESS) - ok_eq_hex(Status, STATUS_INVALID_PARAMETER); - - RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\\\"); - KmtStartSeh() - Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); - KmtEndSeh(STATUS_SUCCESS) - ok_eq_hex(Status, STATUS_INVALID_PARAMETER); - - RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}"); - KmtStartSeh() - Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); - KmtEndSeh(STATUS_SUCCESS) - ok_eq_hex(Status, STATUS_INVALID_PARAMETER); - - /* Valid prefix & GUID, invalid device node */ - RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\X{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}"); - KmtStartSeh() - Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); - KmtEndSeh(STATUS_SUCCESS) - ok_eq_hex(Status, STATUS_OBJECT_NAME_NOT_FOUND); - - RtlInitUnicodeString(&SymbolicLinkName, L"\\\\?\\X{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}"); - KmtStartSeh() - Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); - KmtEndSeh(STATUS_SUCCESS) - ok_eq_hex(Status, STATUS_OBJECT_NAME_NOT_FOUND); - - RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\X{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}\\"); - KmtStartSeh() - Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); - KmtEndSeh(STATUS_SUCCESS) - ok_eq_hex(Status, STATUS_OBJECT_NAME_NOT_FOUND); - - RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\#{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}"); - KmtStartSeh() - Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); - KmtEndSeh(STATUS_SUCCESS) - ok_eq_hex(Status, STATUS_OBJECT_NAME_NOT_FOUND); - - /* Must not read past the buffer */ - RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\#{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}"); - BufferSize = SymbolicLinkName.Length; - Buffer = KmtAllocateGuarded(BufferSize); - if (!skip(Buffer != NULL, "Failed to allocate %lu bytes\n", BufferSize)) + size_t n; + for (n = 0; n < RTL_NUMBER_OF(Types); ++n) { - RtlCopyMemory(Buffer, SymbolicLinkName.Buffer, BufferSize); - SymbolicLinkName.Buffer = Buffer; - SymbolicLinkName.MaximumLength = BufferSize; - KmtStartSeh() - Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); - KmtEndSeh(STATUS_SUCCESS) - ok_eq_hex(Status, STATUS_OBJECT_NAME_NOT_FOUND); - KmtFreeGuarded(Buffer); + Test_IoGetDeviceInterfaces(Types[n]); } - - RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\#aaaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}"); - BufferSize = SymbolicLinkName.Length; - Buffer = KmtAllocateGuarded(BufferSize); - if (!skip(Buffer != NULL, "Failed to allocate %lu bytes\n", BufferSize)) - { - RtlCopyMemory(Buffer, SymbolicLinkName.Buffer, BufferSize); - SymbolicLinkName.Buffer = Buffer; - SymbolicLinkName.MaximumLength = BufferSize; - KmtStartSeh() - Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); - KmtEndSeh(STATUS_SUCCESS) - ok_eq_hex(Status, STATUS_INVALID_PARAMETER); - KmtFreeGuarded(Buffer); - } -} - -START_TEST(IoDeviceInterface) -{ - // FIXME: This test crashes in Windows - (void)Test_IoRegisterDeviceInterface; + /* Test the invalid case behaviour */ + Test_IoGetDeviceInterfaceAlias(NULL); + Test_IoOpenDeviceInterfaceRegistryKey(NULL); + Test_IoSetDeviceInterfaceState(NULL); Test_IoRegisterPlugPlayNotification(); - Test_IoSetDeviceInterface(); } diff --git a/modules/rostests/kmtests/ntos_io/IoVolume.c b/modules/rostests/kmtests/ntos_io/IoVolume.c index 51d5eccfb3fa9..a0824e5ef82b9 100644 --- a/modules/rostests/kmtests/ntos_io/IoVolume.c +++ b/modules/rostests/kmtests/ntos_io/IoVolume.c @@ -6,7 +6,7 @@ */ #include - +#include static void @@ -24,17 +24,16 @@ TestIoVolumeDeviceToDosName(void) RtlInitEmptyUnicodeString(&VolumeDeviceName, VolumeDeviceNameBuffer, sizeof(VolumeDeviceNameBuffer)); - VolumeNumber = 0; - while (1) + // TODO: Query the partition/volume manager for the list of volumes. + for (VolumeNumber = 0; VolumeNumber < 32; ++VolumeNumber) { - VolumeNumber++; Status = RtlStringCbPrintfW(VolumeDeviceName.Buffer, VolumeDeviceName.MaximumLength, L"\\Device\\HarddiskVolume%lu", VolumeNumber); if (!NT_SUCCESS(Status)) { - trace("RtlStringCbPrintfW(0x%lx) failed with %lx\n", + trace("RtlStringCbPrintfW(%lu) failed with 0x%lx\n", VolumeNumber, Status); break; } @@ -46,7 +45,7 @@ TestIoVolumeDeviceToDosName(void) &DeviceObject); if (!NT_SUCCESS(Status)) { - trace("IoGetDeviceObjectPointer(%wZ) failed with %lx\n", + trace("IoGetDeviceObjectPointer(%wZ) failed with 0x%lx\n", &VolumeDeviceName, Status); continue; } @@ -56,6 +55,22 @@ TestIoVolumeDeviceToDosName(void) if (!skip(NT_SUCCESS(Status), "No DOS name\n")) { trace("DOS name for %wZ is %wZ\n", &VolumeDeviceName, &DosName); + + /* The DosName should contain one NUL-terminated string (always there?), + * plus one final NUL-terminator */ + ok(DosName.MaximumLength == DosName.Length + sizeof(UNICODE_NULL), + "Unexpected DOS name maximum length %hu, expected %hu\n", + DosName.MaximumLength, DosName.Length + sizeof(UNICODE_NULL)); + ok(DosName.Length >= sizeof(UNICODE_NULL), + "DOS name too short (length: %lu)\n", + DosName.Length / sizeof(WCHAR)); + ok(DosName.Buffer[DosName.Length / sizeof(WCHAR)] == UNICODE_NULL, + "Missing NUL-terminator (1)\n"); + ok(DosName.Buffer[DosName.MaximumLength / sizeof(WCHAR) - 1] == UNICODE_NULL, + "Missing NUL-terminator (2)\n"); + + /* The DOS name is either a drive letter, or a + * volume GUID name (if the volume is not mounted) */ if (DosName.Length == 2 * sizeof(WCHAR)) { ok(DosName.Buffer[0] >= L'A' && @@ -67,6 +82,8 @@ TestIoVolumeDeviceToDosName(void) { ok(RtlPrefixUnicodeString(&DosVolumePrefix, &DosName, FALSE), "Unexpected volume path: %wZ\n", &DosName); + ok(MOUNTMGR_IS_DOS_VOLUME_NAME(&DosName), + "Invalid DOS volume path returned: %wZ\n", &DosName); } RtlFreeUnicodeString(&DosName); } diff --git a/modules/rostests/kmtests/ntos_kd/KdSystemDebugControl.c b/modules/rostests/kmtests/ntos_kd/KdSystemDebugControl.c new file mode 100644 index 0000000000000..a4da12f2224db --- /dev/null +++ b/modules/rostests/kmtests/ntos_kd/KdSystemDebugControl.c @@ -0,0 +1,151 @@ +/* + * PROJECT: ReactOS kernel-mode tests + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Kernel-Mode Test Suite for KdSystemDebugControl (kernel-mode) + * COPYRIGHT: Copyright 2024 Hermès Bélusca-Maïto + */ + +#include +#include + +#define ok_eq_print_test(testid, value, expected, spec) \ + ok((value) == (expected), "In test %lu: " #value " = " spec ", expected " spec "\n", testid, value, expected) + +#define ok_eq_hex_test(testid, value, expected) \ + ok_eq_print_test(testid, value, expected, "0x%08lx") + +#define ok_neq_print_test(testid, value, expected, spec) \ + ok((value) != (expected), "In test %lu: " #value " = " spec ", expected != " spec "\n", testid, value, expected) + +#define ok_neq_hex_test(testid, value, expected) \ + ok_neq_print_test(testid, value, expected, "0x%08lx") + + +BOOLEAN +(NTAPI *pKdRefreshDebuggerNotPresent)(VOID); + +NTSTATUS +(NTAPI *pKdSystemDebugControl)( + _In_ SYSDBG_COMMAND Command, + _In_ PVOID InputBuffer, + _In_ ULONG InputBufferLength, + _Out_ PVOID OutputBuffer, + _In_ ULONG OutputBufferLength, + _Inout_ PULONG ReturnLength, + _In_ KPROCESSOR_MODE PreviousMode); + + +static +NTSTATUS +TestSystemDebugControl( + _In_ SYSDBG_COMMAND Command) +{ + return pKdSystemDebugControl(Command, + NULL, // _In_ PVOID InputBuffer, + 0, // _In_ ULONG InputBufferLength, + NULL, // _Out_ PVOID OutputBuffer, + 0, // _In_ ULONG OutputBufferLength, + NULL, + KernelMode); +} + +START_TEST(KdSystemDebugControl) +{ + NTSTATUS Status; + ULONG Command; + RTL_OSVERSIONINFOEXW verInfo; + UNICODE_STRING fnName; + BOOLEAN IsNT52SP1OrHigher; + BOOLEAN IsVistaOrHigher; + BOOLEAN IsDebuggerActive; + + /* Test for OS version: KdSystemDebugControl() + * exists only on NT 5.2 SP1 and higher */ + verInfo.dwOSVersionInfoSize = sizeof(verInfo); + Status = RtlGetVersion((PRTL_OSVERSIONINFOW)&verInfo); + if (skip(NT_SUCCESS(Status), "RtlGetVersion() returned 0x%08lx\n", Status)) + return; + + // IsWindowsVersionOrGreater(5, 2, 1); + IsNT52SP1OrHigher = + (verInfo.dwMajorVersion > 5) || + (verInfo.dwMajorVersion == 5 && verInfo.dwMinorVersion > 2) || + (verInfo.dwMajorVersion == 5 && verInfo.dwMinorVersion == 2 && verInfo.wServicePackMajor >= 1); + + if (skip(IsNT52SP1OrHigher, "KdSystemDebugControl() only exists on NT 5.2 SP1 and higher\n")) + return; + + // IsWindowsVersionOrGreater(6, 0, 0); + IsVistaOrHigher = (verInfo.dwMajorVersion >= 6); + + + /* Load the Kd routines at runtime */ + + /* Note: KdRefreshDebuggerNotPresent() is NT 5.2+ */ + RtlInitUnicodeString(&fnName, L"KdRefreshDebuggerNotPresent"); + pKdRefreshDebuggerNotPresent = MmGetSystemRoutineAddress(&fnName); + ok(!!pKdRefreshDebuggerNotPresent, + "KdRefreshDebuggerNotPresent() unavailable but OS is NT 5.2 SP1 or higher?\n"); + + RtlInitUnicodeString(&fnName, L"KdSystemDebugControl"); + pKdSystemDebugControl = MmGetSystemRoutineAddress(&fnName); + if (skip(!!pKdSystemDebugControl, "KdSystemDebugControl() unavailable but OS is NT 5.2 SP1 or higher?\n")) + return; + + + /* Check whether the kernel debugger is present or not */ + IsDebuggerActive = (pKdRefreshDebuggerNotPresent + ? !pKdRefreshDebuggerNotPresent() + : (/*KD_DEBUGGER_ENABLED &&*/ !KD_DEBUGGER_NOT_PRESENT)); + + trace("Debugger is %s\n", IsDebuggerActive ? "active" : "inactive"); + + /* Unsupported commands */ + for (Command = 0; Command <= 6; ++Command) + { + Status = TestSystemDebugControl((SYSDBG_COMMAND)Command); + if (!IsVistaOrHigher || IsDebuggerActive) + ok_eq_hex_test(Command, Status, STATUS_INVALID_INFO_CLASS); + else + ok_eq_hex_test(Command, Status, STATUS_DEBUGGER_INACTIVE); + } + + /* + * Supported commands: + * + * SysDbgQueryVersion = 7, + * SysDbgReadVirtual = 8, + * SysDbgWriteVirtual = 9, + * SysDbgReadPhysical = 10, + * SysDbgWritePhysical = 11, + * SysDbgReadControlSpace = 12, + * SysDbgWriteControlSpace = 13, + * SysDbgReadIoSpace = 14, + * SysDbgWriteIoSpace = 15, + * SysDbgReadMsr = 16, + * SysDbgWriteMsr = 17, + * SysDbgReadBusData = 18, + * SysDbgWriteBusData = 19, + * SysDbgCheckLowMemory = 20 + */ + for (Command = 7; Command <= 20; ++Command) + { + Status = TestSystemDebugControl((SYSDBG_COMMAND)Command); + if (!IsVistaOrHigher || IsDebuggerActive) + ok_neq_hex_test(Command, Status, STATUS_INVALID_INFO_CLASS); // Status must be != STATUS_INVALID_INFO_CLASS + else + ok_eq_hex_test(Command, Status, STATUS_DEBUGGER_INACTIVE); + } + + /* Unsupported commands */ + for (Command = 21; Command <= 40; ++Command) + { + Status = TestSystemDebugControl((SYSDBG_COMMAND)Command); + if (!IsVistaOrHigher || IsDebuggerActive) + ok_eq_hex_test(Command, Status, STATUS_INVALID_INFO_CLASS); + else + ok_eq_hex_test(Command, Status, STATUS_DEBUGGER_INACTIVE); + } +} + +/* EOF */ diff --git a/modules/rostests/kmtests/ntos_kd/NtSystemDebugControl.c b/modules/rostests/kmtests/ntos_kd/NtSystemDebugControl.c new file mode 100644 index 0000000000000..352ed6c9f5732 --- /dev/null +++ b/modules/rostests/kmtests/ntos_kd/NtSystemDebugControl.c @@ -0,0 +1,300 @@ +/* + * PROJECT: ReactOS kernel-mode tests + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Kernel-Mode Test Suite for NtSystemDebugControl (user-mode) + * COPYRIGHT: Copyright 2024 Hermès Bélusca-Maïto + */ + +#include +#include +#include +#include + +#define ok_eq_print_test(testid, value, expected, spec) \ + ok((value) == (expected), "In test %lu: " #value " = " spec ", expected " spec "\n", testid, value, expected) + +#define ok_eq_hex_test(testid, value, expected) \ + ok_eq_print_test(testid, value, expected, "0x%08lx") + +#define ok_neq_print_test(testid, value, expected, spec) \ + ok((value) != (expected), "In test %lu: " #value " = " spec ", expected != " spec "\n", testid, value, expected) + +#define ok_neq_hex_test(testid, value, expected) \ + ok_neq_print_test(testid, value, expected, "0x%08lx") + +ULONG +GetNtDdiVersion(VOID) +{ + RTL_OSVERSIONINFOEXW verInfo; + NTSTATUS Status; + ULONG Version; + + verInfo.dwOSVersionInfoSize = sizeof(verInfo); + Status = RtlGetVersion((PRTL_OSVERSIONINFOW)&verInfo); + if (!NT_SUCCESS(Status)) + { + trace("RtlGetVersion() returned 0x%08lx\n", Status); + return 0; + } + + Version = ((((verInfo.dwMajorVersion & 0xFF) << 8) | + (verInfo.dwMinorVersion & 0xFF)) << 16) | + (((verInfo.wServicePackMajor & 0xFF) << 8) | + (verInfo.wServicePackMinor & 0xFF)); + + return Version; +} + +static +NTSTATUS +TestSystemDebugControl( + _In_ SYSDBG_COMMAND Command) +{ + return NtSystemDebugControl(Command, + NULL, // _In_ PVOID InputBuffer, + 0, // _In_ ULONG InputBufferLength, + NULL, // _Out_ PVOID OutputBuffer, + 0, // _In_ ULONG OutputBufferLength, + NULL); +} + +START_TEST(NtSystemDebugControl) +{ + NTSTATUS Status; + ULONG Command; + ULONG Version; + SYSTEM_KERNEL_DEBUGGER_INFORMATION DebuggerInfo = {0}; + BOOLEAN IsNT52SP1OrHigher; + BOOLEAN IsVistaOrHigher; + BOOLEAN IsDebuggerActive; + BOOLEAN PrivilegeSet[2] = {FALSE}; + BOOLEAN WasDebuggerEnabled; + + /* Test for OS version: KdSystemDebugControl() + * exists only on NT 5.2 SP1 and higher */ + Version = GetNtDdiVersion(); + if (skip(Version != 0, "GetNtDdiVersion() returned 0\n")) + return; + + // IsWindowsVersionOrGreater(5, 2, 1); + IsNT52SP1OrHigher = (Version >= NTDDI_WS03SP1); + + // IsWindowsVersionOrGreater(6, 0, 0); + IsVistaOrHigher = (Version >= NTDDI_WIN6); + + + /* Check whether the kernel debugger is present or not */ + Status = NtQuerySystemInformation(SystemKernelDebuggerInformation, + &DebuggerInfo, + sizeof(DebuggerInfo), + NULL); + + IsDebuggerActive = NT_SUCCESS(Status) && !DebuggerInfo.KernelDebuggerNotPresent; + // DebuggerInfo.KernelDebuggerEnabled; // SharedUserData->KdDebuggerEnabled; + + trace("Debugger is %s\n", IsDebuggerActive ? "active" : "inactive"); + + /* + * Explicitly disable the debug privilege so that we can test + * that NtSystemDebugControl() fails when the privilege is absent. + * Note that SysDbgGetTriageDump (29) is used for testing here, + * because it doesn't require a debugger to be active in order + * to proceed further (privilege check and actual functionality). + */ + Status = RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, FALSE, FALSE, &PrivilegeSet[0]); + ok_eq_hex(Status, STATUS_SUCCESS); + Status = TestSystemDebugControl(SysDbgGetTriageDump /* 29 */); + ok_eq_hex(Status, STATUS_ACCESS_DENIED); + + /* Now, enable the debug privilege for the rest of the tests */ + Status = RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, TRUE, FALSE, &PrivilegeSet[1]); + ok_eq_hex(Status, STATUS_SUCCESS); + + /* Supported commands */ + for (Command = 0; Command <= 5; ++Command) + { + Status = TestSystemDebugControl((SYSDBG_COMMAND)Command); + if (!IsVistaOrHigher || IsDebuggerActive) + ok_neq_hex_test(Command, Status, STATUS_INVALID_INFO_CLASS); + else + ok_eq_hex_test(Command, Status, STATUS_DEBUGGER_INACTIVE); + } + + /* Test SysDbgBreakPoint (6) only when the debugger is inactive + * or disabled; otherwise this call would trigger a breakpoint */ + if (!skip((IsVistaOrHigher && !IsDebuggerActive) || !SharedUserData->KdDebuggerEnabled, + "NtSystemDebugControl(SysDbgBreakPoint) skipped because the debugger is active\n")) + { + Status = TestSystemDebugControl(SysDbgBreakPoint /* 6 */); + if (!SharedUserData->KdDebuggerEnabled /*&& (!IsVistaOrHigher || IsDebuggerActive)*/) + { + ok_eq_hex_test(Command, Status, STATUS_UNSUCCESSFUL); + } + else + { + // ASSERT(IsVistaOrHigher && !IsDebuggerActive); + ok_eq_hex_test(Command, Status, STATUS_DEBUGGER_INACTIVE); + } + } + + /* + * Commands handled by kernel-mode KdSystemDebugControl(), + * and unsupported in user-mode: + * + * SysDbgQueryVersion = 7, + * SysDbgReadVirtual = 8, + * SysDbgWriteVirtual = 9, + * SysDbgReadPhysical = 10, + * SysDbgWritePhysical = 11, + * SysDbgReadControlSpace = 12, + * SysDbgWriteControlSpace = 13, + * SysDbgReadIoSpace = 14, + * SysDbgWriteIoSpace = 15, + * SysDbgReadMsr = 16, + * SysDbgWriteMsr = 17, + * SysDbgReadBusData = 18, + * SysDbgWriteBusData = 19, + * SysDbgCheckLowMemory = 20 + */ + // TODO: Handle this differently if !IsNT52SP1OrHigher ? + DBG_UNREFERENCED_PARAMETER(IsNT52SP1OrHigher); + for (Command = 7; Command <= 20; ++Command) + { + Status = TestSystemDebugControl((SYSDBG_COMMAND)Command); + if (!IsVistaOrHigher || IsDebuggerActive) + ok_eq_hex_test(Command, Status, STATUS_NOT_IMPLEMENTED); + else + ok_eq_hex_test(Command, Status, STATUS_DEBUGGER_INACTIVE); + } + + + /* + * Separately test commands SysDbgEnableKernelDebugger (21) + * and SysDbgDisableKernelDebugger (22), as they influence + * the internal state of the debugger. The order of testing + * matters, depending on whether the debugger was originally + * enabled or disabled. + */ + + /* Save whether the debugger is currently enabled; + * the next tests are going to change its state */ + WasDebuggerEnabled = SharedUserData->KdDebuggerEnabled; + +// +// FIXME: Re-enable ONCE our KDBG and KDCOM dlls support disabling and re-enabling. +// + DBG_UNREFERENCED_LOCAL_VARIABLE(WasDebuggerEnabled); +#if 0 + /* Try to disable or enable the debugger, depending on its original state */ + if (WasDebuggerEnabled) + Command = SysDbgDisableKernelDebugger; // 22 + else + Command = SysDbgEnableKernelDebugger; // 21 + Status = TestSystemDebugControl((SYSDBG_COMMAND)Command); + if (!IsVistaOrHigher || IsDebuggerActive) + { + /* + * KdEnableDebugger() (with lock enabled) wants a KdDisableDebugger() + * first (i.e. that the debugger was previously explicitly disabled) + * in order to return success; otherwise it'll return STATUS_INVALID_PARAMETER. + */ + if (Command == SysDbgEnableKernelDebugger) + { + ok(Status == STATUS_SUCCESS || Status == STATUS_INVALID_PARAMETER, + "In test %lu: Status = 0x%08lx, expected 0x%08lx or 0x%08lx\n", + Command, Status, STATUS_SUCCESS, STATUS_INVALID_PARAMETER); + } + else + { + ok_eq_hex_test(Command, Status, STATUS_SUCCESS); + } + } + else + { + ok_eq_hex_test(Command, Status, STATUS_DEBUGGER_INACTIVE); + } + + /* Re-enable or disable the debugger, depending on its original state */ + if (WasDebuggerEnabled) + Command = SysDbgEnableKernelDebugger; // 21 + else + Command = SysDbgDisableKernelDebugger; // 22 + Status = TestSystemDebugControl((SYSDBG_COMMAND)Command); + if (!IsVistaOrHigher || IsDebuggerActive) + ok_eq_hex_test(Command, Status, STATUS_SUCCESS); + else + ok_eq_hex_test(Command, Status, STATUS_DEBUGGER_INACTIVE); +#endif +// END FIXME + + + /* Supported commands */ + for (Command = 23; Command <= 31; ++Command) + { + Status = TestSystemDebugControl((SYSDBG_COMMAND)Command); + if (!IsVistaOrHigher || IsDebuggerActive) + ok_neq_hex_test(Command, Status, STATUS_INVALID_INFO_CLASS); + else + ok_eq_hex_test(Command, Status, STATUS_DEBUGGER_INACTIVE); + } + + /* These are Vista+ and depend on the OS version */ + for (Command = 32; Command <= 36; ++Command) + { + Status = TestSystemDebugControl((SYSDBG_COMMAND)Command); + if (!IsVistaOrHigher || IsDebuggerActive) + { + if (Version >= NTDDI_WIN6) // IsVistaOrHigher + ok_neq_hex_test(Command, Status, STATUS_INVALID_INFO_CLASS); + else + ok_eq_hex_test(Command, Status, STATUS_INVALID_INFO_CLASS); + } + else + { + ok_eq_hex_test(Command, Status, STATUS_DEBUGGER_INACTIVE); + } + } + + Command = 37; // SysDbgGetLiveKernelDump + Status = TestSystemDebugControl((SYSDBG_COMMAND)Command); + if (!IsVistaOrHigher || IsDebuggerActive) + { + if (Version >= NTDDI_WINBLUE) + ok_neq_hex_test(Command, Status, STATUS_INVALID_INFO_CLASS); + else + ok_eq_hex_test(Command, Status, STATUS_INVALID_INFO_CLASS); + } + else + { + ok_eq_hex_test(Command, Status, STATUS_DEBUGGER_INACTIVE); + } + + Command = 38; // SysDbgKdPullRemoteFile + Status = TestSystemDebugControl((SYSDBG_COMMAND)Command); + if (!IsVistaOrHigher || IsDebuggerActive) + { + if (Version >= NTDDI_WIN10_VB) + ok_neq_hex_test(Command, Status, STATUS_INVALID_INFO_CLASS); + else + ok_eq_hex_test(Command, Status, STATUS_INVALID_INFO_CLASS); + } + else + { + ok_eq_hex_test(Command, Status, STATUS_DEBUGGER_INACTIVE); + } + + /* Unsupported commands */ + for (Command = 39; Command <= 40; ++Command) + { + Status = TestSystemDebugControl((SYSDBG_COMMAND)Command); + if (!IsVistaOrHigher || IsDebuggerActive) + ok_eq_hex_test(Command, Status, STATUS_INVALID_INFO_CLASS); + else + ok_eq_hex_test(Command, Status, STATUS_DEBUGGER_INACTIVE); + } + + /* Finally restore the original debug privilege state */ + RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, PrivilegeSet[0], FALSE, &PrivilegeSet[0]); +} + +/* EOF */ diff --git a/modules/rostests/kmtests/ntos_mm/ZwMapViewOfSection.c b/modules/rostests/kmtests/ntos_mm/ZwMapViewOfSection.c index 73bc8f0c02e3e..2b195fb8f4ef7 100644 --- a/modules/rostests/kmtests/ntos_mm/ZwMapViewOfSection.c +++ b/modules/rostests/kmtests/ntos_mm/ZwMapViewOfSection.c @@ -479,7 +479,7 @@ BehaviorChecks(HANDLE FileHandleReadOnly, HANDLE FileHandleWriteOnly) { //check also the SEC_COMMIT flag /* This test proves that MSDN is once again wrong - * msdn.microsoft.com/en-us/library/windows/hardware/aa366537.aspx states that SEC_RESERVE + * https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-createfilemappingw states that SEC_RESERVE * should cause the allocated memory for the view to be reserved but in fact it is always committed. * It fails also on windows. */ diff --git a/modules/rostests/kmtests/ntos_ob/ObQuery.c b/modules/rostests/kmtests/ntos_ob/ObQuery.c index b58762067f761..be6000f16438a 100644 --- a/modules/rostests/kmtests/ntos_ob/ObQuery.c +++ b/modules/rostests/kmtests/ntos_ob/ObQuery.c @@ -3,6 +3,7 @@ * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) * PURPOSE: Kernel mode tests for object information querying * COPYRIGHT: Copyright 2023 George Bișoc + * Copyright 2024 Hermès Bélusca-Maïto */ #include @@ -65,7 +66,111 @@ ObjectBasicInformationTests(VOID) ZwClose(WinStaDirHandle); } +/* Flags combination allowing all the read, write and delete share modes. + * Currently similar to FILE_SHARE_VALID_FLAGS. */ +#define FILE_SHARE_ALL \ + (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE) + +#define ok_ntstatus ok_eq_hex + +/* Adapted from apitests/ntdll/NtQueryObject.c!START_TEST(NtQueryObject). + * Please sync both tests in case you add or remove new features. */ +static +VOID +ObjectNameInformationTests(VOID) +{ + ULONG g_OsVersion = + SharedUserData->NtMajorVersion << 8 | SharedUserData->NtMinorVersion; + + NTSTATUS Status; + HANDLE DeviceHandle; + UNICODE_STRING DeviceName; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + + ULONG BufferSize1, BufferSize2, BufferSize3; + struct { OBJECT_NAME_INFORMATION; WCHAR Buffer[MAX_PATH]; } ObjectNameBuffer; + PUNICODE_STRING ObjectName = &ObjectNameBuffer.Name; + + /* Test the drive containing SystemRoot */ + WCHAR NtDeviceName[] = L"\\DosDevices\\?:"; + NtDeviceName[sizeof("\\DosDevices\\")-1] = SharedUserData->NtSystemRoot[0]; + + /* We must be in PASSIVE_LEVEL to do all of this stuff */ + ok_irql(PASSIVE_LEVEL); + + /* Open a handle to the device */ + RtlInitUnicodeString(&DeviceName, NtDeviceName); + InitializeObjectAttributes(&ObjectAttributes, + &DeviceName, + OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, + NULL, + NULL); + Status = ZwOpenFile(&DeviceHandle, + FILE_READ_ATTRIBUTES | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_ALL, + FILE_SYNCHRONOUS_IO_NONALERT); + ok_ntstatus(Status, STATUS_SUCCESS); + if (skip(NT_SUCCESS(Status), "Device '%wZ': Opening failed\n", &DeviceName)) + return; + + /* Invoke ObjectNameInformation that retrieves the canonical device name */ + Status = ZwQueryObject(DeviceHandle, + ObjectNameInformation, + &ObjectNameBuffer, + 0, + &BufferSize1); + ok_ntstatus(Status, STATUS_INFO_LENGTH_MISMATCH); + + Status = ZwQueryObject(DeviceHandle, + ObjectNameInformation, + &ObjectNameBuffer, + sizeof(OBJECT_NAME_INFORMATION), + &BufferSize2); + ok_ntstatus(Status, STATUS_BUFFER_OVERFLOW); + + Status = ZwQueryObject(DeviceHandle, + ObjectNameInformation, + &ObjectNameBuffer, + sizeof(ObjectNameBuffer), + &BufferSize3); + ok_ntstatus(Status, STATUS_SUCCESS); + + ZwClose(DeviceHandle); + + /* Compare the returned buffer sizes */ + + /* The returned size behaviour changed (when ZwQueryObject()'s + * input Length is zero) between Windows <= 2003 and Vista+ */ + if (g_OsVersion < _WIN32_WINNT_VISTA) + ok_eq_ulong(BufferSize1, sizeof(OBJECT_NAME_INFORMATION)); + else + ok_eq_ulong(BufferSize1, sizeof(OBJECT_NAME_INFORMATION) + ObjectName->MaximumLength); + + ok_eq_ulong(BufferSize2, BufferSize3); + ok_eq_ulong(BufferSize3, sizeof(OBJECT_NAME_INFORMATION) + ObjectName->MaximumLength); + + /* Test the name buffer */ + ok(ObjectName->Length > 0, "ObjectName->Length == %hu, expected > 0\n", ObjectName->Length); + ok_eq_uint(ObjectName->MaximumLength, ObjectName->Length + sizeof(WCHAR)); + ok(ObjectName->Buffer[ObjectName->Length / sizeof(WCHAR)] == UNICODE_NULL, + "UNICODE_NULL not found at end of ObjectName->Buffer\n"); + if (skip(ObjectName->Buffer[ObjectName->Length / sizeof(WCHAR)] == UNICODE_NULL, + "ObjectName->Buffer string length check skipped\n")) + { + return; + } + /* Verify that ObjectName->Length doesn't count extra NUL-terminators */ + { + SIZE_T strLen = wcslen(ObjectName->Buffer) * sizeof(WCHAR); + ok_eq_size(strLen, (SIZE_T)ObjectName->Length); + } +} + START_TEST(ObQuery) { ObjectBasicInformationTests(); + ObjectNameInformationTests(); } diff --git a/modules/rostests/rosautotest/CConfiguration.cpp b/modules/rostests/rosautotest/CConfiguration.cpp index 8eee32dbb2955..0475ab2ae9c7a 100644 --- a/modules/rostests/rosautotest/CConfiguration.cpp +++ b/modules/rostests/rosautotest/CConfiguration.cpp @@ -6,6 +6,7 @@ */ #include "precomp.h" +#include #define CONFIGURATION_FILENAMEA "rosautotest.ini" #define CONFIGURATION_FILENAMEW L"rosautotest.ini" @@ -32,6 +33,7 @@ CConfiguration::CConfiguration() FATAL("GetWindowsDirectoryW failed\n"); m_IsReactOS = !_wcsnicmp(&WindowsDirectory[3], L"reactos", 7); + m_IsReactOS = m_IsReactOS || IsReactOS(); if(GetEnvironmentVariableW(L"WINETEST_INTERACTIVE", Interactive, _countof(Interactive))) m_IsInteractive = _wtoi(Interactive); diff --git a/modules/rostests/rosautotest/CWineTest.cpp b/modules/rostests/rosautotest/CWineTest.cpp index 7175f7ec023e5..4ca9567fbf4cb 100644 --- a/modules/rostests/rosautotest/CWineTest.cpp +++ b/modules/rostests/rosautotest/CWineTest.cpp @@ -64,11 +64,27 @@ CWineTest::GetNextFile() WIN32_FIND_DATAW fd; /* Did we already begin searching for files? */ - if(m_hFind) + if (m_hFind) { /* Then get the next file (if any) */ - if(FindNextFileW(m_hFind, &fd)) - FoundFile = true; + if (FindNextFileW(m_hFind, &fd)) + { + // printf("cFileName is '%S'.\n", fd.cFileName); + /* If it was NOT rosautotest.exe then proceed as normal */ + if (_wcsicmp(fd.cFileName, TestName) != 0) + { + FoundFile = true; + } + else + { + /* It was rosautotest.exe so get the next file (if any) */ + if (FindNextFileW(m_hFind, &fd)) + { + FoundFile = true; + } + // printf("cFileName is '%S'.\n", fd.cFileName); + } + } } else { @@ -91,8 +107,25 @@ CWineTest::GetNextFile() /* Search for the first file and check whether we got one */ m_hFind = FindFirstFileW(FindPath.c_str(), &fd); - if(m_hFind != INVALID_HANDLE_VALUE) - FoundFile = true; + /* If we returned a good handle */ + if (m_hFind != INVALID_HANDLE_VALUE) + { + // printf("cFileName is '%S'.\n", fd.cFileName); + /* If it was NOT rosautotest.exe then proceed as normal */ + if (_wcsicmp(fd.cFileName, TestName) != 0) + { + FoundFile = true; + } + else + { + /* It was rosautotest.exe so get the next file (if any) */ + if (FindNextFileW(m_hFind, &fd)) + { + FoundFile = true; + } + // printf("cFileName is '%S'.\n", fd.cFileName); + } + } } if(FoundFile) diff --git a/modules/rostests/rosautotest/main.cpp b/modules/rostests/rosautotest/main.cpp index e808d5da91a17..6a5bef97248cf 100644 --- a/modules/rostests/rosautotest/main.cpp +++ b/modules/rostests/rosautotest/main.cpp @@ -10,6 +10,8 @@ #include #include +WCHAR TestName[MAX_PATH]; + CConfiguration Configuration; /** @@ -87,6 +89,14 @@ extern "C" int wmain(int argc, wchar_t* argv[]) { int ReturnValue = 1; + DWORD TestStartTime, TestEndTime; + + GetModuleFileNameW(NULL, TestName, _countof(TestName)); +// printf("Full TestName is '%S'\n", TestName); + WCHAR* Name = wcsrchr(TestName, '\\'); + if (Name) + memmove(TestName, Name + 1, (wcslen(Name + 1) + 1) * sizeof(WCHAR)); +// printf("Short TestName is '%S'.\n", TestName); SetNtGlobalFlags(); @@ -99,10 +109,11 @@ wmain(int argc, wchar_t* argv[]) Configuration.GetSystemInformation(); Configuration.GetConfigurationFromFile(); + TestStartTime = GetTickCount(); ss << endl << endl << "[ROSAUTOTEST] System uptime " << setprecision(2) << fixed; - ss << ((float)GetTickCount()/1000) << " seconds" << endl; + ss << (float)TestStartTime / 1000 << " seconds" << endl; StringOut(ss.str()); /* Report tests startup */ @@ -139,6 +150,23 @@ wmain(int argc, wchar_t* argv[]) WineTest.Run(); } + /* Clear the stringstream */ + ss.str(""); + ss.clear(); + + /* Show the beginning time again */ + ss << "[ROSAUTOTEST] System uptime at start was " << setprecision(2) << fixed; + ss << (float)TestStartTime / 1000 << " seconds" << endl; + + /* Show the time now so that we can see how long the tests took */ + TestEndTime = GetTickCount(); + ss << endl + << "[ROSAUTOTEST] System uptime at end was " << setprecision(2) << fixed; + ss << ((float)TestEndTime / 1000) << " seconds" << endl; + ss << "[ROSAUTOTEST] Duration was " << (float)(TestEndTime - TestStartTime) / (60 * 1000); + ss << " minutes" << endl; + StringOut(ss.str()); + /* For sysreg2 */ DbgPrint("SYSREG_CHECKPOINT:THIRDBOOT_COMPLETE\n"); diff --git a/modules/rostests/rosautotest/precomp.h b/modules/rostests/rosautotest/precomp.h index 5e0f05b5794a9..a9157b8684274 100644 --- a/modules/rostests/rosautotest/precomp.h +++ b/modules/rostests/rosautotest/precomp.h @@ -80,4 +80,6 @@ string StringOut(const string& String, bool forcePrint = true); string UnicodeToAscii(PCWSTR UnicodeString); string UnicodeToAscii(const wstring& UnicodeString); +extern WCHAR TestName[MAX_PATH]; + #endif /* _ROSAUTOTEST_H_ */ diff --git a/modules/rostests/win32/advapi32/eventlog/EvtLogTest.c b/modules/rostests/win32/advapi32/eventlog/EvtLogTest.c index e498c31ba014c..da7868e9e4595 100644 --- a/modules/rostests/win32/advapi32/eventlog/EvtLogTest.c +++ b/modules/rostests/win32/advapi32/eventlog/EvtLogTest.c @@ -302,7 +302,7 @@ VOID TestEventsGeneration(VOID) /* * This code was adapted from the MSDN article "Reporting Events" at: - * https://msdn.microsoft.com/en-us/library/windows/desktop/aa363680(v=vs.85).aspx + * https://learn.microsoft.com/en-us/windows/win32/eventlog/reporting-an-event */ VOID TestMyEventProvider(VOID) { diff --git a/modules/rostests/win32/kernel32/notificationtest/notificationtest.c b/modules/rostests/win32/kernel32/notificationtest/notificationtest.c index f6280324921d2..81ba4421ab9f8 100644 --- a/modules/rostests/win32/kernel32/notificationtest/notificationtest.c +++ b/modules/rostests/win32/kernel32/notificationtest/notificationtest.c @@ -1,7 +1,7 @@ /* * FILE: notificationtest.c * PURPOSE: Files notifications testing - * NOTES: MSDN code from: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365261%28v=vs.85%29.aspx + * NOTES: MSDN code from: https://learn.microsoft.com/en-us/windows/win32/fileio/obtaining-directory-change-notifications */ #include diff --git a/modules/rostests/win32/user32/biditext/biditext.rc b/modules/rostests/win32/user32/biditext/biditext.rc index cc2a2632f837a..047fbc026967e 100644 --- a/modules/rostests/win32/user32/biditext/biditext.rc +++ b/modules/rostests/win32/user32/biditext/biditext.rc @@ -38,7 +38,7 @@ BEGIN VALUE "FileDescription", "Win32 Example Application" VALUE "FileVersion", "1.0.0.0" VALUE "InternalName", "Win32App" - VALUE "LegalCopyright", "2017 Transmission Zero" + VALUE "LegalCopyright", "(c)2017 Transmission Zero" VALUE "OriginalFilename", "Win32App.exe" VALUE "ProductName", "Win32 Example Application" VALUE "ProductVersion", "1.0.0.0" @@ -58,7 +58,7 @@ FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN ICON IDI_APPICON,IDC_STATIC,7,7,20,20 LTEXT "Win32 Example Application",IDC_STATIC,34,7,89,8 - LTEXT "2017 Transmission Zero",IDC_STATIC,34,17,86,8 + LTEXT "(c)2017 Transmission Zero",IDC_STATIC,34,17,86,8 DEFPUSHBUTTON "OK",IDOK,90,46,50,14,WS_GROUP END diff --git a/modules/rostests/winetests/CMakeLists.txt b/modules/rostests/winetests/CMakeLists.txt index c6a7ab402f3d8..0bb0412fdc931 100644 --- a/modules/rostests/winetests/CMakeLists.txt +++ b/modules/rostests/winetests/CMakeLists.txt @@ -115,6 +115,7 @@ add_subdirectory(spoolss) add_subdirectory(sti) add_subdirectory(sxs) add_subdirectory(twain_32) +add_subdirectory(ucrtbase) add_subdirectory(urlmon) add_subdirectory(user32) add_subdirectory(userenv) diff --git a/modules/rostests/winetests/GUI/WinetestsGUI.rc b/modules/rostests/winetests/GUI/WinetestsGUI.rc index c07badd922ca2..71728c02d54fc 100644 --- a/modules/rostests/winetests/GUI/WinetestsGUI.rc +++ b/modules/rostests/winetests/GUI/WinetestsGUI.rc @@ -13,7 +13,6 @@ /* UTF-8 */ #pragma code_page(65001) - #ifdef LANGUAGE_EN_US #include "lang/en-US.rc" #endif diff --git a/modules/rostests/winetests/mshtml/activex.c b/modules/rostests/winetests/mshtml/activex.c index 117becd79afec..4d768378fc902 100644 --- a/modules/rostests/winetests/mshtml/activex.c +++ b/modules/rostests/winetests/mshtml/activex.c @@ -2434,6 +2434,7 @@ static void test_flash_ax(void) skip("Skipping test_ui_activate(). ROSTESTS-114.\n"); skip("Skipping test_container(notif_doc). ROSTESTS-114.\n"); skip("Skipping test_object_elem(notif_doc). ROSTESTS-114.\n"); + return; } IOleClientSite_AddRef(client_site); diff --git a/modules/rostests/winetests/msvcrt/CMakeLists.txt b/modules/rostests/winetests/msvcrt/CMakeLists.txt index 53cb3a0067c16..8ee88854dc9a8 100644 --- a/modules/rostests/winetests/msvcrt/CMakeLists.txt +++ b/modules/rostests/winetests/msvcrt/CMakeLists.txt @@ -1,4 +1,6 @@ +remove_definitions(-D_CRT_NON_CONFORMING_SWPRINTFS) + list(APPEND SOURCE cpp.c data.c @@ -15,7 +17,7 @@ list(APPEND SOURCE time.c) list(APPEND PCH_SKIP_SOURCE - printf.c # _CRT_NON_CONFORMING_SWPRINTFS + printf.c testlist.c) add_executable(msvcrt_winetest @@ -25,6 +27,8 @@ add_executable(msvcrt_winetest target_compile_definitions(msvcrt_winetest PRIVATE WINETEST_USE_DBGSTR_LONGLONG _CRT_NONSTDC_NO_DEPRECATE + _USE_MATH_DEFINES + WIN32_NO_STATUS= __msvcrt_ulong=ULONG) if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") @@ -34,13 +38,14 @@ if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") endif() endif() -set_module_type(msvcrt_winetest win32cui) -add_importlibs(msvcrt_winetest advapi32 msvcrt kernel32) -target_link_libraries(msvcrt_winetest oldnames) - if(MSVC) - add_importlibs(msvcrt_winetest ntdll) + # 'swscanf' : unknown type field character '\xe1' in format specifier + target_compile_options(msvcrt_winetest PRIVATE /wd4476) endif() +set_module_type(msvcrt_winetest win32cui) +add_importlibs(msvcrt_winetest advapi32 msvcrt kernel32 ntdll) +target_link_libraries(msvcrt_winetest oldnames) + add_pch(msvcrt_winetest precomp.h "${PCH_SKIP_SOURCE}") add_rostests_file(TARGET msvcrt_winetest) diff --git a/modules/rostests/winetests/msvcrt/cpp.c b/modules/rostests/winetests/msvcrt/cpp.c index 07b49ae755d50..2bbf34dcd018a 100644 --- a/modules/rostests/winetests/msvcrt/cpp.c +++ b/modules/rostests/winetests/msvcrt/cpp.c @@ -44,12 +44,8 @@ typedef struct __type_info #endif /* Function pointers. We need to use these to call these funcs as __thiscall */ -static HMODULE hMsvcrt; - -static void* (__cdecl *poperator_new)(unsigned int); +static void* (__cdecl *poperator_new)(size_t); static void (__cdecl *poperator_delete)(void*); -static void* (__cdecl *pmalloc)(unsigned int); -static void (__cdecl *pfree)(void*); /* exception */ static void (__thiscall *pexception_ctor)(exception*,LPCSTR*); @@ -112,9 +108,6 @@ static void* (__cdecl *p__RTDynamicCast)(void*,int,void*,void*,int); static char* (__cdecl *p__unDName)(char*,const char*,int,void*,void*,unsigned short int); -/* _very_ early native versions have serious RTTI bugs, so we check */ -static void* bAncientVersion; - /* Emulate a __thiscall */ #ifdef __i386__ @@ -157,23 +150,12 @@ static void init_thiscall_thunk(void) #endif /* __i386__ */ /* Some exports are only available in later versions */ -#define SETNOFAIL(x,y) x = (void*)GetProcAddress(hMsvcrt,y) +#define SETNOFAIL(x,y) x = (void*)GetProcAddress(hmsvcrt,y) #define SET(x,y) do { SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y); } while(0) static BOOL InitFunctionPtrs(void) { - hMsvcrt = GetModuleHandleA("msvcrt.dll"); - if (!hMsvcrt) - hMsvcrt = GetModuleHandleA("msvcrtd.dll"); - ok(hMsvcrt != 0, "GetModuleHandleA failed\n"); - if (!hMsvcrt) - { - win_skip("Could not load msvcrt.dll\n"); - return FALSE; - } - - SET(pmalloc, "malloc"); - SET(pfree, "free"); + HMODULE hmsvcrt = GetModuleHandleA("msvcrt.dll"); SET(pexception_vtable, "??_7exception@@6B@"); SET(pbad_typeid_vtable, "??_7bad_typeid@@6B@"); @@ -187,7 +169,6 @@ static BOOL InitFunctionPtrs(void) SET(p__unDName,"__unDName"); /* Extremely early versions export logic_error, and crash in RTTI */ - SETNOFAIL(bAncientVersion, "??0logic_error@@QAE@ABQBD@Z"); if (sizeof(void *) > sizeof(int)) /* 64-bit initialization */ { SETNOFAIL(poperator_new, "??_U@YAPEAX_K@Z"); @@ -242,50 +223,50 @@ static BOOL InitFunctionPtrs(void) SETNOFAIL(poperator_new, "??_U@YAPAXI@Z"); SETNOFAIL(poperator_delete, "??_V@YAXPAX@Z"); - SET(pexception_ctor, "??0exception@std@@QAA@ABQBD@Z"); - SET(pexception_copy_ctor, "??0exception@std@@QAA@ABV01@@Z"); - SET(pexception_default_ctor, "??0exception@std@@QAA@XZ"); - SET(pexception_dtor, "??1exception@std@@UAA@XZ"); - SET(pexception_opequals, "??4exception@std@@QAAAAV01@ABV01@@Z"); - SET(pexception_what, "?what@exception@std@@UBAPBDXZ"); - SET(pexception_vector_dtor, "??_Eexception@@UAEPAXI@Z");/**/ - SET(pexception_scalar_dtor, "??_Gexception@@UAEPAXI@Z");/**/ - - SET(pbad_typeid_ctor, "??0bad_typeid@std@@QAA@PBD@Z"); - SETNOFAIL(pbad_typeid_ctor_closure, "??_Fbad_typeid@std@@QAAXXZ"); - SET(pbad_typeid_copy_ctor, "??0bad_typeid@std@@QAA@ABV01@@Z"); - SET(pbad_typeid_dtor, "??1bad_typeid@std@@UAA@XZ"); - SET(pbad_typeid_opequals, "??4bad_typeid@std@@QAAAAV01@ABV01@@Z"); - SET(pbad_typeid_what, "?what@exception@std@@UBAPBDXZ"); - SET(pbad_typeid_vector_dtor, "??_Ebad_cast@@UAEPAXI@Z"); - SET(pbad_typeid_scalar_dtor, "??_Gbad_cast@@UAEPAXI@Z"); + SET(pexception_ctor, "??0exception@@QAA@ABQBD@Z"); + SET(pexception_copy_ctor, "??0exception@@QAA@ABV0@@Z"); + SET(pexception_default_ctor, "??0exception@@QAA@XZ"); + SET(pexception_dtor, "??1exception@@UAA@XZ"); + SET(pexception_opequals, "??4exception@@QAAAAV0@ABV0@@Z"); + SET(pexception_what, "?what@exception@@UBAPBDXZ"); + pexception_vector_dtor = (void*)pexception_vtable[0]; + pexception_scalar_dtor = (void*)pexception_vtable[0]; + + SET(pbad_typeid_ctor, "??0bad_typeid@@QAA@PBD@Z"); + SETNOFAIL(pbad_typeid_ctor_closure, "??_Fbad_typeid@@QAAXXZ"); + SET(pbad_typeid_copy_ctor, "??0bad_typeid@@QAA@ABV0@@Z"); + SET(pbad_typeid_dtor, "??1bad_typeid@@UAA@XZ"); + SET(pbad_typeid_opequals, "??4bad_typeid@@QAAAAV0@ABV0@@Z"); + SET(pbad_typeid_what, "?what@exception@@UBAPBDXZ"); + pbad_typeid_vector_dtor = (void*)pbad_typeid_vtable[0]; + pbad_typeid_scalar_dtor = (void*)pbad_typeid_vtable[0]; SETNOFAIL(pbad_cast_ctor, "??0bad_cast@@QAE@ABQBD@Z"); if (!pbad_cast_ctor) - SET(pbad_cast_ctor, "??0bad_cast@std@@AAA@PBQBD@Z"); - SETNOFAIL(pbad_cast_ctor2, "??0bad_cast@std@@QAA@PBD@Z"); - SETNOFAIL(pbad_cast_ctor_closure, "??_Fbad_cast@std@@QAAXXZ"); - /* FIXME: No ARM equivalent for "??0bad_cast@@QAE@ABV0@@Z" */ - SET(pbad_cast_dtor, "??1bad_cast@std@@UAA@XZ"); - SET(pbad_cast_opequals, "??4bad_cast@std@@QAAAAV01@ABV01@@Z"); - SET(pbad_cast_what, "?what@exception@std@@UBAPBDXZ"); - SET(pbad_cast_vector_dtor, "??_Ebad_cast@@UAEPAXI@Z"); - SET(pbad_cast_scalar_dtor, "??_Gbad_cast@@UAEPAXI@Z"); + SET(pbad_cast_ctor, "??0bad_cast@@AAA@PBQBD@Z"); + SETNOFAIL(pbad_cast_ctor2, "??0bad_cast@@QAA@PBD@Z"); + SETNOFAIL(pbad_cast_ctor_closure, "??_Fbad_cast@@QAAXXZ"); + SET(pbad_cast_copy_ctor, "??0bad_cast@@QAA@ABV0@@Z"); + SET(pbad_cast_dtor, "??1bad_cast@@UAA@XZ"); + SET(pbad_cast_opequals, "??4bad_cast@@QAAAAV0@ABV0@@Z"); + SET(pbad_cast_what, "?what@exception@@UBAPBDXZ"); + pbad_cast_vector_dtor = (void*)pbad_cast_vtable[0]; + pbad_cast_scalar_dtor = (void*)pbad_cast_vtable[0]; - SET(p__non_rtti_object_ctor, "??0__non_rtti_object@std@@QAA@PBD@Z"); - SET(p__non_rtti_object_copy_ctor, "??0__non_rtti_object@std@@QAA@ABV01@@Z"); - SET(p__non_rtti_object_dtor, "??1__non_rtti_object@std@@UAA@XZ"); - SET(p__non_rtti_object_opequals, "??4__non_rtti_object@std@@QAAAAV01@ABV01@@Z"); - SET(p__non_rtti_object_what, "?what@exception@std@@UBAPBDXZ"); - SET(p__non_rtti_object_vector_dtor, "??_E__non_rtti_object@@UAEPAXI@Z"); - SET(p__non_rtti_object_scalar_dtor, "??_G__non_rtti_object@@UAEPAXI@Z"); + SET(p__non_rtti_object_ctor, "??0__non_rtti_object@@QAA@PBD@Z"); + SET(p__non_rtti_object_copy_ctor, "??0__non_rtti_object@@QAA@ABV0@@Z"); + SET(p__non_rtti_object_dtor, "??1__non_rtti_object@@UAA@XZ"); + SET(p__non_rtti_object_opequals, "??4__non_rtti_object@@QAAAAV0@ABV0@@Z"); + SET(p__non_rtti_object_what, "?what@exception@@UBAPBDXZ"); + p__non_rtti_object_vector_dtor = (void*)p__non_rtti_object_vtable[0]; + p__non_rtti_object_scalar_dtor = (void*)p__non_rtti_object_vtable[0]; SET(ptype_info_dtor, "??1type_info@@UAA@XZ"); SET(ptype_info_raw_name, "?raw_name@type_info@@QBAPBDXZ"); - SET(ptype_info_name, "?name@type_info@@QBEPBDXZ"); - SET(ptype_info_before, "?before@type_info@@QBA_NABV1@@Z"); - SET(ptype_info_opequals_equals, "??8type_info@@QBA_NABV0@@Z"); - SET(ptype_info_opnot_equals, "??9type_info@@QBA_NABV0@@Z"); + SET(ptype_info_name, "?name@type_info@@QBAPBDXZ"); + SET(ptype_info_before, "?before@type_info@@QBAHABV1@@Z"); + SET(ptype_info_opequals_equals, "??8type_info@@QBAHABV0@@Z"); + SET(ptype_info_opnot_equals, "??9type_info@@QBAHABV0@@Z"); #else SETNOFAIL(poperator_new, "??_U@YAPAXI@Z"); SETNOFAIL(poperator_delete, "??_V@YAXPAX@Z"); @@ -338,9 +319,9 @@ static BOOL InitFunctionPtrs(void) } if (!poperator_new) - poperator_new = pmalloc; + poperator_new = malloc; if (!poperator_delete) - poperator_delete = pfree; + poperator_delete = free; init_thiscall_thunk(); return TRUE; @@ -448,7 +429,7 @@ static void test_exception(void) name = call_func1(pexception_what, &e); ok(e.name == name, "Bad exception name from vtable e::what()\n"); - if (p__RTtypeid && !bAncientVersion) + if (p__RTtypeid) { /* Check the rtti */ type_info *ti = p__RTtypeid(&e); @@ -571,7 +552,7 @@ static void test_bad_typeid(void) name = call_func1(pbad_typeid_what, &e); ok(e.name == name, "Bad bad_typeid name from vtable e::what()\n"); - if (p__RTtypeid && !bAncientVersion) + if (p__RTtypeid) { /* Check the rtti */ type_info *ti = p__RTtypeid(&e); @@ -699,7 +680,7 @@ static void test_bad_cast(void) name = call_func1(pbad_cast_what, &e); ok(e.name == name, "Bad bad_cast name from vtable e::what()\n"); - if (p__RTtypeid && !bAncientVersion) + if (p__RTtypeid) { /* Check the rtti */ type_info *ti = p__RTtypeid(&e); @@ -801,7 +782,7 @@ static void test___non_rtti_object(void) name = call_func1(p__non_rtti_object_what, &e); ok(e.name == name, "Bad __non_rtti_object name from vtable e::what()\n"); - if (p__RTtypeid && !bAncientVersion) + if (p__RTtypeid) { /* Check the rtti */ type_info *ti = p__RTtypeid(&e); @@ -818,14 +799,14 @@ static void test_type_info(void) char* name; int res; - if (!pmalloc || !pfree || !ptype_info_dtor || !ptype_info_raw_name || + if (!ptype_info_dtor || !ptype_info_raw_name || !ptype_info_name || !ptype_info_before || !ptype_info_opequals_equals || !ptype_info_opnot_equals) return; /* Test calling the dtors */ call_func1(ptype_info_dtor, &t1); /* No effect, since name is NULL */ - t1.name = pmalloc(64); + t1.name = malloc(64); strcpy(t1.name, "foo"); call_func1(ptype_info_dtor, &t1); /* Frees t1.name using 'free' */ @@ -888,7 +869,7 @@ static inline void/*rtti_object_locator*/ *get_obj_locator( void *cppobj ) return (void *)vtable[-1]; } -#ifndef __x86_64__ +#ifdef __i386__ #define DEFINE_RTTI_REF(type, name) type *name #define RTTI_REF(instance, name) &instance.name #define RTTI_REF_SIG0(instance, name, base) RTTI_REF(instance, name) @@ -910,33 +891,36 @@ static void test_rtti(void) DEFINE_RTTI_REF(void, object_locator); } *obj_locator; + struct _rtti_base_descriptor + { + DEFINE_RTTI_REF(type_info, type_descriptor); + int num_base_classes; + struct { + int this_offset; + int vbase_descr; + int vbase_offset; + } this_ptr_offsets; + unsigned int attributes; + }; + + struct _rtti_base_array { + DEFINE_RTTI_REF(struct _rtti_base_descriptor, bases[4]); + }; + + struct _rtti_object_hierarchy { + unsigned int signature; + unsigned int attributes; + int array_len; + DEFINE_RTTI_REF(struct _rtti_base_array, base_classes); + }; + struct rtti_data { type_info type_info[4]; - struct _rtti_base_descriptor - { - DEFINE_RTTI_REF(type_info, type_descriptor); - int num_base_classes; - struct { - int this_offset; - int vbase_descr; - int vbase_offset; - } this_ptr_offsets; - unsigned int attributes; - } base_descriptor[4]; - - struct _rtti_base_array { - DEFINE_RTTI_REF(struct _rtti_base_descriptor, bases[4]); - } base_array; - - struct _rtti_object_hierarchy { - unsigned int signature; - unsigned int attributes; - int array_len; - DEFINE_RTTI_REF(struct _rtti_base_array, base_classes); - } object_hierarchy; - + struct _rtti_base_descriptor base_descriptor[4]; + struct _rtti_base_array base_array; + struct _rtti_object_hierarchy object_hierarchy; struct _object_locator object_locator; } simple_class_rtti = { { {NULL, NULL, "simple_class"} }, @@ -962,11 +946,17 @@ static void test_rtti(void) void *simple_class_vtbl[2] = {&simple_class_rtti.object_locator}; void *simple_class = &simple_class_vtbl[1]; void *child_class_vtbl[2] = {&child_class_rtti.object_locator}; - void *child_class = &child_class_vtbl[1]; + struct { + void *vtbl; + char data[4]; + } child_class = { &child_class_vtbl[1] }; void *simple_class_sig0_vtbl[2] = {&simple_class_sig0_rtti.object_locator}; void *simple_class_sig0 = &simple_class_sig0_vtbl[1]; void *child_class_sig0_vtbl[2] = {&child_class_sig0_rtti.object_locator}; - void *child_class_sig0 = &child_class_sig0_vtbl[1]; + struct { + void *vtbl; + char data[4]; + } child_class_sig0 = { &child_class_sig0_vtbl[1] }; void *virtual_base_class_vtbl[2] = {&virtual_base_class_rtti.object_locator}; int virtual_base_class_vbtbl[2] = {0, 0x100}; struct { @@ -980,12 +970,11 @@ static void test_rtti(void) exception e,b; void *casted; BOOL old_signature; -#ifdef __x86_64__ +#ifndef __i386__ char *base = (char*)GetModuleHandleW(NULL); #endif - if (bAncientVersion || - !p__RTCastToVoid || !p__RTtypeid || !pexception_ctor || !pbad_typeid_ctor + if (!p__RTCastToVoid || !p__RTtypeid || !pexception_ctor || !pbad_typeid_ctor || !p__RTDynamicCast || !pexception_dtor || !pbad_typeid_dtor) return; @@ -1099,46 +1088,32 @@ static void test_demangle_datatype(void) { char * name; struct _demangle demangle[]={ -/* { "BlaBla"," ?? ::Bla", FALSE}, */ - { "ABVVec4@ref2@dice@@","class dice::ref2::Vec4 const &",TRUE}, - { "?AV?$CDB_GEN_BIG_ENUM_FLAG@W4CDB_WYSIWYG_BITS_ENUM@@$0H@@@", "class CDB_GEN_BIG_ENUM_FLAG", TRUE}, - { "?AV?$CDB_GEN_BIG_ENUM_FLAG@W4CDB_WYSIWYG_BITS_ENUM@@$0HO@@@", "class CDB_GEN_BIG_ENUM_FLAG",TRUE}, - { "?AV?$CDB_GEN_BIG_ENUM_FLAG@W4CDB_WYSIWYG_BITS_ENUM@@$0HOA@@@", "class CDB_GEN_BIG_ENUM_FLAG",TRUE}, - { "?AV?$CDB_GEN_BIG_ENUM_FLAG@W4CDB_WYSIWYG_BITS_ENUM@@$0HOAA@@@", "class CDB_GEN_BIG_ENUM_FLAG",TRUE}, - { "?AV?$CDB_GEN_BIG_ENUM_FLAG@W4CDB_WYSIWYG_BITS_ENUM@@$01@@@", "?AV?$CDB_GEN_BIG_ENUM_FLAG@W4CDB_WYSIWYG_BITS_ENUM@@$01@@@", FALSE}, -/* { "?AV?$CDB_GEN_BIG_ENUM_FLAG@W4CDB_WYSIWYG_BITS_ENUM@@$011@@@", "?AV?$CDB_GEN_BIG_ENUM_FLAG@W4CDB_WYSIWYG_BITS_ENUM@@$011@@@",FALSE}, */ + { "BlaBla"," ?? ::Bla", FALSE}, + { "ABVVec4@ref2@dice@@", "class dice::ref2::Vec4 const &", TRUE}, + { "?AV?$CDB_GEN_BIG_ENUM_FLAG@W4CDB_WYSIWYG_BITS_ENUM@@$0H@@@", + "class CDB_GEN_BIG_ENUM_FLAG", TRUE}, + { "?AV?$CDB_GEN_BIG_ENUM_FLAG@W4CDB_WYSIWYG_BITS_ENUM@@$0HO@@@", + "class CDB_GEN_BIG_ENUM_FLAG",TRUE}, + { "?AV?$CDB_GEN_BIG_ENUM_FLAG@W4CDB_WYSIWYG_BITS_ENUM@@$0HOA@@@", + "class CDB_GEN_BIG_ENUM_FLAG",TRUE}, + { "?AV?$CDB_GEN_BIG_ENUM_FLAG@W4CDB_WYSIWYG_BITS_ENUM@@$0HOAA@@@", + "class CDB_GEN_BIG_ENUM_FLAG",TRUE}, + { "?AV?$CDB_GEN_BIG_ENUM_FLAG@W4CDB_WYSIWYG_BITS_ENUM@@$01@@@", + "?AV?$CDB_GEN_BIG_ENUM_FLAG@W4CDB_WYSIWYG_BITS_ENUM@@$01@@@", FALSE}, + { "P8test@@AACXZ", "signed char (__cdecl test::*)(void)", TRUE}, + { "P8test@@BACXZ", "signed char (__cdecl test::*)(void)const ", TRUE}, }; int i, num_test = ARRAY_SIZE(demangle); for (i = 0; i < num_test; i++) { - name = p__unDName(0, demangle[i].mangled, 0, pmalloc, pfree, 0x2800); + name = p__unDName(0, demangle[i].mangled, 0, malloc, free, 0x2800); todo_wine_if (!demangle[i].test_in_wine) ok(name != NULL && !strcmp(name,demangle[i].result), "Got name \"%s\" for %d\n", name, i); - if(name) - pfree(name); + free(name); } } -/* Compare two strings treating multiple spaces (' ', ascii 0x20) in s2 - as single space. Needed for test_demangle as __unDName() returns sometimes - two spaces instead of one in some older native msvcrt dlls. */ -static int strcmp_space(const char *s1, const char *s2) -{ - const char* s2start = s2; - do { - while (*s1 == *s2 && *s1) { - s1++; - s2++; - } - if (*s2 == ' ' && s2 > s2start && *(s2 - 1) == ' ') - s2++; - else - break; - } while (*s1 && *s2); - return *s1 - *s2; -} - static void test_demangle(void) { static struct {const char* in; const char* out; const char *broken; unsigned int flags;} test[] = { @@ -1202,7 +1177,7 @@ static void test_demangle(void) /* 23 */ {"??0streambuf@@QAE@ABV0@@Z", "public: __thiscall streambuf::streambuf(class streambuf const &)"}, /* 24 */ {"??0strstreambuf@@QAE@ABV0@@Z", "public: __thiscall strstreambuf::strstreambuf(class strstreambuf const &)"}, /* 25 */ {"??0strstreambuf@@QAE@H@Z", "public: __thiscall strstreambuf::strstreambuf(int)"}, -/* 26 */ {"??0strstreambuf@@QAE@P6APAXJ@ZP6AXPAX@Z@Z", "public: __thiscall strstreambuf::strstreambuf(void * (__cdecl*)(long),void (__cdecl*)(void *))"}, +/* 26 */ {"??0strstreambuf@@QAE@Q6APAXJ@ZS6AXPAX@Z@Z", "public: __thiscall strstreambuf::strstreambuf(void * (__cdecl*const)(long),void (__cdecl*const volatile)(void *))"}, /* 27 */ {"??0strstreambuf@@QAE@PADH0@Z", "public: __thiscall strstreambuf::strstreambuf(char *,int,char *)"}, /* 28 */ {"??0strstreambuf@@QAE@PAEH0@Z", "public: __thiscall strstreambuf::strstreambuf(unsigned char *,int,unsigned char *)"}, /* 29 */ {"??0strstreambuf@@QAE@XZ", "public: __thiscall strstreambuf::strstreambuf(void)"}, @@ -1237,7 +1212,7 @@ static void test_demangle(void) /* 58 */ {"?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAJ@Z", "protected: virtual class std::istreambuf_iterator > __thiscall std::num_get > >::do_get(class std::istreambuf_iterator >,class std::istreambuf_iterator >,class std::ios_base &,int &,long &)const "}, /* 59 */ {"?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAK@Z", "protected: virtual class std::istreambuf_iterator > __thiscall std::num_get > >::do_get(class std::istreambuf_iterator >,class std::istreambuf_iterator >,class std::ios_base &,int &,unsigned long &)const "}, /* 60 */ {"?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAM@Z", "protected: virtual class std::istreambuf_iterator > __thiscall std::num_get > >::do_get(class std::istreambuf_iterator >,class std::istreambuf_iterator >,class std::ios_base &,int &,float &)const "}, -/* 61 */ {"?_query_new_handler@@YAP6AHI@ZXZ", "int (__cdecl*__cdecl _query_new_handler(void))(unsigned int)"}, +/* 61 */ {"?_query_new_handler@@YAR6AHI@ZXZ", "int (__cdecl*__cdecl _query_new_handler(void))(unsigned int)"}, /* 62 */ {"?register_callback@ios_base@std@@QAEXP6AXW4event@12@AAV12@H@ZH@Z", "public: void __thiscall std::ios_base::register_callback(void (__cdecl*)(enum std::ios_base::event,class std::ios_base &,int),int)"}, /* 63 */ {"?seekg@?$basic_istream@DU?$char_traits@D@std@@@std@@QAEAAV12@JW4seekdir@ios_base@2@@Z", "public: class std::basic_istream > & __thiscall std::basic_istream >::seekg(long,enum std::ios_base::seekdir)"}, /* 64 */ {"?seekg@?$basic_istream@DU?$char_traits@D@std@@@std@@QAEAAV12@V?$fpos@H@2@@Z", "public: class std::basic_istream > & __thiscall std::basic_istream >::seekg(class std::fpos)"}, @@ -1325,22 +1300,59 @@ static void test_demangle(void) "??$run@XVTask_Render_Preview@@@QtConcurrent@@YA?AV?$QFuture@X@@PEAVTask_Render_Preview@@P82@EAAXXZ@Z"}, /* 130 */ {"??_E?$TStrArray@$$BY0BAA@D$0BA@@@UAEPAXI@Z", "public: virtual void * __thiscall TStrArray::`vector deleting destructor'(unsigned int)"}, +/* 131 */ {"??_R0?AVCC@DD@@@8", "class DD::CC `RTTI Type Descriptor'"}, +/* 132 */ {"??$meth@FD@DD@CC@@QAE_NK@Z", "public: bool __thiscall CC::DD::meth(unsigned long)"}, +/* 133 */ {"?func@@YAXPIFAH@Z", "void __cdecl func(int __unaligned * __restrict)"}, +/* 135 */ {"?x@@3PAY02HA", "int (* x)[3]"}, +/* 136 */ {"?Qux@Bar@@0PAPAP6AHPAV1@AAH1PAH@ZA", + "private: static int (__cdecl** * Bar::Qux)(class Bar *,int &,int &,int *)"}, /* variation of 105: note white space handling! */ +/* 137 */ {"?x@@3PAW4myenum@@A", "enum myenum * x"}, +/* 138 */ {"?pfunc@@3PAY0E@P6AXF@ZA", "void (__cdecl*(* pfunc)[4])(short)"}, +/* 139 */ {"??$?0AEAVzzz@BB4@AA@@AEAV012@$0A@@?$pair@Vzzz@BB4@AA@@V123@@std@@QEAA@AEAVzzz@BB4@AA@@0@Z", + "public: __cdecl std::pair::pair(class AA::BB4::zzz & __ptr64,class AA::BB4::zzz & __ptr64) __ptr64"}, +/* 140 */ {"??$?BH@?$foo@N@@QEAAHXZ", "public: __cdecl foo::operator int(void) __ptr64"}, +/* 141 */ {"??Bcastop@@QAEHXZ", "public: __thiscall castop::operator int(void)"}, +/* 142 */ {"??Bcastop@@QAE?BHXZ", "public: __thiscall castop::operator int const (void)"}, +/* 143 */ {"?pfield@@3PTAA@@DT1@", "char const volatile AA::* const volatile pfield"}, +/* 144 */ {"?ptititi1@@3PEQtititi@@IEQ1@", "unsigned int tititi::* __ptr64 __ptr64 ptititi1"}, +/* 145 */ {"?ptititi2@@3PERtititi@@IER1@", "unsigned int const tititi::* __ptr64 const __ptr64 ptititi2"}, +/* 146 */ {"?ptititi3@@3PEStititi@@IES1@", "unsigned int volatile tititi::* __ptr64 volatile __ptr64 ptititi3"}, +/* 147 */ {"?ptititi4@@3PETtititi@@IET1@", "unsigned int const volatile tititi::* __ptr64 const volatile __ptr64 ptititi4"}, +/* 148 */ {"?ptititi4v@@3RETtititi@@IET1@", "unsigned int const volatile tititi::* __ptr64 const volatile __ptr64 ptititi4v"}, +/* 149 */ {"?meth@AAA@@QFCEXXZ", "public: void __thiscall AAA::meth(void)volatile __unaligned "}, +/* 150 */ {"?RegisterModuleUninitializer@@@YAXP$AAVEventHandler@System@@@Z", + "void __cdecl ::RegisterModuleUninitializer(class System::EventHandler ^)"}, +/* 151 */ {"?RegisterModuleUninitializer@@@YAXBE$AAVEventHandler@System@@@Z", + "void __cdecl ::RegisterModuleUninitializer(class System::EventHandler % __ptr64 volatile)"}, +/* 152 */ {"??$forward@AEAUFFIValue@?1??call@FFIFunctionBinder@@CAHPEAUlua_State@@@Z@@std@@YAAEAUFFIValue@?1??call@" + "FFIFunctionBinder@@CAHPEAUxlua_State@@@Z@AEAU1?1??23@CAH0@Z@@Z", + "struct `private: static int __cdecl FFIFunctionBinder::call(struct xlua_State * __ptr64)'::`2'::FFIValue & " + "__ptr64 __cdecl std::forward(struct `private: static int __cdecl FFIFunctionBinder::call(struct " + "xlua_State * __ptr64)'::`2'::FFIValue & __ptr64)"}, +/* 153 */ {"?$AAA@XX", "AAA"}, +/* 154 */ {"?$AAA@", "AAA<>"}, }; - int i, num_test = ARRAY_SIZE(test); + int i; char* name; - for (i = 0; i < num_test; i++) + for (i = 0; i < ARRAY_SIZE(test); i++) { - name = p__unDName(0, test[i].in, 0, pmalloc, pfree, test[i].flags); + if (((i == 149) || (i == 150)) && (_winver < 0x600)) + { + skip("Skipping test with i = %u, because it fails on Windows 2003\n", i); + continue; + } + name = p__unDName(0, test[i].in, 0, malloc, free, test[i].flags); ok(name != NULL, "%u: unDName failed\n", i); if (!name) continue; - ok( !strcmp_space(test[i].out, name) || - broken(test[i].broken && !strcmp_space(test[i].broken, name)), + ok( !strcmp(test[i].out, name) || + broken(test[i].broken && !strcmp(test[i].broken, name)), "%u: Got name \"%s\"\n", i, name ); - ok( !strcmp_space(test[i].out, name) || - broken(test[i].broken && !strcmp_space(test[i].broken, name)), + ok( !strcmp(test[i].out, name) || + broken(test[i].broken && !strcmp(test[i].broken, name)), "%u: Expected \"%s\"\n", i, test[i].out ); - pfree(name); + free(name); } } diff --git a/modules/rostests/winetests/msvcrt/data.c b/modules/rostests/winetests/msvcrt/data.c index b0acc60b20b16..b78bc4f702996 100644 --- a/modules/rostests/winetests/msvcrt/data.c +++ b/modules/rostests/winetests/msvcrt/data.c @@ -32,7 +32,11 @@ #include #include -void __cdecl __getmainargs(int *, char ***, char ***, int, int *); +#ifdef __REACTOS__ +_CRTIMP void __cdecl __getmainargs(int *, char ***, char ***, int, int *); +_CRTIMP void __cdecl __wgetmainargs(int *, wchar_t ***, wchar_t ***, int, int *); +#endif + static int* (__cdecl *p___p___argc)(void); static char*** (__cdecl *p___p___argv)(void); @@ -92,12 +96,12 @@ static void test_initvar( HMODULE hmsvcrt ) winminor = *pp_winminor; winmajor = *pp_winmajor; GetVersionExA( &osvi); - ok( winminor == osvi.dwMinorVersion, "Wrong value for _winminor %02x expected %02x\n", + ok( winminor == osvi.dwMinorVersion, "Wrong value for _winminor %02x expected %02lx\n", winminor, osvi.dwMinorVersion); - ok( winmajor == osvi.dwMajorVersion, "Wrong value for _winmajor %02x expected %02x\n", + ok( winmajor == osvi.dwMajorVersion, "Wrong value for _winmajor %02x expected %02lx\n", winmajor, osvi.dwMajorVersion); ok( winver == ((osvi.dwMajorVersion << 8) | osvi.dwMinorVersion), - "Wrong value for _winver %02x expected %02x\n", + "Wrong value for _winver %02x expected %02lx\n", winver, ((osvi.dwMajorVersion << 8) | osvi.dwMinorVersion)); if( !pp_osver || !pp_osplatform ) { win_skip("_osver variables are not available\n"); @@ -108,10 +112,10 @@ static void test_initvar( HMODULE hmsvcrt ) ok( osver == (osvi.dwBuildNumber & 0xffff) || ((osvi.dwBuildNumber >> 24) == osvi.dwMajorVersion && ((osvi.dwBuildNumber >> 16) & 0xff) == osvi.dwMinorVersion), /* 95/98/ME */ - "Wrong value for _osver %04x expected %04x\n", + "Wrong value for _osver %04x expected %04lx\n", osver, osvi.dwBuildNumber); ok(osplatform == osvi.dwPlatformId, - "Wrong value for _osplatform %x expected %x\n", + "Wrong value for _osplatform %x expected %lx\n", osplatform, osvi.dwPlatformId); } @@ -133,7 +137,7 @@ static void test___getmainargs(void) { int argc, new_argc, mode; char **argv, **new_argv, **envp; - char tmppath[MAX_PATH], filepath[MAX_PATH]; + char tmppath[MAX_PATH], filepath[MAX_PATH + 14]; FILE *f; ok(GetTempPathA(MAX_PATH, tmppath) != 0, "GetTempPath failed\n"); @@ -194,7 +198,7 @@ static void test___getmainargs(void) static void test___getmainargs_parent(char *name) { char cmdline[3*MAX_PATH]; - char tmppath[MAX_PATH], filepath[MAX_PATH]; + char tmppath[MAX_PATH], filepath[MAX_PATH + 14]; STARTUPINFOA startup; PROCESS_INFORMATION proc; FILE *f; @@ -218,7 +222,7 @@ static void test___getmainargs_parent(char *name) memset(&startup, 0, sizeof(startup)); startup.cb = sizeof(startup); CreateProcessA(NULL, cmdline, NULL, NULL, TRUE, CREATE_DEFAULT_ERROR_MODE|NORMAL_PRIORITY_CLASS, NULL, NULL, &startup, &proc); - winetest_wait_child_process(proc.hProcess); + wait_child_process(proc.hProcess); _unlink(filepath); sprintf(filepath, "%swine_test\\a", tmppath); diff --git a/modules/rostests/winetests/msvcrt/dir.c b/modules/rostests/winetests/msvcrt/dir.c index 210cf3983cdc6..a2a704d85d3ef 100644 --- a/modules/rostests/winetests/msvcrt/dir.c +++ b/modules/rostests/winetests/msvcrt/dir.c @@ -138,36 +138,6 @@ static void test_makepath(void) } } -static const WCHAR expected0[] = {'\0','X','X','X','X','X','X','X','X','X','X','X','X'}; -static const WCHAR expected1[] = {'\0','X','X','X','X','X','X','X','X','X','X','X','X'}; -static const WCHAR expected2[] = {'\0',':','X','X','X','X','X','X','X','X','X','X','X'}; -static const WCHAR expected3[] = {'\0',':','d','X','X','X','X','X','X','X','X','X','X'}; -static const WCHAR expected4[] = {'\0',':','d','\\','X','X','X','X','X','X','X','X','X'}; -static const WCHAR expected5[] = {'\0',':','d','\\','f','X','X','X','X','X','X','X','X'}; -static const WCHAR expected6[] = {'\0',':','d','\\','f','i','X','X','X','X','X','X','X'}; -static const WCHAR expected7[] = {'\0',':','d','\\','f','i','l','X','X','X','X','X','X'}; -static const WCHAR expected8[] = {'\0',':','d','\\','f','i','l','e','X','X','X','X','X'}; -static const WCHAR expected9[] = {'\0',':','d','\\','f','i','l','e','.','X','X','X','X'}; -static const WCHAR expected10[] = {'\0',':','d','\\','f','i','l','e','.','e','X','X','X'}; -static const WCHAR expected11[] = {'\0',':','d','\\','f','i','l','e','.','e','x','X','X'}; - -static const WCHAR expected12[] = {'\0',':','X','X','X','X','X','X','X','X'}; -static const WCHAR expected13[] = {'\0',':','d','X','X','X','X','X','X','X'}; -static const WCHAR expected14[] = {'\0',':','d','i','X','X','X','X','X','X'}; -static const WCHAR expected15[] = {'\0',':','d','i','r','X','X','X','X','X'}; -static const WCHAR expected16[] = {'\0',':','d','i','r','\\','X','X','X','X'}; - -static const WCHAR expected17[] = {'\0','o','o'}; -static const WCHAR expected18[] = {'\0','o','o','\0','X'}; -static const WCHAR expected19[] = {'\0','o','o','\0'}; -static const WCHAR expected20[] = {'\0','o','o','\0','X','X','X','X','X'}; -static const WCHAR expected21[] = {'\0','o','o','\\','f','i','l','X','X'}; -static const WCHAR expected22[] = {'\0','o','o','\0','X','X','X','X','X','X','X','X','X'}; -static const WCHAR expected23[] = {'\0','o','o','\\','f','i','l','X','X','X','X','X','X'}; -static const WCHAR expected24[] = {'\0','o','o','\\','f','i','l','e','.','e','x','X','X'}; -static const WCHAR expected25[] = {'\0','o','o','\0','X','X','X','X'}; -static const WCHAR expected26[] = {'\0','o','o','.','e','x','X','X'}; - typedef struct { const char* buffer; @@ -184,35 +154,35 @@ typedef struct static const makepath_s_case makepath_s_cases[] = { /* Behavior with directory parameter containing backslash. */ - {NULL, 1, "c:", "d\\", "file", "ext", "\0XXXXXXXXXXXX", expected0, 13}, - {NULL, 2, "c:", "d\\", "file", "ext", "\0XXXXXXXXXXXX", expected1, 13}, - {NULL, 3, "c:", "d\\", "file", "ext", "\0:XXXXXXXXXXX", expected2, 13}, - {NULL, 4, "c:", "d\\", "file", "ext", "\0:dXXXXXXXXXX", expected3, 13}, - {NULL, 5, "c:", "d\\", "file", "ext", "\0:d\\XXXXXXXXX", expected4, 13}, - {NULL, 6, "c:", "d\\", "file", "ext", "\0:d\\fXXXXXXXX", expected5, 13}, - {NULL, 7, "c:", "d\\", "file", "ext", "\0:d\\fiXXXXXXX", expected6, 13}, - {NULL, 8, "c:", "d\\", "file", "ext", "\0:d\\filXXXXXX", expected7, 13}, - {NULL, 9, "c:", "d\\", "file", "ext", "\0:d\\fileXXXXX", expected8, 13}, - {NULL, 10, "c:", "d\\", "file", "ext", "\0:d\\file.XXXX", expected9, 13}, - {NULL, 11, "c:", "d\\", "file", "ext", "\0:d\\file.eXXX", expected10, 13}, - {NULL, 12, "c:", "d\\", "file", "ext", "\0:d\\file.exXX", expected11, 13}, + {NULL, 1, "c:", "d\\", "file", "ext", "\0XXXXXXXXXXXX", L"\0XXXXXXXXXXXX", 13}, + {NULL, 2, "c:", "d\\", "file", "ext", "\0XXXXXXXXXXXX", L"\0XXXXXXXXXXXX", 13}, + {NULL, 3, "c:", "d\\", "file", "ext", "\0:XXXXXXXXXXX", L"\0:XXXXXXXXXXX", 13}, + {NULL, 4, "c:", "d\\", "file", "ext", "\0:dXXXXXXXXXX", L"\0:dXXXXXXXXXX", 13}, + {NULL, 5, "c:", "d\\", "file", "ext", "\0:d\\XXXXXXXXX", L"\0:d\\XXXXXXXXX", 13}, + {NULL, 6, "c:", "d\\", "file", "ext", "\0:d\\fXXXXXXXX", L"\0:d\\fXXXXXXXX", 13}, + {NULL, 7, "c:", "d\\", "file", "ext", "\0:d\\fiXXXXXXX", L"\0:d\\fiXXXXXXX", 13}, + {NULL, 8, "c:", "d\\", "file", "ext", "\0:d\\filXXXXXX", L"\0:d\\filXXXXXX", 13}, + {NULL, 9, "c:", "d\\", "file", "ext", "\0:d\\fileXXXXX", L"\0:d\\fileXXXXX", 13}, + {NULL, 10, "c:", "d\\", "file", "ext", "\0:d\\file.XXXX", L"\0:d\\file.XXXX", 13}, + {NULL, 11, "c:", "d\\", "file", "ext", "\0:d\\file.eXXX", L"\0:d\\file.eXXX", 13}, + {NULL, 12, "c:", "d\\", "file", "ext", "\0:d\\file.exXX", L"\0:d\\file.exXX", 13}, /* Behavior with directory parameter lacking backslash. */ - {NULL, 3, "c:", "dir", "f", "ext", "\0:XXXXXXXX", expected12, 10}, - {NULL, 4, "c:", "dir", "f", "ext", "\0:dXXXXXXX", expected13, 10}, - {NULL, 5, "c:", "dir", "f", "ext", "\0:diXXXXXX", expected14, 10}, - {NULL, 6, "c:", "dir", "f", "ext", "\0:dirXXXXX", expected15, 10}, - {NULL, 7, "c:", "dir", "f", "ext", "\0:dir\\XXXX", expected16, 10}, + {NULL, 3, "c:", "dir", "f", "ext", "\0:XXXXXXXX", L"\0:XXXXXXXX", 10}, + {NULL, 4, "c:", "dir", "f", "ext", "\0:dXXXXXXX", L"\0:dXXXXXXX", 10}, + {NULL, 5, "c:", "dir", "f", "ext", "\0:diXXXXXX", L"\0:diXXXXXX", 10}, + {NULL, 6, "c:", "dir", "f", "ext", "\0:dirXXXXX", L"\0:dirXXXXX", 10}, + {NULL, 7, "c:", "dir", "f", "ext", "\0:dir\\XXXX", L"\0:dir\\XXXX", 10}, /* Behavior with overlapped buffer. */ - {"foo", 2, USE_BUFF, NULL, NULL, NULL, "\0oo", expected17, 3}, - {"foo", 4, NULL, USE_BUFF, NULL, NULL, "\0oo\0X", expected18, 5}, - {"foo", 3, NULL, NULL, USE_BUFF, NULL, "\0oo\0", expected19, 4}, - {"foo", 4, NULL, USE_BUFF, "file", NULL, "\0oo\0XXXXX", expected20, 9}, - {"foo", 8, NULL, USE_BUFF, "file", NULL, "\0oo\\filXX", expected21, 9}, - {"foo", 4, NULL, USE_BUFF, "file", "ext", "\0oo\0XXXXXXXXX", expected22, 13}, - {"foo", 8, NULL, USE_BUFF, "file", "ext", "\0oo\\filXXXXXX", expected23, 13}, - {"foo", 12, NULL, USE_BUFF, "file", "ext", "\0oo\\file.exXX", expected24, 13}, - {"foo", 4, NULL, NULL, USE_BUFF, "ext", "\0oo\0XXXX", expected25, 8}, - {"foo", 7, NULL, NULL, USE_BUFF, "ext", "\0oo.exXX", expected26, 8}, + {"foo", 2, USE_BUFF, NULL, NULL, NULL, "\0oo", L"\0oo", 3}, + {"foo", 4, NULL, USE_BUFF, NULL, NULL, "\0oo\0X", L"\0oo\0X", 5}, + {"foo", 3, NULL, NULL, USE_BUFF, NULL, "\0oo\0", L"\0oo", 4}, + {"foo", 4, NULL, USE_BUFF, "file", NULL, "\0oo\0XXXXX", L"\0oo\0XXXXX", 9}, + {"foo", 8, NULL, USE_BUFF, "file", NULL, "\0oo\\filXX", L"\0oo\\filXX", 9}, + {"foo", 4, NULL, USE_BUFF, "file", "ext", "\0oo\0XXXXXXXXX", L"\0oo\0XXXXXXXXX", 13}, + {"foo", 8, NULL, USE_BUFF, "file", "ext", "\0oo\\filXXXXXX", L"\0oo\\filXXXXXX", 13}, + {"foo", 12, NULL, USE_BUFF, "file", "ext", "\0oo\\file.exXX", L"\0oo\\file.exXX", 13}, + {"foo", 4, NULL, NULL, USE_BUFF, "ext", "\0oo\0XXXX", L"\0oo\0XXXX", 8}, + {"foo", 7, NULL, NULL, USE_BUFF, "ext", "\0oo.exXX", L"\0oo.exXX", 8}, }; static void test_makepath_s(void) @@ -438,10 +408,6 @@ static void test_searchenv(void) "\\search_env_test\\dir3longer\\3.dat" }; - const WCHAR env_w[] = {'T','E','S','T','_','P','A','T','H',0}; - const WCHAR dat1_w[] = {'1','.','d','a','t',0}; - const WCHAR dat3_w[] = {'3','.','d','a','t',0}; - char env1[4*MAX_PATH], env2[4*MAX_PATH], tmppath[MAX_PATH], path[2*MAX_PATH]; char result[MAX_PATH], exp[2*MAX_PATH]; WCHAR result_w[MAX_PATH]; @@ -510,13 +476,13 @@ static void test_searchenv(void) } memset(result_w, 'x', sizeof(result_w)); - _wsearchenv(dat1_w, env_w, result_w); + _wsearchenv(L"1.dat", L"TEST_PATH", result_w); WideCharToMultiByte(CP_ACP, 0, result_w, -1, result, MAX_PATH, NULL, NULL); ok(!strcmp(result, exp), "got %s, expected '%s'\n", result, exp); if (p_wsearchenv_s) { memset(result_w, 'x', sizeof(result_w)); - i = p_wsearchenv_s(dat1_w, env_w, result_w, MAX_PATH); + i = p_wsearchenv_s(L"1.dat", L"TEST_PATH", result_w, MAX_PATH); ok(!i, "wsearchenv_s returned %d\n", i); ok(!strcmp(result, exp), "got %s, expected '%s'\n", result, exp); } @@ -535,13 +501,13 @@ static void test_searchenv(void) } memset(result_w, 'x', sizeof(result_w)); - _wsearchenv(dat3_w, env_w, result_w); + _wsearchenv(L"3.dat", L"TEST_PATH", result_w); WideCharToMultiByte(CP_ACP, 0, result_w, -1, result, MAX_PATH, NULL, NULL); ok(!strcmp(result, exp), "got %s, expected '%s'\n", result, exp); if (p_wsearchenv_s) { memset(result_w, 'x', sizeof(result_w)); - i = p_wsearchenv_s(dat3_w, env_w, result_w, MAX_PATH); + i = p_wsearchenv_s(L"3.dat", L"TEST_PATH", result_w, MAX_PATH); ok(!i, "wsearchenv_s returned %d\n", i); ok(!strcmp(result, exp), "got %s, expected '%s'\n", result, exp); } @@ -561,13 +527,13 @@ static void test_searchenv(void) } memset(result_w, 'x', sizeof(result_w)); - _wsearchenv(dat1_w, env_w, result_w); + _wsearchenv(L"1.dat", L"TEST_PATH", result_w); WideCharToMultiByte(CP_ACP, 0, result_w, -1, result, MAX_PATH, NULL, NULL); ok(!strcmp(result, exp), "got %s, expected '%s'\n", result, exp); if (p_wsearchenv_s) { memset(result_w, 'x', sizeof(result_w)); - i = p_wsearchenv_s(dat1_w, env_w, result_w, MAX_PATH); + i = p_wsearchenv_s(L"1.dat", L"TEST_PATH", result_w, MAX_PATH); ok(!i, "wsearchenv_s returned %d\n", i); ok(!strcmp(result, exp), "got %s, expected '%s'\n", result, exp); } @@ -586,17 +552,31 @@ static void test_searchenv(void) } memset(result_w, 'x', sizeof(result_w)); - _wsearchenv(dat3_w, env_w, result_w); + _wsearchenv(L"3.dat", L"TEST_PATH", result_w); WideCharToMultiByte(CP_ACP, 0, result_w, -1, result, MAX_PATH, NULL, NULL); ok(!strcmp(result, exp), "got %s, expected '%s'\n", result, exp); if (p_wsearchenv_s) { memset(result_w, 'x', sizeof(result_w)); - i = p_wsearchenv_s(dat3_w, env_w, result_w, MAX_PATH); + i = p_wsearchenv_s(L"3.dat", L"TEST_PATH", result_w, MAX_PATH); ok(!i, "wsearchenv_s returned %d\n", i); ok(!strcmp(result, exp), "got %s, expected '%s'\n", result, exp); } + strcpy(env1, "TEST_PATH="); + strcat(env1, tmppath); + strcat(env1, "\"\\search_env_test\\\"d\"i\"r\"1"); + putenv(env1); + strcpy(exp, tmppath); + strcat(exp, files[0]); + _searchenv("1.dat", "TEST_PATH", result); + ok(!strcmp(result, exp), "got %s, expected '%s'\n", result, exp); + + strcat(env1, ";"); + putenv(env1); + _searchenv("1.dat", "TEST_PATH", result); + ok(!result[0], "got %s, expected ''\n", result); + putenv("TEST_PATH="); for (i=ARRAY_SIZE(files)-1; i>=0; i--) { diff --git a/modules/rostests/winetests/msvcrt/environ.c b/modules/rostests/winetests/msvcrt/environ.c index b8e0ae6251a2f..4b6f5bc22b413 100644 --- a/modules/rostests/winetests/msvcrt/environ.c +++ b/modules/rostests/winetests/msvcrt/environ.c @@ -19,7 +19,15 @@ */ #include "wine/test.h" +#include #include +#include +#include + +#ifdef __REACTOS__ +_CRTIMP void __cdecl __getmainargs(int *, char ***, char ***, int, int *); +_CRTIMP void __cdecl __wgetmainargs(int *, wchar_t ***, wchar_t ***, int, int *); +#endif static const char *a_very_long_env_string = "LIBRARY_PATH=" @@ -42,13 +50,15 @@ static const char *a_very_long_env_string = "/usr/lib/mingw32/3.4.2/;" "/usr/lib/"; -void __cdecl __getmainargs(int *, char ***, char ***, int, int *); -void __cdecl __wgetmainargs(int *, wchar_t ***, wchar_t ***, int, int *); - static char ***(__cdecl *p__p__environ)(void); static WCHAR ***(__cdecl *p__p__wenviron)(void); -static void (*p_get_environ)(char ***); -static void (*p_get_wenviron)(WCHAR ***); +static char ***(__cdecl *p__p___initenv)(void); +static wchar_t ***(__cdecl *p__p___winitenv)(void); +static void (__cdecl *p_get_environ)(char ***); +static void (__cdecl *p_get_wenviron)(WCHAR ***); +static errno_t (__cdecl *p_putenv_s)(const char*, const char*); +static errno_t (__cdecl *p_wputenv_s)(const wchar_t*, const wchar_t*); +static errno_t (__cdecl *p_getenv_s)(size_t*, char*, size_t, const char*); static char ***p_environ; static WCHAR ***p_wenviron; @@ -59,10 +69,15 @@ static void init(void) p__p__environ = (void *)GetProcAddress(hmod, "__p__environ"); p__p__wenviron = (void *)GetProcAddress(hmod, "__p__wenviron"); + p__p___initenv = (void *)GetProcAddress(hmod, "__p___initenv"); + p__p___winitenv = (void *)GetProcAddress(hmod, "__p___winitenv"); p_environ = (void *)GetProcAddress(hmod, "_environ"); p_wenviron = (void *)GetProcAddress(hmod, "_wenviron"); p_get_environ = (void *)GetProcAddress(hmod, "_get_environ"); p_get_wenviron = (void *)GetProcAddress(hmod, "_get_wenviron"); + p_putenv_s = (void *)GetProcAddress(hmod, "_putenv_s"); + p_wputenv_s = (void *)GetProcAddress(hmod, "_wputenv_s"); + p_getenv_s = (void *)GetProcAddress(hmod, "getenv_s"); } static void test_system(void) @@ -74,30 +89,46 @@ static void test_system(void) ok(ret == 0, "Expected system to return 0, got %d\n", ret); } -static void test__environ(void) +static unsigned env_get_entry_countA( char **env ) { - int argc; - char **argv, **envp = NULL; - int i, mode = 0; + unsigned count; - ok( p_environ != NULL, "Expected the pointer to _environ to be non-NULL\n" ); - if (p_environ) - ok( *p_environ != NULL, "Expected _environ to be initialized on startup\n" ); + if (!env) return 0; + for (count = 0; env[count] != NULL; count++) {} + return count; +} - if (!p_environ || !*p_environ) - { - skip( "_environ pointers are not valid\n" ); - return; - } +static wchar_t *env_get_valueW( wchar_t **envp, const wchar_t *var ) +{ + unsigned i; + size_t len = wcslen( var ); - /* Examine the returned pointer from __p__environ(), if available. */ - if (p__p__environ) + if (!envp) return NULL; + for (i = 0; envp[i] != NULL; i++) { - ok( *p__p__environ() == *p_environ, - "Expected _environ pointers to be identical\n" ); + wchar_t *ptr; + + if (!(ptr = wcschr( envp[i], L'=' ))) continue; + + if (ptr - envp[i] == len && !memcmp( envp[i], var, len * sizeof(wchar_t) )) + return ptr + 1; } + return NULL; +} + +static void test__environ(void) +{ + int argc; + char **argv, **envp = NULL, **initenv = NULL; + int mode = 0; + + ok( p_environ != NULL, "Expected the pointer to _environ to be non-NULL\n" ); + ok( *p_environ != NULL, "Expected _environ to be initialized on startup\n" ); + + if (sizeof(void*) != sizeof(int)) + ok( !p__p__environ, "__p__environ() should be 32-bit only\n"); else - skip( "__p__environ() is not available\n" ); + ok( *p__p__environ() == *p_environ, "Expected _environ pointers to be identical\n" ); if (p_get_environ) { @@ -109,76 +140,74 @@ static void test__environ(void) else win_skip( "_get_environ() is not available\n" ); + if (p__p___initenv) + { + initenv = *p__p___initenv(); + + ok( initenv == *p_environ, + "Expected _environ to be equal to initial env\n" ); + } + else + skip( "__p___initenv() is not available\n" ); + /* Note that msvcrt from Windows versions older than Vista * expects the mode pointer parameter to be valid.*/ __getmainargs(&argc, &argv, &envp, 0, &mode); - ok( envp != NULL, "Expected initial environment block pointer to be non-NULL\n" ); - if (!envp) - { - skip( "Initial environment block pointer is not valid\n" ); - return; - } + ok( envp != NULL, + "Expected initial environment block pointer to be non-NULL\n" ); + ok( envp == *p_environ, + "Expected initial environment to be equal to _environ\n" ); - for (i = 0; ; i++) + ok( _putenv("cat=dog") == 0, "failed setting cat=dog\n" ); + if (p__p___initenv) { - if ((*p_environ)[i]) - { - ok( envp[i] != NULL, "Expected environment block pointer element to be non-NULL\n" ); - ok( !strcmp((*p_environ)[i], envp[i]), - "Expected _environ and environment block pointer strings (%s vs. %s) to match\n", - (*p_environ)[i], envp[i] ); - } - else - { - ok( !envp[i], "Expected environment block pointer element to be NULL, got %p\n", envp[i] ); - break; - } + char **retptr = *p__p___initenv(); + + ok( retptr != *p_environ, + "Expected _environ[] not to be equal to initial env\n" ); + ok( retptr == initenv, + "Unexpected modification of initial env\n" ); } + ok( _putenv("cat=") == 0, "failed setting cat=\n" ); } static void test__wenviron(void) { - static const WCHAR cat_eq_dogW[] = {'c','a','t','=','d','o','g',0}; - static const WCHAR cat_eqW[] = {'c','a','t','=',0}; - int argc; char **argv, **envp = NULL; WCHAR **wargv, **wenvp = NULL; - int i, mode = 0; + int mode = 0; ok( p_wenviron != NULL, "Expected the pointer to _wenviron to be non-NULL\n" ); - if (p_wenviron) - ok( *p_wenviron == NULL, "Expected _wenviron to be NULL, got %p\n", *p_wenviron ); - else - { - win_skip( "Pointer to _wenviron is not valid\n" ); - return; - } + ok( !*p_wenviron, "Expected _wenviron[] to be NULL, got %p\n", *p_wenviron ); - /* Examine the returned pointer from __p__wenviron(), if available. */ - if (p__p__wenviron) - { - ok( *p__p__wenviron() == NULL, - "Expected _wenviron pointers to be NULL\n" ); - } + if (sizeof(void*) != sizeof(int)) + ok( !p__p__wenviron, "__p__wenviron() should be 32-bit only\n"); else - skip( "__p__wenviron() is not available\n" ); + ok( !*p__p__wenviron(), "Expected _wenviron to be NULL, got %p\n", *p_wenviron ); if (p_get_wenviron) { WCHAR **retptr; p_get_wenviron(&retptr); - ok( retptr == NULL, - "Expected _wenviron pointers to be NULL\n" ); + ok( retptr == *p_wenviron, "Expected _wenviron pointers to be NULL\n" ); } else win_skip( "_get_wenviron() is not available\n" ); + if (p__p___winitenv) + { + wchar_t ***retptr = p__p___winitenv(); + ok( !*retptr, "Expected initial env to be NULL\n" ); + } + else + skip( "__p___winitenv() is not available\n" ); + /* __getmainargs doesn't initialize _wenviron. */ __getmainargs(&argc, &argv, &envp, 0, &mode); - ok( *p_wenviron == NULL, "Expected _wenviron to be NULL, got %p\n", *p_wenviron); + ok( !*p_wenviron, "Expected _wenviron to be NULL\n"); ok( envp != NULL, "Expected initial environment block pointer to be non-NULL\n" ); if (!envp) { @@ -188,24 +217,31 @@ static void test__wenviron(void) /* Neither does calling the non-Unicode environment manipulation functions. */ ok( _putenv("cat=dog") == 0, "failed setting cat=dog\n" ); - ok( *p_wenviron == NULL, "Expected _wenviron to be NULL, got %p\n", *p_wenviron); - ok( _putenv("cat=") == 0, "failed deleting cat\n" ); + ok( !*p_wenviron, "Expected _wenviron to be NULL\n" ); /* _wenviron isn't initialized until __wgetmainargs is called or * one of the Unicode environment manipulation functions is called. */ - ok( _wputenv(cat_eq_dogW) == 0, "failed setting cat=dog\n" ); + ok( _wputenv(L"cat=dog2") == 0, "failed setting cat=dog2\n" ); ok( *p_wenviron != NULL, "Expected _wenviron to be non-NULL\n" ); - ok( _wputenv(cat_eqW) == 0, "failed deleting cat\n" ); __wgetmainargs(&argc, &wargv, &wenvp, 0, &mode); - - ok( *p_wenviron != NULL, "Expected _wenviron to be non-NULL\n" ); ok( wenvp != NULL, "Expected initial environment block pointer to be non-NULL\n" ); - if (!wenvp) + ok( wenvp == *p_wenviron, "Expected initial environment to be _wenviron[]\n" ); + + if (p__p___winitenv) { - skip( "Initial environment block pointer is not valid\n" ); - return; + wchar_t ***retptr = p__p___winitenv(); + wchar_t *value; + + skip_2k3_fail ok( *retptr != NULL, "Expected *__p___winitenv() to be NULL\n" ); + ok( *retptr != *p_wenviron, + "Expected _wenviron to be different from __p___winitenv() %p %p\n", *retptr, *p_wenviron ); + /* test that w-initial env is derived from current _environ[] and not from ansi initial env */ + value = env_get_valueW( *retptr, L"cat" ); + skip_2k3_fail ok( value && !wcscmp( value, L"dog" ), + "Expecting initial env to be derived from current env (got %ls)\n", value ); } + _putenv("cat="); /* Examine the returned pointer from __p__wenviron(), * if available, after _wenviron is initialized. */ @@ -222,29 +258,27 @@ static void test__wenviron(void) ok( retptr == *p_wenviron, "Expected _wenviron pointers to be identical\n" ); } - - for (i = 0; ; i++) - { - if ((*p_wenviron)[i]) - { - ok( wenvp[i] != NULL, "Expected environment block pointer element to be non-NULL\n" ); - ok( !winetest_strcmpW((*p_wenviron)[i], wenvp[i]), - "Expected _wenviron and environment block pointer strings (%s vs. %s) to match\n", - wine_dbgstr_w((*p_wenviron)[i]), wine_dbgstr_w(wenvp[i]) ); - } - else - { - ok( !wenvp[i], "Expected environment block pointer element to be NULL, got %p\n", wenvp[i] ); - break; - } - } } static void test_environment_manipulation(void) { + char buf[256]; + errno_t ret; + size_t len; + unsigned count; + char* first; + char* second; + ok( _putenv("cat=") == 0, "_putenv failed on deletion of nonexistent environment variable\n" ); ok( _putenv("cat=dog") == 0, "failed setting cat=dog\n" ); ok( strcmp(getenv("cat"), "dog") == 0, "getenv did not return 'dog'\n" ); + if (p_getenv_s) + { + ret = p_getenv_s(&len, buf, sizeof(buf), "cat"); + ok( !ret, "getenv_s returned %d\n", ret ); + ok( len == 4, "getenv_s returned length is %Id\n", len); + ok( !strcmp(buf, "dog"), "getenv_s did not return 'dog'\n"); + } ok( _putenv("cat=") == 0, "failed deleting cat\n" ); ok( _putenv("=") == -1, "should not accept '=' as input\n" ); @@ -252,16 +286,190 @@ static void test_environment_manipulation(void) ok( _putenv(a_very_long_env_string) == 0, "_putenv failed for long environment string\n"); ok( getenv("nonexistent") == NULL, "getenv should fail with nonexistent var name\n" ); + + if (p_putenv_s) + { + ret = p_putenv_s(NULL, "dog"); + ok( ret == EINVAL, "_putenv_s returned %d\n", ret); + ret = p_putenv_s("cat", NULL); + ok( ret == EINVAL, "_putenv_s returned %d\n", ret); + ret = p_putenv_s("a=b", NULL); + ok( ret == EINVAL, "_putenv_s returned %d\n", ret); + ret = p_putenv_s("cat", "a=b"); + ok( !ret, "_putenv_s returned %d\n", ret); + ret = p_putenv_s("cat", ""); + ok( !ret, "_putenv_s returned %d\n", ret); + } + + if (p_wputenv_s) + { + ret = p_wputenv_s(NULL, L"dog"); + ok( ret == EINVAL, "_wputenv_s returned %d\n", ret); + ret = p_wputenv_s(L"cat", NULL); + ok( ret == EINVAL, "_wputenv_s returned %d\n", ret); + ret = p_wputenv_s(L"a=b", NULL); + ok( ret == EINVAL, "_wputenv_s returned %d\n", ret); + ret = p_wputenv_s(L"cat", L"a=b"); + ok( !ret, "_wputenv_s returned %d\n", ret); + ret = p_wputenv_s(L"cat", L""); + ok( !ret, "_wputenv_s returned %d\n", ret); + } + + if (p_getenv_s) + { + buf[0] = 'x'; + len = 1; + errno = 0xdeadbeef; + ret = p_getenv_s(&len, buf, sizeof(buf), "nonexistent"); + ok( !ret, "_getenv_s returned %d\n", ret); + ok( !len, "getenv_s returned length is %Id\n", len); + ok( !buf[0], "buf = %s\n", buf); + ok( errno == 0xdeadbeef, "errno = %d\n", errno); + + buf[0] = 'x'; + len = 1; + errno = 0xdeadbeef; + ret = p_getenv_s(&len, buf, sizeof(buf), NULL); + ok( !ret, "_getenv_s returned %d\n", ret); + ok( !len, "getenv_s returned length is %Id\n", len); + ok( !buf[0], "buf = %s\n", buf); + ok( errno == 0xdeadbeef, "errno = %d\n", errno); + } + + /* test stability of _environ[] pointers */ + ok( _putenv( "__winetest_cat=" ) == 0, "Couldn't reset env var\n" ); + ok( _putenv( "__winetest_dog=" ) == 0, "Couldn't reset env var\n" ); + count = env_get_entry_countA( *p_environ ); + ok( _putenv( "__winetest_cat=mew") == 0, "Couldn't set env var\n" ); + ok( !strcmp( (*p_environ)[count], "__winetest_cat=mew"), "Unexpected env var value\n" ); + first = (*p_environ)[count]; + ok( getenv("__winetest_cat") == strchr( (*p_environ)[count], '=') + 1, "Expected getenv() to return pointer inside _environ[] entry\n" ); + ok( _putenv( "__winetest_dog=bark" ) == 0, "Couldn't set env var\n" ); + ok( !strcmp( (*p_environ)[count + 1], "__winetest_dog=bark" ), "Unexpected env var value\n" ); + ok( getenv( "__winetest_dog" ) == strchr( (*p_environ)[count + 1], '=' ) + 1, "Expected getenv() to return pointer inside _environ[] entry\n" ); + ok( first == (*p_environ)[count], "Expected stability of _environ[count] pointer\n" ); + second = (*p_environ)[count + 1]; + ok( count + 2 == env_get_entry_countA( *p_environ ), "Unexpected count\n" ); + + ok( _putenv( "__winetest_cat=purr" ) == 0, "Couldn't set env var\n" ); + ok( !strcmp( (*p_environ)[count], "__winetest_cat=purr" ), "Unexpected env var value\n" ); + ok( getenv( "__winetest_cat" ) == strchr( (*p_environ)[count], '=' ) + 1, "Expected getenv() to return pointer inside _environ[] entry\n" ); + ok( second == (*p_environ)[count + 1], "Expected stability of _environ[count] pointer\n" ); + ok( !strcmp( (*p_environ)[count + 1], "__winetest_dog=bark" ), "Couldn't get env var value\n" ); + ok( getenv( "__winetest_dog" ) == strchr( (*p_environ)[count + 1], '=' ) + 1, "Expected getenv() to return pointer inside _environ[] entry\n" ); + ok( count + 2 == env_get_entry_countA( *p_environ ), "Unexpected count\n" ); + ok( _putenv( "__winetest_cat=" ) == 0, "Couldn't reset env vat\n" ); + ok( second == (*p_environ)[count], "Expected _environ[count] to be second\n" ); + ok( !strcmp( (*p_environ)[count], "__winetest_dog=bark" ), "Unexpected env var value\n" ); + ok( count + 1 == env_get_entry_countA( *p_environ ), "Unexpected count\n" ); + ok( _putenv( "__winetest_dog=" ) == 0, "Couldn't reset env var\n" ); + ok( count == env_get_entry_countA( *p_environ ), "Unexpected count\n" ); + + /* in putenv, only changed variable is updated (no other reload of kernel info is done) */ + ret = SetEnvironmentVariableA( "__winetest_cat", "meow" ); + ok( ret, "SetEnvironmentVariableA failed: %lu\n", GetLastError() ); + ok( _putenv( "__winetest_dog=bark" ) == 0, "Couldn't set env var\n" ); + ok( getenv( "__winetest_cat" ) == NULL, "msvcrt env cache shouldn't have been updated\n" ); + ok( _putenv( "__winetest_cat=" ) == 0, "Couldn't reset env var\n" ); + ok( _putenv( "__winetest_dog=" ) == 0, "Couldn't reset env var\n" ); + + /* test setting unicode bits */ + count = env_get_entry_countA( *p_environ ); + ret = WideCharToMultiByte( CP_ACP, 0, L"\u263a", -1, buf, ARRAY_SIZE(buf), 0, 0 ); + ok( ret, "WideCharToMultiByte failed: %lu\n", GetLastError() ); + ok( _wputenv( L"__winetest_cat=\u263a" ) == 0, "Couldn't set env var\n" ); + ok( _wgetenv( L"__winetest_cat" ) && !wcscmp( _wgetenv( L"__winetest_cat" ), L"\u263a" ), "Couldn't retrieve env var\n" ); + ok( getenv( "__winetest_cat" ) && !strcmp( getenv( "__winetest_cat" ), buf ), "Couldn't retrieve env var\n" ); + ok( _wputenv( L"__winetest_cat=" ) == 0, "Couldn't reset env var\n" ); + + ret = WideCharToMultiByte( CP_ACP, 0, L"__winetest_\u263a", -1, buf, ARRAY_SIZE(buf), 0, 0 ); + ok( ret, "WideCharToMultiByte failed: %lu\n", GetLastError() ); + ok( _wputenv( L"__winetest_\u263a=bark" ) == 0, "Couldn't set env var\n" ); + ok( _wgetenv( L"__winetest_\u263a" ) && !wcscmp( _wgetenv( L"__winetest_\u263a" ), L"bark"), "Couldn't retrieve env var\n" ); + ok( getenv( buf ) && !strcmp( getenv( buf ), "bark"), "Couldn't retrieve env var %s\n", wine_dbgstr_a(buf) ); + ok( _wputenv( L"__winetest_\u263a=" ) == 0, "Couldn't reset env var\n" ); + ok( count == env_get_entry_countA( *p_environ ), "Unexpected modification of _environ[]\n" ); +} + +static void test_child_env(char** argv) +{ + STARTUPINFOA si = {sizeof(si)}; + WCHAR *cur_env, *env, *p, *q; + PROCESS_INFORMATION pi; + char tmp[1024]; + BOOL ret; + int len; + + cur_env = GetEnvironmentStringsW(); + ok( cur_env != NULL, "GetEnvironemntStrings failed\n" ); + + p = cur_env; + while (*p) p += wcslen( p ) + 1; + len = p - cur_env; + env = malloc( (len + 1024) * sizeof(*env) ); + memcpy(env, cur_env, len * sizeof(*env) ); + q = env + len; + FreeEnvironmentStringsW( cur_env ); + + wcscpy( q, L"__winetest_dog=bark" ); + q += wcslen( L"__winetest_dog=bark" ) + 1; + wcscpy( q, L"__winetest_\u263a=\u03b2" ); + q += wcslen( L"__winetest_\u263a=\u03b2" ) + 1; + *q = 0; + + snprintf( tmp, sizeof(tmp), "%s %s create", argv[0], argv[1] ); + ret = CreateProcessA( NULL, tmp, NULL, NULL, FALSE, CREATE_UNICODE_ENVIRONMENT, env, NULL, &si, &pi ); + ok( ret, "Couldn't create child process %s\n", tmp ); + winetest_wait_child_process( pi.hProcess ); + CloseHandle( pi.hProcess ); + CloseHandle( pi.hThread ); + free( env ); +} + +static void test_case_insensitive(void) +{ + const char *uppercase_env = getenv("APPDATA"); + const char *lowercase_env = getenv("appdata"); + const wchar_t *uppercase_wenv = _wgetenv(L"APPDATA"); + const wchar_t *lowercase_wenv = _wgetenv(L"appdata"); + + ok( uppercase_env == lowercase_env, "getenv() must be case insensitive, %p should be %p\n", + lowercase_env, uppercase_env ); + ok( uppercase_wenv == lowercase_wenv, "_wgetenv() must be case insensitive, %p should be %p\n", + lowercase_wenv, uppercase_wenv ); + + ok( !_putenv("cAt=bar"), "Failed to set CAT=bar\n" ); + ok( !_putenv("CAT=BAR"), "Failed to set CAT=BAR\n" ); + ok( !strcmp(getenv("cAt"), "BAR"), "_putenv() must be case insensitive\n" ); + + ok( !_wputenv(L"cAt=bar"), "Failed to set CAT=bar\n" ); + ok( !_wputenv(L"CAT=BAR"), "Failed to set CAT=BAR\n" ); + ok( !wcscmp(_wgetenv(L"cAt"), L"BAR"), "_wputenv() must be case insensitive\n" ); + + _putenv("cat="); } START_TEST(environ) { + char **argv; + int argc; + init(); - /* The environ tests should always be run first, as they assume - * that the process has not manipulated the environment. */ + argc = winetest_get_mainargs( &argv ); + if (argc == 3 && !strcmp( argv[2], "create" )) + { + ok( getenv( "__winetest_dog" ) && !strcmp( getenv( "__winetest_dog" ), "bark" ), + "Couldn't find env var\n" ); + skip_2k3_fail ok( _wgetenv( L"__winetest_\u263a" ) && !wcscmp( _wgetenv( L"__winetest_\u263a" ), L"\u03b2" ), + "Couldn't find unicode env var\n" ); + return; + } + test__environ(); test__wenviron(); test_environment_manipulation(); + test_child_env(argv); test_system(); + test_case_insensitive(); } diff --git a/modules/rostests/winetests/msvcrt/file.c b/modules/rostests/winetests/msvcrt/file.c index fe62d5c385ec1..ac02ed5885992 100644 --- a/modules/rostests/winetests/msvcrt/file.c +++ b/modules/rostests/winetests/msvcrt/file.c @@ -35,6 +35,25 @@ #include #include #include +#ifdef __REACTOS__ +#include +#else +#include +#endif + +#define WX_OPEN 0x01 +#define WX_ATEOF 0x02 +#define WX_READNL 0x04 +#define WX_PIPE 0x08 +#define WX_DONTINHERIT 0x10 +#define WX_APPEND 0x20 +#define WX_TTY 0x40 +#define WX_TEXT 0x80 + +#define EF_UTF8 0x01 +#define EF_UTF16 0x02 +#define EF_CRIT_INIT 0x04 +#define EF_UNK_UNICODE 0x08 #define MSVCRT_FD_BLOCK_SIZE 32 typedef struct { @@ -52,6 +71,7 @@ static int (__cdecl *p_fopen_s)(FILE**, const char*, const char*); static int (__cdecl *p__wfopen_s)(FILE**, const wchar_t*, const wchar_t*); static errno_t (__cdecl *p__get_fmode)(int*); static errno_t (__cdecl *p__set_fmode)(int); +static int (__cdecl *p__setmaxstdio)(int); static const char* get_base_name(const char *path) { @@ -76,6 +96,7 @@ static void init(void) __pioinfo = (void*)GetProcAddress(hmod, "__pioinfo"); p__get_fmode = (void*)GetProcAddress(hmod, "_get_fmode"); p__set_fmode = (void*)GetProcAddress(hmod, "_set_fmode"); + p__setmaxstdio = (void*)GetProcAddress(hmod, "_setmaxstdio"); } static void test_filbuf( void ) @@ -211,7 +232,50 @@ static void test_fileops( void ) ok(fread(buffer, sizeof(buffer), 1, file) == 0, "fread test failed\n"); /* feof should be set now */ ok(feof(file), "feof after fread failed\n"); - fclose (file); + clearerr(file); + ok(!feof(file), "feof after clearerr failed\n"); + fclose(file); + + file = fopen("fdopen.tst", "rb"); + ok( file != NULL, "fopen failed\n"); + /* sizeof(buffer) > content of file */ + ok(fread(buffer, sizeof(buffer), 1, file) == 0, "fread test failed\n"); + /* feof should be set now */ + ok(feof(file), "feof after fread failed\n"); + rewind(file); + ok(!feof(file), "feof after rewind failed\n"); + fclose(file); + + file = fopen("fdopen.tst", "rb"); + ok( file != NULL, "fopen failed\n"); + /* sizeof(buffer) > content of file */ + ok(fread(buffer, sizeof(buffer), 1, file) == 0, "fread test failed\n"); + /* feof should be set now */ + ok(feof(file), "feof after fread failed\n"); + fseek(file, 0, SEEK_SET); + ok(!feof(file), "feof after fseek failed\n"); + fclose(file); + + file = fopen("fdopen.tst", "rb"); + ok( file != NULL, "fopen failed\n"); + /* sizeof(buffer) > content of file */ + ok(fread(buffer, sizeof(buffer), 1, file) == 0, "fread test failed\n"); + /* feof should be set now */ + ok(feof(file), "feof after fread failed\n"); + fgetpos(file, &pos); + fsetpos(file, &pos); + ok(!feof(file), "feof after fsetpos failed\n"); + fclose(file); + + file = fopen("fdopen.tst", "rb"); + ok( file != NULL, "fopen failed\n"); + /* sizeof(buffer) > content of file */ + ok(fread(buffer, sizeof(buffer), 1, file) == 0, "fread test failed\n"); + /* feof should be set now */ + ok(feof(file), "feof after fread failed\n"); + fsetpos(file, &pos); + ok(!feof(file), "feof after fsetpos failed\n"); + fclose(file); unlink ("fdopen.tst"); } @@ -233,7 +297,7 @@ static void test_readmode( BOOL ascii_mode ) fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE); /* an internal buffer of BUFSIZ is maintained, so make a file big - * enough to test operations that cross the buffer boundary + * enough to test operations that cross the buffer boundary */ j = (2*BUFSIZ-4)/strlen(padbuffer); for (i=0; i_file; + tempfh->_file = -1; + + ok(tempfh->_ptr - tempfh->_base, "buffer is empty\n"); + ret = fflush(tempfh); + ok(ret == EOF, "expected EOF, got %d\n", ret); + ok(!(tempfh->_ptr - tempfh->_base), "buffer should be empty\n"); + ok(!tempfh->_cnt, "tempfh->_cnt = %d\n", tempfh->_cnt); + + tempfh->_file = fd; + fclose(tempfh); unlink(tempf); free(tempf); } @@ -764,10 +863,10 @@ static void test_fgetwc( void ) tempfh = fopen(tempf,"rt"); /* open in TEXT mode */ fgetws(wtextW,LLEN,tempfh); l=ftell(tempfh); - ok(l==BUFSIZ-2, "ftell expected %d got %d\n", BUFSIZ-2, l); + ok(l==BUFSIZ-2, "ftell expected %d got %ld\n", BUFSIZ-2, l); fgetws(wtextW,LLEN,tempfh); l=ftell(tempfh); - ok(l==BUFSIZ-2+strlen(mytext), "ftell expected %d got %d\n", BUFSIZ-2+lstrlenA(mytext), l); + ok(l==BUFSIZ-2+strlen(mytext), "ftell expected %d got %ld\n", BUFSIZ-2+lstrlenA(mytext), l); mytextW = AtoW (mytext); aptr = mytextW; wptr = wtextW; @@ -779,7 +878,7 @@ static void test_fgetwc( void ) ok(*wptr == '\n', "Carriage return was not skipped\n"); fclose(tempfh); unlink(tempf); - + tempfh = fopen(tempf,"wb"); j = 'a'; /* pad to almost the length of the internal buffer. Use an odd number of bytes @@ -800,25 +899,25 @@ static void test_fgetwc( void ) fgetws(wtextW,j,tempfh); l=ftell(tempfh); j=(j-1)*sizeof(WCHAR); - ok(l==j, "ftell expected %d got %d\n", j, l); + ok(l==j, "ftell expected %d got %ld\n", j, l); i=fgetc(tempfh); ok(i=='a', "fgetc expected %d got %d\n", 0x61, i); l=ftell(tempfh); j++; - ok(l==j, "ftell expected %d got %d\n", j, l); + ok(l==j, "ftell expected %d got %ld\n", j, l); fgetws(wtextW,3,tempfh); ok(wtextW[0]=='\r',"expected carriage return got %04hx\n", wtextW[0]); ok(wtextW[1]=='\n',"expected newline got %04hx\n", wtextW[1]); l=ftell(tempfh); j += 4; - ok(l==j, "ftell expected %d got %d\n", j, l); + ok(l==j, "ftell expected %d got %ld\n", j, l); for(i=0; i 0, "utf-8 conversion failed\n"); + utf8_text[ret] = 0; + fwrite(utf8_text, sizeof(char), ret, tempfh); + fclose(tempfh); + + tempfh = fopen(tempfile, "rt, ccs=UTF-8"); + ok(tempfh != NULL, "can't open tempfile\n"); + for (i = 1; i < ARRAY_SIZE(wchar_text); i++) + { + ch = fgetwc(tempfh); + ok(ch == wchar_text[i], + "got %04hx, expected %04x (utf8[%d])\n", ch, wchar_text[i], i-1); + } + ch = fgetwc(tempfh); + ok(ch == WEOF, "got %04hx, expected WEOF (utf8)\n", ch); + fclose(tempfh); + + tempfh = fopen(tempfile, "rt, ccs=unicode"); + ok(tempfh != NULL, "can't open tempfile\n"); + for (i = 0; utf8_text[i]; i++) + { + ch = fgetwc(tempfh); + ok(ch == (unsigned char) utf8_text[i], + "got %04hx, expected %04x (unicode[%d])\n", ch, (unsigned char)utf8_text[i], i); + } + ch = fgetwc(tempfh); + ok(ch == WEOF, "got %04hx, expected WEOF (unicode)\n", ch); + fclose(tempfh); + unlink(temppath); } @@ -1034,6 +1216,98 @@ static void test_fputwc(void) _unlink(tempfile); } +static void test_freopen( void ) +{ + char filename1[8] = "AXXXXXX"; + char filename2[8] = "BXXXXXX"; + FILE *file; + FILE *new; + int ret; + int fd; + char ch; + long pos; + + mktemp(filename1); + mktemp(filename2); + + file = fopen(filename1, "wt"); + ok(file != NULL, "fopen(filename1) returned NULL\n"); + ret = fwrite("1", 1, 1, file); + ok(ret == 1, "fwrite() returned %d (%d)\n", ret, errno); + ret = fclose(file); + ok(ret == 0, "fclose() returned %d\n", ret); + + file = fopen(filename2, "wt"); + ok(file != NULL, "fopen(filename1) returned NULL\n"); + ret = fwrite("2", 1, 1, file); + ok(ret == 1, "fwrite() returned %d (%d)\n", ret, errno); + ret = fclose(file); + ok(ret == 0, "fclose() returned %d\n", ret); + + file = fopen(filename1, "rt"); + ok(file != NULL, "fopen(filename1) returned NULL\n"); + file = freopen(filename2, "rt", file); + ok(file != NULL, "fopen(filename2) returned NULL\n"); + ch = '#'; + ret = fread(&ch, 1, 1, file); + ok(ret == 1, "fread() returned %d\n", ret); + ok(ch == '2', "fread() read %c\n", ch); + ret = fclose(file); + ok(ret == 0, "fclose() returned %d\n", ret); + + file = fopen(filename1, "at"); + ok(file != NULL, "fopen(filename1) returned NULL\n"); + file = freopen(filename1, "rt", file); + ok(file != NULL, "fopen(filename1) returned NULL\n"); + pos = ftell(file); + ok(pos == 0, "ftell() returned %ld\n", pos); + ch = '#'; + ret = fread(&ch, 1, 1, file); + ok(ret == 1, "fread() returned %d\n", ret); + ok(ch == '1', "fread() read %c\n", ch); + ret = fclose(file); + ok(ret == 0, "fclose() returned %d\n", ret); + + file = fopen(filename1, "rt"); + ok(file != NULL, "fopen(filename1) returned NULL\n"); + fd = fileno(file); + ok(fd > 0, "fileno() returned %d\n", fd); + /* invalid filename */ + new = freopen("_:", "rt", file); + ok(new == NULL, "fopen(_:) returned non NULL\n"); + errno = 0xdeadbeef; + ch = '#'; + ret = read(fd, &ch, 1); + ok(ret == -1, "read() returned %d\n", ret); + ok(errno == EBADF, "errno is %d\n", errno); + errno = 0xdeadbeef; + ret = fclose(file); + ok(ret == EOF, "fclose(file) succeeded\n"); + ok(errno == 0xdeadbeef, "errno is %d\n", errno); + + file = fopen(filename1, "rb"); + ok(file != NULL, "couldn't open %s\n", filename1); + close(file->_file); + file->_file = -1; + + new = freopen(filename2, "rb", file); + ok(new == file, "freopen() didn't return same FILE*\n"); + + fd = fileno(file); + ok(fd > 0, "fileno() returned %d\n", fd); + + ch = '#'; + ret = fread(&ch, 1, 1, file); + ok(ret == 1, "fread() returned %d\n", ret); + ok(ch == '2', "Unexpected char\n"); + + ret = fclose(file); + ok(ret == 0, "fclose(file) returned %d\n", ret); + + unlink(filename1); + unlink(filename2); +} + static void test_ctrlz( void ) { char* tempf; @@ -1062,17 +1336,17 @@ static void test_ctrlz( void ) ok(i==j, "returned string length expected %d got %d\n", j, i); j+=4; /* ftell should indicate the true end of file */ l=ftell(tempfh); - ok(l==j, "ftell expected %d got %d\n", j, l); + ok(l==j, "ftell expected %d got %ld\n", j, l); ok(feof(tempfh), "did not get EOF\n"); fclose(tempfh); - + tempfh = fopen(tempf,"rb"); /* open in BINARY mode */ ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n"); i=strlen(buffer); j=strlen(mytext)+3; /* should get through newline */ ok(i==j, "returned string length expected %d got %d\n", j, i); l=ftell(tempfh); - ok(l==j, "ftell expected %d got %d\n", j, l); + ok(l==j, "ftell expected %d got %ld\n", j, l); ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n"); i=strlen(buffer); ok(i==1, "returned string length expected %d got %d\n", 1, i); @@ -1185,7 +1459,7 @@ static void test_file_write_read( void ) memset(btext, 0, LLEN); tempfd = _open(tempf,_O_APPEND|_O_RDWR); /* open for APPEND in default mode */ - ok(tell(tempfd) == 0, "bad position %u expecting 0\n", tell(tempfd)); + ok(tell(tempfd) == 0, "bad position %lu expecting 0\n", tell(tempfd)); ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext), "_read _O_APPEND got bad length\n"); ok( memcmp(mytext,btext,strlen(mytext)) == 0, "problems with _O_APPEND _read\n"); _close(tempfd); @@ -1206,15 +1480,15 @@ static void test_file_write_read( void ) _lseek(tempfd, -3, FILE_END); ret = _read(tempfd,btext,1); ok(ret == 1 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret); - ok(tell(tempfd) == 41, "bad position %u expecting 41\n", tell(tempfd)); + ok(tell(tempfd) == 41, "bad position %lu expecting 41\n", tell(tempfd)); _lseek(tempfd, -3, FILE_END); ret = _read(tempfd,btext,2); ok(ret == 1 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret); - ok(tell(tempfd) == 42, "bad position %u expecting 42\n", tell(tempfd)); + ok(tell(tempfd) == 42, "bad position %lu expecting 42\n", tell(tempfd)); _lseek(tempfd, -3, FILE_END); ret = _read(tempfd,btext,3); ok(ret == 2 && *btext == 'e', "_read expected 'e' got \"%.*s\" bad length: %d\n", ret, btext, ret); - ok(tell(tempfd) == 43, "bad position %u expecting 43\n", tell(tempfd)); + ok(tell(tempfd) == 43, "bad position %lu expecting 43\n", tell(tempfd)); _close(tempfd); ret = unlink(tempf); @@ -1336,9 +1610,9 @@ static void test_file_write_read( void ) /* test invalid utf8 sequence */ lseek(tempfd, 5, SEEK_SET); ret = _read(tempfd, btext, sizeof(btext)); - todo_wine ok(ret == 10, "_read returned %d, expected 10\n", ret); + ok(ret == 10, "_read returned %d, expected 10\n", ret); /* invalid char should be replaced by U+FFFD in MultiByteToWideChar */ - todo_wine ok(!memcmp(btext, "\xfd\xff", 2), "invalid UTF8 character was not replaced by U+FFFD\n"); + ok(!memcmp(btext, "\xfd\xff", 2), "invalid UTF8 character was not replaced by U+FFFD\n"); ok(!memcmp(btext+ret-8, "\x62\x00\x7c\x01\x0d\x00\x0a\x00", 8), "btext is incorrect\n"); _close(tempfd); } @@ -1355,13 +1629,27 @@ static void test_file_write_read( void ) free(tempf); } -static void test_file_inherit_child(const char* fd_s) +static void test_file_inherit_child(const char* fd_s, const char *handle_str) { + HANDLE handle_value; int fd = atoi(fd_s); + HANDLE *handle_ptr; + unsigned int count; char buffer[32]; + STARTUPINFOA si; int ret; - ret =write(fd, "Success", 8); + GetStartupInfoA(&si); + count = *(unsigned *)si.lpReserved2; + if (handle_str) + { + ok(count == 3, "Got unexpected count %u.\n", count); + sscanf(handle_str, "%p", &handle_value); + handle_ptr = (HANDLE *)(si.lpReserved2 + sizeof(unsigned) + count); + ok(handle_value == handle_ptr[1], "Got unexpected handle %p.\n", handle_ptr[1]); + } + + ret = write(fd, "Success", 8); ok( ret == 8, "Couldn't write in child process on %d (%s)\n", fd, strerror(errno)); lseek(fd, 0, SEEK_SET); ok(read(fd, buffer, sizeof (buffer)) == 8, "Couldn't read back the data\n"); @@ -1374,7 +1662,7 @@ static void test_file_inherit_child_no(const char* fd_s) int ret; ret = write(fd, "Success", 8); - ok( ret == -1 && errno == EBADF, + ok( ret == -1 && errno == EBADF, "Wrong write result in child process on %d (%s)\n", fd, strerror(errno)); } @@ -1430,7 +1718,7 @@ static void test_stdout_handle( STARTUPINFOA *startup, char *cmdline, HANDLE hst CreateProcessA( NULL, cmdline, NULL, NULL, TRUE, CREATE_DEFAULT_ERROR_MODE | NORMAL_PRIORITY_CLASS, NULL, NULL, startup, &proc ); - winetest_wait_child_process( proc.hProcess ); + wait_child_process( proc.hProcess ); data = read_file( hErrorFile ); if (expect_stdout) @@ -1451,6 +1739,18 @@ static void test_stdout_handle( STARTUPINFOA *startup, char *cmdline, HANDLE hst DeleteFileA( "fdopen.err" ); } +static unsigned WINAPI read_pipe_thread(void *argument) +{ + unsigned char buffer[2]; + int ret; + int *pipefds = argument; + + ret = _read(pipefds[0], buffer, sizeof(buffer)); + ok(ret == 1, "ret = %d\n", ret); + ok(buffer[0] == 'a', "%x\n", buffer[0]); + return 0; +} + static void test_file_inherit( const char* selfname ) { int fd; @@ -1460,33 +1760,62 @@ static void test_file_inherit( const char* selfname ) STARTUPINFOA startup; SECURITY_ATTRIBUTES sa; HANDLE handles[3]; + HANDLE thread_handle; + int pipefds[2]; + intptr_t ret; fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY, _S_IREAD |_S_IWRITE); ok(fd != -1, "Couldn't create test file\n"); arg_v[0] = get_base_name(selfname); - arg_v[1] = "tests/file.c"; + arg_v[1] = "file"; arg_v[2] = "inherit"; arg_v[3] = buffer; sprintf(buffer, "%d", fd); arg_v[4] = 0; - _spawnvp(_P_WAIT, selfname, arg_v); - ok(tell(fd) == 8, "bad position %u expecting 8\n", tell(fd)); + ret = _spawnvp(_P_WAIT, selfname, arg_v); + ok(ret == 0, "_spawnvp returned %Id, errno %d\n", ret, errno); + ok(tell(fd) == 8, "bad position %lu expecting 8\n", tell(fd)); lseek(fd, 0, SEEK_SET); ok(read(fd, buffer, sizeof (buffer)) == 8 && memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n"); close (fd); ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n"); - + fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY | O_NOINHERIT, _S_IREAD |_S_IWRITE); ok(fd != -1, "Couldn't create test file\n"); - arg_v[1] = "tests/file.c"; + arg_v[1] = "file"; arg_v[2] = "inherit_no"; arg_v[3] = buffer; sprintf(buffer, "%d", fd); arg_v[4] = 0; - _spawnvp(_P_WAIT, selfname, arg_v); - ok(tell(fd) == 0, "bad position %u expecting 0\n", tell(fd)); + ret = _spawnvp(_P_WAIT, selfname, arg_v); + ok(ret == 0, "_spawnvp returned %Id, errno %d\n", ret, errno); + ok(tell(fd) == 0, "bad position %lu expecting 0\n", tell(fd)); ok(read(fd, buffer, sizeof (buffer)) == 0, "Found unexpected data (%s)\n", buffer); close (fd); ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n"); + /* Show that spawn works while a read is active */ + ok(_pipe(pipefds, 1, O_BINARY) == 0, "_pipe() failed\n"); + thread_handle = (HANDLE)_beginthreadex(NULL, 0, read_pipe_thread, pipefds, 0, NULL); + Sleep(100); /* try to make sure the thread is reading */ + fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY, _S_IREAD |_S_IWRITE); + ok(fd != -1, "Couldn't create test file\n"); + arg_v[1] = "tests/file.c"; + arg_v[2] = "inherit"; + arg_v[3] = buffer; sprintf(buffer, "%d", fd); + arg_v[4] = 0; + ret = _spawnvp(_P_WAIT, selfname, arg_v); + ok(ret == 0, "_spawnvp returned %Id, errno %d\n", ret, errno); + ret = tell(fd); + ok(ret == 8, "bad position %Iu expecting 8\n", ret); + lseek(fd, 0, SEEK_SET); + ok(read(fd, buffer, sizeof (buffer)) == 8 && memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n"); + close (fd); + ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n"); + _write(pipefds[1], "a", 1); + WaitForSingleObject(thread_handle, INFINITE); + CloseHandle(thread_handle); + close(pipefds[0]); + close(pipefds[1]); + /* make file handle inheritable */ sa.nLength = sizeof(sa); sa.lpSecurityDescriptor = NULL; @@ -1544,6 +1873,22 @@ static void test_file_inherit( const char* selfname ) test_stdout_handle( &startup, cmdline, handles[1], TRUE, "large size block" ); CloseHandle( handles[1] ); DeleteFileA("fdopen.tst"); + + /* test inherit block with invalid handle */ + handles[1] = INVALID_HANDLE_VALUE; + create_io_inherit_block( &startup, 3, handles ); + sprintf(cmdline, "%s file inherit 1 %p", selfname, handles[1]); + test_stdout_handle( &startup, cmdline, NULL, FALSE, "INVALID_HANDLE_VALUE stdout handle" ); + + handles[1] = NULL; + create_io_inherit_block( &startup, 3, handles ); + sprintf(cmdline, "%s file inherit 1 %p", selfname, handles[1]); + test_stdout_handle( &startup, cmdline, NULL, FALSE, "NULL stdout handle" ); + + handles[1] = (void *)0xdeadbeef; + create_io_inherit_block( &startup, 3, handles ); + sprintf(cmdline, "%s file inherit 1 %p", selfname, handles[1]); + test_stdout_handle( &startup, cmdline, NULL, FALSE, "invalid stdout handle" ); } static void test_invalid_stdin_child( void ) @@ -1557,6 +1902,8 @@ static void test_invalid_stdin_child( void ) handle = (HANDLE)_get_osfhandle(STDIN_FILENO); ok(handle == (HANDLE)-2, "handle = %p\n", handle); ok(errno == 0xdeadbeef, "errno = %d\n", errno); + handle = GetStdHandle(STD_INPUT_HANDLE); + ok((LONG_PTR)handle > 0, "Expecting passed handle to be untouched\n"); info = &__pioinfo[STDIN_FILENO/MSVCRT_FD_BLOCK_SIZE][STDIN_FILENO%MSVCRT_FD_BLOCK_SIZE]; ok(info->handle == (HANDLE)-2, "info->handle = %p\n", info->handle); @@ -1631,7 +1978,11 @@ static void test_invalid_stdin( const char* selfname ) } ret = RegOpenCurrentUser(KEY_READ, &key); - ok(!ret, "RegOpenCurrentUser failed: %x\n", ret); + ok(!ret, "RegOpenCurrentUser failed: %lx\n", ret); + + ret = DuplicateHandle(GetCurrentProcess(), key, GetCurrentProcess(), + (HANDLE *)&key, GENERIC_READ, TRUE, DUPLICATE_CLOSE_SOURCE); + ok(ret, "DuplicateHandle failed: %lx\n", GetLastError()); sa.nLength = sizeof(sa); sa.lpSecurityDescriptor = NULL; @@ -1647,10 +1998,10 @@ static void test_invalid_stdin( const char* selfname ) sprintf(cmdline, "%s file stdin", selfname); CreateProcessA(NULL, cmdline, NULL, NULL, TRUE, CREATE_DEFAULT_ERROR_MODE|NORMAL_PRIORITY_CLASS, NULL, NULL, &startup, &proc); - winetest_wait_child_process(proc.hProcess); + wait_child_process(proc.hProcess); ret = RegCloseKey(key); - ok(!ret, "RegCloseKey failed: %x\n", ret); + ok(!ret, "RegCloseKey failed: %lx\n", ret); } static void test_tmpnam( void ) @@ -1678,8 +2029,8 @@ static void test_chsize( void ) LONG cur, pos, count; char temptext[] = "012345678"; char *tempfile = _tempnam( ".", "tst" ); - - ok( tempfile != NULL, "Couldn't create test file: %s\n", tempfile ); + + ok( tempfile != NULL, "Couldn't create test file\n" ); fd = _open( tempfile, _O_CREAT|_O_TRUNC|_O_RDWR, _S_IREAD|_S_IWRITE ); ok( fd > 0, "Couldn't open test file\n" ); @@ -1694,14 +2045,14 @@ static void test_chsize( void ) ok( _chsize( fd, sizeof(temptext) / 2 ) == 0, "_chsize() failed\n" ); pos = _lseek( fd, 0, SEEK_CUR ); - ok( cur == pos, "File pointer changed from: %d to: %d\n", cur, pos ); + ok( cur == pos, "File pointer changed from: %ld to: %ld\n", cur, pos ); ok( _filelength( fd ) == sizeof(temptext) / 2, "Wrong file size\n" ); /* enlarge the file */ - ok( _chsize( fd, sizeof(temptext) * 2 ) == 0, "_chsize() failed\n" ); + ok( _chsize( fd, sizeof(temptext) * 2 ) == 0, "_chsize() failed\n" ); pos = _lseek( fd, 0, SEEK_CUR ); - ok( cur == pos, "File pointer changed from: %d to: %d\n", cur, pos ); + ok( cur == pos, "File pointer changed from: %ld to: %ld\n", cur, pos ); ok( _filelength( fd ) == sizeof(temptext) * 2, "Wrong file size\n" ); _close( fd ); @@ -1733,7 +2084,7 @@ static void test_fopen_fclose_fcloseall( void ) "filename is empty, errno = %d (expected 2 or 22)\n", errno); errno = 0xfaceabad; stream4 = fopen(NULL, "w+"); - ok(stream4 == NULL && (errno == EINVAL || errno == ENOENT), + ok(stream4 == NULL && (errno == EINVAL || errno == ENOENT), "filename is NULL, errno = %d (expected 2 or 22)\n", errno); /* testing fclose() */ @@ -1748,6 +2099,11 @@ static void test_fopen_fclose_fcloseall( void ) ret = fclose(stream3); ok(ret == EOF, "Closing file '%s' returned %d\n", fname3, ret); ok(errno == 0xdeadbeef, "errno = %d\n", errno); + skip_2k3_crash { + ret = fclose(NULL); + ok(ret == EOF, "Closing NULL file returned %d\n", ret); + ok(errno == EINVAL, "errno = %d\n", errno); + } /* testing fcloseall() */ numclosed = _fcloseall(); @@ -1879,12 +2235,6 @@ static void test_fopen_s( void ) static void test__wfopen_s( void ) { const char name[] = "empty1"; - const WCHAR wname[] = { - 'e','m','p','t','y','1',0 - }; - const WCHAR wmode[] = { - 'w',0 - }; char buff[16]; FILE *file; int ret; @@ -1896,7 +2246,7 @@ static void test__wfopen_s( void ) return; } /* testing _wfopen_s */ - ret = p__wfopen_s(&file, wname, wmode); + ret = p__wfopen_s(&file, L"empty1", L"w"); ok(ret == 0, "_wfopen_s failed with %d\n", ret); ok(file != 0, "_wfopen_s failed to return value\n"); fwrite(name, sizeof(name), 1, file); @@ -2007,8 +2357,12 @@ static void test_get_osfhandle(void) static void test_setmaxstdio(void) { - ok(2048 == _setmaxstdio(2048),"_setmaxstdio returned %d instead of 2048\n",_setmaxstdio(2048)); - ok(-1 == _setmaxstdio(2049),"_setmaxstdio returned %d instead of -1\n",_setmaxstdio(2049)); + if (p__setmaxstdio) + { + ok(2048 == p__setmaxstdio(2048),"_setmaxstdio returned %d instead of 2048\n",p__setmaxstdio(2048)); + ok(-1 == p__setmaxstdio(2049),"_setmaxstdio returned %d instead of -1\n",p__setmaxstdio(2049)); + } + else win_skip( "_setmaxstdio not supported\n" ); } static void test_stat(void) @@ -2168,7 +2522,7 @@ static void test_pipes(const char* selfname) } arg_v[0] = get_base_name(selfname); - arg_v[1] = "tests/file.c"; + arg_v[1] = "file"; arg_v[2] = "pipes"; arg_v[3] = str_fdr; sprintf(str_fdr, "%d", pipes[0]); arg_v[4] = str_fdw; sprintf(str_fdw, "%d", pipes[1]); @@ -2197,7 +2551,7 @@ static void test_pipes(const char* selfname) return; } - arg_v[1] = "tests/file.c"; + arg_v[1] = "file"; arg_v[2] = "pipes"; arg_v[3] = str_fdr; sprintf(str_fdr, "%d", pipes[0]); arg_v[4] = str_fdw; sprintf(str_fdw, "%d", pipes[1]); @@ -2313,7 +2667,7 @@ static void test_stdin(void) "GetStdHandle(STD_INPUT_HANDLE) != _get_osfhandle(STDIN_FILENO)\n"); r = SetStdHandle(STD_INPUT_HANDLE, INVALID_HANDLE_VALUE); - ok(r == TRUE, "SetStdHandle returned %x, expected TRUE\n", r); + ok(r == TRUE, "SetStdHandle returned %lx, expected TRUE\n", r); h = GetStdHandle(STD_INPUT_HANDLE); ok(h == INVALID_HANDLE_VALUE, "h = %p\n", h); @@ -2548,7 +2902,7 @@ static void test__creat(void) pos = _tell(fd); ok(pos == 6, "expected pos 6 (text mode), got %d\n", pos); } - ok(_lseek(fd, SEEK_SET, 0) == 0, "_lseek failed\n"); + ok(_lseek(fd, 0, SEEK_SET) == 0, "_lseek failed\n"); count = _read(fd, buf, 6); ok(count == 4, "_read returned %d, expected 4\n", count); count = count > 0 ? count > 4 ? 4 : count : 0; @@ -2568,7 +2922,7 @@ static void test__creat(void) pos = _tell(fd); ok(pos == 4, "expected pos 4 (binary mode), got %d\n", pos); } - ok(_lseek(fd, SEEK_SET, 0) == 0, "_lseek failed\n"); + ok(_lseek(fd, 0, SEEK_SET) == 0, "_lseek failed\n"); count = _read(fd, buf, 6); ok(count == 4, "_read returned %d, expected 4\n", count); count = count > 0 ? count > 4 ? 4 : count : 0; @@ -2583,6 +2937,215 @@ static void test__creat(void) p__set_fmode(old_fmode); } +static void test_lseek(void) +{ + int fd; + char testdata[4] = {'a', '\n', 'b', '\n'}; + + errno = 0xdeadbeef; + ok(_lseek(-42, 0, SEEK_SET) == -1, "expected failure\n"); + ok(errno == EBADF, "errno = %d\n", errno); + + fd = _creat("_creat.tst", _S_IWRITE); + ok(fd > 0, "_creat failed\n"); + _write(fd, testdata, 4); + + errno = 0xdeadbeef; + ok(_lseek(fd, 0, 42) == -1, "expected failure\n"); + ok(errno == EINVAL, "errno = %d\n", errno); + + errno = 0xdeadbeef; + ok(_lseek(fd, -42, SEEK_SET) == -1, "expected failure\n"); + ok(errno == EINVAL, "errno = %d\n", errno); + + _close(fd); + DeleteFileA("_creat.tst"); +} + +static BOOL has_sequential_hint(int fd) +{ + HANDLE handle; + FILE_MODE_INFORMATION mode_info; + IO_STATUS_BLOCK io; + NTSTATUS status; + + handle = (HANDLE)_get_osfhandle(fd); + status = NtQueryInformationFile(handle, &io, &mode_info, sizeof(mode_info), + FileModeInformation); + ok(!status, "NtQueryInformationFile failed\n"); + return (mode_info.Mode & FILE_SEQUENTIAL_ONLY) != 0; +} + +static void test_fopen_hints(void) +{ + static const struct { + const char *mode; + BOOL seq; + } tests[] = { + { "rb", FALSE }, + { "rbS", TRUE }, + { "rbR", FALSE }, + { "rbSR", TRUE }, + { "rbRS", FALSE } + }; + + char temppath[MAX_PATH], tempfile[MAX_PATH]; + FILE *fp; + int i; + + GetTempPathA(MAX_PATH, temppath); + GetTempFileNameA(temppath, "", 0, tempfile); + + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + fp = fopen(tempfile, tests[i].mode); + ok(fp != NULL, "unable to fopen test file with mode \"%s\"\n", tests[i].mode); + ok(has_sequential_hint(_fileno(fp)) == tests[i].seq, + "unexpected sequential hint for fopen mode \"%s\"\n", tests[i].mode); + fclose(fp); + } + unlink(tempfile); +} + +static void test_open_hints(void) +{ + static const struct { + int mode; + BOOL seq; + } tests[] = { + { _O_RDONLY | _O_BINARY, FALSE }, + { _O_RDONLY | _O_BINARY | _O_SEQUENTIAL, TRUE }, + { _O_RDONLY | _O_BINARY | _O_RANDOM, FALSE }, + { _O_RDONLY | _O_BINARY | _O_RANDOM | _O_SEQUENTIAL, TRUE } + }; + + char temppath[MAX_PATH], tempfile[MAX_PATH]; + int fd; + int i; + + GetTempPathA(MAX_PATH, temppath); + GetTempFileNameA(temppath, "", 0, tempfile); + + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + fd = open(tempfile, tests[i].mode); + ok(fd != -1, "unable to _open test file with flags %x\n", tests[i].mode); + ok(has_sequential_hint(fd) == tests[i].seq, + "unexpected sequential hint for _open flags %x\n", tests[i].mode); + close(fd); + } + unlink(tempfile); +} + +static void test_ioinfo_flags(void) +{ + HANDLE handle; + ioinfo *info; + char *tempf; + int tempfd; + + tempf = _tempnam(".","wne"); + + tempfd = _open(tempf, _O_CREAT|_O_TRUNC|_O_WRONLY|_O_WTEXT, _S_IWRITE); + ok(tempfd != -1, "_open failed with error: %d\n", errno); + + handle = (HANDLE)_get_osfhandle(tempfd); + info = &__pioinfo[tempfd / MSVCRT_FD_BLOCK_SIZE][tempfd % MSVCRT_FD_BLOCK_SIZE]; + ok(!!info, "NULL info.\n"); + ok(info->handle == handle, "Unexpected handle %p, expected %p.\n", info->handle, handle); + skip_2k3_fail ok(info->exflag == (EF_UTF16 | EF_CRIT_INIT | EF_UNK_UNICODE), "Unexpected exflag %#x.\n", info->exflag); + ok(info->wxflag == (WX_TEXT | WX_OPEN), "Unexpected wxflag %#x.\n", info->wxflag); + + close(tempfd); + + ok(info->handle == INVALID_HANDLE_VALUE, "Unexpected handle %p.\n", info->handle); + skip_2k3_fail ok(info->exflag == (EF_UTF16 | EF_CRIT_INIT | EF_UNK_UNICODE), "Unexpected exflag %#x.\n", info->exflag); + ok(!info->wxflag, "Unexpected wxflag %#x.\n", info->wxflag); + + info = &__pioinfo[(tempfd + 4) / MSVCRT_FD_BLOCK_SIZE][(tempfd + 4) % MSVCRT_FD_BLOCK_SIZE]; + ok(!!info, "NULL info.\n"); + ok(info->handle == INVALID_HANDLE_VALUE, "Unexpected handle %p.\n", info->handle); + ok(!info->exflag, "Unexpected exflag %#x.\n", info->exflag); + + unlink(tempf); + free(tempf); +} + +static void test_std_stream_buffering(void) +{ + int dup_fd, ret, pos; + FILE *file; + char ch; + + dup_fd = _dup(STDOUT_FILENO); + ok(dup_fd != -1, "_dup failed\n"); + + file = freopen("std_stream_test.tmp", "w", stdout); + ok(file != NULL, "freopen failed\n"); + + ret = fprintf(stdout, "test"); + pos = _telli64(STDOUT_FILENO); + + fflush(stdout); + _dup2(dup_fd, STDOUT_FILENO); + close(dup_fd); + setvbuf(stdout, NULL, _IONBF, 0); + + ok(ret == 4, "fprintf(stdout) returned %d\n", ret); + ok(!pos, "expected stdout to be buffered\n"); + + dup_fd = _dup(STDERR_FILENO); + ok(dup_fd != -1, "_dup failed\n"); + + file = freopen("std_stream_test.tmp", "w", stderr); + ok(file != NULL, "freopen failed\n"); + + ret = fprintf(stderr, "test"); + ok(ret == 4, "fprintf(stderr) returned %d\n", ret); + pos = _telli64(STDERR_FILENO); + ok(!pos, "expected stderr to be buffered\n"); + + fflush(stderr); + _dup2(dup_fd, STDERR_FILENO); + close(dup_fd); + + dup_fd = _dup(STDIN_FILENO); + ok(dup_fd != -1, "_dup failed\n"); + + file = freopen("std_stream_test.tmp", "r", stdin); + ok(file != NULL, "freopen failed\n"); + + ch = 0; + ret = fscanf(stdin, "%c", &ch); + ok(ret == 1, "fscanf returned %d\n", ret); + ok(ch == 't', "ch = 0x%x\n", (unsigned char)ch); + pos = _telli64(STDIN_FILENO); + ok(pos == 4, "pos = %d\n", pos); + + fflush(stdin); + _dup2(dup_fd, STDIN_FILENO); + close(dup_fd); + + ok(DeleteFileA("std_stream_test.tmp"), "DeleteFile failed\n"); +} + +static void test_std_stream_open(void) +{ + FILE *f; + int fd; + + fd = _dup(STDIN_FILENO); + ok(fd != -1, "_dup failed\n"); + + ok(!fclose(stdin), "fclose failed\n"); + f = fopen("nul", "r"); + ok(f == stdin, "f = %p, expected %p\n", f, stdin); + ok(_fileno(f) == STDIN_FILENO, "_fileno(f) = %d\n", _fileno(f)); + + _dup2(fd, STDIN_FILENO); + close(fd); +} + START_TEST(file) { int arg_c; @@ -2596,7 +3159,7 @@ START_TEST(file) if (arg_c >= 3) { if (strcmp(arg_v[2], "inherit") == 0) - test_file_inherit_child(arg_v[3]); + test_file_inherit_child(arg_v[3], arg_c > 4 ? arg_v[4] : NULL); else if (strcmp(arg_v[2], "inherit_no") == 0) test_file_inherit_child_no(arg_v[3]); else if (strcmp(arg_v[2], "pipes") == 0) @@ -2642,6 +3205,7 @@ START_TEST(file) test_fgetwc_locale("AB\x83\xa9", "C", 0); test_fgetwc_unicode(); test_fputwc(); + test_freopen(); test_ctrlz(); test_file_put_get(); test_tmpnam(); @@ -2654,6 +3218,12 @@ START_TEST(file) test_write_flush(); test_close(); test__creat(); + test_lseek(); + test_fopen_hints(); + test_open_hints(); + test_ioinfo_flags(); + test_std_stream_buffering(); + test_std_stream_open(); /* Wait for the (_P_NOWAIT) spawned processes to finish to make sure the report * file contains lines in the correct order diff --git a/modules/rostests/winetests/msvcrt/heap.c b/modules/rostests/winetests/msvcrt/heap.c index d934bf0c5425d..e8da95bb867f2 100644 --- a/modules/rostests/winetests/msvcrt/heap.c +++ b/modules/rostests/winetests/msvcrt/heap.c @@ -23,17 +23,13 @@ #include #include "wine/test.h" -#ifdef __REACTOS__ -#if defined(__GNUC__) && __GNUC__ >= 7 -#pragma GCC diagnostic ignored "-Walloc-size-larger-than=9223372036854775807" -#endif -#endif - -static void (__cdecl *p_aligned_free)(void*) = NULL; -static void * (__cdecl *p_aligned_malloc)(size_t,size_t) = NULL; -static void * (__cdecl *p_aligned_offset_malloc)(size_t,size_t,size_t) = NULL; -static void * (__cdecl *p_aligned_realloc)(void*,size_t,size_t) = NULL; -static void * (__cdecl *p_aligned_offset_realloc)(void*,size_t,size_t,size_t) = NULL; +static void (__cdecl *p_aligned_free)(void*); +static void * (__cdecl *p_aligned_malloc)(size_t,size_t); +static void * (__cdecl *p_aligned_offset_malloc)(size_t,size_t,size_t); +static void * (__cdecl *p_aligned_realloc)(void*,size_t,size_t); +static void * (__cdecl *p_aligned_offset_realloc)(void*,size_t,size_t,size_t); +static int (__cdecl *p__set_sbh_threshold)(size_t); +static size_t (__cdecl *p__get_sbh_threshold)(void); static void test_aligned_malloc(unsigned int size, unsigned int alignment) { @@ -421,28 +417,37 @@ static void test_aligned(void) static void test_sbheap(void) { + HMODULE msvcrt = GetModuleHandleA("msvcrt.dll"); void *mem; int threshold; + p__set_sbh_threshold = (void*)GetProcAddress(msvcrt, "_set_sbh_threshold"); + p__get_sbh_threshold = (void*)GetProcAddress(msvcrt, "_get_sbh_threshold"); + if (!p__set_sbh_threshold || !p__get_sbh_threshold) + { + win_skip("_set_sbh_threshold not available\n"); + return; + } + if(sizeof(void*) == 8) { - ok(!_set_sbh_threshold(0), "_set_sbh_threshold succeeded\n"); - ok(!_set_sbh_threshold(1000), "_set_sbh_threshold succeeded\n"); + ok(!p__set_sbh_threshold(0), "_set_sbh_threshold succeeded\n"); + ok(!p__set_sbh_threshold(1000), "_set_sbh_threshold succeeded\n"); return; } mem = malloc(1); ok(mem != NULL, "malloc failed\n"); - ok(_set_sbh_threshold(1), "_set_sbh_threshold failed\n"); - threshold = _get_sbh_threshold(); + ok(p__set_sbh_threshold(1), "_set_sbh_threshold failed\n"); + threshold = p__get_sbh_threshold(); ok(threshold == 16, "threshold = %d\n", threshold); - ok(_set_sbh_threshold(8), "_set_sbh_threshold failed\n"); - threshold = _get_sbh_threshold(); + ok(p__set_sbh_threshold(8), "_set_sbh_threshold failed\n"); + threshold = p__get_sbh_threshold(); ok(threshold == 16, "threshold = %d\n", threshold); - ok(_set_sbh_threshold(1000), "_set_sbh_threshold failed\n"); - threshold = _get_sbh_threshold(); + ok(p__set_sbh_threshold(1000), "_set_sbh_threshold failed\n"); + threshold = p__get_sbh_threshold(); ok(threshold == 1008, "threshold = %d\n", threshold); free(mem); @@ -455,13 +460,42 @@ static void test_sbheap(void) ok(mem != NULL, "realloc failed\n"); ok(!((UINT_PTR)mem & 0xf), "incorrect alignment (%p)\n", mem); - ok(_set_sbh_threshold(0), "_set_sbh_threshold failed\n"); - threshold = _get_sbh_threshold(); + ok(p__set_sbh_threshold(0), "_set_sbh_threshold failed\n"); + threshold = p__get_sbh_threshold(); ok(threshold == 0, "threshold = %d\n", threshold); free(mem); } +static void test_malloc(void) +{ + /* use function pointers to bypass gcc builtins */ + void *(__cdecl *p_malloc)(size_t); + void *(__cdecl *p_realloc)(void *,size_t); + void *mem; + + p_malloc = (void *)GetProcAddress( GetModuleHandleA("msvcrt.dll"), "malloc"); + p_realloc = (void *)GetProcAddress( GetModuleHandleA("msvcrt.dll"), "realloc"); + + mem = p_malloc(0); + ok(mem != NULL, "memory not allocated for size 0\n"); + free(mem); + + mem = p_realloc(NULL, 10); + ok(mem != NULL, "memory not allocated\n"); + + mem = p_realloc(mem, 20); + ok(mem != NULL, "memory not reallocated\n"); + + mem = p_realloc(mem, 0); + ok(mem == NULL, "memory not freed\n"); + + mem = p_realloc(NULL, 0); + ok(mem != NULL, "memory not (re)allocated for size 0\n"); + + free(mem); +} + static void test_calloc(void) { /* use function pointer to bypass gcc builtin */ @@ -489,29 +523,16 @@ static void test_calloc(void) free(ptr); } -START_TEST(heap) +static void test__get_heap_handle(void) { - void *mem; - - mem = malloc(0); - ok(mem != NULL, "memory not allocated for size 0\n"); - free(mem); - - mem = realloc(NULL, 10); - ok(mem != NULL, "memory not allocated\n"); - - mem = realloc(mem, 20); - ok(mem != NULL, "memory not reallocated\n"); - - mem = realloc(mem, 0); - ok(mem == NULL, "memory not freed\n"); - - mem = realloc(NULL, 0); - ok(mem != NULL, "memory not (re)allocated for size 0\n"); - - free(mem); + ok((HANDLE)_get_heap_handle() != GetProcessHeap(), "Expected _get_heap_handle() not to return GetProcessHeap()\n"); +} +START_TEST(heap) +{ test_aligned(); test_sbheap(); + test_malloc(); test_calloc(); + test__get_heap_handle(); } diff --git a/modules/rostests/winetests/msvcrt/locale.c b/modules/rostests/winetests/msvcrt/locale.c index 08abac00bedd3..a9ade6f5c4136 100644 --- a/modules/rostests/winetests/msvcrt/locale.c +++ b/modules/rostests/winetests/msvcrt/locale.c @@ -19,6 +19,7 @@ */ #include +#include #include "wine/test.h" #include "winnls.h" @@ -27,6 +28,9 @@ static BOOL (__cdecl *p__crtGetStringTypeW)(DWORD, DWORD, const wchar_t*, int, W static int (__cdecl *pmemcpy_s)(void *, size_t, void*, size_t); static int (__cdecl *p___mb_cur_max_func)(void); static int *(__cdecl *p__p___mb_cur_max)(void); +static _locale_t(__cdecl *p_create_locale)(int, const char*); +static void(__cdecl *p_free_locale)(_locale_t); +static int (__cdecl *p_wcsicmp_l)(const wchar_t*, const wchar_t*, _locale_t); void* __cdecl _Gettnames(void); static void init(void) @@ -37,6 +41,9 @@ static void init(void) pmemcpy_s = (void*)GetProcAddress(hmod, "memcpy_s"); p___mb_cur_max_func = (void*)GetProcAddress(hmod, "___mb_cur_max_func"); p__p___mb_cur_max = (void*)GetProcAddress(hmod, "__p___mb_cur_max"); + p_create_locale = (void*)GetProcAddress(hmod, "_create_locale"); + p_free_locale = (void*)GetProcAddress(hmod, "_free_locale"); + p_wcsicmp_l = (void*)GetProcAddress(hmod, "_wcsicmp_l"); } static void test_setlocale(void) @@ -45,6 +52,8 @@ static void test_setlocale(void) "LC_MONETARY=Greek_Greece.1253;LC_NUMERIC=Polish_Poland.1250;LC_TIME=C"; char *ret, buf[100]; + char *ptr; + int len; ret = setlocale(20, "C"); ok(ret == NULL, "ret = %s\n", ret); @@ -571,12 +580,14 @@ static void test_setlocale(void) ret = setlocale(LC_ALL, "trk"); ok(ret != NULL || broken (ret == NULL), "ret == NULL\n"); if(ret) - ok(!strcmp(ret, "Turkish_Turkey.1254"), "ret = %s\n", ret); + ok(!strcmp(ret, "Turkish_Turkey.1254") + || !strcmp(ret, "Turkish_T\xfcrkiye.1254"), "ret = %s\n", ret); ret = setlocale(LC_ALL, "turkish"); ok(ret != NULL || broken (ret == NULL), "ret == NULL\n"); if(ret) - ok(!strcmp(ret, "Turkish_Turkey.1254"), "ret = %s\n", ret); + ok(!strcmp(ret, "Turkish_Turkey.1254") + || !strcmp(ret, "Turkish_T\xfcrkiye.1254"), "ret = %s\n", ret); ret = setlocale(LC_ALL, "uk"); ok(ret != NULL, "ret == NULL\n"); @@ -612,6 +623,33 @@ static void test_setlocale(void) ok(!strcmp(ret, buf), "ret = %s, expected %s\n", ret, buf); } + GetLocaleInfoA(GetUserDefaultLCID(), LOCALE_IDEFAULTCODEPAGE, buf, sizeof(buf)); + if(IsValidCodePage(atoi(buf))) { + ret = setlocale(LC_ALL, ".OCP"); + ok(ret != NULL, "ret == NULL\n"); +#ifdef __REACTOS__ + if (ret == NULL) ptr = NULL; else +#endif + ptr = strchr(ret, '.'); + ok(ptr && !strcmp(ptr + 1, buf), "ret %s, buf %s.\n", ret, buf); + } + + len = GetLocaleInfoA(GetUserDefaultLCID(), LOCALE_IDEFAULTANSICODEPAGE, buf, sizeof(buf)) - 1; + if(buf[0] == '0' && !buf[1]) + len = sprintf(buf, "%d", GetACP()); + ret = setlocale(LC_ALL, ".ACP"); + ok(ret != NULL, "ret == NULL\n"); +#ifdef __REACTOS__ + if (ret == NULL) ptr = NULL; else +#endif + ptr = strchr(ret, '.'); + ok(ptr && !strncmp(ptr + 1, buf, len), "ret %s, buf %s.\n", ret, buf); + + ret = setlocale(LC_ALL, ".1250"); + ok(ret != NULL, "ret == NULL\n"); + ptr = strchr(ret, '.'); + ok(ptr && !strcmp(ptr, ".1250"), "ret %s, buf %s.\n", ret, buf); + ret = setlocale(LC_ALL, "English_United States.UTF8"); ok(ret == NULL, "ret != NULL\n"); @@ -621,13 +659,7 @@ static void test_setlocale(void) static void test_crtGetStringTypeW(void) { - static const wchar_t str0[] = { '0', '\0' }; - static const wchar_t strA[] = { 'A', '\0' }; - static const wchar_t str_space[] = { ' ', '\0' }; - static const wchar_t str_null[] = { '\0', '\0' }; - static const wchar_t str_rand[] = { 1234, '\0' }; - - const wchar_t *str[] = { str0, strA, str_space, str_null, str_rand }; + const wchar_t *str[] = { L"0", L"A", L" ", L"\0", L"\x04d2" }; WORD out_crt, out; BOOL ret_crt, ret; @@ -712,10 +744,14 @@ static void test__Gettnames(void) { size = GetLocaleInfoA(MAKELCID(LANG_ENGLISH, SORT_DEFAULT), time_data[i], buf, sizeof(buf)); - ok(size, "GetLocaleInfo failed: %x\n", GetLastError()); + ok(size, "GetLocaleInfo failed: %lx\n", GetLastError()); ok(!strcmp(ret->str[i], buf), "ret->str[%i] = %s, expected %s\n", i, ret->str[i], buf); } + ok(ret->wstr[0] != NULL, "ret->wstr[0] = NULL\n"); + ok(ret->str[42] + strlen(ret->str[42])+1 != (char*)ret->wstr[0], + "ret->str[42] = %p len = %Id, ret->wstr[0] = %p\n", + ret->str[42], strlen(ret->str[42]), ret->wstr[0]); free(ret); if(!setlocale(LC_TIME, "german")) @@ -726,7 +762,7 @@ static void test__Gettnames(void) { size = GetLocaleInfoA(MAKELCID(LANG_GERMAN, SORT_DEFAULT), time_data[i], buf, sizeof(buf)); - ok(size, "GetLocaleInfo failed: %x\n", GetLastError()); + ok(size, "GetLocaleInfo failed: %lx\n", GetLastError()); ok(!strcmp(ret->str[i], buf), "ret->str[%i] = %s, expected %s\n", i, ret->str[i], buf); } free(ret); @@ -775,6 +811,178 @@ static void test___mb_cur_max_func(void) } } +static void test__wcsicmp_l(void) +{ + const struct { + const wchar_t *str1; + const wchar_t *str2; + int exp; + const char *loc; + } tests[] = { + { L"i", L"i", 0 }, + { L"I", L"i", 0 }, + { L"I", L"i", 0, "Turkish" }, + { L"i", L"a", 8 }, + { L"a", L"i", -8 }, + { L"i", L"a", 8, "Turkish" }, + }; + int ret, i; + + if (!p_wcsicmp_l || !p_create_locale) + { + win_skip("_wcsicmp_l or _create_locale not available\n"); + return; + } + ok(!!p_free_locale, "_free_locale not available\n"); + + for(i=0; ilocinfo; + locinfo2 = locale2->locinfo; + + ok(locinfo->mb_cur_max == locinfo2->mb_cur_max, "Got wrong max char size %d %d.\n", + locinfo->mb_cur_max, locinfo2->mb_cur_max); + ok(locinfo->ctype1_refcount != locinfo2->ctype1_refcount, "Got wrong refcount pointer %p vs %p.\n", + locinfo->ctype1_refcount, locinfo2->ctype1_refcount); + ok(locinfo->lc_codepage == 932 && locinfo->lc_codepage == locinfo2->lc_codepage, + "Got wrong codepage %d vs %d.\n", locinfo->lc_codepage, locinfo2->lc_codepage); + ok(locinfo->lc_id[LC_CTYPE].wCodePage == 932 + && locinfo->lc_id[LC_CTYPE].wCodePage == locinfo2->lc_id[LC_CTYPE].wCodePage, + "Got wrong LC_CTYPE codepage %d vs %d.\n", locinfo->lc_id[LC_CTYPE].wCodePage, + locinfo2->lc_id[LC_CTYPE].wCodePage); + ret = strcmp(locinfo->lc_category[LC_CTYPE].locale, locinfo2->lc_category[LC_CTYPE].locale); + ok(!!ret, "Got locale name %s vs %s.\n", locinfo->lc_category[LC_CTYPE].locale, + locinfo2->lc_category[LC_CTYPE].locale); + ret = memcmp(locinfo->ctype1, locinfo2->ctype1, 257 * sizeof(*locinfo->ctype1)); + ok(!ret, "Got wrong ctype1 data.\n"); + ret = memcmp(locinfo->pclmap, locinfo2->pclmap, 256 * sizeof(*locinfo->pclmap)); + ok(!ret, "Got wrong pclmap data.\n"); + ret = memcmp(locinfo->pcumap, locinfo2->pcumap, 256 * sizeof(*locinfo->pcumap)); + ok(!ret, "Got wrong pcumap data.\n"); + ok(locinfo->lc_handle[LC_CTYPE] != locinfo2->lc_handle[LC_CTYPE], + "Got wrong LC_CTYPE %#lx vs %#lx.\n", locinfo->lc_handle[LC_CTYPE], locinfo2->lc_handle[LC_CTYPE]); + + p_free_locale(locale2); + locale2 = p_create_locale(LC_ALL, "Japanese_Japan.1252"); + locinfo2 = locale2->locinfo; + + ok(locinfo->mb_cur_max != locinfo2->mb_cur_max, "Got wrong max char size %d %d.\n", + locinfo->mb_cur_max, locinfo2->mb_cur_max); + ok(locinfo->ctype1_refcount != locinfo2->ctype1_refcount, "Got wrong refcount pointer %p vs %p.\n", + locinfo->ctype1_refcount, locinfo2->ctype1_refcount); + ok(locinfo2->lc_codepage == 1252, "Got wrong codepage %d.\n", locinfo2->lc_codepage); + ok(locinfo2->lc_id[LC_CTYPE].wCodePage == 1252, "Got wrong LC_CTYPE codepage %d.\n", + locinfo2->lc_id[LC_CTYPE].wCodePage); + ok(locinfo->lc_codepage != locinfo2->lc_codepage, "Got wrong codepage %d vs %d.\n", + locinfo->lc_codepage, locinfo2->lc_codepage); + ok(locinfo->lc_id[LC_CTYPE].wCodePage != locinfo2->lc_id[LC_CTYPE].wCodePage, + "Got wrong LC_CTYPE codepage %d vs %d.\n", locinfo->lc_id[LC_CTYPE].wCodePage, + locinfo2->lc_id[LC_CTYPE].wCodePage); + ret = strcmp(locinfo->lc_category[LC_CTYPE].locale, locinfo2->lc_category[LC_CTYPE].locale); + ok(!!ret, "Got locale name %s vs %s.\n", locinfo->lc_category[LC_CTYPE].locale, + locinfo2->lc_category[LC_CTYPE].locale); + ret = memcmp(locinfo->ctype1, locinfo2->ctype1, 257 * sizeof(*locinfo->ctype1)); + ok(!!ret, "Got wrong ctype1 data.\n"); + ret = memcmp(locinfo->pclmap, locinfo2->pclmap, 256 * sizeof(*locinfo->pclmap)); + ok(!!ret, "Got wrong pclmap data.\n"); + ret = memcmp(locinfo->pcumap, locinfo2->pcumap, 256 * sizeof(*locinfo->pcumap)); + ok(!!ret, "Got wrong pcumap data.\n"); + ok(locinfo->lc_handle[LC_CTYPE] == locinfo2->lc_handle[LC_CTYPE], + "Got wrong LC_CTYPE %#lx vs %#lx.\n", locinfo->lc_handle[LC_CTYPE], locinfo2->lc_handle[LC_CTYPE]); + + p_free_locale(locale2); + locale2 = p_create_locale(LC_ALL, "Japanese_Japan.3000"); /* an invalid codepage */ + ok(!locale2, "Got %p.\n", locale2); + + p_free_locale(locale); + } + + locale = p_create_locale(LC_ALL, "German_Germany.437"); + locale2 = p_create_locale(LC_ALL, "German_Germany.1252"); + locinfo = locale->locinfo; + locinfo2 = locale2->locinfo; + + ok(locinfo->mb_cur_max == locinfo2->mb_cur_max, "Got wrong max char size %d %d.\n", + locinfo->mb_cur_max, locinfo2->mb_cur_max); + ok(locinfo->ctype1_refcount != locinfo2->ctype1_refcount, "Got wrong refcount pointer %p vs %p.\n", + locinfo->ctype1_refcount, locinfo2->ctype1_refcount); + ok(locinfo->lc_codepage != locinfo2->lc_codepage, "Got wrong codepage %d vs %d.\n", + locinfo->lc_codepage, locinfo2->lc_codepage); + ok(locinfo->lc_id[LC_CTYPE].wCodePage != locinfo2->lc_id[LC_CTYPE].wCodePage, + "Got wrong LC_CTYPE codepage %d vs %d.\n", locinfo->lc_id[LC_CTYPE].wCodePage, + locinfo2->lc_id[LC_CTYPE].wCodePage); + ret = strcmp(locinfo->lc_category[LC_CTYPE].locale, locinfo2->lc_category[LC_CTYPE].locale); + ok(!!ret, "Got locale name %s vs %s.\n", locinfo->lc_category[LC_CTYPE].locale, + locinfo2->lc_category[LC_CTYPE].locale); + ret = memcmp(locinfo->ctype1, locinfo2->ctype1, 257 * sizeof(*locinfo->ctype1)); + ok(!!ret, "Got wrong ctype1 data.\n"); + ret = memcmp(locinfo->pclmap, locinfo2->pclmap, 256 * sizeof(*locinfo->pclmap)); + ok(!!ret, "Got wrong pclmap data.\n"); + ret = memcmp(locinfo->pcumap, locinfo2->pcumap, 256 * sizeof(*locinfo->pcumap)); + ok(!!ret, "Got wrong pcumap data.\n"); + ok(locinfo->lc_handle[LC_CTYPE] == locinfo2->lc_handle[LC_CTYPE], + "Got wrong LC_CTYPE %#lx vs %#lx.\n", locinfo->lc_handle[LC_CTYPE], locinfo2->lc_handle[LC_CTYPE]); + + p_free_locale(locale2); + p_free_locale(locale); +} + START_TEST(locale) { init(); @@ -783,4 +991,7 @@ START_TEST(locale) test_setlocale(); test__Gettnames(); test___mb_cur_max_func(); + test__wcsicmp_l(); + test_thread_setlocale(); + test_locale_info(); } diff --git a/modules/rostests/winetests/msvcrt/misc.c b/modules/rostests/winetests/msvcrt/misc.c index d82f71e122e6f..cb7dc24e18cc1 100644 --- a/modules/rostests/winetests/msvcrt/misc.c +++ b/modules/rostests/winetests/msvcrt/misc.c @@ -20,30 +20,12 @@ #include "wine/test.h" #include +#include +#include #include #include -#include "msvcrt.h" #include - -static inline float __port_infinity(void) -{ - static const unsigned __inf_bytes = 0x7f800000; - return *(const float *)&__inf_bytes; -} -#ifdef __REACTOS__ -#undef INFINITY -#endif -#define INFINITY __port_infinity() - -static inline float __port_nan(void) -{ - static const unsigned __nan_bytes = 0x7fc00000; - return *(const float *)&__nan_bytes; -} -#ifdef __REACTOS__ -#undef NAN -#endif -#define NAN __port_nan() +#include static inline BOOL almost_equal(double d1, double d2) { if(d1-d2>-1e-30 && d1-d2<1e-30) @@ -56,14 +38,14 @@ struct uld { ULONG lo, hi, exp; }; static int (__cdecl *prand_s)(unsigned int *); static int (__cdecl *pI10_OUTPUT)(struct uld, int, int, void*); -static int (__cdecl *pstrerror_s)(char *, MSVCRT_size_t, int); +static int (__cdecl *pstrerror_s)(char *, size_t, int); static int (__cdecl *p_get_doserrno)(int *); static int (__cdecl *p_get_errno)(int *); static int (__cdecl *p_set_doserrno)(int); static int (__cdecl *p_set_errno)(int); static void (__cdecl *p__invalid_parameter)(const wchar_t*, const wchar_t*, const wchar_t*, unsigned int, uintptr_t); -static void (__cdecl *p_qsort_s)(void*, MSVCRT_size_t, MSVCRT_size_t, +static void (__cdecl *p_qsort_s)(void*, size_t, size_t, int (__cdecl*)(void*, const void*, const void*), void*); static double (__cdecl *p_atan)(double); static double (__cdecl *p_exp)(double); @@ -194,7 +176,7 @@ static void test_I10_OUTPUT(void) j = strlen(I10_OUTPUT_tests[i].remain); todo_wine_if(j && I10_OUTPUT_tests[i].remain[j-1]=='9') ok(!strncmp(out.str+out.len+1, I10_OUTPUT_tests[i].remain, j), - "%d: &out.str[%d] = %.25s...\n", i, out.len+1, out.str+out.len+1); + "%d: &out.str[%d] = %.25s...\n", i, out.len+1, out.str+out.len+1); for(j=out.len+strlen(I10_OUTPUT_tests[i].remain)+1; j= 3) { - if(!strcmp(arg_v[2], "popen")) - test__popen_child(); + if (!strcmp(arg_v[2], "popen_read")) + test__popen_read_child(); + else if(arg_c == 4 && !strcmp(arg_v[2], "popen")) + test__popen_child(atoi(arg_v[3])); else ok(0, "invalid argument '%s'\n", arg_v[2]); @@ -705,5 +777,6 @@ START_TEST(misc) test_qsort_s(); test_math_functions(); test_thread_handle_close(); + test_thread_suspended(); test__lfind_s(); } diff --git a/modules/rostests/winetests/msvcrt/printf.c b/modules/rostests/winetests/msvcrt/printf.c index 4bf55afc1ffa4..ec314544c988a 100644 --- a/modules/rostests/winetests/msvcrt/printf.c +++ b/modules/rostests/winetests/msvcrt/printf.c @@ -23,9 +23,7 @@ /* With Visual Studio >= 2005, swprintf() takes an extra parameter unless * the following macro is defined. */ -#ifndef _CRT_NON_CONFORMING_SWPRINTFS #define _CRT_NON_CONFORMING_SWPRINTFS -#endif #include #include @@ -38,24 +36,6 @@ #include "wine/test.h" -#ifndef __REACTOS__ - -static inline float __port_infinity(void) -{ - static const unsigned __inf_bytes = 0x7f800000; - return *(const float *)&__inf_bytes; -} -#define INFINITY __port_infinity() - -static inline float __port_nan(void) -{ - static const unsigned __nan_bytes = 0x7fc00000; - return *(const float *)&__nan_bytes; -} -#define NAN __port_nan() - -#endif - static inline float __port_ind(void) { static const unsigned __ind_bytes = 0xffc00000; @@ -63,11 +43,11 @@ static inline float __port_ind(void) } #define IND __port_ind() -static int (__cdecl *p__vscprintf)(const char *format, __ms_va_list valist); -static int (__cdecl *p__vscwprintf)(const wchar_t *format, __ms_va_list valist); +static int (__cdecl *p__vscprintf)(const char *format, va_list valist); +static int (__cdecl *p__vscwprintf)(const wchar_t *format, va_list valist); static int (__cdecl *p__vsnwprintf_s)(wchar_t *str, size_t sizeOfBuffer, size_t count, const wchar_t *format, - __ms_va_list valist); + va_list valist); static int (__cdecl *p__ecvt_s)(char *buffer, size_t length, double number, int ndigits, int *decpt, int *sign); static int (__cdecl *p__fcvt_s)(char *buffer, size_t length, double number, @@ -75,17 +55,17 @@ static int (__cdecl *p__fcvt_s)(char *buffer, size_t length, double number, static unsigned int (__cdecl *p__get_output_format)(void); static unsigned int (__cdecl *p__set_output_format)(unsigned int); static int (WINAPIV *p_sprintf)(char*, ...); -static int (__cdecl *p__vsprintf_p)(char*, size_t, const char*, __ms_va_list); -static int (__cdecl *p_vswprintf)(wchar_t *str, const wchar_t *format, __ms_va_list valist); -static int (__cdecl *p__vswprintf)(wchar_t *str, const wchar_t *format, __ms_va_list valist); +static int (__cdecl *p__vsprintf_p)(char*, size_t, const char*, va_list); +static int (__cdecl *p_vswprintf)(wchar_t *str, const wchar_t *format, va_list valist); +static int (__cdecl *p__vswprintf)(wchar_t *str, const wchar_t *format, va_list valist); static int (__cdecl *p__vswprintf_l)(wchar_t *str, const wchar_t *format, - void *locale, __ms_va_list valist); + void *locale, va_list valist); static int (__cdecl *p__vswprintf_c)(wchar_t *str, size_t size, const wchar_t *format, - __ms_va_list valist); + va_list valist); static int (__cdecl *p__vswprintf_c_l)(wchar_t *str, size_t size, const wchar_t *format, - void *locale, __ms_va_list valist); + void *locale, va_list valist); static int (__cdecl *p__vswprintf_p_l)(wchar_t *str, size_t size, const wchar_t *format, - void *locale, __ms_va_list valist); + void *locale, va_list valist); static void init( void ) { @@ -110,466 +90,295 @@ static void init( void ) static void test_sprintf( void ) { - char buffer[100]; - const char *format; - double pnumber=789456123; - int x, r; - WCHAR wide[] = { 'w','i','d','e',0}; - WCHAR buf_w[2]; - - format = "%+#23.15e"; - r = p_sprintf(buffer,format,pnumber); - ok(!strcmp(buffer,"+7.894561230000000e+008"),"+#23.15e failed: '%s'\n", buffer); - ok( r==23, "return count wrong\n"); - - format = "%-#23.15e"; - r = p_sprintf(buffer,format,pnumber); - ok(!strcmp(buffer,"7.894561230000000e+008 "),"-#23.15e failed: '%s'\n", buffer); - ok( r==23, "return count wrong\n"); - - format = "%#23.15e"; - r = p_sprintf(buffer,format,pnumber); - ok(!strcmp(buffer," 7.894561230000000e+008"),"#23.15e failed: '%s'\n", buffer); - ok( r==23, "return count wrong\n"); - - format = "%#1.1g"; - r = p_sprintf(buffer,format,pnumber); - ok(!strcmp(buffer,"8.e+008"),"#1.1g failed: '%s'\n", buffer); - ok( r==7, "return count wrong\n"); - - format = "%I64d"; - r = p_sprintf(buffer,format,((ULONGLONG)0xffffffff)*0xffffffff); - ok(!strcmp(buffer,"-8589934591"),"Problem with long long\n"); - ok( r==11, "return count wrong\n"); - - format = "%+8I64d"; - r = p_sprintf(buffer,format,(LONGLONG)100); - ok(!strcmp(buffer," +100") && r==8,"+8I64d failed: '%s'\n", buffer); - - format = "%+.8I64d"; - r = p_sprintf(buffer,format,(LONGLONG)100); - ok(!strcmp(buffer,"+00000100") && r==9,"+.8I64d failed: '%s'\n", buffer); - - format = "%+10.8I64d"; - r = p_sprintf(buffer,format,(LONGLONG)100); - ok(!strcmp(buffer," +00000100") && r==10,"+10.8I64d failed: '%s'\n", buffer); - format = "%_1I64d"; - r = p_sprintf(buffer,format,(LONGLONG)100); - ok(!strcmp(buffer,"_1I64d") && r==6,"_1I64d failed\n"); - - format = "%-1.5I64d"; - r = p_sprintf(buffer,format,(LONGLONG)-100); - ok(!strcmp(buffer,"-00100") && r==6,"-1.5I64d failed: '%s'\n", buffer); - - format = "%5I64d"; - r = p_sprintf(buffer,format,(LONGLONG)100); - ok(!strcmp(buffer," 100") && r==5,"5I64d failed: '%s'\n", buffer); - - format = "%5I64d"; - r = p_sprintf(buffer,format,(LONGLONG)-100); - ok(!strcmp(buffer," -100") && r==5,"5I64d failed: '%s'\n", buffer); - - format = "%-5I64d"; - r = p_sprintf(buffer,format,(LONGLONG)100); - ok(!strcmp(buffer,"100 ") && r==5,"-5I64d failed: '%s'\n", buffer); - - format = "%-5I64d"; - r = p_sprintf(buffer,format,(LONGLONG)-100); - ok(!strcmp(buffer,"-100 ") && r==5,"-5I64d failed: '%s'\n", buffer); - - format = "%-.5I64d"; - r = p_sprintf(buffer,format,(LONGLONG)100); - ok(!strcmp(buffer,"00100") && r==5,"-.5I64d failed: '%s'\n", buffer); - - format = "%-.5I64d"; - r = p_sprintf(buffer,format,(LONGLONG)-100); - ok(!strcmp(buffer,"-00100") && r==6,"-.5I64d failed: '%s'\n", buffer); - - format = "%-8.5I64d"; - r = p_sprintf(buffer,format,(LONGLONG)100); - ok(!strcmp(buffer,"00100 ") && r==8,"-8.5I64d failed: '%s'\n", buffer); - - format = "%-8.5I64d"; - r = p_sprintf(buffer,format,(LONGLONG)-100); - ok(!strcmp(buffer,"-00100 ") && r==8,"-8.5I64d failed: '%s'\n", buffer); - - format = "%05I64d"; - r = p_sprintf(buffer,format,(LONGLONG)100); - ok(!strcmp(buffer,"00100") && r==5,"05I64d failed: '%s'\n", buffer); - - format = "%05I64d"; - r = p_sprintf(buffer,format,(LONGLONG)-100); - ok(!strcmp(buffer,"-0100") && r==5,"05I64d failed: '%s'\n", buffer); - - format = "% I64d"; - r = p_sprintf(buffer,format,(LONGLONG)100); - ok(!strcmp(buffer," 100") && r==4,"' I64d' failed: '%s'\n", buffer); - - format = "% I64d"; - r = p_sprintf(buffer,format,(LONGLONG)-100); - ok(!strcmp(buffer,"-100") && r==4,"' I64d' failed: '%s'\n", buffer); - - format = "% 5I64d"; - r = p_sprintf(buffer,format,(LONGLONG)100); - ok(!strcmp(buffer," 100") && r==5,"' 5I64d' failed: '%s'\n", buffer); - - format = "% 5I64d"; - r = p_sprintf(buffer,format,(LONGLONG)-100); - ok(!strcmp(buffer," -100") && r==5,"' 5I64d' failed: '%s'\n", buffer); - - format = "% .5I64d"; - r = p_sprintf(buffer,format,(LONGLONG)100); - ok(!strcmp(buffer," 00100") && r==6,"' .5I64d' failed: '%s'\n", buffer); - - format = "% .5I64d"; - r = p_sprintf(buffer,format,(LONGLONG)-100); - ok(!strcmp(buffer,"-00100") && r==6,"' .5I64d' failed: '%s'\n", buffer); - - format = "% 8.5I64d"; - r = p_sprintf(buffer,format,(LONGLONG)100); - ok(!strcmp(buffer," 00100") && r==8,"' 8.5I64d' failed: '%s'\n", buffer); - - format = "% 8.5I64d"; - r = p_sprintf(buffer,format,(LONGLONG)-100); - ok(!strcmp(buffer," -00100") && r==8,"' 8.5I64d' failed: '%s'\n", buffer); - - format = "%.0I64d"; - r = p_sprintf(buffer,format,(LONGLONG)0); - ok(r==0,".0I64d failed: '%s'\n", buffer); - - format = "%#+21.18I64x"; - r = p_sprintf(buffer,format,(LONGLONG)-100); - ok(!strcmp(buffer," 0x00ffffffffffffff9c") && r==21,"#+21.18I64x failed: '%s'\n", buffer); - - format = "%#.25I64o"; - r = p_sprintf(buffer,format,(LONGLONG)-100); - ok(!strcmp(buffer,"0001777777777777777777634") && r==25,"#.25I64o failed: '%s'\n", buffer); - - format = "%#+24.20I64o"; - r = p_sprintf(buffer,format,(LONGLONG)-100); - ok(!strcmp(buffer," 01777777777777777777634") && r==24,"#+24.20I64o failed: '%s'\n", buffer); - - format = "%#+18.21I64X"; - r = p_sprintf(buffer,format,(LONGLONG)-100); - ok(!strcmp(buffer,"0X00000FFFFFFFFFFFFFF9C") && r==23,"#+18.21I64X failed: '%s '\n", buffer); - - format = "%#+20.24I64o"; - r = p_sprintf(buffer,format,(LONGLONG)-100); - ok(!strcmp(buffer,"001777777777777777777634") && r==24,"#+20.24I64o failed: '%s'\n", buffer); - - format = "%#+25.22I64u"; - r = p_sprintf(buffer,format,(LONGLONG)-1); - ok(!strcmp(buffer," 0018446744073709551615") && r==25,"#+25.22I64u conversion failed: '%s'\n", buffer); - - format = "%#+25.22I64u"; - r = p_sprintf(buffer,format,(LONGLONG)-1); - ok(!strcmp(buffer," 0018446744073709551615") && r==25,"#+25.22I64u failed: '%s'\n", buffer); - - format = "%#+30.25I64u"; - r = p_sprintf(buffer,format,(LONGLONG)-1); - ok(!strcmp(buffer," 0000018446744073709551615") && r==30,"#+30.25I64u failed: '%s'\n", buffer); - - format = "%+#25.22I64d"; - r = p_sprintf(buffer,format,(LONGLONG)-1); - ok(!strcmp(buffer," -0000000000000000000001") && r==25,"+#25.22I64d failed: '%s'\n", buffer); - - format = "%#-8.5I64o"; - r = p_sprintf(buffer,format,(LONGLONG)100); - ok(!strcmp(buffer,"00144 ") && r==8,"-8.5I64o failed: '%s'\n", buffer); - - format = "%#-+ 08.5I64d"; - r = p_sprintf(buffer,format,(LONGLONG)100); - ok(!strcmp(buffer,"+00100 ") && r==8,"'#-+ 08.5I64d failed: '%s'\n", buffer); - - format = "%#-+ 08.5I64d"; - r = p_sprintf(buffer,format,(LONGLONG)100); - ok(!strcmp(buffer,"+00100 ") && r==8,"#-+ 08.5I64d failed: '%s'\n", buffer); - - format = "%.80I64d"; - r = p_sprintf(buffer,format,(LONGLONG)1); - ok(r==80,"%s format failed\n", format); - - format = "% .80I64d"; - r = p_sprintf(buffer,format,(LONGLONG)1); - ok(r==81,"%s format failed\n", format); - - format = "% .80d"; - r = p_sprintf(buffer,format,1); - ok(r==81,"%s format failed\n", format); - - format = "%lld"; - r = p_sprintf(buffer,format,((ULONGLONG)0xffffffff)*0xffffffff); - ok( r == 1 || r == 11, "return count wrong %d\n", r); - if (r == 11) /* %ll works on Vista */ - ok(!strcmp(buffer, "-8589934591"), "Problem with \"ll\" interpretation '%s'\n", buffer); - else - ok(!strcmp(buffer, "1"), "Problem with \"ll\" interpretation '%s'\n", buffer); + enum { + NO_ARG, + INT_ARG, + ULONGLONG_ARG, + DOUBLE_ARG, + PTR_ARG, + TODO_FLAG = 0x1000 + }; - format = "%I"; - r = p_sprintf(buffer,format,1); - ok(!strcmp(buffer, "I"), "Problem with \"I\" interpretation\n"); - ok( r==1, "return count wrong\n"); + struct { + const char *format; + const char *out; + const char *broken; + int type; + int arg_i; + ULONGLONG arg_ull; + double arg_d; + const void *arg_ptr; + } tests[] = { + { "%+#23.15e", "+7.894561230000000e+008", 0, DOUBLE_ARG, 0, 0, 789456123 }, + { "%-#23.15e", "7.894561230000000e+008 ", 0, DOUBLE_ARG, 0, 0, 789456123 }, + { "%#23.15e", " 7.894561230000000e+008", 0, DOUBLE_ARG, 0, 0, 789456123 }, + { "%#1.1g", "8.e+008", 0, DOUBLE_ARG, 0, 0, 789456123 }, + { "%I64d", "-8589934591", 0, ULONGLONG_ARG, 0, ((ULONGLONG)0xffffffff)*0xffffffff }, + { "%+8I64d", " +100", 0, ULONGLONG_ARG, 0, 100 }, + { "%+.8I64d", "+00000100", 0, ULONGLONG_ARG, 0, 100 }, + { "%+10.8I64d", " +00000100", 0, ULONGLONG_ARG, 0, 100 }, + { "%_1I64d", "_1I64d", 0, ULONGLONG_ARG, 0, 100 }, + { "%-1.5I64d", "-00100", 0, ULONGLONG_ARG, 0, -100 }, + { "%5I64d", " 100", 0, ULONGLONG_ARG, 0, 100 }, + { "%5I64d", " -100", 0, ULONGLONG_ARG, 0, -100 }, + { "%-5I64d", "100 ", 0, ULONGLONG_ARG, 0, 100 }, + { "%-5I64d", "-100 ", 0, ULONGLONG_ARG, 0, -100 }, + { "%-.5I64d", "00100", 0, ULONGLONG_ARG, 0, 100 }, + { "%-.5I64d", "-00100", 0, ULONGLONG_ARG, 0, -100 }, + { "%-8.5I64d", "00100 ", 0, ULONGLONG_ARG, 0, 100 }, + { "%-8.5I64d", "-00100 ", 0, ULONGLONG_ARG, 0, -100 }, + { "%05I64d", "00100", 0, ULONGLONG_ARG, 0, 100 }, + { "%05I64d", "-0100", 0, ULONGLONG_ARG, 0, -100 }, + { "% I64d", " 100", 0, ULONGLONG_ARG, 0, 100 }, + { "% I64d", "-100", 0, ULONGLONG_ARG, 0, -100 }, + { "% 5I64d", " 100", 0, ULONGLONG_ARG, 0, 100 }, + { "% 5I64d", " -100", 0, ULONGLONG_ARG, 0, -100 }, + { "% .5I64d", " 00100", 0, ULONGLONG_ARG, 0, 100 }, + { "% .5I64d", "-00100", 0, ULONGLONG_ARG, 0, -100 }, + { "% 8.5I64d", " 00100", 0, ULONGLONG_ARG, 0, 100 }, + { "% 8.5I64d", " -00100", 0, ULONGLONG_ARG, 0, -100 }, + { "%.0I64d", "", 0, ULONGLONG_ARG }, + { "%#+21.18I64x", " 0x00ffffffffffffff9c", 0, ULONGLONG_ARG, 0, -100 }, + { "%#.25I64o", "0001777777777777777777634", 0, ULONGLONG_ARG, 0, -100 }, + { "%#+24.20I64o", " 01777777777777777777634", 0, ULONGLONG_ARG, 0, -100 }, + { "%#+18.21I64X", "0X00000FFFFFFFFFFFFFF9C", 0, ULONGLONG_ARG, 0, -100 }, + { "%#+20.24I64o", "001777777777777777777634", 0, ULONGLONG_ARG, 0, -100 }, + { "%#+25.22I64u", " 0018446744073709551615", 0, ULONGLONG_ARG, 0, -1 }, + { "%#+25.22I64u", " 0018446744073709551615", 0, ULONGLONG_ARG, 0, -1 }, + { "%#+30.25I64u", " 0000018446744073709551615", 0, ULONGLONG_ARG, 0, -1 }, + { "%+#25.22I64d", " -0000000000000000000001", 0, ULONGLONG_ARG, 0, -1 }, + { "%#-8.5I64o", "00144 ", 0, ULONGLONG_ARG, 0, 100 }, + { "%#-+ 08.5I64d", "+00100 ", 0, ULONGLONG_ARG, 0, 100 }, + { "%.80I64d", + "00000000000000000000000000000000000000000000000000000000000000000000000000000001", + 0, ULONGLONG_ARG, 0, 1 }, + { "% .80I64d", + " 00000000000000000000000000000000000000000000000000000000000000000000000000000001", + 0, ULONGLONG_ARG, 0, 1 }, + { "% .80d", + " 00000000000000000000000000000000000000000000000000000000000000000000000000000001", + 0, INT_ARG, 1 }, + { "%I", "I", 0, INT_ARG, 1 }, + { "%Iq", "Iq", 0, INT_ARG, 1 }, + { "%Ihd", "Ihd", 0, INT_ARG, 1 }, + { "%I0d", "I0d", 0, INT_ARG, 1 }, + { "%I64D", "D", 0, ULONGLONG_ARG, 0, -1 }, + { "%zx", "1", "zx", INT_ARG, 1 }, + { "%z", "z", 0, INT_ARG, 1 }, + { "%tx", "1", "tx", INT_ARG, 1 }, + { "%t", "t", 0, INT_ARG, 1 }, + { "% d", " 1", 0, INT_ARG, 1 }, + { "%+ d", "+1", 0, INT_ARG, 1 }, + { "%S", "wide", 0, PTR_ARG, 0, 0, 0, L"wide" }, + { "%04c", "0001", 0, INT_ARG, '1' }, + { "%-04c", "1 ", 0, INT_ARG, '1' }, + { "%#012x", "0x0000000001", 0, INT_ARG, 1 }, + { "%#012x", "000000000000", 0, INT_ARG, 0 }, + { "%#04.8x", "0x00000001", 0, INT_ARG, 1 }, + { "%#04.8x", "00000000", 0, INT_ARG, 0 }, + { "%#-08.2x", "0x01 ", 0, INT_ARG, 1 }, + { "%#-08.2x", "00 ", 0, INT_ARG, 0 }, + { "%#.0x", "0x1", 0, INT_ARG, 1 }, + { "%#.0x", "", 0, INT_ARG, 0 }, + { "%#08o", "00000001", 0, INT_ARG, 1 }, + { "%#o", "01", 0, INT_ARG, 1 }, + { "%#o", "0", 0, INT_ARG, 0 }, + { "%04s", "0foo", 0, PTR_ARG, 0, 0, 0, "foo" }, + { "%.1s", "f", 0, PTR_ARG, 0, 0, 0, "foo" }, + { "hello", "hello", 0, NO_ARG }, + { "%ws", "wide", 0, PTR_ARG, 0, 0, 0, L"wide" }, + { "%-10ws", "wide ", 0, PTR_ARG, 0, 0, 0, L"wide" }, + { "%10ws", " wide", 0, PTR_ARG, 0, 0, 0, L"wide" }, + { "%#+ -03whlls", "wide", 0, PTR_ARG, 0, 0, 0, L"wide" }, + { "%w0s", "0s", 0, PTR_ARG, 0, 0, 0, L"wide" }, + { "%w-s", "-s", 0, PTR_ARG, 0, 0, 0, L"wide" }, + { "%ls", "wide", 0, PTR_ARG, 0, 0, 0, L"wide" }, + { "%Ls", "not wide", 0, PTR_ARG, 0, 0, 0, "not wide" }, + { "%b", "b", 0, NO_ARG }, + { "%3c", " a", 0, INT_ARG, 'a' }, + { "%3d", "1234", 0, INT_ARG, 1234 }, + { "%3h", "", 0, NO_ARG }, + { "%k%m%q%r%t%v%y%z", "kmqrtvyz", 0, NO_ARG }, + { "%-1d", "2", 0, INT_ARG, 2 }, + { "%2.4f", "8.6000", 0, DOUBLE_ARG, 0, 0, 8.6 }, + { "%0f", "0.600000", 0, DOUBLE_ARG, 0, 0, 0.6 }, + { "%.0f", "1", 0, DOUBLE_ARG, 0, 0, 0.6 }, + { "%2.4e", "8.6000e+000", 0, DOUBLE_ARG, 0, 0, 8.6 }, + { "% 2.4e", " 8.6000e+000", 0, DOUBLE_ARG, 0, 0, 8.6 }, + { "% 014.4e", " 008.6000e+000", 0, DOUBLE_ARG, 0, 0, 8.6 }, + { "% 2.4e", "-8.6000e+000", 0, DOUBLE_ARG, 0, 0, -8.6 }, + { "%+2.4e", "+8.6000e+000", 0, DOUBLE_ARG, 0, 0, 8.6 }, + { "%2.4g", "8.6", 0, DOUBLE_ARG, 0, 0, 8.6 }, + { "%-i", "-1", 0, INT_ARG, -1 }, + { "%-i", "1", 0, INT_ARG, 1 }, + { "%+i", "+1", 0, INT_ARG, 1 }, + { "%o", "12", 0, INT_ARG, 10 }, + { "%s", "(null)", 0, PTR_ARG, 0, 0, 0, NULL }, + { "%s", "%%%%", 0, PTR_ARG, 0, 0, 0, "%%%%" }, + { "%u", "4294967295", 0, INT_ARG, -1 }, + { "%w", "", 0, INT_ARG, -1 }, + { "%h", "", 0, INT_ARG, -1 }, + { "%j", "", "j", ULONGLONG_ARG, 0, -1 }, + { "%jd", "-1", "jd", ULONGLONG_ARG, 0, -1 }, + { "%F", "", 0, INT_ARG, -1 }, + { "%N", "", 0, INT_ARG, -1 }, + { "%H", "H", 0, INT_ARG, -1 }, + { "x%cx", "xXx", 0, INT_ARG, 0x100+'X' }, + { "%%0", "%0", 0, NO_ARG }, + { "%hx", "2345", 0, INT_ARG, 0x12345 }, + { "%hhx", "123", 0, INT_ARG, 0x123 }, + { "%hhx", "2345", 0, INT_ARG, 0x12345 }, + { "%lf", "-1.#IND00", 0, DOUBLE_ARG, 0, 0, IND }, + { "%lf", "1.#QNAN0", 0, DOUBLE_ARG, 0, 0, NAN }, + { "%lf", "1.#INF00", 0, DOUBLE_ARG, 0, 0, INFINITY }, + { "%le", "-1.#IND00e+000", 0, DOUBLE_ARG, 0, 0, IND }, + { "%le", "1.#QNAN0e+000", 0, DOUBLE_ARG, 0, 0, NAN }, + { "%le", "1.#INF00e+000", 0, DOUBLE_ARG, 0, 0, INFINITY }, + { "%lg", "-1.#IND", 0, DOUBLE_ARG, 0, 0, IND }, + { "%lg", "1.#QNAN", 0, DOUBLE_ARG, 0, 0, NAN }, + { "%lg", "1.#INF", 0, DOUBLE_ARG, 0, 0, INFINITY }, + { "%010.2lf", "-000001.#J", 0, DOUBLE_ARG, 0, 0, IND }, + { "%010.2lf", "0000001.#R", 0, DOUBLE_ARG, 0, 0, NAN }, + { "%010.2lf", "0000001.#J", 0, DOUBLE_ARG, 0, 0, INFINITY }, + { "%c", "a", 0, INT_ARG, 'a' }, + { "%c", "\x82", 0, INT_ARG, 0xa082 }, + { "%C", "a", 0, INT_ARG, 'a' }, + { "%C", "", 0, INT_ARG, 0x3042 }, + { "a%Cb", "ab", 0, INT_ARG, 0x3042 }, + { "%lld", "-8589934591", "1", ULONGLONG_ARG, 0, ((ULONGLONG)0xffffffff)*0xffffffff }, + { "%I32d", "1", "I32d", INT_ARG, 1 }, + { "%.0f", "-2", 0, DOUBLE_ARG, 0, 0, -1.5 }, + { "%.0f", "-1", 0, DOUBLE_ARG, 0, 0, -0.5 }, + { "%.0f", "1", 0, DOUBLE_ARG, 0, 0, 0.5 }, + { "%.0f", "2", 0, DOUBLE_ARG, 0, 0, 1.5 }, + { "%.30f", "0.333333333333333310000000000000", 0, TODO_FLAG | DOUBLE_ARG, 0, 0, 1.0/3.0 }, + { "%.30lf", "1.414213562373095100000000000000", 0, TODO_FLAG | DOUBLE_ARG, 0, 0, sqrt(2) }, + { "%f", "3.141593", 0, DOUBLE_ARG, 0, 0, 3.141592653590000 }, + { "%.10f", "3.1415926536", 0, DOUBLE_ARG, 0, 0, 3.141592653590000 }, + { "%.11f", "3.14159265359", 0, DOUBLE_ARG, 0, 0, 3.141592653590000 }, + { "%.15f", "3.141592653590000", 0, DOUBLE_ARG, 0, 0, 3.141592653590000 }, + { "%.15f", "3.141592653589793", 0, DOUBLE_ARG, 0, 0, M_PI }, + { "%.13f", "37.8662615745371", 0, DOUBLE_ARG, 0, 0, 37.866261574537077 }, + { "%.14f", "37.86626157453708", 0, DOUBLE_ARG, 0, 0, 37.866261574537077 }, + { "%.15f", "37.866261574537077", 0, DOUBLE_ARG, 0, 0, 37.866261574537077 }, + { "%g", "0.0005", 0, DOUBLE_ARG, 0, 0, 0.0005 }, + { "%g", "5e-005", 0, DOUBLE_ARG, 0, 0, 0.00005 }, + { "%g", "5e-006", 0, DOUBLE_ARG, 0, 0, 0.000005 }, + { "%g", "1e+015", 0, DOUBLE_ARG, 0, 0, 999999999999999.0 }, + { "%g", "1e+015", 0, DOUBLE_ARG, 0, 0, 1000000000000000.0 }, + { "%.15g", "0.0005", 0, DOUBLE_ARG, 0, 0, 0.0005 }, + { "%.15g", "5e-005", 0, DOUBLE_ARG, 0, 0, 0.00005 }, + { "%.15g", "5e-006", 0, DOUBLE_ARG, 0, 0, 0.000005 }, + { "%.15g", "999999999999999", 0, DOUBLE_ARG, 0, 0, 999999999999999.0 }, + { "%.15g", "1e+015", 0, DOUBLE_ARG, 0, 0, 1000000000000000.0 }, + }; - format = "%I0d"; - r = p_sprintf(buffer,format,1); - ok(!strcmp(buffer,"I0d"),"I0d failed\n"); - ok( r==3, "return count wrong\n"); + char buffer[100]; + int i, x, r; + + for (i=0; i 1.0 with 0 or -ve precision */ + { -0.0, 5, "00000", "00000", 0, 0, 1 }, + { -0.0, 0, "", "", 0, 0, 1 }, + { -0.0, -1, "", "", 0, 0, 1 }, { -123.0001, 0, "", "123", 3, 3, 1 }, { -123.0001, -1, "", "12", 3, 3, 1 }, { -123.0001, -2, "", "1", 3, 3, 1 }, { -123.0001, -3, "", "", 3, 3, 1 }, - /* Numbers > 1.0, but with rounding at the point of precision */ { 99.99, 1, "1", "1000", 3, 3, 0 }, - /* Numbers < 1.0 where rounding occurs at the point of precision */ { 0.0063, 2, "63", "1", -2, -1, 0 }, { 0.0063, 3, "630", "6", -2, -2, 0 }, { 0.09999999996, 2, "10", "10", 0, 0, 0 }, @@ -1105,12 +691,18 @@ static struct { { 0.4, 0, "", "", 0, 0, 0 }, { 0.49, 0, "", "", 0, 0, 0 }, { 0.51, 0, "", "1", 1, 1, 0 }, - /* ask for ridiculous precision, ruin formatting this table */ + { NAN, 2, "1$", "1#R", 1, 1, 0 }, + { NAN, 5, "1#QNB", "1#QNAN", 1, 1, 0 }, + { -NAN, 2, "1$", "1#J", 1, 1, 1 }, + { -NAN, 5, "1#IND", "1#IND0", 1, 1, 1 }, + { INFINITY, 2, "1$", "1#J", 1, 1, 0 }, + { INFINITY, 5, "1#INF", "1#INF0", 1, 1, 0 }, + { -INFINITY, 2, "1$", "1#J", 1, 1, 1 }, + { -INFINITY, 5, "1#INF", "1#INF0", 1, 1, 1 }, { 1.0, 30, "100000000000000000000000000000", "1000000000000000000000000000000", 1, 1, 0}, { 123456789012345678901.0, 30, "123456789012345680000000000000", "123456789012345680000000000000000000000000000000000", 21, 21, 0}, - /* end marker */ { 0, 0, "END"} }; @@ -1125,14 +717,19 @@ static void test_xcvt(void) test_cvt_testcases[i].nrdigits, &decpt, &sign); - ok( 0 == strncmp( str, test_cvt_testcases[i].expstr_e, 15), - "_ecvt() bad return, got \n'%s' expected \n'%s'\n", str, + ok( !strncmp( str, test_cvt_testcases[i].expstr_e, 15), + "%d) _ecvt() bad return, got '%s' expected '%s'\n", i, str, test_cvt_testcases[i].expstr_e); ok( decpt == test_cvt_testcases[i].expdecpt_e, - "_ecvt() decimal point wrong, got %d expected %d\n", decpt, + "%d) _ecvt() decimal point wrong, got %d expected %d\n", i, decpt, test_cvt_testcases[i].expdecpt_e); + if (((i == 10) || (i == 11) || (i == 12)) && (_winver < 0x600)) + { + skip("broken on win 2003\n"); + continue; + } ok( sign == test_cvt_testcases[i].expsign, - "_ecvt() sign wrong, got %d expected %d\n", sign, + "%d) _ecvt() sign wrong, got %d expected %d\n", i, sign, test_cvt_testcases[i].expsign); } for( i = 0; strcmp( test_cvt_testcases[i].expstr_e, "END"); i++){ @@ -1141,14 +738,19 @@ static void test_xcvt(void) test_cvt_testcases[i].nrdigits, &decpt, &sign); - ok( 0 == strncmp( str, test_cvt_testcases[i].expstr_f, 15), - "_fcvt() bad return, got \n'%s' expected \n'%s'\n", str, + ok( !strncmp( str, test_cvt_testcases[i].expstr_f, 15), + "%d) _fcvt() bad return, got '%s' expected '%s'\n", i, str, test_cvt_testcases[i].expstr_f); ok( decpt == test_cvt_testcases[i].expdecpt_f, - "_fcvt() decimal point wrong, got %d expected %d\n", decpt, + "%d) _fcvt() decimal point wrong, got %d expected %d\n", i, decpt, test_cvt_testcases[i].expdecpt_f); + if (((i == 10) || (i == 11) || (i == 12)) && (_winver < 0x600)) + { + skip("broken on win 2003\n"); + continue; + } ok( sign == test_cvt_testcases[i].expsign, - "_fcvt() sign wrong, got %d expected %d\n", sign, + "%d) _fcvt() sign wrong, got %d expected %d\n", i, sign, test_cvt_testcases[i].expsign); } @@ -1159,14 +761,14 @@ static void test_xcvt(void) decpt = sign = 100; err = p__ecvt_s(str, 1024, test_cvt_testcases[i].value, test_cvt_testcases[i].nrdigits, &decpt, &sign); ok(err == 0, "_ecvt_s() failed with error code %d\n", err); - ok( 0 == strncmp( str, test_cvt_testcases[i].expstr_e, 15), - "_ecvt_s() bad return, got \n'%s' expected \n'%s'\n", str, + ok( !strncmp( str, test_cvt_testcases[i].expstr_e, 15), + "%d) _ecvt_s() bad return, got '%s' expected '%s'\n", i, str, test_cvt_testcases[i].expstr_e); ok( decpt == test_cvt_testcases[i].expdecpt_e, - "_ecvt_s() decimal point wrong, got %d expected %d\n", decpt, + "%d) _ecvt_s() decimal point wrong, got %d expected %d\n", i, decpt, test_cvt_testcases[i].expdecpt_e); ok( sign == test_cvt_testcases[i].expsign, - "_ecvt_s() sign wrong, got %d expected %d\n", sign, + "%d) _ecvt_s() sign wrong, got %d expected %d\n", i, sign, test_cvt_testcases[i].expsign); } free(str); @@ -1203,15 +805,15 @@ static void test_xcvt(void) for( i = 0; strcmp( test_cvt_testcases[i].expstr_e, "END"); i++){ decpt = sign = 100; err = p__fcvt_s(str, 1024, test_cvt_testcases[i].value, test_cvt_testcases[i].nrdigits, &decpt, &sign); - ok(err == 0, "_fcvt_s() failed with error code %d\n", err); - ok( 0 == strncmp( str, test_cvt_testcases[i].expstr_f, 15), - "_fcvt_s() bad return, got '%s' expected '%s'. test %d\n", str, + ok(!err, "%d) _fcvt_s() failed with error code %d\n", i, err); + ok( !strncmp( str, test_cvt_testcases[i].expstr_f, 15), + "%d) _fcvt_s() bad return, got '%s' expected '%s'. test %d\n", i, str, test_cvt_testcases[i].expstr_f, i); ok( decpt == test_cvt_testcases[i].expdecpt_f, - "_fcvt_s() decimal point wrong, got %d expected %d\n", decpt, + "%d) _fcvt_s() decimal point wrong, got %d expected %d\n", i, decpt, test_cvt_testcases[i].expdecpt_f); ok( sign == test_cvt_testcases[i].expsign, - "_fcvt_s() sign wrong, got %d expected %d\n", sign, + "%d) _fcvt_s() sign wrong, got %d expected %d\n", i, sign, test_cvt_testcases[i].expsign); } free(str); @@ -1223,104 +825,94 @@ static void test_xcvt(void) static int WINAPIV _vsnwprintf_wrapper(wchar_t *str, size_t len, const wchar_t *format, ...) { int ret; - __ms_va_list valist; - __ms_va_start(valist, format); + va_list valist; + va_start(valist, format); ret = _vsnwprintf(str, len, format, valist); - __ms_va_end(valist); + va_end(valist); return ret; } static void test_vsnwprintf(void) { - const wchar_t format[] = {'%','w','s','%','w','s','%','w','s',0}; - const wchar_t one[] = {'o','n','e',0}; - const wchar_t two[] = {'t','w','o',0}; - const wchar_t three[] = {'t','h','r','e','e',0}; - int ret; wchar_t str[32]; char buf[32]; - ret = _vsnwprintf_wrapper( str, ARRAY_SIZE(str), format, one, two, three ); - + ret = _vsnwprintf_wrapper( str, ARRAY_SIZE(str), L"%ws%ws%ws", L"one", L"two", L"three" ); ok( ret == 11, "got %d expected 11\n", ret ); WideCharToMultiByte( CP_ACP, 0, str, -1, buf, sizeof(buf), NULL, NULL ); ok( !strcmp(buf, "onetwothree"), "got %s expected 'onetwothree'\n", buf ); - ret = _vsnwprintf_wrapper( str, 0, format, one, two, three ); + ret = _vsnwprintf_wrapper( str, 0, L"%ws%ws%ws", L"one", L"two", L"three" ); ok( ret == -1, "got %d, expected -1\n", ret ); - ret = _vsnwprintf_wrapper( NULL, 0, format, one, two, three ); + ret = _vsnwprintf_wrapper( NULL, 0, L"%ws%ws%ws", L"one", L"two", L"three" ); ok( ret == 11 || broken(ret == -1 /* Win2k */), "got %d, expected 11\n", ret ); } static int WINAPIV vswprintf_wrapper(wchar_t *str, const wchar_t *format, ...) { int ret; - __ms_va_list valist; - __ms_va_start(valist, format); + va_list valist; + va_start(valist, format); ret = p_vswprintf(str, format, valist); - __ms_va_end(valist); + va_end(valist); return ret; } static int WINAPIV _vswprintf_wrapper(wchar_t *str, const wchar_t *format, ...) { int ret; - __ms_va_list valist; - __ms_va_start(valist, format); + va_list valist; + va_start(valist, format); ret = p__vswprintf(str, format, valist); - __ms_va_end(valist); + va_end(valist); return ret; } static int WINAPIV _vswprintf_l_wrapper(wchar_t *str, const wchar_t *format, void *locale, ...) { int ret; - __ms_va_list valist; - __ms_va_start(valist, locale); + va_list valist; + va_start(valist, locale); ret = p__vswprintf_l(str, format, locale, valist); - __ms_va_end(valist); + va_end(valist); return ret; } static int WINAPIV _vswprintf_c_wrapper(wchar_t *str, size_t size, const wchar_t *format, ...) { int ret; - __ms_va_list valist; - __ms_va_start(valist, format); + va_list valist; + va_start(valist, format); ret = p__vswprintf_c(str, size, format, valist); - __ms_va_end(valist); + va_end(valist); return ret; } static int WINAPIV _vswprintf_c_l_wrapper(wchar_t *str, size_t size, const wchar_t *format, void *locale, ...) { int ret; - __ms_va_list valist; - __ms_va_start(valist, locale); + va_list valist; + va_start(valist, locale); ret = p__vswprintf_c_l(str, size, format, locale, valist); - __ms_va_end(valist); + va_end(valist); return ret; } static int WINAPIV _vswprintf_p_l_wrapper(wchar_t *str, size_t size, const wchar_t *format, void *locale, ...) { int ret; - __ms_va_list valist; - __ms_va_start(valist, locale); + va_list valist; + va_start(valist, locale); ret = p__vswprintf_p_l(str, size, format, locale, valist); - __ms_va_end(valist); + va_end(valist); return ret; } static void test_vswprintf(void) { - const wchar_t format[] = {'%','s',' ','%','d',0}; - const wchar_t number[] = {'n','u','m','b','e','r',0}; - const wchar_t out[] = {'n','u','m','b','e','r',' ','1','2','3',0}; wchar_t buf[20]; - int ret; if (!p_vswprintf || !p__vswprintf || !p__vswprintf_l ||!p__vswprintf_c @@ -1330,43 +922,48 @@ static void test_vswprintf(void) return; } - ret = vswprintf_wrapper(buf, format, number, 123); + ret = vswprintf_wrapper(buf, L"%s %d", L"number", 123); ok(ret == 10, "got %d, expected 10\n", ret); - ok(!memcmp(buf, out, sizeof(out)), "buf = %s\n", wine_dbgstr_w(buf)); + ok(!wcscmp(buf, L"number 123"), "buf = %s\n", wine_dbgstr_w(buf)); memset(buf, 0, sizeof(buf)); - ret = _vswprintf_wrapper(buf, format, number, 123); + ret = _vswprintf_wrapper(buf, L"%s %d", L"number", 123); ok(ret == 10, "got %d, expected 10\n", ret); - ok(!memcmp(buf, out, sizeof(out)), "buf = %s\n", wine_dbgstr_w(buf)); + ok(!wcscmp(buf, L"number 123"), "buf = %s\n", wine_dbgstr_w(buf)); memset(buf, 0, sizeof(buf)); - ret = _vswprintf_l_wrapper(buf, format, NULL, number, 123); + ret = _vswprintf_l_wrapper(buf, L"%s %d", NULL, L"number", 123); ok(ret == 10, "got %d, expected 10\n", ret); - ok(!memcmp(buf, out, sizeof(out)), "buf = %s\n", wine_dbgstr_w(buf)); + ok(!wcscmp(buf, L"number 123"), "buf = %s\n", wine_dbgstr_w(buf)); memset(buf, 0, sizeof(buf)); - ret = _vswprintf_c_wrapper(buf, 20, format, number, 123); + ret = _vswprintf_c_wrapper(buf, 20, L"%s %d", L"number", 123); ok(ret == 10, "got %d, expected 10\n", ret); - ok(!memcmp(buf, out, sizeof(out)), "buf = %s\n", wine_dbgstr_w(buf)); + ok(!wcscmp(buf, L"number 123"), "buf = %s\n", wine_dbgstr_w(buf)); + + memset(buf, 'x', sizeof(buf)); + ret = _vswprintf_c_wrapper(buf, 10, L"%s %d", L"number", 123); + ok(ret == -1, "got %d, expected -1\n", ret); + ok(!wcscmp(buf, L"number 12"), "buf = %s\n", wine_dbgstr_w(buf)); memset(buf, 0, sizeof(buf)); - ret = _vswprintf_c_l_wrapper(buf, 20, format, NULL, number, 123); + ret = _vswprintf_c_l_wrapper(buf, 20, L"%s %d", NULL, L"number", 123); ok(ret == 10, "got %d, expected 10\n", ret); - ok(!memcmp(buf, out, sizeof(out)), "buf = %s\n", wine_dbgstr_w(buf)); + ok(!wcscmp(buf, L"number 123"), "buf = %s\n", wine_dbgstr_w(buf)); memset(buf, 0, sizeof(buf)); - ret = _vswprintf_p_l_wrapper(buf, 20, format, NULL, number, 123); + ret = _vswprintf_p_l_wrapper(buf, 20, L"%s %d", NULL, L"number", 123); ok(ret == 10, "got %d, expected 10\n", ret); - ok(!memcmp(buf, out, sizeof(out)), "buf = %s\n", wine_dbgstr_w(buf)); + ok(!wcscmp(buf, L"number 123"), "buf = %s\n", wine_dbgstr_w(buf)); } static int WINAPIV _vscprintf_wrapper(const char *format, ...) { int ret; - __ms_va_list valist; - __ms_va_start(valist, format); + va_list valist; + va_start(valist, format); ret = p__vscprintf(format, valist); - __ms_va_end(valist); + va_end(valist); return ret; } @@ -1387,18 +984,15 @@ static void test_vscprintf(void) static int WINAPIV _vscwprintf_wrapper(const wchar_t *format, ...) { int ret; - __ms_va_list valist; - __ms_va_start(valist, format); + va_list valist; + va_start(valist, format); ret = p__vscwprintf(format, valist); - __ms_va_end(valist); + va_end(valist); return ret; } static void test_vscwprintf(void) { - const wchar_t format[] = {'%','s',' ','%','d',0}; - const wchar_t number[] = {'n','u','m','b','e','r',0}; - int ret; if (!p__vscwprintf) @@ -1407,7 +1001,7 @@ static void test_vscwprintf(void) return; } - ret = _vscwprintf_wrapper( format, number, 1 ); + ret = _vscwprintf_wrapper(L"%s %d", L"number", 1 ); ok( ret == 8, "got %d expected 8\n", ret ); } @@ -1415,22 +1009,17 @@ static int WINAPIV _vsnwprintf_s_wrapper(wchar_t *str, size_t sizeOfBuffer, size_t count, const wchar_t *format, ...) { int ret; - __ms_va_list valist; - __ms_va_start(valist, format); + va_list valist; + va_start(valist, format); ret = p__vsnwprintf_s(str, sizeOfBuffer, count, format, valist); - __ms_va_end(valist); + va_end(valist); return ret; } static void test_vsnwprintf_s(void) { - const wchar_t format[] = { 'A','B','%','u','C',0 }; - const wchar_t out7[] = { 'A','B','1','2','3','C',0 }; - const wchar_t out6[] = { 'A','B','1','2','3',0 }; - const wchar_t out2[] = { 'A',0 }; - const wchar_t out1[] = { 0 }; wchar_t buffer[14] = { 0 }; - int exp, got; + int ret; if (!p__vsnwprintf_s) { @@ -1439,44 +1028,40 @@ static void test_vsnwprintf_s(void) } /* Enough room. */ - exp = wcslen(out7); - - got = _vsnwprintf_s_wrapper(buffer, 14, _TRUNCATE, format, 123); - ok( exp == got, "length wrong, expect=%d, got=%d\n", exp, got); - ok( !wcscmp(out7, buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer)); + ret = _vsnwprintf_s_wrapper(buffer, 14, _TRUNCATE, L"AB%uC", 123); + ok( ret == 6, "length wrong, expect=6, got=%d\n", ret); + ok( !wcscmp(L"AB123C", buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer)); - got = _vsnwprintf_s_wrapper(buffer, 12, _TRUNCATE, format, 123); - ok( exp == got, "length wrong, expect=%d, got=%d\n", exp, got); - ok( !wcscmp(out7, buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer)); + ret = _vsnwprintf_s_wrapper(buffer, 12, _TRUNCATE, L"AB%uC", 123); + ok( ret == 6, "length wrong, expect=6, got=%d\n", ret); + ok( !wcscmp(L"AB123C", buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer)); - got = _vsnwprintf_s_wrapper(buffer, 7, _TRUNCATE, format, 123); - ok( exp == got, "length wrong, expect=%d, got=%d\n", exp, got); - ok( !wcscmp(out7, buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer)); + ret = _vsnwprintf_s_wrapper(buffer, 7, _TRUNCATE, L"AB%uC", 123); + ok( ret == 6, "length wrong, expect=6, got=%d\n", ret); + ok( !wcscmp(L"AB123C", buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer)); /* Not enough room. */ - exp = -1; - - got = _vsnwprintf_s_wrapper(buffer, 6, _TRUNCATE, format, 123); - ok( exp == got, "length wrong, expect=%d, got=%d\n", exp, got); - ok( !wcscmp(out6, buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer)); + ret = _vsnwprintf_s_wrapper(buffer, 6, _TRUNCATE, L"AB%uC", 123); + ok( ret == -1, "length wrong, expect=-1, got=%d\n", ret); + ok( !wcscmp(L"AB123", buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer)); - got = _vsnwprintf_s_wrapper(buffer, 2, _TRUNCATE, format, 123); - ok( exp == got, "length wrong, expect=%d, got=%d\n", exp, got); - ok( !wcscmp(out2, buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer)); + ret = _vsnwprintf_s_wrapper(buffer, 2, _TRUNCATE, L"AB%uC", 123); + ok( ret == -1, "length wrong, expect=-1, got=%d\n", ret); + ok( !wcscmp(L"A", buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer)); - got = _vsnwprintf_s_wrapper(buffer, 1, _TRUNCATE, format, 123); - ok( exp == got, "length wrong, expect=%d, got=%d\n", exp, got); - ok( !wcscmp(out1, buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer)); + ret = _vsnwprintf_s_wrapper(buffer, 1, _TRUNCATE, L"AB%uC", 123); + ok( ret == -1, "length wrong, expect=-1, got=%d\n", ret); + ok( !wcscmp(L"", buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer)); } static int WINAPIV _vsprintf_p_wrapper(char *str, size_t sizeOfBuffer, const char *format, ...) { int ret; - __ms_va_list valist; - __ms_va_start(valist, format); + va_list valist; + va_start(valist, format); ret = p__vsprintf_p(str, sizeOfBuffer, format, valist); - __ms_va_end(valist); + va_end(valist); return ret; } diff --git a/modules/rostests/winetests/msvcrt/scanf.c b/modules/rostests/winetests/msvcrt/scanf.c index 6d38e438c8c42..e175342796b51 100644 --- a/modules/rostests/winetests/msvcrt/scanf.c +++ b/modules/rostests/winetests/msvcrt/scanf.c @@ -22,6 +22,41 @@ #include "wine/test.h" +static void test_fscanf( void ) +{ + static const char file_name[] = "fscanf.tst"; + static const char contents[] = + "line1\n" + "line2 " + ; + char buf[1024]; + FILE *fp; + int ret; + + fp = fopen(file_name, "wb"); + ok(fp != NULL, "fp = %p\n", fp); + if(!fp) { + skip("failed to create temporary test file\n"); + return; + } + + ret = fprintf(fp, contents); + fclose(fp); + + fp = fopen(file_name, "rb"); + ret = fscanf(fp, "%s", buf); + ok(ret == 1, "ret = %d\n", ret); + ok(strcmp(buf, "line1") == 0, "buf = %s\n", buf); + ret = fscanf(fp, "%s", buf); + ok(ret == 1, "ret = %d\n", ret); + ok(strcmp(buf, "line2") == 0, "buf = %s\n", buf); + ret = fscanf(fp, "%s", buf); + ok(ret == EOF, "ret = %d\n", ret); + fclose(fp); + + unlink(file_name); +} + static void test_sscanf( void ) { /* use function pointers to bypass gcc builtin */ @@ -48,6 +83,14 @@ static void test_sscanf( void ) ret = p_sscanf(buffer, "%d", &result); ok( ret == EOF,"sscanf returns %x instead of %x\n", ret, EOF ); + ret = p_sscanf(" \t\n\n", "%s", buffer); + ok( ret == EOF, "ret = %d\n", ret ); + + buffer1[0] = 'a'; + ret = p_sscanf("test\n", "%s%c", buffer, buffer1); + ok( ret == 2, "ret = %d\n", ret ); + ok( buffer1[0] == '\n', "buffer1[0] = %d\n", buffer1[0] ); + /* check %p */ ok( p_sscanf("000000000046F170", "%p", &ptr) == 1, "sscanf failed\n" ); ok( ptr == (void *)0x46F170,"sscanf reads %p instead of %x\n", ptr, 0x46F170 ); @@ -122,6 +165,12 @@ static void test_sscanf( void ) ok(double_res >= 1.1e-30-1e-45 && double_res <= 1.1e-30+1e-45, "Got %.18le, expected %.18le\n", double_res, 1.1e-30); + buffer[0] = 0; + double_res = 1; + ret = p_sscanf(buffer, "%lf", &double_res); + ok(ret == -1, "expected 0, got %u\n", ret); + ok(double_res == 1, "Got %lf, expected 1\n", double_res); + /* check strings */ ret = p_sprintf(buffer," %s", pname); ok( ret == 26, "expected 26, got %u\n", ret); @@ -137,6 +186,22 @@ static void test_sscanf( void ) ok( ret == 1, "Error with format \"%s\"\n","%*[a-cd-dg-e]%c"); ok( buffer[0] == 'h', "Error with \"abcefgdh\" \"%c\"\n", buffer[0]); + ret = p_sscanf("-123", "%[-0-9]", buffer); + ok( ret == 1, "Error with format \"%s\"\n", "%[-0-9]"); + ok( strcmp("-123", buffer) == 0, "Error with \"-123\" \"%s\"\n", buffer); + + ret = p_sscanf("-321", "%[0-9-]", buffer); + ok( ret == 1, "Error with format \"%s\"\n", "%[0-9-]"); + ok( strcmp("-321", buffer) == 0, "Error with \"-321\" \"%s\"\n", buffer); + + ret = p_sscanf("-4123", "%[1-2-4]", buffer); + ok( ret == 1, "Error with format \"%s\"\n", "%[1-2-4]"); + ok( strcmp("-412", buffer) == 0, "Error with \"-412\" \"%s\"\n", buffer); + + ret = p_sscanf("-456123", "%[1-2-45-6]", buffer); + ok( ret == 1, "Error with format \"%s\"\n", "%[1-2-45-6]"); + ok( strcmp("-45612", buffer) == 0, "Error with \"-45612\" \"%s\"\n", buffer); + buffer1[0] = 'b'; ret = p_sscanf("a","%s%s", buffer, buffer1); ok( ret == 1, "expected 1, got %u\n", ret); @@ -162,6 +227,30 @@ static void test_sscanf( void ) ok(ret == 1, "Wrong number of arguments read: %d\n", ret); ok(result == 0xdead614e, "Wrong number read (%x)\n", result); + result = 0xdeadbeef; + strcpy(buffer,"12345678"); + ret = p_sscanf(buffer, "%02hd", &result); + ok(ret == 1, "Wrong number of arguments read: %d\n", ret); + ok(result == 0xdead000c, "Wrong number read (%x)\n", result); + + result = 0xdeadbeef; + strcpy(buffer,"12345678"); + ret = p_sscanf(buffer, "%h02d", &result); + ok(ret == 1, "Wrong number of arguments read: %d\n", ret); + ok(result == 0xdead000c, "Wrong number read (%x)\n", result); + + result = 0xdeadbeef; + strcpy(buffer,"12345678"); + ret = p_sscanf(buffer, "%000h02d", &result); + ok(ret == 1, "Wrong number of arguments read: %d\n", ret); + ok(result == 0xdead000c, "Wrong number read (%x)\n", result); + + result = 0xdeadbeef; + strcpy(buffer,"12345678"); + ret = p_sscanf(buffer, "%2h0d", &result); + ok(ret == 1, "Wrong number of arguments read: %d\n", ret); + ok(result == 0xdead614e, "Wrong number read (%x)\n", result); + result = 0xdeadbeef; ret = p_sscanf(buffer, "%hhd", &result); ok(ret == 1, "Wrong number of arguments read: %d\n", ret); @@ -313,35 +402,34 @@ static void test_sscanf_s(void) static void test_swscanf( void ) { - wchar_t buffer[100]; + wchar_t buffer[100], results[100]; int result, ret; - static const WCHAR formatd[] = {'%','d',0}; - const WCHAR format2[] = {'a',0x1234,'%',0x1234,'%','c',0}; WCHAR c; /* check WEOF */ /* WEOF is an unsigned short -1 but swscanf returns int so it should be sign-extended */ buffer[0] = 0; - ret = swscanf(buffer, formatd, &result); + ret = swscanf(buffer, L"%d", &result); /* msvcrt returns 0 but should return -1 (later versions do) */ ok( ret == (short)WEOF || broken(ret == 0), "swscanf returns %x instead of %x\n", ret, WEOF ); + ret = swscanf(L" \t\n\n", L"%s", results); + /* sscanf returns EOF under this case, but swscanf does not return WEOF */ + ok( ret == 0, "ret = %d\n", ret ); + buffer[0] = 'a'; buffer[1] = 0x1234; buffer[2] = 0x1234; buffer[3] = 'b'; - ret = swscanf(buffer, format2, &c); + ret = swscanf(buffer, L"a\x1234%\x1234%c", &c); ok(ret == 1, "swscanf returned %d\n", ret); ok(c == 'b', "c = %x\n", c); } static void test_swscanf_s(void) { - static const wchar_t fmt1[] = {'%','c',0}; - static const wchar_t fmt2[] = {'%','[','a','-','z',']',0}; - int (WINAPIV *pswscanf_s)(const wchar_t*,const wchar_t*,...); HMODULE hmod = GetModuleHandleA("msvcrt.dll"); wchar_t buf[2], out[2]; @@ -356,15 +444,15 @@ static void test_swscanf_s(void) buf[0] = 'a'; buf[1] = '1'; out[1] = 'b'; - ret = pswscanf_s(buf, fmt1, out, 1); + ret = pswscanf_s(buf, L"%c", out, 1); ok(ret == 1, "swscanf_s returned %d\n", ret); ok(out[0] == 'a', "out[0] = %x\n", out[0]); ok(out[1] == 'b', "out[1] = %x\n", out[1]); - ret = pswscanf_s(buf, fmt2, out, 1); + ret = pswscanf_s(buf, L"%[a-z]", out, 1); ok(!ret, "swscanf_s returned %d\n", ret); - ret = pswscanf_s(buf, fmt2, out, 2); + ret = pswscanf_s(buf, L"%[a-z]", out, 2); ok(ret == 1, "swscanf_s returned %d\n", ret); ok(out[0] == 'a', "out[0] = %x\n", out[0]); ok(!out[1], "out[1] = %x\n", out[1]); @@ -372,6 +460,7 @@ static void test_swscanf_s(void) START_TEST(scanf) { + test_fscanf(); test_sscanf(); test_sscanf_s(); test_swscanf(); diff --git a/modules/rostests/winetests/msvcrt/signal.c b/modules/rostests/winetests/msvcrt/signal.c index ad6ea6ecf906f..b78aca510c0bb 100644 --- a/modules/rostests/winetests/msvcrt/signal.c +++ b/modules/rostests/winetests/msvcrt/signal.c @@ -67,10 +67,10 @@ static void test___pxcptinfoptrs(void) signal(SIGABRT, sighandler); res = raise(SIGABRT); - ok(res == 0, "failed to raise SIGBREAK\n"); + skip_2k3_fail ok(res == 0, "failed to raise SIGBREAK\n"); ok(*ret == (void*)0xdeadbeef, "*ret = %p\n", *ret); - ok(test_value == 2, "test_value = %d\n", test_value); + skip_2k3_fail ok(test_value == 2, "test_value = %d\n", test_value); } START_TEST(signal) diff --git a/modules/rostests/winetests/msvcrt/string.c b/modules/rostests/winetests/msvcrt/string.c index 573289d77b534..f88d672d573e5 100644 --- a/modules/rostests/winetests/msvcrt/string.c +++ b/modules/rostests/winetests/msvcrt/string.c @@ -28,12 +28,16 @@ #include #include #include +#include #include /* make it use a definition from string.h */ #undef strncpy +#undef wcsncpy #include "winbase.h" #include "winnls.h" +#include "winuser.h" +#include static char *buf_to_string(const unsigned char *bin, int len, int nr) { @@ -56,9 +60,13 @@ static void* (__cdecl *pmemcpy)(void *, const void *, size_t n); static int (__cdecl *p_memcpy_s)(void *, size_t, const void *, size_t); static int (__cdecl *p_memmove_s)(void *, size_t, const void *, size_t); static int* (__cdecl *pmemcmp)(void *, const void *, size_t n); +static int (__cdecl *p_strcmp)(const char *, const char *); +static int (__cdecl *p_strncmp)(const char *, const char *, size_t); static int (__cdecl *p_strcpy)(char *dst, const char *src); static int (__cdecl *pstrcpy_s)(char *dst, size_t len, const char *src); static int (__cdecl *pstrcat_s)(char *dst, size_t len, const char *src); +static int (__cdecl *p_strncpy_s)(char *dst, size_t size, const char *src, size_t count); +static int (__cdecl *p_strncat_s)(char *dst, size_t elem, const char *src, size_t count); static int (__cdecl *p_mbscat_s)(unsigned char *dst, size_t size, const unsigned char *src); static int (__cdecl *p_mbsnbcat_s)(unsigned char *dst, size_t size, const unsigned char *src, size_t count); static int (__cdecl *p_mbsnbcpy_s)(unsigned char * dst, size_t size, const unsigned char * src, size_t count); @@ -73,6 +81,7 @@ static unsigned __int64 (__cdecl *p_strtoui64)(const char *, char **, int); static __int64 (__cdecl *p_wcstoi64)(const wchar_t *, wchar_t **, int); static unsigned __int64 (__cdecl *p_wcstoui64)(const wchar_t *, wchar_t **, int); static int (__cdecl *pwcstombs_s)(size_t*,char*,size_t,const wchar_t*,size_t); +static int (__cdecl *p_wcstombs_s_l)(size_t*,char*,size_t,const wchar_t*,size_t,_locale_t); static int (__cdecl *pmbstowcs_s)(size_t*,wchar_t*,size_t,const char*,size_t); static size_t (__cdecl *p_mbsrtowcs)(wchar_t*, const char**, size_t, mbstate_t*); static int (__cdecl *p_mbsrtowcs_s)(size_t*,wchar_t*,size_t,const char**,size_t,mbstate_t*); @@ -87,6 +96,7 @@ static int (__cdecl *p_wcslwr_s)(wchar_t*,size_t); static errno_t (__cdecl *p_mbsupr_s)(unsigned char *str, size_t numberOfElements); static errno_t (__cdecl *p_mbslwr_s)(unsigned char *str, size_t numberOfElements); static int (__cdecl *p_wctob)(wint_t); +static wint_t (__cdecl *p_btowc)(int); static size_t (__cdecl *p_wcrtomb)(char*, wchar_t, mbstate_t*); static int (__cdecl *p_wcrtomb_s)(size_t*, char*, size_t, wchar_t, mbstate_t*); static int (__cdecl *p_tolower)(int); @@ -109,6 +119,12 @@ static int (__cdecl *p__mbccpy_s)(unsigned char*, size_t, int*, const unsigned c static int (__cdecl *p__memicmp)(const char*, const char*, size_t); static int (__cdecl *p__memicmp_l)(const char*, const char*, size_t, _locale_t); static size_t (__cdecl *p___strncnt)(const char*, size_t); +static unsigned int (__cdecl *p_mbsnextc_l)(const unsigned char*, _locale_t); +static int (__cdecl *p_mbscmp_l)(const unsigned char*, const unsigned char*, _locale_t); +static int (__cdecl *p__strnicmp_l)(const char*, const char*, size_t, _locale_t); +static int (__cdecl *p_toupper)(int); + +int CDECL __STRINGTOLD(_LDOUBLE*, char**, const char*, int); #define SETNOFAIL(x,y) x = (void*)GetProcAddress(hMsvcrt,y) #define SET(x,y) SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y) @@ -120,13 +136,13 @@ static void test_swab( void ) { char expected1[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ@#"; char expected2[] = "ABCDEFGHIJKLMNOPQRSTUVWX$"; char expected3[] = "$"; - + char from[30]; char to[30]; - + int testsize; - - /* Test 1 - normal even case */ + + /* Test 1 - normal even case */ memset(to,'$', sizeof(to)); memset(from,'@', sizeof(from)); testsize = 26; @@ -134,7 +150,7 @@ static void test_swab( void ) { _swab( from, to, testsize ); ok(memcmp(to,expected1,testsize) == 0, "Testing even size %d returned '%*.*s'\n", testsize, testsize, testsize, to); - /* Test 2 - uneven case */ + /* Test 2 - uneven case */ memset(to,'$', sizeof(to)); memset(from,'@', sizeof(from)); testsize = 25; @@ -142,7 +158,7 @@ static void test_swab( void ) { _swab( from, to, testsize ); ok(memcmp(to,expected2,testsize) == 0, "Testing odd size %d returned '%*.*s'\n", testsize, testsize, testsize, to); - /* Test 3 - from = to */ + /* Test 3 - from = to */ memset(to,'$', sizeof(to)); memset(from,'@', sizeof(from)); testsize = 26; @@ -150,7 +166,7 @@ static void test_swab( void ) { _swab( to, to, testsize ); ok(memcmp(to,expected1,testsize) == 0, "Testing overlapped size %d returned '%*.*s'\n", testsize, testsize, testsize, to); - /* Test 4 - 1 bytes */ + /* Test 4 - 1 bytes */ memset(to,'$', sizeof(to)); memset(from,'@', sizeof(from)); testsize = 1; @@ -159,6 +175,29 @@ static void test_swab( void ) { ok(memcmp(to,expected3,testsize) == 0, "Testing small size %d returned '%*.*s'\n", testsize, testsize, testsize, to); } +static void test_strcspn(void) +{ + static const struct { + const char *str; + const char *rej; + int ret; + } tests[] = { + { "test", "a", 4 }, + { "test", "e", 1 }, + { "test", "", 4 }, + { "", "a", 0 }, + { "a\xf1", "\xf1", 1 } + }; + int r, i; + + for (i = 0; i < ARRAY_SIZE(tests); i++) + { + r = strcspn(tests[i].str, tests[i].rej); + ok(r == tests[i].ret, "strcspn(\"%s\", \"%s\") = %d, expected %d\n", + tests[i].str, tests[i].rej, r, tests[i].ret); + } +} + #if 0 /* use this to generate more tests */ static void test_codepage(int cp) @@ -228,6 +267,7 @@ static void test_mbcp(void) unsigned char *mbstring2 = (unsigned char *)"\xb0\xb1\xb2\xb3Q\xb4\xb5"; /* correct string */ unsigned char *mbsonlylead = (unsigned char *)"\xb0\0\xb1\xb2 \xb3"; unsigned char buf[16]; + unsigned char *ret; int step; CPINFO cp_info; @@ -299,6 +339,7 @@ static void test_mbcp(void) expect_eq(_ismbstrail(mbsonlylead, &mbsonlylead[5]), FALSE, int, "%d"); /* _mbsbtype */ + skip_2k3_crash expect_eq(_mbsbtype(NULL, 0), _MBC_ILLEGAL, int, "%d"); expect_eq(_mbsbtype(mbstring, 0), _MBC_LEAD, int, "%d"); expect_eq(_mbsbtype(mbstring, 1), _MBC_TRAIL, int, "%d"); expect_eq(_mbsbtype(mbstring, 2), _MBC_LEAD, int, "%d"); @@ -321,10 +362,16 @@ static void test_mbcp(void) expect_eq(_mbsnextc(&mbstring[2]), 0xb220, int, "%x"); /* lead + invalid tail */ expect_eq(_mbsnextc(&mbstring[3]), 0x20, int, "%x"); /* single char */ + if (!p_mbsnextc_l) + win_skip("_mbsnextc_l tests\n"); + else + expect_eq(p_mbsnextc_l(mbstring, NULL), 0xb0b1, int, "%x"); + /* _mbclen/_mbslen */ expect_eq(_mbclen(mbstring), 2, int, "%d"); expect_eq(_mbclen(&mbstring[2]), 2, int, "%d"); expect_eq(_mbclen(&mbstring[3]), 1, int, "%d"); + expect_eq(_mbclen(mbsonlylead), 1, int, "%d"); expect_eq(_mbslen(mbstring2), 4, int, "%d"); expect_eq(_mbslen(mbsonlylead), 0, int, "%d"); /* lead + NUL not counted as character */ expect_eq(_mbslen(mbstring), 4, int, "%d"); /* lead + invalid trail counted */ @@ -419,6 +466,57 @@ static void test_mbcp(void) expect_bin(buf, "\x00\xff", 2); } + skip_2k3_crash { + errno = 0xdeadbeef; + ret = _mbsncpy(NULL, mbstring, 1); + ok(ret == NULL, "_mbsncpy returned %p, expected NULL\n", ret); + ok(errno == EINVAL, "_mbsncpy returned %d\n", errno); + + memset(buf, 0xff, sizeof(buf)); + errno = 0xdeadbeef; + ret = _mbsncpy(buf, NULL, 1); + ok(ret == NULL, "_mbsncpy returned %p, expected NULL\n", ret); + ok(errno == EINVAL, "_mbsncpy returned %d\n", errno); + expect_bin(buf, "\xff\xff\xff", 3); + } + + errno = 0xdeadbeef; + ret = _mbsncpy(NULL, mbstring, 0); + ok(ret == NULL, "_mbsncpy returned %p, expected NULL\n", ret); + ok(errno == 0xdeadbeef, "_mbsncpy should not change errno\n"); + + memset(buf, 0xff, sizeof(buf)); + errno = 0xdeadbeef; + ret = _mbsncpy(buf, NULL, 0); + ok(ret == buf, "_mbsncpy returned %p, expected %sp\n", ret, buf); + ok(errno == 0xdeadbeef, "_mbsncpy should not change errno\n"); + + skip_2k3_crash { + memset(buf, 0xff, sizeof(buf)); + errno = 0xdeadbeef; + ret = _mbsncpy(NULL, mbstring, 1); + ok(ret == NULL, "_mbsncpy returned %p, expected NULL\n", ret); + ok(errno == EINVAL, "_mbsncpy returned %d\n", errno); + + memset(buf, 0xff, sizeof(buf)); + errno = 0xdeadbeef; + ret = _mbsncpy(buf, NULL, 1); + ok(ret == NULL, "_mbsncpy returned %p, expected NULL\n", ret); + ok(errno == EINVAL, "_mbsncpy returned %d\n", errno); + } + + memset(buf, 0xff, sizeof(buf)); + ret = _mbsncpy(NULL, mbstring, 0); + ok(ret == NULL, "_mbsncpy returned %p, expected %p\n", ret, buf); + + memset(buf, 0xff, sizeof(buf)); + ret = _mbsncpy(buf, NULL, 0); + ok(ret == buf, "_mbsncpy returned %p, expected %sp\n", ret, buf); + + memset(buf, 0xff, sizeof(buf)); + ret = _mbsncpy(buf, mbstring, 0); + ok(ret == buf, "_mbsncpy returned %p, expected %p\n", ret, buf); + memset(buf, 0xff, sizeof(buf)); _mbsncpy(buf, mbstring, 1); expect_bin(buf, "\xb0\xb1\xff", 3); @@ -530,6 +628,13 @@ static void test_mbsspn( void) ret=_mbsspn( str1, empty); ok( ret==0, "_mbsspn returns %d should be 0\n", ret); + ret=_mbscspn( str1, set); + ok( ret==0, "_mbscspn returns %d should be 0\n", ret); + ret=_mbscspn( str2, set); + ok( ret==4, "_mbscspn returns %d should be 4\n", ret); + ret=_mbscspn( str1, empty); + ok( ret==8, "_mbscspn returns %d should be 8\n", ret); + _setmbcp( 932); ret=_mbsspn( mbstr, mbset1); ok( ret==8, "_mbsspn returns %d should be 8\n", ret); @@ -542,6 +647,17 @@ static void test_mbsspn( void) ret=_mbsspn( mbstr, mbset3); ok( ret==14, "_mbsspn returns %d should be 14\n", ret); + ret=_mbscspn( mbstr, mbset1); + ok( ret==0, "_mbscspn returns %d should be 0\n", ret); + ret=_mbscspn( mbstr, mbset2); + ok( ret==0, "_mbscspn returns %d should be 0\n", ret); + ret=_mbscspn( mbstr+8, mbset1); + ok( ret==2, "_mbscspn returns %d should be 2\n", ret); + ret=_mbscspn( mbstr+8, mbset2); + ok( ret==0, "_mbscspn returns %d should be 0\n", ret); + ret=_mbscspn( mbstr, mbset3); + ok( ret==0, "_mbscspn returns %d should be 0\n", ret); + _setmbcp( cp); } @@ -582,10 +698,62 @@ static void test_mbsspnp( void) static void test_strdup(void) { - char *str; - str = _strdup( 0 ); - ok( str == 0, "strdup returns %s should be 0\n", str); - free( str ); + char *str; + errno = 0xdeadbeef; + str = strdup(0); + ok(str == 0, "strdup returned %s, expected NULL\n", wine_dbgstr_a(str)); + ok(errno == 0xdeadbeef, "errno is %d, expected 0xdeadbeef\n", errno); +} + +static void test_wcsdup(void) +{ + WCHAR *str; + errno = 0xdeadbeef; + str = wcsdup(0); + ok(str == 0, "wcsdup returned %s, expected NULL\n", wine_dbgstr_w(str)); + ok(errno == 0xdeadbeef, "errno is %d, expected 0xdeadbeef\n", errno); +} + +static void test_strcmp(void) +{ + int ret = p_strcmp( "abc", "abcd" ); + ok( ret == -1, "wrong ret %d\n", ret ); + ret = p_strcmp( "", "abc" ); + ok( ret == -1, "wrong ret %d\n", ret ); + ret = p_strcmp( "abc", "ab\xa0" ); + ok( ret == -1, "wrong ret %d\n", ret ); + ret = p_strcmp( "ab\xb0", "ab\xa0" ); + ok( ret == 1, "wrong ret %d\n", ret ); + ret = p_strcmp( "ab\xc2", "ab\xc2" ); + ok( ret == 0, "wrong ret %d\n", ret ); + + ret = p_strncmp( "abc", "abcd", 3 ); + ok( ret == 0, "wrong ret %d\n", ret ); + skip_2k3_fail { +#ifdef _WIN64 + ret = p_strncmp( "", "abc", 3 ); + ok( ret == -1, "wrong ret %d\n", ret ); + ret = p_strncmp( "abc", "ab\xa0", 4 ); + ok( ret == -1, "wrong ret %d\n", ret ); + ret = p_strncmp( "ab\xb0", "ab\xa0", 3 ); + ok( ret == 1, "wrong ret %d\n", ret ); +#else + ret = p_strncmp( "", "abc", 3 ); + ok( ret == 0 - 'a', "wrong ret %d\n", ret ); + ret = p_strncmp( "abc", "ab\xa0", 4 ); + ok( ret == 'c' - 0xa0, "wrong ret %d\n", ret ); + ret = p_strncmp( "ab\xb0", "ab\xa0", 3 ); + ok( ret == 0xb0 - 0xa0, "wrong ret %d\n", ret ); +#endif + } + ret = p_strncmp( "ab\xb0", "ab\xa0", 2 ); + ok( ret == 0, "wrong ret %d\n", ret ); + ret = p_strncmp( "ab\xc2", "ab\xc2", 3 ); + ok( ret == 0, "wrong ret %d\n", ret ); + ret = p_strncmp( "abc", "abd", 0 ); + ok( ret == 0, "wrong ret %d\n", ret ); + ret = p_strncmp( "abc", "abc", 12 ); + ok( ret == 0, "wrong ret %d\n", ret ); } static void test_strcpy_s(void) @@ -650,6 +818,55 @@ static void test_strcpy_s(void) dest[4] == 'l' && dest[5] == '\0' && dest[6] == '\0' && dest[7] == 'X', "Unexpected return data from strcpy: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]); + + if(!p_strncpy_s) + { + win_skip("strncpy_s not found\n"); + return; + } + + ret = p_strncpy_s(NULL, 18, big, ARRAY_SIZE(big)); + ok(ret == EINVAL, "p_strncpy_s expect EINVAL got %d\n", ret); + + dest[0] = 'A'; + ret = p_strncpy_s(dest, 8, NULL, 1); + ok(ret == EINVAL, "expected EINVAL got %d\n", ret); + ok(dest[0] == 0, "dest[0] not 0\n"); + + dest[0] = 'A'; + ret = p_strncpy_s(dest, 8, NULL, 0); + ok(ret == 0, "expected ERROR_SUCCESS got %d\n", ret); + ok(dest[0] == 0, "dest[0] not 0\n"); + + dest[0] = 'A'; + ret = p_strncpy_s(dest, 0, big, ARRAY_SIZE(big)); + ok(ret == ERANGE || ret == EINVAL, "expected ERANGE/EINVAL got %d\n", ret); + ok(dest[0] == 0 || ret == EINVAL, "dest[0] not 0\n"); + + ret = p_strncpy_s(dest, 8, small, ARRAY_SIZE(small)); + ok(ret == 0, "expected 0 got %d\n", ret); + ok(!strcmp(dest, small), "dest != small\n"); + + dest[0] = 'A'; + ret = p_strncpy_s(dest, 8, big, ARRAY_SIZE(big)); + ok(ret == ERANGE || ret == EINVAL, "expected ERANGE/EINVAL got %d\n", ret); + ok(dest[0] == 0, "dest[0] not 0\n"); + + dest[0] = 'A'; + ret = p_strncpy_s(dest, 5, big, -1); + ok(ret == STRUNCATE, "expected STRUNCATE got %d\n", ret); + ok(dest[4] == 0, "dest[4] not 0\n"); + ok(!memcmp(dest, big, 4), "dest = %s\n", wine_dbgstr_a(dest)); + + ret = p_strncpy_s(NULL, 0, (void*)0xdeadbeef, 0); + ok(ret == 0, "ret = %d\n", ret); + + dest[0] = '1'; + dest[1] = 0; + ret = p_strncpy_s(dest+1, 4, dest, -1); + ok(ret == STRUNCATE, "expected ERROR_SUCCESS got %d\n", ret); + ok(dest[0]=='1' && dest[1]=='1' && dest[2]=='1' && dest[3]=='1', + "dest = %s\n", wine_dbgstr_a(dest)); } #define okchars(dst, b0, b1, b2, b3, b4, b5, b6, b7) \ @@ -1016,7 +1233,7 @@ static void test__mbscpy_s(void) static void test_wcscpy_s(void) { - static const WCHAR szLongText[] = { 'T','h','i','s','A','L','o','n','g','s','t','r','i','n','g',0 }; + static const WCHAR szLongText[] = L"ThisALongstring"; static WCHAR szDest[18]; static WCHAR szDestShort[8]; int ret; @@ -1122,11 +1339,8 @@ static void test_wcscpy_s(void) static void test__wcsupr_s(void) { - static const WCHAR mixedString[] = {'M', 'i', 'X', 'e', 'D', 'l', 'o', 'w', - 'e', 'r', 'U', 'P', 'P', 'E', 'R', 0}; - static const WCHAR expectedString[] = {'M', 'I', 'X', 'E', 'D', 'L', 'O', - 'W', 'E', 'R', 'U', 'P', 'P', 'E', - 'R', 0}; + static const WCHAR mixedString[] = L"MiXeDlowerUPPER"; + static const WCHAR expectedString[] = L"MIXEDLOWERUPPER"; WCHAR testBuffer[2*ARRAY_SIZE(mixedString)]; int ret; @@ -1209,11 +1423,8 @@ static void test__wcsupr_s(void) static void test__wcslwr_s(void) { - static const WCHAR mixedString[] = {'M', 'i', 'X', 'e', 'D', 'l', 'o', 'w', - 'e', 'r', 'U', 'P', 'P', 'E', 'R', 0}; - static const WCHAR expectedString[] = {'m', 'i', 'x', 'e', 'd', 'l', 'o', - 'w', 'e', 'r', 'u', 'p', 'p', 'e', - 'r', 0}; + static const WCHAR mixedString[] = L"MiXeDlowerUPPER"; + static const WCHAR expectedString[] = L"mixedlowerupper"; WCHAR buffer[2*ARRAY_SIZE(mixedString)]; int ret; @@ -1603,6 +1814,14 @@ static void test_strtok(void) "third call string (%p) \'%s\' return %p\n", teststr, testcases_strtok[i].string, strret); } + + strcpy( teststr, "test a=b" ); + strret = strtok( teststr, " " ); + ok( strret == teststr, "strret = %p, expected %p\n", strret, teststr ); + strret = strtok( NULL, "ab=" ); + ok( !strret, "strret = %p, expected NULL\n", strret ); + strret = strtok( NULL, "=" ); + ok( !strret, "strret = %p, expected NULL\n", strret ); } static void test_strtol(void) @@ -1617,58 +1836,58 @@ static void test_strtol(void) /* errno is modified on W2K8+ */ errno = EBADF; l = strtol("-1234", &e, 0); - ok(l==-1234, "wrong value %d\n", l); + ok(l==-1234, "wrong value %ld\n", l); ok(errno == EBADF || broken(errno == 0), "wrong errno %d\n", errno); errno = EBADF; ul = strtoul("1234", &e, 0); - ok(ul==1234, "wrong value %u\n", ul); + ok(ul==1234, "wrong value %lu\n", ul); ok(errno == EBADF || broken(errno == 0), "wrong errno %d\n", errno); errno = EBADF; l = strtol("2147483647L", &e, 0); - ok(l==2147483647, "wrong value %d\n", l); + ok(l==2147483647, "wrong value %ld\n", l); ok(errno == EBADF || broken(errno == 0), "wrong errno %d\n", errno); errno = EBADF; l = strtol("-2147483648L", &e, 0); - ok(l==-2147483647L - 1, "wrong value %d\n", l); + ok(l==-2147483647L - 1, "wrong value %ld\n", l); ok(errno == EBADF || broken(errno == 0), "wrong errno %d\n", errno); errno = EBADF; ul = strtoul("4294967295UL", &e, 0); - ok(ul==4294967295ul, "wrong value %u\n", ul); + ok(ul==4294967295ul, "wrong value %lu\n", ul); ok(errno == EBADF || broken(errno == 0), "wrong errno %d\n", errno); errno = 0; l = strtol("9223372036854775807L", &e, 0); - ok(l==2147483647, "wrong value %d\n", l); + ok(l==2147483647, "wrong value %ld\n", l); ok(errno == ERANGE, "wrong errno %d\n", errno); errno = 0; ul = strtoul("9223372036854775807L", &e, 0); - ok(ul==4294967295ul, "wrong value %u\n", ul); + ok(ul==4294967295ul, "wrong value %lu\n", ul); ok(errno == ERANGE, "wrong errno %d\n", errno); errno = 0; ul = strtoul("-2", NULL, 0); - ok(ul == -2, "wrong value %u\n", ul); + ok(ul == -2, "wrong value %lu\n", ul); ok(errno == 0, "wrong errno %d\n", errno); errno = 0; ul = strtoul("-4294967294", NULL, 0); - ok(ul == 2, "wrong value %u\n", ul); + ok(ul == 2, "wrong value %lu\n", ul); ok(errno == 0, "wrong errno %d\n", errno); errno = 0; ul = strtoul("-4294967295", NULL, 0); - ok(ul==1, "wrong value %u\n", ul); + ok(ul==1, "wrong value %lu\n", ul); ok(errno == 0, "wrong errno %d\n", errno); errno = 0; ul = strtoul("-4294967296", NULL, 0); - ok(ul == 1, "wrong value %u\n", ul); + ok(ul == 1, "wrong value %lu\n", ul); ok(errno == ERANGE, "wrong errno %d\n", errno); errno = 0; l = strtol(neg, &e, 0); - ok(l == 0, "wrong value %d\n", l); + ok(l == 0, "wrong value %ld\n", l); ok(errno == 0, "wrong errno %d\n", errno); ok(e == neg, "e = %p, neg = %p\n", e, neg); } @@ -1838,56 +2057,82 @@ static void test__strtoi64(void) ok(errno == ERANGE, "errno = %x\n", errno); } -static inline BOOL almost_equal(double d1, double d2) { - if(d1-d2>-1e-30 && d1-d2<1e-30) - return TRUE; - return FALSE; +static inline BOOL compare_double(double f, double g, unsigned int ulps) +{ + ULONGLONG x = *(ULONGLONG *)&f; + ULONGLONG y = *(ULONGLONG *)&g; + + if (f < 0) + x = ~x + 1; + else + x |= ((ULONGLONG)1)<<63; + if (g < 0) + y = ~y + 1; + else + y |= ((ULONGLONG)1)<<63; + + return (x>y ? x-y : y-x) <= ulps; } static void test__strtod(void) { - const char double1[] = "12.1"; - const char double2[] = "-13.721"; - const char double3[] = "INF"; - const char double4[] = ".21e12"; - const char double5[] = "214353e-3"; - const char double6[] = "NAN"; + static const struct { + const char *str; + int len; + double ret; + int err; + } tests[] = { + { "12.1", 4, 12.1 }, + { "-13.721", 7, -13.721 }, + { "INF", 0, 0 }, + { ".21e12", 6, 210000000000.0 }, + { "214353e-3", 9, 214.353 }, + { "NAN", 0, 0 }, + { "12.1d2", 6, 12.1e2 }, + { " d10", 0, 0 }, + { "0.1", 3, 0.1 }, + { "-0.1", 4, -0.1 }, + { "0.1281832188491894198128921", 27, 0.1281832188491894198128921 }, + { "0.82181281288121", 16, 0.82181281288121 }, + { "21921922352523587651128218821", 29, 21921922352523587651128218821.0 }, + { "0.1d238", 7, 0.1e238 }, + { "0.1D-4736", 9, 0, ERANGE }, + { "3.4028234663852887e38", 21, FLT_MAX }, + { "1.1754943508222875e-38", 22, FLT_MIN }, + { "1.7976931348623158e+308", 23, DBL_MAX }, + { "1.7976931348623159e+308", 23, INFINITY, ERANGE }, + { "2.2250738585072014e-308", 23, DBL_MIN }, + { "-1.7976931348623158e+308", 24, -DBL_MAX }, + { "-1.7976931348623159e+308", 24, -INFINITY, ERANGE }, + { "00", 2, 0 }, + { "00.", 3, 0 }, + { ".00", 3, 0 }, + { "-0.", 3, 0 }, + { "0e13", 4, 0 }, + }; const char overflow[] = "1d9999999999999999999"; - const char white_chars[] = " d10"; char *end; double d; + int i; - d = strtod(double1, &end); - ok(almost_equal(d, 12.1), "d = %lf\n", d); - ok(end == double1+4, "incorrect end (%d)\n", (int)(end-double1)); - - d = strtod(double2, &end); - ok(almost_equal(d, -13.721), "d = %lf\n", d); - ok(end == double2+7, "incorrect end (%d)\n", (int)(end-double2)); - - d = strtod(double3, &end); - ok(almost_equal(d, 0), "d = %lf\n", d); - ok(end == double3, "incorrect end (%d)\n", (int)(end-double3)); - - d = strtod(double4, &end); - ok(almost_equal(d, 210000000000.0), "d = %lf\n", d); - ok(end == double4+6, "incorrect end (%d)\n", (int)(end-double4)); - - d = strtod(double5, &end); - ok(almost_equal(d, 214.353), "d = %lf\n", d); - ok(end == double5+9, "incorrect end (%d)\n", (int)(end-double5)); - - d = strtod(double6, &end); - ok(almost_equal(d, 0), "d = %lf\n", d); - ok(end == double6, "incorrect end (%d)\n", (int)(end-double6)); - - d = strtod("12.1d2", NULL); - ok(almost_equal(d, 12.1e2), "d = %lf\n", d); - - d = strtod(white_chars, &end); - ok(almost_equal(d, 0), "d = %lf\n", d); - ok(end == white_chars, "incorrect end (%d)\n", (int)(end-white_chars)); + for (i=0; i DBL_MAX) continue; + snprintf(num, sizeof(num), "%de%d", i, j); + ret = _atodbl(&d, num); + ok(compare_double(d.x, expected, 2), "d.x = %.16e, expected %.16e\n", d.x, expected); + } + } + + /* check with denormal doubles */ strcpy(num, "1e-309"); ret = p__atodbl_l(&d, num, NULL); ok(ret == _UNDERFLOW, "_atodbl_l(&d, \"1e-309\", NULL) returned %d, expected _UNDERFLOW\n", ret); - ok(d.x!=0 && almost_equal(d.x, 0), "d.x = %le, expected 0\n", d.x); + ok(compare_double(d.x, 1e-309, 1), "d.x = %.16e, expected 0\n", d.x); ret = _atodbl(&d, num); ok(ret == _UNDERFLOW, "_atodbl(&d, \"1e-309\") returned %d, expected _UNDERFLOW\n", ret); - ok(d.x!=0 && almost_equal(d.x, 0), "d.x = %le, expected 0\n", d.x); + ok(compare_double(d.x, 1e-309, 1), "d.x = %.16e, expected 0\n", d.x); strcpy(num, "1e309"); ret = p__atodbl_l(&d, num, NULL); @@ -3007,6 +3549,10 @@ static void test__stricmp(void) ok(ret > 0, "_stricmp returned %d\n", ret); ret = _stricmp("\xa5", "\xb9"); ok(ret < 0, "_stricmp returned %d\n", ret); + ret = _stricmp("\xa5\xa1", "\xb9\xa1"); /* valid gbk characters */ + ok(ret < 0, "_stricmp returned %d\n", ret); + ret = _stricmp("abc\xa5\xa1", "abc"); + ok(ret > 0, "_stricmp returned %d\n", ret); if(!setlocale(LC_ALL, "polish")) { win_skip("stricmp tests\n"); @@ -3023,28 +3569,88 @@ static void test__stricmp(void) ok(ret == 0, "_stricmp returned %d\n", ret); ret = _stricmp("a", "\xb9"); ok(ret < 0, "_stricmp returned %d\n", ret); + ret = _stricmp("\xa5\xa1", "\xb9\xa1"); /* valid gbk characters */ + ok(ret == 0, "_stricmp returned %d\n", ret); + ret = _stricmp("abc\xa5\xa1", "abc"); + ok(ret > 0, "_stricmp returned %d\n", ret); - setlocale(LC_ALL, "C"); -} - -static void test__wcstoi64(void) -{ - static const WCHAR digit[] = { '9', 0 }; - static const WCHAR space[] = { ' ', 0 }; - static const WCHAR stock[] = { 0x3231, 0 }; /* PARENTHESIZED IDEOGRAPH STOCK */ - static const WCHAR cjk_1[] = { 0x4e00, 0 }; /* CJK Ideograph, First */ - static const WCHAR tamil[] = { 0x0bef, 0 }; /* TAMIL DIGIT NINE */ - static const WCHAR thai[] = { 0x0e59, 0 }; /* THAI DIGIT NINE */ - static const WCHAR fullwidth[] = { 0xff19, 0 }; /* FULLWIDTH DIGIT NINE */ - static const WCHAR superscript1[] = { 0xb9, 0 }; /* SUPERSCRIPT ONE */ - static const WCHAR minus_0x91[] = { '-', 0x0e50, 'x', 0xff19, '1', 0 }; - static const WCHAR plus_071[] = { '+', 0x0e50, 0xff17, '1', 0 }; - static const WCHAR hex[] = { 0xff19, 'f', 0x0e59, 0xff46, 0 }; - static const WCHAR zeros[] = { - 0x660, 0x6f0, 0x966, 0x9e6, 0xa66, 0xae6, 0xb66, 0xc66, 0xce6, - 0xd66, 0xe50, 0xed0, 0xf20, 0x1040, 0x17e0, 0x1810, 0xff10 - }; - int i; + ok(setlocale(LC_ALL, ".936") != NULL, "setlocale failed.\n"); + ret = _stricmp("test", "test"); + ok(ret == 0, "_stricmp returned %d\n", ret); + ret = _stricmp("a", "z"); + ok(ret < 0, "_stricmp returned %d\n", ret); + ret = _stricmp("z", "a"); + ok(ret > 0, "_stricmp returned %d\n", ret); + ret = _stricmp("\xa5", "\xb9"); + ok(ret < 0, "_stricmp returned %d\n", ret); + ret = _stricmp("a", "\xb9"); + ok(ret < 0, "_stricmp returned %d\n", ret); + ret = _stricmp("\xa5\xa1", "\xb9\xa1"); /* valid gbk characters */ + ok(ret < 0, "_stricmp returned %d\n", ret); + ret = _stricmp("\x82\xa0", "\x83\x41"); /* valid shift-jis characters */ + ok(ret < 0, "_stricmp returned %d\n", ret); + ret = _stricmp("\x81\x00", "\x81\x01"); /* invalid for gbk and shift-jis */ + ok(ret < 0, "_stricmp returned %d\n", ret); + ret = _stricmp("abc\xa5\xa1", "abc"); + ok(ret > 0, "_stricmp returned %d\n", ret); + + skip_2k3_fail ok(setlocale(LC_ALL, "Japanese_Japan.932") != NULL, "setlocale failed.\n"); + ret = _stricmp("test", "test"); + ok(ret == 0, "_stricmp returned %d\n", ret); + ret = _stricmp("a", "z"); + ok(ret < 0, "_stricmp returned %d\n", ret); + ret = _stricmp("z", "a"); + ok(ret > 0, "_stricmp returned %d\n", ret); + ret = _stricmp("\xa5", "\xb9"); + ok(ret < 0, "_stricmp returned %d\n", ret); + ret = _stricmp("\xa5\xa1", "\xb9\xa1"); /* valid gbk characters */ + ok(ret < 0, "_stricmp returned %d\n", ret); + ret = _stricmp("\x82\xa0", "\x83\x41"); /* valid shift-jis characters */ + ok(ret < 0, "_stricmp returned %d\n", ret); + ret = _stricmp("\x81\x00", "\x81\x01"); /* invalid for gbk and shift-jis */ + ok(ret < 0, "_stricmp returned %d\n", ret); + ret = _stricmp("abc\x82\xa0", "abc"); + ok(ret > 0, "_stricmp returned %d\n", ret); + + setlocale(LC_ALL, "C"); +} + +static void test__wcstoi64(void) +{ + static const struct { WCHAR str[24]; __int64 res; unsigned __int64 ures; int base; } tests[] = + { + { L"9", 9, 9, 10 }, + { L" ", 0, 0 }, + { L"-1234", -1234, -1234 }, + { L"\x09\x0a\x0b\x0c\x0d -123", -123, -123 }, + { L"\xa0\x2002\x2003\x2028\x3000 +44", 44, 44 }, + { { 0x3231 }, 0, 0 }, /* PARENTHESIZED IDEOGRAPH STOCK */ + { { 0x4e00 }, 0, 0 }, /* CJK Ideograph, First */ + { { 0x0bef }, 0, 0 }, /* TAMIL DIGIT NINE */ + { { 0x0e59 }, 9, 9 }, /* THAI DIGIT NINE */ + { { 0xff19 }, 9, 9 }, /* FULLWIDTH DIGIT NINE */ + { { 0x00b9 }, 0, 0 }, /* SUPERSCRIPT ONE */ + { { '-',0x0e50,'x',0xff19,'1' }, -0x91, -0x91 }, + { { '+',0x0e50,0xff17,'1' }, 071, 071 }, + { { 0xff19,'f',0x0e59,0xff46 }, 0x9f9, 0x9f9, 16 }, + { L"4294967295", 4294967295, 4294967295 }, + { L"4294967296", 4294967296, 4294967296 }, + { L"9223372036854775807", 9223372036854775807, 9223372036854775807 }, + { L"9223372036854775808", _I64_MAX, 9223372036854775808u }, + { L"18446744073709551615", _I64_MAX, _UI64_MAX }, + { L"18446744073709551616", _I64_MAX, _UI64_MAX }, + { L"-4294967295", -4294967295, -4294967295 }, + { L"-4294967296", -4294967296, -4294967296 }, + { L"-9223372036854775807", -9223372036854775807, -9223372036854775807 }, + { L"-9223372036854775808", _I64_MIN, 9223372036854775808u }, + { L"-18446744073709551615", _I64_MIN, 1 }, + { L"-18446744073709551616", _I64_MIN, 1 }, + }; + static const WCHAR zeros[] = { + 0x660, 0x6f0, 0x966, 0x9e6, 0xa66, 0xae6, 0xb66, 0xc66, 0xce6, + 0xd66, 0xe50, 0xed0, 0xf20, 0x1040, 0x17e0, 0x1810, 0xff10 + }; + int i; __int64 res; unsigned __int64 ures; @@ -3055,51 +3661,21 @@ static void test__wcstoi64(void) return; } - res = p_wcstoi64(digit, NULL, 10); - ok(res == 9, "res != 9\n"); - res = p_wcstoi64(space, &endpos, 0); - ok(endpos == space, "endpos != space\n"); - res = p_wcstoi64(stock, &endpos, 10); - ok(res == 0, "res != 0\n"); - ok(endpos == stock, "Incorrect endpos (%p-%p)\n", stock, endpos); - res = p_wcstoi64(cjk_1, NULL, 0); - ok(res == 0, "res != 0\n"); - res = p_wcstoi64(tamil, &endpos, 10); - ok(res == 0, "res != 0\n"); - ok(endpos == tamil, "Incorrect endpos (%p-%p)\n", tamil, endpos); - res = p_wcstoi64(thai, NULL, 10); - ok(res == 9, "res != 9\n"); - res = p_wcstoi64(fullwidth, NULL, 10); - ok(res == 9, "res != 9\n"); - res = p_wcstoi64(superscript1, NULL, 10); - ok(res == 0, "res != 0\n"); - res = p_wcstoi64(hex, NULL, 16); - ok(res == 0x9f9, "res != 0x9f9\n"); - res = p_wcstoi64(minus_0x91, NULL, 0); - ok(res == -0x91, "res != -0x91\n"); - res = p_wcstoi64(plus_071, NULL, 0); - ok(res == 071, "res != 071\n"); - - ures = p_wcstoui64(digit, NULL, 10); - ok(ures == 9, "ures != 9\n"); - ures = p_wcstoui64(space, &endpos, 0); - ok(endpos == space, "endpos != space\n"); - ures = p_wcstoui64(stock, &endpos, 10); - ok(ures == 0, "ures != 0\n"); - ok(endpos == stock, "Incorrect endpos (%p-%p)\n", stock, endpos); - ures = p_wcstoui64(tamil, &endpos, 10); - ok(ures == 0, "ures != 0\n"); - ok(endpos == tamil, "Incorrect endpos (%p-%p)\n", tamil, endpos); - ures = p_wcstoui64(thai, NULL, 10); - ok(ures == 9, "ures != 9\n"); - ures = p_wcstoui64(fullwidth, NULL, 10); - ok(ures == 9, "ures != 9\n"); - ures = p_wcstoui64(superscript1, NULL, 10); - ok(ures == 0, "ures != 0\n"); - ures = p_wcstoui64(hex, NULL, 16); - ok(ures == 0x9f9, "ures != 0x9f9\n"); - ures = p_wcstoui64(plus_071, NULL, 0); - ok(ures == 071, "ures != 071\n"); + for (i = 0; i < ARRAY_SIZE(tests); i++) + { + if ((i == 20) && (_winver < 0x600)) + { + skip("Skipping test with i = 20, because it fails on Windows 2003\n"); + continue; + } + res = p_wcstoi64( tests[i].str, &endpos, tests[i].base ); + ok( res == tests[i].res, "%u: %s res %s\n", + i, wine_dbgstr_w(tests[i].str), wine_dbgstr_longlong(res) ); + if (!res) ok( endpos == tests[i].str, "%u: wrong endpos %p/%p\n", i, endpos, tests[i].str ); + ures = p_wcstoui64( tests[i].str, &endpos, tests[i].base ); + ok( ures == tests[i].ures, "%u: %s res %s\n", + i, wine_dbgstr_w(tests[i].str), wine_dbgstr_longlong(ures) ); + } /* Test various unicode digits */ for (i = 0; i < ARRAY_SIZE(zeros); ++i) { @@ -3110,8 +3686,67 @@ static void test__wcstoi64(void) res = p_wcstoi64(tmp, NULL, 16); ok(res == 4, "with zero = U+%04X: got %d, expected 4\n", zeros[i], (int)res); } +} + +static void test__wcstol(void) +{ + static const struct { WCHAR str[24]; long res; unsigned long ures; int base; } tests[] = + { + { L"9", 9, 9, 10 }, + { L" ", 0, 0 }, + { L"-1234", -1234, -1234 }, + { L"\x09\x0a\x0b\x0c\x0d -123", -123, -123 }, + { L"\xa0\x2002\x2003\x2028\x3000 +44", 44, 44 }, + { { 0x3231 }, 0, 0 }, /* PARENTHESIZED IDEOGRAPH STOCK */ + { { 0x4e00 }, 0, 0 }, /* CJK Ideograph, First */ + { { 0x0bef }, 0, 0 }, /* TAMIL DIGIT NINE */ + { { 0x0e59 }, 9, 9 }, /* THAI DIGIT NINE */ + { { 0xff19 }, 9, 9 }, /* FULLWIDTH DIGIT NINE */ + { { 0x00b9 }, 0, 0 }, /* SUPERSCRIPT ONE */ + { { '-',0x0e50,'x',0xff19,'1' }, -0x91, -0x91 }, + { { '+',0x0e50,0xff17,'1' }, 071, 071 }, + { { 0xff19,'f',0x0e59,0xff46 }, 0x9f9, 0x9f9, 16 }, + { L"2147483647", 2147483647, 2147483647 }, + { L"2147483648", LONG_MAX, 2147483648 }, + { L"4294967295", LONG_MAX, 4294967295 }, + { L"4294967296", LONG_MAX, ULONG_MAX }, + { L"9223372036854775807", LONG_MAX, ULONG_MAX }, + { L"-2147483647", -2147483647, -2147483647 }, + { L"-2147483648", LONG_MIN, LONG_MIN }, + { L"-4294967295", LONG_MIN, 1 }, + { L"-4294967296", LONG_MIN, 1 }, + { L"-9223372036854775807", LONG_MIN, 1 }, + }; + static const WCHAR zeros[] = { + 0x660, 0x6f0, 0x966, 0x9e6, 0xa66, 0xae6, 0xb66, 0xc66, 0xce6, + 0xd66, 0xe50, 0xed0, 0xf20, 0x1040, 0x17e0, 0x1810, 0xff10 + }; + int i; - return; + long res; + unsigned long ures; + WCHAR *endpos; + + for (i = 0; i < ARRAY_SIZE(tests); i++) + { + res = wcstol( tests[i].str, &endpos, tests[i].base ); + ok( res == tests[i].res, "%u: %s res %08lx\n", + i, wine_dbgstr_w(tests[i].str), res ); + if (!res) ok( endpos == tests[i].str, "%u: wrong endpos %p/%p\n", i, endpos, tests[i].str ); + ures = wcstoul( tests[i].str, &endpos, tests[i].base ); + ok( ures == tests[i].ures, "%u: %s res %08lx\n", + i, wine_dbgstr_w(tests[i].str), ures ); + } + + /* Test various unicode digits */ + for (i = 0; i < ARRAY_SIZE(zeros); ++i) { + WCHAR tmp[] = {zeros[i] + 4, zeros[i], zeros[i] + 5, 0}; + res = wcstol(tmp, NULL, 0); + ok(res == 405, "with zero = U+%04X: got %d, expected 405\n", zeros[i], (int)res); + tmp[1] = zeros[i] + 10; + res = wcstol(tmp, NULL, 16); + ok(res == 4, "with zero = U+%04X: got %d, expected 4\n", zeros[i], (int)res); + } } static void test_atoi(void) @@ -3153,13 +3788,13 @@ static void test_atof(void) double d; d = atof("0.0"); - ok(almost_equal(d, 0.0), "d = %lf\n", d); + ok(d == 0.0, "d = %lf\n", d); d = atof("1.0"); - ok(almost_equal(d, 1.0), "d = %lf\n", d); + ok(d == 1.0, "d = %lf\n", d); d = atof("-1.0"); - ok(almost_equal(d, -1.0), "d = %lf\n", d); + ok(d == -1.0, "d = %lf\n", d); if (!p__atof_l) { @@ -3169,12 +3804,12 @@ static void test_atof(void) errno = EBADF; d = atof(NULL); - ok(almost_equal(d, 0.0), "d = %lf\n", d); + ok(d == 0.0, "d = %lf\n", d); ok(errno == EINVAL, "errno = %x\n", errno); errno = EBADF; d = p__atof_l(NULL, NULL); - ok(almost_equal(d, 0.0), "d = %lf\n", d); + ok(d == 0.0, "d = %lf\n", d); ok(errno == EINVAL, "errno = %x\n", errno); } @@ -3311,7 +3946,7 @@ static void test__strnset_s(void) static void test__wcsnset_s(void) { - wchar_t text[] = { 't','e','x','t',0 }; + wchar_t text[] = L"text"; int r; if(!p__wcsnset_s) { @@ -3411,6 +4046,15 @@ static void test__mbscmp(void) ret = _mbscmp(b, a); ok(ret == 1, "got %d\n", ret); + + if (!p_mbscmp_l) + { + win_skip("_mbscmp_l tests\n"); + return; + } + + ret = p_mbscmp_l(a, b, NULL); + ok(ret == -1, "got %d\n", ret); } static void test__ismbclx(void) @@ -3550,6 +4194,7 @@ static void test__memicmp_l(void) static void test__strupr(void) { const char str[] = "123"; + const char *const_p; char str2[4]; char *mem, *p; DWORD prot; @@ -3568,6 +4213,10 @@ static void test__strupr(void) ok(p == mem, "_strupr returned %p\n", p); ok(!strcmp(mem, "123"), "mem = %s\n", mem); + const_p = "ALREADY_UPPERCASE"; + p = _strupr((char *)const_p); + ok(p == const_p, "_strupr returned %p\n", p); + if(!setlocale(LC_ALL, "english")) { VirtualFree(mem, sizeof(str), MEM_RELEASE); win_skip("English locale _strupr tests\n"); @@ -3614,6 +4263,9 @@ static void test__tcsncoll(void) { "English", "ABCe", "ABCf", 3, 0 }, { "English", "abcd", "ABCD", 10, -1 }, + { "English", "AB D", "AB-D", 4, 1 }, + { "English", "AB D", "AB'D", 4, 1 }, + { "C", "ABCD", "ABCD", 4, 0 }, { "C", "ABCD", "ABCD", 10, 0 }, @@ -3625,6 +4277,9 @@ static void test__tcsncoll(void) { "C", "ABCe", "ABCf", 3, 0 }, { "C", "abcd", "ABCD", 10, 1 }, + + { "C", "AB D", "AB-D", 4, -1 }, + { "C", "AB D", "AB'D", 4, -1 }, }; WCHAR str1W[16]; WCHAR str2W[16]; @@ -3651,11 +4306,14 @@ static void test__tcsncoll(void) ret = _strncoll(str1, str2, tests[i].count); if (!tests[i].exp) - ok(!ret, "expected 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); + ok(!ret, "expected 0, got %d for %s, %s, %d for locale %s\n", + ret, str1, str2, (int)tests[i].count, tests[i].locale); else if (tests[i].exp < 0) - ok(ret < 0, "expected < 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); + ok(ret < 0, "expected < 0, got %d for %s, %s, %d for locale %s\n", + ret, str1, str2, (int)tests[i].count, tests[i].locale); else - ok(ret > 0, "expected > 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); + ok(ret > 0, "expected > 0, got %d for %s, %s, %d for locale %s\n", + ret, str1, str2, (int)tests[i].count, tests[i].locale); memset(str1W, 0xee, sizeof(str1W)); len = mbstowcs(str1W, str1, ARRAY_SIZE(str1W)); @@ -3667,11 +4325,94 @@ static void test__tcsncoll(void) ret = _wcsncoll(str1W, str2W, tests[i].count); if (!tests[i].exp) - ok(!ret, "expected 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); + ok(!ret, "expected 0, got %d for %s, %s, %d for locale %s\n", + ret, str1, str2, (int)tests[i].count, tests[i].locale); else if (tests[i].exp < 0) - ok(ret < 0, "expected < 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); + ok(ret < 0, "expected < 0, got %d for %s, %s, %d for locale %s\n", + ret, str1, str2, (int)tests[i].count, tests[i].locale); else - ok(ret > 0, "expected > 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); + ok(ret > 0, "expected > 0, got %d for %s, %s, %d for locale %s\n", + ret, str1, str2, (int)tests[i].count, tests[i].locale); + } +} + +static void test__tcscoll(void) +{ + struct test { + const char *locale; + const char *str1; + const char *str2; + int exp; + }; + static const struct test tests[] = { + { "English", "ABCD", "ABCD", 0 }, + { "English", "ABC", "ABCD", -1 }, + { "English", "ABCD", "ABC", 1 }, + { "English", "ABCe", "ABCf", -1 }, + { "English", "abcd", "ABCD", -1 }, + { "English", "AB D", "AB-D", 1 }, + { "English", "AB D", "AB'D", 1 }, + + { "C", "ABCD", "ABCD", 0 }, + { "C", "ABC", "ABCD", -1 }, + { "C", "ABCD", "ABC", 1 }, + { "C", "ABCe", "ABCf", -1 }, + { "C", "abcd", "ABCD", 1 }, + { "C", "AB D", "AB-D", -1 }, + { "C", "AB D", "AB'D", -1 }, + }; + WCHAR str1W[16]; + WCHAR str2W[16]; + char str1[16]; + char str2[16]; + size_t len; + int i, ret; + + for (i = 0; i < ARRAY_SIZE(tests); i++) + { + if (!setlocale(LC_ALL, tests[i].locale)) + { + win_skip("%s locale _tcsncoll tests\n", tests[i].locale); + for (; i+1 < ARRAY_SIZE(tests); i++) + if (strcmp(tests[i].locale, tests[i+1].locale)) break; + continue; + } + + memset(str1, 0xee, sizeof(str1)); + strcpy(str1, tests[i].str1); + + memset(str2, 0xff, sizeof(str2)); + strcpy(str2, tests[i].str2); + + ret = strcoll(str1, str2); + if (!tests[i].exp) + ok(!ret, "expected 0, got %d for %s, %s for locale %s\n", + ret, str1, str2, tests[i].locale); + else if (tests[i].exp < 0) + ok(ret < 0, "expected < 0, got %d for %s, %s for locale %s\n", + ret, str1, str2, tests[i].locale); + else + ok(ret > 0, "expected > 0, got %d for %s, %s for locale %s\n", + ret, str1, str2, tests[i].locale); + + memset(str1W, 0xee, sizeof(str1W)); + len = mbstowcs(str1W, str1, ARRAY_SIZE(str1W)); + str1W[len] = 0; + + memset(str2W, 0xff, sizeof(str2W)); + len = mbstowcs(str2W, str2, ARRAY_SIZE(str2W)); + str2W[len] = 0; + + ret = wcscoll(str1W, str2W); + if (!tests[i].exp) + ok(!ret, "expected 0, got %d for %s, %s for locale %s\n", + ret, str1, str2, tests[i].locale); + else if (tests[i].exp < 0) + ok(ret < 0, "expected < 0, got %d for %s, %s for locale %s\n", + ret, str1, str2, tests[i].locale); + else + ok(ret > 0, "expected > 0, got %d for %s, %s for locale %s\n", + ret, str1, str2, tests[i].locale); } } @@ -3856,6 +4597,456 @@ static void test_C_locale(void) } } +static void test_strstr(void) +{ + static char long_str[1024]; + const struct { + const char *haystack; + const char *needle; + int off; + } tests[] = { + { "", "", 0 }, + { "", "a", -1 }, + { "a", "", 0 }, + { "aabc", "abc", 1 }, + { "aaaa", "aaaa", 0 }, + { "simple", "simple", 0 }, + { "aaaaxaaaaxaaaa", "aaaaa", -1 }, + { "aaaaxaaaaxaaaaa", "aaaaa", 10 }, + { "abcabcdababcdabcdabde", "abcdabd", 13 }, + { "abababababcabababcababbba", "abababcaba", 4 }, + { long_str, long_str+1, 0 } + }; + const char *r, *exp; + int i; + + memset(long_str, 'a', sizeof(long_str)-1); + + for (i=0; ild) + 1]; + int i; + + for(i=0; ild); i++) + { + buf[2*i] = v->ld[i] / 16 + '0'; + if(buf[2*i] > '9') buf[2*i] -= 10 + '0' - 'a'; + buf[2*i+1] = v->ld[i] % 16 + '0'; + if(buf[2*i+1] > '9') buf[2*i+1] -= 10 + '0' - 'a'; + } + buf[2 * ARRAY_SIZE(v->ld)] = 0; + return buf; +} + +static void test___STRINGTOLD(void) +{ + static const struct { + const char *str; + int endptr; + int r; + _LDOUBLE v; + BOOL todo; + } tests[] = { + { "0", 1 }, + { "nan", 0, 4 }, + { "inf", 0, 4 }, + { "-0.0", 4, 0, {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 }} }, + { "1e0", 3, 0, {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x3f }} }, + { "1.7976931348623158e+308", 23, 0, {{ 0xaf, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x43 }} }, + { "1.7976931348623159e+308", 23, 0, {{ 0xb1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x43 }} }, + { "3.65e-4951", 10, 0, {{ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }} }, + { "1.82e-4951", 10, 0, {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }}, TRUE }, + { "1e-99999", 8, 1, {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }} }, + { "1.18e+4932", 10, 0, {{ 0x25, 0x75, 0x06, 0x68, 0x8a, 0xf1, 0xe7, 0xfd, 0xfe, 0x7f }} }, + { "1.19e+4932", 10, 2, {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x7f }} }, + { "1e+99999", 8, 2, {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x7f }} }, + }; + + char *endptr; + _LDOUBLE v; + int i, r; + + for(i=0; i 0, "tests[%d]: Got %d.\n", i, ret); + + ret = p__strnicmp_l(tests[i].str2, tests[i].str1, INT_MAX, 0); + ok(ret < 0, "tests[%d]: Got %d.\n", i, ret); + } + + if (!p__create_locale) + win_skip("_create_locale isn't available.\n"); + else + { + locale = p__create_locale(LC_ALL, ".936"); + ok(locale != NULL, "Failed to create locale.\n"); + + for (i = 0; i < ARRAY_SIZE(tests); i++) + { + ret = p__strnicmp_l(tests[i].str1, tests[i].str2, INT_MAX, locale); + ok(ret > 0, "tests[%d]: Got %d.\n", i, ret); + + ret = p__strnicmp_l(tests[i].str2, tests[i].str1, INT_MAX, locale); + ok(ret < 0, "tests[%d]: Got %d.\n", i, ret); + } + + p__free_locale(locale); + } + + if (!setlocale(LC_ALL, ".936")) + { + win_skip("Skip testing _strnicmp_l with 936 code page.\n"); + return; + } + + for (i = 0; i < ARRAY_SIZE(tests); i++) + { + ret = p__strnicmp_l(tests[i].str1, tests[i].str2, INT_MAX, 0); + ok(ret > 0, "tests[%d]: Got %d.\n", i, ret); + + ret = p__strnicmp_l(tests[i].str2, tests[i].str1, INT_MAX, 0); + ok(ret < 0, "tests[%d]: Got %d.\n", i, ret); + } + + setlocale(LC_ALL, "C"); +} + +static void test_toupper(void) +{ + int ret; + + ok(setlocale(LC_ALL, "English_United States") != NULL, "setlocale failed.\n"); + errno = 0xdeadbeef; + ret = p_toupper((signed char)0xf0); + ok(ret == 0xd0, "Got %#x.\n", ret); + skip_2k3_fail ok(errno == EILSEQ, "Got errno %d.\n", errno); + errno = 0xdeadbeef; + ret = p_toupper(0xf0); + ok(ret == 0xd0, "Got %#x.\n", ret); + ok(errno == 0xdeadbeef, "Got errno %d.\n", errno); + + ok(setlocale(LC_ALL, "Polish") != NULL, "setlocale failed.\n"); + errno = 0xdeadbeef; + ret = p_toupper((signed char)0xa5); + ok(ret == 0xa5, "Got %#x.\n", ret); + skip_2k3_fail ok(errno == EILSEQ, "Got errno %d.\n", errno); + errno = 0xdeadbeef; + ret = p_toupper((signed char)0xb9); + ok(ret == 0xa5, "Got %#x.\n", ret); + skip_2k3_fail ok(errno == EILSEQ, "Got errno %d.\n", errno); + + skip_2k3_fail { + ok(setlocale(LC_ALL, "Japanese_Japan.932") != NULL, "setlocale failed.\n"); + errno = 0xdeadbeef; + ret = p_toupper((signed char)0xf0); + ok(ret == (signed char)0xf0, "Got %#x.\n", ret); + ok(errno == EILSEQ, "Got errno %d.\n", errno); + errno = 0xdeadbeef; + ret = p_toupper(0xf0); + ok(ret == 0xf0, "Got %#x.\n", ret); + ok(errno == 0xdeadbeef, "Got errno %d.\n", errno); + + ok(setlocale(LC_ALL, "Chinese_China.936") != NULL, "setlocale failed.\n"); + errno = 0xdeadbeef; + ret = p_toupper((signed char)0xf0); + ok(ret == (signed char)0xf0, "Got %#x.\n", ret); + ok(errno == EILSEQ, "Got errno %d.\n", errno); + errno = 0xdeadbeef; + ret = p_toupper(0xf0); + ok(ret == 0xf0, "Got %#x.\n", ret); + ok(errno == 0xdeadbeef, "Got errno %d.\n", errno); + } + + setlocale(LC_ALL, "C"); +} + START_TEST(string) { char mem[100]; @@ -3873,8 +5064,12 @@ START_TEST(string) SET(p_mbctype,"_mbctype"); SET(p__mb_cur_max,"__mb_cur_max"); SET(p_strcpy, "strcpy"); + SET(p_strcmp, "strcmp"); + SET(p_strncmp, "strncmp"); pstrcpy_s = (void *)GetProcAddress( hMsvcrt,"strcpy_s" ); pstrcat_s = (void *)GetProcAddress( hMsvcrt,"strcat_s" ); + p_strncpy_s = (void *)GetProcAddress( hMsvcrt, "strncpy_s" ); + p_strncat_s = (void *)GetProcAddress( hMsvcrt, "strncat_s" ); p_mbscat_s = (void*)GetProcAddress( hMsvcrt, "_mbscat_s" ); p_mbsnbcat_s = (void *)GetProcAddress( hMsvcrt,"_mbsnbcat_s" ); p_mbsnbcpy_s = (void *)GetProcAddress( hMsvcrt,"_mbsnbcpy_s" ); @@ -3890,6 +5085,7 @@ START_TEST(string) p_wcstoui64 = (void *)GetProcAddress(hMsvcrt, "_wcstoui64"); pmbstowcs_s = (void *)GetProcAddress(hMsvcrt, "mbstowcs_s"); pwcstombs_s = (void *)GetProcAddress(hMsvcrt, "wcstombs_s"); + p_wcstombs_s_l = (void *)GetProcAddress(hMsvcrt, "_wcstombs_s_l"); pwcsrtombs = (void *)GetProcAddress(hMsvcrt, "wcsrtombs"); p_gcvt_s = (void *)GetProcAddress(hMsvcrt, "_gcvt_s"); p_itoa_s = (void *)GetProcAddress(hMsvcrt, "_itoa_s"); @@ -3898,6 +5094,7 @@ START_TEST(string) p_wcslwr_s = (void*)GetProcAddress(hMsvcrt, "_wcslwr_s"); p_mbsupr_s = (void*)GetProcAddress(hMsvcrt, "_mbsupr_s"); p_mbslwr_s = (void*)GetProcAddress(hMsvcrt, "_mbslwr_s"); + p_btowc = (void*)GetProcAddress(hMsvcrt, "btowc"); p_wctob = (void*)GetProcAddress(hMsvcrt, "wctob"); p_wcrtomb = (void*)GetProcAddress(hMsvcrt, "wcrtomb"); p_wcrtomb_s = (void*)GetProcAddress(hMsvcrt, "wcrtomb_s"); @@ -3923,6 +5120,10 @@ START_TEST(string) p__memicmp = (void*)GetProcAddress(hMsvcrt, "_memicmp"); p__memicmp_l = (void*)GetProcAddress(hMsvcrt, "_memicmp_l"); p___strncnt = (void*)GetProcAddress(hMsvcrt, "__strncnt"); + p_mbsnextc_l = (void*)GetProcAddress(hMsvcrt, "_mbsnextc_l"); + p_mbscmp_l = (void*)GetProcAddress(hMsvcrt, "_mbscmp_l"); + p__strnicmp_l = (void*)GetProcAddress(hMsvcrt, "_strnicmp_l"); + p_toupper = (void*)GetProcAddress(hMsvcrt, "toupper"); /* MSVCRT memcpy behaves like memmove for overlapping moves, MFC42 CString::Insert seems to rely on that behaviour */ @@ -3935,14 +5136,18 @@ START_TEST(string) /* run tolower tests first */ test_tolower(); test_swab(); + test_strcspn(); test_mbcp(); test_mbsspn(); test_mbsspnp(); test_strdup(); + test_wcsdup(); + test_strcmp(); test_strcpy_s(); test_memcpy_s(); test_memmove_s(); test_strcat_s(); + test_strncat_s(); test__mbscat_s(); test__mbsnbcpy_s(); test__mbscpy_s(); @@ -3963,6 +5168,7 @@ START_TEST(string) test__strtoi64(); test__strtod(); test_mbstowcs(); + test__wcstombs_s_l(); test_gcvt(); test__itoa_s(); test__strlwr_s(); @@ -3973,10 +5179,12 @@ START_TEST(string) test__mbsupr_s(); test__mbslwr_s(); test_wctob(); + test_btowc(); test_wctomb(); test__atodbl(); test__stricmp(); test__wcstoi64(); + test__wcstol(); test_atoi(); test_atol(); test_atof(); @@ -3991,7 +5199,21 @@ START_TEST(string) test__memicmp_l(); test__strupr(); test__tcsncoll(); + test__tcscoll(); test__tcsnicoll(); test___strncnt(); test_C_locale(); + test_strstr(); + test_iswdigit(); + test_wcscmp(); + test___STRINGTOLD(); + test_SpecialCasing(); + test__mbbtype(); + test_wcsncpy(); + test_mbsrev(); +#ifndef __REACTOS__ + test__tolower_l(); +#endif + test__strnicmp_l(); + test_toupper(); } diff --git a/modules/rostests/winetests/msvcrt/time.c b/modules/rostests/winetests/msvcrt/time.c index cf79e5971ecf4..aba911f30a470 100644 --- a/modules/rostests/winetests/msvcrt/time.c +++ b/modules/rostests/winetests/msvcrt/time.c @@ -36,10 +36,27 @@ #define MINSPERHOUR 60 #define HOURSPERDAY 24 +typedef struct { + const char *short_wday[7]; + const char *wday[7]; + const char *short_mon[12]; + const char *mon[12]; + const char *am; + const char *pm; + const char *short_date; + const char *date; + const char *time; + LCID lcid; + int unk; + int refcount; +} __lc_time_data; + static __time32_t (__cdecl *p_mkgmtime32)(struct tm*); static struct tm* (__cdecl *p_gmtime32)(__time32_t*); static struct tm* (__cdecl *p_gmtime)(time_t*); static errno_t (__cdecl *p_gmtime32_s)(struct tm*, __time32_t*); +static struct tm* (__cdecl *p_gmtime64)(__time64_t*); +static errno_t (__cdecl *p_gmtime64_s)(struct tm*, __time64_t*); static errno_t (__cdecl *p_strtime_s)(char*,size_t); static errno_t (__cdecl *p_strdate_s)(char*,size_t); static errno_t (__cdecl *p_localtime32_s)(struct tm*, __time32_t*); @@ -50,6 +67,7 @@ static long* (__cdecl *p___p__dstbias)(void); static long* (__cdecl *p__dstbias)(void); static long* (__cdecl *p___p__timezone)(void); static size_t (__cdecl *p_strftime)(char *, size_t, const char *, const struct tm *); +static size_t (__cdecl *p__Strftime)(char*, size_t, const char*, const struct tm*, void*); static size_t (__cdecl *p_wcsftime)(wchar_t *, size_t, const wchar_t *, const struct tm *); static char* (__cdecl *p_asctime)(const struct tm *); @@ -60,6 +78,8 @@ static void init(void) p_gmtime32 = (void*)GetProcAddress(hmod, "_gmtime32"); p_gmtime = (void*)GetProcAddress(hmod, "gmtime"); p_gmtime32_s = (void*)GetProcAddress(hmod, "_gmtime32_s"); + p_gmtime64 = (void*)GetProcAddress(hmod, "_gmtime64"); + p_gmtime64_s = (void*)GetProcAddress(hmod, "_gmtime64_s"); p_mkgmtime32 = (void*)GetProcAddress(hmod, "_mkgmtime32"); p_strtime_s = (void*)GetProcAddress(hmod, "_strtime_s"); p_strdate_s = (void*)GetProcAddress(hmod, "_strdate_s"); @@ -71,6 +91,7 @@ static void init(void) p__dstbias = (void*)GetProcAddress(hmod, "__dstbias"); p___p__timezone = (void*)GetProcAddress(hmod, "__p__timezone"); p_strftime = (void*)GetProcAddress(hmod, "strftime"); + p__Strftime = (void*)GetProcAddress(hmod, "_Strftime"); p_wcsftime = (void*)GetProcAddress(hmod, "wcsftime"); p_asctime = (void*)GetProcAddress(hmod, "asctime"); } @@ -134,21 +155,21 @@ static void test_gmtime(void) gmt_tm->tm_wday = gmt_tm->tm_yday = 0; gmt = p_mkgmtime32(gmt_tm); - ok(gmt == valid, "gmt = %u\n", gmt); + ok(gmt == valid, "gmt = %lu\n", gmt); ok(gmt_tm->tm_wday == 4, "gmt_tm->tm_wday = %d\n", gmt_tm->tm_wday); ok(gmt_tm->tm_yday == 0, "gmt_tm->tm_yday = %d\n", gmt_tm->tm_yday); gmt_tm->tm_wday = gmt_tm->tm_yday = 0; gmt_tm->tm_isdst = -1; gmt = p_mkgmtime32(gmt_tm); - ok(gmt == valid, "gmt = %u\n", gmt); + ok(gmt == valid, "gmt = %lu\n", gmt); ok(gmt_tm->tm_wday == 4, "gmt_tm->tm_wday = %d\n", gmt_tm->tm_wday); ok(gmt_tm->tm_yday == 0, "gmt_tm->tm_yday = %d\n", gmt_tm->tm_yday); gmt_tm->tm_wday = gmt_tm->tm_yday = 0; gmt_tm->tm_isdst = 1; gmt = p_mkgmtime32(gmt_tm); - ok(gmt == valid, "gmt = %u\n", gmt); + ok(gmt == valid, "gmt = %lu\n", gmt); ok(gmt_tm->tm_wday == 4, "gmt_tm->tm_wday = %d\n", gmt_tm->tm_wday); ok(gmt_tm->tm_yday == 0, "gmt_tm->tm_yday = %d\n", gmt_tm->tm_yday); @@ -161,13 +182,13 @@ static void test_gmtime(void) gmt_tm->tm_isdst = -1; gmt = p_mkgmtime32(gmt_tm); - ok(gmt == valid, "gmt = %u\n", gmt); + ok(gmt == valid, "gmt = %lu\n", gmt); ok(gmt_tm->tm_wday == 6, "gmt_tm->tm_wday = %d\n", gmt_tm->tm_wday); ok(gmt_tm->tm_yday == 2, "gmt_tm->tm_yday = %d\n", gmt_tm->tm_yday); gmt_tm->tm_isdst = 1; gmt = p_mkgmtime32(gmt_tm); - ok(gmt == valid, "gmt = %u\n", gmt); + ok(gmt == valid, "gmt = %lu\n", gmt); if(!p_gmtime32_s) { win_skip("Skipping _gmtime32_s tests\n"); @@ -191,6 +212,78 @@ static void test_gmtime(void) } } +static void test_gmtime64(void) +{ + struct tm *ptm, tm; + __time64_t t; + int ret; + + t = -1; + memset(&tm, 0xcc, sizeof(tm)); + ptm = p_gmtime64(&t); + if (!ptm) + { + skip("Old gmtime64 limits, skipping tests.\n"); + return; + } + ok(!!ptm, "got NULL.\n"); + ret = p_gmtime64_s(&tm, &t); + ok(!ret, "got %d.\n", ret); + ok(tm.tm_year == 69 && tm.tm_hour == 23 && tm.tm_min == 59 && tm.tm_sec == 59, "got %d, %d, %d, %d.\n", + tm.tm_year, tm.tm_hour, tm.tm_min, tm.tm_sec); + + t = -43200; + memset(&tm, 0xcc, sizeof(tm)); + ptm = p_gmtime64(&t); + ok(!!ptm, "got NULL.\n"); + ret = p_gmtime64_s(&tm, &t); + ok(!ret, "got %d.\n", ret); + ok(tm.tm_year == 69 && tm.tm_hour == 12 && tm.tm_min == 0 && tm.tm_sec == 0, "got %d, %d, %d, %d.\n", + tm.tm_year, tm.tm_hour, tm.tm_min, tm.tm_sec); + ptm = p_gmtime32((__time32_t *)&t); + ok(!!ptm, "got NULL.\n"); + memset(&tm, 0xcc, sizeof(tm)); + ret = p_gmtime32_s(&tm, (__time32_t *)&t); + ok(!ret, "got %d.\n", ret); + todo_wine_if(tm.tm_year == 69 && tm.tm_hour == 12) + ok(tm.tm_year == 70 && tm.tm_hour == -12 && tm.tm_min == 0 && tm.tm_sec == 0, "got %d, %d, %d, %d.\n", + tm.tm_year, tm.tm_hour, tm.tm_min, tm.tm_sec); + + t = -43201; + ptm = p_gmtime64(&t); + ok(!ptm, "got non-NULL.\n"); + memset(&tm, 0xcc, sizeof(tm)); + ret = p_gmtime64_s(&tm, &t); + ok(ret == EINVAL, "got %d.\n", ret); + ok(tm.tm_year == -1 && tm.tm_hour == -1 && tm.tm_min == -1 && tm.tm_sec == -1, "got %d, %d, %d, %d.\n", + tm.tm_year, tm.tm_hour, tm.tm_min, tm.tm_sec); + ptm = p_gmtime32((__time32_t *)&t); + ok(!ptm, "got NULL.\n"); + memset(&tm, 0xcc, sizeof(tm)); + ret = p_gmtime32_s(&tm, (__time32_t *)&t); + ok(ret == EINVAL, "got %d.\n", ret); + ok(tm.tm_year == -1 && tm.tm_hour == -1 && tm.tm_min == -1 && tm.tm_sec == -1, "got %d, %d, %d, %d.\n", + tm.tm_year, tm.tm_hour, tm.tm_min, tm.tm_sec); + + t = _MAX__TIME64_T + 46800; + memset(&tm, 0xcc, sizeof(tm)); + ptm = p_gmtime64(&t); + ok(!!ptm, "got NULL.\n"); + ret = p_gmtime64_s(&tm, &t); + ok(!ret, "got %d.\n", ret); + ok(tm.tm_year == 1101 && tm.tm_hour == 20 && tm.tm_min == 59 && tm.tm_sec == 59, "got %d, %d, %d, %d.\n", + tm.tm_year, tm.tm_hour, tm.tm_min, tm.tm_sec); + + t = _MAX__TIME64_T + 46801; + ptm = p_gmtime64(&t); + ok(!ptm, "got non-NULL.\n"); + memset(&tm, 0xcc, sizeof(tm)); + ret = p_gmtime64_s(&tm, &t); + ok(ret == EINVAL, "got %d.\n", ret); + ok(tm.tm_year == -1 && tm.tm_hour == -1 && tm.tm_min == -1 && tm.tm_sec == -1, "got %d, %d, %d, %d.\n", + tm.tm_year, tm.tm_hour, tm.tm_min, tm.tm_sec); +} + static void test_mktime(void) { TIME_ZONE_INFORMATION tzinfo; @@ -207,7 +300,7 @@ static void test_mktime(void) ok (res != TIME_ZONE_ID_INVALID, "GetTimeZoneInformation failed\n"); WideCharToMultiByte( CP_ACP, 0, tzinfo.StandardName, -1, buffer, sizeof(buffer), NULL, NULL ); - trace( "bias %d std %d dst %d zone %s\n", + trace( "bias %ld std %ld dst %ld zone %s\n", tzinfo.Bias, tzinfo.StandardBias, tzinfo.DaylightBias, buffer ); /* Bias may be positive or negative, to use offset of one day */ my_tm = *localtime(&ref); /* retrieve current dst flag */ @@ -227,14 +320,14 @@ static void test_mktime(void) sav_tm = my_tm; local_time = mktime(&my_tm); - ok(local_time == ref, "mktime returned %u, expected %u\n", + ok(local_time == ref, "mktime returned %lu, expected %lu\n", (DWORD)local_time, (DWORD)ref); /* now test some unnormalized struct tm's */ my_tm = sav_tm; my_tm.tm_sec += 60; my_tm.tm_min -= 1; local_time = mktime(&my_tm); - ok(local_time == ref, "Unnormalized mktime returned %u, expected %u\n", + ok(local_time == ref, "Unnormalized mktime returned %lu, expected %lu\n", (DWORD)local_time, (DWORD)ref); ok( my_tm.tm_year == sav_tm.tm_year && my_tm.tm_mon == sav_tm.tm_mon && my_tm.tm_mday == sav_tm.tm_mday && my_tm.tm_hour == sav_tm.tm_hour && @@ -248,7 +341,7 @@ static void test_mktime(void) my_tm.tm_min -= 60; my_tm.tm_hour += 1; local_time = mktime(&my_tm); - ok(local_time == ref, "Unnormalized mktime returned %u, expected %u\n", + ok(local_time == ref, "Unnormalized mktime returned %lu, expected %lu\n", (DWORD)local_time, (DWORD)ref); ok( my_tm.tm_year == sav_tm.tm_year && my_tm.tm_mon == sav_tm.tm_mon && my_tm.tm_mday == sav_tm.tm_mday && my_tm.tm_hour == sav_tm.tm_hour && @@ -262,7 +355,7 @@ static void test_mktime(void) my_tm.tm_mon -= 12; my_tm.tm_year += 1; local_time = mktime(&my_tm); - ok(local_time == ref, "Unnormalized mktime returned %u, expected %u\n", + ok(local_time == ref, "Unnormalized mktime returned %lu, expected %lu\n", (DWORD)local_time, (DWORD)ref); ok( my_tm.tm_year == sav_tm.tm_year && my_tm.tm_mon == sav_tm.tm_mon && my_tm.tm_mday == sav_tm.tm_mday && my_tm.tm_hour == sav_tm.tm_hour && @@ -276,7 +369,7 @@ static void test_mktime(void) my_tm.tm_mon += 12; my_tm.tm_year -= 1; local_time = mktime(&my_tm); - ok(local_time == ref, "Unnormalized mktime returned %u, expected %u\n", + ok(local_time == ref, "Unnormalized mktime returned %lu, expected %lu\n", (DWORD)local_time, (DWORD)ref); ok( my_tm.tm_year == sav_tm.tm_year && my_tm.tm_mon == sav_tm.tm_mon && my_tm.tm_mday == sav_tm.tm_mday && my_tm.tm_hour == sav_tm.tm_hour && @@ -298,7 +391,7 @@ static void test_mktime(void) _snprintf(TZ_env,255,"TZ=%s",(getenv("TZ")?getenv("TZ"):"")); putenv("TZ=GMT"); nulltime = mktime(&my_tm); - ok(nulltime == ref,"mktime returned 0x%08x\n",(DWORD)nulltime); + ok(nulltime == ref,"mktime returned 0x%08lx\n",(DWORD)nulltime); putenv(TZ_env); } @@ -425,13 +518,12 @@ static void test_wstrdate(void) { wchar_t date[16], * result; int month, day, year, count, len; - wchar_t format[] = { '%','0','2','d','/','%','0','2','d','/','%','0','2','d',0 }; result = _wstrdate(date); ok(result == date, "Wrong return value\n"); len = wcslen(date); ok(len == 8, "Wrong length: returned %d, should be 8\n", len); - count = swscanf(date, format, &month, &day, &year); + count = swscanf(date, L"%02d/%02d/%02d", &month, &day, &year); ok(count == 3, "Wrong format: count = %d, should be 3\n", count); } @@ -439,13 +531,12 @@ static void test_wstrtime(void) { wchar_t time[16], * result; int hour, minute, second, count, len; - wchar_t format[] = { '%','0','2','d',':','%','0','2','d',':','%','0','2','d',0 }; result = _wstrtime(time); ok(result == time, "Wrong return value\n"); len = wcslen(time); ok(len == 8, "Wrong length: returned %d, should be 8\n", len); - count = swscanf(time, format, &hour, &minute, &second); + count = swscanf(time, L"%02d:%02d:%02d", &hour, &minute, &second); ok(count == 3, "Wrong format: count = %d, should be 3\n", count); } @@ -575,26 +666,148 @@ static void test_daylight(void) return; } - if (!p___p__daylight) + /* Examine the returned pointer from __p__environ(), if available. */ + if (sizeof(void*) != sizeof(int)) + ok( !p___p__daylight, "___p__daylight() should be 32-bit only\n"); + else { - skip("__p__daylight not available\n"); - return; + ret1 = p__daylight(); + ret2 = p___p__daylight(); + ok(ret1 && ret1 == ret2, "got %p\n", ret1); } - - ret1 = p__daylight(); - ret2 = p___p__daylight(); - ok(ret1 && ret1 == ret2, "got %p\n", ret1); } static void test_strftime(void) { - static const wchar_t cW[] = { '%','c',0 }; - static const char expected[] = "01/01/70 00:00:00"; + const struct { + const char *format; + } tests_einval[] = { + {"%C"}, + {"%D"}, + {"%e"}, + {"%F"}, + {"%h"}, + {"%n"}, + {"%R"}, + {"%t"}, + {"%T"}, + {"%u"}, + }; + + const struct { + const char *format; + const char *ret; + struct tm tm; + BOOL todo; + } tests[] = { + {"e%#%e", "e%e", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%c", "01/01/70 00:00:00", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%c", "02/30/70 00:00:00", { 0, 0, 0, 30, 1, 70, 4, 0, 0 }}, + {"%#c", "Thursday, January 01, 1970 00:00:00", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%#c", "Thursday, February 30, 1970 00:00:00", { 0, 0, 0, 30, 1, 70, 4, 0, 0 }}, + {"%x", "01/01/70", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%x", "02/30/70", { 0, 0, 0, 30, 1, 70, 4, 0, 0 }}, + {"%#x", "Thursday, January 01, 1970", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%#x", "Thursday, February 30, 1970", { 0, 0, 0, 30, 1, 70, 4, 0, 0 }}, + {"%X", "00:00:00", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%X", "14:00:00", { 0, 0, 14, 1, 0, 70, 4, 0, 0 }}, + {"%a", "Thu", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%A", "Thursday", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%b", "Jan", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%B", "January", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%d", "01", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%#d", "1", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%H", "00", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%I", "12", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%j", "001", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%m", "01", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%#M", "0", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%p", "AM", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%U", "00", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%W", "00", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%U", "01", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + {"%W", "00", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + {"%U", "53", { 0, 0, 0, 1, 0, 70, 0, 365, 0 }}, + {"%W", "52", { 0, 0, 0, 1, 0, 70, 0, 365, 0 }}, + }; + + const struct { + const char *format; + const char *ret; + const char *short_date; + const char *date; + const char *time; + struct tm tm; + BOOL todo; + } tests_td[] = { + { "%c", "x z", "x", "y", "z", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%#c", "y z", "x", "y", "z", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%X", "m1", 0, 0, "MMM", { 0, 0, 1, 1, 0, 70, 0, 0, 0 }}, + { "%X", "1", 0, 0, "h", { 0, 0, 1, 1, 0, 70, 0, 0, 0 }}, + { "%X", "01", 0, 0, "hh", { 0, 0, 1, 1, 0, 70, 0, 0, 0 }}, + { "%X", "h01", 0, 0, "hhh", { 0, 0, 1, 1, 0, 70, 0, 0, 0 }}, + { "%X", "hh01", 0, 0, "hhhh", { 0, 0, 1, 1, 0, 70, 0, 0, 0 }}, + { "%X", "1", 0, 0, "H", { 0, 0, 1, 1, 0, 70, 0, 0, 0 }}, + { "%X", "01", 0, 0, "HH", { 0, 0, 1, 1, 0, 70, 0, 0, 0 }}, + { "%X", "H13", 0, 0, "HHH", { 0, 0, 13, 1, 0, 70, 0, 0, 0 }}, + { "%X", "0", 0, 0, "m", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%X", "00", 0, 0, "mm", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%X", "0", 0, 0, "s", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%X", "00", 0, 0, "ss", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%X", "s00", 0, 0, "sss", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%X", "t", 0, 0, "t", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%X", "tam", 0, 0, "tt", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%X", "tam", 0, 0, "ttttttttt", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%X", "tam", 0, 0, "a", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%X", "tam", 0, 0, "aaaaa", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%X", "tam", 0, 0, "A", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%X", "tam", 0, 0, "AAAAA", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%x", "1", "d", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%x", "01", "dd", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%x", "d1", "ddd", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%x", "day1", "dddd", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%x", "dday1", "ddddd", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%x", "1", "M", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%x", "01", "MM", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%x", "m1", "MMM", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%x", "mon1", "MMMM", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%x", "Mmon1", "MMMMM", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%x", "y", "y", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%x", "70", "yy", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%x", "y70", "yyy", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%x", "1970", "yyyy", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%x", "y1970", "yyyyy", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%x", "ggggggggggg", "ggggggggggg", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%#x", "1", 0, "d", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%#x", "01", 0, "dd", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%#x", "d1", 0, "ddd", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%#x", "day1", 0, "dddd", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%#x", "dday1", 0, "ddddd", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%#x", "1", 0, "M", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%#x", "01", 0, "MM", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%#x", "m1", 0, "MMM", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%#x", "mon1", 0, "MMMM", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%#x", "Mmon1", 0, "MMMMM", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%#x", "y", 0, "y", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%#x", "70", 0, "yy", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%#x", "y70", 0, "yyy", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%#x", "1970", 0, "yyyy", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%#x", "y1970", 0, "yyyyy", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + }; + + __lc_time_data time_data = { + { "d1", "d2", "d3", "d4", "d5", "d6", "d7" }, + { "day1", "day2", "day3", "day4", "day5", "day6", "day7" }, + { "m1", "m2", "m3", "m4", "m5", "m6", "m7", "m8", "m9", "m10", "m11", "m12" }, + { "mon1", "mon2", "mon3", "mon4", "mon5", "mon6", "mon7", "mon8", "mon9", "mon10", "mon11", "mon12" }, + "tam", "tpm" + }; time_t gmt; struct tm* gmt_tm; char buf[256], bufA[256]; WCHAR bufW[256]; long retA, retW; + int i; if (!p_strftime || !p_wcsftime || !p_gmtime) { @@ -608,55 +821,13 @@ static void test_strftime(void) gmt_tm = p_gmtime(&gmt); ok(gmt_tm != NULL, "gmtime failed\n"); - errno = 0xdeadbeef; - retA = p_strftime(bufA, 256, "%C", gmt_tm); - ok(retA == 0, "expected 0, got %ld\n", retA); - ok(errno==EINVAL || broken(errno==0xdeadbeef), "errno = %d\n", errno); - - errno = 0xdeadbeef; - retA = p_strftime(bufA, 256, "%D", gmt_tm); - ok(retA == 0, "expected 0, got %ld\n", retA); - ok(errno==EINVAL || broken(errno==0xdeadbeef), "errno = %d\n", errno); - - errno = 0xdeadbeef; - retA = p_strftime(bufA, 256, "%e", gmt_tm); - ok(retA == 0, "expected 0, got %ld\n", retA); - ok(errno==EINVAL || broken(errno==0xdeadbeef), "errno = %d\n", errno); - - errno = 0xdeadbeef; - retA = p_strftime(bufA, 256, "%F", gmt_tm); - ok(retA == 0, "expected 0, got %ld\n", retA); - ok(errno==EINVAL || broken(errno==0xdeadbeef), "errno = %d\n", errno); - - errno = 0xdeadbeef; - retA = p_strftime(bufA, 256, "%h", gmt_tm); - ok(retA == 0, "expected 0, got %ld\n", retA); - ok(errno==EINVAL || broken(errno==0xdeadbeef), "errno = %d\n", errno); - - errno = 0xdeadbeef; - retA = p_strftime(bufA, 256, "%n", gmt_tm); - ok(retA == 0, "expected 0, got %ld\n", retA); - ok(errno==EINVAL || broken(errno==0xdeadbeef), "errno = %d\n", errno); - - errno = 0xdeadbeef; - retA = p_strftime(bufA, 256, "%R", gmt_tm); - ok(retA == 0, "expected 0, got %ld\n", retA); - ok(errno==EINVAL || broken(errno==0xdeadbeef), "errno = %d\n", errno); - - errno = 0xdeadbeef; - retA = p_strftime(bufA, 256, "%t", gmt_tm); - ok(retA == 0, "expected 0, got %ld\n", retA); - ok(errno==EINVAL || broken(errno==0xdeadbeef), "errno = %d\n", errno); - - errno = 0xdeadbeef; - retA = p_strftime(bufA, 256, "%T", gmt_tm); - ok(retA == 0, "expected 0, got %ld\n", retA); - ok(errno==EINVAL || broken(errno==0xdeadbeef), "errno = %d\n", errno); - - errno = 0xdeadbeef; - retA = p_strftime(bufA, 256, "%u", gmt_tm); - ok(retA == 0, "expected 0, got %ld\n", retA); - ok(errno==EINVAL || broken(errno==0xdeadbeef), "errno = %d\n", errno); + for (i=0; itm_wday = 0; - retA = p_strftime(bufA, 256, "%U", gmt_tm); - ok(retA == 2, "expected 2, got %ld\n", retA); - ok(!strcmp(bufA, "01"), "got %s\n", bufA); - - retA = p_strftime(bufA, 256, "%W", gmt_tm); - ok(retA == 2, "expected 2, got %ld\n", retA); - ok(!strcmp(bufA, "00"), "got %s\n", bufA); - - gmt_tm->tm_yday = 365; - retA = p_strftime(bufA, 256, "%U", gmt_tm); - ok(retA == 2, "expected 2, got %ld\n", retA); - ok(!strcmp(bufA, "53"), "got %s\n", bufA); - - retA = p_strftime(bufA, 256, "%W", gmt_tm); - ok(retA == 2, "expected 2, got %ld\n", retA); - ok(!strcmp(bufA, "52"), "got %s\n", bufA); - - gmt_tm->tm_mon = 1; - gmt_tm->tm_mday = 30; - retA = p_strftime(bufA, 256, "%c", gmt_tm); - todo_wine { - ok(retA == 17, "expected 17, got %ld\n", retA); - ok(!strcmp(bufA, "02/30/70 00:00:00"), "got %s\n", bufA); - } - if(!setlocale(LC_ALL, "Japanese_Japan.932")) { win_skip("Japanese_Japan.932 locale not available\n"); return; @@ -806,6 +890,27 @@ static void test_strftime(void) retA = p_strftime(bufA, 256, "\x82%c", gmt_tm); ok(retA == 3, "expected 3, got %ld\n", retA); ok(!strcmp(bufA, "\x82%c"), "got %s\n", bufA); + + setlocale(LC_ALL, "C"); + if(!p__Strftime) { + win_skip("_Strftime is not available\n"); + return; + } + + /* TODO: find meaning of unk */ + time_data.unk = 1; + for (i=0; iuserdata); else @@ -169,7 +190,7 @@ static void CALLBACK rtl_wait_cb(void *userdata, BOOLEAN timeout) if (info->semaphore2) { result = WaitForSingleObject(info->semaphore2, 200); - ok(result == info->wait_result, "expected %u, got %u\n", info->wait_result, result); + ok(result == info->wait_result, "expected %lu, got %lu\n", info->wait_result, result); ReleaseSemaphore(info->semaphore1, 1, NULL); } } @@ -178,7 +199,6 @@ static HANDLE rtl_wait_apc_semaphore; static void CALLBACK rtl_wait_apc_cb(ULONG_PTR userdata) { - trace("Running rtl_wait_apc callback\n"); if (rtl_wait_apc_semaphore) ReleaseSemaphore(rtl_wait_apc_semaphore, 1, NULL); } @@ -189,7 +209,7 @@ static void test_RtlRegisterWait(void) struct rtl_wait_info info; HANDLE semaphores[2]; NTSTATUS status; - DWORD result; + DWORD result, threadid; semaphores[0] = CreateSemaphoreW(NULL, 0, 2, NULL); ok(semaphores[0] != NULL, "failed to create semaphore\n"); @@ -205,196 +225,257 @@ static void test_RtlRegisterWait(void) wait1 = NULL; info.userdata = 0; status = RtlRegisterWait(&wait1, semaphores[1], rtl_wait_cb, &info, INFINITE, WT_EXECUTEDEFAULT); - ok(!status, "RtlRegisterWait failed with status %x\n", status); + ok(!status, "RtlRegisterWait failed with status %lx\n", status); ok(wait1 != NULL, "expected wait1 != NULL\n"); status = RtlDeregisterWait(wait1); - ok(!status, "RtlDeregisterWait failed with status %x\n", status); - ok(info.userdata == 0, "expected info.userdata = 0, got %u\n", info.userdata); + ok(!status, "RtlDeregisterWait failed with status %lx\n", status); + ok(info.userdata == 0, "expected info.userdata = 0, got %lu\n", info.userdata); /* infinite timeout, signal the semaphore two times */ info.userdata = 0; status = RtlRegisterWait(&wait1, semaphores[1], rtl_wait_cb, &info, INFINITE, WT_EXECUTEDEFAULT); - ok(!status, "RtlRegisterWait failed with status %x\n", status); + ok(!status, "RtlRegisterWait failed with status %lx\n", status); ReleaseSemaphore(semaphores[1], 1, NULL); result = WaitForSingleObject(semaphores[0], 100); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); - ok(info.userdata == 1, "expected info.userdata = 1, got %u\n", info.userdata); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 1, "expected info.userdata = 1, got %lu\n", info.userdata); ReleaseSemaphore(semaphores[1], 1, NULL); result = WaitForSingleObject(semaphores[0], 100); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); - ok(info.userdata == 2, "expected info.userdata = 2, got %u\n", info.userdata); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 2, "expected info.userdata = 2, got %lu\n", info.userdata); result = WaitForSingleObject(semaphores[1], 0); - ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %lu\n", result); Sleep(50); status = RtlDeregisterWait(wait1); - ok(!status, "RtlDeregisterWait failed with status %x\n", status); + ok(!status, "RtlDeregisterWait failed with status %lx\n", status); /* repeat test with WT_EXECUTEONLYONCE */ info.userdata = 0; status = RtlRegisterWait(&wait1, semaphores[1], rtl_wait_cb, &info, INFINITE, WT_EXECUTEONLYONCE); - ok(!status, "RtlRegisterWait failed with status %x\n", status); + ok(!status, "RtlRegisterWait failed with status %lx\n", status); ReleaseSemaphore(semaphores[1], 1, NULL); result = WaitForSingleObject(semaphores[0], 100); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); - ok(info.userdata == 1, "expected info.userdata = 1, got %u\n", info.userdata); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 1, "expected info.userdata = 1, got %lu\n", info.userdata); ReleaseSemaphore(semaphores[1], 1, NULL); result = WaitForSingleObject(semaphores[0], 100); - ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); - ok(info.userdata == 1, "expected info.userdata = 1, got %u\n", info.userdata); + ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 1, "expected info.userdata = 1, got %lu\n", info.userdata); result = WaitForSingleObject(semaphores[1], 0); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); Sleep(50); status = RtlDeregisterWait(wait1); - ok(!status, "RtlDeregisterWait failed with status %x\n", status); + ok(!status, "RtlDeregisterWait failed with status %lx\n", status); /* finite timeout, no event */ info.userdata = 0; status = RtlRegisterWait(&wait1, semaphores[1], rtl_wait_cb, &info, 200, WT_EXECUTEDEFAULT); - ok(!status, "RtlRegisterWait failed with status %x\n", status); + ok(!status, "RtlRegisterWait failed with status %lx\n", status); result = WaitForSingleObject(semaphores[0], 100); - ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); - ok(info.userdata == 0, "expected info.userdata = 0, got %u\n", info.userdata); + ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 0, "expected info.userdata = 0, got %lu\n", info.userdata); result = WaitForSingleObject(semaphores[0], 200); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); - ok(info.userdata == 0x10000, "expected info.userdata = 0x10000, got %u\n", info.userdata); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 0x10000, "expected info.userdata = 0x10000, got %lu\n", info.userdata); result = WaitForSingleObject(semaphores[1], 0); - ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %lu\n", result); Sleep(50); status = RtlDeregisterWait(wait1); - ok(!status, "RtlDeregisterWait failed with status %x\n", status); + ok(!status, "RtlDeregisterWait failed with status %lx\n", status); /* finite timeout, with event */ info.userdata = 0; status = RtlRegisterWait(&wait1, semaphores[1], rtl_wait_cb, &info, 200, WT_EXECUTEDEFAULT); - ok(!status, "RtlRegisterWait failed with status %x\n", status); + ok(!status, "RtlRegisterWait failed with status %lx\n", status); + result = WaitForSingleObject(semaphores[0], 100); + ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 0, "expected info.userdata = 0, got %lu\n", info.userdata); + ReleaseSemaphore(semaphores[1], 1, NULL); result = WaitForSingleObject(semaphores[0], 100); - ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); - ok(info.userdata == 0, "expected info.userdata = 0, got %u\n", info.userdata); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 1, "expected info.userdata = 1, got %lu\n", info.userdata); + result = WaitForSingleObject(semaphores[1], 0); + ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %lu\n", result); + Sleep(50); + status = RtlDeregisterWait(wait1); + ok(!status, "RtlDeregisterWait failed with status %lx\n", status); + + /* test RtlRegisterWait WT_EXECUTEINWAITTHREAD flag */ + info.userdata = 0; + info.threadid = 0; + status = RtlRegisterWait(&wait1, semaphores[1], rtl_wait_cb, &info, 200, WT_EXECUTEINWAITTHREAD|WT_EXECUTEONLYONCE); + ok(!status, "RtlRegisterWait failed with status %lx\n", status); + ReleaseSemaphore(semaphores[1], 1, NULL); + result = WaitForSingleObject(semaphores[0], 200); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 1, "expected info.userdata = 1, got %lu\n", info.userdata); + ok(info.threadid && info.threadid != GetCurrentThreadId(), "unexpected wait thread id %lx\n", info.threadid); + threadid = info.threadid; + result = WaitForSingleObject(semaphores[1], 0); + ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %lu\n", result); + Sleep(50); + status = RtlDeregisterWait(wait1); + ok(!status, "RtlDeregisterWait failed with status %lx\n", status); + + info.userdata = 0; + info.threadid = 0; + status = RtlRegisterWait(&wait1, semaphores[1], rtl_wait_cb, &info, 200, WT_EXECUTEINWAITTHREAD|WT_EXECUTEONLYONCE); + ok(!status, "RtlRegisterWait failed with status %lx\n", status); ReleaseSemaphore(semaphores[1], 1, NULL); + result = WaitForSingleObject(semaphores[0], 200); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 1, "expected info.userdata = 1, got %lu\n", info.userdata); + ok(info.threadid == threadid, "unexpected different wait thread id %lx\n", info.threadid); + result = WaitForSingleObject(semaphores[1], 0); + ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %lu\n", result); + Sleep(50); + status = RtlDeregisterWait(wait1); + ok(!status, "RtlDeregisterWait failed with status %lx\n", status); + + /* test RtlRegisterWait WT_EXECUTEINWAITTHREAD flag with 0 timeout */ + info.userdata = 0; + info.threadid = 0; + status = RtlRegisterWait(&wait1, semaphores[1], rtl_wait_cb, &info, 0, WT_EXECUTEINWAITTHREAD|WT_EXECUTEONLYONCE); + ok(!status, "RtlRegisterWait failed with status %lx\n", status); result = WaitForSingleObject(semaphores[0], 100); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); - ok(info.userdata == 1, "expected info.userdata = 1, got %u\n", info.userdata); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 0x10000, "expected info.userdata = 0x10000, got %lu\n", info.userdata); + ok(info.threadid == threadid, "unexpected different wait thread id %lx\n", info.threadid); + result = WaitForSingleObject(semaphores[1], 0); + ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %lu\n", result); + Sleep(50); + status = RtlDeregisterWait(wait1); + ok(!status, "RtlDeregisterWait failed with status %lx\n", status); + + /* test RtlRegisterWait WT_EXECUTEINWAITTHREAD flag with already signaled event */ + info.userdata = 0; + info.threadid = 0; + ReleaseSemaphore(semaphores[1], 1, NULL); + status = RtlRegisterWait(&wait1, semaphores[1], rtl_wait_cb, &info, 200, WT_EXECUTEINWAITTHREAD|WT_EXECUTEONLYONCE); + ok(!status, "RtlRegisterWait failed with status %lx\n", status); + result = WaitForSingleObject(semaphores[0], 200); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 1, "expected info.userdata = 1, got %lu\n", info.userdata); + ok(info.threadid == threadid, "unexpected different wait thread id %lx\n", info.threadid); result = WaitForSingleObject(semaphores[1], 0); - ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %lu\n", result); Sleep(50); status = RtlDeregisterWait(wait1); - ok(!status, "RtlDeregisterWait failed with status %x\n", status); + ok(!status, "RtlDeregisterWait failed with status %lx\n", status); /* test for IO threads */ info.userdata = 0; info.threadid = 0; status = RtlRegisterWait(&wait1, semaphores[1], rtl_wait_cb, &info, INFINITE, WT_EXECUTEINIOTHREAD); - ok(!status, "RtlRegisterWait failed with status %x\n", status); + ok(!status, "RtlRegisterWait failed with status %lx\n", status); ReleaseSemaphore(semaphores[1], 1, NULL); result = WaitForSingleObject(semaphores[0], 100); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); - ok(info.userdata == 1, "expected info.userdata = 1, got %u\n", info.userdata); - ok(info.threadid != 0, "expected info.threadid != 0, got %u\n", info.threadid); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 1, "expected info.userdata = 1, got %lu\n", info.userdata); + ok(info.threadid != 0, "expected info.threadid != 0, got %lu\n", info.threadid); thread = OpenThread(THREAD_SET_CONTEXT, FALSE, info.threadid); - ok(thread != NULL, "OpenThread failed with %u\n", GetLastError()); + ok(thread != NULL, "OpenThread failed with %lu\n", GetLastError()); rtl_wait_apc_semaphore = semaphores[0]; result = QueueUserAPC(rtl_wait_apc_cb, thread, 0); - ok(result != 0, "QueueUserAPC failed with %u\n", GetLastError()); + ok(result != 0, "QueueUserAPC failed with %lu\n", GetLastError()); result = WaitForSingleObject(semaphores[0], 200); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); rtl_wait_apc_semaphore = 0; CloseHandle(thread); ReleaseSemaphore(semaphores[1], 1, NULL); result = WaitForSingleObject(semaphores[0], 100); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); - ok(info.userdata == 2, "expected info.userdata = 2, got %u\n", info.userdata); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 2, "expected info.userdata = 2, got %lu\n", info.userdata); Sleep(50); status = RtlDeregisterWait(wait1); - ok(!status, "RtlDeregisterWait failed with status %x\n", status); + ok(!status, "RtlDeregisterWait failed with status %lx\n", status); info.userdata = 0; info.threadid = 0; status = RtlRegisterWait(&wait1, semaphores[1], rtl_wait_cb, &info, INFINITE, WT_EXECUTEDEFAULT); - ok(!status, "RtlRegisterWait failed with status %x\n", status); + ok(!status, "RtlRegisterWait failed with status %lx\n", status); ReleaseSemaphore(semaphores[1], 1, NULL); result = WaitForSingleObject(semaphores[0], 100); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); - ok(info.userdata == 1, "expected info.userdata = 1, got %u\n", info.userdata); - ok(info.threadid != 0, "expected info.threadid != 0, got %u\n", info.threadid); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 1, "expected info.userdata = 1, got %lu\n", info.userdata); + ok(info.threadid != 0, "expected info.threadid != 0, got %lu\n", info.threadid); thread = OpenThread(THREAD_SET_CONTEXT, FALSE, info.threadid); - ok(thread != NULL, "OpenThread failed with %u\n", GetLastError()); + ok(thread != NULL, "OpenThread failed with %lu\n", GetLastError()); rtl_wait_apc_semaphore = semaphores[0]; result = QueueUserAPC(rtl_wait_apc_cb, thread, 0); - ok(result != 0, "QueueUserAPC failed with %u\n", GetLastError()); + ok(result != 0, "QueueUserAPC failed with %lu\n", GetLastError()); result = WaitForSingleObject(semaphores[0], 200); ok(result == WAIT_TIMEOUT || broken(result == WAIT_OBJECT_0) /* >= Win Vista */, - "WaitForSingleObject returned %u\n", result); + "WaitForSingleObject returned %lu\n", result); rtl_wait_apc_semaphore = 0; CloseHandle(thread); ReleaseSemaphore(semaphores[1], 1, NULL); result = WaitForSingleObject(semaphores[0], 100); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); - ok(info.userdata == 2, "expected info.userdata = 2, got %u\n", info.userdata); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 2, "expected info.userdata = 2, got %lu\n", info.userdata); Sleep(50); status = RtlDeregisterWait(wait1); - ok(!status, "RtlDeregisterWait failed with status %x\n", status); + ok(!status, "RtlDeregisterWait failed with status %lx\n", status); /* test RtlDeregisterWaitEx before wait expired */ info.userdata = 0; status = RtlRegisterWait(&wait1, semaphores[1], rtl_wait_cb, &info, INFINITE, WT_EXECUTEDEFAULT); - ok(!status, "RtlRegisterWait failed with status %x\n", status); + ok(!status, "RtlRegisterWait failed with status %lx\n", status); status = RtlDeregisterWaitEx(wait1, NULL); - ok(!status, "RtlDeregisterWaitEx failed with status %x\n", status); - ok(info.userdata == 0, "expected info.userdata = 0, got %u\n", info.userdata); + ok(!status, "RtlDeregisterWaitEx failed with status %lx\n", status); + ok(info.userdata == 0, "expected info.userdata = 0, got %lu\n", info.userdata); info.userdata = 0; status = RtlRegisterWait(&wait1, semaphores[1], rtl_wait_cb, &info, INFINITE, WT_EXECUTEDEFAULT); - ok(!status, "RtlRegisterWait failed with status %x\n", status); + ok(!status, "RtlRegisterWait failed with status %lx\n", status); status = RtlDeregisterWaitEx(wait1, INVALID_HANDLE_VALUE); - ok(!status, "RtlDeregisterWaitEx failed with status %x\n", status); - ok(info.userdata == 0, "expected info.userdata = 0, got %u\n", info.userdata); + ok(!status, "RtlDeregisterWaitEx failed with status %lx\n", status); + ok(info.userdata == 0, "expected info.userdata = 0, got %lu\n", info.userdata); info.userdata = 0; status = RtlRegisterWait(&wait1, semaphores[1], rtl_wait_cb, &info, INFINITE, WT_EXECUTEDEFAULT); - ok(!status, "RtlRegisterWait failed with status %x\n", status); + ok(!status, "RtlRegisterWait failed with status %lx\n", status); status = RtlDeregisterWaitEx(wait1, event); - ok(!status, "RtlDeregisterWaitEx failed with status %x\n", status); - ok(info.userdata == 0, "expected info.userdata = 0, got %u\n", info.userdata); + ok(!status, "RtlDeregisterWaitEx failed with status %lx\n", status); + ok(info.userdata == 0, "expected info.userdata = 0, got %lu\n", info.userdata); result = WaitForSingleObject(event, 200); - todo_wine - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); /* test RtlDeregisterWaitEx after wait expired */ info.userdata = 0; status = RtlRegisterWait(&wait1, semaphores[1], rtl_wait_cb, &info, 0, WT_EXECUTEONLYONCE); - ok(!status, "RtlRegisterWait failed with status %x\n", status); + ok(!status, "RtlRegisterWait failed with status %lx\n", status); result = WaitForSingleObject(semaphores[0], 100); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); - ok(info.userdata == 0x10000, "expected info.userdata = 0x10000, got %u\n", info.userdata); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 0x10000, "expected info.userdata = 0x10000, got %lu\n", info.userdata); Sleep(50); status = RtlDeregisterWaitEx(wait1, NULL); - ok(!status, "RtlDeregisterWaitEx failed with status %x\n", status); - ok(info.userdata == 0x10000, "expected info.userdata = 0x10000, got %u\n", info.userdata); + ok(!status, "RtlDeregisterWaitEx failed with status %lx\n", status); + ok(info.userdata == 0x10000, "expected info.userdata = 0x10000, got %lu\n", info.userdata); info.userdata = 0; status = RtlRegisterWait(&wait1, semaphores[1], rtl_wait_cb, &info, 0, WT_EXECUTEONLYONCE); - ok(!status, "RtlRegisterWait failed with status %x\n", status); + ok(!status, "RtlRegisterWait failed with status %lx\n", status); result = WaitForSingleObject(semaphores[0], 100); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); - ok(info.userdata == 0x10000, "expected info.userdata = 0x10000, got %u\n", info.userdata); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 0x10000, "expected info.userdata = 0x10000, got %lu\n", info.userdata); Sleep(50); status = RtlDeregisterWaitEx(wait1, INVALID_HANDLE_VALUE); - ok(!status, "RtlDeregisterWaitEx failed with status %x\n", status); - ok(info.userdata == 0x10000, "expected info.userdata = 0x10000, got %u\n", info.userdata); + ok(!status, "RtlDeregisterWaitEx failed with status %lx\n", status); + ok(info.userdata == 0x10000, "expected info.userdata = 0x10000, got %lu\n", info.userdata); info.userdata = 0; status = RtlRegisterWait(&wait1, semaphores[1], rtl_wait_cb, &info, 0, WT_EXECUTEONLYONCE); - ok(!status, "RtlRegisterWait failed with status %x\n", status); + ok(!status, "RtlRegisterWait failed with status %lx\n", status); result = WaitForSingleObject(semaphores[0], 100); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); - ok(info.userdata == 0x10000, "expected info.userdata = 0x10000, got %u\n", info.userdata); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 0x10000, "expected info.userdata = 0x10000, got %lu\n", info.userdata); Sleep(50); status = RtlDeregisterWaitEx(wait1, event); - ok(!status, "RtlDeregisterWaitEx failed with status %x\n", status); - ok(info.userdata == 0x10000, "expected info.userdata = 0x10000, got %u\n", info.userdata); + ok(!status, "RtlDeregisterWaitEx failed with status %lx\n", status); + ok(info.userdata == 0x10000, "expected info.userdata = 0x10000, got %lu\n", info.userdata); result = WaitForSingleObject(event, 200); - todo_wine - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); /* test RtlDeregisterWaitEx while callback is running */ info.semaphore2 = semaphores[1]; @@ -402,58 +483,84 @@ static void test_RtlRegisterWait(void) info.userdata = 0; status = RtlRegisterWait(&wait1, semaphores[1], rtl_wait_cb, &info, INFINITE, WT_EXECUTEONLYONCE); - ok(!status, "RtlRegisterWait failed with status %x\n", status); + ok(!status, "RtlRegisterWait failed with status %lx\n", status); ReleaseSemaphore(semaphores[1], 1, NULL); result = WaitForSingleObject(semaphores[0], 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); - ok(info.userdata == 1, "expected info.userdata = 1, got %u\n", info.userdata); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 1, "expected info.userdata = 1, got %lu\n", info.userdata); status = RtlDeregisterWait(wait1); - ok(status == STATUS_PENDING, "expected STATUS_PENDING, got %x\n", status); + ok(status == STATUS_PENDING, "expected STATUS_PENDING, got %lx\n", status); ReleaseSemaphore(semaphores[1], 1, NULL); result = WaitForSingleObject(semaphores[0], 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + + info.userdata = 0; + status = RtlRegisterWait(&wait1, semaphores[1], rtl_wait_cb, &info, INFINITE, WT_EXECUTEINWAITTHREAD|WT_EXECUTEONLYONCE); + ok(!status, "RtlRegisterWait failed with status %lx\n", status); + ReleaseSemaphore(semaphores[1], 1, NULL); + result = WaitForSingleObject(semaphores[0], 1000); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 1, "expected info.userdata = 1, got %lu\n", info.userdata); + status = RtlDeregisterWait(wait1); + ok(status == STATUS_PENDING, "expected STATUS_PENDING, got %lx\n", status); + ReleaseSemaphore(semaphores[1], 1, NULL); + result = WaitForSingleObject(semaphores[0], 1000); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); info.userdata = 0; status = RtlRegisterWait(&wait1, semaphores[1], rtl_wait_cb, &info, INFINITE, WT_EXECUTEONLYONCE); - ok(!status, "RtlRegisterWait failed with status %x\n", status); + ok(!status, "RtlRegisterWait failed with status %lx\n", status); ReleaseSemaphore(semaphores[1], 1, NULL); result = WaitForSingleObject(semaphores[0], 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); - ok(info.userdata == 1, "expected info.userdata = 1, got %u\n", info.userdata); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 1, "expected info.userdata = 1, got %lu\n", info.userdata); status = RtlDeregisterWaitEx(wait1, NULL); - ok(status == STATUS_PENDING, "expected STATUS_PENDING, got %x\n", status); + ok(status == STATUS_PENDING, "expected STATUS_PENDING, got %lx\n", status); ReleaseSemaphore(semaphores[1], 1, NULL); result = WaitForSingleObject(semaphores[0], 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); info.wait_result = WAIT_TIMEOUT; info.userdata = 0; status = RtlRegisterWait(&wait1, semaphores[1], rtl_wait_cb, &info, INFINITE, WT_EXECUTEONLYONCE); - ok(!status, "RtlRegisterWait failed with status %x\n", status); + ok(!status, "RtlRegisterWait failed with status %lx\n", status); + ReleaseSemaphore(semaphores[1], 1, NULL); + result = WaitForSingleObject(semaphores[0], 1000); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 1, "expected info.userdata = 1, got %lu\n", info.userdata); + status = RtlDeregisterWaitEx(wait1, INVALID_HANDLE_VALUE); + ok(!status, "RtlDeregisterWaitEx failed with status %lx\n", status); + result = WaitForSingleObject(semaphores[0], 0); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + + info.wait_result = WAIT_TIMEOUT; + info.userdata = 0; + status = RtlRegisterWait(&wait1, semaphores[1], rtl_wait_cb, &info, INFINITE, WT_EXECUTEINWAITTHREAD|WT_EXECUTEONLYONCE); + ok(!status, "RtlRegisterWait failed with status %lx\n", status); ReleaseSemaphore(semaphores[1], 1, NULL); result = WaitForSingleObject(semaphores[0], 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); - ok(info.userdata == 1, "expected info.userdata = 1, got %u\n", info.userdata); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 1, "expected info.userdata = 1, got %lu\n", info.userdata); status = RtlDeregisterWaitEx(wait1, INVALID_HANDLE_VALUE); - ok(!status, "RtlDeregisterWaitEx failed with status %x\n", status); + ok(!status, "RtlDeregisterWaitEx failed with status %lx\n", status); result = WaitForSingleObject(semaphores[0], 0); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); info.wait_result = WAIT_OBJECT_0; info.userdata = 0; status = RtlRegisterWait(&wait1, semaphores[1], rtl_wait_cb, &info, INFINITE, WT_EXECUTEONLYONCE); - ok(!status, "RtlRegisterWait failed with status %x\n", status); + ok(!status, "RtlRegisterWait failed with status %lx\n", status); ReleaseSemaphore(semaphores[1], 1, NULL); result = WaitForSingleObject(semaphores[0], 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); - ok(info.userdata == 1, "expected info.userdata = 1, got %u\n", info.userdata); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 1, "expected info.userdata = 1, got %lu\n", info.userdata); status = RtlDeregisterWaitEx(wait1, event); - ok(status == STATUS_PENDING, "expected STATUS_PENDING, got %x\n", status); + ok(status == STATUS_PENDING, "expected STATUS_PENDING, got %lx\n", status); ReleaseSemaphore(semaphores[1], 1, NULL); result = WaitForSingleObject(event, 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); result = WaitForSingleObject(semaphores[0], 0); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); CloseHandle(semaphores[0]); CloseHandle(semaphores[1]); @@ -463,21 +570,23 @@ static void test_RtlRegisterWait(void) static void CALLBACK simple_cb(TP_CALLBACK_INSTANCE *instance, void *userdata) { HANDLE semaphore = userdata; - trace("Running simple callback\n"); ReleaseSemaphore(semaphore, 1, NULL); } static void CALLBACK simple2_cb(TP_CALLBACK_INSTANCE *instance, void *userdata) { - trace("Running simple2 callback\n"); Sleep(50); InterlockedIncrement((LONG *)userdata); } static void test_tp_simple(void) { + IMAGE_NT_HEADERS *nt = RtlImageNtHeader( NtCurrentTeb()->Peb->ImageBaseAddress ); + TP_POOL_STACK_INFORMATION stack_info; TP_CALLBACK_ENVIRON environment; +#ifndef __REACTOS__ TP_CALLBACK_ENVIRON_V3 environment3; +#endif TP_CLEANUP_GROUP *group; HANDLE semaphore; NTSTATUS status; @@ -487,21 +596,21 @@ static void test_tp_simple(void) int i; semaphore = CreateSemaphoreA(NULL, 0, 1, NULL); - ok(semaphore != NULL, "CreateSemaphoreA failed %u\n", GetLastError()); + ok(semaphore != NULL, "CreateSemaphoreA failed %lu\n", GetLastError()); /* post the callback using the default threadpool */ memset(&environment, 0, sizeof(environment)); environment.Version = 1; environment.Pool = NULL; status = pTpSimpleTryPost(simple_cb, semaphore, &environment); - ok(!status, "TpSimpleTryPost failed with status %x\n", status); + ok(!status, "TpSimpleTryPost failed with status %lx\n", status); result = WaitForSingleObject(semaphore, 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); /* allocate new threadpool */ pool = NULL; status = pTpAllocPool(&pool, NULL); - ok(!status, "TpAllocPool failed with status %x\n", status); + ok(!status, "TpAllocPool failed with status %lx\n", status); ok(pool != NULL, "expected pool != NULL\n"); /* post the callback using the new threadpool */ @@ -509,20 +618,31 @@ static void test_tp_simple(void) environment.Version = 1; environment.Pool = pool; status = pTpSimpleTryPost(simple_cb, semaphore, &environment); - ok(!status, "TpSimpleTryPost failed with status %x\n", status); + ok(!status, "TpSimpleTryPost failed with status %lx\n", status); result = WaitForSingleObject(semaphore, 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); +#ifndef __REACTOS__ // Windows 7 /* test with environment version 3 */ memset(&environment3, 0, sizeof(environment3)); environment3.Version = 3; environment3.Pool = pool; - environment3.CallbackPriority = TP_CALLBACK_PRIORITY_NORMAL; environment3.Size = sizeof(environment3); + + for (i = 0; i < 3; ++i) + { + environment3.CallbackPriority = TP_CALLBACK_PRIORITY_HIGH + i; + status = pTpSimpleTryPost(simple_cb, semaphore, (TP_CALLBACK_ENVIRON *)&environment3); + ok(!status, "TpSimpleTryPost failed with status %lx\n", status); + result = WaitForSingleObject(semaphore, 1000); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + } + + environment3.CallbackPriority = 10; status = pTpSimpleTryPost(simple_cb, semaphore, (TP_CALLBACK_ENVIRON *)&environment3); - ok(!status, "TpSimpleTryPost failed with status %x\n", status); - result = WaitForSingleObject(semaphore, 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(status == STATUS_INVALID_PARAMETER || broken(!status) /* Vista does not support priorities */, + "TpSimpleTryPost failed with status %lx\n", status); +#endif /* test with invalid version number */ memset(&environment, 0, sizeof(environment)); @@ -531,17 +651,17 @@ static void test_tp_simple(void) status = pTpSimpleTryPost(simple_cb, semaphore, &environment); todo_wine ok(status == STATUS_INVALID_PARAMETER || broken(!status) /* Vista/2008 */, - "TpSimpleTryPost unexpectedly returned status %x\n", status); + "TpSimpleTryPost unexpectedly returned status %lx\n", status); if (!status) { result = WaitForSingleObject(semaphore, 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); } /* allocate a cleanup group for synchronization */ group = NULL; status = pTpAllocCleanupGroup(&group); - ok(!status, "TpAllocCleanupGroup failed with status %x\n", status); + ok(!status, "TpAllocCleanupGroup failed with status %lx\n", status); ok(group != NULL, "expected pool != NULL\n"); /* use cleanup group to wait for a simple callback */ @@ -551,9 +671,9 @@ static void test_tp_simple(void) environment.Pool = pool; environment.CleanupGroup = group; status = pTpSimpleTryPost(simple2_cb, &userdata, &environment); - ok(!status, "TpSimpleTryPost failed with status %x\n", status); + ok(!status, "TpSimpleTryPost failed with status %lx\n", status); pTpReleaseCleanupGroupMembers(group, FALSE, NULL); - ok(userdata == 1, "expected userdata = 1, got %u\n", userdata); + ok(userdata == 1, "expected userdata = 1, got %lu\n", userdata); /* test cancellation of pending simple callbacks */ userdata = 0; @@ -565,10 +685,26 @@ static void test_tp_simple(void) for (i = 0; i < 100; i++) { status = pTpSimpleTryPost(simple2_cb, &userdata, &environment); - ok(!status, "TpSimpleTryPost failed with status %x\n", status); + ok(!status, "TpSimpleTryPost failed with status %lx\n", status); } pTpReleaseCleanupGroupMembers(group, TRUE, NULL); - ok(userdata < 100, "expected userdata < 100, got %u\n", userdata); + ok(userdata < 100, "expected userdata < 100, got %lu\n", userdata); + + /* test querying and setting the stack size */ + status = pTpQueryPoolStackInformation(pool, &stack_info); + ok(!status, "TpQueryPoolStackInformation failed: %lx\n", status); + ok(stack_info.StackReserve == nt->OptionalHeader.SizeOfStackReserve, "expected default StackReserve, got %Ix\n", stack_info.StackReserve); + ok(stack_info.StackCommit == nt->OptionalHeader.SizeOfStackCommit, "expected default StackCommit, got %Ix\n", stack_info.StackCommit); + + /* threadpool does not validate the stack size values */ + stack_info.StackReserve = stack_info.StackCommit = 1; + status = pTpSetPoolStackInformation(pool, &stack_info); + ok(!status, "TpSetPoolStackInformation failed: %lx\n", status); + + status = pTpQueryPoolStackInformation(pool, &stack_info); + ok(!status, "TpQueryPoolStackInformation failed: %lx\n", status); + ok(stack_info.StackReserve == 1, "expected 1 byte StackReserve, got %ld\n", (ULONG)stack_info.StackReserve); + ok(stack_info.StackCommit == 1, "expected 1 byte StackCommit, got %ld\n", (ULONG)stack_info.StackCommit); /* cleanup */ pTpReleaseCleanupGroup(group); @@ -578,14 +714,12 @@ static void test_tp_simple(void) static void CALLBACK work_cb(TP_CALLBACK_INSTANCE *instance, void *userdata, TP_WORK *work) { - trace("Running work callback\n"); Sleep(100); InterlockedIncrement((LONG *)userdata); } static void CALLBACK work2_cb(TP_CALLBACK_INSTANCE *instance, void *userdata, TP_WORK *work) { - trace("Running work2 callback\n"); Sleep(100); InterlockedExchangeAdd((LONG *)userdata, 0x10000); } @@ -602,7 +736,7 @@ static void test_tp_work(void) /* allocate new threadpool with only one thread */ pool = NULL; status = pTpAllocPool(&pool, NULL); - ok(!status, "TpAllocPool failed with status %x\n", status); + ok(!status, "TpAllocPool failed with status %lx\n", status); ok(pool != NULL, "expected pool != NULL\n"); pTpSetPoolMaxThreads(pool, 1); @@ -612,7 +746,7 @@ static void test_tp_work(void) environment.Version = 1; environment.Pool = pool; status = pTpAllocWork(&work, work_cb, &userdata, &environment); - ok(!status, "TpAllocWork failed with status %x\n", status); + ok(!status, "TpAllocWork failed with status %lx\n", status); ok(work != NULL, "expected work != NULL\n"); /* post 5 identical work items at once */ @@ -620,14 +754,14 @@ static void test_tp_work(void) for (i = 0; i < 5; i++) pTpPostWork(work); pTpWaitForWork(work, FALSE); - ok(userdata == 5, "expected userdata = 5, got %u\n", userdata); + ok(userdata == 5, "expected userdata = 5, got %lu\n", userdata); /* add more tasks and cancel them immediately */ userdata = 0; for (i = 0; i < 10; i++) pTpPostWork(work); pTpWaitForWork(work, TRUE); - ok(userdata < 10, "expected userdata < 10, got %u\n", userdata); + ok(userdata < 10, "expected userdata < 10, got %lu\n", userdata); /* cleanup */ pTpReleaseWork(work); @@ -647,14 +781,14 @@ static void test_tp_work_scheduler(void) /* allocate new threadpool with only one thread */ pool = NULL; status = pTpAllocPool(&pool, NULL); - ok(!status, "TpAllocPool failed with status %x\n", status); + ok(!status, "TpAllocPool failed with status %lx\n", status); ok(pool != NULL, "expected pool != NULL\n"); pTpSetPoolMaxThreads(pool, 1); /* create a cleanup group */ group = NULL; status = pTpAllocCleanupGroup(&group); - ok(!status, "TpAllocCleanupGroup failed with status %x\n", status); + ok(!status, "TpAllocCleanupGroup failed with status %lx\n", status); ok(group != NULL, "expected pool != NULL\n"); /* the first work item has no cleanup group associated */ @@ -663,7 +797,7 @@ static void test_tp_work_scheduler(void) environment.Version = 1; environment.Pool = pool; status = pTpAllocWork(&work, work_cb, &userdata, &environment); - ok(!status, "TpAllocWork failed with status %x\n", status); + ok(!status, "TpAllocWork failed with status %lx\n", status); ok(work != NULL, "expected work != NULL\n"); /* allocate a second work item with a cleanup group */ @@ -673,7 +807,7 @@ static void test_tp_work_scheduler(void) environment.Pool = pool; environment.CleanupGroup = group; status = pTpAllocWork(&work2, work2_cb, &userdata, &environment); - ok(!status, "TpAllocWork failed with status %x\n", status); + ok(!status, "TpAllocWork failed with status %lx\n", status); ok(work2 != NULL, "expected work2 != NULL\n"); /* the 'work' callbacks are not blocking execution of 'work2' callbacks */ @@ -685,8 +819,8 @@ static void test_tp_work_scheduler(void) Sleep(500); pTpWaitForWork(work, TRUE); pTpWaitForWork(work2, TRUE); - ok(userdata & 0xffff, "expected userdata & 0xffff != 0, got %u\n", userdata & 0xffff); - ok(userdata >> 16, "expected userdata >> 16 != 0, got %u\n", userdata >> 16); + ok(userdata & 0xffff, "expected userdata & 0xffff != 0, got %lu\n", userdata & 0xffff); + ok(userdata >> 16, "expected userdata >> 16 != 0, got %lu\n", userdata >> 16); /* test TpReleaseCleanupGroupMembers on a work item */ userdata = 0; @@ -696,8 +830,8 @@ static void test_tp_work_scheduler(void) pTpPostWork(work2); pTpReleaseCleanupGroupMembers(group, FALSE, NULL); pTpWaitForWork(work, TRUE); - ok((userdata & 0xffff) < 10, "expected userdata & 0xffff < 10, got %u\n", userdata & 0xffff); - ok((userdata >> 16) == 3, "expected userdata >> 16 == 3, got %u\n", userdata >> 16); + ok((userdata & 0xffff) < 10, "expected userdata & 0xffff < 10, got %lu\n", userdata & 0xffff); + ok((userdata >> 16) == 3, "expected userdata >> 16 == 3, got %lu\n", userdata >> 16); /* cleanup */ pTpReleaseWork(work); @@ -708,7 +842,6 @@ static void test_tp_work_scheduler(void) static void CALLBACK simple_release_cb(TP_CALLBACK_INSTANCE *instance, void *userdata) { HANDLE *semaphores = userdata; - trace("Running simple release callback\n"); ReleaseSemaphore(semaphores, 1, NULL); Sleep(200); /* wait until main thread is in TpReleaseCleanupGroupMembers */ } @@ -716,7 +849,6 @@ static void CALLBACK simple_release_cb(TP_CALLBACK_INSTANCE *instance, void *use static void CALLBACK work_release_cb(TP_CALLBACK_INSTANCE *instance, void *userdata, TP_WORK *work) { HANDLE semaphore = userdata; - trace("Running work release callback\n"); ReleaseSemaphore(semaphore, 1, NULL); Sleep(200); /* wait until main thread is in TpReleaseCleanupGroupMembers */ pTpReleaseWork(work); @@ -725,7 +857,6 @@ static void CALLBACK work_release_cb(TP_CALLBACK_INSTANCE *instance, void *userd static void CALLBACK timer_release_cb(TP_CALLBACK_INSTANCE *instance, void *userdata, TP_TIMER *timer) { HANDLE semaphore = userdata; - trace("Running timer release callback\n"); ReleaseSemaphore(semaphore, 1, NULL); Sleep(200); /* wait until main thread is in TpReleaseCleanupGroupMembers */ pTpReleaseTimer(timer); @@ -735,7 +866,6 @@ static void CALLBACK wait_release_cb(TP_CALLBACK_INSTANCE *instance, void *userd TP_WAIT *wait, TP_WAIT_RESULT result) { HANDLE semaphore = userdata; - trace("Running wait release callback\n"); ReleaseSemaphore(semaphore, 1, NULL); Sleep(200); /* wait until main thread is in TpReleaseCleanupGroupMembers */ pTpReleaseWait(wait); @@ -755,18 +885,18 @@ static void test_tp_group_wait(void) DWORD result; semaphore = CreateSemaphoreA(NULL, 0, 1, NULL); - ok(semaphore != NULL, "CreateSemaphoreA failed %u\n", GetLastError()); + ok(semaphore != NULL, "CreateSemaphoreA failed %lu\n", GetLastError()); /* allocate new threadpool */ pool = NULL; status = pTpAllocPool(&pool, NULL); - ok(!status, "TpAllocPool failed with status %x\n", status); + ok(!status, "TpAllocPool failed with status %lx\n", status); ok(pool != NULL, "expected pool != NULL\n"); /* allocate a cleanup group */ group = NULL; status = pTpAllocCleanupGroup(&group); - ok(!status, "TpAllocCleanupGroup failed with status %x\n", status); + ok(!status, "TpAllocCleanupGroup failed with status %lx\n", status); ok(group != NULL, "expected pool != NULL\n"); /* release work object during TpReleaseCleanupGroupMembers */ @@ -776,11 +906,11 @@ static void test_tp_group_wait(void) environment.Pool = pool; environment.CleanupGroup = group; status = pTpAllocWork(&work, work_release_cb, semaphore, &environment); - ok(!status, "TpAllocWork failed with status %x\n", status); + ok(!status, "TpAllocWork failed with status %lx\n", status); ok(work != NULL, "expected work != NULL\n"); pTpPostWork(work); result = WaitForSingleObject(semaphore, 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); pTpReleaseCleanupGroupMembers(group, FALSE, NULL); /* release timer object during TpReleaseCleanupGroupMembers */ @@ -790,12 +920,12 @@ static void test_tp_group_wait(void) environment.Pool = pool; environment.CleanupGroup = group; status = pTpAllocTimer(&timer, timer_release_cb, semaphore, &environment); - ok(!status, "TpAllocTimer failed with status %x\n", status); + ok(!status, "TpAllocTimer failed with status %lx\n", status); ok(timer != NULL, "expected timer != NULL\n"); when.QuadPart = 0; pTpSetTimer(timer, &when, 0, 0); result = WaitForSingleObject(semaphore, 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); pTpReleaseCleanupGroupMembers(group, FALSE, NULL); /* release wait object during TpReleaseCleanupGroupMembers */ @@ -805,12 +935,12 @@ static void test_tp_group_wait(void) environment.Pool = pool; environment.CleanupGroup = group; status = pTpAllocWait(&wait, wait_release_cb, semaphore, &environment); - ok(!status, "TpAllocWait failed with status %x\n", status); + ok(!status, "TpAllocWait failed with status %lx\n", status); ok(wait != NULL, "expected wait != NULL\n"); when.QuadPart = 0; pTpSetWait(wait, INVALID_HANDLE_VALUE, &when); result = WaitForSingleObject(semaphore, 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); pTpReleaseCleanupGroupMembers(group, FALSE, NULL); /* cleanup */ @@ -828,17 +958,15 @@ static void CALLBACK simple_group_cancel_cb(TP_CALLBACK_INSTANCE *instance, void DWORD result; int i; - trace("Running simple group cancel callback\n"); - status = pTpCallbackMayRunLong(instance); ok(status == STATUS_TOO_MANY_THREADS || broken(status == 1) /* Win Vista / 2008 */, - "expected STATUS_TOO_MANY_THREADS, got %08x\n", status); + "expected STATUS_TOO_MANY_THREADS, got %08lx\n", status); ReleaseSemaphore(semaphores[1], 1, NULL); for (i = 0; i < 4; i++) { result = WaitForSingleObject(semaphores[0], 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); } ReleaseSemaphore(semaphores[1], 1, NULL); } @@ -848,17 +976,14 @@ static void CALLBACK work_group_cancel_cb(TP_CALLBACK_INSTANCE *instance, void * HANDLE *semaphores = userdata; DWORD result; - trace("Running work group cancel callback\n"); - ReleaseSemaphore(semaphores[1], 1, NULL); result = WaitForSingleObject(semaphores[0], 200); - ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %lu\n", result); } static void CALLBACK group_cancel_cleanup_release_cb(void *object, void *userdata) { HANDLE *semaphores = userdata; - trace("Running group cancel cleanup release callback\n"); group_cancel_tid = GetCurrentThreadId(); ok(object == (void *)0xdeadbeef, "expected 0xdeadbeef, got %p\n", object); ReleaseSemaphore(semaphores[0], 1, NULL); @@ -867,7 +992,6 @@ static void CALLBACK group_cancel_cleanup_release_cb(void *object, void *userdat static void CALLBACK group_cancel_cleanup_release2_cb(void *object, void *userdata) { HANDLE *semaphores = userdata; - trace("Running group cancel cleanup release2 callback\n"); group_cancel_tid = GetCurrentThreadId(); ok(object == userdata, "expected %p, got %p\n", userdata, object); ReleaseSemaphore(semaphores[0], 1, NULL); @@ -875,7 +999,6 @@ static void CALLBACK group_cancel_cleanup_release2_cb(void *object, void *userda static void CALLBACK group_cancel_cleanup_increment_cb(void *object, void *userdata) { - trace("Running group cancel cleanup increment callback\n"); group_cancel_tid = GetCurrentThreadId(); InterlockedIncrement((LONG *)userdata); } @@ -921,21 +1044,21 @@ static void test_tp_group_cancel(void) int i; semaphores[0] = CreateSemaphoreA(NULL, 0, 4, NULL); - ok(semaphores[0] != NULL, "CreateSemaphoreA failed %u\n", GetLastError()); + ok(semaphores[0] != NULL, "CreateSemaphoreA failed %lu\n", GetLastError()); semaphores[1] = CreateSemaphoreA(NULL, 0, 1, NULL); - ok(semaphores[1] != NULL, "CreateSemaphoreA failed %u\n", GetLastError()); + ok(semaphores[1] != NULL, "CreateSemaphoreA failed %lu\n", GetLastError()); /* allocate new threadpool with only one thread */ pool = NULL; status = pTpAllocPool(&pool, NULL); - ok(!status, "TpAllocPool failed with status %x\n", status); + ok(!status, "TpAllocPool failed with status %lx\n", status); ok(pool != NULL, "expected pool != NULL\n"); pTpSetPoolMaxThreads(pool, 1); /* allocate a cleanup group */ group = NULL; status = pTpAllocCleanupGroup(&group); - ok(!status, "TpAllocCleanupGroup failed with status %x\n", status); + ok(!status, "TpAllocCleanupGroup failed with status %lx\n", status); ok(group != NULL, "expected pool != NULL\n"); /* test execution of cancellation callback */ @@ -943,9 +1066,9 @@ static void test_tp_group_cancel(void) environment.Version = 1; environment.Pool = pool; status = pTpSimpleTryPost(simple_group_cancel_cb, semaphores, &environment); - ok(!status, "TpSimpleTryPost failed with status %x\n", status); + ok(!status, "TpSimpleTryPost failed with status %lx\n", status); result = WaitForSingleObject(semaphores[1], 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); memset(&environment, 0, sizeof(environment)); environment.Version = 1; @@ -953,28 +1076,28 @@ static void test_tp_group_cancel(void) environment.CleanupGroup = group; environment.CleanupGroupCancelCallback = group_cancel_cleanup_release_cb; status = pTpSimpleTryPost(unexpected_simple_cb, (void *)0xdeadbeef, &environment); - ok(!status, "TpSimpleTryPost failed with status %x\n", status); + ok(!status, "TpSimpleTryPost failed with status %lx\n", status); work = NULL; status = pTpAllocWork(&work, unexpected_work_cb, (void *)0xdeadbeef, &environment); - ok(!status, "TpAllocWork failed with status %x\n", status); + ok(!status, "TpAllocWork failed with status %lx\n", status); ok(work != NULL, "expected work != NULL\n"); timer = NULL; status = pTpAllocTimer(&timer, unexpected_timer_cb, (void *)0xdeadbeef, &environment); - ok(!status, "TpAllocTimer failed with status %x\n", status); + ok(!status, "TpAllocTimer failed with status %lx\n", status); ok(timer != NULL, "expected timer != NULL\n"); wait = NULL; status = pTpAllocWait(&wait, unexpected_wait_cb, (void *)0xdeadbeef, &environment); - ok(!status, "TpAllocWait failed with status %x\n", status); + ok(!status, "TpAllocWait failed with status %lx\n", status); ok(wait != NULL, "expected wait != NULL\n"); group_cancel_tid = 0xdeadbeef; pTpReleaseCleanupGroupMembers(group, TRUE, semaphores); result = WaitForSingleObject(semaphores[1], 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); - ok(group_cancel_tid == GetCurrentThreadId(), "expected tid %x, got %x\n", + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + ok(group_cancel_tid == GetCurrentThreadId(), "expected tid %lx, got %lx\n", GetCurrentThreadId(), group_cancel_tid); /* test if cancellation callbacks are executed before or after wait */ @@ -985,19 +1108,19 @@ static void test_tp_group_cancel(void) environment.CleanupGroup = group; environment.CleanupGroupCancelCallback = group_cancel_cleanup_release2_cb; status = pTpAllocWork(&work, work_group_cancel_cb, semaphores, &environment); - ok(!status, "TpAllocWork failed with status %x\n", status); + ok(!status, "TpAllocWork failed with status %lx\n", status); ok(work != NULL, "expected work != NULL\n"); pTpPostWork(work); pTpPostWork(work); result = WaitForSingleObject(semaphores[1], 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); group_cancel_tid = 0xdeadbeef; pTpReleaseCleanupGroupMembers(group, TRUE, semaphores); result = WaitForSingleObject(semaphores[0], 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); - ok(group_cancel_tid == GetCurrentThreadId(), "expected tid %x, got %x\n", + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + ok(group_cancel_tid == GetCurrentThreadId(), "expected tid %lx, got %lx\n", GetCurrentThreadId(), group_cancel_tid); /* group cancel callback is not executed if object is destroyed while waiting */ @@ -1008,12 +1131,12 @@ static void test_tp_group_cancel(void) environment.CleanupGroup = group; environment.CleanupGroupCancelCallback = unexpected_group_cancel_cleanup_cb; status = pTpAllocWork(&work, work_release_cb, semaphores[1], &environment); - ok(!status, "TpAllocWork failed with status %x\n", status); + ok(!status, "TpAllocWork failed with status %lx\n", status); ok(work != NULL, "expected work != NULL\n"); pTpPostWork(work); result = WaitForSingleObject(semaphores[1], 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); pTpReleaseCleanupGroupMembers(group, TRUE, NULL); /* terminated simple callbacks should not trigger the group cancel callback */ @@ -1023,9 +1146,9 @@ static void test_tp_group_cancel(void) environment.CleanupGroup = group; environment.CleanupGroupCancelCallback = unexpected_group_cancel_cleanup_cb; status = pTpSimpleTryPost(simple_release_cb, semaphores[1], &environment); - ok(!status, "TpSimpleTryPost failed with status %x\n", status); + ok(!status, "TpSimpleTryPost failed with status %lx\n", status); result = WaitForSingleObject(semaphores[1], 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); pTpReleaseCleanupGroupMembers(group, TRUE, semaphores); /* test cancellation callback for objects with multiple instances */ @@ -1036,7 +1159,7 @@ static void test_tp_group_cancel(void) environment.CleanupGroup = group; environment.CleanupGroupCancelCallback = group_cancel_cleanup_increment_cb; status = pTpAllocWork(&work, work_cb, &userdata, &environment); - ok(!status, "TpAllocWork failed with status %x\n", status); + ok(!status, "TpAllocWork failed with status %lx\n", status); ok(work != NULL, "expected work != NULL\n"); /* post 10 identical work items at once */ @@ -1047,9 +1170,9 @@ static void test_tp_group_cancel(void) /* check if we get multiple cancellation callbacks */ group_cancel_tid = 0xdeadbeef; pTpReleaseCleanupGroupMembers(group, TRUE, &userdata2); - ok(userdata <= 5, "expected userdata <= 5, got %u\n", userdata); - ok(userdata2 == 1, "expected only one cancellation callback, got %u\n", userdata2); - ok(group_cancel_tid == GetCurrentThreadId(), "expected tid %x, got %x\n", + ok(userdata <= 5, "expected userdata <= 5, got %lu\n", userdata); + ok(userdata2 == 1, "expected only one cancellation callback, got %lu\n", userdata2); + ok(group_cancel_tid == GetCurrentThreadId(), "expected tid %lx, got %lx\n", GetCurrentThreadId(), group_cancel_tid); /* cleanup */ @@ -1062,19 +1185,12 @@ static void test_tp_group_cancel(void) static void CALLBACK instance_semaphore_completion_cb(TP_CALLBACK_INSTANCE *instance, void *userdata) { HANDLE *semaphores = userdata; - trace("Running instance completion callback\n"); pTpCallbackReleaseSemaphoreOnCompletion(instance, semaphores[0], 1); } static void CALLBACK instance_finalization_cb(TP_CALLBACK_INSTANCE *instance, void *userdata) { HANDLE *semaphores = userdata; - DWORD result; - - trace("Running instance finalization callback\n"); - - result = WaitForSingleObject(semaphores[0], 100); - ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); ReleaseSemaphore(semaphores[1], 1, NULL); } @@ -1094,7 +1210,7 @@ static void test_tp_instance(void) /* allocate new threadpool */ pool = NULL; status = pTpAllocPool(&pool, NULL); - ok(!status, "TpAllocPool failed with status %x\n", status); + ok(!status, "TpAllocPool failed with status %lx\n", status); ok(pool != NULL, "expected pool != NULL\n"); /* test for TpCallbackReleaseSemaphoreOnCompletion */ @@ -1102,9 +1218,9 @@ static void test_tp_instance(void) environment.Version = 1; environment.Pool = pool; status = pTpSimpleTryPost(instance_semaphore_completion_cb, semaphores, &environment); - ok(!status, "TpSimpleTryPost failed with status %x\n", status); + ok(!status, "TpSimpleTryPost failed with status %lx\n", status); result = WaitForSingleObject(semaphores[0], 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); /* test for finalization callback */ memset(&environment, 0, sizeof(environment)); @@ -1112,11 +1228,11 @@ static void test_tp_instance(void) environment.Pool = pool; environment.FinalizationCallback = instance_finalization_cb; status = pTpSimpleTryPost(instance_semaphore_completion_cb, semaphores, &environment); - ok(!status, "TpSimpleTryPost failed with status %x\n", status); + ok(!status, "TpSimpleTryPost failed with status %lx\n", status); result = WaitForSingleObject(semaphores[0], 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); result = WaitForSingleObject(semaphores[1], 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); /* cleanup */ pTpReleasePool(pool); @@ -1129,11 +1245,9 @@ static void CALLBACK disassociate_cb(TP_CALLBACK_INSTANCE *instance, void *userd HANDLE *semaphores = userdata; DWORD result; - trace("Running disassociate callback\n"); - pTpDisassociateCallback(instance); result = WaitForSingleObject(semaphores[0], 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); ReleaseSemaphore(semaphores[1], 1, NULL); } @@ -1142,11 +1256,9 @@ static void CALLBACK disassociate2_cb(TP_CALLBACK_INSTANCE *instance, void *user HANDLE *semaphores = userdata; DWORD result; - trace("Running disassociate2 callback\n"); - pTpDisassociateCallback(instance); result = WaitForSingleObject(semaphores[0], 100); - ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %lu\n", result); ReleaseSemaphore(semaphores[1], 1, NULL); } @@ -1155,11 +1267,9 @@ static void CALLBACK disassociate3_cb(TP_CALLBACK_INSTANCE *instance, void *user HANDLE *semaphores = userdata; DWORD result; - trace("Running disassociate3 callback\n"); - pTpDisassociateCallback(instance); result = WaitForSingleObject(semaphores[0], 100); - ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %lu\n", result); ReleaseSemaphore(semaphores[1], 1, NULL); } @@ -1181,12 +1291,12 @@ static void test_tp_disassociate(void) /* allocate new threadpool and cleanup group */ pool = NULL; status = pTpAllocPool(&pool, NULL); - ok(!status, "TpAllocPool failed with status %x\n", status); + ok(!status, "TpAllocPool failed with status %lx\n", status); ok(pool != NULL, "expected pool != NULL\n"); group = NULL; status = pTpAllocCleanupGroup(&group); - ok(!status, "TpAllocCleanupGroup failed with status %x\n", status); + ok(!status, "TpAllocCleanupGroup failed with status %lx\n", status); ok(group != NULL, "expected pool != NULL\n"); /* test TpDisassociateCallback on work objects without group */ @@ -1195,17 +1305,17 @@ static void test_tp_disassociate(void) environment.Version = 1; environment.Pool = pool; status = pTpAllocWork(&work, disassociate_cb, semaphores, &environment); - ok(!status, "TpAllocWork failed with status %x\n", status); + ok(!status, "TpAllocWork failed with status %lx\n", status); ok(work != NULL, "expected work != NULL\n"); pTpPostWork(work); pTpWaitForWork(work, FALSE); result = WaitForSingleObject(semaphores[1], 100); - ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %lu\n", result); ReleaseSemaphore(semaphores[0], 1, NULL); result = WaitForSingleObject(semaphores[1], 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); pTpReleaseWork(work); /* test TpDisassociateCallback on work objects with group (1) */ @@ -1215,17 +1325,17 @@ static void test_tp_disassociate(void) environment.Pool = pool; environment.CleanupGroup = group; status = pTpAllocWork(&work, disassociate_cb, semaphores, &environment); - ok(!status, "TpAllocWork failed with status %x\n", status); + ok(!status, "TpAllocWork failed with status %lx\n", status); ok(work != NULL, "expected work != NULL\n"); pTpPostWork(work); pTpWaitForWork(work, FALSE); result = WaitForSingleObject(semaphores[1], 100); - ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %lu\n", result); ReleaseSemaphore(semaphores[0], 1, NULL); result = WaitForSingleObject(semaphores[1], 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); pTpReleaseCleanupGroupMembers(group, FALSE, NULL); /* test TpDisassociateCallback on work objects with group (2) */ @@ -1235,7 +1345,7 @@ static void test_tp_disassociate(void) environment.Pool = pool; environment.CleanupGroup = group; status = pTpAllocWork(&work, disassociate2_cb, semaphores, &environment); - ok(!status, "TpAllocWork failed with status %x\n", status); + ok(!status, "TpAllocWork failed with status %lx\n", status); ok(work != NULL, "expected work != NULL\n"); pTpPostWork(work); @@ -1243,9 +1353,9 @@ static void test_tp_disassociate(void) ReleaseSemaphore(semaphores[0], 1, NULL); result = WaitForSingleObject(semaphores[1], 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); result = WaitForSingleObject(semaphores[0], 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); /* test TpDisassociateCallback on simple callbacks */ memset(&environment, 0, sizeof(environment)); @@ -1253,15 +1363,15 @@ static void test_tp_disassociate(void) environment.Pool = pool; environment.CleanupGroup = group; status = pTpSimpleTryPost(disassociate3_cb, semaphores, &environment); - ok(!status, "TpSimpleTryPost failed with status %x\n", status); + ok(!status, "TpSimpleTryPost failed with status %lx\n", status); pTpReleaseCleanupGroupMembers(group, FALSE, NULL); ReleaseSemaphore(semaphores[0], 1, NULL); result = WaitForSingleObject(semaphores[1], 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); result = WaitForSingleObject(semaphores[0], 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); /* cleanup */ pTpReleaseCleanupGroup(group); @@ -1273,7 +1383,6 @@ static void test_tp_disassociate(void) static void CALLBACK timer_cb(TP_CALLBACK_INSTANCE *instance, void *userdata, TP_TIMER *timer) { HANDLE semaphore = userdata; - trace("Running timer callback\n"); ReleaseSemaphore(semaphore, 1, NULL); } @@ -1290,12 +1399,12 @@ static void test_tp_timer(void) int i; semaphore = CreateSemaphoreA(NULL, 0, 1, NULL); - ok(semaphore != NULL, "CreateSemaphoreA failed %u\n", GetLastError()); + ok(semaphore != NULL, "CreateSemaphoreA failed %lu\n", GetLastError()); /* allocate new threadpool */ pool = NULL; status = pTpAllocPool(&pool, NULL); - ok(!status, "TpAllocPool failed with status %x\n", status); + ok(!status, "TpAllocPool failed with status %lx\n", status); ok(pool != NULL, "expected pool != NULL\n"); /* allocate new timer */ @@ -1304,7 +1413,7 @@ static void test_tp_timer(void) environment.Version = 1; environment.Pool = pool; status = pTpAllocTimer(&timer, timer_cb, semaphore, &environment); - ok(!status, "TpAllocTimer failed with status %x\n", status); + ok(!status, "TpAllocTimer failed with status %lx\n", status); ok(timer != NULL, "expected timer != NULL\n"); success = pTpIsTimerSet(timer); @@ -1319,9 +1428,9 @@ static void test_tp_timer(void) pTpWaitForTimer(timer, FALSE); result = WaitForSingleObject(semaphore, 100); - ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %lu\n", result); result = WaitForSingleObject(semaphore, 200); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); success = pTpIsTimerSet(timer); ok(success, "TpIsTimerSet returned FALSE\n"); @@ -1335,9 +1444,9 @@ static void test_tp_timer(void) pTpWaitForTimer(timer, FALSE); result = WaitForSingleObject(semaphore, 100); - ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %lu\n", result); result = WaitForSingleObject(semaphore, 200); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); success = pTpIsTimerSet(timer); ok(success, "TpIsTimerSet returned FALSE\n"); @@ -1350,7 +1459,7 @@ static void test_tp_timer(void) pTpWaitForTimer(timer, FALSE); result = WaitForSingleObject(semaphore, 50); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); success = pTpIsTimerSet(timer); ok(success, "TpIsTimerSet returned FALSE\n"); @@ -1364,7 +1473,7 @@ static void test_tp_timer(void) CloseHandle(semaphore); semaphore = CreateSemaphoreA(NULL, 0, 3, NULL); - ok(semaphore != NULL, "CreateSemaphoreA failed %u\n", GetLastError()); + ok(semaphore != NULL, "CreateSemaphoreA failed %lu\n", GetLastError()); /* allocate a new timer */ timer = NULL; @@ -1372,7 +1481,7 @@ static void test_tp_timer(void) environment.Version = 1; environment.Pool = pool; status = pTpAllocTimer(&timer, timer_cb, semaphore, &environment); - ok(!status, "TpAllocTimer failed with status %x\n", status); + ok(!status, "TpAllocTimer failed with status %lx\n", status); ok(timer != NULL, "expected timer != NULL\n"); /* test a relative timeout repeated periodically */ @@ -1386,11 +1495,11 @@ static void test_tp_timer(void) for (i = 0; i < 3; i++) { result = WaitForSingleObject(semaphore, 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); } ticks = GetTickCount() - ticks; ok(ticks >= 500 && (ticks <= 700 || broken(ticks <= 750)) /* Win 7 */, - "expected approximately 600 ticks, got %u\n", ticks); + "expected approximately 600 ticks, got %lu\n", ticks); /* unset the timer */ pTpSetTimer(timer, NULL, 0, 0); @@ -1413,7 +1522,6 @@ struct window_length_info static void CALLBACK window_length_cb(TP_CALLBACK_INSTANCE *instance, void *userdata, TP_TIMER *timer) { struct window_length_info *info = userdata; - trace("Running window length callback\n"); info->ticks = GetTickCount(); ReleaseSemaphore(info->semaphore, 1, NULL); } @@ -1431,12 +1539,12 @@ static void test_tp_window_length(void) BOOL merged; semaphore = CreateSemaphoreA(NULL, 0, 2, NULL); - ok(semaphore != NULL, "CreateSemaphoreA failed %u\n", GetLastError()); + ok(semaphore != NULL, "CreateSemaphoreA failed %lu\n", GetLastError()); /* allocate new threadpool */ pool = NULL; status = pTpAllocPool(&pool, NULL); - ok(!status, "TpAllocPool failed with status %x\n", status); + ok(!status, "TpAllocPool failed with status %lx\n", status); ok(pool != NULL, "expected pool != NULL\n"); /* allocate two identical timers */ @@ -1447,13 +1555,13 @@ static void test_tp_window_length(void) timer1 = NULL; info1.semaphore = semaphore; status = pTpAllocTimer(&timer1, window_length_cb, &info1, &environment); - ok(!status, "TpAllocTimer failed with status %x\n", status); + ok(!status, "TpAllocTimer failed with status %lx\n", status); ok(timer1 != NULL, "expected timer1 != NULL\n"); timer2 = NULL; info2.semaphore = semaphore; status = pTpAllocTimer(&timer2, window_length_cb, &info2, &environment); - ok(!status, "TpAllocTimer failed with status %x\n", status); + ok(!status, "TpAllocTimer failed with status %lx\n", status); ok(timer2 != NULL, "expected timer2 != NULL\n"); /* choose parameters so that timers are not merged */ @@ -1468,9 +1576,9 @@ static void test_tp_window_length(void) pTpSetTimer(timer1, &when, 0, 75); result = WaitForSingleObject(semaphore, 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); result = WaitForSingleObject(semaphore, 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); ok(info1.ticks != 0 && info2.ticks != 0, "expected that ticks are nonzero\n"); ok(info2.ticks >= info1.ticks + 75 || broken(info2.ticks < info1.ticks + 75) /* Win 2008 */, "expected that timers are not merged\n"); @@ -1487,9 +1595,9 @@ static void test_tp_window_length(void) pTpSetTimer(timer1, &when, 0, 200); result = WaitForSingleObject(semaphore, 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); result = WaitForSingleObject(semaphore, 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); ok(info1.ticks != 0 && info2.ticks != 0, "expected that ticks are nonzero\n"); merged = info2.ticks >= info1.ticks - 50 && info2.ticks <= info1.ticks + 50; ok(merged || broken(!merged) /* Win 10 */, "expected that timers are merged\n"); @@ -1506,9 +1614,9 @@ static void test_tp_window_length(void) pTpSetTimer(timer2, &when, 0, 0); result = WaitForSingleObject(semaphore, 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); result = WaitForSingleObject(semaphore, 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); ok(info1.ticks != 0 && info2.ticks != 0, "expected that ticks are nonzero\n"); merged = info2.ticks >= info1.ticks - 50 && info2.ticks <= info1.ticks + 50; todo_wine @@ -1531,14 +1639,12 @@ static void CALLBACK wait_cb(TP_CALLBACK_INSTANCE *instance, void *userdata, TP_WAIT *wait, TP_WAIT_RESULT result) { struct wait_info *info = userdata; - trace("Running wait callback\n"); - if (result == WAIT_OBJECT_0) InterlockedIncrement(&info->userdata); else if (result == WAIT_TIMEOUT) InterlockedExchangeAdd(&info->userdata, 0x10000); else - ok(0, "unexpected result %u\n", result); + ok(0, "unexpected result %lu\n", result); ReleaseSemaphore(info->semaphore, 1, NULL); } @@ -1562,7 +1668,7 @@ static void test_tp_wait(void) /* allocate new threadpool */ pool = NULL; status = pTpAllocPool(&pool, NULL); - ok(!status, "TpAllocPool failed with status %x\n", status); + ok(!status, "TpAllocPool failed with status %lx\n", status); ok(pool != NULL, "expected pool != NULL\n"); /* allocate new wait items */ @@ -1572,12 +1678,12 @@ static void test_tp_wait(void) wait1 = NULL; status = pTpAllocWait(&wait1, wait_cb, &info, &environment); - ok(!status, "TpAllocWait failed with status %x\n", status); + ok(!status, "TpAllocWait failed with status %lx\n", status); ok(wait1 != NULL, "expected wait1 != NULL\n"); wait2 = NULL; status = pTpAllocWait(&wait2, wait_cb, &info, &environment); - ok(!status, "TpAllocWait failed with status %x\n", status); + ok(!status, "TpAllocWait failed with status %lx\n", status); ok(wait2 != NULL, "expected wait2 != NULL\n"); /* infinite timeout, signal the semaphore immediately */ @@ -1585,79 +1691,79 @@ static void test_tp_wait(void) pTpSetWait(wait1, semaphores[1], NULL); ReleaseSemaphore(semaphores[1], 1, NULL); result = WaitForSingleObject(semaphores[0], 100); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); - ok(info.userdata == 1, "expected info.userdata = 1, got %u\n", info.userdata); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 1, "expected info.userdata = 1, got %lu\n", info.userdata); result = WaitForSingleObject(semaphores[1], 0); - ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %lu\n", result); /* relative timeout, no event */ info.userdata = 0; when.QuadPart = (ULONGLONG)200 * -10000; pTpSetWait(wait1, semaphores[1], &when); result = WaitForSingleObject(semaphores[0], 100); - ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); - ok(info.userdata == 0, "expected info.userdata = 0, got %u\n", info.userdata); + ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 0, "expected info.userdata = 0, got %lu\n", info.userdata); result = WaitForSingleObject(semaphores[0], 200); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); - ok(info.userdata == 0x10000, "expected info.userdata = 0x10000, got %u\n", info.userdata); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 0x10000, "expected info.userdata = 0x10000, got %lu\n", info.userdata); result = WaitForSingleObject(semaphores[1], 0); - ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %lu\n", result); /* repeat test with call to TpWaitForWait(..., TRUE) */ info.userdata = 0; when.QuadPart = (ULONGLONG)200 * -10000; pTpSetWait(wait1, semaphores[1], &when); result = WaitForSingleObject(semaphores[0], 100); - ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %lu\n", result); pTpWaitForWait(wait1, TRUE); - ok(info.userdata == 0, "expected info.userdata = 0, got %u\n", info.userdata); + ok(info.userdata == 0, "expected info.userdata = 0, got %lu\n", info.userdata); result = WaitForSingleObject(semaphores[0], 200); ok(result == WAIT_OBJECT_0 || broken(result == WAIT_TIMEOUT) /* Win 8 */, - "WaitForSingleObject returned %u\n", result); + "WaitForSingleObject returned %lu\n", result); if (result == WAIT_OBJECT_0) - ok(info.userdata == 0x10000, "expected info.userdata = 0x10000, got %u\n", info.userdata); + ok(info.userdata == 0x10000, "expected info.userdata = 0x10000, got %lu\n", info.userdata); else - ok(info.userdata == 0, "expected info.userdata = 0, got %u\n", info.userdata); + ok(info.userdata == 0, "expected info.userdata = 0, got %lu\n", info.userdata); result = WaitForSingleObject(semaphores[1], 0); - ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %lu\n", result); /* relative timeout, with event */ info.userdata = 0; when.QuadPart = (ULONGLONG)200 * -10000; pTpSetWait(wait1, semaphores[1], &when); result = WaitForSingleObject(semaphores[0], 100); - ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); - ok(info.userdata == 0, "expected info.userdata = 0, got %u\n", info.userdata); + ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 0, "expected info.userdata = 0, got %lu\n", info.userdata); ReleaseSemaphore(semaphores[1], 1, NULL); result = WaitForSingleObject(semaphores[0], 100); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); - ok(info.userdata == 1, "expected info.userdata = 1, got %u\n", info.userdata); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 1, "expected info.userdata = 1, got %lu\n", info.userdata); result = WaitForSingleObject(semaphores[1], 0); - ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %lu\n", result); /* repeat test with call to TpWaitForWait(..., TRUE) */ info.userdata = 0; when.QuadPart = (ULONGLONG)200 * -10000; pTpSetWait(wait1, semaphores[1], &when); result = WaitForSingleObject(semaphores[0], 100); - ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %lu\n", result); pTpWaitForWait(wait1, TRUE); - ok(info.userdata == 0, "expected info.userdata = 0, got %u\n", info.userdata); + ok(info.userdata == 0, "expected info.userdata = 0, got %lu\n", info.userdata); ReleaseSemaphore(semaphores[1], 1, NULL); result = WaitForSingleObject(semaphores[0], 100); ok(result == WAIT_OBJECT_0 || broken(result == WAIT_TIMEOUT) /* Win 8 */, - "WaitForSingleObject returned %u\n", result); + "WaitForSingleObject returned %lu\n", result); if (result == WAIT_OBJECT_0) { - ok(info.userdata == 1, "expected info.userdata = 1, got %u\n", info.userdata); + ok(info.userdata == 1, "expected info.userdata = 1, got %lu\n", info.userdata); result = WaitForSingleObject(semaphores[1], 0); - ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %lu\n", result); } else { - ok(info.userdata == 0, "expected info.userdata = 0, got %u\n", info.userdata); + ok(info.userdata == 0, "expected info.userdata = 0, got %lu\n", info.userdata); result = WaitForSingleObject(semaphores[1], 0); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); } /* absolute timeout, no event */ @@ -1666,13 +1772,13 @@ static void test_tp_wait(void) when.QuadPart += (ULONGLONG)200 * 10000; pTpSetWait(wait1, semaphores[1], &when); result = WaitForSingleObject(semaphores[0], 100); - ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); - ok(info.userdata == 0, "expected info.userdata = 0, got %u\n", info.userdata); + ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 0, "expected info.userdata = 0, got %lu\n", info.userdata); result = WaitForSingleObject(semaphores[0], 200); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); - ok(info.userdata == 0x10000, "expected info.userdata = 0x10000, got %u\n", info.userdata); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 0x10000, "expected info.userdata = 0x10000, got %lu\n", info.userdata); result = WaitForSingleObject(semaphores[1], 0); - ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %lu\n", result); /* absolute timeout, with event */ info.userdata = 0; @@ -1680,63 +1786,63 @@ static void test_tp_wait(void) when.QuadPart += (ULONGLONG)200 * 10000; pTpSetWait(wait1, semaphores[1], &when); result = WaitForSingleObject(semaphores[0], 100); - ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); - ok(info.userdata == 0, "expected info.userdata = 0, got %u\n", info.userdata); + ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 0, "expected info.userdata = 0, got %lu\n", info.userdata); ReleaseSemaphore(semaphores[1], 1, NULL); result = WaitForSingleObject(semaphores[0], 100); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); - ok(info.userdata == 1, "expected info.userdata = 1, got %u\n", info.userdata); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 1, "expected info.userdata = 1, got %lu\n", info.userdata); result = WaitForSingleObject(semaphores[1], 0); - ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %lu\n", result); /* test timeout of zero */ info.userdata = 0; when.QuadPart = 0; pTpSetWait(wait1, semaphores[1], &when); result = WaitForSingleObject(semaphores[0], 100); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); - ok(info.userdata == 0x10000, "expected info.userdata = 0x10000, got %u\n", info.userdata); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 0x10000, "expected info.userdata = 0x10000, got %lu\n", info.userdata); result = WaitForSingleObject(semaphores[1], 0); - ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %lu\n", result); /* cancel a pending wait */ info.userdata = 0; when.QuadPart = (ULONGLONG)250 * -10000; pTpSetWait(wait1, semaphores[1], &when); result = WaitForSingleObject(semaphores[0], 100); - ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %lu\n", result); pTpSetWait(wait1, NULL, (void *)0xdeadbeef); Sleep(50); ReleaseSemaphore(semaphores[1], 1, NULL); result = WaitForSingleObject(semaphores[0], 100); - ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); - ok(info.userdata == 0, "expected info.userdata = 0, got %u\n", info.userdata); + ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 0, "expected info.userdata = 0, got %lu\n", info.userdata); result = WaitForSingleObject(semaphores[1], 0); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); /* test with INVALID_HANDLE_VALUE */ info.userdata = 0; when.QuadPart = 0; pTpSetWait(wait1, INVALID_HANDLE_VALUE, &when); result = WaitForSingleObject(semaphores[0], 100); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); - ok(info.userdata == 0x10000, "expected info.userdata = 0x10000, got %u\n", info.userdata); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 0x10000, "expected info.userdata = 0x10000, got %lu\n", info.userdata); /* cancel a pending wait with INVALID_HANDLE_VALUE */ info.userdata = 0; when.QuadPart = (ULONGLONG)250 * -10000; pTpSetWait(wait1, semaphores[1], &when); result = WaitForSingleObject(semaphores[0], 100); - ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %lu\n", result); when.QuadPart = 0; pTpSetWait(wait1, INVALID_HANDLE_VALUE, &when); Sleep(50); ReleaseSemaphore(semaphores[1], 1, NULL); result = WaitForSingleObject(semaphores[0], 100); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); - ok(info.userdata == 0x10000, "expected info.userdata = 0x10000, got %u\n", info.userdata); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 0x10000, "expected info.userdata = 0x10000, got %lu\n", info.userdata); result = WaitForSingleObject(semaphores[1], 0); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); CloseHandle(semaphores[1]); semaphores[1] = CreateSemaphoreW(NULL, 0, 2, NULL); @@ -1749,12 +1855,12 @@ static void test_tp_wait(void) Sleep(50); ReleaseSemaphore(semaphores[1], 1, NULL); result = WaitForSingleObject(semaphores[0], 100); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); result = WaitForSingleObject(semaphores[0], 100); - ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); - ok(info.userdata == 1, "expected info.userdata = 1, got %u\n", info.userdata); + ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 1, "expected info.userdata = 1, got %lu\n", info.userdata); result = WaitForSingleObject(semaphores[1], 0); - ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %lu\n", result); /* repeat test above with release count 2 */ info.userdata = 0; @@ -1763,12 +1869,12 @@ static void test_tp_wait(void) Sleep(50); result = ReleaseSemaphore(semaphores[1], 2, NULL); result = WaitForSingleObject(semaphores[0], 100); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); result = WaitForSingleObject(semaphores[0], 100); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); - ok(info.userdata == 2, "expected info.userdata = 2, got %u\n", info.userdata); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + ok(info.userdata == 2, "expected info.userdata = 2, got %lu\n", info.userdata); result = WaitForSingleObject(semaphores[1], 0); - ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); + ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %lu\n", result); /* cleanup */ pTpReleaseWait(wait1); @@ -1793,12 +1899,13 @@ static void CALLBACK multi_wait_cb(TP_CALLBACK_INSTANCE *instance, void *userdat else if (result == WAIT_TIMEOUT) multi_wait_info.result = 0x10000 | index; else - ok(0, "unexpected result %u\n", result); + ok(0, "unexpected result %lu\n", result); ReleaseSemaphore(multi_wait_info.semaphore, 1, NULL); } static void test_tp_multi_wait(void) { + TP_POOL_STACK_INFORMATION stack_info; TP_CALLBACK_ENVIRON environment; HANDLE semaphores[512]; TP_WAIT *waits[512]; @@ -1816,78 +1923,83 @@ static void test_tp_multi_wait(void) /* allocate new threadpool */ pool = NULL; status = pTpAllocPool(&pool, NULL); - ok(!status, "TpAllocPool failed with status %x\n", status); + ok(!status, "TpAllocPool failed with status %lx\n", status); ok(pool != NULL, "expected pool != NULL\n"); + /* many threads -> use the smallest stack possible */ + stack_info.StackReserve = 256 * 1024; + stack_info.StackCommit = 4 * 1024; + status = pTpSetPoolStackInformation(pool, &stack_info); + ok(!status, "TpQueryPoolStackInformation failed: %lx\n", status); memset(&environment, 0, sizeof(environment)); environment.Version = 1; environment.Pool = pool; /* create semaphores and corresponding wait objects */ - for (i = 0; i < sizeof(semaphores)/sizeof(semaphores[0]); i++) + for (i = 0; i < ARRAY_SIZE(semaphores); i++) { semaphores[i] = CreateSemaphoreW(NULL, 0, 1, NULL); ok(semaphores[i] != NULL, "failed to create semaphore %i\n", i); waits[i] = NULL; status = pTpAllocWait(&waits[i], multi_wait_cb, (void *)(DWORD_PTR)i, &environment); - ok(!status, "TpAllocWait failed with status %x\n", status); + ok(!status, "TpAllocWait failed with status %lx\n", status); ok(waits[i] != NULL, "expected waits[%d] != NULL\n", i); pTpSetWait(waits[i], semaphores[i], NULL); } /* release all semaphores and wait for callback */ - for (i = 0; i < sizeof(semaphores)/sizeof(semaphores[0]); i++) + for (i = 0; i < ARRAY_SIZE(semaphores); i++) { multi_wait_info.result = 0; ReleaseSemaphore(semaphores[i], 1, NULL); - result = WaitForSingleObject(semaphore, 100); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); - ok(multi_wait_info.result == i, "expected result %d, got %u\n", i, multi_wait_info.result); + result = WaitForSingleObject(semaphore, 2000); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + ok(multi_wait_info.result == i, "expected result %d, got %lu\n", i, multi_wait_info.result); pTpSetWait(waits[i], semaphores[i], NULL); } /* repeat the same test in reverse order */ - for (i = sizeof(semaphores)/sizeof(semaphores[0]) - 1; i >= 0; i--) + for (i = ARRAY_SIZE(semaphores) - 1; i >= 0; i--) { multi_wait_info.result = 0; ReleaseSemaphore(semaphores[i], 1, NULL); - result = WaitForSingleObject(semaphore, 100); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); - ok(multi_wait_info.result == i, "expected result %d, got %u\n", i, multi_wait_info.result); + result = WaitForSingleObject(semaphore, 2000); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + ok(multi_wait_info.result == i, "expected result %d, got %lu\n", i, multi_wait_info.result); pTpSetWait(waits[i], semaphores[i], NULL); } /* test timeout of wait objects */ multi_wait_info.result = 0; - for (i = 0; i < sizeof(semaphores)/sizeof(semaphores[0]); i++) + for (i = 0; i < ARRAY_SIZE(semaphores); i++) { when.QuadPart = (ULONGLONG)50 * -10000; pTpSetWait(waits[i], semaphores[i], &when); } - for (i = 0; i < sizeof(semaphores)/sizeof(semaphores[0]); i++) + for (i = 0; i < ARRAY_SIZE(semaphores); i++) { - result = WaitForSingleObject(semaphore, 150); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); + result = WaitForSingleObject(semaphore, 2000); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); } ok(multi_wait_info.result >> 16, "expected multi_wait_info.result >> 16 != 0\n"); /* destroy the wait objects and semaphores while waiting */ - for (i = 0; i < sizeof(semaphores)/sizeof(semaphores[0]); i++) + for (i = 0; i < ARRAY_SIZE(semaphores); i++) { pTpSetWait(waits[i], semaphores[i], NULL); } Sleep(50); - for (i = 0; i < sizeof(semaphores)/sizeof(semaphores[0]); i++) + for (i = 0; i < ARRAY_SIZE(semaphores); i++) { pTpReleaseWait(waits[i]); NtClose(semaphores[i]); @@ -1897,6 +2009,393 @@ static void test_tp_multi_wait(void) CloseHandle(semaphore); } +struct io_cb_ctx +{ + unsigned int count; + void *ovl; + NTSTATUS ret; + ULONG_PTR length; + TP_IO *io; +}; + +static void CALLBACK io_cb(TP_CALLBACK_INSTANCE *instance, void *userdata, + void *cvalue, IO_STATUS_BLOCK *iosb, TP_IO *io) +{ + struct io_cb_ctx *ctx = userdata; + ++ctx->count; + ctx->ovl = cvalue; + ctx->ret = iosb->Status; + ctx->length = iosb->Information; + ctx->io = io; +} + +static DWORD WINAPI io_wait_thread(void *arg) +{ + TP_IO *io = arg; + pTpWaitForIoCompletion(io, FALSE); + return 0; +} + +static void test_tp_io(void) +{ + TP_CALLBACK_ENVIRON environment = {.Version = 1}; +#ifdef __REACTOS__ + OVERLAPPED ovl = {0}, ovl2 = {0}; +#else + OVERLAPPED ovl = {}, ovl2 = {}; +#endif + HANDLE client, server, thread; + struct io_cb_ctx userdata; + char in[1], in2[1]; + const char out[1]; + NTSTATUS status; + DWORD ret_size; + TP_POOL *pool; + TP_IO *io; + BOOL ret; + + ovl.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); + + status = pTpAllocPool(&pool, NULL); + ok(!status, "failed to allocate pool, status %#lx\n", status); + + server = CreateNamedPipeA("\\\\.\\pipe\\wine_tp_test", + PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 0, 1, 1024, 1024, 0, NULL); + ok(server != INVALID_HANDLE_VALUE, "Failed to create server pipe, error %lu.\n", GetLastError()); + client = CreateFileA("\\\\.\\pipe\\wine_tp_test", GENERIC_READ | GENERIC_WRITE, + 0, NULL, OPEN_EXISTING, 0, 0); + ok(client != INVALID_HANDLE_VALUE, "Failed to create client pipe, error %lu.\n", GetLastError()); + + environment.Pool = pool; + io = NULL; + status = pTpAllocIoCompletion(&io, server, io_cb, &userdata, &environment); + ok(!status, "got %#lx\n", status); + ok(!!io, "expected non-NULL TP_IO\n"); + + pTpWaitForIoCompletion(io, FALSE); + + userdata.count = 0; + pTpStartAsyncIoOperation(io); + + thread = CreateThread(NULL, 0, io_wait_thread, io, 0, NULL); + ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "TpWaitForIoCompletion() should not return\n"); + + ret = ReadFile(server, in, sizeof(in), NULL, &ovl); + ok(!ret, "wrong ret %d\n", ret); + ok(GetLastError() == ERROR_IO_PENDING, "wrong error %lu\n", GetLastError()); + + ret = WriteFile(client, out, sizeof(out), &ret_size, NULL); + ok(ret, "WriteFile() failed, error %lu\n", GetLastError()); + + pTpWaitForIoCompletion(io, FALSE); + ok(userdata.count == 1, "callback ran %u times\n", userdata.count); + ok(userdata.ovl == &ovl, "expected %p, got %p\n", &ovl, userdata.ovl); + ok(userdata.ret == STATUS_SUCCESS, "got status %#lx\n", userdata.ret); + ok(userdata.length == 1, "got length %Iu\n", userdata.length); + ok(userdata.io == io, "expected %p, got %p\n", io, userdata.io); + + ok(!WaitForSingleObject(thread, 1000), "wait timed out\n"); + CloseHandle(thread); + + userdata.count = 0; + pTpStartAsyncIoOperation(io); + pTpStartAsyncIoOperation(io); + + ret = ReadFile(server, in, sizeof(in), NULL, &ovl); + ok(!ret, "wrong ret %d\n", ret); + ok(GetLastError() == ERROR_IO_PENDING, "wrong error %lu\n", GetLastError()); + ret = ReadFile(server, in2, sizeof(in2), NULL, &ovl2); + ok(!ret, "wrong ret %d\n", ret); + ok(GetLastError() == ERROR_IO_PENDING, "wrong error %lu\n", GetLastError()); + + ret = WriteFile(client, out, sizeof(out), &ret_size, NULL); + ok(ret, "WriteFile() failed, error %lu\n", GetLastError()); + ret = WriteFile(client, out, sizeof(out), &ret_size, NULL); + ok(ret, "WriteFile() failed, error %lu\n", GetLastError()); + + pTpWaitForIoCompletion(io, FALSE); + ok(userdata.count == 2, "callback ran %u times\n", userdata.count); + ok(userdata.ret == STATUS_SUCCESS, "got status %#lx\n", userdata.ret); + ok(userdata.length == 1, "got length %Iu\n", userdata.length); + ok(userdata.io == io, "expected %p, got %p\n", io, userdata.io); + + /* The documentation is a bit unclear about passing TRUE to + * WaitForThreadpoolIoCallbacks()—"pending I/O requests are not canceled" + * [as with CancelIoEx()], but pending threadpool callbacks are, even those + * which have not yet reached the completion port [as with + * TpCancelAsyncIoOperation()]. */ + userdata.count = 0; + pTpStartAsyncIoOperation(io); + + pTpWaitForIoCompletion(io, TRUE); + ok(!userdata.count, "callback ran %u times\n", userdata.count); + + pTpStartAsyncIoOperation(io); + + ret = WriteFile(client, out, sizeof(out), &ret_size, NULL); + ok(ret, "WriteFile() failed, error %lu\n", GetLastError()); + + ret = ReadFile(server, in, sizeof(in), NULL, &ovl); + ok(ret, "wrong ret %d\n", ret); + + pTpWaitForIoCompletion(io, FALSE); + ok(userdata.count == 1, "callback ran %u times\n", userdata.count); + ok(userdata.ovl == &ovl, "expected %p, got %p\n", &ovl, userdata.ovl); + ok(userdata.ret == STATUS_SUCCESS, "got status %#lx\n", userdata.ret); + ok(userdata.length == 1, "got length %Iu\n", userdata.length); + ok(userdata.io == io, "expected %p, got %p\n", io, userdata.io); + + userdata.count = 0; + pTpStartAsyncIoOperation(io); + + ret = ReadFile(server, NULL, 1, NULL, &ovl); + ok(!ret, "wrong ret %d\n", ret); + ok(GetLastError() == ERROR_NOACCESS, "wrong error %lu\n", GetLastError()); + + pTpCancelAsyncIoOperation(io); + pTpWaitForIoCompletion(io, FALSE); + ok(!userdata.count, "callback ran %u times\n", userdata.count); + + userdata.count = 0; + pTpStartAsyncIoOperation(io); + + ret = ReadFile(server, in, sizeof(in), NULL, &ovl); + ok(!ret, "wrong ret %d\n", ret); + ok(GetLastError() == ERROR_IO_PENDING, "wrong error %lu\n", GetLastError()); + ret = CancelIo(server); + ok(ret, "CancelIo() failed, error %lu\n", GetLastError()); + + pTpWaitForIoCompletion(io, FALSE); + ok(userdata.count == 1, "callback ran %u times\n", userdata.count); + ok(userdata.ovl == &ovl, "expected %p, got %p\n", &ovl, userdata.ovl); + ok(userdata.ret == STATUS_CANCELLED, "got status %#lx\n", userdata.ret); + ok(!userdata.length, "got length %Iu\n", userdata.length); + ok(userdata.io == io, "expected %p, got %p\n", io, userdata.io); + + userdata.count = 0; + pTpStartAsyncIoOperation(io); + pTpCancelAsyncIoOperation(io); + ret = ReadFile(server, in, sizeof(in), NULL, &ovl); + ok(!ret, "wrong ret %d\n", ret); + ret = WriteFile(client, out, sizeof(out), &ret_size, NULL); + ok(ret, "WriteFile() failed, error %lu\n", GetLastError()); + ok(GetLastError() == ERROR_IO_PENDING, "wrong error %lu\n", GetLastError()); + + pTpWaitForIoCompletion(io, FALSE); + if (0) + { + /* Add a sleep to check that callback is not called later. Commented out to + * save the test time. */ + Sleep(200); + } + ok(userdata.count == 0, "callback ran %u times\n", userdata.count); + + pTpReleaseIoCompletion(io); + CloseHandle(server); + + /* Test TPIO object destruction. */ + server = CreateNamedPipeA("\\\\.\\pipe\\wine_tp_test", + PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 0, 1, 1024, 1024, 0, NULL); + ok(server != INVALID_HANDLE_VALUE, "Failed to create server pipe, error %lu.\n", GetLastError()); + io = NULL; + status = pTpAllocIoCompletion(&io, server, io_cb, &userdata, &environment); + ok(!status, "got %#lx\n", status); + + ret = HeapValidate(GetProcessHeap(), 0, io); + ok(ret, "Got unexpected ret %#x.\n", ret); + pTpReleaseIoCompletion(io); + ret = HeapValidate(GetProcessHeap(), 0, io); + ok(!ret, "Got unexpected ret %#x.\n", ret); + CloseHandle(server); + CloseHandle(client); + + server = CreateNamedPipeA("\\\\.\\pipe\\wine_tp_test", + PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 0, 1, 1024, 1024, 0, NULL); + ok(server != INVALID_HANDLE_VALUE, "Failed to create server pipe, error %lu.\n", GetLastError()); + client = CreateFileA("\\\\.\\pipe\\wine_tp_test", GENERIC_READ | GENERIC_WRITE, + 0, NULL, OPEN_EXISTING, 0, 0); + ok(client != INVALID_HANDLE_VALUE, "Failed to create client pipe, error %lu.\n", GetLastError()); + + io = NULL; + status = pTpAllocIoCompletion(&io, server, io_cb, &userdata, &environment); + ok(!status, "got %#lx\n", status); + pTpStartAsyncIoOperation(io); + pTpWaitForIoCompletion(io, TRUE); + ret = HeapValidate(GetProcessHeap(), 0, io); + ok(ret, "Got unexpected ret %#x.\n", ret); + pTpReleaseIoCompletion(io); + ret = HeapValidate(GetProcessHeap(), 0, io); + ok(ret, "Got unexpected ret %#x.\n", ret); + + if (0) + { + /* Object destruction will wait until one completion arrives (which was started but not cancelled). + * Commented out to save test time. */ + Sleep(1000); + ret = HeapValidate(GetProcessHeap(), 0, io); + ok(ret, "Got unexpected ret %#x.\n", ret); + ret = ReadFile(server, in, sizeof(in), NULL, &ovl); + ok(!ret, "wrong ret %d\n", ret); + ret = WriteFile(client, out, sizeof(out), &ret_size, NULL); + ok(ret, "WriteFile() failed, error %lu\n", GetLastError()); + Sleep(2000); + ret = HeapValidate(GetProcessHeap(), 0, io); + ok(!ret, "Got unexpected ret %#x.\n", ret); + } + + CloseHandle(server); + CloseHandle(ovl.hEvent); + CloseHandle(client); + pTpReleasePool(pool); +} + +static void CALLBACK kernel32_io_cb(TP_CALLBACK_INSTANCE *instance, void *userdata, + void *ovl, ULONG ret, ULONG_PTR length, TP_IO *io) +{ + struct io_cb_ctx *ctx = userdata; + ++ctx->count; + ctx->ovl = ovl; + ctx->ret = ret; + ctx->length = length; + ctx->io = io; +} + +static void test_kernel32_tp_io(void) +{ + TP_CALLBACK_ENVIRON environment = {.Version = 1}; +#ifdef __REACTOS__ + OVERLAPPED ovl = {0}, ovl2 = {0}; +#else + OVERLAPPED ovl = {}, ovl2 = {}; +#endif + HANDLE client, server, thread; + struct io_cb_ctx userdata; + char in[1], in2[1]; + const char out[1]; + NTSTATUS status; + DWORD ret_size; + TP_POOL *pool; + TP_IO *io; + BOOL ret; + + ovl.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); + + status = pTpAllocPool(&pool, NULL); + ok(!status, "failed to allocate pool, status %#lx\n", status); + + server = CreateNamedPipeA("\\\\.\\pipe\\wine_tp_test", + PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 0, 1, 1024, 1024, 0, NULL); + ok(server != INVALID_HANDLE_VALUE, "Failed to create server pipe, error %lu.\n", GetLastError()); + client = CreateFileA("\\\\.\\pipe\\wine_tp_test", GENERIC_READ | GENERIC_WRITE, + 0, NULL, OPEN_EXISTING, 0, 0); + ok(client != INVALID_HANDLE_VALUE, "Failed to create client pipe, error %lu.\n", GetLastError()); + + environment.Pool = pool; + io = NULL; + io = pCreateThreadpoolIo(server, kernel32_io_cb, &userdata, &environment); + ok(!!io, "expected non-NULL TP_IO\n"); + + pWaitForThreadpoolIoCallbacks(io, FALSE); + + userdata.count = 0; + pStartThreadpoolIo(io); + + thread = CreateThread(NULL, 0, io_wait_thread, io, 0, NULL); + ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "TpWaitForIoCompletion() should not return\n"); + + ret = ReadFile(server, in, sizeof(in), NULL, &ovl); + ok(!ret, "wrong ret %d\n", ret); + ok(GetLastError() == ERROR_IO_PENDING, "wrong error %lu\n", GetLastError()); + + ret = WriteFile(client, out, sizeof(out), &ret_size, NULL); + ok(ret, "WriteFile() failed, error %lu\n", GetLastError()); + + pWaitForThreadpoolIoCallbacks(io, FALSE); + ok(userdata.count == 1, "callback ran %u times\n", userdata.count); + ok(userdata.ovl == &ovl, "expected %p, got %p\n", &ovl, userdata.ovl); + ok(userdata.ret == ERROR_SUCCESS, "got status %#lx\n", userdata.ret); + ok(userdata.length == 1, "got length %Iu\n", userdata.length); + ok(userdata.io == io, "expected %p, got %p\n", io, userdata.io); + + ok(!WaitForSingleObject(thread, 1000), "wait timed out\n"); + CloseHandle(thread); + + userdata.count = 0; + pStartThreadpoolIo(io); + pStartThreadpoolIo(io); + + ret = ReadFile(server, in, sizeof(in), NULL, &ovl); + ok(!ret, "wrong ret %d\n", ret); + ok(GetLastError() == ERROR_IO_PENDING, "wrong error %lu\n", GetLastError()); + ret = ReadFile(server, in2, sizeof(in2), NULL, &ovl2); + ok(!ret, "wrong ret %d\n", ret); + ok(GetLastError() == ERROR_IO_PENDING, "wrong error %lu\n", GetLastError()); + + ret = WriteFile(client, out, sizeof(out), &ret_size, NULL); + ok(ret, "WriteFile() failed, error %lu\n", GetLastError()); + ret = WriteFile(client, out, sizeof(out), &ret_size, NULL); + ok(ret, "WriteFile() failed, error %lu\n", GetLastError()); + + pWaitForThreadpoolIoCallbacks(io, FALSE); + ok(userdata.count == 2, "callback ran %u times\n", userdata.count); + ok(userdata.ret == STATUS_SUCCESS, "got status %#lx\n", userdata.ret); + ok(userdata.length == 1, "got length %Iu\n", userdata.length); + ok(userdata.io == io, "expected %p, got %p\n", io, userdata.io); + + userdata.count = 0; + pStartThreadpoolIo(io); + pWaitForThreadpoolIoCallbacks(io, TRUE); + ok(!userdata.count, "callback ran %u times\n", userdata.count); + + pStartThreadpoolIo(io); + + ret = WriteFile(client, out, sizeof(out), &ret_size, NULL); + ok(ret, "WriteFile() failed, error %lu\n", GetLastError()); + + ret = ReadFile(server, in, sizeof(in), NULL, &ovl); + ok(ret, "wrong ret %d\n", ret); + + pWaitForThreadpoolIoCallbacks(io, FALSE); + ok(userdata.count == 1, "callback ran %u times\n", userdata.count); + ok(userdata.ovl == &ovl, "expected %p, got %p\n", &ovl, userdata.ovl); + ok(userdata.ret == ERROR_SUCCESS, "got status %#lx\n", userdata.ret); + ok(userdata.length == 1, "got length %Iu\n", userdata.length); + ok(userdata.io == io, "expected %p, got %p\n", io, userdata.io); + + userdata.count = 0; + pStartThreadpoolIo(io); + + ret = ReadFile(server, NULL, 1, NULL, &ovl); + ok(!ret, "wrong ret %d\n", ret); + ok(GetLastError() == ERROR_NOACCESS, "wrong error %lu\n", GetLastError()); + + pCancelThreadpoolIo(io); + pWaitForThreadpoolIoCallbacks(io, FALSE); + ok(!userdata.count, "callback ran %u times\n", userdata.count); + + userdata.count = 0; + pStartThreadpoolIo(io); + + ret = ReadFile(server, in, sizeof(in), NULL, &ovl); + ok(!ret, "wrong ret %d\n", ret); + ok(GetLastError() == ERROR_IO_PENDING, "wrong error %lu\n", GetLastError()); + ret = CancelIo(server); + ok(ret, "CancelIo() failed, error %lu\n", GetLastError()); + + pWaitForThreadpoolIoCallbacks(io, FALSE); + ok(userdata.count == 1, "callback ran %u times\n", userdata.count); + ok(userdata.ovl == &ovl, "expected %p, got %p\n", &ovl, userdata.ovl); + ok(userdata.ret == ERROR_OPERATION_ABORTED, "got status %#lx\n", userdata.ret); + ok(!userdata.length, "got length %Iu\n", userdata.length); + ok(userdata.io == io, "expected %p, got %p\n", io, userdata.io); + + CloseHandle(ovl.hEvent); + CloseHandle(client); + CloseHandle(server); + pCloseThreadpoolIo(io); + pTpReleasePool(pool); +} + START_TEST(threadpool) { test_RtlQueueWorkItem(); @@ -1916,4 +2415,6 @@ START_TEST(threadpool) test_tp_window_length(); test_tp_wait(); test_tp_multi_wait(); + test_tp_io(); + test_kernel32_tp_io(); } diff --git a/modules/rostests/winetests/propsys/CMakeLists.txt b/modules/rostests/winetests/propsys/CMakeLists.txt index ac14259b7698f..a38b9654b9d78 100644 --- a/modules/rostests/winetests/propsys/CMakeLists.txt +++ b/modules/rostests/winetests/propsys/CMakeLists.txt @@ -1,6 +1,7 @@ add_definitions(-DUSE_WINE_TODOS -DWINETEST_USE_DBGSTR_LONGLONG) -add_executable(propsys_winetest propstore.c propsys.c testlist.c) +remove_definitions(-D__ROS_LONG64__) +add_executable(propsys_winetest propsys.c testlist.c) set_module_type(propsys_winetest win32cui) add_importlibs(propsys_winetest propsys ole32 oleaut32 msvcrt kernel32) diff --git a/modules/rostests/winetests/propsys/propstore.c b/modules/rostests/winetests/propsys/propstore.c deleted file mode 100644 index 5aeb562cf27e7..0000000000000 --- a/modules/rostests/winetests/propsys/propstore.c +++ /dev/null @@ -1,374 +0,0 @@ -/* - * Unit tests for IPropertyStore and related interfaces - * - * Copyright 2012 Vincent Povirk - * - * 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 - */ - -#define COBJMACROS - -#include -#include - -#define NONAMELESSUNION - -#include "windef.h" -#include "winbase.h" -#include "objbase.h" -#include "propsys.h" -#include "wine/test.h" - -#include "initguid.h" - -DEFINE_GUID(PKEY_WineTest, 0x7b317433, 0xdfa3, 0x4c44, 0xad, 0x3e, 0x2f, 0x80, 0x4b, 0x90, 0xdb, 0xf4); -DEFINE_GUID(DUMMY_GUID1, 0x12345678, 0x1234,0x1234, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19); - -#define EXPECT_REF(obj,ref) _expect_ref((IUnknown *)obj, ref, __LINE__) -static void _expect_ref(IUnknown *obj, ULONG ref, int line) -{ - ULONG rc; - IUnknown_AddRef(obj); - rc = IUnknown_Release(obj); - ok_(__FILE__,line)(rc == ref, "expected refcount %d, got %d\n", ref, rc); -} - -static void test_inmemorystore(void) -{ - IPropertyStoreCache *propcache; - HRESULT hr; - PROPERTYKEY pkey; - PROPVARIANT propvar; - DWORD count; - PSC_STATE state; - - hr = CoCreateInstance(&CLSID_InMemoryPropertyStore, NULL, CLSCTX_INPROC_SERVER, - &IID_IPropertyStoreCache, (void**)&propcache); - ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); - - if (FAILED(hr)) - { - skip("CLSID_InMemoryPropertyStore not supported\n"); - return; - } - - hr = IPropertyStoreCache_GetCount(propcache, NULL); - ok(hr == E_POINTER, "GetCount failed, hr=%x\n", hr); - - hr = IPropertyStoreCache_GetCount(propcache, &count); - ok(hr == S_OK, "GetCount failed, hr=%x\n", hr); - ok(count == 0, "GetCount returned %i, expected 0\n", count); - - hr = IPropertyStoreCache_Commit(propcache); - ok(hr == S_OK, "Commit failed, hr=%x\n", hr); - - hr = IPropertyStoreCache_Commit(propcache); - ok(hr == S_OK, "Commit failed, hr=%x\n", hr); - - hr = IPropertyStoreCache_GetAt(propcache, 0, &pkey); - ok(hr == E_INVALIDARG, "GetAt failed, hr=%x\n", hr); - - pkey.fmtid = PKEY_WineTest; - pkey.pid = 4; - - memset(&propvar, 0, sizeof(propvar)); - propvar.vt = VT_I4; - propvar.u.lVal = 12345; - - if (0) - { - /* Crashes on Windows 7 */ - hr = IPropertyStoreCache_SetValue(propcache, NULL, &propvar); - ok(hr == E_POINTER, "SetValue failed, hr=%x\n", hr); - - hr = IPropertyStoreCache_SetValue(propcache, &pkey, NULL); - ok(hr == E_POINTER, "SetValue failed, hr=%x\n", hr); - } - - hr = IPropertyStoreCache_SetValue(propcache, &pkey, &propvar); - ok(hr == S_OK, "SetValue failed, hr=%x\n", hr); - - hr = IPropertyStoreCache_GetCount(propcache, &count); - ok(hr == S_OK, "GetCount failed, hr=%x\n", hr); - ok(count == 1, "GetCount returned %i, expected 0\n", count); - - memset(&pkey, 0, sizeof(pkey)); - - hr = IPropertyStoreCache_GetAt(propcache, 0, &pkey); - ok(hr == S_OK, "GetAt failed, hr=%x\n", hr); - ok(IsEqualGUID(&pkey.fmtid, &PKEY_WineTest), "got wrong pkey\n"); - ok(pkey.pid == 4, "got pid of %i, expected 4\n", pkey.pid); - - pkey.fmtid = PKEY_WineTest; - pkey.pid = 4; - - memset(&propvar, 0, sizeof(propvar)); - - if (0) - { - /* Crashes on Windows 7 */ - hr = IPropertyStoreCache_GetValue(propcache, NULL, &propvar); - ok(hr == E_POINTER, "GetValue failed, hr=%x\n", hr); - } - - hr = IPropertyStoreCache_GetValue(propcache, &pkey, NULL); - ok(hr == E_POINTER, "GetValue failed, hr=%x\n", hr); - - hr = IPropertyStoreCache_GetValue(propcache, &pkey, &propvar); - ok(hr == S_OK, "GetValue failed, hr=%x\n", hr); - ok(propvar.vt == VT_I4, "expected VT_I4, got %d\n", propvar.vt); - ok(propvar.u.lVal == 12345, "expected 12345, got %d\n", propvar.u.lVal); - - pkey.fmtid = PKEY_WineTest; - pkey.pid = 10; - - /* Get information for field that isn't set yet */ - propvar.vt = VT_I2; - hr = IPropertyStoreCache_GetValue(propcache, &pkey, &propvar); - ok(hr == S_OK, "GetValue failed, hr=%x\n", hr); - ok(propvar.vt == VT_EMPTY, "expected VT_EMPTY, got %d\n", propvar.vt); - - state = 0xdeadbeef; - hr = IPropertyStoreCache_GetState(propcache, &pkey, &state); - ok(hr == TYPE_E_ELEMENTNOTFOUND, "GetState failed, hr=%x\n", hr); - ok(state == PSC_NORMAL, "expected PSC_NORMAL, got %d\n", state); - - propvar.vt = VT_I2; - state = 0xdeadbeef; - hr = IPropertyStoreCache_GetValueAndState(propcache, &pkey, &propvar, &state); - ok(hr == TYPE_E_ELEMENTNOTFOUND, "GetValueAndState failed, hr=%x\n", hr); - ok(propvar.vt == VT_EMPTY, "expected VT_EMPTY, got %d\n", propvar.vt); - ok(state == PSC_NORMAL, "expected PSC_NORMAL, got %d\n", state); - - /* Set state on an unset field */ - hr = IPropertyStoreCache_SetState(propcache, &pkey, PSC_NORMAL); - ok(hr == TYPE_E_ELEMENTNOTFOUND, "SetState failed, hr=%x\n", hr); - - /* Manipulate state on already set field */ - pkey.fmtid = PKEY_WineTest; - pkey.pid = 4; - - state = 0xdeadbeef; - hr = IPropertyStoreCache_GetState(propcache, &pkey, &state); - ok(hr == S_OK, "GetState failed, hr=%x\n", hr); - ok(state == PSC_NORMAL, "expected PSC_NORMAL, got %d\n", state); - - hr = IPropertyStoreCache_SetState(propcache, &pkey, 10); - ok(hr == S_OK, "SetState failed, hr=%x\n", hr); - - state = 0xdeadbeef; - hr = IPropertyStoreCache_GetState(propcache, &pkey, &state); - ok(hr == S_OK, "GetState failed, hr=%x\n", hr); - ok(state == 10, "expected 10, got %d\n", state); - - propvar.vt = VT_I4; - propvar.u.lVal = 12346; - hr = IPropertyStoreCache_SetValueAndState(propcache, &pkey, &propvar, 5); - ok(hr == S_OK, "SetValueAndState failed, hr=%x\n", hr); - - memset(&propvar, 0, sizeof(propvar)); - state = 0xdeadbeef; - hr = IPropertyStoreCache_GetValueAndState(propcache, &pkey, &propvar, &state); - ok(hr == S_OK, "GetValueAndState failed, hr=%x\n", hr); - ok(propvar.vt == VT_I4, "expected VT_I4, got %d\n", propvar.vt); - ok(propvar.u.lVal == 12346, "expected 12346, got %d\n", propvar.vt); - ok(state == 5, "expected 5, got %d\n", state); - - /* Set new field with state */ - pkey.fmtid = PKEY_WineTest; - pkey.pid = 8; - - propvar.vt = VT_I4; - propvar.u.lVal = 12347; - hr = IPropertyStoreCache_SetValueAndState(propcache, &pkey, &propvar, PSC_DIRTY); - ok(hr == S_OK, "SetValueAndState failed, hr=%x\n", hr); - - memset(&propvar, 0, sizeof(propvar)); - state = 0xdeadbeef; - hr = IPropertyStoreCache_GetValueAndState(propcache, &pkey, &propvar, &state); - ok(hr == S_OK, "GetValueAndState failed, hr=%x\n", hr); - ok(propvar.vt == VT_I4, "expected VT_I4, got %d\n", propvar.vt); - ok(propvar.u.lVal == 12347, "expected 12347, got %d\n", propvar.vt); - ok(state == PSC_DIRTY, "expected PSC_DIRTY, got %d\n", state); - - IPropertyStoreCache_Release(propcache); -} - -static void test_persistserialized(void) -{ - IPropertyStore *propstore; - IPersistSerializedPropStorage *serialized; - HRESULT hr; - SERIALIZEDPROPSTORAGE *result; - DWORD result_size; - - hr = CoCreateInstance(&CLSID_InMemoryPropertyStore, NULL, CLSCTX_INPROC_SERVER, - &IID_IPropertyStore, (void**)&propstore); - ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); - - hr = IPropertyStore_QueryInterface(propstore, &IID_IPersistSerializedPropStorage, - (void**)&serialized); - todo_wine ok(hr == S_OK, "QueryInterface failed, hr=%x\n", hr); - - if (FAILED(hr)) - { - IPropertyStore_Release(propstore); - skip("IPersistSerializedPropStorage not supported\n"); - return; - } - - hr = IPersistSerializedPropStorage_GetPropertyStorage(serialized, NULL, &result_size); - ok(hr == E_POINTER, "GetPropertyStorage failed, hr=%x\n", hr); - - hr = IPersistSerializedPropStorage_GetPropertyStorage(serialized, &result, NULL); - ok(hr == E_POINTER, "GetPropertyStorage failed, hr=%x\n", hr); - - hr = IPersistSerializedPropStorage_GetPropertyStorage(serialized, &result, &result_size); - ok(hr == S_OK, "GetPropertyStorage failed, hr=%x\n", hr); - - if (SUCCEEDED(hr)) - { - ok(result_size == 0, "expected 0 bytes, got %i\n", result_size); - - CoTaskMemFree(result); - } - - hr = IPersistSerializedPropStorage_SetPropertyStorage(serialized, NULL, 4); - ok(hr == E_POINTER, "SetPropertyStorage failed, hr=%x\n", hr); - - hr = IPersistSerializedPropStorage_SetPropertyStorage(serialized, NULL, 0); - ok(hr == S_OK, "SetPropertyStorage failed, hr=%x\n", hr); - - hr = IPropertyStore_GetCount(propstore, &result_size); - ok(hr == S_OK, "GetCount failed, hr=%x\n", hr); - ok(result_size == 0, "expecting 0, got %d\n", result_size); - - IPropertyStore_Release(propstore); - IPersistSerializedPropStorage_Release(serialized); -} - -static void test_PSCreateMemoryPropertyStore(void) -{ - IPropertyStore *propstore, *propstore1; - IPersistSerializedPropStorage *serialized; - IPropertyStoreCache *propstorecache; - HRESULT hr; - - /* PSCreateMemoryPropertyStore(&IID_IPropertyStore, NULL); crashes */ - - hr = PSCreateMemoryPropertyStore(&IID_IPropertyStore, (void **)&propstore); - ok(hr == S_OK, "PSCreateMemoryPropertyStore failed: 0x%08x.\n", hr); - ok(propstore != NULL, "got %p.\n", propstore); - EXPECT_REF(propstore, 1); - - hr = PSCreateMemoryPropertyStore(&IID_IPersistSerializedPropStorage, (void **)&serialized); - todo_wine ok(hr == S_OK, "PSCreateMemoryPropertyStore failed: 0x%08x.\n", hr); - todo_wine ok(serialized != NULL, "got %p.\n", serialized); - EXPECT_REF(propstore, 1); - if(serialized) - { - EXPECT_REF(serialized, 1); - IPersistSerializedPropStorage_Release(serialized); - } - - hr = PSCreateMemoryPropertyStore(&IID_IPropertyStoreCache, (void **)&propstorecache); - ok(hr == S_OK, "PSCreateMemoryPropertyStore failed: 0x%08x.\n", hr); - ok(propstorecache != NULL, "got %p.\n", propstore); - ok(propstorecache != (IPropertyStoreCache *)propstore, "pointer are equal: %p, %p.\n", propstorecache, propstore); - EXPECT_REF(propstore, 1); - EXPECT_REF(propstorecache, 1); - - hr = PSCreateMemoryPropertyStore(&IID_IPropertyStore, (void **)&propstore1); - ok(hr == S_OK, "PSCreateMemoryPropertyStore failed: 0x%08x.\n", hr); - ok(propstore1 != NULL, "got %p.\n", propstore); - ok(propstore1 != propstore, "pointer are equal: %p, %p.\n", propstore1, propstore); - EXPECT_REF(propstore, 1); - EXPECT_REF(propstore1, 1); - EXPECT_REF(propstorecache, 1); - - IPropertyStore_Release(propstore1); - IPropertyStore_Release(propstore); - IPropertyStoreCache_Release(propstorecache); -} - -static void test_propertystore(void) -{ - IPropertyStore *propstore; - HRESULT hr; - PROPVARIANT propvar, ret_propvar; - PROPERTYKEY propkey; - DWORD count = 0; - - hr = PSCreateMemoryPropertyStore(&IID_IPropertyStore, (void **)&propstore); - ok(hr == S_OK, "PSCreateMemoryPropertyStore failed: 0x%08x.\n", hr); - ok(propstore != NULL, "got %p.\n", propstore); - - hr = IPropertyStore_GetCount(propstore, &count); - ok(hr == S_OK, "IPropertyStore_GetCount failed: 0x%08x.\n", hr); - ok(!count, "got wrong property count: %d, expected 0.\n", count); - - PropVariantInit(&propvar); - propvar.vt = VT_I4; - U(propvar).lVal = 123; - propkey.fmtid = DUMMY_GUID1; - propkey.pid = PID_FIRST_USABLE; - hr = IPropertyStore_SetValue(propstore, &propkey, &propvar); - ok(hr == S_OK, "IPropertyStore_SetValue failed: 0x%08x.\n", hr); - hr = IPropertyStore_Commit(propstore); - ok(hr == S_OK, "IPropertyStore_Commit failed: 0x%08x.\n", hr); - hr = IPropertyStore_GetCount(propstore, &count); - ok(hr == S_OK, "IPropertyStore_GetCount failed: 0x%08x.\n", hr); - ok(count == 1, "got wrong property count: %d, expected 1.\n", count); - PropVariantInit(&ret_propvar); - ret_propvar.vt = VT_I4; - hr = IPropertyStore_GetValue(propstore, &propkey, &ret_propvar); - ok(hr == S_OK, "IPropertyStore_GetValue failed: 0x%08x.\n", hr); - ok(ret_propvar.vt == VT_I4, "got wrong property type: %x.\n", ret_propvar.vt); - ok(U(ret_propvar).lVal == 123, "got wrong value: %d, expected 123.\n", U(ret_propvar).lVal); - PropVariantClear(&propvar); - PropVariantClear(&ret_propvar); - - PropVariantInit(&propvar); - propkey.fmtid = DUMMY_GUID1; - propkey.pid = PID_FIRST_USABLE; - hr = IPropertyStore_SetValue(propstore, &propkey, &propvar); - ok(hr == S_OK, "IPropertyStore_SetValue failed: 0x%08x.\n", hr); - hr = IPropertyStore_Commit(propstore); - ok(hr == S_OK, "IPropertyStore_Commit failed: 0x%08x.\n", hr); - hr = IPropertyStore_GetCount(propstore, &count); - ok(hr == S_OK, "IPropertyStore_GetCount failed: 0x%08x.\n", hr); - ok(count == 1, "got wrong property count: %d, expected 1.\n", count); - PropVariantInit(&ret_propvar); - hr = IPropertyStore_GetValue(propstore, &propkey, &ret_propvar); - ok(hr == S_OK, "IPropertyStore_GetValue failed: 0x%08x.\n", hr); - ok(ret_propvar.vt == VT_EMPTY, "got wrong property type: %x.\n", ret_propvar.vt); - ok(!U(ret_propvar).lVal, "got wrong value: %d, expected 0.\n", U(ret_propvar).lVal); - PropVariantClear(&propvar); - PropVariantClear(&ret_propvar); - - IPropertyStore_Release(propstore); -} - -START_TEST(propstore) -{ - CoInitialize(NULL); - - test_inmemorystore(); - test_persistserialized(); - test_PSCreateMemoryPropertyStore(); - test_propertystore(); - - CoUninitialize(); -} diff --git a/modules/rostests/winetests/propsys/propsys.c b/modules/rostests/winetests/propsys/propsys.c index 77ffe05f6d98e..d63b9ddd3b2b3 100644 --- a/modules/rostests/winetests/propsys/propsys.c +++ b/modules/rostests/winetests/propsys/propsys.c @@ -3,6 +3,7 @@ * * Copyright 2006 Paul Vriens * Copyright 2010 Andrew Nguyen + * Copyright 2012 Vincent Povirk * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,12 +25,10 @@ #include #include -#define NONAMELESSUNION - #include "windef.h" #include "winbase.h" -#include "objbase.h" #include "initguid.h" +#include "objbase.h" #include "propsys.h" #include "propvarutil.h" #include "strsafe.h" @@ -38,18 +37,23 @@ DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); DEFINE_GUID(dummy_guid, 0xdeadbeef, 0xdead, 0xbeef, 0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0xba, 0xbe); DEFINE_GUID(expect_guid, 0x12345678, 0x1234, 0x1234, 0x12, 0x34, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12); +DEFINE_GUID(PKEY_WineTest, 0x7b317433, 0xdfa3, 0x4c44, 0xad, 0x3e, 0x2f, 0x80, 0x4b, 0x90, 0xdb, 0xf4); +DEFINE_GUID(DUMMY_GUID1, 0x12345678, 0x1234,0x1234, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19); #define GUID_MEMBERS(g) {(g).Data1, (g).Data2, (g).Data3, {(g).Data4[0], (g).Data4[1], (g).Data4[2], (g).Data4[3], (g).Data4[4], (g).Data4[5], (g).Data4[6], (g).Data4[7]}} static const char topic[] = "wine topic"; static const WCHAR topicW[] = {'w','i','n','e',' ','t','o','p','i','c',0}; static const WCHAR emptyW[] = {0}; +static const WCHAR dummy_guid_str[] = L"{DEADBEEF-DEAD-BEEF-DEAD-BEEFCAFEBABE}"; -static int strcmp_wa(LPCWSTR strw, const char *stra) +#define EXPECT_REF(obj,ref) _expect_ref((IUnknown *)obj, ref, __LINE__) +static void _expect_ref(IUnknown *obj, ULONG ref, int line) { - CHAR buf[512]; - WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), NULL, NULL); - return lstrcmpA(stra, buf); + ULONG rc; + IUnknown_AddRef(obj); + rc = IUnknown_Release(obj); + ok_(__FILE__,line)(rc == ref, "expected refcount %ld, got %ld\n", ref, rc); } static void test_PSStringFromPropertyKey(void) @@ -144,7 +148,7 @@ static void test_PSStringFromPropertyKey(void) testcases[i].cch); ok(ret == testcases[i].hr_expect || broken(testcases[i].hr_broken && ret == testcases[i].hr2), /* Vista/Win2k8 */ - "[%d] Expected PSStringFromPropertyKey to return 0x%08x, got 0x%08x\n", + "[%d] Expected PSStringFromPropertyKey to return 0x%08lx, got 0x%08lx\n", i, testcases[i].hr_expect, ret); if (testcases[i].psz) @@ -334,6 +338,9 @@ static void test_PSPropertyKeyFromString(void) static const WCHAR fmtid_normalpidW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-', '1','2','3','4','-','1','2','3','4','-', '1','2','3','4','5','6','7','8','9','0','1','2','}',' ','1','3','5','7','9',0}; + static const WCHAR fmtid_udigitW[] = {'{','1','2','3','4','5','6','7','8','-','1','2','3','4','-', + '1','2','3','4','-','1','2','3','4','-', + '1','2','3','4','5','6','7','8','9','0','1','2','}',' ','1','2','3',0x661,'5','7','9',0}; PROPERTYKEY out_init = {GUID_MEMBERS(dummy_guid), 0xdeadbeef}; PROPERTYKEY out; HRESULT ret; @@ -410,6 +417,7 @@ static void test_PSPropertyKeyFromString(void) {fmtid_commanegspcpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 0U}}, {fmtid_negcommapidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 0}}, {fmtid_normalpidW, &out, S_OK, {GUID_MEMBERS(expect_guid), 13579}}, + {fmtid_udigitW, &out, S_OK, {GUID_MEMBERS(expect_guid), 123}}, }; int i; @@ -421,7 +429,7 @@ static void test_PSPropertyKeyFromString(void) ret = PSPropertyKeyFromString(testcases[i].pwzString, testcases[i].pkey); ok(ret == testcases[i].hr_expect, - "[%d] Expected PSPropertyKeyFromString to return 0x%08x, got 0x%08x\n", + "[%d] Expected PSPropertyKeyFromString to return 0x%08lx, got 0x%08lx\n", i, testcases[i].hr_expect, ret); if (testcases[i].pkey) @@ -430,7 +438,7 @@ static void test_PSPropertyKeyFromString(void) "[%d] Expected GUID %s, got %s\n", i, wine_dbgstr_guid(&testcases[i].pkey_expect.fmtid), wine_dbgstr_guid(&testcases[i].pkey->fmtid)); ok(testcases[i].pkey->pid == testcases[i].pkey_expect.pid, - "[%d] Expected property ID %u, got %u\n", + "[%d] Expected property ID %lu, got %lu\n", i, testcases[i].pkey_expect.pid, testcases[i].pkey->pid); } } @@ -443,13 +451,13 @@ static void test_PSRefreshPropertySchema(void) ret = PSRefreshPropertySchema(); todo_wine ok(ret == CO_E_NOTINITIALIZED, - "Expected PSRefreshPropertySchema to return CO_E_NOTINITIALIZED, got 0x%08x\n", ret); + "Expected PSRefreshPropertySchema to return CO_E_NOTINITIALIZED, got 0x%08lx\n", ret); CoInitialize(NULL); ret = PSRefreshPropertySchema(); ok(ret == S_OK, - "Expected PSRefreshPropertySchema to return S_OK, got 0x%08x\n", ret); + "Expected PSRefreshPropertySchema to return S_OK, got 0x%08lx\n", ret); CoUninitialize(); } @@ -463,14 +471,14 @@ static void test_InitPropVariantFromGUIDAsString(void) const struct { REFGUID guid; - const char *str; + const WCHAR *str; } testcases[] = { - {&IID_NULL, "{00000000-0000-0000-0000-000000000000}" }, - {&dummy_guid, "{DEADBEEF-DEAD-BEEF-DEAD-BEEFCAFEBABE}" }, + {&IID_NULL, L"{00000000-0000-0000-0000-000000000000}" }, + {&dummy_guid, dummy_guid_str }, }; hres = InitPropVariantFromGUIDAsString(NULL, &propvar); - ok(hres == E_FAIL, "InitPropVariantFromGUIDAsString returned %x\n", hres); + ok(hres == E_FAIL, "InitPropVariantFromGUIDAsString returned %lx\n", hres); if(0) { /* Returns strange data on Win7, crashes on older systems */ @@ -484,19 +492,19 @@ static void test_InitPropVariantFromGUIDAsString(void) for(i=0; i < ARRAY_SIZE(testcases); i++) { memset(&propvar, 0, sizeof(PROPVARIANT)); hres = InitPropVariantFromGUIDAsString(testcases[i].guid, &propvar); - ok(hres == S_OK, "%d) InitPropVariantFromGUIDAsString returned %x\n", i, hres); + ok(hres == S_OK, "%d) InitPropVariantFromGUIDAsString returned %lx\n", i, hres); ok(propvar.vt == VT_LPWSTR, "%d) propvar.vt = %d\n", i, propvar.vt); - ok(!strcmp_wa(propvar.u.pwszVal, testcases[i].str), "%d) propvar.u.pwszVal = %s\n", - i, wine_dbgstr_w(propvar.u.pwszVal)); - CoTaskMemFree(propvar.u.pwszVal); + ok(!lstrcmpW(propvar.pwszVal, testcases[i].str), "%d) propvar.pwszVal = %s\n", + i, wine_dbgstr_w(propvar.pwszVal)); + CoTaskMemFree(propvar.pwszVal); memset(&var, 0, sizeof(VARIANT)); hres = InitVariantFromGUIDAsString(testcases[i].guid, &var); - ok(hres == S_OK, "%d) InitVariantFromGUIDAsString returned %x\n", i, hres); + ok(hres == S_OK, "%d) InitVariantFromGUIDAsString returned %lx\n", i, hres); ok(V_VT(&var) == VT_BSTR, "%d) V_VT(&var) = %d\n", i, V_VT(&var)); ok(SysStringLen(V_BSTR(&var)) == 38, "SysStringLen returned %d\n", SysStringLen(V_BSTR(&var))); - ok(!strcmp_wa(V_BSTR(&var), testcases[i].str), "%d) V_BSTR(&var) = %s\n", + ok(!lstrcmpW(V_BSTR(&var), testcases[i].str), "%d) V_BSTR(&var) = %s\n", i, wine_dbgstr_w(V_BSTR(&var))); VariantClear(&var); } @@ -512,47 +520,47 @@ static void test_InitPropVariantFromBuffer(void) LONG size; hres = InitPropVariantFromBuffer(NULL, 0, &propvar); - ok(hres == S_OK, "InitPropVariantFromBuffer returned %x\n", hres); + ok(hres == S_OK, "InitPropVariantFromBuffer returned %lx\n", hres); ok(propvar.vt == (VT_VECTOR|VT_UI1), "propvar.vt = %d\n", propvar.vt); - ok(propvar.u.caub.cElems == 0, "cElems = %d\n", propvar.u.caub.cElems == 0); + ok(propvar.caub.cElems == 0, "cElems = %d\n", propvar.caub.cElems == 0); PropVariantClear(&propvar); hres = InitPropVariantFromBuffer(data_in, 4, &propvar); - ok(hres == S_OK, "InitPropVariantFromBuffer returned %x\n", hres); + ok(hres == S_OK, "InitPropVariantFromBuffer returned %lx\n", hres); ok(propvar.vt == (VT_VECTOR|VT_UI1), "propvar.vt = %d\n", propvar.vt); - ok(propvar.u.caub.cElems == 4, "cElems = %d\n", propvar.u.caub.cElems == 0); - ok(!memcmp(propvar.u.caub.pElems, data_in, 4), "Data inside array is incorrect\n"); + ok(propvar.caub.cElems == 4, "cElems = %d\n", propvar.caub.cElems == 0); + ok(!memcmp(propvar.caub.pElems, data_in, 4), "Data inside array is incorrect\n"); PropVariantClear(&propvar); hres = InitVariantFromBuffer(NULL, 0, &var); - ok(hres == S_OK, "InitVariantFromBuffer returned %x\n", hres); + ok(hres == S_OK, "InitVariantFromBuffer returned %lx\n", hres); ok(V_VT(&var) == (VT_ARRAY|VT_UI1), "V_VT(&var) = %d\n", V_VT(&var)); size = SafeArrayGetDim(V_ARRAY(&var)); - ok(size == 1, "SafeArrayGetDim returned %d\n", size); + ok(size == 1, "SafeArrayGetDim returned %ld\n", size); hres = SafeArrayGetLBound(V_ARRAY(&var), 1, &size); - ok(hres == S_OK, "SafeArrayGetLBound returned %x\n", hres); - ok(size == 0, "LBound = %d\n", size); + ok(hres == S_OK, "SafeArrayGetLBound returned %lx\n", hres); + ok(size == 0, "LBound = %ld\n", size); hres = SafeArrayGetUBound(V_ARRAY(&var), 1, &size); - ok(hres == S_OK, "SafeArrayGetUBound returned %x\n", hres); - ok(size == -1, "UBound = %d\n", size); + ok(hres == S_OK, "SafeArrayGetUBound returned %lx\n", hres); + ok(size == -1, "UBound = %ld\n", size); VariantClear(&var); hres = InitVariantFromBuffer(data_in, 4, &var); - ok(hres == S_OK, "InitVariantFromBuffer returned %x\n", hres); + ok(hres == S_OK, "InitVariantFromBuffer returned %lx\n", hres); ok(V_VT(&var) == (VT_ARRAY|VT_UI1), "V_VT(&var) = %d\n", V_VT(&var)); size = SafeArrayGetDim(V_ARRAY(&var)); - ok(size == 1, "SafeArrayGetDim returned %d\n", size); + ok(size == 1, "SafeArrayGetDim returned %ld\n", size); hres = SafeArrayGetLBound(V_ARRAY(&var), 1, &size); - ok(hres == S_OK, "SafeArrayGetLBound returned %x\n", hres); - ok(size == 0, "LBound = %d\n", size); + ok(hres == S_OK, "SafeArrayGetLBound returned %lx\n", hres); + ok(size == 0, "LBound = %ld\n", size); hres = SafeArrayGetUBound(V_ARRAY(&var), 1, &size); - ok(hres == S_OK, "SafeArrayGetUBound returned %x\n", hres); - ok(size == 3, "UBound = %d\n", size); + ok(hres == S_OK, "SafeArrayGetUBound returned %lx\n", hres); + ok(size == 3, "UBound = %ld\n", size); hres = SafeArrayAccessData(V_ARRAY(&var), &data_out); - ok(hres == S_OK, "SafeArrayAccessData failed %x\n", hres); + ok(hres == S_OK, "SafeArrayAccessData failed %lx\n", hres); ok(!memcmp(data_in, data_out, 4), "Data inside safe array is incorrect\n"); hres = SafeArrayUnaccessData(V_ARRAY(&var)); - ok(hres == S_OK, "SafeArrayUnaccessData failed %x\n", hres); + ok(hres == S_OK, "SafeArrayUnaccessData failed %lx\n", hres); VariantClear(&var); } @@ -564,67 +572,67 @@ static void test_PropVariantToGUID(void) HRESULT hres; hres = InitPropVariantFromGUIDAsString(&IID_NULL, &propvar); - ok(hres == S_OK, "InitPropVariantFromGUIDAsString failed %x\n", hres); + ok(hres == S_OK, "InitPropVariantFromGUIDAsString failed %lx\n", hres); hres = PropVariantToGUID(&propvar, &guid); - ok(hres == S_OK, "PropVariantToGUID failed %x\n", hres); + ok(hres == S_OK, "PropVariantToGUID failed %lx\n", hres); ok(IsEqualGUID(&IID_NULL, &guid), "incorrect GUID created: %s\n", wine_dbgstr_guid(&guid)); PropVariantClear(&propvar); hres = InitPropVariantFromGUIDAsString(&dummy_guid, &propvar); - ok(hres == S_OK, "InitPropVariantFromGUIDAsString failed %x\n", hres); + ok(hres == S_OK, "InitPropVariantFromGUIDAsString failed %lx\n", hres); hres = PropVariantToGUID(&propvar, &guid); - ok(hres == S_OK, "PropVariantToGUID failed %x\n", hres); + ok(hres == S_OK, "PropVariantToGUID failed %lx\n", hres); ok(IsEqualGUID(&dummy_guid, &guid), "incorrect GUID created: %s\n", wine_dbgstr_guid(&guid)); ok(propvar.vt == VT_LPWSTR, "incorrect PROPVARIANT type: %d\n", propvar.vt); - propvar.u.pwszVal[1] = 'd'; - propvar.u.pwszVal[2] = 'E'; - propvar.u.pwszVal[3] = 'a'; + propvar.pwszVal[1] = 'd'; + propvar.pwszVal[2] = 'E'; + propvar.pwszVal[3] = 'a'; hres = PropVariantToGUID(&propvar, &guid); - ok(hres == S_OK, "PropVariantToGUID failed %x\n", hres); + ok(hres == S_OK, "PropVariantToGUID failed %lx\n", hres); ok(IsEqualGUID(&dummy_guid, &guid), "incorrect GUID created: %s\n", wine_dbgstr_guid(&guid)); - propvar.u.pwszVal[1] = 'z'; + propvar.pwszVal[1] = 'z'; hres = PropVariantToGUID(&propvar, &guid); - ok(hres == E_INVALIDARG, "PropVariantToGUID returned %x\n", hres); + ok(hres == E_INVALIDARG, "PropVariantToGUID returned %lx\n", hres); PropVariantClear(&propvar); hres = InitVariantFromGUIDAsString(&IID_NULL, &var); - ok(hres == S_OK, "InitVariantFromGUIDAsString failed %x\n", hres); + ok(hres == S_OK, "InitVariantFromGUIDAsString failed %lx\n", hres); hres = VariantToGUID(&var, &guid); - ok(hres == S_OK, "VariantToGUID failed %x\n", hres); + ok(hres == S_OK, "VariantToGUID failed %lx\n", hres); ok(IsEqualGUID(&IID_NULL, &guid), "incorrect GUID created: %s\n", wine_dbgstr_guid(&guid)); VariantClear(&var); hres = InitVariantFromGUIDAsString(&dummy_guid, &var); - ok(hres == S_OK, "InitVariantFromGUIDAsString failed %x\n", hres); + ok(hres == S_OK, "InitVariantFromGUIDAsString failed %lx\n", hres); hres = VariantToGUID(&var, &guid); - ok(hres == S_OK, "VariantToGUID failed %x\n", hres); + ok(hres == S_OK, "VariantToGUID failed %lx\n", hres); ok(IsEqualGUID(&dummy_guid, &guid), "incorrect GUID created: %s\n", wine_dbgstr_guid(&guid)); ok(V_VT(&var) == VT_BSTR, "incorrect VARIANT type: %d\n", V_VT(&var)); V_BSTR(&var)[1] = 'z'; hres = VariantToGUID(&var, &guid); - ok(hres == E_FAIL, "VariantToGUID returned %x\n", hres); + ok(hres == E_FAIL, "VariantToGUID returned %lx\n", hres); V_BSTR(&var)[1] = 'd'; propvar.vt = V_VT(&var); - propvar.u.bstrVal = V_BSTR(&var); + propvar.bstrVal = V_BSTR(&var); V_VT(&var) = VT_EMPTY; hres = PropVariantToGUID(&propvar, &guid); - ok(hres == S_OK, "PropVariantToGUID failed %x\n", hres); + ok(hres == S_OK, "PropVariantToGUID failed %lx\n", hres); ok(IsEqualGUID(&dummy_guid, &guid), "incorrect GUID created: %s\n", wine_dbgstr_guid(&guid)); PropVariantClear(&propvar); memset(&guid, 0, sizeof(guid)); InitPropVariantFromCLSID(&dummy_guid, &propvar); hres = PropVariantToGUID(&propvar, &guid); - ok(hres == S_OK, "PropVariantToGUID failed %x\n", hres); + ok(hres == S_OK, "PropVariantToGUID failed %lx\n", hres); ok(IsEqualGUID(&dummy_guid, &guid), "incorrect GUID created: %s\n", wine_dbgstr_guid(&guid)); PropVariantClear(&propvar); } @@ -637,35 +645,46 @@ static void test_PropVariantToStringAlloc(void) prop.vt = VT_NULL; hres = PropVariantToStringAlloc(&prop, &str); - ok(hres == S_OK, "returned %x\n", hres); + ok(hres == S_OK, "returned %lx\n", hres); ok(!lstrcmpW(str, emptyW), "got %s\n", wine_dbgstr_w(str)); CoTaskMemFree(str); prop.vt = VT_LPSTR; - prop.u.pszVal = CoTaskMemAlloc(strlen(topic)+1); - strcpy(prop.u.pszVal, topic); + prop.pszVal = CoTaskMemAlloc(strlen(topic)+1); + strcpy(prop.pszVal, topic); hres = PropVariantToStringAlloc(&prop, &str); - ok(hres == S_OK, "returned %x\n", hres); + ok(hres == S_OK, "returned %lx\n", hres); ok(!lstrcmpW(str, topicW), "got %s\n", wine_dbgstr_w(str)); CoTaskMemFree(str); PropVariantClear(&prop); prop.vt = VT_EMPTY; hres = PropVariantToStringAlloc(&prop, &str); - ok(hres == S_OK, "returned %x\n", hres); + ok(hres == S_OK, "returned %lx\n", hres); ok(!lstrcmpW(str, emptyW), "got %s\n", wine_dbgstr_w(str)); CoTaskMemFree(str); + + prop.vt = VT_CLSID; + prop.puuid = (CLSID *)&dummy_guid; + hres = PropVariantToStringAlloc(&prop, &str); + ok(hres == S_OK, "PropVariantToStringAlloc returned %#lx.\n", hres); + ok(!wcscmp(str, dummy_guid_str), "Unexpected str %s.\n", debugstr_w(str)); + CoTaskMemFree(str); } -static void test_PropVariantCompare(void) +static void test_PropVariantCompareEx(void) { PROPVARIANT empty, null, emptyarray, i2_0, i2_2, i4_large, i4_largeneg, i4_2, str_2, str_02, str_b; PROPVARIANT clsid_null, clsid, clsid2, r4_0, r4_2, r8_0, r8_2; + PROPVARIANT ui4, ui4_large; + PROPVARIANT var1, var2; INT res; static const WCHAR str_2W[] = {'2', 0}; static const WCHAR str_02W[] = {'0', '2', 0}; static const WCHAR str_bW[] = {'b', 0}; SAFEARRAY emptysafearray; + unsigned char bytevector1[] = {1,2,3}; + unsigned char bytevector2[] = {4,5,6}; PropVariantInit(&empty); PropVariantInit(&null); @@ -681,7 +700,7 @@ static void test_PropVariantCompare(void) empty.vt = VT_EMPTY; null.vt = VT_NULL; emptyarray.vt = VT_ARRAY | VT_I4; - emptyarray.u.parray = &emptysafearray; + emptyarray.parray = &emptysafearray; emptysafearray.cDims = 1; emptysafearray.fFeatures = FADF_FIXEDSIZE; emptysafearray.cbElements = 4; @@ -690,35 +709,39 @@ static void test_PropVariantCompare(void) emptysafearray.rgsabound[0].cElements = 0; emptysafearray.rgsabound[0].lLbound = 0; i2_0.vt = VT_I2; - i2_0.u.iVal = 0; + i2_0.iVal = 0; i2_2.vt = VT_I2; - i2_2.u.iVal = 2; + i2_2.iVal = 2; i4_large.vt = VT_I4; - i4_large.u.lVal = 65536; + i4_large.lVal = 65536; i4_largeneg.vt = VT_I4; - i4_largeneg.u.lVal = -65536; + i4_largeneg.lVal = -65536; i4_2.vt = VT_I4; - i4_2.u.lVal = 2; + i4_2.lVal = 2; + ui4.vt = VT_UI4; + ui4.ulVal = 2; + ui4_large.vt = VT_UI4; + ui4_large.ulVal = 65536; str_2.vt = VT_BSTR; - str_2.u.bstrVal = SysAllocString(str_2W); + str_2.bstrVal = SysAllocString(str_2W); str_02.vt = VT_BSTR; - str_02.u.bstrVal = SysAllocString(str_02W); + str_02.bstrVal = SysAllocString(str_02W); str_b.vt = VT_BSTR; - str_b.u.bstrVal = SysAllocString(str_bW); + str_b.bstrVal = SysAllocString(str_bW); clsid_null.vt = VT_CLSID; - clsid_null.u.puuid = NULL; + clsid_null.puuid = NULL; clsid.vt = VT_CLSID; - clsid.u.puuid = (GUID *)&dummy_guid; + clsid.puuid = (GUID *)&dummy_guid; clsid2.vt = VT_CLSID; - clsid2.u.puuid = (GUID *)&GUID_NULL; + clsid2.puuid = (GUID *)&GUID_NULL; r4_0.vt = VT_R4; - r4_0.u.fltVal = 0.0f; + r4_0.fltVal = 0.0f; r4_2.vt = VT_R4; - r4_2.u.fltVal = 2.0f; + r4_2.fltVal = 2.0f; r8_0.vt = VT_R8; - r8_0.u.dblVal = 0.0; + r8_0.dblVal = 0.0; r8_2.vt = VT_R8; - r8_2.u.dblVal = 2.0; + r8_2.dblVal = 2.0; res = PropVariantCompareEx(&empty, &empty, 0, 0); ok(res == 0, "res=%i\n", res); @@ -747,6 +770,12 @@ static void test_PropVariantCompare(void) res = PropVariantCompareEx(&i2_0, &i2_2, 0, 0); ok(res == -1, "res=%i\n", res); + res = PropVariantCompareEx(&ui4, &ui4_large, 0, 0); + ok(res == -1, "res=%i\n", res); + + res = PropVariantCompareEx(&ui4_large, &ui4, 0, 0); + ok(res == 1, "res=%i\n", res); + /* Always return -1 if second value cannot be converted to first type */ res = PropVariantCompareEx(&i2_0, &i4_large, 0, 0); ok(res == -1, "res=%i\n", res); @@ -817,7 +846,7 @@ static void test_PropVariantCompare(void) /* VT_R4/VT_R8 */ res = PropVariantCompareEx(&r4_0, &r8_0, 0, 0); -todo_wine + todo_wine ok(res == 0, "res=%i\n", res); res = PropVariantCompareEx(&r4_0, &r4_0, 0, 0); @@ -838,9 +867,77 @@ todo_wine res = PropVariantCompareEx(&r8_2, &r8_0, 0, 0); ok(res == 1, "res=%i\n", res); - SysFreeString(str_2.u.bstrVal); - SysFreeString(str_02.u.bstrVal); - SysFreeString(str_b.u.bstrVal); + /* VT_VECTOR | VT_UI1 */ + var1.vt = VT_VECTOR | VT_UI1; + var1.caub.cElems = 1; + var1.caub.pElems = bytevector1; + var2.vt = VT_VECTOR | VT_UI1; + var2.caub.cElems = 1; + var2.caub.pElems = bytevector2; + + res = PropVariantCompareEx(&var1, &var2, 0, 0); + ok(res == -1, "res=%i\n", res); + + res = PropVariantCompareEx(&var2, &var1, 0, 0); + ok(res == 1, "res=%i\n", res); + + /* Vector length mismatch */ + var1.caub.cElems = 2; + res = PropVariantCompareEx(&var1, &var2, 0, 0); + ok(res == -1, "res=%i\n", res); + + res = PropVariantCompareEx(&var2, &var1, 0, 0); + ok(res == 1, "res=%i\n", res); + + var1.caub.pElems = bytevector2; + var2.caub.pElems = bytevector1; + res = PropVariantCompareEx(&var1, &var2, 0, 0); + ok(res == 1, "res=%i\n", res); + + var1.caub.pElems = bytevector1; + var2.caub.pElems = bytevector2; + + var1.caub.cElems = 1; + var2.caub.cElems = 2; + res = PropVariantCompareEx(&var1, &var2, 0, 0); + ok(res == -1, "res=%i\n", res); + + res = PropVariantCompareEx(&var2, &var1, 0, 0); + ok(res == 1, "res=%i\n", res); + + /* Length mismatch over same data */ + var1.caub.pElems = bytevector1; + var2.caub.pElems = bytevector1; + + res = PropVariantCompareEx(&var1, &var2, 0, 0); + ok(res == -1, "res=%i\n", res); + + res = PropVariantCompareEx(&var2, &var1, 0, 0); + ok(res == 1, "res=%i\n", res); + + var1.caub.cElems = 1; + var2.caub.cElems = 1; + res = PropVariantCompareEx(&var1, &var2, 0, 0); + ok(res == 0, "res=%i\n", res); + + var1.caub.cElems = 0; + res = PropVariantCompareEx(&var1, &var2, 0, PVCF_TREATEMPTYASGREATERTHAN); + ok(res == 1, "res=%i\n", res); + res = PropVariantCompareEx(&var2, &var1, 0, PVCF_TREATEMPTYASGREATERTHAN); + ok(res == -1, "res=%i\n", res); + + res = PropVariantCompareEx(&var1, &var2, 0, 0); + ok(res == -1, "res=%i\n", res); + res = PropVariantCompareEx(&var2, &var1, 0, 0); + ok(res == 1, "res=%i\n", res); + + var2.caub.cElems = 0; + res = PropVariantCompareEx(&var1, &var2, 0, 0); + ok(res == 0, "res=%i\n", res); + + SysFreeString(str_2.bstrVal); + SysFreeString(str_02.bstrVal); + SysFreeString(str_b.bstrVal); } static void test_intconversions(void) @@ -862,104 +959,113 @@ static void test_intconversions(void) PropVariantClear(&propvar); propvar.vt = VT_I8; - propvar.u.hVal.QuadPart = (ULONGLONG)1 << 63; + propvar.hVal.QuadPart = (ULONGLONG)1 << 63; hr = PropVariantToInt64(&propvar, &llval); - ok(hr == S_OK, "hr=%x\n", hr); + ok(hr == S_OK, "hr=%lx\n", hr); ok(llval == (ULONGLONG)1 << 63, "got wrong value %s\n", wine_dbgstr_longlong(llval)); hr = PropVariantToUInt64(&propvar, &ullval); - ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr); + ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%lx\n", hr); hr = PropVariantToInt32(&propvar, &lval); - ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr); + ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%lx\n", hr); hr = PropVariantToUInt32(&propvar, &ulval); - ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr); + ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%lx\n", hr); + + ulval = PropVariantToUInt32WithDefault(&propvar, 77); + ok(ulval == 77, "ulval=%lu\n", ulval); hr = PropVariantToInt16(&propvar, &sval); - ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr); + ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%lx\n", hr); hr = PropVariantToUInt16(&propvar, &usval); - ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr); + ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%lx\n", hr); propvar.vt = VT_UI8; - propvar.u.uhVal.QuadPart = 5; + propvar.uhVal.QuadPart = 5; hr = PropVariantToInt64(&propvar, &llval); - ok(hr == S_OK, "hr=%x\n", hr); + ok(hr == S_OK, "hr=%lx\n", hr); ok(llval == 5, "got wrong value %s\n", wine_dbgstr_longlong(llval)); hr = PropVariantToUInt64(&propvar, &ullval); - ok(hr == S_OK, "hr=%x\n", hr); + ok(hr == S_OK, "hr=%lx\n", hr); ok(ullval == 5, "got wrong value %s\n", wine_dbgstr_longlong(ullval)); hr = PropVariantToInt32(&propvar, &lval); - ok(hr == S_OK, "hr=%x\n", hr); - ok(lval == 5, "got wrong value %d\n", lval); + ok(hr == S_OK, "hr=%lx\n", hr); + ok(lval == 5, "got wrong value %ld\n", lval); hr = PropVariantToUInt32(&propvar, &ulval); - ok(hr == S_OK, "hr=%x\n", hr); - ok(ulval == 5, "got wrong value %d\n", ulval); + ok(hr == S_OK, "hr=%lx\n", hr); + ok(ulval == 5, "got wrong value %ld\n", ulval); + + ulval = PropVariantToUInt32WithDefault(&propvar, 77); + ok(ulval == 5, "got wrong value %lu\n", ulval); hr = PropVariantToInt16(&propvar, &sval); - ok(hr == S_OK, "hr=%x\n", hr); + ok(hr == S_OK, "hr=%lx\n", hr); ok(sval == 5, "got wrong value %d\n", sval); hr = PropVariantToUInt16(&propvar, &usval); - ok(hr == S_OK, "hr=%x\n", hr); + ok(hr == S_OK, "hr=%lx\n", hr); ok(usval == 5, "got wrong value %d\n", usval); propvar.vt = VT_I8; - propvar.u.hVal.QuadPart = -5; + propvar.hVal.QuadPart = -5; hr = PropVariantToInt64(&propvar, &llval); - ok(hr == S_OK, "hr=%x\n", hr); + ok(hr == S_OK, "hr=%lx\n", hr); ok(llval == -5, "got wrong value %s\n", wine_dbgstr_longlong(llval)); hr = PropVariantToUInt64(&propvar, &ullval); - ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr); + ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%lx\n", hr); hr = PropVariantToInt32(&propvar, &lval); - ok(hr == S_OK, "hr=%x\n", hr); - ok(lval == -5, "got wrong value %d\n", lval); + ok(hr == S_OK, "hr=%lx\n", hr); + ok(lval == -5, "got wrong value %ld\n", lval); hr = PropVariantToUInt32(&propvar, &ulval); - ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr); + ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%lx\n", hr); + + ulval = PropVariantToUInt32WithDefault(&propvar, 77); + ok(ulval == 77, "ulval=%lu\n", ulval); hr = PropVariantToInt16(&propvar, &sval); - ok(hr == S_OK, "hr=%x\n", hr); + ok(hr == S_OK, "hr=%lx\n", hr); ok(sval == -5, "got wrong value %d\n", sval); hr = PropVariantToUInt16(&propvar, &usval); - ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr); + ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%lx\n", hr); propvar.vt = VT_UI4; - propvar.u.ulVal = 6; + propvar.ulVal = 6; hr = PropVariantToInt64(&propvar, &llval); - ok(hr == S_OK, "hr=%x\n", hr); + ok(hr == S_OK, "hr=%lx\n", hr); ok(llval == 6, "got wrong value %s\n", wine_dbgstr_longlong(llval)); propvar.vt = VT_I4; - propvar.u.lVal = -6; + propvar.lVal = -6; hr = PropVariantToInt64(&propvar, &llval); - ok(hr == S_OK, "hr=%x\n", hr); + ok(hr == S_OK, "hr=%lx\n", hr); ok(llval == -6, "got wrong value %s\n", wine_dbgstr_longlong(llval)); propvar.vt = VT_UI2; - propvar.u.uiVal = 7; + propvar.uiVal = 7; hr = PropVariantToInt64(&propvar, &llval); - ok(hr == S_OK, "hr=%x\n", hr); + ok(hr == S_OK, "hr=%lx\n", hr); ok(llval == 7, "got wrong value %s\n", wine_dbgstr_longlong(llval)); propvar.vt = VT_I2; - propvar.u.iVal = -7; + propvar.iVal = -7; hr = PropVariantToInt64(&propvar, &llval); - ok(hr == S_OK, "hr=%x\n", hr); + ok(hr == S_OK, "hr=%lx\n", hr); ok(llval == -7, "got wrong value %s\n", wine_dbgstr_longlong(llval)); } @@ -982,195 +1088,195 @@ static void test_PropVariantToBoolean(void) /* VT_BOOL */ propvar.vt = VT_BOOL; - propvar.u.boolVal = VARIANT_FALSE; + propvar.boolVal = VARIANT_FALSE; val = TRUE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == FALSE, "Unexpected value %d\n", val); propvar.vt = VT_BOOL; - propvar.u.boolVal = 1; + propvar.boolVal = 1; val = TRUE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == FALSE, "Unexpected value %d\n", val); propvar.vt = VT_BOOL; - propvar.u.boolVal = VARIANT_TRUE; + propvar.boolVal = VARIANT_TRUE; val = FALSE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == TRUE, "Unexpected value %d\n", val); /* VT_EMPTY */ propvar.vt = VT_EMPTY; - propvar.u.boolVal = VARIANT_TRUE; + propvar.boolVal = VARIANT_TRUE; val = TRUE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == FALSE, "Unexpected value %d\n", val); /* test integer conversion */ propvar.vt = VT_I4; - propvar.u.lVal = 0; + propvar.lVal = 0; val = TRUE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == FALSE, "Unexpected value %d\n", val); propvar.vt = VT_I4; - propvar.u.lVal = 1; + propvar.lVal = 1; val = FALSE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == TRUE, "Unexpected value %d\n", val); propvar.vt = VT_I4; - propvar.u.lVal = 67; + propvar.lVal = 67; val = FALSE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == TRUE, "Unexpected value %d\n", val); propvar.vt = VT_I4; - propvar.u.lVal = -67; + propvar.lVal = -67; val = FALSE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == TRUE, "Unexpected value %d\n", val); /* test string conversion */ propvar.vt = VT_LPWSTR; - propvar.u.pwszVal = str_0; + propvar.pwszVal = str_0; val = TRUE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == FALSE, "Unexpected value %d\n", val); propvar.vt = VT_LPWSTR; - propvar.u.pwszVal = str_1; + propvar.pwszVal = str_1; val = FALSE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == TRUE, "Unexpected value %d\n", val); propvar.vt = VT_LPWSTR; - propvar.u.pwszVal = str_7; + propvar.pwszVal = str_7; val = FALSE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == TRUE, "Unexpected value %d\n", val); propvar.vt = VT_LPWSTR; - propvar.u.pwszVal = str_n7; + propvar.pwszVal = str_n7; val = FALSE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == TRUE, "Unexpected value %d\n", val); propvar.vt = VT_LPWSTR; - propvar.u.pwszVal = str_true; + propvar.pwszVal = str_true; val = FALSE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == TRUE, "Unexpected value %d\n", val); propvar.vt = VT_LPWSTR; - propvar.u.pwszVal = str_true_case; + propvar.pwszVal = str_true_case; val = FALSE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == TRUE, "Unexpected value %d\n", val); propvar.vt = VT_LPWSTR; - propvar.u.pwszVal = str_true2; + propvar.pwszVal = str_true2; val = FALSE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == TRUE, "Unexpected value %d\n", val); propvar.vt = VT_LPWSTR; - propvar.u.pwszVal = str_false; + propvar.pwszVal = str_false; val = TRUE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == FALSE, "Unexpected value %d\n", val); propvar.vt = VT_LPWSTR; - propvar.u.pwszVal = str_false2; + propvar.pwszVal = str_false2; val = TRUE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == FALSE, "Unexpected value %d\n", val); propvar.vt = VT_LPWSTR; - propvar.u.pwszVal = str_true_space; + propvar.pwszVal = str_true_space; val = TRUE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == DISP_E_TYPEMISMATCH, "Unexpected hr %#x.\n", hr); + ok(hr == DISP_E_TYPEMISMATCH, "Unexpected hr %#lx.\n", hr); ok(val == FALSE, "Unexpected value %d\n", val); propvar.vt = VT_LPWSTR; - propvar.u.pwszVal = str_yes; + propvar.pwszVal = str_yes; val = TRUE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == DISP_E_TYPEMISMATCH, "Unexpected hr %#x.\n", hr); + ok(hr == DISP_E_TYPEMISMATCH, "Unexpected hr %#lx.\n", hr); ok(val == FALSE, "Unexpected value %d\n", val); propvar.vt = VT_LPWSTR; - propvar.u.pwszVal = NULL; + propvar.pwszVal = NULL; val = TRUE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == DISP_E_TYPEMISMATCH, "Unexpected hr %#x.\n", hr); + ok(hr == DISP_E_TYPEMISMATCH, "Unexpected hr %#lx.\n", hr); ok(val == FALSE, "Unexpected value %d\n", val); /* VT_LPSTR */ propvar.vt = VT_LPSTR; - propvar.u.pszVal = (char *)"#TruE#"; + propvar.pszVal = (char *)"#TruE#"; val = TRUE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == DISP_E_TYPEMISMATCH, "Unexpected hr %#x.\n", hr); + ok(hr == DISP_E_TYPEMISMATCH, "Unexpected hr %#lx.\n", hr); ok(val == FALSE, "Unexpected value %d\n", val); propvar.vt = VT_LPSTR; - propvar.u.pszVal = (char *)"#TRUE#"; + propvar.pszVal = (char *)"#TRUE#"; val = FALSE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == TRUE, "Unexpected value %d\n", val); propvar.vt = VT_LPSTR; - propvar.u.pszVal = (char *)"tRUe"; + propvar.pszVal = (char *)"tRUe"; val = FALSE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == TRUE, "Unexpected value %d\n", val); propvar.vt = VT_LPSTR; - propvar.u.pszVal = (char *)"#FALSE#"; + propvar.pszVal = (char *)"#FALSE#"; val = TRUE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == FALSE, "Unexpected value %d\n", val); propvar.vt = VT_LPSTR; - propvar.u.pszVal = (char *)"fALSe"; + propvar.pszVal = (char *)"fALSe"; val = TRUE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == FALSE, "Unexpected value %d\n", val); propvar.vt = VT_LPSTR; - propvar.u.pszVal = (char *)"1"; + propvar.pszVal = (char *)"1"; val = FALSE; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == TRUE, "Unexpected value %d\n", val); propvar.vt = VT_LPSTR; - propvar.u.pszVal = (char *)"-1"; + propvar.pszVal = (char *)"-1"; hr = PropVariantToBoolean(&propvar, &val); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(val == TRUE, "Unexpected value %d\n", val); } @@ -1195,83 +1301,88 @@ static void test_PropVariantToStringWithDefault(void) ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); propvar.vt = VT_BOOL; - propvar.u.boolVal = VARIANT_TRUE; + propvar.boolVal = VARIANT_TRUE; result = PropVariantToStringWithDefault(&propvar, default_value); ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); propvar.vt = VT_I4; - propvar.u.lVal = 15; + propvar.lVal = 15; result = PropVariantToStringWithDefault(&propvar, default_value); ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); + propvar.vt = VT_CLSID; + propvar.puuid = (CLSID *)&dummy_guid; + result = PropVariantToStringWithDefault(&propvar, default_value); + ok(result == default_value, "Unexpected value %s.\n", debugstr_w(result)); + /* VT_LPWSTR */ propvar.vt = VT_LPWSTR; - propvar.u.pwszVal = NULL; + propvar.pwszVal = NULL; result = PropVariantToStringWithDefault(&propvar, default_value); ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); propvar.vt = VT_LPWSTR; - propvar.u.pwszVal = wstr_empty; + propvar.pwszVal = wstr_empty; result = PropVariantToStringWithDefault(&propvar, default_value); ok(result == wstr_empty, "Unexpected value %s\n", wine_dbgstr_w(result)); propvar.vt = VT_LPWSTR; - propvar.u.pwszVal = wstr_space; + propvar.pwszVal = wstr_space; result = PropVariantToStringWithDefault(&propvar, default_value); ok(result == wstr_space, "Unexpected value %s\n", wine_dbgstr_w(result)); propvar.vt = VT_LPWSTR; - propvar.u.pwszVal = wstr_test2; + propvar.pwszVal = wstr_test2; result = PropVariantToStringWithDefault(&propvar, default_value); ok(result == wstr_test2, "Unexpected value %s\n", wine_dbgstr_w(result)); /* VT_LPSTR */ propvar.vt = VT_LPSTR; - propvar.u.pszVal = NULL; + propvar.pszVal = NULL; result = PropVariantToStringWithDefault(&propvar, default_value); ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); propvar.vt = VT_LPSTR; - propvar.u.pszVal = str_empty; + propvar.pszVal = str_empty; result = PropVariantToStringWithDefault(&propvar, default_value); ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); propvar.vt = VT_LPSTR; - propvar.u.pszVal = str_space; + propvar.pszVal = str_space; result = PropVariantToStringWithDefault(&propvar, default_value); ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); propvar.vt = VT_LPSTR; - propvar.u.pszVal = str_test2; + propvar.pszVal = str_test2; result = PropVariantToStringWithDefault(&propvar, default_value); ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); /* VT_BSTR */ propvar.vt = VT_BSTR; - propvar.u.bstrVal = NULL; + propvar.bstrVal = NULL; result = PropVariantToStringWithDefault(&propvar, default_value); ok(!lstrcmpW(result, wstr_empty), "Unexpected value %s\n", wine_dbgstr_w(result)); propvar.vt = VT_BSTR; - propvar.u.bstrVal = SysAllocString(wstr_empty); + propvar.bstrVal = SysAllocString(wstr_empty); result = PropVariantToStringWithDefault(&propvar, default_value); ok(!lstrcmpW(result, wstr_empty), "Unexpected value %s\n", wine_dbgstr_w(result)); - SysFreeString(propvar.u.bstrVal); + SysFreeString(propvar.bstrVal); propvar.vt = VT_BSTR; - propvar.u.bstrVal = SysAllocString(wstr_space); + propvar.bstrVal = SysAllocString(wstr_space); result = PropVariantToStringWithDefault(&propvar, default_value); ok(!lstrcmpW(result, wstr_space), "Unexpected value %s\n", wine_dbgstr_w(result)); - SysFreeString(propvar.u.bstrVal); + SysFreeString(propvar.bstrVal); propvar.vt = VT_BSTR; - propvar.u.bstrVal = SysAllocString(wstr_test2); + propvar.bstrVal = SysAllocString(wstr_test2); result = PropVariantToStringWithDefault(&propvar, default_value); ok(!lstrcmpW(result, wstr_test2), "Unexpected value %s\n", wine_dbgstr_w(result)); - SysFreeString(propvar.u.bstrVal); + SysFreeString(propvar.bstrVal); } static void test_PropVariantChangeType_LPWSTR(void) @@ -1283,29 +1394,29 @@ static void test_PropVariantChangeType_LPWSTR(void) src.vt = VT_NULL; hr = PropVariantChangeType(&dest, &src, 0, VT_LPWSTR); - ok(hr == S_OK, "hr=%x\n", hr); + ok(hr == S_OK, "hr=%lx\n", hr); ok(dest.vt == VT_LPWSTR, "got %d\n", dest.vt); - ok(!lstrcmpW(dest.u.pwszVal, emptyW), "got %s\n", wine_dbgstr_w(dest.u.pwszVal)); + ok(!lstrcmpW(dest.pwszVal, emptyW), "got %s\n", wine_dbgstr_w(dest.pwszVal)); PropVariantClear(&dest); PropVariantClear(&src); src.vt = VT_LPSTR; - src.u.pszVal = CoTaskMemAlloc(strlen(topic)+1); - strcpy(src.u.pszVal, topic); + src.pszVal = CoTaskMemAlloc(strlen(topic)+1); + strcpy(src.pszVal, topic); hr = PropVariantChangeType(&dest, &src, 0, VT_LPWSTR); - ok(hr == S_OK, "hr=%x\n", hr); + ok(hr == S_OK, "hr=%lx\n", hr); ok(dest.vt == VT_LPWSTR, "got %d\n", dest.vt); - ok(!lstrcmpW(dest.u.pwszVal, topicW), "got %s\n", wine_dbgstr_w(dest.u.pwszVal)); + ok(!lstrcmpW(dest.pwszVal, topicW), "got %s\n", wine_dbgstr_w(dest.pwszVal)); PropVariantClear(&dest); PropVariantClear(&src); src.vt = VT_LPWSTR; - src.u.pwszVal = CoTaskMemAlloc( (lstrlenW(topicW)+1) * sizeof(WCHAR)); - lstrcpyW(src.u.pwszVal, topicW); + src.pwszVal = CoTaskMemAlloc( (lstrlenW(topicW)+1) * sizeof(WCHAR)); + lstrcpyW(src.pwszVal, topicW); hr = PropVariantChangeType(&dest, &src, 0, VT_LPWSTR); - ok(hr == S_OK, "hr=%x\n", hr); + ok(hr == S_OK, "hr=%lx\n", hr); ok(dest.vt == VT_LPWSTR, "got %d\n", dest.vt); - ok(!lstrcmpW(dest.u.pwszVal, topicW), "got %s\n", wine_dbgstr_w(dest.u.pwszVal)); + ok(!lstrcmpW(dest.pwszVal, topicW), "got %s\n", wine_dbgstr_w(dest.pwszVal)); PropVariantClear(&dest); PropVariantClear(&src); } @@ -1318,13 +1429,42 @@ static void test_InitPropVariantFromCLSID(void) memset(&propvar, 0, sizeof(propvar)); propvar.vt = VT_I4; - propvar.u.lVal = 15; + propvar.lVal = 15; memset(&clsid, 0xcc, sizeof(clsid)); hr = InitPropVariantFromCLSID(&clsid, &propvar); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(propvar.vt == VT_CLSID, "Unexpected type %d.\n", propvar.vt); - ok(IsEqualGUID(propvar.u.puuid, &clsid), "Unexpected puuid value.\n"); + ok(IsEqualGUID(propvar.puuid, &clsid), "Unexpected puuid value.\n"); + PropVariantClear(&propvar); +} + +static void test_InitPropVariantFromStringVector(void) +{ + static const WCHAR *strs[2] = { L"abc", L"def" }; + PROPVARIANT propvar; + HRESULT hr; + + memset(&propvar, 0, sizeof(propvar)); + propvar.vt = VT_I4; + propvar.lVal = 15; + + hr = InitPropVariantFromStringVector(NULL, 0, &propvar); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(propvar.vt == (VT_LPWSTR|VT_VECTOR), "Unexpected type %#x.\n", propvar.vt); + ok(!propvar.calpwstr.cElems, "Unexpected number of elements.\n"); + ok(!!propvar.calpwstr.pElems, "Unexpected vector pointer.\n"); + PropVariantClear(&propvar); + + hr = InitPropVariantFromStringVector(strs, 2, &propvar); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(propvar.vt == (VT_LPWSTR|VT_VECTOR), "Unexpected type %#x.\n", propvar.vt); + ok(propvar.calpwstr.cElems == 2, "Unexpected number of elements.\n"); + ok(!!propvar.calpwstr.pElems, "Unexpected vector pointer.\n"); + ok(propvar.calpwstr.pElems[0] != strs[0], "Unexpected string pointer.\n"); + ok(!wcscmp(propvar.calpwstr.pElems[0], strs[0]), "Unexpected string %s.\n", debugstr_w(propvar.calpwstr.pElems[0])); + ok(propvar.calpwstr.pElems[1] != strs[1], "Unexpected string pointer.\n"); + ok(!wcscmp(propvar.calpwstr.pElems[1], strs[1]), "Unexpected string %s.\n", debugstr_w(propvar.calpwstr.pElems[1])); PropVariantClear(&propvar); } @@ -1336,141 +1476,262 @@ static void test_PropVariantToDouble(void) PropVariantInit(&propvar); propvar.vt = VT_R8; - propvar.u.dblVal = 15.0; + propvar.dblVal = 15.0; hr = PropVariantToDouble(&propvar, &value); - ok(hr == S_OK, "PropVariantToDouble failed: 0x%08x.\n", hr); + ok(hr == S_OK, "PropVariantToDouble failed: 0x%08lx.\n", hr); ok(value == 15.0, "Unexpected value: %f.\n", value); PropVariantClear(&propvar); propvar.vt = VT_I4; - propvar.u.lVal = 123; + propvar.lVal = 123; hr = PropVariantToDouble(&propvar, &value); - ok(hr == S_OK, "PropVariantToDouble failed: 0x%08x.\n", hr); + ok(hr == S_OK, "PropVariantToDouble failed: 0x%08lx.\n", hr); ok(value == 123.0, "Unexpected value: %f.\n", value); PropVariantClear(&propvar); propvar.vt = VT_I4; - propvar.u.lVal = -256; + propvar.lVal = -256; hr = PropVariantToDouble(&propvar, &value); - ok(hr == S_OK, "PropVariantToDouble failed: 0x%08x.\n", hr); + ok(hr == S_OK, "PropVariantToDouble failed: 0x%08lx.\n", hr); ok(value == -256, "Unexpected value: %f\n", value); PropVariantClear(&propvar); propvar.vt = VT_I8; - propvar.u.lVal = 65536; + propvar.lVal = 65536; hr = PropVariantToDouble(&propvar, &value); - ok(hr == S_OK, "PropVariantToDouble failed: 0x%08x.\n", hr); + ok(hr == S_OK, "PropVariantToDouble failed: 0x%08lx.\n", hr); ok(value == 65536.0, "Unexpected value: %f.\n", value); PropVariantClear(&propvar); propvar.vt = VT_I8; - propvar.u.lVal = -321; + propvar.lVal = -321; hr = PropVariantToDouble(&propvar, &value); - ok(hr == S_OK, "PropVariantToDouble failed: 0x%08x.\n", hr); + ok(hr == S_OK, "PropVariantToDouble failed: 0x%08lx.\n", hr); ok(value == 4294966975.0, "Unexpected value: %f.\n", value); PropVariantClear(&propvar); propvar.vt = VT_UI4; - propvar.u.ulVal = 6; + propvar.ulVal = 6; hr = PropVariantToDouble(&propvar, &value); - ok(hr == S_OK, "PropVariantToDouble failed: 0x%08x.\n", hr); + ok(hr == S_OK, "PropVariantToDouble failed: 0x%08lx.\n", hr); ok(value == 6.0, "Unexpected value: %f.\n", value); PropVariantClear(&propvar); propvar.vt = VT_UI8; - propvar.u.uhVal.QuadPart = 8; + propvar.uhVal.QuadPart = 8; hr = PropVariantToDouble(&propvar, &value); - ok(hr == S_OK, "PropVariantToDouble failed: 0x%08x.\n", hr); + ok(hr == S_OK, "PropVariantToDouble failed: 0x%08lx.\n", hr); ok(value == 8.0, "Unexpected value: %f.\n", value); } static void test_PropVariantToString(void) { - PROPVARIANT propvar; + static WCHAR stringW[] = L"Wine"; static CHAR string[] = "Wine"; - static WCHAR stringW[] = {'W','i','n','e',0}; WCHAR bufferW[256] = {0}; + PROPVARIANT propvar; HRESULT hr; PropVariantInit(&propvar); propvar.vt = VT_EMPTY; - U(propvar).pwszVal = stringW; + propvar.pwszVal = stringW; bufferW[0] = 65; hr = PropVariantToString(&propvar, bufferW, 0); - ok(hr == E_INVALIDARG, "PropVariantToString should fail: 0x%08x.\n", hr); + ok(hr == E_INVALIDARG, "PropVariantToString should fail: 0x%08lx.\n", hr); ok(!bufferW[0], "got wrong string: \"%s\".\n", wine_dbgstr_w(bufferW)); memset(bufferW, 0, sizeof(bufferW)); PropVariantClear(&propvar); PropVariantInit(&propvar); propvar.vt = VT_EMPTY; - U(propvar).pwszVal = stringW; + propvar.pwszVal = stringW; bufferW[0] = 65; hr = PropVariantToString(&propvar, bufferW, ARRAY_SIZE(bufferW)); - ok(hr == S_OK, "PropVariantToString failed: 0x%08x.\n", hr); + ok(hr == S_OK, "PropVariantToString failed: 0x%08lx.\n", hr); ok(!bufferW[0], "got wrong string: \"%s\".\n", wine_dbgstr_w(bufferW)); memset(bufferW, 0, sizeof(bufferW)); PropVariantClear(&propvar); PropVariantInit(&propvar); propvar.vt = VT_NULL; - U(propvar).pwszVal = stringW; + propvar.pwszVal = stringW; bufferW[0] = 65; hr = PropVariantToString(&propvar, bufferW, ARRAY_SIZE(bufferW)); - ok(hr == S_OK, "PropVariantToString failed: 0x%08x.\n", hr); + ok(hr == S_OK, "PropVariantToString failed: 0x%08lx.\n", hr); ok(!bufferW[0], "got wrong string: \"%s\".\n", wine_dbgstr_w(bufferW)); memset(bufferW, 0, sizeof(bufferW)); PropVariantClear(&propvar); PropVariantInit(&propvar); propvar.vt = VT_I4; - U(propvar).lVal = 22; + propvar.lVal = 22; hr = PropVariantToString(&propvar, bufferW, ARRAY_SIZE(bufferW)); - todo_wine ok(hr == S_OK, "PropVariantToString failed: 0x%08x.\n", hr); - todo_wine ok(!strcmp_wa(bufferW, "22"), "got wrong string: \"%s\".\n", wine_dbgstr_w(bufferW)); + todo_wine ok(hr == S_OK, "PropVariantToString failed: 0x%08lx.\n", hr); + todo_wine ok(!lstrcmpW(bufferW, L"22"), "got wrong string: \"%s\".\n", wine_dbgstr_w(bufferW)); memset(bufferW, 0, sizeof(bufferW)); PropVariantClear(&propvar); PropVariantInit(&propvar); propvar.vt = VT_LPWSTR; - U(propvar).pwszVal = stringW; + propvar.pwszVal = stringW; hr = PropVariantToString(&propvar, bufferW, ARRAY_SIZE(bufferW)); - ok(hr == S_OK, "PropVariantToString failed: 0x%08x.\n", hr); + ok(hr == S_OK, "PropVariantToString failed: 0x%08lx.\n", hr); ok(!lstrcmpW(bufferW, stringW), "got wrong string: \"%s\".\n", wine_dbgstr_w(bufferW)); memset(bufferW, 0, sizeof(bufferW)); PropVariantInit(&propvar); propvar.vt = VT_LPSTR; - U(propvar).pszVal = string; + propvar.pszVal = string; hr = PropVariantToString(&propvar, bufferW, ARRAY_SIZE(bufferW)); - ok(hr == S_OK, "PropVariantToString failed: 0x%08x.\n", hr); + ok(hr == S_OK, "PropVariantToString failed: 0x%08lx.\n", hr); ok(!lstrcmpW(bufferW, stringW), "got wrong string: \"%s\".\n", wine_dbgstr_w(bufferW)); memset(bufferW, 0, sizeof(bufferW)); + /* Result string will be truncated if output buffer is too small. */ + PropVariantInit(&propvar); + propvar.vt = VT_UI4; + propvar.lVal = 123456; + hr = PropVariantToString(&propvar, bufferW, 4); + todo_wine + ok(hr == STRSAFE_E_INSUFFICIENT_BUFFER, "PropVariantToString returned: %#lx.\n", hr); + todo_wine + ok(!wcscmp(bufferW, L"123"), "Unexpected string %s.\n", debugstr_w(bufferW)); + memset(bufferW, 0, sizeof(bufferW)); + PropVariantInit(&propvar); propvar.vt = VT_LPWSTR; - U(propvar).pwszVal = stringW; + propvar.pwszVal = stringW; hr = PropVariantToString(&propvar, bufferW, 4); - ok(hr == STRSAFE_E_INSUFFICIENT_BUFFER, "PropVariantToString returned: 0x%08x.\n", hr); - ok(!memcmp(bufferW, stringW, 4), "got wrong string.\n"); + ok(hr == STRSAFE_E_INSUFFICIENT_BUFFER, "PropVariantToString returned: 0x%08lx.\n", hr); + ok(!wcscmp(bufferW, L"Win"), "Unexpected string %s.\n", debugstr_w(bufferW)); memset(bufferW, 0, sizeof(bufferW)); PropVariantInit(&propvar); propvar.vt = VT_LPSTR; - U(propvar).pszVal = string; + propvar.pszVal = string; hr = PropVariantToString(&propvar, bufferW, 4); - ok(hr == STRSAFE_E_INSUFFICIENT_BUFFER, "PropVariantToString returned: 0x%08x.\n", hr); - ok(!memcmp(bufferW, stringW, 4), "got wrong string.\n"); + ok(hr == STRSAFE_E_INSUFFICIENT_BUFFER, "PropVariantToString returned: 0x%08lx.\n", hr); + ok(!wcscmp(bufferW, L"Win"), "Unexpected string %s.\n", debugstr_w(bufferW)); memset(bufferW, 0, sizeof(bufferW)); PropVariantInit(&propvar); propvar.vt = VT_BSTR; - propvar.u.bstrVal = SysAllocString(stringW); + propvar.bstrVal = SysAllocString(stringW); hr = PropVariantToString(&propvar, bufferW, ARRAY_SIZE(bufferW)); - ok(hr == S_OK, "PropVariantToString failed: 0x%08x.\n", hr); + ok(hr == S_OK, "PropVariantToString failed: 0x%08lx.\n", hr); ok(!lstrcmpW(bufferW, stringW), "got wrong string: \"%s\".\n", wine_dbgstr_w(bufferW)); memset(bufferW, 0, sizeof(bufferW)); - SysFreeString(propvar.u.bstrVal); + SysFreeString(propvar.bstrVal); + + PropVariantInit(&propvar); + propvar.vt = VT_CLSID; + propvar.puuid = (CLSID *)&dummy_guid; + hr = PropVariantToString(&propvar, bufferW, ARRAY_SIZE(bufferW)); + ok(hr == S_OK, "PropVariantToString returned %#lx.\n", hr); + ok(!wcscmp(bufferW, dummy_guid_str), "Unexpected string %s.\n", debugstr_w(bufferW)); + memset(bufferW, 0, sizeof(bufferW)); +} + +#define check_PropVariantToBSTR(type, member, value, expect_str) \ +do \ +{ \ + PROPVARIANT check_propvar_ = {.vt = (type), .member = (value)}; \ + HRESULT check_hr_; \ + BSTR check_bstr_; \ + \ + check_hr_ = PropVariantToBSTR(&check_propvar_, &check_bstr_); \ + ok_(__FILE__, __LINE__)(check_hr_ == S_OK, \ + "PropVariantToBSTR returned %#lx.\n", check_hr_); \ + \ + if (check_hr_ == S_OK) \ + { \ + ok_(__FILE__, __LINE__)(!wcscmp(check_bstr_, (expect_str)), \ + "Unexpected bstr %s.\n", debugstr_w(check_bstr_)); \ + SysFreeString(check_bstr_); \ + } \ +} while (0) + +static void test_PropVariantToBSTR(void) +{ + unsigned char test_bytes[] = {1, 20, 30, 4}; + WCHAR test_bstr[] = {'a', 0, 'b', 0, 'c'}; + PROPVARIANT propvar; + UINT length; + HRESULT hr; + BSTR bstr; + + if (0) /* Crashes. */ + { + hr = PropVariantToBSTR(&propvar, NULL); + hr = PropVariantToBSTR(NULL, &bstr); + } + + todo_wine + { + check_PropVariantToBSTR(VT_I1, cVal, -123, L"-123"); + check_PropVariantToBSTR(VT_I2, iVal, -456, L"-456"); + check_PropVariantToBSTR(VT_I4, lVal, -789, L"-789"); + check_PropVariantToBSTR(VT_I8, hVal.QuadPart, -101112, L"-101112"); + check_PropVariantToBSTR(VT_UI1, bVal, 0xcd, L"205"); + check_PropVariantToBSTR(VT_UI2, uiVal, 0xdead, L"57005"); + check_PropVariantToBSTR(VT_UI4, ulVal, 0xdeadbeef, L"3735928559"); + check_PropVariantToBSTR(VT_UI8, uhVal.QuadPart, 0xdeadbeefdeadbeef, L"16045690984833335023"); + check_PropVariantToBSTR(VT_BOOL, boolVal, TRUE, L"1"); + check_PropVariantToBSTR(VT_R4, fltVal, 0.125f, L"0.125"); + check_PropVariantToBSTR(VT_R8, dblVal, 0.456, L"0.456"); + } + check_PropVariantToBSTR(VT_CLSID, puuid, (CLSID *)&dummy_guid, dummy_guid_str); + check_PropVariantToBSTR(VT_LPSTR, pszVal, (char *)topic, topicW); + check_PropVariantToBSTR(VT_LPWSTR, pwszVal, (WCHAR *)topicW, topicW); + + PropVariantInit(&propvar); + propvar.vt = VT_FILETIME; + propvar.filetime.dwLowDateTime = 0xdead; + propvar.filetime.dwHighDateTime = 0xbeef; + hr = PropVariantToBSTR(&propvar, &bstr); + todo_wine + ok(hr == S_OK, "PropVariantToBSTR returned %#lx.\n", hr); + if (hr == S_OK) + { + ok(!wcscmp(bstr, L"1601/08/31:23:29:30.651"), "Unexpected bstr %s.\n", debugstr_w(bstr)); + SysFreeString(bstr); + } + + PropVariantInit(&propvar); + propvar.vt = VT_DATE; + propvar.date = 123.123f; + hr = PropVariantToBSTR(&propvar, &bstr); + todo_wine + ok(hr == S_OK, "PropVariantToBSTR returned %#lx.\n", hr); + if (hr == S_OK) + { + ok(!wcscmp(bstr, L"1900/05/02:02:57:07.000"), "Unexpected bstr %s.\n", debugstr_w(bstr)); + SysFreeString(bstr); + } + + PropVariantInit(&propvar); + propvar.vt = VT_VECTOR | VT_I1; + propvar.caub.cElems = ARRAY_SIZE(test_bytes); + propvar.caub.pElems = test_bytes; + hr = PropVariantToBSTR(&propvar, &bstr); + todo_wine + ok(hr == S_OK, "PropVariantToBSTR returned %#lx.\n", hr); + if (hr == S_OK) + { + ok(!wcscmp(bstr, L"1; 20; 30; 4"), "Unexpected bstr %s.\n", debugstr_w(bstr)); + SysFreeString(bstr); + } + + PropVariantInit(&propvar); + propvar.vt = VT_BSTR; + propvar.bstrVal = SysAllocStringLen(test_bstr, ARRAY_SIZE(test_bstr)); + hr = PropVariantToBSTR(&propvar, &bstr); + ok(hr == S_OK, "PropVariantToBSTR returned %#lx.\n", hr); + length = SysStringLen(bstr); + ok(length == wcslen(test_bstr), "Unexpected length %u.\n", length); + ok(!wcscmp(bstr, test_bstr), "Unexpected bstr %s.", debugstr_wn(bstr, ARRAY_SIZE(test_bstr))); + SysFreeString(bstr); + PropVariantClear(&propvar); } static void test_PropVariantToBuffer(void) @@ -1482,35 +1743,35 @@ static void test_PropVariantToBuffer(void) SAFEARRAY *sa; SAFEARRAYBOUND sabound; void *pdata; - UINT8 buffer[256]; + UINT8 buffer[256] = {0}; hr = InitPropVariantFromBuffer(data, 10, &propvar); - ok(hr == S_OK, "InitPropVariantFromBuffer failed 0x%08x.\n", hr); + ok(hr == S_OK, "InitPropVariantFromBuffer failed 0x%08lx.\n", hr); hr = PropVariantToBuffer(&propvar, NULL, 0); /* crash when cb isn't zero */ - ok(hr == S_OK, "PropVariantToBuffer failed: 0x%08x.\n", hr); + ok(hr == S_OK, "PropVariantToBuffer failed: 0x%08lx.\n", hr); PropVariantClear(&propvar); hr = InitPropVariantFromBuffer(data, 10, &propvar); - ok(hr == S_OK, "InitPropVariantFromBuffer failed 0x%08x.\n", hr); + ok(hr == S_OK, "InitPropVariantFromBuffer failed 0x%08lx.\n", hr); hr = PropVariantToBuffer(&propvar, buffer, 10); - ok(hr == S_OK, "PropVariantToBuffer failed: 0x%08x.\n", hr); + ok(hr == S_OK, "PropVariantToBuffer failed: 0x%08lx.\n", hr); ok(!memcmp(buffer, data, 10) && !buffer[10], "got wrong buffer.\n"); memset(buffer, 0, sizeof(buffer)); PropVariantClear(&propvar); hr = InitPropVariantFromBuffer(data, 10, &propvar); - ok(hr == S_OK, "InitPropVariantFromBuffer failed 0x%08x.\n", hr); + ok(hr == S_OK, "InitPropVariantFromBuffer failed 0x%08lx.\n", hr); buffer[0] = 99; hr = PropVariantToBuffer(&propvar, buffer, 11); - ok(hr == E_FAIL, "PropVariantToBuffer returned: 0x%08x.\n", hr); + ok(hr == E_FAIL, "PropVariantToBuffer returned: 0x%08lx.\n", hr); ok(buffer[0] == 99, "got wrong buffer.\n"); memset(buffer, 0, sizeof(buffer)); PropVariantClear(&propvar); hr = InitPropVariantFromBuffer(data, 10, &propvar); - ok(hr == S_OK, "InitPropVariantFromBuffer failed 0x%08x.\n", hr); + ok(hr == S_OK, "InitPropVariantFromBuffer failed 0x%08lx.\n", hr); hr = PropVariantToBuffer(&propvar, buffer, 9); - ok(hr == S_OK, "PropVariantToBuffer failed: 0x%08x.\n", hr); + ok(hr == S_OK, "PropVariantToBuffer failed: 0x%08lx.\n", hr); ok(!memcmp(buffer, data, 9) && !buffer[9], "got wrong buffer.\n"); memset(buffer, 0, sizeof(buffer)); PropVariantClear(&propvar); @@ -1523,14 +1784,14 @@ static void test_PropVariantToBuffer(void) sa = SafeArrayCreate(VT_UI1, 1, &sabound); ok(sa != NULL, "SafeArrayCreate failed.\n"); hr = SafeArrayAccessData(sa, &pdata); - ok(hr == S_OK, "SafeArrayAccessData failed: 0x%08x.\n", hr); + ok(hr == S_OK, "SafeArrayAccessData failed: 0x%08lx.\n", hr); memcpy(pdata, data, sizeof(data)); hr = SafeArrayUnaccessData(sa); - ok(hr == S_OK, "SafeArrayUnaccessData failed: 0x%08x.\n", hr); - U(propvar).parray = sa; + ok(hr == S_OK, "SafeArrayUnaccessData failed: 0x%08lx.\n", hr); + propvar.parray = sa; buffer[0] = 99; hr = PropVariantToBuffer(&propvar, buffer, 11); - todo_wine ok(hr == E_FAIL, "PropVariantToBuffer returned: 0x%08x.\n", hr); + todo_wine ok(hr == E_FAIL, "PropVariantToBuffer returned: 0x%08lx.\n", hr); ok(buffer[0] == 99, "got wrong buffer.\n"); memset(buffer, 0, sizeof(buffer)); PropVariantClear(&propvar); @@ -1543,24 +1804,24 @@ static void test_PropVariantToBuffer(void) sa = SafeArrayCreate(VT_UI1, 1, &sabound); ok(sa != NULL, "SafeArrayCreate failed.\n"); hr = SafeArrayAccessData(sa, &pdata); - ok(hr == S_OK, "SafeArrayAccessData failed: 0x%08x.\n", hr); + ok(hr == S_OK, "SafeArrayAccessData failed: 0x%08lx.\n", hr); memcpy(pdata, data, sizeof(data)); hr = SafeArrayUnaccessData(sa); - ok(hr == S_OK, "SafeArrayUnaccessData failed: 0x%08x.\n", hr); - U(propvar).parray = sa; + ok(hr == S_OK, "SafeArrayUnaccessData failed: 0x%08lx.\n", hr); + propvar.parray = sa; hr = PropVariantToBuffer(&propvar, buffer, sizeof(data)); - todo_wine ok(hr == S_OK, "PropVariantToBuffer failed: 0x%08x.\n", hr); + todo_wine ok(hr == S_OK, "PropVariantToBuffer failed: 0x%08lx.\n", hr); todo_wine ok(!memcmp(buffer, data, 10) && !buffer[10], "got wrong buffer.\n"); memset(buffer, 0, sizeof(buffer)); PropVariantClear(&propvar); PropVariantInit(&propvar); propvar.vt = VT_VECTOR|VT_I1; - U(propvar).caub.pElems = CoTaskMemAlloc(sizeof(data_int8)); - U(propvar).caub.cElems = sizeof(data_int8); - memcpy(U(propvar).caub.pElems, data_int8, sizeof(data_int8)); + propvar.caub.pElems = CoTaskMemAlloc(sizeof(data_int8)); + propvar.caub.cElems = sizeof(data_int8); + memcpy(propvar.caub.pElems, data_int8, sizeof(data_int8)); hr = PropVariantToBuffer(&propvar, buffer, sizeof(data_int8)); - ok(hr == E_INVALIDARG, "PropVariantToBuffer failed: 0x%08x.\n", hr); + ok(hr == E_INVALIDARG, "PropVariantToBuffer failed: 0x%08lx.\n", hr); PropVariantClear(&propvar); PropVariantInit(&propvar); @@ -1571,32 +1832,829 @@ static void test_PropVariantToBuffer(void) sa = SafeArrayCreate(VT_I1, 1, &sabound); ok(sa != NULL, "SafeArrayCreate failed.\n"); hr = SafeArrayAccessData(sa, &pdata); - ok(hr == S_OK, "SafeArrayAccessData failed: 0x%08x.\n", hr); + ok(hr == S_OK, "SafeArrayAccessData failed: 0x%08lx.\n", hr); memcpy(pdata, data_int8, sizeof(data_int8)); hr = SafeArrayUnaccessData(sa); - ok(hr == S_OK, "SafeArrayUnaccessData failed: 0x%08x.\n", hr); - U(propvar).parray = sa; + ok(hr == S_OK, "SafeArrayUnaccessData failed: 0x%08lx.\n", hr); + propvar.parray = sa; hr = PropVariantToBuffer(&propvar, buffer, sizeof(data_int8)); - ok(hr == E_INVALIDARG, "PropVariantToBuffer failed: 0x%08x.\n", hr); + ok(hr == E_INVALIDARG, "PropVariantToBuffer failed: 0x%08lx.\n", hr); + PropVariantClear(&propvar); +} + +static void test_inmemorystore(void) +{ + IPropertyStoreCache *propcache; + HRESULT hr; + PROPERTYKEY pkey; + PROPVARIANT propvar; + DWORD count; + PSC_STATE state; + + CoInitialize(NULL); + + hr = CoCreateInstance(&CLSID_InMemoryPropertyStore, NULL, CLSCTX_INPROC_SERVER, + &IID_IPropertyStoreCache, (void**)&propcache); + ok(hr == S_OK, "CoCreateInstance failed, hr=%lx\n", hr); + + if (FAILED(hr)) + { + win_skip("CLSID_InMemoryPropertyStore not supported\n"); + CoUninitialize(); + return; + } + + hr = IPropertyStoreCache_GetCount(propcache, NULL); + ok(hr == E_POINTER, "GetCount failed, hr=%lx\n", hr); + + hr = IPropertyStoreCache_GetCount(propcache, &count); + ok(hr == S_OK, "GetCount failed, hr=%lx\n", hr); + ok(count == 0, "GetCount returned %li, expected 0\n", count); + + hr = IPropertyStoreCache_Commit(propcache); + ok(hr == S_OK, "Commit failed, hr=%lx\n", hr); + + hr = IPropertyStoreCache_Commit(propcache); + ok(hr == S_OK, "Commit failed, hr=%lx\n", hr); + + hr = IPropertyStoreCache_GetAt(propcache, 0, &pkey); + ok(hr == E_INVALIDARG, "GetAt failed, hr=%lx\n", hr); + + pkey.fmtid = PKEY_WineTest; + pkey.pid = 4; + + memset(&propvar, 0, sizeof(propvar)); + propvar.vt = VT_I4; + propvar.lVal = 12345; + + if (0) + { + /* Crashes on Windows 7 */ + hr = IPropertyStoreCache_SetValue(propcache, NULL, &propvar); + ok(hr == E_POINTER, "SetValue failed, hr=%lx\n", hr); + + hr = IPropertyStoreCache_SetValue(propcache, &pkey, NULL); + ok(hr == E_POINTER, "SetValue failed, hr=%lx\n", hr); + } + + hr = IPropertyStoreCache_SetValue(propcache, &pkey, &propvar); + ok(hr == S_OK, "SetValue failed, hr=%lx\n", hr); + + hr = IPropertyStoreCache_GetCount(propcache, &count); + ok(hr == S_OK, "GetCount failed, hr=%lx\n", hr); + ok(count == 1, "GetCount returned %li, expected 0\n", count); + + memset(&pkey, 0, sizeof(pkey)); + + hr = IPropertyStoreCache_GetAt(propcache, 0, &pkey); + ok(hr == S_OK, "GetAt failed, hr=%lx\n", hr); + ok(IsEqualGUID(&pkey.fmtid, &PKEY_WineTest), "got wrong pkey\n"); + ok(pkey.pid == 4, "got pid of %li, expected 4\n", pkey.pid); + + pkey.fmtid = PKEY_WineTest; + pkey.pid = 4; + + memset(&propvar, 0, sizeof(propvar)); + + if (0) + { + /* Crashes on Windows 7 */ + hr = IPropertyStoreCache_GetValue(propcache, NULL, &propvar); + ok(hr == E_POINTER, "GetValue failed, hr=%lx\n", hr); + } + + hr = IPropertyStoreCache_GetValue(propcache, &pkey, NULL); + ok(hr == E_POINTER, "GetValue failed, hr=%lx\n", hr); + + hr = IPropertyStoreCache_GetValue(propcache, &pkey, &propvar); + ok(hr == S_OK, "GetValue failed, hr=%lx\n", hr); + ok(propvar.vt == VT_I4, "expected VT_I4, got %d\n", propvar.vt); + ok(propvar.lVal == 12345, "expected 12345, got %ld\n", propvar.lVal); + + pkey.fmtid = PKEY_WineTest; + pkey.pid = 10; + + /* Get information for field that isn't set yet */ + propvar.vt = VT_I2; + hr = IPropertyStoreCache_GetValue(propcache, &pkey, &propvar); + ok(hr == S_OK, "GetValue failed, hr=%lx\n", hr); + ok(propvar.vt == VT_EMPTY, "expected VT_EMPTY, got %d\n", propvar.vt); + + state = 0xdeadbeef; + hr = IPropertyStoreCache_GetState(propcache, &pkey, &state); + ok(hr == TYPE_E_ELEMENTNOTFOUND, "GetState failed, hr=%lx\n", hr); + ok(state == PSC_NORMAL, "expected PSC_NORMAL, got %d\n", state); + + propvar.vt = VT_I2; + state = 0xdeadbeef; + hr = IPropertyStoreCache_GetValueAndState(propcache, &pkey, &propvar, &state); + ok(hr == TYPE_E_ELEMENTNOTFOUND, "GetValueAndState failed, hr=%lx\n", hr); + ok(propvar.vt == VT_EMPTY, "expected VT_EMPTY, got %d\n", propvar.vt); + ok(state == PSC_NORMAL, "expected PSC_NORMAL, got %d\n", state); + + /* Set state on an unset field */ + hr = IPropertyStoreCache_SetState(propcache, &pkey, PSC_NORMAL); + ok(hr == TYPE_E_ELEMENTNOTFOUND, "SetState failed, hr=%lx\n", hr); + + /* Manipulate state on already set field */ + pkey.fmtid = PKEY_WineTest; + pkey.pid = 4; + + state = 0xdeadbeef; + hr = IPropertyStoreCache_GetState(propcache, &pkey, &state); + ok(hr == S_OK, "GetState failed, hr=%lx\n", hr); + ok(state == PSC_NORMAL, "expected PSC_NORMAL, got %d\n", state); + + hr = IPropertyStoreCache_SetState(propcache, &pkey, 10); + ok(hr == S_OK, "SetState failed, hr=%lx\n", hr); + + state = 0xdeadbeef; + hr = IPropertyStoreCache_GetState(propcache, &pkey, &state); + ok(hr == S_OK, "GetState failed, hr=%lx\n", hr); + ok(state == 10, "expected 10, got %d\n", state); + + propvar.vt = VT_I4; + propvar.lVal = 12346; + hr = IPropertyStoreCache_SetValueAndState(propcache, &pkey, &propvar, 5); + ok(hr == S_OK, "SetValueAndState failed, hr=%lx\n", hr); + + memset(&propvar, 0, sizeof(propvar)); + state = 0xdeadbeef; + hr = IPropertyStoreCache_GetValueAndState(propcache, &pkey, &propvar, &state); + ok(hr == S_OK, "GetValueAndState failed, hr=%lx\n", hr); + ok(propvar.vt == VT_I4, "expected VT_I4, got %d\n", propvar.vt); + ok(propvar.lVal == 12346, "expected 12346, got %d\n", propvar.vt); + ok(state == 5, "expected 5, got %d\n", state); + + /* Set new field with state */ + pkey.fmtid = PKEY_WineTest; + pkey.pid = 8; + + propvar.vt = VT_I4; + propvar.lVal = 12347; + hr = IPropertyStoreCache_SetValueAndState(propcache, &pkey, &propvar, PSC_DIRTY); + ok(hr == S_OK, "SetValueAndState failed, hr=%lx\n", hr); + + memset(&propvar, 0, sizeof(propvar)); + state = 0xdeadbeef; + hr = IPropertyStoreCache_GetValueAndState(propcache, &pkey, &propvar, &state); + ok(hr == S_OK, "GetValueAndState failed, hr=%lx\n", hr); + ok(propvar.vt == VT_I4, "expected VT_I4, got %d\n", propvar.vt); + ok(propvar.lVal == 12347, "expected 12347, got %d\n", propvar.vt); + ok(state == PSC_DIRTY, "expected PSC_DIRTY, got %d\n", state); + + IPropertyStoreCache_Release(propcache); + + CoUninitialize(); +} + +static void test_persistserialized(void) +{ + IPropertyStore *propstore; + IPersistSerializedPropStorage *serialized; + HRESULT hr; + SERIALIZEDPROPSTORAGE *result; + DWORD result_size; + + CoInitialize(NULL); + + hr = CoCreateInstance(&CLSID_InMemoryPropertyStore, NULL, CLSCTX_INPROC_SERVER, + &IID_IPropertyStore, (void**)&propstore); + ok(hr == S_OK, "CoCreateInstance failed, hr=%lx\n", hr); + + hr = IPropertyStore_QueryInterface(propstore, &IID_IPersistSerializedPropStorage, + (void**)&serialized); + todo_wine ok(hr == S_OK, "QueryInterface failed, hr=%lx\n", hr); + + if (FAILED(hr)) + { + IPropertyStore_Release(propstore); + skip("IPersistSerializedPropStorage not supported\n"); + CoUninitialize(); + return; + } + + hr = IPersistSerializedPropStorage_GetPropertyStorage(serialized, NULL, &result_size); + ok(hr == E_POINTER, "GetPropertyStorage failed, hr=%lx\n", hr); + + hr = IPersistSerializedPropStorage_GetPropertyStorage(serialized, &result, NULL); + ok(hr == E_POINTER, "GetPropertyStorage failed, hr=%lx\n", hr); + + hr = IPersistSerializedPropStorage_GetPropertyStorage(serialized, &result, &result_size); + ok(hr == S_OK, "GetPropertyStorage failed, hr=%lx\n", hr); + + if (SUCCEEDED(hr)) + { + ok(result_size == 0, "expected 0 bytes, got %li\n", result_size); + + CoTaskMemFree(result); + } + + hr = IPersistSerializedPropStorage_SetPropertyStorage(serialized, NULL, 4); + ok(hr == E_POINTER, "SetPropertyStorage failed, hr=%lx\n", hr); + + hr = IPersistSerializedPropStorage_SetPropertyStorage(serialized, NULL, 0); + ok(hr == S_OK, "SetPropertyStorage failed, hr=%lx\n", hr); + + hr = IPropertyStore_GetCount(propstore, &result_size); + ok(hr == S_OK, "GetCount failed, hr=%lx\n", hr); + ok(result_size == 0, "expecting 0, got %ld\n", result_size); + + IPropertyStore_Release(propstore); + IPersistSerializedPropStorage_Release(serialized); + + CoUninitialize(); +} + +static void test_PSCreateMemoryPropertyStore(void) +{ + IPropertyStore *propstore, *propstore1; + IPersistSerializedPropStorage *serialized; + IPropertyStoreCache *propstorecache; + HRESULT hr; + + /* PSCreateMemoryPropertyStore(&IID_IPropertyStore, NULL); crashes */ + + hr = PSCreateMemoryPropertyStore(&IID_IPropertyStore, (void **)&propstore); + ok(hr == S_OK, "PSCreateMemoryPropertyStore failed: 0x%08lx.\n", hr); + ok(propstore != NULL, "got %p.\n", propstore); + EXPECT_REF(propstore, 1); + + hr = PSCreateMemoryPropertyStore(&IID_IPersistSerializedPropStorage, (void **)&serialized); + todo_wine ok(hr == S_OK, "PSCreateMemoryPropertyStore failed: 0x%08lx.\n", hr); + todo_wine ok(serialized != NULL, "got %p.\n", serialized); + EXPECT_REF(propstore, 1); + if(serialized) + { + EXPECT_REF(serialized, 1); + IPersistSerializedPropStorage_Release(serialized); + } + + hr = PSCreateMemoryPropertyStore(&IID_IPropertyStoreCache, (void **)&propstorecache); + ok(hr == S_OK, "PSCreateMemoryPropertyStore failed: 0x%08lx.\n", hr); + ok(propstorecache != NULL, "got %p.\n", propstore); + ok(propstorecache != (IPropertyStoreCache *)propstore, "pointer are equal: %p, %p.\n", propstorecache, propstore); + EXPECT_REF(propstore, 1); + EXPECT_REF(propstorecache, 1); + + hr = PSCreateMemoryPropertyStore(&IID_IPropertyStore, (void **)&propstore1); + ok(hr == S_OK, "PSCreateMemoryPropertyStore failed: 0x%08lx.\n", hr); + ok(propstore1 != NULL, "got %p.\n", propstore); + ok(propstore1 != propstore, "pointer are equal: %p, %p.\n", propstore1, propstore); + EXPECT_REF(propstore, 1); + EXPECT_REF(propstore1, 1); + EXPECT_REF(propstorecache, 1); + + IPropertyStore_Release(propstore1); + IPropertyStore_Release(propstore); + IPropertyStoreCache_Release(propstorecache); +} + +static void test_propertystore(void) +{ + IPropertyStore *propstore; + HRESULT hr; + PROPVARIANT propvar, ret_propvar; + PROPERTYKEY propkey; + DWORD count = 0; + + hr = PSCreateMemoryPropertyStore(&IID_IPropertyStore, (void **)&propstore); + ok(hr == S_OK, "PSCreateMemoryPropertyStore failed: 0x%08lx.\n", hr); + ok(propstore != NULL, "got %p.\n", propstore); + + hr = IPropertyStore_GetCount(propstore, &count); + ok(hr == S_OK, "IPropertyStore_GetCount failed: 0x%08lx.\n", hr); + ok(!count, "got wrong property count: %ld, expected 0.\n", count); + + PropVariantInit(&propvar); + propvar.vt = VT_I4; + propvar.lVal = 123; + propkey.fmtid = DUMMY_GUID1; + propkey.pid = PID_FIRST_USABLE; + hr = IPropertyStore_SetValue(propstore, &propkey, &propvar); + ok(hr == S_OK, "IPropertyStore_SetValue failed: 0x%08lx.\n", hr); + hr = IPropertyStore_Commit(propstore); + ok(hr == S_OK, "IPropertyStore_Commit failed: 0x%08lx.\n", hr); + hr = IPropertyStore_GetCount(propstore, &count); + ok(hr == S_OK, "IPropertyStore_GetCount failed: 0x%08lx.\n", hr); + ok(count == 1, "got wrong property count: %ld, expected 1.\n", count); + PropVariantInit(&ret_propvar); + ret_propvar.vt = VT_I4; + hr = IPropertyStore_GetValue(propstore, &propkey, &ret_propvar); + ok(hr == S_OK, "IPropertyStore_GetValue failed: 0x%08lx.\n", hr); + ok(ret_propvar.vt == VT_I4, "got wrong property type: %x.\n", ret_propvar.vt); + ok(ret_propvar.lVal == 123, "got wrong value: %ld, expected 123.\n", ret_propvar.lVal); + PropVariantClear(&propvar); + PropVariantClear(&ret_propvar); + + PropVariantInit(&propvar); + propkey.fmtid = DUMMY_GUID1; + propkey.pid = PID_FIRST_USABLE; + hr = IPropertyStore_SetValue(propstore, &propkey, &propvar); + ok(hr == S_OK, "IPropertyStore_SetValue failed: 0x%08lx.\n", hr); + hr = IPropertyStore_Commit(propstore); + ok(hr == S_OK, "IPropertyStore_Commit failed: 0x%08lx.\n", hr); + hr = IPropertyStore_GetCount(propstore, &count); + ok(hr == S_OK, "IPropertyStore_GetCount failed: 0x%08lx.\n", hr); + ok(count == 1, "got wrong property count: %ld, expected 1.\n", count); + PropVariantInit(&ret_propvar); + hr = IPropertyStore_GetValue(propstore, &propkey, &ret_propvar); + ok(hr == S_OK, "IPropertyStore_GetValue failed: 0x%08lx.\n", hr); + ok(ret_propvar.vt == VT_EMPTY, "got wrong property type: %x.\n", ret_propvar.vt); + ok(!ret_propvar.lVal, "got wrong value: %ld, expected 0.\n", ret_propvar.lVal); PropVariantClear(&propvar); + PropVariantClear(&ret_propvar); + + IPropertyStore_Release(propstore); +} + +static void test_PSCreatePropertyStoreFromObject(void) +{ + IPropertyStore *propstore; + IUnknown *unk; + HRESULT hr; + + hr = PSCreateMemoryPropertyStore(&IID_IPropertyStore, (void **)&propstore); + ok(hr == S_OK, "Failed to create property store, hr %#lx.\n", hr); + + hr = PSCreatePropertyStoreFromObject(NULL, STGM_READWRITE, &IID_IUnknown, (void **)&unk); + ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr); + + hr = PSCreatePropertyStoreFromObject((IUnknown *)propstore, STGM_READWRITE, &IID_IUnknown, NULL); + ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr); + + hr = PSCreatePropertyStoreFromObject((IUnknown *)propstore, STGM_READWRITE, &IID_IUnknown, (void **)&unk); + todo_wine + ok(hr == S_OK, "Failed to create wrapper, hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + { + ok(unk != (IUnknown *)propstore, "Unexpected object returned.\n"); + IUnknown_Release(unk); + } + + hr = PSCreatePropertyStoreFromObject((IUnknown *)propstore, STGM_READWRITE, &IID_IPropertyStore, (void **)&unk); + ok(hr == S_OK, "Failed to create wrapper, hr %#lx.\n", hr); + ok(unk == (IUnknown *)propstore, "Unexpected object returned.\n"); + IUnknown_Release(unk); + + IPropertyStore_Release(propstore); +} + +static void test_InitVariantFromFileTime(void) +{ + FILETIME ft = {0}; + SYSTEMTIME st; + VARIANT var; + HRESULT hr; + double d; + + VariantInit(&var); + if (0) /* crash on Windows */ + { + InitVariantFromFileTime(&ft, NULL); + InitVariantFromFileTime(NULL, &var); + } + + ft.dwHighDateTime = -1; + ft.dwLowDateTime = -1; + V_VT(&var) = 0xdead; + V_DATE(&var) = 42.0; + hr = InitVariantFromFileTime(&ft, &var); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + ok(V_VT(&var) == VT_EMPTY, "Unexpected VT %d\n", V_VT(&var)); + ok(V_DATE(&var) == 0.0, "got wrong value: %f, expected 0.0\n", V_DATE(&var)); + + GetSystemTimeAsFileTime(&ft); + hr = InitVariantFromFileTime(&ft, &var); + ok(V_VT(&var) == VT_DATE, "Unexpected VT %d\n", V_VT(&var)); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + FileTimeToSystemTime(&ft, &st); + SystemTimeToVariantTime(&st, &d); + ok(V_DATE(&var) == d, "got wrong value: %f, expected %f\n", V_DATE(&var), d); +} + +static void test_VariantToStringWithDefault(void) +{ + static WCHAR default_value[] = L"test"; + VARIANT var, var2; + PCWSTR result; + BSTR b; + + V_VT(&var) = VT_EMPTY; + result = VariantToStringWithDefault(&var, NULL); + ok(result == NULL, "Unexpected value %s\n", wine_dbgstr_w(result)); + result = VariantToStringWithDefault(&var, default_value); + ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); + + V_VT(&var) = VT_NULL; + result = VariantToStringWithDefault(&var, NULL); + ok(result == NULL, "Unexpected value %s\n", wine_dbgstr_w(result)); + result = VariantToStringWithDefault(&var, default_value); + ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); + + V_VT(&var) = VT_BOOL; + result = VariantToStringWithDefault(&var, NULL); + ok(result == NULL, "Unexpected value %s\n", wine_dbgstr_w(result)); + V_BOOL(&var) = VARIANT_TRUE; + result = VariantToStringWithDefault(&var, default_value); + ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); + + V_VT(&var) = VT_CY; + V_CY(&var).int64 = 100000; + result = VariantToStringWithDefault(&var, NULL); + ok(result == NULL, "Unexpected value %s\n", wine_dbgstr_w(result)); + result = VariantToStringWithDefault(&var, default_value); + ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); + + V_VT(&var) = VT_DATE; + V_DATE(&var) = 42.0; + result = VariantToStringWithDefault(&var, NULL); + ok(result == NULL, "Unexpected value %s\n", wine_dbgstr_w(result)); + result = VariantToStringWithDefault(&var, default_value); + ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); + + V_VT(&var) = VT_ERROR; + V_ERROR(&var) = DISP_E_PARAMNOTFOUND; + result = VariantToStringWithDefault(&var, NULL); + ok(result == NULL, "Unexpected value %s\n", wine_dbgstr_w(result)); + result = VariantToStringWithDefault(&var, default_value); + ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); + + V_VT(&var) = VT_I4; + V_I4(&var) = 15; + result = VariantToStringWithDefault(&var, NULL); + ok(result == NULL, "Unexpected value %s\n", wine_dbgstr_w(result)); + result = VariantToStringWithDefault(&var, default_value); + ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); + + V_VT(&var) = VT_I1; + V_I1(&var) = 1; + result = VariantToStringWithDefault(&var, NULL); + ok(result == NULL, "Unexpected value %s\n", wine_dbgstr_w(result)); + result = VariantToStringWithDefault(&var, default_value); + ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); + + /* V_BSTR */ + + V_VT(&var) = VT_BSTR; + V_BSTR(&var) = NULL; + result = VariantToStringWithDefault(&var, default_value); + ok(result[0] == '\0', "Unexpected value %s\n", wine_dbgstr_w(result)); + + V_VT(&var) = VT_BSTR; + V_BSTR(&var) = SysAllocString(L""); + result = VariantToStringWithDefault(&var, default_value); + ok(result == V_BSTR(&var), "Unexpected value %s\n", wine_dbgstr_w(result)); + VariantClear(&var); + + V_VT(&var) = VT_BSTR; + V_BSTR(&var) = SysAllocString(L" "); + result = VariantToStringWithDefault(&var, default_value); + ok(result == V_BSTR(&var), "Unexpected value %s\n", wine_dbgstr_w(result)); + VariantClear(&var); + + V_VT(&var) = VT_BSTR; + V_BSTR(&var) = SysAllocString(L"test1"); + result = VariantToStringWithDefault(&var, default_value); + ok(result == V_BSTR(&var), "Unexpected value %s\n", wine_dbgstr_w(result)); + VariantClear(&var); + + /* V_BSTRREF */ + + V_VT(&var) = VT_BYREF | VT_BSTR; + b = NULL; + V_BSTRREF(&var) = &b; + result = VariantToStringWithDefault(&var, default_value); + ok(result[0] == '\0', "Unexpected value %s\n", wine_dbgstr_w(result)); + + V_VT(&var) = VT_BYREF | VT_BSTR; + b = SysAllocString(L""); + V_BSTRREF(&var) = &b; + result = VariantToStringWithDefault(&var, default_value); + ok(result == b, "Unexpected value %s\n", wine_dbgstr_w(result)); + SysFreeString(b); + + V_VT(&var) = VT_BYREF | VT_BSTR; + b = SysAllocString(L" "); + V_BSTRREF(&var) = &b; + result = VariantToStringWithDefault(&var, default_value); + ok(result == b, "Unexpected value %s\n", wine_dbgstr_w(result)); + SysFreeString(b); + + V_VT(&var) = VT_BYREF | VT_BSTR; + b = SysAllocString(L"test1"); + V_BSTRREF(&var) = &b; + result = VariantToStringWithDefault(&var, default_value); + ok(result == b, "Unexpected value %s\n", wine_dbgstr_w(result)); + SysFreeString(b); + + /* Nested V_BSTR */ + + V_VT(&var) = VT_BYREF | VT_VARIANT; + V_VT(&var2) = VT_BSTR; + V_BSTR(&var2) = NULL; + V_VARIANTREF(&var) = &var2; + result = VariantToStringWithDefault(&var, default_value); + ok(result[0] == '\0', "Unexpected value %s\n", wine_dbgstr_w(result)); + + V_VT(&var) = VT_BYREF | VT_VARIANT; + V_VT(&var2) = VT_BSTR; + V_BSTR(&var2) = SysAllocString(L""); + V_VARIANTREF(&var) = &var2; + result = VariantToStringWithDefault(&var, default_value); + ok(result == V_BSTR(&var2), "Unexpected value %s\n", wine_dbgstr_w(result)); + VariantClear(&var2); + + V_VT(&var) = VT_BYREF | VT_VARIANT; + V_VT(&var2) = VT_BSTR; + V_BSTR(&var2) = SysAllocString(L" "); + V_VARIANTREF(&var) = &var2; + result = VariantToStringWithDefault(&var, default_value); + ok(result == V_BSTR(&var2), "Unexpected value %s\n", wine_dbgstr_w(result)); + VariantClear(&var2); + + V_VT(&var) = VT_BYREF | VT_VARIANT; + V_VT(&var2) = VT_BSTR; + V_BSTR(&var2) = SysAllocString(L"test1"); + V_VARIANTREF(&var) = &var2; + result = VariantToStringWithDefault(&var, default_value); + ok(result == V_BSTR(&var2), "Unexpected value %s\n", wine_dbgstr_w(result)); + VariantClear(&var2); + + /* Nested V_BSTRREF */ + + V_VT(&var) = VT_BYREF | VT_VARIANT; + V_VT(&var2) = VT_BYREF | VT_BSTR; + b = NULL; + V_BSTRREF(&var2) = &b; + V_VARIANTREF(&var) = &var2; + result = VariantToStringWithDefault(&var, default_value); + ok(result[0] == '\0', "Unexpected value %s\n", wine_dbgstr_w(result)); + + V_VT(&var) = VT_BYREF | VT_VARIANT; + V_VT(&var2) = VT_BYREF | VT_BSTR; + b = SysAllocString(L""); + V_BSTRREF(&var2) = &b; + V_VARIANTREF(&var) = &var2; + result = VariantToStringWithDefault(&var, default_value); + ok(result == b, "Unexpected value %s\n", wine_dbgstr_w(result)); + SysFreeString(b); + + V_VT(&var) = VT_BYREF | VT_VARIANT; + V_VT(&var2) = VT_BYREF | VT_BSTR; + b = SysAllocString(L" "); + V_BSTRREF(&var2) = &b; + V_VARIANTREF(&var) = &var2; + result = VariantToStringWithDefault(&var, default_value); + ok(result == b, "Unexpected value %s\n", wine_dbgstr_w(result)); + SysFreeString(b); + + V_VT(&var) = VT_BYREF | VT_VARIANT; + V_VT(&var2) = VT_BYREF | VT_BSTR; + b = SysAllocString(L"test1"); + V_BSTRREF(&var2) = &b; + V_VARIANTREF(&var) = &var2; + result = VariantToStringWithDefault(&var, default_value); + ok(result == b, "Unexpected value %s\n", wine_dbgstr_w(result)); + SysFreeString(b); +} + +static void test_VariantToString(void) +{ + HRESULT hr; + VARIANT v; + WCHAR buff[64]; + + buff[0] = 1; + V_VT(&v) = VT_EMPTY; + hr = VariantToString(&v, buff, 64); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!buff[0], "Unexpected buffer.\n"); + + buff[0] = 0; + V_VT(&v) = VT_I4; + V_I4(&v) = 567; + hr = VariantToString(&v, buff, 64); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!wcscmp(buff, L"567"), "Unexpected buffer %s.\n", wine_dbgstr_w(buff)); + + V_VT(&v) = VT_BSTR; + V_BSTR(&v) = SysAllocString(L"test1"); + + buff[0] = 1; + hr = VariantToString(&v, buff, 0); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + ok(!buff[0], "Unexpected buffer.\n"); + + hr = VariantToString(&v, buff, 5); + ok(hr == STRSAFE_E_INSUFFICIENT_BUFFER, "Unexpected hr %#lx.\n", hr); + hr = VariantToString(&v, buff, 6); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!wcscmp(buff, L"test1"), "Unexpected string.\n"); + VariantClear(&v); +} + +#define check_VariantToPropVariant(var, propvar, type, member, value, format) do \ +{ \ + V_VT(&(var)) = VT_##type; \ + V_##type(&(var)) = (value); \ + hr = VariantToPropVariant(&(var), &(propvar)); \ + ok_(__FILE__, __LINE__)(hr == S_OK, "VariantToPropVariant returned %#lx.\n", hr); \ + ok_(__FILE__, __LINE__)((propvar).vt == VT_##type, "Unexpected propvar.vt %d.\n", (propvar).vt); \ + ok_(__FILE__, __LINE__)((propvar).member == (value), \ + "Unexpected propvar."#member" "format".\n", (propvar).member); \ +} while (0) + +#define check_PropVariantToVariant(propvar, var, type, member, value, format) do \ +{ \ + (propvar).vt = VT_##type; \ + (propvar).member = (value); \ + hr = PropVariantToVariant(&(propvar), &(var)); \ + ok_(__FILE__, __LINE__)(hr == S_OK, "PropVariantToVariant returned %#lx.\n", hr); \ + ok_(__FILE__, __LINE__)(V_VT(&(var)) == VT_##type, "Unexpected vt %d.\n", V_VT(&(var))); \ + ok_(__FILE__, __LINE__)(V_##type(&(var)) == (value), \ + "Unexpected V_"#type"(&var) "format".\n", (propvar).member); \ +} while (0) + +static void test_VariantToPropVariant(void) +{ + PROPVARIANT propvar; + VARIANT var; + HRESULT hr; + + VariantInit(&var); + PropVariantInit(&propvar); + + hr = VariantToPropVariant(NULL, &propvar); + ok(hr == E_INVALIDARG, "VariantToPropVariant returned %#lx.\n", hr); + hr = VariantToPropVariant(&var, NULL); + ok(hr == E_INVALIDARG, "VariantToPropVariant returned %#lx.\n", hr); + + V_VT(&var) = 0xdead; + hr = VariantToPropVariant(&var, &propvar); + ok(hr == DISP_E_BADVARTYPE, "VariantToPropVariant returned %#lx.\n", hr); + V_VT(&var) = VT_ILLEGAL; + hr = VariantToPropVariant(&var, &propvar); + todo_wine + ok(hr == TYPE_E_TYPEMISMATCH, "VariantToPropVariant returned %#lx.\n", hr); + V_VT(&var) = VT_CLSID; + hr = VariantToPropVariant(&var, &propvar); + todo_wine + ok(hr == DISP_E_BADVARTYPE, "VariantToPropVariant returned %#lx.\n", hr); + + V_VT(&var) = VT_EMPTY; + hr = VariantToPropVariant(&var, &propvar); + ok(hr == S_OK, "VariantToPropVariant returned %#lx.\n", hr); + ok(propvar.vt == VT_EMPTY, "Unexpected propvar.vt %d.\n", propvar.vt); + + V_VT(&var) = VT_NULL; + hr = VariantToPropVariant(&var, &propvar); + ok(hr == S_OK, "VariantToPropVariant returned %#lx.\n", hr); + ok(propvar.vt == VT_NULL, "Unexpected propvar.vt %d.\n", propvar.vt); + + check_VariantToPropVariant(var, propvar, I1, cVal, -123, "%c"); + check_VariantToPropVariant(var, propvar, I2, iVal, -456, "%d"); + check_VariantToPropVariant(var, propvar, I4, lVal, -789, "%ld"); + check_VariantToPropVariant(var, propvar, I8, hVal.QuadPart, -101112, "%I64d"); + + check_VariantToPropVariant(var, propvar, UI1, bVal, 0xcd, "%#x"); + check_VariantToPropVariant(var, propvar, UI2, uiVal, 0xdead, "%#x"); + check_VariantToPropVariant(var, propvar, UI4, ulVal, 0xdeadbeef, "%#lx"); + check_VariantToPropVariant(var, propvar, UI8, uhVal.QuadPart, 0xdeadbeefdeadbeef, "%I64x"); + + check_VariantToPropVariant(var, propvar, BOOL, boolVal, TRUE, "%d"); + + check_VariantToPropVariant(var, propvar, R4, fltVal, 0.123f, "%f"); + check_VariantToPropVariant(var, propvar, R8, dblVal, 0.456f, "%f"); + + V_VT(&var) = VT_BSTR; + V_BSTR(&var) = SysAllocString(L"test"); + hr = VariantToPropVariant(&var, &propvar); + ok(hr == S_OK, "VariantToPropVariant returned %#lx.\n", hr); + ok(propvar.vt == VT_BSTR, "Unexpected propvar.vt %d.\n", propvar.vt); + ok(propvar.bstrVal != V_BSTR(&var), "Got same string pointer.\n"); + ok(!wcscmp(propvar.bstrVal, V_BSTR(&var)), "Unexpected propvar.bstrVal %s.\n", debugstr_w(propvar.bstrVal)); + + PropVariantClear(&propvar); + VariantClear(&var); +} + +static void test_PropVariantToVariant(void) +{ + PROPVARIANT propvar; + VARIANT var; + HRESULT hr; + + VariantInit(&var); + PropVariantInit(&propvar); + + hr = PropVariantToVariant(NULL, &var); + ok(hr == E_INVALIDARG, "PropVariantToVariant returned %#lx.\n", hr); + hr = PropVariantToVariant(&propvar, NULL); + ok(hr == E_INVALIDARG, "PropVariantToVariant returned %#lx.\n", hr); + + propvar.vt = 0xdead; + hr = PropVariantToVariant(&propvar, &var); + todo_wine + ok(hr == E_OUTOFMEMORY, "PropVariantToVariant returned %#lx.\n", hr); + propvar.vt = VT_ILLEGAL; + hr = PropVariantToVariant(&propvar, &var); + todo_wine + ok(hr == E_OUTOFMEMORY, "PropVariantToVariant returned %#lx.\n", hr); + + propvar.vt = VT_EMPTY; + hr = PropVariantToVariant(&propvar, &var); + ok(hr == S_OK, "PropVariantToVariant returned %#lx.\n", hr); + ok(V_VT(&var) == VT_EMPTY, "Unexpected V_VT(&var) %d.\n", V_VT(&var)); + + propvar.vt = VT_NULL; + hr = PropVariantToVariant(&propvar, &var); + ok(hr == S_OK, "PropVariantToVariant returned %#lx.\n", hr); + ok(V_VT(&var) == VT_NULL, "Unexpected V_VT(&var) %d.\n", V_VT(&var)); + + check_PropVariantToVariant(propvar, var, I1, cVal, 'X', "%c"); + check_PropVariantToVariant(propvar, var, I2, iVal, -456, "%d"); + check_PropVariantToVariant(propvar, var, I4, lVal, -789, "%ld"); + check_PropVariantToVariant(propvar, var, I8, hVal.QuadPart, -101112, "%I64d"); + + check_PropVariantToVariant(propvar, var, UI1, bVal, 0xcd, "%#x"); + check_PropVariantToVariant(propvar, var, UI2, uiVal, 0xdead, "%#x"); + check_PropVariantToVariant(propvar, var, UI4, ulVal, 0xdeadbeef, "%#lx"); + check_PropVariantToVariant(propvar, var, UI8, uhVal.QuadPart, 0xdeadbeefdeadbeef, "%I64x"); + + check_PropVariantToVariant(propvar, var, BOOL, boolVal, TRUE, "%d"); + + check_PropVariantToVariant(propvar, var, R4, fltVal, 0.123f, "%f"); + check_PropVariantToVariant(propvar, var, R8, dblVal, 0.456f, "%f"); + + propvar.vt = VT_BSTR; + propvar.bstrVal = SysAllocString(L"test"); + hr = PropVariantToVariant(&propvar, &var); + ok(hr == S_OK, "PropVariantToVariant returned %#lx.\n", hr); + ok(V_VT(&var) == VT_BSTR, "Unexpected V_VT(&var) %d.\n", V_VT(&var)); + ok(V_BSTR(&var) != propvar.bstrVal, "Got same string pointer.\n"); + ok(!wcscmp(V_BSTR(&var), propvar.bstrVal), "Unexpected V_BSTR(&var) %s.\n", debugstr_w(V_BSTR(&var))); + PropVariantClear(&propvar); + VariantClear(&var); + + propvar.vt = VT_CLSID; + propvar.puuid = (GUID *)&dummy_guid; + hr = PropVariantToVariant(&propvar, &var); + todo_wine + ok(hr == 39, "PropVariantToVariant returned %#lx.\n", hr); + ok(V_VT(&var) == VT_BSTR, "Unexpected V_VT(&var) %d.\n", V_VT(&var)); + ok(!wcscmp(V_BSTR(&var), dummy_guid_str), "Unexpected V_BSTR(&var) %s.\n", debugstr_w(V_BSTR(&var))); + VariantClear(&var); + + propvar.vt = VT_LPSTR; + propvar.pszVal = (char *)topic; + hr = PropVariantToVariant(&propvar, &var); + ok(hr == S_OK, "PropVariantToVariant returned %#lx.\n", hr); + ok(V_VT(&var) == VT_BSTR, "Unexpected V_VT(&var) %d.\n", V_VT(&var)); + ok(!wcscmp(V_BSTR(&var), topicW), "Unexpected V_BSTR(&var) %s.\n", debugstr_w(V_BSTR(&var))); + VariantClear(&var); + + propvar.vt = VT_LPWSTR; + propvar.pwszVal = (WCHAR *)topicW; + hr = PropVariantToVariant(&propvar, &var); + ok(hr == S_OK, "PropVariantToVariant returned %#lx.\n", hr); + ok(V_VT(&var) == VT_BSTR, "Unexpected V_VT(&var) %d.\n", V_VT(&var)); + ok(V_BSTR(&var) != topicW, "Got same string pointer.\n"); + ok(!wcscmp(V_BSTR(&var), topicW), "Unexpected V_BSTR(&var) %s.\n", debugstr_w(V_BSTR(&var))); + VariantClear(&var); } START_TEST(propsys) { + test_InitPropVariantFromGUIDAsString(); + test_InitPropVariantFromBuffer(); + test_InitPropVariantFromCLSID(); + test_InitPropVariantFromStringVector(); + test_InitVariantFromFileTime(); + test_PSStringFromPropertyKey(); test_PSPropertyKeyFromString(); test_PSRefreshPropertySchema(); - test_InitPropVariantFromGUIDAsString(); - test_InitPropVariantFromBuffer(); test_PropVariantToGUID(); test_PropVariantToStringAlloc(); - test_PropVariantCompare(); + test_PropVariantCompareEx(); test_intconversions(); test_PropVariantChangeType_LPWSTR(); test_PropVariantToBoolean(); test_PropVariantToStringWithDefault(); - test_InitPropVariantFromCLSID(); test_PropVariantToDouble(); test_PropVariantToString(); + test_PropVariantToBSTR(); test_PropVariantToBuffer(); + test_inmemorystore(); + test_persistserialized(); + test_PSCreateMemoryPropertyStore(); + test_propertystore(); + test_PSCreatePropertyStoreFromObject(); + test_VariantToStringWithDefault(); + test_VariantToString(); + test_VariantToPropVariant(); + test_PropVariantToVariant(); } diff --git a/modules/rostests/winetests/propsys/testlist.c b/modules/rostests/winetests/propsys/testlist.c index 3773d6ad652c2..364dec7c1a92c 100644 --- a/modules/rostests/winetests/propsys/testlist.c +++ b/modules/rostests/winetests/propsys/testlist.c @@ -3,12 +3,10 @@ #define STANDALONE #include -extern void func_propstore(void); extern void func_propsys(void); const struct test winetest_testlist[] = { - { "propstore", func_propstore }, { "propsys", func_propsys }, { 0, 0 } }; diff --git a/modules/rostests/winetests/riched20/editor.c b/modules/rostests/winetests/riched20/editor.c index 791f471dee2d1..6bac7e0a89b80 100644 --- a/modules/rostests/winetests/riched20/editor.c +++ b/modules/rostests/winetests/riched20/editor.c @@ -33,6 +33,8 @@ #include #include #include +#include +#include #include #include #include @@ -51,12 +53,38 @@ static CHAR string1[MAX_PATH], string2[MAX_PATH], string3[MAX_PATH]; static HMODULE hmoduleRichEdit; static BOOL is_lang_japanese; +#if defined(__i386__) && !defined(__MINGW32__) && (!defined(_MSC_VER) || !defined(__clang__)) +static void disable_beep( HWND hwnd ) +{ + /* don't attempt to disable beep if we don't have thiscall compiler support */ +} +#else +#define ITextServices_OnTxPropertyBitsChange(This,a,b) (This)->lpVtbl->OnTxPropertyBitsChange(This,a,b) +static void disable_beep( HWND hwnd ) +{ + IRichEditOle *richole; + ITextServices *services; + IID *pIID_ITextServices = (IID *)GetProcAddress( hmoduleRichEdit, "IID_ITextServices" ); + + if (SendMessageW( hwnd, EM_GETOLEINTERFACE, 0, (LPARAM)&richole )) + { + if (SUCCEEDED( IRichEditOle_QueryInterface( richole, pIID_ITextServices, (void **)&services ) )) + { + ITextServices_OnTxPropertyBitsChange( services, TXTBIT_ALLOWBEEP, 0 ); + ITextServices_Release( services ); + } + IRichEditOle_Release( richole ); + } +} +#endif + static HWND new_window(LPCSTR lpClassName, DWORD dwStyle, HWND parent) { HWND hwnd; hwnd = CreateWindowA(lpClassName, NULL, dwStyle|WS_POPUP|WS_HSCROLL|WS_VSCROLL |WS_VISIBLE, 0, 0, 200, 60, parent, NULL, hmoduleRichEdit, NULL); ok(hwnd != NULL, "class: %s, error: %d\n", lpClassName, (int) GetLastError()); + disable_beep( hwnd ); return hwnd; } @@ -66,6 +94,7 @@ static HWND new_windowW(LPCWSTR lpClassName, DWORD dwStyle, HWND parent) { |WS_VISIBLE, 0, 0, 200, 60, parent, NULL, hmoduleRichEdit, NULL); ok(hwnd != NULL, "class: %s, error: %d\n", wine_dbgstr_w(lpClassName), (int) GetLastError()); + disable_beep( hwnd ); return hwnd; } @@ -615,7 +644,7 @@ static void test_EM_POSFROMCHAR(void) "gg\n" "hh\n"; - rtl = (GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_FONTSIGNATURE, + rtl = (GetLocaleInfoA(LOCALE_SYSTEM_DEFAULT, LOCALE_FONTSIGNATURE, (LPSTR) &sig, sizeof(LOCALESIGNATURE)) && (sig.lsUsb[3] & 0x08000000) != 0); @@ -772,7 +801,7 @@ static void test_EM_SETCHARFORMAT(void) BOOL rtl; DWORD expect_effects; - rtl = (GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_FONTSIGNATURE, + rtl = (GetLocaleInfoA(LOCALE_SYSTEM_DEFAULT, LOCALE_FONTSIGNATURE, (LPSTR) &sig, sizeof(LOCALESIGNATURE)) && (sig.lsUsb[3] & 0x08000000) != 0); @@ -1791,8 +1820,8 @@ static void test_EM_GETTEXTRANGE(void) textRange.chrg.cpMin = 4; textRange.chrg.cpMax = 8; result = SendMessageA(hwndRichEdit, EM_GETTEXTRANGE, 0, (LPARAM)&textRange); - todo_wine ok(result == 5, "EM_GETTEXTRANGE returned %ld\n", result); - todo_wine ok(!strcmp("ef\x8e\xf0g", buffer), "EM_GETTEXTRANGE filled %s\n", buffer); + ok(result == 5, "EM_GETTEXTRANGE returned %ld\n", result); + ok(!strcmp("ef\x8e\xf0g", buffer), "EM_GETTEXTRANGE filled %s\n", buffer); } DestroyWindow(hwndRichEdit); @@ -1829,8 +1858,8 @@ static void test_EM_GETSELTEXT(void) SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"abcdef\x8e\xf0ghijk"); SendMessageA(hwndRichEdit, EM_SETSEL, 4, 8); result = SendMessageA(hwndRichEdit, EM_GETSELTEXT, 0, (LPARAM)buffer); - todo_wine ok(result == 5, "EM_GETSELTEXT returned %ld\n", result); - todo_wine ok(!strcmp("ef\x8e\xf0g", buffer), "EM_GETSELTEXT filled %s\n", buffer); + ok(result == 5, "EM_GETSELTEXT returned %ld\n", result); + ok(!strcmp("ef\x8e\xf0g", buffer), "EM_GETSELTEXT filled %s\n", buffer); } DestroyWindow(hwndRichEdit); @@ -1863,6 +1892,7 @@ static void test_EM_SETOPTIONS(void) hmoduleRichEdit, NULL); ok(hwndRichEdit != NULL, "class: %s, error: %d\n", RICHEDIT_CLASS20A, (int) GetLastError()); + disable_beep( hwndRichEdit ); options = SendMessageA(hwndRichEdit, EM_GETOPTIONS, 0, 0); /* WS_[VH]SCROLL cause the ECO_AUTO[VH]SCROLL options to be set */ ok(options == (ECO_AUTOVSCROLL|ECO_AUTOHSCROLL), @@ -3110,11 +3140,9 @@ static void test_scrollbar_visibility(void) GetScrollInfo(hwndRichEdit, SB_VERT, &si); ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0), "Vertical scrollbar is invisible, should be visible.\n"); - todo_wine { ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 100, "reported page/range is %d (%d..%d) expected 0 (0..100)\n", si.nPage, si.nMin, si.nMax); - } /* Ditto, see above */ SendMessageA(hwndRichEdit, WM_SETTEXT, 0, 0); @@ -3124,11 +3152,9 @@ static void test_scrollbar_visibility(void) GetScrollInfo(hwndRichEdit, SB_VERT, &si); ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0), "Vertical scrollbar is invisible, should be visible.\n"); - todo_wine { ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 100, "reported page/range is %d (%d..%d) expected 0 (0..100)\n", si.nPage, si.nMin, si.nMax); - } /* Ditto, see above */ SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"a"); @@ -3138,11 +3164,9 @@ static void test_scrollbar_visibility(void) GetScrollInfo(hwndRichEdit, SB_VERT, &si); ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0), "Vertical scrollbar is invisible, should be visible.\n"); - todo_wine { ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 100, "reported page/range is %d (%d..%d) expected 0 (0..100)\n", si.nPage, si.nMin, si.nMax); - } /* Ditto, see above */ SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"a\na"); @@ -3152,11 +3176,9 @@ static void test_scrollbar_visibility(void) GetScrollInfo(hwndRichEdit, SB_VERT, &si); ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0), "Vertical scrollbar is invisible, should be visible.\n"); - todo_wine { ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 100, "reported page/range is %d (%d..%d) expected 0 (0..100)\n", si.nPage, si.nMin, si.nMax); - } /* Ditto, see above */ SendMessageA(hwndRichEdit, WM_SETTEXT, 0, 0); @@ -3166,11 +3188,9 @@ static void test_scrollbar_visibility(void) GetScrollInfo(hwndRichEdit, SB_VERT, &si); ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0), "Vertical scrollbar is invisible, should be visible.\n"); - todo_wine { ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 100, "reported page/range is %d (%d..%d) expected 0 (0..100)\n", si.nPage, si.nMin, si.nMax); - } SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)text); SendMessageA(hwndRichEdit, WM_SETTEXT, 0, 0); @@ -5610,7 +5630,7 @@ static void test_EM_FORMATRANGE(void) {"WINE\r\n\r\nwine\r\nwine", 5, 6} }; - skip_non_english = (PRIMARYLANGID(GetUserDefaultLangID()) != LANG_ENGLISH); + skip_non_english = (PRIMARYLANGID(GetSystemDefaultLangID()) != LANG_ENGLISH); if (skip_non_english) skip("Skipping some tests on non-English platform\n"); @@ -6348,6 +6368,7 @@ static void test_WM_CHAR(void) hwnd = CreateWindowExA(0, "RichEdit20W", NULL, WS_POPUP, 0, 0, 200, 60, 0, 0, 0, 0); ok(hwnd != 0, "CreateWindowExA error %u\n", GetLastError()); + disable_beep( hwnd ); p = char_list; while (*p != '\0') { @@ -6951,6 +6972,7 @@ static void test_undo_coalescing(void) hwnd = CreateWindowExA(0, "RichEdit20W", NULL, WS_POPUP|ES_MULTILINE, 0, 0, 200, 60, 0, 0, 0, 0); ok(hwnd != 0, "CreateWindowExA error %u\n", GetLastError()); + disable_beep( hwnd ); result = SendMessageA(hwnd, EM_CANUNDO, 0, 0); ok (result == FALSE, "Can undo after window creation.\n"); @@ -7461,12 +7483,25 @@ static void test_format_rect(void) ok(EqualRect(&rc, &expected), "rect %s != %s\n", wine_dbgstr_rect(&rc), wine_dbgstr_rect(&expected)); + /* reset back to client rect and now try adding selection bar */ + SendMessageA(hwnd, EM_SETRECT, 0, 0); + expected = clientRect; + InflateRect(&expected, -1, 0); + SendMessageA(hwnd, EM_GETRECT, 0, (LPARAM)&rc); + ok(EqualRect(&rc, &expected), "rect %s != %s\n", wine_dbgstr_rect(&rc), + wine_dbgstr_rect(&expected)); + SendMessageA(hwnd, EM_SETOPTIONS, ECOOP_OR, ECO_SELECTIONBAR); + SendMessageA(hwnd, EM_GETRECT, 0, (LPARAM)&rc); + ok(EqualRect(&rc, &expected), "rect %s != %s\n", wine_dbgstr_rect(&rc), + wine_dbgstr_rect(&expected)); + SendMessageA(hwnd, EM_SETOPTIONS, ECOOP_AND, ~ECO_SELECTIONBAR); + /* Set the absolute value of the formatting rectangle. */ rc = clientRect; SendMessageA(hwnd, EM_SETRECT, 0, (LPARAM)&rc); expected = clientRect; SendMessageA(hwnd, EM_GETRECT, 0, (LPARAM)&rc); - ok(EqualRect(&rc, &expected), "[n=%d] rect %s != %s\n", n, wine_dbgstr_rect(&rc), + ok(EqualRect(&rc, &expected), "rect %s != %s\n", wine_dbgstr_rect(&rc), wine_dbgstr_rect(&expected)); /* MSDN documents the EM_SETRECT message as using the rectangle provided in @@ -9026,7 +9061,7 @@ START_TEST( editor ) * RICHED20.DLL, so the linker doesn't actually link to it. */ hmoduleRichEdit = LoadLibraryA("riched20.dll"); ok(hmoduleRichEdit != NULL, "error: %d\n", (int) GetLastError()); - is_lang_japanese = (PRIMARYLANGID(GetUserDefaultLangID()) == LANG_JAPANESE); + is_lang_japanese = (PRIMARYLANGID(GetSystemDefaultLangID()) == LANG_JAPANESE); test_window_classes(); test_WM_CHAR(); diff --git a/modules/rostests/winetests/riched20/richole.c b/modules/rostests/winetests/riched20/richole.c index 492bdc3fa9a87..3885eb527fca0 100644 --- a/modules/rostests/winetests/riched20/richole.c +++ b/modules/rostests/winetests/riched20/richole.c @@ -149,6 +149,7 @@ static void test_Interfaces(void) LRESULT res; HWND w; ULONG refcount; + IUnknown *unk, *unk2; w = new_richedit(NULL); if (!w) { @@ -180,6 +181,14 @@ static void test_Interfaces(void) hres = ITextDocument_GetSelection(txtDoc, &txtSel); ok(hres == S_OK, "got 0x%08x\n", hres); + hres = ITextDocument_QueryInterface(txtDoc, &IID_IUnknown, (void **)&unk); + ok(hres == S_OK, "got 0x%08x\n", hres); + hres = ITextSelection_QueryInterface(txtSel, &IID_IUnknown, (void **)&unk2); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(unk != unk2, "unknowns are the same\n"); + IUnknown_Release(unk2); + IUnknown_Release(unk); + EXPECT_REF(txtDoc, 4); EXPECT_REF(txtSel, 2); @@ -3203,29 +3212,62 @@ static void fill_reobject_struct(REOBJECT *reobj, LONG cp, LPOLEOBJECT poleobj, reobj->dwUser = user; } -#define CHECK_REOBJECT_STRUCT(reobj,poleobj,pstg,polesite,user) \ - _check_reobject_struct(reobj, poleobj, pstg, polesite, user, __LINE__) -static void _check_reobject_struct(REOBJECT reobj, LPOLEOBJECT poleobj, LPSTORAGE pstg, - LPOLECLIENTSITE polesite, DWORD user, int line) +#define CHECK_REOBJECT_STRUCT(reole,index,flags,cp,poleobj,pstg,polesite,user) \ + _check_reobject_struct(reole, index, flags, cp, poleobj, pstg, polesite, user, __LINE__) +static void _check_reobject_struct(IRichEditOle *reole, LONG index, DWORD flags, LONG cp, + LPOLEOBJECT poleobj, LPSTORAGE pstg, LPOLECLIENTSITE polesite, DWORD user, int line) { + REOBJECT reobj; + HRESULT hr; + + reobj.cbStruct = sizeof(reobj); + reobj.cp = cp; + hr = IRichEditOle_GetObject(reole, index, &reobj, flags); + ok(hr == S_OK, "IRichEditOle_GetObject failed: %#x.\n", hr); ok_(__FILE__,line)(reobj.poleobj == poleobj, "got wrong object interface.\n"); ok_(__FILE__,line)(reobj.pstg == pstg, "got wrong storage interface.\n"); ok_(__FILE__,line)(reobj.polesite == polesite, "got wrong site interface.\n"); ok_(__FILE__,line)(reobj.dwUser == user, "got wrong user-defined value.\n"); } +#define INSERT_REOBJECT(reole,reobj,cp,user) \ + _insert_reobject(reole, reobj, cp, user, __LINE__) +static void _insert_reobject(IRichEditOle *reole, REOBJECT *reobj, LONG cp, DWORD user, int line) +{ + IOleClientSite *clientsite; + HRESULT hr; + hr = IRichEditOle_GetClientSite(reole, &clientsite); + ok_(__FILE__,line)(hr == S_OK, "IRichEditOle_GetClientSite got hr %#x.\n", hr); + fill_reobject_struct(reobj, cp, NULL, NULL, clientsite, 10, 10, DVASPECT_CONTENT, 0, user); + hr = IRichEditOle_InsertObject(reole, reobj); + ok_(__FILE__,line)(hr == S_OK, "IRichEditOle_InsertObject got hr %#x.\n", hr); + IOleClientSite_Release(clientsite); +} + static void test_InsertObject(void) { static CHAR test_text1[] = "abcdefg"; IRichEditOle *reole = NULL; ITextDocument *doc = NULL; - IOleClientSite *clientsite; - REOBJECT reo1, reo2, reo3, received_reo1, received_reo2, received_reo3, received_reo4; + REOBJECT reo1, reo2, reo3, received_reo; HRESULT hr; HWND hwnd; - LONG count; + const WCHAR *expected_string; + const CHAR *expected_stringA; + ITextSelection *selection; + IDataObject *dataobject; + TEXTRANGEA textrange; + FORMATETC formatetc; + CHARRANGE charrange; + GETTEXTEX gettextex; + STGMEDIUM stgmedium; + WCHAR buffer[1024]; + CHAR bufferA[1024]; + LONG count, result; + ITextRange *range; + BSTR bstr; - create_interfaces(&hwnd, &reole, &doc, NULL); + create_interfaces(&hwnd, &reole, &doc, &selection); SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1); hr = IRichEditOle_InsertObject(reole, NULL); @@ -3233,161 +3275,278 @@ static void test_InsertObject(void) /* insert object1 in (0, 1)*/ SendMessageA(hwnd, EM_SETSEL, 0, 1); - hr = IRichEditOle_GetClientSite(reole, &clientsite); - ok(hr == S_OK, "IRichEditOle_GetClientSite failed: 0x%08x\n", hr); - fill_reobject_struct(&reo1, REO_CP_SELECTION, NULL, NULL, clientsite, 10, 10, DVASPECT_CONTENT, 0, 1); - hr = IRichEditOle_InsertObject(reole, &reo1); - ok(hr == S_OK, "IRichEditOle_InsertObject failed: 0x%08x\n", hr); + INSERT_REOBJECT(reole, &reo1, REO_CP_SELECTION, 1); count = IRichEditOle_GetObjectCount(reole); ok(count == 1, "got wrong object count: %d\n", count); - IOleClientSite_Release(clientsite); /* insert object2 in (2, 3)*/ SendMessageA(hwnd, EM_SETSEL, 2, 3); - hr = IRichEditOle_GetClientSite(reole, &clientsite); - ok(hr == S_OK, "IRichEditOle_GetClientSite failed: 0x%08x\n", hr); - fill_reobject_struct(&reo2, REO_CP_SELECTION, NULL, NULL, clientsite, 10, 10, DVASPECT_CONTENT, 0, 2); - hr = IRichEditOle_InsertObject(reole, &reo2); - ok(hr == S_OK, "IRichEditOle_InsertObject failed: 0x%08x\n", hr); + INSERT_REOBJECT(reole, &reo2, REO_CP_SELECTION, 2); count = IRichEditOle_GetObjectCount(reole); ok(count == 2, "got wrong object count: %d\n", count); - IOleClientSite_Release(clientsite); /* insert object3 in (1, 2)*/ SendMessageA(hwnd, EM_SETSEL, 1, 2); - hr = IRichEditOle_GetClientSite(reole, &clientsite); - ok(hr == S_OK, "IRichEditOle_GetClientSite failed: 0x%08x\n", hr); - fill_reobject_struct(&reo3, REO_CP_SELECTION, NULL, NULL, clientsite, 10, 10, DVASPECT_CONTENT, 0, 3); - hr = IRichEditOle_InsertObject(reole, &reo3); - ok(hr == S_OK, "IRichEditOle_InsertObject failed: 0x%08x\n", hr); + INSERT_REOBJECT(reole, &reo3, REO_CP_SELECTION, 3); count = IRichEditOle_GetObjectCount(reole); ok(count == 3, "got wrong object count: %d\n", count); - IOleClientSite_Release(clientsite); /* tests below show that order of rebject (from 0 to 2) is: reo1,reo3,reo2 */ - received_reo1.cbStruct = sizeof(received_reo1); - hr = IRichEditOle_GetObject(reole, 0, &received_reo1, REO_GETOBJ_ALL_INTERFACES); - ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr); - CHECK_REOBJECT_STRUCT(received_reo1, NULL, NULL, reo1.polesite, 1); - - received_reo2.cbStruct = sizeof(received_reo2); - hr = IRichEditOle_GetObject(reole, 1, &received_reo2, REO_GETOBJ_ALL_INTERFACES); - ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr); - CHECK_REOBJECT_STRUCT(received_reo2, NULL, NULL, reo3.polesite, 3); - - received_reo3.cbStruct = sizeof(received_reo3); - hr = IRichEditOle_GetObject(reole, 2, &received_reo3, REO_GETOBJ_ALL_INTERFACES); - ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr); - CHECK_REOBJECT_STRUCT(received_reo3, NULL, NULL, reo2.polesite, 2); + CHECK_REOBJECT_STRUCT(reole, 0, REO_GETOBJ_ALL_INTERFACES, 0, NULL, NULL, reo1.polesite, 1); + CHECK_REOBJECT_STRUCT(reole, 1, REO_GETOBJ_ALL_INTERFACES, 0, NULL, NULL, reo3.polesite, 3); + CHECK_REOBJECT_STRUCT(reole, 2, REO_GETOBJ_ALL_INTERFACES, 0, NULL, NULL, reo2.polesite, 2); hr = IRichEditOle_GetObject(reole, 2, NULL, REO_GETOBJ_ALL_INTERFACES); ok(hr == E_INVALIDARG, "IRichEditOle_GetObject should fail: 0x%08x\n", hr); - received_reo4.cbStruct = 0; - hr = IRichEditOle_GetObject(reole, 2, &received_reo4, REO_GETOBJ_ALL_INTERFACES); + received_reo.cbStruct = 0; + hr = IRichEditOle_GetObject(reole, 2, &received_reo, REO_GETOBJ_ALL_INTERFACES); ok(hr == E_INVALIDARG, "IRichEditOle_GetObject should fail: 0x%08x\n", hr); - received_reo4.cbStruct = sizeof(received_reo4); - hr = IRichEditOle_GetObject(reole, 2, &received_reo4, REO_GETOBJ_PSTG); - ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr); - CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, NULL, 2); - - hr = IRichEditOle_GetObject(reole, 2, &received_reo4, REO_GETOBJ_POLESITE); - ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr); - CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo2.polesite, 2); + CHECK_REOBJECT_STRUCT(reole, 2, REO_GETOBJ_PSTG, 0, NULL, NULL, NULL, 2); + CHECK_REOBJECT_STRUCT(reole, 2, REO_GETOBJ_POLESITE, 0, NULL, NULL, reo2.polesite, 2); - hr = IRichEditOle_GetObject(reole, 4, &received_reo4, REO_GETOBJ_POLESITE); + hr = IRichEditOle_GetObject(reole, 3, &received_reo, REO_GETOBJ_POLESITE); ok(hr == E_INVALIDARG, "IRichEditOle_GetObject should fail: 0x%08x\n", hr); - hr = IRichEditOle_GetObject(reole, 1024, &received_reo4, REO_GETOBJ_POLESITE); + hr = IRichEditOle_GetObject(reole, 4, &received_reo, REO_GETOBJ_POLESITE); ok(hr == E_INVALIDARG, "IRichEditOle_GetObject should fail: 0x%08x\n", hr); - /* received_reo4 will be zeroed before be used */ - hr = IRichEditOle_GetObject(reole, 2, &received_reo4, REO_GETOBJ_NO_INTERFACES); - ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr); - CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, NULL, 2); + hr = IRichEditOle_GetObject(reole, 1024, &received_reo, REO_GETOBJ_POLESITE); + ok(hr == E_INVALIDARG, "IRichEditOle_GetObject should fail: 0x%08x\n", hr); - received_reo4.cbStruct = sizeof(received_reo4); - received_reo4.cp = 0; - hr = IRichEditOle_GetObject(reole, REO_IOB_USE_CP, &received_reo4, REO_GETOBJ_ALL_INTERFACES); - ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr); - CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo1.polesite, 1); + hr = IRichEditOle_GetObject(reole, -10, &received_reo, REO_GETOBJ_POLESITE); + ok(hr == E_INVALIDARG, "IRichEditOle_GetObject should fail: 0x%08x\n", hr); - received_reo4.cbStruct = sizeof(received_reo4); - received_reo4.cp = 1; - hr = IRichEditOle_GetObject(reole, REO_IOB_USE_CP, &received_reo4, REO_GETOBJ_ALL_INTERFACES); + /* received_reo will be zeroed before be used */ + received_reo.cbStruct = sizeof(received_reo); + received_reo.polesite = (IOleClientSite *)0xdeadbeef; + hr = IRichEditOle_GetObject(reole, 2, &received_reo, REO_GETOBJ_NO_INTERFACES); ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr); - CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo3.polesite, 3); + ok(received_reo.polesite == (IOleClientSite *)NULL, "Got wrong site interface.\n"); - received_reo4.cbStruct = sizeof(received_reo4); - received_reo4.cp = 2; - hr = IRichEditOle_GetObject(reole, REO_IOB_USE_CP, &received_reo4, REO_GETOBJ_ALL_INTERFACES); - ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr); - CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo2.polesite, 2); + CHECK_REOBJECT_STRUCT(reole, REO_IOB_USE_CP, REO_GETOBJ_ALL_INTERFACES, 0, NULL, NULL, reo1.polesite, 1); + CHECK_REOBJECT_STRUCT(reole, REO_IOB_USE_CP, REO_GETOBJ_ALL_INTERFACES, 1, NULL, NULL, reo3.polesite, 3); + CHECK_REOBJECT_STRUCT(reole, REO_IOB_USE_CP, REO_GETOBJ_ALL_INTERFACES, 2, NULL, NULL, reo2.polesite, 2); - received_reo4.cbStruct = sizeof(received_reo4); - received_reo4.cp = 4; - hr = IRichEditOle_GetObject(reole, REO_IOB_USE_CP, &received_reo4, REO_GETOBJ_ALL_INTERFACES); + received_reo.cbStruct = sizeof(received_reo); + received_reo.polesite = (IOleClientSite *)0xdeadbeef; + received_reo.dwUser = 4; + received_reo.cp = 4; + hr = IRichEditOle_GetObject(reole, REO_IOB_USE_CP, &received_reo, REO_GETOBJ_ALL_INTERFACES); ok(hr == E_INVALIDARG, "IRichEditOle_GetObject should fail: 0x%08x\n", hr); - /* received_reo4 didn't be zeroed in E_INVALIDARG case */ - CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo2.polesite, 2); + ok(received_reo.polesite == (IOleClientSite *)0xdeadbeef, "Got wrong site interface.\n"); + ok(received_reo.dwUser == 4, "Got wrong user-defined value: %d.\n", received_reo.dwUser); SendMessageA(hwnd, EM_SETSEL, 0, 1); - received_reo4.cbStruct = sizeof(received_reo4); - received_reo4.cp = 1; - hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &received_reo4, REO_GETOBJ_ALL_INTERFACES); - ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr); - CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo1.polesite, 1); + CHECK_REOBJECT_STRUCT(reole, REO_IOB_SELECTION, REO_GETOBJ_ALL_INTERFACES, 0, NULL, NULL, reo1.polesite, 1); SendMessageA(hwnd, EM_SETSEL, 1, 2); - received_reo4.cbStruct = sizeof(received_reo4); - received_reo4.cp = 0; - hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &received_reo4, REO_GETOBJ_ALL_INTERFACES); - ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr); - CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo3.polesite, 3); + CHECK_REOBJECT_STRUCT(reole, REO_IOB_SELECTION, REO_GETOBJ_ALL_INTERFACES, 0, NULL, NULL, reo3.polesite, 3); SendMessageA(hwnd, EM_SETSEL, 2, 3); - received_reo4.cbStruct = sizeof(received_reo4); - received_reo4.cp = 0; - hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &received_reo4, REO_GETOBJ_ALL_INTERFACES); - ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr); - CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo2.polesite, 2); + CHECK_REOBJECT_STRUCT(reole, REO_IOB_SELECTION, REO_GETOBJ_ALL_INTERFACES, 0, NULL, NULL, reo2.polesite, 2); SendMessageA(hwnd, EM_SETSEL, 0, 2); - received_reo4.cbStruct = sizeof(received_reo4); - received_reo4.cp = 0; - hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &received_reo4, REO_GETOBJ_ALL_INTERFACES); - ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr); - CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo1.polesite, 1); + CHECK_REOBJECT_STRUCT(reole, REO_IOB_SELECTION, REO_GETOBJ_ALL_INTERFACES, 0, NULL, NULL, reo1.polesite, 1); SendMessageA(hwnd, EM_SETSEL, 1, 3); - received_reo4.cbStruct = sizeof(received_reo4); - received_reo4.cp = 0; - hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &received_reo4, REO_GETOBJ_ALL_INTERFACES); - ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr); - CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo3.polesite, 3); + CHECK_REOBJECT_STRUCT(reole, REO_IOB_SELECTION, REO_GETOBJ_ALL_INTERFACES, 0, NULL, NULL, reo3.polesite, 3); SendMessageA(hwnd, EM_SETSEL, 2, 0); - received_reo4.cbStruct = sizeof(received_reo4); - received_reo4.cp = 0; - hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &received_reo4, REO_GETOBJ_ALL_INTERFACES); - ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr); - CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo1.polesite, 1); + CHECK_REOBJECT_STRUCT(reole, REO_IOB_SELECTION, REO_GETOBJ_ALL_INTERFACES, 0, NULL, NULL, reo1.polesite, 1); SendMessageA(hwnd, EM_SETSEL, 0, 6); - received_reo4.cbStruct = sizeof(received_reo4); - received_reo4.cp = 0; - hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &received_reo4, REO_GETOBJ_ALL_INTERFACES); - ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr); - CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo1.polesite, 1); + CHECK_REOBJECT_STRUCT(reole, REO_IOB_SELECTION, REO_GETOBJ_ALL_INTERFACES, 0, NULL, NULL, reo1.polesite, 1); SendMessageA(hwnd, EM_SETSEL, 4, 5); - received_reo4.cbStruct = sizeof(received_reo4); - received_reo4.cp = 0; - hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &received_reo4, REO_GETOBJ_ALL_INTERFACES); + received_reo.cbStruct = sizeof(received_reo); + received_reo.cp = 0; + hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &received_reo, REO_GETOBJ_ALL_INTERFACES); ok(hr == E_INVALIDARG, "IRichEditOle_GetObject should fail: 0x%08x\n", hr); - release_interfaces(&hwnd, &reole, &doc, NULL); + SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1); + + /* "abc|d|efg" */ + INSERT_REOBJECT(reole, &reo1, 3, 1); + INSERT_REOBJECT(reole, &reo2, 5, 2); + + SendMessageW(hwnd, EM_SETSEL, 2, 3); + result = SendMessageW(hwnd, EM_SELECTIONTYPE, 0, 0); + ok(result == SEL_TEXT, "Got selection type: %x.\n", result); + + SendMessageW(hwnd, EM_SETSEL, 3, 4); + result = SendMessageW(hwnd, EM_SELECTIONTYPE, 0, 0); + todo_wine ok(result == SEL_OBJECT, "Got selection type: %x.\n", result); + todo_wine CHECK_REOBJECT_STRUCT(reole, REO_IOB_SELECTION, REO_GETOBJ_ALL_INTERFACES, 1, NULL, NULL, reo1.polesite, 1); + + SendMessageW(hwnd, EM_SETSEL, 2, 4); + result = SendMessageW(hwnd, EM_SELECTIONTYPE, 0, 0); + todo_wine ok(result == (SEL_TEXT | SEL_OBJECT), "Got selection type: %x.\n", result); + + SendMessageW(hwnd, EM_SETSEL, 5, 6); + todo_wine CHECK_REOBJECT_STRUCT(reole, REO_IOB_SELECTION, REO_GETOBJ_ALL_INTERFACES, 1, NULL, NULL, reo2.polesite, 2); + +#ifdef __REACTOS__ + expected_string = L"abc\xfffc"L"d\xfffc"L"efg"; +#else + expected_string = L"abc\xfffc""d\xfffc""efg"; +#endif + + gettextex.cb = sizeof(buffer); + gettextex.flags = GT_DEFAULT; + gettextex.codepage = 1200; + gettextex.lpDefaultChar = NULL; + gettextex.lpUsedDefChar = NULL; + result = SendMessageW(hwnd, EM_GETTEXTEX, (WPARAM)&gettextex, (LPARAM)buffer); + ok(result == lstrlenW(expected_string), "Got wrong length: %d.\n", result); + todo_wine ok(!lstrcmpW(buffer, expected_string), "Got wrong content: %s.\n", debugstr_w(buffer)); + + gettextex.flags = GT_RAWTEXT; + memset(buffer, 0, sizeof(buffer)); + result = SendMessageW(hwnd, EM_GETTEXTEX, (WPARAM)&gettextex, (LPARAM)buffer); + ok(result == lstrlenW(expected_string), "Got wrong length: %d.\n", result); + todo_wine ok(!lstrcmpW(buffer, expected_string), "Got wrong content: %s.\n", debugstr_w(buffer)); + + expected_stringA = "abc d efg"; + memset(bufferA, 0, sizeof(bufferA)); + SendMessageA(hwnd, EM_SETSEL, 0, -1); + result = SendMessageA(hwnd, EM_GETSELTEXT, (WPARAM)sizeof(bufferA), (LPARAM)bufferA); + ok(result == strlen(expected_stringA), "Got wrong length: %d.\n", result); + todo_wine ok(!strcmp(bufferA, expected_stringA), "Got wrong content: %s.\n", bufferA); + + memset(bufferA, 0, sizeof(bufferA)); + textrange.lpstrText = bufferA; + textrange.chrg.cpMin = 0; + textrange.chrg.cpMax = 11; + result = SendMessageA(hwnd, EM_GETTEXTRANGE, 0, (LPARAM)&textrange); + ok(result == strlen(expected_stringA), "Got wrong length: %d.\n", result); + todo_wine ok(!strcmp(bufferA, expected_stringA), "Got wrong content: %s.\n", bufferA); + +#ifdef __REACTOS__ + expected_string = L"abc\xfffc"L"d\xfffc"L"efg\r"; +#else + expected_string = L"abc\xfffc""d\xfffc""efg\r"; +#endif + + hr = ITextDocument_Range(doc, 0, 11, &range); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = ITextRange_GetText(range, &bstr); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(lstrlenW(bstr) == lstrlenW(expected_string), "Got wrong length: %d.\n", lstrlenW(bstr)); + todo_wine ok(!lstrcmpW(bstr, expected_string), "Got text: %s.\n", wine_dbgstr_w(bstr)); + SysFreeString(bstr); + hr = ITextRange_SetRange(range, 3, 4); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = ITextRange_GetChar(range, &result); + ok(hr == S_OK, "Got hr %#x.\n", hr); + todo_wine ok(result == 0xfffc, "Got char: %c\n", result); + ITextRange_Release(range); + + SendMessageW(hwnd, EM_SETSEL, 0, -1); + hr = ITextSelection_GetText(selection, &bstr); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(lstrlenW(bstr) == lstrlenW(expected_string), "Got wrong length: %d.\n", lstrlenW(bstr)); + todo_wine ok(!lstrcmpW(bstr, expected_string), "Got text: %s.\n", wine_dbgstr_w(bstr)); + SysFreeString(bstr); + SendMessageW(hwnd, EM_SETSEL, 3, 4); + result = 0; + hr = ITextSelection_GetChar(selection, &result); + ok(hr == S_OK, "Got hr %#x.\n", hr); + todo_wine ok(result == 0xfffc, "Got char: %c\n", result); + + SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)""); + result = SendMessageW(hwnd, EM_SETTEXTMODE, (WPARAM)TM_PLAINTEXT, 0); + ok(!result, "Got result %x.\n", result); + /* "abc|d|efg" */ + SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1); + INSERT_REOBJECT(reole, &reo1, 3, 1); + INSERT_REOBJECT(reole, &reo2, 5, 2); + + expected_string = L"abc d efg"; + charrange.cpMin = 0; + charrange.cpMax = 11; + hr = IRichEditOle_GetClipboardData(reole, &charrange, 1, &dataobject); + ok(hr == S_OK, "Got hr %#x.\n", hr); + formatetc.cfFormat = CF_UNICODETEXT; + formatetc.dwAspect = DVASPECT_CONTENT; + formatetc.ptd = NULL; + formatetc.tymed = TYMED_HGLOBAL; + formatetc.lindex = -1; + hr = IDataObject_GetData(dataobject, &formatetc, &stgmedium); + ok(hr == S_OK, "Got hr %#x.\n", hr); + todo_wine ok(lstrlenW(stgmedium.hGlobal) == lstrlenW(expected_string), "Got wrong length: %d.\n", result); + todo_wine ok(!lstrcmpW(stgmedium.hGlobal, expected_string), "Got wrong content: %s.\n", debugstr_w(stgmedium.hGlobal)); + +#ifdef __REACTOS__ + expected_string = L"abc\xfffc"L"d\xfffc"L"efg"; +#else + expected_string = L"abc\xfffc""d\xfffc""efg"; +#endif + + gettextex.cb = sizeof(buffer); + gettextex.flags = GT_DEFAULT; + gettextex.codepage = 1200; + gettextex.lpDefaultChar = NULL; + gettextex.lpUsedDefChar = NULL; + result = SendMessageW(hwnd, EM_GETTEXTEX, (WPARAM)&gettextex, (LPARAM)buffer); + ok(result == lstrlenW(expected_string), "Got wrong length: %d.\n", result); + todo_wine ok(!lstrcmpW(buffer, expected_string), "Got wrong content: %s.\n", debugstr_w(buffer)); + + gettextex.flags = GT_RAWTEXT; + memset(buffer, 0, sizeof(buffer)); + result = SendMessageW(hwnd, EM_GETTEXTEX, (WPARAM)&gettextex, (LPARAM)buffer); + ok(result == lstrlenW(expected_string), "Got wrong length: %d.\n", result); + todo_wine ok(!lstrcmpW(buffer, expected_string), "Got wrong content: %s.\n", debugstr_w(buffer)); + + expected_stringA = "abc d efg"; + memset(bufferA, 0, sizeof(bufferA)); + SendMessageA(hwnd, EM_SETSEL, 0, -1); + result = SendMessageA(hwnd, EM_GETSELTEXT, (WPARAM)sizeof(bufferA), (LPARAM)bufferA); + ok(result == strlen(expected_stringA), "Got wrong length: %d.\n", result); + todo_wine ok(!strcmp(bufferA, expected_stringA), "Got wrong content: %s.\n", bufferA); + + memset(bufferA, 0, sizeof(bufferA)); + textrange.lpstrText = bufferA; + textrange.chrg.cpMin = 0; + textrange.chrg.cpMax = 11; + result = SendMessageA(hwnd, EM_GETTEXTRANGE, 0, (LPARAM)&textrange); + ok(result == strlen(expected_stringA), "Got wrong length: %d.\n", result); + todo_wine ok(!strcmp(bufferA, expected_stringA), "Got wrong content: %s.\n", bufferA); + +#ifdef __REACTOS__ + expected_string = L"abc\xfffc"L"d\xfffc"L"efg"; +#else + expected_string = L"abc\xfffc""d\xfffc""efg"; +#endif + + hr = ITextDocument_Range(doc, 0, 11, &range); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = ITextRange_GetText(range, &bstr); + ok(hr == S_OK, "Got hr %#x.\n", hr); + todo_wine ok(lstrlenW(bstr) == lstrlenW(expected_string), "Got wrong length: %d.\n", lstrlenW(bstr)); + todo_wine ok(!lstrcmpW(bstr, expected_string), "Got text: %s.\n", wine_dbgstr_w(bstr)); + SysFreeString(bstr); + hr = ITextRange_SetRange(range, 3, 4); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = ITextRange_GetChar(range, &result); + ok(hr == S_OK, "Got hr %#x.\n", hr); + todo_wine ok(result == 0xfffc, "Got char: %c\n", result); + ITextRange_Release(range); + + SendMessageW(hwnd, EM_SETSEL, 0, -1); + hr = ITextSelection_GetText(selection, &bstr); + ok(hr == S_OK, "Got hr %#x.\n", hr); + todo_wine ok(lstrlenW(bstr) == lstrlenW(expected_string), "Got wrong length: %d.\n", lstrlenW(bstr)); + todo_wine ok(!lstrcmpW(bstr, expected_string), "Got text: %s.\n", wine_dbgstr_w(bstr)); + SysFreeString(bstr); + SendMessageW(hwnd, EM_SETSEL, 3, 4); + result = 0; + hr = ITextSelection_GetChar(selection, &result); + ok(hr == S_OK, "Got hr %#x.\n", hr); + todo_wine ok(result == 0xfffc, "Got char: %c\n", result); + + release_interfaces(&hwnd, &reole, &doc, &selection); } static void test_GetStoryLength(void) @@ -3694,7 +3853,7 @@ static void test_Expand(void) ITextRange_Release(range); } -static void test_MoveEnd(void) +static void test_MoveEnd_story(void) { static const char test_text1[] = "Word1 Word2"; IRichEditOle *reole = NULL; @@ -3808,272 +3967,288 @@ static void test_MoveEnd(void) ITextRange_Release(range); } -static void test_ITextRange_SetStart(void) +static void test_character_movestart(ITextRange *range, int textlen, int i, int j, LONG target) { - HWND w; - IRichEditOle *reOle = NULL; - ITextDocument *txtDoc = NULL; - ITextRange *txtRge = NULL; - HRESULT hres; - LONG first, lim, start, end; - static const CHAR test_text1[] = "TestSomeText"; - - create_interfaces(&w, &reOle, &txtDoc, NULL); - SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1); - - first = 4, lim = 8; - ITextDocument_Range(txtDoc, first, lim, &txtRge); - hres = ITextRange_SetStart(txtRge, first); - ok(hres == S_FALSE, "ITextRange_SetStart\n"); - -#define TEST_TXTRGE_SETSTART(cp, expected_start, expected_end) \ - hres = ITextRange_SetStart(txtRge, cp); \ - ok(hres == S_OK, "ITextRange_SetStart\n"); \ - ITextRange_GetStart(txtRge, &start); \ - ITextRange_GetEnd(txtRge, &end); \ - ok(start == expected_start, "got wrong start value: %d\n", start); \ - ok(end == expected_end, "got wrong end value: %d\n", end); - - TEST_TXTRGE_SETSTART(2, 2, 8) - TEST_TXTRGE_SETSTART(-1, 0, 8) - TEST_TXTRGE_SETSTART(13, 12, 12) - - release_interfaces(&w, &reOle, &txtDoc, NULL); + HRESULT hr; + LONG delta = 0; + LONG expected_delta; + LONG expected_start = target; + + if (expected_start < 0) + expected_start = 0; + else if (expected_start > textlen) + expected_start = textlen; + expected_delta = expected_start - i; + hr = ITextRange_SetRange(range, i, j); + ok(SUCCEEDED(hr), "got 0x%08x\n", hr); + hr = ITextRange_MoveStart(range, tomCharacter, target - i, &delta); + if (expected_start == i) { + ok(hr == S_FALSE, "(%d,%d) move by %d got hr=0x%08x\n", i, j, target - i, hr); + ok(delta == 0, "(%d,%d) move by %d got delta %d\n", i, j, target - i, delta); + CHECK_RANGE(range, i, j); + } else { + ok(hr == S_OK, "(%d,%d) move by %d got hr=0x%08x\n", i, j, target - i, hr); + ok(delta == expected_delta, "(%d,%d) move by %d got delta %d\n", i, j, target - i, delta); + if (expected_start <= j) + CHECK_RANGE(range, expected_start, j); + else + CHECK_RANGE(range, expected_start, expected_start); + } } -static void test_ITextRange_SetEnd(void) +static void test_character_moveend(ITextRange *range, int textlen, int i, int j, LONG target) { - HWND w; - IRichEditOle *reOle = NULL; - ITextDocument *txtDoc = NULL; - ITextRange *txtRge = NULL; - HRESULT hres; - LONG first, lim, start, end; - static const CHAR test_text1[] = "TestSomeText"; - - create_interfaces(&w, &reOle, &txtDoc, NULL); - SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1); - - first = 4, lim = 8; - ITextDocument_Range(txtDoc, first, lim, &txtRge); - hres = ITextRange_SetEnd(txtRge, lim); - ok(hres == S_FALSE, "ITextRange_SetEnd\n"); - -#define TEST_TXTRGE_SETEND(cp, expected_start, expected_end) \ - hres = ITextRange_SetEnd(txtRge, cp); \ - ok(hres == S_OK, "ITextRange_SetEnd\n"); \ - ITextRange_GetStart(txtRge, &start); \ - ITextRange_GetEnd(txtRge, &end); \ - ok(start == expected_start, "got wrong start value: %d\n", start); \ - ok(end == expected_end, "got wrong end value: %d\n", end); - - TEST_TXTRGE_SETEND(6, 4, 6) - TEST_TXTRGE_SETEND(14, 4, 13) - TEST_TXTRGE_SETEND(-1, 0, 0) - - ITextRange_Release(txtRge); - release_interfaces(&w, &reOle, &txtDoc, NULL); + HRESULT hr; + LONG delta; + LONG expected_delta; + LONG expected_end = target; + + if (expected_end < 0) + expected_end = 0; + else if (expected_end > textlen + 1) + expected_end = textlen + 1; + expected_delta = expected_end - j; + hr = ITextRange_SetRange(range, i, j); + ok(SUCCEEDED(hr), "got 0x%08x\n", hr); + hr = ITextRange_MoveEnd(range, tomCharacter, target - j, &delta); + if (expected_end == j) { + ok(hr == S_FALSE, "(%d,%d) move by %d got hr=0x%08x\n", i, j, target - j, hr); + ok(delta == 0, "(%d,%d) move by %d got delta %d\n", i, j, target - j, delta); + CHECK_RANGE(range, i, j); + } else { + ok(hr == S_OK, "(%d,%d) move by %d got hr=0x%08x\n", i, j, target - j, hr); + ok(delta == expected_delta, "(%d,%d) move by %d got delta %d\n", i, j, target - j, delta); + if (i <= expected_end) + CHECK_RANGE(range, i, expected_end); + else + CHECK_RANGE(range, expected_end, expected_end); + } } -static void test_ITextSelection_SetStart(void) +static void test_character_move(ITextRange *range, int textlen, int i, int j, LONG target) { - HWND w; - IRichEditOle *reOle = NULL; - ITextDocument *txtDoc = NULL; - ITextSelection *txtSel = NULL; - HRESULT hres; - LONG first, lim, start, end; - static const CHAR test_text1[] = "TestSomeText"; - - create_interfaces(&w, &reOle, &txtDoc, &txtSel); - SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1); - - first = 4, lim = 8; - SendMessageA(w, EM_SETSEL, first, lim); - hres = ITextSelection_SetStart(txtSel, first); - ok(hres == S_FALSE, "ITextSelection_SetStart\n"); - -#define TEST_TXTSEL_SETSTART(cp, expected_start, expected_end) \ - hres = ITextSelection_SetStart(txtSel, cp); \ - ok(hres == S_OK, "ITextSelection_SetStart\n"); \ - SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end); \ - ok(start == expected_start, "got wrong start value: %d\n", start); \ - ok(end == expected_end, "got wrong end value: %d\n", end); - - TEST_TXTSEL_SETSTART(2, 2, 8) - TEST_TXTSEL_SETSTART(-1, 0, 8) - TEST_TXTSEL_SETSTART(13, 12, 12) + HRESULT hr; + LONG move_by; + LONG delta = 0; + LONG expected_delta; + LONG expected_location = target; + + if (expected_location < 0) + expected_location = 0; + else if (expected_location > textlen) + expected_location = textlen; + + if (target <= i) { + move_by = target - i; + expected_delta = expected_location - i; + if (i != j) { + --move_by; + --expected_delta; + } + } else if (j <= target) { + move_by = target - j; + expected_delta = expected_location - j; + if (i != j) { + ++move_by; + ++expected_delta; + } + } else { + /* There's no way to move to a point between start and end: */ + return; + } - release_interfaces(&w, &reOle, &txtDoc, &txtSel); + hr = ITextRange_SetRange(range, i, j); + ok(SUCCEEDED(hr), "got 0x%08x\n", hr); + hr = ITextRange_Move(range, tomCharacter, move_by, &delta); + if (expected_delta == 0) { + ok(hr == S_FALSE, "(%d,%d) move by %d got hr=0x%08x\n", i, j, move_by, hr); + ok(delta == 0, "(%d,%d) move by %d got delta %d\n", i, j, move_by, delta); + CHECK_RANGE(range, expected_location, expected_location); + } else { + ok(hr == S_OK, "(%d,%d) move by %d got hr=0x%08x\n", i, j, move_by, hr); + ok(delta == expected_delta, "(%d,%d) move by %d got delta %d\n", i, j, move_by, delta); + CHECK_RANGE(range, expected_location, expected_location); + } } -static void test_ITextSelection_SetEnd(void) +static void test_character_startof(ITextRange *range, int textlen, int i, int j) { - HWND w; - IRichEditOle *reOle = NULL; - ITextDocument *txtDoc = NULL; - ITextSelection *txtSel = NULL; - HRESULT hres; - LONG first, lim, start, end; - static const CHAR test_text1[] = "TestSomeText"; - - create_interfaces(&w, &reOle, &txtDoc, &txtSel); - SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1); - - first = 4, lim = 8; - SendMessageA(w, EM_SETSEL, first, lim); - hres = ITextSelection_SetEnd(txtSel, lim); - ok(hres == S_FALSE, "ITextSelection_SetEnd\n"); - -#define TEST_TXTSEL_SETEND(cp, expected_start, expected_end) \ - hres = ITextSelection_SetEnd(txtSel, cp); \ - ok(hres == S_OK, "ITextSelection_SetEnd\n"); \ - SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end); \ - ok(start == expected_start, "got wrong start value: %d\n", start); \ - ok(end == expected_end, "got wrong end value: %d\n", end); - - TEST_TXTSEL_SETEND(6, 4, 6) - TEST_TXTSEL_SETEND(14, 4, 13) - TEST_TXTSEL_SETEND(-1, 0, 0) - - release_interfaces(&w, &reOle, &txtDoc, &txtSel); + HRESULT hr; + LONG delta; + + hr = ITextRange_SetRange(range, i, j); + ok(SUCCEEDED(hr), "got 0x%08x\n", hr); + hr = ITextRange_StartOf(range, tomCharacter, tomMove, &delta); + if (i == j) { + ok(hr == S_FALSE, "(%d,%d) tomMove got hr=0x%08x\n", i, j, hr); + ok(delta == 0, "(%d,%d) tomMove got delta %d\n", i, j, delta); + } else { + ok(hr == S_OK, "(%d,%d) tomMove got hr=0x%08x\n", i, j, hr); + ok(delta == -1, "(%d,%d) tomMove got delta %d\n", i, j, delta); + } + CHECK_RANGE(range, i, i); + + hr = ITextRange_SetRange(range, i, j); + ok(SUCCEEDED(hr), "got 0x%08x\n", hr); + hr = ITextRange_StartOf(range, tomCharacter, tomExtend, &delta); + ok(hr == S_FALSE, "(%d,%d) tomExtend got hr=0x%08x\n", i, j, hr); + ok(delta == 0, "(%d,%d) tomExtend got delta %d\n", i, j, delta); + CHECK_RANGE(range, i, j); } -static void test_ITextRange_GetFont(void) +static void test_character_endof(ITextRange *range, int textlen, int i, int j) { - HWND w; - IRichEditOle *reOle = NULL; - ITextDocument *txtDoc = NULL; - ITextRange *txtRge = NULL; - ITextFont *txtFont = NULL, *txtFont1 = NULL; - HRESULT hres; - int first, lim; - int refcount; - static const CHAR test_text1[] = "TestSomeText"; - LONG value; - - create_interfaces(&w, &reOle, &txtDoc, NULL); - SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1); - - first = 4, lim = 4; - ITextDocument_Range(txtDoc, first, lim, &txtRge); - refcount = get_refcount((IUnknown *)txtRge); - ok(refcount == 1, "got wrong ref count: %d\n", refcount); - - hres = ITextRange_GetFont(txtRge, &txtFont); - ok(hres == S_OK, "ITextRange_GetFont\n"); - refcount = get_refcount((IUnknown *)txtFont); - ok(refcount == 1, "got wrong ref count: %d\n", refcount); - refcount = get_refcount((IUnknown *)txtRge); - ok(refcount == 2, "got wrong ref count: %d\n", refcount); - - hres = ITextRange_GetFont(txtRge, &txtFont1); - ok(hres == S_OK, "ITextRange_GetFont\n"); - ok(txtFont1 != txtFont, "A new pointer should be return\n"); - refcount = get_refcount((IUnknown *)txtFont1); - ok(refcount == 1, "got wrong ref count: %d\n", refcount); - ITextFont_Release(txtFont1); - refcount = get_refcount((IUnknown *)txtRge); - ok(refcount == 2, "got wrong ref count: %d\n", refcount); - - ITextRange_Release(txtRge); - release_interfaces(&w, &reOle, &txtDoc, NULL); - - hres = ITextFont_GetOutline(txtFont, &value); - ok(hres == CO_E_RELEASED, "ITextFont after ITextDocument destroyed\n"); - - ITextFont_Release(txtFont); + HRESULT hr; + LONG end; + LONG delta; + + hr = ITextRange_SetRange(range, i, j); + ok(SUCCEEDED(hr), "got 0x%08x\n", hr); + hr = ITextRange_EndOf(range, tomCharacter, tomMove, &delta); + + /* A character "end", apparently cannot be before the very first character */ + end = j; + if (j == 0) + ++end; + + if (i == end) { + ok(hr == S_FALSE, "(%d,%d) tomMove got hr=0x%08x\n", i, j, hr); + ok(delta == 0, "(%d,%d) tomMove got delta %d\n", i, j, delta); + } else { + ok(hr == S_OK, "(%d,%d) tomMove got hr=0x%08x\n", i, j, hr); + ok(delta == 1, "(%d,%d) tomMove got delta %d\n", i, j, delta); + } + CHECK_RANGE(range, end, end); + + hr = ITextRange_SetRange(range, i, j); + ok(SUCCEEDED(hr), "got 0x%08x\n", hr); + hr = ITextRange_EndOf(range, tomCharacter, tomExtend, &delta); + if (0 < j) { + ok(hr == S_FALSE, "(%d,%d) tomExtend got hr=0x%08x\n", i, j, hr); + ok(delta == 0, "(%d,%d) tomExtend got delta %d\n", i, j, delta); + } else { + ok(hr == S_OK, "(%d,%d) tomExtend got hr=0x%08x\n", i, j, hr); + ok(delta == 1, "(%d,%d) tomExtend got delta %d\n", i, j, delta); + } + CHECK_RANGE(range, i, end); } -static void test_ITextSelection_GetFont(void) +static void test_character_movement(void) { - HWND w; - IRichEditOle *reOle = NULL; - ITextDocument *txtDoc = NULL; - ITextSelection *txtSel = NULL; - ITextFont *txtFont = NULL, *txtFont1 = NULL; - HRESULT hres; - int first, lim; - int refcount; - static const CHAR test_text1[] = "TestSomeText"; - LONG value; - - create_interfaces(&w, &reOle, &txtDoc, &txtSel); - SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1); - - first = 4, lim = 4; - SendMessageA(w, EM_SETSEL, first, lim); - refcount = get_refcount((IUnknown *)txtSel); - ok(refcount == 2, "got wrong ref count: %d\n", refcount); - - hres = ITextSelection_GetFont(txtSel, &txtFont); - ok(hres == S_OK, "ITextSelection_GetFont\n"); - refcount = get_refcount((IUnknown *)txtFont); - ok(refcount == 1, "got wrong ref count: %d\n", refcount); - refcount = get_refcount((IUnknown *)txtSel); - ok(refcount == 3, "got wrong ref count: %d\n", refcount); + static const char test_text1[] = "ab\n c"; + IRichEditOle *reole = NULL; + ITextDocument *doc = NULL; + ITextRange *range; + ITextSelection *selection; + HRESULT hr; + HWND hwnd; + int i, j; + const int textlen = strlen(test_text1); - hres = ITextSelection_GetFont(txtSel, &txtFont1); - ok(hres == S_OK, "ITextSelection_GetFont\n"); - ok(txtFont1 != txtFont, "A new pointer should be return\n"); - refcount = get_refcount((IUnknown *)txtFont1); - ok(refcount == 1, "got wrong ref count: %d\n", refcount); - ITextFont_Release(txtFont1); - refcount = get_refcount((IUnknown *)txtSel); - ok(refcount == 3, "got wrong ref count: %d\n", refcount); + create_interfaces(&hwnd, &reole, &doc, &selection); + SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1); - release_interfaces(&w, &reOle, &txtDoc, &txtSel); + hr = ITextDocument_Range(doc, 0, 0, &range); + ok(hr == S_OK, "got 0x%08x\n", hr); - hres = ITextFont_GetOutline(txtFont, &value); - ok(hres == CO_E_RELEASED, "ITextFont after ITextDocument destroyed\n"); + /* Exhaustive test of every possible combination of (start,end) locations, + * against every possible target location to move to. */ + for (i = 0; i <= textlen; i++) { + for (j = i; j <= textlen; j++) { + LONG target; + for (target = -2; target <= textlen + 3; target++) { + test_character_moveend(range, textlen, i, j, target); + test_character_movestart(range, textlen, i, j, target); + test_character_move(range, textlen, i, j, target); + } + test_character_startof(range, textlen, i, j); + test_character_endof(range, textlen, i, j); + } + } - ITextFont_Release(txtFont); + release_interfaces(&hwnd, &reole, &doc, NULL); + ITextSelection_Release(selection); + ITextRange_Release(range); } -static void test_ITextRange_GetPara(void) +#define CLIPBOARD_RANGE_CONTAINS(range, start, end, expected) _clipboard_range_contains(range, start, end, expected, __LINE__, 0); +#define TODO_CLIPBOARD_RANGE_CONTAINS(range, start, end, expected) _clipboard_range_contains(range, start, end, expected, __LINE__, 1); +static void _clipboard_range_contains(ITextRange *range, LONG start, LONG end, const char *expected, int line, int todo) { - HWND w; - IRichEditOle *reOle = NULL; - ITextDocument *txtDoc = NULL; - ITextRange *txtRge = NULL; - ITextPara *txtPara = NULL, *txtPara1 = NULL; - HRESULT hres; - int first, lim; - int refcount; - static const CHAR test_text1[] = "TestSomeText"; - LONG value; - - create_interfaces(&w, &reOle, &txtDoc, NULL); - SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1); - - first = 4, lim = 4; - ITextDocument_Range(txtDoc, first, lim, &txtRge); - refcount = get_refcount((IUnknown *)txtRge); - ok(refcount == 1, "got wrong ref count: %d\n", refcount); + HRESULT hr; + BOOL clipboard_open; + HGLOBAL global; + const char *clipboard_text; + + hr = ITextRange_SetRange(range, start, end); + ok_(__FILE__,line)(SUCCEEDED(hr), "SetRange failed: 0x%08x\n", hr); + hr = ITextRange_Copy(range, NULL); + ok_(__FILE__,line)(hr == S_OK, "Copy failed: 0x%08x\n", hr); + + clipboard_open = OpenClipboard(NULL); + ok_(__FILE__,line)(clipboard_open, "OpenClipboard failed: %d\n", GetLastError()); + global = GetClipboardData(CF_TEXT); + ok_(__FILE__,line)(global != NULL, "GetClipboardData failed: %p\n", global); + clipboard_text = GlobalLock(global); + ok_(__FILE__,line)(clipboard_text != NULL, "GlobalLock failed: %p\n", clipboard_text); +#ifdef __REACTOS__ + if (expected != NULL && clipboard_text != NULL) + todo_wine_if(todo) ok_(__FILE__,line)(!strcmp(expected, clipboard_text), "unexpected contents: %s\n", wine_dbgstr_a(clipboard_text)); + else + todo_wine_if(todo) ok_(__FILE__,line)(FALSE, "Either 'expected' or 'clipboard_text' was NULL\n"); +#else + todo_wine_if(todo) ok_(__FILE__,line)(!strcmp(expected, clipboard_text), "unexpected contents: %s\n", wine_dbgstr_a(clipboard_text)); +#endif + GlobalUnlock(global); + CloseClipboard(); +} - hres = ITextRange_GetPara(txtRge, &txtPara); - ok(hres == S_OK, "ITextRange_GetPara\n"); - refcount = get_refcount((IUnknown *)txtPara); - ok(refcount == 1, "got wrong ref count: %d\n", refcount); - refcount = get_refcount((IUnknown *)txtRge); - ok(refcount == 2, "got wrong ref count: %d\n", refcount); +static void test_clipboard(void) +{ + static const char text_in[] = "ab\n c"; + IRichEditOle *reole = NULL; + ITextDocument *doc = NULL; + ITextRange *range; + ITextSelection *selection; + HRESULT hr; + HWND hwnd; - hres = ITextRange_GetPara(txtRge, &txtPara1); - ok(hres == S_OK, "ITextRange_GetPara\n"); - ok(txtPara1 != txtPara, "A new pointer should be return\n"); - refcount = get_refcount((IUnknown *)txtPara1); - ok(refcount == 1, "got wrong ref count: %d\n", refcount); - ITextPara_Release(txtPara1); - refcount = get_refcount((IUnknown *)txtRge); - ok(refcount == 2, "got wrong ref count: %d\n", refcount); + create_interfaces(&hwnd, &reole, &doc, &selection); + SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)text_in); - ITextRange_Release(txtRge); - release_interfaces(&w, &reOle, &txtDoc, NULL); + hr = ITextDocument_Range(doc, 0, 0, &range); + ok(hr == S_OK, "got 0x%08x\n", hr); - hres = ITextPara_GetStyle(txtPara, &value); - ok(hres == CO_E_RELEASED, "ITextPara after ITextDocument destroyed\n"); + CLIPBOARD_RANGE_CONTAINS(range, 0, 5, "ab\r\n c") + CLIPBOARD_RANGE_CONTAINS(range, 0, 0, "ab\r\n c") + CLIPBOARD_RANGE_CONTAINS(range, 1, 1, "ab\r\n c") + CLIPBOARD_RANGE_CONTAINS(range, 0, 1, "a") + CLIPBOARD_RANGE_CONTAINS(range, 5, 6, "") + + /* Setting password char does not stop Copy */ + SendMessageA(hwnd, EM_SETPASSWORDCHAR, '*', 0); + CLIPBOARD_RANGE_CONTAINS(range, 0, 1, "a") + + /* Cut can be undone */ + hr = ITextRange_SetRange(range, 0, 1); + ok(SUCCEEDED(hr), "SetRange failed: 0x%08x\n", hr); + hr = ITextRange_Cut(range, NULL); + ok(hr == S_OK, "Cut failed: 0x%08x\n", hr); + CLIPBOARD_RANGE_CONTAINS(range, 0, 4, "b\r\n c"); + hr = ITextDocument_Undo(doc, 1, NULL); + todo_wine ok(hr == S_OK, "Undo failed: 0x%08x\n", hr); + TODO_CLIPBOARD_RANGE_CONTAINS(range, 0, 5, "ab\r\n c"); + + /* Cannot cut when read-only */ + SendMessageA(hwnd, EM_SETREADONLY, TRUE, 0); + hr = ITextRange_SetRange(range, 0, 1); + ok(SUCCEEDED(hr), "SetRange failed: 0x%08x\n", hr); + hr = ITextRange_Cut(range, NULL); + ok(hr == E_ACCESSDENIED, "got 0x%08x\n", hr); - ITextPara_Release(txtPara); + release_interfaces(&hwnd, &reole, &doc, NULL); + ITextSelection_Release(selection); + ITextRange_Release(range); } START_TEST(richole) @@ -4088,21 +4263,14 @@ START_TEST(richole) test_GetText(); test_ITextSelection_GetChar(); test_ITextSelection_GetStart_GetEnd(); - test_ITextSelection_SetStart(); - test_ITextSelection_SetEnd(); test_ITextSelection_Collapse(); - test_ITextSelection_GetFont(); test_ITextDocument_Range(); test_ITextRange_GetChar(); test_ITextRange_ScrollIntoView(); test_ITextRange_GetStart_GetEnd(); test_ITextRange_SetRange(); test_ITextRange_GetDuplicate(); - test_ITextRange_SetStart(); - test_ITextRange_SetEnd(); test_ITextRange_Collapse(); - test_ITextRange_GetFont(); - test_ITextRange_GetPara(); test_GetClientSite(); test_IOleWindow_GetWindow(); test_IOleInPlaceSite_GetWindow(); @@ -4121,5 +4289,7 @@ START_TEST(richole) test_GetStoryLength(); test_ITextSelection_GetDuplicate(); test_Expand(); - test_MoveEnd(); + test_MoveEnd_story(); + test_character_movement(); + test_clipboard(); } diff --git a/modules/rostests/winetests/riched20/txtsrv.c b/modules/rostests/winetests/riched20/txtsrv.c index dd290e3fb2f2e..1f789da8a3754 100644 --- a/modules/rostests/winetests/riched20/txtsrv.c +++ b/modules/rostests/winetests/riched20/txtsrv.c @@ -48,7 +48,7 @@ static PCreateTextServices pCreateTextServices; /* Use a special table for x86 machines to convert the thiscall * calling convention. This isn't needed on other platforms. */ -#if defined(__i386__) && !defined(__MINGW32__) +#if defined(__i386__) && !defined(__MINGW32__) && (!defined(_MSC_VER) || !defined(__clang__)) static ITextServicesVtbl itextServicesStdcallVtbl; #define TXTSERV_VTABLE(This) (&itextServicesStdcallVtbl) #else /* __i386__ */ @@ -61,8 +61,8 @@ static ITextServicesVtbl itextServicesStdcallVtbl; #define ITextServices_TxGetVScroll(This,a,b,c,d,e) TXTSERV_VTABLE(This)->TxGetVScroll(This,a,b,c,d,e) #define ITextServices_OnTxSetCursor(This,a,b,c,d,e,f,g,h,i) TXTSERV_VTABLE(This)->OnTxSetCursor(This,a,b,c,d,e,f,g,h,i) #define ITextServices_TxQueryHitPoint(This,a,b,c,d,e,f,g,h,i,j) TXTSERV_VTABLE(This)->TxQueryHitPoint(This,a,b,c,d,e,f,g,h,i,j) -#define ITextServices_OnTxInplaceActivate(This,a) TXTSERV_VTABLE(This)->OnTxInplaceActivate(This,a) -#define ITextServices_OnTxInplaceDeactivate(This) TXTSERV_VTABLE(This)->OnTxInplaceDeactivate(This) +#define ITextServices_OnTxInPlaceActivate(This,a) TXTSERV_VTABLE(This)->OnTxInPlaceActivate(This,a) +#define ITextServices_OnTxInPlaceDeactivate(This) TXTSERV_VTABLE(This)->OnTxInPlaceDeactivate(This) #define ITextServices_OnTxUIActivate(This) TXTSERV_VTABLE(This)->OnTxUIActivate(This) #define ITextServices_OnTxUIDeactivate(This) TXTSERV_VTABLE(This)->OnTxUIDeactivate(This) #define ITextServices_TxGetText(This,a) TXTSERV_VTABLE(This)->TxGetText(This,a) @@ -85,7 +85,10 @@ typedef struct ITextHostTestImpl { ITextHost ITextHost_iface; LONG refCount; + HWND window; + RECT client_rect; CHARFORMAT2W char_format; + DWORD scrollbars, props; } ITextHostTestImpl; static inline ITextHostTestImpl *impl_from_ITextHost(ITextHost *iface) @@ -93,6 +96,11 @@ static inline ITextHostTestImpl *impl_from_ITextHost(ITextHost *iface) return CONTAINING_RECORD(iface, ITextHostTestImpl, ITextHost_iface); } +static const WCHAR lorem[] = L"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " + "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. " + "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. " + "Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."; + static HRESULT WINAPI ITextHostImpl_QueryInterface(ITextHost *iface, REFIID riid, LPVOID *ppvObject) @@ -133,6 +141,7 @@ static HDC __thiscall ITextHostImpl_TxGetDC(ITextHost *iface) { ITextHostTestImpl *This = impl_from_ITextHost(iface); TRACECALL("Call to TxGetDC(%p)\n", This); + if (This->window) return GetDC( This->window ); return NULL; } @@ -140,6 +149,7 @@ static INT __thiscall ITextHostImpl_TxReleaseDC(ITextHost *iface, HDC hdc) { ITextHostTestImpl *This = impl_from_ITextHost(iface); TRACECALL("Call to TxReleaseDC(%p)\n", This); + if (This->window) return ReleaseDC( This->window, hdc ); return 0; } @@ -287,7 +297,8 @@ static HRESULT __thiscall ITextHostImpl_TxGetClientRect(ITextHost *iface, LPRECT { ITextHostTestImpl *This = impl_from_ITextHost(iface); TRACECALL("Call to TxGetClientRect(%p, prc=%p)\n", This, prc); - return E_NOTIMPL; + *prc = This->client_rect; + return S_OK; } static HRESULT __thiscall ITextHostImpl_TxGetViewInset(ITextHost *iface, LPRECT prc) @@ -333,12 +344,12 @@ static HRESULT __thiscall ITextHostImpl_TxGetMaxLength(ITextHost *iface, DWORD * return E_NOTIMPL; } -static HRESULT __thiscall ITextHostImpl_TxGetScrollBars(ITextHost *iface, DWORD *pdwScrollBar) +static HRESULT __thiscall ITextHostImpl_TxGetScrollBars(ITextHost *iface, DWORD *scrollbars) { ITextHostTestImpl *This = impl_from_ITextHost(iface); - TRACECALL("Call to TxGetScrollBars(%p, pdwScrollBar=%p)\n", - This, pdwScrollBar); - return E_NOTIMPL; + TRACECALL("Call to TxGetScrollBars(%p, scrollbars=%p)\n", This, scrollbars); + *scrollbars = This->scrollbars; + return S_OK; } static HRESULT __thiscall ITextHostImpl_TxGetPasswordChar(ITextHost *iface, WCHAR *pch) @@ -383,15 +394,28 @@ static HRESULT __thiscall ITextHostImpl_TxGetPropertyBits(ITextHost *iface, DWOR ITextHostTestImpl *This = impl_from_ITextHost(iface); TRACECALL("Call to TxGetPropertyBits(%p, dwMask=0x%08x, pdwBits=%p)\n", This, dwMask, pdwBits); - *pdwBits = 0; + *pdwBits = This->props & dwMask; return S_OK; } -static HRESULT __thiscall ITextHostImpl_TxNotify(ITextHost *iface, DWORD iNotify, void *pv) +static int en_vscroll_sent; +static int en_update_sent; +static HRESULT __thiscall ITextHostImpl_TxNotify( ITextHost *iface, DWORD code, void *data ) { ITextHostTestImpl *This = impl_from_ITextHost(iface); - TRACECALL("Call to TxNotify(%p, iNotify=%d, pv=%p)\n", This, iNotify, pv); - return E_NOTIMPL; + TRACECALL( "Call to TxNotify(%p, code = %#x, data = %p)\n", This, code, data ); + switch (code) + { + case EN_VSCROLL: + en_vscroll_sent++; + ok( !data, "got %p\n", data ); + break; + case EN_UPDATE: + en_update_sent++; + ok( !data, "got %p\n", data ); + break; + } + return S_OK; } static HIMC __thiscall ITextHostImpl_TxImmGetContext(ITextHost *iface) @@ -492,7 +516,7 @@ typedef struct static void setup_thiscall_wrappers(void) { -#if defined(__i386__) && !defined(__MINGW32__) +#if defined(__i386__) && !defined(__MINGW32__) && (!defined(_MSC_VER) || !defined(__clang__)) void** pVtable; void** pVtableEnd; THISCALL_TO_STDCALL_THUNK *thunk; @@ -591,9 +615,13 @@ static BOOL init_texthost(ITextServices **txtserv, ITextHost **ret) } dummyTextHost->ITextHost_iface.lpVtbl = &itextHostVtbl; dummyTextHost->refCount = 1; + dummyTextHost->window = NULL; + SetRectEmpty( &dummyTextHost->client_rect ); memset(&dummyTextHost->char_format, 0, sizeof(dummyTextHost->char_format)); dummyTextHost->char_format.cbSize = sizeof(dummyTextHost->char_format); dummyTextHost->char_format.dwMask = CFM_ALL2; + dummyTextHost->scrollbars = 0; + dummyTextHost->props = 0; hf = GetStockObject(DEFAULT_GUI_FONT); hf_to_cf(hf, &dummyTextHost->char_format); @@ -602,6 +630,7 @@ static BOOL init_texthost(ITextServices **txtserv, ITextHost **ret) ITextServices object. */ result = pCreateTextServices(NULL, &dummyTextHost->ITextHost_iface, &init); ok(result == S_OK, "Did not return S_OK when created (result = %x)\n", result); + ok(dummyTextHost->refCount == 1, "host ref %d\n", dummyTextHost->refCount); if (result != S_OK) { CoTaskMemFree(dummyTextHost); win_skip("CreateTextServices failed.\n"); @@ -621,9 +650,30 @@ static BOOL init_texthost(ITextServices **txtserv, ITextHost **ret) return TRUE; } +static void fill_reobject_struct(REOBJECT *reobj, LONG cp, LPOLEOBJECT poleobj, + LPSTORAGE pstg, LPOLECLIENTSITE polesite, LONG sizel_cx, + LONG sizel_cy, DWORD aspect, DWORD flags, DWORD user) +{ + reobj->cbStruct = sizeof(*reobj); + reobj->clsid = CLSID_NULL; + reobj->cp = cp; + reobj->poleobj = poleobj; + reobj->pstg = pstg; + reobj->polesite = polesite; + reobj->sizel.cx = sizel_cx; + reobj->sizel.cy = sizel_cy; + reobj->dvaspect = aspect; + reobj->dwFlags = flags; + reobj->dwUser = user; +} + static void test_TxGetText(void) { + const WCHAR *expected_string; + IOleClientSite *clientsite; ITextServices *txtserv; + IRichEditOle *reole; + REOBJECT reobject; ITextHost *host; HRESULT hres; BSTR rettext; @@ -635,6 +685,24 @@ static void test_TxGetText(void) ok(hres == S_OK, "ITextServices_TxGetText failed (result = %x)\n", hres); SysFreeString(rettext); + hres = ITextServices_TxSetText(txtserv, L"abcdefg"); + ok(hres == S_OK, "Got hres: %#x.\n", hres); + hres = ITextServices_QueryInterface(txtserv, &IID_IRichEditOle, (void **)&reole); + ok(hres == S_OK, "Got hres: %#x.\n", hres); + hres = IRichEditOle_GetClientSite(reole, &clientsite); + ok(hres == S_OK, "Got hres: %#x.\n", hres); + expected_string = L"abc\xfffc""defg"; + fill_reobject_struct(&reobject, 3, NULL, NULL, clientsite, 10, 10, DVASPECT_CONTENT, 0, 1); + hres = IRichEditOle_InsertObject(reole, &reobject); + ok(hres == S_OK, "Got hres: %#x.\n", hres); + hres = ITextServices_TxGetText(txtserv, &rettext); + ok(hres == S_OK, "Got hres: %#x.\n", hres); + ok(lstrlenW(rettext) == lstrlenW(expected_string), "Got wrong length: %d.\n", lstrlenW(rettext)); + todo_wine ok(!lstrcmpW(rettext, expected_string), "Got wrong content: %s.\n", debugstr_w(rettext)); + SysFreeString(rettext); + IOleClientSite_Release(clientsite); + IRichEditOle_Release(reole); + ITextServices_Release(txtserv); ITextHost_Release(host); } @@ -689,7 +757,7 @@ static void _check_txgetnaturalsize(HRESULT res, LONG width, LONG height, HDC hd expected_width = expected_rect.right - expected_rect.left; expected_height = expected_rect.bottom - expected_rect.top; ok_(__FILE__,line)(res == S_OK, "ITextServices_TxGetNaturalSize failed: 0x%08x.\n", res); - ok_(__FILE__,line)(width >= expected_width && width <= expected_width + 1, + todo_wine ok_(__FILE__,line)(width >= expected_width && width <= expected_width + 1, "got wrong width: %d, expected: %d {+1}.\n", width, expected_width); ok_(__FILE__,line)(height == expected_height, "got wrong height: %d, expected: %d.\n", height, expected_height); @@ -701,7 +769,7 @@ static void test_TxGetNaturalSize(void) ITextHost *host; HRESULT result; SIZEL extent; - static const WCHAR test_text[] = {'T','e','s','t','S','o','m','e','T','e','x','t',0}; + static const WCHAR test_text[] = L"TestSomeText"; LONG width, height; HDC hdcDraw; HWND hwnd; @@ -736,7 +804,7 @@ static void test_TxGetNaturalSize(void) height = 0; result = ITextServices_TxGetNaturalSize(txtserv, DVASPECT_CONTENT, hdcDraw, NULL, NULL, TXTNS_FITTOCONTENT, &extent, &width, &height); - todo_wine CHECK_TXGETNATURALSIZE(result, width, height, hdcDraw, rect, test_text); + CHECK_TXGETNATURALSIZE(result, width, height, hdcDraw, rect, test_text); ReleaseDC(hwnd, hdcDraw); DestroyWindow(hwnd); @@ -748,26 +816,51 @@ static void test_TxDraw(void) { ITextServices *txtserv; ITextHost *host; - HDC tmphdc = GetDC(NULL); - DWORD dwAspect = DVASPECT_CONTENT; - HDC hicTargetDev = NULL; /* Means "default" device */ - DVTARGETDEVICE *ptd = NULL; - void *pvAspect = NULL; - HRESULT result; - RECTL client = {0,0,100,100}; - + HRESULT hr; + RECT client = {0, 0, 100, 100}; + ITextHostTestImpl *host_impl; + HDC hdc; if (!init_texthost(&txtserv, &host)) return; - todo_wine { - result = ITextServices_TxDraw(txtserv, dwAspect, 0, pvAspect, ptd, - tmphdc, hicTargetDev, &client, NULL, - NULL, NULL, 0, 0); - ok(result == S_OK, "TxDraw failed (result = %x)\n", result); - } - + host_impl = impl_from_ITextHost( host ); + host_impl->window = CreateWindowExA( 0, "static", NULL, WS_POPUP | WS_VISIBLE, + 0, 0, 400, 400, 0, 0, 0, NULL ); + host_impl->client_rect = client; + host_impl->props = TXTBIT_MULTILINE | TXTBIT_RICHTEXT | TXTBIT_WORDWRAP; + ITextServices_OnTxPropertyBitsChange( txtserv, TXTBIT_CLIENTRECTCHANGE | TXTBIT_MULTILINE | TXTBIT_RICHTEXT | TXTBIT_WORDWRAP, + host_impl->props ); + hdc = GetDC( host_impl->window ); + + hr = ITextServices_TxDraw( txtserv, DVASPECT_CONTENT, 0, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, 0, TXTVIEW_INACTIVE ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + hr = ITextServices_TxDraw( txtserv, DVASPECT_CONTENT, 0, NULL, NULL, hdc, NULL, NULL, NULL, + NULL, NULL, 0, TXTVIEW_INACTIVE ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + hr = ITextServices_TxDraw( txtserv, DVASPECT_CONTENT, 0, NULL, NULL, NULL, NULL, (RECTL *)&client, NULL, + NULL, NULL, 0, TXTVIEW_INACTIVE ); + ok( hr == E_FAIL, "got %08x\n", hr ); + hr = ITextServices_TxDraw( txtserv, DVASPECT_CONTENT, 0, NULL, NULL, hdc, NULL, (RECTL *)&client, NULL, + NULL, NULL, 0, TXTVIEW_INACTIVE ); + ok( hr == S_OK, "got %08x\n", hr ); + hr = ITextServices_TxDraw( txtserv, DVASPECT_CONTENT, 0, NULL, NULL, hdc, NULL, (RECTL *)&client, NULL, + NULL, NULL, 0, TXTVIEW_ACTIVE ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = ITextServices_OnTxInPlaceActivate( txtserv, &client ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = ITextServices_TxDraw( txtserv, DVASPECT_CONTENT, 0, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, 0, TXTVIEW_INACTIVE ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = ITextServices_OnTxInPlaceDeactivate( txtserv ); + + ReleaseDC( host_impl->window, hdc ); ITextServices_Release(txtserv); + DestroyWindow( host_impl->window ); ITextHost_Release(host); } @@ -863,6 +956,7 @@ static void test_QueryInterface(void) IRichEditOle *reole, *txtsrv_reole; ITextDocument *txtdoc, *txtsrv_txtdoc; ITextDocument2Old *txtdoc2old, *txtsrv_txtdoc2old; + IUnknown *unk, *unk2; ULONG refcount; if(!init_texthost(&txtserv, &host)) @@ -879,6 +973,14 @@ static void test_QueryInterface(void) refcount = get_refcount((IUnknown *)txtsrv_reole); ok(refcount == 2, "got wrong ref count: %d\n", refcount); + hres = ITextServices_QueryInterface( txtserv, &IID_IUnknown, (void **)&unk ); + ok( hres == S_OK, "got 0x%08x\n", hres ); + hres = IRichEditOle_QueryInterface( txtsrv_reole, &IID_IUnknown, (void **)&unk2 ); + ok( hres == S_OK, "got 0x%08x\n", hres ); + ok( unk == unk2, "unknowns differ\n" ); + IUnknown_Release( unk2 ); + IUnknown_Release( unk ); + hres = IRichEditOle_QueryInterface(txtsrv_reole, &IID_ITextDocument, (void **)&txtdoc); ok(hres == S_OK, "IRichEditOle_QueryInterface: 0x%08x\n", hres); refcount = get_refcount((IUnknown *)txtserv); @@ -987,20 +1089,134 @@ static void test_TxGetScroll(void) ITextServices *txtserv; ITextHost *host; HRESULT ret; + LONG min_pos, max_pos, pos, page; + BOOL enabled; + ITextHostTestImpl *host_impl; + RECT client = {0, 0, 100, 100}; if (!init_texthost(&txtserv, &host)) return; + host_impl = impl_from_ITextHost( host ); + ret = ITextServices_TxGetHScroll(txtserv, NULL, NULL, NULL, NULL, NULL); - ok(ret == S_OK, "ITextSerHices_GetVScroll failed: 0x%08x.\n", ret); + ok(ret == S_OK, "ITextServices_TxGetHScroll failed: 0x%08x.\n", ret); ret = ITextServices_TxGetVScroll(txtserv, NULL, NULL, NULL, NULL, NULL); - ok(ret == S_OK, "ITextServices_GetVScroll failed: 0x%08x.\n", ret); - + ok(ret == S_OK, "ITextServices_TxGetVScroll failed: 0x%08x.\n", ret); + + ret = ITextServices_TxGetVScroll( txtserv, &min_pos, &max_pos, &pos, &page, &enabled ); + ok( ret == S_OK, "ITextServices_TxGetHScroll failed: 0x%08x.\n", ret ); + ok( min_pos == 0, "got %d\n", min_pos ); + ok( max_pos == 0, "got %d\n", max_pos ); + ok( pos == 0, "got %d\n", pos ); + ok( page == 0, "got %d\n", page ); + ok( !enabled, "got %d\n", enabled ); + + host_impl->scrollbars = WS_VSCROLL; + host_impl->props = TXTBIT_MULTILINE | TXTBIT_RICHTEXT | TXTBIT_WORDWRAP; + ITextServices_OnTxPropertyBitsChange( txtserv, TXTBIT_SCROLLBARCHANGE | TXTBIT_MULTILINE | TXTBIT_RICHTEXT | TXTBIT_WORDWRAP, host_impl->props ); + + host_impl->window = CreateWindowExA( 0, "static", NULL, WS_POPUP | WS_VISIBLE, + 0, 0, 400, 400, 0, 0, 0, NULL ); + host_impl->client_rect = client; + ret = ITextServices_OnTxInPlaceActivate( txtserv, &client ); + ok( ret == S_OK, "got 0x%08x.\n", ret ); + + ret = ITextServices_TxGetVScroll( txtserv, &min_pos, &max_pos, &pos, &page, &enabled ); + ok( ret == S_OK, "ITextServices_TxGetHScroll failed: 0x%08x.\n", ret ); + ok( min_pos == 0, "got %d\n", min_pos ); +todo_wine + ok( max_pos == 0, "got %d\n", max_pos ); + ok( pos == 0, "got %d\n", pos ); + ok( page == client.bottom, "got %d\n", page ); + ok( !enabled, "got %d\n", enabled ); + + ret = ITextServices_TxSetText( txtserv, lorem ); + ok( ret == S_OK, "got 0x%08x.\n", ret ); + + ret = ITextServices_TxGetVScroll( txtserv, &min_pos, &max_pos, &pos, &page, &enabled ); + ok( ret == S_OK, "ITextServices_TxGetHScroll failed: 0x%08x.\n", ret ); + ok( min_pos == 0, "got %d\n", min_pos ); + ok( max_pos > client.bottom, "got %d\n", max_pos ); + ok( pos == 0, "got %d\n", pos ); + ok( page == client.bottom, "got %d\n", page ); + ok( enabled, "got %d\n", enabled ); + + host_impl->scrollbars = WS_VSCROLL | ES_DISABLENOSCROLL; + ITextServices_OnTxPropertyBitsChange( txtserv, TXTBIT_SCROLLBARCHANGE, host_impl->props ); + ITextServices_TxSetText( txtserv, L"short" ); + + ret = ITextServices_TxGetVScroll( txtserv, &min_pos, &max_pos, &pos, &page, &enabled ); + ok( ret == S_OK, "ITextServices_TxGetHScroll failed: 0x%08x.\n", ret ); + ok( min_pos == 0, "got %d\n", min_pos ); +todo_wine + ok( max_pos == 0, "got %d\n", max_pos ); + ok( pos == 0, "got %d\n", pos ); + ok( page == client.bottom, "got %d\n", page ); + ok( !enabled, "got %d\n", enabled ); + + DestroyWindow( host_impl->window ); ITextServices_Release(txtserv); ITextHost_Release(host); } +static void test_notifications( void ) +{ + ITextServices *txtserv; + ITextHost *host; + LRESULT res; + HRESULT hr; + RECT client = { 0, 0, 100, 100 }; + ITextHostTestImpl *host_impl; + + init_texthost( &txtserv, &host ); + host_impl = impl_from_ITextHost( host ); + + host_impl->scrollbars = WS_VSCROLL; + host_impl->props = TXTBIT_MULTILINE | TXTBIT_RICHTEXT | TXTBIT_WORDWRAP; + ITextServices_OnTxPropertyBitsChange( txtserv, TXTBIT_SCROLLBARCHANGE | TXTBIT_MULTILINE | TXTBIT_RICHTEXT | TXTBIT_WORDWRAP, host_impl->props ); + + ITextServices_TxSetText( txtserv, lorem ); + + host_impl->window = CreateWindowExA( 0, "static", NULL, WS_POPUP | WS_VISIBLE, + 0, 0, 400, 400, 0, 0, 0, NULL ); + host_impl->client_rect = client; + hr = ITextServices_OnTxInPlaceActivate( txtserv, &client ); + ok( hr == S_OK, "got 0x%08x.\n", hr ); + + hr = ITextServices_TxSendMessage( txtserv, EM_SETEVENTMASK, 0, ENM_SCROLL, &res ); + ok( hr == S_OK, "got %08x\n", hr ); + + /* check EN_VSCROLL notification is sent */ + en_vscroll_sent = 0; + hr = ITextServices_TxSendMessage( txtserv, WM_VSCROLL, SB_LINEDOWN, 0, &res ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( en_vscroll_sent == 1, "got %d\n", en_vscroll_sent ); + + hr = ITextServices_TxSendMessage( txtserv, WM_VSCROLL, SB_BOTTOM, 0, &res ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( en_vscroll_sent == 2, "got %d\n", en_vscroll_sent ); + + /* but not when the thumb is moved */ + hr = ITextServices_TxSendMessage( txtserv, WM_VSCROLL, MAKEWPARAM( SB_THUMBTRACK, 0 ), 0, &res ); + ok( hr == S_OK, "got %08x\n", hr ); + hr = ITextServices_TxSendMessage( txtserv, WM_VSCROLL, MAKEWPARAM( SB_THUMBPOSITION, 0 ), 0, &res ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( en_vscroll_sent == 2, "got %d\n", en_vscroll_sent ); + + /* EN_UPDATE is sent by TxDraw() */ + en_update_sent = 0; + hr = ITextServices_TxDraw( txtserv, DVASPECT_CONTENT, 0, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, 0, TXTVIEW_ACTIVE ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( en_update_sent == 1, "got %d\n", en_update_sent ); + + DestroyWindow( host_impl->window ); + ITextServices_Release( txtserv ); + ITextHost_Release( host ); +} + START_TEST( txtsrv ) { ITextServices *txtserv; @@ -1033,6 +1249,7 @@ START_TEST( txtsrv ) test_QueryInterface(); test_default_format(); test_TxGetScroll(); + test_notifications(); } if (wrapperCodeMem) VirtualFree(wrapperCodeMem, 0, MEM_RELEASE); } diff --git a/modules/rostests/winetests/shlwapi/path.c b/modules/rostests/winetests/shlwapi/path.c index 4a6fbd91f6d50..e9f08a902b012 100644 --- a/modules/rostests/winetests/shlwapi/path.c +++ b/modules/rostests/winetests/shlwapi/path.c @@ -1672,6 +1672,90 @@ static void test_PathStripPathA(void) PathStripPathA((char*)const_path); } +static void test_PathUndecorate(void) +{ + static const struct { + const WCHAR *path; + const WCHAR *expect; + } tests[] = { + { L"c:\\test\\a[123]", L"c:\\test\\a" }, + { L"c:\\test\\a[123].txt", L"c:\\test\\a.txt" }, + { L"c:\\test\\a.txt[123]", L"c:\\test\\a.txt[123]" }, + { L"c:\\test\\a[123a].txt", L"c:\\test\\a[123a].txt" }, + { L"c:\\test\\a[a123].txt", L"c:\\test\\a[a123].txt" }, + { L"c:\\test\\a[12\x0660].txt", L"c:\\test\\a[12\x0660].txt" }, + { L"c:\\test\\a[12]file", L"c:\\test\\a[12]file" }, + { L"c:\\test[123]\\a", L"c:\\test[123]\\a" }, + { L"c:\\test\\[123]", L"c:\\test\\[123]" }, + { L"a[123]", L"a" }, + { L"a[]", L"a" }, + { L"[123]", L"[123]" } + }; + char bufa[MAX_PATH], expect[MAX_PATH]; + WCHAR buf[MAX_PATH]; + unsigned i; + + for (i = 0; i < ARRAY_SIZE(tests); i++) + { + wcscpy(buf, tests[i].path); + PathUndecorateW(buf); + ok(!wcscmp(buf, tests[i].expect), "PathUndecorateW returned %s, expected %s\n", + wine_dbgstr_w(buf), wine_dbgstr_w(tests[i].expect)); + + WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, tests[i].path, -1, bufa, ARRAY_SIZE(bufa), "?", NULL); + WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, tests[i].expect, -1, expect, ARRAY_SIZE(expect), "?", NULL); + PathUndecorateA(bufa); + ok(!strcmp(bufa, expect), "PathUndecorateA returned %s, expected %s\n", bufa, expect); + } + + PathUndecorateA(NULL); + PathUndecorateW(NULL); +} + +static void test_PathRemoveBlanks(void) +{ + struct remove_blanks_test { + const char* input; + const char* expected; + }; + struct remove_blanks_test tests[] = { + {"", ""}, + {" ", ""}, + {"test", "test"}, + {" test", "test"}, + {" test", "test"}, + {"test ", "test"}, + {"test ", "test"}, + {" test ", "test"}, + {" test ", "test"}}; + char pathA[MAX_PATH]; + WCHAR pathW[MAX_PATH]; + int i, ret; + const UINT CP_ASCII = 20127; + + PathRemoveBlanksW(NULL); + PathRemoveBlanksA(NULL); + + for (i=0; i < ARRAY_SIZE(tests); i++) + { + strcpy(pathA, tests[i].input); + PathRemoveBlanksA(pathA); + ok(strcmp(pathA, tests[i].expected) == 0, "input string '%s', expected '%s', got '%s'\n", + tests[i].input, tests[i].expected, pathA); + + ret = MultiByteToWideChar(CP_ASCII, MB_ERR_INVALID_CHARS, tests[i].input, -1, pathW, MAX_PATH); + ok(ret != 0, "MultiByteToWideChar failed for '%s'\n", tests[i].input); + + PathRemoveBlanksW(pathW); + + ret = WideCharToMultiByte(CP_ASCII, 0, pathW, -1, pathA, MAX_PATH, NULL, NULL); + ok(ret != 0, "WideCharToMultiByte failed for %s from test string '%s'\n", wine_dbgstr_w(pathW), tests[i].input); + + ok(strcmp(pathA, tests[i].expected) == 0, "input string '%s', expected '%s', got '%s'\n", + tests[i].input, tests[i].expected, pathA); + } +} + START_TEST(path) { HMODULE hShlwapi = GetModuleHandleA("shlwapi.dll"); @@ -1718,4 +1802,6 @@ START_TEST(path) test_PathIsRelativeA(); test_PathIsRelativeW(); test_PathStripPathA(); + test_PathUndecorate(); + test_PathRemoveBlanks(); } diff --git a/modules/rostests/winetests/ucrtbase/CMakeLists.txt b/modules/rostests/winetests/ucrtbase/CMakeLists.txt new file mode 100644 index 0000000000000..e31e2897430c5 --- /dev/null +++ b/modules/rostests/winetests/ucrtbase/CMakeLists.txt @@ -0,0 +1,74 @@ + +# Hack until we support globally defining _DEBUG +if(DBG) + #add_compile_definitions(_DEBUG) +endif() + +# Generate threaddll.dll +spec2def(threaddll.dll threaddll.spec) +add_library(threaddll SHARED + threaddll.c + threaddll.def +) +set_entrypoint(threaddll DllMain 12) +if(MSVC) + target_link_libraries(threaddll runtmchk) +endif() +add_importlibs(threaddll ucrtbase kernel32) + +# Hacks to make it work with MSVC IDE / MSBUILD +if(MSVC_IDE) + if(DBG) + set(THREADDLL_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/Debug) + else() + set(THREADDLL_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/Release) + endif() + message(STATUS "threaddll.dll output directory: ${THREADDLL_OUTPUT_DIR}") + + set(CMAKE_RC_FLAGS "${CMAKE_RC_FLAGS} /I${THREADDLL_OUTPUT_DIR}") +endif() + +# Hack to replace the old CRT include directory with the UCRT include directory +get_property(INCLUDE_DIRS DIRECTORY . PROPERTY INCLUDE_DIRECTORIES) +list(REMOVE_ITEM INCLUDE_DIRS "${REACTOS_SOURCE_DIR}/sdk/include/crt") +set_property(DIRECTORY . PROPERTY INCLUDE_DIRECTORIES ${INCLUDE_DIRS}) +include_directories(${REACTOS_SOURCE_DIR}/sdk/include/ucrt) + +add_definitions( + -DUSE_WINE_TODOS + -D_USE_MATH_DEFINES + -DWINETEST_USE_DBGSTR_LONGLONG + -D_finddata64_t=__finddata64_t +) + +list(APPEND SOURCE + cpp.c + environ.c + file.c + misc.c + printf.c + scanf.c + string.c + thread.c + testlist.c + ucrtbase_winetest.rc +) + +set_source_files_properties(ucrtbase_winetest.rc OBJECT_DEPENDS threaddll) + +add_executable(ucrtbase_winetest ${SOURCE}) +if(NOT MSVC) + #set_target_properties(ucrtbase_winetest PROPERTIES LINK_FLAGS "-Wl,--major-os-version,6") + target_compile_options(ucrtbase_winetest PRIVATE -Wno-format) +endif() +set_module_type(ucrtbase_winetest win32cui) + +target_link_libraries(ucrtbase_winetest wine oldnames ${PSEH_LIB} chkstk) +if(NOT MSVC) + # Add this manually here, so it can link to ucrtbase.dll and vcstartup + target_link_libraries(ucrtbase_winetest -lgcc) +endif() + +add_importlibs(ucrtbase_winetest ucrtbase kernel32 ntdll) +add_dependencies(ucrtbase_winetest threaddll) +add_rostests_file(TARGET ucrtbase_winetest) diff --git a/modules/rostests/winetests/ucrtbase/cpp.c b/modules/rostests/winetests/ucrtbase/cpp.c new file mode 100644 index 0000000000000..7f63a1216a02a --- /dev/null +++ b/modules/rostests/winetests/ucrtbase/cpp.c @@ -0,0 +1,244 @@ +/* + * Copyright 2016 Daniel Lehman (Esri) + * + * 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 +#include +#include +#include +#include + +#include +#include +#include +#include +#include "wine/test.h" + +typedef unsigned char MSVCRT_bool; + +typedef struct { + const char *what; + MSVCRT_bool dofree; +} __std_exception_data; + +typedef struct +{ + char *name; + char mangled[32]; +} type_info140; + +typedef struct _type_info_list +{ + SLIST_ENTRY entry; + char name[1]; +} type_info_list; + +static void* (CDECL *p_malloc)(size_t); +static void (CDECL *p___std_exception_copy)(const __std_exception_data*, __std_exception_data*); +static void (CDECL *p___std_exception_destroy)(__std_exception_data*); +static int (CDECL *p___std_type_info_compare)(const type_info140*, const type_info140*); +static const char* (CDECL *p___std_type_info_name)(type_info140*, SLIST_HEADER*); +static void (CDECL *p___std_type_info_destroy_list)(SLIST_HEADER*); +static size_t (CDECL *p___std_type_info_hash)(type_info140*); +static char* (__cdecl *p___unDName)(char*,const char*,int,void*,void*,unsigned short int); + +static BOOL init(void) +{ + HMODULE module; + + module = LoadLibraryA("ucrtbase.dll"); + if (!module) + { + win_skip("ucrtbase.dll not installed\n"); + return FALSE; + } + + p_malloc = (void*)GetProcAddress(module, "malloc"); + p___std_exception_copy = (void*)GetProcAddress(module, "__std_exception_copy"); + p___std_exception_destroy = (void*)GetProcAddress(module, "__std_exception_destroy"); + p___std_type_info_compare = (void*)GetProcAddress(module, "__std_type_info_compare"); + p___std_type_info_name = (void*)GetProcAddress(module, "__std_type_info_name"); + p___std_type_info_destroy_list = (void*)GetProcAddress(module, "__std_type_info_destroy_list"); + p___std_type_info_hash = (void*)GetProcAddress(module, "__std_type_info_hash"); + p___unDName = (void*)GetProcAddress(module, "__unDName"); + return TRUE; +} + +static void test___std_exception(void) +{ + __std_exception_data src; + __std_exception_data dst; + + if (0) /* crash on Windows */ + { + p___std_exception_copy(NULL, &src); + p___std_exception_copy(&dst, NULL); + + src.what = "invalid free"; + src.dofree = 1; + p___std_exception_destroy(&src); + p___std_exception_destroy(NULL); + } + + src.what = "what"; + src.dofree = 0; + p___std_exception_copy(&src, &dst); + ok(dst.what == src.what, "expected what to be same, got src %p dst %p\n", src.what, dst.what); + ok(!dst.dofree, "expected 0, got %d\n", dst.dofree); + + src.dofree = 0x42; + p___std_exception_copy(&src, &dst); + ok(dst.what != src.what, "expected what to be different, got src %p dst %p\n", src.what, dst.what); + ok(dst.dofree == 1, "expected 1, got %d\n", dst.dofree); + + p___std_exception_destroy(&dst); + ok(!dst.what, "expected NULL, got %p\n", dst.what); + ok(!dst.dofree, "expected 0, got %d\n", dst.dofree); + + src.what = NULL; + src.dofree = 0; + p___std_exception_copy(&src, &dst); + ok(!dst.what, "dst.what != NULL\n"); + ok(!dst.dofree, "dst.dofree != FALSE\n"); + + src.what = NULL; + src.dofree = 1; + p___std_exception_copy(&src, &dst); + ok(!dst.what, "dst.what != NULL\n"); + ok(!dst.dofree, "dst.dofree != FALSE\n"); +} + +static void test___std_type_info(void) +{ + type_info140 ti1 = { NULL, ".?AVa@@" }; + type_info140 ti2 = { NULL, ".?AVb@@" }; + type_info140 ti3 = ti1; + SLIST_HEADER header; + type_info_list *elem; + const char *ret; + size_t hash1, hash2; + int eq; + + + InitializeSListHead(&header); + p___std_type_info_destroy_list(&header); + + elem = p_malloc(sizeof(*elem)); + memset(elem, 0, sizeof(*elem)); + InterlockedPushEntrySList(&header, &elem->entry); + p___std_type_info_destroy_list(&header); + ok(!InterlockedPopEntrySList(&header), "list is not empty\n"); + + ret = p___std_type_info_name(&ti1, &header); + ok(!strcmp(ret, "class a"), "__std_type_info_name(&ti1) = %s\n", ret); + ok(ti1.name == ret, "ti1.name = %p, ret = %p\n", ti1.name, ret); + + p___std_type_info_destroy_list(&header); + ok(!InterlockedPopEntrySList(&header), "list is not empty\n"); + ok(ti1.name == ret, "ti1.name = %p, ret = %p\n", ti1.name, ret); + ti1.name = NULL; + + eq = p___std_type_info_compare(&ti1, &ti1); + ok(eq == 0, "__std_type_info_compare(&ti1, &ti1) = %d\n", eq); + + eq = p___std_type_info_compare(&ti1, &ti2); + ok(eq == -1, "__std_type_info_compare(&ti1, &ti2) = %d\n", eq); + + eq = p___std_type_info_compare(&ti1, &ti3); + ok(eq == 0, "__std_type_info_compare(&ti1, &ti3) = %d\n", eq); + + ti1.mangled[0] = 0; + ti1.mangled[1] = 0; + ti1.mangled[2] = 0; + hash1 = p___std_type_info_hash(&ti1); +#ifdef _WIN64 + ok(hash1 == 0xcbf29ce44fd0bfc1, "hash = %p\n", (void*)hash1); +#else + ok(hash1 == 0x811c9dc5, "hash = %p\n", (void*)hash1); +#endif + + ti1.mangled[0] = 1; + hash2 = p___std_type_info_hash(&ti1); + ok(hash1 == hash2, "hash1 != hash2 (first char not ignored)\n"); + + ti1.mangled[1] = 1; + hash1 = p___std_type_info_hash(&ti1); +#ifdef _WIN64 + ok(hash1 == 0xaf63bc4c29620a60, "hash = %p\n", (void*)hash1); +#else + ok(hash1 == 0x40c5b8c, "hash = %p\n", (void*)hash1); +#endif + ok(hash1 != hash2, "hash1 == hash2 for different strings\n"); + + ti1.mangled[1] = 2; + hash2 = p___std_type_info_hash(&ti1); + ok(hash1 != hash2, "hash1 == hash2 for different strings\n"); + + hash1 = p___std_type_info_hash(&ti2); + ok(hash1 != hash2, "hash1 == hash2 for different strings\n"); +} + +static void test___unDName(void) +{ + static struct {const char *in; const char *out; const char *broken; unsigned int flags;} und_tests[] = + { +/* 0 */ {"??4QDnsDomainNameRecord@@QAEAAV0@$$QAV0@@Z", + "public: class QDnsDomainNameRecord & __thiscall QDnsDomainNameRecord::operator=(class QDnsDomainNameRecord &&)"}, +/* 1 */ {"??4QDnsDomainNameRecord@@QAEAAV0@$$QEAV0@@Z", + "public: class QDnsDomainNameRecord & __thiscall QDnsDomainNameRecord::operator=(class QDnsDomainNameRecord && __ptr64)"}, +/* 2 */ {"??__K_l@@YA?AUCC@@I@Z", "struct CC __cdecl operator \"\" _l(unsigned int)", + "??__K_l@@YA?AUCC@@I@Z" /* W10 1507 fails on this :-( */}, +/* 3 */ {"?meth@Q@@QEGBA?AV1@XZ", + "public: class Q __cdecl Q::meth(void)const __ptr64& ", + "public: ?? :: ?? ::XZ::V1" /* W10 1507 fails on this :-( */}, +/* 4 */ {"?meth@Q@@QEHAA?AV1@XZ", + "public: class Q __cdecl Q::meth(void) __ptr64&& ", + "public: ?? :: ?? ::XZ::V1" /* W10 1507 fails on this :-( */}, +/* 5 */ {"?meth@Q@@QEGBA?AV1@XZ", + "public: class Q Q::meth(void)const & ", + "public: ?? :: ?? ::XZ::V1" /* W10 1507 fails on this :-( */, + UNDNAME_NO_MS_KEYWORDS}, +/* 6 */ {"?meth@Q@@QEHAA?AV1@XZ", + "public: class Q Q::meth(void)&& ", + "public: ?? :: ?? ::XZ::V1" /* W10 1507 fails on this :-( */, + UNDNAME_NO_MS_KEYWORDS}, +/* 7 */ {"?AU?$my_iter@H$0A@$$V@@", + "struct my_iter", + NULL, + UNDNAME_NO_ARGUMENTS}, +/* 8 */ {"??$foo@J_W$$T@bar@@YAJQB_W$$THQAUgod@@@Z", + "long __cdecl bar::foo(wchar_t const * const,std::nullptr_t,int,struct god * const)"}, + + }; + unsigned i; + for (i = 0; i < ARRAY_SIZE(und_tests); i++) + { + char *name = p___unDName(0, und_tests[i].in, 0, malloc, free, und_tests[i].flags); + ok(!strcmp(name, und_tests[i].out) || + broken(und_tests[i].broken && !strcmp(und_tests[i].broken, name)), + "unDName returned %s for #%u\n", wine_dbgstr_a(name), i); + free(name); + } +} + +START_TEST(cpp) +{ + if (!init()) return; + test___std_exception(); + test___std_type_info(); + test___unDName(); +} diff --git a/modules/rostests/winetests/ucrtbase/environ.c b/modules/rostests/winetests/ucrtbase/environ.c new file mode 100644 index 0000000000000..a42f64466e962 --- /dev/null +++ b/modules/rostests/winetests/ucrtbase/environ.c @@ -0,0 +1,344 @@ +/* + * Unit tests for C library environment routines + * + * Copyright 2004 Mike Hearn + * + * 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 "wine/test.h" +#include +#include +#include +#include + +#define DEFINE_EXPECT(func) \ + static BOOL expect_ ## func = FALSE, called_ ## func = FALSE + +#define SET_EXPECT(func) \ + expect_ ## func = TRUE + +#define CHECK_EXPECT2(func) \ + do { \ + ok(expect_ ##func, "unexpected call " #func "\n"); \ + called_ ## func = TRUE; \ + }while(0) + +#define CHECK_EXPECT(func) \ + do { \ + CHECK_EXPECT2(func); \ + expect_ ## func = FALSE; \ + }while(0) + +#define CHECK_CALLED(func) \ + do { \ + ok(called_ ## func, "expected " #func "\n"); \ + expect_ ## func = called_ ## func = FALSE; \ + }while(0) + +DEFINE_EXPECT(invalid_parameter_handler); + +static const char *a_very_long_env_string = + "LIBRARY_PATH=" + "C:/Program Files/GLBasic/Compiler/platform/Win32/Bin/../lib/gcc/mingw32/3.4.2/;" + "C:/Program Files/GLBasic/Compiler/platform/Win32/Bin/../lib/gcc/;" + "/mingw/lib/gcc/mingw32/3.4.2/;" + "/usr/lib/gcc/mingw32/3.4.2/;" + "C:/Program Files/GLBasic/Compiler/platform/Win32/Bin/../lib/gcc/mingw32/3.4.2/../../../../mingw32/lib/mingw32/3.4.2/;" + "C:/Program Files/GLBasic/Compiler/platform/Win32/Bin/../lib/gcc/mingw32/3.4.2/../../../../mingw32/lib/;" + "/mingw/mingw32/lib/mingw32/3.4.2/;" + "/mingw/mingw32/lib/;" + "/mingw/lib/mingw32/3.4.2/;" + "/mingw/lib/;" + "C:/Program Files/GLBasic/Compiler/platform/Win32/Bin/../lib/gcc/mingw32/3.4.2/../../../mingw32/3.4.2/;" + "C:/Program Files/GLBasic/Compiler/platform/Win32/Bin/../lib/gcc/mingw32/3.4.2/../../../;" + "/mingw/lib/mingw32/3.4.2/;" + "/mingw/lib/;" + "/lib/mingw32/3.4.2/;" + "/lib/;" + "/usr/lib/mingw32/3.4.2/;" + "/usr/lib/"; + +static char ***(__cdecl *p__p__environ)(void); +static WCHAR ***(__cdecl *p__p__wenviron)(void); +static char** (__cdecl *p_get_initial_narrow_environment)(void); +static wchar_t** (__cdecl *p_get_initial_wide_environment)(void); +static errno_t (__cdecl *p_putenv_s)(const char*, const char*); +static errno_t (__cdecl *p_wputenv_s)(const wchar_t*, const wchar_t*); +static errno_t (__cdecl *p_getenv_s)(size_t*, char*, size_t, const char*); + +static char ***p_environ; +static WCHAR ***p_wenviron; + +static void __cdecl test_invalid_parameter_handler(const wchar_t *expression, + const wchar_t *function, const wchar_t *file, + unsigned line, uintptr_t arg) +{ + CHECK_EXPECT(invalid_parameter_handler); + ok(expression == NULL, "expression is not NULL\n"); + ok(function == NULL, "function is not NULL\n"); + ok(file == NULL, "file is not NULL\n"); + ok(line == 0, "line = %u\n", line); + ok(arg == 0, "arg = %Ix\n", arg); +} + +static BOOL init(void) +{ + HMODULE hmod = GetModuleHandleA( "ucrtbase.dll" ); + + p__p__environ = (void *)GetProcAddress( hmod, "__p__environ" ); + p__p__wenviron = (void *)GetProcAddress( hmod, "__p__wenviron" ); + p_get_initial_narrow_environment = (void *)GetProcAddress( hmod, "_get_initial_narrow_environment" ); + p_get_initial_wide_environment = (void *)GetProcAddress( hmod, "_get_initial_wide_environment" ); + p_putenv_s = (void *)GetProcAddress( hmod, "_putenv_s" ); + p_wputenv_s = (void *)GetProcAddress( hmod, "_wputenv_s" ); + p_getenv_s = (void *)GetProcAddress( hmod, "getenv_s" ); + + ok(p__p__environ != NULL, "Unexecped NULL pointer to environ\n" ); + ok(p__p__wenviron != NULL, "Unexecped NULL pointer to environ\n" ); + if (!p__p__environ || !p__p__wenviron) + { + skip( "NULL pointers for environment\n" ); + return FALSE; + } + p_environ = p__p__environ(); + p_wenviron = p__p__wenviron(); + return TRUE; +} + +static unsigned env_get_entry_countA( char **env ) +{ + unsigned count; + + if (!env) return 0; + for (count = 0; env[count] != NULL; count++) {} + return count; +} + +static void test_initial_environ( void ) +{ + ok( p__p__environ() != NULL, "Unexpected NULL _environ[]\n" ); + ok( *p__p__environ() != NULL, "Unexpected empty _environ[]\n" ); + ok( p_get_initial_narrow_environment() != NULL, "Unexpected empty narrow initial environment\n" ); + ok( p_get_initial_narrow_environment() == *p__p__environ(), "Expecting _environ[] to match initial narrow environment\n" ); + + ok( p__p__wenviron() != NULL, "Unexpected NULL _wenviron[]\n" ); + ok( *p__p__wenviron() == NULL, "Unexpected non empty _wenviron[]\n" ); + ok( p_get_initial_wide_environment() != NULL, "Unexpected empty wide initial environment\n" ); + ok( p_get_initial_wide_environment() == *p__p__wenviron(), "Expecting _wenviron[] to match initial wide environment\n" ); +} + +static void test_environment_manipulation(void) +{ + char buf[256]; + errno_t ret; + size_t len; + unsigned count; + char* first; + char* second; + + ok( _putenv( "cat=" ) == 0, "_putenv failed on deletion of nonexistent environment variable\n" ); + ok( _putenv( "cat=dog" ) == 0, "failed setting cat=dog\n" ); + ok( strcmp( getenv( "cat" ), "dog" ) == 0, "getenv did not return 'dog'\n" ); + if (p_getenv_s) + { + ret = p_getenv_s( &len, buf, sizeof(buf), "cat" ); + ok( !ret, "getenv_s returned %d\n", ret ); + ok( len == 4, "getenv_s returned length is %Id\n", len); + ok( !strcmp(buf, "dog"), "getenv_s did not return 'dog'\n" ); + } + ok( _putenv("cat=") == 0, "failed deleting cat\n" ); + + ok( _putenv("=") == -1, "should not accept '=' as input\n" ); + ok( _putenv("=dog") == -1, "should not accept '=dog' as input\n" ); + ok( _putenv(a_very_long_env_string) == 0, "_putenv failed for long environment string\n" ); + + ok( getenv("nonexistent") == NULL, "getenv should fail with nonexistent var name\n" ); + + if (p_putenv_s) + { + SET_EXPECT(invalid_parameter_handler); + ret = p_putenv_s( NULL, "dog" ); + CHECK_CALLED(invalid_parameter_handler); + ok( ret == EINVAL, "_putenv_s returned %d\n", ret ); + SET_EXPECT(invalid_parameter_handler); + ret = p_putenv_s( "cat", NULL ); + CHECK_CALLED(invalid_parameter_handler); + ok( ret == EINVAL, "_putenv_s returned %d\n", ret ); + SET_EXPECT(invalid_parameter_handler); + ret = p_putenv_s( "a=b", NULL ); + CHECK_CALLED(invalid_parameter_handler); + ok( ret == EINVAL, "_putenv_s returned %d\n", ret ); + ret = p_putenv_s( "cat", "a=b" ); + ok( !ret, "_putenv_s returned %d\n", ret ); + ret = p_putenv_s( "cat", "" ); + ok( !ret, "_putenv_s returned %d\n", ret ); + } + + if (p_wputenv_s) + { + SET_EXPECT(invalid_parameter_handler); + ret = p_wputenv_s( NULL, L"dog" ); + CHECK_CALLED(invalid_parameter_handler); + ok( ret == EINVAL, "_wputenv_s returned %d\n", ret ); + SET_EXPECT(invalid_parameter_handler); + ret = p_wputenv_s( L"cat", NULL ); + CHECK_CALLED(invalid_parameter_handler); + ok( ret == EINVAL, "_wputenv_s returned %d\n", ret ); + SET_EXPECT(invalid_parameter_handler); + ret = p_wputenv_s( L"a=b", NULL ); + CHECK_CALLED(invalid_parameter_handler); + ok( ret == EINVAL, "_wputenv_s returned %d\n", ret ); + ret = p_wputenv_s( L"cat", L"a=b" ); + ok( !ret, "_wputenv_s returned %d\n", ret ); + ret = p_wputenv_s( L"cat", L"" ); + ok( !ret, "_wputenv_s returned %d\n", ret ); + } + + if (p_getenv_s) + { + buf[0] = 'x'; + len = 1; + errno = 0xdeadbeef; + ret = p_getenv_s( &len, buf, sizeof(buf), "nonexistent" ); + ok( !ret, "_getenv_s returned %d\n", ret ); + ok( !len, "getenv_s returned length is %Id\n", len ); + ok( !buf[0], "buf = %s\n", buf ); + ok( errno == 0xdeadbeef, "errno = %d\n", errno ); + + buf[0] = 'x'; + len = 1; + errno = 0xdeadbeef; + ret = p_getenv_s( &len, buf, sizeof(buf), NULL ); + ok( !ret, "_getenv_s returned %d\n", ret ); + ok( !len, "getenv_s returned length is %Id\n", len ); + ok( !buf[0], "buf = %s\n", buf ); + ok( errno == 0xdeadbeef, "errno = %d\n", errno ); + } + + /* test stability of _environ[] pointers */ + ok( _putenv( "__winetest_cat=" ) == 0, "Couldn't reset env var\n" ); + ok( _putenv( "__winetest_dog=" ) == 0, "Couldn't reset env var\n" ); + count = env_get_entry_countA( *p_environ ); + ok( _putenv( "__winetest_cat=mew") == 0, "Couldn't set env var\n" ); + ok( !strcmp( (*p_environ)[count], "__winetest_cat=mew"), "Unexpected env var value\n" ); + first = (*p_environ)[count]; + ok( getenv("__winetest_cat") == strchr( (*p_environ)[count], '=') + 1, "Expected getenv() to return pointer inside _environ[] entry\n" ); + ok( _putenv( "__winetest_dog=bark" ) == 0, "Couldn't set env var\n" ); + ok( !strcmp( (*p_environ)[count + 1], "__winetest_dog=bark" ), "Unexpected env var value\n" ); + ok( getenv( "__winetest_dog" ) == strchr( (*p_environ)[count + 1], '=' ) + 1, "Expected getenv() to return pointer inside _environ[] entry\n" ); + ok( first == (*p_environ)[count], "Expected stability of _environ[count] pointer\n" ); + second = (*p_environ)[count + 1]; + ok( count + 2 == env_get_entry_countA( *p_environ ), "Unexpected count\n" ); + + ok( _putenv( "__winetest_cat=purr" ) == 0, "Couldn't set env var\n" ); + ok( !strcmp( (*p_environ)[count], "__winetest_cat=purr" ), "Unexpected env var value\n" ); + ok( getenv( "__winetest_cat" ) == strchr( (*p_environ)[count], '=' ) + 1, "Expected getenv() to return pointer inside _environ[] entry\n" ); + ok( second == (*p_environ)[count + 1], "Expected stability of _environ[count] pointer\n" ); + ok( !strcmp( (*p_environ)[count + 1], "__winetest_dog=bark" ), "Couldn't get env var value\n" ); + ok( getenv( "__winetest_dog" ) == strchr( (*p_environ)[count + 1], '=' ) + 1, "Expected getenv() to return pointer inside _environ[] entry\n" ); + ok( count + 2 == env_get_entry_countA( *p_environ ), "Unexpected count\n" ); + ok( _putenv( "__winetest_cat=" ) == 0, "Couldn't reset env vat\n" ); + ok( second == (*p_environ)[count], "Expected _environ[count] to be second\n" ); + ok( !strcmp( (*p_environ)[count], "__winetest_dog=bark" ), "Unexpected env var value\n" ); + ok( count + 1 == env_get_entry_countA( *p_environ ), "Unexpected count\n" ); + ok( _putenv( "__winetest_dog=" ) == 0, "Couldn't reset env var\n" ); + ok( count == env_get_entry_countA( *p_environ ), "Unexpected count\n" ); + + /* in putenv, only changed variable is updated (no other reload of kernel info is done) */ + ret = SetEnvironmentVariableA( "__winetest_cat", "meow" ); + ok( ret, "SetEnvironmentVariableA failed: %lu\n", GetLastError() ); + ok( _putenv( "__winetest_dog=bark" ) == 0, "Couldn't set env var\n" ); + ok( getenv( "__winetest_cat" ) == NULL, "msvcrt env cache shouldn't have been updated\n" ); + ok( _putenv( "__winetest_cat=" ) == 0, "Couldn't reset env var\n" ); + ok( _putenv( "__winetest_dog=" ) == 0, "Couldn't reset env var\n" ); + + /* test setting unicode bits */ + count = env_get_entry_countA( *p_environ ); + ret = WideCharToMultiByte( CP_ACP, 0, L"\u263a", -1, buf, ARRAY_SIZE(buf), 0, 0 ); + ok( ret, "WideCharToMultiByte failed: %lu\n", GetLastError() ); + ok( _wputenv( L"__winetest_cat=\u263a" ) == 0, "Couldn't set env var\n" ); + ok( _wgetenv( L"__winetest_cat" ) && !wcscmp( _wgetenv( L"__winetest_cat" ), L"\u263a" ), "Couldn't retrieve env var\n" ); + ok( getenv( "__winetest_cat" ) && !strcmp( getenv( "__winetest_cat" ), buf ), "Couldn't retrieve env var\n" ); + ok( _wputenv( L"__winetest_cat=" ) == 0, "Couldn't reset env var\n" ); + + ret = WideCharToMultiByte( CP_ACP, 0, L"__winetest_\u263a", -1, buf, ARRAY_SIZE(buf), 0, 0 ); + ok( ret, "WideCharToMultiByte failed: %lu\n", GetLastError() ); + ok( _wputenv( L"__winetest_\u263a=bark" ) == 0, "Couldn't set env var\n" ); + ok( _wgetenv( L"__winetest_\u263a" ) && !wcscmp( _wgetenv( L"__winetest_\u263a" ), L"bark"), "Couldn't retrieve env var\n" ); + ok( getenv( buf ) && !strcmp( getenv( buf ), "bark"), "Couldn't retrieve env var %s\n", wine_dbgstr_a(buf) ); + ok( _wputenv( L"__winetest_\u263a=" ) == 0, "Couldn't reset env var\n" ); + ok( count == env_get_entry_countA( *p_environ ), "Unexpected modification of _environ[]\n" ); +} + +static void test_child_env(char** argv) +{ + STARTUPINFOA si = {sizeof(si)}; + WCHAR *cur_env, *env, *p, *q; + PROCESS_INFORMATION pi; + char tmp[1024]; + BOOL ret; + int len; + + cur_env = GetEnvironmentStringsW(); + ok( cur_env != NULL, "GetEnvironemntStrings failed\n" ); + + p = cur_env; + while (*p) p += wcslen( p ) + 1; + len = p - cur_env; + env = malloc( (len + 1024) * sizeof(*env) ); + memcpy(env, cur_env, len * sizeof(*env) ); + q = env + len; + FreeEnvironmentStringsW( cur_env ); + + wcscpy( q, L"__winetest_dog=bark" ); + q += wcslen( L"__winetest_dog=bark" ) + 1; + wcscpy( q, L"__winetest_\u263a=\u03b2" ); + q += wcslen( L"__winetest_\u263a=\u03b2" ) + 1; + *q = 0; + + snprintf( tmp, sizeof(tmp), "%s %s create", argv[0], argv[1] ); + ret = CreateProcessA( NULL, tmp, NULL, NULL, FALSE, CREATE_UNICODE_ENVIRONMENT, env, NULL, &si, &pi ); + ok( ret, "Couldn't create child process %s\n", tmp ); + winetest_wait_child_process( pi.hProcess ); + CloseHandle( pi.hProcess ); + CloseHandle( pi.hThread ); + free( env ); +} + +START_TEST(environ) +{ + char **argv; + int argc; + + if (!init()) return; + + ok( _set_invalid_parameter_handler( test_invalid_parameter_handler ) == NULL, + "Invalid parameter handler was already set\n" ); + + argc = winetest_get_mainargs( &argv ); + if (argc == 3 && !strcmp( argv[2], "create" )) + { + ok( getenv( "__winetest_dog" ) && !strcmp( getenv( "__winetest_dog" ), "bark" ), + "Couldn't find env var\n" ); + ok( _wgetenv( L"__winetest_\u263a" ) && !wcscmp( _wgetenv( L"__winetest_\u263a" ), L"\u03b2" ), + "Couldn't find unicode env var\n" ); + return; + } + + test_initial_environ(); + test_environment_manipulation(); + test_child_env(argv); +} diff --git a/modules/rostests/winetests/ucrtbase/file.c b/modules/rostests/winetests/ucrtbase/file.c new file mode 100644 index 0000000000000..6f69997787a01 --- /dev/null +++ b/modules/rostests/winetests/ucrtbase/file.c @@ -0,0 +1,477 @@ +/* + * Unit test suite for file functions + * + * Copyright 2024 Eric Pouech 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 +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "wine/test.h" +#include + +#define STDIN_FILENO 0 +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 + +static void test_std_stream_buffering(void) +{ + int dup_fd, ret, pos; + FILE *file; + char ch; + + dup_fd = _dup(STDOUT_FILENO); + ok(dup_fd != -1, "_dup failed\n"); + + file = freopen("std_stream_test.tmp", "w", stdout); + ok(file != NULL, "freopen failed\n"); + + ret = fprintf(stdout, "test"); + pos = _telli64(STDOUT_FILENO); + + fflush(stdout); + _dup2(dup_fd, STDOUT_FILENO); + close(dup_fd); + setvbuf(stdout, NULL, _IONBF, 0); + + ok(ret == 4, "fprintf(stdout) returned %d\n", ret); + ok(!pos, "expected stdout to be buffered\n"); + + dup_fd = _dup(STDERR_FILENO); + ok(dup_fd != -1, "_dup failed\n"); + + file = freopen("std_stream_test.tmp", "w", stderr); + ok(file != NULL, "freopen failed\n"); + + ret = fprintf(stderr, "test"); + ok(ret == 4, "fprintf(stderr) returned %d\n", ret); + pos = _telli64(STDERR_FILENO); + if (broken(!GetProcAddress(GetModuleHandleA("ucrtbase"), "__CxxFrameHandler4") && !pos)) + trace("stderr is buffered\n"); + else + ok(pos == 4, "expected stderr to be unbuffered (%d)\n", pos); + + fflush(stderr); + _dup2(dup_fd, STDERR_FILENO); + close(dup_fd); + + dup_fd = _dup(STDIN_FILENO); + ok(dup_fd != -1, "_dup failed\n"); + + file = freopen("std_stream_test.tmp", "r", stdin); + ok(file != NULL, "freopen failed\n"); + + ch = 0; + ret = fscanf(stdin, "%c", &ch); + ok(ret == 1, "fscanf returned %d\n", ret); + ok(ch == 't', "ch = 0x%x\n", (unsigned char)ch); + pos = _telli64(STDIN_FILENO); + ok(pos == 4, "pos = %d\n", pos); + + fflush(stdin); + _dup2(dup_fd, STDIN_FILENO); + close(dup_fd); + + ok(DeleteFileA("std_stream_test.tmp"), "DeleteFile failed\n"); +} + +int CDECL _get_stream_buffer_pointers(FILE*,char***,char***,int**); +static void test_iobuf_layout(void) +{ + union + { + FILE *f; + struct + { + char* _ptr; + char* _base; + int _cnt; + int _flag; + int _file; + int _charbuf; + int _bufsiz; + char* _tmpfname; + CRITICAL_SECTION _crit; + } *iobuf; + } fp; + char *tempf, *ptr, **file_ptr, **file_base; + int cnt, r, *file_cnt; + + tempf = _tempnam(".","wne"); + fp.f = fopen(tempf, "wb"); + ok(fp.f != NULL, "fopen failed with error: %d\n", errno); + + ok(!(fp.iobuf->_flag & 0x440), "fp.iobuf->_flag = %x\n", fp.iobuf->_flag); + r = fprintf(fp.f, "%s", "init"); + ok(r == 4, "fprintf returned %d\n", r); + ok(fp.iobuf->_flag & 0x40, "fp.iobuf->_flag = %x\n", fp.iobuf->_flag); + ok(fp.iobuf->_cnt + 4 == fp.iobuf->_bufsiz, "_cnt = %d, _bufsiz = %d\n", + fp.iobuf->_cnt, fp.iobuf->_bufsiz); + + ptr = fp.iobuf->_ptr; + cnt = fp.iobuf->_cnt; + r = fprintf(fp.f, "%s", "hello"); + ok(r == 5, "fprintf returned %d\n", r); + ok(ptr + 5 == fp.iobuf->_ptr, "fp.iobuf->_ptr = %p, expected %p\n", fp.iobuf->_ptr, ptr + 5); + ok(cnt - 5 == fp.iobuf->_cnt, "fp.iobuf->_cnt = %d, expected %d\n", fp.iobuf->_cnt, cnt - 5); + ok(fp.iobuf->_ptr + fp.iobuf->_cnt == fp.iobuf->_base + fp.iobuf->_bufsiz, + "_ptr = %p, _cnt = %d, _base = %p, _bufsiz = %d\n", + fp.iobuf->_ptr, fp.iobuf->_cnt, fp.iobuf->_base, fp.iobuf->_bufsiz); + + _get_stream_buffer_pointers(fp.f, &file_base, &file_ptr, &file_cnt); + ok(file_base == &fp.iobuf->_base, "_base = %p, expected %p\n", file_base, &fp.iobuf->_base); + ok(file_ptr == &fp.iobuf->_ptr, "_ptr = %p, expected %p\n", file_ptr, &fp.iobuf->_ptr); + ok(file_cnt == &fp.iobuf->_cnt, "_cnt = %p, expected %p\n", file_cnt, &fp.iobuf->_cnt); + + r = setvbuf(fp.f, NULL, _IONBF, 0); + ok(!r, "setvbuf returned %d\n", r); + ok(fp.iobuf->_flag & 0x400, "fp.iobuf->_flag = %x\n", fp.iobuf->_flag); + + ok(TryEnterCriticalSection(&fp.iobuf->_crit), "TryEnterCriticalSection section returned FALSE\n"); + LeaveCriticalSection(&fp.iobuf->_crit); + + fclose(fp.f); + unlink(tempf); +} + +static void test_std_stream_open(void) +{ + FILE *f; + int fd; + + fd = _dup(STDIN_FILENO); + ok(fd != -1, "_dup failed\n"); + + ok(!fclose(stdin), "fclose failed\n"); + f = fopen("nul", "r"); + ok(f != stdin, "f = %p, stdin = %p\n", f, stdin); + ok(_fileno(f) == STDIN_FILENO, "_fileno(f) = %d\n", _fileno(f)); + ok(!fclose(f), "fclose failed\n"); + + f = freopen("nul", "r", stdin); + ok(f == stdin, "f = %p, expected %p\n", f, stdin); + ok(_fileno(f) == STDIN_FILENO, "_fileno(f) = %d\n", _fileno(f)); + + _dup2(fd, STDIN_FILENO); + close(fd); +} + +static void test_fopen(void) +{ + int i; + FILE *f; + wchar_t wpath[MAX_PATH]; + static const struct { + const char *loc; + const char *path; + } tests[] = { + { "German.utf8", "t\xc3\xa4\xc3\x8f\xc3\xb6\xc3\x9f.txt" }, + { "Polish.utf8", "t\xc4\x99\xc5\x9b\xc4\x87.txt" }, + { "Turkish.utf8", "t\xc3\x87\xc4\x9e\xc4\xb1\xc4\xb0\xc5\x9e.txt" }, + { "Arabic.utf8", "t\xd8\xaa\xda\x86.txt" }, + { "Japanese.utf8", "t\xe3\x82\xaf\xe3\x83\xa4.txt" }, + { "Chinese.utf8", "t\xe4\xb8\x82\xe9\xbd\xab.txt" }, + { "Japanese", "t\xb8\xd5.txt" }, + + }; + + for(i=0; i +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "wine/test.h" + +#define DEFINE_EXPECT(func) \ + static BOOL expect_ ## func = FALSE, called_ ## func = FALSE + +#define SET_EXPECT(func) \ + expect_ ## func = TRUE + +#define CHECK_EXPECT2(func) \ + do { \ + ok(expect_ ##func, "unexpected call " #func "\n"); \ + called_ ## func = TRUE; \ + }while(0) + +#define CHECK_EXPECT(func) \ + do { \ + CHECK_EXPECT2(func); \ + expect_ ## func = FALSE; \ + }while(0) + +#define CHECK_CALLED(func) \ + do { \ + ok(called_ ## func, "expected " #func "\n"); \ + expect_ ## func = called_ ## func = FALSE; \ + }while(0) + +static inline double __port_min_pos_double(void) +{ + static const UINT64 __min_pos_double = 0x10000000000000; + return *(const double *)&__min_pos_double; +} + +static inline double __port_max_double(void) +{ + static const UINT64 __max_double = 0x7FEFFFFFFFFFFFFF; + return *(const double *)&__max_double; +} + +DEFINE_EXPECT(global_invalid_parameter_handler); +DEFINE_EXPECT(thread_invalid_parameter_handler); + +typedef struct { + const char *short_wday[7]; + const char *wday[7]; + const char *short_mon[12]; + const char *mon[12]; + const char *am; + const char *pm; + const char *short_date; + const char *date; + const char *time; + int unk; + int refcount; + const wchar_t *short_wdayW[7]; + const wchar_t *wdayW[7]; + const wchar_t *short_monW[12]; + const wchar_t *monW[12]; + const wchar_t *amW; + const wchar_t *pmW; + const wchar_t *short_dateW; + const wchar_t *dateW; + const wchar_t *timeW; + const wchar_t *locnameW; +} __lc_time_data; + +typedef void (__cdecl *_se_translator_function)(unsigned int code, struct _EXCEPTION_POINTERS *info); + +static LONGLONG crt_init_end; + +_ACRTIMP int __cdecl _o__initialize_onexit_table(_onexit_table_t *table); +_ACRTIMP int __cdecl _o__register_onexit_function(_onexit_table_t *table, _onexit_t func); +_ACRTIMP int __cdecl _o__execute_onexit_table(_onexit_table_t *table); +_ACRTIMP void *__cdecl _o_malloc(size_t); +_se_translator_function __cdecl _set_se_translator(_se_translator_function func); +void** __cdecl __current_exception(void); +int* __cdecl __processing_throw(void); + +#define _MAX__TIME64_T (((__time64_t)0x00000007 << 32) | 0x93406FFF) + +static void test__initialize_onexit_table(void) +{ + _onexit_table_t table, table2; + int ret; + + ret = _initialize_onexit_table(NULL); + ok(ret == -1, "got %d\n", ret); + + memset(&table, 0, sizeof(table)); + ret = _initialize_onexit_table(&table); + ok(ret == 0, "got %d\n", ret); + ok(table._first == table._last && table._first == table._end, "got first %p, last %p, end %p\n", + table._first, table._last, table._end); + + memset(&table2, 0, sizeof(table2)); + ret = _initialize_onexit_table(&table2); + ok(ret == 0, "got %d\n", ret); + ok(table2._first == table._first, "got %p, %p\n", table2._first, table._first); + ok(table2._last == table._last, "got %p, %p\n", table2._last, table._last); + ok(table2._end == table._end, "got %p, %p\n", table2._end, table._end); + + memset(&table2, 0, sizeof(table2)); + ret = _o__initialize_onexit_table(&table2); + ok(ret == 0, "got %d\n", ret); + ok(table2._first == table._first, "got %p, %p\n", table2._first, table._first); + ok(table2._last == table._last, "got %p, %p\n", table2._last, table._last); + ok(table2._end == table._end, "got %p, %p\n", table2._end, table._end); + + /* uninitialized table */ + table._first = table._last = table._end = (void*)0x123; + ret = _initialize_onexit_table(&table); + ok(ret == 0, "got %d\n", ret); + ok(table._first == table._last && table._first == table._end, "got first %p, last %p, end %p\n", + table._first, table._last, table._end); + ok(table._first != (void*)0x123, "got %p\n", table._first); + + table._first = (void*)0x123; + table._last = (void*)0x456; + table._end = (void*)0x123; + ret = _initialize_onexit_table(&table); + ok(ret == 0, "got %d\n", ret); + ok(table._first == table._last && table._first == table._end, "got first %p, last %p, end %p\n", + table._first, table._last, table._end); + ok(table._first != (void*)0x123, "got %p\n", table._first); + + table._first = (void*)0x123; + table._last = (void*)0x456; + table._end = (void*)0x789; + ret = _initialize_onexit_table(&table); + ok(ret == 0, "got %d\n", ret); + ok(table._first == (void*)0x123, "got %p\n", table._first); + ok(table._last == (void*)0x456, "got %p\n", table._last); + ok(table._end == (void*)0x789, "got %p\n", table._end); + + table._first = NULL; + table._last = (void*)0x456; + table._end = NULL; + ret = _initialize_onexit_table(&table); + ok(ret == 0, "got %d\n", ret); + ok(table._first == table._last && table._first == table._end, "got first %p, last %p, end %p\n", + table._first, table._last, table._end); +} + +static int g_onexit_called; +static int CDECL onexit_func(void) +{ + g_onexit_called++; + return 0; +} + +static int CDECL onexit_func2(void) +{ + ok(g_onexit_called == 0, "got %d\n", g_onexit_called); + g_onexit_called++; + return 0; +} + +static void test__register_onexit_function(void) +{ + _onexit_table_t table; + _PVFV *f; + int ret; + + memset(&table, 0, sizeof(table)); + ret = _initialize_onexit_table(&table); + ok(ret == 0, "got %d\n", ret); + + ret = _register_onexit_function(NULL, NULL); + ok(ret == -1, "got %d\n", ret); + + ret = _register_onexit_function(NULL, onexit_func); + ok(ret == -1, "got %d\n", ret); + + f = table._last; + ret = _register_onexit_function(&table, NULL); + ok(ret == 0, "got %d\n", ret); + ok(f != table._last, "got %p, initial %p\n", table._last, f); + + ret = _register_onexit_function(&table, onexit_func); + ok(ret == 0, "got %d\n", ret); + + f = table._last; + ret = _register_onexit_function(&table, onexit_func); + ok(ret == 0, "got %d\n", ret); + ok(f != table._last, "got %p, initial %p\n", table._last, f); + + f = table._last; + ret = _o__register_onexit_function(&table, NULL); + ok(ret == 0, "got %d\n", ret); + ok(f != table._last, "got %p, initial %p\n", table._last, f); + + f = table._last; + ret = _o__register_onexit_function(&table, onexit_func); + ok(ret == 0, "got %d\n", ret); + ok(f != table._last, "got %p, initial %p\n", table._last, f); + + ret = _execute_onexit_table(&table); + ok(ret == 0, "got %d\n", ret); +} + +static void test__execute_onexit_table(void) +{ + _onexit_table_t table; + int ret; + + ret = _execute_onexit_table(NULL); + ok(ret == -1, "got %d\n", ret); + + memset(&table, 0, sizeof(table)); + ret = _initialize_onexit_table(&table); + ok(ret == 0, "got %d\n", ret); + + /* execute empty table */ + ret = _execute_onexit_table(&table); + ok(ret == 0, "got %d\n", ret); + + /* same function registered multiple times */ + ret = _register_onexit_function(&table, onexit_func); + ok(ret == 0, "got %d\n", ret); + + ret = _register_onexit_function(&table, NULL); + ok(ret == 0, "got %d\n", ret); + + ret = _register_onexit_function(&table, onexit_func); + ok(ret == 0, "got %d\n", ret); + + ret = _o__register_onexit_function(&table, onexit_func); + ok(ret == 0, "got %d\n", ret); + + ok(table._first != table._end, "got %p, %p\n", table._first, table._end); + g_onexit_called = 0; + ret = _execute_onexit_table(&table); + ok(ret == 0, "got %d\n", ret); + ok(g_onexit_called == 3, "got %d\n", g_onexit_called); + ok(table._first == table._end, "got %p, %p\n", table._first, table._end); + + ret = _register_onexit_function(&table, onexit_func); + ok(ret == 0, "got %d\n", ret); + + ret = _register_onexit_function(&table, NULL); + ok(ret == 0, "got %d\n", ret); + + ret = _register_onexit_function(&table, onexit_func); + ok(ret == 0, "got %d\n", ret); + + ret = _o__register_onexit_function(&table, onexit_func); + ok(ret == 0, "got %d\n", ret); + + ok(table._first != table._end, "got %p, %p\n", table._first, table._end); + g_onexit_called = 0; + ret = _o__execute_onexit_table(&table); + ok(ret == 0, "got %d\n", ret); + ok(g_onexit_called == 3, "got %d\n", g_onexit_called); + ok(table._first == table._end, "got %p, %p\n", table._first, table._end); + + /* execute again, table is already empty */ + g_onexit_called = 0; + ret = _execute_onexit_table(&table); + ok(ret == 0, "got %d\n", ret); + ok(g_onexit_called == 0, "got %d\n", g_onexit_called); + + /* check call order */ + memset(&table, 0, sizeof(table)); + ret = _initialize_onexit_table(&table); + ok(ret == 0, "got %d\n", ret); + + ret = _register_onexit_function(&table, onexit_func); + ok(ret == 0, "got %d\n", ret); + + ret = _register_onexit_function(&table, onexit_func2); + ok(ret == 0, "got %d\n", ret); + + g_onexit_called = 0; + ret = _execute_onexit_table(&table); + ok(ret == 0, "got %d\n", ret); + ok(g_onexit_called == 2, "got %d\n", g_onexit_called); +} + +static void test___fpe_flt_rounds(void) +{ + unsigned int cfp = _controlfp(0, 0); + int ret; + + if(!cfp) { + skip("_controlfp not supported\n"); + return; + } + + ok((_controlfp(_RC_NEAR, _RC_CHOP) & _RC_CHOP) == _RC_NEAR, "_controlfp(_RC_NEAR, _RC_CHOP) failed\n"); + ret = __fpe_flt_rounds(); + ok(ret == 1, "__fpe_flt_rounds returned %d\n", ret); + + ok((_controlfp(_RC_UP, _RC_CHOP) & _RC_CHOP) == _RC_UP, "_controlfp(_RC_UP, _RC_CHOP) failed\n"); + ret = __fpe_flt_rounds(); + ok(ret == 2 || broken(ret == 3) /* w1064v1507 */, "__fpe_flt_rounds returned %d\n", ret); + + ok((_controlfp(_RC_DOWN, _RC_CHOP) & _RC_CHOP) == _RC_DOWN, "_controlfp(_RC_DOWN, _RC_CHOP) failed\n"); + ret = __fpe_flt_rounds(); + ok(ret == 3 || broken(ret == 2) /* w1064v1507 */, "__fpe_flt_rounds returned %d\n", ret); + + ok((_controlfp(_RC_CHOP, _RC_CHOP) & _RC_CHOP) == _RC_CHOP, "_controlfp(_RC_CHOP, _RC_CHOP) failed\n"); + ret = __fpe_flt_rounds(); + ok(ret == 0, "__fpe_flt_rounds returned %d\n", ret); + + _controlfp(cfp, _MCW_EM | _MCW_RC | _MCW_PC); +} + +static void test__control87_2(void) +{ +#ifdef __i386__ + unsigned int x86_cw_init, sse2_cw_init, x86_cw, sse2_cw, r; + + r = __control87_2(0, 0, &x86_cw_init, &sse2_cw_init); + ok(r == 1, "__control87_2 returned %d\n", r); + + r = __control87_2(0, _EM_INVALID, &x86_cw, NULL); + ok(r == 1, "__control87_2 returned %d\n", r); + ok(x86_cw == (x86_cw_init & ~_EM_INVALID), "x86_cw = %x, x86_cw_init = %x\n", x86_cw, x86_cw_init); + + r = __control87_2(0, 0, &x86_cw, &sse2_cw); + ok(r == 1, "__control87_2 returned %d\n", r); + ok(x86_cw == (x86_cw_init & ~_EM_INVALID), "x86_cw = %x, x86_cw_init = %x\n", x86_cw, x86_cw_init); + ok(sse2_cw == sse2_cw_init, "sse2_cw = %x, sse2_cw_init = %x\n", sse2_cw, sse2_cw_init); + + r = _control87(0, 0); + ok(r == (x86_cw | sse2_cw | _EM_AMBIGUOUS), "r = %x, expected %x\n", + r, x86_cw | sse2_cw | _EM_AMBIGUOUS); + + _control87(x86_cw_init, ~0); +#endif +} + +static void __cdecl global_invalid_parameter_handler( + const wchar_t *expression, const wchar_t *function, + const wchar_t *file, unsigned line, uintptr_t arg) +{ + CHECK_EXPECT2(global_invalid_parameter_handler); +} + +static void __cdecl thread_invalid_parameter_handler( + const wchar_t *expression, const wchar_t *function, + const wchar_t *file, unsigned line, uintptr_t arg) +{ + CHECK_EXPECT(thread_invalid_parameter_handler); +} + +static void test_invalid_parameter_handler(void) +{ + _invalid_parameter_handler ret; + + ret = _get_invalid_parameter_handler(); + ok(!ret, "ret != NULL\n"); + + ret = _get_thread_local_invalid_parameter_handler(); + ok(!ret, "ret != NULL\n"); + + ret = _set_thread_local_invalid_parameter_handler(thread_invalid_parameter_handler); + ok(!ret, "ret != NULL\n"); + + ret = _get_thread_local_invalid_parameter_handler(); + ok(ret == thread_invalid_parameter_handler, "ret = %p\n", ret); + + ret = _get_invalid_parameter_handler(); + ok(!ret, "ret != NULL\n"); + + ret = _set_invalid_parameter_handler(global_invalid_parameter_handler); + ok(!ret, "ret != NULL\n"); + + ret = _get_invalid_parameter_handler(); + ok(ret == global_invalid_parameter_handler, "ret = %p\n", ret); + + ret = _get_thread_local_invalid_parameter_handler(); + ok(ret == thread_invalid_parameter_handler, "ret = %p\n", ret); + + SET_EXPECT(thread_invalid_parameter_handler); + _ltoa_s(0, NULL, 0, 0); + CHECK_CALLED(thread_invalid_parameter_handler); + + ret = _set_thread_local_invalid_parameter_handler(NULL); + ok(ret == thread_invalid_parameter_handler, "ret = %p\n", ret); + + SET_EXPECT(global_invalid_parameter_handler); + _ltoa_s(0, NULL, 0, 0); + CHECK_CALLED(global_invalid_parameter_handler); + + ret = _set_invalid_parameter_handler(NULL); + ok(ret == global_invalid_parameter_handler, "ret = %p\n", ret); + + ret = _set_invalid_parameter_handler(global_invalid_parameter_handler); + ok(!ret, "ret != NULL\n"); +} + +static void test__get_narrow_winmain_command_line(char *path) +{ + PROCESS_INFORMATION proc; + STARTUPINFOA startup; + char cmd[MAX_PATH+32]; + char *ret, *cmdline, *name; + int len; + + ret = _get_narrow_winmain_command_line(); + cmdline = GetCommandLineA(); + len = strlen(cmdline); + ok(ret>cmdline && ret0; len--) + if(path[len-1]=='\\' || path[len-1]=='/') break; + if(len) name = path+len; + else name = path; + + sprintf(cmd, "\"\"%c\"\"\"%s\" \t \"misc\" cmd", name[0], name+1); + memset(&startup, 0, sizeof(startup)); + startup.cb = sizeof(startup); + CreateProcessA(path, cmd, NULL, NULL, TRUE, + CREATE_DEFAULT_ERROR_MODE|NORMAL_PRIORITY_CLASS, + NULL, NULL, &startup, &proc); + wait_child_process(proc.hProcess); + CloseHandle(proc.hProcess); + CloseHandle(proc.hThread); +} + +static void test__sopen_dispatch(void) +{ + int ret, fd; + char *tempf; + + tempf = _tempnam(".", "wne"); + + fd = 0; + ret = _sopen_dispatch(tempf, _O_CREAT, _SH_DENYWR, 0xff, &fd, 0); + ok(!ret, "got %d\n", ret); + ok(fd > 0, "got fd %d\n", fd); + _close(fd); + unlink(tempf); + + SET_EXPECT(global_invalid_parameter_handler); + fd = 0; + ret = _sopen_dispatch(tempf, _O_CREAT, _SH_DENYWR, 0xff, &fd, 1); + ok(ret == EINVAL, "got %d\n", ret); + ok(fd == -1, "got fd %d\n", fd); + CHECK_CALLED(global_invalid_parameter_handler); + if (fd > 0) + { + _close(fd); + unlink(tempf); + } + + free(tempf); +} + +static void test__sopen_s(void) +{ + int ret, fd; + char *tempf; + + tempf = _tempnam(".", "wne"); + + fd = 0; + ret = _sopen_s(&fd, tempf, _O_CREAT, _SH_DENYWR, 0); + ok(!ret, "got %d\n", ret); + ok(fd > 0, "got fd %d\n", fd); + _close(fd); + unlink(tempf); + + /* _open() does not validate pmode */ + fd = _open(tempf, _O_CREAT, 0xff); + ok(fd > 0, "got fd %d\n", fd); + _close(fd); + unlink(tempf); + + /* _sopen_s() invokes invalid parameter handler on invalid pmode */ + SET_EXPECT(global_invalid_parameter_handler); + fd = 0; + ret = _sopen_s(&fd, tempf, _O_CREAT, _SH_DENYWR, 0xff); + ok(ret == EINVAL, "got %d\n", ret); + ok(fd == -1, "got fd %d\n", fd); + CHECK_CALLED(global_invalid_parameter_handler); + + free(tempf); +} + +static void test_lldiv(void) +{ + lldiv_t r; + + r = lldiv(((LONGLONG)0x111 << 32) + 0x222, (LONGLONG)1 << 32); + ok(r.quot == 0x111, "quot = %s\n", wine_dbgstr_longlong(r.quot)); + ok(r.rem == 0x222, "rem = %s\n", wine_dbgstr_longlong(r.rem)); + + r = lldiv(((LONGLONG)0x69CF0012 << 32) + 0x0033E78A, 0x30); + ok(r.quot == ((LONGLONG)0x02345000 << 32) + 0x600114D2, "quot = %s\n", wine_dbgstr_longlong(r.quot)); + ok(r.rem == 0x2A, "rem = %s\n", wine_dbgstr_longlong(r.rem)); + + r = lldiv(((LONGLONG)0x243A5678 << 32) + 0x9ABCDEF0, (LONGLONG)0x12 << 48); + ok(r.quot == 0x0203, "quot = %s\n", wine_dbgstr_longlong(r.quot)); + ok(r.rem == ((LONGLONG)0x00045678 << 32) + 0x9ABCDEF0, "rem = %s\n", wine_dbgstr_longlong(r.rem)); +} + +static void test_isblank(void) +{ + int c, r; + + for(c = 0; c <= 0xff; c++) { + if(c == '\t') { + ok(!_isctype(c, _BLANK), "tab shouldn't be blank\n"); + ok(isblank(c), "%d should be blank\n", c); + r = _isblank_l(c, NULL); + ok(!r || broken(r == _BLANK), "tab shouldn't be blank (got %x)\n", r); + } else if(c == ' ') { + ok(_isctype(c, _BLANK), "space should be blank\n"); + ok(isblank(c), "%d should be blank\n", c); + r = _isblank_l(c, NULL); + ok(r == _BLANK, "space should be blank (got %x)\n", r); + } else { + ok(!_isctype(c, _BLANK), "%d shouldn't be blank\n", c); + ok(!isblank(c), "%d shouldn't be blank\n", c); + ok(!_isblank_l(c, NULL), "%d shouldn't be blank\n", c); + } + } + + for(c = 0; c <= 0xffff; c++) { + if(c == '\t' || c == ' ' || c == 0x3000 || c == 0xfeff) { + if(c == '\t') + ok(!_iswctype_l(c, _BLANK, NULL), "tab shouldn't be blank\n"); + else + ok(_iswctype_l(c, _BLANK, NULL), "%d should be blank\n", c); + ok(iswblank(c), "%d should be blank\n", c); + ok(_iswblank_l(c, NULL), "%d should be blank\n", c); + } else { + ok(!_iswctype_l(c, _BLANK, NULL), "%d shouldn't be blank\n", c); + ok(!iswblank(c), "%d shouldn't be blank\n", c); + ok(!_iswblank_l(c, NULL), "%d shouldn't be blank\n", c); + } + } +} + +static struct _exception exception; + +static int CDECL matherr_callback(struct _exception *e) +{ + exception = *e; + + if (!strcmp(e->name, "acos") && e->arg1 == 2) + e->retval = -1; + return 0; +} + +static void test_math_errors(void) +{ + const struct { + char func[16]; + double x; + int error; + int exception; + } testsd[] = { + {"_logb", -INFINITY, -1, -1}, + {"_logb", -1, -1, -1}, + {"_logb", 0, ERANGE, _SING}, + {"_logb", INFINITY, -1, -1}, + {"acos", -INFINITY, EDOM, _DOMAIN}, + {"acos", -2, EDOM, _DOMAIN}, + {"acos", -1, -1, -1}, + {"acos", 1, -1, -1}, + {"acos", 2, EDOM, _DOMAIN}, + {"acos", INFINITY, EDOM, _DOMAIN}, + {"acosh", -INFINITY, EDOM, -1}, + {"acosh", 0, EDOM, -1}, + {"acosh", 1, -1, -1}, + {"acosh", INFINITY, -1, -1}, + {"asin", -INFINITY, EDOM, _DOMAIN}, + {"asin", -2, EDOM, _DOMAIN}, + {"asin", -1, -1, -1}, + {"asin", 1, -1, -1}, + {"asin", 2, EDOM, _DOMAIN}, + {"asin", INFINITY, EDOM, _DOMAIN}, + {"asinh", -INFINITY, -1, -1}, + {"asinh", INFINITY, -1, -1}, + {"atan", -INFINITY, -1, -1}, + {"atan", 0, -1, -1}, + {"atan", INFINITY, -1, -1}, + {"atanh", -INFINITY, EDOM, -1}, + {"atanh", -2, EDOM, -1}, + {"atanh", -1, ERANGE, -1}, + {"atanh", 1, ERANGE, -1}, + {"atanh", 2, EDOM, -1}, + {"atanh", INFINITY, EDOM, -1}, + {"cos", -INFINITY, EDOM, _DOMAIN}, + {"cos", INFINITY, EDOM, _DOMAIN}, + {"cosh", -INFINITY, -1, -1}, + {"cosh", 0, -1, -1}, + {"cosh", INFINITY, -1, -1}, + {"exp", -INFINITY, -1, -1}, + {"exp", -1e100, -1, _UNDERFLOW}, + {"exp", 1e100, ERANGE, _OVERFLOW}, + {"exp", INFINITY, -1, -1}, + {"exp2", -INFINITY, -1, -1}, + {"exp2", -1e100, -1, -1}, + {"exp2", 1e100, ERANGE, -1}, + {"exp2", INFINITY, -1, -1}, + {"expm1", -INFINITY, -1, -1}, + {"expm1", INFINITY, -1, -1}, + {"log", -INFINITY, EDOM, _DOMAIN}, + {"log", -1, EDOM, _DOMAIN}, + {"log", 0, ERANGE, _SING}, + {"log", INFINITY, -1, -1}, + {"log10", -INFINITY, EDOM, _DOMAIN}, + {"log10", -1, EDOM, _DOMAIN}, + {"log10", 0, ERANGE, _SING}, + {"log10", INFINITY, -1, -1}, + {"log1p", -INFINITY, EDOM, -1}, + {"log1p", -2, EDOM, -1}, + {"log1p", -1, ERANGE, -1}, + {"log1p", INFINITY, -1, -1}, + {"log2", INFINITY, -1, -1}, + {"sin", -INFINITY, EDOM, _DOMAIN}, + {"sin", INFINITY, EDOM, _DOMAIN}, + {"sinh", -INFINITY, -1, -1}, + {"sinh", 0, -1, -1}, + {"sinh", INFINITY, -1, -1}, + {"sqrt", -INFINITY, EDOM, _DOMAIN}, + {"sqrt", -1, EDOM, _DOMAIN}, + {"sqrt", 0, -1, -1}, + {"sqrt", INFINITY, -1, -1}, + {"tan", -INFINITY, EDOM, _DOMAIN}, + {"tan", -M_PI_2, -1, -1}, + {"tan", M_PI_2, -1, -1}, + {"tan", INFINITY, EDOM, _DOMAIN}, + {"tanh", -INFINITY, -1, -1}, + {"tanh", 0, -1, -1}, + {"tanh", INFINITY, -1, -1}, + }; + const struct { + char func[16]; + double a; + double b; + int error; + int exception; + } tests2d[] = { + {"atan2", -INFINITY, 0, -1, -1}, + {"atan2", 0, 0, -1, -1}, + {"atan2", INFINITY, 0, -1, -1}, + {"atan2", 0, -INFINITY, -1, -1}, + {"atan2", 0, INFINITY, -1, -1}, + {"pow", -INFINITY, -2, -1, -1}, + {"pow", -INFINITY, -1, -1, -1}, + {"pow", -INFINITY, 0, -1, -1}, + {"pow", -INFINITY, 1, -1, -1}, + {"pow", -INFINITY, 2, -1, -1}, + {"pow", -1e100, -10, -1, _UNDERFLOW}, + {"pow", -1e100, 10, ERANGE, _OVERFLOW}, + {"pow", -1, 1.5, EDOM, _DOMAIN}, + {"pow", 0, -2, ERANGE, _SING}, + {"pow", 0, -1, ERANGE, _SING}, + {"pow", 0.5, -INFINITY, -1, -1}, + {"pow", 0.5, INFINITY, -1, -1}, + {"pow", 2, -INFINITY, -1, -1}, + {"pow", 2, -1e100, -1, _UNDERFLOW}, + {"pow", 2, 1e100, ERANGE, _OVERFLOW}, + {"pow", 2, INFINITY, -1, -1}, + {"pow", 1e100, -10, -1, _UNDERFLOW}, + {"pow", 1e100, 10, ERANGE, _OVERFLOW}, + {"pow", INFINITY, -2, -1, -1}, + {"pow", INFINITY, -1, -1, -1}, + {"pow", INFINITY, 0, -1, -1}, + {"pow", INFINITY, 1, -1, -1}, + {"pow", INFINITY, 2, -1, -1}, + }; + const struct { + char func[16]; + double a; + double b; + double c; + int error; + int exception; + } tests3d[] = { + /* 0 * inf --> EDOM */ + {"fma", INFINITY, 0, 0, EDOM, -1}, + {"fma", 0, INFINITY, 0, EDOM, -1}, + /* inf - inf -> EDOM */ + {"fma", INFINITY, 1, -INFINITY, EDOM, -1}, + {"fma", -INFINITY, 1, INFINITY, EDOM, -1}, + {"fma", 1, INFINITY, -INFINITY, EDOM, -1}, + {"fma", 1, -INFINITY, INFINITY, EDOM, -1}, + /* NaN */ + {"fma", NAN, 0, 0, -1, -1}, + {"fma", 0, NAN, 0, -1, -1}, + {"fma", 0, 0, NAN, -1, -1}, + /* over/underflow */ + {"fma", __port_max_double(), __port_max_double(), __port_max_double(), -1, -1}, + {"fma", __port_min_pos_double(), __port_min_pos_double(), 1, -1, -1}, + }; + const struct { + char func[16]; + double a; + long b; + int error; + int exception; + } testsdl[] = { + {"_scalb", -INFINITY, 1, -1, -1}, + {"_scalb", -1e100, 1, -1, -1}, + {"_scalb", 0, 1, -1, -1}, + {"_scalb", 1e100, 1, -1, -1}, + {"_scalb", INFINITY, 1, -1, -1}, + {"_scalb", 1, 1e9, ERANGE, _OVERFLOW}, + {"ldexp", -INFINITY, 1, -1, -1}, + {"ldexp", -1e100, 1, -1, -1}, + {"ldexp", 0, 1, -1, -1}, + {"ldexp", 1e100, 1, -1, -1}, + {"ldexp", INFINITY, 1, -1, -1}, + {"ldexp", 1, -1e9, -1, _UNDERFLOW}, + {"ldexp", 1, 1e9, ERANGE, _OVERFLOW}, + }; + double (CDECL *p_funcd)(double); + double (CDECL *p_func2d)(double, double); + double (CDECL *p_func3d)(double, double, double); + double (CDECL *p_funcdl)(double, long); + HMODULE module; + double d; + int i; + + __setusermatherr(matherr_callback); + module = GetModuleHandleW(L"ucrtbase.dll"); + + /* necessary so that exp(1e100)==INFINITY on glibc, we can remove this if we change our implementation */ + fesetround(FE_TONEAREST); + + for(i = 0; i < ARRAY_SIZE(testsd); i++) { + p_funcd = (void*)GetProcAddress(module, testsd[i].func); + errno = -1; + exception.type = -1; + p_funcd(testsd[i].x); + ok(errno == testsd[i].error, + "%s(%f) got errno %d\n", testsd[i].func, testsd[i].x, errno); + ok(exception.type == testsd[i].exception, + "%s(%f) got exception type %d\n", testsd[i].func, testsd[i].x, exception.type); + if(exception.type == -1) continue; + ok(exception.arg1 == testsd[i].x, + "%s(%f) got exception arg1 %f\n", testsd[i].func, testsd[i].x, exception.arg1); + } + + for(i = 0; i < ARRAY_SIZE(tests2d); i++) { + p_func2d = (void*)GetProcAddress(module, tests2d[i].func); + errno = -1; + exception.type = -1; + p_func2d(tests2d[i].a, tests2d[i].b); + ok(errno == tests2d[i].error, + "%s(%f, %f) got errno %d\n", tests2d[i].func, tests2d[i].a, tests2d[i].b, errno); + ok(exception.type == tests2d[i].exception, + "%s(%f, %f) got exception type %d\n", tests2d[i].func, tests2d[i].a, tests2d[i].b, exception.type); + if(exception.type == -1) continue; + ok(exception.arg1 == tests2d[i].a, + "%s(%f, %f) got exception arg1 %f\n", tests2d[i].func, tests2d[i].a, tests2d[i].b, exception.arg1); + ok(exception.arg2 == tests2d[i].b, + "%s(%f, %f) got exception arg2 %f\n", tests2d[i].func, tests2d[i].a, tests2d[i].b, exception.arg2); + } + + for(i = 0; i < ARRAY_SIZE(tests3d); i++) { + p_func3d = (void*)GetProcAddress(module, tests3d[i].func); + errno = -1; + exception.type = -1; + p_func3d(tests3d[i].a, tests3d[i].b, tests3d[i].c); + ok(errno == tests3d[i].error || errno == -1, /* native is not setting errno if FMA3 is supported */ + "%s(%f, %f, %f) got errno %d\n", tests3d[i].func, tests3d[i].a, tests3d[i].b, tests3d[i].c, errno); + ok(exception.type == tests3d[i].exception, + "%s(%f, %f, %f) got exception type %d\n", tests3d[i].func, tests3d[i].a, tests3d[i].b, tests3d[i].c, exception.type); + if(exception.type == -1) continue; + ok(exception.arg1 == tests3d[i].a, + "%s(%f, %f, %f) got exception arg1 %f\n", tests3d[i].func, tests3d[i].a, tests3d[i].b, tests3d[i].c, exception.arg1); + ok(exception.arg2 == tests3d[i].b, + "%s(%f, %f, %f) got exception arg2 %f\n", tests3d[i].func, tests3d[i].a, tests3d[i].b, tests3d[i].c, exception.arg2); + } + + for(i = 0; i < ARRAY_SIZE(testsdl); i++) { + p_funcdl = (void*)GetProcAddress(module, testsdl[i].func); + errno = -1; + exception.type = -1; + p_funcdl(testsdl[i].a, testsdl[i].b); + ok(errno == testsdl[i].error, + "%s(%f, %ld) got errno %d\n", testsdl[i].func, testsdl[i].a, testsdl[i].b, errno); + ok(exception.type == testsdl[i].exception, + "%s(%f, %ld) got exception type %d\n", testsdl[i].func, testsdl[i].a, testsdl[i].b, exception.type); + if(exception.type == -1) continue; + ok(exception.arg1 == testsdl[i].a, + "%s(%f, %ld) got exception arg1 %f\n", testsdl[i].func, testsdl[i].a, testsdl[i].b, exception.arg1); + ok(exception.arg2 == testsdl[i].b, + "%s(%f, %ld) got exception arg2 %f\n", testsdl[i].func, testsdl[i].a, testsdl[i].b, exception.arg2); + } + + d = acos(2.0); + ok(d == -1.0, "failed to change log10 return value: %e\n", d); +} + +static void test_asctime(void) +{ + const struct tm epoch = { 0, 0, 0, 1, 0, 70, 4, 0, 0 }; + char *ret; + + ret = asctime(&epoch); + ok(!strcmp(ret, "Thu Jan 1 00:00:00 1970\n"), "asctime returned %s\n", ret); +} + +static void test_strftime(void) +{ + const struct { + const char *format; + const char *ret; + struct tm tm; + BOOL todo_value; + BOOL todo_handler; + } tests[] = { + {"%C", "", { 0, 0, 0, 1, 0, -2000, 4, 0, 0 }}, + {"%C", "", { 0, 0, 0, 1, 0, -1901, 4, 0, 0 }}, + {"%C", "00", { 0, 0, 0, 1, 0, -1900, 4, 0, 0 }}, + {"%C", "18", { 0, 0, 0, 1, 0, -1, 4, 0, 0 }}, + {"%C", "19", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%C", "99", { 0, 0, 0, 1, 0, 8099, 4, 0, 0 }}, + {"%C", "", { 0, 0, 0, 1, 0, 8100, 4, 0, 0 }}, + {"%d", "", { 0, 0, 0, 0, 0, 70, 4, 0, 0 }}, + {"%d", "01", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%d", "31", { 0, 0, 0, 31, 0, 70, 4, 0, 0 }}, + {"%d", "", { 0, 0, 0, 32, 0, 70, 4, 0, 0 }}, + {"%D", "", { 0, 0, 0, 1, 0, -1901, 4, 0, 0 }}, + {"%D", "01/01/00", { 0, 0, 0, 1, 0, -1900, 4, 0, 0 }}, + {"%D", "01/01/99", { 0, 0, 0, 1, 0, -1, 4, 0, 0 }}, + {"%D", "01/01/70", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%D", "01/01/99", { 0, 0, 0, 1, 0, 8099, 4, 0, 0 }}, + {"%D", "", { 0, 0, 0, 1, 0, 8100, 4, 0, 0 }}, + {"%#D", "1/1/70", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%e", "", { 0, 0, 0, 0, 0, 70, 4, 0, 0 }}, + {"%e", " 1", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%e", "31", { 0, 0, 0, 31, 0, 70, 4, 0, 0 }}, + {"%e", "", { 0, 0, 0, 32, 0, 70, 4, 0, 0 }}, + {"%#e", "1", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%F", "1970-01-01", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%#F", "1970-1-1", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%R", "00:00", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%#R", "0:0", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%T", "00:00:00", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%#T", "0:0:0", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%u", "", { 0, 0, 0, 1, 0, 117, -1, 0, 0 }}, + {"%u", "7", { 0, 0, 0, 1, 0, 117, 0, 0, 0 }}, + {"%u", "1", { 0, 0, 0, 1, 0, 117, 1, 0, 0 }}, + {"%u", "6", { 0, 0, 0, 1, 0, 117, 6, 0, 0 }}, + {"%u", "", { 0, 0, 0, 1, 0, 117, 7, 0, 0 }}, + {"%h", "Jan", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%I", "", { 0, 0, -1, 1, 0, 70, 4, 0, 0 }}, + {"%I", "12", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%I", "01", { 0, 0, 1, 1, 0, 70, 4, 0, 0 }}, + {"%I", "11", { 0, 0, 11, 1, 0, 70, 4, 0, 0 }}, + {"%I", "12", { 0, 0, 12, 1, 0, 70, 4, 0, 0 }}, + {"%I", "01", { 0, 0, 13, 1, 0, 70, 4, 0, 0 }}, + {"%I", "11", { 0, 0, 23, 1, 0, 70, 4, 0, 0 }}, + {"%I", "", { 0, 0, 24, 1, 0, 70, 4, 0, 0 }}, + {"%n", "\n", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%r", "12:00:00 AM", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%r", "02:00:00 PM", { 0, 0, 14, 1, 0, 121, 6, 0, 0 }}, + {"%#r", "12:0:0 AM", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%#r", "2:0:0 PM", { 0, 0, 14, 1, 0, 121, 6, 0, 0 }}, + {"%t", "\t", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%g", "", { 0, 0, 0, 1, 0, -1901, 4, 0, 0 }}, + {"%g", "", { 0, 0, 0, 1, 0, -1901, 3, 364, 0 }}, + {"%g", "00", { 0, 0, 0, 1, 0, -1900, 4, 0, 0 }}, + {"%g", "70", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%g", "71", { 0, 0, 0, 2, 0, 72, 0, 1, 0 }}, + {"%g", "72", { 0, 0, 0, 3, 0, 72, 1, 2, 0 }}, + {"%g", "16", { 0, 0, 0, 1, 0, 117, 0, 0, 0 }}, + {"%g", "99", { 0, 0, 0, 1, 0, 8099, 4, 0, 0 }}, + {"%g", "00", { 0, 0, 0, 1, 0, 8099, 3, 364, 0 }}, + {"%g", "", { 0, 0, 0, 1, 0, 8100, 0, 0, 0 }}, + {"%g", "", { 0, 0, 0, 1, 0, 8100, 4, 0, 0 }}, + {"%G", "1970", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%G", "1971", { 0, 0, 0, 2, 0, 72, 0, 1, 0 }}, + {"%G", "1972", { 0, 0, 0, 3, 0, 72, 1, 2, 0 }}, + {"%G", "2016", { 0, 0, 0, 1, 0, 117, 0, 0, 0 }}, + {"%V", "01", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%V", "52", { 0, 0, 0, 1, 0, 117, 0, 0, 0 }}, + {"%V", "53", { 0, 0, 14, 1, 0, 121, 6, 0, 0 }}, + {"%y", "", { 0, 0, 0, 0, 0, -1901, 0, 0, 0 }}, + {"%y", "00", { 0, 0, 0, 0, 0, -1900, 0, 0, 0 }}, + {"%y", "99", { 0, 0, 0, 0, 0, 8099, 0, 0, 0 }}, + {"%y", "", { 0, 0, 0, 0, 0, 8100, 0, 0, 0 }}, + {"%c", "Thu Jan 1 00:00:00 1970", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%c", "Thu Feb 30 00:00:00 1970", { 0, 0, 0, 30, 1, 70, 4, 0, 0 }}, + {"%#c", "Thursday, January 01, 1970 00:00:00", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%#c", "Thursday, February 30, 1970 00:00:00", { 0, 0, 0, 30, 1, 70, 4, 0, 0 }}, + {"%x", "01/01/70", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%x", "02/30/70", { 0, 0, 0, 30, 1, 70, 4, 0, 0 }}, + {"%#x", "Thursday, January 01, 1970", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%#x", "Thursday, February 30, 1970", { 0, 0, 0, 30, 1, 70, 4, 0, 0 }}, + {"%#x", "", { 0, 0, 0, 30, 1, 70, 7, 0, 0 }}, + {"%#x", "", { 0, 0, 0, 30, 12, 70, 4, 0, 0 }}, + {"%X", "00:00:00", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, + {"%X", "14:00:00", { 0, 0, 14, 1, 0, 70, 4, 0, 0 }}, + {"%X", "23:59:60", { 60, 59, 23, 1, 0, 70, 4, 0, 0 }}, + }; + + const struct { + const char *format; + const char *ret; + const wchar_t *short_date; + const wchar_t *date; + const wchar_t *time; + struct tm tm; + BOOL todo; + } tests_td[] = { + { "%c", "x z", L"x", L"y", L"z", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%#c", "y z", L"x", L"y", L"z", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%X", "M1", 0, 0, L"MMM", { 0, 0, 1, 1, 0, 70, 0, 0, 0 }}, + { "%X", "1", 0, 0, L"h", { 0, 0, 1, 1, 0, 70, 0, 0, 0 }}, + { "%X", "01", 0, 0, L"hh", { 0, 0, 1, 1, 0, 70, 0, 0, 0 }}, + { "%X", "h01", 0, 0, L"hhh", { 0, 0, 1, 1, 0, 70, 0, 0, 0 }}, + { "%X", "hh01", 0, 0, L"hhhh", { 0, 0, 1, 1, 0, 70, 0, 0, 0 }}, + { "%X", "1", 0, 0, L"H", { 0, 0, 1, 1, 0, 70, 0, 0, 0 }}, + { "%X", "01", 0, 0, L"HH", { 0, 0, 1, 1, 0, 70, 0, 0, 0 }}, + { "%X", "H13", 0, 0, L"HHH", { 0, 0, 13, 1, 0, 70, 0, 0, 0 }}, + { "%X", "0", 0, 0, L"m", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%X", "00", 0, 0, L"mm", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%X", "m00", 0, 0, L"mmm", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%X", "0", 0, 0, L"s", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%X", "00", 0, 0, L"ss", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%X", "s00", 0, 0, L"sss", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%X", "T", 0, 0, L"t", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%X", "TAM", 0, 0, L"tt", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%X", "TAM", 0, 0, L"ttttttttt", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%X", "TAM", 0, 0, L"a", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%X", "TAM", 0, 0, L"aaaaa", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%X", "TAM", 0, 0, L"A", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%X", "TAM", 0, 0, L"AAAAA", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%x", "1", L"d", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%x", "01", L"dd", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%x", "D1", L"ddd", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%x", "Day1", L"dddd", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%x", "dDay1", L"ddddd", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%x", "1", L"M", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%x", "01", L"MM", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%x", "M1", L"MMM", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%x", "Mon1", L"MMMM", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%x", "MMon1", L"MMMMM", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%x", "y", L"y", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%x", "70", L"yy", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%x", "y70", L"yyy", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%x", "1970", L"yyyy", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%x", "y1970", L"yyyyy", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%x", "ggggggggggg", L"ggggggggggg", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%#x", "1", 0, L"d", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%#x", "01", 0, L"dd", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%#x", "D1", 0, L"ddd", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%#x", "Day1", 0, L"dddd", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%#x", "dDay1", 0, L"ddddd", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%#x", "1", 0, L"M", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%#x", "01", 0, L"MM", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%#x", "M1", 0, L"MMM", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%#x", "Mon1", 0, L"MMMM", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%#x", "MMon1", 0, L"MMMMM", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%#x", "y", 0, L"y", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%#x", "70", 0, L"yy", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%#x", "y70", 0, L"yyy", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%#x", "1970", 0, L"yyyy", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%#x", "y1970", 0, L"yyyyy", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + { "%r", "z", L"x", L"y", L"z", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }}, + }; + + const struct { + int year; + int yday; + const char *ret[7]; + } tests_yweek[] = { + { 100, 0, { "99 52", "00 01", "00 01", "00 01", "00 01", "99 53", "99 52" }}, + { 100, 1, { "99 52", "00 01", "00 01", "00 01", "00 01", "00 01", "99 53" }}, + { 100, 2, { "99 53", "00 01", "00 01", "00 01", "00 01", "00 01", "00 01" }}, + { 100, 3, { "00 01", "00 01", "00 01", "00 01", "00 01", "00 01", "00 01" }}, + { 100, 4, { "00 01", "00 02", "00 01", "00 01", "00 01", "00 01", "00 01" }}, + { 100, 5, { "00 01", "00 02", "00 02", "00 01", "00 01", "00 01", "00 01" }}, + { 100, 6, { "00 01", "00 02", "00 02", "00 02", "00 01", "00 01", "00 01" }}, + { 100, 358, { "00 51", "00 52", "00 52", "00 52", "00 52", "00 52", "00 51" }}, + { 100, 359, { "00 51", "00 52", "00 52", "00 52", "00 52", "00 52", "00 52" }}, + { 100, 360, { "00 52", "00 52", "00 52", "00 52", "00 52", "00 52", "00 52" }}, + { 100, 361, { "00 52", "00 53", "00 52", "00 52", "00 52", "00 52", "00 52" }}, + { 100, 362, { "00 52", "00 53", "00 53", "00 52", "00 52", "00 52", "00 52" }}, + { 100, 363, { "00 52", "01 01", "00 53", "00 53", "00 52", "00 52", "00 52" }}, + { 100, 364, { "00 52", "01 01", "01 01", "00 53", "00 53", "00 52", "00 52" }}, + { 100, 365, { "00 52", "01 01", "01 01", "01 01", "00 53", "00 53", "00 52" }}, + { 101, 0, { "00 52", "01 01", "01 01", "01 01", "01 01", "00 53", "00 53" }}, + { 101, 1, { "00 53", "01 01", "01 01", "01 01", "01 01", "01 01", "00 53" }}, + { 101, 2, { "00 53", "01 01", "01 01", "01 01", "01 01", "01 01", "01 01" }}, + { 101, 3, { "01 01", "01 01", "01 01", "01 01", "01 01", "01 01", "01 01" }}, + { 101, 4, { "01 01", "01 02", "01 01", "01 01", "01 01", "01 01", "01 01" }}, + { 101, 5, { "01 01", "01 02", "01 02", "01 01", "01 01", "01 01", "01 01" }}, + { 101, 6, { "01 01", "01 02", "01 02", "01 02", "01 01", "01 01", "01 01" }}, + { 101, 358, { "01 51", "01 52", "01 52", "01 52", "01 52", "01 52", "01 51" }}, + { 101, 359, { "01 51", "01 52", "01 52", "01 52", "01 52", "01 52", "01 52" }}, + { 101, 360, { "01 52", "01 52", "01 52", "01 52", "01 52", "01 52", "01 52" }}, + { 101, 361, { "01 52", "01 53", "01 52", "01 52", "01 52", "01 52", "01 52" }}, + { 101, 362, { "01 52", "02 01", "01 53", "01 52", "01 52", "01 52", "01 52" }}, + { 101, 363, { "01 52", "02 01", "02 01", "01 53", "01 52", "01 52", "01 52" }}, + { 101, 364, { "01 52", "02 01", "02 01", "02 01", "01 53", "01 52", "01 52" }}, + }; + + __lc_time_data time_data = { + { "d1", "d2", "d3", "d4", "d5", "d6", "d7" }, + { "day1", "day2", "day3", "day4", "day5", "day6", "day7" }, + { "m1", "m2", "m3", "m4", "m5", "m6", "m7", "m8", "m9", "m10", "m11", "m12" }, + { "mon1", "mon2", "mon3", "mon4", "mon5", "mon6", "mon7", "mon8", "mon9", "mon10", "mon11", "mon12" }, + "tam", "tpm", 0, 0, 0, 1, 0, + { L"D1", L"D2", L"D3", L"D4", L"D5", L"D6", L"D7" }, + { L"Day1", L"Day2", L"Day3", L"Day4", L"Day5", L"Day6", L"Day7" }, + { L"M1", L"M2", L"M3", L"M4", L"M5", L"M6", L"M7", L"M8", L"M9", L"M10", L"M11", L"M12" }, + { L"Mon1", L"Mon2", L"Mon3", L"Mon4", L"Mon5", L"Mon6", L"Mon7", L"Mon8", L"Mon9", L"Mon10", L"Mon11", L"Mon12" }, + L"TAM", L"TPM" + }; + + const struct tm epoch = { 0, 0, 0, 1, 0, 70, 4, 0, 0 }; + struct tm tm_yweek = { 0, 0, 0, 1, 0, 70, 0, 0, 0 }; + char buf[256]; + int i, ret=0; + + for (i=0; i= 0) + { + ret = _stat32(path, &buf); + ok(!ret, "_stat32('%s') returned %d\n", path, ret); + strcat(path, "\\"); + ret = _stat32(path, &buf); + ok(ret, "_stat32('%s') returned %d\n", path, ret); + close(fd); + remove(path); + } + + memcpy(path+len, test_dir, sizeof(test_dir)); + if(!mkdir(path)) + { + ret = _stat32(path, &buf); + ok(!ret, "_stat32('%s') returned %d\n", path, ret); + strcat(path, "\\"); + ret = _stat32(path, &buf); + ok(!ret, "_stat32('%s') returned %d\n", path, ret); + rmdir(path); + } +} + +static void test__o_malloc(void) +{ + void *m; + size_t s; + + m = _o_malloc(1); + ok(m != NULL, "p__o_malloc(1) returned NULL\n"); + + s = _msize(m); + ok(s == 1, "_msize returned %d\n", (int)s); + + free(m); +} + +static void test_clock(void) +{ + static const int thresh = 100, max_load_delay = 1000; + int c, expect_min; + FILETIME cur; + + GetSystemTimeAsFileTime(&cur); + c = clock(); + + expect_min = (((LONGLONG)cur.dwHighDateTime << 32) + cur.dwLowDateTime - crt_init_end) / 10000; + ok(c >= expect_min - thresh && c < expect_min + max_load_delay, "clock() = %d, expected range [%d, %d]\n", + c, expect_min - thresh, expect_min + max_load_delay); +} + +static void __cdecl se_translator(unsigned int u, EXCEPTION_POINTERS *ep) +{ +} + +static void test_thread_storage(void) +{ + void **current_exception; + void *processing_throw; + + _set_se_translator(se_translator); + current_exception = __current_exception(); + processing_throw = __processing_throw(); + + ok(current_exception+2 == processing_throw, + "current_exception = %p, processing_throw = %p\n", + current_exception, processing_throw); + ok(current_exception[-2] == se_translator, + "can't find se_translator in thread storage\n"); +} + +static unsigned long fenv_encode(unsigned int e) +{ + ok(!(e & ~FE_ALL_EXCEPT), "incorrect argument: %x\n", e); + +#if defined(__i386__) + return e<<24 | e<<16 | e; +#elif defined(__x86_64__) + return e<<24 | e; +#else + return e; +#endif +} + +static void test_fenv(void) +{ + static const int tests[] = { + 0, + FE_INEXACT, + FE_UNDERFLOW, + FE_OVERFLOW, + FE_DIVBYZERO, + FE_INVALID, + FE_ALL_EXCEPT, + }; + static const struct { + fexcept_t except; + unsigned int flag; + unsigned int get; + fexcept_t expect; + } tests2[] = { + /* except flag get expect */ + { 0, 0, 0, 0 }, + { FE_ALL_EXCEPT, FE_INEXACT, 0, 0 }, + { FE_ALL_EXCEPT, FE_INEXACT, FE_ALL_EXCEPT, FE_INEXACT }, + { FE_ALL_EXCEPT, FE_INEXACT, FE_INEXACT, FE_INEXACT }, + { FE_ALL_EXCEPT, FE_INEXACT, FE_OVERFLOW, 0 }, + { FE_ALL_EXCEPT, FE_ALL_EXCEPT, FE_ALL_EXCEPT, FE_ALL_EXCEPT }, + { FE_ALL_EXCEPT, FE_ALL_EXCEPT, FE_INEXACT, FE_INEXACT }, + { FE_ALL_EXCEPT, FE_ALL_EXCEPT, 0, 0 }, + { FE_ALL_EXCEPT, FE_ALL_EXCEPT, ~0, FE_ALL_EXCEPT }, + { FE_ALL_EXCEPT, FE_ALL_EXCEPT, ~FE_ALL_EXCEPT, 0 }, + { FE_INEXACT, FE_ALL_EXCEPT, FE_ALL_EXCEPT, FE_INEXACT }, + { FE_INEXACT, FE_UNDERFLOW, FE_ALL_EXCEPT, 0 }, + { FE_UNDERFLOW, FE_INEXACT, FE_ALL_EXCEPT, 0 }, + { FE_INEXACT|FE_UNDERFLOW, FE_UNDERFLOW, FE_ALL_EXCEPT, FE_UNDERFLOW }, + { FE_UNDERFLOW, FE_INEXACT|FE_UNDERFLOW, FE_ALL_EXCEPT, FE_UNDERFLOW }, + }; + fenv_t env, env2; + fexcept_t except; + int i, ret, flags; + + _clearfp(); + + ret = fegetenv(&env); + ok(!ret, "fegetenv returned %x\n", ret); +#if defined(__i386__) || defined(__x86_64__) + if (env._Fe_ctl >> 24 != (env._Fe_ctl & 0xff)) + { + win_skip("fenv_t format not supported (too old ucrtbase)\n"); + return; + } +#endif + fesetround(FE_UPWARD); + ok(!env._Fe_stat, "env._Fe_stat = %lx\n", env._Fe_stat); + ret = fegetenv(&env2); + ok(!ret, "fegetenv returned %x\n", ret); + ok(env._Fe_ctl != env2._Fe_ctl, "fesetround didn't change _Fe_ctl (%lx).\n", env._Fe_ctl); + ret = fesetenv(&env); + ok(!ret, "fesetenv returned %x\n", ret); + ret = fegetround(); + ok(ret == FE_TONEAREST, "Got unexpected round mode %#x.\n", ret); + + except = fenv_encode(FE_ALL_EXCEPT); + ret = fesetexceptflag(&except, FE_INEXACT|FE_UNDERFLOW); + ok(!ret, "fesetexceptflag returned %x\n", ret); + except = fetestexcept(FE_ALL_EXCEPT); + ok(except == (FE_INEXACT|FE_UNDERFLOW), "expected %x, got %lx\n", FE_INEXACT|FE_UNDERFLOW, except); + + ret = feclearexcept(~FE_ALL_EXCEPT); + ok(!ret, "feclearexceptflag returned %x\n", ret); + except = fetestexcept(FE_ALL_EXCEPT); + ok(except == (FE_INEXACT|FE_UNDERFLOW), "expected %x, got %lx\n", FE_INEXACT|FE_UNDERFLOW, except); + + /* no crash, but no-op */ + ret = fesetexceptflag(NULL, 0); + ok(!ret, "fesetexceptflag returned %x\n", ret); + except = fetestexcept(FE_ALL_EXCEPT); + ok(except == (FE_INEXACT|FE_UNDERFLOW), "expected %x, got %lx\n", FE_INEXACT|FE_UNDERFLOW, except); + + /* zero clears all */ + except = 0; + ret = fesetexceptflag(&except, FE_ALL_EXCEPT); + ok(!ret, "fesetexceptflag returned %x\n", ret); + except = fetestexcept(FE_ALL_EXCEPT); + ok(!except, "expected 0, got %lx\n", except); + + ret = fetestexcept(FE_ALL_EXCEPT); + ok(!ret, "fetestexcept returned %x\n", ret); + + flags = 0; + /* adding bits with flags */ + for(i=0; ipush_esp[0] = 0xff; + thunk->push_esp[1] = 0x74; + thunk->push_esp[2] = 0x24; + thunk->push_esp[3] = 0x04; + + thunk->call_rewind = 0xe8; + thunk->rewind_addr = (BYTE *) rewind - (BYTE *) (&thunk->rewind_addr + 1); + + thunk->pop_eax = 0x58; + thunk->ret = 0xc3; + + test_rewind_wrapper = (void *) thunk; + + fp_in = fopen("rewind_abi.tst", "wb"); + fp_out = test_rewind_wrapper(fp_in); + ok(fp_in == fp_out, "rewind modified the first argument in the stack\n"); + + fclose(fp_in); + unlink("rewind_abi.tst"); +} +#endif + +static void test_gmtime64(void) +{ + struct tm *ptm, tm; + __time64_t t; + int ret; + + t = -1; + memset(&tm, 0xcc, sizeof(tm)); + ptm = _gmtime64(&t); + ok(!!ptm, "got NULL.\n"); + ret = _gmtime64_s(&tm, &t); + ok(!ret, "got %d.\n", ret); + ok(tm.tm_year == 69 && tm.tm_hour == 23 && tm.tm_min == 59 && tm.tm_sec == 59, "got %d, %d, %d, %d.\n", + tm.tm_year, tm.tm_hour, tm.tm_min, tm.tm_sec); + + t = -43200; + memset(&tm, 0xcc, sizeof(tm)); + ptm = _gmtime64(&t); + ok(!!ptm, "got NULL.\n"); + ret = _gmtime64_s(&tm, &t); + ok(!ret, "got %d.\n", ret); + ok(tm.tm_year == 69 && tm.tm_hour == 12 && tm.tm_min == 0 && tm.tm_sec == 0, "got %d, %d, %d, %d.\n", + tm.tm_year, tm.tm_hour, tm.tm_min, tm.tm_sec); + ptm = _gmtime32((__time32_t *)&t); + ok(!!ptm, "got NULL.\n"); + memset(&tm, 0xcc, sizeof(tm)); + ret = _gmtime32_s(&tm, (__time32_t *)&t); + ok(!ret, "got %d.\n", ret); + todo_wine_if(tm.tm_year == 69 && tm.tm_hour == 12) + ok(tm.tm_year == 70 && tm.tm_hour == -12 && tm.tm_min == 0 && tm.tm_sec == 0, "got %d, %d, %d, %d.\n", + tm.tm_year, tm.tm_hour, tm.tm_min, tm.tm_sec); + + t = -43201; + ptm = _gmtime64(&t); + ok(!ptm, "got non-NULL.\n"); + memset(&tm, 0xcc, sizeof(tm)); + ret = _gmtime64_s(&tm, &t); + ok(ret == EINVAL, "got %d.\n", ret); + ok(tm.tm_year == -1 && tm.tm_hour == -1 && tm.tm_min == -1 && tm.tm_sec == -1, "got %d, %d, %d, %d.\n", + tm.tm_year, tm.tm_hour, tm.tm_min, tm.tm_sec); + ptm = _gmtime32((__time32_t *)&t); + ok(!ptm, "got NULL.\n"); + memset(&tm, 0xcc, sizeof(tm)); + ret = _gmtime32_s(&tm, (__time32_t *)&t); + ok(ret == EINVAL, "got %d.\n", ret); + ok(tm.tm_year == -1 && tm.tm_hour == -1 && tm.tm_min == -1 && tm.tm_sec == -1, "got %d, %d, %d, %d.\n", + tm.tm_year, tm.tm_hour, tm.tm_min, tm.tm_sec); + + t = _MAX__TIME64_T + 1605600; + memset(&tm, 0xcc, sizeof(tm)); + ptm = _gmtime64(&t); + ok(!!ptm || broken(!ptm) /* before Win10 1909 */, "got NULL.\n"); + if (!ptm) + { + win_skip("Old gmtime64 limits, skipping tests.\n"); + return; + } + ret = _gmtime64_s(&tm, &t); + ok(!ret, "got %d.\n", ret); + ok(tm.tm_year == 1101 && tm.tm_hour == 21 && tm.tm_min == 59 && tm.tm_sec == 59, "got %d, %d, %d, %d.\n", + tm.tm_year, tm.tm_hour, tm.tm_min, tm.tm_sec); + + t = _MAX__TIME64_T + 1605601; + ptm = _gmtime64(&t); + ok(!ptm, "got non-NULL.\n"); + memset(&tm, 0xcc, sizeof(tm)); + ret = _gmtime64_s(&tm, &t); + ok(ret == EINVAL, "got %d.\n", ret); + ok(tm.tm_year == -1 && tm.tm_hour == -1 && tm.tm_min == -1 && tm.tm_sec == -1, "got %d, %d, %d, %d.\n", + tm.tm_year, tm.tm_hour, tm.tm_min, tm.tm_sec); +} + +static void test__get_heap_handle(void) +{ + ok((HANDLE)_get_heap_handle() == GetProcessHeap(), "Expected _get_heap_handle() to return GetProcessHeap()\n"); +} + +START_TEST(misc) +{ + int arg_c; + char** arg_v; + FILETIME cur; + + GetSystemTimeAsFileTime(&cur); + crt_init_end = ((LONGLONG)cur.dwHighDateTime << 32) + cur.dwLowDateTime; + + arg_c = winetest_get_mainargs(&arg_v); + if(arg_c == 3) { + if(!strcmp(arg_v[2], "cmd")) + test__get_narrow_winmain_command_line(NULL); + else if(!strcmp(arg_v[2], "exit")) + test_call_exit(); + else if(!strcmp(arg_v[2], "quick_exit")) + test_call_quick_exit(); + return; + } + + test_invalid_parameter_handler(); + test__initialize_onexit_table(); + test__register_onexit_function(); + test__execute_onexit_table(); + test___fpe_flt_rounds(); + test__control87_2(); + test__get_narrow_winmain_command_line(arg_v[0]); + test__sopen_dispatch(); + test__sopen_s(); + test_lldiv(); + test_isblank(); + test_math_errors(); + test_asctime(); + test_strftime(); + test_exit(arg_v[0]); + test_quick_exit(arg_v[0]); + test__stat32(); + test__o_malloc(); + test_clock(); + test_thread_storage(); + test_fenv(); + test_fopen_exclusive(); +#if defined(__i386__) + test_rewind_i386_abi(); +#endif + test_gmtime64(); + test__get_heap_handle(); +} diff --git a/modules/rostests/winetests/ucrtbase/printf.c b/modules/rostests/winetests/ucrtbase/printf.c new file mode 100644 index 0000000000000..75bd7830869ce --- /dev/null +++ b/modules/rostests/winetests/ucrtbase/printf.c @@ -0,0 +1,903 @@ +/* + * Conformance tests for *printf functions. + * + * Copyright 2002 Uwe Bonnes + * Copyright 2004 Aneurin Price + * Copyright 2005 Mike McCormack + * Copyright 2015 Martin Storsjo + * + * 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 +#include +#include +#include + +#include "windef.h" +#include "winbase.h" +#include "winnls.h" + +#include "wine/test.h" + +#define DEFINE_EXPECT(func) \ + static BOOL expect_ ## func = FALSE, called_ ## func = FALSE + +#define SET_EXPECT(func) \ + expect_ ## func = TRUE + +#define CHECK_EXPECT2(func) \ + do { \ + ok(expect_ ##func, "unexpected call " #func "\n"); \ + called_ ## func = TRUE; \ + }while(0) + +#define CHECK_EXPECT(func) \ + do { \ + CHECK_EXPECT2(func); \ + expect_ ## func = FALSE; \ + }while(0) + +#define CHECK_CALLED(func) \ + do { \ + ok(called_ ## func, "expected " #func "\n"); \ + expect_ ## func = called_ ## func = FALSE; \ + }while(0) + +DEFINE_EXPECT(invalid_parameter_handler); + +static inline float __port_ind(void) +{ + static const unsigned __ind_bytes = 0xffc00000; + return *(const float *)&__ind_bytes; +} +#define IND __port_ind() + +static void __cdecl test_invalid_parameter_handler(const wchar_t *expression, + const wchar_t *function, const wchar_t *file, + unsigned line, uintptr_t arg) +{ + CHECK_EXPECT(invalid_parameter_handler); + ok(expression == NULL, "expression is not NULL\n"); + ok(function == NULL, "function is not NULL\n"); + ok(file == NULL, "file is not NULL\n"); + ok(line == 0, "line = %u\n", line); + ok(arg == 0, "arg = %Ix\n", arg); +} + +static int WINAPIV vsprintf_wrapper(unsigned __int64 options, char *str, + size_t len, const char *format, ...) +{ + int ret; + va_list valist; + va_start(valist, format); + ret = __stdio_common_vsprintf(options, str, len, format, NULL, valist); + va_end(valist); + return ret; +} + +static void test_snprintf (void) +{ + const char *tests[] = {"short", "justfit", "justfits", "muchlonger", "", "1"}; + char buffer[8]; + int bufsizes[] = { 0, 1, sizeof(buffer) }; + unsigned int i, j; + + for (j = 0; j < ARRAY_SIZE(bufsizes); j++) { + const int bufsiz = bufsizes[j]; + /* Legacy _snprintf style termination */ + for (i = 0; i < ARRAY_SIZE(tests); i++) { + const char *fmt = tests[i]; + const int expect = strlen(fmt) > bufsiz ? -1 : strlen(fmt); + const int n = vsprintf_wrapper (_CRT_INTERNAL_PRINTF_LEGACY_VSPRINTF_NULL_TERMINATION, buffer, bufsiz, fmt); + const int valid = n < 0 ? bufsiz : (n == bufsiz ? n : n+1); + + ok (n == expect, "\"%s\": expected %d, returned %d\n", + fmt, expect, n); + ok (!memcmp (fmt, buffer, valid), + "\"%s\": rendered \"%.*s\"\n", fmt, valid, buffer); + } + + /* C99 snprintf style termination */ + for (i = 0; i < ARRAY_SIZE(tests); i++) { + const char *fmt = tests[i]; + const int expect = strlen(fmt); + const int n = vsprintf_wrapper (_CRT_INTERNAL_PRINTF_STANDARD_SNPRINTF_BEHAVIOR, buffer, bufsiz, fmt); + const int valid = n >= bufsiz ? (bufsiz > 0 ? bufsiz - 1 : 0) : n < 0 ? 0 : n; + + ok (n == expect, "\"%s\": expected %d, returned %d\n", + fmt, expect, n); + ok (!memcmp (fmt, buffer, valid), + "\"%s\": rendered \"%.*s\" bufsiz %d\n", fmt, valid, buffer, bufsiz); + ok (bufsiz == 0 || buffer[valid] == '\0', + "\"%s\": Missing null termination (ret %d) - is %d (bufsiz %d)\n", fmt, n, buffer[valid], bufsiz); + } + + /* swprintf style termination */ + for (i = 0; i < ARRAY_SIZE(tests); i++) { + const char *fmt = tests[i]; + const int expect = strlen(fmt) >= bufsiz ? bufsiz > 0 ? -2 : -1 : strlen(fmt); + const int n = vsprintf_wrapper (0, buffer, bufsiz, fmt); + const int valid = n < 0 ? bufsiz > 0 ? bufsiz - 1 : 0 : n; + + ok (n == expect, "\"%s\": expected %d, returned %d\n", + fmt, expect, n); + ok (!memcmp (fmt, buffer, valid), + "\"%s\": rendered \"%.*s\" bufsiz %d\n", fmt, valid, buffer, bufsiz); + ok (bufsiz == 0 || buffer[valid] == '\0', + "\"%s\": Missing null termination (ret %d) - is %d\n", fmt, n, buffer[valid]); + } + } + + ok (vsprintf_wrapper (_CRT_INTERNAL_PRINTF_STANDARD_SNPRINTF_BEHAVIOR, NULL, 0, "abcd") == 4, + "Failure to snprintf to NULL\n"); + ok (vsprintf_wrapper (_CRT_INTERNAL_PRINTF_LEGACY_VSPRINTF_NULL_TERMINATION, NULL, 0, "abcd") == 4, + "Failure to snprintf to NULL\n"); + ok (vsprintf_wrapper (0, NULL, 0, "abcd") == 4, + "Failure to snprintf to NULL\n"); + ok (vsprintf_wrapper (_CRT_INTERNAL_PRINTF_STANDARD_SNPRINTF_BEHAVIOR, buffer, 0, "abcd") == 4, + "Failure to snprintf to zero length buffer\n"); + ok (vsprintf_wrapper (_CRT_INTERNAL_PRINTF_LEGACY_VSPRINTF_NULL_TERMINATION, buffer, 0, "abcd") == -1, + "Failure to snprintf to zero length buffer\n"); + ok (vsprintf_wrapper (0, buffer, 0, "abcd") == -1, + "Failure to snprintf to zero length buffer\n"); + ok (vsprintf_wrapper (_CRT_INTERNAL_PRINTF_STANDARD_SNPRINTF_BEHAVIOR, buffer, 0, "") == 0, + "Failure to snprintf a zero length string to a zero length buffer\n"); + ok (vsprintf_wrapper (_CRT_INTERNAL_PRINTF_LEGACY_VSPRINTF_NULL_TERMINATION, buffer, 0, "") == 0, + "Failure to snprintf a zero length string to a zero length buffer\n"); + ok (vsprintf_wrapper (0, buffer, 0, "") == -1, + "Failure to snprintf a zero length string to a zero length buffer\n"); +} + +static int WINAPIV vswprintf_wrapper(unsigned __int64 options, wchar_t *str, + size_t len, const wchar_t *format, ...) +{ + int ret; + va_list valist; + va_start(valist, format); + ret = __stdio_common_vswprintf(options, str, len, format, NULL, valist); + va_end(valist); + return ret; +} + +static void test_swprintf (void) +{ + const wchar_t str_short[] = {'s','h','o','r','t',0}; + const wchar_t str_justfit[] = {'j','u','s','t','f','i','t',0}; + const wchar_t str_justfits[] = {'j','u','s','t','f','i','t','s',0}; + const wchar_t str_muchlonger[] = {'m','u','c','h','l','o','n','g','e','r',0}; + const wchar_t str_empty[] = {0}; + const wchar_t *tests[] = {str_short, str_justfit, str_justfits, str_muchlonger}; + + wchar_t buffer[8]; + char narrow[8], narrow_fmt[16]; + const int bufsiz = ARRAY_SIZE(buffer); + unsigned int i; + + /* Legacy _snprintf style termination */ + for (i = 0; i < ARRAY_SIZE(tests); i++) { + const wchar_t *fmt = tests[i]; + const int expect = wcslen(fmt) > bufsiz ? -1 : wcslen(fmt); + const int n = vswprintf_wrapper (_CRT_INTERNAL_PRINTF_LEGACY_VSPRINTF_NULL_TERMINATION, buffer, bufsiz, fmt); + const int valid = n < 0 ? bufsiz : (n == bufsiz ? n : n+1); + + WideCharToMultiByte (CP_ACP, 0, buffer, -1, narrow, sizeof(narrow), NULL, NULL); + WideCharToMultiByte (CP_ACP, 0, fmt, -1, narrow_fmt, sizeof(narrow_fmt), NULL, NULL); + ok (n == expect, "\"%s\": expected %d, returned %d\n", + narrow_fmt, expect, n); + ok (!memcmp (fmt, buffer, valid * sizeof(wchar_t)), + "\"%s\": rendered \"%.*s\"\n", narrow_fmt, valid, narrow); + } + + /* C99 snprintf style termination */ + for (i = 0; i < ARRAY_SIZE(tests); i++) { + const wchar_t *fmt = tests[i]; + const int expect = wcslen(fmt); + const int n = vswprintf_wrapper (_CRT_INTERNAL_PRINTF_STANDARD_SNPRINTF_BEHAVIOR, buffer, bufsiz, fmt); + const int valid = n >= bufsiz ? bufsiz - 1 : n < 0 ? 0 : n; + + WideCharToMultiByte (CP_ACP, 0, buffer, -1, narrow, sizeof(narrow), NULL, NULL); + WideCharToMultiByte (CP_ACP, 0, fmt, -1, narrow_fmt, sizeof(narrow_fmt), NULL, NULL); + ok (n == expect, "\"%s\": expected %d, returned %d\n", + narrow_fmt, expect, n); + ok (!memcmp (fmt, buffer, valid * sizeof(wchar_t)), + "\"%s\": rendered \"%.*s\"\n", narrow_fmt, valid, narrow); + ok (buffer[valid] == '\0', + "\"%s\": Missing null termination (ret %d) - is %d\n", narrow_fmt, n, buffer[valid]); + } + + /* swprintf style termination */ + for (i = 0; i < ARRAY_SIZE(tests); i++) { + const wchar_t *fmt = tests[i]; + const int expect = wcslen(fmt) >= bufsiz ? -2 : wcslen(fmt); + const int n = vswprintf_wrapper (0, buffer, bufsiz, fmt); + const int valid = n < 0 ? bufsiz - 1 : n; + + WideCharToMultiByte (CP_ACP, 0, buffer, -1, narrow, sizeof(narrow), NULL, NULL); + WideCharToMultiByte (CP_ACP, 0, fmt, -1, narrow_fmt, sizeof(narrow_fmt), NULL, NULL); + ok (n == expect, "\"%s\": expected %d, returned %d\n", + narrow_fmt, expect, n); + ok (!memcmp (fmt, buffer, valid * sizeof(wchar_t)), + "\"%s\": rendered \"%.*s\"\n", narrow_fmt, valid, narrow); + ok (buffer[valid] == '\0', + "\"%s\": Missing null termination (ret %d) - is %d\n", narrow_fmt, n, buffer[valid]); + } + + ok (vswprintf_wrapper (_CRT_INTERNAL_PRINTF_STANDARD_SNPRINTF_BEHAVIOR, NULL, 0, str_short) == 5, + "Failure to swprintf to NULL\n"); + ok (vswprintf_wrapper (_CRT_INTERNAL_PRINTF_LEGACY_VSPRINTF_NULL_TERMINATION, NULL, 0, str_short) == 5, + "Failure to swprintf to NULL\n"); + ok (vswprintf_wrapper (0, NULL, 0, str_short) == 5, + "Failure to swprintf to NULL\n"); + ok (vswprintf_wrapper (_CRT_INTERNAL_PRINTF_STANDARD_SNPRINTF_BEHAVIOR, buffer, 0, str_short) == 5, + "Failure to swprintf to a zero length buffer\n"); + ok (vswprintf_wrapper (_CRT_INTERNAL_PRINTF_LEGACY_VSPRINTF_NULL_TERMINATION, buffer, 0, str_short) == -1, + "Failure to swprintf to a zero length buffer\n"); + ok (vswprintf_wrapper (0, buffer, 0, str_short) == -1, + "Failure to swprintf to a zero length buffer\n"); + ok (vswprintf_wrapper (_CRT_INTERNAL_PRINTF_STANDARD_SNPRINTF_BEHAVIOR, buffer, 0, str_empty) == 0, + "Failure to swprintf a zero length string to a zero length buffer\n"); + ok (vswprintf_wrapper (_CRT_INTERNAL_PRINTF_LEGACY_VSPRINTF_NULL_TERMINATION, buffer, 0, str_empty) == 0, + "Failure to swprintf a zero length string to a zero length buffer\n"); + ok (vswprintf_wrapper (0, buffer, 0, str_empty) == -1, + "Failure to swprintf a zero length string to a zero length buffer\n"); +} + +static int WINAPIV vfprintf_wrapper(FILE *file, + const char *format, ...) +{ + int ret; + va_list valist; + va_start(valist, format); + ret = __stdio_common_vfprintf(0, file, format, NULL, valist); + va_end(valist); + return ret; +} + +static void test_fprintf(void) +{ + static const char file_name[] = "fprintf.tst"; + + FILE *fp = fopen(file_name, "wb"); + char buf[1024]; + int ret; + + ret = vfprintf_wrapper(fp, "simple test\n"); + ok(ret == 12, "ret = %d\n", ret); + ret = ftell(fp); + ok(ret == 12, "ftell returned %d\n", ret); + + ret = vfprintf_wrapper(fp, "contains%cnull\n", '\0'); + ok(ret == 14, "ret = %d\n", ret); + ret = ftell(fp); + ok(ret == 26, "ftell returned %d\n", ret); + + fclose(fp); + + fp = fopen(file_name, "rb"); + fgets(buf, sizeof(buf), fp); + ret = ftell(fp); + ok(ret == 12, "ftell returned %d\n", ret); + ok(!strcmp(buf, "simple test\n"), "buf = %s\n", buf); + + fgets(buf, sizeof(buf), fp); + ret = ftell(fp); + ok(ret == 26, "ret = %d\n", ret); + ok(!memcmp(buf, "contains\0null\n", 14), "buf = %s\n", buf); + + fclose(fp); + + fp = fopen(file_name, "wt"); + + ret = vfprintf_wrapper(fp, "simple test\n"); + ok(ret == 12, "ret = %d\n", ret); + ret = ftell(fp); + ok(ret == 13, "ftell returned %d\n", ret); + + ret = vfprintf_wrapper(fp, "contains%cnull\n", '\0'); + ok(ret == 14, "ret = %d\n", ret); + ret = ftell(fp); + ok(ret == 28, "ftell returned %d\n", ret); + + fclose(fp); + + fp = fopen(file_name, "rb"); + fgets(buf, sizeof(buf), fp); + ret = ftell(fp); + ok(ret == 13, "ftell returned %d\n", ret); + ok(!strcmp(buf, "simple test\r\n"), "buf = %s\n", buf); + + fgets(buf, sizeof(buf), fp); + ret = ftell(fp); + ok(ret == 28, "ret = %d\n", ret); + ok(!memcmp(buf, "contains\0null\r\n", 15), "buf = %s\n", buf); + + fclose(fp); + unlink(file_name); +} + +static int WINAPIV vfwprintf_wrapper(FILE *file, + const wchar_t *format, ...) +{ + int ret; + va_list valist; + va_start(valist, format); + ret = __stdio_common_vfwprintf(0, file, format, NULL, valist); + va_end(valist); + return ret; +} + +static void test_fwprintf(void) +{ + static const char file_name[] = "fprintf.tst"; + static const WCHAR simple[] = {'s','i','m','p','l','e',' ','t','e','s','t','\n',0}; + static const WCHAR cont_fmt[] = {'c','o','n','t','a','i','n','s','%','c','n','u','l','l','\n',0}; + static const WCHAR cont[] = {'c','o','n','t','a','i','n','s','\0','n','u','l','l','\n',0}; + + FILE *fp = fopen(file_name, "wb"); + wchar_t bufw[1024]; + char bufa[1024]; + int ret; + + ret = vfwprintf_wrapper(fp, simple); + ok(ret == 12, "ret = %d\n", ret); + ret = ftell(fp); + ok(ret == 24, "ftell returned %d\n", ret); + + ret = vfwprintf_wrapper(fp, cont_fmt, '\0'); + ok(ret == 14, "ret = %d\n", ret); + ret = ftell(fp); + ok(ret == 52, "ftell returned %d\n", ret); + + fclose(fp); + + fp = fopen(file_name, "rb"); + fgetws(bufw, ARRAY_SIZE(bufw), fp); + ret = ftell(fp); + ok(ret == 24, "ftell returned %d\n", ret); + ok(!wcscmp(bufw, simple), "buf = %s\n", wine_dbgstr_w(bufw)); + + fgetws(bufw, ARRAY_SIZE(bufw), fp); + ret = ftell(fp); + ok(ret == 52, "ret = %d\n", ret); + ok(!memcmp(bufw, cont, 28), "buf = %s\n", wine_dbgstr_w(bufw)); + + fclose(fp); + + fp = fopen(file_name, "wt"); + + ret = vfwprintf_wrapper(fp, simple); + ok(ret == 12, "ret = %d\n", ret); + ret = ftell(fp); + ok(ret == 13, "ftell returned %d\n", ret); + + ret = vfwprintf_wrapper(fp, cont_fmt, '\0'); + ok(ret == 14, "ret = %d\n", ret); + ret = ftell(fp); + ok(ret == 28, "ftell returned %d\n", ret); + + fclose(fp); + + fp = fopen(file_name, "rb"); + fgets(bufa, sizeof(bufa), fp); + ret = ftell(fp); + ok(ret == 13, "ftell returned %d\n", ret); + ok(!strcmp(bufa, "simple test\r\n"), "buf = %s\n", bufa); + + fgets(bufa, sizeof(bufa), fp); + ret = ftell(fp); + ok(ret == 28, "ret = %d\n", ret); + ok(!memcmp(bufa, "contains\0null\r\n", 15), "buf = %s\n", bufa); + + fclose(fp); + unlink(file_name); + + /* NULL format */ + errno = 0xdeadbeef; + SET_EXPECT(invalid_parameter_handler); + ret = vfwprintf_wrapper(fp, NULL); + ok(errno == EINVAL, "expected errno EINVAL, got %d\n", errno); + ok(ret == -1, "expected ret -1, got %d\n", ret); + CHECK_CALLED(invalid_parameter_handler); + + /* NULL file */ + errno = 0xdeadbeef; + SET_EXPECT(invalid_parameter_handler); + ret = vfwprintf_wrapper(NULL, simple); + ok(errno == EINVAL, "expected errno EINVAL, got %d\n", errno); + ok(ret == -1, "expected ret -1, got %d\n", ret); + CHECK_CALLED(invalid_parameter_handler); + + /* format using % with NULL arglist*/ + /* crashes on Windows */ + /* ret = __stdio_common_vfwprintf(0, fp, cont_fmt, NULL, NULL); */ +} + +static int WINAPIV _vsnprintf_s_wrapper(char *str, size_t sizeOfBuffer, + size_t count, const char *format, ...) +{ + int ret; + va_list valist; + va_start(valist, format); + ret = __stdio_common_vsnprintf_s(0, str, sizeOfBuffer, count, format, NULL, valist); + va_end(valist); + return ret; +} + +static void test_vsnprintf_s(void) +{ + const char format[] = "AB%uC"; + const char out7[] = "AB123C"; + const char out6[] = "AB123"; + const char out2[] = "A"; + const char out1[] = ""; + char buffer[14] = { 0 }; + int exp, got; + + /* Enough room. */ + exp = strlen(out7); + + got = _vsnprintf_s_wrapper(buffer, 14, _TRUNCATE, format, 123); + ok( exp == got, "length wrong, expect=%d, got=%d\n", exp, got); + ok( !strcmp(out7, buffer), "buffer wrong, got=%s\n", buffer); + + got = _vsnprintf_s_wrapper(buffer, 12, _TRUNCATE, format, 123); + ok( exp == got, "length wrong, expect=%d, got=%d\n", exp, got); + ok( !strcmp(out7, buffer), "buffer wrong, got=%s\n", buffer); + + got = _vsnprintf_s_wrapper(buffer, 7, _TRUNCATE, format, 123); + ok( exp == got, "length wrong, expect=%d, got=%d\n", exp, got); + ok( !strcmp(out7, buffer), "buffer wrong, got=%s\n", buffer); + + /* Not enough room. */ + exp = -1; + + got = _vsnprintf_s_wrapper(buffer, 6, _TRUNCATE, format, 123); + ok( exp == got, "length wrong, expect=%d, got=%d\n", exp, got); + ok( !strcmp(out6, buffer), "buffer wrong, got=%s\n", buffer); + + got = _vsnprintf_s_wrapper(buffer, 2, _TRUNCATE, format, 123); + ok( exp == got, "length wrong, expect=%d, got=%d\n", exp, got); + ok( !strcmp(out2, buffer), "buffer wrong, got=%s\n", buffer); + + got = _vsnprintf_s_wrapper(buffer, 1, _TRUNCATE, format, 123); + ok( exp == got, "length wrong, expect=%d, got=%d\n", exp, got); + ok( !strcmp(out1, buffer), "buffer wrong, got=%s\n", buffer); +} + +static int WINAPIV _vsnwprintf_s_wrapper(WCHAR *str, size_t sizeOfBuffer, + size_t count, const WCHAR *format, ...) +{ + int ret; + va_list valist; + va_start(valist, format); + ret = __stdio_common_vsnwprintf_s(0, str, sizeOfBuffer, count, format, NULL, valist); + va_end(valist); + return ret; +} + +static void test_vsnwprintf_s(void) +{ + const WCHAR format[] = {'A','B','%','u','C',0}; + const WCHAR out7[] = {'A','B','1','2','3','C',0}; + const WCHAR out6[] = {'A','B','1','2','3',0}; + const WCHAR out2[] = {'A',0}; + const WCHAR out1[] = {0}; + WCHAR buffer[14] = { 0 }; + int exp, got; + + /* Enough room. */ + exp = lstrlenW(out7); + + got = _vsnwprintf_s_wrapper(buffer, 14, _TRUNCATE, format, 123); + ok( exp == got, "length wrong, expect=%d, got=%d\n", exp, got); + ok( !lstrcmpW(out7, buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer)); + + got = _vsnwprintf_s_wrapper(buffer, 12, _TRUNCATE, format, 123); + ok( exp == got, "length wrong, expect=%d, got=%d\n", exp, got); + ok( !lstrcmpW(out7, buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer)); + + got = _vsnwprintf_s_wrapper(buffer, 7, _TRUNCATE, format, 123); + ok( exp == got, "length wrong, expect=%d, got=%d\n", exp, got); + ok( !lstrcmpW(out7, buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer)); + + /* Not enough room. */ + exp = -1; + + got = _vsnwprintf_s_wrapper(buffer, 6, _TRUNCATE, format, 123); + ok( exp == got, "length wrong, expect=%d, got=%d\n", exp, got); + ok( !lstrcmpW(out6, buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer)); + + got = _vsnwprintf_s_wrapper(buffer, 2, _TRUNCATE, format, 123); + ok( exp == got, "length wrong, expect=%d, got=%d\n", exp, got); + ok( !lstrcmpW(out2, buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer)); + + got = _vsnwprintf_s_wrapper(buffer, 1, _TRUNCATE, format, 123); + ok( exp == got, "length wrong, expect=%d, got=%d\n", exp, got); + ok( !lstrcmpW(out1, buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer)); +} + +static void test_printf_legacy_wide(void) +{ + const wchar_t wide[] = {'A','B','C','D',0}; + const char narrow[] = "abcd"; + const char out[] = "abcd ABCD"; + /* The legacy wide flag doesn't affect narrow printfs, so the same + * format should behave the same both with and without the flag. */ + const char narrow_fmt[] = "%s %ls"; + /* The standard behaviour is to use the same format as for the narrow + * case, while the legacy case has got a different meaning for %s. */ + const wchar_t std_wide_fmt[] = {'%','s',' ','%','l','s',0}; + const wchar_t legacy_wide_fmt[] = {'%','h','s',' ','%','s',0}; + char buffer[20]; + wchar_t wbuffer[20]; + + vsprintf_wrapper(0, buffer, sizeof(buffer), narrow_fmt, narrow, wide); + ok(!strcmp(buffer, out), "buffer wrong, got=%s\n", buffer); + vsprintf_wrapper(_CRT_INTERNAL_PRINTF_LEGACY_WIDE_SPECIFIERS, buffer, sizeof(buffer), narrow_fmt, narrow, wide); + ok(!strcmp(buffer, out), "buffer wrong, got=%s\n", buffer); + + vswprintf_wrapper(0, wbuffer, sizeof(wbuffer), std_wide_fmt, narrow, wide); + WideCharToMultiByte(CP_ACP, 0, wbuffer, -1, buffer, sizeof(buffer), NULL, NULL); + ok(!strcmp(buffer, out), "buffer wrong, got=%s\n", buffer); + vswprintf_wrapper(_CRT_INTERNAL_PRINTF_LEGACY_WIDE_SPECIFIERS, wbuffer, sizeof(wbuffer), legacy_wide_fmt, narrow, wide); + WideCharToMultiByte(CP_ACP, 0, wbuffer, -1, buffer, sizeof(buffer), NULL, NULL); + ok(!strcmp(buffer, out), "buffer wrong, got=%s\n", buffer); +} + +static void test_printf_legacy_msvcrt(void) +{ + char buf[50]; + + /* In standard mode, %F is a float format conversion, while it is a + * length modifier in legacy msvcrt mode. In legacy mode, N is also + * a length modifier. */ + vsprintf_wrapper(0, buf, sizeof(buf), "%F", 1.23); + ok(!strcmp(buf, "1.230000"), "buf = %s\n", buf); + vsprintf_wrapper(_CRT_INTERNAL_PRINTF_LEGACY_MSVCRT_COMPATIBILITY, buf, sizeof(buf), "%Fd %Nd", 123, 456); + ok(!strcmp(buf, "123 456"), "buf = %s\n", buf); + + vsprintf_wrapper(0, buf, sizeof(buf), "%f %F %f %e %E %g %G", INFINITY, INFINITY, -INFINITY, INFINITY, INFINITY, INFINITY, INFINITY); + ok(!strcmp(buf, "inf INF -inf inf INF inf INF"), "buf = %s\n", buf); + vsprintf_wrapper(_CRT_INTERNAL_PRINTF_LEGACY_MSVCRT_COMPATIBILITY, buf, sizeof(buf), "%f", INFINITY); + ok(!strcmp(buf, "1.#INF00"), "buf = %s\n", buf); + vsprintf_wrapper(0, buf, sizeof(buf), "%f %F", NAN, NAN); + ok(!strcmp(buf, "nan NAN"), "buf = %s\n", buf); + vsprintf_wrapper(_CRT_INTERNAL_PRINTF_LEGACY_MSVCRT_COMPATIBILITY, buf, sizeof(buf), "%f", NAN); + ok(!strcmp(buf, "1.#QNAN0"), "buf = %s\n", buf); + vsprintf_wrapper(0, buf, sizeof(buf), "%f %F", IND, IND); + ok(!strcmp(buf, "-nan(ind) -NAN(IND)"), "buf = %s\n", buf); + vsprintf_wrapper(_CRT_INTERNAL_PRINTF_LEGACY_MSVCRT_COMPATIBILITY, buf, sizeof(buf), "%f", IND); + ok(!strcmp(buf, "-1.#IND00"), "buf = %s\n", buf); +} + +static void test_printf_legacy_three_digit_exp(void) +{ + char buf[20]; + + vsprintf_wrapper(0, buf, sizeof(buf), "%E", 1.23); + ok(!strcmp(buf, "1.230000E+00"), "buf = %s\n", buf); + vsprintf_wrapper(_CRT_INTERNAL_PRINTF_LEGACY_THREE_DIGIT_EXPONENTS, buf, sizeof(buf), "%E", 1.23); + ok(!strcmp(buf, "1.230000E+000"), "buf = %s\n", buf); + vsprintf_wrapper(0, buf, sizeof(buf), "%E", 1.23e+123); + ok(!strcmp(buf, "1.230000E+123"), "buf = %s\n", buf); +} + +static void test_printf_c99(void) +{ + char buf[30]; + int i; + + /* The msvcrt compatibility flag doesn't affect whether 'z' is interpreted + * as size_t size for integers. */ + for (i = 0; i < 2; i++) { + unsigned __int64 options = (i == 0) ? 0 : + _CRT_INTERNAL_PRINTF_LEGACY_MSVCRT_COMPATIBILITY; + + /* z modifier accepts size_t argument */ + vsprintf_wrapper(options, buf, sizeof(buf), "%zx %d", SIZE_MAX, 1); + if (sizeof(size_t) == 8) + ok(!strcmp(buf, "ffffffffffffffff 1"), "buf = %s\n", buf); + else + ok(!strcmp(buf, "ffffffff 1"), "buf = %s\n", buf); + + /* j modifier with signed format accepts intmax_t argument */ + vsprintf_wrapper(options, buf, sizeof(buf), "%jd %d", INTMAX_MIN, 1); + ok(!strcmp(buf, "-9223372036854775808 1"), "buf = %s\n", buf); + + /* j modifier with unsigned format accepts uintmax_t argument */ + vsprintf_wrapper(options, buf, sizeof(buf), "%ju %d", UINTMAX_MAX, 1); + ok(!strcmp(buf, "18446744073709551615 1"), "buf = %s\n", buf); + + /* t modifier accepts ptrdiff_t argument */ + vsprintf_wrapper(options, buf, sizeof(buf), "%td %d", PTRDIFF_MIN, 1); + if (sizeof(ptrdiff_t) == 8) + ok(!strcmp(buf, "-9223372036854775808 1"), "buf = %s\n", buf); + else + ok(!strcmp(buf, "-2147483648 1"), "buf = %s\n", buf); + } +} + +static void test_printf_natural_string(void) +{ + const wchar_t wide[] = {'A','B','C','D',0}; + const char narrow[] = "abcd"; + const char narrow_fmt[] = "%s %Ts"; + const char narrow_out[] = "abcd abcd"; + const wchar_t wide_fmt[] = {'%','s',' ','%','T','s',0}; + const wchar_t wide_out[] = {'a','b','c','d',' ','A','B','C','D',0}; + char buffer[20]; + wchar_t wbuffer[20]; + + vsprintf_wrapper(0, buffer, sizeof(buffer), narrow_fmt, narrow, narrow); + ok(!strcmp(buffer, narrow_out), "buffer wrong, got=%s\n", buffer); + + vswprintf_wrapper(0, wbuffer, sizeof(wbuffer), wide_fmt, narrow, wide); + ok(!lstrcmpW(wbuffer, wide_out), "buffer wrong, got=%s\n", wine_dbgstr_w(wbuffer)); +} + +static void test_printf_fp(void) +{ + static const int flags[] = { + 0, + _CRT_INTERNAL_PRINTF_LEGACY_MSVCRT_COMPATIBILITY, + _CRT_INTERNAL_PRINTF_LEGACY_THREE_DIGIT_EXPONENTS, + _CRT_INTERNAL_PRINTF_LEGACY_MSVCRT_COMPATIBILITY + | _CRT_INTERNAL_PRINTF_LEGACY_THREE_DIGIT_EXPONENTS, + _CRT_INTERNAL_PRINTF_LEGACY_MSVCRT_COMPATIBILITY + | _CRT_INTERNAL_PRINTF_LEGACY_THREE_DIGIT_EXPONENTS + | _CRT_INTERNAL_PRINTF_STANDARD_ROUNDING + }; + const struct { + const char *fmt; + double d; + const char *res[ARRAY_SIZE(flags)]; + const char *broken[ARRAY_SIZE(flags)]; + } tests[] = { + { "%a", NAN, { "nan", "0x1.#QNAN00000000p+0", "nan", "0x1.#QNAN00000000p+0" }}, + { "%A", NAN, { "NAN", "0X1.#QNAN00000000P+0", "NAN", "0X1.#QNAN00000000P+0" }}, + { "%e", NAN, { "nan", "1.#QNAN0e+00", "nan", "1.#QNAN0e+000" }}, + { "%E", NAN, { "NAN", "1.#QNAN0E+00", "NAN", "1.#QNAN0E+000" }}, + { "%g", NAN, { "nan", "1.#QNAN", "nan", "1.#QNAN" }}, + { "%G", NAN, { "NAN", "1.#QNAN", "NAN", "1.#QNAN" }}, + { "%21a", NAN, { " nan", " 0x1.#QNAN00000000p+0", " nan", " 0x1.#QNAN00000000p+0" }}, + { "%20e", NAN, { " nan", " 1.#QNAN0e+00", " nan", " 1.#QNAN0e+000" }}, + { "%20g", NAN, { " nan", " 1.#QNAN", " nan", " 1.#QNAN" }}, + { "%.21a", NAN, { "nan", "0x1.#QNAN0000000000000000p+0", "nan", "0x1.#QNAN0000000000000000p+0" }}, + { "%.20e", NAN, { "nan", "1.#QNAN000000000000000e+00", "nan", "1.#QNAN000000000000000e+000" }}, + { "%.20g", NAN, { "nan", "1.#QNAN", "nan", "1.#QNAN" }}, + { "%.021a", NAN, { "nan", "0x1.#QNAN0000000000000000p+0", "nan", "0x1.#QNAN0000000000000000p+0" }}, + { "%.020e", NAN, { "nan", "1.#QNAN000000000000000e+00", "nan", "1.#QNAN000000000000000e+000" }}, + { "%.020g", NAN, { "nan", "1.#QNAN", "nan", "1.#QNAN" }}, + { "%#.21a", NAN, { "nan", "0x1.#QNAN0000000000000000p+0", "nan", "0x1.#QNAN0000000000000000p+0" }}, + { "%#.20e", NAN, { "nan", "1.#QNAN000000000000000e+00", "nan", "1.#QNAN000000000000000e+000" }}, + { "%#.20g", NAN, { "nan", "1.#QNAN00000000000000", "nan", "1.#QNAN00000000000000" }}, + { "%.1g", NAN, { "nan", "1", "nan", "1" }}, + { "%.2g", NAN, { "nan", "1.$", "nan", "1.$" }}, + { "%.3g", NAN, { "nan", "1.#R", "nan", "1.#R" }}, + + { "%a", IND, { "-nan(ind)", "-0x1.#IND000000000p+0", "-nan(ind)", "-0x1.#IND000000000p+0" }}, + { "%e", IND, { "-nan(ind)", "-1.#IND00e+00", "-nan(ind)", "-1.#IND00e+000" }}, + { "%g", IND, { "-nan(ind)", "-1.#IND", "-nan(ind)", "-1.#IND" }}, + { "%21a", IND, { " -nan(ind)", "-0x1.#IND000000000p+0", " -nan(ind)", "-0x1.#IND000000000p+0" }}, + { "%20e", IND, { " -nan(ind)", " -1.#IND00e+00", " -nan(ind)", " -1.#IND00e+000" }}, + { "%20g", IND, { " -nan(ind)", " -1.#IND", " -nan(ind)", " -1.#IND" }}, + { "%.21a", IND, { "-nan(ind)", "-0x1.#IND00000000000000000p+0", "-nan(ind)", "-0x1.#IND00000000000000000p+0" }}, + { "%.20e", IND, { "-nan(ind)", "-1.#IND0000000000000000e+00", "-nan(ind)", "-1.#IND0000000000000000e+000" }}, + { "%.20g", IND, { "-nan(ind)", "-1.#IND", "-nan(ind)", "-1.#IND" }}, + { "%.021a", IND, { "-nan(ind)", "-0x1.#IND00000000000000000p+0", "-nan(ind)", "-0x1.#IND00000000000000000p+0" }}, + { "%.020e", IND, { "-nan(ind)", "-1.#IND0000000000000000e+00", "-nan(ind)", "-1.#IND0000000000000000e+000" }}, + { "%.020g", IND, { "-nan(ind)", "-1.#IND", "-nan(ind)", "-1.#IND" }}, + { "%#.21a", IND, { "-nan(ind)", "-0x1.#IND00000000000000000p+0", "-nan(ind)", "-0x1.#IND00000000000000000p+0" }}, + { "%#.20e", IND, { "-nan(ind)", "-1.#IND0000000000000000e+00", "-nan(ind)", "-1.#IND0000000000000000e+000" }}, + { "%#.20g", IND, { "-nan(ind)", "-1.#IND000000000000000", "-nan(ind)", "-1.#IND000000000000000" }}, + + { "%a", INFINITY, { "inf", "0x1.#INF000000000p+0", "inf", "0x1.#INF000000000p+0" }}, + { "%e", INFINITY, { "inf", "1.#INF00e+00", "inf", "1.#INF00e+000" }}, + { "%g", INFINITY, { "inf", "1.#INF", "inf", "1.#INF" }}, + { "%21a", INFINITY, { " inf", " 0x1.#INF000000000p+0", " inf", " 0x1.#INF000000000p+0" }}, + { "%20e", INFINITY, { " inf", " 1.#INF00e+00", " inf", " 1.#INF00e+000" }}, + { "%20g", INFINITY, { " inf", " 1.#INF", " inf", " 1.#INF" }}, + { "%.21a", INFINITY, { "inf", "0x1.#INF00000000000000000p+0", "inf", "0x1.#INF00000000000000000p+0" }}, + { "%.20e", INFINITY, { "inf", "1.#INF0000000000000000e+00", "inf", "1.#INF0000000000000000e+000" }}, + { "%.20g", INFINITY, { "inf", "1.#INF", "inf", "1.#INF" }}, + { "%.021a", INFINITY, { "inf", "0x1.#INF00000000000000000p+0", "inf", "0x1.#INF00000000000000000p+0" }}, + { "%.020e", INFINITY, { "inf", "1.#INF0000000000000000e+00", "inf", "1.#INF0000000000000000e+000" }}, + { "%.020g", INFINITY, { "inf", "1.#INF", "inf", "1.#INF" }}, + { "%#.21a", INFINITY, { "inf", "0x1.#INF00000000000000000p+0", "inf", "0x1.#INF00000000000000000p+0" }}, + { "%#.20e", INFINITY, { "inf", "1.#INF0000000000000000e+00", "inf", "1.#INF0000000000000000e+000" }}, + { "%#.20g", INFINITY, { "inf", "1.#INF000000000000000", "inf", "1.#INF000000000000000" }}, + + { "%a", -INFINITY, { "-inf", "-0x1.#INF000000000p+0", "-inf", "-0x1.#INF000000000p+0" }}, + { "%e", -INFINITY, { "-inf", "-1.#INF00e+00", "-inf", "-1.#INF00e+000" }}, + { "%g", -INFINITY, { "-inf", "-1.#INF", "-inf", "-1.#INF" }}, + { "%21a", -INFINITY, { " -inf", "-0x1.#INF000000000p+0", " -inf", "-0x1.#INF000000000p+0" }}, + { "%20e", -INFINITY, { " -inf", " -1.#INF00e+00", " -inf", " -1.#INF00e+000" }}, + { "%20g", -INFINITY, { " -inf", " -1.#INF", " -inf", " -1.#INF" }}, + { "%.21a", -INFINITY, { "-inf", "-0x1.#INF00000000000000000p+0", "-inf", "-0x1.#INF00000000000000000p+0" }}, + { "%.20e", -INFINITY, { "-inf", "-1.#INF0000000000000000e+00", "-inf", "-1.#INF0000000000000000e+000" }}, + { "%.20g", -INFINITY, { "-inf", "-1.#INF", "-inf", "-1.#INF" }}, + { "%.021a", -INFINITY, { "-inf", "-0x1.#INF00000000000000000p+0", "-inf", "-0x1.#INF00000000000000000p+0" }}, + { "%.020e", -INFINITY, { "-inf", "-1.#INF0000000000000000e+00", "-inf", "-1.#INF0000000000000000e+000" }}, + { "%.020g", -INFINITY, { "-inf", "-1.#INF", "-inf", "-1.#INF" }}, + { "%#.21a", -INFINITY, { "-inf", "-0x1.#INF00000000000000000p+0", "-inf", "-0x1.#INF00000000000000000p+0" }}, + { "%#.20e", -INFINITY, { "-inf", "-1.#INF0000000000000000e+00", "-inf", "-1.#INF0000000000000000e+000" }}, + { "%#.20g", -INFINITY, { "-inf", "-1.#INF000000000000000", "-inf", "-1.#INF000000000000000" }}, + + { "%a", 0, { "0x0.0000000000000p+0" }}, + { "%A", 0, { "0X0.0000000000000P+0" }}, + { "%a", 0.5, { "0x1.0000000000000p-1" }}, + { "%a", 1, { "0x1.0000000000000p+0" }}, + { "%a", 20, { "0x1.4000000000000p+4" }}, + { "%a", -1, { "-0x1.0000000000000p+0" }}, + { "%a", 0.1, { "0x1.999999999999ap-4" }}, + { "%24a", 0.1, { " 0x1.999999999999ap-4" }}, + { "%024a", 0.1, { "0x00001.999999999999ap-4" }}, + { "%.2a", 0.1, { "0x1.9ap-4" }}, + { "%.20a", 0.1, { "0x1.999999999999a0000000p-4" }}, + { "%.a", 0.1e-20, { "0x1p-70" }}, + { "%a", 0.1e-20, { "0x1.2e3b40a0e9b4fp-70" }}, + { "%a", 4.9406564584124654e-324, { "0x0.0000000000001p-1022" }}, + { "%.0a", -1.5, { "-0x2p+0" }, { "-0x1p+0" }}, + { "%.0a", -0.5, { "-0x1p-1" }}, + { "%.0a", 0.5, { "0x1p-1" }}, + { "%.0a", 1.5, { "0x2p+0" }, { "0x1p+0" }}, + { "%.0a", 1.99, { "0x2p+0" }}, + { "%.0a", 2, { "0x1p+1" }}, + { "%.0a", 9.5, { "0x1p+3" }}, + { "%.0a", 10.5, { "0x1p+3" }}, + { "%#.0a", -1.5, { "-0x2.p+0" }, { "-0x1.p+0" }}, + { "%#.0a", -0.5, { "-0x1.p-1" }}, + { "%#.0a", 0.5, { "0x1.p-1" }}, + { "%#.0a", 1.5, { "0x2.p+0" }, { "0x1.p+0" }}, + { "%#.1a", 1.03125, { "0x1.1p+0", NULL, NULL, NULL, "0x1.0p+0" }, { "0x1.0p+0" }}, + { "%#.1a", 1.09375, { "0x1.2p+0" }, { "0x1.1p+0" }}, + { "%#.1a", 1.15625, { "0x1.3p+0", NULL, NULL, NULL, "0x1.2p+0" }, { "0x1.2p+0" }}, + + { "%f", 0, { "0.000000" }}, + { "%e", 0, { "0.000000e+00", NULL, "0.000000e+000" }}, + { "%g", 0, { "0" }}, + { "%21f", 0, { " 0.000000" }}, + { "%20e", 0, { " 0.000000e+00", NULL, " 0.000000e+000" }}, + { "%20g", 0, { " 0" }}, + { "%.21f", 0, { "0.000000000000000000000" }}, + { "%.20e", 0, { "0.00000000000000000000e+00", NULL, "0.00000000000000000000e+000" }}, + { "%.20g", 0, { "0" }}, + { "%.021f", 0, { "0.000000000000000000000" }}, + { "%.020e", 0, { "0.00000000000000000000e+00", NULL, "0.00000000000000000000e+000" }}, + { "%.020g", 0, { "0" }}, + { "%#.21f", 0, { "0.000000000000000000000" }}, + { "%#.20e", 0, { "0.00000000000000000000e+00", NULL, "0.00000000000000000000e+000" }}, + { "%#.20g", 0, { "0.0000000000000000000" }, { "0.00000000000000000000" }}, + + { "%f", 123, { "123.000000" }}, + { "%e", 123, { "1.230000e+02", NULL, "1.230000e+002" }}, + { "%g", 123, { "123" }}, + { "%21f", 123, { " 123.000000" }}, + { "%20e", 123, { " 1.230000e+02", NULL, " 1.230000e+002" }}, + { "%20g", 123, { " 123" }}, + { "%.21f", 123, { "123.000000000000000000000" }}, + { "%.20e", 123, { "1.23000000000000000000e+02", NULL, "1.23000000000000000000e+002" }}, + { "%.20g", 123, { "123" }}, + { "%.021f", 123, { "123.000000000000000000000" }}, + { "%.020e", 123, { "1.23000000000000000000e+02", NULL, "1.23000000000000000000e+002" }}, + { "%.020g", 123, { "123" }}, + { "%#.21f", 123, { "123.000000000000000000000" }}, + { "%#.20e", 123, { "1.23000000000000000000e+02", NULL, "1.23000000000000000000e+002" }}, + { "%#.20g", 123, { "123.00000000000000000" }}, + + { "%f", -765, { "-765.000000" }}, + { "%e", -765, { "-7.650000e+02", NULL, "-7.650000e+002" }}, + { "%g", -765, { "-765" }}, + { "%21f", -765, { " -765.000000" }}, + { "%20e", -765, { " -7.650000e+02", NULL, " -7.650000e+002" }}, + { "%20g", -765, { " -765" }}, + { "%.21f", -765, { "-765.000000000000000000000" }}, + { "%.20e", -765, { "-7.65000000000000000000e+02", NULL, "-7.65000000000000000000e+002" }}, + { "%.20g", -765, { "-765" }}, + { "%.021f", -765, { "-765.000000000000000000000" }}, + { "%.020e", -765, { "-7.65000000000000000000e+02", NULL, "-7.65000000000000000000e+002" }}, + { "%.020g", -765, { "-765" }}, + { "%#.21f", -765, { "-765.000000000000000000000" }}, + { "%#.20e", -765, { "-7.65000000000000000000e+02", NULL, "-7.65000000000000000000e+002" }}, + { "%#.20g", -765, { "-765.00000000000000000" }}, + { "%.30f", 1.0/3.0, { "0.333333333333333314829616256247" }}, + { "%.30lf", sqrt(2), { "1.414213562373095145474621858739" }}, + { "%f", 3.141592653590000, { "3.141593" }}, + { "%.10f", 3.141592653590000, { "3.1415926536" }}, + { "%.11f", 3.141592653590000, { "3.14159265359" }}, + { "%.15f", 3.141592653590000, { "3.141592653590000" }}, + { "%.15f", M_PI, { "3.141592653589793" }}, + { "%.13f", 37.866261574537077, { "37.8662615745371" }}, + { "%.14f", 37.866261574537077, { "37.86626157453708" }}, + { "%.15f", 37.866261574537077, { "37.866261574537077" }}, + { "%.0g", 9.8949714229143402e-05, { "0.0001" }}, + { "%.0f", 0.5, { "1", NULL, NULL, NULL, "0" }, {NULL, NULL, NULL, NULL, "1" }}, + { "%.0f", 1.5, { "2" }}, + { "%.0f", 2.5, { "3", NULL, NULL, NULL, "2" }, {NULL, NULL, NULL, NULL, "3" }}, + { "%g", 9.999999999999999e-5, { "0.0001" }}, + + { "%g", 0.0005, { "0.0005" }}, + { "%g", 0.00005, { "5e-05", NULL, "5e-005" }}, + { "%g", 0.000005, { "5e-06", NULL, "5e-006" }}, + { "%g", 999999999999999.0, { "1e+15", NULL, "1e+015" }}, + { "%g", 1000000000000000.0, { "1e+15", NULL, "1e+015" }}, + { "%.15g", 0.0005, { "0.0005" }}, + { "%.15g", 0.00005, { "5e-05", NULL, "5e-005" }}, + { "%.15g", 0.000005, { "5e-06", NULL, "5e-006" }}, + { "%.15g", 999999999999999.0, { "999999999999999" }}, + { "%.15g", 1000000000000000.0, { "1e+15", NULL, "1e+015" }}, + }; + + const char *res = NULL; + const char *broken_res; + char buf[100]; + int i, j, r; + + for (i = 0; i < ARRAY_SIZE(tests); i++) + { + broken_res = NULL; + + for (j = 0; j < ARRAY_SIZE(flags); j++) + { + if (tests[i].res[j]) res = tests[i].res[j]; + if (tests[i].broken[j]) broken_res = tests[i].broken[j]; + + r = vsprintf_wrapper(flags[j], buf, sizeof(buf), tests[i].fmt, tests[i].d); + ok(r == strlen(res) || broken(broken_res && r == strlen(broken_res)), + "%d,%d) r = %d, expected %Id\n", i, j, r, strlen(res)); + ok(!strcmp(buf, res) || broken(broken_res && !strcmp(buf, broken_res)), + "%d,%d) buf = %s, expected %s\n", i, j, buf, res); + } + } +} + +static void test_printf_width_specification(void) +{ + int r; + char buffer[20]; + + r = vsprintf_wrapper(0, buffer, sizeof(buffer), "%0*2d", 1, 3); + ok(r == 2, "r = %d\n", r); + ok(!strcmp(buffer, "03"), "buffer wrong, got=%s\n", buffer); + + r = vsprintf_wrapper(0, buffer, sizeof(buffer), "%*0d", 1, 2); + ok(r == 1, "r = %d\n", r); + ok(!strcmp(buffer, "2"), "buffer wrong, got=%s\n", buffer); + + r = vsprintf_wrapper(0, buffer, sizeof(buffer), "% *2d", 0, 7); + ok(r == 2, "r = %d\n", r); + ok(!strcmp(buffer, " 7"), "buffer wrong, got=%s\n", buffer); +} + +START_TEST(printf) +{ + ok(_set_invalid_parameter_handler(test_invalid_parameter_handler) == NULL, + "Invalid parameter handler was already set\n"); + + test_snprintf(); + test_swprintf(); + test_fprintf(); + test_fwprintf(); + test_vsnprintf_s(); + test_vsnwprintf_s(); + test_printf_legacy_wide(); + test_printf_legacy_msvcrt(); + test_printf_legacy_three_digit_exp(); + test_printf_c99(); + test_printf_natural_string(); + test_printf_fp(); + test_printf_width_specification(); +} diff --git a/modules/rostests/winetests/ucrtbase/scanf.c b/modules/rostests/winetests/ucrtbase/scanf.c new file mode 100644 index 0000000000000..072352ae164dd --- /dev/null +++ b/modules/rostests/winetests/ucrtbase/scanf.c @@ -0,0 +1,330 @@ +/* + * Conformance tests for *scanf functions. + * + * Copyright 2002 Uwe Bonnes + * + * 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 +#include + +#include "windef.h" +#include "winbase.h" +#include "winnls.h" + +#include "wine/test.h" + +static int WINAPIV vsscanf_wrapper(unsigned __int64 options, const char *str, size_t len, const char *format, ...) +{ + int ret; + va_list valist; + va_start(valist, format); + ret = __stdio_common_vsscanf(options, str, len, format, NULL, valist); + va_end(valist); + return ret; +} + +static void test_sscanf(void) +{ + static const float float1 = -82.6267f, float2 = 27.76f; + char buffer[100], buffer1[100]; + int result, ret, hour, min, count; + LONGLONG result64; + DWORD_PTR result_ptr; + char c; + void *ptr; + float ret_float1, ret_float2; + double double_res; + unsigned int i; + size_t ret_size; + + static const unsigned int tests[] = + { + 0, + _CRT_INTERNAL_SCANF_LEGACY_WIDE_SPECIFIERS, + _CRT_INTERNAL_SCANF_LEGACY_MSVCRT_COMPATIBILITY, + }; + + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + ret = vsscanf_wrapper(tests[i], "", -1, "%d", &result); + ok(ret == EOF, "sscanf returned %d for flags %#x\n", ret, tests[i]); + + ret = vsscanf_wrapper(tests[i], "000000000046F170", -1, "%p", &ptr); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(ptr == (void *)0x46f170, "sscanf reads %p for flags %#x\n", ptr, tests[i]); + + ret = vsscanf_wrapper(tests[i], "0046F171", -1, "%p", &ptr); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(ptr == (void *)0x46f171, "sscanf reads %p for flags %#x\n", ptr, tests[i]); + + ret = vsscanf_wrapper(tests[i], "46F172", -1, "%p", &ptr); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(ptr == (void *)0x46f172, "sscanf reads %p for flags %#x\n", ptr, tests[i]); + + ret = vsscanf_wrapper(tests[i], "0x46F173", -1, "%p", &ptr); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + todo_wine ok(ptr == (void *)0x46f173, "sscanf reads %p for flags %#x\n", ptr, tests[i]); + + ret = vsscanf_wrapper(tests[i], "-46F174", -1, "%p", &ptr); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(ptr == (void *)(ULONG_PTR)-0x46f174, "sscanf reads %p for flags %#x\n", ptr, tests[i]); + + ret = vsscanf_wrapper(tests[i], "+46F175", -1, "%p", &ptr); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(ptr == (void *)0x46f175, "sscanf reads %p for flags %#x\n", ptr, tests[i]); + + ret = vsscanf_wrapper(tests[i], "1233", -1, "%p", &ptr); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(ptr == (void *)0x1233, "sscanf reads %p for flags %#x\n", ptr, tests[i]); + + ret = vsscanf_wrapper(tests[i], "1234", -1, "%P", &ptr); + todo_wine ok(ret == 0, "sscanf returned %d for flags %#x\n", ret, tests[i]); + + ret = vsscanf_wrapper(tests[i], "0x519", -1, "%x", &result); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(result == 0x519, "sscanf reads %#x for flags %#x\n", result, tests[i]); + + ret = vsscanf_wrapper(tests[i], "0x51a", -1, "%x", &result); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(result == 0x51a, "sscanf reads %#x for flags %#x\n", result, tests[i]); + + ret = vsscanf_wrapper(tests[i], "0x51g", -1, "%x", &result); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(result == 0x51, "sscanf reads %#x for flags %#x\n", result, tests[i]); + + result = 0; + ret = vsscanf_wrapper(tests[i], "-1", -1, "%x", &result); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(result == -1, "sscanf reads %#x for flags %#x\n", result, tests[i]); + + ret = vsscanf_wrapper(tests[i], "\"%12@", -1, "%\"%%%d%@", &result); + todo_wine ok(ret == 0, "sscanf returned %d for flags %#x\n", ret, tests[i]); + + sprintf(buffer, "%f %f", float1, float2); + ret = vsscanf_wrapper(tests[i], buffer, -1, "%f%f", &ret_float1, &ret_float2); + ok(ret == 2, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(ret_float1 == float1, "got wrong float %.8e for flags %#x\n", ret_float1, tests[i]); + ok(ret_float2 == float2, "got wrong float %.8e for flags %#x\n", ret_float2, tests[i]); + + sprintf(buffer, "%lf", 32.715); + ret = vsscanf_wrapper(tests[i], buffer, -1, "%lf", &double_res); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(double_res == 32.715, "got wrong double %.16e for flags %#x\n", double_res, tests[i]); + ret = vsscanf_wrapper(tests[i], buffer, -1, "%Lf", &double_res); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(double_res == 32.715, "got wrong double %.16e for flags %#x\n", double_res, tests[i]); + + ret = vsscanf_wrapper(tests[i], "1.1e-30", -1, "%lf", &double_res); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(double_res == 1.1e-30, "got wrong double %.16e for flags %#x\n", double_res, tests[i]); + + ret = vsscanf_wrapper(tests[i], " Waverly", -1, "%*c%[^\n]", buffer); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(!strcmp(buffer, " Waverly"), "got string '%s' for flags %#x\n", buffer, tests[i]); + + ret = vsscanf_wrapper(tests[i], "abcefgdh", -1, "%*[a-cg-e]%c", &buffer[0]); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(buffer[0] == 'd', "got char '%c' for flags %#x\n", buffer[0], tests[i]); + + ret = vsscanf_wrapper(tests[i], "abcefgdh", -1, "%*[a-cd-dg-e]%c", &buffer[0]); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(buffer[0] == 'h', "got char '%c' for flags %#x\n", buffer[0], tests[i]); + + strcpy(buffer, "foo"); + strcpy(buffer1, "bar"); + ret = vsscanf_wrapper(tests[i], "a", -1, "%s%s", buffer, buffer1); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(!strcmp(buffer, "a"), "got string '%s' for flags %#x\n", buffer, tests[i]); + ok(!strcmp(buffer1, "bar"), "got string '%s' for flags %#x\n", buffer1, tests[i]); + + ret = vsscanf_wrapper(tests[i], "21:59:20", -1, "%d%n", &result, &count); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(result == 21, "got wrong number %d for flags %#x\n", result, tests[i]); + ok(count == 2, "got wrong count %d for flags %#x\n", count, tests[i]); + + ret = vsscanf_wrapper(tests[i], ":59:20", -1, "%*c%n", &count); + ok(ret == 0, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(count == 1, "got wrong count %d for flags %#x\n", count, tests[i]); + + result = 0xdeadbeef; + ret = vsscanf_wrapper(tests[i], "12345678", -1, "%hd", &result); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(result == 0xdead614e, "got wrong number %#x for flags %#x\n", result, tests[i]); + + result = 0xdeadbeef; + ret = vsscanf_wrapper(tests[i], "12345678", -1, "%hhd", &result); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(result == 0xdeadbe4e, "got wrong number %#x for flags %#x\n", result, tests[i]); + + ret = vsscanf_wrapper(tests[i], "12345678901234", -1, "%lld", &result64); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(result64 == 12345678901234, "got wrong number 0x%s for flags %#x\n", + wine_dbgstr_longlong(result64), tests[i]); + + ret = vsscanf_wrapper(tests[i], "123", -1, "%i", &result); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(result == 123, "got wrong number %d for flags %#x\n", result, tests[i]); + + ret = vsscanf_wrapper(tests[i], "-1", -1, "%i", &result); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(result == -1, "got wrong number %d for flags %#x\n", result, tests[i]); + + ret = vsscanf_wrapper(tests[i], "123", -1, "%d", &result); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(result == 123, "got wrong number %d for flags %#x\n", result, tests[i]); + + ret = vsscanf_wrapper(tests[i], "-1", -1, "%d", &result); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(result == -1, "got wrong number %d for flags %#x\n", result, tests[i]); + + ret = vsscanf_wrapper(tests[i], "017", -1, "%i", &result); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(result == 15, "got wrong number %d for flags %#x\n", result, tests[i]); + + ret = vsscanf_wrapper(tests[i], "0x17", -1, "%i", &result); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(result == 23, "got wrong number %d for flags %#x\n", result, tests[i]); + + ret = vsscanf_wrapper(tests[i], "-1", -1, "%o", &result); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(result == -1, "got wrong number %d for flags %#x\n", result, tests[i]); + + ret = 0xdeadbeef; + ret = vsscanf_wrapper(tests[i], "-1", -1, "%u", &result); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(result == -1, "got wrong number %d for flags %#x\n", result, tests[i]); + + c = 0x55; + ret = vsscanf_wrapper(tests[i], "a", -1, "%c", &c); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(c == 'a', "got wrong char '%c' for flags %#x\n", c, tests[i]); + + c = 0x55; + ret = vsscanf_wrapper(tests[i], " a", -1, "%c", &c); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(c == ' ', "got wrong char '%c' for flags %#x\n", c, tests[i]); + + c = 0x55; + ret = vsscanf_wrapper(tests[i], "18:59", -1, "%d:%d%c", &hour, &min, &c); + ok(ret == 2, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(hour == 18, "got wrong char '%c' for flags %#x\n", hour, tests[i]); + ok(min == 59, "got wrong char '%c' for flags %#x\n", min, tests[i]); + ok(c == 0x55, "got wrong char '%c' for flags %#x\n", c, tests[i]); + + strcpy(buffer, "foo"); + strcpy(buffer1, "bar"); + ret = vsscanf_wrapper(tests[i], "abc def", -1, "%s %n%s", buffer, &count, buffer1); + ok(ret == 2, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(!strcmp(buffer, "abc"), "got wrong string '%s' for flags %#x\n", buffer, tests[i]); + ok(count == 6, "got wrong count %d for flags %#x\n", count, tests[i]); + ok(!strcmp(buffer1, "def"), "got wrong string '%s' for flags %#x\n", buffer1, tests[i]); + + ret = vsscanf_wrapper(tests[i], "3:45", -1, "%d:%d%n", &hour, &min, &count); + ok(ret == 2, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(hour == 3, "got wrong char '%c' for flags %#x\n", hour, tests[i]); + ok(min == 45, "got wrong char '%c' for flags %#x\n", min, tests[i]); + ok(count == 4, "got wrong count %d for flags %#x\n", count, tests[i]); + + strcpy(buffer, "foo"); + strcpy(buffer1, "bar"); + ret = vsscanf_wrapper(tests[i], "test=value\xda", -1, "%[^=] = %[^;]", buffer, buffer1); + ok(ret == 2, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(!strcmp(buffer, "test"), "got wrong string '%s' for flags %#x\n", buffer, tests[i]); + ok(!strcmp(buffer1, "value\xda"), "got wrong string '%s' for flags %#x\n", buffer1, tests[i]); + + ret = vsscanf_wrapper(tests[i], "0.1", 3, "%lf%n", &double_res, &count); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(double_res == 0.1, "got wrong double %.16e for flags %#x\n", double_res, tests[i]); + ok(count == 3, "got wrong count %d for flags %#x\n", count, tests[i]); + + ret = vsscanf_wrapper(tests[i], "a", -1, "%lf%n", &double_res, &count); + ok(ret == 0, "sscanf returned %d for flags %#x\n", ret, tests[i]); + + ret = vsscanf_wrapper(tests[i], "aa", -1, "%c%lf%n", &c, &double_res, &count); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + + ret = vsscanf_wrapper(tests[i], "a0e", -1, "%c%lf%n", &c, &double_res, &count); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + + ret = vsscanf_wrapper(tests[i], "0.", -1, "%lf%n", &double_res, &count); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(double_res == 0, "got wrong double %.16e for flags %#x\n", double_res, tests[i]); + ok(count == 2, "got wrong count %d for flags %#x\n", count, tests[i]); + + ret = vsscanf_wrapper(tests[i], "0.", 2, "%lf%n", &double_res, &count); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(double_res == 0, "got wrong double %.16e for flags %#x\n", double_res, tests[i]); + ok(count == 2, "got wrong count %d for flags %#x\n", count, tests[i]); + + ret = vsscanf_wrapper(tests[i], "1e", -1, "%lf%n", &double_res, &count); + ok(ret == -1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + + ret = vsscanf_wrapper(tests[i], "1e ", 2, "%lf%n", &double_res, &count); + ok(ret == -1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + + ret = vsscanf_wrapper(tests[i], "1e+", -1, "%lf%n", &double_res, &count); + ok(ret == -1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + + ret = vsscanf_wrapper(tests[i], "inf", -1, "%lf%n", &double_res, &count); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(double_res == INFINITY, "got wrong double %.16e for flags %#x\n", double_res, tests[i]); + ok(count == 3, "got wrong count %d for flags %#x\n", count, tests[i]); + + ret = vsscanf_wrapper(tests[i], "infa", -1, "%lf%n", &double_res, &count); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(double_res == INFINITY, "got wrong double %.16e for flags %#x\n", double_res, tests[i]); + ok(count == 3, "got wrong count %d for flags %#x\n", count, tests[i]); + + ret = vsscanf_wrapper(tests[i], "infi", -1, "%lf%n", &double_res, &count); + ok(ret == -1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + + ret_size = ~0; + ret = vsscanf_wrapper(tests[i], "1", -1, "%zd", &ret_size); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(ret_size == 1, "got wrong size_t %s for flags %#x\n", + wine_dbgstr_longlong((LONGLONG)ret_size), tests[i]); + + result64 = 0; + ret = vsscanf_wrapper(tests[i], "12345678901234", -1, "%I64d", &result64); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(result64 == 12345678901234ll, "got wrong number 0x%s for flags %#x\n", + wine_dbgstr_longlong(result64), tests[i]); + + result = 0; + ret = vsscanf_wrapper(tests[i], "12345678901234", -1, "%I32d", &result); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(result == (int)12345678901234ll, /* this is always truncated to 32bit */ + "got wrong number 0x%d for flags %#x\n", result, tests[i]); + + result_ptr = 0; + ret = vsscanf_wrapper(tests[i], "0x87654321", -1, "%Ix", &result_ptr); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(result_ptr == 0x87654321, + "got wrong number %Ix for flags %#x\n", result_ptr, tests[i]); + + result_ptr = 0; + ret = vsscanf_wrapper(tests[i], "0x123456789", -1, "%Ix", &result_ptr); + ok(ret == 1, "sscanf returned %d for flags %#x\n", ret, tests[i]); + ok(result_ptr == (DWORD_PTR)0x123456789ull, /* this is truncated on 32bit systems */ + "got wrong number %Ix for flags %#x\n", result_ptr, tests[i]); + } +} + +START_TEST(scanf) +{ + test_sscanf(); +} diff --git a/modules/rostests/winetests/ucrtbase/string.c b/modules/rostests/winetests/ucrtbase/string.c new file mode 100644 index 0000000000000..aded941d4d9a4 --- /dev/null +++ b/modules/rostests/winetests/ucrtbase/string.c @@ -0,0 +1,860 @@ +/* + * Copyright 2015 Martin Storsjo + * + * 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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "wine/test.h" + +#include + +#define DEFINE_EXPECT(func) \ + static BOOL expect_ ## func = FALSE, called_ ## func = FALSE + +#define SET_EXPECT(func) \ + expect_ ## func = TRUE + +#define CHECK_EXPECT2(func) \ + do { \ + ok(expect_ ##func, "unexpected call " #func "\n"); \ + called_ ## func = TRUE; \ + }while(0) + +#define CHECK_EXPECT(func) \ + do { \ + CHECK_EXPECT2(func); \ + expect_ ## func = FALSE; \ + }while(0) + +#define CHECK_CALLED(func) \ + do { \ + ok(called_ ## func, "expected " #func "\n"); \ + expect_ ## func = called_ ## func = FALSE; \ + }while(0) + +DEFINE_EXPECT(invalid_parameter_handler); + +static void __cdecl test_invalid_parameter_handler(const wchar_t *expression, + const wchar_t *function, const wchar_t *file, + unsigned line, uintptr_t arg) +{ + CHECK_EXPECT(invalid_parameter_handler); + ok(expression == NULL, "expression is not NULL\n"); + ok(function == NULL, "function is not NULL\n"); + ok(file == NULL, "file is not NULL\n"); + ok(line == 0, "line = %u\n", line); + ok(arg == 0, "arg = %Ix\n", arg); +} + +_ACRTIMP int __cdecl _o_tolower(int); +_ACRTIMP int __cdecl _o_toupper(int); + +static BOOL local_isnan(double d) +{ + return d != d; +} + +#define test_strtod_str_errno(string, value, length, err) _test_strtod_str(__LINE__, string, value, length, err) +#define test_strtod_str(string, value, length) _test_strtod_str(__LINE__, string, value, length, 0) +static void _test_strtod_str(int line, const char* string, double value, int length, int err) +{ + char *end; + double d; + errno = 0xdeadbeef; + d = strtod(string, &end); + if(!err) + ok_(__FILE__, line)(errno == 0xdeadbeef, "errno = %d\n", errno); + else + ok_(__FILE__, line)(errno == err, "errno = %d\n", errno); + if (local_isnan(value)) + ok_(__FILE__, line)(local_isnan(d), "d = %.16le (\"%s\")\n", d, string); + else + ok_(__FILE__, line)(d == value, "d = %.16le (\"%s\")\n", d, string); + ok_(__FILE__, line)(end == string + length, "incorrect end (%d, \"%s\")\n", (int)(end - string), string); +} + +static void test_strtod(void) +{ + test_strtod_str("infinity", INFINITY, 8); + test_strtod_str("INFINITY", INFINITY, 8); + test_strtod_str("InFiNiTy", INFINITY, 8); + test_strtod_str("INF", INFINITY, 3); + test_strtod_str("-inf", -INFINITY, 4); + test_strtod_str("inf42", INFINITY, 3); + test_strtod_str("inffoo", INFINITY, 3); + test_strtod_str("infini", INFINITY, 3); + test_strtod_str("input", 0, 0); + test_strtod_str("-input", 0, 0); + test_strtod_str_errno("1.7976931348623159e+308", INFINITY, 23, ERANGE); + test_strtod_str_errno("-1.7976931348623159e+308", -INFINITY, 24, ERANGE); + + test_strtod_str("NAN", NAN, 3); + test_strtod_str("nan", NAN, 3); + test_strtod_str("NaN", NAN, 3); + + test_strtod_str("0x42", 66, 4); + test_strtod_str("0X42", 66, 4); + test_strtod_str("-0x42", -66, 5); + test_strtod_str("0x1p1", 2, 5); + test_strtod_str("0x1P1", 2, 5); + test_strtod_str("0x1p+1", 2, 6); + test_strtod_str("0x2p-1", 1, 6); + test_strtod_str("0xA", 10, 3); + test_strtod_str("0xa", 10, 3); + test_strtod_str("0xABCDEF", 11259375, 8); + test_strtod_str("0Xabcdef", 11259375, 8); + + test_strtod_str("0x1.1", 1.0625, 5); + test_strtod_str("0x1.1p1", 2.125, 7); + test_strtod_str("0x1.A", 1.625, 5); + test_strtod_str("0x1p1a", 2, 5); + test_strtod_str("0xp3", 0, 1); + test_strtod_str("0x.", 0, 1); + test_strtod_str("0x.8", 0.5, 4); + test_strtod_str("0x.8p", 0.5, 4); + test_strtod_str("0x0p10000000000000000000000000", 0, 30); + test_strtod_str("0x1p-1026", 1.3906711615670009e-309, 9); + + test_strtod_str("0x1ffffffffffffe.80000000000000000000", 9007199254740990.0, 37); + test_strtod_str("0x1ffffffffffffe.80000000000000000001", 9007199254740991.0, 37); + test_strtod_str("0x1fffffffffffff.80000000000000000000", 9007199254740992.0, 37); + test_strtod_str("0x1fffffffffffff.80000000000000000001", 9007199254740992.0, 37); + + test_strtod_str("4.0621786324484881721115322e-53", 4.0621786324484881721115322e-53, 31); + test_strtod_str("1.8905590910042396899370942", 1.8905590910042396899370942, 27); + test_strtod_str("1.7976931348623158e+308", 1.7976931348623158e+308, 23); + test_strtod_str("2.2250738585072014e-308", 2.2250738585072014e-308, 23); + test_strtod_str("4.9406564584124654e-324", 4.9406564584124654e-324, 23); + test_strtod_str("2.48e-324", 4.9406564584124654e-324, 9); + test_strtod_str_errno("2.47e-324", 0, 9, ERANGE); +} + +static void test_strtof(void) +{ + static const struct { + const char *str; + int len; + float ret; + int err; + } tests[] = { + { "12.1", 4, 12.1f }, + { "-13.721", 7, -13.721f }, + { "1.e40", 5, INFINITY, ERANGE }, + { "-1.e40", 6, -INFINITY, ERANGE }, + { "0.0", 3, 0.0f }, + { "-0.0", 4, 0.0f }, + { "1.4e-45", 7, 1.4e-45f }, + { "-1.4e-45", 8, -1.4e-45f }, + { "1.e-60", 6, 0, ERANGE }, + { "-1.e-60", 7, 0, ERANGE }, + }; + + char *end; + float f; + int i; + + for (i=0; i= 'A' && i <= 'Z') + { + exp = i + 'a' - 'A'; + ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret); + } + else + ok(ret == i, "expected self %x, got %x for C locale\n", i, ret); + + ret = _tolower(i); + exp = i + 'a' - 'A'; + ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret); + + ret = _o_tolower(i); + if (i >= 'A' && i <= 'Z') + { + exp = i + 'a' - 'A'; + ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret); + } + else + ok(ret == i, "expected self %x, got %x for C locale\n", i, ret); + + ret = towlower(i); + if (i >= 'A' && i <= 'Z') + { + exp = i + 'a' - 'A'; + ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret); + } + else + ok(ret == i, "expected self %x, got %x for C locale\n", i, ret); + + ret = toupper(i); + if (i >= 'a' && i <= 'z') + { + exp = i + 'A' - 'a'; + ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret); + } + else + ok(ret == i, "expected self %x, got %x for C locale\n", i, ret); + + ret = _toupper(i); + exp = i + 'A' - 'a'; + ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret); + + ret = _o_toupper(i); + if (i >= 'a' && i <= 'z') + { + exp = i + 'A' - 'a'; + ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret); + } + else + ok(ret == i, "expected self %x, got %x for C locale\n", i, ret); + + ret = towupper(i); + if (i >= 'a' && i <= 'z') + { + exp = i + 'A' - 'a'; + ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret); + } + else + ok(ret == i, "expected self %x, got %x for C locale\n", i, ret); + } + + for (i = 0; i < ARRAY_SIZE(locales); i++) { + locale = locales[i] ? _create_locale(LC_ALL, locales[i]) : NULL; + + for (j = 0; j <= 0xffff; j++) { + ret = _towlower_l(j, locale); + if (j >= 'A' && j <= 'Z') + { + exp = j + 'a' - 'A'; + ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret); + } + else + ok(ret == j, "expected self %x, got %x for C locale\n", j, ret); + + ret = _towupper_l(j, locale); + if (j >= 'a' && j <= 'z') + { + exp = j + 'A' - 'a'; + ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret); + } + else + ok(ret == j, "expected self %x, got %x for C locale\n", j, ret); + } + + _free_locale(locale); + } +} + +static void test_mbsspn( void) +{ + unsigned char str1[] = "cabernet"; + unsigned char str2[] = "shiraz"; + unsigned char set[] = "abc"; + unsigned char empty[] = ""; + unsigned char mbstr[] = " 2019\x94\x4e" "6\x8c\x8e" "29\x93\xfa"; + unsigned char mbset1[] = "0123456789 \x94\x4e"; + unsigned char mbset2[] = " \x94\x4e\x8c\x8e"; + unsigned char mbset3[] = "\x8e"; + int ret, cp = _getmbcp(); + + ret = _mbsspn(str1, set); + ok(ret == 3, "_mbsspn returns %d should be 3\n", ret); + ret = _mbsspn(str2, set); + ok(ret == 0, "_mbsspn returns %d should be 0\n", ret); + ret = _mbsspn(str1, empty); + ok(ret == 0, "_mbsspn returns %d should be 0\n", ret); + + _setmbcp(932); + ret = _mbsspn(mbstr, mbset1); + ok(ret == 8, "_mbsspn returns %d should be 8\n", ret); + ret = _mbsspn(mbstr, mbset2); + ok(ret == 1, "_mbsspn returns %d should be 1\n", ret); + ret = _mbsspn(mbstr+8, mbset1); + ok(ret == 0, "_mbsspn returns %d should be 0\n", ret); + ret = _mbsspn(mbstr+8, mbset2); + ok(ret == 2, "_mbsspn returns %d should be 2\n", ret); + ret = _mbsspn(mbstr, mbset3); + ok(ret == 14, "_mbsspn returns %d should be 14\n", ret); + + _setmbcp(cp); +} + +static void test_wcstok(void) +{ + static const wchar_t *input = L"two words"; + wchar_t buffer[16]; + wchar_t *token; + wchar_t *next; + + next = NULL; + wcscpy(buffer, input); + token = wcstok(buffer, L" ", &next); + ok(!wcscmp(L"two", token), "expected \"two\", got \"%ls\"\n", token); + ok(next == token + 4, "expected %p, got %p\n", token + 4, next); + token = wcstok(NULL, L" ", &next); + ok(!wcscmp(L"words", token), "expected \"words\", got \"%ls\"\n", token); + ok(next == token + 5, "expected %p, got %p\n", token + 5, next); + token = wcstok(NULL, L" ", &next); + ok(!token, "expected NULL, got %p\n", token); + + wcscpy(buffer, input); + token = wcstok(buffer, L" ", NULL); + ok(!wcscmp(L"two", token), "expected \"two\", got \"%ls\"\n", token); + token = wcstok(NULL, L" ", NULL); + ok(!wcscmp(L"words", token), "expected \"words\", got \"%ls\"\n", token); + token = wcstok(NULL, L" ", NULL); + ok(!token, "expected NULL, got %p\n", token); + + next = NULL; + wcscpy(buffer, input); + token = wcstok(buffer, L"=", &next); + ok(!wcscmp(token, input), "expected \"%ls\", got \"%ls\"\n", input, token); + ok(next == buffer + wcslen(input), "expected %p, got %p\n", buffer + wcslen(input), next); + token = wcstok(NULL, L"=", &next); + ok(!token, "expected NULL, got \"%ls\"\n", token); + ok(next == buffer + wcslen(input), "expected %p, got %p\n", buffer + wcslen(input), next); + + next = NULL; + wcscpy(buffer, L""); + token = wcstok(buffer, L"=", &next); + ok(token == NULL, "expected NULL, got \"%ls\"\n", token); + ok(next == buffer, "expected %p, got %p\n", buffer, next); + token = wcstok(NULL, L"=", &next); + ok(!token, "expected NULL, got \"%ls\"\n", token); + ok(next == buffer, "expected %p, got %p\n", buffer, next); +} + +static void test__strnicmp(void) +{ + static const char str1[] = "TEST"; + static const char str2[] = "test"; + int ret; + + SET_EXPECT(invalid_parameter_handler); + errno = 0xdeadbeef; + ret = _strnicmp(str1, NULL, 2); + CHECK_CALLED(invalid_parameter_handler); + ok(ret == _NLSCMPERROR, "got %d.\n", ret); + ok(errno == EINVAL, "Unexpected errno %d.\n", errno); + + SET_EXPECT(invalid_parameter_handler); + errno = 0xdeadbeef; + ret = _strnicmp(str1, str2, -1); + CHECK_CALLED(invalid_parameter_handler); + ok(ret == _NLSCMPERROR, "got %d.\n", ret); + ok(errno == EINVAL, "Unexpected errno %d.\n", errno); + + ret = _strnicmp(str1, str2, 0); + ok(!ret, "got %d.\n", ret); + + ret = _strnicmp(str1, str2, 0x7fffffff); + ok(!ret, "got %d.\n", ret); + + /* If numbers of characters to compare is too big return error */ + SET_EXPECT(invalid_parameter_handler); + errno = 0xdeadbeef; + ret = _strnicmp(str1, str2, 0x80000000); + CHECK_CALLED(invalid_parameter_handler); + ok(ret == _NLSCMPERROR, "got %d.\n", ret); + ok(errno == EINVAL, "Unexpected errno %d.\n", errno); +} + +static void test_wcsnicmp(void) +{ + static const wchar_t str1[] = L"TEST"; + static const wchar_t str2[] = L"test"; + int ret; + + errno = 0xdeadbeef; + ret = wcsnicmp(str1, str2, -1); + ok(!ret, "got %d.\n", ret); + + ret = wcsnicmp(str1, str2, 0x7fffffff); + ok(!ret, "got %d.\n", ret); +} + +static void test_SpecialCasing(void) +{ + int i; + wint_t ret, exp; + _locale_t locale; + struct test { + const char *lang; + wint_t ch; + wint_t exp; + }; + + struct test ucases[] = { + {"English", 'I', 'i'}, /* LATIN CAPITAL LETTER I */ + {"English", 0x0130}, /* LATIN CAPITAL LETTER I WITH DOT ABOVE */ + + {"Turkish", 'I', 'i'}, /* LATIN CAPITAL LETTER I */ + {"Turkish", 0x0130}, /* LATIN CAPITAL LETTER I WITH DOT ABOVE */ + }; + struct test lcases[] = { + {"English", 'i', 'I'}, /* LATIN SMALL LETTER I */ + {"English", 0x0131}, /* LATIN SMALL LETTER DOTLESS I */ + + {"Turkish", 'i', 'I'}, /* LATIN SMALL LETTER I */ + {"Turkish", 0x0131}, /* LATIN SMALL LETTER DOTLESS I */ + }; + + for (i = 0; i < ARRAY_SIZE(ucases); i++) { + if (!setlocale(LC_ALL, ucases[i].lang)) { + win_skip("skipping special case tests for %s\n", ucases[i].lang); + continue; + } + + ret = towlower(ucases[i].ch); + exp = ucases[i].exp ? ucases[i].exp : ucases[i].ch; + ok(ret == exp, "expected lowercase %x, got %x for locale %s\n", exp, ret, ucases[i].lang); + } + + for (i = 0; i < ARRAY_SIZE(lcases); i++) { + if (!setlocale(LC_ALL, lcases[i].lang)) { + win_skip("skipping special case tests for %s\n", lcases[i].lang); + continue; + } + + ret = towupper(lcases[i].ch); + exp = lcases[i].exp ? lcases[i].exp : lcases[i].ch; + ok(ret == exp, "expected uppercase %x, got %x for locale %s\n", exp, ret, lcases[i].lang); + } + + setlocale(LC_ALL, "C"); + + /* test _towlower_l creating locale */ + for (i = 0; i < ARRAY_SIZE(ucases); i++) { + if (!(locale = _create_locale(LC_ALL, ucases[i].lang))) { + win_skip("locale %s not available. skipping\n", ucases[i].lang); + continue; + } + + ret = _towlower_l(ucases[i].ch, locale); + exp = ucases[i].exp ? ucases[i].exp : ucases[i].ch; + ok(ret == exp, "expected lowercase %x, got %x for locale %s\n", exp, ret, ucases[i].lang); + + _free_locale(locale); + } + + /* test _towupper_l creating locale */ + for (i = 0; i < ARRAY_SIZE(lcases); i++) { + if (!(locale = _create_locale(LC_ALL, lcases[i].lang))) { + win_skip("locale %s not available. skipping\n", lcases[i].lang); + continue; + } + + ret = _towupper_l(lcases[i].ch, locale); + exp = lcases[i].exp ? lcases[i].exp : lcases[i].ch; + ok(ret == exp, "expected uppercase %x, got %x for locale %s\n", exp, ret, lcases[i].lang); + + _free_locale(locale); + } +} + +static void test__mbbtype_l(void) +{ + int expected, ret; + unsigned int c; + + _setmbcp(_MB_CP_LOCALE); + for (c = 0; c < 256; ++c) + { + expected = _mbbtype(c, 0); + ret = _mbbtype_l(c, 0, NULL); + ok(ret == expected, "c %#x, got ret %#x, expected %#x.\n", c, ret, expected); + + expected = _mbbtype(c, 1); + ret = _mbbtype_l(c, 1, NULL); + ok(ret == expected, "c %#x, got ret %#x, expected %#x.\n", c, ret, expected); + } +} + +static void test_strcmp(void) +{ + int ret = strcmp( "abc", "abcd" ); + ok( ret == -1, "wrong ret %d\n", ret ); + ret = strcmp( "", "abc" ); + ok( ret == -1, "wrong ret %d\n", ret ); + ret = strcmp( "abc", "ab\xa0" ); + ok( ret == -1, "wrong ret %d\n", ret ); + ret = strcmp( "ab\xb0", "ab\xa0" ); + ok( ret == 1, "wrong ret %d\n", ret ); + ret = strcmp( "ab\xc2", "ab\xc2" ); + ok( ret == 0, "wrong ret %d\n", ret ); + + ret = strncmp( "abc", "abcd", 3 ); + ok( ret == 0, "wrong ret %d\n", ret ); + ret = strncmp( "", "abc", 3 ); + ok( ret == -1, "wrong ret %d\n", ret ); + ret = strncmp( "abc", "ab\xa0", 4 ); + ok( ret == -1, "wrong ret %d\n", ret ); + ret = strncmp( "ab\xb0", "ab\xa0", 3 ); + ok( ret == 1, "wrong ret %d\n", ret ); + ret = strncmp( "ab\xb0", "ab\xa0", 2 ); + ok( ret == 0, "wrong ret %d\n", ret ); + ret = strncmp( "ab\xc2", "ab\xc2", 3 ); + ok( ret == 0, "wrong ret %d\n", ret ); + ret = strncmp( "abc", "abd", 0 ); + ok( ret == 0, "wrong ret %d\n", ret ); + ret = strncmp( "abc", "abc", 12 ); + ok( ret == 0, "wrong ret %d\n", ret ); +} + +#define expect_bin(buf, value, len) { ok(memcmp((buf), value, len) == 0, \ + "Binary buffer mismatch - expected %s, got %s\n", \ + debugstr_an(value, len), debugstr_an((char *)(buf), len)); } + +static void test__mbsncpy_s(void) +{ + unsigned char *mbstring = (unsigned char *)"\xb0\xb1\xb2\xb3Q\xb4\xb5\x0"; + unsigned char *mbstring2 = (unsigned char *)"\xb0\x0"; + unsigned char buf[16]; + errno_t err; + int oldcp; + + oldcp = _getmbcp(); + if (_setmbcp(936)) + { + skip("Code page 936 is not available, skipping test.\n"); + return; + } + + errno = 0xdeadbeef; + memset(buf, 0xcc, sizeof(buf)); + err = _mbsncpy_s(NULL, 0, mbstring, 0); + ok(errno == 0xdeadbeef, "got %d\n", errno); + ok(!err, "got %d.\n", err); + + errno = 0xdeadbeef; + memset(buf, 0xcc, sizeof(buf)); + err = _mbsncpy_s(buf, 6, mbstring, 1); + ok(errno == 0xdeadbeef, "got %d\n", errno); + ok(!err, "got %d.\n", err); + expect_bin(buf, "\xb0\xb1\0\xcc", 4); + + memset(buf, 0xcc, sizeof(buf)); + errno = 0xdeadbeef; + err = _mbsncpy_s(buf, 6, mbstring, 2); + ok(errno == 0xdeadbeef, "got %d\n", errno); + ok(!err, "got %d.\n", err); + expect_bin(buf, "\xb0\xb1\xb2\xb3\0\xcc", 6); + + errno = 0xdeadbeef; + memset(buf, 0xcc, sizeof(buf)); + err = _mbsncpy_s(buf, 2, mbstring, _TRUNCATE); + ok(errno == 0xdeadbeef, "got %d\n", errno); + ok(err == STRUNCATE, "got %d.\n", err); + expect_bin(buf, "\x00\xb1\xcc", 3); + + memset(buf, 0xcc, sizeof(buf)); + SET_EXPECT(invalid_parameter_handler); + errno = 0xdeadbeef; + err = _mbsncpy_s(buf, 2, mbstring, 1); + ok(errno == err, "got %d.\n", errno); + CHECK_CALLED(invalid_parameter_handler); + ok(err == ERANGE, "got %d.\n", err); + expect_bin(buf, "\x0\xcc\xcc", 3); + + memset(buf, 0xcc, sizeof(buf)); + SET_EXPECT(invalid_parameter_handler); + errno = 0xdeadbeef; + err = _mbsncpy_s(buf, 2, mbstring, 3); + ok(errno == err, "got %d\n", errno); + CHECK_CALLED(invalid_parameter_handler); + ok(err == ERANGE, "got %d.\n", err); + expect_bin(buf, "\x0\xcc\xcc", 3); + + memset(buf, 0xcc, sizeof(buf)); + SET_EXPECT(invalid_parameter_handler); + errno = 0xdeadbeef; + err = _mbsncpy_s(buf, 1, mbstring, 3); + ok(errno == err, "got %d\n", errno); + CHECK_CALLED(invalid_parameter_handler); + ok(err == ERANGE, "got %d.\n", err); + expect_bin(buf, "\x0\xcc", 2); + + memset(buf, 0xcc, sizeof(buf)); + SET_EXPECT(invalid_parameter_handler); + errno = 0xdeadbeef; + err = _mbsncpy_s(buf, 0, mbstring, 3); + ok(errno == err, "got %d\n", errno); + CHECK_CALLED(invalid_parameter_handler); + ok(err == EINVAL, "got %d.\n", err); + expect_bin(buf, "\xcc", 1); + + memset(buf, 0xcc, sizeof(buf)); + SET_EXPECT(invalid_parameter_handler); + errno = 0xdeadbeef; + err = _mbsncpy_s(buf, 0, mbstring, 0); + ok(errno == err, "got %d\n", errno); + CHECK_CALLED(invalid_parameter_handler); + ok(err == EINVAL, "got %d.\n", err); + expect_bin(buf, "\xcc", 1); + + memset(buf, 0xcc, sizeof(buf)); + errno = 0xdeadbeef; + err = _mbsncpy_s(buf, -1, mbstring, 0); + ok(errno == 0xdeadbeef, "got %d\n", errno); + ok(!err, "got %d.\n", err); + expect_bin(buf, "\x0\xcc", 2); + + memset(buf, 0xcc, sizeof(buf)); + errno = 0xdeadbeef; + err = _mbsncpy_s(buf, -1, mbstring, 256); + ok(errno == 0xdeadbeef, "got %d\n", errno); + ok(!err, "got %d.\n", err); + expect_bin(buf, "\xb0\xb1\xb2\xb3Q\xb4\xb5\x0\xcc", 9); + + memset(buf, 0xcc, sizeof(buf)); + errno = 0xdeadbeef; + err = _mbsncpy_s(buf, 1, mbstring2, 4); + ok(errno == err, "got %d\n", errno); + ok(err == EILSEQ, "got %d.\n", err); + expect_bin(buf, "\x0\xcc", 2); + + memset(buf, 0xcc, sizeof(buf)); + errno = 0xdeadbeef; + err = _mbsncpy_s(buf, 2, mbstring2, 4); + ok(errno == err, "got %d\n", errno); + ok(err == EILSEQ, "got %d.\n", err); + expect_bin(buf, "\x0\xcc", 2); + + memset(buf, 0xcc, sizeof(buf)); + errno = 0xdeadbeef; + err = _mbsncpy_s(buf, 1, mbstring2, _TRUNCATE); + ok(errno == 0xdeadbeef, "got %d\n", errno); + ok(err == STRUNCATE, "got %d.\n", err); + expect_bin(buf, "\x0\xcc", 2); + + memset(buf, 0xcc, sizeof(buf)); + errno = 0xdeadbeef; + err = _mbsncpy_s(buf, 2, mbstring2, _TRUNCATE); + ok(errno == 0xdeadbeef, "got %d\n", errno); + ok(!err, "got %d.\n", err); + expect_bin(buf, "\xb0\x0\xcc", 3); + + memset(buf, 0xcc, sizeof(buf)); + errno = 0xdeadbeef; + err = _mbsncpy_s(buf, 1, mbstring2, 1); + ok(errno == err, "got %d\n", errno); + ok(err == EILSEQ, "got %d.\n", err); + expect_bin(buf, "\x0\xcc", 2); + + memset(buf, 0xcc, sizeof(buf)); + errno = 0xdeadbeef; + err = _mbsncpy_s(buf, 2, mbstring2, 1); + ok(errno == err, "got %d\n", errno); + ok(err == EILSEQ, "got %d.\n", err); + expect_bin(buf, "\x0\xcc", 2); + + memset(buf, 0xcc, sizeof(buf)); + errno = 0xdeadbeef; + err = _mbsncpy_s(buf, 3, mbstring2, 1); + ok(errno == err, "got %d\n", errno); + ok(err == EILSEQ, "got %d.\n", err); + expect_bin(buf, "\x0\xcc", 2); + + memset(buf, 0xcc, sizeof(buf)); + errno = 0xdeadbeef; + err = _mbsncpy_s(buf, 3, mbstring2, 2); + ok(errno == err, "got %d\n", errno); + ok(err == EILSEQ, "got %d.\n", err); + expect_bin(buf, "\x0\xcc", 2); + + _setmbcp(oldcp); +} + +static void test_mbstowcs(void) +{ + static const char mbs[] = { 0xc3, 0xa9, 0 }; + WCHAR wcs[2]; + size_t ret; + + if (!setlocale(LC_ALL, "en_US.UTF-8")) + { + win_skip("skipping UTF8 mbstowcs tests\n"); + return; + } + + ret = mbstowcs(NULL, mbs, 0); + ok(ret == 1, "mbstowcs returned %Id\n", ret); + memset(wcs, 0xfe, sizeof(wcs)); + ret = mbstowcs(wcs, mbs, 1); + ok(ret == 1, "mbstowcs returned %Id\n", ret); + ok(wcs[0] == 0xe9, "wcsstring[0] = %x\n", wcs[0]); + ok(wcs[1] == 0xfefe, "wcsstring[1] = %x\n", wcs[1]); + setlocale(LC_ALL, "C"); +} + +START_TEST(string) +{ + ok(_set_invalid_parameter_handler(test_invalid_parameter_handler) == NULL, + "Invalid parameter handler was already set\n"); + + test_strtod(); + test_strtof(); + test__memicmp(); + test__memicmp_l(); + test___strncnt(); + test_C_locale(); + test_mbsspn(); + test_wcstok(); + test__strnicmp(); + test_wcsnicmp(); + test_SpecialCasing(); + test__mbbtype_l(); + test_strcmp(); + test__mbsncpy_s(); + test_mbstowcs(); +} diff --git a/modules/rostests/winetests/ucrtbase/testlist.c b/modules/rostests/winetests/ucrtbase/testlist.c new file mode 100644 index 0000000000000..6445a0dd6adf9 --- /dev/null +++ b/modules/rostests/winetests/ucrtbase/testlist.c @@ -0,0 +1,28 @@ +/* Automatically generated file; DO NOT EDIT!! */ + +#define STANDALONE +#include + +extern void func_cpp(void); +extern void func_environ(void); +extern void func_file(void); +extern void func_misc(void); +extern void func_printf(void); +extern void func_scanf(void); +extern void func_string(void); +extern void func_thread(void); + + +const struct test winetest_testlist[] = +{ + { "cpp", func_cpp }, + { "environ", func_environ }, + { "file", func_file }, + { "misc", func_misc }, + { "printf", func_printf }, + { "scanf", func_scanf }, + { "string", func_string }, + { "thread", func_thread }, + + { 0, 0 } +}; diff --git a/modules/rostests/winetests/ucrtbase/thread.c b/modules/rostests/winetests/ucrtbase/thread.c new file mode 100644 index 0000000000000..5e55c5f94716d --- /dev/null +++ b/modules/rostests/winetests/ucrtbase/thread.c @@ -0,0 +1,187 @@ +/* + * Copyright 2021 Arkadiusz Hiler 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 +#include +#include + +#include +#include +#include "wine/test.h" + +#include "threaddll.h" + +typedef void (__cdecl *_beginthread_start_routine_t)(void *); +typedef unsigned int (__stdcall *_beginthreadex_start_routine_t)(void *); + +enum beginthread_method +{ + use_beginthread, + use_beginthreadex +}; + +static char *get_thread_dll_path(void) +{ + static char path[MAX_PATH]; + const char dll_name[] = "threaddll.dll"; + DWORD written; + HANDLE file; + HRSRC res; + void *ptr; + + GetTempPathA(ARRAY_SIZE(path), path); + strcat(path, dll_name); + + file = CreateFileA(path, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); + ok(file != INVALID_HANDLE_VALUE, "Failed to create file %s: %lu.\n", + debugstr_a(path), GetLastError()); + + res = FindResourceA(NULL, dll_name, "TESTDLL"); + ok(!!res, "Failed to load resource: %lu\n", GetLastError()); + ptr = LockResource(LoadResource(GetModuleHandleA(NULL), res)); + WriteFile(file, ptr, SizeofResource( GetModuleHandleA(NULL), res), &written, NULL); + ok(written == SizeofResource(GetModuleHandleA(NULL), res), "Failed to write resource\n"); + CloseHandle(file); + + return path; +} + +static void set_thead_dll_detach_event(HANDLE dll, HANDLE event) +{ + void (WINAPI *_set_detach_event)(HANDLE event); + _set_detach_event = (void*) GetProcAddress(dll, "set_detach_event"); + ok(_set_detach_event != NULL, "Failed to get set_detach_event: %lu\n", GetLastError()); + _set_detach_event(event); +} + +static void test_thread_library_reference(char *thread_dll, + enum beginthread_method beginthread_method, + enum thread_exit_method exit_method) +{ + HANDLE detach_event; + HMODULE dll; + DWORD ret; + uintptr_t thread_handle; + struct threaddll_args args; + + args.exit_method = exit_method; + + detach_event = CreateEventA(NULL, FALSE, FALSE, NULL); + ok(detach_event != NULL, "Failed to create an event: %lu\n", GetLastError()); + args.confirm_running = CreateEventA(NULL, FALSE, FALSE, NULL); + ok(args.confirm_running != NULL, "Failed to create an event: %lu\n", GetLastError()); + args.past_free = CreateEventA(NULL, FALSE, FALSE, NULL); + ok(args.past_free != NULL, "Failed to create an event: %lu\n", GetLastError()); + + dll = LoadLibraryA(thread_dll); + ok(dll != NULL, "Failed to load the test dll: %lu\n", GetLastError()); + + set_thead_dll_detach_event(dll, detach_event); + + if (beginthread_method == use_beginthreadex) + { + _beginthreadex_start_routine_t proc = (void*) GetProcAddress(dll, "stdcall_thread_proc"); + ok(proc != NULL, "Failed to get stdcall_thread_proc: %lu\n", GetLastError()); + thread_handle = _beginthreadex(NULL, 0, proc, &args, 0, NULL); + } + else + { + _beginthread_start_routine_t proc = (void*) GetProcAddress(dll, "cdecl_thread_proc"); + ok(proc != NULL, "Failed to get stdcall_thread_proc: %lu\n", GetLastError()); + thread_handle = _beginthread(proc, 0, &args); + } + + ok(thread_handle != -1 && thread_handle != 0, "Failed to begin thread: %u\n", errno); + + ret = FreeLibrary(dll); + ok(ret, "Failed to free the library: %lu\n", GetLastError()); + + ret = WaitForSingleObject(args.confirm_running, 200); + ok(ret == WAIT_OBJECT_0, "Event was not signaled, ret: %lu, err: %lu\n", ret, GetLastError()); + + ret = WaitForSingleObject(detach_event, 0); + ok(ret == WAIT_TIMEOUT, "Thread detach happened unexpectedly signaling an event, ret: %ld, err: %lu\n", ret, GetLastError()); + + ret = SetEvent(args.past_free); + ok(ret, "Failed to signal event: %ld\n", GetLastError()); + + if (beginthread_method == use_beginthreadex) + { + ret = WaitForSingleObject((HANDLE)thread_handle, 200); + ok(ret == WAIT_OBJECT_0, "Thread has not exited, ret: %ld, err: %lu\n", ret, GetLastError()); + } + + ret = WaitForSingleObject(detach_event, 200); + ok(ret == WAIT_OBJECT_0, "Detach event was not signaled, ret: %ld, err: %lu\n", ret, GetLastError()); + + if (beginthread_method == use_beginthreadex) + CloseHandle((HANDLE)thread_handle); + + CloseHandle(args.past_free); + CloseHandle(args.confirm_running); + CloseHandle(detach_event); +} + +static BOOL handler_called; + +void CDECL test_invalid_parameter_handler(const wchar_t *expression, + const wchar_t *function_name, + const wchar_t *file_name, + unsigned line_number, + uintptr_t reserved) +{ + handler_called = TRUE; +} + +static void test_thread_invalid_params(void) +{ + uintptr_t hThread; + _invalid_parameter_handler old = _set_invalid_parameter_handler(test_invalid_parameter_handler); + + errno = 0; + handler_called = FALSE; + hThread = _beginthreadex(NULL, 0, NULL, NULL, 0, NULL); + ok(hThread == 0, "_beginthreadex unexpected ret: %Iu\n", hThread); + ok(errno == EINVAL, "_beginthreadex unexpected errno: %d\n", errno); + ok(handler_called, "Expected invalid_parameter_handler to be called\n"); + + errno = 0; + handler_called = FALSE; + hThread = _beginthread(NULL, 0, NULL); + ok(hThread == -1, "_beginthread unexpected ret: %Iu\n", hThread); + ok(errno == EINVAL, "_beginthread unexpected errno: %d\n", errno); + ok(handler_called, "Expected invalid_parameter_handler to be called\n"); + + _set_invalid_parameter_handler(old); +} + +START_TEST(thread) +{ + BOOL ret; + char *thread_dll = get_thread_dll_path(); + + test_thread_library_reference(thread_dll, use_beginthread, thread_exit_return); + test_thread_library_reference(thread_dll, use_beginthread, thread_exit_endthread); + test_thread_library_reference(thread_dll, use_beginthreadex, thread_exit_return); + test_thread_library_reference(thread_dll, use_beginthreadex, thread_exit_endthreadex); + + ret = DeleteFileA(thread_dll); + ok(ret, "Failed to remove the test dll, err: %lu\n", GetLastError()); + + test_thread_invalid_params(); +} diff --git a/modules/rostests/winetests/ucrtbase/threaddll.c b/modules/rostests/winetests/ucrtbase/threaddll.c new file mode 100644 index 0000000000000..387a00bff03c4 --- /dev/null +++ b/modules/rostests/winetests/ucrtbase/threaddll.c @@ -0,0 +1,71 @@ +/* + * Copyright 2021 Arkadiusz Hiler 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 + */ + +#if 0 +#pragma makedep testdll +#endif + +#include + +#include "threaddll.h" + +static HANDLE detach_event; + +void CDECL _endthread(void); +void CDECL _endthreadex(unsigned int); + +void WINAPI set_detach_event(HANDLE event) +{ + detach_event = event; +} + +static unsigned internal_thread_proc(void *param) +{ + struct threaddll_args *args = param; + SetEvent(args->confirm_running); + WaitForSingleObject(args->past_free, INFINITE); + + if (args->exit_method == thread_exit_endthread) + _endthread(); + else if (args->exit_method == thread_exit_endthreadex) + _endthreadex(0); + + return 0; +} + +unsigned WINAPI stdcall_thread_proc(void *param) +{ + return internal_thread_proc(param); +} + +void CDECL cdecl_thread_proc(void *param) +{ + internal_thread_proc(param); +} + +BOOL WINAPI DllMain(HINSTANCE instance_new, DWORD reason, LPVOID reserved) +{ + switch (reason) + { + case DLL_PROCESS_DETACH: + if (detach_event) SetEvent(detach_event); + break; + } + + return TRUE; +} diff --git a/modules/rostests/winetests/ucrtbase/threaddll.h b/modules/rostests/winetests/ucrtbase/threaddll.h new file mode 100644 index 0000000000000..1d8d085798feb --- /dev/null +++ b/modules/rostests/winetests/ucrtbase/threaddll.h @@ -0,0 +1,30 @@ +/* + * Copyright 2021 Arkadiusz Hiler 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 + */ + +enum thread_exit_method { + thread_exit_return, + thread_exit_endthread, + thread_exit_endthreadex +}; + +struct threaddll_args +{ + HANDLE confirm_running; + HANDLE past_free; + enum thread_exit_method exit_method; +}; diff --git a/modules/rostests/winetests/ucrtbase/threaddll.spec b/modules/rostests/winetests/ucrtbase/threaddll.spec new file mode 100644 index 0000000000000..8422c0969464b --- /dev/null +++ b/modules/rostests/winetests/ucrtbase/threaddll.spec @@ -0,0 +1,3 @@ +@ stdcall set_detach_event(ptr) +@ stdcall stdcall_thread_proc(ptr) +@ cdecl cdecl_thread_proc(ptr) diff --git a/modules/rostests/winetests/ucrtbase/ucrtbase_winetest.rc b/modules/rostests/winetests/ucrtbase/ucrtbase_winetest.rc new file mode 100644 index 0000000000000..38f463078d89d --- /dev/null +++ b/modules/rostests/winetests/ucrtbase/ucrtbase_winetest.rc @@ -0,0 +1,2 @@ + +threaddll.dll TESTDLL "threaddll.dll" diff --git a/modules/rostests/winetests/windowscodecs/CMakeLists.txt b/modules/rostests/winetests/windowscodecs/CMakeLists.txt index 418181b1b2376..d1aa7bfba1647 100644 --- a/modules/rostests/winetests/windowscodecs/CMakeLists.txt +++ b/modules/rostests/winetests/windowscodecs/CMakeLists.txt @@ -3,10 +3,13 @@ add_definitions( -DUSE_WINE_TODOS -DWINETEST_USE_DBGSTR_LONGLONG) +remove_definitions(-D__ROS_LONG64__) + list(APPEND SOURCE bitmap.c bmpformat.c converter.c + ddsformat.c gifformat.c icoformat.c info.c @@ -16,7 +19,8 @@ list(APPEND SOURCE pngformat.c propertybag.c stream.c - tiffformat.c) + tiffformat.c + wmpformat.c) list(APPEND PCH_SKIP_SOURCE guid.c @@ -33,5 +37,7 @@ if(MSVC) add_importlibs(windowscodecs_winetest ntdll) endif() +target_link_libraries(windowscodecs_winetest uuid) + add_pch(windowscodecs_winetest precomp.h "${PCH_SKIP_SOURCE}") add_rostests_file(TARGET windowscodecs_winetest) diff --git a/modules/rostests/winetests/windowscodecs/bitmap.c b/modules/rostests/winetests/windowscodecs/bitmap.c index 6cb0c5665c219..78725fed646e8 100644 --- a/modules/rostests/winetests/windowscodecs/bitmap.c +++ b/modules/rostests/winetests/windowscodecs/bitmap.c @@ -31,13 +31,24 @@ #include "wine/test.h" #include "initguid.h" -DEFINE_GUID(IID_IMILUnknown,0x0ccd7824,0xdc16,0x4d09,0xbc,0xa8,0x6b,0x09,0xc4,0xef,0x55,0x35); +DEFINE_GUID(IID_CMetaBitmapRenderTarget, 0x0ccd7824,0xdc16,0x4d09,0xbc,0xa8,0x6b,0x09,0xc4,0xef,0x55,0x35); + +#ifndef IID_IMILBitmap +#include DEFINE_GUID(IID_IMILBitmap,0xb1784d3f,0x8115,0x4763,0x13,0xaa,0x32,0xed,0xdb,0x68,0x29,0x4a); DEFINE_GUID(IID_IMILBitmapSource,0x7543696a,0xbc8d,0x46b0,0x5f,0x81,0x8d,0x95,0x72,0x89,0x72,0xbe); DEFINE_GUID(IID_IMILBitmapLock,0xa67b2b53,0x8fa1,0x4155,0x8f,0x64,0x0c,0x24,0x7a,0x8f,0x84,0xcd); DEFINE_GUID(IID_IMILBitmapScaler,0xa767b0f0,0x1c8c,0x4aef,0x56,0x8f,0xad,0xf9,0x6d,0xcf,0xd5,0xcb); DEFINE_GUID(IID_IMILFormatConverter,0x7e2a746f,0x25c5,0x4851,0xb3,0xaf,0x44,0x3b,0x79,0x63,0x9e,0xc0); DEFINE_GUID(IID_IMILPalette,0xca8e206f,0xf22c,0x4af7,0x6f,0xba,0x7b,0xed,0x5e,0xb1,0xc9,0x2f); +#else +extern IID IID_IMILBitmap; +extern IID IID_IMILBitmapSource; +extern IID IID_IMILBitmapLock; +extern IID IID_IMILBitmapScaler; +extern IID IID_IMILFormatConverter; +extern IID IID_IMILPalette; +#endif #undef INTERFACE #define INTERFACE IMILBitmapSource @@ -206,8 +217,8 @@ static HBITMAP create_dib(int width, int height, int bpp, LOGPALETTE *pal, const ok(hdib != 0, "CreateDIBSection(%dx%d,%d bpp) failed\n", width, height, bpp); GetObjectW(hdib, sizeof(bm), &bm); - ok(bm.bmWidth == width, "expected %d, got %d\n", width, bm.bmWidth); - ok(bm.bmHeight == height, "expected %d, got %d\n", height, bm.bmHeight); + ok(bm.bmWidth == width, "expected %d, got %ld\n", width, bm.bmWidth); + ok(bm.bmHeight == height, "expected %d, got %ld\n", height, bm.bmHeight); ok(bm.bmPlanes == 1, "expected 1, got %d\n", bm.bmPlanes); ok(bm.bmBitsPixel == bpp, "expected %d, got %d\n", bpp, bm.bmBitsPixel); @@ -240,32 +251,32 @@ static void test_createbitmap(void) hr = IWICImagingFactory_CreateBitmap(factory, 3, 3, &GUID_WICPixelFormat24bppBGR, WICBitmapCacheOnLoad, &bitmap); - ok(hr == S_OK, "IWICImagingFactory_CreateBitmap failed hr=%x\n", hr); + ok(hr == S_OK, "IWICImagingFactory_CreateBitmap failed hr=%lx\n", hr); if (FAILED(hr)) return; hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "IWICImagingFactory_CreatePalette failed hr=%x\n", hr); + ok(hr == S_OK, "IWICImagingFactory_CreatePalette failed hr=%lx\n", hr); /* Palette is unavailable until explicitly set */ hr = IWICBitmap_CopyPalette(bitmap, palette); - ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "IWICBitmap_CopyPalette failed hr=%x\n", hr); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "IWICBitmap_CopyPalette failed hr=%lx\n", hr); hr = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeFixedGray256, FALSE); - ok(hr == S_OK, "IWICPalette_InitializePredefined failed hr=%x\n", hr); + ok(hr == S_OK, "IWICPalette_InitializePredefined failed hr=%lx\n", hr); hr = IWICBitmap_SetPalette(bitmap, palette); - ok(hr == S_OK, "IWICBitmap_SetPalette failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_SetPalette failed hr=%lx\n", hr); hr = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeFixedGray4, FALSE); - ok(hr == S_OK, "IWICPalette_InitializePredefined failed hr=%x\n", hr); + ok(hr == S_OK, "IWICPalette_InitializePredefined failed hr=%lx\n", hr); hr = IWICBitmap_CopyPalette(bitmap, palette); - ok(hr == S_OK, "IWICBitmap_CopyPalette failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_CopyPalette failed hr=%lx\n", hr); hr = IWICPalette_GetType(palette, &palettetype); - ok(hr == S_OK, "IWICPalette_GetType failed hr=%x\n", hr); + ok(hr == S_OK, "IWICPalette_GetType failed hr=%lx\n", hr); ok(palettetype == WICBitmapPaletteTypeFixedGray256, "expected WICBitmapPaletteTypeFixedGray256, got %x\n", palettetype); @@ -273,7 +284,7 @@ static void test_createbitmap(void) /* pixel data is initially zeroed */ hr = IWICBitmap_CopyPixels(bitmap, NULL, 9, 27, returned_data); - ok(hr == S_OK, "IWICBitmap_CopyPixels failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_CopyPixels failed hr=%lx\n", hr); for (i=0; i<27; i++) ok(returned_data[i] == 0, "returned_data[%i] == %i\n", i, returned_data[i]); @@ -283,36 +294,36 @@ static void test_createbitmap(void) rc.Width = 4; rc.Height = 3; hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockRead, &lock); - ok(hr == E_INVALIDARG, "IWICBitmap_Lock failed hr=%x\n", hr); + ok(hr == E_INVALIDARG, "IWICBitmap_Lock failed hr=%lx\n", hr); if (SUCCEEDED(hr)) IWICBitmapLock_Release(lock); rc.Width = 3; rc.Height = 4; hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockRead, &lock); - ok(hr == E_INVALIDARG, "IWICBitmap_Lock failed hr=%x\n", hr); + ok(hr == E_INVALIDARG, "IWICBitmap_Lock failed hr=%lx\n", hr); if (SUCCEEDED(hr)) IWICBitmapLock_Release(lock); rc.Height = 3; rc.X = 4; hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockRead, &lock); - ok(hr == E_INVALIDARG, "IWICBitmap_Lock failed hr=%x\n", hr); + ok(hr == E_INVALIDARG, "IWICBitmap_Lock failed hr=%lx\n", hr); if (SUCCEEDED(hr)) IWICBitmapLock_Release(lock); rc.X = 0; rc.Y = 4; hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockRead, &lock); - ok(hr == E_INVALIDARG, "IWICBitmap_Lock failed hr=%x\n", hr); + ok(hr == E_INVALIDARG, "IWICBitmap_Lock failed hr=%lx\n", hr); if (SUCCEEDED(hr)) IWICBitmapLock_Release(lock); /* NULL lock rect */ hr = IWICBitmap_Lock(bitmap, NULL, WICBitmapLockRead, &lock); - ok(hr == S_OK || broken(hr == E_INVALIDARG) /* winxp */, "IWICBitmap_Lock failed hr=%x\n", hr); + ok(hr == S_OK || broken(hr == E_INVALIDARG) /* winxp */, "IWICBitmap_Lock failed hr=%lx\n", hr); if (SUCCEEDED(hr)) { /* entire bitmap is locked */ hr = IWICBitmapLock_GetSize(lock, &width, &height); - ok(hr == S_OK, "IWICBitmapLock_GetSize failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmapLock_GetSize failed hr=%lx\n", hr); ok(width == 3, "got %d, expected 3\n", width); ok(height == 3, "got %d, expected 3\n", height); @@ -324,38 +335,38 @@ static void test_createbitmap(void) /* lock with a valid rect */ rc.Y = 0; hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockRead, &lock); - ok(hr == S_OK, "IWICBitmap_Lock failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_Lock failed hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapLock_GetStride(lock, &lock_buffer_stride); - ok(hr == S_OK, "IWICBitmapLock_GetStride failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmapLock_GetStride failed hr=%lx\n", hr); /* stride is divisible by 4 */ ok(lock_buffer_stride == 12, "got %i, expected 12\n", lock_buffer_stride); hr = IWICBitmapLock_GetDataPointer(lock, &lock_buffer_size, &lock_buffer); - ok(hr == S_OK, "IWICBitmapLock_GetDataPointer failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmapLock_GetDataPointer failed hr=%lx\n", hr); /* buffer size does not include padding from the last row */ ok(lock_buffer_size == 33, "got %i, expected 33\n", lock_buffer_size); ok(lock_buffer != NULL, "got NULL data pointer\n"); base_lock_buffer = lock_buffer; hr = IWICBitmapLock_GetPixelFormat(lock, &pixelformat); - ok(hr == S_OK, "IWICBitmapLock_GetPixelFormat failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmapLock_GetPixelFormat failed hr=%lx\n", hr); ok(IsEqualGUID(&pixelformat, &GUID_WICPixelFormat24bppBGR), "unexpected pixel format\n"); hr = IWICBitmapLock_GetSize(lock, &width, &height); - ok(hr == S_OK, "IWICBitmapLock_GetSize failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmapLock_GetSize failed hr=%lx\n", hr); ok(width == 3, "got %d, expected 3\n", width); ok(height == 3, "got %d, expected 3\n", height); /* We can have multiple simultaneous read locks */ hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockRead, &lock2); - ok(hr == S_OK, "IWICBitmap_Lock failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_Lock failed hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapLock_GetDataPointer(lock2, &lock_buffer_size, &lock_buffer); - ok(hr == S_OK, "IWICBitmapLock_GetDataPointer failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmapLock_GetDataPointer failed hr=%lx\n", hr); ok(lock_buffer_size == 33, "got %i, expected 33\n", lock_buffer_size); ok(lock_buffer == base_lock_buffer, "got %p, expected %p\n", lock_buffer, base_lock_buffer); @@ -366,7 +377,7 @@ static void test_createbitmap(void) { /* But not a read and a write lock */ hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockWrite, &lock2); - ok(hr == WINCODEC_ERR_ALREADYLOCKED, "IWICBitmap_Lock failed hr=%x\n", hr); + ok(hr == WINCODEC_ERR_ALREADYLOCKED, "IWICBitmap_Lock failed hr=%lx\n", hr); } /* But we don't need a write lock to write */ @@ -381,7 +392,7 @@ static void test_createbitmap(void) /* test that the data we wrote is returned by CopyPixels */ hr = IWICBitmap_CopyPixels(bitmap, NULL, 9, 27, returned_data); - ok(hr == S_OK, "IWICBitmap_CopyPixels failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_CopyPixels failed hr=%lx\n", hr); for (i=0; i<27; i++) ok(returned_data[i] == bitmap_data[i], "returned_data[%i] == %i\n", i, returned_data[i]); @@ -392,7 +403,7 @@ static void test_createbitmap(void) rc.Width = 1; rc.Height = 2; hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockWrite, &lock); - ok(hr == S_OK, "IWICBitmap_Lock failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_Lock failed hr=%lx\n", hr); if (SUCCEEDED(hr)) { @@ -400,27 +411,27 @@ static void test_createbitmap(void) { /* Can't lock again while locked for writing */ hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockWrite, &lock2); - ok(hr == WINCODEC_ERR_ALREADYLOCKED, "IWICBitmap_Lock failed hr=%x\n", hr); + ok(hr == WINCODEC_ERR_ALREADYLOCKED, "IWICBitmap_Lock failed hr=%lx\n", hr); hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockRead, &lock2); - ok(hr == WINCODEC_ERR_ALREADYLOCKED, "IWICBitmap_Lock failed hr=%x\n", hr); + ok(hr == WINCODEC_ERR_ALREADYLOCKED, "IWICBitmap_Lock failed hr=%lx\n", hr); } hr = IWICBitmapLock_GetStride(lock, &lock_buffer_stride); - ok(hr == S_OK, "IWICBitmapLock_GetStride failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmapLock_GetStride failed hr=%lx\n", hr); ok(lock_buffer_stride == 12, "got %i, expected 12\n", lock_buffer_stride); hr = IWICBitmapLock_GetDataPointer(lock, &lock_buffer_size, &lock_buffer); - ok(hr == S_OK, "IWICBitmapLock_GetDataPointer failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmapLock_GetDataPointer failed hr=%lx\n", hr); ok(lock_buffer_size == 15, "got %i, expected 15\n", lock_buffer_size); ok(lock_buffer == base_lock_buffer+6, "got %p, expected %p+6\n", lock_buffer, base_lock_buffer); hr = IWICBitmapLock_GetPixelFormat(lock, &pixelformat); - ok(hr == S_OK, "IWICBitmapLock_GetPixelFormat failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmapLock_GetPixelFormat failed hr=%lx\n", hr); ok(IsEqualGUID(&pixelformat, &GUID_WICPixelFormat24bppBGR), "unexpected pixel format\n"); hr = IWICBitmapLock_GetSize(lock, &width, &height); - ok(hr == S_OK, "IWICBitmapLock_GetSize failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmapLock_GetSize failed hr=%lx\n", hr); ok(width == 1, "got %d, expected 1\n", width); ok(height == 2, "got %d, expected 2\n", height); @@ -428,24 +439,24 @@ static void test_createbitmap(void) } hr = IWICBitmap_GetPixelFormat(bitmap, &pixelformat); - ok(hr == S_OK, "IWICBitmap_GetPixelFormat failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_GetPixelFormat failed hr=%lx\n", hr); ok(IsEqualGUID(&pixelformat, &GUID_WICPixelFormat24bppBGR), "unexpected pixel format\n"); hr = IWICBitmap_GetResolution(bitmap, &dpix, &dpiy); - ok(hr == S_OK, "IWICBitmap_GetResolution failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_GetResolution failed hr=%lx\n", hr); ok(dpix == 0.0, "got %f, expected 0.0\n", dpix); ok(dpiy == 0.0, "got %f, expected 0.0\n", dpiy); hr = IWICBitmap_SetResolution(bitmap, 12.0, 34.0); - ok(hr == S_OK, "IWICBitmap_SetResolution failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_SetResolution failed hr=%lx\n", hr); hr = IWICBitmap_GetResolution(bitmap, &dpix, &dpiy); - ok(hr == S_OK, "IWICBitmap_GetResolution failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_GetResolution failed hr=%lx\n", hr); ok(dpix == 12.0, "got %f, expected 12.0\n", dpix); ok(dpiy == 34.0, "got %f, expected 34.0\n", dpiy); hr = IWICBitmap_GetSize(bitmap, &width, &height); - ok(hr == S_OK, "IWICBitmap_GetSize failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_GetSize failed hr=%lx\n", hr); ok(width == 3, "got %d, expected 3\n", width); ok(height == 3, "got %d, expected 3\n", height); @@ -476,19 +487,19 @@ static void test_createbitmapfromsource(void) hr = IWICImagingFactory_CreateBitmap(factory, 3, 3, &GUID_WICPixelFormat24bppBGR, WICBitmapCacheOnLoad, &bitmap); - ok(hr == S_OK, "IWICImagingFactory_CreateBitmap failed hr=%x\n", hr); + ok(hr == S_OK, "IWICImagingFactory_CreateBitmap failed hr=%lx\n", hr); if (FAILED(hr)) return; hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "IWICImagingFactory_CreatePalette failed hr=%x\n", hr); + ok(hr == S_OK, "IWICImagingFactory_CreatePalette failed hr=%lx\n", hr); hr = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeFixedGray256, FALSE); - ok(hr == S_OK, "IWICPalette_InitializePredefined failed hr=%x\n", hr); + ok(hr == S_OK, "IWICPalette_InitializePredefined failed hr=%lx\n", hr); hr = IWICBitmap_SetPalette(bitmap, palette); - ok(hr == S_OK, "IWICBitmap_SetPalette failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_SetPalette failed hr=%lx\n", hr); IWICPalette_Release(palette); @@ -496,15 +507,15 @@ static void test_createbitmapfromsource(void) rc.Width = 3; rc.Height = 3; hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockWrite, &lock); - ok(hr == S_OK, "IWICBitmap_Lock failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_Lock failed hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapLock_GetStride(lock, &lock_buffer_stride); - ok(hr == S_OK, "IWICBitmapLock_GetStride failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmapLock_GetStride failed hr=%lx\n", hr); ok(lock_buffer_stride == 12, "got %i, expected 12\n", lock_buffer_stride); hr = IWICBitmapLock_GetDataPointer(lock, &lock_buffer_size, &lock_buffer); - ok(hr == S_OK, "IWICBitmapLock_GetDataPointer failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmapLock_GetDataPointer failed hr=%lx\n", hr); ok(lock_buffer_size == 33, "got %i, expected 33\n", lock_buffer_size); ok(lock_buffer != NULL, "got NULL data pointer\n"); @@ -515,55 +526,55 @@ static void test_createbitmapfromsource(void) } hr = IWICBitmap_SetResolution(bitmap, 12.0, 34.0); - ok(hr == S_OK, "IWICBitmap_SetResolution failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_SetResolution failed hr=%lx\n", hr); /* WICBitmapNoCache */ hr = IWICImagingFactory_CreateBitmapFromSource(factory, (IWICBitmapSource *)bitmap, WICBitmapNoCache, &bitmap2); - ok(hr == S_OK, "IWICImagingFactory_CreateBitmapFromSource failed hr=%x\n", hr); + ok(hr == S_OK, "IWICImagingFactory_CreateBitmapFromSource failed hr=%lx\n", hr); ok(bitmap2 == bitmap, "Unexpected bitmap instance.\n"); IWICBitmap_Release(bitmap2); bitmap2 = (void *)0xdeadbeef; hr = IWICImagingFactory_CreateBitmapFromSource(factory, &bitmapsource, WICBitmapNoCache, &bitmap2); - ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr); ok(bitmap2 == (void *)0xdeadbeef, "Unexpected pointer %p.\n", bitmap2); hr = IWICImagingFactory_CreateBitmapFromSource(factory, (IWICBitmapSource*)bitmap, WICBitmapCacheOnLoad, &bitmap2); - ok(hr == S_OK, "IWICImagingFactory_CreateBitmapFromSource failed hr=%x\n", hr); + ok(hr == S_OK, "IWICImagingFactory_CreateBitmapFromSource failed hr=%lx\n", hr); IWICBitmap_Release(bitmap); if (FAILED(hr)) return; hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "IWICImagingFactory_CreatePalette failed hr=%x\n", hr); + ok(hr == S_OK, "IWICImagingFactory_CreatePalette failed hr=%lx\n", hr); /* palette isn't copied for non-indexed formats? */ hr = IWICBitmap_CopyPalette(bitmap2, palette); - ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "IWICBitmap_CopyPalette failed hr=%x\n", hr); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "IWICBitmap_CopyPalette failed hr=%lx\n", hr); IWICPalette_Release(palette); hr = IWICBitmap_CopyPixels(bitmap2, NULL, 9, 27, returned_data); - ok(hr == S_OK, "IWICBitmap_CopyPixels failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_CopyPixels failed hr=%lx\n", hr); for (i=0; i<27; i++) ok(returned_data[i] == bitmap_data[i], "returned_data[%i] == %i\n", i, returned_data[i]); hr = IWICBitmap_GetPixelFormat(bitmap2, &pixelformat); - ok(hr == S_OK, "IWICBitmap_GetPixelFormat failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_GetPixelFormat failed hr=%lx\n", hr); ok(IsEqualGUID(&pixelformat, &GUID_WICPixelFormat24bppBGR), "unexpected pixel format\n"); hr = IWICBitmap_GetResolution(bitmap2, &dpix, &dpiy); - ok(hr == S_OK, "IWICBitmap_GetResolution failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_GetResolution failed hr=%lx\n", hr); ok(dpix == 12.0, "got %f, expected 12.0\n", dpix); ok(dpiy == 34.0, "got %f, expected 34.0\n", dpiy); hr = IWICBitmap_GetSize(bitmap2, &width, &height); - ok(hr == S_OK, "IWICBitmap_GetSize failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_GetSize failed hr=%lx\n", hr); ok(width == 3, "got %d, expected 3\n", width); ok(height == 3, "got %d, expected 3\n", height); @@ -572,86 +583,86 @@ static void test_createbitmapfromsource(void) /* Ensure palette is copied for indexed formats */ hr = IWICImagingFactory_CreateBitmap(factory, 3, 3, &GUID_WICPixelFormat4bppIndexed, WICBitmapCacheOnLoad, &bitmap); - ok(hr == S_OK, "IWICImagingFactory_CreateBitmap failed hr=%x\n", hr); + ok(hr == S_OK, "IWICImagingFactory_CreateBitmap failed hr=%lx\n", hr); hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "IWICImagingFactory_CreatePalette failed hr=%x\n", hr); + ok(hr == S_OK, "IWICImagingFactory_CreatePalette failed hr=%lx\n", hr); hr = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeFixedGray256, FALSE); - ok(hr == S_OK, "IWICPalette_InitializePredefined failed hr=%x\n", hr); + ok(hr == S_OK, "IWICPalette_InitializePredefined failed hr=%lx\n", hr); hr = IWICBitmap_SetPalette(bitmap, palette); - ok(hr == S_OK, "IWICBitmap_SetPalette failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_SetPalette failed hr=%lx\n", hr); IWICPalette_Release(palette); hr = IWICImagingFactory_CreateBitmapFromSource(factory, (IWICBitmapSource*)bitmap, WICBitmapCacheOnLoad, &bitmap2); - ok(hr == S_OK, "IWICImagingFactory_CreateBitmapFromSource failed hr=%x\n", hr); + ok(hr == S_OK, "IWICImagingFactory_CreateBitmapFromSource failed hr=%lx\n", hr); IWICBitmap_Release(bitmap); hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "IWICImagingFactory_CreatePalette failed hr=%x\n", hr); + ok(hr == S_OK, "IWICImagingFactory_CreatePalette failed hr=%lx\n", hr); hr = IWICBitmap_CopyPalette(bitmap2, palette); - ok(hr == S_OK, "IWICBitmap_CopyPalette failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_CopyPalette failed hr=%lx\n", hr); hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "IWICPalette_GetColorCount failed hr=%x\n", hr); + ok(hr == S_OK, "IWICPalette_GetColorCount failed hr=%lx\n", hr); ok(count == 256, "unexpected count %d\n", count); hr = IWICPalette_GetType(palette, &palette_type); - ok(hr == S_OK, "IWICPalette_GetType failed hr=%x\n", hr); + ok(hr == S_OK, "IWICPalette_GetType failed hr=%lx\n", hr); ok(palette_type == WICBitmapPaletteTypeFixedGray256, "unexpected palette type %d\n", palette_type); IWICPalette_Release(palette); hr = IWICBitmap_GetPixelFormat(bitmap2, &pixelformat); - ok(hr == S_OK, "IWICBitmap_GetPixelFormat failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_GetPixelFormat failed hr=%lx\n", hr); ok(IsEqualGUID(&pixelformat, &GUID_WICPixelFormat4bppIndexed), "unexpected pixel format\n"); hr = IWICBitmap_GetSize(bitmap2, &width, &height); - ok(hr == S_OK, "IWICBitmap_GetSize failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_GetSize failed hr=%lx\n", hr); ok(width == 3, "got %d, expected 3\n", width); ok(height == 3, "got %d, expected 3\n", height); /* CreateBitmapFromSourceRect */ hr = IWICImagingFactory_CreateBitmapFromSourceRect(factory, (IWICBitmapSource *)bitmap2, 0, 0, 16, 32, &bitmap); - ok(hr == S_OK, "Failed to create a bitmap, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to create a bitmap, hr %#lx.\n", hr); hr = IWICBitmap_GetSize(bitmap, &width, &height); - ok(hr == S_OK, "Failed to get bitmap size, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to get bitmap size, hr %#lx.\n", hr); ok(width == 3, "Unexpected width %u.\n", width); ok(height == 3, "Unexpected height %u.\n", height); IWICBitmap_Release(bitmap); hr = IWICImagingFactory_CreateBitmapFromSourceRect(factory, (IWICBitmapSource *)bitmap2, 0, 0, 1, 1, &bitmap); - ok(hr == S_OK, "Failed to create a bitmap, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to create a bitmap, hr %#lx.\n", hr); hr = IWICBitmap_GetSize(bitmap, &width, &height); - ok(hr == S_OK, "Failed to get bitmap size, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to get bitmap size, hr %#lx.\n", hr); ok(width == 1, "Unexpected width %u.\n", width); ok(height == 1, "Unexpected height %u.\n", height); IWICBitmap_Release(bitmap); hr = IWICImagingFactory_CreateBitmapFromSourceRect(factory, (IWICBitmapSource *)bitmap2, 2, 1, 16, 32, &bitmap); - ok(hr == S_OK, "Failed to create a bitmap, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to create a bitmap, hr %#lx.\n", hr); hr = IWICBitmap_GetSize(bitmap, &width, &height); - ok(hr == S_OK, "Failed to get bitmap size, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to get bitmap size, hr %#lx.\n", hr); ok(width == 1, "Unexpected width %u.\n", width); ok(height == 2, "Unexpected height %u.\n", height); IWICBitmap_Release(bitmap); hr = IWICImagingFactory_CreateBitmapFromSourceRect(factory, (IWICBitmapSource *)bitmap2, 0, 0, 0, 2, &bitmap); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); hr = IWICImagingFactory_CreateBitmapFromSourceRect(factory, (IWICBitmapSource *)bitmap2, 0, 0, 2, 0, &bitmap); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); hr = IWICImagingFactory_CreateBitmapFromSourceRect(factory, (IWICBitmapSource *)bitmap2, 1, 3, 16, 32, &bitmap); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); hr = IWICImagingFactory_CreateBitmapFromSourceRect(factory, (IWICBitmapSource *)bitmap2, 3, 1, 16, 32, &bitmap); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); IWICBitmap_Release(bitmap2); } @@ -676,30 +687,30 @@ static void test_CreateBitmapFromMemory(void) hr = IWICImagingFactory_CreateBitmapFromMemory(factory, 3, 3, &GUID_WICPixelFormat24bppBGR, 0, 0, NULL, &bitmap); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICImagingFactory_CreateBitmapFromMemory(factory, 3, 3, &GUID_WICPixelFormat24bppBGR, 0, sizeof(data3x3), data3x3, &bitmap); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICImagingFactory_CreateBitmapFromMemory(factory, 3, 3, &GUID_WICPixelFormat24bppBGR, 6, sizeof(data3x3), data3x3, &bitmap); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICImagingFactory_CreateBitmapFromMemory(factory, 3, 3, &GUID_WICPixelFormat24bppBGR, 12, sizeof(data3x3), data3x3, &bitmap); - ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "expected WINCODEC_ERR_INSUFFICIENTBUFFER, got %#x\n", hr); + ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "expected WINCODEC_ERR_INSUFFICIENTBUFFER, got %#lx\n", hr); hr = IWICImagingFactory_CreateBitmapFromMemory(factory, 3, 3, &GUID_WICPixelFormat24bppBGR, 9, sizeof(data3x3) - 1, data3x3, &bitmap); - ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "expected WINCODEC_ERR_INSUFFICIENTBUFFER, got %#x\n", hr); + ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "expected WINCODEC_ERR_INSUFFICIENTBUFFER, got %#lx\n", hr); hr = IWICImagingFactory_CreateBitmapFromMemory(factory, 3, 3, &GUID_WICPixelFormat24bppBGR, 9, sizeof(data3x3), data3x3, &bitmap); - ok(hr == S_OK, "IWICImagingFactory_CreateBitmapFromMemory error %#x\n", hr); + ok(hr == S_OK, "IWICImagingFactory_CreateBitmapFromMemory error %#lx\n", hr); hr = IWICBitmap_GetSize(bitmap, &width, &height); - ok(hr == S_OK, "IWICBitmap_GetSize error %#x\n", hr); + ok(hr == S_OK, "IWICBitmap_GetSize error %#lx\n", hr); ok(width == 3, "expected 3, got %u\n", width); ok(height == 3, "expected 3, got %u\n", height); @@ -707,7 +718,7 @@ static void test_CreateBitmapFromMemory(void) memset(data, 0, sizeof(data)); hr = IWICBitmap_CopyPixels(bitmap, NULL, 9, sizeof(data), data); - ok(hr == S_OK, "IWICBitmap_CopyPixels error %#x\n", hr); + ok(hr == S_OK, "IWICBitmap_CopyPixels error %#lx\n", hr); for (i = 0; i < sizeof(data); i++) ok(data[i] == orig_data3x3[i], "%u: expected %u, got %u\n", i, data[i], data3x3[i]); @@ -715,16 +726,16 @@ static void test_CreateBitmapFromMemory(void) hr = IWICImagingFactory_CreateBitmapFromMemory(factory, 3, 2, &GUID_WICPixelFormat24bppBGR, 13, sizeof(orig_data3x3), orig_data3x3, &bitmap); - ok(hr == S_OK, "IWICImagingFactory_CreateBitmapFromMemory error %#x\n", hr); + ok(hr == S_OK, "IWICImagingFactory_CreateBitmapFromMemory error %#lx\n", hr); hr = IWICBitmap_GetSize(bitmap, &width, &height); - ok(hr == S_OK, "IWICBitmap_GetSize error %#x\n", hr); + ok(hr == S_OK, "IWICBitmap_GetSize error %#lx\n", hr); ok(width == 3, "expected 3, got %u\n", width); ok(height == 2, "expected 2, got %u\n", height); memset(data, 0, sizeof(data)); hr = IWICBitmap_CopyPixels(bitmap, NULL, 13, sizeof(data), data); - ok(hr == S_OK, "IWICBitmap_CopyPixels error %#x\n", hr); + ok(hr == S_OK, "IWICBitmap_CopyPixels error %#lx\n", hr); for (i = 0; i < sizeof(data); i++) ok(data[i] == data3x2[i], "%u: expected %u, got %u\n", i, data3x2[i], data[i]); @@ -753,16 +764,16 @@ static void test_CreateBitmapFromHICON(void) DeleteObject(info.hbmMask); hr = IWICImagingFactory_CreateBitmapFromHICON(factory, 0, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICImagingFactory_CreateBitmapFromHICON(factory, 0, &bitmap); - ok(hr == HRESULT_FROM_WIN32(ERROR_INVALID_CURSOR_HANDLE), "expected ERROR_INVALID_CURSOR_HANDLE, got %#x\n", hr); + ok(hr == HRESULT_FROM_WIN32(ERROR_INVALID_CURSOR_HANDLE), "expected ERROR_INVALID_CURSOR_HANDLE, got %#lx\n", hr); hr = IWICImagingFactory_CreateBitmapFromHICON(factory, icon, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICImagingFactory_CreateBitmapFromHICON(factory, icon, &bitmap); - ok(hr == S_OK, "CreateBitmapFromHICON error %#x\n", hr); + ok(hr == S_OK, "CreateBitmapFromHICON error %#lx\n", hr); DestroyIcon(icon); if (hr != S_OK) return; @@ -771,7 +782,7 @@ static void test_CreateBitmapFromHICON(void) "unexpected pixel format %s\n", wine_dbgstr_guid(&format)); hr = IWICBitmap_GetSize(bitmap, &width, &height); - ok(hr == S_OK, "IWICBitmap_GetSize error %#x\n", hr); + ok(hr == S_OK, "IWICBitmap_GetSize error %#lx\n", hr); ok(width == 16, "expected 16, got %u\n", width); ok(height == 16, "expected 16, got %u\n", height); @@ -791,7 +802,7 @@ static void test_CreateBitmapFromHICON(void) DeleteObject(info.hbmMask); hr = IWICImagingFactory_CreateBitmapFromHICON(factory, icon, &bitmap); - ok(hr == S_OK, "CreateBitmapFromHICON error %#x\n", hr); + ok(hr == S_OK, "CreateBitmapFromHICON error %#lx\n", hr); DestroyIcon(icon); IWICBitmap_GetPixelFormat(bitmap, &format); @@ -799,7 +810,7 @@ static void test_CreateBitmapFromHICON(void) "unexpected pixel format %s\n", wine_dbgstr_guid(&format)); hr = IWICBitmap_GetSize(bitmap, &width, &height); - ok(hr == S_OK, "IWICBitmap_GetSize error %#x\n", hr); + ok(hr == S_OK, "IWICBitmap_GetSize error %#lx\n", hr); ok(width == 16, "expected 16, got %u\n", width); ok(height == 16, "expected 16, got %u\n", height); @@ -830,26 +841,26 @@ static void test_CreateBitmapFromHBITMAP(void) ok(hbmp != 0, "failed to create bitmap\n"); hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, 0, 0, WICBitmapIgnoreAlpha, &bitmap); - ok(hr == WINCODEC_ERR_WIN32ERROR || hr == 0x88980003 /*XP*/, "expected WINCODEC_ERR_WIN32ERROR, got %#x\n", hr); + ok(hr == WINCODEC_ERR_WIN32ERROR || hr == 0x88980003 /*XP*/, "expected WINCODEC_ERR_WIN32ERROR, got %#lx\n", hr); hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, hbmp, 0, WICBitmapIgnoreAlpha, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, hbmp, 0, WICBitmapIgnoreAlpha, &bitmap); - ok(hr == S_OK, "CreateBitmapFromHBITMAP error %#x\n", hr); + ok(hr == S_OK, "CreateBitmapFromHBITMAP error %#lx\n", hr); IWICBitmap_GetPixelFormat(bitmap, &format); ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed), "unexpected pixel format %s\n", wine_dbgstr_guid(&format)); hr = IWICBitmap_GetSize(bitmap, &width, &height); - ok(hr == S_OK, "IWICBitmap_GetSize error %#x\n", hr); + ok(hr == S_OK, "IWICBitmap_GetSize error %#lx\n", hr); ok(width == 3, "expected 3, got %u\n", width); ok(height == 3, "expected 3, got %u\n", height); memset(data, 0, sizeof(data)); hr = IWICBitmap_CopyPixels(bitmap, NULL, 4, sizeof(data), data); - ok(hr == S_OK, "IWICBitmap_CopyPixels error %#x\n", hr); + ok(hr == S_OK, "IWICBitmap_CopyPixels error %#lx\n", hr); for (i = 0; i < sizeof(data); i++) ok(data[i] == data_8bpp_rgb_dib[i], "%u: expected %#x, got %#x\n", i, data_8bpp_rgb_dib[i], data[i]); @@ -866,30 +877,30 @@ static void test_CreateBitmapFromHBITMAP(void) hbmp = create_dib(3, 3, 8, pal, data_8bpp_pal_dib); hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, hbmp, hpal, WICBitmapIgnoreAlpha, &bitmap); - ok(hr == S_OK, "CreateBitmapFromHBITMAP error %#x\n", hr); + ok(hr == S_OK, "CreateBitmapFromHBITMAP error %#lx\n", hr); IWICBitmap_GetPixelFormat(bitmap, &format); -todo_wine + todo_wine ok(IsEqualGUID(&format, &GUID_WICPixelFormat4bppIndexed), "unexpected pixel format %s\n", wine_dbgstr_guid(&format)); hr = IWICBitmap_GetSize(bitmap, &width, &height); - ok(hr == S_OK, "IWICBitmap_GetSize error %#x\n", hr); + ok(hr == S_OK, "IWICBitmap_GetSize error %#lx\n", hr); ok(width == 3, "expected 3, got %u\n", width); ok(height == 3, "expected 3, got %u\n", height); hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "CreatePalette error %#x\n", hr); + ok(hr == S_OK, "CreatePalette error %#lx\n", hr); hr = IWICBitmap_CopyPalette(bitmap, palette); - ok(hr == S_OK, "CopyPalette error %#x\n", hr); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); hr = IWICPalette_GetType(palette, &type); - ok(hr == S_OK, "%u: GetType error %#x\n", i, hr); + ok(hr == S_OK, "%u: GetType error %#lx\n", i, hr); ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %#x\n", type); hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); -todo_wine + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); + todo_wine ok(count == 16, "expected 16, got %u\n", count); IWICPalette_Release(palette); @@ -908,35 +919,35 @@ todo_wine hbmp = create_dib(3, 3, 8, pal, data_8bpp_pal_dib); hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, hbmp, hpal, WICBitmapIgnoreAlpha, &bitmap); - ok(hr == S_OK, "CreateBitmapFromHBITMAP error %#x\n", hr); + ok(hr == S_OK, "CreateBitmapFromHBITMAP error %#lx\n", hr); IWICBitmap_GetPixelFormat(bitmap, &format); ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed), "unexpected pixel format %s\n", wine_dbgstr_guid(&format)); hr = IWICBitmap_GetSize(bitmap, &width, &height); - ok(hr == S_OK, "IWICBitmap_GetSize error %#x\n", hr); + ok(hr == S_OK, "IWICBitmap_GetSize error %#lx\n", hr); ok(width == 3, "expected 3, got %u\n", width); ok(height == 3, "expected 3, got %u\n", height); hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "CreatePalette error %#x\n", hr); + ok(hr == S_OK, "CreatePalette error %#lx\n", hr); hr = IWICBitmap_CopyPalette(bitmap, palette); - ok(hr == S_OK, "CopyPalette error %#x\n", hr); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); hr = IWICPalette_GetType(palette, &type); - ok(hr == S_OK, "%u: GetType error %#x\n", i, hr); + ok(hr == S_OK, "%u: GetType error %#lx\n", i, hr); ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %#x\n", type); hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 256, "expected 256, got %u\n", count); IWICPalette_Release(palette); memset(data, 0, sizeof(data)); hr = IWICBitmap_CopyPixels(bitmap, NULL, 4, sizeof(data), data); - ok(hr == S_OK, "IWICBitmap_CopyPixels error %#x\n", hr); + ok(hr == S_OK, "IWICBitmap_CopyPixels error %#lx\n", hr); for (i = 0; i < sizeof(data); i++) todo_wine_if (data[i] != data_8bpp_pal_wic[i]) ok(data[i] == data_8bpp_pal_wic[i], "%u: expected %#x, got %#x\n", i, data_8bpp_pal_wic[i], data[i]); @@ -948,10 +959,10 @@ todo_wine /* 32bpp alpha */ hbmp = create_dib(2, 2, 32, NULL, NULL); hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, hbmp, NULL, WICBitmapUseAlpha, &bitmap); - ok(hr == S_OK, "CreateBitmapFromHBITMAP error %#x\n", hr); + ok(hr == S_OK, "CreateBitmapFromHBITMAP error %#lx\n", hr); hr = IWICBitmap_GetPixelFormat(bitmap, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_WICPixelFormat32bppBGRA), "unexpected pixel format %s\n", wine_dbgstr_guid(&format)); @@ -959,10 +970,10 @@ todo_wine /* 32bpp pre-multiplied alpha */ hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, hbmp, NULL, WICBitmapUsePremultipliedAlpha, &bitmap); - ok(hr == S_OK, "CreateBitmapFromHBITMAP error %#x\n", hr); + ok(hr == S_OK, "CreateBitmapFromHBITMAP error %#lx\n", hr); hr = IWICBitmap_GetPixelFormat(bitmap, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_WICPixelFormat32bppPBGRA), "unexpected pixel format %s\n", wine_dbgstr_guid(&format)); @@ -970,10 +981,10 @@ todo_wine /* 32bpp no alpha */ hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, hbmp, NULL, WICBitmapIgnoreAlpha, &bitmap); - ok(hr == S_OK, "CreateBitmapFromHBITMAP error %#x\n", hr); + ok(hr == S_OK, "CreateBitmapFromHBITMAP error %#lx\n", hr); hr = IWICBitmap_GetPixelFormat(bitmap, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_WICPixelFormat32bppBGR), "unexpected pixel format %s\n", wine_dbgstr_guid(&format)); @@ -992,29 +1003,29 @@ static void test_clipper(void) hr = IWICImagingFactory_CreateBitmap(factory, 10, 10, &GUID_WICPixelFormat24bppBGR, WICBitmapCacheOnLoad, &bitmap); - ok(hr == S_OK, "got 0x%08x\n", hr); + ok(hr == S_OK, "got 0x%08lx\n", hr); hr = IWICImagingFactory_CreateBitmapClipper(factory, &clipper); - ok(hr == S_OK, "got 0x%08x\n", hr); + ok(hr == S_OK, "got 0x%08lx\n", hr); rect.X = rect.Y = 0; rect.Width = rect.Height = 11; hr = IWICBitmapClipper_Initialize(clipper, (IWICBitmapSource*)bitmap, &rect); - ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(hr == E_INVALIDARG, "got 0x%08lx\n", hr); rect.X = rect.Y = 5; rect.Width = rect.Height = 6; hr = IWICBitmapClipper_Initialize(clipper, (IWICBitmapSource*)bitmap, &rect); - ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(hr == E_INVALIDARG, "got 0x%08lx\n", hr); rect.X = rect.Y = 5; rect.Width = rect.Height = 5; hr = IWICBitmapClipper_Initialize(clipper, (IWICBitmapSource*)bitmap, &rect); - ok(hr == S_OK, "got 0x%08x\n", hr); + ok(hr == S_OK, "got 0x%08lx\n", hr); width = height = 0; hr = IWICBitmapClipper_GetSize(clipper, &width, &height); - ok(hr == S_OK, "got 0x%08x\n", hr); + ok(hr == S_OK, "got 0x%08lx\n", hr); ok(width == 5, "got %d\n", width); ok(height == 5, "got %d\n", height); @@ -1023,12 +1034,12 @@ static void test_clipper(void) /* CopyPixels */ hr = IWICImagingFactory_CreateBitmapClipper(factory, &clipper); - ok(hr == S_OK, "got 0x%08x\n", hr); + ok(hr == S_OK, "got 0x%08lx\n", hr); rect.X = rect.Y = 5; rect.Width = rect.Height = 5; hr = IWICBitmapClipper_Initialize(clipper, &bitmapsource, &rect); - ok(hr == S_OK, "got 0x%08x\n", hr); + ok(hr == S_OK, "got 0x%08lx\n", hr); rect.X = rect.Y = 0; rect.Width = rect.Height = 2; @@ -1038,7 +1049,7 @@ static void test_clipper(void) memset(&g_rect, 0, sizeof(g_rect)); called_CopyPixels = FALSE; hr = IWICBitmapClipper_CopyPixels(clipper, &rect, 0, sizeof(buffer), buffer); - ok(hr == S_OK, "got 0x%08x\n", hr); + ok(hr == S_OK, "got 0x%08lx\n", hr); ok(called_CopyPixels, "CopyPixels not called\n"); ok(g_rect.X == 5 && g_rect.Y == 5 && g_rect.Width == 2 && g_rect.Height == 2, "got wrong rectangle (%d,%d)-(%d,%d)\n", g_rect.X, g_rect.Y, g_rect.Width, g_rect.Height); @@ -1051,7 +1062,7 @@ static void test_clipper(void) rect.Width = rect.Height = 5; hr = IWICBitmapClipper_CopyPixels(clipper, &rect, 0, sizeof(buffer), buffer); - ok(hr == S_OK, "got 0x%08x\n", hr); + ok(hr == S_OK, "got 0x%08lx\n", hr); ok(called_CopyPixels, "CopyPixels not called\n"); ok(g_rect.X == 5 && g_rect.Y == 5 && g_rect.Width == 5 && g_rect.Height == 5, "got wrong rectangle (%d,%d)-(%d,%d)\n", g_rect.X, g_rect.Y, g_rect.Width, g_rect.Height); @@ -1064,14 +1075,14 @@ static void test_clipper(void) rect.Width = rect.Height = 20; hr = IWICBitmapClipper_CopyPixels(clipper, &rect, 0, sizeof(buffer), buffer); - ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(hr == E_INVALIDARG, "got 0x%08lx\n", hr); ok(!called_CopyPixels, "CopyPixels called\n"); rect.X = rect.Y = 5; rect.Width = rect.Height = 5; hr = IWICBitmapClipper_CopyPixels(clipper, &rect, 0, sizeof(buffer), buffer); - ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(hr == E_INVALIDARG, "got 0x%08lx\n", hr); ok(!called_CopyPixels, "CopyPixels called\n"); /* null rectangle */ @@ -1079,7 +1090,7 @@ static void test_clipper(void) called_CopyPixels = FALSE; hr = IWICBitmapClipper_CopyPixels(clipper, NULL, 0, sizeof(buffer), buffer); - ok(hr == S_OK, "got 0x%08x\n", hr); + ok(hr == S_OK, "got 0x%08lx\n", hr); ok(called_CopyPixels, "CopyPixels not called\n"); ok(g_rect.X == 5 && g_rect.Y == 5 && g_rect.Width == 5 && g_rect.Height == 5, "got wrong rectangle (%d,%d)-(%d,%d)\n", g_rect.X, g_rect.Y, g_rect.Width, g_rect.Height); @@ -1111,7 +1122,7 @@ static void test_WICCreateBitmapFromSectionEx(void) GetSystemInfo(&sysinfo); hsection = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sysinfo.dwAllocationGranularity * 2, NULL); - ok(hsection != NULL, "CreateFileMapping failed %u\n", GetLastError()); + ok(hsection != NULL, "CreateFileMapping failed %lu\n", GetLastError()); memset(&info, 0, sizeof(info)); info.bmiHeader.biSize = sizeof(info.bmiHeader); @@ -1126,20 +1137,20 @@ static void test_WICCreateBitmapFromSectionEx(void) hr = pWICCreateBitmapFromSectionEx(3, 3, &GUID_WICPixelFormat24bppBGR, hsection, 0, 0, WICSectionAccessLevelReadWrite, &bitmap); - ok(hr == S_OK, "WICCreateBitmapFromSectionEx returned %#x\n", hr); + ok(hr == S_OK, "WICCreateBitmapFromSectionEx returned %#lx\n", hr); IWICBitmap_Release(bitmap); /* non-zero offset, smaller than allocation granularity */ hr = pWICCreateBitmapFromSectionEx(3, 3, &GUID_WICPixelFormat24bppBGR, hsection, 0, 0x100, WICSectionAccessLevelReadWrite, &bitmap); - ok(hr == S_OK, "WICCreateBitmapFromSectionEx returned %#x\n", hr); + ok(hr == S_OK, "WICCreateBitmapFromSectionEx returned %#lx\n", hr); IWICBitmap_Release(bitmap); /* offset larger than allocation granularity */ hr = pWICCreateBitmapFromSectionEx(3, 3, &GUID_WICPixelFormat24bppBGR, hsection, 0, sysinfo.dwAllocationGranularity + 1, WICSectionAccessLevelReadWrite, &bitmap); - ok(hr == S_OK, "WICCreateBitmapFromSectionEx returned %#x\n", hr); + ok(hr == S_OK, "WICCreateBitmapFromSectionEx returned %#lx\n", hr); IWICBitmap_Release(bitmap); DeleteObject(hdib); CloseHandle(hsection); @@ -1153,162 +1164,165 @@ static void test_bitmap_scaler(void) double res_x, res_y; IWICBitmap *bitmap; UINT width, height; - BYTE buf[16]; + BYTE buf[93]; /* capable of holding a 7*4px, 24bpp image with stride 24 -> buffer size = 3*24+21 */ HRESULT hr; hr = IWICImagingFactory_CreateBitmap(factory, 4, 2, &GUID_WICPixelFormat24bppBGR, WICBitmapCacheOnLoad, &bitmap); - ok(hr == S_OK, "Failed to create a bitmap, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to create a bitmap, hr %#lx.\n", hr); hr = IWICBitmap_GetSize(bitmap, &width, &height); - ok(hr == S_OK, "Failed to get bitmap size, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to get bitmap size, hr %#lx.\n", hr); ok(width == 4, "Unexpected width %u.\n", width); ok(height == 2, "Unexpected height %u.\n", height); hr = IWICBitmap_GetResolution(bitmap, &res_x, &res_y); - ok(hr == S_OK, "Failed to get bitmap resolution, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to get bitmap resolution, hr %#lx.\n", hr); ok(res_x == 0.0 && res_y == 0.0, "Unexpected resolution %f x %f.\n", res_x, res_y); hr = IWICImagingFactory_CreateBitmapScaler(factory, &scaler); - ok(hr == S_OK, "Failed to create bitmap scaler, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to create bitmap scaler, hr %#lx.\n", hr); hr = IWICBitmapScaler_Initialize(scaler, NULL, 0, 0, WICBitmapInterpolationModeNearestNeighbor); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); hr = IWICBitmapScaler_Initialize(scaler, (IWICBitmapSource *)bitmap, 0, 0, WICBitmapInterpolationModeNearestNeighbor); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); hr = IWICBitmapScaler_GetSize(scaler, NULL, &height); - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#x.\n", hr); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#lx.\n", hr); hr = IWICBitmapScaler_GetSize(scaler, &width, NULL); - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#x.\n", hr); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#lx.\n", hr); hr = IWICBitmapScaler_GetResolution(scaler, NULL, NULL); - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#x.\n", hr); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#lx.\n", hr); res_x = 0.1; hr = IWICBitmapScaler_GetResolution(scaler, &res_x, NULL); - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#x.\n", hr); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#lx.\n", hr); ok(res_x == 0.1, "Unexpected resolution %f.\n", res_x); hr = IWICBitmapScaler_GetResolution(scaler, NULL, &res_y); - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#x.\n", hr); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#lx.\n", hr); hr = IWICBitmapScaler_GetResolution(scaler, &res_x, &res_y); - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#x.\n", hr); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#lx.\n", hr); hr = IWICBitmapScaler_GetPixelFormat(scaler, NULL); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); memset(&pixel_format, 0, sizeof(pixel_format)); hr = IWICBitmapScaler_GetPixelFormat(scaler, &pixel_format); - ok(hr == S_OK, "Failed to get pixel format, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to get pixel format, hr %#lx.\n", hr); ok(IsEqualGUID(&pixel_format, &GUID_WICPixelFormatDontCare), "Unexpected pixel format %s.\n", wine_dbgstr_guid(&pixel_format)); width = 123; height = 321; hr = IWICBitmapScaler_GetSize(scaler, &width, &height); - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#x.\n", hr); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#lx.\n", hr); ok(width == 123, "Unexpected width %u.\n", width); ok(height == 321, "Unexpected height %u.\n", height); hr = IWICBitmapScaler_CopyPalette(scaler, NULL); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "Failed to create a palette, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to create a palette, hr %#lx.\n", hr); hr = IWICBitmapScaler_CopyPalette(scaler, palette); - ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "Unexpected hr %#x.\n", hr); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "Unexpected hr %#lx.\n", hr); IWICPalette_Release(palette); hr = IWICBitmapScaler_Initialize(scaler, (IWICBitmapSource *)bitmap, 4, 0, WICBitmapInterpolationModeNearestNeighbor); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); hr = IWICBitmapScaler_GetSize(scaler, &width, &height); - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#x.\n", hr); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#lx.\n", hr); hr = IWICBitmapScaler_CopyPixels(scaler, NULL, 1, sizeof(buf), buf); - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#x.\n", hr); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#lx.\n", hr); hr = IWICBitmapScaler_Initialize(scaler, (IWICBitmapSource *)bitmap, 0, 2, WICBitmapInterpolationModeNearestNeighbor); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); hr = IWICBitmapScaler_GetSize(scaler, &width, &height); - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#x.\n", hr); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#lx.\n", hr); hr = IWICBitmapScaler_Initialize(scaler, NULL, 8, 4, WICBitmapInterpolationModeNearestNeighbor); - ok(hr == E_INVALIDARG, "Failed to initialize bitmap scaler, hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Failed to initialize bitmap scaler, hr %#lx.\n", hr); - hr = IWICBitmapScaler_Initialize(scaler, (IWICBitmapSource *)bitmap, 8, 4, + hr = IWICBitmapScaler_Initialize(scaler, (IWICBitmapSource *)bitmap, 7, 4, WICBitmapInterpolationModeNearestNeighbor); - ok(hr == S_OK, "Failed to initialize bitmap scaler, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to initialize bitmap scaler, hr %#lx.\n", hr); hr = IWICBitmapScaler_Initialize(scaler, (IWICBitmapSource *)bitmap, 0, 4, WICBitmapInterpolationModeNearestNeighbor); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); - hr = IWICBitmapScaler_Initialize(scaler, (IWICBitmapSource *)bitmap, 8, 0, + hr = IWICBitmapScaler_Initialize(scaler, (IWICBitmapSource *)bitmap, 7, 0, WICBitmapInterpolationModeNearestNeighbor); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); hr = IWICBitmapScaler_Initialize(scaler, NULL, 8, 4, WICBitmapInterpolationModeNearestNeighbor); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); - hr = IWICBitmapScaler_Initialize(scaler, (IWICBitmapSource *)bitmap, 8, 4, + hr = IWICBitmapScaler_Initialize(scaler, (IWICBitmapSource *)bitmap, 7, 4, WICBitmapInterpolationModeNearestNeighbor); - ok(hr == WINCODEC_ERR_WRONGSTATE, "Unexpected hr %#x.\n", hr); + ok(hr == WINCODEC_ERR_WRONGSTATE, "Unexpected hr %#lx.\n", hr); hr = IWICBitmapScaler_GetSize(scaler, &width, &height); - ok(hr == S_OK, "Failed to get scaler size, hr %#x.\n", hr); - ok(width == 8, "Unexpected width %u.\n", width); + ok(hr == S_OK, "Failed to get scaler size, hr %#lx.\n", hr); + ok(width == 7, "Unexpected width %u.\n", width); ok(height == 4, "Unexpected height %u.\n", height); hr = IWICBitmapScaler_GetSize(scaler, NULL, &height); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); hr = IWICBitmapScaler_GetSize(scaler, &width, NULL); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); hr = IWICBitmapScaler_GetSize(scaler, NULL, NULL); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); hr = IWICBitmapScaler_GetPixelFormat(scaler, NULL); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); memset(&pixel_format, 0, sizeof(pixel_format)); hr = IWICBitmapScaler_GetPixelFormat(scaler, &pixel_format); - ok(hr == S_OK, "Failed to get pixel format, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to get pixel format, hr %#lx.\n", hr); ok(IsEqualGUID(&pixel_format, &GUID_WICPixelFormat24bppBGR), "Unexpected pixel format %s.\n", wine_dbgstr_guid(&pixel_format)); hr = IWICBitmapScaler_GetResolution(scaler, NULL, NULL); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); res_x = 0.1; hr = IWICBitmapScaler_GetResolution(scaler, &res_x, NULL); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); ok(res_x == 0.1, "Unexpected resolution %f.\n", res_x); hr = IWICBitmapScaler_GetResolution(scaler, NULL, &res_y); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); res_x = res_y = 1.0; hr = IWICBitmapScaler_GetResolution(scaler, &res_x, &res_y); - ok(hr == S_OK, "Failed to get scaler resolution, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to get scaler resolution, hr %#lx.\n", hr); ok(res_x == 0.0 && res_y == 0.0, "Unexpected resolution %f x %f.\n", res_x, res_y); hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "Failed to create a palette, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to create a palette, hr %#lx.\n", hr); hr = IWICBitmapScaler_CopyPalette(scaler, palette); - ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "Unexpected hr %#x.\n", hr); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "Unexpected hr %#lx.\n", hr); IWICPalette_Release(palette); + hr = IWICBitmapScaler_CopyPixels(scaler, NULL, /*cbStride=*/24, sizeof(buf), buf); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IWICBitmapScaler_Release(scaler); IWICBitmap_Release(bitmap); @@ -1338,131 +1352,137 @@ static void test_IMILBitmap(void) /* Bitmap */ hr = IWICImagingFactory_CreateBitmap(factory, 1, 1, &GUID_WICPixelFormat24bppBGR, WICBitmapCacheOnDemand, &bitmap); - ok(hr == S_OK, "CreateBitmap error %#x\n", hr); + ok(hr == S_OK, "CreateBitmap error %#lx\n", hr); - ok(obj_refcount(bitmap) == 1, "ref count %d\n", obj_refcount(bitmap)); + ok(obj_refcount(bitmap) == 1, "ref count %ld\n", obj_refcount(bitmap)); hr = IWICBitmap_GetPixelFormat(bitmap, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_WICPixelFormat24bppBGR), "wrong format %s\n", wine_dbgstr_guid(&format)); hr = IWICBitmap_GetResolution(bitmap, &dpix, &dpiy); - ok(hr == S_OK, "GetResolution error %#x\n", hr); + ok(hr == S_OK, "GetResolution error %#lx\n", hr); ok(dpix == 0.0, "got %f, expected 0.0\n", dpix); ok(dpiy == 0.0, "got %f, expected 0.0\n", dpiy); hr = IWICBitmap_SetResolution(bitmap, 12.0, 34.0); - ok(hr == S_OK, "SetResolution error %#x\n", hr); + ok(hr == S_OK, "SetResolution error %#lx\n", hr); hr = IWICBitmap_GetResolution(bitmap, &dpix, &dpiy); - ok(hr == S_OK, "GetResolution error %#x\n", hr); + ok(hr == S_OK, "GetResolution error %#lx\n", hr); ok(dpix == 12.0, "got %f, expected 12.0\n", dpix); ok(dpiy == 34.0, "got %f, expected 34.0\n", dpiy); hr = IWICBitmap_GetSize(bitmap, &width, &height); - ok(hr == S_OK, "GetSize error %#x\n", hr); + ok(hr == S_OK, "GetSize error %#lx\n", hr); ok(width == 1, "got %u, expected 1\n", width); ok(height == 1, "got %u, expected 1\n", height); hr = IWICBitmap_QueryInterface(bitmap, &IID_IMILBitmap, (void **)&mil_bitmap); - ok(hr == S_OK, "QueryInterface error %#x\n", hr); + ok(hr == S_OK, "QueryInterface error %#lx\n", hr); - ok(obj_refcount(bitmap) == 2, "ref count %d\n", obj_refcount(bitmap)); - ok(obj_refcount(mil_bitmap) == 2, "ref count %d\n", obj_refcount(mil_bitmap)); + ok(obj_refcount(bitmap) == 2, "ref count %ld\n", obj_refcount(bitmap)); + ok(obj_refcount(mil_bitmap) == 2, "ref count %ld\n", obj_refcount(mil_bitmap)); hr = IWICBitmap_QueryInterface(bitmap, &IID_IUnknown, (void **)&wic_unknown); - ok(hr == S_OK, "QueryInterface error %#x\n", hr); + ok(hr == S_OK, "QueryInterface error %#lx\n", hr); hr = mil_bitmap->lpVtbl->QueryInterface(mil_bitmap, &IID_IUnknown, (void **)&mil_unknown); - ok(hr == S_OK, "QueryInterface error %#x\n", hr); + ok(hr == S_OK, "QueryInterface error %#lx\n", hr); ok((void *)wic_unknown->lpVtbl == (void *)mil_unknown->lpVtbl, "wrong lpVtbl ptrs %p != %p\n", wic_unknown->lpVtbl, mil_unknown->lpVtbl); IUnknown_Release(wic_unknown); IUnknown_Release(mil_unknown); hr = IWICBitmap_QueryInterface(bitmap, &IID_IMILBitmapSource, (void **)&mil_source); - ok(hr == S_OK, "QueryInterface error %#x\n", hr); + ok(hr == S_OK, "QueryInterface error %#lx\n", hr); ok((void *)mil_source->lpVtbl == (void *)mil_bitmap->lpVtbl, "IMILBitmap->lpVtbl should be equal to IMILBitmapSource->lpVtbl\n"); - ok(obj_refcount(bitmap) == 3, "ref count %d\n", obj_refcount(bitmap)); - ok(obj_refcount(mil_bitmap) == 3, "ref count %d\n", obj_refcount(mil_bitmap)); - ok(obj_refcount(mil_source) == 3, "ref count %d\n", obj_refcount(mil_source)); + ok(obj_refcount(bitmap) == 3, "ref count %ld\n", obj_refcount(bitmap)); + ok(obj_refcount(mil_bitmap) == 3, "ref count %ld\n", obj_refcount(mil_bitmap)); + ok(obj_refcount(mil_source) == 3, "ref count %ld\n", obj_refcount(mil_source)); hr = mil_source->lpVtbl->GetPixelFormat(mil_source, &MIL_format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(MIL_format == 0x0c, "wrong format %d\n", MIL_format); hr = mil_source->lpVtbl->GetResolution(mil_source, &dpix, &dpiy); - ok(hr == S_OK, "GetResolution error %#x\n", hr); + ok(hr == S_OK, "GetResolution error %#lx\n", hr); ok(dpix == 12.0, "got %f, expected 12.0\n", dpix); ok(dpiy == 34.0, "got %f, expected 34.0\n", dpiy); hr = mil_source->lpVtbl->GetSize(mil_source, &width, &height); - ok(hr == S_OK, "GetSize error %#x\n", hr); + ok(hr == S_OK, "GetSize error %#lx\n", hr); ok(width == 1, "got %u, expected 1\n", width); ok(height == 1, "got %u, expected 1\n", height); /* Scaler */ hr = IWICImagingFactory_CreateBitmapScaler(factory, &scaler); - ok(hr == S_OK, "CreateBitmapScaler error %#x\n", hr); + ok(hr == S_OK, "CreateBitmapScaler error %#lx\n", hr); - ok(obj_refcount(scaler) == 1, "ref count %d\n", obj_refcount(scaler)); + ok(obj_refcount(scaler) == 1, "ref count %ld\n", obj_refcount(scaler)); hr = IWICBitmapScaler_QueryInterface(scaler, &IID_IMILBitmapScaler, (void **)&mil_scaler); - ok(hr == S_OK, "QueryInterface error %#x\n", hr); + ok(hr == S_OK, "QueryInterface error %#lx\n", hr); - ok(obj_refcount(scaler) == 2, "ref count %d\n", obj_refcount(scaler)); - ok(obj_refcount(mil_scaler) == 2, "ref count %d\n", obj_refcount(mil_scaler)); + ok(obj_refcount(scaler) == 2, "ref count %ld\n", obj_refcount(scaler)); + ok(obj_refcount(mil_scaler) == 2, "ref count %ld\n", obj_refcount(mil_scaler)); hr = IWICBitmapScaler_QueryInterface(scaler, &IID_IUnknown, (void **)&wic_unknown); - ok(hr == S_OK, "QueryInterface error %#x\n", hr); + ok(hr == S_OK, "QueryInterface error %#lx\n", hr); hr = mil_scaler->lpVtbl->QueryInterface(mil_scaler, &IID_IUnknown, (void **)&mil_unknown); - ok(hr == S_OK, "QueryInterface error %#x\n", hr); + ok(hr == S_OK, "QueryInterface error %#lx\n", hr); ok((void *)wic_unknown->lpVtbl == (void *)mil_unknown->lpVtbl, "wrong lpVtbl ptrs %p != %p\n", wic_unknown->lpVtbl, mil_unknown->lpVtbl); IUnknown_Release(wic_unknown); IUnknown_Release(mil_unknown); hr = mil_scaler->lpVtbl->GetPixelFormat(mil_scaler, &MIL_format); - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "GetPixelFormat error %#x\n", hr); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "GetPixelFormat error %#lx\n", hr); hr = mil_scaler->lpVtbl->GetResolution(mil_scaler, &dpix, &dpiy); - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "GetResolution error %#x\n", hr); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "GetResolution error %#lx\n", hr); hr = mil_scaler->lpVtbl->GetSize(mil_scaler, &width, &height); - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "GetSize error %#x\n", hr); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "GetSize error %#lx\n", hr); memset(buf, 0xde, sizeof(buf)); hr = mil_scaler->lpVtbl->CopyPixels(mil_scaler, NULL, 3, sizeof(buf), buf); - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "CopyPixels error %#x\n", hr); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "CopyPixels error %#lx\n", hr); hr = mil_scaler->lpVtbl->Initialize(mil_scaler, mil_source, 1, 1, 1); - ok(hr == S_OK, "Initialize error %#x\n", hr); + ok(hr == S_OK, "Initialize error %#lx\n", hr); hr = mil_scaler->lpVtbl->GetPixelFormat(mil_scaler, &MIL_format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(MIL_format == 0x0c, "wrong format %d\n", MIL_format); hr = mil_scaler->lpVtbl->GetResolution(mil_scaler, &dpix, &dpiy); - ok(hr == S_OK, "GetResolution error %#x\n", hr); + ok(hr == S_OK, "GetResolution error %#lx\n", hr); ok(dpix == 12.0, "got %f, expected 12.0\n", dpix); ok(dpiy == 34.0, "got %f, expected 34.0\n", dpiy); hr = mil_scaler->lpVtbl->GetSize(mil_scaler, &width, &height); - ok(hr == S_OK, "GetSize error %#x\n", hr); + ok(hr == S_OK, "GetSize error %#lx\n", hr); ok(width == 1, "got %u, expected 1\n", width); ok(height == 1, "got %u, expected 1\n", height); memset(buf, 0xde, sizeof(buf)); hr = mil_scaler->lpVtbl->CopyPixels(mil_scaler, NULL, 3, sizeof(buf), buf); - ok(hr == S_OK, "CopyPixels error %#x\n", hr); + ok(hr == S_OK, "CopyPixels error %#lx\n", hr); ok(buf[0] == 0 && buf[1] == 0 && buf[2] == 0 && buf[3] == 0xde,"wrong data: %02x %02x %02x %02x\n", buf[0], buf[1], buf[2], buf[3]); mil_scaler->lpVtbl->Release(mil_scaler); IWICBitmapScaler_Release(scaler); mil_source->lpVtbl->Release(mil_source); mil_bitmap->lpVtbl->Release(mil_bitmap); + + mil_unknown = (void *)0xdeadbeef; + hr = IWICBitmap_QueryInterface(bitmap, &IID_CMetaBitmapRenderTarget, (void **)&mil_unknown); + ok(hr == E_NOINTERFACE, "got %#lx\n", hr); + ok(!mil_unknown, "got %p\n", mil_unknown); + IWICBitmap_Release(bitmap); } @@ -1474,7 +1494,7 @@ START_TEST(bitmap) hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&factory); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); test_IMILBitmap(); test_createbitmap(); diff --git a/modules/rostests/winetests/windowscodecs/bmpformat.c b/modules/rostests/winetests/windowscodecs/bmpformat.c index 8bac7a3853e28..724723f647a36 100644 --- a/modules/rostests/winetests/windowscodecs/bmpformat.c +++ b/modules/rostests/winetests/windowscodecs/bmpformat.c @@ -22,7 +22,6 @@ #define COBJMACROS #include "windef.h" -#include "initguid.h" #include "objbase.h" #include "wincodec.h" #include "wincodecsdk.h" @@ -76,7 +75,7 @@ static void test_decode_24bpp(void) hr = CoCreateInstance(&CLSID_WICBmpDecoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void**)&decoder); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); if (FAILED(hr)) return; hbmpdata = GlobalAlloc(GMEM_MOVEABLE, sizeof(testbmp_24bpp)); @@ -88,11 +87,11 @@ static void test_decode_24bpp(void) GlobalUnlock(hbmpdata); hr = CreateStreamOnHGlobal(hbmpdata, FALSE, &bmpstream); - ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_Initialize(decoder, bmpstream, WICDecodeMetadataCacheOnLoad); - ok(hr == S_OK || broken(hr == WINCODEC_ERR_BADIMAGE) /* XP */, "Initialize failed, hr=%x\n", hr); + ok(hr == S_OK || broken(hr == WINCODEC_ERR_BADIMAGE) /* XP */, "Initialize failed, hr=%lx\n", hr); if (FAILED(hr)) { win_skip("BMP decoder failed to initialize\n"); @@ -102,72 +101,72 @@ static void test_decode_24bpp(void) } hr = IWICBitmapDecoder_GetContainerFormat(decoder, &guidresult); - ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&guidresult, &GUID_ContainerFormatBmp), "unexpected container format\n"); hr = IWICBitmapDecoder_GetMetadataQueryReader(decoder, &queryreader); - ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "expected WINCODEC_ERR_UNSUPPORTEDOPERATION, got %x\n", hr); + ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "expected WINCODEC_ERR_UNSUPPORTEDOPERATION, got %lx\n", hr); hr = IWICBitmapDecoder_GetColorContexts(decoder, 1, &colorcontext, &count); - ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "expected WINCODEC_ERR_UNSUPPORTEDOPERATION, got %x\n", hr); + ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "expected WINCODEC_ERR_UNSUPPORTEDOPERATION, got %lx\n", hr); hr = IWICBitmapDecoder_GetThumbnail(decoder, &thumbnail); - ok(hr == WINCODEC_ERR_CODECNOTHUMBNAIL, "expected WINCODEC_ERR_CODECNOTHUMBNAIL, got %x\n", hr); + ok(hr == WINCODEC_ERR_CODECNOTHUMBNAIL, "expected WINCODEC_ERR_CODECNOTHUMBNAIL, got %lx\n", hr); hr = IWICBitmapDecoder_GetPreview(decoder, &thumbnail); - ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "expected WINCODEC_ERR_UNSUPPORTEDOPERATION, got %x\n", hr); + ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "expected WINCODEC_ERR_UNSUPPORTEDOPERATION, got %lx\n", hr); hr = IWICBitmapDecoder_GetFrameCount(decoder, &count); - ok(SUCCEEDED(hr), "GetFrameCount failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetFrameCount failed, hr=%lx\n", hr); ok(count == 1, "unexpected count %u\n", count); hr = IWICBitmapDecoder_GetFrame(decoder, 1, &framedecode); - ok(hr == E_INVALIDARG || hr == WINCODEC_ERR_FRAMEMISSING, "GetFrame returned %x\n", hr); + ok(hr == E_INVALIDARG || hr == WINCODEC_ERR_FRAMEMISSING, "GetFrame returned %lx\n", hr); hr = IWICBitmapDecoder_GetFrame(decoder, 0, &framedecode); - ok(SUCCEEDED(hr), "GetFrame failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetFrame failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { IWICImagingFactory *factory; IWICPalette *palette; hr = IWICBitmapFrameDecode_GetSize(framedecode, &width, &height); - ok(SUCCEEDED(hr), "GetSize failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetSize failed, hr=%lx\n", hr); ok(width == 2, "expected width=2, got %u\n", width); ok(height == 3, "expected height=2, got %u\n", height); hr = IWICBitmapFrameDecode_GetResolution(framedecode, &dpiX, &dpiY); - ok(SUCCEEDED(hr), "GetResolution failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetResolution failed, hr=%lx\n", hr); ok(dpiX == 96.0, "expected dpiX=96.0, got %f\n", dpiX); ok(dpiY == 96.0, "expected dpiY=96.0, got %f\n", dpiY); hr = IWICBitmapFrameDecode_GetPixelFormat(framedecode, &guidresult); - ok(SUCCEEDED(hr), "GetPixelFormat failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetPixelFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&guidresult, &GUID_WICPixelFormat24bppBGR), "unexpected pixel format\n"); hr = IWICBitmapFrameDecode_GetMetadataQueryReader(framedecode, &queryreader); - ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "expected WINCODEC_ERR_UNSUPPORTEDOPERATION, got %x\n", hr); + ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "expected WINCODEC_ERR_UNSUPPORTEDOPERATION, got %lx\n", hr); hr = IWICBitmapFrameDecode_GetColorContexts(framedecode, 1, &colorcontext, &count); - ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "expected WINCODEC_ERR_UNSUPPORTEDOPERATION, got %x\n", hr); + ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "expected WINCODEC_ERR_UNSUPPORTEDOPERATION, got %lx\n", hr); hr = IWICBitmapFrameDecode_GetThumbnail(framedecode, &thumbnail); - ok(hr == WINCODEC_ERR_CODECNOTHUMBNAIL, "expected WINCODEC_ERR_CODECNOTHUMBNAIL, got %x\n", hr); + ok(hr == WINCODEC_ERR_CODECNOTHUMBNAIL, "expected WINCODEC_ERR_CODECNOTHUMBNAIL, got %lx\n", hr); hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&factory); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(SUCCEEDED(hr), "CreatePalette failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreatePalette failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_CopyPalette(decoder, palette); - ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %x\n", hr); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %lx\n", hr); hr = IWICBitmapFrameDecode_CopyPalette(framedecode, palette); - ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %x\n", hr); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %lx\n", hr); IWICPalette_Release(palette); } @@ -180,39 +179,39 @@ static void test_decode_24bpp(void) rc.Width = 3; rc.Height = 3; hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 6, sizeof(imagedata), imagedata); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %lx\n", hr); rc.X = -1; rc.Y = 0; rc.Width = 2; rc.Height = 3; hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 6, sizeof(imagedata), imagedata); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %lx\n", hr); rc.X = 0; rc.Y = 0; rc.Width = 2; rc.Height = 3; hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 4, sizeof(imagedata), imagedata); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %lx\n", hr); rc.X = 0; rc.Y = 0; rc.Width = 2; rc.Height = 3; hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 4, 5, imagedata); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %lx\n", hr); rc.X = 0; rc.Y = 0; rc.Width = 2; rc.Height = 3; hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 6, sizeof(imagedata), imagedata); - ok(SUCCEEDED(hr), "CopyPixels failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CopyPixels failed, hr=%lx\n", hr); ok(!memcmp(imagedata, expected_imagedata, sizeof(imagedata)), "unexpected image data\n"); hr = IWICBitmapFrameDecode_CopyPixels(framedecode, NULL, 6, sizeof(imagedata), imagedata); - ok(SUCCEEDED(hr), "CopyPixels(rect=NULL) failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CopyPixels(rect=NULL) failed, hr=%lx\n", hr); ok(!memcmp(imagedata, expected_imagedata, sizeof(imagedata)), "unexpected image data\n"); IWICBitmapFrameDecode_Release(framedecode); @@ -220,29 +219,29 @@ static void test_decode_24bpp(void) /* cannot initialize twice */ hr = IWICBitmapDecoder_Initialize(decoder, bmpstream, WICDecodeMetadataCacheOnLoad); - ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, hr=%x\n", hr); + ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, hr=%lx\n", hr); /* cannot querycapability after initialize */ hr = IWICBitmapDecoder_QueryCapability(decoder, bmpstream, &capability); - ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, hr=%x\n", hr); + ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, hr=%lx\n", hr); hr = CoCreateInstance(&CLSID_WICBmpDecoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void**)&decoder2); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_QueryCapability(decoder2, bmpstream, &capability); - ok(hr == S_OK, "QueryCapability failed, hr=%x\n", hr); + ok(hr == S_OK, "QueryCapability failed, hr=%lx\n", hr); ok(capability == (WICBitmapDecoderCapabilityCanDecodeAllImages), - "unexpected capabilities: %x\n", capability); + "unexpected capabilities: %lx\n", capability); /* cannot initialize after querycapability */ hr = IWICBitmapDecoder_Initialize(decoder2, bmpstream, WICDecodeMetadataCacheOnLoad); - ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, hr=%x\n", hr); + ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, hr=%lx\n", hr); /* cannot querycapability twice */ hr = IWICBitmapDecoder_QueryCapability(decoder2, bmpstream, &capability); - ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, hr=%x\n", hr); + ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, hr=%lx\n", hr); IWICBitmapDecoder_Release(decoder2); } @@ -296,7 +295,7 @@ static void test_decode_1bpp(void) hr = CoCreateInstance(&CLSID_WICBmpDecoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void**)&decoder); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); if (FAILED(hr)) return; hbmpdata = GlobalAlloc(GMEM_MOVEABLE, sizeof(testbmp_1bpp)); @@ -308,62 +307,62 @@ static void test_decode_1bpp(void) GlobalUnlock(hbmpdata); hr = CreateStreamOnHGlobal(hbmpdata, FALSE, &bmpstream); - ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_Initialize(decoder, bmpstream, WICDecodeMetadataCacheOnLoad); - ok(hr == S_OK, "Initialize failed, hr=%x\n", hr); + ok(hr == S_OK, "Initialize failed, hr=%lx\n", hr); hr = IWICBitmapDecoder_GetContainerFormat(decoder, &guidresult); - ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&guidresult, &GUID_ContainerFormatBmp), "unexpected container format\n"); hr = IWICBitmapDecoder_GetFrameCount(decoder, &count); - ok(SUCCEEDED(hr), "GetFrameCount failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetFrameCount failed, hr=%lx\n", hr); ok(count == 1, "unexpected count %u\n", count); hr = IWICBitmapDecoder_GetFrame(decoder, 0, &framedecode); - ok(SUCCEEDED(hr), "GetFrame failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetFrame failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { IWICImagingFactory *factory; IWICPalette *palette; hr = IWICBitmapFrameDecode_GetSize(framedecode, &width, &height); - ok(SUCCEEDED(hr), "GetSize failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetSize failed, hr=%lx\n", hr); ok(width == 2, "expected width=2, got %u\n", width); ok(height == 2, "expected height=2, got %u\n", height); hr = IWICBitmapFrameDecode_GetResolution(framedecode, &dpiX, &dpiY); - ok(SUCCEEDED(hr), "GetResolution failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetResolution failed, hr=%lx\n", hr); ok(dpiX == 96.0, "expected dpiX=96.0, got %f\n", dpiX); ok(dpiY == 96.0, "expected dpiY=96.0, got %f\n", dpiY); hr = IWICBitmapFrameDecode_GetPixelFormat(framedecode, &guidresult); - ok(SUCCEEDED(hr), "GetPixelFormat failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetPixelFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&guidresult, &GUID_WICPixelFormat1bppIndexed), "unexpected pixel format\n"); hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&factory); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(SUCCEEDED(hr), "CreatePalette failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreatePalette failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_CopyPalette(decoder, palette); - ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %x\n", hr); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %lx\n", hr); hr = IWICBitmapFrameDecode_CopyPalette(framedecode, palette); - ok(SUCCEEDED(hr), "CopyPalette failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CopyPalette failed, hr=%lx\n", hr); hr = IWICPalette_GetColorCount(palette, &count); - ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColorCount failed, hr=%lx\n", hr); ok(count == 2, "expected count=2, got %u\n", count); hr = IWICPalette_GetColors(palette, 2, palettedata, &count); - ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColorCount failed, hr=%lx\n", hr); ok(count == 2, "expected count=2, got %u\n", count); ok(!memcmp(palettedata, expected_palettedata, sizeof(palettedata)), "unexpected palette data\n"); @@ -378,7 +377,7 @@ static void test_decode_1bpp(void) rc.Width = 2; rc.Height = 2; hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 1, sizeof(imagedata), imagedata); - ok(SUCCEEDED(hr), "CopyPixels failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CopyPixels failed, hr=%lx\n", hr); ok(!memcmp(imagedata, expected_imagedata, sizeof(imagedata)), "unexpected image data\n"); IWICBitmapFrameDecode_Release(framedecode); @@ -386,13 +385,13 @@ static void test_decode_1bpp(void) hr = CoCreateInstance(&CLSID_WICBmpDecoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void**)&decoder2); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_QueryCapability(decoder2, bmpstream, &capability); - ok(hr == S_OK, "QueryCapability failed, hr=%x\n", hr); + ok(hr == S_OK, "QueryCapability failed, hr=%lx\n", hr); ok(capability == (WICBitmapDecoderCapabilityCanDecodeAllImages), - "unexpected capabilities: %x\n", capability); + "unexpected capabilities: %lx\n", capability); IWICBitmapDecoder_Release(decoder2); } @@ -455,7 +454,7 @@ static void test_decode_4bpp(void) hr = CoCreateInstance(&CLSID_WICBmpDecoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void**)&decoder); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); if (FAILED(hr)) return; hbmpdata = GlobalAlloc(GMEM_MOVEABLE, sizeof(testbmp_4bpp)); @@ -467,62 +466,62 @@ static void test_decode_4bpp(void) GlobalUnlock(hbmpdata); hr = CreateStreamOnHGlobal(hbmpdata, FALSE, &bmpstream); - ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_Initialize(decoder, bmpstream, WICDecodeMetadataCacheOnLoad); - ok(hr == S_OK, "Initialize failed, hr=%x\n", hr); + ok(hr == S_OK, "Initialize failed, hr=%lx\n", hr); hr = IWICBitmapDecoder_GetContainerFormat(decoder, &guidresult); - ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&guidresult, &GUID_ContainerFormatBmp), "unexpected container format\n"); hr = IWICBitmapDecoder_GetFrameCount(decoder, &count); - ok(SUCCEEDED(hr), "GetFrameCount failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetFrameCount failed, hr=%lx\n", hr); ok(count == 1, "unexpected count %u\n", count); hr = IWICBitmapDecoder_GetFrame(decoder, 0, &framedecode); - ok(SUCCEEDED(hr), "GetFrame failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetFrame failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { IWICImagingFactory *factory; IWICPalette *palette; hr = IWICBitmapFrameDecode_GetSize(framedecode, &width, &height); - ok(SUCCEEDED(hr), "GetSize failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetSize failed, hr=%lx\n", hr); ok(width == 2, "expected width=2, got %u\n", width); ok(height == 2, "expected height=2, got %u\n", height); hr = IWICBitmapFrameDecode_GetResolution(framedecode, &dpiX, &dpiY); - ok(SUCCEEDED(hr), "GetResolution failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetResolution failed, hr=%lx\n", hr); ok(fabs(dpiX - 254.0) < 0.01, "expected dpiX=96.0, got %f\n", dpiX); ok(fabs(dpiY - 508.0) < 0.01, "expected dpiY=96.0, got %f\n", dpiY); hr = IWICBitmapFrameDecode_GetPixelFormat(framedecode, &guidresult); - ok(SUCCEEDED(hr), "GetPixelFormat failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetPixelFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&guidresult, &GUID_WICPixelFormat4bppIndexed), "unexpected pixel format\n"); hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&factory); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(SUCCEEDED(hr), "CreatePalette failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreatePalette failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_CopyPalette(decoder, palette); - ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %x\n", hr); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %lx\n", hr); hr = IWICBitmapFrameDecode_CopyPalette(framedecode, palette); - ok(SUCCEEDED(hr), "CopyPalette failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CopyPalette failed, hr=%lx\n", hr); hr = IWICPalette_GetColorCount(palette, &count); - ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColorCount failed, hr=%lx\n", hr); ok(count == 5, "expected count=5, got %u\n", count); hr = IWICPalette_GetColors(palette, 5, palettedata, &count); - ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColorCount failed, hr=%lx\n", hr); ok(count == 5, "expected count=5, got %u\n", count); ok(!memcmp(palettedata, expected_palettedata, sizeof(palettedata)), "unexpected palette data\n"); @@ -537,7 +536,7 @@ static void test_decode_4bpp(void) rc.Width = 2; rc.Height = 2; hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 1, sizeof(imagedata), imagedata); - ok(SUCCEEDED(hr), "CopyPixels failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CopyPixels failed, hr=%lx\n", hr); ok(!memcmp(imagedata, expected_imagedata, sizeof(imagedata)), "unexpected image data\n"); IWICBitmapFrameDecode_Release(framedecode); @@ -545,13 +544,13 @@ static void test_decode_4bpp(void) hr = CoCreateInstance(&CLSID_WICBmpDecoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void**)&decoder2); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_QueryCapability(decoder2, bmpstream, &capability); - ok(hr == S_OK, "QueryCapability failed, hr=%x\n", hr); + ok(hr == S_OK, "QueryCapability failed, hr=%lx\n", hr); ok(capability == (WICBitmapDecoderCapabilityCanDecodeAllImages), - "unexpected capabilities: %x\n", capability); + "unexpected capabilities: %lx\n", capability); IWICBitmapDecoder_Release(decoder2); } @@ -635,7 +634,7 @@ static void test_decode_rle8(void) hr = CoCreateInstance(&CLSID_WICBmpDecoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void**)&decoder); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); if (FAILED(hr)) return; hbmpdata = GlobalAlloc(GMEM_MOVEABLE, sizeof(testbmp_rle8)); @@ -647,62 +646,62 @@ static void test_decode_rle8(void) GlobalUnlock(hbmpdata); hr = CreateStreamOnHGlobal(hbmpdata, FALSE, &bmpstream); - ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_Initialize(decoder, bmpstream, WICDecodeMetadataCacheOnLoad); - ok(hr == S_OK, "Initialize failed, hr=%x\n", hr); + ok(hr == S_OK, "Initialize failed, hr=%lx\n", hr); hr = IWICBitmapDecoder_GetContainerFormat(decoder, &guidresult); - ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&guidresult, &GUID_ContainerFormatBmp), "unexpected container format\n"); hr = IWICBitmapDecoder_GetFrameCount(decoder, &count); - ok(SUCCEEDED(hr), "GetFrameCount failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetFrameCount failed, hr=%lx\n", hr); ok(count == 1, "unexpected count %u\n", count); hr = IWICBitmapDecoder_GetFrame(decoder, 0, &framedecode); - ok(SUCCEEDED(hr), "GetFrame failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetFrame failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { IWICImagingFactory *factory; IWICPalette *palette; hr = IWICBitmapFrameDecode_GetSize(framedecode, &width, &height); - ok(SUCCEEDED(hr), "GetSize failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetSize failed, hr=%lx\n", hr); ok(width == 8, "expected width=8, got %u\n", width); ok(height == 8, "expected height=8, got %u\n", height); hr = IWICBitmapFrameDecode_GetResolution(framedecode, &dpiX, &dpiY); - ok(SUCCEEDED(hr), "GetResolution failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetResolution failed, hr=%lx\n", hr); ok(fabs(dpiX - 72.0) < 0.01, "expected dpiX=96.0, got %f\n", dpiX); ok(fabs(dpiY - 72.0) < 0.01, "expected dpiY=96.0, got %f\n", dpiY); hr = IWICBitmapFrameDecode_GetPixelFormat(framedecode, &guidresult); - ok(SUCCEEDED(hr), "GetPixelFormat failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetPixelFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&guidresult, &GUID_WICPixelFormat32bppBGR), "unexpected pixel format\n"); hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&factory); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(SUCCEEDED(hr), "CreatePalette failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreatePalette failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_CopyPalette(decoder, palette); - ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %x\n", hr); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %lx\n", hr); hr = IWICBitmapFrameDecode_CopyPalette(framedecode, palette); - ok(SUCCEEDED(hr), "CopyPalette failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CopyPalette failed, hr=%lx\n", hr); hr = IWICPalette_GetColorCount(palette, &count); - ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColorCount failed, hr=%lx\n", hr); ok(count == 17, "expected count=17, got %u\n", count); hr = IWICPalette_GetColors(palette, 17, palettedata, &count); - ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColorCount failed, hr=%lx\n", hr); ok(count == 17, "expected count=17, got %u\n", count); ok(!memcmp(palettedata, expected_palettedata, sizeof(palettedata)), "unexpected palette data\n"); @@ -717,7 +716,7 @@ static void test_decode_rle8(void) rc.Width = 8; rc.Height = 8; hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 32, sizeof(imagedata), (BYTE*)imagedata); - ok(SUCCEEDED(hr), "CopyPixels failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CopyPixels failed, hr=%lx\n", hr); ok(!memcmp(imagedata, expected_imagedata, sizeof(imagedata)), "unexpected image data\n"); IWICBitmapFrameDecode_Release(framedecode); @@ -725,13 +724,13 @@ static void test_decode_rle8(void) hr = CoCreateInstance(&CLSID_WICBmpDecoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void**)&decoder2); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_QueryCapability(decoder2, bmpstream, &capability); - ok(hr == S_OK, "QueryCapability failed, hr=%x\n", hr); + ok(hr == S_OK, "QueryCapability failed, hr=%lx\n", hr); ok(capability == (WICBitmapDecoderCapabilityCanDecodeAllImages), - "unexpected capabilities: %x\n", capability); + "unexpected capabilities: %lx\n", capability); IWICBitmapDecoder_Release(decoder2); } @@ -802,7 +801,7 @@ static void test_decode_rle4(void) hr = CoCreateInstance(&CLSID_WICBmpDecoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void**)&decoder); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); if (FAILED(hr)) return; hbmpdata = GlobalAlloc(GMEM_MOVEABLE, sizeof(testbmp_rle4)); @@ -814,62 +813,62 @@ static void test_decode_rle4(void) GlobalUnlock(hbmpdata); hr = CreateStreamOnHGlobal(hbmpdata, FALSE, &bmpstream); - ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_Initialize(decoder, bmpstream, WICDecodeMetadataCacheOnLoad); - ok(hr == S_OK, "Initialize failed, hr=%x\n", hr); + ok(hr == S_OK, "Initialize failed, hr=%lx\n", hr); hr = IWICBitmapDecoder_GetContainerFormat(decoder, &guidresult); - ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&guidresult, &GUID_ContainerFormatBmp), "unexpected container format\n"); hr = IWICBitmapDecoder_GetFrameCount(decoder, &count); - ok(SUCCEEDED(hr), "GetFrameCount failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetFrameCount failed, hr=%lx\n", hr); ok(count == 1, "unexpected count %u\n", count); hr = IWICBitmapDecoder_GetFrame(decoder, 0, &framedecode); - ok(SUCCEEDED(hr), "GetFrame failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetFrame failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { IWICImagingFactory *factory; IWICPalette *palette; hr = IWICBitmapFrameDecode_GetSize(framedecode, &width, &height); - ok(SUCCEEDED(hr), "GetSize failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetSize failed, hr=%lx\n", hr); ok(width == 8, "expected width=8, got %u\n", width); ok(height == 8, "expected height=8, got %u\n", height); hr = IWICBitmapFrameDecode_GetResolution(framedecode, &dpiX, &dpiY); - ok(SUCCEEDED(hr), "GetResolution failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetResolution failed, hr=%lx\n", hr); ok(fabs(dpiX - 72.0) < 0.01, "expected dpiX=96.0, got %f\n", dpiX); ok(fabs(dpiY - 72.0) < 0.01, "expected dpiY=96.0, got %f\n", dpiY); hr = IWICBitmapFrameDecode_GetPixelFormat(framedecode, &guidresult); - ok(SUCCEEDED(hr), "GetPixelFormat failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetPixelFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&guidresult, &GUID_WICPixelFormat32bppBGR), "unexpected pixel format\n"); hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&factory); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(SUCCEEDED(hr), "CreatePalette failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreatePalette failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_CopyPalette(decoder, palette); - ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %x\n", hr); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %lx\n", hr); hr = IWICBitmapFrameDecode_CopyPalette(framedecode, palette); - ok(SUCCEEDED(hr), "CopyPalette failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CopyPalette failed, hr=%lx\n", hr); hr = IWICPalette_GetColorCount(palette, &count); - ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColorCount failed, hr=%lx\n", hr); ok(count == 6, "expected count=6, got %u\n", count); hr = IWICPalette_GetColors(palette, 6, palettedata, &count); - ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColorCount failed, hr=%lx\n", hr); ok(count == 6, "expected count=6, got %u\n", count); ok(!memcmp(palettedata, expected_palettedata, sizeof(palettedata)), "unexpected palette data\n"); @@ -884,7 +883,7 @@ static void test_decode_rle4(void) rc.Width = 8; rc.Height = 8; hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 32, sizeof(imagedata), (BYTE*)imagedata); - ok(SUCCEEDED(hr), "CopyPixels failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CopyPixels failed, hr=%lx\n", hr); ok(!memcmp(imagedata, expected_imagedata, sizeof(imagedata)), "unexpected image data\n"); IWICBitmapFrameDecode_Release(framedecode); @@ -892,13 +891,13 @@ static void test_decode_rle4(void) hr = CoCreateInstance(&CLSID_WICBmpDecoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void**)&decoder2); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_QueryCapability(decoder2, bmpstream, &capability); - ok(hr == S_OK, "QueryCapability failed, hr=%x\n", hr); + ok(hr == S_OK, "QueryCapability failed, hr=%lx\n", hr); ok(capability == (WICBitmapDecoderCapabilityCanDecodeAllImages), - "unexpected capabilities: %x\n", capability); + "unexpected capabilities: %lx\n", capability); IWICBitmapDecoder_Release(decoder2); } @@ -911,6 +910,142 @@ static void test_decode_rle4(void) IWICBitmapDecoder_Release(decoder); } +static const char testbmp_bitfields_abgr[] = { + /* BITMAPFILEHEADER */ + 'B','M', /* "BM" */ + sizeof(BITMAPFILEHEADER)+sizeof(BITMAPV5HEADER)+8,0,0,0, /* file size */ + 0,0,0,0, /* reserved */ + sizeof(BITMAPFILEHEADER)+sizeof(BITMAPV5HEADER),0,0,0, /* offset to bits */ + /* BITMAPV5HEADER */ + sizeof(BITMAPV5HEADER),0,0,0, /* size */ + 2,0,0,0, /* width */ + 1,0,0,0, /* height */ + 1,0, /* planes */ + 32,0, /* bit count */ + BI_BITFIELDS,0,0,0, /* compression */ + 8,0,0,0, /* image size */ + 19,11,0,0, /* X pixels per meter */ + 19,11,0,0, /* Y pixels per meter */ + 0,0,0,0, /* colors used */ + 0,0,0,0, /* colors important */ + 0,0,0,255, /* red mask */ + 0,0,255,0, /* green mask */ + 0,255,0,0, /* blue mask */ + 255,0,0,0, /* alpha mask */ + 'B','G','R','s', /* color space */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, /* gamma */ + LCS_GM_GRAPHICS,0,0,0, /* intent */ + 0,0,0,0,0,0,0,0,0,0,0,0, + /* bits */ + 0,255,0,0,255,0,255,0 +}; + +static void test_decode_bitfields(void) +{ + IWICBitmapDecoder *decoder; + IWICBitmapFrameDecode *framedecode; + HRESULT hr; + HGLOBAL hbmpdata; + char *bmpdata; + IStream *bmpstream; + GUID guidresult; + UINT count=0, width=0, height=0; + double dpiX, dpiY; + DWORD imagedata[2] = {1}; + const DWORD expected_imagedata[2] = { 0xff, 0xff00 }; + WICRect rc; + + hr = CoCreateInstance(&CLSID_WICBmpDecoder, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICBitmapDecoder, (void**)&decoder); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); + if (FAILED(hr)) return; + + hbmpdata = GlobalAlloc(GMEM_MOVEABLE, sizeof(testbmp_bitfields_abgr)); + ok(hbmpdata != 0, "GlobalAlloc failed\n"); + if (hbmpdata) + { + bmpdata = GlobalLock(hbmpdata); + memcpy(bmpdata, testbmp_bitfields_abgr, sizeof(testbmp_bitfields_abgr)); + GlobalUnlock(hbmpdata); + + hr = CreateStreamOnHGlobal(hbmpdata, FALSE, &bmpstream); + ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%lx\n", hr); + if (SUCCEEDED(hr)) + { + hr = IWICBitmapDecoder_Initialize(decoder, bmpstream, WICDecodeMetadataCacheOnLoad); + ok(hr == S_OK, "Initialize failed, hr=%lx\n", hr); + + hr = IWICBitmapDecoder_GetContainerFormat(decoder, &guidresult); + ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%lx\n", hr); + ok(IsEqualGUID(&guidresult, &GUID_ContainerFormatBmp), "unexpected container format\n"); + + hr = IWICBitmapDecoder_GetFrameCount(decoder, &count); + ok(SUCCEEDED(hr), "GetFrameCount failed, hr=%lx\n", hr); + ok(count == 1, "unexpected count %u\n", count); + + hr = IWICBitmapDecoder_GetFrame(decoder, 0, &framedecode); + ok(SUCCEEDED(hr), "GetFrame failed, hr=%lx\n", hr); + if (SUCCEEDED(hr)) + { + IWICImagingFactory *factory; + IWICPalette *palette; + + hr = IWICBitmapFrameDecode_GetSize(framedecode, &width, &height); + ok(SUCCEEDED(hr), "GetSize failed, hr=%lx\n", hr); + ok(width == 2, "expected width=2, got %u\n", width); + ok(height == 1, "expected height=1, got %u\n", height); + + hr = IWICBitmapFrameDecode_GetResolution(framedecode, &dpiX, &dpiY); + ok(SUCCEEDED(hr), "GetResolution failed, hr=%lx\n", hr); + ok(fabs(dpiX - 72.0) < 0.01, "expected dpiX=72.0, got %f\n", dpiX); + ok(fabs(dpiY - 72.0) < 0.01, "expected dpiY=72.0, got %f\n", dpiY); + + hr = IWICBitmapFrameDecode_GetPixelFormat(framedecode, &guidresult); + ok(SUCCEEDED(hr), "GetPixelFormat failed, hr=%lx\n", hr); + ok(IsEqualGUID(&guidresult, &GUID_WICPixelFormat32bppBGR), "unexpected pixel format\n"); + + hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICImagingFactory, (void**)&factory); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); + if (SUCCEEDED(hr)) + { + hr = IWICImagingFactory_CreatePalette(factory, &palette); + ok(SUCCEEDED(hr), "CreatePalette failed, hr=%lx\n", hr); + if (SUCCEEDED(hr)) + { + hr = IWICBitmapDecoder_CopyPalette(decoder, palette); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %lx\n", hr); + + hr = IWICBitmapFrameDecode_CopyPalette(framedecode, palette); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %lx\n", hr); + + IWICPalette_Release(palette); + } + + IWICImagingFactory_Release(factory); + } + + rc.X = 0; + rc.Y = 0; + rc.Width = 2; + rc.Height = 1; + hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 32, sizeof(imagedata), (BYTE*)imagedata); + ok(SUCCEEDED(hr), "CopyPixels failed, hr=%lx\n", hr); + ok(!memcmp(imagedata, expected_imagedata, sizeof(imagedata)), "unexpected image data\n"); + + IWICBitmapFrameDecode_Release(framedecode); + } + + IStream_Release(bmpstream); + } + + GlobalFree(hbmpdata); + } + + IWICBitmapDecoder_Release(decoder); +} + static void test_componentinfo(void) { IWICImagingFactory *factory; @@ -929,31 +1064,31 @@ static void test_componentinfo(void) hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&factory); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICImagingFactory_CreateComponentInfo(factory, &CLSID_WICBmpDecoder, &info); - ok(SUCCEEDED(hr), "CreateComponentInfo failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreateComponentInfo failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICComponentInfo_GetComponentType(info, &type); - ok(SUCCEEDED(hr), "GetComponentType failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetComponentType failed, hr=%lx\n", hr); ok(type == WICDecoder, "got %i, expected WICDecoder\n", type); hr = IWICComponentInfo_QueryInterface(info, &IID_IWICBitmapDecoderInfo, (void**)&decoderinfo); - ok(SUCCEEDED(hr), "QueryInterface failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "QueryInterface failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { pattern_count = 0; pattern_size = 0; hr = IWICBitmapDecoderInfo_GetPatterns(decoderinfo, 0, NULL, &pattern_count, &pattern_size); - ok(SUCCEEDED(hr), "GetPatterns failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetPatterns failed, hr=%lx\n", hr); ok(pattern_count != 0, "pattern count is 0\n"); ok(pattern_size > pattern_count * sizeof(WICBitmapPattern), "size=%i, count=%i\n", pattern_size, pattern_count); patterns = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, pattern_size); hr = IWICBitmapDecoderInfo_GetPatterns(decoderinfo, pattern_size, patterns, &pattern_count, &pattern_size); - ok(SUCCEEDED(hr), "GetPatterns failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetPatterns failed, hr=%lx\n", hr); ok(pattern_count != 0, "pattern count is 0\n"); ok(pattern_size > pattern_count * sizeof(WICBitmapPattern), "size=%i, count=%i\n", pattern_size, pattern_count); ok(patterns[0].Length != 0, "pattern length is 0\n"); @@ -962,16 +1097,16 @@ static void test_componentinfo(void) pattern_size -= 1; hr = IWICBitmapDecoderInfo_GetPatterns(decoderinfo, pattern_size, patterns, &pattern_count, &pattern_size); - ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "GetPatterns returned %x, expected WINCODEC_ERR_INSUFFICIENTBUFFER\n", hr); + ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "GetPatterns returned %lx, expected WINCODEC_ERR_INSUFFICIENTBUFFER\n", hr); HeapFree(GetProcessHeap(), 0, patterns); hr = IWICBitmapDecoderInfo_CreateInstance(decoderinfo, &decoder); - ok(SUCCEEDED(hr), "CreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreateInstance failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_GetContainerFormat(decoder, &guidresult); - ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&guidresult, &GUID_ContainerFormatBmp), "unexpected container format\n"); IWICBitmapDecoder_Release(decoder); @@ -986,12 +1121,12 @@ static void test_componentinfo(void) GlobalUnlock(hbmpdata); hr = CreateStreamOnHGlobal(hbmpdata, FALSE, &bmpstream); - ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { boolresult = 0; hr = IWICBitmapDecoderInfo_MatchesPattern(decoderinfo, bmpstream, &boolresult); - ok(SUCCEEDED(hr), "MatchesPattern failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "MatchesPattern failed, hr=%lx\n", hr); ok(boolresult, "pattern not matched\n"); IStream_Release(bmpstream); @@ -1022,7 +1157,7 @@ static void test_createfromstream(void) hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&factory); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); if (FAILED(hr)) return; hbmpdata = GlobalAlloc(GMEM_MOVEABLE, sizeof(testbmp_1bpp)); @@ -1034,16 +1169,16 @@ static void test_createfromstream(void) GlobalUnlock(hbmpdata); hr = CreateStreamOnHGlobal(hbmpdata, FALSE, &bmpstream); - ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICImagingFactory_CreateDecoderFromStream(factory, bmpstream, NULL, WICDecodeMetadataCacheOnDemand, &decoder); - ok(SUCCEEDED(hr), "CreateDecoderFromStream failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreateDecoderFromStream failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_GetContainerFormat(decoder, &guidresult); - ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&guidresult, &GUID_ContainerFormatBmp), "unexpected container format\n"); IWICBitmapDecoder_Release(decoder); @@ -1066,22 +1201,269 @@ static void test_create_decoder(void) hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void **)&factory); - ok(hr == S_OK, "CoCreateInstance error %#x\n", hr); + ok(hr == S_OK, "CoCreateInstance error %#lx\n", hr); hr = IWICImagingFactory_CreateDecoder(factory, NULL, NULL, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICImagingFactory_CreateDecoder(factory, NULL, NULL, &decoder); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICImagingFactory_CreateDecoder(factory, &GUID_ContainerFormatBmp, NULL, &decoder); - ok(hr == S_OK, "CreateDecoder error %#x\n", hr); + ok(hr == S_OK, "CreateDecoder error %#lx\n", hr); IWICBitmapDecoder_Release(decoder); hr = IWICImagingFactory_CreateDecoder(factory, &GUID_ContainerFormatBmp, &GUID_VendorMicrosoft, &decoder); - ok(hr == S_OK, "CreateDecoder error %#x\n", hr); + ok(hr == S_OK, "CreateDecoder error %#lx\n", hr); + IWICBitmapDecoder_Release(decoder); + + IWICImagingFactory_Release(factory); +} + +static void test_writesource_palette(void) +{ + IWICImagingFactory *factory; + HRESULT hr; + WICColor encode_palette[2] = {0xff111111, 0xffcccccc}; + WICColor source_palette[2] = {0xff555555, 0xffaaaaaa}; + WICColor result_palette[2]; + UINT result_colors; + IWICBitmap *bitmap; + IWICPalette *palette; + IStream *stream; + IWICBitmapEncoder *encoder; + IWICBitmapFrameEncode *frame_encode; + IPropertyBag2 *encode_options; + GUID pixelformat; + IWICBitmapDecoder *decoder; + IWICBitmapFrameDecode *frame_decode; + + hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICImagingFactory, (void **)&factory); + ok(hr == S_OK, "CoCreateInstance error %#lx\n", hr); + + /* Encoder with palette set */ + hr = IWICImagingFactory_CreateBitmap(factory, 1, 1, &GUID_WICPixelFormat1bppIndexed, + WICBitmapCacheOnDemand, &bitmap); + ok(hr == S_OK, "CreateBitmap error %#lx\n", hr); + + hr = IWICImagingFactory_CreatePalette(factory, &palette); + ok(hr == S_OK, "CreatePalette error %#lx\n", hr); + + hr = CreateStreamOnHGlobal(NULL, TRUE, &stream); + ok(hr == S_OK, "CreateStream error %#lx\n", hr); + + hr = IWICImagingFactory_CreateEncoder(factory, &GUID_ContainerFormatBmp, &GUID_VendorMicrosoft, &encoder); + ok(hr == S_OK, "CreateDecoder error %#lx\n", hr); + + hr = IWICBitmapEncoder_Initialize(encoder, stream, WICBitmapEncoderNoCache); + ok(hr == S_OK, "IWICBitmapEncoder_Initialize error %#lx\n", hr); + + hr = IWICBitmapEncoder_CreateNewFrame(encoder, &frame_encode, &encode_options); + ok(hr == S_OK, "CreateNewFrame error %#lx\n", hr); + + hr = IWICBitmapFrameEncode_Initialize(frame_encode, encode_options); + ok(hr == S_OK, "IWICBitmapFrameEncode_Initialize error %#lx\n", hr); + + IPropertyBag2_Release(encode_options); + + hr = IWICBitmapFrameEncode_SetSize(frame_encode, 1, 1); + ok(hr == S_OK, "SetSize error %#lx\n", hr); + + pixelformat = GUID_WICPixelFormat1bppIndexed; + hr = IWICBitmapFrameEncode_SetPixelFormat(frame_encode, &pixelformat); + ok(hr == S_OK, "SetPixelFormat error %#lx\n", hr); + ok(!memcmp(&pixelformat, &GUID_WICPixelFormat1bppIndexed, sizeof(pixelformat)), "pixel format changed\n"); + + hr = IWICPalette_InitializeCustom(palette, encode_palette, 2); + ok(hr == S_OK, "InitializeCustom error %#lx\n", hr); + + hr = IWICBitmapFrameEncode_SetPalette(frame_encode, palette); + ok(hr == S_OK, "SetPalette error %#lx\n", hr); + + hr = IWICPalette_InitializeCustom(palette, source_palette, 2); + ok(hr == S_OK, "InitializeCustom error %#lx\n", hr); + + hr = IWICBitmap_SetPalette(bitmap, palette); + ok(hr == S_OK, "SetPalette error %#lx\n", hr); + + hr = IWICBitmapFrameEncode_WriteSource(frame_encode, (IWICBitmapSource*)bitmap, NULL); + ok(hr == S_OK, "WriteSource error %#lx\n", hr); + + hr = IWICBitmapFrameEncode_Commit(frame_encode); + ok(hr == S_OK, "Commit error %#lx\n", hr); + + IWICBitmapFrameEncode_Release(frame_encode); + + hr = IWICBitmapEncoder_Commit(encoder); + ok(hr == S_OK, "Commit error %#lx\n", hr); + + IWICBitmapEncoder_Release(encoder); + + hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, WICDecodeMetadataCacheOnLoad, &decoder); + ok(hr == S_OK, "CreateDecoderFromStream error %#lx\n", hr); + + hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame_decode); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); + + hr = IWICBitmapFrameDecode_CopyPalette(frame_decode, palette); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); + + hr = IWICPalette_GetColors(palette, 2, result_palette, &result_colors); + ok(hr == S_OK, "GetColors error %#lx\n", hr); + ok(result_colors == 2, "Got %i colors\n", result_colors); + ok(result_palette[0] == encode_palette[0], "Unexpected palette entry: %x\n", result_palette[0]); + ok(result_palette[1] == encode_palette[1], "Unexpected palette entry: %x\n", result_palette[0]); + + IWICBitmapFrameDecode_Release(frame_decode); + IWICBitmapDecoder_Release(decoder); + IStream_Release(stream); + + /* Encoder with no palette set */ + hr = IWICImagingFactory_CreateEncoder(factory, &GUID_ContainerFormatBmp, &GUID_VendorMicrosoft, &encoder); + ok(hr == S_OK, "CreateDecoder error %#lx\n", hr); + + hr = CreateStreamOnHGlobal(NULL, TRUE, &stream); + ok(hr == S_OK, "CreateStream error %#lx\n", hr); + + hr = IWICBitmapEncoder_Initialize(encoder, stream, WICBitmapEncoderNoCache); + ok(hr == S_OK, "IWICBitmapEncoder_Initialize error %#lx\n", hr); + + hr = IWICBitmapEncoder_CreateNewFrame(encoder, &frame_encode, &encode_options); + ok(hr == S_OK, "CreateNewFrame error %#lx\n", hr); + + hr = IWICBitmapFrameEncode_Initialize(frame_encode, encode_options); + ok(hr == S_OK, "IWICBitmapFrameEncode_Initialize error %#lx\n", hr); + + IPropertyBag2_Release(encode_options); + + hr = IWICBitmapFrameEncode_SetSize(frame_encode, 1, 1); + ok(hr == S_OK, "SetSize error %#lx\n", hr); + + pixelformat = GUID_WICPixelFormat1bppIndexed; + hr = IWICBitmapFrameEncode_SetPixelFormat(frame_encode, &pixelformat); + ok(hr == S_OK, "SetPixelFormat error %#lx\n", hr); + ok(!memcmp(&pixelformat, &GUID_WICPixelFormat1bppIndexed, sizeof(pixelformat)), "pixel format changed\n"); + + hr = IWICPalette_InitializeCustom(palette, source_palette, 2); + ok(hr == S_OK, "InitializeCustom error %#lx\n", hr); + + hr = IWICBitmap_SetPalette(bitmap, palette); + ok(hr == S_OK, "SetPalette error %#lx\n", hr); + + hr = IWICBitmapFrameEncode_WriteSource(frame_encode, (IWICBitmapSource*)bitmap, NULL); + if (hr == WINCODEC_ERR_PALETTEUNAVAILABLE) + { + win_skip("old WriteSource palette behavior\n"); /* winxp */ + IWICBitmapFrameEncode_Release(frame_encode); + IWICBitmapEncoder_Release(encoder); + IStream_Release(stream); + IWICPalette_Release(palette); + IWICBitmap_Release(bitmap); + IWICImagingFactory_Release(factory); + return; + } + ok(hr == S_OK, "WriteSource error %#lx\n", hr); + + hr = IWICBitmapFrameEncode_Commit(frame_encode); + ok(hr == S_OK, "Commit error %#lx\n", hr); + + IWICBitmapFrameEncode_Release(frame_encode); + + hr = IWICBitmapEncoder_Commit(encoder); + ok(hr == S_OK, "Commit error %#lx\n", hr); + + IWICBitmapEncoder_Release(encoder); + + hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, WICDecodeMetadataCacheOnLoad, &decoder); + ok(hr == S_OK, "CreateDecoderFromStream error %#lx\n", hr); + + hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame_decode); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); + + hr = IWICBitmapFrameDecode_CopyPalette(frame_decode, palette); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); + + hr = IWICPalette_GetColors(palette, 2, result_palette, &result_colors); + ok(hr == S_OK, "GetColors error %#lx\n", hr); + ok(result_colors == 2, "Got %i colors\n", result_colors); + ok(result_palette[0] == source_palette[0], "Unexpected palette entry: %x\n", result_palette[0]); + ok(result_palette[1] == source_palette[1], "Unexpected palette entry: %x\n", result_palette[0]); + + IWICBitmapFrameDecode_Release(frame_decode); IWICBitmapDecoder_Release(decoder); + IStream_Release(stream); + + IWICPalette_Release(palette); + IWICBitmap_Release(bitmap); + IWICImagingFactory_Release(factory); +} + +static void test_encoder_formats(void) +{ + static const struct + { + const GUID *format; + BOOL supported; + const char *name; + } + tests[] = + { + {&GUID_WICPixelFormat24bppBGR, TRUE, "WICPixelFormat24bppBGR"}, + {&GUID_WICPixelFormatBlackWhite, FALSE, "WICPixelFormatBlackWhite"}, + {&GUID_WICPixelFormat1bppIndexed, TRUE, "WICPixelFormat1bppIndexed"}, + {&GUID_WICPixelFormat2bppIndexed, FALSE, "WICPixelFormat2bppIndexed"}, + {&GUID_WICPixelFormat4bppIndexed, TRUE, "WICPixelFormat4bppIndexed"}, + {&GUID_WICPixelFormat8bppIndexed, TRUE, "WICPixelFormat8bppIndexed"}, + {&GUID_WICPixelFormat16bppBGR555, TRUE, "WICPixelFormat16bppBGR555"}, + {&GUID_WICPixelFormat16bppBGR565, TRUE, "WICPixelFormat16bppBGR565"}, + {&GUID_WICPixelFormat32bppBGR, TRUE, "WICPixelFormat32bppBGR"}, + {&GUID_WICPixelFormat32bppBGRA, TRUE, "WICPixelFormat32bppBGRA"}, + {&GUID_WICPixelFormat8bppGray, FALSE, "WICPixelFormat8bppGray"}, + }; + + IWICImagingFactory *factory; + HRESULT hr; + IStream *stream; + IWICBitmapEncoder *encoder; + IWICBitmapFrameEncode *frame_encode; + GUID pixelformat; + LONG refcount; + unsigned int i; + BOOL supported; + + hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICImagingFactory, (void **)&factory); + ok(hr == S_OK, "got %#lx.\n", hr); + + hr = CreateStreamOnHGlobal(NULL, TRUE, &stream); + ok(hr == S_OK, "got %#lx.\n", hr); + + hr = IWICImagingFactory_CreateEncoder(factory, &GUID_ContainerFormatBmp, &GUID_VendorMicrosoft, &encoder); + ok(hr == S_OK, "got %#lx.\n", hr); + + hr = IWICBitmapEncoder_Initialize(encoder, stream, WICBitmapEncoderNoCache); + ok(hr == S_OK, "got %#lx.\n", hr); + hr = IWICBitmapEncoder_CreateNewFrame(encoder, &frame_encode, NULL); + ok(hr == S_OK, "got %#lx.\n", hr); + hr = IWICBitmapFrameEncode_Initialize(frame_encode, NULL); + ok(hr == S_OK, "got %#lx.\n", hr); + + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + winetest_push_context("%s", tests[i].name); + pixelformat = *tests[i].format; + hr = IWICBitmapFrameEncode_SetPixelFormat(frame_encode, &pixelformat); + ok(hr == S_OK, "got %#lx.\n", hr); + supported = !memcmp(&pixelformat, tests[i].format, sizeof(pixelformat)); + ok(supported == tests[i].supported, "got %d.\n", supported); + winetest_pop_context(); + } + IWICBitmapFrameEncode_Release(frame_encode); + refcount = IWICBitmapEncoder_Release(encoder); + ok(!refcount, "got %ld.\n", refcount); + IStream_Release(stream); IWICImagingFactory_Release(factory); } @@ -1094,9 +1476,12 @@ START_TEST(bmpformat) test_decode_4bpp(); test_decode_rle8(); test_decode_rle4(); + test_decode_bitfields(); test_componentinfo(); test_createfromstream(); test_create_decoder(); + test_writesource_palette(); + test_encoder_formats(); CoUninitialize(); } diff --git a/modules/rostests/winetests/windowscodecs/converter.c b/modules/rostests/winetests/windowscodecs/converter.c index 348d5a8cb21cd..f6cef841d56cc 100644 --- a/modules/rostests/winetests/windowscodecs/converter.c +++ b/modules/rostests/winetests/windowscodecs/converter.c @@ -227,7 +227,7 @@ static void CreateTestBitmap(const bitmap_data *data, BitmapTestSrc **This) static void DeleteTestBitmap(BitmapTestSrc *This) { ok(This->IWICBitmapSource_iface.lpVtbl == &BitmapTestSrc_Vtbl, "test bitmap %p deleted with incorrect vtable\n", This); - ok(This->ref == 1, "test bitmap %p deleted with %i references instead of 1\n", This, This->ref); + ok(This->ref == 1, "test bitmap %p deleted with %li references instead of 1\n", This, This->ref); HeapFree(GetProcessHeap(), 0, This); } @@ -335,17 +335,17 @@ static void compare_bitmap_data(const struct bitmap_data *src, const struct bitm HRESULT hr; hr = IWICBitmapSource_GetSize(source, &width, &height); - ok(SUCCEEDED(hr), "GetSize(%s) failed, hr=%x\n", name, hr); + ok(SUCCEEDED(hr), "GetSize(%s) failed, hr=%lx\n", name, hr); ok(width == expect->width, "expecting %u, got %u (%s)\n", expect->width, width, name); ok(height == expect->height, "expecting %u, got %u (%s)\n", expect->height, height, name); hr = IWICBitmapSource_GetResolution(source, &xres, &yres); - ok(SUCCEEDED(hr), "GetResolution(%s) failed, hr=%x\n", name, hr); + ok(SUCCEEDED(hr), "GetResolution(%s) failed, hr=%lx\n", name, hr); ok(fabs(xres - expect->xres) < 0.02, "expecting %0.2f, got %0.2f (%s)\n", expect->xres, xres, name); ok(fabs(yres - expect->yres) < 0.02, "expecting %0.2f, got %0.2f (%s)\n", expect->yres, yres, name); hr = IWICBitmapSource_GetPixelFormat(source, &dst_pixelformat); - ok(SUCCEEDED(hr), "GetPixelFormat(%s) failed, hr=%x\n", name, hr); + ok(SUCCEEDED(hr), "GetPixelFormat(%s) failed, hr=%lx\n", name, hr); ok(IsEqualGUID(&dst_pixelformat, expect->format), "got unexpected pixel format %s (%s)\n", wine_dbgstr_guid(&dst_pixelformat), name); prc.X = 0; @@ -359,7 +359,7 @@ static void compare_bitmap_data(const struct bitmap_data *src, const struct bitm converted_bits = HeapAlloc(GetProcessHeap(), 0, buffersize); memset(converted_bits, 0xaa, buffersize); hr = IWICBitmapSource_CopyPixels(source, &prc, stride, buffersize, converted_bits); - ok(SUCCEEDED(hr), "CopyPixels(%s) failed, hr=%x\n", name, hr); + ok(SUCCEEDED(hr), "CopyPixels(%s) failed, hr=%lx\n", name, hr); /* The result of conversion of color to indexed formats depends on * optimized palette generation implementation. We either need to @@ -371,7 +371,7 @@ static void compare_bitmap_data(const struct bitmap_data *src, const struct bitm /* Test with NULL rectangle - should copy the whole bitmap */ memset(converted_bits, 0xaa, buffersize); hr = IWICBitmapSource_CopyPixels(source, NULL, stride, buffersize, converted_bits); - ok(SUCCEEDED(hr), "CopyPixels(%s,rc=NULL) failed, hr=%x\n", name, hr); + ok(SUCCEEDED(hr), "CopyPixels(%s,rc=NULL) failed, hr=%lx\n", name, hr); /* see comment above */ if (!(!is_indexed_format(src->format) && is_indexed_format(expect->format))) ok(compare_bits(expect, buffersize, converted_bits), "unexpected pixel data (%s)\n", name); @@ -453,13 +453,21 @@ static const BYTE bits_32bppBGR[] = { 0,255,255,80, 255,0,255,80, 255,255,0,80, 255,255,255,80, 0,255,255,80, 255,0,255,80, 255,255,0,80, 255,255,255,80, 0,255,255,80, 255,0,255,80, 255,255,0,80, 255,255,255,80, 0,255,255,80, 255,0,255,80, 255,255,0,80, 255,255,255,80, 0,255,255,80, 255,0,255,80, 255,255,0,80, 255,255,255,80, 0,255,255,80, 255,0,255,80, 255,255,0,80, 255,255,255,80, - 0,255,255,80, 255,0,255,80, 255,255,0,80, 255,255,255,80, 0,255,255,80, 255,0,255,80, 255,255,0,80, 255,255,255,80}; + 0,255,255,80, 255,0,255,80, 255,255,0,80, 255,255,255,80, 0,255,255,80, 255,0,255,80, 255,255,0,80, 255,255,255,80, + 3,3,3,80, 6,6,6,80, 12,12,12,80, 15,15,15,80, 19,19,19,80, 22,22,22,80, 28,28,28,80, 31,31,31,80, + 35,35,35,80, 38,38,38,80, 41,41,41,80, 47,47,47,80, 47,47,47,80, 54,54,54,80, 57,57,57,80, 63,63,63,80, + 66,66,66,80, 70,70,70,80, 73,73,73,80, 79,79,79,80, 82,82,82,80, 86,86,86,80, 89,89,89,80, 95,95,95,80, + 98,98,98,80, 98,98,98,80, 105,105,105,80, 108,108,108,80, 114,114,114,80, 117,117,117,80, 121,121,121,80, 124,124,124,80, + 130,130,130,80, 133,133,133,80, 137,137,137,80, 140,140,140,80, 146,146,146,80, 149,149,149,80, 156,156,156,80, 156,156,156,80, + 159,159,159,80, 165,165,165,80, 168,168,168,80, 172,172,172,80, 175,175,175,80, 181,181,181,80, 184,184,184,80, 188,188,188,80, + 191,191,191,80, 197,197,197,80, 200,200,200,80, 207,207,207,80, 207,207,207,80, 213,213,213,80, 216,216,216,80, 219,219,219,80, + 223,223,223,80, 226,226,226,80, 232,232,232,80, 235,235,235,80, 239,239,239,80, 242,242,242,80, 248,248,248,80, 251,251,251,80}; static const struct bitmap_data testdata_32bppBGR = { &GUID_WICPixelFormat32bppBGR, 32, bits_32bppBGR, 32, 2, 96.0, 96.0}; static const struct bitmap_data testdata_32bppBGRA80 = { - &GUID_WICPixelFormat32bppBGRA, 32, bits_32bppBGR, 32, 2, 96.0, 96.0}; + &GUID_WICPixelFormat32bppBGRA, 32, bits_32bppBGR, 32, 4, 96.0, 96.0}; static const struct bitmap_data testdata_32bppRGBA80 = { - &GUID_WICPixelFormat32bppRGBA, 32, bits_32bppBGR, 32, 2, 96.0, 96.0}; + &GUID_WICPixelFormat32bppRGBA, 32, bits_32bppBGR, 32, 4, 96.0, 96.0}; static const BYTE bits_32bppBGRA[] = { 255,0,0,255, 0,255,0,255, 0,0,255,255, 0,0,0,255, 255,0,0,255, 0,255,0,255, 0,0,255,255, 0,0,0,255, @@ -469,13 +477,31 @@ static const BYTE bits_32bppBGRA[] = { 0,255,255,255, 255,0,255,255, 255,255,0,255, 255,255,255,255, 0,255,255,255, 255,0,255,255, 255,255,0,255, 255,255,255,255, 0,255,255,255, 255,0,255,255, 255,255,0,255, 255,255,255,255, 0,255,255,255, 255,0,255,255, 255,255,0,255, 255,255,255,255, 0,255,255,255, 255,0,255,255, 255,255,0,255, 255,255,255,255, 0,255,255,255, 255,0,255,255, 255,255,0,255, 255,255,255,255, - 0,255,255,255, 255,0,255,255, 255,255,0,255, 255,255,255,255, 0,255,255,255, 255,0,255,255, 255,255,0,255, 255,255,255,255}; + 0,255,255,255, 255,0,255,255, 255,255,0,255, 255,255,255,255, 0,255,255,255, 255,0,255,255, 255,255,0,255, 255,255,255,255, + 3,3,3,255, 6,6,6,255, 12,12,12,255, 15,15,15,255, 19,19,19,255, 22,22,22,255, 28,28,28,255, 31,31,31,80, + 35,35,35,255, 38,38,38,255, 41,41,41,255, 47,47,47,255, 47,47,47,255, 54,54,54,255, 57,57,57,255, 63,63,63,80, + 66,66,66,255, 70,70,70,255, 73,73,73,255, 79,79,79,255, 82,82,82,255, 86,86,86,255, 89,89,89,255, 95,95,95,80, + 98,98,98,255, 98,98,98,255, 105,105,105,255, 108,108,108,255, 114,114,114,255, 117,117,117,255, 121,121,121,255, 124,124,124,80, + 130,130,130,255, 133,133,133,255, 137,137,137,255, 140,140,140,255, 146,146,146,255, 149,149,149,255, 156,156,156,255, 156,156,156,80, + 159,159,159,255, 165,165,165,255, 168,168,168,255, 172,172,172,255, 175,175,175,255, 181,181,181,255, 184,184,184,255, 188,188,188,80, + 191,191,191,255, 197,197,197,255, 200,200,200,255, 207,207,207,255, 207,207,207,255, 213,213,213,255, 216,216,216,255, 219,219,219,80, + 223,223,223,255, 226,226,226,255, 232,232,232,255, 235,235,235,255, 239,239,239,255, 242,242,242,255, 248,248,248,255, 251,251,251,80}; +static const BYTE bits_32bppRGBA[] = { + 0,0,255,255, 0,255,0,255, 255,0,0,255, 0,0,0,255, 0,0,255,255, 0,255,0,255, 255,0,0,255, 0,0,0,255, + 0,0,255,255, 0,255,0,255, 255,0,0,255, 0,0,0,255, 0,0,255,255, 0,255,0,255, 255,0,0,255, 0,0,0,255, + 0,0,255,255, 0,255,0,255, 255,0,0,255, 0,0,0,255, 0,0,255,255, 0,255,0,255, 255,0,0,255, 0,0,0,255, + 0,0,255,255, 0,255,0,255, 255,0,0,255, 0,0,0,255, 0,0,255,255, 0,255,0,255, 255,0,0,255, 0,0,0,255, + 255,255,0,255, 255,0,255,255, 0,255,255,255, 255,255,255,255, 255,255,0,255, 255,0,255,255, 0,255,255,255, 255,255,255,255, + 255,255,0,255, 255,0,255,255, 0,255,255,255, 255,255,255,255, 255,255,0,255, 255,0,255,255, 0,255,255,255, 255,255,255,255, + 255,255,0,255, 255,0,255,255, 0,255,255,255, 255,255,255,255, 255,255,0,255, 255,0,255,255, 0,255,255,255, 255,255,255,255, + 255,255,0,255, 255,0,255,255, 0,255,255,255, 255,255,255,255, 255,255,0,255, 255,0,255,255, 0,255,255,255, 255,255,255,255}; + static const struct bitmap_data testdata_32bppBGRA = { &GUID_WICPixelFormat32bppBGRA, 32, bits_32bppBGRA, 32, 2, 96.0, 96.0}; static const struct bitmap_data testdata_32bppRGBA = { - &GUID_WICPixelFormat32bppRGBA, 32, bits_32bppBGRA, 32, 2, 96.0, 96.0}; + &GUID_WICPixelFormat32bppRGBA, 32, bits_32bppRGBA, 32, 2, 96.0, 96.0}; static const struct bitmap_data testdata_32bppRGB = { - &GUID_WICPixelFormat32bppRGB, 32, bits_32bppBGRA, 32, 2, 96.0, 96.0}; + &GUID_WICPixelFormat32bppRGB, 32, bits_32bppRGBA, 32, 2, 96.0, 96.0}; static const BYTE bits_32bppPBGRA[] = { 80,0,0,80, 0,80,0,80, 0,0,80,80, 0,0,0,80, 80,0,0,80, 0,80,0,80, 0,0,80,80, 0,0,0,80, @@ -485,21 +511,29 @@ static const BYTE bits_32bppPBGRA[] = { 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80, 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80, 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80, 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80, 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80, 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80, - 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80, 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80}; + 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80, 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80, + 1,1,1,80, 2,2,2,80, 4,4,4,80, 5,5,5,80, 6,6,6,80, 7,7,7,80, 9,9,9,80, 10,10,10,80, + 11,11,11,80, 12,12,12,80, 13,13,13,80, 15,15,15,80, 15,15,15,80, 17,17,17,80, 18,18,18,80, 20,20,20,80, + 21,21,21,80, 22,22,22,80, 23,23,23,80, 25,25,25,80, 26,26,26,80, 27,27,27,80, 28,28,28,80, 30,30,30,80, + 31,31,31,80, 31,31,31,80, 33,33,33,80, 34,34,34,80, 36,36,36,80, 37,37,37,80, 38,38,38,80, 39,39,39,80, + 41,41,41,80, 42,42,42,80, 43,43,43,80, 44,44,44,80, 46,46,46,80, 47,47,47,80, 49,49,49,80, 49,49,49,80, + 50,50,50,80, 52,52,52,80, 53,53,53,80, 54,54,54,80, 55,55,55,80, 57,57,57,80, 58,58,58,80, 59,59,59,80, + 60,60,60,80, 62,62,62,80, 63,63,63,80, 65,65,65,80, 65,65,65,80, 67,67,67,80, 68,68,68,80, 69,69,69,80, + 70,70,70,80, 71,71,71,80, 73,73,73,80, 74,74,74,80, 75,75,75,80, 76,76,76,80, 78,78,78,80, 79,79,79,80}; static const struct bitmap_data testdata_32bppPBGRA = { - &GUID_WICPixelFormat32bppPBGRA, 32, bits_32bppPBGRA, 32, 2, 96.0, 96.0}; + &GUID_WICPixelFormat32bppPBGRA, 32, bits_32bppPBGRA, 32, 4, 96.0, 96.0}; static const struct bitmap_data testdata_32bppPRGBA = { - &GUID_WICPixelFormat32bppPRGBA, 32, bits_32bppPBGRA, 32, 2, 96.0, 96.0}; + &GUID_WICPixelFormat32bppPRGBA, 32, bits_32bppPBGRA, 32, 4, 96.0, 96.0}; static const BYTE bits_64bppRGBA[] = { - 128,255,128,0,128,0,128,255,128, 0,128,255,128,0,128,255,128, 0,128,0,128,255,128,255,128, 0,128,0,128,0,128,255,128, 255,128,0,128,0,128,255,128, 0,128,255,128,0,128,255,128, 0,128,0,128,255,128,255,128, 0,128,0,128,0,128,255, - 128,255,128,0,128,0,128,255,128, 0,128,255,128,0,128,255,128, 0,128,0,128,255,128,255,128, 0,128,0,128,0,128,255,128, 255,128,0,128,0,128,255,128, 0,128,255,128,0,128,255,128, 0,128,0,128,255,128,255,128, 0,128,0,128,0,128,255, - 128,255,128,0,128,0,128,255,128, 0,128,255,128,0,128,255,128, 0,128,0,128,255,128,255,128, 0,128,0,128,0,128,255,128, 255,128,0,128,0,128,255,128, 0,128,255,128,0,128,255,128, 0,128,0,128,255,128,255,128, 0,128,0,128,0,128,255, - 128,255,128,0,128,0,128,255,128, 0,128,255,128,0,128,255,128, 0,128,0,128,255,128,255,128, 0,128,0,128,0,128,255,128, 255,128,0,128,0,128,255,128, 0,128,255,128,0,128,255,128, 0,128,0,128,255,128,255,128, 0,128,0,128,0,128,255, - 128,0,128,255,128,255,128,255,128, 255,128,0,128,255,128,255,128, 255,128,255,128,0,128,255,128, 255,128,255,128,255,128,255,128, 0,128,255,128,255,128,255,128, 255,128,0,128,255,128,255,128, 255,128,255,128,0,128,255,128, 255,128,255,128,255,128,255, - 128,0,128,255,128,255,128,255,128, 255,128,0,128,255,128,255,128, 255,128,255,128,0,128,255,128, 255,128,255,128,255,128,255,128, 0,128,255,128,255,128,255,128, 255,128,0,128,255,128,255,128, 255,128,255,128,0,128,255,128, 255,128,255,128,255,128,255, - 128,0,128,255,128,255,128,255,128, 255,128,0,128,255,128,255,128, 255,128,255,128,0,128,255,128, 255,128,255,128,255,128,255,128, 0,128,255,128,255,128,255,128, 255,128,0,128,255,128,255,128, 255,128,255,128,0,128,255,128, 255,128,255,128,255,128,255, - 128,0,128,255,128,255,128,255,128, 255,128,0,128,255,128,255,128, 255,128,255,128,0,128,255,128, 255,128,255,128,255,128,255,128, 0,128,255,128,255,128,255,128, 255,128,0,128,255,128,255,128, 255,128,255,128,0,128,255,128, 255,128,255,128,255,128,255}; + 128,0,128,0,128,255,128,255, 128,0,128,255,128,0,128,255, 128,255,128,0,128,0,128,255, 128,0,128,0,128,0,128,255, 128,0,128,0,128,255,128,255, 128,0,128,255,128,0,128,255, 128,255,128,0,128,0,128,255, 128,0,128,0,128,0,128,255, + 128,0,128,0,128,255,128,255, 128,0,128,255,128,0,128,255, 128,255,128,0,128,0,128,255, 128,0,128,0,128,0,128,255, 128,0,128,0,128,255,128,255, 128,0,128,255,128,0,128,255, 128,255,128,0,128,0,128,255, 128,0,128,0,128,0,128,255, + 128,0,128,0,128,255,128,255, 128,0,128,255,128,0,128,255, 128,255,128,0,128,0,128,255, 128,0,128,0,128,0,128,255, 128,0,128,0,128,255,128,255, 128,0,128,255,128,0,128,255, 128,255,128,0,128,0,128,255, 128,0,128,0,128,0,128,255, + 128,0,128,0,128,255,128,255, 128,0,128,255,128,0,128,255, 128,255,128,0,128,0,128,255, 128,0,128,0,128,0,128,255, 128,0,128,0,128,255,128,255, 128,0,128,255,128,0,128,255, 128,255,128,0,128,0,128,255, 128,0,128,0,128,0,128,255, + 128,255,128,255,128,0,128,255, 128,255,128,0,128,255,128,255, 128,0,128,255,128,255,128,255, 128,255,128,255,128,255,128,255, 128,255,128,255,128,0,128,255, 128,255,128,0,128,255,128,255, 128,0,128,255,128,255,128,255, 128,255,128,255,128,255,128,255, + 128,255,128,255,128,0,128,255, 128,255,128,0,128,255,128,255, 128,0,128,255,128,255,128,255, 128,255,128,255,128,255,128,255, 128,255,128,255,128,0,128,255, 128,255,128,0,128,255,128,255, 128,0,128,255,128,255,128,255, 128,255,128,255,128,255,128,255, + 128,255,128,255,128,0,128,255, 128,255,128,0,128,255,128,255, 128,0,128,255,128,255,128,255, 128,255,128,255,128,255,128,255, 128,255,128,255,128,0,128,255, 128,255,128,0,128,255,128,255, 128,0,128,255,128,255,128,255, 128,255,128,255,128,255,128,255, + 128,255,128,255,128,0,128,255, 128,255,128,0,128,255,128,255, 128,0,128,255,128,255,128,255, 128,255,128,255,128,255,128,255, 128,255,128,255,128,0,128,255, 128,255,128,0,128,255,128,255, 128,0,128,255,128,255,128,255, 128,255,128,255,128,255,128,255}; static const struct bitmap_data testdata_64bppRGBA = { &GUID_WICPixelFormat64bppRGBA, 64, bits_64bppRGBA, 32, 2, 96.0, 96.0}; @@ -528,6 +562,18 @@ static const float bits_32bppGrayFloat[] = { static const struct bitmap_data testdata_32bppGrayFloat = { &GUID_WICPixelFormat32bppGrayFloat, 32, (const BYTE *)bits_32bppGrayFloat, 32, 2, 96.0, 96.0, &testdata_32bppGrayFloat_xp}; +static const BYTE bits_4bppGray_xp[] = { + 77,112,77,112,77,112,77,112,77,112,77,112,77,112,77,112,249, + 239,249,239,249,239,249,239,249,239,249,239,249,239,249,239}; +static const struct bitmap_data testdata_4bppGray_xp = { + &GUID_WICPixelFormat4bppGray, 4, bits_4bppGray_xp, 32, 2, 96.0, 96.0}; + +static const BYTE bits_4bppGray[] = { + 77,112,77,112,77,112,77,112,77,112,77,112,77,112,77,112,249, + 239,249,239,249,239,249,239,249,239,249,239,249,239,249,239}; +static const struct bitmap_data testdata_4bppGray = { + &GUID_WICPixelFormat4bppGray, 4, bits_4bppGray, 32, 2, 96.0, 96.0, &testdata_4bppGray_xp}; + static const BYTE bits_8bppGray_xp[] = { 29,150,76,0,29,150,76,0,29,150,76,0,29,150,76,0, 29,150,76,0,29,150,76,0,29,150,76,0,29,150,76,0, @@ -556,6 +602,40 @@ static const BYTE bits_24bppBGR_gray[] = { static const struct bitmap_data testdata_24bppBGR_gray = { &GUID_WICPixelFormat24bppBGR, 24, bits_24bppBGR_gray, 32, 2, 96.0, 96.0}; +#define TO_16bppBGRA5551(b,g,r,a) ( \ + ((a >> 7) << 15) | \ + ((r >> 3) << 10) | \ + ((g >> 3) << 5) | \ + ((b >> 3)) \ +) + +static const WORD bits_16bppBGRA5551[] = { + TO_16bppBGRA5551(255,0,0,255), TO_16bppBGRA5551(0,255,0,255), TO_16bppBGRA5551(0,0,255,255), TO_16bppBGRA5551(0,0,0,255), TO_16bppBGRA5551(255,0,0,255), TO_16bppBGRA5551(0,255,0,255), TO_16bppBGRA5551(0,0,255,255), TO_16bppBGRA5551(0,0,0,255), + TO_16bppBGRA5551(255,0,0,255), TO_16bppBGRA5551(0,255,0,255), TO_16bppBGRA5551(0,0,255,255), TO_16bppBGRA5551(0,0,0,255), TO_16bppBGRA5551(255,0,0,255), TO_16bppBGRA5551(0,255,0,255), TO_16bppBGRA5551(0,0,255,255), TO_16bppBGRA5551(0,0,0,255), + TO_16bppBGRA5551(255,0,0,255), TO_16bppBGRA5551(0,255,0,255), TO_16bppBGRA5551(0,0,255,255), TO_16bppBGRA5551(0,0,0,255), TO_16bppBGRA5551(255,0,0,255), TO_16bppBGRA5551(0,255,0,255), TO_16bppBGRA5551(0,0,255,255), TO_16bppBGRA5551(0,0,0,255), + TO_16bppBGRA5551(255,0,0,255), TO_16bppBGRA5551(0,255,0,255), TO_16bppBGRA5551(0,0,255,255), TO_16bppBGRA5551(0,0,0,255), TO_16bppBGRA5551(255,0,0,255), TO_16bppBGRA5551(0,255,0,255), TO_16bppBGRA5551(0,0,255,255), TO_16bppBGRA5551(0,0,0,255), + TO_16bppBGRA5551(0,255,255,255), TO_16bppBGRA5551(255,0,255,255), TO_16bppBGRA5551(255,255,0,255), TO_16bppBGRA5551(255,255,255,255), TO_16bppBGRA5551(0,255,255,255), TO_16bppBGRA5551(255,0,255,255), TO_16bppBGRA5551(255,255,0,255), TO_16bppBGRA5551(255,255,255,255), + TO_16bppBGRA5551(0,255,255,255), TO_16bppBGRA5551(255,0,255,255), TO_16bppBGRA5551(255,255,0,255), TO_16bppBGRA5551(255,255,255,255), TO_16bppBGRA5551(0,255,255,255), TO_16bppBGRA5551(255,0,255,255), TO_16bppBGRA5551(255,255,0,255), TO_16bppBGRA5551(255,255,255,255), + TO_16bppBGRA5551(0,255,255,255), TO_16bppBGRA5551(255,0,255,255), TO_16bppBGRA5551(255,255,0,255), TO_16bppBGRA5551(255,255,255,255), TO_16bppBGRA5551(0,255,255,255), TO_16bppBGRA5551(255,0,255,255), TO_16bppBGRA5551(255,255,0,255), TO_16bppBGRA5551(255,255,255,255), + TO_16bppBGRA5551(0,255,255,255), TO_16bppBGRA5551(255,0,255,255), TO_16bppBGRA5551(255,255,0,255), TO_16bppBGRA5551(255,255,255,255), TO_16bppBGRA5551(0,255,255,255), TO_16bppBGRA5551(255,0,255,255), TO_16bppBGRA5551(255,255,0,255), TO_16bppBGRA5551(255,255,255,255)}; + +static const struct bitmap_data testdata_16bppBGRA5551 = { + &GUID_WICPixelFormat16bppBGRA5551, 16, (BYTE*)bits_16bppBGRA5551, 32, 2, 96.0, 96.0}; + +static const WORD bits_48bppRGB[] = { + 0,0,0, 0,65535,0, 32767,32768,32767, + 65535,65535,65535, 10,10,10, 0,0,10}; + +static const struct bitmap_data testdata_48bppRGB = { + &GUID_WICPixelFormat48bppRGB, 48, (BYTE*)bits_48bppRGB, 3, 2, 96.0, 96.0}; + +static const WORD bits_64bppRGBA_2[] = { + 0,0,0,65535, 0,65535,0,65535, 32767,32768,32767,65535, + 65535,65535,65535,65535, 10,10,10,65535, 0,0,10,65535,}; + +static const struct bitmap_data testdata_64bppRGBA_2 = { + &GUID_WICPixelFormat64bppRGBA, 64, (BYTE*)bits_64bppRGBA_2, 3, 2, 96.0, 96.0}; + static void test_conversion(const struct bitmap_data *src, const struct bitmap_data *dst, const char *name, BOOL todo) { BitmapTestSrc *src_obj; @@ -567,7 +647,7 @@ static void test_conversion(const struct bitmap_data *src, const struct bitmap_d hr = WICConvertBitmapSource(dst->format, &src_obj->IWICBitmapSource_iface, &dst_bitmap); todo_wine_if (todo) ok(hr == S_OK || - broken(hr == E_INVALIDARG || hr == WINCODEC_ERR_COMPONENTNOTFOUND) /* XP */, "WICConvertBitmapSource(%s) failed, hr=%x\n", name, hr); + broken(hr == E_INVALIDARG || hr == WINCODEC_ERR_COMPONENTNOTFOUND) /* XP */, "WICConvertBitmapSource(%s) failed, hr=%lx\n", name, hr); if (hr == S_OK) { @@ -589,7 +669,7 @@ static void test_invalid_conversion(void) /* convert to a non-pixel-format GUID */ hr = WICConvertBitmapSource(&GUID_VendorMicrosoft, &src_obj->IWICBitmapSource_iface, &dst_bitmap); - ok(hr == WINCODEC_ERR_COMPONENTNOTFOUND, "WICConvertBitmapSource returned %x\n", hr); + ok(hr == WINCODEC_ERR_COMPONENTNOTFOUND, "WICConvertBitmapSource returned %lx\n", hr); DeleteTestBitmap(src_obj); } @@ -605,18 +685,18 @@ static void test_default_converter(void) hr = CoCreateInstance(&CLSID_WICDefaultFormatConverter, NULL, CLSCTX_INPROC_SERVER, &IID_IWICFormatConverter, (void**)&converter); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICFormatConverter_CanConvert(converter, &GUID_WICPixelFormat32bppBGRA, &GUID_WICPixelFormat32bppBGR, &can_convert); - ok(SUCCEEDED(hr), "CanConvert returned %x\n", hr); + ok(SUCCEEDED(hr), "CanConvert returned %lx\n", hr); ok(can_convert, "expected TRUE, got %i\n", can_convert); hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface, &GUID_WICPixelFormat32bppBGR, WICBitmapDitherTypeNone, NULL, 0.0, WICBitmapPaletteTypeCustom); - ok(SUCCEEDED(hr), "Initialize returned %x\n", hr); + ok(SUCCEEDED(hr), "Initialize returned %lx\n", hr); if (SUCCEEDED(hr)) compare_bitmap_data(&testdata_32bppBGRA, &testdata_32bppBGR, (IWICBitmapSource*)converter, "default converter"); @@ -627,6 +707,72 @@ static void test_default_converter(void) DeleteTestBitmap(src_obj); } +static void test_converter_4bppGray(void) +{ + BitmapTestSrc *src_obj; + IWICFormatConverter *converter; + BOOL can_convert = TRUE; + HRESULT hr; + + CreateTestBitmap(&testdata_32bppBGRA, &src_obj); + + hr = CoCreateInstance(&CLSID_WICDefaultFormatConverter, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICFormatConverter, (void**)&converter); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); + if (SUCCEEDED(hr)) + { + hr = IWICFormatConverter_CanConvert(converter, &GUID_WICPixelFormat32bppBGRA, + &GUID_WICPixelFormat4bppGray, &can_convert); + ok(SUCCEEDED(hr), "CanConvert returned %lx\n", hr); + todo_wine ok(can_convert, "expected TRUE, got %i\n", can_convert); + + hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface, + &GUID_WICPixelFormat4bppGray, WICBitmapDitherTypeNone, NULL, 0.0, + WICBitmapPaletteTypeCustom); + todo_wine ok(SUCCEEDED(hr), "Initialize returned %lx\n", hr); + + if (SUCCEEDED(hr)) + compare_bitmap_data(&testdata_32bppBGRA, &testdata_4bppGray, (IWICBitmapSource*)converter, "4bppGray converter"); + + IWICFormatConverter_Release(converter); + } + + DeleteTestBitmap(src_obj); +} + +static void test_converter_8bppGray(void) +{ + BitmapTestSrc *src_obj; + IWICFormatConverter *converter; + BOOL can_convert = TRUE; + HRESULT hr; + + CreateTestBitmap(&testdata_32bppBGRA, &src_obj); + + hr = CoCreateInstance(&CLSID_WICDefaultFormatConverter, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICFormatConverter, (void**)&converter); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); + if (SUCCEEDED(hr)) + { + hr = IWICFormatConverter_CanConvert(converter, &GUID_WICPixelFormat32bppBGRA, + &GUID_WICPixelFormat8bppGray, &can_convert); + ok(SUCCEEDED(hr), "CanConvert returned %lx\n", hr); + ok(can_convert, "expected TRUE, got %i\n", can_convert); + + hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface, + &GUID_WICPixelFormat8bppGray, WICBitmapDitherTypeNone, NULL, 0.0, + WICBitmapPaletteTypeCustom); + ok(SUCCEEDED(hr), "Initialize returned %lx\n", hr); + + if (SUCCEEDED(hr)) + compare_bitmap_data(&testdata_32bppBGRA, &testdata_8bppGray, (IWICBitmapSource*)converter, "8bppGray converter"); + + IWICFormatConverter_Release(converter); + } + + DeleteTestBitmap(src_obj); +} + typedef struct property_opt_test_data { LPCOLESTR name; @@ -715,13 +861,13 @@ static void test_specific_encoder_properties(IPropertyBag2 *options, const prope { ok(all_props[idx].vt == data[i].var_type, "Property %s has unexpected vt type, vt=%i\n", wine_dbgstr_w(data[i].name), all_props[idx].vt); - ok(all_props[idx].dwType == PROPBAG2_TYPE_DATA, "Property %s has unexpected dw type, vt=%i\n", + ok(all_props[idx].dwType == PROPBAG2_TYPE_DATA, "Property %s has unexpected dw type, vt=%li\n", wine_dbgstr_w(data[i].name), all_props[idx].dwType); ok(all_props[idx].cfType == 0, "Property %s has unexpected cf type, vt=%i\n", wine_dbgstr_w(data[i].name), all_props[idx].cfType); } - ok(SUCCEEDED(hr), "Reading property %s from bag failed, hr=%x\n", + ok(SUCCEEDED(hr), "Reading property %s from bag failed, hr=%lx\n", wine_dbgstr_w(data[i].name), hr); if (SUCCEEDED(hr)) @@ -767,16 +913,16 @@ static void test_encoder_properties(const CLSID* clsid_encoder, IPropertyBag2 *o /* CountProperties */ { hr = IPropertyBag2_CountProperties(options, &cProperties); - ok(SUCCEEDED(hr), "Reading property count, hr=%x\n", hr); + ok(SUCCEEDED(hr), "Reading property count, hr=%lx\n", hr); } /* GetPropertyInfo */ { hr = IPropertyBag2_GetPropertyInfo(options, cProperties, 1, all_props, &cProperties2); - ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "IPropertyBag2::GetPropertyInfo - iProperty out of bounce handled wrong, hr=%x\n", hr); + ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "IPropertyBag2::GetPropertyInfo - iProperty out of bounce handled wrong, hr=%lx\n", hr); hr = IPropertyBag2_GetPropertyInfo(options, 0, cProperties+1, all_props, &cProperties2); - ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "IPropertyBag2::GetPropertyInfo - cProperty out of bounce handled wrong, hr=%x\n", hr); + ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "IPropertyBag2::GetPropertyInfo - cProperty out of bounce handled wrong, hr=%lx\n", hr); if (cProperties == 0) /* GetPropertyInfo can be called for zero items on Windows 8 but not on Windows 7 (wine behaves like Win8) */ { @@ -786,7 +932,7 @@ static void test_encoder_properties(const CLSID* clsid_encoder, IPropertyBag2 *o else { hr = IPropertyBag2_GetPropertyInfo(options, 0, min(64, cProperties), all_props, &cProperties2); - ok(SUCCEEDED(hr), "Reading infos from property bag failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "Reading infos from property bag failed, hr=%lx\n", hr); } if (FAILED(hr)) @@ -816,17 +962,12 @@ static void load_stream(IUnknown *reader, IStream *stream) { HRESULT hr; IWICPersistStream *persist; -#ifdef WORDS_BIGENDIAN - DWORD persist_options = WICPersistOptionBigEndian; -#else - DWORD persist_options = WICPersistOptionLittleEndian; -#endif hr = IUnknown_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist); - ok(hr == S_OK, "QueryInterface failed, hr=%x\n", hr); + ok(hr == S_OK, "QueryInterface failed, hr=%lx\n", hr); - hr = IWICPersistStream_LoadEx(persist, stream, NULL, persist_options); - ok(hr == S_OK, "LoadEx failed, hr=%x\n", hr); + hr = IWICPersistStream_LoadEx(persist, stream, NULL, 0); + ok(hr == S_OK, "LoadEx failed, hr=%lx\n", hr); IWICPersistStream_Release(persist); } @@ -856,23 +997,23 @@ static void check_tiff_format(IStream *stream, const WICPixelFormatGUID *format) memset(&tiff, 0, sizeof(tiff)); hr = IStream_Read(stream, &tiff, sizeof(tiff), NULL); - ok(hr == S_OK, "IStream_Read error %#x\n", hr); + ok(hr == S_OK, "IStream_Read error %#lx\n", hr); ok(tiff.byte_order == MAKEWORD('I','I') || tiff.byte_order == MAKEWORD('M','M'), "wrong TIFF byte order mark %02x\n", tiff.byte_order); ok(tiff.version == 42, "wrong TIFF version %u\n", tiff.version); pos.QuadPart = tiff.dir_offset; hr = IStream_Seek(stream, pos, SEEK_SET, NULL); - ok(hr == S_OK, "IStream_Seek error %#x\n", hr); + ok(hr == S_OK, "IStream_Seek error %#lx\n", hr); hr = CoCreateInstance(&CLSID_WICIfdMetadataReader, NULL, CLSCTX_INPROC_SERVER, &IID_IWICMetadataReader, (void **)&reader); - ok(hr == S_OK, "CoCreateInstance error %#x\n", hr); + ok(hr == S_OK, "CoCreateInstance error %#lx\n", hr); load_stream((IUnknown *)reader, stream); hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); + ok(hr == S_OK, "GetCount error %#lx\n", hr); ok(count != 0, "wrong count %u\n", count); for (i = 0; i < ARRAY_SIZE(tag); i++) @@ -881,14 +1022,14 @@ static void check_tiff_format(IStream *stream, const WICPixelFormatGUID *format) PropVariantInit(&value); id.vt = VT_UI2; - U(id).uiVal = tag[i].id; + id.uiVal = tag[i].id; hr = IWICMetadataReader_GetValue(reader, NULL, &id, &value); ok(hr == S_OK || (tag[i].id == 0x140 && hr == WINCODEC_ERR_PROPERTYNOTFOUND), - "GetValue(%04x) error %#x\n", tag[i].id, hr); + "GetValue(%04x) error %#lx\n", tag[i].id, hr); if (hr == S_OK) { ok(value.vt == VT_UI2 || value.vt == VT_UI4 || value.vt == (VT_UI2 | VT_VECTOR), "wrong vt: %d\n", value.vt); - tag[i].value[0] = U(value).uiVal; + tag[i].value[0] = value.uiVal; } else tag[i].value[0] = -1; @@ -959,62 +1100,62 @@ static void check_bmp_format(IStream *stream, const WICPixelFormatGUID *format) BITMAPV5HEADER bih; hr = IStream_Read(stream, &bfh, sizeof(bfh), NULL); - ok(hr == S_OK, "IStream_Read error %#x\n", hr); + ok(hr == S_OK, "IStream_Read error %#lx\n", hr); ok(bfh.bfType == 0x4d42, "wrong BMP signature %02x\n", bfh.bfType); ok(bfh.bfReserved1 == 0, "wrong bfReserved1 %02x\n", bfh.bfReserved1); ok(bfh.bfReserved2 == 0, "wrong bfReserved2 %02x\n", bfh.bfReserved2); hr = IStream_Read(stream, &bih, sizeof(bih), NULL); - ok(hr == S_OK, "IStream_Read error %#x\n", hr); + ok(hr == S_OK, "IStream_Read error %#lx\n", hr); if (IsEqualGUID(format, &GUID_WICPixelFormat1bppIndexed)) { - ok(bfh.bfOffBits == 0x0436, "wrong bfOffBits %08x\n", bfh.bfOffBits); + ok(bfh.bfOffBits == 0x0436, "wrong bfOffBits %08lx\n", bfh.bfOffBits); - ok(bih.bV5Width == 32, "wrong width %u\n", bih.bV5Width); - ok(bih.bV5Height == 2, "wrong height %u\n", bih.bV5Height); + ok(bih.bV5Width == 32, "wrong width %lu\n", bih.bV5Width); + ok(bih.bV5Height == 2, "wrong height %lu\n", bih.bV5Height); ok(bih.bV5Planes == 1, "wrong Planes %d\n", bih.bV5Planes); ok(bih.bV5BitCount == 1, "wrong BitCount %d\n", bih.bV5BitCount); - ok(bih.bV5ClrUsed == 256, "wrong ClrUsed %d\n", bih.bV5ClrUsed); - ok(bih.bV5ClrImportant == 256, "wrong ClrImportant %d\n", bih.bV5ClrImportant); + ok(bih.bV5ClrUsed == 256, "wrong ClrUsed %ld\n", bih.bV5ClrUsed); + ok(bih.bV5ClrImportant == 256, "wrong ClrImportant %ld\n", bih.bV5ClrImportant); } else if (IsEqualGUID(format, &GUID_WICPixelFormat4bppIndexed)) { - ok(bfh.bfOffBits == 0x0436, "wrong bfOffBits %08x\n", bfh.bfOffBits); + ok(bfh.bfOffBits == 0x0436, "wrong bfOffBits %08lx\n", bfh.bfOffBits); - ok(bih.bV5Width == 32, "wrong width %u\n", bih.bV5Width); - ok(bih.bV5Height == 2, "wrong height %u\n", bih.bV5Height); + ok(bih.bV5Width == 32, "wrong width %lu\n", bih.bV5Width); + ok(bih.bV5Height == 2, "wrong height %lu\n", bih.bV5Height); ok(bih.bV5Planes == 1, "wrong Planes %d\n", bih.bV5Planes); ok(bih.bV5BitCount == 4, "wrong BitCount %d\n", bih.bV5BitCount); - ok(bih.bV5ClrUsed == 256, "wrong ClrUsed %d\n", bih.bV5ClrUsed); - ok(bih.bV5ClrImportant == 256, "wrong ClrImportant %d\n", bih.bV5ClrImportant); + ok(bih.bV5ClrUsed == 256, "wrong ClrUsed %ld\n", bih.bV5ClrUsed); + ok(bih.bV5ClrImportant == 256, "wrong ClrImportant %ld\n", bih.bV5ClrImportant); } else if (IsEqualGUID(format, &GUID_WICPixelFormat8bppIndexed)) { - ok(bfh.bfOffBits == 0x0436, "wrong bfOffBits %08x\n", bfh.bfOffBits); + ok(bfh.bfOffBits == 0x0436, "wrong bfOffBits %08lx\n", bfh.bfOffBits); - ok(bih.bV5Width == 32, "wrong width %u\n", bih.bV5Width); - ok(bih.bV5Height == 2, "wrong height %u\n", bih.bV5Height); + ok(bih.bV5Width == 32, "wrong width %lu\n", bih.bV5Width); + ok(bih.bV5Height == 2, "wrong height %lu\n", bih.bV5Height); ok(bih.bV5Planes == 1, "wrong Planes %d\n", bih.bV5Planes); ok(bih.bV5BitCount == 8, "wrong BitCount %d\n", bih.bV5BitCount); - ok(bih.bV5ClrUsed == 256, "wrong ClrUsed %d\n", bih.bV5ClrUsed); - ok(bih.bV5ClrImportant == 256, "wrong ClrImportant %d\n", bih.bV5ClrImportant); + ok(bih.bV5ClrUsed == 256, "wrong ClrUsed %ld\n", bih.bV5ClrUsed); + ok(bih.bV5ClrImportant == 256, "wrong ClrImportant %ld\n", bih.bV5ClrImportant); } else if (IsEqualGUID(format, &GUID_WICPixelFormat32bppBGR)) { - ok(bfh.bfOffBits == 0x0036, "wrong bfOffBits %08x\n", bfh.bfOffBits); + ok(bfh.bfOffBits == 0x0036, "wrong bfOffBits %08lx\n", bfh.bfOffBits); - ok(bih.bV5Width == 32, "wrong width %u\n", bih.bV5Width); - ok(bih.bV5Height == 2, "wrong height %u\n", bih.bV5Height); + ok(bih.bV5Width == 32, "wrong width %lu\n", bih.bV5Width); + ok(bih.bV5Height == 2, "wrong height %lu\n", bih.bV5Height); ok(bih.bV5Planes == 1, "wrong Planes %d\n", bih.bV5Planes); ok(bih.bV5BitCount == 32, "wrong BitCount %d\n", bih.bV5BitCount); - ok(bih.bV5ClrUsed == 0, "wrong ClrUsed %d\n", bih.bV5ClrUsed); - ok(bih.bV5ClrImportant == 0, "wrong ClrImportant %d\n", bih.bV5ClrImportant); + ok(bih.bV5ClrUsed == 0, "wrong ClrUsed %ld\n", bih.bV5ClrUsed); + ok(bih.bV5ClrImportant == 0, "wrong ClrImportant %ld\n", bih.bV5ClrImportant); } else ok(0, "unknown BMP pixel format %s\n", wine_dbgstr_guid(format)); @@ -1047,7 +1188,7 @@ static void check_png_format(IStream *stream, const WICPixelFormatGUID *format) memset(&png, 0, sizeof(png)); hr = IStream_Read(stream, &png, sizeof(png), NULL); - ok(hr == S_OK, "IStream_Read error %#x\n", hr); + ok(hr == S_OK, "IStream_Read error %#lx\n", hr); ok(!memcmp(png.png_sig, png_sig, sizeof(png_sig)), "expected PNG signature\n"); ok(!memcmp(png.ihdr_sig, png_IHDR, sizeof(png_IHDR)), "expected PNG IHDR\n"); @@ -1145,7 +1286,7 @@ static void check_gif_format(IStream *stream, const WICPixelFormatGUID *format) memset(&lsd, 0, sizeof(lsd)); hr = IStream_Read(stream, &lsd, sizeof(lsd), NULL); - ok(hr == S_OK, "IStream_Read error %#x\n", hr); + ok(hr == S_OK, "IStream_Read error %#lx\n", hr); ok(!memcmp(lsd.signature, "GIF89a", 6), "wrong GIF signature %.6s\n", lsd.signature); @@ -1163,7 +1304,7 @@ static void check_bitmap_format(IStream *stream, const CLSID *encoder, const WIC pos.QuadPart = 0; hr = IStream_Seek(stream, pos, SEEK_SET, (ULARGE_INTEGER *)&pos); - ok(hr == S_OK, "IStream_Seek error %#x\n", hr); + ok(hr == S_OK, "IStream_Seek error %#lx\n", hr); if (IsEqualGUID(encoder, &CLSID_WICPngEncoder)) check_png_format(stream, format); @@ -1177,7 +1318,7 @@ static void check_bitmap_format(IStream *stream, const CLSID *encoder, const WIC ok(0, "unknown encoder %s\n", wine_dbgstr_guid(encoder)); hr = IStream_Seek(stream, pos, SEEK_SET, NULL); - ok(hr == S_OK, "IStream_Seek error %#x\n", hr); + ok(hr == S_OK, "IStream_Seek error %#lx\n", hr); } struct setting { @@ -1193,7 +1334,7 @@ static void _expect_ref(IUnknown* obj, ULONG ref, int line) ULONG rc; IUnknown_AddRef(obj); rc = IUnknown_Release(obj); - ok_(__FILE__,line)(rc == ref, "expected refcount %d, got %d\n", ref, rc); + ok_(__FILE__,line)(rc == ref, "expected refcount %ld, got %ld\n", ref, rc); } static void test_set_frame_palette(IWICBitmapFrameEncode *frameencode) @@ -1204,36 +1345,36 @@ static void test_set_frame_palette(IWICBitmapFrameEncode *frameencode) hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICComponentFactory, (void **)&factory); - ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); + ok(hr == S_OK, "CoCreateInstance failed, hr=%lx\n", hr); hr = IWICBitmapFrameEncode_SetPalette(frameencode, NULL); - ok(hr == E_INVALIDARG, "SetPalette failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "SetPalette failed, hr=%lx\n", hr); hr = IWICComponentFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "CreatePalette failed, hr=%x\n", hr); + ok(hr == S_OK, "CreatePalette failed, hr=%lx\n", hr); hr = IWICBitmapFrameEncode_SetPalette(frameencode, palette); -todo_wine - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr=%x\n", hr); + todo_wine + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr=%lx\n", hr); hr = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeFixedHalftone256, FALSE); - ok(hr == S_OK, "InitializePredefined failed, hr=%x\n", hr); + ok(hr == S_OK, "InitializePredefined failed, hr=%lx\n", hr); EXPECT_REF(palette, 1); hr = IWICBitmapFrameEncode_SetPalette(frameencode, palette); - ok(hr == S_OK, "SetPalette failed, hr=%x\n", hr); + ok(hr == S_OK, "SetPalette failed, hr=%lx\n", hr); EXPECT_REF(palette, 1); hr = IWICBitmapFrameEncode_SetPalette(frameencode, NULL); - ok(hr == E_INVALIDARG, "SetPalette failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "SetPalette failed, hr=%lx\n", hr); IWICPalette_Release(palette); IWICComponentFactory_Release(factory); } -static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* clsid_encoder, +static void test_multi_encoder_impl(const struct bitmap_data **srcs, const CLSID* clsid_encoder, const struct bitmap_data **dsts, const CLSID *clsid_decoder, WICRect *rc, - const struct setting *settings, const char *name, IWICPalette *palette) + const struct setting *settings, const char *name, IWICPalette *palette, BOOL set_size) { const GUID *container_format = NULL; HRESULT hr; @@ -1251,13 +1392,13 @@ static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* cls hr = CoCreateInstance(clsid_encoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapEncoder, (void **)&encoder); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); hr = CreateStreamOnHGlobal(NULL, TRUE, &stream); - ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%lx\n", hr); hr = IWICBitmapEncoder_GetContainerFormat(encoder, NULL); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); if (IsEqualGUID(clsid_encoder, &CLSID_WICPngEncoder)) container_format = &GUID_ContainerFormatPng; @@ -1267,6 +1408,8 @@ static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* cls container_format = &GUID_ContainerFormatTiff; else if (IsEqualGUID(clsid_encoder, &CLSID_WICJpegEncoder)) container_format = &GUID_ContainerFormatJpeg; + else if (IsEqualGUID(clsid_encoder, &CLSID_WICGifEncoder)) + container_format = &GUID_ContainerFormatGif; else ok(0, "Unknown encoder %s.\n", wine_dbgstr_guid(clsid_encoder)); @@ -1274,16 +1417,16 @@ static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* cls { memset(&guid, 0, sizeof(guid)); hr = IWICBitmapEncoder_GetContainerFormat(encoder, &guid); - ok(SUCCEEDED(hr), "Failed to get container format, hr %#x.\n", hr); + ok(SUCCEEDED(hr), "Failed to get container format, hr %#lx.\n", hr); ok(IsEqualGUID(container_format, &guid), "Unexpected container format %s.\n", wine_dbgstr_guid(&guid)); } hr = IWICBitmapEncoder_Initialize(encoder, stream, WICBitmapEncoderNoCache); - ok(SUCCEEDED(hr), "Initialize failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "Initialize failed, hr=%lx\n", hr); /* Encoder options are optional. */ hr = IWICBitmapEncoder_CreateNewFrame(encoder, &frameencode, NULL); - ok(SUCCEEDED(hr), "Failed to create encode frame, hr %#x.\n", hr); + ok(SUCCEEDED(hr), "Failed to create encode frame, hr %#lx.\n", hr); IStream_Release(stream); IWICBitmapEncoder_Release(encoder); @@ -1291,7 +1434,7 @@ static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* cls hr = CoCreateInstance(clsid_encoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapEncoder, (void**)&encoder); - ok(SUCCEEDED(hr), "CoCreateInstance(%s) failed, hr=%x\n", wine_dbgstr_guid(clsid_encoder), hr); + ok(SUCCEEDED(hr), "CoCreateInstance(%s) failed, hr=%lx\n", wine_dbgstr_guid(clsid_encoder), hr); if (SUCCEEDED(hr)) { hglobal = GlobalAlloc(GMEM_MOVEABLE, 0); @@ -1299,53 +1442,37 @@ static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* cls if (hglobal) { hr = CreateStreamOnHGlobal(hglobal, TRUE, &stream); - ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%lx\n", hr); } if (hglobal && SUCCEEDED(hr)) { - IWICBitmapEncoderInfo *info = NULL; - if (palette) { hr = IWICBitmapEncoder_SetPalette(encoder, palette); - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "wrong error %#x (%s)\n", hr, name); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "wrong error %#lx (%s)\n", hr, name); } hr = IWICBitmapEncoder_Initialize(encoder, stream, WICBitmapEncoderNoCache); - ok(SUCCEEDED(hr), "Initialize failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "Initialize failed, hr=%lx\n", hr); if (palette) { hr = IWICBitmapEncoder_SetPalette(encoder, palette); if (IsEqualGUID(clsid_encoder, &CLSID_WICGifEncoder)) - ok(hr == S_OK, "SetPalette failed, hr=%#x\n", hr); + ok(hr == S_OK, "SetPalette failed, hr=%#lx\n", hr); else - ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "wrong error %#x\n", hr); + ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "wrong error %#lx\n", hr); hr = S_OK; } - hr = IWICBitmapEncoder_GetEncoderInfo(encoder, &info); - ok(hr == S_OK || hr == WINCODEC_ERR_COMPONENTNOTFOUND, "wrong error %#x\n", hr); - if (SUCCEEDED(hr)) - { - CLSID clsid; - - hr = IWICBitmapEncoderInfo_GetCLSID(info, &clsid); - ok(hr == S_OK, "wrong error %#x\n", hr); - ok(!IsEqualGUID(clsid_encoder, &clsid), "wrong CLSID %s (%s)\n", - wine_dbgstr_guid(clsid_encoder), wine_dbgstr_guid(&clsid)); - - IWICBitmapEncoderInfo_Release(info); - } - i=0; while (SUCCEEDED(hr) && srcs[i]) { CreateTestBitmap(srcs[i], &src_obj); hr = IWICBitmapEncoder_CreateNewFrame(encoder, &frameencode, &options); - ok(SUCCEEDED(hr), "CreateFrame failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreateFrame failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { ok(options != NULL, "Encoder initialization has not created an property bag\n"); @@ -1368,70 +1495,75 @@ static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* cls V_UNKNOWN(&var) = settings[j].value; hr = IPropertyBag2_Write(options, 1, &propbag, &var); - ok(SUCCEEDED(hr), "Writing property %s failed, hr=%x\n", wine_dbgstr_w(settings[j].name), hr); + ok(SUCCEEDED(hr), "Writing property %s failed, hr=%lx\n", wine_dbgstr_w(settings[j].name), hr); } } if (palette) { hr = IWICBitmapFrameEncode_SetPalette(frameencode, palette); - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "wrong error %#x\n", hr); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "wrong error %#lx\n", hr); } hr = IWICBitmapFrameEncode_Initialize(frameencode, options); - ok(SUCCEEDED(hr), "Initialize failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "Initialize failed, hr=%lx\n", hr); memcpy(&pixelformat, srcs[i]->format, sizeof(GUID)); hr = IWICBitmapFrameEncode_SetPixelFormat(frameencode, &pixelformat); - ok(SUCCEEDED(hr), "SetPixelFormat failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "SetPixelFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&pixelformat, dsts[i]->format) || (IsEqualGUID(clsid_encoder, &CLSID_WICTiffEncoder) && srcs[i]->bpp == 2 && IsEqualGUID(&pixelformat, &GUID_WICPixelFormat4bppIndexed)) || (IsEqualGUID(clsid_encoder, &CLSID_WICBmpEncoder) && srcs[i]->bpp == 2 && IsEqualGUID(&pixelformat, &GUID_WICPixelFormat4bppIndexed)), "SetPixelFormat changed the format to %s (%s)\n", wine_dbgstr_guid(&pixelformat), name); - hr = IWICBitmapFrameEncode_SetSize(frameencode, srcs[i]->width, srcs[i]->height); - ok(SUCCEEDED(hr), "SetSize failed, hr=%x\n", hr); + if (set_size) + { + hr = IWICBitmapFrameEncode_SetSize(frameencode, srcs[i]->width, srcs[i]->height); + ok(hr == S_OK, "SetSize failed, hr=%lx\n", hr); + } if (IsEqualGUID(clsid_encoder, &CLSID_WICPngEncoder)) test_set_frame_palette(frameencode); if (palette) { - WICColor colors[256]; - hr = IWICBitmapFrameEncode_SetPalette(frameencode, palette); - ok(SUCCEEDED(hr), "SetPalette failed, hr=%x (%s)\n", hr, name); - - /* trash the assigned palette */ - memset(colors, 0, sizeof(colors)); - hr = IWICPalette_InitializeCustom(palette, colors, 256); - ok(hr == S_OK, "InitializeCustom error %#x\n", hr); + ok(SUCCEEDED(hr), "SetPalette failed, hr=%lx (%s)\n", hr, name); } hr = IWICBitmapFrameEncode_WriteSource(frameencode, &src_obj->IWICBitmapSource_iface, rc); if (rc && (rc->Width <= 0 || rc->Height <= 0)) { /* WriteSource fails but WriteSource_Proxy succeeds. */ - ok(hr == E_INVALIDARG, "WriteSource should fail, hr=%x (%s)\n", hr, name); + ok(hr == E_INVALIDARG, "WriteSource should fail, hr=%lx (%s)\n", hr, name); hr = IWICBitmapFrameEncode_WriteSource_Proxy(frameencode, &src_obj->IWICBitmapSource_iface, rc); - ok(SUCCEEDED(hr), "WriteSource_Proxy failed, %dx%d, hr=%x (%s)\n", rc->Width, rc->Height, hr, name); + if (!set_size && rc->Width < 0) + todo_wine + ok(hr == WINCODEC_ERR_SOURCERECTDOESNOTMATCHDIMENSIONS || + hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW) /* win11 */, + "WriteSource_Proxy(%dx%d) got unexpected hr %lx (%s)\n", rc->Width, rc->Height, hr, name); + else + ok(hr == S_OK, "WriteSource_Proxy failed, %dx%d, hr=%lx (%s)\n", rc->Width, rc->Height, hr, name); } else { if (rc) - ok(SUCCEEDED(hr), "WriteSource(%dx%d) failed, hr=%x (%s)\n", rc->Width, rc->Height, hr, name); + ok(SUCCEEDED(hr), "WriteSource(%dx%d) failed, hr=%lx (%s)\n", rc->Width, rc->Height, hr, name); else - ok(hr == S_OK || - (FAILED(hr) && IsEqualGUID(clsid_encoder, &CLSID_WICBmpEncoder) && srcs[i]->bpp == 2) /* XP */ || - (FAILED(hr) && IsEqualGUID(clsid_encoder, &CLSID_WICTiffEncoder) && srcs[i]->bpp == 2) /* XP */ || - broken(hr == E_INVALIDARG && IsEqualGUID(clsid_encoder, &CLSID_WICBmpEncoder) && IsEqualGUID(srcs[i]->format, &GUID_WICPixelFormatBlackWhite)) /* XP */, - "WriteSource(NULL) failed, hr=%x (%s)\n", hr, name); + todo_wine_if((IsEqualGUID(clsid_encoder, &CLSID_WICTiffEncoder) && srcs[i]->bpp == 2) || + (IsEqualGUID(clsid_encoder, &CLSID_WICBmpEncoder) && srcs[i]->bpp == 2)) + ok(hr == S_OK, "WriteSource(NULL) failed, hr=%lx (%s)\n", hr, name); + } if (SUCCEEDED(hr)) { hr = IWICBitmapFrameEncode_Commit(frameencode); - ok(SUCCEEDED(hr), "Commit failed, hr=%x (%s)\n", hr, name); + if (!set_size && rc && rc->Height < 0) + todo_wine + ok(hr == WINCODEC_ERR_UNEXPECTEDSIZE, "Commit got unexpected hr %lx (%s)\n", hr, name); + else + ok(hr == S_OK, "Commit failed, hr=%lx (%s)\n", hr, name); } IWICBitmapFrameEncode_Release(frameencode); @@ -1453,7 +1585,7 @@ static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* cls if (SUCCEEDED(hr)) { hr = IWICBitmapEncoder_Commit(encoder); - ok(SUCCEEDED(hr), "Commit failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "Commit failed, hr=%lx\n", hr); if (IsEqualGUID(&pixelformat, dsts[0]->format)) check_bitmap_format(stream, clsid_encoder, dsts[0]->format); @@ -1463,7 +1595,7 @@ static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* cls { hr = CoCreateInstance(clsid_decoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void**)&decoder); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); } if (SUCCEEDED(hr)) @@ -1471,57 +1603,57 @@ static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* cls IWICPalette *frame_palette; hr = IWICImagingFactory_CreatePalette(factory, &frame_palette); - ok(hr == S_OK, "CreatePalette error %#x\n", hr); + ok(hr == S_OK, "CreatePalette error %#lx\n", hr); hr = IWICBitmapDecoder_CopyPalette(decoder, frame_palette); if (IsEqualGUID(clsid_decoder, &CLSID_WICGifDecoder)) - ok(hr == WINCODEC_ERR_WRONGSTATE, "wrong error %#x\n", hr); + ok(hr == WINCODEC_ERR_WRONGSTATE, "wrong error %#lx\n", hr); else - ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "wrong error %#x\n", hr); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "wrong error %#lx\n", hr); hr = IWICBitmapDecoder_Initialize(decoder, stream, WICDecodeMetadataCacheOnDemand); - ok(SUCCEEDED(hr), "Initialize failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "Initialize failed, hr=%lx\n", hr); hr = IWICBitmapDecoder_CopyPalette(decoder, frame_palette); if (IsEqualGUID(clsid_decoder, &CLSID_WICGifDecoder)) - ok(hr == S_OK || broken(hr == WINCODEC_ERR_FRAMEMISSING) /* XP */, "CopyPalette failed, hr=%#x\n", hr); + ok(hr == S_OK || broken(hr == WINCODEC_ERR_FRAMEMISSING) /* XP */, "CopyPalette failed, hr=%#lx\n", hr); else - ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "wrong error %#x\n", hr); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "wrong error %#lx\n", hr); hr = S_OK; i=0; while (SUCCEEDED(hr) && dsts[i]) { hr = IWICBitmapDecoder_GetFrame(decoder, i, &framedecode); - ok(SUCCEEDED(hr), "GetFrame failed, hr=%x (%s)\n", hr, name); + ok(SUCCEEDED(hr), "GetFrame failed, hr=%lx (%s)\n", hr, name); if (SUCCEEDED(hr)) { hr = IWICBitmapFrameDecode_GetPixelFormat(framedecode, &pixelformat); - ok(hr == S_OK, "GetPixelFormat) failed, hr=%x (%s)\n", hr, name); + ok(hr == S_OK, "GetPixelFormat) failed, hr=%lx (%s)\n", hr, name); if (IsEqualGUID(&pixelformat, dsts[i]->format)) compare_bitmap_data(srcs[i], dsts[i], (IWICBitmapSource*)framedecode, name); hr = IWICBitmapFrameDecode_CopyPalette(framedecode, frame_palette); if (winetest_debug > 1) - trace("%s, bpp %d, %s, hr %#x\n", name, dsts[i]->bpp, wine_dbgstr_guid(dsts[i]->format), hr); + trace("%s, bpp %d, %s, hr %#lx\n", name, dsts[i]->bpp, wine_dbgstr_guid(dsts[i]->format), hr); if (dsts[i]->bpp > 8 || IsEqualGUID(dsts[i]->format, &GUID_WICPixelFormatBlackWhite)) - ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "wrong error %#x\n", hr); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "wrong error %#lx\n", hr); else { UINT count, ret; WICColor colors[256]; - ok(hr == S_OK, "CopyPalette error %#x (%s)\n", hr, name); + ok(hr == S_OK, "CopyPalette error %#lx (%s)\n", hr, name); count = 0; hr = IWICPalette_GetColorCount(frame_palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); memset(colors, 0, sizeof(colors)); ret = 0; hr = IWICPalette_GetColors(frame_palette, count, colors, &ret); - ok(hr == S_OK, "GetColors error %#x\n", hr); + ok(hr == S_OK, "GetColors error %#lx\n", hr); ok(ret == count, "expected %u, got %u\n", count, ret); if (IsEqualGUID(clsid_decoder, &CLSID_WICPngDecoder)) { @@ -1606,6 +1738,14 @@ static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* cls } } +static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* clsid_encoder, + const struct bitmap_data **dsts, const CLSID *clsid_decoder, WICRect *rc, + const struct setting *settings, const char *name, IWICPalette *palette) +{ + test_multi_encoder_impl(srcs, clsid_encoder, dsts, clsid_decoder, rc, settings, name, palette, TRUE); + test_multi_encoder_impl(srcs, clsid_encoder, dsts, clsid_decoder, rc, settings, name, palette, FALSE); +} + static void test_encoder(const struct bitmap_data *src, const CLSID* clsid_encoder, const struct bitmap_data *dst, const CLSID *clsid_decoder, const char *name) { @@ -1616,7 +1756,7 @@ static void test_encoder(const struct bitmap_data *src, const CLSID* clsid_encod HRESULT hr; hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "CreatePalette error %#x\n", hr); + ok(hr == S_OK, "CreatePalette error %#lx\n", hr); memset(colors, 0, sizeof(colors)); colors[0] = 0x11111111; @@ -1626,7 +1766,7 @@ static void test_encoder(const struct bitmap_data *src, const CLSID* clsid_encod colors[4] = 0x55555555; /* TIFF decoder fails to decode a 8bpp frame if palette has less than 256 colors */ hr = IWICPalette_InitializeCustom(palette, colors, 256); - ok(hr == S_OK, "InitializeCustom error %#x\n", hr); + ok(hr == S_OK, "InitializeCustom error %#lx\n", hr); srcs[0] = src; srcs[1] = NULL; @@ -1696,54 +1836,102 @@ static void test_converter_8bppIndexed(void) CreateTestBitmap(&testdata_24bppBGR, &src_obj); hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "CreatePalette error %#x\n", hr); + ok(hr == S_OK, "CreatePalette error %#lx\n", hr); count = 0xdeadbeef; hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 0, "expected 0, got %u\n", count); /* NULL palette + Custom type */ hr = IWICImagingFactory_CreateFormatConverter(factory, &converter); - ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr); + ok(hr == S_OK, "CreateFormatConverter error %#lx\n", hr); hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface, &GUID_WICPixelFormat24bppBGR, WICBitmapDitherTypeNone, NULL, 0.0, WICBitmapPaletteTypeCustom); - ok(hr == S_OK, "Initialize error %#x\n", hr); + ok(hr == S_OK, "Initialize error %#lx\n", hr); hr = IWICFormatConverter_CopyPalette(converter, palette); - ok(hr == 0xdeadbeef, "unexpected error %#x\n", hr); + ok(hr == 0xdeadbeef, "unexpected error %#lx\n", hr); hr = IWICFormatConverter_CopyPixels(converter, NULL, 32 * 3, sizeof(buf), buf); - ok(hr == S_OK, "CopyPixels error %#x\n", hr); + ok(hr == S_OK, "CopyPixels error %#lx\n", hr); IWICFormatConverter_Release(converter); /* NULL palette + Custom type */ hr = IWICImagingFactory_CreateFormatConverter(factory, &converter); - ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr); + ok(hr == S_OK, "CreateFormatConverter error %#lx\n", hr); hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface, &GUID_WICPixelFormat8bppIndexed, WICBitmapDitherTypeNone, NULL, 0.0, WICBitmapPaletteTypeCustom); - ok(hr == E_INVALIDARG, "unexpected error %#x\n", hr); + ok(hr == E_INVALIDARG, "unexpected error %#lx\n", hr); hr = IWICFormatConverter_CopyPalette(converter, palette); - ok(hr == WINCODEC_ERR_WRONGSTATE, "unexpected error %#x\n", hr); + ok(hr == WINCODEC_ERR_WRONGSTATE, "unexpected error %#lx\n", hr); hr = IWICFormatConverter_CopyPixels(converter, NULL, 32, sizeof(buf), buf); - ok(hr == WINCODEC_ERR_WRONGSTATE, "unexpected error %#x\n", hr); + ok(hr == WINCODEC_ERR_WRONGSTATE, "unexpected error %#lx\n", hr); + IWICFormatConverter_Release(converter); + + hr = IWICImagingFactory_CreateFormatConverter(factory, &converter); + ok(hr == S_OK, "CreateFormatConverter error %#lx\n", hr); + hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface, + &GUID_WICPixelFormat4bppIndexed, WICBitmapDitherTypeNone, + NULL, 0.0, WICBitmapPaletteTypeCustom); + ok(hr == E_INVALIDARG, "unexpected error %#lx\n", hr); + IWICFormatConverter_Release(converter); + + hr = IWICImagingFactory_CreateFormatConverter(factory, &converter); + ok(hr == S_OK, "CreateFormatConverter error %#lx\n", hr); + hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface, + &GUID_WICPixelFormat2bppIndexed, WICBitmapDitherTypeNone, + NULL, 0.0, WICBitmapPaletteTypeCustom); + ok(hr == E_INVALIDARG, "unexpected error %#lx\n", hr); + IWICFormatConverter_Release(converter); + + hr = IWICImagingFactory_CreateFormatConverter(factory, &converter); + ok(hr == S_OK, "CreateFormatConverter error %#lx\n", hr); + hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface, + &GUID_WICPixelFormat1bppIndexed, WICBitmapDitherTypeNone, + NULL, 0.0, WICBitmapPaletteTypeCustom); + ok(hr == E_INVALIDARG, "unexpected error %#lx\n", hr); + IWICFormatConverter_Release(converter); + + hr = IWICImagingFactory_CreateFormatConverter(factory, &converter); + ok(hr == S_OK, "CreateFormatConverter error %#lx\n", hr); + hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface, + &GUID_WICPixelFormat1bppIndexed, WICBitmapDitherTypeNone, + NULL, 0.0, WICBitmapPaletteTypeMedianCut); + todo_wine ok(hr == S_OK, "unexpected error %#lx\n", hr); + IWICFormatConverter_Release(converter); + + hr = IWICImagingFactory_CreateFormatConverter(factory, &converter); + ok(hr == S_OK, "CreateFormatConverter error %#lx\n", hr); + hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface, + &GUID_WICPixelFormat1bppIndexed, WICBitmapDitherTypeNone, + NULL, 0.0, WICBitmapPaletteTypeFixedBW); + todo_wine ok(hr == S_OK, "unexpected error %#lx\n", hr); + IWICFormatConverter_Release(converter); + + hr = IWICImagingFactory_CreateFormatConverter(factory, &converter); + ok(hr == S_OK, "CreateFormatConverter error %#lx\n", hr); + hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface, + &GUID_WICPixelFormat1bppIndexed, WICBitmapDitherTypeNone, + NULL, 0.0, WICBitmapPaletteTypeFixedHalftone8); + todo_wine ok(hr == E_INVALIDARG, "unexpected error %#lx\n", hr); IWICFormatConverter_Release(converter); /* empty palette + Custom type */ hr = IWICImagingFactory_CreateFormatConverter(factory, &converter); - ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr); + ok(hr == S_OK, "CreateFormatConverter error %#lx\n", hr); hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface, &GUID_WICPixelFormat8bppIndexed, WICBitmapDitherTypeNone, palette, 0.0, WICBitmapPaletteTypeCustom); - ok(hr == S_OK, "Initialize error %#x\n", hr); + ok(hr == S_OK, "Initialize error %#lx\n", hr); hr = IWICFormatConverter_CopyPalette(converter, palette); - ok(hr == S_OK, "CopyPalette error %#x\n", hr); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); count = 0xdeadbeef; hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 0, "expected 0, got %u\n", count); memset(buf, 0xaa, sizeof(buf)); hr = IWICFormatConverter_CopyPixels(converter, NULL, 32, sizeof(buf), buf); - ok(hr == S_OK, "CopyPixels error %#x\n", hr); + ok(hr == S_OK, "CopyPixels error %#lx\n", hr); count = 0; for (i = 0; i < 32 * 2; i++) if (buf[i] != 0) count++; @@ -1752,19 +1940,19 @@ static void test_converter_8bppIndexed(void) /* NULL palette + Predefined type */ hr = IWICImagingFactory_CreateFormatConverter(factory, &converter); - ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr); + ok(hr == S_OK, "CreateFormatConverter error %#lx\n", hr); hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface, &GUID_WICPixelFormat8bppIndexed, WICBitmapDitherTypeNone, NULL, 0.0, WICBitmapPaletteTypeFixedGray16); - ok(hr == S_OK, "Initialize error %#x\n", hr); + ok(hr == S_OK, "Initialize error %#lx\n", hr); hr = IWICFormatConverter_CopyPalette(converter, palette); - ok(hr == S_OK, "CopyPalette error %#x\n", hr); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); count = 0xdeadbeef; hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 16, "expected 16, got %u\n", count); hr = IWICFormatConverter_CopyPixels(converter, NULL, 32, sizeof(buf), buf); - ok(hr == S_OK, "CopyPixels error %#x\n", hr); + ok(hr == S_OK, "CopyPixels error %#lx\n", hr); count = 0; for (i = 0; i < 32 * 2; i++) if (buf[i] != 0) count++; @@ -1773,19 +1961,19 @@ static void test_converter_8bppIndexed(void) /* not empty palette + Predefined type */ hr = IWICImagingFactory_CreateFormatConverter(factory, &converter); - ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr); + ok(hr == S_OK, "CreateFormatConverter error %#lx\n", hr); hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface, &GUID_WICPixelFormat8bppIndexed, WICBitmapDitherTypeNone, palette, 0.0, WICBitmapPaletteTypeFixedHalftone64); - ok(hr == S_OK, "Initialize error %#x\n", hr); + ok(hr == S_OK, "Initialize error %#lx\n", hr); hr = IWICFormatConverter_CopyPalette(converter, palette); - ok(hr == S_OK, "CopyPalette error %#x\n", hr); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); count = 0xdeadbeef; hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 16, "expected 16, got %u\n", count); hr = IWICFormatConverter_CopyPixels(converter, NULL, 32, sizeof(buf), buf); - ok(hr == S_OK, "CopyPixels error %#x\n", hr); + ok(hr == S_OK, "CopyPixels error %#lx\n", hr); count = 0; for (i = 0; i < 32 * 2; i++) if (buf[i] != 0) count++; @@ -1794,19 +1982,19 @@ static void test_converter_8bppIndexed(void) /* not empty palette + MedianCut type */ hr = IWICImagingFactory_CreateFormatConverter(factory, &converter); - ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr); + ok(hr == S_OK, "CreateFormatConverter error %#lx\n", hr); hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface, &GUID_WICPixelFormat8bppIndexed, WICBitmapDitherTypeNone, palette, 0.0, WICBitmapPaletteTypeMedianCut); - ok(hr == S_OK, "Initialize error %#x\n", hr); + ok(hr == S_OK, "Initialize error %#lx\n", hr); hr = IWICFormatConverter_CopyPalette(converter, palette); - ok(hr == S_OK, "CopyPalette error %#x\n", hr); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); count = 0xdeadbeef; hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 16, "expected 16, got %u\n", count); hr = IWICFormatConverter_CopyPixels(converter, NULL, 32, sizeof(buf), buf); - ok(hr == S_OK, "CopyPixels error %#x\n", hr); + ok(hr == S_OK, "CopyPixels error %#lx\n", hr); count = 0; for (i = 0; i < 32 * 2; i++) if (buf[i] != 0) count++; @@ -1815,21 +2003,21 @@ static void test_converter_8bppIndexed(void) /* NULL palette + MedianCut type */ hr = IWICImagingFactory_CreateFormatConverter(factory, &converter); - ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr); + ok(hr == S_OK, "CreateFormatConverter error %#lx\n", hr); hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface, &GUID_WICPixelFormat8bppIndexed, WICBitmapDitherTypeNone, NULL, 0.0, WICBitmapPaletteTypeMedianCut); - ok(hr == S_OK || broken(hr == E_INVALIDARG) /* XP */, "Initialize error %#x\n", hr); + ok(hr == S_OK || broken(hr == E_INVALIDARG) /* XP */, "Initialize error %#lx\n", hr); if (hr == S_OK) { hr = IWICFormatConverter_CopyPalette(converter, palette); - ok(hr == S_OK, "CopyPalette error %#x\n", hr); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); count = 0xdeadbeef; hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 8, "expected 8, got %u\n", count); hr = IWICFormatConverter_CopyPixels(converter, NULL, 32, sizeof(buf), buf); - ok(hr == S_OK, "CopyPixels error %#x\n", hr); + ok(hr == S_OK, "CopyPixels error %#lx\n", hr); count = 0; for (i = 0; i < 32 * 2; i++) if (buf[i] != 0) count++; @@ -1849,7 +2037,7 @@ START_TEST(converter) hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void **)&factory); - ok(hr == S_OK, "failed to create factory: %#x\n", hr); + ok(hr == S_OK, "failed to create factory: %#lx\n", hr); test_conversion(&testdata_24bppRGB, &testdata_1bppIndexed, "24bppRGB -> 1bppIndexed", TRUE); test_conversion(&testdata_24bppRGB, &testdata_2bppIndexed, "24bppRGB -> 2bppIndexed", TRUE); @@ -1880,6 +2068,10 @@ START_TEST(converter) test_conversion(&testdata_32bppBGR, &testdata_24bppRGB, "32bppBGR -> 24bppRGB", FALSE); test_conversion(&testdata_24bppRGB, &testdata_32bppBGR, "24bppRGB -> 32bppBGR", FALSE); test_conversion(&testdata_32bppBGRA, &testdata_24bppRGB, "32bppBGRA -> 24bppRGB", FALSE); + test_conversion(&testdata_32bppRGBA, &testdata_24bppBGR, "32bppRGBA -> 24bppBGR", FALSE); + + test_conversion(&testdata_32bppRGBA, &testdata_32bppBGRA, "32bppRGBA -> 32bppBGRA", FALSE); + test_conversion(&testdata_32bppBGRA, &testdata_32bppRGBA, "32bppBGRA -> 32bppRGBA", FALSE); test_conversion(&testdata_64bppRGBA, &testdata_32bppRGBA, "64bppRGBA -> 32bppRGBA", FALSE); test_conversion(&testdata_64bppRGBA, &testdata_32bppRGB, "64bppRGBA -> 32bppRGB", FALSE); @@ -1891,9 +2083,13 @@ START_TEST(converter) test_conversion(&testdata_32bppBGR, &testdata_8bppGray, "32bppBGR -> 8bppGray", FALSE); test_conversion(&testdata_32bppGrayFloat, &testdata_24bppBGR_gray, "32bppGrayFloat -> 24bppBGR gray", FALSE); test_conversion(&testdata_32bppGrayFloat, &testdata_8bppGray, "32bppGrayFloat -> 8bppGray", FALSE); + test_conversion(&testdata_32bppBGRA, &testdata_16bppBGRA5551, "32bppBGRA -> 16bppBGRA5551", FALSE); + test_conversion(&testdata_48bppRGB, &testdata_64bppRGBA_2, "48bppRGB -> 64bppRGBA", FALSE); test_invalid_conversion(); test_default_converter(); + test_converter_4bppGray(); + test_converter_8bppGray(); test_converter_8bppIndexed(); test_encoder(&testdata_8bppIndexed, &CLSID_WICGifEncoder, diff --git a/modules/rostests/winetests/windowscodecs/ddsformat.c b/modules/rostests/winetests/windowscodecs/ddsformat.c new file mode 100644 index 0000000000000..116a7cbba3fd2 --- /dev/null +++ b/modules/rostests/winetests/windowscodecs/ddsformat.c @@ -0,0 +1,1579 @@ +/* + * Copyright 2020 Ziqing Hui + * + * 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 COBJMACROS + +#include "windef.h" +#include "wincodec.h" +#include "wine/test.h" + +#ifdef __REACTOS__ +#define debugstr_guid wine_dbgstr_guid +#endif + +#define GET_RGB565_R(color) ((BYTE)(((color) >> 11) & 0x1F)) +#define GET_RGB565_G(color) ((BYTE)(((color) >> 5) & 0x3F)) +#define GET_RGB565_B(color) ((BYTE)(((color) >> 0) & 0x1F)) +#define MAKE_RGB565(r, g, b) ((WORD)(((BYTE)(r) << 11) | ((BYTE)(g) << 5) | (BYTE)(b))) +#define MAKE_ARGB(a, r, g, b) (((DWORD)(a) << 24) | ((DWORD)(r) << 16) | ((DWORD)(g) << 8) | (DWORD)(b)) + +#define BLOCK_WIDTH 4 +#define BLOCK_HEIGHT 4 + +/* 1x1 uncompressed(Alpha) DDS image */ +static BYTE test_dds_alpha[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF +}; + +/* 1x1 uncompressed(Luminance) DDS image */ +static BYTE test_dds_luminance[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x82 +}; + +/* 4x4 uncompressed(16bpp RGB565) DDS image */ +static BYTE test_dds_rgb565[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, + 0xE0, 0x07, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xF5, 0xA7, 0x08, 0x69, 0x4C, 0x7B, 0x08, 0x69, 0xF5, 0xA7, 0xF5, 0xA7, 0xF5, 0xA7, 0x4C, 0x7B, + 0x4C, 0x7B, 0x4C, 0x7B, 0x4C, 0x7B, 0xB1, 0x95, 0x4C, 0x7B, 0x08, 0x69, 0x08, 0x69, 0x4C, 0x7B +}; + +/* 1x1 uncompressed(24bpp RGB) DDS image */ +static BYTE test_dds_24bpp[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, + 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x70, 0x81, 0x83 +}; + +/* 1x1 uncompressed(32bpp XRGB) DDS image */ +static BYTE test_dds_32bpp_xrgb[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, + 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x70, 0x81, 0x83, 0x00 +}; + +/* 1x1 uncompressed(32bpp ARGB) DDS image */ +static BYTE test_dds_32bpp_argb[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, + 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x70, 0x81, 0x83, 0xFF +}; + +/* 1x1 uncompressed(64bpp ABGR) DDS image */ +static BYTE test_dds_64bpp[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x0F, 0x10, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x83, 0x83, 0x81, 0x81, 0x70, 0x70, 0xFF, 0xFF +}; + +/* 1x1 uncompressed(96bpp ABGR float) DDS image */ +static BYTE test_dds_96bpp[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x0F, 0x10, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 'D', 'X', '1', '0', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x84, 0x83, 0x03, 0x3F, 0x82, 0x81, 0x01, 0x3F, 0xE2, 0xE0, 0xE0, 0x3E +}; + +/* 1x1 uncompressed(128bpp ABGR float) DDS image */ +static BYTE test_dds_128bpp[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x0F, 0x10, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x84, 0x83, 0x03, 0x3F, 0x82, 0x81, 0x01, 0x3F, 0xE2, 0xE0, 0xE0, 0x3E, 0x00, 0x00, 0x80, 0x3F +}; + +/* 4x4 compressed(DXT1) cube map, mipMapCount = 3 */ +static BYTE test_dds_cube[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x0A, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 'D', 'X', 'T', '1', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x40, 0x00, + 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xF5, 0xA7, 0x08, 0x69, 0x74, 0xC0, 0xBF, 0xD7, 0x32, 0x96, 0x0B, 0x7B, 0xCC, 0x55, 0xCC, 0x55, + 0x0E, 0x84, 0x0E, 0x84, 0x00, 0x00, 0x00, 0x00, 0xF5, 0xA7, 0x08, 0x69, 0x74, 0xC0, 0xBF, 0xD7, + 0x32, 0x96, 0x0B, 0x7B, 0xCC, 0x55, 0xCC, 0x55, 0x0E, 0x84, 0x0E, 0x84, 0x00, 0x00, 0x00, 0x00, + 0xF5, 0xA7, 0x08, 0x69, 0x74, 0xC0, 0xBF, 0xD7, 0x32, 0x96, 0x0B, 0x7B, 0xCC, 0x55, 0xCC, 0x55, + 0x0E, 0x84, 0x0E, 0x84, 0x00, 0x00, 0x00, 0x00, 0xF5, 0xA7, 0x08, 0x69, 0x74, 0xC0, 0xBF, 0xD7, + 0x32, 0x96, 0x0B, 0x7B, 0xCC, 0x55, 0xCC, 0x55, 0x0E, 0x84, 0x0E, 0x84, 0x00, 0x00, 0x00, 0x00, + 0xF5, 0xA7, 0x08, 0x69, 0x74, 0xC0, 0xBF, 0xD7, 0x32, 0x96, 0x0B, 0x7B, 0xCC, 0x55, 0xCC, 0x55, + 0x0E, 0x84, 0x0E, 0x84, 0x00, 0x00, 0x00, 0x00, 0xF5, 0xA7, 0x08, 0x69, 0x74, 0xC0, 0xBF, 0xD7, + 0x32, 0x96, 0x0B, 0x7B, 0xCC, 0x55, 0xCC, 0x55, 0x0E, 0x84, 0x0E, 0x84, 0x00, 0x00, 0x00, 0x00 +}; + +/* 4x4 compressed(DXT1) cube map with extended header, mipMapCount=3 */ +static BYTE test_dds_cube_dx10[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x0A, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 'D', 'X', '1', '0', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x40, 0x00, + 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x47, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0xF5, 0xA7, 0x08, 0x69, 0x74, 0xC0, 0xBF, 0xD7, 0x32, 0x96, 0x0B, 0x7B, + 0xCC, 0x55, 0xCC, 0x55, 0x0E, 0x84, 0x0E, 0x84, 0x00, 0x00, 0x00, 0x00, 0xF5, 0xA7, 0x08, 0x69, + 0x74, 0xC0, 0xBF, 0xD7, 0x32, 0x96, 0x0B, 0x7B, 0xCC, 0x55, 0xCC, 0x55, 0x0E, 0x84, 0x0E, 0x84, + 0x00, 0x00, 0x00, 0x00, 0xF5, 0xA7, 0x08, 0x69, 0x74, 0xC0, 0xBF, 0xD7, 0x32, 0x96, 0x0B, 0x7B, + 0xCC, 0x55, 0xCC, 0x55, 0x0E, 0x84, 0x0E, 0x84, 0x00, 0x00, 0x00, 0x00, 0xF5, 0xA7, 0x08, 0x69, + 0x74, 0xC0, 0xBF, 0xD7, 0x32, 0x96, 0x0B, 0x7B, 0xCC, 0x55, 0xCC, 0x55, 0x0E, 0x84, 0x0E, 0x84, + 0x00, 0x00, 0x00, 0x00, 0xF5, 0xA7, 0x08, 0x69, 0x74, 0xC0, 0xBF, 0xD7, 0x32, 0x96, 0x0B, 0x7B, + 0xCC, 0x55, 0xCC, 0x55, 0x0E, 0x84, 0x0E, 0x84, 0x00, 0x00, 0x00, 0x00, 0xF5, 0xA7, 0x08, 0x69, + 0x74, 0xC0, 0xBF, 0xD7, 0x32, 0x96, 0x0B, 0x7B, 0xCC, 0x55, 0xCC, 0x55, 0x0E, 0x84, 0x0E, 0x84, + 0x00, 0x00, 0x00, 0x00 +}; + +/* 4x4 compressed(DXT1) DDS image with mip maps, mipMapCount=3 */ +static BYTE test_dds_mipmaps[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x0A, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 'D', 'X', 'T', '1', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xF5, 0xA7, 0x08, 0x69, 0x74, 0xC0, 0xBF, 0xD7, 0xB1, 0x95, 0x6D, 0x7B, 0xFC, 0x55, 0x5D, 0x5D, + 0x2E, 0x8C, 0x4E, 0x7C, 0xAA, 0xAB, 0xAB, 0xAB +}; + +/* 4x4 compressed(DXT1) volume texture, depth=4, mipMapCount=3 */ +static BYTE test_dds_volume[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x8A, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 'D', 'X', 'T', '1', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x40, 0x00, + 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xD5, 0xA7, 0x2C, 0x7B, 0xE0, 0x00, 0x55, 0x55, 0xD5, 0xA7, 0x49, 0x69, 0x57, 0x00, 0xFF, 0x55, + 0xD5, 0xA7, 0x48, 0x69, 0xFD, 0x80, 0xFF, 0x55, 0x30, 0x8D, 0x89, 0x71, 0x55, 0xA8, 0x00, 0xFF, + 0x32, 0x96, 0x6D, 0x83, 0xA8, 0x55, 0x5D, 0x5D, 0x0E, 0x84, 0x6D, 0x7B, 0xA8, 0xA9, 0xAD, 0xAD, + 0x2E, 0x8C, 0x2E, 0x7C, 0xAA, 0xAB, 0xAB, 0xAB +}; + +/* 4x4 compressed(DXT1) texture array, arraySize=3, mipMapCount=3 */ +static BYTE test_dds_array[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x0A, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 'D', 'X', '1', '0', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x47, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xF5, 0xA7, 0x08, 0x69, 0x74, 0xC0, 0xBF, 0xD7, 0x32, 0x96, 0x0B, 0x7B, + 0xCC, 0x55, 0xCC, 0x55, 0x0E, 0x84, 0x0E, 0x84, 0x00, 0x00, 0x00, 0x00, 0xF5, 0xA7, 0x08, 0x69, + 0x74, 0xC0, 0xBF, 0xD7, 0x32, 0x96, 0x0B, 0x7B, 0xCC, 0x55, 0xCC, 0x55, 0x0E, 0x84, 0x0E, 0x84, + 0x00, 0x00, 0x00, 0x00, 0xF5, 0xA7, 0x08, 0x69, 0x74, 0xC0, 0xBF, 0xD7, 0x32, 0x96, 0x0B, 0x7B, + 0xCC, 0x55, 0xCC, 0x55, 0x0E, 0x84, 0x0E, 0x84, 0x00, 0x00, 0x00, 0x00 +}; + +/* 4x4 compressed(DXT1c) DDS image */ +static BYTE test_dds_dxt1c[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 'D', 'X', 'T', '1', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9A, 0xE6, 0x2B, 0x39, 0x37, 0xB7, 0x7F, 0x7F +}; + +/* 4x4 compressed(DXT1a) DDS image */ +static BYTE test_dds_dxt1a[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 'D', 'X', 'T', '1', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2A, 0x31, 0xF5, 0xBC, 0xE3, 0x6E, 0x2A, 0x3A +}; + +/* 4x4 compressed(DXT2) DDS image, mipMapCount=3 */ +static BYTE test_dds_dxt2[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 'D', 'X', 'T', '2', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xDE, 0xC4, 0x10, 0x2F, 0xBF, 0xFF, 0x7B, + 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x53, 0x00, 0x00, 0x52, 0x52, 0x55, 0x55, + 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCE, 0x59, 0x00, 0x00, 0x54, 0x55, 0x55, 0x55 +}; + +/* 1x3 compressed(DXT3) DDS image, mipMapCount=2 */ +static BYTE test_dds_dxt3[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x0A, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 'D', 'X', 'T', '3', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0C, 0x92, 0x38, 0x84, 0x00, 0xFF, 0x55, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x53, 0x8B, 0x53, 0x8B, 0x00, 0x00, 0x00, 0x00 +}; + +/* 4x4 compressed(DXT4) DDS image, mipMapCount=3 */ +static BYTE test_dds_dxt4[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 'D', 'X', 'T', '4', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xDE, 0xC4, 0x10, 0x2F, 0xBF, 0xFF, 0x7B, + 0xFF, 0x00, 0x40, 0x02, 0x24, 0x49, 0x92, 0x24, 0x57, 0x53, 0x00, 0x00, 0x52, 0x52, 0x55, 0x55, + 0xFF, 0x00, 0x48, 0x92, 0x24, 0x49, 0x92, 0x24, 0xCE, 0x59, 0x00, 0x00, 0x54, 0x55, 0x55, 0x55 +}; + +/* 6x6 compressed(DXT5) image, mipMapCount=3 */ +static BYTE test_dds_dxt5[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x0A, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x44, 0x58, 0x54, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x73, 0x8E, 0x51, 0x97, 0x97, 0xBF, 0xAF, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9D, 0xC6, 0xCF, 0x52, 0x22, 0x22, 0xBB, 0x55, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0xA2, 0xB8, 0x5B, 0xF8, 0xF8, 0xF8, 0xF8, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x3A, 0x05, 0x19, 0xCC, 0x66, 0xCC, 0x66, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x9D, 0x0A, 0x39, 0xCF, 0xEF, 0x9B, 0xEF, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x6A, 0xF0, 0x6A, 0x00, 0x00, 0x00, 0x00 +}; + +/* 12x12 compressed(DXT3) texture array, arraySize=2, mipMapCount=4 */ +static BYTE test_dds_12x12[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x0A, 0x00, 0x0C, 0x00, 0x00, 0x00, + 0x0C, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 'D', 'X', '1', '0', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x4A, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB5, 0xA7, 0xAD, 0x83, + 0x60, 0x60, 0xE0, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x12, 0x96, 0x6B, 0x72, + 0xD5, 0xD5, 0xAF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x30, 0x8D, 0x89, 0x69, + 0x57, 0x5F, 0x5E, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xA7, 0xAD, 0x83, + 0x00, 0xAA, 0xFF, 0x55, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0x9E, 0x6D, 0x83, + 0x00, 0x00, 0xAA, 0x55, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x12, 0x96, 0xCD, 0x83, + 0x5C, 0xF8, 0xAA, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEC, 0x7A, 0xC9, 0x71, + 0x80, 0x60, 0x60, 0x60, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x4A, 0x72, 0xA8, 0x68, + 0x28, 0xBE, 0xD7, 0xD7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAF, 0x8C, 0xEA, 0x71, + 0x0B, 0xAB, 0xAD, 0xBD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x54, 0x9F, 0xCC, 0x7A, + 0x5C, 0xA8, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x50, 0x8D, 0x49, 0x69, + 0x77, 0xEE, 0x88, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0C, 0x7B, 0x08, 0x69, + 0xF8, 0x58, 0xF8, 0x58, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x4E, 0x84, 0x6B, 0x72, + 0x33, 0x99, 0x33, 0x99, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x14, 0x9F, 0x0A, 0x72, + 0xDC, 0xAA, 0x75, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0E, 0x84, 0x0E, 0x84, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB5, 0xA7, 0xAD, 0x83, + 0x60, 0x60, 0xE0, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x12, 0x96, 0x6B, 0x72, + 0xD5, 0xD5, 0xAF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x30, 0x8D, 0x89, 0x69, + 0x57, 0x5F, 0x5E, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xA7, 0xAD, 0x83, + 0x00, 0xAA, 0xFF, 0x55, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0x9E, 0x6D, 0x83, + 0x00, 0x00, 0xAA, 0x55, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x12, 0x96, 0xCD, 0x83, + 0x5C, 0xF8, 0xAA, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEC, 0x7A, 0xC9, 0x71, + 0x80, 0x60, 0x60, 0x60, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x4A, 0x72, 0xA8, 0x68, + 0x28, 0xBE, 0xD7, 0xD7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAF, 0x8C, 0xEA, 0x71, + 0x0B, 0xAB, 0xAD, 0xBD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x54, 0x9F, 0xCC, 0x7A, + 0x5C, 0xA8, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x50, 0x8D, 0x49, 0x69, + 0x77, 0xEE, 0x88, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0C, 0x7B, 0x08, 0x69, + 0xF8, 0x58, 0xF8, 0x58, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x4E, 0x84, 0x6B, 0x72, + 0x33, 0x99, 0x33, 0x99, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x14, 0x9F, 0x0A, 0x72, + 0xDC, 0xAA, 0x75, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0E, 0x84, 0x0E, 0x84, + 0x00, 0x00, 0x00, 0x00 +}; + +static BYTE test_dds_bad_magic[sizeof(test_dds_dxt1c)]; +static BYTE test_dds_bad_header[sizeof(test_dds_dxt1c)]; +static BYTE test_byte[1] = { 0 }; +static BYTE test_word[2] = { 0 }; +static BYTE test_dword[4] = { 0 }; +static BYTE test_qword_a[8] = { 0 }; +static BYTE test_qword_b[8] = "DDS "; + +static struct test_data { + BYTE *data; + UINT size; + HRESULT init_hr; + UINT expected_frame_count; + UINT expected_bytes_per_block; + UINT pixel_format_bpp; + const GUID *expected_pixel_format; + WICDdsParameters expected_parameters; + BOOL wine_init; +} test_data[] = { + { test_dds_alpha, sizeof(test_dds_alpha), WINCODEC_ERR_BADHEADER, 1, 1, 8, &GUID_WICPixelFormat8bppAlpha, + { 1, 1, 1, 1, 1, DXGI_FORMAT_A8_UNORM, WICDdsTexture2D, WICDdsAlphaModeUnknown }, TRUE }, + { test_dds_luminance, sizeof(test_dds_luminance), WINCODEC_ERR_BADHEADER, 1, 1, 8, &GUID_WICPixelFormat8bppGray, + { 1, 1, 1, 1, 1, DXGI_FORMAT_R8_UNORM, WICDdsTexture2D, WICDdsAlphaModeUnknown }, TRUE }, + { test_dds_rgb565, sizeof(test_dds_rgb565), WINCODEC_ERR_BADHEADER, 1, 2, 16, &GUID_WICPixelFormat16bppBGR565, + { 4, 4, 1, 1, 1, DXGI_FORMAT_B5G6R5_UNORM, WICDdsTexture2D, WICDdsAlphaModeUnknown }, TRUE }, + { test_dds_24bpp, sizeof(test_dds_24bpp), WINCODEC_ERR_BADHEADER, 1, 3, 24, &GUID_WICPixelFormat24bppBGR, + { 1, 1, 1, 1, 1, DXGI_FORMAT_UNKNOWN, WICDdsTexture2D, WICDdsAlphaModeUnknown }, TRUE }, + { test_dds_32bpp_xrgb, sizeof(test_dds_32bpp_xrgb), WINCODEC_ERR_BADHEADER, 1, 4, 32, &GUID_WICPixelFormat32bppBGR, + { 1, 1, 1, 1, 1, DXGI_FORMAT_B8G8R8X8_UNORM, WICDdsTexture2D, WICDdsAlphaModeUnknown }, TRUE }, + { test_dds_32bpp_argb, sizeof(test_dds_32bpp_argb), WINCODEC_ERR_BADHEADER, 1, 4, 32, &GUID_WICPixelFormat32bppBGRA, + { 1, 1, 1, 1, 1, DXGI_FORMAT_B8G8R8A8_UNORM, WICDdsTexture2D, WICDdsAlphaModeUnknown }, TRUE }, + { test_dds_64bpp, sizeof(test_dds_64bpp), WINCODEC_ERR_BADHEADER, 1, 8, 64, &GUID_WICPixelFormat64bppRGBA, + { 1, 1, 1, 1, 1, DXGI_FORMAT_R16G16B16A16_UNORM, WICDdsTexture2D, WICDdsAlphaModeUnknown }, TRUE }, + { test_dds_96bpp, sizeof(test_dds_96bpp), WINCODEC_ERR_BADHEADER, 1, 12, 96, &GUID_WICPixelFormat96bppRGBFloat, + { 1, 1, 1, 1, 1, DXGI_FORMAT_R32G32B32_FLOAT, WICDdsTexture2D, WICDdsAlphaModeUnknown }, TRUE }, + { test_dds_128bpp, sizeof(test_dds_128bpp), WINCODEC_ERR_BADHEADER, 1, 16, 128, &GUID_WICPixelFormat128bppRGBAFloat, + { 1, 1, 1, 1, 1, DXGI_FORMAT_R32G32B32A32_FLOAT, WICDdsTexture2D, WICDdsAlphaModeUnknown }, TRUE }, + { test_dds_cube, sizeof(test_dds_cube), WINCODEC_ERR_BADHEADER, 18, 8, 32, &GUID_WICPixelFormat32bppPBGRA, + { 4, 4, 1, 3, 1, DXGI_FORMAT_BC1_UNORM, WICDdsTextureCube, WICDdsAlphaModePremultiplied }, TRUE }, + { test_dds_cube_dx10, sizeof(test_dds_cube_dx10), WINCODEC_ERR_BADHEADER, 18, 8, 32, &GUID_WICPixelFormat32bppBGRA, + { 4, 4, 1, 3, 1, DXGI_FORMAT_BC1_UNORM, WICDdsTextureCube, WICDdsAlphaModeUnknown }, TRUE }, + { test_dds_mipmaps, sizeof(test_dds_mipmaps), S_OK, 3, 8, 32, &GUID_WICPixelFormat32bppPBGRA, + { 4, 4, 1, 3, 1, DXGI_FORMAT_BC1_UNORM, WICDdsTexture2D, WICDdsAlphaModePremultiplied } }, + { test_dds_volume, sizeof(test_dds_volume), S_OK, 7, 8, 32, &GUID_WICPixelFormat32bppPBGRA, + { 4, 4, 4, 3, 1, DXGI_FORMAT_BC1_UNORM, WICDdsTexture3D, WICDdsAlphaModePremultiplied } }, + { test_dds_array, sizeof(test_dds_array), S_OK, 9, 8, 32, &GUID_WICPixelFormat32bppBGRA, + { 4, 4, 1, 3, 3, DXGI_FORMAT_BC1_UNORM, WICDdsTexture2D, WICDdsAlphaModeUnknown } }, + { test_dds_dxt1c, sizeof(test_dds_dxt1c), S_OK, 1, 8, 32, &GUID_WICPixelFormat32bppPBGRA, + { 4, 4, 1, 1, 1, DXGI_FORMAT_BC1_UNORM, WICDdsTexture2D, WICDdsAlphaModePremultiplied } }, + { test_dds_dxt1a, sizeof(test_dds_dxt1a), S_OK, 1, 8, 32, &GUID_WICPixelFormat32bppPBGRA, + { 4, 4, 1, 1, 1, DXGI_FORMAT_BC1_UNORM, WICDdsTexture2D, WICDdsAlphaModePremultiplied } }, + { test_dds_dxt2, sizeof(test_dds_dxt2), S_OK, 3, 16, 32, &GUID_WICPixelFormat32bppPBGRA, + { 4, 4, 1, 3, 1, DXGI_FORMAT_BC2_UNORM, WICDdsTexture2D, WICDdsAlphaModePremultiplied } }, + { test_dds_dxt3, sizeof(test_dds_dxt3), S_OK, 2, 16, 32, &GUID_WICPixelFormat32bppBGRA, + { 1, 3, 1, 2, 1, DXGI_FORMAT_BC2_UNORM, WICDdsTexture2D, WICDdsAlphaModeUnknown } }, + { test_dds_dxt4, sizeof(test_dds_dxt4), S_OK, 3, 16, 32, &GUID_WICPixelFormat32bppPBGRA, + { 4, 4, 1, 3, 1, DXGI_FORMAT_BC3_UNORM, WICDdsTexture2D, WICDdsAlphaModePremultiplied } }, + { test_dds_dxt5, sizeof(test_dds_dxt5), S_OK, 3, 16, 32, &GUID_WICPixelFormat32bppBGRA, + { 6, 6, 1, 3, 1, DXGI_FORMAT_BC3_UNORM, WICDdsTexture2D, WICDdsAlphaModeUnknown } }, + { test_dds_12x12, sizeof(test_dds_12x12), S_OK, 8, 16, 32, &GUID_WICPixelFormat32bppBGRA, + { 12, 12, 1, 4, 2, DXGI_FORMAT_BC2_UNORM, WICDdsTexture2D, WICDdsAlphaModeUnknown } }, + { test_dds_bad_magic, sizeof(test_dds_bad_magic), WINCODEC_ERR_UNKNOWNIMAGEFORMAT }, + { test_dds_bad_header, sizeof(test_dds_bad_header), WINCODEC_ERR_BADHEADER }, + { test_byte, sizeof(test_byte), WINCODEC_ERR_STREAMREAD }, + { test_word, sizeof(test_word), WINCODEC_ERR_STREAMREAD }, + { test_dword, sizeof(test_dword), WINCODEC_ERR_UNKNOWNIMAGEFORMAT }, + { test_qword_a, sizeof(test_qword_a), WINCODEC_ERR_UNKNOWNIMAGEFORMAT }, + { test_qword_b, sizeof(test_qword_b), WINCODEC_ERR_STREAMREAD }, +}; + +static DXGI_FORMAT compressed_formats[] = { + DXGI_FORMAT_BC1_TYPELESS, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM_SRGB, + DXGI_FORMAT_BC2_TYPELESS, DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM_SRGB, + DXGI_FORMAT_BC3_TYPELESS, DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_UNORM_SRGB, + DXGI_FORMAT_BC4_TYPELESS, DXGI_FORMAT_BC4_UNORM, DXGI_FORMAT_BC4_SNORM, + DXGI_FORMAT_BC5_TYPELESS, DXGI_FORMAT_BC5_UNORM, DXGI_FORMAT_BC5_SNORM, + DXGI_FORMAT_BC6H_TYPELESS, DXGI_FORMAT_BC6H_UF16, DXGI_FORMAT_BC6H_SF16, + DXGI_FORMAT_BC7_TYPELESS, DXGI_FORMAT_BC7_UNORM, DXGI_FORMAT_BC7_UNORM_SRGB +}; + +static IWICImagingFactory *factory = NULL; + +static IWICStream *create_stream(const void *image_data, UINT image_size) +{ + HRESULT hr; + IWICStream *stream = NULL; + + hr = IWICImagingFactory_CreateStream(factory, &stream); + ok(hr == S_OK, "CreateStream failed, hr %#lx\n", hr); + if (hr != S_OK) goto fail; + + hr = IWICStream_InitializeFromMemory(stream, (BYTE *)image_data, image_size); + ok(hr == S_OK, "InitializeFromMemory failed, hr %#lx\n", hr); + if (hr != S_OK) goto fail; + + return stream; + +fail: + if (stream) IWICStream_Release(stream); + return NULL; +} + +static IWICBitmapDecoder *create_decoder(void) +{ + HRESULT hr; + IWICBitmapDecoder *decoder = NULL; + GUID guidresult; + + hr = CoCreateInstance(&CLSID_WICDdsDecoder, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICBitmapDecoder, (void **)&decoder); + if (hr != S_OK) { + win_skip("Dds decoder is not supported\n"); + return NULL; + } + + memset(&guidresult, 0, sizeof(guidresult)); + hr = IWICBitmapDecoder_GetContainerFormat(decoder, &guidresult); + ok(hr == S_OK, "GetContainerFormat failed, hr %#lx\n", hr); + ok(IsEqualGUID(&guidresult, &GUID_ContainerFormatDds), + "Got unexpected container format %s\n", debugstr_guid(&guidresult)); + + return decoder; +} + +static IWICBitmapEncoder *create_encoder(void) +{ + IWICBitmapEncoder *encoder = NULL; + GUID guidresult; + HRESULT hr; + + hr = CoCreateInstance(&CLSID_WICDdsEncoder, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICBitmapEncoder, (void **)&encoder); + if (hr != S_OK) + { + win_skip("DDS encoder is not supported\n"); + return NULL; + } + + memset(&guidresult, 0, sizeof(guidresult)); + + hr = IWICBitmapEncoder_GetContainerFormat(encoder, &guidresult); + ok(hr == S_OK, "GetContainerFormat failed, hr %#lx\n", hr); + + ok(IsEqualGUID(&guidresult, &GUID_ContainerFormatDds), + "Got unexpected container format %s\n", debugstr_guid(&guidresult)); + + return encoder; +} + +static HRESULT init_decoder(IWICBitmapDecoder *decoder, IWICStream *stream, HRESULT expected, BOOL wine_init) +{ + HRESULT hr; + IWICWineDecoder *wine_decoder; + + hr = IWICBitmapDecoder_Initialize(decoder, (IStream*)stream, WICDecodeMetadataCacheOnDemand); + ok(hr == expected, "Expected hr %#lx, got %#lx\n", expected, hr); + + if (hr != S_OK && wine_init) { + hr = IWICBitmapDecoder_QueryInterface(decoder, &IID_IWICWineDecoder, (void **)&wine_decoder); + ok(hr == S_OK || broken(hr != S_OK), "QueryInterface failed, hr %#lx\n", hr); + + if (hr == S_OK) { + hr = IWICWineDecoder_Initialize(wine_decoder, (IStream*)stream, WICDecodeMetadataCacheOnDemand); + ok(hr == S_OK, "Initialize failed, hr %#lx\n", hr); + } + } + + return hr; +} + +static void release_encoder(IWICBitmapEncoder *encoder, IWICDdsEncoder *dds_encoder, IWICStream *stream) +{ + if (dds_encoder) IWICDdsEncoder_Release(dds_encoder); + if (stream) IWICStream_Release(stream); + if (encoder) IWICBitmapEncoder_Release(encoder); +} + +static HRESULT create_and_init_encoder(BYTE *image_buffer, UINT buffer_size, WICDdsParameters *params, + IWICBitmapEncoder **encoder, IWICDdsEncoder **dds_encoder, IWICStream **stream) +{ + IWICDdsEncoder *dds = NULL; + HRESULT hr; + + *encoder = create_encoder(); + if (!*encoder) goto fail; + + *stream = create_stream(image_buffer, buffer_size); + if (!*stream) goto fail; + + hr = IWICBitmapEncoder_Initialize(*encoder, (IStream *)*stream, WICBitmapEncoderNoCache); + ok(hr == S_OK, "Initialize failed, hr %#lx\n", hr); + if (hr != S_OK) goto fail; + + hr = IWICBitmapEncoder_QueryInterface(*encoder, &IID_IWICDdsEncoder, (void **)&dds); + ok(hr == S_OK, "QueryInterface failed, hr %#lx\n", hr); + if (hr != S_OK) goto fail; + + if (params) + { + hr = IWICDdsEncoder_SetParameters(dds, params); + ok(hr == S_OK, "SetParameters failed, hr %#lx\n", hr); + if (hr != S_OK) goto fail; + } + + if (dds_encoder) + { + *dds_encoder = dds; + } + else + { + IWICDdsEncoder_Release(dds); + dds = NULL; + } + + return S_OK; + +fail: + release_encoder(*encoder, dds, *stream); + return E_FAIL; +} + +static BOOL is_compressed(DXGI_FORMAT format) +{ + UINT i; + for (i = 0; i < ARRAY_SIZE(compressed_formats); i++) + { + if (format == compressed_formats[i]) return TRUE; + } + return FALSE; +} + +static BOOL has_extended_header(const BYTE *data) +{ + return data[84] == 'D' && data[85] == 'X' && data[86] == '1' && data[87] == '0'; +} + +static DWORD rgb565_to_argb(WORD color, BYTE alpha) +{ + return MAKE_ARGB(alpha, (GET_RGB565_R(color) * 0xFF + 0x0F) / 0x1F, + (GET_RGB565_G(color) * 0xFF + 0x1F) / 0x3F, + (GET_RGB565_B(color) * 0xFF + 0x0F) / 0x1F); +} + +static void decode_block(const BYTE *block_data, UINT block_count, DXGI_FORMAT format, + UINT width, UINT height, DWORD *buffer) +{ + const BYTE *block, *color_indices, *alpha_indices, *alpha_table; + int i, j, x, y, block_x, block_y, color_index, alpha_index; + int block_size, color_offset, color_indices_offset; + WORD color[4], color_value = 0; + BYTE alpha[8], alpha_value = 0; + + if (format == DXGI_FORMAT_BC1_UNORM) { + block_size = 8; + color_offset = 0; + color_indices_offset = 4; + } else { + block_size = 16; + color_offset = 8; + color_indices_offset = 12; + } + block_x = 0; + block_y = 0; + + for (i = 0; i < block_count; i++) + { + block = block_data + i * block_size; + + color[0] = *((WORD *)(block + color_offset)); + color[1] = *((WORD *)(block + color_offset + 2)); + color[2] = MAKE_RGB565(((GET_RGB565_R(color[0]) * 2 + GET_RGB565_R(color[1]) + 1) / 3), + ((GET_RGB565_G(color[0]) * 2 + GET_RGB565_G(color[1]) + 1) / 3), + ((GET_RGB565_B(color[0]) * 2 + GET_RGB565_B(color[1]) + 1) / 3)); + color[3] = MAKE_RGB565(((GET_RGB565_R(color[0]) + GET_RGB565_R(color[1]) * 2 + 1) / 3), + ((GET_RGB565_G(color[0]) + GET_RGB565_G(color[1]) * 2 + 1) / 3), + ((GET_RGB565_B(color[0]) + GET_RGB565_B(color[1]) * 2 + 1) / 3)); + + switch (format) + { + case DXGI_FORMAT_BC1_UNORM: + if (color[0] <= color[1]) { + color[2] = MAKE_RGB565(((GET_RGB565_R(color[0]) + GET_RGB565_R(color[1]) + 1) / 2), + ((GET_RGB565_G(color[0]) + GET_RGB565_G(color[1]) + 1) / 2), + ((GET_RGB565_B(color[0]) + GET_RGB565_B(color[1]) + 1) / 2)); + color[3] = 0; + } + break; + case DXGI_FORMAT_BC2_UNORM: + alpha_table = block; + break; + case DXGI_FORMAT_BC3_UNORM: + alpha[0] = *block; + alpha[1] = *(block + 1); + if (alpha[0] > alpha[1]) { + for (j = 2; j < 8; j++) + { + alpha[j] = (BYTE)((alpha[0] * (8 - j) + alpha[1] * (j - 1) + 3) / 7); + } + } else { + for (j = 2; j < 6; j++) + { + alpha[j] = (BYTE)((alpha[0] * (6 - j) + alpha[1] * (j - 1) + 2) / 5); + } + alpha[6] = 0; + alpha[7] = 0xFF; + } + alpha_indices = block + 2; + break; + default: + break; + } + + color_indices = block + color_indices_offset; + for (j = 0; j < 16; j++) + { + x = block_x + j % 4; + y = block_y + j / 4; + if (x >= width || y >= height) continue; + + color_index = (color_indices[j / 4] >> ((j % 4) * 2)) & 0x3; + color_value = color[color_index]; + + switch (format) + { + case DXGI_FORMAT_BC1_UNORM: + if ((color[0] <= color[1]) && !color_value) { + color_value = 0; + alpha_value = 0; + } else { + alpha_value = 0xFF; + } + break; + case DXGI_FORMAT_BC2_UNORM: + alpha_value = (alpha_table[j / 2] >> (j % 2) * 4) & 0xF; + alpha_value = (BYTE)((alpha_value * 0xFF + 0x7)/ 0xF); + break; + case DXGI_FORMAT_BC3_UNORM: + alpha_index = (*((DWORD *)(alpha_indices + (j / 8) * 3)) >> ((j % 8) * 3)) & 0x7; + alpha_value = alpha[alpha_index]; + break; + default: + break; + } + buffer[x + y * width] = rgb565_to_argb(color_value, alpha_value); + } + + block_x += BLOCK_WIDTH; + if (block_x >= width) { + block_x = 0; + block_y += BLOCK_HEIGHT; + } + } +} + +static BOOL color_match(DWORD color_a, DWORD color_b) +{ + static const int tolerance = 8; + + const int da = abs((int)((color_a & 0xFF000000) >> 24) - (int)((color_b & 0xFF000000) >> 24)); + const int dr = abs((int)((color_a & 0x00FF0000) >> 16) - (int)((color_b & 0x00FF0000) >> 16)); + const int dg = abs((int)((color_a & 0x0000FF00) >> 8) - (int)((color_b & 0x0000FF00) >> 8)); + const int db = abs((int)((color_a & 0x000000FF) >> 0) - (int)((color_b & 0x000000FF) >> 0)); + + return (da <= tolerance && dr <= tolerance && dg <= tolerance && db <= tolerance); +} + +static BOOL color_buffer_match(DWORD *color_buffer_a, DWORD *color_buffer_b, UINT color_count) +{ + UINT i; + + for (i = 0; i < color_count; i++) + { + if (!color_match(color_buffer_a[i], color_buffer_b[i])) return FALSE; + } + + return TRUE; +} + +static void copy_pixels(void *src_buffer, UINT src_stride, void *dst_buffer, UINT dst_stride, UINT size) +{ + char *src = src_buffer, *dst = dst_buffer; + UINT i; + + for (i = 0; i < size; i++) + { + *dst = src[i]; + if (i % src_stride == src_stride - 1) dst += dst_stride - src_stride; + dst ++; + } +} + +static void test_dds_decoder_initialize(void) +{ + int i; + + memcpy(test_dds_bad_magic, test_dds_dxt1c, sizeof(test_dds_dxt1c)); + memcpy(test_dds_bad_header, test_dds_dxt1c, sizeof(test_dds_dxt1c)); + test_dds_bad_magic[0] = 0; + test_dds_bad_header[4] = 0; + + for (i = 0; i < ARRAY_SIZE(test_data); i++) + { + IWICStream *stream = NULL; + IWICBitmapDecoder *decoder = NULL; + + winetest_push_context("Test %u", i); + + stream = create_stream(test_data[i].data, test_data[i].size); + if (!stream) goto next; + + decoder = create_decoder(); + if (!decoder) goto next; + + init_decoder(decoder, stream, test_data[i].init_hr, test_data[i].wine_init); + + next: + if (decoder) IWICBitmapDecoder_Release(decoder); + if (stream) IWICStream_Release(stream); + winetest_pop_context(); + } +} + +static void test_dds_decoder_global_properties(IWICBitmapDecoder *decoder) +{ + HRESULT hr; + IWICPalette *palette = NULL; + IWICMetadataQueryReader *metadata_reader = NULL; + IWICBitmapSource *preview = NULL, *thumnail = NULL; + IWICColorContext *color_context = NULL; + UINT count; + + hr = IWICImagingFactory_CreatePalette(factory, &palette); + ok(hr == S_OK, "CreatePalette failed, hr %#lx\n", hr); + if (hr == S_OK) { + hr = IWICBitmapDecoder_CopyPalette(decoder, palette); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "CopyPalette got unexpected hr %#lx\n", hr); + hr = IWICBitmapDecoder_CopyPalette(decoder, NULL); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "CopyPalette got unexpected hr %#lx\n", hr); + } + + hr = IWICBitmapDecoder_GetMetadataQueryReader(decoder, &metadata_reader); + todo_wine ok (hr == S_OK, "GetMetadataQueryReader got unexpected hr %#lx\n", hr); + hr = IWICBitmapDecoder_GetMetadataQueryReader(decoder, NULL); + ok(hr == E_INVALIDARG, "GetMetadataQueryReader got unexpected hr %#lx\n", hr); + + hr = IWICBitmapDecoder_GetPreview(decoder, &preview); + ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "GetPreview got unexpected hr %#lx\n", hr); + hr = IWICBitmapDecoder_GetPreview(decoder, NULL); + ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "GetPreview got unexpected hr %#lx\n", hr); + + hr = IWICBitmapDecoder_GetColorContexts(decoder, 1, &color_context, &count); + ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "GetColorContexts got unexpected hr %#lx\n", hr); + hr = IWICBitmapDecoder_GetColorContexts(decoder, 1, NULL, NULL); + ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "GetColorContexts got unexpected hr %#lx\n", hr); + + hr = IWICBitmapDecoder_GetThumbnail(decoder, &thumnail); + ok(hr == WINCODEC_ERR_CODECNOTHUMBNAIL, "GetThumbnail got unexpected hr %#lx\n", hr); + hr = IWICBitmapDecoder_GetThumbnail(decoder, NULL); + ok(hr == WINCODEC_ERR_CODECNOTHUMBNAIL, "GetThumbnail got unexpected hr %#lx\n", hr); + + if (palette) IWICPalette_Release(palette); + if (metadata_reader) IWICMetadataQueryReader_Release(metadata_reader); + if (preview) IWICBitmapSource_Release(preview); + if (color_context) IWICColorContext_Release(color_context); + if (thumnail) IWICBitmapSource_Release(thumnail); +} + +static void test_dds_decoder_image_parameters(void) +{ + int i; + HRESULT hr; + WICDdsParameters parameters; + + for (i = 0; i < ARRAY_SIZE(test_data); i++) + { + UINT frame_count; + IWICStream *stream = NULL; + IWICBitmapDecoder *decoder = NULL; + IWICDdsDecoder *dds_decoder = NULL; + + winetest_push_context("Test %u", i); + + stream = create_stream(test_data[i].data, test_data[i].size); + if (!stream) goto next; + + decoder = create_decoder(); + if (!decoder) goto next; + + hr = IWICBitmapDecoder_QueryInterface(decoder, &IID_IWICDdsDecoder, (void **)&dds_decoder); + ok(hr == S_OK, "QueryInterface failed, hr %#lx\n", hr); + if (hr != S_OK) goto next; + + hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count); + ok(hr == WINCODEC_ERR_WRONGSTATE, "GetFrameCount got unexpected hr %#lx\n", hr); + hr = IWICBitmapDecoder_GetFrameCount(decoder, NULL); + ok(hr == E_INVALIDARG, "GetFrameCount got unexpected hr %#lx\n", hr); + + hr = IWICDdsDecoder_GetParameters(dds_decoder, ¶meters); + ok(hr == WINCODEC_ERR_WRONGSTATE, "GetParameters got unexpected hr %#lx\n", hr); + hr = IWICDdsDecoder_GetParameters(dds_decoder, NULL); + ok(hr == E_INVALIDARG, "GetParameters got unexpected hr %#lx\n", hr); + + if (test_data[i].init_hr != S_OK && !test_data[i].wine_init) goto next; + + hr = init_decoder(decoder, stream, test_data[i].init_hr, test_data[i].wine_init); + if (hr != S_OK) { + if (test_data[i].expected_parameters.Dimension == WICDdsTextureCube) { + win_skip("Cube map is not supported\n"); + } else { + win_skip("Uncompressed DDS image is not supported\n"); + } + goto next; + } + + hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count); + ok(hr == S_OK, "GetFrameCount failed, hr %#lx\n", hr); + if (hr == S_OK) { + ok(frame_count == test_data[i].expected_frame_count, "Expected frame count %u, got %u\n", + test_data[i].expected_frame_count, frame_count); + } + hr = IWICBitmapDecoder_GetFrameCount(decoder, NULL); + ok(hr == E_INVALIDARG, "GetParameters got unexpected hr %#lx\n", hr); + + hr = IWICDdsDecoder_GetParameters(dds_decoder, ¶meters); + ok(hr == S_OK, "GetParameters failed, hr %#lx\n", hr); + if (hr == S_OK) { + ok(parameters.Width == test_data[i].expected_parameters.Width, + "Expected Width %u, got %u\n", test_data[i].expected_parameters.Width, parameters.Width); + ok(parameters.Height == test_data[i].expected_parameters.Height, + "Expected Height %u, got %u\n", test_data[i].expected_parameters.Height, parameters.Height); + ok(parameters.Depth == test_data[i].expected_parameters.Depth, + "Expected Depth %u, got %u\n", test_data[i].expected_parameters.Depth, parameters.Depth); + ok(parameters.MipLevels == test_data[i].expected_parameters.MipLevels, + "Expected MipLevels %u, got %u\n", test_data[i].expected_parameters.MipLevels, parameters.MipLevels); + ok(parameters.ArraySize == test_data[i].expected_parameters.ArraySize, + "Expected ArraySize %u, got %u\n", test_data[i].expected_parameters.ArraySize, parameters.ArraySize); + ok(parameters.DxgiFormat == test_data[i].expected_parameters.DxgiFormat, + "Expected DxgiFormat %#x, got %#x\n", test_data[i].expected_parameters.DxgiFormat, parameters.DxgiFormat); + ok(parameters.Dimension == test_data[i].expected_parameters.Dimension, + "Expected Dimension %#x, got %#x\n", test_data[i].expected_parameters.Dimension, parameters.Dimension); + ok(parameters.AlphaMode == test_data[i].expected_parameters.AlphaMode, + "Expected AlphaMode %#x, got %#x\n", test_data[i].expected_parameters.AlphaMode, parameters.AlphaMode); + } + hr = IWICDdsDecoder_GetParameters(dds_decoder, NULL); + ok(hr == E_INVALIDARG, "GetParameters got unexpected hr %#lx\n", hr); + + next: + if (decoder) IWICBitmapDecoder_Release(decoder); + if (stream) IWICStream_Release(stream); + if (dds_decoder) IWICDdsDecoder_Release(dds_decoder); + winetest_pop_context(); + } +} + +static void test_dds_decoder_frame_properties(IWICBitmapFrameDecode *frame_decode, IWICDdsFrameDecode *dds_frame, + UINT frame_count, WICDdsParameters *params, struct test_data *test, UINT frame_index) +{ + HRESULT hr; + UINT width, height ,expected_width, expected_height, slice_index, depth; + UINT width_in_blocks, height_in_blocks, expected_width_in_blocks, expected_height_in_blocks; + UINT expected_block_width, expected_block_height; + WICDdsFormatInfo format_info; + GUID pixel_format; + + /* frame size tests */ + + hr = IWICBitmapFrameDecode_GetSize(frame_decode, NULL, NULL); + ok(hr == E_INVALIDARG, "GetSize got unexpected hr %#lx\n", hr); + hr = IWICBitmapFrameDecode_GetSize(frame_decode, NULL, &height); + ok(hr == E_INVALIDARG, "GetSize got unexpected hr %#lx\n", hr); + hr = IWICBitmapFrameDecode_GetSize(frame_decode, &width, NULL); + ok(hr == E_INVALIDARG, "GetSize got unexpected hr %#lx\n", hr); + hr = IWICBitmapFrameDecode_GetSize(frame_decode, &width, &height); + ok(hr == S_OK, "GetSize failed, hr %#lx\n", hr); + if (hr != S_OK) return; + + depth = params->Depth; + expected_width = params->Width; + expected_height = params->Height; + slice_index = frame_index % (frame_count / params->ArraySize); + while (slice_index >= depth) + { + if (expected_width > 1) expected_width /= 2; + if (expected_height > 1) expected_height /= 2; + slice_index -= depth; + if (depth > 1) depth /= 2; + } + ok(width == expected_width, "Expected width %u, got %u\n", expected_width, width); + ok(height == expected_height, "Expected height %u, got %u\n", expected_height, height); + + /* frame format information tests */ + + if (is_compressed(test->expected_parameters.DxgiFormat)) { + expected_block_width = BLOCK_WIDTH; + expected_block_height = BLOCK_HEIGHT; + } else { + expected_block_width = 1; + expected_block_height = 1; + } + + hr = IWICDdsFrameDecode_GetFormatInfo(dds_frame, NULL); + ok(hr == E_INVALIDARG, "GetFormatInfo got unexpected hr %#lx\n", hr); + hr = IWICDdsFrameDecode_GetFormatInfo(dds_frame, &format_info); + ok(hr == S_OK, "GetFormatInfo failed, hr %#lx\n", hr); + if (hr != S_OK) return; + + ok(format_info.DxgiFormat == test->expected_parameters.DxgiFormat, + "Expected DXGI format %#x, got %#x\n", + test->expected_parameters.DxgiFormat, format_info.DxgiFormat); + ok(format_info.BytesPerBlock == test->expected_bytes_per_block, + "Expected bytes per block %u, got %u\n", + test->expected_bytes_per_block, format_info.BytesPerBlock); + ok(format_info.BlockWidth == expected_block_width, + "Expected block width %u, got %u\n", + expected_block_width, format_info.BlockWidth); + ok(format_info.BlockHeight == expected_block_height, + "Expected block height %u, got %u\n", + expected_block_height, format_info.BlockHeight); + + + /* size in blocks tests */ + + hr = IWICDdsFrameDecode_GetSizeInBlocks(dds_frame, NULL, NULL); + ok(hr == E_INVALIDARG, "GetSizeInBlocks got unexpected hr %#lx\n", hr); + hr = IWICDdsFrameDecode_GetSizeInBlocks(dds_frame, NULL, &height_in_blocks); + ok(hr == E_INVALIDARG, "GetSizeInBlocks got unexpected hr %#lx\n", hr); + hr = IWICDdsFrameDecode_GetSizeInBlocks(dds_frame, &width_in_blocks, NULL); + ok(hr == E_INVALIDARG, "GetSizeInBlocks got unexpected hr %#lx\n", hr); + hr = IWICDdsFrameDecode_GetSizeInBlocks(dds_frame, &width_in_blocks, &height_in_blocks); + ok(hr == S_OK, "GetSizeInBlocks failed, hr %#lx\n", hr); + if (hr != S_OK) return; + + expected_width_in_blocks = (expected_width + expected_block_width - 1) / expected_block_width; + expected_height_in_blocks = (expected_height + expected_block_height - 1) / expected_block_height; + ok(width_in_blocks == expected_width_in_blocks, + "Expected width in blocks %u, got %u\n", expected_width_in_blocks, width_in_blocks); + ok(height_in_blocks == expected_height_in_blocks, + "Expected height in blocks %u, got %u\n", expected_height_in_blocks, height_in_blocks); + + /* pixel format tests */ + + hr = IWICBitmapFrameDecode_GetPixelFormat(frame_decode, NULL); + ok(hr == E_INVALIDARG, "GetPixelFormat got unexpected hr %#lx\n", hr); + hr = IWICBitmapFrameDecode_GetPixelFormat(frame_decode, &pixel_format); + ok(hr == S_OK, "GetPixelFormat failed, hr %#lx\n", hr); + if (hr != S_OK) return; + ok(IsEqualGUID(&pixel_format, test->expected_pixel_format), + "Expected pixel format %s, got %s\n", + debugstr_guid(test->expected_pixel_format), debugstr_guid(&pixel_format)); +} + +static void test_dds_decoder_frame_data(IWICBitmapFrameDecode* frame, IWICDdsFrameDecode *dds_frame, UINT frame_count, + WICDdsParameters *params, struct test_data *test, UINT frame_index) +{ + HRESULT hr; + GUID pixel_format; + WICDdsFormatInfo format_info; + WICRect rect = { 0, 0, 1, 1 }, rect_test_a = { 0, 0, 0, 0 }, rect_test_b = { 0, 0, 0xdeadbeaf, 0xdeadbeaf }; + WICRect rect_test_c = { -0xdeadbeaf, -0xdeadbeaf, 1, 1 }, rect_test_d = { 0xdeadbeaf, 0xdeadbeaf, 1, 1 }; + BYTE buffer[2048], pixels[2048]; + UINT stride, frame_stride, frame_size, frame_width, frame_height, width_in_blocks, height_in_blocks, bpp; + UINT width, height, depth, array_index; + UINT block_offset; + int slice_index; + + hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &pixel_format); + ok(hr == S_OK, "GetPixelFormat failed, hr %#lx\n", hr); + if (hr != S_OK) return; + hr = IWICBitmapFrameDecode_GetSize(frame, &frame_width, &frame_height); + ok(hr == S_OK, "GetSize failed, hr %#lx\n", hr); + if (hr != S_OK) return; + hr = IWICDdsFrameDecode_GetFormatInfo(dds_frame, &format_info); + ok(hr == S_OK, "GetFormatInfo failed, hr %#lx\n", hr); + if (hr != S_OK) return; + hr = IWICDdsFrameDecode_GetSizeInBlocks(dds_frame, &width_in_blocks, &height_in_blocks); + ok(hr == S_OK, "GetSizeInBlocks failed, hr %#lx\n", hr); + if (hr != S_OK) return; + stride = rect.Width * format_info.BytesPerBlock; + frame_stride = width_in_blocks * format_info.BytesPerBlock; + frame_size = frame_stride * height_in_blocks; + + /* CopyBlocks tests */ + + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, NULL, 0, 0, NULL); + ok(hr == E_INVALIDARG, "CopyBlocks got unexpected hr %#lx\n", hr); + + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, &rect_test_a, stride, sizeof(buffer), buffer); + ok(hr == E_INVALIDARG, "CopyBlocks got unexpected hr %#lx\n", hr); + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, &rect_test_b, stride, sizeof(buffer), buffer); + ok(hr == E_INVALIDARG, "CopyBlocks got unexpected hr %#lx\n", hr); + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, &rect_test_c, stride, sizeof(buffer), buffer); + ok(hr == E_INVALIDARG, "CopyBlocks got unexpected hr %#lx\n", hr); + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, &rect_test_d, stride, sizeof(buffer), buffer); + ok(hr == E_INVALIDARG, "CopyBlocks got unexpected hr %#lx\n", hr); + + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, NULL, frame_stride - 1, sizeof(buffer), buffer); + ok(hr == E_INVALIDARG, "CopyBlocks got unexpected hr %#lx\n", hr); + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, NULL, frame_stride * 2, sizeof(buffer), buffer); + ok(hr == S_OK, "CopyBlocks got unexpected hr %#lx\n", hr); + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, NULL, frame_stride, sizeof(buffer), buffer); + ok(hr == S_OK, "CopyBlocks got unexpected hr %#lx\n", hr); + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, NULL, frame_stride, frame_stride * height_in_blocks - 1, buffer); + ok(hr == E_INVALIDARG, "CopyBlocks got unexpected hr %#lx\n", hr); + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, NULL, frame_stride, frame_stride * height_in_blocks, buffer); + ok(hr == S_OK, "CopyBlocks got unexpected hr %#lx\n", hr); + + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, &rect, 0, sizeof(buffer), buffer); + ok(hr == E_INVALIDARG, "CopyBlocks got unexpected hr %#lx\n", hr); + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, &rect, stride - 1, sizeof(buffer), buffer); + ok(hr == E_INVALIDARG, "CopyBlocks got unexpected hr %#lx\n", hr); + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, &rect, stride * 2, sizeof(buffer), buffer); + ok(hr == S_OK, "CopyBlocks got unexpected hr %#lx\n", hr); + + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, &rect, stride, 0, buffer); + ok(hr == E_INVALIDARG, "CopyBlocks got unexpected hr %#lx\n", hr); + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, &rect, stride, 1, buffer); + ok(hr == E_INVALIDARG || (hr == S_OK && test->expected_bytes_per_block == 1), + "CopyBlocks got unexpected hr %#lx\n", hr); + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, &rect, stride, stride * rect.Height - 1, buffer); + ok(hr == E_INVALIDARG, "CopyBlocks got unexpected hr %#lx\n", hr); + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, &rect, stride, stride * rect.Height, buffer); + ok(hr == S_OK, "CopyBlocks got unexpected hr %#lx\n", hr); + + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, &rect, stride, sizeof(buffer), NULL); + ok(hr == E_INVALIDARG, "CopyBlocks got unexpected hr %#lx\n", hr); + + block_offset = 128; /* DDS magic and header */ + if (has_extended_header(test->data)) block_offset += 20; /* DDS extended header */ + width = params->Width; + height = params->Height; + depth = params->Depth; + slice_index = frame_index % (frame_count / params->ArraySize); + array_index = frame_index / (frame_count / params->ArraySize); + block_offset += (test->size - block_offset) / params->ArraySize * array_index; + while (slice_index >= 0) + { + width_in_blocks = (width + format_info.BlockWidth - 1) / format_info.BlockWidth; + height_in_blocks = (width + format_info.BlockWidth - 1) / format_info.BlockWidth; + block_offset += (slice_index >= depth) ? + (width_in_blocks * height_in_blocks * format_info.BytesPerBlock * depth) : + (width_in_blocks * height_in_blocks * format_info.BytesPerBlock * slice_index); + if (width > 1) width /= 2; + if (height > 1) height /= 2; + slice_index -= depth; + if (depth > 1) depth /= 2; + } + + memset(buffer, 0, sizeof(buffer)); + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, &rect, stride, sizeof(buffer), buffer); + ok(hr == S_OK, "CopyBlocks failed, hr %#lx\n", hr); + if (hr != S_OK) return; + ok(!memcmp(test->data + block_offset, buffer, format_info.BytesPerBlock), + "Block data mismatch\n"); + + memset(buffer, 0, sizeof(buffer)); + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, NULL, frame_stride, sizeof(buffer), buffer); + ok(hr == S_OK, "CopyBlocks failed, hr %#lx\n", hr); + if (hr != S_OK) return; + ok(!memcmp(test->data + block_offset, buffer, frame_size), + "Block data mismatch\n"); + + memset(buffer, 0, sizeof(buffer)); + memset(pixels, 0, sizeof(pixels)); + copy_pixels(test->data + block_offset, frame_stride, pixels, frame_stride * 2, frame_size); + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, NULL, frame_stride * 2, sizeof(buffer), buffer); + ok(hr == S_OK, "CopyBlocks failed, hr %#lx\n", hr); + if (hr != S_OK) return; + ok(!memcmp(pixels, buffer, frame_size), + "Block data mismatch\n"); + + /* CopyPixels tests */ + + bpp = test->pixel_format_bpp; + stride = rect.Width * bpp / 8; + frame_stride = frame_width * bpp / 8; + frame_size = frame_stride * frame_height; + + hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, 0, 0, NULL); + ok(hr == E_INVALIDARG, "CopyPixels got unexpected hr %#lx\n", hr); + + hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect_test_a, stride, sizeof(buffer), buffer); + ok(hr == E_INVALIDARG, "CopyPixels got unexpected hr %#lx\n", hr); + hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect_test_b, stride, sizeof(buffer), buffer); + ok(hr == E_INVALIDARG, "CopyPixels got unexpected hr %#lx\n", hr); + hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect_test_c, stride, sizeof(buffer), buffer); + ok(hr == E_INVALIDARG, "CopyPixels got unexpected hr %#lx\n", hr); + hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect_test_d, stride, sizeof(buffer), buffer); + ok(hr == E_INVALIDARG, "CopyPixels got unexpected hr %#lx\n", hr); + + hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, frame_stride - 1, sizeof(buffer), buffer); + ok(hr == E_INVALIDARG, "CopyPixels got unexpected hr %#lx\n", hr); + hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, frame_stride * 2, sizeof(buffer), buffer); + ok(hr == S_OK, "CopyPixels got unexpected hr %#lx\n", hr); + hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, frame_stride, sizeof(buffer), buffer); + ok(hr == S_OK, "CopyPixels got unexpected hr %#lx\n", hr); + hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, frame_stride, frame_stride * frame_height - 1, buffer); + ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "CopyPixels got unexpected hr %#lx\n", hr); + hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, frame_stride, frame_stride * frame_height, buffer); + ok(hr == S_OK, "CopyPixels got unexpected hr %#lx\n", hr); + + hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect, 0, sizeof(buffer), buffer); + ok(hr == E_INVALIDARG, "CopyPixels got unexpected hr %#lx\n", hr); + hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect, stride - 1, sizeof(buffer), buffer); + ok(hr == E_INVALIDARG, "CopyPixels got unexpected hr %#lx\n", hr); + hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect, stride * 2, sizeof(buffer), buffer); + ok(hr == S_OK, "CopyPixels got unexpected hr %#lx\n", hr); + + hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect, stride, 0, buffer); + ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "CopyPixels got unexpected hr %#lx\n", hr); + hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect, stride, 1, buffer); + ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER || (hr == S_OK && test->expected_bytes_per_block == 1), + "CopyPixels got unexpected hr %#lx\n", hr); + hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect, stride, stride * rect.Height - 1, buffer); + ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "CopyPixels got unexpected hr %#lx\n", hr); + hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect, stride, stride * rect.Height, buffer); + ok(hr == S_OK, "CopyPixels got unexpected hr %#lx\n", hr); + + hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect, stride, sizeof(buffer), NULL); + ok(hr == E_INVALIDARG, "CopyBlocks got unexpected hr %#lx\n", hr); + + memset(buffer, 0, sizeof(pixels)); + if (is_compressed(format_info.DxgiFormat)) { + decode_block(test->data + block_offset, width_in_blocks * height_in_blocks, + format_info.DxgiFormat, frame_width, frame_height, (DWORD *)pixels); + } else { + memcpy(pixels, test->data + block_offset, frame_size); + } + + memset(buffer, 0, sizeof(buffer)); + hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect, stride, sizeof(buffer), buffer); + ok(hr == S_OK, "CopyPixels failed, hr %#lx\n", hr); + if (hr == S_OK) { + if (is_compressed(format_info.DxgiFormat)) { + ok(color_buffer_match((DWORD *)pixels, (DWORD *)buffer, 1), "Pixels mismatch\n"); + } else { + ok(!memcmp(pixels, buffer, bpp / 8), "Pixels mismatch\n"); + } + } + + memset(buffer, 0, sizeof(buffer)); + hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, frame_stride, sizeof(buffer), buffer); + ok(hr == S_OK, "CopyPixels failed, hr %#lx\n", hr); + if (hr == S_OK) { + if (is_compressed(format_info.DxgiFormat)) { + ok(color_buffer_match((DWORD *)pixels, (DWORD *)buffer, frame_size / (bpp / 8)), "Pixels mismatch\n"); + } else { + ok(!memcmp(pixels, buffer, frame_size), "Pixels mismatch\n"); + }; + } +} + +static void test_dds_decoder_frame(IWICBitmapDecoder *decoder, struct test_data *test) +{ + HRESULT hr; + IWICDdsDecoder *dds_decoder = NULL; + UINT frame_count, j; + WICDdsParameters params; + + hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count); + ok(hr == S_OK, "GetFrameCount failed, hr %#lx\n", hr); + if (hr != S_OK) return; + hr = IWICBitmapDecoder_QueryInterface(decoder, &IID_IWICDdsDecoder, (void **)&dds_decoder); + ok(hr == S_OK, "QueryInterface failed, hr %#lx\n", hr); + if (hr != S_OK) goto end; + hr = IWICDdsDecoder_GetParameters(dds_decoder, ¶ms); + ok(hr == S_OK, "GetParameters failed, hr %#lx\n", hr); + if (hr != S_OK) goto end; + + if (test->expected_parameters.Dimension == WICDdsTextureCube) params.ArraySize *= 6; + + for (j = 0; j < frame_count; j++) + { + IWICBitmapFrameDecode *frame_decode = NULL; + IWICDdsFrameDecode *dds_frame = NULL; + + winetest_push_context("Frame %u", j); + + hr = IWICBitmapDecoder_GetFrame(decoder, j, &frame_decode); + ok(hr == S_OK, "GetFrame failed, hr %#lx\n", hr); + if (hr != S_OK) goto next; + hr = IWICBitmapFrameDecode_QueryInterface(frame_decode, &IID_IWICDdsFrameDecode, (void **)&dds_frame); + ok(hr == S_OK, "QueryInterface failed, hr %#lx\n", hr); + if (hr != S_OK) goto next; + + test_dds_decoder_frame_properties(frame_decode, dds_frame, frame_count, ¶ms, test, j); + test_dds_decoder_frame_data(frame_decode, dds_frame, frame_count, ¶ms, test, j); + + next: + if (frame_decode) IWICBitmapFrameDecode_Release(frame_decode); + if (dds_frame) IWICDdsFrameDecode_Release(dds_frame); + winetest_pop_context(); + } + +end: + if (dds_decoder) IWICDdsDecoder_Release(dds_decoder); +} + +static void test_dds_decoder(void) +{ + int i; + HRESULT hr; + + test_dds_decoder_initialize(); + test_dds_decoder_image_parameters(); + + for (i = 0; i < ARRAY_SIZE(test_data); i++) + { + IWICStream *stream = NULL; + IWICBitmapDecoder *decoder = NULL; + + if (test_data[i].init_hr != S_OK && !test_data[i].wine_init) continue; + + winetest_push_context("Test %u", i); + + stream = create_stream(test_data[i].data, test_data[i].size); + if (!stream) goto next; + decoder = create_decoder(); + if (!decoder) goto next; + hr = init_decoder(decoder, stream, test_data[i].init_hr, test_data[i].wine_init); + if (hr != S_OK) { + if (test_data[i].expected_parameters.Dimension == WICDdsTextureCube) { + win_skip("Cube map is not supported\n"); + } else { + win_skip("Uncompressed DDS image is not supported\n"); + } + goto next; + } + + test_dds_decoder_global_properties(decoder); + test_dds_decoder_frame(decoder, test_data + i); + + next: + if (decoder) IWICBitmapDecoder_Release(decoder); + if (stream) IWICStream_Release(stream); + winetest_pop_context(); + } +} + +static void test_dds_encoder_initialize(void) +{ + IWICBitmapEncoder *encoder = NULL; + IWICStream *stream = NULL; + BYTE buffer[1]; + HRESULT hr; + + encoder = create_encoder(); + if (!encoder) goto end; + + stream = create_stream(buffer, sizeof(buffer)); + if (!stream) goto end; + + /* initialize with invalid cache option */ + + hr = IWICBitmapEncoder_Initialize(encoder, (IStream *)stream, 0xdeadbeef); + todo_wine + ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "Initialize got unexpected hr %#lx\n", hr); + + hr = IWICBitmapEncoder_Initialize(encoder, (IStream *)stream, WICBitmapEncoderNoCache); + todo_wine + ok(hr == E_INVALIDARG, "Initialize got unexpected hr %#lx\n", hr); + + IWICBitmapEncoder_Release(encoder); + + /* initialize with null stream */ + + encoder = create_encoder(); + if (!encoder) goto end; + + hr = IWICBitmapEncoder_Initialize(encoder, NULL, WICBitmapEncoderNoCache); + ok(hr == E_INVALIDARG, "Initialize got unexpected hr %#lx\n", hr); + + hr = IWICBitmapEncoder_Initialize(encoder, (IStream *)stream, WICBitmapEncoderNoCache); + ok(hr == S_OK, "Initialize failed, hr %#lx\n", hr); + + IWICBitmapEncoder_Release(encoder); + + /* regularly initialize */ + + encoder = create_encoder(); + if (!encoder) goto end; + + hr = IWICBitmapEncoder_Initialize(encoder, (IStream *)stream, WICBitmapEncoderNoCache); + ok(hr == S_OK, "Initialize failed, hr %#lx\n", hr); + + hr = IWICBitmapEncoder_Initialize(encoder, (IStream *)stream, WICBitmapEncoderNoCache); + ok(hr == WINCODEC_ERR_WRONGSTATE, "Initialize got unexpected hr %#lx\n", hr); + +end: + if (stream) IWICStream_Release(stream); + if (encoder) IWICBitmapEncoder_Release(encoder); +} + +static void test_dds_encoder_params(void) +{ + WICDdsParameters params, params_set = { 4, 4, 4, 3, 1, DXGI_FORMAT_BC1_UNORM, + WICDdsTexture3D, WICDdsAlphaModePremultiplied }; + IWICDdsEncoder *dds_encoder = NULL; + IWICBitmapEncoder *encoder = NULL; + IWICStream *stream = NULL; + BYTE buffer[1024]; + HRESULT hr; + UINT i; + + hr = create_and_init_encoder(buffer, sizeof(buffer), NULL, &encoder, &dds_encoder, &stream); + if (hr != S_OK) goto end; + + hr = IWICDdsEncoder_GetParameters(dds_encoder, NULL); + ok(hr == E_INVALIDARG, "GetParameters got unexpected hr %#lx\n", hr); + + hr = IWICDdsEncoder_GetParameters(dds_encoder, ¶ms); + ok(hr == S_OK, "GetParameters failed, hr %#lx\n", hr); + if (hr != S_OK) goto end; + + /* default DDS parameters for encoder */ + ok(params.Width == 1, "Got unexpected Width %u\n", params.Width); + ok(params.Height == 1, "Got unexpected Height %u\n", params.Height); + ok(params.Depth == 1, "Got unexpected Depth %u\n", params.Depth); + ok(params.MipLevels == 1, "Got unexpected MipLevels %u\n", params.MipLevels); + ok(params.ArraySize == 1, "Got unexpected ArraySize %u\n", params.ArraySize); + ok(params.DxgiFormat == DXGI_FORMAT_BC3_UNORM, "Got unexpected DxgiFormat %#x\n", params.DxgiFormat); + ok(params.Dimension == WICDdsTexture2D, "Got unexpected Dimension %#x\n", params.Dimension); + ok(params.AlphaMode == WICDdsAlphaModeUnknown, "Got unexpected AlphaMode %#x\n", params.AlphaMode); + + hr = IWICDdsEncoder_SetParameters(dds_encoder, NULL); + ok(hr == E_INVALIDARG, "SetParameters got unexpected hr %#lx\n", hr); + + hr = IWICDdsEncoder_SetParameters(dds_encoder, ¶ms_set); + ok(hr == S_OK, "SetParameters failed, hr %#lx\n", hr); + if (hr != S_OK) goto end; + + IWICDdsEncoder_GetParameters(dds_encoder, ¶ms); + + ok(params.Width == params_set.Width, + "Expected Width %u, got %u\n", params_set.Width, params.Width); + ok(params.Height == params_set.Height, + "Expected Height %u, got %u\n", params_set.Height, params.Height); + ok(params.Depth == params_set.Depth, + "Expected Depth %u, got %u\n", params_set.Depth, params.Depth); + ok(params.MipLevels == params_set.MipLevels, + "Expected MipLevels %u, got %u\n", params_set.MipLevels, params.MipLevels); + ok(params.ArraySize == params_set.ArraySize, + "Expected ArraySize %u, got %u\n", params_set.ArraySize, params.ArraySize); + ok(params.DxgiFormat == params_set.DxgiFormat, + "Expected DxgiFormat %u, got %#x\n", params_set.DxgiFormat, params.DxgiFormat); + ok(params.Dimension == params_set.Dimension, + "Expected Dimension %u, got %#x\n", params_set.Dimension, params.Dimension); + ok(params.AlphaMode == params_set.AlphaMode, + "Expected AlphaMode %u, got %#x\n", params_set.AlphaMode, params.AlphaMode); + + for (i = 0; i < ARRAY_SIZE(test_data); ++i) + { + hr = IWICDdsEncoder_SetParameters(dds_encoder, &test_data[i].expected_parameters); + todo_wine_if(test_data[i].init_hr != S_OK) + ok((hr == S_OK && test_data[i].init_hr == S_OK) || hr == WINCODEC_ERR_BADHEADER, + "Test %u: SetParameters got unexpected hr %#lx\n", i, hr); + } + +end: + release_encoder(encoder, dds_encoder, stream); +} + +static void test_dds_encoder_create_frame(void) +{ + WICDdsParameters params = { 4, 4, 1, 3, 1, DXGI_FORMAT_BC1_UNORM, + WICDdsTexture2D, WICDdsAlphaModePremultiplied }; + IWICBitmapFrameEncode *frame0 = NULL, *frame1 = NULL; + UINT array_index, mip_level, slice_index; + IWICDdsEncoder *dds_encoder = NULL; + IWICBitmapEncoder *encoder = NULL; + IWICStream *stream = NULL; + BYTE buffer[1024]; + HRESULT hr; + + hr = create_and_init_encoder(buffer, sizeof(buffer), ¶ms, &encoder, &dds_encoder, &stream); + if (hr != S_OK) goto end; + + hr = IWICBitmapEncoder_CreateNewFrame(encoder, &frame0, NULL); + ok(hr == S_OK, "CreateNewFrame failed, hr %#lx\n", hr); + hr = IWICBitmapEncoder_CreateNewFrame(encoder, &frame1, NULL); + ok(hr == WINCODEC_ERR_WRONGSTATE, "CreateNewFrame got unexpected hr %#lx\n", hr); + + IWICBitmapFrameEncode_Release(frame0); + hr = IWICBitmapEncoder_CreateNewFrame(encoder, &frame1, NULL); + ok(hr == WINCODEC_ERR_WRONGSTATE, "CreateNewFrame got unexpected hr %#lx\n", hr); + + release_encoder(encoder, dds_encoder, stream); + + create_and_init_encoder(buffer, sizeof(buffer), ¶ms, &encoder, &dds_encoder, &stream); + hr = IWICDdsEncoder_CreateNewFrame(dds_encoder, &frame0, &array_index, &mip_level, &slice_index); + ok(hr == S_OK, "CreateNewFrame failed, hr %#lx\n", hr); + IWICBitmapFrameEncode_Release(frame0); + release_encoder(encoder, dds_encoder, stream); + + create_and_init_encoder(buffer, sizeof(buffer), ¶ms, &encoder, &dds_encoder, &stream); + hr = IWICDdsEncoder_CreateNewFrame(dds_encoder, &frame0, NULL, NULL, NULL); + ok(hr == S_OK, "CreateNewFrame failed, hr %#lx\n", hr); + IWICBitmapFrameEncode_Release(frame0); + +end: + release_encoder(encoder, dds_encoder, stream); +} + +static void test_dds_encoder_pixel_format(void) +{ + DXGI_FORMAT image_formats[] = { DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC3_UNORM }; + const WICPixelFormatGUID *test_formats[] = + { + &GUID_WICPixelFormat8bppIndexed, + &GUID_WICPixelFormatBlackWhite, + &GUID_WICPixelFormat16bppGray, + &GUID_WICPixelFormat8bppAlpha, + &GUID_WICPixelFormat16bppBGR555, + &GUID_WICPixelFormat16bppBGR565, + &GUID_WICPixelFormat24bppBGR, + &GUID_WICPixelFormat32bppBGR, + &GUID_WICPixelFormat32bppBGRA, + &GUID_WICPixelFormat32bppPBGRA, + &GUID_WICPixelFormat32bppRGB, + &GUID_WICPixelFormat32bppRGBA, + &GUID_WICPixelFormat32bppPRGBA, + &GUID_WICPixelFormat48bppRGB, + &GUID_WICPixelFormat64bppRGB, + &GUID_WICPixelFormat64bppRGBA + }; + IWICBitmapFrameEncode *frame = NULL; + IWICDdsEncoder *dds_encoder = NULL; + IWICBitmapEncoder *encoder = NULL; + IWICStream *stream = NULL; + WICPixelFormatGUID format; + WICDdsParameters params; + BYTE buffer[1]; + HRESULT hr; + UINT i, j; + + for (i = 0; i < ARRAY_SIZE(image_formats); ++i) + { + hr = create_and_init_encoder(buffer, sizeof(buffer), NULL, &encoder, &dds_encoder, &stream); + if (hr != S_OK) + { + release_encoder(encoder, dds_encoder, stream); + return; + } + + IWICDdsEncoder_GetParameters(dds_encoder, ¶ms); + params.DxgiFormat = image_formats[i]; + IWICDdsEncoder_SetParameters(dds_encoder, ¶ms); + + IWICBitmapEncoder_CreateNewFrame(encoder, &frame, NULL); + + hr = IWICBitmapFrameEncode_SetPixelFormat(frame, &format); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "SetPixelFormat got unexpected hr %#lx\n", hr); + + IWICBitmapFrameEncode_Initialize(frame, NULL); + + for (j = 0; j < ARRAY_SIZE(test_formats); ++j) + { + winetest_push_context("Test %u", j); + + format = *(test_formats[j]); + hr = IWICBitmapFrameEncode_SetPixelFormat(frame, &format); + ok(hr == S_OK, "SetPixelFormat failed, hr %#lx\n", hr); + ok(IsEqualGUID(&format, &GUID_WICPixelFormat32bppBGRA), + "Got unexpected GUID %s\n", debugstr_guid(&format)); + + winetest_pop_context(); + } + + IWICBitmapFrameEncode_Release(frame); + release_encoder(encoder, dds_encoder, stream); + } +} + +static void test_dds_encoder(void) +{ + test_dds_encoder_initialize(); + test_dds_encoder_params(); + test_dds_encoder_create_frame(); + test_dds_encoder_pixel_format(); +} + +START_TEST(ddsformat) +{ + HRESULT hr; + CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + + hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICImagingFactory, (void **)&factory); + ok(hr == S_OK, "CoCreateInstance failed, hr %#lx\n", hr); + if (hr != S_OK) goto end; + + test_dds_decoder(); + test_dds_encoder(); + +end: + if (factory) IWICImagingFactory_Release(factory); + CoUninitialize(); +} diff --git a/modules/rostests/winetests/windowscodecs/gifformat.c b/modules/rostests/winetests/windowscodecs/gifformat.c index 05affadca4dd7..08f8ba1c12bcd 100644 --- a/modules/rostests/winetests/windowscodecs/gifformat.c +++ b/modules/rostests/winetests/windowscodecs/gifformat.c @@ -57,6 +57,13 @@ static const char gif_local_palette[] = { 0x02,0x02,0x44,0x01,0x00,0x3b }; +static const char gif_no_palette[] = { +/* LSD */'G','I','F','8','7','a',0x01,0x00,0x01,0x00,0x21,0x02,0x00, +/* GCE */0x21,0xf9,0x04,0x01,0x05,0x00,0x01,0x00, /* index 1 */ +/* IMD */0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00, +0x02,0x02,0x44,0x01,0x00,0x3b +}; + /* Generated with ImageMagick: * convert -delay 100 -size 2x2 xc:red \ * -dispose none -page +0+0 -size 2x1 xc:white \ @@ -93,7 +100,7 @@ static IStream *create_stream(const void *image_data, UINT image_size) GlobalUnlock(hmem); hr = CreateStreamOnHGlobal(hmem, TRUE, &stream); - ok(hr == S_OK, "CreateStreamOnHGlobal error %#x\n", hr); + ok(hr == S_OK, "CreateStreamOnHGlobal error %#lx\n", hr); return stream; } @@ -110,10 +117,10 @@ static IWICBitmapDecoder *create_decoder(const void *image_data, UINT image_size if (!stream) return NULL; hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder); - ok(hr == S_OK, "CreateDecoderFromStream error %#x\n", hr); + ok(hr == S_OK, "CreateDecoderFromStream error %#lx\n", hr); hr = IWICBitmapDecoder_GetContainerFormat(decoder, &format); - ok(hr == S_OK, "GetContainerFormat error %#x\n", hr); + ok(hr == S_OK, "GetContainerFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_ContainerFormatGif), "wrong container format %s\n", wine_dbgstr_guid(&format)); @@ -137,18 +144,18 @@ static void test_global_gif_palette(void) ok(decoder != 0, "Failed to load GIF image data\n"); hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "CreatePalette error %#x\n", hr); + ok(hr == S_OK, "CreatePalette error %#lx\n", hr); /* global palette */ hr = IWICBitmapDecoder_CopyPalette(decoder, palette); - ok(hr == S_OK, "CopyPalette error %#x\n", hr); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 4, "expected 4, got %u\n", count); hr = IWICPalette_GetColors(palette, count, color, &ret); - ok(hr == S_OK, "GetColors error %#x\n", hr); + ok(hr == S_OK, "GetColors error %#lx\n", hr); ok(ret == count, "expected %u, got %u\n", count, ret); ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]); ok(color[1] == 0x00040506, "expected 0x00040506, got %#x\n", color[1]); @@ -157,22 +164,22 @@ static void test_global_gif_palette(void) /* frame palette */ hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed), "wrong pixel format %s\n", wine_dbgstr_guid(&format)); hr = IWICBitmapFrameDecode_CopyPalette(frame, palette); - ok(hr == S_OK, "CopyPalette error %#x\n", hr); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 4, "expected 4, got %u\n", count); hr = IWICPalette_GetColors(palette, count, color, &ret); - ok(hr == S_OK, "GetColors error %#x\n", hr); + ok(hr == S_OK, "GetColors error %#lx\n", hr); ok(ret == count, "expected %u, got %u\n", count, ret); ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]); ok(color[1] == 0x00040506, "expected 0x00040506, got %#x\n", color[1]); @@ -199,21 +206,21 @@ static void test_global_gif_palette_2frames(void) /* active frame 0, GCE transparent index 1 */ hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "CreatePalette error %#x\n", hr); + ok(hr == S_OK, "CreatePalette error %#lx\n", hr); /* global palette */ hr = IWICBitmapDecoder_CopyPalette(decoder, palette); - ok(hr == S_OK, "CopyPalette error %#x\n", hr); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 4, "expected 4, got %u\n", count); hr = IWICPalette_GetColors(palette, count, color, &ret); - ok(hr == S_OK, "GetColors error %#x\n", hr); + ok(hr == S_OK, "GetColors error %#lx\n", hr); ok(ret == count, "expected %u, got %u\n", count, ret); ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]); ok(color[1] == 0x00040506, "expected 0x00040506, got %#x\n", color[1]); @@ -222,19 +229,19 @@ static void test_global_gif_palette_2frames(void) /* frame 0 palette */ hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed), "wrong pixel format %s\n", wine_dbgstr_guid(&format)); hr = IWICBitmapFrameDecode_CopyPalette(frame, palette); - ok(hr == S_OK, "CopyPalette error %#x\n", hr); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 4, "expected 4, got %u\n", count); hr = IWICPalette_GetColors(palette, count, color, &ret); - ok(hr == S_OK, "GetColors error %#x\n", hr); + ok(hr == S_OK, "GetColors error %#lx\n", hr); ok(ret == count, "expected %u, got %u\n", count, ret); ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]); ok(color[1] == 0x00040506, "expected 0x00040506, got %#x\n", color[1]); @@ -245,18 +252,18 @@ static void test_global_gif_palette_2frames(void) /* active frame 1, GCE transparent index 2 */ hr = IWICBitmapDecoder_GetFrame(decoder, 1, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); /* global palette */ hr = IWICBitmapDecoder_CopyPalette(decoder, palette); - ok(hr == S_OK, "CopyPalette error %#x\n", hr); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 4, "expected 4, got %u\n", count); hr = IWICPalette_GetColors(palette, count, color, &ret); - ok(hr == S_OK, "GetColors error %#x\n", hr); + ok(hr == S_OK, "GetColors error %#lx\n", hr); ok(ret == count, "expected %u, got %u\n", count, ret); ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]); ok(color[1] == 0xff040506 || broken(color[1] == 0x00040506) /* XP */, "expected 0xff040506, got %#x\n", color[1]); @@ -265,19 +272,19 @@ static void test_global_gif_palette_2frames(void) /* frame 1 palette */ hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed), "wrong pixel format %s\n", wine_dbgstr_guid(&format)); hr = IWICBitmapFrameDecode_CopyPalette(frame, palette); - ok(hr == S_OK, "CopyPalette error %#x\n", hr); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 4, "expected 4, got %u\n", count); hr = IWICPalette_GetColors(palette, count, color, &ret); - ok(hr == S_OK, "GetColors error %#x\n", hr); + ok(hr == S_OK, "GetColors error %#lx\n", hr); ok(ret == count, "expected %u, got %u\n", count, ret); ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]); ok(color[1] == 0xff040506, "expected 0xff040506, got %#x\n", color[1]); @@ -304,24 +311,24 @@ static void test_local_gif_palette(void) ok(decoder != 0, "Failed to load GIF image data\n"); hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "CreatePalette error %#x\n", hr); + ok(hr == S_OK, "CreatePalette error %#lx\n", hr); /* global palette */ hr = IWICBitmapDecoder_CopyPalette(decoder, palette); - ok(hr == S_OK || broken(hr == WINCODEC_ERR_FRAMEMISSING), "CopyPalette %#x\n", hr); + ok(hr == S_OK || broken(hr == WINCODEC_ERR_FRAMEMISSING), "CopyPalette %#lx\n", hr); if (hr == S_OK) { type = -1; hr = IWICPalette_GetType(palette, &type); - ok(hr == S_OK, "GetType error %#x\n", hr); + ok(hr == S_OK, "GetType error %#lx\n", hr); ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %#x\n", type); hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 256, "expected 256, got %u\n", count); hr = IWICPalette_GetColors(palette, count, color, &ret); - ok(hr == S_OK, "GetColors error %#x\n", hr); + ok(hr == S_OK, "GetColors error %#lx\n", hr); ok(ret == count, "expected %u, got %u\n", count, ret); ok(color[0] == 0xff000000, "expected 0xff000000, got %#x\n", color[0]); ok(color[1] == 0x00ffffff, "expected 0x00ffffff, got %#x\n", color[1]); @@ -332,27 +339,27 @@ static void test_local_gif_palette(void) /* frame palette */ hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed), "wrong pixel format %s\n", wine_dbgstr_guid(&format)); hr = IWICBitmapFrameDecode_CopyPalette(frame, palette); - ok(hr == S_OK, "CopyPalette error %#x\n", hr); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 4, "expected 4, got %u\n", count); type = -1; hr = IWICPalette_GetType(palette, &type); - ok(hr == S_OK, "GetType error %#x\n", hr); + ok(hr == S_OK, "GetType error %#lx\n", hr); ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %#x\n", type); hr = IWICPalette_GetColors(palette, count, color, &ret); - ok(hr == S_OK, "GetColors error %#x\n", hr); + ok(hr == S_OK, "GetColors error %#lx\n", hr); ok(ret == count, "expected %u, got %u\n", count, ret); ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]); ok(color[1] == 0x00040506, "expected 0x00040506, got %#x\n", color[1]); @@ -364,6 +371,67 @@ static void test_local_gif_palette(void) IWICBitmapDecoder_Release(decoder); } +static void test_no_gif_palette(void) +{ + HRESULT hr; + IWICBitmapDecoder *decoder; + IWICBitmapFrameDecode *frame; + IWICPalette *palette; + GUID format; + UINT count, ret; + WICColor color[256]; + + decoder = create_decoder(gif_no_palette, sizeof(gif_no_palette)); + ok(decoder != 0, "Failed to load GIF image data\n"); + + hr = IWICImagingFactory_CreatePalette(factory, &palette); + ok(hr == S_OK, "CreatePalette error %#lx\n", hr); + + /* global palette */ + hr = IWICBitmapDecoder_CopyPalette(decoder, palette); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); + + hr = IWICPalette_GetColorCount(palette, &count); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); + ok(count == 4, "expected 4, got %u\n", count); + + hr = IWICPalette_GetColors(palette, count, color, &ret); + ok(hr == S_OK, "GetColors error %#lx\n", hr); + ok(ret == count, "expected %u, got %u\n", count, ret); + ok(color[0] == 0xff000000, "expected 0xff000000, got %#x\n", color[0]); + ok(color[1] == 0x00ffffff, "expected 0x00ffffff, got %#x\n", color[1]); + ok(color[2] == 0xff000000, "expected 0xff000000, got %#x\n", color[2]); + ok(color[3] == 0xff000000, "expected 0xff000000, got %#x\n", color[3]); + + /* frame palette */ + hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); + + hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); + ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed), + "wrong pixel format %s\n", wine_dbgstr_guid(&format)); + + hr = IWICBitmapFrameDecode_CopyPalette(frame, palette); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); + + hr = IWICPalette_GetColorCount(palette, &count); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); + ok(count == 4, "expected 4, got %u\n", count); + + hr = IWICPalette_GetColors(palette, count, color, &ret); + ok(hr == S_OK, "GetColors error %#lx\n", hr); + ok(ret == count, "expected %u, got %u\n", count, ret); + ok(color[0] == 0xff000000, "expected 0xff000000, got %#x\n", color[0]); + ok(color[1] == 0x00ffffff, "expected 0x00ffffff, got %#x\n", color[1]); + ok(color[2] == 0xff000000, "expected 0xff000000, got %#x\n", color[2]); + ok(color[3] == 0xff000000, "expected 0xff000000, got %#x\n", color[3]); + + IWICPalette_Release(palette); + IWICBitmapFrameDecode_Release(frame); + IWICBitmapDecoder_Release(decoder); +} + static void test_gif_frame_sizes(void) { static const BYTE frame0[] = {0, 1, 0xfe, 0xfe, 2, 3, 0xfe, 0xfe}; @@ -379,32 +447,32 @@ static void test_gif_frame_sizes(void) ok(decoder != 0, "Failed to load GIF image data\n"); hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICBitmapFrameDecode_GetSize(frame, &width, &height); - ok(hr == S_OK, "GetSize error %x\n", hr); + ok(hr == S_OK, "GetSize error %lx\n", hr); ok(width == 2, "width = %d\n", width); ok(height == 2, "height = %d\n", height); memset(buf, 0xfe, sizeof(buf)); hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, 4, sizeof(buf), buf); - ok(hr == S_OK, "CopyPixels error %x\n", hr); + ok(hr == S_OK, "CopyPixels error %lx\n", hr); ok(!memcmp(buf, frame0, sizeof(buf)), "buf = %x %x %x %x %x %x %x %x\n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); IWICBitmapFrameDecode_Release(frame); hr = IWICBitmapDecoder_GetFrame(decoder, 1, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICBitmapFrameDecode_GetSize(frame, &width, &height); - ok(hr == S_OK, "GetSize error %x\n", hr); + ok(hr == S_OK, "GetSize error %lx\n", hr); ok(width == 2, "width = %d\n", width); ok(height == 1, "height = %d\n", height); memset(buf, 0xfe, sizeof(buf)); hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, 4, sizeof(buf), buf); - ok(hr == S_OK, "CopyPixels error %x\n", hr); + ok(hr == S_OK, "CopyPixels error %lx\n", hr); ok(!memcmp(buf, frame1, sizeof(buf)), "buf = %x %x %x %x %x %x %x %x\n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); @@ -448,9 +516,9 @@ static void test_truncated_gif(void) if (!stream) return; hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder); - ok(hr == S_OK, "CreateDecoderFromStream error %#x\n", hr); + ok(hr == S_OK, "CreateDecoderFromStream error %#lx\n", hr); hr = IWICBitmapDecoder_GetContainerFormat(decoder, &format); - ok(hr == S_OK, "GetContainerFormat error %#x\n", hr); + ok(hr == S_OK, "GetContainerFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_ContainerFormatGif), "wrong container format %s\n", wine_dbgstr_guid(&format)); IWICBitmapDecoder_Release(decoder); @@ -459,9 +527,9 @@ static void test_truncated_gif(void) stream = create_stream(gif_with_trailer_2, sizeof(gif_with_trailer_2)); if (!stream) return; hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder); - ok(hr == S_OK, "CreateDecoderFromStream error %#x\n", hr); + ok(hr == S_OK, "CreateDecoderFromStream error %#lx\n", hr); hr = IWICBitmapDecoder_GetContainerFormat(decoder, &format); - ok(hr == S_OK, "GetContainerFormat error %#x\n", hr); + ok(hr == S_OK, "GetContainerFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_ContainerFormatGif), "wrong container format %s\n", wine_dbgstr_guid(&format)); IWICBitmapDecoder_Release(decoder); @@ -470,9 +538,9 @@ static void test_truncated_gif(void) stream = create_stream(gif_without_trailer_1, sizeof(gif_without_trailer_1)); if (!stream) return; hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder); - ok(hr == S_OK, "CreateDecoderFromStream error %#x\n", hr); + ok(hr == S_OK, "CreateDecoderFromStream error %#lx\n", hr); hr = IWICBitmapDecoder_GetContainerFormat(decoder, &format); - ok(hr == S_OK, "GetContainerFormat error %#x\n", hr); + ok(hr == S_OK, "GetContainerFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_ContainerFormatGif), "wrong container format %s\n", wine_dbgstr_guid(&format)); IWICBitmapDecoder_Release(decoder); @@ -481,9 +549,9 @@ static void test_truncated_gif(void) stream = create_stream(gif_without_trailer_2, sizeof(gif_without_trailer_2)); if (!stream) return; hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder); - ok(hr == S_OK, "CreateDecoderFromStream error %#x\n", hr); + ok(hr == S_OK, "CreateDecoderFromStream error %#lx\n", hr); hr = IWICBitmapDecoder_GetContainerFormat(decoder, &format); - ok(hr == S_OK, "GetContainerFormat error %#x\n", hr); + ok(hr == S_OK, "GetContainerFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_ContainerFormatGif), "wrong container format %s\n", wine_dbgstr_guid(&format)); IWICBitmapDecoder_Release(decoder); @@ -509,38 +577,38 @@ static void test_gif_notrailer(void) hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&factory); - ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); + ok(hr == S_OK, "CoCreateInstance failed, hr=%lx\n", hr); if (FAILED(hr)) return; hr = IWICImagingFactory_CreateStream(factory, &gifstream); - ok(hr == S_OK, "CreateStream failed, hr=%x\n", hr); + ok(hr == S_OK, "CreateStream failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICStream_InitializeFromMemory(gifstream, gifimage_notrailer, sizeof(gifimage_notrailer)); - ok(hr == S_OK, "InitializeFromMemory failed, hr=%x\n", hr); + ok(hr == S_OK, "InitializeFromMemory failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = CoCreateInstance(&CLSID_WICGifDecoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void**)&decoder); - ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); + ok(hr == S_OK, "CoCreateInstance failed, hr=%lx\n", hr); } if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_Initialize(decoder, (IStream*)gifstream, WICDecodeMetadataCacheOnDemand); - ok(hr == S_OK, "Initialize failed, hr=%x\n", hr); + ok(hr == S_OK, "Initialize failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_GetFrame(decoder, 0, &framedecode); - ok(hr == S_OK, "GetFrame failed, hr=%x\n", hr); + ok(hr == S_OK, "GetFrame failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapFrameDecode_GetResolution(framedecode, &dpiX, &dpiY); - ok(SUCCEEDED(hr), "GetResolution failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetResolution failed, hr=%lx\n", hr); ok(dpiX == 48.0, "expected dpiX=48.0, got %f\n", dpiX); ok(dpiY == 96.0, "expected dpiY=96.0, got %f\n", dpiY); @@ -551,7 +619,7 @@ static void test_gif_notrailer(void) if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_GetFrameCount(decoder, &framecount); - ok(hr == S_OK, "GetFrameCount failed, hr=%x\n", hr); + ok(hr == S_OK, "GetFrameCount failed, hr=%lx\n", hr); ok(framecount == 1, "framecount=%u\n", framecount); } @@ -571,12 +639,13 @@ START_TEST(gifformat) CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void **)&factory); - ok(hr == S_OK, "CoCreateInstance error %#x\n", hr); + ok(hr == S_OK, "CoCreateInstance error %#lx\n", hr); if (FAILED(hr)) return; test_global_gif_palette(); test_global_gif_palette_2frames(); test_local_gif_palette(); + test_no_gif_palette(); test_gif_frame_sizes(); test_gif_notrailer(); @@ -585,11 +654,12 @@ START_TEST(gifformat) /* run the same tests with no COM initialization */ hr = WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION, &factory); - ok(hr == S_OK, "WICCreateImagingFactory_Proxy error %#x\n", hr); + ok(hr == S_OK, "WICCreateImagingFactory_Proxy error %#lx\n", hr); test_global_gif_palette(); test_global_gif_palette_2frames(); test_local_gif_palette(); + test_no_gif_palette(); test_gif_frame_sizes(); test_truncated_gif(); diff --git a/modules/rostests/winetests/windowscodecs/icoformat.c b/modules/rostests/winetests/windowscodecs/icoformat.c index 38db51c376431..71a9dd88f046e 100644 --- a/modules/rostests/winetests/windowscodecs/icoformat.c +++ b/modules/rostests/winetests/windowscodecs/icoformat.c @@ -143,34 +143,34 @@ static void test_ico_data_(void *data, DWORD data_size, HRESULT init_hr, int tod hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&factory); - ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); + ok(hr == S_OK, "CoCreateInstance failed, hr=%lx\n", hr); if (FAILED(hr)) return; hr = IWICImagingFactory_CreateStream(factory, &icostream); - ok(hr == S_OK, "CreateStream failed, hr=%x\n", hr); + ok(hr == S_OK, "CreateStream failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICStream_InitializeFromMemory(icostream, data, data_size); - ok(hr == S_OK, "InitializeFromMemory failed, hr=%x\n", hr); + ok(hr == S_OK, "InitializeFromMemory failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = CoCreateInstance(&CLSID_WICIcoDecoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void**)&decoder); - ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); + ok(hr == S_OK, "CoCreateInstance failed, hr=%lx\n", hr); } if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_Initialize(decoder, (IStream*)icostream, WICDecodeMetadataCacheOnDemand); - todo_wine_if(todo) - ok_(__FILE__, line)(hr == init_hr, "Initialize failed, hr=%x\n", hr); + todo_wine_if(todo) + ok_(__FILE__, line)(hr == init_hr, "Initialize failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_GetFrame(decoder, 0, &framedecode); - ok(hr == S_OK, "GetFrame failed, hr=%x\n", hr); + ok(hr == S_OK, "GetFrame failed, hr=%lx\n", hr); } if (SUCCEEDED(hr)) @@ -180,16 +180,16 @@ static void test_ico_data_(void *data, DWORD data_size, HRESULT init_hr, int tod width = height = 0; hr = IWICBitmapFrameDecode_GetSize(framedecode, &width, &height); - ok(hr == S_OK, "GetFrameSize failed, hr=%x\n", hr); + ok(hr == S_OK, "GetFrameSize failed, hr=%lx\n", hr); ok(width == 16 && height == 16, "framesize=%ux%u\n", width, height); hr = IWICBitmapFrameDecode_GetThumbnail(framedecode, &thumbnail); - ok(hr == S_OK, "GetThumbnail failed, hr=%x\n", hr); + ok(hr == S_OK, "GetThumbnail failed, hr=%lx\n", hr); if (hr == S_OK) { width = height = 0; hr = IWICBitmapSource_GetSize(thumbnail, &width, &height); - ok(hr == S_OK, "GetFrameSize failed, hr=%x\n", hr); + ok(hr == S_OK, "GetFrameSize failed, hr=%lx\n", hr); ok(width == 16 && height == 16, "framesize=%ux%u\n", width, height); IWICBitmapSource_Release(thumbnail); } diff --git a/modules/rostests/winetests/windowscodecs/info.c b/modules/rostests/winetests/windowscodecs/info.c index ee957841667f4..9f184a8953ba8 100644 --- a/modules/rostests/winetests/windowscodecs/info.c +++ b/modules/rostests/winetests/windowscodecs/info.c @@ -28,9 +28,6 @@ #include "wincodecsdk.h" #include "wine/test.h" -#include "initguid.h" -DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); - static HRESULT get_component_info(const GUID *clsid, IWICComponentInfo **result) { IWICImagingFactory *factory; @@ -38,7 +35,7 @@ static HRESULT get_component_info(const GUID *clsid, IWICComponentInfo **result) hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&factory); - ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); + ok(hr == S_OK, "CoCreateInstance failed, hr=%lx\n", hr); if (FAILED(hr)) return hr; hr = IWICImagingFactory_CreateComponentInfo(factory, clsid, result); @@ -108,11 +105,16 @@ static void test_decoder_info(void) ".tiff,.tif", 1 }, + { + &CLSID_WICDdsDecoder, + "image/vnd.ms-dds", + ".dds", + } }; IWICBitmapDecoderInfo *decoder_info, *decoder_info2; IWICComponentInfo *info; HRESULT hr; - ULONG len; + UINT len; WCHAR value[256]; CLSID clsid; GUID pixelformats[32]; @@ -127,22 +129,26 @@ static void test_decoder_info(void) WCHAR mimetypeW[64]; hr = CoCreateInstance(test->clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void **)&decoder); - ok(SUCCEEDED(hr), "Failed to create decoder, hr %#x.\n", hr); + if (test->clsid == &CLSID_WICDdsDecoder && hr != S_OK) { + win_skip("DDS decoder is not supported\n"); + continue; + } + ok(SUCCEEDED(hr), "Failed to create decoder, hr %#lx.\n", hr); decoder_info = NULL; hr = IWICBitmapDecoder_GetDecoderInfo(decoder, &decoder_info); ok(hr == S_OK || broken(IsEqualCLSID(&CLSID_WICBmpDecoder, test->clsid) && FAILED(hr)) /* Fails on Windows */, - "%u: failed to get decoder info, hr %#x.\n", i, hr); + "%u: failed to get decoder info, hr %#lx.\n", i, hr); if (hr == S_OK) { decoder_info2 = NULL; hr = IWICBitmapDecoder_GetDecoderInfo(decoder, &decoder_info2); - ok(hr == S_OK, "Failed to get decoder info, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to get decoder info, hr %#lx.\n", hr); ok(decoder_info == decoder_info2, "Unexpected decoder info instance.\n"); hr = IWICBitmapDecoderInfo_QueryInterface(decoder_info, &IID_IWICBitmapDecoder, (void **)&decoder2); - ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr); + ok(hr == E_NOINTERFACE, "Unexpected hr %#lx.\n", hr); IWICBitmapDecoderInfo_Release(decoder_info); IWICBitmapDecoderInfo_Release(decoder_info2); @@ -153,126 +159,126 @@ static void test_decoder_info(void) MultiByteToWideChar(CP_ACP, 0, test->extensions, -1, extensionsW, ARRAY_SIZE(extensionsW)); hr = get_component_info(test->clsid, &info); - ok(hr == S_OK, "CreateComponentInfo failed, hr=%x\n", hr); + ok(hr == S_OK, "CreateComponentInfo failed, hr=%lx\n", hr); hr = IWICComponentInfo_QueryInterface(info, &IID_IWICBitmapDecoderInfo, (void **)&decoder_info); - ok(hr == S_OK, "QueryInterface failed, hr=%x\n", hr); + ok(hr == S_OK, "QueryInterface failed, hr=%lx\n", hr); hr = IWICBitmapDecoderInfo_GetCLSID(decoder_info, NULL); - ok(hr == E_INVALIDARG, "GetCLSID failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetCLSID failed, hr=%lx\n", hr); hr = IWICBitmapDecoderInfo_GetCLSID(decoder_info, &clsid); - ok(hr == S_OK, "GetCLSID failed, hr=%x\n", hr); + ok(hr == S_OK, "GetCLSID failed, hr=%lx\n", hr); ok(IsEqualGUID(test->clsid, &clsid), "GetCLSID returned wrong result\n"); hr = IWICBitmapDecoderInfo_GetMimeTypes(decoder_info, 0, NULL, NULL); - ok(hr == E_INVALIDARG, "GetMimeType failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetMimeType failed, hr=%lx\n", hr); len = 0; hr = IWICBitmapDecoderInfo_GetMimeTypes(decoder_info, 1, NULL, &len); - ok(hr == E_INVALIDARG, "GetMimeType failed, hr=%x\n", hr); - todo_wine_if(test->todo) + ok(hr == E_INVALIDARG, "GetMimeType failed, hr=%lx\n", hr); + todo_wine_if(test->todo) ok(len == lstrlenW(mimetypeW) + 1, "GetMimeType returned wrong len %i\n", len); hr = IWICBitmapDecoderInfo_GetMimeTypes(decoder_info, len, value, NULL); - ok(hr == E_INVALIDARG, "GetMimeType failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetMimeType failed, hr=%lx\n", hr); len = 0; hr = IWICBitmapDecoderInfo_GetMimeTypes(decoder_info, 0, NULL, &len); - ok(hr == S_OK, "GetMimeType failed, hr=%x\n", hr); - todo_wine_if(test->todo) + ok(hr == S_OK, "GetMimeType failed, hr=%lx\n", hr); + todo_wine_if(test->todo) ok(len == lstrlenW(mimetypeW) + 1, "GetMimeType returned wrong len %i\n", len); value[0] = 0; hr = IWICBitmapDecoderInfo_GetMimeTypes(decoder_info, len, value, &len); - ok(hr == S_OK, "GetMimeType failed, hr=%x\n", hr); + ok(hr == S_OK, "GetMimeType failed, hr=%lx\n", hr); todo_wine_if(test->todo) { ok(lstrcmpW(value, mimetypeW) == 0, "GetMimeType returned wrong value %s\n", wine_dbgstr_w(value)); ok(len == lstrlenW(mimetypeW) + 1, "GetMimeType returned wrong len %i\n", len); } hr = IWICBitmapDecoderInfo_GetMimeTypes(decoder_info, 1, value, &len); - ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "GetMimeType failed, hr=%x\n", hr); - todo_wine_if(test->todo) + ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "GetMimeType failed, hr=%lx\n", hr); + todo_wine_if(test->todo) ok(len == lstrlenW(mimetypeW) + 1, "GetMimeType returned wrong len %i\n", len); hr = IWICBitmapDecoderInfo_GetMimeTypes(decoder_info, 256, value, &len); - ok(hr == S_OK, "GetMimeType failed, hr=%x\n", hr); + ok(hr == S_OK, "GetMimeType failed, hr=%lx\n", hr); todo_wine_if(test->todo) { ok(lstrcmpW(value, mimetypeW) == 0, "GetMimeType returned wrong value %s\n", wine_dbgstr_w(value)); ok(len == lstrlenW(mimetypeW) + 1, "GetMimeType returned wrong len %i\n", len); } num_formats = 0xdeadbeef; hr = IWICBitmapDecoderInfo_GetPixelFormats(decoder_info, 0, NULL, &num_formats); - ok(hr == S_OK, "GetPixelFormats failed, hr=%x\n", hr); + ok(hr == S_OK, "GetPixelFormats failed, hr=%lx\n", hr); ok((num_formats <= 21 && num_formats >= 1) || broken(IsEqualCLSID(test->clsid, &CLSID_WICIcoDecoder) && num_formats == 0) /* WinXP */, "%u: got %d formats\n", i, num_formats); hr = IWICBitmapDecoderInfo_GetPixelFormats(decoder_info, 0, NULL, NULL); - ok(hr == E_INVALIDARG, "GetPixelFormats failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetPixelFormats failed, hr=%lx\n", hr); count = 0xdeadbeef; hr = IWICBitmapDecoderInfo_GetPixelFormats(decoder_info, 0, pixelformats, &count); - ok(hr == S_OK, "GetPixelFormats failed, hr=%x\n", hr); + ok(hr == S_OK, "GetPixelFormats failed, hr=%lx\n", hr); ok(count == 0, "got %d formats\n", count); count = 0xdeadbeef; hr = IWICBitmapDecoderInfo_GetPixelFormats(decoder_info, 1, pixelformats, &count); - ok(hr == S_OK, "GetPixelFormats failed, hr=%x\n", hr); + ok(hr == S_OK, "GetPixelFormats failed, hr=%lx\n", hr); ok((count == 1) || broken(IsEqualCLSID(test->clsid, &CLSID_WICIcoDecoder) && count == 0) /* WinXP */, "%u: got %d formats\n", i, num_formats); ok(is_pixelformat(&pixelformats[0]), "got invalid pixel format\n"); count = 0xdeadbeef; hr = IWICBitmapDecoderInfo_GetPixelFormats(decoder_info, num_formats, pixelformats, &count); - ok(hr == S_OK, "GetPixelFormats failed, hr=%x\n", hr); + ok(hr == S_OK, "GetPixelFormats failed, hr=%lx\n", hr); ok(count == num_formats, "got %d formats, expected %d\n", count, num_formats); for (j = 0; j < num_formats; j++) ok(is_pixelformat(&pixelformats[j]), "got invalid pixel format\n"); hr = IWICBitmapDecoderInfo_GetPixelFormats(decoder_info, num_formats, pixelformats, NULL); - ok(hr == E_INVALIDARG, "GetPixelFormats failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetPixelFormats failed, hr=%lx\n", hr); count = 0xdeadbeef; hr = IWICBitmapDecoderInfo_GetPixelFormats(decoder_info, ARRAY_SIZE(pixelformats), pixelformats, &count); - ok(hr == S_OK, "GetPixelFormats failed, hr=%x\n", hr); + ok(hr == S_OK, "GetPixelFormats failed, hr=%lx\n", hr); ok(count == num_formats, "got %d formats, expected %d\n", count, num_formats); hr = IWICBitmapDecoderInfo_GetFileExtensions(decoder_info, 0, NULL, NULL); - ok(hr == E_INVALIDARG, "GetFileExtensions failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetFileExtensions failed, hr=%lx\n", hr); hr = IWICBitmapDecoderInfo_GetFileExtensions(decoder_info, 1, NULL, &len); - ok(hr == E_INVALIDARG, "GetFileExtensions failed, hr=%x\n", hr); - todo_wine_if(test->todo && !IsEqualCLSID(test->clsid, &CLSID_WICTiffDecoder)) + ok(hr == E_INVALIDARG, "GetFileExtensions failed, hr=%lx\n", hr); + todo_wine_if(test->todo && !IsEqualCLSID(test->clsid, &CLSID_WICTiffDecoder)) ok(len == lstrlenW(extensionsW) + 1, "%u: GetFileExtensions returned wrong len %i\n", i, len); hr = IWICBitmapDecoderInfo_GetFileExtensions(decoder_info, len, value, NULL); - ok(hr == E_INVALIDARG, "GetFileExtensions failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetFileExtensions failed, hr=%lx\n", hr); hr = IWICBitmapDecoderInfo_GetFileExtensions(decoder_info, 0, NULL, &len); - ok(hr == S_OK, "GetFileExtensions failed, hr=%x\n", hr); - todo_wine_if(test->todo && !IsEqualCLSID(test->clsid, &CLSID_WICTiffDecoder)) + ok(hr == S_OK, "GetFileExtensions failed, hr=%lx\n", hr); + todo_wine_if(test->todo && !IsEqualCLSID(test->clsid, &CLSID_WICTiffDecoder)) ok(len == lstrlenW(extensionsW) + 1, "GetFileExtensions returned wrong len %i\n", len); value[0] = 0; hr = IWICBitmapDecoderInfo_GetFileExtensions(decoder_info, len, value, &len); - ok(hr == S_OK, "GetFileExtensions failed, hr=%x\n", hr); - todo_wine_if(test->todo) + ok(hr == S_OK, "GetFileExtensions failed, hr=%lx\n", hr); + todo_wine_if(test->todo) ok(lstrcmpW(value, extensionsW) == 0, "GetFileExtensions returned wrong value %s\n", wine_dbgstr_w(value)); - todo_wine_if(test->todo && !IsEqualCLSID(test->clsid, &CLSID_WICTiffDecoder)) + todo_wine_if(test->todo && !IsEqualCLSID(test->clsid, &CLSID_WICTiffDecoder)) ok(len == lstrlenW(extensionsW) + 1, "GetFileExtensions returned wrong len %i\n", len); hr = IWICBitmapDecoderInfo_GetFileExtensions(decoder_info, 1, value, &len); - ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "GetFileExtensions failed, hr=%x\n", hr); - todo_wine_if(test->todo && !IsEqualCLSID(test->clsid, &CLSID_WICTiffDecoder)) + ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "GetFileExtensions failed, hr=%lx\n", hr); + todo_wine_if(test->todo && !IsEqualCLSID(test->clsid, &CLSID_WICTiffDecoder)) ok(len == lstrlenW(extensionsW) + 1, "GetFileExtensions returned wrong len %i\n", len); hr = IWICBitmapDecoderInfo_GetFileExtensions(decoder_info, 256, value, &len); - ok(hr == S_OK, "GetFileExtensions failed, hr=%x\n", hr); - todo_wine_if(test->todo) + ok(hr == S_OK, "GetFileExtensions failed, hr=%lx\n", hr); + todo_wine_if(test->todo) ok(lstrcmpW(value, extensionsW) == 0, "GetFileExtensions returned wrong value %s\n", wine_dbgstr_w(value)); - todo_wine_if(test->todo && !IsEqualCLSID(test->clsid, &CLSID_WICTiffDecoder)) + todo_wine_if(test->todo && !IsEqualCLSID(test->clsid, &CLSID_WICTiffDecoder)) ok(len == lstrlenW(extensionsW) + 1, "GetFileExtensions returned wrong len %i\n", len); IWICBitmapDecoderInfo_Release(decoder_info); @@ -286,7 +292,7 @@ static void test_pixelformat_info(void) IWICPixelFormatInfo *pixelformat_info; IWICPixelFormatInfo2 *pixelformat_info2; HRESULT hr; - ULONG len, known_len; + UINT len, known_len; WCHAR value[256]; GUID guid; WICComponentType componenttype; @@ -297,29 +303,29 @@ static void test_pixelformat_info(void) BOOL supportstransparency; hr = get_component_info(&GUID_WICPixelFormat32bppBGRA, &info); - ok(hr == S_OK, "CreateComponentInfo failed, hr=%x\n", hr); + ok(hr == S_OK, "CreateComponentInfo failed, hr=%lx\n", hr); if (FAILED(hr)) return; hr = IWICComponentInfo_GetAuthor(info, 0, NULL, 0); - ok(hr == E_INVALIDARG, "GetAuthor failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetAuthor failed, hr=%lx\n", hr); len = 0xdeadbeef; hr = IWICComponentInfo_GetAuthor(info, 0, NULL, &len); - ok(hr == S_OK, "GetAuthor failed, hr=%x\n", hr); + ok(hr == S_OK, "GetAuthor failed, hr=%lx\n", hr); ok(len < 255 && len > 0, "invalid length 0x%x\n", len); known_len = len; memset(value, 0xaa, 256 * sizeof(WCHAR)); hr = IWICComponentInfo_GetAuthor(info, len-1, value, NULL); - ok(hr == E_INVALIDARG, "GetAuthor failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetAuthor failed, hr=%lx\n", hr); ok(value[0] == 0xaaaa, "string modified\n"); len = 0xdeadbeef; memset(value, 0xaa, 256 * sizeof(WCHAR)); hr = IWICComponentInfo_GetAuthor(info, known_len-1, value, &len); - ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "GetAuthor failed, hr=%x\n", hr); + ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "GetAuthor failed, hr=%lx\n", hr); ok(len == known_len, "got length of 0x%x, expected 0x%x\n", len, known_len); ok(value[known_len-1] == 0xaaaa, "string modified past given length\n"); ok(value[0] == 0xaaaa, "string modified\n"); @@ -327,7 +333,7 @@ static void test_pixelformat_info(void) len = 0xdeadbeef; memset(value, 0xaa, 256 * sizeof(WCHAR)); hr = IWICComponentInfo_GetAuthor(info, known_len, value, &len); - ok(hr == S_OK, "GetAuthor failed, hr=%x\n", hr); + ok(hr == S_OK, "GetAuthor failed, hr=%lx\n", hr); ok(len == known_len, "got length of 0x%x, expected 0x%x\n", len, known_len); ok(value[known_len-1] == 0, "string not terminated at expected length\n"); ok(value[known_len-2] != 0xaaaa, "string not modified at given length\n"); @@ -335,107 +341,107 @@ static void test_pixelformat_info(void) len = 0xdeadbeef; memset(value, 0xaa, 256 * sizeof(WCHAR)); hr = IWICComponentInfo_GetAuthor(info, known_len+1, value, &len); - ok(hr == S_OK, "GetAuthor failed, hr=%x\n", hr); + ok(hr == S_OK, "GetAuthor failed, hr=%lx\n", hr); ok(len == known_len, "got length of 0x%x, expected 0x%x\n", len, known_len); ok(value[known_len] == 0xaaaa, "string modified past end\n"); ok(value[known_len-1] == 0, "string not terminated at expected length\n"); ok(value[known_len-2] != 0xaaaa, "string not modified at given length\n"); hr = IWICComponentInfo_GetCLSID(info, NULL); - ok(hr == E_INVALIDARG, "GetCLSID failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetCLSID failed, hr=%lx\n", hr); memset(&guid, 0xaa, sizeof(guid)); hr = IWICComponentInfo_GetCLSID(info, &guid); - ok(hr == S_OK, "GetCLSID failed, hr=%x\n", hr); + ok(hr == S_OK, "GetCLSID failed, hr=%lx\n", hr); ok(IsEqualGUID(&guid, &GUID_WICPixelFormat32bppBGRA), "unexpected CLSID %s\n", wine_dbgstr_guid(&guid)); hr = IWICComponentInfo_GetComponentType(info, NULL); - ok(hr == E_INVALIDARG, "GetComponentType failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetComponentType failed, hr=%lx\n", hr); hr = IWICComponentInfo_GetComponentType(info, &componenttype); - ok(hr == S_OK, "GetComponentType failed, hr=%x\n", hr); + ok(hr == S_OK, "GetComponentType failed, hr=%lx\n", hr); ok(componenttype == WICPixelFormat, "unexpected component type 0x%x\n", componenttype); len = 0xdeadbeef; hr = IWICComponentInfo_GetFriendlyName(info, 0, NULL, &len); - ok(hr == S_OK, "GetFriendlyName failed, hr=%x\n", hr); + ok(hr == S_OK, "GetFriendlyName failed, hr=%lx\n", hr); ok(len < 255 && len > 0, "invalid length 0x%x\n", len); hr = IWICComponentInfo_GetSigningStatus(info, NULL); - ok(hr == E_INVALIDARG, "GetSigningStatus failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetSigningStatus failed, hr=%lx\n", hr); hr = IWICComponentInfo_GetSigningStatus(info, &signing); - ok(hr == S_OK, "GetSigningStatus failed, hr=%x\n", hr); - ok(signing == WICComponentSigned, "unexpected signing status 0x%x\n", signing); + ok(hr == S_OK, "GetSigningStatus failed, hr=%lx\n", hr); + ok(signing == WICComponentSigned, "unexpected signing status 0x%lx\n", signing); len = 0xdeadbeef; hr = IWICComponentInfo_GetSpecVersion(info, 0, NULL, &len); - ok(hr == S_OK, "GetSpecVersion failed, hr=%x\n", hr); + ok(hr == S_OK, "GetSpecVersion failed, hr=%lx\n", hr); ok(len == 0, "invalid length 0x%x\n", len); /* spec version does not apply to pixel formats */ memset(&guid, 0xaa, sizeof(guid)); hr = IWICComponentInfo_GetVendorGUID(info, &guid); - ok(hr == S_OK, "GetVendorGUID failed, hr=%x\n", hr); + ok(hr == S_OK, "GetVendorGUID failed, hr=%lx\n", hr); ok(IsEqualGUID(&guid, &GUID_VendorMicrosoft) || broken(IsEqualGUID(&guid, &GUID_NULL)) /* XP */, "unexpected GUID %s\n", wine_dbgstr_guid(&guid)); len = 0xdeadbeef; hr = IWICComponentInfo_GetVersion(info, 0, NULL, &len); - ok(hr == S_OK, "GetVersion failed, hr=%x\n", hr); + ok(hr == S_OK, "GetVersion failed, hr=%lx\n", hr); ok(len == 0, "invalid length 0x%x\n", len); /* version does not apply to pixel formats */ hr = IWICComponentInfo_QueryInterface(info, &IID_IWICPixelFormatInfo, (void**)&pixelformat_info); - ok(hr == S_OK, "QueryInterface failed, hr=%x\n", hr); + ok(hr == S_OK, "QueryInterface failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICPixelFormatInfo_GetBitsPerPixel(pixelformat_info, NULL); - ok(hr == E_INVALIDARG, "GetBitsPerPixel failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetBitsPerPixel failed, hr=%lx\n", hr); hr = IWICPixelFormatInfo_GetBitsPerPixel(pixelformat_info, &uiresult); - ok(hr == S_OK, "GetBitsPerPixel failed, hr=%x\n", hr); + ok(hr == S_OK, "GetBitsPerPixel failed, hr=%lx\n", hr); ok(uiresult == 32, "unexpected bpp %i\n", uiresult); hr = IWICPixelFormatInfo_GetChannelCount(pixelformat_info, &uiresult); - ok(hr == S_OK, "GetChannelCount failed, hr=%x\n", hr); + ok(hr == S_OK, "GetChannelCount failed, hr=%lx\n", hr); ok(uiresult == 4, "unexpected channel count %i\n", uiresult); hr = IWICPixelFormatInfo_GetChannelMask(pixelformat_info, 0, 0, NULL, NULL); - ok(hr == E_INVALIDARG, "GetChannelMask failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetChannelMask failed, hr=%lx\n", hr); uiresult = 0xdeadbeef; hr = IWICPixelFormatInfo_GetChannelMask(pixelformat_info, 0, 0, NULL, &uiresult); - ok(hr == S_OK, "GetChannelMask failed, hr=%x\n", hr); + ok(hr == S_OK, "GetChannelMask failed, hr=%lx\n", hr); ok(uiresult == 4, "unexpected length %i\n", uiresult); memset(abbuffer, 0xaa, sizeof(abbuffer)); hr = IWICPixelFormatInfo_GetChannelMask(pixelformat_info, 0, known_len, abbuffer, NULL); - ok(hr == E_INVALIDARG, "GetChannelMask failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetChannelMask failed, hr=%lx\n", hr); ok(abbuffer[0] == 0xaa, "buffer modified\n"); uiresult = 0xdeadbeef; memset(abbuffer, 0xaa, sizeof(abbuffer)); hr = IWICPixelFormatInfo_GetChannelMask(pixelformat_info, 0, 3, abbuffer, &uiresult); - ok(hr == E_INVALIDARG, "GetChannelMask failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetChannelMask failed, hr=%lx\n", hr); ok(abbuffer[0] == 0xaa, "buffer modified\n"); ok(uiresult == 4, "unexpected length %i\n", uiresult); memset(abbuffer, 0xaa, sizeof(abbuffer)); hr = IWICPixelFormatInfo_GetChannelMask(pixelformat_info, 0, 4, abbuffer, &uiresult); - ok(hr == S_OK, "GetChannelMask failed, hr=%x\n", hr); - ok(*((ULONG*)abbuffer) == 0xff, "unexpected mask 0x%x\n", *((ULONG*)abbuffer)); + ok(hr == S_OK, "GetChannelMask failed, hr=%lx\n", hr); + ok(*((ULONG*)abbuffer) == 0xff, "unexpected mask 0x%lx\n", *((ULONG*)abbuffer)); ok(uiresult == 4, "unexpected length %i\n", uiresult); memset(abbuffer, 0xaa, sizeof(abbuffer)); hr = IWICPixelFormatInfo_GetChannelMask(pixelformat_info, 0, 5, abbuffer, &uiresult); - ok(hr == S_OK, "GetChannelMask failed, hr=%x\n", hr); - ok(*((ULONG*)abbuffer) == 0xff, "unexpected mask 0x%x\n", *((ULONG*)abbuffer)); + ok(hr == S_OK, "GetChannelMask failed, hr=%lx\n", hr); + ok(*((ULONG*)abbuffer) == 0xff, "unexpected mask 0x%lx\n", *((ULONG*)abbuffer)); ok(abbuffer[4] == 0xaa, "buffer modified past actual length\n"); ok(uiresult == 4, "unexpected length %i\n", uiresult); memset(&guid, 0xaa, sizeof(guid)); hr = IWICPixelFormatInfo_GetFormatGUID(pixelformat_info, &guid); - ok(hr == S_OK, "GetFormatGUID failed, hr=%x\n", hr); + ok(hr == S_OK, "GetFormatGUID failed, hr=%lx\n", hr); ok(IsEqualGUID(&guid, &GUID_WICPixelFormat32bppBGRA), "unexpected GUID %s\n", wine_dbgstr_guid(&guid)); IWICPixelFormatInfo_Release(pixelformat_info); @@ -448,19 +454,19 @@ static void test_pixelformat_info(void) else { hr = IWICPixelFormatInfo2_GetNumericRepresentation(pixelformat_info2, NULL); - ok(hr == E_INVALIDARG, "GetNumericRepresentation failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetNumericRepresentation failed, hr=%lx\n", hr); numericrepresentation = 0xdeadbeef; hr = IWICPixelFormatInfo2_GetNumericRepresentation(pixelformat_info2, &numericrepresentation); - ok(hr == S_OK, "GetNumericRepresentation failed, hr=%x\n", hr); + ok(hr == S_OK, "GetNumericRepresentation failed, hr=%lx\n", hr); ok(numericrepresentation == WICPixelFormatNumericRepresentationUnsignedInteger, "unexpected numeric representation %i\n", numericrepresentation); hr = IWICPixelFormatInfo2_SupportsTransparency(pixelformat_info2, NULL); - ok(hr == E_INVALIDARG, "SupportsTransparency failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "SupportsTransparency failed, hr=%lx\n", hr); supportstransparency = 0xdeadbeef; hr = IWICPixelFormatInfo2_SupportsTransparency(pixelformat_info2, &supportstransparency); - ok(hr == S_OK, "SupportsTransparency failed, hr=%x\n", hr); + ok(hr == S_OK, "SupportsTransparency failed, hr=%lx\n", hr); ok(supportstransparency == 1, "unexpected value %i\n", supportstransparency); IWICPixelFormatInfo2_Release(pixelformat_info2); @@ -477,7 +483,7 @@ static DWORD WINAPI cache_across_threads_test(void *arg) CoInitialize(NULL); hr = get_component_info(&CLSID_WICUnknownMetadataReader, &info); - ok(hr == S_OK, "CreateComponentInfo failed, hr=%x\n", hr); + ok(hr == S_OK, "CreateComponentInfo failed, hr=%lx\n", hr); ok(info == arg, "unexpected info pointer %p\n", info); IWICComponentInfo_Release(info); @@ -493,21 +499,22 @@ static void test_reader_info(void) HRESULT hr; CLSID clsid; GUID container_formats[10]; - UINT count, size, tid; + UINT count, size; + DWORD tid; HANDLE thread; WICMetadataPattern *patterns; hr = get_component_info(&CLSID_WICUnknownMetadataReader, &info2); - ok(hr == S_OK, "CreateComponentInfo failed, hr=%x\n", hr); + ok(hr == S_OK, "CreateComponentInfo failed, hr=%lx\n", hr); IWICComponentInfo_Release(info2); hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&factory); - ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); + ok(hr == S_OK, "CoCreateInstance failed, hr=%lx\n", hr); if (FAILED(hr)) return; hr = IWICImagingFactory_CreateComponentInfo(factory, &CLSID_WICUnknownMetadataReader, &info); - ok(hr == S_OK, "CreateComponentInfo failed, hr=%x\n", hr); + ok(hr == S_OK, "CreateComponentInfo failed, hr=%lx\n", hr); ok(info == info2, "info != info2\n"); thread = CreateThread(NULL, 0, cache_across_threads_test, info, 0, &tid); @@ -515,36 +522,36 @@ static void test_reader_info(void) CloseHandle(thread); hr = IWICComponentInfo_QueryInterface(info, &IID_IWICMetadataReaderInfo, (void**)&reader_info); - ok(hr == S_OK, "QueryInterface failed, hr=%x\n", hr); + ok(hr == S_OK, "QueryInterface failed, hr=%lx\n", hr); hr = IWICMetadataReaderInfo_GetCLSID(reader_info, NULL); - ok(hr == E_INVALIDARG, "GetCLSID failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetCLSID failed, hr=%lx\n", hr); hr = IWICMetadataReaderInfo_GetCLSID(reader_info, &clsid); - ok(hr == S_OK, "GetCLSID failed, hr=%x\n", hr); + ok(hr == S_OK, "GetCLSID failed, hr=%lx\n", hr); ok(IsEqualGUID(&CLSID_WICUnknownMetadataReader, &clsid), "GetCLSID returned wrong result\n"); hr = IWICMetadataReaderInfo_GetMetadataFormat(reader_info, &clsid); - ok(hr == S_OK, "GetMetadataFormat failed, hr=%x\n", hr); + ok(hr == S_OK, "GetMetadataFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&GUID_MetadataFormatUnknown, &clsid), "GetMetadataFormat returned wrong result\n"); hr = IWICMetadataReaderInfo_GetContainerFormats(reader_info, 0, NULL, NULL); - ok(hr == E_INVALIDARG, "GetContainerFormats failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetContainerFormats failed, hr=%lx\n", hr); count = 0xdeadbeef; hr = IWICMetadataReaderInfo_GetContainerFormats(reader_info, 0, NULL, &count); - ok(hr == S_OK, "GetContainerFormats failed, hr=%x\n", hr); + ok(hr == S_OK, "GetContainerFormats failed, hr=%lx\n", hr); ok(count == 0, "unexpected count %d\n", count); hr = IWICMetadataReaderInfo_GetPatterns(reader_info, &GUID_ContainerFormatPng, 0, NULL, NULL, NULL); - ok(hr == E_INVALIDARG, "GetPatterns failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetPatterns failed, hr=%lx\n", hr); count = size = 0xdeadbeef; hr = IWICMetadataReaderInfo_GetPatterns(reader_info, &GUID_ContainerFormatPng, 0, NULL, &count, &size); ok(hr == WINCODEC_ERR_COMPONENTNOTFOUND || broken(hr == S_OK) /* Windows XP */, - "GetPatterns failed, hr=%x\n", hr); + "GetPatterns failed, hr=%lx\n", hr); ok(count == 0xdeadbeef, "unexpected count %d\n", count); ok(size == 0xdeadbeef, "unexpected size %d\n", size); @@ -553,8 +560,8 @@ static void test_reader_info(void) IWICComponentInfo_Release(info); hr = IWICImagingFactory_CreateComponentInfo(factory, &CLSID_WICXMPStructMetadataReader, &info); -todo_wine - ok(hr == S_OK, "CreateComponentInfo failed, hr=%x\n", hr); + todo_wine + ok(hr == S_OK, "CreateComponentInfo failed, hr=%lx\n", hr); if (FAILED(hr)) { @@ -563,49 +570,49 @@ todo_wine } hr = IWICComponentInfo_QueryInterface(info, &IID_IWICMetadataReaderInfo, (void**)&reader_info); - ok(hr == S_OK, "QueryInterface failed, hr=%x\n", hr); + ok(hr == S_OK, "QueryInterface failed, hr=%lx\n", hr); hr = IWICMetadataReaderInfo_GetCLSID(reader_info, NULL); - ok(hr == E_INVALIDARG, "GetCLSID failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetCLSID failed, hr=%lx\n", hr); hr = IWICMetadataReaderInfo_GetCLSID(reader_info, &clsid); - ok(hr == S_OK, "GetCLSID failed, hr=%x\n", hr); + ok(hr == S_OK, "GetCLSID failed, hr=%lx\n", hr); ok(IsEqualGUID(&CLSID_WICXMPStructMetadataReader, &clsid), "GetCLSID returned wrong result\n"); hr = IWICMetadataReaderInfo_GetMetadataFormat(reader_info, &clsid); - ok(hr == S_OK, "GetMetadataFormat failed, hr=%x\n", hr); + ok(hr == S_OK, "GetMetadataFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&GUID_MetadataFormatXMPStruct, &clsid), "GetMetadataFormat returned wrong result\n"); hr = IWICMetadataReaderInfo_GetContainerFormats(reader_info, 0, NULL, NULL); - ok(hr == E_INVALIDARG, "GetContainerFormats failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetContainerFormats failed, hr=%lx\n", hr); count = 0xdeadbeef; hr = IWICMetadataReaderInfo_GetContainerFormats(reader_info, 0, NULL, &count); - ok(hr == S_OK, "GetContainerFormats failed, hr=%x\n", hr); + ok(hr == S_OK, "GetContainerFormats failed, hr=%lx\n", hr); ok(count >= 2, "unexpected count %d\n", count); count = 0xdeadbeef; hr = IWICMetadataReaderInfo_GetContainerFormats(reader_info, 1, container_formats, &count); - ok(hr == S_OK, "GetContainerFormats failed, hr=%x\n", hr); + ok(hr == S_OK, "GetContainerFormats failed, hr=%lx\n", hr); ok(count == 1, "unexpected count %d\n", count); count = 0xdeadbeef; hr = IWICMetadataReaderInfo_GetContainerFormats(reader_info, 10, container_formats, &count); - ok(hr == S_OK, "GetContainerFormats failed, hr=%x\n", hr); + ok(hr == S_OK, "GetContainerFormats failed, hr=%lx\n", hr); ok(count == min(count, 10), "unexpected count %d\n", count); count = size = 0xdeadbeef; hr = IWICMetadataReaderInfo_GetPatterns(reader_info, &GUID_ContainerFormatPng, 0, NULL, &count, &size); ok(hr == WINCODEC_ERR_COMPONENTNOTFOUND || broken(hr == S_OK) /* Windows XP */, - "GetPatterns failed, hr=%x\n", hr); + "GetPatterns failed, hr=%lx\n", hr); ok(count == 0xdeadbeef, "unexpected count %d\n", count); ok(size == 0xdeadbeef, "unexpected size %d\n", size); count = size = 0xdeadbeef; hr = IWICMetadataReaderInfo_GetPatterns(reader_info, &GUID_MetadataFormatXMP, 0, NULL, &count, &size); - ok(hr == S_OK, "GetPatterns failed, hr=%x\n", hr); + ok(hr == S_OK, "GetPatterns failed, hr=%lx\n", hr); ok(count == 1, "unexpected count %d\n", count); ok(size > sizeof(WICMetadataPattern), "unexpected size %d\n", size); @@ -616,14 +623,14 @@ todo_wine count = size = 0xdeadbeef; hr = IWICMetadataReaderInfo_GetPatterns(reader_info, &GUID_MetadataFormatXMP, size-1, patterns, &count, &size); - ok(hr == S_OK, "GetPatterns failed, hr=%x\n", hr); + ok(hr == S_OK, "GetPatterns failed, hr=%lx\n", hr); ok(count == 1, "unexpected count %d\n", count); ok(size > sizeof(WICMetadataPattern), "unexpected size %d\n", size); count = size = 0xdeadbeef; hr = IWICMetadataReaderInfo_GetPatterns(reader_info, &GUID_MetadataFormatXMP, size, patterns, &count, &size); - ok(hr == S_OK, "GetPatterns failed, hr=%x\n", hr); + ok(hr == S_OK, "GetPatterns failed, hr=%lx\n", hr); ok(count == 1, "unexpected count %d\n", count); ok(size == sizeof(WICMetadataPattern) + patterns->Length * 2, "unexpected size %d\n", size); @@ -653,15 +660,15 @@ static void test_imagingfactory_interfaces(void) } hr = IWICImagingFactory2_QueryInterface(factory2, &IID_IWICComponentFactory, (void **)&component_factory); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = IWICComponentFactory_QueryInterface(component_factory, &IID_IWICImagingFactory, (void **)&factory); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(factory == (IWICImagingFactory *)component_factory, "Unexpected factory pointer.\n"); IWICImagingFactory_Release(factory); hr = IWICImagingFactory2_QueryInterface(factory2, &IID_IWICImagingFactory, (void **)&factory); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(factory == (IWICImagingFactory *)component_factory, "Unexpected factory pointer.\n"); IWICComponentFactory_Release(component_factory); @@ -669,6 +676,41 @@ static void test_imagingfactory_interfaces(void) IWICImagingFactory_Release(factory); } +static void test_component_enumerator(void) +{ + static const unsigned int types[] = + { + WICDecoder, + WICEncoder, + WICPixelFormatConverter, + WICMetadataReader, + WICPixelFormat, + }; + IWICImagingFactory *factory; + IEnumUnknown *enumerator; + unsigned int i; + IUnknown *item; + HRESULT hr; + + hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICImagingFactory, (void **)&factory); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + for (i = 0; i < ARRAY_SIZE(types); ++i) + { + hr = IWICImagingFactory_CreateComponentEnumerator(factory, types[i], 0, &enumerator); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IEnumUnknown_Next(enumerator, 1, &item, NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IUnknown_Release(item); + + IEnumUnknown_Release(enumerator); + } + + IWICImagingFactory_Release(factory); +} + START_TEST(info) { CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); @@ -677,6 +719,7 @@ START_TEST(info) test_reader_info(); test_pixelformat_info(); test_imagingfactory_interfaces(); + test_component_enumerator(); CoUninitialize(); } diff --git a/modules/rostests/winetests/windowscodecs/jpegformat.c b/modules/rostests/winetests/windowscodecs/jpegformat.c index c1e46c4869451..e150174f98d41 100644 --- a/modules/rostests/winetests/windowscodecs/jpegformat.c +++ b/modules/rostests/winetests/windowscodecs/jpegformat.c @@ -47,6 +47,8 @@ static void test_decode_adobe_cmyk(void) { IWICBitmapDecoder *decoder; IWICBitmapFrameDecode *framedecode; + IWICImagingFactory *factory; + IWICPalette *palette; HRESULT hr; HGLOBAL hjpegdata; char *jpegdata; @@ -74,9 +76,13 @@ static void test_decode_adobe_cmyk(void) hr = CoCreateInstance(&CLSID_WICJpegDecoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void**)&decoder); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); if (FAILED(hr)) return; + hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICImagingFactory, (void **)&factory); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); + hjpegdata = GlobalAlloc(GMEM_MOVEABLE, sizeof(jpeg_adobe_cmyk_1x5)); ok(hjpegdata != 0, "GlobalAlloc failed\n"); if (hjpegdata) @@ -86,31 +92,31 @@ static void test_decode_adobe_cmyk(void) GlobalUnlock(hjpegdata); hr = CreateStreamOnHGlobal(hjpegdata, FALSE, &jpegstream); - ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_Initialize(decoder, jpegstream, WICDecodeMetadataCacheOnLoad); - ok(hr == S_OK, "Initialize failed, hr=%x\n", hr); + ok(hr == S_OK, "Initialize failed, hr=%lx\n", hr); hr = IWICBitmapDecoder_GetContainerFormat(decoder, &guidresult); - ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&guidresult, &GUID_ContainerFormatJpeg), "unexpected container format\n"); hr = IWICBitmapDecoder_GetFrameCount(decoder, &count); - ok(SUCCEEDED(hr), "GetFrameCount failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetFrameCount failed, hr=%lx\n", hr); ok(count == 1, "unexpected count %u\n", count); hr = IWICBitmapDecoder_GetFrame(decoder, 0, &framedecode); - ok(SUCCEEDED(hr), "GetFrame failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetFrame failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapFrameDecode_GetSize(framedecode, &width, &height); - ok(SUCCEEDED(hr), "GetSize failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetSize failed, hr=%lx\n", hr); ok(width == 1, "expected width=1, got %u\n", width); ok(height == 5, "expected height=5, got %u\n", height); hr = IWICBitmapFrameDecode_GetPixelFormat(framedecode, &guidresult); - ok(SUCCEEDED(hr), "GetPixelFormat failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetPixelFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&guidresult, &GUID_WICPixelFormat32bppCMYK) || broken(IsEqualGUID(&guidresult, &GUID_WICPixelFormat24bppBGR)), /* xp/2003 */ "unexpected pixel format: %s\n", wine_dbgstr_guid(&guidresult)); @@ -120,18 +126,32 @@ static void test_decode_adobe_cmyk(void) for(i=2; i>0; --i) { hr = IWICBitmapFrameDecode_CopyPixels(framedecode, NULL, 4, sizeof(imagedata), imagedata); - ok(SUCCEEDED(hr), "CopyPixels failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CopyPixels failed, hr=%lx\n", hr); ok(!memcmp(imagedata, expected_imagedata, sizeof(imagedata)) || broken(!memcmp(imagedata, expected_imagedata_24bpp, sizeof(expected_imagedata))), /* xp/2003 */ "unexpected image data\n"); } + + hr = IWICImagingFactory_CreatePalette(factory, &palette); + ok(SUCCEEDED(hr), "CreatePalette failed, hr=%lx\n", hr); + + hr = IWICBitmapDecoder_CopyPalette(decoder, palette); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "Unexpected hr %#lx.\n", hr); + + hr = IWICBitmapFrameDecode_CopyPalette(framedecode, palette); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "Unexpected hr %#lx.\n", hr); + + IWICPalette_Release(palette); + IWICBitmapFrameDecode_Release(framedecode); } IStream_Release(jpegstream); } GlobalFree(hjpegdata); } + IWICBitmapDecoder_Release(decoder); + IWICImagingFactory_Release(factory); } diff --git a/modules/rostests/winetests/windowscodecs/metadata.c b/modules/rostests/winetests/windowscodecs/metadata.c index 58da19cee479b..7dd10f5ce9d4f 100644 --- a/modules/rostests/winetests/windowscodecs/metadata.c +++ b/modules/rostests/winetests/windowscodecs/metadata.c @@ -37,29 +37,93 @@ #include "initguid.h" DEFINE_GUID(IID_MdbrUnknown, 0x00240e6f,0x3f23,0x4432,0xb0,0xcc,0x48,0xd5,0xbb,0xff,0x6c,0x36); -#define expect_blob(propvar, data, length) do { \ - ok((propvar).vt == VT_BLOB, "unexpected vt: %i\n", (propvar).vt); \ - if ((propvar).vt == VT_BLOB) { \ - ok(U(propvar).blob.cbSize == (length), "expected size %u, got %u\n", (ULONG)(length), U(propvar).blob.cbSize); \ - if (U(propvar).blob.cbSize == (length)) { \ - ok(!memcmp(U(propvar).blob.pBlobData, (data), (length)), "unexpected data\n"); \ - } \ - } \ -} while (0) - -#define IFD_BYTE 1 -#define IFD_ASCII 2 -#define IFD_SHORT 3 -#define IFD_LONG 4 -#define IFD_RATIONAL 5 -#define IFD_SBYTE 6 -#define IFD_UNDEFINED 7 -#define IFD_SSHORT 8 -#define IFD_SLONG 9 -#define IFD_SRATIONAL 10 -#define IFD_FLOAT 11 -#define IFD_DOUBLE 12 -#define IFD_IFD 13 +#define expect_ref(obj,ref) expect_ref_((IUnknown *)obj, ref, __LINE__) +static void expect_ref_(IUnknown *obj, ULONG ref, int line) +{ + ULONG refcount; + IUnknown_AddRef(obj); + refcount = IUnknown_Release(obj); + ok_(__FILE__, line)(refcount == ref, "Expected refcount %ld, got %ld.\n", ref, refcount); +} + +#define check_interface(a, b, c) check_interface_(__LINE__, a, b, c) +static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported) +{ + IUnknown *iface = iface_ptr; + HRESULT hr, expected_hr; + IUnknown *unk; + + expected_hr = supported ? S_OK : E_NOINTERFACE; + + hr = IUnknown_QueryInterface(iface, iid, (void **)&unk); + ok_(__FILE__, line)(hr == expected_hr, "Got hr %#lx, expected %#lx.\n", hr, expected_hr); + if (SUCCEEDED(hr)) + IUnknown_Release(unk); +} + +#define check_persist_options(a, b) check_persist_options_(__LINE__, a, b) +static void check_persist_options_(unsigned int line, void *iface_ptr, DWORD expected_options) +{ + IWICStreamProvider *stream_provider; + IUnknown *iface = iface_ptr; + DWORD options; + HRESULT hr; + + if (SUCCEEDED(IUnknown_QueryInterface(iface, &IID_IWICStreamProvider, (void **)&stream_provider))) + { + hr = IWICStreamProvider_GetPersistOptions(stream_provider, &options); + ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (hr == S_OK) + ok_(__FILE__, line)(options == expected_options, "Unexpected options %#lx.\n", options); + IWICStreamProvider_Release(stream_provider); + } + else + ok_(__FILE__, line)(0, "IWICStreamProvider is not supported.\n"); +} + +static HRESULT get_persist_stream(void *iface_ptr, IStream **stream) +{ + IWICStreamProvider *stream_provider; + IUnknown *iface = iface_ptr; + HRESULT hr = E_UNEXPECTED; + + if (SUCCEEDED(IUnknown_QueryInterface(iface, &IID_IWICStreamProvider, (void **)&stream_provider))) + { + hr = IWICStreamProvider_GetStream(stream_provider, stream); + IWICStreamProvider_Release(stream_provider); + } + + return hr; +} + +#define compare_blob(a,b,c) compare_blob_(__LINE__,a,b,c) +static void compare_blob_(unsigned int line, const PROPVARIANT *propvar, const char *data, ULONG length) +{ + ok_(__FILE__, line)(propvar->vt == VT_BLOB, "Unexpected vt: %i\n", propvar->vt); + if (propvar->vt == VT_BLOB) + { + ok_(__FILE__, line)(propvar->blob.cbSize == length, "Expected size %lu, got %lu.\n", length, propvar->blob.cbSize); + if (propvar->blob.cbSize == length) + ok_(__FILE__, line)(!memcmp(propvar->blob.pBlobData, data, length), "Unexpected data.\n"); + } +} + +enum ifd_entry_type +{ + IFD_BYTE = 1, + IFD_ASCII = 2, + IFD_SHORT = 3, + IFD_LONG = 4, + IFD_RATIONAL = 5, + IFD_SBYTE = 6, + IFD_UNDEFINED = 7, + IFD_SSHORT = 8, + IFD_SLONG = 9, + IFD_SRATIONAL = 10, + IFD_FLOAT = 11, + IFD_DOUBLE = 12, + IFD_IFD = 13, +}; #include "pshpack2.h" struct IFD_entry @@ -161,6 +225,25 @@ static const char metadata_cHRM[] = { 0xff,0xff,0xff,0xff /* chunk CRC */ }; +static const char metadata_hIST[] = { + 0,0,0,40, /* chunk length */ + 'h','I','S','T', /* chunk type */ + 0,1, 0,2, 0,3, 0,4, + 0,5, 0,6, 0,7, 0,8, + 0,9, 0,10, 0,11, 0,12, + 0,13, 0,14, 0,15, 0,16, + 0,17, 0,18, 0,19, 0,20, + 0xff,0xff,0xff,0xff +}; + +static const char metadata_tIME[] = { + 0,0,0,7, /* chunk length */ + 't','I','M','E', /* chunk type */ + 0x07,0xd0,0x01,0x02, /* year (2 bytes), month, day */ + 0x0c,0x22,0x38, /* hour, minute, second */ + 0xff,0xff,0xff,0xff +}; + static const char pngimage[285] = { 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52, 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0x90,0x77,0x53, @@ -191,16 +274,23 @@ static const char animatedgif[] = { 0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81, 0xDE,0xDE,0xDE,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x4C,0x01,0x00, +0x21,0xF9,0x04,0x01,0x0A,0x00,0x01,0x00, 0x21,0xFE,0x08,'i','m','a','g','e',' ','#','1',0x00, 0x21,0x01,0x0C,'p','l','a','i','n','t','e','x','t',' ','#','1',0x00, -0x21,0xF9,0x04,0x01,0x0A,0x00,0x01,0x00,0x2C, -0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81, +0x2C,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81, 0x4D,0x4D,0x4D,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x44,0x01,0x00, 0x21,0xFE,0x08,'i','m','a','g','e',' ','#','2',0x00, 0x21,0x01,0x0C,'p','l','a','i','n','t','e','x','t',' ','#','2',0x00,0x3B }; +static ULONG get_refcount(void *iface) +{ + IUnknown *unknown = iface; + IUnknown_AddRef(unknown); + return IUnknown_Release(unknown); +} + static IStream *create_stream(const char *data, int data_size) { HRESULT hr; @@ -217,62 +307,293 @@ static IStream *create_stream(const char *data, int data_size) GlobalUnlock(hdata); hr = CreateStreamOnHGlobal(hdata, TRUE, &stream); - ok(hr == S_OK, "CreateStreamOnHGlobal failed, hr=%x\n", hr); + ok(hr == S_OK, "CreateStreamOnHGlobal failed, hr=%lx\n", hr); return stream; } -static void load_stream(IUnknown *reader, const char *data, int data_size, DWORD persist_options) +static void load_stream(void *iface_ptr, const char *data, int data_size, DWORD persist_options) { + IWICStreamProvider *stream_provider; + IUnknown *iface = iface_ptr; HRESULT hr; IWICPersistStream *persist; - IStream *stream; + IStream *stream, *stream2; LARGE_INTEGER pos; ULARGE_INTEGER cur_pos; + DWORD flags; + GUID guid; stream = create_stream(data, data_size); if (!stream) return; - hr = IUnknown_QueryInterface(reader, &IID_IWICPersistStream, (void**)&persist); - ok(hr == S_OK, "QueryInterface failed, hr=%x\n", hr); - - if (SUCCEEDED(hr)) + hr = IUnknown_QueryInterface(iface, &IID_IWICPersistStream, (void **)&persist); + ok(hr == S_OK, "QueryInterface failed, hr=%lx\n", hr); + + hr = IWICPersistStream_LoadEx(persist, NULL, NULL, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IUnknown_QueryInterface(iface, &IID_IWICStreamProvider, (void **)&stream_provider); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + memset(&guid, 0, sizeof(guid)); + hr = IWICStreamProvider_GetPreferredVendorGUID(stream_provider, &guid); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(IsEqualGUID(&guid, &GUID_VendorMicrosoft), "Unexpected vendor %s.\n", wine_dbgstr_guid(&guid)); + + hr = IWICStreamProvider_GetPreferredVendorGUID(stream_provider, NULL); + todo_wine + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + + hr = IWICStreamProvider_GetPersistOptions(stream_provider, NULL); + todo_wine + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + + flags = 123; + hr = IWICStreamProvider_GetPersistOptions(stream_provider, &flags); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(!flags, "Unexpected options %#lx.\n", flags); + + stream2 = (void *)0xdeadbeef; + hr = IWICStreamProvider_GetStream(stream_provider, &stream2); + todo_wine + ok(hr == WINCODEC_ERR_STREAMNOTAVAILABLE, "Unexpected hr %#lx.\n", hr); + ok(stream2 == (void *)0xdeadbeef, "Unexpected stream pointer.\n"); + + hr = IWICPersistStream_LoadEx(persist, stream, NULL, persist_options); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + memset(&guid, 0, sizeof(guid)); + hr = IWICStreamProvider_GetPreferredVendorGUID(stream_provider, &guid); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(IsEqualGUID(&guid, &GUID_VendorMicrosoft), "Unexpected vendor %s.\n", wine_dbgstr_guid(&guid)); + + flags = ~persist_options; + hr = IWICStreamProvider_GetPersistOptions(stream_provider, &flags); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(flags == persist_options, "Unexpected options %#lx.\n", flags); + + if (persist_options & WICPersistOptionNoCacheStream) { - hr = IWICPersistStream_LoadEx(persist, stream, NULL, persist_options); - ok(hr == S_OK, "LoadEx failed, hr=%x\n", hr); - - IWICPersistStream_Release(persist); + stream2 = (void *)0xdeadbeef; + hr = IWICStreamProvider_GetStream(stream_provider, &stream2); + todo_wine + ok(hr == WINCODEC_ERR_STREAMNOTAVAILABLE, "Unexpected hr %#lx.\n", hr); + ok(stream2 == (void *)0xdeadbeef, "Unexpected stream pointer.\n"); + } + else + { + stream2 = NULL; + hr = IWICStreamProvider_GetStream(stream_provider, &stream2); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(stream2 == stream, "Unexpected stream pointer.\n"); + if (stream2) + IStream_Release(stream2); } + IWICStreamProvider_Release(stream_provider); + IWICPersistStream_Release(persist); + pos.QuadPart = 0; hr = IStream_Seek(stream, pos, SEEK_CUR, &cur_pos); - ok(hr == S_OK, "IStream_Seek error %#x\n", hr); + ok(hr == S_OK, "IStream_Seek error %#lx\n", hr); /* IFD metadata reader doesn't rewind the stream to the start */ ok(cur_pos.QuadPart == 0 || cur_pos.QuadPart <= data_size, - "current stream pos is at %x/%x, data size %x\n", cur_pos.u.LowPart, cur_pos.u.HighPart, data_size); + "current stream pos is at %lx/%lx, data size %x\n", cur_pos.u.LowPart, cur_pos.u.HighPart, data_size); IStream_Release(stream); } +struct test_data +{ + ULONG type, id; + int count; /* if VT_VECTOR */ + LONGLONG value[13]; + const char *string; + const WCHAR id_string[32]; +}; + +static void compare_metadata(IWICMetadataReader *reader, const struct test_data *td, ULONG count) +{ + HRESULT hr; + IWICEnumMetadataItem *enumerator; + PROPVARIANT schema, id, value; + ULONG items_returned, i; + + hr = IWICMetadataReader_GetEnumerator(reader, NULL); + ok(hr == E_INVALIDARG, "GetEnumerator error %#lx\n", hr); + + hr = IWICMetadataReader_GetEnumerator(reader, &enumerator); + ok(hr == S_OK, "GetEnumerator error %#lx\n", hr); + + PropVariantInit(&schema); + PropVariantInit(&id); + PropVariantInit(&value); + + for (i = 0; i < count; i++) + { + winetest_push_context("%lu", i); + + hr = IWICEnumMetadataItem_Next(enumerator, 1, &schema, &id, &value, &items_returned); + ok(hr == S_OK, "Next error %#lx\n", hr); + ok(items_returned == 1, "unexpected item count %lu\n", items_returned); + + ok(schema.vt == VT_EMPTY, "Unexpected vt: %u\n", schema.vt); + ok(id.vt == VT_UI2 || id.vt == VT_LPWSTR || id.vt == VT_EMPTY, "Unexpected vt: %u\n", id.vt); + if (id.vt == VT_UI2) + ok(id.uiVal == td[i].id, "Expected id %#lx, got %#x\n", td[i].id, id.uiVal); + else if (id.vt == VT_LPWSTR) + ok(!lstrcmpW(td[i].id_string, id.pwszVal), + "Expected %s, got %s\n", wine_dbgstr_w(td[i].id_string), wine_dbgstr_w(id.pwszVal)); + + ok(value.vt == td[i].type, "Expected vt %#lx, got %#x\n", td[i].type, value.vt); + if (value.vt & VT_VECTOR) + { + ULONG j; + switch (value.vt & ~VT_VECTOR) + { + case VT_I1: + case VT_UI1: + ok(td[i].count == value.caub.cElems, "Expected cElems %d, got %ld\n", td[i].count, value.caub.cElems); + for (j = 0; j < value.caub.cElems; j++) + ok(td[i].value[j] == value.caub.pElems[j], "Expected value[%ld] %#I64x, got %#x\n", j, td[i].value[j], value.caub.pElems[j]); + break; + case VT_I2: + case VT_UI2: + ok(td[i].count == value.caui.cElems, "Expected cElems %d, got %ld\n", td[i].count, value.caui.cElems); + for (j = 0; j < value.caui.cElems; j++) + ok(td[i].value[j] == value.caui.pElems[j], "Expected value[%ld] %#I64x, got %#x\n", j, td[i].value[j], value.caui.pElems[j]); + break; + case VT_I4: + case VT_UI4: + case VT_R4: + ok(td[i].count == value.caul.cElems, "Expected cElems %d, got %ld\n", td[i].count, value.caul.cElems); + for (j = 0; j < value.caul.cElems; j++) + ok(td[i].value[j] == value.caul.pElems[j], "Expected value[%ld] %#I64x, got %#lx\n", j, td[i].value[j], value.caul.pElems[j]); + break; + case VT_I8: + case VT_UI8: + case VT_R8: + ok(td[i].count == value.cauh.cElems, "Expected cElems %d, got %ld\n", td[i].count, value.cauh.cElems); + for (j = 0; j < value.cauh.cElems; j++) + ok(td[i].value[j] == value.cauh.pElems[j].QuadPart, "Expected value[%ld] %I64x, got %08lx/%08lx\n", j, td[i].value[j], value.cauh.pElems[j].u.LowPart, value.cauh.pElems[j].u.HighPart); + break; + case VT_LPSTR: + ok(td[i].count == value.calpstr.cElems, "Expected cElems %d, got %ld\n", td[i].count, value.caub.cElems); + for (j = 0; j < value.calpstr.cElems; j++) + trace("%lu: %s\n", j, value.calpstr.pElems[j]); + /* fall through to not handled message */ + default: + ok(0, "vector of type %d is not handled\n", value.vt & ~VT_VECTOR); + break; + } + } + else if (value.vt == VT_LPSTR) + { + ok(td[i].count == strlen(value.pszVal) || + broken(td[i].count == strlen(value.pszVal) + 1), /* before Win7 */ + "Expected count %d, got %d\n", td[i].count, lstrlenA(value.pszVal)); + if (td[i].count == strlen(value.pszVal)) + ok(!strcmp(td[i].string, value.pszVal), + "Expected %s, got %s\n", td[i].string, value.pszVal); + } + else if (value.vt == VT_BLOB) + { + ok(td[i].count == value.blob.cbSize, "Expected count %d, got %ld\n", td[i].count, value.blob.cbSize); + ok(!memcmp(td[i].string, value.blob.pBlobData, td[i].count), "Expected %s, got %s\n", td[i].string, value.blob.pBlobData); + } + else + ok(value.uhVal.QuadPart == td[i].value[0], "Eexpected value %#I64x got %#lx/%#lx\n", + td[i].value[0], value.uhVal.u.LowPart, value.uhVal.u.HighPart); + + PropVariantClear(&schema); + PropVariantClear(&id); + PropVariantClear(&value); + + winetest_pop_context(); + } + + hr = IWICEnumMetadataItem_Next(enumerator, 1, &schema, &id, &value, &items_returned); + ok(hr == S_FALSE, "Next should fail\n"); + ok(items_returned == 0, "unexpected item count %lu\n", items_returned); + + IWICEnumMetadataItem_Release(enumerator); +} + +#define test_reader_container_format(a, b) _test_reader_container_format(a, b, __LINE__) +static void _test_reader_container_format(IWICMetadataReader *reader, const GUID *format, unsigned int line) +{ + IWICMetadataHandlerInfo *info; + BOOL found = FALSE; + GUID formats[8]; + UINT count; + HRESULT hr; + + hr = IWICMetadataReader_GetMetadataHandlerInfo(reader, &info); + ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IWICMetadataHandlerInfo_GetContainerFormats(info, ARRAY_SIZE(formats), formats, &count); + ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok_(__FILE__, line)(count > 0, "Unexpected count.\n"); + + for (unsigned i = 0; i < count; ++i) + { + if (IsEqualGUID(&formats[i], format)) + { + found = TRUE; + break; + } + } + ok_(__FILE__, line)(found, "Container format %s was not found.\n", wine_dbgstr_guid(format)); + + if (!found) + { + for (unsigned i = 0; i < count; ++i) + ok_(__FILE__, line)(0, "Available format %s.\n", wine_dbgstr_guid(&formats[i])); + } + + IWICMetadataHandlerInfo_Release(info); +} + + static void test_metadata_unknown(void) { HRESULT hr; IWICMetadataReader *reader; IWICEnumMetadataItem *enumerator; - IWICMetadataBlockReader *blockreader; PROPVARIANT schema, id, value; + IWICMetadataWriter *writer; + IWICPersistStream *persist; ULONG items_returned; + UINT count; hr = CoCreateInstance(&CLSID_WICUnknownMetadataReader, NULL, CLSCTX_INPROC_SERVER, &IID_IWICMetadataReader, (void**)&reader); - ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); + ok(hr == S_OK, "CoCreateInstance failed, hr=%lx\n", hr); if (FAILED(hr)) return; - load_stream((IUnknown*)reader, metadata_unknown, sizeof(metadata_unknown), WICPersistOptionDefault); + check_interface(reader, &IID_IWICMetadataReader, TRUE); + check_interface(reader, &IID_IPersist, TRUE); + check_interface(reader, &IID_IPersistStream, TRUE); + check_interface(reader, &IID_IWICPersistStream, TRUE); + check_interface(reader, &IID_IWICStreamProvider, TRUE); + check_interface(reader, &IID_IWICMetadataBlockReader, FALSE); + + load_stream(reader, metadata_unknown, sizeof(metadata_unknown), WICPersistOptionDefault); hr = IWICMetadataReader_GetEnumerator(reader, &enumerator); - ok(hr == S_OK, "GetEnumerator failed, hr=%x\n", hr); + ok(hr == S_OK, "GetEnumerator failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { @@ -281,14 +602,14 @@ static void test_metadata_unknown(void) PropVariantInit(&value); hr = IWICEnumMetadataItem_Next(enumerator, 1, &schema, &id, &value, &items_returned); - ok(hr == S_OK, "Next failed, hr=%x\n", hr); - ok(items_returned == 1, "unexpected item count %i\n", items_returned); + ok(hr == S_OK, "Next failed, hr=%lx\n", hr); + ok(items_returned == 1, "unexpected item count %li\n", items_returned); if (hr == S_OK && items_returned == 1) { ok(schema.vt == VT_EMPTY, "unexpected vt: %i\n", schema.vt); ok(id.vt == VT_EMPTY, "unexpected vt: %i\n", id.vt); - expect_blob(value, metadata_unknown, sizeof(metadata_unknown)); + compare_blob(&value, metadata_unknown, sizeof(metadata_unknown)); PropVariantClear(&schema); PropVariantClear(&id); @@ -296,28 +617,71 @@ static void test_metadata_unknown(void) } hr = IWICEnumMetadataItem_Next(enumerator, 1, &schema, &id, &value, &items_returned); - ok(hr == S_FALSE, "Next failed, hr=%x\n", hr); - ok(items_returned == 0, "unexpected item count %i\n", items_returned); + ok(hr == S_FALSE, "Next failed, hr=%lx\n", hr); + ok(items_returned == 0, "unexpected item count %li\n", items_returned); + + hr = IWICEnumMetadataItem_Reset(enumerator); + ok(hr == S_OK, "Reset failed, hr=%lx\n", hr); + + hr = IWICEnumMetadataItem_Next(enumerator, 1, &schema, &id, NULL, NULL); + ok(hr == S_OK, "Next failed, hr=%lx\n", hr); + + if (hr == S_OK) + { + ok(schema.vt == VT_EMPTY, "unexpected vt: %i\n", schema.vt); + ok(id.vt == VT_EMPTY, "unexpected vt: %i\n", id.vt); + + PropVariantClear(&schema); + PropVariantClear(&id); + } IWICEnumMetadataItem_Release(enumerator); } - hr = IWICMetadataReader_QueryInterface(reader, &IID_IWICMetadataBlockReader, (void**)&blockreader); - ok(hr == E_NOINTERFACE, "QueryInterface failed, hr=%x\n", hr); - - if (SUCCEEDED(hr)) - IWICMetadataBlockReader_Release(blockreader); + hr = IWICMetadataReader_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IWICMetadataReader_GetCount(reader, &count); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(count == 1, "Unexpected count %u.\n", count); + hr = IWICPersistStream_LoadEx(persist, NULL, NULL, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IWICMetadataReader_GetCount(reader, &count); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(count == 1, "Unexpected count %u.\n", count); + IWICPersistStream_Release(persist); IWICMetadataReader_Release(reader); + + hr = CoCreateInstance(&CLSID_WICUnknownMetadataWriter, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataWriter, (void **)&writer); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) return; + + check_interface(writer, &IID_IWICMetadataWriter, TRUE); + check_interface(writer, &IID_IWICMetadataReader, TRUE); + check_interface(writer, &IID_IPersist, TRUE); + check_interface(writer, &IID_IPersistStream, TRUE); + check_interface(writer, &IID_IWICPersistStream, TRUE); + check_interface(writer, &IID_IWICStreamProvider, TRUE); + + load_stream(writer, metadata_unknown, sizeof(metadata_unknown), 0); + load_stream(writer, metadata_unknown, sizeof(metadata_unknown), WICPersistOptionNoCacheStream); + + IWICMetadataWriter_Release(writer); } static void test_metadata_tEXt(void) { + IWICMetadataHandlerInfo *info; HRESULT hr; IWICMetadataReader *reader; IWICEnumMetadataItem *enumerator; PROPVARIANT schema, id, value; - ULONG items_returned, count; + IWICMetadataWriter *writer; + ULONG items_returned; + UINT count; GUID format; PropVariantInit(&schema); @@ -326,41 +690,53 @@ static void test_metadata_tEXt(void) hr = CoCreateInstance(&CLSID_WICPngTextMetadataReader, NULL, CLSCTX_INPROC_SERVER, &IID_IWICMetadataReader, (void**)&reader); - ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); + ok(hr == S_OK, "CoCreateInstance failed, hr=%lx\n", hr); if (FAILED(hr)) return; + check_interface(reader, &IID_IWICMetadataReader, TRUE); + check_interface(reader, &IID_IPersist, TRUE); + check_interface(reader, &IID_IPersistStream, TRUE); + check_interface(reader, &IID_IWICPersistStream, TRUE); + check_interface(reader, &IID_IWICStreamProvider, TRUE); + hr = IWICMetadataReader_GetCount(reader, NULL); - ok(hr == E_INVALIDARG, "GetCount failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetCount failed, hr=%lx\n", hr); hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount failed, hr=%x\n", hr); + ok(hr == S_OK, "GetCount failed, hr=%lx\n", hr); ok(count == 0, "unexpected count %i\n", count); - load_stream((IUnknown*)reader, metadata_tEXt, sizeof(metadata_tEXt), WICPersistOptionDefault); + load_stream(reader, metadata_tEXt, sizeof(metadata_tEXt), WICPersistOptionDefault); + + hr = IWICMetadataReader_GetMetadataHandlerInfo(reader, &info); + todo_wine + ok(hr == WINCODEC_ERR_COMPONENTNOTFOUND, "Unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + IWICMetadataHandlerInfo_Release(info); hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount failed, hr=%x\n", hr); + ok(hr == S_OK, "GetCount failed, hr=%lx\n", hr); ok(count == 1, "unexpected count %i\n", count); hr = IWICMetadataReader_GetEnumerator(reader, NULL); - ok(hr == E_INVALIDARG, "GetEnumerator failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetEnumerator failed, hr=%lx\n", hr); hr = IWICMetadataReader_GetEnumerator(reader, &enumerator); - ok(hr == S_OK, "GetEnumerator failed, hr=%x\n", hr); + ok(hr == S_OK, "GetEnumerator failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICEnumMetadataItem_Next(enumerator, 1, &schema, &id, &value, &items_returned); - ok(hr == S_OK, "Next failed, hr=%x\n", hr); - ok(items_returned == 1, "unexpected item count %i\n", items_returned); + ok(hr == S_OK, "Next failed, hr=%lx\n", hr); + ok(items_returned == 1, "unexpected item count %li\n", items_returned); if (hr == S_OK && items_returned == 1) { ok(schema.vt == VT_EMPTY, "unexpected vt: %i\n", schema.vt); ok(id.vt == VT_LPSTR, "unexpected vt: %i\n", id.vt); - ok(!strcmp(U(id).pszVal, "winetest"), "unexpected id: %s\n", U(id).pszVal); + ok(!strcmp(id.pszVal, "winetest"), "unexpected id: %s\n", id.pszVal); ok(value.vt == VT_LPSTR, "unexpected vt: %i\n", value.vt); - ok(!strcmp(U(value).pszVal, "value"), "unexpected value: %s\n", U(value).pszVal); + ok(!strcmp(value.pszVal, "value"), "unexpected value: %s\n", value.pszVal); PropVariantClear(&schema); PropVariantClear(&id); @@ -368,75 +744,94 @@ static void test_metadata_tEXt(void) } hr = IWICEnumMetadataItem_Next(enumerator, 1, &schema, &id, &value, &items_returned); - ok(hr == S_FALSE, "Next failed, hr=%x\n", hr); - ok(items_returned == 0, "unexpected item count %i\n", items_returned); + ok(hr == S_FALSE, "Next failed, hr=%lx\n", hr); + ok(items_returned == 0, "unexpected item count %li\n", items_returned); IWICEnumMetadataItem_Release(enumerator); } hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat failed, hr=%x\n", hr); + ok(hr == S_OK, "GetMetadataFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&format, &GUID_MetadataFormatChunktEXt), "unexpected format %s\n", wine_dbgstr_guid(&format)); hr = IWICMetadataReader_GetMetadataFormat(reader, NULL); - ok(hr == E_INVALIDARG, "GetMetadataFormat failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetMetadataFormat failed, hr=%lx\n", hr); id.vt = VT_LPSTR; - U(id).pszVal = CoTaskMemAlloc(strlen("winetest") + 1); - strcpy(U(id).pszVal, "winetest"); + id.pszVal = CoTaskMemAlloc(strlen("winetest") + 1); + strcpy(id.pszVal, "winetest"); hr = IWICMetadataReader_GetValue(reader, NULL, &id, NULL); - ok(hr == S_OK, "GetValue failed, hr=%x\n", hr); + ok(hr == S_OK, "GetValue failed, hr=%lx\n", hr); hr = IWICMetadataReader_GetValue(reader, &schema, NULL, &value); - ok(hr == E_INVALIDARG, "GetValue failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetValue failed, hr=%lx\n", hr); hr = IWICMetadataReader_GetValue(reader, &schema, &id, &value); - ok(hr == S_OK, "GetValue failed, hr=%x\n", hr); + ok(hr == S_OK, "GetValue failed, hr=%lx\n", hr); ok(value.vt == VT_LPSTR, "unexpected vt: %i\n", id.vt); - ok(!strcmp(U(value).pszVal, "value"), "unexpected value: %s\n", U(value).pszVal); + ok(!strcmp(value.pszVal, "value"), "unexpected value: %s\n", value.pszVal); PropVariantClear(&value); - strcpy(U(id).pszVal, "test"); + strcpy(id.pszVal, "test"); hr = IWICMetadataReader_GetValue(reader, &schema, &id, &value); - ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "GetValue failed, hr=%x\n", hr); + ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "GetValue failed, hr=%lx\n", hr); PropVariantClear(&id); hr = IWICMetadataReader_GetValueByIndex(reader, 0, NULL, NULL, NULL); - ok(hr == S_OK, "GetValueByIndex failed, hr=%x\n", hr); + ok(hr == S_OK, "GetValueByIndex failed, hr=%lx\n", hr); hr = IWICMetadataReader_GetValueByIndex(reader, 0, &schema, NULL, NULL); - ok(hr == S_OK, "GetValueByIndex failed, hr=%x\n", hr); + ok(hr == S_OK, "GetValueByIndex failed, hr=%lx\n", hr); ok(schema.vt == VT_EMPTY, "unexpected vt: %i\n", schema.vt); hr = IWICMetadataReader_GetValueByIndex(reader, 0, NULL, &id, NULL); - ok(hr == S_OK, "GetValueByIndex failed, hr=%x\n", hr); + ok(hr == S_OK, "GetValueByIndex failed, hr=%lx\n", hr); ok(id.vt == VT_LPSTR, "unexpected vt: %i\n", id.vt); - ok(!strcmp(U(id).pszVal, "winetest"), "unexpected id: %s\n", U(id).pszVal); + ok(!strcmp(id.pszVal, "winetest"), "unexpected id: %s\n", id.pszVal); PropVariantClear(&id); hr = IWICMetadataReader_GetValueByIndex(reader, 0, NULL, NULL, &value); - ok(hr == S_OK, "GetValueByIndex failed, hr=%x\n", hr); + ok(hr == S_OK, "GetValueByIndex failed, hr=%lx\n", hr); ok(value.vt == VT_LPSTR, "unexpected vt: %i\n", value.vt); - ok(!strcmp(U(value).pszVal, "value"), "unexpected value: %s\n", U(value).pszVal); + ok(!strcmp(value.pszVal, "value"), "unexpected value: %s\n", value.pszVal); PropVariantClear(&value); hr = IWICMetadataReader_GetValueByIndex(reader, 1, NULL, NULL, NULL); - ok(hr == E_INVALIDARG, "GetValueByIndex failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetValueByIndex failed, hr=%lx\n", hr); IWICMetadataReader_Release(reader); + + hr = CoCreateInstance(&CLSID_WICPngTextMetadataWriter, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataWriter, (void **)&writer); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) return; + + check_interface(writer, &IID_IWICMetadataWriter, TRUE); + check_interface(writer, &IID_IWICMetadataReader, TRUE); + check_interface(writer, &IID_IPersist, TRUE); + check_interface(writer, &IID_IPersistStream, TRUE); + check_interface(writer, &IID_IWICPersistStream, TRUE); + check_interface(writer, &IID_IWICStreamProvider, TRUE); + + load_stream(writer, metadata_tEXt, sizeof(metadata_tEXt), 0); + load_stream(writer, metadata_tEXt, sizeof(metadata_tEXt), WICPersistOptionNoCacheStream); + + IWICMetadataWriter_Release(writer); } static void test_metadata_gAMA(void) { + IWICMetadataHandlerInfo *info; HRESULT hr; IWICMetadataReader *reader; PROPVARIANT schema, id, value; - ULONG count; + IWICMetadataWriter *writer; + UINT count; GUID format; - static const WCHAR ImageGamma[] = {'I','m','a','g','e','G','a','m','m','a',0}; PropVariantInit(&schema); PropVariantInit(&id); @@ -444,34 +839,64 @@ static void test_metadata_gAMA(void) hr = CoCreateInstance(&CLSID_WICPngGamaMetadataReader, NULL, CLSCTX_INPROC_SERVER, &IID_IWICMetadataReader, (void**)&reader); - ok(hr == S_OK || broken(hr == REGDB_E_CLASSNOTREG) /*winxp*/, "CoCreateInstance failed, hr=%x\n", hr); + ok(hr == S_OK || broken(hr == REGDB_E_CLASSNOTREG) /*winxp*/, "CoCreateInstance failed, hr=%lx\n", hr); if (FAILED(hr)) return; - load_stream((IUnknown*)reader, metadata_gAMA, sizeof(metadata_gAMA), WICPersistOptionDefault); + check_interface(reader, &IID_IWICMetadataReader, TRUE); + check_interface(reader, &IID_IPersist, TRUE); + check_interface(reader, &IID_IPersistStream, TRUE); + check_interface(reader, &IID_IWICPersistStream, TRUE); + check_interface(reader, &IID_IWICStreamProvider, TRUE); + + load_stream(reader, metadata_gAMA, sizeof(metadata_gAMA), WICPersistOptionDefault); + + hr = IWICMetadataReader_GetMetadataHandlerInfo(reader, &info); + todo_wine + ok(hr == WINCODEC_ERR_COMPONENTNOTFOUND, "Unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + IWICMetadataHandlerInfo_Release(info); hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat failed, hr=%x\n", hr); + ok(hr == S_OK, "GetMetadataFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&format, &GUID_MetadataFormatChunkgAMA), "unexpected format %s\n", wine_dbgstr_guid(&format)); hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount failed, hr=%x\n", hr); + ok(hr == S_OK, "GetCount failed, hr=%lx\n", hr); ok(count == 1, "unexpected count %i\n", count); hr = IWICMetadataReader_GetValueByIndex(reader, 0, &schema, &id, &value); - ok(hr == S_OK, "GetValue failed, hr=%x\n", hr); + ok(hr == S_OK, "GetValue failed, hr=%lx\n", hr); ok(schema.vt == VT_EMPTY, "unexpected vt: %i\n", schema.vt); PropVariantClear(&schema); ok(id.vt == VT_LPWSTR, "unexpected vt: %i\n", id.vt); - ok(!lstrcmpW(U(id).pwszVal, ImageGamma), "unexpected value: %s\n", wine_dbgstr_w(U(id).pwszVal)); + ok(!lstrcmpW(id.pwszVal, L"ImageGamma"), "unexpected value: %s\n", wine_dbgstr_w(id.pwszVal)); PropVariantClear(&id); ok(value.vt == VT_UI4, "unexpected vt: %i\n", value.vt); - ok(U(value).ulVal == 33333, "unexpected value: %u\n", U(value).ulVal); + ok(value.ulVal == 33333, "unexpected value: %lu\n", value.ulVal); PropVariantClear(&value); IWICMetadataReader_Release(reader); + + hr = CoCreateInstance(&CLSID_WICPngGamaMetadataWriter, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataWriter, (void **)&writer); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) return; + + check_interface(writer, &IID_IWICMetadataWriter, TRUE); + check_interface(writer, &IID_IWICMetadataReader, TRUE); + check_interface(writer, &IID_IPersist, TRUE); + check_interface(writer, &IID_IPersistStream, TRUE); + check_interface(writer, &IID_IWICPersistStream, TRUE); + check_interface(writer, &IID_IWICStreamProvider, TRUE); + + load_stream(writer, metadata_gAMA, sizeof(metadata_gAMA), 0); + load_stream(writer, metadata_gAMA, sizeof(metadata_gAMA), WICPersistOptionNoCacheStream); + + IWICMetadataWriter_Release(writer); } static void test_metadata_cHRM(void) @@ -479,18 +904,20 @@ static void test_metadata_cHRM(void) HRESULT hr; IWICMetadataReader *reader; PROPVARIANT schema, id, value; - ULONG count; + IWICMetadataWriter *writer; + UINT count; GUID format; int i; - static const WCHAR expected_names[8][12] = { - {'W','h','i','t','e','P','o','i','n','t','X',0}, - {'W','h','i','t','e','P','o','i','n','t','Y',0}, - {'R','e','d','X',0}, - {'R','e','d','Y',0}, - {'G','r','e','e','n','X',0}, - {'G','r','e','e','n','Y',0}, - {'B','l','u','e','X',0}, - {'B','l','u','e','Y',0}, + static const WCHAR *expected_names[8] = + { + L"WhitePointX", + L"WhitePointY", + L"RedX", + L"RedY", + L"GreenX", + L"GreenY", + L"BlueX", + L"BlueY", }; static const ULONG expected_vals[8] = { 31270,32900, 64000,33000, 30000,60000, 15000,6000 @@ -502,95 +929,251 @@ static void test_metadata_cHRM(void) hr = CoCreateInstance(&CLSID_WICPngChrmMetadataReader, NULL, CLSCTX_INPROC_SERVER, &IID_IWICMetadataReader, (void**)&reader); - ok(hr == S_OK || broken(hr == REGDB_E_CLASSNOTREG) /*winxp*/, "CoCreateInstance failed, hr=%x\n", hr); + ok(hr == S_OK || broken(hr == REGDB_E_CLASSNOTREG) /*winxp*/, "CoCreateInstance failed, hr=%lx\n", hr); if (FAILED(hr)) return; - load_stream((IUnknown*)reader, metadata_cHRM, sizeof(metadata_cHRM), WICPersistOptionDefault); + check_interface(reader, &IID_IWICMetadataReader, TRUE); + check_interface(reader, &IID_IPersist, TRUE); + check_interface(reader, &IID_IPersistStream, TRUE); + check_interface(reader, &IID_IWICPersistStream, TRUE); + check_interface(reader, &IID_IWICStreamProvider, TRUE); + + load_stream(reader, metadata_cHRM, sizeof(metadata_cHRM), WICPersistOptionDefault); hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat failed, hr=%x\n", hr); + ok(hr == S_OK, "GetMetadataFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&format, &GUID_MetadataFormatChunkcHRM), "unexpected format %s\n", wine_dbgstr_guid(&format)); hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount failed, hr=%x\n", hr); + ok(hr == S_OK, "GetCount failed, hr=%lx\n", hr); ok(count == 8, "unexpected count %i\n", count); for (i=0; i<8; i++) { hr = IWICMetadataReader_GetValueByIndex(reader, i, &schema, &id, &value); - ok(hr == S_OK, "GetValue failed, hr=%x\n", hr); + ok(hr == S_OK, "GetValue failed, hr=%lx\n", hr); ok(schema.vt == VT_EMPTY, "unexpected vt: %i\n", schema.vt); PropVariantClear(&schema); ok(id.vt == VT_LPWSTR, "unexpected vt: %i\n", id.vt); - ok(!lstrcmpW(U(id).pwszVal, expected_names[i]), "got %s, expected %s\n", wine_dbgstr_w(U(id).pwszVal), wine_dbgstr_w(expected_names[i])); + ok(!lstrcmpW(id.pwszVal, expected_names[i]), "got %s, expected %s\n", wine_dbgstr_w(id.pwszVal), wine_dbgstr_w(expected_names[i])); PropVariantClear(&id); ok(value.vt == VT_UI4, "unexpected vt: %i\n", value.vt); - ok(U(value).ulVal == expected_vals[i], "got %u, expected %u\n", U(value).ulVal, expected_vals[i]); + ok(value.ulVal == expected_vals[i], "got %lu, expected %lu\n", value.ulVal, expected_vals[i]); PropVariantClear(&value); } IWICMetadataReader_Release(reader); -} -static inline USHORT ushort_bswap(USHORT s) -{ - return (s >> 8) | (s << 8); -} + hr = CoCreateInstance(&CLSID_WICPngChrmMetadataWriter, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataWriter, (void **)&writer); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) return; -static inline ULONG ulong_bswap(ULONG l) -{ - return ((ULONG)ushort_bswap((USHORT)l) << 16) | ushort_bswap((USHORT)(l >> 16)); -} + check_interface(writer, &IID_IWICMetadataWriter, TRUE); + check_interface(writer, &IID_IWICMetadataReader, TRUE); + check_interface(writer, &IID_IPersist, TRUE); + check_interface(writer, &IID_IPersistStream, TRUE); + check_interface(writer, &IID_IWICPersistStream, TRUE); + check_interface(writer, &IID_IWICStreamProvider, TRUE); -static inline ULONGLONG ulonglong_bswap(ULONGLONG ll) -{ - return ((ULONGLONG)ulong_bswap((ULONG)ll) << 32) | ulong_bswap((ULONG)(ll >> 32)); + load_stream(writer, metadata_cHRM, sizeof(metadata_cHRM), 0); + load_stream(writer, metadata_cHRM, sizeof(metadata_cHRM), WICPersistOptionNoCacheStream); + + IWICMetadataWriter_Release(writer); } -static void byte_swap_ifd_data(char *data) +static void test_metadata_hIST(void) { - USHORT number_of_entries, i; - struct IFD_entry *entry; - char *data_start = data; + HRESULT hr; + IWICMetadataReader *reader; + PROPVARIANT schema, id, value; + IWICMetadataWriter *writer; + UINT count, i; + GUID format; - number_of_entries = *(USHORT *)data; - *(USHORT *)data = ushort_bswap(*(USHORT *)data); - data += sizeof(USHORT); + PropVariantInit(&schema); + PropVariantInit(&id); + PropVariantInit(&value); - for (i = 0; i < number_of_entries; i++) - { - entry = (struct IFD_entry *)data; + hr = CoCreateInstance(&CLSID_WICPngHistMetadataReader, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataReader, (void**)&reader); + ok(hr == S_OK || broken(hr == REGDB_E_CLASSNOTREG) /*winxp*/, "CoCreateInstance failed, hr=%lx\n", hr); + if (FAILED(hr)) return; - switch (entry->type) - { - case IFD_BYTE: - case IFD_SBYTE: - case IFD_ASCII: - case IFD_UNDEFINED: - if (entry->count > 4) - entry->value = ulong_bswap(entry->value); - break; + check_interface(reader, &IID_IWICMetadataReader, TRUE); + check_interface(reader, &IID_IPersist, TRUE); + check_interface(reader, &IID_IPersistStream, TRUE); + check_interface(reader, &IID_IWICPersistStream, TRUE); + check_interface(reader, &IID_IWICStreamProvider, TRUE); - case IFD_SHORT: - case IFD_SSHORT: - if (entry->count > 2) - { - ULONG j, count = entry->count; - USHORT *us = (USHORT *)(data_start + entry->value); - if (!count) count = 1; - for (j = 0; j < count; j++) - us[j] = ushort_bswap(us[j]); + load_stream(reader, metadata_hIST, sizeof(metadata_hIST), WICPersistOptionDefault); - entry->value = ulong_bswap(entry->value); - } - else - { - ULONG j, count = entry->count; - USHORT *us = (USHORT *)&entry->value; - if (!count) count = 1; + hr = IWICMetadataReader_GetMetadataFormat(reader, &format); + ok(hr == S_OK, "GetMetadataFormat failed, hr=%lx\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatChunkhIST), "unexpected format %s\n", wine_dbgstr_guid(&format)); + + hr = IWICMetadataReader_GetCount(reader, &count); + ok(hr == S_OK, "GetCount failed, hr=%lx\n", hr); + ok(count == 1, "unexpected count %i\n", count); + + hr = IWICMetadataReader_GetValueByIndex(reader, 0, &schema, &id, &value); + ok(hr == S_OK, "GetValue failed, hr=%lx\n", hr); + + ok(schema.vt == VT_EMPTY, "unexpected vt: %i\n", schema.vt); + PropVariantClear(&schema); + + ok(id.vt == VT_LPWSTR, "unexpected vt: %i\n", id.vt); + ok(!lstrcmpW(id.pwszVal, L"Frequencies"), "unexpected value: %s\n", wine_dbgstr_w(id.pwszVal)); + PropVariantClear(&id); + + ok(value.vt == (VT_UI2|VT_VECTOR), "unexpected vt: %i\n", value.vt); + ok(20 == value.caui.cElems, "expected cElems %d, got %ld\n", 20, value.caub.cElems); + for (i = 0; i < value.caui.cElems; i++) + ok(i+1 == value.caui.pElems[i], "%u: expected value %u, got %u\n", i, i+1, value.caui.pElems[i]); + PropVariantClear(&value); + + IWICMetadataReader_Release(reader); + + hr = CoCreateInstance(&CLSID_WICPngHistMetadataWriter, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataWriter, (void **)&writer); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) return; + + check_interface(writer, &IID_IWICMetadataWriter, TRUE); + check_interface(writer, &IID_IWICMetadataReader, TRUE); + check_interface(writer, &IID_IPersist, TRUE); + check_interface(writer, &IID_IPersistStream, TRUE); + check_interface(writer, &IID_IWICPersistStream, TRUE); + check_interface(writer, &IID_IWICStreamProvider, TRUE); + + load_stream(writer, metadata_hIST, sizeof(metadata_hIST), 0); + load_stream(writer, metadata_hIST, sizeof(metadata_hIST), WICPersistOptionNoCacheStream); + + IWICMetadataWriter_Release(writer); +} + +static void test_metadata_tIME(void) +{ + HRESULT hr; + IWICMetadataReader *reader; + IWICMetadataWriter *writer; + UINT count; + GUID format; + static const struct test_data td[] = + { + { VT_UI2, 0, 0, { 2000 }, NULL, L"Year" }, + { VT_UI1, 0, 0, { 1 }, NULL, L"Month" }, + { VT_UI1, 0, 0, { 2 }, NULL, L"Day" }, + { VT_UI1, 0, 0, { 12 }, NULL, L"Hour" }, + { VT_UI1, 0, 0, { 34 }, NULL, L"Minute" }, + { VT_UI1, 0, 0, { 56 }, NULL, L"Second" }, + }; + + hr = CoCreateInstance(&CLSID_WICPngTimeMetadataReader, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataReader, (void**)&reader); + ok(hr == S_OK || broken(hr == REGDB_E_CLASSNOTREG) /*winxp*/, "CoCreateInstance failed, hr=%lx\n", hr); + if (FAILED(hr)) return; + + check_interface(reader, &IID_IWICMetadataReader, TRUE); + check_interface(reader, &IID_IPersist, TRUE); + check_interface(reader, &IID_IPersistStream, TRUE); + check_interface(reader, &IID_IWICPersistStream, TRUE); + check_interface(reader, &IID_IWICStreamProvider, TRUE); + + load_stream(reader, metadata_tIME, sizeof(metadata_tIME), WICPersistOptionDefault); + + hr = IWICMetadataReader_GetMetadataFormat(reader, &format); + ok(hr == S_OK, "GetMetadataFormat failed, hr=%lx\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatChunktIME), "unexpected format %s\n", wine_dbgstr_guid(&format)); + + hr = IWICMetadataReader_GetCount(reader, &count); + ok(hr == S_OK, "GetCount failed, hr=%lx\n", hr); + ok(count == ARRAY_SIZE(td), "unexpected count %i\n", count); + + compare_metadata(reader, td, count); + + IWICMetadataReader_Release(reader); + + hr = CoCreateInstance(&CLSID_WICPngTimeMetadataWriter, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataWriter, (void **)&writer); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) return; + + check_interface(writer, &IID_IWICMetadataWriter, TRUE); + check_interface(writer, &IID_IWICMetadataReader, TRUE); + check_interface(writer, &IID_IPersist, TRUE); + check_interface(writer, &IID_IPersistStream, TRUE); + check_interface(writer, &IID_IWICPersistStream, TRUE); + check_interface(writer, &IID_IWICStreamProvider, TRUE); + + load_stream(writer, metadata_tIME, sizeof(metadata_tIME), 0); + load_stream(writer, metadata_tIME, sizeof(metadata_tIME), WICPersistOptionNoCacheStream); + + IWICMetadataWriter_Release(writer); +} + +static inline USHORT ushort_bswap(USHORT s) +{ + return (s >> 8) | (s << 8); +} + +static inline ULONG ulong_bswap(ULONG l) +{ + return ((ULONG)ushort_bswap((USHORT)l) << 16) | ushort_bswap((USHORT)(l >> 16)); +} + +static inline ULONGLONG ulonglong_bswap(ULONGLONG ll) +{ + return ((ULONGLONG)ulong_bswap((ULONG)ll) << 32) | ulong_bswap((ULONG)(ll >> 32)); +} + +static void byte_swap_ifd_data(char *data) +{ + USHORT number_of_entries, i; + struct IFD_entry *entry; + char *data_start = data; + + number_of_entries = *(USHORT *)data; + *(USHORT *)data = ushort_bswap(*(USHORT *)data); + data += sizeof(USHORT); + + for (i = 0; i < number_of_entries; i++) + { + entry = (struct IFD_entry *)data; + + switch (entry->type) + { + case IFD_BYTE: + case IFD_SBYTE: + case IFD_ASCII: + case IFD_UNDEFINED: + if (entry->count > 4) + entry->value = ulong_bswap(entry->value); + break; + + case IFD_SHORT: + case IFD_SSHORT: + if (entry->count > 2) + { + ULONG j, count = entry->count; + USHORT *us = (USHORT *)(data_start + entry->value); + if (!count) count = 1; + for (j = 0; j < count; j++) + us[j] = ushort_bswap(us[j]); + + entry->value = ulong_bswap(entry->value); + } + else + { + ULONG j, count = entry->count; + USHORT *us = (USHORT *)&entry->value; + if (!count) count = 1; for (j = 0; j < count; j++) us[j] = ushort_bswap(us[j]); } @@ -643,119 +1226,7 @@ static void byte_swap_ifd_data(char *data) } } -struct test_data -{ - ULONG type, id; - int count; /* if VT_VECTOR */ - LONGLONG value[13]; - const char *string; - const WCHAR id_string[32]; -}; - -static void compare_metadata(IWICMetadataReader *reader, const struct test_data *td, ULONG count) -{ - HRESULT hr; - IWICEnumMetadataItem *enumerator; - PROPVARIANT schema, id, value; - ULONG items_returned, i; - - hr = IWICMetadataReader_GetEnumerator(reader, NULL); - ok(hr == E_INVALIDARG, "GetEnumerator error %#x\n", hr); - - hr = IWICMetadataReader_GetEnumerator(reader, &enumerator); - ok(hr == S_OK, "GetEnumerator error %#x\n", hr); - - PropVariantInit(&schema); - PropVariantInit(&id); - PropVariantInit(&value); - - for (i = 0; i < count; i++) - { - hr = IWICEnumMetadataItem_Next(enumerator, 1, &schema, &id, &value, &items_returned); - ok(hr == S_OK, "Next error %#x\n", hr); - ok(items_returned == 1, "unexpected item count %u\n", items_returned); - - ok(schema.vt == VT_EMPTY, "%u: unexpected vt: %u\n", i, schema.vt); - ok(id.vt == VT_UI2 || id.vt == VT_LPWSTR || id.vt == VT_EMPTY, "%u: unexpected vt: %u\n", i, id.vt); - if (id.vt == VT_UI2) - ok(U(id).uiVal == td[i].id, "%u: expected id %#x, got %#x\n", i, td[i].id, U(id).uiVal); - else if (id.vt == VT_LPWSTR) - ok(!lstrcmpW(td[i].id_string, U(id).pwszVal), - "%u: expected %s, got %s\n", i, wine_dbgstr_w(td[i].id_string), wine_dbgstr_w(U(id).pwszVal)); - - ok(value.vt == td[i].type, "%u: expected vt %#x, got %#x\n", i, td[i].type, value.vt); - if (value.vt & VT_VECTOR) - { - ULONG j; - switch (value.vt & ~VT_VECTOR) - { - case VT_I1: - case VT_UI1: - ok(td[i].count == U(value).caub.cElems, "%u: expected cElems %d, got %d\n", i, td[i].count, U(value).caub.cElems); - for (j = 0; j < U(value).caub.cElems; j++) - ok(td[i].value[j] == U(value).caub.pElems[j], "%u: expected value[%d] %#x/%#x, got %#x\n", i, j, (ULONG)td[i].value[j], (ULONG)(td[i].value[j] >> 32), U(value).caub.pElems[j]); - break; - case VT_I2: - case VT_UI2: - ok(td[i].count == U(value).caui.cElems, "%u: expected cElems %d, got %d\n", i, td[i].count, U(value).caui.cElems); - for (j = 0; j < U(value).caui.cElems; j++) - ok(td[i].value[j] == U(value).caui.pElems[j], "%u: expected value[%d] %#x/%#x, got %#x\n", i, j, (ULONG)td[i].value[j], (ULONG)(td[i].value[j] >> 32), U(value).caui.pElems[j]); - break; - case VT_I4: - case VT_UI4: - case VT_R4: - ok(td[i].count == U(value).caul.cElems, "%u: expected cElems %d, got %d\n", i, td[i].count, U(value).caul.cElems); - for (j = 0; j < U(value).caul.cElems; j++) - ok(td[i].value[j] == U(value).caul.pElems[j], "%u: expected value[%d] %#x/%#x, got %#x\n", i, j, (ULONG)td[i].value[j], (ULONG)(td[i].value[j] >> 32), U(value).caul.pElems[j]); - break; - case VT_I8: - case VT_UI8: - case VT_R8: - ok(td[i].count == U(value).cauh.cElems, "%u: expected cElems %d, got %d\n", i, td[i].count, U(value).cauh.cElems); - for (j = 0; j < U(value).cauh.cElems; j++) - ok(td[i].value[j] == U(value).cauh.pElems[j].QuadPart, "%u: expected value[%d] %08x/%08x, got %08x/%08x\n", i, j, (ULONG)td[i].value[j], (ULONG)(td[i].value[j] >> 32), U(value).cauh.pElems[j].u.LowPart, U(value).cauh.pElems[j].u.HighPart); - break; - case VT_LPSTR: - ok(td[i].count == U(value).calpstr.cElems, "%u: expected cElems %d, got %d\n", i, td[i].count, U(value).caub.cElems); - for (j = 0; j < U(value).calpstr.cElems; j++) - trace("%u: %s\n", j, U(value).calpstr.pElems[j]); - /* fall through to not handled message */ - default: - ok(0, "%u: array of type %d is not handled\n", i, value.vt & ~VT_VECTOR); - break; - } - } - else if (value.vt == VT_LPSTR) - { - ok(td[i].count == strlen(U(value).pszVal) || - broken(td[i].count == strlen(U(value).pszVal) + 1), /* before Win7 */ - "%u: expected count %d, got %d\n", i, td[i].count, lstrlenA(U(value).pszVal)); - if (td[i].count == strlen(U(value).pszVal)) - ok(!strcmp(td[i].string, U(value).pszVal), - "%u: expected %s, got %s\n", i, td[i].string, U(value).pszVal); - } - else if (value.vt == VT_BLOB) - { - ok(td[i].count == U(value).blob.cbSize, "%u: expected count %d, got %d\n", i, td[i].count, U(value).blob.cbSize); - ok(!memcmp(td[i].string, U(value).blob.pBlobData, td[i].count), "%u: expected %s, got %s\n", i, td[i].string, U(value).blob.pBlobData); - } - else - ok(U(value).uhVal.QuadPart == td[i].value[0], "%u: expected value %#x/%#x got %#x/%#x\n", - i, (UINT)td[i].value[0], (UINT)(td[i].value[0] >> 32), U(value).uhVal.u.LowPart, U(value).uhVal.u.HighPart); - - PropVariantClear(&schema); - PropVariantClear(&id); - PropVariantClear(&value); - } - - hr = IWICEnumMetadataItem_Next(enumerator, 1, &schema, &id, &value, &items_returned); - ok(hr == S_FALSE, "Next should fail\n"); - ok(items_returned == 0, "unexpected item count %u\n", items_returned); - - IWICEnumMetadataItem_Release(enumerator); -} - -static void test_metadata_IFD(void) +static void test_ifd_content(IWICMetadataReader *reader) { static const struct test_data td[28] = { @@ -791,171 +1262,277 @@ static void test_metadata_IFD(void) ((LONGLONG)0x50607080 << 32) | 0x10203040, ((LONGLONG)0x55667788 << 32) | 0x11223344 } }, }; - HRESULT hr; - IWICMetadataReader *reader; - IWICMetadataBlockReader *blockreader; PROPVARIANT schema, id, value; - ULONG count; - GUID format; char *IFD_data_swapped; -#ifdef WORDS_BIGENDIAN - DWORD persist_options = WICPersistOptionBigEndian; -#else - DWORD persist_options = WICPersistOptionLittleEndian; -#endif - - hr = CoCreateInstance(&CLSID_WICIfdMetadataReader, NULL, CLSCTX_INPROC_SERVER, - &IID_IWICMetadataReader, (void**)&reader); - ok(hr == S_OK, "CoCreateInstance error %#x\n", hr); - - hr = IWICMetadataReader_GetCount(reader, NULL); - ok(hr == E_INVALIDARG, "GetCount error %#x\n", hr); + UINT count; + HRESULT hr; hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); + ok(hr == S_OK, "GetCount error %#lx\n", hr); ok(count == 0, "unexpected count %u\n", count); - load_stream((IUnknown*)reader, (const char *)&IFD_data, sizeof(IFD_data), persist_options); + load_stream(reader, (const char *)&IFD_data, sizeof(IFD_data), WICPersistOptionLittleEndian); hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); + ok(hr == S_OK, "GetCount error %#lx\n", hr); ok(count == ARRAY_SIZE(td), "unexpected count %u\n", count); compare_metadata(reader, td, count); - /* test IFD data with different endianness */ - if (persist_options == WICPersistOptionLittleEndian) - persist_options = WICPersistOptionBigEndian; - else - persist_options = WICPersistOptionLittleEndian; - + /* Test big-endian IFD data */ IFD_data_swapped = HeapAlloc(GetProcessHeap(), 0, sizeof(IFD_data)); memcpy(IFD_data_swapped, &IFD_data, sizeof(IFD_data)); byte_swap_ifd_data(IFD_data_swapped); - load_stream((IUnknown *)reader, IFD_data_swapped, sizeof(IFD_data), persist_options); + load_stream(reader, IFD_data_swapped, sizeof(IFD_data), WICPersistOptionBigEndian); + todo_wine + check_persist_options(reader, WICPersistOptionBigEndian); hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); + ok(hr == S_OK, "GetCount error %#lx\n", hr); ok(count == ARRAY_SIZE(td), "unexpected count %u\n", count); compare_metadata(reader, td, count); HeapFree(GetProcessHeap(), 0, IFD_data_swapped); - hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat error %#x\n", hr); - ok(IsEqualGUID(&format, &GUID_MetadataFormatIfd), "unexpected format %s\n", wine_dbgstr_guid(&format)); - - hr = IWICMetadataReader_GetMetadataFormat(reader, NULL); - ok(hr == E_INVALIDARG, "GetMetadataFormat should fail\n"); - hr = IWICMetadataReader_GetValueByIndex(reader, 0, NULL, NULL, NULL); - ok(hr == S_OK, "GetValueByIndex error %#x\n", hr); + ok(hr == S_OK, "GetValueByIndex error %#lx\n", hr); PropVariantInit(&schema); PropVariantInit(&id); PropVariantInit(&value); hr = IWICMetadataReader_GetValueByIndex(reader, count - 1, NULL, NULL, NULL); - ok(hr == S_OK, "GetValueByIndex error %#x\n", hr); + ok(hr == S_OK, "GetValueByIndex error %#lx\n", hr); hr = IWICMetadataReader_GetValueByIndex(reader, 0, &schema, NULL, NULL); - ok(hr == S_OK, "GetValueByIndex error %#x\n", hr); + ok(hr == S_OK, "GetValueByIndex error %#lx\n", hr); ok(schema.vt == VT_EMPTY, "unexpected vt: %u\n", schema.vt); hr = IWICMetadataReader_GetValueByIndex(reader, count - 1, &schema, NULL, NULL); - ok(hr == S_OK, "GetValueByIndex error %#x\n", hr); + ok(hr == S_OK, "GetValueByIndex error %#lx\n", hr); ok(schema.vt == VT_EMPTY, "unexpected vt: %u\n", schema.vt); hr = IWICMetadataReader_GetValueByIndex(reader, 0, NULL, &id, NULL); - ok(hr == S_OK, "GetValueByIndex error %#x\n", hr); + ok(hr == S_OK, "GetValueByIndex error %#lx\n", hr); ok(id.vt == VT_UI2, "unexpected vt: %u\n", id.vt); - ok(U(id).uiVal == 0xfe, "unexpected id: %#x\n", U(id).uiVal); + ok(id.uiVal == 0xfe, "unexpected id: %#x\n", id.uiVal); PropVariantClear(&id); hr = IWICMetadataReader_GetValueByIndex(reader, 0, NULL, NULL, &value); - ok(hr == S_OK, "GetValueByIndex error %#x\n", hr); + ok(hr == S_OK, "GetValueByIndex error %#lx\n", hr); ok(value.vt == VT_UI2, "unexpected vt: %u\n", value.vt); - ok(U(value).uiVal == 1, "unexpected id: %#x\n", U(value).uiVal); + ok(value.uiVal == 1, "unexpected id: %#x\n", value.uiVal); PropVariantClear(&value); hr = IWICMetadataReader_GetValueByIndex(reader, count, &schema, NULL, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); PropVariantInit(&schema); PropVariantInit(&id); PropVariantInit(&value); hr = IWICMetadataReader_GetValue(reader, &schema, &id, &value); - ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "expected WINCODEC_ERR_PROPERTYNOTFOUND, got %#x\n", hr); + ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "expected WINCODEC_ERR_PROPERTYNOTFOUND, got %#lx\n", hr); hr = IWICMetadataReader_GetValue(reader, NULL, &id, NULL); - ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "expected WINCODEC_ERR_PROPERTYNOTFOUND, got %#x\n", hr); + ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "expected WINCODEC_ERR_PROPERTYNOTFOUND, got %#lx\n", hr); hr = IWICMetadataReader_GetValue(reader, &schema, NULL, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICMetadataReader_GetValue(reader, &schema, &id, NULL); - ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "expected WINCODEC_ERR_PROPERTYNOTFOUND, got %#x\n", hr); + ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "expected WINCODEC_ERR_PROPERTYNOTFOUND, got %#lx\n", hr); hr = IWICMetadataReader_GetValue(reader, &schema, NULL, &value); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); id.vt = VT_UI2; - U(id).uiVal = 0xf00e; + id.uiVal = 0xf00e; hr = IWICMetadataReader_GetValue(reader, NULL, &id, NULL); - ok(hr == S_OK, "GetValue error %#x\n", hr); + ok(hr == S_OK, "GetValue error %#lx\n", hr); /* schema is ignored by Ifd metadata reader */ schema.vt = VT_UI4; - U(schema).ulVal = 0xdeadbeef; + schema.ulVal = 0xdeadbeef; hr = IWICMetadataReader_GetValue(reader, &schema, &id, &value); - ok(hr == S_OK, "GetValue error %#x\n", hr); + ok(hr == S_OK, "GetValue error %#lx\n", hr); ok(value.vt == VT_LPSTR, "unexpected vt: %i\n", id.vt); - ok(!strcmp(U(value).pszVal, "Hello World!"), "unexpected value: %s\n", U(value).pszVal); + ok(!strcmp(value.pszVal, "Hello World!"), "unexpected value: %s\n", value.pszVal); PropVariantClear(&value); hr = IWICMetadataReader_GetValue(reader, NULL, &id, &value); - ok(hr == S_OK, "GetValue error %#x\n", hr); + ok(hr == S_OK, "GetValue error %#lx\n", hr); ok(value.vt == VT_LPSTR, "unexpected vt: %i\n", id.vt); - ok(!strcmp(U(value).pszVal, "Hello World!"), "unexpected value: %s\n", U(value).pszVal); + ok(!strcmp(value.pszVal, "Hello World!"), "unexpected value: %s\n", value.pszVal); PropVariantClear(&value); +} - hr = IWICMetadataReader_QueryInterface(reader, &IID_IWICMetadataBlockReader, (void**)&blockreader); - ok(hr == E_NOINTERFACE, "QueryInterface failed, hr=%x\n", hr); +static void test_metadata_Ifd(void) +{ + IWICMetadataReader *reader; + IWICMetadataWriter *writer; + GUID format; + UINT count; + HRESULT hr; - if (SUCCEEDED(hr)) - IWICMetadataBlockReader_Release(blockreader); + hr = CoCreateInstance(&CLSID_WICIfdMetadataReader, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataReader, (void**)&reader); + ok(hr == S_OK, "CoCreateInstance error %#lx\n", hr); + + check_interface(reader, &IID_IWICMetadataReader, TRUE); + check_interface(reader, &IID_IPersist, TRUE); + check_interface(reader, &IID_IPersistStream, TRUE); + check_interface(reader, &IID_IWICPersistStream, TRUE); + check_interface(reader, &IID_IWICStreamProvider, TRUE); + check_interface(reader, &IID_IWICMetadataBlockReader, FALSE); + + hr = IWICMetadataReader_GetCount(reader, NULL); + ok(hr == E_INVALIDARG, "GetCount error %#lx\n", hr); + + hr = IWICMetadataReader_GetCount(reader, &count); + ok(hr == S_OK, "GetCount error %#lx\n", hr); + ok(count == 0, "unexpected count %u\n", count); + + test_ifd_content(reader); + + test_reader_container_format(reader, &GUID_ContainerFormatTiff); + + hr = IWICMetadataReader_GetMetadataFormat(reader, &format); + ok(hr == S_OK, "GetMetadataFormat error %#lx\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatIfd), "unexpected format %s\n", wine_dbgstr_guid(&format)); + + hr = IWICMetadataReader_GetMetadataFormat(reader, NULL); + ok(hr == E_INVALIDARG, "GetMetadataFormat should fail\n"); IWICMetadataReader_Release(reader); + + hr = CoCreateInstance(&CLSID_WICIfdMetadataWriter, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataWriter, (void **)&writer); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) return; + + check_interface(writer, &IID_IWICMetadataWriter, TRUE); + check_interface(writer, &IID_IWICMetadataReader, TRUE); + check_interface(writer, &IID_IPersist, TRUE); + check_interface(writer, &IID_IPersistStream, TRUE); + check_interface(writer, &IID_IWICPersistStream, TRUE); + check_interface(writer, &IID_IWICStreamProvider, TRUE); + + load_stream(writer, (const char *)&IFD_data, sizeof(IFD_data), 0); + load_stream(writer, (const char *)&IFD_data, sizeof(IFD_data), WICPersistOptionNoCacheStream); + + IWICMetadataWriter_Release(writer); } static void test_metadata_Exif(void) { HRESULT hr; IWICMetadataReader *reader; - IWICMetadataBlockReader *blockreader; + IWICMetadataWriter *writer; UINT count=0; + GUID format; hr = CoCreateInstance(&CLSID_WICExifMetadataReader, NULL, CLSCTX_INPROC_SERVER, &IID_IWICMetadataReader, (void**)&reader); - todo_wine ok(hr == S_OK, "CoCreateInstance error %#x\n", hr); + todo_wine ok(hr == S_OK, "CoCreateInstance error %#lx\n", hr); if (FAILED(hr)) return; + check_interface(reader, &IID_IWICMetadataReader, TRUE); + check_interface(reader, &IID_IPersist, TRUE); + check_interface(reader, &IID_IPersistStream, TRUE); + check_interface(reader, &IID_IWICPersistStream, TRUE); + check_interface(reader, &IID_IWICStreamProvider, TRUE); + check_interface(reader, &IID_IWICMetadataBlockReader, FALSE); + hr = IWICMetadataReader_GetCount(reader, NULL); - ok(hr == E_INVALIDARG, "GetCount error %#x\n", hr); + ok(hr == E_INVALIDARG, "GetCount error %#lx\n", hr); hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); + ok(hr == S_OK, "GetCount error %#lx\n", hr); ok(count == 0, "unexpected count %u\n", count); - hr = IWICMetadataReader_QueryInterface(reader, &IID_IWICMetadataBlockReader, (void**)&blockreader); - ok(hr == E_NOINTERFACE, "QueryInterface failed, hr=%x\n", hr); + hr = IWICMetadataReader_GetMetadataFormat(reader, &format); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatExif), "Unexpected format %s.\n", wine_dbgstr_guid(&format)); - if (SUCCEEDED(hr)) - IWICMetadataBlockReader_Release(blockreader); + test_reader_container_format(reader, &GUID_MetadataFormatIfd); + test_ifd_content(reader); + + IWICMetadataReader_Release(reader); + + hr = CoCreateInstance(&CLSID_WICExifMetadataWriter, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataWriter, (void **)&writer); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) return; + + check_interface(writer, &IID_IWICMetadataWriter, TRUE); + check_interface(writer, &IID_IWICMetadataReader, TRUE); + check_interface(writer, &IID_IPersist, TRUE); + check_interface(writer, &IID_IPersistStream, TRUE); + check_interface(writer, &IID_IWICPersistStream, TRUE); + todo_wine + check_interface(writer, &IID_IWICStreamProvider, TRUE); + + load_stream(writer, (const char *)&IFD_data, sizeof(IFD_data), 0); + load_stream(writer, (const char *)&IFD_data, sizeof(IFD_data), WICPersistOptionNoCacheStream); + + IWICMetadataWriter_Release(writer); +} + +static void test_metadata_Gps(void) +{ + IWICMetadataReader *reader; + IWICMetadataWriter *writer; + UINT count=0; + GUID format; + HRESULT hr; + + hr = CoCreateInstance(&CLSID_WICGpsMetadataReader, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataReader, (void **)&reader); + todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) return; + + check_interface(reader, &IID_IWICMetadataReader, TRUE); + check_interface(reader, &IID_IPersist, TRUE); + check_interface(reader, &IID_IPersistStream, TRUE); + check_interface(reader, &IID_IWICPersistStream, TRUE); + check_interface(reader, &IID_IWICStreamProvider, TRUE); + check_interface(reader, &IID_IWICMetadataBlockReader, FALSE); + + hr = IWICMetadataReader_GetCount(reader, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + + hr = IWICMetadataReader_GetCount(reader, &count); + ok(hr == S_OK, "GetCount error %#lx\n", hr); + ok(!count, "Unexpected count %u.\n", count); + + hr = IWICMetadataReader_GetMetadataFormat(reader, &format); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatGps), "Unexpected format %s.\n", wine_dbgstr_guid(&format)); + + test_reader_container_format(reader, &GUID_MetadataFormatIfd); + test_ifd_content(reader); IWICMetadataReader_Release(reader); + + hr = CoCreateInstance(&CLSID_WICGpsMetadataWriter, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataWriter, (void **)&writer); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) return; + + check_interface(writer, &IID_IWICMetadataWriter, TRUE); + check_interface(writer, &IID_IWICMetadataReader, TRUE); + check_interface(writer, &IID_IPersist, TRUE); + check_interface(writer, &IID_IPersistStream, TRUE); + check_interface(writer, &IID_IWICPersistStream, TRUE); + check_interface(writer, &IID_IWICStreamProvider, TRUE); + + load_stream(writer, (const char *)&IFD_data, sizeof(IFD_data), 0); + load_stream(writer, (const char *)&IFD_data, sizeof(IFD_data), WICPersistOptionNoCacheStream); + + IWICMetadataWriter_Release(writer); } -static void test_create_reader(void) +static void test_create_reader_from_container(void) { HRESULT hr; IWICComponentFactory *factory; @@ -966,38 +1543,44 @@ static void test_create_reader(void) hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICComponentFactory, (void**)&factory); - ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); + ok(hr == S_OK, "CoCreateInstance failed, hr=%lx\n", hr); stream = create_stream(metadata_tEXt, sizeof(metadata_tEXt)); hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory, NULL, NULL, WICPersistOptionDefault, stream, &reader); - ok(hr == E_INVALIDARG, "CreateMetadataReaderFromContainer failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "CreateMetadataReaderFromContainer failed, hr=%lx\n", hr); hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory, &GUID_ContainerFormatPng, NULL, WICPersistOptionDefault, NULL, &reader); - ok(hr == E_INVALIDARG, "CreateMetadataReaderFromContainer failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "CreateMetadataReaderFromContainer failed, hr=%lx\n", hr); hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory, &GUID_ContainerFormatPng, NULL, WICPersistOptionDefault, stream, NULL); - ok(hr == E_INVALIDARG, "CreateMetadataReaderFromContainer failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "CreateMetadataReaderFromContainer failed, hr=%lx\n", hr); hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory, &GUID_ContainerFormatPng, NULL, WICPersistOptionDefault, stream, &reader); - ok(hr == S_OK, "CreateMetadataReaderFromContainer failed, hr=%x\n", hr); + ok(hr == S_OK, "CreateMetadataReaderFromContainer failed, hr=%lx\n", hr); + + check_interface(reader, &IID_IWICMetadataReader, TRUE); + check_interface(reader, &IID_IPersist, TRUE); + check_interface(reader, &IID_IPersistStream, TRUE); + check_interface(reader, &IID_IWICPersistStream, TRUE); + check_interface(reader, &IID_IWICStreamProvider, TRUE); if (SUCCEEDED(hr)) { hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount failed, hr=%x\n", hr); + ok(hr == S_OK, "GetCount failed, hr=%lx\n", hr); ok(count == 1, "unexpected count %i\n", count); hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat failed, hr=%x\n", hr); + ok(hr == S_OK, "GetMetadataFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&format, &GUID_MetadataFormatChunktEXt), "unexpected format %s\n", wine_dbgstr_guid(&format)); IWICMetadataReader_Release(reader); @@ -1006,21 +1589,187 @@ static void test_create_reader(void) hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory, &GUID_ContainerFormatWmp, NULL, WICPersistOptionDefault, stream, &reader); - ok(hr == S_OK, "CreateMetadataReaderFromContainer failed, hr=%x\n", hr); + ok(hr == S_OK, "CreateMetadataReaderFromContainer failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount failed, hr=%x\n", hr); + ok(hr == S_OK, "GetCount failed, hr=%lx\n", hr); ok(count == 1, "unexpected count %i\n", count); hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat failed, hr=%x\n", hr); + ok(hr == S_OK, "GetMetadataFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&format, &GUID_MetadataFormatUnknown), "unexpected format %s\n", wine_dbgstr_guid(&format)); IWICMetadataReader_Release(reader); } + hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory, &GUID_ContainerFormatWmp, + NULL, WICMetadataCreationFailUnknown, stream, &reader); + ok(hr == WINCODEC_ERR_COMPONENTNOTFOUND, "Unexpected hr %#lx.\n", hr); + + IStream_Release(stream); + + IWICComponentFactory_Release(factory); +} + +static void test_CreateMetadataReader(void) +{ + IWICPersistStream *persist_stream; + IWICComponentFactory *factory; + IWICMetadataReader *reader; + IStream *stream, *stream2; + LARGE_INTEGER pos; + UINT count = 0; + GUID format; + HRESULT hr; + + hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICComponentFactory, (void **)&factory); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + stream = create_stream(metadata_tEXt, sizeof(metadata_tEXt)); + + hr = IWICComponentFactory_CreateMetadataReader(factory, NULL, NULL, 0, stream, &reader); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + + memset(&format, 0xcc, sizeof(format)); + hr = IWICComponentFactory_CreateMetadataReader(factory, &format, NULL, 0, stream, &reader); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = get_persist_stream(reader, &stream2); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + { + ok(stream == stream2, "Unexpected stream.\n"); + IStream_Release(stream2); + } + + hr = IWICMetadataReader_GetMetadataFormat(reader, &format); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatUnknown), "Unexpected format %s.\n", wine_dbgstr_guid(&format)); + IWICMetadataReader_Release(reader); + + memset(&format, 0xcc, sizeof(format)); + hr = IWICComponentFactory_CreateMetadataReader(factory, &format, NULL, WICMetadataCreationFailUnknown, stream, &reader); + ok(hr == WINCODEC_ERR_COMPONENTNOTFOUND, "Unexpected hr %#lx.\n", hr); + + hr = IWICComponentFactory_CreateMetadataReader(factory, &GUID_MetadataFormatChunktEXt, + NULL, 0, NULL, &reader); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = get_persist_stream(reader, &stream2); + todo_wine + ok(hr == WINCODEC_ERR_STREAMNOTAVAILABLE, "Unexpected hr %#lx.\n", hr); + + hr = IWICMetadataReader_GetMetadataFormat(reader, &format); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatChunktEXt), "Unexpected format %s.\n", wine_dbgstr_guid(&format)); + IWICMetadataReader_Release(reader); + + pos.QuadPart = 0; + hr = IStream_Seek(stream, pos, STREAM_SEEK_SET, NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IWICComponentFactory_CreateMetadataReader(factory, &GUID_MetadataFormatChunktEXt, NULL, 0, + stream, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + + hr = IStream_Seek(stream, pos, STREAM_SEEK_SET, NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IWICComponentFactory_CreateMetadataReader(factory, &GUID_ContainerFormatPng, NULL, 0, stream, &reader); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IWICMetadataReader_GetMetadataFormat(reader, &format); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatUnknown), "Unexpected format %s.\n", wine_dbgstr_guid(&format)); + IWICMetadataReader_Release(reader); + + hr = IStream_Seek(stream, pos, STREAM_SEEK_SET, NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IWICComponentFactory_CreateMetadataReader(factory, &GUID_MetadataFormatChunktEXt, NULL, 0, stream, &reader); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + check_interface(reader, &IID_IWICMetadataReader, TRUE); + check_interface(reader, &IID_IWICMetadataWriter, FALSE); + check_interface(reader, &IID_IPersist, TRUE); + check_interface(reader, &IID_IPersistStream, TRUE); + check_interface(reader, &IID_IWICPersistStream, TRUE); + check_interface(reader, &IID_IWICStreamProvider, TRUE); + + hr = IWICMetadataReader_GetCount(reader, &count); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(count == 1, "Unexpected count %u.\n", count); + + hr = IWICMetadataReader_GetMetadataFormat(reader, &format); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatChunktEXt), "Unexpected format %s.\n", wine_dbgstr_guid(&format)); + + IWICMetadataReader_Release(reader); + + /* Invalid vendor. */ + hr = IStream_Seek(stream, pos, STREAM_SEEK_SET, NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IWICComponentFactory_CreateMetadataReader(factory, &GUID_MetadataFormatChunktEXt, &IID_IUnknown, 0, stream, &reader); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IWICMetadataReader_GetMetadataFormat(reader, &format); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatChunktEXt), "Unexpected format %s.\n", wine_dbgstr_guid(&format)); + IWICMetadataReader_Release(reader); + + /* Mismatching metadata format. */ + hr = IStream_Seek(stream, pos, STREAM_SEEK_SET, NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IWICComponentFactory_CreateMetadataReader(factory, &GUID_MetadataFormatApp1, NULL, 0, stream, &reader); + todo_wine + ok(hr == WINCODEC_ERR_BADMETADATAHEADER, "Unexpected hr %#lx.\n", hr); + + /* With and without caching */ + hr = IStream_Seek(stream, pos, STREAM_SEEK_SET, NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IWICComponentFactory_CreateMetadataReader(factory, &GUID_MetadataFormatChunktEXt, NULL, + WICPersistOptionNoCacheStream, stream, &reader); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IWICMetadataReader_GetCount(reader, &count); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(count == 1, "Unexpected count %u.\n", count); + + hr = get_persist_stream(reader, &stream2); + todo_wine + ok(hr == WINCODEC_ERR_STREAMNOTAVAILABLE, "Unexpected hr %#lx.\n", hr); + + hr = IWICMetadataReader_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist_stream); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IWICPersistStream_LoadEx(persist_stream, stream, NULL, 0); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = get_persist_stream(reader, &stream2); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + { + ok(stream == stream2, "Unexpected stream.\n"); + IStream_Release(stream2); + } + + /* Going from caching to no caching. */ + hr = IStream_Seek(stream, pos, STREAM_SEEK_SET, NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IWICPersistStream_LoadEx(persist_stream, stream, NULL, WICPersistOptionNoCacheStream); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = get_persist_stream(reader, &stream2); + todo_wine + ok(hr == WINCODEC_ERR_STREAMNOTAVAILABLE, "Unexpected hr %#lx.\n", hr); + todo_wine + check_persist_options(reader, WICPersistOptionNoCacheStream); + + IWICPersistStream_Release(persist_stream); + + IWICMetadataReader_Release(reader); + IStream_Release(stream); IWICComponentFactory_Release(factory); @@ -1030,12 +1779,12 @@ static void test_metadata_png(void) { static const struct test_data td[6] = { - { VT_UI2, 0, 0, { 2005 }, NULL, { 'Y','e','a','r',0 } }, - { VT_UI1, 0, 0, { 6 }, NULL, { 'M','o','n','t','h',0 } }, - { VT_UI1, 0, 0, { 3 }, NULL, { 'D','a','y',0 } }, - { VT_UI1, 0, 0, { 15 }, NULL, { 'H','o','u','r',0 } }, - { VT_UI1, 0, 0, { 7 }, NULL, { 'M','i','n','u','t','e',0 } }, - { VT_UI1, 0, 0, { 45 }, NULL, { 'S','e','c','o','n','d',0 } } + { VT_UI2, 0, 0, { 2005 }, NULL, L"Year" }, + { VT_UI1, 0, 0, { 6 }, NULL, L"Month" }, + { VT_UI1, 0, 0, { 3 }, NULL, L"Day" }, + { VT_UI1, 0, 0, { 15 }, NULL, L"Hour" }, + { VT_UI1, 0, 0, { 7 }, NULL, L"Minute" }, + { VT_UI1, 0, 0, { 45 }, NULL, L"Second" } }; IStream *stream; IWICBitmapDecoder *decoder; @@ -1050,61 +1799,62 @@ static void test_metadata_png(void) hr = CoCreateInstance(&CLSID_WICPngDecoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void**)&decoder); - ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); + ok(hr == S_OK, "CoCreateInstance failed, hr=%lx\n", hr); if (FAILED(hr)) return; stream = create_stream(pngimage, sizeof(pngimage)); hr = IWICBitmapDecoder_Initialize(decoder, stream, WICDecodeMetadataCacheOnLoad); - ok(hr == S_OK, "Initialize failed, hr=%x\n", hr); + ok(hr == S_OK, "Initialize failed, hr=%lx\n", hr); - hr = IWICBitmapDecoder_QueryInterface(decoder, &IID_IWICMetadataBlockReader, (void**)&blockreader); - ok(hr == E_NOINTERFACE, "QueryInterface failed, hr=%x\n", hr); + check_interface(decoder, &IID_IWICMetadataBlockReader, FALSE); hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame failed, hr=%x\n", hr); + ok(hr == S_OK, "GetFrame failed, hr=%lx\n", hr); hr = IWICBitmapFrameDecode_QueryInterface(frame, &IID_IWICMetadataBlockReader, (void**)&blockreader); - ok(hr == S_OK, "QueryInterface failed, hr=%x\n", hr); + ok(hr == S_OK, "QueryInterface failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICMetadataBlockReader_GetContainerFormat(blockreader, NULL); - ok(hr == E_INVALIDARG, "GetContainerFormat failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetContainerFormat failed, hr=%lx\n", hr); hr = IWICMetadataBlockReader_GetContainerFormat(blockreader, &containerformat); - ok(hr == S_OK, "GetContainerFormat failed, hr=%x\n", hr); + ok(hr == S_OK, "GetContainerFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&containerformat, &GUID_ContainerFormatPng), "unexpected container format\n"); hr = IWICMetadataBlockReader_GetCount(blockreader, NULL); - ok(hr == E_INVALIDARG, "GetCount failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetCount failed, hr=%lx\n", hr); hr = IWICMetadataBlockReader_GetCount(blockreader, &count); - ok(hr == S_OK, "GetCount failed, hr=%x\n", hr); + ok(hr == S_OK, "GetCount failed, hr=%lx\n", hr); ok(count == 1, "unexpected count %d\n", count); if (0) { /* Crashes on Windows XP */ hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 0, NULL); - ok(hr == E_INVALIDARG, "GetReaderByIndex failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetReaderByIndex failed, hr=%lx\n", hr); } hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 0, &reader); - ok(hr == S_OK, "GetReaderByIndex failed, hr=%x\n", hr); + ok(hr == S_OK, "GetReaderByIndex failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICMetadataReader_GetMetadataFormat(reader, &containerformat); - ok(hr == S_OK, "GetMetadataFormat failed, hr=%#x\n", hr); - todo_wine ok(IsEqualGUID(&containerformat, &GUID_MetadataFormatChunktIME) || + ok(hr == S_OK, "GetMetadataFormat failed, hr=%#lx\n", hr); + ok(IsEqualGUID(&containerformat, &GUID_MetadataFormatChunktIME) || broken(IsEqualGUID(&containerformat, &GUID_MetadataFormatUnknown)) /* Windows XP */, "unexpected container format\n"); + test_reader_container_format(reader, &GUID_ContainerFormatPng); + hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); - todo_wine ok(count == 6 || broken(count == 1) /* XP */, "expected 6, got %u\n", count); + ok(hr == S_OK, "GetCount error %#lx\n", hr); + ok(count == 6 || broken(count == 1) /* XP */, "expected 6, got %u\n", count); if (count == 6) compare_metadata(reader, td, count); @@ -1112,20 +1862,20 @@ static void test_metadata_png(void) } hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 1, &reader); - todo_wine ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "GetReaderByIndex failed, hr=%x\n", hr); + todo_wine ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "GetReaderByIndex failed, hr=%lx\n", hr); hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICComponentFactory, (void**)&factory); - ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); + ok(hr == S_OK, "CoCreateInstance failed, hr=%lx\n", hr); hr = IWICComponentFactory_CreateQueryReaderFromBlockReader(factory, NULL, &queryreader); - ok(hr == E_INVALIDARG, "CreateQueryReaderFromBlockReader should have failed: %08x\n", hr); + ok(hr == E_INVALIDARG, "CreateQueryReaderFromBlockReader should have failed: %08lx\n", hr); hr = IWICComponentFactory_CreateQueryReaderFromBlockReader(factory, blockreader, NULL); - ok(hr == E_INVALIDARG, "CreateQueryReaderFromBlockReader should have failed: %08x\n", hr); + ok(hr == E_INVALIDARG, "CreateQueryReaderFromBlockReader should have failed: %08lx\n", hr); hr = IWICComponentFactory_CreateQueryReaderFromBlockReader(factory, blockreader, &queryreader); - ok(hr == S_OK, "CreateQueryReaderFromBlockReader failed: %08x\n", hr); + ok(hr == S_OK, "CreateQueryReaderFromBlockReader failed: %08lx\n", hr); IWICMetadataQueryReader_Release(queryreader); @@ -1135,7 +1885,7 @@ static void test_metadata_png(void) } hr = IWICBitmapFrameDecode_GetMetadataQueryReader(frame, &queryreader); - ok(hr == S_OK, "GetMetadataQueryReader failed: %08x\n", hr); + ok(hr == S_OK, "GetMetadataQueryReader failed: %08lx\n", hr); if (SUCCEEDED(hr)) { @@ -1241,39 +1991,41 @@ static void test_metadata_gif(void) hr = CoCreateInstance(&CLSID_WICGifDecoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void **)&decoder); - ok(hr == S_OK, "CoCreateInstance error %#x\n", hr); + ok(hr == S_OK, "CoCreateInstance error %#lx\n", hr); hr = IWICBitmapDecoder_Initialize(decoder, stream, WICDecodeMetadataCacheOnLoad); - ok(hr == S_OK, "Initialize error %#x\n", hr); + ok(hr == S_OK, "Initialize error %#lx\n", hr); IStream_Release(stream); /* global metadata block */ hr = IWICBitmapDecoder_QueryInterface(decoder, &IID_IWICMetadataBlockReader, (void **)&blockreader); - ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* before Win7 */, "QueryInterface error %#x\n", hr); + ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* before Win7 */, "QueryInterface error %#lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICMetadataBlockReader_GetContainerFormat(blockreader, &format); - ok(hr == S_OK, "GetContainerFormat error %#x\n", hr); + ok(hr == S_OK, "GetContainerFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_ContainerFormatGif), "wrong container format %s\n", wine_dbgstr_guid(&format)); hr = IWICMetadataBlockReader_GetCount(blockreader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); + ok(hr == S_OK, "GetCount error %#lx\n", hr); ok(count == 1, "expected 1, got %u\n", count); hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 0, &reader); - ok(hr == S_OK, "GetReaderByIndex error %#x\n", hr); + ok(hr == S_OK, "GetReaderByIndex error %#lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat failed, hr=%#x\n", hr); + ok(hr == S_OK, "GetMetadataFormat failed, hr=%#lx\n", hr); ok(IsEqualGUID(&format, &GUID_MetadataFormatLSD), /* Logical Screen Descriptor */ "wrong metadata format %s\n", wine_dbgstr_guid(&format)); + test_reader_container_format(reader, &GUID_ContainerFormatGif); + hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); + ok(hr == S_OK, "GetCount error %#lx\n", hr); ok(count == ARRAY_SIZE(gif_LSD), "unexpected count %u\n", count); compare_metadata(reader, gif_LSD, count); @@ -1282,47 +2034,47 @@ static void test_metadata_gif(void) } hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 1, &reader); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); IWICMetadataBlockReader_Release(blockreader); } /* frame metadata block */ hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICBitmapFrameDecode_QueryInterface(frame, &IID_IWICMetadataBlockReader, (void **)&blockreader); - ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* before Win7 */, "QueryInterface error %#x\n", hr); + ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* before Win7 */, "QueryInterface error %#lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICMetadataBlockReader_GetContainerFormat(blockreader, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICMetadataBlockReader_GetContainerFormat(blockreader, &format); - ok(hr == S_OK, "GetContainerFormat error %#x\n", hr); + ok(hr == S_OK, "GetContainerFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_ContainerFormatGif), "wrong container format %s\n", wine_dbgstr_guid(&format)); hr = IWICMetadataBlockReader_GetCount(blockreader, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICMetadataBlockReader_GetCount(blockreader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); + ok(hr == S_OK, "GetCount error %#lx\n", hr); ok(count == 1, "expected 1, got %u\n", count); hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 0, &reader); - ok(hr == S_OK, "GetReaderByIndex error %#x\n", hr); + ok(hr == S_OK, "GetReaderByIndex error %#lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat failed, hr=%#x\n", hr); + ok(hr == S_OK, "GetMetadataFormat failed, hr=%#lx\n", hr); ok(IsEqualGUID(&format, &GUID_MetadataFormatIMD), /* Image Descriptor */ "wrong metadata format %s\n", wine_dbgstr_guid(&format)); hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); + ok(hr == S_OK, "GetCount error %#lx\n", hr); ok(count == ARRAY_SIZE(gif_IMD), "unexpected count %u\n", count); compare_metadata(reader, gif_IMD, count); @@ -1331,7 +2083,7 @@ static void test_metadata_gif(void) } hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 1, &reader); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); IWICMetadataBlockReader_Release(blockreader); } @@ -1344,39 +2096,39 @@ static void test_metadata_gif(void) hr = CoCreateInstance(&CLSID_WICGifDecoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void **)&decoder); - ok(hr == S_OK, "CoCreateInstance error %#x\n", hr); + ok(hr == S_OK, "CoCreateInstance error %#lx\n", hr); hr = IWICBitmapDecoder_Initialize(decoder, stream, WICDecodeMetadataCacheOnLoad); - ok(hr == S_OK, "Initialize error %#x\n", hr); + ok(hr == S_OK, "Initialize error %#lx\n", hr); IStream_Release(stream); /* global metadata block */ hr = IWICBitmapDecoder_QueryInterface(decoder, &IID_IWICMetadataBlockReader, (void **)&blockreader); - ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* before Win7 */, "QueryInterface error %#x\n", hr); + ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* before Win7 */, "QueryInterface error %#lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICMetadataBlockReader_GetContainerFormat(blockreader, &format); - ok(hr == S_OK, "GetContainerFormat error %#x\n", hr); + ok(hr == S_OK, "GetContainerFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_ContainerFormatGif), "wrong container format %s\n", wine_dbgstr_guid(&format)); hr = IWICMetadataBlockReader_GetCount(blockreader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); + ok(hr == S_OK, "GetCount error %#lx\n", hr); ok(count == 4, "expected 4, got %u\n", count); hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 0, &reader); - ok(hr == S_OK, "GetReaderByIndex error %#x\n", hr); + ok(hr == S_OK, "GetReaderByIndex error %#lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat failed, hr=%#x\n", hr); + ok(hr == S_OK, "GetMetadataFormat failed, hr=%#lx\n", hr); ok(IsEqualGUID(&format, &GUID_MetadataFormatLSD), /* Logical Screen Descriptor */ "wrong metadata format %s\n", wine_dbgstr_guid(&format)); hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); + ok(hr == S_OK, "GetCount error %#lx\n", hr); ok(count == ARRAY_SIZE(animated_gif_LSD), "unexpected count %u\n", count); compare_metadata(reader, animated_gif_LSD, count); @@ -1385,17 +2137,17 @@ static void test_metadata_gif(void) } hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 1, &reader); - ok(hr == S_OK, "GetReaderByIndex error %#x\n", hr); + ok(hr == S_OK, "GetReaderByIndex error %#lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat failed, hr=%#x\n", hr); + ok(hr == S_OK, "GetMetadataFormat failed, hr=%#lx\n", hr); ok(IsEqualGUID(&format, &GUID_MetadataFormatAPE), /* Application Extension */ "wrong metadata format %s\n", wine_dbgstr_guid(&format)); hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); + ok(hr == S_OK, "GetCount error %#lx\n", hr); ok(count == ARRAY_SIZE(animated_gif_APE), "unexpected count %u\n", count); compare_metadata(reader, animated_gif_APE, count); @@ -1404,17 +2156,17 @@ static void test_metadata_gif(void) } hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 2, &reader); - ok(hr == S_OK, "GetReaderByIndex error %#x\n", hr); + ok(hr == S_OK, "GetReaderByIndex error %#lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat failed, hr=%#x\n", hr); + ok(hr == S_OK, "GetMetadataFormat failed, hr=%#lx\n", hr); ok(IsEqualGUID(&format, &GUID_MetadataFormatGifComment), /* Comment Extension */ "wrong metadata format %s\n", wine_dbgstr_guid(&format)); hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); + ok(hr == S_OK, "GetCount error %#lx\n", hr); ok(count == ARRAY_SIZE(animated_gif_comment_1), "unexpected count %u\n", count); compare_metadata(reader, animated_gif_comment_1, count); @@ -1423,17 +2175,17 @@ static void test_metadata_gif(void) } hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 3, &reader); - ok(hr == S_OK, "GetReaderByIndex error %#x\n", hr); + ok(hr == S_OK, "GetReaderByIndex error %#lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat failed, hr=%#x\n", hr); + ok(hr == S_OK, "GetMetadataFormat failed, hr=%#lx\n", hr); ok(IsEqualGUID(&format, &GUID_MetadataFormatUnknown), "wrong metadata format %s\n", wine_dbgstr_guid(&format)); hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); + ok(hr == S_OK, "GetCount error %#lx\n", hr); ok(count == ARRAY_SIZE(animated_gif_plain_1), "unexpected count %u\n", count); compare_metadata(reader, animated_gif_plain_1, count); @@ -1442,47 +2194,47 @@ static void test_metadata_gif(void) } hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 4, &reader); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); IWICMetadataBlockReader_Release(blockreader); } /* frame metadata block */ hr = IWICBitmapDecoder_GetFrame(decoder, 1, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICBitmapFrameDecode_QueryInterface(frame, &IID_IWICMetadataBlockReader, (void **)&blockreader); - ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* before Win7 */, "QueryInterface error %#x\n", hr); + ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* before Win7 */, "QueryInterface error %#lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICMetadataBlockReader_GetContainerFormat(blockreader, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICMetadataBlockReader_GetContainerFormat(blockreader, &format); - ok(hr == S_OK, "GetContainerFormat error %#x\n", hr); + ok(hr == S_OK, "GetContainerFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_ContainerFormatGif), "wrong container format %s\n", wine_dbgstr_guid(&format)); hr = IWICMetadataBlockReader_GetCount(blockreader, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICMetadataBlockReader_GetCount(blockreader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); + ok(hr == S_OK, "GetCount error %#lx\n", hr); ok(count == 4, "expected 4, got %u\n", count); hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 0, &reader); - ok(hr == S_OK, "GetReaderByIndex error %#x\n", hr); + ok(hr == S_OK, "GetReaderByIndex error %#lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat failed, hr=%#x\n", hr); + ok(hr == S_OK, "GetMetadataFormat failed, hr=%#lx\n", hr); ok(IsEqualGUID(&format, &GUID_MetadataFormatIMD), /* Image Descriptor */ "wrong metadata format %s\n", wine_dbgstr_guid(&format)); hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); + ok(hr == S_OK, "GetCount error %#lx\n", hr); ok(count == ARRAY_SIZE(animated_gif_IMD), "unexpected count %u\n", count); compare_metadata(reader, animated_gif_IMD, count); @@ -1491,72 +2243,72 @@ static void test_metadata_gif(void) } hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 1, &reader); - ok(hr == S_OK, "GetReaderByIndex error %#x\n", hr); + ok(hr == S_OK, "GetReaderByIndex error %#lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat failed, hr=%#x\n", hr); - ok(IsEqualGUID(&format, &GUID_MetadataFormatGifComment), /* Comment Extension */ - "wrong metadata format %s\n", wine_dbgstr_guid(&format)); + ok(hr == S_OK, "GetMetadataFormat failed, hr=%#lx\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatGCE), /* Graphic Control Extension */ + "wrong metadata format %s\n", wine_dbgstr_guid(&format)); hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); - ok(count == ARRAY_SIZE(animated_gif_comment_2), "unexpected count %u\n", count); + ok(hr == S_OK, "GetCount error %#lx\n", hr); + ok(count == ARRAY_SIZE(animated_gif_GCE), "unexpected count %u\n", count); - if (count == 1) - compare_metadata(reader, animated_gif_comment_2, count); + compare_metadata(reader, animated_gif_GCE, count); IWICMetadataReader_Release(reader); } hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 2, &reader); - ok(hr == S_OK, "GetReaderByIndex error %#x\n", hr); + ok(hr == S_OK, "GetReaderByIndex error %#lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat failed, hr=%#x\n", hr); - ok(IsEqualGUID(&format, &GUID_MetadataFormatUnknown), - "wrong metadata format %s\n", wine_dbgstr_guid(&format)); + ok(hr == S_OK, "GetMetadataFormat failed, hr=%#lx\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatGifComment), /* Comment Extension */ + "wrong metadata format %s\n", wine_dbgstr_guid(&format)); hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); - ok(count == ARRAY_SIZE(animated_gif_plain_2), "unexpected count %u\n", count); + ok(hr == S_OK, "GetCount error %#lx\n", hr); + ok(count == ARRAY_SIZE(animated_gif_comment_2), "unexpected count %u\n", count); - compare_metadata(reader, animated_gif_plain_2, count); + if (count == 1) + compare_metadata(reader, animated_gif_comment_2, count); IWICMetadataReader_Release(reader); } hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 3, &reader); - ok(hr == S_OK, "GetReaderByIndex error %#x\n", hr); + ok(hr == S_OK, "GetReaderByIndex error %#lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat failed, hr=%#x\n", hr); - ok(IsEqualGUID(&format, &GUID_MetadataFormatGCE), /* Graphic Control Extension */ + ok(hr == S_OK, "GetMetadataFormat failed, hr=%#lx\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatUnknown), "wrong metadata format %s\n", wine_dbgstr_guid(&format)); hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); - ok(count == ARRAY_SIZE(animated_gif_GCE), "unexpected count %u\n", count); + ok(hr == S_OK, "GetCount error %#lx\n", hr); + ok(count == ARRAY_SIZE(animated_gif_plain_2), "unexpected count %u\n", count); - compare_metadata(reader, animated_gif_GCE, count); + compare_metadata(reader, animated_gif_plain_2, count); IWICMetadataReader_Release(reader); } hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 4, &reader); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); IWICMetadataBlockReader_Release(blockreader); } hr = IWICBitmapDecoder_GetMetadataQueryReader(decoder, &queryreader); ok(hr == S_OK || broken(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION) /* before Vista */, - "GetMetadataQueryReader error %#x\n", hr); + "GetMetadataQueryReader error %#lx\n", hr); if (SUCCEEDED(hr)) { static const struct @@ -1584,23 +2336,22 @@ static void test_metadata_gif(void) { "grctlext", WINCODEC_ERR_PROPERTYNOTSUPPORTED, 0 }, { "/imgdesc", WINCODEC_ERR_PROPERTYNOTFOUND, 0 }, }; - static const WCHAR rootW[] = {'/',0}; WCHAR name[256]; UINT len, i, j; PROPVARIANT value; IWICMetadataQueryReader *meta_reader; hr = IWICMetadataQueryReader_GetContainerFormat(queryreader, &format); - ok(hr == S_OK, "GetContainerFormat error %#x\n", hr); + ok(hr == S_OK, "GetContainerFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_ContainerFormatGif), "wrong container format %s\n", wine_dbgstr_guid(&format)); name[0] = 0; len = 0xdeadbeef; hr = IWICMetadataQueryReader_GetLocation(queryreader, 256, name, &len); - ok(hr == S_OK, "GetLocation error %#x\n", hr); + ok(hr == S_OK, "GetLocation error %#lx\n", hr); ok(len == 2, "expected 2, got %u\n", len); - ok(!lstrcmpW(name, rootW), "expected '/', got %s\n", wine_dbgstr_w(name)); + ok(!lstrcmpW(name, L"/"), "expected '/', got %s\n", wine_dbgstr_w(name)); for (i = 0; i < ARRAY_SIZE(decoder_data); i++) { @@ -1611,21 +2362,21 @@ static void test_metadata_gif(void) MultiByteToWideChar(CP_ACP, 0, decoder_data[i].query, -1, queryW, 256); hr = IWICMetadataQueryReader_GetMetadataByName(queryreader, queryW, NULL); - ok(hr == decoder_data[i].hr, "GetMetadataByName(%s) returned %#x, expected %#x\n", wine_dbgstr_w(queryW), hr, decoder_data[i].hr); + ok(hr == decoder_data[i].hr, "GetMetadataByName(%s) returned %#lx, expected %#lx\n", wine_dbgstr_w(queryW), hr, decoder_data[i].hr); PropVariantInit(&value); hr = IWICMetadataQueryReader_GetMetadataByName(queryreader, queryW, &value); - ok(hr == decoder_data[i].hr, "GetMetadataByName(%s) returned %#x, expected %#x\n", wine_dbgstr_w(queryW), hr, decoder_data[i].hr); + ok(hr == decoder_data[i].hr, "GetMetadataByName(%s) returned %#lx, expected %#lx\n", wine_dbgstr_w(queryW), hr, decoder_data[i].hr); ok(value.vt == decoder_data[i].vt, "expected %#x, got %#x\n", decoder_data[i].vt, value.vt); if (hr == S_OK && value.vt == VT_UNKNOWN) { hr = IUnknown_QueryInterface(value.punkVal, &IID_IWICMetadataQueryReader, (void **)&meta_reader); - ok(hr == S_OK, "QueryInterface error %#x\n", hr); + ok(hr == S_OK, "QueryInterface error %#lx\n", hr); name[0] = 0; len = 0xdeadbeef; hr = IWICMetadataQueryReader_GetLocation(meta_reader, 256, name, &len); - ok(hr == S_OK, "GetLocation error %#x\n", hr); + ok(hr == S_OK, "GetLocation error %#lx\n", hr); ok(len == lstrlenW(queryW) + 1, "expected %u, got %u\n", lstrlenW(queryW) + 1, len); ok(!lstrcmpW(name, queryW), "expected %s, got %s\n", wine_dbgstr_w(queryW), wine_dbgstr_w(name)); @@ -1639,7 +2390,7 @@ static void test_metadata_gif(void) trace("query: %s\n", wine_dbgstr_w(queryW + len - 1)); PropVariantClear(&value); hr = IWICMetadataQueryReader_GetMetadataByName(meta_reader, queryW + len - 1, &value); - ok(hr == decoder_data[j].hr, "GetMetadataByName(%s) returned %#x, expected %#x\n", wine_dbgstr_w(queryW + len - 1), hr, decoder_data[j].hr); + ok(hr == decoder_data[j].hr, "GetMetadataByName(%s) returned %#lx, expected %#lx\n", wine_dbgstr_w(queryW + len - 1), hr, decoder_data[j].hr); ok(value.vt == decoder_data[j].vt, "expected %#x, got %#x\n", decoder_data[j].vt, value.vt); } } @@ -1655,7 +2406,7 @@ static void test_metadata_gif(void) hr = IWICBitmapFrameDecode_GetMetadataQueryReader(frame, &queryreader); ok(hr == S_OK || broken(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION) /* before Vista */, - "GetMetadataQueryReader error %#x\n", hr); + "GetMetadataQueryReader error %#lx\n", hr); if (SUCCEEDED(hr)) { static const struct @@ -1684,26 +2435,23 @@ static void test_metadata_gif(void) { "/grctlext/{str=\\delay}", S_OK, VT_UI2 }, { "grctlext/Delay", WINCODEC_ERR_PROPERTYNOTSUPPORTED, 0 }, }; - static const WCHAR rootW[] = {'/',0}; static const WCHAR guidW[] = {'/','{','g','u','i','d','=','\\',0}; - static const WCHAR imgdescW[] = {'i','m','g','d','e','s','c',0}; - static const WCHAR ImgDescW[] = {'I','m','g','D','e','s','c',0}; WCHAR name[256], queryW[256]; UINT len, i; PROPVARIANT value; IWICMetadataQueryReader *meta_reader; hr = IWICMetadataQueryReader_GetContainerFormat(queryreader, &format); - ok(hr == S_OK, "GetContainerFormat error %#x\n", hr); + ok(hr == S_OK, "GetContainerFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_ContainerFormatGif), "wrong container format %s\n", wine_dbgstr_guid(&format)); name[0] = 0; len = 0xdeadbeef; hr = IWICMetadataQueryReader_GetLocation(queryreader, 256, name, &len); - ok(hr == S_OK, "GetLocation error %#x\n", hr); + ok(hr == S_OK, "GetLocation error %#lx\n", hr); ok(len == 2, "expected 2, got %u\n", len); - ok(!lstrcmpW(name, rootW), "expected '/', got %s\n", wine_dbgstr_w(name)); + ok(!lstrcmpW(name, L"/"), "expected '/', got %s\n", wine_dbgstr_w(name)); for (i = 0; i < ARRAY_SIZE(frame_data); i++) { @@ -1712,17 +2460,17 @@ static void test_metadata_gif(void) MultiByteToWideChar(CP_ACP, 0, frame_data[i].query, -1, queryW, 256); PropVariantInit(&value); hr = IWICMetadataQueryReader_GetMetadataByName(queryreader, queryW, &value); - ok(hr == frame_data[i].hr, "GetMetadataByName(%s) returned %#x, expected %#x\n", wine_dbgstr_w(queryW), hr, frame_data[i].hr); + ok(hr == frame_data[i].hr, "GetMetadataByName(%s) returned %#lx, expected %#lx\n", wine_dbgstr_w(queryW), hr, frame_data[i].hr); ok(value.vt == frame_data[i].vt, "expected %#x, got %#x\n", frame_data[i].vt, value.vt); if (hr == S_OK && value.vt == VT_UNKNOWN) { hr = IUnknown_QueryInterface(value.punkVal, &IID_IWICMetadataQueryReader, (void **)&meta_reader); - ok(hr == S_OK, "QueryInterface error %#x\n", hr); + ok(hr == S_OK, "QueryInterface error %#lx\n", hr); name[0] = 0; len = 0xdeadbeef; hr = IWICMetadataQueryReader_GetLocation(meta_reader, 256, name, &len); - ok(hr == S_OK, "GetLocation error %#x\n", hr); + ok(hr == S_OK, "GetLocation error %#lx\n", hr); ok(len == lstrlenW(queryW) + 1, "expected %u, got %u\n", lstrlenW(queryW) + 1, len); ok(!lstrcmpW(name, queryW), "expected %s, got %s\n", wine_dbgstr_w(queryW), wine_dbgstr_w(name)); @@ -1735,17 +2483,17 @@ static void test_metadata_gif(void) name[0] = 0; len = 0xdeadbeef; hr = WICMapGuidToShortName(&GUID_MetadataFormatIMD, 256, name, &len); - ok(hr == S_OK, "WICMapGuidToShortName error %#x\n", hr); - ok(!lstrcmpW(name, imgdescW), "wrong short name %s\n", wine_dbgstr_w(name)); + ok(hr == S_OK, "WICMapGuidToShortName error %#lx\n", hr); + ok(!lstrcmpW(name, L"imgdesc"), "wrong short name %s\n", wine_dbgstr_w(name)); format = GUID_NULL; - hr = WICMapShortNameToGuid(imgdescW, &format); - ok(hr == S_OK, "WICMapGuidToShortName error %#x\n", hr); + hr = WICMapShortNameToGuid(L"imgdesc", &format); + ok(hr == S_OK, "WICMapGuidToShortName error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_MetadataFormatIMD), "wrong guid %s\n", wine_dbgstr_guid(&format)); format = GUID_NULL; - hr = WICMapShortNameToGuid(ImgDescW, &format); - ok(hr == S_OK, "WICMapGuidToShortName error %#x\n", hr); + hr = WICMapShortNameToGuid(L"ImgDesc", &format); + ok(hr == S_OK, "WICMapGuidToShortName error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_MetadataFormatIMD), "wrong guid %s\n", wine_dbgstr_guid(&format)); lstrcpyW(queryW, guidW); @@ -1755,7 +2503,7 @@ static void test_metadata_gif(void) trace("query: %s\n", wine_dbgstr_w(queryW)); PropVariantInit(&value); hr = IWICMetadataQueryReader_GetMetadataByName(queryreader, queryW, &value); - ok(hr == S_OK, "GetMetadataByName(%s) error %#x\n", wine_dbgstr_w(queryW), hr); + ok(hr == S_OK, "GetMetadataByName(%s) error %#lx\n", wine_dbgstr_w(queryW), hr); ok(value.vt == VT_UNKNOWN, "expected VT_UNKNOWN, got %#x\n", value.vt); PropVariantClear(&value); @@ -1768,25 +2516,25 @@ static void test_metadata_gif(void) static void test_metadata_LSD(void) { - static const WCHAR LSD_name[] = {'L','o','g','i','c','a','l',' ','S','c','r','e','e','n',' ','D','e','s','c','r','i','p','t','o','r',' ','R','e','a','d','e','r',0}; static const char LSD_data[] = "hello world!\x1\x2\x3\x4\xab\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf"; static const struct test_data td[9] = { - { VT_UI1|VT_VECTOR, 0, 6, {'w','o','r','l','d','!'}, NULL, { 'S','i','g','n','a','t','u','r','e',0 } }, - { VT_UI2, 0, 0, { 0x201 }, NULL, { 'W','i','d','t','h',0 } }, - { VT_UI2, 0, 0, { 0x403 }, NULL, { 'H','e','i','g','h','t',0 } }, - { VT_BOOL, 0, 0, { 1 }, NULL, { 'G','l','o','b','a','l','C','o','l','o','r','T','a','b','l','e','F','l','a','g',0 } }, - { VT_UI1, 0, 0, { 2 }, NULL, { 'C','o','l','o','r','R','e','s','o','l','u','t','i','o','n',0 } }, - { VT_BOOL, 0, 0, { 1 }, NULL, { 'S','o','r','t','F','l','a','g',0 } }, - { VT_UI1, 0, 0, { 3 }, NULL, { 'G','l','o','b','a','l','C','o','l','o','r','T','a','b','l','e','S','i','z','e',0 } }, - { VT_UI1, 0, 0, { 6 }, NULL, { 'B','a','c','k','g','r','o','u','n','d','C','o','l','o','r','I','n','d','e','x',0 } }, - { VT_UI1, 0, 0, { 7 }, NULL, { 'P','i','x','e','l','A','s','p','e','c','t','R','a','t','i','o',0 } } + { VT_UI1|VT_VECTOR, 0, 6, {'w','o','r','l','d','!'}, NULL, L"Signature" }, + { VT_UI2, 0, 0, { 0x201 }, NULL, L"Width" }, + { VT_UI2, 0, 0, { 0x403 }, NULL, L"Height" }, + { VT_BOOL, 0, 0, { 1 }, NULL, L"GlobalColorTableFlag" }, + { VT_UI1, 0, 0, { 2 }, NULL, L"ColorResolution" }, + { VT_BOOL, 0, 0, { 1 }, NULL, L"SortFlag" }, + { VT_UI1, 0, 0, { 3 }, NULL, L"GlobalColorTableSize" }, + { VT_UI1, 0, 0, { 6 }, NULL, L"BackgroundColorIndex" }, + { VT_UI1, 0, 0, { 7 }, NULL, L"PixelAspectRatio" } }; LARGE_INTEGER pos; HRESULT hr; IStream *stream; IWICPersistStream *persist; IWICMetadataReader *reader; + IWICMetadataWriter *writer; IWICMetadataHandlerInfo *info; WCHAR name[64]; UINT count, dummy; @@ -1796,75 +2544,98 @@ static void test_metadata_LSD(void) hr = CoCreateInstance(&CLSID_WICLSDMetadataReader, NULL, CLSCTX_INPROC_SERVER, &IID_IWICMetadataReader, (void **)&reader); ok(hr == S_OK || broken(hr == E_NOINTERFACE || hr == REGDB_E_CLASSNOTREG) /* before Win7 */, - "CoCreateInstance error %#x\n", hr); + "CoCreateInstance error %#lx\n", hr); + if (FAILED(hr)) return; + + check_interface(reader, &IID_IWICMetadataReader, TRUE); + check_interface(reader, &IID_IPersist, TRUE); + check_interface(reader, &IID_IPersistStream, TRUE); + check_interface(reader, &IID_IWICPersistStream, TRUE); + check_interface(reader, &IID_IWICStreamProvider, TRUE); stream = create_stream(LSD_data, sizeof(LSD_data)); - if (SUCCEEDED(hr)) - { - pos.QuadPart = 6; - hr = IStream_Seek(stream, pos, SEEK_SET, NULL); - ok(hr == S_OK, "IStream_Seek error %#x\n", hr); + test_reader_container_format(reader, &GUID_ContainerFormatGif); - hr = IUnknown_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist); - ok(hr == S_OK, "QueryInterface error %#x\n", hr); + pos.QuadPart = 6; + hr = IStream_Seek(stream, pos, SEEK_SET, NULL); + ok(hr == S_OK, "IStream_Seek error %#lx\n", hr); - hr = IWICPersistStream_Load(persist, stream); - ok(hr == S_OK, "Load error %#x\n", hr); + hr = IUnknown_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist); + ok(hr == S_OK, "QueryInterface error %#lx\n", hr); - IWICPersistStream_Release(persist); - } + hr = IWICPersistStream_Load(persist, stream); + ok(hr == S_OK, "Load error %#lx\n", hr); + todo_wine + check_persist_options(reader, 0); - if (SUCCEEDED(hr)) - { - hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); - ok(count == ARRAY_SIZE(td), "unexpected count %u\n", count); + IWICPersistStream_Release(persist); - compare_metadata(reader, td, count); + hr = IWICMetadataReader_GetCount(reader, &count); + ok(hr == S_OK, "GetCount error %#lx\n", hr); + ok(count == ARRAY_SIZE(td), "unexpected count %u\n", count); - hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat error %#x\n", hr); - ok(IsEqualGUID(&format, &GUID_MetadataFormatLSD), "wrong format %s\n", wine_dbgstr_guid(&format)); + compare_metadata(reader, td, count); - hr = IWICMetadataReader_GetMetadataHandlerInfo(reader, &info); - ok(hr == S_OK, "GetMetadataHandlerInfo error %#x\n", hr); + hr = IWICMetadataReader_GetMetadataFormat(reader, &format); + ok(hr == S_OK, "GetMetadataFormat error %#lx\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatLSD), "wrong format %s\n", wine_dbgstr_guid(&format)); - hr = IWICMetadataHandlerInfo_GetCLSID(info, &id); - ok(hr == S_OK, "GetCLSID error %#x\n", hr); - ok(IsEqualGUID(&id, &CLSID_WICLSDMetadataReader), "wrong CLSID %s\n", wine_dbgstr_guid(&id)); + hr = IWICMetadataReader_GetMetadataHandlerInfo(reader, &info); + ok(hr == S_OK, "GetMetadataHandlerInfo error %#lx\n", hr); - hr = IWICMetadataHandlerInfo_GetFriendlyName(info, 64, name, &dummy); - ok(hr == S_OK, "GetFriendlyName error %#x\n", hr); - ok(lstrcmpW(name, LSD_name) == 0, "wrong LSD reader name %s\n", wine_dbgstr_w(name)); + hr = IWICMetadataHandlerInfo_GetCLSID(info, &id); + ok(hr == S_OK, "GetCLSID error %#lx\n", hr); + ok(IsEqualGUID(&id, &CLSID_WICLSDMetadataReader), "wrong CLSID %s\n", wine_dbgstr_guid(&id)); - IWICMetadataHandlerInfo_Release(info); - IWICMetadataReader_Release(reader); - } + hr = IWICMetadataHandlerInfo_GetFriendlyName(info, 64, name, &dummy); + ok(hr == S_OK, "GetFriendlyName error %#lx\n", hr); + ok(!lstrcmpW(name, L"Logical Screen Descriptor Reader"), "wrong LSD reader name %s\n", wine_dbgstr_w(name)); + + IWICMetadataHandlerInfo_Release(info); + IWICMetadataReader_Release(reader); IStream_Release(stream); + + hr = CoCreateInstance(&CLSID_WICLSDMetadataWriter, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataWriter, (void **)&writer); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) return; + + check_interface(writer, &IID_IWICMetadataWriter, TRUE); + check_interface(writer, &IID_IWICMetadataReader, TRUE); + check_interface(writer, &IID_IPersist, TRUE); + check_interface(writer, &IID_IPersistStream, TRUE); + check_interface(writer, &IID_IWICPersistStream, TRUE); + check_interface(writer, &IID_IWICStreamProvider, TRUE); + + load_stream(writer, LSD_data, sizeof(LSD_data), 0); + load_stream(writer, LSD_data, sizeof(LSD_data), WICPersistOptionNoCacheStream); + + IWICMetadataWriter_Release(writer); } static void test_metadata_IMD(void) { - static const WCHAR IMD_name[] = {'I','m','a','g','e',' ','D','e','s','c','r','i','p','t','o','r',' ','R','e','a','d','e','r',0}; static const char IMD_data[] = "hello world!\x1\x2\x3\x4\x5\x6\x7\x8\xed\xa\xb\xc\xd\xe\xf"; static const struct test_data td[8] = { - { VT_UI2, 0, 0, { 0x201 }, NULL, { 'L','e','f','t',0 } }, - { VT_UI2, 0, 0, { 0x403 }, NULL, { 'T','o','p',0 } }, - { VT_UI2, 0, 0, { 0x605 }, NULL, { 'W','i','d','t','h',0 } }, - { VT_UI2, 0, 0, { 0x807 }, NULL, { 'H','e','i','g','h','t',0 } }, - { VT_BOOL, 0, 0, { 1 }, NULL, { 'L','o','c','a','l','C','o','l','o','r','T','a','b','l','e','F','l','a','g',0 } }, - { VT_BOOL, 0, 0, { 1 }, NULL, { 'I','n','t','e','r','l','a','c','e','F','l','a','g',0 } }, - { VT_BOOL, 0, 0, { 1 }, NULL, { 'S','o','r','t','F','l','a','g',0 } }, - { VT_UI1, 0, 0, { 5 }, NULL, { 'L','o','c','a','l','C','o','l','o','r','T','a','b','l','e','S','i','z','e',0 } } + { VT_UI2, 0, 0, { 0x201 }, NULL, L"Left" }, + { VT_UI2, 0, 0, { 0x403 }, NULL, L"Top" }, + { VT_UI2, 0, 0, { 0x605 }, NULL, L"Width" }, + { VT_UI2, 0, 0, { 0x807 }, NULL, L"Height" }, + { VT_BOOL, 0, 0, { 1 }, NULL, L"LocalColorTableFlag" }, + { VT_BOOL, 0, 0, { 1 }, NULL, L"InterlaceFlag" }, + { VT_BOOL, 0, 0, { 1 }, NULL, L"SortFlag" }, + { VT_UI1, 0, 0, { 5 }, NULL, L"LocalColorTableSize" } }; LARGE_INTEGER pos; HRESULT hr; IStream *stream; IWICPersistStream *persist; IWICMetadataReader *reader; + IWICMetadataWriter *writer; IWICMetadataHandlerInfo *info; WCHAR name[64]; UINT count, dummy; @@ -1874,72 +2645,95 @@ static void test_metadata_IMD(void) hr = CoCreateInstance(&CLSID_WICIMDMetadataReader, NULL, CLSCTX_INPROC_SERVER, &IID_IWICMetadataReader, (void **)&reader); ok(hr == S_OK || broken(hr == E_NOINTERFACE || hr == REGDB_E_CLASSNOTREG) /* before Win7 */, - "CoCreateInstance error %#x\n", hr); + "CoCreateInstance error %#lx\n", hr); + if (FAILED(hr)) return; + + check_interface(reader, &IID_IWICMetadataReader, TRUE); + check_interface(reader, &IID_IPersist, TRUE); + check_interface(reader, &IID_IPersistStream, TRUE); + check_interface(reader, &IID_IWICPersistStream, TRUE); + check_interface(reader, &IID_IWICStreamProvider, TRUE); + + test_reader_container_format(reader, &GUID_ContainerFormatGif); stream = create_stream(IMD_data, sizeof(IMD_data)); - if (SUCCEEDED(hr)) - { - pos.QuadPart = 12; - hr = IStream_Seek(stream, pos, SEEK_SET, NULL); - ok(hr == S_OK, "IStream_Seek error %#x\n", hr); + pos.QuadPart = 12; + hr = IStream_Seek(stream, pos, SEEK_SET, NULL); + ok(hr == S_OK, "IStream_Seek error %#lx\n", hr); - hr = IUnknown_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist); - ok(hr == S_OK, "QueryInterface error %#x\n", hr); + hr = IUnknown_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist); + ok(hr == S_OK, "QueryInterface error %#lx\n", hr); - hr = IWICPersistStream_Load(persist, stream); - ok(hr == S_OK, "Load error %#x\n", hr); + hr = IWICPersistStream_Load(persist, stream); + ok(hr == S_OK, "Load error %#lx\n", hr); + todo_wine + check_persist_options(reader, 0); - IWICPersistStream_Release(persist); - } + IWICPersistStream_Release(persist); - if (SUCCEEDED(hr)) - { - hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); - ok(count == ARRAY_SIZE(td), "unexpected count %u\n", count); + hr = IWICMetadataReader_GetCount(reader, &count); + ok(hr == S_OK, "GetCount error %#lx\n", hr); + ok(count == ARRAY_SIZE(td), "unexpected count %u\n", count); - compare_metadata(reader, td, count); + compare_metadata(reader, td, count); - hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat error %#x\n", hr); - ok(IsEqualGUID(&format, &GUID_MetadataFormatIMD), "wrong format %s\n", wine_dbgstr_guid(&format)); + hr = IWICMetadataReader_GetMetadataFormat(reader, &format); + ok(hr == S_OK, "GetMetadataFormat error %#lx\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatIMD), "wrong format %s\n", wine_dbgstr_guid(&format)); - hr = IWICMetadataReader_GetMetadataHandlerInfo(reader, &info); - ok(hr == S_OK, "GetMetadataHandlerInfo error %#x\n", hr); + hr = IWICMetadataReader_GetMetadataHandlerInfo(reader, &info); + ok(hr == S_OK, "GetMetadataHandlerInfo error %#lx\n", hr); - hr = IWICMetadataHandlerInfo_GetCLSID(info, &id); - ok(hr == S_OK, "GetCLSID error %#x\n", hr); - ok(IsEqualGUID(&id, &CLSID_WICIMDMetadataReader), "wrong CLSID %s\n", wine_dbgstr_guid(&id)); + hr = IWICMetadataHandlerInfo_GetCLSID(info, &id); + ok(hr == S_OK, "GetCLSID error %#lx\n", hr); + ok(IsEqualGUID(&id, &CLSID_WICIMDMetadataReader), "wrong CLSID %s\n", wine_dbgstr_guid(&id)); - hr = IWICMetadataHandlerInfo_GetFriendlyName(info, 64, name, &dummy); - ok(hr == S_OK, "GetFriendlyName error %#x\n", hr); - ok(lstrcmpW(name, IMD_name) == 0, "wrong IMD reader name %s\n", wine_dbgstr_w(name)); + hr = IWICMetadataHandlerInfo_GetFriendlyName(info, 64, name, &dummy); + ok(hr == S_OK, "GetFriendlyName error %#lx\n", hr); + ok(!lstrcmpW(name, L"Image Descriptor Reader"), "wrong IMD reader name %s\n", wine_dbgstr_w(name)); - IWICMetadataHandlerInfo_Release(info); - IWICMetadataReader_Release(reader); - } + IWICMetadataHandlerInfo_Release(info); + IWICMetadataReader_Release(reader); IStream_Release(stream); + + hr = CoCreateInstance(&CLSID_WICIMDMetadataWriter, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataWriter, (void **)&writer); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) return; + + check_interface(writer, &IID_IWICMetadataWriter, TRUE); + check_interface(writer, &IID_IWICMetadataReader, TRUE); + check_interface(writer, &IID_IPersist, TRUE); + check_interface(writer, &IID_IPersistStream, TRUE); + check_interface(writer, &IID_IWICPersistStream, TRUE); + check_interface(writer, &IID_IWICStreamProvider, TRUE); + + load_stream(writer, IMD_data, sizeof(IMD_data), 0); + load_stream(writer, IMD_data, sizeof(IMD_data), WICPersistOptionNoCacheStream); + + IWICMetadataWriter_Release(writer); } static void test_metadata_GCE(void) { - static const WCHAR GCE_name[] = {'G','r','a','p','h','i','c',' ','C','o','n','t','r','o','l',' ','E','x','t','e','n','s','i','o','n',' ','R','e','a','d','e','r',0}; static const char GCE_data[] = "hello world!\xa\x2\x3\x4\x5\x6\x7\x8\xed\xa\xb\xc\xd\xe\xf"; static const struct test_data td[5] = { - { VT_UI1, 0, 0, { 2 }, NULL, { 'D','i','s','p','o','s','a','l',0 } }, - { VT_BOOL, 0, 0, { 1 }, NULL, { 'U','s','e','r','I','n','p','u','t','F','l','a','g',0 } }, - { VT_BOOL, 0, 0, { 0 }, NULL, { 'T','r','a','n','s','p','a','r','e','n','c','y','F','l','a','g',0 } }, - { VT_UI2, 0, 0, { 0x302 }, NULL, { 'D','e','l','a','y',0 } }, - { VT_UI1, 0, 0, { 4 }, NULL, { 'T','r','a','n','s','p','a','r','e','n','t','C','o','l','o','r','I','n','d','e','x',0 } } + { VT_UI1, 0, 0, { 2 }, NULL, L"Disposal" }, + { VT_BOOL, 0, 0, { 1 }, NULL, L"UserInputFlag" }, + { VT_BOOL, 0, 0, { 0 }, NULL, L"TransparencyFlag" }, + { VT_UI2, 0, 0, { 0x302 }, NULL, L"Delay" }, + { VT_UI1, 0, 0, { 4 }, NULL, L"TransparentColorIndex" } }; LARGE_INTEGER pos; HRESULT hr; IStream *stream; IWICPersistStream *persist; IWICMetadataReader *reader; + IWICMetadataWriter *writer; IWICMetadataHandlerInfo *info; WCHAR name[64]; UINT count, dummy; @@ -1949,58 +2743,80 @@ static void test_metadata_GCE(void) hr = CoCreateInstance(&CLSID_WICGCEMetadataReader, NULL, CLSCTX_INPROC_SERVER, &IID_IWICMetadataReader, (void **)&reader); ok(hr == S_OK || broken(hr == E_NOINTERFACE || hr == REGDB_E_CLASSNOTREG) /* before Win7 */, - "CoCreateInstance error %#x\n", hr); + "CoCreateInstance error %#lx\n", hr); + if (FAILED(hr)) return; + + check_interface(reader, &IID_IWICMetadataReader, TRUE); + check_interface(reader, &IID_IPersist, TRUE); + check_interface(reader, &IID_IPersistStream, TRUE); + check_interface(reader, &IID_IWICPersistStream, TRUE); + check_interface(reader, &IID_IWICStreamProvider, TRUE); + + test_reader_container_format(reader, &GUID_ContainerFormatGif); stream = create_stream(GCE_data, sizeof(GCE_data)); - if (SUCCEEDED(hr)) - { - pos.QuadPart = 12; - hr = IStream_Seek(stream, pos, SEEK_SET, NULL); - ok(hr == S_OK, "IStream_Seek error %#x\n", hr); + pos.QuadPart = 12; + hr = IStream_Seek(stream, pos, SEEK_SET, NULL); + ok(hr == S_OK, "IStream_Seek error %#lx\n", hr); - hr = IUnknown_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist); - ok(hr == S_OK, "QueryInterface error %#x\n", hr); + hr = IUnknown_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist); + ok(hr == S_OK, "QueryInterface error %#lx\n", hr); - hr = IWICPersistStream_Load(persist, stream); - ok(hr == S_OK, "Load error %#x\n", hr); + hr = IWICPersistStream_Load(persist, stream); + ok(hr == S_OK, "Load error %#lx\n", hr); + todo_wine + check_persist_options(reader, 0); - IWICPersistStream_Release(persist); - } + IWICPersistStream_Release(persist); - if (SUCCEEDED(hr)) - { - hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); - ok(count == ARRAY_SIZE(td), "unexpected count %u\n", count); + hr = IWICMetadataReader_GetCount(reader, &count); + ok(hr == S_OK, "GetCount error %#lx\n", hr); + ok(count == ARRAY_SIZE(td), "unexpected count %u\n", count); - compare_metadata(reader, td, count); + compare_metadata(reader, td, count); - hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat error %#x\n", hr); - ok(IsEqualGUID(&format, &GUID_MetadataFormatGCE), "wrong format %s\n", wine_dbgstr_guid(&format)); + hr = IWICMetadataReader_GetMetadataFormat(reader, &format); + ok(hr == S_OK, "GetMetadataFormat error %#lx\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatGCE), "wrong format %s\n", wine_dbgstr_guid(&format)); - hr = IWICMetadataReader_GetMetadataHandlerInfo(reader, &info); - ok(hr == S_OK, "GetMetadataHandlerInfo error %#x\n", hr); + hr = IWICMetadataReader_GetMetadataHandlerInfo(reader, &info); + ok(hr == S_OK, "GetMetadataHandlerInfo error %#lx\n", hr); - hr = IWICMetadataHandlerInfo_GetCLSID(info, &id); - ok(hr == S_OK, "GetCLSID error %#x\n", hr); - ok(IsEqualGUID(&id, &CLSID_WICGCEMetadataReader), "wrong CLSID %s\n", wine_dbgstr_guid(&id)); + hr = IWICMetadataHandlerInfo_GetCLSID(info, &id); + ok(hr == S_OK, "GetCLSID error %#lx\n", hr); + ok(IsEqualGUID(&id, &CLSID_WICGCEMetadataReader), "wrong CLSID %s\n", wine_dbgstr_guid(&id)); - hr = IWICMetadataHandlerInfo_GetFriendlyName(info, 64, name, &dummy); - ok(hr == S_OK, "GetFriendlyName error %#x\n", hr); - ok(lstrcmpW(name, GCE_name) == 0, "wrong GCE reader name %s\n", wine_dbgstr_w(name)); + hr = IWICMetadataHandlerInfo_GetFriendlyName(info, 64, name, &dummy); + ok(hr == S_OK, "GetFriendlyName error %#lx\n", hr); + ok(!lstrcmpW(name, L"Graphic Control Extension Reader"), "wrong GCE reader name %s\n", wine_dbgstr_w(name)); - IWICMetadataHandlerInfo_Release(info); - IWICMetadataReader_Release(reader); - } + IWICMetadataHandlerInfo_Release(info); + IWICMetadataReader_Release(reader); IStream_Release(stream); + + hr = CoCreateInstance(&CLSID_WICGCEMetadataWriter, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataWriter, (void **)&writer); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) return; + + check_interface(writer, &IID_IWICMetadataWriter, TRUE); + check_interface(writer, &IID_IWICMetadataReader, TRUE); + check_interface(writer, &IID_IPersist, TRUE); + check_interface(writer, &IID_IPersistStream, TRUE); + check_interface(writer, &IID_IWICPersistStream, TRUE); + check_interface(writer, &IID_IWICStreamProvider, TRUE); + + load_stream(writer, GCE_data, sizeof(GCE_data), 0); + load_stream(writer, GCE_data, sizeof(GCE_data), WICPersistOptionNoCacheStream); + + IWICMetadataWriter_Release(writer); } static void test_metadata_APE(void) { - static const WCHAR APE_name[] = {'A','p','p','l','i','c','a','t','i','o','n',' ','E','x','t','e','n','s','i','o','n',' ','R','e','a','d','e','r',0}; static const char APE_data[] = { 0x21,0xff,0x0b,'H','e','l','l','o',' ','W','o','r','l','d', /*sub-block*/1,0x11, /*sub-block*/2,0x22,0x33, @@ -2008,14 +2824,15 @@ static void test_metadata_APE(void) /*terminator*/0 }; static const struct test_data td[2] = { - { VT_UI1|VT_VECTOR, 0, 11, { 'H','e','l','l','o',' ','W','o','r','l','d' }, NULL, { 'A','p','p','l','i','c','a','t','i','o','n',0 } }, - { VT_UI1|VT_VECTOR, 0, 10, { 1,0x11,2,0x22,0x33,4,0x44,0x55,0x66,0x77 }, NULL, { 'D','a','t','a',0 } } + { VT_UI1|VT_VECTOR, 0, 11, { 'H','e','l','l','o',' ','W','o','r','l','d' }, NULL, L"Application" }, + { VT_UI1|VT_VECTOR, 0, 10, { 1,0x11,2,0x22,0x33,4,0x44,0x55,0x66,0x77 }, NULL, L"Data" } }; WCHAR dataW[] = { 'd','a','t','a',0 }; HRESULT hr; IStream *stream; IWICPersistStream *persist; IWICMetadataReader *reader; + IWICMetadataWriter *writer; IWICMetadataHandlerInfo *info; WCHAR name[64]; UINT count, dummy, i; @@ -2026,66 +2843,88 @@ static void test_metadata_APE(void) hr = CoCreateInstance(&CLSID_WICAPEMetadataReader, NULL, CLSCTX_INPROC_SERVER, &IID_IWICMetadataReader, (void **)&reader); ok(hr == S_OK || broken(hr == E_NOINTERFACE || hr == REGDB_E_CLASSNOTREG) /* before Win7 */, - "CoCreateInstance error %#x\n", hr); + "CoCreateInstance error %#lx\n", hr); + if (FAILED(hr)) return; + + check_interface(reader, &IID_IWICMetadataReader, TRUE); + check_interface(reader, &IID_IPersist, TRUE); + check_interface(reader, &IID_IPersistStream, TRUE); + check_interface(reader, &IID_IWICPersistStream, TRUE); + check_interface(reader, &IID_IWICStreamProvider, TRUE); + + test_reader_container_format(reader, &GUID_ContainerFormatGif); stream = create_stream(APE_data, sizeof(APE_data)); - if (SUCCEEDED(hr)) - { - hr = IUnknown_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist); - ok(hr == S_OK, "QueryInterface error %#x\n", hr); + hr = IUnknown_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist); + ok(hr == S_OK, "QueryInterface error %#lx\n", hr); - hr = IWICPersistStream_Load(persist, stream); - ok(hr == S_OK, "Load error %#x\n", hr); + hr = IWICPersistStream_Load(persist, stream); + ok(hr == S_OK, "Load error %#lx\n", hr); + todo_wine + check_persist_options(reader, 0); - IWICPersistStream_Release(persist); - } + IWICPersistStream_Release(persist); - if (SUCCEEDED(hr)) - { - hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); - ok(count == ARRAY_SIZE(td), "unexpected count %u\n", count); + hr = IWICMetadataReader_GetCount(reader, &count); + ok(hr == S_OK, "GetCount error %#lx\n", hr); + ok(count == ARRAY_SIZE(td), "unexpected count %u\n", count); - compare_metadata(reader, td, count); + compare_metadata(reader, td, count); - hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat error %#x\n", hr); - ok(IsEqualGUID(&format, &GUID_MetadataFormatAPE), "wrong format %s\n", wine_dbgstr_guid(&format)); + hr = IWICMetadataReader_GetMetadataFormat(reader, &format); + ok(hr == S_OK, "GetMetadataFormat error %#lx\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatAPE), "wrong format %s\n", wine_dbgstr_guid(&format)); - PropVariantInit(&value); - id.vt = VT_LPWSTR; - U(id).pwszVal = dataW; - - hr = IWICMetadataReader_GetValue(reader, NULL, &id, &value); - ok(hr == S_OK, "GetValue error %#x\n", hr); - ok(value.vt == (VT_UI1|VT_VECTOR), "unexpected vt: %i\n", id.vt); - ok(td[1].count == U(value).caub.cElems, "expected cElems %d, got %d\n", td[1].count, U(value).caub.cElems); - for (i = 0; i < U(value).caub.cElems; i++) - ok(td[1].value[i] == U(value).caub.pElems[i], "%u: expected value %#x/%#x, got %#x\n", i, (ULONG)td[1].value[i], (ULONG)(td[1].value[i] >> 32), U(value).caub.pElems[i]); - PropVariantClear(&value); + PropVariantInit(&value); + id.vt = VT_LPWSTR; + id.pwszVal = dataW; + + hr = IWICMetadataReader_GetValue(reader, NULL, &id, &value); + ok(hr == S_OK, "GetValue error %#lx\n", hr); + ok(value.vt == (VT_UI1|VT_VECTOR), "unexpected vt: %i\n", id.vt); + ok(td[1].count == value.caub.cElems, "expected cElems %d, got %ld\n", td[1].count, value.caub.cElems); + for (i = 0; i < value.caub.cElems; i++) + ok(td[1].value[i] == value.caub.pElems[i], "%u: expected value %#I64x, got %#x\n", i, td[1].value[i], value.caub.pElems[i]); + PropVariantClear(&value); - hr = IWICMetadataReader_GetMetadataHandlerInfo(reader, &info); - ok(hr == S_OK, "GetMetadataHandlerInfo error %#x\n", hr); + hr = IWICMetadataReader_GetMetadataHandlerInfo(reader, &info); + ok(hr == S_OK, "GetMetadataHandlerInfo error %#lx\n", hr); - hr = IWICMetadataHandlerInfo_GetCLSID(info, &clsid); - ok(hr == S_OK, "GetCLSID error %#x\n", hr); - ok(IsEqualGUID(&clsid, &CLSID_WICAPEMetadataReader), "wrong CLSID %s\n", wine_dbgstr_guid(&clsid)); + hr = IWICMetadataHandlerInfo_GetCLSID(info, &clsid); + ok(hr == S_OK, "GetCLSID error %#lx\n", hr); + ok(IsEqualGUID(&clsid, &CLSID_WICAPEMetadataReader), "wrong CLSID %s\n", wine_dbgstr_guid(&clsid)); - hr = IWICMetadataHandlerInfo_GetFriendlyName(info, 64, name, &dummy); - ok(hr == S_OK, "GetFriendlyName error %#x\n", hr); - ok(lstrcmpW(name, APE_name) == 0, "wrong APE reader name %s\n", wine_dbgstr_w(name)); + hr = IWICMetadataHandlerInfo_GetFriendlyName(info, 64, name, &dummy); + ok(hr == S_OK, "GetFriendlyName error %#lx\n", hr); + ok(!lstrcmpW(name, L"Application Extension Reader"), "wrong APE reader name %s\n", wine_dbgstr_w(name)); - IWICMetadataHandlerInfo_Release(info); - IWICMetadataReader_Release(reader); - } + IWICMetadataHandlerInfo_Release(info); + IWICMetadataReader_Release(reader); IStream_Release(stream); + + hr = CoCreateInstance(&CLSID_WICAPEMetadataWriter, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataWriter, (void **)&writer); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) return; + + check_interface(writer, &IID_IWICMetadataWriter, TRUE); + check_interface(writer, &IID_IWICMetadataReader, TRUE); + check_interface(writer, &IID_IPersist, TRUE); + check_interface(writer, &IID_IPersistStream, TRUE); + check_interface(writer, &IID_IWICPersistStream, TRUE); + check_interface(writer, &IID_IWICStreamProvider, TRUE); + + load_stream(writer, APE_data, sizeof(APE_data), 0); + load_stream(writer, APE_data, sizeof(APE_data), WICPersistOptionNoCacheStream); + + IWICMetadataWriter_Release(writer); } static void test_metadata_GIF_comment(void) { - static const WCHAR GIF_comment_name[] = {'C','o','m','m','e','n','t',' ','E','x','t','e','n','s','i','o','n',' ','R','e','a','d','e','r',0}; static const char GIF_comment_data[] = { 0x21,0xfe, /*sub-block*/5,'H','e','l','l','o', /*sub-block*/1,' ', @@ -2093,13 +2932,14 @@ static void test_metadata_GIF_comment(void) /*terminator*/0 }; static const struct test_data td[1] = { - { VT_LPSTR, 0, 12, { 0 }, "Hello World!", { 'T','e','x','t','E','n','t','r','y',0 } } + { VT_LPSTR, 0, 12, { 0 }, "Hello World!", L"TextEntry" } }; - WCHAR text_entryW[] = { 'T','E','X','T','E','N','T','R','Y',0 }; + WCHAR text_entryW[] = L"TEXTENTRY"; HRESULT hr; IStream *stream; IWICPersistStream *persist; IWICMetadataReader *reader; + IWICMetadataWriter *writer; IWICMetadataHandlerInfo *info; WCHAR name[64]; UINT count, dummy; @@ -2110,65 +2950,86 @@ static void test_metadata_GIF_comment(void) hr = CoCreateInstance(&CLSID_WICGifCommentMetadataReader, NULL, CLSCTX_INPROC_SERVER, &IID_IWICMetadataReader, (void **)&reader); ok(hr == S_OK || broken(hr == E_NOINTERFACE || hr == REGDB_E_CLASSNOTREG) /* before Win7 */, - "CoCreateInstance error %#x\n", hr); + "CoCreateInstance error %#lx\n", hr); + if (FAILED(hr)) return; + + check_interface(reader, &IID_IWICMetadataReader, TRUE); + check_interface(reader, &IID_IPersist, TRUE); + check_interface(reader, &IID_IPersistStream, TRUE); + check_interface(reader, &IID_IWICPersistStream, TRUE); + check_interface(reader, &IID_IWICStreamProvider, TRUE); + + test_reader_container_format(reader, &GUID_ContainerFormatGif); stream = create_stream(GIF_comment_data, sizeof(GIF_comment_data)); - if (SUCCEEDED(hr)) - { - hr = IUnknown_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist); - ok(hr == S_OK, "QueryInterface error %#x\n", hr); + hr = IUnknown_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist); + ok(hr == S_OK, "QueryInterface error %#lx\n", hr); - hr = IWICPersistStream_Load(persist, stream); - ok(hr == S_OK, "Load error %#x\n", hr); + hr = IWICPersistStream_Load(persist, stream); + ok(hr == S_OK, "Load error %#lx\n", hr); + todo_wine + check_persist_options(reader, 0); - IWICPersistStream_Release(persist); - } + IWICPersistStream_Release(persist); - if (SUCCEEDED(hr)) - { - hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); - ok(count == ARRAY_SIZE(td), "unexpected count %u\n", count); + hr = IWICMetadataReader_GetCount(reader, &count); + ok(hr == S_OK, "GetCount error %#lx\n", hr); + ok(count == ARRAY_SIZE(td), "unexpected count %u\n", count); - compare_metadata(reader, td, count); + compare_metadata(reader, td, count); - hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat error %#x\n", hr); - ok(IsEqualGUID(&format, &GUID_MetadataFormatGifComment), "wrong format %s\n", wine_dbgstr_guid(&format)); + hr = IWICMetadataReader_GetMetadataFormat(reader, &format); + ok(hr == S_OK, "GetMetadataFormat error %#lx\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatGifComment), "wrong format %s\n", wine_dbgstr_guid(&format)); - PropVariantInit(&value); - id.vt = VT_LPWSTR; - U(id).pwszVal = text_entryW; + PropVariantInit(&value); + id.vt = VT_LPWSTR; + id.pwszVal = text_entryW; - hr = IWICMetadataReader_GetValue(reader, NULL, &id, &value); - ok(hr == S_OK, "GetValue error %#x\n", hr); - ok(value.vt == VT_LPSTR, "unexpected vt: %i\n", id.vt); - ok(!strcmp(U(value).pszVal, "Hello World!"), "unexpected value: %s\n", U(value).pszVal); - PropVariantClear(&value); + hr = IWICMetadataReader_GetValue(reader, NULL, &id, &value); + ok(hr == S_OK, "GetValue error %#lx\n", hr); + ok(value.vt == VT_LPSTR, "unexpected vt: %i\n", id.vt); + ok(!strcmp(value.pszVal, "Hello World!"), "unexpected value: %s\n", value.pszVal); + PropVariantClear(&value); - hr = IWICMetadataReader_GetMetadataHandlerInfo(reader, &info); - ok(hr == S_OK, "GetMetadataHandlerInfo error %#x\n", hr); + hr = IWICMetadataReader_GetMetadataHandlerInfo(reader, &info); + ok(hr == S_OK, "GetMetadataHandlerInfo error %#lx\n", hr); - hr = IWICMetadataHandlerInfo_GetCLSID(info, &clsid); - ok(hr == S_OK, "GetCLSID error %#x\n", hr); - ok(IsEqualGUID(&clsid, &CLSID_WICGifCommentMetadataReader), "wrong CLSID %s\n", wine_dbgstr_guid(&clsid)); + hr = IWICMetadataHandlerInfo_GetCLSID(info, &clsid); + ok(hr == S_OK, "GetCLSID error %#lx\n", hr); + ok(IsEqualGUID(&clsid, &CLSID_WICGifCommentMetadataReader), "wrong CLSID %s\n", wine_dbgstr_guid(&clsid)); - hr = IWICMetadataHandlerInfo_GetFriendlyName(info, 64, name, &dummy); - ok(hr == S_OK, "GetFriendlyName error %#x\n", hr); - ok(lstrcmpW(name, GIF_comment_name) == 0, "wrong APE reader name %s\n", wine_dbgstr_w(name)); + hr = IWICMetadataHandlerInfo_GetFriendlyName(info, 64, name, &dummy); + ok(hr == S_OK, "GetFriendlyName error %#lx\n", hr); + ok(!lstrcmpW(name, L"Comment Extension Reader"), "wrong APE reader name %s\n", wine_dbgstr_w(name)); - IWICMetadataHandlerInfo_Release(info); - IWICMetadataReader_Release(reader); - } + IWICMetadataHandlerInfo_Release(info); + IWICMetadataReader_Release(reader); IStream_Release(stream); + + hr = CoCreateInstance(&CLSID_WICGifCommentMetadataWriter, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataWriter, (void **)&writer); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) return; + + check_interface(writer, &IID_IWICMetadataWriter, TRUE); + check_interface(writer, &IID_IWICMetadataReader, TRUE); + check_interface(writer, &IID_IPersist, TRUE); + check_interface(writer, &IID_IPersistStream, TRUE); + check_interface(writer, &IID_IWICPersistStream, TRUE); + check_interface(writer, &IID_IWICStreamProvider, TRUE); + + load_stream(writer, GIF_comment_data, sizeof(GIF_comment_data), 0); + load_stream(writer, GIF_comment_data, sizeof(GIF_comment_data), WICPersistOptionNoCacheStream); + + IWICMetadataWriter_Release(writer); } static void test_WICMapGuidToShortName(void) { - static const WCHAR unkW[] = { 'u','n','k',0 }; - static const WCHAR unknownW[] = { 'u','n','k','n','o','w','n',0 }; HRESULT hr; UINT len; WCHAR name[16]; @@ -2176,84 +3037,80 @@ static void test_WICMapGuidToShortName(void) name[0] = 0; len = 0xdeadbeef; hr = WICMapGuidToShortName(&GUID_MetadataFormatUnknown, 8, name, &len); - ok(hr == S_OK, "got %#x\n", hr); + ok(hr == S_OK, "got %#lx\n", hr); ok(len == 8, "got %u\n", len); - ok(!lstrcmpW(name, unknownW), "got %s\n", wine_dbgstr_w(name)); + ok(!lstrcmpW(name, L"unknown"), "got %s\n", wine_dbgstr_w(name)); name[0] = 0; hr = WICMapGuidToShortName(&GUID_MetadataFormatUnknown, 8, name, NULL); - ok(hr == S_OK, "got %#x\n", hr); - ok(!lstrcmpW(name, unknownW), "got %s\n", wine_dbgstr_w(name)); + ok(hr == S_OK, "got %#lx\n", hr); + ok(!lstrcmpW(name, L"unknown"), "got %s\n", wine_dbgstr_w(name)); len = 0xdeadbeef; hr = WICMapGuidToShortName(&GUID_MetadataFormatUnknown, 8, NULL, &len); - ok(hr == S_OK, "got %#x\n", hr); + ok(hr == S_OK, "got %#lx\n", hr); ok(len == 8, "got %u\n", len); len = 0xdeadbeef; hr = WICMapGuidToShortName(&GUID_MetadataFormatUnknown, 0, NULL, &len); - ok(hr == S_OK, "got %#x\n", hr); + ok(hr == S_OK, "got %#lx\n", hr); ok(len == 8, "got %u\n", len); hr = WICMapGuidToShortName(&GUID_MetadataFormatUnknown, 0, NULL, NULL); - ok(hr == S_OK, "got %#x\n", hr); + ok(hr == S_OK, "got %#lx\n", hr); hr = WICMapGuidToShortName(&GUID_MetadataFormatUnknown, 8, NULL, NULL); - ok(hr == S_OK, "got %#x\n", hr); + ok(hr == S_OK, "got %#lx\n", hr); hr = WICMapGuidToShortName(&GUID_NULL, 0, NULL, NULL); - ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "got %#x\n", hr); + ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "got %#lx\n", hr); name[0] = 0; len = 0xdeadbeef; hr = WICMapGuidToShortName(&GUID_MetadataFormatUnknown, 4, name, &len); - ok(hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), "got %#x\n", hr); + ok(hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), "got %#lx\n", hr); ok(len == 0xdeadbeef, "got %u\n", len); - ok(!lstrcmpW(name, unkW), "got %s\n", wine_dbgstr_w(name)); + ok(!lstrcmpW(name, L"unk"), "got %s\n", wine_dbgstr_w(name)); name[0] = 0; len = 0xdeadbeef; hr = WICMapGuidToShortName(&GUID_MetadataFormatUnknown, 0, name, &len); - ok(hr == E_INVALIDARG, "got %#x\n", hr); + ok(hr == E_INVALIDARG, "got %#lx\n", hr); ok(len == 0xdeadbeef, "got %u\n", len); ok(!name[0], "got %s\n", wine_dbgstr_w(name)); hr = WICMapGuidToShortName(NULL, 8, name, NULL); - ok(hr == E_INVALIDARG, "got %#x\n", hr); + ok(hr == E_INVALIDARG, "got %#lx\n", hr); } static void test_WICMapShortNameToGuid(void) { - static const WCHAR unkW[] = { 'u','n','k',0 }; - static const WCHAR xmpW[] = { 'x','m','p',0 }; - static const WCHAR XmPW[] = { 'X','m','P',0 }; - static const WCHAR unknownW[] = { 'u','n','k','n','o','w','n',0 }; HRESULT hr; GUID guid; hr = WICMapShortNameToGuid(NULL, NULL); - ok(hr == E_INVALIDARG, "got %#x\n", hr); + ok(hr == E_INVALIDARG, "got %#lx\n", hr); hr = WICMapShortNameToGuid(NULL, &guid); - ok(hr == E_INVALIDARG, "got %#x\n", hr); + ok(hr == E_INVALIDARG, "got %#lx\n", hr); - hr = WICMapShortNameToGuid(unknownW, NULL); - ok(hr == E_INVALIDARG, "got %#x\n", hr); + hr = WICMapShortNameToGuid(L"unknown", NULL); + ok(hr == E_INVALIDARG, "got %#lx\n", hr); - hr = WICMapShortNameToGuid(unkW, &guid); - ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "got %#x\n", hr); + hr = WICMapShortNameToGuid(L"unk", &guid); + ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "got %#lx\n", hr); - hr = WICMapShortNameToGuid(unknownW, &guid); - ok(hr == S_OK, "got %#x\n", hr); + hr = WICMapShortNameToGuid(L"unknown", &guid); + ok(hr == S_OK, "got %#lx\n", hr); ok(IsEqualGUID(&guid, &GUID_MetadataFormatUnknown), "got %s\n", wine_dbgstr_guid(&guid)); - hr = WICMapShortNameToGuid(xmpW, &guid); - ok(hr == S_OK, "got %#x\n", hr); + hr = WICMapShortNameToGuid(L"xmp", &guid); + ok(hr == S_OK, "got %#lx\n", hr); ok(IsEqualGUID(&guid, &GUID_MetadataFormatXMP), "got %s\n", wine_dbgstr_guid(&guid)); guid = GUID_NULL; - hr = WICMapShortNameToGuid(XmPW, &guid); - ok(hr == S_OK, "got %#x\n", hr); + hr = WICMapShortNameToGuid(L"XmP", &guid); + ok(hr == S_OK, "got %#lx\n", hr); ok(IsEqualGUID(&guid, &GUID_MetadataFormatXMP), "got %s\n", wine_dbgstr_guid(&guid)); } @@ -2364,65 +3221,63 @@ static WCHAR *schema_list[] = static void test_WICMapSchemaToName(void) { - static const WCHAR xmW[] = { 'x','m',0 }; - static const WCHAR xmpW[] = { 'x','m','p',0 }; - static WCHAR schemaW[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/',0 }; - static WCHAR SCHEMAW[] = { 'H','T','T','P',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/',0 }; + static WCHAR schemaW[] = L"http://ns.adobe.com/xap/1.0/"; + static WCHAR SCHEMAW[] = L"HTTP://ns.adobe.com/xap/1.0/"; HRESULT hr; UINT len, i, j; WCHAR name[16]; hr = WICMapSchemaToName(&GUID_MetadataFormatUnknown, NULL, 0, NULL, NULL); - ok(hr == E_INVALIDARG, "got %#x\n", hr); + ok(hr == E_INVALIDARG, "got %#lx\n", hr); hr = WICMapSchemaToName(&GUID_MetadataFormatUnknown, schemaW, 0, NULL, NULL); - ok(hr == E_INVALIDARG, "got %#x\n", hr); + ok(hr == E_INVALIDARG, "got %#lx\n", hr); hr = WICMapSchemaToName(&GUID_MetadataFormatUnknown, schemaW, 0, NULL, &len); - ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "got %#x\n", hr); + ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "got %#lx\n", hr); hr = WICMapSchemaToName(NULL, schemaW, 0, NULL, &len); - ok(hr == E_INVALIDARG, "got %#x\n", hr); + ok(hr == E_INVALIDARG, "got %#lx\n", hr); hr = WICMapSchemaToName(&GUID_MetadataFormatXMP, schemaW, 0, NULL, NULL); - ok(hr == E_INVALIDARG, "got %#x\n", hr); + ok(hr == E_INVALIDARG, "got %#lx\n", hr); len = 0xdeadbeef; hr = WICMapSchemaToName(&GUID_MetadataFormatXMP, schemaW, 0, NULL, &len); - ok(hr == S_OK, "got %#x\n", hr); + ok(hr == S_OK, "got %#lx\n", hr); ok(len == 4, "got %u\n", len); len = 0xdeadbeef; hr = WICMapSchemaToName(&GUID_MetadataFormatXMP, schemaW, 4, NULL, &len); - ok(hr == S_OK, "got %#x\n", hr); + ok(hr == S_OK, "got %#lx\n", hr); ok(len == 4, "got %u\n", len); len = 0xdeadbeef; hr = WICMapSchemaToName(&GUID_MetadataFormatXMP, SCHEMAW, 0, NULL, &len); - ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "got %#x\n", hr); + ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "got %#lx\n", hr); ok(len == 0xdeadbeef, "got %u\n", len); name[0] = 0; len = 0xdeadbeef; hr = WICMapSchemaToName(&GUID_MetadataFormatXMP, schemaW, 4, name, &len); - ok(hr == S_OK, "got %#x\n", hr); + ok(hr == S_OK, "got %#lx\n", hr); ok(len == 4, "got %u\n", len); - ok(!lstrcmpW(name, xmpW), "got %s\n", wine_dbgstr_w(name)); + ok(!lstrcmpW(name, L"xmp"), "got %s\n", wine_dbgstr_w(name)); len = 0xdeadbeef; hr = WICMapSchemaToName(&GUID_MetadataFormatXMP, schemaW, 0, name, &len); - ok(hr == E_INVALIDARG, "got %#x\n", hr); + ok(hr == E_INVALIDARG, "got %#lx\n", hr); ok(len == 0xdeadbeef, "got %u\n", len); name[0] = 0; len = 0xdeadbeef; hr = WICMapSchemaToName(&GUID_MetadataFormatXMP, schemaW, 3, name, &len); - ok(hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), "got %#x\n", hr); + ok(hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), "got %#lx\n", hr); ok(len == 0xdeadbeef, "got %u\n", len); - ok(!lstrcmpW(name, xmW), "got %s\n", wine_dbgstr_w(name)); + ok(!lstrcmpW(name, L"xm"), "got %s\n", wine_dbgstr_w(name)); hr = WICMapSchemaToName(&GUID_MetadataFormatXMP, schemaW, 4, name, NULL); - ok(hr == E_INVALIDARG, "got %#x\n", hr); + ok(hr == E_INVALIDARG, "got %#lx\n", hr); /* Check whether modern schemas are supported */ hr = WICMapSchemaToName(&GUID_MetadataFormatXMP, schema_list[0], 0, NULL, &len); @@ -2480,8 +3335,6 @@ static char the_worst[] = "The Worst"; static HRESULT WINAPI mdr_QueryInterface(IWICMetadataReader *iface, REFIID iid, void **out) { - trace("%p,%s,%p\n", iface, wine_dbgstr_guid(iid), out); - if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IWICMetadataReader)) { @@ -2507,8 +3360,6 @@ static ULONG WINAPI mdr_Release(IWICMetadataReader *iface) static HRESULT WINAPI mdr_GetMetadataFormat(IWICMetadataReader *iface, GUID *format) { - trace("%p,%p\n", iface, format); - ok(current_metadata_block != NULL, "current_metadata_block can't be NULL\n"); if (!current_metadata_block) return E_POINTER; @@ -2524,8 +3375,6 @@ static HRESULT WINAPI mdr_GetMetadataHandlerInfo(IWICMetadataReader *iface, IWIC static HRESULT WINAPI mdr_GetCount(IWICMetadataReader *iface, UINT *count) { - trace("%p,%p\n", iface, count); - ok(current_metadata_block != NULL, "current_metadata_block can't be NULL\n"); if (!current_metadata_block) return E_POINTER; @@ -2533,50 +3382,10 @@ static HRESULT WINAPI mdr_GetCount(IWICMetadataReader *iface, UINT *count) return S_OK; } -static HRESULT WINAPI mdr_GetValueByIndex(IWICMetadataReader *iface, UINT index, PROPVARIANT *schema, PROPVARIANT *id, PROPVARIANT *value) -{ - ok(0, "not implemented\n"); - return E_NOTIMPL; -} - -static char *get_temp_buffer(int size) -{ - static char buf[16][256]; - static int idx; - char *p; - - assert(size < 256); - - p = buf[idx & 0x0f]; - idx++; - return p; -} - -static const char *wine_dbgstr_propvariant(const PROPVARIANT *var) +static HRESULT WINAPI mdr_GetValueByIndex(IWICMetadataReader *iface, UINT index, PROPVARIANT *schema, PROPVARIANT *id, PROPVARIANT *value) { - char *ret; - - if (!var) return "(null)"; - - switch (var->vt) - { - case VT_LPWSTR: - ret = get_temp_buffer(lstrlenW(U(*var).pwszVal) + 16); - sprintf(ret, "(VT_LPWSTR:%s)", wine_dbgstr_w(U(*var).pwszVal)); - break; - - case VT_LPSTR: - ret = get_temp_buffer(lstrlenA(U(*var).pszVal) + 16); - sprintf(ret, "(VT_LPSTR:%s)", U(*var).pszVal); - break; - - default: - ret = get_temp_buffer(16); - sprintf(ret, "(vt:%u)", var->vt); - break; - } - - return ret; + ok(0, "not implemented\n"); + return E_NOTIMPL; } static int propvar_cmp(const PROPVARIANT *v1, LONGLONG value2) @@ -2594,8 +3403,6 @@ static HRESULT WINAPI mdr_GetValue(IWICMetadataReader *iface, const PROPVARIANT { UINT i; - trace("%p,%s,%s,%s\n", iface, wine_dbgstr_propvariant(schema), wine_dbgstr_propvariant(id), wine_dbgstr_propvariant(value)); - ok(current_metadata_block != NULL, "current_metadata_block can't be NULL\n"); if (!current_metadata_block) return E_POINTER; @@ -2611,14 +3418,14 @@ static HRESULT WINAPI mdr_GetValue(IWICMetadataReader *iface, const PROPVARIANT switch (schema->vt) { case VT_LPSTR: - if (lstrcmpA(U(*schema).pszVal, current_metadata_block->item[i].schema) != 0) + if (lstrcmpA(schema->pszVal, current_metadata_block->item[i].schema) != 0) continue; break; case VT_LPWSTR: { char schemaA[256]; - WideCharToMultiByte(CP_ACP, 0, U(*schema).pwszVal, -1, schemaA, sizeof(schemaA), NULL, NULL); + WideCharToMultiByte(CP_ACP, 0, schema->pwszVal, -1, schemaA, sizeof(schemaA), NULL, NULL); if (lstrcmpA(schemaA, current_metadata_block->item[i].schema) != 0) continue; break; @@ -2637,10 +3444,10 @@ static HRESULT WINAPI mdr_GetValue(IWICMetadataReader *iface, const PROPVARIANT case VT_LPSTR: if (current_metadata_block->item[i].id_str) { - if (!lstrcmpA(U(*id).pszVal, current_metadata_block->item[i].id_str)) + if (!lstrcmpA(id->pszVal, current_metadata_block->item[i].id_str)) { value->vt = VT_LPSTR; - U(*value).pszVal = the_best; + value->pszVal = the_best; return S_OK; } break; @@ -2651,11 +3458,11 @@ static HRESULT WINAPI mdr_GetValue(IWICMetadataReader *iface, const PROPVARIANT if (current_metadata_block->item[i].id_str) { char idA[256]; - WideCharToMultiByte(CP_ACP, 0, U(*id).pwszVal, -1, idA, sizeof(idA), NULL, NULL); + WideCharToMultiByte(CP_ACP, 0, id->pwszVal, -1, idA, sizeof(idA), NULL, NULL); if (!lstrcmpA(idA, current_metadata_block->item[i].id_str)) { value->vt = VT_LPSTR; - U(*value).pszVal = the_worst; + value->pszVal = the_worst; return S_OK; } break; @@ -2663,8 +3470,8 @@ static HRESULT WINAPI mdr_GetValue(IWICMetadataReader *iface, const PROPVARIANT break; case VT_CLSID: - if (IsEqualGUID(U(*id).puuid, &GUID_MetadataFormatXMP) || - IsEqualGUID(U(*id).puuid, &GUID_ContainerFormatTiff)) + if (IsEqualGUID(id->puuid, &GUID_MetadataFormatXMP) || + IsEqualGUID(id->puuid, &GUID_ContainerFormatTiff)) { value->vt = VT_UNKNOWN; value->punkVal = (IUnknown *)iface; @@ -2676,7 +3483,7 @@ static HRESULT WINAPI mdr_GetValue(IWICMetadataReader *iface, const PROPVARIANT if (!propvar_cmp(id, current_metadata_block->item[i].id)) { value->vt = current_metadata_block->item[i].type; - U(*value).uiVal = current_metadata_block->item[i].value; + value->uiVal = current_metadata_block->item[i].value; return S_OK; } break; @@ -2736,8 +3543,6 @@ static ULONG WINAPI mdbr_Release(IWICMetadataBlockReader *iface) static HRESULT WINAPI mdbr_GetContainerFormat(IWICMetadataBlockReader *iface, GUID *format) { - trace("%p,%p\n", iface, format); - ok(current_metadata != NULL, "current_metadata can't be NULL\n"); if (!current_metadata) return E_POINTER; @@ -2747,8 +3552,6 @@ static HRESULT WINAPI mdbr_GetContainerFormat(IWICMetadataBlockReader *iface, GU static HRESULT WINAPI mdbr_GetCount(IWICMetadataBlockReader *iface, UINT *count) { - trace("%p,%p\n", iface, count); - ok(current_metadata != NULL, "current_metadata can't be NULL\n"); if (!current_metadata) return E_POINTER; @@ -2758,8 +3561,6 @@ static HRESULT WINAPI mdbr_GetCount(IWICMetadataBlockReader *iface, UINT *count) static HRESULT WINAPI mdbr_GetReaderByIndex(IWICMetadataBlockReader *iface, UINT index, IWICMetadataReader **out) { - trace("%p,%u,%p\n", iface, index, out); - *out = NULL; ok(current_metadata != NULL, "current_metadata can't be NULL\n"); @@ -2870,88 +3671,52 @@ static const struct metadata data3 = static void test_queryreader(void) { - static const char q1[] = "/ifd/{uchar=1}"; - static const char q2[] = "/ifd/xmp:{long=4}"; - static const char q3[] = "/ifd/{str=xmp}:{uint=4}"; - static const char q4[] = "/xmp/{char=7}"; - static const char q5[] = "/[1]xmp/{short=7}"; - static const char q6[] = "/[1]ifd/{str=dc}:{uint=7}"; - static const char q7[] = "/[1]ifd/{str=http://purl.org/dc/elements/1.1/}:{longlong=7}"; - static const char q8[] = "/[1]ifd/{str=http://ns.adobe.com/tiff/1.0/}:{int=10}"; - static const char q9[] = "/[2]xmp/xmp:{ulong=4}"; - static const char q10[] = "/[2]xmp/{str=xmp}:{ulong=4}"; - static const char q11[] = "/xmp"; - static const char q12[] = "/ifd/xmp"; - static const char q13[] = "/ifd/xmp/tiff"; - static const char q14[] = "/[0]ifd/[0]xmp/[0]tiff"; - static const char q15[] = "/[*]xmp"; - - static const char q20[] = "/ifd/\\Rating"; - static const char q21[] = "/[0]ifd/Rating"; - static const char q22[] = "/[2]xmp/xmp:{str=Rating}"; - static const char q23[] = "/[2]xmp/xmp:Rating"; - - static const char q24[] = "/[1]ifd/{str=http://ns.adobe.com/xap/1.0/}:Rating"; - static const char q25[] = "/[1]ifd/{str=http://ns.adobe.com/xap/1.0/}:{str=Rating}"; - static const char q26[] = "/[1]ifd/{wstr=\\RATING}"; - static const char q27[] = "/[1]ifd/{str=R\\ATING}"; - static const char q28[] = "/[1]ifd/{str=R\\}ATING}"; - - static const char q40[] = "[0]/ifd/Rating"; - static const char q41[] = "/[+1]ifd/Rating"; - static const char q42[] = "/[-1]ifd/Rating"; - static const char q43[] = "/ifd/{\\str=Rating}"; - static const char q44[] = "/ifd/{badtype=0}"; - static const char q45[] = "/ifd/{uint=0x1234}"; - static const char q46[] = "/ifd/[0]Rating"; - static const char q47[] = "/ifd/[*]Rating"; static const struct { BOOL todo; const struct metadata *data; - const char *query; + const WCHAR *query; HRESULT hr; UINT vt, value; const char *str_value; } test_data[] = { - { FALSE, &data1, q1, S_OK, 2, 3, NULL }, - { FALSE, &data2, q2, S_OK, 5, 6, NULL }, - { FALSE, &data2, q3, S_OK, 5, 6, NULL }, - { FALSE, &data3, q4, 0xdeadbeef }, - { FALSE, &data3, q5, S_OK, 8, 9, NULL }, - { FALSE, &data3, q6, 0xdeadbeef }, - { FALSE, &data3, q7, S_OK, 8, 9, NULL }, - { FALSE, &data3, q8, S_OK, 11, 12, NULL }, - { FALSE, &data3, q9, S_OK, 5, 6, NULL }, - { FALSE, &data3, q10, 0xdeadbeef }, - - { FALSE, &data3, q11, S_OK, VT_UNKNOWN, 0, NULL }, - { FALSE, &data3, q12, S_OK, VT_UNKNOWN, 0, NULL }, - { FALSE, &data3, q13, S_OK, VT_UNKNOWN, 0, NULL }, - { FALSE, &data3, q14, S_OK, VT_UNKNOWN, 0, NULL }, - { TRUE, &data3, q15, S_OK, VT_LPSTR, 0, the_worst }, - - { FALSE, &data3, q20, S_OK, VT_LPSTR, 0, the_worst }, - { FALSE, &data3, q21, S_OK, VT_LPSTR, 0, the_worst }, - { FALSE, &data3, q22, S_OK, VT_LPSTR, 0, the_best }, - { FALSE, &data3, q23, S_OK, VT_LPSTR, 0, the_worst }, - { FALSE, &data3, q24, S_OK, VT_LPSTR, 0, the_worst }, - { FALSE, &data3, q25, S_OK, VT_LPSTR, 0, the_best }, - { FALSE, &data3, q26, S_OK, VT_LPSTR, 0, the_worst }, - { FALSE, &data3, q27, S_OK, VT_LPSTR, 0, the_best }, - { FALSE, &data3, q28, S_OK, VT_LPSTR, 0, the_best }, - - { FALSE, &data1, q40, WINCODEC_ERR_PROPERTYNOTSUPPORTED }, - { TRUE, &data1, q41, WINCODEC_ERR_INVALIDQUERYCHARACTER }, - { TRUE, &data1, q42, WINCODEC_ERR_INVALIDQUERYCHARACTER }, - { FALSE, &data1, q43, WINCODEC_ERR_WRONGSTATE }, - { FALSE, &data1, q44, WINCODEC_ERR_WRONGSTATE }, - { TRUE, &data1, q45, DISP_E_TYPEMISMATCH }, - { TRUE, &data1, q46, E_INVALIDARG }, - { TRUE, &data1, q47, WINCODEC_ERR_REQUESTONLYVALIDATMETADATAROOT }, + { FALSE, &data1, L"/ifd/{uchar=1}", S_OK, 2, 3, NULL }, + { FALSE, &data2, L"/ifd/xmp:{long=4}", S_OK, 5, 6, NULL }, + { FALSE, &data2, L"/ifd/{str=xmp}:{uint=4}", S_OK, 5, 6, NULL }, + { FALSE, &data3, L"/xmp/{char=7}", 0xdeadbeef }, + { FALSE, &data3, L"/[1]xmp/{short=7}", S_OK, 8, 9, NULL }, + { FALSE, &data3, L"/[1]ifd/{str=dc}:{uint=7}", 0xdeadbeef }, + { FALSE, &data3, L"/[1]ifd/{str=http://purl.org/dc/elements/1.1/}:{longlong=7}", S_OK, 8, 9, NULL }, + { FALSE, &data3, L"/[1]ifd/{str=http://ns.adobe.com/tiff/1.0/}:{int=10}", S_OK, 11, 12, NULL }, + { FALSE, &data3, L"/[2]xmp/xmp:{ulong=4}", S_OK, 5, 6, NULL }, + { FALSE, &data3, L"/[2]xmp/{str=xmp}:{ulong=4}", 0xdeadbeef }, + + { FALSE, &data3, L"/xmp", S_OK, VT_UNKNOWN, 0, NULL }, + { FALSE, &data3, L"/ifd/xmp", S_OK, VT_UNKNOWN, 0, NULL }, + { FALSE, &data3, L"/ifd/xmp/tiff", S_OK, VT_UNKNOWN, 0, NULL }, + { FALSE, &data3, L"/[0]ifd/[0]xmp/[0]tiff", S_OK, VT_UNKNOWN, 0, NULL }, + { TRUE, &data3, L"/[*]xmp", S_OK, VT_LPSTR, 0, the_worst }, + + { FALSE, &data3, L"/ifd/\\Rating", S_OK, VT_LPSTR, 0, the_worst }, + { FALSE, &data3, L"/[0]ifd/Rating", S_OK, VT_LPSTR, 0, the_worst }, + { FALSE, &data3, L"/[2]xmp/xmp:{str=Rating}", S_OK, VT_LPSTR, 0, the_best }, + { FALSE, &data3, L"/[2]xmp/xmp:Rating", S_OK, VT_LPSTR, 0, the_worst }, + { FALSE, &data3, L"/[1]ifd/{str=http://ns.adobe.com/xap/1.0/}:Rating", S_OK, VT_LPSTR, 0, the_worst }, + { FALSE, &data3, L"/[1]ifd/{str=http://ns.adobe.com/xap/1.0/}:{str=Rating}", S_OK, VT_LPSTR, 0, the_best }, + { FALSE, &data3, L"/[1]ifd/{wstr=\\RATING}", S_OK, VT_LPSTR, 0, the_worst }, + { FALSE, &data3, L"/[1]ifd/{str=R\\ATING}", S_OK, VT_LPSTR, 0, the_best }, + { FALSE, &data3, L"/[1]ifd/{str=R\\}ATING}", S_OK, VT_LPSTR, 0, the_best }, + + { FALSE, &data1, L"[0]/ifd/Rating", WINCODEC_ERR_PROPERTYNOTSUPPORTED }, + { TRUE, &data1, L"/[+1]ifd/Rating", WINCODEC_ERR_INVALIDQUERYCHARACTER }, + { TRUE, &data1, L"/[-1]ifd/Rating", WINCODEC_ERR_INVALIDQUERYCHARACTER }, + { FALSE, &data1, L"/ifd/{\\str=Rating}", WINCODEC_ERR_WRONGSTATE }, + { FALSE, &data1, L"/ifd/{badtype=0}", WINCODEC_ERR_WRONGSTATE }, + { TRUE, &data1, L"/ifd/{uint=0x1234}", DISP_E_TYPEMISMATCH }, + { TRUE, &data1, L"/ifd/[0]Rating", E_INVALIDARG }, + { TRUE, &data1, L"/ifd/[*]Rating", WINCODEC_ERR_REQUESTONLYVALIDATMETADATAROOT }, }; - WCHAR queryW[256]; HRESULT hr; IWICComponentFactory *factory; IWICMetadataQueryReader *reader; @@ -2961,28 +3726,29 @@ static void test_queryreader(void) hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICComponentFactory, (void **)&factory); - ok(hr == S_OK, "CoCreateInstance error %#x\n", hr); + ok(hr == S_OK, "CoCreateInstance error %#lx\n", hr); hr = IWICComponentFactory_CreateQueryReaderFromBlockReader(factory, &mdbr, &reader); - ok(hr == S_OK, "CreateQueryReaderFromBlockReader error %#x\n", hr); + ok(hr == S_OK, "CreateQueryReaderFromBlockReader error %#lx\n", hr); for (i = 0; i < ARRAY_SIZE(test_data); i++) { + winetest_push_context("%u", i); + current_metadata = test_data[i].data; hr = IWICMetadataQueryReader_GetContainerFormat(reader, &format); - ok(hr == S_OK, "%u: GetContainerFormat error %#x\n", i, hr); - ok(IsEqualGUID(&format, test_data[i].data->container_format), "%u: expected %s, got %s\n", - i, wine_dbgstr_guid(test_data[i].data->container_format), wine_dbgstr_guid(&format)); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&format, test_data[i].data->container_format), "Expected %s, got %s.\n", + wine_dbgstr_guid(test_data[i].data->container_format), wine_dbgstr_guid(&format)); - MultiByteToWideChar(CP_ACP, 0, test_data[i].query, -1, queryW, 256); PropVariantInit(&value); - hr = IWICMetadataQueryReader_GetMetadataByName(reader, queryW, &value); + hr = IWICMetadataQueryReader_GetMetadataByName(reader, test_data[i].query, &value); todo_wine_if(test_data[i].todo) - ok(hr == test_data[i].hr, "%u: expected %#x, got %#x\n", i, test_data[i].hr, hr); + ok(hr == test_data[i].hr, "Expected %#lx, got %#lx.\n", test_data[i].hr, hr); if (hr == S_OK) { - ok(value.vt == test_data[i].vt, "%u: expected %u, got %u\n", i, test_data[i].vt, value.vt); + ok(value.vt == test_data[i].vt, "Expected %u, got %u.\n", test_data[i].vt, value.vt); if (test_data[i].vt == value.vt) { if (value.vt == VT_UNKNOWN) @@ -2992,66 +3758,718 @@ static void test_queryreader(void) UINT len; hr = IUnknown_QueryInterface(value.punkVal, &IID_IWICMetadataQueryReader, (void **)&new_reader); - ok(hr == S_OK, "QueryInterface error %#x\n", hr); + ok(hr == S_OK, "QueryInterface error %#lx\n", hr); location[0] = 0; len = 0xdeadbeef; hr = IWICMetadataQueryReader_GetLocation(new_reader, 256, location, &len); - ok(hr == S_OK, "GetLocation error %#x\n", hr); - ok(len == lstrlenW(queryW) + 1, "expected %u, got %u\n", lstrlenW(queryW) + 1, len); - ok(!lstrcmpW(location, queryW), "expected %s, got %s\n", wine_dbgstr_w(queryW), wine_dbgstr_w(location)); + ok(hr == S_OK, "GetLocation error %#lx\n", hr); + ok(len == lstrlenW(test_data[i].query) + 1, "expected %u, got %u\n", lstrlenW(test_data[i].query) + 1, len); + ok(!lstrcmpW(location, test_data[i].query), "expected %s, got %s\n", wine_dbgstr_w(test_data[i].query), wine_dbgstr_w(location)); hr = IWICMetadataQueryReader_GetLocation(new_reader, 256, location, NULL); - ok(hr == E_INVALIDARG, "got %#x\n", hr); + ok(hr == E_INVALIDARG, "got %#lx\n", hr); location[0] = 0; len = 0xdeadbeef; hr = IWICMetadataQueryReader_GetLocation(new_reader, 3, location, &len); - ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "got %#x\n", hr); + ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "got %#lx\n", hr); ok(len == 0xdeadbeef, "got %u\n", len); ok(!location[0], "got %s\n", wine_dbgstr_w(location)); location[0] = 0; len = 0xdeadbeef; hr = IWICMetadataQueryReader_GetLocation(new_reader, 0, location, &len); - ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "got %#x\n", hr); + ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "got %#lx\n", hr); ok(len == 0xdeadbeef, "got %u\n", len); ok(!location[0], "got %s\n", wine_dbgstr_w(location)); len = 0xdeadbeef; hr = IWICMetadataQueryReader_GetLocation(new_reader, 0, NULL, &len); - ok(hr == S_OK, "GetLocation error %#x\n", hr); - ok(len == lstrlenW(queryW) + 1, "expected %u, got %u\n", lstrlenW(queryW) + 1, len); + ok(hr == S_OK, "GetLocation error %#lx\n", hr); + ok(len == lstrlenW(test_data[i].query) + 1, "expected %u, got %u\n", lstrlenW(test_data[i].query) + 1, len); len = 0xdeadbeef; hr = IWICMetadataQueryReader_GetLocation(new_reader, 3, NULL, &len); - ok(hr == S_OK, "GetLocation error %#x\n", hr); - ok(len == lstrlenW(queryW) + 1, "expected %u, got %u\n", lstrlenW(queryW) + 1, len); + ok(hr == S_OK, "GetLocation error %#lx\n", hr); + ok(len == lstrlenW(test_data[i].query) + 1, "expected %u, got %u\n", lstrlenW(test_data[i].query) + 1, len); hr = IWICMetadataQueryReader_GetLocation(new_reader, 0, NULL, NULL); - ok(hr == E_INVALIDARG, "got %#x\n", hr); + ok(hr == E_INVALIDARG, "got %#lx\n", hr); IWICMetadataQueryReader_Release(new_reader); PropVariantClear(&value); } else if (value.vt == VT_LPSTR) - ok(!lstrcmpA(U(value).pszVal, test_data[i].str_value), "%u: expected %s, got %s\n", - i, test_data[i].str_value, U(value).pszVal); + ok(!lstrcmpA(value.pszVal, test_data[i].str_value), "Expected %s, got %s.\n", + test_data[i].str_value, value.pszVal); else - ok(U(value).uiVal == test_data[i].value, "%u: expected %u, got %u\n", - i, test_data[i].value, U(value).uiVal); + ok(value.uiVal == test_data[i].value, "Expected %u, got %u\n", + test_data[i].value, value.uiVal); } /* * Do NOT call PropVariantClear(&value) for fake value types. */ } + + winetest_pop_context(); } IWICMetadataQueryReader_Release(reader); IWICComponentFactory_Release(factory); } +static void test_metadata_writer(void) +{ + static struct + { + REFCLSID rclsid; + BOOL wine_supports_encoder; + BOOL metadata_supported; + BOOL succeeds_uninitialized; + } + tests[] = + { + {&CLSID_WICBmpEncoder, TRUE, FALSE}, + {&CLSID_WICPngEncoder, TRUE, TRUE}, + {&CLSID_WICJpegEncoder, TRUE, TRUE}, + {&CLSID_WICGifEncoder, TRUE, TRUE}, + {&CLSID_WICTiffEncoder, TRUE, TRUE}, + {&CLSID_WICWmpEncoder, FALSE, TRUE, TRUE}, + }; + + IWICMetadataQueryWriter *querywriter, *querywriter2; + IWICMetadataBlockWriter *blockwriter; + IWICBitmapFrameEncode *frameencode; + IWICComponentFactory *factory; + IWICBitmapEncoder *encoder; + IEnumString *enumstring; + LPOLESTR olestring; + ULONG ref, count; + IStream *stream; + unsigned int i; + HRESULT hr; + + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + winetest_push_context("%u", i); + + hr = CoCreateInstance(tests[i].rclsid, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICBitmapEncoder, (void **)&encoder); + todo_wine_if(!tests[i].wine_supports_encoder) ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + if (FAILED(hr)) + { + winetest_pop_context(); + continue; + } + + blockwriter = NULL; + querywriter = querywriter2 = NULL; + + hr = CreateStreamOnHGlobal(NULL, TRUE, &stream); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + hr = IWICBitmapEncoder_Initialize(encoder, stream, WICBitmapEncoderNoCache); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + hr = IWICBitmapEncoder_CreateNewFrame(encoder, &frameencode, NULL); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + hr = IWICBitmapFrameEncode_QueryInterface(frameencode, &IID_IWICMetadataBlockWriter, (void**)&blockwriter); + ok(hr == (tests[i].metadata_supported ? S_OK : E_NOINTERFACE), "Got unexpected hr %#lx.\n", hr); + + hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICComponentFactory, (void**)&factory); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + hr = IWICComponentFactory_CreateQueryWriterFromBlockWriter(factory, blockwriter, &querywriter); + ok(hr == (tests[i].metadata_supported ? S_OK : E_INVALIDARG), "Got unexpected hr %#lx.\n", hr); + + hr = IWICBitmapFrameEncode_GetMetadataQueryWriter(frameencode, &querywriter2); + ok(hr == (tests[i].succeeds_uninitialized ? S_OK : WINCODEC_ERR_NOTINITIALIZED), + "Got unexpected hr %#lx.\n", hr); + if (hr == S_OK) + IWICMetadataQueryWriter_Release(querywriter2); + + hr = IWICBitmapFrameEncode_Initialize(frameencode, NULL); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + hr = IWICBitmapFrameEncode_GetMetadataQueryWriter(frameencode, &querywriter2); + ok(hr == (tests[i].metadata_supported ? S_OK : WINCODEC_ERR_UNSUPPORTEDOPERATION), + "Got unexpected hr %#lx.\n", hr); + + if (tests[i].metadata_supported) + ok(querywriter2 != querywriter, "Got unexpected interfaces %p, %p.\n", querywriter, querywriter2); + + IWICComponentFactory_Release(factory); + if (querywriter) + { + ref = get_refcount(querywriter); + ok(ref == 1, "Got unexpected ref %lu.\n", ref); + + hr = IWICMetadataQueryWriter_QueryInterface(querywriter, &IID_IEnumString, (void **)&enumstring); + ok(hr == E_NOINTERFACE, "Got unexpected hr %#lx.\n", hr); + + hr = IWICMetadataQueryWriter_GetEnumerator(querywriter, &enumstring); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + ref = get_refcount(querywriter); + ok(ref == 1, "Got unexpected ref %lu.\n", ref); + + hr = IEnumString_Skip(enumstring, 0); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + count = 0xdeadbeef; + hr = IEnumString_Next(enumstring, 0, NULL, &count); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + ok(count == 0xdeadbeef, "Got unexpected count %lu.\n", count); + + hr = IEnumString_Next(enumstring, 0, &olestring, &count); + ok(hr == S_OK || hr == WINCODEC_ERR_VALUEOUTOFRANGE, "Got unexpected hr %#lx.\n", hr); + + count = 0xdeadbeef; + hr = IEnumString_Next(enumstring, 1, &olestring, &count); + ok(hr == S_OK || hr == S_FALSE, "Got unexpected hr %#lx, i %u.\n", hr, i); + ok((hr && !count) || (!hr && count == 1), "Got unexpected hr %#lx, count %lu.\n", hr, count); + if (count) + { + CoTaskMemFree(olestring); + + /* IEnumString_Skip() crashes at least on Win7 when + * trying to skip past the string count. */ + hr = IEnumString_Reset(enumstring); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + hr = IEnumString_Skip(enumstring, 1); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + } + IEnumString_Release(enumstring); + + IWICMetadataQueryWriter_Release(querywriter); + IWICMetadataQueryWriter_Release(querywriter2); + IWICMetadataBlockWriter_Release(blockwriter); + } + IWICBitmapFrameEncode_Release(frameencode); + IStream_Release(stream); + IWICBitmapEncoder_Release(encoder); + + winetest_pop_context(); + } +} + +#include "pshpack2.h" +static const struct app1_data +{ + BYTE exif_header[6]; + BYTE bom[2]; + USHORT marker; + ULONG ifd0_offset; + + USHORT ifd0_count; + struct IFD_entry ifd0[4]; + ULONG next_IFD; + + USHORT exif_ifd_count; + struct IFD_entry exif_ifd[1]; + ULONG next_IFD_2; + + USHORT gps_ifd_count; + struct IFD_entry gps_ifd[1]; + ULONG next_IFD_3; +} +app1_data = +{ + { 'E','x','i','f',0,0 }, + { 'I','I' }, + 0x002a, + 0x8, + + /* IFD 0 */ + 4, + { + { 0x100, IFD_LONG, 1, 222 }, /* IMAGEWIDTH */ + { 0x101, IFD_LONG, 1, 333 }, /* IMAGELENGTH */ + /* Exif IFD pointer */ + { 0x8769, IFD_LONG, 1, FIELD_OFFSET(struct app1_data, exif_ifd_count) - 6 }, + /* GPS IFD pointer */ + { 0x8825, IFD_LONG, 1, FIELD_OFFSET(struct app1_data, gps_ifd_count) - 6 }, + }, + 0, + + /* Exif IFD */ + 1, + { + { 0x200, IFD_SHORT, 1, 444 }, + }, + 0, + + /* GPS IFD */ + 1, + { + { 0x300, IFD_SHORT, 1, 555 }, + }, + 0, +}; +#include "poppack.h" + +static void test_metadata_App1(void) +{ + IWICMetadataReader *reader, *ifd_reader, *exif_reader, *gps_reader; + IStream *app1_stream, *stream2; + IWICMetadataWriter *writer; + PROPVARIANT id, value; + GUID format; + HRESULT hr; + UINT count; + + hr = CoCreateInstance(&CLSID_WICApp1MetadataReader, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataReader, (void **)&reader); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) return; + + check_interface(reader, &IID_IWICMetadataReader, TRUE); + check_interface(reader, &IID_IPersist, TRUE); + check_interface(reader, &IID_IPersistStream, TRUE); + check_interface(reader, &IID_IWICPersistStream, TRUE); + check_interface(reader, &IID_IWICStreamProvider, TRUE); + check_interface(reader, &IID_IWICMetadataBlockReader, FALSE); + + hr = IWICMetadataReader_GetCount(reader, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + + count = 1; + hr = IWICMetadataReader_GetCount(reader, &count); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!count, "Unexpected count %u.\n", count); + + hr = IWICMetadataReader_GetMetadataFormat(reader, &format); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatApp1), "Unexpected format %s.\n", wine_dbgstr_guid(&format)); + + test_reader_container_format(reader, &GUID_ContainerFormatJpeg); + + load_stream(reader, (const char *)&app1_data, sizeof(app1_data), 0); + check_persist_options(reader, 0); + hr = get_persist_stream(reader, &app1_stream); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IWICMetadataReader_GetCount(reader, &count); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(count == 1, "Unexpected count %u.\n", count); + + PropVariantInit(&id); + PropVariantInit(&value); + hr = IWICMetadataReader_GetValueByIndex(reader, 0, NULL, &id, &value); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + /* Top level IFD reader. */ + ok(id.vt == VT_UI2, "Unexpected id type: %u.\n", id.vt); + ok(id.uiVal == 0, "Unexpected id %u.\n", id.uiVal); + + ok(value.vt == VT_UNKNOWN, "Unexpected value type: %u.\n", value.vt); + ok(!!value.punkVal, "Unexpected value.\n"); + + hr = IUnknown_QueryInterface(value.punkVal, &IID_IWICMetadataReader, (void **)&ifd_reader); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + PropVariantClear(&value); + + hr = IWICMetadataReader_GetMetadataFormat(ifd_reader, &format); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatIfd), "Unexpected format %s.\n", wine_dbgstr_guid(&format)); + check_persist_options(ifd_reader, 0); + + hr = get_persist_stream(ifd_reader, &stream2); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!!stream2 && stream2 != app1_stream, "Unexpected stream %p.\n", stream2); + IStream_Release(stream2); + + hr = IWICMetadataReader_GetCount(ifd_reader, &count); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(count == 4, "Unexpected count %u.\n", count); + + PropVariantInit(&id); + PropVariantInit(&value); + hr = IWICMetadataReader_GetValueByIndex(ifd_reader, 0, NULL, &id, &value); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + ok(id.vt == VT_UI2, "Unexpected id type: %u.\n", id.vt); + ok(id.uiVal == 0x100, "Unexpected id %#x.\n", id.uiVal); + ok(value.vt == VT_UI4, "Unexpected value type: %u.\n", value.vt); + ok(value.ulVal == 222, "Unexpected value %lu.\n", value.ulVal); + + PropVariantInit(&id); + PropVariantInit(&value); + hr = IWICMetadataReader_GetValueByIndex(ifd_reader, 1, NULL, &id, &value); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + ok(id.vt == VT_UI2, "Unexpected id type: %u.\n", id.vt); + ok(id.uiVal == 0x101, "Unexpected id %#x.\n", id.uiVal); + ok(value.vt == VT_UI4, "Unexpected value type: %u.\n", value.vt); + ok(value.ulVal == 333, "Unexpected value %lu.\n", value.ulVal); + + PropVariantInit(&id); + PropVariantInit(&value); + hr = IWICMetadataReader_GetValueByIndex(ifd_reader, 2, NULL, &id, &value); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + ok(id.vt == VT_UI2, "Unexpected id type: %u.\n", id.vt); + ok(id.uiVal == 0x8769, "Unexpected id %#x.\n", id.uiVal); + ok(value.vt == VT_UNKNOWN, "Unexpected value type: %u.\n", value.vt); + hr = IUnknown_QueryInterface(value.punkVal, &IID_IWICMetadataReader, (void **)&exif_reader); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + PropVariantClear(&value); + + /* Exif IFD */ + hr = IWICMetadataReader_GetMetadataFormat(exif_reader, &format); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatExif), "Unexpected format %s.\n", wine_dbgstr_guid(&format)); + check_persist_options(exif_reader, 0); + + hr = get_persist_stream(exif_reader, &stream2); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!!stream2 && stream2 != app1_stream, "Unexpected stream.\n"); + IStream_Release(stream2); + + hr = IWICMetadataReader_GetCount(exif_reader, &count); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(count == 1, "Unexpected count %u.\n", count); + + PropVariantInit(&id); + PropVariantInit(&value); + hr = IWICMetadataReader_GetValueByIndex(exif_reader, 0, NULL, &id, &value); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + ok(id.vt == VT_UI2, "Unexpected id type: %u.\n", id.vt); + ok(id.uiVal == 0x200, "Unexpected id %#x.\n", id.uiVal); + ok(value.vt == VT_UI2, "Unexpected value type: %u.\n", value.vt); + ok(value.ulVal == 444, "Unexpected value %lu.\n", value.ulVal); + + PropVariantInit(&id); + PropVariantInit(&value); + hr = IWICMetadataReader_GetValueByIndex(ifd_reader, 3, NULL, &id, &value); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + ok(id.vt == VT_UI2, "Unexpected id type: %u.\n", id.vt); + ok(id.uiVal == 0x8825, "Unexpected id %#x.\n", id.uiVal); + ok(value.vt == VT_UNKNOWN, "Unexpected value type: %u.\n", value.vt); + hr = IUnknown_QueryInterface(value.punkVal, &IID_IWICMetadataReader, (void **)&gps_reader); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + PropVariantClear(&value); + + /* GPS IFD */ + hr = IWICMetadataReader_GetMetadataFormat(gps_reader, &format); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatGps), "Unexpected format %s.\n", wine_dbgstr_guid(&format)); + check_persist_options(gps_reader, 0); + + hr = get_persist_stream(gps_reader, &stream2); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!!stream2 && stream2 != app1_stream, "Unexpected stream.\n"); + IStream_Release(stream2); + + hr = IWICMetadataReader_GetCount(gps_reader, &count); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(count == 1, "Unexpected count %u.\n", count); + + PropVariantInit(&id); + PropVariantInit(&value); + hr = IWICMetadataReader_GetValueByIndex(gps_reader, 0, NULL, &id, &value); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + ok(id.vt == VT_UI2, "Unexpected id type: %u.\n", id.vt); + ok(id.uiVal == 0x300, "Unexpected id %#x.\n", id.uiVal); + ok(value.vt == VT_UI2, "Unexpected value type: %u.\n", value.vt); + ok(value.ulVal == 555, "Unexpected value %lu.\n", value.ulVal); + + IWICMetadataReader_Release(gps_reader); + IWICMetadataReader_Release(exif_reader); + IWICMetadataReader_Release(ifd_reader); + + IStream_Release(app1_stream); + IWICMetadataReader_Release(reader); + + hr = CoCreateInstance(&CLSID_WICApp1MetadataWriter, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataWriter, (void **)&writer); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) return; + + check_interface(writer, &IID_IWICMetadataWriter, TRUE); + check_interface(writer, &IID_IWICMetadataReader, TRUE); + check_interface(writer, &IID_IPersist, TRUE); + check_interface(writer, &IID_IPersistStream, TRUE); + check_interface(writer, &IID_IWICPersistStream, TRUE); + check_interface(writer, &IID_IWICStreamProvider, TRUE); + + IWICMetadataWriter_Release(writer); +} + +static void test_CreateMetadataWriterFromReader(void) +{ + IWICComponentFactory *factory; + IWICMetadataReader *reader; + IWICMetadataWriter *writer; + IStream *stream, *stream2; + PROPVARIANT id, value; + GUID format; + HRESULT hr; + UINT count; + char *data; + + hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICComponentFactory, (void **)&factory); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + /* tEXt, uninitialized */ + hr = IWICComponentFactory_CreateMetadataReader(factory, &GUID_MetadataFormatChunktEXt, + NULL, 0, NULL, &reader); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + check_persist_options(reader, 0); + + hr = IWICComponentFactory_CreateMetadataWriterFromReader(factory, reader, NULL, &writer); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) + { + IWICMetadataReader_Release(reader); + IWICComponentFactory_Release(factory); + return; + } + + IWICMetadataReader_Release(reader); + + check_persist_options(writer, 0); + IWICMetadataWriter_Release(writer); + + /* tEXt, loaded */ + stream = create_stream(metadata_tEXt, sizeof(metadata_tEXt)); + hr = IWICComponentFactory_CreateMetadataReader(factory, &GUID_MetadataFormatChunktEXt, + NULL, 0, stream, &reader); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + check_persist_options(reader, 0); + IStream_Release(stream); + + hr = IWICComponentFactory_CreateMetadataWriterFromReader(factory, NULL, NULL, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + + hr = IWICComponentFactory_CreateMetadataWriterFromReader(factory, NULL, NULL, &writer); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + + hr = IWICComponentFactory_CreateMetadataWriterFromReader(factory, reader, NULL, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + + expect_ref(reader, 1); + hr = IWICComponentFactory_CreateMetadataWriterFromReader(factory, reader, NULL, &writer); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + expect_ref(reader, 1); + + hr = IWICMetadataReader_GetCount(reader, &count); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(count == 1, "Unexpected count %u.\n", count); + + PropVariantInit(&id); + PropVariantInit(&value); + hr = IWICMetadataReader_GetValueByIndex(reader, 0, NULL, &id, &value); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(id.vt == VT_LPSTR, "Unexpected id type %u.\n", id.vt); + ok(!strcmp(id.pszVal, "winetest"), "Unexpected id %s.\n", wine_dbgstr_a(id.pszVal)); + ok(value.vt == VT_LPSTR, "Unexpected value type %u.\n", value.vt); + ok(!strcmp(value.pszVal, "value"), "Unexpected value %s.\n", wine_dbgstr_a(value.pszVal)); + PropVariantClear(&id); + PropVariantClear(&value); + + hr = IWICMetadataWriter_GetMetadataFormat(writer, &format); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatChunktEXt), "Unexpected format %s.\n", wine_dbgstr_guid(&format)); + + hr = IWICMetadataWriter_GetCount(writer, &count); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(count == 1, "Unexpected count %u.\n", count); + + PropVariantInit(&id); + PropVariantInit(&value); + hr = IWICMetadataWriter_GetValueByIndex(writer, 0, NULL, &id, &value); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(id.vt == VT_LPSTR, "Unexpected id type %u.\n", id.vt); + ok(!strcmp(id.pszVal, "winetest"), "Unexpected id %s.\n", wine_dbgstr_a(id.pszVal)); + ok(value.vt == VT_LPSTR, "Unexpected value type %u.\n", value.vt); + ok(!strcmp(value.pszVal, "value"), "Unexpected value %s.\n", wine_dbgstr_a(value.pszVal)); + PropVariantClear(&id); + PropVariantClear(&value); + + IWICMetadataWriter_Release(writer); + IWICMetadataReader_Release(reader); + + /* App1 reader */ + stream = create_stream((const char *)&app1_data, sizeof(app1_data)); + hr = IWICComponentFactory_CreateMetadataReader(factory, &GUID_MetadataFormatApp1, + NULL, 0, stream, &reader); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IWICComponentFactory_CreateMetadataWriterFromReader(factory, reader, NULL, &writer); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IWICMetadataReader_GetMetadataFormat(reader, &format); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatApp1), "Unexpected format %s.\n", wine_dbgstr_guid(&format)); + + hr = IWICMetadataWriter_GetCount(writer, &count); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(count == 1, "Unexpected count %u.\n", count); + + PropVariantInit(&id); + PropVariantInit(&value); + hr = IWICMetadataReader_GetValueByIndex(reader, 0, NULL, &id, &value); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(id.vt == VT_UI2, "Unexpected id type %u.\n", id.vt); + ok(value.vt == VT_UNKNOWN, "Unexpected value type %u.\n", value.vt); + check_interface(value.punkVal, &IID_IWICMetadataReader, TRUE); + check_interface(value.punkVal, &IID_IWICMetadataWriter, FALSE); + PropVariantClear(&value); + + hr = IWICMetadataWriter_GetMetadataFormat(writer, &format); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatApp1), "Unexpected format %s.\n", wine_dbgstr_guid(&format)); + + hr = IWICMetadataWriter_GetCount(writer, &count); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(count == 1, "Unexpected count %u.\n", count); + + PropVariantInit(&id); + PropVariantInit(&value); + hr = IWICMetadataWriter_GetValueByIndex(writer, 0, NULL, &id, &value); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(id.vt == VT_UI2, "Unexpected id type %u.\n", id.vt); + ok(value.vt == VT_UNKNOWN, "Unexpected value type %u.\n", value.vt); + check_interface(value.punkVal, &IID_IWICMetadataReader, TRUE); + check_interface(value.punkVal, &IID_IWICMetadataWriter, TRUE); + check_persist_options(value.punkVal, 0); + PropVariantClear(&value); + + hr = get_persist_stream(writer, &stream2); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(stream2 != stream, "Unexpected stream.\n"); + IStream_Release(stream2); + + IWICMetadataWriter_Release(writer); + IWICMetadataReader_Release(reader); + IStream_Release(stream); + + /* Big-endian IFD */ + data = malloc(sizeof(IFD_data)); + memcpy(data, &IFD_data, sizeof(IFD_data)); + byte_swap_ifd_data(data); + + hr = IWICComponentFactory_CreateMetadataReader(factory, &GUID_MetadataFormatIfd, + NULL, 0, NULL, &reader); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + load_stream(reader, data, sizeof(IFD_data), WICPersistOptionBigEndian); + check_persist_options(reader, WICPersistOptionBigEndian); + free(data); + + hr = IWICComponentFactory_CreateMetadataWriterFromReader(factory, reader, NULL, &writer); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + check_persist_options(writer, WICPersistOptionBigEndian); + IWICMetadataWriter_Release(writer); + + IWICMetadataReader_Release(reader); + + IWICComponentFactory_Release(factory); +} + +static void test_CreateMetadataWriter(void) +{ + static const struct options_test + { + const GUID *clsid; + DWORD options; + } + options_tests[] = + { + { &GUID_MetadataFormatApp1, WICPersistOptionBigEndian }, + { &GUID_MetadataFormatIfd, WICPersistOptionBigEndian }, + { &GUID_MetadataFormatChunktEXt, WICPersistOptionBigEndian }, + { &GUID_MetadataFormatApp1, WICPersistOptionNoCacheStream }, + { &GUID_MetadataFormatIfd, WICPersistOptionNoCacheStream }, + { &GUID_MetadataFormatChunktEXt, WICPersistOptionNoCacheStream }, + { &GUID_MetadataFormatApp1, 0x100 }, + }; + IWICStreamProvider *stream_provider; + IWICComponentFactory *factory; + IWICMetadataWriter *writer; + IStream *stream; + unsigned int i; + GUID format; + HRESULT hr; + + hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICComponentFactory, (void **)&factory); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + for (i = 0; i < ARRAY_SIZE(options_tests); ++i) + { + const struct options_test *test = &options_tests[i]; + + hr = IWICComponentFactory_CreateMetadataWriter(factory, test->clsid, NULL, test->options, &writer); + todo_wine + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + } + + hr = IWICComponentFactory_CreateMetadataWriter(factory, &GUID_MetadataFormatChunktEXt, NULL, 0, &writer); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) + { + IWICComponentFactory_Release(factory); + return; + } + check_persist_options(writer, 0); + + hr = IWICMetadataWriter_QueryInterface(writer, &IID_IWICStreamProvider, (void **)&stream_provider); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + stream = (void *)0xdeadbeef; + hr = IWICStreamProvider_GetStream(stream_provider, &stream); + ok(hr == WINCODEC_ERR_STREAMNOTAVAILABLE, "Unexpected hr %#lx.\n", hr); + ok(stream == (void *)0xdeadbeef, "Unexpected stream.\n"); + + IWICStreamProvider_Release(stream_provider); + + hr = IWICMetadataWriter_GetMetadataFormat(writer, &format); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatChunktEXt), "Unexpected format %s.\n", wine_dbgstr_guid(&format)); + + IWICMetadataWriter_Release(writer); + + /* Invalid format */ + hr = IWICComponentFactory_CreateMetadataWriter(factory, &IID_IUnknown, NULL, 0, &writer); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IWICMetadataWriter_GetMetadataFormat(writer, &format); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatUnknown), "Unexpected format %s.\n", wine_dbgstr_guid(&format)); + IWICMetadataWriter_Release(writer); + + writer = (void *)0xdeadbeef; + hr = IWICComponentFactory_CreateMetadataWriter(factory, &IID_IUnknown, NULL, WICMetadataCreationFailUnknown, &writer); + ok(hr == WINCODEC_ERR_COMPONENTNOTFOUND, "Unexpected hr %#lx.\n", hr); + ok(writer == (void *)0xdeadbeef, "Unexpected pointer.\n"); + + /* App1 */ + hr = IWICComponentFactory_CreateMetadataWriter(factory, &GUID_MetadataFormatApp1, NULL, 0, &writer); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + check_persist_options(writer, 0); + IWICMetadataWriter_Release(writer); + + /* Ifd */ + hr = IWICComponentFactory_CreateMetadataWriter(factory, &GUID_MetadataFormatIfd, NULL, 0, &writer); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + check_persist_options(writer, 0); + IWICMetadataWriter_Release(writer); + + IWICComponentFactory_Release(factory); +} + START_TEST(metadata) { CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); @@ -3064,9 +4482,13 @@ START_TEST(metadata) test_metadata_tEXt(); test_metadata_gAMA(); test_metadata_cHRM(); - test_metadata_IFD(); + test_metadata_hIST(); + test_metadata_tIME(); + test_metadata_Ifd(); test_metadata_Exif(); - test_create_reader(); + test_metadata_Gps(); + test_create_reader_from_container(); + test_CreateMetadataReader(); test_metadata_png(); test_metadata_gif(); test_metadata_LSD(); @@ -3074,6 +4496,10 @@ START_TEST(metadata) test_metadata_GCE(); test_metadata_APE(); test_metadata_GIF_comment(); + test_metadata_writer(); + test_metadata_App1(); + test_CreateMetadataWriterFromReader(); + test_CreateMetadataWriter(); CoUninitialize(); } diff --git a/modules/rostests/winetests/windowscodecs/palette.c b/modules/rostests/winetests/windowscodecs/palette.c index 583fa66c80e27..85860b3d03b2b 100644 --- a/modules/rostests/winetests/windowscodecs/palette.c +++ b/modules/rostests/winetests/windowscodecs/palette.c @@ -40,172 +40,172 @@ static void test_custom_palette(void) BOOL boolresult; hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(SUCCEEDED(hr), "CreatePalette failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreatePalette failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICPalette_GetType(palette, &type); - ok(SUCCEEDED(hr), "GetType failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetType failed, hr=%lx\n", hr); ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %x\n", type); hr = IWICPalette_GetColorCount(palette, &count); - ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColorCount failed, hr=%lx\n", hr); ok(count == 0, "expected 0, got %u\n", count); hr = IWICPalette_GetColors(palette, 0, colors, &count); - ok(SUCCEEDED(hr), "GetColors failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColors failed, hr=%lx\n", hr); ok(count == 0, "expected 0, got %u\n", count); hr = IWICPalette_GetColors(palette, 4, colors, &count); - ok(SUCCEEDED(hr), "GetColors failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColors failed, hr=%lx\n", hr); ok(count == 0, "expected 0, got %u\n", count); memcpy(colors, initcolors, sizeof(initcolors)); hr = IWICPalette_InitializeCustom(palette, colors, 4); - ok(SUCCEEDED(hr), "InitializeCustom failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "InitializeCustom failed, hr=%lx\n", hr); hr = IWICPalette_GetType(palette, &type); - ok(SUCCEEDED(hr), "GetType failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetType failed, hr=%lx\n", hr); ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %x\n", type); hr = IWICPalette_GetColorCount(palette, &count); - ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColorCount failed, hr=%lx\n", hr); ok(count == 4, "expected 4, got %u\n", count); memset(colors, 0, sizeof(colors)); count = 0; hr = IWICPalette_GetColors(palette, 4, colors, &count); - ok(SUCCEEDED(hr), "GetColors failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColors failed, hr=%lx\n", hr); ok(count == 4, "expected 4, got %u\n", count); ok(!memcmp(colors, initcolors, sizeof(colors)), "got unexpected palette data\n"); memset(colors, 0, sizeof(colors)); count = 0; hr = IWICPalette_GetColors(palette, 2, colors, &count); - ok(SUCCEEDED(hr), "GetColors failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColors failed, hr=%lx\n", hr); ok(count == 2, "expected 2, got %u\n", count); ok(!memcmp(colors, initcolors, sizeof(WICColor)*2), "got unexpected palette data\n"); count = 0; hr = IWICPalette_GetColors(palette, 6, colors, &count); - ok(SUCCEEDED(hr), "GetColors failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColors failed, hr=%lx\n", hr); ok(count == 4, "expected 4, got %u\n", count); hr = IWICPalette_HasAlpha(palette, &boolresult); - ok(SUCCEEDED(hr), "HasAlpha failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "HasAlpha failed, hr=%lx\n", hr); ok(!boolresult, "expected FALSE, got TRUE\n"); hr = IWICPalette_IsBlackWhite(palette, &boolresult); - ok(SUCCEEDED(hr), "IsBlackWhite failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "IsBlackWhite failed, hr=%lx\n", hr); ok(!boolresult, "expected FALSE, got TRUE\n"); hr = IWICPalette_IsGrayscale(palette, &boolresult); - ok(SUCCEEDED(hr), "IsGrayscale failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "IsGrayscale failed, hr=%lx\n", hr); ok(!boolresult, "expected FALSE, got TRUE\n"); hr = IWICImagingFactory_CreatePalette(factory, &palette2); - ok(SUCCEEDED(hr), "CreatePalette failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreatePalette failed, hr=%lx\n", hr); hr = IWICPalette_InitializeFromPalette(palette2, palette); - ok(SUCCEEDED(hr), "InitializeFromPalette failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "InitializeFromPalette failed, hr=%lx\n", hr); type = 0xdeadbeef; hr = IWICPalette_GetType(palette2, &type); - ok(SUCCEEDED(hr), "GetType failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetType failed, hr=%lx\n", hr); ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %x\n", type); count = 0xdeadbeef; hr = IWICPalette_GetColorCount(palette2, &count); - ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColorCount failed, hr=%lx\n", hr); ok(count == 4, "expected 4, got %u\n", count); memset(colors, 0, sizeof(colors)); count = 0xdeadbeef; hr = IWICPalette_GetColors(palette2, 4, colors, &count); - ok(SUCCEEDED(hr), "GetColors failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColors failed, hr=%lx\n", hr); ok(count == 4, "expected 4, got %u\n", count); ok(!memcmp(colors, initcolors, sizeof(colors)), "got unexpected palette data\n"); /* try a palette with some alpha in it */ colors[2] = 0x80ffffff; hr = IWICPalette_InitializeCustom(palette, colors, 4); - ok(SUCCEEDED(hr), "InitializeCustom failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "InitializeCustom failed, hr=%lx\n", hr); hr = IWICPalette_HasAlpha(palette, &boolresult); - ok(SUCCEEDED(hr), "HasAlpha failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "HasAlpha failed, hr=%lx\n", hr); ok(boolresult, "expected TRUE, got FALSE\n"); /* setting to a 0-color palette is acceptable */ hr = IWICPalette_InitializeCustom(palette, NULL, 0); - ok(SUCCEEDED(hr), "InitializeCustom failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "InitializeCustom failed, hr=%lx\n", hr); type = 0xdeadbeef; hr = IWICPalette_GetType(palette, &type); - ok(SUCCEEDED(hr), "GetType failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetType failed, hr=%lx\n", hr); ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %x\n", type); count = 0xdeadbeef; hr = IWICPalette_GetColorCount(palette, &count); - ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColorCount failed, hr=%lx\n", hr); ok(count == 0, "expected 0, got %u\n", count); count = 0xdeadbeef; hr = IWICPalette_GetColors(palette, 4, colors, &count); - ok(SUCCEEDED(hr), "GetColors failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColors failed, hr=%lx\n", hr); ok(count == 0, "expected 0, got %u\n", count); hr = IWICPalette_InitializeFromPalette(palette2, palette); - ok(SUCCEEDED(hr), "InitializeFromPalette failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "InitializeFromPalette failed, hr=%lx\n", hr); type = 0xdeadbeef; hr = IWICPalette_GetType(palette2, &type); - ok(SUCCEEDED(hr), "GetType failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetType failed, hr=%lx\n", hr); ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %x\n", type); count = 0xdeadbeef; hr = IWICPalette_GetColorCount(palette2, &count); - ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColorCount failed, hr=%lx\n", hr); ok(count == 0, "expected 0, got %u\n", count); memset(colors, 0, sizeof(colors)); count = 0xdeadbeef; hr = IWICPalette_GetColors(palette2, 4, colors, &count); - ok(SUCCEEDED(hr), "GetColors failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColors failed, hr=%lx\n", hr); ok(count == 0, "expected 0, got %u\n", count); /* IWICPalette is paranoid about NULL pointers */ hr = IWICPalette_GetType(palette, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %lx\n", hr); hr = IWICPalette_GetColorCount(palette, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %lx\n", hr); hr = IWICPalette_InitializeCustom(palette, NULL, 4); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %lx\n", hr); hr = IWICPalette_GetColors(palette, 4, NULL, &count); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %lx\n", hr); hr = IWICPalette_GetColors(palette, 4, colors, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %lx\n", hr); hr = IWICPalette_HasAlpha(palette, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %lx\n", hr); hr = IWICPalette_IsBlackWhite(palette, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %lx\n", hr); hr = IWICPalette_IsGrayscale(palette, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %lx\n", hr); hr = IWICPalette_InitializeFromPalette(palette, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %lx\n", hr); IWICPalette_Release(palette2); IWICPalette_Release(palette); } } -static void generate_gray16_palette(DWORD *entries, UINT count) +static void generate_gray16_palette(WICColor *entries, UINT count) { UINT i; @@ -218,7 +218,7 @@ static void generate_gray16_palette(DWORD *entries, UINT count) } } -static void generate_gray256_palette(DWORD *entries, UINT count) +static void generate_gray256_palette(WICColor *entries, UINT count) { UINT i; @@ -231,7 +231,7 @@ static void generate_gray256_palette(DWORD *entries, UINT count) } } -static void generate_halftone8_palette(DWORD *entries, UINT count, BOOL add_transparent) +static void generate_halftone8_palette(WICColor *entries, UINT count, BOOL add_transparent) { UINT i; @@ -260,7 +260,7 @@ static void generate_halftone8_palette(DWORD *entries, UINT count, BOOL add_tran entries[i] = 0; } -static void generate_halftone27_palette(DWORD *entries, UINT count, BOOL add_transparent) +static void generate_halftone27_palette(WICColor *entries, UINT count, BOOL add_transparent) { static const BYTE halftone_values[4] = { 0x00,0x80,0xff }; UINT i; @@ -283,7 +283,7 @@ static void generate_halftone27_palette(DWORD *entries, UINT count, BOOL add_tra entries[i] = 0; } -static void generate_halftone64_palette(DWORD *entries, UINT count, BOOL add_transparent) +static void generate_halftone64_palette(WICColor *entries, UINT count, BOOL add_transparent) { static const BYTE halftone_values[4] = { 0x00,0x55,0xaa,0xff }; UINT i; @@ -313,7 +313,7 @@ static void generate_halftone64_palette(DWORD *entries, UINT count, BOOL add_tra entries[i] = 0; } -static void generate_halftone125_palette(DWORD *entries, UINT count, BOOL add_transparent) +static void generate_halftone125_palette(WICColor *entries, UINT count, BOOL add_transparent) { static const BYTE halftone_values[5] = { 0x00, 0x40, 0x80, 0xbf, 0xff }; UINT i; @@ -336,7 +336,7 @@ static void generate_halftone125_palette(DWORD *entries, UINT count, BOOL add_tr entries[i] = 0; } -static void generate_halftone216_palette(DWORD *entries, UINT count, BOOL add_transparent) +static void generate_halftone216_palette(WICColor *entries, UINT count, BOOL add_transparent) { static const BYTE halftone_values[6] = { 0x00,0x33,0x66,0x99,0xcc,0xff }; UINT i; @@ -366,7 +366,7 @@ static void generate_halftone216_palette(DWORD *entries, UINT count, BOOL add_tr entries[i] = 0; } -static void generate_halftone252_palette(DWORD *entries, UINT count, BOOL add_transparent) +static void generate_halftone252_palette(WICColor *entries, UINT count, BOOL add_transparent) { static const BYTE halftone_values_rb[6] = { 0x00,0x33,0x66,0x99,0xcc,0xff }; static const BYTE halftone_values_g[7] = { 0x00,0x2b,0x55,0x80,0xaa,0xd5,0xff }; @@ -389,7 +389,7 @@ static void generate_halftone252_palette(DWORD *entries, UINT count, BOOL add_tr entries[i] = 0; } -static void generate_halftone256_palette(DWORD *entries, UINT count, BOOL add_transparent) +static void generate_halftone256_palette(WICColor *entries, UINT count, BOOL add_transparent) { static const BYTE halftone_values_b[4] = { 0x00,0x55,0xaa,0xff }; static const BYTE halftone_values_gr[8] = { 0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff }; @@ -453,47 +453,47 @@ static void test_predefined_palette(void) WICColor color[256]; hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "CreatePalette error %#x\n", hr); + ok(hr == S_OK, "CreatePalette error %#lx\n", hr); hr = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeCustom, FALSE); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeMedianCut, FALSE); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICPalette_InitializePredefined(palette, 0x0f, FALSE); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); IWICPalette_Release(palette); for (i = 0; i < ARRAY_SIZE(td); i++) { hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "%u: CreatePalette error %#x\n", i, hr); + ok(hr == S_OK, "%u: CreatePalette error %#lx\n", i, hr); hr = IWICPalette_InitializePredefined(palette, td[i].type, td[i].add_transparent); - ok(hr == S_OK, "%u: InitializePredefined error %#x\n", i, hr); + ok(hr == S_OK, "%u: InitializePredefined error %#lx\n", i, hr); bret = -1; hr = IWICPalette_IsBlackWhite(palette, &bret); - ok(hr == S_OK, "%u: IsBlackWhite error %#x\n", i, hr); + ok(hr == S_OK, "%u: IsBlackWhite error %#lx\n", i, hr); ok(bret == td[i].is_bw || broken(td[i].type == WICBitmapPaletteTypeFixedBW && bret != td[i].is_bw), /* XP */ "%u: expected %d, got %d\n",i, td[i].is_bw, bret); bret = -1; hr = IWICPalette_IsGrayscale(palette, &bret); - ok(hr == S_OK, "%u: IsGrayscale error %#x\n", i, hr); + ok(hr == S_OK, "%u: IsGrayscale error %#lx\n", i, hr); ok(bret == td[i].is_gray, "%u: expected %d, got %d\n", i, td[i].is_gray, bret); type = -1; hr = IWICPalette_GetType(palette, &type); - ok(hr == S_OK, "%u: GetType error %#x\n", i, hr); + ok(hr == S_OK, "%u: GetType error %#lx\n", i, hr); ok(type == td[i].type, "%u: expected %#x, got %#x\n", i, td[i].type, type); count = 0xdeadbeef; hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "%u: GetColorCount error %#x\n", i, hr); + ok(hr == S_OK, "%u: GetColorCount error %#lx\n", i, hr); ok(count == td[i].count, "%u: expected %u, got %u\n", i, td[i].count, count); hr = IWICPalette_GetColors(palette, count, color, &ret); - ok(hr == S_OK, "%u: GetColors error %#x\n", i, hr); + ok(hr == S_OK, "%u: GetColors error %#lx\n", i, hr); ok(ret == count, "%u: expected %u, got %u\n", i, count, ret); if (ret == td[i].count) { @@ -571,68 +571,68 @@ static void test_palette_from_bitmap(void) hr = IWICImagingFactory_CreateBitmapFromMemory(factory, width, height, &GUID_WICPixelFormat24bppRGB, stride, stride * height, data, &bitmap); - ok(hr == S_OK, "CreateBitmapFromMemory error %#x\n", hr); + ok(hr == S_OK, "CreateBitmapFromMemory error %#lx\n", hr); hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "CreatePalette error %#x\n", hr); + ok(hr == S_OK, "CreatePalette error %#lx\n", hr); hr = IWICPalette_InitializeFromBitmap(palette, (IWICBitmapSource *)bitmap, 0, FALSE); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICPalette_InitializeFromBitmap(palette, (IWICBitmapSource *)bitmap, 1, FALSE); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICPalette_InitializeFromBitmap(palette, (IWICBitmapSource *)bitmap, 257, FALSE); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICPalette_InitializeFromBitmap(palette, NULL, 16, FALSE); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICPalette_InitializeFromBitmap(palette, (IWICBitmapSource *)bitmap, 2, FALSE); - ok(hr == S_OK, "InitializeFromBitmap error %#x\n", hr); + ok(hr == S_OK, "InitializeFromBitmap error %#lx\n", hr); count = 0; hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 2, "expected 2, got %u\n", count); hr = IWICPalette_InitializeFromBitmap(palette, (IWICBitmapSource *)bitmap, 2, TRUE); - ok(hr == S_OK, "InitializeFromBitmap error %#x\n", hr); + ok(hr == S_OK, "InitializeFromBitmap error %#lx\n", hr); count = 0; hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 2, "expected 2, got %u\n", count); /* without transparent color */ hr = IWICPalette_InitializeFromBitmap(palette, (IWICBitmapSource *)bitmap, 16, FALSE); - ok(hr == S_OK, "InitializeFromBitmap error %#x\n", hr); + ok(hr == S_OK, "InitializeFromBitmap error %#lx\n", hr); type = -1; hr = IWICPalette_GetType(palette, &type); - ok(hr == S_OK, "GetType error %#x\n", hr); + ok(hr == S_OK, "GetType error %#lx\n", hr); ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %#x\n", type); count = 0; hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 16, "expected 16, got %u\n", count); memset(color, 0, sizeof(color)); hr = IWICPalette_GetColors(palette, count, color, &ret); - ok(hr == S_OK, "GetColors error %#x\n", hr); + ok(hr == S_OK, "GetColors error %#lx\n", hr); ok(ret == count, "expected %u, got %u\n", count, ret); ok(color[count - 1] != 0, "expected !0, got %08x\n", color[count - 1]); /* with transparent color */ hr = IWICPalette_InitializeFromBitmap(palette, (IWICBitmapSource *)bitmap, 16, TRUE); - ok(hr == S_OK, "InitializeFromBitmap error %#x\n", hr); + ok(hr == S_OK, "InitializeFromBitmap error %#lx\n", hr); type = -1; hr = IWICPalette_GetType(palette, &type); - ok(hr == S_OK, "GetType error %#x\n", hr); + ok(hr == S_OK, "GetType error %#lx\n", hr); ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %#x\n", type); count = 0; hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 16, "expected 16, got %u\n", count); memset(color, 0xff, sizeof(color)); hr = IWICPalette_GetColors(palette, count, color, &ret); - ok(hr == S_OK, "GetColors error %#x\n", hr); + ok(hr == S_OK, "GetColors error %#lx\n", hr); ok(ret == count, "expected %u, got %u\n", count, ret); ok(color[count - 1] == 0, "expected 0, got %08x\n", color[count - 1]); @@ -650,7 +650,7 @@ START_TEST(palette) hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void **)&factory); - ok(hr == S_OK, "CoCreateInstance error %#x\n", hr); + ok(hr == S_OK, "CoCreateInstance error %#lx\n", hr); test_custom_palette(); test_predefined_palette(); diff --git a/modules/rostests/winetests/windowscodecs/pngformat.c b/modules/rostests/winetests/windowscodecs/pngformat.c index 8c33d3b9645eb..ca5a220d40d6a 100644 --- a/modules/rostests/winetests/windowscodecs/pngformat.c +++ b/modules/rostests/winetests/windowscodecs/pngformat.c @@ -294,14 +294,14 @@ static HRESULT create_decoder(const void *image_data, UINT image_size, IWICBitma if (hr == S_OK) { hr = IWICBitmapDecoder_GetContainerFormat(*decoder, &format); - ok(hr == S_OK, "GetContainerFormat error %#x\n", hr); + ok(hr == S_OK, "GetContainerFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_ContainerFormatPng), "wrong container format %s\n", wine_dbgstr_guid(&format)); zero.QuadPart = 0; IStream_Seek (stream, zero, STREAM_SEEK_CUR, &pos); - ok(pos.QuadPart < image_size, "seek beyond the end of stream: %x%08x >= %x\n", - (UINT)(pos.QuadPart >> 32), (UINT)pos.QuadPart, image_size); + ok(pos.QuadPart < image_size, "seek beyond the end of stream: %I64x >= %x\n", + pos.QuadPart, image_size); refcount = IStream_Release(stream); ok(refcount > 0, "expected stream refcount > 0\n"); @@ -346,182 +346,182 @@ static void test_color_contexts(void) BOOL ret; hr = create_decoder(png_no_color_profile, sizeof(png_no_color_profile), &decoder); - ok(hr == S_OK, "Failed to load PNG image data %#x\n", hr); + ok(hr == S_OK, "Failed to load PNG image data %#lx\n", hr); if (hr != S_OK) return; /* global color context */ hr = IWICBitmapDecoder_GetColorContexts(decoder, 0, NULL, NULL); - ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "GetColorContexts error %#x\n", hr); + ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "GetColorContexts error %#lx\n", hr); count = 0xdeadbeef; hr = IWICBitmapDecoder_GetColorContexts(decoder, 0, NULL, &count); - ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "GetColorContexts error %#x\n", hr); + ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "GetColorContexts error %#lx\n", hr); ok(count == 0xdeadbeef, "unexpected count %u\n", count); /* frame color context */ hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICBitmapFrameDecode_GetColorContexts(frame, 0, NULL, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); count = 0xdeadbeef; hr = IWICBitmapFrameDecode_GetColorContexts(frame, 0, NULL, &count); - ok(hr == S_OK, "GetColorContexts error %#x\n", hr); + ok(hr == S_OK, "GetColorContexts error %#lx\n", hr); ok(!count, "unexpected count %u\n", count); IWICBitmapFrameDecode_Release(frame); IWICBitmapDecoder_Release(decoder); hr = create_decoder(png_color_profile, sizeof(png_color_profile), &decoder); - ok(hr == S_OK, "Failed to load PNG image data %#x\n", hr); + ok(hr == S_OK, "Failed to load PNG image data %#lx\n", hr); if (hr != S_OK) return; /* global color context */ count = 0xdeadbeef; hr = IWICBitmapDecoder_GetColorContexts(decoder, 0, NULL, &count); - ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "GetColorContexts error %#x\n", hr); + ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "GetColorContexts error %#lx\n", hr); ok(count == 0xdeadbeef, "unexpected count %u\n", count); /* frame color context */ hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); count = 0xdeadbeef; hr = IWICBitmapFrameDecode_GetColorContexts(frame, 0, NULL, &count); - ok(hr == S_OK, "GetColorContexts error %#x\n", hr); + ok(hr == S_OK, "GetColorContexts error %#lx\n", hr); ok(count == 1, "unexpected count %u\n", count); hr = IWICImagingFactory_CreateColorContext(factory, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICImagingFactory_CreateColorContext(factory, &context); - ok(hr == S_OK, "CreateColorContext error %#x\n", hr); + ok(hr == S_OK, "CreateColorContext error %#lx\n", hr); hr = IWICColorContext_GetType(context, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); type = 0xdeadbeef; hr = IWICColorContext_GetType(context, &type); - ok(hr == S_OK, "GetType error %#x\n", hr); + ok(hr == S_OK, "GetType error %#lx\n", hr); ok(type == WICColorContextUninitialized, "unexpected type %u\n", type); hr = IWICColorContext_GetProfileBytes(context, 0, NULL, NULL); - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "GetProfileBytes error %#x\n", hr); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "GetProfileBytes error %#lx\n", hr); size = 0; hr = IWICColorContext_GetProfileBytes(context, 0, NULL, &size); - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "GetProfileBytes error %#x\n", hr); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "GetProfileBytes error %#lx\n", hr); ok(!size, "unexpected size %u\n", size); hr = IWICColorContext_GetExifColorSpace(context, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); colorspace = 0xdeadbeef; hr = IWICColorContext_GetExifColorSpace(context, &colorspace); - ok(hr == S_OK, "GetExifColorSpace error %#x\n", hr); + ok(hr == S_OK, "GetExifColorSpace error %#lx\n", hr); ok(colorspace == 0xffffffff, "unexpected color space %u\n", colorspace); hr = IWICColorContext_InitializeFromExifColorSpace(context, 0); - ok(hr == S_OK, "InitializeFromExifColorSpace error %#x\n", hr); + ok(hr == S_OK, "InitializeFromExifColorSpace error %#lx\n", hr); hr = IWICColorContext_InitializeFromExifColorSpace(context, 1); - ok(hr == S_OK, "InitializeFromExifColorSpace error %#x\n", hr); + ok(hr == S_OK, "InitializeFromExifColorSpace error %#lx\n", hr); hr = IWICColorContext_InitializeFromExifColorSpace(context, 2); - ok(hr == S_OK, "InitializeFromExifColorSpace error %#x\n", hr); + ok(hr == S_OK, "InitializeFromExifColorSpace error %#lx\n", hr); colorspace = 0xdeadbeef; hr = IWICColorContext_GetExifColorSpace(context, &colorspace); - ok(hr == S_OK, "GetExifColorSpace error %#x\n", hr); + ok(hr == S_OK, "GetExifColorSpace error %#lx\n", hr); ok(colorspace == 2, "unexpected color space %u\n", colorspace); size = 0; hr = IWICColorContext_GetProfileBytes(context, 0, NULL, &size); - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "GetProfileBytes error %#x\n", hr); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "GetProfileBytes error %#lx\n", hr); ok(!size, "unexpected size %u\n", size); type = 0xdeadbeef; hr = IWICColorContext_GetType(context, &type); - ok(hr == S_OK, "GetType error %#x\n", hr); + ok(hr == S_OK, "GetType error %#lx\n", hr); ok(type == WICColorContextExifColorSpace, "unexpected type %u\n", type); hr = IWICBitmapFrameDecode_GetColorContexts(frame, count, &context, &count); - ok(hr == WINCODEC_ERR_WRONGSTATE, "GetColorContexts error %#x\n", hr); + ok(hr == WINCODEC_ERR_WRONGSTATE, "GetColorContexts error %#lx\n", hr); IWICColorContext_Release(context); IWICBitmapFrameDecode_Release(frame); hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICImagingFactory_CreateColorContext(factory, &context); - ok(hr == S_OK, "CreateColorContext error %#x\n", hr); + ok(hr == S_OK, "CreateColorContext error %#lx\n", hr); count = 1; hr = IWICBitmapFrameDecode_GetColorContexts(frame, count, &context, &count); - ok(hr == S_OK, "GetColorContexts error %#x\n", hr); + ok(hr == S_OK, "GetColorContexts error %#lx\n", hr); hr = IWICColorContext_GetProfileBytes(context, 0, NULL, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); size = 0; hr = IWICColorContext_GetProfileBytes(context, 0, NULL, &size); - ok(hr == S_OK, "GetProfileBytes error %#x\n", hr); + ok(hr == S_OK, "GetProfileBytes error %#lx\n", hr); ok(size, "unexpected size %u\n", size); buffer = HeapAlloc(GetProcessHeap(), 0, size); hr = IWICColorContext_GetProfileBytes(context, size, buffer, &size); - ok(hr == S_OK, "GetProfileBytes error %#x\n", hr); + ok(hr == S_OK, "GetProfileBytes error %#lx\n", hr); tmpfile = save_profile( buffer, size ); HeapFree(GetProcessHeap(), 0, buffer); type = 0xdeadbeef; hr = IWICColorContext_GetType(context, &type); - ok(hr == S_OK, "GetType error %#x\n", hr); + ok(hr == S_OK, "GetType error %#lx\n", hr); ok(type == WICColorContextProfile, "unexpected type %u\n", type); colorspace = 0xdeadbeef; hr = IWICColorContext_GetExifColorSpace(context, &colorspace); - ok(hr == S_OK, "GetExifColorSpace error %#x\n", hr); + ok(hr == S_OK, "GetExifColorSpace error %#lx\n", hr); ok(colorspace == 0xffffffff, "unexpected color space %u\n", colorspace); hr = IWICColorContext_InitializeFromExifColorSpace(context, 1); - ok(hr == WINCODEC_ERR_WRONGSTATE, "InitializeFromExifColorSpace error %#x\n", hr); + ok(hr == WINCODEC_ERR_WRONGSTATE, "InitializeFromExifColorSpace error %#lx\n", hr); if (tmpfile) { hr = IWICColorContext_InitializeFromFilename(context, NULL); - ok(hr == E_INVALIDARG, "InitializeFromFilename error %#x\n", hr); + ok(hr == E_INVALIDARG, "InitializeFromFilename error %#lx\n", hr); hr = IWICColorContext_InitializeFromFilename(context, tmpfile); - ok(hr == S_OK, "InitializeFromFilename error %#x\n", hr); + ok(hr == S_OK, "InitializeFromFilename error %#lx\n", hr); ret = DeleteFileW(tmpfile); - ok(ret, "DeleteFileW failed %u\n", GetLastError()); + ok(ret, "DeleteFileW failed %lu\n", GetLastError()); type = 0xdeadbeef; hr = IWICColorContext_GetType(context, &type); - ok(hr == S_OK, "GetType error %#x\n", hr); + ok(hr == S_OK, "GetType error %#lx\n", hr); ok(type == WICColorContextProfile, "unexpected type %u\n", type); colorspace = 0xdeadbeef; hr = IWICColorContext_GetExifColorSpace(context, &colorspace); - ok(hr == S_OK, "GetExifColorSpace error %#x\n", hr); + ok(hr == S_OK, "GetExifColorSpace error %#lx\n", hr); ok(colorspace == 0xffffffff, "unexpected color space %u\n", colorspace); hr = IWICColorContext_InitializeFromExifColorSpace(context, 1); - ok(hr == WINCODEC_ERR_WRONGSTATE, "InitializeFromExifColorSpace error %#x\n", hr); + ok(hr == WINCODEC_ERR_WRONGSTATE, "InitializeFromExifColorSpace error %#lx\n", hr); size = 0; hr = IWICColorContext_GetProfileBytes(context, 0, NULL, &size); - ok(hr == S_OK, "GetProfileBytes error %#x\n", hr); + ok(hr == S_OK, "GetProfileBytes error %#lx\n", hr); ok(size, "unexpected size %u\n", size); buffer = HeapAlloc(GetProcessHeap(), 0, size); hr = IWICColorContext_GetProfileBytes(context, size, buffer, &size); - ok(hr == S_OK, "GetProfileBytes error %#x\n", hr); + ok(hr == S_OK, "GetProfileBytes error %#lx\n", hr); HeapFree(GetProcessHeap(), 0, buffer); HeapFree(GetProcessHeap(), 0, tmpfile); @@ -562,28 +562,28 @@ static void test_png_palette(void) char *buf; hr = create_decoder(png_PLTE_tRNS, sizeof(png_PLTE_tRNS), &decoder); - ok(hr == S_OK, "Failed to load PNG image data %#x\n", hr); + ok(hr == S_OK, "Failed to load PNG image data %#lx\n", hr); if (hr != S_OK) return; hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_WICPixelFormat1bppIndexed), "got wrong format %s\n", wine_dbgstr_guid(&format)); hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "CreatePalette error %#x\n", hr); + ok(hr == S_OK, "CreatePalette error %#lx\n", hr); hr = IWICBitmapFrameDecode_CopyPalette(frame, palette); - ok(hr == S_OK, "CopyPalette error %#x\n", hr); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 2, "expected 2, got %u\n", count); hr = IWICPalette_GetColors(palette, 256, color, &ret); - ok(hr == S_OK, "GetColors error %#x\n", hr); + ok(hr == S_OK, "GetColors error %#lx\n", hr); ok(ret == count, "expected %u, got %u\n", count, ret); ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]); ok(color[1] == 0x00040506, "expected 0x00040506, got %#x\n", color[1]); @@ -593,21 +593,21 @@ static void test_png_palette(void) IWICBitmapDecoder_Release(decoder); hr = create_decoder(png_gray_tRNS, sizeof(png_gray_tRNS), &decoder); - ok(hr == S_OK, "Failed to load PNG image data %#x\n", hr); + ok(hr == S_OK, "Failed to load PNG image data %#lx\n", hr); if (hr != S_OK) return; hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_WICPixelFormat64bppRGBA), "got wrong format %s\n", wine_dbgstr_guid(&format)); hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "CreatePalette error %#x\n", hr); + ok(hr == S_OK, "CreatePalette error %#lx\n", hr); hr = IWICBitmapFrameDecode_CopyPalette(frame, palette); - ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "CopyPalette error %#x\n", hr); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "CopyPalette error %#lx\n", hr); IWICPalette_Release(palette); IWICBitmapFrameDecode_Release(frame); @@ -619,28 +619,28 @@ static void test_png_palette(void) buf[24] = 8; /* override bit depth */ hr = create_decoder(buf, sizeof(png_gray_tRNS), &decoder); - ok(hr == S_OK, "Failed to load PNG image data %#x\n", hr); + ok(hr == S_OK, "Failed to load PNG image data %#lx\n", hr); if (hr != S_OK) return; hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed), "got wrong format %s\n", wine_dbgstr_guid(&format)); hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "CreatePalette error %#x\n", hr); + ok(hr == S_OK, "CreatePalette error %#lx\n", hr); hr = IWICBitmapFrameDecode_CopyPalette(frame, palette); - ok(hr == S_OK, "CopyPalette error %#x\n", hr); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 256, "expected 256, got %u\n", count); hr = IWICPalette_GetColors(palette, 256, color, &ret); - ok(hr == S_OK, "GetColors error %#x\n", hr); + ok(hr == S_OK, "GetColors error %#lx\n", hr); ok(ret == count, "expected %u, got %u\n", count, ret); ok(color[0] == 0x00000000, "expected 0x00000000, got %#x\n", color[0]); ok(color[1] == 0xff010101, "expected 0xff010101, got %#x\n", color[1]); @@ -813,18 +813,18 @@ static void test_color_formats(void) hr = create_decoder(buf, sizeof(buf), &decoder); if (!is_valid_png_type_depth(td[i].color_type, td[i].bit_depth, TRUE)) - ok(hr == WINCODEC_ERR_UNKNOWNIMAGEFORMAT, "%d: wrong error %#x\n", i, hr); + ok(hr == WINCODEC_ERR_UNKNOWNIMAGEFORMAT, "%d: wrong error %#lx\n", i, hr); else -todo_wine_if(td[i].todo_load) - ok(hr == S_OK, "%d: Failed to load PNG image data (type %d, bpp %d) %#x\n", i, td[i].color_type, td[i].bit_depth, hr); + todo_wine_if(td[i].todo_load) + ok(hr == S_OK, "%d: Failed to load PNG image data (type %d, bpp %d) %#lx\n", i, td[i].color_type, td[i].bit_depth, hr); if (hr != S_OK) goto next_1; hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); -todo_wine_if(td[i].todo) + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); + todo_wine_if(td[i].todo) ok(IsEqualGUID(&format, td[i].format_PLTE_tRNS), "PLTE+tRNS: expected %s, got %s (type %d, bpp %d)\n", wine_dbgstr_guid(td[i].format_PLTE_tRNS), wine_dbgstr_guid(&format), td[i].color_type, td[i].bit_depth); @@ -841,17 +841,17 @@ todo_wine_if(td[i].todo) hr = create_decoder(buf, sizeof(buf), &decoder); if (!is_valid_png_type_depth(td[i].color_type, td[i].bit_depth, TRUE)) - ok(hr == WINCODEC_ERR_UNKNOWNIMAGEFORMAT, "%d: wrong error %#x\n", i, hr); + ok(hr == WINCODEC_ERR_UNKNOWNIMAGEFORMAT, "%d: wrong error %#lx\n", i, hr); else -todo_wine_if(td[i].todo_load) - ok(hr == S_OK, "%d: Failed to load PNG image data (type %d, bpp %d) %#x\n", i, td[i].color_type, td[i].bit_depth, hr); + todo_wine_if(td[i].todo_load) + ok(hr == S_OK, "%d: Failed to load PNG image data (type %d, bpp %d) %#lx\n", i, td[i].color_type, td[i].bit_depth, hr); if (hr != S_OK) goto next_2; hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(IsEqualGUID(&format, td[i].format_PLTE), "PLTE: expected %s, got %s (type %d, bpp %d)\n", wine_dbgstr_guid(td[i].format_PLTE), wine_dbgstr_guid(&format), td[i].color_type, td[i].bit_depth); @@ -869,17 +869,17 @@ todo_wine_if(td[i].todo_load) hr = create_decoder(buf, sizeof(buf), &decoder); if (!is_valid_png_type_depth(td[i].color_type, td[i].bit_depth, FALSE)) - ok(hr == WINCODEC_ERR_UNKNOWNIMAGEFORMAT, "%d: wrong error %#x\n", i, hr); + ok(hr == WINCODEC_ERR_UNKNOWNIMAGEFORMAT, "%d: wrong error %#lx\n", i, hr); else -todo_wine_if(td[i].todo_load) - ok(hr == S_OK, "%d: Failed to load PNG image data (type %d, bpp %d) %#x\n", i, td[i].color_type, td[i].bit_depth, hr); + todo_wine_if(td[i].todo_load) + ok(hr == S_OK, "%d: Failed to load PNG image data (type %d, bpp %d) %#lx\n", i, td[i].color_type, td[i].bit_depth, hr); if (hr != S_OK) goto next_3; hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(IsEqualGUID(&format, td[i].format), "expected %s, got %s (type %d, bpp %d)\n", wine_dbgstr_guid(td[i].format), wine_dbgstr_guid(&format), td[i].color_type, td[i].bit_depth); @@ -896,18 +896,18 @@ todo_wine_if(td[i].todo_load) hr = create_decoder(buf, sizeof(buf), &decoder); if (!is_valid_png_type_depth(td[i].color_type, td[i].bit_depth, FALSE)) - ok(hr == WINCODEC_ERR_UNKNOWNIMAGEFORMAT, "%d: wrong error %#x\n", i, hr); + ok(hr == WINCODEC_ERR_UNKNOWNIMAGEFORMAT, "%d: wrong error %#lx\n", i, hr); else -todo_wine_if(td[i].todo_load) - ok(hr == S_OK, "%d: Failed to load PNG image data (type %d, bpp %d) %#x\n", i, td[i].color_type, td[i].bit_depth, hr); + todo_wine_if(td[i].todo_load) + ok(hr == S_OK, "%d: Failed to load PNG image data (type %d, bpp %d) %#lx\n", i, td[i].color_type, td[i].bit_depth, hr); if (hr != S_OK) continue; hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); -todo_wine_if(td[i].todo) + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); + todo_wine_if(td[i].todo) ok(IsEqualGUID(&format, td[i].format_PLTE_tRNS), "tRNS: expected %s, got %s (type %d, bpp %d)\n", wine_dbgstr_guid(td[i].format_PLTE_tRNS), wine_dbgstr_guid(&format), td[i].color_type, td[i].bit_depth); @@ -922,6 +922,34 @@ todo_wine_if(td[i].todo) #undef PNG_COLOR_TYPE_GRAY_ALPHA #undef PNG_COLOR_TYPE_RGB_ALPHA +/* 1 bpp 1x1 pixel PNG image with 8 MiB comment */ +static const char png_8M_tEXt_start[] = { + 0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a, + 0x00,0x00,0x00,0x0d,'I','H','D','R',0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x37,0x6e,0xf9,0x24, + 0x00,0x80,0x00,0x08,'t','E','X','t','C','o','m','m','e','n','t',0x00 /* ,[0x800030]=0x00,0x1e,0x13,0xe2,0xc7 */ +}; +static const char png_8M_tEXt_end[] = { + /* 0x00,0x80,0x00,0x08,'t','E','X','t','C','o','m','m','e','n','t',0x00,[0x800030]=0x00, */ 0x1e,0x13,0xe2,0xc7, + 0x00,0x00,0x00,0x0c,'I','D','A','T',0x78,0x9c,0x63,0x68,0x00,0x00,0x00,0x82,0x00,0x81,0x77,0xcd,0x72,0xb6, + 0x00,0x00,0x00,0x00,'I','E','N','D',0xae,0x42,0x60,0x82 +}; + +static void test_chunk_size(void) +{ + static char png_8M_tEXt[sizeof(png_8M_tEXt_start) + 0x800000 + sizeof(png_8M_tEXt_end)] = {0}; + HRESULT hr; + IWICBitmapDecoder *decoder; + + memcpy(png_8M_tEXt, png_8M_tEXt_start, sizeof(png_8M_tEXt_start)); + memcpy(png_8M_tEXt + sizeof(png_8M_tEXt) - sizeof(png_8M_tEXt_end), png_8M_tEXt_end, sizeof(png_8M_tEXt_end)); + + hr = create_decoder(png_8M_tEXt, sizeof(png_8M_tEXt), &decoder); + ok(hr == S_OK, "Failed to load PNG image data %#lx\n", hr); + if (hr != S_OK) return; + + IWICBitmapDecoder_Release(decoder); +} + START_TEST(pngformat) { HRESULT hr; @@ -929,12 +957,13 @@ START_TEST(pngformat) CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void **)&factory); - ok(hr == S_OK, "CoCreateInstance error %#x\n", hr); + ok(hr == S_OK, "CoCreateInstance error %#lx\n", hr); if (FAILED(hr)) return; test_color_contexts(); test_png_palette(); test_color_formats(); + test_chunk_size(); IWICImagingFactory_Release(factory); CoUninitialize(); diff --git a/modules/rostests/winetests/windowscodecs/propertybag.c b/modules/rostests/winetests/windowscodecs/propertybag.c index fd57073d9124f..1e0baf480521a 100644 --- a/modules/rostests/winetests/windowscodecs/propertybag.c +++ b/modules/rostests/winetests/windowscodecs/propertybag.c @@ -41,36 +41,36 @@ static void test_propertybag_getpropertyinfo(IPropertyBag2 *property, ULONG expe /* iProperty: Out of bounce */ hr = IPropertyBag2_GetPropertyInfo(property, expected_count, 1, pb, &out_count); ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, - "GetPropertyInfo handled iProperty out of bounce wrong, hr=%x\n", hr); + "GetPropertyInfo handled iProperty out of bounce wrong, hr=%lx\n", hr); /* cProperty: Out of bounce */ hr = IPropertyBag2_GetPropertyInfo(property, 0, expected_count+1, pb, &out_count); ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, - "GetPropertyInfo handled cProperty out of bounce wrong, hr=%x\n", hr); + "GetPropertyInfo handled cProperty out of bounce wrong, hr=%lx\n", hr); /* GetPropertyInfo can be called for zero items on Windows 8 but not on Windows 7 (wine behaves like Win8) */ if (expected_count == 0) return; hr = IPropertyBag2_GetPropertyInfo(property, 0, expected_count, pb, &out_count); - ok(hr == S_OK, "GetPropertyInfo failed, hr=%x\n", hr); + ok(hr == S_OK, "GetPropertyInfo failed, hr=%lx\n", hr); if (FAILED(hr)) return; ok(expected_count == out_count, - "GetPropertyInfo returned unexpected property count, %i != %i)\n", + "GetPropertyInfo returned unexpected property count, %li != %li)\n", expected_count, out_count); if(expected_count != 2) return; ok(pb[0].vt == VT_UI1, "Invalid variant type, pb[0].vt=%x\n", pb[0].vt); - ok(pb[0].dwType == PROPBAG2_TYPE_DATA, "Invalid variant type, pb[0].dwType=%x\n", pb[0].dwType); + ok(pb[0].dwType == PROPBAG2_TYPE_DATA, "Invalid variant type, pb[0].dwType=%lx\n", pb[0].dwType); ok(lstrcmpW(pb[0].pstrName, wszTestProperty1) == 0, "Invalid property name, pb[0].pstrName=%s\n", wine_dbgstr_w(pb[0].pstrName)); CoTaskMemFree(pb[0].pstrName); ok(pb[1].vt == VT_R4, "Invalid variant type, pb[1].vt=%x\n", pb[1].vt); - ok(pb[1].dwType == PROPBAG2_TYPE_DATA, "Invalid variant type, pb[1].dwType=%x\n", pb[1].dwType); + ok(pb[1].dwType == PROPBAG2_TYPE_DATA, "Invalid variant type, pb[1].dwType=%lx\n", pb[1].dwType); ok(lstrcmpW(pb[1].pstrName, wszTestProperty2) == 0, "Invalid property name, pb[1].pstrName=%s\n", wine_dbgstr_w(pb[1].pstrName)); CoTaskMemFree(pb[1].pstrName); } @@ -81,15 +81,15 @@ static void test_propertybag_countproperties(IPropertyBag2 *property, ULONG expe HRESULT hr; hr = IPropertyBag2_CountProperties(property, NULL); - ok(hr == E_INVALIDARG, "CountProperties returned unexpected result, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "CountProperties returned unexpected result, hr=%lx\n", hr); hr = IPropertyBag2_CountProperties(property, &count); - ok(hr == S_OK, "CountProperties failed, hr=%x\n", hr); + ok(hr == S_OK, "CountProperties failed, hr=%lx\n", hr); if (FAILED(hr)) return; - ok(count == expected_count, "CountProperties returned invalid value, count=%i\n", count); + ok(count == expected_count, "CountProperties returned invalid value, count=%li\n", count); } static void test_propertybag_read(IPropertyBag2 *property) @@ -103,17 +103,17 @@ static void test_propertybag_read(IPropertyBag2 *property) options[0].pstrName = (LPOLESTR)wszTestInvalidProperty; hr = IPropertyBag2_Read(property, 1, options, NULL, values, itm_hr); ok(hr == E_FAIL, - "Read for an unknown property did not fail with expected code, hr=%x\n", hr); + "Read for an unknown property did not fail with expected code, hr=%lx\n", hr); /* 2. One known property */ options[0].pstrName = (LPOLESTR)wszTestProperty1; itm_hr[0] = E_FAIL; hr = IPropertyBag2_Read(property, 1, options, NULL, values, itm_hr); - ok(hr == S_OK, "Read failed, hr=%x\n", hr); + ok(hr == S_OK, "Read failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { ok(itm_hr[0] == S_OK, - "Read failed, itm_hr[0]=%x\n", itm_hr[0]); + "Read failed, itm_hr[0]=%lx\n", itm_hr[0]); ok(V_VT(&values[0]) == VT_UI1, "Read failed, V_VT(&values[0])=%x\n", V_VT(&values[0])); ok(V_UNION(&values[0], bVal) == 12, @@ -128,14 +128,14 @@ static void test_propertybag_read(IPropertyBag2 *property) itm_hr[0] = E_FAIL; itm_hr[1] = E_FAIL; hr = IPropertyBag2_Read(property, 2, options, NULL, values, itm_hr); - ok(hr == S_OK, "Read failed, hr=%x\n", hr); + ok(hr == S_OK, "Read failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { - ok(itm_hr[0] == S_OK, "Read failed, itm_hr[0]=%x\n", itm_hr[0]); + ok(itm_hr[0] == S_OK, "Read failed, itm_hr[0]=%lx\n", itm_hr[0]); ok(V_VT(&values[0]) == VT_UI1, "Read failed, V_VT(&values[0])=%x\n", V_VT(&values[0])); ok(V_UNION(&values[0], bVal) == 12, "Read failed, &values[0]=%i\n", V_UNION(&values[0], bVal)); - ok(itm_hr[1] == S_OK, "Read failed, itm_hr[1]=%x\n", itm_hr[1]); + ok(itm_hr[1] == S_OK, "Read failed, itm_hr[1]=%lx\n", itm_hr[1]); ok(V_VT(&values[1]) == VT_R4, "Read failed, V_VT(&values[1])=%x\n", V_VT(&values[1])); ok(V_UNION(&values[1], fltVal) == (float)3.14, "Read failed, &values[1]=%f\n", V_UNION(&values[1], fltVal)); @@ -160,12 +160,12 @@ static void test_propertybag_read(IPropertyBag2 *property) options[2].pstrName = (LPOLESTR)wszTestProperty2; hr = IPropertyBag2_Read(property, 3, options, NULL, values, itm_hr); - ok(hr == E_FAIL, "Read failed, hr=%x\n", hr); + ok(hr == E_FAIL, "Read failed, hr=%lx\n", hr); if (hr == E_FAIL) { - ok(itm_hr[0] == S_OK, "Read error code has unexpected value, itm_hr[0]=%x\n", itm_hr[0]); - ok(itm_hr[1] == -1, "Read error code has unexpected value, itm_hr[1]=%x\n", itm_hr[1]); - ok(itm_hr[2] == -1, "Read error code has unexpected value, itm_hr[2]=%x\n", itm_hr[2]); + ok(itm_hr[0] == S_OK, "Read error code has unexpected value, itm_hr[0]=%lx\n", itm_hr[0]); + ok(itm_hr[1] == -1, "Read error code has unexpected value, itm_hr[1]=%lx\n", itm_hr[1]); + ok(itm_hr[2] == -1, "Read error code has unexpected value, itm_hr[2]=%lx\n", itm_hr[2]); ok(V_VT(&values[0]) == VT_UI1, "Read variant has unexpected type, V_VT(&values[0])=%x\n", V_VT(&values[0])); ok(V_VT(&values[1]) == VT_NULL, "Read variant has unexpected type, V_VT(&values[1])=%x\n", V_VT(&values[1])); @@ -189,14 +189,14 @@ static void test_propertybag_write(IPropertyBag2 *property) /* 1. One unknown property */ options[0].pstrName = (LPOLESTR)wszTestInvalidProperty; hr = IPropertyBag2_Write(property, 1, options, values); - ok(hr == E_FAIL, "Write for an unknown property did not fail with expected code, hr=%x\n", hr); + ok(hr == E_FAIL, "Write for an unknown property did not fail with expected code, hr=%lx\n", hr); /* 2. One property without correct type */ options[0].pstrName = (LPOLESTR)wszTestProperty1; V_VT(&values[0]) = VT_UI1; V_UNION(&values[0], bVal) = 1; hr = IPropertyBag2_Write(property, 1, options, values); - ok(hr == S_OK, "Write for one property failed, hr=%x\n", hr); + ok(hr == S_OK, "Write for one property failed, hr=%lx\n", hr); /* 3. One property with mismatching type */ options[0].pstrName = (LPOLESTR)wszTestProperty1; @@ -204,14 +204,14 @@ static void test_propertybag_write(IPropertyBag2 *property) V_UNION(&values[0], bVal) = 2; hr = IPropertyBag2_Write(property, 1, options, values); ok(hr == WINCODEC_ERR_PROPERTYUNEXPECTEDTYPE, - "Write with mismatching type did not fail with expected code hr=%x\n", hr); + "Write with mismatching type did not fail with expected code hr=%lx\n", hr); /* 4. Reset one property to empty */ options[0].pstrName = (LPOLESTR)wszTestProperty1; VariantClear(&values[0]); hr = IPropertyBag2_Write(property, 1, options, values); ok(hr == WINCODEC_ERR_PROPERTYUNEXPECTEDTYPE, - "Write to reset to empty value does not fail with expected code, hr=%x\n", hr); + "Write to reset to empty value does not fail with expected code, hr=%lx\n", hr); /* 5. Set two properties */ options[0].pstrName = (LPOLESTR)wszTestProperty1; @@ -221,7 +221,7 @@ static void test_propertybag_write(IPropertyBag2 *property) V_VT(&values[1]) = VT_R4; V_UNION(&values[1], fltVal) = (float)3.14; hr = IPropertyBag2_Write(property, 2, options, values); - ok(hr == S_OK, "Write for two properties failed, hr=%x\n", hr); + ok(hr == S_OK, "Write for two properties failed, hr=%lx\n", hr); } static void test_empty_propertybag(void) @@ -232,11 +232,11 @@ static void test_empty_propertybag(void) hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICComponentFactory, (void**)&factory); - ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); + ok(hr == S_OK, "CoCreateInstance failed, hr=%lx\n", hr); hr = IWICComponentFactory_CreateEncoderPropertyBag(factory, NULL, 0, &property); - ok(hr == S_OK, "Creating EncoderPropertyBag failed, hr=%x\n", hr); + ok(hr == S_OK, "Creating EncoderPropertyBag failed, hr=%lx\n", hr); if (FAILED(hr)) return; test_propertybag_countproperties(property, 0); @@ -260,11 +260,11 @@ static void test_filled_propertybag(void) hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICComponentFactory, (void**)&factory); - ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); + ok(hr == S_OK, "CoCreateInstance failed, hr=%lx\n", hr); hr = IWICComponentFactory_CreateEncoderPropertyBag(factory, opts, 2, &property); - ok(hr == S_OK, "Creating EncoderPropertyBag failed, hr=%x\n", hr); + ok(hr == S_OK, "Creating EncoderPropertyBag failed, hr=%lx\n", hr); if (FAILED(hr)) return; test_propertybag_countproperties(property, 2); diff --git a/modules/rostests/winetests/windowscodecs/stream.c b/modules/rostests/winetests/windowscodecs/stream.c index 048f1326be002..2a1b3e3092829 100644 --- a/modules/rostests/winetests/windowscodecs/stream.c +++ b/modules/rostests/winetests/windowscodecs/stream.c @@ -31,8 +31,8 @@ static void _check_cur_pos(IStream *stream, ULONGLONG expected_pos, BOOL todo, u offset.QuadPart = 0; hr = IStream_Seek(stream, offset, STREAM_SEEK_CUR, &pos); - ok_(__FILE__, line)(hr == S_OK, "Failed to get current position, hr %#x.\n", hr); -todo_wine_if(todo) + ok_(__FILE__, line)(hr == S_OK, "Failed to get current position, hr %#lx.\n", hr); + todo_wine_if(todo) ok_(__FILE__, line)(pos.QuadPart == expected_pos, "Unexpected stream position %s.\n", wine_dbgstr_longlong(pos.QuadPart)); } @@ -69,12 +69,12 @@ static void test_StreamOnMemory(void) hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&pFactory); if(FAILED(hr)) { - skip("CoCreateInstance returned with %#x, expected %#x\n", hr, S_OK); + skip("CoCreateInstance returned with %#lx, expected %#lx\n", hr, S_OK); return; } hr = IWICImagingFactory_CreateStream(pFactory, &pStream); - ok(hr == S_OK, "CreateStream returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "CreateStream returned with %#lx, expected %#lx\n", hr, S_OK); if(FAILED(hr)) { skip("Failed to create stream\n"); return; @@ -82,73 +82,73 @@ static void test_StreamOnMemory(void) /* InitializeFromMemory */ hr = IWICStream_InitializeFromMemory(pStream, NULL, sizeof(Memory)); /* memory = NULL */ - ok(hr == E_INVALIDARG, "InitializeFromMemory returned with %#x, expected %#x\n", hr, E_INVALIDARG); + ok(hr == E_INVALIDARG, "InitializeFromMemory returned with %#lx, expected %#lx\n", hr, E_INVALIDARG); hr = IWICStream_InitializeFromMemory(pStream, Memory, 0); /* size = 0 */ - ok(hr == S_OK, "InitializeFromMemory returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "InitializeFromMemory returned with %#lx, expected %#lx\n", hr, S_OK); hr = IWICStream_InitializeFromMemory(pStream, Memory, sizeof(Memory)); /* stream already initialized */ - ok(hr == WINCODEC_ERR_WRONGSTATE, "InitializeFromMemory returned with %#x, expected %#x\n", hr, WINCODEC_ERR_WRONGSTATE); + ok(hr == WINCODEC_ERR_WRONGSTATE, "InitializeFromMemory returned with %#lx, expected %#lx\n", hr, WINCODEC_ERR_WRONGSTATE); /* recreate stream */ IWICStream_Release(pStream); hr = IWICImagingFactory_CreateStream(pFactory, &pStream); - ok(hr == S_OK, "CreateStream failed with %#x\n", hr); + ok(hr == S_OK, "CreateStream failed with %#lx\n", hr); hr = IWICStream_InitializeFromMemory(pStream, Memory, sizeof(Memory)); - ok(hr == S_OK, "InitializeFromMemory returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "InitializeFromMemory returned with %#lx, expected %#lx\n", hr, S_OK); /* IWICStream does not maintain an independent copy of the backing memory buffer. */ memcpy(Memory, ZeroMem, sizeof(ZeroMem)); hr = IWICStream_Read(pStream, MemBuf, sizeof(ZeroMem), &uBytesRead); - ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK); if(SUCCEEDED(hr)) { - ok(uBytesRead == sizeof(ZeroMem), "Read %u bytes\n", uBytesRead); + ok(uBytesRead == sizeof(ZeroMem), "Read %lu bytes\n", uBytesRead); ok(memcmp(MemBuf, ZeroMem, sizeof(ZeroMem)) == 0, "Read returned invalid data!\n"); } IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL); hr = IWICStream_Write(pStream, CmpMem, sizeof(CmpMem), &uBytesWritten); - ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK); /* Seek */ hr = IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, &uNewPos); - ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK); - ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 0, "Seek cursor moved to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, 0); + ok(hr == S_OK, "Seek returned with %#lx, expected %#lx\n", hr, S_OK); + ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 0, "Seek cursor moved to position (%lu;%lu), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, 0); hr = IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL); - ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Seek returned with %#lx, expected %#lx\n", hr, S_OK); LargeInt.u.HighPart = 1; LargeInt.u.LowPart = 0; uNewPos.u.HighPart = 0xdeadbeef; uNewPos.u.LowPart = 0xdeadbeef; hr = IWICStream_Seek(pStream, LargeInt, STREAM_SEEK_SET, &uNewPos); - ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "Seek returned with %#x, expected %#x\n", hr, HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW)); - ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef); + ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "Seek returned with %#lx, expected %#lx\n", hr, HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW)); + ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%lu;%lu), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef); CHECK_CUR_POS(pStream, 0); LargeInt.QuadPart = sizeof(Memory) + 10; uNewPos.u.HighPart = 0xdeadbeef; uNewPos.u.LowPart = 0xdeadbeef; hr = IWICStream_Seek(pStream, LargeInt, STREAM_SEEK_SET, &uNewPos); - ok(hr == E_INVALIDARG, "Seek returned with %#x, expected %#x\n", hr, E_INVALIDARG); - ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef); + ok(hr == E_INVALIDARG, "Seek returned with %#lx, expected %#lx\n", hr, E_INVALIDARG); + ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%lu;%lu), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef); CHECK_CUR_POS(pStream, 0); LargeInt.QuadPart = 1; uNewPos.u.HighPart = 0xdeadbeef; uNewPos.u.LowPart = 0xdeadbeef; hr = IWICStream_Seek(pStream, LargeInt, STREAM_SEEK_END, &uNewPos); - ok(hr == E_INVALIDARG, "Seek returned with %#x, expected %#x\n", hr, E_INVALIDARG); - ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef); + ok(hr == E_INVALIDARG, "Seek returned with %#lx, expected %#lx\n", hr, E_INVALIDARG); + ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%lu;%lu), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef); CHECK_CUR_POS(pStream, 0); LargeInt.QuadPart = -1; hr = IWICStream_Seek(pStream, LargeInt, STREAM_SEEK_END, &uNewPos); - ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK); - ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == sizeof(Memory) - 1, "bSeek cursor moved to position (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart); + ok(hr == S_OK, "Seek returned with %#lx, expected %#lx\n", hr, S_OK); + ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == sizeof(Memory) - 1, "bSeek cursor moved to position (%lu;%lu)\n", uNewPos.u.HighPart, uNewPos.u.LowPart); IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, &uNewPos); /* reset seek pointer */ LargeInt.QuadPart = -(LONGLONG)sizeof(Memory) - 5; @@ -156,16 +156,16 @@ static void test_StreamOnMemory(void) uNewPos.u.LowPart = 0xdeadbeef; hr = IWICStream_Seek(pStream, LargeInt, STREAM_SEEK_END, &uNewPos); ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), - "Seek returned with %#x, expected %#x\n", hr, HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW)); - ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef); + "Seek returned with %#lx, expected %#lx\n", hr, HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW)); + ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%lu;%lu), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef); CHECK_CUR_POS(pStream, 0); IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL); /* Read */ hr = IWICStream_Read(pStream, MemBuf, 12, &uBytesRead); - ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK); if(SUCCEEDED(hr)) { - ok(uBytesRead == 12, "Read %u bytes, expected %u\n", uBytesRead, 12); + ok(uBytesRead == 12, "Read %lu bytes, expected %u\n", uBytesRead, 12); ok(memcmp(MemBuf, CmpMem, 12) == 0, "Read returned invalid data!\n"); /* check whether the seek pointer has moved correctly */ @@ -175,18 +175,18 @@ static void test_StreamOnMemory(void) IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL); hr = IWICStream_Read(pStream, Memory, 10, &uBytesRead); /* source = dest */ - ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK); if(SUCCEEDED(hr)) { - ok(uBytesRead == 10, "Read %u bytes, expected %u\n", uBytesRead, 10); + ok(uBytesRead == 10, "Read %lu bytes, expected %u\n", uBytesRead, 10); ok(memcmp(Memory, CmpMem, uBytesRead) == 0, "Read returned invalid data!\n"); } IWICStream_Seek(pStream, SeekPos, STREAM_SEEK_SET, NULL); hr = IWICStream_Read(pStream, Memory, 10, &uBytesRead); /* source and dest overlap */ - ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK); if(SUCCEEDED(hr)) { - ok(uBytesRead == 10, "Read %u bytes, expected %u\n", uBytesRead, 10); + ok(uBytesRead == 10, "Read %lu bytes, expected %u\n", uBytesRead, 10); ok(memcmp(Memory, CmpMemOverlap, uBytesRead) == 0, "Read returned invalid data!\n"); } @@ -195,33 +195,33 @@ static void test_StreamOnMemory(void) IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL); hr = IWICStream_Read(pStream, Memory, sizeof(Memory) + 10, &uBytesRead); /* request too many bytes */ - ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK); if(SUCCEEDED(hr)) { - ok(uBytesRead == sizeof(Memory), "Read %u bytes\n", uBytesRead); + ok(uBytesRead == sizeof(Memory), "Read %lu bytes\n", uBytesRead); ok(memcmp(Memory, CmpMem, uBytesRead) == 0, "Read returned invalid data!\n"); } hr = IWICStream_Read(pStream, NULL, 1, &uBytesRead); /* destination buffer = NULL */ - ok(hr == E_INVALIDARG, "Read returned with %#x, expected %#x\n", hr, E_INVALIDARG); + ok(hr == E_INVALIDARG, "Read returned with %#lx, expected %#lx\n", hr, E_INVALIDARG); hr = IWICStream_Read(pStream, MemBuf, 0, &uBytesRead); /* read 0 bytes */ - ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK); hr = IWICStream_Read(pStream, NULL, 0, &uBytesRead); - ok(hr == E_INVALIDARG, "Read returned with %#x, expected %#x\n", hr, E_INVALIDARG); + ok(hr == E_INVALIDARG, "Read returned with %#lx, expected %#lx\n", hr, E_INVALIDARG); hr = IWICStream_Read(pStream, NULL, 0, NULL); - ok(hr == E_INVALIDARG, "Read returned with %#x, expected %#x\n", hr, E_INVALIDARG); + ok(hr == E_INVALIDARG, "Read returned with %#lx, expected %#lx\n", hr, E_INVALIDARG); hr = IWICStream_Read(pStream, MemBuf, 1, NULL); - ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK); IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL); ZeroMemory(MemBuf, sizeof(MemBuf)); hr = IWICStream_Read(pStream, MemBuf, sizeof(Memory) + 10, &uBytesRead); - ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK); if(SUCCEEDED(hr)) { - ok(uBytesRead == sizeof(Memory), "Read %u bytes\n", uBytesRead); + ok(uBytesRead == sizeof(Memory), "Read %lu bytes\n", uBytesRead); ok(memcmp(Memory, CmpMem, 64) == 0, "Read returned invalid data!\n"); } IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL); @@ -232,9 +232,9 @@ static void test_StreamOnMemory(void) MemBuf[1] = CmpMem[1] + 1; MemBuf[2] = CmpMem[2] + 1; hr = IWICStream_Write(pStream, MemBuf, 3, &uBytesWritten); - ok(hr == S_OK, "Write returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Write returned with %#lx, expected %#lx\n", hr, S_OK); if(SUCCEEDED(hr)) { - ok(uBytesWritten == 3, "Wrote %u bytes, expected %u\n", uBytesWritten, 3); + ok(uBytesWritten == 3, "Wrote %lu bytes, expected %u\n", uBytesWritten, 3); ok(memcmp(MemBuf, Memory, 3) == 0, "Wrote returned invalid data!\n"); /* make sure we're writing directly */ /* check whether the seek pointer has moved correctly */ @@ -243,19 +243,19 @@ static void test_StreamOnMemory(void) IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL); hr = IWICStream_Write(pStream, MemBuf, 0, &uBytesWritten); - ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK); /* Restore the original contents of the memory stream. */ hr = IWICStream_Write(pStream, CmpMem, sizeof(CmpMem), &uBytesWritten); - ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK); IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL); /* Source and destination overlap. */ hr = IWICStream_Write(pStream, Memory + 5, 10, &uBytesWritten); - ok(hr == S_OK, "Write returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Write returned with %#lx, expected %#lx\n", hr, S_OK); if(SUCCEEDED(hr)) { - ok(uBytesWritten == 10, "Wrote %u bytes, expected %u\n", uBytesWritten, 10); + ok(uBytesWritten == 10, "Wrote %lu bytes, expected %u\n", uBytesWritten, 10); ok(memcmp(CmpMemOverlap, Memory, sizeof(CmpMemOverlap)) == 0, "Wrote returned invalid data!\n"); } @@ -263,20 +263,20 @@ static void test_StreamOnMemory(void) uBytesWritten = 0xdeadbeef; hr = IWICStream_Write(pStream, NULL, 3, &uBytesWritten); - ok(hr == E_INVALIDARG, "Write returned with %#x, expected %#x\n", hr, E_INVALIDARG); - ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %u\n", uBytesWritten); + ok(hr == E_INVALIDARG, "Write returned with %#lx, expected %#lx\n", hr, E_INVALIDARG); + ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %lu\n", uBytesWritten); CHECK_CUR_POS(pStream, 0); uBytesWritten = 0xdeadbeef; hr = IWICStream_Write(pStream, NULL, 0, &uBytesWritten); - ok(hr == E_INVALIDARG, "Write returned with %#x, expected %#x\n", hr, E_INVALIDARG); - ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %u\n", uBytesWritten); + ok(hr == E_INVALIDARG, "Write returned with %#lx, expected %#lx\n", hr, E_INVALIDARG); + ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %lu\n", uBytesWritten); CHECK_CUR_POS(pStream, 0); uBytesWritten = 0xdeadbeef; hr = IWICStream_Write(pStream, CmpMem, sizeof(Memory) + 10, &uBytesWritten); - ok(hr == STG_E_MEDIUMFULL, "Write returned with %#x, expected %#x\n", hr, STG_E_MEDIUMFULL); - ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %u\n", uBytesWritten); + ok(hr == STG_E_MEDIUMFULL, "Write returned with %#lx, expected %#lx\n", hr, STG_E_MEDIUMFULL); + ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %lu\n", uBytesWritten); CHECK_CUR_POS(pStream, 0); IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL); @@ -285,97 +285,97 @@ static void test_StreamOnMemory(void) uNewPos.u.HighPart = 0; uNewPos.u.LowPart = sizeof(Memory) + 10; hr = IWICStream_SetSize(pStream, uNewPos); - ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "SetSize returned %#lx, expected %#lx\n", hr, E_NOTIMPL); uNewPos.u.HighPart = 0; uNewPos.u.LowPart = sizeof(Memory); hr = IWICStream_SetSize(pStream, uNewPos); - ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "SetSize returned %#lx, expected %#lx\n", hr, E_NOTIMPL); uNewPos.u.HighPart = 0; uNewPos.u.LowPart = sizeof(Memory) - 10; hr = IWICStream_SetSize(pStream, uNewPos); - ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "SetSize returned %#lx, expected %#lx\n", hr, E_NOTIMPL); uNewPos.u.HighPart = 0; uNewPos.u.LowPart = 0; hr = IWICStream_SetSize(pStream, uNewPos); - ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "SetSize returned %#lx, expected %#lx\n", hr, E_NOTIMPL); uNewPos.QuadPart = -10; hr = IWICStream_SetSize(pStream, uNewPos); - ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "SetSize returned %#lx, expected %#lx\n", hr, E_NOTIMPL); /* CopyTo */ uNewPos.u.HighPart = 0; uNewPos.u.LowPart = 5; hr = IWICStream_CopyTo(pStream, NULL, uNewPos, NULL, NULL); - ok(hr == E_NOTIMPL, "CopyTo returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "CopyTo returned %#lx, expected %#lx\n", hr, E_NOTIMPL); hr = IWICImagingFactory_CreateStream(pFactory, &pBufStream); - ok(hr == S_OK, "CreateStream failed with %#x\n", hr); + ok(hr == S_OK, "CreateStream failed with %#lx\n", hr); hr = IWICStream_InitializeFromMemory(pBufStream, Memory, sizeof(Memory)); - ok(hr == S_OK, "InitializeFromMemory returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "InitializeFromMemory returned with %#lx, expected %#lx\n", hr, S_OK); hr = IWICStream_CopyTo(pStream, (IStream*)pBufStream, uNewPos, NULL, NULL); - ok(hr == E_NOTIMPL, "CopyTo returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "CopyTo returned %#lx, expected %#lx\n", hr, E_NOTIMPL); IWICStream_Release(pBufStream); /* Commit */ hr = IWICStream_Commit(pStream, STGC_DEFAULT); - ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr); hr = IWICStream_Commit(pStream, STGC_OVERWRITE); - ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr); hr = IWICStream_Commit(pStream, STGC_ONLYIFCURRENT); - ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr); hr = IWICStream_Commit(pStream, STGC_DANGEROUSLYCOMMITMERELYTODISKCACHE); - ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr); hr = IWICStream_Commit(pStream, STGC_CONSOLIDATE); - ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr); /* Revert */ IWICStream_Write(pStream, &MemBuf[5], 6, NULL); hr = IWICStream_Revert(pStream); - ok(hr == E_NOTIMPL, "Revert returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "Revert returned %#lx, expected %#lx\n", hr, E_NOTIMPL); memcpy(Memory, CmpMem, sizeof(Memory)); /* LockRegion/UnlockRegion */ hr = IWICStream_LockRegion(pStream, uLargeNull, uLargeNull, 0); - ok(hr == E_NOTIMPL, "LockRegion returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "LockRegion returned %#lx, expected %#lx\n", hr, E_NOTIMPL); hr = IWICStream_UnlockRegion(pStream, uLargeNull, uLargeNull, 0); - ok(hr == E_NOTIMPL, "UnlockRegion returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "UnlockRegion returned %#lx, expected %#lx\n", hr, E_NOTIMPL); /* Stat */ hr = IWICStream_Stat(pStream, NULL, 0); - ok(hr == E_INVALIDARG, "Stat returned %#x, expected %#x\n", hr, E_INVALIDARG); + ok(hr == E_INVALIDARG, "Stat returned %#lx, expected %#lx\n", hr, E_INVALIDARG); hr = IWICStream_Stat(pStream, &Stats, 0); - ok(hr == S_OK, "Stat returned %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Stat returned %#lx, expected %#lx\n", hr, S_OK); ok(Stats.pwcsName == NULL, "Stat returned name %p, expected %p\n", Stats.pwcsName, NULL); - ok(Stats.type == STGTY_STREAM, "Stat returned type %d, expected %d\n", Stats.type, STGTY_STREAM); - ok(Stats.cbSize.u.HighPart == 0 && Stats.cbSize.u.LowPart == sizeof(Memory), "Stat returned size (%u;%u)\n", Stats.cbSize.u.HighPart, Stats.cbSize.u.LowPart); - ok(Stats.mtime.dwHighDateTime == 0 && Stats.mtime.dwLowDateTime == 0, "Stat returned mtime (%u;%u), expected (%u;%u)\n", Stats.mtime.dwHighDateTime, Stats.mtime.dwLowDateTime, 0, 0); - ok(Stats.ctime.dwHighDateTime == 0 && Stats.ctime.dwLowDateTime == 0, "Stat returned ctime (%u;%u), expected (%u;%u)\n", Stats.ctime.dwHighDateTime, Stats.ctime.dwLowDateTime, 0, 0); - ok(Stats.atime.dwHighDateTime == 0 && Stats.atime.dwLowDateTime == 0, "Stat returned atime (%u;%u), expected (%u;%u)\n", Stats.atime.dwHighDateTime, Stats.atime.dwLowDateTime, 0, 0); - ok(Stats.grfMode == 0, "Stat returned access mode %d, expected %d\n", Stats.grfMode, 0); - ok(Stats.grfLocksSupported == 0, "Stat returned supported locks %#x, expected %#x\n", Stats.grfLocksSupported, 0); - ok(Stats.grfStateBits == 0, "Stat returned state bits %#x, expected %#x\n", Stats.grfStateBits, 0); + ok(Stats.type == STGTY_STREAM, "Stat returned type %ld, expected %d\n", Stats.type, STGTY_STREAM); + ok(Stats.cbSize.u.HighPart == 0 && Stats.cbSize.u.LowPart == sizeof(Memory), "Stat returned size (%lu;%lu)\n", Stats.cbSize.u.HighPart, Stats.cbSize.u.LowPart); + ok(Stats.mtime.dwHighDateTime == 0 && Stats.mtime.dwLowDateTime == 0, "Stat returned mtime (%lu;%lu), expected (%u;%u)\n", Stats.mtime.dwHighDateTime, Stats.mtime.dwLowDateTime, 0, 0); + ok(Stats.ctime.dwHighDateTime == 0 && Stats.ctime.dwLowDateTime == 0, "Stat returned ctime (%lu;%lu), expected (%u;%u)\n", Stats.ctime.dwHighDateTime, Stats.ctime.dwLowDateTime, 0, 0); + ok(Stats.atime.dwHighDateTime == 0 && Stats.atime.dwLowDateTime == 0, "Stat returned atime (%lu;%lu), expected (%u;%u)\n", Stats.atime.dwHighDateTime, Stats.atime.dwLowDateTime, 0, 0); + ok(Stats.grfMode == 0, "Stat returned access mode %ld, expected %d\n", Stats.grfMode, 0); + ok(Stats.grfLocksSupported == 0, "Stat returned supported locks %#lx, expected %#x\n", Stats.grfLocksSupported, 0); + ok(Stats.grfStateBits == 0, "Stat returned state bits %#lx, expected %#x\n", Stats.grfStateBits, 0); /* Clone */ hr = IWICStream_Clone(pStream, (IStream**)&pBufStream); - ok(hr == E_NOTIMPL, "UnlockRegion returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "UnlockRegion returned %#lx, expected %#lx\n", hr, E_NOTIMPL); IWICStream_Release(pStream); @@ -409,27 +409,27 @@ static void test_StreamOnStreamRange(void) hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&pFactory); if(FAILED(hr)) { - skip("CoCreateInstance returned with %#x, expected %#x\n", hr, S_OK); + skip("CoCreateInstance returned with %#lx, expected %#lx\n", hr, S_OK); return; } hr = IWICImagingFactory_CreateStream(pFactory, &pStream); - ok(hr == S_OK, "CreateStream returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "CreateStream returned with %#lx, expected %#lx\n", hr, S_OK); if(FAILED(hr)) { skip("Failed to create stream\n"); return; } hr = IWICStream_InitializeFromMemory(pStream, Memory, sizeof(Memory)); - ok(hr == S_OK, "InitializeFromMemory returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "InitializeFromMemory returned with %#lx, expected %#lx\n", hr, S_OK); hr = IWICImagingFactory_CreateStream(pFactory, &pSubStream); - ok(hr == S_OK, "CreateStream returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "CreateStream returned with %#lx, expected %#lx\n", hr, S_OK); uNewPos.QuadPart = 20; uSize.QuadPart = 20; hr = IWICStream_InitializeFromIStreamRegion(pSubStream, (IStream*)pStream, uNewPos, uSize); - ok(hr == S_OK, "InitializeFromIStreamRegion returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "InitializeFromIStreamRegion returned with %#lx, expected %#lx\n", hr, S_OK); if(FAILED(hr)) { skip("InitializeFromIStreamRegion unimplemented\n"); IWICStream_Release(pSubStream); @@ -442,47 +442,47 @@ static void test_StreamOnStreamRange(void) /* Seek */ CHECK_CUR_POS(pStream, 0); hr = IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_END, &uNewPos); - ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 20, "Seek cursor moved to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, 20); - ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK); + ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 20, "Seek cursor moved to position (%lu;%lu), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, 20); + ok(hr == S_OK, "Seek returned with %#lx, expected %#lx\n", hr, S_OK); CHECK_CUR_POS(pStream, 0); hr = IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, &uNewPos); - ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK); - ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 0, "Seek cursor moved to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, 0); + ok(hr == S_OK, "Seek returned with %#lx, expected %#lx\n", hr, S_OK); + ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 0, "Seek cursor moved to position (%lu;%lu), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, 0); CHECK_CUR_POS(pStream, 0); hr = IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL); - ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Seek returned with %#lx, expected %#lx\n", hr, S_OK); LargeInt.u.HighPart = 1; LargeInt.u.LowPart = 0; uNewPos.u.HighPart = 0xdeadbeef; uNewPos.u.LowPart = 0xdeadbeef; hr = IWICStream_Seek(pSubStream, LargeInt, STREAM_SEEK_SET, &uNewPos); - ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "Seek returned with %#x, expected %#x\n", hr, WINCODEC_ERR_VALUEOUTOFRANGE); - ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef); + ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "Seek returned with %#lx, expected %#lx\n", hr, WINCODEC_ERR_VALUEOUTOFRANGE); + ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%lu;%lu), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef); CHECK_CUR_POS(pStream, 0); LargeInt.QuadPart = 30; uNewPos.u.HighPart = 0xdeadbeef; uNewPos.u.LowPart = 0xdeadbeef; hr = IWICStream_Seek(pSubStream, LargeInt, STREAM_SEEK_SET, &uNewPos); - ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "Seek returned with %#x, expected %#x\n", hr, WINCODEC_ERR_VALUEOUTOFRANGE); - ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef); + ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "Seek returned with %#lx, expected %#lx\n", hr, WINCODEC_ERR_VALUEOUTOFRANGE); + ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%lu;%lu), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef); CHECK_CUR_POS(pStream, 0); LargeInt.QuadPart = 1; uNewPos.u.HighPart = 0xdeadbeef; uNewPos.u.LowPart = 0xdeadbeef; hr = IWICStream_Seek(pSubStream, LargeInt, STREAM_SEEK_END, &uNewPos); - ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "Seek returned with %#x, expected %#x\n", hr, WINCODEC_ERR_VALUEOUTOFRANGE); - ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef); + ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "Seek returned with %#lx, expected %#lx\n", hr, WINCODEC_ERR_VALUEOUTOFRANGE); + ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%lu;%lu), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef); CHECK_CUR_POS(pStream, 0); LargeInt.QuadPart = -1; hr = IWICStream_Seek(pSubStream, LargeInt, STREAM_SEEK_END, &uNewPos); - ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK); - ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 19, "bSeek cursor moved to position (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart); + ok(hr == S_OK, "Seek returned with %#lx, expected %#lx\n", hr, S_OK); + ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 19, "bSeek cursor moved to position (%lu;%lu)\n", uNewPos.u.HighPart, uNewPos.u.LowPart); CHECK_CUR_POS(pStream, 0); IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, &uNewPos); /* reset seek pointer */ @@ -491,17 +491,17 @@ static void test_StreamOnStreamRange(void) uNewPos.u.LowPart = 0xdeadbeef; hr = IWICStream_Seek(pSubStream, LargeInt, STREAM_SEEK_END, &uNewPos); ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, - "Seek returned with %#x, expected %#x\n", hr, HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW)); - ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef); + "Seek returned with %#lx, expected %#lx\n", hr, HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW)); + ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%lu;%lu), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef); CHECK_CUR_POS(pStream, 0); IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL); /* Read */ hr = IWICStream_Read(pSubStream, MemBuf, 12, &uBytesRead); - ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK); if(SUCCEEDED(hr)) { - ok(uBytesRead == 12, "Read %u bytes, expected %u\n", uBytesRead, 12); + ok(uBytesRead == 12, "Read %lu bytes, expected %u\n", uBytesRead, 12); ok(memcmp(MemBuf, CmpMem+20, 12) == 0, "Read returned invalid data!\n"); /* check whether the seek pointer has moved correctly */ @@ -512,9 +512,9 @@ static void test_StreamOnStreamRange(void) IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL); hr = IWICStream_Read(pSubStream, Memory, 10, &uBytesRead); /* source = dest */ - ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK); if(SUCCEEDED(hr)) { - ok(uBytesRead == 10, "Read %u bytes, expected %u\n", uBytesRead, 10); + ok(uBytesRead == 10, "Read %lu bytes, expected %u\n", uBytesRead, 10); ok(memcmp(Memory, CmpMem+20, uBytesRead) == 0, "Read returned invalid data!\n"); } CHECK_CUR_POS(pStream, 0); @@ -522,9 +522,9 @@ static void test_StreamOnStreamRange(void) IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL); hr = IWICStream_Read(pSubStream, Memory, 30, &uBytesRead); /* request too many bytes */ - ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK); if(SUCCEEDED(hr)) { - ok(uBytesRead == 20, "Read %u bytes\n", uBytesRead); + ok(uBytesRead == 20, "Read %lu bytes\n", uBytesRead); ok(memcmp(Memory, CmpMem+20, uBytesRead) == 0, "Read returned invalid data!\n"); } CHECK_CUR_POS(pStream, 0); @@ -532,29 +532,29 @@ static void test_StreamOnStreamRange(void) IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL); uBytesRead = 0xdeadbeef; hr = IWICStream_Read(pSubStream, NULL, 1, &uBytesRead); /* destination buffer = NULL */ - ok(hr == E_INVALIDARG, "Read returned with %#x, expected %#x\n", hr, E_INVALIDARG); - ok(uBytesRead == 0xdeadbeef, "Expected uBytesRead to be unchanged, got %u\n", uBytesRead); + ok(hr == E_INVALIDARG, "Read returned with %#lx, expected %#lx\n", hr, E_INVALIDARG); + ok(uBytesRead == 0xdeadbeef, "Expected uBytesRead to be unchanged, got %lu\n", uBytesRead); hr = IWICStream_Read(pSubStream, MemBuf, 0, &uBytesRead); /* read 0 bytes */ - ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK); uBytesRead = 0xdeadbeef; hr = IWICStream_Read(pSubStream, NULL, 0, &uBytesRead); - ok(hr == E_INVALIDARG, "Read returned with %#x, expected %#x\n", hr, E_INVALIDARG); - ok(uBytesRead == 0xdeadbeef, "Expected uBytesRead to be unchanged, got %u\n", uBytesRead); + ok(hr == E_INVALIDARG, "Read returned with %#lx, expected %#lx\n", hr, E_INVALIDARG); + ok(uBytesRead == 0xdeadbeef, "Expected uBytesRead to be unchanged, got %lu\n", uBytesRead); hr = IWICStream_Read(pSubStream, NULL, 0, NULL); - ok(hr == E_INVALIDARG, "Read returned with %#x, expected %#x\n", hr, E_INVALIDARG); + ok(hr == E_INVALIDARG, "Read returned with %#lx, expected %#lx\n", hr, E_INVALIDARG); hr = IWICStream_Read(pSubStream, MemBuf, 1, NULL); - ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK); IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL); ZeroMemory(MemBuf, sizeof(MemBuf)); hr = IWICStream_Read(pSubStream, MemBuf, 30, &uBytesRead); - ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK); if(SUCCEEDED(hr)) { - ok(uBytesRead == 20, "Read %u bytes\n", uBytesRead); + ok(uBytesRead == 20, "Read %lu bytes\n", uBytesRead); ok(memcmp(Memory, CmpMem+20, 20) == 0, "Read returned invalid data!\n"); } IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL); @@ -565,9 +565,9 @@ static void test_StreamOnStreamRange(void) MemBuf[1] = CmpMem[1] + 1; MemBuf[2] = CmpMem[2] + 1; hr = IWICStream_Write(pSubStream, MemBuf, 3, &uBytesWritten); - ok(hr == S_OK, "Write returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Write returned with %#lx, expected %#lx\n", hr, S_OK); if(SUCCEEDED(hr)) { - ok(uBytesWritten == 3, "Wrote %u bytes, expected %u\n", uBytesWritten, 3); + ok(uBytesWritten == 3, "Wrote %lu bytes, expected %u\n", uBytesWritten, 3); ok(memcmp(MemBuf, Memory+20, 3) == 0, "Wrote returned invalid data!\n"); /* make sure we're writing directly */ /* check whether the seek pointer has moved correctly */ @@ -577,25 +577,25 @@ static void test_StreamOnStreamRange(void) IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL); hr = IWICStream_Write(pSubStream, MemBuf, 0, &uBytesWritten); - ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK); uBytesWritten = 0xdeadbeef; hr = IWICStream_Write(pSubStream, NULL, 3, &uBytesWritten); - ok(hr == E_INVALIDARG, "Write returned with %#x, expected %#x\n", hr, E_INVALIDARG); - ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %u\n", uBytesWritten); + ok(hr == E_INVALIDARG, "Write returned with %#lx, expected %#lx\n", hr, E_INVALIDARG); + ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %lu\n", uBytesWritten); CHECK_CUR_POS(pSubStream, 0); CHECK_CUR_POS(pStream, 0); uBytesWritten = 0xdeadbeef; hr = IWICStream_Write(pSubStream, NULL, 0, &uBytesWritten); - ok(hr == E_INVALIDARG, "Write returned with %#x, expected %#x\n", hr, E_INVALIDARG); - ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %u\n", uBytesWritten); + ok(hr == E_INVALIDARG, "Write returned with %#lx, expected %#lx\n", hr, E_INVALIDARG); + ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %lu\n", uBytesWritten); CHECK_CUR_POS(pSubStream, 0); CHECK_CUR_POS(pStream, 0); hr = IWICStream_Write(pSubStream, CmpMem, 30, &uBytesWritten); - ok(hr == S_OK, "Write returned with %#x, expected %#x\n", hr, STG_E_MEDIUMFULL); - ok(uBytesWritten == 20, "Wrote %u bytes, expected %u\n", uBytesWritten, 0); + ok(hr == S_OK, "Write returned with %#lx, expected %#lx\n", hr, STG_E_MEDIUMFULL); + ok(uBytesWritten == 20, "Wrote %lu bytes, expected %u\n", uBytesWritten, 0); CHECK_CUR_POS(pSubStream, uBytesWritten); CHECK_CUR_POS(pStream, 0); IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL); @@ -605,94 +605,94 @@ static void test_StreamOnStreamRange(void) uNewPos.u.HighPart = 0; uNewPos.u.LowPart = sizeof(Memory) + 10; hr = IWICStream_SetSize(pSubStream, uNewPos); - ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "SetSize returned %#lx, expected %#lx\n", hr, E_NOTIMPL); uNewPos.u.HighPart = 0; uNewPos.u.LowPart = sizeof(Memory); hr = IWICStream_SetSize(pSubStream, uNewPos); - ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "SetSize returned %#lx, expected %#lx\n", hr, E_NOTIMPL); uNewPos.u.HighPart = 0; uNewPos.u.LowPart = sizeof(Memory) - 10; hr = IWICStream_SetSize(pSubStream, uNewPos); - ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "SetSize returned %#lx, expected %#lx\n", hr, E_NOTIMPL); uNewPos.u.HighPart = 0; uNewPos.u.LowPart = 0; hr = IWICStream_SetSize(pSubStream, uNewPos); - ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "SetSize returned %#lx, expected %#lx\n", hr, E_NOTIMPL); uNewPos.QuadPart = -10; hr = IWICStream_SetSize(pSubStream, uNewPos); - ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "SetSize returned %#lx, expected %#lx\n", hr, E_NOTIMPL); /* CopyTo */ uNewPos.u.HighPart = 0; uNewPos.u.LowPart = 30; hr = IWICStream_CopyTo(pSubStream, NULL, uNewPos, NULL, NULL); - ok(hr == E_NOTIMPL, "CopyTo returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "CopyTo returned %#lx, expected %#lx\n", hr, E_NOTIMPL); hr = CreateStreamOnHGlobal(NULL, TRUE, &CopyStream); - ok(hr == S_OK, "CreateStream failed with %#x\n", hr); + ok(hr == S_OK, "CreateStream failed with %#lx\n", hr); hr = IWICStream_CopyTo(pSubStream, CopyStream, uNewPos, NULL, NULL); - ok(hr == E_NOTIMPL, "CopyTo returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "CopyTo returned %#lx, expected %#lx\n", hr, E_NOTIMPL); IStream_Release(CopyStream); /* Commit */ hr = IWICStream_Commit(pSubStream, STGC_DEFAULT); - ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr); hr = IWICStream_Commit(pSubStream, STGC_OVERWRITE); - ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr); hr = IWICStream_Commit(pSubStream, STGC_ONLYIFCURRENT); - ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr); hr = IWICStream_Commit(pSubStream, STGC_DANGEROUSLYCOMMITMERELYTODISKCACHE); - ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr); hr = IWICStream_Commit(pSubStream, STGC_CONSOLIDATE); - ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr); /* Revert */ IWICStream_Write(pSubStream, &MemBuf[5], 6, NULL); hr = IWICStream_Revert(pSubStream); - ok(hr == E_NOTIMPL, "Revert returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "Revert returned %#lx, expected %#lx\n", hr, E_NOTIMPL); memcpy(Memory, CmpMem, sizeof(Memory)); /* LockRegion/UnlockRegion */ hr = IWICStream_LockRegion(pSubStream, uLargeNull, uLargeNull, 0); - ok(hr == E_NOTIMPL, "LockRegion returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "LockRegion returned %#lx, expected %#lx\n", hr, E_NOTIMPL); hr = IWICStream_UnlockRegion(pSubStream, uLargeNull, uLargeNull, 0); - ok(hr == E_NOTIMPL, "UnlockRegion returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "UnlockRegion returned %#lx, expected %#lx\n", hr, E_NOTIMPL); /* Stat */ hr = IWICStream_Stat(pSubStream, NULL, 0); - ok(hr == E_INVALIDARG, "Stat returned %#x, expected %#x\n", hr, E_INVALIDARG); + ok(hr == E_INVALIDARG, "Stat returned %#lx, expected %#lx\n", hr, E_INVALIDARG); hr = IWICStream_Stat(pSubStream, &Stats, 0); - ok(hr == S_OK, "Stat returned %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Stat returned %#lx, expected %#lx\n", hr, S_OK); ok(Stats.pwcsName == NULL, "Stat returned name %p, expected %p\n", Stats.pwcsName, NULL); - ok(Stats.type == STGTY_STREAM, "Stat returned type %d, expected %d\n", Stats.type, STGTY_STREAM); - ok(Stats.cbSize.u.HighPart == 0 && Stats.cbSize.u.LowPart == 20, "Stat returned size (%u;%u)\n", Stats.cbSize.u.HighPart, Stats.cbSize.u.LowPart); - ok(Stats.mtime.dwHighDateTime == 0 && Stats.mtime.dwLowDateTime == 0, "Stat returned mtime (%u;%u), expected (%u;%u)\n", Stats.mtime.dwHighDateTime, Stats.mtime.dwLowDateTime, 0, 0); - ok(Stats.ctime.dwHighDateTime == 0 && Stats.ctime.dwLowDateTime == 0, "Stat returned ctime (%u;%u), expected (%u;%u)\n", Stats.ctime.dwHighDateTime, Stats.ctime.dwLowDateTime, 0, 0); - ok(Stats.atime.dwHighDateTime == 0 && Stats.atime.dwLowDateTime == 0, "Stat returned atime (%u;%u), expected (%u;%u)\n", Stats.atime.dwHighDateTime, Stats.atime.dwLowDateTime, 0, 0); - ok(Stats.grfMode == 0, "Stat returned access mode %d, expected %d\n", Stats.grfMode, 0); - ok(Stats.grfLocksSupported == 0, "Stat returned supported locks %#x, expected %#x\n", Stats.grfLocksSupported, 0); - ok(Stats.grfStateBits == 0, "Stat returned state bits %#x, expected %#x\n", Stats.grfStateBits, 0); + ok(Stats.type == STGTY_STREAM, "Stat returned type %ld, expected %d\n", Stats.type, STGTY_STREAM); + ok(Stats.cbSize.u.HighPart == 0 && Stats.cbSize.u.LowPart == 20, "Stat returned size (%lu;%lu)\n", Stats.cbSize.u.HighPart, Stats.cbSize.u.LowPart); + ok(Stats.mtime.dwHighDateTime == 0 && Stats.mtime.dwLowDateTime == 0, "Stat returned mtime (%lu;%lu), expected (%u;%u)\n", Stats.mtime.dwHighDateTime, Stats.mtime.dwLowDateTime, 0, 0); + ok(Stats.ctime.dwHighDateTime == 0 && Stats.ctime.dwLowDateTime == 0, "Stat returned ctime (%lu;%lu), expected (%u;%u)\n", Stats.ctime.dwHighDateTime, Stats.ctime.dwLowDateTime, 0, 0); + ok(Stats.atime.dwHighDateTime == 0 && Stats.atime.dwLowDateTime == 0, "Stat returned atime (%lu;%lu), expected (%u;%u)\n", Stats.atime.dwHighDateTime, Stats.atime.dwLowDateTime, 0, 0); + ok(Stats.grfMode == 0, "Stat returned access mode %ld, expected %d\n", Stats.grfMode, 0); + ok(Stats.grfLocksSupported == 0, "Stat returned supported locks %#lx, expected %#x\n", Stats.grfLocksSupported, 0); + ok(Stats.grfStateBits == 0, "Stat returned state bits %#lx, expected %#x\n", Stats.grfStateBits, 0); /* Clone */ hr = IWICStream_Clone(pSubStream, &CopyStream); - ok(hr == E_NOTIMPL, "Clone returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "Clone returned %#lx, expected %#lx\n", hr, E_NOTIMPL); IWICStream_Release(pSubStream); @@ -700,30 +700,30 @@ static void test_StreamOnStreamRange(void) /* Recreate, this time larger than the original. */ hr = IWICImagingFactory_CreateStream(pFactory, &pSubStream); - ok(hr == S_OK, "CreateStream returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "CreateStream returned with %#lx, expected %#lx\n", hr, S_OK); uNewPos.QuadPart = 48; uSize.QuadPart = 32; hr = IWICStream_InitializeFromIStreamRegion(pSubStream, (IStream*)pStream, uNewPos, uSize); - ok(hr == S_OK, "InitializeFromMemory returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "InitializeFromMemory returned with %#lx, expected %#lx\n", hr, S_OK); hr = IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_END, &uNewPos); - ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK); - ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 16, "Seek cursor moved to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, 16); + ok(hr == S_OK, "Seek returned with %#lx, expected %#lx\n", hr, S_OK); + ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 16, "Seek cursor moved to position (%lu;%lu), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, 16); IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL); hr = IWICStream_Read(pSubStream, Memory, 48, &uBytesRead); - ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK); if(SUCCEEDED(hr)) { - ok(uBytesRead == 16, "Read %u bytes\n", uBytesRead); + ok(uBytesRead == 16, "Read %lu bytes\n", uBytesRead); ok(memcmp(Memory, CmpMem+48, uBytesRead) == 0, "Read returned invalid data!\n"); } IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL); uBytesWritten = 0xdeadbeef; hr = IWICStream_Write(pSubStream, CmpMem, 32, &uBytesWritten); - ok(hr == STG_E_MEDIUMFULL, "Write returned with %#x, expected %#x\n", hr, STG_E_MEDIUMFULL); - ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %u\n", uBytesWritten); + ok(hr == STG_E_MEDIUMFULL, "Write returned with %#lx, expected %#lx\n", hr, STG_E_MEDIUMFULL); + ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %lu\n", uBytesWritten); CHECK_CUR_POS(pSubStream, 0); CHECK_CUR_POS(pStream, 0); @@ -759,49 +759,49 @@ static void test_StreamOnIStream(void) hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void **)&factory); - ok(hr == S_OK, "Failed to create a factory, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to create a factory, hr %#lx.\n", hr); hr = IWICImagingFactory_CreateStream(factory, &stream); - ok(hr == S_OK, "Failed to create a stream, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to create a stream, hr %#lx.\n", hr); hr = IWICStream_InitializeFromMemory(stream, memory, sizeof(memory)); - ok(hr == S_OK, "Failed to initialize stream, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to initialize stream, hr %#lx.\n", hr); hr = IWICImagingFactory_CreateStream(factory, &substream); - ok(hr == S_OK, "Failed to create a stream, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to create a stream, hr %#lx.\n", hr); pos.QuadPart = 1; hr = IWICStream_Seek(stream, pos, STREAM_SEEK_SET, &newpos); - ok(hr == S_OK, "Failed to set position, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to set position, hr %#lx.\n", hr); CHECK_CUR_POS(stream, 1); hr = IWICStream_InitializeFromIStream(substream, (IStream *)stream); - ok(hr == S_OK, "Failed to initialize stream, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to initialize stream, hr %#lx.\n", hr); CHECK_CUR_POS(substream, 1); /* Seek */ CHECK_CUR_POS(stream, 1); hr = IWICStream_Seek(substream, zero_pos, STREAM_SEEK_END, &newpos); - ok(hr == S_OK, "Failed to seek a stream, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to seek a stream, hr %#lx.\n", hr); ok(newpos.QuadPart == sizeof(memory), "Unexpected position %s.\n", wine_dbgstr_longlong(newpos.QuadPart)); CHECK_CUR_POS(substream, sizeof(memory)); CHECK_CUR_POS(stream, sizeof(memory)); hr = IWICStream_Seek(substream, zero_pos, STREAM_SEEK_SET, &newpos); - ok(hr == S_OK, "Failed to seek a stream, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to seek a stream, hr %#lx.\n", hr); ok(newpos.QuadPart == 0, "Unexpected position %s.\n", wine_dbgstr_longlong(newpos.QuadPart)); CHECK_CUR_POS(stream, 0); CHECK_CUR_POS(substream, 0); hr = IWICStream_Seek(substream, zero_pos, STREAM_SEEK_SET, NULL); - ok(hr == S_OK, "Failed to seek a stream, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to seek a stream, hr %#lx.\n", hr); pos.u.HighPart = 1; pos.u.LowPart = 0; newpos.u.HighPart = 0xdeadbeef; newpos.u.LowPart = 0xdeadbeef; hr = IWICStream_Seek(substream, pos, STREAM_SEEK_SET, &newpos); - ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "Unexpected hr %#x.\n", hr); + ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "Unexpected hr %#lx.\n", hr); ok(newpos.u.HighPart == 0xdeadbeef && newpos.u.LowPart == 0xdeadbeef, "Unexpected position %s.\n", wine_dbgstr_longlong(newpos.QuadPart)); CHECK_CUR_POS(stream, 0); @@ -811,7 +811,7 @@ static void test_StreamOnIStream(void) newpos.u.HighPart = 0xdeadbeef; newpos.u.LowPart = 0xdeadbeef; hr = IWICStream_Seek(substream, pos, STREAM_SEEK_SET, &newpos); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); ok(newpos.u.HighPart == 0xdeadbeef && newpos.u.LowPart == 0xdeadbeef, "Unexpected position %s.\n", wine_dbgstr_longlong(newpos.QuadPart)); CHECK_CUR_POS(stream, 0); @@ -821,7 +821,7 @@ static void test_StreamOnIStream(void) newpos.u.HighPart = 0xdeadbeef; newpos.u.LowPart = 0xdeadbeef; hr = IWICStream_Seek(substream, pos, STREAM_SEEK_END, &newpos); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); ok(newpos.u.HighPart == 0xdeadbeef && newpos.u.LowPart == 0xdeadbeef, "Unexpected position %s.\n", wine_dbgstr_longlong(newpos.QuadPart)); CHECK_CUR_POS(stream, 0); @@ -829,7 +829,7 @@ static void test_StreamOnIStream(void) pos.QuadPart = -1; hr = IWICStream_Seek(substream, pos, STREAM_SEEK_END, &newpos); - ok(hr == S_OK, "Failed to seek a stream, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to seek a stream, hr %#lx.\n", hr); ok(newpos.QuadPart == sizeof(memory) - 1, "Unexpected position %s.\n", wine_dbgstr_longlong(newpos.QuadPart)); CHECK_CUR_POS(stream, sizeof(memory) - 1); CHECK_CUR_POS(substream, sizeof(memory) - 1); @@ -838,8 +838,8 @@ static void test_StreamOnIStream(void) /* Read */ hr = IWICStream_Read(substream, buff, 12, &read_len); - ok(hr == S_OK, "Failed to read from stream, hr %#x.\n", hr); - ok(read_len == 12, "Unexpected read length %u.\n", read_len); + ok(hr == S_OK, "Failed to read from stream, hr %#lx.\n", hr); + ok(read_len == 12, "Unexpected read length %lu.\n", read_len); ok(!memcmp(buff, data, 12), "Unexpected data.\n"); CHECK_CUR_POS(substream, read_len); CHECK_CUR_POS(stream, read_len); @@ -848,39 +848,39 @@ static void test_StreamOnIStream(void) CHECK_CUR_POS(stream, 0); hr = IWICStream_Read(substream, memory, 10, &read_len); /* source = dest */ - ok(hr == S_OK, "Failed to read from stream, hr %#x.\n", hr); - ok(read_len == 10, "Unexpected read length %u.\n", read_len); + ok(hr == S_OK, "Failed to read from stream, hr %#lx.\n", hr); + ok(read_len == 10, "Unexpected read length %lu.\n", read_len); ok(!memcmp(memory, data, read_len), "Unexpected data.\n"); CHECK_CUR_POS(stream, 10); IWICStream_Seek(substream, zero_pos, STREAM_SEEK_SET, NULL); hr = IWICStream_Read(substream, memory, 2 * sizeof(data), &read_len); /* request too many bytes */ - ok(hr == S_OK, "Failed to read from stream, hr %#x.\n", hr); - ok(read_len == 64, "Unexpected read length %u.\n", read_len); + ok(hr == S_OK, "Failed to read from stream, hr %#lx.\n", hr); + ok(read_len == 64, "Unexpected read length %lu.\n", read_len); ok(!memcmp(memory, data, read_len), "Unexpected data.\n"); CHECK_CUR_POS(stream, sizeof(data)); IWICStream_Seek(substream, zero_pos, STREAM_SEEK_SET, NULL); read_len = 0xdeadbeef; hr = IWICStream_Read(substream, NULL, 1, &read_len); /* destination buffer = NULL */ - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); - ok(read_len == 0xdeadbeef, "Unexpected read length %u.\n", read_len); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + ok(read_len == 0xdeadbeef, "Unexpected read length %lu.\n", read_len); read_len = 1; hr = IWICStream_Read(substream, buff, 0, &read_len); /* read 0 bytes */ - ok(hr == S_OK, "Failed to read from stream, hr %#x.\n", hr); - ok(read_len == 0, "Unexpected read length %u.\n", read_len); + ok(hr == S_OK, "Failed to read from stream, hr %#lx.\n", hr); + ok(read_len == 0, "Unexpected read length %lu.\n", read_len); read_len = 0xdeadbeef; hr = IWICStream_Read(substream, NULL, 0, &read_len); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); - ok(read_len == 0xdeadbeef, "Unexpected read length %u.\n", read_len); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + ok(read_len == 0xdeadbeef, "Unexpected read length %lu.\n", read_len); hr = IWICStream_Read(substream, NULL, 0, NULL); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); hr = IWICStream_Read(substream, buff, 1, NULL); - ok(hr == S_OK, "Failed to read from stream, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to read from stream, hr %#lx.\n", hr); CHECK_CUR_POS(substream, 1); CHECK_CUR_POS(stream, 1); IWICStream_Seek(substream, zero_pos, STREAM_SEEK_SET, NULL); @@ -890,27 +890,27 @@ static void test_StreamOnIStream(void) buff[i] = data[i] + 1; hr = IWICStream_Write(substream, buff, 3, &written); - ok(hr == S_OK, "Failed to write to stream, hr %#x.\n", hr); - ok(written == 3, "Unexpected written length %u.\n", written); + ok(hr == S_OK, "Failed to write to stream, hr %#lx.\n", hr); + ok(written == 3, "Unexpected written length %lu.\n", written); ok(!memcmp(buff, memory, 3), "Unexpected stream data.\n"); CHECK_CUR_POS(substream, written); CHECK_CUR_POS(stream, written); IWICStream_Seek(substream, zero_pos, STREAM_SEEK_SET, NULL); hr = IWICStream_Write(substream, buff, 0, &written); - ok(hr == S_OK, "Failed to write to stream, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to write to stream, hr %#lx.\n", hr); written = 0xdeadbeef; hr = IWICStream_Write(substream, NULL, 3, &written); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); - ok(written == 0xdeadbeef, "Unexpected written length %u.\n", written); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + ok(written == 0xdeadbeef, "Unexpected written length %lu.\n", written); CHECK_CUR_POS(substream, 0); CHECK_CUR_POS(stream, 0); written = 0xdeadbeef; hr = IWICStream_Write(substream, NULL, 0, &written); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); - ok(written == 0xdeadbeef, "Unexpected written length %u.\n", written); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + ok(written == 0xdeadbeef, "Unexpected written length %lu.\n", written); CHECK_CUR_POS(substream, 0); CHECK_CUR_POS(stream, 0); @@ -918,90 +918,90 @@ static void test_StreamOnIStream(void) newpos.u.HighPart = 0; newpos.u.LowPart = sizeof(memory) + 10; hr = IWICStream_SetSize(substream, newpos); - ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr); newpos.u.HighPart = 0; newpos.u.LowPart = sizeof(memory); hr = IWICStream_SetSize(substream, newpos); - ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr); newpos.u.HighPart = 0; newpos.u.LowPart = sizeof(memory) - 10; hr = IWICStream_SetSize(substream, newpos); - ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr); newpos.QuadPart = 0; hr = IWICStream_SetSize(substream, newpos); - ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr); newpos.QuadPart = -10; hr = IWICStream_SetSize(substream, newpos); - ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr); /* CopyTo */ newpos.u.HighPart = 0; newpos.u.LowPart = 30; hr = IWICStream_CopyTo(substream, NULL, newpos, NULL, NULL); - ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr); hr = CreateStreamOnHGlobal(NULL, TRUE, ©_stream); - ok(hr == S_OK, "Failed to create a stream, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to create a stream, hr %#lx.\n", hr); hr = IWICStream_CopyTo(substream, copy_stream, newpos, NULL, NULL); - ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr); IStream_Release(copy_stream); /* Commit */ hr = IWICStream_Commit(substream, STGC_DEFAULT); - ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr); hr = IWICStream_Commit(substream, STGC_OVERWRITE); - ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr); hr = IWICStream_Commit(substream, STGC_ONLYIFCURRENT); - ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr); hr = IWICStream_Commit(substream, STGC_DANGEROUSLYCOMMITMERELYTODISKCACHE); - ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr); hr = IWICStream_Commit(substream, STGC_CONSOLIDATE); - ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr); /* Revert */ IWICStream_Write(substream, buff + 5, 6, NULL); hr = IWICStream_Revert(substream); - ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr); memcpy(memory, data, sizeof(memory)); /* LockRegion/UnlockRegion */ hr = IWICStream_LockRegion(substream, uzero, uzero, 0); - ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr); hr = IWICStream_UnlockRegion(substream, uzero, uzero, 0); - ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr); /* Stat */ hr = IWICStream_Stat(substream, NULL, 0); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); hr = IWICStream_Stat(substream, &stats, 0); - ok(hr == S_OK, "Failed to get stream stats, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to get stream stats, hr %#lx.\n", hr); ok(stats.pwcsName == NULL, "Unexpected name %p.\n", stats.pwcsName); - ok(stats.type == STGTY_STREAM, "Unexpected type %d.\n", stats.type); + ok(stats.type == STGTY_STREAM, "Unexpected type %ld.\n", stats.type); ok(stats.cbSize.QuadPart == sizeof(data), "Unexpected size %s.\n", wine_dbgstr_longlong(stats.cbSize.QuadPart)); - ok(stats.mtime.dwHighDateTime == 0 && stats.mtime.dwLowDateTime == 0, "Unexpected mtime (%u;%u).\n", + ok(stats.mtime.dwHighDateTime == 0 && stats.mtime.dwLowDateTime == 0, "Unexpected mtime (%lu;%lu).\n", stats.mtime.dwHighDateTime, stats.mtime.dwLowDateTime); - ok(stats.ctime.dwHighDateTime == 0 && stats.ctime.dwLowDateTime == 0, "Unexpected ctime (%u;%u).\n", + ok(stats.ctime.dwHighDateTime == 0 && stats.ctime.dwLowDateTime == 0, "Unexpected ctime (%lu;%lu).\n", stats.ctime.dwHighDateTime, stats.ctime.dwLowDateTime); - ok(stats.atime.dwHighDateTime == 0 && stats.atime.dwLowDateTime == 0, "Unexpected atime (%u;%u).\n", + ok(stats.atime.dwHighDateTime == 0 && stats.atime.dwLowDateTime == 0, "Unexpected atime (%lu;%lu).\n", stats.atime.dwHighDateTime, stats.atime.dwLowDateTime); - ok(stats.grfMode == 0, "Unexpected mode %d.\n", stats.grfMode); - ok(stats.grfLocksSupported == 0, "Unexpected locks support %#x.\n", stats.grfLocksSupported); - ok(stats.grfStateBits == 0, "Unexpected state bits %#x.\n", stats.grfStateBits); + ok(stats.grfMode == 0, "Unexpected mode %ld.\n", stats.grfMode); + ok(stats.grfLocksSupported == 0, "Unexpected locks support %#lx.\n", stats.grfLocksSupported); + ok(stats.grfStateBits == 0, "Unexpected state bits %#lx.\n", stats.grfStateBits); /* Clone */ hr = IWICStream_Clone(substream, ©_stream); - ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr); IWICStream_Release(substream); IWICStream_Release(stream); diff --git a/modules/rostests/winetests/windowscodecs/testlist.c b/modules/rostests/winetests/windowscodecs/testlist.c index 6ea28ad82b1de..f310eba12dbb7 100644 --- a/modules/rostests/winetests/windowscodecs/testlist.c +++ b/modules/rostests/winetests/windowscodecs/testlist.c @@ -6,6 +6,7 @@ extern void func_bitmap(void); extern void func_bmpformat(void); extern void func_converter(void); +extern void func_ddsformat(void); extern void func_gifformat(void); extern void func_icoformat(void); extern void func_info(void); @@ -16,12 +17,14 @@ extern void func_pngformat(void); extern void func_propertybag(void); extern void func_stream(void); extern void func_tiffformat(void); +extern void func_wmpformat(void); const struct test winetest_testlist[] = { { "bitmap", func_bitmap }, { "bmpformat", func_bmpformat }, { "converter", func_converter }, + { "ddsformat", func_ddsformat }, { "gifformat", func_gifformat }, { "icoformat", func_icoformat }, { "info", func_info }, @@ -32,5 +35,6 @@ const struct test winetest_testlist[] = { "propertybag", func_propertybag }, { "stream", func_stream }, { "tiffformat", func_tiffformat }, + { "wmpformat", func_wmpformat }, { 0, 0 } }; diff --git a/modules/rostests/winetests/windowscodecs/tiffformat.c b/modules/rostests/winetests/windowscodecs/tiffformat.c index 0c68904abad7e..9fb2ab6216c36 100644 --- a/modules/rostests/winetests/windowscodecs/tiffformat.c +++ b/modules/rostests/winetests/windowscodecs/tiffformat.c @@ -32,7 +32,7 @@ static void _expect_ref(IUnknown* obj, ULONG ref, int line) ULONG rc; IUnknown_AddRef(obj); rc = IUnknown_Release(obj); - ok_(__FILE__,line)(rc == ref, "expected refcount %d, got %d\n", ref, rc); + ok_(__FILE__,line)(rc == ref, "expected refcount %ld, got %ld\n", ref, rc); } #define IFD_BYTE 1 @@ -75,11 +75,7 @@ static const struct tiff_1bpp_data BYTE pixel_data[4]; } tiff_1bpp_data = { -#ifdef WORDS_BIGENDIAN - 'M' | 'M' << 8, -#else 'I' | 'I' << 8, -#endif 42, FIELD_OFFSET(struct tiff_1bpp_data, number_of_entries), 13, @@ -115,11 +111,7 @@ static const struct tiff_8bpp_alpha BYTE pixel_data[8]; } tiff_8bpp_alpha = { -#ifdef WORDS_BIGENDIAN - 'M' | 'M' << 8, -#else 'I' | 'I' << 8, -#endif 42, FIELD_OFFSET(struct tiff_8bpp_alpha, number_of_entries), 15, @@ -158,11 +150,7 @@ static const struct tiff_8bpp_data BYTE pixel_data[4]; } tiff_8bpp_data = { -#ifdef WORDS_BIGENDIAN - 'M' | 'M' << 8, -#else 'I' | 'I' << 8, -#endif 42, FIELD_OFFSET(struct tiff_8bpp_data, number_of_entries), 14, @@ -234,11 +222,7 @@ static struct tiff_resolution_image_data BYTE pixel_data[4]; } tiff_resolution_image_data = { -#ifdef WORDS_BIGENDIAN - 'M' | 'M' << 8, -#else 'I' | 'I' << 8, -#endif 42, FIELD_OFFSET(struct tiff_resolution_image_data, number_of_entries), 13, @@ -275,11 +259,7 @@ static const struct tiff_24bpp_data BYTE pixel_data[3]; } tiff_24bpp_data = { -#ifdef WORDS_BIGENDIAN - 'M' | 'M' << 8, -#else 'I' | 'I' << 8, -#endif 42, FIELD_OFFSET(struct tiff_1bpp_data, number_of_entries), 13, @@ -315,11 +295,7 @@ static const struct tiff_4bps_bgra BYTE pixel_data[4]; } tiff_4bps_bgra = { -#ifdef WORDS_BIGENDIAN - 'M' | 'M' << 8, -#else 'I' | 'I' << 8, -#endif 42, FIELD_OFFSET(struct tiff_4bps_bgra, number_of_entries), 14, @@ -363,7 +339,7 @@ static IStream *create_stream(const void *data, int data_size) GlobalUnlock(hdata); hr = CreateStreamOnHGlobal(hdata, TRUE, &stream); - ok(hr == S_OK, "CreateStreamOnHGlobal failed, hr=%x\n", hr); + ok(hr == S_OK, "CreateStreamOnHGlobal failed, hr=%lx\n", hr); return stream; } @@ -385,13 +361,13 @@ static HRESULT create_decoder(const void *image_data, UINT image_size, IWICBitma GlobalUnlock(hmem); hr = CreateStreamOnHGlobal(hmem, TRUE, &stream); - ok(hr == S_OK, "CreateStreamOnHGlobal error %#x\n", hr); + ok(hr == S_OK, "CreateStreamOnHGlobal error %#lx\n", hr); hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, decoder); if (hr == S_OK) { hr = IWICBitmapDecoder_GetContainerFormat(*decoder, &format); - ok(hr == S_OK, "GetContainerFormat error %#x\n", hr); + ok(hr == S_OK, "GetContainerFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_ContainerFormatTiff), "wrong container format %s\n", wine_dbgstr_guid(&format)); @@ -402,30 +378,30 @@ static HRESULT create_decoder(const void *image_data, UINT image_size, IWICBitma return hr; } -static HRESULT get_pixelformat_info(const GUID *format, UINT *bpp, UINT *channels, BOOL *trasparency) +static HRESULT get_pixelformat_info(const GUID *format, UINT *bpp, UINT *channels, BOOL *transparency) { HRESULT hr; IWICComponentInfo *info; IWICPixelFormatInfo2 *formatinfo; hr = IWICImagingFactory_CreateComponentInfo(factory, format, &info); - ok(hr == S_OK, "CreateComponentInfo(%s) error %#x\n", wine_dbgstr_guid(format), hr); + ok(hr == S_OK, "CreateComponentInfo(%s) error %#lx\n", wine_dbgstr_guid(format), hr); if (hr == S_OK) { hr = IWICComponentInfo_QueryInterface(info, &IID_IWICPixelFormatInfo2, (void **)&formatinfo); if (hr == S_OK) { - hr = IWICPixelFormatInfo2_SupportsTransparency(formatinfo, trasparency); - ok(hr == S_OK, "SupportsTransparency error %#x\n", hr); + hr = IWICPixelFormatInfo2_SupportsTransparency(formatinfo, transparency); + ok(hr == S_OK, "SupportsTransparency error %#lx\n", hr); IWICPixelFormatInfo2_Release(formatinfo); } hr = IWICComponentInfo_QueryInterface(info, &IID_IWICPixelFormatInfo, (void **)&formatinfo); if (hr == S_OK) { hr = IWICPixelFormatInfo2_GetBitsPerPixel(formatinfo, bpp); - ok(hr == S_OK, "GetBitsPerPixel error %#x\n", hr); + ok(hr == S_OK, "GetBitsPerPixel error %#lx\n", hr); hr = IWICPixelFormatInfo2_GetChannelCount(formatinfo, channels); - ok(hr == S_OK, "GetChannelCount error %#x\n", hr); + ok(hr == S_OK, "GetChannelCount error %#lx\n", hr); IWICPixelFormatInfo2_Release(formatinfo); } IWICComponentInfo_Release(info); @@ -445,7 +421,7 @@ static void dump_tiff(void *buf) for (i = 0; i < count; i++) { - printf("tag %u: id %04x, type %04x, count %u, value %d", + printf("tag %u: id %04x, type %04x, count %lu, value %ld", i, tag[i].id, tag[i].type, tag[i].count, tag[i].value); if (tag[i].id == 0x102 && tag[i].count > 2) { @@ -466,22 +442,22 @@ static void test_tiff_1bpp_palette(void) GUID format; hr = create_decoder(&tiff_1bpp_data, sizeof(tiff_1bpp_data), &decoder); - ok(hr == S_OK, "Failed to load TIFF image data %#x\n", hr); + ok(hr == S_OK, "Failed to load TIFF image data %#lx\n", hr); if (hr != S_OK) return; hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_WICPixelFormatBlackWhite), "got wrong format %s\n", wine_dbgstr_guid(&format)); hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "CreatePalette error %#x\n", hr); + ok(hr == S_OK, "CreatePalette error %#lx\n", hr); hr = IWICBitmapFrameDecode_CopyPalette(frame, palette); ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, - "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %#x\n", hr); + "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %#lx\n", hr); IWICPalette_Release(palette); IWICBitmapFrameDecode_Release(frame); @@ -501,85 +477,83 @@ static void test_QueryCapability(void) WICBitmapDecoderCapabilityCanDecodeSomeImages; DWORD capability; LARGE_INTEGER pos; - ULARGE_INTEGER cur_pos; UINT frame_count; stream = create_stream(&tiff_1bpp_data, sizeof(tiff_1bpp_data)); if (!stream) return; hr = IWICImagingFactory_CreateDecoder(factory, &GUID_ContainerFormatTiff, NULL, &decoder); - ok(hr == S_OK, "CreateDecoder error %#x\n", hr); + ok(hr == S_OK, "CreateDecoder error %#lx\n", hr); if (FAILED(hr)) return; frame_count = 0xdeadbeef; hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count); - ok(hr == S_OK || broken(hr == E_POINTER) /* XP */, "GetFrameCount error %#x\n", hr); + ok(hr == S_OK || broken(hr == E_POINTER) /* XP */, "GetFrameCount error %#lx\n", hr); ok(frame_count == 0, "expected 0, got %u\n", frame_count); hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == WINCODEC_ERR_FRAMEMISSING || broken(hr == E_POINTER) /* XP */, "expected WINCODEC_ERR_FRAMEMISSING, got %#x\n", hr); + ok(hr == WINCODEC_ERR_FRAMEMISSING || broken(hr == E_POINTER) /* XP */, "expected WINCODEC_ERR_FRAMEMISSING, got %#lx\n", hr); pos.QuadPart = 4; hr = IStream_Seek(stream, pos, SEEK_SET, NULL); - ok(hr == S_OK, "IStream_Seek error %#x\n", hr); + ok(hr == S_OK, "IStream_Seek error %#lx\n", hr); capability = 0xdeadbeef; hr = IWICBitmapDecoder_QueryCapability(decoder, stream, &capability); - ok(hr == S_OK, "QueryCapability error %#x\n", hr); + ok(hr == S_OK, "QueryCapability error %#lx\n", hr); ok(capability == exp_caps || capability == exp_caps_xp, - "expected %#x, got %#x\n", exp_caps, capability); + "expected %#lx, got %#lx\n", exp_caps, capability); frame_count = 0xdeadbeef; hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count); - ok(hr == S_OK, "GetFrameCount error %#x\n", hr); + ok(hr == S_OK, "GetFrameCount error %#lx\n", hr); ok(frame_count == 1, "expected 1, got %u\n", frame_count); hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); IWICBitmapFrameDecode_Release(frame); - pos.QuadPart = 0; - hr = IStream_Seek(stream, pos, SEEK_CUR, &cur_pos); - ok(hr == S_OK, "IStream_Seek error %#x\n", hr); - ok(cur_pos.QuadPart > 4 && cur_pos.QuadPart < sizeof(tiff_1bpp_data), - "current stream pos is at %x/%x\n", cur_pos.u.LowPart, cur_pos.u.HighPart); + pos.QuadPart = 5; + hr = IStream_Seek(stream, pos, SEEK_SET, NULL); + ok(hr == S_OK, "IStream_Seek error %#lx\n", hr); hr = IWICBitmapDecoder_QueryCapability(decoder, stream, &capability); - ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#x\n", hr); + ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#lx\n", hr); hr = IWICBitmapDecoder_Initialize(decoder, stream, WICDecodeMetadataCacheOnDemand); - ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#x\n", hr); + ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#lx\n", hr); IWICBitmapDecoder_Release(decoder); + /* CreateDecoderFromStream fails if seeked past the start */ hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder); -todo_wine - ok(hr == WINCODEC_ERR_COMPONENTNOTFOUND, "expected WINCODEC_ERR_COMPONENTNOTFOUND, got %#x\n", hr); + todo_wine + ok(hr == WINCODEC_ERR_COMPONENTNOTFOUND, "expected WINCODEC_ERR_COMPONENTNOTFOUND, got %#lx\n", hr); if (SUCCEEDED(hr)) IWICBitmapDecoder_Release(decoder); pos.QuadPart = 0; hr = IStream_Seek(stream, pos, SEEK_SET, NULL); - ok(hr == S_OK, "IStream_Seek error %#x\n", hr); + ok(hr == S_OK, "IStream_Seek error %#lx\n", hr); hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder); - ok(hr == S_OK, "CreateDecoderFromStream error %#x\n", hr); + ok(hr == S_OK, "CreateDecoderFromStream error %#lx\n", hr); frame_count = 0xdeadbeef; hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count); - ok(hr == S_OK, "GetFrameCount error %#x\n", hr); + ok(hr == S_OK, "GetFrameCount error %#lx\n", hr); ok(frame_count == 1, "expected 1, got %u\n", frame_count); hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); IWICBitmapFrameDecode_Release(frame); hr = IWICBitmapDecoder_Initialize(decoder, stream, WICDecodeMetadataCacheOnDemand); - ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#x\n", hr); + ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#lx\n", hr); hr = IWICBitmapDecoder_QueryCapability(decoder, stream, &capability); - ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#x\n", hr); + ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#lx\n", hr); IWICBitmapDecoder_Release(decoder); IStream_Release(stream); @@ -600,39 +574,39 @@ static void test_tiff_8bpp_alpha(void) 0x55,0x55,0x55,0x66,0x77,0x77,0x77,0x88 }; hr = create_decoder(&tiff_8bpp_alpha, sizeof(tiff_8bpp_alpha), &decoder); - ok(hr == S_OK, "Failed to load TIFF image data %#x\n", hr); + ok(hr == S_OK, "Failed to load TIFF image data %#lx\n", hr); if (hr != S_OK) return; hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count); - ok(hr == S_OK, "GetFrameCount error %#x\n", hr); + ok(hr == S_OK, "GetFrameCount error %#lx\n", hr); ok(frame_count == 1, "expected 1, got %u\n", frame_count); EXPECT_REF(decoder, 1); hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); EXPECT_REF(decoder, 2); IWICBitmapDecoder_Release(decoder); hr = IWICBitmapFrameDecode_GetSize(frame, &width, &height); - ok(hr == S_OK, "GetSize error %#x\n", hr); + ok(hr == S_OK, "GetSize error %#lx\n", hr); ok(width == 2, "expected 2, got %u\n", width); ok(height == 2, "expected 2, got %u\n", height); hr = IWICBitmapFrameDecode_GetResolution(frame, &dpi_x, &dpi_y); - ok(hr == S_OK, "GetResolution error %#x\n", hr); + ok(hr == S_OK, "GetResolution error %#lx\n", hr); ok(dpi_x == 96.0, "expected 96.0, got %f\n", dpi_x); ok(dpi_y == 96.0, "expected 96.0, got %f\n", dpi_y); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_WICPixelFormat32bppPBGRA), "got wrong format %s\n", wine_dbgstr_guid(&format)); hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "CreatePalette error %#x\n", hr); + ok(hr == S_OK, "CreatePalette error %#lx\n", hr); hr = IWICBitmapFrameDecode_CopyPalette(frame, palette); ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, - "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %#x\n", hr); + "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %#lx\n", hr); IWICPalette_Release(palette); rc.X = 0; @@ -640,7 +614,7 @@ static void test_tiff_8bpp_alpha(void) rc.Width = 2; rc.Height = 2; hr = IWICBitmapFrameDecode_CopyPixels(frame, &rc, 8, sizeof(data), data); - ok(hr == S_OK, "CopyPixels error %#x\n", hr); + ok(hr == S_OK, "CopyPixels error %#lx\n", hr); for (i = 0; i < sizeof(data); i++) ok(data[i] == expected_data[i], "%u: expected %02x, got %02x\n", i, expected_data[i], data[i]); @@ -693,28 +667,28 @@ static void test_tiff_8bpp_palette(void) generate_tiff_palette(buf + FIELD_OFFSET(struct tiff_8bpp_data, palette_data), 256); hr = create_decoder(buf, sizeof(buf), &decoder); - ok(hr == S_OK, "Failed to load TIFF image data %#x\n", hr); + ok(hr == S_OK, "Failed to load TIFF image data %#lx\n", hr); if (hr != S_OK) return; hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed), "expected GUID_WICPixelFormat8bppIndexed, got %s\n", wine_dbgstr_guid(&format)); hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "CreatePalette error %#x\n", hr); + ok(hr == S_OK, "CreatePalette error %#lx\n", hr); hr = IWICBitmapFrameDecode_CopyPalette(frame, palette); - ok(hr == S_OK, "CopyPalette error %#x\n", hr); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 256, "expected 256, got %u\n", count); hr = IWICPalette_GetColors(palette, 256, color, &ret); - ok(hr == S_OK, "GetColors error %#x\n", hr); + ok(hr == S_OK, "GetColors error %#lx\n", hr); ok(ret == count, "expected %u, got %u\n", count, ret); ok(color[0] == 0xff112233, "got %#x\n", color[0]); ok(color[1] == 0xff445566, "got %#x\n", color[1]); @@ -742,14 +716,14 @@ static void test_tiff_resolution(void) tiff_resolution_image_data.entry[12].value = test_data->resolution_unit; hr = create_decoder(&tiff_resolution_image_data, sizeof(tiff_resolution_image_data), &decoder); - ok(hr == S_OK, "Failed to load TIFF image data %#x\n", hr); + ok(hr == S_OK, "Failed to load TIFF image data %#lx\n", hr); if (hr != S_OK) return; hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "%d: GetFrame error %#x\n", i, hr); + ok(hr == S_OK, "%d: GetFrame error %#lx\n", i, hr); hr = IWICBitmapFrameDecode_GetResolution(frame, &dpi_x, &dpi_y); - ok(hr == S_OK, "%d: GetResolution error %#x\n", i, hr); + ok(hr == S_OK, "%d: GetResolution error %#lx\n", i, hr); if (test_data->broken_dpi_x != 0) { @@ -791,29 +765,29 @@ static void test_tiff_24bpp(void) static const BYTE expected_data[] = { 0x33,0x22,0x11 }; hr = create_decoder(&tiff_24bpp_data, sizeof(tiff_24bpp_data), &decoder); - ok(hr == S_OK, "Failed to load TIFF image data %#x\n", hr); + ok(hr == S_OK, "Failed to load TIFF image data %#lx\n", hr); if (hr != S_OK) return; ok(decoder != NULL, "Failed to load TIFF image data\n"); hr = IWICBitmapDecoder_GetFrameCount(decoder, &count); - ok(hr == S_OK, "GetFrameCount error %#x\n", hr); + ok(hr == S_OK, "GetFrameCount error %#lx\n", hr); ok(count == 1, "got %u\n", count); hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICBitmapFrameDecode_GetSize(frame, &width, &height); - ok(hr == S_OK, "GetSize error %#x\n", hr); + ok(hr == S_OK, "GetSize error %#lx\n", hr); ok(width == 1, "got %u\n", width); ok(height == 1, "got %u\n", height); hr = IWICBitmapFrameDecode_GetResolution(frame, &dpi_x, &dpi_y); - ok(hr == S_OK, "GetResolution error %#x\n", hr); + ok(hr == S_OK, "GetResolution error %#lx\n", hr); ok(dpi_x == 300.0, "got %f\n", dpi_x); ok(dpi_y == 300.0, "got %f\n", dpi_y); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_WICPixelFormat24bppBGR), "got wrong format %s\n", wine_dbgstr_guid(&format)); @@ -826,10 +800,10 @@ static void test_tiff_24bpp(void) rc.Height = 1; hr = IWICBitmapFrameDecode_CopyPixels(frame, &rc, stride, sizeof(data), data); if (stride < 3) - ok(hr == E_INVALIDARG, "CopyPixels(%u) should fail: %#x\n", stride, hr); + ok(hr == E_INVALIDARG, "CopyPixels(%u) should fail: %#lx\n", stride, hr); else { - ok(hr == S_OK, "CopyPixels(%u) error %#x\n", stride, hr); + ok(hr == S_OK, "CopyPixels(%u) error %#lx\n", stride, hr); for (i = 0; i < sizeof(data); i++) ok(data[i] == expected_data[i], "%u: expected %02x, got %02x\n", i, expected_data[i], data[i]); @@ -847,7 +821,7 @@ static const struct tiff_1x1_data USHORT version; ULONG dir_offset; USHORT number_of_entries; - struct IFD_entry entry[12]; + struct IFD_entry entry[13]; ULONG next_IFD; struct IFD_rational res; short palette_data[3][256]; @@ -855,14 +829,10 @@ static const struct tiff_1x1_data BYTE pixel_data[32]; } tiff_1x1_data = { -#ifdef WORDS_BIGENDIAN - 'M' | 'M' << 8, -#else 'I' | 'I' << 8, -#endif 42, FIELD_OFFSET(struct tiff_1x1_data, number_of_entries), - 12, + 13, { { 0xff, IFD_SHORT, 1, 0 }, /* SUBFILETYPE */ { 0x100, IFD_LONG, 1, 1 }, /* IMAGEWIDTH */ @@ -875,7 +845,8 @@ static const struct tiff_1x1_data { 0x11a, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_1x1_data, res) }, { 0x11b, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_1x1_data, res) }, { 0x128, IFD_SHORT, 1, 2 }, /* RESOLUTIONUNIT */ - { 0x140, IFD_SHORT, 256*3, FIELD_OFFSET(struct tiff_1x1_data, palette_data) } /* COLORMAP */ + { 0x140, IFD_SHORT, 256*3, FIELD_OFFSET(struct tiff_1x1_data, palette_data) }, /* COLORMAP */ + { 0x152, IFD_SHORT, 1, 1 } /* EXTRASAMPLES: 1 - Associated alpha with pre-multiplied color */ }, 0, { 96, 1 }, @@ -925,21 +896,37 @@ static void test_color_formats(void) { 32, 5, 2, &GUID_WICPixelFormat32bppBGRA, bits_1bpsBGRA }; + static const struct bitmap_data data_1bpsPBGRA = + { + 32, 5, 2, &GUID_WICPixelFormat32bppPBGRA, bits_1bpsBGRA + }; static const BYTE bits_4bpsBGRA[] = { 204,85,85,51,85,136,187,85,0,68,0,85,0,102,0,119,0,136,0,153,0,0,0,17,0,34,0,51 }; static const struct bitmap_data data_4bpsBGRA = { 32, 5, 2, &GUID_WICPixelFormat32bppBGRA, bits_4bpsBGRA }; + static const struct bitmap_data data_4bpsPBGRA = + { + 32, 5, 2, &GUID_WICPixelFormat32bppPBGRA, bits_4bpsBGRA + }; static const BYTE bits_8bpsBGRA[] = { 2,0,1,3,6,5,4,7,0,9,8,1,4,3,2,5 }; static const struct bitmap_data data_8bpsBGRA = { 32, 4, 1, &GUID_WICPixelFormat32bppBGRA, bits_8bpsBGRA }; + static const struct bitmap_data data_8bpsPBGRA = + { + 32, 4, 1, &GUID_WICPixelFormat32bppPBGRA, bits_8bpsBGRA + }; static const BYTE bits_64bppRGBA[] = { 1,0,2,3,4,5,6,7,8,9,0,1,2,3,4,5 }; static const struct bitmap_data data_64bppRGBA = { 64, 2, 1, &GUID_WICPixelFormat64bppRGBA, bits_64bppRGBA }; + static const struct bitmap_data data_64bppPRGBA = + { + 64, 2, 1, &GUID_WICPixelFormat64bppPRGBA, bits_64bppRGBA + }; static const BYTE bits_BlackWhite[] = { 85,195,184,85 }; static const struct bitmap_data data_BlackWhite = { @@ -975,18 +962,20 @@ static void test_color_formats(void) { 32, 3, 1, &GUID_WICPixelFormat32bppGrayFloat, bits_32bppGrayFloat }; -#if 0 /* FIXME */ - static const BYTE bits_96bpp3Channels[] = { 0 }; - static const struct bitmap_data data_96bpp3Channels = + static const BYTE bits_96bppRGBFloat[] = { 1,0,2,3,4,5,6,7,8,9,0,1 }; + static const struct bitmap_data data_96bppRGBFloat = { - 64, 1, 1, &GUID_WICPixelFormat96bpp3Channels, bits_96bpp3Channels + 96, 1, 1, &GUID_WICPixelFormat96bppRGBFloat, bits_96bppRGBFloat }; -#endif static const BYTE bits_128bppRGBAFloat[] = { 1,0,2,3,4,5,6,7,8,9,0,1,2,3,4,5 }; static const struct bitmap_data data_128bppRGBAFloat = { 128, 1, 1, &GUID_WICPixelFormat128bppRGBAFloat, bits_128bppRGBAFloat }; + static const struct bitmap_data data_128bppPRGBAFloat = + { + 128, 1, 1, &GUID_WICPixelFormat128bppPRGBAFloat, bits_128bppRGBAFloat + }; static const BYTE bits_1bppIndexed[] = { 85,195,184,85 }; static const struct bitmap_data data_1bppIndexed = { @@ -1022,48 +1011,52 @@ static void test_color_formats(void) int photometric; /* PhotometricInterpretation */ int samples; /* SamplesPerPixel */ int bps; /* BitsPerSample */ + int extra_samples; /* ExtraSamples */ const struct bitmap_data *data; const struct bitmap_data *alt_data; } td[] = { /* 2 - RGB */ - { 2, 3, 1, &data_1bpsBGR }, - { 2, 3, 4, &data_4bpsBGR }, - { 2, 3, 8, &data_8bpsBGR }, - { 2, 3, 16, &data_48bppRGB }, - { 2, 3, 24, NULL }, -#if 0 /* FIXME */ - { 2, 3, 32, &data_96bpp3Channels }, -#endif - { 2, 4, 1, &data_1bpsBGRA }, - { 2, 4, 4, &data_4bpsBGRA }, - { 2, 4, 8, &data_8bpsBGRA }, - { 2, 4, 16, &data_64bppRGBA }, - { 2, 4, 24, NULL }, - { 2, 4, 32, &data_128bppRGBAFloat }, + { 2, 3, 1, 0, &data_1bpsBGR }, + { 2, 3, 4, 0, &data_4bpsBGR }, + { 2, 3, 8, 0, &data_8bpsBGR }, + { 2, 3, 16, 0, &data_48bppRGB }, + { 2, 3, 24, 0, NULL }, + { 2, 3, 32, 0, &data_96bppRGBFloat }, + { 2, 4, 1, 0, &data_1bpsBGRA }, + { 2, 4, 1, 1, &data_1bpsPBGRA }, + { 2, 4, 4, 0, &data_4bpsBGRA }, + { 2, 4, 4, 1, &data_4bpsPBGRA }, + { 2, 4, 8, 0, &data_8bpsBGRA }, + { 2, 4, 8, 1, &data_8bpsPBGRA }, + { 2, 4, 16, 0, &data_64bppRGBA }, + { 2, 4, 16, 1, &data_64bppPRGBA }, + { 2, 4, 24, 0, NULL }, + { 2, 4, 32, 0, &data_128bppRGBAFloat }, + { 2, 4, 32, 1, &data_128bppPRGBAFloat }, /* 1 - BlackIsZero (Bilevel) */ - { 1, 1, 1, &data_BlackWhite, &data_BlackWhite_xp }, - { 1, 1, 4, &data_4bppGray, &data_4bppGray_xp }, - { 1, 1, 8, &data_8bppGray }, - { 1, 1, 16, &data_16bppGray }, - { 1, 1, 24, NULL }, - { 1, 1, 32, &data_32bppGrayFloat }, + { 1, 1, 1, 0, &data_BlackWhite, &data_BlackWhite_xp }, + { 1, 1, 4, 0, &data_4bppGray, &data_4bppGray_xp }, + { 1, 1, 8, 0, &data_8bppGray }, + { 1, 1, 16, 0, &data_16bppGray }, + { 1, 1, 24, 0, NULL }, + { 1, 1, 32, 0, &data_32bppGrayFloat }, /* 3 - Palette Color */ - { 3, 1, 1, &data_1bppIndexed }, - { 3, 1, 4, &data_4bppIndexed, &data_4bppIndexed_xp }, - { 3, 1, 8, &data_8bppIndexed }, + { 3, 1, 1, 0, &data_1bppIndexed }, + { 3, 1, 4, 0, &data_4bppIndexed, &data_4bppIndexed_xp }, + { 3, 1, 8, 0, &data_8bppIndexed }, #if 0 /* FIXME: for some reason libtiff replaces photometric 3 by 1 for bps > 8 */ - { 3, 1, 16, &data_8bppIndexed }, - { 3, 1, 24, &data_8bppIndexed }, - { 3, 1, 32, &data_8bppIndexed }, + { 3, 1, 16, 0, &data_8bppIndexed }, + { 3, 1, 24, 0, &data_8bppIndexed }, + { 3, 1, 32, 0, &data_8bppIndexed }, #endif /* 5 - Separated */ - { 5, 4, 1, NULL }, - { 5, 4, 4, NULL }, - { 5, 4, 8, &data_32bppCMYK }, - { 5, 4, 16, &data_64bppCMYK }, - { 5, 4, 24, NULL }, - { 5, 4, 32, NULL }, + { 5, 4, 1, 0, NULL }, + { 5, 4, 4, 0, NULL }, + { 5, 4, 8, 0, &data_32bppCMYK }, + { 5, 4, 16, 0, &data_64bppCMYK }, + { 5, 4, 24, 0, NULL }, + { 5, 4, 32, 0, NULL }, }; BYTE buf[sizeof(tiff_1x1_data)]; BYTE pixels[256]; @@ -1072,9 +1065,9 @@ static void test_color_formats(void) IWICBitmapFrameDecode *frame; GUID format; UINT count, i, bpp, channels, ret; - BOOL trasparency; + BOOL transparency; struct IFD_entry *tag, *tag_photo = NULL, *tag_bps = NULL, *tag_samples = NULL, *tag_colormap = NULL; - struct IFD_entry *tag_width = NULL, *tag_height = NULL; + struct IFD_entry *tag_width = NULL, *tag_height = NULL, *tag_extra_samples = NULL; short *bps; memcpy(buf, &tiff_1x1_data, sizeof(tiff_1x1_data)); @@ -1098,23 +1091,26 @@ static void test_color_formats(void) tag_samples = &tag[i]; else if (tag[i].id == 0x140) /* ColorMap */ tag_colormap = &tag[i]; + else if (tag[i].id == 0x152) /* ExtraSamples */ + tag_extra_samples = &tag[i]; } - ok(tag_bps && tag_photo && tag_samples && tag_colormap, "tag 0x102,0x106,0x115 or 0x140 is missing\n"); - if (!tag_bps || !tag_photo || !tag_samples || !tag_colormap) return; + ok(tag_bps && tag_photo && tag_samples && tag_colormap && tag_extra_samples, "tag 0x102,0x106,0x115,0x140 or 0x152 is missing\n"); + if (!tag_bps || !tag_photo || !tag_samples || !tag_colormap || !tag_extra_samples) return; ok(tag_bps->type == IFD_SHORT, "tag 0x102 should have type IFD_SHORT\n"); bps = (short *)(buf + tag_bps->value); ok(bps[0] == 8 && bps[1] == 8 && bps[2] == 8 && bps[3] == 0, "expected bps 8,8,8,0 got %d,%d,%d,%d\n", bps[0], bps[1], bps[2], bps[3]); - for (i = 0; i < sizeof(td)/sizeof(td[0]); i++) + for (i = 0; i < ARRAY_SIZE(td); i++) { if (td[i].data) { bpp = td[i].samples * td[i].bps; if (winetest_debug > 1) - trace("samples %u, bps %u, bpp %u, width %u => width_bytes %u\n", td[i].samples, td[i].bps, bpp, + trace("photometric %d, samples %d, extra samples %d, bps %d, bpp %u, width %u => width_bytes %u\n", + td[i].photometric, td[i].samples, td[i].extra_samples, td[i].bps, bpp, td[i].data->width, width_bytes(td[i].data->width, bpp)); tag_width->value = td[i].data->width; tag_height->value = td[i].data->height; @@ -1166,11 +1162,22 @@ static void test_color_formats(void) continue; } + if (td[i].extra_samples) + { + tag_extra_samples->id = 0x152; /* ExtraSamples */ + tag_extra_samples->value = td[i].extra_samples; + } + else /* remove ExtraSamples tag */ + { + tag_extra_samples->id = 0x14e; /* NumberOfInks */ + tag_extra_samples->value = td[i].samples; + } + hr = create_decoder(buf, sizeof(buf), &decoder); if (!td[i].data) { - ok(hr == WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT || hr == WINCODEC_ERR_COMPONENTNOTFOUND /* win8+ */ || WINCODEC_ERR_BADIMAGE /* XP */, - "%u: (%d,%d,%d) wrong error %#x\n", i, td[i].photometric, td[i].samples, td[i].bps, hr); + ok(hr == WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT || hr == WINCODEC_ERR_COMPONENTNOTFOUND /* win8+ */ || hr == WINCODEC_ERR_BADIMAGE /* XP */, + "%u: (%d,%d,%d,%d) wrong error %#lx\n", i, td[i].photometric, td[i].samples, td[i].extra_samples, td[i].bps, hr); if (hr == S_OK) { IWICBitmapDecoder_Release(decoder); @@ -1180,34 +1187,41 @@ static void test_color_formats(void) } else ok(hr == S_OK || broken(hr == WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT || hr == WINCODEC_ERR_BADIMAGE) /* XP */, - "%u: failed to load TIFF image data (%d,%d,%d) %#x\n", - i, td[i].photometric, td[i].samples, td[i].bps, hr); + "%u: failed to load TIFF image data (%d,%d,%d,%d) %#lx\n", + i, td[i].photometric, td[i].samples, td[i].extra_samples, td[i].bps, hr); if (hr != S_OK) continue; hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "%u: GetFrame error %#x\n", i, hr); + ok(hr == S_OK, "%u: GetFrame error %#lx\n", i, hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); - ok(hr == S_OK, "%u: GetPixelFormat error %#x\n", i, hr); + ok(hr == S_OK, "%u: GetPixelFormat error %#lx\n", i, hr); + if (IsEqualGUID(td[i].data->format, &GUID_WICPixelFormat96bppRGBFloat) && IsEqualGUID(&format, &GUID_WICPixelFormat128bppRGBFloat)) + { + win_skip("Windows Server 2008 misinterprets 96bppRGBFloat as 128bppRGBFloat, skipping the tests\n"); + IWICBitmapFrameDecode_Release(frame); + IWICBitmapDecoder_Release(decoder); + continue; + } ok(IsEqualGUID(&format, td[i].data->format), - "%u (%d,%d,%d): expected %s, got %s\n", - i, td[i].photometric, td[i].samples, td[i].bps, + "%u (%d,%d,%d,%d): expected %s, got %s\n", + i, td[i].photometric, td[i].samples, td[i].extra_samples, td[i].bps, wine_dbgstr_guid(td[i].data->format), wine_dbgstr_guid(&format)); - trasparency = (td[i].photometric == 2 && td[i].samples == 4); /* for XP */ - hr = get_pixelformat_info(&format, &bpp, &channels, &trasparency); - ok(hr == S_OK, "%u: get_pixelformat_bpp error %#x\n", i, hr); + transparency = (td[i].photometric == 2 && td[i].samples == 4); /* for XP */ + hr = get_pixelformat_info(&format, &bpp, &channels, &transparency); + ok(hr == S_OK, "%u: get_pixelformat_bpp error %#lx\n", i, hr); ok(bpp == td[i].data->bpp, "%u: expected %u, got %u\n", i, td[i].data->bpp, bpp); ok(channels == td[i].samples, "%u: expected %u, got %u\n", i, td[i].samples, channels); - ok(trasparency == (td[i].photometric == 2 && td[i].samples == 4), "%u: got %u\n", i, trasparency); + ok(transparency == (td[i].photometric == 2 && td[i].samples == 4), "%u: got %u\n", i, transparency); memset(pixels, 0, sizeof(pixels)); hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, width_bytes(td[i].data->width, bpp), sizeof(pixels), pixels); - ok(hr == S_OK, "%u: CopyPixels error %#x\n", i, hr); + ok(hr == S_OK, "%u: CopyPixels error %#lx\n", i, hr); ret = memcmp(pixels, td[i].data->bits, width_bytes(td[i].data->width, bpp)); if (ret && td[i].alt_data) ret = memcmp(pixels, td[i].alt_data->bits, width_bytes(td[i].data->width, bpp)); - ok(ret == 0, "%u: (%d,%d,%d) wrong pixel data\n", i, td[i].photometric, td[i].samples, td[i].bps); + ok(ret == 0, "%u: (%d,%d,%d,%d) wrong pixel data\n", i, td[i].photometric, td[i].samples, td[i].extra_samples, td[i].bps); if (ret) { UINT j, n = width_bytes(td[i].data->width, bpp); @@ -1235,36 +1249,36 @@ static void test_tiff_4bps_bgra(void) 0,0xff,0,0, 0xff,0xff,0,0xff, 0xff,0xff,0xff,0 }; hr = create_decoder(&tiff_4bps_bgra, sizeof(tiff_4bps_bgra), &decoder); - ok(hr == S_OK, "Failed to load TIFF image data %#x\n", hr); + ok(hr == S_OK, "Failed to load TIFF image data %#lx\n", hr); if (hr != S_OK) return; hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count); - ok(hr == S_OK, "GetFrameCount error %#x\n", hr); + ok(hr == S_OK, "GetFrameCount error %#lx\n", hr); ok(frame_count == 1, "expected 1, got %u\n", frame_count); hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICBitmapFrameDecode_GetSize(frame, &width, &height); - ok(hr == S_OK, "GetSize error %#x\n", hr); + ok(hr == S_OK, "GetSize error %#lx\n", hr); ok(width == 3, "got %u\n", width); ok(height == 2, "got %u\n", height); hr = IWICBitmapFrameDecode_GetResolution(frame, &dpi_x, &dpi_y); - ok(hr == S_OK, "GetResolution error %#x\n", hr); + ok(hr == S_OK, "GetResolution error %#lx\n", hr); ok(dpi_x == 96.0, "expected 96.0, got %f\n", dpi_x); ok(dpi_y == 96.0, "expected 96.0, got %f\n", dpi_y); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_WICPixelFormat32bppBGRA), "got wrong format %s\n", wine_dbgstr_guid(&format)); hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "CreatePalette error %#x\n", hr); + ok(hr == S_OK, "CreatePalette error %#lx\n", hr); hr = IWICBitmapFrameDecode_CopyPalette(frame, palette); ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, - "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %#x\n", hr); + "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %#lx\n", hr); IWICPalette_Release(palette); memset(data, 0xaa, sizeof(data)); @@ -1273,7 +1287,7 @@ static void test_tiff_4bps_bgra(void) rc.Width = 3; rc.Height = 2; hr = IWICBitmapFrameDecode_CopyPixels(frame, &rc, 12, sizeof(data), data); - ok(hr == S_OK, "CopyPixels error %#x\n", hr); + ok(hr == S_OK, "CopyPixels error %#lx\n", hr); for (i = 0; i < sizeof(data); i++) ok(data[i] == expected_data[i], "%u: expected %02x, got %02x\n", i, expected_data[i], data[i]); @@ -1290,7 +1304,7 @@ START_TEST(tiffformat) hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void **)&factory); - ok(hr == S_OK, "CoCreateInstance error %#x\n", hr); + ok(hr == S_OK, "CoCreateInstance error %#lx\n", hr); if (FAILED(hr)) return; test_tiff_4bps_bgra(); diff --git a/modules/rostests/winetests/windowscodecs/wmpformat.c b/modules/rostests/winetests/windowscodecs/wmpformat.c new file mode 100644 index 0000000000000..365902b3172b4 --- /dev/null +++ b/modules/rostests/winetests/windowscodecs/wmpformat.c @@ -0,0 +1,182 @@ +/* + * 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 + */ + +#define COBJMACROS + +#include "objbase.h" +#include "wincodec.h" +#include "wine/test.h" + +/* generated with JxrEncApp -i image.bmp -o image.jxr -q 1 -c 22 */ +unsigned char wmp_imagedata[] = { + 0x49, 0x49, 0xbc, 0x01, 0x20, 0x00, 0x00, 0x00, 0x24, 0xc3, 0xdd, 0x6f, + 0x03, 0x4e, 0xfe, 0x4b, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x01, 0xbc, + 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0xbc, + 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xbc, + 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x81, 0xbc, + 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x82, 0xbc, + 0x0b, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x42, 0x83, 0xbc, + 0x0b, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x42, 0xc0, 0xbc, + 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00, 0xc1, 0xbc, + 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0xaf, 0x00, 0x00, 0x00, 0xc2, 0xbc, + 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x4e, 0x01, 0x00, 0x00, 0xc3, 0xbc, + 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x57, 0x4d, 0x50, 0x48, 0x4f, 0x54, 0x4f, 0x00, 0x11, 0x45, + 0xc0, 0x71, 0x00, 0x00, 0x00, 0x04, 0x60, 0x00, 0xc0, 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x26, 0xff, 0xff, 0x00, 0x00, 0x01, 0x01, 0x51, 0x40, 0xc2, + 0x51, 0x88, 0x00, 0x00, 0x01, 0x02, 0x02, 0x10, 0x08, 0x62, 0x18, 0x84, + 0x21, 0x00, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x18, 0x00, 0x00, 0x80, 0x40, 0x30, 0x00, 0x00, 0x00, 0x01, 0x03, 0x19, + 0x0d, 0x34, 0xd2, 0x77, 0x06, 0x62, 0xe8, 0x89, 0x8b, 0xa2, 0x26, 0x2f, + 0x11, 0xba, 0xbc, 0x46, 0xea, 0xa3, 0x6e, 0xdd, 0x72, 0x23, 0x75, 0x86, + 0xcd, 0x48, 0x73, 0xae, 0x43, 0xb9, 0x67, 0x8d, 0xfd, 0x98, 0xb0, 0xd5, + 0x52, 0x1d, 0xcb, 0x0d, 0x81, 0x06, 0xb4, 0x7d, 0xb8, 0x92, 0x5f, 0xf3, + 0x75, 0xc0, 0x3b, 0xd5, 0x07, 0xcb, 0xd0, 0xec, 0xde, 0x54, 0x1f, 0x7a, + 0x9a, 0x21, 0x8e, 0xcd, 0xe5, 0x4c, 0xdc, 0xce, 0xb8, 0x3e, 0xfa, 0x1d, + 0x8d, 0xca, 0x32, 0x94, 0xd2, 0x93, 0x2c, 0x76, 0x37, 0x2a, 0x63, 0x77, + 0x72, 0xd4, 0xd7, 0x66, 0x5a, 0xdb, 0x66, 0xed, 0x60, 0x00, 0x57, 0x4d, + 0x50, 0x48, 0x4f, 0x54, 0x4f, 0x00, 0x11, 0x45, 0xc0, 0x01, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x80, 0x20, 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x13, 0xff, 0xff, 0x00, 0x00, 0x01, 0x01, 0x91, 0xe2, 0x00, + 0x00, 0x01, 0x02, 0x00, 0x86, 0x00, 0x00, 0x20, 0x10, 0x0c, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x03, 0xad, 0xcf, 0xf4, 0x6b, 0x64, 0x45, 0xe1, 0x91, + 0x17, 0x8e, 0x9a, 0x51, 0x32, 0x1f, 0xe2, 0x02, 0xfa, 0x69, 0x44, 0x3b, + 0xfc, 0x7b, 0xab, 0x20, 0xfe, 0x9d, 0x35, 0xd4, 0xda, 0xb7, 0xcb, 0x77, + 0x5f, 0x4d, 0xe5, 0x0e, 0xee, 0x39, 0x97, 0x6f, 0xb9, 0x99, 0x6b, 0x6d, + 0xcc, 0xb9, 0x60}; + +static void test_decode(void) +{ + IWICBitmapDecoder *decoder; + IWICBitmapFrameDecode *framedecode; + IWICImagingFactory *factory; + IWICPalette *palette; + HRESULT hr; + HGLOBAL hwmpdata; + char *wmpdata; + IStream *wmpstream; + GUID format; + UINT count = 0, width = 0, height = 0; + BYTE imagedata[5 * 4] = {1}; + UINT i, j; + + const BYTE expected_imagedata[5 * 4] = { + 0x6d, 0xb0, 0xfc, 0x00, 0x6d, 0xb0, 0xfc, 0x00, 0x6d, 0xb0, + 0xfc, 0x00, 0x6d, 0xb0, 0xfc, 0x00, 0x6d, 0xb0, 0xfc, 0x00, + }; + + const BYTE broken_imagedata[5 * 4] = { + 0x74, 0xa2, 0xd6, 0x28, 0x73, 0xa1, 0xd4, 0x29, 0x71, 0xa9, + 0xe7, 0x16, 0x71, 0xa9, 0xe7, 0x16, 0x70, 0xa7, 0xe5, 0x17 + }; + + hr = CoCreateInstance(&CLSID_WICWmpDecoder, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICBitmapDecoder, (void **)&decoder); + if (FAILED(hr)) + { + win_skip("WmpDecoder isn't available, skipping test\n"); + return; + } + + hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICImagingFactory, (void **)&factory); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); + + hwmpdata = GlobalAlloc(GMEM_MOVEABLE, sizeof(wmp_imagedata)); + ok(hwmpdata != 0, "GlobalAlloc failed\n"); + + wmpdata = GlobalLock(hwmpdata); + memcpy(wmpdata, wmp_imagedata, sizeof(wmp_imagedata)); + GlobalUnlock(hwmpdata); + + hr = CreateStreamOnHGlobal(hwmpdata, FALSE, &wmpstream); + ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%lx\n", hr); + + hr = IWICBitmapDecoder_Initialize(decoder, wmpstream, WICDecodeMetadataCacheOnLoad); + ok(hr == S_OK, "Initialize failed, hr=%lx\n", hr); + + hr = IWICBitmapDecoder_Initialize(decoder, wmpstream, WICDecodeMetadataCacheOnLoad); + ok(hr == WINCODEC_ERR_WRONGSTATE, "Initialize returned %lx\n", hr); + + hr = IWICBitmapDecoder_GetContainerFormat(decoder, &format); + ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%lx\n", hr); + ok(IsEqualGUID(&format, &GUID_ContainerFormatWmp), + "unexpected container format\n"); + + hr = IWICBitmapDecoder_GetFrameCount(decoder, &count); + ok(SUCCEEDED(hr), "GetFrameCount failed, hr=%lx\n", hr); + ok(count == 1, "unexpected count %u\n", count); + + hr = IWICBitmapDecoder_GetFrame(decoder, 0, NULL); + ok(hr == E_INVALIDARG, "GetFrame(NULL) returned hr=%lx\n", hr); + + for (j = 2; j > 0; --j) + { + hr = IWICBitmapDecoder_GetFrame(decoder, 0, &framedecode); + ok(SUCCEEDED(hr), "GetFrame failed, hr=%lx\n", hr); + + hr = IWICBitmapFrameDecode_GetSize(framedecode, &width, &height); + ok(SUCCEEDED(hr), "GetSize failed, hr=%lx\n", hr); + ok(width == 1, "expected width=1, got %u\n", width); + ok(height == 5, "expected height=5, got %u\n", height); + + hr = IWICBitmapFrameDecode_GetPixelFormat(framedecode, &format); + ok(SUCCEEDED(hr), "GetPixelFormat failed, hr=%lx\n", hr); + ok(IsEqualGUID(&format, &GUID_WICPixelFormat32bppBGRA), + "unexpected pixel format: %s\n", wine_dbgstr_guid(&format)); + + for (i = 2; i > 0; --i) + { + memset(imagedata, 0, sizeof(imagedata)); + hr = IWICBitmapFrameDecode_CopyPixels( + framedecode, NULL, 4, sizeof(imagedata), imagedata); + ok(SUCCEEDED(hr), "CopyPixels failed, hr=%lx\n", hr); + ok(!memcmp(imagedata, expected_imagedata, sizeof(imagedata)) || + broken(!memcmp(imagedata, broken_imagedata, sizeof(imagedata)) /* w2008s64 */), + "unexpected image data\n"); + } + + hr = IWICImagingFactory_CreatePalette(factory, &palette); + ok(SUCCEEDED(hr), "CreatePalette failed, hr=%lx\n", hr); + + hr = IWICBitmapDecoder_CopyPalette(decoder, palette); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "Unexpected hr %#lx.\n", hr); + + hr = IWICBitmapFrameDecode_CopyPalette(framedecode, palette); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "Unexpected hr %#lx.\n", hr); + + IWICPalette_Release(palette); + + IWICBitmapFrameDecode_Release(framedecode); + } + + IStream_Release(wmpstream); + GlobalFree(hwmpdata); + + IWICBitmapDecoder_Release(decoder); + IWICImagingFactory_Release(factory); +} + +START_TEST(wmpformat) +{ + CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + + test_decode(); + + CoUninitialize(); +} diff --git a/modules/rostests/winetests/windowscodecsext/CMakeLists.txt b/modules/rostests/winetests/windowscodecsext/CMakeLists.txt index 80af9711a4582..a037859937c37 100644 --- a/modules/rostests/winetests/windowscodecsext/CMakeLists.txt +++ b/modules/rostests/winetests/windowscodecsext/CMakeLists.txt @@ -1,4 +1,5 @@ +remove_definitions(-D__ROS_LONG64__) add_executable(windowscodecsext_winetest transform.c testlist.c) set_module_type(windowscodecsext_winetest win32cui) add_importlibs(windowscodecsext_winetest ole32 windowscodecsext msvcrt kernel32) diff --git a/modules/rostests/winetests/windowscodecsext/transform.c b/modules/rostests/winetests/windowscodecsext/transform.c index e76f9fe8a4fe9..01f0d8a289e1b 100644 --- a/modules/rostests/winetests/windowscodecsext/transform.c +++ b/modules/rostests/winetests/windowscodecsext/transform.c @@ -32,28 +32,28 @@ static void test_WICCreateColorTransform_Proxy(void) IWICColorTransform *transform; hr = WICCreateColorTransform_Proxy( NULL ); - ok( hr == E_INVALIDARG, "got %08x\n", hr ); + ok( hr == E_INVALIDARG, "got %08lx\n", hr ); transform = NULL; hr = WICCreateColorTransform_Proxy( &transform ); - ok( hr == S_OK, "got %08x\n", hr ); + ok( hr == S_OK, "got %08lx\n", hr ); if (transform) IWICColorTransform_Release( transform ); hr = CoInitializeEx( NULL, COINIT_APARTMENTTHREADED ); - ok( hr == S_OK, "got %08x\n", hr ); + ok( hr == S_OK, "got %08lx\n", hr ); transform = NULL; hr = WICCreateColorTransform_Proxy( &transform ); - ok( hr == S_OK, "got %08x\n", hr ); + ok( hr == S_OK, "got %08lx\n", hr ); if (transform) IWICColorTransform_Release( transform ); CoUninitialize(); hr = CoInitializeEx( NULL, COINIT_MULTITHREADED ); - ok( hr == S_OK, "got %08x\n", hr ); + ok( hr == S_OK, "got %08lx\n", hr ); transform = NULL; hr = WICCreateColorTransform_Proxy( &transform ); - ok( hr == S_OK, "got %08x\n", hr ); + ok( hr == S_OK, "got %08lx\n", hr ); if (transform) IWICColorTransform_Release( transform ); CoUninitialize(); } diff --git a/modules/wallpapers/Angelus/ReactOS/Angelus.ReactOS7.Dark_16-9.jpg b/modules/wallpapers/Angelus/ReactOS/Angelus ReactOS Dark 16x9 1067x600.jpg similarity index 100% rename from modules/wallpapers/Angelus/ReactOS/Angelus.ReactOS7.Dark_16-9.jpg rename to modules/wallpapers/Angelus/ReactOS/Angelus ReactOS Dark 16x9 1067x600.jpg diff --git a/modules/wallpapers/Angelus/ReactOS/Angelus.ReactOS7.Dark_4-3.jpg b/modules/wallpapers/Angelus/ReactOS/Angelus ReactOS Dark 4x3 800x600.jpg similarity index 100% rename from modules/wallpapers/Angelus/ReactOS/Angelus.ReactOS7.Dark_4-3.jpg rename to modules/wallpapers/Angelus/ReactOS/Angelus ReactOS Dark 4x3 800x600.jpg diff --git a/modules/wallpapers/Angelus/ReactOS/CMakeLists.txt b/modules/wallpapers/Angelus/ReactOS/CMakeLists.txt index ea729e2fd7171..518a0ea5bc726 100644 --- a/modules/wallpapers/Angelus/ReactOS/CMakeLists.txt +++ b/modules/wallpapers/Angelus/ReactOS/CMakeLists.txt @@ -1,2 +1,2 @@ -add_cd_file(FILE ${CMAKE_CURRENT_SOURCE_DIR}/Angelus.ReactOS7.Dark_16-9.jpg DESTINATION reactos/Web/Wallpaper FOR all) -add_cd_file(FILE ${CMAKE_CURRENT_SOURCE_DIR}/Angelus.ReactOS7.Dark_4-3.jpg DESTINATION reactos/Web/Wallpaper FOR all) +add_cd_file(FILE "${CMAKE_CURRENT_SOURCE_DIR}/Angelus ReactOS Dark 16x9 1067x600.jpg" DESTINATION reactos/Web/Wallpaper FOR all) +add_cd_file(FILE "${CMAKE_CURRENT_SOURCE_DIR}/Angelus ReactOS Dark 4x3 800x600.jpg" DESTINATION reactos/Web/Wallpaper FOR all) diff --git a/modules/wallpapers/Mizu/CMakeLists.txt b/modules/wallpapers/Mizu/CMakeLists.txt index 1dcff54b2969b..2931961ed2aa8 100644 --- a/modules/wallpapers/Mizu/CMakeLists.txt +++ b/modules/wallpapers/Mizu/CMakeLists.txt @@ -1,4 +1,4 @@ -add_cd_file(FILE ${CMAKE_CURRENT_SOURCE_DIR}/ReactOS_Mizu.png DESTINATION reactos/Web/Wallpaper FOR all) -add_cd_file(FILE ${CMAKE_CURRENT_SOURCE_DIR}/ReactOS_Mizu_4x3.png DESTINATION reactos/Web/Wallpaper FOR all) -add_cd_file(FILE ${CMAKE_CURRENT_SOURCE_DIR}/ReactOS_Mizu_16x9_A.png DESTINATION reactos/Web/Wallpaper FOR all) -add_cd_file(FILE ${CMAKE_CURRENT_SOURCE_DIR}/ReactOS_Mizu_16x9_B.png DESTINATION reactos/Web/Wallpaper FOR all) +add_cd_file(FILE "${CMAKE_CURRENT_SOURCE_DIR}/ReactOS Mizu 16x9 1920x1080.png" DESTINATION reactos/Web/Wallpaper FOR all) +add_cd_file(FILE "${CMAKE_CURRENT_SOURCE_DIR}/ReactOS Mizu 4x3 1440x1080.png" DESTINATION reactos/Web/Wallpaper FOR all) +add_cd_file(FILE "${CMAKE_CURRENT_SOURCE_DIR}/ReactOS Mizu A 16x9 1920x1080.png" DESTINATION reactos/Web/Wallpaper FOR all) +add_cd_file(FILE "${CMAKE_CURRENT_SOURCE_DIR}/ReactOS Mizu B 16x9 1920x1080.png" DESTINATION reactos/Web/Wallpaper FOR all) diff --git a/modules/wallpapers/Mizu/ReactOS_Mizu.png b/modules/wallpapers/Mizu/ReactOS Mizu 16x9 1920x1080.png similarity index 100% rename from modules/wallpapers/Mizu/ReactOS_Mizu.png rename to modules/wallpapers/Mizu/ReactOS Mizu 16x9 1920x1080.png diff --git a/modules/wallpapers/Mizu/ReactOS_Mizu_4x3.png b/modules/wallpapers/Mizu/ReactOS Mizu 4x3 1440x1080.png similarity index 100% rename from modules/wallpapers/Mizu/ReactOS_Mizu_4x3.png rename to modules/wallpapers/Mizu/ReactOS Mizu 4x3 1440x1080.png diff --git a/modules/wallpapers/Mizu/ReactOS_Mizu_16x9_A.png b/modules/wallpapers/Mizu/ReactOS Mizu A 16x9 1920x1080.png similarity index 100% rename from modules/wallpapers/Mizu/ReactOS_Mizu_16x9_A.png rename to modules/wallpapers/Mizu/ReactOS Mizu A 16x9 1920x1080.png diff --git a/modules/wallpapers/Mizu/ReactOS_Mizu_16x9_B.png b/modules/wallpapers/Mizu/ReactOS Mizu B 16x9 1920x1080.png similarity index 100% rename from modules/wallpapers/Mizu/ReactOS_Mizu_16x9_B.png rename to modules/wallpapers/Mizu/ReactOS Mizu B 16x9 1920x1080.png diff --git a/modules/wallpapers/ReadMe.txt b/modules/wallpapers/ReadMe.txt index 6ad4db5186320..ce75cb7cf4e89 100644 --- a/modules/wallpapers/ReadMe.txt +++ b/modules/wallpapers/ReadMe.txt @@ -1,16 +1,16 @@ Wallpapers =========== -|-------------------------------|-----------------------------------------------|--------------------------------------------------------| -|Filename | Author | Origin | -|-------------------------------|-----------------------------------------------|--------------------------------------------------------| -|Angelus.ReactOS7.Dark_4-3.jpg | Forum user "Angelus" (jedi.knight@wanadoo.es) | https://reactos.org/forum/viewtopic.php?p=50543#p50543 | -|Angelus.ReactOS7.Dark_16-9.jpg | Forum user "Angelus" (jedi.knight@wanadoo.es) | https://reactos.org/forum/viewtopic.php?p=50543#p50543 | -|ReactOS_Mizu.png | Forum user "Foxlet" (foxlet@furcode.co) | https://jira.reactos.org/browse/CORE-15783 | -|ReactOS_Mizu_4x3.png | Forum user "Foxlet" (foxlet@furcode.co) | https://jira.reactos.org/browse/CORE-15783 | -|ReactOS_Mizu_16x9_A.png | Forum user "Foxlet" (foxlet@furcode.co) | https://jira.reactos.org/browse/CORE-15783 | -|ReactOS_Mizu_16x9_B.png | Forum user "Foxlet" (foxlet@furcode.co) | https://jira.reactos.org/browse/CORE-15783 | -|-------------------------------|-----------------------------------------------|--------------------------------------------------------| +|--------------------------------|-----------------------------------------------|--------------------------------------------------------| +|Filename | Author | Origin | +|--------------------------------|-----------------------------------------------|--------------------------------------------------------| +|"Angelus ReactOS Dark 4x3.jpg" | Forum user "Angelus" (jedi.knight@wanadoo.es) | https://reactos.org/forum/viewtopic.php?p=50543#p50543 | +|"Angelus ReactOS Dark 16x9.jpg" | Forum user "Angelus" (jedi.knight@wanadoo.es) | https://reactos.org/forum/viewtopic.php?p=50543#p50543 | +|"ReactOS Mizu.png" | Forum user "Foxlet" (foxlet@furcode.co) | https://jira.reactos.org/browse/CORE-15783 | +|"ReactOS Mizu 4x3.png" | Forum user "Foxlet" (foxlet@furcode.co) | https://jira.reactos.org/browse/CORE-15783 | +|"ReactOS Mizu 16x9 A.png" | Forum user "Foxlet" (foxlet@furcode.co) | https://jira.reactos.org/browse/CORE-15783 | +|"ReactOS Mizu 16x9 B.png" | Forum user "Foxlet" (foxlet@furcode.co) | https://jira.reactos.org/browse/CORE-15783 | +|--------------------------------|-----------------------------------------------|--------------------------------------------------------| You can also download the other wallpapers from the "ReactOS Standard Wallpapers" package in the ReactOS Applications Manager. diff --git a/ntoskrnl/CMakeLists.txt b/ntoskrnl/CMakeLists.txt index b9c51ab0c4a79..1fb906cb24dd2 100644 --- a/ntoskrnl/CMakeLists.txt +++ b/ntoskrnl/CMakeLists.txt @@ -31,28 +31,28 @@ endif() list(APPEND PCH_SKIP_SOURCE guid.c) -add_executable(ntoskrnl - ${ntoskrnl_asm} - ${NTOSKRNL_SOURCE} - ${PCH_SKIP_SOURCE} - ntoskrnl.rc - ${CMAKE_CURRENT_BINARY_DIR}/ntoskrnl.def) -set_module_type(ntoskrnl kernel) +if(NOT SARCH STREQUAL "wow64") + add_executable(ntoskrnl + ${ntoskrnl_asm} + ${NTOSKRNL_SOURCE} + ${PCH_SKIP_SOURCE} + ntoskrnl.rc + ${CMAKE_CURRENT_BINARY_DIR}/ntoskrnl.def) + set_module_type(ntoskrnl kernel) -source_group(TREE ${REACTOS_SOURCE_DIR}/ntoskrnl PREFIX "Source Files" FILES ${NTOSKRNL_SOURCE}) + source_group(TREE ${REACTOS_SOURCE_DIR}/ntoskrnl PREFIX "Source Files" FILES ${NTOSKRNL_SOURCE}) -target_link_libraries(ntoskrnl cportlib csq ${PSEH_LIB} arbiter cmlib ntlsalib rtl ${ROSSYM_LIB} libcntpr wdmguid ioevent) + target_link_libraries(ntoskrnl cportlib csq ${PSEH_LIB} arbiter cmlib ntlsalib rtl ${ROSSYM_LIB} libcntpr wdmguid ioevent) -if(STACK_PROTECTOR) - target_sources(ntoskrnl PRIVATE $) -endif() + if(STACK_PROTECTOR) + target_sources(ntoskrnl PRIVATE $) + endif() -add_importlibs(ntoskrnl hal kdcom bootvid) -add_pch(ntoskrnl ${REACTOS_SOURCE_DIR}/ntoskrnl/include/ntoskrnl.h "${PCH_SKIP_SOURCE}") -add_dependencies(ntoskrnl psdk asm) -add_cd_file(TARGET ntoskrnl DESTINATION reactos/system32 NO_CAB FOR all) + add_importlibs(ntoskrnl hal kdcom bootvid) + add_pch(ntoskrnl ${REACTOS_SOURCE_DIR}/ntoskrnl/include/ntoskrnl.h "${PCH_SKIP_SOURCE}") + add_dependencies(ntoskrnl psdk asm) + add_cd_file(TARGET ntoskrnl DESTINATION reactos/system32 NO_CAB FOR all) -if(BUILD_MP) add_subdirectory(ntkrnlmp) endif() diff --git a/ntoskrnl/cache/fssup.c b/ntoskrnl/cache/fssup.c index fa24c83bc84e0..bcf42117c64dc 100644 --- a/ntoskrnl/cache/fssup.c +++ b/ntoskrnl/cache/fssup.c @@ -188,7 +188,7 @@ PFILE_OBJECT CcpFindOtherStreamFileObject(PFILE_OBJECT FileObject) return 0; } -/* Thanks: http://windowsitpro.com/Windows/Articles/ArticleID/3864/pg/2/2.html */ +/* Thanks: https://web.archive.org/web/20070228145211/http://windowsitpro.com/Windows/Articles/ArticleID/3864/pg/2/2.html */ VOID NTAPI diff --git a/ntoskrnl/cache/section/data.c b/ntoskrnl/cache/section/data.c index 3b4aafac89f57..b9afadb1fdf61 100644 --- a/ntoskrnl/cache/section/data.c +++ b/ntoskrnl/cache/section/data.c @@ -60,7 +60,7 @@ of this change is that a mapping of a small files takes a bit more than 1/4 of the size in nonpaged kernel space as it did previously. When we need other threads that may be competing for the same page fault to -wait, we have a mechanism seperate from PageOps for dealing with that, which +wait, we have a mechanism separate from PageOps for dealing with that, which was suggested by Travis Geiselbrecht after a conversation I had with Alex Ionescu. That mechanism is the MM_WAIT_ENTRY, which is the all-ones SWAPENTRY. diff --git a/ntoskrnl/cache/section/fault.c b/ntoskrnl/cache/section/fault.c index e869dac88fb7b..10fc379d48df7 100644 --- a/ntoskrnl/cache/section/fault.c +++ b/ntoskrnl/cache/section/fault.c @@ -498,7 +498,7 @@ MmpFaultWorker(PVOID Parameter) /* -This code seperates the action of fault handling into an upper and lower +This code separates the action of fault handling into an upper and lower handler to allow the inner handler to optionally be called in work item if the stack is getting too deep. My experiments show that the third recursive page fault taken at PASSIVE_LEVEL must be shunted away to a @@ -739,7 +739,7 @@ MmAccessFaultCacheSection(KPROCESSOR_MODE Mode, /* -As above, this code seperates the active part of fault handling from a carrier +As above, this code separates the active part of fault handling from a carrier that can use the thread's active fault count to determine whether a work item is required. Also as above, this function repeatedly calls the active not present fault handler until a clear success or failure is received, using a diff --git a/ntoskrnl/cc/view.c b/ntoskrnl/cc/view.c index 774e5e9d42640..75b90eff265fc 100644 --- a/ntoskrnl/cc/view.c +++ b/ntoskrnl/cc/view.c @@ -33,6 +33,7 @@ /* INCLUDES ******************************************************************/ #include + #define NDEBUG #include @@ -385,7 +386,7 @@ CcRosFlushDirtyPages ( Locked = SharedCacheMap->Callbacks->AcquireForLazyWrite(SharedCacheMap->LazyWriteContext, Wait); if (!Locked) { - DPRINT("Not locked!"); + DPRINT("Not locked\n"); ASSERT(!Wait); CcRosVacbDecRefCount(current); OldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock); @@ -1038,7 +1039,7 @@ CcRosRequestVacb ( if (FileOffset % VACB_MAPPING_GRANULARITY != 0) { - DPRINT1("Bad fileoffset %I64x should be multiple of %x", + DPRINT1("Bad FileOffset %I64x: should be multiple of %x\n", FileOffset, VACB_MAPPING_GRANULARITY); KeBugCheck(CACHE_MANAGER); } diff --git a/ntoskrnl/config/cmdata.c b/ntoskrnl/config/cmdata.c index 693c9ac7b2667..f53ac05a7cdc7 100644 --- a/ntoskrnl/config/cmdata.c +++ b/ntoskrnl/config/cmdata.c @@ -54,13 +54,15 @@ UNICODE_STRING CmSymbolicLinkValueName = UNICODE_STRING CmpLoadOptions; +/* TRUE if all hives must be loaded in shared mode */ +ULONG CmpVolatileBoot; /* TRUE if the system hives must be loaded in shared mode */ BOOLEAN CmpShareSystemHives; /* TRUE when the registry is in PE mode */ BOOLEAN CmpMiniNTBoot; ULONG CmpBootType; -BOOLEAN CmSelfHeal = TRUE; +ULONG CmSelfHeal = TRUE; BOOLEAN CmpSelfHeal = TRUE; USHORT CmpUnknownBusCount; @@ -540,6 +542,13 @@ DATA_SEG("INITDATA") CM_SYSTEM_CONTROL_VECTOR CmControlVector[] = &ObpUnsecureGlobalNamesLength, NULL }, + { + L"Session Manager\\Kernel", + L"ObCaseInsensitive", + &ObpCaseInsensitive, + NULL, + NULL + }, { L"Session Manager\\I/O System", L"CountOperations", @@ -624,8 +633,6 @@ DATA_SEG("INITDATA") CM_SYSTEM_CONTROL_VECTOR CmControlVector[] = NULL, NULL }, - - { L"ProductOptions", L"ProductSuite", @@ -668,6 +675,41 @@ DATA_SEG("INITDATA") CM_SYSTEM_CONTROL_VECTOR CmControlVector[] = &DummyData, &DummyData }, + { + L"Session Manager\\Configuration Manager", + L"SelfHealingEnabled", + &CmSelfHeal, + NULL, + NULL + }, + { + L"Session Manager\\Configuration Manager", + L"RegistryLazyFlushInterval", + &CmpLazyFlushIntervalInSeconds, + NULL, + NULL + }, + { + L"Session Manager\\Configuration Manager", + L"RegistryLazyFlushHiveCount", + &CmpLazyFlushHiveCount, + NULL, + NULL + }, + { + L"Session Manager\\Configuration Manager", + L"DelayCloseSize", + &CmpDelayedCloseSize, + NULL, + NULL + }, + { + L"Session Manager\\Configuration Manager", + L"VolatileBoot", + &CmpVolatileBoot, + NULL, + NULL + }, { L"Session Manager", L"ForceNpxEmulation", @@ -926,6 +968,13 @@ DATA_SEG("INITDATA") CM_SYSTEM_CONTROL_VECTOR CmControlVector[] = NULL, NULL }, + { + L"CrashControl", + L"AutoReboot", + &IopAutoReboot, + NULL, + NULL + }, { NULL, NULL, diff --git a/ntoskrnl/config/cmlazy.c b/ntoskrnl/config/cmlazy.c index ebac8a205324a..201f719a3a420 100644 --- a/ntoskrnl/config/cmlazy.c +++ b/ntoskrnl/config/cmlazy.c @@ -22,7 +22,7 @@ BOOLEAN CmpLazyFlushPending; BOOLEAN CmpForceForceFlush; BOOLEAN CmpHoldLazyFlush = TRUE; ULONG CmpLazyFlushIntervalInSeconds = 5; -static ULONG CmpLazyFlushHiveCount = 7; +ULONG CmpLazyFlushHiveCount = 7; ULONG CmpLazyFlushCount = 1; LONG CmpFlushStarveWriters; @@ -60,7 +60,7 @@ CmpDoFlushNextHive(_In_ BOOLEAN ForceFlush, if (!(CmHive->Hive.HiveFlags & HIVE_NOLAZYFLUSH) && (CmHive->FlushCount != CmpLazyFlushCount)) { - /* Great sucess! */ + /* Great success! */ Result = TRUE; /* One less to flush */ @@ -80,7 +80,7 @@ CmpDoFlushNextHive(_In_ BOOLEAN ForceFlush, DPRINT("Flushing: %wZ\n", &CmHive->FileFullPath); DPRINT("Handle: %p\n", CmHive->FileHandles[HFILE_TYPE_PRIMARY]); Status = HvSyncHive(&CmHive->Hive); - if(!NT_SUCCESS(Status)) + if (!NT_SUCCESS(Status)) { /* Let them know we failed */ DPRINT1("Failed to flush %wZ on handle %p (status 0x%08lx)\n", diff --git a/ntoskrnl/config/cmsysini.c b/ntoskrnl/config/cmsysini.c index a8ddc104073f6..df1de46a210d9 100644 --- a/ntoskrnl/config/cmsysini.c +++ b/ntoskrnl/config/cmsysini.c @@ -1164,7 +1164,7 @@ CmpCreateRegistryRoot(VOID) return FALSE; } - /* Completely sucessful */ + /* Completely successful */ return TRUE; } @@ -1635,6 +1635,10 @@ CmInitSystem1(VOID) CmpMiniNTBoot = TRUE; CmpShareSystemHives = TRUE; } + /* If we are in volatile boot mode, ALL hives without exception + * (system hives and others) will be loaded in shared mode */ + if (CmpVolatileBoot) + CmpShareSystemHives = TRUE; /* Initialize the hive list and lock */ InitializeListHead(&CmpHiveListHead); diff --git a/ntoskrnl/ex/callback.c b/ntoskrnl/ex/callback.c index 59fc2e7135ca7..c43826197a1cb 100644 --- a/ntoskrnl/ex/callback.c +++ b/ntoskrnl/ex/callback.c @@ -335,8 +335,8 @@ ExpInitializeCallbacks(VOID) * Opens or creates a Callback Object. Creates only if Create is true. * Allows multiple Callback Functions to be registered only if * AllowMultipleCallbacks is true. - * See: http://www.osronline.com/ddkx/kmarch/k102_967m.htm - * http://www.osronline.com/article.cfm?id=24 + * See: https://web.archive.org/web/20081230235552/http://www.osronline.com/DDKx/kmarch/k102_967m.htm + * https://www.osronline.com/article.cfm%5eid=24.htm * * @param CallbackObject * Pointer that will receive the Callback Object. @@ -445,8 +445,8 @@ ExCreateCallback(OUT PCALLBACK_OBJECT *CallbackObject, * @implemented * * Calls a function pointer (a registered callback) - * See: http://www.osronline.com/ddkx/kmarch/k102_2f5e.htm - * http://vmsone.com/~decuslib/vmssig/vmslt99b/nt/wdm-callback.txt + * See: https://web.archive.org/web/20090106214158/http://www.osronline.com/DDKx/kmarch/k102_2f5e.htm + * http://vmsone.com/~decuslib/vmssig/vmslt99b/nt/wdm-callback.txt (DEAD_LINK) * * @param CallbackObject * Which callback to call diff --git a/ntoskrnl/ex/dbgctrl.c b/ntoskrnl/ex/dbgctrl.c index 70280703a31ec..5ed32619fee1a 100644 --- a/ntoskrnl/ex/dbgctrl.c +++ b/ntoskrnl/ex/dbgctrl.c @@ -49,7 +49,8 @@ ULONG_PTR ExpDebuggerPageIn; */ VOID NTAPI -ExpDebuggerWorker(IN PVOID Context) +ExpDebuggerWorker( + _In_ PVOID Context) { PEPROCESS ProcessToAttach, ProcessToKill; ULONG_PTR PageInAddress; @@ -83,11 +84,10 @@ ExpDebuggerWorker(IN PVOID Context) Process = NULL; /* Check if we need to attach or kill some process */ - if (ProcessToAttach != NULL || ProcessToKill != NULL) + if (ProcessToAttach || ProcessToKill) { /* Find the process in the list */ - Process = PsGetNextProcess(Process); - while (Process) + while ((Process = PsGetNextProcess(Process))) { /* Is this the process we want to attach to? */ if (Process == ProcessToAttach) @@ -104,12 +104,16 @@ ExpDebuggerWorker(IN PVOID Context) ObDereferenceObject(Process); return; } + } - /* Get the next process */ - Process = PsGetNextProcess(Process); + if (!Process) + { + DbgPrintEx(DPFLTR_SYSTEM_ID, DPFLTR_ERROR_LEVEL, + "EX debug work: Unable to find process %p\n", + ProcessToAttach ? ProcessToAttach : ProcessToKill); } - /* We either have found a process, or we default to the current process */ + /* We either have found a process, or we default to the current one */ } /* If we have an address to page in... */ @@ -122,7 +126,9 @@ ExpDebuggerWorker(IN PVOID Context) } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - DPRINT1("Failed to page in address 0x%p, Status 0x%08lx\n", PageInAddress, _SEH2_GetExceptionCode()); + DbgPrintEx(DPFLTR_SYSTEM_ID, DPFLTR_ERROR_LEVEL, + "EX page in: Failed to page-in address 0x%p, Status 0x%08lx\n", + PageInAddress, _SEH2_GetExceptionCode()); } _SEH2_END; } @@ -135,98 +141,280 @@ ExpDebuggerWorker(IN PVOID Context) { /* ... we can detach from the process */ KeUnstackDetachProcess(&ApcState); - /* Dereference the process which was referenced for us by PsGetNextProcess */ + /* Dereference the process referenced by PsGetNextProcess() */ ObDereferenceObject(Process); } } -/*++ - * @name NtSystemDebugControl - * @implemented +/** + * @brief + * Perform various queries to the kernel debugger. + * + * @param[in] Command + * A SYSDBG_COMMAND value describing the kernel debugger command to perform. + * + * @param[in] InputBuffer + * Pointer to a user-provided input command-specific buffer, whose length + * is given by InputBufferLength. + * + * @param[in] InputBufferLength + * The size (in bytes) of the buffer pointed by InputBuffer. + * + * @param[out] OutputBuffer + * Pointer to a user-provided command-specific output buffer, whose length + * is given by OutputBufferLength. * - * Perform various queries to debugger. - * This API is subject to test-case creation to further evaluate its - * abilities (if needed to at all) + * @param[in] OutputBufferLength + * The size (in bytes) of the buffer pointed by OutputBuffer. * - * See: http://www.osronline.com/showthread.cfm?link=93915 - * http://void.ru/files/Ntexapi.h - * http://www.codeguru.com/code/legacy/system/ntexapi.zip - * http://www.securityfocus.com/bid/9694 + * @param[out] ReturnLength + * Optional pointer to a ULONG variable that receives the actual length of + * data written written in the output buffer. It is always zero, except for + * the live dump commands where an actual non-zero length is returned. * - * @param ControlCode - * Description of the parameter. Wrapped to more lines on ~70th - * column. + * @return + * STATUS_SUCCESS in case of success, or a proper error code otherwise. * - * @param InputBuffer - * FILLME + * @remarks * - * @param InputBufferLength - * FILLME + * - The caller must have SeDebugPrivilege, otherwise the function fails + * with STATUS_ACCESS_DENIED. * - * @param OutputBuffer - * FILLME + * - Only the live dump commands: SysDbgGetTriageDump, and SysDbgGetLiveKernelDump + * (Win8.1+) are available even if the debugger is disabled or absent. * - * @param OutputBufferLength - * FILLME + * - The following system-critical commands are not accessible anymore + * for user-mode usage with this API on NT 5.2+ (Windows 2003 SP1 and later) + * systems: * - * @param ReturnLength - * FILLME + * SysDbgQueryVersion, + * SysDbgReadVirtual and SysDbgWriteVirtual, + * SysDbgReadPhysical and SysDbgWritePhysical, + * SysDbgReadControlSpace and SysDbgWriteControlSpace, + * SysDbgReadIoSpace and SysDbgWriteIoSpace, + * SysDbgReadMsr and SysDbgWriteMsr, + * SysDbgReadBusData and SysDbgWriteBusData, + * SysDbgCheckLowMemory. * - * @return STATUS_SUCCESS in case of success, proper error code otherwise + * For these, NtSystemDebugControl() will return STATUS_NOT_IMPLEMENTED. + * They are now available from kernel-mode only with KdSystemDebugControl(). * - * @remarks None + * @note + * See: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2004-2339 * - *--*/ + * @see KdSystemDebugControl() + **/ NTSTATUS NTAPI -NtSystemDebugControl(SYSDBG_COMMAND ControlCode, - PVOID InputBuffer, - ULONG InputBufferLength, - PVOID OutputBuffer, - ULONG OutputBufferLength, - PULONG ReturnLength) +NtSystemDebugControl( + _In_ SYSDBG_COMMAND Command, + _In_reads_bytes_(InputBufferLength) PVOID InputBuffer, + _In_ ULONG InputBufferLength, + _Out_writes_bytes_(OutputBufferLength) PVOID OutputBuffer, + _In_ ULONG OutputBufferLength, + _Out_opt_ PULONG ReturnLength) { - switch (ControlCode) + KPROCESSOR_MODE PreviousMode = KeGetPreviousMode(); + ULONG Length = 0; + NTSTATUS Status; + + /* Debugger controlling requires the debug privilege */ + if (!SeSinglePrivilegeCheck(SeDebugPrivilege, PreviousMode)) + return STATUS_ACCESS_DENIED; + + _SEH2_TRY + { + if (PreviousMode != KernelMode) + { + if (InputBufferLength) + ProbeForRead(InputBuffer, InputBufferLength, sizeof(ULONG)); + if (OutputBufferLength) + ProbeForWrite(OutputBuffer, OutputBufferLength, sizeof(ULONG)); + if (ReturnLength) + ProbeForWriteUlong(ReturnLength); + } + + switch (Command) + { + case SysDbgQueryModuleInformation: + /* Removed in WinNT4 */ + Status = STATUS_INVALID_INFO_CLASS; + break; + +#ifdef _M_IX86 + case SysDbgQueryTraceInformation: + case SysDbgSetTracepoint: + case SysDbgSetSpecialCall: + case SysDbgClearSpecialCalls: + case SysDbgQuerySpecialCalls: + UNIMPLEMENTED; + Status = STATUS_NOT_IMPLEMENTED; + break; +#endif + + case SysDbgQueryVersion: + case SysDbgReadVirtual: + case SysDbgWriteVirtual: + case SysDbgReadPhysical: + case SysDbgWritePhysical: + case SysDbgReadControlSpace: + case SysDbgWriteControlSpace: + case SysDbgReadIoSpace: + case SysDbgWriteIoSpace: + case SysDbgReadMsr: + case SysDbgWriteMsr: + case SysDbgReadBusData: + case SysDbgWriteBusData: + case SysDbgCheckLowMemory: + /* Those are implemented in KdSystemDebugControl */ + if (InitIsWinPEMode) + { + Status = KdSystemDebugControl(Command, + InputBuffer, InputBufferLength, + OutputBuffer, OutputBufferLength, + &Length, PreviousMode); + } + else + { + Status = STATUS_NOT_IMPLEMENTED; + } + break; + + case SysDbgBreakPoint: + if (KdDebuggerEnabled) + { + DbgBreakPointWithStatus(DBG_STATUS_DEBUG_CONTROL); + Status = STATUS_SUCCESS; + } + else + { + Status = STATUS_UNSUCCESSFUL; + } + break; + + case SysDbgEnableKernelDebugger: + Status = KdEnableDebugger(); + break; + + case SysDbgDisableKernelDebugger: + Status = KdDisableDebugger(); + break; + + case SysDbgGetAutoKdEnable: + if (OutputBufferLength != sizeof(BOOLEAN)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + else + { + *(PBOOLEAN)OutputBuffer = KdAutoEnableOnEvent; + Status = STATUS_SUCCESS; + } + break; + + case SysDbgSetAutoKdEnable: + if (InputBufferLength != sizeof(BOOLEAN)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + else if (KdPitchDebugger) + { + Status = STATUS_ACCESS_DENIED; + } + else + { + KdAutoEnableOnEvent = *(PBOOLEAN)InputBuffer; + Status = STATUS_SUCCESS; + } + break; + + case SysDbgGetPrintBufferSize: + if (OutputBufferLength != sizeof(ULONG)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + else + { + /* Return buffer size only if KD is enabled */ + *(PULONG)OutputBuffer = KdPitchDebugger ? 0 : KdPrintBufferSize; + Status = STATUS_SUCCESS; + } + break; + + case SysDbgSetPrintBufferSize: + UNIMPLEMENTED; + Status = STATUS_NOT_IMPLEMENTED; + break; + + case SysDbgGetKdUmExceptionEnable: + if (OutputBufferLength != sizeof(BOOLEAN)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + else + { + /* Unfortunately, the internal flag says if UM exceptions are disabled */ + *(PBOOLEAN)OutputBuffer = !KdIgnoreUmExceptions; + Status = STATUS_SUCCESS; + } + break; + + case SysDbgSetKdUmExceptionEnable: + if (InputBufferLength != sizeof(BOOLEAN)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + else if (KdPitchDebugger) + { + Status = STATUS_ACCESS_DENIED; + } + else + { + /* Unfortunately, the internal flag says if UM exceptions are disabled */ + KdIgnoreUmExceptions = !*(PBOOLEAN)InputBuffer; + Status = STATUS_SUCCESS; + } + break; + + case SysDbgGetTriageDump: + UNIMPLEMENTED; + Status = STATUS_NOT_IMPLEMENTED; + break; + + case SysDbgGetKdBlockEnable: + if (OutputBufferLength != sizeof(BOOLEAN)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + else + { + *(PBOOLEAN)OutputBuffer = KdBlockEnable; + Status = STATUS_SUCCESS; + } + break; + + case SysDbgSetKdBlockEnable: + Status = KdChangeOption(KD_OPTION_SET_BLOCK_ENABLE, + InputBufferLength, + InputBuffer, + OutputBufferLength, + OutputBuffer, + &Length); + break; + + default: + Status = STATUS_INVALID_INFO_CLASS; + break; + } + + if (ReturnLength) + *ReturnLength = Length; + + _SEH2_YIELD(return Status); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - case SysDbgQueryModuleInformation: - case SysDbgQueryTraceInformation: - case SysDbgSetTracepoint: - case SysDbgSetSpecialCall: - case SysDbgClearSpecialCalls: - case SysDbgQuerySpecialCalls: - case SysDbgQueryVersion: - case SysDbgReadVirtual: - case SysDbgWriteVirtual: - case SysDbgReadPhysical: - case SysDbgWritePhysical: - case SysDbgReadControlSpace: - case SysDbgWriteControlSpace: - case SysDbgReadIoSpace: - case SysDbgWriteIoSpace: - case SysDbgReadMsr: - case SysDbgWriteMsr: - case SysDbgReadBusData: - case SysDbgWriteBusData: - case SysDbgCheckLowMemory: - case SysDbgGetTriageDump: - return STATUS_NOT_IMPLEMENTED; - case SysDbgBreakPoint: - case SysDbgEnableKernelDebugger: - case SysDbgDisableKernelDebugger: - case SysDbgGetAutoKdEnable: - case SysDbgSetAutoKdEnable: - case SysDbgGetPrintBufferSize: - case SysDbgSetPrintBufferSize: - case SysDbgGetKdUmExceptionEnable: - case SysDbgSetKdUmExceptionEnable: - case SysDbgGetKdBlockEnable: - case SysDbgSetKdBlockEnable: - return KdSystemDebugControl( - ControlCode, - InputBuffer, InputBufferLength, - OutputBuffer, OutputBufferLength, - ReturnLength, KeGetPreviousMode()); - default: - return STATUS_INVALID_INFO_CLASS; + _SEH2_YIELD(return _SEH2_GetExceptionCode()); } + _SEH2_END; } diff --git a/ntoskrnl/ex/harderr.c b/ntoskrnl/ex/harderr.c index 490514d601e88..8ac2b106f2b32 100644 --- a/ntoskrnl/ex/harderr.c +++ b/ntoskrnl/ex/harderr.c @@ -295,8 +295,8 @@ ExpRaiseHardError(IN NTSTATUS ErrorStatus, * The ExRaiseAccessViolation routine can be used with structured exception * handling to throw a driver-determined exception for a memory access * violation that occurs when a driver processes I/O requests. - * See: http://msdn.microsoft.com/library/en-us/Kernel_r/hh/Kernel_r/k102_71b4c053-599c-4a6d-8a59-08aae6bdc534.xml.asp?frame=true - * http://www.osronline.com/ddkx/kmarch/k102_814i.htm + * See: http://msdn.microsoft.com/library/en-us/Kernel_r/hh/Kernel_r/k102_71b4c053-599c-4a6d-8a59-08aae6bdc534.xml.asp?frame=true (DEAD_LINK) + * https://web.archive.org/web/20081231000748/http://www.osronline.com/ddkx/kmarch/k102_814i.htm * * @return None * @@ -318,7 +318,7 @@ ExRaiseAccessViolation(VOID) * ExRaiseDatatypeMisalignment raises an exception with the exception * code set to STATUS_DATATYPE_MISALIGNMENT * See: MSDN / DDK - * http://www.osronline.com/ddkx/kmarch/k102_814i.htm + * https://web.archive.org/web/20081231000748/http://www.osronline.com/ddkx/kmarch/k102_814i.htm * * @return None * diff --git a/ntoskrnl/ex/hdlsterm.c b/ntoskrnl/ex/hdlsterm.c index b4fd7b949f6d6..bfed212d91df3 100644 --- a/ntoskrnl/ex/hdlsterm.c +++ b/ntoskrnl/ex/hdlsterm.c @@ -450,8 +450,15 @@ HdlspDispatch(IN HEADLESS_CMD Command, case HeadlessCmdGetLine: break; + case HeadlessCmdStartBugCheck: + { + HeadlessGlobals->InBugCheck = TRUE; + HeadlessGlobals->ProcessingCmd = FALSE; + Status = STATUS_SUCCESS; break; + } + case HeadlessCmdDoBugCheckProcessing: break; @@ -518,7 +525,10 @@ HdlspDispatch(IN HEADLESS_CMD Command, } case HeadlessCmdSendBlueScreenData: + // TODO: Send XML description of bugcheck. + // InputBuffer points to the BugCheckCode. break; + case HeadlessCmdQueryGUID: break; diff --git a/ntoskrnl/ex/init.c b/ntoskrnl/ex/init.c index 433a635d7d2a2..16c0eb8d4a28f 100644 --- a/ntoskrnl/ex/init.c +++ b/ntoskrnl/ex/init.c @@ -790,84 +790,89 @@ ExpIsLoaderValid(IN PLOADER_PARAMETER_BLOCK LoaderBlock) return TRUE; } -CODE_SEG("INIT") +static CODE_SEG("INIT") VOID -NTAPI -ExpLoadBootSymbols(IN PLOADER_PARAMETER_BLOCK LoaderBlock) +ExpLoadBootSymbols( + _In_ PLOADER_PARAMETER_BLOCK LoaderBlock) { - ULONG i = 0; PLIST_ENTRY NextEntry; + PLDR_DATA_TABLE_ENTRY LdrEntry; + NTSTATUS Status; + ULONG i; ULONG Count, Length; PWCHAR Name; - PLDR_DATA_TABLE_ENTRY LdrEntry; + STRING ImageName; CHAR NameBuffer[256]; - STRING SymbolString; - NTSTATUS Status; - /* Loop the driver list */ - NextEntry = LoaderBlock->LoadOrderListHead.Flink; - while (NextEntry != &LoaderBlock->LoadOrderListHead) + /* Loop over the boot modules list */ + for (NextEntry = LoaderBlock->LoadOrderListHead.Flink, i = 0; + NextEntry != &LoaderBlock->LoadOrderListHead; + NextEntry = NextEntry->Flink, ++i) { - /* Skip the first two images */ - if (i >= 2) + /* Skip the first two images: HAL and kernel */ + if (i < 2) + continue; + + /* Get the entry */ + LdrEntry = CONTAINING_RECORD(NextEntry, + LDR_DATA_TABLE_ENTRY, + InLoadOrderLinks); + if (LdrEntry->FullDllName.Buffer[0] == L'\\') { - /* Get the entry */ - LdrEntry = CONTAINING_RECORD(NextEntry, - LDR_DATA_TABLE_ENTRY, - InLoadOrderLinks); - if (LdrEntry->FullDllName.Buffer[0] == L'\\') - { - /* We have a name, read its data */ - Name = LdrEntry->FullDllName.Buffer; - Length = LdrEntry->FullDllName.Length / sizeof(WCHAR); + /* We have a name, read its data */ + Name = LdrEntry->FullDllName.Buffer; + Length = LdrEntry->FullDllName.Length / sizeof(WCHAR); - /* Check if our buffer can hold it */ - if (sizeof(NameBuffer) < Length + sizeof(ANSI_NULL)) - { - /* It's too long */ - Status = STATUS_BUFFER_OVERFLOW; - } - else - { - /* Copy the name */ - Count = 0; - do - { - /* Copy the character */ - NameBuffer[Count++] = (CHAR)*Name++; - } while (Count < Length); - - /* Null-terminate */ - NameBuffer[Count] = ANSI_NULL; - Status = STATUS_SUCCESS; - } - } - else + /* Check if our buffer can hold it */ + if (sizeof(NameBuffer) < Length + sizeof(ANSI_NULL)) { - /* Safely print the string into our buffer */ - Status = RtlStringCbPrintfA(NameBuffer, - sizeof(NameBuffer), - "%S\\System32\\Drivers\\%wZ", - &SharedUserData->NtSystemRoot[2], - &LdrEntry->BaseDllName); + /* It's too long */ + Status = STATUS_BUFFER_OVERFLOW; } - - /* Check if the buffer was ok */ - if (NT_SUCCESS(Status)) + else { - /* Initialize the STRING for the debugger */ - RtlInitString(&SymbolString, NameBuffer); + /* Copy the name */ + Count = 0; + do + { + /* Do cheap Unicode to ANSI conversion */ + NameBuffer[Count++] = (CHAR)*Name++; + } while (Count < Length); - /* Load the symbols */ - DbgLoadImageSymbols(&SymbolString, - LdrEntry->DllBase, - (ULONG_PTR)PsGetCurrentProcessId()); + /* Null-terminate */ + NameBuffer[Count] = ANSI_NULL; + Status = STATUS_SUCCESS; } } + else + { + /* Safely print the string into our buffer */ + Status = RtlStringCbPrintfA(NameBuffer, + sizeof(NameBuffer), + "%S\\System32\\Drivers\\%wZ", + &SharedUserData->NtSystemRoot[2], + &LdrEntry->BaseDllName); + } - /* Go to the next entry */ - i++; - NextEntry = NextEntry->Flink; + /* Check if the buffer is OK */ + if (NT_SUCCESS(Status)) + { + /* Load the symbols */ + RtlInitString(&ImageName, NameBuffer); + DbgLoadImageSymbols(&ImageName, + LdrEntry->DllBase, + (ULONG_PTR)PsGetCurrentProcessId()); + } + +#ifdef CONFIG_SMP + /* Check that the image is safe to use if we have more than one CPU */ + if (!MmVerifyImageIsOkForMpUse(LdrEntry->DllBase)) + { + KeBugCheckEx(UP_DRIVER_ON_MP_SYSTEM, + (ULONG_PTR)LdrEntry->DllBase, + 0, 0, 0); + } +#endif // CONFIG_SMP } } @@ -1108,7 +1113,8 @@ ExpInitializeExecutive(IN ULONG Cpu, ExpLoadBootSymbols(LoaderBlock); /* Check if we should break after symbol load */ - if (KdBreakAfterSymbolLoad) DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C); + if (KdBreakAfterSymbolLoad) + DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C); /* Check if this loader is compatible with NT 5.2 */ if (LoaderBlock->Extension->Size >= sizeof(LOADER_PARAMETER_EXTENSION)) @@ -1139,8 +1145,8 @@ ExpInitializeExecutive(IN ULONG Cpu, { /* Get the service pack string */ Status = RtlFindMessage(NtosEntry->DllBase, - 11, - 0, + RT_MESSAGETABLE, + MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), WINDOWS_NT_CSD_STRING, &MsgEntry); if (NT_SUCCESS(Status)) @@ -1428,8 +1434,8 @@ Phase1InitializationDiscard(IN PVOID Context) /* Find the banner message */ MsgStatus = RtlFindMessage(NtosEntry->DllBase, - 11, - 0, + RT_MESSAGETABLE, + MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), WINDOWS_NT_BANNER, &MsgEntry); @@ -1563,6 +1569,34 @@ Phase1InitializationDiscard(IN PVOID Context) } #ifdef CONFIG_SMP + /* + * IMPORTANT NOTE: + * Because ReactOS is a "nice" OS, we do not care _at all_ + * about any number of registered/licensed processors: + * no usage of KeRegisteredProcessors nor KeLicensedProcessors. + */ + if (CommandLine) + { + PSTR Option; + + /* Check for NUMPROC: maximum number of logical processors + * that can be started (including dynamically) at run-time */ + Option = strstr(CommandLine, "NUMPROC"); + if (Option) Option = strstr(Option, "="); + if (Option) KeNumprocSpecified = atol(Option + 1); + + /* Check for BOOTPROC (NT6+ and ReactOS): maximum number + * of logical processors that can be started at boot-time */ + Option = strstr(CommandLine, "BOOTPROC"); + if (Option) Option = strstr(Option, "="); + if (Option) KeBootprocSpecified = atol(Option + 1); + + /* Check for MAXPROC (NT6+ and ReactOS): forces the kernel to report + * as existing the maximum number of processors that can be handled */ + if (strstr(CommandLine, "MAXPROC")) + KeMaximumProcessors = MAXIMUM_PROCESSORS; + } + /* Start Application Processors */ KeStartAllProcessors(); #endif @@ -1589,8 +1623,8 @@ Phase1InitializationDiscard(IN PVOID Context) /* Get the information string from our resource file */ MsgStatus = RtlFindMessage(NtosEntry->DllBase, - 11, - 0, + RT_MESSAGETABLE, + MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), KeNumberProcessors > 1 ? WINDOWS_NT_INFO_STRING_PLURAL : WINDOWS_NT_INFO_STRING, @@ -1763,8 +1797,8 @@ Phase1InitializationDiscard(IN PVOID Context) /* Find the message to print out */ Status = RtlFindMessage(NtosEntry->DllBase, - 11, - 0, + RT_MESSAGETABLE, + MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), MessageCode, &MsgEntry); if (NT_SUCCESS(Status)) @@ -1783,8 +1817,8 @@ Phase1InitializationDiscard(IN PVOID Context) { /* Find the message to print out */ Status = RtlFindMessage(NtosEntry->DllBase, - 11, - 0, + RT_MESSAGETABLE, + MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), BOOTLOG_ENABLED, &MsgEntry); if (NT_SUCCESS(Status)) diff --git a/ntoskrnl/ex/profile.c b/ntoskrnl/ex/profile.c index a7e2e9b9fbe0b..2cdbdb6b1c646 100644 --- a/ntoskrnl/ex/profile.c +++ b/ntoskrnl/ex/profile.c @@ -104,6 +104,7 @@ NtCreateProfile(OUT PHANDLE ProfileHandle, NTSTATUS Status; ULONG Log2 = 0; ULONG_PTR Segment = 0; + ULONG BucketsRequired; PAGED_CODE(); /* Easy way out */ @@ -136,7 +137,12 @@ NtCreateProfile(OUT PHANDLE ProfileHandle, } /* Make sure that the buckets can map the range */ - if ((RangeSize >> (BucketSize - 2)) > BufferSize) + BucketsRequired = RangeSize >> BucketSize; + if (RangeSize & ((1 << BucketSize) - 1)) + { + BucketsRequired++; + } + if (BucketsRequired > BufferSize / sizeof(ULONG)) { DPRINT1("Bucket size too small\n"); return STATUS_BUFFER_TOO_SMALL; diff --git a/ntoskrnl/ex/sysinfo.c b/ntoskrnl/ex/sysinfo.c index e7e67cd85b960..2ad4b907e8768 100644 --- a/ntoskrnl/ex/sysinfo.c +++ b/ntoskrnl/ex/sysinfo.c @@ -208,7 +208,7 @@ ExLockUserBuffer( PMDL *OutMdl) { PMDL Mdl; - PAGED_CODE(); + ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); *MappedSystemVa = NULL; *OutMdl = NULL; @@ -664,7 +664,13 @@ QSI_DEF(SystemProcessorInformation) #else Spi->MaximumProcessors = 0; #endif - Spi->ProcessorFeatureBits = KeFeatureBits; + + /* According to Geoff Chappell, on Win 8.1 x64 / Win 10 x86, where this + field is extended to 64 bits, it continues to produce only the low 32 + bits. For the full value, use SYSTEM_PROCESSOR_FEATURES_INFORMATION. + See https://www.geoffchappell.com/studies/windows/km/ntoskrnl/api/ex/sysinfo/processor.htm + */ + Spi->ProcessorFeatureBits = (ULONG)KeFeatureBits; DPRINT("Arch %u Level %u Rev 0x%x\n", Spi->ProcessorArchitecture, Spi->ProcessorLevel, Spi->ProcessorRevision); @@ -2486,6 +2492,36 @@ QSI_DEF(SystemNumaAvailableMemory) return STATUS_SUCCESS; } +/* Class 62 - Emulation basic information */ +QSI_DEF(SystemEmulationBasicInformation) +{ + PSYSTEM_BASIC_INFORMATION Sbi + = (PSYSTEM_BASIC_INFORMATION) Buffer; + + *ReqSize = sizeof(SYSTEM_BASIC_INFORMATION); + + /* Check user buffer's size */ + if (Size != sizeof(SYSTEM_BASIC_INFORMATION)) + { + return STATUS_INFO_LENGTH_MISMATCH; + } + + RtlZeroMemory(Sbi, Size); + Sbi->Reserved = 0; + Sbi->TimerResolution = KeMaximumIncrement; + Sbi->PageSize = PAGE_SIZE; + Sbi->NumberOfPhysicalPages = MmNumberOfPhysicalPages; + Sbi->LowestPhysicalPageNumber = (ULONG)MmLowestPhysicalPage; + Sbi->HighestPhysicalPageNumber = (ULONG)MmHighestPhysicalPage; + Sbi->AllocationGranularity = MM_VIRTMEM_GRANULARITY; /* hard coded on Intel? */ + Sbi->MinimumUserModeAddress = 0x10000; /* Top of 64k */ + Sbi->MaximumUserModeAddress = (ULONG_PTR)0xFFFFFFFF; /* FIXME */ + Sbi->ActiveProcessorsAffinityMask = KeActiveProcessors; + Sbi->NumberOfProcessors = KeNumberProcessors; + + return STATUS_SUCCESS; +} + /* Class 64 - Extended handle information */ QSI_DEF(SystemExtendedHandleInformation) { @@ -2901,7 +2937,7 @@ CallQS[] = SI_XX(SystemComPlusPackage), SI_QX(SystemNumaAvailableMemory), SI_XX(SystemProcessorPowerInformation), /* FIXME: not implemented */ - SI_XX(SystemEmulationBasicInformation), /* FIXME: not implemented */ + SI_QX(SystemEmulationBasicInformation), SI_XX(SystemEmulationProcessorInformation), /* FIXME: not implemented */ SI_QX(SystemExtendedHandleInformation), SI_XX(SystemLostDelayedWriteInformation), /* FIXME: not implemented */ diff --git a/ntoskrnl/fsrtl/notify.c b/ntoskrnl/fsrtl/notify.c index f69475c9984d9..1c6a27479bf2f 100644 --- a/ntoskrnl/fsrtl/notify.c +++ b/ntoskrnl/fsrtl/notify.c @@ -1415,7 +1415,7 @@ FsRtlNotifyFilterReportChange(IN PNOTIFY_SYNC NotifySync, /* If asking for old name in case of a rename, notify later on, * so that we can wait for new name. - * http://msdn.microsoft.com/en-us/library/dn392331.aspx + * https://learn.microsoft.com/en-us/openspecs/main/ms-openspeclp/3589baea-5b22-48f2-9d43-f5bea4960ddb */ if (Action == FILE_ACTION_RENAMED_OLD_NAME) { diff --git a/ntoskrnl/inbv/inbv.c b/ntoskrnl/inbv/inbv.c index 006f96a4192d1..31902337e159d 100644 --- a/ntoskrnl/inbv/inbv.c +++ b/ntoskrnl/inbv/inbv.c @@ -91,6 +91,8 @@ static ULONG InbvTerminalBkgdColor = 40; /* FUNCTIONS *****************************************************************/ +#define RT_BITMAP MAKEINTRESOURCE(2) + CODE_SEG("INIT") static PVOID @@ -131,9 +133,10 @@ FindBitmapResource( if (NextEntry != ListHead) { /* Try to find the resource */ - ResourceInfo.Type = 2; // RT_BITMAP; + ResourceInfo.Type = RT_BITMAP; ResourceInfo.Name = ResourceId; - ResourceInfo.Language = 0; + ResourceInfo.Language = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL); + Status = LdrFindResource_U(LdrEntry->DllBase, &ResourceInfo, RESOURCE_DATA_LEVEL, diff --git a/ntoskrnl/inbv/resources/copyright.bmp b/ntoskrnl/inbv/resources/copyright.bmp index 8ed8975abfca5..5f96f94411ba5 100644 Binary files a/ntoskrnl/inbv/resources/copyright.bmp and b/ntoskrnl/inbv/resources/copyright.bmp differ diff --git a/ntoskrnl/include/internal/amd64/ke.h b/ntoskrnl/include/internal/amd64/ke.h index f0c6785ae6f80..2bd4d5c8f3db3 100644 --- a/ntoskrnl/include/internal/amd64/ke.h +++ b/ntoskrnl/include/internal/amd64/ke.h @@ -356,7 +356,10 @@ KiEndInterrupt(IN KIRQL Irql, { /* Make sure this is from the clock handler */ ASSERT(TrapFrame->ErrorCode == 0xc10c4); - //KeLowerIrql(Irql); + + /* Disable interrupts and end the interrupt */ + _disable(); + HalEndSystemInterrupt(Irql, TrapFrame); } FORCEINLINE diff --git a/ntoskrnl/include/internal/cm.h b/ntoskrnl/include/internal/cm.h index f40d842089570..7aed5fef6e454 100644 --- a/ntoskrnl/include/internal/cm.h +++ b/ntoskrnl/include/internal/cm.h @@ -1420,6 +1420,7 @@ CmGetSystemDriverList( extern ULONG CmpTraceLevel; extern BOOLEAN CmpSpecialBootCondition; extern BOOLEAN CmpFlushOnLockRelease; +extern ULONG CmpVolatileBoot; extern BOOLEAN CmpShareSystemHives; extern BOOLEAN CmpMiniNTBoot; extern BOOLEAN CmpNoVolatileCreates; @@ -1452,14 +1453,14 @@ extern HIVE_LIST_ENTRY CmpMachineHiveList[]; extern UNICODE_STRING CmSymbolicLinkValueName; extern UNICODE_STRING CmpSystemStartOptions; extern UNICODE_STRING CmpLoadOptions; -extern BOOLEAN CmSelfHeal; -extern BOOLEAN CmpSelfHeal; extern ULONG CmpBootType; +extern ULONG CmSelfHeal; +extern BOOLEAN CmpSelfHeal; extern HANDLE CmpRegistryRootHandle; extern BOOLEAN ExpInTextModeSetup; extern BOOLEAN InitIsWinPEMode; extern ULONG CmpHashTableSize; -extern ULONG CmpDelayedCloseSize, CmpDelayedCloseIndex; +extern ULONG CmpDelayedCloseSize; extern BOOLEAN CmpNoWrite; extern BOOLEAN CmpForceForceFlush; extern BOOLEAN CmpWasSetupBoot; @@ -1467,6 +1468,8 @@ extern BOOLEAN CmpProfileLoaded; extern PCMHIVE CmiVolatileHive; extern LIST_ENTRY CmiKeyObjectListHead; extern BOOLEAN CmpHoldLazyFlush; +extern ULONG CmpLazyFlushIntervalInSeconds; +extern ULONG CmpLazyFlushHiveCount; extern BOOLEAN HvShutdownComplete; // diff --git a/ntoskrnl/include/internal/ex.h b/ntoskrnl/include/internal/ex.h index 50dde0cbfc89b..3b3a2fbafb921 100644 --- a/ntoskrnl/include/internal/ex.h +++ b/ntoskrnl/include/internal/ex.h @@ -70,7 +70,10 @@ extern PEPROCESS ExpDebuggerProcessAttach; extern PEPROCESS ExpDebuggerProcessKill; extern ULONG_PTR ExpDebuggerPageIn; -VOID NTAPI ExpDebuggerWorker(IN PVOID Context); +VOID +NTAPI +ExpDebuggerWorker( + _In_ PVOID Context); #ifdef _WIN64 #define HANDLE_LOW_BITS (PAGE_SHIFT - 4) @@ -1507,6 +1510,20 @@ ExTimerRundown( VOID ); +VOID +NTAPI +ExUnlockUserBuffer(PMDL Mdl); + +NTSTATUS +NTAPI +ExLockUserBuffer( + PVOID BaseAddress, + ULONG Length, + KPROCESSOR_MODE AccessMode, + LOCK_OPERATION Operation, + PVOID *MappedSystemVa, + PMDL *OutMdl); + CODE_SEG("INIT") VOID NTAPI diff --git a/ntoskrnl/include/internal/i386/ke.h b/ntoskrnl/include/internal/i386/ke.h index 81194e91e0eb9..3d4675b30d842 100644 --- a/ntoskrnl/include/internal/i386/ke.h +++ b/ntoskrnl/include/internal/i386/ke.h @@ -22,6 +22,14 @@ extern "C" #define KD_BREAKPOINT_SIZE sizeof(UCHAR) #define KD_BREAKPOINT_VALUE 0xCC +/* CPUID 1 - ECX flags */ +#define X86_FEATURE_SSE3 0x00000001 +#define X86_FEATURE_SSSE3 0x00000200 +#define X86_FEATURE_SSE4_1 0x00080000 +#define X86_FEATURE_SSE4_2 0x00100000 +#define X86_FEATURE_XSAVE 0x04000000 +#define X86_FEATURE_RDRAND 0x40000000 + /* CPUID 1 - EDX flags */ #define X86_FEATURE_FPU 0x00000001 /* x87 FPU is present */ #define X86_FEATURE_VME 0x00000002 /* Virtual 8086 Extensions are present */ @@ -462,7 +470,7 @@ NTAPI KiSetProcessorType(VOID); CODE_SEG("INIT") -ULONG +ULONG64 NTAPI KiGetFeatureBits(VOID); diff --git a/ntoskrnl/include/internal/io.h b/ntoskrnl/include/internal/io.h index 10dc76bc2bac2..f78c05a14be71 100644 --- a/ntoskrnl/include/internal/io.h +++ b/ntoskrnl/include/internal/io.h @@ -1453,6 +1453,7 @@ extern GENERIC_MAPPING IopFileMapping; extern POBJECT_TYPE _IoFileObjectType; extern HAL_DISPATCH _HalDispatchTable; extern LIST_ENTRY IopErrorLogListHead; +extern ULONG IopAutoReboot; extern ULONG IopNumTriageDumpDataBlocks; extern PVOID IopTriageDumpDataBlocks[64]; extern PIO_BUS_TYPE_GUID_LIST PnpBusTypeGuidList; diff --git a/ntoskrnl/include/internal/kd64.h b/ntoskrnl/include/internal/kd64.h index bc28eb48cc918..d9be3e72cc336 100644 --- a/ntoskrnl/include/internal/kd64.h +++ b/ntoskrnl/include/internal/kd64.h @@ -33,8 +33,8 @@ // // I'm wondering whether this can be computed using MmHighestUserAddress // or whether there is already some #define somewhere else... -// See http://www.drdobbs.com/windows/faster-dll-load-load/184416918 -// and http://www.drdobbs.com/rebasing-win32-dlls/184416272 +// See https://www.drdobbs.com/windows/faster-dll-load-load/184416918 +// and https://www.drdobbs.com/rebasing-win32-dlls/184416272 // for a tentative explanation. // #define KD_HIGHEST_USER_BREAKPOINT_ADDRESS (PVOID)0x60000000 // MmHighestUserAddress @@ -375,8 +375,7 @@ KdpZeroMemory( VOID NTAPI KdpSysGetVersion( - IN PDBGKD_GET_VERSION64 Version -); + _Out_ PDBGKD_GET_VERSION64 Version); // // Context @@ -401,16 +400,14 @@ KdpSetContextState( NTSTATUS NTAPI KdpSysReadMsr( - IN ULONG Msr, - OUT PLARGE_INTEGER MsrValue -); + _In_ ULONG Msr, + _Out_ PULONGLONG MsrValue); NTSTATUS NTAPI KdpSysWriteMsr( - IN ULONG Msr, - IN PLARGE_INTEGER MsrValue -); + _In_ ULONG Msr, + _In_ PULONGLONG MsrValue); // // Bus @@ -418,26 +415,24 @@ KdpSysWriteMsr( NTSTATUS NTAPI KdpSysReadBusData( - IN ULONG BusDataType, - IN ULONG BusNumber, - IN ULONG SlotNumber, - IN ULONG Offset, - IN PVOID Buffer, - IN ULONG Length, - OUT PULONG ActualLength -); + _In_ BUS_DATA_TYPE BusDataType, + _In_ ULONG BusNumber, + _In_ ULONG SlotNumber, + _In_ ULONG Offset, + _Out_writes_bytes_(Length) PVOID Buffer, + _In_ ULONG Length, + _Out_ PULONG ActualLength); NTSTATUS NTAPI KdpSysWriteBusData( - IN ULONG BusDataType, - IN ULONG BusNumber, - IN ULONG SlotNumber, - IN ULONG Offset, - IN PVOID Buffer, - IN ULONG Length, - OUT PULONG ActualLength -); + _In_ BUS_DATA_TYPE BusDataType, + _In_ ULONG BusNumber, + _In_ ULONG SlotNumber, + _In_ ULONG Offset, + _In_reads_bytes_(Length) PVOID Buffer, + _In_ ULONG Length, + _Out_ PULONG ActualLength); // // Control Space @@ -445,22 +440,20 @@ KdpSysWriteBusData( NTSTATUS NTAPI KdpSysReadControlSpace( - IN ULONG Processor, - IN ULONG64 BaseAddress, - IN PVOID Buffer, - IN ULONG Length, - OUT PULONG ActualLength -); + _In_ ULONG Processor, + _In_ ULONG64 BaseAddress, + _Out_writes_bytes_(Length) PVOID Buffer, + _In_ ULONG Length, + _Out_ PULONG ActualLength); NTSTATUS NTAPI KdpSysWriteControlSpace( - IN ULONG Processor, - IN ULONG64 BaseAddress, - IN PVOID Buffer, - IN ULONG Length, - OUT PULONG ActualLength -); + _In_ ULONG Processor, + _In_ ULONG64 BaseAddress, + _In_reads_bytes_(Length) PVOID Buffer, + _In_ ULONG Length, + _Out_ PULONG ActualLength); // // I/O Space @@ -468,26 +461,24 @@ KdpSysWriteControlSpace( NTSTATUS NTAPI KdpSysReadIoSpace( - IN ULONG InterfaceType, - IN ULONG BusNumber, - IN ULONG AddressSpace, - IN ULONG64 IoAddress, - IN PVOID DataValue, - IN ULONG DataSize, - OUT PULONG ActualDataSize -); + _In_ INTERFACE_TYPE InterfaceType, + _In_ ULONG BusNumber, + _In_ ULONG AddressSpace, + _In_ ULONG64 IoAddress, + _Out_writes_bytes_(DataSize) PVOID DataValue, + _In_ ULONG DataSize, + _Out_ PULONG ActualDataSize); NTSTATUS NTAPI KdpSysWriteIoSpace( - IN ULONG InterfaceType, - IN ULONG BusNumber, - IN ULONG AddressSpace, - IN ULONG64 IoAddress, - IN PVOID DataValue, - IN ULONG DataSize, - OUT PULONG ActualDataSize -); + _In_ INTERFACE_TYPE InterfaceType, + _In_ ULONG BusNumber, + _In_ ULONG AddressSpace, + _In_ ULONG64 IoAddress, + _In_reads_bytes_(DataSize) PVOID DataValue, + _In_ ULONG DataSize, + _Out_ PULONG ActualDataSize); // // Low Memory diff --git a/ntoskrnl/include/internal/ke.h b/ntoskrnl/include/internal/ke.h index d05d2a24049d0..3efa907e3097d 100644 --- a/ntoskrnl/include/internal/ke.h +++ b/ntoskrnl/include/internal/ke.h @@ -90,7 +90,6 @@ typedef PCHAR IN ULONG Length ); -extern KAFFINITY KeActiveProcessors; extern PKNMI_HANDLER_CALLBACK KiNmiCallbackListHead; extern KSPIN_LOCK KiNmiCallbackListLock; extern PVOID KeUserApcDispatcher; @@ -103,7 +102,14 @@ extern BOOLEAN ExCmosClockIsSane; extern USHORT KeProcessorArchitecture; extern USHORT KeProcessorLevel; extern USHORT KeProcessorRevision; -extern ULONG KeFeatureBits; +extern ULONG64 KeFeatureBits; +extern KAFFINITY KeActiveProcessors; +extern PKPRCB KiProcessorBlock[]; +#ifdef CONFIG_SMP +extern ULONG KeMaximumProcessors; +extern ULONG KeNumprocSpecified; +extern ULONG KeBootprocSpecified; +#endif extern KNODE KiNode0; extern PKNODE KeNodeBlock[1]; extern UCHAR KeNumberNodes; @@ -136,7 +142,6 @@ extern LIST_ENTRY KiProcessListHead; extern LIST_ENTRY KiProcessInSwapListHead, KiProcessOutSwapListHead; extern LIST_ENTRY KiStackInSwapListHead; extern KEVENT KiSwapEvent; -extern PKPRCB KiProcessorBlock[]; extern KAFFINITY KiIdleSummary; extern PVOID KeUserApcDispatcher; extern PVOID KeUserCallbackDispatcher; @@ -1061,14 +1066,14 @@ KiSystemFatalException( PVOID NTAPI -KiPcToFileHeader(IN PVOID Eip, +KiPcToFileHeader(IN PVOID Pc, OUT PLDR_DATA_TABLE_ENTRY *LdrEntry, IN BOOLEAN DriversOnly, OUT PBOOLEAN InKernel); PVOID NTAPI -KiRosPcToUserFileHeader(IN PVOID Eip, +KiRosPcToUserFileHeader(IN PVOID Pc, OUT PLDR_DATA_TABLE_ENTRY *LdrEntry); PCHAR @@ -1079,6 +1084,14 @@ KeBugCheckUnicodeToAnsi( IN ULONG Length ); +#ifdef CONFIG_SMP +ULONG +NTAPI +KiFindIdealProcessor( + _In_ KAFFINITY ProcessorSet, + _In_ UCHAR OriginalIdealProcessor); +#endif // CONFIG_SMP + #ifdef __cplusplus } // extern "C" diff --git a/ntoskrnl/include/internal/mm.h b/ntoskrnl/include/internal/mm.h index 91bf7599df236..3f56c9b9d0895 100644 --- a/ntoskrnl/include/internal/mm.h +++ b/ntoskrnl/include/internal/mm.h @@ -131,6 +131,13 @@ typedef ULONG_PTR SWAPENTRY; #define MM_ROUND_DOWN(x,s) \ ((PVOID)(((ULONG_PTR)(x)) & ~((ULONG_PTR)(s)-1))) +/* PAGE_ROUND_UP and PAGE_ROUND_DOWN equivalent, with support for 64-bit-only data types */ +#define PAGE_ROUND_UP_64(x) \ + (((x) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) + +#define PAGE_ROUND_DOWN_64(x) \ + ((x) & ~(PAGE_SIZE - 1)) + #define PAGE_FLAGS_VALID_FOR_SECTION \ (PAGE_READONLY | \ PAGE_READWRITE | \ @@ -1642,12 +1649,17 @@ MmUnloadSystemImage( IN PVOID ImageHandle ); +#ifdef CONFIG_SMP +BOOLEAN +NTAPI +MmVerifyImageIsOkForMpUse( + _In_ PVOID BaseAddress); +#endif // CONFIG_SMP + NTSTATUS NTAPI MmCheckSystemImage( - IN HANDLE ImageHandle, - IN BOOLEAN PurgeSection -); + _In_ HANDLE ImageHandle); NTSTATUS NTAPI diff --git a/ntoskrnl/include/internal/ob.h b/ntoskrnl/include/internal/ob.h index 4aad5a5e253f2..9b897392f0396 100644 --- a/ntoskrnl/include/internal/ob.h +++ b/ntoskrnl/include/internal/ob.h @@ -205,7 +205,7 @@ ObpLookupEntryDirectory( IN POBJECT_DIRECTORY Directory, IN PUNICODE_STRING Name, IN ULONG Attributes, - IN UCHAR SearchShadow, + IN BOOLEAN SearchShadow, IN POBP_LOOKUP_CONTEXT Context ); @@ -648,6 +648,7 @@ extern ALIGNEDNAME ObpDosDevicesShortNameRoot; extern UNICODE_STRING ObpDosDevicesShortName; extern WCHAR ObpUnsecureGlobalNamesBuffer[128]; extern ULONG ObpUnsecureGlobalNamesLength; +extern ULONG ObpCaseInsensitive; extern ULONG ObpObjectSecurityMode; extern ULONG ObpProtectionMode; extern ULONG ObpLUIDDeviceMapsDisabled; diff --git a/ntoskrnl/include/internal/ps_i.h b/ntoskrnl/include/internal/ps_i.h index 21f8368fa8896..04d564bd36a88 100644 --- a/ntoskrnl/include/internal/ps_i.h +++ b/ntoskrnl/include/internal/ps_i.h @@ -27,7 +27,9 @@ static const INFORMATION_CLASS_INFO PsProcessInfoClass[] = ( QUOTA_LIMITS, ULONG, - ICIF_QUERY | ICIF_SET | ICIF_SET_SIZE_VARIABLE + + /* NOTE: ICIF_SIZE_VARIABLE is for QUOTA_LIMITS_EX support */ + ICIF_QUERY | ICIF_SET | ICIF_SIZE_VARIABLE ), /* ProcessIoCounters */ diff --git a/ntoskrnl/include/internal/tag.h b/ntoskrnl/include/internal/tag.h index 35cf14d6ae620..6febe9d6e5118 100644 --- a/ntoskrnl/include/internal/tag.h +++ b/ntoskrnl/include/internal/tag.h @@ -59,7 +59,6 @@ #define TAG_IO_TIMER 'MTOI' #define TAG_DRIVER 'RVRD' #define TAG_DRIVER_EXTENSION 'EVRD' -#define TAG_SYSB 'BSYS' #define TAG_LOCK 'kclF' #define TAG_FILE_NAME 'MANF' #define TAG_FILE_SYSTEM 'SYSF' @@ -84,8 +83,8 @@ #define TAG_REINIT 'iRoI' #define TAG_IOWI 'IWOI' #define TAG_IRP ' prI' -#define TAG_SYS_BUF 'BSYS' -#define TAG_KINTERRUPT 'RSIK' +#define TAG_IOBUF 'UBOI' +#define TAG_IO_INTERRUPT 'nioI' #define TAG_MDL ' LDM' #define TAG_IO_DEVNODE 'donD' #define TAG_PNP_NOTIFY 'NPnP' @@ -93,9 +92,9 @@ #define TAG_IO_RESOURCE 'CRSR' #define TAG_IO_TIMER 'MTOI' #define TAG_VPB ' BPV' -#define TAG_SYSB 'BSYS' #define TAG_RTLREGISTRY 'vrqR' #define TAG_PNP_DEVACTION 'aDpP' +#define TAG_DEV2DOS ' d2D' /* Loader Related Tags */ #define TAG_MODULE_OBJECT 'omlk' /* klmo - kernel ldr module object */ diff --git a/ntoskrnl/include/sysfuncs.h b/ntoskrnl/include/sysfuncs.h index b900287d4e535..422a71fa1141c 100644 --- a/ntoskrnl/include/sysfuncs.h +++ b/ntoskrnl/include/sysfuncs.h @@ -294,3 +294,8 @@ SVC_(QueryPortInformationProcess, 0) SVC_(GetCurrentProcessorNumber, 0) SVC_(WaitForMultipleObjects32, 5) +#ifdef BUILD_WOW6432 + SVC_(Wow64AllocateVirtualMemory64, 7) + SVC_(Wow64ReadVirtualMemory64, 7) + SVC_(Wow64WriteVirtualMemory64, 7) +#endif \ No newline at end of file diff --git a/ntoskrnl/io/iomgr/deviface.c b/ntoskrnl/io/iomgr/deviface.c index ed81e4407c4af..5c3391f929b88 100644 --- a/ntoskrnl/io/iomgr/deviface.c +++ b/ntoskrnl/io/iomgr/deviface.c @@ -7,6 +7,7 @@ * PROGRAMMERS: Filip Navara (xnavara@volny.cz) * Matthew Brace (ismarc@austin.rr.com) * Hervé Poussineau (hpoussin@reactos.org) + * Oleg Dubinskiy (oleg.dubinskiy@reactos.org) */ /* INCLUDES ******************************************************************/ @@ -26,189 +27,542 @@ C_ASSERT(sizeof(L"{01234567-89ab-cdef-0123-456789abcdef}") == GUID_STRING_BYTES PDEVICE_OBJECT IopGetDeviceObjectFromDeviceInstance(PUNICODE_STRING DeviceInstance); -static PWCHAR BaseKeyString = L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\DeviceClasses\\"; +static PCWSTR BaseKeyString = L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\DeviceClasses\\"; +/** + * @brief + * Creates a new symbolic link from the specified format of the prefix, device string, + * class GUID and reference string (if any). + * + * @param[in] DeviceString + * Device string, placed after prefix and before GUID, for example ACPI#PNP0501#1#. + * + * @param[in] GuidString + * Device interface class GUID represented by a string. Placed in curly brackets {}, + * after device string, should always be 38 characters long. For example, + * {01234567-89ab-cdef-0123-456789abcdef}. + * + * @param[in] ReferenceString + * Optional reference string, if any. Placed after GUID, at the end of symbolic link. + * Usually contains human-readable subdevice name or class GUID. + * + * @param[in] UserModePrefixFormat + * Specifies whether a new symbolic link should have either a kernel mode or user mode prefix. + * TRUE for user mode prefix, FALSE for kernel mode. + * + * @param[out] SymbolicLinkName + * Pointer to unicode string which receives created symbolic link. + * + * @return + * STATUS_SUCCESS in case of success, or an NTSTATUS error code otherwise. + **/ static NTSTATUS -OpenRegistryHandlesFromSymbolicLink(IN PUNICODE_STRING SymbolicLinkName, - IN ACCESS_MASK DesiredAccess, - IN OPTIONAL PHANDLE GuidKey, - IN OPTIONAL PHANDLE DeviceKey, - IN OPTIONAL PHANDLE InstanceKey) +IopBuildSymbolicLink( + _In_ PCUNICODE_STRING DeviceString, + _In_ PCUNICODE_STRING GuidString, + _In_opt_ PCUNICODE_STRING ReferenceString, + _In_ BOOLEAN UserModePrefixFormat, + _Out_ PUNICODE_STRING SymbolicLinkName) { - OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING BaseKeyU; - UNICODE_STRING GuidString, SubKeyName, ReferenceString; - PWCHAR StartPosition, EndPosition; - HANDLE ClassesKey; - PHANDLE GuidKeyRealP, DeviceKeyRealP, InstanceKeyRealP; - HANDLE GuidKeyReal, DeviceKeyReal, InstanceKeyReal; + static const UNICODE_STRING KernelModePrefix = RTL_CONSTANT_STRING(L"\\??\\"); + static const UNICODE_STRING UserModePrefix = RTL_CONSTANT_STRING(L"\\\\?\\"); + static const UNICODE_STRING PathSep = RTL_CONSTANT_STRING(L"\\"); + UNICODE_STRING MungedDeviceString, SymbolicLink; NTSTATUS Status; + ULONG Length; + USHORT i; - SubKeyName.Buffer = NULL; + /* Use a backslash if reference string is not specified */ + if (!ReferenceString) + ReferenceString = &PathSep; - if (GuidKey != NULL) - GuidKeyRealP = GuidKey; - else - GuidKeyRealP = &GuidKeyReal; + /* Duplicate the device string (to "munge" it) */ + Status = RtlDuplicateUnicodeString(0, DeviceString, &MungedDeviceString); + if (!NT_SUCCESS(Status)) + { + DPRINT1("RtlDuplicateUnicodeString() failed, Status 0x%08lx\n", Status); + return Status; + } - if (DeviceKey != NULL) - DeviceKeyRealP = DeviceKey; - else - DeviceKeyRealP = &DeviceKeyReal; + /* Replace all '\' by '#' in device string */ + for (i = 0; i < MungedDeviceString.Length / sizeof(WCHAR); i++) + { + if (MungedDeviceString.Buffer[i] == L'\\') + MungedDeviceString.Buffer[i] = L'#'; + } - if (InstanceKey != NULL) - InstanceKeyRealP = InstanceKey; - else - InstanceKeyRealP = &InstanceKeyReal; + /* Calculate total length */ + Length = KernelModePrefix.Length // Same as UserModePrefix.Length + + MungedDeviceString.Length + + sizeof(L"#") + GuidString->Length + + ReferenceString->Length; + ASSERT(Length <= MAXUSHORT); + + /* Build up new symbolic link */ + SymbolicLink.Length = 0; + SymbolicLink.MaximumLength = Length; + SymbolicLink.Buffer = ExAllocatePoolWithTag(PagedPool, SymbolicLink.MaximumLength, TAG_IO); + if (!SymbolicLink.Buffer) + { + DPRINT1("ExAllocatePoolWithTag() failed\n"); + return STATUS_INSUFFICIENT_RESOURCES; + } - *GuidKeyRealP = NULL; - *DeviceKeyRealP = NULL; - *InstanceKeyRealP = NULL; + Status = RtlUnicodeStringPrintf(&SymbolicLink, + L"%wZ%wZ#%wZ%wZ", + UserModePrefixFormat ? + &UserModePrefix : &KernelModePrefix, + &MungedDeviceString, + GuidString, + ReferenceString); + NT_VERIFY(NT_SUCCESS(Status)); - RtlInitUnicodeString(&BaseKeyU, BaseKeyString); + DPRINT("New symbolic link is %wZ\n", &SymbolicLink); - /* Open the DeviceClasses key */ - InitializeObjectAttributes(&ObjectAttributes, - &BaseKeyU, - OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, - NULL, - NULL); - Status = ZwOpenKey(&ClassesKey, - DesiredAccess | KEY_ENUMERATE_SUB_KEYS, - &ObjectAttributes); - if (!NT_SUCCESS(Status)) + *SymbolicLinkName = SymbolicLink; + return STATUS_SUCCESS; +} + +/** + * @brief + * Parses the specified symbolic link onto the 4 parts: prefix, device string, + * class GUID and reference string. + * + * @param[in] SymbolicLinkName + * Pointer to a symbolic link string to parse. + * + * @param[out] PrefixString + * Receives prefix of symbolic link. Can be '\??\' for Kernel mode or '\\?\' for User mode. + * + * @param[out] MungedString + * Receives device string. For example, ##?#ACPI#PNP0501#1#. + * + * @param[out] GuidString + * Receives device interface class GUID string represented by device interface. + * For example, {01234567-89ab-cdef-0123-456789abcdef}. + * + * @param[out] ReferenceString + * Receives reference string, if any. Usually contains a human-readable + * subdevice name or class GUID. + * + * @param[out] ReferenceStringPresent + * Pointer to variable that indicates whether the reference string exists in symbolic link. + * TRUE if it does, FALSE otherwise. + * + * @param[out] InterfaceClassGuid + * Receives the interface class GUID to which specified symbolic link belongs to. + * + * @return + * STATUS_SUCCESS in case of success, or an NTSTATUS error code otherwise. + **/ +static +NTSTATUS +IopSeparateSymbolicLink( + _In_ PCUNICODE_STRING SymbolicLinkName, + _Out_opt_ PUNICODE_STRING PrefixString, + _Out_opt_ PUNICODE_STRING MungedString, + _Out_opt_ PUNICODE_STRING GuidString, + _Out_opt_ PUNICODE_STRING ReferenceString, + _Out_opt_ PBOOLEAN ReferenceStringPresent, + _Out_opt_ LPGUID InterfaceClassGuid) +{ + static const UNICODE_STRING KernelModePrefix = RTL_CONSTANT_STRING(L"\\??\\"); + static const UNICODE_STRING UserModePrefix = RTL_CONSTANT_STRING(L"\\\\?\\"); + UNICODE_STRING MungedStringReal, GuidStringReal, ReferenceStringReal; + UNICODE_STRING LinkNameNoPrefix; + USHORT i, ReferenceStringOffset; + NTSTATUS Status = STATUS_SUCCESS; + + DPRINT("Symbolic link is %wZ\n", SymbolicLinkName); + + /* The symbolic link name looks like \??\ACPI#PNP0501#1#{GUID}\ReferenceString + * Make sure it starts with the expected prefix. */ + if (!RtlPrefixUnicodeString(&KernelModePrefix, SymbolicLinkName, FALSE) && + !RtlPrefixUnicodeString(&UserModePrefix, SymbolicLinkName, FALSE)) { - DPRINT1("Failed to open %wZ\n", &BaseKeyU); - goto cleanup; + DPRINT1("Invalid link name %wZ\n", SymbolicLinkName); + return STATUS_INVALID_PARAMETER; } - StartPosition = wcschr(SymbolicLinkName->Buffer, L'{'); - EndPosition = wcschr(SymbolicLinkName->Buffer, L'}'); - if (!StartPosition || !EndPosition || StartPosition > EndPosition) + /* Sanity checks */ + ASSERT(KernelModePrefix.Length == UserModePrefix.Length); + ASSERT(SymbolicLinkName->Length >= KernelModePrefix.Length); + + /* Make a version without the prefix for further processing */ + LinkNameNoPrefix.Buffer = SymbolicLinkName->Buffer + KernelModePrefix.Length / sizeof(WCHAR); + LinkNameNoPrefix.Length = SymbolicLinkName->Length - KernelModePrefix.Length; + LinkNameNoPrefix.MaximumLength = LinkNameNoPrefix.Length; + + DPRINT("Symbolic link without prefix is %wZ\n", &LinkNameNoPrefix); + + /* Find the reference string, if any */ + for (i = 0; i < LinkNameNoPrefix.Length / sizeof(WCHAR); i++) { - DPRINT1("Bad symbolic link: %wZ\n", SymbolicLinkName); - return STATUS_INVALID_PARAMETER_1; + if (LinkNameNoPrefix.Buffer[i] == L'\\') + break; } - GuidString.Buffer = StartPosition; - GuidString.MaximumLength = GuidString.Length = (USHORT)((ULONG_PTR)(EndPosition + 1) - (ULONG_PTR)StartPosition); + ReferenceStringOffset = i * sizeof(WCHAR); - InitializeObjectAttributes(&ObjectAttributes, - &GuidString, - OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, - ClassesKey, - NULL); - Status = ZwCreateKey(GuidKeyRealP, - DesiredAccess | KEY_ENUMERATE_SUB_KEYS, - &ObjectAttributes, - 0, - NULL, - REG_OPTION_NON_VOLATILE, - NULL); - ZwClose(ClassesKey); - if (!NT_SUCCESS(Status)) + /* The GUID is before the reference string or at the end */ + ASSERT(LinkNameNoPrefix.Length >= ReferenceStringOffset); + if (ReferenceStringOffset < GUID_STRING_BYTES + sizeof(WCHAR)) { - DPRINT1("Failed to open %wZ%wZ (%x)\n", &BaseKeyU, &GuidString, Status); - goto cleanup; + DPRINT1("Invalid link name %wZ\n", SymbolicLinkName); + return STATUS_INVALID_PARAMETER; } - SubKeyName.MaximumLength = SymbolicLinkName->Length + sizeof(WCHAR); - SubKeyName.Length = 0; - SubKeyName.Buffer = ExAllocatePool(PagedPool, SubKeyName.MaximumLength); - if (!SubKeyName.Buffer) + /* Get reference string (starts with \ after {GUID}) from link without prefix */ + ReferenceStringReal.Buffer = LinkNameNoPrefix.Buffer + ReferenceStringOffset / sizeof(WCHAR); + ReferenceStringReal.Length = LinkNameNoPrefix.Length - ReferenceStringOffset; + ReferenceStringReal.MaximumLength = ReferenceStringReal.Length; + + DPRINT("Reference string is %wZ\n", &ReferenceStringReal); + + /* Get GUID string (device class GUID in {} brackets) */ + GuidStringReal.Buffer = LinkNameNoPrefix.Buffer + (ReferenceStringOffset - GUID_STRING_BYTES) / sizeof(WCHAR); + GuidStringReal.Length = GUID_STRING_BYTES; + GuidStringReal.MaximumLength = GuidStringReal.Length; + + DPRINT("GUID string is %wZ\n", &GuidStringReal); + + /* Validate GUID string for: + * 1) {} brackets at the start and the end; + * 2) - separators in the appropriate places. */ + ASSERT(GuidStringReal.Buffer[0] == L'{'); + ASSERT(GuidStringReal.Buffer[GUID_STRING_CHARS - 1] == L'}'); + ASSERT(GuidStringReal.Buffer[9] == L'-'); + ASSERT(GuidStringReal.Buffer[14] == L'-'); + ASSERT(GuidStringReal.Buffer[19] == L'-'); + ASSERT(GuidStringReal.Buffer[24] == L'-'); + + if (MungedString) { - Status = STATUS_INSUFFICIENT_RESOURCES; - goto cleanup; + /* Create a munged path string (looks like ACPI#PNP0501#1#) */ + MungedStringReal.Buffer = LinkNameNoPrefix.Buffer; + MungedStringReal.Length = LinkNameNoPrefix.Length - ReferenceStringReal.Length - GUID_STRING_BYTES - sizeof(WCHAR); + MungedStringReal.MaximumLength = MungedStringReal.Length; + + DPRINT("Munged string is %wZ\n", &MungedStringReal); } - RtlAppendUnicodeStringToString(&SubKeyName, - SymbolicLinkName); + /* Store received parts if the parameters are not null */ + if (PrefixString) + { + PrefixString->Buffer = SymbolicLinkName->Buffer; + PrefixString->Length = KernelModePrefix.Length; // Same as UserModePrefix.Length + PrefixString->MaximumLength = PrefixString->Length; + + DPRINT("Prefix string is %wZ\n", PrefixString); + } - SubKeyName.Buffer[SubKeyName.Length / sizeof(WCHAR)] = UNICODE_NULL; + if (MungedString) + *MungedString = MungedStringReal; - SubKeyName.Buffer[0] = L'#'; - SubKeyName.Buffer[1] = L'#'; - SubKeyName.Buffer[2] = L'?'; - SubKeyName.Buffer[3] = L'#'; + if (GuidString) + *GuidString = GuidStringReal; - ReferenceString.Buffer = wcsrchr(SubKeyName.Buffer, '\\'); - if (ReferenceString.Buffer != NULL) + if (ReferenceString) { - ReferenceString.Buffer[0] = L'#'; + if (ReferenceStringReal.Length > sizeof(WCHAR)) + *ReferenceString = ReferenceStringReal; + else + RtlInitEmptyUnicodeString(ReferenceString, NULL, 0); + } + + if (ReferenceStringPresent) + *ReferenceStringPresent = ReferenceStringReal.Length > sizeof(WCHAR); + + if (InterfaceClassGuid) + { + /* Convert GUID string into a GUID and store it also */ + Status = RtlGUIDFromString(&GuidStringReal, InterfaceClassGuid); + if (!NT_SUCCESS(Status)) + { + DPRINT1("RtlGUIDFromString() failed, Status 0x%08lx\n", Status); + } + } + + /* We're done */ + return Status; +} + +/** + * @brief + * Retrieves a handles to the device and instance registry keys + * for the previously opened registry key handle of the specified symbolic link. + **/ +static +NTSTATUS +IopOpenOrCreateSymbolicLinkSubKeys( + _Out_opt_ PHANDLE DeviceHandle, + _Out_opt_ PULONG DeviceDisposition, + _Out_opt_ PHANDLE InstanceHandle, + _Out_opt_ PULONG InstanceDisposition, + _In_ HANDLE ClassHandle, + _In_ PCUNICODE_STRING SymbolicLinkName, + _In_ ACCESS_MASK DesiredAccess, + _In_ BOOLEAN Create) +{ + UNICODE_STRING ReferenceString = {0}; + UNICODE_STRING SymbolicLink = {0}; + HANDLE DeviceKeyHandle, InstanceKeyHandle; + ULONG DeviceKeyDisposition, InstanceKeyDisposition; + BOOLEAN ReferenceStringPresent = FALSE; /* Assuming no ref string by default */ + NTSTATUS Status; + USHORT i; + + DeviceKeyHandle = InstanceKeyHandle = NULL; + + /* Duplicate the symbolic link (we'll modify it later) */ + Status = RtlDuplicateUnicodeString(0, SymbolicLinkName, &SymbolicLink); + if (!NT_SUCCESS(Status)) + { + DPRINT1("RtlDuplicateUnicodeString() failed, Status 0x%08lx\n", Status); + goto Quit; + } - SubKeyName.Length = (USHORT)((ULONG_PTR)(ReferenceString.Buffer) - (ULONG_PTR)SubKeyName.Buffer); - ReferenceString.Length = SymbolicLinkName->Length - SubKeyName.Length; + /* Separate it into its constituents */ + Status = IopSeparateSymbolicLink(&SymbolicLink, + NULL, + NULL, + NULL, + &ReferenceString, + &ReferenceStringPresent, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to separate symbolic link %wZ, Status 0x%08lx\n", &SymbolicLink, Status); + goto Quit; + } + + /* Did we got a ref string? */ + if (ReferenceStringPresent) + { + /* Remove it from our symbolic link */ + SymbolicLink.MaximumLength = SymbolicLink.Length -= ReferenceString.Length; + + /* Replace the 1st backslash `\` character by '#' pound */ + ReferenceString.Buffer[0] = L'#'; } else { + /* No ref string, initialize it with a single pound character '#' */ RtlInitUnicodeString(&ReferenceString, L"#"); } - InitializeObjectAttributes(&ObjectAttributes, - &SubKeyName, - OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, - *GuidKeyRealP, - NULL); - Status = ZwCreateKey(DeviceKeyRealP, - DesiredAccess | KEY_ENUMERATE_SUB_KEYS, - &ObjectAttributes, - 0, - NULL, - REG_OPTION_NON_VOLATILE, - NULL); + /* Replace all '\' by '#' in symbolic link */ + for (i = 0; i < SymbolicLink.Length / sizeof(WCHAR); i++) + { + if (SymbolicLink.Buffer[i] == L'\\') + SymbolicLink.Buffer[i] = L'#'; + } + + /* Fix prefix: '#??#' -> '##?#' */ + SymbolicLink.Buffer[1] = L'#'; + + DPRINT("Munged symbolic link is %wZ\n", &SymbolicLink); + + /* Try to open or create device interface keys */ + if (Create) + { + Status = IopCreateRegistryKeyEx(&DeviceKeyHandle, + ClassHandle, + &SymbolicLink, + DesiredAccess | KEY_ENUMERATE_SUB_KEYS, + REG_OPTION_NON_VOLATILE, + &DeviceKeyDisposition); + } + else + { + Status = IopOpenRegistryKeyEx(&DeviceKeyHandle, + ClassHandle, + &SymbolicLink, + DesiredAccess | KEY_ENUMERATE_SUB_KEYS); + } + if (!NT_SUCCESS(Status)) { - DPRINT1("Failed to open %wZ%wZ\\%wZ Status %x\n", &BaseKeyU, &GuidString, &SubKeyName, Status); - goto cleanup; + DPRINT1("Failed to create or open %wZ, Status 0x%08lx\n", &SymbolicLink, Status); + goto Quit; + } + + DPRINT("Munged reference string is %wZ\n", &ReferenceString); + + /* Try to open or create instance subkeys */ + if (Create) + { + Status = IopCreateRegistryKeyEx(&InstanceKeyHandle, + DeviceKeyHandle, + &ReferenceString, + DesiredAccess, + REG_OPTION_NON_VOLATILE, + &InstanceKeyDisposition); + } + else + { + Status = IopOpenRegistryKeyEx(&InstanceKeyHandle, + DeviceKeyHandle, + &ReferenceString, + DesiredAccess); } - InitializeObjectAttributes(&ObjectAttributes, - &ReferenceString, - OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, - *DeviceKeyRealP, - NULL); - Status = ZwCreateKey(InstanceKeyRealP, - DesiredAccess, - &ObjectAttributes, - 0, - NULL, - REG_OPTION_NON_VOLATILE, - NULL); if (!NT_SUCCESS(Status)) { - DPRINT1("Failed to open %wZ%wZ\\%wZ%\\%wZ (%x)\n", &BaseKeyU, &GuidString, &SubKeyName, &ReferenceString, Status); - goto cleanup; + DPRINT1("Failed to create or open %wZ, Status 0x%08lx\n", &ReferenceString, Status); + goto Quit; } Status = STATUS_SUCCESS; -cleanup: - if (SubKeyName.Buffer != NULL) - ExFreePool(SubKeyName.Buffer); - +Quit: if (NT_SUCCESS(Status)) { - if (!GuidKey) - ZwClose(*GuidKeyRealP); + if (DeviceHandle) + *DeviceHandle = DeviceKeyHandle; + else + ZwClose(DeviceKeyHandle); + + if (DeviceDisposition) + *DeviceDisposition = DeviceKeyDisposition; + + if (InstanceHandle) + *InstanceHandle = InstanceKeyHandle; + else + ZwClose(InstanceKeyHandle); + + if (InstanceDisposition) + *InstanceDisposition = InstanceKeyDisposition; + } + else + { + if (InstanceKeyHandle) + ZwClose(InstanceKeyHandle); + + if (Create) + ZwDeleteKey(DeviceKeyHandle); + + if (DeviceKeyHandle) + ZwClose(DeviceKeyHandle); + } + + if (SymbolicLink.Buffer) + RtlFreeUnicodeString(&SymbolicLink); + + return Status; +} + +/** + * @brief + * Retrieves a handles to the GUID, device and instance registry keys + * for the specified symbolic link. + **/ +static +NTSTATUS +OpenRegistryHandlesFromSymbolicLink( + _In_ PCUNICODE_STRING SymbolicLinkName, + _In_ ACCESS_MASK DesiredAccess, + _Out_opt_ PHANDLE GuidKey, + _Out_opt_ PHANDLE DeviceKey, + _Out_opt_ PHANDLE InstanceKey) +{ + UNICODE_STRING BaseKeyU; + UNICODE_STRING GuidString; + HANDLE ClassesKey; + HANDLE GuidKeyReal, DeviceKeyReal, InstanceKeyReal; + NTSTATUS Status; + + ClassesKey = GuidKeyReal = DeviceKeyReal = InstanceKeyReal = NULL; + + RtlInitUnicodeString(&BaseKeyU, BaseKeyString); + + /* Separate symbolic link onto the parts */ + Status = IopSeparateSymbolicLink(SymbolicLinkName, + NULL, + NULL, + &GuidString, + NULL, + NULL, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to parse symbolic link %wZ, Status 0x%08lx\n", + SymbolicLinkName, Status); + goto Quit; + } + + /* Open the DeviceClasses key */ + Status = IopOpenRegistryKeyEx(&ClassesKey, + NULL, + &BaseKeyU, + DesiredAccess | KEY_ENUMERATE_SUB_KEYS); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to open %wZ, Status 0x%08lx\n", &BaseKeyU, Status); + goto Quit; + } + + /* Open the GUID subkey */ + Status = IopOpenRegistryKeyEx(&GuidKeyReal, + ClassesKey, + &GuidString, + DesiredAccess | KEY_ENUMERATE_SUB_KEYS); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to open %wZ%wZ, Status 0x%08lx\n", &BaseKeyU, &GuidString, Status); + goto Quit; + } + + /* Open the device and instance subkeys */ + Status = IopOpenOrCreateSymbolicLinkSubKeys(&DeviceKeyReal, + NULL, + &InstanceKeyReal, + NULL, + GuidKeyReal, + SymbolicLinkName, + DesiredAccess, + FALSE); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to open %wZ%wZ, Status 0x%08lx\n", &BaseKeyU, &GuidString, Status); + goto Quit; + } - if (!DeviceKey) - ZwClose(*DeviceKeyRealP); + Status = STATUS_SUCCESS; - if (!InstanceKey) - ZwClose(*InstanceKeyRealP); +Quit: + if (NT_SUCCESS(Status)) + { + if (GuidKey) + *GuidKey = GuidKeyReal; + else + ZwClose(GuidKeyReal); + + if (DeviceKey) + *DeviceKey = DeviceKeyReal; + else + ZwClose(DeviceKeyReal); + + if (InstanceKey) + *InstanceKey = InstanceKeyReal; + else + ZwClose(InstanceKeyReal); } else { - if (*GuidKeyRealP != NULL) - ZwClose(*GuidKeyRealP); + if (GuidKeyReal) + ZwClose(GuidKeyReal); - if (*DeviceKeyRealP != NULL) - ZwClose(*DeviceKeyRealP); + if (DeviceKeyReal) + ZwClose(DeviceKeyReal); - if (*InstanceKeyRealP != NULL) - ZwClose(*InstanceKeyRealP); + if (InstanceKeyReal) + ZwClose(InstanceKeyReal); } + if (ClassesKey) + ZwClose(ClassesKey); + return Status; } @@ -275,38 +629,6 @@ IoOpenDeviceInterfaceRegistryKey(IN PUNICODE_STRING SymbolicLinkName, return Status; } -/*++ - * @name IoGetDeviceInterfaceAlias - * @unimplemented - * - * Returns the alias device interface of the specified device interface - * instance, if the alias exists. - * Documented in WDK. - * - * @param SymbolicLinkName - * Pointer to a string which identifies the device interface instance - * - * @param AliasInterfaceClassGuid - * See WDK - * - * @param AliasSymbolicLinkName - * See WDK - * - * @return Three different NTSTATUS values in case of errors, and STATUS_SUCCESS - * otherwise (see WDK for details) - * - * @remarks Must be called at IRQL = PASSIVE_LEVEL in the context of a system thread - * - *--*/ -NTSTATUS -NTAPI -IoGetDeviceInterfaceAlias(IN PUNICODE_STRING SymbolicLinkName, - IN CONST GUID *AliasInterfaceClassGuid, - OUT PUNICODE_STRING AliasSymbolicLinkName) -{ - return STATUS_NOT_IMPLEMENTED; -} - /*++ * @name IopOpenInterfaceKey * @@ -412,6 +734,166 @@ IopOpenInterfaceKey(IN CONST GUID *InterfaceClassGuid, return Status; } +/** + * @brief + * Returns the alias device interface of the specified device interface + * instance, if the alias exists. + * + * @param[in] SymbolicLinkName + * Pointer to a symbolic link string which identifies the device interface instance. + * + * @param[in] AliasInterfaceClassGuid + * Pointer to a device interface class GUID. + * + * @param[out] AliasSymbolicLinkName + * Pointer to unicode string which receives the alias symbolic link upon success. + * Must be freed with RtlFreeUnicodeString after using. + * + * @return NTSTATUS values in case of errors, STATUS_SUCCESS otherwise. + * + * @remarks Must be called at IRQL = PASSIVE_LEVEL in the context of a system thread + **/ +NTSTATUS +NTAPI +IoGetDeviceInterfaceAlias( + _In_ PUNICODE_STRING SymbolicLinkName, + _In_ CONST GUID *AliasInterfaceClassGuid, + _Out_ PUNICODE_STRING AliasSymbolicLinkName) +{ + static const UNICODE_STRING UserModePrefix = RTL_CONSTANT_STRING(L"\\\\?\\"); + UNICODE_STRING AliasSymbolicLink = {0}; + UNICODE_STRING AliasGuidString = {0}; + UNICODE_STRING DeviceString = {0}; + UNICODE_STRING ReferenceString = {0}; + PKEY_VALUE_FULL_INFORMATION kvInfo; + HANDLE DeviceKey, AliasInstanceKey; + BOOLEAN UserModePrefixFormat; + BOOLEAN ReferenceStringPresent = FALSE; /* Assuming no ref string by default */ + PVOID Buffer; + NTSTATUS Status; + + DPRINT("IoGetDeviceInterfaceAlias(%wZ, 0x%p)\n", SymbolicLinkName, AliasInterfaceClassGuid); + + /* Sanity check */ + if (!SymbolicLinkName || !AliasInterfaceClassGuid) + { + DPRINT1("IoGetDeviceInterfaceAlias() invalid symbolic link or alias class GUID\n"); + return STATUS_INVALID_PARAMETER; + } + + /* Convert alias GUID to a string */ + Status = RtlStringFromGUID(AliasInterfaceClassGuid, &AliasGuidString); + if (!NT_SUCCESS(Status)) + { + DPRINT1("RtlStringFromGUID() failed, Status 0x%08lx\n", Status); + goto Quit; + } + + DPRINT("Alias GUID is %wZ\n", &AliasGuidString); + + /* Get the device instance string of existing symbolic link */ + Status = OpenRegistryHandlesFromSymbolicLink(SymbolicLinkName, + KEY_QUERY_VALUE, + NULL, + &DeviceKey, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to open device instance key for %wZ, Status 0x%08lx\n", SymbolicLinkName, Status); + goto Quit; + } + + Status = IopGetRegistryValue(DeviceKey, L"DeviceInstance", &kvInfo); + ZwClose(DeviceKey); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed get device instance value, Status 0x%08lx\n", Status); + goto Quit; + } + + if (kvInfo->Type != REG_SZ || kvInfo->DataLength == 0 || kvInfo->DataLength > MAXUSHORT) + { + DPRINT1("Wrong or empty instance value\n"); + Status = STATUS_INVALID_PARAMETER; + goto Quit; + } + + /* Convert received data to unicode string */ + Buffer = (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset); + PnpRegSzToString(Buffer, kvInfo->DataLength, &DeviceString.Length); + DeviceString.MaximumLength = DeviceString.Length; + DeviceString.Buffer = Buffer; + + /* + * Separate symbolic link into 4 parts: + * 1) prefix string (\??\ for kernel mode or \\?\ for user mode), + * 2) munged path string (like ##?#ACPI#PNP0501#1#{GUID}), + * 3) GUID string (the current GUID), + * 4) reference string (goes after GUID, starts with '\'). + * + * We need only reference string. + */ + Status = IopSeparateSymbolicLink(SymbolicLinkName, + NULL, + NULL, + NULL, + &ReferenceString, + &ReferenceStringPresent, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to separate symbolic link %wZ, Status 0x%08lx\n", SymbolicLinkName, Status); + goto Quit; + } + + DPRINT("Device string is '%wZ'\n", &DeviceString); + + /* Does symbolic link have kernel mode "\??\" or user mode "\\?\" prefix format? */ + UserModePrefixFormat = RtlPrefixUnicodeString(&UserModePrefix, SymbolicLinkName, FALSE); + + /* Build up new symbolic link with alias GUID */ + Status = IopBuildSymbolicLink(&DeviceString, + &AliasGuidString, + ReferenceStringPresent ? &ReferenceString : NULL, + UserModePrefixFormat, + &AliasSymbolicLink); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to build alias symbolic link, Status 0x%08lx\n", Status); + goto Quit; + } + + /* Make sure that alias symbolic link key exists in registry */ + Status = OpenRegistryHandlesFromSymbolicLink(&AliasSymbolicLink, + KEY_READ, + NULL, + NULL, + &AliasInstanceKey); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to open alias symbolic link key, Status 0x%08lx\n", Status); + goto Quit; + } + ZwClose(AliasInstanceKey); + + /* We're done */ + DPRINT("IoGetDeviceInterfaceAlias(): alias symbolic link %wZ\n", &AliasSymbolicLink); + *AliasSymbolicLinkName = AliasSymbolicLink; + Status = STATUS_SUCCESS; + +Quit: + if (!NT_SUCCESS(Status)) + { + if (AliasSymbolicLink.Buffer) + RtlFreeUnicodeString(&AliasSymbolicLink); + } + + if (AliasGuidString.Buffer) + RtlFreeUnicodeString(&AliasGuidString); + + return Status; +} + /*++ * @name IoGetDeviceInterfaces * @implemented diff --git a/ntoskrnl/io/iomgr/file.c b/ntoskrnl/io/iomgr/file.c index bfe11ab295b50..865cd52fc789f 100644 --- a/ntoskrnl/io/iomgr/file.c +++ b/ntoskrnl/io/iomgr/file.c @@ -2108,10 +2108,11 @@ IopQueryNameInternal(IN PVOID ObjectBody, _SEH2_LEAVE; } - /* In such case, zero output */ + /* In such case, zero the output and reset the status */ LocalReturnLength = FIELD_OFFSET(FILE_NAME_INFORMATION, FileName); LocalFileInfo->FileNameLength = 0; LocalFileInfo->FileName[0] = OBJ_NAME_PATH_SEPARATOR; + Status = STATUS_SUCCESS; } else { diff --git a/ntoskrnl/io/iomgr/iofunc.c b/ntoskrnl/io/iomgr/iofunc.c index f672f4b5af69d..64b692ea2aab2 100644 --- a/ntoskrnl/io/iomgr/iofunc.c +++ b/ntoskrnl/io/iomgr/iofunc.c @@ -295,7 +295,7 @@ IopDeviceFsIoControl(IN HANDLE DeviceHandle, return STATUS_INVALID_PARAMETER; } - /* Check if we from user mode */ + /* Check if we came from user mode */ if (PreviousMode != KernelMode) { /* Get the access mask */ @@ -529,7 +529,7 @@ IopDeviceFsIoControl(IN HANDLE DeviceHandle, Irp->AssociatedIrp.SystemBuffer = ExAllocatePoolWithQuotaTag(PoolType, BufferLength, - TAG_SYS_BUF); + TAG_IOBUF); /* Check if we got a buffer */ if (InputBuffer) @@ -576,7 +576,7 @@ IopDeviceFsIoControl(IN HANDLE DeviceHandle, Irp->AssociatedIrp.SystemBuffer = ExAllocatePoolWithQuotaTag(PoolType, InputBufferLength, - TAG_SYS_BUF); + TAG_IOBUF); /* Copy into the System Buffer */ RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, @@ -2047,7 +2047,7 @@ NtQueryDirectoryFile(IN HANDLE FileHandle, AuxBuffer = ExAllocatePoolWithTag(NonPagedPool, CapturedFileName.Length + sizeof(UNICODE_STRING), - TAG_SYSB); + TAG_IOBUF); RtlCopyMemory((PVOID)((ULONG_PTR)AuxBuffer + sizeof(UNICODE_STRING)), CapturedFileName.Buffer, @@ -2064,7 +2064,7 @@ NtQueryDirectoryFile(IN HANDLE FileHandle, _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { /* Free buffer and return the exception code */ - if (AuxBuffer) ExFreePoolWithTag(AuxBuffer, TAG_SYSB); + if (AuxBuffer) ExFreePoolWithTag(AuxBuffer, TAG_IOBUF); _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; @@ -2100,7 +2100,7 @@ NtQueryDirectoryFile(IN HANDLE FileHandle, if (!NT_SUCCESS(Status)) { /* Fail */ - if (AuxBuffer) ExFreePoolWithTag(AuxBuffer, TAG_SYSB); + if (AuxBuffer) ExFreePoolWithTag(AuxBuffer, TAG_IOBUF); return Status; } @@ -2108,7 +2108,7 @@ NtQueryDirectoryFile(IN HANDLE FileHandle, if (FileObject->CompletionContext != NULL && ApcRoutine != NULL) { ObDereferenceObject(FileObject); - if (AuxBuffer) ExFreePoolWithTag(AuxBuffer, TAG_SYSB); + if (AuxBuffer) ExFreePoolWithTag(AuxBuffer, TAG_IOBUF); return STATUS_INVALID_PARAMETER; } @@ -2125,7 +2125,7 @@ NtQueryDirectoryFile(IN HANDLE FileHandle, if (!NT_SUCCESS(Status)) { /* Fail */ - if (AuxBuffer) ExFreePoolWithTag(AuxBuffer, TAG_SYSB); + if (AuxBuffer) ExFreePoolWithTag(AuxBuffer, TAG_IOBUF); ObDereferenceObject(FileObject); return Status; } @@ -2143,7 +2143,7 @@ NtQueryDirectoryFile(IN HANDLE FileHandle, { if (Event) ObDereferenceObject(Event); ObDereferenceObject(FileObject); - if (AuxBuffer) ExFreePoolWithTag(AuxBuffer, TAG_SYSB); + if (AuxBuffer) ExFreePoolWithTag(AuxBuffer, TAG_IOBUF); return Status; } @@ -2181,13 +2181,13 @@ NtQueryDirectoryFile(IN HANDLE FileHandle, { /* Allocate a buffer */ Irp->AssociatedIrp.SystemBuffer = - ExAllocatePoolWithQuotaTag(NonPagedPool, Length, TAG_SYSB); + ExAllocatePoolWithQuotaTag(NonPagedPool, Length, TAG_IOBUF); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { /* Allocating failed, clean up and return the exception code */ IopCleanupAfterException(FileObject, Irp, Event, NULL); - if (AuxBuffer) ExFreePoolWithTag(AuxBuffer, TAG_SYSB); + if (AuxBuffer) ExFreePoolWithTag(AuxBuffer, TAG_IOBUF); /* Return the exception code */ return _SEH2_GetExceptionCode(); @@ -2517,7 +2517,7 @@ NtQueryInformationFile(IN HANDLE FileHandle, { /* Allocate a buffer */ Irp->AssociatedIrp.SystemBuffer = - ExAllocatePoolWithQuotaTag(NonPagedPool, Length, TAG_SYSB); + ExAllocatePoolWithQuotaTag(NonPagedPool, Length, TAG_IOBUF); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { @@ -2985,7 +2985,7 @@ NtReadFile(IN HANDLE FileHandle, { /* Allocate a buffer */ Irp->AssociatedIrp.SystemBuffer = - ExAllocatePoolWithQuotaTag(NonPagedPool, Length, TAG_SYSB); + ExAllocatePoolWithQuotaTag(NonPagedPool, Length, TAG_IOBUF); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { @@ -3286,7 +3286,7 @@ NtSetInformationFile(IN HANDLE FileHandle, { /* Allocate a buffer */ Irp->AssociatedIrp.SystemBuffer = - ExAllocatePoolWithQuotaTag(NonPagedPool, Length, TAG_SYSB); + ExAllocatePoolWithQuotaTag(NonPagedPool, Length, TAG_IOBUF); /* Copy the data into it */ RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, @@ -4058,7 +4058,7 @@ NtWriteFile(IN HANDLE FileHandle, { /* Allocate a buffer */ Irp->AssociatedIrp.SystemBuffer = - ExAllocatePoolWithQuotaTag(NonPagedPool, Length, TAG_SYSB); + ExAllocatePoolWithQuotaTag(NonPagedPool, Length, TAG_IOBUF); /* Copy the data into it */ RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, Buffer, Length); @@ -4385,7 +4385,7 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle, { /* Allocate a buffer */ Irp->AssociatedIrp.SystemBuffer = - ExAllocatePoolWithQuotaTag(NonPagedPool, Length, TAG_SYSB); + ExAllocatePoolWithQuotaTag(NonPagedPool, Length, TAG_IOBUF); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { @@ -4566,7 +4566,7 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle, { /* Allocate a buffer */ Irp->AssociatedIrp.SystemBuffer = - ExAllocatePoolWithQuotaTag(NonPagedPool, Length, TAG_SYSB); + ExAllocatePoolWithQuotaTag(NonPagedPool, Length, TAG_IOBUF); /* Copy the data into it */ RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, FsInformation, Length); diff --git a/ntoskrnl/io/iomgr/iomgr.c b/ntoskrnl/io/iomgr/iomgr.c index b982414e27007..249d93b6cae92 100644 --- a/ntoskrnl/io/iomgr/iomgr.c +++ b/ntoskrnl/io/iomgr/iomgr.c @@ -43,6 +43,7 @@ LARGE_INTEGER IoWriteTransferCount = {{0, 0}}; ULONG IoOtherOperationCount = 0; LARGE_INTEGER IoOtherTransferCount = {{0, 0}}; KSPIN_LOCK IoStatisticsLock = 0; +ULONG IopAutoReboot; ULONG IopNumTriageDumpDataBlocks; PVOID IopTriageDumpDataBlocks[64]; diff --git a/ntoskrnl/io/iomgr/irp.c b/ntoskrnl/io/iomgr/irp.c index 2de843975e01a..cbd85f4e607bd 100644 --- a/ntoskrnl/io/iomgr/irp.c +++ b/ntoskrnl/io/iomgr/irp.c @@ -210,7 +210,7 @@ IopCleanupIrp(IN PIRP Irp, if (Irp->Flags & IRP_DEALLOCATE_BUFFER) { /* Free the buffer */ - ExFreePoolWithTag(Irp->AssociatedIrp.SystemBuffer, TAG_SYS_BUF); + ExFreePoolWithTag(Irp->AssociatedIrp.SystemBuffer, TAG_IOBUF); } /* Check if this IRP has a user event, a file object, and is async */ @@ -233,6 +233,56 @@ IopCleanupIrp(IN PIRP Irp, IoFreeIrp(Irp); } +static +VOID +IopWriteAsyncUserIosb(PIRP Irp) +{ +#ifdef _WIN64 + PIO_STATUS_BLOCK32 Iosb32 = NULL; +#endif + + /* Check for UserIos */ + if (Irp->UserIosb != NULL) + { + /* Use SEH to make sure we don't write somewhere invalid */ + _SEH2_TRY + { +#ifdef _WIN64 + Iosb32 = (PIO_STATUS_BLOCK32)Irp->UserIosb->Pointer; + + /* + * If this is a 32-bit process, and UserIosb falls within the + * 32-bit address space, assume it is a 32-bit IOSB that has + * to be filled. + */ + if (Irp->RequestorMode == UserMode && + /* + * This is an APC - we're running in the correct thread context, + * and Irp->Tail is trashed. Don't bother with getting the thread + * from the IRP then. The process mode still should be checked. + */ + IoIs32bitProcess(NULL) && + Iosb32 != NULL && (PVOID)Iosb32 <= (PVOID)0xFFFFFFFFULL) + { + InterlockedExchangePointer(&Irp->UserIosb->Pointer, NULL); + + Iosb32->Information = Irp->IoStatus.Information; + Iosb32->Status = Irp->IoStatus.Status; + } + else +#endif + { + *Irp->UserIosb = Irp->IoStatus; + } + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Ignore any error */ + } + _SEH2_END; + } +} + VOID NTAPI IopCompleteRequest(IN PKAPC Apc, @@ -340,21 +390,7 @@ IopCompleteRequest(IN PKAPC Apc, Key = FileObject->CompletionContext->Key; } - /* Check for UserIos */ - if (Irp->UserIosb != NULL) - { - /* Use SEH to make sure we don't write somewhere invalid */ - _SEH2_TRY - { - /* Save the IOSB Information */ - *Irp->UserIosb = Irp->IoStatus; - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - /* Ignore any error */ - } - _SEH2_END; - } + IopWriteAsyncUserIosb(Irp); /* Check if we have an event or a file object */ if (Irp->UserEvent) @@ -778,7 +814,7 @@ IoBuildAsynchronousFsdRequest(IN ULONG MajorFunction, { /* Allocate the System Buffer */ Irp->AssociatedIrp.SystemBuffer = - ExAllocatePoolWithTag(NonPagedPool, Length, TAG_SYS_BUF); + ExAllocatePoolWithTag(NonPagedPool, Length, TAG_IOBUF); if (!Irp->AssociatedIrp.SystemBuffer) { /* Free the IRP and fail */ @@ -927,7 +963,7 @@ IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, Irp->AssociatedIrp.SystemBuffer = ExAllocatePoolWithTag(NonPagedPool, BufferLength, - TAG_SYS_BUF); + TAG_IOBUF); if (!Irp->AssociatedIrp.SystemBuffer) { /* Free the IRP and fail */ @@ -970,7 +1006,7 @@ IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, Irp->AssociatedIrp.SystemBuffer = ExAllocatePoolWithTag(NonPagedPool, InputBufferLength, - TAG_SYS_BUF); + TAG_IOBUF); if (!Irp->AssociatedIrp.SystemBuffer) { /* Free the IRP and fail */ @@ -2004,12 +2040,43 @@ IoSetTopLevelIrp(IN PIRP Irp) } #if defined (_WIN64) +/* + * @implemented + */ BOOLEAN NTAPI -IoIs32bitProcess( - IN PIRP Irp OPTIONAL) +IoIs32bitProcess(IN PIRP Irp OPTIONAL) { - UNIMPLEMENTED; - return FALSE; + PETHREAD pThread, pCurrentThread; + PEPROCESS pProcess; + + pCurrentThread = CONTAINING_RECORD(KeGetCurrentThread(), ETHREAD, Tcb); + + if (Irp == NULL) + { + pThread = pCurrentThread; + } + else + { + /* If it's a kernel mode IRP, it could not have originated from WOW64 */ + if (Irp->RequestorMode == KernelMode || + (PVOID)Irp->UserIosb > MmHighestUserAddress) + { + return FALSE; + } + + pThread = Irp->Tail.Overlay.Thread; + } + + pProcess = CONTAINING_RECORD(pThread->Tcb.Process, EPROCESS, Pcb); + + /* FIXME: A two-part hack: delay setting Process->Wow64Process, so 64-bit + NTDLL can use IO to init stuff. */ + if (pProcess->Wow64Process == (PVOID)TRUE) + { + return FALSE; + } + + return pProcess->Wow64Process != NULL; } #endif diff --git a/ntoskrnl/io/iomgr/irq.c b/ntoskrnl/io/iomgr/irq.c index 6e09f6b196e33..aaaea556760b9 100644 --- a/ntoskrnl/io/iomgr/irq.c +++ b/ntoskrnl/io/iomgr/irq.c @@ -60,7 +60,7 @@ IoConnectInterrupt(OUT PKINTERRUPT *InterruptObject, IoInterrupt = ExAllocatePoolZero(NonPagedPool, (Count - 1) * sizeof(KINTERRUPT) + sizeof(IO_INTERRUPT), - TAG_KINTERRUPT); + TAG_IO_INTERRUPT); if (!IoInterrupt) return STATUS_INSUFFICIENT_RESOURCES; /* Use the structure's spinlock, if none was provided */ @@ -105,7 +105,7 @@ IoConnectInterrupt(OUT PKINTERRUPT *InterruptObject, if (FirstRun) { /* We failed early so just free this */ - ExFreePoolWithTag(IoInterrupt, TAG_KINTERRUPT); + ExFreePoolWithTag(IoInterrupt, TAG_IO_INTERRUPT); } else { @@ -166,7 +166,7 @@ IoDisconnectInterrupt(PKINTERRUPT InterruptObject) } /* Free the I/O interrupt */ - ExFreePoolWithTag(IoInterrupt, TAG_KINTERRUPT); + ExFreePoolWithTag(IoInterrupt, TAG_IO_INTERRUPT); } NTSTATUS @@ -189,7 +189,8 @@ IopConnectInterruptExFullySpecific( Parameters->FullySpecified.ShareVector, Parameters->FullySpecified.ProcessorEnableMask, Parameters->FullySpecified.FloatingSave); - DPRINT("IopConnectInterruptEx_FullySpecific: has failed with status %X", Status); + if (!NT_SUCCESS(Status)) + DPRINT1("IopConnectInterruptExFullySpecific() failed: 0x%lx\n", Status); return Status; } diff --git a/ntoskrnl/io/iomgr/volume.c b/ntoskrnl/io/iomgr/volume.c index 024823636f5f4..f5164fe412b3e 100644 --- a/ntoskrnl/io/iomgr/volume.c +++ b/ntoskrnl/io/iomgr/volume.c @@ -9,13 +9,13 @@ * Pierre Schweitzer (pierre.schweitzer@reactos.org) */ -/* INCLUDES *****************************************************************/ +/* INCLUDES ******************************************************************/ #include #define NDEBUG #include -/* GLOBALS ******************************************************************/ +/* GLOBALS *******************************************************************/ ERESOURCE IopDatabaseResource; LIST_ENTRY IopDiskFileSystemQueueHead, IopNetworkFileSystemQueueHead; @@ -1097,7 +1097,7 @@ IoRegisterFsRegistrationChange(IN PDRIVER_OBJECT DriverObject, ExAcquireResourceExclusiveLite(&IopDatabaseResource, TRUE); /* Check if that driver is already registered (successive calls) - * See MSDN note: http://msdn.microsoft.com/en-us/library/ff548499%28v=vs.85%29.aspx + * See MSDN note: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-ioregisterfsregistrationchange */ if (!IsListEmpty(&IopFsNotifyChangeQueueHead)) { @@ -1276,13 +1276,15 @@ IoSetSystemPartition(IN PUNICODE_STRING VolumeNameString) */ NTSTATUS NTAPI -IoVolumeDeviceToDosName(IN PVOID VolumeDeviceObject, - OUT PUNICODE_STRING DosName) +IoVolumeDeviceToDosName( + _In_ PVOID VolumeDeviceObject, + _Out_ _When_(return==0, _At_(DosName->Buffer, __drv_allocatesMem(Mem))) + PUNICODE_STRING DosName) { - PIRP Irp; + NTSTATUS Status; ULONG Length; KEVENT Event; - NTSTATUS Status; + PIRP Irp; PFILE_OBJECT FileObject; PDEVICE_OBJECT DeviceObject; IO_STATUS_BLOCK IoStatusBlock; @@ -1290,10 +1292,10 @@ IoVolumeDeviceToDosName(IN PVOID VolumeDeviceObject, MOUNTMGR_VOLUME_PATHS VolumePath; PMOUNTMGR_VOLUME_PATHS VolumePathPtr; /* - * This variable with be required to query device name. + * This variable is used to query the device name. * It's based on MOUNTDEV_NAME (mountmgr.h). - * Doing it that way will prevent dyn memory allocation. - * Device name won't be longer. + * Doing it this way prevents memory allocation. + * The device name won't be longer. */ struct { @@ -1303,10 +1305,11 @@ IoVolumeDeviceToDosName(IN PVOID VolumeDeviceObject, PAGED_CODE(); - /* First step, getting device name */ + /* First, retrieve the corresponding device name */ KeInitializeEvent(&Event, NotificationEvent, FALSE); Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, - VolumeDeviceObject, NULL, 0, + VolumeDeviceObject, + NULL, 0, &DeviceName, sizeof(DeviceName), FALSE, &Event, &IoStatusBlock); if (!Irp) @@ -1320,15 +1323,12 @@ IoVolumeDeviceToDosName(IN PVOID VolumeDeviceObject, KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); Status = IoStatusBlock.Status; } - if (!NT_SUCCESS(Status)) { return Status; } - /* Now that we have the device name, we can query the MountMgr - * So, get its device object first. - */ + /* Retrieve the MountMgr controlling device */ RtlInitUnicodeString(&MountMgrDevice, MOUNTMGR_DEVICE_NAME); Status = IoGetDeviceObjectPointer(&MountMgrDevice, FILE_READ_ATTRIBUTES, &FileObject, &DeviceObject); @@ -1337,16 +1337,17 @@ IoVolumeDeviceToDosName(IN PVOID VolumeDeviceObject, return Status; } - /* Then, use the proper IOCTL to query the DOS name */ + /* Now, query the MountMgr for the DOS path */ KeInitializeEvent(&Event, NotificationEvent, FALSE); Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH, - DeviceObject, &DeviceName, sizeof(DeviceName), + DeviceObject, + &DeviceName, sizeof(DeviceName), &VolumePath, sizeof(VolumePath), FALSE, &Event, &IoStatusBlock); if (!Irp) { Status = STATUS_INSUFFICIENT_RESOURCES; - goto DereferenceFO; + goto Quit; } Status = IoCallDriver(DeviceObject, Irp); @@ -1356,41 +1357,37 @@ IoVolumeDeviceToDosName(IN PVOID VolumeDeviceObject, Status = IoStatusBlock.Status; } - /* Only tolerated failure here is buffer too small, which is - * expected. - */ - if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW) + /* The only tolerated failure here is buffer too small, which is expected */ + if (!NT_SUCCESS(Status) && (Status != STATUS_BUFFER_OVERFLOW)) { - goto DereferenceFO; + goto Quit; } - /* Compute needed size to store DOS name. - * Even if MOUNTMGR_VOLUME_PATHS allows bigger - * name lengths than MAXUSHORT, we can't use - * them, because we have to return this in an UNICODE_STRING - * that stores length on USHORT. - */ - Length = VolumePath.MultiSzLength + sizeof(VolumePath); + /* Compute the needed size to store the DOS path. + * Even if MOUNTMGR_VOLUME_PATHS allows bigger name lengths + * than MAXUSHORT, we can't use them, because we have to return + * this in an UNICODE_STRING that stores length in a USHORT. */ + Length = FIELD_OFFSET(MOUNTMGR_VOLUME_PATHS, MultiSz) + VolumePath.MultiSzLength; if (Length > MAXUSHORT) { Status = STATUS_INVALID_BUFFER_SIZE; - goto DereferenceFO; + goto Quit; } - /* Reallocate memory, even in case of success, because - * that's the buffer that will be returned to caller - */ - VolumePathPtr = ExAllocatePoolWithTag(PagedPool, Length, 'D2d '); + /* Allocate the buffer, even in case of success, + * because it is returned to the caller */ + VolumePathPtr = ExAllocatePoolWithTag(PagedPool, Length, TAG_DEV2DOS); if (!VolumePathPtr) { Status = STATUS_INSUFFICIENT_RESOURCES; - goto DereferenceFO; + goto Quit; } - /* Requery DOS path with proper size */ + /* Re-query the DOS path with the proper size */ KeInitializeEvent(&Event, NotificationEvent, FALSE); Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH, - DeviceObject, &DeviceName, sizeof(DeviceName), + DeviceObject, + &DeviceName, sizeof(DeviceName), VolumePathPtr, Length, FALSE, &Event, &IoStatusBlock); if (!Irp) @@ -1405,31 +1402,30 @@ IoVolumeDeviceToDosName(IN PVOID VolumeDeviceObject, KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); Status = IoStatusBlock.Status; } - if (!NT_SUCCESS(Status)) { goto ReleaseMemory; } - /* Set output string */ - DosName->Length = (USHORT)VolumePathPtr->MultiSzLength; - DosName->MaximumLength = (USHORT)VolumePathPtr->MultiSzLength + sizeof(UNICODE_NULL); - /* Our MOUNTMGR_VOLUME_PATHS will be used as output buffer */ + /* Set the output string. Discount the last two + * NUL-terminators from the multi-string length. */ + DosName->Length = (USHORT)VolumePathPtr->MultiSzLength - 2 * sizeof(UNICODE_NULL); + DosName->MaximumLength = DosName->Length + sizeof(UNICODE_NULL); + /* Recycle our MOUNTMGR_VOLUME_PATHS as the output buffer + * and move the NUL-terminated string to the beginning */ DosName->Buffer = (PWSTR)VolumePathPtr; - /* Move name at the begin, RtlMoveMemory is OK with overlapping */ - RtlMoveMemory(DosName->Buffer, VolumePathPtr->MultiSz, VolumePathPtr->MultiSzLength); + RtlMoveMemory(DosName->Buffer, VolumePathPtr->MultiSz, DosName->Length); DosName->Buffer[DosName->Length / sizeof(WCHAR)] = UNICODE_NULL; - /* DON'T release buffer, just dereference FO, and return success */ + /* Don't release the buffer, just dereference the FO and return success */ Status = STATUS_SUCCESS; - goto DereferenceFO; + goto Quit; ReleaseMemory: - ExFreePoolWithTag(VolumePathPtr, 'D2d '); + ExFreePoolWithTag(VolumePathPtr, TAG_DEV2DOS); -DereferenceFO: +Quit: ObDereferenceObject(FileObject); - return Status; } diff --git a/ntoskrnl/kd/kd.h b/ntoskrnl/kd/kd.h index 0e10f0c90b037..639b1edfa2bd7 100644 --- a/ntoskrnl/kd/kd.h +++ b/ntoskrnl/kd/kd.h @@ -83,11 +83,15 @@ KdpDebugLogInit( #define DEFAULT_DEBUG_BAUD_RATE 115200 /* 115200 Baud */ /* KD Native Modes */ -#define KdScreen 0 -#define KdSerial 1 -#define KdFile 2 -#define KdKdbg 3 +// #define KdScreen 0 +// #define KdSerial 1 +// #define KdFile 2 +#ifdef KDBG +// #define KdKdbg 3 #define KdMax 4 +#else +#define KdMax 3 +#endif /* KD Private Debug Modes */ typedef struct _KDP_DEBUG_MODE diff --git a/ntoskrnl/kd64/amd64/kdx64.c b/ntoskrnl/kd64/amd64/kdx64.c index 5c6871d3a9e99..c19505f634a94 100644 --- a/ntoskrnl/kd64/amd64/kdx64.c +++ b/ntoskrnl/kd64/amd64/kdx64.c @@ -93,13 +93,14 @@ KdpSetContextState(IN PDBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange, NTSTATUS NTAPI -KdpSysReadMsr(IN ULONG Msr, - OUT PLARGE_INTEGER MsrValue) +KdpSysReadMsr( + _In_ ULONG Msr, + _Out_ PULONGLONG MsrValue) { /* Use SEH to protect from invalid MSRs */ _SEH2_TRY { - MsrValue->QuadPart = __readmsr(Msr); + *MsrValue = __readmsr(Msr); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { @@ -112,13 +113,14 @@ KdpSysReadMsr(IN ULONG Msr, NTSTATUS NTAPI -KdpSysWriteMsr(IN ULONG Msr, - IN PLARGE_INTEGER MsrValue) +KdpSysWriteMsr( + _In_ ULONG Msr, + _In_ PULONGLONG MsrValue) { /* Use SEH to protect from invalid MSRs */ _SEH2_TRY { - __writemsr(Msr, MsrValue->QuadPart); + __writemsr(Msr, *MsrValue); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { @@ -131,13 +133,14 @@ KdpSysWriteMsr(IN ULONG Msr, NTSTATUS NTAPI -KdpSysReadBusData(IN ULONG BusDataType, - IN ULONG BusNumber, - IN ULONG SlotNumber, - IN ULONG Offset, - IN PVOID Buffer, - IN ULONG Length, - OUT PULONG ActualLength) +KdpSysReadBusData( + _In_ BUS_DATA_TYPE BusDataType, + _In_ ULONG BusNumber, + _In_ ULONG SlotNumber, + _In_ ULONG Offset, + _Out_writes_bytes_(Length) PVOID Buffer, + _In_ ULONG Length, + _Out_ PULONG ActualLength) { UNIMPLEMENTED; return STATUS_UNSUCCESSFUL; @@ -145,13 +148,14 @@ KdpSysReadBusData(IN ULONG BusDataType, NTSTATUS NTAPI -KdpSysWriteBusData(IN ULONG BusDataType, - IN ULONG BusNumber, - IN ULONG SlotNumber, - IN ULONG Offset, - IN PVOID Buffer, - IN ULONG Length, - OUT PULONG ActualLength) +KdpSysWriteBusData( + _In_ BUS_DATA_TYPE BusDataType, + _In_ ULONG BusNumber, + _In_ ULONG SlotNumber, + _In_ ULONG Offset, + _In_reads_bytes_(Length) PVOID Buffer, + _In_ ULONG Length, + _Out_ PULONG ActualLength) { UNIMPLEMENTED; return STATUS_UNSUCCESSFUL; @@ -159,11 +163,12 @@ KdpSysWriteBusData(IN ULONG BusDataType, NTSTATUS NTAPI -KdpSysReadControlSpace(IN ULONG Processor, - IN ULONG64 BaseAddress, - IN PVOID Buffer, - IN ULONG Length, - OUT PULONG ActualLength) +KdpSysReadControlSpace( + _In_ ULONG Processor, + _In_ ULONG64 BaseAddress, + _Out_writes_bytes_(Length) PVOID Buffer, + _In_ ULONG Length, + _Out_ PULONG ActualLength) { PVOID ControlStart; PKPRCB Prcb = KiProcessorBlock[Processor]; @@ -210,11 +215,12 @@ KdpSysReadControlSpace(IN ULONG Processor, NTSTATUS NTAPI -KdpSysWriteControlSpace(IN ULONG Processor, - IN ULONG64 BaseAddress, - IN PVOID Buffer, - IN ULONG Length, - OUT PULONG ActualLength) +KdpSysWriteControlSpace( + _In_ ULONG Processor, + _In_ ULONG64 BaseAddress, + _In_reads_bytes_(Length) PVOID Buffer, + _In_ ULONG Length, + _Out_ PULONG ActualLength) { PVOID ControlStart; PKPRCB Prcb = KiProcessorBlock[Processor]; @@ -241,13 +247,14 @@ KdpSysWriteControlSpace(IN ULONG Processor, NTSTATUS NTAPI -KdpSysReadIoSpace(IN ULONG InterfaceType, - IN ULONG BusNumber, - IN ULONG AddressSpace, - IN ULONG64 IoAddress, - OUT PVOID DataValue, - IN ULONG DataSize, - OUT PULONG ActualDataSize) +KdpSysReadIoSpace( + _In_ INTERFACE_TYPE InterfaceType, + _In_ ULONG BusNumber, + _In_ ULONG AddressSpace, + _In_ ULONG64 IoAddress, + _Out_writes_bytes_(DataSize) PVOID DataValue, + _In_ ULONG DataSize, + _Out_ PULONG ActualDataSize) { /* Verify parameters */ if (InterfaceType != Isa || BusNumber != 0 || AddressSpace != 1) @@ -297,13 +304,14 @@ KdpSysReadIoSpace(IN ULONG InterfaceType, NTSTATUS NTAPI -KdpSysWriteIoSpace(IN ULONG InterfaceType, - IN ULONG BusNumber, - IN ULONG AddressSpace, - IN ULONG64 IoAddress, - IN PVOID DataValue, - IN ULONG DataSize, - OUT PULONG ActualDataSize) +KdpSysWriteIoSpace( + _In_ INTERFACE_TYPE InterfaceType, + _In_ ULONG BusNumber, + _In_ ULONG AddressSpace, + _In_ ULONG64 IoAddress, + _In_reads_bytes_(DataSize) PVOID DataValue, + _In_ ULONG DataSize, + _Out_ PULONG ActualDataSize) { /* Verify parameters */ if (InterfaceType != Isa || BusNumber != 0 || AddressSpace != 1) diff --git a/ntoskrnl/kd64/arm/kdarm.c b/ntoskrnl/kd64/arm/kdarm.c index a62956d1065ac..5a8674046a04c 100644 --- a/ntoskrnl/kd64/arm/kdarm.c +++ b/ntoskrnl/kd64/arm/kdarm.c @@ -35,8 +35,9 @@ KdpSetContextState(IN PDBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange, NTSTATUS NTAPI -KdpSysReadMsr(IN ULONG Msr, - OUT PLARGE_INTEGER MsrValue) +KdpSysReadMsr( + _In_ ULONG Msr, + _Out_ PULONGLONG MsrValue) { UNIMPLEMENTED; return STATUS_UNSUCCESSFUL; @@ -44,8 +45,9 @@ KdpSysReadMsr(IN ULONG Msr, NTSTATUS NTAPI -KdpSysWriteMsr(IN ULONG Msr, - IN PLARGE_INTEGER MsrValue) +KdpSysWriteMsr( + _In_ ULONG Msr, + _In_ PULONGLONG MsrValue) { UNIMPLEMENTED; return STATUS_UNSUCCESSFUL; @@ -53,13 +55,14 @@ KdpSysWriteMsr(IN ULONG Msr, NTSTATUS NTAPI -KdpSysReadBusData(IN ULONG BusDataType, - IN ULONG BusNumber, - IN ULONG SlotNumber, - IN ULONG Offset, - IN PVOID Buffer, - IN ULONG Length, - OUT PULONG ActualLength) +KdpSysReadBusData( + _In_ BUS_DATA_TYPE BusDataType, + _In_ ULONG BusNumber, + _In_ ULONG SlotNumber, + _In_ ULONG Offset, + _Out_writes_bytes_(Length) PVOID Buffer, + _In_ ULONG Length, + _Out_ PULONG ActualLength) { UNIMPLEMENTED; return STATUS_UNSUCCESSFUL; @@ -67,13 +70,14 @@ KdpSysReadBusData(IN ULONG BusDataType, NTSTATUS NTAPI -KdpSysWriteBusData(IN ULONG BusDataType, - IN ULONG BusNumber, - IN ULONG SlotNumber, - IN ULONG Offset, - IN PVOID Buffer, - IN ULONG Length, - OUT PULONG ActualLength) +KdpSysWriteBusData( + _In_ BUS_DATA_TYPE BusDataType, + _In_ ULONG BusNumber, + _In_ ULONG SlotNumber, + _In_ ULONG Offset, + _In_reads_bytes_(Length) PVOID Buffer, + _In_ ULONG Length, + _Out_ PULONG ActualLength) { UNIMPLEMENTED; return STATUS_UNSUCCESSFUL; @@ -81,11 +85,12 @@ KdpSysWriteBusData(IN ULONG BusDataType, NTSTATUS NTAPI -KdpSysReadControlSpace(IN ULONG Processor, - IN ULONG64 BaseAddress, - IN PVOID Buffer, - IN ULONG Length, - OUT PULONG ActualLength) +KdpSysReadControlSpace( + _In_ ULONG Processor, + _In_ ULONG64 BaseAddress, + _Out_writes_bytes_(Length) PVOID Buffer, + _In_ ULONG Length, + _Out_ PULONG ActualLength) { UNIMPLEMENTED; return STATUS_UNSUCCESSFUL; @@ -93,11 +98,12 @@ KdpSysReadControlSpace(IN ULONG Processor, NTSTATUS NTAPI -KdpSysWriteControlSpace(IN ULONG Processor, - IN ULONG64 BaseAddress, - IN PVOID Buffer, - IN ULONG Length, - OUT PULONG ActualLength) +KdpSysWriteControlSpace( + _In_ ULONG Processor, + _In_ ULONG64 BaseAddress, + _In_reads_bytes_(Length) PVOID Buffer, + _In_ ULONG Length, + _Out_ PULONG ActualLength) { UNIMPLEMENTED; return STATUS_UNSUCCESSFUL; @@ -105,13 +111,14 @@ KdpSysWriteControlSpace(IN ULONG Processor, NTSTATUS NTAPI -KdpSysReadIoSpace(IN ULONG InterfaceType, - IN ULONG BusNumber, - IN ULONG AddressSpace, - IN ULONG64 IoAddress, - IN PVOID DataValue, - IN ULONG DataSize, - OUT PULONG ActualDataSize) +KdpSysReadIoSpace( + _In_ INTERFACE_TYPE InterfaceType, + _In_ ULONG BusNumber, + _In_ ULONG AddressSpace, + _In_ ULONG64 IoAddress, + _Out_writes_bytes_(DataSize) PVOID DataValue, + _In_ ULONG DataSize, + _Out_ PULONG ActualDataSize) { UNIMPLEMENTED; return STATUS_UNSUCCESSFUL; @@ -119,13 +126,14 @@ KdpSysReadIoSpace(IN ULONG InterfaceType, NTSTATUS NTAPI -KdpSysWriteIoSpace(IN ULONG InterfaceType, - IN ULONG BusNumber, - IN ULONG AddressSpace, - IN ULONG64 IoAddress, - IN PVOID DataValue, - IN ULONG DataSize, - OUT PULONG ActualDataSize) +KdpSysWriteIoSpace( + _In_ INTERFACE_TYPE InterfaceType, + _In_ ULONG BusNumber, + _In_ ULONG AddressSpace, + _In_ ULONG64 IoAddress, + _In_reads_bytes_(DataSize) PVOID DataValue, + _In_ ULONG DataSize, + _Out_ PULONG ActualDataSize) { UNIMPLEMENTED; return STATUS_UNSUCCESSFUL; diff --git a/ntoskrnl/kd64/i386/kdx86.c b/ntoskrnl/kd64/i386/kdx86.c index 843f6e88b0d07..8fc77ebcf6e43 100644 --- a/ntoskrnl/kd64/i386/kdx86.c +++ b/ntoskrnl/kd64/i386/kdx86.c @@ -91,57 +91,54 @@ KdpSetContextState(IN PDBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange, NTSTATUS NTAPI -KdpSysReadMsr(IN ULONG Msr, - OUT PLARGE_INTEGER MsrValue) +KdpSysReadMsr( + _In_ ULONG Msr, + _Out_ PULONGLONG MsrValue) { - /* Wrap this in SEH in case the MSR doesn't exist */ + /* Use SEH to protect from invalid MSRs */ _SEH2_TRY { - /* Read from the MSR */ - MsrValue->QuadPart = __readmsr(Msr); + *MsrValue = __readmsr(Msr); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - /* Invalid MSR */ _SEH2_YIELD(return STATUS_NO_SUCH_DEVICE); } _SEH2_END; - /* Success */ return STATUS_SUCCESS; } NTSTATUS NTAPI -KdpSysWriteMsr(IN ULONG Msr, - IN PLARGE_INTEGER MsrValue) +KdpSysWriteMsr( + _In_ ULONG Msr, + _In_ PULONGLONG MsrValue) { - /* Wrap this in SEH in case the MSR doesn't exist */ + /* Use SEH to protect from invalid MSRs */ _SEH2_TRY { - /* Write to the MSR */ - __writemsr(Msr, MsrValue->QuadPart); + __writemsr(Msr, *MsrValue); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - /* Invalid MSR */ _SEH2_YIELD(return STATUS_NO_SUCH_DEVICE); } _SEH2_END; - /* Success */ return STATUS_SUCCESS; } NTSTATUS NTAPI -KdpSysReadBusData(IN ULONG BusDataType, - IN ULONG BusNumber, - IN ULONG SlotNumber, - IN ULONG Offset, - IN PVOID Buffer, - IN ULONG Length, - OUT PULONG ActualLength) +KdpSysReadBusData( + _In_ BUS_DATA_TYPE BusDataType, + _In_ ULONG BusNumber, + _In_ ULONG SlotNumber, + _In_ ULONG Offset, + _Out_writes_bytes_(Length) PVOID Buffer, + _In_ ULONG Length, + _Out_ PULONG ActualLength) { /* Just forward to HAL */ *ActualLength = HalGetBusDataByOffset(BusDataType, @@ -152,18 +149,19 @@ KdpSysReadBusData(IN ULONG BusDataType, Length); /* Return status */ - return *ActualLength != 0 ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL; + return (*ActualLength != 0 ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL); } NTSTATUS NTAPI -KdpSysWriteBusData(IN ULONG BusDataType, - IN ULONG BusNumber, - IN ULONG SlotNumber, - IN ULONG Offset, - IN PVOID Buffer, - IN ULONG Length, - OUT PULONG ActualLength) +KdpSysWriteBusData( + _In_ BUS_DATA_TYPE BusDataType, + _In_ ULONG BusNumber, + _In_ ULONG SlotNumber, + _In_ ULONG Offset, + _In_reads_bytes_(Length) PVOID Buffer, + _In_ ULONG Length, + _Out_ PULONG ActualLength) { /* Just forward to HAL */ *ActualLength = HalSetBusDataByOffset(BusDataType, @@ -174,16 +172,17 @@ KdpSysWriteBusData(IN ULONG BusDataType, Length); /* Return status */ - return *ActualLength != 0 ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL; + return (*ActualLength != 0 ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL); } NTSTATUS NTAPI -KdpSysReadControlSpace(IN ULONG Processor, - IN ULONG64 BaseAddress, - IN PVOID Buffer, - IN ULONG Length, - OUT PULONG ActualLength) +KdpSysReadControlSpace( + _In_ ULONG Processor, + _In_ ULONG64 BaseAddress, + _Out_writes_bytes_(Length) PVOID Buffer, + _In_ ULONG Length, + _Out_ PULONG ActualLength) { PVOID ControlStart; ULONG RealLength; @@ -219,11 +218,12 @@ KdpSysReadControlSpace(IN ULONG Processor, NTSTATUS NTAPI -KdpSysWriteControlSpace(IN ULONG Processor, - IN ULONG64 BaseAddress, - IN PVOID Buffer, - IN ULONG Length, - OUT PULONG ActualLength) +KdpSysWriteControlSpace( + _In_ ULONG Processor, + _In_ ULONG64 BaseAddress, + _In_reads_bytes_(Length) PVOID Buffer, + _In_ ULONG Length, + _Out_ PULONG ActualLength) { PVOID ControlStart; @@ -254,20 +254,19 @@ KdpSysWriteControlSpace(IN ULONG Processor, NTSTATUS NTAPI -KdpSysReadIoSpace(IN ULONG InterfaceType, - IN ULONG BusNumber, - IN ULONG AddressSpace, - IN ULONG64 IoAddress, - IN PVOID DataValue, - IN ULONG DataSize, - OUT PULONG ActualDataSize) +KdpSysReadIoSpace( + _In_ INTERFACE_TYPE InterfaceType, + _In_ ULONG BusNumber, + _In_ ULONG AddressSpace, + _In_ ULONG64 IoAddress, + _Out_writes_bytes_(DataSize) PVOID DataValue, + _In_ ULONG DataSize, + _Out_ PULONG ActualDataSize) { NTSTATUS Status; /* Verify parameters */ - if ((InterfaceType != Isa) || - (BusNumber != 0) || - (AddressSpace != 1)) + if ((InterfaceType != Isa) || (BusNumber != 0) || (AddressSpace != 1)) { /* Fail, we don't support this */ *ActualDataSize = 0; @@ -278,16 +277,17 @@ KdpSysReadIoSpace(IN ULONG InterfaceType, switch (DataSize) { case sizeof(UCHAR): - + { /* Read 1 byte */ *(PUCHAR)DataValue = READ_PORT_UCHAR((PUCHAR)(ULONG_PTR)IoAddress); *ActualDataSize = sizeof(UCHAR); Status = STATUS_SUCCESS; break; + } case sizeof(USHORT): - + { /* Make sure the address is aligned */ if ((IoAddress & (sizeof(USHORT) - 1)) != 0) { @@ -303,9 +303,10 @@ KdpSysReadIoSpace(IN ULONG InterfaceType, *ActualDataSize = sizeof(USHORT); Status = STATUS_SUCCESS; break; + } case sizeof(ULONG): - + { /* Make sure the address is aligned */ if ((IoAddress & (sizeof(ULONG) - 1)) != 0) { @@ -321,9 +322,9 @@ KdpSysReadIoSpace(IN ULONG InterfaceType, *ActualDataSize = sizeof(ULONG); Status = STATUS_SUCCESS; break; + } default: - /* Invalid size, fail */ *ActualDataSize = 0; Status = STATUS_INVALID_PARAMETER; @@ -335,20 +336,19 @@ KdpSysReadIoSpace(IN ULONG InterfaceType, NTSTATUS NTAPI -KdpSysWriteIoSpace(IN ULONG InterfaceType, - IN ULONG BusNumber, - IN ULONG AddressSpace, - IN ULONG64 IoAddress, - IN PVOID DataValue, - IN ULONG DataSize, - OUT PULONG ActualDataSize) +KdpSysWriteIoSpace( + _In_ INTERFACE_TYPE InterfaceType, + _In_ ULONG BusNumber, + _In_ ULONG AddressSpace, + _In_ ULONG64 IoAddress, + _In_reads_bytes_(DataSize) PVOID DataValue, + _In_ ULONG DataSize, + _Out_ PULONG ActualDataSize) { NTSTATUS Status; /* Verify parameters */ - if ((InterfaceType != Isa) || - (BusNumber != 0) || - (AddressSpace != 1)) + if ((InterfaceType != Isa) || (BusNumber != 0) || (AddressSpace != 1)) { /* Fail, we don't support this */ *ActualDataSize = 0; @@ -359,16 +359,17 @@ KdpSysWriteIoSpace(IN ULONG InterfaceType, switch (DataSize) { case sizeof(UCHAR): - + { /* Write 1 byte */ WRITE_PORT_UCHAR((PUCHAR)(ULONG_PTR)IoAddress, *(PUCHAR)DataValue); *ActualDataSize = sizeof(UCHAR); Status = STATUS_SUCCESS; break; + } case sizeof(USHORT): - + { /* Make sure the address is aligned */ if ((IoAddress & (sizeof(USHORT) - 1)) != 0) { @@ -384,9 +385,10 @@ KdpSysWriteIoSpace(IN ULONG InterfaceType, *ActualDataSize = sizeof(USHORT); Status = STATUS_SUCCESS; break; + } case sizeof(ULONG): - + { /* Make sure the address is aligned */ if ((IoAddress & (sizeof(ULONG) - 1)) != 0) { @@ -402,9 +404,9 @@ KdpSysWriteIoSpace(IN ULONG InterfaceType, *ActualDataSize = sizeof(ULONG); Status = STATUS_SUCCESS; break; + } default: - /* Invalid size, fail */ *ActualDataSize = 0; Status = STATUS_INVALID_PARAMETER; diff --git a/ntoskrnl/kd64/kdapi.c b/ntoskrnl/kd64/kdapi.c index 089af9c5f864f..dca8cc73cc2c1 100644 --- a/ntoskrnl/kd64/kdapi.c +++ b/ntoskrnl/kd64/kdapi.c @@ -430,7 +430,8 @@ KdpSetCommonState(IN ULONG NewState, VOID NTAPI -KdpSysGetVersion(IN PDBGKD_GET_VERSION64 Version) +KdpSysGetVersion( + _Out_ PDBGKD_GET_VERSION64 Version) { /* Copy the version block */ KdpMoveMemory(Version, @@ -960,7 +961,7 @@ KdpReadMachineSpecificRegister(IN PDBGKD_MANIPULATE_STATE64 State, { STRING Header; PDBGKD_READ_WRITE_MSR ReadMsr = &State->u.ReadWriteMsr; - LARGE_INTEGER MsrValue; + ULARGE_INTEGER MsrValue; /* Setup the header */ Header.Length = sizeof(DBGKD_MANIPULATE_STATE64); @@ -968,8 +969,7 @@ KdpReadMachineSpecificRegister(IN PDBGKD_MANIPULATE_STATE64 State, ASSERT(Data->Length == 0); /* Call the internal routine */ - State->ReturnStatus = KdpSysReadMsr(ReadMsr->Msr, - &MsrValue); + State->ReturnStatus = KdpSysReadMsr(ReadMsr->Msr, &MsrValue.QuadPart); /* Return the data */ ReadMsr->DataValueLow = MsrValue.LowPart; @@ -990,7 +990,7 @@ KdpWriteMachineSpecificRegister(IN PDBGKD_MANIPULATE_STATE64 State, { STRING Header; PDBGKD_READ_WRITE_MSR WriteMsr = &State->u.ReadWriteMsr; - LARGE_INTEGER MsrValue; + ULARGE_INTEGER MsrValue; /* Setup the header */ Header.Length = sizeof(DBGKD_MANIPULATE_STATE64); @@ -1000,8 +1000,7 @@ KdpWriteMachineSpecificRegister(IN PDBGKD_MANIPULATE_STATE64 State, /* Call the internal routine */ MsrValue.LowPart = WriteMsr->DataValueLow; MsrValue.HighPart = WriteMsr->DataValueHigh; - State->ReturnStatus = KdpSysWriteMsr(WriteMsr->Msr, - &MsrValue); + State->ReturnStatus = KdpSysWriteMsr(WriteMsr->Msr, &MsrValue.QuadPart); /* Send the reply */ KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, @@ -1061,7 +1060,6 @@ KdpSetBusData(IN PDBGKD_MANIPULATE_STATE64 State, { STRING Header; PDBGKD_GET_SET_BUS_DATA SetBusData = &State->u.GetSetBusData; - ULONG Length; /* Setup the header */ Header.Length = sizeof(DBGKD_MANIPULATE_STATE64); @@ -1074,10 +1072,7 @@ KdpSetBusData(IN PDBGKD_MANIPULATE_STATE64 State, SetBusData->Offset, Data->Buffer, SetBusData->Length, - &Length); - - /* Return the actual length written */ - SetBusData->Length = Length; + &SetBusData->Length); /* Send the reply */ KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, @@ -1497,8 +1492,9 @@ KdpSendWaitContinue(IN ULONG PacketType, case DbgKdPageInApi: - /* TODO */ - KdpDprintf("Page-In support is unimplemented!\n"); + /* This API, introduced in NT4, has been obsoleted in NT5. It is + * replaced by ExpDebuggerPageIn support in ExpDebuggerWorker(). */ + KdpDprintf("DbgKdPageInApi is obsolete!\n"); KdpNotSupported(&ManipulateState); break; @@ -1924,7 +1920,7 @@ KdEnterDebugger(IN PKTRAP_FRAME TrapFrame, /* Freeze all CPUs, raising also the IRQL to HIGH_LEVEL */ Enable = KeFreezeExecution(TrapFrame, ExceptionFrame); - /* Lock the port, save the state and set debugger entered */ + /* Lock the port, save its state and set the debugger entered flag */ KdpPortLocked = KeTryToAcquireSpinLockAtDpcLevel(&KdpDebuggerLock); KdSave(FALSE); KdEnteredDebugger = TRUE; @@ -1956,7 +1952,8 @@ KdExitDebugger(IN BOOLEAN Enable) { ULONG TimeSlip; - /* Restore the state and unlock the port */ + /* Reset the debugger entered flag, restore the port state and unlock it */ + KdEnteredDebugger = FALSE; KdRestore(FALSE); if (KdpPortLocked) KdpPortUnlock(); @@ -2175,20 +2172,60 @@ KdDisableDebugger(VOID) return KdDisableDebuggerWithLock(TRUE); } -/* - * @unimplemented - */ +/** + * @brief + * Perform various queries to the kernel debugger. + * + * @param[in] Command + * A SYSDBG_COMMAND value describing the kernel debugger command to perform. + * + * @param[in] InputBuffer + * Pointer to a user-provided input command-specific buffer, whose length + * is given by InputBufferLength. + * + * @param[in] InputBufferLength + * The size (in bytes) of the buffer pointed by InputBuffer. + * + * @param[out] OutputBuffer + * Pointer to a user-provided command-specific output buffer, whose length + * is given by OutputBufferLength. + * + * @param[in] OutputBufferLength + * The size (in bytes) of the buffer pointed by OutputBuffer. + * + * @param[out] ReturnLength + * Optional pointer to a ULONG variable that receives the actual length of + * data written written in the output buffer. It is always zero, except for + * the live dump commands where an actual non-zero length is returned. + * + * @param[in] PreviousMode + * The processor mode (KernelMode or UserMode) in which the command is being executed. + * + * @return + * STATUS_SUCCESS in case of success, or a proper error code otherwise. + * + * @remarks + * - This is a kernel-mode function, accessible only by kernel-mode drivers. + * + * @note + * See: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2004-2339 + * + * @see NtSystemDebugControl() + **/ NTSTATUS NTAPI KdSystemDebugControl( _In_ SYSDBG_COMMAND Command, - _In_ PVOID InputBuffer, + _In_reads_bytes_(InputBufferLength) PVOID InputBuffer, _In_ ULONG InputBufferLength, - _Out_ PVOID OutputBuffer, + _Out_writes_bytes_(OutputBufferLength) PVOID OutputBuffer, _In_ ULONG OutputBufferLength, - _Inout_ PULONG ReturnLength, + _Out_opt_ PULONG ReturnLength, _In_ KPROCESSOR_MODE PreviousMode) { + NTSTATUS Status; + ULONG Length = 0; + /* Handle some internal commands */ switch ((ULONG)Command) { @@ -2252,9 +2289,301 @@ KdSystemDebugControl( break; } - /* Local kernel debugging is not yet supported */ - DbgPrint("KdSystemDebugControl is unimplemented!\n"); - return STATUS_NOT_IMPLEMENTED; + switch (Command) + { + case SysDbgQueryVersion: + if (OutputBufferLength != sizeof(DBGKD_GET_VERSION64)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + else + { + KdpSysGetVersion((PDBGKD_GET_VERSION64)OutputBuffer); + Status = STATUS_SUCCESS; + } + break; + + case SysDbgReadVirtual: + case SysDbgWriteVirtual: + if (InputBufferLength != sizeof(SYSDBG_VIRTUAL)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + else + { + SYSDBG_VIRTUAL Request = *(PSYSDBG_VIRTUAL)InputBuffer; + PVOID LockedBuffer; + PMDL LockVariable; + + Status = ExLockUserBuffer(Request.Buffer, + Request.Request, + PreviousMode, + Command == SysDbgReadVirtual ? IoWriteAccess : IoReadAccess, + &LockedBuffer, + &LockVariable); + if (NT_SUCCESS(Status)) + { + Status = KdpCopyMemoryChunks((ULONG64)(ULONG_PTR)Request.Address, + Request.Buffer, + Request.Request, + 0, + Command == SysDbgReadVirtual ? 0 : MMDBG_COPY_WRITE, + &Length); + ExUnlockUserBuffer(LockVariable); + } + } + break; + + case SysDbgReadPhysical: + case SysDbgWritePhysical: + if (InputBufferLength != sizeof(SYSDBG_PHYSICAL)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + else + { + SYSDBG_PHYSICAL Request = *(PSYSDBG_PHYSICAL)InputBuffer; + PVOID LockedBuffer; + PMDL LockVariable; + + Status = ExLockUserBuffer(Request.Buffer, + Request.Request, + PreviousMode, + Command == SysDbgReadVirtual ? IoWriteAccess : IoReadAccess, + &LockedBuffer, + &LockVariable); + if (NT_SUCCESS(Status)) + { + Status = KdpCopyMemoryChunks(Request.Address.QuadPart, + Request.Buffer, + Request.Request, + 0, + MMDBG_COPY_PHYSICAL | (Command == SysDbgReadVirtual ? 0 : MMDBG_COPY_WRITE), + &Length); + ExUnlockUserBuffer(LockVariable); + } + } + break; + + case SysDbgReadControlSpace: + if (InputBufferLength != sizeof(SYSDBG_CONTROL_SPACE)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + else + { + SYSDBG_CONTROL_SPACE Request = *(PSYSDBG_CONTROL_SPACE)InputBuffer; + PVOID LockedBuffer; + PMDL LockVariable; + + Status = ExLockUserBuffer(Request.Buffer, + Request.Request, + PreviousMode, + IoWriteAccess, + &LockedBuffer, + &LockVariable); + if (NT_SUCCESS(Status)) + { + Status = KdpSysReadControlSpace(Request.Processor, + Request.Address, + LockedBuffer, + Request.Request, + &Length); + ExUnlockUserBuffer(LockVariable); + } + } + break; + + case SysDbgWriteControlSpace: + if (InputBufferLength != sizeof(SYSDBG_CONTROL_SPACE)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + else + { + SYSDBG_CONTROL_SPACE Request = *(PSYSDBG_CONTROL_SPACE)InputBuffer; + PVOID LockedBuffer; + PMDL LockVariable; + + Status = ExLockUserBuffer(Request.Buffer, + Request.Request, + PreviousMode, + IoReadAccess, + &LockedBuffer, + &LockVariable); + if (NT_SUCCESS(Status)) + { + Status = KdpSysWriteControlSpace(Request.Processor, + Request.Address, + LockedBuffer, + Request.Request, + &Length); + ExUnlockUserBuffer(LockVariable); + } + } + break; + + case SysDbgReadIoSpace: + if (InputBufferLength != sizeof(SYSDBG_IO_SPACE)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + else + { + SYSDBG_IO_SPACE Request = *(PSYSDBG_IO_SPACE)InputBuffer; + PVOID LockedBuffer; + PMDL LockVariable; + + Status = ExLockUserBuffer(Request.Buffer, + Request.Request, + PreviousMode, + IoWriteAccess, + &LockedBuffer, + &LockVariable); + if (NT_SUCCESS(Status)) + { + Status = KdpSysReadIoSpace(Request.InterfaceType, + Request.BusNumber, + Request.AddressSpace, + Request.Address, + LockedBuffer, + Request.Request, + &Length); + ExUnlockUserBuffer(LockVariable); + } + } + break; + + case SysDbgWriteIoSpace: + if (InputBufferLength != sizeof(SYSDBG_IO_SPACE)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + else + { + SYSDBG_IO_SPACE Request = *(PSYSDBG_IO_SPACE)InputBuffer; + PVOID LockedBuffer; + PMDL LockVariable; + + Status = ExLockUserBuffer(Request.Buffer, + Request.Request, + PreviousMode, + IoReadAccess, + &LockedBuffer, + &LockVariable); + if (NT_SUCCESS(Status)) + { + Status = KdpSysWriteIoSpace(Request.InterfaceType, + Request.BusNumber, + Request.AddressSpace, + Request.Address, + LockedBuffer, + Request.Request, + &Length); + ExUnlockUserBuffer(LockVariable); + } + } + break; + + case SysDbgReadMsr: + if (InputBufferLength != sizeof(SYSDBG_MSR)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + else + { + PSYSDBG_MSR Request = (PSYSDBG_MSR)InputBuffer; + Status = KdpSysReadMsr(Request->Address, &Request->Data); + } + break; + + case SysDbgWriteMsr: + if (InputBufferLength != sizeof(SYSDBG_MSR)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + else + { + PSYSDBG_MSR Request = (PSYSDBG_MSR)InputBuffer; + Status = KdpSysWriteMsr(Request->Address, &Request->Data); + } + break; + + case SysDbgReadBusData: + if (InputBufferLength != sizeof(SYSDBG_BUS_DATA)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + else + { + SYSDBG_BUS_DATA Request = *(PSYSDBG_BUS_DATA)InputBuffer; + PVOID LockedBuffer; + PMDL LockVariable; + + Status = ExLockUserBuffer(Request.Buffer, + Request.Request, + PreviousMode, + IoWriteAccess, + &LockedBuffer, + &LockVariable); + if (NT_SUCCESS(Status)) + { + Status = KdpSysReadBusData(Request.BusDataType, + Request.BusNumber, + Request.SlotNumber, + Request.Address, + LockedBuffer, + Request.Request, + &Length); + ExUnlockUserBuffer(LockVariable); + } + } + break; + + case SysDbgWriteBusData: + if (InputBufferLength != sizeof(SYSDBG_BUS_DATA)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + else + { + SYSDBG_BUS_DATA Request = *(PSYSDBG_BUS_DATA)InputBuffer; + PVOID LockedBuffer; + PMDL LockVariable; + + Status = ExLockUserBuffer(Request.Buffer, + Request.Request, + PreviousMode, + IoReadAccess, + &LockedBuffer, + &LockVariable); + if (NT_SUCCESS(Status)) + { + Status = KdpSysWriteBusData(Request.BusDataType, + Request.BusNumber, + Request.SlotNumber, + Request.Address, + LockedBuffer, + Request.Request, + &Length); + ExUnlockUserBuffer(LockVariable); + } + } + break; + + case SysDbgCheckLowMemory: + Status = KdpSysCheckLowMemory(0); + break; + + default: + Status = STATUS_INVALID_INFO_CLASS; + break; + } + + if (ReturnLength) + *ReturnLength = Length; + + return Status; } /* diff --git a/ntoskrnl/kd64/kdinit.c b/ntoskrnl/kd64/kdinit.c index 93f2bd7dfca64..c371d1526b242 100644 --- a/ntoskrnl/kd64/kdinit.c +++ b/ntoskrnl/kd64/kdinit.c @@ -25,14 +25,15 @@ /* UTILITY FUNCTIONS *********************************************************/ -/* - * Get the total size of the memory before - * Mm is initialized, by counting the number - * of physical pages. Useful for debug logging. +#include // For MiIsMemoryTypeInvisible() + +/** + * @brief + * Retrieves the total size of the memory before Mm is initialized, + * by counting the number of physical pages. Useful for debug logging. * - * Strongly inspired by: - * mm\ARM3\mminit.c : MiScanMemoryDescriptors(...) - */ + * Adapted from mm/ARM3/mminit.c!MiScanMemoryDescriptors(). + **/ static SIZE_T KdpGetMemorySizeInMBs( @@ -63,20 +64,14 @@ KdpGetMemorySizeInMBs( MEMORY_ALLOCATION_DESCRIPTOR, ListEntry); - /* Check if this is invisible memory */ - if ((Descriptor->MemoryType == LoaderFirmwarePermanent) || - (Descriptor->MemoryType == LoaderSpecialMemory) || - (Descriptor->MemoryType == LoaderHALCachedMemory) || - (Descriptor->MemoryType == LoaderBBTMemory)) - { - /* Skip this descriptor */ + /* If this is invisible memory, skip this descriptor */ + if (MiIsMemoryTypeInvisible(Descriptor->MemoryType)) continue; - } - /* Check if this is bad memory */ + /* Check if this isn't bad memory */ if (Descriptor->MemoryType != LoaderBad) { - /* Count this in the total of pages */ + /* Count it in the physical pages */ NumberOfPhysicalPages += Descriptor->PageCount; } } @@ -86,10 +81,16 @@ KdpGetMemorySizeInMBs( return ALIGN_UP_BY(NumberOfPhysicalPages * PAGE_SIZE, 1024 * 1024) / (1024 * 1024); } +/** + * @brief + * Displays the kernel debugger initialization banner. + **/ static VOID -KdpPrintBanner(IN SIZE_T MemSizeMBs) +KdpPrintBanner(VOID) { + SIZE_T MemSizeMBs = KdpGetMemorySizeInMBs(KeLoaderBlock); + DPRINT1("-----------------------------------------------------\n"); DPRINT1("ReactOS " KERNEL_VERSION_STR " (Build " KERNEL_VERSION_BUILD_STR ") (Commit " KERNEL_VERSION_COMMIT_HASH ")\n"); DPRINT1("%u System Processor [%u MB Memory]\n", KeNumberProcessors, MemSizeMBs); @@ -97,7 +98,9 @@ KdpPrintBanner(IN SIZE_T MemSizeMBs) if (KeLoaderBlock) { DPRINT1("Command Line: %s\n", KeLoaderBlock->LoadOptions); - DPRINT1("ARC Paths: %s %s %s %s\n", KeLoaderBlock->ArcBootDeviceName, KeLoaderBlock->NtHalPathName, KeLoaderBlock->ArcHalDeviceName, KeLoaderBlock->NtBootPathName); + DPRINT1("ARC Paths: %s %s %s %s\n", + KeLoaderBlock->ArcBootDeviceName, KeLoaderBlock->NtHalPathName, + KeLoaderBlock->ArcHalDeviceName, KeLoaderBlock->NtBootPathName); } } @@ -162,21 +165,9 @@ KdInitSystem( _In_ ULONG BootPhase, _In_opt_ PLOADER_PARAMETER_BLOCK LoaderBlock) { - BOOLEAN EnableKd, DisableKdAfterInit = FALSE, BlockEnable; - PSTR CommandLine, DebugLine, DebugOptionStart, DebugOptionEnd; - STRING ImageName; + BOOLEAN EnableKd, DisableKdAfterInit = FALSE, BlockEnable = FALSE; PLDR_DATA_TABLE_ENTRY LdrEntry; - PLIST_ENTRY NextEntry; - ULONG i, j, Length; - SIZE_T DebugOptionLength; - SIZE_T MemSizeMBs; - CHAR NameBuffer[256]; - PWCHAR Name; - -#if defined(__GNUC__) - /* Make gcc happy */ - BlockEnable = FALSE; -#endif + ULONG i; /* Check if this is Phase 1 */ if (BootPhase) @@ -187,7 +178,8 @@ KdInitSystem( } /* Check if we already initialized once */ - if (KdDebuggerEnabled) return TRUE; + if (KdDebuggerEnabled) + return TRUE; /* Set the Debug Routine as the Stub for now */ KiDebugRoutine = KdpStub; @@ -233,6 +225,8 @@ KdInitSystem( /* Check if we have a loader block */ if (LoaderBlock) { + PSTR CommandLine, DebugLine; + /* Get the image entry */ LdrEntry = CONTAINING_RECORD(LoaderBlock->LoadOrderListHead.Flink, LDR_DATA_TABLE_ENTRY, @@ -263,7 +257,7 @@ KdInitSystem( /* Don't enable KD and don't let it be enabled later */ KdPitchDebugger = TRUE; } - else if ((DebugLine = strstr(CommandLine, "DEBUG")) != NULL) + else if ((DebugLine = strstr(CommandLine, "DEBUG"))) { /* Enable KD */ EnableKd = TRUE; @@ -272,11 +266,14 @@ KdInitSystem( if (DebugLine[5] == '=') { /* Save pointers */ + PSTR DebugOptionStart, DebugOptionEnd; DebugOptionStart = DebugOptionEnd = &DebugLine[6]; /* Scan the string for debug options */ for (;;) { + SIZE_T DebugOptionLength; + /* Loop until we reach the end of the string */ while (*DebugOptionEnd != ANSI_NULL) { @@ -287,7 +284,7 @@ KdInitSystem( { /* * We reached the end of the option or - * the end of the string, break out + * the end of the string, break out. */ break; } @@ -301,20 +298,19 @@ KdInitSystem( /* Calculate the length of the current option */ DebugOptionLength = (DebugOptionEnd - DebugOptionStart); - /* - * Break out if we reached the last option - * or if there were no options at all - */ - if (!DebugOptionLength) break; + /* + * Break out if we reached the last option + * or if there were no options at all. + */ + if (!DebugOptionLength) + break; /* Now check which option this is */ if ((DebugOptionLength == 10) && !(strncmp(DebugOptionStart, "AUTOENABLE", 10))) { - /* - * Disable the debugger, but - * allow it to be reenabled - */ + /* Disable the debugger, but + * allow to re-enable it later */ DisableKdAfterInit = TRUE; BlockEnable = FALSE; KdAutoEnableOnEvent = TRUE; @@ -335,14 +331,11 @@ KdInitSystem( } /* - * If there are more options then - * the next character should be a comma + * If there are more options then the next character + * should be a comma. Break out if it isn't. */ if (*DebugOptionEnd != ',') - { - /* It isn't, break out */ break; - } /* Move on to the next option */ DebugOptionEnd++; @@ -410,9 +403,8 @@ KdInitSystem( /* Let user-mode know that it's enabled as well */ SharedUserData->KdDebuggerEnabled = TRUE; - /* Display separator + ReactOS version at start of the debug log */ - MemSizeMBs = KdpGetMemorySizeInMBs(KeLoaderBlock); - KdpPrintBanner(MemSizeMBs); + /* Display separator + ReactOS version at the start of the debug log */ + KdpPrintBanner(); /* Check if the debugger should be disabled initially */ if (DisableKdAfterInit) @@ -431,10 +423,16 @@ KdInitSystem( /* Check if we have a loader block */ if (LoaderBlock) { - /* Loop boot images */ - NextEntry = LoaderBlock->LoadOrderListHead.Flink; - i = 0; - while ((NextEntry != &LoaderBlock->LoadOrderListHead) && (i < 2)) + PLIST_ENTRY NextEntry; + ULONG j, Length; + PWCHAR Name; + STRING ImageName; + CHAR NameBuffer[256]; + + /* Loop over the first two boot images: HAL and kernel */ + for (NextEntry = LoaderBlock->LoadOrderListHead.Flink, i = 0; + NextEntry != &LoaderBlock->LoadOrderListHead && (i < 2); + NextEntry = NextEntry->Flink, ++i) { /* Get the image entry */ LdrEntry = CONTAINING_RECORD(NextEntry, @@ -454,15 +452,11 @@ KdInitSystem( /* Null-terminate */ NameBuffer[j] = ANSI_NULL; - /* Load symbols for image */ + /* Load the symbols */ RtlInitString(&ImageName, NameBuffer); DbgLoadImageSymbols(&ImageName, LdrEntry->DllBase, (ULONG_PTR)PsGetCurrentProcessId()); - - /* Go to the next entry */ - NextEntry = NextEntry->Flink; - i++; } /* Check for incoming break-in and break on symbol load diff --git a/ntoskrnl/kd64/kdtrap.c b/ntoskrnl/kd64/kdtrap.c index 4cfac2b04b0c6..8af25e3429f2f 100644 --- a/ntoskrnl/kd64/kdtrap.c +++ b/ntoskrnl/kd64/kdtrap.c @@ -318,7 +318,6 @@ KdIsThisAKdTrap(IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT Context, IN KPROCESSOR_MODE PreviousMode) { -#ifdef _WINKD_ /* * Determine if this is a valid debug service call and make sure that * it isn't a software breakpoint @@ -335,8 +334,4 @@ KdIsThisAKdTrap(IN PEXCEPTION_RECORD ExceptionRecord, /* We don't have to handle it */ return FALSE; } -#else - /* KDBG has its own mechanism for ignoring user mode exceptions */ - return FALSE; -#endif } diff --git a/ntoskrnl/kdbg/kdb_cli.c b/ntoskrnl/kdbg/kdb_cli.c index b4794dca7390d..c86b770c81d73 100644 --- a/ntoskrnl/kdbg/kdb_cli.c +++ b/ntoskrnl/kdbg/kdb_cli.c @@ -353,6 +353,7 @@ static const struct #endif // _M_IX86 { "x", "x [address] [L count]", "Display count dwords, starting at address.", KdbpCmdDisassembleX }, { "regs", "regs", "Display general purpose registers.", KdbpCmdRegs }, + { "cregs", "cregs", "Display control, descriptor table and task segment registers.", KdbpCmdRegs }, { "sregs", "sregs", "Display status registers.", KdbpCmdRegs }, { "dregs", "dregs", "Display debug registers.", KdbpCmdRegs }, { "bt", "bt [*frameaddr|thread id]", "Prints current backtrace or from given frame address.", KdbpCmdBackTrace }, @@ -984,6 +985,84 @@ KdbpCmdRegs( } KdbpPrint("\n"); } + else if (Argv[0][0] == 'c') /* cregs */ + { + ULONG Cr0, Cr2, Cr3, Cr4; + KDESCRIPTOR Gdtr = {0, 0, 0}, Idtr = {0, 0, 0}; + USHORT Ldtr, Tr; + static const PCHAR Cr0Bits[32] = { " PE", " MP", " EM", " TS", " ET", " NE", NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + " WP", NULL, " AM", NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, " NW", " CD", " PG" }; + static const PCHAR Cr4Bits[32] = { " VME", " PVI", " TSD", " DE", " PSE", " PAE", " MCE", " PGE", + " PCE", " OSFXSR", " OSXMMEXCPT", NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; + SYSDBG_CONTROL_SPACE Input; + KSPECIAL_REGISTERS SpecialRegisters; + NTSTATUS Status = STATUS_NOT_IMPLEMENTED; + + /* Retrieve the control registers */ + RtlZeroMemory(&Input, sizeof(Input)); + Input.Buffer = &SpecialRegisters; + Input.Request = sizeof(SpecialRegisters); +#ifdef _M_IX86 + Input.Address = sizeof(CONTEXT); +#else + Input.Address = AMD64_DEBUG_CONTROL_SPACE_KSPECIAL; +#endif + Status = KdSystemDebugControl(SysDbgReadControlSpace, + &Input, sizeof(Input), + NULL, 0, + NULL, KernelMode); + if (!NT_SUCCESS(Status)) + { + KdbpPrint("Failed to get registers: status 0x%08x\n", Status); + return TRUE; + } + Cr0 = SpecialRegisters.Cr0; + Cr2 = SpecialRegisters.Cr2; + Cr3 = SpecialRegisters.Cr3; + Cr4 = SpecialRegisters.Cr4; + + /* Retrieve the descriptor table and task segment registers */ + Gdtr = SpecialRegisters.Gdtr; + Ldtr = SpecialRegisters.Ldtr; + Idtr = SpecialRegisters.Idtr; + Tr = SpecialRegisters.Tr; + + /* Display the control registers */ + KdbpPrint("CR0 0x%08x ", Cr0); + for (i = 0; i < 32; i++) + { + if (!Cr0Bits[i]) + continue; + + if ((Cr0 & (1 << i)) != 0) + KdbpPrint(Cr0Bits[i]); + } + KdbpPrint("\n"); + + KdbpPrint("CR2 0x%08x\n", Cr2); + KdbpPrint("CR3 0x%08x Pagedir-Base 0x%08x %s%s\n", Cr3, (Cr3 & 0xfffff000), + (Cr3 & (1 << 3)) ? " PWT" : "", (Cr3 & (1 << 4)) ? " PCD" : "" ); + KdbpPrint("CR4 0x%08x ", Cr4); + for (i = 0; i < 32; i++) + { + if (!Cr4Bits[i]) + continue; + + if ((Cr4 & (1 << i)) != 0) + KdbpPrint(Cr4Bits[i]); + } + KdbpPrint("\n"); + + /* Display the descriptor table and task segment registers */ + KdbpPrint("GDTR Base 0x%08x Size 0x%04x\n", Gdtr.Base, Gdtr.Limit); + KdbpPrint("LDTR 0x%04x\n", Ldtr); + KdbpPrint("IDTR Base 0x%08x Size 0x%04x\n", Idtr.Base, Idtr.Limit); + KdbpPrint("TR 0x%04x\n", Tr); + } else if (Argv[0][0] == 's') /* sregs */ { KdbpPrint("CS 0x%04x Index 0x%04x %cDT RPL%d\n", diff --git a/ntoskrnl/ke/amd64/cpu.c b/ntoskrnl/ke/amd64/cpu.c index d1e9567c1b82a..76ccb184f20df 100644 --- a/ntoskrnl/ke/amd64/cpu.c +++ b/ntoskrnl/ke/amd64/cpu.c @@ -12,6 +12,7 @@ #include #include #include + #define NDEBUG #include @@ -206,6 +207,7 @@ KiGetFeatureBits(VOID) if (VersionInfo.Ecx.Bits.SSSE3) FeatureBits |= KF_SSSE3; if (VersionInfo.Ecx.Bits.CMPXCHG16B) FeatureBits |= KF_CMPXCHG16B; if (VersionInfo.Ecx.Bits.SSE4_1) FeatureBits |= KF_SSE4_1; + if (VersionInfo.Ecx.Bits.SSE4_2) FeatureBits |= KF_SSE4_2; if (VersionInfo.Ecx.Bits.XSAVE) FeatureBits |= KF_XSTATE; if (VersionInfo.Ecx.Bits.RDRAND) FeatureBits |= KF_RDRAND; @@ -255,7 +257,7 @@ KiGetFeatureBits(VOID) if (signature.MaxLeaf >= CPUID_EXTENDED_STATE) { /* Read CPUID_EXTENDED_STATE */ - CPUID_EXTENDED_STATE_SUB_LEAF_EAX_REGS ExtStateSub; + CPUID_EXTENDED_STATE_SUB_LEAF_REGS ExtStateSub; __cpuidex(ExtStateSub.AsInt32, CPUID_EXTENDED_STATE, CPUID_EXTENDED_STATE_SUB_LEAF); @@ -357,9 +359,9 @@ KiReportCpuFeatures(IN PKPRCB Prcb) CpuFeatures = CpuInfo.Edx; } - DPRINT1("Supported CPU features: "); + DPRINT1("Supported CPU features:"); -#define print_kf_bit(kf_value) if (Prcb->FeatureBits & kf_value) DbgPrint(#kf_value " ") +#define print_kf_bit(kf_value) if (Prcb->FeatureBits & kf_value) DbgPrint(" " #kf_value) print_kf_bit(KF_SMEP); print_kf_bit(KF_RDTSC); print_kf_bit(KF_CR4); @@ -404,7 +406,7 @@ KiReportCpuFeatures(IN PKPRCB Prcb) print_kf_bit(KF_SSE4_2); #undef print_kf_bit -#define print_cf(cpu_flag) if (CpuFeatures & cpu_flag) DbgPrint(#cpu_flag " ") +#define print_cf(cpu_flag) if (CpuFeatures & cpu_flag) DbgPrint(" " #cpu_flag) print_cf(X86_FEATURE_PAE); print_cf(X86_FEATURE_HT); #undef print_cf @@ -667,16 +669,6 @@ KeFlushEntireTb(IN BOOLEAN Invalid, } -KAFFINITY -NTAPI -KeQueryActiveProcessors(VOID) -{ - PAGED_CODE(); - - /* Simply return the number of active processors */ - return KeActiveProcessors; -} - NTSTATUS NTAPI KxSaveFloatingPointState(OUT PKFLOATING_SAVE FloatingState) diff --git a/ntoskrnl/ke/amd64/ctxswitch.S b/ntoskrnl/ke/amd64/ctxswitch.S index 829026ce49ccf..e0df609a76aa8 100644 --- a/ntoskrnl/ke/amd64/ctxswitch.S +++ b/ntoskrnl/ke/amd64/ctxswitch.S @@ -197,6 +197,10 @@ PUBLIC KiUserThreadStartupExit mov cl, [rsp + SwApcBypass] call KiSwapContextResume + + /* Force reloading of FS */ + push fs + pop fs /* Cleanup and return */ add rsp, 6 * 8 diff --git a/ntoskrnl/ke/amd64/freeze.c b/ntoskrnl/ke/amd64/freeze.c index 5cf53f3f27fa1..5e655d3293971 100644 --- a/ntoskrnl/ke/amd64/freeze.c +++ b/ntoskrnl/ke/amd64/freeze.c @@ -1,8 +1,30 @@ /* * PROJECT: ReactOS Kernel - * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * LICENSE: MIT (https://spdx.org/licenses/MIT) * PURPOSE: Processor freeze support for x64 - * COPYRIGHT: Copyright 2023 Timo Kreuzer + * COPYRIGHT: Copyright 2023-2024 Timo Kreuzer + */ + +/* + + IpiFrozen state graph (based on Windows behavior): + + +-----------------+ Freeze request +-----------------+ + | RUNNING |------------------------>| TARGET_FREEZE | + +-----------------+<--------- +-----------------+ + |^ | Resume | + Freeze || Thaw +-----------+ Thaw request | Freeze IPI + v| | THAW |<-----------\ v + +-----------------+ +-----------+ +-----------------+ + | OWNER + ACTIVE | ^ | FROZEN | + +-----------------+ | +-----------------+ + ^ | ^ + | Kd proc switch | | Kd proc switch + v | v + +-----------------+ | +-----------------+ + | OWNER |---------+ | FROZEN + ACTIVE | + +-----------------+ Thaw request +-----------------+ + */ /* INCLUDES *******************************************************************/ @@ -98,8 +120,8 @@ KxFreezeExecution( } } - /* We are the owner now */ - CurrentPrcb->IpiFrozen = IPI_FROZEN_STATE_OWNER; + /* We are the owner now and active */ + CurrentPrcb->IpiFrozen = IPI_FROZEN_STATE_OWNER | IPI_FROZEN_FLAG_ACTIVE; /* Loop all processors */ for (ULONG i = 0; i < KeNumberProcessors; i++) @@ -107,7 +129,7 @@ KxFreezeExecution( PKPRCB TargetPrcb = KiProcessorBlock[i]; if (TargetPrcb != CurrentPrcb) { - /* Nobody else is allowed to change IpiFrozen, except the freeze owner */ + /* Only the active processor is allowed to change IpiFrozen */ ASSERT(TargetPrcb->IpiFrozen == IPI_FROZEN_STATE_RUNNING); /* Request target to freeze */ @@ -142,6 +164,7 @@ KxThawExecution( VOID) { PKPRCB CurrentPrcb = KeGetCurrentPrcb(); + ASSERT(CurrentPrcb->IpiFrozen & IPI_FROZEN_FLAG_ACTIVE); /* Loop all processors */ for (ULONG i = 0; i < KeNumberProcessors; i++) @@ -190,6 +213,10 @@ KxSwitchKdProcessor( /* Make sure that the processor index is valid */ ASSERT(ProcessorIndex < KeNumberProcessors); + /* We are no longer active */ + ASSERT(CurrentPrcb->IpiFrozen & IPI_FROZEN_FLAG_ACTIVE); + CurrentPrcb->IpiFrozen &= ~IPI_FROZEN_FLAG_ACTIVE; + /* Inform the target processor that it's his turn now */ TargetPrcb = KiProcessorBlock[ProcessorIndex]; TargetPrcb->IpiFrozen |= IPI_FROZEN_FLAG_ACTIVE; @@ -212,12 +239,12 @@ KxSwitchKdProcessor( { /* Another CPU has completed, we can leave the debugger now */ KdpDprintf("[%u] KxSwitchKdProcessor: ContinueSuccess\n", KeGetCurrentProcessorNumber()); - CurrentPrcb->IpiFrozen = IPI_FROZEN_STATE_OWNER; + CurrentPrcb->IpiFrozen = IPI_FROZEN_STATE_OWNER | IPI_FROZEN_FLAG_ACTIVE; return ContinueSuccess; } /* We have been reselected, return to Kd to continue in the debugger */ - CurrentPrcb->IpiFrozen = IPI_FROZEN_STATE_OWNER; + ASSERT(CurrentPrcb->IpiFrozen == (IPI_FROZEN_STATE_OWNER | IPI_FROZEN_FLAG_ACTIVE)); return ContinueProcessorReselected; } diff --git a/ntoskrnl/ke/amd64/krnlinit.c b/ntoskrnl/ke/amd64/krnlinit.c index d7aea4db7386a..f580cacbba91d 100644 --- a/ntoskrnl/ke/amd64/krnlinit.c +++ b/ntoskrnl/ke/amd64/krnlinit.c @@ -233,7 +233,7 @@ KiInitializeKernel(IN PKPROCESS InitProcess, ULONG i; /* Set boot-level flags */ - KeFeatureBits = Prcb->FeatureBits; + KeFeatureBits = Prcb->FeatureBits | (ULONG64)Prcb->FeatureBitsHigh << 32; /* Initialize 8/16 bit SList support */ RtlpUse16ByteSLists = (KeFeatureBits & KF_CMPXCHG16B) ? TRUE : FALSE; diff --git a/ntoskrnl/ke/amd64/thrdini.c b/ntoskrnl/ke/amd64/thrdini.c index 3185de21cd6c7..bb6b592440932 100644 --- a/ntoskrnl/ke/amd64/thrdini.c +++ b/ntoskrnl/ke/amd64/thrdini.c @@ -151,6 +151,9 @@ KiSwapContextResume( { PKIPCR Pcr = (PKIPCR)KeGetPcr(); PKPROCESS OldProcess, NewProcess; +#ifdef _M_AMD64 + PEPROCESS ENewProcess; +#endif /* Setup ring 0 stack pointer */ Pcr->TssBase->Rsp0 = (ULONG64)NewThread->InitialStack; // FIXME: NPX save area? @@ -174,6 +177,20 @@ KiSwapContextResume( { /* This will switch the usermode gs */ __writemsr(MSR_GS_SWAP, (ULONG64)NewThread->Teb); + + ENewProcess = (PEPROCESS) NewProcess; + if (ENewProcess->Wow64Process != NULL) + { + ULONG_PTR base = ROUND_TO_PAGES((ULONG_PTR)(NewThread->Teb + 1)); + + PKGDTENTRY64 CmTebEntry = KiGetGdtEntry(Pcr->GdtBase, KGDT64_R3_CMTEB); + CmTebEntry->LimitLow = 0xFFFF; + CmTebEntry->Bits.LimitHigh = 0xFFFF; + + CmTebEntry->BaseLow = base & 0xFFFF; + CmTebEntry->Bits.BaseMiddle = (base & 0xFF0000) >> 16; + CmTebEntry->Bits.BaseHigh = (base & 0xFF000000) >> 24; + } } /* Increase context switch count */ diff --git a/ntoskrnl/ke/amd64/trap.S b/ntoskrnl/ke/amd64/trap.S index 34b7c906104d3..b1606c914e627 100644 --- a/ntoskrnl/ke/amd64/trap.S +++ b/ntoskrnl/ke/amd64/trap.S @@ -23,8 +23,9 @@ EXTERN KiDpcInterruptHandler:PROC EXTERN PsConvertToGuiThread:PROC EXTERN MmCreateKernelStack:PROC EXTERN MmDeleteKernelStack:PROC - EXTERN KdSetOwedBreakpoints:PROC +EXTERN KeAcquireSpinLockAtDpcLevel:PROC +EXTERN KeReleaseSpinLockFromDpcLevel:PROC /* Helper Macros *************************************************************/ @@ -744,11 +745,13 @@ FUNC KiInterruptDispatch movzx rax, byte ptr [rbx + KINTERRUPT_SynchronizeIrql] mov cr8, rax + /* Enable interrupts */ + sti + #ifdef CONFIG_SMP /* Acquire interrupt lock */ - mov r8, [rbx + KINTERRUPT_ActualLock] - - //KxAcquireSpinLock(Interrupt->ActualLock); + mov rcx, [rbx + KINTERRUPT_ActualLock] + call KeAcquireSpinLockAtDpcLevel #endif /* Call the ISR */ @@ -758,10 +761,12 @@ FUNC KiInterruptDispatch #ifdef CONFIG_SMP /* Release interrupt lock */ - //KxReleaseSpinLock(Interrupt->ActualLock); + mov rcx, [rbx + KINTERRUPT_ActualLock] + call KeReleaseSpinLockFromDpcLevel #endif - /* Go back to old irql */ + /* Disable interrupts and go back to old irql */ + cli movzx rax, byte ptr [rbp + KTRAP_FRAME_PreviousIrql] mov cr8, rax @@ -825,6 +830,13 @@ PUBLIC KiSystemCallEntry64 mov [rsp + MAX_SYSCALL_PARAM_SIZE + KTRAP_FRAME_EFlags], r11 mov [rsp + MAX_SYSCALL_PARAM_SIZE + KTRAP_FRAME_Rbp], rbp + /* Set the trapframe cs register to a fixed 64-bit, usermode selector + (when returning with a sysret cs is loaded with this selector anyway, + but we have to make sure we're not writing garbage/outdated values to cs + when starting user APCs) */ + mov rax, HEX(33) + mov [rsp + MAX_SYSCALL_PARAM_SIZE + KTRAP_FRAME_SegCs], rax + /* Store user stack pointer in the trap frame */ mov rax, gs:[PcUserRsp] mov [rsp + MAX_SYSCALL_PARAM_SIZE + KTRAP_FRAME_Rsp], rax diff --git a/ntoskrnl/ke/amd64/traphandler.c b/ntoskrnl/ke/amd64/traphandler.c index dc72d08fc63da..ef2cb4d7dae27 100644 --- a/ntoskrnl/ke/amd64/traphandler.c +++ b/ntoskrnl/ke/amd64/traphandler.c @@ -159,9 +159,8 @@ KiSystemCallHandler( /* We don't have an exception frame yet */ TrapFrame->ExceptionFrame = 0; - /* Before enabling interrupts get the user rsp from the KPCR */ - UserRsp = __readgsqword(FIELD_OFFSET(KIPCR, UserRsp)); - TrapFrame->Rsp = UserRsp; + /* Get the user Stack pointer */ + UserRsp = TrapFrame->Rsp; /* Enable interrupts */ _enable(); diff --git a/ntoskrnl/ke/amd64/usercall.c b/ntoskrnl/ke/amd64/usercall.c index 9bcc81384b4b9..bab35e9e40ed8 100644 --- a/ntoskrnl/ke/amd64/usercall.c +++ b/ntoskrnl/ke/amd64/usercall.c @@ -16,8 +16,8 @@ * * \brief * Prepares the current trap frame (which must have come from user mode) - * with the ntdll.KiUserApcDispatcher entrypoint, copying a CONTEXT - * record with the context from the old trap frame to the threads user + * with the ntdll.KiUserApcDispatcher entrypoint, copying a UAPC_FRAME + * structure with the context from the old trap frame to the threads user * mode stack. * * \param ExceptionFrame - Pointer to the Exception Frame @@ -53,20 +53,22 @@ KiInitializeUserApc( _In_ PVOID SystemArgument1, _In_ PVOID SystemArgument2) { + PUAPC_FRAME ApcFrame; PCONTEXT Context; EXCEPTION_RECORD ExceptionRecord; /* Sanity check, that the trap frame is from user mode */ ASSERT((TrapFrame->SegCs & MODE_MASK) != KernelMode); - /* Align the user tack to 16 bytes and allocate space for a CONTEXT structure */ - Context = (PCONTEXT)ALIGN_DOWN_POINTER_BY(TrapFrame->Rsp, 16) - 1; + /* Allocate a 16 byte aligned UAPC_FRAME structure on the user stack */ + ApcFrame = (PUAPC_FRAME)ALIGN_DOWN_POINTER_BY(TrapFrame->Rsp - sizeof(*ApcFrame), 16); + Context = &ApcFrame->Context; /* Protect with SEH */ _SEH2_TRY { - /* Probe the context */ - ProbeForWrite(Context, sizeof(CONTEXT), 16); + /* Probe the user mode APC frame */ + ProbeForWrite(ApcFrame, sizeof(*ApcFrame), 16); /* Convert the current trap frame to a context */ Context->ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS; @@ -77,6 +79,10 @@ KiInitializeUserApc( Context->P2Home = (ULONG64)SystemArgument1; Context->P3Home = (ULONG64)SystemArgument2; Context->P4Home = (ULONG64)NormalRoutine; + + /* Set up the machine frame for unwinding */ + ApcFrame->MachineFrame.Rip = TrapFrame->Rip; + ApcFrame->MachineFrame.Rsp = TrapFrame->Rsp; } _SEH2_EXCEPT(ExceptionRecord = *_SEH2_GetExceptionInformation()->ExceptionRecord, EXCEPTION_EXECUTE_HANDLER) { @@ -318,9 +324,6 @@ KeUserModeCallback( /* Restore stack and return */ *UserStackPointer = OldStack; -#ifdef _M_AMD64 // could probably move the update to TrapFrame->Rsp from the C handler to the asm code - __writegsqword(FIELD_OFFSET(KIPCR, UserRsp), OldStack); -#endif return CallbackStatus; } diff --git a/ntoskrnl/ke/arm/cpu.c b/ntoskrnl/ke/arm/cpu.c index 756b9ab9f1cb1..f86a95952920a 100644 --- a/ntoskrnl/ke/arm/cpu.c +++ b/ntoskrnl/ke/arm/cpu.c @@ -153,21 +153,6 @@ KeSetDmaIoCoherency(IN ULONG Coherency) KiDmaIoCoherency = Coherency; } -/* - * @implemented - */ -KAFFINITY -NTAPI -KeQueryActiveProcessors(VOID) -{ - PAGED_CODE(); - - // - // Simply return the number of active processors - // - return KeActiveProcessors; -} - /* * @implemented */ diff --git a/ntoskrnl/ke/bug.c b/ntoskrnl/ke/bug.c index 1bf6e7cafbda8..7ab38c6614b16 100644 --- a/ntoskrnl/ke/bug.c +++ b/ntoskrnl/ke/bug.c @@ -310,12 +310,12 @@ KiInitializeBugCheck(VOID) LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); - /* Cache the Bugcheck Message Strings. Prepare the Lookup Data */ - ResourceInfo.Type = 11; + /* Cache the bugcheck message strings. Prepare the lookup data. */ + ResourceInfo.Type = RT_MESSAGETABLE; ResourceInfo.Name = 1; - ResourceInfo.Language = 9; + ResourceInfo.Language = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL); - /* Do the lookup. */ + /* Do the lookup */ Status = LdrFindResource_U(LdrEntry->DllBase, &ResourceInfo, RESOURCE_DATA_LEVEL, @@ -449,7 +449,7 @@ KiDoBugCheckCallbacks(VOID) NextEntry = ListHead->Flink; while (NextEntry != ListHead) { - /* Get the reord */ + /* Get the record */ CurrentRecord = CONTAINING_RECORD(NextEntry, KBUGCHECK_CALLBACK_RECORD, Entry); @@ -615,8 +615,20 @@ KiDisplayBlueScreen(IN ULONG MessageId, IN PCHAR HardErrMessage OPTIONAL, IN PCHAR Message) { + ULONG BugCheckCode = (ULONG)KiBugCheckData[0]; + BOOLEAN Enable = TRUE; CHAR AnsiName[107]; + /* Enable headless support for bugcheck */ + HeadlessDispatch(HeadlessCmdStartBugCheck, + NULL, 0, NULL, NULL); + HeadlessDispatch(HeadlessCmdEnableTerminal, + &Enable, sizeof(Enable), + NULL, NULL); + HeadlessDispatch(HeadlessCmdSendBlueScreenData, + &BugCheckCode, sizeof(BugCheckCode), + NULL, NULL); + /* Check if bootvid is installed */ if (InbvIsBootDriverInstalled()) { @@ -664,7 +676,7 @@ KiDisplayBlueScreen(IN ULONG MessageId, if (MessageId == BUGCODE_PSS_MESSAGE) { /* It is, so get the bug code string as well */ - KeGetBugMessageText((ULONG)KiBugCheckData[0], NULL); + KeGetBugMessageText(BugCheckCode, NULL); InbvDisplayString("\r\n\r\n"); } @@ -683,7 +695,7 @@ KiDisplayBlueScreen(IN ULONG MessageId, RtlStringCbPrintfA(AnsiName, sizeof(AnsiName), "\r\n\r\n*** STOP: 0x%08lX (0x%p,0x%p,0x%p,0x%p)\r\n\r\n", - (ULONG)KiBugCheckData[0], + BugCheckCode, (PVOID)KiBugCheckData[1], (PVOID)KiBugCheckData[2], (PVOID)KiBugCheckData[3], @@ -1080,17 +1092,7 @@ KeBugCheckWithTf(IN ULONG BugCheckCode, KeBugCheckOwner = Prcb->Number; /* Freeze the other CPUs */ - for (ULONG i = 0; i < KeNumberProcessors; i++) - { - if (i != Prcb->Number) - { - /* Send the IPI */ - KiIpiSend(AFFINITY_MASK(i), IPI_FREEZE); - } - } - - /* Give the other CPUs one second to catch up */ - KeStallExecutionProcessor(1000000); + KxFreezeExecution(); #endif /* Display the BSOD */ @@ -1122,6 +1124,8 @@ KeBugCheckWithTf(IN ULONG BugCheckCode, /* FIXME: Support Triage Dump */ /* FIXME: Write the crash dump */ + // TODO: The crash-dump helper must set the Reboot variable. + Reboot = !!IopAutoReboot; } else { diff --git a/ntoskrnl/ke/dpc.c b/ntoskrnl/ke/dpc.c index 04d45fe16659f..39e2c16b9d702 100644 --- a/ntoskrnl/ke/dpc.c +++ b/ntoskrnl/ke/dpc.c @@ -905,7 +905,7 @@ KeRemoveQueueDpc(IN PKDPC Dpc) } /* Re-enable interrupts */ - if (Enable) _enable(); + KeRestoreInterrupts(Enable); /* Return if the DPC was in the queue or not */ return DpcData ? TRUE : FALSE; diff --git a/ntoskrnl/ke/i386/cpu.c b/ntoskrnl/ke/i386/cpu.c index a39d27a21396c..b54a94d13c25c 100644 --- a/ntoskrnl/ke/i386/cpu.c +++ b/ntoskrnl/ke/i386/cpu.c @@ -9,11 +9,11 @@ /* INCLUDES *****************************************************************/ #include +#include + #define NDEBUG #include -#include - /* GLOBALS *******************************************************************/ /* The TSS to use for Double Fault Traps (INT 0x9) */ @@ -209,13 +209,13 @@ KiSetProcessorType(VOID) } CODE_SEG("INIT") -ULONG +ULONG64 NTAPI KiGetFeatureBits(VOID) { PKPRCB Prcb = KeGetCurrentPrcb(); ULONG Vendor; - ULONG FeatureBits = KF_WORKING_PTE; + ULONG64 FeatureBits = KF_WORKING_PTE; CPU_INFO CpuInfo, DummyCpuInfo; UCHAR Ccr1; BOOLEAN ExtendedCPUID = TRUE; @@ -361,6 +361,14 @@ KiGetFeatureBits(VOID) break; } + /* Get some features from ECX */ + if (CpuInfo.Ecx & X86_FEATURE_SSE3) FeatureBits |= KF_SSE3; + if (CpuInfo.Ecx & X86_FEATURE_SSSE3) FeatureBits |= KF_SSSE3; + if (CpuInfo.Ecx & X86_FEATURE_SSE4_1) FeatureBits |= KF_SSE4_1; + if (CpuInfo.Ecx & X86_FEATURE_SSE4_2) FeatureBits |= KF_SSE4_2; + if (CpuInfo.Ecx & X86_FEATURE_XSAVE) FeatureBits |= KF_XSTATE; + if (CpuInfo.Ecx & X86_FEATURE_RDRAND) FeatureBits |= KF_RDRAND; + /* Set the current features */ CpuFeatures = CpuInfo.Edx; @@ -443,9 +451,9 @@ KiReportCpuFeatures(VOID) CpuFeatures = CpuInfo.Edx; } - DPRINT1("Supported CPU features: "); + DPRINT1("Supported CPU features:"); -#define print_kf_bit(kf_value) if (KeFeatureBits & kf_value) DbgPrint(#kf_value " ") +#define print_kf_bit(kf_value) if (KeFeatureBits & kf_value) DbgPrint(" " #kf_value) print_kf_bit(KF_V86_VIS); print_kf_bit(KF_RDTSC); print_kf_bit(KF_CR4); @@ -469,7 +477,7 @@ KiReportCpuFeatures(VOID) print_kf_bit(KF_NX_ENABLED); #undef print_kf_bit -#define print_cf(cpu_flag) if (CpuFeatures & cpu_flag) DbgPrint(#cpu_flag " ") +#define print_cf(cpu_flag) if (CpuFeatures & cpu_flag) DbgPrint(" " #cpu_flag) print_cf(X86_FEATURE_PAE); print_cf(X86_FEATURE_APIC); print_cf(X86_FEATURE_HT); @@ -1649,19 +1657,6 @@ KeSetDmaIoCoherency(IN ULONG Coherency) KiDmaIoCoherency = Coherency; } -/* - * @implemented - */ -KAFFINITY -NTAPI -KeQueryActiveProcessors(VOID) -{ - PAGED_CODE(); - - /* Simply return the number of active processors */ - return KeActiveProcessors; -} - /* * @implemented */ diff --git a/ntoskrnl/ke/i386/kiinit.c b/ntoskrnl/ke/i386/kiinit.c index e3ec9ed94bfb4..671adad67c365 100644 --- a/ntoskrnl/ke/i386/kiinit.c +++ b/ntoskrnl/ke/i386/kiinit.c @@ -384,7 +384,7 @@ KiVerifyCpuFeatures(PKPRCB Prcb) KeBugCheckEx(UNSUPPORTED_PROCESSOR, 0x386, 0, 0, 0); // 3. Finally, obtain CPU features. - ULONG FeatureBits = KiGetFeatureBits(); + ULONG64 FeatureBits = KiGetFeatureBits(); // 4. Verify it supports everything we need. if (!(FeatureBits & KF_RDTSC)) @@ -423,7 +423,8 @@ KiVerifyCpuFeatures(PKPRCB Prcb) } // 5. Save feature bits. - Prcb->FeatureBits = FeatureBits; + Prcb->FeatureBits = (ULONG)FeatureBits; + Prcb->FeatureBitsHigh = FeatureBits >> 32; } CODE_SEG("INIT") @@ -445,7 +446,7 @@ KiInitializeKernel(IN PKPROCESS InitProcess, /* Set boot-level flags */ if (Number == 0) - KeFeatureBits = Prcb->FeatureBits; + KeFeatureBits = Prcb->FeatureBits | (ULONG64)Prcb->FeatureBitsHigh << 32; /* Set the default NX policy (opt-in) */ SharedUserData->NXSupportPolicy = NX_SUPPORT_POLICY_OPTIN; @@ -571,6 +572,17 @@ KiInitializeKernel(IN PKPROCESS InitProcess, (KeFeatureBits & KF_3DNOW) ? TRUE: FALSE; SharedUserData->ProcessorFeatures[PF_RDTSC_INSTRUCTION_AVAILABLE] = (KeFeatureBits & KF_RDTSC) ? TRUE: FALSE; + SharedUserData->ProcessorFeatures[PF_RDRAND_INSTRUCTION_AVAILABLE] = + (KeFeatureBits & KF_RDRAND) ? TRUE : FALSE; + // Note: On x86 we lack support for saving/restoring SSE state + SharedUserData->ProcessorFeatures[PF_SSE3_INSTRUCTIONS_AVAILABLE] = + (KeFeatureBits & KF_SSE3) ? TRUE : FALSE; + SharedUserData->ProcessorFeatures[PF_SSSE3_INSTRUCTIONS_AVAILABLE] = + (KeFeatureBits & KF_SSSE3) ? TRUE : FALSE; + SharedUserData->ProcessorFeatures[PF_SSE4_1_INSTRUCTIONS_AVAILABLE] = + (KeFeatureBits & KF_SSE4_1) ? TRUE : FALSE; + SharedUserData->ProcessorFeatures[PF_SSE4_2_INSTRUCTIONS_AVAILABLE] = + (KeFeatureBits & KF_SSE4_2) ? TRUE : FALSE; /* Set up the thread-related fields in the PRCB */ Prcb->CurrentThread = InitThread; diff --git a/ntoskrnl/ke/i386/mproc.c b/ntoskrnl/ke/i386/mproc.c index 63e7a748bd12a..e3e05191dfcf9 100644 --- a/ntoskrnl/ke/i386/mproc.c +++ b/ntoskrnl/ke/i386/mproc.c @@ -9,6 +9,7 @@ /* INCLUDES *****************************************************************/ #include + #define NDEBUG #include @@ -38,12 +39,28 @@ NTAPI KeStartAllProcessors(VOID) { PVOID KernelStack, DPCStack; - ULONG ProcessorCount = 0; PAPINFO APInfo; + ULONG ProcessorCount; + ULONG MaximumProcessors; + + /* NOTE: NT6+ HAL exports HalEnumerateProcessors() and + * HalQueryMaximumProcessorCount() that help determining + * the number of detected processors on the system. */ + MaximumProcessors = KeMaximumProcessors; + + /* Limit the number of processors we can start at run-time */ + if (KeNumprocSpecified) + MaximumProcessors = min(MaximumProcessors, KeNumprocSpecified); + + /* Limit also the number of processors we can start during boot-time */ + if (KeBootprocSpecified) + MaximumProcessors = min(MaximumProcessors, KeBootprocSpecified); + + // TODO: Support processor nodes - while (TRUE) + /* Start ProcessorCount at 1 because we already have the boot CPU */ + for (ProcessorCount = 1; ProcessorCount < MaximumProcessors; ++ProcessorCount) { - ProcessorCount++; KernelStack = NULL; DPCStack = NULL; diff --git a/ntoskrnl/ke/i386/v86vdm.c b/ntoskrnl/ke/i386/v86vdm.c index a50f3aba188f4..b4790d146f693 100644 --- a/ntoskrnl/ke/i386/v86vdm.c +++ b/ntoskrnl/ke/i386/v86vdm.c @@ -191,13 +191,21 @@ KiVdmOpcodeINTnn(IN PKTRAP_FRAME TrapFrame, V86EFlags &= (EFLAGS_ALIGN_CHECK | EFLAGS_INTERRUPT_MASK); /* Check for VME support */ - ASSERT(KeI386VirtualIntExtensions == FALSE); + if (KeI386VirtualIntExtensions) + { + /* Set IF based on VIF */ + V86EFlags &= ~EFLAGS_INTERRUPT_MASK; + if (TrapEFlags & EFLAGS_VIF) + { + V86EFlags |= EFLAGS_INTERRUPT_MASK; + } + } /* Mask in the relevant V86 EFlags into the trap flags */ V86EFlags |= (TrapEFlags & ~EFLAGS_INTERRUPT_MASK); /* And mask out the VIF, nested task and TF flag from the trap flags */ - TrapFrame->EFlags = TrapEFlags &~ (EFLAGS_VIF | EFLAGS_NESTED_TASK | EFLAGS_TF); + TrapFrame->EFlags = TrapEFlags & ~(EFLAGS_VIF | EFLAGS_NESTED_TASK | EFLAGS_TF); /* Add the IOPL flag to the local trap flags */ V86EFlags |= EFLAGS_IOPL; @@ -299,11 +307,17 @@ KiVdmOpcodeIRET(IN PKTRAP_FRAME TrapFrame, } /* Mask out EFlags */ - EFlags &= ~(EFLAGS_IOPL + EFLAGS_VIF + EFLAGS_NESTED_TASK + EFLAGS_VIP); + EFlags &= ~(EFLAGS_VIP | EFLAGS_VIF | EFLAGS_NESTED_TASK | EFLAGS_IOPL); V86EFlags = EFlags; /* Check for VME support */ - ASSERT(KeI386VirtualIntExtensions == FALSE); + if (KeI386VirtualIntExtensions) + { + if (EFlags & EFLAGS_INTERRUPT_MASK) + { + EFlags |= EFLAGS_VIF; + } + } /* Add V86 and Interrupt flag */ EFlags |= EFLAGS_V86_MASK | EFLAGS_INTERRUPT_MASK; diff --git a/ntoskrnl/ke/krnlinit.c b/ntoskrnl/ke/krnlinit.c index 66299e3d57ca5..edb455abfc5dc 100644 --- a/ntoskrnl/ke/krnlinit.c +++ b/ntoskrnl/ke/krnlinit.c @@ -19,8 +19,7 @@ USHORT KeProcessorArchitecture; USHORT KeProcessorLevel; USHORT KeProcessorRevision; -ULONG KeFeatureBits; -KAFFINITY KeActiveProcessors = 1; +ULONG64 KeFeatureBits; /* System call count */ ULONG KiServiceLimit = NUMBER_OF_SYSCALLS; @@ -31,9 +30,6 @@ PLOADER_PARAMETER_BLOCK KeLoaderBlock; /* PRCB Array */ PKPRCB KiProcessorBlock[MAXIMUM_PROCESSORS]; -/* Number of processors */ -CCHAR KeNumberProcessors = 0; - /* NUMA Node Support */ KNODE KiNode0; PKNODE KeNodeBlock[1] = { &KiNode0 }; diff --git a/ntoskrnl/ke/processor.c b/ntoskrnl/ke/processor.c new file mode 100644 index 0000000000000..48e6b11fe6d88 --- /dev/null +++ b/ntoskrnl/ke/processor.c @@ -0,0 +1,44 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: Portable processor related routines + * COPYRIGHT: Copyright 2025 Timo Kreuzer + */ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +/* GLOBALS *******************************************************************/ + +KAFFINITY KeActiveProcessors = 0; + +/* Number of processors */ +CCHAR KeNumberProcessors = 0; + +#ifdef CONFIG_SMP + +/* Theoretical maximum number of processors that can be handled. + * Set once at run-time. Returned by KeQueryMaximumProcessorCount(). */ +ULONG KeMaximumProcessors = MAXIMUM_PROCESSORS; + +/* Maximum number of logical processors that can be started + * (including dynamically) at run-time. If 0: do not perform checks. */ +ULONG KeNumprocSpecified = 0; + +/* Maximum number of logical processors that can be started + * at boot-time. If 0: do not perform checks. */ +ULONG KeBootprocSpecified = 0; + +#endif // CONFIG_SMP + +/* FUNCTIONS *****************************************************************/ + +KAFFINITY +NTAPI +KeQueryActiveProcessors(VOID) +{ + return KeActiveProcessors; +} diff --git a/ntoskrnl/ke/thrdobj.c b/ntoskrnl/ke/thrdobj.c index 6fca3821411b7..f1069e09d0bb9 100644 --- a/ntoskrnl/ke/thrdobj.c +++ b/ntoskrnl/ke/thrdobj.c @@ -1119,29 +1119,10 @@ KeSetSystemAffinityThread(IN KAFFINITY Affinity) CurrentThread->Affinity = Affinity; CurrentThread->SystemAffinityActive = TRUE; - /* Check if the ideal processor is part of the affinity */ #ifdef CONFIG_SMP - if (!(Affinity & AFFINITY_MASK(CurrentThread->IdealProcessor))) - { - KAFFINITY AffinitySet, NodeMask; - ULONG IdealProcessor; - - /* It's not! Get the PRCB */ - Prcb = KiProcessorBlock[CurrentThread->IdealProcessor]; - - /* Calculate the affinity set */ - AffinitySet = KeActiveProcessors & Affinity; - NodeMask = Prcb->ParentNode->ProcessorMask & AffinitySet; - if (NodeMask) - { - /* Use the Node set instead */ - AffinitySet = NodeMask; - } - - /* Calculate the ideal CPU from the affinity set */ - BitScanReverseAffinity(&IdealProcessor, AffinitySet); - CurrentThread->IdealProcessor = (UCHAR)IdealProcessor; - } + /* Calculate the ideal processor from the affinity set */ + CurrentThread->IdealProcessor = + KiFindIdealProcessor(Affinity, CurrentThread->IdealProcessor); #endif /* Get the current PRCB and check if it doesn't match this affinity */ diff --git a/ntoskrnl/ke/thrdschd.c b/ntoskrnl/ke/thrdschd.c index 40801ff5beedd..fbc56277c951e 100644 --- a/ntoskrnl/ke/thrdschd.c +++ b/ntoskrnl/ke/thrdschd.c @@ -74,13 +74,84 @@ KiQueueReadyThread(IN PKTHREAD Thread, KxQueueReadyThread(Thread, Prcb); } +#ifdef CONFIG_SMP +ULONG +NTAPI +KiFindIdealProcessor( + _In_ KAFFINITY ProcessorSet, + _In_ UCHAR OriginalIdealProcessor) +{ + PKPRCB OriginalIdealPrcb; + KAFFINITY NodeMask; + ULONG Processor; + + /* Check if we can use the original ideal processor */ + if (ProcessorSet & AFFINITY_MASK(OriginalIdealProcessor)) + { + /* We can, so use it */ + return OriginalIdealProcessor; + } + + /* Only use active processors */ + ProcessorSet &= KeActiveProcessors; + + /* Get the original ideal PRCB */ + OriginalIdealPrcb = KiProcessorBlock[OriginalIdealProcessor]; + + /* Check if we can use the original node */ + NodeMask = OriginalIdealPrcb->ParentNode->ProcessorMask & ProcessorSet; + if (NodeMask) + { + /* Use the node set instead */ + ProcessorSet = NodeMask; + } + + /* Calculate the ideal CPU from the affinity set */ + BitScanReverseAffinity(&Processor, ProcessorSet); + return Processor; +} + +static +ULONG +KiSelectNextProcessor( + _In_ PKTHREAD Thread) +{ + KAFFINITY PreferredSet, IdleSet; + ULONG Processor; + + /* Start with the affinity */ + PreferredSet = Thread->Affinity; + + /* If we have matching idle processors, use them */ + IdleSet = PreferredSet & KiIdleSummary; + if (IdleSet != 0) + { + PreferredSet = IdleSet; + } + + /* Check if we can use the ideal processor */ + if (PreferredSet & AFFINITY_MASK(Thread->IdealProcessor)) + { + return Thread->IdealProcessor; + } + + /* Return the first set bit */ + NT_VERIFY(BitScanForwardAffinity(&Processor, PreferredSet) != FALSE); + ASSERT(Processor < KeNumberProcessors); + + return Processor; +} +#else +#define KiSelectNextProcessor(Thread) 0 +#endif + VOID FASTCALL KiDeferredReadyThread(IN PKTHREAD Thread) { PKPRCB Prcb; BOOLEAN Preempted; - ULONG Processor = 0; + ULONG Processor; KPRIORITY OldPriority; PKTHREAD NextThread; @@ -228,11 +299,15 @@ KiDeferredReadyThread(IN PKTHREAD Thread) OldPriority = Thread->Priority; Thread->Preempted = FALSE; - /* Queue the thread on CPU 0 and get the PRCB and lock it */ - Thread->NextProcessor = 0; - Prcb = KiProcessorBlock[0]; + /* Select a processor to run on */ + Processor = KiSelectNextProcessor(Thread); + Thread->NextProcessor = Processor; + + /* Get the PRCB and lock it */ + Prcb = KiProcessorBlock[Processor]; KiAcquirePrcbLock(Prcb); +#ifndef CONFIG_SMP /* Check if we have an idle summary */ if (KiIdleSummary) { @@ -245,9 +320,7 @@ KiDeferredReadyThread(IN PKTHREAD Thread) KiReleasePrcbLock(Prcb); return; } - - /* Set the CPU number */ - Thread->NextProcessor = (UCHAR)Processor; +#endif // !CONFIG_SMP /* Get the next scheduled thread */ NextThread = Prcb->NextThread; @@ -341,12 +414,12 @@ KiSelectNextThread(IN PKPRCB Prcb) Prcb->IdleSchedule = TRUE; /* FIXME: SMT support */ - ASSERTMSG("SMP: Not yet implemented\n", FALSE); + //ASSERTMSG("SMP: Not yet implemented\n", FALSE); } /* Sanity checks and return the thread */ ASSERT(Thread != NULL); - ASSERT((Thread->BasePriority == 0) || (Thread->Priority != 0)); + //ASSERT((Thread->BasePriority == 0) || (Thread->Priority != 0)); return Thread; } @@ -680,6 +753,73 @@ KiSetPriorityThread(IN PKTHREAD Thread, } } +#ifdef CONFIG_SMP +static +VOID +KiUpdateEffectiveAffinityThread( + _In_ PKTHREAD Thread) +{ + PKPRCB Prcb; + + /* Acquire the thread lock */ + KiAcquireThreadLock(Thread); + + /* Get the PRCB that the thread is to be run on and lock it */ + Prcb = KiProcessorBlock[Thread->NextProcessor]; + KiAcquirePrcbLock(Prcb); + + /* Set the thread's affinity and ideal processor */ + Thread->Affinity = Thread->UserAffinity; + Thread->IdealProcessor = Thread->UserIdealProcessor; + + /* Check if the affinity doesn't match with the current processor */ + if ((Prcb->SetMember & Thread->Affinity) == 0) + { + if (Thread->State == Running) + { + /* Check if there is the next thread is selected already */ + if (Prcb->NextThread == NULL) + { + /* It is not, select a new thread and set it on standby */ + Prcb->NextThread = KiSelectNextThread(Prcb); + Prcb->NextThread->State = Standby; + } + + /* Check if the thread is running on a different processor */ + if (Prcb != KeGetCurrentPrcb()) + { + /* It is, send an IPI */ + KiIpiSend(AFFINITY_MASK(Thread->NextProcessor), IPI_DPC); + } + } + else if (Thread->State == Standby) + { + /* Select a new thread and set it on standby */ + Prcb->NextThread = KiSelectNextThread(Prcb); + Prcb->NextThread->State = Standby; + + /* Insert the thread back into the ready list */ + KiInsertDeferredReadyList(Thread); + } + else if (Thread->State == Ready) + { + /* Remove it from the list */ + if (RemoveEntryList(&Thread->WaitListEntry)) + { + /* The list is empty now, reset the ready summary */ + Prcb->ReadySummary &= ~PRIORITY_MASK(Thread->Priority); + } + + /* Insert the thread back into the ready list */ + KiInsertDeferredReadyList(Thread); + } + } + + KiReleasePrcbLock(Prcb); + KiReleaseThreadLock(Thread); +} +#endif // CONFIG_SMP + KAFFINITY FASTCALL KiSetAffinityThread(IN PKTHREAD Thread, @@ -701,14 +841,18 @@ KiSetAffinityThread(IN PKTHREAD Thread, /* Update the new affinity */ Thread->UserAffinity = Affinity; - /* Check if system affinity is disabled */ +#ifdef CONFIG_SMP + /* Check if system affinity is not active */ if (!Thread->SystemAffinityActive) { -#ifdef CONFIG_SMP - /* FIXME: TODO */ - DPRINT1("Affinity support disabled!\n"); -#endif + /* Calculate the new ideal processor from the affinity set */ + Thread->UserIdealProcessor = + KiFindIdealProcessor(Affinity, Thread->UserIdealProcessor); + + /* Update the effective affinity */ + KiUpdateEffectiveAffinityThread(Thread); } +#endif /* Return the old affinity */ return OldAffinity; @@ -722,8 +866,7 @@ KiSetAffinityThread(IN PKTHREAD Thread, // that could happen, Windows seems to define this as a macro that directly acceses // the ready summary through a single fs: read by going through the KPCR's PrcbData. // -// See http://research.microsoft.com/en-us/collaboration/global/asia-pacific/ -// programs/trk_case4_process-thread_management.pdf +// See http://research.microsoft.com/en-us/collaboration/global/asia-pacific/programs/trk_case4_process-thread_management.pdf (DEAD_LINK) // // We need this per-arch because sometimes it's Prcb and sometimes PrcbData, and // because on x86 it's FS, and on x64 it's GS (not sure what it is on ARM/PPC). diff --git a/ntoskrnl/ke/time.c b/ntoskrnl/ke/time.c index 09b61f0007d06..cb10259bb6529 100644 --- a/ntoskrnl/ke/time.c +++ b/ntoskrnl/ke/time.c @@ -77,7 +77,10 @@ KeUpdateSystemTime(IN PKTRAP_FRAME TrapFrame, /* Increase interrupt count and end the interrupt */ Prcb->InterruptCount++; + +#ifdef _M_IX86 // x86 optimization KiEndInterrupt(Irql, TrapFrame); +#endif /* Note: non-x86 return back to the caller! */ return; @@ -131,8 +134,10 @@ KeUpdateSystemTime(IN PKTRAP_FRAME TrapFrame, Prcb->InterruptCount++; } +#ifdef _M_IX86 // x86 optimization /* Disable interrupts and end the interrupt */ KiEndInterrupt(Irql, TrapFrame); +#endif } VOID diff --git a/ntoskrnl/mm/ARM3/i386/init.c b/ntoskrnl/mm/ARM3/i386/init.c index 4ad52cf2b805b..143a6705b17c5 100644 --- a/ntoskrnl/mm/ARM3/i386/init.c +++ b/ntoskrnl/mm/ARM3/i386/init.c @@ -562,7 +562,7 @@ MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock) { /* Mark the 1st IDT page as Write-Through to prevent a lockup on a F00F instruction. - See http://www.rcollins.org/Errata/Dec97/F00FBug.html */ + See https://www.rcollins.org/Errata/Dec97/F00FBug.html */ PointerPte = MiAddressToPte(KeGetPcr()->IDT); PointerPte->u.Hard.WriteThrough = 1; } diff --git a/ntoskrnl/mm/ARM3/mmdbg.c b/ntoskrnl/mm/ARM3/mmdbg.c index c47b8cfe1562d..316b43e1df88d 100644 --- a/ntoskrnl/mm/ARM3/mmdbg.c +++ b/ntoskrnl/mm/ARM3/mmdbg.c @@ -132,7 +132,15 @@ MmDbgCopyMemory(IN ULONG64 Address, PVOID CopyDestination, CopySource; /* No local kernel debugging support yet, so don't worry about locking */ - ASSERT(Flags & MMDBG_COPY_UNSAFE); + if (!(Flags & MMDBG_COPY_UNSAFE)) + { + static BOOLEAN Warned = FALSE; + if (!Warned) + { + KdpDprintf("MmDbgCopyMemory: not providing MMDBG_COPY_UNSAFE is UNIMPLEMENTED\n"); + Warned = TRUE; + } + } /* We only handle 1, 2, 4 and 8 byte requests */ if ((Size != 1) && diff --git a/ntoskrnl/mm/ARM3/mminit.c b/ntoskrnl/mm/ARM3/mminit.c index bd5ab3caa8836..c35669cbb43d5 100644 --- a/ntoskrnl/mm/ARM3/mminit.c +++ b/ntoskrnl/mm/ARM3/mminit.c @@ -33,7 +33,7 @@ PFN_NUMBER MmMaximumNonPagedPoolInPages; // These numbers describe the discrete equation components of the nonpaged // pool sizing algorithm. // -// They are described on http://support.microsoft.com/default.aspx/kb/126402/ja +// They are described on http://support.microsoft.com/default.aspx/kb/126402/ja (DEAD_LINK) // along with the algorithm that uses them, which is implemented later below. // SIZE_T MmMinimumNonPagedPoolSize = 256 * 1024; @@ -91,7 +91,7 @@ ULONG MmMaxAdditionNonPagedPoolPerMb = 400 * 1024; // The following URLs, valid as of April 23rd, 2008, support this evidence: // // http://www.cs.miami.edu/~burt/journal/NT/memory.html -// http://www.ditii.com/2007/09/28/windows-memory-management-x86-virtual-address-space/ +// https://web.archive.org/web/20130412053421/http://www.ditii.com/2007/09/28/windows-memory-management-x86-virtual-address-space/ // PVOID MmNonPagedSystemStart; PVOID MmNonPagedPoolStart; @@ -421,20 +421,14 @@ MiScanMemoryDescriptors(IN PLOADER_PARAMETER_BLOCK LoaderBlock) /* Count this descriptor */ MiNumberDescriptors++; - /* Check if this is invisible memory */ - if ((Descriptor->MemoryType == LoaderFirmwarePermanent) || - (Descriptor->MemoryType == LoaderSpecialMemory) || - (Descriptor->MemoryType == LoaderHALCachedMemory) || - (Descriptor->MemoryType == LoaderBBTMemory)) - { - /* Skip this descriptor */ + /* If this is invisible memory, skip this descriptor */ + if (MiIsMemoryTypeInvisible(Descriptor->MemoryType)) continue; - } - /* Check if this is bad memory */ + /* Check if this isn't bad memory */ if (Descriptor->MemoryType != LoaderBad) { - /* Count this in the total of pages */ + /* Count it in the physical pages */ MmNumberOfPhysicalPages += (PFN_COUNT)Descriptor->PageCount; } @@ -454,12 +448,9 @@ MiScanMemoryDescriptors(IN PLOADER_PARAMETER_BLOCK LoaderBlock) } /* Check if this is free memory */ - if ((Descriptor->MemoryType == LoaderFree) || - (Descriptor->MemoryType == LoaderLoadedProgram) || - (Descriptor->MemoryType == LoaderFirmwareTemporary) || - (Descriptor->MemoryType == LoaderOsloaderStack)) + if (MiIsMemoryTypeFree(Descriptor->MemoryType)) { - /* Count it too free pages */ + /* Count it in the free pages */ MiNumberOfFreePages += Descriptor->PageCount; /* Check if this is the largest memory descriptor */ diff --git a/ntoskrnl/mm/ARM3/pagfault.c b/ntoskrnl/mm/ARM3/pagfault.c index 62451086ddade..52cf4d900be8c 100644 --- a/ntoskrnl/mm/ARM3/pagfault.c +++ b/ntoskrnl/mm/ARM3/pagfault.c @@ -102,6 +102,14 @@ MiCheckForUserStackOverflow(IN PVOID Address, { /* Success! */ Teb->NtTib.StackLimit = NextStackAddress; + +#ifdef _WIN64 + /* Update WOW64 32-bit TEB stack limit */ + if (CurrentThread->ThreadsProcess->Wow64Process != NULL) + { + ((PTEB32)(ROUND_TO_PAGES(Teb + 1)))->NtTib.StackLimit = PtrToUlong(Teb->NtTib.StackLimit); + } +#endif } else { @@ -117,6 +125,14 @@ MiCheckForUserStackOverflow(IN PVOID Address, /* Update the stack limit */ Teb->NtTib.StackLimit = (PVOID)((ULONG_PTR)NextStackAddress + GuaranteedSize); +#ifdef _WIN64 + /* Update WOW64 32-bit TEB stack limit */ + if (CurrentThread->ThreadsProcess->Wow64Process != NULL) + { + ((PTEB32)(ROUND_TO_PAGES(Teb + 1)))->NtTib.StackLimit = PtrToUlong(Teb->NtTib.StackLimit); + } +#endif + /* Now move the guard page to the next page */ Status = ZwAllocateVirtualMemory(NtCurrentProcess(), &NextStackAddress, diff --git a/ntoskrnl/mm/ARM3/procsup.c b/ntoskrnl/mm/ARM3/procsup.c index da94b64b7ec1a..861e2d70026dc 100644 --- a/ntoskrnl/mm/ARM3/procsup.c +++ b/ntoskrnl/mm/ARM3/procsup.c @@ -20,6 +20,7 @@ ULONG MmProcessColorSeed = 0x12345678; ULONG MmMaximumDeadKernelStacks = 5; SLIST_HEADER MmDeadStackSListHead; +ULONG MmRotatingUniprocessorNumber = 0; /* PRIVATE FUNCTIONS **********************************************************/ @@ -34,6 +35,13 @@ MiCreatePebOrTeb(IN PEPROCESS Process, ULONG_PTR HighestAddress, RandomBase; ULONG AlignedSize; LARGE_INTEGER CurrentTime; +#ifdef _WIN64 + BOOLEAN IsWow64; +#endif + BOOLEAN IsPeb; + + ASSERT(sizeof(TEB) != sizeof(PEB)); + IsPeb = (sizeof(PEB) == Size); Status = PsChargeProcessNonPagedPoolQuota(Process, sizeof(MMVAD_LONG)); if (!NT_SUCCESS(Status)) @@ -65,23 +73,51 @@ MiCreatePebOrTeb(IN PEPROCESS Process, Vad->ControlArea = NULL; // For Memory-Area hack Vad->FirstPrototypePte = NULL; + HighestAddress = (ULONG_PTR)MM_HIGHEST_VAD_ADDRESS; + +#ifdef _M_AMD64 + IsWow64 = FALSE; + + if (Process->SectionBaseAddress != NULL) + { + if (RtlImageNtHeader(Process->SectionBaseAddress)->FileHeader.Machine + != IMAGE_FILE_MACHINE_AMD64) + { + IsWow64 = TRUE; + } + } + + if (IsWow64) + { + /* Make sure the structure resides in the 32-bit address space */ + HighestAddress &= ROUND_DOWN(0xFFFFFFFFULL, PAGE_SIZE); + } +#endif + /* Check if this is a PEB creation */ - ASSERT(sizeof(TEB) != sizeof(PEB)); - if (Size == sizeof(PEB)) + if (IsPeb) { +#ifdef _WIN64 + /* If this is a WOW64 process, allocate enough space for the 32 bit PEB */ + if (IsWow64) + { + Size += ROUND_TO_PAGES(sizeof(PEB32)); + } +#endif + /* Create a random value to select one page in a 64k region */ KeQueryTickCount(&CurrentTime); CurrentTime.LowPart &= (_64K / PAGE_SIZE) - 1; /* Calculate a random base address */ - RandomBase = (ULONG_PTR)MM_HIGHEST_VAD_ADDRESS + 1; + RandomBase = HighestAddress + 1; RandomBase -= CurrentTime.LowPart << PAGE_SHIFT; /* Make sure the base address is not too high */ AlignedSize = ROUND_TO_PAGES(Size); - if ((RandomBase + AlignedSize) > (ULONG_PTR)MM_HIGHEST_VAD_ADDRESS + 1) + if ((RandomBase + AlignedSize) > HighestAddress + 1) { - RandomBase = (ULONG_PTR)MM_HIGHEST_VAD_ADDRESS + 1 - AlignedSize; + RandomBase = HighestAddress + 1 - AlignedSize; } /* Calculate the highest allowed address */ @@ -89,7 +125,13 @@ MiCreatePebOrTeb(IN PEPROCESS Process, } else { - HighestAddress = (ULONG_PTR)MM_HIGHEST_VAD_ADDRESS; +#ifdef _WIN64 + /* If this is a WOW64 process, allocate enough space for the 32 bit TEB */ + if (IsWow64) + { + Size += ROUND_TO_PAGES(sizeof(TEB32)); + } +#endif } *BaseAddress = 0; @@ -106,6 +148,12 @@ MiCreatePebOrTeb(IN PEPROCESS Process, goto FailPath; } +#ifdef _WIN64 + if (IsPeb && IsWow64) + { + Process->Wow64Process = (PVOID)TRUE; + } +#endif /* Success */ return STATUS_SUCCESS; @@ -130,6 +178,14 @@ MmDeleteTeb(IN PEPROCESS Process, /* TEB is one page */ TebEnd = (ULONG_PTR)Teb + ROUND_TO_PAGES(sizeof(TEB)) - 1; +#ifdef _WIN64 + /* If this is a WOW64 process, the TEB is followed by a TEB32 */ + if (Process->Wow64Process) + { + TebEnd += ROUND_TO_PAGES(sizeof(TEB32)); + } +#endif + /* Attach to the process */ KeAttachProcess(&Process->Pcb); @@ -526,7 +582,6 @@ MmCreatePeb(IN PEPROCESS Process, PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigData; NTSTATUS Status; USHORT Characteristics; - KAFFINITY ProcessAffinityMask = 0; SectionOffset.QuadPart = (ULONGLONG)0; *BasePeb = NULL; @@ -606,6 +661,7 @@ MmCreatePeb(IN PEPROCESS Process, // Heap and Debug Data // Peb->NumberOfProcessors = KeNumberProcessors; + Peb->ImageProcessAffinityMask = KeActiveProcessors; Peb->BeingDebugged = (BOOLEAN)(Process->DebugPort != NULL); Peb->NtGlobalFlag = NtGlobalFlag; Peb->HeapSegmentReserve = MmHeapSegmentReserve; @@ -712,7 +768,7 @@ MmCreatePeb(IN PEPROCESS Process, if ((ImageConfigData) && (ImageConfigData->ProcessAffinityMask)) { /* Take the value from the image configuration directory */ - ProcessAffinityMask = ImageConfigData->ProcessAffinityMask; + Peb->ImageProcessAffinityMask = ImageConfigData->ProcessAffinityMask; } // @@ -720,17 +776,12 @@ MmCreatePeb(IN PEPROCESS Process, if (Characteristics & IMAGE_FILE_UP_SYSTEM_ONLY) { // - // Force it to use CPU 0 - // - /* FIXME: this should use the MmRotatingUniprocessorNumber */ - Peb->ImageProcessAffinityMask = 0; - } - else - { - // - // Whatever was configured + // Set single processor rotating affinity. + // See https://www.microsoftpressstore.com/articles/article.aspx?p=2233328&seqNum=3 // - Peb->ImageProcessAffinityMask = ProcessAffinityMask; + Peb->ImageProcessAffinityMask = AFFINITY_MASK(MmRotatingUniprocessorNumber); + ASSERT(Peb->ImageProcessAffinityMask & KeActiveProcessors); + MmRotatingUniprocessorNumber = (MmRotatingUniprocessorNumber + 1) % KeNumberProcessors; } } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) diff --git a/ntoskrnl/mm/ARM3/special.c b/ntoskrnl/mm/ARM3/special.c index 6d40315bc0d53..b9744d153cb0e 100644 --- a/ntoskrnl/mm/ARM3/special.c +++ b/ntoskrnl/mm/ARM3/special.c @@ -8,7 +8,7 @@ /* References: - http://msdn.microsoft.com/en-us/library/ff551832(v=VS.85).aspx + https://learn.microsoft.com/en-us/windows-hardware/drivers/devtest/special-pool */ /* INCLUDES *******************************************************************/ diff --git a/ntoskrnl/mm/ARM3/sysldr.c b/ntoskrnl/mm/ARM3/sysldr.c index 2cdfc365cc701..aec54cd9cf155 100644 --- a/ntoskrnl/mm/ARM3/sysldr.c +++ b/ntoskrnl/mm/ARM3/sysldr.c @@ -2716,34 +2716,43 @@ MiEnablePagingOfDriver(IN PLDR_DATA_TABLE_ENTRY LdrEntry) if (PointerPte) MiSetPagingOfDriver(PointerPte, LastPte); } +#ifdef CONFIG_SMP +FORCEINLINE BOOLEAN -NTAPI -MmVerifyImageIsOkForMpUse(IN PVOID BaseAddress) +MiVerifyImageIsOkForMpUse( + _In_ PIMAGE_NT_HEADERS NtHeaders) { - PIMAGE_NT_HEADERS NtHeader; - PAGED_CODE(); - - /* Get NT Headers */ - NtHeader = RtlImageNtHeader(BaseAddress); - if (NtHeader) + /* Fail if we have more than one CPU, but the image is only safe for UP */ + if ((KeNumberProcessors > 1) && + (NtHeaders->FileHeader.Characteristics & IMAGE_FILE_UP_SYSTEM_ONLY)) { - /* Check if this image is only safe for UP while we have 2+ CPUs */ - if ((KeNumberProcessors > 1) && - (NtHeader->FileHeader.Characteristics & IMAGE_FILE_UP_SYSTEM_ONLY)) - { - /* Fail */ - return FALSE; - } + return FALSE; } - - /* Otherwise, it's safe */ + /* Otherwise, it's safe to use */ return TRUE; } +BOOLEAN +NTAPI +MmVerifyImageIsOkForMpUse( + _In_ PVOID BaseAddress) +{ + PIMAGE_NT_HEADERS NtHeaders; + PAGED_CODE(); + + /* Get the NT headers. If none, suppose the image is safe + * to use on an MP system, otherwise invoke the helper. */ + NtHeaders = RtlImageNtHeader(BaseAddress); + if (!NtHeaders) + return TRUE; + return MiVerifyImageIsOkForMpUse(NtHeaders); +} +#endif // CONFIG_SMP + NTSTATUS NTAPI -MmCheckSystemImage(IN HANDLE ImageHandle, - IN BOOLEAN PurgeSection) +MmCheckSystemImage( + _In_ HANDLE ImageHandle) { NTSTATUS Status; HANDLE SectionHandle; @@ -2837,12 +2846,14 @@ MmCheckSystemImage(IN HANDLE ImageHandle, goto Fail; } - /* Check that it's a valid SMP image if we have more then one CPU */ - if (!MmVerifyImageIsOkForMpUse(ViewBase)) +#ifdef CONFIG_SMP + /* Check that the image is safe to use if we have more than one CPU */ + if (!MiVerifyImageIsOkForMpUse(NtHeaders)) { /* Otherwise it's not the right image */ Status = STATUS_IMAGE_MP_UP_MISMATCH; } +#endif // CONFIG_SMP } /* Unmap the section, close the handle, and return status */ @@ -3171,7 +3182,7 @@ MmLoadSystemImage(IN PUNICODE_STRING FileName, } /* Validate it */ - Status = MmCheckSystemImage(FileHandle, FALSE); + Status = MmCheckSystemImage(FileHandle); if ((Status == STATUS_IMAGE_CHECKSUM_MISMATCH) || (Status == STATUS_IMAGE_MP_UP_MISMATCH) || (Status == STATUS_INVALID_IMAGE_PROTECT)) diff --git a/ntoskrnl/mm/balance.c b/ntoskrnl/mm/balance.c index 3b11aeab2c8ff..6e3c51f9dedb1 100644 --- a/ntoskrnl/mm/balance.c +++ b/ntoskrnl/mm/balance.c @@ -289,7 +289,7 @@ VOID NTAPI MmRebalanceMemoryConsumers(VOID) { - // if (InterlockedCompareExchange(&PageOutThreadActive, 0, 1) == 0) + if (InterlockedCompareExchange(&PageOutThreadActive, 1, 0) == 0) { KeSetEvent(&MiBalancerEvent, IO_NO_INCREMENT, FALSE); } @@ -314,10 +314,12 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait, PPFN_NUMBER AllocatedPage) { PFN_NUMBER Page; + + /* Delay some requests for the Memory Manager to recover pages (CORE-17624). + * FIXME: This is suboptimal. + */ static INT i = 0; static LARGE_INTEGER TinyTime = {{-1L, -1L}}; - - /* Delay some requests for the Memory Manager to recover pages */ if (i++ >= 100) { KeDelayExecutionThread(KernelMode, FALSE, &TinyTime); @@ -347,20 +349,20 @@ CcRosTrimCache( _In_ ULONG Target, _Out_ PULONG NrFreed); -VOID NTAPI +VOID +NTAPI MiBalancerThread(PVOID Unused) { PVOID WaitObjects[2]; NTSTATUS Status; - ULONG i; WaitObjects[0] = &MiBalancerEvent; WaitObjects[1] = &MiBalancerTimer; - while (1) + while (TRUE) { KeSetEvent(&MiBalancerDoneEvent, IO_NO_INCREMENT, FALSE); - Status = KeWaitForMultipleObjects(2, + Status = KeWaitForMultipleObjects(_countof(WaitObjects), WaitObjects, WaitAny, Executive, @@ -380,7 +382,7 @@ MiBalancerThread(PVOID Unused) ULONG OldTarget = InitialTarget; /* Trim each consumer */ - for (i = 0; i < MC_MAXIMUM; i++) + for (ULONG i = 0; i < MC_MAXIMUM; i++) { InitialTarget = MiTrimMemoryConsumer(i, InitialTarget); } @@ -395,7 +397,7 @@ MiBalancerThread(PVOID Unused) /* No pages left to swap! */ if (InitialTarget != 0 && - InitialTarget == OldTarget) + InitialTarget == OldTarget) { /* Game over */ KeBugCheck(NO_PAGES_AVAILABLE); @@ -404,7 +406,11 @@ MiBalancerThread(PVOID Unused) while (InitialTarget != 0); if (Status == STATUS_WAIT_0) - InterlockedDecrement(&PageOutThreadActive); + { + LONG Active = InterlockedExchange(&PageOutThreadActive, 0); + ASSERT(Active == 1); + DBG_UNREFERENCED_LOCAL_VARIABLE(Active); + } } else { diff --git a/ntoskrnl/mm/freelist.c b/ntoskrnl/mm/freelist.c index 6f2f99bfc3cc8..0147fb09a9009 100644 --- a/ntoskrnl/mm/freelist.c +++ b/ntoskrnl/mm/freelist.c @@ -318,7 +318,7 @@ MiAllocatePagesForMdl(IN PHYSICAL_ADDRESS LowAddress, // Get the PFN entry for this page // Pfn1 = MiGetPfnEntry(Page); - ASSERT(Pfn1); + if (!Pfn1) continue; // // Make sure it's free and if this is our first pass, zeroed diff --git a/ntoskrnl/mm/section.c b/ntoskrnl/mm/section.c index 73b414315fe38..d570dbc3cec0f 100644 --- a/ntoskrnl/mm/section.c +++ b/ntoskrnl/mm/section.c @@ -4876,7 +4876,7 @@ MmPurgeSegment( } /* Find byte offset of the page to start */ - PurgeStart.QuadPart = PAGE_ROUND_DOWN(PurgeStart.QuadPart); + PurgeStart.QuadPart = PAGE_ROUND_DOWN_64(PurgeStart.QuadPart); while (PurgeStart.QuadPart < PurgeEnd.QuadPart) { @@ -4947,7 +4947,7 @@ MmIsDataSectionResident( return FALSE; /* Find byte offset of the page to start */ - RangeStart.QuadPart = PAGE_ROUND_DOWN(RangeStart.QuadPart); + RangeStart.QuadPart = PAGE_ROUND_DOWN_64(RangeStart.QuadPart); MmLockSectionSegment(Segment); @@ -5010,7 +5010,7 @@ MmMakeSegmentDirty( return STATUS_NOT_MAPPED_VIEW; /* Find byte offset of the page to start */ - RangeStart.QuadPart = PAGE_ROUND_DOWN(RangeStart.QuadPart); + RangeStart.QuadPart = PAGE_ROUND_DOWN_64(RangeStart.QuadPart); MmLockSectionSegment(Segment); @@ -5098,7 +5098,7 @@ MmFlushSegment( } /* Find byte offset of the page to start */ - FlushStart.QuadPart = PAGE_ROUND_DOWN(FlushStart.QuadPart); + FlushStart.QuadPart = PAGE_ROUND_DOWN_64(FlushStart.QuadPart); while (FlushStart.QuadPart < FlushEnd.QuadPart) { diff --git a/ntoskrnl/ntkrnlmp/CMakeLists.txt b/ntoskrnl/ntkrnlmp/CMakeLists.txt index a56ec6ce8e382..da4677de0a035 100644 --- a/ntoskrnl/ntkrnlmp/CMakeLists.txt +++ b/ntoskrnl/ntkrnlmp/CMakeLists.txt @@ -10,6 +10,16 @@ endif() add_asm_files(ntkrnlmp_asm ${NTKRNLMP_ASM_SOURCE}) +if(ARCH STREQUAL "i386") + list(APPEND NTKRNLMP_SOURCE + ${REACTOS_SOURCE_DIR}/ntoskrnl/ke/i386/mproc.c) +elseif(ARCH STREQUAL "amd64") + list(APPEND NTKRNLMP_SOURCE + ${REACTOS_SOURCE_DIR}/ntoskrnl/ke/amd64/mproc.c) +elseif(ARCH STREQUAL "arm") + #TBD +endif() + list(APPEND NTKRNLMP_PCH_SKIP_SOURCE ${REACTOS_SOURCE_DIR}/ntoskrnl/guid.c) diff --git a/ntoskrnl/ntos.cmake b/ntoskrnl/ntos.cmake index 082f61216c5a3..65e8b743f790c 100644 --- a/ntoskrnl/ntos.cmake +++ b/ntoskrnl/ntos.cmake @@ -186,6 +186,7 @@ list(APPEND SOURCE ${REACTOS_SOURCE_DIR}/ntoskrnl/ke/ipi.c ${REACTOS_SOURCE_DIR}/ntoskrnl/ke/krnlinit.c ${REACTOS_SOURCE_DIR}/ntoskrnl/ke/mutex.c + ${REACTOS_SOURCE_DIR}/ntoskrnl/ke/processor.c ${REACTOS_SOURCE_DIR}/ntoskrnl/ke/procobj.c ${REACTOS_SOURCE_DIR}/ntoskrnl/ke/profobj.c ${REACTOS_SOURCE_DIR}/ntoskrnl/ke/queue.c @@ -333,10 +334,6 @@ if(ARCH STREQUAL "i386") ${REACTOS_SOURCE_DIR}/ntoskrnl/ps/i386/psldt.c ${REACTOS_SOURCE_DIR}/ntoskrnl/vdm/vdmmain.c ${REACTOS_SOURCE_DIR}/ntoskrnl/vdm/vdmexec.c) - if(BUILD_MP) - list(APPEND SOURCE - ${REACTOS_SOURCE_DIR}/ntoskrnl/ke/i386/mproc.c) - endif() elseif(ARCH STREQUAL "amd64") list(APPEND ASM_SOURCE ${REACTOS_SOURCE_DIR}/ntoskrnl/ke/amd64/boot.S @@ -365,10 +362,6 @@ elseif(ARCH STREQUAL "amd64") ${REACTOS_SOURCE_DIR}/ntoskrnl/ke/amd64/stubs.c ${REACTOS_SOURCE_DIR}/ntoskrnl/ke/amd64/traphandler.c ${REACTOS_SOURCE_DIR}/ntoskrnl/ke/amd64/usercall.c) - if(BUILD_MP) - list(APPEND SOURCE - ${REACTOS_SOURCE_DIR}/ntoskrnl/ke/amd64/mproc.c) - endif() elseif(ARCH STREQUAL "arm") list(APPEND ASM_SOURCE ${REACTOS_SOURCE_DIR}/ntoskrnl/ex/arm/ioport.s diff --git a/ntoskrnl/ntoskrnl.spec b/ntoskrnl/ntoskrnl.spec index 4d5bf883c601b..6e44fb2c140aa 100644 --- a/ntoskrnl/ntoskrnl.spec +++ b/ntoskrnl/ntoskrnl.spec @@ -1309,7 +1309,7 @@ @ stdcall RtlUnicodeToOemN(ptr long ptr wstr long) @ stdcall RtlUnlockBootStatusData(ptr) @ stdcall RtlUnwind(ptr ptr ptr ptr) -@ cdecl -arch=x86_64 RtlUnwindEx(double double ptr ptr ptr ptr) +@ stdcall -arch=x86_64,arm RtlUnwindEx(ptr ptr ptr ptr ptr ptr) @ stdcall RtlUpcaseUnicodeChar(long) @ stdcall RtlUpcaseUnicodeString(ptr ptr long) @ stdcall RtlUpcaseUnicodeStringToAnsiString(ptr ptr long) @@ -1325,7 +1325,7 @@ @ stdcall RtlValidSecurityDescriptor(ptr) @ stdcall RtlValidSid(ptr) @ stdcall RtlVerifyVersionInfo(ptr long long long) -@ cdecl -arch=x86_64 RtlVirtualUnwind(long double double ptr ptr ptr ptr ptr) +@ stdcall -arch=x86_64,arm RtlVirtualUnwind(long int64 int64 ptr ptr ptr ptr ptr) @ stdcall RtlVolumeDeviceToDosName(ptr ptr) IoVolumeDeviceToDosName @ stdcall RtlWalkFrameChain(ptr long long) @ stdcall RtlWriteRegistryValue(long wstr wstr long ptr long) diff --git a/ntoskrnl/ob/obdir.c b/ntoskrnl/ob/obdir.c index 3f3bc492c11ab..f566c995ee49b 100644 --- a/ntoskrnl/ob/obdir.c +++ b/ntoskrnl/ob/obdir.c @@ -158,7 +158,7 @@ NTAPI ObpLookupEntryDirectory(IN POBJECT_DIRECTORY Directory, IN PUNICODE_STRING Name, IN ULONG Attributes, - IN UCHAR SearchShadow, + IN BOOLEAN SearchShadow, IN POBP_LOOKUP_CONTEXT Context) { BOOLEAN CaseInsensitive = FALSE; diff --git a/ntoskrnl/ob/obname.c b/ntoskrnl/ob/obname.c index 5c829327c14bb..de0ac79053eea 100644 --- a/ntoskrnl/ob/obname.c +++ b/ntoskrnl/ob/obname.c @@ -15,7 +15,7 @@ #define NDEBUG #include -BOOLEAN ObpCaseInsensitive = TRUE; +ULONG ObpCaseInsensitive = TRUE; POBJECT_DIRECTORY ObpRootDirectoryObject; POBJECT_DIRECTORY ObpTypeDirectoryObject; diff --git a/ntoskrnl/ps/apphelp.c b/ntoskrnl/ps/apphelp.c index 91cd277cb048b..2f2dd9a68776f 100644 --- a/ntoskrnl/ps/apphelp.c +++ b/ntoskrnl/ps/apphelp.c @@ -10,12 +10,12 @@ /* Useful references: https://github.com/mandiant/ShimCacheParser/blob/master/ShimCacheParser.py -http://technet.microsoft.com/en-us/library/dd837644(v=ws.10).aspx -http://msdn.microsoft.com/en-us/library/bb432182(v=vs.85).aspx -http://www.alex-ionescu.com/?p=43 -http://recxltd.blogspot.nl/2012/04/windows-appcompat-research-notes-part-1.html -http://journeyintoir.blogspot.ch/2013/12/revealing-recentfilecachebcf-file.html -https://dl.mandiant.com/EE/library/Whitepaper_ShimCacheParser.pdf +https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-7/dd837644(v=ws.10) +https://learn.microsoft.com/en-us/windows/win32/devnotes/application-compatibility-database +https://www.alex-ionescu.com/secrets-of-the-application-compatilibity-database-sdb-part-4/ +https://web.archive.org/web/20170101173150/http://recxltd.blogspot.nl/2012/04/windows-appcompat-research-notes-part-1.html +http://journeyintoir.blogspot.com/2013/12/revealing-recentfilecachebcf-file.html +https://web.archive.org/web/20150926070918/https://dl.mandiant.com/EE/library/Whitepaper_ShimCacheParser.pdf */ /* INCLUDES ******************************************************************/ diff --git a/ntoskrnl/ps/kill.c b/ntoskrnl/ps/kill.c index 4a74649248660..7f29e537e7183 100644 --- a/ntoskrnl/ps/kill.c +++ b/ntoskrnl/ps/kill.c @@ -378,6 +378,17 @@ PspDeleteProcess(IN PVOID ObjectBody) /* Dereference the Device Map */ ObDereferenceDeviceMap(Process); +#ifdef _WIN64 + /* Check if this is a WOW64 process */ + if (Process->Wow64Process && Process->Wow64Process != (PVOID)TRUE) + { + /* Free WOW64_PROCESS structure */ + ExFreePool(Process->Wow64Process); + + PsReturnProcessNonPagedPoolQuota(Process, sizeof(WOW64_PROCESS)); + } +#endif + /* * Dereference the quota block, the function * will invoke a quota block cleanup if the diff --git a/ntoskrnl/ps/psmgr.c b/ntoskrnl/ps/psmgr.c index bd642375a88e7..0d80257bd46cd 100644 --- a/ntoskrnl/ps/psmgr.c +++ b/ntoskrnl/ps/psmgr.c @@ -196,7 +196,7 @@ PsLocateSystemDll(VOID) /* Locate and open NTDLL to determine ImageBase and LdrStartup */ InitializeObjectAttributes(&ObjectAttributes, &PsNtDllPathName, - 0, + OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); Status = ZwOpenFile(&FileHandle, @@ -212,8 +212,8 @@ PsLocateSystemDll(VOID) } /* Check if the image is valid */ - Status = MmCheckSystemImage(FileHandle, TRUE); - if (Status == STATUS_IMAGE_CHECKSUM_MISMATCH) + Status = MmCheckSystemImage(FileHandle); + if (Status == STATUS_IMAGE_CHECKSUM_MISMATCH || Status == STATUS_INVALID_IMAGE_PROTECT) { /* Raise a hard error */ HardErrorParameters = (ULONG_PTR)&PsNtDllPathName; diff --git a/ntoskrnl/ps/query.c b/ntoskrnl/ps/query.c index cc7bae50ba46f..ae3c425467e11 100644 --- a/ntoskrnl/ps/query.c +++ b/ntoskrnl/ps/query.c @@ -67,23 +67,7 @@ NtQueryInformationProcess( KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); NTSTATUS Status; ULONG Length = 0; - HANDLE DebugPort = 0; - PPROCESS_BASIC_INFORMATION ProcessBasicInfo = - (PPROCESS_BASIC_INFORMATION)ProcessInformation; - PKERNEL_USER_TIMES ProcessTime = (PKERNEL_USER_TIMES)ProcessInformation; - ULONG UserTime, KernelTime; - PPROCESS_PRIORITY_CLASS PsPriorityClass = (PPROCESS_PRIORITY_CLASS)ProcessInformation; - ULONG HandleCount; - PPROCESS_SESSION_INFORMATION SessionInfo = - (PPROCESS_SESSION_INFORMATION)ProcessInformation; - PVM_COUNTERS VmCounters = (PVM_COUNTERS)ProcessInformation; - PIO_COUNTERS IoCounters = (PIO_COUNTERS)ProcessInformation; - PQUOTA_LIMITS QuotaLimits = (PQUOTA_LIMITS)ProcessInformation; - PUNICODE_STRING ImageName; - ULONG Cookie, ExecuteOptions = 0; - ULONG_PTR Wow64 = 0; - PROCESS_VALUES ProcessValues; - ULONG Flags; + PAGED_CODE(); /* Verify Information Class validity */ @@ -119,6 +103,8 @@ NtQueryInformationProcess( { /* Basic process information */ case ProcessBasicInformation: + { + PPROCESS_BASIC_INFORMATION ProcessBasicInfo = (PPROCESS_BASIC_INFORMATION)ProcessInformation; if (ProcessInformationLength != sizeof(PROCESS_BASIC_INFORMATION)) { @@ -162,17 +148,24 @@ NtQueryInformationProcess( /* Dereference the process */ ObDereferenceObject(Process); break; + } /* Process quota limits */ case ProcessQuotaLimits: + { + QUOTA_LIMITS_EX QuotaLimits; + BOOLEAN Extended; - if (ProcessInformationLength != sizeof(QUOTA_LIMITS)) + if (ProcessInformationLength != sizeof(QUOTA_LIMITS) && + ProcessInformationLength != sizeof(QUOTA_LIMITS_EX)) { Status = STATUS_INFO_LENGTH_MISMATCH; break; } - Length = sizeof(QUOTA_LIMITS); + /* Set return length */ + Length = ProcessInformationLength; + Extended = (Length == sizeof(QUOTA_LIMITS_EX)); /* Reference the process */ Status = ObReferenceObjectByHandle(ProcessHandle, @@ -186,36 +179,53 @@ NtQueryInformationProcess( /* Indicate success */ Status = STATUS_SUCCESS; - _SEH2_TRY + RtlZeroMemory(&QuotaLimits, sizeof(QuotaLimits)); + + /* Get max/min working set sizes */ + QuotaLimits.MaximumWorkingSetSize = + Process->Vm.MaximumWorkingSetSize << PAGE_SHIFT; + QuotaLimits.MinimumWorkingSetSize = + Process->Vm.MinimumWorkingSetSize << PAGE_SHIFT; + + /* Get default time limits */ + QuotaLimits.TimeLimit.QuadPart = -1LL; + + /* Is quota block a default one? */ + if (Process->QuotaBlock == &PspDefaultQuotaBlock) { - /* Set max/min working set sizes */ - QuotaLimits->MaximumWorkingSetSize = - Process->Vm.MaximumWorkingSetSize << PAGE_SHIFT; - QuotaLimits->MinimumWorkingSetSize = - Process->Vm.MinimumWorkingSetSize << PAGE_SHIFT; + /* Get default pools and pagefile limits */ + QuotaLimits.PagedPoolLimit = (SIZE_T)-1; + QuotaLimits.NonPagedPoolLimit = (SIZE_T)-1; + QuotaLimits.PagefileLimit = (SIZE_T)-1; + } + else + { + /* Get limits from non-default quota block */ + QuotaLimits.PagedPoolLimit = + Process->QuotaBlock->QuotaEntry[PsPagedPool].Limit; + QuotaLimits.NonPagedPoolLimit = + Process->QuotaBlock->QuotaEntry[PsNonPagedPool].Limit; + QuotaLimits.PagefileLimit = + Process->QuotaBlock->QuotaEntry[PsPageFile].Limit; + } - /* Set default time limits */ - QuotaLimits->TimeLimit.LowPart = MAXULONG; - QuotaLimits->TimeLimit.HighPart = MAXULONG; + /* Get additional information, if needed */ + if (Extended) + { + QuotaLimits.Flags |= (Process->Vm.Flags.MaximumWorkingSetHard ? + QUOTA_LIMITS_HARDWS_MAX_ENABLE : QUOTA_LIMITS_HARDWS_MAX_DISABLE); + QuotaLimits.Flags |= (Process->Vm.Flags.MinimumWorkingSetHard ? + QUOTA_LIMITS_HARDWS_MIN_ENABLE : QUOTA_LIMITS_HARDWS_MIN_DISABLE); - /* Is quota block a default one? */ - if (Process->QuotaBlock == &PspDefaultQuotaBlock) - { - /* Set default pools and pagefile limits */ - QuotaLimits->PagedPoolLimit = (SIZE_T)-1; - QuotaLimits->NonPagedPoolLimit = (SIZE_T)-1; - QuotaLimits->PagefileLimit = (SIZE_T)-1; - } - else - { - /* Get limits from non-default quota block */ - QuotaLimits->PagedPoolLimit = - Process->QuotaBlock->QuotaEntry[PsPagedPool].Limit; - QuotaLimits->NonPagedPoolLimit = - Process->QuotaBlock->QuotaEntry[PsNonPagedPool].Limit; - QuotaLimits->PagefileLimit = - Process->QuotaBlock->QuotaEntry[PsPageFile].Limit; - } + /* FIXME: Get the correct information */ + //QuotaLimits.WorkingSetLimit = (SIZE_T)-1; // Not used on Win2k3, it is set to 0 + QuotaLimits.CpuRateLimit.RateData = 0; + } + + /* Protect writes with SEH */ + _SEH2_TRY + { + RtlCopyMemory(ProcessInformation, &QuotaLimits, Length); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { @@ -227,8 +237,12 @@ NtQueryInformationProcess( /* Dereference the process */ ObDereferenceObject(Process); break; + } case ProcessIoCounters: + { + PIO_COUNTERS IoCounters = (PIO_COUNTERS)ProcessInformation; + PROCESS_VALUES ProcessValues; if (ProcessInformationLength != sizeof(IO_COUNTERS)) { @@ -266,9 +280,13 @@ NtQueryInformationProcess( /* Dereference the process */ ObDereferenceObject(Process); break; + } /* Timing */ case ProcessTimes: + { + PKERNEL_USER_TIMES ProcessTime = (PKERNEL_USER_TIMES)ProcessInformation; + ULONG UserTime, KernelTime; /* Set the return length */ if (ProcessInformationLength != sizeof(KERNEL_USER_TIMES)) @@ -308,6 +326,7 @@ NtQueryInformationProcess( /* Dereference the process */ ObDereferenceObject(Process); break; + } /* Process Debug Port */ case ProcessDebugPort: @@ -349,6 +368,8 @@ NtQueryInformationProcess( break; case ProcessHandleCount: + { + ULONG HandleCount; if (ProcessInformationLength != sizeof(ULONG)) { @@ -387,9 +408,12 @@ NtQueryInformationProcess( /* Dereference the process */ ObDereferenceObject(Process); break; + } /* Session ID for the process */ case ProcessSessionInformation: + { + PPROCESS_SESSION_INFORMATION SessionInfo = (PPROCESS_SESSION_INFORMATION)ProcessInformation; if (ProcessInformationLength != sizeof(PROCESS_SESSION_INFORMATION)) { @@ -425,9 +449,12 @@ NtQueryInformationProcess( /* Dereference the process */ ObDereferenceObject(Process); break; + } /* Virtual Memory Statistics */ case ProcessVmCounters: + { + PVM_COUNTERS VmCounters = (PVM_COUNTERS)ProcessInformation; /* Validate the input length */ if ((ProcessInformationLength != sizeof(VM_COUNTERS)) && @@ -477,6 +504,7 @@ NtQueryInformationProcess( /* Dereference the process */ ObDereferenceObject(Process); break; + } /* Hard Error Processing Mode */ case ProcessDefaultHardErrorMode: @@ -558,6 +586,8 @@ NtQueryInformationProcess( /* DOS Device Map */ case ProcessDeviceMap: + { + ULONG Flags; if (ProcessInformationLength == sizeof(PROCESS_DEVICEMAP_INFORMATION_EX)) { @@ -617,9 +647,12 @@ NtQueryInformationProcess( /* Dereference the process */ ObDereferenceObject(Process); break; + } /* Priority class */ case ProcessPriorityClass: + { + PPROCESS_PRIORITY_CLASS PsPriorityClass = (PPROCESS_PRIORITY_CLASS)ProcessInformation; if (ProcessInformationLength != sizeof(PROCESS_PRIORITY_CLASS)) { @@ -656,8 +689,11 @@ NtQueryInformationProcess( /* Dereference the process */ ObDereferenceObject(Process); break; + } case ProcessImageFileName: + { + PUNICODE_STRING ImageName; /* Reference the process */ Status = ObReferenceObjectByHandle(ProcessHandle, @@ -710,6 +746,7 @@ NtQueryInformationProcess( /* Dereference the process */ ObDereferenceObject(Process); break; + } case ProcessDebugFlags: @@ -787,6 +824,8 @@ NtQueryInformationProcess( /* Per-process security cookie */ case ProcessCookie: + { + ULONG Cookie; if (ProcessInformationLength != sizeof(ULONG)) { @@ -836,6 +875,7 @@ NtQueryInformationProcess( } _SEH2_END; break; + } case ProcessImageInformation: @@ -866,6 +906,8 @@ NtQueryInformationProcess( break; case ProcessDebugObjectHandle: + { + HANDLE DebugPort = 0; if (ProcessInformationLength != sizeof(HANDLE)) { @@ -904,6 +946,7 @@ NtQueryInformationProcess( } _SEH2_END; break; + } case ProcessHandleTracing: DPRINT1("Handle tracing Not implemented: %lx\n", ProcessInformationClass); @@ -976,6 +1019,8 @@ NtQueryInformationProcess( break; case ProcessWow64Information: + { + ULONG_PTR Wow64 = 0; if (ProcessInformationLength != sizeof(ULONG_PTR)) { @@ -998,9 +1043,40 @@ NtQueryInformationProcess( /* Make sure the process isn't dying */ if (ExAcquireRundownProtection(&Process->RundownProtect)) { - /* Get the WOW64 process structure */ #ifdef _WIN64 - Wow64 = (ULONG_PTR)Process->Wow64Process; + /* FIXME: A two-part hack: delay setting Process->Wow64Process, + so 64-bit NTDLL can use IO to init stuff. */ + if (Process->Wow64Process == (PVOID)TRUE) + { + PsChargeProcessNonPagedPoolQuota(Process, sizeof(WOW64_PROCESS)); + Process->Wow64Process = ExAllocatePool(NonPagedPool, sizeof(WOW64_PROCESS)); + if (!Process->Wow64Process) + { + PsReturnProcessNonPagedPoolQuota(Process, sizeof(WOW64_PROCESS)); + + Status = STATUS_NO_MEMORY; + Process->Wow64Process = (PVOID)TRUE; + } + else + { + Process->Wow64Process->Wow64 = (PVOID)((ULONG_PTR)(Process->Peb) + ROUND_TO_PAGES(sizeof(PEB))); + } + } + + /* Get the WOW64 process structure */ + if (Process->Wow64Process == NULL) + { + Wow64 = 0; + } + /* FIXME */ + else if (Process->Wow64Process == (PVOID)TRUE) + { + Wow64 = TRUE; + } + else + { + Wow64 = (ULONG_PTR)Process->Wow64Process->Wow64; + } #else Wow64 = 0; #endif @@ -1024,8 +1100,11 @@ NtQueryInformationProcess( /* Dereference the process */ ObDereferenceObject(Process); break; + } case ProcessExecuteFlags: + { + ULONG ExecuteOptions = 0; if (ProcessInformationLength != sizeof(ULONG)) { @@ -1059,6 +1138,7 @@ NtQueryInformationProcess( _SEH2_END; } break; + } case ProcessLdtInformation: DPRINT1("VDM/16-bit not implemented: %lx\n", ProcessInformationClass); @@ -1998,7 +2078,7 @@ NtSetInformationProcess(IN HANDLE ProcessHandle, DPRINT1("Handle tracing not implemented\n"); Status = STATUS_NOT_IMPLEMENTED; break; - + /* Anything else is invalid */ default: DPRINT1("Invalid Server 2003 Info Class: %lx\n", ProcessInformationClass); diff --git a/ntoskrnl/rtl/misc.c b/ntoskrnl/rtl/misc.c index 4bb5f21794bcb..ba4003f3b8d79 100644 --- a/ntoskrnl/rtl/misc.c +++ b/ntoskrnl/rtl/misc.c @@ -222,4 +222,12 @@ RtlPrefetchMemoryNonTemporal(IN PVOID Source, } #endif +VOID NTAPI +AVrfInternalHeapFreeNotification(PVOID AllocationBase, SIZE_T AllocationSize) +{ + /* Stub for linking against rtl */ +} + + + /* EOF */ diff --git a/ntoskrnl/se/srm.c b/ntoskrnl/se/srm.c index 3e9f90c2e055a..a3d969e04f87c 100644 --- a/ntoskrnl/se/srm.c +++ b/ntoskrnl/se/srm.c @@ -10,6 +10,7 @@ /* INCLUDES *******************************************************************/ #include + #define NDEBUG #include @@ -225,7 +226,7 @@ SeRmInitPhase1(VOID) 2 * PAGE_SIZE); if (!NT_SUCCESS(Status)) { - DPRINT1("Security: Rm Create Command Port failed 0x%lx\n", Status); + DPRINT1("Security: Rm Command Port creation failed: 0x%lx\n", Status); return FALSE; } @@ -239,7 +240,7 @@ SeRmInitPhase1(VOID) FALSE); if (!NT_VERIFY((NT_SUCCESS(Status)))) { - DPRINT1("Security: LSA init event creation failed.0x%xl\n", Status); + DPRINT1("Security: LSA Init Event creation failed: 0x%lx\n", Status); return FALSE; } @@ -253,7 +254,7 @@ SeRmInitPhase1(VOID) NULL); if (!NT_SUCCESS(Status)) { - DPRINT1("Security: Rm Server Thread creation failed 0x%lx\n", Status); + DPRINT1("Security: Rm Command Server Thread creation failed: 0x%lx\n", Status); return FALSE; } @@ -297,8 +298,7 @@ SepAdtInitializeBounds(VOID) (ListBounds.MinLength < 16) || (ListBounds.MaxLength - ListBounds.MinLength < 16)) { - DPRINT1("ListBounds are invalid: %u, %u\n", - ListBounds.MinLength, ListBounds.MaxLength); + DPRINT1("ListBounds invalid: %lu, %lu\n", ListBounds.MinLength, ListBounds.MaxLength); return; } @@ -1149,7 +1149,7 @@ SepRmCommandServerThreadInit(VOID) NULL); if (!NT_SUCCESS(Status)) { - DPRINT1("Security Rm Init: Create Memory Section for LSA port failed: %X\n", Status); + DPRINT1("Security Rm Init: Create Memory Section for LSA port failed: 0x%lx\n", Status); goto Cleanup; } @@ -1251,7 +1251,7 @@ SepRmCommandServerThread( &Message.Header); if (!NT_SUCCESS(Status)) { - DPRINT1("Failed to get message: 0x%lx", Status); + DPRINT1("Failed to get message: 0x%lx\n", Status); ReplyMessage = NULL; continue; } @@ -1283,7 +1283,7 @@ SepRmCommandServerThread( /* Check if this is an actual request */ if (Message.Header.u2.s2.Type != LPC_REQUEST) { - DPRINT1("SepRmCommandServerThread: unexpected message type: 0x%lx\n", + DPRINT1("SepRmCommandServerThread: unexpected message type: 0x%x\n", Message.Header.u2.s2.Type); /* Restart without replying */ diff --git a/ntoskrnl/se/tokenlif.c b/ntoskrnl/se/tokenlif.c index 85a8ee01f78ed..1bb077c904212 100644 --- a/ntoskrnl/se/tokenlif.c +++ b/ntoskrnl/se/tokenlif.c @@ -1859,7 +1859,7 @@ NtCreateToken( * this is certainly NOT true, although I can't say for sure that EffectiveOnly * is correct either. -Gunnar * This is true. EffectiveOnly overrides SQOS.EffectiveOnly. - IAI - * NOTE for readers: http://hex.pp.ua/nt/NtDuplicateToken.php is therefore + * NOTE for readers: https://hex.pp.ua/nt/NtDuplicateToken.php is therefore * wrong in that regard, while MSDN documentation is correct. */ _Must_inspect_result_ diff --git a/sdk/cmake/CMakeMacros.cmake b/sdk/cmake/CMakeMacros.cmake index 7bc66aebce14e..759e5af20f525 100644 --- a/sdk/cmake/CMakeMacros.cmake +++ b/sdk/cmake/CMakeMacros.cmake @@ -245,7 +245,8 @@ macro(dir_to_num dir var) set(${var} 79) elseif(${dir} STREQUAL reactos/winsxs/arm64_microsoft.windows.gdiplus_6595b64144ccf1df_1.0.14393.0_none_deadbeef) set(${var} 81) - + elseif(${dir} STREQUAL reactos/SysWOW64) + set(${var} 82) else() message(FATAL_ERROR "Wrong destination: ${dir}") diff --git a/sdk/cmake/config.cmake b/sdk/cmake/config.cmake index 77b26a0383e8d..fb737211f0297 100644 --- a/sdk/cmake/config.cmake +++ b/sdk/cmake/config.cmake @@ -92,8 +92,6 @@ else() set(_WINKD_ FALSE CACHE BOOL "Whether to compile with the KD protocol.") endif() -option(BUILD_MP "Whether to build the multiprocessor versions of NTOSKRNL and HAL." ON) - cmake_dependent_option(ISAPNP_ENABLE "Whether to enable the ISA PnP support." ON "ARCH STREQUAL i386 AND NOT SARCH STREQUAL xbox" OFF) diff --git a/sdk/cmake/gcc.cmake b/sdk/cmake/gcc.cmake index 860594ef38de4..944051c1368b5 100644 --- a/sdk/cmake/gcc.cmake +++ b/sdk/cmake/gcc.cmake @@ -14,6 +14,8 @@ endif() # Dwarf based builds (no rsym) if(CMAKE_BUILD_TYPE STREQUAL "Release") set(NO_ROSSYM TRUE) +elseif(NOT ARCH STREQUAL "i386") + set(NO_ROSSYM TRUE) elseif(NOT DEFINED NO_ROSSYM) set(NO_ROSSYM FALSE) endif() @@ -56,6 +58,59 @@ if(CMAKE_C_COMPILER_ID STREQUAL "GNU") add_compile_options("$<$:-Wold-style-declaration>") endif() + # Disable all math intrinsics. The reason is that these are implicitly declared + # extern by GCC, which causes inline functions to generate global symbols. + # And since GCC is retarded, these symbols are not marked as weak, so they + # conflict with each other in multiple compilation units. + add_compile_options(-fno-builtin-acosf) + add_compile_options(-fno-builtin-acosl) + add_compile_options(-fno-builtin-asinf) + add_compile_options(-fno-builtin-asinl) + add_compile_options(-fno-builtin-atan2f) + add_compile_options(-fno-builtin-atan2l) + add_compile_options(-fno-builtin-atanf) + add_compile_options(-fno-builtin-atanl) + add_compile_options(-fno-builtin-ceilf) + add_compile_options(-fno-builtin-ceill) + add_compile_options(-fno-builtin-coshf) + add_compile_options(-fno-builtin-coshl) + add_compile_options(-fno-builtin-cosf) + add_compile_options(-fno-builtin-cosl) + add_compile_options(-fno-builtin-expf) + add_compile_options(-fno-builtin-expl) + add_compile_options(-fno-builtin-fabsf) + add_compile_options(-fno-builtin-fabsl) + add_compile_options(-fno-builtin-floorf) + add_compile_options(-fno-builtin-floorl) + add_compile_options(-fno-builtin-fmodf) + add_compile_options(-fno-builtin-fmodl) + add_compile_options(-fno-builtin-frexpf) + add_compile_options(-fno-builtin-frexpl) + add_compile_options(-fno-builtin-hypotf) + add_compile_options(-fno-builtin-hypotl) + add_compile_options(-fno-builtin-ldexpf) + add_compile_options(-fno-builtin-ldexpl) + add_compile_options(-fno-builtin-logf) + add_compile_options(-fno-builtin-logl) + add_compile_options(-fno-builtin-log10f) + add_compile_options(-fno-builtin-log10l) + add_compile_options(-fno-builtin-modff) + add_compile_options(-fno-builtin-modfl) + add_compile_options(-fno-builtin-powf) + add_compile_options(-fno-builtin-powl) + add_compile_options(-fno-builtin-sinhf) + add_compile_options(-fno-builtin-sinhl) + add_compile_options(-fno-builtin-sinf) + add_compile_options(-fno-builtin-sinl) + add_compile_options(-fno-builtin-sqrtf) + add_compile_options(-fno-builtin-sqrtl) + add_compile_options(-fno-builtin-tanhf) + add_compile_options(-fno-builtin-tanhl) + add_compile_options(-fno-builtin-tanf) + add_compile_options(-fno-builtin-tanl) + add_compile_options(-fno-builtin-feraiseexcept) + add_compile_options(-fno-builtin-feupdateenv) + if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 11) add_compile_options(-fno-builtin-ceil) add_compile_options(-fno-builtin-ceilf) @@ -113,24 +168,24 @@ endif() add_compile_options(-march=${OARCH} -mtune=${TUNE}) # Warnings, errors -if((NOT CMAKE_BUILD_TYPE STREQUAL "Release") AND (NOT CMAKE_C_COMPILER_ID STREQUAL Clang)) +if((NOT CMAKE_BUILD_TYPE STREQUAL "Release") AND (NOT CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") AND (NOT CMAKE_C_COMPILER_ID STREQUAL Clang)) add_compile_options(-Werror) -else() - if(CMAKE_C_COMPILER_ID STREQUAL "Clang") - add_compile_options($<$:-Werror=unknown-warning-option>) - endif() endif() add_compile_options(-Wall -Wpointer-arith) -add_compile_options(-Wno-char-subscripts -Wno-multichar -Wno-unused-value) -add_compile_options(-Wno-unused-const-variable) -add_compile_options(-Wno-unused-local-typedefs) -add_compile_options(-Wno-deprecated) -add_compile_options(-Wno-unused-result) # FIXME To be removed when CORE-17637 is resolved - -if(NOT CMAKE_C_COMPILER_ID STREQUAL "Clang") - add_compile_options(-Wno-maybe-uninitialized) -endif() + +# Disable some overzealous warnings +add_compile_options( + -Wno-unknown-warning-option + -Wno-char-subscripts + -Wno-multichar + -Wno-unused-value + -Wno-unused-const-variable + -Wno-unused-local-typedefs + -Wno-deprecated + -Wno-unused-result # FIXME To be removed when CORE-17637 is resolved + -Wno-maybe-uninitialized +) if(ARCH STREQUAL "amd64") add_compile_options(-Wno-format) @@ -198,6 +253,9 @@ endif() # Fix build with GLIBCXX + our c++ headers add_definitions(-D_GLIBCXX_HAVE_BROKEN_VSWPRINTF) +# Fix build with UCRT headers +add_definitions(-D_CRT_SUPPRESS_RESTRICT) + # Alternative arch name if(ARCH STREQUAL "amd64") set(ARCH2 x86_64) @@ -373,11 +431,11 @@ function(fixup_load_config _target) DEPENDS native-pefixup) endfunction() -function(generate_import_lib _libname _dllname _spec_file __version_arg) +function(generate_import_lib _libname _dllname _spec_file __version_arg __dbg_arg) # Generate the def for the import lib add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_libname}_implib.def - COMMAND native-spec2def ${__version_arg} -n=${_dllname} -a=${ARCH2} ${ARGN} --implib -d=${CMAKE_CURRENT_BINARY_DIR}/${_libname}_implib.def ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file} + COMMAND native-spec2def ${__version_arg} ${__dbg_arg} -n=${_dllname} -a=${ARCH2} ${ARGN} --implib -d=${CMAKE_CURRENT_BINARY_DIR}/${_libname}_implib.def ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file} DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file} native-spec2def) # With this, we let DLLTOOL create an import library @@ -427,7 +485,7 @@ endfunction() function(spec2def _dllname _spec_file) - cmake_parse_arguments(__spec2def "ADD_IMPORTLIB;NO_PRIVATE_WARNINGS;WITH_RELAY" "VERSION" "" ${ARGN}) + cmake_parse_arguments(__spec2def "ADD_IMPORTLIB;NO_PRIVATE_WARNINGS;WITH_RELAY;WITH_DBG;NO_DBG" "VERSION" "" ${ARGN}) # Get library basename get_filename_component(_file ${_dllname} NAME_WE) @@ -447,10 +505,14 @@ function(spec2def _dllname _spec_file) set(__version_arg "--version=${DLL_EXPORT_VERSION}") endif() + if(__spec2def_WITH_DBG OR (DBG AND NOT __spec2def_NO_DBG)) + set(__dbg_arg "--dbg") + endif() + # Generate exports def and C stubs file for the DLL add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_file}.def ${CMAKE_CURRENT_BINARY_DIR}/${_file}_stubs.c - COMMAND native-spec2def -n=${_dllname} -a=${ARCH2} -d=${CMAKE_CURRENT_BINARY_DIR}/${_file}.def -s=${CMAKE_CURRENT_BINARY_DIR}/${_file}_stubs.c ${__with_relay_arg} ${__version_arg} ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file} + COMMAND native-spec2def -n=${_dllname} -a=${ARCH2} -d=${CMAKE_CURRENT_BINARY_DIR}/${_file}.def -s=${CMAKE_CURRENT_BINARY_DIR}/${_file}_stubs.c ${__with_relay_arg} ${__version_arg} ${__dbg_arg} ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file} DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file} native-spec2def) # Do not use precompiled headers for the stub file @@ -462,7 +524,7 @@ function(spec2def _dllname _spec_file) set(_extraflags --no-private-warnings) endif() - generate_import_lib(lib${_file} ${_dllname} ${_spec_file} ${_extraflags} "${__version_arg}") + generate_import_lib(lib${_file} ${_dllname} ${_spec_file} ${_extraflags} "${__version_arg}" "${__dbg_arg}") endif() endfunction() @@ -575,8 +637,8 @@ add_library(libgcc STATIC IMPORTED) execute_process(COMMAND ${GXX_EXECUTABLE} -print-file-name=libgcc.a OUTPUT_VARIABLE LIBGCC_LOCATION) string(STRIP ${LIBGCC_LOCATION} LIBGCC_LOCATION) set_target_properties(libgcc PROPERTIES IMPORTED_LOCATION ${LIBGCC_LOCATION}) -# libgcc needs kernel32 imports, winpthread, a CRT and msvcrtex -target_link_libraries(libgcc INTERFACE libwinpthread libkernel32 libmsvcrt msvcrtex) +# libgcc needs kernel32 and winpthread (an appropriate CRT must be linked manually) +target_link_libraries(libgcc INTERFACE libwinpthread libkernel32) add_library(libsupc++ STATIC IMPORTED GLOBAL) execute_process(COMMAND ${GXX_EXECUTABLE} -print-file-name=libsupc++.a OUTPUT_VARIABLE LIBSUPCXX_LOCATION) @@ -597,7 +659,7 @@ execute_process(COMMAND ${GXX_EXECUTABLE} -print-file-name=libstdc++.a OUTPUT_VA string(STRIP ${LIBSTDCCXX_LOCATION} LIBSTDCCXX_LOCATION) set_target_properties(libstdc++ PROPERTIES IMPORTED_LOCATION ${LIBSTDCCXX_LOCATION}) # libstdc++ requires libsupc++ and mingwex provided by GCC -target_link_libraries(libstdc++ INTERFACE libsupc++ libmingwex) +target_link_libraries(libstdc++ INTERFACE libsupc++ libmingwex oldnames) # this is for our SAL annotations target_compile_definitions(libstdc++ INTERFACE "$<$:PAL_STDCPP_COMPAT>") diff --git a/sdk/cmake/host-tools.cmake b/sdk/cmake/host-tools.cmake index b7932a82bb809..4f346d029bd1b 100644 --- a/sdk/cmake/host-tools.cmake +++ b/sdk/cmake/host-tools.cmake @@ -4,7 +4,10 @@ include(ExternalProject) function(setup_host_tools) list(APPEND HOST_TOOLS asmpp bin2c widl gendib cabman fatten hpp isohybrid mkhive mkisofs obj2bin spec2def geninc mkshelllink txt2nls utf16le xml2sdb) if(NOT MSVC) - list(APPEND HOST_TOOLS rsym pefixup) + list(APPEND HOST_TOOLS pefixup) + if (ARCH STREQUAL "i386") + list(APPEND HOST_TOOLS rsym) + endif() endif() if ((ARCH STREQUAL "amd64") AND (CMAKE_C_COMPILER_ID STREQUAL "GNU")) execute_process( @@ -91,6 +94,10 @@ function(setup_host_tools) ) endif() + if(NOT DEFINED HOST_BUILD_TYPE) + set(HOST_BUILD_TYPE Debug) + endif() + ExternalProject_Add(host-tools SOURCE_DIR ${REACTOS_SOURCE_DIR} PREFIX ${REACTOS_BINARY_DIR}/host-tools @@ -102,6 +109,8 @@ function(setup_host_tools) -DCMAKE_INSTALL_PREFIX=${REACTOS_BINARY_DIR}/host-tools -DTOOLS_FOLDER=${REACTOS_BINARY_DIR}/host-tools/bin -DTARGET_COMPILER_ID=${CMAKE_C_COMPILER_ID} + -DTARGET_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -DCMAKE_BUILD_TYPE=${HOST_BUILD_TYPE} ${CMAKE_HOST_TOOLS_EXTRA_ARGS} BUILD_ALWAYS TRUE INSTALL_COMMAND ${CMAKE_COMMAND} -E true diff --git a/sdk/cmake/msvc.cmake b/sdk/cmake/msvc.cmake index bf804dd3bfd68..f01df38f8913d 100644 --- a/sdk/cmake/msvc.cmake +++ b/sdk/cmake/msvc.cmake @@ -147,15 +147,27 @@ endif() add_compile_options(/w14115) if(CMAKE_C_COMPILER_ID STREQUAL "Clang") - add_compile_options($<$:-Werror=unknown-warning-option>) - add_compile_options("$<$:-nostdinc;-Wno-multichar;-Wno-char-subscripts;-Wno-microsoft-enum-forward-reference;-Wno-pragma-pack;-Wno-microsoft-anon-tag;-Wno-parentheses-equality;-Wno-unknown-pragmas>") + add_compile_options("$<$:-nostdinc>") + add_compile_options( + -Wno-unknown-warning-option + -Wno-multichar + -Wno-char-subscripts + -Wno-microsoft-enum-forward-reference + -Wno-pragma-pack + -Wno-microsoft-anon-tag + -Wno-parentheses-equality + -Wno-unknown-pragmas + -Wno-ignored-pragmas + -Wno-ignored-pragma-intrinsic + -Wno-microsoft-exception-spec + ) endif() # Debugging if(NOT (_PREFAST_ OR _VS_ANALYZE_)) add_compile_options($<$:/Zi>) endif() -add_compile_definitions($<$:NDEBUG>) +add_compile_definitions($<$:NDEBUG=>) # Hotpatchable images if(ARCH STREQUAL "i386") @@ -320,7 +332,7 @@ function(fixup_load_config _target) # msvc knows how to generate a load_config so no hacks here endfunction() -function(generate_import_lib _libname _dllname _spec_file __version_arg) +function(generate_import_lib _libname _dllname _spec_file __version_arg __dbg_arg) set(_def_file ${CMAKE_CURRENT_BINARY_DIR}/${_libname}_implib.def) set(_asm_stubs_file ${CMAKE_CURRENT_BINARY_DIR}/${_libname}_stubs.asm) @@ -329,7 +341,7 @@ function(generate_import_lib _libname _dllname _spec_file __version_arg) # Generate the def, asm stub and alias files add_custom_command( OUTPUT ${_asm_stubs_file} ${_def_file} ${_asm_impalias_file} - COMMAND native-spec2def --ms ${__version_arg} -a=${SPEC2DEF_ARCH} --implib -n=${_dllname} -d=${_def_file} -l=${_asm_stubs_file} -i=${_asm_impalias_file} ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file} + COMMAND native-spec2def --ms ${__version_arg} ${__dbg_arg} -a=${SPEC2DEF_ARCH} --implib -n=${_dllname} -d=${_def_file} -l=${_asm_stubs_file} -i=${_asm_impalias_file} ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file} DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file} native-spec2def) # Compile the generated asm stub file @@ -377,9 +389,10 @@ elseif(ARCH STREQUAL "arm64") else() set(SPEC2DEF_ARCH i386) endif() + function(spec2def _dllname _spec_file) - cmake_parse_arguments(__spec2def "ADD_IMPORTLIB;NO_PRIVATE_WARNINGS;WITH_RELAY" "VERSION" "" ${ARGN}) + cmake_parse_arguments(__spec2def "ADD_IMPORTLIB;NO_PRIVATE_WARNINGS;WITH_RELAY;WITH_DBG;NO_DBG" "VERSION" "" ${ARGN}) # Get library basename get_filename_component(_file ${_dllname} NAME_WE) @@ -399,17 +412,21 @@ function(spec2def _dllname _spec_file) set(__version_arg "--version=${DLL_EXPORT_VERSION}") endif() + if(__spec2def_WITH_DBG OR (DBG AND NOT __spec2def_NO_DBG)) + set(__dbg_arg "--dbg") + endif() + # Generate exports def and C stubs file for the DLL add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_file}.def ${CMAKE_CURRENT_BINARY_DIR}/${_file}_stubs.c - COMMAND native-spec2def --ms -a=${SPEC2DEF_ARCH} -n=${_dllname} -d=${CMAKE_CURRENT_BINARY_DIR}/${_file}.def -s=${CMAKE_CURRENT_BINARY_DIR}/${_file}_stubs.c ${__with_relay_arg} ${__version_arg} ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file} + COMMAND native-spec2def --ms -a=${SPEC2DEF_ARCH} -n=${_dllname} -d=${CMAKE_CURRENT_BINARY_DIR}/${_file}.def -s=${CMAKE_CURRENT_BINARY_DIR}/${_file}_stubs.c ${__with_relay_arg} ${__version_arg} ${__dbg_arg} ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file} DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file} native-spec2def) # Do not use precompiled headers for the stub file set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${_file}_stubs.c PROPERTIES SKIP_PRECOMPILE_HEADERS ON) if(__spec2def_ADD_IMPORTLIB) - generate_import_lib(lib${_file} ${_dllname} ${_spec_file} "${__version_arg}") + generate_import_lib(lib${_file} ${_dllname} ${_spec_file} "${__version_arg}" "${__dbg_arg}") if(__spec2def_NO_PRIVATE_WARNINGS) set_property(TARGET lib${_file} APPEND PROPERTY STATIC_LIBRARY_OPTIONS /ignore:4104) endif() diff --git a/sdk/cmake/set_wine_module.cmake b/sdk/cmake/set_wine_module.cmake new file mode 100644 index 0000000000000..b2de459878ba2 --- /dev/null +++ b/sdk/cmake/set_wine_module.cmake @@ -0,0 +1,16 @@ + +# FIXME: CORE-5743 + +function(set_wine_module TARGET) + include_directories(BEFORE + ${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine + ${REACTOS_BINARY_DIR}/sdk/include/reactos/wine) +endfunction() + +# FIXME: Replace this call with set_wine_module +function(set_wine_module_FIXME TARGET) + include_directories(BEFORE + ${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine + ${REACTOS_BINARY_DIR}/sdk/include/reactos/wine) + target_compile_definitions(${TARGET} PRIVATE __WINESRC__) +endfunction() diff --git a/sdk/cmake/widl-support.cmake b/sdk/cmake/widl-support.cmake index a8e926614a042..1b291dfa5b380 100644 --- a/sdk/cmake/widl-support.cmake +++ b/sdk/cmake/widl-support.cmake @@ -1,11 +1,11 @@ #idl files support if(ARCH STREQUAL "i386") - set(IDL_FLAGS -m32 --win32) + set(IDL_FLAGS -m32 --win32 -b i386-x-y) elseif(ARCH STREQUAL "amd64") - set(IDL_FLAGS -m64 --win64) + set(IDL_FLAGS -m64 --win64 -b amd64-x-y) else() - set(IDL_FLAGS "") + set(IDL_FLAGS -b ${ARCH}-x-y) endif() function(add_typelib) diff --git a/sdk/include/asm/alias.inc b/sdk/include/asm/alias.inc new file mode 100644 index 0000000000000..a81f3465771ae --- /dev/null +++ b/sdk/include/asm/alias.inc @@ -0,0 +1,58 @@ + +#ifdef _M_IX86 +#define SYM(name) _##name +#define IMPSYM(name) __imp__##name +#else +#define SYM(name) name +#define IMPSYM(name) __imp_##name +#endif + +#if (defined(_M_IX86) || defined(_M_AMD64)) + +#include + +MACRO(CREATE_ALIAS1, alias, target) +#ifdef _USE_ML + EXTERN SYM(&target):PROC + ALIAS = +#else + .weakref SYM(&alias), SYM(&target) +#endif +ENDM + +MACRO(CREATE_ALIAS2, alias, target) +#ifdef _USE_ML + EXTERN IMPSYM(&target):PROC + ALIAS = +#else + .weakref IMPSYM(&alias), IMPSYM(&target) +#endif +ENDM + +MACRO(CREATE_ALIAS, alias, target) + CREATE_ALIAS1 &alias, &target + CREATE_ALIAS2 &alias, &target +ENDM + +#elif defined(_M_ARM) + +#include + + MACRO + CREATE_ALIAS1 $alias, $target + IMPORT SYM($alias), WEAK SYM($target) + MEND + + MACRO + CREATE_ALIAS2 $alias, $target + IMPORT IMPSYM($alias), WEAK IMPSYM($target) + MEND + + MACRO + CREATE_ALIAS $alias, $target + CREATE_ALIAS1 $alias, $target + CREATE_ALIAS2 $alias, $target + MEND +#else +#error "Unsupported platform." +#endif diff --git a/sdk/include/asm/asm.inc b/sdk/include/asm/asm.inc index b1a29b8802e29..d5e4bc988181a 100644 --- a/sdk/include/asm/asm.inc +++ b/sdk/include/asm/asm.inc @@ -172,6 +172,9 @@ ENDM .skip size, fill ENDM +/* OFFset macro */ +#define OFF(x) offset x + #define lXdtPrefix fword ptr ljmp MACRO segment, offset @@ -316,12 +319,17 @@ ENDM .endm /* MASM compatible ALIGN */ -#define ALIGN .align +.macro align x + .align x +.endm /* MASM compatible REPEAT, additional ENDR */ #define REPEAT .rept #define ENDR .endr +/* OFFset macro */ +#define OFF(x) x + #define lXdtPrefix .macro ljmp segment, offset @@ -350,7 +358,8 @@ ENDM .endm /* MASM needs an END tag */ -#define END +.macro END +.endm .macro .MODEL model .endm diff --git a/sdk/include/asm/macamd64.inc b/sdk/include/asm/macamd64.inc index af917f54f3152..e8cdfe043352d 100644 --- a/sdk/include/asm/macamd64.inc +++ b/sdk/include/asm/macamd64.inc @@ -75,52 +75,52 @@ MACRO(BEGIN_EPILOGUE) ENDM MACRO(LEAF_ENTRY, Name, Section, NoPad) - Section segment para 'CODE' - ifb - db 6 dup HEX(CC) - endif +//Section segment para 'CODE' +//ifb +// db 6 dup (0cch) +//endif align 16 - public Name -Name proc frame + public Name +.PROC Name END_PROLOGUE ENDM MACRO(LEAF_ENTRY_ARG1, Name, Section, Arg1, NoPad) - Section segment para 'CODE' - ifb - db 6 dup HEX(CC) - endif +//Section segment para 'CODE' +//ifb +// db 6 dup (0cch) +//endif align 16 - public Name -Name proc frame + public Name +.PROC Name END_PROLOGUE ENDM MACRO(LEAF_ENTRY_ARG2, Name, Section, Arg1, Arg2, NoPad) - Section segment para 'CODE' - ifb - db 6 dup HEX(CC) - endif +//Section segment para 'CODE' +//ifb +// db 6 dup (0cch) +//endif align 16 - public Name -Name proc frame + public Name +.PROC Name END_PROLOGUE ENDM MACRO(LEAF_ENTRY_ARG3, Name, Section, Arg1, Arg2, Arg3, NoPad) - Section segment para 'CODE' - ifb - db 6 dup HEX(CC) - endif +//Section segment para 'CODE' +//ifb +// db 6 dup (0cch) +//endif align 16 - public Name -Name proc frame + public Name +.PROC Name END_PROLOGUE ENDM -MACRO(LEAF_END, Name, section) - Name endp - Section ends +MACRO(LEAF_END, Name, Section) +.ENDP +//Section ends ENDM MACRO(NESTED_ENTR, Name, Section, Handler, NoPad) diff --git a/sdk/include/asm/syscalls.inc b/sdk/include/asm/syscalls.inc index a59cee00e6bfa..b4ede49054aa4 100644 --- a/sdk/include/asm/syscalls.inc +++ b/sdk/include/asm/syscalls.inc @@ -53,6 +53,63 @@ $ZwFuncEndName SyscallId = 0 #ifdef _M_IX86 +#ifdef BUILD_WOW6432 +#define KUSER_SHARED_SYSCALL HEX(7ffe0300) +MACRO(STUBCODE_U, Name, SyscallId, ArgCount) +LOCAL x, x2, x3 + StackBytes = 4 * ArgCount + FPO 0, 0, 0, 0, 0, FRAME_FPO + push ecx + push edx + + mov ecx, SyscallId + mov edx, ArgCount + + push ebp + mov ebp, esp + + ; Align the stack, and allocate shadow space for the x64 calling convention + sub esp, 48 + and esp, 0FFFFFFF0h + + push 0 + push ebp + + ljmp 33h, x +x: + ; pop rdx + db 5ah + + ; add rdx, 16 + db 48h + db 83h + db 0c2h + db 10h + + call x3 + + push 23h + push x2 + db 48h + retf +x2: + mov esp, ebp + pop ebp + + pop edx + pop ecx + + ret StackBytes +x3: + dd 25048b64h + dd 000000c0h + db 50h + db 0c3h +ENDM +MACRO(STUBCODE_K, Name, SyscallId, ArgCount) + int 3 +ENDM +#else #define KUSER_SHARED_SYSCALL HEX(7ffe0300) #define KGDT_R0_CODE 8 MACRO(STUBCODE_U, Name, SyscallId, ArgCount) @@ -73,6 +130,7 @@ MACRO(STUBCODE_K, Name, SyscallId, ArgCount) call _KiSystemService ret StackBytes ENDM +#endif #elif defined(_M_AMD64) MACRO(STUBCODE_U, Name, SyscallId, ArgCount) .ENDPROLOG diff --git a/sdk/include/crt/crtdbg.h b/sdk/include/crt/crtdbg.h index 6b90bc018d524..284cb38114a13 100644 --- a/sdk/include/crt/crtdbg.h +++ b/sdk/include/crt/crtdbg.h @@ -4,6 +4,7 @@ * No warranty is given; refer to the file DISCLAIMER within this package. */ #include +#include #ifndef _INC_CRTDBG #define _INC_CRTDBG diff --git a/sdk/include/crt/math.h b/sdk/include/crt/math.h index bd5d70225237b..09113acef86c9 100644 --- a/sdk/include/crt/math.h +++ b/sdk/include/crt/math.h @@ -57,7 +57,21 @@ typedef double double_t; #define HUGE_VALD ((double)INFINITY) #define HUGE_VALF ((float)INFINITY) #define HUGE_VALL ((long double)INFINITY) -#define NAN ((float)(INFINITY * 0.0F)) +#ifndef _UCRT_NEGATIVE_NAN +// This operation creates a negative NAN adding a - to make it positive +#ifdef _MSC_VER +#define NAN (-(float)(INFINITY * 0.0F)) +#else +#define NAN (__builtin_nanf("")) +#endif +#else +// Keep this for backwards compatibility +#ifdef _MSC_VER +#define NAN ((float)(INFINITY * 0.0F)) +#else +#define NAN (-__builtin_nanf("")) +#endif +#endif #define _DENORM (-2) #define _FINITE (-1) @@ -99,7 +113,7 @@ _Check_return_ _CRT_JIT_INTRINSIC double __cdecl sqrt(_In_ double x); _Check_return_ double __cdecl tan(_In_ double x); _Check_return_ double __cdecl tanh(_In_ double x); -#ifdef _MSC_VER +#if defined(_MSC_VER) && !defined(__clang__) /* Prevent the compiler from generating calls to _CIatan2 */ #pragma function(atan2) #ifdef _M_AMD64 @@ -148,7 +162,7 @@ _Check_return_ _CRTIMP int __cdecl _set_SSE2_enable(_In_ int flag); _Check_return_ _CRTIMP float __cdecl _nextafterf(_In_ float x, _In_ float y); _Check_return_ _CRTIMP int __cdecl _isnanf(_In_ float x); _Check_return_ _CRTIMP int __cdecl _fpclassf(_In_ float x); -#ifdef _MSC_VER +#if defined(_MSC_VER) && !defined(__clang__) /* Prevent the compiler from generating calls to __vdecl_floor2 */ #pragma function(floor) #endif @@ -202,7 +216,7 @@ _Check_return_ float __cdecl sqrtf(_In_ float x); _Check_return_ float __cdecl tanf(_In_ float x); _Check_return_ float __cdecl tanhf(_In_ float x); -#if defined(_MSC_VER) +#if defined(_MSC_VER) && !defined(__clang__) /* Make sure intrinsics don't get in our way */ #if defined(_M_AMD64) || defined(_M_ARM) || defined(_M_ARM64) #pragma function(acosf,asinf,atanf,atan2f,ceilf,cosf,coshf,expf,floorf,fmodf,logf,log10f,powf,sinf,sinhf,sqrtf,tanf,tanhf) @@ -269,7 +283,7 @@ _Check_return_ __CRT_INLINE long double ldexpl(_In_ long double x, _In_ int y) { _Check_return_ __CRT_INLINE long double modfl(_In_ long double x, _Out_ long double *y) { return (long double)modf((double)x, (double *)y); } /* Support for some functions, not exported in MSVCRT */ -#if (_MSC_VER >= 1929) +#if (_MSC_VER >= 1929) && !defined(__clang__) _Check_return_ long lrint(_In_ double x); _Check_return_ long lrintf(_In_ float x); _Check_return_ long lrintl(_In_ long double x); diff --git a/sdk/include/crt/stdlib.h b/sdk/include/crt/stdlib.h index fc66c3a6874dd..b522f0c8648ed 100644 --- a/sdk/include/crt/stdlib.h +++ b/sdk/include/crt/stdlib.h @@ -1428,7 +1428,7 @@ extern "C" { __MINGW_EXTENSION _Check_return_ lldiv_t __cdecl lldiv(_In_ long long, _In_ long long); -#if defined(_MSC_VER) +#if defined(_MSC_VER) && !defined(__clang__) _Check_return_ long long __cdecl llabs(_In_ long long _j); #pragma function(llabs) #endif diff --git a/sdk/include/ddk/ata.h b/sdk/include/ddk/ata.h index a0c59a698376f..d5b749f0c1307 100644 --- a/sdk/include/ddk/ata.h +++ b/sdk/include/ddk/ata.h @@ -14,7 +14,7 @@ typedef struct _IDENTIFY_DEVICE_DATA { USHORT DeviceType :1; } GeneralConfiguration; USHORT NumCylinders; - USHORT ReservedWord2; + USHORT SpecificConfiguration; USHORT NumHeads; USHORT Retired1[2]; USHORT NumSectorsPerTrack; @@ -26,9 +26,13 @@ typedef struct _IDENTIFY_DEVICE_DATA { UCHAR ModelNumber[40]; UCHAR MaximumBlockTransfer; UCHAR VendorUnique2; - USHORT ReservedWord48; struct { - UCHAR ReservedByte49; + USHORT FeatureSupported :1; + USHORT Reserved :15; + } TrustedComputing; + struct { + UCHAR CurrentLongPhysicalSectorAlignment :2; + UCHAR ReservedByte49 :6; UCHAR DmaSupported :1; UCHAR LbaSupported :1; UCHAR IordyDisable :1; @@ -40,14 +44,19 @@ typedef struct _IDENTIFY_DEVICE_DATA { } Capabilities; USHORT ObsoleteWords51[2]; USHORT TranslationFieldsValid :3; - USHORT Reserved3 :13; + USHORT Reserved3 :5; + USHORT FreeFallControlSensitivity :8; USHORT NumberOfCurrentCylinders; USHORT NumberOfCurrentHeads; USHORT CurrentSectorsPerTrack; ULONG CurrentSectorCapacity; UCHAR CurrentMultiSectorSetting; UCHAR MultiSectorSettingValid :1; - UCHAR ReservedByte59 :7; + UCHAR ReservedByte59 :3; + UCHAR SanitizeFeatureSupported :1; + UCHAR CryptoScrambleExtCommandSupported :1; + UCHAR OverwriteExtCommandSupported :1; + UCHAR BlockEraseExtCommandSupported :1; ULONG UserAddressableSectors; USHORT ObsoleteWord62; USHORT MultiWordDMASupport :8; @@ -58,10 +67,74 @@ typedef struct _IDENTIFY_DEVICE_DATA { USHORT RecommendedMWXferCycleTime; USHORT MinimumPIOCycleTime; USHORT MinimumPIOCycleTimeIORDY; - USHORT ReservedWords69[6]; + struct { + USHORT ZonedCapabilities :2; + USHORT NonVolatileWriteCache :1; + USHORT ExtendedUserAddressableSectorsSupported :1; + USHORT DeviceEncryptsAllUserData :1; + USHORT ReadZeroAfterTrimSupported :1; + USHORT Optional28BitCommandsSupported :1; + USHORT IEEE1667 :1; + USHORT DownloadMicrocodeDmaSupported :1; + USHORT SetMaxSetPasswordUnlockDmaSupported :1; + USHORT WriteBufferDmaSupported :1; + USHORT ReadBufferDmaSupported :1; + USHORT DeviceConfigIdentifySetDmaSupported :1; + USHORT LPSAERCSupported :1; + USHORT DeterministicReadAfterTrimSupported :1; + USHORT CFastSpecSupported :1; + } AdditionalSupported; + USHORT ReservedWords70[5]; USHORT QueueDepth :5; USHORT ReservedWord75 :11; - USHORT ReservedWords76[4]; + struct { + USHORT Reserved0 :1; + USHORT SataGen1 :1; + USHORT SataGen2 :1; + USHORT SataGen3 :1; + USHORT Reserved1 :4; + USHORT NCQ :1; + USHORT HIPM :1; + USHORT PhyEvents :1; + USHORT NcqUnload :1; + USHORT NcqPriority :1; + USHORT HostAutoPS :1; + USHORT DeviceAutoPS :1; + USHORT ReadLogDMA :1; + USHORT Reserved2 :1; + USHORT CurrentSpeed :3; + USHORT NcqStreaming :1; + USHORT NcqQueueMgmt :1; + USHORT NcqReceiveSend :1; + USHORT DEVSLPtoReducedPwrState :1; + USHORT Reserved3 :8; + } SerialAtaCapabilities; + struct { + USHORT Reserved0 :1; + USHORT NonZeroOffsets :1; + USHORT DmaSetupAutoActivate :1; + USHORT DIPM :1; + USHORT InOrderData :1; + USHORT HardwareFeatureControl :1; + USHORT SoftwareSettingsPreservation :1; + USHORT NCQAutosense :1; + USHORT DEVSLP :1; + USHORT HybridInformation :1; + USHORT Reserved1 :6; + } SerialAtaFeaturesSupported; + struct { + USHORT Reserved0 :1; + USHORT NonZeroOffsets :1; + USHORT DmaSetupAutoActivate :1; + USHORT DIPM :1; + USHORT InOrderData :1; + USHORT HardwareFeatureControl :1; + USHORT SoftwareSettingsPreservation :1; + USHORT DeviceAutoPS :1; + USHORT DEVSLP :1; + USHORT HybridInformation :1; + USHORT Reserved1 :6; + } SerialAtaFeaturesEnabled; USHORT MajorRevision; USHORT MinorRevision; struct { @@ -95,7 +168,7 @@ typedef struct _IDENTIFY_DEVICE_DATA { USHORT DeviceConfigOverlay :1; USHORT FlushCache :1; USHORT FlushCacheExt :1; - USHORT Resrved3 :2; + USHORT WordValid83 :2; USHORT SmartErrorLog :1; USHORT SmartSelfTest :1; USHORT MediaSerialNumber :1; @@ -109,7 +182,7 @@ typedef struct _IDENTIFY_DEVICE_DATA { USHORT URGWriteStream :1; USHORT ReservedForTechReport :2; USHORT IdleWithUnloadFeature :1; - USHORT Reserved4 :2; + USHORT WordValid :2; } CommandSetSupport; struct { USHORT SmartCommands :1; @@ -142,7 +215,8 @@ typedef struct _IDENTIFY_DEVICE_DATA { USHORT DeviceConfigOverlay :1; USHORT FlushCache :1; USHORT FlushCacheExt :1; - USHORT Resrved3 :2; + USHORT Resrved3 :1; + USHORT Words119_120Valid :1; USHORT SmartErrorLog :1; USHORT SmartSelfTest :1; USHORT MediaSerialNumber :1; @@ -160,14 +234,27 @@ typedef struct _IDENTIFY_DEVICE_DATA { } CommandSetActive; USHORT UltraDMASupport :8; USHORT UltraDMAActive :8; - USHORT ReservedWord89[4]; + struct { + USHORT TimeRequired :15; + USHORT ExtendedTimeReported :1; + } NormalSecurityEraseUnit; + struct { + USHORT TimeRequired :15; + USHORT ExtendedTimeReported :1; + } EnhancedSecurityEraseUnit; + USHORT CurrentAPMLevel :8; + USHORT ReservedWord91 :8; + USHORT MasterPasswordID; USHORT HardwareResetResult; USHORT CurrentAcousticValue :8; USHORT RecommendedAcousticValue :8; - USHORT ReservedWord95[5]; + USHORT StreamMinRequestSize; + USHORT StreamingTransferTimeDMA; + USHORT StreamingAccessLatencyDMAPIO; + ULONG StreamingPerfGranularity; ULONG Max48BitLBA[2]; USHORT StreamingTransferTime; - USHORT ReservedWord105; + USHORT DsmCap; struct { USHORT LogicalSectorsPerPhysicalSector :4; USHORT Reserved0 :8; @@ -182,19 +269,31 @@ typedef struct _IDENTIFY_DEVICE_DATA { USHORT WordsPerLogicalSector[2]; struct { USHORT ReservedForDrqTechnicalReport :1; - USHORT WriteReadVerifySupported :1; - USHORT Reserved01 :11; - USHORT Reserved1 :2; + USHORT WriteReadVerify :1; + USHORT WriteUncorrectableExt :1; + USHORT ReadWriteLogDmaExt :1; + USHORT DownloadMicrocodeMode3 :1; + USHORT FreefallControl :1; + USHORT SenseDataReporting :1; + USHORT ExtendedPowerConditions :1; + USHORT Reserved0 :6; + USHORT WordValid :2; } CommandSetSupportExt; struct { USHORT ReservedForDrqTechnicalReport :1; - USHORT WriteReadVerifyEnabled :1; - USHORT Reserved01 :11; + USHORT WriteReadVerify :1; + USHORT WriteUncorrectableExt :1; + USHORT ReadWriteLogDmaExt :1; + USHORT DownloadMicrocodeMode3 :1; + USHORT FreefallControl :1; + USHORT SenseDataReporting :1; + USHORT ExtendedPowerConditions :1; + USHORT Reserved0 :6; USHORT Reserved1 :2; } CommandSetActiveExt; USHORT ReservedForExpandedSupportandActive[6]; USHORT MsnSupport :2; - USHORT ReservedWord1274 :14; + USHORT ReservedWord127 :14; struct { USHORT SecuritySupported :1; USHORT SecurityEnabled :1; @@ -208,20 +307,32 @@ typedef struct _IDENTIFY_DEVICE_DATA { } SecurityStatus; USHORT ReservedWord129[31]; struct { - USHORT MaximumCurrentInMA2 :12; + USHORT MaximumCurrentInMA :12; USHORT CfaPowerMode1Disabled :1; USHORT CfaPowerMode1Required :1; USHORT Reserved0 :1; USHORT Word160Supported :1; - } CfaPowerModel; - USHORT ReservedForCfaWord161[8]; + } CfaPowerMode1; + USHORT ReservedForCfaWord161[7]; + USHORT NominalFormFactor :4; + USHORT ReservedWord168 :12; struct { USHORT SupportsTrim :1; USHORT Reserved0 :15; } DataSetManagementFeature; - USHORT ReservedForCfaWord170[6]; + USHORT AdditionalProductID[4]; + USHORT ReservedForCfaWord174[2]; USHORT CurrentMediaSerialNumber[30]; - USHORT ReservedWord206; + struct { + USHORT Supported :1; + USHORT Reserved0 :1; + USHORT WriteSameSuported :1; + USHORT ErrorRecoveryControlSupported :1; + USHORT FeatureControlSuported :1; + USHORT DataTablesSuported :1; + USHORT Reserved1 :6; + USHORT VendorSpecific :4; + } SCTCommandTransport; USHORT ReservedWord207[2]; struct { USHORT AlignmentOfLogicalWithinPhysical :14; @@ -246,56 +357,367 @@ typedef struct _IDENTIFY_DEVICE_DATA { UCHAR NVCacheEstimatedTimeToSpinUpInSeconds; UCHAR Reserved; } NVCacheOptions; - USHORT ReservedWord220[35]; + USHORT WriteReadVerifySectorCountMode :8; + USHORT ReservedWord220 :8; + USHORT ReservedWord221; + struct { + USHORT MajorVersion :12; + USHORT TransportType :4; + } TransportMajorVersion; + USHORT TransportMinorVersion; + USHORT ReservedWord224[6]; + ULONG ExtendedNumberOfUserAddressableSectors[2]; + USHORT MinBlocksPerDownloadMicrocodeMode03; + USHORT MaxBlocksPerDownloadMicrocodeMode03; + USHORT ReservedWord236[19]; USHORT Signature :8; USHORT CheckSum :8; } IDENTIFY_DEVICE_DATA, *PIDENTIFY_DEVICE_DATA; + +typedef struct _IDENTIFY_PACKET_DATA { + struct { + USHORT PacketType :2; + USHORT IncompleteResponse :1; + USHORT Reserved1 :2; + USHORT DrqDelay :2; + USHORT RemovableMedia :1; + USHORT CommandPacketType :5; + USHORT Reserved2 :1; + USHORT DeviceType :2; + } GeneralConfiguration; + USHORT ResevedWord1; + USHORT UniqueConfiguration; + USHORT ReservedWords3[7]; + UCHAR SerialNumber[20]; + USHORT ReservedWords20[3]; + UCHAR FirmwareRevision[8]; + UCHAR ModelNumber[40]; + USHORT ReservedWords47[2]; + struct { + USHORT VendorSpecific :8; + USHORT DmaSupported :1; + USHORT LbaSupported :1; + USHORT IordyDisabled :1; + USHORT IordySupported :1; + USHORT Obsolete :1; + USHORT OverlapSupported :1; + USHORT QueuedCommandsSupported :1; + USHORT InterleavedDmaSupported :1; + USHORT DeviceSpecificStandbyTimerValueMin :1; + USHORT Obsolete1 :1; + USHORT ReservedWord50 :12; + USHORT WordValid :2; + } Capabilities; + USHORT ObsoleteWords51[2]; + USHORT TranslationFieldsValid :3; + USHORT Reserved3 :13; + USHORT ReservedWords54[8]; + struct { + USHORT UDMA0Supported :1; + USHORT UDMA1Supported :1; + USHORT UDMA2Supported :1; + USHORT UDMA3Supported :1; + USHORT UDMA4Supported :1; + USHORT UDMA5Supported :1; + USHORT UDMA6Supported :1; + USHORT MDMA0Supported :1; + USHORT MDMA1Supported :1; + USHORT MDMA2Supported :1; + USHORT DMASupported :1; + USHORT ReservedWord62 :4; + USHORT DMADIRBitRequired :1; + } DMADIR; + USHORT MultiWordDMASupport :8; + USHORT MultiWordDMAActive :8; + USHORT AdvancedPIOModes :8; + USHORT ReservedByte64 :8; + USHORT MinimumMWXferCycleTime; + USHORT RecommendedMWXferCycleTime; + USHORT MinimumPIOCycleTime; + USHORT MinimumPIOCycleTimeIORDY; + USHORT ReservedWords69[2]; + USHORT BusReleaseDelay; + USHORT ServiceCommandDelay; + USHORT ReservedWords73[2]; + USHORT QueueDepth :5; + USHORT ReservedWord75 :11; + struct { + USHORT Reserved0 :1; + USHORT SataGen1 :1; + USHORT SataGen2 :1; + USHORT SataGen3 :1; + USHORT Reserved1 :5; + USHORT HIPM :1; + USHORT PhyEvents :1; + USHORT Reserved3 :2; + USHORT HostAutoPS :1; + USHORT DeviceAutoPS :1; + USHORT Reserved4 :1; + USHORT Reserved5 :1; + USHORT CurrentSpeed :3; + USHORT SlimlineDeviceAttention :1; + USHORT HostEnvironmentDetect :1; + USHORT Reserved :10; + } SerialAtaCapabilities; + struct { + USHORT Reserved0 :1; + USHORT Reserved1 :2; + USHORT DIPM :1; + USHORT Reserved2 :1; + USHORT AsynchronousNotification :1; + USHORT SoftwareSettingsPreservation :1; + USHORT Reserved3 :9; + } SerialAtaFeaturesSupported; + struct { + USHORT Reserved0 :1; + USHORT Reserved1 :2; + USHORT DIPM :1; + USHORT Reserved2 :1; + USHORT AsynchronousNotification :1; + USHORT SoftwareSettingsPreservation :1; + USHORT DeviceAutoPS :1; + USHORT Reserved3 :8; + } SerialAtaFeaturesEnabled; + USHORT MajorRevision; + USHORT MinorRevision; + struct { + USHORT SmartCommands :1; + USHORT SecurityMode :1; + USHORT RemovableMedia :1; + USHORT PowerManagement :1; + USHORT PacketCommands :1; + USHORT WriteCache :1; + USHORT LookAhead :1; + USHORT ReleaseInterrupt :1; + USHORT ServiceInterrupt :1; + USHORT DeviceReset :1; + USHORT HostProtectedArea :1; + USHORT Obsolete1 :1; + USHORT WriteBuffer :1; + USHORT ReadBuffer :1; + USHORT Nop :1; + USHORT Obsolete2 :1; + USHORT DownloadMicrocode :1; + USHORT Reserved1 :2; + USHORT AdvancedPm :1; + USHORT Msn :1; + USHORT PowerUpInStandby :1; + USHORT ManualPowerUp :1; + USHORT Reserved2 :1; + USHORT SetMax :1; + USHORT Reserved3 :3; + USHORT FlushCache :1; + USHORT Reserved4 :1; + USHORT WordValid :2; + } CommandSetSupport; + struct { + USHORT Reserved0 :5; + USHORT GpLogging :1; + USHORT Reserved1 :2; + USHORT WWN64Bit :1; + USHORT Reserved2 :5; + USHORT WordValid :2; + } CommandSetSupportExt; + struct { + USHORT SmartCommands :1; + USHORT SecurityMode :1; + USHORT RemovableMedia :1; + USHORT PowerManagement :1; + USHORT PacketCommands :1; + USHORT WriteCache :1; + USHORT LookAhead :1; + USHORT ReleaseInterrupt :1; + USHORT ServiceInterrupt :1; + USHORT DeviceReset :1; + USHORT HostProtectedArea :1; + USHORT Obsolete1 :1; + USHORT WriteBuffer :1; + USHORT ReadBuffer :1; + USHORT Nop :1; + USHORT Obsolete2 :1; + USHORT DownloadMicrocode :1; + USHORT Reserved1 :2; + USHORT AdvancedPm :1; + USHORT Msn :1; + USHORT PowerUpInStandby :1; + USHORT ManualPowerUp :1; + USHORT Reserved2 :1; + USHORT SetMax :1; + USHORT Reserved3 :3; + USHORT FlushCache :1; + USHORT Reserved :3; + } CommandSetActive; + struct { + USHORT Reserved0 :5; + USHORT GpLogging :1; + USHORT Reserved1 :2; + USHORT WWN64Bit :1; + USHORT Reserved2 :5; + USHORT WordValid :2; + } CommandSetActiveExt; + USHORT UltraDMASupport :8; + USHORT UltraDMAActive :8; + USHORT TimeRequiredForNormalEraseModeSecurityEraseUnit; + USHORT TimeRequiredForEnhancedEraseModeSecurityEraseUnit; + USHORT CurrentAPMLevel; + USHORT MasterPasswordID; + USHORT HardwareResetResult; + USHORT ReservedWords94[14]; + USHORT WorldWideName[4]; + USHORT ReservedWords112[13]; + USHORT AtapiZeroByteCount; + USHORT ReservedWord126; + USHORT MsnSupport :2; + USHORT ReservedWord127 :14; + USHORT SecurityStatus; + USHORT VendorSpecific[31]; + USHORT ReservedWord160[16]; + USHORT ReservedWord176[46]; + struct { + USHORT MajorVersion :12; + USHORT TransportType :4; + } TransportMajorVersion; + USHORT TransportMinorVersion; + USHORT ReservedWord224[31]; + USHORT Signature :8; + USHORT CheckSum :8; +} IDENTIFY_PACKET_DATA, *PIDENTIFY_PACKET_DATA; + +typedef struct _GP_LOG_NCQ_COMMAND_ERROR { + UCHAR NcqTag : 5; + UCHAR Reserved0 : 1; + UCHAR UNL : 1; + UCHAR NonQueuedCmd : 1; + UCHAR Reserved1; + UCHAR Status; + UCHAR Error; + UCHAR LBA7_0; + UCHAR LBA15_8; + UCHAR LBA23_16; + UCHAR Device; + UCHAR LBA31_24; + UCHAR LBA39_32; + UCHAR LBA47_40; + UCHAR Reserved2; + UCHAR Count7_0; + UCHAR Count15_8; + UCHAR SenseKey; + UCHAR ASC; + UCHAR ASCQ; + UCHAR Reserved3[239]; + UCHAR Vendor[255]; + UCHAR Checksum; +} GP_LOG_NCQ_COMMAND_ERROR, *PGP_LOG_NCQ_COMMAND_ERROR; #include #define IDE_LBA_MODE (1 << 6) -#define IDE_COMMAND_NOP 0x00 -#define IDE_COMMAND_DATA_SET_MANAGEMENT 0x06 -#define IDE_COMMAND_ATAPI_RESET 0x08 -#define IDE_COMMAND_READ 0x20 -#define IDE_COMMAND_READ_EXT 0x24 -#define IDE_COMMAND_READ_DMA_EXT 0x25 -#define IDE_COMMAND_READ_DMA_QUEUED_EXT 0x26 -#define IDE_COMMAND_READ_MULTIPLE_EXT 0x29 -#define IDE_COMMAND_WRITE 0x30 -#define IDE_COMMAND_WRITE_EXT 0x34 -#define IDE_COMMAND_WRITE_DMA_EXT 0x35 -#define IDE_COMMAND_WRITE_DMA_QUEUED_EXT 0x36 -#define IDE_COMMAND_WRITE_MULTIPLE_EXT 0x39 -#define IDE_COMMAND_WRITE_DMA_FUA_EXT 0x3D -#define IDE_COMMAND_WRITE_DMA_QUEUED_FUA_EXT 0x3E -#define IDE_COMMAND_VERIFY 0x40 -#define IDE_COMMAND_VERIFY_EXT 0x42 -#define IDE_COMMAND_EXECUTE_DEVICE_DIAGNOSTIC 0x90 -#define IDE_COMMAND_SET_DRIVE_PARAMETERS 0x91 -#define IDE_COMMAND_ATAPI_PACKET 0xA0 -#define IDE_COMMAND_ATAPI_IDENTIFY 0xA1 -#define IDE_COMMAND_SMART 0xB0 -#define IDE_COMMAND_READ_MULTIPLE 0xC4 -#define IDE_COMMAND_WRITE_MULTIPLE 0xC5 -#define IDE_COMMAND_SET_MULTIPLE 0xC6 -#define IDE_COMMAND_READ_DMA 0xC8 -#define IDE_COMMAND_WRITE_DMA 0xCA -#define IDE_COMMAND_WRITE_DMA_QUEUED 0xCC -#define IDE_COMMAND_WRITE_MULTIPLE_FUA_EXT 0xCE -#define IDE_COMMAND_GET_MEDIA_STATUS 0xDA -#define IDE_COMMAND_DOOR_LOCK 0xDE -#define IDE_COMMAND_DOOR_UNLOCK 0xDF -#define IDE_COMMAND_STANDBY_IMMEDIATE 0xE0 -#define IDE_COMMAND_IDLE_IMMEDIATE 0xE1 -#define IDE_COMMAND_CHECK_POWER 0xE5 -#define IDE_COMMAND_SLEEP 0xE6 -#define IDE_COMMAND_FLUSH_CACHE 0xE7 -#define IDE_COMMAND_FLUSH_CACHE_EXT 0xEA -#define IDE_COMMAND_IDENTIFY 0xEC -#define IDE_COMMAND_MEDIA_EJECT 0xED -#define IDE_COMMAND_SET_FEATURE 0xEF -#define IDE_COMMAND_SECURITY_FREEZE_LOCK 0xF5 -#define IDE_COMMAND_NOT_VALID 0xFF +#define IDE_DC_DISABLE_INTERRUPTS 0x02 +#define IDE_DC_RESET_CONTROLLER 0x04 +#define IDE_DC_REENABLE_CONTROLLER 0x00 + +#define IDE_STATUS_ERROR 0x01 +#define IDE_STATUS_INDEX 0x02 +#define IDE_STATUS_CORRECTED_ERROR 0x04 +#define IDE_STATUS_DRQ 0x08 +#define IDE_STATUS_DSC 0x10 +#define IDE_STATUS_DEVICE_FAULT 0x20 +#define IDE_STATUS_DRDY 0x40 +#define IDE_STATUS_IDLE 0x50 +#define IDE_STATUS_BUSY 0x80 + +#define IDE_ERROR_ILLEGAL_LENGTH 0x01 +#define IDE_ERROR_ADDRESS_NOT_FOUND IDE_ERROR_ILLEGAL_LENGTH +#define IDE_ERROR_END_OF_MEDIA 0x02 +#define IDE_ERROR_COMMAND_ABORTED 0x04 +#define IDE_ERROR_MEDIA_CHANGE_REQ 0x08 +#define IDE_ERROR_ID_NOT_FOUND 0x10 +#define IDE_ERROR_MEDIA_CHANGE 0x20 +#define IDE_ERROR_DATA_ERROR 0x40 +#define IDE_ERROR_BAD_BLOCK 0x80 +#define IDE_ERROR_CRC_ERROR IDE_ERROR_BAD_BLOCK + +#define IDE_COMMAND_NOP 0x00 +#define IDE_COMMAND_DATA_SET_MANAGEMENT 0x06 +#define IDE_COMMAND_ATAPI_RESET 0x08 +#define IDE_COMMAND_GET_PHYSICAL_ELEMENT_STATUS 0x12 +#define IDE_COMMAND_READ 0x20 +#define IDE_COMMAND_READ_EXT 0x24 +#define IDE_COMMAND_READ_DMA_EXT 0x25 +#define IDE_COMMAND_READ_DMA_QUEUED_EXT 0x26 +#define IDE_COMMAND_READ_MULTIPLE_EXT 0x29 +#define IDE_COMMAND_READ_LOG_EXT 0x2F +#define IDE_COMMAND_WRITE 0x30 +#define IDE_COMMAND_WRITE_EXT 0x34 +#define IDE_COMMAND_WRITE_DMA_EXT 0x35 +#define IDE_COMMAND_WRITE_DMA_QUEUED_EXT 0x36 +#define IDE_COMMAND_WRITE_MULTIPLE_EXT 0x39 +#define IDE_COMMAND_WRITE_DMA_FUA_EXT 0x3D +#define IDE_COMMAND_WRITE_DMA_QUEUED_FUA_EXT 0x3E +#define IDE_COMMAND_WRITE_LOG_EXT 0x3F +#define IDE_COMMAND_VERIFY 0x40 +#define IDE_COMMAND_VERIFY_EXT 0x42 +#define IDE_COMMAND_ZAC_MANAGEMENT_IN 0x4A +#define IDE_COMMAND_WRITE_LOG_DMA_EXT 0x57 +#define IDE_COMMAND_TRUSTED_NON_DATA 0x5B +#define IDE_COMMAND_TRUSTED_RECEIVE 0x5C +#define IDE_COMMAND_TRUSTED_RECEIVE_DMA 0x5D +#define IDE_COMMAND_TRUSTED_SEND 0x5E +#define IDE_COMMAND_TRUSTED_SEND_DMA 0x5F +#define IDE_COMMAND_READ_FPDMA_QUEUED 0x60 +#define IDE_COMMAND_WRITE_FPDMA_QUEUED 0x61 +#define IDE_COMMAND_NCQ_NON_DATA 0x63 +#define IDE_COMMAND_SEND_FPDMA_QUEUED 0x64 +#define IDE_COMMAND_RECEIVE_FPDMA_QUEUED 0x65 +#define IDE_COMMAND_SET_DATE_AND_TIME 0x77 +#define IDE_COMMAND_REMOVE_ELEMENT_AND_TRUNCATE 0x7C +#define IDE_COMMAND_EXECUTE_DEVICE_DIAGNOSTIC 0x90 +#define IDE_COMMAND_SET_DRIVE_PARAMETERS 0x91 +#define IDE_COMMAND_DOWNLOAD_MICROCODE 0x92 +#define IDE_COMMAND_DOWNLOAD_MICROCODE_DMA 0x93 +#define IDE_COMMAND_ZAC_MANAGEMENT_OUT 0x9F +#define IDE_COMMAND_ATAPI_PACKET 0xA0 +#define IDE_COMMAND_ATAPI_IDENTIFY 0xA1 +#define IDE_COMMAND_SMART 0xB0 +#define IDE_COMMAND_READ_LOG_DMA_EXT 0xB1 +#define IDE_COMMAND_SANITIZE_DEVICE 0xB4 +#define IDE_COMMAND_READ_MULTIPLE 0xC4 +#define IDE_COMMAND_WRITE_MULTIPLE 0xC5 +#define IDE_COMMAND_SET_MULTIPLE 0xC6 +#define IDE_COMMAND_READ_DMA 0xC8 +#define IDE_COMMAND_WRITE_DMA 0xCA +#define IDE_COMMAND_WRITE_DMA_QUEUED 0xCC +#define IDE_COMMAND_WRITE_MULTIPLE_FUA_EXT 0xCE +#define IDE_COMMAND_GET_MEDIA_STATUS 0xDA +#define IDE_COMMAND_DOOR_LOCK 0xDE +#define IDE_COMMAND_DOOR_UNLOCK 0xDF +#define IDE_COMMAND_STANDBY_IMMEDIATE 0xE0 +#define IDE_COMMAND_IDLE_IMMEDIATE 0xE1 +#define IDE_COMMAND_CHECK_POWER 0xE5 +#define IDE_COMMAND_SLEEP 0xE6 +#define IDE_COMMAND_FLUSH_CACHE 0xE7 +#define IDE_COMMAND_FLUSH_CACHE_EXT 0xEA +#define IDE_COMMAND_IDENTIFY 0xEC +#define IDE_COMMAND_MEDIA_EJECT 0xED +#define IDE_COMMAND_SET_FEATURE 0xEF +#define IDE_COMMAND_SECURITY_SET_PASSWORD 0xF1 +#define IDE_COMMAND_SECURITY_UNLOCK 0xF2 +#define IDE_COMMAND_SECURITY_ERASE_PREPARE 0xF3 +#define IDE_COMMAND_SECURITY_ERASE_UNIT 0xF4 +#define IDE_COMMAND_SECURITY_FREEZE_LOCK 0xF5 +#define IDE_COMMAND_SECURITY_DISABLE_PASSWORD 0xF6 +#define IDE_COMMAND_NOT_VALID 0xFF + +#define IDE_FEATURE_ENABLE_WRITE_CACHE 0x2 +#define IDE_FEATURE_SET_TRANSFER_MODE 0x3 +#define IDE_FEATURE_ENABLE_PUIS 0x6 +#define IDE_FEATURE_PUIS_SPIN_UP 0x7 +#define IDE_FEATURE_ENABLE_SATA_FEATURE 0x10 +#define IDE_FEATURE_DISABLE_MSN 0x31 +#define IDE_FEATURE_DISABLE_REVERT_TO_POWER_ON 0x66 +#define IDE_FEATURE_DISABLE_WRITE_CACHE 0x82 +#define IDE_FEATURE_DISABLE_PUIS 0x86 +#define IDE_FEATURE_DISABLE_SATA_FEATURE 0x90 +#define IDE_FEATURE_ENABLE_MSN 0x95 #endif diff --git a/sdk/include/ddk/d3dkmddi.h b/sdk/include/ddk/d3dkmddi.h new file mode 100644 index 0000000000000..d319665f113e3 --- /dev/null +++ b/sdk/include/ddk/d3dkmddi.h @@ -0,0 +1,241 @@ +/* + * PROJECT: ReactOS Display Driver Model + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: Header file for WDDM style DDIs + * COPYRIGHT: Copyright 2024 Justin Miller + */ + +#ifndef _D3DKMDDI_H_ +#define _D3DKMDDI_H_ + +#include + +typedef struct _DXGK_ALLOCATIONINFOFLAGS_WDDM2_0 +{ + union + { + struct + { + UINT CpuVisible : 1; + UINT PermanentSysMem : 1; + UINT Cached : 1; + UINT Protected : 1; + UINT ExistingSysMem : 1; + UINT ExistingKernelSysMem : 1; + UINT FromEndOfSegment : 1; + UINT DisableLargePageMapping : 1; + UINT Overlay : 1; + UINT Capture : 1; +#if (DXGKDDI_INTERFACE_VERSION >= DXGKDDI_INTERFACE_VERSION_WDDM2_1) + UINT CreateInVpr : 1; +#else + UINT Reserved00 : 1; +#endif + UINT DXGK_ALLOC_RESERVED17 : 1; + UINT Reserved02 : 1; +#if (DXGKDDI_INTERFACE_VERSION >= DXGKDDI_INTERFACE_VERSION_WDDM2_9) + UINT MapApertureCpuVisible : 1; +#else + UINT Reserved03 : 1; +#endif + UINT HistoryBuffer : 1; + UINT AccessedPhysically : 1; + UINT ExplicitResidencyNotification : 1; + UINT HardwareProtected : 1; + UINT CpuVisibleOnDemand : 1; + UINT DXGK_ALLOC_RESERVED16 : 1; + UINT DXGK_ALLOC_RESERVED15 : 1; + UINT DXGK_ALLOC_RESERVED14 : 1; + UINT DXGK_ALLOC_RESERVED13 : 1; + UINT DXGK_ALLOC_RESERVED12 : 1; + UINT DXGK_ALLOC_RESERVED11 : 1; + UINT DXGK_ALLOC_RESERVED10 : 1; + UINT DXGK_ALLOC_RESERVED9 : 1; + UINT DXGK_ALLOC_RESERVED4 : 1; + UINT DXGK_ALLOC_RESERVED3 : 1; + UINT DXGK_ALLOC_RESERVED2 : 1; + UINT DXGK_ALLOC_RESERVED1 : 1; + UINT DXGK_ALLOC_RESERVED0 : 1; + }; + UINT Value; + }; +} DXGK_ALLOCATIONINFOFLAGS_WDDM2_0; +C_ASSERT(sizeof(DXGK_ALLOCATIONINFOFLAGS_WDDM2_0) == 0x4); + +typedef struct _DXGK_SEGMENTPREFERENCE +{ + union + { + struct + { + UINT SegmentId0 : 5; + UINT Direction0 : 1; + UINT SegmentId1 : 5; + UINT Direction1 : 1; + UINT SegmentId2 : 5; + UINT Direction2 : 1; + UINT SegmentId3 : 5; + UINT Direction3 : 1; + UINT SegmentId4 : 5; + UINT Direction4 : 1; + UINT Reserved : 2; + }; + UINT Value; + }; +} DXGK_SEGMENTPREFERENCE, *PDXGK_SEGMENTPREFERENCE; +C_ASSERT(sizeof(DXGK_SEGMENTPREFERENCE) == 0x4); + +typedef struct _DXGK_SEGMENTBANKPREFERENCE +{ + union + { + struct + { + UINT Bank0 : 7; + UINT Direction0 : 1; + UINT Bank1 : 7; + UINT Direction1 : 1; + UINT Bank2 : 7; + UINT Direction2 : 1; + UINT Bank3 : 7; + UINT Direction3 : 1; + }; + UINT Value; + }; +} DXGK_SEGMENTBANKPREFERENCE; +C_ASSERT(sizeof(DXGK_SEGMENTBANKPREFERENCE) == 0x4); + +typedef struct _DXGK_ALLOCATIONINFOFLAGS +{ + union + { + struct + { + UINT CpuVisible : 1; + UINT PermanentSysMem : 1; + UINT Cached : 1; + UINT Protected : 1; + UINT ExistingSysMem : 1; + UINT ExistingKernelSysMem : 1; + UINT FromEndOfSegment : 1; + UINT Swizzled : 1; + UINT Overlay : 1; + UINT Capture : 1; + UINT UseAlternateVA : 1; + UINT SynchronousPaging : 1; + UINT LinkMirrored : 1; + UINT LinkInstanced : 1; + UINT HistoryBuffer : 1; +#if (DXGKDDI_INTERFACE_VERSION >= DXGKDDI_INTERFACE_VERSION_WDDM2_0) + UINT AccessedPhysically : 1; + UINT ExplicitResidencyNotification : 1; + UINT HardwareProtected : 1; + UINT CpuVisibleOnDemand : 1; +#else + UINT Reserved : 4; +#endif + UINT DXGK_ALLOC_RESERVED16 : 1; + UINT DXGK_ALLOC_RESERVED15 : 1; + UINT DXGK_ALLOC_RESERVED14 : 1; + UINT DXGK_ALLOC_RESERVED13 : 1; + UINT DXGK_ALLOC_RESERVED12 : 1; + UINT DXGK_ALLOC_RESERVED11 : 1; + UINT DXGK_ALLOC_RESERVED10 : 1; + UINT DXGK_ALLOC_RESERVED9 : 1; + UINT DXGK_ALLOC_RESERVED4 : 1; + UINT DXGK_ALLOC_RESERVED3 : 1; + UINT DXGK_ALLOC_RESERVED2 : 1; + UINT DXGK_ALLOC_RESERVED1 : 1; + UINT DXGK_ALLOC_RESERVED0 : 1; + }; + UINT Value; + }; +} DXGK_ALLOCATIONINFOFLAGS; +C_ASSERT(sizeof(DXGK_ALLOCATIONINFOFLAGS) == 0x4); + +typedef struct _DXGK_ALLOCATIONUSAGEINFO1 +{ + union + { + struct + { + UINT PrivateFormat : 1; + UINT Swizzled : 1; + UINT MipMap : 1; + UINT Cube : 1; + UINT Volume : 1; + UINT Vertex : 1; + UINT Index : 1; + UINT Reserved : 25; + }; + UINT Value; + } Flags; + union + { + D3DDDIFORMAT Format; + UINT PrivateFormat; + }; + UINT SwizzledFormat; + UINT ByteOffset; + UINT Width; + UINT Height; + UINT Pitch; + UINT Depth; + UINT SlicePitch; +} DXGK_ALLOCATIONUSAGEINFO1; +C_ASSERT(sizeof(DXGK_ALLOCATIONUSAGEINFO1) == 0x24); + +typedef struct _DXGK_ALLOCATIONUSAGEHINT +{ + UINT Version; + DXGK_ALLOCATIONUSAGEINFO1 v1; +} DXGK_ALLOCATIONUSAGEHINT; +C_ASSERT(sizeof(DXGK_ALLOCATIONUSAGEHINT) == 0x28); + +typedef struct _DXGK_ALLOCATIONINFO +{ + VOID* pPrivateDriverData; + UINT PrivateDriverDataSize; + UINT Alignment; + SIZE_T Size; + SIZE_T PitchAlignedSize; + DXGK_SEGMENTBANKPREFERENCE HintedBank; + DXGK_SEGMENTPREFERENCE PreferredSegment; + UINT SupportedReadSegmentSet; + UINT SupportedWriteSegmentSet; + UINT EvictionSegmentSet; + union + { + UINT MaximumRenamingListLength; + UINT PhysicalAdapterIndex; + }; + HANDLE hAllocation; + union + { + DXGK_ALLOCATIONINFOFLAGS Flags; +#if (DXGKDDI_INTERFACE_VERSION >= DXGKDDI_INTERFACE_VERSION_WDDM2_0) + DXGK_ALLOCATIONINFOFLAGS_WDDM2_0 FlagsWddm2; +#endif + }; + DXGK_ALLOCATIONUSAGEHINT* pAllocationUsageHint; + UINT AllocationPriority; +#if (DXGKDDI_INTERFACE_VERSION >= DXGKDDI_INTERFACE_VERSION_WDDM3_0) + DXGK_ALLOCATIONINFOFLAGS2 Flags2; +#endif +} DXGK_ALLOCATIONINFO; + +#ifdef _WIN64 +#if (DXGKDDI_INTERFACE_VERSION >= DXGKDDI_INTERFACE_VERSION_WDDM3_0) +C_ASSERT(sizeof(DXGK_ALLOCATIONINFO) == 0x5C); +#else +C_ASSERT(sizeof(DXGK_ALLOCATIONINFO) == 0x58); +#endif +#else +#if (DXGKDDI_INTERFACE_VERSION >= DXGKDDI_INTERFACE_VERSION_WDDM3_0) +C_ASSERT(sizeof(DXGK_ALLOCATIONINFO) == 0x40); +#else +C_ASSERT(sizeof(DXGK_ALLOCATIONINFO) == 0x3C); +#endif +#endif + +#endif // _D3DKMDDI_H_ diff --git a/sdk/include/ddk/ntmsv1_0.h b/sdk/include/ddk/ntmsv1_0.h new file mode 100644 index 0000000000000..7db82d1feb155 --- /dev/null +++ b/sdk/include/ddk/ntmsv1_0.h @@ -0,0 +1,47 @@ +#ifndef _NTMSV1_0_ +#define _NTMSV1_0_ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _MSV1_0_ENUMUSERS_REQUEST +{ + MSV1_0_PROTOCOL_MESSAGE_TYPE MessageType; +} MSV1_0_ENUMUSERS_REQUEST, *PMSV1_0_ENUMUSERS_REQUEST; + +typedef struct _MSV1_0_ENUMUSERS_RESPONSE +{ + MSV1_0_PROTOCOL_MESSAGE_TYPE MessageType; + ULONG NumberOfLoggedOnUsers; + PLUID LogonIds; + PULONG EnumHandles; +} MSV1_0_ENUMUSERS_RESPONSE, *PMSV1_0_ENUMUSERS_RESPONSE; + +typedef struct _MSV1_0_GETUSERINFO_REQUEST +{ + MSV1_0_PROTOCOL_MESSAGE_TYPE MessageType; + LUID LogonId; +} MSV1_0_GETUSERINFO_REQUEST, *PMSV1_0_GETUSERINFO_REQUEST; + +typedef struct _MSV1_0_GETUSERINFO_RESPONSE +{ + MSV1_0_PROTOCOL_MESSAGE_TYPE MessageType; + PSID UserSid; + UNICODE_STRING UserName; + UNICODE_STRING LogonDomainName; + UNICODE_STRING LogonServer; + SECURITY_LOGON_TYPE LogonType; +} MSV1_0_GETUSERINFO_RESPONSE, *PMSV1_0_GETUSERINFO_RESPONSE; + +typedef struct _MSV1_0_RELOGON_REQUEST +{ + MSV1_0_PROTOCOL_MESSAGE_TYPE MessageType; + UNICODE_STRING LogonServer; +} MSV1_0_RELOGON_REQUEST, *PMSV1_0_RELOGON_REQUEST; + +#ifdef __cplusplus +} +#endif + +#endif /* _NTMSV1_0_ */ diff --git a/sdk/include/ndk/amd64/asm.h b/sdk/include/ndk/amd64/asm.h deleted file mode 100644 index 9adcc3842d12b..0000000000000 --- a/sdk/include/ndk/amd64/asm.h +++ /dev/null @@ -1,427 +0,0 @@ -/*++ NDK Version: 0095 - -Copyright (c) Alex Ionescu. All rights reserved. - -Header Name: - - amd64/asm.h - -Abstract: - - ASM Offsets for dealing with de-referencing structures in registers. - -Author: - - Timo Kreuzer (timo.kreuzer@reactos.org) 06-Sep-2008 - ---*/ -#ifndef _ASM_AMD64_H -#define _ASM_AMD64_H - -#ifndef HEX - #ifdef _USE_ML - #define HEX(x) x##h - #else - #define HEX(val) 0x0##val - #endif -#endif - -#define SIZEOF_FX_SAVE_AREA 528 // HACK - -// -// CPU Modes -// -#define KernelMode HEX(0) -#define UserMode HEX(1) - -// -// KTSS Offsets -// -#define KTSS64_RSP0 HEX(04) -#define KTSS64_RSP1 HEX(0c) -#define KTSS64_RSP2 HEX(14) -#define KTSS64_IST HEX(1c) -#define KTSS64_IO_MAP_BASE HEX(66) - -// -// KTHREAD Offsets -// -#define KTHREAD_DEBUG_ACTIVE HEX(03) -#define KTHREAD_INITIAL_STACK HEX(28) -#define KTHREAD_STACK_LIMIT HEX(30) -#define KTHREAD_WAIT_IRQL HEX(156) - -// -// KPRCB Offsets -// -#define KPRCB_CurrentThread HEX(08) - - -// -// KPCR Offsets -// -#define KPCR_TSS_BASE HEX(08) -#define KPCR_SELF HEX(18) -#define KPCR_STALL_SCALE_FACTOR HEX(64) -#define KPCR_PRCB HEX(180 - -// -// KTRAP_FRAME Offsets -// -#define KTRAP_FRAME_P1Home HEX(00) -#define KTRAP_FRAME_P2Home HEX(08) -#define KTRAP_FRAME_P3Home HEX(10) -#define KTRAP_FRAME_P4Home HEX(18) -#define KTRAP_FRAME_P5 HEX(20) -#define KTRAP_FRAME_PreviousMode HEX(28) -#define KTRAP_FRAME_PreviousIrql HEX(29) -#define KTRAP_FRAME_FaultIndicator HEX(2A) -#define KTRAP_FRAME_ExceptionActive HEX(2B) -#define KTRAP_FRAME_MxCsr HEX(2C) -#define KTRAP_FRAME_Rax HEX(30) -#define KTRAP_FRAME_Rcx HEX(38) -#define KTRAP_FRAME_Rdx HEX(40) -#define KTRAP_FRAME_R8 HEX(48) -#define KTRAP_FRAME_R9 HEX(50) -#define KTRAP_FRAME_R10 HEX(58) -#define KTRAP_FRAME_R11 HEX(60) -#define KTRAP_FRAME_GsBase HEX(68) -#define KTRAP_FRAME_Xmm0 HEX(70) -#define KTRAP_FRAME_Xmm1 HEX(80) -#define KTRAP_FRAME_Xmm2 HEX(90) -#define KTRAP_FRAME_Xmm3 HEX(A0) -#define KTRAP_FRAME_Xmm4 HEX(B0) -#define KTRAP_FRAME_Xmm5 HEX(C0) -#define KTRAP_FRAME_FaultAddress HEX(D0) -#define KTRAP_FRAME_Dr0 HEX(D8) -#define KTRAP_FRAME_Dr1 HEX(E0) -#define KTRAP_FRAME_Dr2 HEX(E8) -#define KTRAP_FRAME_Dr3 HEX(F0) -#define KTRAP_FRAME_Dr6 HEX(F8) -#define KTRAP_FRAME_Dr7 HEX(100) -#define KTRAP_FRAME_DebugControl HEX(108) -#define KTRAP_FRAME_LastBranchToRip HEX(110) -#define KTRAP_FRAME_LastBranchFromRip HEX(118) -#define KTRAP_FRAME_LastExceptionToRip HEX(120) -#define KTRAP_FRAME_LastExceptionFromRip HEX(128) -#define KTRAP_FRAME_SegDs HEX(130) -#define KTRAP_FRAME_SegEs HEX(132) -#define KTRAP_FRAME_SegFs HEX(134) -#define KTRAP_FRAME_SegGs HEX(136) -#define KTRAP_FRAME_TrapFrame HEX(138) -#define KTRAP_FRAME_Rbx HEX(140) -#define KTRAP_FRAME_Rdi HEX(148) -#define KTRAP_FRAME_Rsi HEX(150) -#define KTRAP_FRAME_Rbp HEX(158) -#define KTRAP_FRAME_ErrorCode HEX(160) -#define KTRAP_FRAME_Rip HEX(168) -#define KTRAP_FRAME_SegCs HEX(170) -#define KTRAP_FRAME_Logging HEX(173) -#define KTRAP_FRAME_EFlags HEX(178) -#define KTRAP_FRAME_Rsp HEX(180) -#define KTRAP_FRAME_SegSs HEX(188) -#define KTRAP_FRAME_CodePatchCycle HEX(18c) -#define SIZE_KTRAP_FRAME HEX(190) -#define KTRAP_FRAME_ALIGN HEX(10) -#define KTRAP_FRAME_LENGTH HEX(190) - -// -// CONTEXT Offsets -// -#define CONTEXT_P1Home 0 -#define CONTEXT_P2Home HEX(08) -#define CONTEXT_P3Home HEX(10) -#define CONTEXT_P4Home HEX(18) -#define CONTEXT_P5Home HEX(20) -#define CONTEXT_P6Home HEX(28) -#define CONTEXT_ContextFlags HEX(30) -#define CONTEXT_MxCsr HEX(34) -#define CONTEXT_SegCs HEX(38) -#define CONTEXT_SegDs HEX(3a) -#define CONTEXT_SegEs HEX(3c) -#define CONTEXT_SegFs HEX(3e) -#define CONTEXT_SegGs HEX(40) -#define CONTEXT_SegSs HEX(42) -#define CONTEXT_EFlags HEX(44) -#define CONTEXT_Dr0 HEX(48) -#define CONTEXT_Dr1 HEX(50) -#define CONTEXT_Dr2 HEX(58) -#define CONTEXT_Dr3 HEX(60) -#define CONTEXT_Dr6 HEX(68) -#define CONTEXT_Dr7 HEX(70) -#define CONTEXT_Rax HEX(78) -#define CONTEXT_Rcx HEX(80) -#define CONTEXT_Rdx HEX(88) -#define CONTEXT_Rbx HEX(90) -#define CONTEXT_Rsp HEX(98) -#define CONTEXT_Rbp HEX(a0) -#define CONTEXT_Rsi HEX(a8) -#define CONTEXT_Rdi HEX(b0) -#define CONTEXT_R8 HEX(b8) -#define CONTEXT_R9 HEX(c0) -#define CONTEXT_R10 HEX(c8) -#define CONTEXT_R11 HEX(d0) -#define CONTEXT_R12 HEX(d8) -#define CONTEXT_R13 HEX(e0) -#define CONTEXT_R14 HEX(e8) -#define CONTEXT_R15 HEX(f0) -#define CONTEXT_Rip HEX(f8) -#define CONTEXT_Header HEX(100) -#define CONTEXT_Legacy HEX(120) -#define CONTEXT_Xmm0 HEX(1a0) -#define CONTEXT_Xmm1 HEX(1b0) -#define CONTEXT_Xmm2 HEX(1c0) -#define CONTEXT_Xmm3 HEX(1d0) -#define CONTEXT_Xmm4 HEX(1e0) -#define CONTEXT_Xmm5 HEX(1f0) -#define CONTEXT_Xmm6 HEX(200) -#define CONTEXT_Xmm7 HEX(210) -#define CONTEXT_Xmm8 HEX(220) -#define CONTEXT_Xmm9 HEX(230) -#define CONTEXT_Xmm10 HEX(240) -#define CONTEXT_Xmm11 HEX(250) -#define CONTEXT_Xmm12 HEX(260) -#define CONTEXT_Xmm13 HEX(270) -#define CONTEXT_Xmm14 HEX(280) -#define CONTEXT_Xmm15 HEX(290) -#define CONTEXT_VectorRegister HEX(300) -#define CONTEXT_VectorControl HEX(4a0) -#define CONTEXT_DebugControl HEX(4a8) -#define CONTEXT_LastBranchToRip HEX(4b0) -#define CONTEXT_LastBranchFromRip HEX(4b8) -#define CONTEXT_LastExceptionToRip HEX(4c0) -#define CONTEXT_LastExceptionFromRip HEX(4c8) - -// -// KEXCEPTION_FRAME offsets -// -#define KEXCEPTION_FRAME_P1Home HEX(000) -#define KEXCEPTION_FRAME_P2Home HEX(008) -#define KEXCEPTION_FRAME_P3Home HEX(010) -#define KEXCEPTION_FRAME_P4Home HEX(018) -#define KEXCEPTION_FRAME_P5 HEX(020) -#define KEXCEPTION_FRAME_InitialStack HEX(028) -#define KEXCEPTION_FRAME_Xmm6 HEX(030) -#define KEXCEPTION_FRAME_Xmm7 HEX(040) -#define KEXCEPTION_FRAME_Xmm8 HEX(050) -#define KEXCEPTION_FRAME_Xmm9 HEX(060) -#define KEXCEPTION_FRAME_Xmm10 HEX(070) -#define KEXCEPTION_FRAME_Xmm11 HEX(080) -#define KEXCEPTION_FRAME_Xmm12 HEX(090) -#define KEXCEPTION_FRAME_Xmm13 HEX(0A0) -#define KEXCEPTION_FRAME_Xmm14 HEX(0B0) -#define KEXCEPTION_FRAME_Xmm15 HEX(0C0) -#define KEXCEPTION_FRAME_TrapFrame HEX(0D0) -#define KEXCEPTION_FRAME_CallbackStack HEX(0D8) -#define KEXCEPTION_FRAME_OutputBuffer HEX(0E0) -#define KEXCEPTION_FRAME_OutputLength HEX(0E8) -#define KEXCEPTION_FRAME_MxCsr HEX(0F0) -#define KEXCEPTION_FRAME_Rbp HEX(0F8) -#define KEXCEPTION_FRAME_Rbx HEX(100) -#define KEXCEPTION_FRAME_Rdi HEX(108) -#define KEXCEPTION_FRAME_Rsi HEX(110) -#define KEXCEPTION_FRAME_R12 HEX(118) -#define KEXCEPTION_FRAME_R13 HEX(120) -#define KEXCEPTION_FRAME_R14 HEX(128) -#define KEXCEPTION_FRAME_R15 HEX(130) -#define KEXCEPTION_FRAME_Return HEX(138) -#define SIZE_KEXCEPTION_FRAME HEX(140) - - -// -// EXCEPTION_RECORD Offsets -// -#define EXCEPTION_RECORD_ExceptionCode HEX(00) -#define EXCEPTION_RECORD_ExceptionFlags HEX(04) -#define EXCEPTION_RECORD_ExceptionRecord HEX(08) -#define EXCEPTION_RECORD_ExceptionAddress HEX(10) -#define EXCEPTION_RECORD_NumberParameters HEX(18) -#define EXCEPTION_RECORD_ExceptionInformation HEX(20) -#define SIZE_EXCEPTION_RECORD HEX(98) - -// -// CR0 -// -#define CR0_PE HEX(1) -#define CR0_MP HEX(2) -#define CR0_EM HEX(4) -#define CR0_TS HEX(8) -#define CR0_ET HEX(10) -#define CR0_NE HEX(20) -#define CR0_WP HEX(10000) -#define CR0_AM HEX(40000) -#define CR0_NW HEX(20000000) -#define CR0_CD HEX(40000000) -#define CR0_PG HEX(80000000) - -/* Number of bytes reserved for syscall parameters */ -#define MAX_SYSCALL_PARAM_SIZE (16 * 8) - -#ifdef _ASM_ -// -// CR4 -// -#define CR4_VME HEX(1) -#define CR4_PVI HEX(2) -#define CR4_TSD HEX(4) -#define CR4_DE HEX(8) -#define CR4_PSE HEX(10) -#define CR4_PAE HEX(20) -#define CR4_MCE HEX(40) -#define CR4_PGE HEX(80) -#define CR4_FXSR HEX(200) -#define CR4_XMMEXCPT HEX(400) -#endif - -// -// Generic Definitions -// -#define PRIMARY_VECTOR_BASE HEX(30) -#define MAXIMUM_IDTVECTOR HEX(FF) - -// -// Usermode callout frame definitions -// -#define CBSTACK_STACK HEX(0) -#define CBSTACK_TRAP_FRAME HEX(8) -#define CBSTACK_CALLBACK_STACK HEX(10) -#define CBSTACK_RBP HEX(18) -#define CBSTACK_RESULT HEX(20) -#define CBSTACK_RESULT_LENGTH HEX(28) - - -/* Following ones are ASM only! ***********************************************/ - -#ifdef __ASM__ - -// -// PCR Access -// -#define PCR gs: - -// -// EFLAGS -// -#define EFLAGS_TF HEX(100) -#define EFLAGS_INTERRUPT_MASK HEX(200) -#define EFLAGS_NESTED_TASK HEX(4000) -#define EFLAGS_V86_MASK HEX(20000) -#define EFLAGS_ALIGN_CHECK HEX(40000) -#define EFLAGS_VIF HEX(80000) -#define EFLAGS_VIP HEX(100000) -#define EFLAG_SIGN HEX(8000) -#define EFLAG_ZERO HEX(4000) -#define EFLAG_SELECT (EFLAG_SIGN + EFLAG_ZERO) -#define EFLAGS_USER_SANITIZE HEX(3F4DD7) - -// -// Exception codes -// -#define EXCEPTION_DIVIDED_BY_ZERO HEX(00000) -#define EXCEPTION_DEBUG HEX(00001) -#define EXCEPTION_NMI HEX(00002) -#define EXCEPTION_INT3 HEX(00003) -#define EXCEPTION_BOUND_CHECK HEX(00005) -#define EXCEPTION_INVALID_OPCODE HEX(00006) -#define EXCEPTION_NPX_NOT_AVAILABLE HEX(00007) -#define EXCEPTION_DOUBLE_FAULT HEX(00008) -#define EXCEPTION_NPX_OVERRUN HEX(00009) -#define EXCEPTION_INVALID_TSS HEX(0000A) -#define EXCEPTION_SEGMENT_NOT_PRESENT HEX(0000B) -#define EXCEPTION_STACK_FAULT HEX(0000C) -#define EXCEPTION_GP_FAULT HEX(0000D) -#define EXCEPTION_RESERVED_TRAP HEX(0000F) -#define EXCEPTION_NPX_ERROR HEX(00010) -#define EXCEPTION_ALIGNMENT_CHECK HEX(00011) - -// -// NTSTATUS values -// -#define STATUS_ACCESS_VIOLATION HEX(C0000005) -#define STATUS_IN_PAGE_ERROR HEX(C0000006) -#define STATUS_GUARD_PAGE_VIOLATION HEX(80000001) -#define STATUS_PRIVILEGED_INSTRUCTION HEX(C0000096) -#define STATUS_STACK_OVERFLOW HEX(C00000FD) -#define KI_EXCEPTION_ACCESS_VIOLATION HEX(10000004) -#define STATUS_INVALID_SYSTEM_SERVICE HEX(C000001C) -#define STATUS_NO_CALLBACK_ACTIVE HEX(C0000258) -#define STATUS_CALLBACK_POP_STACK HEX(C0000423) -#define STATUS_ARRAY_BOUNDS_EXCEEDED HEX(C000008C) -#define STATUS_ILLEGAL_INSTRUCTION HEX(C000001D) -#define STATUS_INVALID_LOCK_SEQUENCE HEX(C000001E) -#define STATUS_BREAKPOINT HEX(80000003) -#define STATUS_SINGLE_STEP HEX(80000004) -#define STATUS_INTEGER_DIVIDE_BY_ZERO HEX(C0000094) -#define STATUS_INTEGER_OVERFLOW HEX(C0000095) -#define STATUS_FLOAT_DENORMAL_OPERAND HEX(C000008D) -#define STATUS_FLOAT_DIVIDE_BY_ZERO HEX(C000008E) -#define STATUS_FLOAT_INEXACT_RESULT HEX(C000008F) -#define STATUS_FLOAT_INVALID_OPERATION HEX(C0000090) -#define STATUS_FLOAT_OVERFLOW HEX(C0000091) -#define STATUS_FLOAT_STACK_CHECK HEX(C0000092) -#define STATUS_FLOAT_UNDERFLOW HEX(C0000093) -#define STATUS_FLOAT_MULTIPLE_FAULTS HEX(C00002B4) -#define STATUS_FLOAT_MULTIPLE_TRAPS HEX(C00002B5) -#define STATUS_ASSERTION_FAILURE HEX(C0000420) - -// -// Bugcheck Codes -// -#define APC_INDEX_MISMATCH HEX(01) -#define IRQL_NOT_GREATER_OR_EQUAL HEX(09) -#define IRQL_NOT_LESS_OR_EQUAL HEX(0A) -#define TRAP_CAUSE_UNKNOWN HEX(12) -#define KMODE_EXCEPTION_NOT_HANDLED HEX(13) -#define IRQL_GT_ZERO_AT_SYSTEM_SERVICE HEX(4A) -#define UNEXPECTED_KERNEL_MODE_TRAP HEX(7F) -#define ATTEMPTED_SWITCH_FROM_DPC HEX(B8) -#define HARDWARE_INTERRUPT_STORM HEX(F2) - -// -// IRQL Levels -// -#define PASSIVE_LEVEL 0 -#define LOW_LEVEL 0 -#define APC_LEVEL 1 -#define DISPATCH_LEVEL 2 -#define CLOCK_LEVEL 13 -#define IPI_LEVEL 14 -#define POWER_LEVEL 14 -#define PROFILE_LEVEL 15 -#define HIGH_LEVEL 15 - -// -// Synchronization-level IRQL -// -#ifndef CONFIG_SMP -#define SYNCH_LEVEL DISPATCH_LEVEL -#else -#define SYNCH_LEVEL (IPI_LEVEL - 2) -#endif - -// -// Quantum Decrements -// -#define CLOCK_QUANTUM_DECREMENT HEX(3) - -// -// Machine types -// -#define MACHINE_TYPE_ISA HEX(0000) -#define MACHINE_TYPE_EISA HEX(0001) -#define MACHINE_TYPE_MCA HEX(0002) - -// -// Kernel Feature Bits -// -#define KF_RDTSC HEX(00000002) - -// -// Kernel Stack Size -// -#define KERNEL_STACK_SIZE HEX(6000) - -#endif // __ASM__ - -#endif // !_ASM_AMD64_H - diff --git a/sdk/include/ndk/amd64/ketypes.h b/sdk/include/ndk/amd64/ketypes.h index 410e0b55cb077..5d65d4a3508b5 100644 --- a/sdk/include/ndk/amd64/ketypes.h +++ b/sdk/include/ndk/amd64/ketypes.h @@ -128,6 +128,21 @@ typedef enum #define KGDT64_R3_CMTEB 0x0050 #define KGDT64_R0_LDT 0x0060 +// +// CR0 +// +#define CR0_PE 0x00000001 +#define CR0_MP 0x00000002 +#define CR0_EM 0x00000004 +#define CR0_TS 0x00000008 +#define CR0_ET 0x00000010 +#define CR0_NE 0x00000020 +#define CR0_WP 0x00010000 +#define CR0_AM 0x00040000 +#define CR0_NW 0x20000000 +#define CR0_CD 0x40000000 +#define CR0_PG 0x80000000 + // // CR4 // @@ -322,6 +337,8 @@ typedef enum // // HAL Variables // +#define PRIMARY_VECTOR_BASE 0x30 +#define MAXIMUM_IDTVECTOR 0xFF #define INITIAL_STALL_COUNT 100 #define MM_HAL_VA_START 0xFFFFFFFFFFC00000ULL /* This is Vista+ */ #define MM_HAL_VA_END 0xFFFFFFFFFFFFFFFFULL @@ -345,6 +362,9 @@ typedef enum #define NMI_STACK_SIZE 0x2000 #define ISR_STACK_SIZE 0x6000 +/* Number of bytes reserved for syscall parameters */ +#define MAX_SYSCALL_PARAM_SIZE (16 * 8) + // // Synchronization-level IRQL // @@ -919,8 +939,11 @@ typedef struct _KPRCB ULONG CacheCount; #endif #ifdef __REACTOS__ +#if (NTDDI_VERSION < NTDDI_WINBLUE) + // On Win 8.1+ the FeatureBits field is extended to 64 bits ULONG FeatureBitsHigh; #endif +#endif } KPRCB, *PKPRCB; // @@ -1073,6 +1096,15 @@ typedef struct _UCALLOUT_FRAME MACHINE_FRAME MachineFrame; } UCALLOUT_FRAME, *PUCALLOUT_FRAME; // size = 0x0058 +// +// User side APC dispatcher frame +// +typedef struct _UAPC_FRAME +{ + CONTEXT Context; + MACHINE_FRAME MachineFrame; +} UAPC_FRAME, *PUAPC_FRAME; + // // Stack frame layout for KiUserExceptionDispatcher // The name is totally made up diff --git a/sdk/include/ndk/asm.h b/sdk/include/ndk/asm.h index ce2ada8cd1f17..71c01b3fa72bc 100644 --- a/sdk/include/ndk/asm.h +++ b/sdk/include/ndk/asm.h @@ -18,11 +18,9 @@ Header Name: #if defined(_M_IX86) #include -#elif defined(_M_AMD64) -#include -#elif defined(_M_ARM) || defined(_M_PPC) || defined(_M_ARM64) +#elif defined(_M_AMD64) || defined(_M_ARM) || defined(_M_PPC) || defined(_M_ARM64) // -// ARM and PPC ports don't use asm.h +// AMD64, ARM and PPC ports don't use asm.h // #else #error Unsupported Architecture diff --git a/sdk/include/ndk/extypes.h b/sdk/include/ndk/extypes.h index 2b190f1ca3083..251a7a0e6f2e9 100644 --- a/sdk/include/ndk/extypes.h +++ b/sdk/include/ndk/extypes.h @@ -761,7 +761,11 @@ typedef struct _SYSTEM_PROCESSOR_INFORMATION #else USHORT MaximumProcessors; #endif +#if (NTDDI_VERSION >= NTDDI_WIN10) || ((NTDDI_VERSION >= NTDDI_WINBLUE) && defined(_WIN64)) + ULONG64 ProcessorFeatureBits; +#else ULONG ProcessorFeatureBits; +#endif } SYSTEM_PROCESSOR_INFORMATION, *PSYSTEM_PROCESSOR_INFORMATION; // Class 2 diff --git a/sdk/include/ndk/i386/ketypes.h b/sdk/include/ndk/i386/ketypes.h index 757fd4e82d4f8..e97f243b6c082 100644 --- a/sdk/include/ndk/i386/ketypes.h +++ b/sdk/include/ndk/i386/ketypes.h @@ -781,6 +781,12 @@ typedef struct _KPRCB ULONG PackageProcessorSet; ULONG CoreProcessorSet; #endif +#ifdef __REACTOS__ +#if (NTDDI_VERSION < NTDDI_WIN10) + // On Win 10+ the FeatureBits field is extended to 64 bits + ULONG FeatureBitsHigh; +#endif +#endif } KPRCB, *PKPRCB; // diff --git a/sdk/include/ndk/iotypes.h b/sdk/include/ndk/iotypes.h index 3e78ef20979f6..8ab6c146d1824 100644 --- a/sdk/include/ndk/iotypes.h +++ b/sdk/include/ndk/iotypes.h @@ -892,6 +892,11 @@ typedef struct _FILE_PIPE_PEEK_BUFFER CHAR Data[1]; } FILE_PIPE_PEEK_BUFFER, *PFILE_PIPE_PEEK_BUFFER; +typedef struct _FILE_MODE_INFORMATION +{ + ULONG Mode; +} FILE_MODE_INFORMATION, *PFILE_MODE_INFORMATION; + // // I/O Error Log Structures // diff --git a/sdk/include/ndk/kdfuncs.h b/sdk/include/ndk/kdfuncs.h index 21681a67674d9..0ab68c26bcdf1 100644 --- a/sdk/include/ndk/kdfuncs.h +++ b/sdk/include/ndk/kdfuncs.h @@ -34,11 +34,11 @@ NTSTATUS NTAPI KdSystemDebugControl( _In_ SYSDBG_COMMAND Command, - _In_ PVOID InputBuffer, + _In_reads_bytes_(InputBufferLength) PVOID InputBuffer, _In_ ULONG InputBufferLength, - _Out_ PVOID OutputBuffer, + _Out_writes_bytes_(OutputBufferLength) PVOID OutputBuffer, _In_ ULONG OutputBufferLength, - _Inout_ PULONG ReturnLength, + _Out_opt_ PULONG ReturnLength, _In_ KPROCESSOR_MODE PreviousMode ); @@ -74,12 +74,12 @@ NTSYSCALLAPI NTSTATUS NTAPI NtSystemDebugControl( - SYSDBG_COMMAND ControlCode, - PVOID InputBuffer, - ULONG InputBufferLength, - PVOID OutputBuffer, - ULONG OutputBufferLength, - PULONG ReturnLength + _In_ SYSDBG_COMMAND Command, + _In_reads_bytes_(InputBufferLength) PVOID InputBuffer, + _In_ ULONG InputBufferLength, + _Out_writes_bytes_(OutputBufferLength) PVOID OutputBuffer, + _In_ ULONG OutputBufferLength, + _Out_opt_ PULONG ReturnLength ); NTSYSAPI @@ -103,11 +103,11 @@ NTSYSAPI NTSTATUS NTAPI ZwSystemDebugControl( - SYSDBG_COMMAND ControlCode, - PVOID InputBuffer, - ULONG InputBufferLength, - PVOID OutputBuffer, - ULONG OutputBufferLength, - PULONG ReturnLength + _In_ SYSDBG_COMMAND Command, + _In_reads_bytes_(InputBufferLength) PVOID InputBuffer, + _In_ ULONG InputBufferLength, + _Out_writes_bytes_(OutputBufferLength) PVOID OutputBuffer, + _In_ ULONG OutputBufferLength, + _Out_opt_ PULONG ReturnLength ); #endif diff --git a/sdk/include/ndk/kdtypes.h b/sdk/include/ndk/kdtypes.h index 26eb130cc57bd..342f2824469ea 100644 --- a/sdk/include/ndk/kdtypes.h +++ b/sdk/include/ndk/kdtypes.h @@ -91,11 +91,19 @@ typedef enum _SYSDBG_COMMAND SysDbgGetTriageDump = 29, SysDbgGetKdBlockEnable = 30, SysDbgSetKdBlockEnable = 31, +#if (NTDDI_VERSION >= NTDDI_VISTA) SysDbgRegisterForUmBreakInfo = 32, SysDbgGetUmBreakPid = 33, SysDbgClearUmBreakPid = 34, SysDbgGetUmAttachPid = 35, SysDbgClearUmAttachPid = 36, +#endif +#if (NTDDI_VERSION >= NTDDI_WINBLUE) // NTDDI_WIN81 + SysDbgGetLiveKernelDump = 37, +#endif +#if (NTDDI_VERSION >= NTDDI_WIN10_VB) + SysDbgKdPullRemoteFile = 38, +#endif } SYSDBG_COMMAND; // @@ -162,6 +170,96 @@ typedef struct _SYSDBG_TRIAGE_DUMP PHANDLE Handles; } SYSDBG_TRIAGE_DUMP, *PSYSDBG_TRIAGE_DUMP; +#if (NTDDI_VERSION >= NTDDI_WINBLUE) // NTDDI_WIN81 + +typedef union _SYSDBG_LIVEDUMP_CONTROL_FLAGS +{ + struct + { + ULONG UseDumpStorageStack : 1; + ULONG CompressMemoryPagesData : 1; + ULONG IncludeUserSpaceMemoryPages : 1; +#if (NTDDI_VERSION >= NTDDI_WIN10_RS4) + ULONG AbortIfMemoryPressure : 1; +#if (NTDDI_VERSION >= NTDDI_WIN11) + ULONG SelectiveDump : 1; + ULONG Reserved : 27; +#else + ULONG Reserved : 28; +#endif // (NTDDI_VERSION >= NTDDI_WIN11) +#else + ULONG Reserved : 29; +#endif // (NTDDI_VERSION >= NTDDI_WIN10_RS4) + }; + ULONG AsUlong; +} SYSDBG_LIVEDUMP_CONTROL_FLAGS; + +typedef union _SYSDBG_LIVEDUMP_CONTROL_ADDPAGES +{ + struct + { + ULONG HypervisorPages : 1; +#if (NTDDI_VERSION >= NTDDI_WIN11) + ULONG NonEssentialHypervisorPages : 1; + ULONG Reserved : 30; +#else + ULONG Reserved : 31; +#endif + }; + ULONG AsUlong; +} SYSDBG_LIVEDUMP_CONTROL_ADDPAGES; + +#if (NTDDI_VERSION >= NTDDI_WIN11) + +typedef struct _SYSDBG_LIVEDUMP_SELECTIVE_CONTROL +{ + ULONG Version; + ULONG Size; + union + { + ULONGLONG Flags; + struct + { + ULONGLONG ThreadKernelStacks : 1; + ULONGLONG ReservedFlags : 63; + }; + }; + ULONGLONG Reserved[4]; +} SYSDBG_LIVEDUMP_SELECTIVE_CONTROL, *PSYSDBG_LIVEDUMP_SELECTIVE_CONTROL; + +#define SYSDBG_LIVEDUMP_CONTROL_VERSION 1 +#define SYSDBG_LIVEDUMP_CONTROL_VERSION_WIN11 2 + +#endif // (NTDDI_VERSION >= NTDDI_WIN11) + +typedef struct _SYSDBG_LIVEDUMP_CONTROL +{ + ULONG Version; + ULONG BugCheckCode; + ULONG_PTR BugCheckParam1; + ULONG_PTR BugCheckParam2; + ULONG_PTR BugCheckParam3; + ULONG_PTR BugCheckParam4; + PVOID DumpFileHandle; + PVOID CancelEventHandle; + SYSDBG_LIVEDUMP_CONTROL_FLAGS Flags; + SYSDBG_LIVEDUMP_CONTROL_ADDPAGES AddPagesControl; +#if (NTDDI_VERSION >= NTDDI_WIN11) + PSYSDBG_LIVEDUMP_SELECTIVE_CONTROL SelectiveControl; +#endif +} SYSDBG_LIVEDUMP_CONTROL, *PSYSDBG_LIVEDUMP_CONTROL; + +#endif // (NTDDI_VERSION >= NTDDI_WINBLUE) + +#if (NTDDI_VERSION >= NTDDI_WIN10_VB) + +typedef struct _SYSDBG_KD_PULL_REMOTE_FILE +{ + UNICODE_STRING ImageFileName; +} SYSDBG_KD_PULL_REMOTE_FILE, *PSYSDBG_KD_PULL_REMOTE_FILE; + +#endif + // // KD Structures // diff --git a/sdk/include/ndk/ldrfuncs.h b/sdk/include/ndk/ldrfuncs.h index 62e334aacf77a..bdade6abcf9a5 100644 --- a/sdk/include/ndk/ldrfuncs.h +++ b/sdk/include/ndk/ldrfuncs.h @@ -147,6 +147,23 @@ LdrEnumerateLoadedModules( _In_opt_ PVOID Context ); +#if (_WIN32_WINNT >= _WIN32_WINNT_VISTA) || (DLL_EXPORT_VERSION >= _WIN32_WINNT_VISTA) + +NTSTATUS +NTAPI +LdrRegisterDllNotification( + _In_ ULONG Flags, + _In_ PLDR_DLL_NOTIFICATION_FUNCTION NotificationFunction, + _In_opt_ PVOID Context, + _Out_ PVOID* Cookie); + +NTSTATUS +NTAPI +LdrUnregisterDllNotification( + _In_ PVOID Cookie); + +#endif /* (_WIN32_WINNT >= _WIN32_WINNT_VISTA) || (DLL_EXPORT_VERSION >= _WIN32_WINNT_VISTA) */ + #ifdef NTOS_MODE_USER NTSYSAPI BOOLEAN diff --git a/sdk/include/ndk/ldrtypes.h b/sdk/include/ndk/ldrtypes.h index 3b71d02288706..4c16bd524c1ed 100644 --- a/sdk/include/ndk/ldrtypes.h +++ b/sdk/include/ndk/ldrtypes.h @@ -37,7 +37,11 @@ Header Name: // #define LDRP_STATIC_LINK 0x00000002 #define LDRP_IMAGE_DLL 0x00000004 +#if (NTDDI_VERSION < NTDDI_WIN8) #define LDRP_SHIMENG_SUPPRESSED_ENTRY 0x00000008 +#else +#define LDRP_LOAD_NOTIFICATIONS_SENT 0x00000008 +#endif #define LDRP_IMAGE_INTEGRITY_FORCED 0x00000020 #define LDRP_LOAD_IN_PROGRESS 0x00001000 #define LDRP_UNLOAD_IN_PROGRESS 0x00002000 @@ -196,26 +200,39 @@ typedef struct _LDR_ENUM_RESOURCE_INFO // // DLL Notifications // +#define LDR_DLL_NOTIFICATION_REASON_LOADED 1 +#define LDR_DLL_NOTIFICATION_REASON_UNLOADED 2 + typedef struct _LDR_DLL_LOADED_NOTIFICATION_DATA { ULONG Flags; - PUNICODE_STRING FullDllName; - PUNICODE_STRING BaseDllName; + PCUNICODE_STRING FullDllName; + PCUNICODE_STRING BaseDllName; PVOID DllBase; ULONG SizeOfImage; } LDR_DLL_LOADED_NOTIFICATION_DATA, *PLDR_DLL_LOADED_NOTIFICATION_DATA; -typedef VOID -(NTAPI *PLDR_DLL_LOADED_NOTIFICATION_CALLBACK)( - _In_ BOOLEAN Type, - _In_ struct _LDR_DLL_LOADED_NOTIFICATION_DATA *Data -); +typedef struct _LDR_DLL_UNLOADED_NOTIFICATION_DATA +{ + ULONG Flags; + PCUNICODE_STRING FullDllName; + PCUNICODE_STRING BaseDllName; + PVOID DllBase; + ULONG SizeOfImage; +} LDR_DLL_UNLOADED_NOTIFICATION_DATA, *PLDR_DLL_UNLOADED_NOTIFICATION_DATA; -typedef struct _LDR_DLL_LOADED_NOTIFICATION_ENTRY +typedef union _LDR_DLL_NOTIFICATION_DATA { - LIST_ENTRY NotificationListEntry; - PLDR_DLL_LOADED_NOTIFICATION_CALLBACK Callback; -} LDR_DLL_LOADED_NOTIFICATION_ENTRY, *PLDR_DLL_LOADED_NOTIFICATION_ENTRY; + LDR_DLL_LOADED_NOTIFICATION_DATA Loaded; + LDR_DLL_UNLOADED_NOTIFICATION_DATA Unloaded; +} LDR_DLL_NOTIFICATION_DATA, *PLDR_DLL_NOTIFICATION_DATA; +typedef const LDR_DLL_NOTIFICATION_DATA *PCLDR_DLL_NOTIFICATION_DATA; + +typedef VOID +(NTAPI *PLDR_DLL_NOTIFICATION_FUNCTION)( + _In_ ULONG NotificationReason, + _In_ PCLDR_DLL_NOTIFICATION_DATA NotificationData, + _In_opt_ PVOID Context); // // Alternate Resources Support diff --git a/sdk/include/ndk/lpctypes.h b/sdk/include/ndk/lpctypes.h index 23d2f48005f6c..276a8db9989ed 100644 --- a/sdk/include/ndk/lpctypes.h +++ b/sdk/include/ndk/lpctypes.h @@ -19,6 +19,10 @@ Header Name: #ifndef _LPCTYPES_H #define _LPCTYPES_H +#if defined(BUILD_WOW6432) && defined(_M_IX86) +#define USE_LPC6432 +#endif + // // Dependencies // @@ -94,7 +98,7 @@ typedef enum _PORT_INFORMATION_CLASS // // Maximum message size that can be sent through an LPC Port without a section // -#ifdef _WIN64 +#if defined(_WIN64) || defined(USE_LPC6432) #define PORT_MAXIMUM_MESSAGE_LENGTH 512 #else #define PORT_MAXIMUM_MESSAGE_LENGTH 256 @@ -104,15 +108,35 @@ typedef enum _PORT_INFORMATION_CLASS // Portable LPC Types for 32/64-bit compatibility // #ifdef USE_LPC6432 -#define LPC_CLIENT_ID CLIENT_ID64 + #define LPC_SIZE_T ULONGLONG #define LPC_PVOID ULONGLONG #define LPC_HANDLE ULONGLONG +#define LPC_ULONG_PTR ULONGLONG +typedef struct +{ + LPC_HANDLE UniqueProcess; + LPC_HANDLE UniqueThread; +} LPC_CLIENT_ID; +#define LPC_UNICODE_STRING UNICODE_STRING64 +#define LPC_PTR(x) LPC_PVOID +#define LPC_PTRTYPE(x) LPC_PVOID +#define TO_LPC_HANDLE(h) ((LPC_HANDLE)(h)) +#define FROM_LPC_HANDLE(h) ((HANDLE)(h)) + #else + #define LPC_CLIENT_ID CLIENT_ID #define LPC_SIZE_T SIZE_T #define LPC_PVOID PVOID #define LPC_HANDLE HANDLE +#define LPC_ULONG_PTR ULONG_PTR +#define LPC_UNICODE_STRING UNICODE_STRING +#define LPC_PTR(x) x* +#define LPC_PTRTYPE(x) x +#define TO_LPC_HANDLE(h) h +#define FROM_LPC_HANDLE(h) h + #endif // diff --git a/sdk/include/ndk/pstypes.h b/sdk/include/ndk/pstypes.h index 155b2e37d895c..2ff60956810d4 100644 --- a/sdk/include/ndk/pstypes.h +++ b/sdk/include/ndk/pstypes.h @@ -838,7 +838,7 @@ typedef enum _APPCOMPAT_USERFLAGS_HIGHPART // #include "peb_teb.h" -#ifdef _WIN64 +#if defined(_WIN64) || defined(BUILD_WOW6432) // // Explicit 32 bit PEB/TEB // diff --git a/sdk/include/ndk/rtlfuncs.h b/sdk/include/ndk/rtlfuncs.h index 3a00f4909356a..41ecb3d8f31db 100644 --- a/sdk/include/ndk/rtlfuncs.h +++ b/sdk/include/ndk/rtlfuncs.h @@ -39,6 +39,18 @@ extern "C" { // // List Functions // + +DECLSPEC_NORETURN +FORCEINLINE +VOID +RtlFailFast( + _In_ ULONG Code) +{ + __fastfail(Code); +} + +#define RTL_STATIC_LIST_HEAD(x) LIST_ENTRY x = { &x, &x } + FORCEINLINE VOID InitializeListHead( @@ -839,7 +851,7 @@ RtlVirtualUnwind( _In_ ULONG64 ControlPc, _In_ PRUNTIME_FUNCTION FunctionEntry, _Inout_ PCONTEXT Context, - _Outptr_ PVOID* HandlerData, + _Out_ PVOID* HandlerData, _Out_ PULONG64 EstablisherFrame, _Inout_opt_ PKNONVOLATILE_CONTEXT_POINTERS ContextPointers ); @@ -1856,9 +1868,24 @@ RtlCharToInteger( // #ifdef NTOS_MODE_USER -unsigned short __cdecl _byteswap_ushort(unsigned short); -unsigned long __cdecl _byteswap_ulong (unsigned long); -unsigned __int64 __cdecl _byteswap_uint64(unsigned __int64); +_Check_return_ +unsigned short +__cdecl +_byteswap_ushort( + _In_ unsigned short _Short); + +_Check_return_ +unsigned long +__cdecl +_byteswap_ulong( + _In_ unsigned long _Long); + +_Check_return_ +unsigned __int64 +__cdecl +_byteswap_uint64( + _In_ unsigned __int64 _Int64); + #ifdef _MSC_VER #pragma intrinsic(_byteswap_ushort) #pragma intrinsic(_byteswap_ulong) @@ -3826,50 +3853,6 @@ DbgCommandString( _In_ PCCH Command ); -// -// Generic Table Functions -// -#if defined(NTOS_MODE_USER) || defined(_NTIFS_) -NTSYSAPI -PVOID -NTAPI -RtlInsertElementGenericTable( - _In_ PRTL_GENERIC_TABLE Table, - _In_reads_bytes_(BufferSize) PVOID Buffer, - _In_ CLONG BufferSize, - _Out_opt_ PBOOLEAN NewElement -); - -NTSYSAPI -PVOID -NTAPI -RtlInsertElementGenericTableFull( - _In_ PRTL_GENERIC_TABLE Table, - _In_reads_bytes_(BufferSize) PVOID Buffer, - _In_ CLONG BufferSize, - _Out_opt_ PBOOLEAN NewElement, - _In_ PVOID NodeOrParent, - _In_ TABLE_SEARCH_RESULT SearchResult -); - -NTSYSAPI -BOOLEAN -NTAPI -RtlIsGenericTableEmpty( - _In_ PRTL_GENERIC_TABLE Table -); - -NTSYSAPI -PVOID -NTAPI -RtlLookupElementGenericTableFull( - _In_ PRTL_GENERIC_TABLE Table, - _In_ PVOID Buffer, - _Out_ PVOID *NodeOrParent, - _Out_ TABLE_SEARCH_RESULT *SearchResult -); -#endif - // // Handle Table Functions // @@ -4745,6 +4728,59 @@ RtlSleepConditionVariableSRW( _In_ ULONG Flags); #endif +// +// Synchronization functions +// +NTSYSAPI +VOID +NTAPI +RtlInitializeConditionVariable(OUT PRTL_CONDITION_VARIABLE ConditionVariable); + +NTSYSAPI +VOID +NTAPI +RtlWakeConditionVariable(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable); + +NTSYSAPI +VOID +NTAPI +RtlWakeAllConditionVariable(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable); + +NTSYSAPI +NTSTATUS +NTAPI +RtlSleepConditionVariableCS(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable, + IN OUT PRTL_CRITICAL_SECTION CriticalSection, + IN const PLARGE_INTEGER TimeOut OPTIONAL); + +NTSYSAPI +NTSTATUS +NTAPI +RtlSleepConditionVariableSRW(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable, + IN OUT PRTL_SRWLOCK SRWLock, + IN PLARGE_INTEGER TimeOut OPTIONAL, + IN ULONG Flags); + +VOID +NTAPI +RtlInitializeSRWLock(OUT PRTL_SRWLOCK SRWLock); + +VOID +NTAPI +RtlAcquireSRWLockShared(IN OUT PRTL_SRWLOCK SRWLock); + +VOID +NTAPI +RtlReleaseSRWLockShared(IN OUT PRTL_SRWLOCK SRWLock); + +VOID +NTAPI +RtlAcquireSRWLockExclusive(IN OUT PRTL_SRWLOCK SRWLock); + +VOID +NTAPI +RtlReleaseSRWLockExclusive(IN OUT PRTL_SRWLOCK SRWLock); + // // Secure Memory Functions // @@ -5076,6 +5112,59 @@ VOID NTAPI RtlReleaseSRWLockExclusive(IN OUT PRTL_SRWLOCK SRWLock); +NTSYSAPI +NTSTATUS +NTAPI +RtlConvertLCIDToString( + _In_ LCID LcidValue, + _In_ ULONG Base, + _In_ ULONG Padding, + _Out_writes_(Size) PWSTR pResultBuf, + _In_ ULONG Size); + +_Success_(return != FALSE) +NTSYSAPI +BOOLEAN +NTAPI +RtlCultureNameToLCID( + _In_ PCUNICODE_STRING String, + _Out_ PLCID Lcid); + +_Success_(return != FALSE) +NTSYSAPI +BOOLEAN +NTAPI +RtlLCIDToCultureName( + _In_ LCID Lcid, + _Inout_ PUNICODE_STRING String); + +NTSYSAPI +NTSTATUS +NTAPI +RtlLcidToLocaleName( + _In_ LCID Lcid, + _Inout_ PUNICODE_STRING LocaleName, + _In_ ULONG Flags, + _In_ BOOLEAN AllocateDestinationString); + +NTSYSAPI +NTSTATUS +NTAPI +RtlLocaleNameToLcid( + _In_ PCWSTR LocaleName, + _Out_ PLCID Lcid, + _In_ ULONG Flags); + +NTSYSAPI +BOOLEAN +NTAPI +RtlIsValidLocaleName( + _In_ LPCWSTR LocaleName, + _In_ ULONG Flags); + +// Flags for RtlLocaleNameToLcid / RtlLcidToLocaleName / RtlIsValidLocaleName +#define RTL_LOCALE_ALLOW_NEUTRAL_NAMES 0x00000002 // Return locales like "en" or "de" + #endif /* Win vista or Reactos Ntdll build */ #if (_WIN32_WINNT >= _WIN32_WINNT_WIN7) || (defined(__REACTOS__) && defined(_NTDLLBUILD_)) diff --git a/sdk/include/ndk/rtltypes.h b/sdk/include/ndk/rtltypes.h index 32bfb4fa486e2..fdda1203a8c67 100644 --- a/sdk/include/ndk/rtltypes.h +++ b/sdk/include/ndk/rtltypes.h @@ -344,13 +344,7 @@ C_ASSERT(HEAP_CREATE_VALID_MASK == 0x0007F0FF); #define RTL_INIT_OBJECT_ATTRIBUTES(n, a) \ RTL_CONSTANT_OBJECT_ATTRIBUTES(n, a) -#else /* NTOS_MODE_USER */ -// -// Message Resource Flag -// -#define MESSAGE_RESOURCE_UNICODE 0x0001 - -#endif /* !NTOS_MODE_USER */ +#endif /* NTOS_MODE_USER */ // // RtlImageNtHeaderEx Flags @@ -1423,9 +1417,25 @@ typedef struct _RTL_CRITICAL_SECTION_DEBUG LIST_ENTRY ProcessLocksList; ULONG EntryCount; ULONG ContentionCount; - ULONG Spare[2]; + union + { + ULONG_PTR WineDebugString; + ULONG_PTR Spare[1]; + struct + { + ULONG Flags; + USHORT CreatorBackTraceIndexHigh; + USHORT SpareWORD; + }; + }; } RTL_CRITICAL_SECTION_DEBUG, *PRTL_CRITICAL_SECTION_DEBUG, RTL_RESOURCE_DEBUG, *PRTL_RESOURCE_DEBUG; +#ifdef _WIN64 +C_ASSERT(sizeof(RTL_CRITICAL_SECTION_DEBUG) == 0x30); +#else +C_ASSERT(sizeof(RTL_CRITICAL_SECTION_DEBUG) == 0x20); +#endif + typedef struct _RTL_CRITICAL_SECTION { PRTL_CRITICAL_SECTION_DEBUG DebugInfo; @@ -1889,6 +1899,23 @@ typedef struct _RTL_UNICODE_STRING_BUFFER #ifndef NTOS_MODE_USER +#ifndef MAKEINTRESOURCE +#define MAKEINTRESOURCE(i) ((ULONG_PTR)(USHORT)(i)) +#endif + +/* Predefined Resource Types */ +#ifndef RT_STRING +#define RT_STRING MAKEINTRESOURCE(6) +#endif +#ifndef RT_MESSAGETABLE +#define RT_MESSAGETABLE MAKEINTRESOURCE(11) +#endif + +// +// Message Resource Flag +// +#define MESSAGE_RESOURCE_UNICODE 0x0001 + // // Message Resource Entry, Block and Data // diff --git a/sdk/include/ndk/sefuncs.h b/sdk/include/ndk/sefuncs.h index 3c24177cb16ad..ab55dab6550a3 100644 --- a/sdk/include/ndk/sefuncs.h +++ b/sdk/include/ndk/sefuncs.h @@ -443,6 +443,7 @@ ZwOpenProcessToken( _In_ ACCESS_MASK DesiredAccess, _Out_ PHANDLE TokenHandle); +_IRQL_requires_max_(PASSIVE_LEVEL) NTSYSAPI NTSTATUS NTAPI diff --git a/sdk/include/psdk/CMakeLists.txt b/sdk/include/psdk/CMakeLists.txt index 360082e103b45..9463f9a5c0f66 100644 --- a/sdk/include/psdk/CMakeLists.txt +++ b/sdk/include/psdk/CMakeLists.txt @@ -45,7 +45,9 @@ list(APPEND SOURCE docobjectservice.idl downloadmgr.idl drmexternals.idl + dxgiformat.idl # dyngraph.idl + emptyvc.idl endpointvolume.idl exdisp.idl fusion.idl diff --git a/sdk/include/psdk/basetsd.h b/sdk/include/psdk/basetsd.h index 7d3efc0472563..6d8d85f17e251 100644 --- a/sdk/include/psdk/basetsd.h +++ b/sdk/include/psdk/basetsd.h @@ -6,8 +6,8 @@ #include #endif -#if defined(__LP64__) || (!defined(_M_AMD64) && defined(__WINESRC__)) -#if !defined(__ROS_LONG64__) +#if (defined(_LP64) || defined(__LP64__)) && !defined(_M_AMD64) +#ifndef __ROS_LONG64__ #define __ROS_LONG64__ #endif #endif @@ -161,7 +161,7 @@ static inline void* ULongToPtr( const unsigned long ul ) { return( (void*)(ULONG_PTR)ul ); } #endif /* !__midl */ #else /* !_WIN64 */ -#if !defined(__ROS_LONG64__) +#ifndef __ROS_LONG64__ typedef int INT_PTR, *PINT_PTR; typedef unsigned int UINT_PTR, *PUINT_PTR; #else diff --git a/sdk/include/psdk/batclass.h b/sdk/include/psdk/batclass.h index f97140d9b0515..02641a65f8613 100644 --- a/sdk/include/psdk/batclass.h +++ b/sdk/include/psdk/batclass.h @@ -65,7 +65,7 @@ DEFINE_GUID(BATTERY_TAG_CHANGE_WMI_GUID, #define BATTERY_UNKNOWN_CAPACITY 0xFFFFFFFF /* BatteryEstimatedTime constant */ -#define BATTERY_UNKNOWN_TIME 0x80000000 +#define BATTERY_UNKNOWN_TIME 0xFFFFFFFF #define MAX_BATTERY_STRING_SIZE 128 diff --git a/sdk/include/psdk/ddraw.h b/sdk/include/psdk/ddraw.h index 637afd9e2803c..a7d01b54363d4 100644 --- a/sdk/include/psdk/ddraw.h +++ b/sdk/include/psdk/ddraw.h @@ -8,7 +8,9 @@ #else #define IUnknown void #if !defined(NT_BUILD_ENVIRONMENT) && !defined(WINNT) - #define CO_E_NOTINITIALIZED 0x800401F0L + #ifndef CO_E_NOTINITIALIZED /* Avoid conflict warning with _HRESULT_TYPEDEF_(0x800401F0L) in winerror.h */ + #define CO_E_NOTINITIALIZED 0x800401F0L + #endif #endif #endif diff --git a/sdk/include/psdk/dxgiformat.idl b/sdk/include/psdk/dxgiformat.idl new file mode 100644 index 0000000000000..5f85064d0ddde --- /dev/null +++ b/sdk/include/psdk/dxgiformat.idl @@ -0,0 +1,145 @@ +/* + * Copyright 2016 Józef Kucia 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 + */ + +const unsigned int DXGI_FORMAT_DEFINED = 1; + +typedef enum DXGI_FORMAT +{ + DXGI_FORMAT_UNKNOWN = 0x00, + DXGI_FORMAT_R32G32B32A32_TYPELESS = 0x01, + DXGI_FORMAT_R32G32B32A32_FLOAT = 0x02, + DXGI_FORMAT_R32G32B32A32_UINT = 0x03, + DXGI_FORMAT_R32G32B32A32_SINT = 0x04, + DXGI_FORMAT_R32G32B32_TYPELESS = 0x05, + DXGI_FORMAT_R32G32B32_FLOAT = 0x06, + DXGI_FORMAT_R32G32B32_UINT = 0x07, + DXGI_FORMAT_R32G32B32_SINT = 0x08, + DXGI_FORMAT_R16G16B16A16_TYPELESS = 0x09, + DXGI_FORMAT_R16G16B16A16_FLOAT = 0x0a, + DXGI_FORMAT_R16G16B16A16_UNORM = 0x0b, + DXGI_FORMAT_R16G16B16A16_UINT = 0x0c, + DXGI_FORMAT_R16G16B16A16_SNORM = 0x0d, + DXGI_FORMAT_R16G16B16A16_SINT = 0x0e, + DXGI_FORMAT_R32G32_TYPELESS = 0x0f, + DXGI_FORMAT_R32G32_FLOAT = 0x10, + DXGI_FORMAT_R32G32_UINT = 0x11, + DXGI_FORMAT_R32G32_SINT = 0x12, + DXGI_FORMAT_R32G8X24_TYPELESS = 0x13, + DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 0x14, + DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 0x15, + DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 0x16, + DXGI_FORMAT_R10G10B10A2_TYPELESS = 0x17, + DXGI_FORMAT_R10G10B10A2_UNORM = 0x18, + DXGI_FORMAT_R10G10B10A2_UINT = 0x19, + DXGI_FORMAT_R11G11B10_FLOAT = 0x1a, + DXGI_FORMAT_R8G8B8A8_TYPELESS = 0x1b, + DXGI_FORMAT_R8G8B8A8_UNORM = 0x1c, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 0x1d, + DXGI_FORMAT_R8G8B8A8_UINT = 0x1e, + DXGI_FORMAT_R8G8B8A8_SNORM = 0x1f, + DXGI_FORMAT_R8G8B8A8_SINT = 0x20, + DXGI_FORMAT_R16G16_TYPELESS = 0x21, + DXGI_FORMAT_R16G16_FLOAT = 0x22, + DXGI_FORMAT_R16G16_UNORM = 0x23, + DXGI_FORMAT_R16G16_UINT = 0x24, + DXGI_FORMAT_R16G16_SNORM = 0x25, + DXGI_FORMAT_R16G16_SINT = 0x26, + DXGI_FORMAT_R32_TYPELESS = 0x27, + DXGI_FORMAT_D32_FLOAT = 0x28, + DXGI_FORMAT_R32_FLOAT = 0x29, + DXGI_FORMAT_R32_UINT = 0x2a, + DXGI_FORMAT_R32_SINT = 0x2b, + DXGI_FORMAT_R24G8_TYPELESS = 0x2c, + DXGI_FORMAT_D24_UNORM_S8_UINT = 0x2d, + DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 0x2e, + DXGI_FORMAT_X24_TYPELESS_G8_UINT = 0x2f, + DXGI_FORMAT_R8G8_TYPELESS = 0x30, + DXGI_FORMAT_R8G8_UNORM = 0x31, + DXGI_FORMAT_R8G8_UINT = 0x32, + DXGI_FORMAT_R8G8_SNORM = 0x33, + DXGI_FORMAT_R8G8_SINT = 0x34, + DXGI_FORMAT_R16_TYPELESS = 0x35, + DXGI_FORMAT_R16_FLOAT = 0x36, + DXGI_FORMAT_D16_UNORM = 0x37, + DXGI_FORMAT_R16_UNORM = 0x38, + DXGI_FORMAT_R16_UINT = 0x39, + DXGI_FORMAT_R16_SNORM = 0x3a, + DXGI_FORMAT_R16_SINT = 0x3b, + DXGI_FORMAT_R8_TYPELESS = 0x3c, + DXGI_FORMAT_R8_UNORM = 0x3d, + DXGI_FORMAT_R8_UINT = 0x3e, + DXGI_FORMAT_R8_SNORM = 0x3f, + DXGI_FORMAT_R8_SINT = 0x40, + DXGI_FORMAT_A8_UNORM = 0x41, + DXGI_FORMAT_R1_UNORM = 0x42, + DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 0x43, + DXGI_FORMAT_R8G8_B8G8_UNORM = 0x44, + DXGI_FORMAT_G8R8_G8B8_UNORM = 0x45, + DXGI_FORMAT_BC1_TYPELESS = 0x46, + DXGI_FORMAT_BC1_UNORM = 0x47, + DXGI_FORMAT_BC1_UNORM_SRGB = 0x48, + DXGI_FORMAT_BC2_TYPELESS = 0x49, + DXGI_FORMAT_BC2_UNORM = 0x4a, + DXGI_FORMAT_BC2_UNORM_SRGB = 0x4b, + DXGI_FORMAT_BC3_TYPELESS = 0x4c, + DXGI_FORMAT_BC3_UNORM = 0x4d, + DXGI_FORMAT_BC3_UNORM_SRGB = 0x4e, + DXGI_FORMAT_BC4_TYPELESS = 0x4f, + DXGI_FORMAT_BC4_UNORM = 0x50, + DXGI_FORMAT_BC4_SNORM = 0x51, + DXGI_FORMAT_BC5_TYPELESS = 0x52, + DXGI_FORMAT_BC5_UNORM = 0x53, + DXGI_FORMAT_BC5_SNORM = 0x54, + DXGI_FORMAT_B5G6R5_UNORM = 0x55, + DXGI_FORMAT_B5G5R5A1_UNORM = 0x56, + DXGI_FORMAT_B8G8R8A8_UNORM = 0x57, + DXGI_FORMAT_B8G8R8X8_UNORM = 0x58, + DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 0x59, + DXGI_FORMAT_B8G8R8A8_TYPELESS = 0x5a, + DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 0x5b, + DXGI_FORMAT_B8G8R8X8_TYPELESS = 0x5c, + DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 0x5d, + DXGI_FORMAT_BC6H_TYPELESS = 0x5e, + DXGI_FORMAT_BC6H_UF16 = 0x5f, + DXGI_FORMAT_BC6H_SF16 = 0x60, + DXGI_FORMAT_BC7_TYPELESS = 0x61, + DXGI_FORMAT_BC7_UNORM = 0x62, + DXGI_FORMAT_BC7_UNORM_SRGB = 0x63, + DXGI_FORMAT_AYUV = 0x64, + DXGI_FORMAT_Y410 = 0x65, + DXGI_FORMAT_Y416 = 0x66, + DXGI_FORMAT_NV12 = 0x67, + DXGI_FORMAT_P010 = 0x68, + DXGI_FORMAT_P016 = 0x69, + DXGI_FORMAT_420_OPAQUE = 0x6a, + DXGI_FORMAT_YUY2 = 0x6b, + DXGI_FORMAT_Y210 = 0x6c, + DXGI_FORMAT_Y216 = 0x6d, + DXGI_FORMAT_NV11 = 0x6e, + DXGI_FORMAT_AI44 = 0x6f, + DXGI_FORMAT_IA44 = 0x70, + DXGI_FORMAT_P8 = 0x71, + DXGI_FORMAT_A8P8 = 0x72, + DXGI_FORMAT_B4G4R4A4_UNORM = 0x73, + + DXGI_FORMAT_P208 = 0x82, + DXGI_FORMAT_V208 = 0x83, + DXGI_FORMAT_V408 = 0x84, + + DXGI_FORMAT_FORCE_UINT = 0xffffffff, +} DXGI_FORMAT; diff --git a/sdk/include/psdk/emptyvc.idl b/sdk/include/psdk/emptyvc.idl new file mode 100644 index 0000000000000..c4fc54aa84852 --- /dev/null +++ b/sdk/include/psdk/emptyvc.idl @@ -0,0 +1,99 @@ +/* + * PROJECT: ReactOS Disk Cleanup + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: Interface definitions for Disk Cleanup + * COPYRIGHT: Copyright 2023-2025 Mark Jansen + */ + +cpp_quote("#pragma once") + +import "wtypes.idl"; +import "unknwn.idl"; + +interface IEmptyVolumeCache; +interface IEmptyVolumeCache2; +interface IEmptyVolumeCacheCallBack; + + +cpp_quote("// IEmptyVolumeCache flags") +cpp_quote("#define EVCF_HASSETTINGS 0x0001") +cpp_quote("#define EVCF_ENABLEBYDEFAULT 0x0002") +cpp_quote("#define EVCF_REMOVEFROMLIST 0x0004") +cpp_quote("#define EVCF_ENABLEBYDEFAULT_AUTO 0x0008") +cpp_quote("#define EVCF_DONTSHOWIFZERO 0x0010") +cpp_quote("#define EVCF_SETTINGSMODE 0x0020") +cpp_quote("#define EVCF_OUTOFDISKSPACE 0x0040") + +cpp_quote("// IEmptyVolumeCacheCallBack flags") +cpp_quote("#define EVCCBF_LASTNOTIFICATION 0x0001") + + +[ + object, + uuid(6e793361-73c6-11d0-8469-00aa00442901), + pointer_default(unique) +] +interface IEmptyVolumeCacheCallBack: IUnknown +{ + HRESULT ScanProgress( + [in] DWORDLONG dwlSpaceUsed, + [in] DWORD dwFlags, + [in] LPCWSTR pcwszStatus); + + HRESULT PurgeProgress( + [in] DWORDLONG dwlSpaceFreed, + [in] DWORDLONG dwlSpaceToFree, + [in] DWORD dwFlags, + [in] LPCWSTR pcwszStatus); +} + + +[ + object, + uuid(8fce5227-04da-11d1-a004-00805f8abe06), + pointer_default(unique) +] +interface IEmptyVolumeCache: IUnknown +{ + [local] + HRESULT Initialize( + [in] HKEY hkRegKey, + [in] LPCWSTR pcwszVolume, + [out] LPWSTR *ppwszDisplayName, + [out] LPWSTR *ppwszDescription, + [in, out] DWORD *pdwFlags); + + HRESULT GetSpaceUsed( + [out] DWORDLONG *pdwlSpaceUsed, + [in] IEmptyVolumeCacheCallBack *picb); + + HRESULT Purge( + [in] DWORDLONG dwlSpaceToFree, + [in] IEmptyVolumeCacheCallBack *picb); + + HRESULT ShowProperties( + [in] HWND hwnd); + + HRESULT Deactivate( + [out] DWORD *pdwFlags); +} + + +[ + object, + uuid(02b7e3ba-4db3-11d2-b2d9-00c04f8eec8c), + pointer_default(unique) +] +interface IEmptyVolumeCache2: IEmptyVolumeCache +{ + [local] + HRESULT InitializeEx( + [in] HKEY hkRegKey, + [in] LPCWSTR pcwszVolume, + [in] LPCWSTR pcwszKeyName, + [out] LPWSTR *ppwszDisplayName, + [out] LPWSTR *ppwszDescription, + [out] LPWSTR *ppwszBtnText, + [in, out] DWORD *pdwFlags); +} + diff --git a/sdk/include/psdk/mgmtapi.h b/sdk/include/psdk/mgmtapi.h index 6ea25f865f011..5ff91564aa6c0 100644 --- a/sdk/include/psdk/mgmtapi.h +++ b/sdk/include/psdk/mgmtapi.h @@ -4,7 +4,7 @@ Written by Filip Navara References (2003-08-25): - http://msdn.microsoft.com/library/en-us/snmp/snmp/snmp_reference.asp + https://web.archive.org/web/20050113043001/http://msdn.microsoft.com/library/en-us/snmp/snmp/snmp_reference.asp This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sdk/include/psdk/netcfgx.h b/sdk/include/psdk/netcfgx.h index 90ef3ae6d254a..bcd6758c4c68f 100644 --- a/sdk/include/psdk/netcfgx.h +++ b/sdk/include/psdk/netcfgx.h @@ -314,5 +314,74 @@ EXTERN_C const IID IID_INetCfg; #define NETCFG_S_CAUSED_SETUP_CHANGE 0x8004A024 #define NETCFG_S_COMMIT_NOW 0x8004A025 +EXTERN_C const IID IID_INetCfgClass; + +#undef INTERFACE +#define INTERFACE INetCfgClass +DECLARE_INTERFACE_(INetCfgClass, IUnknown) +{ + STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void **ppv) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + STDMETHOD_(HRESULT,FindComponent) (THIS_ INetCfgComponent **ppnccItem) PURE; + STDMETHOD_(HRESULT,EnumComponents) (THIS_ IEnumNetCfgComponent **ppenumComponent) PURE; +}; +#undef INTERFACE + +#if !defined(__cplusplus) || defined(CINTERFACE) +/*** IUnknown methods ***/ +#define INetCfgClass_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define INetCfgClass_AddRef(p) (p)->lpVtbl->AddRef(p) +#define INetCfgClass_Release(p) (p)->lpVtbl->Release(p) +#define INetCfgClass_FindComponent(p,a) (p)->lpVtbl->FindComponent(p,a) +#define INetCfgClass_EnumComponents(p,a) (p)->lpVtbl->EnumComponents(p,a) +#endif + +typedef +enum tagOBO_TOKEN_TYPE +{ + OBO_USER = 1, + OBO_COMPONENT = 2, + OBO_SOFTWARE = 3 +} OBO_TOKEN_TYPE; + +typedef struct tagOBO_TOKEN +{ + OBO_TOKEN_TYPE Type; + INetCfgComponent *pncc; + LPCWSTR pszwManufacturer; + LPCWSTR pszwProduct; + LPCWSTR pszwDisplayName; + BOOL fRegistered; +} OBO_TOKEN; + +#define NSF_PRIMARYINSTALL 1 +#define NSF_POSTSYSINSTALL 2 + +EXTERN_C const IID IID_INetCfgClassSetup; + +#undef INTERFACE +#define INTERFACE INetCfgClassSetup +DECLARE_INTERFACE_(INetCfgClassSetup, IUnknown) +{ + STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void **ppv) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + STDMETHOD_(HRESULT,SelectAndInstall)(THIS_ HWND hwndParent, OBO_TOKEN *pOboToken, INetCfgComponent **ppnccItem) PURE; + STDMETHOD_(HRESULT,Install)(THIS_ LPCWSTR pszwInfId, OBO_TOKEN *pOboToken, DWORD dwSetupFlags, DWORD dwUpgradeFromBuildNo, + LPCWSTR pszwAnswerFile, LPCWSTR pszwAnswerSections, INetCfgComponent **ppnccItem) PURE; + STDMETHOD_(HRESULT,DeInstall)(THIS_ INetCfgComponent *pComponent, OBO_TOKEN *pOboToken, LPWSTR *pmszwRefs) PURE; +}; +#undef INTERFACE + +#if !defined(__cplusplus) || defined(CINTERFACE) +/*** IUnknown methods ***/ +#define INetCfgClassSetup_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define INetCfgClassSetup_AddRef(p) (p)->lpVtbl->AddRef(p) +#define INetCfgClassSetup_Release(p) (p)->lpVtbl->Release(p) +#define INetCfgClassSetup_SelectAndInstall(p,a,b,c) (p)->lpVtbl->SelectAndInstall(p,a,b,c) +#define INetCfgClassSetup_Install(p,a,b,c,d,e,f,g) (p)->lpVtbl->Install(p,a,b,c,d,e,f,g) +#define INetCfgClassSetup_DeInstall(p,a,b,c) (p)->lpVtbl->DeInstall(p,a,b,c) +#endif #endif diff --git a/sdk/include/psdk/ntgdi.h b/sdk/include/psdk/ntgdi.h index 1087e8cc42e41..d5d651020d401 100644 --- a/sdk/include/psdk/ntgdi.h +++ b/sdk/include/psdk/ntgdi.h @@ -2500,10 +2500,10 @@ NtGdiExtTextOutW( _In_ INT x, _In_ INT y, _In_ UINT flOpts, - _In_opt_ LPRECT prcl, - _In_reads_opt_(cwc) LPWSTR pwsz, - _In_range_(0, 0xffff) INT cwc, - _In_reads_opt_(_Inexpressible_(cwc)) LPINT pdx, + _In_opt_ LPCRECT prcl, + _In_reads_opt_(cwc) LPCWSTR pwsz, + _In_range_(0, 0xffff) UINT cwc, + _In_reads_opt_(_Inexpressible_(cwc)) const INT *pdx, _In_ DWORD dwCodePage); __kernel_entry @@ -3923,4 +3923,392 @@ NtGdiGetCurrentDpiInfo( #endif /* PRIVATE_DWM_INTERFACE */ + +/* ReactOS Display Driver Model */ +__kernel_entry +W32KAPI +BOOLEAN +APIENTRY +NtGdiDdDDICheckExclusiveOwnership(VOID); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDICreateAllocation( + _Inout_ D3DKMT_CREATEALLOCATION* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDICheckMonitorPowerState( + _In_ const D3DKMT_CHECKMONITORPOWERSTATE* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDICheckOcclusion( + _In_ const D3DKMT_CHECKOCCLUSION* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDICloseAdapter( + _In_ const D3DKMT_CLOSEADAPTER* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +WINAPI +NtGdiDdDDICreateContext( + _Inout_ D3DKMT_CREATECONTEXT* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDICreateDevice( + _Inout_ D3DKMT_CREATEDEVICE* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDICreateOverlay( + _Inout_ D3DKMT_CREATEOVERLAY* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDICreateSynchronizationObject( + _Inout_ D3DKMT_CREATESYNCHRONIZATIONOBJECT* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDIWaitForVerticalBlankEvent( + _In_ const D3DKMT_WAITFORVERTICALBLANKEVENT* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDIWaitForIdle( + _In_ const D3DKMT_WAITFORIDLE* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDIUpdateOverlay( + _In_ const D3DKMT_UPDATEOVERLAY* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +WINAPI +NtGdiDdDDIUnlock( + _In_ const D3DKMT_UNLOCK* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDIDestroyAllocation( + _In_ const D3DKMT_DESTROYALLOCATION* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDIDestroyContext( + _In_ const D3DKMT_DESTROYCONTEXT* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDIDestroyDevice( + _In_ const D3DKMT_DESTROYDEVICE* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDIDestroyOverlay( + _In_ const D3DKMT_DESTROYOVERLAY* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDIDestroySynchronizationObject( + _In_ const D3DKMT_DESTROYSYNCHRONIZATIONOBJECT* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDIEscape( + _In_ const D3DKMT_ESCAPE* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDIFlipOverlay( + _In_ const D3DKMT_FLIPOVERLAY* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDIGetContextSchedulingPriority( + _Inout_ D3DKMT_GETCONTEXTSCHEDULINGPRIORITY* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDIGetDeviceState( + _Inout_ D3DKMT_GETDEVICESTATE* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDIGetDisplayModeList( + _Inout_ D3DKMT_GETDISPLAYMODELIST* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDIGetMultisampleMethodList( + _Inout_ D3DKMT_GETMULTISAMPLEMETHODLIST* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDIGetPresentHistory( + _Inout_ D3DKMT_GETPRESENTHISTORY* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDIGetProcessSchedulingPriorityClass( + _In_ HANDLE unnamedParam1, + _Out_ D3DKMT_SCHEDULINGPRIORITYCLASS *unnamedParam2); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDIGetRuntimeData( + _In_ const D3DKMT_GETRUNTIMEDATA* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDIGetScanLine( + _In_ D3DKMT_GETSCANLINE* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDIGetSharedPrimaryHandle( + _Inout_ D3DKMT_GETSHAREDPRIMARYHANDLE* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDIInvalidateActiveVidPn( + _In_ const D3DKMT_INVALIDATEACTIVEVIDPN* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDILock( + _Inout_ D3DKMT_LOCK* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDIOpenAdapterFromDeviceName( + _Inout_ D3DKMT_OPENADAPTERFROMDEVICENAME* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDIOpenAdapterFromGdiDisplayName( + _Inout_ D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDIOpenAdapterFromHdc( + _Inout_ D3DKMT_OPENADAPTERFROMHDC* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDIOpenResource( + _Inout_ D3DKMT_OPENRESOURCE* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDIPollDisplayChildren( + _In_ const D3DKMT_POLLDISPLAYCHILDREN* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDIPresent( + _In_ D3DKMT_PRESENT* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDIQueryAdapterInfo( + _Inout_ const D3DKMT_QUERYADAPTERINFO* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDIQueryAllocationResidency( + _In_ const D3DKMT_QUERYALLOCATIONRESIDENCY* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDIQueryResourceInfo( + _Inout_ D3DKMT_QUERYRESOURCEINFO* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDIQueryStatistics( + _Inout_ const D3DKMT_QUERYSTATISTICS* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDIReleaseProcessVidPnSourceOwners( + _In_ HANDLE unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDIRender( + _In_ D3DKMT_RENDER* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDISetAllocationPriority( + _In_ const D3DKMT_SETALLOCATIONPRIORITY* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDISetContextSchedulingPriority( + _In_ const D3DKMT_SETCONTEXTSCHEDULINGPRIORITY* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDISetDisplayMode( + _In_ const D3DKMT_SETDISPLAYMODE* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDISetDisplayPrivateDriverFormat( + _In_ const D3DKMT_SETDISPLAYPRIVATEDRIVERFORMAT* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDISetGammaRamp( + _In_ const D3DKMT_SETGAMMARAMP* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDISetProcessSchedulingPriorityClass( + _In_ HANDLE unnamedParam1, + _In_ D3DKMT_SCHEDULINGPRIORITYCLASS unnamedParam2); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDISetQueuedLimit( + _Inout_ const D3DKMT_SETQUEUEDLIMIT* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDISetVidPnSourceOwner( + _In_ const D3DKMT_SETVIDPNSOURCEOWNER* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDISharedPrimaryLockNotification( + _In_ const D3DKMT_SHAREDPRIMARYLOCKNOTIFICATION* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDISharedPrimaryUnLockNotification( + _In_ const D3DKMT_SHAREDPRIMARYUNLOCKNOTIFICATION* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDISignalSynchronizationObject( + _In_ const D3DKMT_SIGNALSYNCHRONIZATIONOBJECT* unnamedParam1); + +__kernel_entry +W32KAPI +NTSTATUS +APIENTRY +NtGdiDdDDIWaitForSynchronizationObject( + _In_ const D3DKMT_WAITFORSYNCHRONIZATIONOBJECT* unnamedParam1); + #endif /* _NTGDI_ */ diff --git a/sdk/include/psdk/ntldap.h b/sdk/include/psdk/ntldap.h index a0c2a1de483fc..8ae544a28da11 100644 --- a/sdk/include/psdk/ntldap.h +++ b/sdk/include/psdk/ntldap.h @@ -5,7 +5,7 @@ References: Lightweight Directory Access Protocol Reference - http://msdn.microsoft.com/library/en-us/netdir/ldap/ldap_reference.asp + http://msdn.microsoft.com/library/en-us/netdir/ldap/ldap_reference.asp (DEAD_LINK) This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sdk/include/psdk/oaidl.idl b/sdk/include/psdk/oaidl.idl index 0dc4c0574607b..27e27a92125f5 100644 --- a/sdk/include/psdk/oaidl.idl +++ b/sdk/include/psdk/oaidl.idl @@ -230,6 +230,17 @@ typedef VARIANT *LPVARIANT; typedef VARIANT VARIANTARG; typedef VARIANTARG *LPVARIANTARG; +cpp_quote("#ifdef MIDL_PASS") +typedef const VARIANT *REFVARIANT; +cpp_quote("#elif !defined(_REFVARIANT_DEFINED)") +cpp_quote("#define _REFVARIANT_DEFINED") +cpp_quote("#ifdef __cplusplus") +cpp_quote("#define REFVARIANT const VARIANT &") +cpp_quote("#else") +cpp_quote("#define REFVARIANT const VARIANT *__MIDL_CONST") +cpp_quote("#endif") +cpp_quote("#endif") + struct _wireBRECORD { ULONG fFlags; ULONG clSize; diff --git a/sdk/include/psdk/powrprof.h b/sdk/include/psdk/powrprof.h index 50e54cd6ad93f..4c5f0c69f3c4e 100644 --- a/sdk/include/psdk/powrprof.h +++ b/sdk/include/psdk/powrprof.h @@ -12,87 +12,147 @@ extern "C" { #endif -#define EnableMultiBatteryDisplay 2 -#define EnablePasswordLogon 4 -#define EnableSysTrayBatteryMeter 1 -#define EnableWakeOnRing 8 -#define EnableVideoDimDisplay 16 +#ifdef __REACTOS__ #define NEWSCHEME (UINT)-1 -#ifndef RC_INVOKED - -typedef struct _GLOBAL_MACHINE_POWER_POLICY{ - ULONG Revision; - SYSTEM_POWER_STATE LidOpenWakeAc; - SYSTEM_POWER_STATE LidOpenWakeDc; - ULONG BroadcastCapacityResolution; -} GLOBAL_MACHINE_POWER_POLICY, *PGLOBAL_MACHINE_POWER_POLICY; -typedef struct _GLOBAL_USER_POWER_POLICY{ - ULONG Revision; - POWER_ACTION_POLICY PowerButtonAc; - POWER_ACTION_POLICY PowerButtonDc; - POWER_ACTION_POLICY SleepButtonAc; - POWER_ACTION_POLICY SleepButtonDc; - POWER_ACTION_POLICY LidCloseAc; - POWER_ACTION_POLICY LidCloseDc; - SYSTEM_POWER_LEVEL DischargePolicy[NUM_DISCHARGE_POLICIES]; - ULONG GlobalFlags; -} GLOBAL_USER_POWER_POLICY, *PGLOBAL_USER_POWER_POLICY; -typedef struct _GLOBAL_POWER_POLICY{ - GLOBAL_USER_POWER_POLICY user; - GLOBAL_MACHINE_POWER_POLICY mach; -} GLOBAL_POWER_POLICY, *PGLOBAL_POWER_POLICY; -typedef struct _MACHINE_POWER_POLICY{ - ULONG Revision; - SYSTEM_POWER_STATE MinSleepAc; - SYSTEM_POWER_STATE MinSleepDc; - SYSTEM_POWER_STATE ReducedLatencySleepAc; - SYSTEM_POWER_STATE ReducedLatencySleepDc; - ULONG DozeTimeoutAc; - ULONG DozeTimeoutDc; - ULONG DozeS4TimeoutAc; - ULONG DozeS4TimeoutDc; - UCHAR MinThrottleAc; - UCHAR MinThrottleDc; - UCHAR pad1[2]; - POWER_ACTION_POLICY OverThrottledAc; - POWER_ACTION_POLICY OverThrottledDc; -} MACHINE_POWER_POLICY, *PMACHINE_POWER_POLICY; +typedef enum _POWER_PLATFORM_ROLE { + PlatformRoleUnspecified, + PlatformRoleDesktop, + PlatformRoleMobile, + PlatformRoleWorkstation, + PlatformRoleEnterpriseServer, + PlatformRoleSOHOServer, + PlatformRoleAppliancePC, + PlatformRolePerformanceServer, + PlatformRoleSlate, + PlatformRoleMaximum +} POWER_PLATFORM_ROLE, *PPOWER_PLATFORM_ROLE; +#endif + +#define EnableSysTrayBatteryMeter 0x01 +#define EnableMultiBatteryDisplay 0x02 +#define EnablePasswordLogon 0x04 +#define EnableWakeOnRing 0x08 +#define EnableVideoDimDisplay 0x10 + +typedef struct _GLOBAL_MACHINE_POWER_POLICY { + ULONG Revision; + SYSTEM_POWER_STATE LidOpenWakeAc; + SYSTEM_POWER_STATE LidOpenWakeDc; + ULONG BroadcastCapacityResolution; +} GLOBAL_MACHINE_POWER_POLICY, +*PGLOBAL_MACHINE_POWER_POLICY; + +typedef struct _GLOBAL_USER_POWER_POLICY { + ULONG Revision; + POWER_ACTION_POLICY PowerButtonAc; + POWER_ACTION_POLICY PowerButtonDc; + POWER_ACTION_POLICY SleepButtonAc; + POWER_ACTION_POLICY SleepButtonDc; + POWER_ACTION_POLICY LidCloseAc; + POWER_ACTION_POLICY LidCloseDc; + SYSTEM_POWER_LEVEL DischargePolicy[NUM_DISCHARGE_POLICIES]; + ULONG GlobalFlags; +} GLOBAL_USER_POWER_POLICY, +*PGLOBAL_USER_POWER_POLICY; + +typedef struct _GLOBAL_POWER_POLICY { + GLOBAL_USER_POWER_POLICY user; + GLOBAL_MACHINE_POWER_POLICY mach; +} GLOBAL_POWER_POLICY, +*PGLOBAL_POWER_POLICY; + +typedef struct _MACHINE_POWER_POLICY { + ULONG Revision; + SYSTEM_POWER_STATE MinSleepAc; + SYSTEM_POWER_STATE MinSleepDc; + SYSTEM_POWER_STATE ReducedLatencySleepAc; + SYSTEM_POWER_STATE ReducedLatencySleepDc; + ULONG DozeTimeoutAc; + ULONG DozeTimeoutDc; + ULONG DozeS4TimeoutAc; + ULONG DozeS4TimeoutDc; + UCHAR MinThrottleAc; + UCHAR MinThrottleDc; + UCHAR pad1[2]; + POWER_ACTION_POLICY OverThrottledAc; + POWER_ACTION_POLICY OverThrottledDc; +} MACHINE_POWER_POLICY, +*PMACHINE_POWER_POLICY; + typedef struct _MACHINE_PROCESSOR_POWER_POLICY { - ULONG Revision; - PROCESSOR_POWER_POLICY ProcessorPolicyAc; - PROCESSOR_POWER_POLICY ProcessorPolicyDc; -} MACHINE_PROCESSOR_POWER_POLICY, *PMACHINE_PROCESSOR_POWER_POLICY; -typedef struct _USER_POWER_POLICY{ - ULONG Revision; - POWER_ACTION_POLICY IdleAc; - POWER_ACTION_POLICY IdleDc; - ULONG IdleTimeoutAc; - ULONG IdleTimeoutDc; - UCHAR IdleSensitivityAc; - UCHAR IdleSensitivityDc; - UCHAR ThrottlePolicyAc; - UCHAR ThrottlePolicyDc; - SYSTEM_POWER_STATE MaxSleepAc; - SYSTEM_POWER_STATE MaxSleepDc; - ULONG Reserved[2]; - ULONG VideoTimeoutAc; - ULONG VideoTimeoutDc; - ULONG SpindownTimeoutAc; - ULONG SpindownTimeoutDc; - BOOLEAN OptimizeForPowerAc; - BOOLEAN OptimizeForPowerDc; - UCHAR FanThrottleToleranceAc; - UCHAR FanThrottleToleranceDc; - UCHAR ForcedThrottleAc; - UCHAR ForcedThrottleDc; -} USER_POWER_POLICY, *PUSER_POWER_POLICY; -typedef struct _POWER_POLICY{ - USER_POWER_POLICY user; - MACHINE_POWER_POLICY mach; -} POWER_POLICY, *PPOWER_POLICY; + ULONG Revision; + PROCESSOR_POWER_POLICY ProcessorPolicyAc; + PROCESSOR_POWER_POLICY ProcessorPolicyDc; +} MACHINE_PROCESSOR_POWER_POLICY, +*PMACHINE_PROCESSOR_POWER_POLICY; + +typedef struct _USER_POWER_POLICY { + ULONG Revision; + POWER_ACTION_POLICY IdleAc; + POWER_ACTION_POLICY IdleDc; + ULONG IdleTimeoutAc; + ULONG IdleTimeoutDc; + UCHAR IdleSensitivityAc; + UCHAR IdleSensitivityDc; + UCHAR ThrottlePolicyAc; + UCHAR ThrottlePolicyDc; + SYSTEM_POWER_STATE MaxSleepAc; + SYSTEM_POWER_STATE MaxSleepDc; + ULONG Reserved[2]; + ULONG VideoTimeoutAc; + ULONG VideoTimeoutDc; + ULONG SpindownTimeoutAc; + ULONG SpindownTimeoutDc; + BOOLEAN OptimizeForPowerAc; + BOOLEAN OptimizeForPowerDc; + UCHAR FanThrottleToleranceAc; + UCHAR FanThrottleToleranceDc; + UCHAR ForcedThrottleAc; + UCHAR ForcedThrottleDc; +} USER_POWER_POLICY, +*PUSER_POWER_POLICY; + +typedef struct _POWER_POLICY { + USER_POWER_POLICY user; + MACHINE_POWER_POLICY mach; +} POWER_POLICY, +*PPOWER_POLICY; + +typedef enum _POWER_DATA_ACCESSOR { + ACCESS_AC_POWER_SETTING_INDEX, + ACCESS_DC_POWER_SETTING_INDEX, + ACCESS_FRIENDLY_NAME, + ACCESS_DESCRIPTION, + ACCESS_POSSIBLE_POWER_SETTING, + ACCESS_POSSIBLE_POWER_SETTING_FRIENDLY_NAME, + ACCESS_POSSIBLE_POWER_SETTING_DESCRIPTION, + ACCESS_DEFAULT_AC_POWER_SETTING, + ACCESS_DEFAULT_DC_POWER_SETTING, + ACCESS_POSSIBLE_VALUE_MIN, + ACCESS_POSSIBLE_VALUE_MAX, + ACCESS_POSSIBLE_VALUE_INCREMENT, + ACCESS_POSSIBLE_VALUE_UNITS, + ACCESS_ICON_RESOURCE, + ACCESS_DEFAULT_SECURITY_DESCRIPTOR, + ACCESS_ATTRIBUTES, + ACCESS_SCHEME, + ACCESS_SUBGROUP, + ACCESS_INDIVIDUAL_SETTING, + ACCESS_ACTIVE_SCHEME, + ACCESS_CREATE_SCHEME, + ACCESS_AC_POWER_SETTING_MAX, + ACCESS_DC_POWER_SETTING_MAX, + ACCESS_AC_POWER_SETTING_MIN, + ACCESS_DC_POWER_SETTING_MIN, + ACCESS_PROFILE, + ACCESS_OVERLAY_SCHEME, + ACCESS_ACTIVE_OVERLAY_SCHEME, +} POWER_DATA_ACCESSOR, *PPOWER_DATA_ACCESSOR; + typedef BOOLEAN (CALLBACK* PWRSCHEMESENUMPROC)(UINT, DWORD, LPWSTR, DWORD, LPWSTR, PPOWER_POLICY, LPARAM); -typedef BOOLEAN (CALLBACK* PFNNTINITIATEPWRACTION)(POWER_ACTION, SYSTEM_POWER_STATE, ULONG, BOOLEAN); +typedef PVOID HPOWERNOTIFY, *PHPOWERNOTIFY; + NTSTATUS WINAPI CallNtPowerInformation(POWER_INFORMATION_LEVEL, PVOID, ULONG, PVOID, ULONG); BOOLEAN WINAPI CanUserWritePwrScheme(VOID); BOOLEAN WINAPI DeletePwrScheme(UINT); @@ -105,6 +165,12 @@ BOOLEAN WINAPI IsAdminOverrideActive(PADMINISTRATOR_POWER_POLICY); BOOLEAN WINAPI IsPwrHibernateAllowed(VOID); BOOLEAN WINAPI IsPwrShutdownAllowed(VOID); BOOLEAN WINAPI IsPwrSuspendAllowed(VOID); +DWORD WINAPI PowerEnumerate(HKEY, const GUID *, const GUID *, POWER_DATA_ACCESSOR, ULONG, UCHAR *, DWORD *); +DWORD WINAPI PowerRegisterSuspendResumeNotification(DWORD, HANDLE, PHPOWERNOTIFY); +DWORD WINAPI PowerUnregisterSuspendResumeNotification(HPOWERNOTIFY); +DWORD WINAPI PowerSettingRegisterNotification(const GUID *, DWORD, HANDLE, PHPOWERNOTIFY); +DWORD WINAPI PowerSettingUnregisterNotification(HPOWERNOTIFY); +DWORD WINAPI PowerWriteACValueIndex(HKEY, const GUID *, const GUID *, const GUID *, DWORD); BOOLEAN WINAPI ReadGlobalPwrPolicy(PGLOBAL_POWER_POLICY); BOOLEAN WINAPI ReadProcessorPwrScheme(UINT, PMACHINE_PROCESSOR_POWER_POLICY); BOOLEAN WINAPI ReadPwrScheme(UINT, PPOWER_POLICY); @@ -115,7 +181,8 @@ BOOLEAN WINAPI WriteProcessorPwrScheme(UINT, PMACHINE_PROCESSOR_POWER_POLICY); BOOLEAN WINAPI ValidatePowerPolicies(PGLOBAL_POWER_POLICY, PPOWER_POLICY); BOOLEAN WINAPI WritePwrScheme(PUINT, LPWSTR, LPWSTR, PPOWER_POLICY); -#endif /* RC_INVOKED */ +/* Power scheme */ +POWER_PLATFORM_ROLE WINAPI PowerDeterminePlatformRole(void); #ifdef __cplusplus } diff --git a/sdk/include/psdk/propsys.idl b/sdk/include/psdk/propsys.idl index bdd67fa6a5993..240bbfd86ca12 100644 --- a/sdk/include/psdk/propsys.idl +++ b/sdk/include/psdk/propsys.idl @@ -27,7 +27,13 @@ import "shtypes.idl"; import "structuredquerycondition.idl"; cpp_quote("#ifndef PSSTDAPI") -cpp_quote("#define PSSTDAPI EXTERN_C DECLSPEC_IMPORT HRESULT STDAPICALLTYPE") +cpp_quote("#ifdef _PROPSYS_") +cpp_quote("#define PSSTDAPI STDAPI") +cpp_quote("#define PSSTDAPI_(type) STDAPI_(type)") +cpp_quote("#else") +cpp_quote("#define PSSTDAPI EXTERN_C DECLSPEC_IMPORT HRESULT STDAPICALLTYPE") +cpp_quote("#define PSSTDAPI_(type) EXTERN_C DECLSPEC_IMPORT type STDAPICALLTYPE") +cpp_quote("#endif") cpp_quote("#endif") cpp_quote("#if 0") @@ -272,7 +278,7 @@ interface IPropertyEnumType : IUnknown } [ - uuid(9b6e051c-5ddd-4321-9070-fe2acb55e974), + uuid(9b6e051c-5ddd-4321-9070-fe2acb55e794), object, pointer_default(unique) ] @@ -799,14 +805,15 @@ cpp_quote("#define PKEY_PIDSTR_MAX 10") cpp_quote("#define GUIDSTRING_MAX 39") cpp_quote("#define PKEYSTR_MAX (GUIDSTRING_MAX + 1 + PKEY_PIDSTR_MAX)") -cpp_quote("HRESULT WINAPI PSCreateMemoryPropertyStore(REFIID,void **);") -cpp_quote("HRESULT WINAPI PSStringFromPropertyKey(REFPROPERTYKEY,LPWSTR,UINT);") -cpp_quote("HRESULT WINAPI PSPropertyKeyFromString(LPCWSTR,PROPERTYKEY*);") -cpp_quote("HRESULT WINAPI PSGetPropertyDescription(REFPROPERTYKEY,REFIID,void **);") -cpp_quote("HRESULT WINAPI PSGetPropertyDescriptionListFromString(LPCWSTR,REFIID,void **);") -cpp_quote("HRESULT WINAPI PSRefreshPropertySchema(void);") -cpp_quote("HRESULT WINAPI PSRegisterPropertySchema(LPCWSTR);") -cpp_quote("HRESULT WINAPI PSUnregisterPropertySchema(LPCWSTR);") +cpp_quote("PSSTDAPI PSCreateMemoryPropertyStore(REFIID,void **);") +cpp_quote("PSSTDAPI PSCreatePropertyStoreFromObject(IUnknown*,DWORD,REFIID,void **);") +cpp_quote("PSSTDAPI PSStringFromPropertyKey(REFPROPERTYKEY,LPWSTR,UINT);") +cpp_quote("PSSTDAPI PSPropertyKeyFromString(LPCWSTR,PROPERTYKEY*);") +cpp_quote("PSSTDAPI PSGetPropertyDescription(REFPROPERTYKEY,REFIID,void **);") +cpp_quote("PSSTDAPI PSGetPropertyDescriptionListFromString(LPCWSTR,REFIID,void **);") +cpp_quote("PSSTDAPI PSRefreshPropertySchema(void);") +cpp_quote("PSSTDAPI PSRegisterPropertySchema(LPCWSTR);") +cpp_quote("PSSTDAPI PSUnregisterPropertySchema(LPCWSTR);") /* TODO: Add remainder of the C api here */ @@ -821,7 +828,7 @@ library PropSysObjects { interface IPropertyStore; } - [uuid(b8967f86-58ae-4f96-9fb2-5d7904798f4b)] coclass PropertySystem + [uuid(b8967f85-58ae-4f46-9fb2-5d7904798f4b)] coclass PropertySystem { interface IPropertySystem; } diff --git a/sdk/include/psdk/propvarutil.h b/sdk/include/psdk/propvarutil.h index e0a21faf8c733..9f6890335483e 100644 --- a/sdk/include/psdk/propvarutil.h +++ b/sdk/include/psdk/propvarutil.h @@ -22,6 +22,16 @@ #include #include +#ifndef PSSTDAPI +#ifdef _PROPSYS_ +#define PSSTDAPI STDAPI +#define PSSTDAPI_(type) STDAPI_(type) +#else +#define PSSTDAPI DECLSPEC_IMPORT STDAPI +#define PSSTDAPI_(type) DECLSPEC_IMPORT STDAPI_(type) +#endif +#endif + #ifdef __cplusplus extern "C" { #endif @@ -63,37 +73,56 @@ enum tagPROPVAR_COMPARE_FLAGS typedef int PROPVAR_COMPARE_FLAGS; -HRESULT WINAPI PropVariantChangeType(PROPVARIANT *ppropvarDest, REFPROPVARIANT propvarSrc, +PSSTDAPI PropVariantChangeType(PROPVARIANT *ppropvarDest, REFPROPVARIANT propvarSrc, PROPVAR_CHANGE_FLAGS flags, VARTYPE vt); -HRESULT WINAPI InitPropVariantFromGUIDAsString(REFGUID guid, PROPVARIANT *ppropvar); -HRESULT WINAPI InitVariantFromGUIDAsString(REFGUID guid, VARIANT *pvar); -HRESULT WINAPI InitPropVariantFromBuffer(const VOID *pv, UINT cb, PROPVARIANT *ppropvar); -HRESULT WINAPI InitPropVariantFromCLSID(REFCLSID clsid, PROPVARIANT *ppropvar); -HRESULT WINAPI InitVariantFromBuffer(const VOID *pv, UINT cb, VARIANT *pvar); -HRESULT WINAPI PropVariantToGUID(const PROPVARIANT *ppropvar, GUID *guid); -HRESULT WINAPI VariantToGUID(const VARIANT *pvar, GUID *guid); -INT WINAPI PropVariantCompareEx(REFPROPVARIANT propvar1, REFPROPVARIANT propvar2, +PSSTDAPI InitPropVariantFromGUIDAsString(REFGUID guid, PROPVARIANT *ppropvar); +PSSTDAPI InitVariantFromFileTime(const FILETIME *ft, VARIANT *var); +PSSTDAPI InitVariantFromGUIDAsString(REFGUID guid, VARIANT *pvar); +PSSTDAPI InitPropVariantFromBuffer(const VOID *pv, UINT cb, PROPVARIANT *ppropvar); +PSSTDAPI InitPropVariantFromCLSID(REFCLSID clsid, PROPVARIANT *ppropvar); +PSSTDAPI InitVariantFromBuffer(const VOID *pv, UINT cb, VARIANT *pvar); +PSSTDAPI PropVariantToGUID(const PROPVARIANT *ppropvar, GUID *guid); +PSSTDAPI VariantToGUID(const VARIANT *pvar, GUID *guid); +PSSTDAPI_(INT) PropVariantCompareEx(REFPROPVARIANT propvar1, REFPROPVARIANT propvar2, PROPVAR_COMPARE_UNIT uint, PROPVAR_COMPARE_FLAGS flags); - -HRESULT WINAPI PropVariantToDouble(REFPROPVARIANT propvarIn, double *ret); -HRESULT WINAPI PropVariantToInt16(REFPROPVARIANT propvarIn, SHORT *ret); -HRESULT WINAPI PropVariantToInt32(REFPROPVARIANT propvarIn, LONG *ret); -HRESULT WINAPI PropVariantToInt64(REFPROPVARIANT propvarIn, LONGLONG *ret); -HRESULT WINAPI PropVariantToUInt16(REFPROPVARIANT propvarIn, USHORT *ret); -HRESULT WINAPI PropVariantToUInt32(REFPROPVARIANT propvarIn, ULONG *ret); -HRESULT WINAPI PropVariantToUInt64(REFPROPVARIANT propvarIn, ULONGLONG *ret); -HRESULT WINAPI PropVariantToBoolean(REFPROPVARIANT propvarIn, BOOL *ret); -HRESULT WINAPI PropVariantToBuffer(REFPROPVARIANT propvarIn, void *ret, UINT cb); -HRESULT WINAPI PropVariantToString(REFPROPVARIANT propvarIn, PWSTR ret, UINT cch); -PCWSTR WINAPI PropVariantToStringWithDefault(REFPROPVARIANT propvarIn, LPCWSTR pszDefault); - -HRESULT WINAPI PropVariantToStringAlloc(REFPROPVARIANT propvarIn, WCHAR **ret); +PSSTDAPI InitPropVariantFromFileTime(const FILETIME *pftIn, PROPVARIANT *ppropvar); +PSSTDAPI InitPropVariantFromStringVector(PCWSTR *strs, ULONG count, PROPVARIANT *ppropvar); + +PSSTDAPI PropVariantToDouble(REFPROPVARIANT propvarIn, double *ret); +PSSTDAPI PropVariantToInt16(REFPROPVARIANT propvarIn, SHORT *ret); +PSSTDAPI PropVariantToInt32(REFPROPVARIANT propvarIn, LONG *ret); +PSSTDAPI PropVariantToInt64(REFPROPVARIANT propvarIn, LONGLONG *ret); +PSSTDAPI PropVariantToUInt16(REFPROPVARIANT propvarIn, USHORT *ret); +PSSTDAPI PropVariantToUInt32(REFPROPVARIANT propvarIn, ULONG *ret); +PSSTDAPI_(ULONG) PropVariantToUInt32WithDefault(REFPROPVARIANT propvarIn, ULONG uLDefault); +PSSTDAPI PropVariantToUInt64(REFPROPVARIANT propvarIn, ULONGLONG *ret); +PSSTDAPI PropVariantToBoolean(REFPROPVARIANT propvarIn, BOOL *ret); +PSSTDAPI PropVariantToBSTR(REFPROPVARIANT propvar, BSTR *bstr); +PSSTDAPI PropVariantToBuffer(REFPROPVARIANT propvarIn, void *ret, UINT cb); +PSSTDAPI PropVariantToString(REFPROPVARIANT propvarIn, PWSTR ret, UINT cch); +PSSTDAPI_(PCWSTR) PropVariantToStringWithDefault(REFPROPVARIANT propvarIn, LPCWSTR pszDefault); +PSSTDAPI_(PCWSTR) VariantToStringWithDefault(const VARIANT *pvar, LPCWSTR pszDefault); +PSSTDAPI VariantToString(REFVARIANT var, PWSTR ret, UINT cch); + +PSSTDAPI PropVariantToStringAlloc(REFPROPVARIANT propvarIn, WCHAR **ret); + +PSSTDAPI PropVariantToVariant(const PROPVARIANT *propvar, VARIANT *var); +PSSTDAPI VariantToPropVariant(const VARIANT* var, PROPVARIANT* propvar); #ifdef __cplusplus HRESULT InitPropVariantFromBoolean(BOOL fVal, PROPVARIANT *ppropvar); -HRESULT InitPropVariantFromString(PCWSTR psz, PROPVARIANT *ppropvar); +HRESULT InitPropVariantFromInt16(SHORT nVal, PROPVARIANT *ppropvar); +HRESULT InitPropVariantFromUInt16(USHORT uiVal, PROPVARIANT *ppropvar); +HRESULT InitPropVariantFromInt32(LONG lVal, PROPVARIANT *ppropvar); +HRESULT InitPropVariantFromUInt32(ULONG ulVal, PROPVARIANT *ppropvar); HRESULT InitPropVariantFromInt64(LONGLONG llVal, PROPVARIANT *ppropvar); +HRESULT InitPropVariantFromUInt64(ULONGLONG ullVal, PROPVARIANT *ppropvar); +HRESULT InitPropVariantFromDouble(DOUBLE dblVal, PROPVARIANT *ppropvar); +HRESULT InitPropVariantFromString(PCWSTR psz, PROPVARIANT *ppropvar); +HRESULT InitPropVariantFromGUIDAsBuffer(REFGUID guid, PROPVARIANT *ppropvar); +BOOL IsPropVariantVector(REFPROPVARIANT propvar); +BOOL IsPropVariantString(REFPROPVARIANT propvar); #ifndef NO_PROPVAR_INLINES @@ -104,6 +133,55 @@ inline HRESULT InitPropVariantFromBoolean(BOOL fVal, PROPVARIANT *ppropvar) return S_OK; } +inline HRESULT InitPropVariantFromInt16(SHORT nVal, PROPVARIANT *ppropvar) +{ + ppropvar->vt = VT_I2; + ppropvar->iVal = nVal; + return S_OK; +} + +inline HRESULT InitPropVariantFromUInt16(USHORT uiVal, PROPVARIANT *ppropvar) +{ + ppropvar->vt = VT_UI2; + ppropvar->uiVal = uiVal; + return S_OK; +} + +inline HRESULT InitPropVariantFromInt32(LONG lVal, PROPVARIANT *ppropvar) +{ + ppropvar->vt = VT_I4; + ppropvar->lVal = lVal; + return S_OK; +} + +inline HRESULT InitPropVariantFromUInt32(ULONG ulVal, PROPVARIANT *ppropvar) +{ + ppropvar->vt = VT_UI4; + ppropvar->ulVal = ulVal; + return S_OK; +} + +inline HRESULT InitPropVariantFromInt64(LONGLONG llVal, PROPVARIANT *ppropvar) +{ + ppropvar->vt = VT_I8; + ppropvar->hVal.QuadPart = llVal; + return S_OK; +} + +inline HRESULT InitPropVariantFromUInt64(ULONGLONG ullVal, PROPVARIANT *ppropvar) +{ + ppropvar->vt = VT_UI8; + ppropvar->uhVal.QuadPart = ullVal; + return S_OK; +} + +inline HRESULT InitPropVariantFromDouble(DOUBLE dblVal, PROPVARIANT *ppropvar) +{ + ppropvar->vt = VT_R8; + ppropvar->dblVal = dblVal; + return S_OK; +} + inline HRESULT InitPropVariantFromString(PCWSTR psz, PROPVARIANT *ppropvar) { HRESULT hres; @@ -117,16 +195,26 @@ inline HRESULT InitPropVariantFromString(PCWSTR psz, PROPVARIANT *ppropvar) return hres; } -inline HRESULT InitPropVariantFromInt64(LONGLONG llVal, PROPVARIANT *ppropvar) +inline HRESULT InitPropVariantFromGUIDAsBuffer(REFGUID guid, PROPVARIANT *ppropvar) { - ppropvar->vt = VT_I8; - ppropvar->hVal.QuadPart = llVal; - return S_OK; + return InitPropVariantFromBuffer(&guid, sizeof(GUID), ppropvar); +} + +inline BOOL IsPropVariantVector(REFPROPVARIANT propvar) +{ + return (propvar.vt & (VT_ARRAY | VT_VECTOR)); +} + +inline BOOL IsPropVariantString(REFPROPVARIANT propvar) +{ + return (PropVariantToStringWithDefault(propvar, NULL) != NULL); } #endif /* NO_PROPVAR_INLINES */ #endif /* __cplusplus */ +PSSTDAPI StgSerializePropVariant(const PROPVARIANT *ppropvar, SERIALIZEDPROPERTYVALUE **ppprop, ULONG *pcb); +PSSTDAPI StgDeserializePropVariant(const SERIALIZEDPROPERTYVALUE *pprop, ULONG cbmax, PROPVARIANT *ppropvar); #ifdef __cplusplus } diff --git a/sdk/include/psdk/rpc.h b/sdk/include/psdk/rpc.h index b35c35fcad1cb..42d76d9a95270 100644 --- a/sdk/include/psdk/rpc.h +++ b/sdk/include/psdk/rpc.h @@ -5,10 +5,6 @@ #endif /* _INC_WINDOWS */ #endif -#if defined(__USE_PSEH2__) && !defined(RC_INVOKED) -#include -#endif - #ifndef __RPC_H__ #define __RPC_H__ @@ -122,25 +118,14 @@ typedef int RPC_STATUS; #include #include - #ifndef __USE_PSEH2__ - #define RpcTryExcept __try { - #define RpcExcept(expr) } __except (expr) { - #define RpcEndExcept } - #define RpcTryFinally __try { - #define RpcFinally } __finally { - #define RpcEndFinally } - #define RpcExceptionCode() GetExceptionCode() - #define RpcAbnormalTermination() AbnormalTermination() - #else - #define RpcTryExcept _SEH2_TRY - #define RpcExcept(expr) _SEH2_EXCEPT((expr)) - #define RpcEndExcept _SEH2_END; - #define RpcTryFinally _SEH2_TRY - #define RpcFinally _SEH2_FINALLY - #define RpcEndFinally _SEH2_END; - #define RpcExceptionCode() _SEH2_GetExceptionCode() - #define RpcAbnormalTermination() (_SEH2_GetExceptionCode() != 0) - #endif + #define RpcTryExcept _SEH2_TRY + #define RpcExcept(expr) _SEH2_EXCEPT((expr)) + #define RpcEndExcept _SEH2_END; + #define RpcTryFinally _SEH2_TRY + #define RpcFinally _SEH2_FINALLY + #define RpcEndFinally _SEH2_END; + #define RpcExceptionCode() _SEH2_GetExceptionCode() + #define RpcAbnormalTermination() (_SEH2_GetExceptionCode() != 0) #endif #if defined(__RPC_WIN64__) diff --git a/sdk/include/psdk/secext.h b/sdk/include/psdk/secext.h index b60399241ee2d..d93971131711b 100644 --- a/sdk/include/psdk/secext.h +++ b/sdk/include/psdk/secext.h @@ -1,8 +1,13 @@ #ifndef _SECEXT_H #define _SECEXT_H +#ifdef __cplusplus +extern "C" { +#endif + #ifndef RC_INVOKED #if (_WIN32_WINNT >= 0x0500) + typedef enum { NameUnknown = 0, @@ -34,7 +39,11 @@ BOOLEAN WINAPI TranslateNameW(LPCWSTR,EXTENDED_NAME_FORMAT,EXTENDED_NAME_FORMAT, #define TranslateName TranslateNameA #endif - #endif /* ! RC_INVOKED */ #endif /* _WIN32_WINNT >= 0x0500 */ + +#ifdef __cplusplus +} // extern "C" +#endif + #endif /* ! _SECEXT_H */ diff --git a/sdk/include/psdk/setupapi.h b/sdk/include/psdk/setupapi.h index efe15a7b0bfda..b209c8f00bbd6 100644 --- a/sdk/include/psdk/setupapi.h +++ b/sdk/include/psdk/setupapi.h @@ -117,6 +117,7 @@ extern "C" { #define DICS_START 4 #define DICS_FLAG_CONFIGGENERAL 4 #define DICS_STOP 5 +#define DICUSTOMDEVPROP_MERGE_MULTISZ 0x00000001 #define DIF_SELECTDEVICE 1 #define DIF_INSTALLDEVICE 2 #define DIF_ASSIGNRESOURCES 3 diff --git a/sdk/include/psdk/shellapi.h b/sdk/include/psdk/shellapi.h index 479d27d228d28..fa94826ade4b2 100644 --- a/sdk/include/psdk/shellapi.h +++ b/sdk/include/psdk/shellapi.h @@ -638,6 +638,12 @@ DoEnvironmentSubstW( _Inout_updates_(cchSrc) LPWSTR pszSrc, UINT cchSrc); +HRESULT WINAPI +SHSetUnreadMailCountW( + _In_ PCWSTR pszMailAddress, + _In_ DWORD dwCount, + _In_ PCWSTR pszShellExecuteCommand); + #if (_WIN32_IE >= 0x0601) BOOL WINAPI @@ -646,6 +652,22 @@ SHTestTokenMembership( _In_ ULONG ulRID); #endif +HRESULT WINAPI +SHEnumerateUnreadMailAccountsW( + _In_opt_ HKEY hKeyUser, + _In_ DWORD dwIndex, + _Out_writes_(cchMailAddress) PWSTR pszMailAddress, + _In_ INT cchMailAddress); + +HRESULT WINAPI +SHGetUnreadMailCountW( + _In_opt_ HKEY hKeyUser, + _In_opt_ PCWSTR pszMailAddress, + _Out_opt_ PDWORD pdwCount, + _Inout_opt_ PFILETIME pFileTime, + _Out_writes_opt_(cchShellExecuteCommand) PWSTR pszShellExecuteCommand, + _In_ INT cchShellExecuteCommand); + #ifdef UNICODE #define NOTIFYICONDATA_V1_SIZE NOTIFYICONDATAW_V1_SIZE #define NOTIFYICONDATA_V2_SIZE NOTIFYICONDATAW_V2_SIZE diff --git a/sdk/include/psdk/shlobj.h b/sdk/include/psdk/shlobj.h index 10e73f0ddcd2a..530b9c07f9b17 100644 --- a/sdk/include/psdk/shlobj.h +++ b/sdk/include/psdk/shlobj.h @@ -409,6 +409,14 @@ SHStartNetConnectionDialogW( _In_ LPCWSTR pszRemoteName, _In_ DWORD dwType); +BOOL WINAPI +PathMakeUniqueName( + _Out_ PWSTR pszUniqueName, + _In_ UINT cchMax, + _In_ PCWSTR pszTemplate, + _In_opt_ PCWSTR pszLongPlate, + _In_opt_ PCWSTR pszDir); + /***************************************************************************** * IContextMenu interface */ diff --git a/sdk/include/psdk/shlwapi.h b/sdk/include/psdk/shlwapi.h index 547cf01ea8ad0..c1430aafebe1c 100644 --- a/sdk/include/psdk/shlwapi.h +++ b/sdk/include/psdk/shlwapi.h @@ -25,6 +25,15 @@ #include #include +#ifndef _SHLWAPI_ +#define LWSTDAPI_(type) EXTERN_C DECLSPEC_IMPORT type WINAPI +#define LWSTDAPIV_(type) EXTERN_C DECLSPEC_IMPORT type STDAPIVCALLTYPE +#else +#define LWSTDAPI_(type) type WINAPI +#define LWSTDAPIV_(type) type STDAPIVCALLTYPE +#endif +#define LWSTDAPI LWSTDAPI_(HRESULT) + #ifdef __cplusplus extern "C" { #endif /* defined(__cplusplus) */ @@ -1558,8 +1567,8 @@ LPSTR WINAPI StrDupA(_In_ LPCSTR); LPWSTR WINAPI StrDupW(_In_ LPCWSTR); #define StrDup WINELIB_NAME_AW(StrDup) -HRESULT WINAPI SHStrDupA(_In_ LPCSTR, _Outptr_ WCHAR**); -HRESULT WINAPI SHStrDupW(_In_ LPCWSTR, _Outptr_ WCHAR**); +HRESULT WINAPI SHStrDupA(_In_ LPCSTR psz, _Outptr_ WCHAR** ppwsz); +HRESULT WINAPI SHStrDupW(_In_ LPCWSTR psz, _Outptr_ WCHAR** ppwsz); #define SHStrDup WINELIB_NAME_AW(SHStrDup) LPSTR @@ -1897,6 +1906,14 @@ SHCreateStreamOnFileEx( HRESULT WINAPI SHCreateStreamWrapper(LPBYTE,DWORD,DWORD,struct IStream**); +#ifndef _SHLWAPI_ +LWSTDAPI IStream_Reset(_In_ struct IStream*); +#if !defined(IStream_Read) && defined(__cplusplus) +LWSTDAPI IStream_Read(_In_ struct IStream*, _Out_ void*, _In_ ULONG); +LWSTDAPI IStream_Write(_In_ struct IStream*, _In_ const void*, _In_ ULONG); +#endif +#endif + #endif /* NO_SHLWAPI_STREAM */ #ifndef NO_SHLWAPI_SHARED diff --git a/sdk/include/psdk/shobjidl.idl b/sdk/include/psdk/shobjidl.idl index 8738863eb5525..777cfde2e4a4d 100644 --- a/sdk/include/psdk/shobjidl.idl +++ b/sdk/include/psdk/shobjidl.idl @@ -898,6 +898,7 @@ interface IFolderView : IUnknown [in] DWORD flags ); } +cpp_quote("#define SID_SFolderView IID_IFolderView") [v1_enum] enum tagSORTDIRECTION { diff --git a/sdk/include/psdk/textserv.h b/sdk/include/psdk/textserv.h index 455e88c558156..26278cc85c82f 100644 --- a/sdk/include/psdk/textserv.h +++ b/sdk/include/psdk/textserv.h @@ -33,9 +33,9 @@ extern "C" { #define THISCALLMETHOD_(type,method) type (__thiscall *method) #endif -DEFINE_GUID(IID_ITextServices,0x8d33f740,0xcf58,0x11ce,0xa8,0x9d,0x00,0xaa,0x00,0x6c,0xad,0xc5); -DEFINE_GUID(IID_ITextHost, 0xc5bdd8d0,0xd26e,0x11ce,0xa8,0x9e,0x00,0xaa,0x00,0x6c,0xad,0xc5); -DEFINE_GUID(IID_ITextHost2, 0xc5bdd8d0,0xd26e,0x11ce,0xa8,0x9e,0x00,0xaa,0x00,0x6c,0xad,0xc5); +EXTERN_C const IID IID_ITextServices; +EXTERN_C const IID IID_ITextHost; +EXTERN_C const IID IID_ITextHost2; /***************************************************************************** * ITextServices interface @@ -108,10 +108,10 @@ DECLARE_INTERFACE_(ITextServices,IUnknown) INT y, DWORD* pHitResult) PURE; - THISCALLMETHOD_(HRESULT,OnTxInplaceActivate)( THIS_ + THISCALLMETHOD_(HRESULT,OnTxInPlaceActivate)( THIS_ LPCRECT prcClient) PURE; - THISCALLMETHOD_(HRESULT,OnTxInplaceDeactivate)( THIS ) PURE; + THISCALLMETHOD_(HRESULT,OnTxInPlaceDeactivate)( THIS ) PURE; THISCALLMETHOD_(HRESULT,OnTxUIActivate)( THIS ) PURE; @@ -151,6 +151,7 @@ DECLARE_INTERFACE_(ITextServices,IUnknown) DWORD* pdwHeight) PURE; }; +#undef INTERFACE #ifdef COBJMACROS /*** IUnknown methods ***/ @@ -159,8 +160,6 @@ DECLARE_INTERFACE_(ITextServices,IUnknown) #define ITextServices_Release(p) (p)->lpVtbl->Release(p) #endif -#undef INTERFACE - typedef enum _TXTBACKSTYLE { TXTBACK_TRANSPARENT = 0, TXTBACK_OPAQUE @@ -180,7 +179,7 @@ enum TXTNATURALSIZE { enum TXTVIEW { TXTVIEW_ACTIVE = 0, - TXTVIEW_INACTIVE = 1 + TXTVIEW_INACTIVE = -1 }; #define TXTBIT_RICHTEXT 0x000001 @@ -361,6 +360,7 @@ DECLARE_INTERFACE_(ITextHost,IUnknown) LONG* lSelBarWidth) PURE; }; +#undef INTERFACE #ifdef COBJMACROS /*** IUnknown methods ***/ @@ -369,8 +369,80 @@ DECLARE_INTERFACE_(ITextHost,IUnknown) #define ITextHost_Release(p) (p)->lpVtbl->Release(p) #endif +/***************************************************************************** + * ITextHost2 interface + */ +#define INTERFACE ITextHost2 +DECLARE_INTERFACE_(ITextHost2,ITextHost) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)( THIS_ REFIID riid, void** ppvObject ) PURE; + STDMETHOD_(ULONG,AddRef)( THIS ) PURE; + STDMETHOD_(ULONG,Release)( THIS ) PURE; + /*** ITextHost methods ***/ + THISCALLMETHOD_(HDC,TxGetDC)( THIS ) PURE; + THISCALLMETHOD_(INT,TxReleaseDC)( THIS_ HDC hdc ) PURE; + THISCALLMETHOD_(BOOL,TxShowScrollBar)( THIS_ INT fnBar, BOOL fShow ) PURE; + THISCALLMETHOD_(BOOL,TxEnableScrollBar)( THIS_ INT fuSBFlags, INT fuArrowflags ) PURE; + THISCALLMETHOD_(BOOL,TxSetScrollRange)( THIS_ INT fnBar, LONG nMinPos, INT nMaxPos, BOOL fRedraw ) PURE; + THISCALLMETHOD_(BOOL,TxSetScrollPos)( THIS_ INT fnBar, INT nPos, BOOL fRedraw ) PURE; + THISCALLMETHOD_(void,TxInvalidateRect)( THIS_ LPCRECT prc, BOOL fMode ) PURE; + THISCALLMETHOD_(void,TxViewChange)( THIS_ BOOL fUpdate ) PURE; + THISCALLMETHOD_(BOOL,TxCreateCaret)( THIS_ HBITMAP hbmp, INT xWidth, INT yHeight ) PURE; + THISCALLMETHOD_(BOOL,TxShowCaret)( THIS_ BOOL fShow ) PURE; + THISCALLMETHOD_(BOOL,TxSetCaretPos)( THIS_ INT x, INT y ) PURE; + THISCALLMETHOD_(BOOL,TxSetTimer)( THIS_ UINT idTimer, UINT uTimeout ) PURE; + THISCALLMETHOD_(void,TxKillTimer)( THIS_ UINT idTimer ) PURE; + THISCALLMETHOD_(void,TxScrollWindowEx)( THIS_ INT dx, INT dy, LPCRECT lprcScroll, LPCRECT lprcClip, + HRGN hRgnUpdate, LPRECT lprcUpdate, UINT fuScroll ) PURE; + THISCALLMETHOD_(void,TxSetCapture)( THIS_ BOOL fCapture ) PURE; + THISCALLMETHOD_(void,TxSetFocus)( THIS ) PURE; + THISCALLMETHOD_(void,TxSetCursor)( THIS_ HCURSOR hcur, BOOL fText ) PURE; + THISCALLMETHOD_(BOOL,TxScreenToClient)( THIS_ LPPOINT lppt ) PURE; + THISCALLMETHOD_(BOOL,TxClientToScreen)( THIS_ LPPOINT lppt ) PURE; + THISCALLMETHOD_(HRESULT,TxActivate)( THIS_ LONG* plOldState ) PURE; + THISCALLMETHOD_(HRESULT,TxDeactivate)( THIS_ LONG lNewState ) PURE; + THISCALLMETHOD_(HRESULT,TxGetClientRect)( THIS_ LPRECT prc ) PURE; + THISCALLMETHOD_(HRESULT,TxGetViewInset)( THIS_ LPRECT prc ) PURE; + THISCALLMETHOD_(HRESULT,TxGetCharFormat)( THIS_ const CHARFORMATW** ppCF ) PURE; + THISCALLMETHOD_(HRESULT,TxGetParaFormat)( THIS_ const PARAFORMAT** ppPF ) PURE; + THISCALLMETHOD_(COLORREF,TxGetSysColor)( THIS_ int nIndex ) PURE; + THISCALLMETHOD_(HRESULT,TxGetBackStyle)( THIS_ TXTBACKSTYLE* pStyle ) PURE; + THISCALLMETHOD_(HRESULT,TxGetMaxLength)( THIS_ DWORD* plength ) PURE; + THISCALLMETHOD_(HRESULT,TxGetScrollBars)( THIS_ DWORD* pdwScrollBar ) PURE; + THISCALLMETHOD_(HRESULT,TxGetPasswordChar)( THIS_ WCHAR* pch ) PURE; + THISCALLMETHOD_(HRESULT,TxGetAcceleratorPos)( THIS_ LONG* pch ) PURE; + THISCALLMETHOD_(HRESULT,TxGetExtent)( THIS_ LPSIZEL lpExtent ) PURE; + THISCALLMETHOD_(HRESULT,OnTxCharFormatChange)( THIS_ const CHARFORMATW* pcf ) PURE; + THISCALLMETHOD_(HRESULT,OnTxParaFormatChange)( THIS_ const PARAFORMAT* ppf ) PURE; + THISCALLMETHOD_(HRESULT,TxGetPropertyBits)( THIS_ DWORD dwMask, DWORD* pdwBits ) PURE; + THISCALLMETHOD_(HRESULT,TxNotify)( THIS_ DWORD iNotify, void* pv ) PURE; + THISCALLMETHOD_(HIMC,TxImmGetContext)( THIS ) PURE; + THISCALLMETHOD_(void,TxImmReleaseContext)( THIS_ HIMC himc ) PURE; + THISCALLMETHOD_(HRESULT,TxGetSelectionBarWidth)( THIS_ LONG* lSelBarWidth ) PURE; + /* ITextHost2 methods */ + THISCALLMETHOD_(BOOL,TxIsDoubleClickPending)( THIS ) PURE; + THISCALLMETHOD_(HRESULT,TxGetWindow)( THIS_ HWND *hwnd ) PURE; + THISCALLMETHOD_(HRESULT,TxSetForegroundWindow)( THIS ) PURE; + THISCALLMETHOD_(HPALETTE,TxGetPalette)( THIS ) PURE; + THISCALLMETHOD_(HRESULT,TxGetEastAsianFlags)( THIS_ LONG *flags ) PURE; + THISCALLMETHOD_(HCURSOR,TxSetCursor2)( THIS_ HCURSOR cursor, BOOL text ) PURE; + THISCALLMETHOD_(void,TxFreeTextServicesNotification)( THIS ) PURE; + THISCALLMETHOD_(HRESULT,TxGetEditStyle)( THIS_ DWORD item, DWORD *data ) PURE; + THISCALLMETHOD_(HRESULT,TxGetWindowStyles)( THIS_ DWORD *style, DWORD *ex_style ) PURE; + THISCALLMETHOD_(HRESULT,TxShowDropCaret)( THIS_ BOOL show, HDC hdc, const RECT *rect ) PURE; + THISCALLMETHOD_(HRESULT,TxDestroyCaret)( THIS ) PURE; + THISCALLMETHOD_(HRESULT,TxGetHorzExtent)( THIS_ LONG *horz_extent ) PURE; +}; #undef INTERFACE +#ifdef COBJMACROS +/*** IUnknown methods ***/ +#define ITextHost2_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define ITextHost2_AddRef(p) (p)->lpVtbl->AddRef(p) +#define ITextHost2_Release(p) (p)->lpVtbl->Release(p) +#endif + HRESULT WINAPI CreateTextServices(IUnknown*,ITextHost*,IUnknown**); typedef HRESULT (WINAPI *PCreateTextServices)(IUnknown*,ITextHost*,IUnknown**); diff --git a/sdk/include/psdk/versionhelpers.h b/sdk/include/psdk/versionhelpers.h index 339a4d0cda4e2..c13a2c8f59526 100644 --- a/sdk/include/psdk/versionhelpers.h +++ b/sdk/include/psdk/versionhelpers.h @@ -145,12 +145,10 @@ IsActiveSessionCountLimited() } #ifdef __REACTOS__ +#include VERSIONHELPERAPI IsReactOS() { - // FIXME: Find a better method! - WCHAR szWinDir[MAX_PATH]; - GetWindowsDirectoryW(szWinDir, _countof(szWinDir)); - return (wcsstr(szWinDir, L"ReactOS") != NULL); + return *(UINT*)(MM_SHARED_USER_DATA_VA + PAGE_SIZE - sizeof(ULONG)) == 0x8EAC705; } #endif // __REACTOS__ diff --git a/sdk/include/psdk/winbase.h b/sdk/include/psdk/winbase.h index f5eed96465409..42f98494d7db9 100644 --- a/sdk/include/psdk/winbase.h +++ b/sdk/include/psdk/winbase.h @@ -908,11 +908,17 @@ typedef struct _CRITICAL_SECTION_DEBUG { LIST_ENTRY ProcessLocksList; DWORD EntryCount; DWORD ContentionCount; -//#ifdef __WINESRC__ //not all wine code is marked so - DWORD_PTR Spare[8/sizeof(DWORD_PTR)];/* in Wine they store a string here */ -//#else - //WORD SpareWORD; -//#endif + union + { + DWORD_PTR WineDebugString; + DWORD_PTR Spare[1]; + struct + { + DWORD Flags; + WORD CreatorBackTraceIndexHigh; + WORD SpareWORD; + }; + }; } CRITICAL_SECTION_DEBUG,*PCRITICAL_SECTION_DEBUG,*LPCRITICAL_SECTION_DEBUG; typedef struct _CRITICAL_SECTION { @@ -4123,6 +4129,7 @@ InitOnceExecuteOnce( _Inout_opt_ PVOID Parameter, _Outptr_opt_result_maybenull_ LPVOID *Context); +typedef VOID (NTAPI *PTP_WIN32_IO_CALLBACK)(PTP_CALLBACK_INSTANCE,PVOID,PVOID,ULONG,ULONG_PTR,PTP_IO); #if defined(_SLIST_HEADER_) && !defined(_NTOS_) && !defined(_NTOSP_) diff --git a/sdk/include/psdk/winber.h b/sdk/include/psdk/winber.h index 7d11d324834e2..5fef3f799bfab 100644 --- a/sdk/include/psdk/winber.h +++ b/sdk/include/psdk/winber.h @@ -8,7 +8,7 @@ http://www.watersprings.org/pub/id/draft-ietf-ldapext-ldap-c-api-05.txt Lightweight Directory Access Protocol Reference - http://msdn.microsoft.com/library/en-us/netdir/ldap/ldap_reference.asp + http://msdn.microsoft.com/library/en-us/netdir/ldap/ldap_reference.asp (DEAD_LINK) This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sdk/include/psdk/wincodec.idl b/sdk/include/psdk/wincodec.idl index c35ef755746fe..32a0f33581322 100644 --- a/sdk/include/psdk/wincodec.idl +++ b/sdk/include/psdk/wincodec.idl @@ -19,6 +19,7 @@ import "wtypes.idl"; import "propidl.idl"; import "ocidl.idl"; +import "dxgiformat.idl"; cpp_quote("#define WINCODEC_SDK_VERSION 0x0236") @@ -193,6 +194,23 @@ typedef enum WICSectionAccessLevel { WICSectionAccessLevel_FORCE_DWORD = CODEC_FORCE_DWORD } WICSectionAccessLevel; +typedef enum WICDdsDimension { + WICDdsTexture1D = 0x00000000, + WICDdsTexture2D = 0x00000001, + WICDdsTexture3D = 0x00000002, + WICDdsTextureCube = 0x00000003, + WICDDSTEXTURE_FORCE_DWORD = CODEC_FORCE_DWORD +} WICDdsDimension; + +typedef enum WICDdsAlphaMode { + WICDdsAlphaModeUnknown = 0x00000000, + WICDdsAlphaModeStraight = 0x00000001, + WICDdsAlphaModePremultiplied = 0x00000002, + WICDdsAlphaModeOpaque = 0x00000003, + WICDdsAlphaModeCustom = 0x00000004, + WICDDSALPHAMODE_FORCE_DWORD = CODEC_FORCE_DWORD +} WICDdsAlphaMode; + typedef GUID WICPixelFormatGUID; typedef REFGUID REFWICPixelFormatGUID; @@ -227,6 +245,7 @@ cpp_quote("DEFINE_GUID(GUID_WICPixelFormat32bppGrayFloat, 0x6fddc324,0x4e03,0x4b cpp_quote("DEFINE_GUID(GUID_WICPixelFormat48bppRGB, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x15);") cpp_quote("DEFINE_GUID(GUID_WICPixelFormat48bppBGR, 0xe605a384,0xb468,0x46ce,0xbb,0x2e,0x36,0xf1,0x80,0xe6,0x43,0x13);") +cpp_quote("DEFINE_GUID(GUID_WICPixelFormat64bppRGB, 0xa1182111,0x186d,0x4d42,0xbc,0x6a,0x9c,0x83,0x03,0xa8,0xdf,0xf9);") cpp_quote("DEFINE_GUID(GUID_WICPixelFormat64bppRGBA, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x16);") cpp_quote("DEFINE_GUID(GUID_WICPixelFormat64bppBGRA, 0x1562ff7c,0xd352,0x46f9,0x97,0x9e,0x42,0x97,0x6b,0x79,0x22,0x46);") cpp_quote("DEFINE_GUID(GUID_WICPixelFormat64bppPRGBA, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x17);") @@ -237,6 +256,7 @@ cpp_quote("DEFINE_GUID(GUID_WICPixelFormat32bppBGR101010, 0x6fddc324,0x4e03,0x4b cpp_quote("DEFINE_GUID(GUID_WICPixelFormat48bppRGBFixedPoint, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x12);") cpp_quote("DEFINE_GUID(GUID_WICPixelFormat48bppBGRFixedPoint, 0x49ca140e,0xcab6,0x493b,0x9d,0xdf,0x60,0x18,0x7c,0x37,0x53,0x2a);") cpp_quote("DEFINE_GUID(GUID_WICPixelFormat96bppRGBFixedPoint, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x18);") +cpp_quote("DEFINE_GUID(GUID_WICPixelFormat96bppRGBFloat, 0xe3fed78f,0xe8db,0x4acf,0x84,0xc1,0xe9,0x7f,0x61,0x36,0xb3,0x27);") cpp_quote("DEFINE_GUID(GUID_WICPixelFormat128bppRGBAFloat, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x19);") cpp_quote("DEFINE_GUID(GUID_WICPixelFormat128bppPRGBAFloat, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x1a);") cpp_quote("DEFINE_GUID(GUID_WICPixelFormat128bppRGBFloat, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x1b);") @@ -250,6 +270,7 @@ cpp_quote("DEFINE_GUID(GUID_WICPixelFormat128bppRGBAFixedPoint, 0x6fddc324,0x4e0 cpp_quote("DEFINE_GUID(GUID_WICPixelFormat128bppRGBFixedPoint, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x41);") cpp_quote("DEFINE_GUID(GUID_WICPixelFormat64bppRGBAHalf, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x3a);") +cpp_quote("DEFINE_GUID(GUID_WICPixelFormat64bppPRGBAHalf, 0x58ad26c2,0xc623,0x4d9d,0xb3,0x20,0x38,0x7e,0x49,0xf8,0xc4,0x42);") cpp_quote("DEFINE_GUID(GUID_WICPixelFormat64bppRGBHalf, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x42);") cpp_quote("DEFINE_GUID(GUID_WICPixelFormat48bppRGBHalf, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x3b);") @@ -261,6 +282,10 @@ cpp_quote("DEFINE_GUID(GUID_WICPixelFormat32bppGrayFixedPoint, 0x6fddc324,0x4e03 cpp_quote("DEFINE_GUID(GUID_WICPixelFormat32bppRGBA1010102, 0x25238d72,0xfcf9,0x4522,0xb5,0x14,0x55,0x78,0xe5,0xad,0x55,0xe0);") cpp_quote("DEFINE_GUID(GUID_WICPixelFormat32bppRGBA1010102XR, 0x00de6b9a,0xc101,0x434b,0xb5,0x02,0xd0,0x16,0x5e,0xe1,0x12,0x2c);") +cpp_quote("DEFINE_GUID(GUID_WICPixelFormat32bppR10G10B10A2, 0x604e1bb5,0x8a3c,0x4b65,0xb1,0x1c,0xbc,0x0b,0x8d,0xd7,0x5b,0x7f);") + +cpp_quote("DEFINE_GUID(GUID_WICPixelFormat32bppR10G10B10A2HDR10, 0x9c215c5d,0x1acc,0x4f0e,0xa4,0xbc,0x70,0xfb,0x3a,0xe8,0xfd,0x28);") + cpp_quote("DEFINE_GUID(GUID_WICPixelFormat64bppCMYK, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x1f);") cpp_quote("DEFINE_GUID(GUID_WICPixelFormat24bpp3Channels, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x20);") @@ -294,6 +319,15 @@ cpp_quote("DEFINE_GUID(GUID_WICPixelFormat112bpp6ChannelsAlpha, 0x6fddc324,0x4e0 cpp_quote("DEFINE_GUID(GUID_WICPixelFormat128bpp7ChannelsAlpha, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x38);") cpp_quote("DEFINE_GUID(GUID_WICPixelFormat144bpp8ChannelsAlpha, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x39);") +cpp_quote("DEFINE_GUID(GUID_WICPixelFormat8bppY, 0x91b4db54,0x2df9,0x42f0,0xb4,0x49,0x29,0x09,0xbb,0x3d,0xf8,0x8e);") +cpp_quote("DEFINE_GUID(GUID_WICPixelFormat8bppCb, 0x1339f224,0x6bfe,0x4c3e,0x93,0x02,0xe4,0xf3,0xa6,0xd0,0xca,0x2a);") +cpp_quote("DEFINE_GUID(GUID_WICPixelFormat8bppCr, 0xb8145053,0x2116,0x49f0,0x88,0x35,0xed,0x84,0x4b,0x20,0x5c,0x51);") +cpp_quote("DEFINE_GUID(GUID_WICPixelFormat16bppCbCr, 0xff95ba6e,0x11e0,0x4263,0xbb,0x45,0x01,0x72,0x1f,0x34,0x60,0xa4);") + +cpp_quote("DEFINE_GUID(GUID_WICPixelFormat16bppYQuantizedDctCoefficients, 0xa355f433,0x48e8,0x4a42,0x84,0xd8,0xe2,0xaa,0x26,0xca,0x80,0xa4);") +cpp_quote("DEFINE_GUID(GUID_WICPixelFormat16bppCbQuantizedDctCoefficients, 0xd2c4ff61,0x56a5,0x49c2,0x8b,0x5c,0x4c,0x19,0x25,0x96,0x48,0x37);") +cpp_quote("DEFINE_GUID(GUID_WICPixelFormat16bppCrQuantizedDctCoefficients, 0x2fe354f0,0x1680,0x42d8,0x92,0x31,0xe7,0x3c,0x05,0x65,0xbf,0xc1);") + typedef struct WICRect { INT X; INT Y; @@ -309,6 +343,24 @@ typedef struct WICBitmapPattern { BOOL EndOfStream; } WICBitmapPattern; +typedef struct WICDdsParameters { + UINT Width; + UINT Height; + UINT Depth; + UINT MipLevels; + UINT ArraySize; + DXGI_FORMAT DxgiFormat; + WICDdsDimension Dimension; + WICDdsAlphaMode AlphaMode; +} WICDdsParameters; + +typedef struct WICDdsFormatInfo { + DXGI_FORMAT DxgiFormat; + UINT BytesPerBlock; + UINT BlockWidth; + UINT BlockHeight; +} WICDdsFormatInfo; + typedef UINT32 WICColor; interface IWICPalette; @@ -1083,6 +1135,72 @@ interface IWICEnumMetadataItem : IUnknown [out] IWICEnumMetadataItem **ppIEnumMetadataItem); } +[ + object, + uuid(409cd537-8532-40cb-9774-e2feb2df4e9c) +] +interface IWICDdsDecoder : IUnknown +{ + HRESULT GetParameters( + [out] WICDdsParameters *parameters); + + HRESULT GetFrame( + [in] UINT arrayIndex, + [in] UINT mipLevel, + [in] UINT sliceIndex, + [out, retval] IWICBitmapFrameDecode **bitmapFrame); +}; + +[ + object, + uuid(5cacdb4c-407e-41b3-b936-d0f010cd6732) +] +interface IWICDdsEncoder : IUnknown +{ + HRESULT SetParameters( + [in] WICDdsParameters *parameters); + + HRESULT GetParameters( + [out] WICDdsParameters *parameters); + + HRESULT CreateNewFrame( + [out] IWICBitmapFrameEncode **frameEncode, + [out, optional] UINT *arrayIndex, + [out, optional] UINT *mipLevel, + [out, optional] UINT *sliceIndex); +}; + +[ + object, + uuid(3d4c0c61-18a4-41e4-bd80-481a4fc9f464) +] +interface IWICDdsFrameDecode : IUnknown +{ + HRESULT GetSizeInBlocks( + [out] UINT *widthInBlocks, + [out] UINT *heightInBlocks); + + HRESULT GetFormatInfo( + [out] WICDdsFormatInfo *formatInfo); + + HRESULT CopyBlocks( + [in, unique] const WICRect *boundsInBlocks, + [in] UINT stride, + [in] UINT bufferSize, + [out, size_is(bufferSize)] BYTE *buffer); +}; + +[ + object, + uuid(b9bd430d-28a8-41d3-a1f5-f36ee02840bf) +] +interface IWICWineDecoder : IUnknown +{ + HRESULT Initialize( + [in] IStream *stream, + [in] WICDecodeOptions options); +}; + cpp_quote("HRESULT WINAPI WICConvertBitmapSource(REFWICPixelFormatGUID dstFormat, IWICBitmapSource *pISrc, IWICBitmapSource **ppIDst);") cpp_quote("HRESULT WINAPI WICCreateBitmapFromSection(UINT width, UINT height, REFWICPixelFormatGUID format, HANDLE section, UINT stride, UINT offset, IWICBitmap **bitmap);") cpp_quote("HRESULT WINAPI WICCreateBitmapFromSectionEx(UINT width, UINT height, REFWICPixelFormatGUID format, HANDLE section, UINT stride, UINT offset, WICSectionAccessLevel access, IWICBitmap **bitmap);") @@ -1093,11 +1211,14 @@ cpp_quote("HRESULT WINAPI WICMapSchemaToName(REFGUID,LPWSTR,UINT,WCHAR *,UINT *) cpp_quote("DEFINE_GUID(CLSID_WICBmpDecoder, 0x6b462062,0x7cbf,0x400d,0x9f,0xdb,0x81,0x3d,0xd1,0x0f,0x27,0x78);") cpp_quote("DEFINE_GUID(CLSID_WICPngDecoder, 0x389ea17b,0x5078,0x4cde,0xb6,0xef,0x25,0xc1,0x51,0x75,0xc7,0x51);") +cpp_quote("DEFINE_GUID(CLSID_WICPngDecoder1, 0x389ea17b,0x5078,0x4cde,0xb6,0xef,0x25,0xc1,0x51,0x75,0xc7,0x51);") +cpp_quote("DEFINE_GUID(CLSID_WICPngDecoder2, 0xe018945b,0xaa86,0x4008,0x9b,0xd4,0x67,0x77,0xa1,0xe4,0x0c,0x11);") cpp_quote("DEFINE_GUID(CLSID_WICIcoDecoder, 0xc61bfcdf,0x2e0f,0x4aad,0xa8,0xd7,0xe0,0x6b,0xaf,0xeb,0xcd,0xfe);") cpp_quote("DEFINE_GUID(CLSID_WICJpegDecoder, 0x9456a480,0xe88b,0x43ea,0x9e,0x73,0x0b,0x2d,0x9b,0x71,0xb1,0xca);") cpp_quote("DEFINE_GUID(CLSID_WICGifDecoder, 0x381dda3c,0x9ce9,0x4834,0xa2,0x3e,0x1f,0x98,0xf8,0xfc,0x52,0xbe);") cpp_quote("DEFINE_GUID(CLSID_WICTiffDecoder, 0xb54e85d9,0xfe23,0x499f,0x8b,0x88,0x6a,0xce,0xa7,0x13,0x75,0x2b);") cpp_quote("DEFINE_GUID(CLSID_WICWmpDecoder, 0xa26cec36,0x234c,0x4950,0xae,0x16,0xe3,0x4a,0xac,0xe7,0x1d,0x0d);") +cpp_quote("DEFINE_GUID(CLSID_WICDdsDecoder, 0x9053699f,0xa341,0x429d,0x9e,0x90,0xee,0x43,0x7c,0xf8,0x0c,0x73);") cpp_quote("DEFINE_GUID(CLSID_WICBmpEncoder, 0x69be8bb4,0xd66d,0x47c8,0x86,0x5a,0xed,0x15,0x89,0x43,0x37,0x82);") cpp_quote("DEFINE_GUID(CLSID_WICPngEncoder, 0x27949969,0x876a,0x41d7,0x94,0x47,0x56,0x8f,0x6a,0x35,0xa4,0xdc);") @@ -1105,11 +1226,22 @@ cpp_quote("DEFINE_GUID(CLSID_WICJpegEncoder, 0x1a34f5c1,0x4a5a,0x46dc,0xb6,0x44, cpp_quote("DEFINE_GUID(CLSID_WICGifEncoder, 0x114f5598,0x0b22,0x40a0,0x86,0xa1,0xc8,0x3e,0xa4,0x95,0xad,0xbd);") cpp_quote("DEFINE_GUID(CLSID_WICTiffEncoder, 0x0131be10,0x2001,0x4c5f,0xa9,0xb0,0xcc,0x88,0xfa,0xb6,0x4c,0xe8);") cpp_quote("DEFINE_GUID(CLSID_WICWmpEncoder, 0xac4ce3cb,0xe1c1,0x44cd,0x82,0x15,0x5a,0x16,0x65,0x50,0x9e,0xc2);") +cpp_quote("DEFINE_GUID(CLSID_WICDdsEncoder, 0xa61dde94,0x66ce,0x4ac1,0x88,0x1b,0x71,0x68,0x05,0x88,0x89,0x5e);") +cpp_quote("DEFINE_GUID(CLSID_WICAdngDecoder, 0x981d9411,0x909e,0x42a7,0x8f,0x5d,0xa7,0x47,0xff,0x05,0x2e,0xdb);") + +cpp_quote("DEFINE_GUID(CLSID_WICJpegQualcommPhoneEncoder, 0x68ed5c62,0xf534,0x4979,0xb2,0xb3,0x68,0x6a,0x12,0xb2,0xb3,0x4c);") + +cpp_quote("DEFINE_GUID(CLSID_WICHeifDecoder, 0xe9a4a80a,0x44fe,0x4de4,0x89,0x71,0x71,0x50,0xb1,0x0a,0x51,0x99);") +cpp_quote("DEFINE_GUID(CLSID_WICHeifEncoder, 0x0dbecec1,0x9eb3,0x4860,0x9c,0x6f,0xdd,0xbe,0x86,0x63,0x45,0x75);") + +cpp_quote("DEFINE_GUID(CLSID_WICWebpDecoder, 0x7693e886,0x51c9,0x4070,0x84,0x19,0x9f,0x70,0x73,0x8e,0xc8,0xfa);") +cpp_quote("DEFINE_GUID(CLSID_WICRAWDecoder, 0x41945702,0x8302,0x44a6,0x94,0x45,0xac,0x98,0xe8,0xaf,0xa0,0x86);") cpp_quote("DEFINE_GUID(CLSID_WICDefaultFormatConverter, 0x1a3f11dc,0xb514,0x4b17,0x8c,0x5f,0x21,0x54,0x51,0x38,0x52,0xf1);") cpp_quote("DEFINE_GUID(CLSID_WICFormatConverterHighColor, 0xac75d454,0x9f37,0x48f8,0xb9,0x72,0x4e,0x19,0xbc,0x85,0x60,0x11);") cpp_quote("DEFINE_GUID(CLSID_WICFormatConverterNChannel, 0xc17cabb2,0xd4a3,0x47d7,0xa5,0x57,0x33,0x9b,0x2e,0xfb,0xd4,0xf1);") cpp_quote("DEFINE_GUID(CLSID_WICFormatConverterWMPhoto, 0x9cb5172b,0xd600,0x46ba,0xab,0x77,0x77,0xbb,0x7e,0x3a,0x00,0xd9);") +cpp_quote("DEFINE_GUID(CLSID_WICPlanarFormatConverter, 0x184132b8,0x32f8,0x4784,0x91,0x31,0xdd,0x72,0x24,0xb2,0x34,0x38);") cpp_quote("DEFINE_GUID(GUID_ContainerFormatBmp, 0x0af1d87e,0xfcfe,0x4188,0xbd,0xeb,0xa7,0x90,0x64,0x71,0xcb,0xe3);") cpp_quote("DEFINE_GUID(GUID_ContainerFormatPng, 0x1b7cfaf4,0x713f,0x473c,0xbb,0xcd,0x61,0x37,0x42,0x5f,0xae,0xaf);") @@ -1118,6 +1250,11 @@ cpp_quote("DEFINE_GUID(GUID_ContainerFormatJpeg, 0x19e4a5aa,0x5662,0x4fc5,0xa0,0 cpp_quote("DEFINE_GUID(GUID_ContainerFormatTiff, 0x163bcc30,0xe2e9,0x4f0b,0x96,0x1d,0xa3,0xe9,0xfd,0xb7,0x88,0xa3);") cpp_quote("DEFINE_GUID(GUID_ContainerFormatGif, 0x1f8a5601,0x7d4d,0x4cbd,0x9c,0x82,0x1b,0xc8,0xd4,0xee,0xb9,0xa5);") cpp_quote("DEFINE_GUID(GUID_ContainerFormatWmp, 0x57a37caa,0x367a,0x4540,0x91,0x6b,0xf1,0x83,0xc5,0x09,0x3a,0x4b);") +cpp_quote("DEFINE_GUID(GUID_ContainerFormatDds, 0x9967cb95,0x2e85,0x4ac8,0x8c,0xa2,0x83,0xd7,0xcc,0xd4,0x25,0xc9);") +cpp_quote("DEFINE_GUID(GUID_ContainerFormatAdng, 0xf3ff6d0d,0x38c0,0x41c4,0xb1,0xfe,0x1f,0x38,0x24,0xf1,0x7b,0x84);") +cpp_quote("DEFINE_GUID(GUID_ContainerFormatHeif, 0xe1e62521,0x6787,0x405b,0xa3,0x39,0x50,0x07,0x15,0xb5,0x76,0x3f);") +cpp_quote("DEFINE_GUID(GUID_ContainerFormatWebp, 0xe094b0e2,0x67f2,0x45b3,0xb0,0xea,0x11,0x53,0x37,0xca,0x7c,0xf3);") +cpp_quote("DEFINE_GUID(GUID_ContainerFormatRaw, 0xfe99ce60,0xf19c,0x433c,0xa3,0xae,0x00,0xac,0xef,0xa9,0xca,0x21);") cpp_quote("DEFINE_GUID(GUID_VendorMicrosoft, 0xf0e749ca,0xedef,0x4589,0xa7,0x3a,0xee,0x0e,0x62,0x6a,0x2a,0x2b);") cpp_quote("DEFINE_GUID(GUID_VendorMicrosoftBuiltIn, 0x257a30fd,0x6b6,0x462b,0xae,0xa4,0x63,0xf7,0xb,0x86,0xe5,0x33);") diff --git a/sdk/include/psdk/wincodecsdk.idl b/sdk/include/psdk/wincodecsdk.idl index 75492774f3163..a12ca9226d170 100644 --- a/sdk/include/psdk/wincodecsdk.idl +++ b/sdk/include/psdk/wincodecsdk.idl @@ -73,17 +73,44 @@ cpp_quote("DEFINE_GUID(GUID_MetadataFormatChunkiTXt, 0xc2bec729,0xb68,0x4b77,0xa cpp_quote("DEFINE_GUID(GUID_MetadataFormatChunkhIST, 0xc59a82da,0xdb74,0x48a4,0xbd,0x6a,0xb6,0x9c,0x49,0x31,0xef,0x95);") cpp_quote("DEFINE_GUID(GUID_MetadataFormatChunkiCCP, 0xeb4349ab,0xb685,0x450f,0x91,0xb5,0xe8,0x2,0xe8,0x92,0x53,0x6c);") cpp_quote("DEFINE_GUID(GUID_MetadataFormatChunksRGB, 0xc115fd36,0xcc6f,0x4e3f,0x83,0x63,0x52,0x4b,0x87,0xc6,0xb0,0xd9);") +cpp_quote("DEFINE_GUID(GUID_MetadataFormatDds, 0x4a064603,0x8c33,0x4e60,0x9c,0x29,0x13,0x62,0x31,0x70,0x2d,0x08);") +cpp_quote("DEFINE_GUID(GUID_MetadataFormatHeif, 0x817ef3e1,0x1288,0x45f4,0xa8,0x52,0x26,0x0d,0x9e,0x7c,0xce,0x83);") +cpp_quote("DEFINE_GUID(GUID_MetadataFormatHeifHDR, 0x568b8d8a,0x1e65,0x438c,0x89,0x68,0xd6,0x0e,0x10,0x12,0xbe,0xb9);") +cpp_quote("DEFINE_GUID(GUID_MetadataFormatWebpANIM, 0x6dc4fda6,0x78e6,0x4102,0xae,0x35,0xbc,0xfa,0x1e,0xdc,0xc7,0x8b);") +cpp_quote("DEFINE_GUID(GUID_MetadataFormatWebpANMF, 0x43c105ee,0xb93b,0x4abb,0xb0,0x03,0xa0,0x8c,0x0d,0x87,0x04,0x71);") cpp_quote("DEFINE_GUID(CLSID_WICUnknownMetadataReader, 0x699745c2,0x5066,0x4b82,0xa8,0xe3,0xd4,0x04,0x78,0xdb,0xec,0x8c);") cpp_quote("DEFINE_GUID(CLSID_WICUnknownMetadataWriter, 0xa09cca86,0x27ba,0x4f39,0x90,0x53,0x12,0x1f,0xa4,0xdc,0x08,0xfc);") +cpp_quote("DEFINE_GUID(CLSID_WICPngBkgdMetadataReader, 0x0ce7a4a6,0x03e8,0x4a60,0x9d,0x15,0x28,0x2e,0xf3,0x2e,0xe7,0xda);") +cpp_quote("DEFINE_GUID(CLSID_WICPngBkgdMetadataWriter, 0x68e3f2fd,0x31ae,0x4441,0xbb,0x6a,0xfd,0x70,0x47,0x52,0x5f,0x90);") cpp_quote("DEFINE_GUID(CLSID_WICPngChrmMetadataReader, 0xf90b5f36,0x367b,0x402a,0x9d,0xd1,0xbc,0x0f,0xd5,0x9d,0x8f,0x62);") +cpp_quote("DEFINE_GUID(CLSID_WICPngChrmMetadataWriter, 0xe23ce3eb,0x5608,0x4e83,0xbc,0xef,0x27,0xb1,0x98,0x7e,0x51,0xd7);") cpp_quote("DEFINE_GUID(CLSID_WICPngGamaMetadataReader, 0x3692ca39,0xe082,0x4350,0x9e,0x1f,0x37,0x04,0xcb,0x08,0x3c,0xd5);") +cpp_quote("DEFINE_GUID(CLSID_WICPngGamaMetadataWriter, 0xff036d13,0x5d4b,0x46dd,0xb1,0x0f,0x10,0x66,0x93,0xd9,0xfe,0x4f);") +cpp_quote("DEFINE_GUID(CLSID_WICPngHistMetadataReader, 0x877a0bb7,0xa313,0x4491,0x87,0xb5,0x2e,0x6d,0x05,0x94,0xf5,0x20);") +cpp_quote("DEFINE_GUID(CLSID_WICPngHistMetadataWriter, 0x8a03e749,0x672e,0x446e,0xbf,0x1f,0x2c,0x11,0xd2,0x33,0xb6,0xff);") +cpp_quote("DEFINE_GUID(CLSID_WICPngIccpMetadataReader, 0xf5d3e63b,0xcb0f,0x4628,0xa4,0x78,0x6d,0x82,0x44,0xbe,0x36,0xb1);") +cpp_quote("DEFINE_GUID(CLSID_WICPngIccpMetadataWriter, 0x16671e5f,0x0ce6,0x4cc4,0x97,0x68,0xe8,0x9f,0xe5,0x01,0x8a,0xde);") +cpp_quote("DEFINE_GUID(CLSID_WICPngItxtMetadataReader, 0xaabfb2fa,0x3e1e,0x4a8f,0x89,0x77,0x55,0x56,0xfb,0x94,0xea,0x23);") +cpp_quote("DEFINE_GUID(CLSID_WICPngItxtMetadataWriter, 0x31879719,0xe751,0x4df8,0x98,0x1d,0x68,0xdf,0xf6,0x77,0x04,0xed);") +cpp_quote("DEFINE_GUID(CLSID_WICPngSrgbMetadataReader, 0xfb40360c,0x547e,0x4956,0xa3,0xb9,0xd4,0x41,0x88,0x59,0xba,0x66);") +cpp_quote("DEFINE_GUID(CLSID_WICPngSrgbMetadataWriter, 0xa6ee35c6,0x87ec,0x47df,0x9f,0x22,0x1d,0x5a,0xad,0x84,0x0c,0x82);") cpp_quote("DEFINE_GUID(CLSID_WICPngTextMetadataReader, 0x4b59afcc,0xb8c3,0x408a,0xb6,0x70,0x89,0xe5,0xfa,0xb6,0xfd,0xa7);") cpp_quote("DEFINE_GUID(CLSID_WICPngTextMetadataWriter, 0xb5ebafb9,0x253e,0x4a72,0xa7,0x44,0x07,0x62,0xd2,0x68,0x56,0x83);") +cpp_quote("DEFINE_GUID(CLSID_WICPngTimeMetadataReader, 0xd94edf02,0xefe5,0x4f0d,0x85,0xc8,0xf5,0xa6,0x8b,0x30,0x00,0xb1);") +cpp_quote("DEFINE_GUID(CLSID_WICPngTimeMetadataWriter, 0x1ab78400,0xb5a3,0x4d91,0x8a,0xce,0x33,0xfc,0xd1,0x49,0x9b,0xe6);") cpp_quote("DEFINE_GUID(CLSID_WICIfdMetadataReader, 0x8f914656,0x9d0a,0x4eb2,0x90,0x19,0x0b,0xf9,0x6d,0x8a,0x9e,0xe6);") cpp_quote("DEFINE_GUID(CLSID_WICIfdMetadataWriter, 0xb1ebfc28,0xc9bd,0x47a2,0x8d,0x33,0xb9,0x48,0x76,0x97,0x77,0xa7);") cpp_quote("DEFINE_GUID(CLSID_WICExifMetadataReader, 0xd9403860,0x297f,0x4a49,0xbf,0x9b,0x77,0x89,0x81,0x50,0xa4,0x42);") cpp_quote("DEFINE_GUID(CLSID_WICExifMetadataWriter, 0xc9a14cda,0xc339,0x460b,0x90,0x78,0xd4,0xde,0xbc,0xfa,0xbe,0x91);") +cpp_quote("DEFINE_GUID(CLSID_WICXMPMetadataReader, 0x72b624df,0xae11,0x4948,0xa6,0x5c,0x35,0x1e,0xb0,0x82,0x94,0x19);") +cpp_quote("DEFINE_GUID(CLSID_WICXMPMetadataWriter, 0x1765e14e,0x1bd4,0x462e,0xb6,0xb1,0x59,0x0b,0xf1,0x26,0x2a,0xc6);") +cpp_quote("DEFINE_GUID(CLSID_WICXMPAltMetadataReader, 0xaa94dcc2,0xb8b0,0x4898,0xb8,0x35,0x00,0x0a,0xab,0xd7,0x43,0x93);") +cpp_quote("DEFINE_GUID(CLSID_WICXMPAltMetadataWriter, 0x076c2a6c,0xf78f,0x4c46,0xa7,0x23,0x35,0x83,0xe7,0x08,0x76,0xea);") +cpp_quote("DEFINE_GUID(CLSID_WICXMPBagMetadataReader, 0xe7e79a30,0x4f2c,0x4fab,0x8d,0x00,0x39,0x4f,0x2d,0x6b,0xbe,0xbe);") +cpp_quote("DEFINE_GUID(CLSID_WICXMPBagMetadataWriter, 0xed822c8c,0xd6be,0x4301,0xa6,0x31,0x0e,0x14,0x16,0xba,0xd2,0x8f);") +cpp_quote("DEFINE_GUID(CLSID_WICXMPSeqMetadataReader, 0x7f12e753,0xfc71,0x43d7,0xa5,0x1d,0x92,0xf3,0x59,0x77,0xab,0xb5);") +cpp_quote("DEFINE_GUID(CLSID_WICXMPSeqMetadataWriter, 0x6d68d1de,0xd432,0x4b0f,0x92,0x3a,0x09,0x11,0x83,0xa9,0xbd,0xa7);") cpp_quote("DEFINE_GUID(CLSID_WICXMPStructMetadataReader, 0x01b90d9a,0x8209,0x47f7,0x9c,0x52,0xe1,0x24,0x4b,0xf5,0x0c,0xed);") cpp_quote("DEFINE_GUID(CLSID_WICXMPStructMetadataWriter, 0x22c21f93,0x7ddb,0x411c,0x9b,0x17,0xc5,0xb7,0xbd,0x06,0x4a,0xbc);") cpp_quote("DEFINE_GUID(CLSID_WICLSDMetadataReader, 0x41070793,0x59e4,0x479a,0xa1,0xf7,0x95,0x4a,0xdc,0x2e,0xf5,0xfc);") @@ -96,6 +123,43 @@ cpp_quote("DEFINE_GUID(CLSID_WICAPEMetadataReader, 0x1767b93a,0xb021,0x44ea,0x92 cpp_quote("DEFINE_GUID(CLSID_WICAPEMetadataWriter, 0xbd6edfca,0x2890,0x482f,0xb2,0x33,0x8d,0x73,0x39,0xa1,0xcf,0x8d);") cpp_quote("DEFINE_GUID(CLSID_WICGifCommentMetadataReader, 0x32557d3b,0x69dc,0x4f95,0x83,0x6e,0xf5,0x97,0x2b,0x2f,0x61,0x59);") cpp_quote("DEFINE_GUID(CLSID_WICGifCommentMetadataWriter, 0xa02797fc,0xc4ae,0x418c,0xaf,0x95,0xe6,0x37,0xc7,0xea,0xd2,0xa1);") +cpp_quote("DEFINE_GUID(CLSID_WICApp0MetadataWriter, 0xf3c633a2,0x46c8,0x498e,0x8f,0xbb,0xcc,0x6f,0x72,0x1b,0xbc,0xde);") +cpp_quote("DEFINE_GUID(CLSID_WICApp0MetadataReader, 0x43324b33,0xa78f,0x480f,0x91,0x11,0x96,0x38,0xaa,0xcc,0xc8,0x32);") +cpp_quote("DEFINE_GUID(CLSID_WICApp1MetadataWriter, 0xee366069,0x1832,0x420f,0xb3,0x81,0x04,0x79,0xad,0x06,0x6f,0x19);") +cpp_quote("DEFINE_GUID(CLSID_WICApp1MetadataReader, 0xdde33513,0x774e,0x4bcd,0xae,0x79,0x02,0xf4,0xad,0xfe,0x62,0xfc);") +cpp_quote("DEFINE_GUID(CLSID_WICApp13MetadataWriter, 0x7b19a919,0xa9d6,0x49e5,0xbd,0x45,0x02,0xc3,0x4e,0x4e,0x4c,0xd5);") +cpp_quote("DEFINE_GUID(CLSID_WICApp13MetadataReader, 0xaa7e3c50,0x864c,0x4604,0xbc,0x04,0x8b,0x0b,0x76,0xe6,0x37,0xf6);") +cpp_quote("DEFINE_GUID(CLSID_WICSubIfdMetadataReader, 0x50d42f09,0xecd1,0x4b41,0xb6,0x5d,0xda,0x1f,0xda,0xa7,0x56,0x63);" ) +cpp_quote("DEFINE_GUID(CLSID_WICSubIfdMetadataWriter, 0x8ade5386,0x8e9b,0x4f4c,0xac,0xf2,0xf0,0x00,0x87,0x06,0xb2,0x38);" ) +cpp_quote("DEFINE_GUID(CLSID_WICGpsMetadataReader, 0x3697790b,0x223b,0x484e,0x99,0x25,0xc4,0x86,0x92,0x18,0xf1,0x7a);" ) +cpp_quote("DEFINE_GUID(CLSID_WICGpsMetadataWriter, 0xcb8c13e4,0x62b5,0x4c96,0xa4,0x8b,0x6b,0xa6,0xac,0xe3,0x9c,0x76);") +cpp_quote("DEFINE_GUID(CLSID_WICInteropMetadataReader, 0xb5c8b898,0x0074,0x459f,0xb7,0x00,0x86,0x0d,0x46,0x51,0xea,0x14);") +cpp_quote("DEFINE_GUID(CLSID_WICInteropMetadataWriter, 0x122ec645,0xcd7e,0x44d8,0xb1,0x86,0x2c,0x8c,0x20,0xc3,0xb5,0x0f);") +cpp_quote("DEFINE_GUID(CLSID_WICThumbnailMetadataReader, 0xfb012959,0xf4f6,0x44d7,0x9d,0x09,0xda,0xa0,0x87,0xa9,0xdb,0x57);") +cpp_quote("DEFINE_GUID(CLSID_WICThumbnailMetadataWriter, 0xd049b20c,0x5dd0,0x44fe,0xb0,0xb3,0x8f,0x92,0xc8,0xe6,0xd0,0x80);") +cpp_quote("DEFINE_GUID(CLSID_WICIPTCMetadataReader, 0x03012959,0xf4f6,0x44d7,0x9d,0x09,0xda,0xa0,0x87,0xa9,0xdb,0x57);") +cpp_quote("DEFINE_GUID(CLSID_WICIPTCMetadataWriter, 0x1249b20c,0x5dd0,0x44fe,0xb0,0xb3,0x8f,0x92,0xc8,0xe6,0xd0,0x80);") +cpp_quote("DEFINE_GUID(CLSID_WICIRBMetadataReader, 0xd4dcd3d7,0xb4c2,0x47d9,0xa6,0xbf,0xb8,0x9b,0xa3,0x96,0xa4,0xa3);") +cpp_quote("DEFINE_GUID(CLSID_WICIRBMetadataWriter, 0x5c5c1935,0x0235,0x4434,0x80,0xbc,0x25,0x1b,0xc1,0xec,0x39,0xc6);") +cpp_quote("DEFINE_GUID(CLSID_WIC8BIMIPTCMetadataReader, 0x0010668c,0x0801,0x4da6,0xa4,0xa4,0x82,0x65,0x22,0xb6,0xd2,0x8f);") +cpp_quote("DEFINE_GUID(CLSID_WIC8BIMIPTCMetadataWriter, 0x00108226,0xee41,0x44a2,0x9e,0x9c,0x4b,0xe4,0xd5,0xb1,0xd2,0xcd);") +cpp_quote("DEFINE_GUID(CLSID_WIC8BIMIPTCDigestMetadataReader, 0x02805f1e,0xd5aa,0x415b,0x82,0xc5,0x61,0xc0,0x33,0xa9,0x88,0xa6);") +cpp_quote("DEFINE_GUID(CLSID_WIC8BIMIPTCDigestMetadataWriter, 0x2db5e62b,0x0d67,0x495f,0x8f,0x9d,0xc2,0xf0,0x18,0x86,0x47,0xac);") +cpp_quote("DEFINE_GUID(CLSID_WIC8BIMResolutionInfoMetadataReader, 0x5805137a,0xe348,0x4f7c,0xb3,0xcc,0x6d,0xb9,0x96,0x5a,0x05,0x99);") +cpp_quote("DEFINE_GUID(CLSID_WIC8BIMResolutionInfoMetadataWriter, 0x4ff2fe0e,0xe74a,0x4b71,0x98,0xc4,0xab,0x7d,0xc1,0x67,0x07,0xba);") +cpp_quote("DEFINE_GUID(CLSID_WICJpegChrominanceMetadataReader, 0x50b1904b,0xf28f,0x4574,0x93,0xf4,0x0b,0xad,0xe8,0x2c,0x69,0xe9);") +cpp_quote("DEFINE_GUID(CLSID_WICJpegChrominanceMetadataWriter, 0x3ff566f0,0x6e6b,0x49d4,0x96,0xe6,0xb7,0x88,0x86,0x69,0x2c,0x62);") +cpp_quote("DEFINE_GUID(CLSID_WICJpegCommentMetadataReader, 0x9f66347c,0x60c4,0x4c4d,0xab,0x58,0xd2,0x35,0x86,0x85,0xf6,0x07);") +cpp_quote("DEFINE_GUID(CLSID_WICJpegCommentMetadataWriter, 0xe573236f,0x55b1,0x4eda,0x81,0xea,0x9f,0x65,0xdb,0x02,0x90,0xd3);") +cpp_quote("DEFINE_GUID(CLSID_WICJpegLuminanceMetadataReader, 0x356f2f88,0x05a6,0x4728,0xb9,0xa4,0x1b,0xfb,0xce,0x04,0xd8,0x38);") +cpp_quote("DEFINE_GUID(CLSID_WICJpegLuminanceMetadataWriter, 0x1d583abc,0x8a0e,0x4657,0x99,0x82,0xa3,0x80,0xca,0x58,0xfb,0x4b);") +cpp_quote("DEFINE_GUID(CLSID_WICDdsMetadataReader, 0x276c88ca,0x7533,0x4a86,0xb6,0x76,0x66,0xb3,0x60,0x80,0xd4,0x84);") +cpp_quote("DEFINE_GUID(CLSID_WICDdsMetadataWriter, 0xfd688bbd,0x31ed,0x4db7,0xa7,0x23,0x93,0x49,0x27,0xd3,0x83,0x67);") +cpp_quote("DEFINE_GUID(CLSID_WICHeifMetadataReader, 0xacddfc3f,0x85ec,0x41bc,0xbd,0xef,0x1b,0xc2,0x62,0xe4,0xdb,0x05);") +cpp_quote("DEFINE_GUID(CLSID_WICHeifMetadataWriter, 0x3ae45e79,0x40bc,0x4401,0xac,0xe5,0xdd,0x3c,0xb1,0x6e,0x6a,0xfe);") +cpp_quote("DEFINE_GUID(CLSID_WICHeifHDRMetadataReader, 0x2438de3d,0x94d9,0x4be8,0x84,0xa8,0x4d,0xe9,0x5a,0x57,0x5e,0x75);") +cpp_quote("DEFINE_GUID(CLSID_WICWebpAnimMetadataReader, 0x076f9911,0xa348,0x465c,0xa8,0x07,0xa2,0x52,0xf3,0xf2,0xd3,0xde);") +cpp_quote("DEFINE_GUID(CLSID_WICWebpAnmfMetadataReader, 0x85a10b03,0xc9f6,0x439f,0xbe,0x5e,0xc0,0xfb,0xef,0x67,0x80,0x7c);") typedef struct WICMetadataPattern { ULARGE_INTEGER Position; @@ -302,6 +366,24 @@ interface IWICPersistStream : IPersistStream [in] BOOL fClearDirty); } +[ + object, + uuid(449494bc-b468-4927-96d7-ba90d31ab505) +] +interface IWICStreamProvider : IUnknown +{ + HRESULT GetStream( + [out] IStream **stream); + + HRESULT GetPersistOptions( + [out] DWORD *options); + + HRESULT GetPreferredVendorGUID( + [out] GUID *guid); + + HRESULT RefreshStream(); +} + [ object, uuid(412d0c3a-9650-44fa-af5b-dd2a06c8e8fb) diff --git a/sdk/include/psdk/windef.h b/sdk/include/psdk/windef.h index a1f5581e3bec3..0766d6168e9f8 100644 --- a/sdk/include/psdk/windef.h +++ b/sdk/include/psdk/windef.h @@ -14,8 +14,8 @@ #pragma warning(disable:4255) #endif -#if defined(__LP64__) || (!defined(_M_AMD64) && defined(__WINESRC__)) -#if !defined(__ROS_LONG64__) +#if (defined(_LP64) || defined(__LP64__)) && !defined(_M_AMD64) +#ifndef __ROS_LONG64__ #define __ROS_LONG64__ #endif #endif @@ -166,9 +166,9 @@ typedef BOOL *LPBOOL; typedef unsigned char BYTE; typedef unsigned short WORD; #ifndef __ROS_LONG64__ - typedef unsigned long DWORD; +typedef unsigned long DWORD; #else - typedef unsigned int DWORD; +typedef unsigned int DWORD; #endif typedef float FLOAT; typedef FLOAT *PFLOAT; diff --git a/sdk/include/psdk/winldap.h b/sdk/include/psdk/winldap.h index 6d1251391d951..bfb9dc65ccd3d 100644 --- a/sdk/include/psdk/winldap.h +++ b/sdk/include/psdk/winldap.h @@ -8,7 +8,7 @@ http://www.watersprings.org/pub/id/draft-ietf-ldapext-ldap-c-api-05.txt Lightweight Directory Access Protocol Reference - http://msdn.microsoft.com/library/en-us/netdir/ldap/ldap_reference.asp + http://msdn.microsoft.com/library/en-us/netdir/ldap/ldap_reference.asp (DEAD_LINK) This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sdk/include/psdk/winsnmp.h b/sdk/include/psdk/winsnmp.h index b61cddef0572b..442c1bacc223d 100644 --- a/sdk/include/psdk/winsnmp.h +++ b/sdk/include/psdk/winsnmp.h @@ -14,7 +14,7 @@ http://www.winsnmp.com/docs/winsnmp3.htm WinSNMP Reference - http://msdn.microsoft.com/library/en-us/snmp/snmp/winsnmp_api_reference.asp + https://web.archive.org/web/20041127132734/http://msdn.microsoft.com/library/en-us/snmp/snmp/winsnmp_api_reference.asp This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sdk/include/psdk/winsock.h b/sdk/include/psdk/winsock.h index 0d95be1e49e8e..cad1913fc81c4 100644 --- a/sdk/include/psdk/winsock.h +++ b/sdk/include/psdk/winsock.h @@ -15,8 +15,8 @@ #include #endif -#if defined(__LP64__) || (!defined(_M_AMD64) && defined(__WINESRC__)) -#if !defined(__ROS_LONG64__) +#if (defined(_LP64) || defined(__LP64__)) && !defined(_M_AMD64) +#ifndef __ROS_LONG64__ #define __ROS_LONG64__ #endif #endif diff --git a/sdk/include/psdk/winsock2.h b/sdk/include/psdk/winsock2.h index aa296a2311d0d..9646428a1549d 100644 --- a/sdk/include/psdk/winsock2.h +++ b/sdk/include/psdk/winsock2.h @@ -39,8 +39,8 @@ #endif #endif -#if defined(__LP64__) || (!defined(_M_AMD64) && defined(__WINESRC__)) -#if !defined(__ROS_LONG64__) +#if (defined(_LP64) || defined(__LP64__)) && !defined(_M_AMD64) +#ifndef __ROS_LONG64__ #define __ROS_LONG64__ #endif #endif diff --git a/sdk/include/psdk/winuser.h b/sdk/include/psdk/winuser.h index 442add4548ecc..8544d9b18f334 100644 --- a/sdk/include/psdk/winuser.h +++ b/sdk/include/psdk/winuser.h @@ -596,37 +596,45 @@ extern "C" { #ifndef NORESOURCE -#define RT_CURSOR MAKEINTRESOURCE(1) -#define RT_BITMAP MAKEINTRESOURCE(2) -#define RT_ICON MAKEINTRESOURCE(3) -#define RT_MENU MAKEINTRESOURCE(4) -#define RT_DIALOG MAKEINTRESOURCE(5) -#define RT_STRING MAKEINTRESOURCE(6) -#define RT_FONTDIR MAKEINTRESOURCE(7) -#define RT_FONT MAKEINTRESOURCE(8) -#define RT_ACCELERATOR MAKEINTRESOURCE(9) -#define RT_RCDATA MAKEINTRESOURCE(10) +/* Predefined resource types */ +#define RT_CURSOR MAKEINTRESOURCE(1) +#define RT_BITMAP MAKEINTRESOURCE(2) +#define RT_ICON MAKEINTRESOURCE(3) +#define RT_MENU MAKEINTRESOURCE(4) +#define RT_DIALOG MAKEINTRESOURCE(5) +#define RT_STRING MAKEINTRESOURCE(6) +#define RT_FONTDIR MAKEINTRESOURCE(7) +#define RT_FONT MAKEINTRESOURCE(8) +#define RT_ACCELERATOR MAKEINTRESOURCE(9) +#define RT_RCDATA MAKEINTRESOURCE(10) #define RT_MESSAGETABLE MAKEINTRESOURCE(11) #define DIFFERENCE 11 #define RT_GROUP_CURSOR MAKEINTRESOURCE((ULONG_PTR)RT_CURSOR+DIFFERENCE) -#define RT_GROUP_ICON MAKEINTRESOURCE((ULONG_PTR)RT_ICON+DIFFERENCE) -#define RT_VERSION MAKEINTRESOURCE(16) -#define RT_DLGINCLUDE MAKEINTRESOURCE(17) -#define RT_PLUGPLAY MAKEINTRESOURCE(19) -#define RT_VXD MAKEINTRESOURCE(20) -#define RT_ANICURSOR MAKEINTRESOURCE(21) -#define RT_ANIICON MAKEINTRESOURCE(22) -#define RT_HTML MAKEINTRESOURCE(23) +#define RT_GROUP_ICON MAKEINTRESOURCE((ULONG_PTR)RT_ICON+DIFFERENCE) +#define RT_VERSION MAKEINTRESOURCE(16) +#define RT_DLGINCLUDE MAKEINTRESOURCE(17) +#if (WINVER >= 0x0400) +#define RT_PLUGPLAY MAKEINTRESOURCE(19) +#define RT_VXD MAKEINTRESOURCE(20) +#define RT_ANICURSOR MAKEINTRESOURCE(21) +#define RT_ANIICON MAKEINTRESOURCE(22) +#endif /* WINVER >= 0x0400 */ +#define RT_HTML MAKEINTRESOURCE(23) + #ifndef RC_INVOKED -#define RT_MANIFEST MAKEINTRESOURCE(24) -#define CREATEPROCESS_MANIFEST_RESOURCE_ID MAKEINTRESOURCE(1) -#define ISOLATIONAWARE_MANIFEST_RESOURCE_ID MAKEINTRESOURCE(2) +#define RT_MANIFEST MAKEINTRESOURCE(24) +#define CREATEPROCESS_MANIFEST_RESOURCE_ID MAKEINTRESOURCE(1) +#define ISOLATIONAWARE_MANIFEST_RESOURCE_ID MAKEINTRESOURCE(2) #define ISOLATIONAWARE_NOSTATICIMPORT_MANIFEST_RESOURCE_ID MAKEINTRESOURCE(3) +#define MINIMUM_RESERVED_MANIFEST_RESOURCE_ID MAKEINTRESOURCE(1) /* inclusive */ +#define MAXIMUM_RESERVED_MANIFEST_RESOURCE_ID MAKEINTRESOURCE(16) /* inclusive */ #else -#define RT_MANIFEST 24 -#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1 -#define ISOLATIONAWARE_MANIFEST_RESOURCE_ID 2 +#define RT_MANIFEST 24 +#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1 +#define ISOLATIONAWARE_MANIFEST_RESOURCE_ID 2 #define ISOLATIONAWARE_NOSTATICIMPORT_MANIFEST_RESOURCE_ID 3 +#define MINIMUM_RESERVED_MANIFEST_RESOURCE_ID 1 /* inclusive */ +#define MAXIMUM_RESERVED_MANIFEST_RESOURCE_ID 16 /* inclusive */ #endif /* !RC_INVOKED */ #endif /* !NORESOURCE */ diff --git a/sdk/include/psdk/winuser.rh b/sdk/include/psdk/winuser.rh index d7ffcaf91e81a..0e660a0c58836 100644 --- a/sdk/include/psdk/winuser.rh +++ b/sdk/include/psdk/winuser.rh @@ -34,8 +34,8 @@ #define CREATEPROCESS_MANIFEST_RESOURCE_ID MAKEINTRESOURCE(1) #define ISOLATIONAWARE_MANIFEST_RESOURCE_ID MAKEINTRESOURCE(2) #define ISOLATIONAWARE_NOSTATICIMPORT_MANIFEST_RESOURCE_ID MAKEINTRESOURCE(3) -#define MINIMUM_RESERVED_MANIFEST_RESOURCE_ID MAKEINTRESOURCE(1) -#define MAXIMUM_RESERVED_MANIFEST_RESOURCE_ID MAKEINTRESOURCE(16) +#define MINIMUM_RESERVED_MANIFEST_RESOURCE_ID MAKEINTRESOURCE(1) /* inclusive */ +#define MAXIMUM_RESERVED_MANIFEST_RESOURCE_ID MAKEINTRESOURCE(16) /* inclusive */ /*** ShowWindow() codes ***/ diff --git a/sdk/include/psdk/wlanapi.h b/sdk/include/psdk/wlanapi.h index e16089372a871..64c0a32ff3ed3 100644 --- a/sdk/include/psdk/wlanapi.h +++ b/sdk/include/psdk/wlanapi.h @@ -29,8 +29,22 @@ extern "C" { #define WLAN_AVAILABLE_NETWORK_HOTSPOT2_ROAMING 0x00000080 #define WLAN_AVAILABLE_NETWORK_AUTO_CONNECT_FAILED 0x00000100 +#define WLAN_READ_ACCESS (STANDARD_RIGHTS_READ | FILE_READ_DATA) +#define WLAN_EXECUTE_ACCESS (STANDARD_RIGHTS_EXECUTE | FILE_EXECUTE | WLAN_READ_ACCESS) +#define WLAN_WRITE_ACCESS (STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA | DELETE | WRITE_DAC | WLAN_READ_ACCESS | WLAN_EXECUTE_ACCESS) + /* Enumerations */ +#if defined(__midl) || defined(__WIDL__) +typedef [v1_enum] enum _DOT11_RADIO_STATE { +#else +typedef enum _DOT11_RADIO_STATE { +#endif + dot11_radio_state_unknown = 0, + dot11_radio_state_on, + dot11_radio_state_off +} DOT11_RADIO_STATE; /* HACK: WIDL is broken, *PDOT11_RADIO_STATE; */ + #if defined(__midl) || defined(__WIDL__) typedef [v1_enum] enum _WLAN_OPCODE_VALUE_TYPE { #else @@ -175,6 +189,17 @@ typedef struct _WLAN_INTERFACE_CAPABILITY { /* enum32 */ long dot11PhyTypes[WLAN_MAX_PHY_INDEX]; } WLAN_INTERFACE_CAPABILITY, *PWLAN_INTERFACE_CAPABILITY; +typedef struct _WLAN_PHY_RADIO_STATE { + DWORD dwPhyIndex; + DOT11_RADIO_STATE dot11SoftwareRadioState; + DOT11_RADIO_STATE dot11HardwareRadioState; +} WLAN_PHY_RADIO_STATE, *PWLAN_PHY_RADIO_STATE; + +typedef struct _WLAN_RADIO_STATE { + DWORD dwNumberOfPhys; + WLAN_PHY_RADIO_STATE PhyRadioState[WLAN_MAX_PHY_INDEX]; +} WLAN_RADIO_STATE, *PWLAN_RADIO_STATE; + typedef struct _WLAN_RAW_DATA { DWORD dwDataSize; #if defined(__midl) || defined(__WIDL__) diff --git a/sdk/include/reactos/browseui_undoc.h b/sdk/include/reactos/browseui_undoc.h index 027ef4a097772..f8e75a3ac1515 100644 --- a/sdk/include/reactos/browseui_undoc.h +++ b/sdk/include/reactos/browseui_undoc.h @@ -25,6 +25,7 @@ extern "C" { #endif /* defined(__cplusplus) */ +#define FCW_MENU 7 #define FCW_ADDRESSBAR 9 // GetControlWindow/IsControlWindowShown // Name is IETHREADPARAM according to symbols / mangled function names diff --git a/sdk/include/reactos/comctl32_undoc.h b/sdk/include/reactos/comctl32_undoc.h index 1a36f4267f83d..4b48e4ad5c448 100644 --- a/sdk/include/reactos/comctl32_undoc.h +++ b/sdk/include/reactos/comctl32_undoc.h @@ -140,6 +140,14 @@ typedef INT (WINAPI *FN_FreeMRUList)(HANDLE); // #define GET_PROC(hComCtl32, fn) fn = (FN_##fn)GetProcAddress((hComCtl32), (LPSTR)I_##fn) +#ifndef NOIMAGEAPIS + +#define ILC_SYSTEM 0x0100 /* Used by the shell system image lists */ +DWORD WINAPI ImageList_GetFlags(HIMAGELIST himl); +BOOL WINAPI ImageList_SetFlags(HIMAGELIST himl, DWORD flags); + +#endif /* NOIMAGEAPIS */ + #ifdef __cplusplus } /* extern "C" */ #endif /* defined(__cplusplus) */ diff --git a/sdk/include/reactos/drivers/acpi/acpi.h b/sdk/include/reactos/drivers/acpi/acpi.h index fc4acff699b96..078145b461d31 100644 --- a/sdk/include/reactos/drivers/acpi/acpi.h +++ b/sdk/include/reactos/drivers/acpi/acpi.h @@ -79,20 +79,23 @@ typedef struct _GEN_ADDR // typedef struct _RSDP { + // ACPI v1.0 (Rev=0) ULONGLONG Signature; UCHAR Checksum; UCHAR OEMID[6]; - UCHAR Revision; + UCHAR Revision; // Was reserved before ACPI v2.0 (Rev=2). ULONG RsdtAddress; + // ACPI v2.0 (Rev=2) ULONG Length; PHYSICAL_ADDRESS XsdtAddress; UCHAR XChecksum; - UCHAR Reserved[3]; + UCHAR Reserved33[3]; } RSDP; typedef RSDP *PRSDP; typedef struct _DESCRIPTION_HEADER { + // ACPI v1.0 ULONG Signature; ULONG Length; UCHAR Revision; @@ -107,24 +110,28 @@ typedef DESCRIPTION_HEADER *PDESCRIPTION_HEADER; typedef struct _FACS { + // ACPI v1.0 (Ver=0) ULONG Signature; ULONG Length; ULONG HardwareSignature; ULONG pFirmwareWakingVector; ULONG GlobalLock; ULONG Flags; - PHYSICAL_ADDRESS x_FirmwareWakingVector; - UCHAR version; - UCHAR Reserved[32]; + PHYSICAL_ADDRESS x_FirmwareWakingVector; // Was reserved before ACPI v2.0 (Ver=1). + UCHAR Version; // Was reserved before ACPI v2.0 (Ver=1). + UCHAR Reserved33[3]; + ULONG OsFlags; // Was reserved before ACPI v4.0 (Ver=2). + UCHAR Reserved40[24]; } FACS; typedef FACS *PFACS; typedef struct _FADT { + // ACPI v1.0 (H.Rev=1) DESCRIPTION_HEADER Header; ULONG facs; ULONG dsdt; - UCHAR int_model; + UCHAR reserved44[1]; // Was int_model before ACPI v2.0. UCHAR pm_profile; USHORT sci_int_vector; ULONG smi_cmd_io_port; @@ -158,11 +165,13 @@ typedef struct _FADT UCHAR month_alarm_index; UCHAR century_alarm_index; USHORT boot_arch; - UCHAR reserved3[1]; + UCHAR reserved111[1]; ULONG flags; + // ACPI v1.5 (H.Rev=3) GEN_ADDR reset_reg; UCHAR reset_val; - UCHAR reserved4[3]; + USHORT arm_boot_arch; // Was reserved before ACPI v5.1. + UCHAR minor_revision; // Was reserved before ACPI v5.1. PHYSICAL_ADDRESS x_firmware_ctrl; PHYSICAL_ADDRESS x_dsdt; GEN_ADDR x_pm1a_evt_blk; @@ -173,6 +182,11 @@ typedef struct _FADT GEN_ADDR x_pm_tmr_blk; GEN_ADDR x_gp0_blk; GEN_ADDR x_gp1_blk; + // ACPI v5.0 (H.Rev=5) + GEN_ADDR sleep_control; + GEN_ADDR sleep_status; + // ACPI v6.0 (H.Rev=6) + ULONGLONG hypervisor_id; } FADT; typedef FADT *PFADT; @@ -185,6 +199,7 @@ typedef DSDT *PDSDT; typedef struct _RSDT { + // ACPI v1.0 (H.Rev=1) DESCRIPTION_HEADER Header; ULONG Tables[ANYSIZE_ARRAY]; } RSDT; @@ -192,6 +207,7 @@ typedef RSDT *PRSDT; typedef struct _XSDT { + // ACPI v2.0 (H.Rev=1) DESCRIPTION_HEADER Header; PHYSICAL_ADDRESS Tables[ANYSIZE_ARRAY]; } XSDT; diff --git a/sdk/include/reactos/drivers/afd/shared.h b/sdk/include/reactos/drivers/afd/shared.h index 04a2ccb1dffe0..a66ca7432e3a1 100644 --- a/sdk/include/reactos/drivers/afd/shared.h +++ b/sdk/include/reactos/drivers/afd/shared.h @@ -4,158 +4,244 @@ * FILE: include/reactos/drivers/afd/shared.h * PURPOSE: Shared definitions for AFD.SYS and MSAFD.DLL */ -#ifndef __AFD_SHARED_H -#define __AFD_SHARED_H -#define AFD_MAX_EVENTS 10 -#define AFD_PACKET_COMMAND_LENGTH 15 +#if !defined(__AFD_SHARED_H) || \ + (defined(EXPLICIT_32BIT) && !defined(__AFD_SHARED_H_32)) || \ + (defined(EXPLICIT_64BIT) && !defined(__AFD_SHARED_H_64)) + +#if defined(EXPLICIT_32BIT) && !defined(__AFD_SHARED_H_32) +#define __AFD_SHARED_H_32 +#elif defined(EXPLICIT_64BIT) && !defined(__AFD_SHARED_H_64) +#define __AFD_SHARED_H_64 +#elif !defined(__AFD_SHARED_H) +#define __AFD_SHARED_H +#endif + +/* This is copied from sdk/include/ndk/peb_teb.h */ +#define PASTE2(x,y) x##y +#define PASTE(x,y) PASTE2(x,y) + +#ifdef EXPLICIT_32BIT + #define STRUCT(x) PASTE(x,32) + #define PTR(x) ULONG +#elif defined(EXPLICIT_64BIT) + #define STRUCT(x) PASTE(x,64) + #define PTR(x) ULONG64 +#else + #define STRUCT(x) x + #define PTR(x) x +#endif + +#if (defined(_WIN64) && !defined(EXPLICIT_32BIT)) || defined(EXPLICIT_64BIT) + #define _STRUCT64 + #define _SELECT3264(x32, x64) (x64) +#else + #undef _STRUCT64 + #define _SELECT3264(x32, x64) (x32) +#endif + +#define AFD_MAX_EVENTS 10 +#define AFD_PACKET_COMMAND_LENGTH 15 #define AfdCommand "AfdOpenPacketXX" /* Extra definition of WSABUF for AFD so that I don't have to include any * userland winsock headers. */ -typedef struct _AFD_WSABUF { - UINT len; - PCHAR buf; -} AFD_WSABUF, *PAFD_WSABUF; - -typedef struct _AFD_CREATE_PACKET { - DWORD EndpointFlags; - DWORD GroupID; - DWORD SizeOfTransportName; - WCHAR TransportName[1]; -} AFD_CREATE_PACKET, *PAFD_CREATE_PACKET; - -typedef struct _AFD_INFO { - ULONG InformationClass; - union { - ULONG Ulong; - LARGE_INTEGER LargeInteger; - BOOLEAN Boolean; - } Information; - ULONG Padding; -} AFD_INFO, *PAFD_INFO; - -typedef struct _AFD_BIND_DATA { - ULONG ShareType; - TRANSPORT_ADDRESS Address; -} AFD_BIND_DATA, *PAFD_BIND_DATA; - -typedef struct _AFD_LISTEN_DATA { - BOOLEAN UseSAN; - ULONG Backlog; - BOOLEAN UseDelayedAcceptance; -} AFD_LISTEN_DATA, *PAFD_LISTEN_DATA; - -typedef struct _AFD_HANDLE_ { - SOCKET Handle; - ULONG Events; - NTSTATUS Status; -} AFD_HANDLE, *PAFD_HANDLE; - -typedef struct _AFD_POLL_INFO { - LARGE_INTEGER Timeout; - ULONG HandleCount; - ULONG_PTR Exclusive; - AFD_HANDLE Handles[1]; -} AFD_POLL_INFO, *PAFD_POLL_INFO; - -typedef struct _AFD_ACCEPT_DATA { - ULONG UseSAN; - ULONG SequenceNumber; - HANDLE ListenHandle; -} AFD_ACCEPT_DATA, *PAFD_ACCEPT_DATA; - -typedef struct _AFD_RECEIVED_ACCEPT_DATA { - ULONG SequenceNumber; - TRANSPORT_ADDRESS Address; -} AFD_RECEIVED_ACCEPT_DATA, *PAFD_RECEIVED_ACCEPT_DATA; - -typedef struct _AFD_PENDING_ACCEPT_DATA { - ULONG SequenceNumber; - ULONG SizeOfData; - ULONG ReturnSize; -} AFD_PENDING_ACCEPT_DATA, *PAFD_PENDING_ACCEPT_DATA; - -typedef struct _AFD_DEFER_ACCEPT_DATA { - ULONG SequenceNumber; - BOOLEAN RejectConnection; -} AFD_DEFER_ACCEPT_DATA, *PAFD_DEFER_ACCEPT_DATA; - -typedef struct _AFD_RECV_INFO { - PAFD_WSABUF BufferArray; - ULONG BufferCount; - ULONG AfdFlags; - ULONG TdiFlags; -} AFD_RECV_INFO , *PAFD_RECV_INFO ; - -typedef struct _AFD_RECV_INFO_UDP { - PAFD_WSABUF BufferArray; - ULONG BufferCount; - ULONG AfdFlags; - ULONG TdiFlags; - PVOID Address; - PINT AddressLength; -} AFD_RECV_INFO_UDP, *PAFD_RECV_INFO_UDP; - -typedef struct _AFD_SEND_INFO { - PAFD_WSABUF BufferArray; - ULONG BufferCount; - ULONG AfdFlags; - ULONG TdiFlags; -} AFD_SEND_INFO , *PAFD_SEND_INFO ; - -typedef struct _AFD_SEND_INFO_UDP { - PAFD_WSABUF BufferArray; - ULONG BufferCount; - ULONG AfdFlags; - TDI_REQUEST_SEND_DATAGRAM TdiRequest; - TDI_CONNECTION_INFORMATION TdiConnection; -} AFD_SEND_INFO_UDP, *PAFD_SEND_INFO_UDP; +typedef struct STRUCT(_AFD_WSABUF) +{ + UINT len; + PTR(PCHAR) buf; +} STRUCT(AFD_WSABUF), *STRUCT(PAFD_WSABUF); + +typedef struct STRUCT(_AFD_CREATE_PACKET) +{ + DWORD EndpointFlags; + DWORD GroupID; + DWORD SizeOfTransportName; + WCHAR TransportName[1]; +} STRUCT(AFD_CREATE_PACKET), *STRUCT(PAFD_CREATE_PACKET); + +typedef struct STRUCT(_AFD_INFO) +{ + ULONG InformationClass; + union + { + ULONG Ulong; + LARGE_INTEGER LargeInteger; + BOOLEAN Boolean; + } Information; + ULONG Padding; +} STRUCT(AFD_INFO), *STRUCT(PAFD_INFO); + +typedef struct STRUCT(_AFD_BIND_DATA) +{ + ULONG ShareType; + TRANSPORT_ADDRESS Address; +} STRUCT(AFD_BIND_DATA), *STRUCT(PAFD_BIND_DATA); + +typedef struct STRUCT(_AFD_LISTEN_DATA) +{ + BOOLEAN UseSAN; + ULONG Backlog; + BOOLEAN UseDelayedAcceptance; +} STRUCT(AFD_LISTEN_DATA), *STRUCT(PAFD_LISTEN_DATA); + +typedef struct STRUCT(_AFD_HANDLE) +{ + PTR(SOCKET) Handle; + ULONG Events; + NTSTATUS Status; +} STRUCT(AFD_HANDLE), *STRUCT(PAFD_HANDLE); + +typedef struct STRUCT(_AFD_POLL_INFO) +{ + LARGE_INTEGER Timeout; + ULONG HandleCount; + PTR(ULONG_PTR) Exclusive; + STRUCT(AFD_HANDLE) Handles[1]; +} STRUCT(AFD_POLL_INFO), *STRUCT(PAFD_POLL_INFO); + +typedef struct STRUCT(_AFD_ACCEPT_DATA) +{ + ULONG UseSAN; + ULONG SequenceNumber; + HANDLE ListenHandle; +} STRUCT(AFD_ACCEPT_DATA), *STRUCT(PAFD_ACCEPT_DATA); + +typedef struct STRUCT(_AFD_RECEIVED_ACCEPT_DATA) +{ + ULONG SequenceNumber; + TRANSPORT_ADDRESS Address; +} STRUCT(AFD_RECEIVED_ACCEPT_DATA), *STRUCT(PAFD_RECEIVED_ACCEPT_DATA); + +typedef struct STRUCT(_AFD_PENDING_ACCEPT_DATA) +{ + ULONG SequenceNumber; + ULONG SizeOfData; + ULONG ReturnSize; +} STRUCT(AFD_PENDING_ACCEPT_DATA), *STRUCT(PAFD_PENDING_ACCEPT_DATA); + +typedef struct STRUCT(_AFD_DEFER_ACCEPT_DATA) +{ + ULONG SequenceNumber; + BOOLEAN RejectConnection; +} STRUCT(AFD_DEFER_ACCEPT_DATA), *STRUCT(PAFD_DEFER_ACCEPT_DATA); + +typedef struct STRUCT(_AFD_RECV_INFO) +{ + PTR(PAFD_WSABUF) BufferArray; + ULONG BufferCount; + ULONG AfdFlags; + ULONG TdiFlags; +} STRUCT(AFD_RECV_INFO), *STRUCT(PAFD_RECV_INFO); + +typedef struct STRUCT(_AFD_RECV_INFO_UDP) +{ + PTR(PAFD_WSABUF) BufferArray; + ULONG BufferCount; + ULONG AfdFlags; + ULONG TdiFlags; + PTR(PVOID) Address; + PTR(PINT) AddressLength; +} STRUCT(AFD_RECV_INFO_UDP), *STRUCT(PAFD_RECV_INFO_UDP); + +typedef struct STRUCT(_AFD_SEND_INFO) +{ + PTR(PAFD_WSABUF) BufferArray; + ULONG BufferCount; + ULONG AfdFlags; + ULONG TdiFlags; +} STRUCT(AFD_SEND_INFO), *STRUCT(PAFD_SEND_INFO); + +#ifdef EXPLICIT_32BIT + +typedef struct _TDI_REQUEST32 +{ + union + { + ULONG AddressHandle; + ULONG ConnectionContext; + ULONG ControlChannel; + } Handle; + ULONG RequestNotifyObject; + ULONG RequestContext; + TDI_STATUS TdiStatus; +} TDI_REQUEST32, *PTDI_REQUEST32; + +typedef struct _TDI_REQUEST_SEND_DATAGRAM32 +{ + TDI_REQUEST32 Request; + ULONG SendDatagramInformation; +} TDI_REQUEST_SEND_DATAGRAM32, *PTDI_REQUEST_SEND_DATAGRAM32; + +typedef struct _TDI_CONNECTION_INFORMATION32 +{ + LONG UserDataLength; + ULONG UserData; + LONG OptionsLength; + ULONG Options; + LONG RemoteAddressLength; + ULONG RemoteAddress; +} TDI_CONNECTION_INFORMATION32, *PTDI_CONNECTION_INFORMATION32; + +#endif + +typedef struct STRUCT(_AFD_SEND_INFO_UDP) +{ + PTR(PAFD_WSABUF) BufferArray; + ULONG BufferCount; + ULONG AfdFlags; + STRUCT(TDI_REQUEST_SEND_DATAGRAM) TdiRequest; + STRUCT(TDI_CONNECTION_INFORMATION) TdiConnection; +} STRUCT(AFD_SEND_INFO_UDP), *STRUCT(PAFD_SEND_INFO_UDP); C_ASSERT(sizeof(AFD_RECV_INFO) == sizeof(AFD_SEND_INFO)); -typedef struct _AFD_CONNECT_INFO { - BOOLEAN UseSAN; - ULONG Root; - ULONG Unknown; - TRANSPORT_ADDRESS RemoteAddress; -} AFD_CONNECT_INFO , *PAFD_CONNECT_INFO ; +typedef struct STRUCT(_AFD_CONNECT_INFO) +{ + BOOLEAN UseSAN; + ULONG Root; + ULONG Unknown; + TRANSPORT_ADDRESS RemoteAddress; +} STRUCT(AFD_CONNECT_INFO), *STRUCT(PAFD_CONNECT_INFO); -typedef struct _AFD_EVENT_SELECT_INFO { - HANDLE EventObject; - ULONG Events; -} AFD_EVENT_SELECT_INFO, *PAFD_EVENT_SELECT_INFO; +typedef struct STRUCT(_AFD_EVENT_SELECT_INFO) +{ + PTR(HANDLE) EventObject; + ULONG Events; +} STRUCT(AFD_EVENT_SELECT_INFO), *STRUCT(PAFD_EVENT_SELECT_INFO); -typedef struct _AFD_ENUM_NETWORK_EVENTS_INFO { - HANDLE Event; - ULONG PollEvents; - NTSTATUS EventStatus[AFD_MAX_EVENTS]; -} AFD_ENUM_NETWORK_EVENTS_INFO, *PAFD_ENUM_NETWORK_EVENTS_INFO; +typedef struct STRUCT(_AFD_ENUM_NETWORK_EVENTS_INFO) +{ + PTR(HANDLE) Event; + ULONG PollEvents; + NTSTATUS EventStatus[AFD_MAX_EVENTS]; +} STRUCT(AFD_ENUM_NETWORK_EVENTS_INFO), *STRUCT(PAFD_ENUM_NETWORK_EVENTS_INFO); -typedef struct _AFD_DISCONNECT_INFO { - ULONG DisconnectType; - LARGE_INTEGER Timeout; -} AFD_DISCONNECT_INFO, *PAFD_DISCONNECT_INFO; +typedef struct STRUCT(_AFD_DISCONNECT_INFO) +{ + ULONG DisconnectType; + LARGE_INTEGER Timeout; +} STRUCT(AFD_DISCONNECT_INFO), *STRUCT(PAFD_DISCONNECT_INFO); -typedef struct _AFD_VALIDATE_GROUP_DATA +typedef struct STRUCT(_AFD_VALIDATE_GROUP_DATA) { - LONG GroupId; - TRANSPORT_ADDRESS Address; -} AFD_VALIDATE_GROUP_DATA, *PAFD_VALIDATE_GROUP_DATA; + LONG GroupId; + TRANSPORT_ADDRESS Address; +} STRUCT(AFD_VALIDATE_GROUP_DATA), *STRUCT(PAFD_VALIDATE_GROUP_DATA); -typedef struct _AFD_TDI_HANDLE_DATA +typedef struct STRUCT(_AFD_TDI_HANDLE_DATA) { - HANDLE TdiAddressHandle; - HANDLE TdiConnectionHandle; -} AFD_TDI_HANDLE_DATA, *PAFD_TDI_HANDLE_DATA; + PTR(HANDLE) TdiAddressHandle; + PTR(HANDLE) TdiConnectionHandle; +} STRUCT(AFD_TDI_HANDLE_DATA), *STRUCT(PAFD_TDI_HANDLE_DATA); /* AFD Packet Endpoint Flags */ -#define AFD_ENDPOINT_CONNECTIONLESS 0x1 -#define AFD_ENDPOINT_MESSAGE_ORIENTED 0x10 -#define AFD_ENDPOINT_RAW 0x100 -#define AFD_ENDPOINT_MULTIPOINT 0x1000 -#define AFD_ENDPOINT_C_ROOT 0x10000 -#define AFD_ENDPOINT_D_ROOT 0x100000 +#define AFD_ENDPOINT_CONNECTIONLESS 0x1 +#define AFD_ENDPOINT_MESSAGE_ORIENTED 0x10 +#define AFD_ENDPOINT_RAW 0x100 +#define AFD_ENDPOINT_MULTIPOINT 0x1000 +#define AFD_ENDPOINT_C_ROOT 0x10000 +#define AFD_ENDPOINT_D_ROOT 0x100000 /* AFD TDI Query Flags */ #define AFD_ADDRESS_HANDLE 0x1L @@ -179,25 +265,25 @@ typedef struct _AFD_TDI_HANDLE_DATA #define AFD_ALL_EVENTS ((1 << AFD_MAX_EVENT) - 1) /* AFD Info Flags */ -#define AFD_INFO_INLINING_MODE 0x01L -#define AFD_INFO_BLOCKING_MODE 0x02L -#define AFD_INFO_SENDS_IN_PROGRESS 0x04L -#define AFD_INFO_RECEIVE_WINDOW_SIZE 0x06L -#define AFD_INFO_SEND_WINDOW_SIZE 0x07L -#define AFD_INFO_GROUP_ID_TYPE 0x10L +#define AFD_INFO_INLINING_MODE 0x01L +#define AFD_INFO_BLOCKING_MODE 0x02L +#define AFD_INFO_SENDS_IN_PROGRESS 0x04L +#define AFD_INFO_RECEIVE_WINDOW_SIZE 0x06L +#define AFD_INFO_SEND_WINDOW_SIZE 0x07L +#define AFD_INFO_GROUP_ID_TYPE 0x10L #define AFD_INFO_RECEIVE_CONTENT_SIZE 0x11L /* AFD Share Flags */ -#define AFD_SHARE_UNIQUE 0x0L -#define AFD_SHARE_REUSE 0x1L -#define AFD_SHARE_WILDCARD 0x2L -#define AFD_SHARE_EXCLUSIVE 0x3L +#define AFD_SHARE_UNIQUE 0x0L +#define AFD_SHARE_REUSE 0x1L +#define AFD_SHARE_WILDCARD 0x2L +#define AFD_SHARE_EXCLUSIVE 0x3L /* AFD Disconnect Flags */ -#define AFD_DISCONNECT_SEND 0x01L -#define AFD_DISCONNECT_RECV 0x02L -#define AFD_DISCONNECT_ABORT 0x04L -#define AFD_DISCONNECT_DATAGRAM 0x08L +#define AFD_DISCONNECT_SEND 0x01L +#define AFD_DISCONNECT_RECV 0x02L +#define AFD_DISCONNECT_ABORT 0x04L +#define AFD_DISCONNECT_DATAGRAM 0x08L /* AFD Event Flags */ #define AFD_EVENT_RECEIVE (1 << AFD_EVENT_RECEIVE_BIT) @@ -215,52 +301,51 @@ typedef struct _AFD_TDI_HANDLE_DATA #define AFD_EVENT_ADDRESS_LIST_CHANGE (1 << AFD_EVENT_ADDRESS_LIST_CHANGE_BIT) /* AFD SEND/RECV Flags */ -#define AFD_SKIP_FIO 0x1L -#define AFD_OVERLAPPED 0x2L -#define AFD_IMMEDIATE 0x4L +#define AFD_SKIP_FIO 0x1L +#define AFD_OVERLAPPED 0x2L +#define AFD_IMMEDIATE 0x4L /* IOCTL Generation */ -#define FSCTL_AFD_BASE FILE_DEVICE_NETWORK -#define _AFD_CONTROL_CODE(Operation,Method) \ - ((FSCTL_AFD_BASE)<<12 | (Operation<<2) | Method) +#define FSCTL_AFD_BASE FILE_DEVICE_NETWORK +#define _AFD_CONTROL_CODE(Operation, Method) ((FSCTL_AFD_BASE) << 12 | (Operation << 2) | Method) /* AFD Commands */ -#define AFD_BIND 0 -#define AFD_CONNECT 1 -#define AFD_START_LISTEN 2 -#define AFD_WAIT_FOR_LISTEN 3 -#define AFD_ACCEPT 4 -#define AFD_RECV 5 -#define AFD_RECV_DATAGRAM 6 -#define AFD_SEND 7 -#define AFD_SEND_DATAGRAM 8 -#define AFD_SELECT 9 -#define AFD_DISCONNECT 10 -#define AFD_GET_SOCK_NAME 11 +#define AFD_BIND 0 +#define AFD_CONNECT 1 +#define AFD_START_LISTEN 2 +#define AFD_WAIT_FOR_LISTEN 3 +#define AFD_ACCEPT 4 +#define AFD_RECV 5 +#define AFD_RECV_DATAGRAM 6 +#define AFD_SEND 7 +#define AFD_SEND_DATAGRAM 8 +#define AFD_SELECT 9 +#define AFD_DISCONNECT 10 +#define AFD_GET_SOCK_NAME 11 #define AFD_GET_PEER_NAME 12 -#define AFD_GET_TDI_HANDLES 13 -#define AFD_SET_INFO 14 -#define AFD_GET_CONTEXT_SIZE 15 -#define AFD_GET_CONTEXT 16 -#define AFD_SET_CONTEXT 17 -#define AFD_SET_CONNECT_DATA 18 -#define AFD_SET_CONNECT_OPTIONS 19 -#define AFD_SET_DISCONNECT_DATA 20 -#define AFD_SET_DISCONNECT_OPTIONS 21 -#define AFD_GET_CONNECT_DATA 22 -#define AFD_GET_CONNECT_OPTIONS 23 -#define AFD_GET_DISCONNECT_DATA 24 -#define AFD_GET_DISCONNECT_OPTIONS 25 +#define AFD_GET_TDI_HANDLES 13 +#define AFD_SET_INFO 14 +#define AFD_GET_CONTEXT_SIZE 15 +#define AFD_GET_CONTEXT 16 +#define AFD_SET_CONTEXT 17 +#define AFD_SET_CONNECT_DATA 18 +#define AFD_SET_CONNECT_OPTIONS 19 +#define AFD_SET_DISCONNECT_DATA 20 +#define AFD_SET_DISCONNECT_OPTIONS 21 +#define AFD_GET_CONNECT_DATA 22 +#define AFD_GET_CONNECT_OPTIONS 23 +#define AFD_GET_DISCONNECT_DATA 24 +#define AFD_GET_DISCONNECT_OPTIONS 25 #define AFD_SET_CONNECT_DATA_SIZE 26 #define AFD_SET_CONNECT_OPTIONS_SIZE 27 #define AFD_SET_DISCONNECT_DATA_SIZE 28 #define AFD_SET_DISCONNECT_OPTIONS_SIZE 29 -#define AFD_GET_INFO 30 -#define AFD_EVENT_SELECT 33 +#define AFD_GET_INFO 30 +#define AFD_EVENT_SELECT 33 #define AFD_ENUM_NETWORK_EVENTS 34 -#define AFD_DEFER_ACCEPT 35 -#define AFD_GET_PENDING_CONNECT_DATA 41 -#define AFD_VALIDATE_GROUP 42 +#define AFD_DEFER_ACCEPT 35 +#define AFD_GET_PENDING_CONNECT_DATA 41 +#define AFD_VALIDATE_GROUP 42 /* AFD IOCTLs */ @@ -337,111 +422,129 @@ typedef struct _AFD_TDI_HANDLE_DATA #define IOCTL_AFD_VALIDATE_GROUP \ _AFD_CONTROL_CODE(AFD_VALIDATE_GROUP, METHOD_NEITHER) -typedef struct _AFD_SOCKET_INFORMATION { +typedef struct STRUCT(_AFD_SOCKET_INFORMATION) +{ BOOL CommandChannel; INT AddressFamily; INT SocketType; INT Protocol; - PVOID HelperContext; + PTR(PVOID) HelperContext; DWORD NotificationEvents; - UNICODE_STRING TdiDeviceName; + STRUCT(UNICODE_STRING) TdiDeviceName; SOCKADDR Name; -} AFD_SOCKET_INFORMATION, *PAFD_SOCKET_INFORMATION; +} STRUCT(AFD_SOCKET_INFORMATION), *STRUCT(PAFD_SOCKET_INFORMATION); -typedef struct _FILE_REQUEST_BIND { +typedef struct STRUCT(_FILE_REQUEST_BIND) +{ SOCKADDR Name; -} FILE_REQUEST_BIND, *PFILE_REQUEST_BIND; +} STRUCT(FILE_REQUEST_BIND), *STRUCT(PFILE_REQUEST_BIND); -typedef struct _FILE_REPLY_BIND { +typedef struct STRUCT(_FILE_REPLY_BIND) +{ INT Status; - HANDLE TdiAddressObjectHandle; - HANDLE TdiConnectionObjectHandle; -} FILE_REPLY_BIND, *PFILE_REPLY_BIND; + PTR(HANDLE) TdiAddressObjectHandle; + PTR(HANDLE) TdiConnectionObjectHandle; +} STRUCT(FILE_REPLY_BIND), *STRUCT(PFILE_REPLY_BIND); -typedef struct _FILE_REQUEST_LISTEN { +typedef struct STRUCT(_FILE_REQUEST_LISTEN) +{ INT Backlog; -} FILE_REQUEST_LISTEN, *PFILE_REQUEST_LISTEN; +} STRUCT(FILE_REQUEST_LISTEN), *STRUCT(PFILE_REQUEST_LISTEN); -typedef struct _FILE_REPLY_LISTEN { +typedef struct STRUCT(_FILE_REPLY_LISTEN) +{ INT Status; -} FILE_REPLY_LISTEN, *PFILE_REPLY_LISTEN; +} STRUCT(FILE_REPLY_LISTEN), *STRUCT(PFILE_REPLY_LISTEN); -typedef struct _FILE_REQUEST_SENDTO { - LPWSABUF Buffers; +typedef struct STRUCT(_FILE_REQUEST_SENDTO) +{ + PTR(LPWSABUF) Buffers; DWORD BufferCount; DWORD Flags; SOCKADDR To; INT ToLen; -} FILE_REQUEST_SENDTO, *PFILE_REQUEST_SENDTO; +} STRUCT(FILE_REQUEST_SENDTO), *STRUCT(PFILE_REQUEST_SENDTO); -typedef struct _FILE_REPLY_SENDTO { +typedef struct STRUCT(_FILE_REPLY_SENDTO) +{ INT Status; DWORD NumberOfBytesSent; -} FILE_REPLY_SENDTO, *PFILE_REPLY_SENDTO; - -typedef struct _FILE_REQUEST_RECVFROM { - LPWSABUF Buffers; - DWORD BufferCount; - LPDWORD Flags; - LPSOCKADDR From; - LPINT FromLen; -} FILE_REQUEST_RECVFROM, *PFILE_REQUEST_RECVFROM; +} STRUCT(FILE_REPLY_SENDTO), *STRUCT(PFILE_REPLY_SENDTO); -typedef struct _FILE_REPLY_RECVFROM { +typedef struct STRUCT(_FILE_REQUEST_RECVFROM) +{ + PTR(LPWSABUF) Buffers; + DWORD BufferCount; + PTR(LPDWORD) Flags; + PTR(LPSOCKADDR) From; + PTR(LPINT) FromLen; +} STRUCT(FILE_REQUEST_RECVFROM), *STRUCT(PFILE_REQUEST_RECVFROM); + +typedef struct STRUCT(_FILE_REPLY_RECVFROM) +{ INT Status; DWORD NumberOfBytesRecvd; -} FILE_REPLY_RECVFROM, *PFILE_REPLY_RECVFROM; +} STRUCT(FILE_REPLY_RECVFROM), *STRUCT(PFILE_REPLY_RECVFROM); -typedef struct _FILE_REQUEST_RECV { - LPWSABUF Buffers; - DWORD BufferCount; - LPDWORD Flags; -} FILE_REQUEST_RECV, *PFILE_REQUEST_RECV; +typedef struct STRUCT(_FILE_REQUEST_RECV) +{ + PTR(LPWSABUF) Buffers; + DWORD BufferCount; + PTR(LPDWORD) Flags; +} STRUCT(FILE_REQUEST_RECV), *STRUCT(PFILE_REQUEST_RECV); -typedef struct _FILE_REPLY_RECV { +typedef struct STRUCT(_FILE_REPLY_RECV) +{ INT Status; DWORD NumberOfBytesRecvd; -} FILE_REPLY_RECV, *PFILE_REPLY_RECV; +} STRUCT(FILE_REPLY_RECV), *STRUCT(PFILE_REPLY_RECV); +typedef struct STRUCT(_FILE_REQUEST_SEND) +{ + PTR(LPWSABUF) Buffers; + DWORD BufferCount; + DWORD Flags; +} STRUCT(FILE_REQUEST_SEND), *STRUCT(PFILE_REQUEST_SEND); -typedef struct _FILE_REQUEST_SEND { - LPWSABUF Buffers; - DWORD BufferCount; - DWORD Flags; -} FILE_REQUEST_SEND, *PFILE_REQUEST_SEND; - -typedef struct _FILE_REPLY_SEND { +typedef struct STRUCT(_FILE_REPLY_SEND) +{ INT Status; DWORD NumberOfBytesSent; -} FILE_REPLY_SEND, *PFILE_REPLY_SEND; - +} STRUCT(FILE_REPLY_SEND), *STRUCT(PFILE_REPLY_SEND); -typedef struct _FILE_REQUEST_ACCEPT { - LPSOCKADDR addr; +typedef struct STRUCT(_FILE_REQUEST_ACCEPT) +{ + PTR(LPSOCKADDR) addr; INT addrlen; - LPCONDITIONPROC lpfnCondition; + PTR(LPCONDITIONPROC) lpfnCondition; DWORD dwCallbackData; -} FILE_REQUEST_ACCEPT, *PFILE_REQUEST_ACCEPT; +} STRUCT(FILE_REQUEST_ACCEPT), *STRUCT(PFILE_REQUEST_ACCEPT); -typedef struct _FILE_REPLY_ACCEPT { +typedef struct STRUCT(_FILE_REPLY_ACCEPT) +{ INT Status; INT addrlen; SOCKET Socket; -} FILE_REPLY_ACCEPT, *PFILE_REPLY_ACCEPT; +} STRUCT(FILE_REPLY_ACCEPT), *STRUCT(PFILE_REPLY_ACCEPT); - -typedef struct _FILE_REQUEST_CONNECT { - LPSOCKADDR name; +typedef struct STRUCT(_FILE_REQUEST_CONNECT) +{ + PTR(LPSOCKADDR) name; INT namelen; - LPWSABUF lpCallerData; - LPWSABUF lpCalleeData; - LPQOS lpSQOS; - LPQOS lpGQOS; -} FILE_REQUEST_CONNECT, *PFILE_REQUEST_CONNECT; + PTR(LPWSABUF) lpCallerData; + PTR(LPWSABUF) lpCalleeData; + PTR(LPQOS) lpSQOS; + PTR(LPQOS) lpGQOS; +} STRUCT(FILE_REQUEST_CONNECT), *STRUCT(PFILE_REQUEST_CONNECT); -typedef struct _FILE_REPLY_CONNECT { +typedef struct STRUCT(_FILE_REPLY_CONNECT) +{ INT Status; -} FILE_REPLY_CONNECT, *PFILE_REPLY_CONNECT; +} STRUCT(FILE_REPLY_CONNECT), *STRUCT(PFILE_REPLY_CONNECT); + +#undef STRUCT +#undef PTR +#undef _SELECT3264 #endif /*__AFD_SHARED_H */ diff --git a/sdk/include/reactos/drivers/wow64/wow64.h b/sdk/include/reactos/drivers/wow64/wow64.h new file mode 100644 index 0000000000000..2e5cd933f44de --- /dev/null +++ b/sdk/include/reactos/drivers/wow64/wow64.h @@ -0,0 +1,9 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Ancillary Function Driver + * FILE: include/reactos/drivers/afd/wow64.h + * PURPOSE: 32-bit definitions for AFD.SYS for WOW64 support + * PROGRAMMER: Marcin Jabłoński + */ + +#pragma once diff --git a/sdk/include/reactos/idl/wkssvc.idl b/sdk/include/reactos/idl/wkssvc.idl index b4cac96edd39e..6e5cce98ead7a 100644 --- a/sdk/include/reactos/idl/wkssvc.idl +++ b/sdk/include/reactos/idl/wkssvc.idl @@ -180,7 +180,7 @@ typedef struct _WKSTA_USER_INFO_1101 { [string] wchar_t *wkui1101_oth_domains; } WKSTA_USER_INFO_1101, *PWKSTA_USER_INFO_1101, *LPWKSTA_USER_INFO_1101; - +/* typedef [switch_type(unsigned long)] union _WKSTA_USER_INFO { [case(0)] LPWKSTA_USER_INFO_0 UserInfo0; @@ -188,6 +188,14 @@ typedef [switch_type(unsigned long)] union _WKSTA_USER_INFO [case(1101)] LPWKSTA_USER_INFO_1101 UserInfo1101; [default] ; } WKSTA_USER_INFO, *PWKSTA_USER_INFO, *LPWKSTA_USER_INFO; +*/ +typedef [switch_type(unsigned long)] union _WKSTA_USER_INFO +{ + [case(0)] WKSTA_USER_INFO_0 UserInfo0; + [case(1)] WKSTA_USER_INFO_1 UserInfo1; + [case(1101)] WKSTA_USER_INFO_1101 UserInfo1101; + [default] ; +} WKSTA_USER_INFO, *PWKSTA_USER_INFO, *LPWKSTA_USER_INFO; typedef struct _WKSTA_TRANSPORT_INFO_0 { @@ -303,7 +311,7 @@ typedef struct _WKSTA_USER_INFO_1_CONTAINER unsigned long EntriesRead; [size_is(EntriesRead)] LPWKSTA_USER_INFO_1 Buffer; } WKSTA_USER_INFO_1_CONTAINER, *PWKSTA_USER_INFO_1_CONTAINER, *LPWKSTA_USER_INFO_1_CONTAINER; - +/* typedef struct _WKSTA_USER_ENUM_STRUCT { unsigned long Level; @@ -314,6 +322,17 @@ typedef struct _WKSTA_USER_ENUM_STRUCT [default] ; } WkstaUserInfo; } WKSTA_USER_ENUM_STRUCT, *PWKSTA_USER_ENUM_STRUCT, *LPWKSTA_USER_ENUM_STRUCT; +*/ +typedef struct _WKSTA_USER_ENUM_STRUCT +{ + unsigned long Level; + [switch_is(Level)] union _WKSTA_USER_ENUM_UNION + { + [case(0)] WKSTA_USER_INFO_0_CONTAINER Level0; + [case(1)] WKSTA_USER_INFO_1_CONTAINER Level1; + [default] ; + } WkstaUserInfo; +} WKSTA_USER_ENUM_STRUCT, *PWKSTA_USER_ENUM_STRUCT, *LPWKSTA_USER_ENUM_STRUCT; typedef struct _WKSTA_TRANSPORT_INFO_0_CONTAINER { @@ -407,7 +426,8 @@ interface wkssvc NetrWkstaUserGetInfo( [in, string, unique] WKSSVC_IDENTIFY_HANDLE Unused, [in] unsigned long Level, - [out, switch_is(Level)] LPWKSTA_USER_INFO UserInfo); + [out, switch_is(Level)] LPWKSTA_USER_INFO *UserInfo); +// [out, switch_is(Level)] LPWKSTA_USER_INFO UserInfo); /* Function 4 */ unsigned long diff --git a/sdk/include/reactos/ishellfolder_helpers.h b/sdk/include/reactos/ishellfolder_helpers.h new file mode 100644 index 0000000000000..28591f7158964 --- /dev/null +++ b/sdk/include/reactos/ishellfolder_helpers.h @@ -0,0 +1,51 @@ +/* + * PROJECT: ReactOS header + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: SHLWAPI IShellFolder helpers + * COPYRIGHT: Copyright 2009 Andrew Hill + * Copyright 2025 Katayama Hirofumi MZ + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +/* HACK! These function names are conflicting with functions. */ +#undef IShellFolder_GetDisplayNameOf +#undef IShellFolder_ParseDisplayName +#undef IShellFolder_CompareIDs + +HRESULT WINAPI +IShellFolder_GetDisplayNameOf( + _In_ IShellFolder *psf, + _In_ LPCITEMIDLIST pidl, + _In_ SHGDNF uFlags, + _Out_ LPSTRRET lpName, + _In_ DWORD dwRetryFlags); + +/* Flags for IShellFolder_GetDisplayNameOf */ +#define SFGDNO_RETRYWITHFORPARSING 0x00000001 +#define SFGDNO_RETRYALWAYS 0x80000000 + +HRESULT WINAPI +IShellFolder_ParseDisplayName( + _In_ IShellFolder *psf, + _In_ HWND hwndOwner, + _In_ LPBC pbcReserved, + _In_ LPOLESTR lpszDisplayName, + _Out_ ULONG *pchEaten, + _Out_ PIDLIST_RELATIVE *ppidl, + _Out_ ULONG *pdwAttributes); + +EXTERN_C HRESULT WINAPI +IShellFolder_CompareIDs( + _In_ IShellFolder *psf, + _In_ LPARAM lParam, + _In_ PCUIDLIST_RELATIVE pidl1, + _In_ PCUIDLIST_RELATIVE pidl2); + +#ifdef __cplusplus +} /* extern "C" */ +#endif diff --git a/sdk/include/reactos/libs/libmpg123/compat.h b/sdk/include/reactos/libs/libmpg123/compat.h index 66c1c64b2e853..c3c109879e2b2 100644 --- a/sdk/include/reactos/libs/libmpg123/compat.h +++ b/sdk/include/reactos/libs/libmpg123/compat.h @@ -187,7 +187,7 @@ int compat_fclose(FILE* stream); * @param[out] buflen Optional parameter for length of allocated buffer. * @return status of WideCharToMultiByte conversion. * - * WideCharToMultiByte - http://msdn.microsoft.com/en-us/library/dd374130(VS.85).aspx + * WideCharToMultiByte - https://learn.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-widechartomultibyte */ int win32_wide_utf8(const wchar_t * const wptr, char **mbptr, size_t * buflen); @@ -200,7 +200,7 @@ int win32_wide_utf8(const wchar_t * const wptr, char **mbptr, size_t * buflen); * @param[out] buflen Optional parameter for length of allocated buffer. * @return status of WideCharToMultiByte conversion. * - * MultiByteToWideChar - http://msdn.microsoft.com/en-us/library/dd319072(VS.85).aspx + * MultiByteToWideChar - https://learn.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-multibytetowidechar */ int win32_utf8_wide(const char *const mbptr, wchar_t **wptr, size_t *buflen); diff --git a/sdk/include/reactos/mc/bugcodes.mc b/sdk/include/reactos/mc/bugcodes.mc index ec64c19b96a9e..90e447573794b 100644 --- a/sdk/include/reactos/mc/bugcodes.mc +++ b/sdk/include/reactos/mc/bugcodes.mc @@ -292,7 +292,7 @@ Severity=Success Facility=System SymbolicName=CREATE_DELETE_LOCK_NOT_LOCKED Language=English -The thread reaper was handed a thread to reap, but the thread's process' +CREATE_DELETE_LOCK_NOT_LOCKED . MessageId=0x15 @@ -1179,6 +1179,14 @@ Language=English WIN32K_INIT_OR_RIT_FAILURE . +MessageId=0x92 +Severity=Success +Facility=System +SymbolicName=UP_DRIVER_ON_MP_SYSTEM +Language=English +UP_DRIVER_ON_MP_SYSTEM +. + MessageId=0x93 Severity=Success Facility=System diff --git a/sdk/include/reactos/mc/errcodes.mc b/sdk/include/reactos/mc/errcodes.mc index 550e563d9f027..a74bea47dd9c0 100644 --- a/sdk/include/reactos/mc/errcodes.mc +++ b/sdk/include/reactos/mc/errcodes.mc @@ -6145,16 +6145,16 @@ Severity=Success Facility=System SymbolicName=ERROR_FAILED_DRIVER_ENTRY Language=English -The driver was not loaded because it failed it's initialization call. +The driver was not loaded because it failed its initialization call. . Language=Russian -The driver was not loaded because it failed it's initialization call. +The driver was not loaded because it failed its initialization call. . Language=Polish Sterownik nie został załadowany, ponieważ nie powiodło się wywołanie jego inicjalizacji. . Language=Romanian -The driver was not loaded because it failed it's initialization call. +The driver was not loaded because it failed its initialization call. . Language=Japanese ドライバの初期化コールに失敗したため、ドライバがロードされませんでした。 @@ -34540,16 +34540,16 @@ Severity=Success Facility=System SymbolicName=ERROR_DS_LDAP_SEND_QUEUE_FULL Language=English -The LDAP servers network send queue has filled up because the client is not processing the results of it's requests fast enough. No more requests will be processed until the client catches up. If the client does not catch up then it will be disconnected. +The LDAP servers network send queue has filled up because the client is not processing the results of its requests fast enough. No more requests will be processed until the client catches up. If the client does not catch up then it will be disconnected. . Language=Russian -The LDAP servers network send queue has filled up because the client is not processing the results of it's requests fast enough. No more requests will be processed until the client catches up. If the client does not catch up then it will be disconnected. +The LDAP servers network send queue has filled up because the client is not processing the results of its requests fast enough. No more requests will be processed until the client catches up. If the client does not catch up then it will be disconnected. . Language=Polish Kolejka odbiorcza sieci serwerów LDAP wypełniła się, ponieważ klient nie przetwarza odpowiednio szybko wyników swoich żądań. Żadne żądania nie będą przetwarzane do czasu wyrównania klienta. Jeżeli klient nie zostanie wyrównany, zostanie rozłączony. . Language=Romanian -The LDAP servers network send queue has filled up because the client is not processing the results of it's requests fast enough. No more requests will be processed until the client catches up. If the client does not catch up then it will be disconnected. +The LDAP servers network send queue has filled up because the client is not processing the results of its requests fast enough. No more requests will be processed until the client catches up. If the client does not catch up then it will be disconnected. . Language=Japanese クライアントが要求の結果を十分に速く処理できないため、LDAPサーバーのネットワーク送信キューがいっぱいになりました。クライアントが追いつくまで、これ以上のリクエストは処理されません。クライアントが追いつかない場合、クライアントは切断されます。 diff --git a/sdk/include/reactos/mc/ntstatus.mc b/sdk/include/reactos/mc/ntstatus.mc index 86c69332ae08e..0794625812cb8 100644 --- a/sdk/include/reactos/mc/ntstatus.mc +++ b/sdk/include/reactos/mc/ntstatus.mc @@ -1045,7 +1045,7 @@ Severity=Warning Facility=System SymbolicName=STATUS_DEVICE_DOOR_OPEN Language=English -The device has indicated that it's door is open. Further operations require it closed and secured. +The device has indicated that its door is open. Further operations require it closed and secured. . MessageId=0x1 @@ -4369,7 +4369,7 @@ Severity=Error Facility=System SymbolicName=STATUS_FAILED_DRIVER_ENTRY Language=English -The driver was not loaded because it failed it's initialization call. +The driver was not loaded because it failed its initialization call. . MessageId=0x366 diff --git a/sdk/include/reactos/msv1_0p.h b/sdk/include/reactos/msv1_0p.h deleted file mode 100644 index 674d5f1f5a20b..0000000000000 --- a/sdk/include/reactos/msv1_0p.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef _MSV1_0P_ -#define _MSV1_0P_ - -typedef struct _MSV1_0_ENUMUSERS_REQUEST -{ - MSV1_0_PROTOCOL_MESSAGE_TYPE MessageType; -} MSV1_0_ENUMUSERS_REQUEST, *PMSV1_0_ENUMUSERS_REQUEST; - -typedef struct _MSV1_0_ENUMUSERS_RESPONSE -{ - MSV1_0_PROTOCOL_MESSAGE_TYPE MessageType; - ULONG NumberOfLoggedOnUsers; - PLUID LogonIds; - PULONG EnumHandles; -} MSV1_0_ENUMUSERS_RESPONSE, *PMSV1_0_ENUMUSERS_RESPONSE; - -#endif /* _MSV1_0P_ */ diff --git a/sdk/include/reactos/rddm/rxgkinterface.h b/sdk/include/reactos/rddm/rxgkinterface.h new file mode 100644 index 0000000000000..48d0bffacfb81 --- /dev/null +++ b/sdk/include/reactos/rddm/rxgkinterface.h @@ -0,0 +1,410 @@ +/* + * PROJECT: ReactOS Display Driver Model + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: Dxgkrnl callbacks header + * COPYRIGHT: Copyright 2023 Justin Miller + */ + +#pragma once + +#include + +/* + * Every structure in here is shared across two or more modules and doesn't currently + * match a single Windows version/update. + * + * These structures DO have variants in Windows, I just would like to track what + * we don't match 1:1 yet. Or haven't bother attempting to do so. + */ + +/* REACTOS_WIN32K_DXGKRNL_INTERFACE function Pointers: */ + +typedef +NTSTATUS +DXGADAPTER_CREATEALLOCATION(_Inout_ D3DKMT_CREATEALLOCATION* unnamedParam1); + +typedef DXGADAPTER_CREATEALLOCATION *PDXGADAPTER_CREATEALLOCATION; + +typedef +NTSTATUS +DXGADAPTER_CHECKMONITORPOWERSTATE(_In_ const D3DKMT_CHECKMONITORPOWERSTATE* unnamedParam1); + +typedef DXGADAPTER_CHECKMONITORPOWERSTATE *PDXGADAPTER_CHECKMONITORPOWERSTATE; + +typedef +NTSTATUS +DXGADAPTER_CHECKOCCLUSION(_In_ const D3DKMT_CHECKOCCLUSION* unnamedParam1); + +typedef DXGADAPTER_CHECKOCCLUSION *PDXGADAPTER_CHECKOCCLUSION; + +typedef +NTSTATUS +DXGADAPTER_CLOSEADAPTER(_In_ const D3DKMT_CLOSEADAPTER* unnamedParam1); + +typedef DXGADAPTER_CLOSEADAPTER *PDXGADAPTER_CLOSEADAPTER; + +typedef +NTSTATUS +DXGADAPTER_CREATECONTEXT(_Inout_ const D3DKMT_CREATECONTEXT* unnamedParam1); + +typedef DXGADAPTER_CREATECONTEXT *PDXGADAPTER_CREATECONTEXT; + +typedef +NTSTATUS +DXGADAPTER_CREATEDEVICE(_Inout_ const D3DKMT_CREATEDEVICE* unnamedParam1); + +typedef DXGADAPTER_CREATEDEVICE *PDXGADAPTER_CREATEDEVICE; + +typedef +NTSTATUS +DXGADAPTER_CREATEOVERLAY(_Inout_ const D3DKMT_CREATEOVERLAY* unnamedParam1); + +typedef DXGADAPTER_CREATEOVERLAY *PDXGADAPTER_CREATEOVERLAY; + +typedef +NTSTATUS +DXGADAPTER_CREATESYNCHRONIZATIONOBJECT(_Inout_ const D3DKMT_CREATESYNCHRONIZATIONOBJECT* unnamedParam1); + +typedef DXGADAPTER_CREATESYNCHRONIZATIONOBJECT *PDXGADAPTER_CREATESYNCHRONIZATIONOBJECT; + +typedef +NTSTATUS +DXGADAPTER_DESTROYALLOCATION(_In_ const D3DKMT_DESTROYALLOCATION* unnamedParam1); + +typedef DXGADAPTER_DESTROYALLOCATION *PDXGADAPTER_DESTROYALLOCATION; + +typedef +NTSTATUS +DXGADAPTER_DESTROYCONTEXT(_In_ const D3DKMT_DESTROYCONTEXT* unnamedParam1); + +typedef DXGADAPTER_DESTROYCONTEXT *PDXGADAPTER_DESTROYCONTEXT; + +typedef +NTSTATUS +DXGADAPTER_DESTROYDEVICE(_In_ const D3DKMT_DESTROYDEVICE* unnamedParam1); + +typedef DXGADAPTER_DESTROYDEVICE *PDXGADAPTER_DESTROYDEVICE; + +typedef +NTSTATUS +DXGADAPTER_DESTROYOVERLAY(_In_ const D3DKMT_DESTROYOVERLAY* unnamedParam1); + +typedef DXGADAPTER_DESTROYOVERLAY *PDXGADAPTER_DESTROYOVERLAY; + +typedef +NTSTATUS +DXGADAPTER_DESTROYSYNCHRONIZATIONOBJECT(_In_ const D3DKMT_DESTROYSYNCHRONIZATIONOBJECT* unnamedParam1); + +typedef DXGADAPTER_DESTROYSYNCHRONIZATIONOBJECT *PDXGADAPTER_DESTROYSYNCHRONIZATIONOBJECT; + +typedef +NTSTATUS +DXGADAPTER_ESCAPE(_In_ const D3DKMT_ESCAPE* unnamedParam1); + +typedef DXGADAPTER_ESCAPE *PDXGADAPTER_ESCAPE; + +typedef +NTSTATUS +DXGADAPTER_FLIPOVERLAY(_In_ const D3DKMT_FLIPOVERLAY* unnamedParam1); + +typedef DXGADAPTER_FLIPOVERLAY *PDXGADAPTER_FLIPOVERLAY; + +typedef +NTSTATUS +DXGADAPTER_GETCONTEXTSCHEDULINGPRIORITY(_Inout_ const D3DKMT_GETCONTEXTSCHEDULINGPRIORITY* unnamedParam1); + +typedef DXGADAPTER_GETCONTEXTSCHEDULINGPRIORITY *PDXGADAPTER_GETCONTEXTSCHEDULINGPRIORITY; + +typedef +NTSTATUS +DXGADAPTER_GETDEVICESTATE(_Inout_ D3DKMT_GETDEVICESTATE* unnamedParam1); + +typedef DXGADAPTER_GETDEVICESTATE *PDXGADAPTER_GETDEVICESTATE; + +typedef +NTSTATUS +DXGADAPTER_GETDISPLAYMODELIST(_Inout_ D3DKMT_GETDISPLAYMODELIST* unnamedParam1); + +typedef DXGADAPTER_GETDISPLAYMODELIST *PDXGADAPTER_GETDISPLAYMODELIST; + +typedef +NTSTATUS +DXGADAPTER_GETMULTISAMPLEMETHODLIST(_Inout_ D3DKMT_GETMULTISAMPLEMETHODLIST* unnamedParam1); + +typedef DXGADAPTER_GETMULTISAMPLEMETHODLIST *PDXGADAPTER_GETMULTISAMPLEMETHODLIST; + +typedef +NTSTATUS +DXGADAPTER_GETRUNTIMEDATA(_Inout_ const D3DKMT_GETRUNTIMEDATA* unnamedParam1); + +typedef DXGADAPTER_GETRUNTIMEDATA *PDXGADAPTER_GETRUNTIMEDATA; + +typedef +NTSTATUS +DXGADAPTER_GETSCANLINE(_Inout_ D3DKMT_GETSCANLINE* unnamedParam1); + +typedef DXGADAPTER_GETSCANLINE *PDXGADAPTER_GETSCANLINE; + +typedef +NTSTATUS +DXGADAPTER_SIGNALSYNCHRONIZATIONOBJECT(_In_ const D3DKMT_SIGNALSYNCHRONIZATIONOBJECT* unnamedParam1); + +typedef DXGADAPTER_SIGNALSYNCHRONIZATIONOBJECT *PDXGADAPTER_SIGNALSYNCHRONIZATIONOBJECT; + +typedef +NTSTATUS +DXGADAPTER_WAITFORVERTICALBLANKEVENT(_In_ const D3DKMT_WAITFORVERTICALBLANKEVENT* unnamedParam1); + +typedef DXGADAPTER_WAITFORVERTICALBLANKEVENT *PDXGADAPTER_WAITFORVERTICALBLANKEVENT; + +typedef +NTSTATUS +DXGADAPTER_WAITFORSYNCHRONIZATIONOBJECT(_In_ const D3DKMT_WAITFORSYNCHRONIZATIONOBJECT* unnamedParam1); + +typedef DXGADAPTER_WAITFORSYNCHRONIZATIONOBJECT *PDXGADAPTER_WAITFORSYNCHRONIZATIONOBJECT; + +typedef +NTSTATUS +DXGADAPTER_SETVIDPNSOURCEOWNER(_In_ const D3DKMT_SETVIDPNSOURCEOWNER* unnamedParam1); + +typedef DXGADAPTER_SETVIDPNSOURCEOWNER *PDXGADAPTER_SETVIDPNSOURCEOWNER; + +typedef +NTSTATUS +DXGADAPTER_WAITFORIDLE(_In_ const D3DKMT_WAITFORIDLE* unnamedParam1); + +typedef DXGADAPTER_WAITFORIDLE *PDXGADAPTER_WAITFORIDLE; + +typedef +NTSTATUS +DXGADAPTER_UPDATEOVERLAY(_In_ const D3DKMT_UPDATEOVERLAY* unnamedParam1); + +typedef DXGADAPTER_UPDATEOVERLAY *PDXGADAPTER_UPDATEOVERLAY; + +typedef +NTSTATUS +DXGADAPTER_SETQUEUEDLIMIT(_In_ const D3DKMT_SETQUEUEDLIMIT* unnamedParam1); + +typedef DXGADAPTER_SETQUEUEDLIMIT *PDXGADAPTER_SETQUEUEDLIMIT; + +typedef +NTSTATUS +DXGADAPTER_SETGAMMARAMP(_In_ const D3DKMT_SETGAMMARAMP* unnamedParam1); + +typedef DXGADAPTER_SETGAMMARAMP *PDXGADAPTER_SETGAMMARAMP; + +typedef +NTSTATUS +DXGADAPTER_SETDISPLAYMODE(_In_ const D3DKMT_SETDISPLAYMODE* unnamedParam1); + +typedef DXGADAPTER_SETDISPLAYMODE *PDXGADAPTER_SETDISPLAYMODE; + +typedef +NTSTATUS +DXGADAPTER_SETDISPLAYPRIVATEDRIVERFORMAT(_In_ const D3DKMT_SETDISPLAYPRIVATEDRIVERFORMAT* unnamedParam1); + +typedef DXGADAPTER_SETDISPLAYPRIVATEDRIVERFORMAT *PDXGADAPTER_SETDISPLAYPRIVATEDRIVERFORMAT; + + +typedef +NTSTATUS +DXGADAPTER_SETGAMMARAMP(_In_ const D3DKMT_SETGAMMARAMP* unnamedParam1); + +typedef DXGADAPTER_SETGAMMARAMP *PDXGADAPTER_SETGAMMARAMP; + +typedef +NTSTATUS +DXGADAPTER_SETQUEUEDLIMIT(_In_ const D3DKMT_SETQUEUEDLIMIT* unnamedParam1); + +typedef DXGADAPTER_SETQUEUEDLIMIT *PDXGADAPTER_SETQUEUEDLIMIT; + +typedef +NTSTATUS +DXGADAPTER_SETVIDPNSOURCEOWNER(_In_ const D3DKMT_SETVIDPNSOURCEOWNER* unnamedParam1); + +typedef DXGADAPTER_SETVIDPNSOURCEOWNER *PDXGADAPTER_SETVIDPNSOURCEOWNER; + +typedef +NTSTATUS +DXGADAPTER_UNLOCK(_In_ const D3DKMT_UNLOCK* unnamedParam1); + +typedef DXGADAPTER_UNLOCK *PDXGADAPTER_UNLOCK; + +typedef +NTSTATUS +DXGADAPTER_UPDATEOVERLAY(_In_ const D3DKMT_UPDATEOVERLAY* unnamedParam1); + +typedef DXGADAPTER_UPDATEOVERLAY *PDXGADAPTER_UPDATEOVERLAY; + +typedef +NTSTATUS +DXGADAPTER_WAITFORIDLE(_In_ const D3DKMT_WAITFORIDLE* unnamedParam1); + +typedef DXGADAPTER_WAITFORIDLE *PDXGADAPTER_WAITFORIDLE; + +typedef +NTSTATUS +DXGADAPTER_WAITFORSYNCHRONIZATIONOBJECT(_In_ const D3DKMT_WAITFORSYNCHRONIZATIONOBJECT* unnamedParam1); + +typedef DXGADAPTER_WAITFORSYNCHRONIZATIONOBJECT *PDXGADAPTER_WAITFORSYNCHRONIZATIONOBJECT; + +typedef +NTSTATUS +DXGADAPTER_WAITFORVERTICALBLANKEVENT(_In_ const D3DKMT_WAITFORVERTICALBLANKEVENT* unnamedParam1); + +typedef DXGADAPTER_WAITFORVERTICALBLANKEVENT *PDXGADAPTER_WAITFORVERTICALBLANKEVENT; + +typedef +NTSTATUS +DXGADAPTER_SIGNALSYNCHRONIZATIONOBJECT(_In_ const D3DKMT_SIGNALSYNCHRONIZATIONOBJECT* unnamedParam1); + +typedef DXGADAPTER_SIGNALSYNCHRONIZATIONOBJECT *PDXGADAPTER_SIGNALSYNCHRONIZATIONOBJECT; + +typedef +NTSTATUS +DXGADAPTER_QUERYRESOURCEINFO(_Inout_ D3DKMT_QUERYRESOURCEINFO* unnamedParam1); + +typedef DXGADAPTER_QUERYRESOURCEINFO *PDXGADAPTER_QUERYRESOURCEINFO; + +typedef +NTSTATUS +DXGADAPTER_GETPRESENTHISTORY(_Inout_ D3DKMT_GETPRESENTHISTORY* unnamedParam1); + +typedef DXGADAPTER_GETPRESENTHISTORY *PDXGADAPTER_GETPRESENTHISTORY; + +typedef +NTSTATUS +DXGADAPTER_SETALLOCATIONPRIORITY(_In_ const D3DKMT_SETALLOCATIONPRIORITY* unnamedParam1); + +typedef DXGADAPTER_SETALLOCATIONPRIORITY *PDXGADAPTER_SETALLOCATIONPRIORITY; + +typedef +NTSTATUS +DXGADAPTER_INVALIDATEACTIVEVIDPN(_In_ const D3DKMT_INVALIDATEACTIVEVIDPN* unnamedParam1); + +typedef DXGADAPTER_INVALIDATEACTIVEVIDPN *PDXGADAPTER_INVALIDATEACTIVEVIDPN; + +typedef +NTSTATUS +DXGADAPTER_GETSHAREDPRIMARYHANDLE(_In_ D3DKMT_GETSHAREDPRIMARYHANDLE* unnamedParam1); + +typedef DXGADAPTER_GETSHAREDPRIMARYHANDLE *PDXGADAPTER_GETSHAREDPRIMARYHANDLE; + +typedef +NTSTATUS +DXGADAPTER_LOCK(_In_ D3DKMT_LOCK* unnamedParam1); + +typedef DXGADAPTER_LOCK *PDXGADAPTER_LOCK; + +typedef +NTSTATUS +DXGADAPTER_POLLDISPLAYCHILDREN(_In_ const D3DKMT_POLLDISPLAYCHILDREN* unnamedParam1); + +typedef DXGADAPTER_POLLDISPLAYCHILDREN *PDXGADAPTER_POLLDISPLAYCHILDREN; + +typedef +NTSTATUS +DXGADAPTER_OPENRESOURCE(_Inout_ D3DKMT_OPENRESOURCE* unnamedParam1); + +typedef DXGADAPTER_OPENRESOURCE *PDXGADAPTER_OPENRESOURCE; + +typedef +NTSTATUS +DXGADAPTER_PRESENT(_In_ D3DKMT_PRESENT* unnamedParam1); + +typedef DXGADAPTER_PRESENT *PDXGADAPTER_PRESENT; + +typedef +NTSTATUS +DXGADAPTER_QUERYADAPTERINFO(_Inout_ const D3DKMT_QUERYADAPTERINFO* unnamedParam1); + +typedef DXGADAPTER_QUERYADAPTERINFO *PDXGADAPTER_QUERYADAPTERINFO; + +typedef +NTSTATUS +DXGADAPTER_QUERYALLOCATIONRESIDENCY(_In_ const D3DKMT_QUERYALLOCATIONRESIDENCY* unnamedParam1); + +typedef DXGADAPTER_QUERYALLOCATIONRESIDENCY *PDXGADAPTER_QUERYALLOCATIONRESIDENCY; + +typedef +NTSTATUS +DXGADAPTER_QUERYSTATISTICS(_Inout_ const D3DKMT_QUERYSTATISTICS* unnamedParam1); + +typedef DXGADAPTER_QUERYSTATISTICS *PDXGADAPTER_QUERYSTATISTICS; + +typedef +NTSTATUS +DXGADAPTER_RELEASEPROCESSVIDPNSOURCEOWNERS(_In_ HANDLE unnamedParam1); + +typedef DXGADAPTER_RELEASEPROCESSVIDPNSOURCEOWNERS *PDXGADAPTER_RELEASEPROCESSVIDPNSOURCEOWNERS; + +typedef +NTSTATUS +DXGADAPTER_RENDER(_In_ D3DKMT_RENDER* unnamedParam1); + +typedef DXGADAPTER_RENDER *PDXGADAPTER_RENDER; + +typedef +NTSTATUS +DXGADAPTER_SETCONTEXTSCHEDULINGPRIORITY(_In_ const D3DKMT_SETCONTEXTSCHEDULINGPRIORITY* unnamedParam1); + +typedef DXGADAPTER_SETCONTEXTSCHEDULINGPRIORITY *PDXGADAPTER_SETCONTEXTSCHEDULINGPRIORITY; + +/* + * This structure is the callbacks list that exist between DXGKNRL and Win32k. + * This private interface is undocumented and changes with every Windows update + * that remotely touches WDDM. + * + * Reversing this isn't possible until we can throw our DxgKrnl into vista or above at runtime. + * But this cannot happen without us first supporting watchdog. + */ +typedef struct _REACTOS_WIN32K_DXGKRNL_INTERFACE +{ + PDXGADAPTER_PRESENT RxgkIntPfnPresent; + PDXGADAPTER_QUERYADAPTERINFO RxgkIntPfnQueryAdapterInfo; + PDXGADAPTER_QUERYALLOCATIONRESIDENCY RxgkIntPfnQueryAllocationResidency; + PDXGADAPTER_QUERYSTATISTICS RxgkIntPfnQueryStatistics; + PDXGADAPTER_RELEASEPROCESSVIDPNSOURCEOWNERS RxgkIntPfnReleaseProcessVidPnSourceOwners; + PDXGADAPTER_RENDER RxgkIntPfnRender; + PDXGADAPTER_SETCONTEXTSCHEDULINGPRIORITY RxgkIntPfnSetContextSchedulingPriority; + PDXGADAPTER_OPENRESOURCE RxgkIntPfnOpenResource; + PDXGADAPTER_POLLDISPLAYCHILDREN RxgkIntPfnPollDisplayChildren; + PDXGADAPTER_LOCK RxgkIntPfnLock; + PDXGADAPTER_GETSHAREDPRIMARYHANDLE RxgkIntPfnGetSharedPrimaryHandle; + PDXGADAPTER_INVALIDATEACTIVEVIDPN RxgkIntPfnInvalidateActiveVidPn; + PDXGADAPTER_SETALLOCATIONPRIORITY RxgkIntPfnSetAllocationPriority; + PDXGADAPTER_GETPRESENTHISTORY RxgkIntPfnGetPresentHistory; + PDXGADAPTER_QUERYRESOURCEINFO RxgkIntPfnQueryResourceInfo; + PDXGADAPTER_CREATEALLOCATION RxgkIntPfnCreateAllocation; + PDXGADAPTER_CHECKMONITORPOWERSTATE RxgkIntPfnCheckMonitorPowerState; + PDXGADAPTER_CHECKOCCLUSION RxgkIntPfnCheckOcclusion; + PDXGADAPTER_CLOSEADAPTER RxgkIntPfnCloseAdapter; + PDXGADAPTER_CREATECONTEXT RxgkIntPfnCreateContext; + PDXGADAPTER_CREATEDEVICE RxgkIntPfnCreateDevice; + PDXGADAPTER_CREATEOVERLAY RxgkIntPfnCreateOverlay; + PDXGADAPTER_CREATESYNCHRONIZATIONOBJECT RxgkIntPfnCreateSynchronizationObject; + PDXGADAPTER_DESTROYCONTEXT RxgkIntPfnDestroyContext; + PDXGADAPTER_DESTROYDEVICE RxgkIntPfnDestroyDevice; + PDXGADAPTER_DESTROYOVERLAY RxgkIntPfnDestroyOverlay; + PDXGADAPTER_DESTROYSYNCHRONIZATIONOBJECT RxgkIntPfnDestroySynchronizationObject; + PDXGADAPTER_ESCAPE RxgkIntPfnEscape; + PDXGADAPTER_DESTROYALLOCATION RxgkIntPfnDestroyAllocation; + PDXGADAPTER_FLIPOVERLAY RxgkIntPfnFlipOverlay; + PDXGADAPTER_GETCONTEXTSCHEDULINGPRIORITY RxgkIntPfnGetContextSchedulingPriority; + PDXGADAPTER_GETDEVICESTATE RxgkIntPfnGetDeviceState; + PDXGADAPTER_GETDISPLAYMODELIST RxgkIntPfnGetDisplayModeList; + PDXGADAPTER_GETMULTISAMPLEMETHODLIST RxgkIntPfnGetMultisampleMethodList; + PDXGADAPTER_GETRUNTIMEDATA RxgkIntPfnGetRuntimeData; + PDXGADAPTER_GETSCANLINE RxgkIntPfnGetScanLine; + PDXGADAPTER_SIGNALSYNCHRONIZATIONOBJECT RxgkIntPfnSignalSynchronizationObject; + PDXGADAPTER_WAITFORVERTICALBLANKEVENT RxgkIntPfnWaitForVerticalBlankEvent; + PDXGADAPTER_WAITFORSYNCHRONIZATIONOBJECT RxgkIntPfnWaitForSynchronizationObject; + PDXGADAPTER_SETVIDPNSOURCEOWNER RxgkIntPfnSetVidPnSourceOwner; + PDXGADAPTER_WAITFORIDLE RxgkIntPfnWaitForIdle; + PDXGADAPTER_UPDATEOVERLAY RxgkIntPfnUpdateOverlay; + PDXGADAPTER_SETQUEUEDLIMIT RxgkIntPfnSetQueuedLimit; + PDXGADAPTER_SETGAMMARAMP RxgkIntPfnSetGammaRamp; + PDXGADAPTER_SETDISPLAYMODE RxgkIntPfnSetDisplayMode; + PDXGADAPTER_SETDISPLAYPRIVATEDRIVERFORMAT RxgkIntPfnSetDisplayPrivateDriverFormat; + PDXGADAPTER_UNLOCK RxgkIntPfnUnlock; +} REACTOS_WIN32K_DXGKRNL_INTERFACE, *PREACTOS_WIN32K_DXGKRNL_INTERFACE; diff --git a/sdk/include/reactos/shdocvw_undoc.h b/sdk/include/reactos/shdocvw_undoc.h index 57e3ee8b9d705..76c8970006eea 100644 --- a/sdk/include/reactos/shdocvw_undoc.h +++ b/sdk/include/reactos/shdocvw_undoc.h @@ -2,14 +2,16 @@ * PROJECT: ReactOS Headers * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) * PURPOSE: shdocvw.dll undocumented APIs - * COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ + * COPYRIGHT: Copyright 2024-2025 Katayama Hirofumi MZ */ #pragma once +#include // For IShellWindows + #ifdef __cplusplus extern "C" { -#endif /* defined(__cplusplus) */ +#endif BOOL WINAPI IEILIsEqual( @@ -17,6 +19,38 @@ IEILIsEqual( _In_ LPCITEMIDLIST pidl2, _In_ BOOL bUnknown); +HRESULT WINAPI +AddUrlToFavorites( + _In_ HWND hwnd, + _In_opt_ LPCWSTR pszUrlW, + _In_ LPCWSTR pszTitleW, + _In_ BOOL fDisplayUI); + +BOOL WINAPI WinList_Init(VOID); +VOID WINAPI WinList_Terminate(VOID); +HRESULT WINAPI WinList_Revoke(_In_ LONG lCookie); +IShellWindows* WINAPI WinList_GetShellWindows(_In_ BOOL bCreate); + +HRESULT WINAPI +WinList_NotifyNewLocation( + _In_ IShellWindows *pShellWindows, + _In_ LONG lCookie, + _In_ LPCITEMIDLIST pidl); + +HRESULT WINAPI +WinList_FindFolderWindow( + _In_ LPCITEMIDLIST pidl, + _In_ DWORD dwUnused, + _Out_opt_ PLONG phwnd, + _Out_opt_ IWebBrowserApp **ppWebBrowserApp); + +HRESULT WINAPI +WinList_RegisterPending( + _In_ DWORD dwThreadId, + _In_ LPCITEMIDLIST pidl, + _In_ DWORD dwUnused, + _Out_ PLONG plCookie); + #ifdef __cplusplus } /* extern "C" */ -#endif /* defined(__cplusplus) */ +#endif diff --git a/sdk/include/reactos/shellutils.h b/sdk/include/reactos/shellutils.h index 756c57c9d7321..2165a6706dccc 100644 --- a/sdk/include/reactos/shellutils.h +++ b/sdk/include/reactos/shellutils.h @@ -23,7 +23,7 @@ extern "C" { #endif /* defined(__cplusplus) */ -inline ULONG +static inline ULONG Win32DbgPrint(const char *filename, int line, const char *lpFormat, ...) { char szMsg[512]; @@ -63,11 +63,11 @@ Win32DbgPrint(const char *filename, int line, const char *lpFormat, ...) # define IID_PPV_ARG(Itype, ppType) IID_##Itype, reinterpret_cast((static_cast(ppType))) # define IID_NULL_PPV_ARG(Itype, ppType) IID_##Itype, NULL, reinterpret_cast((static_cast(ppType))) #else -# define IID_PPV_ARG(Itype, ppType) IID_##Itype, (void**)(ppType) -# define IID_NULL_PPV_ARG(Itype, ppType) IID_##Itype, NULL, (void**)(ppType) +# define IID_PPV_ARG(Itype, ppType) &IID_##Itype, (void**)(ppType) +# define IID_NULL_PPV_ARG(Itype, ppType) &IID_##Itype, NULL, (void**)(ppType) #endif -inline HRESULT HResultFromWin32(DWORD hr) +static inline HRESULT HResultFromWin32(DWORD hr) { // HRESULT_FROM_WIN32 will evaluate its parameter twice, this function will not. return HRESULT_FROM_WIN32(hr); @@ -75,7 +75,7 @@ inline HRESULT HResultFromWin32(DWORD hr) #if 1 -inline BOOL _ROS_FAILED_HELPER(HRESULT hr, const char* expr, const char* filename, int line) +static inline BOOL _ROS_FAILED_HELPER(HRESULT hr, const char* expr, const char* filename, int line) { if (FAILED(hr)) { @@ -122,9 +122,12 @@ SHELL_ErrorBox(H hwndOwner, UINT Error = GetLastError()) { return SHELL_ErrorBoxHelper(const_cast(hwndOwner), Error); } +#else +#define SHELL_ErrorBox SHELL_ErrorBoxHelper #endif #ifdef __cplusplus +#ifdef DECLARE_CLASSFACTORY // ATL template class CComCreatorCentralInstance { @@ -454,6 +457,7 @@ HRESULT inline ShellObjectCreatorInit(T1 initArg1, T2 initArg2, T3 initArg3, T4 return hResult; } +#endif // DECLARE_CLASSFACTORY (ATL) template static HRESULT SHILClone(P pidl, R *ppOut) { diff --git a/sdk/include/reactos/shlguid_undoc.h b/sdk/include/reactos/shlguid_undoc.h index b72e61c9e3d34..52aad4a13fb64 100644 --- a/sdk/include/reactos/shlguid_undoc.h +++ b/sdk/include/reactos/shlguid_undoc.h @@ -161,6 +161,8 @@ DEFINE_GUID(IID_IDelegateHostItemContainer,0x02468693, 0xE7E5, 0x4C6B, 0x99, 0x9 DEFINE_GUID(IID_IDrawPropertyControl, 0xE6DFF6FD, 0xBCD5, 0x4162, 0x9C, 0x65, 0xA3, 0xB1, 0x8C, 0x61, 0x6F, 0xDB); DEFINE_GUID(IID_IEnumAssociationElements, 0xA6B0FB57, 0x7523, 0x4439, 0x94, 0x25, 0xEB, 0xE9, 0x98, 0x23, 0xB8, 0x28); DEFINE_GUID(IID_IEnumerateAssociationElements,0x7513A16E,0xCF00,0x4817,0xA8, 0x90, 0xA2, 0x3C, 0x60, 0x8F, 0xE7, 0xB7); +DEFINE_GUID(IID_IAssociationElementOld, 0xE58B1ABF, 0x9596, 0x4DBA, 0x89, 0x97, 0x89, 0xDC, 0xDE, 0xF4, 0x69, 0x92); +DEFINE_GUID(IID_IAssociationElement, 0xD8F6AD5B, 0xB44F, 0x4BCC, 0x88, 0xFD, 0xEB, 0x34, 0x73, 0xDB, 0x75, 0x02); DEFINE_GUID(IID_IFilterCondition, 0xFCA2857D, 0x1760, 0x4AD3, 0x8C, 0x63, 0xC9, 0xB6, 0x02, 0xFC, 0xBA, 0xEA); DEFINE_GUID(IID_IFolderNotify, 0x0FF22D71, 0x5172, 0x11D1, 0xA9, 0xC6, 0x08, 0x00, 0x36, 0xAF, 0x3F, 0x03); DEFINE_GUID(IID_IFolderProperties, 0x7361EE29, 0x5BAD, 0x459D, 0xA9, 0xF5, 0xF6, 0x55, 0x06, 0x89, 0x82, 0xF0); @@ -209,7 +211,6 @@ DEFINE_GUID(IID_IPinnedList, 0xBBD20037, 0xBC0E, 0x42F1, 0x91, 0x3 #define SID_STravelLogCursor IID_ITravelLogStg #define SID_IBandSite IID_IBandSite -#define SID_IFolderView IID_IFolderView #define SID_IShellBrowser IID_IShellBrowser #endif // __SHLGUID_UNDOC_H diff --git a/sdk/include/reactos/shlobj_undoc.h b/sdk/include/reactos/shlobj_undoc.h index c9796909aa14b..a8928315b559c 100644 --- a/sdk/include/reactos/shlobj_undoc.h +++ b/sdk/include/reactos/shlobj_undoc.h @@ -1,30 +1,19 @@ /* - * ReactOS undocumented shell interface - * - * Copyright 2009 Andrew Hill - * Copyright 2013 Dominik Hornung - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * PROJECT: ReactOS header + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Undocumented shell interface + * COPYRIGHT: Copyright 2009 Andrew Hill + * Copyright 2013 Dominik Hornung + * Copyright 2025 Katayama Hirofumi MZ */ -#ifndef __SHLOBJ_UNDOC__H -#define __SHLOBJ_UNDOC__H +#pragma once + +#include // For ASSOCQUERY #ifdef __cplusplus extern "C" { -#endif /* defined(__cplusplus) */ +#endif typedef struct tagSLOTITEMDATA { @@ -365,7 +354,7 @@ DECLARE_INTERFACE_(IAddressEditBox, IUnknown) STDMETHOD_(ULONG,Release)(THIS) PURE; /*** IAddressEditBox ***/ STDMETHOD(Init)(THIS_ HWND comboboxEx, HWND editControl, long param14, IUnknown *param18) PURE; - STDMETHOD(SetCurrentDir)(THIS_ long paramC) PURE; + STDMETHOD(SetCurrentDir)(THIS_ PCWSTR pszPath) PURE; STDMETHOD(ParseNow)(THIS_ long paramC) PURE; STDMETHOD(Execute)(THIS_ long paramC) PURE; STDMETHOD(Save)(THIS_ long paramC) PURE; @@ -817,12 +806,145 @@ DECLARE_INTERFACE_(ITrayPriv, IUnknown) #define ITrayPriv_AppendMenu(T,a) (T)->lpVtbl->AppendMenu(T,a) #endif +/***************************************************************************** + * IAssociationElement interface + * + * @see IAssociationElementOld + * @see https://www.geoffchappell.com/studies/windows/shell/shlwapi/interfaces/iassociationelement.htm + */ +#define INTERFACE IAssociationElement +DECLARE_INTERFACE_(IAssociationElement, IUnknown) // {D8F6AD5B-B44F-4BCC-88FD-EB3473DB7502} +{ + /*** IUnknown ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + /*** IAssociationElement ***/ + STDMETHOD(QueryString)(THIS_ ASSOCQUERY query, PCWSTR key, PWSTR *ppszValue) PURE; + STDMETHOD(QueryDword)(THIS_ ASSOCQUERY query, PCWSTR key, DWORD *pdwValue) PURE; + STDMETHOD(QueryGuid)(THIS_ ASSOCQUERY query, PCWSTR key, GUID *pguid) PURE; + STDMETHOD(QueryExists)(THIS_ ASSOCQUERY query, PCWSTR key) PURE; + STDMETHOD(QueryDirect)(THIS_ ASSOCQUERY query, PCWSTR key, FLAGGED_BYTE_BLOB **ppBlob) PURE; + STDMETHOD(QueryObject)(THIS_ ASSOCQUERY query, PCWSTR key, REFIID riid, PVOID *ppvObj) PURE; +}; +#undef INTERFACE + +#ifdef COBJMACROS +#define IAssociationElement_QueryInterface(T,a,b) (T)->lpVtbl->QueryInterface(T,a,b) +#define IAssociationElement_AddRef(T) (T)->lpVtbl->AddRef(T) +#define IAssociationElement_Release(T) (T)->lpVtbl->Release(T) +#define IAssociationElement_QueryString(T,a,b,c) (T)->lpVtbl->QueryString(T,a,b,c) +#define IAssociationElement_QueryDword(T,a,b,c) (T)->lpVtbl->QueryDword(T,a,b,c) +#define IAssociationElement_QueryGuid(T,a,b,c) (T)->lpVtbl->QueryGuid(T,a,b,c) +#define IAssociationElement_QueryExists(T,a,b) (T)->lpVtbl->QueryExists(T,a,b) +#define IAssociationElement_QueryDirect(T,a,b,c) (T)->lpVtbl->QueryDirect(T,a,b,c) +#define IAssociationElement_QueryObject(T,a,b,c,d) (T)->lpVtbl->QueryObject(T,a,b,c,d) +#endif + +/***************************************************************************** + * IEnumAssociationElements interface + * + * @see https://www.geoffchappell.com/studies/windows/shell/shell32/interfaces/ienumassociationelements.htm + */ +#define INTERFACE IEnumAssociationElements +DECLARE_INTERFACE_(IEnumAssociationElements, IUnknown) // {A6B0FB57-7523-4439-9425-EBE99823B828} +{ + /*** IUnknown ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + /*** IEnumAssociationElements ***/ + STDMETHOD(Next)(THIS_ ULONG celt, IAssociationElement *pElement, ULONG *pceltFetched) PURE; + STDMETHOD(Skip)(THIS_ ULONG celt) PURE; + STDMETHOD(Reset)(THIS) PURE; + STDMETHOD(Clone)(THIS_ IEnumAssociationElements **ppNew) PURE; +}; +#undef INTERFACE + +#ifdef COBJMACROS +#define IEnumAssociationElements_QueryInterface(T,a,b) (T)->lpVtbl->QueryInterface(T,a,b) +#define IEnumAssociationElements_AddRef(T) (T)->lpVtbl->AddRef(T) +#define IEnumAssociationElements_Release(T) (T)->lpVtbl->Release(T) +#define IEnumAssociationElements_Next(T,a,b,c) (T)->lpVtbl->Next(T,a,b,c) +#define IEnumAssociationElements_Skip(T,a) (T)->lpVtbl->Skip(T,a) +#define IEnumAssociationElements_Reset(T) (T)->lpVtbl->Reset(T) +#define IEnumAssociationElements_Clone(T,a) (T)->lpVtbl->Clone(T,a) +#endif + +/***************************************************************************** + * IAssociationArrayOld interface + * + * @see IAssociationArray + * @see https://www.geoffchappell.com/studies/windows/shell/shell32/interfaces/iassociationarray.htm + */ +#define INTERFACE IAssociationArrayOld +DECLARE_INTERFACE_(IAssociationArrayOld, IUnknown) // {3B877E3C-67DE-4F9A-B29B-17D0A1521C6A} +{ + /*** IUnknown ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + /*** IAssociationArrayOld ***/ + STDMETHOD(EnumElements)(THIS_ ULONG flags, IEnumAssociationElements **ppElement) PURE; + STDMETHOD(QueryString)(THIS_ ULONG flags, ASSOCQUERY query, PCWSTR key, PWSTR *ppszValue) PURE; + STDMETHOD(QueryDword)(THIS_ ULONG flags, ASSOCQUERY query, PCWSTR key, DWORD *pdwValue) PURE; + STDMETHOD(QueryExists)(THIS_ ULONG flags, ASSOCQUERY query, PCWSTR key) PURE; + STDMETHOD(QueryDirect)(THIS_ ULONG flags, ASSOCQUERY query, PCWSTR key, FLAGGED_BYTE_BLOB **ppBlob) PURE; + STDMETHOD(QueryObject)(THIS_ ULONG flags, ASSOCQUERY query, PCWSTR key, REFIID riid, PVOID *ppvObj) PURE; +}; +#undef INTERFACE + +#ifdef COBJMACROS +#define IAssociationArrayOld_QueryInterface(T,a,b) (T)->lpVtbl->QueryInterface(T,a,b) +#define IAssociationArrayOld_AddRef(T) (T)->lpVtbl->AddRef(T) +#define IAssociationArrayOld_Release(T) (T)->lpVtbl->Release(T) +#define IAssociationArrayOld_EnumElements(T,a,b) (T)->lpVtbl->EnumElements(T,a,b) +#define IAssociationArrayOld_QueryString(T,a,b,c,d) (T)->lpVtbl->QueryString(T,a,b,c,d) +#define IAssociationArrayOld_QueryDword(T,a,b,c,d) (T)->lpVtbl->QueryDword(T,a,b,c,d) +#define IAssociationArrayOld_QueryExists(T,a,b,c) (T)->lpVtbl->QueryExists(T,a,b,c) +#define IAssociationArrayOld_QueryDirect(T,a,b,c,d) (T)->lpVtbl->QueryDirect(T,a,b,c,d) +#define IAssociationArrayOld_QueryObject(T,a,b,c,d,e) (T)->lpVtbl->QueryObject(T,a,b,c,d,e) +#endif + +/***************************************************************************** + * IAssociationArray interface + * + * @see IAssociationArrayOld + * @see https://www.geoffchappell.com/studies/windows/shell/shell32/interfaces/iassociationarray.htm + */ +#define INTERFACE IAssociationArray +DECLARE_INTERFACE_(IAssociationArray, IUnknown) // {19ADBAFD-1C5F-4FC7-94EE-846702DFB58B} +{ + /*** IUnknown ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + /*** IAssociationArray ***/ + STDMETHOD(QueryString)(THIS_ ASSOCQUERY query, PCWSTR key, PWSTR *ppszValue) PURE; + STDMETHOD(QueryDword)(THIS_ ASSOCQUERY query, PCWSTR key, DWORD *pdwValue) PURE; + STDMETHOD(QueryGuid)(THIS_ ASSOCQUERY query, PCWSTR key, GUID *pguid) PURE; + STDMETHOD(QueryExists)(THIS_ ASSOCQUERY query, PCWSTR key) PURE; + STDMETHOD(QueryDirect)(THIS_ ASSOCQUERY query, PCWSTR key, FLAGGED_BYTE_BLOB **ppBlob) PURE; + STDMETHOD(QueryObject)(THIS_ ASSOCQUERY query, PCWSTR key, REFIID riid, PVOID *ppvObj) PURE; +}; +#undef INTERFACE + +#ifdef COBJMACROS +#define IAssociationArray_QueryInterface(T,a,b) (T)->lpVtbl->QueryInterface(T,a,b) +#define IAssociationArray_AddRef(T) (T)->lpVtbl->AddRef(T) +#define IAssociationArray_Release(T) (T)->lpVtbl->Release(T) +#define IAssociationArray_QueryString(T,a,b,c) (T)->lpVtbl->QueryString(T,a,b,c) +#define IAssociationArray_QueryDword(T,a,b,c) (T)->lpVtbl->QueryDword(T,a,b,c) +#define IAssociationArray_QueryGuid(T,a,b,c) (T)->lpVtbl->QueryGuid(T,a,b,c) +#define IAssociationArray_QueryExists(T,a,b) (T)->lpVtbl->QueryExists(T,a,b) +#define IAssociationArray_QueryDirect(T,a,b,c) (T)->lpVtbl->QueryDirect(T,a,b,c) +#define IAssociationArray_QueryObject(T,a,b,c,d) (T)->lpVtbl->QueryObject(T,a,b,c,d) +#endif + HANDLE WINAPI SHCreateDesktop(IShellDesktopTray*); BOOL WINAPI SHDesktopMessageLoop(HANDLE); HRESULT WINAPI SHCreateFileDataObject(PCIDLIST_ABSOLUTE pidlFolder, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, IDataObject* pDataInner, IDataObject** ppDataObj); #ifdef __cplusplus } /* extern "C" */ -#endif /* defined(__cplusplus) */ - -#endif // __SHLOBJ_UNDOC__H +#endif diff --git a/sdk/include/reactos/shlwapi_undoc.h b/sdk/include/reactos/shlwapi_undoc.h index def0725cdd22f..2ca22001c21dd 100644 --- a/sdk/include/reactos/shlwapi_undoc.h +++ b/sdk/include/reactos/shlwapi_undoc.h @@ -1,29 +1,38 @@ /* - * ReactOS shlwapi - * - * Copyright 2009 Andrew Hill - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * PROJECT: ReactOS header + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Undocumented SHLWAPI definitions + * COPYRIGHT: Copyright 2009 Andrew Hill + * Copyright 2025 Katayama Hirofumi MZ */ -#ifndef __SHLWAPI_UNDOC_H -#define __SHLWAPI_UNDOC_H +#pragma once + +#include // For REGSAM #ifdef __cplusplus extern "C" { -#endif /* defined(__cplusplus) */ +#endif + +/***************************************************************************** + * ASSOCQUERY --- The type flags of association query + * + * @see IAssociationElementOld, IAssociationElement, IAssociationArrayOld, IAssociationArray + * @see https://www.geoffchappell.com/studies/windows/shell/shell32/api/assocelem/query.htm + */ +typedef DWORD ASSOCQUERY; +#define ASSOCQUERY_LOWORD_MASK 0x0000FFFF // The low-order word of flags +#define ASSOCQUERY_STRING 0x00010000 // Responds to QueryString method +#define ASSOCQUERY_EXISTS 0x00020000 // Responds to QueryExists method +#define ASSOCQUERY_DIRECT 0x00040000 // Responds to QueryDirect method +#define ASSOCQUERY_DWORD 0x00080000 // Responds to QueryDword method +#define ASSOCQUERY_INDIRECT 0x00100000 // Obtains resource string from QueryString +#define ASSOCQUERY_OBJECT 0x00200000 // Responds to QueryObject method +#define ASSOCQUERY_GUID 0x00400000 // Responds to QueryGuid method +#define ASSOCQUERY_EXTRA_NON_VERB 0x01000000 // Expects pszExtra for path or value +#define ASSOCQUERY_EXTRA_VERB 0x02000000 // Expects pszExtra for verb +#define ASSOCQUERY_SIGNIFICANCE 0x04000000 // Significance unknown +#define ASSOCQUERY_FALLBACK 0x80000000 // Fallback to secondary query source #define SHELL_NO_POLICY ((DWORD)-1) @@ -364,43 +373,42 @@ IContextMenu_Invoke( DWORD WINAPI SHGetObjectCompatFlags(IUnknown *pUnk, const CLSID *clsid); -/* - * HACK! These functions are conflicting with inline functions... - * We provide a macro option SHLWAPI_ISHELLFOLDER_HELPERS for using these functions. - */ -#ifdef SHLWAPI_ISHELLFOLDER_HELPERS -HRESULT WINAPI -IShellFolder_GetDisplayNameOf( - _In_ IShellFolder *psf, - _In_ LPCITEMIDLIST pidl, - _In_ SHGDNF uFlags, - _Out_ LPSTRRET lpName, - _In_ DWORD dwRetryFlags); +#define SHACF_WIN95SHLEXEC 0x00000200 /* Geoff Chappell */ +DWORD WINAPI SHGetAppCompatFlags(DWORD dwMask); -/* Flags for IShellFolder_GetDisplayNameOf */ -#define SFGDNO_RETRYWITHFORPARSING 0x00000001 -#define SFGDNO_RETRYALWAYS 0x80000000 - -HRESULT WINAPI -IShellFolder_ParseDisplayName( - _In_ IShellFolder *psf, - _In_ HWND hwndOwner, - _In_ LPBC pbcReserved, - _In_ LPOLESTR lpszDisplayName, - _Out_ ULONG *pchEaten, - _Out_ PIDLIST_RELATIVE *ppidl, - _Out_ ULONG *pdwAttributes); - -EXTERN_C HRESULT WINAPI -IShellFolder_CompareIDs( - _In_ IShellFolder *psf, - _In_ LPARAM lParam, - _In_ PCUIDLIST_RELATIVE pidl1, - _In_ PCUIDLIST_RELATIVE pidl2); -#endif /* SHLWAPI_ISHELLFOLDER_HELPERS */ +/***************************************************************************** + * IAssociationElementOld interface + * + * @see IAssociationElement + * @see https://www.geoffchappell.com/studies/windows/shell/shlwapi/interfaces/iassociationelement.htm + */ +#define INTERFACE IAssociationElementOld +DECLARE_INTERFACE_(IAssociationElementOld, IUnknown) // {E58B1ABF-9596-4DBA-8997-89DCDEF46992} +{ + /*** IUnknown ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + /*** IAssociationElementOld ***/ + STDMETHOD(QueryString)(THIS_ ASSOCQUERY query, PCWSTR key, PWSTR *ppszValue) PURE; + STDMETHOD(QueryDword)(THIS_ ASSOCQUERY query, PCWSTR key, DWORD *pdwValue) PURE; + STDMETHOD(QueryExists)(THIS_ ASSOCQUERY query, PCWSTR key) PURE; + STDMETHOD(QueryDirect)(THIS_ ASSOCQUERY query, PCWSTR key, FLAGGED_BYTE_BLOB **ppBlob) PURE; + STDMETHOD(QueryObject)(THIS_ ASSOCQUERY query, PCWSTR key, REFIID riid, PVOID *ppvObj) PURE; +}; +#undef INTERFACE + +#ifdef COBJMACROS +#define IAssociationElementOld_QueryInterface(T,a,b) (T)->lpVtbl->QueryInterface(T,a,b) +#define IAssociationElementOld_AddRef(T) (T)->lpVtbl->AddRef(T) +#define IAssociationElementOld_Release(T) (T)->lpVtbl->Release(T) +#define IAssociationElementOld_QueryString(T,a,b,c) (T)->lpVtbl->QueryString(T,a,b,c) +#define IAssociationElementOld_QueryDword(T,a,b,c) (T)->lpVtbl->QueryDword(T,a,b,c) +#define IAssociationElementOld_QueryExists(T,a,b) (T)->lpVtbl->QueryExists(T,a,b) +#define IAssociationElementOld_QueryDirect(T,a,b,c) (T)->lpVtbl->QueryDirect(T,a,b,c) +#define IAssociationElementOld_QueryObject(T,a,b,c,d) (T)->lpVtbl->QueryObject(T,a,b,c,d) +#endif #ifdef __cplusplus } /* extern "C" */ -#endif /* defined(__cplusplus) */ - -#endif /* __SHLWAPI_UNDOC_H */ +#endif diff --git a/sdk/include/reactos/subsys/csr/csr.h b/sdk/include/reactos/subsys/csr/csr.h index bfa59b60465c3..e819de990260a 100644 --- a/sdk/include/reactos/subsys/csr/csr.h +++ b/sdk/include/reactos/subsys/csr/csr.h @@ -39,7 +39,7 @@ NTAPI CsrAllocateMessagePointer( _Inout_ PCSR_CAPTURE_BUFFER CaptureBuffer, _In_ ULONG MessageLength, - _Out_ PVOID* CapturedData); + _Out_ LPC_PVOID* CapturedData); VOID NTAPI @@ -47,7 +47,71 @@ CsrCaptureMessageBuffer( _Inout_ PCSR_CAPTURE_BUFFER CaptureBuffer, _In_opt_ PVOID MessageBuffer, _In_ ULONG MessageLength, - _Out_ PVOID* CapturedData); + _Out_ LPC_PVOID* CapturedData); + +#ifdef USE_LPC6432 + +static +ULONG +CsrAllocateMessagePointerNative( + _Inout_ PCSR_CAPTURE_BUFFER CaptureBuffer, + _In_ ULONG MessageLength, + _Out_ LPC_PVOID* CapturedData) +{ + return CsrAllocateMessagePointer(CaptureBuffer, MessageLength, CapturedData); +} + +static +VOID +CsrCaptureMessageBufferNative( + _Inout_ PCSR_CAPTURE_BUFFER CaptureBuffer, + _In_opt_ PVOID MessageBuffer, + _In_ ULONG MessageLength, + _Out_ LPC_PVOID* CapturedData) +{ + CsrCaptureMessageBuffer(CaptureBuffer, MessageBuffer, MessageLength, CapturedData); +} + +static +ULONG +CsrAllocateMessagePointer32( + _Inout_ PCSR_CAPTURE_BUFFER CaptureBuffer, + _In_ ULONG MessageLength, + _Out_ PVOID* CapturedData) +{ + LPC_PVOID Temp; + ULONG Result; + + Result = CsrAllocateMessagePointer(CaptureBuffer, MessageLength, &Temp); + ASSERT((((ULONGLONG)Temp) & 0xFFFFFFFF00000000ULL) == 0); + + *CapturedData = (PVOID)Temp; + return Result; +} + +static +VOID +CsrCaptureMessageBuffer32( + _Inout_ PCSR_CAPTURE_BUFFER CaptureBuffer, + _In_opt_ PVOID MessageBuffer, + _In_ ULONG MessageLength, + _Out_ PVOID* CapturedData) +{ + LPC_PVOID Temp; + CsrCaptureMessageBuffer(CaptureBuffer, MessageBuffer, MessageLength, &Temp); + ASSERT((((ULONGLONG)Temp) & 0xFFFFFFFF00000000ULL) == 0); + *CapturedData = (PVOID)Temp; +} + +#define CsrAllocateMessagePointer CsrAllocateMessagePointer32 +#define CsrCaptureMessageBuffer CsrCaptureMessageBuffer32 + +#else + +#define CsrAllocateMessagePointerNative CsrAllocateMessagePointer +#define CsrCaptureMessageBufferNative CsrCaptureMessageBuffer + +#endif VOID NTAPI diff --git a/sdk/include/reactos/subsys/csr/csrmsg.h b/sdk/include/reactos/subsys/csr/csrmsg.h index 759e6eab0e984..20987c35f2b52 100644 --- a/sdk/include/reactos/subsys/csr/csrmsg.h +++ b/sdk/include/reactos/subsys/csr/csrmsg.h @@ -13,9 +13,44 @@ #pragma once - #define CSR_PORT_NAME L"ApiPort" // CSR_API_PORT_NAME +/* FIXME: win32ss compile fails due to some precompiled header if this is not duplicated here. */ +#ifndef LPC_ULONG_PTR + +#ifdef USE_LPC6432 + +#define LPC_SIZE_T ULONGLONG +#define LPC_PVOID ULONGLONG +#define LPC_HANDLE ULONGLONG +#define LPC_ULONG_PTR ULONGLONG +typedef struct +{ + LPC_HANDLE UniqueProcess; + LPC_HANDLE UniqueThread; +} LPC_CLIENT_ID; +#define LPC_UNICODE_STRING UNICODE_STRING64 +#define LPC_PTR(x) LPC_PVOID +#define LPC_PTRTYPE(x) LPC_PVOID +#define TO_LPC_HANDLE(h) ((LPC_HANDLE)(h)) +#define FROM_LPC_HANDLE(h) ((HANDLE)(h)) + +#else + +#define LPC_CLIENT_ID CLIENT_ID +#define LPC_SIZE_T SIZE_T +#define LPC_PVOID PVOID +#define LPC_HANDLE HANDLE +#define LPC_ULONG_PTR ULONG_PTR +#define LPC_UNICODE_STRING UNICODE_STRING +#define LPC_PTR(x) x* +#define LPC_PTRTYPE(x) x +#define TO_LPC_HANDLE(h) h +#define FROM_LPC_HANDLE(h) h + +#endif + +#endif #define CSRSRV_SERVERDLL_INDEX 0 #define CSRSRV_FIRST_API_NUMBER 0 @@ -46,18 +81,18 @@ typedef ULONG CSR_API_NUMBER; typedef struct _CSR_API_CONNECTINFO { - HANDLE ObjectDirectory; // Unused on Windows >= 2k3 - PVOID SharedSectionBase; - PVOID SharedStaticServerData; - PVOID SharedSectionHeap; - ULONG DebugFlags; - ULONG SizeOfPebData; - ULONG SizeOfTebData; - ULONG NumberOfServerDllNames; - HANDLE ServerProcessId; + LPC_HANDLE ObjectDirectory; // Unused on Windows >= 2k3 + LPC_PVOID SharedSectionBase; + LPC_PVOID SharedStaticServerData; + LPC_PVOID SharedSectionHeap; + ULONG DebugFlags; + ULONG SizeOfPebData; + ULONG SizeOfTebData; + ULONG NumberOfServerDllNames; + LPC_HANDLE ServerProcessId; } CSR_API_CONNECTINFO, *PCSR_API_CONNECTINFO; -#if defined(_M_IX86) +#if defined(_M_IX86) && !defined(USE_LPC6432) C_ASSERT(sizeof(CSR_API_CONNECTINFO) == 0x24); #endif @@ -69,12 +104,12 @@ C_ASSERT(sizeof(CSR_API_CONNECTINFO) <= LPC_MAX_DATA_LENGTH); typedef struct _CSR_IDENTIFY_ALERTABLE_THREAD { - CLIENT_ID Cid; + LPC_CLIENT_ID Cid; } CSR_IDENTIFY_ALERTABLE_THREAD, *PCSR_IDENTIFY_ALERTABLE_THREAD; typedef struct _CSR_SET_PRIORITY_CLASS { - HANDLE hProcess; + LPC_HANDLE hProcess; ULONG PriorityClass; } CSR_SET_PRIORITY_CLASS, *PCSR_SET_PRIORITY_CLASS; @@ -83,17 +118,17 @@ typedef struct _CSR_SET_PRIORITY_CLASS typedef struct _CSR_CLIENT_CONNECT { ULONG ServerId; - PVOID ConnectionInfo; + LPC_PVOID ConnectionInfo; ULONG ConnectionInfoSize; } CSR_CLIENT_CONNECT, *PCSR_CLIENT_CONNECT; typedef struct _CSR_CAPTURE_BUFFER { ULONG Size; - struct _CSR_CAPTURE_BUFFER *PreviousCaptureBuffer; + LPC_PVOID /* struct _CSR_CAPTURE_BUFFER * */ PreviousCaptureBuffer; ULONG PointerCount; - PVOID BufferEnd; - ULONG_PTR PointerOffsetsArray[ANYSIZE_ARRAY]; + LPC_PVOID BufferEnd; + LPC_ULONG_PTR PointerOffsetsArray[ANYSIZE_ARRAY]; } CSR_CAPTURE_BUFFER, *PCSR_CAPTURE_BUFFER; @@ -105,7 +140,7 @@ typedef struct _CSR_API_MESSAGE CSR_API_CONNECTINFO ConnectionInfo; // Uniquely used in CSRSRV for internal signaling (opening a new connection). struct { - PCSR_CAPTURE_BUFFER CsrCaptureData; + LPC_PTR(CSR_CAPTURE_BUFFER) CsrCaptureData; CSR_API_NUMBER ApiNumber; NTSTATUS Status; // ReturnValue; ULONG Reserved; @@ -134,7 +169,7 @@ typedef struct _CSR_API_MESSAGE // Finally, the overall message structure size must be at most // equal to the maximum acceptable LPC message size. // - ULONG_PTR ApiMessageData[39]; + LPC_ULONG_PTR ApiMessageData[39]; } Data; }; }; diff --git a/sdk/include/reactos/subsys/lsass/lsass.h b/sdk/include/reactos/subsys/lsass/lsass.h index 5522b0ef85f36..ad2df3ee2d99a 100644 --- a/sdk/include/reactos/subsys/lsass/lsass.h +++ b/sdk/include/reactos/subsys/lsass/lsass.h @@ -27,6 +27,12 @@ typedef enum _LSA_API_NUMBER LSASS_REQUEST_MAXIMUM } LSA_API_NUMBER, *PLSA_API_NUMBER; +typedef enum _LSA_TRUSTED_CALLER +{ + NO, + YES, + CHECK +} LSA_TRUSTED_CALLER; typedef struct _LSA_CONNECTION_INFO { @@ -35,7 +41,7 @@ typedef struct _LSA_CONNECTION_INFO ULONG Length; CHAR LogonProcessNameBuffer[LSASS_MAX_LOGON_PROCESS_NAME_LENGTH + 1]; BOOL CreateContext; - BOOL TrustedCaller; + LSA_TRUSTED_CALLER TrustedCaller; } LSA_CONNECTION_INFO, *PLSA_CONNECTION_INFO; diff --git a/sdk/include/reactos/subsys/sm/smmsg.h b/sdk/include/reactos/subsys/sm/smmsg.h index 50601e38409ba..43c1583555930 100644 --- a/sdk/include/reactos/subsys/sm/smmsg.h +++ b/sdk/include/reactos/subsys/sm/smmsg.h @@ -124,8 +124,12 @@ typedef struct _SM_API_MSG // This is the size that Server 2003 SP1 SMSS expects, so make sure we conform. // #ifndef _WIN64 +#ifndef BUILD_WOW6432 C_ASSERT(sizeof(SM_API_MSG) == 0x130); #else +/* TODO */ +#endif +#else C_ASSERT(sizeof(SM_API_MSG) == 0x148); #endif @@ -252,8 +256,12 @@ typedef struct _SB_API_MSG // This is the size that Server 2003 SP1 SMSS expects, so make sure we conform. // #ifndef _WIN64 +#ifndef BUILD_WOW6432 C_ASSERT(sizeof(SB_API_MSG) == 0x110); #else +/* TODO */ +#endif +#else C_ASSERT(sizeof(SB_API_MSG) == 0x120); #endif diff --git a/sdk/include/reactos/subsys/win/base.h b/sdk/include/reactos/subsys/win/base.h index 28f21bee7dd80..c0b2cff2f8a90 100644 --- a/sdk/include/reactos/subsys/win/base.h +++ b/sdk/include/reactos/subsys/win/base.h @@ -81,13 +81,13 @@ C_ASSERT(sizeof(NLS_USER_INFO) == 0x1870); typedef struct _INIFILE_MAPPING_TARGET { struct _INIFILE_MAPPING_TARGET *Next; - UNICODE_STRING RegistryPath; + LPC_UNICODE_STRING RegistryPath; } INIFILE_MAPPING_TARGET, *PINIFILE_MAPPING_TARGET; typedef struct _INIFILE_MAPPING_VARNAME { struct _INIFILE_MAPPING_VARNAME *Next; - UNICODE_STRING Name; + LPC_UNICODE_STRING Name; ULONG MappingFlags; PINIFILE_MAPPING_TARGET MappingTarget; } INIFILE_MAPPING_VARNAME, *PINIFILE_MAPPING_VARNAME; @@ -95,7 +95,7 @@ typedef struct _INIFILE_MAPPING_VARNAME typedef struct _INIFILE_MAPPING_APPNAME { struct _INIFILE_MAPPING_APPNAME *Next; - UNICODE_STRING Name; + LPC_UNICODE_STRING Name; PINIFILE_MAPPING_VARNAME VariableNames; PINIFILE_MAPPING_VARNAME DefaultVarNameMapping; } INIFILE_MAPPING_APPNAME, *PINIFILE_MAPPING_APPNAME; @@ -103,7 +103,7 @@ typedef struct _INIFILE_MAPPING_APPNAME typedef struct _INIFILE_MAPPING_FILENAME { struct _INIFILE_MAPPING_FILENAME *Next; - UNICODE_STRING Name; + LPC_UNICODE_STRING Name; PINIFILE_MAPPING_APPNAME ApplicationNames; PINIFILE_MAPPING_APPNAME DefaultAppNameMapping; } INIFILE_MAPPING_FILENAME, *PINIFILE_MAPPING_FILENAME; @@ -118,22 +118,26 @@ typedef struct _INIFILE_MAPPING typedef struct _BASE_STATIC_SERVER_DATA { - UNICODE_STRING WindowsDirectory; - UNICODE_STRING WindowsSystemDirectory; - UNICODE_STRING NamedObjectDirectory; + LPC_UNICODE_STRING WindowsDirectory; + LPC_UNICODE_STRING WindowsSystemDirectory; + LPC_UNICODE_STRING NamedObjectDirectory; USHORT WindowsMajorVersion; USHORT WindowsMinorVersion; USHORT BuildNumber; USHORT CSDNumber; USHORT RCNumber; WCHAR CSDVersion[128]; +#ifdef USE_LPC6432 + ULONG Padding; +#endif + /* FIXME: WOW64 */ SYSTEM_BASIC_INFORMATION SysInfo; SYSTEM_TIMEOFDAY_INFORMATION TimeOfDay; - PVOID IniFileMapping; + LPC_PVOID IniFileMapping; NLS_USER_INFO NlsUserInfo; BOOLEAN DefaultSeparateVDM; BOOLEAN IsWowTaskReady; - UNICODE_STRING WindowsSys32x86Directory; + LPC_UNICODE_STRING WindowsSys32x86Directory; BOOLEAN fTermsrvAppInstallMode; TIME_ZONE_INFORMATION tziTermsrvClientTimeZone; KSYSTEM_TIME ktTermsrvClientBias; @@ -142,7 +146,7 @@ typedef struct _BASE_STATIC_SERVER_DATA ULONG TermsrvClientTimeZoneChangeNum; } BASE_STATIC_SERVER_DATA, *PBASE_STATIC_SERVER_DATA; -#if defined(_M_IX86) +#if defined(_M_IX86) && !defined(USE_LPC6432) C_ASSERT(sizeof(BASE_STATIC_SERVER_DATA) == 0x1AC8); #endif diff --git a/sdk/include/reactos/subsys/win/basemsg.h b/sdk/include/reactos/subsys/win/basemsg.h index 9d0761e2d77d1..44121a5ad3602 100644 --- a/sdk/include/reactos/subsys/win/basemsg.h +++ b/sdk/include/reactos/subsys/win/basemsg.h @@ -67,18 +67,18 @@ typedef struct _BASE_SXS_CREATEPROCESS_MSG { ULONG Flags; ULONG ProcessParameterFlags; - HANDLE FileHandle; - UNICODE_STRING SxsWin32ExePath; - UNICODE_STRING SxsNtExePath; - SIZE_T OverrideManifestOffset; + LPC_HANDLE FileHandle; + LPC_UNICODE_STRING SxsWin32ExePath; + LPC_UNICODE_STRING SxsNtExePath; + LPC_SIZE_T OverrideManifestOffset; ULONG OverrideManifestSize; - SIZE_T OverridePolicyOffset; + LPC_SIZE_T OverridePolicyOffset; ULONG OverridePolicySize; - PVOID PEManifestAddress; + LPC_PVOID PEManifestAddress; ULONG PEManifestSize; - UNICODE_STRING CultureFallbacks; + LPC_UNICODE_STRING CultureFallbacks; ULONG Unknown[7]; - UNICODE_STRING AssemblyName; + LPC_UNICODE_STRING AssemblyName; } BASE_SXS_CREATEPROCESS_MSG, *PBASE_SXS_CREATEPROCESS_MSG; typedef struct _BASE_CREATE_PROCESS @@ -86,23 +86,23 @@ typedef struct _BASE_CREATE_PROCESS // // NT-type structure (BASE_CREATEPROCESS_MSG) // - HANDLE ProcessHandle; - HANDLE ThreadHandle; - CLIENT_ID ClientId; + LPC_HANDLE ProcessHandle; + LPC_HANDLE ThreadHandle; + LPC_CLIENT_ID ClientId; ULONG CreationFlags; ULONG VdmBinaryType; ULONG VdmTask; - HANDLE hVDM; + LPC_HANDLE hVDM; BASE_SXS_CREATEPROCESS_MSG Sxs; - PVOID PebAddressNative; + LPC_PVOID PebAddressNative; ULONG PebAddressWow64; USHORT ProcessorArchitecture; } BASE_CREATE_PROCESS, *PBASE_CREATE_PROCESS; typedef struct _BASE_CREATE_THREAD { - HANDLE ThreadHandle; - CLIENT_ID ClientId; + LPC_HANDLE ThreadHandle; + LPC_CLIENT_ID ClientId; } BASE_CREATE_THREAD, *PBASE_CREATE_THREAD; typedef struct _BASE_GET_TEMP_FILE @@ -274,7 +274,7 @@ typedef struct _BASE_API_MESSAGE { PORT_MESSAGE Header; - PCSR_CAPTURE_BUFFER CsrCaptureData; + LPC_PTR(CSR_CAPTURE_BUFFER) CsrCaptureData; CSR_API_NUMBER ApiNumber; NTSTATUS Status; ULONG Reserved; diff --git a/sdk/include/reactos/subsys/win/conmsg.h b/sdk/include/reactos/subsys/win/conmsg.h index 67dba20e4207c..a3c5ec94f2266 100644 --- a/sdk/include/reactos/subsys/win/conmsg.h +++ b/sdk/include/reactos/subsys/win/conmsg.h @@ -115,13 +115,13 @@ typedef enum _CONSRV_API_NUMBER } CONSRV_API_NUMBER, *PCONSRV_API_NUMBER; // -// See http://msdn.microsoft.com/en-us/library/windows/desktop/bb773359(v=vs.85).aspx +// See https://learn.microsoft.com/en-us/windows/win32/api/shlobj_core/ns-shlobj_core-nt_console_props // typedef struct _CONSOLE_PROPERTIES { INT IconIndex; - HICON hIcon; - HICON hIconSm; + LPC_PTRTYPE(HICON) hIcon; + LPC_PTRTYPE(HICON) hIconSm; DWORD dwHotKey; DWORD dwStartupFlags; @@ -167,17 +167,17 @@ enum typedef struct _CONSOLE_START_INFO { - HANDLE ConsoleHandle; - HANDLE InputWaitHandle; - HANDLE InputHandle; - HANDLE OutputHandle; - HANDLE ErrorHandle; - HANDLE InitEvents[MAX_INIT_EVENTS]; + LPC_HANDLE ConsoleHandle; + LPC_HANDLE InputWaitHandle; + LPC_HANDLE InputHandle; + LPC_HANDLE OutputHandle; + LPC_HANDLE ErrorHandle; + LPC_HANDLE InitEvents[MAX_INIT_EVENTS]; CONSOLE_PROPERTIES; } CONSOLE_START_INFO, *PCONSOLE_START_INFO; -#if defined(_M_IX86) +#if defined(_M_IX86) && !defined(USE_LPC6432) C_ASSERT(sizeof(CONSOLE_START_INFO) == 0xFC); #endif @@ -190,14 +190,14 @@ typedef struct _CONSRV_API_CONNECTINFO // USHORT Padding; - LPTHREAD_START_ROUTINE CtrlRoutine; - LPTHREAD_START_ROUTINE PropRoutine; - LPTHREAD_START_ROUTINE ImeRoutine; + LPC_PTRTYPE(LPTHREAD_START_ROUTINE) CtrlRoutine; + LPC_PTRTYPE(LPTHREAD_START_ROUTINE) PropRoutine; + LPC_PTRTYPE(LPTHREAD_START_ROUTINE) ImeRoutine; ULONG TitleLength; WCHAR ConsoleTitle[MAX_PATH + 1]; // Console title or full path to the startup shortcut ULONG DesktopLength; - PWCHAR Desktop; // Contrary to the case of CONSOLE_ALLOCCONSOLE, the + LPC_PTR(WCHAR) Desktop; // Contrary to the case of CONSOLE_ALLOCCONSOLE, the // desktop string is allocated in the process' heap, // and CSR will read it via NtReadVirtualMemory. ULONG AppNameLength; @@ -206,38 +206,40 @@ typedef struct _CONSRV_API_CONNECTINFO WCHAR CurDir[MAX_PATH + 1]; } CONSRV_API_CONNECTINFO, *PCONSRV_API_CONNECTINFO; -#if defined(_M_IX86) +#if defined(_M_IX86) && !defined(USE_LPC6432) C_ASSERT(sizeof(CONSRV_API_CONNECTINFO) == 0x638); +#elif defined(_M_IX86) || defined(_M_AMD64) +C_ASSERT(sizeof(CONSRV_API_CONNECTINFO) == 0x680); #endif typedef struct _CONSOLE_GETPROCESSLIST { - HANDLE ConsoleHandle; + LPC_HANDLE ConsoleHandle; ULONG ProcessCount; - PDWORD ProcessIdsList; + LPC_PTR(DWORD) ProcessIdsList; } CONSOLE_GETPROCESSLIST, *PCONSOLE_GETPROCESSLIST; typedef struct _CONSOLE_GENERATECTRLEVENT { - HANDLE ConsoleHandle; + LPC_HANDLE ConsoleHandle; ULONG CtrlEvent; ULONG ProcessGroupId; } CONSOLE_GENERATECTRLEVENT, *PCONSOLE_GENERATECTRLEVENT; typedef struct _CONSOLE_NOTIFYLASTCLOSE { - HANDLE ConsoleHandle; + LPC_HANDLE ConsoleHandle; } CONSOLE_NOTIFYLASTCLOSE, *PCONSOLE_NOTIFYLASTCLOSE; typedef struct _CONSOLE_WRITECONSOLE { - HANDLE ConsoleHandle; - HANDLE OutputHandle; + LPC_HANDLE ConsoleHandle; + LPC_HANDLE OutputHandle; CHAR StaticBuffer[80]; - PVOID Buffer; // BufPtr + LPC_PVOID Buffer; // BufPtr ULONG NumBytes; // On Windows, the client never uses this member @@ -252,13 +254,13 @@ typedef struct _CONSOLE_WRITECONSOLE typedef struct _CONSOLE_READCONSOLE { - HANDLE ConsoleHandle; - HANDLE InputHandle; + LPC_HANDLE ConsoleHandle; + LPC_HANDLE InputHandle; USHORT ExeLength; CHAR StaticBuffer[80]; - PVOID Buffer; // BufPtr + LPC_PVOID Buffer; // BufPtr ULONG NumBytes; ULONG CaptureBufferSize; @@ -271,19 +273,19 @@ typedef struct _CONSOLE_READCONSOLE typedef struct _CONSOLE_ALLOCCONSOLE { - PCONSOLE_START_INFO ConsoleStartInfo; + LPC_PTR(CONSOLE_START_INFO) ConsoleStartInfo; ULONG TitleLength; - PWCHAR ConsoleTitle; // Console title or full path to the startup shortcut + LPC_PTR(WCHAR) ConsoleTitle; // Console title or full path to the startup shortcut ULONG DesktopLength; - PWCHAR Desktop; + LPC_PTR(WCHAR) Desktop; ULONG AppNameLength; - PWCHAR AppName; // Full path of the launched app + LPC_PTR(WCHAR) AppName; // Full path of the launched app ULONG CurDirLength; - PWCHAR CurDir; + LPC_PTR(WCHAR) CurDir; - LPTHREAD_START_ROUTINE CtrlRoutine; - LPTHREAD_START_ROUTINE PropRoutine; + LPC_PTRTYPE(LPTHREAD_START_ROUTINE) CtrlRoutine; + LPC_PTRTYPE(LPTHREAD_START_ROUTINE) PropRoutine; } CONSOLE_ALLOCCONSOLE, *PCONSOLE_ALLOCCONSOLE; typedef struct _CONSOLE_ATTACHCONSOLE @@ -294,21 +296,21 @@ typedef struct _CONSOLE_ATTACHCONSOLE */ ULONG ProcessId; - PCONSOLE_START_INFO ConsoleStartInfo; + LPC_PTR(CONSOLE_START_INFO) ConsoleStartInfo; - LPTHREAD_START_ROUTINE CtrlRoutine; - LPTHREAD_START_ROUTINE PropRoutine; + LPC_PTRTYPE(LPTHREAD_START_ROUTINE) CtrlRoutine; + LPC_PTRTYPE(LPTHREAD_START_ROUTINE) PropRoutine; } CONSOLE_ATTACHCONSOLE, *PCONSOLE_ATTACHCONSOLE; typedef struct _CONSOLE_FREECONSOLE { - HANDLE ConsoleHandle; + LPC_HANDLE ConsoleHandle; } CONSOLE_FREECONSOLE, *PCONSOLE_FREECONSOLE; typedef struct _CONSOLE_GETSCREENBUFFERINFO { - HANDLE ConsoleHandle; - HANDLE OutputHandle; + LPC_HANDLE ConsoleHandle; + LPC_HANDLE OutputHandle; COORD ScreenBufferSize; COORD CursorPosition; COORD ViewOrigin; @@ -319,30 +321,30 @@ typedef struct _CONSOLE_GETSCREENBUFFERINFO typedef struct _CONSOLE_SETCURSORPOSITION { - HANDLE ConsoleHandle; - HANDLE OutputHandle; + LPC_HANDLE ConsoleHandle; + LPC_HANDLE OutputHandle; COORD Position; } CONSOLE_SETCURSORPOSITION, *PCONSOLE_SETCURSORPOSITION; typedef struct _CONSOLE_SHOWCURSOR { - HANDLE ConsoleHandle; - HANDLE OutputHandle; + LPC_HANDLE ConsoleHandle; + LPC_HANDLE OutputHandle; BOOL Show; INT RefCount; } CONSOLE_SHOWCURSOR, *PCONSOLE_SHOWCURSOR; typedef struct _CONSOLE_SETCURSOR { - HANDLE ConsoleHandle; - HANDLE OutputHandle; + LPC_HANDLE ConsoleHandle; + LPC_HANDLE OutputHandle; HCURSOR CursorHandle; } CONSOLE_SETCURSOR, *PCONSOLE_SETCURSOR; typedef struct _CONSOLE_GETSETCURSORINFO { - HANDLE ConsoleHandle; - HANDLE OutputHandle; + LPC_HANDLE ConsoleHandle; + LPC_HANDLE OutputHandle; CONSOLE_CURSOR_INFO Info; /* ULONG Size; @@ -352,37 +354,37 @@ typedef struct _CONSOLE_GETSETCURSORINFO typedef struct _CONSOLE_GETMOUSEINFO { - HANDLE ConsoleHandle; + LPC_HANDLE ConsoleHandle; ULONG NumButtons; } CONSOLE_GETMOUSEINFO, *PCONSOLE_GETMOUSEINFO; typedef struct _CONSOLE_SETTEXTATTRIB { - HANDLE ConsoleHandle; - HANDLE OutputHandle; + LPC_HANDLE ConsoleHandle; + LPC_HANDLE OutputHandle; WORD Attributes; } CONSOLE_SETTEXTATTRIB, *PCONSOLE_SETTEXTATTRIB; typedef struct _CONSOLE_GETSETCONSOLEMODE { - HANDLE ConsoleHandle; - HANDLE Handle; + LPC_HANDLE ConsoleHandle; + LPC_HANDLE Handle; ULONG Mode; } CONSOLE_GETSETCONSOLEMODE, *PCONSOLE_GETSETCONSOLEMODE; typedef struct _CONSOLE_GETDISPLAYMODE { - HANDLE ConsoleHandle; + LPC_HANDLE ConsoleHandle; ULONG DisplayMode; // ModeFlags } CONSOLE_GETDISPLAYMODE, *PCONSOLE_GETDISPLAYMODE; typedef struct _CONSOLE_SETDISPLAYMODE { - HANDLE ConsoleHandle; - HANDLE OutputHandle; + LPC_HANDLE ConsoleHandle; + LPC_HANDLE OutputHandle; ULONG DisplayMode; // ModeFlags COORD NewSBDim; - HANDLE EventHandle; + LPC_HANDLE EventHandle; } CONSOLE_SETDISPLAYMODE, *PCONSOLE_SETDISPLAYMODE; /* @@ -393,8 +395,8 @@ typedef struct _CONSOLE_SETDISPLAYMODE typedef struct _CONSOLE_GETSETHWSTATE { - HANDLE ConsoleHandle; - HANDLE OutputHandle; + LPC_HANDLE ConsoleHandle; + LPC_HANDLE OutputHandle; ULONG Flags; ULONG State; } CONSOLE_GETSETHWSTATE, *PCONSOLE_GETSETHWSTATE; @@ -402,31 +404,31 @@ typedef struct _CONSOLE_GETSETHWSTATE typedef struct _CONSOLE_GETNUMFONTS { - HANDLE ConsoleHandle; + LPC_HANDLE ConsoleHandle; ULONG NumFonts; } CONSOLE_GETNUMFONTS, *PCONSOLE_GETNUMFONTS; typedef struct _CONSOLE_GETFONTINFO { - HANDLE ConsoleHandle; - HANDLE OutputHandle; + LPC_HANDLE ConsoleHandle; + LPC_HANDLE OutputHandle; BOOLEAN MaximumWindow; - PCONSOLE_FONT_INFO FontInfo; + LPC_PTR(CONSOLE_FONT_INFO) FontInfo; ULONG NumFonts; } CONSOLE_GETFONTINFO, *PCONSOLE_GETFONTINFO; typedef struct _CONSOLE_GETFONTSIZE { - HANDLE ConsoleHandle; - HANDLE OutputHandle; + LPC_HANDLE ConsoleHandle; + LPC_HANDLE OutputHandle; ULONG FontIndex; COORD FontSize; } CONSOLE_GETFONTSIZE, *PCONSOLE_GETFONTSIZE; typedef struct _CONSOLE_GETCURRENTFONT { - HANDLE ConsoleHandle; - HANDLE OutputHandle; + LPC_HANDLE ConsoleHandle; + LPC_HANDLE OutputHandle; BOOLEAN MaximumWindow; ULONG FontIndex; COORD FontSize; @@ -434,8 +436,8 @@ typedef struct _CONSOLE_GETCURRENTFONT typedef struct _CONSOLE_SETFONT { - HANDLE ConsoleHandle; - HANDLE OutputHandle; + LPC_HANDLE ConsoleHandle; + LPC_HANDLE OutputHandle; ULONG FontIndex; } CONSOLE_SETFONT, *PCONSOLE_SETFONT; @@ -443,7 +445,7 @@ typedef struct _CONSOLE_SETFONT typedef struct _CONSOLE_CREATESCREENBUFFER { - HANDLE ConsoleHandle; + LPC_HANDLE ConsoleHandle; ULONG DesiredAccess; // ACCESS_MASK BOOL InheritHandle; ULONG ShareMode; @@ -454,50 +456,50 @@ typedef struct _CONSOLE_CREATESCREENBUFFER * for graphics screen buffers. */ CONSOLE_GRAPHICS_BUFFER_INFO GraphicsBufferInfo; - HANDLE hMutex; - PVOID lpBitMap; - HANDLE OutputHandle; /* Handle to newly created screen buffer */ + LPC_HANDLE hMutex; + LPC_PVOID lpBitMap; + LPC_HANDLE OutputHandle; /* Handle to newly created screen buffer */ } CONSOLE_CREATESCREENBUFFER, *PCONSOLE_CREATESCREENBUFFER; typedef struct _CONSOLE_SETACTIVESCREENBUFFER { - HANDLE ConsoleHandle; - HANDLE OutputHandle; /* Handle to screen buffer to switch to */ + LPC_HANDLE ConsoleHandle; + LPC_HANDLE OutputHandle; /* Handle to screen buffer to switch to */ } CONSOLE_SETACTIVESCREENBUFFER, *PCONSOLE_SETACTIVESCREENBUFFER; typedef struct _CONSOLE_INVALIDATEDIBITS { - HANDLE ConsoleHandle; - HANDLE OutputHandle; + LPC_HANDLE ConsoleHandle; + LPC_HANDLE OutputHandle; SMALL_RECT Region; } CONSOLE_INVALIDATEDIBITS, *PCONSOLE_INVALIDATEDIBITS; typedef struct _CONSOLE_SETPALETTE { - HANDLE ConsoleHandle; - HANDLE OutputHandle; - HPALETTE PaletteHandle; + LPC_HANDLE ConsoleHandle; + LPC_HANDLE OutputHandle; + LPC_PTRTYPE(HPALETTE) PaletteHandle; UINT Usage; } CONSOLE_SETPALETTE, *PCONSOLE_SETPALETTE; typedef struct _CONSOLE_GETSETCONSOLETITLE { - HANDLE ConsoleHandle; + LPC_HANDLE ConsoleHandle; ULONG Length; - PVOID Title; + LPC_PVOID Title; BOOLEAN Unicode; } CONSOLE_GETSETCONSOLETITLE, *PCONSOLE_GETSETCONSOLETITLE; typedef struct _CONSOLE_FLUSHINPUTBUFFER { - HANDLE ConsoleHandle; - HANDLE InputHandle; + LPC_HANDLE ConsoleHandle; + LPC_HANDLE InputHandle; } CONSOLE_FLUSHINPUTBUFFER, *PCONSOLE_FLUSHINPUTBUFFER; typedef struct _CONSOLE_SCROLLSCREENBUFFER { - HANDLE ConsoleHandle; - HANDLE OutputHandle; + LPC_HANDLE ConsoleHandle; + LPC_HANDLE OutputHandle; SMALL_RECT ScrollRectangle; SMALL_RECT ClipRectangle; BOOL UseClipRectangle; @@ -528,18 +530,18 @@ typedef union _CODE_ELEMENT typedef struct _CONSOLE_OUTPUTCODE { - HANDLE ConsoleHandle; - HANDLE OutputHandle; + LPC_HANDLE ConsoleHandle; + LPC_HANDLE OutputHandle; COORD Coord; CODE_TYPE CodeType; CHAR CodeStaticBuffer[80]; // == 40 * sizeof(CODE_ELEMENT) - PVOID pCode; // Either a pointer to a character or to an attribute. + LPC_PVOID pCode; // Either a pointer to a character or to an attribute. // union // { - // PVOID pCode; + // LPC_PVOID pCode; // PCHAR AsciiChar; - // PWCHAR UnicodeChar; + // LPC_PTR(WCHAR) UnicodeChar; // PWORD Attribute; // } pCode; // Either a pointer to a character or to an attribute. @@ -549,8 +551,8 @@ typedef struct _CONSOLE_OUTPUTCODE typedef struct _CONSOLE_FILLOUTPUTCODE { - HANDLE ConsoleHandle; - HANDLE OutputHandle; + LPC_HANDLE ConsoleHandle; + LPC_HANDLE OutputHandle; COORD WriteCoord; CODE_TYPE CodeType; @@ -561,10 +563,10 @@ typedef struct _CONSOLE_FILLOUTPUTCODE typedef struct _CONSOLE_GETINPUT { - HANDLE ConsoleHandle; - HANDLE InputHandle; + LPC_HANDLE ConsoleHandle; + LPC_HANDLE InputHandle; INPUT_RECORD RecordStaticBuffer[5]; - PINPUT_RECORD RecordBufPtr; + LPC_PTR(INPUT_RECORD) RecordBufPtr; ULONG NumRecords; WORD Flags; BOOLEAN Unicode; @@ -572,10 +574,10 @@ typedef struct _CONSOLE_GETINPUT typedef struct _CONSOLE_WRITEINPUT { - HANDLE ConsoleHandle; - HANDLE InputHandle; + LPC_HANDLE ConsoleHandle; + LPC_HANDLE InputHandle; INPUT_RECORD RecordStaticBuffer[5]; - PINPUT_RECORD RecordBufPtr; + LPC_PTR(INPUT_RECORD) RecordBufPtr; ULONG NumRecords; BOOLEAN Unicode; BOOLEAN AppendToEnd; @@ -583,11 +585,11 @@ typedef struct _CONSOLE_WRITEINPUT typedef struct _CONSOLE_READOUTPUT { - HANDLE ConsoleHandle; - HANDLE OutputHandle; + LPC_HANDLE ConsoleHandle; + LPC_HANDLE OutputHandle; CHAR_INFO StaticBuffer; - PCHAR_INFO CharInfo; + LPC_PTR(CHAR_INFO) CharInfo; SMALL_RECT ReadRegion; BOOLEAN Unicode; @@ -595,11 +597,11 @@ typedef struct _CONSOLE_READOUTPUT typedef struct _CONSOLE_WRITEOUTPUT { - HANDLE ConsoleHandle; - HANDLE OutputHandle; + LPC_HANDLE ConsoleHandle; + LPC_HANDLE OutputHandle; CHAR_INFO StaticBuffer; - PCHAR_INFO CharInfo; + LPC_PTR(CHAR_INFO) CharInfo; SMALL_RECT WriteRegion; BOOLEAN Unicode; @@ -614,8 +616,8 @@ typedef struct _CONSOLE_WRITEOUTPUT typedef struct _CONSOLE_GETNUMINPUTEVENTS { - HANDLE ConsoleHandle; - HANDLE InputHandle; + LPC_HANDLE ConsoleHandle; + LPC_HANDLE InputHandle; ULONG NumberOfEvents; } CONSOLE_GETNUMINPUTEVENTS, *PCONSOLE_GETNUMINPUTEVENTS; @@ -623,38 +625,38 @@ typedef struct _CONSOLE_GETNUMINPUTEVENTS typedef struct _CONSOLE_CLOSEHANDLE { - HANDLE ConsoleHandle; - HANDLE Handle; + LPC_HANDLE ConsoleHandle; + LPC_HANDLE Handle; } CONSOLE_CLOSEHANDLE, *PCONSOLE_CLOSEHANDLE; typedef struct _CONSOLE_VERIFYHANDLE { BOOL IsValid; - HANDLE ConsoleHandle; - HANDLE Handle; + LPC_HANDLE ConsoleHandle; + LPC_HANDLE Handle; } CONSOLE_VERIFYHANDLE, *PCONSOLE_VERIFYHANDLE; typedef struct _CONSOLE_DUPLICATEHANDLE { - HANDLE ConsoleHandle; - HANDLE SourceHandle; + LPC_HANDLE ConsoleHandle; + LPC_HANDLE SourceHandle; ULONG DesiredAccess; // ACCESS_MASK BOOLEAN InheritHandle; ULONG Options; - HANDLE TargetHandle; + LPC_HANDLE TargetHandle; } CONSOLE_DUPLICATEHANDLE, *PCONSOLE_DUPLICATEHANDLE; typedef struct _CONSOLE_GETHANDLEINFO { - HANDLE ConsoleHandle; - HANDLE Handle; + LPC_HANDLE ConsoleHandle; + LPC_HANDLE Handle; ULONG Flags; } CONSOLE_GETHANDLEINFO, *PCONSOLE_GETHANDLEINFO; typedef struct _CONSOLE_SETHANDLEINFO { - HANDLE ConsoleHandle; - HANDLE Handle; + LPC_HANDLE ConsoleHandle; + LPC_HANDLE Handle; ULONG Mask; ULONG Flags; } CONSOLE_SETHANDLEINFO, *PCONSOLE_SETHANDLEINFO; @@ -670,27 +672,27 @@ typedef enum _CONSOLE_HANDLE_TYPE typedef struct _CONSOLE_OPENCONSOLE { - HANDLE ConsoleHandle; + LPC_HANDLE ConsoleHandle; CONSOLE_HANDLE_TYPE HandleType; ULONG DesiredAccess; // ACCESS_MASK BOOL InheritHandle; ULONG ShareMode; - HANDLE Handle; + LPC_HANDLE Handle; } CONSOLE_OPENCONSOLE, *PCONSOLE_OPENCONSOLE; typedef struct _CONSOLE_GETLARGESTWINDOWSIZE { - HANDLE ConsoleHandle; - HANDLE OutputHandle; + LPC_HANDLE ConsoleHandle; + LPC_HANDLE OutputHandle; COORD Size; } CONSOLE_GETLARGESTWINDOWSIZE, *PCONSOLE_GETLARGESTWINDOWSIZE; typedef struct _CONSOLE_MENUCONTROL { - HANDLE ConsoleHandle; - HANDLE OutputHandle; + LPC_HANDLE ConsoleHandle; + LPC_HANDLE OutputHandle; ULONG CmdIdLow; ULONG CmdIdHigh; HMENU MenuHandle; @@ -698,14 +700,14 @@ typedef struct _CONSOLE_MENUCONTROL typedef struct _CONSOLE_SETMENUCLOSE { - HANDLE ConsoleHandle; + LPC_HANDLE ConsoleHandle; BOOL Enable; } CONSOLE_SETMENUCLOSE, *PCONSOLE_SETMENUCLOSE; typedef struct _CONSOLE_SETWINDOWINFO { - HANDLE ConsoleHandle; - HANDLE OutputHandle; + LPC_HANDLE ConsoleHandle; + LPC_HANDLE OutputHandle; BOOL Absolute; SMALL_RECT WindowRect; // New console window position in the screen-buffer frame (Absolute == TRUE) // or in the old window position frame (Absolute == FALSE). @@ -713,47 +715,47 @@ typedef struct _CONSOLE_SETWINDOWINFO typedef struct _CONSOLE_GETWINDOW { - HANDLE ConsoleHandle; - HWND WindowHandle; + LPC_HANDLE ConsoleHandle; + LPC_PTRTYPE(HWND) WindowHandle; } CONSOLE_GETWINDOW, *PCONSOLE_GETWINDOW; typedef struct _CONSOLE_SETICON { - HANDLE ConsoleHandle; - HICON IconHandle; + LPC_HANDLE ConsoleHandle; + LPC_PTRTYPE(HICON) IconHandle; } CONSOLE_SETICON, *PCONSOLE_SETICON; typedef struct _CONSOLE_ADDGETALIAS { - HANDLE ConsoleHandle; + LPC_HANDLE ConsoleHandle; USHORT SourceLength; USHORT TargetLength; // Also used for storing the number of bytes written. USHORT ExeLength; - PVOID Source; - PVOID Target; - PVOID ExeName; + LPC_PVOID Source; + LPC_PVOID Target; + LPC_PVOID ExeName; BOOLEAN Unicode; BOOLEAN Unicode2; } CONSOLE_ADDGETALIAS, *PCONSOLE_ADDGETALIAS; typedef struct _CONSOLE_GETALLALIASES { - HANDLE ConsoleHandle; + LPC_HANDLE ConsoleHandle; USHORT ExeLength; - PVOID ExeName; + LPC_PVOID ExeName; BOOLEAN Unicode; BOOLEAN Unicode2; ULONG AliasesBufferLength; - PVOID AliasesBuffer; + LPC_PVOID AliasesBuffer; } CONSOLE_GETALLALIASES, *PCONSOLE_GETALLALIASES; typedef struct _CONSOLE_GETALLALIASESLENGTH { - HANDLE ConsoleHandle; + LPC_HANDLE ConsoleHandle; USHORT ExeLength; - PVOID ExeName; + LPC_PVOID ExeName; ULONG Length; BOOLEAN Unicode; BOOLEAN Unicode2; @@ -761,15 +763,15 @@ typedef struct _CONSOLE_GETALLALIASESLENGTH typedef struct _CONSOLE_GETALIASESEXES { - HANDLE ConsoleHandle; + LPC_HANDLE ConsoleHandle; ULONG Length ; // ExeLength; // ExesLength - PVOID ExeNames; + LPC_PVOID ExeNames; BOOLEAN Unicode; } CONSOLE_GETALIASESEXES, *PCONSOLE_GETALIASESEXES; typedef struct _CONSOLE_GETALIASESEXESLENGTH { - HANDLE ConsoleHandle; + LPC_HANDLE ConsoleHandle; ULONG Length; BOOLEAN Unicode; } CONSOLE_GETALIASESEXESLENGTH, *PCONSOLE_GETALIASESEXESLENGTH; @@ -778,30 +780,30 @@ typedef struct _CONSOLE_GETALIASESEXESLENGTH typedef struct _CONSOLE_GETCOMMANDHISTORY { - HANDLE ConsoleHandle; + LPC_HANDLE ConsoleHandle; ULONG HistoryLength; - PVOID History; + LPC_PVOID History; USHORT ExeLength; - PVOID ExeName; + LPC_PVOID ExeName; BOOLEAN Unicode; BOOLEAN Unicode2; } CONSOLE_GETCOMMANDHISTORY, *PCONSOLE_GETCOMMANDHISTORY; typedef struct _CONSOLE_GETCOMMANDHISTORYLENGTH { - HANDLE ConsoleHandle; + LPC_HANDLE ConsoleHandle; ULONG HistoryLength; USHORT ExeLength; - PVOID ExeName; + LPC_PVOID ExeName; BOOLEAN Unicode; BOOLEAN Unicode2; } CONSOLE_GETCOMMANDHISTORYLENGTH, *PCONSOLE_GETCOMMANDHISTORYLENGTH; typedef struct _CONSOLE_EXPUNGECOMMANDHISTORY { - HANDLE ConsoleHandle; + LPC_HANDLE ConsoleHandle; USHORT ExeLength; - PVOID ExeName; + LPC_PVOID ExeName; BOOLEAN Unicode; BOOLEAN Unicode2; } CONSOLE_EXPUNGECOMMANDHISTORY, *PCONSOLE_EXPUNGECOMMANDHISTORY; @@ -815,17 +817,17 @@ typedef struct _CONSOLE_GETSETHISTORYINFO typedef struct _CONSOLE_SETHISTORYNUMBERCOMMANDS { - HANDLE ConsoleHandle; + LPC_HANDLE ConsoleHandle; ULONG NumCommands; USHORT ExeLength; - PVOID ExeName; + LPC_PVOID ExeName; BOOLEAN Unicode; BOOLEAN Unicode2; } CONSOLE_SETHISTORYNUMBERCOMMANDS, *PCONSOLE_SETHISTORYNUMBERCOMMANDS; typedef struct _CONSOLE_SETHISTORYMODE { - HANDLE ConsoleHandle; + LPC_HANDLE ConsoleHandle; ULONG Mode; } CONSOLE_SETHISTORYMODE, *PCONSOLE_SETHISTORYMODE; @@ -833,71 +835,71 @@ typedef struct _CONSOLE_SETHISTORYMODE typedef struct _CONSOLE_SETSCREENBUFFERSIZE { - HANDLE ConsoleHandle; - HANDLE OutputHandle; + LPC_HANDLE ConsoleHandle; + LPC_HANDLE OutputHandle; COORD Size; } CONSOLE_SETSCREENBUFFERSIZE, *PCONSOLE_SETSCREENBUFFERSIZE; typedef struct _CONSOLE_GETSELECTIONINFO { - HANDLE ConsoleHandle; + LPC_HANDLE ConsoleHandle; CONSOLE_SELECTION_INFO Info; } CONSOLE_GETSELECTIONINFO, *PCONSOLE_GETSELECTIONINFO; typedef struct _CONSOLE_GETINPUTOUTPUTCP { - HANDLE ConsoleHandle; + LPC_HANDLE ConsoleHandle; UINT CodePage; BOOL OutputCP; // TRUE : Output Code Page ; FALSE : Input Code Page } CONSOLE_GETINPUTOUTPUTCP, *PCONSOLE_GETINPUTOUTPUTCP; typedef struct _CONSOLE_SETINPUTOUTPUTCP { - HANDLE ConsoleHandle; + LPC_HANDLE ConsoleHandle; UINT CodePage; BOOL OutputCP; // TRUE : Output Code Page ; FALSE : Input Code Page - HANDLE EventHandle; + LPC_HANDLE EventHandle; } CONSOLE_SETINPUTOUTPUTCP, *PCONSOLE_SETINPUTOUTPUTCP; typedef struct _CONSOLE_GETLANGID { - HANDLE ConsoleHandle; + LPC_HANDLE ConsoleHandle; LANGID LangId; } CONSOLE_GETLANGID, *PCONSOLE_GETLANGID; typedef struct _CONSOLE_GETKBDLAYOUTNAME { - HANDLE ConsoleHandle; + LPC_HANDLE ConsoleHandle; CHAR LayoutBuffer[KL_NAMELENGTH * sizeof(WCHAR)]; // Can hold up to 9 wchars BOOL Ansi; } CONSOLE_GETKBDLAYOUTNAME, *PCONSOLE_GETKBDLAYOUTNAME; typedef struct _CONSOLE_REGISTERVDM { - HANDLE ConsoleHandle; + LPC_HANDLE ConsoleHandle; ULONG RegisterFlags; - HANDLE StartHardwareEvent; - HANDLE EndHardwareEvent; - HANDLE ErrorHardwareEvent; + LPC_HANDLE StartHardwareEvent; + LPC_HANDLE EndHardwareEvent; + LPC_HANDLE ErrorHardwareEvent; /* Unused member */ ULONG UnusedVar; ULONG VideoStateLength; - PVOID VideoState; // PVIDEO_HARDWARE_STATE_HEADER + LPC_PVOID VideoState; // PVIDEO_HARDWARE_STATE_HEADER /* Unused members */ - PVOID UnusedBuffer; + LPC_PVOID UnusedBuffer; ULONG UnusedBufferLength; COORD VDMBufferSize; - PVOID VDMBuffer; + LPC_PVOID VDMBuffer; } CONSOLE_REGISTERVDM, *PCONSOLE_REGISTERVDM; typedef struct _CONSOLE_REGISTERCONSOLEIME { - HANDLE ConsoleHandle; - HWND hWnd; + LPC_HANDLE ConsoleHandle; + LPC_PTRTYPE(HWND) hWnd; DWORD dwThreadId; DWORD cbDesktop; LPWSTR pDesktop; @@ -906,7 +908,7 @@ typedef struct _CONSOLE_REGISTERCONSOLEIME typedef struct _CONSOLE_UNREGISTERCONSOLEIME { - HANDLE ConsoleHandle; + LPC_HANDLE ConsoleHandle; DWORD dwThreadId; } CONSOLE_UNREGISTERCONSOLEIME, *PCONSOLE_UNREGISTERCONSOLEIME; @@ -914,7 +916,7 @@ typedef struct _CONSOLE_API_MESSAGE { PORT_MESSAGE Header; - PCSR_CAPTURE_BUFFER CsrCaptureData; + LPC_PTR(CSR_CAPTURE_BUFFER) CsrCaptureData; CSR_API_NUMBER ApiNumber; NTSTATUS Status; ULONG Reserved; diff --git a/sdk/include/reactos/subsys/win/winmsg.h b/sdk/include/reactos/subsys/win/winmsg.h index df6aa389e1e76..13a352753d216 100644 --- a/sdk/include/reactos/subsys/win/winmsg.h +++ b/sdk/include/reactos/subsys/win/winmsg.h @@ -40,7 +40,7 @@ typedef enum _USERSRV_API_NUMBER #define USERSRV_API_CONNECTINFO USERCONNECT #define PUSERSRV_API_CONNECTINFO PUSERCONNECT -#if defined(_M_IX86) +#if defined(_M_IX86) && !defined(BUILD_WOW6432) C_ASSERT(sizeof(USERSRV_API_CONNECTINFO) == 0x124); #endif diff --git a/sdk/include/reactos/undocshell.h b/sdk/include/reactos/undocshell.h index f5bd2cd7f2eff..52330f25123d2 100644 --- a/sdk/include/reactos/undocshell.h +++ b/sdk/include/reactos/undocshell.h @@ -19,6 +19,15 @@ #ifndef __WINE_UNDOCSHELL_H #define __WINE_UNDOCSHELL_H +#ifndef SHSTDAPI +#if defined(_SHELL32_) /* DECLSPEC_IMPORT disabled because of CORE-6504: */ || TRUE +#define SHSTDAPI_(type) type WINAPI +#else +#define SHSTDAPI_(type) EXTERN_C DECLSPEC_IMPORT type WINAPI +#endif +#define SHSTDAPI SHSTDAPI_(HRESULT) +#endif + #ifdef __cplusplus extern "C" { #endif /* defined(__cplusplus) */ @@ -78,6 +87,15 @@ BOOL WINAPI ILGetDisplayNameEx( LPVOID path, DWORD type); +#if (NTDDI_VERSION >= NTDDI_LONGHORN) || defined(_SHELL32_) +SHSTDAPI DisplayNameOfW( + _In_ IShellFolder *psf, + _In_ LPCITEMIDLIST pidl, + _In_ DWORD dwFlags, + _Out_ LPWSTR pszBuf, + _In_ UINT cchBuf); +#endif + LPITEMIDLIST WINAPI ILGlobalClone(LPCITEMIDLIST pidl); void WINAPI ILGlobalFree(LPITEMIDLIST pidl); LPITEMIDLIST WINAPI SHSimpleIDListFromPathA (LPCSTR lpszPath); //FIXME @@ -204,6 +222,8 @@ int WINAPI SHOutOfMemoryMessageBox( LPCSTR lpCaption, UINT uType); +HRESULT WINAPI SHShouldShowWizards(_In_ IUnknown *pUnknown); + DWORD WINAPI SHNetConnectionDialog( HWND hwndOwner, LPCWSTR lpstrRemoteName, @@ -211,6 +231,11 @@ DWORD WINAPI SHNetConnectionDialog( BOOL WINAPI SHIsTempDisplayMode(VOID); +HRESULT WINAPI +SHGetUserDisplayName( + _Out_writes_to_(*puSize, *puSize) PWSTR pName, + _Inout_ PULONG puSize); + /**************************************************************************** * Cabinet Window Messages */ @@ -705,6 +730,27 @@ RealShellExecuteExW( _Out_opt_ PHANDLE lphProcess, _In_ DWORD dwFlags); +VOID WINAPI +ShellExec_RunDLL( + _In_opt_ HWND hwnd, + _In_opt_ HINSTANCE hInstance, + _In_ PCSTR pszCmdLine, + _In_ INT nCmdShow); + +VOID WINAPI +ShellExec_RunDLLA( + _In_opt_ HWND hwnd, + _In_opt_ HINSTANCE hInstance, + _In_ PCSTR pszCmdLine, + _In_ INT nCmdShow); + +VOID WINAPI +ShellExec_RunDLLW( + _In_opt_ HWND hwnd, + _In_opt_ HINSTANCE hInstance, + _In_ PCWSTR pszCmdLine, + _In_ INT nCmdShow); + /* RegisterShellHook types */ #define RSH_DEREGISTER 0 #define RSH_REGISTER 1 @@ -766,6 +812,18 @@ BOOL WINAPI GUIDFromStringW( _In_ PCWSTR psz, _Out_ LPGUID pguid); +PSTR WINAPI +StrRStrA( + _In_ PCSTR pszSrc, + _In_opt_ PCSTR pszLast, + _In_ PCSTR pszSearch); + +PWSTR WINAPI +StrRStrW( + _In_ PCWSTR pszSrc, + _In_opt_ PCWSTR pszLast, + _In_ PCWSTR pszSearch); + LPSTR WINAPI SheRemoveQuotesA(LPSTR psz); LPWSTR WINAPI SheRemoveQuotesW(LPWSTR psz); @@ -888,7 +946,6 @@ BOOL WINAPI SHSettingsChanged(LPCVOID unused, LPCWSTR pszKey); #define TABDMC_LOADINPROC 2 void WINAPI ShellDDEInit(BOOL bInit); -DWORD WINAPI WinList_Init(void); IStream* WINAPI SHGetViewStream(LPCITEMIDLIST, DWORD, LPCTSTR, LPCTSTR, LPCTSTR); @@ -914,6 +971,11 @@ LONG WINAPI SHRegQueryValueExW( #define SHRegQueryValueEx SHRegQueryValueExA #endif +BOOL WINAPI +SHIsBadInterfacePtr( + _In_ LPCVOID pv, + _In_ UINT_PTR ucb); + HRESULT WINAPI CopyStreamUI( _In_ IStream *pSrc, @@ -921,6 +983,17 @@ CopyStreamUI( _Inout_opt_ IProgressDialog *pProgress, _In_opt_ DWORDLONG dwlSize); +// Flags for SHGetComputerDisplayNameW +#define SHGCDN_NOCACHE 0x1 +#define SHGCDN_NOSERVERNAME 0x10000 + +HRESULT WINAPI +SHGetComputerDisplayNameW( + _In_opt_ LPWSTR pszServerName, + _In_ DWORD dwFlags, + _Out_writes_z_(cchNameMax) LPWSTR pszName, + _In_ DWORD cchNameMax); + /***************************************************************************** * INVALID_FILETITLE_CHARACTERS */ diff --git a/sdk/include/reactos/uxundoc.h b/sdk/include/reactos/uxundoc.h index ed3ed4368ff04..2c6e23cb22b2e 100644 --- a/sdk/include/reactos/uxundoc.h +++ b/sdk/include/reactos/uxundoc.h @@ -1,7 +1,23 @@ #pragma once +#ifdef __cplusplus +extern "C" { +#endif + typedef HANDLE HTHEMEFILE; +typedef struct tagPARSE_ERROR_INFO +{ + DWORD cbSize; + UINT nID; + WCHAR szDescription[2 * MAX_PATH]; + WCHAR szFile[MAX_PATH]; + WCHAR szLine[MAX_PATH]; + INT nLineNo; +} PARSE_ERROR_INFO, *PPARSE_ERROR_INFO; + +HRESULT WINAPI GetThemeParseErrorInfo(_Inout_ PPARSE_ERROR_INFO pInfo); + /********************************************************************** * ENUMTHEMEPROC * @@ -118,3 +134,6 @@ BOOL WINAPI ThemeHooksInstall(VOID); BOOL WINAPI ThemeHooksRemove(VOID); +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/sdk/include/reactos/verifier.h b/sdk/include/reactos/verifier.h index 112f9dd9b9225..a3c2556b7eef0 100644 --- a/sdk/include/reactos/verifier.h +++ b/sdk/include/reactos/verifier.h @@ -84,21 +84,103 @@ typedef struct _RTL_VERIFIER_PROVIDER_DESCRIPTOR { #define RTL_VRF_DBG_ENTRYPOINT_CALLS 0x20000 -// Verifier stop codes - -#define APPLICATION_VERIFIER_CORRUPT_HEAP_POINTER 0x0006 -#define APPLICATION_VERIFIER_DOUBLE_FREE 0x0007 - -#define APPLICATION_VERIFIER_EXCEPTION_WHILE_VERIFYING_BLOCK_HEADER 0x000B -#define APPLICATION_VERIFIER_CORRUPTED_HEAP_BLOCK_AFTER_FREE 0x000D -#define APPLICATION_VERIFIER_CORRUPTED_INFIX_PATTERN 0x000E -#define APPLICATION_VERIFIER_CORRUPTED_SUFFIX_PATTERN 0x000F -#define APPLICATION_VERIFIER_CORRUPTED_START_STAMP 0x0010 -#define APPLICATION_VERIFIER_CORRUPTED_END_STAMP 0x0011 -#define APPLICATION_VERIFIER_CORRUPTED_PREFIX_PATTERN 0x0012 - -VOID NTAPI +// Verifier stop codes +#define APPLICATION_VERIFIER_INTERNAL_ERROR 0x80000000 +#define APPLICATION_VERIFIER_INTERNAL_WARNING 0x40000000 +#define APPLICATION_VERIFIER_NO_BREAK 0x20000000 +#define APPLICATION_VERIFIER_CONTINUABLE_BREAK 0x10000000 + +#define APPLICATION_VERIFIER_UNKNOWN_ERROR 0x0001 +#define APPLICATION_VERIFIER_ACCESS_VIOLATION 0x0002 +#define APPLICATION_VERIFIER_UNSYNCHRONIZED_ACCESS 0x0003 +#define APPLICATION_VERIFIER_EXTREME_SIZE_REQUEST 0x0004 +#define APPLICATION_VERIFIER_BAD_HEAP_HANDLE 0x0005 +#define APPLICATION_VERIFIER_SWITCHED_HEAP_HANDLE 0x0006 +#define APPLICATION_VERIFIER_DOUBLE_FREE 0x0007 +#define APPLICATION_VERIFIER_CORRUPTED_HEAP_BLOCK 0x0008 +#define APPLICATION_VERIFIER_DESTROY_PROCESS_HEAP 0x0009 +#define APPLICATION_VERIFIER_UNEXPECTED_EXCEPTION 0x000A +#define APPLICATION_VERIFIER_CORRUPTED_HEAP_BLOCK_EXCEPTION_RAISED_FOR_HEADER 0x000B +#define APPLICATION_VERIFIER_CORRUPTED_HEAP_BLOCK_EXCEPTION_RAISED_FOR_PROBING 0x000C +#define APPLICATION_VERIFIER_CORRUPTED_HEAP_BLOCK_HEADER 0x000D +#define APPLICATION_VERIFIER_CORRUPTED_FREED_HEAP_BLOCK 0x000E +#define APPLICATION_VERIFIER_CORRUPTED_HEAP_BLOCK_SUFFIX 0x000F +#define APPLICATION_VERIFIER_CORRUPTED_HEAP_BLOCK_START_STAMP 0x0010 +#define APPLICATION_VERIFIER_CORRUPTED_HEAP_BLOCK_END_STAMP 0x0011 +#define APPLICATION_VERIFIER_CORRUPTED_HEAP_BLOCK_PREFIX 0x0012 +#define APPLICATION_VERIFIER_FIRST_CHANCE_ACCESS_VIOLATION 0x0013 +#define APPLICATION_VERIFIER_CORRUPTED_HEAP_LIST 0x0014 + +#define APPLICATION_VERIFIER_TERMINATE_THREAD_CALL 0x0100 +#define APPLICATION_VERIFIER_STACK_OVERFLOW 0x0101 +#define APPLICATION_VERIFIER_INVALID_EXIT_PROCESS_CALL 0x0102 + +#define APPLICATION_VERIFIER_EXIT_THREAD_OWNS_LOCK 0x0200 +#define APPLICATION_VERIFIER_LOCK_IN_UNLOADED_DLL 0x0201 +#define APPLICATION_VERIFIER_LOCK_IN_FREED_HEAP 0x0202 +#define APPLICATION_VERIFIER_LOCK_DOUBLE_INITIALIZE 0x0203 +#define APPLICATION_VERIFIER_LOCK_IN_FREED_MEMORY 0x0204 +#define APPLICATION_VERIFIER_LOCK_CORRUPTED 0x0205 +#define APPLICATION_VERIFIER_LOCK_INVALID_OWNER 0x0206 +#define APPLICATION_VERIFIER_LOCK_INVALID_RECURSION_COUNT 0x0207 +#define APPLICATION_VERIFIER_LOCK_INVALID_LOCK_COUNT 0x0208 +#define APPLICATION_VERIFIER_LOCK_OVER_RELEASED 0x0209 +#define APPLICATION_VERIFIER_LOCK_NOT_INITIALIZED 0x0210 +#define APPLICATION_VERIFIER_LOCK_ALREADY_INITIALIZED 0x0211 +#define APPLICATION_VERIFIER_LOCK_IN_FREED_VMEM 0x0212 +#define APPLICATION_VERIFIER_LOCK_IN_UNMAPPED_MEM 0x0213 +#define APPLICATION_VERIFIER_THREAD_NOT_LOCK_OWNER 0x0214 + +#define APPLICATION_VERIFIER_INVALID_HANDLE 0x0300 +#define APPLICATION_VERIFIER_INVALID_TLS_VALUE 0x0301 +#define APPLICATION_VERIFIER_INCORRECT_WAIT_CALL 0x0302 +#define APPLICATION_VERIFIER_NULL_HANDLE 0x0303 +#define APPLICATION_VERIFIER_WAIT_IN_DLLMAIN 0x0304 + +#define APPLICATION_VERIFIER_COM_ERROR 0x0400 +#define APPLICATION_VERIFIER_COM_API_IN_DLLMAIN 0x0401 +#define APPLICATION_VERIFIER_COM_UNHANDLED_EXCEPTION 0x0402 +#define APPLICATION_VERIFIER_COM_UNBALANCED_COINIT 0x0403 +#define APPLICATION_VERIFIER_COM_UNBALANCED_OLEINIT 0x0404 +#define APPLICATION_VERIFIER_COM_UNBALANCED_SWC 0x0405 +#define APPLICATION_VERIFIER_COM_NULL_DACL 0x0406 +#define APPLICATION_VERIFIER_COM_UNSAFE_IMPERSONATION 0x0407 +#define APPLICATION_VERIFIER_COM_SMUGGLED_WRAPPER 0x0408 +#define APPLICATION_VERIFIER_COM_SMUGGLED_PROXY 0x0409 +#define APPLICATION_VERIFIER_COM_CF_SUCCESS_WITH_NULL 0x040A +#define APPLICATION_VERIFIER_COM_GCO_SUCCESS_WITH_NULL 0x040B +#define APPLICATION_VERIFIER_COM_OBJECT_IN_FREED_MEMORY 0x040C +#define APPLICATION_VERIFIER_COM_OBJECT_IN_UNLOADED_DLL 0x040D +#define APPLICATION_VERIFIER_COM_VTBL_IN_FREED_MEMORY 0x040E +#define APPLICATION_VERIFIER_COM_VTBL_IN_UNLOADED_DLL 0x040F +#define APPLICATION_VERIFIER_COM_HOLDING_LOCKS_ON_CALL 0x0410 + +#define APPLICATION_VERIFIER_RPC_ERROR 0x0500 + +#define APPLICATION_VERIFIER_INVALID_FREEMEM 0x0600 +#define APPLICATION_VERIFIER_INVALID_ALLOCMEM 0x0601 +#define APPLICATION_VERIFIER_INVALID_MAPVIEW 0x0602 +#define APPLICATION_VERIFIER_PROBE_INVALID_ADDRESS 0x0603 +#define APPLICATION_VERIFIER_PROBE_FREE_MEM 0x0604 +#define APPLICATION_VERIFIER_PROBE_GUARD_PAGE 0x0605 +#define APPLICATION_VERIFIER_PROBE_NULL 0x0606 +#define APPLICATION_VERIFIER_PROBE_INVALID_START_OR_SIZE 0x0607 +#define APPLICATION_VERIFIER_SIZE_HEAP_UNEXPECTED_EXCEPTION 0x0618 + +#define VERIFIER_STOP(Code, Msg, Val1, Desc1, Val2, Desc2, Val3, Desc3, Val4, Desc4) \ + do { \ + RtlApplicationVerifierStop((Code), \ + (Msg), \ + (Val1), (Desc1), \ + (Val2), (Desc2), \ + (Val3), (Desc3), \ + (Val4), (Desc4)); \ + } while (0) + + +VOID +NTAPI RtlApplicationVerifierStop( _In_ ULONG_PTR Code, _In_ PCSTR Message, diff --git a/sdk/include/reactos/version.cmake b/sdk/include/reactos/version.cmake index c06d0919cd19c..68cfeafeb85fd 100644 --- a/sdk/include/reactos/version.cmake +++ b/sdk/include/reactos/version.cmake @@ -9,7 +9,7 @@ endif() set(KERNEL_VERSION_MAJOR "0") set(KERNEL_VERSION_MINOR "4") set(KERNEL_VERSION_PATCH_LEVEL "16") -set(COPYRIGHT_YEAR "2024") +set(COPYRIGHT_YEAR "2025") # KERNEL_VERSION_BUILD_TYPE is "dev" for Git builds # or "RC1", "RC2", "" for releases. diff --git a/sdk/include/reactos/wine/exception.h b/sdk/include/reactos/wine/exception.h index f9333e8ff2a29..409d1e644075b 100644 --- a/sdk/include/reactos/wine/exception.h +++ b/sdk/include/reactos/wine/exception.h @@ -3,10 +3,7 @@ #include #include -#ifdef __USE_PSEH2__ -# include -# include -#endif +#include #ifdef __cplusplus extern "C" { @@ -58,12 +55,11 @@ typedef struct _WINE_EXCEPTION_REGISTRATION_RECORD #define PEXCEPTION_REGISTRATION_RECORD PWINE_EXCEPTION_REGISTRATION_RECORD #endif -#ifdef __USE_PSEH2__ #define __TRY _SEH2_TRY #define __EXCEPT(func) _SEH2_EXCEPT(func(_SEH2_GetExceptionInformation())) #define __EXCEPT_CTX(func, ctx) _SEH2_EXCEPT((func)(GetExceptionInformation(), ctx)) #define __EXCEPT_PAGE_FAULT _SEH2_EXCEPT(_SEH2_GetExceptionCode() == STATUS_ACCESS_VIOLATION) -#define __EXCEPT_ALL _SEH2_EXCEPT(_SEH_EXECUTE_HANDLER) +#define __EXCEPT_ALL _SEH2_EXCEPT(1) #define __ENDTRY _SEH2_END #define __FINALLY(func) _SEH2_FINALLY { func(!_SEH2_AbnormalTermination()); } #define __FINALLY_CTX(func, ctx) _SEH2_FINALLY { func(!_SEH2_AbnormalTermination(), ctx); }; _SEH2_END @@ -79,16 +75,6 @@ typedef struct _WINE_EXCEPTION_REGISTRATION_RECORD #ifndef AbnormalTermination #define AbnormalTermination() _SEH2_AbnormalTermination() #endif -#else -#define __TRY __try -#define __EXCEPT(func) __except(func(GetExceptionInformation())) -#define __EXCEPT_CTX(func, ctx) __except((func)(GetExceptionInformation(), ctx)) -#define __EXCEPT_PAGE_FAULT __except(GetExceptionCode() == STATUS_ACCESS_VIOLATION) -#define __EXCEPT_ALL __except(1) -#define __ENDTRY -#define __FINALLY(func) __finally { func(!AbnormalTermination()); } -#define __FINALLY_CTX(func, ctx) __finally { func(!AbnormalTermination(), ctx); } -#endif #if defined(__MINGW32__) || defined(__CYGWIN__) #define sigjmp_buf jmp_buf diff --git a/sdk/include/reactos/wine/test.h b/sdk/include/reactos/wine/test.h index 872ab75378a3d..7dbd2845f996f 100644 --- a/sdk/include/reactos/wine/test.h +++ b/sdk/include/reactos/wine/test.h @@ -156,12 +156,14 @@ extern void winetest_pop_context(void); #define skip_(file, line) (winetest_set_location(file, line), 0) ? (void)0 : winetest_skip #define win_skip_(file, line) (winetest_set_location(file, line), 0) ? (void)0 : winetest_win_skip #define trace_(file, line) (winetest_set_location(file, line), 0) ? (void)0 : winetest_trace +#define wait_child_process_(file, line) (winetest_set_location(file, line), 0) ? (void)0 : winetest_wait_child_process #define subtest subtest_(__FILE__, __LINE__) #define ok ok_(__FILE__, __LINE__) #define skip skip_(__FILE__, __LINE__) #define win_skip win_skip_(__FILE__, __LINE__) #define trace trace_(__FILE__, __LINE__) +#define wait_child_process wait_child_process_(__FILE__, __LINE__) #define todo_if(is_todo) for (winetest_start_todo(is_todo); \ winetest_loop_todo(); \ @@ -185,6 +187,9 @@ extern void winetest_pop_context(void); winetest_loop_nocount(); \ winetest_end_nocount()) +#define skip_2k3_crash if (_winver < 0x600) skip("Test skipped, because it crashes on win 2003\n"); else +#define skip_2k3_fail if (_winver < 0x600) skip("Test skipped, because it fails on win 2003\n"); else + #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) #ifdef NONAMELESSUNION @@ -747,7 +752,7 @@ const char *wine_dbgstr_wn( const WCHAR *str, intptr_t n ) } *dst = 0; - res = get_temp_buffer(strlen(buffer + 1)); + res = get_temp_buffer(strlen(buffer) + 1); strcpy(res, buffer); return res; } diff --git a/sdk/include/reactos/x86x64/Cpuid.h b/sdk/include/reactos/x86x64/Cpuid.h index 39ece442c99e3..3c317ccea6215 100644 --- a/sdk/include/reactos/x86x64/Cpuid.h +++ b/sdk/include/reactos/x86x64/Cpuid.h @@ -112,7 +112,7 @@ typedef union CPUID_EXTENDED_STATE_SUB_LEAF_ECX Ecx; UINT32 Edx; // Reports the supported bits of the upper 32 bits of the IA32_XSS MSR. IA32_XSS[n + 32] can be set to 1 only if EDX[n] is 1. }; -} CPUID_EXTENDED_STATE_SUB_LEAF_EAX_REGS; +} CPUID_EXTENDED_STATE_SUB_LEAF_REGS; // CPUID_EXTENDED_CPU_SIG (0x80000001) typedef union diff --git a/sdk/include/ucrt/assert.h b/sdk/include/ucrt/assert.h new file mode 100644 index 0000000000000..be5dbfca7f8fb --- /dev/null +++ b/sdk/include/ucrt/assert.h @@ -0,0 +1,50 @@ +// +// assert.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// Defines the assert macro and related functionality. +// +#if defined _VCRT_BUILD && !defined _ASSERT_OK + #error assert.h not for CRT internal use +#endif + +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS +_CRT_BEGIN_C_HEADER + +#if _CRT_HAS_C11 + +#define static_assert _Static_assert + +#endif // _CRT_HAS_C11 + +#undef assert + +#ifdef NDEBUG + + #define assert(expression) ((void)0) + +#else + + _ACRTIMP void __cdecl _wassert( + _In_z_ wchar_t const* _Message, + _In_z_ wchar_t const* _File, + _In_ unsigned _Line + ); + + #define assert(expression) (void)( \ + (!!(expression)) || \ + (_wassert(_CRT_WIDE(#expression), _CRT_WIDE(__FILE__), (unsigned)(__LINE__)), 0) \ + ) + +#endif + + + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS diff --git a/sdk/include/ucrt/complex.h b/sdk/include/ucrt/complex.h new file mode 100644 index 0000000000000..72ee07b1c42db --- /dev/null +++ b/sdk/include/ucrt/complex.h @@ -0,0 +1,580 @@ +// +// complex.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The complex math library. +// +#pragma once +#ifndef _COMPLEX +#define _COMPLEX + +#include + +#if (_CRT_HAS_CXX17 == 1) && !defined(_CRT_USE_C_COMPLEX_H) +#include +#else // ^^^^ /std:c++17 ^^^^ // vvvv _CRT_USE_C_COMPLEX_H vvvv + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Types +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#ifndef _C_COMPLEX_T + #define _C_COMPLEX_T + typedef struct _C_double_complex + { + double _Val[2]; + } _C_double_complex; + + typedef struct _C_float_complex + { + float _Val[2]; + } _C_float_complex; + + typedef struct _C_ldouble_complex + { + long double _Val[2]; + } _C_ldouble_complex; +#endif + +typedef _C_double_complex _Dcomplex; +typedef _C_float_complex _Fcomplex; +typedef _C_ldouble_complex _Lcomplex; + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Macros +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#define _DCOMPLEX_(re, im) _Cbuild(re, im) +#define _FCOMPLEX_(re, im) _FCbuild(re, im) +#define _LCOMPLEX_(re, im) _LCbuild(re, im) + +#define _Complex_I _FCbuild(0.0F, 1.0F) +#define I _Complex_I + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Functions +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +_ACRTIMP double __cdecl cabs(_In_ _Dcomplex _Z); +_ACRTIMP _Dcomplex __cdecl cacos(_In_ _Dcomplex _Z); +_ACRTIMP _Dcomplex __cdecl cacosh(_In_ _Dcomplex _Z); +_ACRTIMP double __cdecl carg(_In_ _Dcomplex _Z); +_ACRTIMP _Dcomplex __cdecl casin(_In_ _Dcomplex _Z); +_ACRTIMP _Dcomplex __cdecl casinh(_In_ _Dcomplex _Z); +_ACRTIMP _Dcomplex __cdecl catan(_In_ _Dcomplex _Z); +_ACRTIMP _Dcomplex __cdecl catanh(_In_ _Dcomplex _Z); +_ACRTIMP _Dcomplex __cdecl ccos(_In_ _Dcomplex _Z); +_ACRTIMP _Dcomplex __cdecl ccosh(_In_ _Dcomplex _Z); +_ACRTIMP _Dcomplex __cdecl cexp(_In_ _Dcomplex _Z); +_ACRTIMP double __cdecl cimag(_In_ _Dcomplex _Z); +_ACRTIMP _Dcomplex __cdecl clog(_In_ _Dcomplex _Z); +_ACRTIMP _Dcomplex __cdecl clog10(_In_ _Dcomplex _Z); +_ACRTIMP _Dcomplex __cdecl conj(_In_ _Dcomplex _Z); +_ACRTIMP _Dcomplex __cdecl cpow(_In_ _Dcomplex _X, _In_ _Dcomplex _Y); +_ACRTIMP _Dcomplex __cdecl cproj(_In_ _Dcomplex _Z); +_ACRTIMP double __cdecl creal(_In_ _Dcomplex _Z); +_ACRTIMP _Dcomplex __cdecl csin(_In_ _Dcomplex _Z); +_ACRTIMP _Dcomplex __cdecl csinh(_In_ _Dcomplex _Z); +_ACRTIMP _Dcomplex __cdecl csqrt(_In_ _Dcomplex _Z); +_ACRTIMP _Dcomplex __cdecl ctan(_In_ _Dcomplex _Z); +_ACRTIMP _Dcomplex __cdecl ctanh(_In_ _Dcomplex _Z); +_ACRTIMP double __cdecl norm(_In_ _Dcomplex _Z); + +_ACRTIMP float __cdecl cabsf(_In_ _Fcomplex _Z); +_ACRTIMP _Fcomplex __cdecl cacosf(_In_ _Fcomplex _Z); +_ACRTIMP _Fcomplex __cdecl cacoshf(_In_ _Fcomplex _Z); +_ACRTIMP float __cdecl cargf(_In_ _Fcomplex _Z); +_ACRTIMP _Fcomplex __cdecl casinf(_In_ _Fcomplex _Z); +_ACRTIMP _Fcomplex __cdecl casinhf(_In_ _Fcomplex _Z); +_ACRTIMP _Fcomplex __cdecl catanf(_In_ _Fcomplex _Z); +_ACRTIMP _Fcomplex __cdecl catanhf(_In_ _Fcomplex _Z); +_ACRTIMP _Fcomplex __cdecl ccosf(_In_ _Fcomplex _Z); +_ACRTIMP _Fcomplex __cdecl ccoshf(_In_ _Fcomplex _Z); +_ACRTIMP _Fcomplex __cdecl cexpf(_In_ _Fcomplex _Z); +_ACRTIMP float __cdecl cimagf(_In_ _Fcomplex _Z); +_ACRTIMP _Fcomplex __cdecl clogf(_In_ _Fcomplex _Z); +_ACRTIMP _Fcomplex __cdecl clog10f(_In_ _Fcomplex _Z); +_ACRTIMP _Fcomplex __cdecl conjf(_In_ _Fcomplex _Z); +_ACRTIMP _Fcomplex __cdecl cpowf(_In_ _Fcomplex _X, _In_ _Fcomplex _Y); +_ACRTIMP _Fcomplex __cdecl cprojf(_In_ _Fcomplex _Z); +_ACRTIMP float __cdecl crealf(_In_ _Fcomplex _Z); +_ACRTIMP _Fcomplex __cdecl csinf(_In_ _Fcomplex _Z); +_ACRTIMP _Fcomplex __cdecl csinhf(_In_ _Fcomplex _Z); +_ACRTIMP _Fcomplex __cdecl csqrtf(_In_ _Fcomplex _Z); +_ACRTIMP _Fcomplex __cdecl ctanf(_In_ _Fcomplex _Z); +_ACRTIMP _Fcomplex __cdecl ctanhf(_In_ _Fcomplex _Z); +_ACRTIMP float __cdecl normf(_In_ _Fcomplex _Z); + +_ACRTIMP long double __cdecl cabsl(_In_ _Lcomplex _Z); +_ACRTIMP _Lcomplex __cdecl cacosl(_In_ _Lcomplex _Z); +_ACRTIMP _Lcomplex __cdecl cacoshl(_In_ _Lcomplex _Z); +_ACRTIMP long double __cdecl cargl(_In_ _Lcomplex _Z); +_ACRTIMP _Lcomplex __cdecl casinl(_In_ _Lcomplex _Z); +_ACRTIMP _Lcomplex __cdecl casinhl(_In_ _Lcomplex _Z); +_ACRTIMP _Lcomplex __cdecl catanl(_In_ _Lcomplex _Z); +_ACRTIMP _Lcomplex __cdecl catanhl(_In_ _Lcomplex _Z); +_ACRTIMP _Lcomplex __cdecl ccosl(_In_ _Lcomplex _Z); +_ACRTIMP _Lcomplex __cdecl ccoshl(_In_ _Lcomplex _Z); +_ACRTIMP _Lcomplex __cdecl cexpl(_In_ _Lcomplex _Z); +_ACRTIMP long double __cdecl cimagl(_In_ _Lcomplex _Z); +_ACRTIMP _Lcomplex __cdecl clogl(_In_ _Lcomplex _Z); +_ACRTIMP _Lcomplex __cdecl clog10l(_In_ _Lcomplex _Z); +_ACRTIMP _Lcomplex __cdecl conjl(_In_ _Lcomplex _Z); +_ACRTIMP _Lcomplex __cdecl cpowl(_In_ _Lcomplex _X, _In_ _Lcomplex _Y); +_ACRTIMP _Lcomplex __cdecl cprojl(_In_ _Lcomplex _Z); +_ACRTIMP long double __cdecl creall(_In_ _Lcomplex _Z); +_ACRTIMP _Lcomplex __cdecl csinl(_In_ _Lcomplex _Z); +_ACRTIMP _Lcomplex __cdecl csinhl(_In_ _Lcomplex _Z); +_ACRTIMP _Lcomplex __cdecl csqrtl(_In_ _Lcomplex _Z); +_ACRTIMP _Lcomplex __cdecl ctanl(_In_ _Lcomplex _Z); +_ACRTIMP _Lcomplex __cdecl ctanhl(_In_ _Lcomplex _Z); +_ACRTIMP long double __cdecl norml(_In_ _Lcomplex _Z); + +_ACRTIMP _Dcomplex __cdecl _Cbuild(_In_ double _Re, _In_ double _Im); +_ACRTIMP _Dcomplex __cdecl _Cmulcc(_In_ _Dcomplex _X, _In_ _Dcomplex _Y); +_ACRTIMP _Dcomplex __cdecl _Cmulcr(_In_ _Dcomplex _X, _In_ double _Y); + +_ACRTIMP _Fcomplex __cdecl _FCbuild(_In_ float _Re, _In_ float _Im); +_ACRTIMP _Fcomplex __cdecl _FCmulcc(_In_ _Fcomplex _X, _In_ _Fcomplex _Y); +_ACRTIMP _Fcomplex __cdecl _FCmulcr(_In_ _Fcomplex _X, _In_ float _Y); + +_ACRTIMP _Lcomplex __cdecl _LCbuild(_In_ long double _Re, _In_ long double _Im); +_ACRTIMP _Lcomplex __cdecl _LCmulcc(_In_ _Lcomplex _X, _In_ _Lcomplex _Y); +_ACRTIMP _Lcomplex __cdecl _LCmulcr(_In_ _Lcomplex _X, _In_ long double _Y); + + + +#ifdef __cplusplus +extern "C++" +{ + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + // double complex overloads + // + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + inline _Dcomplex __CRTDECL acos(_In_ _Dcomplex _X) throw() + { + return cacos(_X); + } + + inline _Dcomplex __CRTDECL acosh(_In_ _Dcomplex _X) throw() + { + return cacosh(_X); + } + + inline _Dcomplex __CRTDECL asin(_In_ _Dcomplex _X) throw() + { + return casin(_X); + } + + inline _Dcomplex __CRTDECL asinh(_In_ _Dcomplex _X) throw() + { + return casinh(_X); + } + + inline _Dcomplex __CRTDECL atan(_In_ _Dcomplex _X) throw() + { + return catan(_X); + } + + inline _Dcomplex __CRTDECL atanh(_In_ _Dcomplex _X) throw() + { + return catanh(_X); + } + + inline _Dcomplex __CRTDECL cos(_In_ _Dcomplex _X) throw() + { + return ccos(_X); + } + + inline _Dcomplex __CRTDECL cosh(_In_ _Dcomplex _X) throw() + { + return ccosh(_X); + } + + inline _Dcomplex __CRTDECL proj(_In_ _Dcomplex _X) throw() + { + return cproj(_X); + } + + inline _Dcomplex __CRTDECL exp(_In_ _Dcomplex _X) throw() + { + return cexp(_X); + } + + inline _Dcomplex __CRTDECL log(_In_ _Dcomplex _X) throw() + { + return clog(_X); + } + + inline _Dcomplex __CRTDECL log10(_In_ _Dcomplex _X) throw() + { + return clog10(_X); + } + + inline _Dcomplex __CRTDECL pow(_In_ _Dcomplex _X, _In_ _Dcomplex _Y) throw() + { + return cpow(_X, _Y); + } + + inline _Dcomplex __CRTDECL sin(_In_ _Dcomplex _X) throw() + { + return csin(_X); + } + + inline _Dcomplex __CRTDECL sinh(_In_ _Dcomplex _X) throw() + { + return csinh(_X); + } + + inline _Dcomplex __CRTDECL sqrt(_In_ _Dcomplex _X) throw() + { + return csqrt(_X); + } + + inline _Dcomplex __CRTDECL tan(_In_ _Dcomplex _X) throw() + { + return ctan(_X); + } + + inline _Dcomplex __CRTDECL tanh(_In_ _Dcomplex _X) throw() + { + return ctanh(_X); + } + + inline double __CRTDECL abs(_In_ _Dcomplex _X) throw() + { + return cabs(_X); + } + + inline double __CRTDECL arg(_In_ _Dcomplex _X) throw() + { + return carg(_X); + } + + inline double __CRTDECL imag(_In_ _Dcomplex _X) throw() + { + return cimag(_X); + } + + inline double __CRTDECL real(_In_ _Dcomplex _X) throw() + { + return creal(_X); + } + + + + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + // float complex overloads + // + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + inline _Fcomplex __CRTDECL acos(_In_ _Fcomplex _X) throw() + { + return cacosf(_X); + } + + inline _Fcomplex __CRTDECL acosh(_In_ _Fcomplex _X) throw() + { + return cacoshf(_X); + } + + inline _Fcomplex __CRTDECL asin(_In_ _Fcomplex _X) throw() + { + return casinf(_X); + } + + inline _Fcomplex __CRTDECL asinh(_In_ _Fcomplex _X) throw() + { + return casinhf(_X); + } + + inline _Fcomplex __CRTDECL atan(_In_ _Fcomplex _X) throw() + { + return catanf(_X); + } + + inline _Fcomplex __CRTDECL atanh(_In_ _Fcomplex _X) throw() + { + return catanhf(_X); + } + + inline _Fcomplex __CRTDECL conj(_In_ _Fcomplex _X) throw() + { + return conjf(_X); + } + + inline _Fcomplex __CRTDECL cos(_In_ _Fcomplex _X) throw() + { + return ccosf(_X); + } + + inline _Fcomplex __CRTDECL cosh(_In_ _Fcomplex _X) throw() + { + return ccoshf(_X); + } + + inline _Fcomplex __CRTDECL cproj(_In_ _Fcomplex _X) throw() + { + return cprojf(_X); + } + + inline _Fcomplex __CRTDECL proj(_In_ _Fcomplex _X) throw() + { + return cprojf(_X); + } + + inline _Fcomplex __CRTDECL exp(_In_ _Fcomplex _X) throw() + { + return cexpf(_X); + } + + inline _Fcomplex __CRTDECL log(_In_ _Fcomplex _X) throw() + { + return clogf(_X); + } + + inline _Fcomplex __CRTDECL log10(_In_ _Fcomplex _X) throw() + { + return clog10f(_X); + } + + inline float __CRTDECL norm(_In_ _Fcomplex _X) throw() + { + return normf(_X); + } + + inline _Fcomplex __CRTDECL pow(_In_ _Fcomplex _X, _In_ _Fcomplex _Y) throw() + { + return cpowf(_X, _Y); + } + + inline _Fcomplex __CRTDECL sin(_In_ _Fcomplex _X) throw() + { + return csinf(_X); + } + + inline _Fcomplex __CRTDECL sinh(_In_ _Fcomplex _X) throw() + { + return csinhf(_X); + } + + inline _Fcomplex __CRTDECL sqrt(_In_ _Fcomplex _X) throw() + { + return csqrtf(_X); + } + + inline _Fcomplex __CRTDECL tan(_In_ _Fcomplex _X) throw() + { + return ctanf(_X); + } + + inline _Fcomplex __CRTDECL tanh(_In_ _Fcomplex _X) throw() + { + return ctanhf(_X); + } + + inline float __CRTDECL abs(_In_ _Fcomplex _X) throw() + { + return cabsf(_X); + } + + inline float __CRTDECL arg(_In_ _Fcomplex _X) throw() + { + return cargf(_X); + } + + inline float __CRTDECL carg(_In_ _Fcomplex _X) throw() + { + return cargf(_X); + } + + inline float __CRTDECL cimag(_In_ _Fcomplex _X) throw() + { + return cimagf(_X); + } + + inline float __CRTDECL creal(_In_ _Fcomplex _X) throw() + { + return crealf(_X); + } + + inline float __CRTDECL imag(_In_ _Fcomplex _X) throw() + { + return cimagf(_X); + } + + inline float __CRTDECL real(_In_ _Fcomplex _X) throw() + { + return crealf(_X); + } + + + + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + // long double complex overloads + // + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + inline _Lcomplex __CRTDECL acos(_In_ _Lcomplex _X) throw() + { + return cacosl(_X); + } + + inline _Lcomplex __CRTDECL acosh(_In_ _Lcomplex _X) throw() + { + return cacoshl(_X); + } + + inline _Lcomplex __CRTDECL asin(_In_ _Lcomplex _X) throw() + { + return casinl(_X); + } + + inline _Lcomplex __CRTDECL asinh(_In_ _Lcomplex _X) throw() + { + return casinhl(_X); + } + + inline _Lcomplex __CRTDECL atan(_In_ _Lcomplex _X) throw() + { + return catanl(_X); + } + + inline _Lcomplex __CRTDECL atanh(_In_ _Lcomplex _X) throw() + { + return catanhl(_X); + } + + inline _Lcomplex __CRTDECL conj(_In_ _Lcomplex _X) throw() + { + return conjl(_X); + } + + inline _Lcomplex __CRTDECL cos(_In_ _Lcomplex _X) throw() + { + return ccosl(_X); + } + + inline _Lcomplex __CRTDECL cosh(_In_ _Lcomplex _X) throw() + { + return ccoshl(_X); + } + + inline _Lcomplex __CRTDECL cproj(_In_ _Lcomplex _X) throw() + { + return cprojl(_X); + } + + inline _Lcomplex __CRTDECL proj(_In_ _Lcomplex _X) throw() + { + return cprojl(_X); + } + + inline _Lcomplex __CRTDECL exp(_In_ _Lcomplex _X) throw() + { + return cexpl(_X); + } + + inline _Lcomplex __CRTDECL log(_In_ _Lcomplex _X) throw() + { + return clogl(_X); + } + + inline _Lcomplex __CRTDECL log10(_In_ _Lcomplex _X) throw() + { + return clog10l(_X); + } + + inline long double __CRTDECL norm(_In_ _Lcomplex _X) throw() + { + return norml(_X); + } + + inline _Lcomplex __CRTDECL pow(_In_ _Lcomplex _X, _In_ _Lcomplex _Y) throw() + { + return cpowl(_X, _Y); + } + + inline _Lcomplex __CRTDECL sin(_In_ _Lcomplex _X) throw() + { + return csinl(_X); + } + + inline _Lcomplex __CRTDECL sinh(_In_ _Lcomplex _X) throw() + { + return csinhl(_X); + } + + inline _Lcomplex __CRTDECL sqrt(_In_ _Lcomplex _X) throw() + { + return csqrtl(_X); + } + + inline _Lcomplex __CRTDECL tan(_In_ _Lcomplex _X) throw() + { + return ctanl(_X); + } + + inline _Lcomplex __CRTDECL tanh(_In_ _Lcomplex _X) throw() + { + return ctanhl(_X); + } + + inline long double __CRTDECL abs(_In_ _Lcomplex _X) throw() + { + return cabsl(_X); + } + + inline long double __CRTDECL arg(_In_ _Lcomplex _X) throw() + { + return cargl(_X); + } + + inline long double __CRTDECL carg(_In_ _Lcomplex _X) throw() + { + return cargl(_X); + } + + inline long double __CRTDECL cimag(_In_ _Lcomplex _X) throw() + { + return cimagl(_X); + } + + inline long double __CRTDECL creal(_In_ _Lcomplex _X) throw() + { + return creall(_X); + } + + inline long double __CRTDECL imag(_In_ _Lcomplex _X) throw() + { + return cimagl(_X); + } + + inline long double __CRTDECL real(_In_ _Lcomplex _X) throw() + { + return creall(_X); + } + +} // extern "C++" +#endif // __cplusplus + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS +#endif // (_CRT_HAS_CXX17 == 1) && !defined(_CRT_USE_C_COMPLEX_H) +#endif // _COMPLEX diff --git a/sdk/include/ucrt/conio.h b/sdk/include/ucrt/conio.h new file mode 100644 index 0000000000000..a0f5e9c192cc8 --- /dev/null +++ b/sdk/include/ucrt/conio.h @@ -0,0 +1,504 @@ +// +// conio.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// This file declares the direct console I/O functions. +// +#pragma once +#ifndef _INC_CONIO // include guard for 3rd party interop +#define _INC_CONIO + +#include +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + + _Check_return_wat_ + _Success_(_BufferCount > 0) + _DCRTIMP errno_t __cdecl _cgets_s( + _Out_writes_z_(_BufferCount) char* _Buffer, + _In_ size_t _BufferCount, + _Out_ size_t* _SizeRead + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1( + _Success_(return == 0) + errno_t, _cgets_s, + _Out_writes_z_(*_Buffer) char, _Buffer, + _Out_ size_t*, _SizeRead + ) + + _Check_return_opt_ + _DCRTIMP int __cdecl _cputs( + _In_z_ char const* _Buffer + ); + + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + // Narrow Character Formatted Output Functions (Console) + // + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + _Check_return_opt_ + _DCRTIMP int __cdecl __conio_common_vcprintf( + _In_ unsigned __int64 _Options, + _In_z_ _Printf_format_string_params_(2) char const* _Format, + _In_opt_ _locale_t _Locale, + va_list _ArgList + ); + + _Check_return_opt_ + _DCRTIMP int __cdecl __conio_common_vcprintf_s( + _In_ unsigned __int64 _Options, + _In_z_ _Printf_format_string_params_(2) char const* _Format, + _In_opt_ _locale_t _Locale, + va_list _ArgList + ); + + _Check_return_opt_ + _DCRTIMP int __cdecl __conio_common_vcprintf_p( + _In_ unsigned __int64 _Options, + _In_z_ _Printf_format_string_params_(2) char const* _Format, + _In_opt_ _locale_t _Locale, + va_list _ArgList + ); + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vcprintf_l( + _In_z_ _Printf_format_string_params_(2) char const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + return __conio_common_vcprintf( + _CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, + _Format, _Locale, _ArgList); + } +#endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vcprintf( + _In_z_ _Printf_format_string_ char const* const _Format, + va_list _ArgList + ) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + return _vcprintf_l(_Format, NULL, _ArgList); + } +#endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vcprintf_s_l( + _In_z_ _Printf_format_string_params_(2) char const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + return __conio_common_vcprintf_s( + _CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, + _Format, _Locale, _ArgList); + } +#endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vcprintf_s( + _In_z_ _Printf_format_string_ char const* const _Format, + va_list _ArgList + ) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + return _vcprintf_s_l(_Format, NULL, _ArgList); + } +#endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vcprintf_p_l( + _In_z_ _Printf_format_string_params_(2) char const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + return __conio_common_vcprintf_p( + _CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, + _Format, _Locale, _ArgList); + } +#endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vcprintf_p( + _In_z_ char const* const _Format, + va_list _ArgList + ) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + return _vcprintf_p_l(_Format, NULL, _ArgList); + } +#endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _cprintf_l( + _In_z_ _Printf_format_string_params_(0) char const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vcprintf_l(_Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } +#endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _cprintf( + _In_z_ _Printf_format_string_ char const* const _Format, + ...) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vcprintf_l(_Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } +#endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _cprintf_s_l( + _In_z_ _Printf_format_string_params_(0) char const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vcprintf_s_l(_Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } +#endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _cprintf_s( + _In_z_ _Printf_format_string_ char const* const _Format, + ...) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vcprintf_s_l(_Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } +#endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _cprintf_p_l( + _In_z_ _Printf_format_string_params_(0) char const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vcprintf_p_l(_Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } +#endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _cprintf_p( + _In_z_ _Printf_format_string_ char const* const _Format, + ...) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vcprintf_p_l(_Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } +#endif + + + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + // Narrow Character Formatted Input Functions (Console) + // + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + _Check_return_opt_ + _DCRTIMP int __cdecl __conio_common_vcscanf( + _In_ unsigned __int64 _Options, + _In_z_ _Scanf_format_string_params_(2) char const* _Format, + _In_opt_ _locale_t _Locale, + va_list _ArgList + ); + + _Check_return_opt_ _CRT_INSECURE_DEPRECATE(_vcscanf_s_l) + _CRT_STDIO_INLINE int __CRTDECL _vcscanf_l( + _In_z_ _Scanf_format_string_params_(2) char const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + return __conio_common_vcscanf( + _CRT_INTERNAL_LOCAL_SCANF_OPTIONS, + _Format, _Locale, _ArgList); + } +#endif + + _Check_return_opt_ _CRT_INSECURE_DEPRECATE(_vcscanf_s) + _CRT_STDIO_INLINE int __CRTDECL _vcscanf( + _In_z_ _Scanf_format_string_params_(1) char const* const _Format, + va_list _ArgList + ) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + return _vcscanf_l(_Format, NULL, _ArgList); + } +#endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vcscanf_s_l( + _In_z_ _Scanf_format_string_params_(2) char const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + return __conio_common_vcscanf( + _CRT_INTERNAL_LOCAL_SCANF_OPTIONS | _CRT_INTERNAL_SCANF_SECURECRT, + _Format, _Locale, _ArgList); + } +#endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vcscanf_s( + _In_z_ _Scanf_format_string_params_(1) char const* const _Format, + va_list _ArgList + ) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + return _vcscanf_s_l(_Format, NULL, _ArgList); + } +#endif + + _Check_return_opt_ _CRT_INSECURE_DEPRECATE(_cscanf_s_l) + _CRT_STDIO_INLINE int __CRTDECL _cscanf_l( + _In_z_ _Scanf_format_string_params_(0) char const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + + _Result = _vcscanf_l(_Format, _Locale, _ArgList); + + __crt_va_end(_ArgList); + return _Result; + } +#endif + + _Check_return_opt_ _CRT_INSECURE_DEPRECATE(_cscanf_s) + _CRT_STDIO_INLINE int __CRTDECL _cscanf( + _In_z_ _Scanf_format_string_ char const* const _Format, + ...) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + + _Result = _vcscanf_l(_Format, NULL, _ArgList); + + __crt_va_end(_ArgList); + return _Result; + } +#endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _cscanf_s_l( + _In_z_ _Scanf_format_string_params_(0) char const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vcscanf_s_l(_Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } +#endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _cscanf_s( + _In_z_ _Scanf_format_string_ char const* const _Format, + ...) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vcscanf_s_l(_Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } +#endif + + + _DCRTIMP int __cdecl _kbhit(void); + + _Check_return_ _DCRTIMP int __cdecl _getch(void); + _Check_return_ _DCRTIMP int __cdecl _getche(void); + _Check_return_opt_ _DCRTIMP int __cdecl _putch (_In_ int _Ch); + _Check_return_opt_ _DCRTIMP int __cdecl _ungetch(_In_ int _Ch); + + _Check_return_ _DCRTIMP int __cdecl _getch_nolock (void); + _Check_return_ _DCRTIMP int __cdecl _getche_nolock (void); + _Check_return_opt_ _DCRTIMP int __cdecl _putch_nolock (_In_ int _Ch); + _Check_return_opt_ _DCRTIMP int __cdecl _ungetch_nolock(_In_ int _Ch); + + #if defined(_CRT_INTERNAL_NONSTDC_NAMES) && _CRT_INTERNAL_NONSTDC_NAMES + + // Suppress double-deprecation warnings: + #pragma warning(push) + #pragma warning(disable: 4141) + + _Success_(return != 0) + _Check_return_opt_ _CRT_NONSTDC_DEPRECATE(_cgets) _CRT_INSECURE_DEPRECATE(_cgets_s) + _DCRTIMP char* __cdecl cgets( + _At_(&_Buffer[0], _In_reads_(1)) + _At_(&_Buffer[1], _Out_writes_(1)) + _At_(&_Buffer[2], _Post_z_ _Out_writes_to_(_Buffer[0], _Buffer[1])) + char* _Buffer + ); + + #pragma warning(pop) + + _Check_return_opt_ _CRT_NONSTDC_DEPRECATE(_cputs) + _DCRTIMP int __cdecl cputs( + _In_z_ char const* _String + ); + + _Check_return_ _CRT_NONSTDC_DEPRECATE(_getch) + _DCRTIMP int __cdecl getch(void); + + _Check_return_ _CRT_NONSTDC_DEPRECATE(_getche) + _DCRTIMP int __cdecl getche(void); + + _Check_return_ _CRT_NONSTDC_DEPRECATE(_kbhit) + _DCRTIMP int __cdecl kbhit(void); + + _Check_return_opt_ _CRT_NONSTDC_DEPRECATE(_putch) + _DCRTIMP int __cdecl putch( + _In_ int _Ch + ); + + _Check_return_opt_ _CRT_NONSTDC_DEPRECATE(_ungetch) + _DCRTIMP int __cdecl ungetch( + _In_ int _Ch + ); + + _Check_return_opt_ _CRT_NONSTDC_DEPRECATE(_cprintf) + _CRT_STDIO_INLINE int __CRTDECL cprintf( + _In_z_ _Printf_format_string_ char const* const _Format, + ...) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vcprintf_l(_Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } +#endif + + _Check_return_opt_ _CRT_NONSTDC_DEPRECATE(_cscanf) + _CRT_STDIO_INLINE int __CRTDECL cscanf( + _In_z_ _Scanf_format_string_ char const* const _Format, + ...) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + + _Result = _vcscanf_l(_Format, NULL, _ArgList); + + __crt_va_end(_ArgList); + return _Result; + } +#endif + + #endif // _CRT_INTERNAL_NONSTDC_NAMES + +_CRT_END_C_HEADER + +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS +#endif // _INC_CONIO diff --git a/sdk/include/ucrt/corecrt.h b/sdk/include/ucrt/corecrt.h new file mode 100644 index 0000000000000..4fe20566df96a --- /dev/null +++ b/sdk/include/ucrt/corecrt.h @@ -0,0 +1,2086 @@ +// +// corecrt.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// Declarations used throughout the CoreCRT library. +// +#pragma once + +#include + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Windows API Partitioning and ARM Desktop Support +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#ifndef _CRT_USE_WINAPI_FAMILY_DESKTOP_APP + #ifdef WINAPI_FAMILY + #include + #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) + #define _CRT_USE_WINAPI_FAMILY_DESKTOP_APP + #else + #ifdef WINAPI_FAMILY_PHONE_APP + #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + #define _CRT_USE_WINAPI_FAMILY_PHONE_APP + #endif + #endif + + #ifdef WINAPI_FAMILY_GAMES + #if WINAPI_FAMILY == WINAPI_FAMILY_GAMES + #define _CRT_USE_WINAPI_FAMILY_GAMES + #endif + #endif + #endif + #else + #define _CRT_USE_WINAPI_FAMILY_DESKTOP_APP + #endif +#endif + +#ifndef _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE + #define _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE 1 +#endif + +#ifndef _CRT_BUILD_DESKTOP_APP + #ifdef _CRT_USE_WINAPI_FAMILY_DESKTOP_APP + #define _CRT_BUILD_DESKTOP_APP 1 + #else + #define _CRT_BUILD_DESKTOP_APP 0 + #endif +#endif + +// Verify that the ARM Desktop SDK is available when building an ARM Desktop app +#ifdef _M_ARM + #if _CRT_BUILD_DESKTOP_APP && !_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE + #error Compiling Desktop applications for the ARM platform is not supported. + #endif +#endif + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Warning Suppression +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +// C4412: function signature contains type '_locale_t'; +// C++ objects are unsafe to pass between pure code and mixed or native. (/Wall) +#ifndef _UCRT_DISABLED_WARNING_4412 + #ifdef _M_CEE_PURE + #define _UCRT_DISABLED_WARNING_4412 4412 + #else + #define _UCRT_DISABLED_WARNING_4412 + #endif +#endif + +// Use _UCRT_EXTRA_DISABLED_WARNINGS to add additional warning suppressions to UCRT headers. +#ifndef _UCRT_EXTRA_DISABLED_WARNINGS + #define _UCRT_EXTRA_DISABLED_WARNINGS +#endif + +// C4324: structure was padded due to __declspec(align()) (/W4) +// C4514: unreferenced inline function has been removed (/Wall) +// C4574: 'MACRO' is defined to be '0': did you mean to use '#if MACRO'? (/Wall) +// C4668: '__cplusplus' is not defined as a preprocessor macro (/Wall) +// C4710: function not inlined (/Wall) +// C4793: 'function' is compiled as native code (/Wall and /W1 under /clr:pure) +// C4820: padding after data member (/Wall) +// C4995: name was marked #pragma deprecated +// C4996: __declspec(deprecated) +// C28719: Banned API, use a more robust and secure replacement. +// C28726: Banned or deprecated API, use a more robust and secure replacement. +// C28727: Banned API. +#ifndef _UCRT_DISABLED_WARNINGS + #define _UCRT_DISABLED_WARNINGS 4324 _UCRT_DISABLED_WARNING_4412 4514 4574 4710 4793 4820 4995 4996 28719 28726 28727 _UCRT_EXTRA_DISABLED_WARNINGS +#endif + +#ifndef _UCRT_DISABLE_CLANG_WARNINGS + #ifdef __clang__ + // warning: declspec(deprecated) [-Wdeprecated-declarations] + // warning: __declspec attribute 'allocator' is not supported [-Wignored-attributes] + // warning: '#pragma optimize' is not supported [-Wignored-pragma-optimize] + // warning: unknown pragma ignored [-Wunknown-pragmas] + #define _UCRT_DISABLE_CLANG_WARNINGS \ + _Pragma("clang diagnostic push") \ + _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") \ + _Pragma("clang diagnostic ignored \"-Wignored-attributes\"") \ + _Pragma("clang diagnostic ignored \"-Wignored-pragma-optimize\"") \ + _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"") + #else // __clang__ + #define _UCRT_DISABLE_CLANG_WARNINGS + #endif // __clang__ +#endif // _UCRT_DISABLE_CLANG_WARNINGS + +#ifndef _UCRT_RESTORE_CLANG_WARNINGS + #ifdef __clang__ + #define _UCRT_RESTORE_CLANG_WARNINGS _Pragma("clang diagnostic pop") + #else // __clang__ + #define _UCRT_RESTORE_CLANG_WARNINGS + #endif // __clang__ +#endif // _UCRT_RESTORE_CLANG_WARNINGS + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Annotation Macros +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#ifndef _ACRTIMP + #if defined _CRTIMP && !defined _VCRT_DEFINED_CRTIMP + #define _ACRTIMP _CRTIMP + #elif !defined _CORECRT_BUILD && defined _DLL + #define _ACRTIMP __declspec(dllimport) + #else + #define _ACRTIMP + #endif +#endif + +// If you need the ability to remove __declspec(import) from an API, to support static replacement, +// declare the API using _ACRTIMP_ALT instead of _ACRTIMP. +#ifndef _ACRTIMP_ALT + #define _ACRTIMP_ALT _ACRTIMP +#endif + +#ifndef _DCRTIMP + #if defined _CRTIMP && !defined _VCRT_DEFINED_CRTIMP + #define _DCRTIMP _CRTIMP + #elif !defined _CORECRT_BUILD && defined _DLL + #define _DCRTIMP __declspec(dllimport) + #else + #define _DCRTIMP + #endif +#endif + +#if defined _CRT_SUPPRESS_RESTRICT || defined _CORECRT_BUILD + #define _CRTRESTRICT +#else + #define _CRTRESTRICT __declspec(restrict) +#endif + +#if defined _MSC_VER && _MSC_VER >= 1900 && !defined _CORECRT_BUILD + #define _CRTALLOCATOR __declspec(allocator) +#else + #define _CRTALLOCATOR +#endif + +#if defined _M_CEE && defined _M_X64 + // This is only needed when managed code is calling the native APIs, + // targeting the 64-bit runtime. + #define _CRT_JIT_INTRINSIC __declspec(jitintrinsic) +#else + #define _CRT_JIT_INTRINSIC +#endif + +// __declspec(guard(overflow)) enabled by /sdl compiler switch for CRT allocators +#ifdef _GUARDOVERFLOW_CRT_ALLOCATORS + #define _CRT_GUARDOVERFLOW __declspec(guard(overflow)) +#else + #define _CRT_GUARDOVERFLOW +#endif + +#if defined _DLL && (defined _M_HYBRID || defined _M_ARM64EC) && (defined _CORECRT_BUILD || defined _VCRT_BUILD) + #define _CRT_HYBRIDPATCHABLE __declspec(hybrid_patchable) +#else + #define _CRT_HYBRIDPATCHABLE +#endif + +// The CLR requires code calling other SecurityCritical code or using SecurityCritical types +// to be marked as SecurityCritical. +// _CRT_SECURITYCRITICAL_ATTRIBUTE covers this for internal function definitions. +// _CRT_INLINE_PURE_SECURITYCRITICAL_ATTRIBUTE is for inline pure functions defined in the header. +// This is clr:pure-only because for mixed mode we compile inline functions as native. +#ifdef _M_CEE_PURE + #define _CRT_INLINE_PURE_SECURITYCRITICAL_ATTRIBUTE [System::Security::SecurityCritical] +#else + #define _CRT_INLINE_PURE_SECURITYCRITICAL_ATTRIBUTE +#endif + +#ifndef _CONST_RETURN + #ifdef __cplusplus + #define _CONST_RETURN const + #define _CRT_CONST_CORRECT_OVERLOADS + #else + #define _CONST_RETURN + #endif +#endif + +#define _WConst_return _CONST_RETURN // For backwards compatibility + +#ifndef _CRT_ALIGN + #ifdef __midl + #define _CRT_ALIGN(x) + #else + #define _CRT_ALIGN(x) __declspec(align(x)) + #endif +#endif + +#if defined _PREFAST_ && defined _CA_SHOULD_CHECK_RETURN + #define _Check_return_opt_ _Check_return_ +#else + #define _Check_return_opt_ +#endif + +#if defined _PREFAST_ && defined _CA_SHOULD_CHECK_RETURN_WER + #define _Check_return_wat_ _Check_return_ +#else + #define _Check_return_wat_ +#endif + +#if !defined __midl && !defined MIDL_PASS && defined _PREFAST_ + #define __crt_typefix(ctype) __declspec("SAL_typefix(" _CRT_STRINGIZE(ctype) ")") +#else + #define __crt_typefix(ctype) +#endif + +#ifndef _CRT_NOEXCEPT + #ifdef __cplusplus + #define _CRT_NOEXCEPT noexcept + #else + #define _CRT_NOEXCEPT + #endif +#endif + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Miscellaneous Stuff +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#ifdef __cplusplus +extern "C++" +{ + template + struct _CrtEnableIf; + + template + struct _CrtEnableIf + { + typedef _Ty _Type; + }; +} +#endif + +#if defined __cplusplus + typedef bool __crt_bool; +#elif defined __midl + // MIDL understands neither bool nor _Bool. Use char as a best-fit + // replacement (the differences won't matter in practice). + typedef char __crt_bool; +#else + typedef _Bool __crt_bool; +#endif + +#define _ARGMAX 100 +#define _TRUNCATE ((size_t)-1) +#define _CRT_INT_MAX 2147483647 +#define _CRT_SIZE_MAX ((size_t)-1) + +#define __FILEW__ _CRT_WIDE(__FILE__) + +#ifdef _MSC_VER +#define __FUNCTIONW__ _CRT_WIDE(__FUNCTION__) +#else // _MSC_VER +#define __FUNCTIONW__ \ +({ \ + static wchar_t __funcw__[sizeof(__func__)]; \ + for (size_t i = 0; i < sizeof(__func__); i++) \ + __funcw__[i] = __func__[i]; \ + __funcw__; \ +}) +#endif // _MSC_VER + +#ifdef __cplusplus + #ifndef _STATIC_ASSERT + #define _STATIC_ASSERT(expr) static_assert((expr), #expr) + #endif +#else + #ifndef _STATIC_ASSERT + #ifdef __clang__ + #define _STATIC_ASSERT(expr) _Static_assert((expr), #expr) + #else + #define _STATIC_ASSERT(expr) typedef char __static_assert_t[(expr) != 0] + #endif + #endif +#endif + +#ifndef NULL + #ifdef __cplusplus + #define NULL 0 + #else + #define NULL ((void *)0) + #endif +#endif + +// CRT headers are included into some kinds of source files where only data type +// definitions and macro definitions are required but function declarations and +// inline function definitions are not. These files include assembly files, IDL +// files, and resource files. The tools that process these files often have a +// limited ability to process C and C++ code. The _CRT_FUNCTIONS_REQUIRED macro +// is defined to 1 when we are compiling a file that actually needs functions to +// be declared (and defined, where applicable), and to 0 when we are compiling a +// file that does not. This allows us to suppress declarations and definitions +// that are not compilable with the aforementioned tools. +#if !defined _CRT_FUNCTIONS_REQUIRED + #if defined __assembler || defined __midl || defined RC_INVOKED + #define _CRT_FUNCTIONS_REQUIRED 0 + #else + #define _CRT_FUNCTIONS_REQUIRED 1 + #endif +#endif + +#if !defined _NO_INLINING && !_CRT_FUNCTIONS_REQUIRED + #define _NO_INLINING // Suppress inlines +#endif + +#ifndef _CRT_UNUSED + #define _CRT_UNUSED(x) (void)x +#endif + +#ifndef _CRT_HAS_CXX17 + #ifdef _MSVC_LANG + #if _MSVC_LANG > 201402 + #define _CRT_HAS_CXX17 1 + #else /* _MSVC_LANG > 201402 */ + #define _CRT_HAS_CXX17 0 + #endif /* _MSVC_LANG > 201402 */ + #else /* _MSVC_LANG */ + #if defined __cplusplus && __cplusplus > 201402 + #define _CRT_HAS_CXX17 1 + #else /* __cplusplus > 201402 */ + #define _CRT_HAS_CXX17 0 + #endif /* __cplusplus > 201402 */ + #endif /* _MSVC_LANG */ +#endif /* _CRT_HAS_CXX17 */ + +#ifndef _CRT_HAS_C11 + #if defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112L + #define _CRT_HAS_C11 1 + #else /* defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112L */ + #define _CRT_HAS_C11 0 + #endif /* defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112L */ +#endif /* _CRT_HAS_C11 */ + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Invalid Parameter Handler +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#ifdef _DEBUG + _ACRTIMP void __cdecl _invalid_parameter( + _In_opt_z_ wchar_t const*, + _In_opt_z_ wchar_t const*, + _In_opt_z_ wchar_t const*, + _In_ unsigned int, + _In_ uintptr_t + ); +#endif + +_ACRTIMP_ALT void __cdecl _invalid_parameter_noinfo(void); +_ACRTIMP __declspec(noreturn) void __cdecl _invalid_parameter_noinfo_noreturn(void); + +__declspec(noreturn) +_ACRTIMP void __cdecl _invoke_watson( + _In_opt_z_ wchar_t const* _Expression, + _In_opt_z_ wchar_t const* _FunctionName, + _In_opt_z_ wchar_t const* _FileName, + _In_ unsigned int _LineNo, + _In_ uintptr_t _Reserved); + +#ifndef _CRT_SECURE_INVALID_PARAMETER + #ifdef _DEBUG + #define _CRT_SECURE_INVALID_PARAMETER(expr) \ + ::_invalid_parameter(_CRT_WIDE(#expr), __FUNCTIONW__, __FILEW__, __LINE__, 0) + #else + // By default, _CRT_SECURE_INVALID_PARAMETER in retail invokes + // _invalid_parameter_noinfo_noreturn(), which is marked + // __declspec(noreturn) and does not return control to the application. + // Even if _set_invalid_parameter_handler() is used to set a new invalid + // parameter handler which does return control to the application, + // _invalid_parameter_noinfo_noreturn() will terminate the application + // and invoke Watson. You can overwrite the definition of + // _CRT_SECURE_INVALID_PARAMETER if you need. + // + // _CRT_SECURE_INVALID_PARAMETER is used in the Standard C++ Libraries + // and the SafeInt library. + #define _CRT_SECURE_INVALID_PARAMETER(expr) \ + ::_invalid_parameter_noinfo_noreturn() + #endif +#endif + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Deprecation and Warnings +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#define _CRT_WARNING_MESSAGE(NUMBER, MESSAGE) \ + __FILE__ "(" _CRT_STRINGIZE(__LINE__) "): warning " NUMBER ": " MESSAGE + +#if ( defined _CRT_DECLARE_NONSTDC_NAMES && _CRT_DECLARE_NONSTDC_NAMES) || \ + (!defined _CRT_DECLARE_NONSTDC_NAMES && !__STDC__ ) + #define _CRT_INTERNAL_NONSTDC_NAMES 1 +#else + #define _CRT_INTERNAL_NONSTDC_NAMES 0 +#endif + +#if defined _CRT_NONSTDC_NO_DEPRECATE && !defined _CRT_NONSTDC_NO_WARNINGS + #define _CRT_NONSTDC_NO_WARNINGS +#endif + +#ifndef _CRT_NONSTDC_DEPRECATE + #ifdef _CRT_NONSTDC_NO_WARNINGS + #define _CRT_NONSTDC_DEPRECATE(_NewName) + #else + #define _CRT_NONSTDC_DEPRECATE(_NewName) _CRT_DEPRECATE_TEXT( \ + "The POSIX name for this item is deprecated. Instead, use the ISO C " \ + "and C++ conformant name: " #_NewName ". See online help for details.") + #endif +#endif + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Managed CRT Support +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#ifndef _PGLOBAL + #ifdef _M_CEE + #ifdef __cplusplus_cli + #define _PGLOBAL __declspec(process) + #else + #define _PGLOBAL + #endif + #else + #define _PGLOBAL + #endif +#endif + +#ifndef _AGLOBAL + #ifdef _M_CEE + #define _AGLOBAL __declspec(appdomain) + #else + #define _AGLOBAL + #endif +#endif + +#if defined _M_CEE && !defined _M_CEE_PURE + #define _M_CEE_MIXED +#endif + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// SecureCRT Configuration +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#if defined _CRTBLD || defined _CORECRT_BUILD || defined _VCRT_BUILD + // Disable C++ overloads internally: + #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 0 + #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT 0 + #define _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES 0 +#endif + +#if !_CRT_FUNCTIONS_REQUIRED + // If we don't require function declarations at all, we need not define the + // overloads (MIDL and RC do not need the C++ overloads). + #undef _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES + #undef _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT + #undef _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES + #undef _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_MEMORY + #undef _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES_MEMORY + + #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 0 + #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT 0 + #define _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES 0 + #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_MEMORY 0 + #define _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES_MEMORY 0 +#endif + +#define __STDC_SECURE_LIB__ 200411L +#define __GOT_SECURE_LIB__ __STDC_SECURE_LIB__ // For backwards compatibility + +#ifndef __STDC_WANT_SECURE_LIB__ + #define __STDC_WANT_SECURE_LIB__ 1 +#endif + +#if !__STDC_WANT_SECURE_LIB__ && !defined _CRT_SECURE_NO_WARNINGS + #define _CRT_SECURE_NO_WARNINGS +#endif + +#ifndef RC_INVOKED + #if defined _CRT_SECURE_NO_DEPRECATE_GLOBALS && !defined _CRT_SECURE_NO_WARNINGS_GLOBALS + #define _CRT_SECURE_NO_WARNINGS_GLOBALS + #endif +#endif + +#ifndef _CRT_INSECURE_DEPRECATE_GLOBALS + #ifdef RC_INVOKED + #define _CRT_INSECURE_DEPRECATE_GLOBALS(replacement) + #else + #ifdef _CRT_SECURE_NO_WARNINGS_GLOBALS + #define _CRT_INSECURE_DEPRECATE_GLOBALS(replacement) + #else + #define _CRT_INSECURE_DEPRECATE_GLOBALS(replacement) _CRT_INSECURE_DEPRECATE(replacement) + #endif + #endif +#endif + +#if defined _CRT_MANAGED_HEAP_NO_DEPRECATE && !defined _CRT_MANAGED_HEAP_NO_WARNINGS + #define _CRT_MANAGED_HEAP_NO_WARNINGS +#endif + +#define _SECURECRT_FILL_BUFFER_PATTERN 0xFE + +#if defined _CRT_OBSOLETE_NO_DEPRECATE && !defined _CRT_OBSOLETE_NO_WARNINGS + #define _CRT_OBSOLETE_NO_WARNINGS +#endif + +#ifndef _CRT_OBSOLETE + #ifdef _CRT_OBSOLETE_NO_WARNINGS + #define _CRT_OBSOLETE(_NewItem) + #else + #define _CRT_OBSOLETE(_NewItem) _CRT_DEPRECATE_TEXT( \ + "This function or variable has been superceded by newer library " \ + "or operating system functionality. Consider using " #_NewItem " " \ + "instead. See online help for details.") + #endif +#endif + +#ifndef RC_INVOKED + #ifndef _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES + #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 0 + #else + #if !__STDC_WANT_SECURE_LIB__ && _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES + #error Cannot use Secure CRT C++ overloads when __STDC_WANT_SECURE_LIB__ is 0 + #endif + #endif + + #ifndef _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT + // _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT is ignored if + // _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES is set to 0 + #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT 0 + #else + #if !__STDC_WANT_SECURE_LIB__ && _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT + #error Cannot use Secure CRT C++ overloads when __STDC_WANT_SECURE_LIB__ is 0 + #endif + #endif + + #ifndef _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES + #if __STDC_WANT_SECURE_LIB__ + #define _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES 1 + #else + #define _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES 0 + #endif + #else + #if !__STDC_WANT_SECURE_LIB__ && _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES + #error Cannot use Secure CRT C++ overloads when __STDC_WANT_SECURE_LIB__ is 0 + #endif + #endif + + #ifndef _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_MEMORY + #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_MEMORY 0 + #else + #if !__STDC_WANT_SECURE_LIB__ && _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_MEMORY + #error Cannot use Secure CRT C++ overloads when __STDC_WANT_SECURE_LIB__ is 0 + #endif + #endif + + #ifndef _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES_MEMORY + #define _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES_MEMORY 0 + #else + #if !__STDC_WANT_SECURE_LIB__ && _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES_MEMORY + #error Cannot use Secure CRT C++ overloads when __STDC_WANT_SECURE_LIB__ is 0 + #endif + #endif +#endif + +#ifndef _CRT_SECURE_CPP_NOTHROW + #define _CRT_SECURE_CPP_NOTHROW throw() +#endif + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Basic Types +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +typedef int errno_t; +typedef unsigned short wint_t; +typedef unsigned short wctype_t; +typedef long __time32_t; +typedef __int64 __time64_t; + +typedef struct __crt_locale_data_public +{ + unsigned short const* _locale_pctype; + _Field_range_(1, 2) int _locale_mb_cur_max; + unsigned int _locale_lc_codepage; +} __crt_locale_data_public; + +typedef struct __crt_locale_pointers +{ + struct __crt_locale_data* locinfo; + struct __crt_multibyte_data* mbcinfo; +} __crt_locale_pointers; + +typedef __crt_locale_pointers* _locale_t; + +typedef struct _Mbstatet +{ // state of a multibyte translation + unsigned long _Wchar; + unsigned short _Byte, _State; +} _Mbstatet; + +typedef _Mbstatet mbstate_t; + +#if defined _USE_32BIT_TIME_T && defined _WIN64 + #error You cannot use 32-bit time_t (_USE_32BIT_TIME_T) with _WIN64 +#endif + +#if defined _VCRT_BUILD || defined _CORECRT_BUILD + #define _CRT_NO_TIME_T +#endif + +#ifndef _CRT_NO_TIME_T + #ifdef _USE_32BIT_TIME_T + typedef __time32_t time_t; + #else + typedef __time64_t time_t; + #endif +#endif + +// Indicate that these common types are defined +#ifndef _TIME_T_DEFINED + #define _TIME_T_DEFINED +#endif + +#if __STDC_WANT_SECURE_LIB__ + typedef size_t rsize_t; +#endif + + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// C++ Secure Overload Generation Macros +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#ifndef RC_INVOKED + #if defined __cplusplus && _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES + + #define __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_0(_ReturnType, _FuncName, _DstType, _Dst) \ + extern "C++" \ + { \ + template \ + inline \ + _ReturnType __CRTDECL _FuncName(_DstType (&_Dst)[_Size]) _CRT_SECURE_CPP_NOTHROW \ + { \ + return _FuncName(_Dst, _Size); \ + } \ + } + + #define __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1(_ReturnType, _FuncName, _DstType, _Dst, _TType1, _TArg1) \ + extern "C++" \ + { \ + template \ + inline \ + _ReturnType __CRTDECL _FuncName(_DstType (&_Dst)[_Size], _TType1 _TArg1) _CRT_SECURE_CPP_NOTHROW \ + { \ + return _FuncName(_Dst, _Size, _TArg1); \ + } \ + } + + #define __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2(_ReturnType, _FuncName, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) \ + extern "C++" \ + { \ + template \ + inline \ + _ReturnType __CRTDECL _FuncName(_DstType (&_Dst)[_Size], _TType1 _TArg1, _TType2 _TArg2) _CRT_SECURE_CPP_NOTHROW \ + { \ + return _FuncName(_Dst, _Size, _TArg1, _TArg2); \ + } \ + } + + #define __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_3(_ReturnType, _FuncName, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3) \ + extern "C++" \ + { \ + template \ + inline \ + _ReturnType __CRTDECL _FuncName(_DstType (&_Dst)[_Size], _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3) _CRT_SECURE_CPP_NOTHROW \ + { \ + return _FuncName(_Dst, _Size, _TArg1, _TArg2, _TArg3); \ + } \ + } + + #define __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_4(_ReturnType, _FuncName, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3, _TType4, _TArg4) \ + extern "C++" \ + { \ + template \ + inline \ + _ReturnType __CRTDECL _FuncName(_DstType (&_Dst)[_Size], _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3, _TType4 _TArg4) _CRT_SECURE_CPP_NOTHROW \ + { \ + return _FuncName(_Dst, _Size, _TArg1, _TArg2, _TArg3, _TArg4); \ + } \ + } + + #define __DEFINE_CPP_OVERLOAD_SECURE_FUNC_1_1(_ReturnType, _FuncName, _HType1, _HArg1, _DstType, _Dst, _TType1, _TArg1) \ + extern "C++" \ + { \ + template \ + inline \ + _ReturnType __CRTDECL _FuncName(_HType1 _HArg1, _DstType (&_Dst)[_Size], _TType1 _TArg1) _CRT_SECURE_CPP_NOTHROW \ + { \ + return _FuncName(_HArg1, _Dst, _Size, _TArg1); \ + } \ + } + + #define __DEFINE_CPP_OVERLOAD_SECURE_FUNC_1_2(_ReturnType, _FuncName, _HType1, _HArg1, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) \ + extern "C++" \ + { \ + template \ + inline \ + _ReturnType __CRTDECL _FuncName(_HType1 _HArg1, _DstType (&_Dst)[_Size], _TType1 _TArg1, _TType2 _TArg2) _CRT_SECURE_CPP_NOTHROW \ + { \ + return _FuncName(_HArg1, _Dst, _Size, _TArg1, _TArg2); \ + } \ + } + + #define __DEFINE_CPP_OVERLOAD_SECURE_FUNC_1_3(_ReturnType, _FuncName, _HType1, _HArg1, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3) \ + extern "C++" \ + { \ + template \ + inline \ + _ReturnType __CRTDECL _FuncName(_HType1 _HArg1, _DstType (&_Dst)[_Size], _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3) _CRT_SECURE_CPP_NOTHROW \ + { \ + return _FuncName(_HArg1, _Dst, _Size, _TArg1, _TArg2, _TArg3); \ + } \ + } + + #define __DEFINE_CPP_OVERLOAD_SECURE_FUNC_2_0(_ReturnType, _FuncName, _HType1, _HArg1, _HType2, _HArg2, _DstType, _Dst) \ + extern "C++" \ + { \ + template \ + inline \ + _ReturnType __CRTDECL _FuncName(_HType1 _HArg1, _HType2 _HArg2, _DstType (&_Dst)[_Size]) _CRT_SECURE_CPP_NOTHROW \ + { \ + return _FuncName(_HArg1, _HArg2, _Dst, _Size); \ + } \ + } + + #define __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1_ARGLIST(_ReturnType, _FuncName, _VFuncName, _DstType, _Dst, _TType1, _TArg1) \ + extern "C++" \ + { \ + template \ + inline \ + _ReturnType __CRTDECL _FuncName(_DstType (&_Dst)[_Size], _TType1 _TArg1, ...) _CRT_SECURE_CPP_NOTHROW \ + { \ + va_list _ArgList; \ + __crt_va_start(_ArgList, _TArg1); \ + return _VFuncName(_Dst, _Size, _TArg1, _ArgList); \ + } \ + } + + #define __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2_ARGLIST(_ReturnType, _FuncName, _VFuncName, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) \ + extern "C++" \ + { \ + template \ + inline \ + _ReturnType __CRTDECL _FuncName(_DstType (&_Dst)[_Size], _TType1 _TArg1, _TType2 _TArg2, ...) _CRT_SECURE_CPP_NOTHROW \ + { \ + va_list _ArgList; \ + __crt_va_start(_ArgList, _TArg2); \ + return _VFuncName(_Dst, _Size, _TArg1, _TArg2, _ArgList); \ + } \ + } + + #define __DEFINE_CPP_OVERLOAD_SECURE_FUNC_SPLITPATH(_ReturnType, _FuncName, _DstType, _Src) \ + extern "C++" \ + { \ + template \ + inline \ + _ReturnType __CRTDECL _FuncName( \ + _In_z_ _DstType const* _Src, \ + _Post_z_ _DstType (&_Drive)[_DriveSize], \ + _Post_z_ _DstType (&_Dir)[_DirSize], \ + _Post_z_ _DstType (&_Name)[_NameSize], \ + _Post_z_ _DstType (&_Ext)[_ExtSize] \ + ) _CRT_SECURE_CPP_NOTHROW \ + { \ + return _FuncName(_Src, _Drive, _DriveSize, _Dir, _DirSize, _Name, _NameSize, _Ext, _ExtSize); \ + } \ + } + + #else // ^^^ _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES ^^^ // vvv !_CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES vvv // + + #define __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_0(_ReturnType, _FuncName, _DstType, _Dst) + #define __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1(_ReturnType, _FuncName, _DstType, _Dst, _TType1, _TArg1) + #define __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2(_ReturnType, _FuncName, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) + #define __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_3(_ReturnType, _FuncName, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3) + #define __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_4(_ReturnType, _FuncName, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3, _TType4, _TArg4) + #define __DEFINE_CPP_OVERLOAD_SECURE_FUNC_1_1(_ReturnType, _FuncName, _HType1, _HArg1, _DstType, _Dst, _TType1, _TArg1) + #define __DEFINE_CPP_OVERLOAD_SECURE_FUNC_1_2(_ReturnType, _FuncName, _HType1, _HArg1, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) + #define __DEFINE_CPP_OVERLOAD_SECURE_FUNC_1_3(_ReturnType, _FuncName, _HType1, _HArg1, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3) + #define __DEFINE_CPP_OVERLOAD_SECURE_FUNC_2_0(_ReturnType, _FuncName, _HType1, _HArg1, _HType2, _HArg2, _DstType, _Dst) + #define __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1_ARGLIST(_ReturnType, _FuncName, _VFuncName, _DstType, _Dst, _TType1, _TArg1) + #define __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2_ARGLIST(_ReturnType, _FuncName, _VFuncName, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) + #define __DEFINE_CPP_OVERLOAD_SECURE_FUNC_SPLITPATH(_ReturnType, _FuncName, _DstType, _Src) + + #endif // !_CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES +#endif + + + +#define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_0(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SalAttributeDst, _DstType, _Dst) \ + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_0_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _FuncName##_s, _SalAttributeDst, _DstType, _Dst) + +#define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1) \ + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _FuncName##_s, _DstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1) + +#define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_2(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) \ + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_2_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _FuncName##_s, _DstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) + +#define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_3(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3) \ + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_3_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _FuncName##_s, _DstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3) + +#define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_4(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3, _TType4, _TArg4) \ + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_4_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _FuncName##_s, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3, _TType4, _TArg4) + +#define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_1_1(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _HType1, _HArg1, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1) \ + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_1_1_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _FuncName##_s, _HType1, _HArg1, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1) + +#define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_2_0(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _HType1, _HArg1, _HType2, _HArg2, _SalAttributeDst, _DstType, _Dst) \ + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_2_0_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _FuncName##_s, _HType1, _HArg1, _HType2, _HArg2, _SalAttributeDst, _DstType, _Dst) + +#define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1_ARGLIST(_ReturnType, _ReturnPolicy, _DeclSpec, _CC, _FuncName, _VFuncName, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1) \ + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1_ARGLIST_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _CC, _FuncName, _FuncName##_s, _VFuncName, _VFuncName##_s, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1) + +#define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_2_ARGLIST(_ReturnType, _ReturnPolicy, _DeclSpec, _CC, _FuncName, _VFuncName, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) \ + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_2_ARGLIST_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _CC, _FuncName, _VFuncName, _VFuncName##_s, _DstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) + +#define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_2_SIZE(_DeclSpec, _FuncName, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) \ + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_2_SIZE_EX(_DeclSpec, _FuncName, _FuncName##_s, _DstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) + +#define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_3_SIZE(_DeclSpec, _FuncName, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3) \ + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_3_SIZE_EX(_DeclSpec, _FuncName, _FuncName##_s, _DstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3) + + + +#define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_0(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SalAttributeDst, _DstType, _Dst) \ + __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_0_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _FuncName##_s, _SalAttributeDst, _DstType, _Dst) + +#define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_1(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1) \ + __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_1_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _FuncName##_s, _SalAttributeDst, _DstType, _DstType, _Dst, _TType1, _TArg1) + +#define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) \ + __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _FuncName##_s, _DstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) + +#define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_3(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3) \ + __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_3_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _FuncName##_s, _DstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3) + +#define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_4(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3, _TType4, _TArg4) \ + __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_4_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _FuncName##_s, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3, _TType4, _TArg4) + +#define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_1_1(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _HType1, _HArg1, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1) \ + __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_1_1_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _FuncName##_s, _HType1, _HArg1, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1) + +#define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_2_0(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _HType1, _HArg1, _HType2, _HArg2, _SalAttributeDst, _DstType, _Dst) \ + __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_2_0_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _FuncName##_s, _HType1, _HArg1, _HType2, _HArg2, _SalAttributeDst, _DstType, _Dst) + +#define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_1_ARGLIST(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _VFuncName, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1) \ + __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_1_ARGLIST_EX(_ReturnType, _ReturnPolicy, _DeclSpec, __cdecl, _FuncName, _FuncName##_s, _VFuncName, _VFuncName##_s, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1) + +#define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2_SIZE(_DeclSpec, _FuncName, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) \ + __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2_SIZE_EX(_DeclSpec, _FuncName, _FuncName##_s, _DstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) + +#define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_3_SIZE(_DeclSpec, _FuncName, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3) \ + __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_3_SIZE_EX(_DeclSpec, _FuncName, _FuncName##_s, _DstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3) + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// C++ Standard Overload Generation Macros +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#ifndef RC_INVOKED + #if defined __cplusplus && _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES + + #define __RETURN_POLICY_SAME(_FunctionCall, _Dst) return (_FunctionCall) + #define __RETURN_POLICY_DST(_FunctionCall, _Dst) return ((_FunctionCall) == 0 ? _Dst : 0) + #define __RETURN_POLICY_VOID(_FunctionCall, _Dst) (_FunctionCall); return + #define __EMPTY_DECLSPEC + + #define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_0_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _SalAttributeDst, _DstType, _Dst) \ + __inline \ + _ReturnType __CRTDECL __insecure_##_FuncName(_SalAttributeDst _DstType *_Dst) \ + { \ + _ReturnType __cdecl _FuncName(_SalAttributeDst _DstType *_Dst); \ + return _FuncName(_Dst); \ + } \ + extern "C++" \ + { \ + template \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName(_T &_Dst) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(static_cast<_DstType *>(_Dst)); \ + } \ + template \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName(const _T &_Dst) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(static_cast<_DstType *>(_Dst)); \ + } \ + template <> \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName(_SalAttributeDst _DstType * &_Dst) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(_Dst); \ + } \ + template \ + inline \ + _ReturnType __CRTDECL _FuncName(_DstType (&_Dst)[_Size]) _CRT_SECURE_CPP_NOTHROW \ + { \ + _ReturnPolicy(_SecureFuncName(_Dst, _Size), _Dst); \ + } \ + template <> \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName<1>(_DstType (&_Dst)[1]) _CRT_SECURE_CPP_NOTHROW \ + { \ + _ReturnPolicy(_SecureFuncName(_Dst, 1), _Dst); \ + } \ + } + + #define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_0_CGETS(_ReturnType, _DeclSpec, _FuncName, _SalAttributeDst, _DstType, _Dst) \ + __inline \ + _ReturnType __CRTDECL __insecure_##_FuncName(_SalAttributeDst _DstType *_Dst) \ + { \ + _ReturnType __cdecl _FuncName(_SalAttributeDst _DstType *_Dst); \ + return _FuncName(_Dst); \ + } \ + extern "C++" \ + { \ + template \ + inline \ + _CRT_INSECURE_DEPRECATE(_FuncName##_s) \ + _ReturnType __CRTDECL _FuncName(_T &_Dst) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(static_cast<_DstType *>(_Dst)); \ + } \ + template \ + inline \ + _CRT_INSECURE_DEPRECATE(_FuncName##_s) \ + _ReturnType __CRTDECL _FuncName(const _T &_Dst) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(static_cast<_DstType *>(_Dst)); \ + } \ + template <> \ + inline \ + _CRT_INSECURE_DEPRECATE(_FuncName##_s) \ + _ReturnType __CRTDECL _FuncName(_SalAttributeDst _DstType * &_Dst) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(_Dst); \ + } \ + template \ + inline \ + _ReturnType __CRTDECL _FuncName(_DstType (&_Dst)[_Size]) _CRT_SECURE_CPP_NOTHROW \ + { \ + size_t _SizeRead = 0; \ + errno_t _Err = _FuncName##_s(_Dst + 2, (_Size - 2) < ((size_t)_Dst[0]) ? (_Size - 2) : ((size_t)_Dst[0]), &_SizeRead); \ + _Dst[1] = (_DstType)(_SizeRead); \ + return (_Err == 0 ? _Dst + 2 : 0); \ + } \ + template <> \ + inline \ + _CRT_INSECURE_DEPRECATE(_FuncName##_s) \ + _ReturnType __CRTDECL _FuncName<1>(_DstType (&_Dst)[1]) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName((_DstType *)_Dst); \ + } \ + template <> \ + inline \ + _CRT_INSECURE_DEPRECATE(_FuncName##_s) \ + _ReturnType __CRTDECL _FuncName<2>(_DstType (&_Dst)[2]) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName((_DstType *)_Dst); \ + } \ + } + + #define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1) \ + __inline \ + _ReturnType __CRTDECL __insecure_##_FuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1) \ + { \ + _ReturnType __cdecl _FuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1); \ + return _FuncName(_Dst, _TArg1); \ + } \ + extern "C++" \ + { \ + template \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName(_T &_Dst, _TType1 _TArg1) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(static_cast<_DstType *>(_Dst), _TArg1); \ + } \ + template \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName(const _T &_Dst, _TType1 _TArg1) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(static_cast<_DstType *>(_Dst), _TArg1); \ + } \ + template <> \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName(_SalAttributeDst _DstType * &_Dst, _TType1 _TArg1) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(_Dst, _TArg1); \ + } \ + template \ + inline \ + _ReturnType __CRTDECL _FuncName(_SecureDstType (&_Dst)[_Size], _TType1 _TArg1) _CRT_SECURE_CPP_NOTHROW \ + { \ + _ReturnPolicy(_SecureFuncName(_Dst, _Size, _TArg1), _Dst); \ + } \ + template <> \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName<1>(_DstType (&_Dst)[1], _TType1 _TArg1) _CRT_SECURE_CPP_NOTHROW \ + { \ + _ReturnPolicy(_SecureFuncName(_Dst, 1, _TArg1), _Dst); \ + } \ + } + + #define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_2_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) \ + __inline \ + _ReturnType __CRTDECL __insecure_##_FuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2) _CRT_SECURE_CPP_NOTHROW \ + { \ + _ReturnType __cdecl _FuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2); \ + return _FuncName(_Dst, _TArg1, _TArg2); \ + } \ + extern "C++" \ + { \ + template \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName(_T &_Dst, _TType1 _TArg1, _TType2 _TArg2) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(static_cast<_DstType *>(_Dst), _TArg1, _TArg2); \ + } \ + template \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName(const _T &_Dst, _TType1 _TArg1, _TType2 _TArg2) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(static_cast<_DstType *>(_Dst), _TArg1, _TArg2); \ + } \ + template <> \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName(_SalAttributeDst _DstType * &_Dst, _TType1 _TArg1, _TType2 _TArg2) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(_Dst, _TArg1, _TArg2); \ + } \ + template \ + inline \ + _ReturnType __CRTDECL _FuncName(_SecureDstType (&_Dst)[_Size], _TType1 _TArg1, _TType2 _TArg2) _CRT_SECURE_CPP_NOTHROW \ + { \ + _ReturnPolicy(_SecureFuncName(_Dst, _Size, _TArg1, _TArg2), _Dst); \ + } \ + template <> \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName<1>(_DstType (&_Dst)[1], _TType1 _TArg1, _TType2 _TArg2) _CRT_SECURE_CPP_NOTHROW \ + { \ + _ReturnPolicy(_SecureFuncName(_Dst, 1, _TArg1, _TArg2), _Dst); \ + } \ + } + + #define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_3_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3) \ + __inline \ + _ReturnType __CRTDECL __insecure_##_FuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3) \ + { \ + _ReturnType __cdecl _FuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3); \ + return _FuncName(_Dst, _TArg1, _TArg2, _TArg3); \ + } \ + extern "C++" \ + { \ + template \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName(_T &_Dst, _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(static_cast<_DstType *>(_Dst), _TArg1, _TArg2, _TArg3); \ + } \ + template \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName(const _T &_Dst, _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(static_cast<_DstType *>(_Dst), _TArg1, _TArg2, _TArg3); \ + } \ + template <> \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName(_SalAttributeDst _DstType * &_Dst, _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(_Dst, _TArg1, _TArg2, _TArg3); \ + } \ + template \ + inline \ + _ReturnType __CRTDECL _FuncName(_SecureDstType (&_Dst)[_Size], _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3) _CRT_SECURE_CPP_NOTHROW \ + { \ + _ReturnPolicy(_SecureFuncName(_Dst, _Size, _TArg1, _TArg2, _TArg3), _Dst); \ + } \ + template <> \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName<1>(_DstType (&_Dst)[1], _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3) _CRT_SECURE_CPP_NOTHROW \ + { \ + _ReturnPolicy(_SecureFuncName(_Dst, 1, _TArg1, _TArg2, _TArg3), _Dst); \ + } \ + } + + #define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_4_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3, _TType4, _TArg4) \ + __inline \ + _ReturnType __CRTDECL __insecure_##_FuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3, _TType4 _TArg4) \ + { \ + _ReturnType __cdecl _FuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3, _TType4 _TArg4); \ + return _FuncName(_Dst, _TArg1, _TArg2, _TArg3, _TArg4); \ + } \ + extern "C++" \ + { \ + template \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName(_T &_Dst, _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3, _TType4 _TArg4) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(static_cast<_DstType *>(_Dst), _TArg1, _TArg2, _TArg3, _TArg4); \ + } \ + template \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName(const _T &_Dst, _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3, _TType4 _TArg4) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(static_cast<_DstType *>(_Dst), _TArg1, _TArg2, _TArg3, _TArg4); \ + } \ + template <> \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName(_SalAttributeDst _DstType * &_Dst, _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3, _TType4 _TArg4) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(_Dst, _TArg1, _TArg2, _TArg3, _TArg4); \ + } \ + template \ + inline \ + _ReturnType __CRTDECL _FuncName(_DstType (&_Dst)[_Size], _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3, _TType4 _TArg4) _CRT_SECURE_CPP_NOTHROW \ + { \ + _ReturnPolicy(_SecureFuncName(_Dst, _Size, _TArg1, _TArg2, _TArg3, _TArg4), _Dst); \ + } \ + template <> \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName<1>(_DstType (&_Dst)[1], _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3, _TType4 _TArg4) _CRT_SECURE_CPP_NOTHROW \ + { \ + _ReturnPolicy(_SecureFuncName(_Dst, 1, _TArg1, _TArg2, _TArg3, _TArg4), _Dst); \ + } \ + } + + #define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_1_1_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _HType1, _HArg1, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1) \ + __inline \ + _ReturnType __CRTDECL __insecure_##_FuncName(_HType1 _HArg1, _SalAttributeDst _DstType *_Dst, _TType1 _TArg1) \ + { \ + _ReturnType __cdecl _FuncName(_HType1 _HArg1, _SalAttributeDst _DstType *_Dst, _TType1 _TArg1); \ + return _FuncName(_HArg1, _Dst, _TArg1); \ + } \ + extern "C++" \ + { \ + template \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName(_HType1 _HArg1, _T &_Dst, _TType1 _TArg1) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(_HArg1, static_cast<_DstType *>(_Dst), _TArg1); \ + } \ + template \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName(_HType1 _HArg1, const _T &_Dst, _TType1 _TArg1) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(_HArg1, static_cast<_DstType *>(_Dst), _TArg1); \ + } \ + template <> \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName(_HType1 _HArg1, _SalAttributeDst _DstType * &_Dst, _TType1 _TArg1) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(_HArg1, _Dst, _TArg1); \ + } \ + template \ + inline \ + _ReturnType __CRTDECL _FuncName(_HType1 _HArg1, _DstType (&_Dst)[_Size], _TType1 _TArg1) _CRT_SECURE_CPP_NOTHROW \ + { \ + _ReturnPolicy(_SecureFuncName(_HArg1, _Dst, _Size, _TArg1), _Dst); \ + } \ + template <> \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName<1>(_HType1 _HArg1, _DstType (&_Dst)[1], _TType1 _TArg1) _CRT_SECURE_CPP_NOTHROW \ + { \ + _ReturnPolicy(_SecureFuncName(_HArg1, _Dst, 1, _TArg1), _Dst); \ + } \ + } + + #define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_2_0_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _HType1, _HArg1, _HType2, _HArg2, _SalAttributeDst, _DstType, _Dst) \ + __inline \ + _ReturnType __CRTDECL __insecure_##_FuncName(_HType1 _HArg1, _HType2 _HArg2, _SalAttributeDst _DstType *_Dst) \ + { \ + _ReturnType __cdecl _FuncName(_HType1 _HArg1, _HType2 _HArg2, _SalAttributeDst _DstType *_Dst); \ + return _FuncName(_HArg1, _HArg2, _Dst); \ + } \ + extern "C++" \ + { \ + template \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName(_HType1 _HArg1, _HType2 _HArg2, _T &_Dst) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(_HArg1, _HArg2, static_cast<_DstType *>(_Dst)); \ + } \ + template \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName(_HType1 _HArg1, _HType2 _HArg2, const _T &_Dst) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(_HArg1, _HArg2, static_cast<_DstType *>(_Dst)); \ + } \ + template <> \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName(_HType1 _HArg1, _HType2 _HArg2, _SalAttributeDst _DstType * &_Dst) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(_HArg1, _HArg2, _Dst); \ + } \ + template \ + inline \ + _ReturnType __CRTDECL _FuncName(_HType1 _HArg1, _HType2 _HArg2, _DstType (&_Dst)[_Size]) _CRT_SECURE_CPP_NOTHROW \ + { \ + _ReturnPolicy(_SecureFuncName(_HArg1, _HArg2, _Dst, _Size), _Dst); \ + } \ + template <> \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName<1>(_HType1 _HArg1, _HType2 _HArg2, _DstType (&_Dst)[1]) _CRT_SECURE_CPP_NOTHROW \ + { \ + _ReturnPolicy(_SecureFuncName(_HArg1, _HArg2, _Dst, 1), _Dst); \ + } \ + } + + #define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1_ARGLIST_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _CC, _FuncName, _SecureFuncName, _VFuncName, _SecureVFuncName, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1) \ + __inline \ + _ReturnType __CRTDECL __insecure_##_VFuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, va_list _ArgList) \ + { \ + _ReturnType _CC _VFuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, va_list _ArgList); \ + return _VFuncName(_Dst, _TArg1, _ArgList); \ + } \ + extern "C++" \ + { \ + template \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName(_T &_Dst, _TType1 _TArg1, ...) _CRT_SECURE_CPP_NOTHROW \ + { \ + va_list _ArgList; \ + __crt_va_start(_ArgList, _TArg1); \ + return __insecure_##_VFuncName(static_cast<_DstType *>(_Dst), _TArg1, _ArgList); \ + } \ + template \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName(const _T &_Dst, _TType1 _TArg1, ...) _CRT_SECURE_CPP_NOTHROW \ + { \ + va_list _ArgList; \ + __crt_va_start(_ArgList, _TArg1); \ + return __insecure_##_VFuncName(static_cast<_DstType *>(_Dst), _TArg1, _ArgList); \ + } \ + \ + template <> \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName(_SalAttributeDst _DstType * &_Dst, _TType1 _TArg1, ...) _CRT_SECURE_CPP_NOTHROW \ + { \ + va_list _ArgList; \ + __crt_va_start(_ArgList, _TArg1); \ + return __insecure_##_VFuncName(_Dst, _TArg1, _ArgList); \ + } \ + \ + template \ + inline \ + _ReturnType __CRTDECL _FuncName(_DstType (&_Dst)[_Size], _TType1 _TArg1, ...) _CRT_SECURE_CPP_NOTHROW \ + { \ + va_list _ArgList; \ + __crt_va_start(_ArgList, _TArg1); \ + _ReturnPolicy(_SecureVFuncName(_Dst, _Size, _TArg1, _ArgList), _Dst); \ + } \ + \ + template <> \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName<1>(_DstType (&_Dst)[1], _TType1 _TArg1, ...) _CRT_SECURE_CPP_NOTHROW \ + { \ + va_list _ArgList; \ + __crt_va_start(_ArgList, _TArg1); \ + _ReturnPolicy(_SecureVFuncName(_Dst, 1, _TArg1, _ArgList), _Dst); \ + } \ + \ + template \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureVFuncName) \ + _ReturnType __CRTDECL _VFuncName(_T &_Dst, _TType1 _TArg1, va_list _ArgList) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_VFuncName(static_cast<_DstType *>(_Dst), _TArg1, _ArgList); \ + } \ + template \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureVFuncName) \ + _ReturnType __CRTDECL _VFuncName(const _T &_Dst, _TType1 _TArg1, va_list _ArgList) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_VFuncName(static_cast<_DstType *>(_Dst), _TArg1, _ArgList); \ + } \ + template <> \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureVFuncName) \ + _ReturnType __CRTDECL _VFuncName(_SalAttributeDst _DstType *&_Dst, _TType1 _TArg1, va_list _ArgList) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_VFuncName(_Dst, _TArg1, _ArgList); \ + } \ + template \ + inline \ + _ReturnType __CRTDECL _VFuncName(_DstType (&_Dst)[_Size], _TType1 _TArg1, va_list _ArgList) _CRT_SECURE_CPP_NOTHROW \ + { \ + _ReturnPolicy(_SecureVFuncName(_Dst, _Size, _TArg1, _ArgList), _Dst); \ + } \ + template <> \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureVFuncName) \ + _ReturnType __CRTDECL _VFuncName<1>(_DstType (&_Dst)[1], _TType1 _TArg1, va_list _ArgList) _CRT_SECURE_CPP_NOTHROW \ + { \ + _ReturnPolicy(_SecureVFuncName(_Dst, 1, _TArg1, _ArgList), _Dst); \ + } \ + } + + #define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_2_ARGLIST_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _CC, _FuncName, _VFuncName, _SecureVFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) \ + __inline \ + _ReturnType __CRTDECL __insecure_##_VFuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2, va_list _ArgList) \ + { \ + _ReturnType _CC _VFuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2, va_list _ArgList); \ + return _VFuncName(_Dst, _TArg1, _TArg2, _ArgList); \ + } \ + extern "C++" \ + { \ + template \ + inline \ + _CRT_INSECURE_DEPRECATE(_FuncName##_s) \ + _ReturnType __CRTDECL _FuncName(_T &_Dst, _TType1 _TArg1, _TType2 _TArg2, ...) _CRT_SECURE_CPP_NOTHROW \ + { \ + va_list _ArgList; \ + __crt_va_start(_ArgList, _TArg2); \ + return __insecure_##_VFuncName(static_cast<_DstType *>(_Dst), _TArg1, _TArg2, _ArgList); \ + } \ + template \ + inline \ + _CRT_INSECURE_DEPRECATE(_FuncName##_s) \ + _ReturnType __CRTDECL _FuncName(const _T &_Dst, _TType1 _TArg1, _TType2 _TArg2, ...) _CRT_SECURE_CPP_NOTHROW \ + { \ + va_list _ArgList; \ + __crt_va_start(_ArgList, _TArg2); \ + return __insecure_##_VFuncName(static_cast<_DstType *>(_Dst), _TArg1, _TArg2, _ArgList); \ + } \ + \ + template <> \ + inline \ + _CRT_INSECURE_DEPRECATE(_FuncName##_s) \ + _ReturnType __CRTDECL _FuncName(_SalAttributeDst _DstType * &_Dst, _TType1 _TArg1, _TType2 _TArg2, ...) _CRT_SECURE_CPP_NOTHROW \ + { \ + va_list _ArgList; \ + __crt_va_start(_ArgList, _TArg2); \ + return __insecure_##_VFuncName(_Dst, _TArg1, _TArg2, _ArgList); \ + } \ + \ + template \ + inline \ + _ReturnType __CRTDECL _FuncName(_SecureDstType (&_Dst)[_Size], _TType1 _TArg1, _TType2 _TArg2, ...) _CRT_SECURE_CPP_NOTHROW \ + { \ + va_list _ArgList; \ + __crt_va_start(_ArgList, _TArg2); \ + _ReturnPolicy(_SecureVFuncName(_Dst, _Size, _TArg1, _TArg2, _ArgList), _Dst); \ + } \ + \ + template <> \ + inline \ + _CRT_INSECURE_DEPRECATE(_FuncName##_s) \ + _ReturnType __CRTDECL _FuncName<1>(_DstType (&_Dst)[1], _TType1 _TArg1, _TType2 _TArg2, ...) _CRT_SECURE_CPP_NOTHROW \ + { \ + va_list _ArgList; \ + __crt_va_start(_ArgList, _TArg2); \ + _ReturnPolicy(_SecureVFuncName(_Dst, 1, _TArg1, _TArg2, _ArgList), _Dst); \ + } \ + \ + template \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureVFuncName) \ + _ReturnType __CRTDECL _VFuncName(_T &_Dst, _TType1 _TArg1, _TType2 _TArg2, va_list _ArgList) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_VFuncName(static_cast<_DstType *>(_Dst), _TArg1, _TArg2, _ArgList); \ + } \ + template \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureVFuncName) \ + _ReturnType __CRTDECL _VFuncName(const _T &_Dst, _TType1 _TArg1, _TType2 _TArg2, va_list _ArgList) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_VFuncName(static_cast<_DstType *>(_Dst), _TArg1, _TArg2, _ArgList); \ + } \ + template <> \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureVFuncName) \ + _ReturnType __CRTDECL _VFuncName(_SalAttributeDst _DstType *&_Dst, _TType1 _TArg1, _TType2 _TArg2, va_list _ArgList) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_VFuncName(_Dst, _TArg1, _TArg2, _ArgList); \ + } \ + template \ + inline \ + _ReturnType __CRTDECL _VFuncName(_SecureDstType (&_Dst)[_Size], _TType1 _TArg1, _TType2 _TArg2, va_list _ArgList) _CRT_SECURE_CPP_NOTHROW \ + { \ + _ReturnPolicy(_SecureVFuncName(_Dst, _Size, _TArg1, _TArg2, _ArgList), _Dst); \ + } \ + template <> \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureVFuncName) \ + _ReturnType __CRTDECL _VFuncName<1>(_DstType (&_Dst)[1], _TType1 _TArg1, _TType2 _TArg2, va_list _ArgList) _CRT_SECURE_CPP_NOTHROW \ + { \ + _ReturnPolicy(_SecureVFuncName(_Dst, 1, _TArg1, _TArg2, _ArgList), _Dst); \ + } \ + } + + #define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_2_SIZE_EX(_DeclSpec, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) \ + __inline \ + size_t __CRTDECL __insecure_##_FuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2) \ + { \ + _DeclSpec size_t __cdecl _FuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2); \ + return _FuncName(_Dst, _TArg1, _TArg2); \ + } \ + extern "C++" \ + { \ + template \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + size_t __CRTDECL _FuncName(_T &_Dst, _TType1 _TArg1, _TType2 _TArg2) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(static_cast<_DstType *>(_Dst), _TArg1, _TArg2); \ + } \ + template \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + size_t __CRTDECL _FuncName(const _T &_Dst, _TType1 _TArg1, _TType2 _TArg2) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(static_cast<_DstType *>(_Dst), _TArg1, _TArg2); \ + } \ + template <> \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + size_t __CRTDECL _FuncName(_SalAttributeDst _DstType * &_Dst, _TType1 _TArg1, _TType2 _TArg2) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(_Dst, _TArg1, _TArg2); \ + } \ + template \ + inline \ + size_t __CRTDECL _FuncName(_SecureDstType (&_Dst)[_Size], _TType1 _TArg1, _TType2 _TArg2) _CRT_SECURE_CPP_NOTHROW \ + { \ + size_t _Ret = 0; \ + _SecureFuncName(&_Ret, _Dst, _Size, _TArg1, _TArg2); \ + return (_Ret > 0 ? (_Ret - 1) : _Ret); \ + } \ + template <> \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + size_t __CRTDECL _FuncName<1>(_DstType (&_Dst)[1], _TType1 _TArg1, _TType2 _TArg2) _CRT_SECURE_CPP_NOTHROW \ + { \ + size_t _Ret = 0; \ + _SecureFuncName(&_Ret, _Dst, 1, _TArg1, _TArg2); \ + return (_Ret > 0 ? (_Ret - 1) : _Ret); \ + } \ + } + + #define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_3_SIZE_EX(_DeclSpec, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3) \ + __inline \ + size_t __CRTDECL __insecure_##_FuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3) \ + { \ + _DeclSpec size_t __cdecl _FuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3); \ + return _FuncName(_Dst, _TArg1, _TArg2, _TArg3); \ + } \ + extern "C++" \ + { \ + template \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + size_t __CRTDECL _FuncName(_T &_Dst, _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(static_cast<_DstType *>(_Dst), _TArg1, _TArg2, _TArg3); \ + } \ + template \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + size_t __CRTDECL _FuncName(const _T &_Dst, _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(static_cast<_DstType *>(_Dst), _TArg1, _TArg2, _TArg3); \ + } \ + template <> \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + size_t __CRTDECL _FuncName(_SalAttributeDst _DstType * &_Dst, _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(_Dst, _TArg1, _TArg2, _TArg3); \ + } \ + template \ + inline \ + size_t __CRTDECL _FuncName(_SecureDstType (&_Dst)[_Size], _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3) _CRT_SECURE_CPP_NOTHROW \ + { \ + size_t _Ret = 0; \ + _SecureFuncName(&_Ret, _Dst, _Size, _TArg1, _TArg2, _TArg3); \ + return (_Ret > 0 ? (_Ret - 1) : _Ret); \ + } \ + template <> \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + size_t __CRTDECL _FuncName<1>(_DstType (&_Dst)[1], _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3) _CRT_SECURE_CPP_NOTHROW \ + { \ + size_t _Ret = 0; \ + _SecureFuncName(&_Ret, _Dst, 1, _TArg1, _TArg2, _TArg3); \ + return (_Ret > 0 ? (_Ret - 1) : _Ret); \ + } \ + } + + #define __DECLARE_CPP_OVERLOAD_INLINE_FUNC_0_0_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _DstType, _Dst) \ + __inline \ + _ReturnType __CRTDECL __insecure_##_FuncName(_DstType *_Dst) + + #define __DEFINE_CPP_OVERLOAD_INLINE_FUNC_0_0_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _DstType, _Dst) \ + extern "C++" \ + { \ + template \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName(_T &_Dst) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(static_cast<_DstType *>(_Dst)); \ + } \ + template \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName(const _T &_Dst) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(static_cast<_DstType *>(_Dst)); \ + } \ + template <> \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName(_DstType * &_Dst) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(_Dst); \ + } \ + template \ + inline \ + _ReturnType __CRTDECL _FuncName(_SecureDstType (&_Dst)[_Size]) _CRT_SECURE_CPP_NOTHROW \ + { \ + _ReturnPolicy(_SecureFuncName(_Dst, _Size), _Dst); \ + } \ + template <> \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName<1>(_DstType (&_Dst)[1]) _CRT_SECURE_CPP_NOTHROW \ + { \ + _ReturnPolicy(_SecureFuncName(_Dst, 1), _Dst); \ + } \ + } + + #define __DECLARE_CPP_OVERLOAD_INLINE_FUNC_0_1_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _DstType, _Dst, _TType1, _TArg1) \ + __inline \ + _ReturnType __CRTDECL __insecure_##_FuncName(_DstType *_Dst, _TType1 _TArg1) + + #define __DEFINE_CPP_OVERLOAD_INLINE_FUNC_0_1_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _DstType, _Dst, _TType1, _TArg1) \ + extern "C++" \ + { \ + template \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName(_T &_Dst, _TType1 _TArg1) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(static_cast<_DstType *>(_Dst), _TArg1); \ + } \ + template \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName(const _T &_Dst, _TType1 _TArg1) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(static_cast<_DstType *>(_Dst), _TArg1); \ + } \ + template <> \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName(_DstType * &_Dst, _TType1 _TArg1) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(_Dst, _TArg1); \ + } \ + template \ + inline \ + _ReturnType __CRTDECL _FuncName(_SecureDstType (&_Dst)[_Size], _TType1 _TArg1) _CRT_SECURE_CPP_NOTHROW \ + { \ + _ReturnPolicy(_SecureFuncName(_Dst, _Size, _TArg1), _Dst); \ + } \ + template <> \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName<1>(_DstType (&_Dst)[1], _TType1 _TArg1) _CRT_SECURE_CPP_NOTHROW \ + { \ + _ReturnPolicy(_SecureFuncName(_Dst, 1, _TArg1), _Dst); \ + } \ + } + + #define __DECLARE_CPP_OVERLOAD_INLINE_FUNC_0_2_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) \ + __inline \ + _ReturnType __CRTDECL __insecure_##_FuncName(_DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2) + + #define __DEFINE_CPP_OVERLOAD_INLINE_FUNC_0_2_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) \ + extern "C++" \ + { \ + template \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName(_T &_Dst, _TType1 _TArg1, _TType2 _TArg2) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(static_cast<_DstType *>(_Dst), _TArg1, _TArg2); \ + } \ + template \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName(const _T &_Dst, _TType1 _TArg1, _TType2 _TArg2) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(static_cast<_DstType *>(_Dst), _TArg1, _TArg2); \ + } \ + template <> \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName(_SalAttributeDst _DstType * &_Dst, _TType1 _TArg1, _TType2 _TArg2) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(_Dst, _TArg1, _TArg2); \ + } \ + template \ + inline \ + _ReturnType __CRTDECL _FuncName(_SecureDstType (&_Dst)[_Size], _TType1 _TArg1, _TType2 _TArg2) _CRT_SECURE_CPP_NOTHROW \ + { \ + _ReturnPolicy(_SecureFuncName(_Dst, _Size, _TArg1, _TArg2), _Dst); \ + } \ + template <> \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName<1>(_DstType (&_Dst)[1], _TType1 _TArg1, _TType2 _TArg2) _CRT_SECURE_CPP_NOTHROW \ + { \ + _ReturnPolicy(_SecureFuncName(_Dst, 1, _TArg1, _TArg2), _Dst); \ + } \ + } + + #define __DECLARE_CPP_OVERLOAD_INLINE_FUNC_0_3_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3) \ + __inline \ + _ReturnType __CRTDECL __insecure_##_FuncName(_DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3) + + #define __DEFINE_CPP_OVERLOAD_INLINE_FUNC_0_3_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3) \ + extern "C++" \ + { \ + template \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName(_T &_Dst, _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(static_cast<_DstType *>(_Dst), _TArg1, _TArg2, _TArg3); \ + } \ + template \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName(const _T &_Dst, _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(static_cast<_DstType *>(_Dst), _TArg1, _TArg2, _TArg3); \ + } \ + template <> \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName(_SalAttributeDst _DstType * &_Dst, _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3) _CRT_SECURE_CPP_NOTHROW \ + { \ + return __insecure_##_FuncName(_Dst, _TArg1, _TArg2, _TArg3); \ + } \ + template \ + inline \ + _ReturnType __CRTDECL _FuncName(_SecureDstType (&_Dst)[_Size], _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3) _CRT_SECURE_CPP_NOTHROW \ + { \ + _ReturnPolicy(_SecureFuncName(_Dst, _Size, _TArg1, _TArg2, _TArg3), _Dst); \ + } \ + template <> \ + inline \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + _ReturnType __CRTDECL _FuncName<1>(_DstType (&_Dst)[1], _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3) _CRT_SECURE_CPP_NOTHROW \ + { \ + _ReturnPolicy(_SecureFuncName(_Dst, 1, _TArg1, _TArg2, _TArg3), _Dst); \ + } \ + } + + #if _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT + + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_0_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _SalAttributeDst, _DstType, _Dst) \ + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_0_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _SalAttributeDst, _DstType, _Dst) + + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_0_CGETS(_ReturnType, _DeclSpec, _FuncName, _SalAttributeDst, _DstType, _Dst) \ + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_0_CGETS(_ReturnType, _DeclSpec, _FuncName, _SalAttributeDst, _DstType, _Dst) + + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_1_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1) \ + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1) + + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) \ + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_2_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) + + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_3_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3) \ + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_3_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3) + + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_4_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3, _TType4) \ + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_4_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3, _TType4) + + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_1_1_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _HType1, _HArg1, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1) \ + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_1_1_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _HType1, _HArg1, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1) + + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_2_0_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _HType1, _HArg1, _HType2, _HArg2, _SalAttributeDst, _DstType, _Dst) \ + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_2_0_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _HType1, _HArg1, _HType2, _HArg2, _SalAttributeDst, _DstType, _Dst) + + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_1_ARGLIST_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _CC, _FuncName, _SecureFuncName, _VFuncName, _SecureVFuncName, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1) \ + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1_ARGLIST_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _CC, _FuncName, _SecureFuncName, _VFuncName, _SecureVFuncName, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1) + + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2_ARGLIST(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _VFuncName, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) \ + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_2_ARGLIST(_ReturnType, _ReturnPolicy, _DeclSpec, __cdecl, _FuncName, _VFuncName, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) + + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2_ARGLIST_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _CC, _FuncName, _VFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) \ + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_2_ARGLIST_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _CC, _FuncName, _VFuncName, _VFuncName##_s, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) + + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2_SIZE_EX(_DeclSpec, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) \ + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_2_SIZE_EX(_DeclSpec, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) + + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_3_SIZE_EX(_DeclSpec, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3) \ + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_3_SIZE_EX(_DeclSpec, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3) + + + #define __DECLARE_CPP_OVERLOAD_INLINE_NFUNC_0_0_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _DstType, _Dst) \ + __DECLARE_CPP_OVERLOAD_INLINE_FUNC_0_0_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType _DstType, _Dst) + + #define __DEFINE_CPP_OVERLOAD_INLINE_NFUNC_0_0_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _DstType, _Dst) \ + __DEFINE_CPP_OVERLOAD_INLINE_FUNC_0_0_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _DstType, _Dst) + + #define __DECLARE_CPP_OVERLOAD_INLINE_NFUNC_0_1_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _DstType, _Dst, _TType1, _TArg1) \ + __DECLARE_CPP_OVERLOAD_INLINE_FUNC_0_1_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType _DstType, _Dst, _TType1, _TArg1) + + #define __DEFINE_CPP_OVERLOAD_INLINE_NFUNC_0_1_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _DstType, _Dst, _TType1, _TArg1) \ + __DEFINE_CPP_OVERLOAD_INLINE_FUNC_0_1_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _DstType, _Dst, _TType1, _TArg1) + + #define __DECLARE_CPP_OVERLOAD_INLINE_NFUNC_0_2_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) \ + __DECLARE_CPP_OVERLOAD_INLINE_FUNC_0_2_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) + + #define __DEFINE_CPP_OVERLOAD_INLINE_NFUNC_0_2_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) \ + __DEFINE_CPP_OVERLOAD_INLINE_FUNC_0_2_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) + + #define __DECLARE_CPP_OVERLOAD_INLINE_NFUNC_0_3_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3) \ + __DECLARE_CPP_OVERLOAD_INLINE_FUNC_0_3_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3) + + #define __DEFINE_CPP_OVERLOAD_INLINE_NFUNC_0_3_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3) \ + __DEFINE_CPP_OVERLOAD_INLINE_FUNC_0_3_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3) + + #else // ^^^ _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT ^^^ // vvv _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT vvv // + + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_0_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _SalAttributeDst, _DstType, _Dst) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) _DeclSpec _ReturnType __cdecl _FuncName(_SalAttributeDst _DstType *_Dst); + + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_0_GETS(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _DstType, _Dst) \ + _CRT_INSECURE_DEPRECATE(_FuncName##_s) _DeclSpec _ReturnType __cdecl _FuncName(_DstType *_Dst); + + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_1_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) _DeclSpec _ReturnType __cdecl _FuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1); + + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) _DeclSpec _ReturnType __cdecl _FuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2); + + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_3_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) _DeclSpec _ReturnType __cdecl _FuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3); + + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_4_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3, _TType4, _TArg4) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) _DeclSpec _ReturnType __cdecl _FuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3, _TType4 _TArg4); + + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_1_1_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _HType1, _HArg1, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) _DeclSpec _ReturnType __cdecl _FuncName(_HType1 _HArg1, _SalAttributeDst _DstType *_Dst, _TType1 _TArg1); + + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_2_0_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _HType1, _HArg1, _HType2, _HArg2, _SalAttributeDst, _DstType, _Dst) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) _DeclSpec _ReturnType __cdecl _FuncName(_HType1 _HArg1, _HType2 _HArg2, _SalAttributeDst _DstType *_Dst); + + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_1_ARGLIST_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _CC, _FuncName, _SecureFuncName,_VFuncName, _SecureVFuncName, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) _DeclSpec _ReturnType _CC _FuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, ...); \ + _CRT_INSECURE_DEPRECATE(_SecureVFuncName) _DeclSpec _ReturnType _CC _VFuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, va_list _Args); + + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2_ARGLIST(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _VFuncName, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) \ + _CRT_INSECURE_DEPRECATE(_FuncName##_s) _DeclSpec _ReturnType __cdecl _FuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2, ...); \ + _CRT_INSECURE_DEPRECATE(_VFuncName##_s) _DeclSpec _ReturnType __cdecl _VFuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2, va_list _Args); + + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2_ARGLIST_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _CC, _FuncName, _VFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) \ + _CRT_INSECURE_DEPRECATE(_FuncName##_s) _DeclSpec _ReturnType _CC _FuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2, ...); \ + _CRT_INSECURE_DEPRECATE(_VFuncName##_s) _DeclSpec _ReturnType _CC _VFuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2, va_list _Args); + + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2_SIZE_EX(_DeclSpec, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) _DeclSpec size_t __cdecl _FuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2); + + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_3_SIZE_EX(_DeclSpec, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) _DeclSpec size_t __cdecl _FuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3); + + + #define __DECLARE_CPP_OVERLOAD_INLINE_NFUNC_0_0_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _DstType, _Dst) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + __inline \ + _ReturnType __CRTDECL _FuncName(_DstType *_Dst) + + #define __DEFINE_CPP_OVERLOAD_INLINE_NFUNC_0_0_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _DstType, _Dst) + + #define __DECLARE_CPP_OVERLOAD_INLINE_NFUNC_0_1_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _DstType, _Dst, _TType1, _TArg1) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + __inline \ + _ReturnType __CRTDECL _FuncName(_DstType *_Dst, _TType1 _TArg1) + + #define __DEFINE_CPP_OVERLOAD_INLINE_NFUNC_0_1_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _DstType, _Dst, _TType1, _TArg1) + + #define __DECLARE_CPP_OVERLOAD_INLINE_NFUNC_0_2_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + __inline \ + _ReturnType __CRTDECL _FuncName(_DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2) + + #define __DEFINE_CPP_OVERLOAD_INLINE_NFUNC_0_2_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) + + #define __DECLARE_CPP_OVERLOAD_INLINE_NFUNC_0_3_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + __inline \ + _ReturnType __CRTDECL _FuncName(_DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3) + + #define __DEFINE_CPP_OVERLOAD_INLINE_NFUNC_0_3_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3) + + #endif // !_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT + + #else // ^^^ _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES ^^^ // vvv !_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES vvv // + + #define __RETURN_POLICY_SAME(_FunctionCall) + #define __RETURN_POLICY_DST(_FunctionCall) + #define __RETURN_POLICY_VOID(_FunctionCall) + #define __EMPTY_DECLSPEC + + #if _CRT_FUNCTIONS_REQUIRED + + #define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_0_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _SalAttributeDst, _DstType, _Dst) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) _DeclSpec _ReturnType __cdecl _FuncName(_SalAttributeDst _DstType *_Dst); + + #define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_0_CGETS(_ReturnType, _DeclSpec, _FuncName, _SalAttributeDst, _DstType, _Dst) \ + _CRT_INSECURE_DEPRECATE(_FuncName##_s) _DeclSpec _ReturnType __cdecl _FuncName(_SalAttributeDst _DstType *_Dst); + + #define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) _DeclSpec _ReturnType __cdecl _FuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1); + + #define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_2_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) _DeclSpec _ReturnType __cdecl _FuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2); + + #define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_3_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) _DeclSpec _ReturnType __cdecl _FuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3); + + #define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_4_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3, _TType4, _TArg4) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) _DeclSpec _ReturnType __cdecl _FuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3, _TType4 _TArg4); + + #define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_1_1_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _HType1, _HArg1, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) _DeclSpec _ReturnType __cdecl _FuncName(_HType1 _HArg1, _SalAttributeDst _DstType *_Dst, _TType1 _TArg1); + + #define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_2_0_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _HType1, _HArg1, _HType2, _HArg2, _SalAttributeDst, _DstType, _Dst) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) _DeclSpec _ReturnType __cdecl _FuncName(_HType1 _HArg1, _HType2 _HArg2, _SalAttributeDst _DstType *_Dst); + + #define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1_ARGLIST_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _CC, _FuncName, _SecureFuncName, _VFuncName, _SecureVFuncName, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) _DeclSpec _ReturnType _CC _FuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, ...); \ + _CRT_INSECURE_DEPRECATE(_SecureVFuncName) _DeclSpec _ReturnType _CC _VFuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, va_list _Args); + + #define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_2_ARGLIST_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _CC, _FuncName, _VFuncName, _SecureVFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) \ + _CRT_INSECURE_DEPRECATE(_FuncName##_s) _DeclSpec _ReturnType _CC _FuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2, ...); \ + _CRT_INSECURE_DEPRECATE(_SecureVFuncName) _DeclSpec _ReturnType _CC _VFuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2, va_list _Args); + + #define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_2_SIZE_EX(_DeclSpec, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) _DeclSpec size_t __cdecl _FuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2); + + #define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_3_SIZE_EX(_DeclSpec, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) _DeclSpec size_t __cdecl _FuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3); + + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_0_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _SalAttributeDst, _DstType, _Dst) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) _DeclSpec _ReturnType __cdecl _FuncName(_SalAttributeDst _DstType *_Dst); + + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_0_GETS(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _DstType, _Dst) \ + _CRT_INSECURE_DEPRECATE(_FuncName##_s) _DeclSpec _ReturnType __cdecl _FuncName(_DstType *_Dst); + + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_1_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) _DeclSpec _ReturnType __cdecl _FuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1); + + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) _DeclSpec _ReturnType __cdecl _FuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2); + + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_3_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) _DeclSpec _ReturnType __cdecl _FuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3); + + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_4_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3, _TType4, _TArg4) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) _DeclSpec _ReturnType __cdecl _FuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3, _TType4 _TArg4); + + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_1_1_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _HType1, _HArg1, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) _DeclSpec _ReturnType __cdecl _FuncName(_HType1 _HArg1, _SalAttributeDst _DstType *_Dst, _TType1 _TArg1); + + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_2_0_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _SecureFuncName, _HType1, _HArg1, _HType2, _HArg2, _SalAttributeDst, _DstType, _Dst) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) _DeclSpec _ReturnType __cdecl _FuncName(_HType1 _HArg1, _HType2 _HArg2, _SalAttributeDst _DstType *_Dst); + + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_1_ARGLIST_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _CC, _FuncName, _SecureFuncName, _VFuncName, _SecureVFuncName, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) _DeclSpec _ReturnType _CC _FuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, ...); \ + _CRT_INSECURE_DEPRECATE(_SecureVFuncName) _DeclSpec _ReturnType _CC _VFuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, va_list _Args); + + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2_ARGLIST(_ReturnType, _ReturnPolicy, _DeclSpec, _FuncName, _VFuncName, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) \ + _CRT_INSECURE_DEPRECATE(_FuncName##_s) _DeclSpec _ReturnType __cdecl _FuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2, ...); \ + _CRT_INSECURE_DEPRECATE(_VFuncName##_s) _DeclSpec _ReturnType __cdecl _VFuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2, va_list _Args); + + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2_ARGLIST_EX(_ReturnType, _ReturnPolicy, _DeclSpec, _CC, _FuncName, _VFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) \ + _CRT_INSECURE_DEPRECATE(_FuncName##_s) _DeclSpec _ReturnType _CC _FuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2, ...); \ + _CRT_INSECURE_DEPRECATE(_VFuncName##_s) _DeclSpec _ReturnType _CC _VFuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2, va_list _Args); + + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2_SIZE_EX(_DeclSpec, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) _DeclSpec size_t __cdecl _FuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2); + + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_3_SIZE_EX(_DeclSpec, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) _DeclSpec size_t __cdecl _FuncName(_SalAttributeDst _DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3); + + + #define __DECLARE_CPP_OVERLOAD_INLINE_FUNC_0_0_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _DstType, _Dst) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + __inline \ + _ReturnType __CRTDECL _FuncName(_DstType *_Dst) + + #define __DEFINE_CPP_OVERLOAD_INLINE_FUNC_0_0_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _DstType, _Dst) + + #define __DECLARE_CPP_OVERLOAD_INLINE_FUNC_0_1_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _DstType, _Dst, _TType1, _TArg1) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + __inline \ + _ReturnType __CRTDECL _FuncName(_DstType *_Dst, _TType1 _TArg1) + + #define __DEFINE_CPP_OVERLOAD_INLINE_FUNC_0_1_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _DstType, _Dst, _TType1, _TArg1) + + #define __DECLARE_CPP_OVERLOAD_INLINE_FUNC_0_2_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + __inline \ + _ReturnType __CRTDECL _FuncName(_DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2) + + #define __DEFINE_CPP_OVERLOAD_INLINE_FUNC_0_2_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) + + #define __DECLARE_CPP_OVERLOAD_INLINE_FUNC_0_3_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + __inline \ + _ReturnType __CRTDECL _FuncName(_DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3) + + #define __DEFINE_CPP_OVERLOAD_INLINE_FUNC_0_3_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3) + + #define __DECLARE_CPP_OVERLOAD_INLINE_NFUNC_0_0_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _DstType, _Dst) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + __inline \ + _ReturnType __CRTDECL _FuncName(_DstType *_Dst) + + #define __DEFINE_CPP_OVERLOAD_INLINE_NFUNC_0_0_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _DstType, _Dst) + + #define __DECLARE_CPP_OVERLOAD_INLINE_NFUNC_0_1_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _DstType, _Dst, _TType1, _TArg1) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + __inline \ + _ReturnType __CRTDECL _FuncName(_DstType *_Dst, _TType1 _TArg1) + + #define __DEFINE_CPP_OVERLOAD_INLINE_NFUNC_0_1_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _DstType, _Dst, _TType1, _TArg1) + + #define __DECLARE_CPP_OVERLOAD_INLINE_NFUNC_0_2_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + __inline \ + _ReturnType __CRTDECL _FuncName(_DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2) + + #define __DEFINE_CPP_OVERLOAD_INLINE_NFUNC_0_2_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) + + #define __DECLARE_CPP_OVERLOAD_INLINE_NFUNC_0_3_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3) \ + _CRT_INSECURE_DEPRECATE(_SecureFuncName) \ + __inline \ + _ReturnType __CRTDECL _FuncName(_DstType *_Dst, _TType1 _TArg1, _TType2 _TArg2, _TType3 _TArg3) + + #define __DEFINE_CPP_OVERLOAD_INLINE_NFUNC_0_3_EX(_ReturnType, _ReturnPolicy, _FuncName, _SecureFuncName, _SecureDstType, _SalAttributeDst, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2, _TType3, _TArg3) + + #else // ^^^ _CRT_FUNCTIONS_REQUIRED ^^^ // vvv !_CRT_FUNCTIONS_REQUIRED vvv // + + #define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_0_EX(...) + #define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_0_CGETS(...) + #define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1_EX(...) + #define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_2_EX(...) + #define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_3_EX(...) + #define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_4_EX(...) + #define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_1_1_EX(...) + #define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_2_0_EX(...) + #define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1_ARGLIST_EX(...) + #define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_2_ARGLIST_EX(...) + #define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_2_SIZE_EX(...) + #define __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_3_SIZE_EX(...) + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_0_EX(...) + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_0_GETS(...) + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_1_EX(...) + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2_EX(...) + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_3_EX(...) + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_4_EX(...) + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_1_1_EX(...) + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_2_0_EX(...) + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_1_ARGLIST_EX(...) + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2_ARGLIST(...) + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2_ARGLIST_EX(...) + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2_SIZE_EX(...) + #define __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_3_SIZE_EX(...) + #define __DECLARE_CPP_OVERLOAD_INLINE_FUNC_0_0_EX(...) + #define __DEFINE_CPP_OVERLOAD_INLINE_FUNC_0_0_EX(...) + #define __DECLARE_CPP_OVERLOAD_INLINE_FUNC_0_1_EX(...) + #define __DEFINE_CPP_OVERLOAD_INLINE_FUNC_0_1_EX(...) + #define __DECLARE_CPP_OVERLOAD_INLINE_FUNC_0_2_EX(...) + #define __DEFINE_CPP_OVERLOAD_INLINE_FUNC_0_2_EX(...) + #define __DECLARE_CPP_OVERLOAD_INLINE_FUNC_0_3_EX(...) + #define __DEFINE_CPP_OVERLOAD_INLINE_FUNC_0_3_EX(...) + #define __DECLARE_CPP_OVERLOAD_INLINE_NFUNC_0_0_EX(...) + #define __DEFINE_CPP_OVERLOAD_INLINE_NFUNC_0_0_EX(...) + #define __DECLARE_CPP_OVERLOAD_INLINE_NFUNC_0_1_EX(...) + #define __DEFINE_CPP_OVERLOAD_INLINE_NFUNC_0_1_EX(...) + #define __DECLARE_CPP_OVERLOAD_INLINE_NFUNC_0_2_EX(...) + #define __DEFINE_CPP_OVERLOAD_INLINE_NFUNC_0_2_EX(...) + #define __DECLARE_CPP_OVERLOAD_INLINE_NFUNC_0_3_EX(...) + #define __DEFINE_CPP_OVERLOAD_INLINE_NFUNC_0_3_EX(...) + + #endif // !_CRT_FUNCTIONS_REQUIRED + #endif // !_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES +#endif + +_CRT_END_C_HEADER + +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS diff --git a/sdk/include/ucrt/corecrt_io.h b/sdk/include/ucrt/corecrt_io.h new file mode 100644 index 0000000000000..5beefbc881225 --- /dev/null +++ b/sdk/include/ucrt/corecrt_io.h @@ -0,0 +1,572 @@ +// +// corecrt_io.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// This file declares the low-level I/O and file handling functionality. These +// declarations are split out to support the Windows build. +// +#pragma once + +#include +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Types +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#ifdef _USE_32BIT_TIME_T + #define _finddata_t _finddata32_t + #define _finddatai64_t _finddata32i64_t +#else + #define _finddata_t _finddata64i32_t + #define _finddatai64_t __finddata64_t +#endif + +struct _finddata32_t +{ + unsigned attrib; + __time32_t time_create; // -1 for FAT file systems + __time32_t time_access; // -1 for FAT file systems + __time32_t time_write; + _fsize_t size; + char name[260]; +}; + +struct _finddata32i64_t +{ + unsigned attrib; + __time32_t time_create; // -1 for FAT file systems + __time32_t time_access; // -1 for FAT file systems + __time32_t time_write; + __int64 size; + char name[260]; +}; + +struct _finddata64i32_t +{ + unsigned attrib; + __time64_t time_create; // -1 for FAT file systems + __time64_t time_access; // -1 for FAT file systems + __time64_t time_write; + _fsize_t size; + char name[260]; +}; + +struct __finddata64_t +{ + unsigned attrib; + __time64_t time_create; // -1 for FAT file systems + __time64_t time_access; // -1 for FAT file systems + __time64_t time_write; + __int64 size; + char name[260]; +}; + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Macros +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// File attribute constants for the _findfirst() family of functions +#define _A_NORMAL 0x00 // Normal file - No read/write restrictions +#define _A_RDONLY 0x01 // Read only file +#define _A_HIDDEN 0x02 // Hidden file +#define _A_SYSTEM 0x04 // System file +#define _A_SUBDIR 0x10 // Subdirectory +#define _A_ARCH 0x20 // Archive file + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Functions +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#ifdef _USE_32BIT_TIME_T + #define _findfirst _findfirst32 + #define _findnext _findnext32 + #define _findfirsti64 _findfirst32i64 + #define _findnexti64 _findnext32i64 +#else + #define _findfirst _findfirst64i32 + #define _findnext _findnext64i32 + #define _findfirsti64 _findfirst64 + #define _findnexti64 _findnext64 +#endif + +#if _CRT_FUNCTIONS_REQUIRED + + _Check_return_ + _ACRTIMP int __cdecl _access( + _In_z_ char const* _FileName, + _In_ int _AccessMode + ); + + _Check_return_wat_ + _ACRTIMP errno_t __cdecl _access_s( + _In_z_ char const* _FileName, + _In_ int _AccessMode + ); + + _Check_return_ + _ACRTIMP int __cdecl _chmod( + _In_z_ char const* _FileName, + _In_ int _Mode + ); + + _Check_return_ + _ACRTIMP int __cdecl _chsize( + _In_ int _FileHandle, + _In_ long _Size + ); + + _Check_return_wat_ + _ACRTIMP errno_t __cdecl _chsize_s( + _In_ int _FileHandle, + _In_ __int64 _Size + ); + + _Check_return_opt_ + _ACRTIMP int __cdecl _close( + _In_ int _FileHandle + ); + + _Check_return_opt_ + _ACRTIMP int __cdecl _commit( + _In_ int _FileHandle + ); + + _Check_return_ _CRT_INSECURE_DEPRECATE(_sopen_s) + _ACRTIMP int __cdecl _creat( + _In_z_ char const* _FileName, + _In_ int _PermissionMode + ); + + _Check_return_ + _ACRTIMP int __cdecl _dup( + _In_ int _FileHandle + ); + + _Check_return_ + _ACRTIMP int __cdecl _dup2( + _In_ int _FileHandleSrc, + _In_ int _FileHandleDst + ); + + _Check_return_ + _ACRTIMP int __cdecl _eof( + _In_ int _FileHandle + ); + + _Check_return_ + _ACRTIMP long __cdecl _filelength( + _In_ int _FileHandle + ); + + _Success_(return != -1) + _Check_return_ + _ACRTIMP intptr_t __cdecl _findfirst32( + _In_z_ char const* _FileName, + _Out_ struct _finddata32_t* _FindData + ); + + _Success_(return != -1) + _Check_return_ + _ACRTIMP int __cdecl _findnext32( + _In_ intptr_t _FindHandle, + _Out_ struct _finddata32_t* _FindData + ); + + _Check_return_opt_ + _ACRTIMP int __cdecl _findclose( + _In_ intptr_t _FindHandle + ); + + _ACRTIMP intptr_t __cdecl _get_osfhandle( + _In_ int _FileHandle + ); + + _Check_return_ + _ACRTIMP int __cdecl _isatty( + _In_ int _FileHandle + ); + + _ACRTIMP int __cdecl _locking( + _In_ int _FileHandle, + _In_ int _LockMode, + _In_ long _NumOfBytes + ); + + _Check_return_opt_ + _ACRTIMP long __cdecl _lseek( + _In_ int _FileHandle, + _In_ long _Offset, + _In_ int _Origin + ); + + _Success_(return == 0) + _Check_return_wat_ + _ACRTIMP errno_t __cdecl _mktemp_s( + _Inout_updates_z_(_Size) char* _TemplateName, + _In_ size_t _Size + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_0( + errno_t, _mktemp_s, + _Prepost_z_ char, _TemplateName + ) + + _Success_(return != 0) + _Check_return_ __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_0( + char *, __RETURN_POLICY_DST, _ACRTIMP, _mktemp, + _Inout_z_, char, _TemplateName + ) + + _ACRTIMP int __cdecl _open_osfhandle( + _In_ intptr_t _OSFileHandle, + _In_ int _Flags + ); + + #ifdef _CRT_USE_WINAPI_FAMILY_DESKTOP_APP + _Success_(return != -1) + _Check_return_ + _DCRTIMP int __cdecl _pipe( + _Out_writes_(2) int* _PtHandles, + _In_ unsigned int _PipeSize, + _In_ int _TextMode + ); + #endif + + _Success_(return != -1) + _Check_return_ + _ACRTIMP int __cdecl _read( + _In_ int _FileHandle, + _Out_writes_bytes_(_MaxCharCount) void* _DstBuf, + _In_ unsigned int _MaxCharCount + ); + + _ACRTIMP int __cdecl remove( + _In_z_ char const* _FileName + ); + + _Check_return_ + _ACRTIMP int __cdecl rename( + _In_z_ char const* _OldFilename, + _In_z_ char const* _NewFilename + ); + + _ACRTIMP int __cdecl _unlink( + _In_z_ char const* _FileName + ); + + _Check_return_ + _ACRTIMP int __cdecl _setmode( + _In_ int _FileHandle, + _In_ int _Mode + ); + + _Check_return_ + _ACRTIMP long __cdecl _tell( + _In_ int _FileHandle + ); + + _CRT_INSECURE_DEPRECATE(_umask_s) + _ACRTIMP int __cdecl _umask( + _In_ int _Mode + ); + + _Check_return_wat_ + _ACRTIMP errno_t __cdecl _umask_s( + _In_ int _NewMode, + _Out_ int* _OldMode + ); + + _ACRTIMP int __cdecl _write( + _In_ int _FileHandle, + _In_reads_bytes_(_MaxCharCount) void const* _Buf, + _In_ unsigned int _MaxCharCount + ); + + _Check_return_ + _ACRTIMP __int64 __cdecl _filelengthi64( + _In_ int _FileHandle + ); + + _Success_(return != -1) + _Check_return_ + _ACRTIMP intptr_t __cdecl _findfirst32i64( + _In_z_ char const* _FileName, + _Out_ struct _finddata32i64_t* _FindData + ); + + _Success_(return != -1) + _Check_return_ + _ACRTIMP intptr_t __cdecl _findfirst64i32( + _In_z_ char const* _FileName, + _Out_ struct _finddata64i32_t* _FindData + ); + + _Success_(return != -1) + _Check_return_ + _ACRTIMP intptr_t __cdecl _findfirst64( + _In_z_ char const* _FileName, + _Out_ struct __finddata64_t* _FindData + ); + + _Success_(return != -1) + _Check_return_ + _ACRTIMP int __cdecl _findnext32i64( + _In_ intptr_t _FindHandle, + _Out_ struct _finddata32i64_t* _FindData + ); + + _Success_(return != -1) + _Check_return_ + _ACRTIMP int __cdecl _findnext64i32( + _In_ intptr_t _FindHandle, + _Out_ struct _finddata64i32_t* _FindData + ); + + _Success_(return != -1) + _Check_return_ + _ACRTIMP int __cdecl _findnext64( + _In_ intptr_t _FindHandle, + _Out_ struct __finddata64_t* _FindData + ); + + _Check_return_opt_ + _ACRTIMP __int64 __cdecl _lseeki64( + _In_ int _FileHandle, + _In_ __int64 _Offset, + _In_ int _Origin + ); + + _Check_return_ + _ACRTIMP __int64 __cdecl _telli64( + _In_ int _FileHandle + ); + + _Check_return_wat_ + _ACRTIMP errno_t __cdecl _sopen_s( + _Out_ int* _FileHandle, + _In_z_ char const* _FileName, + _In_ int _OpenFlag, + _In_ int _ShareFlag, + _In_ int _PermissionMode + ); + + _Check_return_ + _ACRTIMP errno_t __cdecl _sopen_s_nolock( + _Out_ int* _FileHandle, + _In_z_ char const* _FileName, + _In_ int _OpenFlag, + _In_ int _ShareFlag, + _In_ int _PermissionMode + ); + + _ACRTIMP errno_t __cdecl _sopen_dispatch( + _In_z_ char const* _FileName, + _In_ int _OFlag, + _In_ int _ShFlag, + _In_ int _PMode, + _Out_ int* _PFileHandle, + _In_ int _BSecure + ); + + + + #ifdef __cplusplus + + // These function do not validate pmode; use _sopen_s instead. + extern "C++" _Check_return_ _CRT_INSECURE_DEPRECATE(_sopen_s) + inline int __CRTDECL _open( + _In_z_ char const* const _FileName, + _In_ int const _OFlag, + _In_ int const _PMode = 0 + ) + { + int _FileHandle; + // Last parameter passed as 0 because we don't want to validate pmode from _open + errno_t const _Result = _sopen_dispatch(_FileName, _OFlag, _SH_DENYNO, _PMode, &_FileHandle, 0); + return _Result ? -1 : _FileHandle; + } + + extern "C++" _Check_return_ _CRT_INSECURE_DEPRECATE(_sopen_s) + inline int __CRTDECL _sopen( + _In_z_ char const* const _FileName, + _In_ int const _OFlag, + _In_ int const _ShFlag, + _In_ int const _PMode = 0 + ) + { + int _FileHandle; + // Last parameter passed as 0 because we don't want to validate pmode from _sopen + errno_t const _Result = _sopen_dispatch(_FileName, _OFlag, _ShFlag, _PMode, &_FileHandle, 0); + return _Result ? -1 : _FileHandle; + } + + #else + + _Check_return_ _CRT_INSECURE_DEPRECATE(_sopen_s) + _ACRTIMP int __cdecl _open( + _In_z_ char const* _FileName, + _In_ int _OpenFlag, + ...); + + _Check_return_ _CRT_INSECURE_DEPRECATE(_sopen_s) + _ACRTIMP int __cdecl _sopen( + _In_z_ char const* _FileName, + _In_ int _OpenFlag, + _In_ int _ShareFlag, + ...); + + #endif + + + + #if defined(_CRT_INTERNAL_NONSTDC_NAMES) && _CRT_INTERNAL_NONSTDC_NAMES + // Suppress warnings about double deprecation + #pragma warning(push) + #pragma warning(disable: 4141) + + _Check_return_ _CRT_NONSTDC_DEPRECATE(_access) + _ACRTIMP int __cdecl access( + _In_z_ char const* _FileName, + _In_ int _AccessMode + ); + + _Check_return_ _CRT_NONSTDC_DEPRECATE(_chmod) + _ACRTIMP int __cdecl chmod( + _In_z_ char const* _FileName, + _In_ int _AccessMode + ); + + _Check_return_ _CRT_NONSTDC_DEPRECATE(_chsize) + _ACRTIMP int __cdecl chsize( + _In_ int _FileHandle, + _In_ long _Size + ); + + _Check_return_opt_ _CRT_NONSTDC_DEPRECATE(_close) + _ACRTIMP int __cdecl close( + _In_ int _FileHandle + ); + + _Check_return_ _CRT_NONSTDC_DEPRECATE(_creat) _CRT_INSECURE_DEPRECATE(_sopen_s) + _ACRTIMP int __cdecl creat( + _In_z_ char const* _FileName, + _In_ int _PermissionMode + ); + + _Check_return_ _CRT_NONSTDC_DEPRECATE(_dup) + _ACRTIMP int __cdecl dup( + _In_ int _FileHandle + ); + + _Check_return_ _CRT_NONSTDC_DEPRECATE(_dup2) + _ACRTIMP int __cdecl dup2( + _In_ int _FileHandleSrc, + _In_ int _FileHandleDst + ); + + _Check_return_ _CRT_NONSTDC_DEPRECATE(_eof) + _ACRTIMP int __cdecl eof( + _In_ int _FileHandle + ); + + _Check_return_ _CRT_NONSTDC_DEPRECATE(_filelength) + _ACRTIMP long __cdecl filelength( + _In_ int _FileHandle + ); + + _Check_return_ _CRT_NONSTDC_DEPRECATE(_isatty) + _ACRTIMP int __cdecl isatty( + _In_ int _FileHandle + ); + + _Check_return_ _CRT_NONSTDC_DEPRECATE(_locking) + _ACRTIMP int __cdecl locking( + _In_ int _FileHandle, + _In_ int _LockMode, + _In_ long _NumOfBytes + ); + + _Check_return_opt_ _CRT_NONSTDC_DEPRECATE(_lseek) + _ACRTIMP long __cdecl lseek( + _In_ int _FileHandle, + _In_ long _Offset, + _In_ int _Origin + ); + + _Success_(return != 0) + _CRT_NONSTDC_DEPRECATE(_mktemp) _CRT_INSECURE_DEPRECATE(_mktemp_s) + _ACRTIMP char * __cdecl mktemp( + _Inout_z_ char* _TemplateName + ); + + _Check_return_ _CRT_NONSTDC_DEPRECATE(_open) _CRT_INSECURE_DEPRECATE(_sopen_s) + _ACRTIMP int __cdecl open( + _In_z_ char const* _FileName, + _In_ int _OpenFlag, + ...); + + _Success_(return != -1) + _CRT_NONSTDC_DEPRECATE(_read) + _ACRTIMP int __cdecl read( + _In_ int _FileHandle, + _Out_writes_bytes_(_MaxCharCount) void* _DstBuf, + _In_ unsigned int _MaxCharCount + ); + + _Check_return_ _CRT_NONSTDC_DEPRECATE(_setmode) + _ACRTIMP int __cdecl setmode( + _In_ int _FileHandle, + _In_ int _Mode + ); + + _CRT_NONSTDC_DEPRECATE(_sopen) _CRT_INSECURE_DEPRECATE(_sopen_s) + _ACRTIMP int __cdecl sopen( + _In_ char const* _FileName, + _In_ int _OpenFlag, + _In_ int _ShareFlag, + ...); + + _Check_return_ _CRT_NONSTDC_DEPRECATE(_tell) + _ACRTIMP long __cdecl tell( + _In_ int _FileHandle + ); + + _CRT_NONSTDC_DEPRECATE(_umask) _CRT_INSECURE_DEPRECATE(_umask_s) + _ACRTIMP int __cdecl umask( + _In_ int _Mode + ); + + _CRT_NONSTDC_DEPRECATE(_unlink) + _ACRTIMP int __cdecl unlink( + _In_z_ char const* _FileName + ); + + _Check_return_ _CRT_NONSTDC_DEPRECATE(_write) + _ACRTIMP int __cdecl write( + _In_ int _FileHandle, + _In_reads_bytes_(_MaxCharCount) void const* _Buf, + _In_ unsigned int _MaxCharCount + ); + + #pragma warning(pop) + #endif // _CRT_INTERNAL_NONSTDC_NAMES +#endif // _CRT_FUNCTIONS_REQUIRED + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS diff --git a/sdk/include/ucrt/corecrt_malloc.h b/sdk/include/ucrt/corecrt_malloc.h new file mode 100644 index 0000000000000..b6d90bdf9759b --- /dev/null +++ b/sdk/include/ucrt/corecrt_malloc.h @@ -0,0 +1,234 @@ +// +// corecrt_malloc.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The memory allocation library. These pieces of the allocation library are +// shared by both and . +// +#pragma once + +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + + + +#if defined _DEBUG && defined _CRTDBG_MAP_ALLOC + #pragma push_macro("_aligned_free") + #pragma push_macro("_aligned_malloc") + #pragma push_macro("_aligned_msize") + #pragma push_macro("_aligned_offset_malloc") + #pragma push_macro("_aligned_offset_realloc") + #pragma push_macro("_aligned_offset_recalloc") + #pragma push_macro("_aligned_realloc") + #pragma push_macro("_aligned_recalloc") + #pragma push_macro("_expand") + #pragma push_macro("_freea") + #pragma push_macro("_msize") + #pragma push_macro("_recalloc") + #pragma push_macro("calloc") + #pragma push_macro("free") + #pragma push_macro("malloc") + #pragma push_macro("realloc") + + #undef _aligned_free + #undef _aligned_malloc + #undef _aligned_msize + #undef _aligned_offset_malloc + #undef _aligned_offset_realloc + #undef _aligned_offset_recalloc + #undef _aligned_realloc + #undef _aligned_recalloc + #undef _expand + #undef _freea + #undef _msize + #undef _recalloc + #undef calloc + #undef free + #undef malloc + #undef realloc +#endif + +_Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Count * _Size) +_ACRTIMP _CRTALLOCATOR _CRTRESTRICT +void* __cdecl _calloc_base( + _In_ size_t _Count, + _In_ size_t _Size + ); + +_Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Count * _Size) +_ACRTIMP _CRT_JIT_INTRINSIC _CRTALLOCATOR _CRTRESTRICT _CRT_HYBRIDPATCHABLE +void* __cdecl calloc( + _In_ _CRT_GUARDOVERFLOW size_t _Count, + _In_ _CRT_GUARDOVERFLOW size_t _Size + ); + +_Check_return_ +_ACRTIMP int __cdecl _callnewh( + _In_ size_t _Size + ); + +_Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Size) +_ACRTIMP _CRTALLOCATOR _CRT_HYBRIDPATCHABLE +void* __cdecl _expand( + _Pre_notnull_ void* _Block, + _In_ _CRT_GUARDOVERFLOW size_t _Size + ); + +_ACRTIMP +void __cdecl _free_base( + _Pre_maybenull_ _Post_invalid_ void* _Block + ); + +_ACRTIMP _CRT_HYBRIDPATCHABLE +void __cdecl free( + _Pre_maybenull_ _Post_invalid_ void* _Block + ); + +_Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Size) +_ACRTIMP _CRTALLOCATOR _CRTRESTRICT +void* __cdecl _malloc_base( + _In_ size_t _Size + ); + +_Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Size) +_ACRTIMP _CRTALLOCATOR _CRT_JIT_INTRINSIC _CRTRESTRICT _CRT_HYBRIDPATCHABLE +void* __cdecl malloc( + _In_ _CRT_GUARDOVERFLOW size_t _Size + ); + +_Check_return_ +_ACRTIMP +size_t __cdecl _msize_base( + _Pre_notnull_ void* _Block + ) _CRT_NOEXCEPT; + +_Check_return_ +_ACRTIMP _CRT_HYBRIDPATCHABLE +size_t __cdecl _msize( + _Pre_notnull_ void* _Block + ); + +_Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Size) +_ACRTIMP _CRTALLOCATOR _CRTRESTRICT +void* __cdecl _realloc_base( + _Pre_maybenull_ _Post_invalid_ void* _Block, + _In_ size_t _Size + ); + +_Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Size) +_ACRTIMP _CRTALLOCATOR _CRTRESTRICT _CRT_HYBRIDPATCHABLE +void* __cdecl realloc( + _Pre_maybenull_ _Post_invalid_ void* _Block, + _In_ _CRT_GUARDOVERFLOW size_t _Size + ); + +_Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Count * _Size) +_ACRTIMP _CRTALLOCATOR _CRTRESTRICT +void* __cdecl _recalloc_base( + _Pre_maybenull_ _Post_invalid_ void* _Block, + _In_ size_t _Count, + _In_ size_t _Size + ); + +_Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Count * _Size) +_ACRTIMP _CRTALLOCATOR _CRTRESTRICT +void* __cdecl _recalloc( + _Pre_maybenull_ _Post_invalid_ void* _Block, + _In_ _CRT_GUARDOVERFLOW size_t _Count, + _In_ _CRT_GUARDOVERFLOW size_t _Size + ); + +_ACRTIMP +void __cdecl _aligned_free( + _Pre_maybenull_ _Post_invalid_ void* _Block + ); + +_Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Size) +_ACRTIMP _CRTALLOCATOR _CRTRESTRICT +void* __cdecl _aligned_malloc( + _In_ _CRT_GUARDOVERFLOW size_t _Size, + _In_ size_t _Alignment + ); + +_Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Size) +_ACRTIMP _CRTALLOCATOR _CRTRESTRICT +void* __cdecl _aligned_offset_malloc( + _In_ _CRT_GUARDOVERFLOW size_t _Size, + _In_ size_t _Alignment, + _In_ size_t _Offset + ); + +_Check_return_ +_ACRTIMP +size_t __cdecl _aligned_msize( + _Pre_notnull_ void* _Block, + _In_ size_t _Alignment, + _In_ size_t _Offset + ); + +_Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Size) +_ACRTIMP _CRTALLOCATOR _CRTRESTRICT +void* __cdecl _aligned_offset_realloc( + _Pre_maybenull_ _Post_invalid_ void* _Block, + _In_ _CRT_GUARDOVERFLOW size_t _Size, + _In_ size_t _Alignment, + _In_ size_t _Offset + ); + +_Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Count * _Size) +_ACRTIMP _CRTALLOCATOR _CRTRESTRICT +void* __cdecl _aligned_offset_recalloc( + _Pre_maybenull_ _Post_invalid_ void* _Block, + _In_ _CRT_GUARDOVERFLOW size_t _Count, + _In_ _CRT_GUARDOVERFLOW size_t _Size, + _In_ size_t _Alignment, + _In_ size_t _Offset + ); + +_Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Size) +_ACRTIMP _CRTALLOCATOR _CRTRESTRICT +void* __cdecl _aligned_realloc( + _Pre_maybenull_ _Post_invalid_ void* _Block, + _In_ _CRT_GUARDOVERFLOW size_t _Size, + _In_ size_t _Alignment + ); + +_Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Count * _Size) +_ACRTIMP _CRTALLOCATOR _CRTRESTRICT +void* __cdecl _aligned_recalloc( + _Pre_maybenull_ _Post_invalid_ void* _Block, + _In_ _CRT_GUARDOVERFLOW size_t _Count, + _In_ _CRT_GUARDOVERFLOW size_t _Size, + _In_ size_t _Alignment + ); + +#if defined _DEBUG && defined _CRTDBG_MAP_ALLOC + #pragma pop_macro("realloc") + #pragma pop_macro("malloc") + #pragma pop_macro("free") + #pragma pop_macro("calloc") + #pragma pop_macro("_recalloc") + #pragma pop_macro("_msize") + #pragma pop_macro("_freea") + #pragma pop_macro("_expand") + #pragma pop_macro("_aligned_recalloc") + #pragma pop_macro("_aligned_realloc") + #pragma pop_macro("_aligned_offset_recalloc") + #pragma pop_macro("_aligned_offset_realloc") + #pragma pop_macro("_aligned_offset_malloc") + #pragma pop_macro("_aligned_msize") + #pragma pop_macro("_aligned_malloc") + #pragma pop_macro("_aligned_free") +#endif + + + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS diff --git a/sdk/include/ucrt/corecrt_math.h b/sdk/include/ucrt/corecrt_math.h new file mode 100644 index 0000000000000..215a0b964229b --- /dev/null +++ b/sdk/include/ucrt/corecrt_math.h @@ -0,0 +1,1006 @@ +// +// corecrt_math.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The majority of the C Standard Library functionality. +// +#pragma once +#ifndef _INC_MATH // include guard for 3rd party interop +#define _INC_MATH + +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + +#ifndef __assembler + // Definition of the _exception struct, which is passed to the matherr function + // when a floating point exception is detected: + struct _exception + { + int type; // exception type - see below + char* name; // name of function where error occurred + double arg1; // first argument to function + double arg2; // second argument (if any) to function + double retval; // value to be returned by function + }; + + // Definition of the _complex struct to be used by those who use the complex + // functions and want type checking. + #ifndef _COMPLEX_DEFINED + #define _COMPLEX_DEFINED + + struct _complex + { + double x, y; // real and imaginary parts + }; + + #if defined(_CRT_INTERNAL_NONSTDC_NAMES) && _CRT_INTERNAL_NONSTDC_NAMES && !defined __cplusplus + // Non-ANSI name for compatibility + #define complex _complex + #endif + #endif +#endif // __assembler + + + +// On x86, when not using /arch:SSE2 or greater, floating point operations +// are performed using the x87 instruction set and FLT_EVAL_METHOD is 2. +// (When /fp:fast is used, floating point operations may be consistent, so +// we use the default types.) +#if defined _M_IX86 && _M_IX86_FP < 2 && !defined _M_FP_FAST + typedef long double float_t; + typedef long double double_t; +#else + typedef float float_t; + typedef double double_t; +#endif + + + +// Constant definitions for the exception type passed in the _exception struct +#define _DOMAIN 1 // argument domain error +#define _SING 2 // argument singularity +#define _OVERFLOW 3 // overflow range error +#define _UNDERFLOW 4 // underflow range error +#define _TLOSS 5 // total loss of precision +#define _PLOSS 6 // partial loss of precision + +// Definitions of _HUGE and HUGE_VAL - respectively the XENIX and ANSI names +// for a value returned in case of error by a number of the floating point +// math routines. +#ifndef __assembler + #ifndef _M_CEE_PURE + extern double const _HUGE; + #else + double const _HUGE = System::Double::PositiveInfinity; + #endif +#endif + +#ifndef _HUGE_ENUF + #define _HUGE_ENUF 1e+300 // _HUGE_ENUF*_HUGE_ENUF must overflow +#endif + +#define INFINITY ((float)(_HUGE_ENUF * _HUGE_ENUF)) +#define HUGE_VAL ((double)INFINITY) +#define HUGE_VALF ((float)INFINITY) +#define HUGE_VALL ((long double)INFINITY) +#ifndef _UCRT_NEGATIVE_NAN +// This operation creates a negative NAN adding a - to make it positive +#ifdef _MSC_VER +#define NAN (-(float)(INFINITY * 0.0F)) +#else +#define NAN (__builtin_nanf("")) +#endif +#else +// Keep this for backwards compatibility +#ifdef _MSC_VER +#define NAN ((float)(INFINITY * 0.0F)) +#else +#define NAN (-__builtin_nanf("")) +#endif +#endif + +#define _DENORM (-2) +#define _FINITE (-1) +#define _INFCODE 1 +#define _NANCODE 2 + +#define FP_INFINITE _INFCODE +#define FP_NAN _NANCODE +#define FP_NORMAL _FINITE +#define FP_SUBNORMAL _DENORM +#define FP_ZERO 0 + +#define _C2 1 // 0 if not 2's complement +#define FP_ILOGB0 (-0x7fffffff - _C2) +#define FP_ILOGBNAN 0x7fffffff + +#define MATH_ERRNO 1 +#define MATH_ERREXCEPT 2 +#define math_errhandling (MATH_ERRNO | MATH_ERREXCEPT) + +// Values for use as arguments to the _fperrraise function +#define _FE_DIVBYZERO 0x04 +#define _FE_INEXACT 0x20 +#define _FE_INVALID 0x01 +#define _FE_OVERFLOW 0x08 +#define _FE_UNDERFLOW 0x10 + +#define _D0_C 3 // little-endian, small long doubles +#define _D1_C 2 +#define _D2_C 1 +#define _D3_C 0 + +#define _DBIAS 0x3fe +#define _DOFF 4 + +#define _F0_C 1 // little-endian +#define _F1_C 0 + +#define _FBIAS 0x7e +#define _FOFF 7 +#define _FRND 1 + +#define _L0_C 3 // little-endian, 64-bit long doubles +#define _L1_C 2 +#define _L2_C 1 +#define _L3_C 0 + +#define _LBIAS 0x3fe +#define _LOFF 4 + +// IEEE 754 double properties +#define _DFRAC ((unsigned short)((1 << _DOFF) - 1)) +#define _DMASK ((unsigned short)(0x7fff & ~_DFRAC)) +#define _DMAX ((unsigned short)((1 << (15 - _DOFF)) - 1)) +#define _DSIGN ((unsigned short)0x8000) + +// IEEE 754 float properties +#define _FFRAC ((unsigned short)((1 << _FOFF) - 1)) +#define _FMASK ((unsigned short)(0x7fff & ~_FFRAC)) +#define _FMAX ((unsigned short)((1 << (15 - _FOFF)) - 1)) +#define _FSIGN ((unsigned short)0x8000) + +// IEEE 754 long double properties +#define _LFRAC ((unsigned short)(-1)) +#define _LMASK ((unsigned short)0x7fff) +#define _LMAX ((unsigned short)0x7fff) +#define _LSIGN ((unsigned short)0x8000) + +#define _DHUGE_EXP (int)(_DMAX * 900L / 1000) +#define _FHUGE_EXP (int)(_FMAX * 900L / 1000) +#define _LHUGE_EXP (int)(_LMAX * 900L / 1000) + +#define _DSIGN_C(_Val) (((_double_val *)(char*)&(_Val))->_Sh[_D0_C] & _DSIGN) +#define _FSIGN_C(_Val) (((_float_val *)(char*)&(_Val))->_Sh[_F0_C] & _FSIGN) +#define _LSIGN_C(_Val) (((_ldouble_val*)(char*)&(_Val))->_Sh[_L0_C] & _LSIGN) + +void __cdecl _fperrraise(_In_ int _Except); + +_Check_return_ _ACRTIMP short __cdecl _dclass(_In_ double _X); +_Check_return_ _ACRTIMP short __cdecl _ldclass(_In_ long double _X); +_Check_return_ _ACRTIMP short __cdecl _fdclass(_In_ float _X); + +_Check_return_ _ACRTIMP int __cdecl _dsign(_In_ double _X); +_Check_return_ _ACRTIMP int __cdecl _ldsign(_In_ long double _X); +_Check_return_ _ACRTIMP int __cdecl _fdsign(_In_ float _X); + +_Check_return_ _ACRTIMP int __cdecl _dpcomp(_In_ double _X, _In_ double _Y); +_Check_return_ _ACRTIMP int __cdecl _ldpcomp(_In_ long double _X, _In_ long double _Y); +_Check_return_ _ACRTIMP int __cdecl _fdpcomp(_In_ float _X, _In_ float _Y); + +_Check_return_ _ACRTIMP short __cdecl _dtest(_In_ double* _Px); +_Check_return_ _ACRTIMP short __cdecl _ldtest(_In_ long double* _Px); +_Check_return_ _ACRTIMP short __cdecl _fdtest(_In_ float* _Px); + +_ACRTIMP short __cdecl _d_int(_Inout_ double* _Px, _In_ short _Xexp); +_ACRTIMP short __cdecl _ld_int(_Inout_ long double* _Px, _In_ short _Xexp); +_ACRTIMP short __cdecl _fd_int(_Inout_ float* _Px, _In_ short _Xexp); + +_ACRTIMP short __cdecl _dscale(_Inout_ double* _Px, _In_ long _Lexp); +_ACRTIMP short __cdecl _ldscale(_Inout_ long double* _Px, _In_ long _Lexp); +_ACRTIMP short __cdecl _fdscale(_Inout_ float* _Px, _In_ long _Lexp); + +_ACRTIMP short __cdecl _dunscale(_Out_ short* _Pex, _Inout_ double* _Px); +_ACRTIMP short __cdecl _ldunscale(_Out_ short* _Pex, _Inout_ long double* _Px); +_ACRTIMP short __cdecl _fdunscale(_Out_ short* _Pex, _Inout_ float* _Px); + +_Check_return_ _ACRTIMP short __cdecl _dexp(_Inout_ double* _Px, _In_ double _Y, _In_ long _Eoff); +_Check_return_ _ACRTIMP short __cdecl _ldexp(_Inout_ long double* _Px, _In_ long double _Y, _In_ long _Eoff); +_Check_return_ _ACRTIMP short __cdecl _fdexp(_Inout_ float* _Px, _In_ float _Y, _In_ long _Eoff); + +_Check_return_ _ACRTIMP short __cdecl _dnorm(_Inout_updates_(4) unsigned short* _Ps); +_Check_return_ _ACRTIMP short __cdecl _fdnorm(_Inout_updates_(2) unsigned short* _Ps); + +_Check_return_ _ACRTIMP double __cdecl _dpoly(_In_ double _X, _In_reads_(_N) double const* _Tab, _In_ int _N); +_Check_return_ _ACRTIMP long double __cdecl _ldpoly(_In_ long double _X, _In_reads_(_N) long double const* _Tab, _In_ int _N); +_Check_return_ _ACRTIMP float __cdecl _fdpoly(_In_ float _X, _In_reads_(_N) float const* _Tab, _In_ int _N); + +_Check_return_ _ACRTIMP double __cdecl _dlog(_In_ double _X, _In_ int _Baseflag); +_Check_return_ _ACRTIMP long double __cdecl _ldlog(_In_ long double _X, _In_ int _Baseflag); +_Check_return_ _ACRTIMP float __cdecl _fdlog(_In_ float _X, _In_ int _Baseflag); + +_Check_return_ _ACRTIMP double __cdecl _dsin(_In_ double _X, _In_ unsigned int _Qoff); +_Check_return_ _ACRTIMP long double __cdecl _ldsin(_In_ long double _X, _In_ unsigned int _Qoff); +_Check_return_ _ACRTIMP float __cdecl _fdsin(_In_ float _X, _In_ unsigned int _Qoff); + +// double declarations +typedef union +{ // pun floating type as integer array + unsigned short _Sh[4]; + double _Val; +} _double_val; + +// float declarations +typedef union +{ // pun floating type as integer array + unsigned short _Sh[2]; + float _Val; +} _float_val; + +// long double declarations +typedef union +{ // pun floating type as integer array + unsigned short _Sh[4]; + long double _Val; +} _ldouble_val; + +typedef union +{ // pun float types as integer array + unsigned short _Word[4]; + float _Float; + double _Double; + long double _Long_double; +} _float_const; + +extern const _float_const _Denorm_C, _Inf_C, _Nan_C, _Snan_C, _Hugeval_C; +extern const _float_const _FDenorm_C, _FInf_C, _FNan_C, _FSnan_C; +extern const _float_const _LDenorm_C, _LInf_C, _LNan_C, _LSnan_C; + +extern const _float_const _Eps_C, _Rteps_C; +extern const _float_const _FEps_C, _FRteps_C; +extern const _float_const _LEps_C, _LRteps_C; + +extern const double _Zero_C, _Xbig_C; +extern const float _FZero_C, _FXbig_C; +extern const long double _LZero_C, _LXbig_C; + +#define _FP_LT 1 +#define _FP_EQ 2 +#define _FP_GT 4 + +#ifndef __cplusplus + + #define _CLASS_ARG(_Val) __pragma(warning(suppress:6334))(sizeof ((_Val) + (float)0) == sizeof (float) ? 'f' : sizeof ((_Val) + (double)0) == sizeof (double) ? 'd' : 'l') + #define _CLASSIFY(_Val, _FFunc, _DFunc, _LDFunc) (_CLASS_ARG(_Val) == 'f' ? _FFunc((float)(_Val)) : _CLASS_ARG(_Val) == 'd' ? _DFunc((double)(_Val)) : _LDFunc((long double)(_Val))) + #define _CLASSIFY2(_Val1, _Val2, _FFunc, _DFunc, _LDFunc) (_CLASS_ARG((_Val1) + (_Val2)) == 'f' ? _FFunc((float)(_Val1), (float)(_Val2)) : _CLASS_ARG((_Val1) + (_Val2)) == 'd' ? _DFunc((double)(_Val1), (double)(_Val2)) : _LDFunc((long double)(_Val1), (long double)(_Val2))) + + #define fpclassify(_Val) (_CLASSIFY(_Val, _fdclass, _dclass, _ldclass)) + #define _FPCOMPARE(_Val1, _Val2) (_CLASSIFY2(_Val1, _Val2, _fdpcomp, _dpcomp, _ldpcomp)) + + #define isfinite(_Val) (fpclassify(_Val) <= 0) + #define isinf(_Val) (fpclassify(_Val) == FP_INFINITE) + #define isnan(_Val) (fpclassify(_Val) == FP_NAN) + #define isnormal(_Val) (fpclassify(_Val) == FP_NORMAL) + #define signbit(_Val) (_CLASSIFY(_Val, _fdsign, _dsign, _ldsign)) + + #define isgreater(x, y) ((_FPCOMPARE(x, y) & _FP_GT) != 0) + #define isgreaterequal(x, y) ((_FPCOMPARE(x, y) & (_FP_EQ | _FP_GT)) != 0) + #define isless(x, y) ((_FPCOMPARE(x, y) & _FP_LT) != 0) + #define islessequal(x, y) ((_FPCOMPARE(x, y) & (_FP_LT | _FP_EQ)) != 0) + #define islessgreater(x, y) ((_FPCOMPARE(x, y) & (_FP_LT | _FP_GT)) != 0) + #define isunordered(x, y) (_FPCOMPARE(x, y) == 0) + +#else // __cplusplus +extern "C++" +{ + _Check_return_ inline int fpclassify(_In_ float _X) throw() + { + return _fdtest(&_X); + } + + _Check_return_ inline int fpclassify(_In_ double _X) throw() + { + return _dtest(&_X); + } + + _Check_return_ inline int fpclassify(_In_ long double _X) throw() + { + return _ldtest(&_X); + } + + _Check_return_ inline bool signbit(_In_ float _X) throw() + { + return _fdsign(_X) != 0; + } + + _Check_return_ inline bool signbit(_In_ double _X) throw() + { + return _dsign(_X) != 0; + } + + _Check_return_ inline bool signbit(_In_ long double _X) throw() + { + return _ldsign(_X) != 0; + } + + _Check_return_ inline int _fpcomp(_In_ float _X, _In_ float _Y) throw() + { + return _fdpcomp(_X, _Y); + } + + _Check_return_ inline int _fpcomp(_In_ double _X, _In_ double _Y) throw() + { + return _dpcomp(_X, _Y); + } + + _Check_return_ inline int _fpcomp(_In_ long double _X, _In_ long double _Y) throw() + { + return _ldpcomp(_X, _Y); + } + + template struct _Combined_type + { // determine combined type + typedef float _Type; + }; + + template <> struct _Combined_type + { // determine combined type + typedef double _Type; + }; + + template <> struct _Combined_type + { // determine combined type + typedef long double _Type; + }; + + template struct _Real_widened + { // determine widened real type + typedef long double _Type; + }; + + template <> struct _Real_widened + { // determine widened real type + typedef float _Type; + }; + + template <> struct _Real_widened + { // determine widened real type + typedef double _Type; + }; + + template <> struct _Real_widened + { // determine widened real type + typedef double _Type; + }; + + template <> struct _Real_widened + { // determine widened real type + typedef double _Type; + }; + + template struct _Real_type + { // determine equivalent real type + typedef double _Type; // default is double + }; + + template <> struct _Real_type + { // determine equivalent real type + typedef float _Type; + }; + + template <> struct _Real_type + { // determine equivalent real type + typedef long double _Type; + }; + + template + _Check_return_ inline int _fpcomp(_In_ _T1 _X, _In_ _T2 _Y) throw() + { // compare _Left and _Right + typedef typename _Combined_type::_Type, + typename _Real_type<_T2>::_Type>::_Type>::_Type _Tw; + return _fpcomp((_Tw)_X, (_Tw)_Y); + } + + template + _Check_return_ inline bool isfinite(_In_ _Ty _X) throw() + { + return fpclassify(_X) <= 0; + } + + template + _Check_return_ inline bool isinf(_In_ _Ty _X) throw() + { + return fpclassify(_X) == FP_INFINITE; + } + + template + _Check_return_ inline bool isnan(_In_ _Ty _X) throw() + { + return fpclassify(_X) == FP_NAN; + } + + template + _Check_return_ inline bool isnormal(_In_ _Ty _X) throw() + { + return fpclassify(_X) == FP_NORMAL; + } + + template + _Check_return_ inline bool isgreater(_In_ _Ty1 _X, _In_ _Ty2 _Y) throw() + { + return (_fpcomp(_X, _Y) & _FP_GT) != 0; + } + + template + _Check_return_ inline bool isgreaterequal(_In_ _Ty1 _X, _In_ _Ty2 _Y) throw() + { + return (_fpcomp(_X, _Y) & (_FP_EQ | _FP_GT)) != 0; + } + + template + _Check_return_ inline bool isless(_In_ _Ty1 _X, _In_ _Ty2 _Y) throw() + { + return (_fpcomp(_X, _Y) & _FP_LT) != 0; + } + + template + _Check_return_ inline bool islessequal(_In_ _Ty1 _X, _In_ _Ty2 _Y) throw() + { + return (_fpcomp(_X, _Y) & (_FP_LT | _FP_EQ)) != 0; + } + + template + _Check_return_ inline bool islessgreater(_In_ _Ty1 _X, _In_ _Ty2 _Y) throw() + { + return (_fpcomp(_X, _Y) & (_FP_LT | _FP_GT)) != 0; + } + + template + _Check_return_ inline bool isunordered(_In_ _Ty1 _X, _In_ _Ty2 _Y) throw() + { + return _fpcomp(_X, _Y) == 0; + } +} // extern "C++" +#endif // __cplusplus + + + +#if _CRT_FUNCTIONS_REQUIRED + + _Check_return_ int __cdecl abs(_In_ int _X); + _Check_return_ long __cdecl labs(_In_ long _X); + _Check_return_ long long __cdecl llabs(_In_ long long _X); + + _Check_return_ double __cdecl acos(_In_ double _X); + _Check_return_ double __cdecl asin(_In_ double _X); + _Check_return_ double __cdecl atan(_In_ double _X); + _Check_return_ double __cdecl atan2(_In_ double _Y, _In_ double _X); + + _Check_return_ double __cdecl cos(_In_ double _X); + _Check_return_ double __cdecl cosh(_In_ double _X); + _Check_return_ double __cdecl exp(_In_ double _X); + _Check_return_ _CRT_JIT_INTRINSIC double __cdecl fabs(_In_ double _X); + _Check_return_ double __cdecl fmod(_In_ double _X, _In_ double _Y); + _Check_return_ double __cdecl log(_In_ double _X); + _Check_return_ double __cdecl log10(_In_ double _X); + _Check_return_ double __cdecl pow(_In_ double _X, _In_ double _Y); + _Check_return_ double __cdecl sin(_In_ double _X); + _Check_return_ double __cdecl sinh(_In_ double _X); + _Check_return_ _CRT_JIT_INTRINSIC double __cdecl sqrt(_In_ double _X); + _Check_return_ double __cdecl tan(_In_ double _X); + _Check_return_ double __cdecl tanh(_In_ double _X); + + _Check_return_ _ACRTIMP double __cdecl acosh(_In_ double _X); + _Check_return_ _ACRTIMP double __cdecl asinh(_In_ double _X); + _Check_return_ _ACRTIMP double __cdecl atanh(_In_ double _X); + _Check_return_ _ACRTIMP double __cdecl atof(_In_z_ char const* _String); + _Check_return_ _ACRTIMP double __cdecl _atof_l(_In_z_ char const* _String, _In_opt_ _locale_t _Locale); + _Check_return_ _ACRTIMP double __cdecl _cabs(_In_ struct _complex _Complex_value); + _Check_return_ _ACRTIMP double __cdecl cbrt(_In_ double _X); + _Check_return_ _ACRTIMP double __cdecl ceil(_In_ double _X); + _Check_return_ _ACRTIMP double __cdecl _chgsign(_In_ double _X); + _Check_return_ _ACRTIMP double __cdecl copysign(_In_ double _Number, _In_ double _Sign); + _Check_return_ _ACRTIMP double __cdecl _copysign(_In_ double _Number, _In_ double _Sign); + _Check_return_ _ACRTIMP double __cdecl erf(_In_ double _X); + _Check_return_ _ACRTIMP double __cdecl erfc(_In_ double _X); + _Check_return_ _ACRTIMP double __cdecl exp2(_In_ double _X); + _Check_return_ _ACRTIMP double __cdecl expm1(_In_ double _X); + _Check_return_ _ACRTIMP double __cdecl fdim(_In_ double _X, _In_ double _Y); + _Check_return_ _ACRTIMP double __cdecl floor(_In_ double _X); + _Check_return_ _ACRTIMP double __cdecl fma(_In_ double _X, _In_ double _Y, _In_ double _Z); + _Check_return_ _ACRTIMP double __cdecl fmax(_In_ double _X, _In_ double _Y); + _Check_return_ _ACRTIMP double __cdecl fmin(_In_ double _X, _In_ double _Y); + _Check_return_ _ACRTIMP double __cdecl frexp(_In_ double _X, _Out_ int* _Y); + _Check_return_ _ACRTIMP double __cdecl hypot(_In_ double _X, _In_ double _Y); + _Check_return_ _ACRTIMP double __cdecl _hypot(_In_ double _X, _In_ double _Y); + _Check_return_ _ACRTIMP int __cdecl ilogb(_In_ double _X); + _Check_return_ _ACRTIMP double __cdecl ldexp(_In_ double _X, _In_ int _Y); + _Check_return_ _ACRTIMP double __cdecl lgamma(_In_ double _X); + _Check_return_ _ACRTIMP long long __cdecl llrint(_In_ double _X); + _Check_return_ _ACRTIMP long long __cdecl llround(_In_ double _X); + _Check_return_ _ACRTIMP double __cdecl log1p(_In_ double _X); + _Check_return_ _ACRTIMP double __cdecl log2(_In_ double _X); + _Check_return_ _ACRTIMP double __cdecl logb(_In_ double _X); + _Check_return_ _ACRTIMP long __cdecl lrint(_In_ double _X); + _Check_return_ _ACRTIMP long __cdecl lround(_In_ double _X); + + int __CRTDECL _matherr(_Inout_ struct _exception* _Except); + + _Check_return_ _ACRTIMP double __cdecl modf(_In_ double _X, _Out_ double* _Y); + _Check_return_ _ACRTIMP double __cdecl nan(_In_ char const* _X); + _Check_return_ _ACRTIMP double __cdecl nearbyint(_In_ double _X); + _Check_return_ _ACRTIMP double __cdecl nextafter(_In_ double _X, _In_ double _Y); + _Check_return_ _ACRTIMP double __cdecl nexttoward(_In_ double _X, _In_ long double _Y); + _Check_return_ _ACRTIMP double __cdecl remainder(_In_ double _X, _In_ double _Y); + _Check_return_ _ACRTIMP double __cdecl remquo(_In_ double _X, _In_ double _Y, _Out_ int* _Z); + _Check_return_ _ACRTIMP double __cdecl rint(_In_ double _X); + _Check_return_ _ACRTIMP double __cdecl round(_In_ double _X); + _Check_return_ _ACRTIMP double __cdecl scalbln(_In_ double _X, _In_ long _Y); + _Check_return_ _ACRTIMP double __cdecl scalbn(_In_ double _X, _In_ int _Y); + _Check_return_ _ACRTIMP double __cdecl tgamma(_In_ double _X); + _Check_return_ _ACRTIMP double __cdecl trunc(_In_ double _X); + _Check_return_ _ACRTIMP double __cdecl _j0(_In_ double _X ); + _Check_return_ _ACRTIMP double __cdecl _j1(_In_ double _X ); + _Check_return_ _ACRTIMP double __cdecl _jn(int _X, _In_ double _Y); + _Check_return_ _ACRTIMP double __cdecl _y0(_In_ double _X); + _Check_return_ _ACRTIMP double __cdecl _y1(_In_ double _X); + _Check_return_ _ACRTIMP double __cdecl _yn(_In_ int _X, _In_ double _Y); + + _Check_return_ _ACRTIMP float __cdecl acoshf(_In_ float _X); + _Check_return_ _ACRTIMP float __cdecl asinhf(_In_ float _X); + _Check_return_ _ACRTIMP float __cdecl atanhf(_In_ float _X); + _Check_return_ _ACRTIMP float __cdecl cbrtf(_In_ float _X); + _Check_return_ _ACRTIMP float __cdecl _chgsignf(_In_ float _X); + _Check_return_ _ACRTIMP float __cdecl copysignf(_In_ float _Number, _In_ float _Sign); + _Check_return_ _ACRTIMP float __cdecl _copysignf(_In_ float _Number, _In_ float _Sign); + _Check_return_ _ACRTIMP float __cdecl erff(_In_ float _X); + _Check_return_ _ACRTIMP float __cdecl erfcf(_In_ float _X); + _Check_return_ _ACRTIMP float __cdecl expm1f(_In_ float _X); + _Check_return_ _ACRTIMP float __cdecl exp2f(_In_ float _X); + _Check_return_ _ACRTIMP float __cdecl fdimf(_In_ float _X, _In_ float _Y); + _Check_return_ _ACRTIMP float __cdecl fmaf(_In_ float _X, _In_ float _Y, _In_ float _Z); + _Check_return_ _ACRTIMP float __cdecl fmaxf(_In_ float _X, _In_ float _Y); + _Check_return_ _ACRTIMP float __cdecl fminf(_In_ float _X, _In_ float _Y); + _Check_return_ _ACRTIMP float __cdecl _hypotf(_In_ float _X, _In_ float _Y); + _Check_return_ _ACRTIMP int __cdecl ilogbf(_In_ float _X); + _Check_return_ _ACRTIMP float __cdecl lgammaf(_In_ float _X); + _Check_return_ _ACRTIMP long long __cdecl llrintf(_In_ float _X); + _Check_return_ _ACRTIMP long long __cdecl llroundf(_In_ float _X); + _Check_return_ _ACRTIMP float __cdecl log1pf(_In_ float _X); + _Check_return_ _ACRTIMP float __cdecl log2f(_In_ float _X); + _Check_return_ _ACRTIMP float __cdecl logbf(_In_ float _X); + _Check_return_ _ACRTIMP long __cdecl lrintf(_In_ float _X); + _Check_return_ _ACRTIMP long __cdecl lroundf(_In_ float _X); + _Check_return_ _ACRTIMP float __cdecl nanf(_In_ char const* _X); + _Check_return_ _ACRTIMP float __cdecl nearbyintf(_In_ float _X); + _Check_return_ _ACRTIMP float __cdecl nextafterf(_In_ float _X, _In_ float _Y); + _Check_return_ _ACRTIMP float __cdecl nexttowardf(_In_ float _X, _In_ long double _Y); + _Check_return_ _ACRTIMP float __cdecl remainderf(_In_ float _X, _In_ float _Y); + _Check_return_ _ACRTIMP float __cdecl remquof(_In_ float _X, _In_ float _Y, _Out_ int* _Z); + _Check_return_ _ACRTIMP float __cdecl rintf(_In_ float _X); + _Check_return_ _ACRTIMP float __cdecl roundf(_In_ float _X); + _Check_return_ _ACRTIMP float __cdecl scalblnf(_In_ float _X, _In_ long _Y); + _Check_return_ _ACRTIMP float __cdecl scalbnf(_In_ float _X, _In_ int _Y); + _Check_return_ _ACRTIMP float __cdecl tgammaf(_In_ float _X); + _Check_return_ _ACRTIMP float __cdecl truncf(_In_ float _X); + + #if defined _M_IX86 + + _Check_return_ _ACRTIMP int __cdecl _set_SSE2_enable(_In_ int _Flag); + + #endif + + #if defined _M_X64 + + _Check_return_ _ACRTIMP float __cdecl _logbf(_In_ float _X); + _Check_return_ _ACRTIMP float __cdecl _nextafterf(_In_ float _X, _In_ float _Y); + _Check_return_ _ACRTIMP int __cdecl _finitef(_In_ float _X); + _Check_return_ _ACRTIMP int __cdecl _isnanf(_In_ float _X); + _Check_return_ _ACRTIMP int __cdecl _fpclassf(_In_ float _X); + + _Check_return_ _ACRTIMP int __cdecl _set_FMA3_enable(_In_ int _Flag); + _Check_return_ _ACRTIMP int __cdecl _get_FMA3_enable(void); + + #elif defined _M_ARM || defined _M_ARM64 || defined _M_HYBRID_X86_ARM64 + + _Check_return_ _ACRTIMP int __cdecl _finitef(_In_ float _X); + _Check_return_ _ACRTIMP float __cdecl _logbf(_In_ float _X); + + #endif + + + + #if defined _M_X64 || defined _M_ARM || defined _M_ARM64 || defined _M_HYBRID_X86_ARM64 || defined _CORECRT_BUILD_APISET || defined _M_ARM64EC + + _Check_return_ _ACRTIMP float __cdecl acosf(_In_ float _X); + _Check_return_ _ACRTIMP float __cdecl asinf(_In_ float _X); + _Check_return_ _ACRTIMP float __cdecl atan2f(_In_ float _Y, _In_ float _X); + _Check_return_ _ACRTIMP float __cdecl atanf(_In_ float _X); + _Check_return_ _ACRTIMP float __cdecl ceilf(_In_ float _X); + _Check_return_ _ACRTIMP float __cdecl cosf(_In_ float _X); + _Check_return_ _ACRTIMP float __cdecl coshf(_In_ float _X); + _Check_return_ _ACRTIMP float __cdecl expf(_In_ float _X); + + #else + + _Check_return_ __inline float __CRTDECL acosf(_In_ float _X) + { + return (float)acos(_X); + } + + _Check_return_ __inline float __CRTDECL asinf(_In_ float _X) + { + return (float)asin(_X); + } + + _Check_return_ __inline float __CRTDECL atan2f(_In_ float _Y, _In_ float _X) + { + return (float)atan2(_Y, _X); + } + + _Check_return_ __inline float __CRTDECL atanf(_In_ float _X) + { + return (float)atan(_X); + } + + _Check_return_ __inline float __CRTDECL ceilf(_In_ float _X) + { + return (float)ceil(_X); + } + + _Check_return_ __inline float __CRTDECL cosf(_In_ float _X) + { + return (float)cos(_X); + } + + _Check_return_ __inline float __CRTDECL coshf(_In_ float _X) + { + return (float)cosh(_X); + } + + _Check_return_ __inline float __CRTDECL expf(_In_ float _X) + { + return (float)exp(_X); + } + + #endif + + #if defined _M_ARM || defined _M_ARM64 || defined _M_HYBRID_X86_ARM64 || defined _M_ARM64EC + + _Check_return_ _CRT_JIT_INTRINSIC _ACRTIMP float __cdecl fabsf(_In_ float _X); + + #else + + _Check_return_ __inline float __CRTDECL fabsf(_In_ float _X) + { + return (float)fabs(_X); + } + + #endif + + #if defined _M_X64 || defined _M_ARM || defined _M_ARM64 || defined _M_HYBRID_X86_ARM64 || defined _M_ARM64EC + + _Check_return_ _ACRTIMP float __cdecl floorf(_In_ float _X); + _Check_return_ _ACRTIMP float __cdecl fmodf(_In_ float _X, _In_ float _Y); + + #else + + _Check_return_ __inline float __CRTDECL floorf(_In_ float _X) + { + return (float)floor(_X); + } + + _Check_return_ __inline float __CRTDECL fmodf(_In_ float _X, _In_ float _Y) + { + return (float)fmod(_X, _Y); + } + + #endif + + _Check_return_ __inline float __CRTDECL frexpf(_In_ float _X, _Out_ int *_Y) + { + return (float)frexp(_X, _Y); + } + + _Check_return_ __inline float __CRTDECL hypotf(_In_ float _X, _In_ float _Y) + { + return _hypotf(_X, _Y); + } + + _Check_return_ __inline float __CRTDECL ldexpf(_In_ float _X, _In_ int _Y) + { + return (float)ldexp(_X, _Y); + } + + #if defined _M_X64 || defined _M_ARM || defined _M_ARM64 || defined _M_HYBRID_X86_ARM64 || defined _CORECRT_BUILD_APISET || defined _M_ARM64EC + + _Check_return_ _ACRTIMP float __cdecl log10f(_In_ float _X); + _Check_return_ _ACRTIMP float __cdecl logf(_In_ float _X); + _Check_return_ _ACRTIMP float __cdecl modff(_In_ float _X, _Out_ float *_Y); + _Check_return_ _ACRTIMP float __cdecl powf(_In_ float _X, _In_ float _Y); + _Check_return_ _ACRTIMP float __cdecl sinf(_In_ float _X); + _Check_return_ _ACRTIMP float __cdecl sinhf(_In_ float _X); + _Check_return_ _ACRTIMP float __cdecl sqrtf(_In_ float _X); + _Check_return_ _ACRTIMP float __cdecl tanf(_In_ float _X); + _Check_return_ _ACRTIMP float __cdecl tanhf(_In_ float _X); + + #else + + _Check_return_ __inline float __CRTDECL log10f(_In_ float _X) + { + return (float)log10(_X); + } + + _Check_return_ __inline float __CRTDECL logf(_In_ float _X) + { + return (float)log(_X); + } + + _Check_return_ __inline float __CRTDECL modff(_In_ float _X, _Out_ float* _Y) + { + double _F, _I; + _F = modf(_X, &_I); + *_Y = (float)_I; + return (float)_F; + } + + _Check_return_ __inline float __CRTDECL powf(_In_ float _X, _In_ float _Y) + { + return (float)pow(_X, _Y); + } + + _Check_return_ __inline float __CRTDECL sinf(_In_ float _X) + { + return (float)sin(_X); + } + + _Check_return_ __inline float __CRTDECL sinhf(_In_ float _X) + { + return (float)sinh(_X); + } + + _Check_return_ __inline float __CRTDECL sqrtf(_In_ float _X) + { + return (float)sqrt(_X); + } + + _Check_return_ __inline float __CRTDECL tanf(_In_ float _X) + { + return (float)tan(_X); + } + + _Check_return_ __inline float __CRTDECL tanhf(_In_ float _X) + { + return (float)tanh(_X); + } + + #endif + + _Check_return_ _ACRTIMP long double __cdecl acoshl(_In_ long double _X); + + _Check_return_ __inline long double __CRTDECL acosl(_In_ long double _X) + { + return acos((double)_X); + } + + _Check_return_ _ACRTIMP long double __cdecl asinhl(_In_ long double _X); + + _Check_return_ __inline long double __CRTDECL asinl(_In_ long double _X) + { + return asin((double)_X); + } + + _Check_return_ __inline long double __CRTDECL atan2l(_In_ long double _Y, _In_ long double _X) + { + return atan2((double)_Y, (double)_X); + } + + _Check_return_ _ACRTIMP long double __cdecl atanhl(_In_ long double _X); + + _Check_return_ __inline long double __CRTDECL atanl(_In_ long double _X) + { + return atan((double)_X); + } + + _Check_return_ _ACRTIMP long double __cdecl cbrtl(_In_ long double _X); + + _Check_return_ __inline long double __CRTDECL ceill(_In_ long double _X) + { + return ceil((double)_X); + } + + _Check_return_ __inline long double __CRTDECL _chgsignl(_In_ long double _X) + { + return _chgsign((double)_X); + } + + _Check_return_ _ACRTIMP long double __cdecl copysignl(_In_ long double _Number, _In_ long double _Sign); + + _Check_return_ __inline long double __CRTDECL _copysignl(_In_ long double _Number, _In_ long double _Sign) + { + return _copysign((double)_Number, (double)_Sign); + } + + _Check_return_ __inline long double __CRTDECL coshl(_In_ long double _X) + { + return cosh((double)_X); + } + + _Check_return_ __inline long double __CRTDECL cosl(_In_ long double _X) + { + return cos((double)_X); + } + + _Check_return_ _ACRTIMP long double __cdecl erfl(_In_ long double _X); + _Check_return_ _ACRTIMP long double __cdecl erfcl(_In_ long double _X); + + _Check_return_ __inline long double __CRTDECL expl(_In_ long double _X) + { + return exp((double)_X); + } + + _Check_return_ _ACRTIMP long double __cdecl exp2l(_In_ long double _X); + _Check_return_ _ACRTIMP long double __cdecl expm1l(_In_ long double _X); + + _Check_return_ __inline long double __CRTDECL fabsl(_In_ long double _X) + { + return fabs((double)_X); + } + + _Check_return_ _ACRTIMP long double __cdecl fdiml(_In_ long double _X, _In_ long double _Y); + + _Check_return_ __inline long double __CRTDECL floorl(_In_ long double _X) + { + return floor((double)_X); + } + + _Check_return_ _ACRTIMP long double __cdecl fmal(_In_ long double _X, _In_ long double _Y, _In_ long double _Z); + _Check_return_ _ACRTIMP long double __cdecl fmaxl(_In_ long double _X, _In_ long double _Y); + _Check_return_ _ACRTIMP long double __cdecl fminl(_In_ long double _X, _In_ long double _Y); + + _Check_return_ __inline long double __CRTDECL fmodl(_In_ long double _X, _In_ long double _Y) + { + return fmod((double)_X, (double)_Y); + } + + _Check_return_ __inline long double __CRTDECL frexpl(_In_ long double _X, _Out_ int *_Y) + { + return frexp((double)_X, _Y); + } + + _Check_return_ _ACRTIMP int __cdecl ilogbl(_In_ long double _X); + + _Check_return_ __inline long double __CRTDECL _hypotl(_In_ long double _X, _In_ long double _Y) + { + return _hypot((double)_X, (double)_Y); + } + + _Check_return_ __inline long double __CRTDECL hypotl(_In_ long double _X, _In_ long double _Y) + { + return _hypot((double)_X, (double)_Y); + } + + _Check_return_ __inline long double __CRTDECL ldexpl(_In_ long double _X, _In_ int _Y) + { + return ldexp((double)_X, _Y); + } + + _Check_return_ _ACRTIMP long double __cdecl lgammal(_In_ long double _X); + _Check_return_ _ACRTIMP long long __cdecl llrintl(_In_ long double _X); + _Check_return_ _ACRTIMP long long __cdecl llroundl(_In_ long double _X); + + _Check_return_ __inline long double __CRTDECL logl(_In_ long double _X) + { + return log((double)_X); + } + + _Check_return_ __inline long double __CRTDECL log10l(_In_ long double _X) + { + return log10((double)_X); + } + + _Check_return_ _ACRTIMP long double __cdecl log1pl(_In_ long double _X); + _Check_return_ _ACRTIMP long double __cdecl log2l(_In_ long double _X); + _Check_return_ _ACRTIMP long double __cdecl logbl(_In_ long double _X); + _Check_return_ _ACRTIMP long __cdecl lrintl(_In_ long double _X); + _Check_return_ _ACRTIMP long __cdecl lroundl(_In_ long double _X); + + _Check_return_ __inline long double __CRTDECL modfl(_In_ long double _X, _Out_ long double* _Y) + { + double _F, _I; + _F = modf((double)_X, &_I); + *_Y = _I; + return _F; + } + + _Check_return_ _ACRTIMP long double __cdecl nanl(_In_ char const* _X); + _Check_return_ _ACRTIMP long double __cdecl nearbyintl(_In_ long double _X); + _Check_return_ _ACRTIMP long double __cdecl nextafterl(_In_ long double _X, _In_ long double _Y); + _Check_return_ _ACRTIMP long double __cdecl nexttowardl(_In_ long double _X, _In_ long double _Y); + + _Check_return_ __inline long double __CRTDECL powl(_In_ long double _X, _In_ long double _Y) + { + return pow((double)_X, (double)_Y); + } + + _Check_return_ _ACRTIMP long double __cdecl remainderl(_In_ long double _X, _In_ long double _Y); + _Check_return_ _ACRTIMP long double __cdecl remquol(_In_ long double _X, _In_ long double _Y, _Out_ int* _Z); + _Check_return_ _ACRTIMP long double __cdecl rintl(_In_ long double _X); + _Check_return_ _ACRTIMP long double __cdecl roundl(_In_ long double _X); + _Check_return_ _ACRTIMP long double __cdecl scalblnl(_In_ long double _X, _In_ long _Y); + _Check_return_ _ACRTIMP long double __cdecl scalbnl(_In_ long double _X, _In_ int _Y); + + _Check_return_ __inline long double __CRTDECL sinhl(_In_ long double _X) + { + return sinh((double)_X); + } + + _Check_return_ __inline long double __CRTDECL sinl(_In_ long double _X) + { + return sin((double)_X); + } + + _Check_return_ __inline long double __CRTDECL sqrtl(_In_ long double _X) + { + return sqrt((double)_X); + } + + _Check_return_ __inline long double __CRTDECL tanhl(_In_ long double _X) + { + return tanh((double)_X); + } + + _Check_return_ __inline long double __CRTDECL tanl(_In_ long double _X) + { + return tan((double)_X); + } + + _Check_return_ _ACRTIMP long double __cdecl tgammal(_In_ long double _X); + _Check_return_ _ACRTIMP long double __cdecl truncl(_In_ long double _X); + + #ifndef __cplusplus + #define _matherrl _matherr + #endif + +#endif // _CRT_FUNCTIONS_REQUIRED + +#if defined(_CRT_INTERNAL_NONSTDC_NAMES) && _CRT_INTERNAL_NONSTDC_NAMES + + #define DOMAIN _DOMAIN + #define SING _SING + #define OVERFLOW _OVERFLOW + #define UNDERFLOW _UNDERFLOW + #define TLOSS _TLOSS + #define PLOSS _PLOSS + + #define matherr _matherr + + #ifndef __assembler + #ifndef _M_CEE_PURE + extern double HUGE; + #else + double const HUGE = _HUGE; + #endif + + _CRT_NONSTDC_DEPRECATE(_j0) _Check_return_ _ACRTIMP double __cdecl j0(_In_ double _X); + _CRT_NONSTDC_DEPRECATE(_j1) _Check_return_ _ACRTIMP double __cdecl j1(_In_ double _X); + _CRT_NONSTDC_DEPRECATE(_jn) _Check_return_ _ACRTIMP double __cdecl jn(_In_ int _X, _In_ double _Y); + _CRT_NONSTDC_DEPRECATE(_y0) _Check_return_ _ACRTIMP double __cdecl y0(_In_ double _X); + _CRT_NONSTDC_DEPRECATE(_y1) _Check_return_ _ACRTIMP double __cdecl y1(_In_ double _X); + _CRT_NONSTDC_DEPRECATE(_yn) _Check_return_ _ACRTIMP double __cdecl yn(_In_ int _X, _In_ double _Y); + #endif // !__assembler + +#endif // _CRT_INTERNAL_NONSTDC_NAMES + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS +#endif /* _INC_MATH */ diff --git a/sdk/include/ucrt/corecrt_math_defines.h b/sdk/include/ucrt/corecrt_math_defines.h new file mode 100644 index 0000000000000..5b048161a2bb0 --- /dev/null +++ b/sdk/include/ucrt/corecrt_math_defines.h @@ -0,0 +1,39 @@ +// +// corecrt_math_defines.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// Definitions of useful mathematical constants +// +#pragma once +#ifndef _MATH_DEFINES_DEFINED +#define _MATH_DEFINES_DEFINED + +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +// Definitions of useful mathematical constants +// +// Define _USE_MATH_DEFINES before including to expose these macro +// definitions for common math constants. These are placed under an #ifdef +// since these commonly-defined names are not part of the C or C++ standards +#define M_E 2.71828182845904523536 // e +#define M_LOG2E 1.44269504088896340736 // log2(e) +#define M_LOG10E 0.434294481903251827651 // log10(e) +#define M_LN2 0.693147180559945309417 // ln(2) +#define M_LN10 2.30258509299404568402 // ln(10) +#define M_PI 3.14159265358979323846 // pi +#define M_PI_2 1.57079632679489661923 // pi/2 +#define M_PI_4 0.785398163397448309616 // pi/4 +#define M_1_PI 0.318309886183790671538 // 1/pi +#define M_2_PI 0.636619772367581343076 // 2/pi +#define M_2_SQRTPI 1.12837916709551257390 // 2/sqrt(pi) +#define M_SQRT2 1.41421356237309504880 // sqrt(2) +#define M_SQRT1_2 0.707106781186547524401 // 1/sqrt(2) + +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS +#endif // _MATH_DEFINES_DEFINED diff --git a/sdk/include/ucrt/corecrt_memcpy_s.h b/sdk/include/ucrt/corecrt_memcpy_s.h new file mode 100644 index 0000000000000..002eed111c9e8 --- /dev/null +++ b/sdk/include/ucrt/corecrt_memcpy_s.h @@ -0,0 +1,93 @@ +// +// corecrt_memcpy_s.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// Inline definitions of memcpy_s and memmove_s +// +#pragma once + +#include +#include +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + +#ifndef _CRT_MEMCPY_S_INLINE + #define _CRT_MEMCPY_S_INLINE static __inline +#endif + +#define _CRT_MEMCPY_S_VALIDATE_RETURN_ERRCODE(expr, errorcode) \ + { \ + int _Expr_val=!!(expr); \ + if (!(_Expr_val)) \ + { \ + errno = errorcode; \ + _invalid_parameter_noinfo(); \ + return errorcode; \ + } \ + } + +#if !defined RC_INVOKED && !defined __midl && __STDC_WANT_SECURE_LIB__ + + _Success_(return == 0) + _Check_return_opt_ + _CRT_MEMCPY_S_INLINE errno_t __CRTDECL memcpy_s( + _Out_writes_bytes_to_opt_(_DestinationSize, _SourceSize) void* const _Destination, + _In_ rsize_t const _DestinationSize, + _In_reads_bytes_opt_(_SourceSize) void const* const _Source, + _In_ rsize_t const _SourceSize + ) + { + if (_SourceSize == 0) + { + return 0; + } + + _CRT_MEMCPY_S_VALIDATE_RETURN_ERRCODE(_Destination != NULL, EINVAL); + if (_Source == NULL || _DestinationSize < _SourceSize) + { + memset(_Destination, 0, _DestinationSize); + + _CRT_MEMCPY_S_VALIDATE_RETURN_ERRCODE(_Source != NULL, EINVAL); + _CRT_MEMCPY_S_VALIDATE_RETURN_ERRCODE(_DestinationSize >= _SourceSize, ERANGE); + + // Unreachable, but required to suppress /analyze warnings: + return EINVAL; + } + memcpy(_Destination, _Source, _SourceSize); + return 0; + } + + _Check_return_wat_ + _CRT_MEMCPY_S_INLINE errno_t __CRTDECL memmove_s( + _Out_writes_bytes_to_opt_(_DestinationSize, _SourceSize) void* const _Destination, + _In_ rsize_t const _DestinationSize, + _In_reads_bytes_opt_(_SourceSize) void const* const _Source, + _In_ rsize_t const _SourceSize + ) + { + if (_SourceSize == 0) + { + return 0; + } + + _CRT_MEMCPY_S_VALIDATE_RETURN_ERRCODE(_Destination != NULL, EINVAL); + _CRT_MEMCPY_S_VALIDATE_RETURN_ERRCODE(_Source != NULL, EINVAL); + _CRT_MEMCPY_S_VALIDATE_RETURN_ERRCODE(_DestinationSize >= _SourceSize, ERANGE); + + memmove(_Destination, _Source, _SourceSize); + return 0; + } + +#endif + +#undef _CRT_MEMCPY_S_VALIDATE_RETURN_ERRCODE + +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS +_CRT_END_C_HEADER diff --git a/sdk/include/ucrt/corecrt_memory.h b/sdk/include/ucrt/corecrt_memory.h new file mode 100644 index 0000000000000..a9909f85a7bbe --- /dev/null +++ b/sdk/include/ucrt/corecrt_memory.h @@ -0,0 +1,122 @@ +// +// corecrt_memory.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The buffer (memory) manipulation library. These declarations are split out +// so that they may be included by both and . +// does not include to avoid introducing conflicts with other user +// headers named . +// +#pragma once + +#include +#include +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +#ifndef __midl + +_CRT_BEGIN_C_HEADER + + + +_Check_return_ +_ACRTIMP int __cdecl _memicmp( + _In_reads_bytes_opt_(_Size) void const* _Buf1, + _In_reads_bytes_opt_(_Size) void const* _Buf2, + _In_ size_t _Size + ); + +_Check_return_ +_ACRTIMP int __cdecl _memicmp_l( + _In_reads_bytes_opt_(_Size) void const* _Buf1, + _In_reads_bytes_opt_(_Size) void const* _Buf2, + _In_ size_t _Size, + _In_opt_ _locale_t _Locale + ); + + + +#if !defined RC_INVOKED && __STDC_WANT_SECURE_LIB__ + + #if defined __cplusplus && _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_MEMORY + extern "C++" + { + template + inline typename _CrtEnableIf<(_Size > 1), void *>::_Type __cdecl memcpy( + _DstType (&_Dst)[_Size], + _In_reads_bytes_opt_(_SrcSize) void const* _Src, + _In_ size_t _SrcSize + ) _CRT_SECURE_CPP_NOTHROW + { + return memcpy_s(_Dst, _Size * sizeof(_DstType), _Src, _SrcSize) == 0 ? _Dst : 0; + } + } + #endif + + #if defined __cplusplus && _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES_MEMORY + extern "C++" + { + template + inline errno_t __CRTDECL memcpy_s( + _DstType (&_Dst)[_Size], + _In_reads_bytes_opt_(_SrcSize) void const* _Src, + _In_ rsize_t _SrcSize + ) _CRT_SECURE_CPP_NOTHROW + { + return memcpy_s(_Dst, _Size * sizeof(_DstType), _Src, _SrcSize); + } + } + #endif + +#endif // !defined RC_INVOKED && __STDC_WANT_SECURE_LIB__ + + + +#if defined(_CRT_INTERNAL_NONSTDC_NAMES) && _CRT_INTERNAL_NONSTDC_NAMES + + _CRT_NONSTDC_DEPRECATE(_memccpy) + _ACRTIMP void* __cdecl memccpy( + _Out_writes_bytes_opt_(_Size) void* _Dst, + _In_reads_bytes_opt_(_Size) void const* _Src, + _In_ int _Val, + _In_ size_t _Size + ); + + _Check_return_ _CRT_NONSTDC_DEPRECATE(_memicmp) + _ACRTIMP int __cdecl memicmp( + _In_reads_bytes_opt_(_Size) void const* _Buf1, + _In_reads_bytes_opt_(_Size) void const* _Buf2, + _In_ size_t _Size + ); + +#endif // _CRT_INTERNAL_NONSTDC_NAMES + + + +#if defined __cplusplus + + extern "C++" _Check_return_ + inline void* __CRTDECL memchr( + _In_reads_bytes_opt_(_N) void* _Pv, + _In_ int _C, + _In_ size_t _N + ) + { + void const* const _Pvc = _Pv; + return const_cast(memchr(_Pvc, _C, _N)); + } + +#endif + + + +_CRT_END_C_HEADER + +#endif // !__midl +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS diff --git a/sdk/include/ucrt/corecrt_search.h b/sdk/include/ucrt/corecrt_search.h new file mode 100644 index 0000000000000..499258586f9a4 --- /dev/null +++ b/sdk/include/ucrt/corecrt_search.h @@ -0,0 +1,218 @@ +// +// corecrt_search.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// Declarations of functions for sorting and searching. These declarations are +// split out so that they may be included by both and . +// does not include to avoid introducing conflicts with +// other user headers named . +// +#pragma once + +#include +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + + + typedef int (__cdecl* _CoreCrtSecureSearchSortCompareFunction)(void*, void const*, void const*); + typedef int (__cdecl* _CoreCrtNonSecureSearchSortCompareFunction)(void const*, void const*); + + +#if __STDC_WANT_SECURE_LIB__ + + _Check_return_ + _ACRTIMP void* __cdecl bsearch_s( + _In_ void const* _Key, + _In_reads_bytes_(_NumOfElements * _SizeOfElements) void const* _Base, + _In_ rsize_t _NumOfElements, + _In_ rsize_t _SizeOfElements, + _In_ _CoreCrtSecureSearchSortCompareFunction _CompareFunction, + _In_opt_ void* _Context + ); + + _ACRTIMP void __cdecl qsort_s( + _Inout_updates_bytes_(_NumOfElements * _SizeOfElements) void* _Base, + _In_ rsize_t _NumOfElements, + _In_ rsize_t _SizeOfElements, + _In_ _CoreCrtSecureSearchSortCompareFunction _CompareFunction, + _In_opt_ void* _Context + ); + +#endif // __STDC_WANT_SECURE_LIB__ + + + +_Check_return_ +_ACRTIMP void* __cdecl bsearch( + _In_ void const* _Key, + _In_reads_bytes_(_NumOfElements * _SizeOfElements) void const* _Base, + _In_ size_t _NumOfElements, + _In_ size_t _SizeOfElements, + _In_ _CoreCrtNonSecureSearchSortCompareFunction _CompareFunction + ); + +_ACRTIMP void __cdecl qsort( + _Inout_updates_bytes_(_NumOfElements * _SizeOfElements) void* _Base, + _In_ size_t _NumOfElements, + _In_ size_t _SizeOfElements, + _In_ _CoreCrtNonSecureSearchSortCompareFunction _CompareFunction + ); + +_Check_return_ +_ACRTIMP void* __cdecl _lfind_s( + _In_ void const* _Key, + _In_reads_bytes_((*_NumOfElements) * _SizeOfElements) void const* _Base, + _Inout_ unsigned int* _NumOfElements, + _In_ size_t _SizeOfElements, + _In_ _CoreCrtSecureSearchSortCompareFunction _CompareFunction, + _In_ void* _Context + ); + +_Check_return_ +_ACRTIMP void* __cdecl _lfind( + _In_ void const* _Key, + _In_reads_bytes_((*_NumOfElements) * _SizeOfElements) void const* _Base, + _Inout_ unsigned int* _NumOfElements, + _In_ unsigned int _SizeOfElements, + _In_ _CoreCrtNonSecureSearchSortCompareFunction _CompareFunction + ); + +_Check_return_ +_ACRTIMP void* __cdecl _lsearch_s( + _In_ void const* _Key, + _Inout_updates_bytes_((*_NumOfElements ) * _SizeOfElements) void* _Base, + _Inout_ unsigned int* _NumOfElements, + _In_ size_t _SizeOfElements, + _In_ _CoreCrtSecureSearchSortCompareFunction _CompareFunction, + _In_ void* _Context + ); + +_Check_return_ +_ACRTIMP void* __cdecl _lsearch( + _In_ void const* _Key, + _Inout_updates_bytes_((*_NumOfElements ) * _SizeOfElements) void* _Base, + _Inout_ unsigned int* _NumOfElements, + _In_ unsigned int _SizeOfElements, + _In_ _CoreCrtNonSecureSearchSortCompareFunction _CompareFunction + ); + + + +// Managed search routines +#if defined __cplusplus && defined _M_CEE +extern "C++" +{ + typedef int (__clrcall* _CoreCrtMgdSecureSearchSortCompareFunction)(void*, void const*, void const*); + typedef int (__clrcall* _CoreCrtMgdNonSecureSearchSortCompareFunction)(void const*, void const*); + + #if __STDC_WANT_SECURE_LIB__ + + _Check_return_ + void* __clrcall bsearch_s( + _In_ void const* _Key, + _In_reads_bytes_(_NumOfElements * _SizeOfElements) void const* _Base, + _In_ rsize_t _NumOfElements, + _In_ rsize_t _SizeOfElements, + _In_ _CoreCrtMgdSecureSearchSortCompareFunction _CompareFunction, + _In_ void* _Context); + + void __clrcall qsort_s( + _Inout_updates_bytes_(_NumOfElements * _SizeOfElements) void* _Base, + _In_ rsize_t _NumOfElements, + _In_ rsize_t _SizeOfElements, + _In_ _CoreCrtMgdSecureSearchSortCompareFunction _CompareFunction, + _In_ void* _Context); + + #endif // __STDC_WANT_SECURE_LIB__ + + _Check_return_ + void* __clrcall bsearch( + _In_ void const* _Key, + _In_reads_bytes_(_NumOfElements * _SizeOfElements) void const* _Base, + _In_ size_t _NumOfElements, + _In_ size_t _SizeOfElements, + _In_ _CoreCrtMgdNonSecureSearchSortCompareFunction _CompareFunction + ); + + _Check_return_ + void* __clrcall _lfind_s( + _In_ void const* _Key, + _In_reads_bytes_(_NumOfElements * _SizeOfElements) void const* _Base, + _Inout_ unsigned int* _NumOfElements, + _In_ size_t _SizeOfElements, + _In_ _CoreCrtMgdSecureSearchSortCompareFunction _CompareFunction, + _In_ void* _Context + ); + + _Check_return_ + void* __clrcall _lfind( + _In_ void const* _Key, + _In_reads_bytes_((*_NumOfElements) * _SizeOfElements) void const* _Base, + _Inout_ unsigned int* _NumOfElements, + _In_ unsigned int _SizeOfElements, + _In_ _CoreCrtMgdNonSecureSearchSortCompareFunction _CompareFunction + ); + + _Check_return_ + void* __clrcall _lsearch_s( + _In_ void const* _Key, + _In_reads_bytes_((*_NumOfElements) * _SizeOfElements) void* _Base, + _In_ unsigned int* _NumOfElements, + _In_ size_t _SizeOfElements, + _In_ _CoreCrtMgdSecureSearchSortCompareFunction _CompareFunction, + _In_ void* _Context + ); + + _Check_return_ + void* __clrcall _lsearch( + _In_ void const* _Key, + _Inout_updates_bytes_((*_NumOfElements) * _SizeOfElements) void* _Base, + _Inout_ unsigned int* _NumOfElements, + _In_ unsigned int _SizeOfElements, + _In_ _CoreCrtMgdNonSecureSearchSortCompareFunction _CompareFunction + ); + + void __clrcall qsort( + _Inout_updates_bytes_(_NumOfElements * _SizeOfElements) void* _Base, + _In_ size_t _NumOfElements, + _In_ size_t _SizeOfElements, + _In_ _CoreCrtMgdNonSecureSearchSortCompareFunction _CompareFunction + ); +} +#endif // defined __cplusplus && defined _M_CEE + + + +#if defined(_CRT_INTERNAL_NONSTDC_NAMES) && _CRT_INTERNAL_NONSTDC_NAMES + + _Check_return_ _CRT_NONSTDC_DEPRECATE(_lfind) + _ACRTIMP void* __cdecl lfind( + _In_ void const* _Key, + _In_reads_bytes_((*_NumOfElements) * _SizeOfElements) void const* _Base, + _Inout_ unsigned int* _NumOfElements, + _In_ unsigned int _SizeOfElements, + _In_ _CoreCrtNonSecureSearchSortCompareFunction _CompareFunction + ); + + _Check_return_ _CRT_NONSTDC_DEPRECATE(_lsearch) + _ACRTIMP void* __cdecl lsearch( + _In_ void const* _Key, + _Inout_updates_bytes_((*_NumOfElements) * _SizeOfElements) void* _Base, + _Inout_ unsigned int* _NumOfElements, + _In_ unsigned int _SizeOfElements, + _In_ _CoreCrtNonSecureSearchSortCompareFunction _CompareFunction + ); + +#endif // _CRT_INTERNAL_NONSTDC_NAMES + + + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS diff --git a/sdk/include/ucrt/corecrt_share.h b/sdk/include/ucrt/corecrt_share.h new file mode 100644 index 0000000000000..64925bcfff52b --- /dev/null +++ b/sdk/include/ucrt/corecrt_share.h @@ -0,0 +1,33 @@ +// +// corecrt_share.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// Defines the file sharing modes for the sopen() family of functions. These +// declarations are split out to support the Windows build. +// +#pragma once + +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +#define _SH_DENYRW 0x10 // deny read/write mode +#define _SH_DENYWR 0x20 // deny write mode +#define _SH_DENYRD 0x30 // deny read mode +#define _SH_DENYNO 0x40 // deny none mode +#define _SH_SECURE 0x80 // secure mode + + + +#if (defined _CRT_DECLARE_NONSTDC_NAMES && _CRT_DECLARE_NONSTDC_NAMES) || (!defined _CRT_DECLARE_NONSTDC_NAMES && !__STDC__) + #define SH_DENYRW _SH_DENYRW + #define SH_DENYWR _SH_DENYWR + #define SH_DENYRD _SH_DENYRD + #define SH_DENYNO _SH_DENYNO +#endif + +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS diff --git a/sdk/include/ucrt/corecrt_startup.h b/sdk/include/ucrt/corecrt_startup.h new file mode 100644 index 0000000000000..19e6dc27866e0 --- /dev/null +++ b/sdk/include/ucrt/corecrt_startup.h @@ -0,0 +1,199 @@ +// +// corecrt_startup.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// Declarations for the CoreCRT startup functionality, used while initializing +// the CRT and during app startup and termination. +// +#pragma once + +#include +#include +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Exception Filters for main() and DllMain() +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +struct _EXCEPTION_POINTERS; + +_ACRTIMP int __cdecl _seh_filter_dll( + _In_ unsigned long _ExceptionNum, + _In_ struct _EXCEPTION_POINTERS* _ExceptionPtr + ); + +_ACRTIMP int __cdecl _seh_filter_exe( + _In_ unsigned long _ExceptionNum, + _In_ struct _EXCEPTION_POINTERS* _ExceptionPtr + ); + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Miscellaneous Runtime Support +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +typedef enum _crt_app_type +{ + _crt_unknown_app, + _crt_console_app, + _crt_gui_app +} _crt_app_type; + +_ACRTIMP _crt_app_type __cdecl _query_app_type(void); + +_ACRTIMP void __cdecl _set_app_type( + _In_ _crt_app_type _Type + ); + +typedef int (__cdecl *_UserMathErrorFunctionPointer)(struct _exception *); + +_ACRTIMP void __cdecl __setusermatherr( + _UserMathErrorFunctionPointer _UserMathErrorFunction + ); + +int __cdecl _is_c_termination_complete(void); + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Arguments API for main() et al. +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +_ACRTIMP errno_t __cdecl _configure_narrow_argv( + _In_ _crt_argv_mode mode + ); + +_ACRTIMP errno_t __cdecl _configure_wide_argv( + _In_ _crt_argv_mode mode + ); + +// There is a linkopt for these to disable environment initialization when using +// the static CRT, so they are not declared _ACRTIMP. +int __CRTDECL _initialize_narrow_environment(void); +int __CRTDECL _initialize_wide_environment(void); + +_ACRTIMP char** __cdecl _get_initial_narrow_environment(void); +_ACRTIMP wchar_t** __cdecl _get_initial_wide_environment(void); + +char* __CRTDECL _get_narrow_winmain_command_line(void); +wchar_t* __CRTDECL _get_wide_winmain_command_line(void); + +_ACRTIMP char** __cdecl __p__acmdln(void); +_ACRTIMP wchar_t** __cdecl __p__wcmdln(void); + +#ifdef _CRT_DECLARE_GLOBAL_VARIABLES_DIRECTLY + extern char* _acmdln; + extern wchar_t* _wcmdln; +#else + #define _acmdln (*__p__acmdln()) + #define _wcmdln (*__p__wcmdln()) +#endif + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Initializer and Terminator Support +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +typedef void (__cdecl* _PVFV)(void); +typedef int (__cdecl* _PIFV)(void); +typedef void (__cdecl* _PVFI)(int); + +#ifndef _M_CEE + _ACRTIMP void __cdecl _initterm( + _In_reads_(_Last - _First) _In_ _PVFV* _First, + _In_ _PVFV* _Last + ); + + _ACRTIMP int __cdecl _initterm_e( + _In_reads_(_Last - _First) _PIFV* _First, + _In_ _PIFV* _Last + ); +#endif + +#ifndef _CRT_ONEXIT_T_DEFINED + #define _CRT_ONEXIT_T_DEFINED + + typedef int (__CRTDECL* _onexit_t)(void); + #ifdef _M_CEE + typedef int (__clrcall* _onexit_m_t)(void); + #endif +#endif + +typedef struct _onexit_table_t +{ + _PVFV* _first; + _PVFV* _last; + _PVFV* _end; +} _onexit_table_t; + +_ACRTIMP int __cdecl _initialize_onexit_table( + _In_opt_ _onexit_table_t* _Table + ); + +_ACRTIMP int __cdecl _register_onexit_function( + _In_opt_ _onexit_table_t* _Table, + _In_opt_ _onexit_t _Function + ); + +_ACRTIMP int __cdecl _execute_onexit_table( + _In_opt_ _onexit_table_t* _Table + ); + +_ACRTIMP int __cdecl _crt_atexit( + _In_opt_ _PVFV _Function + ); + +_ACRTIMP int __cdecl _crt_at_quick_exit( + _In_opt_ _PVFV _Function + ); + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Static CRT Initialization Support +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#if _CRT_FUNCTIONS_REQUIRED + + _Success_(return != 0) + __crt_bool __cdecl __acrt_initialize(void); + + _Success_(return != 0) + __crt_bool __cdecl __acrt_uninitialize( + _In_ __crt_bool _Terminating + ); + + _Success_(return != 0) + __crt_bool __cdecl __acrt_uninitialize_critical( + _In_ __crt_bool _Terminating + ); + + _Success_(return != 0) + __crt_bool __cdecl __acrt_thread_attach(void); + + _Success_(return != 0) + __crt_bool __cdecl __acrt_thread_detach(void); + +#endif // _CRT_FUNCTIONS_REQUIRED + + + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS diff --git a/sdk/include/ucrt/corecrt_stdio_config.h b/sdk/include/ucrt/corecrt_stdio_config.h new file mode 100644 index 0000000000000..cc4b410b525fa --- /dev/null +++ b/sdk/include/ucrt/corecrt_stdio_config.h @@ -0,0 +1,131 @@ +// +// corecrt_stdio_config.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// Per-module configuration. +// +#pragma once + +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + +#if !defined _NO_CRT_STDIO_INLINE && !_CRT_FUNCTIONS_REQUIRED + #define _NO_CRT_STDIO_INLINE +#endif + +#if defined _NO_CRT_STDIO_INLINE + #undef _CRT_STDIO_INLINE + #define _CRT_STDIO_INLINE +#elif !defined _CRT_STDIO_INLINE + #if defined(__GNUC__) + #define _CRT_STDIO_INLINE static __inline + #else + #define _CRT_STDIO_INLINE __inline + #endif +#endif + +#if !defined RC_INVOKED // RC has no target architecture + #if defined _M_IX86 + #define _CRT_INTERNAL_STDIO_SYMBOL_PREFIX "_" + #elif defined _M_X64 || defined _M_ARM || defined _M_ARM64 + #define _CRT_INTERNAL_STDIO_SYMBOL_PREFIX "" + #else + #error Unsupported architecture + #endif +#endif + + + +// Predefine _CRT_STDIO_ISO_WIDE_SPECIFIERS to use ISO-conforming behavior for +// the wide string printf and scanf functions (%s, %c, and %[] specifiers). +// +// Predefine _CRT_STDIO_LEGACY_WIDE_SPECIFIERS to use VC++ 2013 and earlier behavior for +// the wide string printf and scanf functions (%s, %c, and %[] specifiers). +// +// Predefine _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS when building code that does +// not use these format specifiers without a length modifier and thus can be +// used with either the legacy (default) or the conforming mode. (This option +// is intended for use by static libraries). +#if !defined RC_INVOKED // _CRT_STDIO_LEGACY_WIDE_SPECIFIERS et al. are too long for rc + #if defined _CRT_STDIO_ISO_WIDE_SPECIFIERS + #if defined _CRT_STDIO_LEGACY_WIDE_SPECIFIERS + #error _CRT_STDIO_ISO_WIDE_SPECIFIERS and _CRT_STDIO_LEGACY_WIDE_SPECIFIERS cannot be defined together. + #endif + + #if !defined _M_CEE_PURE + #pragma comment(lib, "iso_stdio_wide_specifiers") + #pragma comment(linker, "/include:" _CRT_INTERNAL_STDIO_SYMBOL_PREFIX "__PLEASE_LINK_WITH_iso_stdio_wide_specifiers.lib") + #endif + #elif defined _CRT_STDIO_LEGACY_WIDE_SPECIFIERS + #if !defined _M_CEE_PURE + #pragma comment(lib, "legacy_stdio_wide_specifiers") + #pragma comment(linker, "/include:" _CRT_INTERNAL_STDIO_SYMBOL_PREFIX "__PLEASE_LINK_WITH_legacy_stdio_wide_specifiers.lib") + #endif + #endif + + #if defined __cplusplus && !defined _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS + #ifdef _CRT_STDIO_ISO_WIDE_SPECIFIERS + #pragma detect_mismatch("_CRT_STDIO_ISO_WIDE_SPECIFIERS", "1") + #else + #pragma detect_mismatch("_CRT_STDIO_ISO_WIDE_SPECIFIERS", "0") + #endif + #endif +#endif + +// If we're compiling mixed managed code, make sure these inline functions are +// compiled as native to ensure that there is only one instance of each of the +// function-local static variables. +#if defined _M_CEE && !defined _M_CEE_PURE + #pragma managed(push, off) +#endif + +#if _CRT_FUNCTIONS_REQUIRED + __declspec(selectany) unsigned __int64 __local_stdio_printf_options_storage; + _Check_return_ _Ret_notnull_ + _CRT_INLINE_PURE_SECURITYCRITICAL_ATTRIBUTE + __inline unsigned __int64* __CRTDECL __local_stdio_printf_options(void) + { + return &__local_stdio_printf_options_storage; + } + + __declspec(selectany) unsigned __int64 __local_stdio_scanf_options_storage; + _Check_return_ _Ret_notnull_ + _CRT_INLINE_PURE_SECURITYCRITICAL_ATTRIBUTE + __inline unsigned __int64* __CRTDECL __local_stdio_scanf_options(void) + { + return &__local_stdio_scanf_options_storage; + } +#endif + +#if defined _M_CEE && !defined _M_CEE_PURE + #pragma managed(pop) +#endif + +#define _CRT_INTERNAL_LOCAL_PRINTF_OPTIONS (*__local_stdio_printf_options()) +#define _CRT_INTERNAL_LOCAL_SCANF_OPTIONS (*__local_stdio_scanf_options ()) + + + +#define _CRT_INTERNAL_PRINTF_LEGACY_VSPRINTF_NULL_TERMINATION (1ULL << 0) +#define _CRT_INTERNAL_PRINTF_STANDARD_SNPRINTF_BEHAVIOR (1ULL << 1) +#define _CRT_INTERNAL_PRINTF_LEGACY_WIDE_SPECIFIERS (1ULL << 2) +#define _CRT_INTERNAL_PRINTF_LEGACY_MSVCRT_COMPATIBILITY (1ULL << 3) +#define _CRT_INTERNAL_PRINTF_LEGACY_THREE_DIGIT_EXPONENTS (1ULL << 4) +#define _CRT_INTERNAL_PRINTF_STANDARD_ROUNDING (1ULL << 5) + + +#define _CRT_INTERNAL_SCANF_SECURECRT (1ULL << 0) +#define _CRT_INTERNAL_SCANF_LEGACY_WIDE_SPECIFIERS (1ULL << 1) +#define _CRT_INTERNAL_SCANF_LEGACY_MSVCRT_COMPATIBILITY (1ULL << 2) + + + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS diff --git a/sdk/include/ucrt/corecrt_terminate.h b/sdk/include/ucrt/corecrt_terminate.h new file mode 100644 index 0000000000000..ac374bc29b40d --- /dev/null +++ b/sdk/include/ucrt/corecrt_terminate.h @@ -0,0 +1,51 @@ +// +// corecrt_terminate.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The terminate handler +// +#pragma once + +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +#ifndef RC_INVOKED + +_CRT_BEGIN_C_HEADER + +// terminate_handler is the standard name; terminate_function is defined for +// source compatibility. +typedef void (__CRTDECL* terminate_handler )(void); +typedef void (__CRTDECL* terminate_function)(void); + +#ifdef _M_CEE + typedef void (__clrcall* __terminate_function_m)(); + typedef void (__clrcall* __terminate_handler_m )(); +#endif + +#ifdef __cplusplus + + _ACRTIMP __declspec(noreturn) void __cdecl abort(); + _ACRTIMP __declspec(noreturn) void __cdecl terminate() throw(); + + #ifndef _M_CEE_PURE + + _ACRTIMP terminate_handler __cdecl set_terminate( + _In_opt_ terminate_handler _NewTerminateHandler + ) throw(); + + _ACRTIMP terminate_handler __cdecl _get_terminate(); + + #endif + +#endif // __cplusplus + +_CRT_END_C_HEADER + +#endif // RC_INVOKED +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS diff --git a/sdk/include/ucrt/corecrt_wconio.h b/sdk/include/ucrt/corecrt_wconio.h new file mode 100644 index 0000000000000..d987fb630bc48 --- /dev/null +++ b/sdk/include/ucrt/corecrt_wconio.h @@ -0,0 +1,424 @@ +// +// corecrt_wconio.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// This file declares the wide character (wchar_t) console I/O functionality, +// shared by both and +// +#pragma once + +#include +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + +#define WEOF ((wint_t)(0xFFFF)) + + + +#ifdef _CRT_USE_WINAPI_FAMILY_DESKTOP_APP + + _Check_return_wat_ + _Success_(_BufferCount > 0) + _DCRTIMP errno_t __cdecl _cgetws_s( + _Out_writes_to_(_BufferCount, *_SizeRead) wchar_t* _Buffer, + _In_ size_t _BufferCount, + _Out_ size_t* _SizeRead + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1( + _Success_(return == 0) + errno_t, _cgetws_s, + _Out_writes_z_(*_Buffer) wchar_t, _Buffer, + _In_ size_t*, _SizeRead + ) + + _Check_return_opt_ + _DCRTIMP int __cdecl _cputws( + _In_z_ wchar_t const* _Buffer + ); + + _Check_return_ _DCRTIMP wint_t __cdecl _getwch (void); + _Check_return_ _DCRTIMP wint_t __cdecl _getwche (void); + _Check_return_opt_ _DCRTIMP wint_t __cdecl _putwch (_In_ wchar_t _Character); + _Check_return_opt_ _DCRTIMP wint_t __cdecl _ungetwch(_In_ wint_t _Character); + + _Check_return_ _DCRTIMP wint_t __cdecl _getwch_nolock (void); + _Check_return_ _DCRTIMP wint_t __cdecl _getwche_nolock (void); + _Check_return_opt_ _DCRTIMP wint_t __cdecl _putwch_nolock (_In_ wchar_t _Character); + _Check_return_opt_ _DCRTIMP wint_t __cdecl _ungetwch_nolock(_In_ wint_t _Character); + + + + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + // Wide Character Formatted Output Functions (Console) + // + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + _Check_return_opt_ + _DCRTIMP int __cdecl __conio_common_vcwprintf( + _In_ unsigned __int64 _Options, + _In_z_ _Printf_format_string_params_(2) wchar_t const* _Format, + _In_opt_ _locale_t _Locale, + va_list _ArgList + ); + + _Check_return_opt_ + _DCRTIMP int __cdecl __conio_common_vcwprintf_s( + _In_ unsigned __int64 _Options, + _In_z_ _Printf_format_string_params_(2) wchar_t const* _Format, + _In_opt_ _locale_t _Locale, + va_list _ArgList + ); + + _Check_return_opt_ + _DCRTIMP int __cdecl __conio_common_vcwprintf_p( + _In_ unsigned __int64 _Options, + _In_z_ _Printf_format_string_params_(2) wchar_t const* _Format, + _In_opt_ _locale_t _Locale, + va_list _ArgList + ); + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vcwprintf_l( + _In_z_ _Printf_format_string_params_(2) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + return __conio_common_vcwprintf(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, _Format, _Locale, _ArgList); + } +#endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vcwprintf( + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + va_list _ArgList + ) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + return _vcwprintf_l(_Format, NULL, _ArgList); + } +#endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vcwprintf_s_l( + _In_z_ _Printf_format_string_params_(2) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + return __conio_common_vcwprintf_s(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, _Format, _Locale, _ArgList); + } +#endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vcwprintf_s( + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + va_list _ArgList + ) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + return _vcwprintf_s_l(_Format, NULL, _ArgList); + } +#endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vcwprintf_p_l( + _In_z_ _Printf_format_string_params_(2) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + return __conio_common_vcwprintf_p(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, _Format, _Locale, _ArgList); + } +#endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vcwprintf_p( + _In_z_ _Printf_format_string_ const wchar_t* const _Format, + va_list _ArgList + ) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + return _vcwprintf_p_l(_Format, NULL, _ArgList); + } +#endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _cwprintf_l( + _In_z_ _Printf_format_string_params_(0) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vcwprintf_l(_Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } +#endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _cwprintf( + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + ...) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vcwprintf_l(_Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } +#endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _cwprintf_s_l( + _In_z_ _Printf_format_string_params_(0) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vcwprintf_s_l(_Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } +#endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _cwprintf_s( + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + ...) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vcwprintf_s_l(_Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } +#endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _cwprintf_p_l( + _In_z_ _Printf_format_string_params_(0) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vcwprintf_p_l(_Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } +#endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _cwprintf_p( + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + ...) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vcwprintf_p_l(_Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } +#endif + + + + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + // Wide Character Formatted Input Functions (Console) + // + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + _Check_return_opt_ + _DCRTIMP int __cdecl __conio_common_vcwscanf( + _In_ unsigned __int64 _Options, + _In_z_ _Scanf_format_string_params_(2) wchar_t const* _Format, + _In_opt_ _locale_t _Locale, + va_list _ArgList + ); + + _Check_return_opt_ _CRT_INSECURE_DEPRECATE(_vcwscanf_s_l) + _CRT_STDIO_INLINE int __CRTDECL _vcwscanf_l( + _In_z_ _Scanf_format_string_params_(2) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + return __conio_common_vcwscanf( + _CRT_INTERNAL_LOCAL_SCANF_OPTIONS, + _Format, _Locale, _ArgList); + } +#endif + + _Check_return_opt_ _CRT_INSECURE_DEPRECATE(_vcwscanf_s) + _CRT_STDIO_INLINE int __CRTDECL _vcwscanf( + _In_z_ _Scanf_format_string_params_(1) wchar_t const* const _Format, + va_list _ArgList + ) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + return _vcwscanf_l(_Format, NULL, _ArgList); + } +#endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vcwscanf_s_l( + _In_z_ _Scanf_format_string_params_(2) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + return __conio_common_vcwscanf( + _CRT_INTERNAL_LOCAL_SCANF_OPTIONS | _CRT_INTERNAL_SCANF_SECURECRT, + _Format, _Locale, _ArgList); + } +#endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vcwscanf_s( + _In_z_ _Scanf_format_string_params_(1) wchar_t const* const _Format, + va_list _ArgList + ) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + return _vcwscanf_s_l(_Format, NULL, _ArgList); + } +#endif + + _Check_return_opt_ _CRT_INSECURE_DEPRECATE(_cwscanf_s_l) + _CRT_STDIO_INLINE int __CRTDECL _cwscanf_l( + _In_z_ _Scanf_format_string_params_(0) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + + _Result = _vcwscanf_l(_Format, _Locale, _ArgList); + + __crt_va_end(_ArgList); + return _Result; + } +#endif + + _Check_return_opt_ _CRT_INSECURE_DEPRECATE(_cwscanf_s) + _CRT_STDIO_INLINE int __CRTDECL _cwscanf( + _In_z_ _Scanf_format_string_ wchar_t const* const _Format, + ...) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + + _Result = _vcwscanf_l(_Format, NULL, _ArgList); + + __crt_va_end(_ArgList); + return _Result; + } +#endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _cwscanf_s_l( + _In_z_ _Scanf_format_string_params_(0) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vcwscanf_s_l(_Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } +#endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _cwscanf_s( + _In_z_ _Scanf_format_string_ wchar_t const* const _Format, + ...) +#if defined _NO_CRT_STDIO_INLINE +; +#else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vcwscanf_s_l(_Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } +#endif + +#endif // _CRT_USE_WINAPI_FAMILY_DESKTOP_APP + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS diff --git a/sdk/include/ucrt/corecrt_wctype.h b/sdk/include/ucrt/corecrt_wctype.h new file mode 100644 index 0000000000000..26f1854006885 --- /dev/null +++ b/sdk/include/ucrt/corecrt_wctype.h @@ -0,0 +1,205 @@ +// +// corecrt_wctype.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// This file declares the wide character (wchar_t) classification functionality, +// shared by , , and . +// +#pragma once + +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + + + +#define WEOF ((wint_t)(0xFFFF)) + + + +// This declaration allows the user access to the ctype look-up +// array _ctype defined in ctype.obj by simply including ctype.h +#ifndef _CTYPE_DISABLE_MACROS + + #if defined _CRT_DISABLE_PERFCRIT_LOCKS && !defined _DLL + #define __PCTYPE_FUNC _pctype + #else + #define __PCTYPE_FUNC __pctype_func() + #endif + + _ACRTIMP const unsigned short* __cdecl __pctype_func(void); + _ACRTIMP const wctype_t* __cdecl __pwctype_func(void); + + #ifdef _CRT_DECLARE_GLOBAL_VARIABLES_DIRECTLY + extern const unsigned short* _pctype; + extern const wctype_t* _pwctype; + #else + #define _pctype (__pctype_func()) + #define _pwctype (__pwctype_func()) + #endif +#endif + +// Bit masks for the possible character types +#define _UPPER 0x01 // uppercase letter +#define _LOWER 0x02 // lowercase letter +#define _DIGIT 0x04 // digit[0-9] +#define _SPACE 0x08 // tab, carriage return, newline, vertical tab, or form feed +#define _PUNCT 0x10 // punctuation character +#define _CONTROL 0x20 // control character +#define _BLANK 0x40 // space char (tab is handled separately) +#define _HEX 0x80 // hexadecimal digit + +#define _LEADBYTE 0x8000 // multibyte leadbyte +#define _ALPHA (0x0100 | _UPPER | _LOWER) // alphabetic character + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Wide Character Classification and Conversion Functions +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +_Check_return_ _ACRTIMP int __cdecl iswalnum (_In_ wint_t _C); +_Check_return_ _ACRTIMP int __cdecl iswalpha (_In_ wint_t _C); +_Check_return_ _ACRTIMP int __cdecl iswascii (_In_ wint_t _C); +_Check_return_ _ACRTIMP int __cdecl iswblank (_In_ wint_t _C); +_Check_return_ _ACRTIMP int __cdecl iswcntrl (_In_ wint_t _C); + +_When_(_Param_(1) == 0, _Post_equal_to_(0)) +_Check_return_ _ACRTIMP int __cdecl iswdigit (_In_ wint_t _C); + +_Check_return_ _ACRTIMP int __cdecl iswgraph (_In_ wint_t _C); +_Check_return_ _ACRTIMP int __cdecl iswlower (_In_ wint_t _C); +_Check_return_ _ACRTIMP int __cdecl iswprint (_In_ wint_t _C); +_Check_return_ _ACRTIMP int __cdecl iswpunct (_In_ wint_t _C); +_Check_return_ _ACRTIMP int __cdecl iswspace (_In_ wint_t _C); +_Check_return_ _ACRTIMP int __cdecl iswupper (_In_ wint_t _C); +_Check_return_ _ACRTIMP int __cdecl iswxdigit (_In_ wint_t _C); +_Check_return_ _ACRTIMP int __cdecl __iswcsymf(_In_ wint_t _C); +_Check_return_ _ACRTIMP int __cdecl __iswcsym (_In_ wint_t _C); + +_Check_return_ _ACRTIMP int __cdecl _iswalnum_l (_In_ wint_t _C, _In_opt_ _locale_t _Locale); +_Check_return_ _ACRTIMP int __cdecl _iswalpha_l (_In_ wint_t _C, _In_opt_ _locale_t _Locale); +_Check_return_ _ACRTIMP int __cdecl _iswblank_l (_In_ wint_t _C, _In_opt_ _locale_t _Locale); +_Check_return_ _ACRTIMP int __cdecl _iswcntrl_l (_In_ wint_t _C, _In_opt_ _locale_t _Locale); +_Check_return_ _ACRTIMP int __cdecl _iswdigit_l (_In_ wint_t _C, _In_opt_ _locale_t _Locale); +_Check_return_ _ACRTIMP int __cdecl _iswgraph_l (_In_ wint_t _C, _In_opt_ _locale_t _Locale); +_Check_return_ _ACRTIMP int __cdecl _iswlower_l (_In_ wint_t _C, _In_opt_ _locale_t _Locale); +_Check_return_ _ACRTIMP int __cdecl _iswprint_l (_In_ wint_t _C, _In_opt_ _locale_t _Locale); +_Check_return_ _ACRTIMP int __cdecl _iswpunct_l (_In_ wint_t _C, _In_opt_ _locale_t _Locale); +_Check_return_ _ACRTIMP int __cdecl _iswspace_l (_In_ wint_t _C, _In_opt_ _locale_t _Locale); +_Check_return_ _ACRTIMP int __cdecl _iswupper_l (_In_ wint_t _C, _In_opt_ _locale_t _Locale); +_Check_return_ _ACRTIMP int __cdecl _iswxdigit_l(_In_ wint_t _C, _In_opt_ _locale_t _Locale); +_Check_return_ _ACRTIMP int __cdecl _iswcsymf_l (_In_ wint_t _C, _In_opt_ _locale_t _Locale); +_Check_return_ _ACRTIMP int __cdecl _iswcsym_l (_In_ wint_t _C, _In_opt_ _locale_t _Locale); + + +_Check_return_ _ACRTIMP wint_t __cdecl towupper(_In_ wint_t _C); +_Check_return_ _ACRTIMP wint_t __cdecl towlower(_In_ wint_t _C); +_Check_return_ _ACRTIMP int __cdecl iswctype(_In_ wint_t _C, _In_ wctype_t _Type); + +_Check_return_ _ACRTIMP wint_t __cdecl _towupper_l(_In_ wint_t _C, _In_opt_ _locale_t _Locale); +_Check_return_ _ACRTIMP wint_t __cdecl _towlower_l(_In_ wint_t _C, _In_opt_ _locale_t _Locale); +_Check_return_ _ACRTIMP int __cdecl _iswctype_l(_In_ wint_t _C, _In_ wctype_t _Type, _In_opt_ _locale_t _Locale); + + +#ifdef _CRT_USE_WINAPI_FAMILY_DESKTOP_APP + _Check_return_ _ACRTIMP int __cdecl isleadbyte(_In_ int _C); + _Check_return_ _ACRTIMP int __cdecl _isleadbyte_l(_In_ int _C, _In_opt_ _locale_t _Locale); + + _CRT_OBSOLETE(iswctype) _DCRTIMP int __cdecl is_wctype(_In_ wint_t _C, _In_ wctype_t _Type); +#endif + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Macro and Inline Definitions +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#if !defined __cplusplus || defined _M_CEE_PURE || defined MRTDLL || defined _CORECRT_BUILD + #ifndef _CTYPE_DISABLE_MACROS + + #define iswalpha(_c) (iswctype(_c, _ALPHA)) + #define iswupper(_c) (iswctype(_c, _UPPER)) + #define iswlower(_c) (iswctype(_c, _LOWER)) + #define iswdigit(_c) (iswctype(_c, _DIGIT)) + #define iswxdigit(_c) (iswctype(_c, _HEX)) + #define iswspace(_c) (iswctype(_c, _SPACE)) + #define iswpunct(_c) (iswctype(_c, _PUNCT)) + #define iswblank(_c) (((_c) == '\t') ? _BLANK : iswctype(_c,_BLANK) ) + #define iswalnum(_c) (iswctype(_c, _ALPHA | _DIGIT)) + #define iswprint(_c) (iswctype(_c, _BLANK | _PUNCT | _ALPHA | _DIGIT)) + #define iswgraph(_c) (iswctype(_c, _PUNCT | _ALPHA | _DIGIT)) + #define iswcntrl(_c) (iswctype(_c, _CONTROL)) + #define iswascii(_c) ((unsigned)(_c) < 0x80) + + #define _iswalpha_l(_c,_p) (iswctype(_c, _ALPHA)) + #define _iswupper_l(_c,_p) (iswctype(_c, _UPPER)) + #define _iswlower_l(_c,_p) (iswctype(_c, _LOWER)) + #define _iswdigit_l(_c,_p) (iswctype(_c, _DIGIT)) + #define _iswxdigit_l(_c,_p) (iswctype(_c, _HEX)) + #define _iswspace_l(_c,_p) (iswctype(_c, _SPACE)) + #define _iswpunct_l(_c,_p) (iswctype(_c, _PUNCT)) + #define _iswblank_l(_c,_p) (iswctype(_c, _BLANK)) + #define _iswalnum_l(_c,_p) (iswctype(_c, _ALPHA | _DIGIT)) + #define _iswprint_l(_c,_p) (iswctype(_c, _BLANK | _PUNCT | _ALPHA | _DIGIT)) + #define _iswgraph_l(_c,_p) (iswctype(_c, _PUNCT | _ALPHA | _DIGIT)) + #define _iswcntrl_l(_c,_p) (iswctype(_c, _CONTROL)) + + #ifdef _CRT_USE_WINAPI_FAMILY_DESKTOP_APP + #define isleadbyte(_c) (__PCTYPE_FUNC[(unsigned char)(_c)] & _LEADBYTE) + #endif + + #endif // _CTYPE_DISABLE_MACROS +// CRT_REFACTOR TODO I've had to remove the inline function definitions because +// they break the debugger build. These were moved here from in +// C968560. We need to figure out what is wrong. +//#else +// #ifndef _CTYPE_DISABLE_MACROS +// inline int __cdecl iswalpha (_In_ wint_t _C) { return iswctype(_C, _ALPHA); } +// inline int __cdecl iswupper (_In_ wint_t _C) { return iswctype(_C, _UPPER); } +// inline int __cdecl iswlower (_In_ wint_t _C) { return iswctype(_C, _LOWER); } +// inline int __cdecl iswdigit (_In_ wint_t _C) { return iswctype(_C, _DIGIT); } +// inline int __cdecl iswxdigit(_In_ wint_t _C) { return iswctype(_C, _HEX); } +// inline int __cdecl iswspace (_In_ wint_t _C) { return iswctype(_C, _SPACE); } +// inline int __cdecl iswpunct (_In_ wint_t _C) { return iswctype(_C, _PUNCT); } +// inline int __cdecl iswblank (_In_ wint_t _C) { return (((_C) == '\t') ? _BLANK : iswctype(_C,_BLANK)); } +// inline int __cdecl iswalnum (_In_ wint_t _C) { return iswctype(_C, _ALPHA | _DIGIT); } +// inline int __cdecl iswprint (_In_ wint_t _C) { return iswctype(_C, _BLANK | _PUNCT | _ALPHA | _DIGIT); } +// inline int __cdecl iswgraph (_In_ wint_t _C) { return iswctype(_C, _PUNCT | _ALPHA | _DIGIT); } +// inline int __cdecl iswcntrl (_In_ wint_t _C) { return iswctype(_C, _CONTROL); } +// inline int __cdecl iswascii (_In_ wint_t _C) { return (unsigned)(_C) < 0x80; } +// +// inline int __cdecl _iswalpha_l (_In_ wint_t _C, _In_opt_ _locale_t) { return iswctype(_C, _ALPHA); } +// inline int __cdecl _iswupper_l (_In_ wint_t _C, _In_opt_ _locale_t) { return iswctype(_C, _UPPER); } +// inline int __cdecl _iswlower_l (_In_ wint_t _C, _In_opt_ _locale_t) { return iswctype(_C, _LOWER); } +// inline int __cdecl _iswdigit_l (_In_ wint_t _C, _In_opt_ _locale_t) { return iswctype(_C, _DIGIT); } +// inline int __cdecl _iswxdigit_l(_In_ wint_t _C, _In_opt_ _locale_t) { return iswctype(_C, _HEX); } +// inline int __cdecl _iswspace_l (_In_ wint_t _C, _In_opt_ _locale_t) { return iswctype(_C, _SPACE); } +// inline int __cdecl _iswpunct_l (_In_ wint_t _C, _In_opt_ _locale_t) { return iswctype(_C, _PUNCT); } +// inline int __cdecl _iswblank_l (_In_ wint_t _C, _In_opt_ _locale_t) { return iswctype(_C, _BLANK); } +// inline int __cdecl _iswalnum_l (_In_ wint_t _C, _In_opt_ _locale_t) { return iswctype(_C, _ALPHA | _DIGIT); } +// inline int __cdecl _iswprint_l (_In_ wint_t _C, _In_opt_ _locale_t) { return iswctype(_C, _BLANK | _PUNCT | _ALPHA | _DIGIT); } +// inline int __cdecl _iswgraph_l (_In_ wint_t _C, _In_opt_ _locale_t) { return iswctype(_C, _PUNCT | _ALPHA | _DIGIT); } +// inline int __cdecl _iswcntrl_l (_In_ wint_t _C, _In_opt_ _locale_t) { return iswctype(_C, _CONTROL); } +// +// #ifdef _CRT_USE_WINAPI_FAMILY_DESKTOP_APP +// inline int __cdecl isleadbyte(_In_ int _C) +// { +// return __pctype_func()[(unsigned char)(_C)] & _LEADBYTE; +// } +// #endif +// #endif +#endif + + + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS diff --git a/sdk/include/ucrt/corecrt_wdirect.h b/sdk/include/ucrt/corecrt_wdirect.h new file mode 100644 index 0000000000000..e8b1969ab128d --- /dev/null +++ b/sdk/include/ucrt/corecrt_wdirect.h @@ -0,0 +1,63 @@ +// +// corecrt_wdirect.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// This file declares the wide character (wchar_t) directory functionality, shared +// by and . +// +#pragma once + +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + +#pragma push_macro("_wgetcwd") +#pragma push_macro("_wgetdcwd") +#undef _wgetcwd +#undef _wgetdcwd + +_Success_(return != 0) +_Check_return_ _Ret_maybenull_z_ +_ACRTIMP _CRTALLOCATOR wchar_t* __cdecl _wgetcwd( + _Out_writes_opt_z_(_SizeInWords) wchar_t* _DstBuf, + _In_ int _SizeInWords + ); + +_Success_(return != 0) +_Check_return_ _Ret_maybenull_z_ +_ACRTIMP _CRTALLOCATOR wchar_t* __cdecl _wgetdcwd( + _In_ int _Drive, + _Out_writes_opt_z_(_SizeInWords) wchar_t* _DstBuf, + _In_ int _SizeInWords + ); + +#define _wgetdcwd_nolock _wgetdcwd + +#pragma pop_macro("_wgetcwd") +#pragma pop_macro("_wgetdcwd") + +_Check_return_ +_ACRTIMP int __cdecl _wchdir( + _In_z_ wchar_t const* _Path + ); + +_Check_return_ +_ACRTIMP int __cdecl _wmkdir( + _In_z_ wchar_t const* _Path + ); + +_Check_return_ +_ACRTIMP int __cdecl _wrmdir( + _In_z_ wchar_t const* _Path + ); + + + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS diff --git a/sdk/include/ucrt/corecrt_wio.h b/sdk/include/ucrt/corecrt_wio.h new file mode 100644 index 0000000000000..0196bf663dff0 --- /dev/null +++ b/sdk/include/ucrt/corecrt_wio.h @@ -0,0 +1,270 @@ +// +// corecrt_wio.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// This file declares the wide character (wchar_t) I/O functionality, shared by +// and . +// +#pragma once + +#include +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Types +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#ifdef _USE_32BIT_TIME_T + #define _wfinddata_t _wfinddata32_t + #define _wfinddatai64_t _wfinddata32i64_t +#else + #define _wfinddata_t _wfinddata64i32_t + #define _wfinddatai64_t _wfinddata64_t +#endif + +typedef unsigned long _fsize_t; + +struct _wfinddata32_t +{ + unsigned attrib; + __time32_t time_create; // -1 for FAT file systems + __time32_t time_access; // -1 for FAT file systems + __time32_t time_write; + _fsize_t size; + wchar_t name[260]; +}; + +struct _wfinddata32i64_t +{ + unsigned attrib; + __time32_t time_create; // -1 for FAT file systems + __time32_t time_access; // -1 for FAT file systems + __time32_t time_write; + __int64 size; + wchar_t name[260]; +}; + +struct _wfinddata64i32_t +{ + unsigned attrib; + __time64_t time_create; // -1 for FAT file systems + __time64_t time_access; // -1 for FAT file systems + __time64_t time_write; + _fsize_t size; + wchar_t name[260]; +}; + +struct _wfinddata64_t +{ + unsigned attrib; + __time64_t time_create; // -1 for FAT file systems + __time64_t time_access; // -1 for FAT file systems + __time64_t time_write; + __int64 size; + wchar_t name[260]; +}; + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Functions +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#ifdef _USE_32BIT_TIME_T + #define _wfindfirst _wfindfirst32 + #define _wfindnext _wfindnext32 + #define _wfindfirsti64 _wfindfirst32i64 + #define _wfindnexti64 _wfindnext32i64 +#else + #define _wfindfirst _wfindfirst64i32 + #define _wfindnext _wfindnext64i32 + #define _wfindfirsti64 _wfindfirst64 + #define _wfindnexti64 _wfindnext64 +#endif + +_Check_return_ +_ACRTIMP int __cdecl _waccess( + _In_z_ wchar_t const* _FileName, + _In_ int _AccessMode + ); + +_Check_return_wat_ +_ACRTIMP errno_t __cdecl _waccess_s( + _In_z_ wchar_t const* _FileName, + _In_ int _AccessMode + ); + +_Check_return_ +_ACRTIMP int __cdecl _wchmod( + _In_z_ wchar_t const* _FileName, + _In_ int _Mode + ); + +_Check_return_ _CRT_INSECURE_DEPRECATE(_wsopen_s) +_ACRTIMP int __cdecl _wcreat( + _In_z_ wchar_t const* _FileName, + _In_ int _PermissionMode + ); + +_Success_(return != -1) +_Check_return_ +_ACRTIMP intptr_t __cdecl _wfindfirst32( + _In_z_ wchar_t const* _FileName, + _Out_ struct _wfinddata32_t* _FindData + ); + +_Success_(return != -1) +_Check_return_ +_ACRTIMP int __cdecl _wfindnext32( + _In_ intptr_t _FindHandle, + _Out_ struct _wfinddata32_t* _FindData + ); + +_ACRTIMP int __cdecl _wunlink( + _In_z_ wchar_t const* _FileName + ); + +_Check_return_ +_ACRTIMP int __cdecl _wrename( + _In_z_ wchar_t const* _OldFileName, + _In_z_ wchar_t const* _NewFileName + ); + +_ACRTIMP errno_t __cdecl _wmktemp_s( + _Inout_updates_z_(_SizeInWords) wchar_t* _TemplateName, + _In_ size_t _SizeInWords + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_0( + errno_t, _wmktemp_s, + wchar_t, _TemplateName + ) + +_Success_(return != 0) +__DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_0( + wchar_t*, __RETURN_POLICY_DST, _ACRTIMP, _wmktemp, + _Inout_z_, wchar_t, _TemplateName + ) + +_Success_(return != -1) +_Check_return_ +_ACRTIMP intptr_t __cdecl _wfindfirst32i64( + _In_z_ wchar_t const* _FileName, + _Out_ struct _wfinddata32i64_t* _FindData + ); + +_Success_(return != -1) +_Check_return_ +_ACRTIMP intptr_t __cdecl _wfindfirst64i32( + _In_z_ wchar_t const* _FileName, + _Out_ struct _wfinddata64i32_t* _FindData + ); + +_Success_(return != -1) +_Check_return_ +_ACRTIMP intptr_t __cdecl _wfindfirst64( + _In_z_ wchar_t const* _FileName, + _Out_ struct _wfinddata64_t* _FindData + ); + +_Success_(return != -1) +_Check_return_ +_ACRTIMP int __cdecl _wfindnext32i64( + _In_ intptr_t _FindHandle, + _Out_ struct _wfinddata32i64_t* _FindData + ); + +_Success_(return != -1) +_Check_return_ +_ACRTIMP int __cdecl _wfindnext64i32( + _In_ intptr_t _FindHandle, + _Out_ struct _wfinddata64i32_t* _FindData + ); + +_Success_(return != -1) +_Check_return_ +_ACRTIMP int __cdecl _wfindnext64( + _In_ intptr_t _FindHandle, + _Out_ struct _wfinddata64_t* _FindData + ); + +_Check_return_wat_ +_ACRTIMP errno_t __cdecl _wsopen_s( + _Out_ int* _FileHandle, + _In_z_ wchar_t const* _FileName, + _In_ int _OpenFlag, + _In_ int _ShareFlag, + _In_ int _PermissionFlag + ); + +_ACRTIMP errno_t __cdecl _wsopen_dispatch( + _In_z_ wchar_t const* _FileName, + _In_ int _OFlag, + _In_ int _ShFlag, + _In_ int _PMode, + _Out_ int* _PFileHandle, + _In_ int _BSecure + ); + + + +#if defined __cplusplus + + // These functions do not validate pmode; use _wsopen_s instead. + extern "C++" _Check_return_ _CRT_INSECURE_DEPRECATE(_wsopen_s) + inline int __CRTDECL _wopen( + _In_z_ wchar_t const* _FileName, + _In_ int _OFlag, + _In_ int _PMode = 0 + ) + { + int _FileHandle; + // Last parameter passed as 0 because we don't want to validate pmode from _open + errno_t const _Result = _wsopen_dispatch(_FileName, _OFlag, _SH_DENYNO, _PMode, &_FileHandle, 0); + return _Result ? -1 : _FileHandle; + } + + extern "C++" _Check_return_ _CRT_INSECURE_DEPRECATE(_wsopen_s) + inline int __CRTDECL _wsopen( + _In_z_ wchar_t const* _FileName, + _In_ int _OFlag, + _In_ int _ShFlag, + _In_ int _PMode = 0 + ) + { + int _FileHandle; + // Last parameter passed as 0 because we don't want to validate pmode from _sopen + errno_t const _Result = _wsopen_dispatch(_FileName, _OFlag, _ShFlag, _PMode, &_FileHandle, 0); + return _Result ? -1 : _FileHandle; + } + + +#else + + _Check_return_ _CRT_INSECURE_DEPRECATE(_wsopen_s) + _ACRTIMP int __cdecl _wopen( + _In_z_ wchar_t const* _FileName, + _In_ int _OpenFlag, + ...); + + _Check_return_ _CRT_INSECURE_DEPRECATE(_wsopen_s) + _ACRTIMP int __cdecl _wsopen( + _In_z_ wchar_t const* _FileName, + _In_ int _OpenFlag, + _In_ int _ShareFlag, + ...); + +#endif + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS diff --git a/sdk/include/ucrt/corecrt_wprocess.h b/sdk/include/ucrt/corecrt_wprocess.h new file mode 100644 index 0000000000000..c686da602cd16 --- /dev/null +++ b/sdk/include/ucrt/corecrt_wprocess.h @@ -0,0 +1,127 @@ +// +// corecrt_wprocess.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// This file declares the wide character (wchar_t) process functionality, shared +// by and . +// +#pragma once + +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + + + +#if _CRT_FUNCTIONS_REQUIRED + #ifdef _CRT_USE_WINAPI_FAMILY_DESKTOP_APP + + _DCRTIMP intptr_t __cdecl _wexecl( + _In_z_ wchar_t const* _FileName, + _In_z_ wchar_t const* _ArgList, + ...); + + _DCRTIMP intptr_t __cdecl _wexecle( + _In_z_ wchar_t const* _FileName, + _In_z_ wchar_t const* _ArgList, + ...); + + _DCRTIMP intptr_t __cdecl _wexeclp( + _In_z_ wchar_t const* _FileName, + _In_z_ wchar_t const* _ArgList, + ...); + + _DCRTIMP intptr_t __cdecl _wexeclpe( + _In_z_ wchar_t const* _FileName, + _In_z_ wchar_t const* _ArgList, + ...); + + _DCRTIMP intptr_t __cdecl _wexecv( + _In_z_ wchar_t const* _FileName, + _In_z_ wchar_t const* const* _ArgList + ); + + _DCRTIMP intptr_t __cdecl _wexecve( + _In_z_ wchar_t const* _FileName, + _In_z_ wchar_t const* const* _ArgList, + _In_opt_z_ wchar_t const* const* _Env + ); + + _DCRTIMP intptr_t __cdecl _wexecvp( + _In_z_ wchar_t const* _FileName, + _In_z_ wchar_t const* const* _ArgList + ); + + _DCRTIMP intptr_t __cdecl _wexecvpe( + _In_z_ wchar_t const* _FileName, + _In_z_ wchar_t const* const* _ArgList, + _In_opt_z_ wchar_t const* const* _Env + ); + + _DCRTIMP intptr_t __cdecl _wspawnl( + _In_ int _Mode, + _In_z_ wchar_t const* _FileName, + _In_z_ wchar_t const* _ArgList, + ...); + + _DCRTIMP intptr_t __cdecl _wspawnle( + _In_ int _Mode, + _In_z_ wchar_t const* _FileName, + _In_z_ wchar_t const* _ArgList, + ...); + + _DCRTIMP intptr_t __cdecl _wspawnlp( + _In_ int _Mode, + _In_z_ wchar_t const* _FileName, + _In_z_ wchar_t const* _ArgList, + ...); + + _DCRTIMP intptr_t __cdecl _wspawnlpe( + _In_ int _Mode, + _In_z_ wchar_t const* _FileName, + _In_z_ wchar_t const* _ArgList, + ...); + + _DCRTIMP intptr_t __cdecl _wspawnv( + _In_ int _Mode, + _In_z_ wchar_t const* _FileName, + _In_z_ wchar_t const* const* _ArgList + ); + + _DCRTIMP intptr_t __cdecl _wspawnve( + _In_ int _Mode, + _In_z_ wchar_t const* _FileName, + _In_z_ wchar_t const* const* _ArgList, + _In_opt_z_ wchar_t const* const* _Env + ); + + _DCRTIMP intptr_t __cdecl _wspawnvp( + _In_ int _Mode, + _In_z_ wchar_t const* _FileName, + _In_z_ wchar_t const* const* _ArgList + ); + + _DCRTIMP intptr_t __cdecl _wspawnvpe( + _In_ int _Mode, + _In_z_ wchar_t const* _FileName, + _In_z_ wchar_t const* const* _ArgList, + _In_opt_z_ wchar_t const* const* _Env + ); + + _DCRTIMP int __cdecl _wsystem( + _In_opt_z_ wchar_t const* _Command + ); + + #endif // _CRT_USE_WINAPI_FAMILY_DESKTOP_APP +#endif // _CRT_FUNCTIONS_REQUIRED + + + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS diff --git a/sdk/include/ucrt/corecrt_wstdio.h b/sdk/include/ucrt/corecrt_wstdio.h new file mode 100644 index 0000000000000..bec2554cecc37 --- /dev/null +++ b/sdk/include/ucrt/corecrt_wstdio.h @@ -0,0 +1,2171 @@ +// +// corecrt_wstdio.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// This file declares the wide character (wchar_t) I/O functionality, shared by +// and . It also defines several core I/O types, which are +// also shared by those two headers. +// +#pragma once + +#include +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Stream I/O Declarations Required by this Header +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#ifndef _FILE_DEFINED + #define _FILE_DEFINED + typedef struct _iobuf + { + void* _Placeholder; + } FILE; +#endif + +_ACRTIMP_ALT FILE* __cdecl __acrt_iob_func(unsigned _Ix); + +#define stdin (__acrt_iob_func(0)) +#define stdout (__acrt_iob_func(1)) +#define stderr (__acrt_iob_func(2)) + +#define WEOF ((wint_t)(0xFFFF)) + + + +#if _CRT_FUNCTIONS_REQUIRED + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + // Wide Character Stream I/O Functions + // + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + _Check_return_opt_ + _ACRTIMP wint_t __cdecl fgetwc( + _Inout_ FILE* _Stream + ); + + _Check_return_opt_ + _ACRTIMP wint_t __cdecl _fgetwchar(void); + + _Check_return_opt_ + _ACRTIMP wint_t __cdecl fputwc( + _In_ wchar_t _Character, + _Inout_ FILE* _Stream); + + _Check_return_opt_ + _ACRTIMP wint_t __cdecl _fputwchar( + _In_ wchar_t _Character + ); + + _Check_return_ + _ACRTIMP wint_t __cdecl getwc( + _Inout_ FILE* _Stream + ); + + _Check_return_ + _ACRTIMP wint_t __cdecl getwchar(void); + + + _Check_return_opt_ + _Success_(return == _Buffer) + _ACRTIMP wchar_t* __cdecl fgetws( + _Out_writes_z_(_BufferCount) wchar_t* _Buffer, + _In_ int _BufferCount, + _Inout_ FILE* _Stream + ); + + _Check_return_opt_ + _ACRTIMP int __cdecl fputws( + _In_z_ wchar_t const* _Buffer, + _Inout_ FILE* _Stream + ); + + _Check_return_opt_ + _Success_(return != 0) + _ACRTIMP wchar_t* __cdecl _getws_s( + _Out_writes_z_(_BufferCount) wchar_t* _Buffer, + _In_ size_t _BufferCount + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_0( + _Success_(return != 0) + wchar_t*, _getws_s, + _Always_(_Post_z_) wchar_t, _Buffer + ) + + _Check_return_opt_ + _ACRTIMP wint_t __cdecl putwc( + _In_ wchar_t _Character, + _Inout_ FILE* _Stream + ); + + _Check_return_opt_ + _ACRTIMP wint_t __cdecl putwchar( + _In_ wchar_t _Character + ); + + _Check_return_opt_ + _ACRTIMP int __cdecl _putws( + _In_z_ wchar_t const* _Buffer + ); + + _Check_return_opt_ + _ACRTIMP wint_t __cdecl ungetwc( + _In_ wint_t _Character, + _Inout_ FILE* _Stream + ); + + _Check_return_ + _ACRTIMP FILE * __cdecl _wfdopen( + _In_ int _FileHandle, + _In_z_ wchar_t const* _Mode + ); + + _Check_return_ _CRT_INSECURE_DEPRECATE(_wfopen_s) + _ACRTIMP FILE* __cdecl _wfopen( + _In_z_ wchar_t const* _FileName, + _In_z_ wchar_t const* _Mode + ); + + _Check_return_wat_ + _ACRTIMP errno_t __cdecl _wfopen_s( + _Outptr_result_maybenull_ FILE** _Stream, + _In_z_ wchar_t const* _FileName, + _In_z_ wchar_t const* _Mode + ); + + _Check_return_ + _CRT_INSECURE_DEPRECATE(_wfreopen_s) + _ACRTIMP FILE* __cdecl _wfreopen( + _In_z_ wchar_t const* _FileName, + _In_z_ wchar_t const* _Mode, + _Inout_ FILE* _OldStream + ); + + _Check_return_wat_ + _ACRTIMP errno_t __cdecl _wfreopen_s( + _Outptr_result_maybenull_ FILE** _Stream, + _In_z_ wchar_t const* _FileName, + _In_z_ wchar_t const* _Mode, + _Inout_ FILE* _OldStream + ); + + _Check_return_ + _ACRTIMP FILE* __cdecl _wfsopen( + _In_z_ wchar_t const* _FileName, + _In_z_ wchar_t const* _Mode, + _In_ int _ShFlag + ); + + _ACRTIMP void __cdecl _wperror( + _In_opt_z_ wchar_t const* _ErrorMessage + ); + + #ifdef _CRT_USE_WINAPI_FAMILY_DESKTOP_APP + + _Check_return_ + _DCRTIMP FILE* __cdecl _wpopen( + _In_z_ wchar_t const* _Command, + _In_z_ wchar_t const* _Mode + ); + + #endif + + _ACRTIMP int __cdecl _wremove( + _In_z_ wchar_t const* _FileName + ); + + #pragma push_macro("_wtempnam") + #undef _wtempnam + + _Check_return_ + _ACRTIMP _CRTALLOCATOR wchar_t* __cdecl _wtempnam( + _In_opt_z_ wchar_t const* _Directory, + _In_opt_z_ wchar_t const* _FilePrefix + ); + + #pragma pop_macro("_wtempnam") + + _Success_(return == 0) + _Check_return_wat_ + _ACRTIMP errno_t __cdecl _wtmpnam_s( + _Out_writes_z_(_BufferCount) wchar_t* _Buffer, + _In_ size_t _BufferCount + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_0( + _Success_(return == 0) + errno_t, _wtmpnam_s, + _Always_(_Post_z_) wchar_t, _Buffer + ) + + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_0( + _Success_(return != 0) + wchar_t*, __RETURN_POLICY_DST, _ACRTIMP, _wtmpnam, + _Pre_maybenull_ _Always_(_Post_z_), wchar_t, _Buffer + ) + + + + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + // I/O Synchronization and _nolock family of I/O functions + // + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + _Check_return_opt_ + _ACRTIMP wint_t __cdecl _fgetwc_nolock( + _Inout_ FILE* _Stream + ); + + _Check_return_opt_ + _ACRTIMP wint_t __cdecl _fputwc_nolock( + _In_ wchar_t _Character, + _Inout_ FILE* _Stream + ); + + _Check_return_opt_ + _ACRTIMP wint_t __cdecl _getwc_nolock( + _Inout_ FILE* _Stream + ); + + _Check_return_opt_ + _ACRTIMP wint_t __cdecl _putwc_nolock( + _In_ wchar_t _Character, + _Inout_ FILE* _Stream + ); + + _Check_return_opt_ + _ACRTIMP wint_t __cdecl _ungetwc_nolock( + _In_ wint_t _Character, + _Inout_ FILE* _Stream + ); + + #if defined _CRT_DISABLE_PERFCRIT_LOCKS && !defined _DLL + #define fgetwc(stream) _getwc_nolock(stream) + #define fputwc(c, stream) _putwc_nolock(c, stream) + #define ungetwc(c, stream) _ungetwc_nolock(c, stream) + #endif + + + + // Variadic functions are not supported in managed code under /clr + #ifdef _M_CEE_MIXED + #pragma managed(push, off) + #endif + + + + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + // Wide Character Formatted Output Functions (Stream) + // + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + _Check_return_opt_ + _ACRTIMP int __cdecl __stdio_common_vfwprintf( + _In_ unsigned __int64 _Options, + _Inout_ FILE* _Stream, + _In_z_ _Printf_format_string_params_(2) wchar_t const* _Format, + _In_opt_ _locale_t _Locale, + va_list _ArgList + ); + + _Check_return_opt_ + _ACRTIMP int __cdecl __stdio_common_vfwprintf_s( + _In_ unsigned __int64 _Options, + _Inout_ FILE* _Stream, + _In_z_ _Printf_format_string_params_(2) wchar_t const* _Format, + _In_opt_ _locale_t _Locale, + va_list _ArgList + ); + + _Check_return_opt_ + _ACRTIMP int __cdecl __stdio_common_vfwprintf_p( + _In_ unsigned __int64 _Options, + _Inout_ FILE* _Stream, + _In_z_ _Printf_format_string_params_(2) wchar_t const* _Format, + _In_opt_ _locale_t _Locale, + va_list _ArgList + ); + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vfwprintf_l( + _Inout_ FILE* const _Stream, + _In_z_ _Printf_format_string_params_(2) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return __stdio_common_vfwprintf(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, _Stream, _Format, _Locale, _ArgList); + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL vfwprintf( + _Inout_ FILE* const _Stream, + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vfwprintf_l(_Stream, _Format, NULL, _ArgList); + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vfwprintf_s_l( + _Inout_ FILE* const _Stream, + _In_z_ _Printf_format_string_params_(2) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return __stdio_common_vfwprintf_s(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, _Stream, _Format, _Locale, _ArgList); + } + #endif + + #if __STDC_WANT_SECURE_LIB__ + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL vfwprintf_s( + _Inout_ FILE* const _Stream, + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vfwprintf_s_l(_Stream, _Format, NULL, _ArgList); + } + #endif + + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vfwprintf_p_l( + _Inout_ FILE* const _Stream, + _In_z_ _Printf_format_string_params_(2) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return __stdio_common_vfwprintf_p(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, _Stream, _Format, _Locale, _ArgList); + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vfwprintf_p( + _Inout_ FILE* const _Stream, + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vfwprintf_p_l(_Stream, _Format, NULL, _ArgList); + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vwprintf_l( + _In_z_ _Printf_format_string_params_(2) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vfwprintf_l(stdout, _Format, _Locale, _ArgList); + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL vwprintf( + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vfwprintf_l(stdout, _Format, NULL, _ArgList); + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vwprintf_s_l( + _In_z_ _Printf_format_string_params_(2) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vfwprintf_s_l(stdout, _Format, _Locale, _ArgList); + } + #endif + + #if __STDC_WANT_SECURE_LIB__ + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL vwprintf_s( + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vfwprintf_s_l(stdout, _Format, NULL, _ArgList); + } + #endif + + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vwprintf_p_l( + _In_z_ _Printf_format_string_params_(2) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vfwprintf_p_l(stdout, _Format, _Locale, _ArgList); + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vwprintf_p( + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vfwprintf_p_l(stdout, _Format, NULL, _ArgList); + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _fwprintf_l( + _Inout_ FILE* const _Stream, + _In_z_ _Printf_format_string_params_(0) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vfwprintf_l(_Stream, _Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL fwprintf( + _Inout_ FILE* const _Stream, + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vfwprintf_l(_Stream, _Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _fwprintf_s_l( + _Inout_ FILE* const _Stream, + _In_z_ _Printf_format_string_params_(0) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vfwprintf_s_l(_Stream, _Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + #if __STDC_WANT_SECURE_LIB__ + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL fwprintf_s( + _Inout_ FILE* const _Stream, + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vfwprintf_s_l(_Stream, _Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _fwprintf_p_l( + _Inout_ FILE* const _Stream, + _In_z_ _Printf_format_string_params_(0) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vfwprintf_p_l(_Stream, _Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _fwprintf_p( + _Inout_ FILE* const _Stream, + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vfwprintf_p_l(_Stream, _Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _wprintf_l( + _In_z_ _Printf_format_string_params_(0) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vfwprintf_l(stdout, _Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL wprintf( + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vfwprintf_l(stdout, _Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _wprintf_s_l( + _In_z_ _Printf_format_string_params_(0) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vfwprintf_s_l(stdout, _Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + #if __STDC_WANT_SECURE_LIB__ + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL wprintf_s( + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vfwprintf_s_l(stdout, _Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _wprintf_p_l( + _In_z_ _Printf_format_string_params_(0) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vfwprintf_p_l(stdout, _Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _wprintf_p( + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vfwprintf_p_l(stdout, _Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + // Wide Character Formatted Input Functions (Stream) + // + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + _Check_return_opt_ + _ACRTIMP int __cdecl __stdio_common_vfwscanf( + _In_ unsigned __int64 _Options, + _Inout_ FILE* _Stream, + _In_z_ _Scanf_format_string_params_(2) wchar_t const* _Format, + _In_opt_ _locale_t _Locale, + va_list _ArgList + ); + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vfwscanf_l( + _Inout_ FILE* const _Stream, + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return __stdio_common_vfwscanf( + _CRT_INTERNAL_LOCAL_SCANF_OPTIONS, + _Stream, _Format, _Locale, _ArgList); + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL vfwscanf( + _Inout_ FILE* const _Stream, + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vfwscanf_l(_Stream, _Format, NULL, _ArgList); + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vfwscanf_s_l( + _Inout_ FILE* const _Stream, + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return __stdio_common_vfwscanf( + _CRT_INTERNAL_LOCAL_SCANF_OPTIONS | _CRT_INTERNAL_SCANF_SECURECRT, + _Stream, _Format, _Locale, _ArgList); + } + #endif + + #if __STDC_WANT_SECURE_LIB__ + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL vfwscanf_s( + _Inout_ FILE* const _Stream, + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vfwscanf_s_l(_Stream, _Format, NULL, _ArgList); + } + #endif + + #endif + + _CRT_STDIO_INLINE int __CRTDECL _vwscanf_l( + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vfwscanf_l(stdin, _Format, _Locale, _ArgList); + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL vwscanf( + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vfwscanf_l(stdin, _Format, NULL, _ArgList); + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vwscanf_s_l( + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vfwscanf_s_l(stdin, _Format, _Locale, _ArgList); + } + #endif + + #if __STDC_WANT_SECURE_LIB__ + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL vwscanf_s( + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vfwscanf_s_l(stdin, _Format, NULL, _ArgList); + } + #endif + + #endif + + _Check_return_opt_ _CRT_INSECURE_DEPRECATE(_fwscanf_s_l) + _CRT_STDIO_INLINE int __CRTDECL _fwscanf_l( + _Inout_ FILE* const _Stream, + _In_z_ _Scanf_format_string_params_(0) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE // SCANF + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vfwscanf_l(_Stream, _Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Check_return_ _CRT_INSECURE_DEPRECATE(fwscanf_s) + _CRT_STDIO_INLINE int __CRTDECL fwscanf( + _Inout_ FILE* const _Stream, + _In_z_ _Scanf_format_string_ wchar_t const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE // SCANF + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vfwscanf_l(_Stream, _Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _fwscanf_s_l( + _Inout_ FILE* const _Stream, + _In_z_ _Scanf_s_format_string_params_(0) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE // SCANF + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vfwscanf_s_l(_Stream, _Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + #if __STDC_WANT_SECURE_LIB__ + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL fwscanf_s( + _Inout_ FILE* const _Stream, + _In_z_ _Scanf_s_format_string_ wchar_t const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE // SCANF + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vfwscanf_s_l(_Stream, _Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + #endif + + _Check_return_opt_ _CRT_INSECURE_DEPRECATE(_wscanf_s_l) + _CRT_STDIO_INLINE int __CRTDECL _wscanf_l( + _In_z_ _Scanf_format_string_params_(0) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE // SCANF + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vfwscanf_l(stdin, _Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Check_return_ _CRT_INSECURE_DEPRECATE(wscanf_s) + _CRT_STDIO_INLINE int __CRTDECL wscanf( + _In_z_ _Scanf_format_string_ wchar_t const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE // SCANF + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vfwscanf_l(stdin, _Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _wscanf_s_l( + _In_z_ _Scanf_s_format_string_params_(0) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE // SCANF + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vfwscanf_s_l(stdin, _Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + #if __STDC_WANT_SECURE_LIB__ + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL wscanf_s( + _In_z_ _Scanf_s_format_string_ wchar_t const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE // SCANF + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vfwscanf_s_l(stdin, _Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + #endif + + + + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + // Wide Character Formatted Output Functions (String) + // + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + #ifndef _CRT_NON_CONFORMING_SWPRINTFS + #define _SWPRINTFS_DEPRECATED _CRT_DEPRECATE_TEXT( \ + "function has been changed to conform with the ISO C standard, " \ + "adding an extra character count parameter. To use the traditional " \ + "Microsoft version, set _CRT_NON_CONFORMING_SWPRINTFS.") + #else + #define _SWPRINTFS_DEPRECATED + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _ACRTIMP int __cdecl __stdio_common_vswprintf( + _In_ unsigned __int64 _Options, + _Out_writes_opt_z_(_BufferCount) wchar_t* _Buffer, + _In_ size_t _BufferCount, + _In_z_ _Printf_format_string_params_(2) wchar_t const* _Format, + _In_opt_ _locale_t _Locale, + va_list _ArgList + ); + + _Success_(return >= 0) + _Check_return_opt_ + _ACRTIMP int __cdecl __stdio_common_vswprintf_s( + _In_ unsigned __int64 _Options, + _Out_writes_z_(_BufferCount) wchar_t* _Buffer, + _In_ size_t _BufferCount, + _In_z_ _Printf_format_string_params_(2) wchar_t const* _Format, + _In_opt_ _locale_t _Locale, + va_list _ArgList + ); + + _Success_(return >= 0) + _Check_return_opt_ + _ACRTIMP int __cdecl __stdio_common_vsnwprintf_s( + _In_ unsigned __int64 _Options, + _Out_writes_opt_z_(_BufferCount) wchar_t* _Buffer, + _In_ size_t _BufferCount, + _In_ size_t _MaxCount, + _In_z_ _Printf_format_string_params_(2) wchar_t const* _Format, + _In_opt_ _locale_t _Locale, + va_list _ArgList + ); + + _Success_(return >= 0) + _Check_return_opt_ + _ACRTIMP int __cdecl __stdio_common_vswprintf_p( + _In_ unsigned __int64 _Options, + _Out_writes_z_(_BufferCount) wchar_t* _Buffer, + _In_ size_t _BufferCount, + _In_z_ _Printf_format_string_params_(2) wchar_t const* _Format, + _In_opt_ _locale_t _Locale, + va_list _ArgList + ); + + _Success_(return >= 0) + _Check_return_opt_ _CRT_INSECURE_DEPRECATE(_vsnwprintf_s_l) + _CRT_STDIO_INLINE int __CRTDECL _vsnwprintf_l( + _Out_writes_opt_(_BufferCount) _Post_maybez_ wchar_t* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Printf_format_string_params_(2) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int const _Result = __stdio_common_vswprintf( + _CRT_INTERNAL_LOCAL_PRINTF_OPTIONS | _CRT_INTERNAL_PRINTF_LEGACY_VSPRINTF_NULL_TERMINATION, + _Buffer, _BufferCount, _Format, _Locale, _ArgList); + + return _Result < 0 ? -1 : _Result; + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vsnwprintf_s_l( + _Out_writes_opt_(_BufferCount) _Always_(_Post_z_) wchar_t* const _Buffer, + _In_ size_t const _BufferCount, + _In_ size_t const _MaxCount, + _In_z_ _Printf_format_string_params_(2) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int const _Result = __stdio_common_vsnwprintf_s( + _CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, + _Buffer, _BufferCount, _MaxCount, _Format, _Locale, _ArgList); + + return _Result < 0 ? -1 : _Result; + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vsnwprintf_s( + _Out_writes_opt_(_BufferCount) _Always_(_Post_z_) wchar_t* const _Buffer, + _In_ size_t const _BufferCount, + _In_ size_t const _MaxCount, + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vsnwprintf_s_l(_Buffer, _BufferCount, _MaxCount, _Format, NULL, _ArgList); + } + #endif + + __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2_ARGLIST_EX( + _Success_(return >= 0) + int, __RETURN_POLICY_SAME, _CRT_STDIO_INLINE, __CRTDECL, _snwprintf, _vsnwprintf, + _Pre_notnull_ _Post_maybez_ wchar_t, + _Out_writes_opt_(_BufferCount) _Post_maybez_, wchar_t, _Buffer, + _In_ size_t, _BufferCount, + _In_z_ _Printf_format_string_ wchar_t const*, _Format + ) + + _Success_(return >= 0) + _Check_return_opt_ _CRT_INSECURE_DEPRECATE(_vsnwprintf_s) + _CRT_STDIO_INLINE int __CRTDECL _vsnwprintf( + _Out_writes_opt_(_BufferCount) _Post_maybez_ wchar_t* _Buffer, + _In_ size_t _BufferCount, + _In_z_ _Printf_format_string_ wchar_t const* _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vsnwprintf_l(_Buffer, _BufferCount, _Format, NULL, _ArgList); + } + #endif + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_3( + _Success_(return >= 0) + int, _vsnwprintf_s, + _Always_(_Post_z_) wchar_t, _Buffer, + _In_ size_t, _BufferCount, + _In_z_ _Printf_format_string_ wchar_t const*, _Format, + va_list, _ArgList + ) + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vswprintf_c_l( + _Out_writes_opt_(_BufferCount) _Always_(_Post_z_) wchar_t* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Printf_format_string_params_(2) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int const _Result = __stdio_common_vswprintf( + _CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, + _Buffer, _BufferCount, _Format, _Locale, _ArgList); + + return _Result < 0 ? -1 : _Result; + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vswprintf_c( + _Out_writes_opt_(_BufferCount) _Always_(_Post_z_) wchar_t* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vswprintf_c_l(_Buffer, _BufferCount, _Format, NULL, _ArgList); + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vswprintf_l( + _Out_writes_opt_(_BufferCount) _Always_(_Post_z_) wchar_t* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Printf_format_string_params_(2) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vswprintf_c_l(_Buffer, _BufferCount, _Format, _Locale, _ArgList); + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL __vswprintf_l( + _Pre_notnull_ _Always_(_Post_z_) wchar_t* const _Buffer, + _In_z_ _Printf_format_string_params_(2) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vswprintf_l(_Buffer, (size_t)-1, _Format, _Locale, _ArgList); + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vswprintf( + _Pre_notnull_ _Always_(_Post_z_) wchar_t* const _Buffer, + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vswprintf_l(_Buffer, (size_t)-1, _Format, NULL, _ArgList); + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL vswprintf( + _Out_writes_opt_(_BufferCount) _Always_(_Post_z_) wchar_t* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Printf_format_string_params_(1) wchar_t const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vswprintf_c_l(_Buffer, _BufferCount, _Format, NULL, _ArgList); + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vswprintf_s_l( + _Out_writes_(_BufferCount) _Always_(_Post_z_) wchar_t* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Printf_format_string_params_(2) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int const _Result = __stdio_common_vswprintf_s( + _CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, + _Buffer, _BufferCount, _Format, _Locale, _ArgList); + + return _Result < 0 ? -1 : _Result; + } + #endif + + #if __STDC_WANT_SECURE_LIB__ + + _Success_(return >= 0) + _CRT_STDIO_INLINE int __CRTDECL vswprintf_s( + _Out_writes_(_BufferCount) _Always_(_Post_z_) wchar_t* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vswprintf_s_l(_Buffer, _BufferCount, _Format, NULL, _ArgList); + } + #endif + + #endif + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2( + _Success_(return >= 0) + int, vswprintf_s, + _Always_(_Post_z_) wchar_t, _Buffer, + _In_z_ _Printf_format_string_ wchar_t const*, _Format, + va_list, _ArgList + ) + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vswprintf_p_l( + _Out_writes_(_BufferCount) _Always_(_Post_z_) wchar_t* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Printf_format_string_params_(2) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int const _Result = __stdio_common_vswprintf_p( + _CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, + _Buffer, _BufferCount, _Format, _Locale, _ArgList); + + return _Result < 0 ? -1 : _Result; + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vswprintf_p( + _Out_writes_(_BufferCount) _Always_(_Post_z_) wchar_t* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vswprintf_p_l(_Buffer, _BufferCount, _Format, NULL, _ArgList); + } + #endif + + _Success_(return >= 0) + _Check_return_ + _CRT_STDIO_INLINE int __CRTDECL _vscwprintf_l( + _In_z_ _Printf_format_string_params_(2) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int const _Result = __stdio_common_vswprintf( + _CRT_INTERNAL_LOCAL_PRINTF_OPTIONS | _CRT_INTERNAL_PRINTF_STANDARD_SNPRINTF_BEHAVIOR, + NULL, 0, _Format, _Locale, _ArgList); + + return _Result < 0 ? -1 : _Result; + } + #endif + + _Success_(return >= 0) + _Check_return_ + _CRT_STDIO_INLINE int __CRTDECL _vscwprintf( + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vscwprintf_l(_Format, NULL, _ArgList); + } + #endif + + _Success_(return >= 0) + _Check_return_ + _CRT_STDIO_INLINE int __CRTDECL _vscwprintf_p_l( + _In_z_ _Printf_format_string_params_(2) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int const _Result = __stdio_common_vswprintf_p( + _CRT_INTERNAL_LOCAL_PRINTF_OPTIONS | _CRT_INTERNAL_PRINTF_STANDARD_SNPRINTF_BEHAVIOR, + NULL, 0, _Format, _Locale, _ArgList); + + return _Result < 0 ? -1 : _Result; + } + #endif + + _Success_(return >= 0) + _Check_return_ + _CRT_STDIO_INLINE int __CRTDECL _vscwprintf_p( + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vscwprintf_p_l(_Format, NULL, _ArgList); + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL __swprintf_l( + _Pre_notnull_ _Always_(_Post_z_) wchar_t* const _Buffer, + _In_z_ _Printf_format_string_params_(2) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = __vswprintf_l(_Buffer, _Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _swprintf_l( + _Out_writes_opt_(_BufferCount) _Always_(_Post_z_) wchar_t* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Printf_format_string_params_(0) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vswprintf_c_l(_Buffer, _BufferCount, _Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _swprintf( + _Pre_notnull_ _Always_(_Post_z_) wchar_t* const _Buffer, + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = __vswprintf_l(_Buffer, _Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL swprintf( + _Out_writes_opt_(_BufferCount) _Always_(_Post_z_) wchar_t* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vswprintf_c_l(_Buffer, _BufferCount, _Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_2_ARGLIST_EX( + _Success_(return >= 0) + int, __RETURN_POLICY_SAME, _CRT_STDIO_INLINE, __CRTDECL, __swprintf_l, __vswprintf_l, _vswprintf_s_l, + _Pre_notnull_ _Always_(_Post_z_) wchar_t, + _Pre_notnull_ _Always_(_Post_z_), wchar_t, _Buffer, + _In_z_ _Printf_format_string_params_(2) wchar_t const*, _Format, + _In_opt_ _locale_t, _Locale + ) + + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1_ARGLIST_EX( + _Success_(return >= 0) + int, __RETURN_POLICY_SAME, _CRT_STDIO_INLINE, __CRTDECL, _swprintf, swprintf_s, _vswprintf, vswprintf_s, + _Pre_notnull_ _Always_(_Post_z_), wchar_t, _Buffer, + _In_z_ _Printf_format_string_ wchar_t const*, _Format + ) + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _swprintf_s_l( + _Out_writes_(_BufferCount) _Always_(_Post_z_) wchar_t* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Printf_format_string_params_(0) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vswprintf_s_l(_Buffer, _BufferCount, _Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + #if __STDC_WANT_SECURE_LIB__ + + _Success_(return >= 0) + _CRT_STDIO_INLINE int __CRTDECL swprintf_s( + _Out_writes_(_BufferCount) _Always_(_Post_z_) wchar_t* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vswprintf_s_l(_Buffer, _BufferCount, _Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + #endif + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1_ARGLIST( + _Success_(return >= 0) + int, swprintf_s, vswprintf_s, + _Always_(_Post_z_) wchar_t, _Buffer, + _In_z_ _Printf_format_string_ wchar_t const*, _Format + ) + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _swprintf_p_l( + _Out_writes_(_BufferCount) _Always_(_Post_z_) wchar_t* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Printf_format_string_params_(0) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vswprintf_p_l(_Buffer, _BufferCount, _Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _swprintf_p( + _Out_writes_(_BufferCount) _Always_(_Post_z_) wchar_t* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vswprintf_p_l(_Buffer, _BufferCount, _Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _swprintf_c_l( + _Out_writes_opt_(_BufferCount) _Always_(_Post_z_) wchar_t* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Printf_format_string_params_(0) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vswprintf_c_l(_Buffer, _BufferCount, _Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _swprintf_c( + _Out_writes_opt_(_BufferCount) _Always_(_Post_z_) wchar_t* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vswprintf_c_l(_Buffer, _BufferCount, _Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ _CRT_INSECURE_DEPRECATE(_snwprintf_s_l) + _CRT_STDIO_INLINE int __CRTDECL _snwprintf_l( + _Out_writes_opt_(_BufferCount) _Post_maybez_ wchar_t* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Printf_format_string_params_(0) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + + _Result = _vsnwprintf_l(_Buffer, _BufferCount, _Format, _Locale, _ArgList); + + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _snwprintf( + _Out_writes_opt_(_BufferCount) _Post_maybez_ wchar_t* _Buffer, + _In_ size_t _BufferCount, + _In_z_ _Printf_format_string_ wchar_t const* _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + + _Result = _vsnwprintf_l(_Buffer, _BufferCount, _Format, NULL, _ArgList); + + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _snwprintf_s_l( + _Out_writes_opt_(_BufferCount) _Always_(_Post_z_) wchar_t* const _Buffer, + _In_ size_t const _BufferCount, + _In_ size_t const _MaxCount, + _In_z_ _Printf_format_string_params_(0) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vsnwprintf_s_l(_Buffer, _BufferCount, _MaxCount, _Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _snwprintf_s( + _Out_writes_opt_(_BufferCount) _Always_(_Post_z_) wchar_t* const _Buffer, + _In_ size_t const _BufferCount, + _In_ size_t const _MaxCount, + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vsnwprintf_s_l(_Buffer, _BufferCount, _MaxCount, _Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2_ARGLIST( + _Success_(return >= 0) + int, _snwprintf_s, _vsnwprintf_s, + _Always_(_Post_z_) wchar_t, _Buffer, + _In_ size_t, _BufferCount, + _In_z_ _Printf_format_string_ wchar_t const*, _Format + ) + + _Check_return_ + _CRT_STDIO_INLINE int __CRTDECL _scwprintf_l( + _In_z_ _Printf_format_string_params_(0) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vscwprintf_l(_Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Success_(return >= 0) + _Check_return_ + _CRT_STDIO_INLINE int __CRTDECL _scwprintf( + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vscwprintf_l(_Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Success_(return >= 0) + _Check_return_ + _CRT_STDIO_INLINE int __CRTDECL _scwprintf_p_l( + _In_z_ _Printf_format_string_params_(0) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vscwprintf_p_l(_Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Success_(return >= 0) + _Check_return_ + _CRT_STDIO_INLINE int __CRTDECL _scwprintf_p( + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vscwprintf_p_l(_Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + + #if !defined RC_INVOKED && !defined __midl && !defined _INC_SWPRINTF_INL_ + // C4141: double deprecation + // C6054: string may not be zero-terminated + #pragma warning(push) + #pragma warning(disable: 4141 6054) + + #ifdef __cplusplus + + extern "C++" _SWPRINTFS_DEPRECATED _CRT_INSECURE_DEPRECATE(swprintf_s) + inline int swprintf( + _Pre_notnull_ _Post_z_ wchar_t* const _Buffer, + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + ...) throw() + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = vswprintf(_Buffer, _CRT_INT_MAX, _Format, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + + extern "C++" _SWPRINTFS_DEPRECATED _CRT_INSECURE_DEPRECATE(vswprintf_s) + inline int __CRTDECL vswprintf( + _Pre_notnull_ _Post_z_ wchar_t* const _Buffer, + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + va_list _ArgList + ) throw() + { + return vswprintf(_Buffer, _CRT_INT_MAX, _Format, _ArgList); + } + + extern "C++" _SWPRINTFS_DEPRECATED _CRT_INSECURE_DEPRECATE(_swprintf_s_l) + inline int _swprintf_l( + _Pre_notnull_ _Post_z_ wchar_t* const _Buffer, + _In_z_ _Printf_format_string_params_(0) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) throw() + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vswprintf_l(_Buffer, (size_t)-1, _Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + + extern "C++" _SWPRINTFS_DEPRECATED _CRT_INSECURE_DEPRECATE(_vswprintf_s_l) + inline int __CRTDECL _vswprintf_l( + _Pre_notnull_ _Post_z_ wchar_t* const _Buffer, + _In_z_ _Printf_format_string_params_(2) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) throw() + { + return _vswprintf_l(_Buffer, (size_t)-1, _Format, _Locale, _ArgList); + } + + #endif // __cplusplus + + #pragma warning(pop) + #endif // !_INC_SWPRINTF_INL_ + + #if defined _CRT_NON_CONFORMING_SWPRINTFS && !defined __cplusplus + #define swprintf _swprintf + #define vswprintf _vswprintf + #define _swprintf_l __swprintf_l + #define _vswprintf_l __vswprintf_l + #endif + + + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + // Wide Character Formatted Input Functions (String) + // + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + _Success_(return >= 0) + _ACRTIMP int __cdecl __stdio_common_vswscanf( + _In_ unsigned __int64 _Options, + _In_reads_(_BufferCount) _Pre_z_ wchar_t const* _Buffer, + _In_ size_t _BufferCount, + _In_z_ _Scanf_format_string_params_(2) wchar_t const* _Format, + _In_opt_ _locale_t _Locale, + va_list _ArgList + ); + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vswscanf_l( + _In_z_ wchar_t const* const _Buffer, + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return __stdio_common_vswscanf( + _CRT_INTERNAL_LOCAL_SCANF_OPTIONS, + _Buffer, (size_t)-1, _Format, _Locale, _ArgList); + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL vswscanf( + _In_z_ wchar_t const* _Buffer, + _In_z_ _Printf_format_string_ wchar_t const* _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vswscanf_l(_Buffer, _Format, NULL, _ArgList); + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vswscanf_s_l( + _In_z_ wchar_t const* const _Buffer, + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return __stdio_common_vswscanf( + _CRT_INTERNAL_LOCAL_SCANF_OPTIONS | _CRT_INTERNAL_SCANF_SECURECRT, + _Buffer, (size_t)-1, _Format, _Locale, _ArgList); + } + #endif + + #if __STDC_WANT_SECURE_LIB__ + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL vswscanf_s( + _In_z_ wchar_t const* const _Buffer, + _In_z_ _Printf_format_string_ wchar_t const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vswscanf_s_l(_Buffer, _Format, NULL, _ArgList); + } + #endif + + #endif + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2( + _Success_(return >= 0) + int, vswscanf_s, + _In_z_ wchar_t, _Buffer, + _In_z_ _Printf_format_string_ wchar_t const*, _Format, + va_list, _ArgList + ) + + _Success_(return >= 0) + _Check_return_opt_ _CRT_INSECURE_DEPRECATE(_vsnwscanf_s_l) + _CRT_STDIO_INLINE int __CRTDECL _vsnwscanf_l( + _In_reads_(_BufferCount) _Pre_z_ wchar_t const* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Scanf_format_string_params_(2) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return __stdio_common_vswscanf( + _CRT_INTERNAL_LOCAL_SCANF_OPTIONS, + _Buffer, _BufferCount, _Format, _Locale, _ArgList); + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vsnwscanf_s_l( + _In_reads_(_BufferCount) _Pre_z_ wchar_t const* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Scanf_s_format_string_params_(2) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return __stdio_common_vswscanf( + _CRT_INTERNAL_LOCAL_SCANF_OPTIONS | _CRT_INTERNAL_SCANF_SECURECRT, + _Buffer, _BufferCount, _Format, _Locale, _ArgList); + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ _CRT_INSECURE_DEPRECATE(_swscanf_s_l) + _CRT_STDIO_INLINE int __CRTDECL _swscanf_l( + _In_z_ wchar_t const* const _Buffer, + _In_z_ _Scanf_format_string_params_(0) wchar_t const* const _Format, + _In_opt_ _locale_t _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE // SCANF + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vswscanf_l(_Buffer, _Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Success_(return >= 0) + _Check_return_ _CRT_INSECURE_DEPRECATE(swscanf_s) + _CRT_STDIO_INLINE int __CRTDECL swscanf( + _In_z_ wchar_t const* const _Buffer, + _In_z_ _Scanf_format_string_ wchar_t const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE // SCANF + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vswscanf_l(_Buffer, _Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _swscanf_s_l( + _In_z_ wchar_t const* const _Buffer, + _In_z_ _Scanf_s_format_string_params_(0) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE // SCANF + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vswscanf_s_l(_Buffer, _Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + #if __STDC_WANT_SECURE_LIB__ + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL swscanf_s( + _In_z_ wchar_t const* const _Buffer, + _In_z_ _Scanf_s_format_string_ wchar_t const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE // SCANF + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vswscanf_s_l(_Buffer, _Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + #endif + + _Success_(return >= 0) + _Check_return_opt_ _CRT_INSECURE_DEPRECATE(_snwscanf_s_l) + _CRT_STDIO_INLINE int __CRTDECL _snwscanf_l( + _In_reads_(_BufferCount) _Pre_z_ wchar_t const* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Scanf_format_string_params_(0) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE // SCANF + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + + _Result = _vsnwscanf_l(_Buffer, _BufferCount, _Format, _Locale, _ArgList); + + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ _CRT_INSECURE_DEPRECATE(_snwscanf_s) + _CRT_STDIO_INLINE int __CRTDECL _snwscanf( + _In_reads_(_BufferCount) _Pre_z_ wchar_t const* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Scanf_format_string_ wchar_t const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE // SCANF + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + + _Result = _vsnwscanf_l(_Buffer, _BufferCount, _Format, NULL, _ArgList); + + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _snwscanf_s_l( + _In_reads_(_BufferCount) _Pre_z_ wchar_t const* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Scanf_s_format_string_params_(0) wchar_t const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE // SCANF + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vsnwscanf_s_l(_Buffer, _BufferCount, _Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _snwscanf_s( + _In_reads_(_BufferCount) _Pre_z_ wchar_t const* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Scanf_s_format_string_ wchar_t const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE // SCANF + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vsnwscanf_s_l(_Buffer, _BufferCount, _Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + #ifdef _M_CEE_MIXED + #pragma managed(pop) + #endif +#endif // _CRT_FUNCTIONS_REQUIRED + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS diff --git a/sdk/include/ucrt/corecrt_wstdlib.h b/sdk/include/ucrt/corecrt_wstdlib.h new file mode 100644 index 0000000000000..755db3639067b --- /dev/null +++ b/sdk/include/ucrt/corecrt_wstdlib.h @@ -0,0 +1,481 @@ +// +// corecrt_wstdlib.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// This file declares the wide character (wchar_t) C Standard Library functions +// that are declared by both and . +// +#pragma once + +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + + + +// Maximum number of elements, including null terminator (and negative sign +// where appropriate), needed for integer-to-string conversions for several +// bases and integer types. +#define _MAX_ITOSTR_BASE16_COUNT (8 + 1) +#define _MAX_ITOSTR_BASE10_COUNT (1 + 10 + 1) +#define _MAX_ITOSTR_BASE8_COUNT (11 + 1) +#define _MAX_ITOSTR_BASE2_COUNT (32 + 1) + +#define _MAX_LTOSTR_BASE16_COUNT (8 + 1) +#define _MAX_LTOSTR_BASE10_COUNT (1 + 10 + 1) +#define _MAX_LTOSTR_BASE8_COUNT (11 + 1) +#define _MAX_LTOSTR_BASE2_COUNT (32 + 1) + +#define _MAX_ULTOSTR_BASE16_COUNT (8 + 1) +#define _MAX_ULTOSTR_BASE10_COUNT (10 + 1) +#define _MAX_ULTOSTR_BASE8_COUNT (11 + 1) +#define _MAX_ULTOSTR_BASE2_COUNT (32 + 1) + +#define _MAX_I64TOSTR_BASE16_COUNT (16 + 1) +#define _MAX_I64TOSTR_BASE10_COUNT (1 + 19 + 1) +#define _MAX_I64TOSTR_BASE8_COUNT (22 + 1) +#define _MAX_I64TOSTR_BASE2_COUNT (64 + 1) + +#define _MAX_U64TOSTR_BASE16_COUNT (16 + 1) +#define _MAX_U64TOSTR_BASE10_COUNT (20 + 1) +#define _MAX_U64TOSTR_BASE8_COUNT (22 + 1) +#define _MAX_U64TOSTR_BASE2_COUNT (64 + 1) + + +#if _CRT_FUNCTIONS_REQUIRED + + _Success_(return == 0) + _Check_return_wat_ + _ACRTIMP errno_t __cdecl _itow_s( + _In_ int _Value, + _Out_writes_z_(_BufferCount) wchar_t* _Buffer, + _In_ size_t _BufferCount, + _In_ int _Radix + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_1_1( + errno_t, _itow_s, + _In_ int, _Value, + wchar_t, _Buffer, + _In_ int, _Radix + ) + + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_1_1( + wchar_t*, __RETURN_POLICY_DST, _ACRTIMP, _itow, + _In_ int, _Value, + _Pre_notnull_ _Post_z_, wchar_t, _Buffer, + _In_ int, _Radix + ) + + _Success_(return == 0) + _Check_return_wat_ + _ACRTIMP errno_t __cdecl _ltow_s( + _In_ long _Value, + _Out_writes_z_(_BufferCount) wchar_t* _Buffer, + _In_ size_t _BufferCount, + _In_ int _Radix + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_1_1( + errno_t, _ltow_s, + _In_ long, _Value, + wchar_t, _Buffer, + _In_ int, _Radix + ) + + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_1_1( + wchar_t*, __RETURN_POLICY_DST, _ACRTIMP, _ltow, + _In_ long, _Value, + _Pre_notnull_ _Post_z_, wchar_t, _Buffer, + _In_ int, _Radix + ) + + _Check_return_wat_ + _ACRTIMP errno_t __cdecl _ultow_s( + _In_ unsigned long _Value, + _Out_writes_z_(_BufferCount) wchar_t* _Buffer, + _In_ size_t _BufferCount, + _In_ int _Radix + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_1_1( + errno_t, _ultow_s, + _In_ unsigned long, _Value, + wchar_t, _Buffer, + _In_ int, _Radix + ) + + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_1_1( + wchar_t*, __RETURN_POLICY_DST, _ACRTIMP, _ultow, + _In_ unsigned long, _Value, + _Pre_notnull_ _Post_z_, wchar_t, _Buffer, + _In_ int, _Radix + ) + + _Check_return_ + _ACRTIMP double __cdecl wcstod( + _In_z_ wchar_t const* _String, + _Out_opt_ _Deref_post_z_ wchar_t** _EndPtr + ); + + _Check_return_ + _ACRTIMP double __cdecl _wcstod_l( + _In_z_ wchar_t const* _String, + _Out_opt_ _Deref_post_z_ wchar_t** _EndPtr, + _In_opt_ _locale_t _Locale + ); + + _Check_return_ + _ACRTIMP long __cdecl wcstol( + _In_z_ wchar_t const* _String, + _Out_opt_ _Deref_post_z_ wchar_t** _EndPtr, + _In_ int _Radix + ); + + _Check_return_ + _ACRTIMP long __cdecl _wcstol_l( + _In_z_ wchar_t const* _String, + _Out_opt_ _Deref_post_z_ wchar_t** _EndPtr, + _In_ int _Radix, + _In_opt_ _locale_t _Locale + ); + + _Check_return_ + _ACRTIMP long long __cdecl wcstoll( + _In_z_ wchar_t const* _String, + _Out_opt_ _Deref_post_z_ wchar_t** _EndPtr, + _In_ int _Radix + ); + + _Check_return_ + _ACRTIMP long long __cdecl _wcstoll_l( + _In_z_ wchar_t const* _String, + _Out_opt_ _Deref_post_z_ wchar_t** _EndPtr, + _In_ int _Radix, + _In_opt_ _locale_t _Locale + ); + + _Check_return_ + _ACRTIMP unsigned long __cdecl wcstoul( + _In_z_ wchar_t const* _String, + _Out_opt_ _Deref_post_z_ wchar_t** _EndPtr, + _In_ int _Radix + ); + + _Check_return_ + _ACRTIMP unsigned long __cdecl _wcstoul_l( + _In_z_ wchar_t const* _String, + _Out_opt_ _Deref_post_z_ wchar_t** _EndPtr, + _In_ int _Radix, + _In_opt_ _locale_t _Locale + ); + + _Check_return_ + _ACRTIMP unsigned long long __cdecl wcstoull( + _In_z_ wchar_t const* _String, + _Out_opt_ _Deref_post_z_ wchar_t** _EndPtr, + _In_ int _Radix + ); + + _Check_return_ + _ACRTIMP unsigned long long __cdecl _wcstoull_l( + _In_z_ wchar_t const* _String, + _Out_opt_ _Deref_post_z_ wchar_t** _EndPtr, + _In_ int _Radix, + _In_opt_ _locale_t _Locale + ); + + _Check_return_ + _ACRTIMP long double __cdecl wcstold( + _In_z_ wchar_t const* _String, + _Out_opt_ _Deref_post_z_ wchar_t** _EndPtr + ); + + _Check_return_ + _ACRTIMP long double __cdecl _wcstold_l( + _In_z_ wchar_t const* _String, + _Out_opt_ _Deref_post_z_ wchar_t** _EndPtr, + _In_opt_ _locale_t _Locale + ); + + _Check_return_ + _ACRTIMP float __cdecl wcstof( + _In_z_ wchar_t const* _String, + _Out_opt_ _Deref_post_z_ wchar_t** _EndPtr + ); + + _Check_return_ + _ACRTIMP float __cdecl _wcstof_l( + _In_z_ wchar_t const* _String, + _Out_opt_ _Deref_post_z_ wchar_t** _EndPtr, + _In_opt_ _locale_t _Locale + ); + + _Check_return_ + _ACRTIMP double __cdecl _wtof( + _In_z_ wchar_t const* _String + ); + + _Check_return_ + _ACRTIMP double __cdecl _wtof_l( + _In_z_ wchar_t const* _String, + _In_opt_ _locale_t _Locale + ); + + _Check_return_ + _ACRTIMP int __cdecl _wtoi( + _In_z_ wchar_t const* _String + ); + + _Check_return_ + _ACRTIMP int __cdecl _wtoi_l( + _In_z_ wchar_t const* _String, + _In_opt_ _locale_t _Locale + ); + + _Check_return_ + _ACRTIMP long __cdecl _wtol( + _In_z_ wchar_t const* _String + ); + + _Check_return_ + _ACRTIMP long __cdecl _wtol_l( + _In_z_ wchar_t const* _String, + _In_opt_ _locale_t _Locale + ); + + _Check_return_ + _ACRTIMP long long __cdecl _wtoll( + _In_z_ wchar_t const* _String + ); + + _Check_return_ + _ACRTIMP long long __cdecl _wtoll_l( + _In_z_ wchar_t const* _String, + _In_opt_ _locale_t _Locale + ); + + _Check_return_wat_ + _ACRTIMP errno_t __cdecl _i64tow_s( + _In_ __int64 _Value, + _Out_writes_z_(_BufferCount) wchar_t* _Buffer, + _In_ size_t _BufferCount, + _In_ int _Radix + ); + + _CRT_INSECURE_DEPRECATE(_i64tow_s) + _ACRTIMP wchar_t* __cdecl _i64tow( + _In_ __int64 _Value, + _Pre_notnull_ _Post_z_ wchar_t* _Buffer, + _In_ int _Radix + ); + + _Check_return_wat_ + _ACRTIMP errno_t __cdecl _ui64tow_s( + _In_ unsigned __int64 _Value, + _Out_writes_z_(_BufferCount) wchar_t* _Buffer, + _In_ size_t _BufferCount, + _In_ int _Radix + ); + + _CRT_INSECURE_DEPRECATE(_ui64tow_s) + _ACRTIMP wchar_t* __cdecl _ui64tow( + _In_ unsigned __int64 _Value, + _Pre_notnull_ _Post_z_ wchar_t* _Buffer, + _In_ int _Radix + ); + + _Check_return_ + _ACRTIMP __int64 __cdecl _wtoi64( + _In_z_ wchar_t const* _String + ); + + _Check_return_ + _ACRTIMP __int64 __cdecl _wtoi64_l( + _In_z_ wchar_t const* _String, + _In_opt_ _locale_t _Locale + ); + + _Check_return_ + _ACRTIMP __int64 __cdecl _wcstoi64( + _In_z_ wchar_t const* _String, + _Out_opt_ _Deref_post_z_ wchar_t** _EndPtr, + _In_ int _Radix + ); + + _Check_return_ + _ACRTIMP __int64 __cdecl _wcstoi64_l( + _In_z_ wchar_t const* _String, + _Out_opt_ _Deref_post_z_ wchar_t** _EndPtr, + _In_ int _Radix, + _In_opt_ _locale_t _Locale + ); + + _Check_return_ + _ACRTIMP unsigned __int64 __cdecl _wcstoui64( + _In_z_ wchar_t const* _String, + _Out_opt_ _Deref_post_z_ wchar_t** _EndPtr, + _In_ int _Radix + ); + + _Check_return_ + _ACRTIMP unsigned __int64 __cdecl _wcstoui64_l( + _In_z_ wchar_t const* _String, + _Out_opt_ _Deref_post_z_ wchar_t** _EndPtr, + _In_ int _Radix, + _In_opt_ _locale_t _Locale + ); + + #pragma push_macro("_wfullpath") + #undef _wfullpath + + _Success_(return != 0) + _Check_return_ + _ACRTIMP _CRTALLOCATOR wchar_t* __cdecl _wfullpath( + _Out_writes_opt_z_(_BufferCount) wchar_t* _Buffer, + _In_z_ wchar_t const* _Path, + _In_ size_t _BufferCount + ); + + #pragma pop_macro("_wfullpath") + + _Check_return_wat_ + _ACRTIMP errno_t __cdecl _wmakepath_s( + _Out_writes_z_(_BufferCount) wchar_t* _Buffer, + _In_ size_t _BufferCount, + _In_opt_z_ wchar_t const* _Drive, + _In_opt_z_ wchar_t const* _Dir, + _In_opt_z_ wchar_t const* _Filename, + _In_opt_z_ wchar_t const* _Ext + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_4( + errno_t, _wmakepath_s, + wchar_t, _Buffer, + _In_opt_z_ wchar_t const*, _Drive, + _In_opt_z_ wchar_t const*, _Dir, + _In_opt_z_ wchar_t const*, _Filename, + _In_opt_z_ wchar_t const*, _Ext + ) + +__DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_4( + void, __RETURN_POLICY_VOID, _ACRTIMP, _wmakepath, + _Pre_notnull_ _Post_z_, wchar_t, _Buffer, + _In_opt_z_ wchar_t const*, _Drive, + _In_opt_z_ wchar_t const*, _Dir, + _In_opt_z_ wchar_t const*, _Filename, + _In_opt_z_ wchar_t const*, _Ext + ) + + _ACRTIMP void __cdecl _wperror( + _In_opt_z_ wchar_t const* _ErrorMessage + ); + + _CRT_INSECURE_DEPRECATE(_wsplitpath_s) + _ACRTIMP void __cdecl _wsplitpath( + _In_z_ wchar_t const* _FullPath, + _Pre_maybenull_ _Post_z_ wchar_t* _Drive, + _Pre_maybenull_ _Post_z_ wchar_t* _Dir, + _Pre_maybenull_ _Post_z_ wchar_t* _Filename, + _Pre_maybenull_ _Post_z_ wchar_t* _Ext + ); + + _ACRTIMP errno_t __cdecl _wsplitpath_s( + _In_z_ wchar_t const* _FullPath, + _Out_writes_opt_z_(_DriveCount) wchar_t* _Drive, + _In_ size_t _DriveCount, + _Out_writes_opt_z_(_DirCount) wchar_t* _Dir, + _In_ size_t _DirCount, + _Out_writes_opt_z_(_FilenameCount) wchar_t* _Filename, + _In_ size_t _FilenameCount, + _Out_writes_opt_z_(_ExtCount) wchar_t* _Ext, + _In_ size_t _ExtCount + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_SPLITPATH( + errno_t, _wsplitpath_s, + wchar_t, _Path + ) + + #pragma push_macro("_wdupenv_s") + #undef _wdupenv_s + + _Check_return_wat_ + _DCRTIMP errno_t __cdecl _wdupenv_s( + _Outptr_result_buffer_maybenull_(*_BufferCount) _Outptr_result_maybenull_z_ wchar_t** _Buffer, + _Out_opt_ size_t* _BufferCount, + _In_z_ wchar_t const* _VarName + ); + + #pragma pop_macro("_wdupenv_s") + + _Check_return_ _CRT_INSECURE_DEPRECATE(_wdupenv_s) + _DCRTIMP wchar_t* __cdecl _wgetenv( + _In_z_ wchar_t const* _VarName + ); + + _Success_(return == 0) + _Check_return_wat_ + _DCRTIMP errno_t __cdecl _wgetenv_s( + _Out_ size_t* _RequiredCount, + _Out_writes_opt_z_(_BufferCount) wchar_t* _Buffer, + _In_ size_t _BufferCount, + _In_z_ wchar_t const* _VarName + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_1_1( + _Success_(return == 0) + errno_t, _wgetenv_s, + _Out_ size_t*, _RequiredCount, + wchar_t, _Buffer, + _In_z_ wchar_t const*, _VarName + ) + + _Check_return_ + _DCRTIMP int __cdecl _wputenv( + _In_z_ wchar_t const* _EnvString + ); + + _Check_return_wat_ + _DCRTIMP errno_t __cdecl _wputenv_s( + _In_z_ wchar_t const* _Name, + _In_z_ wchar_t const* _Value + ); + + _DCRTIMP errno_t __cdecl _wsearchenv_s( + _In_z_ wchar_t const* _Filename, + _In_z_ wchar_t const* _VarName, + _Out_writes_z_(_BufferCount) wchar_t* _Buffer, + _In_ size_t _BufferCount + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_2_0( + errno_t, _wsearchenv_s, + _In_z_ wchar_t const*, _Filename, + _In_z_ wchar_t const*, _VarName, + wchar_t, _ResultPath + ) + + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_2_0( + void, __RETURN_POLICY_VOID, _DCRTIMP, _wsearchenv, + _In_z_ wchar_t const*, _Filename, + _In_z_ wchar_t const*, _VarName, + _Pre_notnull_ _Post_z_, wchar_t, _ResultPath + ) + + _DCRTIMP int __cdecl _wsystem( + _In_opt_z_ wchar_t const* _Command + ); + +#endif // _CRT_FUNCTIONS_REQUIRED + + + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS diff --git a/sdk/include/ucrt/corecrt_wstring.h b/sdk/include/ucrt/corecrt_wstring.h new file mode 100644 index 0000000000000..4865eacb8a344 --- /dev/null +++ b/sdk/include/ucrt/corecrt_wstring.h @@ -0,0 +1,641 @@ +// +// corecrt_wstring.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// This file declares the wide character (wchar_t) string functionality, shared +// by and . +// +#pragma once + +#include +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +#ifndef __midl + +_CRT_BEGIN_C_HEADER + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Secure Alternatives +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#if __STDC_WANT_SECURE_LIB__ + + _Check_return_wat_ + _ACRTIMP errno_t __cdecl wcscat_s( + _Inout_updates_z_(_SizeInWords) wchar_t* _Destination, + _In_ rsize_t _SizeInWords, + _In_z_ wchar_t const* _Source + ); + + _Check_return_wat_ + _ACRTIMP errno_t __cdecl wcscpy_s( + _Out_writes_z_(_SizeInWords) wchar_t* _Destination, + _In_ rsize_t _SizeInWords, + _In_z_ wchar_t const* _Source + ); + + _Check_return_wat_ + _ACRTIMP errno_t __cdecl wcsncat_s( + _Inout_updates_z_(_SizeInWords) wchar_t* _Destination, + _In_ rsize_t _SizeInWords, + _In_reads_or_z_(_MaxCount) wchar_t const* _Source, + _In_ rsize_t _MaxCount + ); + + _Check_return_wat_ + _ACRTIMP errno_t __cdecl wcsncpy_s( + _Out_writes_z_(_SizeInWords) wchar_t* _Destination, + _In_ rsize_t _SizeInWords, + _In_reads_or_z_(_MaxCount) wchar_t const* _Source, + _In_ rsize_t _MaxCount + ); + + _Check_return_ + _ACRTIMP wchar_t* __cdecl wcstok_s( + _Inout_opt_z_ wchar_t* _String, + _In_z_ wchar_t const* _Delimiter, + _Inout_ _Deref_prepost_opt_z_ wchar_t** _Context + ); + +#endif // __STDC_WANT_SECURE_LIB__ + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Wide-Character Functions +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#if defined _DEBUG && defined _CRTDBG_MAP_ALLOC + #pragma push_macro("_wcsdup") + #undef _wcsdup +#endif + +_Check_return_ +_ACRTIMP _CRTALLOCATOR wchar_t* __cdecl _wcsdup( + _In_z_ wchar_t const* _String + ); + +#if defined _DEBUG && defined _CRTDBG_MAP_ALLOC + #pragma pop_macro("_wcsdup") +#endif + + + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1( + errno_t, wcscat_s, + wchar_t, _Destination, + _In_z_ wchar_t const*, _Source + ) + +#ifndef RC_INVOKED + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1( + wchar_t*, __RETURN_POLICY_DST, _ACRTIMP, wcscat, + _Inout_updates_z_(_String_length_(_Destination) + _String_length_(_Source) + 1), wchar_t, _Destination, + _In_z_ wchar_t const*, _Source + ) +#endif + +_Check_return_ +_ACRTIMP int __cdecl wcscmp( + _In_z_ wchar_t const* _String1, + _In_z_ wchar_t const* _String2 + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1( + errno_t, wcscpy_s, + wchar_t, _Destination, + _In_z_ wchar_t const*, _Source + ) + +__DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1( + wchar_t*, __RETURN_POLICY_DST, _ACRTIMP, wcscpy, + _Out_writes_z_(_String_length_(_Source) + 1), wchar_t, _Destination, + _In_z_ wchar_t const*, _Source + ) + +_Check_return_ +_ACRTIMP size_t __cdecl wcscspn( + _In_z_ wchar_t const* _String, + _In_z_ wchar_t const* _Control + ); + +_Check_return_ +_ACRTIMP size_t __cdecl wcslen( + _In_z_ wchar_t const* _String + ); + +_Check_return_ +_When_( + _MaxCount > _String_length_(_Source), + _Post_satisfies_(return == _String_length_(_Source)) +) +_When_( + _MaxCount <= _String_length_(_Source), + _Post_satisfies_(return == _MaxCount) +) +_ACRTIMP size_t __cdecl wcsnlen( + _In_reads_or_z_(_MaxCount) wchar_t const* _Source, + _In_ size_t _MaxCount + ); + +#if __STDC_WANT_SECURE_LIB__ && !defined(__midl) + + _Check_return_ + _When_( + _MaxCount > _String_length_(_Source), + _Post_satisfies_(return == _String_length_(_Source)) + ) + _When_( + _MaxCount <= _String_length_(_Source), + _Post_satisfies_(return == _MaxCount) + ) + static __inline size_t __CRTDECL wcsnlen_s( + _In_reads_or_z_(_MaxCount) wchar_t const* _Source, + _In_ size_t _MaxCount + ) + { + return (_Source == 0) ? 0 : wcsnlen(_Source, _MaxCount); + } + +#endif // __STDC_WANT_SECURE_LIB__ && !defined(__midl) + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2( + errno_t, wcsncat_s, + _Prepost_z_ wchar_t, _Destination, + _In_reads_or_z_(_Count) wchar_t const*, _Source, + _In_ size_t, _Count + ) + +__DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2_EX( + wchar_t*, __RETURN_POLICY_DST, _ACRTIMP, wcsncat, wcsncat_s, + _Inout_updates_z_(_Size) wchar_t, + _Inout_updates_z_(_Count), wchar_t, _Destination, + _In_reads_or_z_(_Count) wchar_t const*, _Source, + _In_ size_t, _Count + ) + +_Check_return_ +_ACRTIMP int __cdecl wcsncmp( + _In_reads_or_z_(_MaxCount) wchar_t const* _String1, + _In_reads_or_z_(_MaxCount) wchar_t const* _String2, + _In_ size_t _MaxCount + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2( + errno_t, wcsncpy_s, + wchar_t, _Destination, + _In_reads_or_z_(_Count) wchar_t const*, _Source, + _In_ size_t, _Count + ) + +__DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2_EX( + wchar_t*, __RETURN_POLICY_DST, _ACRTIMP, wcsncpy, wcsncpy_s, + _Pre_notnull_ _Post_maybez_ wchar_t, + _Out_writes_(_Count) _Post_maybez_, wchar_t, _Destination, + _In_reads_or_z_(_Count) wchar_t const*, _Source, + _In_ size_t, _Count + ) + +_Check_return_ +_ACRTIMP wchar_t _CONST_RETURN* __cdecl wcspbrk( + _In_z_ wchar_t const* _String, + _In_z_ wchar_t const* _Control + ); + +_Check_return_ +_ACRTIMP size_t __cdecl wcsspn( + _In_z_ wchar_t const* _String, + _In_z_ wchar_t const* _Control + ); + +_Check_return_ _CRT_INSECURE_DEPRECATE(wcstok_s) +_ACRTIMP wchar_t* __cdecl wcstok( + _Inout_opt_z_ wchar_t* _String, + _In_z_ wchar_t const* _Delimiter, + _Inout_opt_ _Deref_prepost_opt_z_ wchar_t** _Context + ); + +#if !defined RC_INVOKED && !defined __midl + + #if defined _CRT_NON_CONFORMING_WCSTOK + #define _WCSTOK_DEPRECATED _CRT_INSECURE_DEPRECATE(wcstok_s) + #else + #define _WCSTOK_DEPRECATED _CRT_DEPRECATE_TEXT( \ + "wcstok has been changed to conform with the ISO C standard, " \ + "adding an extra context parameter. To use the legacy Microsoft " \ + "wcstok, define _CRT_NON_CONFORMING_WCSTOK.") + #endif + + _Check_return_ _CRT_INSECURE_DEPRECATE(wcstok_s) + static __inline wchar_t* __CRTDECL _wcstok( + _Inout_opt_z_ wchar_t* const _String, + _In_z_ wchar_t const* const _Delimiter + ) + { + return wcstok(_String, _Delimiter, 0); + } + + #if defined _CRT_NON_CONFORMING_WCSTOK && !defined __cplusplus + #define wcstok _wcstok + #endif + + #if defined __cplusplus && !defined _CRT_NO_INLINE_DEPRECATED_WCSTOK + extern "C++" _Check_return_ _WCSTOK_DEPRECATED + inline wchar_t* __CRTDECL wcstok( + _Inout_opt_z_ wchar_t* _String, + _In_z_ wchar_t const* _Delimiter + ) throw() + { + return wcstok(_String, _Delimiter, 0); + } + #endif + +#endif // !defined RC_INVOKED && !defined __midl + + + +_Ret_z_ +_Check_return_ _CRT_INSECURE_DEPRECATE(_wcserror_s) +_ACRTIMP wchar_t* __cdecl _wcserror( + _In_ int _ErrorNumber + ); + +_Check_return_wat_ +_ACRTIMP errno_t __cdecl _wcserror_s( + _Out_writes_opt_z_(_SizeInWords) wchar_t* _Buffer, + _In_ size_t _SizeInWords, + _In_ int _ErrorNumber + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1( + errno_t, _wcserror_s, + wchar_t, _Buffer, + _In_ int, _Error + ) + +_Ret_z_ +_Success_(return != 0) +_Check_return_ _CRT_INSECURE_DEPRECATE(__wcserror_s) +_ACRTIMP wchar_t* __cdecl __wcserror( + _In_opt_z_ wchar_t const* _String + ); + +_Check_return_wat_ _ACRTIMP_ALT errno_t __cdecl __wcserror_s( + _Out_writes_opt_z_(_SizeInWords) wchar_t* _Buffer, + _In_ size_t _SizeInWords, + _In_z_ wchar_t const* _ErrorMessage + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1( + errno_t, __wcserror_s, + wchar_t, _Buffer, + _In_z_ wchar_t const*, _ErrorMessage + ) + +_Check_return_ _ACRTIMP int __cdecl _wcsicmp( + _In_z_ wchar_t const* _String1, + _In_z_ wchar_t const* _String2 + ); + +_Check_return_ _ACRTIMP int __cdecl _wcsicmp_l( + _In_z_ wchar_t const* _String1, + _In_z_ wchar_t const* _String2, + _In_opt_ _locale_t _Locale + ); + +_Check_return_ _ACRTIMP int __cdecl _wcsnicmp( + _In_reads_or_z_(_MaxCount) wchar_t const* _String1, + _In_reads_or_z_(_MaxCount) wchar_t const* _String2, + _In_ size_t _MaxCount + ); + +_Check_return_ _ACRTIMP int __cdecl _wcsnicmp_l( + _In_reads_or_z_(_MaxCount) wchar_t const* _String1, + _In_reads_or_z_(_MaxCount) wchar_t const* _String2, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale + ); + +_Check_return_wat_ _ACRTIMP errno_t __cdecl _wcsnset_s( + _Inout_updates_z_(_SizeInWords) wchar_t* _Destination, + _In_ size_t _SizeInWords, + _In_ wchar_t _Value, + _In_ size_t _MaxCount + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2( + errno_t, _wcsnset_s, + _Prepost_z_ wchar_t, _Destination, + _In_ wchar_t, _Value, + _In_ size_t, _MaxCount + ) + +__DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2_EX( + wchar_t*, __RETURN_POLICY_DST, _ACRTIMP, _wcsnset, _wcsnset_s, + _Inout_updates_z_(_Size) wchar_t, + _Inout_updates_z_(_MaxCount), wchar_t, _String, + _In_ wchar_t, _Value, + _In_ size_t, _MaxCount + ) + +_ACRTIMP wchar_t* __cdecl _wcsrev( + _Inout_z_ wchar_t* _String + ); + +_Check_return_wat_ _ACRTIMP errno_t __cdecl _wcsset_s( + _Inout_updates_z_(_SizeInWords) wchar_t* _Destination, + _In_ size_t _SizeInWords, + _In_ wchar_t _Value + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1( + errno_t, _wcsset_s, + _Prepost_z_ wchar_t, _String, + _In_ wchar_t, _Value + ) + +__DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1_EX( + wchar_t*, __RETURN_POLICY_DST, _ACRTIMP, _wcsset, _wcsset_s, + _Inout_updates_z_(_Size) wchar_t, + _Inout_z_, wchar_t, _String, + _In_ wchar_t, _Value + ) + +_Check_return_wat_ _ACRTIMP errno_t __cdecl _wcslwr_s( + _Inout_updates_z_(_SizeInWords) wchar_t* _String, + _In_ size_t _SizeInWords + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_0( + errno_t, _wcslwr_s, + _Prepost_z_ wchar_t, _String + ) + +__DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_0( + wchar_t*, __RETURN_POLICY_DST, _ACRTIMP, _wcslwr, + _Inout_z_, wchar_t, _String + ) + +_Check_return_wat_ +_ACRTIMP errno_t __cdecl _wcslwr_s_l( + _Inout_updates_z_(_SizeInWords) wchar_t* _String, + _In_ size_t _SizeInWords, + _In_opt_ _locale_t _Locale + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1( + errno_t, _wcslwr_s_l, + _Prepost_z_ wchar_t, _String, + _In_opt_ _locale_t, _Locale + ) + +__DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1_EX( + wchar_t*, __RETURN_POLICY_DST, _ACRTIMP, _wcslwr_l, _wcslwr_s_l, + _Inout_updates_z_(_Size) wchar_t, + _Inout_z_, wchar_t, _String, + _In_opt_ _locale_t, _Locale + ) + +_Check_return_wat_ +_ACRTIMP errno_t __cdecl _wcsupr_s( + _Inout_updates_z_(_Size) wchar_t* _String, + _In_ size_t _Size + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_0( + errno_t, _wcsupr_s, + _Prepost_z_ wchar_t, _String + ) + +__DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_0( + wchar_t*, __RETURN_POLICY_DST, _ACRTIMP, _wcsupr, + _Inout_z_, wchar_t, _String + ) + +_Check_return_wat_ +_ACRTIMP errno_t __cdecl _wcsupr_s_l( + _Inout_updates_z_(_Size) wchar_t* _String, + _In_ size_t _Size, + _In_opt_ _locale_t _Locale + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1( + errno_t, _wcsupr_s_l, + _Prepost_z_ wchar_t, _String, + _In_opt_ _locale_t, _Locale + ) + +__DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1_EX( + wchar_t*, __RETURN_POLICY_DST, _ACRTIMP, _wcsupr_l, _wcsupr_s_l, + _Inout_updates_z_(_Size) wchar_t, + _Inout_z_, wchar_t, _String, + _In_opt_ _locale_t, _Locale + ) + +_Success_(return < _MaxCount) +_Check_return_opt_ +_ACRTIMP size_t __cdecl wcsxfrm( + _Out_writes_opt_(_MaxCount) _Post_maybez_ wchar_t* _Destination, + _In_z_ wchar_t const* _Source, + _In_ _In_range_(<= ,_CRT_INT_MAX) size_t _MaxCount + ); + +_Success_(return < _MaxCount) +_Check_return_opt_ +_ACRTIMP size_t __cdecl _wcsxfrm_l( + _Out_writes_opt_(_MaxCount) _Post_maybez_ wchar_t* _Destination, + _In_z_ wchar_t const* _Source, + _In_ _In_range_(<= ,_CRT_INT_MAX) size_t _MaxCount, + _In_opt_ _locale_t _Locale + ); + +_Check_return_ +_ACRTIMP int __cdecl wcscoll( + _In_z_ wchar_t const* _String1, + _In_z_ wchar_t const* _String2 + ); + +_Check_return_ +_ACRTIMP int __cdecl _wcscoll_l( + _In_z_ wchar_t const* _String1, + _In_z_ wchar_t const* _String2, + _In_opt_ _locale_t _Locale + ); + +_Check_return_ +_ACRTIMP int __cdecl _wcsicoll( + _In_z_ wchar_t const* _String1, + _In_z_ wchar_t const* _String2 + ); + +_Check_return_ +_ACRTIMP int __cdecl _wcsicoll_l( + _In_z_ wchar_t const* _String1, + _In_z_ wchar_t const* _String2, + _In_opt_ _locale_t _Locale + ); + +_Check_return_ +_ACRTIMP int __cdecl _wcsncoll( + _In_reads_or_z_(_MaxCount) wchar_t const* _String1, + _In_reads_or_z_(_MaxCount) wchar_t const* _String2, + _In_ size_t _MaxCount + ); + +_Check_return_ +_ACRTIMP int __cdecl _wcsncoll_l( + _In_reads_or_z_(_MaxCount) wchar_t const* _String1, + _In_reads_or_z_(_MaxCount) wchar_t const* _String2, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale + ); + +_Check_return_ +_ACRTIMP int __cdecl _wcsnicoll( + _In_reads_or_z_(_MaxCount) wchar_t const* _String1, + _In_reads_or_z_(_MaxCount) wchar_t const* _String2, + _In_ size_t _MaxCount + ); + +_Check_return_ +_ACRTIMP int __cdecl _wcsnicoll_l( + _In_reads_or_z_(_MaxCount) wchar_t const* _String1, + _In_reads_or_z_(_MaxCount) wchar_t const* _String2, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale + ); + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Inline C++ Overloads +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#ifdef __cplusplus +extern "C++" { + + _Check_return_ + _When_(return != NULL, _Ret_range_(_String, _String+_String_length_(_String)-1)) + inline wchar_t* __CRTDECL wcschr(_In_z_ wchar_t* _String, wchar_t _C) + { + return const_cast(wcschr(static_cast(_String), _C)); + } + + _Check_return_ + inline wchar_t* __CRTDECL wcspbrk(_In_z_ wchar_t* _String, _In_z_ wchar_t const* _Control) + { + return const_cast(wcspbrk(static_cast(_String), _Control)); + } + + _Check_return_ + inline wchar_t* __CRTDECL wcsrchr(_In_z_ wchar_t* _String, _In_ wchar_t _C) + { + return const_cast(wcsrchr(static_cast(_String), _C)); + } + + _Check_return_ _Ret_maybenull_ + _When_(return != NULL, _Ret_range_(_String, _String+_String_length_(_String)-1)) + inline wchar_t* __CRTDECL wcsstr(_In_z_ wchar_t* _String, _In_z_ wchar_t const*_SubStr) + { + return const_cast(wcsstr(static_cast(_String), _SubStr)); + } + +} +#endif // __cplusplus + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Non-Standard Names +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#if defined(_CRT_INTERNAL_NONSTDC_NAMES) && _CRT_INTERNAL_NONSTDC_NAMES + #if defined _DEBUG && defined _CRTDBG_MAP_ALLOC + #pragma push_macro("wcsdup") + #undef wcsdup + #endif + + _Check_return_ _CRT_NONSTDC_DEPRECATE(_wcsdup) + _ACRTIMP wchar_t* __cdecl wcsdup( + _In_z_ wchar_t const* _String + ); + + #if defined _DEBUG && defined _CRTDBG_MAP_ALLOC + #pragma pop_macro("wcsdup") + #endif + + // Declarations of functions defined in oldnames.lib: + #define wcswcs wcsstr + + _Check_return_ _CRT_NONSTDC_DEPRECATE(_wcsicmp) + _ACRTIMP int __cdecl wcsicmp( + _In_z_ wchar_t const* _String1, + _In_z_ wchar_t const* _String2 + ); + + _Check_return_ _CRT_NONSTDC_DEPRECATE(_wcsnicmp) + _ACRTIMP int __cdecl wcsnicmp( + _In_reads_or_z_(_MaxCount) wchar_t const* _String1, + _In_reads_or_z_(_MaxCount) wchar_t const* _String2, + _In_ size_t _MaxCount + ); + + _CRT_NONSTDC_DEPRECATE(_wcsnset) + _Ret_z_ + _ACRTIMP wchar_t* __cdecl wcsnset( + _Inout_updates_z_(_MaxCount) wchar_t* _String, + _In_ wchar_t _Value, + _In_ size_t _MaxCount + ); + + _CRT_NONSTDC_DEPRECATE(_wcsrev) + _Ret_z_ + _ACRTIMP wchar_t* __cdecl wcsrev( + _Inout_z_ wchar_t* _String + ); + + _CRT_NONSTDC_DEPRECATE(_wcsset) + _Ret_z_ + _ACRTIMP wchar_t* __cdecl wcsset( + _Inout_z_ wchar_t* _String, + _In_ wchar_t _Value + ); + + _CRT_NONSTDC_DEPRECATE(_wcslwr) + _Ret_z_ + _ACRTIMP wchar_t* __cdecl wcslwr( + _Inout_z_ wchar_t* _String + ); + + _CRT_NONSTDC_DEPRECATE(_wcsupr) + _Ret_z_ + _ACRTIMP wchar_t* __cdecl wcsupr( + _Inout_z_ wchar_t* _String + ); + + _Check_return_ _CRT_NONSTDC_DEPRECATE(_wcsicoll) + _ACRTIMP int __cdecl wcsicoll( + _In_z_ wchar_t const* _String1, + _In_z_ wchar_t const* _String2 + ); + +#endif // _CRT_INTERNAL_NONSTDC_NAMES + + + +_CRT_END_C_HEADER + +#endif // !__midl +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS diff --git a/sdk/include/ucrt/corecrt_wtime.h b/sdk/include/ucrt/corecrt_wtime.h new file mode 100644 index 0000000000000..3366f75031dd6 --- /dev/null +++ b/sdk/include/ucrt/corecrt_wtime.h @@ -0,0 +1,207 @@ +// +// corecrt_wtime.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// This file declares the wide character (wchar_t) time functionality, shared +// by and . +// +#pragma once + +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Types +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +struct tm +{ + int tm_sec; // seconds after the minute - [0, 60] including leap second + int tm_min; // minutes after the hour - [0, 59] + int tm_hour; // hours since midnight - [0, 23] + int tm_mday; // day of the month - [1, 31] + int tm_mon; // months since January - [0, 11] + int tm_year; // years since 1900 + int tm_wday; // days since Sunday - [0, 6] + int tm_yday; // days since January 1 - [0, 365] + int tm_isdst; // daylight savings time flag +}; + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Wide String Time Functions +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +_Check_return_ _CRT_INSECURE_DEPRECATE(_wasctime_s) +_Success_(return != 0) +_Ret_writes_z_(26) +_ACRTIMP wchar_t* __cdecl _wasctime( + _In_ struct tm const* _Tm + ); + +_Success_(return == 0) +_Check_return_wat_ +_ACRTIMP errno_t __cdecl _wasctime_s( + _Out_writes_z_(_SizeInWords) _Post_readable_size_(26) wchar_t* _Buffer, + _In_range_(>=,26) size_t _SizeInWords, + _In_ struct tm const* _Tm + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1( + _Success_(return == 0) + errno_t, _wasctime_s, + _Post_readable_size_(26) wchar_t, _Buffer, + _In_ struct tm const*, _Time + ) + +_Success_(return > 0) +_Check_return_wat_ +_ACRTIMP size_t __cdecl wcsftime( + _Out_writes_z_(_SizeInWords) wchar_t* _Buffer, + _In_ size_t _SizeInWords, + _In_z_ wchar_t const* _Format, + _In_ struct tm const* _Tm + ); + +_Success_(return > 0) +_Check_return_wat_ +_ACRTIMP size_t __cdecl _wcsftime_l( + _Out_writes_z_(_SizeInWords) wchar_t* _Buffer, + _In_ size_t _SizeInWords, + _In_z_ wchar_t const* _Format, + _In_ struct tm const* _Tm, + _In_opt_ _locale_t _Locale + ); + +_Success_(return != 0) +_Check_return_ _CRT_INSECURE_DEPRECATE(_wctime32_s) +_ACRTIMP wchar_t* __cdecl _wctime32( + _In_ __time32_t const* _Time + ); + +_Check_return_wat_ +_ACRTIMP errno_t __cdecl _wctime32_s( + _Out_writes_z_(_SizeInWords) _Post_readable_size_(26) wchar_t* _Buffer, + _In_ _In_range_(>=, 26) size_t _SizeInWords, + _In_ __time32_t const* _Time + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1( + errno_t, _wctime32_s, + _Post_readable_size_(26) wchar_t, _Buffer, + _In_ __time32_t const*, _Time + ) + +_Success_(return != 0) +_Ret_writes_z_(26) +_Check_return_ _CRT_INSECURE_DEPRECATE(_wctime64_s) +_ACRTIMP wchar_t* __cdecl _wctime64( + _In_ __time64_t const* _Time + ); + +_Check_return_wat_ +_ACRTIMP errno_t __cdecl _wctime64_s( + _Out_writes_z_(_SizeInWords) _Post_readable_size_(26) wchar_t* _Buffer, + _In_ _In_range_(>=, 26) size_t _SizeInWords, + _In_ __time64_t const* _Time); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1( + errno_t, _wctime64_s, + _Post_readable_size_(26) wchar_t, _Buffer, + _In_ __time64_t const*, _Time + ) + +_Check_return_wat_ +_ACRTIMP errno_t __cdecl _wstrdate_s( + _Out_writes_z_(_SizeInWords) _When_(_SizeInWords >=9, _Post_readable_size_(9)) wchar_t* _Buffer, + _In_ size_t _SizeInWords + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_0( + errno_t, _wstrdate_s, + _Post_readable_size_(9) wchar_t, _Buffer + ) + +__DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_0( + _Success_(return != 0) _Ret_writes_z_(9) wchar_t*, __RETURN_POLICY_DST, _ACRTIMP, _wstrdate, + _Out_writes_z_(9), wchar_t, _Buffer + ) + +_Check_return_wat_ +_ACRTIMP errno_t __cdecl _wstrtime_s( + _Out_writes_z_(_SizeInWords) _When_(_SizeInWords >=9, _Post_readable_size_(9)) wchar_t* _Buffer, + _In_ size_t _SizeInWords + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_0( + errno_t, _wstrtime_s, + _Post_readable_size_(9) wchar_t, _Buffer + ) + +__DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_0( + _Success_(return != 0) _Ret_writes_z_(9) wchar_t*, __RETURN_POLICY_DST, _ACRTIMP, _wstrtime, + _Out_writes_z_(9), wchar_t, _Buffer + ) + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Inline Definitions +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#if !defined RC_INVOKED && !defined __midl && !defined _INC_WTIME_INL && !defined _CRT_NO_TIME_T + #ifdef _USE_32BIT_TIME_T + + _Check_return_ + static __inline wchar_t* __CRTDECL _wctime( + _In_ time_t const* const _Time + ) + { + return _wctime32(_Time); + } + + _Check_return_wat_ + static __inline errno_t __CRTDECL _wctime_s( + _Pre_notnull_ _Post_z_ _Out_writes_z_(_SizeInWords) wchar_t* const _Buffer, + _In_ size_t const _SizeInWords, + _In_ time_t const* const _Time) + { + return _wctime32_s(_Buffer, _SizeInWords, _Time); + } + + #else // ^^^ _USE_32BIT_TIME_T ^^^ // vvv !_USE_32BIT_TIME_T vvv // + + _Check_return_ + static __inline wchar_t * __CRTDECL _wctime( + _In_ time_t const* const _Time) + { + return _wctime64(_Time); + } + + _Check_return_wat_ + static __inline errno_t __CRTDECL _wctime_s( + _Pre_notnull_ _Post_z_ _Out_writes_z_(_SizeInWords) wchar_t* const _Buffer, + _In_ size_t const _SizeInWords, + _In_ time_t const* const _Time + ) + { + return _wctime64_s(_Buffer, _SizeInWords, _Time); + } + + #endif // !_USE_32BIT_TIME_T +#endif + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS diff --git a/sdk/include/ucrt/crtdbg.h b/sdk/include/ucrt/crtdbg.h new file mode 100644 index 0000000000000..e9f6952acedf6 --- /dev/null +++ b/sdk/include/ucrt/crtdbg.h @@ -0,0 +1,817 @@ +// +// crtdbg.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// Public debugging facilities for the CRT +// +#pragma once +#ifndef _INC_CRTDBG // include guard for 3rd party interop +#define _INC_CRTDBG + +#include +#include +#include // for __debugbreak() on GCC + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + + + +typedef void* _HFILE; // file handle pointer + +#define _CRT_WARN 0 +#define _CRT_ERROR 1 +#define _CRT_ASSERT 2 +#define _CRT_ERRCNT 3 + +#define _CRTDBG_MODE_FILE 0x1 +#define _CRTDBG_MODE_DEBUG 0x2 +#define _CRTDBG_MODE_WNDW 0x4 +#define _CRTDBG_REPORT_MODE -1 + +#define _CRTDBG_INVALID_HFILE ((_HFILE)(intptr_t)-1) +#define _CRTDBG_HFILE_ERROR ((_HFILE)(intptr_t)-2) +#define _CRTDBG_FILE_STDOUT ((_HFILE)(intptr_t)-4) +#define _CRTDBG_FILE_STDERR ((_HFILE)(intptr_t)-5) +#define _CRTDBG_REPORT_FILE ((_HFILE)(intptr_t)-6) + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Client-defined reporting and allocation hooks +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +typedef int (__CRTDECL* _CRT_REPORT_HOOK )(int, char*, int*); +typedef int (__CRTDECL* _CRT_REPORT_HOOKW)(int, wchar_t*, int*); + +#define _CRT_RPTHOOK_INSTALL 0 +#define _CRT_RPTHOOK_REMOVE 1 + + +typedef int (__CRTDECL* _CRT_ALLOC_HOOK)(int, void*, size_t, int, long, unsigned char const*, int); + +#ifdef _M_CEE + typedef int (__clrcall* _CRT_ALLOC_HOOK_M)(int, void*, size_t, int, long, unsigned char const*, int); +#endif + +#define _HOOK_ALLOC 1 +#define _HOOK_REALLOC 2 +#define _HOOK_FREE 3 + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Memory Management and State Tracking +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +// Bit values for _crtDbgFlag flag. These bitflags control debug heap behavior. +#define _CRTDBG_ALLOC_MEM_DF 0x01 // Turn on debug allocation +#define _CRTDBG_DELAY_FREE_MEM_DF 0x02 // Don't actually free memory +#define _CRTDBG_CHECK_ALWAYS_DF 0x04 // Check heap every alloc/dealloc +#define _CRTDBG_RESERVED_DF 0x08 // Reserved - do not use +#define _CRTDBG_CHECK_CRT_DF 0x10 // Leak check/diff CRT blocks +#define _CRTDBG_LEAK_CHECK_DF 0x20 // Leak check at program exit + +// Some bit values for _crtDbgFlag which correspond to frequencies for checking +// the heap. +#define _CRTDBG_CHECK_EVERY_16_DF 0x00100000 // Check heap every 16 heap ops +#define _CRTDBG_CHECK_EVERY_128_DF 0x00800000 // Check heap every 128 heap ops +#define _CRTDBG_CHECK_EVERY_1024_DF 0x04000000 // Check heap every 1024 heap ops + +// We do not check the heap by default at this point because the cost was too +// high for some applications. You can still turn this feature on manually. +#define _CRTDBG_CHECK_DEFAULT_DF 0 + +#define _CRTDBG_REPORT_FLAG -1 // Query bitflag status + +#define _BLOCK_TYPE(block) (block & 0xFFFF) +#define _BLOCK_SUBTYPE(block) (block >> 16 & 0xFFFF) + +// Memory block identification +#define _FREE_BLOCK 0 +#define _NORMAL_BLOCK 1 +#define _CRT_BLOCK 2 +#define _IGNORE_BLOCK 3 +#define _CLIENT_BLOCK 4 +#define _MAX_BLOCKS 5 + +// _UNKNOWN_BLOCK is a sentinel value that may be passed to some functions that +// expect a block type as an argument. If this value is passed, those functions +// will use the block type specified in the block header instead. This is used +// in cases where the heap lock cannot be acquired to compute the block type +// before calling the function (e.g. when the caller is outside of the CoreCRT). +#define _UNKNOWN_BLOCK (-1) + +typedef void (__CRTDECL* _CRT_DUMP_CLIENT)(void*, size_t); + +#ifdef _M_CEE + typedef void (__clrcall* _CRT_DUMP_CLIENT_M)(void*, size_t); +#endif + +struct _CrtMemBlockHeader; + +typedef struct _CrtMemState +{ + struct _CrtMemBlockHeader* pBlockHeader; + size_t lCounts[_MAX_BLOCKS]; + size_t lSizes[_MAX_BLOCKS]; + size_t lHighWaterCount; + size_t lTotalCount; +} _CrtMemState; + +#ifndef _DEBUG + + #define _CrtGetAllocHook() ((_CRT_ALLOC_HOOK)0) + #define _CrtSetAllocHook(f) ((_CRT_ALLOC_HOOK)0) + + #define _CrtGetDumpClient() ((_CRT_DUMP_CLIENT)0) + #define _CrtSetDumpClient(f) ((_CRT_DUMP_CLIENT)0) + + #define _CrtCheckMemory() ((int)1) + #define _CrtDoForAllClientObjects(f, c) ((void)0) + #define _CrtDumpMemoryLeaks() ((int)0) + #define _CrtIsMemoryBlock(p, t, r, f, l) ((int)1) + #define _CrtIsValidHeapPointer(p) ((int)1) + #define _CrtIsValidPointer(p, n, r) ((int)1) + #define _CrtMemCheckpoint(s) ((void)0) + #define _CrtMemDifference(s1, s2, s3) ((int)0) + #define _CrtMemDumpAllObjectsSince(s) ((void)0) + #define _CrtMemDumpStatistics(s) ((void)0) + #define _CrtReportBlockType(p) ((int)-1) + #define _CrtSetBreakAlloc(a) ((long)0) + #define _CrtSetDbgFlag(f) ((int)0) + + +#else // ^^^ !_DEBUG ^^^ // vvv _DEBUG vvv // + + #ifndef _M_CEE_PURE + + _ACRTIMP int* __cdecl __p__crtDbgFlag(void); + _ACRTIMP long* __cdecl __p__crtBreakAlloc(void); + + #define _crtDbgFlag (*__p__crtDbgFlag()) + #define _crtBreakAlloc (*__p__crtBreakAlloc()) + + _ACRTIMP _CRT_ALLOC_HOOK __cdecl _CrtGetAllocHook(void); + + _ACRTIMP _CRT_ALLOC_HOOK __cdecl _CrtSetAllocHook( + _In_opt_ _CRT_ALLOC_HOOK _PfnNewHook + ); + + _ACRTIMP _CRT_DUMP_CLIENT __cdecl _CrtGetDumpClient(void); + + _ACRTIMP _CRT_DUMP_CLIENT __cdecl _CrtSetDumpClient( + _In_opt_ _CRT_DUMP_CLIENT _PFnNewDump + ); + + #endif // _M_CEE_PURE + + _ACRTIMP int __cdecl _CrtCheckMemory(void); + + typedef void (__cdecl* _CrtDoForAllClientObjectsCallback)(void*, void*); + + _ACRTIMP void __cdecl _CrtDoForAllClientObjects( + _In_ _CrtDoForAllClientObjectsCallback _Callback, + _In_ void* _Context + ); + + _ACRTIMP int __cdecl _CrtDumpMemoryLeaks(void); + + _ACRTIMP int __cdecl _CrtIsMemoryBlock( + _In_opt_ void const* _Block, + _In_ unsigned int _Size, + _Out_opt_ long* _RequestNumber, + _Out_opt_ char** _FileName, + _Out_opt_ int* _LineNumber + ); + + _Check_return_ + _ACRTIMP int __cdecl _CrtIsValidHeapPointer( + _In_opt_ void const* _Pointer + ); + + _Check_return_ + _ACRTIMP int __cdecl _CrtIsValidPointer( + _In_opt_ void const* _Pointer, + _In_ unsigned int _Size, + _In_ int _ReadWrite + ); + + _ACRTIMP void __cdecl _CrtMemCheckpoint( + _Out_ _CrtMemState* _State + ); + + _ACRTIMP int __cdecl _CrtMemDifference( + _Out_ _CrtMemState* _State, + _In_ _CrtMemState const* _OldState, + _In_ _CrtMemState const* _NewState + ); + + _ACRTIMP void __cdecl _CrtMemDumpAllObjectsSince( + _In_opt_ _CrtMemState const* _State + ); + + _ACRTIMP void __cdecl _CrtMemDumpStatistics( + _In_ _CrtMemState const* _State + ); + + _Check_return_ + _ACRTIMP int __cdecl _CrtReportBlockType( + _In_opt_ void const* _Block + ); + + _ACRTIMP long __cdecl _CrtSetBreakAlloc( + _In_ long _NewValue + ); + + _ACRTIMP int __cdecl _CrtSetDbgFlag( + _In_ int _NewFlag + ); + +#endif // _DEBUG + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Debug Heap Routines +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#ifndef _DEBUG + + #define _calloc_dbg(c, s, t, f, l) calloc(c, s) + #define _expand_dbg(p, s, t, f, l) _expand(p, s) + #define _free_dbg(p, t) free(p) + #define _malloc_dbg(s, t, f, l) malloc(s) + #define _msize_dbg(p, t) _msize(p) + #define _realloc_dbg(p, s, t, f, l) realloc(p, s) + #define _recalloc_dbg(p, c, s, t, f, l) _recalloc(p, c, s) + + #define _aligned_free_dbg(p) _aligned_free(p) + #define _aligned_malloc_dbg(s, a, f, l) _aligned_malloc(s, a) + #define _aligned_msize_dbg(p, a, o) _aligned_msize(p, a, o) + #define _aligned_offset_malloc_dbg(s, a, o, f, l) _aligned_offset_malloc(s, a, o) + #define _aligned_offset_realloc_dbg(p, s, a, o, f, l) _aligned_offset_realloc(p, s, a, o) + #define _aligned_offset_recalloc_dbg(p, c, s, a, o, f, l) _aligned_offset_recalloc(p, c, s, a, o) + #define _aligned_realloc_dbg(p, s, a, f, l) _aligned_realloc(p, s, a) + #define _aligned_recalloc_dbg(p, c, s, a, f, l) _aligned_recalloc(p, c, s, a) + + #define _freea_dbg(p, t) _freea(p) + #define _malloca_dbg(s, t, f, l) _malloca(s) + + #define _dupenv_s_dbg(ps1, size, s2, t, f, l) _dupenv_s(ps1, size, s2) + #define _fullpath_dbg(s1, s2, le, t, f, l) _fullpath(s1, s2, le) + #define _getcwd_dbg(s, le, t, f, l) _getcwd(s, le) + #define _getdcwd_dbg(d, s, le, t, f, l) _getdcwd(d, s, le) + #define _getdcwd_lk_dbg(d, s, le, t, f, l) _getdcwd(d, s, le) + #define _mbsdup_dbg(s, t, f, l) _mbsdup(s) + #define _strdup_dbg(s, t, f, l) _strdup(s) + #define _tempnam_dbg(s1, s2, t, f, l) _tempnam(s1, s2) + #define _wcsdup_dbg(s, t, f, l) _wcsdup(s) + #define _wdupenv_s_dbg(ps1, size, s2, t, f, l) _wdupenv_s(ps1, size, s2) + #define _wfullpath_dbg(s1, s2, le, t, f, l) _wfullpath(s1, s2, le) + #define _wgetcwd_dbg(s, le, t, f, l) _wgetcwd(s, le) + #define _wgetdcwd_dbg(d, s, le, t, f, l) _wgetdcwd(d, s, le) + #define _wgetdcwd_lk_dbg(d, s, le, t, f, l) _wgetdcwd(d, s, le) + #define _wtempnam_dbg(s1, s2, t, f, l) _wtempnam(s1, s2) + +#else // ^^^ !_DEBUG ^^^ // vvv _DEBUG vvv // + + #ifdef _CRTDBG_MAP_ALLOC + + #define calloc(c, s) _calloc_dbg(c, s, _NORMAL_BLOCK, __FILE__, __LINE__) + #define _expand(p, s) _expand_dbg(p, s, _NORMAL_BLOCK, __FILE__, __LINE__) + #define free(p) _free_dbg(p, _NORMAL_BLOCK) + #define malloc(s) _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__) + #define _msize(p) _msize_dbg(p, _NORMAL_BLOCK) + #define realloc(p, s) _realloc_dbg(p, s, _NORMAL_BLOCK, __FILE__, __LINE__) + #define _recalloc(p, c, s) _recalloc_dbg(p, c, s, _NORMAL_BLOCK, __FILE__, __LINE__) + + #define _aligned_free(p) _aligned_free_dbg(p) + #define _aligned_malloc(s, a) _aligned_malloc_dbg(s, a, __FILE__, __LINE__) + #define _aligned_msize(p, a, o) _aligned_msize_dbg(p, a, o) + #define _aligned_offset_malloc(s, a, o) _aligned_offset_malloc_dbg(s, a, o, __FILE__, __LINE__) + #define _aligned_offset_realloc(p, s, a, o) _aligned_offset_realloc_dbg(p, s, a, o, __FILE__, __LINE__) + #define _aligned_offset_recalloc(p, c, s, a, o) _aligned_offset_recalloc_dbg(p, c, s, a, o, __FILE__, __LINE__) + #define _aligned_realloc(p, s, a) _aligned_realloc_dbg(p, s, a, __FILE__, __LINE__) + #define _aligned_recalloc(p, c, s, a) _aligned_recalloc_dbg(p, c, s, a, __FILE__, __LINE__) + + #define _freea(p) _freea_dbg(p, _NORMAL_BLOCK) + #define _malloca(s) _malloca_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__) + + #define _dupenv_s(ps1, size, s2) _dupenv_s_dbg(ps1, size, s2, _NORMAL_BLOCK, __FILE__, __LINE__) + #define _fullpath(s1, s2, le) _fullpath_dbg(s1, s2, le, _NORMAL_BLOCK, __FILE__, __LINE__) + #define _getcwd(s, le) _getcwd_dbg(s, le, _NORMAL_BLOCK, __FILE__, __LINE__) + #define _getdcwd(d, s, le) _getdcwd_dbg(d, s, le, _NORMAL_BLOCK, __FILE__, __LINE__) + #define _mbsdup(s) _strdup_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__) + #define _strdup(s) _strdup_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__) + #define _tempnam(s1, s2) _tempnam_dbg(s1, s2, _NORMAL_BLOCK, __FILE__, __LINE__) + #define _wcsdup(s) _wcsdup_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__) + #define _wdupenv_s(ps1, size, s2) _wdupenv_s_dbg(ps1, size, s2, _NORMAL_BLOCK, __FILE__, __LINE__) + #define _wfullpath(s1, s2, le) _wfullpath_dbg(s1, s2, le, _NORMAL_BLOCK, __FILE__, __LINE__) + #define _wgetcwd(s, le) _wgetcwd_dbg(s, le, _NORMAL_BLOCK, __FILE__, __LINE__) + #define _wgetdcwd(d, s, le) _wgetdcwd_dbg(d, s, le, _NORMAL_BLOCK, __FILE__, __LINE__) + #define _wtempnam(s1, s2) _wtempnam_dbg(s1, s2, _NORMAL_BLOCK, __FILE__, __LINE__) + + #if defined(_CRT_INTERNAL_NONSTDC_NAMES) && _CRT_INTERNAL_NONSTDC_NAMES + #define strdup(s) _strdup_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__) + #define wcsdup(s) _wcsdup_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__) + #define tempnam(s1, s2) _tempnam_dbg(s1, s2, _NORMAL_BLOCK, __FILE__, __LINE__) + #define getcwd(s, le) _getcwd_dbg(s, le, _NORMAL_BLOCK, __FILE__, __LINE__) + #endif + + #endif // _CRTDBG_MAP_ALLOC + + _ACRTIMP void __cdecl _aligned_free_dbg( + _Pre_maybenull_ _Post_invalid_ void* _Block + ); + + _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Size) + _ACRTIMP _CRTALLOCATOR void* __cdecl _aligned_malloc_dbg( + _In_ size_t _Size, + _In_ size_t _Alignment, + _In_opt_z_ char const* _FileName, + _In_ int _LineNumber + ); + + _ACRTIMP size_t __cdecl _aligned_msize_dbg( + _Pre_notnull_ void* _Block, + _In_ size_t _Alignment, + _In_ size_t _Offset + ); + + _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Size) + _ACRTIMP _CRTALLOCATOR void* __cdecl _aligned_offset_malloc_dbg( + _In_ size_t _Size, + _In_ size_t _Alignment, + _In_ size_t _Offset, + _In_opt_z_ char const* _FileName, + _In_ int _LineNumber + ); + + _Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Size) + _ACRTIMP _CRTALLOCATOR void* __cdecl _aligned_offset_realloc_dbg( + _Pre_maybenull_ _Post_invalid_ void* _Block, + _In_ size_t _Size, + _In_ size_t _Alignment, + _In_ size_t _Offset, + _In_opt_z_ char const* _FileName, + _In_ int _LineNumber + ); + + _Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Count * _Size) + _ACRTIMP _CRTALLOCATOR void* __cdecl _aligned_offset_recalloc_dbg( + _Pre_maybenull_ _Post_invalid_ void* _Block, + _In_ size_t _Count, + _In_ size_t _Size, + _In_ size_t _Alignment, + _In_ size_t _Offset, + _In_opt_z_ char const* _FileName, + _In_ int _LineNumber + ); + + _Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Size) + _ACRTIMP _CRTALLOCATOR void* __cdecl _aligned_realloc_dbg( + _Pre_maybenull_ _Post_invalid_ void* _Block, + _In_ size_t _Size, + _In_ size_t _Alignment, + _In_opt_z_ char const* _FileName, + _In_ int _LineNumber + ); + + _Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Count * _Size) + _ACRTIMP _CRTALLOCATOR void* __cdecl _aligned_recalloc_dbg( + _Pre_maybenull_ _Post_invalid_ void* _Block, + _In_ size_t _Count, + _In_ size_t _Size, + _In_ size_t _Alignment, + _In_opt_z_ char const* _FileName, + _In_ int _LineNumber + ); + + _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Count * _Size) + _ACRTIMP _CRTALLOCATOR void* __cdecl _calloc_dbg( + _In_ size_t _Count, + _In_ size_t _Size, + _In_ int _BlockUse, + _In_opt_z_ char const* _FileName, + _In_ int _LineNumber + ); + + _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Size) + _ACRTIMP _CRTALLOCATOR void* __cdecl _expand_dbg( + _Pre_notnull_ void* _Block, + _In_ size_t _Size, + _In_ int _BlockUse, + _In_opt_z_ char const* _FileName, + _In_ int _LineNumber + ); + + _ACRTIMP void __cdecl _free_dbg( + _Pre_maybenull_ _Post_invalid_ void* _Block, + _In_ int _BlockUse + ); + + _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Size) + _ACRTIMP _CRTALLOCATOR void* __cdecl _malloc_dbg( + _In_ size_t _Size, + _In_ int _BlockUse, + _In_opt_z_ char const* _FileName, + _In_ int _LineNumber + ); + + _ACRTIMP size_t __cdecl _msize_dbg( + _Pre_notnull_ void* _Block, + _In_ int _BlockUse + ); + + _Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Size) + _ACRTIMP _CRTALLOCATOR void* __cdecl _realloc_dbg( + _Pre_maybenull_ _Post_invalid_ void* _Block, + _In_ size_t _Size, + _In_ int _BlockUse, + _In_opt_z_ char const* _FileName, + _In_ int _LineNumber + ); + + _Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Count * _Size) + _ACRTIMP _CRTALLOCATOR void* __cdecl _recalloc_dbg( + _Pre_maybenull_ _Post_invalid_ void* _Block, + _In_ size_t _Count, + _In_ size_t _Size, + _In_ int _BlockUse, + _In_opt_z_ char const* _FileName, + _In_ int _LineNumber + ); + + _Success_(return == 0) + _Check_return_wat_ + _DCRTIMP errno_t __cdecl _dupenv_s_dbg( + _Outptr_result_buffer_maybenull_(*_PBufferSizeInBytes) char** _PBuffer, + _Out_opt_ size_t* _PBufferSizeInBytes, + _In_z_ char const* _VarName, + _In_ int _BlockType, + _In_opt_z_ char const* _FileName, + _In_ int _LineNumber + ); + + _Success_(return != 0) + _Check_return_ _Ret_maybenull_z_ + _ACRTIMP _CRTALLOCATOR char* __cdecl _fullpath_dbg( + _Out_writes_opt_z_(_SizeInBytes) char* _FullPath, + _In_z_ char const* _Path, + _In_ size_t _SizeInBytes, + _In_ int _BlockType, + _In_opt_z_ char const* _FileName, + _In_ int _LineNumber + ); + + _Success_(return != 0) + _Check_return_ _Ret_maybenull_z_ + _DCRTIMP _CRTALLOCATOR char* __cdecl _getcwd_dbg( + _Out_writes_opt_z_(_SizeInBytes) char* _DstBuf, + _In_ int _SizeInBytes, + _In_ int _BlockType, + _In_opt_z_ char const* _FileName, + _In_ int _LineNumber + ); + + + _Success_(return != 0) + _Check_return_ _Ret_maybenull_z_ + _DCRTIMP _CRTALLOCATOR char* __cdecl _getdcwd_dbg( + _In_ int _Drive, + _Out_writes_opt_z_(_SizeInBytes) char* _DstBuf, + _In_ int _SizeInBytes, + _In_ int _BlockType, + _In_opt_z_ char const* _FileName, + _In_ int _LineNumber + ); + + _Check_return_ _Ret_maybenull_z_ + _ACRTIMP _CRTALLOCATOR char* __cdecl _strdup_dbg( + _In_opt_z_ char const* _String, + _In_ int _BlockUse, + _In_opt_z_ char const* _FileName, + _In_ int _LineNumber + ); + + _Check_return_ _Ret_maybenull_z_ + _ACRTIMP _CRTALLOCATOR char* __cdecl _tempnam_dbg( + _In_opt_z_ char const* _DirName, + _In_opt_z_ char const* _FilePrefix, + _In_ int _BlockType, + _In_opt_z_ char const* _FileName, + _In_ int _LineNumber + ); + + _Success_(return != 0) + _Check_return_ _Ret_maybenull_z_ + _ACRTIMP _CRTALLOCATOR wchar_t* __cdecl _wcsdup_dbg( + _In_opt_z_ wchar_t const* _String, + _In_ int _BlockUse, + _In_opt_z_ char const* _FileName, + _In_ int _LineNumber + ); + + _Success_(return == 0) + _Check_return_wat_ + _DCRTIMP errno_t __cdecl _wdupenv_s_dbg( + _Outptr_result_buffer_maybenull_(*_PBufferSizeInWords) wchar_t** _PBuffer, + _Out_opt_ size_t* _PBufferSizeInWords, + _In_z_ wchar_t const* _VarName, + _In_ int _BlockType, + _In_opt_z_ char const* _FileName, + _In_ int _LineNumber + ); + + _Success_(return != 0) + _Check_return_ _Ret_maybenull_z_ + _ACRTIMP _CRTALLOCATOR wchar_t* __cdecl _wfullpath_dbg( + _Out_writes_opt_z_(_SizeInWords) wchar_t* _FullPath, + _In_z_ wchar_t const* _Path, + _In_ size_t _SizeInWords, + _In_ int _BlockType, + _In_opt_z_ char const* _FileName, + _In_ int _LineNumber + ); + + _Success_(return != 0) + _Check_return_ _Ret_maybenull_z_ + _DCRTIMP _CRTALLOCATOR wchar_t* __cdecl _wgetcwd_dbg( + _Out_writes_opt_z_(_SizeInWords) wchar_t* _DstBuf, + _In_ int _SizeInWords, + _In_ int _BlockType, + _In_opt_z_ char const* _FileName, + _In_ int _LineNumber + ); + + _Success_(return != 0) + _Check_return_ _Ret_maybenull_z_ + _DCRTIMP _CRTALLOCATOR wchar_t* __cdecl _wgetdcwd_dbg( + _In_ int _Drive, + _Out_writes_opt_z_(_SizeInWords) wchar_t* _DstBuf, + _In_ int _SizeInWords, + _In_ int _BlockType, + _In_opt_z_ char const* _FileName, + _In_ int _LineNumber + ); + + _Check_return_ _Ret_maybenull_z_ + _ACRTIMP _CRTALLOCATOR wchar_t* __cdecl _wtempnam_dbg( + _In_opt_z_ wchar_t const* _DirName, + _In_opt_z_ wchar_t const* _FilePrefix, + _In_ int _BlockType, + _In_opt_z_ char const* _FileName, + _In_ int _LineNumber + ); + + #define _malloca_dbg(s, t, f, l) _malloc_dbg(s, t, f, l) + #define _freea_dbg(p, t) _free_dbg(p, t) + + #if defined __cplusplus && defined _CRTDBG_MAP_ALLOC + namespace std + { + using ::_calloc_dbg; + using ::_free_dbg; + using ::_malloc_dbg; + using ::_realloc_dbg; + } + #endif + +#endif // _DEBUG + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Debug Reporting +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +#ifndef _DEBUG + + #define _CrtSetDebugFillThreshold(t) ((size_t)0) + #define _CrtSetReportFile(t, f) ((_HFILE)0) + #define _CrtSetReportMode(t, f) ((int)0) + #define _CrtGetReportHook() ((_CRT_REPORT_HOOK)0) + #define _CrtSetReportHook(f) ((_CRT_REPORT_HOOK)0) + #define _CrtSetReportHook2(t, f) ((int)0) + #define _CrtSetReportHookW2(t, f) ((int)0) + +#else // ^^^ !_DEBUG ^^^ // vvv _DEBUG vvv // + + _ACRTIMP int __cdecl _CrtDbgReport( + _In_ int _ReportType, + _In_opt_z_ char const* _FileName, + _In_ int _Linenumber, + _In_opt_z_ char const* _ModuleName, + _In_opt_z_ char const* _Format, + ...); + + _ACRTIMP int __cdecl _CrtDbgReportW( + _In_ int _ReportType, + _In_opt_z_ wchar_t const* _FileName, + _In_ int _LineNumber, + _In_opt_z_ wchar_t const* _ModuleName, + _In_opt_z_ wchar_t const* _Format, + ...); + + + _ACRTIMP int __cdecl _VCrtDbgReportA( + _In_ int _ReportType, + _In_opt_ void* _ReturnAddress, + _In_opt_z_ char const* _FileName, + _In_ int _LineNumber, + _In_opt_z_ char const* _ModuleName, + _In_opt_z_ char const* _Format, + va_list _ArgList + ); + + _ACRTIMP int __cdecl _VCrtDbgReportW( + _In_ int _ReportType, + _In_opt_ void* _ReturnAddress, + _In_opt_z_ wchar_t const* _FileName, + _In_ int _LineNumber, + _In_opt_z_ wchar_t const* _ModuleName, + _In_opt_z_ wchar_t const* _Format, + va_list _ArgList + ); + + _ACRTIMP size_t __cdecl _CrtSetDebugFillThreshold( + _In_ size_t _NewDebugFillThreshold + ); + + _ACRTIMP size_t __cdecl _CrtGetDebugFillThreshold(void); + + _ACRTIMP _HFILE __cdecl _CrtSetReportFile( + _In_ int _ReportType, + _In_opt_ _HFILE _ReportFile + ); + + _ACRTIMP int __cdecl _CrtSetReportMode( + _In_ int _ReportType, + _In_ int _ReportMode + ); + + #ifndef _M_CEE_PURE + + extern long _crtAssertBusy; + + _ACRTIMP _CRT_REPORT_HOOK __cdecl _CrtGetReportHook(void); + + // _CrtSetReportHook[[W]2]: + // For IJW, we need two versions: one for clrcall and one for cdecl. + // For pure and native, we just need clrcall and cdecl, respectively. + _ACRTIMP _CRT_REPORT_HOOK __cdecl _CrtSetReportHook( + _In_opt_ _CRT_REPORT_HOOK _PFnNewHook + ); + + _ACRTIMP int __cdecl _CrtSetReportHook2( + _In_ int _Mode, + _In_opt_ _CRT_REPORT_HOOK _PFnNewHook + ); + + _ACRTIMP int __cdecl _CrtSetReportHookW2( + _In_ int _Mode, + _In_opt_ _CRT_REPORT_HOOKW _PFnNewHook + ); + + #endif // !_M_CEE_PURE + +#endif // _DEBUG + + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Assertions and Error Reporting Macros +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#ifndef _DEBUG + + #define _CrtDbgBreak() ((void)0) + + #ifndef _ASSERT_EXPR + #define _ASSERT_EXPR(expr, msg) ((void)0) + #endif + + #ifndef _ASSERT + #define _ASSERT(expr) ((void)0) + #endif + + #ifndef _ASSERTE + #define _ASSERTE(expr) ((void)0) + #endif + + #define _RPT0(rptno, msg) + #define _RPTN(rptno, msg, ...) + + #define _RPTW0(rptno, msg) + #define _RPTWN(rptno, msg, ...) + + #define _RPTF0(rptno, msg) + #define _RPTFN(rptno, msg, ...) + + #define _RPTFW0(rptno, msg) + #define _RPTFWN(rptno, msg, ...) + +#else // ^^^ !_DEBUG ^^^ // vvv _DEBUG vvv // + + #define _CrtDbgBreak() __debugbreak() + + // !! is used to ensure that any overloaded operators used to evaluate expr + // do not end up at &&. + #ifndef _ASSERT_EXPR + #define _ASSERT_EXPR(expr, msg) \ + (void)( \ + (!!(expr)) || \ + (1 != _CrtDbgReportW(_CRT_ASSERT, _CRT_WIDE(__FILE__), __LINE__, NULL, L"%ls", msg)) || \ + (_CrtDbgBreak(), 0) \ + ) + #endif + + #ifndef _ASSERT + #define _ASSERT(expr) _ASSERT_EXPR((expr), NULL) + #endif + + #ifndef _ASSERTE + #define _ASSERTE(expr) _ASSERT_EXPR((expr), _CRT_WIDE(#expr)) + #endif + + #define _RPT_BASE(...) \ + (void) ((1 != _CrtDbgReport(__VA_ARGS__)) || \ + (_CrtDbgBreak(), 0)) + + #define _RPT_BASE_W(...) \ + (void) ((1 != _CrtDbgReportW(__VA_ARGS__)) || \ + (_CrtDbgBreak(), 0)) + + #define _RPT0(rptno, msg) _RPT_BASE(rptno, NULL, 0, NULL, "%s", msg) + #define _RPTN(rptno, msg, ...) _RPT_BASE(rptno, NULL, 0, NULL, msg, __VA_ARGS__) + + #define _RPTW0(rptno, msg) _RPT_BASE_W(rptno, NULL, 0, NULL, L"%ls", msg) + #define _RPTWN(rptno, msg, ...) _RPT_BASE_W(rptno, NULL, 0, NULL, msg, __VA_ARGS__) + + #define _RPTF0(rptno, msg) _RPT_BASE(rptno, __FILE__, __LINE__, NULL, "%s", msg) + #define _RPTFN(rptno, msg, ...) _RPT_BASE(rptno, __FILE__, __LINE__, NULL, msg, __VA_ARGS__) + + #define _RPTFW0(rptno, msg) _RPT_BASE_W(rptno, _CRT_WIDE(__FILE__), __LINE__, NULL, L"%ls", msg) + #define _RPTFWN(rptno, msg, ...) _RPT_BASE_W(rptno, _CRT_WIDE(__FILE__), __LINE__, NULL, msg, __VA_ARGS__) + +#endif // _DEBUG + +// Asserts in debug. Invokes Watson in both debug and release +#define _ASSERT_AND_INVOKE_WATSON(expr) \ + { \ + _ASSERTE((expr)); \ + if (!(expr)) \ + { \ + _invoke_watson(_CRT_WIDE(#expr), __FUNCTIONW__, __FILEW__, __LINE__, 0); \ + } \ + } + +// _ASSERT_BASE is provided only for backwards compatibility. +#ifndef _ASSERT_BASE + #define _ASSERT_BASE _ASSERT_EXPR +#endif + +#define _RPT1 _RPTN +#define _RPT2 _RPTN +#define _RPT3 _RPTN +#define _RPT4 _RPTN +#define _RPT5 _RPTN + +#define _RPTW1 _RPTWN +#define _RPTW2 _RPTWN +#define _RPTW3 _RPTWN +#define _RPTW4 _RPTWN +#define _RPTW5 _RPTWN + +#define _RPTF1 _RPTFN +#define _RPTF2 _RPTFN +#define _RPTF3 _RPTFN +#define _RPTF4 _RPTFN +#define _RPTF5 _RPTFN + +#define _RPTFW1 _RPTFWN +#define _RPTFW2 _RPTFWN +#define _RPTFW3 _RPTFWN +#define _RPTFW4 _RPTFWN +#define _RPTFW5 _RPTFWN + + + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS +#endif // _INC_CRTDBG diff --git a/sdk/include/ucrt/ctype.h b/sdk/include/ucrt/ctype.h new file mode 100644 index 0000000000000..6b8d479113452 --- /dev/null +++ b/sdk/include/ucrt/ctype.h @@ -0,0 +1,310 @@ +// +// ctype.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// This file declares the narrow character (char) classification functionality. +// +#pragma once +#ifndef _INC_CTYPE // include guard for 3rd party interop +#define _INC_CTYPE + +#include +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER +#if !defined __midl && !defined RC_INVOKED + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Character Classification Function Declarations +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +_Check_return_ _ACRTIMP int __cdecl _isctype(_In_ int _C, _In_ int _Type); +_Check_return_ _ACRTIMP int __cdecl _isctype_l(_In_ int _C, _In_ int _Type, _In_opt_ _locale_t _Locale); +_Check_return_ _CRT_JIT_INTRINSIC _ACRTIMP int __cdecl isalpha(_In_ int _C); +_Check_return_ _ACRTIMP int __cdecl _isalpha_l(_In_ int _C, _In_opt_ _locale_t _Locale); +_Check_return_ _CRT_JIT_INTRINSIC _ACRTIMP int __cdecl isupper(_In_ int _C); +_Check_return_ _ACRTIMP int __cdecl _isupper_l(_In_ int _C, _In_opt_ _locale_t _Locale); +_Check_return_ _CRT_JIT_INTRINSIC _ACRTIMP int __cdecl islower(_In_ int _C); +_Check_return_ _ACRTIMP int __cdecl _islower_l(_In_ int _C, _In_opt_ _locale_t _Locale); + +_When_(_Param_(1) == 0, _Post_equal_to_(0)) +_Check_return_ _CRT_JIT_INTRINSIC _ACRTIMP int __cdecl isdigit(_In_ int _C); + +_Check_return_ _ACRTIMP int __cdecl _isdigit_l(_In_ int _C, _In_opt_ _locale_t _Locale); +_Check_return_ _ACRTIMP int __cdecl isxdigit(_In_ int _C); +_Check_return_ _ACRTIMP int __cdecl _isxdigit_l(_In_ int _C, _In_opt_ _locale_t _Locale); + +_When_(_Param_(1) == 0, _Post_equal_to_(0)) +_Check_return_ _CRT_JIT_INTRINSIC _ACRTIMP int __cdecl isspace(_In_ int _C); + +_Check_return_ _ACRTIMP int __cdecl _isspace_l(_In_ int _C, _In_opt_ _locale_t _Locale); +_Check_return_ _ACRTIMP int __cdecl ispunct(_In_ int _C); +_Check_return_ _ACRTIMP int __cdecl _ispunct_l(_In_ int _C, _In_opt_ _locale_t _Locale); +_Check_return_ _ACRTIMP int __cdecl isblank(_In_ int _C); +_Check_return_ _ACRTIMP int __cdecl _isblank_l(_In_ int _C, _In_opt_ _locale_t _Locale); +_Check_return_ _CRT_JIT_INTRINSIC _ACRTIMP int __cdecl isalnum(_In_ int _C); +_Check_return_ _ACRTIMP int __cdecl _isalnum_l(_In_ int _C, _In_opt_ _locale_t _Locale); +_Check_return_ _ACRTIMP int __cdecl isprint(_In_ int _C); +_Check_return_ _ACRTIMP int __cdecl _isprint_l(_In_ int _C, _In_opt_ _locale_t _Locale); +_Check_return_ _ACRTIMP int __cdecl isgraph(_In_ int _C); +_Check_return_ _ACRTIMP int __cdecl _isgraph_l(_In_ int _C, _In_opt_ _locale_t _Locale); +_Check_return_ _ACRTIMP int __cdecl iscntrl(_In_ int _C); +_Check_return_ _ACRTIMP int __cdecl _iscntrl_l(_In_ int _C, _In_opt_ _locale_t _Locale); + +_When_(_Param_(1) == 0, _Post_equal_to_(0)) +_Check_return_ _CRT_JIT_INTRINSIC _ACRTIMP int __cdecl toupper(_In_ int _C); + +_When_(_Param_(1) == 0, _Post_equal_to_(0)) +_Check_return_ _CRT_JIT_INTRINSIC _ACRTIMP int __cdecl tolower(_In_ int _C); + +_Check_return_ _CRT_JIT_INTRINSIC _ACRTIMP int __cdecl _tolower(_In_ int _C); +_Check_return_ _ACRTIMP int __cdecl _tolower_l(_In_ int _C, _In_opt_ _locale_t _Locale); +_Check_return_ _CRT_JIT_INTRINSIC _ACRTIMP int __cdecl _toupper(_In_ int _C); +_Check_return_ _ACRTIMP int __cdecl _toupper_l(_In_ int _C, _In_opt_ _locale_t _Locale); + +_Check_return_ _ACRTIMP int __cdecl __isascii(_In_ int _C); +_Check_return_ _ACRTIMP int __cdecl __toascii(_In_ int _C); +_Check_return_ _ACRTIMP int __cdecl __iscsymf(_In_ int _C); +_Check_return_ _ACRTIMP int __cdecl __iscsym(_In_ int _C); + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Character Classification Macro Definitions +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +__inline int __CRTDECL __acrt_locale_get_ctype_array_value( + _In_reads_(_Char_value + 1) unsigned short const * const _Locale_pctype_array, + _In_range_(-1, 255) int const _Char_value, + _In_ int const _Mask + ) +{ + // The C Standard specifies valid input to a ctype function ranges from -1 to 255. + // To avoid undefined behavior, we should check this range for all accesses. + // Note _locale_pctype array does extend to -127 to support accessing + // _pctype directly with signed chars. + + if (_Char_value >= -1 && _Char_value <= 255) + { + return _Locale_pctype_array[_Char_value] & _Mask; + } + + return 0; +} + +#ifndef _CTYPE_DISABLE_MACROS + + // Maximum number of bytes in multi-byte character in the current locale + // (also defined in stdlib.h). + #ifndef MB_CUR_MAX + #if defined _CRT_DISABLE_PERFCRIT_LOCKS && !defined _DLL + #define MB_CUR_MAX __mb_cur_max + #else + #define MB_CUR_MAX ___mb_cur_max_func() + #endif + + #ifdef _CRT_DECLARE_GLOBAL_VARIABLES_DIRECTLY + extern int __mb_cur_max; + #else + #define __mb_cur_max (___mb_cur_max_func()) + #endif + + // MB_LEN_MAX = 5 in limits.h but we do not include that header here so use 5 + // directly. + _Post_satisfies_(return > 0 && return < 5) + _ACRTIMP int __cdecl ___mb_cur_max_func(void); + _Post_satisfies_(return > 0 && return < 5) + _ACRTIMP int __cdecl ___mb_cur_max_l_func(_locale_t _Locale); + #endif + + // In the debug CRT, we make all calls through the validation function to catch + // invalid integer inputs that yield undefined behavior. + #ifdef _DEBUG + _ACRTIMP int __cdecl _chvalidator(_In_ int _Ch, _In_ int _Mask); + #define __chvalidchk(a, b) _chvalidator(a, b) + #else + + #define __chvalidchk(a, b) (__acrt_locale_get_ctype_array_value(__PCTYPE_FUNC, (a), (b))) + #endif + + + + #define __ascii_isalpha(c) ( __chvalidchk(c, _ALPHA)) + #define __ascii_isdigit(c) ( __chvalidchk(c, _DIGIT)) + + #ifdef _CRT_DEFINE_ASCII_CTYPE_MACROS + #define __ascii_tolower(c) ( (((c) >= 'A') && ((c) <= 'Z')) ? ((c) - 'A' + 'a') : (c) ) + #define __ascii_toupper(c) ( (((c) >= 'a') && ((c) <= 'z')) ? ((c) - 'a' + 'A') : (c) ) + #define __ascii_iswalpha(c) ( ('A' <= (c) && (c) <= 'Z') || ( 'a' <= (c) && (c) <= 'z')) + #define __ascii_iswdigit(c) ( '0' <= (c) && (c) <= '9') + #define __ascii_towlower(c) ( (((c) >= L'A') && ((c) <= L'Z')) ? ((c) - L'A' + L'a') : (c) ) + #define __ascii_towupper(c) ( (((c) >= L'a') && ((c) <= L'z')) ? ((c) - L'a' + L'A') : (c) ) + #else + __forceinline int __CRTDECL __ascii_tolower(int const _C) + { + if (_C >= 'A' && _C <= 'Z') + { + return _C - ('A' - 'a'); + } + return _C; + } + + __forceinline int __CRTDECL __ascii_toupper(int const _C) + { + if (_C >= 'a' && _C <= 'z') + { + return _C - ('a' - 'A'); + } + return _C; + } + + __forceinline int __CRTDECL __ascii_iswalpha(int const _C) + { + return (_C >= 'A' && _C <= 'Z') || (_C >= 'a' && _C <= 'z'); + } + + __forceinline int __CRTDECL __ascii_iswdigit(int const _C) + { + return _C >= '0' && _C <= '9'; + } + + __forceinline int __CRTDECL __ascii_towlower(int const _C) + { + return __ascii_tolower(_C); + } + + __forceinline int __CRTDECL __ascii_towupper(int const _C) + { + return __ascii_toupper(_C); + } + #endif + + + + #if defined _CRT_DISABLE_PERFCRIT_LOCKS && !defined _DLL && !defined __cplusplus + #define isalpha(c) (MB_CUR_MAX > 1 ? _isctype(c, _ALPHA) : __chvalidchk(c, _ALPHA)) + #define isupper(c) (MB_CUR_MAX > 1 ? _isctype(c, _UPPER) : __chvalidchk(c, _UPPER)) + #define islower(c) (MB_CUR_MAX > 1 ? _isctype(c, _LOWER) : __chvalidchk(c, _LOWER)) + #define isdigit(c) (MB_CUR_MAX > 1 ? _isctype(c, _DIGIT) : __chvalidchk(c, _DIGIT)) + #define isxdigit(c) (MB_CUR_MAX > 1 ? _isctype(c, _HEX) : __chvalidchk(c, _HEX)) + #define isspace(c) (MB_CUR_MAX > 1 ? _isctype(c, _SPACE) : __chvalidchk(c, _SPACE)) + #define ispunct(c) (MB_CUR_MAX > 1 ? _isctype(c, _PUNCT) : __chvalidchk(c, _PUNCT)) + #define isblank(c) (MB_CUR_MAX > 1 ? (((c) == '\t') ? _BLANK : _isctype(c, _BLANK)) : (((c) == '\t') ? _BLANK : __chvalidchk(c, _BLANK))) + #define isalnum(c) (MB_CUR_MAX > 1 ? _isctype(c, _ALPHA | _DIGIT) : __chvalidchk(c, (_ALPHA | _DIGIT))) + #define isprint(c) (MB_CUR_MAX > 1 ? _isctype(c, _BLANK | _PUNCT | _ALPHA | _DIGIT) : __chvalidchk(c, (_BLANK | _PUNCT | _ALPHA | _DIGIT))) + #define isgraph(c) (MB_CUR_MAX > 1 ? _isctype(c, _PUNCT | _ALPHA | _DIGIT) : __chvalidchk(c, (_PUNCT | _ALPHA | _DIGIT))) + #define iscntrl(c) (MB_CUR_MAX > 1 ? _isctype(c, _CONTROL) : __chvalidchk(c, _CONTROL)) + #endif + + __inline __crt_locale_data_public* __CRTDECL __acrt_get_locale_data_prefix(void const volatile* const _LocalePointers) + { + _locale_t const _TypedLocalePointers = (_locale_t)_LocalePointers; + return (__crt_locale_data_public*)_TypedLocalePointers->locinfo; + } + + #ifdef _DEBUG + _ACRTIMP int __cdecl _chvalidator_l(_In_opt_ _locale_t, _In_ int _Ch, _In_ int _Mask); + #endif + + __inline int __CRTDECL _chvalidchk_l( + _In_ int const _C, + _In_ int const _Mask, + _In_opt_ _locale_t const _Locale + ) + { + #ifdef _DEBUG + return _chvalidator_l(_Locale, _C, _Mask); + #else + if (!_Locale) + { + return __chvalidchk(_C, _Mask); + } + + return __acrt_locale_get_ctype_array_value(__acrt_get_locale_data_prefix(_Locale)->_locale_pctype, _C, _Mask); + #endif + } + + #define __ascii_isalpha_l(c, locale) (_chvalidchk_l(c, _ALPHA, locale)) + #define __ascii_isdigit_l(c, locale) (_chvalidchk_l(c, _DIGIT, locale)) + + __inline int __CRTDECL _ischartype_l( + _In_ int const _C, + _In_ int const _Mask, + _In_opt_ _locale_t const _Locale + ) + { + if (!_Locale) + { + return _chvalidchk_l(_C, _Mask, 0); + } + + if (_C >= -1 && _C <= 255) + { + return __acrt_get_locale_data_prefix(_Locale)->_locale_pctype[_C] & _Mask; + } + + if (__acrt_get_locale_data_prefix(_Locale)->_locale_mb_cur_max > 1) + { + return _isctype_l(_C, _Mask, _Locale); + } + + return 0; // >0xFF and SBCS locale + } + + #define _isalpha_l(c, locale) _ischartype_l(c, _ALPHA, locale) + #define _isupper_l(c, locale) _ischartype_l(c, _UPPER, locale) + #define _islower_l(c, locale) _ischartype_l(c, _LOWER, locale) + #define _isdigit_l(c, locale) _ischartype_l(c, _DIGIT, locale) + #define _isxdigit_l(c, locale) _ischartype_l(c, _HEX, locale) + #define _isspace_l(c, locale) _ischartype_l(c, _SPACE, locale) + #define _ispunct_l(c, locale) _ischartype_l(c, _PUNCT, locale) + #define _isblank_l(c, locale) (((c) == '\t') ? _BLANK : _ischartype_l(c, _BLANK, locale)) + #define _isalnum_l(c, locale) _ischartype_l(c, _ALPHA | _DIGIT, locale) + #define _isprint_l(c, locale) _ischartype_l(c, _BLANK | _PUNCT | _ALPHA | _DIGIT, locale) + #define _isgraph_l(c, locale) _ischartype_l(c, _PUNCT | _ALPHA | _DIGIT, locale) + #define _iscntrl_l(c, locale) _ischartype_l(c, _CONTROL, locale) + + #define _tolower(c) ((c) - 'A' + 'a') + #define _toupper(c) ((c) - 'a' + 'A') + + #define __isascii(c) ((unsigned)(c) < 0x80) + #define __toascii(c) ((c) & 0x7f) + + + // Microsoft C version 2.0 extended ctype macros + #define __iscsymf(c) (isalpha(c) || ((c) == '_')) + #define __iscsym(c) (isalnum(c) || ((c) == '_')) + #define __iswcsymf(c) (iswalpha(c) || ((c) == '_')) + #define __iswcsym(c) (iswalnum(c) || ((c) == '_')) + + #define _iscsymf_l(c, p) (_isalpha_l(c, p) || ((c) == '_')) + #define _iscsym_l(c, p) (_isalnum_l(c, p) || ((c) == '_')) + #define _iswcsymf_l(c, p) (iswalpha(c) || ((c) == '_')) + #define _iswcsym_l(c, p) (iswalnum(c) || ((c) == '_')) + +#endif // _CTYPE_DISABLE_MACROS + + +#if defined(_CRT_INTERNAL_NONSTDC_NAMES) && _CRT_INTERNAL_NONSTDC_NAMES + #define isascii __isascii + #define toascii __toascii + #define iscsymf __iscsymf + #define iscsym __iscsym +#endif + + + +#endif // !defined __midl && !defined RC_INVOKED +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS +#endif // _INC_CTYPE diff --git a/sdk/include/ucrt/direct.h b/sdk/include/ucrt/direct.h new file mode 100644 index 0000000000000..45d6fbc3cf5c3 --- /dev/null +++ b/sdk/include/ucrt/direct.h @@ -0,0 +1,131 @@ +// +// direct.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// Functions for directory handling and creation. +// +#pragma once +#ifndef _INC_DIRECT // include guard for 3rd party interop +#define _INC_DIRECT + +#include +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + + + +#ifdef _CRT_USE_WINAPI_FAMILY_DESKTOP_APP + + #ifndef _DISKFREE_T_DEFINED + #define _DISKFREE_T_DEFINED + struct _diskfree_t + { + unsigned total_clusters; + unsigned avail_clusters; + unsigned sectors_per_cluster; + unsigned bytes_per_sector; + }; + #endif + + #if _CRT_FUNCTIONS_REQUIRED + + _Success_(return == 0) + _Check_return_ + _DCRTIMP unsigned __cdecl _getdiskfree( + _In_ unsigned _Drive, + _Out_ struct _diskfree_t* _DiskFree + ); + + _Check_return_ _DCRTIMP int __cdecl _chdrive(_In_ int _Drive); + + _Check_return_ _DCRTIMP int __cdecl _getdrive(void); + + _Check_return_ _DCRTIMP unsigned long __cdecl _getdrives(void); + + #endif // _CRT_FUNCTIONS_REQUIRED +#endif // _CRT_USE_WINAPI_FAMILY_DESKTOP_APP + + + +#pragma push_macro("_getcwd") +#pragma push_macro("_getdcwd") +#undef _getcwd +#undef _getdcwd + +_Success_(return != 0) +_Check_return_ _Ret_maybenull_z_ +_ACRTIMP _CRTALLOCATOR char* __cdecl _getcwd( + _Out_writes_opt_z_(_SizeInBytes) char* _DstBuf, + _In_ int _SizeInBytes + ); + +_Success_(return != 0) +_Check_return_ _Ret_maybenull_z_ +_ACRTIMP _CRTALLOCATOR char* __cdecl _getdcwd( + _In_ int _Drive, + _Out_writes_opt_z_(_SizeInBytes) char* _DstBuf, + _In_ int _SizeInBytes + ); + +#define _getdcwd_nolock _getdcwd + +#pragma pop_macro("_getcwd") +#pragma pop_macro("_getdcwd") + +_Check_return_ _ACRTIMP int __cdecl _chdir(_In_z_ char const* _Path); + +_Check_return_ _ACRTIMP int __cdecl _mkdir(_In_z_ char const* _Path); + +_Check_return_ _ACRTIMP int __cdecl _rmdir(_In_z_ char const* _Path); + + + +#if defined(_CRT_INTERNAL_NONSTDC_NAMES) && _CRT_INTERNAL_NONSTDC_NAMES + + #ifdef _CRT_USE_WINAPI_FAMILY_DESKTOP_APP + + #pragma push_macro("getcwd") + #undef getcwd + + _Success_(return != 0) + _Check_return_ _Ret_maybenull_z_ _CRT_NONSTDC_DEPRECATE(_getcwd) + _DCRTIMP char* __cdecl getcwd( + _Out_writes_opt_z_(_SizeInBytes) char* _DstBuf, + _In_ int _SizeInBytes + ); + + #pragma pop_macro("getcwd") + + _Check_return_ _CRT_NONSTDC_DEPRECATE(_chdir) + _DCRTIMP int __cdecl chdir( + _In_z_ char const* _Path + ); + + #define diskfree_t _diskfree_t + + #endif // _CRT_USE_WINAPI_FAMILY_DESKTOP_APP + + _Check_return_ _CRT_NONSTDC_DEPRECATE(_mkdir) + _ACRTIMP int __cdecl mkdir( + _In_z_ char const* _Path + ); + + _Check_return_ _CRT_NONSTDC_DEPRECATE(_rmdir) + _ACRTIMP int __cdecl rmdir( + _In_z_ char const* _Path + ); + +#endif // _CRT_INTERNAL_NONSTDC_NAMES + + + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS +#endif // _INC_DIRECT diff --git a/sdk/include/ucrt/dos.h b/sdk/include/ucrt/dos.h new file mode 100644 index 0000000000000..7dbe7943c02a8 --- /dev/null +++ b/sdk/include/ucrt/dos.h @@ -0,0 +1,61 @@ +// +// dos.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// This file declares the structures, constants, and functions used for the +// legacy DOS interface. +// +#pragma once +#ifndef _INC_DOS // include guard for 3rd party interop +#define _INC_DOS + +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + +// File attribute constants +#define _A_NORMAL 0x00 // Normal file - No read/write restrictions +#define _A_RDONLY 0x01 // Read only file +#define _A_HIDDEN 0x02 // Hidden file +#define _A_SYSTEM 0x04 // System file +#define _A_SUBDIR 0x10 // Subdirectory +#define _A_ARCH 0x20 // Archive file + +#ifdef _CRT_USE_WINAPI_FAMILY_DESKTOP_APP + + #ifndef _DISKFREE_T_DEFINED + #define _DISKFREE_T_DEFINED + + struct _diskfree_t + { + unsigned total_clusters; + unsigned avail_clusters; + unsigned sectors_per_cluster; + unsigned bytes_per_sector; + }; + #endif + + #if _CRT_FUNCTIONS_REQUIRED + _Success_(return == 0) + _Check_return_ + _DCRTIMP unsigned __cdecl _getdiskfree( + _In_ unsigned _Drive, + _Out_ struct _diskfree_t* _DiskFree + ); + #endif + + #if defined(_CRT_INTERNAL_NONSTDC_NAMES) && _CRT_INTERNAL_NONSTDC_NAMES + #define diskfree_t _diskfree_t + #endif + +#endif + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS +#endif // _INC_DOS diff --git a/sdk/include/ucrt/errno.h b/sdk/include/ucrt/errno.h new file mode 100644 index 0000000000000..7110e905acaaa --- /dev/null +++ b/sdk/include/ucrt/errno.h @@ -0,0 +1,137 @@ +// +// errno.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// System error numbers for use with errno and errno_t. +// +#pragma once +#ifndef _INC_ERRNO // include guard for 3rd party interop +#define _INC_ERRNO + +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + + + +#if _CRT_FUNCTIONS_REQUIRED + _ACRTIMP int* __cdecl _errno(void); + #define errno (*_errno()) + + _ACRTIMP errno_t __cdecl _set_errno(_In_ int _Value); + _ACRTIMP errno_t __cdecl _get_errno(_Out_ int* _Value); + + _ACRTIMP unsigned long* __cdecl __doserrno(void); + #define _doserrno (*__doserrno()) + + _ACRTIMP errno_t __cdecl _set_doserrno(_In_ unsigned long _Value); + _ACRTIMP errno_t __cdecl _get_doserrno(_Out_ unsigned long * _Value); +#endif // _CRT_FUNCTIONS_REQUIRED + + + +// Error codes +#define EPERM 1 +#define ENOENT 2 +#define ESRCH 3 +#define EINTR 4 +#define EIO 5 +#define ENXIO 6 +#define E2BIG 7 +#define ENOEXEC 8 +#define EBADF 9 +#define ECHILD 10 +#define EAGAIN 11 +#define ENOMEM 12 +#define EACCES 13 +#define EFAULT 14 +#define EBUSY 16 +#define EEXIST 17 +#define EXDEV 18 +#define ENODEV 19 +#define ENOTDIR 20 +#define EISDIR 21 +#define ENFILE 23 +#define EMFILE 24 +#define ENOTTY 25 +#define EFBIG 27 +#define ENOSPC 28 +#define ESPIPE 29 +#define EROFS 30 +#define EMLINK 31 +#define EPIPE 32 +#define EDOM 33 +#define EDEADLK 36 +#define ENAMETOOLONG 38 +#define ENOLCK 39 +#define ENOSYS 40 +#define ENOTEMPTY 41 + +// Error codes used in the Secure CRT functions +#ifndef RC_INVOKED + #define _SECURECRT_ERRCODE_VALUES_DEFINED + #define EINVAL 22 + #define ERANGE 34 + #define EILSEQ 42 + #define STRUNCATE 80 +#endif + +// Support EDEADLOCK for compatibility with older Microsoft C versions +#define EDEADLOCK EDEADLK + +// POSIX Supplement +#ifndef _CRT_NO_POSIX_ERROR_CODES + #define EADDRINUSE 100 + #define EADDRNOTAVAIL 101 + #define EAFNOSUPPORT 102 + #define EALREADY 103 + #define EBADMSG 104 + #define ECANCELED 105 + #define ECONNABORTED 106 + #define ECONNREFUSED 107 + #define ECONNRESET 108 + #define EDESTADDRREQ 109 + #define EHOSTUNREACH 110 + #define EIDRM 111 + #define EINPROGRESS 112 + #define EISCONN 113 + #define ELOOP 114 + #define EMSGSIZE 115 + #define ENETDOWN 116 + #define ENETRESET 117 + #define ENETUNREACH 118 + #define ENOBUFS 119 + #define ENODATA 120 + #define ENOLINK 121 + #define ENOMSG 122 + #define ENOPROTOOPT 123 + #define ENOSR 124 + #define ENOSTR 125 + #define ENOTCONN 126 + #define ENOTRECOVERABLE 127 + #define ENOTSOCK 128 + #define ENOTSUP 129 + #define EOPNOTSUPP 130 + #define EOTHER 131 + #define EOVERFLOW 132 + #define EOWNERDEAD 133 + #define EPROTO 134 + #define EPROTONOSUPPORT 135 + #define EPROTOTYPE 136 + #define ETIME 137 + #define ETIMEDOUT 138 + #define ETXTBSY 139 + #define EWOULDBLOCK 140 +#endif // _CRT_NO_POSIX_ERROR_CODES + + + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS +#endif // _INC_ERRNO diff --git a/sdk/include/ucrt/fcntl.h b/sdk/include/ucrt/fcntl.h new file mode 100644 index 0000000000000..0c72b7f2df1fb --- /dev/null +++ b/sdk/include/ucrt/fcntl.h @@ -0,0 +1,68 @@ +// +// fcntl.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// File control options used by _open(). +// +#pragma once +#ifndef _INC_FCNTL // include guard for 3rd party interop +#define _INC_FCNTL + +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +#define _O_RDONLY 0x0000 // open for reading only +#define _O_WRONLY 0x0001 // open for writing only +#define _O_RDWR 0x0002 // open for reading and writing +#define _O_APPEND 0x0008 // writes done at eof + +#define _O_CREAT 0x0100 // create and open file +#define _O_TRUNC 0x0200 // open and truncate +#define _O_EXCL 0x0400 // open only if file doesn't already exist + +// O_TEXT files have sequences translated to on read()'s and +// sequences translated to on write()'s + +#define _O_TEXT 0x4000 // file mode is text (translated) +#define _O_BINARY 0x8000 // file mode is binary (untranslated) +#define _O_WTEXT 0x10000 // file mode is UTF16 (translated) +#define _O_U16TEXT 0x20000 // file mode is UTF16 no BOM (translated) +#define _O_U8TEXT 0x40000 // file mode is UTF8 no BOM (translated) + +// macro to translate the C 2.0 name used to force binary mode for files +#define _O_RAW _O_BINARY + +#define _O_NOINHERIT 0x0080 // child process doesn't inherit file +#define _O_TEMPORARY 0x0040 // temporary file bit (file is deleted when last handle is closed) +#define _O_SHORT_LIVED 0x1000 // temporary storage file, try not to flush +#define _O_OBTAIN_DIR 0x2000 // get information about a directory +#define _O_SEQUENTIAL 0x0020 // file access is primarily sequential +#define _O_RANDOM 0x0010 // file access is primarily random + + + +#if (defined _CRT_DECLARE_NONSTDC_NAMES && _CRT_DECLARE_NONSTDC_NAMES) || (!defined _CRT_DECLARE_NONSTDC_NAMES && !__STDC__) + #define O_RDONLY _O_RDONLY + #define O_WRONLY _O_WRONLY + #define O_RDWR _O_RDWR + #define O_APPEND _O_APPEND + #define O_CREAT _O_CREAT + #define O_TRUNC _O_TRUNC + #define O_EXCL _O_EXCL + #define O_TEXT _O_TEXT + #define O_BINARY _O_BINARY + #define O_RAW _O_BINARY + #define O_TEMPORARY _O_TEMPORARY + #define O_NOINHERIT _O_NOINHERIT + #define O_SEQUENTIAL _O_SEQUENTIAL + #define O_RANDOM _O_RANDOM +#endif + +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS + +#endif // _INC_FCNTL diff --git a/sdk/include/ucrt/fenv.h b/sdk/include/ucrt/fenv.h new file mode 100644 index 0000000000000..37e0ecd411027 --- /dev/null +++ b/sdk/include/ucrt/fenv.h @@ -0,0 +1,169 @@ +// +// fenv.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// Floating point environment library. +// +#pragma once +#ifndef _FENV // include guard for 3rd party interop +#define _FENV + +#include +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + + + +#define FE_TONEAREST _RC_NEAR +#define FE_UPWARD _RC_UP +#define FE_DOWNWARD _RC_DOWN +#define FE_TOWARDZERO _RC_CHOP + +#define FE_ROUND_MASK _MCW_RC + +_ACRTIMP int __cdecl fegetround(void); +_ACRTIMP int __cdecl fesetround(_In_ int _Round); + + + +#if !defined _M_CEE + + typedef unsigned long fexcept_t; + + typedef struct fenv_t + { + unsigned long _Fe_ctl, _Fe_stat; + } fenv_t; + + + + #define FE_INEXACT _SW_INEXACT // _EM_INEXACT 0x00000001 inexact (precision) + #define FE_UNDERFLOW _SW_UNDERFLOW // _EM_UNDERFLOW 0x00000002 underflow + #define FE_OVERFLOW _SW_OVERFLOW // _EM_OVERFLOW 0x00000004 overflow + #define FE_DIVBYZERO _SW_ZERODIVIDE // _EM_ZERODIVIDE 0x00000008 zero divide + #define FE_INVALID _SW_INVALID // _EM_INVALID 0x00000010 invalid + + #define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW) + + _ACRTIMP int __cdecl fegetenv(_Out_ fenv_t* _Env); + _ACRTIMP int __cdecl fesetenv(_In_ fenv_t const* _Env); + _ACRTIMP int __cdecl feclearexcept(_In_ int _Flags); + _ACRTIMP _Success_(return == 0) int __cdecl feholdexcept(_Out_ fenv_t* _Env); + _ACRTIMP int __cdecl fetestexcept(_In_ int _Flags); + _ACRTIMP int __cdecl fegetexceptflag(_Out_ fexcept_t* _Except, _In_ int _TestFlags); + _ACRTIMP int __cdecl fesetexceptflag(_In_ fexcept_t const* _Except, _In_ int _SetFlags); + + #if !defined __midl // MIDL does not support compound initializers + // In the original implementation (_Fenv0), the global variable was zero + // initialized, indicating no exceptions are masked. In the current + // implementation (_Fenv1), the global variable is initialized with all + // exceptions masked, which is the actual initial environment. + #ifdef __cplusplus + #define CPP_EXTERN extern + #else + #define CPP_EXTERN + #endif + #if defined _M_IX86 + CPP_EXTERN __declspec(selectany) const fenv_t _Fenv1 = { 0x3f3f103f, 0 }; + #elif defined _M_X64 + CPP_EXTERN __declspec(selectany) const fenv_t _Fenv1 = { 0x3f00003f, 0 }; + #else + CPP_EXTERN __declspec(selectany) const fenv_t _Fenv1 = { 0x0000003f, 0 }; + #endif + #endif + + #define FE_DFL_ENV (&_Fenv1) + + + + // feraiseexcept is defined inline in this header so that it is compiled + // with the same /arch setting as is specified in the consuming application, + // rather than the /arch:IA32 setting with which the CRT sources are built. + // optimizer has to be turned off to avoid optimizing out since the function + // doesn't have side effects. + // + // feupdateenv is inline because it calls feraiseexcept. + #if _CRT_FUNCTIONS_REQUIRED + #if !defined(_BEGIN_PRAGMA_OPTIMIZE_DISABLE) + #define _BEGIN_PRAGMA_OPTIMIZE_DISABLE(flags, bug, reason) \ + __pragma(optimize(flags, off)) + #define _BEGIN_PRAGMA_OPTIMIZE_ENABLE(flags, bug, reason) \ + __pragma(optimize(flags, on)) + #define _END_PRAGMA_OPTIMIZE() \ + __pragma(optimize("", on)) + #endif + _BEGIN_PRAGMA_OPTIMIZE_DISABLE("", MSFT:4499495, "If optimizations are on, the floating-point exception might not get triggered (because the compiler optimizes it out), breaking the function.") + __inline int __CRTDECL feraiseexcept(_In_ int _Except) + { + static struct + { + int _Except_Val; + double _Num; + double _Denom; + } const _Table[] = + { // Raise exception by evaluating num / denom: + {FE_INVALID, 0.0, 0.0 }, + {FE_DIVBYZERO, 1.0, 0.0 }, + {FE_OVERFLOW, 1e+300, 1e-300 }, + {FE_UNDERFLOW, 1e-300, 1e+300 }, + {FE_INEXACT, 2.0, 3.0 } + }; + + double _Ans = 0.0; + (void) _Ans; // Suppress set-but-not-used warnings. _Ans is not "used" in the traditional static-analysis sense, but it is needed to trigger a floating point exception below. + size_t _Index; + + if ((_Except &= FE_ALL_EXCEPT) == 0) + { + return 0; + } + + // Raise the exceptions not masked: + for (_Index = 0; _Index < sizeof(_Table) / sizeof(_Table[0]); ++_Index) + { + if ((_Except & _Table[_Index]._Except_Val) != 0) + { + _Ans = _Table[_Index]._Num / _Table[_Index]._Denom; + + // x87 exceptions are raised immediately before execution of the + // next floating point instruction. If we're using /arch:IA32, + // force the exception to be raised immediately: + #if defined _M_IX86 && _M_IX86_FP == 0 && !defined _M_HYBRID_X86_ARM64 + #ifdef _MSC_VER + __asm fwait; + #else + __asm__ __volatile__("fwait"); + #endif + #endif + } + } + + return 0; + } + _END_PRAGMA_OPTIMIZE() + + __inline int __CRTDECL feupdateenv(_In_ const fenv_t *_Penv) + { + int _Except = fetestexcept(FE_ALL_EXCEPT); + + if (fesetenv(_Penv) != 0 || feraiseexcept(_Except) != 0) + { + return 1; + } + + return 0; + } + #endif // _CRT_FUNCTIONS_REQUIRED + +#endif // !defined _M_CEE && !defined _CORECRT_BUILD + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS +#endif // _FENV diff --git a/sdk/include/ucrt/float.h b/sdk/include/ucrt/float.h new file mode 100644 index 0000000000000..5c126634e5a90 --- /dev/null +++ b/sdk/include/ucrt/float.h @@ -0,0 +1,409 @@ +// +// float.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// Implementation-defined values commonly used by sophisticated numerical +// (floating point) programs. +// +#pragma once +#ifndef _INC_FLOAT // include guard for 3rd party interop +#define _INC_FLOAT + +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + + + +#ifndef _CRT_MANAGED_FP_DEPRECATE + #ifdef _CRT_MANAGED_FP_NO_DEPRECATE + #define _CRT_MANAGED_FP_DEPRECATE + #else + #ifdef _M_CEE + #define _CRT_MANAGED_FP_DEPRECATE _CRT_DEPRECATE_TEXT("Direct floating point control is not supported or reliable from within managed code. ") + #else + #define _CRT_MANAGED_FP_DEPRECATE + #endif + #endif +#endif + + +// Define the floating point precision used. +// +// For x86, results are in double precision (unless /arch:sse2 is used, in which +// case results are in source precision. +// +// For x64 and ARM, results are in source precision. +// +// If the compiler is invoked with /fp:fast, the compiler is allowed to use the +// fastest precision and even mix within a single function, so precision is +// indeterminable. +// +// Note that manipulating the floating point behavior using the float_control/ +// fenv_access/fp_contract #pragmas may alter the actual floating point evaluation +// method, which may in turn invalidate the value of FLT_EVAL_METHOD. +#ifdef _M_FP_FAST + #define FLT_EVAL_METHOD -1 +#else + #ifdef _M_IX86 + #if _M_IX86_FP >= 2 + #define FLT_EVAL_METHOD 0 + #else + #define FLT_EVAL_METHOD 2 + #endif + #else + #define FLT_EVAL_METHOD 0 + #endif +#endif + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Constants +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#define DBL_DECIMAL_DIG 17 // # of decimal digits of rounding precision +#define DBL_DIG 15 // # of decimal digits of precision +#define DBL_EPSILON 2.2204460492503131e-016 // smallest such that 1.0+DBL_EPSILON != 1.0 +#define DBL_HAS_SUBNORM 1 // type does support subnormal numbers +#define DBL_MANT_DIG 53 // # of bits in mantissa +#define DBL_MAX 1.7976931348623158e+308 // max value +#define DBL_MAX_10_EXP 308 // max decimal exponent +#define DBL_MAX_EXP 1024 // max binary exponent +#define DBL_MIN 2.2250738585072014e-308 // min positive value +#define DBL_MIN_10_EXP (-307) // min decimal exponent +#define DBL_MIN_EXP (-1021) // min binary exponent +#define _DBL_RADIX 2 // exponent radix +#define DBL_TRUE_MIN 4.9406564584124654e-324 // min positive value + +#define FLT_DECIMAL_DIG 9 // # of decimal digits of rounding precision +#define FLT_DIG 6 // # of decimal digits of precision +#define FLT_EPSILON 1.192092896e-07F // smallest such that 1.0+FLT_EPSILON != 1.0 +#define FLT_HAS_SUBNORM 1 // type does support subnormal numbers +#define FLT_GUARD 0 +#define FLT_MANT_DIG 24 // # of bits in mantissa +#define FLT_MAX 3.402823466e+38F // max value +#define FLT_MAX_10_EXP 38 // max decimal exponent +#define FLT_MAX_EXP 128 // max binary exponent +#define FLT_MIN 1.175494351e-38F // min normalized positive value +#define FLT_MIN_10_EXP (-37) // min decimal exponent +#define FLT_MIN_EXP (-125) // min binary exponent +#define FLT_NORMALIZE 0 +#define FLT_RADIX 2 // exponent radix +#define FLT_TRUE_MIN 1.401298464e-45F // min positive value + +#define LDBL_DIG DBL_DIG // # of decimal digits of precision +#define LDBL_EPSILON DBL_EPSILON // smallest such that 1.0+LDBL_EPSILON != 1.0 +#define LDBL_HAS_SUBNORM DBL_HAS_SUBNORM // type does support subnormal numbers +#define LDBL_MANT_DIG DBL_MANT_DIG // # of bits in mantissa +#define LDBL_MAX DBL_MAX // max value +#define LDBL_MAX_10_EXP DBL_MAX_10_EXP // max decimal exponent +#define LDBL_MAX_EXP DBL_MAX_EXP // max binary exponent +#define LDBL_MIN DBL_MIN // min normalized positive value +#define LDBL_MIN_10_EXP DBL_MIN_10_EXP // min decimal exponent +#define LDBL_MIN_EXP DBL_MIN_EXP // min binary exponent +#define _LDBL_RADIX _DBL_RADIX // exponent radix +#define LDBL_TRUE_MIN DBL_TRUE_MIN // min positive value + +#define DECIMAL_DIG DBL_DECIMAL_DIG + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Flags +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#define _SW_INEXACT 0x00000001 // Inexact (precision) +#define _SW_UNDERFLOW 0x00000002 // Underflow +#define _SW_OVERFLOW 0x00000004 // Overflow +#define _SW_ZERODIVIDE 0x00000008 // Divide by zero +#define _SW_INVALID 0x00000010 // Invalid +#define _SW_DENORMAL 0x00080000 // Denormal status bit + +// New Control Bit that specifies the ambiguity in control word. +#define _EM_AMBIGUIOUS 0x80000000 // For backwards compatibility +#define _EM_AMBIGUOUS 0x80000000 + +// Abstract User Control Word Mask and bit definitions +#define _MCW_EM 0x0008001f // Interrupt Exception Masks +#define _EM_INEXACT 0x00000001 // inexact (precision) +#define _EM_UNDERFLOW 0x00000002 // underflow +#define _EM_OVERFLOW 0x00000004 // overflow +#define _EM_ZERODIVIDE 0x00000008 // zero divide +#define _EM_INVALID 0x00000010 // invalid +#define _EM_DENORMAL 0x00080000 // Denormal exception mask (_control87 only) + +#define _MCW_RC 0x00000300 // Rounding Control +#define _RC_NEAR 0x00000000 // near +#define _RC_DOWN 0x00000100 // down +#define _RC_UP 0x00000200 // up +#define _RC_CHOP 0x00000300 // chop + +// i386 specific definitions +#define _MCW_PC 0x00030000 // Precision Control +#define _PC_64 0x00000000 // 64 bits +#define _PC_53 0x00010000 // 53 bits +#define _PC_24 0x00020000 // 24 bits + +#define _MCW_IC 0x00040000 // Infinity Control +#define _IC_AFFINE 0x00040000 // affine +#define _IC_PROJECTIVE 0x00000000 // projective + +// RISC specific definitions +#define _MCW_DN 0x03000000 // Denormal Control +#define _DN_SAVE 0x00000000 // save denormal results and operands +#define _DN_FLUSH 0x01000000 // flush denormal results and operands to zero +#define _DN_FLUSH_OPERANDS_SAVE_RESULTS 0x02000000 // flush operands to zero and save results +#define _DN_SAVE_OPERANDS_FLUSH_RESULTS 0x03000000 // save operands and flush results to zero + + + +// Invalid subconditions (_SW_INVALID also set) +#define _SW_UNEMULATED 0x0040 // Unemulated instruction +#define _SW_SQRTNEG 0x0080 // Square root of a negative number +#define _SW_STACKOVERFLOW 0x0200 // FP stack overflow +#define _SW_STACKUNDERFLOW 0x0400 // FP stack underflow + + + +// Floating point error signals and return codes +#define _FPE_INVALID 0x81 +#define _FPE_DENORMAL 0x82 +#define _FPE_ZERODIVIDE 0x83 +#define _FPE_OVERFLOW 0x84 +#define _FPE_UNDERFLOW 0x85 +#define _FPE_INEXACT 0x86 + +#define _FPE_UNEMULATED 0x87 +#define _FPE_SQRTNEG 0x88 +#define _FPE_STACKOVERFLOW 0x8a +#define _FPE_STACKUNDERFLOW 0x8b + +#define _FPE_EXPLICITGEN 0x8c // raise(SIGFPE); + +// On x86 with arch:SSE2, the OS returns these exceptions +#define _FPE_MULTIPLE_TRAPS 0x8d +#define _FPE_MULTIPLE_FAULTS 0x8e + + + +#define _FPCLASS_SNAN 0x0001 // signaling NaN +#define _FPCLASS_QNAN 0x0002 // quiet NaN +#define _FPCLASS_NINF 0x0004 // negative infinity +#define _FPCLASS_NN 0x0008 // negative normal +#define _FPCLASS_ND 0x0010 // negative denormal +#define _FPCLASS_NZ 0x0020 // -0 +#define _FPCLASS_PZ 0x0040 // +0 +#define _FPCLASS_PD 0x0080 // positive denormal +#define _FPCLASS_PN 0x0100 // positive normal +#define _FPCLASS_PINF 0x0200 // positive infinity + + + +// Initial Control Word value +#if defined _M_IX86 + + #define _CW_DEFAULT (_RC_NEAR + _PC_53 + _EM_INVALID + _EM_ZERODIVIDE + _EM_OVERFLOW + _EM_UNDERFLOW + _EM_INEXACT + _EM_DENORMAL) + +#elif defined _M_X64 || defined _M_ARM || defined _M_ARM64 + + #define _CW_DEFAULT (_RC_NEAR + _EM_INVALID + _EM_ZERODIVIDE + _EM_OVERFLOW + _EM_UNDERFLOW + _EM_INEXACT + _EM_DENORMAL) + +#endif + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// State Manipulation +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// Note that reading or writing the floating point control or status words is +// not supported in managed code. +_CRT_MANAGED_FP_DEPRECATE +_ACRTIMP unsigned int __cdecl _clearfp(void); + +#pragma warning(push) +#pragma warning(disable: 4141) // Double deprecation + +_CRT_MANAGED_FP_DEPRECATE _CRT_INSECURE_DEPRECATE(_controlfp_s) +_ACRTIMP unsigned int __cdecl _controlfp( + _In_ unsigned int _NewValue, + _In_ unsigned int _Mask + ); + +#pragma warning(pop) + +_CRT_MANAGED_FP_DEPRECATE +_ACRTIMP void __cdecl _set_controlfp( + _In_ unsigned int _NewValue, + _In_ unsigned int _Mask + ); + +_CRT_MANAGED_FP_DEPRECATE +_ACRTIMP errno_t __cdecl _controlfp_s( + _Out_opt_ unsigned int* _CurrentState, + _In_ unsigned int _NewValue, + _In_ unsigned int _Mask + ); + +_CRT_MANAGED_FP_DEPRECATE +_ACRTIMP unsigned int __cdecl _statusfp(void); + +_CRT_MANAGED_FP_DEPRECATE +_ACRTIMP void __cdecl _fpreset(void); + +#ifdef _M_IX86 + + _CRT_MANAGED_FP_DEPRECATE + _ACRTIMP void __cdecl _statusfp2( + _Out_opt_ unsigned int* _X86Status, + _Out_opt_ unsigned int* _SSE2Status + ); + +#endif + +#define _clear87 _clearfp +#define _status87 _statusfp + +_CRT_MANAGED_FP_DEPRECATE +_ACRTIMP unsigned int __cdecl _control87( + _In_ unsigned int _NewValue, + _In_ unsigned int _Mask + ); + +#ifdef _M_IX86 + _CRT_MANAGED_FP_DEPRECATE + _ACRTIMP int __cdecl __control87_2( + _In_ unsigned int _NewValue, + _In_ unsigned int _Mask, + _Out_opt_ unsigned int* _X86ControlWord, + _Out_opt_ unsigned int* _Sse2ControlWord + ); +#endif + +// Global variable holding floating point error code +_Check_return_ +_ACRTIMP int* __cdecl __fpecode(void); + +#define _fpecode (*__fpecode()) + +_Check_return_ +_ACRTIMP int __cdecl __fpe_flt_rounds(void); + +#define FLT_ROUNDS (__fpe_flt_rounds()) +#define _DBL_ROUNDS FLT_ROUNDS +#define _LDBL_ROUNDS _DBL_ROUNDS + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// IEEE Recommended Functions +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +_Check_return_ _ACRTIMP double __cdecl _copysign(_In_ double _Number, _In_ double _Sign); +_Check_return_ _ACRTIMP double __cdecl _chgsign(_In_ double _X); +_Check_return_ _ACRTIMP double __cdecl _scalb(_In_ double _X, _In_ long _Y); +_Check_return_ _ACRTIMP double __cdecl _logb(_In_ double _X); +_Check_return_ _ACRTIMP double __cdecl _nextafter(_In_ double _X, _In_ double _Y); +_Check_return_ _ACRTIMP int __cdecl _finite(_In_ double _X); +_Check_return_ _ACRTIMP int __cdecl _isnan(_In_ double _X); +_Check_return_ _ACRTIMP int __cdecl _fpclass(_In_ double _X); + +#ifdef _M_X64 + _Check_return_ _ACRTIMP float __cdecl _scalbf(_In_ float _X, _In_ long _Y); +#endif + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Nonstandard Names for Compatibility +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#if defined(_CRT_INTERNAL_NONSTDC_NAMES) && _CRT_INTERNAL_NONSTDC_NAMES + + #define clear87 _clear87 + #define status87 _status87 + #define control87 _control87 + + _CRT_MANAGED_FP_DEPRECATE + _ACRTIMP void __cdecl fpreset(void); + + #define DBL_RADIX _DBL_RADIX + #define DBL_ROUNDS _DBL_ROUNDS + + #define LDBL_RADIX _LDBL_RADIX + #define LDBL_ROUNDS _LDBL_ROUNDS + + // For backwards compatibility with the old spelling + #define EM_AMBIGUIOUS _EM_AMBIGUOUS + #define EM_AMBIGUOUS _EM_AMBIGUOUS + + #define MCW_EM _MCW_EM + #define EM_INVALID _EM_INVALID + #define EM_DENORMAL _EM_DENORMAL + #define EM_ZERODIVIDE _EM_ZERODIVIDE + #define EM_OVERFLOW _EM_OVERFLOW + #define EM_UNDERFLOW _EM_UNDERFLOW + #define EM_INEXACT _EM_INEXACT + + #define MCW_IC _MCW_IC + #define IC_AFFINE _IC_AFFINE + #define IC_PROJECTIVE _IC_PROJECTIVE + + #define MCW_RC _MCW_RC + #define RC_CHOP _RC_CHOP + #define RC_UP _RC_UP + #define RC_DOWN _RC_DOWN + #define RC_NEAR _RC_NEAR + + #define MCW_PC _MCW_PC + #define PC_24 _PC_24 + #define PC_53 _PC_53 + #define PC_64 _PC_64 + + #define CW_DEFAULT _CW_DEFAULT + + #define SW_INVALID _SW_INVALID + #define SW_DENORMAL _SW_DENORMAL + #define SW_ZERODIVIDE _SW_ZERODIVIDE + #define SW_OVERFLOW _SW_OVERFLOW + #define SW_UNDERFLOW _SW_UNDERFLOW + #define SW_INEXACT _SW_INEXACT + + #define SW_UNEMULATED _SW_UNEMULATED + #define SW_SQRTNEG _SW_SQRTNEG + #define SW_STACKOVERFLOW _SW_STACKOVERFLOW + #define SW_STACKUNDERFLOW _SW_STACKUNDERFLOW + + #define FPE_INVALID _FPE_INVALID + #define FPE_DENORMAL _FPE_DENORMAL + #define FPE_ZERODIVIDE _FPE_ZERODIVIDE + #define FPE_OVERFLOW _FPE_OVERFLOW + #define FPE_UNDERFLOW _FPE_UNDERFLOW + #define FPE_INEXACT _FPE_INEXACT + + #define FPE_UNEMULATED _FPE_UNEMULATED + #define FPE_SQRTNEG _FPE_SQRTNEG + #define FPE_STACKOVERFLOW _FPE_STACKOVERFLOW + #define FPE_STACKUNDERFLOW _FPE_STACKUNDERFLOW + + #define FPE_EXPLICITGEN _FPE_EXPLICITGEN + +#endif // _CRT_INTERNAL_NONSTDC_NAMES + + + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS +#endif // _INC_FLOAT diff --git a/sdk/include/ucrt/fpieee.h b/sdk/include/ucrt/fpieee.h new file mode 100644 index 0000000000000..ea3c3cb520056 --- /dev/null +++ b/sdk/include/ucrt/fpieee.h @@ -0,0 +1,478 @@ +// +// fpieee.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// This file contains constant and type definitions for handling floating point +// exceptions (IEEE 754). +// +#pragma once +#ifndef _INC_FPIEEE // include guard for 3rd party interop +#define _INC_FPIEEE + +#ifndef __midl + +#ifdef _M_CEE_PURE + #error ERROR: This file is not supported in the pure mode! +#endif + +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + + + +#ifndef __assembler + + // Define floating point IEEE compare result values. + typedef enum + { + _FpCompareEqual, + _FpCompareGreater, + _FpCompareLess, + _FpCompareUnordered + } _FPIEEE_COMPARE_RESULT; + + // Define floating point format and result precision values. + typedef enum + { + _FpFormatFp32, + _FpFormatFp64, + _FpFormatFp80, + _FpFormatFp128, + _FpFormatI16, + _FpFormatI32, + _FpFormatI64, + _FpFormatU16, + _FpFormatU32, + _FpFormatU64, + _FpFormatBcd80, + _FpFormatCompare, + _FpFormatString, + } _FPIEEE_FORMAT; + + // Define operation code values. + typedef enum + { + _FpCodeUnspecified, + _FpCodeAdd, + _FpCodeSubtract, + _FpCodeMultiply, + _FpCodeDivide, + _FpCodeSquareRoot, + _FpCodeRemainder, + _FpCodeCompare, + _FpCodeConvert, + _FpCodeRound, + _FpCodeTruncate, + _FpCodeFloor, + _FpCodeCeil, + _FpCodeAcos, + _FpCodeAsin, + _FpCodeAtan, + _FpCodeAtan2, + _FpCodeCabs, + _FpCodeCos, + _FpCodeCosh, + _FpCodeExp, + _FpCodeFabs, + _FpCodeFmod, + _FpCodeFrexp, + _FpCodeHypot, + _FpCodeLdexp, + _FpCodeLog, + _FpCodeLog10, + _FpCodeModf, + _FpCodePow, + _FpCodeSin, + _FpCodeSinh, + _FpCodeTan, + _FpCodeTanh, + _FpCodeY0, + _FpCodeY1, + _FpCodeYn, + _FpCodeLogb, + _FpCodeNextafter, + _FpCodeNegate, + _FpCodeFmin, // XMMI + _FpCodeFmax, // XMMI + _FpCodeConvertTrunc, // XMMI + _XMMIAddps, // XMMI + _XMMIAddss, + _XMMISubps, + _XMMISubss, + _XMMIMulps, + _XMMIMulss, + _XMMIDivps, + _XMMIDivss, + _XMMISqrtps, + _XMMISqrtss, + _XMMIMaxps, + _XMMIMaxss, + _XMMIMinps, + _XMMIMinss, + _XMMICmpps, + _XMMICmpss, + _XMMIComiss, + _XMMIUComiss, + _XMMICvtpi2ps, + _XMMICvtsi2ss, + _XMMICvtps2pi, + _XMMICvtss2si, + _XMMICvttps2pi, + _XMMICvttss2si, + _XMMIAddsubps, // XMMI for PNI + _XMMIHaddps, // XMMI for PNI + _XMMIHsubps, // XMMI for PNI + _XMMIRoundps, // 66 0F 3A 08 + _XMMIRoundss, // 66 0F 3A 0A + _XMMIDpps, // 66 0F 3A 40 + _XMMI2Addpd, // XMMI2 + _XMMI2Addsd, + _XMMI2Subpd, + _XMMI2Subsd, + _XMMI2Mulpd, + _XMMI2Mulsd, + _XMMI2Divpd, + _XMMI2Divsd, + _XMMI2Sqrtpd, + _XMMI2Sqrtsd, + _XMMI2Maxpd, + _XMMI2Maxsd, + _XMMI2Minpd, + _XMMI2Minsd, + _XMMI2Cmppd, + _XMMI2Cmpsd, + _XMMI2Comisd, + _XMMI2UComisd, + _XMMI2Cvtpd2pi, // 66 2D + _XMMI2Cvtsd2si, // F2 + _XMMI2Cvttpd2pi, // 66 2C + _XMMI2Cvttsd2si, // F2 + _XMMI2Cvtps2pd, // 0F 5A + _XMMI2Cvtss2sd, // F3 + _XMMI2Cvtpd2ps, // 66 + _XMMI2Cvtsd2ss, // F2 + _XMMI2Cvtdq2ps, // 0F 5B + _XMMI2Cvttps2dq, // F3 + _XMMI2Cvtps2dq, // 66 + _XMMI2Cvttpd2dq, // 66 0F E6 + _XMMI2Cvtpd2dq, // F2 + _XMMI2Addsubpd, // 66 0F D0 + _XMMI2Haddpd, // 66 0F 7C + _XMMI2Hsubpd, // 66 0F 7D + _XMMI2Roundpd, // 66 0F 3A 09 + _XMMI2Roundsd, // 66 0F 3A 0B + _XMMI2Dppd, // 66 0F 3A 41 + } _FP_OPERATION_CODE; + +#endif // __assembler + +#ifdef _CORECRT_BUILD + #ifndef __assembler + + #define OP_UNSPEC _FpCodeUnspecified + #define OP_ADD _FpCodeAdd + #define OP_SUB _FpCodeSubtract + #define OP_MUL _FpCodeMultiply + #define OP_DIV _FpCodeDivide + #define OP_REM _FpCodeRemainder + #define OP_COMP _FpCodeCompare + #define OP_CVT _FpCodeConvert + #define OP_RND _FpCodeRound + #define OP_TRUNC _FpCodeTruncate + + #define OP_EXP _FpCodeExp + + #define OP_POW _FpCodePow + #define OP_LOG _FpCodeLog + #define OP_LOG10 _FpCodeLog10 + #define OP_SINH _FpCodeSinh + #define OP_COSH _FpCodeCosh + #define OP_TANH _FpCodeTanh + #define OP_ASIN _FpCodeAsin + #define OP_ACOS _FpCodeAcos + #define OP_ATAN _FpCodeAtan + #define OP_ATAN2 _FpCodeAtan2 + #define OP_SQRT _FpCodeSquareRoot + #define OP_SIN _FpCodeSin + #define OP_COS _FpCodeCos + #define OP_TAN _FpCodeTan + #define OP_CEIL _FpCodeCeil + #define OP_FLOOR _FpCodeFloor + #define OP_ABS _FpCodeFabs + #define OP_MODF _FpCodeModf + #define OP_LDEXP _FpCodeLdexp + #define OP_CABS _FpCodeCabs + #define OP_HYPOT _FpCodeHypot + #define OP_FMOD _FpCodeFmod + #define OP_FREXP _FpCodeFrexp + #define OP_Y0 _FpCodeY0 + #define OP_Y1 _FpCodeY1 + #define OP_YN _FpCodeYn + + #define OP_LOGB _FpCodeLogb + #define OP_NEXTAFTER _FpCodeNextafter + + // XMMI + #define OP_ADDPS _XMMIAddps + #define OP_ADDSS _XMMIAddss + #define OP_SUBPS _XMMISubps + #define OP_SUBSS _XMMISubss + #define OP_MULPS _XMMIMulps + #define OP_MULSS _XMMIMulss + #define OP_DIVPS _XMMIDivps + #define OP_DIVSS _XMMIDivss + #define OP_SQRTPS _XMMISqrtps + #define OP_SQRTSS _XMMISqrtss + #define OP_MAXPS _XMMIMaxps + #define OP_MAXSS _XMMIMaxss + #define OP_MINPS _XMMIMinps + #define OP_MINSS _XMMIMinss + #define OP_CMPPS _XMMICmpps + #define OP_CMPSS _XMMICmpss + #define OP_COMISS _XMMIComiss + #define OP_UCOMISS _XMMIUComiss + #define OP_CVTPI2PS _XMMICvtpi2ps + #define OP_CVTSI2SS _XMMICvtsi2ss + #define OP_CVTPS2PI _XMMICvtps2pi + #define OP_CVTSS2SI _XMMICvtss2si + #define OP_CVTTPS2PI _XMMICvttps2pi + #define OP_CVTTSS2SI _XMMICvttss2si + #define OP_ADDSUBPS _XMMIAddsubps + #define OP_HADDPS _XMMIHaddps + #define OP_HSUBPS _XMMIHsubps + #define OP_ROUNDPS _XMMIRoundps + #define OP_ROUNDSS _XMMIRoundss + #define OP_DPPS _XMMIDpps + // XMMI + + // XMMI2 + #define OP_ADDPD _XMMI2Addpd // XMMI2 + #define OP_ADDSD _XMMI2Addsd + #define OP_SUBPD _XMMI2Subpd + #define OP_SUBSD _XMMI2Subsd + #define OP_MULPD _XMMI2Mulpd + #define OP_MULSD _XMMI2Mulsd + #define OP_DIVPD _XMMI2Divpd + #define OP_DIVSD _XMMI2Divsd + #define OP_SQRTPD _XMMI2Sqrtpd + #define OP_SQRTSD _XMMI2Sqrtsd + #define OP_MAXPD _XMMI2Maxpd + #define OP_MAXSD _XMMI2Maxsd + #define OP_MINPD _XMMI2Minpd + #define OP_MINSD _XMMI2Minsd + #define OP_CMPPD _XMMI2Cmppd + #define OP_CMPSD _XMMI2Cmpsd + #define OP_COMISD _XMMI2Comisd + #define OP_UCOMISD _XMMI2UComisd + #define OP_CVTPD2PI _XMMI2Cvtpd2pi // 66 2D + #define OP_CVTSD2SI _XMMI2Cvtsd2si // F2 + #define OP_CVTTPD2PI _XMMI2Cvttpd2pi // 66 2C + #define OP_CVTTSD2SI _XMMI2Cvttsd2si // F2 + #define OP_CVTPS2PD _XMMI2Cvtps2pd // 0F 5A + #define OP_CVTSS2SD _XMMI2Cvtss2sd // F3 + #define OP_CVTPD2PS _XMMI2Cvtpd2ps // 66 + #define OP_CVTSD2SS _XMMI2Cvtsd2ss // F2 + #define OP_CVTDQ2PS _XMMI2Cvtdq2ps // 0F 5B + #define OP_CVTTPS2DQ _XMMI2Cvttps2dq // F3 + #define OP_CVTPS2DQ _XMMI2Cvtps2dq // 66 + #define OP_CVTTPD2DQ _XMMI2Cvttpd2dq // 66 0F E6 + #define OP_CVTPD2DQ _XMMI2Cvtpd2dq // F2 + #define OP_ADDSUBPD _XMMI2Addsubpd // 66 0F D0 + #define OP_HADDPD _XMMI2Haddpd // 66 0F 7C + #define OP_HSUBPD _XMMI2Hsubpd // 66 0F 7D + #define OP_ROUNDPD _XMMI2Roundpd // 66 0F 3A 09 + #define OP_ROUNDSD _XMMI2Roundsd // 66 0F 3A 0B + #define OP_DPPD _XMMI2Dppd // 66 0F 3A 41 + // XMMI2 + + #else // __assembler + + // This must be the same as the enumerator _FP_OPERATION_CODE + #define OP_UNSPEC 0 + #define OP_ADD 1 + #define OP_SUB 2 + #define OP_MUL 3 + #define OP_DIV 4 + #define OP_SQRT 5 + #define OP_REM 6 + #define OP_COMP 7 + #define OP_CVT 8 + #define OP_RND 9 + #define OP_TRUNC 10 + #define OP_FLOOR 11 + #define OP_CEIL 12 + #define OP_ACOS 13 + #define OP_ASIN 14 + #define OP_ATAN 15 + #define OP_ATAN2 16 + #define OP_CABS 17 + #define OP_COS 18 + #define OP_COSH 19 + #define OP_EXP 20 + #define OP_ABS 21 // same as OP_FABS + #define OP_FABS 21 // same as OP_ABS + #define OP_FMOD 22 + #define OP_FREXP 23 + #define OP_HYPOT 24 + #define OP_LDEXP 25 + #define OP_LOG 26 + #define OP_LOG10 27 + #define OP_MODF 28 + #define OP_POW 29 + #define OP_SIN 30 + #define OP_SINH 31 + #define OP_TAN 32 + #define OP_TANH 33 + #define OP_Y0 34 + #define OP_Y1 35 + #define OP_YN 36 + #define OP_LOGB 37 + #define OP_NEXTAFTER 38 + #define OP_NEG 39 + + #endif // __assembler +#endif // _CORECRT_BUILD + +// Define rounding modes. +#ifndef __assembler + + typedef enum + { + _FpRoundNearest, + _FpRoundMinusInfinity, + _FpRoundPlusInfinity, + _FpRoundChopped + } _FPIEEE_ROUNDING_MODE; + + typedef enum + { + _FpPrecisionFull, + _FpPrecision53, + _FpPrecision24, + } _FPIEEE_PRECISION; + + + // Define floating point context record + typedef float _FP32; + typedef double _FP64; + typedef short _I16; + typedef int _I32; + typedef unsigned short _U16; + typedef unsigned int _U32; + typedef __int64 _Q64; + + #ifdef _CORECRT_BUILD + typedef struct + { + unsigned long W[4]; + } _U32ARRAY; + #endif + + typedef struct + { + unsigned short W[5]; + } _FP80; + + typedef struct _CRT_ALIGN(16) + { + unsigned long W[4]; + } _FP128; + + typedef struct _CRT_ALIGN(8) + { + unsigned long W[2]; + } _I64; + + typedef struct _CRT_ALIGN(8) + { + unsigned long W[2]; + } _U64; + + typedef struct + { + unsigned short W[5]; + } _BCD80; + + typedef struct _CRT_ALIGN(16) + { + _Q64 W[2]; + } _FPQ64; + + typedef struct + { + union + { + _FP32 Fp32Value; + _FP64 Fp64Value; + _FP80 Fp80Value; + _FP128 Fp128Value; + _I16 I16Value; + _I32 I32Value; + _I64 I64Value; + _U16 U16Value; + _U32 U32Value; + _U64 U64Value; + _BCD80 Bcd80Value; + char *StringValue; + int CompareValue; + #ifdef _CORECRT_BUILD + _U32ARRAY U32ArrayValue; + #endif + _Q64 Q64Value; + _FPQ64 Fpq64Value; + } Value; + + unsigned int OperandValid : 1; + unsigned int Format : 4; + + } _FPIEEE_VALUE; + + typedef struct + { + unsigned int Inexact : 1; + unsigned int Underflow : 1; + unsigned int Overflow : 1; + unsigned int ZeroDivide : 1; + unsigned int InvalidOperation : 1; + } _FPIEEE_EXCEPTION_FLAGS; + + + typedef struct + { + unsigned int RoundingMode : 2; + unsigned int Precision : 3; + unsigned int Operation : 12; + _FPIEEE_EXCEPTION_FLAGS Cause; + _FPIEEE_EXCEPTION_FLAGS Enable; + _FPIEEE_EXCEPTION_FLAGS Status; + _FPIEEE_VALUE Operand1; + _FPIEEE_VALUE Operand2; + _FPIEEE_VALUE Result; + } _FPIEEE_RECORD, *_PFPIEEE_RECORD; + + + struct _EXCEPTION_POINTERS; + + typedef int (__cdecl* _FpieeFltHandlerType)(_FPIEEE_RECORD*); + + // Floating point IEEE exception filter routine + _ACRTIMP int __cdecl _fpieee_flt( + _In_ unsigned long _ExceptionCode, + _In_ struct _EXCEPTION_POINTERS* _PtExceptionPtr, + _In_ _FpieeFltHandlerType _Handler + ); + +#endif // __assembler + +_CRT_END_C_HEADER + +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS +#endif // __midl +#endif // _INC_FPIEEE diff --git a/sdk/include/ucrt/inttypes.h b/sdk/include/ucrt/inttypes.h new file mode 100644 index 0000000000000..7e2f2f33bb27a --- /dev/null +++ b/sdk/include/ucrt/inttypes.h @@ -0,0 +1,341 @@ +// +// inttypes.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// Various integer format specifier macros for use with the stdio library, and +// various integer conversion and manipulation functions. +// +#pragma once +#ifndef _INTTYPES // include guard for 3rd party interop +#define _INTTYPES + +#include +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Types +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +typedef struct +{ + intmax_t quot; + intmax_t rem; +} _Lldiv_t; + +typedef _Lldiv_t imaxdiv_t; + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Functions +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +_Check_return_ +_ACRTIMP intmax_t __cdecl imaxabs( + _In_ intmax_t _Number + ); + +_Check_return_ +_ACRTIMP imaxdiv_t __cdecl imaxdiv( + _In_ intmax_t _Numerator, + _In_ intmax_t _Denominator + ); + +_ACRTIMP intmax_t __cdecl strtoimax( + _In_z_ char const* _String, + _Out_opt_ _Deref_post_z_ char** _EndPtr, + _In_ int _Radix + ); + +_ACRTIMP intmax_t __cdecl _strtoimax_l( + _In_z_ char const* _String, + _Out_opt_ _Deref_post_z_ char** _EndPtr, + _In_ int _Radix, + _In_opt_ _locale_t _Locale + ); + +_ACRTIMP uintmax_t __cdecl strtoumax( + _In_z_ char const* _String, + _Out_opt_ _Deref_post_z_ char** _EndPtr, + _In_ int _Radix + ); + +_ACRTIMP uintmax_t __cdecl _strtoumax_l( + _In_z_ char const* _String, + _Out_opt_ _Deref_post_z_ char** _EndPtr, + _In_ int _Radix, + _In_opt_ _locale_t _Locale + ); + +_ACRTIMP intmax_t __cdecl wcstoimax( + _In_z_ wchar_t const* _String, + _Out_opt_ _Deref_post_z_ wchar_t** _EndPtr, + _In_ int _Radix + ); + +_ACRTIMP intmax_t __cdecl _wcstoimax_l( + _In_z_ wchar_t const* _String, + _Out_opt_ _Deref_post_z_ wchar_t** _EndPtr, + _In_ int _Radix, + _In_opt_ _locale_t _Locale + ); + +_ACRTIMP uintmax_t __cdecl wcstoumax( + _In_z_ wchar_t const* _String, + _Out_opt_ _Deref_post_z_ wchar_t** _EndPtr, + _In_ int _Radix + ); + +_ACRTIMP uintmax_t __cdecl _wcstoumax_l( + _In_z_ wchar_t const* _String, + _Out_opt_ _Deref_post_z_ wchar_t** _EndPtr, + _In_ int _Radix, + _In_opt_ _locale_t _Locale + ); + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Output Format Specifier Macros +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#define PRId8 "hhd" +#define PRId16 "hd" +#define PRId32 "d" +#define PRId64 "lld" +#define PRIdLEAST8 PRId8 +#define PRIdLEAST16 PRId16 +#define PRIdLEAST32 PRId32 +#define PRIdLEAST64 PRId64 +#define PRIdFAST8 PRId8 +#define PRIdFAST16 PRId32 +#define PRIdFAST32 PRId32 +#define PRIdFAST64 PRId64 +#define PRIdMAX PRId64 +#ifdef _WIN64 + #define PRIdPTR PRId64 +#else + #define PRIdPTR PRId32 +#endif + +#define PRIi8 "hhi" +#define PRIi16 "hi" +#define PRIi32 "i" +#define PRIi64 "lli" +#define PRIiLEAST8 PRIi8 +#define PRIiLEAST16 PRIi16 +#define PRIiLEAST32 PRIi32 +#define PRIiLEAST64 PRIi64 +#define PRIiFAST8 PRIi8 +#define PRIiFAST16 PRIi32 +#define PRIiFAST32 PRIi32 +#define PRIiFAST64 PRIi64 +#define PRIiMAX PRIi64 +#ifdef _WIN64 + #define PRIiPTR PRIi64 +#else + #define PRIiPTR PRIi32 +#endif + +#define PRIo8 "hho" +#define PRIo16 "ho" +#define PRIo32 "o" +#define PRIo64 "llo" +#define PRIoLEAST8 PRIo8 +#define PRIoLEAST16 PRIo16 +#define PRIoLEAST32 PRIo32 +#define PRIoLEAST64 PRIo64 +#define PRIoFAST8 PRIo8 +#define PRIoFAST16 PRIo32 +#define PRIoFAST32 PRIo32 +#define PRIoFAST64 PRIo64 +#define PRIoMAX PRIo64 +#ifdef _WIN64 + #define PRIoPTR PRIo64 +#else + #define PRIoPTR PRIo32 +#endif + +#define PRIu8 "hhu" +#define PRIu16 "hu" +#define PRIu32 "u" +#define PRIu64 "llu" +#define PRIuLEAST8 PRIu8 +#define PRIuLEAST16 PRIu16 +#define PRIuLEAST32 PRIu32 +#define PRIuLEAST64 PRIu64 +#define PRIuFAST8 PRIu8 +#define PRIuFAST16 PRIu32 +#define PRIuFAST32 PRIu32 +#define PRIuFAST64 PRIu64 +#define PRIuMAX PRIu64 +#ifdef _WIN64 + #define PRIuPTR PRIu64 +#else + #define PRIuPTR PRIu32 +#endif + +#define PRIx8 "hhx" +#define PRIx16 "hx" +#define PRIx32 "x" +#define PRIx64 "llx" +#define PRIxLEAST8 PRIx8 +#define PRIxLEAST16 PRIx16 +#define PRIxLEAST32 PRIx32 +#define PRIxLEAST64 PRIx64 +#define PRIxFAST8 PRIx8 +#define PRIxFAST16 PRIx32 +#define PRIxFAST32 PRIx32 +#define PRIxFAST64 PRIx64 +#define PRIxMAX PRIx64 +#ifdef _WIN64 + #define PRIxPTR PRIx64 +#else + #define PRIxPTR PRIx32 +#endif + +#define PRIX8 "hhX" +#define PRIX16 "hX" +#define PRIX32 "X" +#define PRIX64 "llX" +#define PRIXLEAST8 PRIX8 +#define PRIXLEAST16 PRIX16 +#define PRIXLEAST32 PRIX32 +#define PRIXLEAST64 PRIX64 +#define PRIXFAST8 PRIX8 +#define PRIXFAST16 PRIX32 +#define PRIXFAST32 PRIX32 +#define PRIXFAST64 PRIX64 +#define PRIXMAX PRIX64 +#ifdef _WIN64 + #define PRIXPTR PRIX64 +#else + #define PRIXPTR PRIX32 +#endif + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Input Format Specifier Macros +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#define SCNd8 "hhd" +#define SCNd16 "hd" +#define SCNd32 "d" +#define SCNd64 "lld" +#define SCNdLEAST8 SCNd8 +#define SCNdLEAST16 SCNd16 +#define SCNdLEAST32 SCNd32 +#define SCNdLEAST64 SCNd64 +#define SCNdFAST8 SCNd8 +#define SCNdFAST16 SCNd32 +#define SCNdFAST32 SCNd32 +#define SCNdFAST64 SCNd64 +#define SCNdMAX SCNd64 +#ifdef _WIN64 + #define SCNdPTR SCNd64 +#else + #define SCNdPTR SCNd32 +#endif + +#define SCNi8 "hhi" +#define SCNi16 "hi" +#define SCNi32 "i" +#define SCNi64 "lli" +#define SCNiLEAST8 SCNi8 +#define SCNiLEAST16 SCNi16 +#define SCNiLEAST32 SCNi32 +#define SCNiLEAST64 SCNi64 +#define SCNiFAST8 SCNi8 +#define SCNiFAST16 SCNi32 +#define SCNiFAST32 SCNi32 +#define SCNiFAST64 SCNi64 +#define SCNiMAX SCNi64 +#ifdef _WIN64 + #define SCNiPTR SCNi64 +#else + #define SCNiPTR SCNi32 +#endif + +#define SCNo8 "hho" +#define SCNo16 "ho" +#define SCNo32 "o" +#define SCNo64 "llo" +#define SCNoLEAST8 SCNo8 +#define SCNoLEAST16 SCNo16 +#define SCNoLEAST32 SCNo32 +#define SCNoLEAST64 SCNo64 +#define SCNoFAST8 SCNo8 +#define SCNoFAST16 SCNo32 +#define SCNoFAST32 SCNo32 +#define SCNoFAST64 SCNo64 +#define SCNoMAX SCNo64 +#ifdef _WIN64 + #define SCNoPTR SCNo64 +#else + #define SCNoPTR SCNo32 +#endif + +#define SCNu8 "hhu" +#define SCNu16 "hu" +#define SCNu32 "u" +#define SCNu64 "llu" +#define SCNuLEAST8 SCNu8 +#define SCNuLEAST16 SCNu16 +#define SCNuLEAST32 SCNu32 +#define SCNuLEAST64 SCNu64 +#define SCNuFAST8 SCNu8 +#define SCNuFAST16 SCNu32 +#define SCNuFAST32 SCNu32 +#define SCNuFAST64 SCNu64 +#define SCNuMAX SCNu64 +#ifdef _WIN64 + #define SCNuPTR SCNu64 +#else + #define SCNuPTR SCNu32 +#endif + +#define SCNx8 "hhx" +#define SCNx16 "hx" +#define SCNx32 "x" +#define SCNx64 "llx" +#define SCNxLEAST8 SCNx8 +#define SCNxLEAST16 SCNx16 +#define SCNxLEAST32 SCNx32 +#define SCNxLEAST64 SCNx64 +#define SCNxFAST8 SCNx8 +#define SCNxFAST16 SCNx32 +#define SCNxFAST32 SCNx32 +#define SCNxFAST64 SCNx64 +#define SCNxMAX SCNx64 +#ifdef _WIN64 + #define SCNxPTR SCNx64 +#else + #define SCNxPTR SCNx32 +#endif + + + +_CRT_END_C_HEADER + +/* + * Copyright (c) 1992-2010 by P.J. Plauger. ALL RIGHTS RESERVED. + * Consult your license regarding permissions and restrictions. +V5.30:0009 */ + +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS +#endif // _INTTYPES diff --git a/sdk/include/ucrt/io.h b/sdk/include/ucrt/io.h new file mode 100644 index 0000000000000..94cde082b2bcf --- /dev/null +++ b/sdk/include/ucrt/io.h @@ -0,0 +1,13 @@ +// +// io.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// This file declares the low-level I/O and file handling functionality. +// +#pragma once +#ifndef _INC_IO // include guard for 3rd party interop +#define _INC_IO + +#include +#endif // _INC_IO diff --git a/sdk/include/ucrt/locale.h b/sdk/include/ucrt/locale.h new file mode 100644 index 0000000000000..a60971cd0549c --- /dev/null +++ b/sdk/include/ucrt/locale.h @@ -0,0 +1,184 @@ +// +// locale.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The C locale library. +// +#pragma once +#ifndef _INC_LOCALE // include guard for 3rd party interop +#define _INC_LOCALE + +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + + + +// Locale categories +#define LC_ALL 0 +#define LC_COLLATE 1 +#define LC_CTYPE 2 +#define LC_MONETARY 3 +#define LC_NUMERIC 4 +#define LC_TIME 5 + +#define LC_MIN LC_ALL +#define LC_MAX LC_TIME + +// Locale convention structure +struct lconv +{ + char* decimal_point; + char* thousands_sep; + char* grouping; + char* int_curr_symbol; + char* currency_symbol; + char* mon_decimal_point; + char* mon_thousands_sep; + char* mon_grouping; + char* positive_sign; + char* negative_sign; + char int_frac_digits; + char frac_digits; + char p_cs_precedes; + char p_sep_by_space; + char n_cs_precedes; + char n_sep_by_space; + char p_sign_posn; + char n_sign_posn; + wchar_t* _W_decimal_point; + wchar_t* _W_thousands_sep; + wchar_t* _W_int_curr_symbol; + wchar_t* _W_currency_symbol; + wchar_t* _W_mon_decimal_point; + wchar_t* _W_mon_thousands_sep; + wchar_t* _W_positive_sign; + wchar_t* _W_negative_sign; +}; + +struct tm; + +// ANSI: char lconv members default is CHAR_MAX which is compile time dependent. +// Defining and using __do_unsigned_char_lconv_initialization here causes CRT +// startup code to initialize lconv members properly +#ifdef _CHAR_UNSIGNED + extern int __do_unsigned_char_lconv_initialization; + extern __inline int __use_char_max(void) + { + return __do_unsigned_char_lconv_initialization; + } +#endif + + + +#define _ENABLE_PER_THREAD_LOCALE 0x0001 +#define _DISABLE_PER_THREAD_LOCALE 0x0002 +#define _ENABLE_PER_THREAD_LOCALE_GLOBAL 0x0010 +#define _DISABLE_PER_THREAD_LOCALE_GLOBAL 0x0020 +#define _ENABLE_PER_THREAD_LOCALE_NEW 0x0100 +#define _DISABLE_PER_THREAD_LOCALE_NEW 0x0200 + +#if _CRT_FUNCTIONS_REQUIRED + + _ACRTIMP void __cdecl _lock_locales(void); + _ACRTIMP void __cdecl _unlock_locales(void); + + _Check_return_opt_ + _ACRTIMP int __cdecl _configthreadlocale( + _In_ int _Flag + ); + + _Check_return_opt_ _Success_(return != 0) _Ret_z_ + _ACRTIMP char* __cdecl setlocale( + _In_ int _Category, + _In_opt_z_ char const* _Locale + ); + + _Check_return_opt_ + _ACRTIMP struct lconv* __cdecl localeconv(void); + + _Check_return_opt_ + _ACRTIMP _locale_t __cdecl _get_current_locale(void); + + _Check_return_opt_ + _ACRTIMP _locale_t __cdecl _create_locale( + _In_ int _Category, + _In_z_ char const* _Locale + ); + + _ACRTIMP void __cdecl _free_locale( + _In_opt_ _locale_t _Locale + ); + + // Also declared in + _Check_return_opt_ _Success_(return != 0) _Ret_z_ + _ACRTIMP wchar_t* __cdecl _wsetlocale( + _In_ int _Category, + _In_opt_z_ wchar_t const* _Locale + ); + + _Check_return_opt_ + _ACRTIMP _locale_t __cdecl _wcreate_locale( + _In_ int _Category, + _In_z_ wchar_t const* _Locale + ); + + + + _ACRTIMP wchar_t** __cdecl ___lc_locale_name_func(void); + _ACRTIMP unsigned int __cdecl ___lc_codepage_func (void); + _ACRTIMP unsigned int __cdecl ___lc_collate_cp_func (void); + + + + + // Time-related functions + _Success_(return != 0) + _Ret_z_ + _ACRTIMP char* __cdecl _Getdays(void); + + _Success_(return != 0) + _Ret_z_ + _ACRTIMP char* __cdecl _Getmonths(void); + + _ACRTIMP void* __cdecl _Gettnames(void); + + _Success_(return != 0) + _Ret_z_ + _ACRTIMP wchar_t* __cdecl _W_Getdays(void); + + _Success_(return != 0) + _Ret_z_ + _ACRTIMP wchar_t* __cdecl _W_Getmonths(void); + + _ACRTIMP void* __cdecl _W_Gettnames(void); + + _Success_(return > 0) + _ACRTIMP size_t __cdecl _Strftime( + _Out_writes_z_(_Max_size) char* _Buffer, + _In_ size_t _Max_size, + _In_z_ char const* _Format, + _In_ struct tm const* _Timeptr, + _In_opt_ void* _Lc_time_arg); + + _Success_(return > 0) + _ACRTIMP size_t __cdecl _Wcsftime( + _Out_writes_z_(_Max_size) wchar_t* _Buffer, + _In_ size_t _Max_size, + _In_z_ wchar_t const* _Format, + _In_ struct tm const* _Timeptr, + _In_opt_ void* _Lc_time_arg + ); + +#endif // _CRT_FUNCTIONS_REQUIRED + + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS +#endif // _INC_LOCALE diff --git a/sdk/include/ucrt/malloc.h b/sdk/include/ucrt/malloc.h new file mode 100644 index 0000000000000..20abe3fe9295f --- /dev/null +++ b/sdk/include/ucrt/malloc.h @@ -0,0 +1,187 @@ +// +// malloc.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The memory allocation library. +// +#pragma once +#ifndef _INC_MALLOC // include guard for 3rd party interop +#define _INC_MALLOC + +#include +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + + + +// Maximum heap request the heap manager will attempt +#ifdef _WIN64 + #define _HEAP_MAXREQ 0xFFFFFFFFFFFFFFE0 +#else + #define _HEAP_MAXREQ 0xFFFFFFE0 +#endif + + + +// Constants for _heapchk and _heapwalk routines +#define _HEAPEMPTY (-1) +#define _HEAPOK (-2) +#define _HEAPBADBEGIN (-3) +#define _HEAPBADNODE (-4) +#define _HEAPEND (-5) +#define _HEAPBADPTR (-6) +#define _FREEENTRY 0 +#define _USEDENTRY 1 + +typedef struct _heapinfo +{ + int* _pentry; + size_t _size; + int _useflag; +} _HEAPINFO; + +#define _mm_free(a) _aligned_free(a) +#define _mm_malloc(a, b) _aligned_malloc(a, b) + + +#if defined(__GNUC__) || defined(__clang__) +#define _alloca(x) __builtin_alloca((x)) +#else +_Ret_notnull_ _Post_writable_byte_size_(_Size) +void* __cdecl _alloca(_In_ size_t _Size); +#endif + + + +#if !defined __midl && !defined RC_INVOKED + + _ACRTIMP intptr_t __cdecl _get_heap_handle(void); + + _Check_return_ + _DCRTIMP int __cdecl _heapmin(void); + + #if defined _DEBUG || defined _CRT_USE_WINAPI_FAMILY_DESKTOP_APP || defined _CORECRT_BUILD + _ACRTIMP int __cdecl _heapwalk(_Inout_ _HEAPINFO* _EntryInfo); + #endif + + #if defined _CRT_USE_WINAPI_FAMILY_DESKTOP_APP || defined _CRT_USE_WINAPI_FAMILY_GAMES + _Check_return_ _DCRTIMP int __cdecl _heapchk(void); + #endif + + _DCRTIMP int __cdecl _resetstkoflw(void); + + #define _ALLOCA_S_THRESHOLD 1024 + #define _ALLOCA_S_STACK_MARKER 0xCCCC + #define _ALLOCA_S_HEAP_MARKER 0xDDDD + + #ifdef _WIN64 + #define _ALLOCA_S_MARKER_SIZE 16 + #else + #define _ALLOCA_S_MARKER_SIZE 8 + #endif + + _STATIC_ASSERT(sizeof(unsigned int) <= _ALLOCA_S_MARKER_SIZE); + + + #pragma warning(push) + #pragma warning(disable: 6540) // C6540: attribute annotations on this function will invalidate all + // of its existing __declspec annotations + + __inline void* _MarkAllocaS(_Out_opt_ __crt_typefix(unsigned int*) void* _Ptr, unsigned int _Marker) + { + if (_Ptr) + { + *((unsigned int*)_Ptr) = _Marker; + _Ptr = (char*)_Ptr + _ALLOCA_S_MARKER_SIZE; + } + return _Ptr; + } + + __inline size_t _MallocaComputeSize(size_t _Size) + { + size_t _MarkedSize = _Size + _ALLOCA_S_MARKER_SIZE; + return _MarkedSize > _Size ? _MarkedSize : 0; + } + + #pragma warning(pop) + +#endif + + + +#ifdef _DEBUG +// C6255: _alloca indicates failure by raising a stack overflow exception +// C6386: buffer overrun + #ifndef _CRTDBG_MAP_ALLOC + #undef _malloca + #define _malloca(size) \ + __pragma(warning(suppress: 6255 6386)) \ + (_MallocaComputeSize(size) != 0 \ + ? _MarkAllocaS(malloc(_MallocaComputeSize(size)), _ALLOCA_S_HEAP_MARKER) \ + : NULL) + #endif + +#else + + #undef _malloca + #define _malloca(size) \ + __pragma(warning(suppress: 6255 6386)) \ + (_MallocaComputeSize(size) != 0 \ + ? (((_MallocaComputeSize(size) <= _ALLOCA_S_THRESHOLD) \ + ? _MarkAllocaS(_alloca(_MallocaComputeSize(size)), _ALLOCA_S_STACK_MARKER) \ + : _MarkAllocaS(malloc(_MallocaComputeSize(size)), _ALLOCA_S_HEAP_MARKER))) \ + : NULL) + +#endif + + + +#if defined __midl && !defined RC_INVOKED +#elif defined _DEBUG && defined _CRTDBG_MAP_ALLOC +#else + + #undef _freea + + #pragma warning(push) + #pragma warning(disable: 6014) // leaking memory + __inline void __CRTDECL _freea(_Pre_maybenull_ _Post_invalid_ void* _Memory) + { + unsigned int _Marker; + if (_Memory) + { + _Memory = (char*)_Memory - _ALLOCA_S_MARKER_SIZE; + _Marker = *(unsigned int*)_Memory; + if (_Marker == _ALLOCA_S_HEAP_MARKER) + { + free(_Memory); + } + #ifdef _ASSERTE + else if (_Marker != _ALLOCA_S_STACK_MARKER) + { + _ASSERTE(("Corrupted pointer passed to _freea" && 0)); + } + #endif + } + } + #pragma warning(pop) + +#endif + + + +#if defined(_CRT_INTERNAL_NONSTDC_NAMES) && _CRT_INTERNAL_NONSTDC_NAMES + #define alloca _alloca +#endif + + + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS +#endif // _INC_MALLOC diff --git a/sdk/include/ucrt/math.h b/sdk/include/ucrt/math.h new file mode 100644 index 0000000000000..61995ee6076d8 --- /dev/null +++ b/sdk/include/ucrt/math.h @@ -0,0 +1,15 @@ +// +// math.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The C Standard Library header. This header consists of two parts: +// contains the math library; contains +// the nonstandard but useful constant definitions. The headers are divided in +// this way for modularity (to support the C++ modules feature). +// +#include + +#ifdef _USE_MATH_DEFINES + #include +#endif diff --git a/sdk/include/ucrt/mbctype.h b/sdk/include/ucrt/mbctype.h new file mode 100644 index 0000000000000..b62ac4bc3f168 --- /dev/null +++ b/sdk/include/ucrt/mbctype.h @@ -0,0 +1,173 @@ +// +// mbctype.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// Functions and macros for MBCS character classification and conversion. +// +#pragma once +#ifndef _INC_MBCTYPE // include guard for 3rd party interop +#define _INC_MBCTYPE + +#include +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + + + +// This declaration allows the user access the _mbctype[] look-up array. +_Check_return_ _ACRTIMP unsigned char* __cdecl __p__mbctype(void); +_Check_return_ _ACRTIMP unsigned char* __cdecl __p__mbcasemap(void); + +#ifdef _CRT_DECLARE_GLOBAL_VARIABLES_DIRECTLY + #ifndef _CORECRT_BUILD + extern unsigned char _mbctype[]; + extern unsigned char _mbcasemap[]; + #endif +#else + #define _mbctype (__p__mbctype()) + #define _mbcasemap (__p__mbcasemap()) +#endif + + + +// Bit masks for MBCS character types: +// Different encodings may have different behaviors, applications are discouraged +// from attempting to reverse engineer the mechanics of the various encodings. +#define _MS 0x01 // MBCS single-byte symbol +#define _MP 0x02 // MBCS punctuation +#define _M1 0x04 // MBCS (not UTF-8!) 1st (lead) byte +#define _M2 0x08 // MBCS (not UTF-8!) 2nd byte + +// The CRT does not do proper linguistic casing, it is preferred that applications +// use appropriate NLS or Globalization functions. +#define _SBUP 0x10 // SBCS uppercase char +#define _SBLOW 0x20 // SBCS lowercase char + +// Byte types +// Different encodings may have different behaviors, use of these is discouraged +#define _MBC_SINGLE 0 // Valid single byte char +#define _MBC_LEAD 1 // Lead byte +#define _MBC_TRAIL 2 // Trailing byte +#define _MBC_ILLEGAL (-1) // Illegal byte + +#define _KANJI_CP 932 + +// _setmbcp parameter defines: +// Use of UTF-8 is encouraged +#define _MB_CP_SBCS 0 +#define _MB_CP_OEM -2 +#define _MB_CP_ANSI -3 +#define _MB_CP_LOCALE -4 +// CP_UTF8 - UTF-8 was not permitted in earlier CRT versions +#define _MB_CP_UTF8 65001 + +// Multibyte control routines: +_ACRTIMP int __cdecl _setmbcp(_In_ int _CodePage); +_ACRTIMP int __cdecl _getmbcp(void); + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Multibyte Character Classification and Conversion Functions +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#if _CRT_FUNCTIONS_REQUIRED + _Check_return_ _DCRTIMP int __cdecl _ismbbkalnum(_In_ unsigned int _C); + _Check_return_ _DCRTIMP int __cdecl _ismbbkana (_In_ unsigned int _C); + _Check_return_ _DCRTIMP int __cdecl _ismbbkpunct(_In_ unsigned int _C); + _Check_return_ _DCRTIMP int __cdecl _ismbbkprint(_In_ unsigned int _C); + _Check_return_ _DCRTIMP int __cdecl _ismbbalpha (_In_ unsigned int _C); + _Check_return_ _DCRTIMP int __cdecl _ismbbpunct (_In_ unsigned int _C); + _Check_return_ _DCRTIMP int __cdecl _ismbbblank (_In_ unsigned int _C); + _Check_return_ _DCRTIMP int __cdecl _ismbbalnum (_In_ unsigned int _C); + _Check_return_ _DCRTIMP int __cdecl _ismbbprint (_In_ unsigned int _C); + _Check_return_ _DCRTIMP int __cdecl _ismbbgraph (_In_ unsigned int _C); + + _Check_return_ _DCRTIMP int __cdecl _ismbbkalnum_l(_In_ unsigned int _C, _In_opt_ _locale_t _Locale); + _Check_return_ _DCRTIMP int __cdecl _ismbbkana_l (_In_ unsigned int _C, _In_opt_ _locale_t _Locale); + _Check_return_ _DCRTIMP int __cdecl _ismbbkpunct_l(_In_ unsigned int _C, _In_opt_ _locale_t _Locale); + _Check_return_ _DCRTIMP int __cdecl _ismbbkprint_l(_In_ unsigned int _C, _In_opt_ _locale_t _Locale); + _Check_return_ _DCRTIMP int __cdecl _ismbbalpha_l (_In_ unsigned int _C, _In_opt_ _locale_t _Locale); + _Check_return_ _DCRTIMP int __cdecl _ismbbpunct_l (_In_ unsigned int _C, _In_opt_ _locale_t _Locale); + _Check_return_ _DCRTIMP int __cdecl _ismbbblank_l (_In_ unsigned int _C, _In_opt_ _locale_t _Locale); + _Check_return_ _DCRTIMP int __cdecl _ismbbalnum_l (_In_ unsigned int _C, _In_opt_ _locale_t _Locale); + _Check_return_ _DCRTIMP int __cdecl _ismbbprint_l (_In_ unsigned int _C, _In_opt_ _locale_t _Locale); + _Check_return_ _DCRTIMP int __cdecl _ismbbgraph_l (_In_ unsigned int _C, _In_opt_ _locale_t _Locale); + + // BEGIN _MBLEADTRAIL_DEFINED + // Lead and trail bytes do not apply correctly to all encodings, including UTF-8. Applications + // are recommended to use the system codepage conversion APIs and not attempt to reverse + // engineer the behavior of any particular encoding. Lead and trail are always FALSE for UTF-8. + _When_(_Ch == 0, _Post_equal_to_(0)) + _Check_return_ _DCRTIMP int __cdecl _ismbblead (_In_ unsigned int _Ch); + _Check_return_ _DCRTIMP int __cdecl _ismbbtrail(_In_ unsigned int _Ch); + + _When_(_Ch == 0, _Post_equal_to_(0)) + _Check_return_ _DCRTIMP int __cdecl _ismbblead_l (_In_ unsigned int _Ch, _In_opt_ _locale_t _Locale); + _Check_return_ _DCRTIMP int __cdecl _ismbbtrail_l(_In_ unsigned int _Ch, _In_opt_ _locale_t _Locale); + + _Check_return_ + _DCRTIMP int __cdecl _ismbslead( + _In_reads_z_(_Pos - _String + 1) unsigned char const* _String, + _In_z_ unsigned char const* _Pos + ); + + _Check_return_ + _DCRTIMP int __cdecl _ismbslead_l( + _In_reads_z_(_Pos - _String + 1) unsigned char const* _String, + _In_z_ unsigned char const* _Pos, + _In_opt_ _locale_t _Locale + ); + + _Check_return_ + _ACRTIMP int __cdecl _ismbstrail( + _In_reads_z_(_Pos - _String + 1) unsigned char const* _String, + _In_z_ unsigned char const* _Pos + ); + + _Check_return_ + _ACRTIMP int __cdecl _ismbstrail_l( + _In_reads_z_(_Pos - _String + 1) unsigned char const* _String, + _In_z_ unsigned char const* _Pos, + _In_opt_ _locale_t _Locale + ); +#endif // _CRT_FUNCTIONS_REQUIRED + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Unsynchronized Macro Forms of Some Classification Functions +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#if defined _CRT_DISABLE_PERFCRIT_LOCKS && !defined _DLL + #define _ismbbkalnum(_c) ((_mbctype+1)[(unsigned char)(_c)] & (_MS )) + #define _ismbbkprint(_c) ((_mbctype+1)[(unsigned char)(_c)] & (_MS | _MP)) + #define _ismbbkpunct(_c) ((_mbctype+1)[(unsigned char)(_c)] & (_MP )) + + #define _ismbbalnum(_c) (((_pctype)[(unsigned char)(_c)] & (_ALPHA | _DIGIT )) || _ismbbkalnum(_c)) + #define _ismbbalpha(_c) (((_pctype)[(unsigned char)(_c)] & (_ALPHA )) || _ismbbkalnum(_c)) + #define _ismbbgraph(_c) (((_pctype)[(unsigned char)(_c)] & (_PUNCT | _ALPHA | _DIGIT )) || _ismbbkprint(_c)) + #define _ismbbprint(_c) (((_pctype)[(unsigned char)(_c)] & (_BLANK | _PUNCT | _ALPHA | _DIGIT)) || _ismbbkprint(_c)) + #define _ismbbpunct(_c) (((_pctype)[(unsigned char)(_c)] & (_PUNCT )) || _ismbbkpunct(_c)) + #define _ismbbblank(_c) (((_c) == '\t') ? _BLANK : (_pctype)[(unsigned char)(_c)] & _BLANK) + + // Note that these are intended for double byte character sets (DBCS) and so UTF-8 doesn't consider either to be true for any bytes + // (for UTF-8 we never set _M1 or _M2 in this array) + #define _ismbblead(_c) ((_mbctype+1)[(unsigned char)(_c)] & _M1) + #define _ismbbtrail(_c) ((_mbctype+1)[(unsigned char)(_c)] & _M2) + + #define _ismbbkana(_c) ((_mbctype+1)[(unsigned char)(_c)] & (_MS | _MP)) +#endif + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS +#endif // _INC_MBCTYPE diff --git a/sdk/include/ucrt/mbstring.h b/sdk/include/ucrt/mbstring.h new file mode 100644 index 0000000000000..a22c17bd4c07c --- /dev/null +++ b/sdk/include/ucrt/mbstring.h @@ -0,0 +1,1235 @@ +// +// mbstring.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// Functions and macros for MBCS string manipulation +// +#pragma once +#ifndef _INC_MBSTRING // include guard for 3rd party interop +#define _INC_MBSTRING + +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + + + +#ifndef _FILE_DEFINED + #define _FILE_DEFINED + typedef struct _iobuf + { + void* _Placeholder; + } FILE; +#endif + +#ifdef _CRT_USE_WINAPI_FAMILY_DESKTOP_APP + + #pragma push_macro("_mbsdup") + #undef _mbsdup + + _Check_return_ + _DCRTIMP unsigned char* __cdecl _mbsdup( + _In_z_ unsigned char const* _Str + ); + + #pragma pop_macro("_mbsdup") + + + + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + // The Multibyte Character String Library Functions + // + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + _Check_return_ + _DCRTIMP unsigned int __cdecl _mbbtombc( + _In_ unsigned int _C + ); + + _Check_return_ + _DCRTIMP unsigned int __cdecl _mbbtombc_l( + _In_ unsigned int _C, + _In_opt_ _locale_t _Locale + ); + + _Check_return_ + _DCRTIMP int __cdecl _mbbtype( + _In_ unsigned char _C, + _In_ int _CType + ); + + _Check_return_ + _DCRTIMP int __cdecl _mbbtype_l( + _In_ unsigned char _C, + _In_ int _CType, + _In_opt_ _locale_t _Locale + ); + + _Check_return_ + _DCRTIMP unsigned int __cdecl _mbctombb( + _In_ unsigned int _C + ); + + _Check_return_ + _DCRTIMP unsigned int __cdecl _mbctombb_l( + _In_ unsigned int _C, + _In_opt_ _locale_t _Locale + ); + + _DCRTIMP int __cdecl _mbsbtype( + _In_reads_z_(_Pos) unsigned char const* _Str, + _In_ size_t _Pos + ); + + _DCRTIMP int __cdecl _mbsbtype_l( + _In_reads_z_(_Pos) unsigned char const* _Str, + _In_ size_t _Pos, + _In_opt_ _locale_t _Locale + ); + + _DCRTIMP errno_t __cdecl _mbscat_s( + _Inout_updates_z_(_SizeInBytes) unsigned char* _Dst, + _In_ size_t _SizeInBytes, + _In_z_ unsigned char const* _Src + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1( + errno_t, _mbscat_s, + unsigned char, _Dst, + _In_z_ unsigned char const*, _DstSizeInBytes + ) + + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1( + unsigned char*, __RETURN_POLICY_DST, _DCRTIMP, _mbscat, + _Inout_updates_z_(_String_length_(_Dest) + _String_length_(_Source) + 1), unsigned char, _Dest, + _In_z_ unsigned char const*, _Source + ) + + _DCRTIMP errno_t __cdecl _mbscat_s_l( + _Inout_updates_z_(_DstSizeInBytes) unsigned char* _Dst, + _In_ size_t _DstSizeInBytes, + _In_z_ unsigned char const* _Src, + _In_opt_ _locale_t _Locale + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2( + errno_t, _mbscat_s_l, + unsigned char, _Dest, + _In_z_ unsigned char const*, _Source, + _In_opt_ _locale_t, _Locale + ) + + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_2_EX( + unsigned char* , __RETURN_POLICY_DST, _DCRTIMP, _mbscat_l, _mbscat_s_l, + _Inout_z_ unsigned char, + _Inout_z_, unsigned char, _Dest, + _In_z_ unsigned char const*, _Source, + _In_opt_ _locale_t, _Locale + ) + + _Check_return_ + _DCRTIMP _CONST_RETURN unsigned char* __cdecl _mbschr( + _In_z_ unsigned char const* _Str, + _In_ unsigned int _C + ); + + _Check_return_ + _DCRTIMP _CONST_RETURN unsigned char* __cdecl _mbschr_l( + _In_z_ unsigned char const* _Str, + _In_ unsigned int _C, + _In_opt_ _locale_t _Locale + ); + + _Check_return_ + _DCRTIMP int __cdecl _mbscmp( + _In_z_ unsigned char const* _Str1, + _In_z_ unsigned char const* _Str2 + ); + + _Check_return_ + _DCRTIMP int __cdecl _mbscmp_l( + _In_z_ unsigned char const* _Str1, + _In_z_ unsigned char const* _Str2, + _In_opt_ _locale_t _Locale + ); + + _Check_return_ + _DCRTIMP int __cdecl _mbscoll( + _In_z_ unsigned char const* _Str1, + _In_z_ unsigned char const* _Str2 + ); + + _Check_return_ + _DCRTIMP int __cdecl _mbscoll_l( + _In_z_ unsigned char const* _Str1, + _In_z_ unsigned char const* _Str2, + _In_opt_ _locale_t _Locale + ); + + _DCRTIMP errno_t __cdecl _mbscpy_s( + _Out_writes_z_(_SizeInBytes) unsigned char* _Dst, + _In_ size_t _SizeInBytes, + _In_z_ unsigned char const* _Src + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1( + errno_t, _mbscpy_s, + unsigned char, _Dest, + _In_z_ unsigned char const*, _Source + ) + + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1( + unsigned char*, __RETURN_POLICY_DST, _DCRTIMP, _mbscpy, + _Out_writes_z_(_String_length_(_Source) + 1), unsigned char, _Dest, + _In_z_ unsigned char const*, _Source + ) + + _DCRTIMP errno_t __cdecl _mbscpy_s_l( + _Out_writes_z_(_DstSizeInBytes) unsigned char* _Dst, + _In_ size_t _DstSizeInBytes, + _In_z_ unsigned char const* _Src, + _In_opt_ _locale_t _Locale + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2( + errno_t, _mbscpy_s, + unsigned char, _Dest, + _In_z_ unsigned char const*, _Source, + _In_opt_ _locale_t, _Locale + ) + + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_2_EX( + unsigned char*, __RETURN_POLICY_DST, _DCRTIMP, _mbscpy_l, _mbscpy_s_l, + _Pre_notnull_ _Post_z_ unsigned char, + _Pre_notnull_ _Post_z_, unsigned char, _Dest, + _In_z_ unsigned char const*, _Source, + _In_opt_ _locale_t, _Locale + ) + + _Check_return_ + _DCRTIMP size_t __cdecl _mbscspn( + _In_z_ unsigned char const* _String, + _In_z_ unsigned char const* _Control + ); + + _Check_return_ + _DCRTIMP size_t __cdecl _mbscspn_l( + _In_z_ unsigned char const* _String, + _In_z_ unsigned char const* _Control, + _In_opt_ _locale_t _Locale + ); + + _Check_return_ + _DCRTIMP unsigned char* __cdecl _mbsdec( + _In_reads_z_(_Pos - _Start + 1) unsigned char const* _Start, + _In_z_ unsigned char const* _Pos + ); + + _Check_return_ + _DCRTIMP unsigned char* __cdecl _mbsdec_l( + _In_reads_z_(_Pos-_Start+1) unsigned char const* _Start, + _In_z_ unsigned char const* _Pos, + _In_opt_ _locale_t _Locale + ); + + _Check_return_ + _DCRTIMP int __cdecl _mbsicmp( + _In_z_ unsigned char const* _Str1, + _In_z_ unsigned char const* _Str2 + ); + + _Check_return_ + _DCRTIMP int __cdecl _mbsicmp_l( + _In_z_ unsigned char const* _Str1, + _In_z_ unsigned char const* _Str2, + _In_opt_ _locale_t _Locale + ); + + _Check_return_ + _DCRTIMP int __cdecl _mbsicoll( + _In_z_ unsigned char const* _Str1, + _In_z_ unsigned char const* _Str2 + ); + + _Check_return_ + _DCRTIMP int __cdecl _mbsicoll_l( + _In_z_ unsigned char const* _Str1, + _In_z_ unsigned char const* _Str2, + _In_opt_ _locale_t _Locale + ); + + _Check_return_ + _DCRTIMP unsigned char* __cdecl _mbsinc( + _In_z_ unsigned char const* _Ptr + ); + + _Check_return_ + _DCRTIMP unsigned char* __cdecl _mbsinc_l( + _In_z_ unsigned char const* _Ptr, + _In_opt_ _locale_t _Locale + ); + + _Check_return_ + _Post_satisfies_(return <= _String_length_(_String)) + _DCRTIMP size_t __cdecl _mbslen( + _In_z_ unsigned char const* _String + ); + + _Check_return_ + _Post_satisfies_(return <= _String_length_(_String)) + _DCRTIMP size_t __cdecl _mbslen_l( + _In_z_ unsigned char const* _String, + _In_opt_ _locale_t _Locale + ); + + _Check_return_ + _Post_satisfies_(return <= _String_length_(_String) && return <= _MaxCount) + _DCRTIMP size_t __cdecl _mbsnlen( + _In_z_ unsigned char const* _String, + _In_ size_t _MaxCount + ); + + _Check_return_ + _Post_satisfies_(return <= _String_length_(_String) && return <= _MaxCount) + _DCRTIMP size_t __cdecl _mbsnlen_l( + _In_z_ unsigned char const* _String, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale + ); + + _DCRTIMP errno_t __cdecl _mbslwr_s( + _Inout_updates_opt_z_(_SizeInBytes) unsigned char* _String, + _In_ size_t _SizeInBytes + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_0( + errno_t, _mbslwr_s, + _Inout_updates_z_(_Size) unsigned char, _String + ) + + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_0( + unsigned char*, __RETURN_POLICY_DST, _DCRTIMP, _mbslwr, + _Inout_z_, unsigned char, _String + ) + + _DCRTIMP errno_t __cdecl _mbslwr_s_l( + _Inout_updates_opt_z_(_SizeInBytes) unsigned char* _String, + _In_ size_t _SizeInBytes, + _In_opt_ _locale_t _Locale + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1( + errno_t, _mbslwr_s_l, + unsigned char, _String, + _In_opt_ _locale_t, _Locale + ) + + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1_EX( + unsigned char*, __RETURN_POLICY_DST, _DCRTIMP, _mbslwr_l, _mbslwr_s_l, + _Inout_updates_z_(_Size) unsigned char, + _Inout_z_, unsigned char, _String, + _In_opt_ _locale_t, _Locale + ) + + _DCRTIMP errno_t __cdecl _mbsnbcat_s( + _Inout_updates_z_(_SizeInBytes) unsigned char* _Dst, + _In_ size_t _SizeInBytes, + _In_z_ unsigned char const* _Src, + _In_ size_t _MaxCount + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2( + errno_t, _mbsnbcat_s, + unsigned char, _Dest, + _In_z_ unsigned char const*, _Source, + _In_ size_t, _Count + ) + + __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2( + unsigned char*, __RETURN_POLICY_DST, _DCRTIMP, _mbsnbcat, + _Inout_z_, unsigned char, _Dest, + _In_z_ unsigned char const*, _Source, + _In_ size_t, _Count + ) + + _DCRTIMP errno_t __cdecl _mbsnbcat_s_l( + _Inout_updates_z_(_DstSizeInBytes) unsigned char* _Dst, + _In_ size_t _DstSizeInBytes, + _In_z_ unsigned char const* _Src, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_3( + errno_t, _mbsnbcat_s_l, + unsigned char, _Dest, + _In_z_ unsigned char const*, _Source, + _In_ size_t, _Count, + _In_opt_ _locale_t, _Locale + ) + + __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_3_EX( + unsigned char*, __RETURN_POLICY_DST, _DCRTIMP, _mbsnbcat_l, _mbsnbcat_s_l, + _Inout_updates_z_(_Size) unsigned char, + _Inout_z_, unsigned char, _Dest, + _In_z_ unsigned char const*, _Source, + _In_ size_t, _Count, + _In_opt_ _locale_t, _Locale + ) + + _Check_return_ + _DCRTIMP int __cdecl _mbsnbcmp( + _In_z_ unsigned char const* _Str1, + _In_z_ unsigned char const* _Str2, + _In_ size_t _MaxCount + ); + + _Check_return_ + _DCRTIMP int __cdecl _mbsnbcmp_l( + _In_z_ unsigned char const* _Str1, + _In_z_ unsigned char const* _Str2, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale + ); + + _Check_return_ + _DCRTIMP int __cdecl _mbsnbcoll( + _In_z_ unsigned char const* _Str1, + _In_z_ unsigned char const* _Str2, + _In_ size_t _MaxCount + ); + + _Check_return_ + _DCRTIMP int __cdecl _mbsnbcoll_l( + _In_z_ unsigned char const* _Str1, + _In_z_ unsigned char const* _Str2, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale + ); + + _Check_return_ + _DCRTIMP size_t __cdecl _mbsnbcnt( + _In_reads_or_z_(_MaxCount) unsigned char const* _String, + _In_ size_t _MaxCount + ); + + _Check_return_ + _DCRTIMP size_t __cdecl _mbsnbcnt_l( + _In_reads_or_z_(_MaxCount) unsigned char const* _String, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale + ); + + _DCRTIMP errno_t __cdecl _mbsnbcpy_s( + _Out_writes_z_(_SizeInBytes) unsigned char* _Dst, + _In_ size_t _SizeInBytes, + _In_z_ unsigned char const* _Src, + _In_ size_t _MaxCount + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2( + errno_t, _mbsnbcpy_s, + unsigned char, _Dest, + _In_z_ unsigned char const*, _Source, + _In_ size_t, _Count + ) + + __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2( + _Success_(return != 0) unsigned char*, __RETURN_POLICY_DST, _DCRTIMP, _mbsnbcpy, + _Out_writes_(_Count) _Post_maybez_, unsigned char, _Dest, + _In_z_ unsigned char const*, _Source, + _In_ size_t, _Count + ) + + _DCRTIMP errno_t __cdecl _mbsnbcpy_s_l( + _Out_writes_z_(_DstSizeInBytes) unsigned char* _Dst, + _In_ size_t _DstSizeInBytes, + _In_z_ unsigned char const* _Src, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_3( + errno_t, _mbsnbcpy_s_l, + unsigned char, _Dest, + _In_z_ unsigned char const*, _Source, + _In_ size_t, _Count, + _In_opt_ _locale_t, _Locale + ) + + __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_3_EX( + _Success_(return != 0) unsigned char*, __RETURN_POLICY_DST, _DCRTIMP, _mbsnbcpy_l, _mbsnbcpy_s_l, + _Out_writes_z_(_Size) unsigned char, + _Out_writes_(_Count) _Post_maybez_, unsigned char, _Dest, + _In_z_ unsigned char const*, _Source, + _In_ size_t, _Count, + _In_opt_ _locale_t, _Locale + ) + + _Check_return_ + _DCRTIMP int __cdecl _mbsnbicmp( + _In_z_ unsigned char const* _Str1, + _In_z_ unsigned char const* _Str2, + _In_ size_t _MaxCount + ); + + _Check_return_ + _DCRTIMP int __cdecl _mbsnbicmp_l( + _In_z_ unsigned char const* _Str1, + _In_z_ unsigned char const* _Str2, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale + ); + + _Check_return_ + _DCRTIMP int __cdecl _mbsnbicoll( + _In_z_ unsigned char const* _Str1, + _In_z_ unsigned char const* _Str2, + _In_ size_t _MaxCount + ); + + _Check_return_ + _DCRTIMP int __cdecl _mbsnbicoll_l( + _In_z_ unsigned char const* _Str1, + _In_z_ unsigned char const* _Str2, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale + ); + + _DCRTIMP errno_t __cdecl _mbsnbset_s( + _Inout_updates_z_(_SizeInBytes) unsigned char* _Dst, + _In_ size_t _SizeInBytes, + _In_ unsigned int _C, + _In_ size_t _MaxCount + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2( + errno_t, _mbsnbset_s, + _Prepost_z_ unsigned char, _Dest, + _In_ unsigned int, _Val, + _In_ size_t, _MaxCount + ) + + __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2_EX( + unsigned char*, __RETURN_POLICY_DST, _DCRTIMP, _mbsnbset, _mbsnbset_s, + _Inout_updates_z_(_Size) unsigned char, + _Inout_updates_z_(_MaxCount), unsigned char, _String, + _In_ unsigned int, _Val, + _In_ size_t, _MaxCount + ) + + _DCRTIMP errno_t __cdecl _mbsnbset_s_l( + _Inout_updates_z_(_DstSizeInBytes) unsigned char* _Dst, + _In_ size_t _DstSizeInBytes, + _In_ unsigned int _Ch, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_3( + errno_t, _mbsnbset_s_l, + _Prepost_z_ unsigned char, _Dest, + _In_ unsigned int, _Val, + _In_ size_t, _MaxCount, + _In_opt_ _locale_t, _Locale + ) + + __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_3_EX( + unsigned char*, __RETURN_POLICY_DST, _DCRTIMP, _mbsnbset_l, _mbsnbset_s_l, + _Inout_updates_z_(_Size) unsigned char, + _Inout_updates_z_(_MaxCount), unsigned char, _String, + _In_ unsigned int, _Val, + _In_ size_t, _MaxCount, + _In_opt_ _locale_t, _Locale + ) + + _DCRTIMP errno_t __cdecl _mbsncat_s( + _Inout_updates_z_(_SizeInBytes) unsigned char* _Dst, + _In_ size_t _SizeInBytes, + _In_z_ unsigned char const* _Src, + _In_ size_t _MaxCount + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2( + errno_t, _mbsncat_s, + unsigned char, _Dest, + _In_z_ unsigned char const*, _Source, + _In_ size_t, _Count + ) + + __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2( + unsigned char*, __RETURN_POLICY_DST, _DCRTIMP, _mbsncat, + _Inout_z_, unsigned char, _Dest, + _In_z_ unsigned char const*, _Source, + _In_ size_t, _Count + ) + + _DCRTIMP errno_t __cdecl _mbsncat_s_l( + _Inout_updates_z_(_DstSizeInBytes) unsigned char* _Dst, + _In_ size_t _DstSizeInBytes, + _In_z_ unsigned char const* _Src, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_3( + errno_t, _mbsncat_s_l, + unsigned char, _Dest, + _In_z_ unsigned char const*, _Source, + _In_ size_t, _Count, + _In_opt_ _locale_t, _Locale + ) + + __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_3_EX( + unsigned char*, __RETURN_POLICY_DST, _DCRTIMP, _mbsncat_l, _mbsncat_s_l, + _Inout_updates_z_(_Size) unsigned char, + _Inout_z_, unsigned char, _Dest, + _In_z_ unsigned char const*, _Source, + _In_ size_t, _Count, + _In_opt_ _locale_t, _Locale + ) + + _Check_return_ + _DCRTIMP size_t __cdecl _mbsnccnt( + _In_reads_or_z_(_MaxCount) unsigned char const* _Str, + _In_ size_t _MaxCount + ); + + _Check_return_ + _DCRTIMP size_t __cdecl _mbsnccnt_l( + _In_reads_or_z_(_MaxCount) unsigned char const* _Str, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale + ); + + _Check_return_ + _DCRTIMP int __cdecl _mbsncmp( + _In_reads_or_z_(_MaxCount) unsigned char const* _Str1, + _In_z_ unsigned char const* _Str2, + _In_ size_t _MaxCount + ); + + _Check_return_ + _DCRTIMP int __cdecl _mbsncmp_l( + _In_reads_or_z_(_MaxCount) unsigned char const* _Str1, + _In_z_ unsigned char const* _Str2, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale + ); + + _Check_return_ + _DCRTIMP int __cdecl _mbsncoll( + _In_z_ unsigned char const* _Str1, + _In_z_ unsigned char const* _Str2, + _In_ size_t _MaxCount + ); + + _Check_return_ + _DCRTIMP int __cdecl _mbsncoll_l( + _In_z_ unsigned char const* _Str1, + _In_z_ unsigned char const* _Str2, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale + ); + + _DCRTIMP errno_t __cdecl _mbsncpy_s( + _Out_writes_z_(_SizeInBytes) unsigned char* _Dst, + _In_ size_t _SizeInBytes, + _In_z_ unsigned char const* _Src, + _In_ size_t _MaxCount + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2( + errno_t, _mbsncpy_s, + unsigned char, _Dest, + _In_z_ unsigned char const*, _Source, + _In_ size_t, _Count + ) + + __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2( + unsigned char*, __RETURN_POLICY_DST, _DCRTIMP, _mbsncpy, + _Pre_notnull_ _Out_writes_(2 * _Count) _Post_maybez_, unsigned char, _Dest, + _In_z_ unsigned char const*, _Source, + _In_ size_t, _Count + ) + + _DCRTIMP errno_t __cdecl _mbsncpy_s_l( + _Out_writes_z_(_DstSizeInBytes) unsigned char* _Dst, + _In_ size_t _DstSizeInBytes, + _In_z_ unsigned char const* _Src, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_3( + errno_t, _mbsncpy_s_l, + unsigned char, _Dest, + _In_z_ unsigned char const*, _Source, + _In_ size_t, _Count, + _In_opt_ _locale_t, _Locale + ) + + __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_3_EX( + unsigned char*, __RETURN_POLICY_DST, _DCRTIMP, _mbsncpy_l, _mbsncpy_s_l, + _Out_writes_z_(_Size) unsigned char, + _Out_writes_(_Count) _Post_maybez_, unsigned char, _Dest, + _In_z_ unsigned char const*, _Source, + _In_ size_t, _Count, + _In_opt_ _locale_t, _Locale + ) + + _Check_return_ + _DCRTIMP unsigned int __cdecl _mbsnextc( + _In_z_ unsigned char const* _String + ); + + _Check_return_ + _DCRTIMP unsigned int __cdecl _mbsnextc_l( + _In_z_ unsigned char const* _String, + _In_opt_ _locale_t _Locale + ); + + _Check_return_ + _DCRTIMP int __cdecl _mbsnicmp( + _In_reads_or_z_(_MaxCount) unsigned char const* _Str1, + _In_reads_or_z_(_MaxCount) unsigned char const* _Str2, + _In_ size_t _MaxCount + ); + + _Check_return_ + _DCRTIMP int __cdecl _mbsnicmp_l( + _In_reads_or_z_(_MaxCount) unsigned char const* _Str1, + _In_reads_or_z_(_MaxCount) unsigned char const* _Str2, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale + ); + + _Check_return_ + _DCRTIMP int __cdecl _mbsnicoll( + _In_reads_or_z_(_MaxCount) unsigned char const* _Str1, + _In_reads_or_z_(_MaxCount) unsigned char const* _Str2, + _In_ size_t _MaxCount + ); + + _Check_return_ + _DCRTIMP int __cdecl _mbsnicoll_l( + _In_reads_or_z_(_MaxCount) unsigned char const* _Str1, + _In_reads_or_z_(_MaxCount) unsigned char const* _Str2, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale + ); + + _Check_return_ + _DCRTIMP unsigned char* __cdecl _mbsninc( + _In_reads_or_z_(_Count) unsigned char const* _String, + _In_ size_t _Count + ); + + _Check_return_ + _DCRTIMP unsigned char* __cdecl _mbsninc_l( + _In_reads_or_z_(_Count) unsigned char const* _String, + _In_ size_t _Count, + _In_opt_ _locale_t _Locale + ); + + _DCRTIMP errno_t __cdecl _mbsnset_s( + _Inout_updates_z_(_SizeInBytes) unsigned char* _Dst, + _In_ size_t _SizeInBytes, + _In_ unsigned int _Val, + _In_ size_t _MaxCount + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2( + errno_t, _mbsnset_s, + _Prepost_z_ unsigned char, _Dest, + _In_ unsigned int, _Val, + _In_ size_t, _MaxCount + ) + + __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2_EX( + unsigned char*, __RETURN_POLICY_DST, _DCRTIMP, _mbsnset, _mbsnset_s, + _Inout_updates_z_(_Size) unsigned char, + _Inout_updates_z_(_MaxCount), unsigned char, _String, + _In_ unsigned int, _Val, + _In_ size_t, _MaxCount + ) + + _DCRTIMP errno_t __cdecl _mbsnset_s_l( + _Inout_updates_z_(_DstSizeInBytes) unsigned char* _Dst, + _In_ size_t _DstSizeInBytes, + _In_ unsigned int _Val, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_3( + errno_t, _mbsnset_s_l, + _Prepost_z_ unsigned char, _Dest, + _In_ unsigned int, _Val, + _In_ size_t, _MaxCount, + _In_opt_ _locale_t, _Locale + ) + + __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_3_EX( + unsigned char* , __RETURN_POLICY_DST, _DCRTIMP, _mbsnset_l, _mbsnset_s_l, + _Inout_updates_z_(_Size) unsigned char, + _Inout_updates_z_(_MaxCount), unsigned char, _String, + _In_ unsigned int, _Val, + _In_ size_t, _MaxCount, + _In_opt_ _locale_t, _Locale + ) + + _Check_return_ + _DCRTIMP _CONST_RETURN unsigned char* __cdecl _mbspbrk( + _In_z_ unsigned char const* _String, + _In_z_ unsigned char const* _Control + ); + + _Check_return_ + _DCRTIMP _CONST_RETURN unsigned char* __cdecl _mbspbrk_l( + _In_z_ unsigned char const* _String, + _In_z_ unsigned char const* _Control, + _In_opt_ _locale_t _Locale + ); + + _Check_return_ + _DCRTIMP _CONST_RETURN unsigned char* __cdecl _mbsrchr( + _In_z_ unsigned char const* _String, + _In_ unsigned int _C + ); + + _Check_return_ + _DCRTIMP _CONST_RETURN unsigned char* __cdecl _mbsrchr_l( + _In_z_ unsigned char const* _String, + _In_ unsigned int _C, + _In_opt_ _locale_t _Locale + ); + + _DCRTIMP unsigned char* __cdecl _mbsrev( + _Inout_z_ unsigned char* _String + ); + + _DCRTIMP unsigned char* __cdecl _mbsrev_l( + _Inout_z_ unsigned char* _String, + _In_opt_ _locale_t _Locale + ); + + _DCRTIMP errno_t __cdecl _mbsset_s( + _Inout_updates_z_(_SizeInBytes) unsigned char* _Dst, + _In_ size_t _SizeInBytes, + _In_ unsigned int _Val + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1( + errno_t, _mbsset_s, + _Prepost_z_ unsigned char, _Dest, + _In_ unsigned int, _Val + ) + + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1_EX( + unsigned char*, __RETURN_POLICY_DST, _DCRTIMP, _mbsset, _mbsset_s, + _Inout_updates_z_(_Size) unsigned char, + _Inout_z_, unsigned char, _String, + _In_ unsigned int, _Val + ) + + _DCRTIMP errno_t __cdecl _mbsset_s_l( + _Inout_updates_z_(_DstSizeInBytes) unsigned char* _Dst, + _In_ size_t _DstSizeInBytes, + _In_ unsigned int _Val, + _In_opt_ _locale_t _Locale + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2( + errno_t, _mbsset_s_l, + _Prepost_z_ unsigned char, _Dest, + _In_ unsigned int, _Val, + _In_opt_ _locale_t, _Locale + ) + + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_2_EX( + unsigned char*, __RETURN_POLICY_DST, _DCRTIMP, _mbsset_l, _mbsset_s_l, + _Inout_updates_z_(_Size) unsigned char, + _Inout_z_, unsigned char, _String, + _In_ unsigned int, _Val, + _In_opt_ _locale_t, _Locale + ) + + _Check_return_ + _DCRTIMP size_t __cdecl _mbsspn( + _In_z_ unsigned char const* _Str, + _In_z_ unsigned char const* _Control + ); + + _Check_return_ + _DCRTIMP size_t __cdecl _mbsspn_l( + _In_z_ unsigned char const* _Str, + _In_z_ unsigned char const* _Control, + _In_opt_ _locale_t _Locale + ); + + _Check_return_ + _DCRTIMP unsigned char* __cdecl _mbsspnp( + _In_z_ unsigned char const* _Str1, + _In_z_ unsigned char const* _Str2 + ); + + _Check_return_ + _DCRTIMP unsigned char* __cdecl _mbsspnp_l( + _In_z_ unsigned char const* _Str1, + _In_z_ unsigned char const* _Str2, + _In_opt_ _locale_t _Locale + ); + + _Check_return_ _Ret_maybenull_ + _DCRTIMP _CONST_RETURN unsigned char* __cdecl _mbsstr( + _In_z_ unsigned char const* _Str, + _In_z_ unsigned char const* _Substr + ); + + _Check_return_ _Ret_maybenull_ + _DCRTIMP _CONST_RETURN unsigned char* __cdecl _mbsstr_l( + _In_z_ unsigned char const* _Str, + _In_z_ unsigned char const* _Substr, + _In_opt_ _locale_t _Locale + ); + + _Check_return_ _CRT_INSECURE_DEPRECATE(_mbstok_s) + _DCRTIMP unsigned char* __cdecl _mbstok( + _Inout_opt_z_ unsigned char* _Str, + _In_z_ unsigned char const* _Delim + ); + + _Check_return_ _CRT_INSECURE_DEPRECATE(_mbstok_s_l) + _DCRTIMP unsigned char* __cdecl _mbstok_l( + _Inout_opt_z_ unsigned char* _Str, + _In_z_ unsigned char const* _Delim, + _In_opt_ _locale_t _Locale + ); + + _Check_return_ + _DCRTIMP unsigned char* __cdecl _mbstok_s( + _Inout_opt_z_ unsigned char* _Str, + _In_z_ unsigned char const* _Delim, + _Inout_ _Deref_prepost_opt_z_ unsigned char** _Context + ); + + _Check_return_ + _DCRTIMP unsigned char* __cdecl _mbstok_s_l( + _Inout_opt_z_ unsigned char* _Str, + _In_z_ unsigned char const* _Delim, + _Inout_ _Deref_prepost_opt_z_ unsigned char** _Context, + _In_opt_ _locale_t _Locale + ); + + _DCRTIMP errno_t __cdecl _mbsupr_s( + _Inout_updates_z_(_SizeInBytes) unsigned char* _Str, + _In_ size_t _SizeInBytes + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_0( + errno_t, _mbsupr_s, + _Inout_updates_z_(_Size) unsigned char, _String + ) + + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_0( + unsigned char*, __RETURN_POLICY_DST, _DCRTIMP, _mbsupr, + _Inout_z_, unsigned char, _String + ) + + _DCRTIMP errno_t __cdecl _mbsupr_s_l( + _Inout_updates_z_(_SizeInBytes) unsigned char* _Str, + _In_ size_t _SizeInBytes, + _In_opt_ _locale_t _Locale + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1( + errno_t, _mbsupr_s_l, + unsigned char, _String, + _In_opt_ _locale_t, _Locale + ) + + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1_EX( + unsigned char*, __RETURN_POLICY_DST, _DCRTIMP, _mbsupr_l, _mbsupr_s_l, + _Inout_updates_z_(_Size) unsigned char, + _Inout_z_, unsigned char, _String, + _In_opt_ _locale_t, _Locale + ) + + _Check_return_ + _DCRTIMP size_t __cdecl _mbclen( + _In_z_ unsigned char const* _String + ); + + _Check_return_ + _DCRTIMP size_t __cdecl _mbclen_l( + _In_z_ unsigned char const* _String, + _In_opt_ _locale_t _Locale + ); + + _CRT_INSECURE_DEPRECATE(_mbccpy_s) + _DCRTIMP void __cdecl _mbccpy( + _Out_writes_bytes_(2) unsigned char* _Dst, + _In_z_ unsigned char const* _Src + ); + + _CRT_INSECURE_DEPRECATE(_mbccpy_s_l) + _DCRTIMP void __cdecl _mbccpy_l( + _Out_writes_bytes_(2) unsigned char* _Dst, + _In_z_ unsigned char const* _Src, + _In_opt_ _locale_t _Locale + ); + + _DCRTIMP errno_t __cdecl _mbccpy_s( + _Out_writes_z_(_SizeInBytes) unsigned char* _Dst, + _In_ size_t _SizeInBytes, + _Out_opt_ int* _PCopied, + _In_z_ unsigned char const* _Src + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2( + errno_t, _mbccpy_s, + unsigned char, _Dest, + _Out_opt_ int*, _PCopied, + _In_z_ unsigned char const*, _Source + ) + + _DCRTIMP errno_t __cdecl _mbccpy_s_l( + _Out_writes_bytes_(_DstSizeInBytes) unsigned char* _Dst, + _In_ size_t _DstSizeInBytes, + _Out_opt_ int* _PCopied, + _In_z_ unsigned char const* _Src, + _In_opt_ _locale_t _Locale + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_3( + errno_t, _mbccpy_s_l, + unsigned char, _Dest, + _Out_opt_ int*, _PCopied, + _In_z_ unsigned char const*, _Source, + _In_opt_ _locale_t, _Locale + ) + + #define _mbccmp(_cpc1, _cpc2) _mbsncmp((_cpc1), (_cpc2), 1) + + + + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + // Const-Correct C++ Overloads + // + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + #ifndef _EXCLUDE_MBSTRING_CONST_CORRECT_OVERLOADS + #ifdef __cplusplus + extern "C++" { + + _Check_return_ + inline unsigned char* __CRTDECL _mbschr( + _In_z_ unsigned char* const _String, + _In_ unsigned int const _Char + ) + { + unsigned char const* const _ConstString = _String; + return const_cast(_mbschr(_ConstString, _Char)); + } + + _Check_return_ + inline unsigned char* __CRTDECL _mbschr_l( + _In_z_ unsigned char* const _String, + _In_ unsigned int const _Char, + _In_opt_ _locale_t const _Locale + ) + { + unsigned char const* const _ConstString = _String; + return const_cast(_mbschr_l(_ConstString, _Char, _Locale)); + } + + _Check_return_ + inline unsigned char* __CRTDECL _mbspbrk( + _In_z_ unsigned char* const _String, + _In_z_ unsigned char const* const _CharSet + ) + { + unsigned char const* const _ConstString = _String; + return const_cast(_mbspbrk(_ConstString, _CharSet)); + } + + _Check_return_ + inline unsigned char* __CRTDECL _mbspbrk_l( + _In_z_ unsigned char* const _String, + _In_z_ unsigned char const* const _CharSet, + _In_opt_ _locale_t const _Locale + ) + { + unsigned char const* const _ConstString = _String; + return const_cast(_mbspbrk_l(_ConstString, _CharSet, _Locale)); + } + + _Check_return_ + inline unsigned char* __CRTDECL _mbsrchr( + _In_z_ unsigned char* const _String, + _In_ unsigned int const _Char + ) + { + unsigned char const* const _ConstString = _String; + return const_cast(_mbsrchr(_ConstString, _Char)); + } + + _Check_return_ + inline unsigned char* __CRTDECL _mbsrchr_l( + _In_z_ unsigned char* const _String, + _In_ unsigned int const _Char, + _In_opt_ _locale_t const _Locale + ) + { + unsigned char const* const _ConstString = _String; + return const_cast(_mbsrchr_l(_ConstString, _Char, _Locale)); + } + + _Check_return_ _Ret_maybenull_ + inline unsigned char* __CRTDECL _mbsstr( + _In_z_ unsigned char* const _String, + _In_z_ unsigned char const* const _Match + ) + { + unsigned char const* const _ConstString = _String; + return const_cast(_mbsstr(_ConstString, _Match)); + } + + _Check_return_ _Ret_maybenull_ + inline unsigned char* __CRTDECL _mbsstr_l( + _In_z_ unsigned char* const _String, + _In_z_ unsigned char const* const _Match, + _In_opt_ _locale_t const _Locale + ) + { + unsigned char const* const _ConstString = _String; + return const_cast(_mbsstr_l(_ConstString, _Match, _Locale)); + } + + } // extern "C++" + #endif // __cplusplus + #endif // _EXCLUDE_MBSTRING_CONST_CORRECT_OVERLOADS + + + + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + // Multibyte Character Classification and Conversion Functions + // + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + _Check_return_ _DCRTIMP int __cdecl _ismbcalnum(_In_ unsigned int _C); + _Check_return_ _DCRTIMP int __cdecl _ismbcalpha(_In_ unsigned int _C); + _Check_return_ _DCRTIMP int __cdecl _ismbcdigit(_In_ unsigned int _C); + _Check_return_ _DCRTIMP int __cdecl _ismbcgraph(_In_ unsigned int _C); + _Check_return_ _DCRTIMP int __cdecl _ismbclegal(_In_ unsigned int _C); + _Check_return_ _DCRTIMP int __cdecl _ismbclower(_In_ unsigned int _C); + _Check_return_ _DCRTIMP int __cdecl _ismbcprint(_In_ unsigned int _C); + _Check_return_ _DCRTIMP int __cdecl _ismbcpunct(_In_ unsigned int _C); + _Check_return_ _DCRTIMP int __cdecl _ismbcblank(_In_ unsigned int _C); + _Check_return_ _DCRTIMP int __cdecl _ismbcspace(_In_ unsigned int _C); + _Check_return_ _DCRTIMP int __cdecl _ismbcupper(_In_ unsigned int _C); + + _Check_return_ _DCRTIMP int __cdecl _ismbcalnum_l(_In_ unsigned int _C, _In_opt_ _locale_t _Locale); + _Check_return_ _DCRTIMP int __cdecl _ismbcalpha_l(_In_ unsigned int _C, _In_opt_ _locale_t _Locale); + _Check_return_ _DCRTIMP int __cdecl _ismbcdigit_l(_In_ unsigned int _C, _In_opt_ _locale_t _Locale); + _Check_return_ _DCRTIMP int __cdecl _ismbcgraph_l(_In_ unsigned int _C, _In_opt_ _locale_t _Locale); + _Check_return_ _DCRTIMP int __cdecl _ismbclegal_l(_In_ unsigned int _C, _In_opt_ _locale_t _Locale); + _Check_return_ _DCRTIMP int __cdecl _ismbclower_l(_In_ unsigned int _C, _In_opt_ _locale_t _Locale); + _Check_return_ _DCRTIMP int __cdecl _ismbcprint_l(_In_ unsigned int _C, _In_opt_ _locale_t _Locale); + _Check_return_ _DCRTIMP int __cdecl _ismbcpunct_l(_In_ unsigned int _C, _In_opt_ _locale_t _Locale); + _Check_return_ _DCRTIMP int __cdecl _ismbcblank_l(_In_ unsigned int _C, _In_opt_ _locale_t _Locale); + _Check_return_ _DCRTIMP int __cdecl _ismbcspace_l(_In_ unsigned int _C, _In_opt_ _locale_t _Locale); + _Check_return_ _DCRTIMP int __cdecl _ismbcupper_l(_In_ unsigned int _C, _In_opt_ _locale_t _Locale); + + _Check_return_ _DCRTIMP unsigned int __cdecl _mbctolower(_In_ unsigned int _Ch); + _Check_return_ _DCRTIMP unsigned int __cdecl _mbctoupper(_In_ unsigned int _Ch); + + _Check_return_ _DCRTIMP unsigned int __cdecl _mbctolower_l(_In_ unsigned int _Ch, _In_opt_ _locale_t _Locale); + _Check_return_ _DCRTIMP unsigned int __cdecl _mbctoupper_l(_In_ unsigned int _Ch, _In_opt_ _locale_t _Locale); + + + + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + // Multibyte Character Kanji Classification and Conversion Functions + // + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + _Check_return_ _DCRTIMP int __cdecl _ismbchira (_In_ unsigned int _C); + _Check_return_ _DCRTIMP int __cdecl _ismbckata (_In_ unsigned int _C); + _Check_return_ _DCRTIMP int __cdecl _ismbcsymbol(_In_ unsigned int _C); + _Check_return_ _DCRTIMP int __cdecl _ismbcl0 (_In_ unsigned int _C); + _Check_return_ _DCRTIMP int __cdecl _ismbcl1 (_In_ unsigned int _C); + _Check_return_ _DCRTIMP int __cdecl _ismbcl2 (_In_ unsigned int _C); + + _Check_return_ _DCRTIMP int __cdecl _ismbchira_l (_In_ unsigned int _C, _In_opt_ _locale_t _Locale); + _Check_return_ _DCRTIMP int __cdecl _ismbckata_l (_In_ unsigned int _C, _In_opt_ _locale_t _Locale); + _Check_return_ _DCRTIMP int __cdecl _ismbcsymbol_l(_In_ unsigned int _C, _In_opt_ _locale_t _Locale); + _Check_return_ _DCRTIMP int __cdecl _ismbcl0_l (_In_ unsigned int _C, _In_opt_ _locale_t _Locale); + _Check_return_ _DCRTIMP int __cdecl _ismbcl1_l (_In_ unsigned int _C, _In_opt_ _locale_t _Locale); + _Check_return_ _DCRTIMP int __cdecl _ismbcl2_l (_In_ unsigned int _C, _In_opt_ _locale_t _Locale); + + _Check_return_ _DCRTIMP unsigned int __cdecl _mbcjistojms(_In_ unsigned int _C); + _Check_return_ _DCRTIMP unsigned int __cdecl _mbcjmstojis(_In_ unsigned int _C); + _Check_return_ _DCRTIMP unsigned int __cdecl _mbctohira (_In_ unsigned int _C); + _Check_return_ _DCRTIMP unsigned int __cdecl _mbctokata (_In_ unsigned int _C); + + _Check_return_ _DCRTIMP unsigned int __cdecl _mbcjistojms_l(_In_ unsigned int _C, _In_opt_ _locale_t _Locale); + _Check_return_ _DCRTIMP unsigned int __cdecl _mbcjmstojis_l(_In_ unsigned int _C, _In_opt_ _locale_t _Locale); + _Check_return_ _DCRTIMP unsigned int __cdecl _mbctohira_l (_In_ unsigned int _C, _In_opt_ _locale_t _Locale); + _Check_return_ _DCRTIMP unsigned int __cdecl _mbctokata_l (_In_ unsigned int _C, _In_opt_ _locale_t _Locale); + +#endif // _CRT_USE_WINAPI_FAMILY_DESKTOP_APP + + + +#if _CRT_FUNCTIONS_REQUIRED + // Lead and trail bytes do not apply correctly to all encodings, including UTF-8. Applications + // are recommended to use the system codepage conversion APIs and not attempt to reverse + // engineer the behavior of any particular encoding. Lead and trail are always FALSE for UTF-8. + _When_(_Ch == 0, _Post_equal_to_(0)) + _Check_return_ _DCRTIMP int __cdecl _ismbblead (_In_ unsigned int _Ch); + _Check_return_ _DCRTIMP int __cdecl _ismbbtrail(_In_ unsigned int _Ch); + + _When_(_Ch == 0, _Post_equal_to_(0)) + _Check_return_ _DCRTIMP int __cdecl _ismbblead_l (_In_ unsigned int _Ch, _In_opt_ _locale_t _Locale); + _Check_return_ _DCRTIMP int __cdecl _ismbbtrail_l(_In_ unsigned int _Ch, _In_opt_ _locale_t _Locale); + + _Check_return_ + _DCRTIMP int __cdecl _ismbslead( + _In_reads_z_(_Pos - _String + 1) unsigned char const* _String, + _In_z_ unsigned char const* _Pos + ); + + _Check_return_ + _DCRTIMP int __cdecl _ismbslead_l( + _In_reads_z_(_Pos - _String + 1) unsigned char const* _String, + _In_z_ unsigned char const* _Pos, + _In_opt_ _locale_t _Locale + ); + + _Check_return_ + _ACRTIMP int __cdecl _ismbstrail( + _In_reads_z_(_Pos - _String + 1) unsigned char const* _String, + _In_z_ unsigned char const* _Pos + ); + + _Check_return_ + _ACRTIMP int __cdecl _ismbstrail_l( + _In_reads_z_(_Pos - _String + 1) unsigned char const* _String, + _In_z_ unsigned char const* _Pos, + _In_opt_ _locale_t _Locale + ); +#endif // _CRT_FUNCTIONS_REQUIRED + + + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS +#endif // _INC_MBSTRING diff --git a/sdk/include/ucrt/memory.h b/sdk/include/ucrt/memory.h new file mode 100644 index 0000000000000..8d4f2a5fb5c75 --- /dev/null +++ b/sdk/include/ucrt/memory.h @@ -0,0 +1,13 @@ +// +// memory.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The buffer (memory) manipulation library. +// +#pragma once +#ifndef _INC_MEMORY // include guard for 3rd party interop +#define _INC_MEMORY + +#include +#endif // _INC_MEMORY diff --git a/sdk/include/ucrt/minmax.h b/sdk/include/ucrt/minmax.h new file mode 100644 index 0000000000000..859ffcc4e8f36 --- /dev/null +++ b/sdk/include/ucrt/minmax.h @@ -0,0 +1,28 @@ +// +// minmax.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// Familiar min() and max() macros +// +#pragma once +#ifndef _INC_MINMAX +#define _INC_MINMAX + +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +#ifndef max + #define max(a ,b) (((a) > (b)) ? (a) : (b)) +#endif + +#ifndef min + #define min(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS +#endif // _INC_MINMAX diff --git a/sdk/include/ucrt/new.h b/sdk/include/ucrt/new.h new file mode 100644 index 0000000000000..3c3123c4a8206 --- /dev/null +++ b/sdk/include/ucrt/new.h @@ -0,0 +1,68 @@ +// +// new.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The C++ memory allocation library functionality +// +#pragma once +#ifndef _INC_NEW // include guard for 3rd party interop +#define _INC_NEW + +#include +#include + +#ifdef __cplusplus + + #if !defined _MSC_EXTENSIONS && !defined _CRTBLD && !defined _CORECRT_BUILD + #include + #endif + + #if defined _MSC_EXTENSIONS && !defined _CORECRT_BUILD + #include + + namespace std + { + typedef void (__CRTDECL* new_handler)(); + + #ifdef _M_CEE + typedef void (__clrcall* _new_handler_m) (); + #endif + + _CRTIMP2 new_handler __cdecl set_new_handler(_In_opt_ new_handler _NewHandler) throw(); + } + + #ifdef _M_CEE + using ::std::_new_handler_m; + #endif + + using ::std::new_handler; + using ::std::set_new_handler; + #endif + +#endif // __cplusplus + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + + + +typedef int (__CRTDECL* _PNH)(size_t); + +_PNH __cdecl _query_new_handler(void); +_PNH __cdecl _set_new_handler(_In_opt_ _PNH _NewHandler); + +// new mode flag -- when set, makes malloc() behave like new() +_ACRTIMP int __cdecl _query_new_mode(void); +_ACRTIMP int __cdecl _set_new_mode(_In_ int _NewMode); + + + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS + +#endif // _INC_NEW diff --git a/sdk/include/ucrt/process.h b/sdk/include/ucrt/process.h new file mode 100644 index 0000000000000..78dfcb5ceb122 --- /dev/null +++ b/sdk/include/ucrt/process.h @@ -0,0 +1,375 @@ +// +// process.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// This file declares the process control functionality (e.g., the exec and +// spawn families of functions). +// +#pragma once +#ifndef _INC_PROCESS // include guard for 3rd party interop +#define _INC_PROCESS + +#include +#include +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + + + +// Flag values for the _spawn family of functions +#define _P_WAIT 0 +#define _P_NOWAIT 1 +#define _OLD_P_OVERLAY 2 +#define _P_NOWAITO 3 +#define _P_DETACH 4 +#define _P_OVERLAY 2 + +// Action codes for _cwait(). The action code argument to _cwait() is ignored on +// Win32. The parameter only exists so that we do not break existing code. +#define _WAIT_CHILD 0 +#define _WAIT_GRANDCHILD 1 + + + +#if _CRT_FUNCTIONS_REQUIRED + + _ACRTIMP __declspec(noreturn) void __cdecl exit(_In_ int _Code); + _ACRTIMP __declspec(noreturn) void __cdecl _exit(_In_ int _Code); + _ACRTIMP __declspec(noreturn) void __cdecl _Exit(_In_ int _Code); + _ACRTIMP __declspec(noreturn) void __cdecl quick_exit(_In_ int _Code); + _ACRTIMP __declspec(noreturn) void __cdecl abort(void); + + _DCRTIMP int __cdecl system(_In_opt_z_ char const* _Command); + + _ACRTIMP void __cdecl _cexit(void); + _ACRTIMP void __cdecl _c_exit(void); + + typedef void (__stdcall *_tls_callback_type)(void *, unsigned long, void *); + _ACRTIMP void __cdecl _register_thread_local_exe_atexit_callback(_In_ _tls_callback_type _Callback); + +#endif // _CRT_FUNCTIONS_REQUIRED + +// Declare DLL notification (initialization/termination) routines. The preferred +// method is for the CRT client to define DllMain(), which will automatically be +// called by the DLL entry point defined by the CRT. If the CRT client wants to +// define the DLL entry point, the client entry point must call _CRT_INIT on all +// types of notifications, as the very first thing on attach notifications and as +// the very last thing on detach notifications. +#ifdef _DECL_DLLMAIN + + int __stdcall DllMain( + _In_ void* _DllHandle, + _In_ unsigned long _Reason, + _In_opt_ void* _Reserved + ); + + int __stdcall _CRT_INIT( + _In_ void* _DllHandle, + _In_ unsigned long _Reason, + _In_opt_ void* _Reserved + ); + + extern int (__stdcall* const _pRawDllMain)(void*, unsigned long, void*); + +#endif + + + +typedef void (__cdecl* _beginthread_proc_type )(void*); +typedef unsigned (__stdcall* _beginthreadex_proc_type)(void*); + +_ACRTIMP uintptr_t __cdecl _beginthread( + _In_ _beginthread_proc_type _StartAddress, + _In_ unsigned _StackSize, + _In_opt_ void* _ArgList + ); + +_ACRTIMP void __cdecl _endthread(void); + +_Success_(return != 0) +_ACRTIMP uintptr_t __cdecl _beginthreadex( + _In_opt_ void* _Security, + _In_ unsigned _StackSize, + _In_ _beginthreadex_proc_type _StartAddress, + _In_opt_ void* _ArgList, + _In_ unsigned _InitFlag, + _Out_opt_ unsigned* _ThrdAddr + ); + +_ACRTIMP void __cdecl _endthreadex( + _In_ unsigned _ReturnCode + ); + + + +#ifdef _CRT_USE_WINAPI_FAMILY_DESKTOP_APP + + _ACRTIMP int __cdecl _getpid(void); + + _DCRTIMP intptr_t __cdecl _cwait( + _Out_opt_ int* _TermStat, + _In_ intptr_t _ProcHandle, + _In_ int _Action + ); + + _DCRTIMP intptr_t __cdecl _execl( + _In_z_ char const* _FileName, + _In_z_ char const* _Arguments, + ...); + + _DCRTIMP intptr_t __cdecl _execle( + _In_z_ char const* _FileName, + _In_z_ char const* _Arguments, + ...); + + _DCRTIMP intptr_t __cdecl _execlp( + _In_z_ char const* _FileName, + _In_z_ char const* _Arguments, + ...); + + _DCRTIMP intptr_t __cdecl _execlpe( + _In_z_ char const* _FileName, + _In_z_ char const* _Arguments, + ...); + + _DCRTIMP intptr_t __cdecl _execv( + _In_z_ char const* _FileName, + _In_z_ char const* const* _Arguments + ); + + _DCRTIMP intptr_t __cdecl _execve( + _In_z_ char const* _FileName, + _In_z_ char const* const* _Arguments, + _In_opt_z_ char const* const* _Environment + ); + + _DCRTIMP intptr_t __cdecl _execvp( + _In_z_ char const* _FileName, + _In_z_ char const* const* _Arguments + ); + + _DCRTIMP intptr_t __cdecl _execvpe( + _In_z_ char const* _FileName, + _In_z_ char const* const* _Arguments, + _In_opt_z_ char const* const* _Environment + ); + + _DCRTIMP intptr_t __cdecl _spawnl( + _In_ int _Mode, + _In_z_ char const* _FileName, + _In_z_ char const* _Arguments, + ...); + + _DCRTIMP intptr_t __cdecl _spawnle( + _In_ int _Mode, + _In_z_ char const* _FileName, + _In_z_ char const* _Arguments, + ...); + + _DCRTIMP intptr_t __cdecl _spawnlp( + _In_ int _Mode, + _In_z_ char const* _FileName, + _In_z_ char const* _Arguments, + ...); + + _DCRTIMP intptr_t __cdecl _spawnlpe( + _In_ int _Mode, + _In_z_ char const* _FileName, + _In_z_ char const* _Arguments, + ...); + + _DCRTIMP intptr_t __cdecl _spawnv( + _In_ int _Mode, + _In_z_ char const* _FileName, + _In_z_ char const* const* _Arguments + ); + + _DCRTIMP intptr_t __cdecl _spawnve( + _In_ int _Mode, + _In_z_ char const* _FileName, + _In_z_ char const* const* _Arguments, + _In_opt_z_ char const* const* _Environment + ); + + _DCRTIMP intptr_t __cdecl _spawnvp( + _In_ int _Mode, + _In_z_ char const* _FileName, + _In_z_ char const* const* _Arguments + ); + + _DCRTIMP intptr_t __cdecl _spawnvpe( + _In_ int _Mode, + _In_z_ char const* _FileName, + _In_z_ char const* const* _Arguments, + _In_opt_z_ char const* const* _Environment + ); + + _CRT_OBSOLETE(LoadLibrary) + _DCRTIMP intptr_t __cdecl _loaddll( + _In_z_ char* _FileName + ); + + _CRT_OBSOLETE(FreeLibrary) + _DCRTIMP int __cdecl _unloaddll( + _In_ intptr_t _Handle + ); + + typedef int (__cdecl* _GetDllProcAddrProcType)(void); + + _CRT_OBSOLETE(GetProcAddress) + _DCRTIMP _GetDllProcAddrProcType __cdecl _getdllprocaddr( + _In_ intptr_t _Handle, + _In_opt_z_ char* _ProcedureName, + _In_ intptr_t _Ordinal + ); + +#endif // _CRT_USE_WINAPI_FAMILY_DESKTOP_APP + + + +#if defined(_CRT_INTERNAL_NONSTDC_NAMES) && _CRT_INTERNAL_NONSTDC_NAMES + + #define P_WAIT _P_WAIT + #define P_NOWAIT _P_NOWAIT + #define P_OVERLAY _P_OVERLAY + #define OLD_P_OVERLAY _OLD_P_OVERLAY + #define P_NOWAITO _P_NOWAITO + #define P_DETACH _P_DETACH + #define WAIT_CHILD _WAIT_CHILD + #define WAIT_GRANDCHILD _WAIT_GRANDCHILD + + #ifdef _CRT_USE_WINAPI_FAMILY_DESKTOP_APP + + _CRT_NONSTDC_DEPRECATE(_cwait) + _DCRTIMP intptr_t __cdecl cwait( + _Out_opt_ int* _TermStat, + _In_ intptr_t _ProcHandle, + _In_ int _Action + ); + + _CRT_NONSTDC_DEPRECATE(_execl) + _DCRTIMP intptr_t __cdecl execl( + _In_z_ char const* _FileName, + _In_z_ char const* _Arguments, + ...); + + _CRT_NONSTDC_DEPRECATE(_execle) + _DCRTIMP intptr_t __cdecl execle( + _In_z_ char const* _FileName, + _In_z_ char const* _Arguments, + ...); + + _CRT_NONSTDC_DEPRECATE(_execlp) + _DCRTIMP intptr_t __cdecl execlp( + _In_z_ char const* _FileName, + _In_z_ char const* _Arguments, + ...); + + _CRT_NONSTDC_DEPRECATE(_execlpe) + _DCRTIMP intptr_t __cdecl execlpe( + _In_z_ char const* _FileName, + _In_z_ char const* _Arguments, + ...); + + _CRT_NONSTDC_DEPRECATE(_execv) + _DCRTIMP intptr_t __cdecl execv( + _In_z_ char const* _FileName, + _In_z_ char const* const* _Arguments + ); + + _CRT_NONSTDC_DEPRECATE(_execve) + _DCRTIMP intptr_t __cdecl execve( + _In_z_ char const* _FileName, + _In_z_ char const* const* _Arguments, + _In_opt_z_ char const* const* _Environment + ); + + _CRT_NONSTDC_DEPRECATE(_execvp) + _DCRTIMP intptr_t __cdecl execvp( + _In_z_ char const* _FileName, + _In_z_ char const* const* _Arguments + ); + + _CRT_NONSTDC_DEPRECATE(_execvpe) + _DCRTIMP intptr_t __cdecl execvpe( + _In_z_ char const* _FileName, + _In_z_ char const* const* _Arguments, + _In_opt_z_ char const* const* _Environment + ); + + _CRT_NONSTDC_DEPRECATE(_spawnl) + _DCRTIMP intptr_t __cdecl spawnl( + _In_ int _Mode, + _In_z_ char const* _FileName, + _In_z_ char const* _Arguments, + ...); + + _CRT_NONSTDC_DEPRECATE(_spawnle) + _DCRTIMP intptr_t __cdecl spawnle( + _In_ int _Mode, + _In_z_ char const* _FileName, + _In_z_ char const* _Arguments, + ...); + + _CRT_NONSTDC_DEPRECATE(_spawnlp) + _DCRTIMP intptr_t __cdecl spawnlp( + _In_ int _Mode, + _In_z_ char const* _FileName, + _In_z_ char const* _Arguments, + ...); + + _CRT_NONSTDC_DEPRECATE(_spawnlpe) + _DCRTIMP intptr_t __cdecl spawnlpe( + _In_ int _Mode, + _In_z_ char const* _FileName, + _In_z_ char const* _Arguments, + ...); + + _CRT_NONSTDC_DEPRECATE(_spawnv) + _DCRTIMP intptr_t __cdecl spawnv( + _In_ int _Mode, + _In_z_ char const* _FileName, + _In_z_ char const* const* _Arguments); + + _CRT_NONSTDC_DEPRECATE(_spawnve) + _DCRTIMP intptr_t __cdecl spawnve( + _In_ int _Mode, + _In_z_ char const* _FileName, + _In_z_ char const* const* _Arguments, + _In_opt_z_ char const* const* _Environment + ); + + _CRT_NONSTDC_DEPRECATE(_spawnvp) + _DCRTIMP intptr_t __cdecl spawnvp( + _In_ int _Mode, + _In_z_ char const* _FileName, + _In_z_ char const* const* _Arguments + ); + + _CRT_NONSTDC_DEPRECATE(_spawnvpe) + _DCRTIMP intptr_t __cdecl spawnvpe( + _In_ int _Mode, + _In_z_ char const* _FileName, + _In_z_ char const* const* _Arguments, + _In_opt_z_ char const* const* _Environment + ); + + _CRT_NONSTDC_DEPRECATE(_getpid) + _ACRTIMP int __cdecl getpid(void); + + #endif // _CRT_USE_WINAPI_FAMILY_DESKTOP_APP + +#endif // _CRT_INTERNAL_NONSTDC_NAMES + + + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS +#endif // _INC_PROCESS diff --git a/sdk/include/ucrt/safeint.h b/sdk/include/ucrt/safeint.h new file mode 100644 index 0000000000000..ecab94f67dd9a --- /dev/null +++ b/sdk/include/ucrt/safeint.h @@ -0,0 +1,1665 @@ +/*** +*safeint.h - SafeInt class and free-standing functions used to prevent arithmetic overflows +* +* Copyright (c) Microsoft Corporation. All rights reserved. +* +*Purpose: +* +* The SafeInt class is designed to have as low an overhead as possible +* while still ensuring that all integer operations are conducted safely. +* Nearly every operator has been overloaded, with a very few exceptions. +* +* A usability-safety trade-off has been made to help ensure safety. This +* requires that every operation return either a SafeInt or a bool. If we +* allowed an operator to return a base integer type T, then the following +* can happen: +* +* char i = SafeInt(32) * 2 + SafeInt(16) * 4; +* +* The * operators take precedence, get overloaded, return a char, and then +* you have: +* +* char i = (char)64 + (char)64; //overflow! +* +* This situation would mean that safety would depend on usage, which isn't +* acceptable. +* +* One key operator that is missing is an implicit cast to type T. The reason for +* this is that if there is an implicit cast operator, then we end up with +* an ambiguous compile-time precedence. Because of this amiguity, there +* are two methods that are provided: +* +* Casting operators for every native integer type +* +* SafeInt::Ptr() - returns the address of the internal integer +* +* The SafeInt class should be used in any circumstances where ensuring +* integrity of the calculations is more important than performance. See Performance +* Notes below for additional information. +* +* Many of the conditionals will optimize out or be inlined for a release +* build (especially with /Ox), but it does have significantly more overhead, +* especially for signed numbers. If you do not _require_ negative numbers, use +* unsigned integer types - certain types of problems cannot occur, and this class +* performs most efficiently. +* +* Here's an example of when the class should ideally be used - +* +* void* AllocateMemForStructs(int StructSize, int HowMany) +* { +* SafeInt s(StructSize); +* +* s *= HowMany; +* +* return malloc(s); +* +* } +* +* Here's when it should NOT be used: +* +* void foo() +* { +* int i; +* +* for(i = 0; i < 0xffff; i++) +* .... +* } +* +* Error handling - a SafeInt class will throw exceptions if something +* objectionable happens. The exceptions are SafeIntException classes, +* which contain an enum as a code. +* +* Typical usage might be: +* +* bool foo() +* { +* SafeInt s; //note that s == 0 unless set +* +* try{ +* s *= 23; +* .... +* } +* catch(SafeIntException err) +* { +* //handle errors here +* } +* } +* +* SafeInt accepts an error policy as an optional template parameter. +* We provide two error policy along with SafeInt: SafeIntErrorPolicy_SafeIntException, which +* throws SafeIntException in case of error, and SafeIntErrorPolicy_InvalidParameter, which +* calls _invalid_parameter to terminate the program. +* +* You can replace the error policy class with any class you like. This is accomplished by: +* 1) Create a class that has the following interface: +* +* struct YourSafeIntErrorPolicy +* { +* static __declspec(noreturn) void __stdcall SafeIntOnOverflow() +* { +* throw YourException( YourSafeIntArithmeticOverflowError ); +* // or do something else which will terminate the program +* } +* +* static __declspec(noreturn) void __stdcall SafeIntOnDivZero() +* { +* throw YourException( YourSafeIntDivideByZeroError ); +* // or do something else which will terminate the program +* } +* }; +* +* Note that you don't have to throw C++ exceptions, you can throw Win32 exceptions, or do +* anything you like, just don't return from the call back into the code. +* +* 2) Either explicitly declare SafeInts like so: +* SafeInt< int, YourSafeIntErrorPolicy > si; +* or, before including SafeInt: +* #define _SAFEINT_DEFAULT_ERROR_POLICY ::YourSafeIntErrorPolicy +* +* Performance: +* +* Due to the highly nested nature of this class, you can expect relatively poor +* performance in unoptimized code. In tests of optimized code vs. correct inline checks +* in native code, this class has been found to take approximately 8% more CPU time (this varies), +* most of which is due to exception handling. +* +* Binary Operators: +* +* All of the binary operators have certain assumptions built into the class design. +* This is to ensure correctness. Notes on each class of operator follow: +* +* Arithmetic Operators (*,/,+,-,%) +* There are three possible variants: +* SafeInt< T, E > op SafeInt< T, E > +* SafeInt< T, E > op U +* U op SafeInt< T, E > +* +* The SafeInt< T, E > op SafeInt< U, E > variant is explicitly not supported, and if you try to do +* this the compiler with throw the following error: +* +* error C2593: 'operator *' is ambiguous +* +* This is because the arithmetic operators are required to return a SafeInt of some type. +* The compiler cannot know whether you'd prefer to get a type T or a type U returned. If +* you need to do this, you need to extract the value contained within one of the two using +* the casting operator. For example: +* +* SafeInt< T, E > t, result; +* SafeInt< U, E > u; +* +* result = t * (U)u; +* +* Comparison Operators: +* +* Because each of these operators return type bool, mixing SafeInts of differing types is +* allowed. +* +* Shift Operators: +* +* Shift operators always return the type on the left hand side of the operator. Mixed type +* operations are allowed because the return type is always known. +* +* Boolean Operators: +* +* Like comparison operators, these overloads always return type bool, and mixed-type SafeInts +* are allowed. Additionally, specific overloads exist for type bool on both sides of the +* operator. +* +* Binary Operators: +* +* Mixed-type operations are discouraged, however some provision has been made in order to +* enable things like: +* +* SafeInt c = 2; +* +* if(c & 0x02) +* ... +* +* The "0x02" is actually an int, and it needs to work. +* In the case of binary operations on integers smaller than 32-bit, or of mixed type, corner +* cases do exist where you could get unexpected results. In any case where SafeInt returns a different +* result than the underlying operator, it will call _ASSERTE(). You should examine your code and cast things +* properly so that you are not programming with side effects. +* +* Comparison Operators and ANSI Conversions: +* +* The comparison operator behavior in this class varies from the ANSI definition. +* As an example, consider the following: +* +* unsigned int l = 0xffffffff; +* char c = -1; +* +* if(c == l) +* printf("Why is -1 equal to 4 billion???\n"); +* +* The problem here is that c gets cast to an int, now has a value of 0xffffffff, and then gets +* cast again to an unsigned int, losing the true value. This behavior is despite the fact that +* an __int64 exists, and the following code will yield a different (and intuitively correct) +* answer: +* +* if((__int64)c == (__int64)l)) +* printf("Why is -1 equal to 4 billion???\n"); +* else +* printf("Why doesn't the compiler upcast to 64-bits when needed?\n"); +* +* Note that combinations with smaller integers won't display the problem - if you +* changed "unsigned int" above to "unsigned short", you'd get the right answer. +* +* If you prefer to retain the ANSI standard behavior insert, before including safeint.h: +* +* #define _SAFEINT_ANSI_CONVERSIONS 1 +* +* into your source. Behavior differences occur in the following cases: +* 8, 16, and 32-bit signed int, unsigned 32-bit int +* any signed int, unsigned 64-bit int +* Note - the signed int must be negative to show the problem +* +****/ + +#pragma once + +#if !defined(RC_INVOKED) + +#include +#include + +// Disable warnings hit under /Wall: +// C4514: unreferenced inline function has been removed (/Wall) +// C4710: function not inlined (/Wall) +#pragma warning(push) +#pragma warning(disable: 4514) +#pragma warning(disable: 4710) + +#if !defined (_SAFEINT_DEFAULT_ERROR_POLICY) +#define _SAFEINT_DEFAULT_ERROR_POLICY SafeIntErrorPolicy_SafeIntException +#endif /* !defined (_SAFEINT_DEFAULT_ERROR_POLICY) */ + +#if !defined (_SAFEINT_SHIFT_ASSERT) +#define _SAFEINT_SHIFT_ASSERT(x) _ASSERTE(x) +#endif /* !defined (_SAFEINT_SHIFT_ASSERT) */ + +#if !defined (_SAFEINT_BINARY_ASSERT) +#define _SAFEINT_BINARY_ASSERT(x) _ASSERTE(x) +#endif /* !defined (_SAFEINT_BINARY_ASSERT) */ + +#if !defined (_SAFEINT_EXCEPTION_ASSERT) +#define _SAFEINT_EXCEPTION_ASSERT() +#endif /* !defined (_SAFEINT_EXCEPTION_ASSERT) */ + +// by default, SafeInt will accept negation of an unsigned int; +// if you wish to disable it or assert, you can define the following +// macro to be a static assert or a runtime assert +#if !defined (_SAFEINT_UNSIGNED_NEGATION_BEHAVIOR) +#define _SAFEINT_UNSIGNED_NEGATION_BEHAVIOR() +#endif /* !defined (_SAFEINT_UNSIGNED_NEGATION_BEHAVIOR) */ + +// See above "Comparison Operators and ANSI Conversions" for an explanation +// of _SAFEINT_USE_ANSI_CONVERSIONS +#if !defined (_SAFEINT_USE_ANSI_CONVERSIONS) +#define _SAFEINT_USE_ANSI_CONVERSIONS 0 +#endif /* !defined (_SAFEINT_USE_ANSI_CONVERSIONS) */ + +#pragma pack(push, _CRT_PACKING) + +namespace msl +{ + +namespace utilities +{ + +enum SafeIntError +{ + SafeIntNoError = 0, + SafeIntArithmeticOverflow, + SafeIntDivideByZero +}; + +} // namespace utilities + +} // namespace msl + +#include "safeint_internal.h" + +namespace msl +{ + +namespace utilities +{ + +class SafeIntException +{ +public: + SafeIntException() { m_code = SafeIntNoError; } + SafeIntException( SafeIntError code ) + { + m_code = code; + } + SafeIntError m_code; +}; + +struct SafeIntErrorPolicy_SafeIntException +{ + static __declspec(noreturn) void SafeIntOnOverflow() + { + _SAFEINT_EXCEPTION_ASSERT(); + throw SafeIntException( SafeIntArithmeticOverflow ); + } + + static __declspec(noreturn) void SafeIntOnDivZero() + { + _SAFEINT_EXCEPTION_ASSERT(); + throw SafeIntException( SafeIntDivideByZero ); + } +}; + +struct SafeIntErrorPolicy_InvalidParameter +{ + static __declspec(noreturn) void SafeIntOnOverflow() + { + _SAFEINT_EXCEPTION_ASSERT(); + _CRT_SECURE_INVALID_PARAMETER("SafeInt Arithmetic Overflow"); + } + + static __declspec(noreturn) void SafeIntOnDivZero() + { + _SAFEINT_EXCEPTION_ASSERT(); + _CRT_SECURE_INVALID_PARAMETER("SafeInt Divide By Zero"); + } +}; + +// Free-standing functions that can be used where you only need to check one operation +// non-class helper function so that you can check for a cast's validity +// and handle errors how you like + +template < typename T, typename U > +inline bool SafeCast( const T From, U& To ) throw() +{ + return (details::SafeCastHelper< U, T, + details::SafeIntErrorPolicy_NoThrow >::Cast( From, To ) == SafeIntNoError); +} + +template < typename T, typename U > +inline bool SafeEquals( const T t, const U u ) throw() +{ + return details::EqualityTest< T, U >::IsEquals( t, u ); +} + +template < typename T, typename U > +inline bool SafeNotEquals( const T t, const U u ) throw() +{ + return !details::EqualityTest< T, U >::IsEquals( t, u ); +} + +template < typename T, typename U > +inline bool SafeGreaterThan( const T t, const U u ) throw() +{ + return details::GreaterThanTest< T, U >::GreaterThan( t, u ); +} + +template < typename T, typename U > +inline bool SafeGreaterThanEquals( const T t, const U u ) throw() +{ + return !details::GreaterThanTest< U, T >::GreaterThan( u, t ); +} + +template < typename T, typename U > +inline bool SafeLessThan( const T t, const U u ) throw() +{ + return details::GreaterThanTest< U, T >::GreaterThan( u, t ); +} + +template < typename T, typename U > +inline bool SafeLessThanEquals( const T t, const U u ) throw() +{ + return !details::GreaterThanTest< T, U >::GreaterThan( t, u ); +} + +template < typename T, typename U > +inline bool SafeModulus( const T& t, const U& u, T& result ) throw() +{ + return ( details::ModulusHelper< T, U, details::SafeIntErrorPolicy_NoThrow >::Modulus( t, u, result ) == SafeIntNoError ); +} + +template < typename T, typename U > +inline bool SafeMultiply( T t, U u, T& result ) throw() +{ + return ( details::MultiplicationHelper< T, U, + details::SafeIntErrorPolicy_NoThrow >::Multiply( t, u, result ) == SafeIntNoError ); +} + +template < typename T, typename U > +inline bool SafeDivide( T t, U u, T& result ) throw() +{ + return ( details::DivisionHelper< T, U, + details::SafeIntErrorPolicy_NoThrow >::Divide( t, u, result ) == SafeIntNoError ); +} + +template < typename T, typename U > +inline bool SafeAdd( T t, U u, T& result ) throw() +{ + return ( details::AdditionHelper< T, U, + details::SafeIntErrorPolicy_NoThrow >::Addition( t, u, result ) == SafeIntNoError ); +} + +template < typename T, typename U > +inline bool SafeSubtract( T t, U u, T& result ) throw() +{ + return ( details::SubtractionHelper< T, U, + details::SafeIntErrorPolicy_NoThrow >::Subtract( t, u, result ) == SafeIntNoError ); +} + +// SafeInt class +template < typename T, typename E = _SAFEINT_DEFAULT_ERROR_POLICY > +class SafeInt +{ +public: + SafeInt() throw() + { + static_assert( details::NumericType< T >::isInt , "SafeInt: T needs to be an integer type" ); + m_int = 0; + } + + // Having a constructor for every type of int + // avoids having the compiler evade our checks when doing implicit casts - + // e.g., SafeInt s = 0x7fffffff; + SafeInt( const T& i ) throw() + { + static_assert( details::NumericType< T >::isInt , "SafeInt: T needs to be an integer type" ); + //always safe + m_int = i; + } + + // provide explicit boolean converter + SafeInt( bool b ) throw() + { + static_assert( details::NumericType< T >::isInt , "SafeInt: T needs to be an integer type" ); + m_int = b ? 1 : 0; + } + + template < typename U > + SafeInt(const SafeInt< U, E >& u) + { + static_assert( details::NumericType< T >::isInt , "SafeInt: T needs to be an integer type" ); + *this = SafeInt< T, E >( (U)u ); + } + + template < typename U > + SafeInt( const U& i ) + { + static_assert( details::NumericType< T >::isInt , "SafeInt: T needs to be an integer type" ); + // SafeCast will throw exceptions if i won't fit in type T + details::SafeCastHelper< T, U, E >::Cast( i, m_int ); + } + + // now start overloading operators + // assignment operator + // constructors exist for all int types and will ensure safety + + template < typename U > + SafeInt< T, E >& operator =( const U& rhs ) + { + // use constructor to test size + // constructor is optimized to do minimal checking based + // on whether T can contain U + // note - do not change this + *this = SafeInt< T, E >( rhs ); + return *this; + } + + SafeInt< T, E >& operator =( const T& rhs ) throw() + { + m_int = rhs; + return *this; + } + + template < typename U > + SafeInt< T, E >& operator =( const SafeInt< U, E >& rhs ) + { + details::SafeCastHelper< T, U, E >::Cast( rhs.Ref(), m_int ); + return *this; + } + + SafeInt< T, E >& operator =( const SafeInt< T, E >& rhs ) throw() + { + m_int = rhs.m_int; + return *this; + } + + // Casting operators + + operator bool() const throw() + { + return !!m_int; + } + + operator char() const + { + char val; + details::SafeCastHelper< char, T, E >::Cast( m_int, val ); + return val; + } + + operator signed char() const + { + signed char val; + details::SafeCastHelper< signed char, T, E >::Cast( m_int, val ); + return val; + } + + operator unsigned char() const + { + unsigned char val; + details::SafeCastHelper< unsigned char, T, E >::Cast( m_int, val ); + return val; + } + + operator __int16() const + { + __int16 val; + details::SafeCastHelper< __int16, T, E >::Cast( m_int, val ); + return val; + } + + operator unsigned __int16() const + { + unsigned __int16 val; + details::SafeCastHelper< unsigned __int16, T, E >::Cast( m_int, val ); + return val; + } + + operator __int32() const + { + __int32 val; + details::SafeCastHelper< __int32, T, E >::Cast( m_int, val ); + return val; + } + + operator unsigned __int32() const + { + unsigned __int32 val; + details::SafeCastHelper< unsigned __int32, T, E >::Cast( m_int, val ); + return val; + } + + // The compiler knows that int == __int32 + // but not that long == __int32 + operator long() const + { + long val; + details::SafeCastHelper< long, T, E >::Cast( m_int, val ); + return val; + } + + operator unsigned long() const + { + unsigned long val; + details::SafeCastHelper< unsigned long, T, E >::Cast( m_int, val ); + return val; + } + + operator __int64() const + { + __int64 val; + details::SafeCastHelper< __int64, T, E >::Cast( m_int, val ); + return val; + } + + operator unsigned __int64() const + { + unsigned __int64 val; + details::SafeCastHelper< unsigned __int64, T, E >::Cast( m_int, val ); + return val; + } + +#ifdef _NATIVE_WCHAR_T_DEFINED + operator wchar_t() const + { + unsigned __int16 val; + details::SafeCastHelper< unsigned __int16, T, E >::Cast( m_int, val ); + return val; + } +#endif /* _NATIVE_WCHAR_T_DEFINED */ + + // If you need a pointer to the data + // this could be dangerous, but allows you to correctly pass + // instances of this class to APIs that take a pointer to an integer + // also see overloaded address-of operator below + T* Ptr() throw() { return &m_int; } + const T* Ptr() const throw() { return &m_int; } + const T& Ref() const throw() { return m_int; } + + // Unary operators + bool operator !() const throw() { return (!m_int) ? true : false; } + + // operator + (unary) + // note - normally, the '+' and '-' operators will upcast to a signed int + // for T < 32 bits. This class changes behavior to preserve type + const SafeInt< T, E >& operator +() const throw() { return *this; }; + + //unary - + SafeInt< T, E > operator -() const + { + // Note - unsigned still performs the bitwise manipulation + // will warn at level 2 or higher if the value is 32-bit or larger + T tmp; + details::NegationHelper< T, E, details::IntTraits< T >::isSigned >::Negative( m_int, tmp ); + return SafeInt< T, E >( tmp ); + } + + // prefix increment operator + SafeInt< T, E >& operator ++() + { + if( m_int != details::IntTraits< T >::maxInt ) + { + ++m_int; + return *this; + } + E::SafeIntOnOverflow(); + } + + // prefix decrement operator + SafeInt< T, E >& operator --() + { + if( m_int != details::IntTraits< T >::minInt ) + { + --m_int; + return *this; + } + E::SafeIntOnOverflow(); + } + + // note that postfix operators have inherently worse perf + // characteristics + + // postfix increment operator + SafeInt< T, E > operator ++( int ) // dummy arg to comply with spec + { + if( m_int != details::IntTraits< T >::maxInt ) + { + SafeInt< T, E > tmp( m_int ); + + m_int++; + return tmp; + } + E::SafeIntOnOverflow(); + } + + // postfix decrement operator + SafeInt< T, E > operator --( int ) // dummy arg to comply with spec + { + if( m_int != details::IntTraits< T >::minInt ) + { + SafeInt< T, E > tmp( m_int ); + m_int--; + return tmp; + } + E::SafeIntOnOverflow(); + } + + // One's complement + // Note - this operator will normally change size to an int + // cast in return improves perf and maintains type + SafeInt< T, E > operator ~() const throw() { return SafeInt< T, E >( (T)~m_int ); } + + // Binary operators + // + // arithmetic binary operators + // % modulus + // * multiplication + // / division + // + addition + // - subtraction + // + // For each of the arithmetic operators, you will need to + // use them as follows: + // + // SafeInt c = 2; + // SafeInt i = 3; + // + // SafeInt i2 = i op (char)c; + // OR + // SafeInt i2 = (int)i op c; + // + // The base problem is that if the lhs and rhs inputs are different SafeInt types + // it is not possible in this implementation to determine what type of SafeInt + // should be returned. You have to let the class know which of the two inputs + // need to be the return type by forcing the other value to the base integer type. + // + // Note - as per feedback from Scott Meyers, I'm exploring how to get around this. + // 3.0 update - I'm still thinking about this. It can be done with template metaprogramming, + // but it is tricky, and there's a perf vs. correctness tradeoff where the right answer + // is situational. + // + // The case of: + // + // SafeInt< T, E > i, j, k; + // i = j op k; + // + // works just fine and no unboxing is needed because the return type is not ambiguous. + + // Modulus + // Modulus has some convenient properties - + // first, the magnitude of the return can never be + // larger than the lhs operand, and it must be the same sign + // as well. It does, however, suffer from the same promotion + // problems as comparisons, division and other operations + template < typename U > + SafeInt< T, E > operator %( U rhs ) const + { + T result; + details::ModulusHelper< T, U, E >::Modulus( m_int, rhs, result ); + return SafeInt< T, E >( result ); + } + + SafeInt< T, E > operator %( SafeInt< T, E > rhs ) const + { + T result; + details::ModulusHelper< T, T, E >::Modulus( m_int, rhs, result ); + return SafeInt< T, E >( result ); + } + + // Modulus assignment + template < typename U > + SafeInt< T, E >& operator %=( U rhs ) + { + details::ModulusHelper< T, U, E >::Modulus( m_int, rhs, m_int ); + return *this; + } + + template < typename U > + SafeInt< T, E >& operator %=( SafeInt< U, E > rhs ) + { + details::ModulusHelper< T, U, E >::Modulus( m_int, (U)rhs, m_int ); + return *this; + } + + // Multiplication + template < typename U > + SafeInt< T, E > operator *( U rhs ) const + { + T ret( 0 ); + details::MultiplicationHelper< T, U, E >::Multiply( m_int, rhs, ret ); + return SafeInt< T, E >( ret ); + } + + SafeInt< T, E > operator *( SafeInt< T, E > rhs ) const + { + T ret( 0 ); + details::MultiplicationHelper< T, T, E >::Multiply( m_int, (T)rhs, ret ); + return SafeInt< T, E >( ret ); + } + + // Multiplication assignment + SafeInt< T, E >& operator *=( SafeInt< T, E > rhs ) + { + details::MultiplicationHelper< T, T, E >::Multiply( m_int, (T)rhs, m_int ); + return *this; + } + + template < typename U > + SafeInt< T, E >& operator *=( U rhs ) + { + details::MultiplicationHelper< T, U, E >::Multiply( m_int, rhs, m_int ); + return *this; + } + + template < typename U > + SafeInt< T, E >& operator *=( SafeInt< U, E > rhs ) + { + details::MultiplicationHelper< T, U, E >::Multiply( m_int, rhs.Ref(), m_int ); + return *this; + } + + // Division + template < typename U > + SafeInt< T, E > operator /( U rhs ) const + { + T ret( 0 ); + details::DivisionHelper< T, U, E >::Divide( m_int, rhs, ret ); + return SafeInt< T, E >( ret ); + } + + SafeInt< T, E > operator /( SafeInt< T, E > rhs ) const + { + T ret( 0 ); + details::DivisionHelper< T, T, E >::Divide( m_int, (T)rhs, ret ); + return SafeInt< T, E >( ret ); + } + + // Division assignment + SafeInt< T, E >& operator /=( SafeInt< T, E > i ) + { + details::DivisionHelper< T, T, E >::Divide( m_int, (T)i, m_int ); + return *this; + } + + template < typename U > SafeInt< T, E >& operator /=( U i ) + { + details::DivisionHelper< T, U, E >::Divide( m_int, i, m_int ); + return *this; + } + + template < typename U > SafeInt< T, E >& operator /=( SafeInt< U, E > i ) + { + details::DivisionHelper< T, U, E >::Divide( m_int, (U)i, m_int ); + return *this; + } + + // For addition and subtraction + + // Addition + SafeInt< T, E > operator +( SafeInt< T, E > rhs ) const + { + T ret( 0 ); + details::AdditionHelper< T, T, E >::Addition( m_int, (T)rhs, ret ); + return SafeInt< T, E >( ret ); + } + + template < typename U > + SafeInt< T, E > operator +( U rhs ) const + { + T ret( 0 ); + details::AdditionHelper< T, U, E >::Addition( m_int, rhs, ret ); + return SafeInt< T, E >( ret ); + } + + //addition assignment + SafeInt< T, E >& operator +=( SafeInt< T, E > rhs ) + { + details::AdditionHelper< T, T, E >::Addition( m_int, (T)rhs, m_int ); + return *this; + } + + template < typename U > + SafeInt< T, E >& operator +=( U rhs ) + { + details::AdditionHelper< T, U, E >::Addition( m_int, rhs, m_int ); + return *this; + } + + template < typename U > + SafeInt< T, E >& operator +=( SafeInt< U, E > rhs ) + { + details::AdditionHelper< T, U, E >::Addition( m_int, (U)rhs, m_int ); + return *this; + } + + // Subtraction + template < typename U > + SafeInt< T, E > operator -( U rhs ) const + { + T ret( 0 ); + details::SubtractionHelper< T, U, E >::Subtract( m_int, rhs, ret ); + return SafeInt< T, E >( ret ); + } + + SafeInt< T, E > operator -(SafeInt< T, E > rhs) const + { + T ret( 0 ); + details::SubtractionHelper< T, T, E >::Subtract( m_int, (T)rhs, ret ); + return SafeInt< T, E >( ret ); + } + + // Subtraction assignment + SafeInt< T, E >& operator -=( SafeInt< T, E > rhs ) + { + details::SubtractionHelper< T, T, E >::Subtract( m_int, (T)rhs, m_int ); + return *this; + } + + template < typename U > + SafeInt< T, E >& operator -=( U rhs ) + { + details::SubtractionHelper< T, U, E >::Subtract( m_int, rhs, m_int ); + return *this; + } + + template < typename U > + SafeInt< T, E >& operator -=( SafeInt< U, E > rhs ) + { + details::SubtractionHelper< T, U, E >::Subtract( m_int, (U)rhs, m_int ); + return *this; + } + + // Comparison operators + // Additional overloads defined outside the class + // to allow for cases where the SafeInt is the rhs value + + // Less than + template < typename U > + bool operator <( U rhs ) const throw() + { + return details::GreaterThanTest< U, T >::GreaterThan( rhs, m_int ); + } + + bool operator <( SafeInt< T, E > rhs ) const throw() + { + return m_int < (T)rhs; + } + + // Greater than or eq. + template < typename U > + bool operator >=( U rhs ) const throw() + { + return !details::GreaterThanTest< U, T >::GreaterThan( rhs, m_int ); + } + + bool operator >=( SafeInt< T, E > rhs ) const throw() + { + return m_int >= (T)rhs; + } + + // Greater than + template < typename U > + bool operator >( U rhs ) const throw() + { + return details::GreaterThanTest< T, U >::GreaterThan( m_int, rhs ); + } + + bool operator >( SafeInt< T, E > rhs ) const throw() + { + return m_int > (T)rhs; + } + + // Less than or eq. + template < typename U > + bool operator <=( U rhs ) const throw() + { + return !details::GreaterThanTest< T, U >::GreaterThan( m_int, rhs ); + } + + bool operator <=( SafeInt< T, E > rhs ) const throw() + { + return m_int <= (T)rhs; + } + + // Equality + template < typename U > + bool operator ==( U rhs ) const throw() + { + return details::EqualityTest< T, U >::IsEquals( m_int, rhs ); + } + + // Need an explicit override for type bool + bool operator ==( bool rhs ) const throw() + { + return ( m_int == 0 ? false : true ) == rhs; + } + + bool operator ==( SafeInt< T, E > rhs ) const throw() { return m_int == (T)rhs; } + + // != operators + template < typename U > + bool operator !=( U rhs ) const throw() + { + return !details::EqualityTest< T, U >::IsEquals( m_int, rhs ); + } + + bool operator !=( bool b ) const throw() + { + return ( m_int == 0 ? false : true ) != b; + } + + bool operator !=( SafeInt< T, E > rhs ) const throw() { return m_int != (T)rhs; } + + // Shift operators + // Note - shift operators ALWAYS return the same type as the lhs + // specific version for SafeInt< T, E > not needed - + // code path is exactly the same as for SafeInt< U, E > as rhs + + // Left shift + // Also, shifting > bitcount is undefined - trap in debug (check _SAFEINT_SHIFT_ASSERT) + + template < typename U > + SafeInt< T, E > operator <<( U bits ) const throw() + { + _SAFEINT_SHIFT_ASSERT( !details::IntTraits< U >::isSigned || bits >= 0 ); + _SAFEINT_SHIFT_ASSERT( bits < (int)details::IntTraits< T >::bitCount ); + + return SafeInt< T, E >( (T)( m_int << bits ) ); + } + + template < typename U > + SafeInt< T, E > operator <<( SafeInt< U, E > bits ) const throw() + { + _SAFEINT_SHIFT_ASSERT( !details::IntTraits< U >::isSigned || (U)bits >= 0 ); + _SAFEINT_SHIFT_ASSERT( (U)bits < (int)details::IntTraits< T >::bitCount ); + + return SafeInt< T, E >( (T)( m_int << (U)bits ) ); + } + + // Left shift assignment + + template < typename U > + SafeInt< T, E >& operator <<=( U bits ) throw() + { + _SAFEINT_SHIFT_ASSERT( !details::IntTraits< U >::isSigned || bits >= 0 ); + _SAFEINT_SHIFT_ASSERT( bits < (int)details::IntTraits< T >::bitCount ); + + m_int <<= bits; + return *this; + } + + template < typename U > + SafeInt< T, E >& operator <<=( SafeInt< U, E > bits ) throw() + { + _SAFEINT_SHIFT_ASSERT( !details::IntTraits< U >::isSigned || (U)bits >= 0 ); + _SAFEINT_SHIFT_ASSERT( (U)bits < (int)details::IntTraits< T >::bitCount ); + + m_int <<= (U)bits; + return *this; + } + + // Right shift + template < typename U > + SafeInt< T, E > operator >>( U bits ) const throw() + { + _SAFEINT_SHIFT_ASSERT( !details::IntTraits< U >::isSigned || bits >= 0 ); + _SAFEINT_SHIFT_ASSERT( bits < (int)details::IntTraits< T >::bitCount ); + + return SafeInt< T, E >( (T)( m_int >> bits ) ); + } + + template < typename U > + SafeInt< T, E > operator >>( SafeInt< U, E > bits ) const throw() + { + _SAFEINT_SHIFT_ASSERT( !details::IntTraits< U >::isSigned || (U)bits >= 0 ); + _SAFEINT_SHIFT_ASSERT( bits < (int)details::IntTraits< T >::bitCount ); + + return SafeInt< T, E >( (T)(m_int >> (U)bits) ); + } + + // Right shift assignment + template < typename U > + SafeInt< T, E >& operator >>=( U bits ) throw() + { + _SAFEINT_SHIFT_ASSERT( !details::IntTraits< U >::isSigned || bits >= 0 ); + _SAFEINT_SHIFT_ASSERT( bits < (int)details::IntTraits< T >::bitCount ); + + m_int >>= bits; + return *this; + } + + template < typename U > + SafeInt< T, E >& operator >>=( SafeInt< U, E > bits ) throw() + { + _SAFEINT_SHIFT_ASSERT( !details::IntTraits< U >::isSigned || (U)bits >= 0 ); + _SAFEINT_SHIFT_ASSERT( (U)bits < (int)details::IntTraits< T >::bitCount ); + + m_int >>= (U)bits; + return *this; + } + + // Bitwise operators + // This only makes sense if we're dealing with the same type and size + // demand a type T, or something that fits into a type T + + // Bitwise & + SafeInt< T, E > operator &( SafeInt< T, E > rhs ) const throw() + { + return SafeInt< T, E >( m_int & (T)rhs ); + } + + template < typename U > + SafeInt< T, E > operator &( U rhs ) const throw() + { + // we want to avoid setting bits by surprise + // consider the case of lhs = int, value = 0xffffffff + // rhs = char, value = 0xff + // + // programmer intent is to get only the lower 8 bits + // normal behavior is to upcast both sides to an int + // which then sign extends rhs, setting all the bits + + // If you land in the assert, this is because the bitwise operator + // was causing unexpected behavior. Fix is to properly cast your inputs + // so that it works like you meant, not unexpectedly + + return SafeInt< T, E >( details::BinaryAndHelper< T, U >::And( m_int, rhs ) ); + } + + // Bitwise & assignment + SafeInt< T, E >& operator &=( SafeInt< T, E > rhs ) throw() + { + m_int &= (T)rhs; + return *this; + } + + template < typename U > + SafeInt< T, E >& operator &=( U rhs ) throw() + { + m_int = details::BinaryAndHelper< T, U >::And( m_int, rhs ); + return *this; + } + + template < typename U > + SafeInt< T, E >& operator &=( SafeInt< U, E > rhs ) throw() + { + m_int = details::BinaryAndHelper< T, U >::And( m_int, (U)rhs ); + return *this; + } + + // XOR + SafeInt< T, E > operator ^( SafeInt< T, E > rhs ) const throw() + { + return SafeInt< T, E >( (T)( m_int ^ (T)rhs ) ); + } + + template < typename U > + SafeInt< T, E > operator ^( U rhs ) const throw() + { + // If you land in the assert, this is because the bitwise operator + // was causing unexpected behavior. Fix is to properly cast your inputs + // so that it works like you meant, not unexpectedly + + return SafeInt< T, E >( details::BinaryXorHelper< T, U >::Xor( m_int, rhs ) ); + } + + // XOR assignment + SafeInt< T, E >& operator ^=( SafeInt< T, E > rhs ) throw() + { + m_int ^= (T)rhs; + return *this; + } + + template < typename U > + SafeInt< T, E >& operator ^=( U rhs ) throw() + { + m_int = details::BinaryXorHelper< T, U >::Xor( m_int, rhs ); + return *this; + } + + template < typename U > + SafeInt< T, E >& operator ^=( SafeInt< U, E > rhs ) throw() + { + m_int = details::BinaryXorHelper< T, U >::Xor( m_int, (U)rhs ); + return *this; + } + + // bitwise OR + SafeInt< T, E > operator |( SafeInt< T, E > rhs ) const throw() + { + return SafeInt< T, E >( (T)( m_int | (T)rhs ) ); + } + + template < typename U > + SafeInt< T, E > operator |( U rhs ) const throw() + { + return SafeInt< T, E >( details::BinaryOrHelper< T, U >::Or( m_int, rhs ) ); + } + + // bitwise OR assignment + SafeInt< T, E >& operator |=( SafeInt< T, E > rhs ) throw() + { + m_int |= (T)rhs; + return *this; + } + + template < typename U > + SafeInt< T, E >& operator |=( U rhs ) throw() + { + m_int = details::BinaryOrHelper< T, U >::Or( m_int, rhs ); + return *this; + } + + template < typename U > + SafeInt< T, E >& operator |=( SafeInt< U, E > rhs ) throw() + { + m_int = details::BinaryOrHelper< T, U >::Or( m_int, (U)rhs ); + return *this; + } + + // Miscellaneous helper functions + SafeInt< T, E > Min( SafeInt< T, E > test, SafeInt< T, E > floor = SafeInt< T, E >( details::IntTraits< T >::minInt ) ) const throw() + { + T tmp = test < m_int ? test : m_int; + return tmp < floor ? floor : tmp; + } + + SafeInt< T, E > Max( SafeInt< T, E > test, SafeInt< T, E > upper = SafeInt< T, E >( details::IntTraits< T >::maxInt ) ) const throw() + { + T tmp = test > m_int ? test : m_int; + return tmp > upper ? upper : tmp; + } + + void Swap( SafeInt< T, E >& with ) throw() + { + T temp( m_int ); + m_int = with.m_int; + with.m_int = temp; + } + + template < int bits > + const SafeInt< T, E >& Align() + { + // Zero is always aligned + if( m_int == 0 ) + return *this; + + // We don't support aligning negative numbers at this time + // Can't align unsigned numbers on bitCount (e.g., 8 bits = 256, unsigned char max = 255) + // or signed numbers on bitCount-1 (e.g., 7 bits = 128, signed char max = 127). + // Also makes no sense to try to align on negative or no bits. + + _SAFEINT_SHIFT_ASSERT( ( ( details::IntTraits::isSigned && bits < (int)details::IntTraits< T >::bitCount - 1 ) + || ( !details::IntTraits::isSigned && bits < (int)details::IntTraits< T >::bitCount ) ) && + bits >= 0 && ( !details::IntTraits::isSigned || m_int > 0 ) ); + + const T AlignValue = ( (T)1 << bits ) - 1; + + m_int = ( m_int + AlignValue ) & ~AlignValue; + + if( m_int <= 0 ) + E::SafeIntOnOverflow(); + + return *this; + } + + // Commonly needed alignments: + const SafeInt< T, E >& Align2() { return Align< 1 >(); } + const SafeInt< T, E >& Align4() { return Align< 2 >(); } + const SafeInt< T, E >& Align8() { return Align< 3 >(); } + const SafeInt< T, E >& Align16() { return Align< 4 >(); } + const SafeInt< T, E >& Align32() { return Align< 5 >(); } + const SafeInt< T, E >& Align64() { return Align< 6 >(); } + +private: + T m_int; +}; + +// Externally defined functions for the case of U op SafeInt< T, E > +template < typename T, typename U, typename E > +bool operator <( U lhs, SafeInt< T, E > rhs ) throw() +{ + return details::GreaterThanTest< T, U >::GreaterThan( (T)rhs, lhs ); +} + +template < typename T, typename U, typename E > +bool operator <( SafeInt< U, E > lhs, SafeInt< T, E > rhs ) throw() +{ + return details::GreaterThanTest< T, U >::GreaterThan( (T)rhs, (U)lhs ); +} + +// Greater than +template < typename T, typename U, typename E > +bool operator >( U lhs, SafeInt< T, E > rhs ) throw() +{ + return details::GreaterThanTest< U, T >::GreaterThan( lhs, (T)rhs ); +} + +template < typename T, typename U, typename E > +bool operator >( SafeInt< T, E > lhs, SafeInt< U, E > rhs ) throw() +{ + return details::GreaterThanTest< T, U >::GreaterThan( (T)lhs, (U)rhs ); +} + +// Greater than or equal +template < typename T, typename U, typename E > +bool operator >=( U lhs, SafeInt< T, E > rhs ) throw() +{ + return !details::GreaterThanTest< T, U >::GreaterThan( (T)rhs, lhs ); +} + +template < typename T, typename U, typename E > +bool operator >=( SafeInt< T, E > lhs, SafeInt< U, E > rhs ) throw() +{ + return !details::GreaterThanTest< U, T >::GreaterThan( (U)rhs, (T)lhs ); +} + +// Less than or equal +template < typename T, typename U, typename E > +bool operator <=( U lhs, SafeInt< T, E > rhs ) throw() +{ + return !details::GreaterThanTest< U, T >::GreaterThan( lhs, (T)rhs ); +} + +template < typename T, typename U, typename E > +bool operator <=( SafeInt< T, E > lhs, SafeInt< U, E > rhs ) throw() +{ + return !details::GreaterThanTest< T, U >::GreaterThan( (T)lhs, (U)rhs ); +} + +// equality +// explicit overload for bool +template < typename T, typename E > +bool operator ==( bool lhs, SafeInt< T, E > rhs ) throw() +{ + return lhs == ( (T)rhs == 0 ? false : true ); +} + +template < typename T, typename U, typename E > +bool operator ==( U lhs, SafeInt< T, E > rhs ) throw() +{ + return details::EqualityTest< T, U >::IsEquals((T)rhs, lhs); +} + +template < typename T, typename U, typename E > +bool operator ==( SafeInt< T, E > lhs, SafeInt< U, E > rhs ) throw() +{ + return details::EqualityTest< T, U >::IsEquals( (T)lhs, (U)rhs ); +} + +//not equals +template < typename T, typename U, typename E > +bool operator !=( U lhs, SafeInt< T, E > rhs ) throw() +{ + return !details::EqualityTest< T, U >::IsEquals( rhs, lhs ); +} + +template < typename T, typename E > +bool operator !=( bool lhs, SafeInt< T, E > rhs ) throw() +{ + return ( (T)rhs == 0 ? false : true ) != lhs; +} + +template < typename T, typename U, typename E > +bool operator !=( SafeInt< T, E > lhs, SafeInt< U, E > rhs ) throw() +{ + return !details::EqualityTest< T, U >::IsEquals( lhs, rhs ); +} + +// Modulus +template < typename T, typename U, typename E > +SafeInt< T, E > operator %( U lhs, SafeInt< T, E > rhs ) +{ + // Value of return depends on sign of lhs + // This one may not be safe - bounds check in constructor + // if lhs is negative and rhs is unsigned, this will throw an exception. + + // Fast-track the simple case + // same size and same sign +#pragma warning(suppress:4127 6326) + if( sizeof(T) == sizeof(U) && details::IntTraits< T >::isSigned == details::IntTraits< U >::isSigned ) + { + if( rhs != 0 ) + { + if( details::IntTraits< T >::isSigned && (T)rhs == -1 ) + return 0; + + return SafeInt< T, E >( (T)( lhs % (T)rhs ) ); + } + + E::SafeIntOnDivZero(); + } + + return SafeInt< T, E >( ( SafeInt< U, E >( lhs ) % (T)rhs ) ); +} + +// Multiplication +template < typename T, typename U, typename E > +SafeInt< T, E > operator *( U lhs, SafeInt< T, E > rhs ) +{ + T ret( 0 ); + details::MultiplicationHelper< T, U, E >::Multiply( (T)rhs, lhs, ret ); + return SafeInt< T, E >(ret); +} + +// Division +template < typename T, typename U, typename E > SafeInt< T, E > operator /( U lhs, SafeInt< T, E > rhs ) +{ +#pragma warning(push) +#pragma warning(disable: 4127 4146 4307 4310 6326) + // Corner case - has to be handled separately + if( details::DivisionMethod< U, T >::method == details::DivisionState_UnsignedSigned ) + { + if( (T)rhs > 0 ) + return SafeInt< T, E >( lhs/(T)rhs ); + + // Now rhs is either negative, or zero + if( (T)rhs != 0 ) + { + if( sizeof( U ) >= 4 && sizeof( T ) <= sizeof( U ) ) + { + // Problem case - normal casting behavior changes meaning + // flip rhs to positive + // any operator casts now do the right thing + U tmp; + if( sizeof(T) == 4 ) + tmp = lhs/(U)(unsigned __int32)( -(T)rhs ); + else + tmp = lhs/(U)( -(T)rhs ); + + if( tmp <= details::IntTraits< T >::maxInt ) + return SafeInt< T, E >( -( (T)tmp ) ); + + // Corner case + // Note - this warning happens because we're not using partial + // template specialization in this case. For any real cases where + // this block isn't optimized out, the warning won't be present. + if( tmp == (U)details::IntTraits< T >::maxInt + 1 ) + return SafeInt< T, E >( details::IntTraits< T >::minInt ); + + E::SafeIntOnOverflow(); + } + + return SafeInt< T, E >(lhs/(T)rhs); + } + + E::SafeIntOnDivZero(); + } // method == DivisionState_UnsignedSigned + + if( details::SafeIntCompare< T, U >::isBothSigned ) + { + if( lhs == details::IntTraits< U >::minInt && (T)rhs == -1 ) + { + // corner case of a corner case - lhs = min int, rhs = -1, + // but rhs is the return type, so in essence, we can return -lhs + // if rhs is a larger type than lhs + if( sizeof( U ) < sizeof( T ) ) + { + return SafeInt< T, E >( (T)( -(T)details::IntTraits< U >::minInt ) ); + } + + // If rhs is smaller or the same size int, then -minInt won't work + E::SafeIntOnOverflow(); + } + } + + // Otherwise normal logic works with addition of bounds check when casting from U->T + U ret; + details::DivisionHelper< U, T, E >::Divide( lhs, (T)rhs, ret ); + return SafeInt< T, E >( ret ); +#pragma warning(pop) +} + +// Addition +template < typename T, typename U, typename E > +SafeInt< T, E > operator +( U lhs, SafeInt< T, E > rhs ) +{ + T ret( 0 ); + details::AdditionHelper< T, U, E >::Addition( (T)rhs, lhs, ret ); + return SafeInt< T, E >( ret ); +} + +// Subtraction +template < typename T, typename U, typename E > +SafeInt< T, E > operator -( U lhs, SafeInt< T, E > rhs ) +{ + T ret( 0 ); + details::SubtractionHelper< U, T, E, details::SubtractionMethod2< U, T >::method >::Subtract( lhs, rhs.Ref(), ret ); + + return SafeInt< T, E >( ret ); +} + +// Overrides designed to deal with cases where a SafeInt is assigned out +// to a normal int - this at least makes the last operation safe +// += +template < typename T, typename U, typename E > +T& operator +=( T& lhs, SafeInt< U, E > rhs ) +{ + T ret( 0 ); + details::AdditionHelper< T, U, E >::Addition( lhs, (U)rhs, ret ); + lhs = ret; + return lhs; +} + +template < typename T, typename U, typename E > +T& operator -=( T& lhs, SafeInt< U, E > rhs ) +{ + T ret( 0 ); + details::SubtractionHelper< T, U, E >::Subtract( lhs, (U)rhs, ret ); + lhs = ret; + return lhs; +} + +template < typename T, typename U, typename E > +T& operator *=( T& lhs, SafeInt< U, E > rhs ) +{ + T ret( 0 ); + details::MultiplicationHelper< T, U, E >::Multiply( lhs, (U)rhs, ret ); + lhs = ret; + return lhs; +} + +template < typename T, typename U, typename E > +T& operator /=( T& lhs, SafeInt< U, E > rhs ) +{ + T ret( 0 ); + details::DivisionHelper< T, U, E >::Divide( lhs, (U)rhs, ret ); + lhs = ret; + return lhs; +} + +template < typename T, typename U, typename E > +T& operator %=( T& lhs, SafeInt< U, E > rhs ) +{ + T ret( 0 ); + details::ModulusHelper< T, U, E >::Modulus( lhs, (U)rhs, ret ); + lhs = ret; + return lhs; +} + +template < typename T, typename U, typename E > +T& operator &=( T& lhs, SafeInt< U, E > rhs ) throw() +{ + lhs = details::BinaryAndHelper< T, U >::And( lhs, (U)rhs ); + return lhs; +} + +template < typename T, typename U, typename E > +T& operator ^=( T& lhs, SafeInt< U, E > rhs ) throw() +{ + lhs = details::BinaryXorHelper< T, U >::Xor( lhs, (U)rhs ); + return lhs; +} + +template < typename T, typename U, typename E > +T& operator |=( T& lhs, SafeInt< U, E > rhs ) throw() +{ + lhs = details::BinaryOrHelper< T, U >::Or( lhs, (U)rhs ); + return lhs; +} + +template < typename T, typename U, typename E > +T& operator <<=( T& lhs, SafeInt< U, E > rhs ) throw() +{ + lhs = (T)( SafeInt< T, E >( lhs ) << (U)rhs ); + return lhs; +} + +template < typename T, typename U, typename E > +T& operator >>=( T& lhs, SafeInt< U, E > rhs ) throw() +{ + lhs = (T)( SafeInt< T, E >( lhs ) >> (U)rhs ); + return lhs; +} + +// Specific pointer overrides +// Note - this function makes no attempt to ensure +// that the resulting pointer is still in the buffer, only +// that no int overflows happened on the way to getting the new pointer +template < typename T, typename U, typename E > +T*& operator +=( T*& lhs, SafeInt< U, E > rhs ) +{ + // Cast the pointer to a number so we can do arithmetic + SafeInt< uintptr_t, E > ptr_val = reinterpret_cast< uintptr_t >( lhs ); + // Check first that rhs is valid for the type of ptrdiff_t + // and that multiplying by sizeof( T ) doesn't overflow a ptrdiff_t + // Next, we need to add 2 SafeInts of different types, so unbox the ptr_diff + // Finally, cast the number back to a pointer of the correct type + lhs = reinterpret_cast< T* >( (uintptr_t)( ptr_val + (ptrdiff_t)( SafeInt< ptrdiff_t, E >( rhs ) * sizeof( T ) ) ) ); + return lhs; +} + +template < typename T, typename U, typename E > +T*& operator -=( T*& lhs, SafeInt< U, E > rhs ) +{ + // Cast the pointer to a number so we can do arithmetic + SafeInt< size_t, E > ptr_val = reinterpret_cast< uintptr_t >( lhs ); + // See above for comments + lhs = reinterpret_cast< T* >( (uintptr_t)( ptr_val - (ptrdiff_t)( SafeInt< ptrdiff_t, E >( rhs ) * sizeof( T ) ) ) ); + return lhs; +} + +template < typename T, typename U, typename E > +T*& operator *=( T* lhs, SafeInt< U, E >) +{ + static_assert( details::DependentFalse< T >::value, "SafeInt: This operator explicitly not supported" ); + return lhs; +} + +template < typename T, typename U, typename E > +T*& operator /=( T* lhs, SafeInt< U, E >) +{ + static_assert( details::DependentFalse< T >::value, "SafeInt: This operator explicitly not supported" ); + return lhs; +} + +template < typename T, typename U, typename E > +T*& operator %=( T* lhs, SafeInt< U, E >) +{ + static_assert( details::DependentFalse< T >::value, "SafeInt: This operator explicitly not supported" ); + return lhs; +} + +template < typename T, typename U, typename E > +T*& operator &=( T* lhs, SafeInt< U, E >) +{ + static_assert( details::DependentFalse< T >::value, "SafeInt: This operator explicitly not supported" ); + return lhs; +} + +template < typename T, typename U, typename E > +T*& operator ^=( T* lhs, SafeInt< U, E >) +{ + static_assert( details::DependentFalse< T >::value, "SafeInt: This operator explicitly not supported" ); + return lhs; +} + +template < typename T, typename U, typename E > +T*& operator |=( T* lhs, SafeInt< U, E >) +{ + static_assert( details::DependentFalse< T >::value, "SafeInt: This operator explicitly not supported" ); + return lhs; +} + +template < typename T, typename U, typename E > +T*& operator <<=( T* lhs, SafeInt< U, E >) +{ + static_assert( details::DependentFalse< T >::value, "SafeInt: This operator explicitly not supported" ); + return lhs; +} + +template < typename T, typename U, typename E > +T*& operator >>=( T* lhs, SafeInt< U, E >) +{ + static_assert( details::DependentFalse< T >::value, "SafeInt: This operator explicitly not supported" ); + return lhs; +} + +// Shift operators +// NOTE - shift operators always return the type of the lhs argument + +// Left shift +template < typename T, typename U, typename E > +SafeInt< U, E > operator <<( U lhs, SafeInt< T, E > bits ) throw() +{ + _SAFEINT_SHIFT_ASSERT( !details::IntTraits< T >::isSigned || (T)bits >= 0 ); + _SAFEINT_SHIFT_ASSERT( (T)bits < (int)details::IntTraits< U >::bitCount ); + + return SafeInt< U, E >( (U)( lhs << (T)bits ) ); +} + +// Right shift +template < typename T, typename U, typename E > +SafeInt< U, E > operator >>( U lhs, SafeInt< T, E > bits ) throw() +{ + _SAFEINT_SHIFT_ASSERT( !details::IntTraits< T >::isSigned || (T)bits >= 0 ); + _SAFEINT_SHIFT_ASSERT( (T)bits < (int)details::IntTraits< U >::bitCount ); + + return SafeInt< U, E >( (U)( lhs >> (T)bits ) ); +} + +// Bitwise operators +// This only makes sense if we're dealing with the same type and size +// demand a type T, or something that fits into a type T. + +// Bitwise & +template < typename T, typename U, typename E > +SafeInt< T, E > operator &( U lhs, SafeInt< T, E > rhs ) throw() +{ + return SafeInt< T, E >( details::BinaryAndHelper< T, U >::And( (T)rhs, lhs ) ); +} + +// Bitwise XOR +template < typename T, typename U, typename E > +SafeInt< T, E > operator ^( U lhs, SafeInt< T, E > rhs ) throw() +{ + return SafeInt< T, E >(details::BinaryXorHelper< T, U >::Xor( (T)rhs, lhs ) ); +} + +// Bitwise OR +template < typename T, typename U, typename E > +SafeInt< T, E > operator |( U lhs, SafeInt< T, E > rhs ) throw() +{ + return SafeInt< T, E >( details::BinaryOrHelper< T, U >::Or( (T)rhs, lhs ) ); +} + +} // namespace utilities + +} // namespace msl + +#pragma pack(pop) + +#pragma warning(pop) // Disable /Wall warnings +#endif // RC_INVOKED diff --git a/sdk/include/ucrt/safeint_internal.h b/sdk/include/ucrt/safeint_internal.h new file mode 100644 index 0000000000000..89a6852bf7fa1 --- /dev/null +++ b/sdk/include/ucrt/safeint_internal.h @@ -0,0 +1,2898 @@ +/*** +*safeint_internal.h - Internal details for SafeInt (see safeint.h) +* +* Copyright (c) Microsoft Corporation. All rights reserved. +* +*Purpose: +* Private internal details for SafeInt. +* The constructs and functions in Microsoft::Utilities::details are not +* meant to be used by external code and can change at any time. +* +****/ + +#pragma once + +#include + +#pragma pack(push, _CRT_PACKING) + +namespace msl +{ + +namespace utilities +{ + +namespace details +{ +#pragma warning(push) +#pragma warning(disable:4702) + +template < typename T > +class DependentFalse { public: enum{ value = false }; }; + +template < typename T > class NumericType; + +template <> class NumericType { public: enum{ isBool = true, isFloat = false, isInt = false }; }; +template <> class NumericType { public: enum{ isBool = false, isFloat = false, isInt = true }; }; +template <> class NumericType { public: enum{ isBool = false, isFloat = false, isInt = true }; }; +template <> class NumericType { public: enum{ isBool = false, isFloat = false, isInt = true }; }; +template <> class NumericType { public: enum{ isBool = false, isFloat = false, isInt = true }; }; +template <> class NumericType { public: enum{ isBool = false, isFloat = false, isInt = true }; }; +#ifdef _NATIVE_WCHAR_T_DEFINED +template <> class NumericType { public: enum{ isBool = false, isFloat = false, isInt = true }; }; +#endif /* _NATIVE_WCHAR_T_DEFINED */ +template <> class NumericType { public: enum{ isBool = false, isFloat = false, isInt = true }; }; +template <> class NumericType { public: enum{ isBool = false, isFloat = false, isInt = true }; }; +template <> class NumericType { public: enum{ isBool = false, isFloat = false, isInt = true }; }; +template <> class NumericType { public: enum{ isBool = false, isFloat = false, isInt = true }; }; +template <> class NumericType<__int64> { public: enum{ isBool = false, isFloat = false, isInt = true }; }; +template <> class NumericType { public: enum{ isBool = false, isFloat = false, isInt = true }; }; +template <> class NumericType { public: enum{ isBool = false, isFloat = true, isInt = false }; }; +template <> class NumericType { public: enum{ isBool = false, isFloat = true, isInt = false }; }; +template <> class NumericType { public: enum{ isBool = false, isFloat = true, isInt = false }; }; +// Catch-all for anything not supported +template < typename T > class NumericType { public: enum{ isBool = false, isFloat = false, isInt = false }; }; + + +template < typename T > class IntTraits +{ +public: + static_assert( NumericType::isInt || NumericType::isBool, "non-integral type T" ); + enum + { +#pragma warning(suppress:4804) + isSigned = ( (T)(-1) < 0 ), + is64Bit = ( sizeof(T) == 8 ), + is32Bit = ( sizeof(T) == 4 ), + is16Bit = ( sizeof(T) == 2 ), + is8Bit = ( sizeof(T) == 1 ), + isLT32Bit = ( sizeof(T) < 4 ), + isLT64Bit = ( sizeof(T) < 8 ), + isInt8 = ( sizeof(T) == 1 && isSigned ), + isUint8 = ( sizeof(T) == 1 && !isSigned ), + isInt16 = ( sizeof(T) == 2 && isSigned ), + isUint16 = ( sizeof(T) == 2 && !isSigned ), + isInt32 = ( sizeof(T) == 4 && isSigned ), + isUint32 = ( sizeof(T) == 4 && !isSigned ), + isInt64 = ( sizeof(T) == 8 && isSigned ), + isUint64 = ( sizeof(T) == 8 && !isSigned ), + bitCount = ( sizeof(T)*8 ), +#pragma warning(suppress:4804) + isBool = NumericType::isBool + }; + +#pragma warning(push) +#pragma warning(disable:4310) +#pragma warning(disable:4804) // suppress warning about '<<' being an unsafe operation when T is bool + const static T maxInt = isSigned ? ((T)~((T)1 << (T)(bitCount-1))) : ((T)(~(T)0)); + const static T minInt = isSigned ? ((T)((T)1 << (T)(bitCount-1))) : ((T)0); +#pragma warning(pop) +}; + +// this is strictly internal and not to be used as a policy in SafeInt<> +struct SafeIntErrorPolicy_NoThrow +{ + static void SafeIntOnOverflow() + { + } + + static void SafeIntOnDivZero() + { + } +}; + +template < typename T, typename U > class SafeIntCompare +{ +public: + enum + { + isBothSigned = (IntTraits< T >::isSigned && IntTraits< U >::isSigned), + isBothUnsigned = (!IntTraits< T >::isSigned && !IntTraits< U >::isSigned), + isLikeSigned = (static_cast(IntTraits< T >::isSigned) == static_cast(IntTraits< U >::isSigned)), + isCastOK = ((isLikeSigned && sizeof(T) >= sizeof(U)) || + (IntTraits< T >::isSigned && sizeof(T) > sizeof(U))), + isBothLT32Bit = (IntTraits< T >::isLT32Bit && IntTraits< U >::isLT32Bit), + isBothLT64Bit = (IntTraits< T >::isLT64Bit && IntTraits< U >::isLT64Bit) + }; +}; + +template < typename U > class SafeIntCompare< float, U > +{ +public: + enum + { + isBothSigned = IntTraits< U >::isSigned, + isBothUnsigned = false, + isLikeSigned = IntTraits< U >::isSigned, + isCastOK = true + }; +}; + +template < typename U > class SafeIntCompare< double, U > +{ +public: + enum + { + isBothSigned = IntTraits< U >::isSigned, + isBothUnsigned = false, + isLikeSigned = IntTraits< U >::isSigned, + isCastOK = true + }; +}; + +template < typename U > class SafeIntCompare< long double, U > +{ +public: + enum + { + isBothSigned = IntTraits< U >::isSigned, + isBothUnsigned = false, + isLikeSigned = IntTraits< U >::isSigned, + isCastOK = true + }; +}; + +//all of the arithmetic operators can be solved by the same code within +//each of these regions without resorting to compile-time constant conditionals +//most operators collapse the problem into less than the 22 zones, but this is used +//as the first cut +//using this also helps ensure that we handle all of the possible cases correctly + +template < typename T, typename U > class IntRegion +{ +public: + enum + { + //unsigned-unsigned zone + IntZone_UintLT32_UintLT32 = SafeIntCompare< T,U >::isBothUnsigned && SafeIntCompare< T,U >::isBothLT32Bit, + IntZone_Uint32_UintLT64 = SafeIntCompare< T,U >::isBothUnsigned && IntTraits< T >::is32Bit && IntTraits< U >::isLT64Bit, + IntZone_UintLT32_Uint32 = SafeIntCompare< T,U >::isBothUnsigned && IntTraits< T >::isLT32Bit && IntTraits< U >::is32Bit, + IntZone_Uint64_Uint = SafeIntCompare< T,U >::isBothUnsigned && IntTraits< T >::is64Bit, + IntZone_UintLT64_Uint64 = SafeIntCompare< T,U >::isBothUnsigned && IntTraits< T >::isLT64Bit && IntTraits< U >::is64Bit, + //unsigned-signed + IntZone_UintLT32_IntLT32 = !IntTraits< T >::isSigned && IntTraits< U >::isSigned && SafeIntCompare< T,U >::isBothLT32Bit, + IntZone_Uint32_IntLT64 = IntTraits< T >::isUint32 && IntTraits< U >::isSigned && IntTraits< U >::isLT64Bit, + IntZone_UintLT32_Int32 = !IntTraits< T >::isSigned && IntTraits< T >::isLT32Bit && IntTraits< U >::isInt32, + IntZone_Uint64_Int = IntTraits< T >::isUint64 && IntTraits< U >::isSigned && IntTraits< U >::isLT64Bit, + IntZone_UintLT64_Int64 = !IntTraits< T >::isSigned && IntTraits< T >::isLT64Bit && IntTraits< U >::isInt64, + IntZone_Uint64_Int64 = IntTraits< T >::isUint64 && IntTraits< U >::isInt64, + //signed-signed + IntZone_IntLT32_IntLT32 = SafeIntCompare< T,U >::isBothSigned && SafeIntCompare< T, U >::isBothLT32Bit, + IntZone_Int32_IntLT64 = SafeIntCompare< T,U >::isBothSigned && IntTraits< T >::is32Bit && IntTraits< U >::isLT64Bit, + IntZone_IntLT32_Int32 = SafeIntCompare< T,U >::isBothSigned && IntTraits< T >::isLT32Bit && IntTraits< U >::is32Bit, + IntZone_Int64_Int64 = SafeIntCompare< T,U >::isBothSigned && IntTraits< T >::isInt64 && IntTraits< U >::isInt64, + IntZone_Int64_Int = SafeIntCompare< T,U >::isBothSigned && IntTraits< T >::is64Bit && IntTraits< U >::isLT64Bit, + IntZone_IntLT64_Int64 = SafeIntCompare< T,U >::isBothSigned && IntTraits< T >::isLT64Bit && IntTraits< U >::is64Bit, + //signed-unsigned + IntZone_IntLT32_UintLT32 = IntTraits< T >::isSigned && !IntTraits< U >::isSigned && SafeIntCompare< T,U >::isBothLT32Bit, + IntZone_Int32_UintLT32 = IntTraits< T >::isInt32 && !IntTraits< U >::isSigned && IntTraits< U >::isLT32Bit, + IntZone_IntLT64_Uint32 = IntTraits< T >::isSigned && IntTraits< T >::isLT64Bit && IntTraits< U >::isUint32, + IntZone_Int64_UintLT64 = IntTraits< T >::isInt64 && !IntTraits< U >::isSigned && IntTraits< U >::isLT64Bit, + IntZone_Int_Uint64 = IntTraits< T >::isSigned && IntTraits< U >::isUint64 && IntTraits< T >::isLT64Bit, + IntZone_Int64_Uint64 = IntTraits< T >::isInt64 && IntTraits< U >::isUint64 + }; +}; + +// useful function to help with getting the magnitude of a negative number +enum AbsMethod +{ + AbsMethodInt, + AbsMethodInt64, + AbsMethodNoop +}; + +template < typename T > +class GetAbsMethod +{ +public: + enum + { + method = IntTraits< T >::isLT64Bit && IntTraits< T >::isSigned ? AbsMethodInt : + IntTraits< T >::isInt64 ? AbsMethodInt64 : AbsMethodNoop + }; +}; + +template < typename T, int Method = GetAbsMethod< T >::method > class AbsValueHelper; + +template < typename T > class AbsValueHelper < T, AbsMethodInt > +{ +public: + static unsigned __int32 Abs( T t ) throw() + { + _ASSERTE( t < 0 ); + return (unsigned __int32)-t; + } +}; + +template < typename T > class AbsValueHelper < T, AbsMethodInt64 > +{ +public: + static unsigned __int64 Abs( T t ) throw() + { + _ASSERTE( t < 0 ); + return (unsigned __int64)-t; + } +}; + +template < typename T > class AbsValueHelper < T, AbsMethodNoop > +{ +public: + static T Abs( T t ) throw() + { + // Why are you calling Abs on an unsigned number ??? + _ASSERTE( ("AbsValueHelper::Abs should not be called with an unsigned integer type", 0) ); + return t; + } +}; + +template < typename T, typename E, bool fSigned > class NegationHelper; + +template < typename T, typename E > class NegationHelper < T, E, true > // Signed +{ +public: + static SafeIntError Negative( T t, T& ret ) + { + // corner case + if( t != IntTraits< T >::minInt ) + { + // cast prevents unneeded checks in the case of small ints + ret = -t; + return SafeIntNoError; + } + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + + +template < typename T, typename E > class NegationHelper < T, E, false > // unsigned +{ +public: + static SafeIntError Negative( T t, T& ret ) throw() + { + _SAFEINT_UNSIGNED_NEGATION_BEHAVIOR(); + +#pragma warning(suppress:4127) + _ASSERTE( !IntTraits::isLT32Bit ); + +#pragma warning(suppress:4146) + ret = -t; + return SafeIntNoError; + } +}; + +//core logic to determine casting behavior +enum CastMethod +{ + CastOK = 0, + CastCheckLTZero, + CastCheckGTMax, + CastCheckMinMaxUnsigned, + CastCheckMinMaxSigned, + CastFromFloat, + CastToBool, + CastFromBool +}; + +template < typename ToType, typename FromType > +class GetCastMethod +{ +public: + enum + { + method = ( IntTraits< FromType >::isBool && + !IntTraits< ToType >::isBool ) ? CastFromBool : + + ( !IntTraits< FromType >::isBool && + IntTraits< ToType >::isBool ) ? CastToBool : + ( NumericType< FromType >::isFloat && + !NumericType< ToType >::isFloat ) ? CastFromFloat : + + ( SafeIntCompare< ToType, FromType >::isCastOK || + ( NumericType< ToType >::isFloat && + !NumericType< FromType >::isFloat ) ) ? CastOK : + + ( ( IntTraits< ToType >::isSigned && + !IntTraits< FromType >::isSigned && + sizeof( FromType ) >= sizeof( ToType ) ) || + ( SafeIntCompare< ToType, FromType >::isBothUnsigned && + sizeof( FromType ) > sizeof( ToType ) ) ) ? CastCheckGTMax : + + ( !IntTraits< ToType >::isSigned && + IntTraits< FromType >::isSigned && + sizeof( ToType ) >= sizeof( FromType ) ) ? CastCheckLTZero : + + ( !IntTraits< ToType >::isSigned ) ? CastCheckMinMaxUnsigned + : CastCheckMinMaxSigned + }; +}; + +template < typename T, typename U, typename E, + int Method = GetCastMethod< T, U >::method > class SafeCastHelper; + +template < typename T, typename U, typename E > class SafeCastHelper < T, U, E, CastOK > +{ +public: + static SafeIntError Cast( U u, T& t ) throw() + { + t = (T)u; + return SafeIntNoError; + } +}; + +// special case floats and doubles +// tolerate loss of precision +template < typename T, typename U, typename E > class SafeCastHelper < T, U, E, CastFromFloat > +{ +public: + static SafeIntError Cast( U u, T& t ) + { + if( u <= (U)IntTraits< T >::maxInt && + u >= (U)IntTraits< T >::minInt ) + { + t = (T)u; + return SafeIntNoError; + } + + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +// Match on any method where a bool is cast to type T +template < typename T, typename U, typename E > class SafeCastHelper < T, U, E, CastFromBool > +{ +public: + static SafeIntError Cast( bool b, T& t ) throw() + { + t = (T)( b ? 1 : 0 ); + return SafeIntNoError; + } +}; + +template < typename T, typename U, typename E > class SafeCastHelper < T, U, E, CastToBool > +{ +public: + static SafeIntError Cast( T t, bool& b ) throw() + { + b = !!t; + return SafeIntNoError; + } +}; + +template < typename T, typename U, typename E > class SafeCastHelper < T, U, E, CastCheckLTZero > +{ +public: + static SafeIntError Cast( U u, T& t ) + { + if( u < 0 ) + { + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } + + t = (T)u; + return SafeIntNoError; + } +}; + +template < typename T, typename U, typename E > class SafeCastHelper < T, U, E, CastCheckGTMax > +{ +public: + static SafeIntError Cast( U u, T& t ) + { + if( u > IntTraits< T >::maxInt ) + { + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } + + t = (T)u; + return SafeIntNoError; + } +}; + +template < typename T, typename U, typename E > class SafeCastHelper < T, U, E, CastCheckMinMaxUnsigned > +{ +public: + static SafeIntError Cast( U u, T& t ) + { + // U is signed - T could be either signed or unsigned + if( u > IntTraits< T >::maxInt || u < 0 ) + { + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } + + t = (T)u; + return SafeIntNoError; + } +}; + +template < typename T, typename U, typename E > class SafeCastHelper < T, U, E, CastCheckMinMaxSigned > +{ +public: + static SafeIntError Cast( U u, T& t ) + { + // T, U are signed + if( u > IntTraits< T >::maxInt || u < IntTraits< T >::minInt ) + { + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } + + t = (T)u; + return SafeIntNoError; + } +}; + +//core logic to determine whether a comparison is valid, or needs special treatment +enum ComparisonMethod +{ + ComparisonMethod_Ok = 0, + ComparisonMethod_CastInt, + ComparisonMethod_CastInt64, + ComparisonMethod_UnsignedT, + ComparisonMethod_UnsignedU +}; + +template < typename T, typename U > +class ValidComparison +{ +public: + enum + { +#if _SAFEINT_USE_ANSI_CONVERSIONS + method = ComparisonMethod_Ok +#else /* _SAFEINT_USE_ANSI_CONVERSIONS */ + method = ( ( SafeIntCompare< T, U >::isLikeSigned ) ? ComparisonMethod_Ok : + ( ( IntTraits< T >::isSigned && sizeof(T) < 8 && sizeof(U) < 4 ) || + ( IntTraits< U >::isSigned && sizeof(T) < 4 && sizeof(U) < 8 ) ) ? ComparisonMethod_CastInt : + ( ( IntTraits< T >::isSigned && sizeof(U) < 8 ) || + ( IntTraits< U >::isSigned && sizeof(T) < 8 ) ) ? ComparisonMethod_CastInt64 : + ( !IntTraits< T >::isSigned ) ? ComparisonMethod_UnsignedT : + ComparisonMethod_UnsignedU ) +#endif /* _SAFEINT_USE_ANSI_CONVERSIONS */ + }; +}; + +template ::method > class EqualityTest; + +template < typename T, typename U > class EqualityTest< T, U, ComparisonMethod_Ok > +{ +public: + static bool IsEquals( const T t, const U u ) throw() { return ( t == u ); } +}; + +template < typename T, typename U > class EqualityTest< T, U, ComparisonMethod_CastInt > +{ +public: + static bool IsEquals( const T t, const U u ) throw() { return ( (int)t == (int)u ); } +}; + +template < typename T, typename U > class EqualityTest< T, U, ComparisonMethod_CastInt64 > +{ +public: + static bool IsEquals( const T t, const U u ) throw() { return ( (__int64)t == (__int64)u ); } +}; + +template < typename T, typename U > class EqualityTest< T, U, ComparisonMethod_UnsignedT > +{ +public: + static bool IsEquals( const T t, const U u ) throw() + { + //one operand is 32 or 64-bit unsigned, and the other is signed and the same size or smaller + if( u < 0 ) + { + return false; + } + + //else safe to cast to type T + return ( t == (T)u ); + } +}; + +template < typename T, typename U > class EqualityTest< T, U, ComparisonMethod_UnsignedU> +{ +public: + static bool IsEquals( const T t, const U u ) throw() + { + //one operand is 32 or 64-bit unsigned, and the other is signed and the same size or smaller + if( t < 0 ) + { + return false; + } + + //else safe to cast to type U + return ( (U)t == u ); + } +}; + +template ::method > class GreaterThanTest; + +template < typename T, typename U > class GreaterThanTest< T, U, ComparisonMethod_Ok > +{ +public: + static bool GreaterThan( const T t, const U u ) throw() { return ( t > u ); } +}; + +template < typename T, typename U > class GreaterThanTest< T, U, ComparisonMethod_CastInt > +{ +public: + static bool GreaterThan( const T t, const U u ) throw() { return ( (int)t > (int)u ); } +}; + +template < typename T, typename U > class GreaterThanTest< T, U, ComparisonMethod_CastInt64 > +{ +public: + static bool GreaterThan( const T t, const U u ) throw() { return ( (__int64)t > (__int64)u ); } +}; + +template < typename T, typename U > class GreaterThanTest< T, U, ComparisonMethod_UnsignedT > +{ +public: + static bool GreaterThan( const T t, const U u ) throw() + { + // one operand is 32 or 64-bit unsigned, and the other is signed and the same size or smaller + if( u < 0 ) + { + return SafeIntNoError; + } + + // else safe to cast to type T + return ( t > (T)u ); + } +}; + +template < typename T, typename U > class GreaterThanTest< T, U, ComparisonMethod_UnsignedU > +{ +public: + static bool GreaterThan( const T t, const U u ) throw() + { + // one operand is 32 or 64-bit unsigned, and the other is signed and the same size or smaller + if( t < 0 ) + { + return false; + } + + // else safe to cast to type U + return ( (U)t > u ); + } +}; + +// Modulus is simpler than comparison, but follows much the same logic +// using this set of functions, it can't fail except in a div 0 situation +template ::method > class ModulusHelper; + +template class ModulusHelper +{ +public: + static SafeIntError Modulus( const T& t, const U& u, T& result ) + { + if(u == 0) + { + E::SafeIntOnDivZero(); + return SafeIntDivideByZero; + } + + // trap corner case +#pragma warning(suppress:4127) + if( IntTraits< U >::isSigned ) + { + if(u == -1) + { + result = 0; + return SafeIntNoError; + } + } + + result = (T)(t % u); + return SafeIntNoError; + } +}; + +template class ModulusHelper +{ +public: + static SafeIntError Modulus( const T& t, const U& u, T& result ) + { + if(u == 0) + { + E::SafeIntOnDivZero(); + return SafeIntDivideByZero; + } + + // trap corner case +#pragma warning(suppress:4127) + if( IntTraits< U >::isSigned ) + { + if(u == -1) + { + result = 0; + return SafeIntNoError; + } + } + + result = (T)(t % u); + return SafeIntNoError; + } +}; + +template class ModulusHelper +{ +public: + static SafeIntError Modulus( const T& t, const U& u, T& result ) + { + if(u == 0) + { + E::SafeIntOnDivZero(); + return SafeIntDivideByZero; + } + +#pragma warning(suppress:4127) + if(IntTraits< U >::isSigned && u == -1) + { + result = 0; + } + else + { + result = (T)((__int64)t % (__int64)u); + } + + return SafeIntNoError; + } +}; + +// T is unsigned __int64, U is any signed int +template class ModulusHelper +{ +public: + static SafeIntError Modulus( const T& t, const U& u, T& result ) + { + if(u == 0) + { + E::SafeIntOnDivZero(); + return SafeIntDivideByZero; + } + + // u could be negative - if so, need to convert to positive + // casts below are always safe due to the way modulus works + if(u < 0) + { + result = (T)(t % AbsValueHelper< U >::Abs(u)); + } + else + { + result = (T)(t % u); + } + + return SafeIntNoError; + } +}; + +// U is unsigned __int64, T any signed int +template class ModulusHelper +{ +public: + static SafeIntError Modulus( const T& t, const U& u, T& result ) + { + if(u == 0) + { + E::SafeIntOnDivZero(); + return SafeIntDivideByZero; + } + + //t could be negative - if so, need to convert to positive + if(t < 0) + { + result = -(T)( AbsValueHelper< T >::Abs( t ) % u ); + } + else + { + result = (T)((T)t % u); + } + + return SafeIntNoError; + } +}; + +//core logic to determine method to check multiplication +enum MultiplicationState +{ + MultiplicationState_CastInt = 0, // One or both signed, smaller than 32-bit + MultiplicationState_CastInt64, // One or both signed, smaller than 64-bit + MultiplicationState_CastUint, // Both are unsigned, smaller than 32-bit + MultiplicationState_CastUint64, // Both are unsigned, both 32-bit or smaller + MultiplicationState_Uint64Uint, // Both are unsigned, lhs 64-bit, rhs 32-bit or smaller + MultiplicationState_Uint64Uint64, // Both are unsigned int64 + MultiplicationState_Uint64Int, // lhs is unsigned int64, rhs int32 + MultiplicationState_Uint64Int64, // lhs is unsigned int64, rhs signed int64 + MultiplicationState_UintUint64, // Both are unsigned, lhs 32-bit or smaller, rhs 64-bit + MultiplicationState_UintInt64, // lhs unsigned 32-bit or less, rhs int64 + MultiplicationState_Int64Uint, // lhs int64, rhs unsigned int32 + MultiplicationState_Int64Int64, // lhs int64, rhs int64 + MultiplicationState_Int64Int, // lhs int64, rhs int32 + MultiplicationState_IntUint64, // lhs int, rhs unsigned int64 + MultiplicationState_IntInt64, // lhs int, rhs int64 + MultiplicationState_Int64Uint64, // lhs int64, rhs uint64 + MultiplicationState_Error +}; + +template < typename T, typename U > +class MultiplicationMethod +{ +public: + enum + { + // unsigned-unsigned + method = (IntRegion< T,U >::IntZone_UintLT32_UintLT32 ? MultiplicationState_CastUint : + (IntRegion< T,U >::IntZone_Uint32_UintLT64 || + IntRegion< T,U >::IntZone_UintLT32_Uint32) ? MultiplicationState_CastUint64 : + SafeIntCompare< T,U >::isBothUnsigned && + IntTraits< T >::isUint64 && IntTraits< U >::isUint64 ? MultiplicationState_Uint64Uint64 : + (IntRegion< T,U >::IntZone_Uint64_Uint) ? MultiplicationState_Uint64Uint : + (IntRegion< T,U >::IntZone_UintLT64_Uint64) ? MultiplicationState_UintUint64 : + // unsigned-signed + (IntRegion< T,U >::IntZone_UintLT32_IntLT32) ? MultiplicationState_CastInt : + (IntRegion< T,U >::IntZone_Uint32_IntLT64 || + IntRegion< T,U >::IntZone_UintLT32_Int32) ? MultiplicationState_CastInt64 : + (IntRegion< T,U >::IntZone_Uint64_Int) ? MultiplicationState_Uint64Int : + (IntRegion< T,U >::IntZone_UintLT64_Int64) ? MultiplicationState_UintInt64 : + (IntRegion< T,U >::IntZone_Uint64_Int64) ? MultiplicationState_Uint64Int64 : + // signed-signed + (IntRegion< T,U >::IntZone_IntLT32_IntLT32) ? MultiplicationState_CastInt : + (IntRegion< T,U >::IntZone_Int32_IntLT64 || + IntRegion< T,U >::IntZone_IntLT32_Int32) ? MultiplicationState_CastInt64 : + (IntRegion< T,U >::IntZone_Int64_Int64) ? MultiplicationState_Int64Int64 : + (IntRegion< T,U >::IntZone_Int64_Int) ? MultiplicationState_Int64Int : + (IntRegion< T,U >::IntZone_IntLT64_Int64) ? MultiplicationState_IntInt64 : + // signed-unsigned + (IntRegion< T,U >::IntZone_IntLT32_UintLT32) ? MultiplicationState_CastInt : + (IntRegion< T,U >::IntZone_Int32_UintLT32 || + IntRegion< T,U >::IntZone_IntLT64_Uint32) ? MultiplicationState_CastInt64 : + (IntRegion< T,U >::IntZone_Int64_UintLT64) ? MultiplicationState_Int64Uint : + (IntRegion< T,U >::IntZone_Int_Uint64) ? MultiplicationState_IntUint64 : + (IntRegion< T,U >::IntZone_Int64_Uint64 ? MultiplicationState_Int64Uint64 : + MultiplicationState_Error ) ) + }; +}; + +template ::method > class MultiplicationHelper; + +template < typename T, typename U, typename E > class MultiplicationHelper< T, U, E, MultiplicationState_CastInt> +{ +public: + //accepts signed, both less than 32-bit + static SafeIntError Multiply( const T& t, const U& u, T& ret ) + { + int tmp = t * u; + + if( tmp > IntTraits< T >::maxInt || tmp < IntTraits< T >::minInt ) + { + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } + + ret = (T)tmp; + return SafeIntNoError; + } +}; + +template < typename T, typename U, typename E > class MultiplicationHelper< T, U, E, MultiplicationState_CastUint > +{ +public: + //accepts unsigned, both less than 32-bit + static SafeIntError Multiply( const T& t, const U& u, T& ret ) + { + unsigned int tmp = t * u; + + if( tmp > IntTraits< T >::maxInt ) + { + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } + + ret = (T)tmp; + return SafeIntNoError; + } +}; + +template < typename T, typename U, typename E > class MultiplicationHelper< T, U, E, MultiplicationState_CastInt64> +{ +public: + //mixed signed or both signed where at least one argument is 32-bit, and both a 32-bit or less + static SafeIntError Multiply( const T& t, const U& u, T& ret ) + { + __int64 tmp = (__int64)t * (__int64)u; + + if(tmp > (__int64)IntTraits< T >::maxInt || tmp < (__int64)IntTraits< T >::minInt) + { + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } + + ret = (T)tmp; + return SafeIntNoError; + } +}; + +template < typename T, typename U, typename E > class MultiplicationHelper< T, U, E, MultiplicationState_CastUint64> +{ +public: + //both unsigned where at least one argument is 32-bit, and both are 32-bit or less + static SafeIntError Multiply( const T& t, const U& u, T& ret ) + { + unsigned __int64 tmp = (unsigned __int64)t * (unsigned __int64)u; + + if(tmp > (unsigned __int64)IntTraits< T >::maxInt) + { + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } + + ret = (T)tmp; + return SafeIntNoError; + } +}; + +// T = left arg and return type +// U = right arg +template < typename T, typename U, typename E > class LargeIntRegMultiply; + +template< typename E > class LargeIntRegMultiply< unsigned __int64, unsigned __int64, E > +{ +public: + static SafeIntError RegMultiply( const unsigned __int64& a, const unsigned __int64& b, unsigned __int64& ret ) + { + unsigned __int32 aHigh, aLow, bHigh, bLow; + + // Consider that a*b can be broken up into: + // (aHigh * 2^32 + aLow) * (bHigh * 2^32 + bLow) + // => (aHigh * bHigh * 2^64) + (aLow * bHigh * 2^32) + (aHigh * bLow * 2^32) + (aLow * bLow) + // Note - same approach applies for 128 bit math on a 64-bit system + + aHigh = (unsigned __int32)(a >> 32); + aLow = (unsigned __int32)a; + bHigh = (unsigned __int32)(b >> 32); + bLow = (unsigned __int32)b; + + ret = 0; + + if(aHigh == 0) + { + if(bHigh != 0) + { + ret = (unsigned __int64)aLow * (unsigned __int64)bHigh; + } + } + else if(bHigh == 0) + { + if(aHigh != 0) + { + ret = (unsigned __int64)aHigh * (unsigned __int64)bLow; + } + } + else + { + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } + + if(ret != 0) + { + unsigned __int64 tmp; + + if((unsigned __int32)(ret >> 32) != 0) + { + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } + + ret <<= 32; + tmp = (unsigned __int64)aLow * (unsigned __int64)bLow; + ret += tmp; + + if(ret < tmp) + { + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } + + return SafeIntNoError; + } + + ret = (unsigned __int64)aLow * (unsigned __int64)bLow; + return SafeIntNoError; + } +}; + +template< typename E > class LargeIntRegMultiply< unsigned __int64, unsigned __int32, E > +{ +public: + static SafeIntError RegMultiply( const unsigned __int64& a, unsigned __int32 b, unsigned __int64& ret ) + { + unsigned __int32 aHigh, aLow; + + // Consider that a*b can be broken up into: + // (aHigh * 2^32 + aLow) * b + // => (aHigh * b * 2^32) + (aLow * b) + + aHigh = (unsigned __int32)(a >> 32); + aLow = (unsigned __int32)a; + + ret = 0; + + if(aHigh != 0) + { + ret = (unsigned __int64)aHigh * (unsigned __int64)b; + + unsigned __int64 tmp; + + if((unsigned __int32)(ret >> 32) != 0) + { + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } + + ret <<= 32; + tmp = (unsigned __int64)aLow * (unsigned __int64)b; + ret += tmp; + + if(ret < tmp) + { + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } + + return SafeIntNoError; + } + + ret = (unsigned __int64)aLow * (unsigned __int64)b; + return SafeIntNoError; + } +}; + +template< typename E > class LargeIntRegMultiply< unsigned __int64, signed __int32, E > +{ +public: + static SafeIntError RegMultiply( const unsigned __int64& a, signed __int32 b, unsigned __int64& ret ) + { + if( b < 0 && a != 0 ) + { + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } + + return LargeIntRegMultiply< unsigned __int64, unsigned __int32, E >::RegMultiply(a, (unsigned __int32)b, ret); + } +}; + +template< typename E > class LargeIntRegMultiply< unsigned __int64, signed __int64, E > +{ +public: + static SafeIntError RegMultiply( const unsigned __int64& a, signed __int64 b, unsigned __int64& ret ) + { + if( b < 0 && a != 0 ) + { + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } + + return LargeIntRegMultiply< unsigned __int64, unsigned __int64, E >::RegMultiply(a, (unsigned __int64)b, ret); + } +}; + +template< typename E > class LargeIntRegMultiply< signed __int32, unsigned __int64, E > +{ +public: + static SafeIntError RegMultiply( signed __int32 a, const unsigned __int64& b, signed __int32& ret ) + { + unsigned __int32 bHigh, bLow; + bool fIsNegative = false; + + // Consider that a*b can be broken up into: + // (aHigh * 2^32 + aLow) * (bHigh * 2^32 + bLow) + // => (aHigh * bHigh * 2^64) + (aLow * bHigh * 2^32) + (aHigh * bLow * 2^32) + (aLow * bLow) + + bHigh = (unsigned __int32)(b >> 32); + bLow = (unsigned __int32)b; + + ret = 0; + + if(bHigh != 0 && a != 0) + { + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } + + if( a < 0 ) + { + a = -a; + fIsNegative = true; + } + + unsigned __int64 tmp = (unsigned __int32)a * (unsigned __int64)bLow; + + + if( !fIsNegative ) + { + if( tmp <= (unsigned __int64)IntTraits< signed __int32 >::maxInt ) + { + ret = (signed __int32)tmp; + return SafeIntNoError; + } + } + else + { + if( tmp <= (unsigned __int64)IntTraits< signed __int32 >::maxInt+1 ) + { + ret = -( (signed __int32)tmp ); + return SafeIntNoError; + } + } + + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +template < typename E > class LargeIntRegMultiply< unsigned __int32, unsigned __int64, E > +{ +public: + static SafeIntError RegMultiply( unsigned __int32 a, const unsigned __int64& b, unsigned __int32& ret ) + { + // Consider that a*b can be broken up into: + // (bHigh * 2^32 + bLow) * a + // => (bHigh * a * 2^32) + (bLow * a) + // In this case, the result must fit into 32-bits + // If bHigh != 0 && a != 0, immediate error. + + if( (unsigned __int32)(b >> 32) != 0 && a != 0 ) + { + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } + + unsigned __int64 tmp = b * (unsigned __int64)a; + + if( (unsigned __int32)(tmp >> 32) != 0 ) // overflow + { + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } + + ret = (unsigned __int32)tmp; + return SafeIntNoError; + } +}; + +template < typename E > class LargeIntRegMultiply< unsigned __int32, signed __int64, E > +{ +public: + static SafeIntError RegMultiply( unsigned __int32 a, const signed __int64& b, unsigned __int32& ret ) + { + if( b < 0 && a != 0 ) + { + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } + + return LargeIntRegMultiply< unsigned __int32, unsigned __int64, E >::RegMultiply( a, (unsigned __int64)b, ret ); + } +}; + +template < typename E > class LargeIntRegMultiply< signed __int64, signed __int64, E > +{ +public: + static SafeIntError RegMultiply( const signed __int64& a, const signed __int64& b, signed __int64& ret ) + { + bool aNegative = false; + bool bNegative = false; + + unsigned __int64 tmp; + __int64 a1 = a; + __int64 b1 = b; + + if( a1 < 0 ) + { + aNegative = true; + a1 = -a1; + } + + if( b1 < 0 ) + { + bNegative = true; + b1 = -b1; + } + + if( LargeIntRegMultiply< unsigned __int64, unsigned __int64, E >:: + RegMultiply( (unsigned __int64)a1, (unsigned __int64)b1, tmp ) == SafeIntNoError ) + { + // The unsigned multiplication didn't overflow + if( aNegative ^ bNegative ) + { + // Result must be negative + if( tmp <= (unsigned __int64)IntTraits< signed __int64 >::minInt ) + { + ret = -(signed __int64)tmp; + return SafeIntNoError; + } + } + else + { + // Result must be positive + if( tmp <= (unsigned __int64)IntTraits< signed __int64 >::maxInt ) + { + ret = (signed __int64)tmp; + return SafeIntNoError; + } + } + } + + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +template < typename E > class LargeIntRegMultiply< signed __int64, unsigned __int32, E > +{ +public: + static SafeIntError RegMultiply( const signed __int64& a, unsigned __int32 b, signed __int64& ret ) + { + bool aNegative = false; + unsigned __int64 tmp; + __int64 a1 = a; + + if( a1 < 0 ) + { + aNegative = true; + a1 = -a1; + } + + if( LargeIntRegMultiply< unsigned __int64, unsigned __int32, E >::RegMultiply( (unsigned __int64)a1, b, tmp ) == SafeIntNoError ) + { + // The unsigned multiplication didn't overflow + if( aNegative ) + { + // Result must be negative + if( tmp <= (unsigned __int64)IntTraits< signed __int64 >::minInt ) + { + ret = -(signed __int64)tmp; + return SafeIntNoError; + } + } + else + { + // Result must be positive + if( tmp <= (unsigned __int64)IntTraits< signed __int64 >::maxInt ) + { + ret = (signed __int64)tmp; + return SafeIntNoError; + } + } + } + + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +template < typename E > class LargeIntRegMultiply< signed __int64, signed __int32, E > +{ +public: + static SafeIntError RegMultiply( const signed __int64& a, signed __int32 b, signed __int64& ret ) + { + bool aNegative = false; + bool bNegative = false; + + unsigned __int64 tmp; + __int64 a1 = a; + __int64 b1 = b; + + if( a1 < 0 ) + { + aNegative = true; + a1 = -a1; + } + + if( b1 < 0 ) + { + bNegative = true; + b1 = -b1; + } + + if( LargeIntRegMultiply< unsigned __int64, unsigned __int32, E >:: + RegMultiply( (unsigned __int64)a1, (unsigned __int32)b1, tmp ) == SafeIntNoError ) + { + // The unsigned multiplication didn't overflow + if( aNegative ^ bNegative ) + { + // Result must be negative + if( tmp <= (unsigned __int64)IntTraits< signed __int64 >::minInt ) + { + ret = -(signed __int64)tmp; + return SafeIntNoError; + } + } + else + { + // Result must be positive + if( tmp <= (unsigned __int64)IntTraits< signed __int64 >::maxInt ) + { + ret = (signed __int64)tmp; + return SafeIntNoError; + } + } + } + + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +template < typename E > class LargeIntRegMultiply< signed __int32, signed __int64, E > +{ +public: + static SafeIntError RegMultiply( signed __int32 a, const signed __int64& b, signed __int32& ret ) + { + bool aNegative = false; + bool bNegative = false; + + unsigned __int32 tmp; + __int64 b1 = b; + + if( a < 0 ) + { + aNegative = true; + a = -a; + } + + if( b1 < 0 ) + { + bNegative = true; + b1 = -b1; + } + + if( LargeIntRegMultiply< unsigned __int32, unsigned __int64, E >:: + RegMultiply( (unsigned __int32)a, (unsigned __int64)b1, tmp ) == SafeIntNoError ) + { + // The unsigned multiplication didn't overflow + if( aNegative ^ bNegative ) + { + // Result must be negative + if( tmp <= (unsigned __int32)IntTraits< signed __int32 >::minInt ) + { +#pragma warning(suppress:4146) + ret = -tmp; + return SafeIntNoError; + } + } + else + { + // Result must be positive + if( tmp <= (unsigned __int32)IntTraits< signed __int32 >::maxInt ) + { + ret = (signed __int32)tmp; + return SafeIntNoError; + } + } + } + + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +template < typename E > class LargeIntRegMultiply< signed __int64, unsigned __int64, E > +{ +public: + static SafeIntError RegMultiply( const signed __int64& a, const unsigned __int64& b, signed __int64& ret ) + { + bool aNegative = false; + + unsigned __int64 tmp; + __int64 a1 = a; + + if( a1 < 0 ) + { + aNegative = true; + a1 = -a1; + } + + if( LargeIntRegMultiply< unsigned __int64, unsigned __int64, E >:: + RegMultiply( (unsigned __int64)a1, (unsigned __int64)b, tmp ) == SafeIntNoError ) + { + // The unsigned multiplication didn't overflow + if( aNegative ) + { + // Result must be negative + if( tmp <= (unsigned __int64)IntTraits< signed __int64 >::minInt ) + { + ret = -((signed __int64)tmp); + return SafeIntNoError; + } + } + else + { + // Result must be positive + if( tmp <= (unsigned __int64)IntTraits< signed __int64 >::maxInt ) + { + ret = (signed __int64)tmp; + return SafeIntNoError; + } + } + } + + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +template < typename E > class MultiplicationHelper< unsigned __int64, unsigned __int64, E, MultiplicationState_Uint64Uint64 > +{ +public: + static SafeIntError Multiply( const unsigned __int64& t, const unsigned __int64& u, unsigned __int64& ret ) + { + return LargeIntRegMultiply< unsigned __int64, unsigned __int64, E >::RegMultiply( t, u, ret ); + } +}; + +template < typename U, typename E > class MultiplicationHelper +{ +public: + //U is any unsigned int 32-bit or less + static SafeIntError Multiply( const unsigned __int64& t, const U& u, unsigned __int64& ret ) + { + return LargeIntRegMultiply< unsigned __int64, unsigned __int32, E >::RegMultiply( t, (unsigned __int32)u, ret ); + } +}; + +// converse of the previous function +template < typename T, typename E > class MultiplicationHelper< T, unsigned __int64, E, MultiplicationState_UintUint64 > +{ +public: + // T is any unsigned int up to 32-bit + static SafeIntError Multiply( const T& t, const unsigned __int64& u, T& ret ) + { + unsigned __int32 tmp; + + if( LargeIntRegMultiply< unsigned __int32, unsigned __int64, E >::RegMultiply( t, u, tmp ) == SafeIntNoError && + SafeCastHelper< T, unsigned __int32, E >::Cast(tmp, ret) == SafeIntNoError ) + { + return SafeIntNoError; + } + + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +template < typename U, typename E > class MultiplicationHelper< unsigned __int64, U, E, MultiplicationState_Uint64Int > +{ +public: + //U is any signed int, up to 64-bit + static SafeIntError Multiply(const unsigned __int64& t, const U& u, unsigned __int64& ret) + { + return LargeIntRegMultiply< unsigned __int64, signed __int32, E >::RegMultiply(t, (signed __int32)u, ret); + } +}; + +template < typename E > class MultiplicationHelper +{ +public: + static SafeIntError Multiply(const unsigned __int64& t, const __int64& u, unsigned __int64& ret) + { + return LargeIntRegMultiply< unsigned __int64, __int64, E >::RegMultiply(t, u, ret); + } +}; + +template < typename T, typename E > class MultiplicationHelper< T, __int64, E, MultiplicationState_UintInt64 > +{ +public: + //T is unsigned up to 32-bit + static SafeIntError Multiply( const T& t, const __int64& u, T& ret ) + { + unsigned __int32 tmp; + + if( LargeIntRegMultiply< unsigned __int32, __int64, E >::RegMultiply( (unsigned __int32)t, u, tmp ) == SafeIntNoError && + SafeCastHelper< T, unsigned __int32, E >::Cast( tmp, ret ) == SafeIntNoError ) + { + return SafeIntNoError; + } + + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +template < typename U, typename E > class MultiplicationHelper<__int64, U, E, MultiplicationState_Int64Uint > +{ +public: + //U is unsigned up to 32-bit + static SafeIntError Multiply( const __int64& t, const U& u, __int64& ret ) + { + return LargeIntRegMultiply< __int64, unsigned __int32, E >::RegMultiply( t, (unsigned __int32)u, ret ); + } +}; + +template < typename E > class MultiplicationHelper<__int64, __int64, E, MultiplicationState_Int64Int64 > +{ +public: + static SafeIntError Multiply( const __int64& t, const __int64& u, __int64& ret ) + { + return LargeIntRegMultiply< __int64, __int64, E >::RegMultiply( t, u, ret ); + } +}; + +template < typename U, typename E > class MultiplicationHelper<__int64, U, E, MultiplicationState_Int64Int> +{ +public: + //U is signed up to 32-bit + static SafeIntError Multiply( const __int64& t, U u, __int64& ret ) + { + return LargeIntRegMultiply< __int64, __int32, E >::RegMultiply( t, (__int32)u, ret ); + } +}; + +template < typename T, typename E > class MultiplicationHelper< T, unsigned __int64, E, MultiplicationState_IntUint64 > +{ +public: + //T is signed up to 32-bit + static SafeIntError Multiply(T t, const unsigned __int64& u, T& ret) + { + __int32 tmp; + + if( LargeIntRegMultiply< __int32, unsigned __int64, E >::RegMultiply( (__int32)t, u, tmp ) == SafeIntNoError && + SafeCastHelper< T, __int32, E >::Cast( tmp, ret ) == SafeIntNoError ) + { + return SafeIntNoError; + } + + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +template < typename E > class MultiplicationHelper<__int64, unsigned __int64, E, MultiplicationState_Int64Uint64> +{ +public: + //U is signed up to 32-bit + static SafeIntError Multiply( const __int64& t, const unsigned __int64& u, __int64& ret ) + { + return LargeIntRegMultiply< __int64, unsigned __int64, E >::RegMultiply( t, u, ret ); + } +}; + +template < typename T, typename E > class MultiplicationHelper< T, __int64, E, MultiplicationState_IntInt64> +{ +public: + //T is signed, up to 32-bit + static SafeIntError Multiply( T t, const __int64& u, T& ret ) + { + __int32 tmp; + + if( LargeIntRegMultiply< __int32, __int64, E >::RegMultiply( (__int32)t, u, tmp ) == SafeIntNoError && + SafeCastHelper< T, __int32, E >::Cast( tmp, ret ) == SafeIntNoError ) + { + return SafeIntNoError; + } + + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +enum DivisionState +{ + DivisionState_OK, + DivisionState_UnsignedSigned, + DivisionState_SignedUnsigned32, + DivisionState_SignedUnsigned64, + DivisionState_SignedUnsigned, + DivisionState_SignedSigned +}; + +template < typename T, typename U > class DivisionMethod +{ +public: + enum + { + method = (SafeIntCompare< T, U >::isBothUnsigned ? DivisionState_OK : + (!IntTraits< T >::isSigned && IntTraits< U >::isSigned) ? DivisionState_UnsignedSigned : + (IntTraits< T >::isSigned && + IntTraits< U >::isUint32 && + IntTraits< T >::isLT64Bit) ? DivisionState_SignedUnsigned32 : + (IntTraits< T >::isSigned && IntTraits< U >::isUint64) ? DivisionState_SignedUnsigned64 : + (IntTraits< T >::isSigned && !IntTraits< U >::isSigned) ? DivisionState_SignedUnsigned : + DivisionState_SignedSigned) + }; +}; + +template < typename T, typename U, typename E, int Method = DivisionMethod< T, U >::method > class DivisionHelper; + +template < typename T, typename U, typename E > class DivisionHelper< T, U, E, DivisionState_OK > +{ +public: + static SafeIntError Divide( const T& t, const U& u, T& result ) + { + if( u == 0 ) + { + E::SafeIntOnDivZero(); + return SafeIntDivideByZero; + } + + result = (T)( t/u ); + return SafeIntNoError; + } +}; + +template < typename T, typename U, typename E > class DivisionHelper< T, U, E, DivisionState_UnsignedSigned> +{ +public: + static SafeIntError Divide( const T& t, const U& u, T& result ) + { + if( u > 0 ) + { + result = (T)( t/u ); + return SafeIntNoError; + } + + if( u == 0 ) + { + E::SafeIntOnDivZero(); + return SafeIntDivideByZero; + } + + // it is always an error to try and divide an unsigned number by a negative signed number + // unless u is bigger than t + if( AbsValueHelper< U >::Abs( u ) > t ) + { + result = 0; + return SafeIntNoError; + } + + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +template < typename T, typename U, typename E > class DivisionHelper< T, U, E, DivisionState_SignedUnsigned32 > +{ +public: + static SafeIntError Divide( const T& t, const U& u, T& result ) + { + if( u == 0 ) + { + E::SafeIntOnDivZero(); + return SafeIntDivideByZero; + } + + // Test for t > 0 + // If t < 0, must explicitly upcast, or implicit upcast to ulong will cause errors + // As it turns out, 32-bit division is about twice as fast, which justifies the extra conditional + if( t > 0 ) + result = (T)( t/u ); + else + result = (T)( (__int64)t/(__int64)u ); + + return SafeIntNoError; + } +}; + +template < typename T, typename E > class DivisionHelper< T, unsigned __int64, E, DivisionState_SignedUnsigned64 > +{ +public: + static SafeIntError Divide( const T& t, const unsigned __int64& u, T& result ) + { + if( u == 0 ) + { + E::SafeIntOnDivZero(); + return SafeIntDivideByZero; + } + + if( u <= (unsigned __int64)IntTraits< T >::maxInt ) + { + // Else u can safely be cast to T +#pragma warning(suppress:4127) + if( sizeof( T ) < sizeof( __int64 ) ) + result = (T)( (int)t/(int)u ); + else + result = (T)((__int64)t/(__int64)u); + } + else // Corner case + if( t == IntTraits< T >::minInt && u == (unsigned __int64)IntTraits< T >::minInt ) + { + // Min int divided by its own magnitude is -1 + result = -1; + } + else + { + result = 0; + } + return SafeIntNoError; + } +}; + +template < typename T, typename U, typename E > class DivisionHelper< T, U, E, DivisionState_SignedUnsigned> +{ +public: + // T is any signed, U is unsigned and smaller than 32-bit + // In this case, standard operator casting is correct + static SafeIntError Divide( const T& t, const U& u, T& result ) + { + if( u == 0 ) + { + E::SafeIntOnDivZero(); + return SafeIntDivideByZero; + } + + result = (T)( t/u ); + return SafeIntNoError; + } +}; + +template < typename T, typename U, typename E > class DivisionHelper< T, U, E, DivisionState_SignedSigned> +{ +public: + static SafeIntError Divide( const T& t, const U& u, T& result ) + { + if( u == 0 ) + { + E::SafeIntOnDivZero(); + return SafeIntDivideByZero; + } + + // Must test for corner case + if( t == IntTraits< T >::minInt && u == -1 ) + { + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } + + result = (T)( t/u ); + return SafeIntNoError; + } +}; + +enum AdditionState +{ + AdditionState_CastIntCheckMax, + AdditionState_CastUintCheckOverflow, + AdditionState_CastUintCheckOverflowMax, + AdditionState_CastUint64CheckOverflow, + AdditionState_CastUint64CheckOverflowMax, + AdditionState_CastIntCheckMinMax, + AdditionState_CastInt64CheckMinMax, + AdditionState_CastInt64CheckMax, + AdditionState_CastUint64CheckMinMax, + AdditionState_CastUint64CheckMinMax2, + AdditionState_CastInt64CheckOverflow, + AdditionState_CastInt64CheckOverflowMinMax, + AdditionState_CastInt64CheckOverflowMax, + AdditionState_ManualCheckInt64Uint64, + AdditionState_ManualCheck, + AdditionState_Error +}; + +template< typename T, typename U > +class AdditionMethod +{ +public: + enum + { + //unsigned-unsigned + method = (IntRegion< T,U >::IntZone_UintLT32_UintLT32 ? AdditionState_CastIntCheckMax : + (IntRegion< T,U >::IntZone_Uint32_UintLT64) ? AdditionState_CastUintCheckOverflow : + (IntRegion< T,U >::IntZone_UintLT32_Uint32) ? AdditionState_CastUintCheckOverflowMax : + (IntRegion< T,U >::IntZone_Uint64_Uint) ? AdditionState_CastUint64CheckOverflow : + (IntRegion< T,U >::IntZone_UintLT64_Uint64) ? AdditionState_CastUint64CheckOverflowMax : + //unsigned-signed + (IntRegion< T,U >::IntZone_UintLT32_IntLT32) ? AdditionState_CastIntCheckMinMax : + (IntRegion< T,U >::IntZone_Uint32_IntLT64 || + IntRegion< T,U >::IntZone_UintLT32_Int32) ? AdditionState_CastInt64CheckMinMax : + (IntRegion< T,U >::IntZone_Uint64_Int || + IntRegion< T,U >::IntZone_Uint64_Int64) ? AdditionState_CastUint64CheckMinMax : + (IntRegion< T,U >::IntZone_UintLT64_Int64) ? AdditionState_CastUint64CheckMinMax2 : + //signed-signed + (IntRegion< T,U >::IntZone_IntLT32_IntLT32) ? AdditionState_CastIntCheckMinMax : + (IntRegion< T,U >::IntZone_Int32_IntLT64 || + IntRegion< T,U >::IntZone_IntLT32_Int32) ? AdditionState_CastInt64CheckMinMax : + (IntRegion< T,U >::IntZone_Int64_Int || + IntRegion< T,U >::IntZone_Int64_Int64) ? AdditionState_CastInt64CheckOverflow : + (IntRegion< T,U >::IntZone_IntLT64_Int64) ? AdditionState_CastInt64CheckOverflowMinMax : + //signed-unsigned + (IntRegion< T,U >::IntZone_IntLT32_UintLT32) ? AdditionState_CastIntCheckMax : + (IntRegion< T,U >::IntZone_Int32_UintLT32 || + IntRegion< T,U >::IntZone_IntLT64_Uint32) ? AdditionState_CastInt64CheckMax : + (IntRegion< T,U >::IntZone_Int64_UintLT64) ? AdditionState_CastInt64CheckOverflowMax : + (IntRegion< T,U >::IntZone_Int64_Uint64) ? AdditionState_ManualCheckInt64Uint64 : + (IntRegion< T,U >::IntZone_Int_Uint64) ? AdditionState_ManualCheck : + AdditionState_Error) + }; +}; + +template < typename T, typename U, typename E, int Method = AdditionMethod< T, U >::method > class AdditionHelper; + +template < typename T, typename U, typename E > class AdditionHelper < T, U, E, AdditionState_CastIntCheckMax > +{ +public: + static SafeIntError Addition( const T& lhs, const U& rhs, T& result ) + { + //16-bit or less unsigned addition + __int32 tmp = lhs + rhs; + + if( tmp <= (__int32)IntTraits< T >::maxInt ) + { + result = (T)tmp; + return SafeIntNoError; + } + + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +template < typename T, typename U, typename E > class AdditionHelper < T, U, E, AdditionState_CastUintCheckOverflow > +{ +public: + static SafeIntError Addition( const T& lhs, const U& rhs, T& result ) + { + // 32-bit or less - both are unsigned + unsigned __int32 tmp = (unsigned __int32)lhs + (unsigned __int32)rhs; + + //we added didn't get smaller + if( tmp >= lhs ) + { + result = (T)tmp; + return SafeIntNoError; + } + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +template < typename T, typename U, typename E > class AdditionHelper < T, U, E, AdditionState_CastUintCheckOverflowMax> +{ +public: + static SafeIntError Addition( const T& lhs, const U& rhs, T& result ) + { + // 32-bit or less - both are unsigned + unsigned __int32 tmp = (unsigned __int32)lhs + (unsigned __int32)rhs; + + // We added and it didn't get smaller or exceed maxInt + if( tmp >= lhs && tmp <= IntTraits< T >::maxInt ) + { + result = (T)tmp; + return SafeIntNoError; + } + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +template < typename T, typename U, typename E > class AdditionHelper < T, U, E, AdditionState_CastUint64CheckOverflow> +{ +public: + static SafeIntError Addition( const T& lhs, const U& rhs, T& result ) + { + // lhs unsigned __int64, rhs unsigned + unsigned __int64 tmp = (unsigned __int64)lhs + (unsigned __int64)rhs; + + // We added and it didn't get smaller + if(tmp >= lhs) + { + result = (T)tmp; + return SafeIntNoError; + } + + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +template < typename T, typename U, typename E > class AdditionHelper < T, U, E, AdditionState_CastUint64CheckOverflowMax > +{ +public: + static SafeIntError Addition( const T& lhs, const U& rhs, T& result ) + { + //lhs unsigned __int64, rhs unsigned + unsigned __int64 tmp = (unsigned __int64)lhs + (unsigned __int64)rhs; + + // We added and it didn't get smaller + if( tmp >= lhs && tmp <= IntTraits< T >::maxInt ) + { + result = (T)tmp; + return SafeIntNoError; + } + + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +template < typename T, typename U, typename E > class AdditionHelper < T, U, E, AdditionState_CastIntCheckMinMax > +{ +public: + static SafeIntError Addition( const T& lhs, const U& rhs, T& result ) + { + // 16-bit or less - one or both are signed + __int32 tmp = lhs + rhs; + + if( tmp <= (__int32)IntTraits< T >::maxInt && tmp >= (__int32)IntTraits< T >::minInt ) + { + result = (T)tmp; + return SafeIntNoError; + } + + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +#pragma warning(push) +#pragma warning(disable:4702) +template < typename T, typename U, typename E > class AdditionHelper < T, U, E, AdditionState_CastInt64CheckMinMax > +{ +public: + static SafeIntError Addition( const T& lhs, const U& rhs, T& result ) + { + // 32-bit or less - one or both are signed + __int64 tmp = (__int64)lhs + (__int64)rhs; + + if( tmp <= (__int64)IntTraits< T >::maxInt && tmp >= (__int64)IntTraits< T >::minInt ) + { + result = (T)tmp; + return SafeIntNoError; + } + + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + // return E::SafeIntOnOverflow2(); + } +}; +#pragma warning(pop) + +template < typename T, typename U, typename E > class AdditionHelper < T, U, E, AdditionState_CastInt64CheckMax > +{ +public: + static SafeIntError Addition( const T& lhs, const U& rhs, T& result ) + { + // 32-bit or less - lhs signed, rhs unsigned + __int64 tmp = (__int64)lhs + (__int64)rhs; + + if( tmp <= IntTraits< T >::maxInt ) + { + result = (T)tmp; + return SafeIntNoError; + } + + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +template < typename T, typename U, typename E > class AdditionHelper < T, U, E, AdditionState_CastUint64CheckMinMax > +{ +public: + static SafeIntError Addition( const T& lhs, const U& rhs, T& result ) + { + // lhs is unsigned __int64, rhs signed + unsigned __int64 tmp; + + if( rhs < 0 ) + { + // So we're effectively subtracting + tmp = AbsValueHelper< U >::Abs( rhs ); + + if( tmp <= lhs ) + { + result = lhs - tmp; + return SafeIntNoError; + } + } + else + { + // now we know that rhs can be safely cast into an unsigned __int64 + tmp = (unsigned __int64)lhs + (unsigned __int64)rhs; + + // We added and it did not become smaller + if( tmp >= lhs ) + { + result = (T)tmp; + return SafeIntNoError; + } + } + + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +template < typename T, typename U, typename E > class AdditionHelper < T, U, E, AdditionState_CastUint64CheckMinMax2> +{ +public: + static SafeIntError Addition( const T& lhs, const U& rhs, T& result ) + { + // lhs is unsigned and < 64-bit, rhs signed __int64 + if( rhs < 0 ) + { + if( lhs >= (unsigned __int64)( -rhs ) )//negation is safe, since rhs is 64-bit + { + result = (T)( lhs + rhs ); + return SafeIntNoError; + } + } + else + { + // now we know that rhs can be safely cast into an unsigned __int64 + unsigned __int64 tmp = (unsigned __int64)lhs + (unsigned __int64)rhs; + + // special case - rhs cannot be larger than 0x7fffffffffffffff, lhs cannot be larger than 0xffffffff + // it is not possible for the operation above to overflow, so just check max + if( tmp <= IntTraits< T >::maxInt ) + { + result = (T)tmp; + return SafeIntNoError; + } + } + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +template < typename T, typename U, typename E > class AdditionHelper < T, U, E, AdditionState_CastInt64CheckOverflow> +{ +public: + static SafeIntError Addition( const T& lhs, const U& rhs, T& result ) + { + // lhs is signed __int64, rhs signed + __int64 tmp = (__int64)lhs + (__int64)rhs; + + if( lhs >= 0 ) + { + // mixed sign cannot overflow + if( rhs >= 0 && tmp < lhs ) + { + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } + } + else + { + // lhs negative + if( rhs < 0 && tmp > lhs ) + { + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } + } + + result = (T)tmp; + return SafeIntNoError; + } +}; + +template < typename T, typename U, typename E > class AdditionHelper < T, U, E, AdditionState_CastInt64CheckOverflowMinMax> +{ +public: + static SafeIntError Addition( const T& lhs, const U& rhs, T& result ) + { + //rhs is signed __int64, lhs signed + __int64 tmp; + + if( AdditionHelper< __int64, __int64, E, AdditionState_CastInt64CheckOverflow >:: + Addition( (__int64)lhs, (__int64)rhs, tmp ) == SafeIntNoError && + tmp <= IntTraits< T >::maxInt && + tmp >= IntTraits< T >::minInt ) + { + result = (T)tmp; + return SafeIntNoError; + } + + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +template < typename T, typename U, typename E > class AdditionHelper < T, U, E, AdditionState_CastInt64CheckOverflowMax > +{ +public: + static SafeIntError Addition( const T& lhs, const U& rhs, T& result ) + { + //lhs is signed __int64, rhs unsigned < 64-bit + __int64 tmp = lhs + (__int64)rhs; + + if( tmp >= lhs ) + { + result = (T)tmp; + return SafeIntNoError; + } + + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +template < typename E > class AdditionHelper < __int64, unsigned __int64, E, AdditionState_ManualCheckInt64Uint64 > +{ +public: + static SafeIntError Addition( const __int64& lhs, const unsigned __int64& rhs, __int64& result ) + { + // rhs is unsigned __int64, lhs __int64 + __int64 tmp = lhs + (__int64)rhs; + + if( tmp >= lhs ) + { + result = tmp; + return SafeIntNoError; + } + + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +template < typename T, typename U, typename E > class AdditionHelper < T, U, E, AdditionState_ManualCheck > +{ +public: + static SafeIntError Addition( const T& lhs, const U& rhs, T& result ) + { + // rhs is unsigned __int64, lhs signed, 32-bit or less + + if( (unsigned __int32)( rhs >> 32 ) == 0 ) + { + // Now it just happens to work out that the standard behavior does what we want + // Adding explicit casts to show exactly what's happening here + __int32 tmp = (__int32)( (unsigned __int32)rhs + (unsigned __int32)lhs ); + + if( tmp >= lhs && + SafeCastHelper< T, __int32, E >::Cast( tmp, result ) == SafeIntNoError ) + return SafeIntNoError; + } + + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +enum SubtractionState +{ + SubtractionState_BothUnsigned, + SubtractionState_CastIntCheckMinMax, + SubtractionState_CastIntCheckMin, + SubtractionState_CastInt64CheckMinMax, + SubtractionState_CastInt64CheckMin, + SubtractionState_Uint64Int, + SubtractionState_UintInt64, + SubtractionState_Int64Int, + SubtractionState_IntInt64, + SubtractionState_Int64Uint, + SubtractionState_IntUint64, + SubtractionState_Int64Uint64, + // states for SubtractionMethod2 + SubtractionState_BothUnsigned2, + SubtractionState_CastIntCheckMinMax2, + SubtractionState_CastInt64CheckMinMax2, + SubtractionState_Uint64Int2, + SubtractionState_UintInt642, + SubtractionState_Int64Int2, + SubtractionState_IntInt642, + SubtractionState_Int64Uint2, + SubtractionState_IntUint642, + SubtractionState_Int64Uint642, + SubtractionState_Error +}; + +template < typename T, typename U > class SubtractionMethod +{ +public: + enum + { + // unsigned-unsigned + method = ((IntRegion< T,U >::IntZone_UintLT32_UintLT32 || + (IntRegion< T,U >::IntZone_Uint32_UintLT64) || + (IntRegion< T,U >::IntZone_UintLT32_Uint32) || + (IntRegion< T,U >::IntZone_Uint64_Uint) || + (IntRegion< T,U >::IntZone_UintLT64_Uint64)) ? SubtractionState_BothUnsigned : + // unsigned-signed + (IntRegion< T,U >::IntZone_UintLT32_IntLT32) ? SubtractionState_CastIntCheckMinMax : + (IntRegion< T,U >::IntZone_Uint32_IntLT64 || + IntRegion< T,U >::IntZone_UintLT32_Int32) ? SubtractionState_CastInt64CheckMinMax : + (IntRegion< T,U >::IntZone_Uint64_Int || + IntRegion< T,U >::IntZone_Uint64_Int64) ? SubtractionState_Uint64Int : + (IntRegion< T,U >::IntZone_UintLT64_Int64) ? SubtractionState_UintInt64 : + // signed-signed + (IntRegion< T,U >::IntZone_IntLT32_IntLT32) ? SubtractionState_CastIntCheckMinMax : + (IntRegion< T,U >::IntZone_Int32_IntLT64 || + IntRegion< T,U >::IntZone_IntLT32_Int32) ? SubtractionState_CastInt64CheckMinMax : + (IntRegion< T,U >::IntZone_Int64_Int || + IntRegion< T,U >::IntZone_Int64_Int64) ? SubtractionState_Int64Int : + (IntRegion< T,U >::IntZone_IntLT64_Int64) ? SubtractionState_IntInt64 : + // signed-unsigned + (IntRegion< T,U >::IntZone_IntLT32_UintLT32) ? SubtractionState_CastIntCheckMin : + (IntRegion< T,U >::IntZone_Int32_UintLT32 || + IntRegion< T,U >::IntZone_IntLT64_Uint32) ? SubtractionState_CastInt64CheckMin : + (IntRegion< T,U >::IntZone_Int64_UintLT64) ? SubtractionState_Int64Uint : + (IntRegion< T,U >::IntZone_Int_Uint64) ? SubtractionState_IntUint64 : + (IntRegion< T,U >::IntZone_Int64_Uint64) ? SubtractionState_Int64Uint64 : + SubtractionState_Error) + }; +}; + +// this is for the case of U - SafeInt< T, E > +template < typename T, typename U > class SubtractionMethod2 +{ +public: + enum + { + // unsigned-unsigned + method = ((IntRegion< T,U >::IntZone_UintLT32_UintLT32 || + (IntRegion< T,U >::IntZone_Uint32_UintLT64) || + (IntRegion< T,U >::IntZone_UintLT32_Uint32) || + (IntRegion< T,U >::IntZone_Uint64_Uint) || + (IntRegion< T,U >::IntZone_UintLT64_Uint64)) ? SubtractionState_BothUnsigned2 : + // unsigned-signed + (IntRegion< T,U >::IntZone_UintLT32_IntLT32) ? SubtractionState_CastIntCheckMinMax2 : + (IntRegion< T,U >::IntZone_Uint32_IntLT64 || + IntRegion< T,U >::IntZone_UintLT32_Int32) ? SubtractionState_CastInt64CheckMinMax2 : + (IntRegion< T,U >::IntZone_Uint64_Int || + IntRegion< T,U >::IntZone_Uint64_Int64) ? SubtractionState_Uint64Int2 : + (IntRegion< T,U >::IntZone_UintLT64_Int64) ? SubtractionState_UintInt642 : + // signed-signed + (IntRegion< T,U >::IntZone_IntLT32_IntLT32) ? SubtractionState_CastIntCheckMinMax2 : + (IntRegion< T,U >::IntZone_Int32_IntLT64 || + IntRegion< T,U >::IntZone_IntLT32_Int32) ? SubtractionState_CastInt64CheckMinMax2 : + (IntRegion< T,U >::IntZone_Int64_Int || + IntRegion< T,U >::IntZone_Int64_Int64) ? SubtractionState_Int64Int2 : + (IntRegion< T,U >::IntZone_IntLT64_Int64) ? SubtractionState_IntInt642 : + // signed-unsigned + (IntRegion< T,U >::IntZone_IntLT32_UintLT32) ? SubtractionState_CastIntCheckMinMax2 : + (IntRegion< T,U >::IntZone_Int32_UintLT32 || + IntRegion< T,U >::IntZone_IntLT64_Uint32) ? SubtractionState_CastInt64CheckMinMax2 : + (IntRegion< T,U >::IntZone_Int64_UintLT64) ? SubtractionState_Int64Uint2 : + (IntRegion< T,U >::IntZone_Int_Uint64) ? SubtractionState_IntUint642 : + (IntRegion< T,U >::IntZone_Int64_Uint64) ? SubtractionState_Int64Uint642 : + SubtractionState_Error) + }; +}; + +template < typename T, typename U, typename E, int Method = SubtractionMethod< T, U >::method > class SubtractionHelper; + +template < typename T, typename U, typename E > class SubtractionHelper< T, U, E, SubtractionState_BothUnsigned > +{ +public: + static SafeIntError Subtract( const T& lhs, const U& rhs, T& result ) + { + // both are unsigned - easy case + if( rhs <= lhs ) + { + result = (T)( lhs - rhs ); + return SafeIntNoError; + } + + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +template < typename T, typename U, typename E > class SubtractionHelper< T, U, E, SubtractionState_BothUnsigned2 > +{ +public: + static SafeIntError Subtract( const T& lhs, const U& rhs, U& result ) + { + // both are unsigned - easy case + // Except we do have to check for overflow - lhs could be larger than result can hold + if( rhs <= lhs ) + { + T tmp = (T)(lhs - rhs); + return SafeCastHelper< U, T, E>::Cast( tmp, result); + } + + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +template < typename T, typename U, typename E > class SubtractionHelper< T, U, E, SubtractionState_CastIntCheckMinMax > +{ +public: + static SafeIntError Subtract( const T& lhs, const U& rhs, T& result ) + { + // both values are 16-bit or less + // rhs is signed, so could end up increasing or decreasing + __int32 tmp = lhs - rhs; + + if( SafeCastHelper< T, __int32, E >::Cast( tmp, result ) == SafeIntNoError ) + { + result = (T)tmp; + return SafeIntNoError; + } + + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +template < typename U, typename T, typename E > class SubtractionHelper< U, T, E, SubtractionState_CastIntCheckMinMax2 > +{ +public: + static SafeIntError Subtract( const U& lhs, const T& rhs, T& result ) + { + // both values are 16-bit or less + // rhs is signed, so could end up increasing or decreasing + __int32 tmp = lhs - rhs; + + return SafeCastHelper< T, __int32, E >::Cast( tmp, result ); + } +}; + +template < typename T, typename U, typename E > class SubtractionHelper< T, U, E, SubtractionState_CastIntCheckMin > +{ +public: + static SafeIntError Subtract( const T& lhs, const U& rhs, T& result ) + { + // both values are 16-bit or less + // rhs is unsigned - check only minimum + __int32 tmp = lhs - rhs; + + if( tmp >= (__int32)IntTraits< T >::minInt ) + { + result = (T)tmp; + return SafeIntNoError; + } + + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +template < typename T, typename U, typename E > class SubtractionHelper< T, U, E, SubtractionState_CastInt64CheckMinMax > +{ +public: + static SafeIntError Subtract( const T& lhs, const U& rhs, T& result ) + { + // both values are 32-bit or less + // rhs is signed, so could end up increasing or decreasing + __int64 tmp = (__int64)lhs - (__int64)rhs; + + return SafeCastHelper< T, __int64, E >::Cast( tmp, result ); + } +}; + +template < typename U, typename T, typename E > class SubtractionHelper< U, T, E, SubtractionState_CastInt64CheckMinMax2 > +{ +public: + static SafeIntError Subtract( const U& lhs, const T& rhs, T& result ) + { + // both values are 32-bit or less + // rhs is signed, so could end up increasing or decreasing + __int64 tmp = (__int64)lhs - (__int64)rhs; + + return SafeCastHelper< T, __int64, E >::Cast( tmp, result ); + } +}; + +template < typename T, typename U, typename E > class SubtractionHelper< T, U, E, SubtractionState_CastInt64CheckMin > +{ +public: + static SafeIntError Subtract( const T& lhs, const U& rhs, T& result ) + { + // both values are 32-bit or less + // rhs is unsigned - check only minimum + __int64 tmp = (__int64)lhs - (__int64)rhs; + + if( tmp >= (__int64)IntTraits< T >::minInt ) + { + result = (T)tmp; + return SafeIntNoError; + } + + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +template < typename T, typename U, typename E > class SubtractionHelper< T, U, E, SubtractionState_Uint64Int > +{ +public: + static SafeIntError Subtract( const T& lhs, const U& rhs, T& result ) + { + // lhs is an unsigned __int64, rhs signed + // must first see if rhs is positive or negative + if( rhs >= 0 ) + { + if( (unsigned __int64)rhs <= lhs ) + { + result = (T)( lhs - (unsigned __int64)rhs ); + return SafeIntNoError; + } + } + else + { + // we're now effectively adding + T tmp = lhs + AbsValueHelper< U >::Abs( rhs ); + + if(tmp >= lhs) + { + result = tmp; + return SafeIntNoError; + } + } + + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +template < typename U, typename T, typename E > class SubtractionHelper< U, T, E, SubtractionState_Uint64Int2 > +{ +public: + static SafeIntError Subtract( const U& lhs, const T& rhs, T& result ) + { + // U is unsigned __int64, T is signed + if( rhs < 0 ) + { + // treat this as addition + unsigned __int64 tmp; + + tmp = lhs + (unsigned __int64)AbsValueHelper< T >::Abs( rhs ); + + // must check for addition overflow and max + if( tmp >= lhs && tmp <= IntTraits< T >::maxInt ) + { + result = (T)tmp; + return SafeIntNoError; + } + } + else if( (unsigned __int64)rhs > lhs ) // now both are positive, so comparison always works + { + // result is negative + // implies that lhs must fit into T, and result cannot overflow + // Also allows us to drop to 32-bit math, which is faster on a 32-bit system + result = (T)lhs - (T)rhs; + return SafeIntNoError; + } + else + { + // result is positive + unsigned __int64 tmp = (unsigned __int64)lhs - (unsigned __int64)rhs; + + if( tmp <= IntTraits< T >::maxInt ) + { + result = (T)tmp; + return SafeIntNoError; + } + } + + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +template < typename T, typename U, typename E > class SubtractionHelper< T, U, E, SubtractionState_UintInt64 > +{ +public: + static SafeIntError Subtract( const T& lhs, const U& rhs, T& result ) + { + // lhs is an unsigned int32 or smaller, rhs signed __int64 + // must first see if rhs is positive or negative + if( rhs >= 0 ) + { + if( (unsigned __int64)rhs <= lhs ) + { + result = (T)( lhs - (T)rhs ); + return SafeIntNoError; + } + } + else + { + // we're now effectively adding + // since lhs is 32-bit, and rhs cannot exceed 2^63 + // this addition cannot overflow + unsigned __int64 tmp = lhs + (unsigned __int64)( -rhs ); // negation safe + + // but we could exceed MaxInt + if(tmp <= IntTraits< T >::maxInt) + { + result = (T)tmp; + return SafeIntNoError; + } + } + + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +template < typename U, typename T, typename E > class SubtractionHelper< U, T, E, SubtractionState_UintInt642 > +{ +public: + static SafeIntError Subtract( const U& lhs, const T& rhs, T& result ) + { + // U unsigned 32-bit or less, T __int64 + if( rhs >= 0 ) + { + // overflow not possible + result = (T)( (__int64)lhs - rhs ); + return SafeIntNoError; + } + else + { + // we effectively have an addition + // which cannot overflow internally + unsigned __int64 tmp = (unsigned __int64)lhs + (unsigned __int64)( -rhs ); + + if( tmp <= (unsigned __int64)IntTraits< T >::maxInt ) + { + result = (T)tmp; + return SafeIntNoError; + } + } + + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +template < typename T, typename U, typename E > class SubtractionHelper< T, U, E, SubtractionState_Int64Int > +{ +public: + static SafeIntError Subtract( const T& lhs, const U& rhs, T& result ) + { + // lhs is an __int64, rhs signed (up to 64-bit) + // we have essentially 4 cases: + // + // 1) lhs positive, rhs positive - overflow not possible + // 2) lhs positive, rhs negative - equivalent to addition - result >= lhs or error + // 3) lhs negative, rhs positive - check result <= lhs + // 4) lhs negative, rhs negative - overflow not possible + + __int64 tmp = lhs - rhs; + + // Note - ideally, we can order these so that true conditionals + // lead to success, which enables better pipelining + // It isn't practical here + if( ( lhs >= 0 && rhs < 0 && tmp < lhs ) || // condition 2 + ( rhs >= 0 && tmp > lhs ) ) // condition 3 + { + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } + + result = (T)tmp; + return SafeIntNoError; + } +}; + +template < typename U, typename T, typename E > class SubtractionHelper< U, T, E, SubtractionState_Int64Int2 > +{ +public: + static SafeIntError Subtract( const U& lhs, const T& rhs, T& result ) + { + // lhs __int64, rhs any signed int (including __int64) + __int64 tmp = lhs - rhs; + + // we have essentially 4 cases: + // + // 1) lhs positive, rhs positive - overflow not possible in tmp + // 2) lhs positive, rhs negative - equivalent to addition - result >= lhs or error + // 3) lhs negative, rhs positive - check result <= lhs + // 4) lhs negative, rhs negative - overflow not possible in tmp + + if( lhs >= 0 ) + { + // if both positive, overflow to negative not possible + // which is why we'll explicitly check maxInt, and not call SafeCast +#pragma warning(suppress:4127) + if( ( IntTraits< T >::isLT64Bit && tmp > IntTraits< T >::maxInt ) || + ( rhs < 0 && tmp < lhs ) ) + { + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } + } + else + { + // lhs negative +#pragma warning(suppress:4127) + if( ( IntTraits< T >::isLT64Bit && tmp < IntTraits< T >::minInt) || + ( rhs >=0 && tmp > lhs ) ) + { + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } + } + + result = (T)tmp; + return SafeIntNoError; + } +}; + +template < typename T, typename U, typename E > class SubtractionHelper< T, U, E, SubtractionState_IntInt64 > +{ +public: + static SafeIntError Subtract( const T& lhs, const U& rhs, T& result ) + { + // lhs is a 32-bit int or less, rhs __int64 + // we have essentially 4 cases: + // + // lhs positive, rhs positive - rhs could be larger than lhs can represent + // lhs positive, rhs negative - additive case - check tmp >= lhs and tmp > max int + // lhs negative, rhs positive - check tmp <= lhs and tmp < min int + // lhs negative, rhs negative - addition cannot internally overflow, check against max + + __int64 tmp = (__int64)lhs - rhs; + + if( lhs >= 0 ) + { + // first case + if( rhs >= 0 ) + { + if( tmp >= IntTraits< T >::minInt ) + { + result = (T)tmp; + return SafeIntNoError; + } + } + else + { + // second case + if( tmp >= lhs && tmp <= IntTraits< T >::maxInt ) + { + result = (T)tmp; + return SafeIntNoError; + } + } + } + else + { + // lhs < 0 + // third case + if( rhs >= 0 ) + { + if( tmp <= lhs && tmp >= IntTraits< T >::minInt ) + { + result = (T)tmp; + return SafeIntNoError; + } + } + else + { + // fourth case + if( tmp <= IntTraits< T >::maxInt ) + { + result = (T)tmp; + return SafeIntNoError; + } + } + } + + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +template < typename U, typename T, typename E > class SubtractionHelper< U, T, E, SubtractionState_IntInt642 > +{ +public: + static SafeIntError Subtract( const U& lhs, const T& rhs, T& result ) + { + // lhs is any signed int32 or smaller, rhs is int64 + __int64 tmp = (__int64)lhs - rhs; + + if( ( lhs >= 0 && rhs < 0 && tmp < lhs ) || + ( rhs > 0 && tmp > lhs ) ) + { + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + //else OK + } + + result = (T)tmp; + return SafeIntNoError; + } +}; + +template < typename T, typename U, typename E > class SubtractionHelper< T, U, E, SubtractionState_Int64Uint > +{ +public: + static SafeIntError Subtract( const T& lhs, const U& rhs, T& result ) + { + // lhs is a 64-bit int, rhs unsigned int32 or smaller + + __int64 tmp = lhs - (__int64)rhs; + + if( tmp <= lhs ) + { + result = (T)tmp; + return SafeIntNoError; + } + + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +template < typename U, typename T, typename E > class SubtractionHelper< U, T, E, SubtractionState_Int64Uint2 > +{ +public: + // lhs is __int64, rhs is unsigned 32-bit or smaller + static SafeIntError Subtract( const U& lhs, const T& rhs, T& result ) + { + __int64 tmp = lhs - (__int64)rhs; + + if( tmp <= IntTraits< T >::maxInt && tmp >= IntTraits< T >::minInt ) + { + result = (T)tmp; + return SafeIntNoError; + } + + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +template < typename T, typename U, typename E > class SubtractionHelper< T, U, E, SubtractionState_IntUint64 > +{ +public: + static SafeIntError Subtract( const T& lhs, const U& rhs, T& result ) + { + // lhs is any signed int, rhs unsigned int64 + // check against available range + + // We need the absolute value of IntTraits< T >::minInt + // This will give it to us without extraneous compiler warnings + const unsigned __int64 AbsMinIntT = (unsigned __int64)IntTraits< T >::maxInt + 1; + + if( lhs < 0 ) + { + if( rhs <= AbsMinIntT - AbsValueHelper< T >::Abs( lhs ) ) + { + result = (T)( lhs - rhs ); + return SafeIntNoError; + } + } + else + { + if( rhs <= AbsMinIntT + (unsigned __int64)lhs ) + { + result = (T)( lhs - rhs ); + return SafeIntNoError; + } + } + + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +template < typename U, typename T, typename E > class SubtractionHelper< U, T, E, SubtractionState_IntUint642 > +{ +public: + static SafeIntError Subtract( const U& lhs, const T& rhs, T& result ) + { + // We run into upcasting problems on comparison - needs 2 checks + if( lhs >= 0 && (T)lhs >= rhs ) + { + result = (T)((U)lhs - (U)rhs); + return SafeIntNoError; + } + + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +template < typename E > class SubtractionHelper< __int64, unsigned __int64, E, SubtractionState_Int64Uint64 > +{ +public: + static SafeIntError Subtract( const __int64& lhs, const unsigned __int64& rhs, __int64& result ) + { + // if we subtract, and it gets larger, there's a problem + __int64 tmp = lhs - (__int64)rhs; + + if( tmp <= lhs ) + { + result = tmp; + return SafeIntNoError; + } + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +template < typename E > class SubtractionHelper< __int64, unsigned __int64, E, SubtractionState_Int64Uint642 > +{ +public: + // If lhs is negative, immediate problem - return must be positive, and subtracting only makes it + // get smaller. If rhs > lhs, then it would also go negative, which is the other case + static SafeIntError Subtract( const __int64& lhs, const unsigned __int64& rhs, unsigned __int64& result ) + { + if( lhs >= 0 && (unsigned __int64)lhs >= rhs ) + { + result = (unsigned __int64)lhs - rhs; + return SafeIntNoError; + } + + E::SafeIntOnOverflow(); + return SafeIntArithmeticOverflow; + } +}; + +enum BinaryState +{ + BinaryState_OK, + BinaryState_Int8, + BinaryState_Int16, + BinaryState_Int32 +}; + +template < typename T, typename U > class BinaryMethod +{ +public: + enum + { + // If both operands are unsigned OR + // return type is smaller than rhs OR + // return type is larger and rhs is unsigned + // Then binary operations won't produce unexpected results + method = ( sizeof( T ) <= sizeof( U ) || + SafeIntCompare< T, U >::isBothUnsigned || + !IntTraits< U >::isSigned ) ? BinaryState_OK : + IntTraits< U >::isInt8 ? BinaryState_Int8 : + IntTraits< U >::isInt16 ? BinaryState_Int16 + : BinaryState_Int32 + }; +}; + +template < typename T, typename U, int Method = BinaryMethod< T, U >::method > class BinaryAndHelper; + +template < typename T, typename U > class BinaryAndHelper< T, U, BinaryState_OK > +{ +public: + static T And( T lhs, U rhs ){ return (T)( lhs & rhs ); } +}; + +template < typename T, typename U > class BinaryAndHelper< T, U, BinaryState_Int8 > +{ +public: + static T And( T lhs, U rhs ) + { + // cast forces sign extension to be zeros + _SAFEINT_BINARY_ASSERT( ( lhs & rhs ) == ( lhs & (unsigned __int8)rhs ) ); + return (T)( lhs & (unsigned __int8)rhs ); + } +}; + +template < typename T, typename U > class BinaryAndHelper< T, U, BinaryState_Int16 > +{ +public: + static T And( T lhs, U rhs ) + { + //cast forces sign extension to be zeros + _SAFEINT_BINARY_ASSERT( ( lhs & rhs ) == ( lhs & (unsigned __int16)rhs ) ); + return (T)( lhs & (unsigned __int16)rhs ); + } +}; + +template < typename T, typename U > class BinaryAndHelper< T, U, BinaryState_Int32 > +{ +public: + static T And( T lhs, U rhs ) + { + //cast forces sign extension to be zeros + _SAFEINT_BINARY_ASSERT( ( lhs & rhs ) == ( lhs & (unsigned __int32)rhs ) ); + return (T)( lhs & (unsigned __int32)rhs ); + } +}; + +template < typename T, typename U, int Method = BinaryMethod< T, U >::method > class BinaryOrHelper; + +template < typename T, typename U > class BinaryOrHelper< T, U, BinaryState_OK > +{ +public: + static T Or( T lhs, U rhs ){ return (T)( lhs | rhs ); } +}; + +template < typename T, typename U > class BinaryOrHelper< T, U, BinaryState_Int8 > +{ +public: + static T Or( T lhs, U rhs ) + { + //cast forces sign extension to be zeros + _SAFEINT_BINARY_ASSERT( ( lhs | rhs ) == ( lhs | (unsigned __int8)rhs ) ); + return (T)( lhs | (unsigned __int8)rhs ); + } +}; + +template < typename T, typename U > class BinaryOrHelper< T, U, BinaryState_Int16 > +{ +public: + static T Or( T lhs, U rhs ) + { + //cast forces sign extension to be zeros + _SAFEINT_BINARY_ASSERT( ( lhs | rhs ) == ( lhs | (unsigned __int16)rhs ) ); + return (T)( lhs | (unsigned __int16)rhs ); + } +}; + +template < typename T, typename U > class BinaryOrHelper< T, U, BinaryState_Int32 > +{ +public: + static T Or( T lhs, U rhs ) + { + //cast forces sign extension to be zeros + _SAFEINT_BINARY_ASSERT( ( lhs | rhs ) == ( lhs | (unsigned __int32)rhs ) ); + return (T)( lhs | (unsigned __int32)rhs ); + } +}; + +template ::method > class BinaryXorHelper; + +template < typename T, typename U > class BinaryXorHelper< T, U, BinaryState_OK > +{ +public: + static T Xor( T lhs, U rhs ){ return (T)( lhs ^ rhs ); } +}; + +template < typename T, typename U > class BinaryXorHelper< T, U, BinaryState_Int8 > +{ +public: + static T Xor( T lhs, U rhs ) + { + // cast forces sign extension to be zeros + _SAFEINT_BINARY_ASSERT( ( lhs ^ rhs ) == ( lhs ^ (unsigned __int8)rhs ) ); + return (T)( lhs ^ (unsigned __int8)rhs ); + } +}; + +template < typename T, typename U > class BinaryXorHelper< T, U, BinaryState_Int16 > +{ +public: + static T Xor( T lhs, U rhs ) + { + // cast forces sign extension to be zeros + _SAFEINT_BINARY_ASSERT( ( lhs ^ rhs ) == ( lhs ^ (unsigned __int16)rhs ) ); + return (T)( lhs ^ (unsigned __int16)rhs ); + } +}; + +template < typename T, typename U > class BinaryXorHelper< T, U, BinaryState_Int32 > +{ +public: + static T Xor( T lhs, U rhs ) + { + // cast forces sign extension to be zeros + _SAFEINT_BINARY_ASSERT( ( lhs ^ rhs ) == ( lhs ^ (unsigned __int32)rhs ) ); + return (T)( lhs ^ (unsigned __int32)rhs ); + } +}; + +#pragma warning(pop) +} // namespace details + +} // namespace utilities + +} // namespace msl + +#pragma pack(pop) diff --git a/sdk/include/ucrt/search.h b/sdk/include/ucrt/search.h new file mode 100644 index 0000000000000..c05389865bcd6 --- /dev/null +++ b/sdk/include/ucrt/search.h @@ -0,0 +1,13 @@ +// +// search.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// Declarations of functions for sorting and searching. +// +#pragma once +#ifndef _INC_SEARCH // include guard for 3rd party interop +#define _INC_SEARCH + +#include +#endif // _INC_SEARCH diff --git a/sdk/include/ucrt/share.h b/sdk/include/ucrt/share.h new file mode 100644 index 0000000000000..0d1524741f9d1 --- /dev/null +++ b/sdk/include/ucrt/share.h @@ -0,0 +1,13 @@ +// +// share.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// Defines the file sharing modes for the sopen() family of functions. +// +#pragma once +#ifndef _INC_SHARE // include guard for 3rd party interop +#define _INC_SHARE + +#include +#endif // _INC_SHARE diff --git a/sdk/include/ucrt/signal.h b/sdk/include/ucrt/signal.h new file mode 100644 index 0000000000000..aadc00e85db3e --- /dev/null +++ b/sdk/include/ucrt/signal.h @@ -0,0 +1,72 @@ +// +// stdio.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The C Standard Library header. +// +#pragma once +#ifndef _INC_SIGNAL // include guard for 3rd party interop +#define _INC_SIGNAL + +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + + + +typedef int sig_atomic_t; + +typedef void (__CRTDECL* _crt_signal_t)(int); + +#define NSIG 23 // maximum signal number + 1 + +// Signal types +#define SIGINT 2 // interrupt +#define SIGILL 4 // illegal instruction - invalid function image +#define SIGFPE 8 // floating point exception +#define SIGSEGV 11 // segment violation +#define SIGTERM 15 // Software termination signal from kill +#define SIGBREAK 21 // Ctrl-Break sequence +#define SIGABRT 22 // abnormal termination triggered by abort call + +#define SIGABRT_COMPAT 6 // SIGABRT compatible with other platforms, same as SIGABRT + +// Signal action codes +#define SIG_DFL ((_crt_signal_t)0) // default signal action +#define SIG_IGN ((_crt_signal_t)1) // ignore signal +#define SIG_GET ((_crt_signal_t)2) // return current value +#define SIG_SGE ((_crt_signal_t)3) // signal gets error +#define SIG_ACK ((_crt_signal_t)4) // acknowledge + +#ifdef _CORECRT_BUILD + // Internal use only! Not valid as an argument to signal(). + #define SIG_DIE ((_crt_signal_t)5) // terminate process +#endif + +// Signal error value (returned by signal call on error) +#define SIG_ERR ((_crt_signal_t)-1) // signal error value + + + +// Pointer to exception information pointers structure +_ACRTIMP void** __cdecl __pxcptinfoptrs(void); +#define _pxcptinfoptrs (*__pxcptinfoptrs()) + +// Function prototypes +#ifndef _M_CEE_PURE + _ACRTIMP _crt_signal_t __cdecl signal(_In_ int _Signal, _In_opt_ _crt_signal_t _Function); +#endif + +_ACRTIMP int __cdecl raise(_In_ int _Signal); + + + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS +#endif // _INC_SIGNAL diff --git a/sdk/include/ucrt/stdalign.h b/sdk/include/ucrt/stdalign.h new file mode 100644 index 0000000000000..a00a724f74144 --- /dev/null +++ b/sdk/include/ucrt/stdalign.h @@ -0,0 +1,31 @@ +// +// stdalign.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The C Standard Library header. +// +#pragma once +#ifndef _INC_STDALIGN // include guard for 3rd party interop +#define _INC_STDALIGN + +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS +_CRT_BEGIN_C_HEADER + +#if _CRT_HAS_C11 + +#define alignas _Alignas +#define alignof _Alignof +#define __alignas_is_defined 1 +#define __alignof_is_defined 1 + +#endif // _CRT_HAS_C11 + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS +#endif // _INC_STDALIGN diff --git a/sdk/include/ucrt/stddef.h b/sdk/include/ucrt/stddef.h new file mode 100644 index 0000000000000..9d44415d36166 --- /dev/null +++ b/sdk/include/ucrt/stddef.h @@ -0,0 +1,64 @@ +// +// stddef.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The C Standard Library header. +// +#pragma once +#ifndef _INC_STDDEF // include guard for 3rd party interop +#define _INC_STDDEF + +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + + + +#ifdef __cplusplus + namespace std + { + typedef decltype(__nullptr) nullptr_t; + } + + using ::std::nullptr_t; +#endif + + + +#if _CRT_FUNCTIONS_REQUIRED + + _ACRTIMP int* __cdecl _errno(void); + #define errno (*_errno()) + + _ACRTIMP errno_t __cdecl _set_errno(_In_ int _Value); + _ACRTIMP errno_t __cdecl _get_errno(_Out_ int* _Value); + +#endif // _CRT_FUNCTIONS_REQUIRED + + + +#if defined _MSC_VER && !defined __clang__ && !defined _CRT_USE_BUILTIN_OFFSETOF + #ifdef __cplusplus + #define offsetof(s,m) ((::size_t)&reinterpret_cast((((s*)0)->m))) + #else + #define offsetof(s,m) ((size_t)&(((s*)0)->m)) + #endif +#else + #define offsetof(s,m) __builtin_offsetof(s,m) +#endif + +_ACRTIMP extern unsigned long __cdecl __threadid(void); +#define _threadid (__threadid()) +_ACRTIMP extern uintptr_t __cdecl __threadhandle(void); + + + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS +#endif // _INC_STDDEF diff --git a/sdk/include/ucrt/stdio.h b/sdk/include/ucrt/stdio.h new file mode 100644 index 0000000000000..0fffddf1526fc --- /dev/null +++ b/sdk/include/ucrt/stdio.h @@ -0,0 +1,2448 @@ +// +// stdio.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The C Standard Library header. +// +#pragma once +#ifndef _INC_STDIO // include guard for 3rd party interop +#define _INC_STDIO + +#include +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + +/* Buffered I/O macros */ + +#define BUFSIZ 512 + + + +/* + * Default number of supported streams. _NFILE is confusing and obsolete, but + * supported anyway for backwards compatibility. + */ +#define _NFILE _NSTREAM_ + +#define _NSTREAM_ 512 + +/* + * Number of entries in _iob[] (declared below). Note that _NSTREAM_ must be + * greater than or equal to _IOB_ENTRIES. + */ +#define _IOB_ENTRIES 3 + +#define EOF (-1) + +#define _IOFBF 0x0000 +#define _IOLBF 0x0040 +#define _IONBF 0x0004 + + + +#define L_tmpnam 260 // _MAX_PATH +#if __STDC_WANT_SECURE_LIB__ + #define L_tmpnam_s L_tmpnam +#endif + + + +/* Seek method constants */ + +#define SEEK_CUR 1 +#define SEEK_END 2 +#define SEEK_SET 0 + + +#define FILENAME_MAX 260 +#define FOPEN_MAX 20 +#define _SYS_OPEN 20 +#define TMP_MAX _CRT_INT_MAX +#if __STDC_WANT_SECURE_LIB__ + #define TMP_MAX_S TMP_MAX + #define _TMP_MAX_S TMP_MAX +#endif + + +typedef __int64 fpos_t; + + + +#if _CRT_FUNCTIONS_REQUIRED + + _Check_return_opt_ + _ACRTIMP errno_t __cdecl _get_stream_buffer_pointers( + _In_ FILE* _Stream, + _Out_opt_ char*** _Base, + _Out_opt_ char*** _Pointer, + _Out_opt_ int** _Count + ); + + + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + // Narrow Character Stream I/O Functions + // + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + #if __STDC_WANT_SECURE_LIB__ + + _Check_return_wat_ + _ACRTIMP errno_t __cdecl clearerr_s( + _Inout_ FILE* _Stream + ); + + _Check_return_wat_ + _Success_(return == 0) + _ACRTIMP errno_t __cdecl fopen_s( + _Outptr_result_nullonfailure_ FILE** _Stream, + _In_z_ char const* _FileName, + _In_z_ char const* _Mode + ); + + _Check_return_opt_ + _Success_(return != 0) + _ACRTIMP size_t __cdecl fread_s( + _Out_writes_bytes_to_(_BufferSize, _ElementSize * _ElementCount) void* _Buffer, + _In_range_(>=, _ElementSize * _ElementCount) size_t _BufferSize, + _In_ size_t _ElementSize, + _In_ size_t _ElementCount, + _Inout_ FILE* _Stream + ); + + _Check_return_wat_ + _ACRTIMP errno_t __cdecl freopen_s( + _Outptr_result_maybenull_ FILE** _Stream, + _In_z_ char const* _FileName, + _In_z_ char const* _Mode, + _Inout_ FILE* _OldStream + ); + + _Success_(return != 0) + _ACRTIMP char* __cdecl gets_s( + _Out_writes_z_(_Size) char* _Buffer, + _In_ rsize_t _Size + ); + + _Check_return_wat_ + _ACRTIMP errno_t __cdecl tmpfile_s( + _Out_opt_ _Deref_post_valid_ FILE** _Stream + ); + + _Success_(return == 0) + _Check_return_wat_ + _ACRTIMP errno_t __cdecl tmpnam_s( + _Out_writes_z_(_Size) char* _Buffer, + _In_ rsize_t _Size + ); + + #endif + + _ACRTIMP void __cdecl clearerr( + _Inout_ FILE* _Stream + ); + + _Success_(return != -1) + _Check_return_opt_ + _ACRTIMP int __cdecl fclose( + _Inout_ FILE* _Stream + ); + + _Check_return_opt_ + _ACRTIMP int __cdecl _fcloseall(void); + + _Check_return_ + _ACRTIMP FILE* __cdecl _fdopen( + _In_ int _FileHandle, + _In_z_ char const* _Mode + ); + + _Check_return_ + _ACRTIMP int __cdecl feof( + _In_ FILE* _Stream + ); + + _Check_return_ + _ACRTIMP int __cdecl ferror( + _In_ FILE* _Stream + ); + + _Check_return_opt_ + _ACRTIMP int __cdecl fflush( + _Inout_opt_ FILE* _Stream + ); + + _Success_(return != EOF) + _Check_return_opt_ + _ACRTIMP int __cdecl fgetc( + _Inout_ FILE* _Stream + ); + + _Check_return_opt_ + _ACRTIMP int __cdecl _fgetchar(void); + + _Success_(return != EOF) + _Check_return_opt_ + _ACRTIMP int __cdecl fgetpos( + _Inout_ FILE* _Stream, + _Out_ fpos_t* _Position + ); + + _Success_(return == _Buffer) + _Check_return_opt_ + _ACRTIMP char* __cdecl fgets( + _Out_writes_z_(_MaxCount) char* _Buffer, + _In_ int _MaxCount, + _Inout_ FILE* _Stream + ); + + _Check_return_ + _ACRTIMP int __cdecl _fileno( + _In_ FILE* _Stream + ); + + _Check_return_opt_ + _ACRTIMP int __cdecl _flushall(void); + + _Check_return_ _CRT_INSECURE_DEPRECATE(fopen_s) + _ACRTIMP FILE* __cdecl fopen( + _In_z_ char const* _FileName, + _In_z_ char const* _Mode + ); + + + _Success_(return != EOF) + _Check_return_opt_ + _ACRTIMP int __cdecl fputc( + _In_ int _Character, + _Inout_ FILE* _Stream + ); + + _Check_return_opt_ + _ACRTIMP int __cdecl _fputchar( + _In_ int _Character + ); + + _Success_(return != EOF) + _Check_return_opt_ + _ACRTIMP int __cdecl fputs( + _In_z_ char const* _Buffer, + _Inout_ FILE* _Stream + ); + + _Check_return_opt_ + _ACRTIMP size_t __cdecl fread( + _Out_writes_bytes_(_ElementSize * _ElementCount) void* _Buffer, + _In_ size_t _ElementSize, + _In_ size_t _ElementCount, + _Inout_ FILE* _Stream + ); + + _Success_(return != 0) + _Check_return_ _CRT_INSECURE_DEPRECATE(freopen_s) + _ACRTIMP FILE* __cdecl freopen( + _In_z_ char const* _FileName, + _In_z_ char const* _Mode, + _Inout_ FILE* _Stream + ); + + _Check_return_ + _ACRTIMP FILE* __cdecl _fsopen( + _In_z_ char const* _FileName, + _In_z_ char const* _Mode, + _In_ int _ShFlag + ); + + _Success_(return == 0) + _Check_return_opt_ + _ACRTIMP int __cdecl fsetpos( + _Inout_ FILE* _Stream, + _In_ fpos_t const* _Position + ); + + _Success_(return == 0) + _Check_return_opt_ + _ACRTIMP int __cdecl fseek( + _Inout_ FILE* _Stream, + _In_ long _Offset, + _In_ int _Origin + ); + + _Success_(return == 0) + _Check_return_opt_ + _ACRTIMP int __cdecl _fseeki64( + _Inout_ FILE* _Stream, + _In_ __int64 _Offset, + _In_ int _Origin + ); + + _Success_(return != -1) + _Check_return_ + _ACRTIMP long __cdecl ftell( + _Inout_ FILE* _Stream + ); + + _Success_(return != -1) + _Check_return_ + _ACRTIMP __int64 __cdecl _ftelli64( + _Inout_ FILE* _Stream + ); + + _Check_return_opt_ + _ACRTIMP size_t __cdecl fwrite( + _In_reads_bytes_(_ElementSize * _ElementCount) void const* _Buffer, + _In_ size_t _ElementSize, + _In_ size_t _ElementCount, + _Inout_ FILE* _Stream + ); + + _Success_(return != EOF) + _Check_return_ + _ACRTIMP int __cdecl getc( + _Inout_ FILE* _Stream + ); + + _Check_return_ + _ACRTIMP int __cdecl getchar(void); + + _Check_return_ + _ACRTIMP int __cdecl _getmaxstdio(void); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_0( + char*, gets_s, + char, _Buffer) + + _Check_return_ + _ACRTIMP int __cdecl _getw( + _Inout_ FILE* _Stream + ); + + _ACRTIMP void __cdecl perror( + _In_opt_z_ char const* _ErrorMessage + ); + + #if defined _CRT_USE_WINAPI_FAMILY_DESKTOP_APP + + _Success_(return != -1) + _Check_return_opt_ + _DCRTIMP int __cdecl _pclose( + _Inout_ FILE* _Stream + ); + + _Check_return_ + _DCRTIMP FILE* __cdecl _popen( + _In_z_ char const* _Command, + _In_z_ char const* _Mode + ); + + #endif + + _Success_(return != EOF) + _Check_return_opt_ + _ACRTIMP int __cdecl putc( + _In_ int _Character, + _Inout_ FILE* _Stream + ); + + _Check_return_opt_ + _ACRTIMP int __cdecl putchar( + _In_ int _Character + ); + + _Check_return_opt_ + _ACRTIMP int __cdecl puts( + _In_z_ char const* _Buffer + ); + + _Success_(return != -1) + _Check_return_opt_ + _ACRTIMP int __cdecl _putw( + _In_ int _Word, + _Inout_ FILE* _Stream + ); + + _ACRTIMP int __cdecl remove( + _In_z_ char const* _FileName + ); + + _Check_return_ + _ACRTIMP int __cdecl rename( + _In_z_ char const* _OldFileName, + _In_z_ char const* _NewFileName + ); + + _ACRTIMP int __cdecl _unlink( + _In_z_ char const* _FileName + ); + + #if defined(_CRT_INTERNAL_NONSTDC_NAMES) && _CRT_INTERNAL_NONSTDC_NAMES + + _CRT_NONSTDC_DEPRECATE(_unlink) + _ACRTIMP int __cdecl unlink( + _In_z_ char const* _FileName + ); + + #endif + + _ACRTIMP void __cdecl rewind( + _Inout_ FILE* _Stream + ); + + _Check_return_opt_ + _ACRTIMP int __cdecl _rmtmp(void); + + _CRT_INSECURE_DEPRECATE(setvbuf) + _ACRTIMP void __cdecl setbuf( + _Inout_ FILE* _Stream, + _Inout_updates_opt_(BUFSIZ) _Post_readable_size_(0) char* _Buffer + ); + + _Check_return_opt_ + _ACRTIMP int __cdecl _setmaxstdio( + _In_ int _Maximum + ); + + _Success_(return == 0) + _Check_return_opt_ + _ACRTIMP int __cdecl setvbuf( + _Inout_ FILE* _Stream, + _Inout_updates_opt_(_Size) char* _Buffer, + _In_ int _Mode, + _In_ size_t _Size + ); + + #if defined _DEBUG && defined _CRTDBG_MAP_ALLOC + #pragma push_macro("_tempnam") + #undef _tempnam + #endif + + _Check_return_ + _ACRTIMP _CRTALLOCATOR char* __cdecl _tempnam( + _In_opt_z_ char const* _DirectoryName, + _In_opt_z_ char const* _FilePrefix + ); + + #if defined _DEBUG && defined _CRTDBG_MAP_ALLOC + #pragma pop_macro("_tempnam") + #endif + + _Check_return_ _CRT_INSECURE_DEPRECATE(tmpfile_s) + _ACRTIMP FILE* __cdecl tmpfile(void); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_0( + _Success_(return == 0) + errno_t, tmpnam_s, + _Always_(_Post_z_) char, _Buffer + ) + +__DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_0( + _Success_(return != 0) + char*, __RETURN_POLICY_DST, _ACRTIMP, tmpnam, + _Pre_maybenull_ _Always_(_Post_z_), char, _Buffer + ) + + _Success_(return != EOF) + _Check_return_opt_ + _ACRTIMP int __cdecl ungetc( + _In_ int _Character, + _Inout_ FILE* _Stream + ); + + + + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + // I/O Synchronization and _nolock family of I/O functions + // + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + _ACRTIMP void __cdecl _lock_file( + _Inout_ FILE* _Stream + ); + + _ACRTIMP void __cdecl _unlock_file( + _Inout_ FILE* _Stream + ); + + _Success_(return != EOF) + _Check_return_opt_ + _ACRTIMP int __cdecl _fclose_nolock( + _Inout_ FILE* _Stream + ); + + _Success_(return != EOF) + _Check_return_opt_ + _ACRTIMP int __cdecl _fflush_nolock( + _Inout_opt_ FILE* _Stream + ); + + _Success_(return != EOF) + _Check_return_opt_ + _ACRTIMP int __cdecl _fgetc_nolock( + _Inout_ FILE* _Stream + ); + + _Success_(return != EOF) + _Check_return_opt_ + _ACRTIMP int __cdecl _fputc_nolock( + _In_ int _Character, + _Inout_ FILE* _Stream + ); + + _Check_return_opt_ + _ACRTIMP size_t __cdecl _fread_nolock( + _Out_writes_bytes_(_ElementSize * _ElementCount) void* _Buffer, + _In_ size_t _ElementSize, + _In_ size_t _ElementCount, + _Inout_ FILE* _Stream + ); + + _Check_return_opt_ + _Success_(return != 0) + _ACRTIMP size_t __cdecl _fread_nolock_s( + _Out_writes_bytes_to_(_BufferSize, _ElementSize * _ElementCount) void* _Buffer, + _In_range_(>=, _ElementSize * _ElementCount) size_t _BufferSize, + _In_ size_t _ElementSize, + _In_ size_t _ElementCount, + _Inout_ FILE* _Stream + ); + + _Check_return_opt_ + _ACRTIMP int __cdecl _fseek_nolock( + _Inout_ FILE* _Stream, + _In_ long _Offset, + _In_ int _Origin + ); + + _Check_return_opt_ + _ACRTIMP int __cdecl _fseeki64_nolock( + _Inout_ FILE* _Stream, + _In_ __int64 _Offset, + _In_ int _Origin + ); + + _Check_return_ + _ACRTIMP long __cdecl _ftell_nolock( + _Inout_ FILE* _Stream + ); + + _Check_return_ + _ACRTIMP __int64 __cdecl _ftelli64_nolock( + _Inout_ FILE* _Stream + ); + + _Check_return_opt_ + _ACRTIMP size_t __cdecl _fwrite_nolock( + _In_reads_bytes_(_ElementSize * _ElementCount) void const* _Buffer, + _In_ size_t _ElementSize, + _In_ size_t _ElementCount, + _Inout_ FILE* _Stream + ); + + _Check_return_opt_ + _ACRTIMP int __cdecl _getc_nolock( + _Inout_ FILE* _Stream + ); + + _Check_return_opt_ + _ACRTIMP int __cdecl _putc_nolock( + _In_ int _Character, + _Inout_ FILE* _Stream + ); + + _Check_return_opt_ + _ACRTIMP int __cdecl _ungetc_nolock( + _In_ int _Character, + _Inout_ FILE* _Stream + ); + + #define _getchar_nolock() _getc_nolock(stdin) + #define _putchar_nolock(_Ch) _putc_nolock(_Ch, stdout) + #define _getwchar_nolock() _getwc_nolock(stdin) + #define _putwchar_nolock(_Ch) _putwc_nolock(_Ch, stdout) + + + + #if defined _CRT_DISABLE_PERFCRIT_LOCKS && !defined _DLL + #define fclose(_Stream) _fclose_nolock(_Stream) + #define fflush(_Stream) _fflush_nolock(_Stream) + #define fgetc(_Stream) _fgetc_nolock(_Stream) + #define fputc(_Ch, _Stream) _fputc_nolock(_Ch, _Stream) + #define fread(_DstBuf, _ElementSize, _Count, _Stream) _fread_nolock(_DstBuf, _ElementSize, _Count, _Stream) + #define fread_s(_DstBuf, _DstSize, _ElementSize, _Count, _Stream) _fread_nolock_s(_DstBuf, _DstSize, _ElementSize, _Count, _Stream) + #define fseek(_Stream, _Offset, _Origin) _fseek_nolock(_Stream, _Offset, _Origin) + #define _fseeki64(_Stream, _Offset, _Origin) _fseeki64_nolock(_Stream, _Offset, _Origin) + #define ftell(_Stream) _ftell_nolock(_Stream) + #define _ftelli64(_Stream) _ftelli64_nolock(_Stream) + #define fwrite(_SrcBuf, _ElementSize, _Count, _Stream) _fwrite_nolock(_SrcBuf, _ElementSize, _Count, _Stream) + #define getc(_Stream) _getc_nolock(_Stream) + #define putc(_Ch, _Stream) _putc_nolock(_Ch, _Stream) + #define ungetc(_Ch, _Stream) _ungetc_nolock(_Ch, _Stream) + #endif + + + + _ACRTIMP int* __cdecl __p__commode(void); + + #ifdef _CRT_DECLARE_GLOBAL_VARIABLES_DIRECTLY + extern int _commode; + #else + #define _commode (*__p__commode()) + #endif + + + + // Variadic functions are not supported in managed code under /clr + #if defined _M_CEE_MIXED + #pragma managed(push, off) + #endif + + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + // Narrow Character Formatted Output Functions (Stream) + // + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + _ACRTIMP int __cdecl __stdio_common_vfprintf( + _In_ unsigned __int64 _Options, + _Inout_ FILE* _Stream, + _In_z_ _Printf_format_string_params_(2) char const* _Format, + _In_opt_ _locale_t _Locale, + va_list _ArgList + ); + + _ACRTIMP int __cdecl __stdio_common_vfprintf_s( + _In_ unsigned __int64 _Options, + _Inout_ FILE* _Stream, + _In_z_ _Printf_format_string_params_(2) char const* _Format, + _In_opt_ _locale_t _Locale, + va_list _ArgList + ); + + _Success_(return >= 0) + _ACRTIMP int __cdecl __stdio_common_vfprintf_p( + _In_ unsigned __int64 _Options, + _Inout_ FILE* _Stream, + _In_z_ _Printf_format_string_params_(2) char const* _Format, + _In_opt_ _locale_t _Locale, + va_list _ArgList + ); + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vfprintf_l( + _Inout_ FILE* const _Stream, + _In_z_ char const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return __stdio_common_vfprintf(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, _Stream, _Format, _Locale, _ArgList); + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL vfprintf( + _Inout_ FILE* const _Stream, + _In_z_ _Printf_format_string_ char const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vfprintf_l(_Stream, _Format, NULL, _ArgList); + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vfprintf_s_l( + _Inout_ FILE* const _Stream, + _In_z_ char const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return __stdio_common_vfprintf_s(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, _Stream, _Format, _Locale, _ArgList); + } + #endif + + #if __STDC_WANT_SECURE_LIB__ + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL vfprintf_s( + _Inout_ FILE* const _Stream, + _In_z_ _Printf_format_string_ char const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vfprintf_s_l(_Stream, _Format, NULL, _ArgList); + } + #endif + + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vfprintf_p_l( + _Inout_ FILE* const _Stream, + _In_z_ char const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return __stdio_common_vfprintf_p(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, _Stream, _Format, _Locale, _ArgList); + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vfprintf_p( + _Inout_ FILE* const _Stream, + _In_z_ _Printf_format_string_ char const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vfprintf_p_l(_Stream, _Format, NULL, _ArgList); + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vprintf_l( + _In_z_ _Printf_format_string_params_(2) char const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vfprintf_l(stdout, _Format, _Locale, _ArgList); + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL vprintf( + _In_z_ _Printf_format_string_ char const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vfprintf_l(stdout, _Format, NULL, _ArgList); + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vprintf_s_l( + _In_z_ _Printf_format_string_params_(2) char const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vfprintf_s_l(stdout, _Format, _Locale, _ArgList); + } + #endif + + #if __STDC_WANT_SECURE_LIB__ + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL vprintf_s( + _In_z_ _Printf_format_string_ char const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vfprintf_s_l(stdout, _Format, NULL, _ArgList); + } + #endif + + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vprintf_p_l( + _In_z_ _Printf_format_string_params_(2) char const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vfprintf_p_l(stdout, _Format, _Locale, _ArgList); + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vprintf_p( + _In_z_ _Printf_format_string_ char const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vfprintf_p_l(stdout, _Format, NULL, _ArgList); + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _fprintf_l( + _Inout_ FILE* const _Stream, + _In_z_ _Printf_format_string_params_(0) char const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vfprintf_l(_Stream, _Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL fprintf( + _Inout_ FILE* const _Stream, + _In_z_ _Printf_format_string_ char const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vfprintf_l(_Stream, _Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _ACRTIMP int __cdecl _set_printf_count_output( + _In_ int _Value + ); + + _ACRTIMP int __cdecl _get_printf_count_output(void); + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _fprintf_s_l( + _Inout_ FILE* const _Stream, + _In_z_ _Printf_format_string_params_(0) char const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vfprintf_s_l(_Stream, _Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + #if __STDC_WANT_SECURE_LIB__ + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL fprintf_s( + _Inout_ FILE* const _Stream, + _In_z_ _Printf_format_string_ char const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vfprintf_s_l(_Stream, _Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _fprintf_p_l( + _Inout_ FILE* const _Stream, + _In_z_ _Printf_format_string_params_(0) char const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vfprintf_p_l(_Stream, _Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _fprintf_p( + _Inout_ FILE* const _Stream, + _In_z_ _Printf_format_string_ char const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vfprintf_p_l(_Stream, _Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _printf_l( + _In_z_ _Printf_format_string_params_(0) char const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vfprintf_l(stdout, _Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL printf( + _In_z_ _Printf_format_string_ char const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vfprintf_l(stdout, _Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _printf_s_l( + _In_z_ _Printf_format_string_params_(0) char const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vfprintf_s_l(stdout, _Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + #if __STDC_WANT_SECURE_LIB__ + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL printf_s( + _In_z_ _Printf_format_string_ char const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vfprintf_s_l(stdout, _Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _printf_p_l( + _In_z_ _Printf_format_string_params_(0) char const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vfprintf_p_l(stdout, _Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _printf_p( + _In_z_ _Printf_format_string_ char const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vfprintf_p_l(stdout, _Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + // Narrow Character Formatted Input Functions (Stream) + // + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + _ACRTIMP int __cdecl __stdio_common_vfscanf( + _In_ unsigned __int64 _Options, + _Inout_ FILE* _Stream, + _In_z_ _Scanf_format_string_params_(2) char const* _Format, + _In_opt_ _locale_t _Locale, + va_list _Arglist + ); + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vfscanf_l( + _Inout_ FILE* const _Stream, + _In_z_ _Printf_format_string_ char const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return __stdio_common_vfscanf( + _CRT_INTERNAL_LOCAL_SCANF_OPTIONS, + _Stream, _Format, _Locale, _ArgList); + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL vfscanf( + _Inout_ FILE* const _Stream, + _In_z_ _Printf_format_string_ char const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vfscanf_l(_Stream, _Format, NULL, _ArgList); + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vfscanf_s_l( + _Inout_ FILE* const _Stream, + _In_z_ _Printf_format_string_ char const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return __stdio_common_vfscanf( + _CRT_INTERNAL_LOCAL_SCANF_OPTIONS | _CRT_INTERNAL_SCANF_SECURECRT, + _Stream, _Format, _Locale, _ArgList); + } + #endif + + + #if __STDC_WANT_SECURE_LIB__ + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL vfscanf_s( + _Inout_ FILE* const _Stream, + _In_z_ _Printf_format_string_ char const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vfscanf_s_l(_Stream, _Format, NULL, _ArgList); + } + #endif + + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vscanf_l( + _In_z_ _Printf_format_string_ char const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vfscanf_l(stdin, _Format, _Locale, _ArgList); + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL vscanf( + _In_z_ _Printf_format_string_ char const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vfscanf_l(stdin, _Format, NULL, _ArgList); + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vscanf_s_l( + _In_z_ _Printf_format_string_ char const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vfscanf_s_l(stdin, _Format, _Locale, _ArgList); + } + #endif + + #if __STDC_WANT_SECURE_LIB__ + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL vscanf_s( + _In_z_ _Printf_format_string_ char const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vfscanf_s_l(stdin, _Format, NULL, _ArgList); + } + #endif + + #endif + + _Check_return_opt_ _CRT_INSECURE_DEPRECATE(_fscanf_s_l) + _CRT_STDIO_INLINE int __CRTDECL _fscanf_l( + _Inout_ FILE* const _Stream, + _In_z_ _Scanf_format_string_params_(0) char const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE // SCANF + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vfscanf_l(_Stream, _Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Check_return_ _CRT_INSECURE_DEPRECATE(fscanf_s) + _CRT_STDIO_INLINE int __CRTDECL fscanf( + _Inout_ FILE* const _Stream, + _In_z_ _Scanf_format_string_ char const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE // SCANF + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vfscanf_l(_Stream, _Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _fscanf_s_l( + _Inout_ FILE* const _Stream, + _In_z_ _Scanf_s_format_string_params_(0) char const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE // SCANF + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vfscanf_s_l(_Stream, _Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + #if __STDC_WANT_SECURE_LIB__ + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL fscanf_s( + _Inout_ FILE* const _Stream, + _In_z_ _Scanf_s_format_string_ char const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE // SCANF + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vfscanf_s_l(_Stream, _Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + #endif + + _Check_return_opt_ _CRT_INSECURE_DEPRECATE(_scanf_s_l) + _CRT_STDIO_INLINE int __CRTDECL _scanf_l( + _In_z_ _Scanf_format_string_params_(0) char const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE // SCANF + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vfscanf_l(stdin, _Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Check_return_ _CRT_INSECURE_DEPRECATE(scanf_s) + _CRT_STDIO_INLINE int __CRTDECL scanf( + _In_z_ _Scanf_format_string_ char const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE // SCANF + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vfscanf_l(stdin, _Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _scanf_s_l( + _In_z_ _Scanf_s_format_string_params_(0) char const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE // SCANF + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vfscanf_s_l(stdin, _Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + #if __STDC_WANT_SECURE_LIB__ + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL scanf_s( + _In_z_ _Scanf_s_format_string_ char const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE // SCANF + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vfscanf_s_l(stdin, _Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + #endif + + + + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + // Narrow Character Formatted Output Functions (String) + // + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + _Success_(return >= 0) + _ACRTIMP int __cdecl __stdio_common_vsprintf( + _In_ unsigned __int64 _Options, + _Out_writes_opt_z_(_BufferCount) char* _Buffer, + _In_ size_t _BufferCount, + _In_z_ _Printf_format_string_params_(2) char const* _Format, + _In_opt_ _locale_t _Locale, + va_list _ArgList + ); + + _Success_(return >= 0) + _ACRTIMP int __cdecl __stdio_common_vsprintf_s( + _In_ unsigned __int64 _Options, + _Out_writes_z_(_BufferCount) char* _Buffer, + _In_ size_t _BufferCount, + _In_z_ _Printf_format_string_params_(2) char const* _Format, + _In_opt_ _locale_t _Locale, + va_list _ArgList + ); + + _Success_(return >= 0) + _ACRTIMP int __cdecl __stdio_common_vsnprintf_s( + _In_ unsigned __int64 _Options, + _Out_writes_opt_z_(_BufferCount) char* _Buffer, + _In_ size_t _BufferCount, + _In_ size_t _MaxCount, + _In_z_ _Printf_format_string_params_(2) char const* _Format, + _In_opt_ _locale_t _Locale, + va_list _ArgList + ); + + _Success_(return >= 0) + _ACRTIMP int __cdecl __stdio_common_vsprintf_p( + _In_ unsigned __int64 _Options, + _Out_writes_z_(_BufferCount) char* _Buffer, + _In_ size_t _BufferCount, + _In_z_ _Printf_format_string_params_(2) char const* _Format, + _In_opt_ _locale_t _Locale, + va_list _ArgList + ); + + _Success_(return >= 0) + _Check_return_opt_ _CRT_INSECURE_DEPRECATE(_vsnprintf_s_l) + _CRT_STDIO_INLINE int __CRTDECL _vsnprintf_l( + _Out_writes_opt_(_BufferCount) _Post_maybez_ char* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Printf_format_string_params_(2) char const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int const _Result = __stdio_common_vsprintf( + _CRT_INTERNAL_LOCAL_PRINTF_OPTIONS | _CRT_INTERNAL_PRINTF_LEGACY_VSPRINTF_NULL_TERMINATION, + _Buffer, _BufferCount, _Format, _Locale, _ArgList); + + return _Result < 0 ? -1 : _Result; + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vsnprintf( + _Out_writes_opt_(_BufferCount) _Post_maybez_ char* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Printf_format_string_ char const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vsnprintf_l(_Buffer, _BufferCount, _Format, NULL, _ArgList); + } + #endif + + #if defined vsnprintf + // This definition of vsnprintf will generate "warning C4005: 'vsnprintf': macro + // redefinition" with a subsequent line indicating where the previous definition + // of vsnprintf was. This makes it easier to find where vsnprintf was defined. + #pragma warning(push, 1) + #pragma warning(1: 4005) // macro redefinition + #define vsnprintf Do not define vsnprintf as a macro + #pragma warning(pop) + #error Macro definition of vsnprintf conflicts with Standard Library function declaration + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL vsnprintf( + _Out_writes_opt_(_BufferCount) _Always_(_Post_z_) char* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Printf_format_string_ char const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int const _Result = __stdio_common_vsprintf( + _CRT_INTERNAL_LOCAL_PRINTF_OPTIONS | _CRT_INTERNAL_PRINTF_STANDARD_SNPRINTF_BEHAVIOR, + _Buffer, _BufferCount, _Format, NULL, _ArgList); + + return _Result < 0 ? -1 : _Result; + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ _CRT_INSECURE_DEPRECATE(_vsprintf_s_l) + _CRT_STDIO_INLINE int __CRTDECL _vsprintf_l( + _Pre_notnull_ _Always_(_Post_z_) char* const _Buffer, + _In_z_ char const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vsnprintf_l(_Buffer, (size_t)-1, _Format, _Locale, _ArgList); + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ _CRT_INSECURE_DEPRECATE(vsprintf_s) + _CRT_STDIO_INLINE int __CRTDECL vsprintf( + _Pre_notnull_ _Always_(_Post_z_) char* const _Buffer, + _In_z_ _Printf_format_string_ char const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vsnprintf_l(_Buffer, (size_t)-1, _Format, NULL, _ArgList); + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vsprintf_s_l( + _Out_writes_(_BufferCount) _Always_(_Post_z_) char* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Printf_format_string_params_(2) char const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int const _Result = __stdio_common_vsprintf_s( + _CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, + _Buffer, _BufferCount, _Format, _Locale, _ArgList); + + return _Result < 0 ? -1 : _Result; + } + #endif + + #if __STDC_WANT_SECURE_LIB__ + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL vsprintf_s( + _Out_writes_(_BufferCount) _Always_(_Post_z_) char* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Printf_format_string_ char const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vsprintf_s_l(_Buffer, _BufferCount, _Format, NULL, _ArgList); + } + #endif + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2( + _Success_(return >= 0) + int, vsprintf_s, + _Always_(_Post_z_) char, _Buffer, + _In_z_ _Printf_format_string_ char const*, _Format, + va_list, _ArgList + ) + + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vsprintf_p_l( + _Out_writes_(_BufferCount) _Always_(_Post_z_) char* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Printf_format_string_params_(2) char const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int const _Result = __stdio_common_vsprintf_p( + _CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, + _Buffer, _BufferCount, _Format, _Locale, _ArgList); + + return _Result < 0 ? -1 : _Result; + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vsprintf_p( + _Out_writes_(_BufferCount) _Always_(_Post_z_) char* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Printf_format_string_ char const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vsprintf_p_l(_Buffer, _BufferCount, _Format, NULL, _ArgList); + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vsnprintf_s_l( + _Out_writes_opt_(_BufferCount) _Always_(_Post_z_) char* const _Buffer, + _In_ size_t const _BufferCount, + _In_ size_t const _MaxCount, + _In_z_ _Printf_format_string_params_(2) char const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int const _Result = __stdio_common_vsnprintf_s( + _CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, + _Buffer, _BufferCount, _MaxCount, _Format, _Locale, _ArgList); + + return _Result < 0 ? -1 : _Result; + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vsnprintf_s( + _Out_writes_opt_(_BufferCount) _Always_(_Post_z_) char* const _Buffer, + _In_ size_t const _BufferCount, + _In_ size_t const _MaxCount, + _In_z_ _Printf_format_string_ char const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vsnprintf_s_l(_Buffer, _BufferCount, _MaxCount, _Format, NULL, _ArgList); + } + #endif + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_3( + _Success_(return >= 0) + int, _vsnprintf_s, + _Always_(_Post_z_) char, _Buffer, + _In_ size_t, _BufferCount, + _In_z_ _Printf_format_string_ char const*, _Format, + va_list, _ArgList + ) + + #if __STDC_WANT_SECURE_LIB__ + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL vsnprintf_s( + _Out_writes_opt_(_BufferCount) _Always_(_Post_z_) char* const _Buffer, + _In_ size_t const _BufferCount, + _In_ size_t const _MaxCount, + _In_z_ _Printf_format_string_ char const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vsnprintf_s_l(_Buffer, _BufferCount, _MaxCount, _Format, NULL, _ArgList); + } + #endif + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_3( + _Success_(return >= 0) + int, vsnprintf_s, + _Always_(_Post_z_) char, _Buffer, + _In_ size_t, _BufferCount, + _In_z_ _Printf_format_string_ char const*, _Format, + va_list, _ArgList + ) + + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vscprintf_l( + _In_z_ _Printf_format_string_params_(2) char const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int const _Result = __stdio_common_vsprintf( + _CRT_INTERNAL_LOCAL_PRINTF_OPTIONS | _CRT_INTERNAL_PRINTF_STANDARD_SNPRINTF_BEHAVIOR, + NULL, 0, _Format, _Locale, _ArgList); + + return _Result < 0 ? -1 : _Result; + } + #endif + + _Check_return_ + _CRT_STDIO_INLINE int __CRTDECL _vscprintf( + _In_z_ _Printf_format_string_ char const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vscprintf_l(_Format, NULL, _ArgList); + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vscprintf_p_l( + _In_z_ _Printf_format_string_params_(2) char const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int const _Result = __stdio_common_vsprintf_p( + _CRT_INTERNAL_LOCAL_PRINTF_OPTIONS | _CRT_INTERNAL_PRINTF_STANDARD_SNPRINTF_BEHAVIOR, + NULL, 0, _Format, _Locale, _ArgList); + + return _Result < 0 ? -1 : _Result; + } + #endif + + _Check_return_ + _CRT_STDIO_INLINE int __CRTDECL _vscprintf_p( + _In_z_ _Printf_format_string_ char const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vscprintf_p_l(_Format, NULL, _ArgList); + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vsnprintf_c_l( + _Out_writes_opt_(_BufferCount) char* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Printf_format_string_params_(2) char const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int const _Result = __stdio_common_vsprintf( + _CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, + _Buffer, _BufferCount, _Format, _Locale, _ArgList); + + return _Result < 0 ? -1 : _Result; + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vsnprintf_c( + _Out_writes_opt_(_BufferCount) char* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Printf_format_string_ char const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vsnprintf_c_l(_Buffer, _BufferCount, _Format, NULL, _ArgList); + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ _CRT_INSECURE_DEPRECATE(_sprintf_s_l) + _CRT_STDIO_INLINE int __CRTDECL _sprintf_l( + _Pre_notnull_ _Always_(_Post_z_) char* const _Buffer, + _In_z_ _Printf_format_string_params_(0) char const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + + _Result = _vsprintf_l(_Buffer, _Format, _Locale, _ArgList); + + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL sprintf( + _Pre_notnull_ _Always_(_Post_z_) char* const _Buffer, + _In_z_ _Printf_format_string_ char const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + + _Result = _vsprintf_l(_Buffer, _Format, NULL, _ArgList); + + __crt_va_end(_ArgList); + return _Result; + } + #endif + + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1_ARGLIST( + _Success_(return >= 0) + int, __RETURN_POLICY_SAME, __EMPTY_DECLSPEC, __CRTDECL, sprintf, vsprintf, + _Pre_notnull_ _Always_(_Post_z_), char, _Buffer, + _In_z_ _Printf_format_string_ char const*, _Format + ) + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _sprintf_s_l( + _Out_writes_(_BufferCount) _Always_(_Post_z_) char* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Printf_format_string_params_(0) char const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vsprintf_s_l(_Buffer, _BufferCount, _Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + #if __STDC_WANT_SECURE_LIB__ + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL sprintf_s( + _Out_writes_(_BufferCount) _Always_(_Post_z_) char* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Printf_format_string_ char const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vsprintf_s_l(_Buffer, _BufferCount, _Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + #endif + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1_ARGLIST( + _Success_(return >= 0) + int, sprintf_s, vsprintf_s, + _Always_(_Post_z_) char, _Buffer, + _In_z_ _Printf_format_string_ char const*, _Format + ) + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _sprintf_p_l( + _Out_writes_(_BufferCount) _Always_(_Post_z_) char* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Printf_format_string_params_(0) char const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vsprintf_p_l(_Buffer, _BufferCount, _Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _sprintf_p( + _Out_writes_(_BufferCount) _Always_(_Post_z_) char* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Printf_format_string_ char const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vsprintf_p_l(_Buffer, _BufferCount, _Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ _CRT_INSECURE_DEPRECATE(_snprintf_s_l) + _CRT_STDIO_INLINE int __CRTDECL _snprintf_l( + _Out_writes_opt_(_BufferCount) _Post_maybez_ char* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Printf_format_string_params_(0) char const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + + _Result = _vsnprintf_l(_Buffer, _BufferCount, _Format, _Locale, _ArgList); + + __crt_va_end(_ArgList); + return _Result; + } + #endif + + #if defined snprintf + // This definition of snprintf will generate "warning C4005: 'snprintf': macro + // redefinition" with a subsequent line indicating where the previous definition + // of snprintf was. This makes it easier to find where snprintf was defined. + #pragma warning(push, 1) + #pragma warning(1: 4005) // macro redefinition + #define snprintf Do not define snprintf as a macro + #pragma warning(pop) + #error Macro definition of snprintf conflicts with Standard Library function declaration + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL snprintf( + _Out_writes_opt_(_BufferCount) _Always_(_Post_z_) char* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Printf_format_string_ char const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = vsnprintf(_Buffer, _BufferCount, _Format, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _snprintf( + _Out_writes_opt_(_BufferCount) _Post_maybez_ char* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Printf_format_string_ char const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vsnprintf(_Buffer, _BufferCount, _Format, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2_ARGLIST_EX( + _Success_(return >= 0) + int, __RETURN_POLICY_SAME, __EMPTY_DECLSPEC, __CRTDECL, _snprintf, _vsnprintf, + _Pre_notnull_ _Post_maybez_ char, + _Out_writes_opt_(_BufferCount) _Post_maybez_, char, _Buffer, + _In_ size_t, _BufferCount, + _In_z_ _Printf_format_string_ char const*, _Format + ) + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _snprintf_c_l( + _Out_writes_opt_(_BufferCount) char* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Printf_format_string_params_(0) char const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vsnprintf_c_l(_Buffer, _BufferCount, _Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _snprintf_c( + _Out_writes_opt_(_BufferCount) char* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Printf_format_string_ char const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vsnprintf_c_l(_Buffer, _BufferCount, _Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _snprintf_s_l( + _Out_writes_opt_(_BufferCount) _Always_(_Post_z_) char* const _Buffer, + _In_ size_t const _BufferCount, + _In_ size_t const _MaxCount, + _In_z_ _Printf_format_string_params_(0) char const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vsnprintf_s_l(_Buffer, _BufferCount, _MaxCount, _Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Success_(return >= 0) + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _snprintf_s( + _Out_writes_opt_(_BufferCount) _Always_(_Post_z_) char* const _Buffer, + _In_ size_t const _BufferCount, + _In_ size_t const _MaxCount, + _In_z_ _Printf_format_string_ char const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vsnprintf_s_l(_Buffer, _BufferCount, _MaxCount, _Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2_ARGLIST( + _Success_(return >= 0) + int, _snprintf_s, _vsnprintf_s, + _Always_(_Post_z_) char, _Buffer, + _In_ size_t, _BufferCount, + _In_z_ _Printf_format_string_ char const*, _Format + ) + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _scprintf_l( + _In_z_ _Printf_format_string_params_(0) char const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vscprintf_l(_Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Check_return_ + _CRT_STDIO_INLINE int __CRTDECL _scprintf( + _In_z_ _Printf_format_string_ char const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vscprintf_l(_Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _scprintf_p_l( + _In_z_ _Printf_format_string_params_(0) char const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vscprintf_p_l(_Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Check_return_ + _CRT_STDIO_INLINE int __CRTDECL _scprintf_p( + _In_z_ _Printf_format_string_ char const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vscprintf_p(_Format, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + // Narrow Character Formatted Input Functions (String) + // + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + _ACRTIMP int __cdecl __stdio_common_vsscanf( + _In_ unsigned __int64 _Options, + _In_reads_(_BufferCount) _Pre_z_ char const* _Buffer, + _In_ size_t _BufferCount, + _In_z_ _Scanf_format_string_params_(2) char const* _Format, + _In_opt_ _locale_t _Locale, + va_list _ArgList + ); + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vsscanf_l( + _In_z_ char const* const _Buffer, + _In_z_ _Printf_format_string_ char const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return __stdio_common_vsscanf( + _CRT_INTERNAL_LOCAL_SCANF_OPTIONS, + _Buffer, (size_t)-1, _Format, _Locale, _ArgList); + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL vsscanf( + _In_z_ char const* const _Buffer, + _In_z_ _Printf_format_string_ char const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vsscanf_l(_Buffer, _Format, NULL, _ArgList); + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _vsscanf_s_l( + _In_z_ char const* const _Buffer, + _In_z_ _Printf_format_string_ char const* const _Format, + _In_opt_ _locale_t const _Locale, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return __stdio_common_vsscanf( + _CRT_INTERNAL_LOCAL_SCANF_OPTIONS | _CRT_INTERNAL_SCANF_SECURECRT, + _Buffer, (size_t)-1, _Format, _Locale, _ArgList); + } + #endif + + #if __STDC_WANT_SECURE_LIB__ + + #pragma warning(push) + #pragma warning(disable: 6530) // Unrecognized SAL format string + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL vsscanf_s( + _In_z_ char const* const _Buffer, + _In_z_ _Printf_format_string_ char const* const _Format, + va_list _ArgList + ) + #if defined _NO_CRT_STDIO_INLINE + ; + #else + { + return _vsscanf_s_l(_Buffer, _Format, NULL, _ArgList); + } + #endif + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2( + int, vsscanf_s, + _In_z_ char const, _Buffer, + _In_z_ _Printf_format_string_ char const*, _Format, + va_list, _ArgList + ) + + #pragma warning(pop) + + #endif + + _Check_return_opt_ _CRT_INSECURE_DEPRECATE(_sscanf_s_l) + _CRT_STDIO_INLINE int __CRTDECL _sscanf_l( + _In_z_ char const* const _Buffer, + _In_z_ _Scanf_format_string_params_(0) char const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE // SCANF + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vsscanf_l(_Buffer, _Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Check_return_ _CRT_INSECURE_DEPRECATE(sscanf_s) + _CRT_STDIO_INLINE int __CRTDECL sscanf( + _In_z_ char const* const _Buffer, + _In_z_ _Scanf_format_string_ char const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE // SCANF + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + _Result = _vsscanf_l(_Buffer, _Format, NULL, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _sscanf_s_l( + _In_z_ char const* const _Buffer, + _In_z_ _Scanf_s_format_string_params_(0) char const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE // SCANF + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + _Result = _vsscanf_s_l(_Buffer, _Format, _Locale, _ArgList); + __crt_va_end(_ArgList); + return _Result; + } + #endif + + #if __STDC_WANT_SECURE_LIB__ + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL sscanf_s( + _In_z_ char const* const _Buffer, + _In_z_ _Scanf_s_format_string_ char const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE // SCANF + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + + _Result = vsscanf_s(_Buffer, _Format, _ArgList); + + __crt_va_end(_ArgList); + return _Result; + } + #endif + + #endif + + #pragma warning(push) + #pragma warning(disable: 6530) // Unrecognized SAL format string + + _Check_return_opt_ _CRT_INSECURE_DEPRECATE(_snscanf_s_l) + _CRT_STDIO_INLINE int __CRTDECL _snscanf_l( + _In_reads_bytes_(_BufferCount) _Pre_z_ char const* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Scanf_format_string_params_(0) char const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE // SCANF + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + + _Result = __stdio_common_vsscanf( + _CRT_INTERNAL_LOCAL_SCANF_OPTIONS, + _Buffer, _BufferCount, _Format, _Locale, _ArgList); + + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Check_return_opt_ _CRT_INSECURE_DEPRECATE(_snscanf_s) + _CRT_STDIO_INLINE int __CRTDECL _snscanf( + _In_reads_bytes_(_BufferCount) _Pre_z_ char const* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Scanf_format_string_ char const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE // SCANF + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + + _Result = __stdio_common_vsscanf( + _CRT_INTERNAL_LOCAL_SCANF_OPTIONS, + _Buffer, _BufferCount, _Format, NULL, _ArgList); + + __crt_va_end(_ArgList); + return _Result; + } + #endif + + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _snscanf_s_l( + _In_reads_bytes_(_BufferCount) _Pre_z_ char const* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Scanf_s_format_string_params_(0) char const* const _Format, + _In_opt_ _locale_t const _Locale, + ...) + #if defined _NO_CRT_STDIO_INLINE // SCANF + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Locale); + + _Result = __stdio_common_vsscanf( + _CRT_INTERNAL_LOCAL_SCANF_OPTIONS | _CRT_INTERNAL_SCANF_SECURECRT, + _Buffer, _BufferCount, _Format, _Locale, _ArgList); + + __crt_va_end(_ArgList); + return _Result; + } + #endif + + _Check_return_opt_ + _CRT_STDIO_INLINE int __CRTDECL _snscanf_s( + _In_reads_bytes_(_BufferCount) _Pre_z_ char const* const _Buffer, + _In_ size_t const _BufferCount, + _In_z_ _Scanf_s_format_string_ char const* const _Format, + ...) + #if defined _NO_CRT_STDIO_INLINE // SCANF + ; + #else + { + int _Result; + va_list _ArgList; + __crt_va_start(_ArgList, _Format); + + _Result = __stdio_common_vsscanf( + _CRT_INTERNAL_LOCAL_SCANF_OPTIONS | _CRT_INTERNAL_SCANF_SECURECRT, + _Buffer, _BufferCount, _Format, NULL, _ArgList); + + __crt_va_end(_ArgList); + return _Result; + } + #endif + + #pragma warning(pop) + + #if defined _M_CEE_MIXED + #pragma managed(pop) + #endif + + + + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + // Non-ANSI Names for Compatibility + // + //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + #if defined(_CRT_INTERNAL_NONSTDC_NAMES) && _CRT_INTERNAL_NONSTDC_NAMES + + #define SYS_OPEN _SYS_OPEN + + #if defined _DEBUG && defined _CRTDBG_MAP_ALLOC + #pragma push_macro("tempnam") + #undef tempnam + #endif + + _CRT_NONSTDC_DEPRECATE(_tempnam) + _ACRTIMP char* __cdecl tempnam( + _In_opt_z_ char const* _Directory, + _In_opt_z_ char const* _FilePrefix + ); + + #if defined _DEBUG && defined _CRTDBG_MAP_ALLOC + #pragma pop_macro("tempnam") + #endif + + _Check_return_opt_ _CRT_NONSTDC_DEPRECATE(_fcloseall) _ACRTIMP int __cdecl fcloseall(void); + _Check_return_ _CRT_NONSTDC_DEPRECATE(_fdopen) _ACRTIMP FILE* __cdecl fdopen(_In_ int _FileHandle, _In_z_ char const* _Format); + _Check_return_opt_ _CRT_NONSTDC_DEPRECATE(_fgetchar) _ACRTIMP int __cdecl fgetchar(void); + _Check_return_ _CRT_NONSTDC_DEPRECATE(_fileno) _ACRTIMP int __cdecl fileno(_In_ FILE* _Stream); + _Check_return_opt_ _CRT_NONSTDC_DEPRECATE(_flushall) _ACRTIMP int __cdecl flushall(void); + _Check_return_opt_ _CRT_NONSTDC_DEPRECATE(_fputchar) _ACRTIMP int __cdecl fputchar(_In_ int _Ch); + _Check_return_ _CRT_NONSTDC_DEPRECATE(_getw) _ACRTIMP int __cdecl getw(_Inout_ FILE* _Stream); + _Check_return_opt_ _CRT_NONSTDC_DEPRECATE(_putw) _ACRTIMP int __cdecl putw(_In_ int _Ch, _Inout_ FILE* _Stream); + _Check_return_ _CRT_NONSTDC_DEPRECATE(_rmtmp) _ACRTIMP int __cdecl rmtmp(void); + + #endif // _CRT_INTERNAL_NONSTDC_NAMES +#endif // _CRT_FUNCTIONS_REQUIRED + + + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS +#endif // _INC_STDIO diff --git a/sdk/include/ucrt/stdlib.h b/sdk/include/ucrt/stdlib.h new file mode 100644 index 0000000000000..53b6e081d016b --- /dev/null +++ b/sdk/include/ucrt/stdlib.h @@ -0,0 +1,1362 @@ +// +// stdlib.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The C Standard Library header. +// +#pragma once +#ifndef _INC_STDLIB // include guard for 3rd party interop +#define _INC_STDLIB + +#include +#include +#include +#include +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + + + +#ifndef _countof + #define _countof __crt_countof +#endif + + + +// Minimum and maximum macros +#define __max(a,b) (((a) > (b)) ? (a) : (b)) +#define __min(a,b) (((a) < (b)) ? (a) : (b)) + + + +_ACRTIMP void __cdecl _swab( + _Inout_updates_(_SizeInBytes) _Post_readable_size_(_SizeInBytes) char* _Buf1, + _Inout_updates_(_SizeInBytes) _Post_readable_size_(_SizeInBytes) char* _Buf2, + _In_ int _SizeInBytes + ); + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Exit and Abort +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// Argument values for exit() +#define EXIT_SUCCESS 0 +#define EXIT_FAILURE 1 + +#if _CRT_FUNCTIONS_REQUIRED + _ACRTIMP __declspec(noreturn) void __cdecl exit(_In_ int _Code); + _ACRTIMP __declspec(noreturn) void __cdecl _exit(_In_ int _Code); + _ACRTIMP __declspec(noreturn) void __cdecl _Exit(_In_ int _Code); + _ACRTIMP __declspec(noreturn) void __cdecl quick_exit(_In_ int _Code); + _ACRTIMP __declspec(noreturn) void __cdecl abort(void); +#endif // _CRT_FUNCTIONS_REQUIRED + +// Argument values for _set_abort_behavior(). +#define _WRITE_ABORT_MSG 0x1 // debug only, has no effect in release +#define _CALL_REPORTFAULT 0x2 + +_ACRTIMP unsigned int __cdecl _set_abort_behavior( + _In_ unsigned int _Flags, + _In_ unsigned int _Mask + ); + + + +#ifndef _CRT_ONEXIT_T_DEFINED + #define _CRT_ONEXIT_T_DEFINED + + typedef int (__CRTDECL* _onexit_t)(void); + #ifdef _M_CEE + typedef int (__clrcall* _onexit_m_t)(void); + #endif +#endif + +#if defined(_CRT_INTERNAL_NONSTDC_NAMES) && _CRT_INTERNAL_NONSTDC_NAMES + // Non-ANSI name for compatibility + #define onexit_t _onexit_t +#endif + + + +#ifdef _M_CEE + #pragma warning (push) + #pragma warning (disable: 4985) // Attributes not present on previous declaration + + _Check_return_ int __clrcall _atexit_m_appdomain(_In_opt_ void (__clrcall* _Function)(void)); + + _onexit_m_t __clrcall _onexit_m_appdomain(_onexit_m_t _Function); + + #ifdef _M_CEE_MIXED + #ifdef __cplusplus + [System::Security::SecurityCritical] + #endif + _Check_return_ int __clrcall _atexit_m(_In_opt_ void (__clrcall* _Function)(void)); + + _onexit_m_t __clrcall _onexit_m(_onexit_m_t _Function); + #else + #ifdef __cplusplus + [System::Security::SecurityCritical] + #endif + _Check_return_ inline int __clrcall _atexit_m(_In_opt_ void (__clrcall* _Function)(void)) + { + return _atexit_m_appdomain(_Function); + } + + inline _onexit_m_t __clrcall _onexit_m(_onexit_t _Function) + { + return _onexit_m_appdomain(_Function); + } + #endif + #pragma warning (pop) +#endif + + + +#ifdef _M_CEE_PURE + // In pure mode, atexit is the same as atexit_m_appdomain + extern "C++" + { + + #ifdef __cplusplus + [System::Security::SecurityCritical] + #endif + inline int __clrcall atexit(void (__clrcall* _Function)(void)) + { + return _atexit_m_appdomain(_Function); + } + + inline _onexit_t __clrcall _onexit(_onexit_t _Function) + { + return _onexit_m_appdomain(_Function); + } + + } // extern "C++" +#else + int __cdecl atexit(void (__cdecl*)(void)); + _onexit_t __cdecl _onexit(_In_opt_ _onexit_t _Func); +#endif + +int __cdecl at_quick_exit(void (__cdecl*)(void)); + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Global State (errno, global handlers, etc.) +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#ifndef _M_CEE_PURE + // a purecall handler procedure. Never returns normally + typedef void (__cdecl* _purecall_handler)(void); + + // Invalid parameter handler function pointer type + typedef void (__cdecl* _invalid_parameter_handler)( + wchar_t const*, + wchar_t const*, + wchar_t const*, + unsigned int, + uintptr_t + ); + + // Establishes a purecall handler + _VCRTIMP _purecall_handler __cdecl _set_purecall_handler( + _In_opt_ _purecall_handler _Handler + ); + + _VCRTIMP _purecall_handler __cdecl _get_purecall_handler(void); + + // Establishes an invalid parameter handler + _ACRTIMP _invalid_parameter_handler __cdecl _set_invalid_parameter_handler( + _In_opt_ _invalid_parameter_handler _Handler + ); + + _ACRTIMP _invalid_parameter_handler __cdecl _get_invalid_parameter_handler(void); + + _ACRTIMP _invalid_parameter_handler __cdecl _set_thread_local_invalid_parameter_handler( + _In_opt_ _invalid_parameter_handler _Handler + ); + + _ACRTIMP _invalid_parameter_handler __cdecl _get_thread_local_invalid_parameter_handler(void); +#endif + + +#if defined __cplusplus && defined _M_CEE_PURE +extern "C++" +{ + typedef void (__clrcall* _purecall_handler)(void); + typedef _purecall_handler _purecall_handler_m; + + _MRTIMP _purecall_handler __cdecl _set_purecall_handler( + _In_opt_ _purecall_handler _Handler + ); +} // extern "C++" +#endif + + + +// Argument values for _set_error_mode(). +#define _OUT_TO_DEFAULT 0 +#define _OUT_TO_STDERR 1 +#define _OUT_TO_MSGBOX 2 +#define _REPORT_ERRMODE 3 + +_Check_return_opt_ _ACRTIMP int __cdecl _set_error_mode(_In_ int _Mode); + + + +#if _CRT_FUNCTIONS_REQUIRED + _ACRTIMP int* __cdecl _errno(void); + #define errno (*_errno()) + + _ACRTIMP errno_t __cdecl _set_errno(_In_ int _Value); + _ACRTIMP errno_t __cdecl _get_errno(_Out_ int* _Value); + + _ACRTIMP unsigned long* __cdecl __doserrno(void); + #define _doserrno (*__doserrno()) + + _ACRTIMP errno_t __cdecl _set_doserrno(_In_ unsigned long _Value); + _ACRTIMP errno_t __cdecl _get_doserrno(_Out_ unsigned long * _Value); + + // This is non-const for backwards compatibility; do not modify it. + _ACRTIMP _CRT_INSECURE_DEPRECATE(strerror) char** __cdecl __sys_errlist(void); + #define _sys_errlist (__sys_errlist()) + + _ACRTIMP _CRT_INSECURE_DEPRECATE(strerror) int * __cdecl __sys_nerr(void); + #define _sys_nerr (*__sys_nerr()) + + _ACRTIMP void __cdecl perror(_In_opt_z_ char const* _ErrMsg); +#endif // _CRT_FUNCTIONS_REQUIRED + + + +// These point to the executable module name. +_CRT_INSECURE_DEPRECATE_GLOBALS(_get_pgmptr ) _ACRTIMP char** __cdecl __p__pgmptr (void); +_CRT_INSECURE_DEPRECATE_GLOBALS(_get_wpgmptr) _ACRTIMP wchar_t** __cdecl __p__wpgmptr(void); +_CRT_INSECURE_DEPRECATE_GLOBALS(_get_fmode ) _ACRTIMP int* __cdecl __p__fmode (void); + +#ifdef _CRT_DECLARE_GLOBAL_VARIABLES_DIRECTLY + _CRT_INSECURE_DEPRECATE_GLOBALS(_get_pgmptr ) extern char* _pgmptr; + _CRT_INSECURE_DEPRECATE_GLOBALS(_get_wpgmptr) extern wchar_t* _wpgmptr; + #ifndef _CORECRT_BUILD + _CRT_INSECURE_DEPRECATE_GLOBALS(_get_fmode ) extern int _fmode; + #endif +#else + #define _pgmptr (*__p__pgmptr ()) + #define _wpgmptr (*__p__wpgmptr()) + #define _fmode (*__p__fmode ()) +#endif + +_Success_(return == 0) +_ACRTIMP errno_t __cdecl _get_pgmptr (_Outptr_result_z_ char** _Value); + +_Success_(return == 0) +_ACRTIMP errno_t __cdecl _get_wpgmptr(_Outptr_result_z_ wchar_t** _Value); + +_ACRTIMP errno_t __cdecl _set_fmode (_In_ int _Mode ); + +_ACRTIMP errno_t __cdecl _get_fmode (_Out_ int* _PMode); + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Math +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +typedef struct _div_t +{ + int quot; + int rem; +} div_t; + +typedef struct _ldiv_t +{ + long quot; + long rem; +} ldiv_t; + +typedef struct _lldiv_t +{ + long long quot; + long long rem; +} lldiv_t; + +_Check_return_ int __cdecl abs (_In_ int _Number); +_Check_return_ long __cdecl labs (_In_ long _Number); +_Check_return_ long long __cdecl llabs (_In_ long long _Number); +_Check_return_ __int64 __cdecl _abs64(_In_ __int64 _Number); + +_Check_return_ unsigned short __cdecl _byteswap_ushort(_In_ unsigned short _Number); +_Check_return_ unsigned long __cdecl _byteswap_ulong (_In_ unsigned long _Number); +_Check_return_ unsigned __int64 __cdecl _byteswap_uint64(_In_ unsigned __int64 _Number); + +_Check_return_ _ACRTIMP div_t __cdecl div (_In_ int _Numerator, _In_ int _Denominator); +_Check_return_ _ACRTIMP ldiv_t __cdecl ldiv (_In_ long _Numerator, _In_ long _Denominator); +_Check_return_ _ACRTIMP lldiv_t __cdecl lldiv(_In_ long long _Numerator, _In_ long long _Denominator); + +// These functions have declspecs in their declarations in the Windows headers, +// which cause PREfast to fire 6540. +#pragma warning(push) +#pragma warning(disable: 6540) + +unsigned int __cdecl _rotl( + _In_ unsigned int _Value, + _In_ int _Shift + ); + +_Check_return_ +unsigned long __cdecl _lrotl( + _In_ unsigned long _Value, + _In_ int _Shift + ); + +unsigned __int64 __cdecl _rotl64( + _In_ unsigned __int64 _Value, + _In_ int _Shift + ); + +unsigned int __cdecl _rotr( + _In_ unsigned int _Value, + _In_ int _Shift + ); + +_Check_return_ +unsigned long __cdecl _lrotr( + _In_ unsigned long _Value, + _In_ int _Shift + ); + +unsigned __int64 __cdecl _rotr64( + _In_ unsigned __int64 _Value, + _In_ int _Shift + ); + +#pragma warning(pop) + + + +// Maximum value that can be returned by the rand function: +#define RAND_MAX 0x7fff + +_ACRTIMP void __cdecl srand(_In_ unsigned int _Seed); + +_Check_return_ _ACRTIMP int __cdecl rand(void); + +#if defined _CRT_RAND_S || defined _CRTBLD + _ACRTIMP errno_t __cdecl rand_s(_Out_ unsigned int* _RandomValue); +#endif + + + +#ifdef __cplusplus +extern "C++" +{ + inline long abs(long const _X) throw() + { + return labs(_X); + } + + inline long long abs(long long const _X) throw() + { + return llabs(_X); + } + + inline ldiv_t div(long const _A1, long const _A2) throw() + { + return ldiv(_A1, _A2); + } + + inline lldiv_t div(long long const _A1, long long const _A2) throw() + { + return lldiv(_A1, _A2); + } +} +#endif // __cplusplus + + + + +// Structs used to fool the compiler into not generating floating point +// instructions when copying and pushing [long] double values +#define _CRT_DOUBLE_DEC + +#ifndef _LDSUPPORT + + #pragma pack(push, 4) + typedef struct + { + unsigned char ld[10]; + } _LDOUBLE; + #pragma pack(pop) + + #define _PTR_LD(x) ((unsigned char*)(&(x)->ld)) + +#else // _LDSUPPORT + + // push and pop long, which is #defined as __int64 by a spec2k test + #pragma push_macro("long") + #undef long + typedef long double _LDOUBLE; + #pragma pop_macro("long") + + #define _PTR_LD(x) ((unsigned char *)(x)) + +#endif // _LDSUPPORT + +typedef struct +{ + double x; +} _CRT_DOUBLE; + +typedef struct +{ + float f; +} _CRT_FLOAT; + +// push and pop long, which is #defined as __int64 by a spec2k test +#pragma push_macro("long") +#undef long + +typedef struct +{ + long double x; +} _LONGDOUBLE; + +#pragma pop_macro("long") + +#pragma pack(push, 4) +typedef struct +{ + unsigned char ld12[12]; +} _LDBL12; +#pragma pack(pop) + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Narrow String to Number Conversions +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +_Check_return_ _ACRTIMP double __cdecl atof (_In_z_ char const* _String); +_Check_return_ _CRT_JIT_INTRINSIC _ACRTIMP int __cdecl atoi (_In_z_ char const* _String); +_Check_return_ _ACRTIMP long __cdecl atol (_In_z_ char const* _String); +_Check_return_ _ACRTIMP long long __cdecl atoll (_In_z_ char const* _String); +_Check_return_ _ACRTIMP __int64 __cdecl _atoi64(_In_z_ char const* _String); + +_Check_return_ _ACRTIMP double __cdecl _atof_l (_In_z_ char const* _String, _In_opt_ _locale_t _Locale); +_Check_return_ _ACRTIMP int __cdecl _atoi_l (_In_z_ char const* _String, _In_opt_ _locale_t _Locale); +_Check_return_ _ACRTIMP long __cdecl _atol_l (_In_z_ char const* _String, _In_opt_ _locale_t _Locale); +_Check_return_ _ACRTIMP long long __cdecl _atoll_l (_In_z_ char const* _String, _In_opt_ _locale_t _Locale); +_Check_return_ _ACRTIMP __int64 __cdecl _atoi64_l(_In_z_ char const* _String, _In_opt_ _locale_t _Locale); + +_Check_return_ _ACRTIMP int __cdecl _atoflt (_Out_ _CRT_FLOAT* _Result, _In_z_ char const* _String); +_Check_return_ _ACRTIMP int __cdecl _atodbl (_Out_ _CRT_DOUBLE* _Result, _In_z_ char* _String); +_Check_return_ _ACRTIMP int __cdecl _atoldbl(_Out_ _LDOUBLE* _Result, _In_z_ char* _String); + +_Check_return_ +_ACRTIMP int __cdecl _atoflt_l( + _Out_ _CRT_FLOAT* _Result, + _In_z_ char const* _String, + _In_opt_ _locale_t _Locale + ); + +_Check_return_ +_ACRTIMP int __cdecl _atodbl_l( + _Out_ _CRT_DOUBLE* _Result, + _In_z_ char* _String, + _In_opt_ _locale_t _Locale + ); + + +_Check_return_ +_ACRTIMP int __cdecl _atoldbl_l( + _Out_ _LDOUBLE* _Result, + _In_z_ char* _String, + _In_opt_ _locale_t _Locale + ); + +_Check_return_ +_ACRTIMP float __cdecl strtof( + _In_z_ char const* _String, + _Out_opt_ _Deref_post_z_ char** _EndPtr + ); + +_Check_return_ +_ACRTIMP float __cdecl _strtof_l( + _In_z_ char const* _String, + _Out_opt_ _Deref_post_z_ char** _EndPtr, + _In_opt_ _locale_t _Locale + ); + +_Check_return_ +_ACRTIMP double __cdecl strtod( + _In_z_ char const* _String, + _Out_opt_ _Deref_post_z_ char** _EndPtr + ); + +_Check_return_ +_ACRTIMP double __cdecl _strtod_l( + _In_z_ char const* _String, + _Out_opt_ _Deref_post_z_ char** _EndPtr, + _In_opt_ _locale_t _Locale + ); + +_Check_return_ +_ACRTIMP long double __cdecl strtold( + _In_z_ char const* _String, + _Out_opt_ _Deref_post_z_ char** _EndPtr + ); + +_Check_return_ +_ACRTIMP long double __cdecl _strtold_l( + _In_z_ char const* _String, + _Out_opt_ _Deref_post_z_ char** _EndPtr, + _In_opt_ _locale_t _Locale + ); + +_Check_return_ +_ACRTIMP long __cdecl strtol( + _In_z_ char const* _String, + _Out_opt_ _Deref_post_z_ char** _EndPtr, + _In_ int _Radix + ); + +_Check_return_ +_ACRTIMP long __cdecl _strtol_l( + _In_z_ char const* _String, + _Out_opt_ _Deref_post_z_ char** _EndPtr, + _In_ int _Radix, + _In_opt_ _locale_t _Locale + ); + +_Check_return_ +_ACRTIMP long long __cdecl strtoll( + _In_z_ char const* _String, + _Out_opt_ _Deref_post_z_ char** _EndPtr, + _In_ int _Radix + ); + +_Check_return_ +_ACRTIMP long long __cdecl _strtoll_l( + _In_z_ char const* _String, + _Out_opt_ _Deref_post_z_ char** _EndPtr, + _In_ int _Radix, + _In_opt_ _locale_t _Locale + ); + +_Check_return_ +_ACRTIMP unsigned long __cdecl strtoul( + _In_z_ char const* _String, + _Out_opt_ _Deref_post_z_ char** _EndPtr, + _In_ int _Radix + ); + +_Check_return_ +_ACRTIMP unsigned long __cdecl _strtoul_l( + _In_z_ char const* _String, + _Out_opt_ _Deref_post_z_ char** _EndPtr, + _In_ int _Radix, + _In_opt_ _locale_t _Locale + ); + +_Check_return_ +_ACRTIMP unsigned long long __cdecl strtoull( + _In_z_ char const* _String, + _Out_opt_ _Deref_post_z_ char** _EndPtr, + _In_ int _Radix + ); + +_Check_return_ +_ACRTIMP unsigned long long __cdecl _strtoull_l( + _In_z_ char const* _String, + _Out_opt_ _Deref_post_z_ char** _EndPtr, + _In_ int _Radix, + _In_opt_ _locale_t _Locale + ); + +_Check_return_ +_ACRTIMP __int64 __cdecl _strtoi64( + _In_z_ char const* _String, + _Out_opt_ _Deref_post_z_ char** _EndPtr, + _In_ int _Radix + ); + +_Check_return_ +_ACRTIMP __int64 __cdecl _strtoi64_l( + _In_z_ char const* _String, + _Out_opt_ _Deref_post_z_ char** _EndPtr, + _In_ int _Radix, + _In_opt_ _locale_t _Locale + ); + +_Check_return_ +_ACRTIMP unsigned __int64 __cdecl _strtoui64( + _In_z_ char const* _String, + _Out_opt_ _Deref_post_z_ char** _EndPtr, + _In_ int _Radix + ); + +_Check_return_ +_ACRTIMP unsigned __int64 __cdecl _strtoui64_l( + _In_z_ char const* _String, + _Out_opt_ _Deref_post_z_ char** _EndPtr, + _In_ int _Radix, + _In_opt_ _locale_t _Locale + ); + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Number to Narrow String Conversions +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +_Success_(return == 0) +_Check_return_opt_ +_ACRTIMP errno_t __cdecl _itoa_s( + _In_ int _Value, + _Out_writes_z_(_BufferCount) char* _Buffer, + _In_ size_t _BufferCount, + _In_ int _Radix + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_1_1( + _Success_(return == 0) + errno_t, _itoa_s, + _In_ int, _Value, + char, _Buffer, + _In_ int, _Radix + ) + +__DEFINE_CPP_OVERLOAD_STANDARD_FUNC_1_1( + char*, __RETURN_POLICY_DST, _ACRTIMP, _itoa, + _In_ int, _Value, + _Pre_notnull_ _Post_z_, char, _Buffer, + _In_ int, _Radix + ) + +_Success_(return == 0) +_Check_return_opt_ +_ACRTIMP errno_t __cdecl _ltoa_s( + _In_ long _Value, + _Out_writes_z_(_BufferCount) char* _Buffer, + _In_ size_t _BufferCount, + _In_ int _Radix + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_1_1( + errno_t, _ltoa_s, + _In_ long, _Value, + char, _Buffer, + _In_ int, _Radix + ) + +__DEFINE_CPP_OVERLOAD_STANDARD_FUNC_1_1( + char*, __RETURN_POLICY_DST, _ACRTIMP, _ltoa, + _In_ long, _Value, + _Pre_notnull_ _Post_z_, char, _Buffer, + _In_ int, _Radix + ) + +_Success_(return == 0) +_Check_return_opt_ +_ACRTIMP errno_t __cdecl _ultoa_s( + _In_ unsigned long _Value, + _Out_writes_z_(_BufferCount) char* _Buffer, + _In_ size_t _BufferCount, + _In_ int _Radix + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_1_1( + errno_t, _ultoa_s, + _In_ unsigned long, _Value, + char, _Buffer, + _In_ int, _Radix + ) + +__DEFINE_CPP_OVERLOAD_STANDARD_FUNC_1_1( + char*, __RETURN_POLICY_DST, _ACRTIMP, _ultoa, + _In_ unsigned long, _Value, + _Pre_notnull_ _Post_z_, char, _Buffer, + _In_ int, _Radix + ) + +_Success_(return == 0) +_Check_return_opt_ +_ACRTIMP errno_t __cdecl _i64toa_s( + _In_ __int64 _Value, + _Out_writes_z_(_BufferCount) char* _Buffer, + _In_ size_t _BufferCount, + _In_ int _Radix + ); + +_Success_(return == 0) +_CRT_INSECURE_DEPRECATE(_i64toa_s) +_ACRTIMP char* __cdecl _i64toa( + _In_ __int64 _Value, + _Pre_notnull_ _Post_z_ char* _Buffer, + _In_ int _Radix + ); + +_Success_(return == 0) +_Check_return_opt_ +_ACRTIMP errno_t __cdecl _ui64toa_s( + _In_ unsigned __int64 _Value, + _Out_writes_z_(_BufferCount) char* _Buffer, + _In_ size_t _BufferCount, + _In_ int _Radix + ); + +_CRT_INSECURE_DEPRECATE(_ui64toa_s) +_ACRTIMP char* __cdecl _ui64toa( + _In_ unsigned __int64 _Value, + _Pre_notnull_ _Post_z_ char* _Buffer, + _In_ int _Radix + ); + + + +// _CVTBUFSIZE is the maximum size for the per-thread conversion buffer. It +// should be at least as long as the number of digits in the largest double +// precision value (?.?e308 in IEEE arithmetic). We will use the same size +// buffer as is used in the printf support routines. +// +// (This value actually allows 40 additional decimal places; even though there +// are only 16 digits of accuracy in a double precision IEEE number, the user may +// ask for more to effect zero padding.) +#define _CVTBUFSIZE (309 + 40) // # of digits in max. dp value + slop + +_Success_(return == 0) +_Check_return_wat_ +_ACRTIMP errno_t __cdecl _ecvt_s( + _Out_writes_z_(_BufferCount) char* _Buffer, + _In_ size_t _BufferCount, + _In_ double _Value, + _In_ int _DigitCount, + _Out_ int* _PtDec, + _Out_ int* _PtSign + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_4( + errno_t, _ecvt_s, + char, _Buffer, + _In_ double, _Value, + _In_ int, _DigitCount, + _Out_ int*, _PtDec, + _Out_ int*, _PtSign + ) + +_Check_return_ _CRT_INSECURE_DEPRECATE(_ecvt_s) +_ACRTIMP char* __cdecl _ecvt( + _In_ double _Value, + _In_ int _DigitCount, + _Out_ int* _PtDec, + _Out_ int* _PtSign + ); + +_Success_(return == 0) +_Check_return_wat_ +_ACRTIMP errno_t __cdecl _fcvt_s( + _Out_writes_z_(_BufferCount) char* _Buffer, + _In_ size_t _BufferCount, + _In_ double _Value, + _In_ int _FractionalDigitCount, + _Out_ int* _PtDec, + _Out_ int* _PtSign + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_4( + _Success_(return == 0) + errno_t, _fcvt_s, + char, _Buffer, + _In_ double, _Value, + _In_ int, _FractionalDigitCount, + _Out_ int*, _PtDec, + _Out_ int*, _PtSign + ) + +_Success_(return == 0) +_Check_return_ _CRT_INSECURE_DEPRECATE(_fcvt_s) +_ACRTIMP char* __cdecl _fcvt( + _In_ double _Value, + _In_ int _FractionalDigitCount, + _Out_ int* _PtDec, + _Out_ int* _PtSign + ); + +_Success_(return == 0) +_ACRTIMP errno_t __cdecl _gcvt_s( + _Out_writes_z_(_BufferCount) char* _Buffer, + _In_ size_t _BufferCount, + _In_ double _Value, + _In_ int _DigitCount + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2( + _Success_(return == 0) + errno_t, _gcvt_s, + char, _Buffer, + _In_ double, _Value, + _In_ int, _DigitCount + ) + +_CRT_INSECURE_DEPRECATE(_gcvt_s) +_ACRTIMP char* __cdecl _gcvt( + _In_ double _Value, + _In_ int _DigitCount, + _Pre_notnull_ _Post_z_ char* _Buffer + ); + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Multibyte String Operations and Conversions +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// Maximum number of bytes in multi-byte character in the current locale +// (also defined in ctype.h). +#ifndef MB_CUR_MAX + #if defined _CRT_DISABLE_PERFCRIT_LOCKS && !defined _DLL + #define MB_CUR_MAX __mb_cur_max + #else + #define MB_CUR_MAX ___mb_cur_max_func() + #endif + + #ifdef _CRT_DECLARE_GLOBAL_VARIABLES_DIRECTLY + extern int __mb_cur_max; + #else + #define __mb_cur_max (___mb_cur_max_func()) + #endif + + _Post_satisfies_(return > 0 && return < MB_LEN_MAX) + _ACRTIMP int __cdecl ___mb_cur_max_func(void); + + _Post_satisfies_(return > 0 && return < MB_LEN_MAX) + _ACRTIMP int __cdecl ___mb_cur_max_l_func(_locale_t _Locale); +#endif + + + +_Check_return_ +_ACRTIMP int __cdecl mblen( + _In_reads_bytes_opt_(_MaxCount) _Pre_opt_z_ char const* _Ch, + _In_ size_t _MaxCount + ); + +_Check_return_ +_ACRTIMP int __cdecl _mblen_l( + _In_reads_bytes_opt_(_MaxCount) _Pre_opt_z_ char const* _Ch, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale + ); + +_Check_return_ +_Post_satisfies_(return <= _String_length_(_String)) +_ACRTIMP size_t __cdecl _mbstrlen( + _In_z_ char const* _String + ); + +_Check_return_ +_Post_satisfies_(return <= _String_length_(_String) || return == (size_t)-1) +_ACRTIMP size_t __cdecl _mbstrlen_l( + _In_z_ char const* _String, + _In_opt_ _locale_t _Locale + ); + +_Check_return_ +_Post_satisfies_((return <= _String_length_(_String) && return <= _MaxCount) || return == (size_t)-1) +_ACRTIMP size_t __cdecl _mbstrnlen( + _In_z_ char const* _String, + _In_ size_t _MaxCount + ); + +_Post_satisfies_((return <= _String_length_(_String) && return <= _MaxCount) || return == (size_t)-1) +_Check_return_ +_ACRTIMP size_t __cdecl _mbstrnlen_l( + _In_z_ char const* _String, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale + ); + +_Success_(return != -1) +_ACRTIMP int __cdecl mbtowc( + _Pre_notnull_ _Post_z_ wchar_t* _DstCh, + _In_reads_or_z_opt_(_SrcSizeInBytes) char const* _SrcCh, + _In_ size_t _SrcSizeInBytes + ); + +_Success_(return != -1) +_ACRTIMP int __cdecl _mbtowc_l( + _Pre_notnull_ _Post_z_ wchar_t* _DstCh, + _In_reads_or_z_opt_(_SrcSizeInBytes) char const* _SrcCh, + _In_ size_t _SrcSizeInBytes, + _In_opt_ _locale_t _Locale + ); + +_Check_return_opt_ +_ACRTIMP errno_t __cdecl mbstowcs_s( + _Out_opt_ size_t* _PtNumOfCharConverted, + _Out_writes_to_opt_(_SizeInWords, *_PtNumOfCharConverted) wchar_t* _DstBuf, + _In_ size_t _SizeInWords, + _In_reads_or_z_(_MaxCount) char const* _SrcBuf, + _In_ size_t _MaxCount + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_1_2( + errno_t, mbstowcs_s, + _Out_opt_ size_t*, _PtNumOfCharConverted, + _Post_z_ wchar_t, _Dest, + _In_z_ char const*, _Source, + _In_ size_t, _MaxCount + ) + +__DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2_SIZE( + _ACRTIMP, mbstowcs, + _Out_writes_opt_z_(_MaxCount), wchar_t, _Dest, + _In_z_ char const*, _Source, + _In_ size_t, _MaxCount + ) + +_Check_return_opt_ +_ACRTIMP errno_t __cdecl _mbstowcs_s_l( + _Out_opt_ size_t* _PtNumOfCharConverted, + _Out_writes_to_opt_(_SizeInWords, *_PtNumOfCharConverted) wchar_t* _DstBuf, + _In_ size_t _SizeInWords, + _In_reads_or_z_(_MaxCount) char const* _SrcBuf, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_1_3( + errno_t, _mbstowcs_s_l, + _Out_opt_ size_t*, _PtNumOfCharConverted, + _Post_z_ wchar_t, _Dest, + _In_z_ char const*, _Source, + _In_ size_t, _MaxCount, + _In_opt_ _locale_t, _Locale + ) + +__DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_3_SIZE_EX( + _ACRTIMP, _mbstowcs_l, _mbstowcs_s_l, + _Out_writes_opt_z_(_Size) wchar_t, + _Out_writes_z_(_MaxCount), wchar_t, _Dest, + _In_z_ char const*, _Source, + _In_ size_t, _MaxCount, + _In_opt_ _locale_t, _Locale + ) + + + + +_CRT_INSECURE_DEPRECATE(wctomb_s) +_ACRTIMP int __cdecl wctomb( + _Out_writes_opt_z_(MB_LEN_MAX) char* _MbCh, + _In_ wchar_t _WCh + ); + +_CRT_INSECURE_DEPRECATE(_wctomb_s_l) +_ACRTIMP int __cdecl _wctomb_l( + _Pre_maybenull_ _Post_z_ char* _MbCh, + _In_ wchar_t _WCh, + _In_opt_ _locale_t _Locale + ); + +#if __STDC_WANT_SECURE_LIB__ + + _Check_return_wat_ + _ACRTIMP errno_t __cdecl wctomb_s( + _Out_opt_ int* _SizeConverted, + _Out_writes_bytes_to_opt_(_SizeInBytes, *_SizeConverted) char* _MbCh, + _In_ rsize_t _SizeInBytes, + _In_ wchar_t _WCh + ); + +#endif // __STDC_WANT_SECURE_LIB__ + +_Check_return_wat_ +_ACRTIMP errno_t __cdecl _wctomb_s_l( + _Out_opt_ int* _SizeConverted, + _Out_writes_opt_z_(_SizeInBytes) char* _MbCh, + _In_ size_t _SizeInBytes, + _In_ wchar_t _WCh, + _In_opt_ _locale_t _Locale); + +_Check_return_wat_ +_ACRTIMP errno_t __cdecl wcstombs_s( + _Out_opt_ size_t* _PtNumOfCharConverted, + _Out_writes_bytes_to_opt_(_DstSizeInBytes, *_PtNumOfCharConverted) char* _Dst, + _In_ size_t _DstSizeInBytes, + _In_z_ wchar_t const* _Src, + _In_ size_t _MaxCountInBytes + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_1_2( + errno_t, wcstombs_s, + _Out_opt_ size_t*, _PtNumOfCharConverted, + _Out_writes_bytes_opt_(_Size) char, _Dest, + _In_z_ wchar_t const*, _Source, + _In_ size_t, _MaxCount + ) + +__DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2_SIZE( + _ACRTIMP, wcstombs, + _Out_writes_opt_(_MaxCount), char, _Dest, + _In_z_ wchar_t const*, _Source, + _In_ size_t, _MaxCount + ) + +_Check_return_wat_ +_ACRTIMP errno_t __cdecl _wcstombs_s_l( + _Out_opt_ size_t* _PtNumOfCharConverted, + _Out_writes_bytes_to_opt_(_DstSizeInBytes, *_PtNumOfCharConverted) char* _Dst, + _In_ size_t _DstSizeInBytes, + _In_z_ wchar_t const* _Src, + _In_ size_t _MaxCountInBytes, + _In_opt_ _locale_t _Locale + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_1_3( + errno_t, _wcstombs_s_l, + _Out_opt_ size_t*, _PtNumOfCharConverted, + _Out_writes_opt_(_Size) char, _Dest, + _In_z_ wchar_t const*, _Source, + _In_ size_t, _MaxCount, + _In_opt_ _locale_t, _Locale + ) + +__DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_3_SIZE_EX( + _ACRTIMP, _wcstombs_l, _wcstombs_s_l, + _Out_writes_opt_z_(_Size) char, + _Out_writes_(_MaxCount), char, _Dest, + _In_z_ wchar_t const*, _Source, + _In_ size_t, _MaxCount, + _In_opt_ _locale_t, _Locale + ) + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Path Manipulation +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// Sizes for buffers used by the _makepath() and _splitpath() functions. +// note that the sizes include space for 0-terminator +#define _MAX_PATH 260 // max. length of full pathname +#define _MAX_DRIVE 3 // max. length of drive component +#define _MAX_DIR 256 // max. length of path component +#define _MAX_FNAME 256 // max. length of file name component +#define _MAX_EXT 256 // max. length of extension component + + +#pragma push_macro("_fullpath") +#undef _fullpath + +_Success_(return != 0) +_Check_return_ +_ACRTIMP _CRTALLOCATOR char* __cdecl _fullpath( + _Out_writes_opt_z_(_BufferCount) char* _Buffer, + _In_z_ char const* _Path, + _In_ size_t _BufferCount + ); + +#pragma pop_macro("_fullpath") + +_Check_return_wat_ +_ACRTIMP errno_t __cdecl _makepath_s( + _Out_writes_z_(_BufferCount) char* _Buffer, + _In_ size_t _BufferCount, + _In_opt_z_ char const* _Drive, + _In_opt_z_ char const* _Dir, + _In_opt_z_ char const* _Filename, + _In_opt_z_ char const* _Ext + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_4( + errno_t, _makepath_s, + char, _Buffer, + _In_opt_z_ char const*, _Drive, + _In_opt_z_ char const*, _Dir, + _In_opt_z_ char const*, _Filename, + _In_opt_z_ char const*, _Ext + ) + +__DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_4( + void, __RETURN_POLICY_VOID, _ACRTIMP, _makepath, + _Pre_notnull_ _Post_z_, char, _Buffer, + _In_opt_z_ char const*, _Drive, + _In_opt_z_ char const*, _Dir, + _In_opt_z_ char const*, _Filename, + _In_opt_z_ char const*, _Ext + ) + +_CRT_INSECURE_DEPRECATE(_splitpath_s) +_ACRTIMP void __cdecl _splitpath( + _In_z_ char const* _FullPath, + _Pre_maybenull_ _Post_z_ char* _Drive, + _Pre_maybenull_ _Post_z_ char* _Dir, + _Pre_maybenull_ _Post_z_ char* _Filename, + _Pre_maybenull_ _Post_z_ char* _Ext + ); + +_Check_return_wat_ +_ACRTIMP errno_t __cdecl _splitpath_s( + _In_z_ char const* _FullPath, + _Out_writes_opt_z_(_DriveCount) char* _Drive, + _In_ size_t _DriveCount, + _Out_writes_opt_z_(_DirCount) char* _Dir, + _In_ size_t _DirCount, + _Out_writes_opt_z_(_FilenameCount) char* _Filename, + _In_ size_t _FilenameCount, + _Out_writes_opt_z_(_ExtCount) char* _Ext, + _In_ size_t _ExtCount + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_SPLITPATH(errno_t, _splitpath_s, char, _Dest) + +#if __STDC_WANT_SECURE_LIB__ + +_Check_return_opt_ +_Success_(return == 0) +_DCRTIMP errno_t __cdecl getenv_s( + _Out_ size_t* _RequiredCount, + _Out_writes_opt_z_(_BufferCount) char* _Buffer, + _In_ rsize_t _BufferCount, + _In_z_ char const* _VarName + ); + +#endif // __STDC_WANT_SECURE_LIB__ + + + + +_ACRTIMP int* __cdecl __p___argc (void); +_ACRTIMP char*** __cdecl __p___argv (void); +_ACRTIMP wchar_t*** __cdecl __p___wargv(void); + +#ifdef _CRT_DECLARE_GLOBAL_VARIABLES_DIRECTLY + extern int __argc; + extern char** __argv; + extern wchar_t** __wargv; +#else + #define __argc (*__p___argc()) // Pointer to number of command line arguments + #define __argv (*__p___argv()) // Pointer to table of narrow command line arguments + #define __wargv (*__p___wargv()) // Pointer to table of wide command line arguments +#endif + +_DCRTIMP char*** __cdecl __p__environ (void); +_DCRTIMP wchar_t*** __cdecl __p__wenviron(void); + +#ifndef _CRT_BEST_PRACTICES_USAGE + #define _CRT_V12_LEGACY_FUNCTIONALITY +#endif + +#ifndef _CRT_V12_LEGACY_FUNCTIONALITY + // Deprecated symbol: Do not expose environment global pointers unless + // legacy access is specifically requested + #define _environ crt_usage_error__do_not_reference_global_pointer_directly__environ + #define _wenviron crt_usage_error__do_not_reference_global_pointer_directly__wenviron +#else + #define _environ (*__p__environ()) // Pointer to narrow environment table + #define _wenviron (*__p__wenviron()) // Pointer to wide environment table +#endif + + + +// Sizes for buffers used by the getenv/putenv family of functions. +#define _MAX_ENV 32767 + + +#if _CRT_FUNCTIONS_REQUIRED + + _Check_return_ _CRT_INSECURE_DEPRECATE(_dupenv_s) + _DCRTIMP char* __cdecl getenv( + _In_z_ char const* _VarName + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_1_1( + errno_t, getenv_s, + _Out_ size_t*, _RequiredCount, + char, _Buffer, + _In_z_ char const*, _VarName + ) + + #if defined(_DEBUG) && defined(_CRTDBG_MAP_ALLOC) + #pragma push_macro("_dupenv_s") + #undef _dupenv_s + #endif + + _Check_return_opt_ + _DCRTIMP errno_t __cdecl _dupenv_s( + _Outptr_result_buffer_maybenull_(*_BufferCount) _Outptr_result_maybenull_z_ char** _Buffer, + _Out_opt_ size_t* _BufferCount, + _In_z_ char const* _VarName + ); + + #if defined(_DEBUG) && defined(_CRTDBG_MAP_ALLOC) + #pragma pop_macro("_dupenv_s") + #endif + + _DCRTIMP int __cdecl system( + _In_opt_z_ char const* _Command + ); + + // The functions below have declspecs in their declarations in the Windows + // headers, causing PREfast to fire 6540 here + #pragma warning(push) + #pragma warning(disable: 6540) + + _Check_return_ + _DCRTIMP int __cdecl _putenv( + _In_z_ char const* _EnvString + ); + + _Check_return_wat_ + _DCRTIMP errno_t __cdecl _putenv_s( + _In_z_ char const* _Name, + _In_z_ char const* _Value + ); + + #pragma warning(pop) + + _DCRTIMP errno_t __cdecl _searchenv_s( + _In_z_ char const* _Filename, + _In_z_ char const* _VarName, + _Out_writes_z_(_BufferCount) char* _Buffer, + _In_ size_t _BufferCount + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_2_0( + errno_t, _searchenv_s, + _In_z_ char const*, _Filename, + _In_z_ char const*, _VarName, + char, _Buffer + ) + + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_2_0( + void, __RETURN_POLICY_VOID, _DCRTIMP, _searchenv, + _In_z_ char const*, _Filename, + _In_z_ char const*, _VarName, + _Pre_notnull_ _Post_z_, char, _Buffer + ) + + // The Win32 API SetErrorMode, Beep and Sleep should be used instead. + _CRT_OBSOLETE(SetErrorMode) + _DCRTIMP void __cdecl _seterrormode( + _In_ int _Mode + ); + + _CRT_OBSOLETE(Beep) + _DCRTIMP void __cdecl _beep( + _In_ unsigned _Frequency, + _In_ unsigned _Duration + ); + + _CRT_OBSOLETE(Sleep) + _DCRTIMP void __cdecl _sleep( + _In_ unsigned long _Duration + ); + +#endif // _CRT_FUNCTIONS_REQUIRED + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Non-ANSI Names for Compatibility +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#if defined(_CRT_INTERNAL_NONSTDC_NAMES) && _CRT_INTERNAL_NONSTDC_NAMES + + #ifndef __cplusplus + #define max(a,b) (((a) > (b)) ? (a) : (b)) + #define min(a,b) (((a) < (b)) ? (a) : (b)) + #endif + + #define sys_errlist _sys_errlist + #define sys_nerr _sys_nerr + + #pragma warning(push) + #pragma warning(disable: 4141) // Using deprecated twice + + _Check_return_ _CRT_NONSTDC_DEPRECATE(_ecvt) _CRT_INSECURE_DEPRECATE(_ecvt_s) + _ACRTIMP char* __cdecl ecvt( + _In_ double _Value, + _In_ int _DigitCount, + _Out_ int* _PtDec, + _Out_ int* _PtSign + ); + + _Check_return_ _CRT_NONSTDC_DEPRECATE(_fcvt) _CRT_INSECURE_DEPRECATE(_fcvt_s) + _ACRTIMP char* __cdecl fcvt( + _In_ double _Value, + _In_ int _FractionalDigitCount, + _Out_ int* _PtDec, + _Out_ int* _PtSign + ); + + _CRT_NONSTDC_DEPRECATE(_gcvt) _CRT_INSECURE_DEPRECATE(_fcvt_s) + _ACRTIMP char* __cdecl gcvt( + _In_ double _Value, + _In_ int _DigitCount, + _Pre_notnull_ _Post_z_ char* _DstBuf + ); + + _CRT_NONSTDC_DEPRECATE(_itoa) _CRT_INSECURE_DEPRECATE(_itoa_s) + _ACRTIMP char* __cdecl itoa( + _In_ int _Value, + _Pre_notnull_ _Post_z_ char* _Buffer, + _In_ int _Radix + ); + + _CRT_NONSTDC_DEPRECATE(_ltoa) _CRT_INSECURE_DEPRECATE(_ltoa_s) + _ACRTIMP char* __cdecl ltoa( + _In_ long _Value, + _Pre_notnull_ _Post_z_ char* _Buffer, + _In_ int _Radix + ); + + + _CRT_NONSTDC_DEPRECATE(_swab) + _ACRTIMP void __cdecl swab( + _Inout_updates_z_(_SizeInBytes) char* _Buf1, + _Inout_updates_z_(_SizeInBytes) char* _Buf2, + _In_ int _SizeInBytes + ); + + _CRT_NONSTDC_DEPRECATE(_ultoa) _CRT_INSECURE_DEPRECATE(_ultoa_s) + _ACRTIMP char* __cdecl ultoa( + _In_ unsigned long _Value, + _Pre_notnull_ _Post_z_ char* _Buffer, + _In_ int _Radix + ); + + #define environ _environ + + _Check_return_ _CRT_NONSTDC_DEPRECATE(_putenv) + _DCRTIMP int __cdecl putenv( + _In_z_ char const* _EnvString + ); + + #pragma warning(pop) + + onexit_t __cdecl onexit(_In_opt_ onexit_t _Func); + +#endif // _CRT_INTERNAL_NONSTDC_NAMES + + + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS +#endif // _INC_STDLIB diff --git a/sdk/include/ucrt/stdnoreturn.h b/sdk/include/ucrt/stdnoreturn.h new file mode 100644 index 0000000000000..c9bd87df4eab4 --- /dev/null +++ b/sdk/include/ucrt/stdnoreturn.h @@ -0,0 +1,28 @@ +// +// stdnoreturn.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The C Standard Library header. +// +#pragma once +#ifndef _INC_STDNORETURN // include guard for 3rd party interop +#define _INC_STDNORETURN + +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS +_CRT_BEGIN_C_HEADER + +#if _CRT_HAS_C11 + +#define noreturn _Noreturn + +#endif // _CRT_HAS_C11 + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS +#endif // _INC_STDNORETURN diff --git a/sdk/include/ucrt/string.h b/sdk/include/ucrt/string.h new file mode 100644 index 0000000000000..37406d48e2e35 --- /dev/null +++ b/sdk/include/ucrt/string.h @@ -0,0 +1,592 @@ +// +// string.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The C Standard Library header. +// +#pragma once +#ifndef _INC_STRING // include guard for 3rd party interop +#define _INC_STRING + +#include +#include +#include +#include + +#ifndef __midl + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + + + +#define _NLSCMPERROR _CRT_INT_MAX // currently == INT_MAX + +#if __STDC_WANT_SECURE_LIB__ + + _Check_return_wat_ + _ACRTIMP errno_t __cdecl strcpy_s( + _Out_writes_z_(_SizeInBytes) char* _Destination, + _In_ rsize_t _SizeInBytes, + _In_z_ char const* _Source + ); + + _Check_return_wat_ + _ACRTIMP errno_t __cdecl strcat_s( + _Inout_updates_z_(_SizeInBytes) char* _Destination, + _In_ rsize_t _SizeInBytes, + _In_z_ char const* _Source + ); + + _Check_return_wat_ + _ACRTIMP errno_t __cdecl strerror_s( + _Out_writes_z_(_SizeInBytes) char* _Buffer, + _In_ size_t _SizeInBytes, + _In_ int _ErrorNumber); + + _Check_return_wat_ + _ACRTIMP errno_t __cdecl strncat_s( + _Inout_updates_z_(_SizeInBytes) char* _Destination, + _In_ rsize_t _SizeInBytes, + _In_reads_or_z_(_MaxCount) char const* _Source, + _In_ rsize_t _MaxCount + ); + + _Check_return_wat_ + _ACRTIMP errno_t __cdecl strncpy_s( + _Out_writes_z_(_SizeInBytes) char* _Destination, + _In_ rsize_t _SizeInBytes, + _In_reads_or_z_(_MaxCount) char const* _Source, + _In_ rsize_t _MaxCount + ); + + _Check_return_ + _ACRTIMP char* __cdecl strtok_s( + _Inout_opt_z_ char* _String, + _In_z_ char const* _Delimiter, + _Inout_ _Deref_prepost_opt_z_ char** _Context + ); + +#endif // __STDC_WANT_SECURE_LIB__ + +_ACRTIMP void* __cdecl _memccpy( + _Out_writes_bytes_opt_(_MaxCount) void* _Dst, + _In_ void const* _Src, + _In_ int _Val, + _In_ size_t _MaxCount + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1( + errno_t, strcat_s, + char, _Destination, + _In_z_ char const*, _Source + ) + +#ifndef RC_INVOKED + + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1( + char*, __RETURN_POLICY_DST, __EMPTY_DECLSPEC, strcat, + _Inout_updates_z_(_String_length_(_Destination) + _String_length_(_Source) + 1), char, _Destination, + _In_z_ char const*, _Source + ) + +#endif // RC_INVOKED + +_Check_return_ +int __cdecl strcmp( + _In_z_ char const* _Str1, + _In_z_ char const* _Str2 + ); + +_Check_return_ +_ACRTIMP int __cdecl _strcmpi( + _In_z_ char const* _String1, + _In_z_ char const* _String2 + ); + +_Check_return_ +_ACRTIMP int __cdecl strcoll( + _In_z_ char const* _String1, + _In_z_ char const* _String2 + ); + +_Check_return_ +_ACRTIMP int __cdecl _strcoll_l( + _In_z_ char const* _String1, + _In_z_ char const* _String2, + _In_opt_ _locale_t _Locale + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1( + errno_t, strcpy_s, + _Post_z_ char, _Destination, + _In_z_ char const*, _Source + ) + +__DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1( + char*, __RETURN_POLICY_DST, __EMPTY_DECLSPEC, strcpy, + _Out_writes_z_(_String_length_(_Source) + 1), char, _Destination, + _In_z_ char const*, _Source + ) + +_Check_return_ +_ACRTIMP size_t __cdecl strcspn( + _In_z_ char const* _Str, + _In_z_ char const* _Control + ); + +#if defined _DEBUG && defined _CRTDBG_MAP_ALLOC + #pragma push_macro("_strdup") + #undef _strdup +#endif + +_Check_return_ +_ACRTIMP _CRTALLOCATOR char* __cdecl _strdup( + _In_opt_z_ char const* _Source + ); + +#if defined _DEBUG && defined _CRTDBG_MAP_ALLOC + #pragma pop_macro("_strdup") +#endif + +_Ret_z_ +_Success_(return != 0) +_Check_return_ _CRT_INSECURE_DEPRECATE(_strerror_s) +_ACRTIMP char* __cdecl _strerror( + _In_opt_z_ char const* _ErrorMessage + ); + +_Check_return_wat_ +_ACRTIMP errno_t __cdecl _strerror_s( + _Out_writes_z_(_SizeInBytes) char* _Buffer, + _In_ size_t _SizeInBytes, + _In_opt_z_ char const* _ErrorMessage + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1( + errno_t, _strerror_s, + char, _Buffer, + _In_opt_z_ char const*, _ErrorMessage + ) + +_Ret_z_ +_Check_return_ _CRT_INSECURE_DEPRECATE(strerror_s) +_ACRTIMP char* __cdecl strerror( + _In_ int _ErrorMessage + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1( + errno_t, strerror_s, + char, _Buffer, + _In_ int, _ErrorMessage + ) + +_Check_return_ +_ACRTIMP int __cdecl _stricmp( + _In_z_ char const* _String1, + _In_z_ char const* _String2 + ); + +_Check_return_ +_ACRTIMP int __cdecl _stricoll( + _In_z_ char const* _String1, + _In_z_ char const* _String2 + ); + +_Check_return_ +_ACRTIMP int __cdecl _stricoll_l( + _In_z_ char const* _String1, + _In_z_ char const* _String2, + _In_opt_ _locale_t _Locale + ); + +_Check_return_ +_ACRTIMP int __cdecl _stricmp_l( + _In_z_ char const* _String1, + _In_z_ char const* _String2, + _In_opt_ _locale_t _Locale + ); + +_Check_return_ +size_t __cdecl strlen( + _In_z_ char const* _Str + ); + +_Check_return_wat_ +_ACRTIMP errno_t __cdecl _strlwr_s( + _Inout_updates_z_(_Size) char* _String, + _In_ size_t _Size + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_0( + errno_t, _strlwr_s, + _Prepost_z_ char, _String + ) + +__DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_0( + char*, __RETURN_POLICY_DST, _ACRTIMP, _strlwr, + _Inout_z_, char, _String + ) + +_Check_return_wat_ +_ACRTIMP errno_t __cdecl _strlwr_s_l( + _Inout_updates_z_(_Size) char* _String, + _In_ size_t _Size, + _In_opt_ _locale_t _Locale + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1( + errno_t, _strlwr_s_l, + _Prepost_z_ char, _String, + _In_opt_ _locale_t, _Locale + ) + +__DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1_EX( + char*, __RETURN_POLICY_DST, _ACRTIMP, _strlwr_l, _strlwr_s_l, + _Inout_updates_z_(_Size) char, + _Inout_z_, char, _String, + _In_opt_ _locale_t, _Locale + ) + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2( + errno_t, strncat_s, + _Prepost_z_ char, _Destination, + _In_reads_or_z_(_Count) char const*, _Source, + _In_ size_t, _Count + ) + +__DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2_EX( + char*, __RETURN_POLICY_DST, _ACRTIMP, strncat, strncat_s, + _Inout_updates_z_(_Size) char, + _Inout_updates_z_(_Count), char, _Destination, + _In_reads_or_z_(_Count) char const*, _Source, + _In_ size_t, _Count + ) + +_Check_return_ +_ACRTIMP int __cdecl strncmp( + _In_reads_or_z_(_MaxCount) char const* _Str1, + _In_reads_or_z_(_MaxCount) char const* _Str2, + _In_ size_t _MaxCount + ); + +_Check_return_ +_ACRTIMP int __cdecl _strnicmp( + _In_reads_or_z_(_MaxCount) char const* _String1, + _In_reads_or_z_(_MaxCount) char const* _String2, + _In_ size_t _MaxCount + ); + +_Check_return_ +_ACRTIMP int __cdecl _strnicmp_l( + _In_reads_or_z_(_MaxCount) char const* _String1, + _In_reads_or_z_(_MaxCount) char const* _String2, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale + ); + +_Check_return_ +_ACRTIMP int __cdecl _strnicoll( + _In_reads_or_z_(_MaxCount) char const* _String1, + _In_reads_or_z_(_MaxCount) char const* _String2, + _In_ size_t _MaxCount + ); + +_Check_return_ +_ACRTIMP int __cdecl _strnicoll_l( + _In_reads_or_z_(_MaxCount) char const* _String1, + _In_reads_or_z_(_MaxCount) char const* _String2, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale + ); + +_Check_return_ +_ACRTIMP int __cdecl _strncoll( + _In_reads_or_z_(_MaxCount) char const* _String1, + _In_reads_or_z_(_MaxCount) char const* _String2, + _In_ size_t _MaxCount + ); + +_Check_return_ +_ACRTIMP int __cdecl _strncoll_l( + _In_reads_or_z_(_MaxCount) char const* _String1, + _In_reads_or_z_(_MaxCount) char const* _String2, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale + ); + +_ACRTIMP size_t __cdecl __strncnt( + _In_reads_or_z_(_Count) char const* _String, + _In_ size_t _Count + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2( + errno_t, strncpy_s, + char, _Destination, + _In_reads_or_z_(_Count) char const*, _Source, + _In_ size_t, _Count + ) + +__DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2_EX( + char*, __RETURN_POLICY_DST, _ACRTIMP, strncpy, strncpy_s, + _Out_writes_z_(_Size) char, + _Out_writes_(_Count) _Post_maybez_, char, _Destination, + _In_reads_or_z_(_Count) char const*, _Source, + _In_ size_t, _Count + ) + +_Check_return_ +_When_( + _MaxCount > _String_length_(_String), + _Post_satisfies_(return == _String_length_(_String)) +) +_When_( + _MaxCount <= _String_length_(_String), + _Post_satisfies_(return == _MaxCount) +) +_ACRTIMP size_t __cdecl strnlen( + _In_reads_or_z_(_MaxCount) char const* _String, + _In_ size_t _MaxCount + ); + +#if __STDC_WANT_SECURE_LIB__ && !defined __midl + + _Check_return_ + _When_( + _MaxCount > _String_length_(_String), + _Post_satisfies_(return == _String_length_(_String)) + ) + _When_( + _MaxCount <= _String_length_(_String), + _Post_satisfies_(return == _MaxCount) + ) + static __inline size_t __CRTDECL strnlen_s( + _In_reads_or_z_(_MaxCount) char const* _String, + _In_ size_t _MaxCount + ) + { + return _String == 0 ? 0 : strnlen(_String, _MaxCount); + } + +#endif + +_Check_return_wat_ +_ACRTIMP errno_t __cdecl _strnset_s( + _Inout_updates_z_(_SizeInBytes) char* _String, + _In_ size_t _SizeInBytes, + _In_ int _Value, + _In_ size_t _MaxCount + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2( + errno_t, _strnset_s, + _Prepost_z_ char, _Destination, + _In_ int, _Value, + _In_ size_t, _Count + ) + +__DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2_EX( + char*, __RETURN_POLICY_DST, _ACRTIMP, _strnset, _strnset_s, + _Inout_updates_z_(_Size) char, + _Inout_updates_z_(_Count), char, _Destination, + _In_ int, _Value, + _In_ size_t, _Count + ) + +_Check_return_ +_ACRTIMP char _CONST_RETURN* __cdecl strpbrk( + _In_z_ char const* _Str, + _In_z_ char const* _Control + ); + +_ACRTIMP char* __cdecl _strrev( + _Inout_z_ char* _Str + ); + +_Check_return_wat_ +_ACRTIMP errno_t __cdecl _strset_s( + _Inout_updates_z_(_DestinationSize) char* _Destination, + _In_ size_t _DestinationSize, + _In_ int _Value + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1( + errno_t, _strset_s, + _Prepost_z_ char, _Destination, + _In_ int, _Value + ) + +__DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1( + char*, __RETURN_POLICY_DST, __EMPTY_DECLSPEC, _strset, + _Inout_z_, char, _Destination, + _In_ int, _Value + ) + +_Check_return_ +_ACRTIMP size_t __cdecl strspn( + _In_z_ char const* _Str, + _In_z_ char const* _Control + ); + +_Check_return_ _CRT_INSECURE_DEPRECATE(strtok_s) +_ACRTIMP char* __cdecl strtok( + _Inout_opt_z_ char* _String, + _In_z_ char const* _Delimiter + ); + +_Check_return_wat_ +_ACRTIMP errno_t __cdecl _strupr_s( + _Inout_updates_z_(_Size) char* _String, + _In_ size_t _Size + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_0( + errno_t, _strupr_s, + _Prepost_z_ char, _String + ) + +__DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_0( + char*, __RETURN_POLICY_DST, _ACRTIMP, _strupr, + _Inout_z_, char, _String + ) + +_Check_return_wat_ +_ACRTIMP errno_t __cdecl _strupr_s_l( + _Inout_updates_z_(_Size) char* _String, + _In_ size_t _Size, + _In_opt_ _locale_t _Locale + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1( + errno_t, _strupr_s_l, + _Prepost_z_ char, _String, + _In_opt_ _locale_t, _Locale + ) + +__DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1_EX( + char*, __RETURN_POLICY_DST, _ACRTIMP, _strupr_l, _strupr_s_l, + _Inout_updates_z_(_Size) char, + _Inout_z_, char, _String, + _In_opt_ _locale_t, _Locale + ) + +_Success_(return < _MaxCount) +_Check_return_opt_ +_ACRTIMP size_t __cdecl strxfrm( + _Out_writes_opt_(_MaxCount) _Post_maybez_ char* _Destination, + _In_z_ char const* _Source, + _In_ _In_range_(<=,_CRT_INT_MAX) size_t _MaxCount + ); + +_Success_(return < _MaxCount) +_Check_return_opt_ +_ACRTIMP size_t __cdecl _strxfrm_l( + _Out_writes_opt_(_MaxCount) _Post_maybez_ char* _Destination, + _In_z_ char const* _Source, + _In_ _In_range_(<=,_CRT_INT_MAX) size_t _MaxCount, + _In_opt_ _locale_t _Locale + ); + + + +#ifdef __cplusplus +extern "C++" +{ + _Check_return_ + inline char* __CRTDECL strchr(_In_z_ char* const _String, _In_ int const _Ch) + { + return const_cast(strchr(static_cast(_String), _Ch)); + } + + _Check_return_ + inline char* __CRTDECL strpbrk(_In_z_ char* const _String, _In_z_ char const* const _Control) + { + return const_cast(strpbrk(static_cast(_String), _Control)); + } + + _Check_return_ + inline char* __CRTDECL strrchr(_In_z_ char* const _String, _In_ int const _Ch) + { + return const_cast(strrchr(static_cast(_String), _Ch)); + } + + _Check_return_ _Ret_maybenull_ + inline char* __CRTDECL strstr(_In_z_ char* const _String, _In_z_ char const* const _SubString) + { + return const_cast(strstr(static_cast(_String), _SubString)); + } +} +#endif // __cplusplus + + + +#if defined(_CRT_INTERNAL_NONSTDC_NAMES) && _CRT_INTERNAL_NONSTDC_NAMES + + #pragma push_macro("strdup") + #undef strdup + _Check_return_ _CRT_NONSTDC_DEPRECATE(_strdup) + _ACRTIMP char* __cdecl strdup( + _In_opt_z_ char const* _String + ); + #pragma pop_macro("strdup") + + // Declarations of functions defined in oldnames.lib: + _Check_return_ _CRT_NONSTDC_DEPRECATE(_strcmpi) + _ACRTIMP int __cdecl strcmpi( + _In_z_ char const* _String1, + _In_z_ char const* _String2 + ); + + _Check_return_ _CRT_NONSTDC_DEPRECATE(_stricmp) + _ACRTIMP int __cdecl stricmp( + _In_z_ char const* _String1, + _In_z_ char const* _String2 + ); + + _CRT_NONSTDC_DEPRECATE(_strlwr) + _ACRTIMP char* __cdecl strlwr( + _Inout_z_ char* _String + ); + + _Check_return_ _CRT_NONSTDC_DEPRECATE(_strnicmp) + _ACRTIMP int __cdecl strnicmp( + _In_reads_or_z_(_MaxCount) char const* _String1, + _In_reads_or_z_(_MaxCount) char const* _String2, + _In_ size_t _MaxCount + ); + + _CRT_NONSTDC_DEPRECATE(_strnset) + _ACRTIMP char* __cdecl strnset( + _Inout_updates_z_(_MaxCount) char* _String, + _In_ int _Value, + _In_ size_t _MaxCount + ); + + _CRT_NONSTDC_DEPRECATE(_strrev) + _ACRTIMP char* __cdecl strrev( + _Inout_z_ char* _String + ); + + _CRT_NONSTDC_DEPRECATE(_strset) + char* __cdecl strset( + _Inout_z_ char* _String, + _In_ int _Value); + + _CRT_NONSTDC_DEPRECATE(_strupr) + _ACRTIMP char* __cdecl strupr( + _Inout_z_ char* _String + ); + +#endif // _CRT_INTERNAL_NONSTDC_NAMES + + + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS +#endif // !__midl +#endif // _INC_STRING diff --git a/sdk/include/ucrt/sys/locking.h b/sdk/include/ucrt/sys/locking.h new file mode 100644 index 0000000000000..5bb8d34758a8b --- /dev/null +++ b/sdk/include/ucrt/sys/locking.h @@ -0,0 +1,31 @@ +// +// sys/locking.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// This file defines the flags for the locking() function. +// +#pragma once + +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +#define _LK_UNLCK 0 // unlock the file region +#define _LK_LOCK 1 // lock the file region +#define _LK_NBLCK 2 // non-blocking lock +#define _LK_RLCK 3 // lock for writing +#define _LK_NBRLCK 4 // non-blocking lock for writing + +#if (defined _CRT_DECLARE_NONSTDC_NAMES && _CRT_DECLARE_NONSTDC_NAMES) || (!defined _CRT_DECLARE_NONSTDC_NAMES && !__STDC__) + #define LK_UNLCK _LK_UNLCK + #define LK_LOCK _LK_LOCK + #define LK_NBLCK _LK_NBLCK + #define LK_RLCK _LK_RLCK + #define LK_NBRLCK _LK_NBRLCK +#endif + +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS diff --git a/sdk/include/ucrt/sys/stat.h b/sdk/include/ucrt/sys/stat.h new file mode 100644 index 0000000000000..5bce53a349766 --- /dev/null +++ b/sdk/include/ucrt/sys/stat.h @@ -0,0 +1,249 @@ +// +// sys/stat.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The _stat() and _fstat() families of functions. +// +#pragma once + +#include +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Types +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +struct _stat32 +{ + _dev_t st_dev; + _ino_t st_ino; + unsigned short st_mode; + short st_nlink; + short st_uid; + short st_gid; + _dev_t st_rdev; + _off_t st_size; + __time32_t st_atime; + __time32_t st_mtime; + __time32_t st_ctime; +}; + +struct _stat32i64 +{ + _dev_t st_dev; + _ino_t st_ino; + unsigned short st_mode; + short st_nlink; + short st_uid; + short st_gid; + _dev_t st_rdev; + __int64 st_size; + __time32_t st_atime; + __time32_t st_mtime; + __time32_t st_ctime; +}; + +struct _stat64i32 +{ + _dev_t st_dev; + _ino_t st_ino; + unsigned short st_mode; + short st_nlink; + short st_uid; + short st_gid; + _dev_t st_rdev; + _off_t st_size; + __time64_t st_atime; + __time64_t st_mtime; + __time64_t st_ctime; +}; + +struct _stat64 +{ + _dev_t st_dev; + _ino_t st_ino; + unsigned short st_mode; + short st_nlink; + short st_uid; + short st_gid; + _dev_t st_rdev; + __int64 st_size; + __time64_t st_atime; + __time64_t st_mtime; + __time64_t st_ctime; +}; + +#define __stat64 _stat64 // For legacy compatibility + +#if defined(_CRT_INTERNAL_NONSTDC_NAMES) && _CRT_INTERNAL_NONSTDC_NAMES && !defined _CRT_NO_TIME_T + struct stat + { + _dev_t st_dev; + _ino_t st_ino; + unsigned short st_mode; + short st_nlink; + short st_uid; + short st_gid; + _dev_t st_rdev; + _off_t st_size; + time_t st_atime; + time_t st_mtime; + time_t st_ctime; + }; +#endif + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Flags +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#define _S_IFMT 0xF000 // File type mask +#define _S_IFDIR 0x4000 // Directory +#define _S_IFCHR 0x2000 // Character special +#define _S_IFIFO 0x1000 // Pipe +#define _S_IFREG 0x8000 // Regular +#define _S_IREAD 0x0100 // Read permission, owner +#define _S_IWRITE 0x0080 // Write permission, owner +#define _S_IEXEC 0x0040 // Execute/search permission, owner + +#if defined(_CRT_INTERNAL_NONSTDC_NAMES) && _CRT_INTERNAL_NONSTDC_NAMES + #define S_IFMT _S_IFMT + #define S_IFDIR _S_IFDIR + #define S_IFCHR _S_IFCHR + #define S_IFREG _S_IFREG + #define S_IREAD _S_IREAD + #define S_IWRITE _S_IWRITE + #define S_IEXEC _S_IEXEC +#endif + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Functions +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#ifdef _USE_32BIT_TIME_T + #define _fstat _fstat32 + #define _fstati64 _fstat32i64 + #define _stat _stat32 + #define _stati64 _stat32i64 + #define _wstat _wstat32 + #define _wstati64 _wstat32i64 +#else + #define _fstat _fstat64i32 + #define _fstati64 _fstat64 + #define _stat _stat64i32 + #define _stati64 _stat64 + #define _wstat _wstat64i32 + #define _wstati64 _wstat64 +#endif + + + +_ACRTIMP int __cdecl _fstat32( + _In_ int _FileHandle, + _Out_ struct _stat32* _Stat + ); + +_ACRTIMP int __cdecl _fstat32i64( + _In_ int _FileHandle, + _Out_ struct _stat32i64* _Stat + ); + +_ACRTIMP int __cdecl _fstat64i32( + _In_ int _FileHandle, + _Out_ struct _stat64i32* _Stat + ); + +_ACRTIMP int __cdecl _fstat64( + _In_ int _FileHandle, + _Out_ struct _stat64* _Stat + ); + +_ACRTIMP int __cdecl _stat32( + _In_z_ char const* _FileName, + _Out_ struct _stat32* _Stat + ); + +_ACRTIMP int __cdecl _stat32i64( + _In_z_ char const* _FileName, + _Out_ struct _stat32i64* _Stat + ); + +_ACRTIMP int __cdecl _stat64i32( + _In_z_ char const* _FileName, + _Out_ struct _stat64i32* _Stat + ); + +_ACRTIMP int __cdecl _stat64( + _In_z_ char const* _FileName, + _Out_ struct _stat64* _Stat + ); + +_ACRTIMP int __cdecl _wstat32( + _In_z_ wchar_t const* _FileName, + _Out_ struct _stat32* _Stat + ); + +_ACRTIMP int __cdecl _wstat32i64( + _In_z_ wchar_t const* _FileName, + _Out_ struct _stat32i64* _Stat + ); + +_ACRTIMP int __cdecl _wstat64i32( + _In_z_ wchar_t const* _FileName, + _Out_ struct _stat64i32* _Stat + ); + +_ACRTIMP int __cdecl _wstat64( + _In_z_ wchar_t const* _FileName, + _Out_ struct _stat64* _Stat + ); + + + +#if !defined RC_INVOKED && !defined __midl && defined(_CRT_INTERNAL_NONSTDC_NAMES) && _CRT_INTERNAL_NONSTDC_NAMES && !defined _CRT_NO_TIME_T + #ifdef _USE_32BIT_TIME_T + + static __inline int __CRTDECL fstat(int const _FileHandle, struct stat* const _Stat) + { + _STATIC_ASSERT(sizeof(struct stat) == sizeof(struct _stat32)); + return _fstat32(_FileHandle, (struct _stat32*)_Stat); + } + + static __inline int __CRTDECL stat(char const* const _FileName, struct stat* const _Stat) + { + _STATIC_ASSERT(sizeof(struct stat) == sizeof(struct _stat32)); + return _stat32(_FileName, (struct _stat32*)_Stat); + } + + #else + + static __inline int __CRTDECL fstat(int const _FileHandle, struct stat* const _Stat) + { + _STATIC_ASSERT(sizeof(struct stat) == sizeof(struct _stat64i32)); + return _fstat64i32(_FileHandle, (struct _stat64i32*)_Stat); + } + static __inline int __CRTDECL stat(char const* const _FileName, struct stat* const _Stat) + { + _STATIC_ASSERT(sizeof(struct stat) == sizeof(struct _stat64i32)); + return _stat64i32(_FileName, (struct _stat64i32*)_Stat); + } + + #endif +#endif + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS diff --git a/sdk/include/ucrt/sys/timeb.h b/sdk/include/ucrt/sys/timeb.h new file mode 100644 index 0000000000000..d1589a0d18e72 --- /dev/null +++ b/sdk/include/ucrt/sys/timeb.h @@ -0,0 +1,112 @@ +// +// sys/timeb.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The _ftime() family of functions +// +#pragma once + +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Types +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +struct __timeb32 +{ + __time32_t time; + unsigned short millitm; + short timezone; + short dstflag; +}; + +struct __timeb64 +{ + __time64_t time; + unsigned short millitm; + short timezone; + short dstflag; +}; + +#if defined(_CRT_INTERNAL_NONSTDC_NAMES) && _CRT_INTERNAL_NONSTDC_NAMES && !defined _CRT_NO_TIME_T + struct timeb + { + time_t time; + unsigned short millitm; + short timezone; + short dstflag; + }; +#endif + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Functions +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#ifdef _USE_32BIT_TIME_T + #define _timeb __timeb32 + #define _ftime _ftime32 + #define _ftime_s _ftime32_s +#else + #define _timeb __timeb64 + #define _ftime _ftime64 + #define _ftime_s _ftime64_s +#endif + + + +_CRT_INSECURE_DEPRECATE(_ftime32_s) +_ACRTIMP void __cdecl _ftime32( + _Out_ struct __timeb32* _Time + ); + +_ACRTIMP errno_t __cdecl _ftime32_s( + _Out_ struct __timeb32* _Time + ); + +_CRT_INSECURE_DEPRECATE(_ftime64_s) +_ACRTIMP void __cdecl _ftime64( + _Out_ struct __timeb64* _Time + ); + +_ACRTIMP errno_t __cdecl _ftime64_s( + _Out_ struct __timeb64* _Time + ); + + + +#if !defined RC_INVOKED && !defined __midl && defined(_CRT_INTERNAL_NONSTDC_NAMES) && _CRT_INTERNAL_NONSTDC_NAMES && !defined _CRT_NO_TIME_T + + #ifdef _USE_32BIT_TIME_T + + static __inline void __CRTDECL ftime(struct timeb* const _Tmb) + { + _STATIC_ASSERT(sizeof(struct timeb) == sizeof(struct __timeb32)); + _ftime32((struct __timeb32*)_Tmb); + } + + #else + + static __inline void __CRTDECL ftime(struct timeb* const _Tmb) + { + _STATIC_ASSERT(sizeof(struct timeb) == sizeof(struct __timeb64)); + _ftime64((struct __timeb64*)_Tmb); + } + + #endif + +#endif + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS diff --git a/sdk/include/ucrt/sys/types.h b/sdk/include/ucrt/sys/types.h new file mode 100644 index 0000000000000..fac4c372aabcb --- /dev/null +++ b/sdk/include/ucrt/sys/types.h @@ -0,0 +1,51 @@ +// +// sys/types.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// Types used for returning file status and time information. +// +#pragma once + +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +#ifndef _INO_T_DEFINED + #define _INO_T_DEFINED + + typedef unsigned short _ino_t; // inode number (unused on Windows) + + #if (defined _CRT_DECLARE_NONSTDC_NAMES && _CRT_DECLARE_NONSTDC_NAMES) || (!defined _CRT_DECLARE_NONSTDC_NAMES && !__STDC__) + typedef _ino_t ino_t; + #endif +#endif + + + +#ifndef _DEV_T_DEFINED + #define _DEV_T_DEFINED + + typedef unsigned int _dev_t; // device code + + #if (defined _CRT_DECLARE_NONSTDC_NAMES && _CRT_DECLARE_NONSTDC_NAMES) || (!defined _CRT_DECLARE_NONSTDC_NAMES && !__STDC__) + typedef _dev_t dev_t; + #endif +#endif + + + +#ifndef _OFF_T_DEFINED + #define _OFF_T_DEFINED + + typedef long _off_t; // file offset value + + #if (defined _CRT_DECLARE_NONSTDC_NAMES && _CRT_DECLARE_NONSTDC_NAMES) || (!defined _CRT_DECLARE_NONSTDC_NAMES && !__STDC__) + typedef _off_t off_t; + #endif +#endif + +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS diff --git a/sdk/include/ucrt/sys/utime.h b/sdk/include/ucrt/sys/utime.h new file mode 100644 index 0000000000000..6f41f4cc85991 --- /dev/null +++ b/sdk/include/ucrt/sys/utime.h @@ -0,0 +1,163 @@ +// +// sys/utime.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The _utime() family of functions. +// +#pragma once + +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Types +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#ifndef _CRT_NO_TIME_T + struct _utimbuf + { + time_t actime; // access time + time_t modtime; // modification time + }; +#endif + +struct __utimbuf32 +{ + __time32_t actime; // access time + __time32_t modtime; // modification time +}; + +struct __utimbuf64 +{ + __time64_t actime; // access time + __time64_t modtime; // modification time +}; + +#if defined(_CRT_INTERNAL_NONSTDC_NAMES) && _CRT_INTERNAL_NONSTDC_NAMES && !defined _CRT_NO_TIME_T + + struct utimbuf + { + time_t actime; // access time + time_t modtime; // modification time + }; + + struct utimbuf32 + { + __time32_t actime; // access time + __time32_t modtime; // modification time + }; + +#endif + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Functions +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +_ACRTIMP int __cdecl _utime32( + _In_z_ char const* _FileName, + _In_opt_ struct __utimbuf32* _Time + ); + +_ACRTIMP int __cdecl _futime32( + _In_ int _FileHandle, + _In_opt_ struct __utimbuf32* _Time + ); + +_ACRTIMP int __cdecl _wutime32( + _In_z_ wchar_t const* _FileName, + _In_opt_ struct __utimbuf32* _Time + ); + +_ACRTIMP int __cdecl _utime64( + _In_z_ char const* _FileName, + _In_opt_ struct __utimbuf64* _Time + ); + +_ACRTIMP int __cdecl _futime64( + _In_ int _FileHandle, + _In_opt_ struct __utimbuf64* _Time + ); + +_ACRTIMP int __cdecl _wutime64( + _In_z_ wchar_t const* _FileName, + _In_opt_ struct __utimbuf64* _Time + ); + + + +#if !defined RC_INVOKED && !defined __midl && !defined _CRT_NO_TIME_T + #ifdef _USE_32BIT_TIME_T + + static __inline int __CRTDECL _utime(char const* const _FileName, struct _utimbuf* const _Time) + { + _STATIC_ASSERT(sizeof(struct _utimbuf) == sizeof(struct __utimbuf32)); + return _utime32(_FileName, (struct __utimbuf32*)_Time); + } + + static __inline int __CRTDECL _futime(int const _FileHandle, struct _utimbuf* const _Time) + { + _STATIC_ASSERT(sizeof(struct _utimbuf) == sizeof(struct __utimbuf32)); + return _futime32(_FileHandle, (struct __utimbuf32*)_Time); + } + + static __inline int __CRTDECL _wutime(wchar_t const* const _FileName, struct _utimbuf* const _Time) + { + _STATIC_ASSERT(sizeof(struct _utimbuf) == sizeof(struct __utimbuf32)); + return _wutime32(_FileName, (struct __utimbuf32*)_Time); + } + + #else + static __inline int __CRTDECL _utime(char const* const _FileName, struct _utimbuf* const _Time) + { + _STATIC_ASSERT(sizeof(struct _utimbuf) == sizeof(struct __utimbuf64)); + return _utime64(_FileName, (struct __utimbuf64*)_Time); + } + + static __inline int __CRTDECL _futime(int const _FileHandle, struct _utimbuf* const _Time) + { + _STATIC_ASSERT(sizeof(struct _utimbuf) == sizeof(struct __utimbuf64)); + return _futime64(_FileHandle, (struct __utimbuf64*)_Time); + } + + static __inline int __CRTDECL _wutime(wchar_t const* const _FileName, struct _utimbuf* const _Time) + { + _STATIC_ASSERT(sizeof(struct _utimbuf) == sizeof(struct __utimbuf64)); + return _wutime64(_FileName, (struct __utimbuf64*)_Time); + } + + #endif + + #if defined(_CRT_INTERNAL_NONSTDC_NAMES) && _CRT_INTERNAL_NONSTDC_NAMES + #ifdef _USE_32BIT_TIME_T + + static __inline int __CRTDECL utime(char const* const _FileName, struct utimbuf* const _Time) + { + _STATIC_ASSERT(sizeof(struct utimbuf) == sizeof(struct __utimbuf32)); + return _utime32(_FileName, (struct __utimbuf32*)_Time); + } + + #else + + static __inline int __CRTDECL utime(char const* const _FileName, struct utimbuf* const _Time) + { + _STATIC_ASSERT(sizeof(struct utimbuf) == sizeof(struct __utimbuf64)); + return _utime64(_FileName, (struct __utimbuf64*)_Time); + } + + #endif + #endif +#endif + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS diff --git a/sdk/include/ucrt/tchar.h b/sdk/include/ucrt/tchar.h new file mode 100644 index 0000000000000..42a98d76ae3f2 --- /dev/null +++ b/sdk/include/ucrt/tchar.h @@ -0,0 +1,2330 @@ +/*** +*tchar.h - definitions for generic international text functions +* +* Copyright (c) Microsoft Corporation. All rights reserved. +* +*Purpose: +* Definitions for generic international functions, mostly defines +* which map string/formatted-io/ctype functions to char, wchar_t, or +* MBCS versions. To be used for compatibility between single-byte, +* multi-byte and Unicode text models. +* +* [Public] +* +****/ + +#pragma once +#ifndef _INC_TCHAR // include guard for 3rd party interop +#define _INC_TCHAR + +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +/* Notes */ + +/* There is no: + * _tcscat_l + * _tcscpy_l + * because mbscat and mbscpy just behave like strcat and strcpy, + * so no special locale-specific behavior is needed. + */ + +/* Functions like: + * _strncat_l + * _strncat_s_l + * are only available if ANSI is defined (i.e. no _UNICODE nor _MBCS), + * because these functions are only accessible through the _tcs macros. + */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef _CRT_FAR_MAPPINGS_NO_DEPRECATE +/* +Long ago, these f prefix text functions referred to handling of text in segmented architectures. Ever since the move +to Win32 they have been obsolete names, but we kept them around as aliases. Now that we have a deprecation +mechanism we can warn about them. You should switch to the identical function without the f prefix. +*/ +#pragma deprecated("_ftcscat") +#pragma deprecated("_ftcschr") +#pragma deprecated("_ftcscpy") +#pragma deprecated("_ftcscspn") +#pragma deprecated("_ftcslen") +#pragma deprecated("_ftcsncat") +#pragma deprecated("_ftcsncpy") +#pragma deprecated("_ftcspbrk") +#pragma deprecated("_ftcsrchr") +#pragma deprecated("_ftcsspn") +#pragma deprecated("_ftcsstr") +#pragma deprecated("_ftcstok") +#pragma deprecated("_ftcsdup") +#pragma deprecated("_ftcsnset") +#pragma deprecated("_ftcsrev") +#pragma deprecated("_ftcsset") +#pragma deprecated("_ftcscmp") +#pragma deprecated("_ftcsicmp") +#pragma deprecated("_ftcsnccmp") +#pragma deprecated("_ftcsncmp") +#pragma deprecated("_ftcsncicmp") +#pragma deprecated("_ftcsnicmp") +#pragma deprecated("_ftcscoll") +#pragma deprecated("_ftcsicoll") +#pragma deprecated("_ftcsnccoll") +#pragma deprecated("_ftcsncoll") +#pragma deprecated("_ftcsncicoll") +#pragma deprecated("_ftcsnicoll") +#pragma deprecated("_ftcsclen") +#pragma deprecated("_ftcsnccat") +#pragma deprecated("_ftcsnccpy") +#pragma deprecated("_ftcsncset") +#pragma deprecated("_ftcsdec") +#pragma deprecated("_ftcsinc") +#pragma deprecated("_ftcsnbcnt") +#pragma deprecated("_ftcsnccnt") +#pragma deprecated("_ftcsnextc") +#pragma deprecated("_ftcsninc") +#pragma deprecated("_ftcsspnp") +#pragma deprecated("_ftcslwr") +#pragma deprecated("_ftcsupr") +#pragma deprecated("_ftclen") +#pragma deprecated("_ftccpy") +#pragma deprecated("_ftccmp") +#endif /* _CRT_FAR_MAPPINGS_NO_DEPRECATE */ + +#define _ftcscat _tcscat +#define _ftcschr _tcschr +#define _ftcscpy _tcscpy +#define _ftcscspn _tcscspn +#define _ftcslen _tcslen +#define _ftcsncat _tcsncat +#define _ftcsncpy _tcsncpy +#define _ftcspbrk _tcspbrk +#define _ftcsrchr _tcsrchr +#define _ftcsspn _tcsspn +#define _ftcsstr _tcsstr +#define _ftcstok _tcstok + +#define _ftcsdup _tcsdup +#define _ftcsnset _tcsnset +#define _ftcsrev _tcsrev +#define _ftcsset _tcsset + +#define _ftcscmp _tcscmp +#define _ftcsicmp _tcsicmp +#define _ftcsnccmp _tcsnccmp +#define _ftcsncmp _tcsncmp +#define _ftcsncicmp _tcsncicmp +#define _ftcsnicmp _tcsnicmp + +#define _ftcscoll _tcscoll +#define _ftcsicoll _tcsicoll +#define _ftcsnccoll _tcsnccoll +#define _ftcsncoll _tcsncoll +#define _ftcsncicoll _tcsncicoll +#define _ftcsnicoll _tcsnicoll + +/* Redundant "logical-character" mappings */ + +#define _ftcsclen _tcsclen +#define _ftcsnccat _tcsnccat +#define _ftcsnccpy _tcsnccpy +#define _ftcsncset _tcsncset + +#define _ftcsdec _tcsdec +#define _ftcsinc _tcsinc +#define _ftcsnbcnt _tcsnbcnt +#define _ftcsnccnt _tcsnccnt +#define _ftcsnextc _tcsnextc +#define _ftcsninc _tcsninc +#define _ftcsspnp _tcsspnp + +#define _ftcslwr _tcslwr +#define _ftcsupr _tcsupr + +#define _ftclen _tclen +#define _ftccpy _tccpy +#define _ftccmp _tccmp + +#ifdef _UNICODE + +#ifdef __cplusplus +} /* ... extern "C" */ +#endif /* __cplusplus */ + +/* ++++++++++++++++++++ UNICODE ++++++++++++++++++++ */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef __TCHAR_DEFINED +typedef wchar_t _TCHAR; +typedef wchar_t _TSCHAR; +typedef wchar_t _TUCHAR; +typedef wchar_t _TXCHAR; +typedef wint_t _TINT; +#define __TCHAR_DEFINED +#endif /* __TCHAR_DEFINED */ + +#if defined(_CRT_INTERNAL_NONSTDC_NAMES) && _CRT_INTERNAL_NONSTDC_NAMES +#ifndef _TCHAR_DEFINED +typedef wchar_t TCHAR; +typedef wchar_t * PTCHAR; +typedef wchar_t TBYTE; +typedef wchar_t * PTBYTE; +#define _TCHAR_DEFINED +#endif /* _TCHAR_DEFINED */ +#endif /* _CRT_INTERNAL_NONSTDC_NAMES */ + +#define _TEOF WEOF + +#define __T(x) L ## x + + +/* Program */ + +#define _tmain wmain +#define _tWinMain wWinMain +#define _tenviron _wenviron +#define __targv __wargv + +/* Formatted i/o */ + +#define _tprintf wprintf +#define _tprintf_l _wprintf_l +#define _tprintf_s wprintf_s +#define _tprintf_s_l _wprintf_s_l +#define _tprintf_p _wprintf_p +#define _tprintf_p_l _wprintf_p_l +#define _tcprintf _cwprintf +#define _tcprintf_l _cwprintf_l +#define _tcprintf_s _cwprintf_s +#define _tcprintf_s_l _cwprintf_s_l +#define _tcprintf_p _cwprintf_p +#define _tcprintf_p_l _cwprintf_p_l +#define _vtcprintf _vcwprintf +#define _vtcprintf_l _vcwprintf_l +#define _vtcprintf_s _vcwprintf_s +#define _vtcprintf_s_l _vcwprintf_s_l +#define _vtcprintf_p _vcwprintf_p +#define _vtcprintf_p_l _vcwprintf_p_l +#define _ftprintf fwprintf +#define _ftprintf_l _fwprintf_l +#define _ftprintf_s fwprintf_s +#define _ftprintf_s_l _fwprintf_s_l +#define _ftprintf_p _fwprintf_p +#define _ftprintf_p_l _fwprintf_p_l +#define _stprintf _swprintf +#define _stprintf_l __swprintf_l +#define _stprintf_s swprintf_s +#define _stprintf_s_l _swprintf_s_l +#define _stprintf_p _swprintf_p +#define _stprintf_p_l _swprintf_p_l +#define _sctprintf _scwprintf +#define _sctprintf_l _scwprintf_l +#define _sctprintf_p _scwprintf_p +#define _sctprintf_p_l _scwprintf_p_l +#define _sntprintf _snwprintf +#define _sntprintf_l _snwprintf_l +#define _sntprintf_s _snwprintf_s +#define _sntprintf_s_l _snwprintf_s_l +#define _vtprintf vwprintf +#define _vtprintf_l _vwprintf_l +#define _vtprintf_s vwprintf_s +#define _vtprintf_s_l _vwprintf_s_l +#define _vtprintf_p _vwprintf_p +#define _vtprintf_p_l _vwprintf_p_l +#define _vftprintf vfwprintf +#define _vftprintf_l _vfwprintf_l +#define _vftprintf_s vfwprintf_s +#define _vftprintf_s_l _vfwprintf_s_l +#define _vftprintf_p _vfwprintf_p +#define _vftprintf_p_l _vfwprintf_p_l +#define _vstprintf vswprintf +#define _vstprintf_l _vswprintf_l +#define _vstprintf_s vswprintf_s +#define _vstprintf_s_l _vswprintf_s_l +#define _vstprintf_p _vswprintf_p +#define _vstprintf_p_l _vswprintf_p_l +#define _vsctprintf _vscwprintf +#define _vsctprintf_l _vscwprintf_l +#define _vsctprintf_p _vscwprintf_p +#define _vsctprintf_p_l _vscwprintf_p_l +#define _vsntprintf _vsnwprintf +#define _vsntprintf_l _vsnwprintf_l +#define _vsntprintf_s _vsnwprintf_s +#define _vsntprintf_s_l _vsnwprintf_s_l + +#define _tscanf wscanf +#define _tscanf_l _wscanf_l +#define _tscanf_s wscanf_s +#define _tscanf_s_l _wscanf_s_l +#define _tcscanf _cwscanf +#define _tcscanf_l _cwscanf_l +#define _tcscanf_s _cwscanf_s +#define _tcscanf_s_l _cwscanf_s_l +#define _ftscanf fwscanf +#define _ftscanf_l _fwscanf_l +#define _ftscanf_s fwscanf_s +#define _ftscanf_s_l _fwscanf_s_l +#define _stscanf swscanf +#define _stscanf_l _swscanf_l +#define _stscanf_s swscanf_s +#define _stscanf_s_l _swscanf_s_l +#define _sntscanf _snwscanf +#define _sntscanf_l _snwscanf_l +#define _sntscanf_s _snwscanf_s +#define _sntscanf_s_l _snwscanf_s_l +#define _vtscanf vwscanf +#define _vtscanf_s vwscanf_s +#define _vftscanf vfwscanf +#define _vftscanf_s vfwscanf_s +#define _vstscanf vswscanf +#define _vstscanf_s vswscanf_s + + +/* Unformatted i/o */ + +#define _fgettc fgetwc +#define _fgettc_nolock _fgetwc_nolock +#define _fgettchar _fgetwchar +#define _fgetts fgetws +#define _fputtc fputwc +#define _fputtc_nolock _fputwc_nolock +#define _fputtchar _fputwchar +#define _fputts fputws +#define _cputts _cputws +#define _cgetts_s _cgetws_s +#define _gettc getwc +#define _gettc_nolock _getwc_nolock +#define _gettch _getwch +#define _gettch_nolock _getwch_nolock +#define _gettche _getwche +#define _gettche_nolock _getwche_nolock +#define _gettchar getwchar +#define _gettchar_nolock _getwchar_nolock +#define _getts_s _getws_s +#define _puttc putwc +#define _puttc_nolock _fputwc_nolock +#define _puttchar putwchar +#define _puttchar_nolock _putwchar_nolock +#define _puttch _putwch +#define _puttch_nolock _putwch_nolock +#define _putts _putws +#define _ungettc ungetwc +#define _ungettc_nolock _ungetwc_nolock +#define _ungettch _ungetwch +#define _ungettch_nolock _ungetwch_nolock + + +/* String conversion functions */ + +#define _tcstod wcstod +#define _tcstof wcstof +#define _tcstol wcstol +#define _tcstold wcstold +#define _tcstoll wcstoll +#define _tcstoul wcstoul +#define _tcstoull wcstoull +#define _tcstoimax wcstoimax +#define _tcstoumax wcstoumax +#define _tcstoi64 _wcstoi64 +#define _tcstoui64 _wcstoui64 +#define _ttof _wtof +#define _tstof _wtof +#define _tstol _wtol +#define _tstoll _wtoll +#define _tstoi _wtoi +#define _tstoi64 _wtoi64 +#define _tcstod_l _wcstod_l +#define _tcstof_l _wcstof_l +#define _tcstol_l _wcstol_l +#define _tcstold_l _wcstold_l +#define _tcstoll_l _wcstoll_l +#define _tcstoul_l _wcstoul_l +#define _tcstoull_l _wcstoull_l +#define _tcstoi64_l _wcstoi64_l +#define _tcstoui64_l _wcstoui64_l +#define _tcstoimax_l _wcstoimax_l +#define _tcstoumax_l _wcstoumax_l +#define _tstof_l _wtof_l +#define _tstol_l _wtol_l +#define _tstoll_l _wtoll_l +#define _tstoi_l _wtoi_l +#define _tstoi64_l _wtoi64_l + +#define _itot_s _itow_s +#define _ltot_s _ltow_s +#define _ultot_s _ultow_s +#define _itot _itow +#define _ltot _ltow +#define _ultot _ultow +#define _ttoi _wtoi +#define _ttol _wtol +#define _ttoll _wtoll + +#define _ttoi64 _wtoi64 +#define _i64tot_s _i64tow_s +#define _ui64tot_s _ui64tow_s +#define _i64tot _i64tow +#define _ui64tot _ui64tow + +/* String functions */ + +#define _tcscat wcscat +#define _tcscat_s wcscat_s +#define _tcschr wcschr +#define _tcscpy wcscpy +#define _tcscpy_s wcscpy_s +#define _tcscspn wcscspn +#define _tcslen wcslen +#define _tcsnlen wcsnlen +#define _tcsncat wcsncat +#define _tcsncat_s wcsncat_s +#define _tcsncat_l _wcsncat_l +#define _tcsncat_s_l _wcsncat_s_l +#define _tcsncpy wcsncpy +#define _tcsncpy_s wcsncpy_s +#define _tcsncpy_l _wcsncpy_l +#define _tcsncpy_s_l _wcsncpy_s_l +#define _tcspbrk wcspbrk +#define _tcsrchr wcsrchr +#define _tcsspn wcsspn +#define _tcsstr wcsstr +#define _tcstok _wcstok +#define _tcstok_s wcstok_s +#define _tcstok_l _wcstok_l +#define _tcstok_s_l _wcstok_s_l +#define _tcserror _wcserror +#define _tcserror_s _wcserror_s +#define __tcserror __wcserror +#define __tcserror_s __wcserror_s + +#define _tcsdup _wcsdup +#define _tcsnset _wcsnset +#define _tcsnset_s _wcsnset_s +#define _tcsnset_l _wcsnset_l +#define _tcsnset_s_l _wcsnset_s_l +#define _tcsrev _wcsrev +#define _tcsset _wcsset +#define _tcsset_s _wcsset_s +#define _tcsset_l _wcsset_l +#define _tcsset_s_l _wcsset_s_l + +#define _tcscmp wcscmp +#define _tcsicmp _wcsicmp +#define _tcsicmp_l _wcsicmp_l +#define _tcsnccmp wcsncmp +#define _tcsncmp wcsncmp +#define _tcsncicmp _wcsnicmp +#define _tcsncicmp_l _wcsnicmp_l +#define _tcsnicmp _wcsnicmp +#define _tcsnicmp_l _wcsnicmp_l + +#define _tcscoll wcscoll +#define _tcscoll_l _wcscoll_l +#define _tcsicoll _wcsicoll +#define _tcsicoll_l _wcsicoll_l +#define _tcsnccoll _wcsncoll +#define _tcsnccoll_l _wcsncoll_l +#define _tcsncoll _wcsncoll +#define _tcsncoll_l _wcsncoll_l +#define _tcsncicoll _wcsnicoll +#define _tcsncicoll_l _wcsnicoll_l +#define _tcsnicoll _wcsnicoll +#define _tcsnicoll_l _wcsnicoll_l + +#ifdef _DEBUG +#define _tcsdup_dbg _wcsdup_dbg +#endif /* _DEBUG */ + +/* Execute functions */ + +#define _texecl _wexecl +#define _texecle _wexecle +#define _texeclp _wexeclp +#define _texeclpe _wexeclpe +#define _texecv _wexecv +#define _texecve _wexecve +#define _texecvp _wexecvp +#define _texecvpe _wexecvpe + +#define _tspawnl _wspawnl +#define _tspawnle _wspawnle +#define _tspawnlp _wspawnlp +#define _tspawnlpe _wspawnlpe +#define _tspawnv _wspawnv +#define _tspawnve _wspawnve +#define _tspawnvp _wspawnvp +#define _tspawnvp _wspawnvp +#define _tspawnvpe _wspawnvpe + +#define _tsystem _wsystem + + +/* Time functions */ + +#define _tasctime _wasctime +#define _tctime _wctime +#define _tctime32 _wctime32 +#define _tctime64 _wctime64 +#define _tstrdate _wstrdate +#define _tstrtime _wstrtime +#define _tutime _wutime +#define _tutime32 _wutime32 +#define _tutime64 _wutime64 +#define _tcsftime wcsftime +#define _tcsftime_l _wcsftime_l + +#define _tasctime_s _wasctime_s +#define _tctime_s _wctime_s +#define _tctime32_s _wctime32_s +#define _tctime64_s _wctime64_s +#define _tstrdate_s _wstrdate_s +#define _tstrtime_s _wstrtime_s + +/* Directory functions */ + +#define _tchdir _wchdir +#define _tgetcwd _wgetcwd +#define _tgetdcwd _wgetdcwd +#define _tgetdcwd_nolock _wgetdcwd_nolock +#define _tmkdir _wmkdir +#define _trmdir _wrmdir + +#ifdef _DEBUG +#define _tgetcwd_dbg _wgetcwd_dbg +#define _tgetdcwd_dbg _wgetdcwd_dbg +#define _tgetdcwd_lk_dbg _wgetdcwd_lk_dbg +#endif /* _DEBUG */ + +/* Environment/Path functions */ + +#define _tfullpath _wfullpath +#define _tgetenv _wgetenv +#define _tgetenv_s _wgetenv_s +#define _tdupenv_s _wdupenv_s +#define _tmakepath _wmakepath +#define _tmakepath_s _wmakepath_s +#define _tpgmptr _wpgmptr +#define _get_tpgmptr _get_wpgmptr +#define _tputenv _wputenv +#define _tputenv_s _wputenv_s +#define _tsearchenv _wsearchenv +#define _tsearchenv_s _wsearchenv_s +#define _tsplitpath _wsplitpath +#define _tsplitpath_s _wsplitpath_s + +#ifdef _DEBUG +#define _tfullpath_dbg _wfullpath_dbg +#define _tdupenv_s_dbg _wdupenv_s_dbg +#endif /* _DEBUG */ + +/* Stdio functions */ + +#define _tfdopen _wfdopen +#define _tfsopen _wfsopen +#define _tfopen _wfopen +#define _tfopen_s _wfopen_s +#define _tfreopen _wfreopen +#define _tfreopen_s _wfreopen_s +#define _tperror _wperror +#define _tpopen _wpopen +#define _ttempnam _wtempnam +#define _ttmpnam _wtmpnam +#define _ttmpnam_s _wtmpnam_s + +#ifdef _DEBUG +#define _ttempnam_dbg _wtempnam_dbg +#endif /* _DEBUG */ + + +/* Io functions */ + +#define _taccess _waccess +#define _taccess_s _waccess_s +#define _tchmod _wchmod +#define _tcreat _wcreat +#define _tfindfirst _wfindfirst +#define _tfindfirst32 _wfindfirst32 +#define _tfindfirst64 _wfindfirst64 +#define _tfindfirsti64 _wfindfirsti64 +#define _tfindfirst32i64 _wfindfirst32i64 +#define _tfindfirst64i32 _wfindfirst64i32 +#define _tfindnext _wfindnext +#define _tfindnext32 _wfindnext32 +#define _tfindnext64 _wfindnext64 +#define _tfindnexti64 _wfindnexti64 +#define _tfindnext32i64 _wfindnext32i64 +#define _tfindnext64i32 _wfindnext64i32 +#define _tmktemp _wmktemp +#define _tmktemp_s _wmktemp_s +#define _topen _wopen +#define _tremove _wremove +#define _trename _wrename +#define _tsopen _wsopen +#define _tsopen_s _wsopen_s +#define _tunlink _wunlink + +#define _tfinddata_t _wfinddata_t +#define _tfinddata32_t _wfinddata32_t +#define _tfinddata64_t _wfinddata64_t +#define _tfinddatai64_t _wfinddatai64_t +#define _tfinddata32i64_t _wfinddata32i64_t +#define _tfinddata64i32_t _wfinddata64i32_t + + +/* Stat functions */ + +#define _tstat _wstat +#define _tstat32 _wstat32 +#define _tstat32i64 _wstat32i64 +#define _tstat64 _wstat64 +#define _tstat64i32 _wstat64i32 +#define _tstati64 _wstati64 + + +/* Setlocale functions */ + +#define _tsetlocale _wsetlocale + + +/* Redundant "logical-character" mappings */ + +#define _tcsclen wcslen +#define _tcscnlen wcsnlen +#define _tcsclen_l(_String, _Locale) wcslen(_String) +#define _tcscnlen_l(_String, _Max_count, _Locale) wcsnlen((_String), (_Max_count)) +#define _tcsnccat wcsncat +#define _tcsnccat_s wcsncat_s +#define _tcsnccat_l _wcsncat_l +#define _tcsnccat_s_l _wcsncat_s_l +#define _tcsnccpy wcsncpy +#define _tcsnccpy_s wcsncpy_s +#define _tcsnccpy_l _wcsncpy_l +#define _tcsnccpy_s_l _wcsncpy_s_l +#define _tcsncset _wcsnset +#define _tcsncset_s _wcsnset_s +#define _tcsncset_l _wcsnset_l +#define _tcsncset_s_l _wcsnset_s_l + +#define _tcsdec _wcsdec +#define _tcsinc _wcsinc +#define _tcsnbcnt _wcsncnt +#define _tcsnccnt _wcsncnt +#define _tcsnextc _wcsnextc +#define _tcsninc _wcsninc +#define _tcsspnp _wcsspnp + +#define _tcslwr _wcslwr +#define _tcslwr_l _wcslwr_l +#define _tcslwr_s _wcslwr_s +#define _tcslwr_s_l _wcslwr_s_l +#define _tcsupr _wcsupr +#define _tcsupr_l _wcsupr_l +#define _tcsupr_s _wcsupr_s +#define _tcsupr_s_l _wcsupr_s_l +#define _tcsxfrm wcsxfrm +#define _tcsxfrm_l _wcsxfrm_l + + +#if __STDC__ || defined (_NO_INLINING) +#define _tclen(_pc) (1) +#define _tccpy(_pc1,_cpc2) ((*(_pc1) = *(_cpc2))) +#define _tccpy_l(_pc1,_cpc2,_locale) _tccpy((_pc1),(_cpc2)) +#define _tccmp(_cpc1,_cpc2) ((*(_cpc1))-(*(_cpc2))) +#else /* __STDC__ || defined (_NO_INLINING) */ +_Check_return_ __inline size_t __CRTDECL _tclen(_In_z_ const wchar_t *_Cpc) +{ + /* avoid compiler warning */ + (void)_Cpc; + return 1; +} +__inline void __CRTDECL _tccpy(_Out_ wchar_t *_Pc1, _In_z_ const wchar_t *_Cpc2) { *_Pc1 = (wchar_t)*_Cpc2; } +__inline void __CRTDECL _tccpy_l(_Out_ wchar_t *_Pc1, _In_z_ const wchar_t *_Cpc2, _In_opt_ _locale_t _Locale) +{ + _CRT_UNUSED(_Locale); + _tccpy(_Pc1, _Cpc2); +} +_Check_return_ __inline int __CRTDECL _tccmp(_In_z_ const wchar_t *_Cpc1, _In_z_ const wchar_t *_Cpc2) { return (int) ((*_Cpc1)-(*_Cpc2)); } +#endif /* __STDC__ || defined (_NO_INLINING) */ + +/* ctype functions */ + +#define _istalnum iswalnum +#define _istalnum_l _iswalnum_l +#define _istalpha iswalpha +#define _istalpha_l _iswalpha_l +#define _istascii iswascii +#define _istcntrl iswcntrl +#define _istcntrl_l _iswcntrl_l +#define _istdigit iswdigit +#define _istdigit_l _iswdigit_l +#define _istgraph iswgraph +#define _istgraph_l _iswgraph_l +#define _istlower iswlower +#define _istlower_l _iswlower_l +#define _istprint iswprint +#define _istprint_l _iswprint_l +#define _istpunct iswpunct +#define _istpunct_l _iswpunct_l +#define _istblank iswblank +#define _istblank_l _iswblank_l +#define _istspace iswspace +#define _istspace_l _iswspace_l +#define _istupper iswupper +#define _istupper_l _iswupper_l +#define _istxdigit iswxdigit +#define _istxdigit_l _iswxdigit_l + +#define _totupper towupper +#define _totupper_l _towupper_l +#define _totlower towlower +#define _totlower_l _towlower_l + +#define _istlegal(_Char) (1) +#define _istlead(_Char) (0) +#define _istleadbyte(_Char) (0) +#define _istleadbyte_l(_Char, _Locale) (0) + + +#if __STDC__ || defined _NO_INLINING +#define _wcsdec(_cpc1, _cpc2) ((_cpc1)>=(_cpc2) ? NULL : (_cpc2)-1) +#define _wcsinc(_pc) ((_pc)+1) +#define _wcsnextc(_cpc) ((unsigned int) *(_cpc)) +#define _wcsninc(_pc, _sz) (((_pc)+(_sz))) +_Check_return_ _ACRTIMP size_t __cdecl __wcsncnt(_In_reads_or_z_(_MaxCount) const wchar_t * _Str, _In_ size_t _MaxCount); +#define _wcsncnt(_cpc, _sz) (__wcsncnt(_cpc,_sz)) +#define _wcsspnp(_cpc1, _cpc2) (_cpc1==NULL ? NULL : ((*((_cpc1)+wcsspn(_cpc1,_cpc2))) ? ((_cpc1)+wcsspn(_cpc1,_cpc2)) : NULL)) +#define _wcsncpy_l(_Destination, _Source, _Count, _Locale) (wcsncpy(_Destination, _Source, _Count)) +#if __STDC_WANT_SECURE_LIB__ +#define _wcsncpy_s_l(_Destination, _Destination_size_chars, _Source, _Count, _Locale) (wcsncpy_s(_Destination, _Destination_size_chars, _Source, _Count)) +#endif /* __STDC_WANT_SECURE_LIB__ */ +#define _wcsncat_l(_Destination, _Source, _Count, _Locale) (wcsncat(_Destination, _Source, _Count)) +#if __STDC_WANT_SECURE_LIB__ +#define _wcsncat_s_l(_Destination, _Destination_size_chars, _Source, _Count, _Locale) (wcsncat_s(_Destination, _Destination_size_chars, _Source, _Count)) +#endif /* __STDC_WANT_SECURE_LIB__ */ +#define _wcstok_l(_String, _Delimiters, _Locale) (_wcstok(_String, _Delimiters)) +#define _wcstok_s_l(_String, _Delimiters, _Current_position, _Locale) (wcstok_s(_String, _Delimiters, _Current_position)) +#define _wcsnset_l(_Destination, _Value, _Count, _Locale) (_wcsnset(_Destination, _Value, _Count)) +#define _wcsnset_s_l(_Destination, _Destination_size_chars, _Value, _Count, _Locale) (_wcsnset_s(_Destination, _Destination_size_chars, _Value, _Count)) +#define _wcsset_l(_Destination, _Value, _Locale) (_wcsset(_Destination, _Value)) +#define _wcsset_s_l(_Destination, _Destination_size_chars, _Value, _Locale) (_wcsset_s(_Destination, _Destination_size_chars, _Value)) +#else /* __STDC__ || defined (_NO_INLINING) */ +_Check_return_ __inline wchar_t * __CRTDECL _wcsdec(_In_z_ const wchar_t * _Cpc1, _In_z_ const wchar_t * _Cpc2) { return (wchar_t *)((_Cpc1)>=(_Cpc2) ? NULL : ((_Cpc2)-1)); } +_Check_return_ __inline wchar_t * __CRTDECL _wcsinc(_In_z_ const wchar_t * _Pc) { return (wchar_t *)(_Pc+1); } +_Check_return_ __inline unsigned int __CRTDECL _wcsnextc(_In_z_ const wchar_t * _Cpc) { return (unsigned int)*_Cpc; } +_Check_return_ __inline wchar_t * __CRTDECL _wcsninc(_In_z_ const wchar_t * _Pc, _In_ size_t _Sz) { return (wchar_t *)(_Pc+_Sz); } +_Check_return_ __inline size_t __CRTDECL _wcsncnt( _In_reads_or_z_(_Cnt) const wchar_t * _String, _In_ size_t _Cnt) +{ + size_t n = _Cnt; + wchar_t *cp = (wchar_t *)_String; + while (n-- && *cp) + cp++; + return _Cnt - n - 1; +} +_Check_return_ __inline wchar_t * __CRTDECL _wcsspnp +( + _In_z_ const wchar_t * _Cpc1, + _In_z_ const wchar_t * _Cpc2 +) +{ + return _Cpc1==NULL ? NULL : ((*(_Cpc1 += wcsspn(_Cpc1,_Cpc2))!='\0') ? (wchar_t*)_Cpc1 : NULL); +} + +#if __STDC_WANT_SECURE_LIB__ +_Check_return_wat_ __inline errno_t __CRTDECL _wcsncpy_s_l(_Out_writes_z_(_Destination_size_chars) wchar_t *_Destination, _In_ size_t _Destination_size_chars, _In_z_ const wchar_t *_Source, _In_ size_t _Count, _In_opt_ _locale_t _Locale) +{ + _CRT_UNUSED(_Locale); + return wcsncpy_s(_Destination, _Destination_size_chars, _Source, _Count); +} +#endif /* __STDC_WANT_SECURE_LIB__ */ + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_3(errno_t, _wcsncpy_s_l, wchar_t, _Dest, _In_z_ const wchar_t *, _Source, _In_ size_t, _Count, _In_opt_ _locale_t, _Locale) + +__DECLARE_CPP_OVERLOAD_INLINE_NFUNC_0_3_EX(wchar_t *, __RETURN_POLICY_DST, _wcsncpy_l, _wcsncpy_s_l, _Out_writes_z_(_Size) wchar_t, _Out_writes_(_Count) wchar_t, _Dst, _In_z_ const wchar_t *, _Source, _In_ size_t, _Count, _In_opt_ _locale_t, _Locale) +{ + _CRT_UNUSED(_Locale); +#pragma warning(suppress: 6054) // String may not be zero-terminated + return wcsncpy(_Dst, _Source, _Count); +} + +__DEFINE_CPP_OVERLOAD_INLINE_NFUNC_0_3_EX(wchar_t *, __RETURN_POLICY_DST, _wcsncpy_l, _wcsncpy_s_l, _Out_writes_z_(_Size) wchar_t, _Out_writes_(_Count), wchar_t, _Dst, _In_z_ const wchar_t *, _Source, _In_ size_t, _Count, _In_opt_ _locale_t, _Locale) + +#if __STDC_WANT_SECURE_LIB__ +_Check_return_wat_ __inline errno_t __CRTDECL _wcsncat_s_l(_Inout_updates_z_(_Destination_size_chars) wchar_t *_Destination, _In_ size_t _Destination_size_chars, _In_z_ const wchar_t *_Source, _In_ size_t _Count, _In_opt_ _locale_t _Locale) +{ + _CRT_UNUSED(_Locale); + return wcsncat_s(_Destination, _Destination_size_chars, _Source, _Count); +} +#endif /* __STDC_WANT_SECURE_LIB__ */ + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_3(errno_t, _wcsncat_s_l, wchar_t, _Dest, _In_z_ const wchar_t *, _Source, _In_ size_t, _Count, _In_opt_ _locale_t, _Locale) + +__DECLARE_CPP_OVERLOAD_INLINE_NFUNC_0_3_EX(wchar_t *, __RETURN_POLICY_DST, _wcsncat_l, _wcsncat_s_l, _Inout_updates_z_(_Size) wchar_t, _Inout_z_ wchar_t, _Dst, _In_z_ const wchar_t *, _Source, _In_ size_t, _Count, _In_opt_ _locale_t, _Locale) +{ + _CRT_UNUSED(_Locale); +// C6054: String may not be zero-terminated +// C6059: Incorrect length parameter in call +#pragma warning(suppress: 6054 6059) + return wcsncat(_Dst, _Source, _Count); +} + +__DEFINE_CPP_OVERLOAD_INLINE_NFUNC_0_3_EX(wchar_t *, __RETURN_POLICY_DST, _wcsncat_l, _wcsncat_s_l, _Inout_updates_z_(_Size) wchar_t, _Inout_z_, wchar_t, _Dst, _In_z_ const wchar_t *, _Source, _In_ size_t, _Count, _In_opt_ _locale_t, _Locale) + +_CRT_INSECURE_DEPRECATE(_wcstok_s_l) __inline wchar_t * _wcstok_l(_Inout_opt_z_ wchar_t * _String, _In_z_ const wchar_t * _Delimiters, _In_opt_ _locale_t _Locale) +{ + _CRT_UNUSED(_Locale); +#ifdef _CRT_NON_CONFORMING_WCSTOK + return wcstok(_String,_Delimiters); +#else + return wcstok(_String,_Delimiters,0); +#endif +} + +#if __STDC_WANT_SECURE_LIB__ +__inline wchar_t * _wcstok_s_l(_Inout_opt_z_ wchar_t * _String, _In_z_ const wchar_t * _Delimiters, _Inout_ _Deref_prepost_opt_z_ wchar_t **_Current_position, _In_opt_ _locale_t _Locale) +{ + _CRT_UNUSED(_Locale); + return wcstok_s(_String, _Delimiters, _Current_position); +} +#endif /* __STDC_WANT_SECURE_LIB__ */ + +_Check_return_wat_ __inline errno_t _wcsnset_s_l(_Inout_updates_z_(_Destination_size_chars) wchar_t * _Destination, _In_ size_t _Destination_size_chars, _In_ wchar_t _Value, _In_ size_t _Count, _In_opt_ _locale_t _Locale) +{ + _CRT_UNUSED(_Locale); + return _wcsnset_s(_Destination, _Destination_size_chars, _Value, _Count); +} + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_3(errno_t, _wcsnset_s_l, _Prepost_z_ wchar_t, _Dest, _In_ wchar_t, _Value, _In_ size_t, _Count, _In_opt_ _locale_t, _Locale) + +__DECLARE_CPP_OVERLOAD_INLINE_NFUNC_0_3_EX(wchar_t *, __RETURN_POLICY_DST, _wcsnset_l, _wcsnset_s_l, _Inout_updates_z_(_Size) wchar_t, _Inout_updates_z_(_MaxCount) wchar_t, _Dst, _In_ wchar_t, _Value, _In_ size_t, _MaxCount, _In_opt_ _locale_t, _Locale) +{ + _CRT_UNUSED(_Locale); + return _wcsnset(_Dst, _Value, _MaxCount); +} + +__DEFINE_CPP_OVERLOAD_INLINE_NFUNC_0_3_EX(wchar_t *, __RETURN_POLICY_DST, _wcsnset_l, _wcsnset_s_l, _Inout_updates_z_(_Size) wchar_t, _Inout_updates_z_(_MaxCount), wchar_t, _Dst, _In_ wchar_t, _Value, _In_ size_t, _MaxCount, _In_opt_ _locale_t, _Locale) + +_Check_return_wat_ __inline errno_t _wcsset_s_l(_Inout_updates_z_(_Destination_size_chars) wchar_t * _Destination, _In_ size_t _Destination_size_chars, _In_ wchar_t _Value, _In_opt_ _locale_t _Locale) +{ + _CRT_UNUSED(_Locale); + return _wcsset_s(_Destination, _Destination_size_chars, _Value); +} + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2(errno_t, _wcsset_s_l, _Prepost_z_ wchar_t, _Dest, _In_ wchar_t, _Value, _In_opt_ _locale_t, _Locale) + +__DECLARE_CPP_OVERLOAD_INLINE_FUNC_0_2_EX(wchar_t *, __RETURN_POLICY_DST, _wcsset_l, _wcsset_s_l, _Inout_updates_z_(_Size) wchar_t, _Inout_z_ wchar_t, _Dst, _In_ wchar_t, _Value, _In_opt_ _locale_t, _Locale) +{ + _CRT_UNUSED(_Locale); + return _wcsset(_Dst, _Value); +} + +__DEFINE_CPP_OVERLOAD_INLINE_FUNC_0_2_EX(wchar_t *, __RETURN_POLICY_DST, _wcsset_l, _wcsset_s_l, _Inout_updates_z_(_Size) wchar_t, _Inout_z_, wchar_t, _Dst, _In_ wchar_t, _Value, _In_opt_ _locale_t, _Locale) + +#endif /* __STDC__ || defined (_NO_INLINING) */ + +#else /* _UNICODE */ + +/* ++++++++++++++++++++ SBCS and MBCS ++++++++++++++++++++ */ + +#ifdef __cplusplus +} /* ... extern "C" */ +#endif /* __cplusplus */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +#define _TEOF EOF + +#define __T(x) x + + +/* Program */ + +#define _tmain main +#define _tWinMain WinMain +#define _tenviron _environ +#define __targv __argv + + +/* Formatted i/o */ + +#define _tprintf printf +#define _tprintf_l _printf_l +#define _tprintf_s printf_s +#define _tprintf_s_l _printf_s_l +#define _tprintf_p _printf_p +#define _tprintf_p_l _printf_p_l +#define _tcprintf _cprintf +#define _tcprintf_l _cprintf_l +#define _tcprintf_s _cprintf_s +#define _tcprintf_s_l _cprintf_s_l +#define _tcprintf_p _cprintf_p +#define _tcprintf_p_l _cprintf_p_l +#define _vtcprintf _vcprintf +#define _vtcprintf_l _vcprintf_l +#define _vtcprintf_s _vcprintf_s +#define _vtcprintf_s_l _vcprintf_s_l +#define _vtcprintf_p _vcprintf_p +#define _vtcprintf_p_l _vcprintf_p_l +#define _ftprintf fprintf +#define _ftprintf_l _fprintf_l +#define _ftprintf_s fprintf_s +#define _ftprintf_s_l _fprintf_s_l +#define _ftprintf_p _fprintf_p +#define _ftprintf_p_l _fprintf_p_l +#define _stprintf sprintf +#define _stprintf_l _sprintf_l +#define _stprintf_s sprintf_s +#define _stprintf_s_l _sprintf_s_l +#define _stprintf_p _sprintf_p +#define _stprintf_p_l _sprintf_p_l +#define _sctprintf _scprintf +#define _sctprintf_l _scprintf_l +#define _sctprintf_p _scprintf_p +#define _sctprintf_p_l _scprintf_p_l +#define _sntprintf _snprintf +#define _sntprintf_l _snprintf_l +#define _sntprintf_s _snprintf_s +#define _sntprintf_s_l _snprintf_s_l +#define _vtprintf vprintf +#define _vtprintf_l _vprintf_l +#define _vtprintf_s vprintf_s +#define _vtprintf_s_l _vprintf_s_l +#define _vtprintf_p _vprintf_p +#define _vtprintf_p_l _vprintf_p_l +#define _vftprintf vfprintf +#define _vftprintf_l _vfprintf_l +#define _vftprintf_s vfprintf_s +#define _vftprintf_s_l _vfprintf_s_l +#define _vftprintf_p _vfprintf_p +#define _vftprintf_p_l _vfprintf_p_l +#define _vstprintf vsprintf +#define _vstprintf_l _vsprintf_l +#define _vstprintf_s vsprintf_s +#define _vstprintf_s_l _vsprintf_s_l +#define _vstprintf_p _vsprintf_p +#define _vstprintf_p_l _vsprintf_p_l +#define _vsctprintf _vscprintf +#define _vsctprintf_l _vscprintf_l +#define _vsctprintf_p _vscprintf_p +#define _vsctprintf_p_l _vscprintf_p_l +#define _vsntprintf _vsnprintf +#define _vsntprintf_l _vsnprintf_l +#define _vsntprintf_s _vsnprintf_s +#define _vsntprintf_s_l _vsnprintf_s_l + +#define _tscanf scanf +#define _tscanf_l _scanf_l +#define _tscanf_s scanf_s +#define _tscanf_s_l _scanf_s_l +#define _tcscanf _cscanf +#define _tcscanf_l _cscanf_l +#define _tcscanf_s _cscanf_s +#define _tcscanf_s_l _cscanf_s_l +#define _ftscanf fscanf +#define _ftscanf_l _fscanf_l +#define _ftscanf_s fscanf_s +#define _ftscanf_s_l _fscanf_s_l +#define _stscanf sscanf +#define _stscanf_l _sscanf_l +#define _stscanf_s sscanf_s +#define _stscanf_s_l _sscanf_s_l +#define _sntscanf _snscanf +#define _sntscanf_l _snscanf_l +#define _sntscanf_s _snscanf_s +#define _sntscanf_s_l _snscanf_s_l +#define _vtscanf vscanf +#define _vtscanf_s vscanf_s +#define _vftscanf vfscanf +#define _vftscanf_s vfscanf_s +#define _vstscanf vsscanf +#define _vstscanf_s vsscanf_s + + +/* Unformatted i/o */ + +#define _fgettc fgetc +#define _fgettc_nolock _fgetc_nolock +#define _fgettchar _fgetchar +#define _fgetts fgets +#define _fputtc fputc +#define _fputtc_nolock _fputc_nolock +#define _fputtchar _fputchar +#define _fputts fputs +#define _cputts _cputs +#define _gettc getc +#define _gettc_nolock _getc_nolock +#define _gettch _getch +#define _gettch_nolock _getch_nolock +#define _gettche _getche +#define _gettche_nolock _getche_nolock +#define _gettchar getchar +#define _gettchar_nolock _getchar_nolock +#define _getts_s gets_s +#define _cgetts_s _cgets_s +#define _puttc putc +#define _puttc_nolock _fputc_nolock +#define _puttchar putchar +#define _puttchar_nolock _putchar_nolock +#define _puttch _putch +#define _puttch_nolock _putch_nolock +#define _putts puts +#define _ungettc ungetc +#define _ungettc_nolock _ungetc_nolock +#define _ungettch _ungetch +#define _ungettch_nolock _ungetch_nolock + +/* String conversion functions */ + +#define _tcstod strtod +#define _tcstof strtof +#define _tcstol strtol +#define _tcstold strtold +#define _tcstoll strtoll +#define _tcstoul strtoul +#define _tcstoull strtoull +#define _tcstoimax strtoimax +#define _tcstoumax strtoumax +#define _ttof atof +#define _tstof atof +#define _tstol atol +#define _tstoll atoll +#define _tstoi atoi +#define _tstoi64 _atoi64 +#define _tcstod_l _strtod_l +#define _tcstof_l _strtof_l +#define _tcstol_l _strtol_l +#define _tcstold_l _strtold_l +#define _tcstoll_l _strtoll_l +#define _tcstoul_l _strtoul_l +#define _tcstoull_l _strtoull_l +#define _tcstoimax_l _strtoimax_l +#define _tcstoumax_l _strtoumax_l +#define _tstof_l _atof_l +#define _tstol_l _atol_l +#define _tstoll_l _atoll_l +#define _tstoi_l _atoi_l +#define _tstoi64_l _atoi64_l + +#define _itot_s _itoa_s +#define _ltot_s _ltoa_s +#define _ultot_s _ultoa_s +#define _itot _itoa +#define _ltot _ltoa +#define _ultot _ultoa +#define _ttoi atoi +#define _ttol atol +#define _ttoll atoll + +#define _ttoi64 _atoi64 +#define _tcstoi64 _strtoi64 +#define _tcstoi64_l _strtoi64_l +#define _tcstoui64 _strtoui64 +#define _tcstoui64_l _strtoui64_l +#define _i64tot_s _i64toa_s +#define _ui64tot_s _ui64toa_s +#define _i64tot _i64toa +#define _ui64tot _ui64toa + +/* String functions */ + +/* Note that _mbscat, _mbscpy and _mbsdup are functionally equivalent to + strcat, strcpy and strdup, respectively. */ + +#define _tcscat strcat +#define _tcscat_s strcat_s +#define _tcscpy strcpy +#define _tcscpy_s strcpy_s +#define _tcsdup _strdup +#define _tcslen strlen +#define _tcsnlen strnlen +#define _tcsxfrm strxfrm +#define _tcsxfrm_l _strxfrm_l +#define _tcserror strerror +#define _tcserror_s strerror_s +#define __tcserror _strerror +#define __tcserror_s _strerror_s + +#ifdef _DEBUG +#define _tcsdup_dbg _strdup_dbg +#endif /* _DEBUG */ + +/* Execute functions */ + +#define _texecl _execl +#define _texecle _execle +#define _texeclp _execlp +#define _texeclpe _execlpe +#define _texecv _execv +#define _texecve _execve +#define _texecvp _execvp +#define _texecvpe _execvpe + +#define _tspawnl _spawnl +#define _tspawnle _spawnle +#define _tspawnlp _spawnlp +#define _tspawnlpe _spawnlpe +#define _tspawnv _spawnv +#define _tspawnve _spawnve +#define _tspawnvp _spawnvp +#define _tspawnvpe _spawnvpe + +#define _tsystem system + + +/* Time functions */ + +#define _tasctime asctime +#define _tctime ctime +#define _tctime32 _ctime32 +#define _tctime64 _ctime64 +#define _tstrdate _strdate +#define _tstrtime _strtime +#define _tutime _utime +#define _tutime32 _utime32 +#define _tutime64 _utime64 +#define _tcsftime strftime +#define _tcsftime_l _strftime_l + +#define _tasctime_s asctime_s +#define _tctime_s ctime_s +#define _tctime32_s _ctime32_s +#define _tctime64_s _ctime64_s +#define _tstrdate_s _strdate_s +#define _tstrtime_s _strtime_s + +/* Directory functions */ + +#define _tchdir _chdir +#define _tgetcwd _getcwd +#define _tgetdcwd _getdcwd +#define _tgetdcwd_nolock _getdcwd_nolock +#define _tmkdir _mkdir +#define _trmdir _rmdir + +#ifdef _DEBUG +#define _tgetcwd_dbg _getcwd_dbg +#define _tgetdcwd_dbg _getdcwd_dbg +#define _tgetdcwd_lk_dbg _getdcwd_lk_dbg +#endif /* _DEBUG */ + +/* Environment/Path functions */ + +#define _tfullpath _fullpath +#define _tgetenv getenv +#define _tgetenv_s getenv_s +#define _tdupenv_s _dupenv_s +#define _tmakepath _makepath +#define _tmakepath_s _makepath_s +#define _tpgmptr _pgmptr +#define _get_tpgmptr _get_pgmptr +#define _tputenv _putenv +#define _tputenv_s _putenv_s +#define _tsearchenv _searchenv +#define _tsearchenv_s _searchenv_s +#define _tsplitpath _splitpath +#define _tsplitpath_s _splitpath_s + +#ifdef _DEBUG +#define _tfullpath_dbg _fullpath_dbg +#define _tdupenv_s_dbg _dupenv_s_dbg +#endif /* _DEBUG */ + +/* Stdio functions */ + +#define _tfdopen _fdopen +#define _tfsopen _fsopen +#define _tfopen fopen +#define _tfopen_s fopen_s +#define _tfreopen freopen +#define _tfreopen_s freopen_s +#define _tperror perror +#define _tpopen _popen +#define _ttempnam _tempnam +#define _ttmpnam tmpnam +#define _ttmpnam_s tmpnam_s + +#ifdef _DEBUG +#define _ttempnam_dbg _tempnam_dbg +#endif /* _DEBUG */ + + +/* Io functions */ + +#define _tchmod _chmod +#define _tcreat _creat +#define _tfindfirst _findfirst +#define _tfindfirst32 _findfirst32 +#define _tfindfirst64 _findfirst64 +#define _tfindfirsti64 _findfirsti64 +#define _tfindfirst32i64 _findfirst32i64 +#define _tfindfirst64i32 _findfirst64i32 +#define _tfindnext _findnext +#define _tfindnext32 _findnext32 +#define _tfindnext64 _findnext64 +#define _tfindnexti64 _findnexti64 +#define _tfindnext32i64 _findnext32i64 +#define _tfindnext64i32 _findnext64i32 +#define _tmktemp _mktemp +#define _tmktemp_s _mktemp_s + +#define _topen _open +#define _taccess _access +#define _taccess_s _access_s + +#define _tremove remove +#define _trename rename +#define _tsopen _sopen +#define _tsopen_s _sopen_s +#define _tunlink _unlink + +#define _tfinddata_t _finddata_t +#define _tfinddata32_t _finddata32_t +#define _tfinddata64_t __finddata64_t +#define _tfinddatai64_t _finddatai64_t +#define _tfinddata32i64_t _finddata32i64_t +#define _tfinddata64i32_t _finddata64i32_t + +/* ctype functions */ +#define _istascii __isascii +#define _istcntrl iscntrl +#define _istcntrl_l _iscntrl_l +#define _istxdigit isxdigit +#define _istxdigit_l _isxdigit_l + +/* Stat functions */ +#define _tstat _stat +#define _tstat32 _stat32 +#define _tstat32i64 _stat32i64 +#define _tstat64 _stat64 +#define _tstat64i32 _stat64i32 +#define _tstati64 _stati64 + + +/* Setlocale functions */ + +#define _tsetlocale setlocale + + +#ifdef _MBCS + +#ifndef _CRT_USE_WINAPI_FAMILY_DESKTOP_APP +#error Multibyte Character Set (MBCS) not supported for the current WINAPI_FAMILY. +#endif /* _CRT_USE_WINAPI_FAMILY_DESKTOP_APP */ + +/* ++++++++++++++++++++ MBCS ++++++++++++++++++++ */ + +#ifdef __cplusplus +} /* ... extern "C" */ +#endif /* __cplusplus */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +#ifndef __TCHAR_DEFINED +typedef char _TCHAR; +typedef signed char _TSCHAR; +typedef unsigned char _TUCHAR; +typedef unsigned char _TXCHAR; +typedef unsigned int _TINT; +#define __TCHAR_DEFINED +#endif /* __TCHAR_DEFINED */ + +#if defined(_CRT_INTERNAL_NONSTDC_NAMES) && _CRT_INTERNAL_NONSTDC_NAMES +#ifndef _TCHAR_DEFINED +typedef char TCHAR; +typedef char * PTCHAR; +typedef unsigned char TBYTE; +typedef unsigned char * PTBYTE; +#define _TCHAR_DEFINED +#endif /* _TCHAR_DEFINED */ +#endif /* _CRT_INTERNAL_NONSTDC_NAMES */ + + +#ifdef _MB_MAP_DIRECT + +/* use mb functions directly - types must match */ + +/* String functions */ + +#define _tcschr _mbschr +#define _tcscspn _mbscspn +#define _tcsncat _mbsnbcat +#define _tcsncat_s _mbsnbcat_s +#define _tcsncat_l _mbsnbcat_l +#define _tcsncat_s_l _mbsnbcat_s_l +#define _tcsncpy _mbsnbcpy +#define _tcsncpy_s _mbsnbcpy_s +#define _tcsncpy_l _mbsnbcpy_l +#define _tcsncpy_s_l _mbsnbcpy_s_l +#define _tcspbrk _mbspbrk +#define _tcsrchr _mbsrchr +#define _tcsspn _mbsspn +#define _tcsstr _mbsstr +#define _tcstok _mbstok +#define _tcstok_s _mbstok_s +#define _tcstok_l _mbstok_l +#define _tcstok_s_l _mbstok_s_l + +#define _tcsnset _mbsnbset +#define _tcsnset_l _mbsnbset_l +#define _tcsnset_s _mbsnbset_s +#define _tcsnset_s_l _mbsnbset_s_l +#define _tcsrev _mbsrev +#define _tcsset _mbsset +#define _tcsset_s _mbsset_s +#define _tcsset_l _mbsset_l +#define _tcsset_s_l _mbsset_s_l + +#define _tcscmp _mbscmp +#define _tcsicmp _mbsicmp +#define _tcsicmp_l _mbsicmp_l +#define _tcsnccmp _mbsncmp +#define _tcsncmp _mbsnbcmp +#define _tcsncicmp _mbsnicmp +#define _tcsncicmp_l _mbsnicmp_l +#define _tcsnicmp _mbsnbicmp +#define _tcsnicmp_l _mbsnbicmp_l + +#define _tcscoll _mbscoll +#define _tcscoll_l _mbscoll_l +#define _tcsicoll _mbsicoll +#define _tcsicoll_l _mbsicoll_l +#define _tcsnccoll _mbsncoll +#define _tcsnccoll_l _mbsncoll_l +#define _tcsncoll _mbsnbcoll +#define _tcsncoll_l _mbsnbcoll_l +#define _tcsncicoll _mbsnicoll +#define _tcsncicoll_l _mbsnicoll_l +#define _tcsnicoll _mbsnbicoll +#define _tcsnicoll_l _mbsnbicoll_l + +/* "logical-character" mappings */ + +#define _tcsclen _mbslen +#define _tcscnlen _mbsnlen +#define _tcsclen_l _mbslen_l +#define _tcscnlen_l _mbsnlen_l +#define _tcsnccat _mbsncat +#define _tcsnccat_s _mbsncat_s +#define _tcsnccat_l _mbsncat_l +#define _tcsnccat_s_l _mbsncat_s_l +#define _tcsnccpy _mbsncpy +#define _tcsnccpy_s _mbsncpy_s +#define _tcsnccpy_l _mbsncpy_l +#define _tcsnccpy_s_l _mbsncpy_s_l +#define _tcsncset _mbsnset +#define _tcsncset_s _mbsnset_s +#define _tcsncset_l _mbsnset_l +#define _tcsncset_s_l _mbsnset_s_l + +/* MBCS-specific mappings */ + +#define _tcsdec _mbsdec +#define _tcsinc _mbsinc +#define _tcsnbcnt _mbsnbcnt +#define _tcsnccnt _mbsnccnt +#define _tcsnextc _mbsnextc +#define _tcsninc _mbsninc +#define _tcsspnp _mbsspnp + +#define _tcslwr _mbslwr +#define _tcslwr_l _mbslwr_l +#define _tcslwr_s _mbslwr_s +#define _tcslwr_s_l _mbslwr_s_l +#define _tcsupr _mbsupr +#define _tcsupr_l _mbsupr_l +#define _tcsupr_s _mbsupr_s +#define _tcsupr_s_l _mbsupr_s_l + +#define _tclen _mbclen +#define _tccpy _mbccpy +#define _tccpy_l _mbccpy_l +#define _tccpy_s _mbccpy_s +#define _tccpy_s_l _mbccpy_s_l + +#else /* _MB_MAP_DIRECT */ + +#if __STDC__ || defined _NO_INLINING + +/* use type-safe linked-in function thunks */ + +/* String functions */ + +_Check_return_ _ACRTIMP _CONST_RETURN char * __cdecl _tcschr(_In_z_ const char * _Str, _In_ unsigned int _Val); +_Check_return_ _ACRTIMP size_t __cdecl _tcscspn(_In_z_ const char * _Str, _In_z_ const char * _Control); +_CRT_INSECURE_DEPRECATE(_tcsncat_s) _ACRTIMP char * __cdecl _tcsncat(_Inout_updates_z_(_MaxCount) char *_Dst, _In_z_ const char *_Src, _In_ size_t _MaxCount); +_ACRTIMP char * __cdecl _tcsncat_s(_Inout_updates_z_(_DstSizeInChars) char *_Dst, _In_ size_t _DstSizeInChars, _In_z_ const char *_Src, size_t _MaxCount); +_CRT_INSECURE_DEPRECATE(_tcsncat_s_l) _ACRTIMP char * __cdecl _tcsncat_l(_Inout_updates_z_(_MaxCount) char *_Dst, _In_z_ const char *_Src, _In_ size_t _MaxCount, _In_opt_ _locale_t _Locale); +_ACRTIMP char * __cdecl _tcsncat_s_l(_Inout_updates_z_(_DstSizeInChars) char *_Dst, _In_ size_t _DstSizeInChars, _In_z_ const char *_Src, _In_ size_t _MaxCount, _In_opt_ _locale_t _Locale); +_CRT_INSECURE_DEPRECATE(_tcsncpy_s) _ACRTIMP char * __cdecl _tcsncpy(_Out_writes_(_MaxCount) _Post_maybez_ char *_Dst, _In_z_ const char *_Src, size_t _MaxCount); +_ACRTIMP char * __cdecl _tcsncpy_s(_Out_writes_(_DstSizeInChars) char *_Dst, _In_ size_t _DstSizeInChars, _In_z_ const char *_Src, size_t _MaxCount); +_CRT_INSECURE_DEPRECATE(_tcsncpy_s_l) _ACRTIMP char * __cdecl _tcsncpy_l(_Out_writes_(_MaxCount) _Post_maybez_ char *_Dst, _In_z_ const char *_Src, _In_ size_t _MaxCount, _In_opt_ _locale_t _Locale); +_ACRTIMP char * __cdecl _tcsncpy_s_l(_Out_writes_(_DstSizeInChars) char *_Dst, _In_ size_t _DstSizeInChars, _In_z_ const char *_Src, _In_ size_t _MaxCount, _In_opt_ _locale_t _Locale); +_Check_return_ _ACRTIMP _CONST_RETURN char * __cdecl _tcspbrk(_In_z_ const char * _Str, _In_z_ const char * _Control); +_Check_return_ _ACRTIMP _CONST_RETURN char * __cdecl _tcsrchr(_In_z_ const char * _Str, _In_ unsigned int _Ch); +_Check_return_ _ACRTIMP size_t __cdecl _tcsspn(_In_z_ const char * _Str, _In_z_ const char * _Control); +_Check_return_ _ACRTIMP _CONST_RETURN char * __cdecl _tcsstr(_In_z_ const char * _Str, _In_z_ const char * _Substr); +_Check_return_ _CRT_INSECURE_DEPRECATE(_tcstok_s) _ACRTIMP char * __cdecl _tcstok(_Inout_opt_ char *_Str, _In_z_ const char *_Delim); +_Check_return_ _ACRTIMP char * __cdecl _tcstok_s(_Inout_opt_ char *_Str, _In_z_ const char *_Delim, _Inout_ _Deref_prepost_opt_z_ char **_Context); +_Check_return_ _CRT_INSECURE_DEPRECATE(_tcstok_s_l) _ACRTIMP char * __cdecl _tcstok_l(_Inout_opt_ char *_Str, _In_z_ const char *_Delim, _In_opt_ _locale_t _Locale); +_Check_return_ _ACRTIMP char * __cdecl _tcstok_s_l(_Inout_opt_ char *_Str, _In_z_ const char *_Delim, _Inout_ _Deref_prepost_opt_z_ char **_Context, _In_opt_ _locale_t _Locale); + +_CRT_INSECURE_DEPRECATE(_tcsnset_s) _ACRTIMP char * __cdecl _tcsnset(_Inout_z_ char * _Str, _In_ unsigned int _Val, _In_ size_t _MaxCount); +_Check_return_wat_ _ACRTIMP errno_t __cdecl _tcsnset_s(_Inout_updates_z_(_SizeInChars) char * _Str, _In_ size_t _SizeInChars, _In_ unsigned int _Val , _In_ size_t _MaxCount); +_CRT_INSECURE_DEPRECATE(_tcsnset_s_l) _ACRTIMP char * __cdecl _tcsnset_l(_Inout_z_ char * _Str, _In_ unsigned int _Val, _In_ size_t _MaxCount, _In_opt_ _locale_t _Locale); +_Check_return_wat_ _ACRTIMP errno_t __cdecl _tcsnset_s_l(_Inout_updates_z_(_SizeInChars) char * _Str, _In_ size_t _SizeInChars, _In_ unsigned int _Val , _In_ size_t _MaxCount, _In_opt_ _locale_t _Locale); +_ACRTIMP char * __cdecl _tcsrev(_Inout_z_ char * _Str); +_CRT_INSECURE_DEPRECATE(_tcsset_s) _ACRTIMP char * __cdecl _tcsset(_Inout_z_ char * _Str, _In_ unsigned int _Val); +_CRT_INSECURE_DEPRECATE(_tcsset_s_l) _ACRTIMP char * __cdecl _tcsset_l(_Inout_z_ char * _Str, _In_ unsigned int _Val, _In_opt_ _locale_t _Locale); +_Check_return_wat_ _ACRTIMP errno_t __cdecl _tcsset_s(_Inout_updates_z_(_SizeInChars) char * _Str, _In_ size_t _SizeInChars, _In_ unsigned int _Val); +_Check_return_wat_ _ACRTIMP errno_t __cdecl _tcsset_s_l(_Inout_updates_z_(_SizeInChars) char * _Str, _In_ size_t _SizeInChars, _In_ unsigned int, _In_opt_ _locale_t _Locale); + +_Check_return_ _ACRTIMP int __cdecl _tcscmp(_In_z_ const char *_Str1, _In_z_ const char * _Str); +_Check_return_ _ACRTIMP int __cdecl _tcsicmp(_In_z_ const char *_Str1, _In_z_ const char *_Str2); +_Check_return_ _ACRTIMP int __cdecl _tcsicmp_l(_In_z_ const char *_Str1, _In_z_ const char *_Str2, _In_opt_ _locale_t _Locale); +_Check_return_ _ACRTIMP int __cdecl _tcsnccmp(_In_z_ const char * _Str1, _In_z_ const char * _Str2, _In_ size_t _MaxCount); +_Check_return_ _ACRTIMP int __cdecl _tcsncmp(_In_z_ const char * _Str1, _In_z_ const char * _Str2, _In_ size_t _MaxCount); +_Check_return_ _ACRTIMP int __cdecl _tcsncicmp(_In_z_ const char * _Str1, _In_z_ const char * _Str2, _In_ size_t _MaxCount); +_Check_return_ _ACRTIMP int __cdecl _tcsncicmp_l(_In_z_ const char *_Str1, _In_z_ const char *_Str2, _In_ size_t _MaxCount, _In_opt_ _locale_t _Locale); +_Check_return_ _ACRTIMP int __cdecl _tcsnicmp(_In_z_ const char * _Str1, _In_z_ const char * _Str2, _In_ size_t _MaxCount); +_Check_return_ _ACRTIMP int __cdecl _tcsnicmp_l(_In_z_ const char *_Str1, _In_z_ const char *_Str2, size_t _MaxCount, _In_opt_ _locale_t _Locale); + +_Check_return_ _ACRTIMP int __cdecl _tcscoll(_In_z_ const char * _Str1, _In_z_ const char * _Str2); +_Check_return_ _ACRTIMP int __cdecl _tcscoll_l(_In_z_ const char *_Str1, _In_z_ const char *_Str2, _In_opt_ _locale_t _Locale); +_Check_return_ _ACRTIMP int __cdecl _tcsicoll(_In_z_ const char * _Str1, _In_z_ const char * _Str2); +_Check_return_ _ACRTIMP int __cdecl _tcsicoll_l(_In_z_ const char *_Str1, _In_z_ const char *_Str2, _In_opt_ _locale_t _Locale); +_Check_return_ _ACRTIMP int __cdecl _tcsnccoll(_In_z_ const char * _Str1, _In_z_ const char * _Str2, _In_ size_t _MaxCount); +_Check_return_ _ACRTIMP int __cdecl _tcsnccoll_l(_In_z_ const char *_Str1, _In_z_ const char *_Str2, _In_ size_t _MaxCount, _In_opt_ _locale_t _Locale); +_Check_return_ _ACRTIMP int __cdecl _tcsncoll(_In_z_ const char *_Str1, _In_z_ const char * _Str2, _In_ size_t _MaxCount); +_Check_return_ _ACRTIMP int __cdecl _tcsncoll_l(_In_z_ const char *_Str1, _In_z_ const char *_Str2, size_t _MaxCount, _In_opt_ _locale_t _Locale); +_Check_return_ _ACRTIMP int __cdecl _tcsncicoll(_In_z_ const char * _Str1, _In_z_ const char * _Str2, _In_ size_t _MaxCount); +_Check_return_ _ACRTIMP int __cdecl _tcsncicoll_l(_In_z_ const char *_Str1, _In_z_ const char *_Str2, _In_ size_t _MaxCount, _In_opt_ _locale_t _Locale); +_Check_return_ _ACRTIMP int __cdecl _tcsnicoll(_In_z_ const char * _Str1, _In_z_ const char * _Str2, _In_ size_t _MaxCount); +_Check_return_ _ACRTIMP int __cdecl _tcsnicoll_l(_In_z_ const char *_Str1, _In_z_ const char *_Str2, _In_ size_t _MaxCount, _In_opt_ _locale_t _Locale); + +/* "logical-character" mappings */ + +_Post_satisfies_(return <= _String_length_(_Str)) +_Check_return_ _ACRTIMP size_t __cdecl _tcsclen(_In_z_ const char *_Str); + +_Post_satisfies_(return <= _String_length_(_Str) && return <= _MaxCount) +_Check_return_ _ACRTIMP size_t __cdecl _tcscnlen(_In_z_ const char *_Str, _In_ size_t _MaxCount); + +_Post_satisfies_(return <= _String_length_(_Str)) +_Check_return_ _ACRTIMP size_t __cdecl _tcsclen_l(_In_z_ const char *_Str, _In_opt_ _locale_t _Locale); + +_Post_satisfies_(return <= _String_length_(_Str) && return <= _MaxCount) +_Check_return_ _ACRTIMP size_t __cdecl _tcscnlen_l(_In_z_ const char *_Str, _In_ size_t _MaxCount, _In_opt_ _locale_t _Locale); + +_CRT_INSECURE_DEPRECATE(_tcsnccat_s) _ACRTIMP char * __cdecl _tcsnccat(_Inout_ char *_Dst, _In_z_ const char *_Src, _In_ size_t _MaxCount); +_ACRTIMP char * __cdecl _tcsnccat_s(_Inout_updates_z_(_DstSizeInChars) char *_Dst, _In_ size_t _DstSizeInChars, _In_z_ const char *_Src, _In_ size_t _MaxCount); +_CRT_INSECURE_DEPRECATE(_tcsnccat_s_l) _ACRTIMP char * __cdecl _tcsnccat_l(_Inout_ char *_Dst, _In_z_ const char *_Src, _In_ size_t _MaxCount, _In_opt_ _locale_t _Locale); +_ACRTIMP char * __cdecl _tcsnccat_s_l(_Inout_updates_z_(_DstSizeInChars) char *_Dst, _In_ size_t _DstSizeInChars, _In_z_ const char *_Src, _In_ size_t _MaxCount, _In_opt_ _locale_t _Locale); +_CRT_INSECURE_DEPRECATE(_tcsnccpy_s) _ACRTIMP char * __cdecl _tcsnccpy(_Out_writes_(_MaxCount) _Post_maybez_ char *_Dst, _In_z_ const char *_Src, _In_ size_t _MaxCount); +_ACRTIMP char * __cdecl _tcsnccpy_s(_Out_writes_(_DstSizeInChars) char *_Dst, _In_ size_t _DstSizeInChars, _In_z_ const char *_Src, _In_ size_t _MaxCount); +_CRT_INSECURE_DEPRECATE(_tcsnccpy_s_l) _ACRTIMP char * __cdecl _tcsnccpy_l(_Out_writes_(_MaxCount) _Post_maybez_ char *_Dst, _In_z_ const char *_Src, _In_ size_t _MaxCount, _In_opt_ _locale_t _Locale); +_ACRTIMP char * __cdecl _tcsnccpy_s_l(_Out_writes_(_DstSizeInChars) char *_Dst, _In_ size_t _DstSizeInChars, _In_z_ const char *_Src, _In_ size_t _MaxCount, _In_opt_ _locale_t _Locale); +_CRT_INSECURE_DEPRECATE(_tcsncset_s) _ACRTIMP char * __cdecl _tcsncset(_Inout_updates_z_(_MaxCount) char * _Str, _In_ unsigned int _Val, _In_ size_t _MaxCount); +_ACRTIMP char * __cdecl _tcsncset_s(_Inout_updates_z_(_SizeInChars) char * _Str, _In_ size_t _SizeInChars, _In_ unsigned int _Val, _In_ size_t _MaxCount); +_CRT_INSECURE_DEPRECATE(_tcsncset_s_l) _ACRTIMP char * __cdecl _tcsncset_l(_Inout_updates_z_(_MaxCount) char * _Str, _In_ unsigned int _Val, _In_ size_t _MaxCount, _In_opt_ _locale_t _Locale); +_ACRTIMP char * __cdecl _tcsncset_s_l(_Inout_updates_z_(_SizeInChars) char * _Str, _In_ size_t _SizeInChars, _In_ unsigned int _Val, _In_ size_t _MaxCount, _In_opt_ _locale_t _Locale); + +/* MBCS-specific mappings */ + +_ACRTIMP char * __cdecl _tcsdec(_In_reads_z_(_Pos-_Start+1) const char * _Start, _In_z_ const char * _Pos); +_ACRTIMP char * __cdecl _tcsinc(_In_z_ const char * _Ptr); +_ACRTIMP size_t __cdecl _tcsnbcnt(_In_reads_or_z_(_MaxCount) const char * _Str, _In_ size_t _MaxCount); +_ACRTIMP size_t __cdecl _tcsnccnt(_In_reads_or_z_(_MaxCount) const char * _Str, _In_ size_t _MaxCount); +_ACRTIMP unsigned int __cdecl _tcsnextc (_In_z_ const char * _Str); +_ACRTIMP char * __cdecl _tcsninc(_In_reads_or_z_(_Count) const char * _Ptr, _In_ size_t _Count); +_ACRTIMP char * __cdecl _tcsspnp(_In_z_ const char * _Str1, _In_z_ const char * _Str2); + +_CRT_INSECURE_DEPRECATE(_tcslwr_s) _ACRTIMP char * __cdecl _tcslwr(_Inout_ char *_Str); +_CRT_INSECURE_DEPRECATE(_tcslwr_s_l) _ACRTIMP char * __cdecl _tcslwr_l(_Inout_ char *_Str, _In_opt_ _locale_t _Locale); +_ACRTIMP char * __cdecl _tcslwr_s(_Inout_updates_z_(_SizeInChars) char *_Str, _In_ size_t _SizeInChars); +_ACRTIMP char * __cdecl _tcslwr_s_l(_Inout_updates_z_(_SizeInChars) char *_Str, _In_ size_t _SizeInChars, _In_opt_ _locale_t _Locale); +_CRT_INSECURE_DEPRECATE(_tcsupr_s) _ACRTIMP char * __cdecl _tcsupr(_Inout_ char *_Str); +_CRT_INSECURE_DEPRECATE(_tcsupr_s_l) _ACRTIMP char * __cdecl _tcsupr_l(_Inout_ char *_Str, _In_opt_ _locale_t _Locale); +_ACRTIMP char * __cdecl _tcsupr_s(_Inout_updates_z_(_SizeInChars) char *_Str, _In_ size_t _SizeInChars); +_ACRTIMP char * __cdecl _tcsupr_s_l(_Inout_updates_z_(_SizeInChars) char *_Str, _In_ size_t _SizeInChars, _In_opt_ _locale_t _Locale); + +_Check_return_ _ACRTIMP size_t __cdecl _tclen(_In_z_ const char * _Str); +_CRT_INSECURE_DEPRECATE(_tccpy_s) _ACRTIMP void __cdecl _tccpy(_Pre_notnull_ _Post_z_ char * _DstCh, _In_z_ const char * _SrcCh); +_CRT_INSECURE_DEPRECATE(_tccpy_s_l) _ACRTIMP void __cdecl _tccpy_l(_Pre_notnull_ _Post_z_ char * _DstCh, _In_z_ const char * _SrcCh, _In_opt_ _locale_t _Locale); +_Check_return_wat_ _ACRTIMP errno_t __cdecl _tccpy_s(_Out_writes_z_(_SizeInBytes) char * _DstCh, size_t _SizeInBytes, _Out_opt_ int *_PCopied, _In_z_ const char * _SrcCh); +_Check_return_wat_ _ACRTIMP errno_t __cdecl _tccpy_s_l(_Out_writes_z_(_SizeInBytes) char * _DstCh, size_t _SizeInBytes, _Out_opt_ int *_PCopied, _In_z_ const char * _SrcCh, _In_opt_ _locale_t _Locale); + +#else /* __STDC__ || defined (_NO_INLINING) */ + +/* the default: use type-safe inline function thunks */ + +#define _PUC unsigned char * +#define _CPUC const unsigned char * +#define _PC char * +#define _CRPC _CONST_RETURN char * +#define _CPC const char * +#define _UI unsigned int + + +/* String functions */ + +__inline _CRPC _tcschr(_In_z_ _CPC _s1,_In_ _UI _c) {return (_CRPC)_mbschr((_CPUC)_s1,_c);} +__inline size_t _tcscspn(_In_z_ _CPC _s1,_In_z_ _CPC _s2) {return _mbscspn((_CPUC)_s1,(_CPUC)_s2);} + +_Check_return_wat_ __inline errno_t _tcsncat_s(_Inout_updates_z_(_Destination_size_chars) char *_Destination, _In_ size_t _Destination_size_chars, _In_z_ const char *_Source, _In_ size_t _Count) +{ + return _mbsnbcat_s((unsigned char *)_Destination, _Destination_size_chars, (const unsigned char *)_Source,_Count); +} + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2(errno_t, _tcsncat_s, _Prepost_z_ char, _Dest, _In_z_ const char *, _Source, _In_ size_t, _Count) + +__DECLARE_CPP_OVERLOAD_INLINE_NFUNC_0_2_EX(char *, __RETURN_POLICY_DST, _tcsncat, _tcsncat_s, _Inout_updates_z_(_Size) char, _Inout_z_ char, _Dst, _In_z_ const char *, _Source, _In_ size_t, _Count) +{ + return (char *)_mbsnbcat((unsigned char *)_Dst,(const unsigned char *)_Source,_Count); +} + +__DEFINE_CPP_OVERLOAD_INLINE_NFUNC_0_2_EX(char *, __RETURN_POLICY_DST, _tcsncat, _tcsncat_s, _Inout_updates_z_(_Size) char, _Inout_z_, char, _Dst, _In_z_ const char *, _Source, _In_ size_t, _Count) + +_Check_return_wat_ __inline errno_t _tcsncat_s_l(_Inout_updates_z_(_Destination_size_chars) char *_Destination, _In_ size_t _Destination_size_chars, _In_z_ const char *_Source, _In_ size_t _Count, _In_opt_ _locale_t _Locale) +{ + return _mbsnbcat_s_l((unsigned char *)_Destination, _Destination_size_chars, (const unsigned char *)_Source,_Count, _Locale); +} + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_3(errno_t, _tcsncat_s_l, _Prepost_z_ char, _Dest, _In_z_ const char *, _Source, _In_ size_t, _Count, _In_opt_ _locale_t, _Locale) + +__DECLARE_CPP_OVERLOAD_INLINE_NFUNC_0_3_EX(char *, __RETURN_POLICY_DST, _tcsncat_l, _tcsncat_s_l, _Inout_updates_z_(_Size) char, _Inout_z_ char, _Dst, _In_z_ const char *, _Source, _In_ size_t, _Count, _In_opt_ _locale_t, _Locale) +{ + return (char *)_mbsnbcat_l((unsigned char *)_Dst,(const unsigned char *)_Source,_Count, _Locale); +} + +__DEFINE_CPP_OVERLOAD_INLINE_NFUNC_0_3_EX(char *, __RETURN_POLICY_DST, _tcsncat_l, _tcsncat_s_l, _Inout_updates_z_(_Size) char, _Inout_z_, char, _Dst, _In_z_ const char *, _Source, _In_ size_t, _Count, _In_opt_ _locale_t, _Locale) + +_Check_return_wat_ __inline errno_t _tcsncpy_s(_Out_writes_z_(_Destination_size_chars) char * _Destination, _In_ size_t _Destination_size_chars, _In_z_ const char * _Source,_In_ size_t _Count) +{ + return _mbsnbcpy_s((unsigned char *)_Destination, _Destination_size_chars, (const unsigned char *)_Source,_Count); +} + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2(errno_t, _tcsncpy_s, _Post_z_ char, _Dest, _In_z_ const char *, _Source, _In_ size_t, _Count) + +__DECLARE_CPP_OVERLOAD_INLINE_NFUNC_0_2_EX(_Success_(return != 0) char *, __RETURN_POLICY_DST, _tcsncpy, _tcsncpy_s, _Out_writes_bytes_(_Count) _Post_maybez_ char, _Out_writes_bytes_(_Count) _Post_maybez_ char, _Dst, _In_z_ const char *, _Source, _In_ size_t, _Count) +{ + return (char *)_mbsnbcpy((unsigned char *)_Dst,(const unsigned char *)_Source,_Count); +} + +__DEFINE_CPP_OVERLOAD_INLINE_NFUNC_0_2_EX(char *, __RETURN_POLICY_DST, _tcsncpy, _tcsncpy_s, _Out_writes_z_(_Size) char, _Inout_z_, char, _Dst, _In_z_ const char *, _Source, _In_ size_t, _Count) + +_Check_return_wat_ __inline errno_t _tcsncpy_s_l(_Out_writes_z_(_Destination_size_chars) char * _Destination, _In_ size_t _Destination_size_chars, _In_z_ const char * _Source,_In_ size_t _Count, _In_opt_ _locale_t _Locale) +{ + return _mbsnbcpy_s_l((unsigned char *)_Destination, _Destination_size_chars, (const unsigned char *)_Source,_Count, _Locale); +} + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_3(errno_t, _tcsncpy_s_l, _Post_z_ char, _Dest, _In_z_ const char *, _Source, _In_ size_t, _Count, _In_opt_ _locale_t, _Locale) + +__DECLARE_CPP_OVERLOAD_INLINE_NFUNC_0_3_EX(char *, __RETURN_POLICY_DST, _tcsncpy_l, _tcsncpy_s_l, _Out_writes_z_(_Size) char, _Out_writes_bytes_(_Count) _Post_maybez_ char, _Dst, _In_z_ const char *, _Source, _In_ size_t, _Count, _In_opt_ _locale_t, _Locale) +{ + return (char *)_mbsnbcpy_l((unsigned char *)_Dst,(const unsigned char *)_Source,_Count, _Locale); +} + +__DEFINE_CPP_OVERLOAD_INLINE_NFUNC_0_3_EX(char *, __RETURN_POLICY_DST, _tcsncpy_l, _tcsncpy_s_l, _Out_writes_z_(_Size) char, _Out_writes_z_(_Count), char, _Dst, _In_z_ const char *, _Source, _In_ size_t, _Count, _In_opt_ _locale_t, _Locale) + +_Check_return_ __inline _CRPC _tcspbrk(_In_z_ _CPC _s1,_In_z_ _CPC _s2) {return (_CRPC)_mbspbrk((_CPUC)_s1,(_CPUC)_s2);} +_Check_return_ __inline _CRPC _tcsrchr(_In_z_ _CPC _s1,_In_ _UI _c) {return (_CRPC)_mbsrchr((_CPUC)_s1,_c);} +_Check_return_ __inline size_t _tcsspn(_In_z_ _CPC _s1,_In_z_ _CPC _s2) {return _mbsspn((_CPUC)_s1,(_CPUC)_s2);} +_Check_return_ __inline _CRPC _tcsstr(_In_z_ _CPC _s1,_In_z_ _CPC _s2) {return (_CRPC)_mbsstr((_CPUC)_s1,(_CPUC)_s2);} + +_Check_return_ _CRT_INSECURE_DEPRECATE(_tcstok_s) __inline char * _tcstok(_Inout_opt_z_ char * _String,_In_z_ const char * _Delimiters) +{ + return (char * )_mbstok((unsigned char *)_String,(const unsigned char *)_Delimiters); +} + +_Check_return_ __inline char * _tcstok_s(_Inout_opt_z_ char * _String,_In_z_ const char * _Delimiters, _Inout_ _Deref_prepost_opt_z_ char **_Current_position) +{ + return (char * )_mbstok_s((unsigned char *)_String,(const unsigned char *)_Delimiters, (unsigned char **)_Current_position); +} + +_Check_return_ _CRT_INSECURE_DEPRECATE(_tcstok_s_l) __inline char * _tcstok_l(_Inout_opt_z_ char * _String,_In_z_ const char * _Delimiters, _In_opt_ _locale_t _Locale) +{ + return (char * )_mbstok_l((unsigned char *)_String,(const unsigned char *)_Delimiters, _Locale); +} + +_Check_return_ __inline char * _tcstok_s_l(_Inout_opt_z_ char * _String,_In_z_ const char * _Delimiters, _Inout_ _Deref_prepost_opt_z_ char **_Current_position, _In_opt_ _locale_t _Locale) +{ + return (char * )_mbstok_s_l((unsigned char *)_String,(const unsigned char *)_Delimiters, (unsigned char **)_Current_position, _Locale); +} + +_Check_return_wat_ __inline errno_t _tcsnset_s(_Inout_updates_z_(_SizeInBytes) char * _Dst, _In_ size_t _SizeInBytes, _In_ unsigned int _Value , _In_ size_t _Count) +{ + return _mbsnbset_s((unsigned char *)_Dst, _SizeInBytes, _Value, _Count); +} + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2(errno_t, _tcsnset_s, _Prepost_z_ char, _Dest, _In_ unsigned int, _Value , _In_ size_t, _Count) + +__DECLARE_CPP_OVERLOAD_INLINE_NFUNC_0_2_EX(char *, __RETURN_POLICY_DST, _tcsnset, _tcsnset_s, _Inout_updates_z_(_Size) char, _Inout_updates_z_(_Count) char, _Dst, _In_ unsigned int, _Value , _In_ size_t, _Count) +{ + return (char *)_mbsnbset((unsigned char *)_Dst, _Value, _Count); +} + +__DEFINE_CPP_OVERLOAD_INLINE_NFUNC_0_2_EX(char *, __RETURN_POLICY_DST, _tcsnset, _tcsnset_s, _Inout_updates_z_(_Size) char, _Inout_updates_z_(_Count), char, _Dst, _In_ unsigned int, _Value , _In_ size_t, _Count) + +_Check_return_wat_ __inline errno_t _tcsnset_s_l(_Inout_updates_z_(_SizeInBytes) char * _Dst, _In_ size_t _SizeInBytes, _In_ unsigned int _Value , _In_ size_t _Count, _In_opt_ _locale_t _Locale) +{ + return _mbsnbset_s_l((unsigned char *)_Dst, _SizeInBytes, _Value, _Count, _Locale); +} + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_3(errno_t, _tcsnset_s_l, _Prepost_z_ char, _Dest, _In_ unsigned int, _Value , _In_ size_t, _Count, _In_opt_ _locale_t, _Locale) + +__DECLARE_CPP_OVERLOAD_INLINE_NFUNC_0_3_EX(char *, __RETURN_POLICY_DST, _tcsnset_l, _tcsnset_s_l, _Inout_updates_z_(_Size) char, _Inout_updates_z_(_Count) char, _Dst, _In_ unsigned int, _Value , _In_ size_t, _Count, _In_opt_ _locale_t, _Locale) +{ + return (char *)_mbsnbset_l((unsigned char *)_Dst, _Value, _Count, _Locale); +} + +__DEFINE_CPP_OVERLOAD_INLINE_NFUNC_0_3_EX(char *, __RETURN_POLICY_DST, _tcsnset_l, _tcsnset_s_l, _Inout_updates_z_(_Size) char, _Inout_updates_z_(_Count), char, _Dst, _In_ unsigned int, _Value , _In_ size_t, _Count, _In_opt_ _locale_t, _Locale) + +__inline _PC _tcsrev(_Inout_z_ _PC _s1) {return (_PC)_mbsrev((_PUC)_s1);} + +_Check_return_wat_ __inline errno_t _tcsset_s(_Inout_updates_z_(_SizeInBytes) char * _Dst, _In_ size_t _SizeInBytes, _In_ unsigned int _Value) +{ + return _mbsset_s((unsigned char *)_Dst, _SizeInBytes, _Value); +} + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1(errno_t, _tcsset_s, _Prepost_z_ char, _Dest, _In_ unsigned int, _Value) + +__DECLARE_CPP_OVERLOAD_INLINE_FUNC_0_1_EX(char *, __RETURN_POLICY_DST, _tcsset, _tcsset_s, _Inout_updates_z_(_Size) char, _Inout_z_ char, _Dst, _In_ unsigned int, _Value) +{ + return (char *)_mbsset((unsigned char *)_Dst, _Value); +} + +__DEFINE_CPP_OVERLOAD_INLINE_FUNC_0_1_EX(char *, __RETURN_POLICY_DST, _tcsset, _tcsset_s, _Inout_updates_z_(_Size) char, _Inout_z_ char, _Dst, _In_ unsigned int, _Value) + +_Check_return_wat_ __inline errno_t _tcsset_s_l(_Inout_updates_z_(_SizeInBytes) char * _Dst, _In_ size_t _SizeInBytes, _In_ unsigned int _Value, _In_opt_ _locale_t _Locale) +{ + return _mbsset_s_l((unsigned char *)_Dst, _SizeInBytes, _Value, _Locale); +} + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2(errno_t, _tcsset_s_l, _Prepost_z_ char, _Dest, _In_ unsigned int, _Value, _In_opt_ _locale_t, _Locale) + +__DECLARE_CPP_OVERLOAD_INLINE_FUNC_0_2_EX(char *, __RETURN_POLICY_DST, _tcsset_l, _tcsset_s_l, _Inout_updates_z_(_Size) char, _Inout_z_ char, _Dst, _In_ unsigned int, _Value, _In_opt_ _locale_t, _Locale) +{ + return (char *)_mbsset_l((unsigned char *)_Dst, _Value, _Locale); +} + +__DEFINE_CPP_OVERLOAD_INLINE_FUNC_0_2_EX(char *, __RETURN_POLICY_DST, _tcsset_l, _tcsset_s_l, _Inout_updates_z_(_Size) char, _Inout_z_, char, _Dst, _In_ unsigned int, _Value, _In_opt_ _locale_t, _Locale) + +_Check_return_ __inline int _tcscmp(_In_z_ _CPC _s1,_In_z_ _CPC _s2) {return _mbscmp((_CPUC)_s1,(_CPUC)_s2);} + +_Check_return_ __inline int _tcsicmp(_In_z_ const char * _String1, _In_z_ const char * _String2) +{ + return _mbsicmp((const unsigned char *)_String1,(const unsigned char *)_String2); +} + +_Check_return_ __inline int _tcsicmp_l(_In_z_ const char * _String1, _In_z_ const char * _String2, _In_opt_ _locale_t _Locale) +{ + return _mbsicmp_l((const unsigned char *)_String1,(const unsigned char *)_String2, _Locale); +} + +_Check_return_ __inline int _tcsnccmp(_In_reads_or_z_(_n) _CPC _s1,_In_z_ _CPC _s2,_In_ size_t _n) {return _mbsncmp((_CPUC)_s1,(_CPUC)_s2,_n);} +__inline int _tcsncmp(_In_z_ _CPC _s1,_In_z_ _CPC _s2,_In_ size_t _n) {return _mbsnbcmp((_CPUC)_s1,(_CPUC)_s2,_n);} + +_Check_return_ __inline int _tcsncicmp(_In_z_ const char * _String1, _In_z_ const char * _String2, _In_ size_t _Char_count) +{ + return _mbsnicmp((const unsigned char *)_String1,(const unsigned char *)_String2,_Char_count); +} + +_Check_return_ __inline int _tcsncicmp_l(_In_z_ const char * _String1, _In_z_ const char * _String2, _In_ size_t _Char_count, _In_opt_ _locale_t _Locale) +{ + return _mbsnicmp_l((const unsigned char *)_String1,(const unsigned char *)_String2,_Char_count, _Locale); +} + +_Check_return_ __inline int _tcsnicmp(_In_z_ const char * _String1, _In_z_ const char * _String2, _In_ size_t _Char_count) +{ + return _mbsnbicmp((const unsigned char *)_String1,(const unsigned char *)_String2,_Char_count); +} + +_Check_return_ __inline int _tcsnicmp_l(_In_z_ const char * _String1, _In_z_ const char * _String2, _In_ size_t _Char_count, _In_opt_ _locale_t _Locale) +{ + return _mbsnbicmp_l((const unsigned char *)_String1,(const unsigned char *)_String2,_Char_count, _Locale); +} + +_Check_return_ __inline int _tcscoll(_In_z_ const char * _String1, _In_z_ const char * _String2) +{ + return _mbscoll((const unsigned char *)_String1,(const unsigned char *)_String2); +} + +_Check_return_ __inline int _tcscoll_l(_In_z_ const char * _String1, _In_z_ const char * _String2, _In_opt_ _locale_t _Locale) +{ + return _mbscoll_l((const unsigned char *)_String1,(const unsigned char *)_String2, _Locale); +} + +_Check_return_ __inline int _tcsicoll(_In_z_ const char * _String1, _In_z_ const char * _String2) +{ + return _mbsicoll((const unsigned char *)_String1,(const unsigned char *)_String2); +} + +_Check_return_ __inline int _tcsicoll_l(_In_z_ const char * _String1, _In_z_ const char * _String2, _In_opt_ _locale_t _Locale) +{ + return _mbsicoll_l((const unsigned char *)_String1,(const unsigned char *)_String2, _Locale); +} + +_Check_return_ __inline int _tcsnccoll(_In_z_ const char * _String1, _In_z_ const char * _String2, _In_ size_t _Count) +{ + return _mbsncoll((const unsigned char *)_String1,(const unsigned char *)_String2, _Count); +} + +_Check_return_ __inline int _tcsnccoll_l(_In_z_ const char * _String1, _In_z_ const char * _String2, _In_ size_t _Count, _In_opt_ _locale_t _Locale) +{ + return _mbsncoll_l((const unsigned char *)_String1,(const unsigned char *)_String2, _Count, _Locale); +} + +_Check_return_ __inline int _tcsncoll(_In_z_ const char * _String1, _In_z_ const char * _String2, _In_ size_t _Count) +{ + return _mbsnbcoll((const unsigned char *)_String1,(const unsigned char *)_String2, _Count); +} + +_Check_return_ __inline int _tcsncoll_l(_In_z_ const char * _String1, _In_z_ const char * _String2, _In_ size_t _Count, _In_opt_ _locale_t _Locale) +{ + return _mbsnbcoll_l((const unsigned char *)_String1,(const unsigned char *)_String2, _Count, _Locale); +} + +_Check_return_ __inline int _tcsncicoll(_In_z_ const char * _String1, _In_z_ const char * _String2, _In_ size_t _Count) +{ + return _mbsnicoll((const unsigned char *)_String1,(const unsigned char *)_String2, _Count); +} + +_Check_return_ __inline int _tcsncicoll_l(_In_z_ const char * _String1, _In_z_ const char * _String2, _In_ size_t _Count, _In_opt_ _locale_t _Locale) +{ + return _mbsnicoll_l((const unsigned char *)_String1,(const unsigned char *)_String2, _Count, _Locale); +} + +_Check_return_ __inline int _tcsnicoll(_In_z_ const char * _String1, _In_z_ const char * _String2, _In_ size_t _Count) +{ + return _mbsnbicoll((const unsigned char *)_String1,(const unsigned char *)_String2, _Count); +} + +_Check_return_ __inline int _tcsnicoll_l(_In_z_ const char * _String1, _In_z_ const char * _String2, _In_ size_t _Count, _In_opt_ _locale_t _Locale) +{ + return _mbsnbicoll_l((const unsigned char *)_String1,(const unsigned char *)_String2, _Count, _Locale); +} + +/* "logical-character" mappings */ +_Check_return_ __inline size_t _tcsclen(_In_z_ const char * _String) +{ + return _mbslen((const unsigned char *)_String); +} + +_Check_return_ __inline size_t _tcscnlen(_In_z_ const char * _String, _In_ size_t _Maximum) +{ + return _mbsnlen((const unsigned char *)_String, _Maximum); +} + +_Check_return_ __inline size_t _tcsclen_l(_In_z_ const char * _String, _In_opt_ _locale_t _Locale) +{ + return _mbslen_l((const unsigned char *)_String, _Locale); +} + +_Check_return_ __inline size_t _tcscnlen_l(_In_z_ const char * _String, _In_ size_t _Maximum, _In_opt_ _locale_t _Locale) +{ + return _mbsnlen_l((const unsigned char *)_String, _Maximum, _Locale); +} + +_Check_return_wat_ __inline errno_t _tcsnccat_s(_Inout_updates_z_(_Destination_size_chars) char * _Destination, _In_ size_t _Destination_size_chars, _In_z_ const char * _Source, _In_ size_t _Count) +{ + return _mbsncat_s((unsigned char *)_Destination, _Destination_size_chars, (const unsigned char *)_Source, _Count); +} + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2(errno_t, _tcsnccat_s, _Prepost_z_ char, _Dest, _In_z_ const char *, _Source, _In_ size_t, _Count) + +__DECLARE_CPP_OVERLOAD_INLINE_NFUNC_0_2_EX(char *, __RETURN_POLICY_DST, _tcsnccat, _tcsnccat_s, _Inout_updates_z_(_Size) char, _Inout_z_ char, _Dst, _In_z_ const char *, _Source, _In_ size_t, _Count) +{ + return (char *)_mbsncat((unsigned char *)_Dst,(const unsigned char *)_Source, _Count); +} + +__DEFINE_CPP_OVERLOAD_INLINE_NFUNC_0_2_EX(char *, __RETURN_POLICY_DST, _tcsnccat, _tcsnccat_s, _Inout_updates_z_(_Size) char, _Inout_z_, char, _Dst, _In_z_ const char *, _Source, _In_ size_t, _Count) + +_Check_return_wat_ __inline errno_t _tcsnccat_s_l(_Inout_updates_z_(_Destination_size_chars) char * _Destination, _In_ size_t _Destination_size_chars, _In_z_ const char * _Source, _In_ size_t _Count, _In_opt_ _locale_t _Locale) +{ + return _mbsncat_s_l((unsigned char *)_Destination, _Destination_size_chars, (const unsigned char *)_Source, _Count, _Locale); +} + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_3(errno_t, _tcsnccat_s_l, _Prepost_z_ char, _Dest, _In_z_ const char *, _Source, _In_ size_t, _Count, _In_opt_ _locale_t, _Locale) + +__DECLARE_CPP_OVERLOAD_INLINE_NFUNC_0_3_EX(char *, __RETURN_POLICY_DST, _tcsnccat_l, _tcsnccat_s_l, _Inout_updates_z_(_Size) char, _Inout_z_ char, _Dst, _In_z_ const char *, _Source, _In_ size_t, _Count, _In_opt_ _locale_t, _Locale) +{ + return (char *)_mbsncat_l((unsigned char *)_Dst,(const unsigned char *)_Source, _Count, _Locale); +} + +__DEFINE_CPP_OVERLOAD_INLINE_NFUNC_0_3_EX(char *, __RETURN_POLICY_DST, _tcsnccat_l, _tcsnccat_s_l, _Inout_updates_z_(_Size) char, _Inout_z_, char, _Dst, _In_z_ const char *, _Source, _In_ size_t, _Count, _In_opt_ _locale_t, _Locale) + +_Check_return_wat_ __inline errno_t _tcsnccpy_s(_Out_writes_z_(_Destination_size_chars) char * _Destination, _In_ size_t _Destination_size_chars, _In_z_ const char * _Source, _In_ size_t _Count) +{ + return _mbsncpy_s((unsigned char *)_Destination, _Destination_size_chars, (const unsigned char *)_Source, _Count); +} + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2(errno_t, _tcsnccpy_s, _Post_z_ char, _Dest, _In_z_ const char *, _Source, _In_ size_t, _Count) + +__DECLARE_CPP_OVERLOAD_INLINE_NFUNC_0_2_EX(char *, __RETURN_POLICY_DST, _tcsnccpy, _tcsnccpy_s, _Out_writes_bytes_(_Size) _Post_maybez_ char, _Pre_notnull_ _Post_maybez_ char, _Dst, _In_z_ const char *, _Source, _In_ size_t, _Count) +{ + return (char *)_mbsncpy((unsigned char *)_Dst,(const unsigned char *)_Source, _Count); +} + +__DEFINE_CPP_OVERLOAD_INLINE_NFUNC_0_2_EX(char *, __RETURN_POLICY_DST, _tcsnccpy, _tcsnccpy_s, _Out_writes_z_(_Size) char, _Pre_notnull_ _Post_z_, char, _Dst, _In_z_ const char *, _Source, _In_ size_t, _Count) + +_Check_return_wat_ __inline errno_t _tcsnccpy_s_l(_Out_writes_z_(_Destination_size_chars) char * _Destination, _In_ size_t _Destination_size_chars, _In_z_ const char * _Source, _In_ size_t _Count, _In_opt_ _locale_t _Locale) +{ + return _mbsncpy_s_l((unsigned char *)_Destination, _Destination_size_chars, (const unsigned char *)_Source, _Count, _Locale); +} + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_3(errno_t, _tcsnccpy_s_l, _Post_z_ char, _Dest, _In_z_ const char *, _Source, _In_ size_t, _Count, _In_opt_ _locale_t, _Locale) + +__DECLARE_CPP_OVERLOAD_INLINE_NFUNC_0_3_EX(char *, __RETURN_POLICY_DST, _tcsnccpy_l, _tcsnccpy_s_l, _Out_writes_z_(_Size) char, _Out_writes_bytes_(_Count) _Post_maybez_ char, _Dst, _In_z_ const char *, _Source, _In_ size_t, _Count, _In_opt_ _locale_t, _Locale) +{ + return (char *)_mbsncpy_l((unsigned char *)_Dst,(const unsigned char *)_Source, _Count, _Locale); +} + +__DEFINE_CPP_OVERLOAD_INLINE_NFUNC_0_3_EX(char *, __RETURN_POLICY_DST, _tcsnccpy_l, _tcsnccpy_s_l, _Out_writes_z_(_Size) char, _Out_writes_bytes_(_Count) _Post_maybez_, char, _Dst, _In_z_ const char *, _Source, _In_ size_t, _Count, _In_opt_ _locale_t, _Locale) + +_Check_return_wat_ __inline errno_t _tcsncset_s(_Inout_updates_bytes_(_SizeInBytes) char *_Destination, _In_ size_t _SizeInBytes, _In_ unsigned int _Value, _In_ size_t _Count) +{ + return _mbsnset_s((unsigned char *)_Destination, _SizeInBytes, _Value, _Count); +} + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2(errno_t, _tcsncset_s, char, _Dest, _In_ unsigned int, _Value, _In_ size_t, _Count) + +__DECLARE_CPP_OVERLOAD_INLINE_NFUNC_0_2_EX(char *, __RETURN_POLICY_DST, _tcsncset, _tcsncset_s, _Inout_updates_z_(_Size) char, _Inout_updates_bytes_(_Count) char, _Dst, _In_ unsigned int, _Value, _In_ size_t, _Count) +{ + return (char *)_mbsnset((unsigned char *)_Dst, _Value, _Count); +} + +__DEFINE_CPP_OVERLOAD_INLINE_NFUNC_0_2_EX(char *, __RETURN_POLICY_DST, _tcsncset, _tcsncset_s, _Inout_updates_z_(_Size) char, _Inout_updates_bytes_(_Count), char, _Dst, _In_ unsigned int, _Value, _In_ size_t, _Count) + +_Check_return_wat_ __inline errno_t _tcsncset_s_l(_Inout_updates_bytes_(_SizeInBytes) char *_Destination, _In_ size_t _SizeInBytes, _In_ unsigned int _Value, _In_ size_t _Count, _In_opt_ _locale_t _Locale) +{ + return _mbsnset_s_l((unsigned char *)_Destination, _SizeInBytes, _Value, _Count, _Locale); +} + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_3(errno_t, _tcsncset_s_l, char, _Dest, _In_ unsigned int, _Value, _In_ size_t, _Count, _In_opt_ _locale_t, _Locale) + +__DECLARE_CPP_OVERLOAD_INLINE_NFUNC_0_3_EX(char *, __RETURN_POLICY_DST, _tcsncset_l, _tcsncset_s_l, _Inout_updates_z_(_Size) char, _Inout_updates_bytes_(_Count) char, _Dst, _In_ unsigned int, _Value, _In_ size_t, _Count, _In_opt_ _locale_t, _Locale) +{ + return (char *)_mbsnset_l((unsigned char *)_Dst, _Value, _Count, _Locale); +} + +__DEFINE_CPP_OVERLOAD_INLINE_NFUNC_0_3_EX(char *, __RETURN_POLICY_DST, _tcsncset_l, _tcsncset_s_l, _Inout_updates_z_(_Size) char, _Inout_updates_bytes_(_Count), char, _Dst, _In_ unsigned int, _Value, _In_ size_t, _Count, _In_opt_ _locale_t, _Locale) + +/* MBCS-specific mappings */ + +_Check_return_ __inline _PC _tcsdec(_In_reads_z_(_s2 - _s1 + 1) _CPC _s1,_In_z_ _CPC _s2) {return (_PC)_mbsdec((_CPUC)_s1,(_CPUC)_s2);} +_Check_return_ __inline _PC _tcsinc(_In_z_ _CPC _s1) {return (_PC)_mbsinc((_CPUC)_s1);} +_Check_return_ __inline size_t _tcsnbcnt(_In_reads_or_z_(_n) _CPC _s1,_In_ size_t _n) {return _mbsnbcnt((_CPUC)_s1,_n);} +_Check_return_ __inline size_t _tcsnccnt(_In_reads_or_z_(_n) _CPC _s1,_In_ size_t _n) {return _mbsnccnt((_CPUC)_s1,_n);} +_Check_return_ __inline _PC _tcsninc(_In_reads_or_z_(_n) _CPC _s1,_In_ size_t _n) {return (_PC)_mbsninc((_CPUC)_s1,_n);} +_Check_return_ __inline _PC _tcsspnp(_In_z_ _CPC _s1,_In_z_ _CPC _s2) {return (_PC)_mbsspnp((_CPUC)_s1,(_CPUC)_s2);} + +_Check_return_wat_ __inline errno_t _tcslwr_s(_Inout_updates_z_(_SizeInBytes) char * _String, size_t _SizeInBytes) +{ + return _mbslwr_s((unsigned char *)_String, _SizeInBytes); +} + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_0(errno_t, _tcslwr_s, _Prepost_z_ char, _String) + +__DECLARE_CPP_OVERLOAD_INLINE_FUNC_0_0_EX(char *, __RETURN_POLICY_DST, _tcslwr, _tcslwr_s, _Inout_updates_z_(_Size) char, _Inout_z_ char, _String) +{ + return (char *)_mbslwr((unsigned char *)_String); +} + +__DEFINE_CPP_OVERLOAD_INLINE_FUNC_0_0_EX(char *, __RETURN_POLICY_DST, _tcslwr, _tcslwr_s, _Inout_updates_z_(_Size) char, _Inout_z_ char, _String) + +_Check_return_wat_ __inline errno_t _tcslwr_s_l(_Inout_updates_z_(_SizeInBytes) char * _String, _In_ size_t _SizeInBytes, _In_opt_ _locale_t _Locale) +{ + return _mbslwr_s_l((unsigned char *)_String, _SizeInBytes, _Locale); +} + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1(errno_t, _tcslwr_s_l, _Prepost_z_ char, _String, _In_opt_ _locale_t, _Locale) + +__DECLARE_CPP_OVERLOAD_INLINE_FUNC_0_1_EX(char *, __RETURN_POLICY_DST, _tcslwr_l, _tcslwr_s_l, _Inout_updates_z_(_Size) char, _Inout_z_ char, _String, _In_opt_ _locale_t, _Locale) +{ + return (char *)_mbslwr_l((unsigned char *)_String, _Locale); +} + +__DEFINE_CPP_OVERLOAD_INLINE_FUNC_0_1_EX(char *, __RETURN_POLICY_DST, _tcslwr_l, _tcslwr_s_l, _Inout_updates_z_(_Size) char, _Inout_z_ char, _String, _In_opt_ _locale_t, _Locale) + +_Check_return_wat_ __inline errno_t _tcsupr_s(_Inout_updates_z_(_Count) char * _String, _In_ size_t _Count) +{ + return _mbsupr_s((unsigned char *)_String, _Count); +} + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_0(errno_t, _tcsupr_s, _Prepost_z_ char, _String) + +__DECLARE_CPP_OVERLOAD_INLINE_FUNC_0_0_EX(char *, __RETURN_POLICY_DST, _tcsupr, _tcsupr_s, _Inout_updates_z_(_Size) char, _Inout_z_ char, _String) +{ + return (char *)_mbsupr((unsigned char *)_String); +} + +__DEFINE_CPP_OVERLOAD_INLINE_FUNC_0_0_EX(char *, __RETURN_POLICY_DST, _tcsupr, _tcsupr_s, _Inout_updates_z_(_Size) char, _Inout_z_ char, _String) + +_Check_return_wat_ __inline errno_t _tcsupr_s_l(_Inout_updates_z_(_Count) char * _String, _In_ size_t _Count, _In_opt_ _locale_t _Locale) +{ + return _mbsupr_s_l((unsigned char *)_String, _Count, _Locale); +} + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1(errno_t, _tcsupr_s_l, _Prepost_z_ char, _String, _In_opt_ _locale_t, _Locale) + +__DECLARE_CPP_OVERLOAD_INLINE_FUNC_0_1_EX(char *, __RETURN_POLICY_DST, _tcsupr_l, _tcsupr_s_l, _Inout_updates_z_(_Size) char, _Inout_z_ char, _String, _In_opt_ _locale_t, _Locale) +{ + return (char *)_mbsupr_l((unsigned char *)_String, _Locale); +} + +__DEFINE_CPP_OVERLOAD_INLINE_FUNC_0_1_EX(char *, __RETURN_POLICY_DST, _tcsupr_l, _tcsupr_s_l, _Inout_updates_z_(_Size) char, _Inout_z_ char, _String, _In_opt_ _locale_t, _Locale) + +_Check_return_ __inline size_t _tclen(_In_z_ _CPC _s1) {return _mbclen((_CPUC)_s1);} + +_Check_return_wat_ __inline errno_t _tccpy_s(_Out_writes_z_(_SizeInBytes) char * _Destination, size_t _SizeInBytes, _Out_opt_ int *_PCopied, _In_z_ const char * _Source) +{ + return _mbccpy_s((unsigned char *)_Destination, _SizeInBytes, _PCopied, (const unsigned char *)_Source); +} + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2(errno_t, _tccpy_s, _Post_z_ char, _Dest, _Out_opt_ int *, _PCopied, _In_z_ const char *, _Source) + +_CRT_INSECURE_DEPRECATE(_tccpy_s) __inline void _tccpy(_Out_writes_z_(2) char * _Destination, _In_z_ const char * _Source) +{ + _mbccpy((unsigned char *)_Destination, (const unsigned char *)_Source); +} + +_Check_return_wat_ __inline errno_t _tccpy_s_l(_Out_writes_z_(_SizeInBytes) char * _Destination, _In_ size_t _SizeInBytes, _Out_opt_ int *_PCopied, _In_z_ const char * _Source, _In_opt_ _locale_t _Locale) +{ + return _mbccpy_s_l((unsigned char *)_Destination, _SizeInBytes, _PCopied, (const unsigned char *)_Source, _Locale); +} + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_3(errno_t, _tccpy_s_l, _Post_z_ char, _Dest, _Out_opt_ int *, _PCopied, _In_z_ const char *, _Source, _In_opt_ _locale_t, _Locale) + +_CRT_INSECURE_DEPRECATE(_tccpy_s_l) __inline void _tccpy_l(_Out_writes_z_(2) char * _Destination, _In_z_ const char * _Source, _In_opt_ _locale_t _Locale) +{ + _mbccpy_l((unsigned char *)_Destination,( const unsigned char *)_Source, _Locale); +} + +/* inline helper */ +_Check_return_ __inline _UI _tcsnextc(_In_z_ _CPC _s1) +{ + _UI _n=0; + if (_ismbblead((_UI)*(_PUC)_s1)) + { + /* for a dud MBCS string (leadbyte, EOS), we don't move forward 2 + We do not assert here because this routine is too low-level + */ + if(_s1[1]!='\0') + { + _n=((_UI)*(_PUC)_s1)<<8; + _s1++; + } + } + _n+=(_UI)*(_PUC)_s1; + + return(_n); +} + +#endif /* __STDC__ || defined (_NO_INLINING) */ + +#ifdef __cplusplus +#ifndef _CPP_TCHAR_INLINES_DEFINED +#define _CPP_TCHAR_INLINES_DEFINED +extern "C++" { +_Check_return_ inline char * __CRTDECL _tcschr(_In_z_ char *_S, _In_ unsigned int _C) + {return ((char *)_tcschr((const char *)_S, _C)); } +_Check_return_ inline char * __CRTDECL _tcspbrk(_In_z_ char *_S, _In_z_ const char *_P) + {return ((char *)_tcspbrk((const char *)_S, _P)); } +_Check_return_ inline char * __CRTDECL _tcsrchr(_In_z_ char *_S, _In_ unsigned int _C) + {return ((char *)_tcsrchr((const char *)_S, _C)); } +_Check_return_ inline char * __CRTDECL _tcsstr(_In_z_ char *_S, _In_z_ const char *_P) + {return ((char *)_tcsstr((const char *)_S, _P)); } +} +#endif /* _CPP_TCHAR_INLINES_DEFINED */ +#endif /* __cplusplus */ + +#endif /* _MB_MAP_DIRECT */ + + +/* MBCS-specific mappings */ + +#define _tccmp(_cp1,_cp2) _tcsnccmp(_cp1,_cp2,1) + + +/* ctype functions */ + +#define _istalnum _ismbcalnum +#define _istalnum_l _ismbcalnum_l +#define _istalpha _ismbcalpha +#define _istalpha_l _ismbcalpha_l +#define _istdigit _ismbcdigit +#define _istdigit_l _ismbcdigit_l +#define _istgraph _ismbcgraph +#define _istgraph_l _ismbcgraph_l +#define _istlegal _ismbclegal +#define _istlegal_l _ismbclegal_l +#define _istlower _ismbclower +#define _istlower_l _ismbclower_l +#define _istprint _ismbcprint +#define _istprint_l _ismbcprint_l +#define _istpunct _ismbcpunct +#define _istpunct_l _ismbcpunct_l +#define _istblank _ismbcblank +#define _istblank_l _ismbcblank_l +#define _istspace _ismbcspace +#define _istspace_l _ismbcspace_l +#define _istupper _ismbcupper +#define _istupper_l _ismbcupper_l + +#define _totupper _mbctoupper +#define _totupper_l _mbctoupper_l +#define _totlower _mbctolower +#define _totlower_l _mbctolower_l + +#define _istlead _ismbblead +#define _istleadbyte isleadbyte +#define _istleadbyte_l _isleadbyte_l + +#else /* _MBCS */ + +/* ++++++++++++++++++++ SBCS ++++++++++++++++++++ */ + + +#ifndef __TCHAR_DEFINED +typedef char _TCHAR; +typedef signed char _TSCHAR; +typedef unsigned char _TUCHAR; +typedef char _TXCHAR; +typedef int _TINT; +#define __TCHAR_DEFINED +#endif /* __TCHAR_DEFINED */ + +#if defined(_CRT_INTERNAL_NONSTDC_NAMES) && _CRT_INTERNAL_NONSTDC_NAMES +#ifndef _TCHAR_DEFINED +typedef char TCHAR; +typedef char * PTCHAR; +typedef unsigned char TBYTE; +typedef unsigned char * PTBYTE; +#define _TCHAR_DEFINED +#endif /* _TCHAR_DEFINED */ +#endif /* _CRT_INTERNAL_NONSTDC_NAMES */ + + +/* String functions */ + +#define _tcschr strchr +#define _tcscspn strcspn +#define _tcsncat strncat +#define _tcsncat_s strncat_s +#define _tcsncat_l _strncat_l +#define _tcsncat_s_l _strncat_s_l +#define _tcsncpy strncpy +#define _tcsncpy_s strncpy_s +#define _tcsncpy_l _strncpy_l +#define _tcsncpy_s_l _strncpy_s_l +#define _tcspbrk strpbrk +#define _tcsrchr strrchr +#define _tcsspn strspn +#define _tcsstr strstr +#define _tcstok strtok +#define _tcstok_s strtok_s +#define _tcstok_l _strtok_l +#define _tcstok_s_l _strtok_s_l + +#define _tcsnset _strnset +#define _tcsnset_s _strnset_s +#define _tcsnset_l _strnset_l +#define _tcsnset_s_l _strnset_s_l +#define _tcsrev _strrev +#define _tcsset _strset +#define _tcsset_s _strset_s +#define _tcsset_l _strset_l +#define _tcsset_s_l _strset_s_l + +#define _tcscmp strcmp +#define _tcsicmp _stricmp +#define _tcsicmp_l _stricmp_l +#define _tcsnccmp strncmp +#define _tcsncmp strncmp +#define _tcsncicmp _strnicmp +#define _tcsncicmp_l _strnicmp_l +#define _tcsnicmp _strnicmp +#define _tcsnicmp_l _strnicmp_l + +#define _tcscoll strcoll +#define _tcscoll_l _strcoll_l +#define _tcsicoll _stricoll +#define _tcsicoll_l _stricoll_l +#define _tcsnccoll _strncoll +#define _tcsnccoll_l _strncoll_l +#define _tcsncoll _strncoll +#define _tcsncoll_l _strncoll_l +#define _tcsncicoll _strnicoll +#define _tcsncicoll_l _strnicoll_l +#define _tcsnicoll _strnicoll +#define _tcsnicoll_l _strnicoll_l + +/* "logical-character" mappings */ + +#define _tcsclen strlen +#define _tcscnlen strnlen +#define _tcsclen_l(_String, _Locale) strlen(_String) +#define _tcscnlen_l(_String, _Max_count, _Locale) strnlen((_String), (_Max_count)) +#define _tcsnccat strncat +#define _tcsnccat_s strncat_s +#define _tcsnccat_l _strncat_l +#define _tcsnccat_s_l _strncat_s_l +#define _tcsnccpy strncpy +#define _tcsnccpy_s strncpy_s +#define _tcsnccpy_l _strncpy_l +#define _tcsnccpy_s_l _strncpy_s_l +#define _tcsncset _strnset +#define _tcsncset_s _strnset_s +#define _tcsncset_l _strnset_l +#define _tcsncset_s_l _strnset_s_l + +/* MBCS-specific functions */ + +#define _tcsdec _strdec +#define _tcsinc _strinc +#define _tcsnbcnt _strncnt +#define _tcsnccnt _strncnt +#define _tcsnextc _strnextc +#define _tcsninc _strninc +#define _tcsspnp _strspnp + +#define _tcslwr _strlwr +#define _tcslwr_l _strlwr_l +#define _tcslwr_s _strlwr_s +#define _tcslwr_s_l _strlwr_s_l +#define _tcsupr _strupr +#define _tcsupr_l _strupr_l +#define _tcsupr_s _strupr_s +#define _tcsupr_s_l _strupr_s_l +#define _tcsxfrm strxfrm +#define _tcsxfrm_l _strxfrm_l + +#define _istlead(_Char) (0) +#define _istleadbyte(_Char) (0) +#define _istleadbyte_l(_Char, _Locale) (0) + +#if __STDC__ || defined (_NO_INLINING) +#define _tclen(_pc) (1) +#define _tccpy(_pc1,_cpc2) (*(_pc1) = *(_cpc2)) +#define _tccpy_l(_pc1,_cpc2,_locale) _tccpy((_pc1),(_cpc2)) +#define _tccmp(_cpc1,_cpc2) (((unsigned char)*(_cpc1))-((unsigned char)*(_cpc2))) +#else /* __STDC__ || defined (_NO_INLINING) */ +_Check_return_ __inline size_t __CRTDECL _tclen(_In_z_ const char *_cpc) +{ + _CRT_UNUSED(_cpc); + return 1; +} +__inline void __CRTDECL _tccpy(_Out_ char *_pc1, _In_z_ const char *_cpc2) { *_pc1 = *_cpc2; } +__inline void __CRTDECL _tccpy_l(_Out_ char *_Pc1, _In_z_ const char *_Cpc2, _In_opt_ _locale_t _Locale) +{ + _CRT_UNUSED(_Locale); + _tccpy(_Pc1, _Cpc2); +} +_Check_return_ __inline int __CRTDECL _tccmp(_In_z_ const char *_cpc1, _In_z_ const char *_cpc2) { return (int) (((unsigned char)*_cpc1)-((unsigned char)*_cpc2)); } +#endif /* __STDC__ || defined (_NO_INLINING) */ + + +/* ctype-functions */ + +#define _istalnum isalnum +#define _istalnum_l _isalnum_l +#define _istalpha isalpha +#define _istalpha_l _isalpha_l +#define _istdigit isdigit +#define _istdigit_l _isdigit_l +#define _istgraph isgraph +#define _istgraph_l _isgraph_l +#define _istlower islower +#define _istlower_l _islower_l +#define _istprint isprint +#define _istprint_l _isprint_l +#define _istpunct ispunct +#define _istpunct_l _ispunct_l +#define _istblank isblank +#define _istblank_l _isblank_l +#define _istspace isspace +#define _istspace_l _isspace_l +#define _istupper isupper +#define _istupper_l _isupper_l + +#define _totupper toupper +#define _totupper_l _toupper_l +#define _totlower tolower +#define _totlower_l _tolower_l + +#define _istlegal(_c) (1) + + +/* the following is optional if functional versions are available */ + +#if __STDC__ || defined (_NO_INLINING) +#define _strdec(_cpc1, _cpc2) ((_cpc1)>=(_cpc2) ? NULL : (_cpc2)-1) +#define _strinc(_pc) ((_pc)+1) +#define _strnextc(_cpc) ((unsigned int) *(const unsigned char *)(_cpc)) +#define _strninc(_pc, _sz) (((_pc)+(_sz))) +_ACRTIMP size_t __cdecl __strncnt(_In_reads_or_z_(_Cnt) const char * _Str, _In_ size_t _Cnt); +#define _strncnt(_cpc, _sz) (__strncnt(_cpc,_sz)) +#define _strspnp(_cpc1, _cpc2) (_cpc1==NULL ? NULL : ((*((_cpc1)+strspn(_cpc1,_cpc2))) ? ((_cpc1)+strspn(_cpc1,_cpc2)) : NULL)) + +#define _strncpy_l(_Destination, _Source, _Count, _Locale) (strncpy(_Destination, _Source, _Count)) +#if __STDC_WANT_SECURE_LIB__ +#define _strncpy_s_l(_Destination, _Destination_size_chars, _Source, _Count, _Locale) (strncpy_s(_Destination, _Destination_size_chars, _Source, _Count)) +#endif /* __STDC_WANT_SECURE_LIB__ */ +#define _strncat_l(_Destination, _Source, _Count, _Locale) (strncat(_Destination, _Source, _Count)) +#if __STDC_WANT_SECURE_LIB__ +#define _strncat_s_l(_Destination, _Destination_size_chars, _Source, _Count, _Locale) (strncat_s(_Destination, _Destination_size_chars, _Source, _Count)) +#endif /* __STDC_WANT_SECURE_LIB__ */ +#define _strtok_l(_String, _Delimiters, _Locale) (strtok(_String, _Delimiters)) +#if __STDC_WANT_SECURE_LIB__ +#define _strtok_s_l(_String, _Delimiters, _Current_position, _Locale) (strtok_s(_String, _Delimiters, _Current_position)) +#endif /* __STDC_WANT_SECURE_LIB__ */ +#define _strnset_l(_Destination, _Value, _Count, _Locale) (_strnset(_Destination, _Value, _Count)) +#define _strnset_s_l(_Destination, _Destination_size_chars, _Value, _Count, _Locale) (_strnset_s(_Destination, _Destination_size_chars, _Value, _Count)) +#define _strset_l(_Destination, _Value, _Locale) (_strset(_Destination, _Value)) +#define _strset_s_l(_Destination, _Destination_size_chars, _Value, _Locale) (_strset_s(_Destination, _Destination_size_chars, _Value)) +#else /* __STDC__ || defined (_NO_INLINING) */ +_Check_return_ __inline char * __CRTDECL _strdec(_In_reads_z_(_Cpc2 - _Cpc1) const char * _Cpc1, _In_z_ const char * _Cpc2) { return (char *)((_Cpc1)>=(_Cpc2) ? NULL : (_Cpc2-1)); } +_Check_return_ __inline char * __CRTDECL _strinc(_In_z_ const char * _Pc) { return (char *)(_Pc+1); } +_Check_return_ __inline unsigned int __CRTDECL _strnextc(_In_z_ const char * _Cpc) { return (unsigned int)*(const unsigned char *)_Cpc; } +_Check_return_ __inline char * __CRTDECL _strninc(_In_reads_or_z_(_Sz) const char * _Pc, _In_ size_t _Sz) { return (char *)(_Pc+_Sz); } +_Check_return_ __inline size_t __CRTDECL _strncnt(_In_reads_or_z_(_Cnt) const char * _String, _In_ size_t _Cnt) +{ + size_t n = _Cnt; + char *cp = (char *)_String; + while (n-- && *cp) + cp++; + return _Cnt - n - 1; +} +_Check_return_ __inline char * __CRTDECL _strspnp +( + _In_z_ const char * _Cpc1, + _In_z_ const char * _Cpc2 +) +{ + return _Cpc1==NULL ? NULL : ((*(_Cpc1 += strspn(_Cpc1,_Cpc2))!='\0') ? (char*)_Cpc1 : NULL); +} + +#if __STDC_WANT_SECURE_LIB__ +_Check_return_wat_ __inline errno_t __CRTDECL _strncpy_s_l(_Out_writes_z_(_Destination_size_chars) char *_Destination, _In_ size_t _Destination_size_chars, _In_z_ const char *_Source, _In_ size_t _Count, _In_opt_ _locale_t _Locale) +{ + _CRT_UNUSED(_Locale); + return strncpy_s(_Destination, _Destination_size_chars, _Source, _Count); +} +#endif /* __STDC_WANT_SECURE_LIB__ */ + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_3(errno_t, _strncpy_s_l, _Post_z_ char, _Dest, _In_z_ const char *, _Source, _In_ size_t, _Count, _In_opt_ _locale_t, _Locale) + +__DECLARE_CPP_OVERLOAD_INLINE_NFUNC_0_3_EX(char *, __RETURN_POLICY_DST, _strncpy_l, _strncpy_s_l, _Out_writes_z_(_Size) char, _Out_writes_(_Count) char, _Dst, _In_z_ const char *, _Source, _In_ size_t, _Count, _In_opt_ _locale_t, _Locale) +{ + _CRT_UNUSED(_Locale); + return strncpy(_Dst, _Source, _Count); +} + +__DEFINE_CPP_OVERLOAD_INLINE_NFUNC_0_3_EX(char *, __RETURN_POLICY_DST, _strncpy_l, _strncpy_s_l, _Out_writes_z_(_Size) char, _Out_writes_(_Count), char, _Dst, _In_z_ const char *, _Source, _In_ size_t, _Count, _In_opt_ _locale_t, _Locale) + +#if __STDC_WANT_SECURE_LIB__ +_Check_return_wat_ __inline errno_t __CRTDECL _strncat_s_l(_Inout_updates_z_(_Destination_size_chars) char *_Destination, _In_ size_t _Destination_size_chars, _In_z_ const char *_Source, _In_ size_t _Count, _In_opt_ _locale_t _Locale) +{ + _CRT_UNUSED(_Locale); + return strncat_s(_Destination, _Destination_size_chars, _Source, _Count); +} +#endif /* __STDC_WANT_SECURE_LIB__ */ + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_3(errno_t, _strncat_s_l, _Prepost_z_ char, _Dest, _In_z_ const char *, _Source, _In_ size_t, _Count, _In_opt_ _locale_t, _Locale) + +__DECLARE_CPP_OVERLOAD_INLINE_NFUNC_0_3_EX(char *, __RETURN_POLICY_DST, _strncat_l, _strncat_s_l, _Inout_updates_z_(_Size) char, _Inout_z_ char, _Dst, _In_z_ const char *, _Source, _In_ size_t, _Count, _In_opt_ _locale_t, _Locale) +{ + _CRT_UNUSED(_Locale); +#pragma warning(suppress: 6054) // String may not be zero-terminated + return strncat(_Dst, _Source, _Count); +} + +__DEFINE_CPP_OVERLOAD_INLINE_NFUNC_0_3_EX(char *, __RETURN_POLICY_DST, _strncat_l, _strncat_s_l, _Inout_updates_z_(_Size) char, _Inout_z_, char, _Dst, _In_z_ const char *, _Source, _In_ size_t, _Count, _In_opt_ _locale_t, _Locale) + +_Check_return_ _CRT_INSECURE_DEPRECATE(_strtok_s_l) __inline char * _strtok_l(_Inout_opt_z_ char * _String, _In_z_ const char * _Delimiters, _In_opt_ _locale_t _Locale) +{ + _CRT_UNUSED(_Locale); + return strtok(_String,_Delimiters); +} + +#if __STDC_WANT_SECURE_LIB__ +_Check_return_ __inline char * _strtok_s_l(_Inout_opt_z_ char * _String, _In_z_ const char * _Delimiters, _Inout_ _Deref_prepost_opt_z_ char **_Current_position, _In_opt_ _locale_t _Locale) +{ + _CRT_UNUSED(_Locale); + return strtok_s(_String, _Delimiters, _Current_position); +} +#endif /* __STDC_WANT_SECURE_LIB__ */ + +__inline errno_t __CRTDECL _strnset_s_l(_Inout_updates_z_(_Destination_size_chars) char *_Destination, _In_ size_t _Destination_size_chars, _In_ int _Value, _In_ size_t _Count, _In_opt_ _locale_t _Locale) +{ + _CRT_UNUSED(_Locale); + return _strnset_s(_Destination, _Destination_size_chars, _Value, _Count); +} + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_3(errno_t, _strnset_s_l, _Prepost_z_ char, _Dest, _In_ int, _Value, _In_ size_t, _Count, _In_opt_ _locale_t, _Locale) + +__DECLARE_CPP_OVERLOAD_INLINE_NFUNC_0_3_EX(char *, __RETURN_POLICY_DST, _strnset_l, _strnset_s_l, _Inout_updates_z_(_Size) char, _Inout_updates_z_(_MaxCount) char, _Dst, _In_ int, _Value, _In_ size_t, _MaxCount, _In_opt_ _locale_t, _Locale) +{ + _CRT_UNUSED(_Locale); +#pragma warning(suppress: 6054) // String may not be zero-terminated + return _strnset(_Dst, _Value, _MaxCount); +} + +__DEFINE_CPP_OVERLOAD_INLINE_NFUNC_0_3_EX(char *, __RETURN_POLICY_DST, _strnset_l, _strnset_s_l, _Inout_updates_z_(_Size) char, _Inout_updates_z_(_MaxCount), char, _Dst, _In_ int, _Value, _In_ size_t, _Count, _In_opt_ _locale_t, _Locale) + +__inline errno_t __CRTDECL _strset_s_l(_Inout_updates_z_(_Destination_size_chars) char *_Destination, _In_ size_t _Destination_size_chars, _In_ int _Value, _In_opt_ _locale_t _Locale) +{ + _CRT_UNUSED(_Locale); + return _strset_s(_Destination, _Destination_size_chars, _Value); +} + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2(errno_t, _strset_s_l, _Prepost_z_ char, _Dest, _In_ int, _Value, _In_opt_ _locale_t, _Locale) + +__DECLARE_CPP_OVERLOAD_INLINE_FUNC_0_2_EX(char *, __RETURN_POLICY_DST, _strset_l, _strset_s_l, _Inout_updates_z_(_Size) char, _Inout_z_ char, _Dst, _In_ int, _Value, _In_opt_ _locale_t, _Locale) +{ + _CRT_UNUSED(_Locale); + return _strset(_Dst, _Value); +} + +__DEFINE_CPP_OVERLOAD_INLINE_FUNC_0_2_EX(char *, __RETURN_POLICY_DST, _strset_l, _strset_s_l, _Inout_updates_z_(_Size) char, _Inout_z_, char, _Dst, _In_ int, _Value, _In_opt_ _locale_t, _Locale) + +#endif /* __STDC__ || defined (_NO_INLINING) */ + + +#endif /* _MBCS */ + +#endif /* _UNICODE */ + + +/* Generic text macros to be used with string literals and character constants. + Will also allow symbolic constants that resolve to same. */ + +#define _T(x) __T(x) +#define _TEXT(x) __T(x) + + +#ifdef __cplusplus +} /* ... extern "C" */ +#endif /* __cplusplus */ +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS +#endif /* _INC_TCHAR */ + diff --git a/sdk/include/ucrt/tgmath.h b/sdk/include/ucrt/tgmath.h new file mode 100644 index 0000000000000..ba5cca30b1fc4 --- /dev/null +++ b/sdk/include/ucrt/tgmath.h @@ -0,0 +1,650 @@ +// +// tgmath.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The type-generic math library. +// +#pragma once +#ifndef _TGMATH +#define _TGMATH + +#include + +#if (_CRT_HAS_CXX17 == 1) && !defined(_CRT_USE_C_TGMATH_H) + +#include + +#else // ^^^^ /std:c++17 ^^^^ // vvvv _CRT_USE_C_TGMATH_H vvvv + +#include +#include + +#if _CRT_HAS_C11 == 0 + +#ifndef _CRT_SILENCE_NONCONFORMING_TGMATH_H + +#pragma message(_CRT_WARNING_MESSAGE("UCRT4000", \ + "This header does not conform to the C99 standard. " \ + "C99 functionality is available when compiling in C11 mode or higher (/std:c11). " \ + "Functionality equivalent to the type-generic functions provided by tgmath.h is available " \ + "in when compiling as C++. " \ + "If compiling in C++17 mode or higher (/std:c++17), this header will automatically include instead. " \ + "You can define _CRT_SILENCE_NONCONFORMING_TGMATH_H to acknowledge that you have received this warning.")) + +#endif // _CRT_SILENCE_NONCONFORMING_TGMATH_H + +#else // ^^^^ Default C Support ^^^^ // vvvv C11 Support vvvv + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS +_CRT_BEGIN_C_HEADER + +#define __tgmath_resolve_real_binary_op(X, Y) _Generic((X), \ + long double: 0.0l, \ + \ + default: _Generic((Y), \ + long double: 0.0l, \ + default: 0.0 \ + ), \ + \ + float: _Generic((Y), \ + long double: 0.0l, \ + default: 0.0, \ + float: 0.0f \ + ) \ + ) + +#define fabs(X) _Generic((X), \ + _Lcomplex: cabsl, \ + _Fcomplex: cabsf, \ + _Dcomplex: cabs, \ + long double: fabsl, \ + float: fabsf, \ + default: fabs \ +)(X) + +#define exp(X) _Generic((X), \ + _Lcomplex: cexpl, \ + _Fcomplex: cexpf, \ + _Dcomplex: cexp, \ + long double: expl, \ + float: expf, \ + default: exp \ +)(X) + +#define log(X) _Generic((X), \ + _Lcomplex: clogl, \ + _Fcomplex: clogf, \ + _Dcomplex: clog, \ + long double: logl, \ + float: logf, \ + default: log \ +)(X) + +// C99 Complex types currently not supported. Complex types do not cast/promote implicitly - need inline helper functions. + +inline _Lcomplex __cpowl_lc_dc(_Lcomplex const __lc, _Dcomplex const __dc) +{ + return cpowl(__lc, _LCbuild(__dc._Val[0], __dc._Val[1])); +} + +inline _Lcomplex __cpowl_dc_lc(_Dcomplex const __dc, _Lcomplex const __lc) +{ + return cpowl(_LCbuild(__dc._Val[0], __dc._Val[1]), __lc); +} + +inline _Lcomplex __cpowl_lc_fc(_Lcomplex const __lc, _Fcomplex const __fc) +{ + return cpowl(__lc, _LCbuild(__fc._Val[0], __fc._Val[1])); +} + +inline _Lcomplex __cpowl_fc_lc(_Fcomplex const __fc, _Lcomplex const __lc) +{ + return cpowl(_LCbuild(__fc._Val[0], __fc._Val[1]), __lc); +} + +inline _Lcomplex __cpowl_lc_l(_Lcomplex const __lc, long double const __l) +{ + return cpowl(__lc, _LCbuild(__l, 0.0)); +} + +inline _Lcomplex __cpowl_l_lc(long double const __l, _Lcomplex const __lc) +{ + return cpowl(_LCbuild(__l, 0.0), __lc); +} + +inline _Lcomplex __cpowl_lc_d(_Lcomplex const __lc, double const __d) +{ + return cpowl(__lc, _LCbuild(__d, 0.0)); +} + +inline _Lcomplex __cpowl_d_lc(double const __d, _Lcomplex const __lc) +{ + return cpowl(_LCbuild(__d, 0.0), __lc); +} + +inline _Lcomplex __cpowl_lc_f(_Lcomplex const __lc, float const __f) +{ + return cpowl(__lc, _LCbuild(__f, 0.0)); +} + +inline _Lcomplex __cpowl_f_lc(float const __f, _Lcomplex const __lc) +{ + return cpowl(_LCbuild(__f, 0.0), __lc); +} + +inline _Lcomplex __cpowl_dc_l(_Dcomplex const __dc, long double const __l) +{ + return cpowl(_LCbuild(__dc._Val[0], __dc._Val[1]), _LCbuild(__l, 0.0)); +} + +inline _Lcomplex __cpowl_l_dc(long double const __l, _Dcomplex const __dc) +{ + return cpowl(_LCbuild(__l, 0.0), _LCbuild(__dc._Val[0], __dc._Val[1])); +} + +inline _Lcomplex __cpowl_fc_l(_Fcomplex const __fc, long double const __l) +{ + return cpowl(_LCbuild(__fc._Val[0], __fc._Val[1]), _LCbuild(__l, 0.0)); +} + +inline _Lcomplex __cpowl_l_fc(long double const __l, _Fcomplex const __fc) +{ + return cpowl(_LCbuild(__l, 0.0), _LCbuild(__fc._Val[0], __fc._Val[1])); +} + +inline _Dcomplex __cpow_dc_fc(_Dcomplex const __dc, _Fcomplex const __fc) +{ + return cpow(__dc, _Cbuild(__fc._Val[0], __fc._Val[1])); +} + +inline _Dcomplex __cpow_fc_dc(_Fcomplex const __fc, _Dcomplex const __dc) +{ + return cpow(_Cbuild(__fc._Val[0], __fc._Val[1]), __dc); +} + +inline _Dcomplex __cpow_dc_d(_Dcomplex const __dc, double const __d) +{ + return cpow(__dc, _Cbuild(__d, 0.0)); +} + +inline _Dcomplex __cpow_d_dc(double const __d, _Dcomplex const __dc) +{ + return cpow(_Cbuild(__d, 0.0), __dc); +} + +inline _Dcomplex __cpow_dc_f(_Dcomplex const __dc, float const __f) +{ + return cpow(__dc, _Cbuild(__f, 0.0)); +} + +inline _Dcomplex __cpow_f_dc(float const __f, _Dcomplex const __dc) +{ + return cpow(_Cbuild(__f, 0.0), __dc); +} + +inline _Dcomplex __cpow_fc_d(_Fcomplex const __fc, double const __d) +{ + return cpow(_Cbuild(__fc._Val[0], __fc._Val[1]), _Cbuild(__d, 0.0)); +} + +inline _Dcomplex __cpow_d_fc(double const __d, _Fcomplex const __fc) +{ + return cpow(_Cbuild(__d, 0.0), _Cbuild(__fc._Val[0], __fc._Val[1])); +} + +inline _Fcomplex __cpowf_fc_f(_Fcomplex const __fc, float const __f) +{ + return cpowf(__fc, _FCbuild(__f, 0.0f)); +} + +inline _Fcomplex __cpowf_f_fc(float const __f, _Fcomplex const __fc) +{ + return cpowf(_FCbuild(__f, 0.0f), __fc); +} + +#define pow(X, Y) _Generic((X), \ + _Lcomplex: _Generic((Y), \ + _Lcomplex: cpowl, \ + _Fcomplex: __cpowl_lc_fc, \ + _Dcomplex: __cpowl_lc_dc, \ + long double: __cpowl_lc_l, \ + default: __cpowl_lc_d, \ + float: __cpowl_lc_f \ + ), \ + \ + _Fcomplex: _Generic((Y), \ + _Lcomplex: __cpowl_fc_lc, \ + _Fcomplex: cpowf, \ + _Dcomplex: __cpow_fc_dc, \ + long double: __cpowl_fc_l, \ + default: __cpow_fc_d, \ + float: __cpowf_fc_f \ + ), \ + \ + _Dcomplex: _Generic((Y), \ + _Lcomplex: __cpowl_dc_lc, \ + _Fcomplex: __cpow_dc_fc, \ + _Dcomplex: cpow, \ + long double: __cpowl_dc_l, \ + default: __cpow_dc_d, \ + float: __cpow_dc_f \ + ), \ + \ + long double: _Generic((Y), \ + _Lcomplex: __cpowl_l_lc, \ + _Fcomplex: __cpowl_l_fc, \ + _Dcomplex: __cpowl_l_dc, \ + default: powl \ + ), \ + \ + float: _Generic((Y), \ + _Lcomplex: __cpowl_f_lc, \ + _Fcomplex: __cpowf_f_fc, \ + _Dcomplex: __cpow_f_dc, \ + long double: powl, \ + default: pow, \ + float: powf \ + ), \ + \ + default: _Generic((Y), \ + _Lcomplex: __cpowl_d_lc, \ + _Fcomplex: __cpow_d_fc, \ + _Dcomplex: __cpow_d_dc, \ + long double: powl, \ + default: pow \ + ) \ +)(X, Y) + +#define sqrt(X) _Generic((X), \ + _Lcomplex: csqrtl, \ + _Fcomplex: csqrtf, \ + _Dcomplex: csqrt, \ + long double: sqrtl, \ + float: sqrtf, \ + default: sqrt \ +)(X) + +#define sin(X) _Generic((X), \ + _Lcomplex: csinl, \ + _Fcomplex: csinf, \ + _Dcomplex: csin, \ + long double: sinl, \ + float: sinf, \ + default: sin \ +)(X) + +#define cos(X) _Generic((X), \ + _Lcomplex: ccosl, \ + _Fcomplex: ccosf, \ + _Dcomplex: ccos, \ + long double: cosl, \ + float: cosf, \ + default: cos \ +)(X) + +#define tan(X) _Generic((X), \ + _Lcomplex: ctanl, \ + _Fcomplex: ctanf, \ + _Dcomplex: ctan, \ + long double: tanl, \ + float: tanf, \ + default: tan \ +)(X) + +#define asin(X) _Generic((X), \ + _Lcomplex: casinl, \ + _Fcomplex: casinf, \ + _Dcomplex: casin, \ + long double: asinl, \ + float: asinf, \ + default: asin \ +)(X) + +#define acos(X) _Generic((X), \ + _Lcomplex: cacosl, \ + _Fcomplex: cacosf, \ + _Dcomplex: cacos, \ + long double: acosl, \ + float: acosf, \ + default: acos \ +)(X) + +#define atan(X) _Generic((X), \ + _Lcomplex: catanl, \ + _Fcomplex: catanf, \ + _Dcomplex: catan, \ + long double: atanl, \ + float: atanf, \ + default: atan \ +)(X) + +#define asinh(X) _Generic((X), \ + _Lcomplex: casinhl, \ + _Fcomplex: casinhf, \ + _Dcomplex: casinh, \ + long double: asinhl, \ + float: asinhf, \ + default: asinh \ +)(X) + +#define acosh(X) _Generic((X), \ + _Lcomplex: cacoshl, \ + _Fcomplex: cacoshf, \ + _Dcomplex: cacosh, \ + long double: acoshl, \ + float: acoshf, \ + default: acosh \ +)(X) + +#define atanh(X) _Generic((X), \ + _Lcomplex: catanhl, \ + _Fcomplex: catanhf, \ + _Dcomplex: catanh, \ + long double: atanhl, \ + float: atanhf, \ + default: atanh \ +)(X) + +#define atan2(X, Y) _Generic(__tgmath_resolve_real_binary_op((X), (Y)), \ + long double: atan2l, \ + float: atan2f, \ + default: atan2 \ +)(X, Y) + +#define cbrt(X) _Generic((X), \ + long double: cbrtl, \ + float: cbrtf, \ + default: cbrt \ +)(X) + +#define ceil(X) _Generic((X), \ + long double: ceill, \ + float: ceilf, \ + default: ceil \ +)(X) + +#define copysign(X, Y) _Generic(__tgmath_resolve_real_binary_op((X), (Y)), \ + long double: copysignl, \ + float: copysignf, \ + default: copysign \ +)(X, Y) + +#define erf(X) _Generic((X), \ + long double: erfl, \ + float: erff, \ + default: erf \ +)(X) + +#define erfc(X) _Generic((X), \ + long double: erfcl, \ + float: erfcf, \ + default: erfc \ +)(X) + +#define exp2(X) _Generic((X), \ + long double: exp2l, \ + float: exp2f, \ + default: exp2 \ +)(X) + +#define expm1(X) _Generic((X), \ + long double: expm1l, \ + float: expm1f, \ + default: expm1 \ +)(X) + +#define fdim(X, Y) _Generic(__tgmath_resolve_real_binary_op((X), (Y)), \ + long double: fdiml, \ + float: fdimf, \ + default: fdim \ +)(X, Y) + +#define floor(X) _Generic((X), \ + long double: floorl, \ + float: floorf, \ + default: floor \ +)(X) + +#define fma(X, Y, Z) _Generic(__tgmath_resolve_real_binary_op((X), __tgmath_resolve_real_binary_op((Y), (Z))), \ + long double: fmal, \ + float: fmaf, \ + default: fma \ +)(X, Y, Z) + +#define fmax(X, Y) _Generic(__tgmath_resolve_real_binary_op((X), (Y)), \ + long double: fmaxl, \ + float: fmaxf, \ + default: fmax \ +)(X, Y) + +#define fmin(X, Y) _Generic(__tgmath_resolve_real_binary_op((X), (Y)), \ + long double: fminl, \ + float: fminf, \ + default: fmin \ +)(X, Y) + +#define fmod(X, Y) _Generic(__tgmath_resolve_real_binary_op((X), (Y)), \ + long double: fmodl, \ + float: fmodf, \ + default: fmod \ +)(X, Y) + +#define frexp(X, INT_PTR) _Generic((X), \ + long double: frexpl, \ + float: frexpf, \ + default: frexp \ +)(X, INT_PTR) + +#define hypot(X, Y) _Generic(__tgmath_resolve_real_binary_op((X), (Y)), \ + long double: hypotl, \ + float: hypotf, \ + default: hypot \ +)(X, Y) + +#define ilogb(X) _Generic((X), \ + long double: ilogbl, \ + float: ilogbf, \ + default: ilogb \ +)(X) + +#define ldexp(X, INT) _Generic((X), \ + long double: ldexpl, \ + float: ldexpf, \ + default: ldexp \ +)(X, INT) + +#define lgamma(X) _Generic((X), \ + long double: lgammal, \ + float: lgammaf, \ + default: lgamma \ +)(X) + +#define llrint(X) _Generic((X), \ + long double: llrintl, \ + float: llrintf, \ + default: llrint \ +)(X) + +#define llround(X) _Generic((X), \ + long double: llroundl, \ + float: llroundf, \ + default: llround \ +)(X) + +#define log10(X) _Generic((X), \ + long double: log10l, \ + float: log10f, \ + default: log10 \ +)(X) + +#define log1p(X) _Generic((X), \ + long double: log1pl, \ + float: log1pf, \ + default: log1p \ +)(X) + +#define log2(X) _Generic((X), \ + long double: log2l, \ + float: log2f, \ + default: log2 \ +)(X) + +#define logb(X) _Generic((X), \ + long double: logbl, \ + float: logbf, \ + default: logb \ +)(X) + +#define lrint(X) _Generic((X), \ + long double: lrintl, \ + float: lrintf, \ + default: lrint \ +)(X) + +#define lround(X) _Generic((X), \ + long double: lroundl, \ + float: lroundf, \ + default: lround \ +)(X) + +#define nearbyint(X) _Generic((X), \ + long double: nearbyintl, \ + float: nearbyintf, \ + default: nearbyint \ +)(X) + +#define nextafter(X, Y) _Generic(__tgmath_resolve_real_binary_op((X), (Y)), \ + long double: nextafterl, \ + float: nextafterf, \ + default: nextafter \ +)(X, Y) + +#define nexttoward(X, LONG_DOUBLE) _Generic((X), \ + long double: nexttowardl, \ + float: nexttowardf, \ + default: nexttoward \ +)(X, LONG_DOUBLE) + +#define remainder(X, Y) _Generic(__tgmath_resolve_real_binary_op((X), (Y)), \ + long double: remainderl, \ + float: remainderf, \ + default: remainder \ +)(X, Y) + +#define remquo(X, Y, INT_PTR) _Generic(__tgmath_resolve_real_binary_op((X), (Y)), \ + long double: remquol, \ + float: remquof, \ + default: remquo \ +)(X, Y, INT_PTR) + +#define rint(X) _Generic((X), \ + long double: rintl, \ + float: rintf, \ + default: rint \ +)(X) + +#define round(X) _Generic((X), \ + long double: roundl, \ + float: roundf, \ + default: round \ +)(X) + +#define scalbln(X, LONG) _Generic((X), \ + long double: scalblnl, \ + float: scalblnf, \ + default: scalbln \ +)(X, LONG) + +#define scalbn(X, INT) _Generic((X), \ + long double: scalbnl, \ + float: scalbnf, \ + default: scalbn \ +)(X, INT) + +#define tgamma(X) _Generic((X), \ + long double: tgammal, \ + float: tgammaf, \ + default: tgamma \ +)(X) + +#define trunc(X) _Generic((X), \ + long double: truncl, \ + float: truncf, \ + default: trunc \ +)(X) + +inline double __carg_d(double const __d) +{ + return carg(_Cbuild(__d, 0.0)); +} + +#define carg(X) _Generic((X), \ + _Lcomplex: cargl, \ + _Fcomplex: cargf, \ + _Dcomplex: carg, \ + default: __carg_d \ +)(X) + +inline _Dcomplex __conj_d(double const __d) +{ + return conj(_Cbuild(__d, 0.0)); +} + +#define conj(X) _Generic((X), \ + _Lcomplex: conjl, \ + _Fcomplex: conjf, \ + _Dcomplex: conj, \ + default: __conj_d \ +)(X) + +inline double __creal_d(double const __d) +{ + // The real part of a double casted to a double complex is just the double value. + return __d; +} + +#define creal(X) _Generic((X), \ + _Lcomplex: creall, \ + _Fcomplex: crealf, \ + _Dcomplex: creal, \ + default: __creal_d \ +)(X) + +inline double __cimag_d(double const __d) +{ + // The imaginary part of a double casted to a double complex is 0. + (void) __d; + return 0.0; +} + +#define cimag(X) _Generic((X), \ + _Lcomplex: cimagl, \ + _Fcomplex: cimagf, \ + _Dcomplex: cimag, \ + default: __cimag_d \ +)(X) + +inline _Dcomplex __cproj_d(double const __d) +{ + return cproj(_Cbuild(__d, 0.0)); +} + +#define cproj(X) _Generic((X), \ + _Lcomplex: cprojl, \ + _Fcomplex: cprojf, \ + _Dcomplex: cproj, \ + default: __cproj_d \ +)(X) + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS + +#endif // _CRT_HAS_C11 == 0 + +#endif // (_CRT_HAS_CXX17 == 1) && !defined(_CRT_USE_C_TGMATH_H) + +#endif // _TGMATH diff --git a/sdk/include/ucrt/time.h b/sdk/include/ucrt/time.h new file mode 100644 index 0000000000000..9c21af4788f7c --- /dev/null +++ b/sdk/include/ucrt/time.h @@ -0,0 +1,648 @@ +// +// time.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The C Standard Library header. +// +#pragma once +#ifndef _INC_TIME // include guard for 3rd party interop +#define _INC_TIME + +#include +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + +#ifndef _CRT_USE_CONFORMING_ANNEX_K_TIME +#define _CRT_USE_CONFORMING_ANNEX_K_TIME 0 +#endif + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Types +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +typedef long clock_t; + +struct _timespec32 +{ + __time32_t tv_sec; + long tv_nsec; +}; + +struct _timespec64 +{ + __time64_t tv_sec; + long tv_nsec; +}; + +#ifndef _CRT_NO_TIME_T + struct timespec + { + time_t tv_sec; // Seconds - >= 0 + long tv_nsec; // Nanoseconds - [0, 999999999] + }; +#endif + + + +// The number of clock ticks per second +#define CLOCKS_PER_SEC ((clock_t)1000) + +#define TIME_UTC 1 + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Time Zone and Daylight Savings Time Data and Accessors +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// Nonzero if Daylight Savings Time is used +_Check_return_ _CRT_INSECURE_DEPRECATE_GLOBALS(_get_daylight) +_ACRTIMP int* __cdecl __daylight(void); + +#define _daylight (*__daylight()) + +// Offset for Daylight Savings Time +_Check_return_ _CRT_INSECURE_DEPRECATE_GLOBALS(_get_dstbias) +_ACRTIMP long* __cdecl __dstbias(void); + +#define _dstbias (*__dstbias()) + +// Difference in seconds between GMT and local time +_Check_return_ _CRT_INSECURE_DEPRECATE_GLOBALS(_get_timezone) +_ACRTIMP long* __cdecl __timezone(void); + +#define _timezone (*__timezone()) + +// Standard and Daylight Savings Time time zone names +_Check_return_ _Deref_ret_z_ _CRT_INSECURE_DEPRECATE_GLOBALS(_get_tzname) +_ACRTIMP char** __cdecl __tzname(void); + +#define _tzname (__tzname()) + + _Success_(_Daylight != 0) +_ACRTIMP errno_t __cdecl _get_daylight( + _Out_ int* _Daylight + ); + +_Success_(_DaylightSavingsBias != 0) +_ACRTIMP errno_t __cdecl _get_dstbias( + _Out_ long* _DaylightSavingsBias + ); + + _Success_(_TimeZone != 0) +_ACRTIMP errno_t __cdecl _get_timezone( + _Out_ long* _TimeZone + ); + +_Success_(return == 0) +_ACRTIMP errno_t __cdecl _get_tzname( + _Out_ size_t* _ReturnValue, + _Out_writes_z_(_SizeInBytes) char* _Buffer, + _In_ size_t _SizeInBytes, + _In_ int _Index + ); + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// AppCRT Time Functions +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +_Success_(return != 0) +_Ret_writes_z_(26) +_Check_return_ _CRT_INSECURE_DEPRECATE(asctime_s) +_ACRTIMP char* __cdecl asctime( + _In_ struct tm const* _Tm + ); + +#if __STDC_WANT_SECURE_LIB__ + _Success_(return == 0) + _Check_return_wat_ + _ACRTIMP errno_t __cdecl asctime_s( + _Out_writes_(_SizeInBytes) _Post_readable_size_(26) char* _Buffer, + _In_range_(>=,26) size_t _SizeInBytes, + _In_ struct tm const* _Tm + ); +#endif + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1( + errno_t, asctime_s, + _Post_readable_size_(26) char, _Buffer, + _In_ struct tm const*, _Time + ) + +_Check_return_ +_ACRTIMP clock_t __cdecl clock(void); + +_Ret_z_ +_Success_(return != 0) +_Check_return_ _CRT_INSECURE_DEPRECATE(_ctime32_s) +_ACRTIMP char* __cdecl _ctime32( + _In_ __time32_t const* _Time + ); + +_Check_return_wat_ +_ACRTIMP errno_t __cdecl _ctime32_s( + _Out_writes_(_SizeInBytes) _Post_readable_size_(26) char* _Buffer, + _In_range_(>=,26) size_t _SizeInBytes, + _In_ __time32_t const* _Time + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1( + errno_t, _ctime32_s, + _Post_readable_size_(26) char, _Buffer, + _In_ __time32_t const*, _Time + ) + +_Ret_z_ +_Success_(return != 0) +_Check_return_ _CRT_INSECURE_DEPRECATE(_ctime64_s) +_ACRTIMP char* __cdecl _ctime64( + _In_ __time64_t const* _Time + ); + +_Check_return_wat_ +_ACRTIMP errno_t __cdecl _ctime64_s( + _Out_writes_z_(_SizeInBytes) _Post_readable_size_(26) char* _Buffer, + _In_range_(>=,26) size_t _SizeInBytes, + _In_ __time64_t const* _Time + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1( + errno_t, _ctime64_s, + _Post_readable_size_(26) char, _Buffer, + _In_ __time64_t const*, _Time + ) + +_Check_return_ +_ACRTIMP double __cdecl _difftime32( + _In_ __time32_t _Time1, + _In_ __time32_t _Time2 + ); + +_Check_return_ +_ACRTIMP double __cdecl _difftime64( + _In_ __time64_t _Time1, + _In_ __time64_t _Time2 + ); + +_Success_(return != 0) +_Check_return_ _CRT_INSECURE_DEPRECATE(_gmtime32_s) +_ACRTIMP struct tm* __cdecl _gmtime32( + _In_ __time32_t const* _Time + ); + +_Check_return_wat_ +_ACRTIMP errno_t __cdecl _gmtime32_s( + _Out_ struct tm* _Tm, + _In_ __time32_t const* _Time + ); + +_Success_(return != 0) +_Check_return_ _CRT_INSECURE_DEPRECATE(_gmtime64_s) +_ACRTIMP struct tm* __cdecl _gmtime64( + _In_ __time64_t const* _Time + ); + +_Check_return_wat_ +_ACRTIMP errno_t __cdecl _gmtime64_s( + _Out_ struct tm* _Tm, + _In_ __time64_t const* _Time + ); + +_Success_(return != 0) +_Check_return_ _CRT_INSECURE_DEPRECATE(_localtime32_s) +_ACRTIMP struct tm* __cdecl _localtime32( + _In_ __time32_t const* _Time + ); + +_Check_return_wat_ +_ACRTIMP errno_t __cdecl _localtime32_s( + _Out_ struct tm* _Tm, + _In_ __time32_t const* _Time + ); + +_Success_(return != 0) +_Check_return_ _CRT_INSECURE_DEPRECATE(_localtime64_s) +_ACRTIMP struct tm* __cdecl _localtime64( + _In_ __time64_t const* _Time + ); + +_Check_return_wat_ +_ACRTIMP errno_t __cdecl _localtime64_s( + _Out_ struct tm* _Tm, + _In_ __time64_t const* _Time + ); + +_Check_return_ +_ACRTIMP __time32_t __cdecl _mkgmtime32( + _Inout_ struct tm* _Tm + ); + +_Check_return_ +_ACRTIMP __time64_t __cdecl _mkgmtime64( + _Inout_ struct tm* _Tm + ); + +_Check_return_opt_ +_ACRTIMP __time32_t __cdecl _mktime32( + _Inout_ struct tm* _Tm + ); + +_Check_return_opt_ +_ACRTIMP __time64_t __cdecl _mktime64( + _Inout_ struct tm* _Tm + ); + +_Success_(return > 0) +_Check_return_wat_ +_ACRTIMP size_t __cdecl strftime( + _Out_writes_z_(_SizeInBytes) char* _Buffer, + _In_ size_t _SizeInBytes, + _In_z_ _Printf_format_string_ char const* _Format, + _In_ struct tm const* _Tm + ); + +_Success_(return > 0) +_Check_return_wat_ +_ACRTIMP size_t __cdecl _strftime_l( + _Out_writes_z_(_MaxSize) char* _Buffer, + _In_ size_t _MaxSize, + _In_z_ _Printf_format_string_ char const* _Format, + _In_ struct tm const* _Tm, + _In_opt_ _locale_t _Locale + ); + +_Check_return_wat_ +_ACRTIMP errno_t __cdecl _strdate_s( + _Out_writes_(_SizeInBytes) _When_(_SizeInBytes >=9, _Post_readable_size_(9)) char* _Buffer, + _In_ size_t _SizeInBytes + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_0( + errno_t, _strdate_s, + _Post_readable_size_(9) char, _Buffer + ) + +__DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_0( + _Success_(return != 0) char*, __RETURN_POLICY_DST, _ACRTIMP, _strdate, + _Out_writes_z_(9), char, _Buffer + ) + +_Check_return_wat_ +_ACRTIMP errno_t __cdecl _strtime_s( + _Out_writes_(_SizeInBytes) _When_(_SizeInBytes >=9, _Post_readable_size_(9)) char* _Buffer, + _In_ size_t _SizeInBytes + ); + +__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_0( + errno_t, _strtime_s, + _Post_readable_size_(9) char, _Buffer + ) + +__DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_0( + char*, __RETURN_POLICY_DST, _ACRTIMP, _strtime, + _Out_writes_z_(9), char, _Buffer + ) + +_ACRTIMP __time32_t __cdecl _time32( + _Out_opt_ __time32_t* _Time + ); + +_ACRTIMP __time64_t __cdecl _time64( + _Out_opt_ __time64_t* _Time + ); + +_Success_(return != 0) +_Check_return_ +_ACRTIMP int __cdecl _timespec32_get( + _Out_ struct _timespec32* _Ts, + _In_ int _Base + ); + +_Success_(return != 0) +_Check_return_ +_ACRTIMP int __cdecl _timespec64_get( + _Out_ struct _timespec64* _Ts, + _In_ int _Base + ); + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// DesktopCRT Time Functions +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#ifdef _CRT_USE_WINAPI_FAMILY_DESKTOP_APP + + _ACRTIMP void __cdecl _tzset(void); + + // The Win32 API GetLocalTime and SetLocalTime should be used instead. + _CRT_OBSOLETE(GetLocalTime) + _DCRTIMP unsigned __cdecl _getsystime( + _Out_ struct tm* _Tm + ); + + _CRT_OBSOLETE(SetLocalTime) + _DCRTIMP unsigned __cdecl _setsystime( + _In_ struct tm* _Tm, + _In_ unsigned _Milliseconds + ); + +#endif + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Inline Function Definitions +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#if !defined RC_INVOKED && !defined __midl && !defined _INC_TIME_INL && !defined _CRT_NO_TIME_T + + #ifdef _USE_32BIT_TIME_T + + _Check_return_ _CRT_INSECURE_DEPRECATE(ctime_s) + static __inline char* __CRTDECL ctime( + _In_ time_t const* const _Time + ) + { + return _ctime32(_Time); + } + + _Check_return_ + static __inline double __CRTDECL difftime( + _In_ time_t const _Time1, + _In_ time_t const _Time2 + ) + { + return _difftime32(_Time1, _Time2); + } + + _Check_return_ _CRT_INSECURE_DEPRECATE(gmtime_s) + static __inline struct tm* __CRTDECL gmtime( + _In_ time_t const* const _Time + ) + { + return _gmtime32(_Time); + } + + _Check_return_ _CRT_INSECURE_DEPRECATE(localtime_s) + static __inline struct tm* __CRTDECL localtime( + _In_ time_t const* const _Time + ) + { + return _localtime32(_Time); + } + + _Check_return_ + static __inline time_t __CRTDECL _mkgmtime( + _Inout_ struct tm* const _Tm + ) + { + return _mkgmtime32(_Tm); + } + + _Check_return_opt_ + static __inline time_t __CRTDECL mktime( + _Inout_ struct tm* const _Tm + ) + { + return _mktime32(_Tm); + } + + static __inline time_t __CRTDECL time( + _Out_opt_ time_t* const _Time + ) + { + return _time32(_Time); + } + + _Check_return_ + static __inline int __CRTDECL timespec_get( + _Out_ struct timespec* const _Ts, + _In_ int const _Base + ) + { + return _timespec32_get((struct _timespec32*)_Ts, _Base); + } + + #if __STDC_WANT_SECURE_LIB__ + _Check_return_wat_ + static __inline errno_t __CRTDECL ctime_s( + _Out_writes_(_SizeInBytes) _Post_readable_size_(26) char* const _Buffer, + _In_range_(>=,26) size_t const _SizeInBytes, + _In_ time_t const* const _Time + ) + { + return _ctime32_s(_Buffer, _SizeInBytes, _Time); + } + + #if _CRT_USE_CONFORMING_ANNEX_K_TIME + _Check_return_wat_ + static __inline struct tm* __CRTDECL gmtime_s( + _In_ time_t const* const _Time, + _Out_ struct tm* const _Tm + ) + { + if (_gmtime32_s(_Tm, _Time) == 0) + { + return _Tm; + } + return NULL; + } + + _Check_return_wat_ + static __inline struct tm* __CRTDECL localtime_s( + _In_ time_t const* const _Time, + _Out_ struct tm* const _Tm + ) + { + if (_localtime32_s(_Tm, _Time) == 0) + { + return _Tm; + } + return NULL; + } + #else // _CRT_USE_CONFORMING_ANNEX_K_TIME + _Check_return_wat_ + static __inline errno_t __CRTDECL gmtime_s( + _Out_ struct tm* const _Tm, + _In_ time_t const* const _Time + ) + { + return _gmtime32_s(_Tm, _Time); + } + + _Check_return_wat_ + static __inline errno_t __CRTDECL localtime_s( + _Out_ struct tm* const _Tm, + _In_ time_t const* const _Time + ) + { + return _localtime32_s(_Tm, _Time); + } + #endif // _CRT_USE_CONFORMING_ANNEX_K_TIME + #endif + + #else // ^^^ _USE_32BIT_TIME_T ^^^ // vvv !_USE_32BIT_TIME_T vvv + + _Check_return_ _CRT_INSECURE_DEPRECATE(ctime_s) + static __inline char* __CRTDECL ctime( + _In_ time_t const* const _Time + ) + { + return _ctime64(_Time); + } + + _Check_return_ + static __inline double __CRTDECL difftime( + _In_ time_t const _Time1, + _In_ time_t const _Time2 + ) + { + return _difftime64(_Time1, _Time2); + } + + _Check_return_ _CRT_INSECURE_DEPRECATE(gmtime_s) + static __inline struct tm* __CRTDECL gmtime( + _In_ time_t const* const _Time) + { + return _gmtime64(_Time); + } + + _CRT_INSECURE_DEPRECATE(localtime_s) + static __inline struct tm* __CRTDECL localtime( + _In_ time_t const* const _Time + ) + { + return _localtime64(_Time); + } + + _Check_return_ + static __inline time_t __CRTDECL _mkgmtime( + _Inout_ struct tm* const _Tm + ) + { + return _mkgmtime64(_Tm); + } + + _Check_return_opt_ + static __inline time_t __CRTDECL mktime( + _Inout_ struct tm* const _Tm + ) + { + return _mktime64(_Tm); + } + + static __inline time_t __CRTDECL time( + _Out_opt_ time_t* const _Time + ) + { + return _time64(_Time); + } + + _Check_return_ + static __inline int __CRTDECL timespec_get( + _Out_ struct timespec* const _Ts, + _In_ int const _Base + ) + { + return _timespec64_get((struct _timespec64*)_Ts, _Base); + } + + #if __STDC_WANT_SECURE_LIB__ + _Check_return_wat_ + static __inline errno_t __CRTDECL ctime_s( + _Out_writes_(_SizeInBytes) _Post_readable_size_(26) char* const _Buffer, + _In_range_(>=,26) size_t const _SizeInBytes, + _In_ time_t const* const _Time + ) + { + return _ctime64_s(_Buffer, _SizeInBytes, _Time); + } + + #if _CRT_USE_CONFORMING_ANNEX_K_TIME + _Check_return_wat_ + static __inline struct tm* __CRTDECL gmtime_s( + _In_ time_t const* const _Time, + _Out_ struct tm* const _Tm + ) + { + if (_gmtime64_s(_Tm, _Time) == 0) + { + return _Tm; + } + return NULL; + } + + _Check_return_wat_ + static __inline struct tm* __CRTDECL localtime_s( + _In_ time_t const* const _Time, + _Out_ struct tm* const _Tm + ) + { + if (_localtime64_s(_Tm, _Time) == 0) + { + return _Tm; + } + return NULL; + } + #else // _CRT_USE_CONFORMING_ANNEX_K_TIME + _Check_return_wat_ + static __inline errno_t __CRTDECL gmtime_s( + _Out_ struct tm* const _Tm, + _In_ time_t const* const _Time + ) + { + return _gmtime64_s(_Tm, _Time); + } + + _Check_return_wat_ + static __inline errno_t __CRTDECL localtime_s( + _Out_ struct tm* const _Tm, + _In_ time_t const* const _Time + ) + { + return _localtime64_s(_Tm, _Time); + } + #endif // _CRT_USE_CONFORMING_ANNEX_K_TIME + #endif + + #endif // !_USE_32BIT_TIME_T + +#endif + + + +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Non-ANSI Names for Compatibility +// +//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#if defined(_CRT_INTERNAL_NONSTDC_NAMES) && _CRT_INTERNAL_NONSTDC_NAMES + + #define CLK_TCK CLOCKS_PER_SEC + + #ifdef _CRT_USE_WINAPI_FAMILY_DESKTOP_APP + _CRT_NONSTDC_DEPRECATE(_tzset) _ACRTIMP void __cdecl tzset(void); + #endif + +#endif // _CRT_INTERNAL_NONSTDC_NAMES + + + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS +#endif // _INC_TIME diff --git a/sdk/include/ucrt/uchar.h b/sdk/include/ucrt/uchar.h new file mode 100644 index 0000000000000..50df37a5dcadd --- /dev/null +++ b/sdk/include/ucrt/uchar.h @@ -0,0 +1,50 @@ +// +// uchar.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// + +#pragma once +#ifndef _UCHAR // include guard for 3rd party interop +#define _UCHAR + +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + +#ifndef __STDC_UTF_16__ + #define __STDC_UTF_16__ 1 +#endif + +#ifndef __STDC_UTF_32__ + #define __STDC_UTF_32__ 1 +#endif + +typedef unsigned short _Char16_t; +typedef unsigned int _Char32_t; + +#if !defined __cplusplus || (defined _MSC_VER && _MSC_VER < 1900) + typedef unsigned short char16_t; + typedef unsigned int char32_t; +#endif + + +_Check_return_ _ACRTIMP size_t __cdecl mbrtoc16(_Out_opt_ char16_t *_Pc16, _In_reads_or_z_opt_(_N) const char *_S, _In_ size_t _N, _Inout_ mbstate_t *_Ps); +_Check_return_ _ACRTIMP size_t __cdecl c16rtomb(_Out_writes_opt_(4) char *_S, _In_ char16_t _C16, _Inout_ mbstate_t *_Ps); + +_Check_return_ _ACRTIMP size_t __cdecl mbrtoc32(_Out_opt_ char32_t *_Pc32, _In_reads_or_z_opt_(_N) const char *_S, _In_ size_t _N, _Inout_ mbstate_t *_Ps); +_Check_return_ _ACRTIMP size_t __cdecl c32rtomb(_Out_writes_opt_(4) char *_S, _In_ char32_t _C32, _Inout_ mbstate_t *_Ps); + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS + +/* + * Copyright (c) 1992-2013 by P.J. Plauger. ALL RIGHTS RESERVED. + * Consult your license regarding permissions and restrictions. + V6.40:0009 */ + #endif // _UCHAR diff --git a/sdk/include/ucrt/wchar.h b/sdk/include/ucrt/wchar.h new file mode 100644 index 0000000000000..b2ca8f73edff0 --- /dev/null +++ b/sdk/include/ucrt/wchar.h @@ -0,0 +1,286 @@ +// +// wchar.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// All of the types, macros, and function declarations for all wide-character +// related functionality. Most of the functionality is in the #included +// headers, which are also #included by other public headers. +// +#pragma once +#ifndef _INC_WCHAR // include guard for 3rd party interop +#define _INC_WCHAR + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + + + +#define WCHAR_MIN 0x0000 +#define WCHAR_MAX 0xffff + + + +typedef wchar_t _Wint_t; + + + +#if _CRT_FUNCTIONS_REQUIRED + + _Check_return_opt_ _Success_(return != 0) _Ret_z_ + _ACRTIMP wchar_t* __cdecl _wsetlocale( + _In_ int _Category, + _In_opt_z_ wchar_t const* _Locale + ); + + _Check_return_opt_ + _ACRTIMP _locale_t __cdecl _wcreate_locale( + _In_ int _Category, + _In_z_ wchar_t const* _Locale + ); + + + + _ACRTIMP wint_t __cdecl btowc( + _In_ int _Ch + ); + + _ACRTIMP size_t __cdecl mbrlen( + _In_reads_bytes_opt_(_SizeInBytes) _Pre_opt_z_ char const* _Ch, + _In_ size_t _SizeInBytes, + _Inout_ mbstate_t* _State + ); + + _ACRTIMP size_t __cdecl mbrtowc( + _Pre_maybenull_ _Post_z_ wchar_t* _DstCh, + _In_reads_bytes_opt_(_SizeInBytes) _Pre_opt_z_ char const* _SrcCh, + _In_ size_t _SizeInBytes, + _Inout_ mbstate_t* _State + ); + + _Success_(return == 0) + _ACRTIMP errno_t __cdecl mbsrtowcs_s( + _Out_opt_ size_t* _Retval, + _Out_writes_opt_z_(_Size) wchar_t* _Dst, + _In_ size_t _Size, + _Deref_pre_opt_z_ char const** _PSrc, + _In_ size_t _N, + _Inout_ mbstate_t* _State + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_1_3( + _Success_(return == 0) + errno_t, mbsrtowcs_s, + _Out_opt_ size_t*, _Retval, + _Post_z_ wchar_t, _Dest, + _Inout_ _Deref_prepost_opt_valid_ char const**, _PSource, + _In_ size_t, _Count, + _Inout_ mbstate_t*, _State + ) + + __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_3_SIZE( + _Success_(return == 0) _ACRTIMP, mbsrtowcs, + _Out_writes_opt_z_(_Count), wchar_t, _Dest, + _Deref_pre_opt_z_ char const**, _PSrc, + _In_ size_t, _Count, + _Inout_ mbstate_t*, _State + ) + + _Success_(return == 0) + _ACRTIMP errno_t __cdecl wcrtomb_s( + _Out_opt_ size_t* _Retval, + _Out_writes_opt_z_(_SizeInBytes) char* _Dst, + _In_ size_t _SizeInBytes, + _In_ wchar_t _Ch, + _Inout_opt_ mbstate_t* _State + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_1_2( + _Success_(return == 0) + errno_t, wcrtomb_s, + _Out_opt_ size_t*, _Retval, + _Out_writes_opt_z_(_Size) char, _Dest, + _In_ wchar_t, _Source, + _Inout_opt_ mbstate_t*, _State + ) + + __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_2_SIZE( + _ACRTIMP, wcrtomb, + _Pre_maybenull_ _Post_z_, char, _Dest, + _In_ wchar_t, _Source, + _Inout_opt_ mbstate_t*, _State + ) + + _Success_(return == 0) + _ACRTIMP errno_t __cdecl wcsrtombs_s( + _Out_opt_ size_t* _Retval, + _Out_writes_bytes_to_opt_(_SizeInBytes, *_Retval) char* _Dst, + _In_ size_t _SizeInBytes, + _Inout_ _Deref_prepost_z_ wchar_t const** _Src, + _In_ size_t _Size, + _Inout_opt_ mbstate_t* _State + ); + + __DEFINE_CPP_OVERLOAD_SECURE_FUNC_1_3( + _Success_(return == 0) + errno_t, wcsrtombs_s, + _Out_opt_ size_t*, _Retval, + _Out_writes_opt_z_(_Size) char, _Dest, + _Inout_ _Deref_prepost_z_ wchar_t const**, _PSrc, + _In_ size_t, _Count, + _Inout_opt_ mbstate_t*, _State + ) + + __DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_3_SIZE( + _ACRTIMP, wcsrtombs, + _Pre_maybenull_ _Post_z_, char, _Dest, + _Inout_ _Deref_prepost_z_ wchar_t const**, _PSource, + _In_ size_t, _Count, + _Inout_opt_ mbstate_t*, _State + ) + + _ACRTIMP int __cdecl wctob( + _In_ wint_t _WCh + ); + + #if __STDC_WANT_SECURE_LIB__ + + _Success_(return == 0) + errno_t __CRTDECL wmemcpy_s( + _Out_writes_to_opt_(_N1, _N) wchar_t* _S1, + _In_ rsize_t _N1, + _In_reads_opt_(_N) wchar_t const* _S2, + _In_ rsize_t _N + ); + + _Success_(return == 0) + errno_t __CRTDECL wmemmove_s( + _Out_writes_to_opt_(_N1, _N) wchar_t* _S1, + _In_ rsize_t _N1, + _In_reads_opt_(_N) wchar_t const* _S2, + _In_ rsize_t _N + ); + + #endif // __STDC_WANT_SECURE_LIB__ + + __inline int __CRTDECL fwide( + _In_opt_ FILE* _F, + _In_ int _M + ) + { + _CRT_UNUSED(_F); + return (_M); + } + + __inline int __CRTDECL mbsinit( + _In_opt_ mbstate_t const* _P + ) + { + return _P == NULL || _P->_Wchar == 0; + } + + __inline wchar_t _CONST_RETURN* __CRTDECL wmemchr( + _In_reads_(_N) wchar_t const* _S, + _In_ wchar_t _C, + _In_ size_t _N + ) + { + for (; 0 < _N; ++_S, --_N) + if (*_S == _C) + return (wchar_t _CONST_RETURN*)_S; + + return 0; + } + + __inline int __CRTDECL wmemcmp( + _In_reads_(_N) wchar_t const* _S1, + _In_reads_(_N) wchar_t const* _S2, + _In_ size_t _N + ) + { + for (; 0 < _N; ++_S1, ++_S2, --_N) + if (*_S1 != *_S2) + return *_S1 < *_S2 ? -1 : 1; + + return 0; + } + + _Post_equal_to_(_S1) + _At_buffer_(_S1, _Iter_, _N, _Post_satisfies_(_S1[_Iter_] == _S2[_Iter_])) + __inline _CRT_INSECURE_DEPRECATE_MEMORY(wmemcpy_s) + wchar_t* __CRTDECL wmemcpy( + _Out_writes_all_(_N) wchar_t* _S1, + _In_reads_(_N) wchar_t const* _S2, + _In_ size_t _N + ) + { + #pragma warning(suppress: 6386) // Buffer overrun + return (wchar_t*)memcpy(_S1, _S2, _N*sizeof(wchar_t)); + } + + __inline _CRT_INSECURE_DEPRECATE_MEMORY(wmemmove_s) + wchar_t* __CRTDECL wmemmove( + _Out_writes_all_opt_(_N) wchar_t* _S1, + _In_reads_opt_(_N) wchar_t const* _S2, + _In_ size_t _N + ) + { + #pragma warning(suppress: 6386) // Buffer overrun + return (wchar_t*)memmove(_S1, _S2, _N*sizeof(wchar_t)); + } + + _Post_equal_to_(_S) + _At_buffer_(_S, _Iter_, _N, _Post_satisfies_(_S[_Iter_] == _C)) + __inline wchar_t* __CRTDECL wmemset( + _Out_writes_all_(_N) wchar_t* _S, + _In_ wchar_t _C, + _In_ size_t _N + ) + { + wchar_t *_Su = _S; + for (; 0 < _N; ++_Su, --_N) + { + *_Su = _C; + } + return _S; + } + + #ifdef __cplusplus + + extern "C++" inline wchar_t* __CRTDECL wmemchr( + _In_reads_(_N) wchar_t* _S, + _In_ wchar_t _C, + _In_ size_t _N + ) + { + wchar_t const* const _SC = _S; + return const_cast(wmemchr(_SC, _C, _N)); + } + + #endif // __cplusplus + +#endif // _CRT_FUNCTIONS_REQUIRED + + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS +#endif // _INC_WCHAR diff --git a/sdk/include/ucrt/wctype.h b/sdk/include/ucrt/wctype.h new file mode 100644 index 0000000000000..7e58e91eabdd6 --- /dev/null +++ b/sdk/include/ucrt/wctype.h @@ -0,0 +1,33 @@ +// +// stdio.h +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The C Standard Library header. +// +#pragma once +#ifndef _INC_WCTYPE // include guard for 3rd party interop +#define _INC_WCTYPE + +#include +#include + +#pragma warning(push) +#pragma warning(disable: _UCRT_DISABLED_WARNINGS) +_UCRT_DISABLE_CLANG_WARNINGS + +_CRT_BEGIN_C_HEADER + + + +typedef wchar_t wctrans_t; +_ACRTIMP wint_t __cdecl towctrans(wint_t c, wctrans_t value); +_ACRTIMP wctrans_t __cdecl wctrans(const char *name); +_ACRTIMP wctype_t __cdecl wctype(const char *name); + + + +_CRT_END_C_HEADER +_UCRT_RESTORE_CLANG_WARNINGS +#pragma warning(pop) // _UCRT_DISABLED_WARNINGS +#endif // _INC_WCTYPE diff --git a/sdk/include/vcruntime/emmintrin.h b/sdk/include/vcruntime/emmintrin.h index 2c053599e0d2a..99aeef76616dd 100644 --- a/sdk/include/vcruntime/emmintrin.h +++ b/sdk/include/vcruntime/emmintrin.h @@ -1345,8 +1345,15 @@ __INTRIN_INLINE_SSE2 __m128i _mm_xor_si128(__m128i a, __m128i b) return (__m128i)((__v2du)a ^ (__v2du)b); } +#ifdef __clang__ #define _mm_slli_si128(a, imm) \ ((__m128i)__builtin_ia32_pslldqi128_byteshift((__v2di)(__m128i)(a), (int)(imm))) +#else +__INTRIN_INLINE_SSE2 __m128i _mm_slli_si128(__m128i a, const int imm) +{ + return (__m128i)__builtin_ia32_pslldqi128(a, imm * 8); +} +#endif __INTRIN_INLINE_SSE2 __m128i _mm_slli_epi16(__m128i a, int count) { @@ -1398,8 +1405,15 @@ __INTRIN_INLINE_SSE2 __m128i _mm_sra_epi32(__m128i a, __m128i count) return (__m128i)__builtin_ia32_psrad128((__v4si)a, (__v4si)count); } +#ifdef __clang__ #define _mm_srli_si128(a, imm) \ ((__m128i)__builtin_ia32_psrldqi128_byteshift((__v2di)(__m128i)(a), (int)(imm))) +#else +__INTRIN_INLINE_SSE2 __m128i _mm_srli_si128(__m128i a, const int imm) +{ + return (__m128i)__builtin_ia32_psrldqi128(a, imm * 8); +} +#endif __INTRIN_INLINE_SSE2 __m128i _mm_srli_epi16(__m128i a, int count) { diff --git a/sdk/include/vcruntime/excpt.h b/sdk/include/vcruntime/excpt.h index 8bd6e90cc4680..faf5f2fe40530 100644 --- a/sdk/include/vcruntime/excpt.h +++ b/sdk/include/vcruntime/excpt.h @@ -74,7 +74,7 @@ typedef enum _EXCEPTION_DISPOSITION #endif -#if defined(_MSC_VER) || (defined(__clang__) && defined(__SEH__)) +#if (defined(_MSC_VER) || (defined(__clang__) && defined(__SEH__))) && !defined(_exception_code) unsigned long __cdecl _exception_code(void); void *__cdecl _exception_info(void); int __cdecl _abnormal_termination(void); diff --git a/sdk/include/vcruntime/mingw32/intrin_x86.h b/sdk/include/vcruntime/mingw32/intrin_x86.h index f6300702b4045..0eb1da7258e41 100644 --- a/sdk/include/vcruntime/mingw32/intrin_x86.h +++ b/sdk/include/vcruntime/mingw32/intrin_x86.h @@ -95,14 +95,14 @@ __INTRIN_INLINE void _ReadWriteBarrier(void) #define _ReadBarrier _ReadWriteBarrier #define _WriteBarrier _ReadWriteBarrier -#if !HAS_BUILTIN(_mm_mfence) +#if !HAS_BUILTIN(_mm_mfence) && !defined(__clang__) __INTRIN_INLINE void _mm_mfence(void) { __asm__ __volatile__("mfence" : : : "memory"); } #endif -#if !HAS_BUILTIN(_mm_lfence) +#if !HAS_BUILTIN(_mm_lfence)&& !defined(__clang__) __INTRIN_INLINE void _mm_lfence(void) { _ReadBarrier(); @@ -1227,7 +1227,7 @@ __INTRIN_INLINE unsigned int __cdecl _rotl(unsigned int value, int shift) __INTRIN_INLINE unsigned long long _rotl64(unsigned long long value, int shift) { unsigned long long retval; - __asm__("rolq %b[shift], %k[retval]" : [retval] "=rm" (retval) : "[retval]" (value), [shift] "Nc" (shift)); + __asm__("rolq %b[shift], %[retval]" : [retval] "=rm" (retval) : "[retval]" (value), [shift] "Nc" (shift)); return retval; } #else /* __x86_64__ */ @@ -1271,7 +1271,7 @@ __INTRIN_INLINE unsigned short __cdecl _rotr16(unsigned short value, unsigned ch __INTRIN_INLINE unsigned long long _rotr64(unsigned long long value, int shift) { unsigned long long retval; - __asm__("rorq %b[shift], %k[retval]" : [retval] "=rm" (retval) : "[retval]" (value), [shift] "Nc" (shift)); + __asm__("rorq %b[shift], %[retval]" : [retval] "=rm" (retval) : "[retval]" (value), [shift] "Nc" (shift)); return retval; } #else /* __x86_64__ */ @@ -1301,8 +1301,13 @@ __INTRIN_INLINE unsigned long __cdecl _lrotr(unsigned long value, int shift) } #endif -#ifdef __x86_64__ -__INTRIN_INLINE unsigned long long __ll_lshift(unsigned long long Mask, int Bit) +#if defined __x86_64__ +#if defined(__clang__) && defined(_MSC_VER) // stupid hack because clang is broken +static inline __attribute__((__always_inline__)) +#else +__INTRIN_INLINE +#endif +unsigned long long __ll_lshift(unsigned long long Mask, int Bit) { unsigned long long retval; unsigned char shift = Bit & 0x3F; @@ -1348,7 +1353,12 @@ __INTRIN_INLINE unsigned long long __ull_rshift(unsigned long long Mask, int Bit just confuses it. Also we declare Bit as an int and then truncate it to match Visual C++ behavior */ -__INTRIN_INLINE unsigned long long __ll_lshift(unsigned long long Mask, int Bit) +#if defined(__clang__) && defined(_MSC_VER) // stupid hack because clang is broken +static inline __attribute__((__always_inline__)) +#else +__INTRIN_INLINE +#endif +unsigned long long __ll_lshift(unsigned long long Mask, int Bit) { unsigned long long retval = Mask; @@ -1641,15 +1651,19 @@ __INTRIN_INLINE unsigned long __cdecl _outpd(unsigned short Port, unsigned long /*** System information ***/ +#if !HAS_BUILTIN(__cpuid) __INTRIN_INLINE void __cpuid(int CPUInfo[4], int InfoType) { __asm__ __volatile__("cpuid" : "=a" (CPUInfo[0]), "=b" (CPUInfo[1]), "=c" (CPUInfo[2]), "=d" (CPUInfo[3]) : "a" (InfoType)); } +#endif +#if !HAS_BUILTIN(__cpuidex) __INTRIN_INLINE void __cpuidex(int CPUInfo[4], int InfoType, int ECXValue) { __asm__ __volatile__("cpuid" : "=a" (CPUInfo[0]), "=b" (CPUInfo[1]), "=c" (CPUInfo[2]), "=d" (CPUInfo[3]) : "a" (InfoType), "c" (ECXValue)); } +#endif #if !HAS_BUILTIN(__rdtsc) __INTRIN_INLINE unsigned long long __rdtsc(void) @@ -1972,8 +1986,12 @@ __INTRIN_INLINE void __invlpg(void *Address) /*** System operations ***/ - -__INTRIN_INLINE unsigned long long __readmsr(unsigned long reg) +#if defined(__clang__) && defined(_MSC_VER) // stupid hack because clang is broken +static inline __attribute__((__always_inline__)) +#else +__INTRIN_INLINE +#endif +unsigned long long __readmsr(unsigned long reg) { #ifdef __x86_64__ unsigned long low, high; @@ -1986,7 +2004,12 @@ __INTRIN_INLINE unsigned long long __readmsr(unsigned long reg) #endif } -__INTRIN_INLINE void __writemsr(unsigned long Register, unsigned long long Value) +#if defined(__clang__) && defined(_MSC_VER) // stupid hack because clang is broken +static inline __attribute__((__always_inline__)) +#else +__INTRIN_INLINE +#endif +void __writemsr(unsigned long Register, unsigned long long Value) { #ifdef __x86_64__ __asm__ __volatile__("wrmsr" : : "a" (Value), "d" (Value >> 32), "c" (Register)); diff --git a/sdk/include/vcruntime/vcruntime.h b/sdk/include/vcruntime/vcruntime.h index cd7d591340740..bc16388bc970e 100644 --- a/sdk/include/vcruntime/vcruntime.h +++ b/sdk/include/vcruntime/vcruntime.h @@ -25,7 +25,7 @@ #define _CRT_UNPARENTHESIZE_(...) __VA_ARGS__ #define _CRT_UNPARENTHESIZE(...) _CRT_UNPARENTHESIZE_ __VA_ARGS__ -#ifndef _MSC_VER +#if !defined(_MSC_VER) && !defined(__pragma) #define __pragma(x) _Pragma(_CRT_STRINGIZE(x)) #endif diff --git a/sdk/include/vcruntime/xmmintrin.h b/sdk/include/vcruntime/xmmintrin.h index 224cbc25f1bbb..37c7fefd1050f 100644 --- a/sdk/include/vcruntime/xmmintrin.h +++ b/sdk/include/vcruntime/xmmintrin.h @@ -531,14 +531,14 @@ do { \ /* Use inline functions on GCC/Clang */ -#if !HAS_BUILTIN(_mm_getcsr) +#if !HAS_BUILTIN(_mm_getcsr) && !defined(_MSC_VER) __INTRIN_INLINE_SSE unsigned int _mm_getcsr(void) { return __builtin_ia32_stmxcsr(); } #endif -#if !HAS_BUILTIN(_mm_setcsr) +#if !HAS_BUILTIN(_mm_setcsr) && !defined(_MSC_VER) __INTRIN_INLINE_SSE void _mm_setcsr(unsigned int a) { __builtin_ia32_ldmxcsr(a); @@ -1136,7 +1136,7 @@ __INTRIN_INLINE_SSE void _mm_stream_ps(float *__p, __m128 __a) #endif } -#if !HAS_BUILTIN(_mm_sfence) +#if !HAS_BUILTIN(_mm_sfence) && !defined(_MSC_VER) __INTRIN_INLINE_SSE void _mm_sfence(void) { __builtin_ia32_sfence(); diff --git a/sdk/include/xdk/rtlfuncs.h b/sdk/include/xdk/rtlfuncs.h index 6aeca552d6e2e..f35b8e28452fc 100644 --- a/sdk/include/xdk/rtlfuncs.h +++ b/sdk/include/xdk/rtlfuncs.h @@ -22,6 +22,9 @@ #define FAST_FAIL_MRDATA_MODIFIED 19 #define FAST_FAIL_INVALID_FAST_FAIL_CODE 0xFFFFFFFF +$endif(_WDMDDK_ || _WINNT_) +$if (_WDMDDK_) + DECLSPEC_NORETURN FORCEINLINE VOID @@ -31,9 +34,6 @@ RtlFailFast( __fastfail(Code); } -$endif(_WDMDDK_ || _WINNT_) -$if (_WDMDDK_) - #if !defined(NO_KERNEL_LIST_ENTRY_CHECKS) && (defined(_M_CEE_PURE) || defined(_M_CEE_SAFE)) #define NO_KERNEL_LIST_ENTRY_CHECKS #endif diff --git a/sdk/include/xdk/winnt.template.h b/sdk/include/xdk/winnt.template.h index 050e87d472d8d..0da46e9285b56 100644 --- a/sdk/include/xdk/winnt.template.h +++ b/sdk/include/xdk/winnt.template.h @@ -28,8 +28,8 @@ #error Compiler too old! #endif -#if defined(__LP64__) || (!defined(_M_AMD64) && defined(__WINESRC__)) -#if !defined(__ROS_LONG64__) +#if (defined(_LP64) || defined(__LP64__)) && !defined(_M_AMD64) +#ifndef __ROS_LONG64__ #define __ROS_LONG64__ #endif #endif diff --git a/sdk/include/xdk/winnt_old.h b/sdk/include/xdk/winnt_old.h index 157c3724e8096..94d603073a87d 100644 --- a/sdk/include/xdk/winnt_old.h +++ b/sdk/include/xdk/winnt_old.h @@ -583,7 +583,7 @@ #define SECTION_MAP_EXECUTE 8 #define SECTION_ALL_ACCESS 0xf001f #define WRITE_WATCH_FLAG_RESET 0x01 -#define MESSAGE_RESOURCE_UNICODE 1 + #define RTL_CRITSECT_TYPE 0 #define RTL_RESOURCE_TYPE 1 @@ -952,9 +952,7 @@ #define DLL_PROCESS_ATTACH 1 #define DLL_THREAD_ATTACH 2 #define DLL_THREAD_DETACH 3 -#ifdef __WINESRC__ -#define DLL_WINE_PREATTACH 8 /* Never called, but defined for compatibility with Wine source */ -#endif + #define TAPE_ABSOLUTE_POSITION 0 #define TAPE_LOGICAL_POSITION 1 #define TAPE_PSEUDO_LOGICAL_POSITION 2 @@ -2650,6 +2648,8 @@ typedef struct _MESSAGE_RESOURCE_ENTRY { BYTE Text[1]; } MESSAGE_RESOURCE_ENTRY, *PMESSAGE_RESOURCE_ENTRY; +#define MESSAGE_RESOURCE_UNICODE 1 + typedef struct _MESSAGE_RESOURCE_BLOCK { DWORD LowId; DWORD HighId; @@ -2793,9 +2793,17 @@ typedef struct _RTL_CRITICAL_SECTION_DEBUG { LIST_ENTRY ProcessLocksList; DWORD EntryCount; DWORD ContentionCount; - DWORD Flags; - WORD CreatorBackTraceIndexHigh; - WORD SpareWORD; + union + { + DWORD_PTR WineDebugString; + DWORD_PTR Spare[1]; + struct + { + DWORD Flags; + WORD CreatorBackTraceIndexHigh; + WORD SpareWORD; + }; + }; } RTL_CRITICAL_SECTION_DEBUG, *PRTL_CRITICAL_SECTION_DEBUG, RTL_RESOURCE_DEBUG, *PRTL_RESOURCE_DEBUG; #include "pshpack8.h" @@ -4480,7 +4488,11 @@ DbgRaiseAssertionFailure(VOID) typedef struct _TP_POOL TP_POOL, *PTP_POOL; typedef struct _TP_WORK TP_WORK, *PTP_WORK; typedef struct _TP_CALLBACK_INSTANCE TP_CALLBACK_INSTANCE, *PTP_CALLBACK_INSTANCE; +typedef struct _TP_TIMER TP_TIMER, *PTP_TIMER; +typedef struct _TP_WAIT TP_WAIT, *PTP_WAIT; +typedef struct _TP_IO TP_IO, *PTP_IO; +typedef DWORD TP_WAIT_RESULT; typedef DWORD TP_VERSION, *PTP_VERSION; typedef enum _TP_CALLBACK_PRIORITY { @@ -4491,6 +4503,12 @@ typedef enum _TP_CALLBACK_PRIORITY { TP_CALLBACK_PRIORITY_COUNT = TP_CALLBACK_PRIORITY_INVALID } TP_CALLBACK_PRIORITY; +typedef struct _TP_POOL_STACK_INFORMATION +{ + SIZE_T StackReserve; + SIZE_T StackCommit; +} TP_POOL_STACK_INFORMATION,*PTP_POOL_STACK_INFORMATION; + typedef VOID (NTAPI *PTP_WORK_CALLBACK)( _Inout_ PTP_CALLBACK_INSTANCE Instance, @@ -4509,6 +4527,9 @@ typedef VOID _Inout_opt_ PVOID ObjectContext, _Inout_opt_ PVOID CleanupContext); +typedef VOID (NTAPI *PTP_TIMER_CALLBACK)(PTP_CALLBACK_INSTANCE,PVOID,PTP_TIMER); +typedef VOID (NTAPI *PTP_WAIT_CALLBACK)(PTP_CALLBACK_INSTANCE,PVOID,PTP_WAIT,TP_WAIT_RESULT); + #if (_WIN32_WINNT >= _WIN32_WINNT_WIN7) typedef struct _TP_CALLBACK_ENVIRON_V3 { TP_VERSION Version; diff --git a/sdk/lib/3rdparty/freetype/CMakeLists.txt b/sdk/lib/3rdparty/freetype/CMakeLists.txt index 6eb1c346c51e9..5f9fa7e7092ba 100644 --- a/sdk/lib/3rdparty/freetype/CMakeLists.txt +++ b/sdk/lib/3rdparty/freetype/CMakeLists.txt @@ -6,35 +6,29 @@ include_directories(include) list(APPEND SOURCE src/autofit/autofit.c - src/base/ftadvanc.c + src/base/ftbase.c src/base/ftbbox.c + src/base/ftbdf.c src/base/ftbitmap.c - src/base/ftcalc.c - src/base/ftfntfmt.c - src/base/ftgloadr.c + src/base/ftcid.c + src/base/ftdebug.c + src/base/ftfstype.c + src/base/ftgasp.c src/base/ftglyph.c src/base/ftgxval.c - src/base/fthash.c src/base/ftinit.c - src/base/ftlcdfil.c src/base/ftmm.c - src/base/ftobjs.c src/base/ftotval.c - src/base/ftoutln.c src/base/ftpatent.c src/base/ftpfr.c - src/base/ftpsprop.c - src/base/ftrfork.c - src/base/ftsnames.c - src/base/ftstream.c src/base/ftstroke.c src/base/ftsynth.c src/base/ftsystem.c - src/base/fttrigon.c src/base/fttype1.c - src/base/ftutil.c src/base/ftwinfnt.c src/bdf/bdf.c + src/bzip2/ftbzip2.c + src/cache/ftcache.c src/cff/cff.c src/cid/type1cid.c src/gzip/ftgzip.c @@ -43,7 +37,7 @@ list(APPEND SOURCE src/pfr/pfr.c src/psaux/psaux.c src/pshinter/pshinter.c - src/psnames/psmodule.c + src/psnames/psnames.c src/raster/raster.c src/sfnt/sfnt.c src/smooth/smooth.c diff --git a/sdk/lib/3rdparty/freetype/ChangeLog b/sdk/lib/3rdparty/freetype/ChangeLog index fa38730b73271..670e8480550d1 100644 --- a/sdk/lib/3rdparty/freetype/ChangeLog +++ b/sdk/lib/3rdparty/freetype/ChangeLog @@ -1,17 +1,15 @@ -2018-01-08 Werner Lemberg +2019-03-15 Werner Lemberg - * Version 2.9 released. - ======================= + * Version 2.10.0 released. + ========================== - Tag sources with `VER-2-9'. + Tag sources with `VER-2-10-0'. - * docs/VERSION.TXT: Add entry for version 2.9. + * docs/VERSION.TXT: Add entry for version 2.10.0. + * docs/CHANGES: Updated. - * README, Jamfile (RefDoc), builds/windows/vc2005/freetype.vcproj, - builds/windows/vc2005/index.html, - builds/windows/vc2008/freetype.vcproj, - builds/windows/vc2008/index.html, + * README, Jamfile (RefDoc), src/base/ftver.rc, builds/windows/vc2010/freetype.vcxproj, builds/windows/vc2010/index.html, builds/windows/visualc/freetype.dsp, @@ -20,4915 +18,4852 @@ builds/windows/visualce/freetype.dsp, builds/windows/visualce/freetype.vcproj, builds/windows/visualce/index.html, - builds/windows/ftver.rc, builds/wince/vc2005-ce/freetype.vcproj, builds/wince/vc2005-ce/index.html, builds/wince/vc2008-ce/freetype.vcproj, - builds/wince/vc2008-ce/index.html: s/2.8.1/2.9/, s/281/29/. + builds/wince/vc2008-ce/index.html: s/2.9.1/2.10.0/, s/291/2100/. - * include/freetype/freetype.h (FREETYPE_MINOR): Set to 9. + * include/freetype/freetype.h (FREETYPE_MINOR): Set to 10. (FREETYPE_PATCH): Set to 0. - * builds/unix/configure.raw (version_info): Set to 22:0:16. - * CMakeLists.txt (VERSION_PATCH): Set to 1. + * builds/unix/configure.raw (version_info): Set to 23:0:17. + * CMakeLists.txt (VERSION_MINOR): Set to 10. + (VERSION_PATCH): Set to 0. -2018-01-07 Werner Lemberg + * builds/toplevel.mk (version, winversion): Since the minor version + number has two digits now, never omit the patch number. We would + get ambiguous zip file names otherwise. + (dist): Remove remnants of `docmaker' tool. + (do-dist): Remove unused intermediate files. - Add check for librt, needed for `ftbench' (#52824). + * src/cff/cffparse.c (destrict_c2s_item): Guard function with + CFF_CONFIG_OPTION_OLD_ENGINE macro. - * builds/unix/configure.raw (LIB_CLOCK_GETTIME): Define; this will - hold `-lrt' if necessary. +2019-03-07 Andrei Alexeyev <0x416b617269@gmail.com> + Werner Lemberg - * builds/unix/unix-cc.in (LIB_CLOCK_GETTIME): New variable. + Fix invalid function pointer casts. -2018-01-07 Ewald Hew + This change should allow Freetype to work on WASM/Emscripten without + needing `-s EMULATE_FUNCTION_POINTER_CASTS=1'. - [psaux] Fix Type 1 glyphs with too many stem hints. + * src/autofit/afdummy.c (af_dummy_hints_apply): Fix signature. - According to the CFF specification, charstrings can have up to 96 stem - hints. Due to hint replacement routines in Type 1 charstrings, some - glyphs are rejected by the Adobe engine, which implements the above - limit. This fix turns off hinting for such glyphs. + * src/cid/cidload.c (cid_parse_font_matrix, parse_fd_array, + parse_expansion_factor, parse_font_name): Return `void', not + `FT_Error'. - * src/psaux/pshints.c (cf2_hintmap_build): Reset the error from calling - `cf2_hintmask_setAll' on a problematic Type 1 charstring and turn off - hinting. + * include/freetype/internal/ftobjs.h (FT_CMap_CharVarIsDefaultFunc): + Fix signature. -2018-01-06 Werner Lemberg +2019-03-05 Werner Lemberg - Add `FT_Done_MM_Var'. + [base] Handle numeric overflow (#55827). - This is necessary in case the application's memory routines differ - from FreeType. A typical example is a Python application on Windows - that calls FreeType compiled as a DLL via the `ctypes' interface. + * src/base/ftglyph.c (FT_Glyph_Get_CBox): Use `FT_PIX_CEIL_LONG'. - * include/freetype/ftmm.h, src/base/ftmm.c (FT_Done_MM_Var): Declare - and define. +2019-03-05 Sebastian Rasmussen - * docs/CHANGES: Updated. + [psaux] Fix use of uninitialized memory (#55832). -2018-01-03 Werner Lemberg + * src/psaux/psintrp.c (cf2_interpT2CharString): The call to + `cf2_arrstack_setCount' may fail because the allocator ran out of + memory. When this happens the stack is still written to before the + error condition is checked. This means that FreeType writes outside + of allocated memory. This commit moves the error check prior to the + stack assignment, hence the function now properly returns with an + error condition. - [truetype] Round offsets of glyph components only if hinting is on. +2019-02-23 Werner Lemberg - * src/truetype/ttgload.c (TT_Process_Composite_Component): Implement - it. + * src/base/ftbitmap.c (FT_Bitmap_Blend): No fractional offsets. -2018-01-03 Werner Lemberg + The function only provided a framework without an actual + implementation, which this commit removes. - * src/truetype/ttgxvar.c (ft_var_to_design): Remove dead code. +2019-02-23 Werner Lemberg - This is a better fix than the previous commit, which is now - reverted. + * src/tools/update-copyright-year: Insert `(C)'. -2018-01-03 Alexei Podtelezhnikov +2019-02-21 Armin Hasitzka - Move internal LCD-related declarations. + [truetype] Mask numeric overflows. - * include/freetype/ftlcdfil.h (ft_lcd_padding, ft_lcd_filter_fir): - Move from here... - * include/freetype/internal/ftobjs.h: ... to here. + * src/truetype/ttinterp.c (Move_CVT, Move_CVT_Stretched, Ins_MIRP): + Mask numeric overflows. -2018-01-03 Alexei Podtelezhnikov + Reported as - * include/freetype/config/ftconfig.h (FT_EXPORT, FT_EXPORT_DEF) - [_MSC_VER]: Limit Visual C++ attributes. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11681 + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11734 -2018-01-03 Werner Lemberg +2019-02-21 Armin Hasitzka - [truetype] Make blend/design coordinate round-tripping work. + [psaux] Mask numeric overflow. - Behdad reported that setting blend coordinates, then getting design - coordinates did incorrectly return the default instance's - coordinates. + * src/psaux/cffdecode.c (cff_decoder_parse_charstrings): Mask numeric + overflow. - * src/truetype/ttgxvar.c (tt_set_mm_blend): Fix it. + Reported as -2017-12-31 Werner Lemberg + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=13041 - * src/sfnt/ttcmap.c (tt_cmap2_char_next): Fix endless loop. +2019-02-16 Wink Saville - Reported as + * src/autofit/afwarp.h (af_warper_compute): Fix declaration. - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=4838 +2019-02-02 Nikolaus Waxweiler -2017-12-31 Werner Lemberg + [truetype] Apply MVAR hasc, hdsc and hlgp metrics to current FT_Face metrics. - Synchronize other Windows project files. + Instead of setting typo or win metrics as the new `FT_Face' metrics + indiscriminately, apply only typo deltas to the currently active + `FT_Face' metrics. This prevents line height differences when the + default outlines were used as the regular face and instances for + everything else, for example. - * builds/windows/*: Add missing files. + * src/truetype/ttgxvar.c (tt_apply_mvar): Implement. -2017-12-31 Werner Lemberg +2019-02-02 Nikolaus Waxweiler - Update Visual C 2010 project files. + [sfnt] Use typo metrics if OS/2 fsSelection USE_TYPO_METRICS bit is set. - Problem reported by Hin-Tak. + If the `OS/2' table exists and `fsSelection' bit 7 + (USE_TYPO_METRICS) is set, use the `sTypo*' set of values to compute + the `FT_Face's ascender, descender, and height. Otherwise, fall + back to old behavior. - * builds/windows/vc2010/freetype.vcxproj: Add files `ftbdf.c' and - `ftcid.c'. - Sort entries. - * builds/windows/vc2010/freetype.vcxproj.filter: Ditto. - Fix members of `FT_MODULE' group. + * src/sfnt/sfobjs.c (sfnt_load_face): Implement. -2017-12-30 Werner Lemberg +2019-01-18 John Tytgat - * builds/vms/ftconfig.h: Synchronize with unix `ftconfig.in' file. + [sfnt] Handle TT fonts having two PostScript font names (#55471). -2017-12-28 Werner Lemberg + * src/sfnt/sfdriver.c (sfnt_get_name_id): Prefer English over any + other language found for PostScript font names. - * builds/unix/ftconfig.in: Synchronize with main `ftconfig.h' file. +2019-01-08 Chris Liddell - Reported by Nikolaus. + [psaux] Fix closepath (#55414). -2017-12-27 Werner Lemberg + All of the Type 1 path building is done with code common to the + revised CFF engine, with the exception of closepath, which was still + calling ps_builder_close_contour(), thus previously cached segments + were not always written to the path, and glyph corruption, or even + invalid outlines were possible. - Fix compiler warnings. + * src/psauc/psinterp.c (cf2_interpT2CharString) : + Switch to calling `cf2_glyphpath_closeOpenPath'. - * src/base/ftbitmap.c (ft_bitmap_assure_buffer): Make `pitch' and - `new_pitch' unsigned. +2018-12-29 Werner Lemberg - * src/base/ftpsprop.c: Include FT_INTERNAL_POSTSCRIPT_PROPS_H. + * src/autofit/aflatin2.c: Some fixes from `aflatin.c' (#55310). -2017-12-27 Werner Lemberg +2018-12-25 Werner Lemberg - Fixes for `make multi'. + * src/psaux/cffdecode.c (cff_operaor_seac): Fix numeric overflow. - * include/freetype/internal/ftpsprop.h: Use `FT_BASE_CALLBACK'. - (ps_property_get): Harmonize declaration with corresponding - function typedef. + Reported as - * include/freety[e/internal/fttrace.h: Add `trace_psprops'. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11915 - * src/base/ftpsprop.c: Include necessary header files. - (FT_COMPONENT): Define. - (ps_property_set): Tag with `FT_BASE_CALLBACK_DEF'. - (ps_property_get): Tag with `FT_BASE_CALLBACK_DEF'. - Harmonize declaration with corresponding function typedef. +2018-12-12 Werner Lemberg -2017-12-27 Werner Lemberg + [gxvalid] Fix compiler warnings. - Provide support for intra-module callback functions. + * src/gxvalid/gxvjust.c (gxv_just_check_max_gid), + src/gxvalid/gxvmort.c (gxv_mort_coverage_validate): Use `FT_UNUSED'. - This is needed especially for `make multi' with C++. +2018-12-11 Werner Lemberg - * include/freetype/config/ftconfig.h (FT_BASE_CALLBACK, - FT_BASE_CALLBACK_DEF): New macros. + * src/truetype/ttgload.c (TT_Hint_Glyph): Remove useless test. -2017-12-25 Ewald Hew + `control_len' only gets its value from `n_ins' (and vice versa), + which is always read as `unsigned short' and thus can't be larger + than 0xFFFF. - Move PostScript drivers' property handlers to `base'. +2018-12-04 Werner Lemberg - This reduces the amount of duplicated code across PostScript - drivers. + [bdf] Ignore data after `ENDFONT'. - * src/cff/cffdrivr.c, src/cid/cidriver.c, src/type1/t1driver.c - ({cff,cid,t1}_property_{get,set}): Moved to... - * include/freetype/internal/ftpsprop.h: ...this new file. - (ps_property_{get,set}): New functions to replace moved ones. + Reported as - * src/base/ftpsprop.c: New file that implements above functions. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10798 - * include/freetype/internal/internal.h - (FT_INTERNAL_POSTSCRIPT_PROPS_H): New macro. + * src/bdf/bdflib.c (_bdf_parse_end): New function. + (_bdf_parse_glyphs): Switch to `_bdf_parse_end' after `ENDFONT' has + been encountered. - * src/cff/cffdrivr.c, src/cid/cidriver.c, src/type1/t1driver.c: - Updated. +2018-12-02 Alexei Podtelezhnikov - * src/base/Jamfile, src/base/rules.mk (BASE_SRC), src/base/ftbase.c: - Updated. + * builds/windows/visualc/freetype.dsp: Dust off. -2017-12-20 Werner Lemberg +2018-11-27 Alexei Podtelezhnikov - Speed up FT_Set_Var_{Design,Blend}_Coordinates if curr == new. + * builds/windows/vc2010/freetype.vcxproj: Simplify. - We exit early if the current design or blend coordinates are - identical to the new ones. +2018-11-27 Chris Liddell - * src/truetype/ttgxvar.c (tt_set_mm_blend, TT_Set_Var_Design): - Implement it, returning internal error code -1 if there will be no - variation change. + [type1,cff] Add FT_{Set,Get}_MM_WeightVector API calls. - * src/type1/t1load.c (t1_set_mm_blend): Ditto. + For multiple master fonts, common usage (in Postscript) is to modify + the WeightVector of an existing font instance, this addition + supports that use. - * src/base/ftmm.c (FT_Set_Var_Design_Coordinates, - FT_Set_MM_Blend_Coordinates, FT_Set_Var_Blend_Coordinates): Updated. + * include/freetype/ftmm.h, src/base/ftmm.c (FT_Set_MM_WeightVector, + FT_Get_MM_WeightVector): New API functions. -2017-12-18 Werner Lemberg + * include/freetype/internalservices/svmm.h + (FT_Set_MM_WeightVector_Func, FT_Get_MM_WeightVector_Func): New + function types. + (MultiMasters): Add `set_mm_weightvector' and `get_mm_weightvector' + members. + (FT_DEFINE_SERVICE_MULTIMASTERSREC): Updated. - [sfnt] Fix charmap type 2 iterator (#52646). + * src/cffcffdrivr.c (cff_set_mm_weightvector, + cff_get_mm_weightvector): New functions. + (cff_service_multi_masters): Register them. - The subsetted demo font of the report that exhibits the bug has a - very unusual type 2 cmap for Unicode(!): It contains only two - sub-headers, one for one-byte characters (covering the range 0x20 to - 0xFA), and a second one for higher byte 0x01 (just for character - code U+0131). + * src/truetype/ttdriver.c (tt_service_gx_multi_masters): Updated. + This driver doesn't use the new interface. - Before this commit, the iterator wasn't able to correctly handle a - sub-header for higher byte 0x01. + * src/type1/t1load.c (T1_Set_MM_WeightVector, + T1_Get_MM_WeightVector): New functions. + * src/type1/t1driver.c (t1_service_multi_masters): Register them. + * src/type1/t1load.h: Updated. - * src/sfnt/ttcmap.c (tt_cmap2_char_next): Fix character increment - for outer loop. +2018-11-27 Ben Wagner -2017-12-18 Matthias Clasen + [cff] Fix compiler warning (#55105). - [truetype] Fix clamping, minor tracing code beautification. + * src/cff/cffparse.c (cff_parser_run): Guard label only used if + CFF_CONFIG_OPTION_OLD_ENGINE is active. - * src/truetype/ttgxvar.c (ft_var_to_normalized): Trace number of - design coordinates. - Use clamped value. +2018-11-27 Ben Wagner -2017-12-18 Werner Lemberg + [truetype] Fix numeric overflow (#55103). - * src/*/*: Only use `ft_' and `FT_' variants of stdc library stuff. + * src/truetype/ttgload.c (compute_glyph_metrics): Use `SUB_LONG'. -2017-12-18 Werner Lemberg +2018-11-25 Alexei Podtelezhnikov - * src/truetype/ttgxvar.c (tt_face_vary_cvt): Add size guard (#52688). + [builds] Belated DLL support with vc2002-vc2008. -2017-12-18 Werner Lemberg + The solution and project files should be automatically upgraded for + the approriate Visual C++ version. - [truetype] Fix previous commit. + * builds/windows/visualc/freetype.{sln,vcproj}: Major upgrades. + * builds/windows/visualc/index.html: Document the change. + * builds/windows/vc2005, builds/windows/vc2008: Removed as redundant. - * src/truetype/ttgload.c (TT_Process_Simple_Glyph): Correctly handle - unhinted phantom points, which must be properly scaled. +2018-11-22 Armin Hasitzka -2017-12-18 Werner Lemberg + * src/cff/cffparse.c: Please the compiler. - [truetype] Don't apply HVAR and VVAR deltas twice (#52683). +2018-11-22 Armin Hasitzka - * src/truetype/ttgload.c (TT_Process_Simple_Glyph): Always adjust - `pp1' to `pp4', except if we have an HVAR and/or VVAR table. + [cff] Fix memory overflow. - * src/truetype/ttgxvar.c (TT_Vary_Apply_Glyph_Deltas): Handle - alternative code branch identically w.r.t. presence of an HVAR - and/or VVAR table. + Reported as -2017-12-17 Jonathan Kew + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9869 + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10869 - [truetype] Correctly handle variation font phantom points (#52683). + * src/cff/cffparse.c (destruct_t2s_item, cff_parser_run): Store + evaluated T2 charstrings in separately allocated memory. - * src/truetype/ttgxvar.c (TT_Vary_Apply_Glyph_Deltas): Fix phantom - point indices. +2018-11-18 Alexei Podtelezhnikov -2017-12-17 Jonathan Kew + * builds/windows/{visualc,vc2005,vc2008}/freetype.vcproj: Fix it. - Fix incorrect advance width scaling (#52683). +2018-11-10 Alexei Podtelezhnikov - * src/base/ftadvance.c (FT_Get_Advances): Always respect the - FT_LOAD_NO_SCALE flag if present. + [smooth] Placeholder only for library-enabled LCD filtering. -2017-12-16 Alexei Podtelezhnikov + * src/smooth/ftsmooth.c (ft_smooth_init): Add disabled + `FT_Library_SetLcdFilter' call. - * builds/windows/vc2010/freetype.vcxproj: AfterBuild copy. - * objs/.gitignore: Ignore almost everything. +2018-11-09 Young Xiao -2017-12-11 Werner Lemberg + [psaux] Add safety guard (#54985). - Fix compiler warning (#52640). + * src/psaux/psobjs.c (cff_builder_close_contour): Do it. - * src/base/ftbitmap.c (ft_bitmap_assure_buffer): Remove unused - variable. +2018-11-08 Alexei Podtelezhnikov -2017-12-08 Azzuro + * builds/unix/configure.raw: Require `windows.h' for windres. - * builds/windows/vc2010/freetype.vcxproj: Adjust output directory. +2018-11-08 Alexei Podtelezhnikov - This allows builds with different configurations in parallel. + [ftstroke] Fix unpredictable failures (#54986). -2017-12-08 Werner Lemberg + * src/base/ftstroke.c (ft_sroke_border_lineto): Fix lineto check. - Fix `make setup dos', second try (#52622). +2018-11-08 Alexei Podtelezhnikov - * builds/detect.mk (dos_setup): Don't use literal `>' character at - all. Mixing the different escaping rules from make, dos, and - windows is too fragile. + [ftstroke] Fix unpredictable failures (#54976). -2017-12-08 Werner Lemberg + * src/base/ftstroke.c (ft_sroke_border_close): Set the start tags. - [docmaker] Fix code section parsing. +2018-11-07 Ben Wagner - Stuff like + [truetype] Fix VF check from 2018-09-12 (#54973). - { - - } + * src/truetype/ttgxvar.c (TT_Vary_Apply_Glyph_Deltas): Use correct + offsets for estimates. - confused the parser, which incorrectly treated `' as a markup - tag. +2018-11-06 Werner Lemberg - * src/tools/docmaker/content.py (ContentProcessor::process_content): - Apply `re_markup_tags' only outside of code sections. + [pshinter] Fix numeric overflow. -2017-12-08 Werner Lemberg + Reported as - New `ftdriver.h' file, covering all driver modules. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11242 - This reduces redundancy and increases synergy; it also reduces the - number of header files. + * src/pshinter/pshrec.c (ps_dimension_add_t1stem): Implement it. - * include/freetype/config/ftheader.h (FT_DRIVER_H): New macro. - (FT_AUTOHINTER_H, FT_CFF_DRIVER_H, FT_TRUETYPE_DRIVER_H, - FT_PCF_DRIVER_H, FT_TYPE1_DRIVER_H): Make them aliases to - FT_DRIVER_H. +2018-11-06 Werner Lemberg - * include/freetype/ftautoh.h, include/freetype/ftcffdrv.h, - include/freetype/ftpcfdrv.h, include/freetype/ftt1drv.h, - include/freetype/ftttdrv.h: Replaced with... - * include/freetype/ftdriver.h: ...this new file. - (FT_CFF_HINTING_ADOBE, FT_T1_HINTING_ADOBE): Renamed to... - (FT_HINTING_ADOBE): ... this new macro. - (FT_CFF_HINTING_FREETYPE, FT_T1_HINTING_FREETYPE): Renamed to... - (FT_HINTING_FREETYPE): ... this new macro. + [psaux] Fix timeout in old CFF engine. - * src/*/*: Updated accordingly. + Reported as -2017-12-08 Werner Lemberg + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11260 - Move `ftdriver.h' to `ftdrv.h'. + * src/psaux/cffdecode.c (cff_decoder_parse_charstrings) + [CFF_CONFIG_OPTION_OLD_ENGINE]: Fix potential endless + loop. - * include/freetype/internal/ftdriver.h: Renamed to... - * include/freetype/internal/ftdrv.h: ... this name. +2018-11-04 Alexei Podtelezhnikov - * include/freetype/internal/internal.h (FT_INTERNAL_DRIVER_H): - Updated. + * src/truetype/ttgxvar.c: Use enum definitions. -2017-12-08 Werner Lemberg +2018-11-03 Alexei Podtelezhnikov - Fix access to uninitalized memory (#52613). + * src/truetype/ttgxvar.c (ft_var_apply_tuple): Adjust condition. - Also reported as +2018-11-03 Alexei Podtelezhnikov - https://bugs.chromium.org/p/chromium/issues/detail?id=791317 + * src/truetype/ttgxvar.c (ft_var_apply_tuple): Tracing tweaks. - * src/base/ftbitmap.c (ft_bitmap_assure_buffer): If increasing the - bitmap size needs a larger bitmap buffer, assure that the new memory - areas are initialized also. +2018-11-03 Alexei Podtelezhnikov -2017-12-08 Werner Lemberg + Revert due to specs: [truetype] Speed up variation IUP. - Fix `make setup dos' (#52622). +2018-11-02 Alexei Podtelezhnikov - * builds/detect.mk (dos_setup): Properly escape literal `>' - character. + * src/truetype/ttgxvar.c (ft_var_get_item_delta): Fixed logic. -2017-12-07 Werner Lemberg + Reported and tested by Behdad. - Fix C++ compilation. +2018-11-02 Shailesh Mistry - * src/psaux/psauxmod.h: Use FT_CALLBACK_TABLE macro where necessary. + [autofit] Prevent SEGV. - * src/smooth/ftsmooth.c (ft_smooth_render_generic): Fix warning. + See -2017-12-07 Werner Lemberg + https://bugs.ghostscript.com/show_bug.cgi?id=697545 - Fix `make multi'. + for more details on how the bug was found. - * include/freetype/internal/fttrace.h: Remove unused tracing macros. - s/pshalgo2/pshalgo/. - Add `trace_cffdecode'. - * src/pshinter/pshalgo.c (FT_COMPONENT): Updated. + * src/autofit/afloader.c (af_loader_load_glyph): Propagate error + code. - * src/cff/cffload.c: Include FT_INTERNAL_POSTSCRIPT_AUX_H. - * src/cff/cffobjs.c: Include FT_SERVICE_METRICS_VARIATIONS_H and - FT_SERVICE_CFF_TABLE_LOAD_H. +2018-10-31 Alexei Podtelezhnikov - * src/cid/cidriver.c: Include FT_INTERNAL_POSTSCRIPT_AUX_H. + [truetype] Speed up variation IUP. - * src/psaux/cffdecode.c: Include FT_FREETYPE_H and - FT_INTERNAL_DEBUG_H. - (FT_COMPONENT): Define. - * src/psaux/cffdecode.h: Include FT_INTERNAL_POSTSCRIPT_AUX_H. - * src/psaux/psauxmod.h: Include FT_INTERNAL_POSTSCRIPT_AUX_H. - Declare `cff_builder_funcs' and `ps_builder_funcs'. - * src/psaux/psft.c: Include `psobjs.h' and `cffdecode.h'. - * src/psaux/psobjs.c : Include `psauxmod.h'. + * src/truetype/ttgxvar.c (tt_delta_interpolate): Separate trivial + snapping to the same position from true interpolation. -2017-12-07 Werner Lemberg +2018-10-31 Alexei Podtelezhnikov - * include/freetype/config/ftheader.h: Some clean-up. + * src/type1/t1load.c (t1_set_mm_blend): Optimized. - This commit removes documentation of deprecated macros and does some - minor streamlining. +2018-10-31 Alexei Podtelezhnikov -2017-12-06 Werner Lemberg + * src/truetype/ttgxvar.c (ft_var_get_item_delta): Optimized. - * builds/symbian/bld.inf: Updated. +2018-10-29 Werner Lemberg -2017-12-06 Werner Lemberg + [base] Fix numeric overflow. - New header file `ftparams.h' that collects all parameter tags. + Reported as - * include/freetype/config/ftheader.h (FT_PARAMETER_TAGS_H): New - macro. - (FT_TRUETYPE_UNPATENTED_H, FT_UNPATENTED_HINTING_H): Define it to - `ftparams.h'. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11080 - * include/freetype/ftautoh.h, include/freetype/ftcffdrv.h, - include/freetype/ftincrem.h, include/freetype/ftlcdfil.h, - include/freetype/ftsnames.h, include/freetype/ftt1drv.h: Include - FT_PARAMETER_TAGS_H. - Move FT_PARAM_TAG_XXX definitions to... - * include/freetype/ftparams.h: ...this new file. + * src/base/ftoutln.c (FT_Outline_Get_Orientation): Use `MUL_LONG'. - * include/freetype/ttunpat.h: Remove. No longer needed. +2018-10-29 Werner Lemberg -2017-12-05 Werner Lemberg + [cff] Fix numeric overflow. - Improve tracing messages by using singular and plural forms. + Reported as - * src/*/*.c: Implement it. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10988 -2017-12-04 Werner Lemberg + * src/cff/cffparse.c (cff_parser_run) + [CFF_CONFIG_OPTION_OLD_ENGINE]: Use `NEG_LONG'. - [truetype] Allow shared points in `cvar' table (#52532). +2018-10-27 Alexei Podtelezhnikov - * src/truetype/ttgxvar.c (tt_face_vary_cvt): Implement it by copying - and adjusting the corresponding code from - `TT_Vary_Apply_Glyph_Deltas'. + [sfnt] Make `head' timestamps unsigned. -2017-11-28 Werner Lemberg + It's been more than 2^31 seconds since 1904. - [truetype] Improving tracing of composite glyphs. + * include/freetype/tttables.h (TT_Header): Change field types. + * src/sfnt/ttload.c (tt_face_load_generic_header): Updated. - * src/truetype/ttgload.c (TT_Load_Composite_Glyph) - [FT_DEBUG_LEVEL_TRACE]: Show composite glyph information. +2018-10-27 Alexei Podtelezhnikov -2017-11-27 Werner Lemberg + Revert: Align FreeType with standard C memory management. - [type1] Allow (again) `/Encoding' with >256 elements (#52464). +2018-10-27 Werner Lemberg - In version 2.6.1, this has been disallowed to better reject - malformed fonts; however, this restriction was too strong. This - time, we only take the first 256 elements into account, since - encoding arrays are always accessed with a 8bit integer, according - to the PostScript Language Reference. + [psaux] Fix numeric overflow. - * src/type1/t1load.c (parse_encoding): Implement it. + Triggered by -2017-11-27 Jan Alexander Steffens (heftig) + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11157 - Fix last commit (#52522). + * src/psaux/cffdecode.c (cff_decoder_parse_charstrings) + [CFF_CONFIG_OPTION_OLD_ENGINE]: Fix integer overflow. - * builds/freetype.mk: Set `FT_OPTION_H' and `FTOPTION_FLAG' - properly if we have `ftoption.h' in `BUILD_DIR'. +2018-10-20 Werner Lemberg -2017-11-24 Werner Lemberg + Avoid endless loop while tracing (#54858). - [unix] Install a massaged `ftoption.h' file (#51780). + * src/type1/t1load.c (parse_buildchar): Guard tracing stuff with + FT_DEBUG_LEVEL_TRACE. - * builds/unix/configure.raw (ftoption_set, ftoption_unset): New - auxiliary functions to construct... - (FTOPTION_H_SED): ... this new variable. - Apply it as a sed argument while copying `ftoption.h' to the - `builds/unix' directory (using `AC_CONFIG_FILES'). - Simplify code of test that checks cpp's computation of bit length - (the test previously created an empty `ftoption.h' file and deleted - it immediately afterwards); without this change, it can happen on my - GNU/Linux box that `configure's execution of `config.status' doesn't - create `ftoption.h' (no idea why this happens). +2018-10-17 David Demelier - * builds/unix/install.mk (install): Install - `builds/unix/ftoption.h'. + * CMakeLists.txt: Specify `RUNTIME DESTINATION'. - * builds/unix/unix-def.in (DISTCLEAN): Updated. + This is needed for DLL builds. - * builds/unix/.gitignore: Updated. +2018-10-07 Werner Lemberg -2017-11-23 Tor Andersson + A missing Unicode cmap is not a fatal error. - Silence unused function warnings (#52465). + This is a follow-up to the previous commit. - Some static function declarations cause unused function warnings if - certain config options are turned off via `ftoption.h'. + * src/cff/cffobjs.c (cff_face_init), src/sfnt/sfobjs.c + (sfnt_load_face), src/type1/t1objs.c (T1_Face_Init), + src/type42/t42objs.c (T42_Face_Init): Implement it. - * src/base/ftbase.h, src/base/ftrfork.c, src/sfnt/ttbdf.h, - src/truetype/ttgxvar.h: Add #ifdef guards around these sections. +2018-10-07 Werner Lemberg -2017-11-22 Ewald Hew + Fix handling of FT_CONFIG_OPTION_ADOBE_GLYPH_LIST (#54794). - * src/psaux/psft.c (cf2_setGlyphWidth): Check format before setting. + * src/cff/cffcmap.c (cff_cmap_unicode_init), src/psaux/t1cmap.c + (t1_cmap_unicode_init), src/sfnt/ttcmap.c (tt_cmap_unicode_init): + Check `unicodes_init' field. + +2018-10-03 Werner Lemberg + + [ftgrays] Fix typo in stand-alone mode (#54771). + + * src/smooth/ftgrays.c (FT_THROW) [STANDALONE_ && + FT_DEBUG_LEVEL_TRACE]: Fix call to `FT_ERR_CAT'. + +2018-10-02 Werner Lemberg + + [psaux] Fix segfault. Reported as - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=4377 + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10768 -2017-11-22 Ewald Hew + * src/psaux/cffdecode.c (cff_decoder_parse_charstrings) + [CFF_CONFIG_OPTION_OLD_ENGINE]: Check + argument. - [psaux] Fix CFF advance widths. (#52466) +2018-10-02 Werner Lemberg - Glyph advance widths were being written to the new `PS_Decoder' but not - saved to the underlying format specific decoder. This caused pure CFF - fonts to have bad advance width. + [psaux] Fix numeric overflow. - * include/freetype/internal/psaux.h (PS_Decoder): Change `glyph_width' - field to pointer. - Remove unused fields. - * src/psaux/psobjs.c (ps_decoder_init): Change `glyph_width' from copy - to reference. - Remove unused. - * src/psaux/psft.c (cf2_setGlyphWidth): Update code. + Reported as -2017-11-15 Vlad Tsyrklevich + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10740 - * include/freetype/ftrender.h: Fix `FT_Renderer_RenderFunc' type. + * src/psaux/cffdecode.c (cff_decoder_parse_charstrings) + [CFF_CONFIG_OPTION_OLD_ENGINE]: Use NEG_INT. -2017-11-14 Nikolaus Waxweiler +2018-10-02 Werner Lemberg - Use Adobe hinting engine for `light' hinting of both CFF and Type 1. + [pshinter] Handle numeric overflow. - Since Ewald Hew factored the Adobe hinting engine out of the CFF - driver code, we can now use it on Type 1 (and CID) font formats, as - both have the same hinting philosophy. + Reported as - This change activates the Adobe hinter when in LIGHT mode, and - therefore always unless explicitly asking for the auto-hinter. This - makes LIGHT behavior consistent with CFF fonts. As of this commit, - the hinting engine table looks as follows. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10550 - LIGHT NORMAL - ------------------------- - TrueType Auto v40 - CFF Adobe Adobe - Type 1 Adobe Adobe + * src/pshinter/pshglob.c (psh_blues_snap_stem): Mask numeric + overflow. -2017-11-10 Yuri Levchenko +2018-09-27 Alexei Podtelezhnikov - * CMakeLists.txt: Add `DISABLE_FORCE_DEBUG_PREFIX' option. + Align FreeType with standard C memory management. -2017-11-06 Alexei Podtelezhnikov + * include/freetype/ftsystem.h: Include FT_TYPES_H. + (*FT_Alloc_Func, *FT_Realloc_Func): Use size_t for the size arguments. + * src/raster/ftmisc.h: Ditto. - * src/base/ftobjs.c (FT_Load_Glyph): Relocate condition. + * builds/amiga/src/base/ftsystem.c, builds/unix/ftsystem.c, + * builds/vms/ftsystem.c, src/base/ftsystem.c (ft_alloc, ft_realloc): + Use size_t for the size arguments. -2017-11-06 Alexei Podtelezhnikov + * src/base/ftdbgmem.c (ft_mem_debug_alloc, ft_mem_debug_realloc): Use + FT_Offset, aka size_t, for the size arguments. - * src/smooth/ftgrays.c (gray_set_cell): Fix uninitialized variables. +2018-09-25 Werner Lemberg -2017-11-03 Ewald Hew + Fix handling of `FT_Bool'. - [psaux] Fix PostScript interpreter rewinding in Type 1 mode. (#52251) + Before this commit we had code like - The interpreter in Type 1 mode rewinds the charstring after collecting - all hints for building the initial hintmap (commit d52dd7f). However, - some charstrings use `endchar' in a final subroutine call, rewinding to - the start of that subroutine, and only a small section of the actual - glyph is drawn. + (FT_Bool)( globals->glyph_styles[gindex] & 0x8000) - * src/psaux/psintrp.c (cf2_interpT2CharString) : - Ensure we are on the top level charstring before rewinding. + Since `FT_Bool' is defined to be an `unsigned char', the code + evaluated to something like -2017-11-03 suzuki toshiya + (unsigned char)( 0x8532 & 0x8000) - [truetype] Add more tricky fonts. + which in turn expanded to - See the report by Yang Yinsen. - https://lists.gnu.org/archive/html/freetype-devel/2017-11/msg00000.html + (unsigned char)( 0x8000) - * src/truetype/ttobjs.c (trick_names): Add `DFGothic-EB', - `DFGyoSho-Lt', `DFHSGothic-W5', `DFHSMincho-W3' and `DFHSMincho-W7'. - (tt_check_trickyness_sfnt_ids): Add checksums for DFGothic-EB, - DFGyoSho-Lt, DFHSGothic-W5, DFHSMincho-W3 and DFHSMincho-W7. Also - add checksums for DLCLiShu and DLCHayBold which their family names - were already listed but their checksums were previously unknown. + and finally yielded 0x00 – i.e., false – not as expected. -2017-11-01 Alexei Podtelezhnikov + Problem reported and analyzed by Tony Smith . - [smooth] Fix complex rendering at high ppem. + * include/freetype/fttypes.h (FT_BOOL): Add a comparison against + zero so that we always have a Boolean expression. - We used to split large glyphs into horizontal bands and continue - bisecting them still horizontally if that was not enough. This is - guaranteed to fail when a single scanline cannot fit into the - rendering memory pool. Now we bisect the bands vertically so that - the smallest unit is a column of the band height, which is guranteed - to fit into memory. + */*: Replace castings to `FT_Bool' with calls to `FT_BOOL' where + possible. - * src/smooth/ftgrays.c (gray_convert_glyph): Implement it. +2018-09-23 Alexei Podtelezhnikov -2017-10-20 Alexei Podtelezhnikov + [bdf] Speed up charmap access. - [smooth] Improve complex rendering at high ppem. + This makes FT_Get_Char_Index and FT_Get_Next_Char 4-5 times faster. - At large sizes almost but not exactly horizontal segments can quickly - drain the rendering pool. This patch at least avoids filling the pool - with trivial cells. Beyond this, we can only increase the pool size. + * src/bdf/bdfdrivr.c (bdf_cmap_char_{index,next}): Help binary search + with continuous prediction. - Reported, analyzed, and tested by Colin Fahey. +2018-09-22 Alexei Podtelezhnikov - * src/smooth/ftgrays.c (gray_set_cell): Do not record trivial cells. + * src/base/ftobjs.c (ft_glyphslot_preset_bimap): Another tweak. -2017-10-20 Alexei Podtelezhnikov + This one should be clearer. When the rounded monochrome bbox collapses + we add a pixel that covers most if not all original cbox. - [base] Improve tracing in FT_Load_Glyph, FT_*_Size. +2018-09-21 Alexei Podtelezhnikov - * src/base/ftobjs.c (FT_Load_Glyph): Tag tracing messages with - function name, glyph index, and load flags. - (FT_Select_Metrics, FT_Request_Metrics): Remove all tracing. - (FT_Select_Size, FT_Request_Size): Improve tracing. + * src/base/ftobjs.c (ft_glyphslot_preset_bimap): Further tweak. -2017-10-18 Alexei Podtelezhnikov +2018-09-21 Ben Wagner - [base] Improve tracing in FT_Render_Glyph. + Improve auto-hinter handling of bitmap fonts (#54681). - * src/base/ftobjs.c (FT_Render_Glyph_Internal): Add total coverage - calculations and downgrade Netpbm dump to bitmap:7. + For bitmap fonts, `FT_Load_Glyph' should either return an error or + not set the format to `FT_GLYPH_FORMAT_OUTLINE'. However, in this + case `FT_Load_Glyph' calls into the auto-hinter which calls back + into `FT_Load_Glyph' with `FT_LOAD_NO_SCALE' in the flags, which + marks the glyph as `FT_GLYPH_FORMAT_OUTLINE' with an empty path + (even though it doesn't have any path). It appears that the + auto-hinter should not be called when the face doesn't have + outlines. The current test for using the auto-hinter in + `FT_Load_Glyph' checks whether the driver supports scalable + outlines, but not if the face supports scalable outlines. -2017-10-15 Ewald Hew + * src/base/ftobjs.c (FT_Load_Glyph): Directly check whether we have + scalable outlines. - [cff] Fix segfault on missing `psaux' (#52218) +2018-09-21 Werner Lemberg - * src/cff/cffload.c (cff_done_blend): Add a check for possible nullptr. + [raster] Fix disappearing vertical lines (#54589). - * modules.cfg: Update dependency list. + * src/raster/ftraster.c (Vertical_Sweep_Span): Handle special case + where both left and right outline exactly pass pixel centers. -2017-10-15 Alexei Podtelezhnikov +2018-09-20 Alexei Podtelezhnikov - [base, cff] Fix MSVC warnings. + * src/base/ftobjs.c (ft_glyphslot_preset_bimap): Tiny rounding tweak. - * src/base/ftobjs.c (FT_New_Library): C4702: unreachable code. - (ft_glyphslot_preset_bitmap): C4244: possible loss of data. - * src/cff/cffload.c (cff_blend_doBlend): C4244: possible loss of data. - Turn `sum' into unsigned. + This adds pixels in case a contour goes through the center + and they need to be turned on in the b/w rasterizer. -2017-10-14 Alexei Podtelezhnikov +2018-09-20 Alexei Podtelezhnikov - [base] Netpbm image tracing. + [pcf] Replace charmap implementation. - * src/base/ftobjs.c (FT_Load_Glyph): Trace bitmap size. - (FT_Render_Glyph_Internal): Trace bitmap in Netpbm format. + PCF comes with charmap lookup table, aka PCF encodings. Using it + directly makes FT_Get_Char_Index and FT_Get_Next_Char 4-5 times + faster than the original BDF-like binary searches. - * src/smooth/ftgrays.c (gray_sweep): Sweep remnants of span tracing. + * src/pcf/pcf.h (PCF_EncodingRec): Removed. + (PCF_FaceRec): Remove `nencodings' and `encodings'. + * src/pcf/pcfdrivr.c (pcf_cmap_char_{index,next}): Replaced. + * src/pcf/pcfread.c (pcf_get_encodings): Store data differently. -2017-10-14 Alexei Podtelezhnikov +2018-09-20 Werner Lemberg - * builds/windows/ftdebug.c (FT_Message): Print to stderr. - * builds/wince/ftdebug.c (FT_Message): Ditto. + [base] Remove unused function `FT_GlyphLoader_CopyPoints'. -2017-10-14 Behdad Esfahbod + * include/freetype/internal/ftgloadr.h, src/base/ftgloadr.c + (FT_GlyphLoader_CopyPoints): Do it. - [afshaper] Delay creating `hb_set' objects until needed. +2018-09-19 Alexei Podtelezhnikov - In runs on Noto Naskh Arabic, this results in 89 sets created - instead of 340 before. Makes auto-hinter setup with HarfBuzz - enabled 20% to 30% faster. + [pcf] Prepare to replace charmap implementation. - * src/autofit/afshaper.c (af_shaper_get_coverage): Implement it. + * src/pcf/pcf.h (PCF_FaceRec): Updated to include... + (PCF_EncRec): ... this new structure to store charmap geometry. -2017-10-12 Ewald Hew + * src/pcf/pcfread.c (pcf_get_encodings): Store charmap geometry. - [type1, cid] Add hinting engine switch. +2018-09-18 Alexei Podtelezhnikov - Implement property service in `type1' and `cid' drivers to allow - switching between FreeType or Adobe hinting engine when both are - available. + Remove unused fields. - * src/cid/cidriver.c (cid_property_{set,get}, cid_services), - src/type1/t1driver.c (t1_property_{set,get}, t1_services): Add - Properties service. + * src/pcf.h (PCF_FaceRec): Remove `charmap' and `charmap_handle'. + * src/bdfdrvr.h (BDF_FaceRec): Ditto. + * src/winfonts/winfnt.h (FNT_FaceRec): Ditto. - * src/cid/cidobjs.c (cid_driver_init), src/type1/t1objs.c - (T1_Driver_Init): Add default property values. +2018-09-17 Werner Lemberg -2017-10-12 Ewald Hew + [pshinter] Handle numeric overflow. - Add T1_CONFIG_OPTION_OLD_ENGINE configuration option. + Reported as - This controls whether the old Type 1 engine gets compiled into FreeType. - It is disabled by default. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10396 - * devel/ftoption.h, include/freetype/config/ftoption.h - (T1_CONFIG_OPTION_OLD_ENGINE): New macro. + * src/pshinter/pshglob.c: Include FT_INTERNAL_CALC_H. + (psh_blues_snap_stem): Mask numeric overflow. - * include/freetype/internal/psaux.h (PS_Decoder): Remove unused field. - * include/freetype/internal/psaux.h, src/cid/cidgload.c - (cid_load_glyph), src/psaux/psauxmod.c, src/psaux/psobjs.c - (ps_builder_add_point), src/psaux/t1decode.c - (t1_lookup_glyph_by_stdcharcode, t1_decoder_parse_glyph, - t1operator_seac, t1_decoder_parse_charstrings), src/psaux/t1decode.h, - src/type1/t1gload.c (T1_Parse_Glyph_And_Get_Char_String): Surround - relevant code with macro. - Minor code changes. +2018-09-13 Werner Lemberg -2017-10-12 Ewald Hew + [truetype] Some fixes for VF checks. - Extract width parsing from Type 1 parser. + Reported as - Duplicate the fast advance width calculations from the old parser. - This is to facilitate adding options for compiling out the old parser. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10317 - * src/psaux/t1decode.{c,h} (t1_decoder_parse_metrics): New function. - * include/freetype/internal/psaux.h (T1_Decoder_Funcs): New entry - `parse_metrics'. - * src/psaux/psauxmod.c: Set the new entry. + * src/truetype/ttgxvar.c (ft_var_load_gvar): Properly exit memory + frame if we have invalid glyph variation data offsets. + (tt_face_vary_cvt): Protect against missing `tuplecoords' array. + Fix typo. - * src/type1/t1gload.c (T1_Parse_Glyph_And_Get_Char_String), - src/cid/cidgload.c (cid_load_glyph): Separate - conditional for selecting engine. +2018-09-13 Werner Lemberg -2017-10-09 Werner Lemberg + * src/sfnt/sfdriver.c (sfnt_get_var_ps_name): Fix last commit. - * src/base/ftoutln.c (FT_Outline_Translate): Fix integer overflow. +2018-09-13 Werner Lemberg + + * src/sfnt/sfdriver.c (sfnt_get_var_ps_name): Check `result'. Reported as - https://bugs.chromium.org/p/chromium/issues/detail?id=772775 + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10316 -2017-10-08 Werner Lemberg +2018-09-12 John Tytgat - * src/base/ftobjs.c (ft_glyphslot_preset_bitmap): Integer overflows. + [sfnt] Better PS name handling (#54629). - Reported as + * src/sfnt/sfdriver (IS_WIN, IS_APPLE): Omit language ID checks. + (get_win_string, get_apple_string): Return NULL when the PostScript + font name characters is not according to specification. + (get_win_string): Make trace output work if the high byte if + non-zero. + (sfnt_get_var_ps_name, sfnt_get_ps_name): Previously we preferred + Win PS name (when there is also an Apple PS name); change this into + a fallback to Apple PS name in case the Win PS name is invalid. - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3579 +2018-09-12 Werner Lemberg -2017-10-07 Werner Lemberg + [truetype] Improve VF check. - [sfnt] Adjust behaviour of PS font names for variation fonts. + Triggered by - * src/sfnt/sfdriver.c (sfnt_get_var_ps_name): Use a named instance's - PS name only if no variation is applied. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10255 -2017-10-07 Werner Lemberg + * src/truetype/ttgxvar.c (ft_var_load_gvar): Use better limit check + for `tupleCount'. - [cff, truetype] Adjust behaviour of named instances. +2018-09-12 Werner Lemberg - This commit completely separates the interaction between named - instances and variation functions. In particular, resetting the - variation returns to the current named instance (if set) and not to - the base font. + * src/truetype/ttgxvar.c (ft_var_load_gvar): Check `glyphoffsets'. - As a side effect, variation functions no longer change the named - instance index. +2018-09-10 Armin Hasitzka - * src/cff/cffobjs.c (cff_face_init): Use MM service's `set_instance' - function. - Also apply `MVAR' table to named instances. + * src/pshinter/pshrec.c (t2_hints_stems): Mask numeric overflow. - * src/truetype/ttgxvar.c (TT_Get_MM_Var): Add cast. - (tt_set_mm_blend): No longer check whether requested variation - coincides with a named instance. - (TT_Set_Var_Design): Use current named instance for default - coordinates. - * src/truetype/ttobjs.c (tt_face_init): Use `TT_Set_Named_Instance'. + Reported as -2017-10-07 Werner Lemberg + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10215 - Make `FT_Set_Named_Instance' work. +2018-09-09 Ben Wagner - * src/cff/cffdrivr.c (cff_set_instance): New function. - (cff_service_multi_masters): Register it. + * builds/freetype.mk (refdoc-venv): Ensure python version (#54631). - * src/truetype/ttgxvar.c (TT_Set_Named_Instance): New function. - * src/truetype/ttgxvar.h: Updated. - * src/truetype/ttdriver.c (tt_service_gx_multi_masters): Register - it. +2018-09-07 Werner Lemberg - * src/type1/t1load.c (T1_Reset_MM_Blend): New function. - * src/type1/t1load.h: Updated. - * src/type1/t1driver.c (t1_service_multi_masters): Register it. + [truetype] Fix assertion failure. -2017-10-07 Werner Lemberg + Triggered by - Make `FT_FACE_FLAG_VARIATION' work. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10212 - * include/freetype/internal/tttypes.h (TT_Face): Remove - `is_default_instance'; this can be replaced with a combination of - `FT_IS_VARIATION' and `FT_IS_INSTANCE'. + * src/truetype/ttgload.c (load_truetype_glyph): Reintroduce + `opened_frame' (removed in a change from 2018-08-26) to handle + deallocation of the second frame. - * src/cff/cffdrivr.c (cff_get_advances): Updated. +2018-09-05 Werner Lemberg - * src/sfnt/sfdriver.c (sfnt_get_ps_name), src/sfnt/sfobjs.c - (sfnt_init_face): Updated. + Synchronize `ftdebug.c' files. - * src/truetype/ttdriver.c (tt_get_advances), src/truetype/ttgload.c - (TT_Process_Simple_Glyph, load_truetype_glyph, IS_DEFAULT_INSTANCE), - src/truetype/ttgxvar.c (tt_set_mm_blend): Updated. - * src/truetype/ttgxvar.c (TT_Set_MM_Blend, TT_Set_Var_Design): - Handle `FT_FACE_FLAG_VARIATION'. + * builds/amiga/src/base/ftdebug.c, builds/wince/ftdebug.c, + builds/windows/ftdebug.c: Synchronize with `src/base/ftdebug.c'. - * src/type1/t1load.c (T1_Set_MM_Blend, T1_Set_MM_Design): Handle - `FT_FACE_FLAG_VARIATION'. +2018-09-05 Nikhil Ramakrishnan -2017-10-07 Werner Lemberg + Add documentation guidelines file. - New function `FT_Set_Named_Instance'. + * docs/DOCGUIDE: New file. - No effect yet. +2018-09-04 Werner Lemberg - * src/base/ftmm.c (FT_Set_Named_Instance): New function. + * devel/ftoption.h: Synchronize with master `ftoption.h'. - * include/freetype/ftmm.h: Updated. +2018-09-03 Nikhil Ramakrishnan -2017-10-07 Werner Lemberg + [docwriter] Don't break code snippets accross lines. - Add macros for checking whether a font variation is active. + Reported as - * include/freetype/freetype.h (FT_FACE_FLAG_VARIATION, - FT_IS_VARIATION): New macros. - No effect yet. + https://lists.nongnu.org/archive/html/freetype-devel/2018-08/msg00124.html -2017-10-07 Werner Lemberg + * docs/reference/markdown/stylesheets/extra.css (.md-typeset code): + Add rule `white-space'. - Add framework for setting named instance in MM service. +2018-09-03 Werner Lemberg - * include/freetype/internal/services/svmm.h (FT_Set_Instance_Func): - New function typedef. - (MultiMasters): Add `set_instance' member. - (FT_DEFINE_SERVICE_MULTIMASTERSREC): Updated. + */*: s/PSNames/psnames/. - * src/cff/cffdrivr.c (cff_service_multi_masters), - src/truetype/ttdriver (tt_service_gx_multi_masters), - src/type1/t1driver.c (t1_service_multi_masters): Updated. + Only tracing messages are affected. -2017-10-07 Werner Lemberg +2018-09-03 Werner Lemberg - [type1] Minor code shuffling. + [sfnt] Fix heap buffer overflow in CPAL handling. - * src/type1/t1load.c (T1_Set_MM_Blend): Make it a wrapper of... - (t1_set_mm_blend): ...this new function. - (T1_Set_MM_Design): Use `t1_set_mm_blend'. + * src/sfnt/ttcpal.c (tt_face_palette_set): Fix boundary test. + (tt_face_load_cpal): Updated. -2017-10-05 Werner Lemberg +2018-09-01 Werner Lemberg - * src/base/ftobjs.c (ft_glyphslot_preset_bitmap): Fix integer - overflow. + Remove `FT_Outline_{New,Done}_Internal'. - Reported as + These public API functions(!) were always undocumented and have + escaped all clean-up efforts until now. - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3539 + * include/freetype/ftoutln.h (FT_Outline_New_Internal, + FT_Outline_Done_Internal): Removed. -2017-10-05 Werner Lemberg + * src/base/ftoutln.h (FT_Outline_New_Internal, + FT_Outline_Done_Internal): Merge into... + (FT_Outline_New, FT_Outline_Done): ... these functions. - Fix compiler warnings. + * docs/README: Updated. - * src/cff/cffdrivr.c (cff_ps_get_font_extra): Avoid code that relies - on numeric overflow. - Add cast. +2018-08-30 Alexei Podtelezhnikov - * src/smooth/ftsmooth.c (ft_smooth_render_generic): Fix variable - types, add cast. + * src/base/ftobjs.c (ft_glyphslot_preset_bitmap): Check glyph format. -2017-10-04 John Tytgat +2018-08-31 Armin Hasitzka - [cff] Add support for `FSType'. + [errors] Refine the macro logic surrounding `FT_Error_String'. - * include/freetype/internal/cfftypes.h (CFF_FontRec): Add - `font_extra' entry. + * include/freetype/fterrors.h (FT_INCLUDE_ERR_PROTOS, + FT_ERR_PROTOS_DEFINED): Undefine `FT_INCLUDE_ERR_PROTOS' after + checking it and introduce a new macro that takes proper care of + multiple-inclusion protection. - * src/cff/cffdrivr.c (cff_ps_get_font_extra): New function to - retrieve FSType info from the embedded PostScript data. - (cff_service_ps_info): Register function. +2018-08-31 Werner Lemberg - * src/cff/cffload.c (cff_font_done): Free `font_extra'. + * src/base/ftdebug.c (FT_Throw): Restore missing `FT_UNUSED' calls. -2017-09-30 Alexei Podtelezhnikov +2018-08-31 Werner Lemberg - Signedness fixes in bitmap presetting. + * src/base/ftdebug.c (FT_Throw): Reduce chattiness. - Reported as +2018-08-31 Werner Lemberg - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3514. + * src/autofit/afhints.c (af_glyph_hints_reload): Add initialization. + +2018-08-30 Alexei Podtelezhnikov + + Consolidate bitmap presetting and size assessment. - * src/raster/ftrend1.c (ft_raster1_render): Exlicitly signed height. + * include/freetype/internal/ftobjs.h (ft_glyphslot_preset_bitmap): + Change return type. + * src/base/ftobjs.c (ft_glyphslot_preset_bitmap): Return the bitmap + size assessment. + + * src/raster/ftrend1.c (ft_raster1_render): Use it to refuse the + rendering of enourmous or far-fetched outlines. * src/smooth/ftsmooth.c (ft_smooth_render_generic): Ditto. - * src/base/ftobjs.c (ft_glyphslot_preset_bitmap): Explicitly unsigned - subtraction. -2017-09-29 Alexei Podtelezhnikov +2018-08-30 Alexei Podtelezhnikov - Bitmap metrics presetting [2/2]. + * src/base/ftobjs.c (ft_glyphslot_preset_bitmap): Correct mono. - * src/base/ftobjs.c (FT_Load_Glyph): Preset the bitmap metrics when - appropriate but `FT_Render_Glyph' is not called. - * include/freetype/freetype.h (FT_GlyphSlotRec): Document the change. +2018-08-30 Armin Hasitzka -2017-09-28 Alexei Podtelezhnikov + [errors] Introduce a macro to control `FT_Error_String'. - [smooth, raster] Miscellaneous cleanups. + * devel/ftoption.h (FT_CONFIG_OPTION_ERROR_STRINGS), + include/freetype/config/ftoption.h (FT_CONFIG_OPTION_ERROR_STRINGS): + New macro. - * src/raster/ftrend1.c (ft_raster1_render): Clean up the exit. - * src/smooth/ftsmooth.c (ft_smooth_render_generic): Reduce - translations and clean up the exit. - (ft_smooth_render_lcd, ft_smooth_render_lcd): Remove unused `error'. +2018-08-30 Armin Hasitzka -2017-09-28 Ben Wagner + [errors] Introduce `FT_Error_String'. - [truetype] Really, really fix #52082. + * include/freetype/fterrors.h (FT_Error_String), + src/base/fterrors.c (FT_Error_String): Implement `FT_Error_String'. - * src/truetype/ttinterp.c (Ins_MDRP): Correct conditional. + * src/base/ftbase.c, src/base/Jamfile (_source), + src/base/rules.mk (BASE_SRC): Add `fterrors.c' to the build logic. -2017-09-28 Werner Lemberg + * src/base/ftdebug.c (FT_Throw): Use `FT_Error_String'. - * src/psaux/psintrp.c (cf2_doStems): Fix integer overflow. +2018-08-30 Werner Lemberg - Reported as + [autofit] Trace `before' and `after' edges of strong points. - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3510 + * src/autofit/afhints.h (AF_PointRec) [FT_DEBUG_AUTOFIT]: New arrays + `before' and `after'. -2017-09-28 Ewald Hew + * src/autofit/afhints.c (af_get_strong_edge_index): New auxiliary + function. + (af_glyph_hints_dump_points): Trace `before' and `after' edges. + (af_glyph_hints_align_strong_points) [FT_DEBUG_AUTOFIT]: Set + `before' and `after' information. - * src/cid/cidgload.c (cid_slot_load_glyph): Fix memory leak. +2018-08-30 Alexei Podtelezhnikov + + [base] Overflow-resistant bitmap presetting. + + * src/base/ftobjs.c (ft_glyphslot_preset_bitmap): Implement it. + +2018-08-29 Armin Hasitzka + + Fix numeric overflows. + + * src/pshint/pshalgo.c (psh_hint_align, psh_hint_align_light, + psh_hint_table_find_strong_points): Fix numeric overflows. Reported as - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3489 + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10083 -2017-09-28 Alexei Podtelezhnikov +2018-08-29 Werner Lemberg - Bitmap metrics presetting [1/2]. + [cff] Fix handling of `roll' op in old engine. - This mainly just extracts the code for presetting the bitmap metrics - from the monochrome, grayscale, and LCD renderers into a separate - function. + Reported as - * src/base/ftobjs.c (ft_glyphslot_preset_bitmap): New function that - calculates prospective bitmap metrics for the given rendering mode. - * include/freetype/internal/ftobjs.h (ft_glyphslot_preset_bitmap): - Declare it. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10080 - * src/base/ftlcdfil.c (ft_lcd_padding): New helper function that adds - padding to CBox taking into account pecularities of LCD rendering. - * include/freetype/ftlcdfil.h (ft_lcd_padding): Declare it. + * src/psaux/cffdecode.c (cff_decoder_parse_charstrings) + [CFF_CONFIG_OPTION_OLD_ENGINE]: Use modulo for loop count, as + documented in the specification. - * src/raster/ftrend1.c (ft_raster1_render): Reworked to use - `ft_glyphslot_preset_bitmap'. - * src/smooth/ftsmooth.c (ft_smooth_render_generic): Ditto. - (ft_smooth_render_lcd, ft_smooth_render_lcd): The pixel_mode setting - is moved to `ft_glyphslot_preset_bitmap'. +2018-08-26 Werner Lemberg -2017-09-28 Ewald Hew + * src/truetype/ttobjs.c (tt_size_read_bytecode): Trace CVT values. - [psaux] Fix compiler warning. +2018-08-26 Nikhil Ramakrishnan - * src/psaux/pshints.c (cf2_hintmap_dump): Add switch for tracing - code. + * configure: Copy assets required by docwriter. -2017-09-27 Werner Lemberg + Copy directory `docs/reference/markdown' when FreeType is compiled in a + different directory. - * src/sfnt/ttload.c (tt_face_load_font_dir): Fix compiler warning. + Fixes `make refdoc' if builddir != srcdir. -2017-09-25 Werner Lemberg + Reported as - [psaux] Fix compiler warnings. + https://lists.nongnu.org/archive/html/freetype-devel/2018-08/msg00083.html - * src/psaux/psft.c (cf2_initLocalRegionBuffer): Remove redundant - test. +2018-08-26 Werner Lemberg - * src/psaux/psintrp.c (cf2_interpT2CharString) - : Add casts. + * src/pshint/pshalgo.c (psh_hint_overlap): Fix numeric overflow. - * src/psaux/psobjs.c (ps_decoder_init): Add cast. + Reported as -2017-09-25 Ewald Hew + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10057 - [psaux] Minor fixes. +2018-08-26 Werner Lemberg - * include/freetype/internal/psaux.h, src/psaux/psobjs.{c,h}: - Rearrange `ps_builder_init' arguments to conventional order. + Minor tracing adjustments. - * src/psaux/psft.c (cf2_decoder_parse_charstrings): Add a check and - notice for `SubFont' in Type 1 mode. + * src/base/ftstream.c (FT_Stream_EnterFrame, FT_Stream_ExitFrame): + Trace. -2017-09-25 Ewald Hew + * src/truetype/ttgload.c (TT_Access_Glyph_Frame): Remove tracing. - [psaux] Move `psdecode' into `psobjs'. +2018-08-26 Werner Lemberg - As the former only contains a single procedure, move it into - `psobjs' for simplicity. Also change the parameter order to the - conventional one. + [truetype] Avoid nested frames. - * src/psaux/psdecode.c (ps_decoder_init): Moved to... - * src/psaux/psobjs.c: ...Here. - * src/psaux/psdecode.h, src/psaux/psobjs.h: Ditto. + Triggered by - * include/freetype/internal/psaux.h (PSAux_ServiceRec): Update - `ps_decoder_init' function signature. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10054 - * src/cff/cffgload.c, src/cid/cidgload.c, src/type1/t1gload.c: - Update calls. + * src/truetype/ttgload.c (load_truetype_glyph): Don't use variable + `opened_frame' to trace whether a frame must be closed at the end of + function: This fails because `TT_Vary_Apply_Glyph_Deltas' (which + gets called for space glyphs) uses a frame by itself. Instead, + close the frame after loading the header, then use another frame for + the remaining part of the glyph later on. - * src/psaux/psaux.c, src/psaux/psauxmod.c: Update includes. + Also avoid calling `tt_get_metrics' twice under some circumstances. - * src/psaux/Jamfile (_sources), src/psaux/rules.mk (PSAUX_DRV_SRC): - Update file references. +2018-08-26 Werner Lemberg -2017-09-25 Ewald Hew + Various minor clean-ups. - [psaux] Fix Type 1 hinting. + * src/base/ftapi.c: Remove. Unused. + * src/base/Jamfile (_sources): Updated. - Type 1 hinting breaks sometimes when mid-charstring hints should - have been in the initial hintmap. This fix adds a preprocessing - pass that reads all hints and builds the correct initial hintmap - first, before proceeding to build the glyph outline. + * src/base/ftstream.c (FT_Stream_ReleaseFrame): Remove redundant + code. - * src/psaux/psintrp.c (cf2_interpT2CharString): New - `initial_map_ready' boolean flag. - Ignore outline commands and hint changes on first pass. - : Add section to build hintmap and rewind. +2018-08-25 Nikhil Ramakrishnan -2017-09-25 Ewald Hew + Convert documentation markup to Markdown. - [psaux] Add tracing for hints. + It is the result of a GSoC 2018 project; this separate ChangeLog + commit covers the last four commits - * src/psaux/pshints.c (cf2_hintmap_dump): New function. - (cf2_hintmap_insertHint): Trace incoming and inserted hints. - (cf2_hintmap_build): Dump hintmap before and after hint adjustment. + ae5d1a4cec37557f31aec270332cfe886a62f9a0 + 53c69ce04faed3dcc68ca0f54cb8d703d8babf69 + 195728d5ba38f34fb2c2c20807c01656f2f59b66 + c962db28ea59225f0105c03d907d4a9b71765687 -2017-09-25 Ewald Hew + * docs/reference/markdown/images/favico.ico, + docs/reference/markdown/javascripts/extra.js, + docs/reference/markdown/stylesheets/extra.css: New files. - [psaux] Minor fixes. + * docs/reference/.gitignore, docs/reference/README: Updated. - * src/psaux/psintrp.c (cf2_interpT2CharString): Fix check for pop - results. - s/font->decoder/decoder/ where necessary. - : Use - offset parameter in `cf2_doStems' instead of doing correction for - left-sidebearing. + * src/tools/docmaker/*: Removed. It has been replaced with + `docwriter', a python package available at -2017-09-25 Ewald Hew + https://pypi.org/project/docwriter/ - [cid] Use the new engine. + * Jamfile: Updated. + * builds/ansi/ansi-def.mk, builds/beos/beos-def.mk, + builds/dos/dos-def.mk, builds/os2/os2-def.mk (BIN), + builds/unix/unixddef.mk, builds/windows/win32-def.mk: New variable. - * src/cid/cidgload.c: Update includes. - (cid_load_glyph, cid_slot_load_glyph): Implement changes to glyph - loading code as with `type1' module. + * builds/unix/configure.raw: Check for `python' and `pip'. + If not present, warn that `make refdoc' will fail. + * builds/unix/unix-def.in (PYTHON, PIP, BIN): New variables. -2017-09-25 Ewald Hew + * builds/freetype.mk (PYTHON, PIP, VENV_NAME, VENV_DIR, ENV_PYTHON, + ENV_PIP): New variables. + (refdoc): Updated. + (refdoc-venv): New target. + (.PHONY): Updated. - [cid] Add Adobe engine configuration. +2018-08-23 Werner Lemberg - This is similar to what was done in the `type1' module. + Add macros for handling over-/underflowing `FT_Int64' values. - * src/cid/cidriver.c (t1cid_driver_class): Update declaration. - * src/cid/cidobjs.c: Include FT_TYPE1_DRIVER_H. - (cid_driver_init): Update code. + * include/freetype/internal/ftcalc.h (ADD_INT64, SUB_INT64, + MUL_INT64, DIV_INT64) [FT_LONG64]: New macros. -2017-09-25 Ewald Hew + * src/base/ftcalc.c (ft_corner_orientation) [FT_LONG64]: Use + `SUB_INT64' and `MUL_INT64'. - [psaux] Change subfont synthesis for CID fonts. + Reported as - Change `t1_make_subfont' to take in the Private dict record as an - argument. This is because Type 1 and CID font records in FreeType - have this in different places. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10028 - * src/psaux/psobjs.c (t1_make_subfont): Change `T1_Face' to - `FT_Face' so that CID is also accepted. - Take `PS_Private' as an argument and let caller figure out where the - Private dict actually is. - Update references. +2018-08-22 Werner Lemberg - * include/freetype/internal/psaux.h, src/psaux/psobjs.h: Update - declaration. + [truetype] Improve legibility of `glyf' parsing. - * src/type1/t1gload.c (T1_Parse_Glyph_And_Get_Char_String): Update - call. + * src/truetype/ttgload.c (ON_CURVE_POINT, X_SHORT_VECTOR, + Y_SHORT_VECTOR, REPEAT_FLAG, X_POSITIVE, SAME_X, Y_POSITIVE, SAME_Y, + OVERLAP_SIMPLE): New macros. + (TT_Load_Simple_Glyph): Use new macros to make code more readable. + Remove useless adjustment of `outline->tags' elements. -2017-09-25 Ewald Hew +2018-08-21 Werner Lemberg - [type1] Switch to Adobe engine. + * src/sfnt/ttcpal.c (tt_face_load_cpal): Add missing safety check. - * src/type1/t1objs.c (T1_Driver_Init): Set default to Adobe engine. + Reported as -2017-09-25 Ewald Hew + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9981 - [psaux] Extend Adobe interpreter (seac). +2018-08-18 Werner Lemberg - This concludes the changes needed to add Type 1 support. + [psaux] Avoid slow PS font parsing in case of error. - * src/psaux/psintrp.c: Update includes. - (cf2_interpT2CharString) : Implement this similarly to - implied seac for CFF. + Reported as - * src/psaux/t1decode.c (t1_lookup_glyph_by_stdcharcode_ps): New - function to look up the glyph index. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9955 - * src/psaux/psft.c (cf2_getT1SeacComponent, - cf2_freeT1SeacComponent): New functions to get the charstrings for - seac components. + * src/psaux/psobjs.c (ps_parser_to_bytes): Set `parser->cursor' even + in case of error to avoid potential re-scanning. - * src/psaux/t1decode.h, src/psaux/psft.h: Update declarations. +2018-08-18 Werner Lemberg -2017-09-25 Ewald Hew + [cff] Fix heap buffer overflow in old engine. - [psaux] Extend Adobe interpreter (flex in callothersubr). + Reported as - * src/psaux/psintrp.c (cf2_interpT2CharString) - : Fix Flex feature handling (OtherSubrs 0, 1, - 2). - : Do not actually move the `glyphPath' while doing - flex. This is to avoid closing the current contour. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9967 -2017-09-25 Ewald Hew + * src/psaux/cffdecode.c (cff_decoder_parse_charstrings) + [CFF_CONFIG_OPTION_OLD_ENGINE]: `num_designs' must be + non-zero. - [psaux] Extend Adobe interpreter (callothersubr). +2018-08-16 Young Xiao - * src/psaux/psintrp.c (cf2_interpT2CharString) - : Copy code from - `t1_decoder_parse_charstrings' (in `t1decode.c'). - OtherSubr 3 (change hints) should reset the hintmask, so that the - new hints are applied. - Fix function calls and stack access. + * builds/mac/ftmac.c (parse_fond): Fix buffer overrun. -2017-09-25 Ewald Hew + Reported as bug #54515, duplicate of #43540. - [psaux] Extend Adobe interpreter (pop). +2018-08-16 Werner Lemberg - * src/psaux/psintrp.c (cf2_interpT2CharString): Change how unhandled - OtherSubr results are stored. Implement the PostScript stack using - an array. - : Ensure that the stack is not cleared after getting - `OtherSubr' results. - Fix stack access. + * builds/*/ftsystem.c (FT_COMPONENT): Updated also. -2017-09-25 Ewald Hew +2018-08-15 Alexei Podtelezhnikov - [psaux] Extend Adobe interpreter (callsubr). + [bdf] Don't track duplicate encodings. - * src/psaux/psintrp.c (cf2_interpT2CharString) : - Type 1 mode. + There is no harm except some umbiguity in broken fonts with duplicate + encodings. - * src/psaux/psft.c (cf2_initLocalRegionBuffer): Add Type 1 mode. + * src/bdf/bdflib.c (_bdf_parse_glyphs): Remove duplicate tracking. + (_bdf_parse_t): Remove large `have' bitfield. -2017-09-25 Ewald Hew +2018-08-15 Werner Lemberg - [psaux] Extend Adobe interpreter (div, four-byte numbers). + Don't use `trace_' prefix for FT_COMPONENT arguments. - * src/psaux/psintrp.c (cf2_interpT2CharString) : Add - Type 1 mode. Type 1 requires large integers to be followed by - `div'; cf. `Adobe Type 1 Font Format', section 6.2. - : Push Type 1 four-byte numbers as `Int' always. This is - to ensure `div' and `callsubr' get values they can use. + * include/freetype/internal/ftdebug.h (FT_TRACE_COMP, + FT_TRACE_COMP_): New auxiliary macros to add `trace_' prefix. + (FT_TRACE): Use `FT_TRACE_COMP'. -2017-09-25 Ewald Hew + */* (FT_COMPONENT): Updated. - [psaux] Extend Adobe interpreter (hints). +2018-08-14 Werner Lemberg - * src/psaux/psintrp.c (cf2_interpT2CharString) : Add correction for left sidebearing in Type 1 mode. - Allow adding hints mid-charstring. - : Translate into equivalent commands - for three normal stem hints. This requires some recalculation of - stem positions. - Correction for left sidebearing. + Use formatting string in FT_TRACEX calls for non-simple arguments. -2017-09-25 Ewald Hew + * src/psaux/cffdecode.c (cff_decoder_parse_charstrings) + : + Do it. - [psaux] Extend Adobe interpreter (hsbw, sbw). + * src/psaux/pshints.c (cf2_hintmap_build): Ditto. - * src/psaux/psintrp.c (cf2_doStems): `hsbw' or `sbw' must be the - first operation in a Type 1 charstring. - (cf2_interpT2CharString): Remove unused variables. - : `hsbw' or `sbw' - must be the first operation in a Type 1 charstring. - : Fix data access and add correction for - left sidebearing. + * src/psaux/psintrp.c (cf2_interpT2CharString) : Ditto. -2017-09-25 Ewald Hew + * src/truetype/ttinterp.c (TT_RunIns): Ditto. - [psaux] Extend Adobe interpreter (setcurrentpoint). +2018-08-14 Alexei Podtelezhnikov - * src/psaux/psintrp.c (cf2_interpT2CharString) - : Fix stack access. + [bdf] Remove unused fields. -2017-09-25 Ewald Hew + * src/bdf/bdf.h (bdf_font_t): Remove `nmod', `umod', and `modified', + which were set but never used. + * src/bdf/bdflib.c (_bdf_parse_{glyphs,properties}, bdf_load_font): + Updated accordingly. - [psaux] Extend Adobe interpreter (closepath). +2018-08-14 Werner Lemberg - * src/psaux/psintrp.c (cf2_interpT2CharString) : - Use the right builder function. We can use the `haveWidth' boolean - already present, instead of implementing `parse_state'. + [cff] Fix another segv in old engine. -2017-09-25 Ewald Hew + Reported as - [psaux] Add Type 1 operations to Adobe CFF interpreter. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9872 - The following Type 1 specific ops have been added (copied from - `t1decode'): + * src/psaux/cffdecode.c (cff_decoder_parse_charstrings) + [CFF_CONFIG_OPTION_OLD_ENGINE]: Disallow invalid T1 opcodes in + dictionaries. - closepath - vstem3 - hstem3 - seac - sbw - callothersubr - pop - setcurrentpoint - hsbw +2018-08-14 Werner Lemberg - The following require a Type 1 mode, because of differences in - specification: + [cff] Fix missing error handling. - hstem - vstem - vmoveto - callsubr - div - rmoveto - hmoveto - Numbers + Reported as - The subsequent commits will implement these changes and adapt - accesses of data and objects to the new interpreter. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9865 - NOTE: Will not compile in the meantime! + * src/psaux/cffparse.c (cff_parser_run) + [CFF_CONFIG_OPTION_OLD_ENGINE]: Don't ignore return value of + `parse_charstrings_old'. - * src/psaux/psintrp.c: Add opcodes to enum. - (cf2_interpT2CharString): Copy relevant code over from - `t1_decoder_parse_charstrings' (in `t1decode.c'). +2018-08-14 Alexei Podtelezhnikov -2017-09-25 Ewald Hew + [bdf] Remove unused overflow storage. - [type1] Fixes for rendering. + * src/bdf/bdf.h (bdf_glyphlist_t): Remove this type. + (bdf_font_t): Remove `overflow' field. + * src/bdf/bdflib.c (bdf_free_font): Remove `overflow' freeing. - The Type 1 advance width calculation passes null for glyph slot, - etc, which can cause null pointer access in the new interpreter. - Fall back to the old one for now. +2018-08-14 Werner Lemberg - Fix the large glyph retry code and ensure hinting and scaling flags - are set properly. + [cff] Fix segv in old engine. - * src/type1/t1gload.c (T1_Parse_Glyph_And_Get_Char_String): Add a - check for metrics_only. - Set the `force_scaling' flag. - (T1_Parse_Glyph): Updated. - (T1_Load_Glyph): Add `hinting' and `scaled' flags. + Reported as -2017-09-25 Ewald Hew + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9864 - [psaux] Add missing objects (2/2). + * src/psaux/cffdecode.c (cff_decoder_parse_charstrings) + [CFF_CONFIG_OPTION_OLD_ENGINE]: Use top dict's + `random' field directly if parsing dictionaries. - Synthesize a `SubFont' object for Type 1 fonts. This is used in the - interpreter to access Private dict data, which are stored in - different places for Type 1 and CFF. This allows the same data to - be used in either mode. +2018-08-13 Alexei Podtelezhnikov - * src/psaux/psobjs.c (t1_make_subfont): New procedure to copy - required values to a dummy `CFF_SubFont' object. This is similar to - `cff_make_private_dict'. - * src/psaux/psobjs.h: Add the new declaration. + [bdf] Use unsigned types. - * include/freetype/internal/psaux.h, src/psaux/psauxmod.c: Ditto. - Add this to the PSAux Service for future use with CID fonts. + * src/bdf/bdf.h (bdf_glyph_t): Unsign `encoding'. + (bdf_font_t): Unsign `default_char'. + * src/bdf/bdfdrivr.h (BDF_encoding_el): Unsign `enc'. - * src/type1/t1gload.c: Include FT_INTERNAL_CFF_TYPES_H. - (T1_Parse_Glyph_And_Get_Char_String): Add the call. + * src/bdf/bdflib.c (_bdf_add_property, _bdf_parse_glyphs, + _bdf_parse_start): Updated accordingly. + * src/bdf/bdfdrivr.c (bdf_cmap_char_{index,next}): Ditto. -2017-09-25 Ewald Hew +2018-08-13 Werner Lemberg - [psaux] Add missing objects for Type 1 (1/2). + * src/type42/t42parse.c (t42_parse_sfnts): One more format check. - Move `CF2_Font' instance to `PS_Decoder'. This is the context for - the interpreter and since it is currently stored in `CFF_Font', is - unavailable in Type 1 mode. + Reported as - * include/freetype/internal/psaux.h (T1_Decoder, PS_Decoder): New - `cf2_instance' field. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9832 - * src/psaux/psdecode.c (ps_decoder_init): Copy `cf2_instance' to - `PS_Decoder'. +2018-08-11 Werner Lemberg - * src/psaux/t1decode.c (t1_decoder_done): Add finalization code. + * src/base/ftcalc.c (FT_Matrix_Check): Fix integer overflow. - * src/psaux/psft.c (cf2_decoder_parse_charstrings): Update accesses. + Reported as -2017-09-25 Ewald Hew + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9811 - Allow `type1' module to use the Adobe engine. +2018-08-10 Alexei Podtelezhnikov - Add the callback and some conditionals to switch between the two - engines. + * src/sfnt/ttsbit.c (tt_sbit_decoder_load_compound): Follow specs. - * include/freetype/internal/psaux.h (T1_Decoder_FuncsRec): Change - function declarations. - * src/psaux/psauxmod.c (T1_Decoder_FuncsRec): Register the - callbacks. +2018-08-10 Ben Wagner - * src/psaux/psobjs.c (ps_builder_add_point): Add conditionals for - number conversion. + * src/sfnt/sfobjs.c (sfnt_done_face): Fix memory leak (#54435). - * src/type1/t1gload.c (T1_Parse_Glyph_And_Get_Char_String): Add code - to choose which renderer to use. +2018-08-10 Werner Lemberg - * src/cid/cidgload.c (cid_load_glyph): Update call. - * src/base/ftobjs.c, src/psaux/psobjs.c, src/type1/t1gload.c: Update - includes. + * src/base/ftobjs.c (FT_Render_Glyph_Internal): Improve tracing. -2017-09-25 Ewald Hew +2018-08-10 Werner Lemberg - [type1] Add Adobe engine configuration. + Fix clang warnings. - Use the previously changed PS_Driver in type1 module to store - hinting engine configuration. + * src/base/ftdebug.c (ft_trace_level_enabled, + ft_trace_level_disabled): Add `static' keyword. - * include/freetype/ftt1drv.h: New file. - Duplicate and rename config options from CFF. - * include/freetype/config/ftheader.h (FT_TYPE1_DRIVER_H): New macro. +2018-08-09 Alexei Podtelezhnikov - * src/type1/t1driver.c (t1_driver_class): Update declaration. - * src/type1/t1objs.c: Include FT_TYPE1_DRIVER_H. - (T1_Driver_Init): Update code. + [raster, smooth] Reinstate bitmap size limits. -2017-09-25 Ewald Hew + This again moves outline and bitmap size checks one level up. - [cff] Move and rename `CFF_Driver'. + * src/base/ftoutln.c (FT_Outline_Render): Explicitly reject enormous + outlines. + * src/raster/ftrend1.c (ft_raster1_render): Reject enormous bitmaps + and, therefore, outlines that require them. + * src/smooth/ftsmooth.c (ft_smooth_render_generic): Ditto. - This is so that we can use the same hinting engine parameters for - Type 1. + * src/raster/ftraster.c (ft_black_render): Remove outline size checks. + * src/smooth/ftgrays.c (gray_raster_render): Ditto. + [STANDALONE]: Remove `FT_Outline_Get_CBox' copy. - * include/freetype/internal/cffotypes.h (CFF_Driver): Rename and - move to... - * include/freetype/internal/psaux.h (PS_Driver): ...here. +2018-08-08 Alexei Podtelezhnikov - * src/cff/cffdrivr.c, src/cff/cffgload.c, src/cff/cffload.c, - src/cff/cffobjs.c, src/cff/cffobjs.h, src/psaux/psft.c, - src/psaux/psobjs.c: Update references. + [pcf] Revert massive unsigning. -2017-09-25 Ewald Hew +2018-08-08 Werner Lemberg - [psaux, type1] Reorganize object fields. + [smooth] Improve tracing. - Make some fields more generic, so that we can access them the same - way regardless of Type 1 or CFF. + * src/smooth/ftgrays.c (gray_convert_glyph_inner): Only use tracing + if called the first time. + (gray_convert_glyph): Updated. - * include/freetype/internal/psaux.h (PS_Builder): Change `TT_Face' - to `FT_Face'. - Remove unused fields. +2018-08-08 Werner Lemberg - * src/psaux/psft.c: Update all accesses of `PS_Builder.face'. - Add some asserts to guard against casting `T1_Face' as `TT_Face'. + Add internal functions `FT_Trace_Disable' and `FT_Trace_Enable'. - * src/type1/t1objs.h (T1_GlyphSlot): Reorder fields to follow - `CFF_GlyphSlot', so that we can pretend they are the same in the - interpreter. + It sometimes makes sense to suppress tracing informations, for + example, if it outputs identical messages again and again. - * src/psaux/psobjs.c (ps_builder_init, ps_builder_add_point): - Updated with above changes. + * include/freetype/internal/ftdebug.h: Make `ft_trace_levels' a + pointer. + (FT_Trace_Disable, FT_Trace_Enable): New declarations. -2017-09-25 Ewald Hew + * src/base/ftdebug.c (ft_trace_levels): Rename to... + (ft_trace_levels_enabled): ... this. + (ft_trace_levels_disabled): New array. + (ft_trace_levels): New pointer. + (FT_Trace_Disable, FT_Trace_Enable): Implement. + (ft_debug_init): Updated. - [psaux] Prepare for Type 1 mode. +2018-08-08 Werner Lemberg - Add some checks for Type 1 data passing through. + Debugging improvements. - * src/psaux/psfont.h (CF2_Font): Add `isT1' flag. - * src/psaux/psfont.c (cf2_font_setup): Skip the variations and blend - code which is not applicable for Type 1. + * src/base/ftobjs.c (pixel_modes): Move this array to top level + from ... + (FT_Load_Glyph): ... here. + (FT_Render_Glyph_Internal): Use `width' x `height' in trace message. + Use `pixel_modes'. - * src/psaux/psft.c (cf2_decoder_parse_charstrings): Avoid accessing - `decoder->cff' in Type 1 mode. - Copy `is_t1' flag to `CF2_Font'. +2018-08-08 Alexei Podtelezhnikov -2017-09-25 Ewald Hew + [pcf] Massive unsigning (part 2). - [psaux, cff] Use the new objects. + Treat all size related properties as unsigned values. - * include/freetype/internal/psaux.h, src/psaux/psauxmod.c: Fix - switching between new and old engines. + * src/pcf/pcf.h (PCF_ParsePropertyRec): Use unsigned `name' and + `value'. + * src/pcf/pcfread.c (pcf_get_properties, pcf_load_font): Updated + parsing code and handling of AVERAGE_WIDTH, POINT_SIZE, PIXEL_SIZE, + RESOLUTION_X and RESOLUTION_Y. - * src/cff/cffgload.c, src/cff/cffparse.c: Update calls. +2018-08-08 Alexei Podtelezhnikov - * src/psaux/psblues.c, src/psaux/psfont.c, src/psaux/psfont.h, - src/psaux/psft.c, src/psaux/psft.h, src/psaux/psintrp.c: Update all - to use new objects. + [pcf] Massive unsigning (part 1). -2017-09-24 Ewald Hew + Unofficial specifications hesitate to use unsigned 32-bit integers. + Negative values caused a lot of trouble in the past and it is safer + and easier to treat some properties as unsigned. - [psaux] Objects for new interpreter (part 2). + * src/pcf/pcf.h (PCF_AccelRec): Use unsigned values for `fontAscent', + `fontDescent', and `maxOverlap'. + * src/pcf/pcfread.c (pcf_load_font, pcf_get_accel): Updated. + * src/pcf/pcfdrivr.c (PCF_Glyph_Load, PCF_Size_Select, + PCF_Size_Request): Updated. - Make the new objects copy over values. They are essentially wrapper - types for the different decoders/builders. +2018-08-07 Alexei Podtelezhnikov - * include/freetype/internal/psaux.h: Update declarations. - (PS_Builder): Add `is_t1' flag. - (PS_Decoder_{Get,Free}_Glyph_Callback): Renamed to... - (CFF_Decoder_{Get,Free}_Glyph_Callback: ... this. - (PS_Decoder): Updated. - Add `t1_parse_callback' member. - (PSAux_ServiceRec): Add `ps_decoder_init' member. + * src/pcf/pcfread.c (pcf_get_bitmaps): Unsign `offsets' and + `bitmapSizes'. - * src/psaux/psdecode.h, src/psaux/psobjs.h: Update declarations. +2018-08-06 Werner Lemberg - * src/psaux/psdecode.c, src/psaux/psobjs.c: Implement copy with two - modes. + * devel/ftoption.h: Synchronize with main `ftoption.h'. - * src/psaux/psauxmod.c: Add builder and decoder functions to `PSAux' - service. +2018-08-06 Alexei Podtelezhnikov -2017-09-24 Ewald Hew + [pcf] Use unsigned types. - [psaux] Add objects for new interpreter. + * src/pcf/pcf.h (PCF_Encoding): Use unsigned `enc'. + * src/pcf/pcfdrivr.c (pcf_cmap_char_{index,next}): Ditto. + * src/pcf/pcfread.c (pcf_get_encodings): Use unsigned types. - Introduce `PS_Decoder' and `PS_Builder' which include all fields - from either Type 1 or CFF decoders/builders. +2018-08-05 Werner Lemberg - * include/freetype/internal/psaux.h (PS_Builder, PS_Decoder): New - structs. + * src/truetype/ttgload.c (compute_glyph_metrics): Fix overflow. - * src/psaux/psobjs.c, src/psaux/psobjs.h: Add `PS_Builder' - functions. + Reported as - * src/psaux/psdecode.c, src/psaux/psdecode.h: New files to hold - `PS_Decoder' initialization functions. + https://bugs.chromium.org/p/chromium/issues/detail?id=777151 - * src/psaux/psaux.c, src/psaux/Jamfile (_sources), - src/psaux/rules.mk (PSAUX_DRV_SRC): Updated. +2018-08-04 Werner Lemberg -2017-09-24 Ewald Hew + * src/truetype/ttinterp.c (opcode_name): Fix typos. - [psaux] Rename files. +2018-08-04 Werner Lemberg - Replace the `cf2' file name prefix with `ps' as the Adobe engine - will be used for both PostScript Types 1 and 2 (CFF) instead of just - CFF. + Fix clang warnings. - s/cf2/ps/ for all following. + * src/base/ftoutln.c (FT_Outline_EmboldenXY): Fix type of + `orientation'. - * src/psaux/cf2*: Rename files. - * src/psaux/*: Update includes. + * src/gxvalid/gxvcommn.c (gx_lookup_value_read): Fix signature. - * src/psaux/Jamfile (_sources), src/psaux/rules.mk (PSAUX_DRC_SRC, - PSAUX_DRV_H): Update file references. + * src/pcf/pcfread.c (pcf_get_encodings): Fix type of some variables. + Add cast. -2017-09-24 Ewald Hew + * src/type1/t1load.c (parse_weight_vector): Fix cast. - [psaux] Minor fix. +2018-07-31 Werner Lemberg - Use `MultiMasters' service in `psaux' instead of a call to `cff'. - The project builds if CFF_CONFIG_OPTION_OLD_ENGINE is not defined. + * src/cid/cidtoken.h: Handle `XUID' keyword. - * src/psaux/cf2ft.c: Update includes. - (cf2_getNormalizedVector): Use `mm->get_var_blend' instead of - `cff_get_var_blend'. +2018-07-31 Werner Lemberg -2017-09-24 Ewald Hew + [cid] Trace PostScript dictionaries. - [psaux, cff] Move `cff_random' into `psaux' service. + * src/cid/cidload.c: Include FT_INTERNAL_POSTSCRIPT_AUX_H. + (cid_load_keyword, cid_parse_font_matrix, parse_fd_array, + parse_expansion_factor, cid_parse_dict): Add tracing calls. + (parse_font_name): New function to trace `/FontName' keywords in + /FDArray dict. + (cid_field_records): Register `parse_font_name'. - NOTE: Does not compile! +2018-07-30 Werner Lemberg - Minor fix to allow both `cff' and `psaux' to use `cff_random'. + [cff] Fix typo. - * src/cff/cffload.c (cff_random): Move to... - * src/psaux/psobjs.c: Here. - * src/cff/cffload.h: Move corresponding declaration to - `src/psaux/psobjs.h'. + Reported as - * include/freetype/internal/psaux.h (PSAux_ServiceRec): Register the - function here... - * src/psaux/psauxmod.c: And here. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9409 - * src/cff/cffload.c, src/psaux/cf2intrp.c: Update code. + * src/cff/cffdrivr.c (cff_get_cid_from_glyph_index): Fix boundary + check. -2017-09-24 Ewald Hew +2018-07-29 Werner Lemberg - [cff] Move struct declarations to `freetype/internal'. + * src/pcf/pcfread.c (pcf_get_encodings): Another thinko. - NOTE: Does not compile! + Reported as - This is so that the CFF functions moved to `psaux' can access the - same structs that they need. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9608 - * src/cff/cfftypes.h: Moved to... - * include/freetype/internal/cfftypes.h: ...Here. +2018-07-28 Alexei Podtelezhnikov - * src/cff/cffobjs.h: Moved the struct declarations to... - * include/freetype/internal/cffotypes.h: ... this new file. + [smooth] Fix Harmony memory management. - * include/freetype/internal/internal.h (FT_INTERNAL_CFF_TYPES_H, - FT_INTERNAL_CFF_OBJECT_TYPES_H): New macros. + Reported as - * src/cff/cffcmap.h, src/cff/cffdrivr.c, src/cff/cffgload.c, - src/cff/cffgload.h, src/cff/cffload.h, src/cff/cffobjs.c, - src/cff/cffobjs.h, src/cff/cffparse.h, src/psaux/psobjs.h, - include/freetype/internal/psaux.h, - include/freetype/internal/services/svcfftl.h: Update includes. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9501 - * src/cff/rules.mk (CFF_DRV_H): Updated. + * src/smooth/ftgrays.c (ft_smooth_render_generic): Restore buffer + after each rendering in case of failure. -2017-09-24 Ewald Hew +2018-07-28 Werner Lemberg - [psaux, cff] Add new service for inter-module calls. + [type1] Avoid segfaults with `FT_Get_PS_Font_Value'. - NOTE: Does not compile! + Reported as - This is to allow CFF functions moved to `psaux' to call functions - declared in `src/cff/cffload.h'. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9610 - * include/freetype/internal/services/svcfftl.h: New file, setting up - a `CFFLoad' service. - - * include/freetype/internal/ftserv.h (FT_DEFINE_SERVICEDESCREC10, - FT_DEFINE_SERVICEDESCREC): New macros. - (FT_SERVICE_CFF_TABLE_LOAD_H): New macro. + * src/type1/t1driver.c (t1_ps_get_font_value): Protect against NULL. - * src/cff/cffdrivr.c, src/cff/cffpic.h: Register the new service. +2018-07-27 Werner Lemberg - * src/cff/cfftypes.h (CFF_FontRec), src/psaux/cf2font.h - (CF2_FontRec): Add service interface. + [truetype] Make `TT_Set_MM_Blend' idempotent (#54388). - * src/cff/cffobjs.c, src/psaux/cf2font.c, src/psaux/cf2ft.c, - src/psaux/cf2intrp.c, src/psaux/cffdecode.c: Use the new service. + * src/truetype/ttgxvar.c (tt_set_mm_blend): Correctly set + `face->doblend' if the current call to the function yields the same + blend coordinates as the previous call. -2017-09-24 Ewald Hew +2018-07-27 Werner Lemberg - [psaux, cff] Add callbacks for inter-module calls. + [psaux, type1]: More tracing improvements. - NOTE: Does not compile! + * src/psaux/psintrp.c (cf2_interpT2CharString): Trace skipped + outline commands. - * include/freetype/internal/psaux.h: Add function pointer - declarations. + * src/psaux/t1decode.c (t1_decoder_parse_charstring): Fix + missing case. + (t1_decoder_parse_metrics): Make tracing output more compact. - * src/psaux/cffdecode.c (cff_decoder_init): Update to take in - callbacks. - * src/psaux/cffdecode.h: Ditto. + * src/type1/t1gload.c (T1_Compute_Max_Advance): Be less verbose. + (T1_Get_Advances): Add tracing. - * src/cff/cffgload.c (cff_compute_max_advance, cff_slot_load): - Update calls to pass in callbacks. - * src/psaux/cf2ft.c, src/psaux/cffdecode.c: Use them. +2018-07-25 Werner Lemberg -2017-09-24 Ewald Hew + [psaux, type1] Trace PostScript dictionaries and other things. - [psaux, cff] Create new `PSAux' service interface entries. + The tracing of /Encoding, /Subrs, and /Charstrings is rudimentary + right now. - NOTE: Does not compile! + * src/psaux/psobjs.c (ps_parser_load_field, + ps_parser_load_field_table): Add tracing calls. - * include/freetype/internal/psaux.h: Include - FT_INTERNAL_TRUETYPE_TYPES_H. - (CFF_Builder_FuncsRec, CFF_Decocer_FuncsRec): New function tables. - (CFF_Builder): Updated. - Fix for forward declaration. - (PSAux_ServiceRec): New field `cff_decoder_funcs'. + * src/psaux/t1decode.c (t1_decoder_parse_charstrings): Make tracing + output more compact. - * src/psaux/psauxmod.c (cff_builder_funcs, cff_decoder_funcs): New - function tables. - (PSAux_Interface): Updated. + * src/type1/t1gload.c (T1_Compute_Max_Advance, T1_Get_Advances): Add + tracing messages. - * include/freetype/internal/tttypes.h (TT_FaceRec): Add `psaux' - service interface. + * src/type1/t1load.c (parse_blend_axis_types, + parse_blend_design_positions, parse_blend_design_map, + parse_weight_vector, t1_load_keyword, t1_parse_font_matrix, + parse_encoding, parse_subrs, parse_charstrings, T1_Open_Face): Add + tracing calls. - * src/cff/cffgload.c, src/cff/cffobjs.c, src/cff/cffparse.c: Update - function calls to use psaux service. + * src/type1/t1objs.c (T1_Face_Init): Add tracing call. -2017-09-24 Ewald Hew + * src/sfnt/sfobjs.c (sfnt_init_face): Make tracing message more + verbose. - [psaux, cff] Move CFF builder components into `psaux' module. +2018-07-25 Werner Lemberg - NOTE: Does not compile! + Fix minor ASAN run-time warnings. - * src/cff/cffgload.c - (cff_builder_{init,done,add_point,add_point1,add_contour,start_point,close_contour}, - cff_check_points): Move to... - * src/psaux/psobjs.c: Here. + * src/base/ftutil.c (ft_mem_alloc, ft_mem_realloc): Only call + `FT_MEM_ZERO' if we actually have a buffer. + (ft_mem_dup): Only call `ft_memcpy' if we actually have a buffer. - * src/cff/cffgload.h: Move corresponding declarations to - `src/psaux/psobjs.h'. +2018-07-24 Alexei Podtelezhnikov - * src/cff/cffgload.h (CFF_Builder): Move struct declaration to... - * include/freetype/internal/psaux.h: Here. + [build] Fortify dllexport/dllimport attributes (#53969,#54330). -2017-09-24 Ewald Hew + We no longer use predefined _DLL, which can be defined for static + builds too with /MD. We use DLL_EXPORT and DLL_IMPORT instead, + following libtool convention. - [psaux, cff] Move CFF decoder components into `psaux' module. + * CMakeLists.txt [WIN32], builds/windows/vc2010/freetype.vcxproj: + Define DLL_EXPORT manually. - NOTE: Does not compile! + * include/freetype/config/ftconfig.h, builds/unix/ftconfig.in, + builds/vms/ftconfig.h, builds/windows/vc2010/index.html, + src/base/ftver.rc: /_DLL/d, s/FT2_DLLIMPORT/DLL_IMPORT/. - * src/cff/cffgload.c (CFF_Operator, - CFF_COUNT_{CHECK_WIDTH,EXACT,CLEAR_STACK}, cff_argument_counts, - cff_operator_seac, cff_compute_bias, - cff_lookup_glyph_by_stdcharcode, - cff_decoder_{parse_charstrings,init,prepare}): Move to... - * src/psaux/cffdecode.c: This new file. +2018-07-24 Werner Lemberg - * src/cff/cffgload.h: Move corresponding declarations to... - * src/psaux/cffdecode.h: This new file. + [type1] Check relationship between number of axes and designs. - * src/cff/cffgload.h (CFF_MAX_{OPERANDS,SUBRS_CALLS,TRANS_ELEMENTS}, - CFF_Decoder_Zone, CFF_Decoder): Move declarations to... - * include/freetype/internal/psaux.h: Here. + For Multiple Masters fonts we don't support intermediate designs; + this implies that - * src/psaux/cf2ft.h: Update include. + number_of_designs == 2 ^^ number_of_axes - * src/psaux/psaux.c, src/psaux/rules.mk (PSAUX_DRV_SRC): Update with - the new file. + Reported as -2017-09-24 Ewald Hew + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9557 - [psaux, cff] Move Adobe's engine components into `psaux' module. + * src/type1/t1load.c (T1_Open_Face): Ensure above constraint. + (T1_Get_MM_Var): Remove now redundant test. - This is the first patch of a sequence to move the Type 2 charstring - processing capability from the `cff' module to the `psaux' module. +2018-07-24 Hin-Tak Leung - NOTE: Does not compile! + [truetype] Match ttdebug's naming of instruction mnemonics. - * src/cff/cf2*: Move these files to... - * src/psaux/cf2*: Here. + * src/truetype/ttinterp.c: The form used in ttdebug, + "MDRP[G,B,W,?]", etc., is slightly more readable than + "MDRP[00,01,02,03]". - * src/cff/Jamfile (_sources), src/cff/rules.mk (CFF_DRV_SRC, - CFF_DRV_H), src/cff/cff.c, src/cff/cffgload.c: Remove file - references. +2018-07-24 Werner Lemberg - * src/psaux/Jamfile (_sources), src/psaux/rules.mk, src/psaux/psaux.c - (PSAUX_DRV_SRC, PSAUX_DRV_H): Add file references. + * src/pcf/pcfread.c (pcf_get_encodings): Thinko. -2017-09-24 Alexei Podtelezhnikov + Reported as - Tweak per-face LCD filtering controls. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9561 - Thing are simpler with a NULL-function pointer. +2018-07-22 Werner Lemberg - * include/freetype/internal/ftobjs.h (FT_Face_InternalRec): New - pointer to the filter function. - (FT_LibraryRec): Remove unused `lcd_filter'. - (FT_Bitmap_LcdFilterFunc, ft_lcd_filter_fir): Move from here... - * include/freetype/ftlcdfil.h (FT_Bitmap_LcdFilterFunc, - ft_lcd_filter_fir): ... to here. + * src/pcf/pcfread.c (pcf_get_encodings): Check index of defaultChar. - * src/base/ftobjs.c (ft_open_face_internal): NULL-initialize the - per-face filter. - (FT_Face_Properties): Set it. - * src/smooth/ftsmooth.c (ft_smooth_render_generic): Simplify. + Reported as - * src/base/ftlcdfil.c (ft_lcd_filter_fir, FT_Libary_SetLcdFilter): - Minor. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9527 -2017-09-24 Jonathan Kew +2018-07-22 Werner Lemberg - [sfnt] Fix `premultiply_data' (#52092). + * src/pcf/pcfread.c (pcf_load_font): Fix number of glyphs. - * src/sfnt/pngshim.c (premultiply_data): Don't use vector extension - if we have less than 16 bytes of data. + This is an oversight of the module change 2018-07-21. -2017-09-24 Werner Lemberg + Reported as - [otvalid] Fix handling of ValueRecords. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9524 - For GPOS pair positioning format 1 the description of ValueRecords - in the OpenType specification (1.8.2, from today) is wrong – the - offset has to be taken from the parent structure; in this case the - `PairSet' table. +2018-07-22 Werner Lemberg - * src/otvalid/otvgpos.c (otv_PairSet_validate): Set `extra3'. - (otv_PairPos_validate): Adjust. + [cid] Sanitize `BlueShift' and `BlueFuzz'. -2017-09-23 Werner Lemberg + This code is taken from the type1 module. - [otvalid] Handle `GSUB' and `GPOS' v1.1 tables. + Reported as - * src/otvalid/otvgsub.c (otv_GSUB_validate), src/otvalid/otvgpos.c - (otv_GPOS_validate): Implement it. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9510 -2017-09-23 Werner Lemberg + * src/cid/cidload.c (parse_fd_array): Set some private dict default + values. + (cid_face_open): Do the sanitizing. + Fix some tracing messages. - [otvalid] Update common table handling to OpenType 1.8.2. +2018-07-21 Werner Lemberg - * src/otvalid/otvcommn.c (otv_Device_validate): Handle - VariationIndex subtable. - (otv_Lookup_validate): Handle MarkFilteringSet. + [pcf] Fix handling of the undefined glyph. -2017-09-23 Alexei Podtelezhnikov + This change makes the driver use the `defaultChar' property of PCF + files. - [build] Windows-style DLL versioning. + * src/pcf/pcf.h (PCF_FaceRec): Change type of `defaultChar' to + unsigned. - * build/windows/ftver.rc: New VERSIONINFO resource. - * build/windows/vc2010/freetype.vcxproj: Further improvements. + * src/pcf/pcfread.c (pcf_get_encodings): Read `defaultChar' as + unsigned. + Validate `defaultChar'. + If `defaultChar' doesn't point to glyph index zero, swap glyphs with + index zero and index `defaultChar' and adjust the encodings + accordingly. -2017-09-23 Ben Wagner + * src/pcf/pcfdrivr.c (pcf_cmap_char_index, pcf_cmap_char_next, + PCF_Glyph_Load): Undo change from 2002-06-16 which always enforced + the first character in the font to be the default character. - [truetype] Really fix #52082. +2018-07-20 Armin Hasitzka - * src/truetype/ttinterp.c (Ins_MDRP): Correct conditional. + Move the legacy fuzz target to the `freetype-testing' repository. -2017-09-23 Werner Lemberg + It can now be found at - [otvalid] Handle `GDEF' v1.2 and v1.3 tables. + https://github.com/freetype/freetype2-testing/tree/master/fuzzing/src/legacy - No validation of variation stuff yet. + * src/tools/ftfuzzer: Remove this folder and its contents from the + repository. - * src/otvalid/otvgdef.c (otv_MarkGlyphSets_validate): New function. - (otv_GDEF_validate): Implement it. +2018-07-20 Werner Lemberg -2017-09-22 Werner Lemberg + [cff] Avoid left-shift of negative numbers (#54322). - [otvalid] Handle `BASE' v1.1 table. + * src/cff/cffgload.c (cff_slot_load): Use multiplication. - No validation of variation stuff yet. +2018-07-17 Werner Lemberg - * src/otvalid/otvbase.c (otv_BASE_validate): Implement it. + Allow FT_ENCODING_NONE for `FT_Select_Charmap'. -2017-09-22 Werner Lemberg + This is a valid encoding tag for BDF, PCF, and Windows FNT, and + there is no reason to disallow it for these formats. - [otvalid] Macros for 32bit offset support. + * src/base/ftobjs.c (FT_Select_Charmap): Implement it. - * src/otvalid/otvcommn.h (OTV_OPTIONAL_TABLE32, - OTV_OPTIONAL_OFFSET32, OTV_SIZE_CHECK32): New macros. +2018-07-17 Werner Lemberg -2017-09-21 Alexei Podtelezhnikov + * src/pcf/pcfread.c (pcf_get_encodings): Trace `defaultChar'. - [build] Simplify Visual C++ 2010 project. +2018-07-16 Armin Hasitzka - * build/windows/vc2010/freetype.vcxproj: Remove fake singlethreaded - configurations and tweak. + * include/freetype/internal/ftcalc.h: Add macros for handling + harmless over-/underflowing `FT_Int' values. -2017-09-21 Werner Lemberg + * src/sfnt/sfdriver.c (fixed2float): Fix negation of + `(int)(-2147483648)'. - [truetype] Integer overflow (#52082). + Reported as - * src/truetype/ttinterp.c (Ins_MDRP): Avoid FT_ABS. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9423 -2017-09-21 Werner Lemberg +2018-07-16 Werner Lemberg - [sfnt] Fix postscript name for default instance of variation fonts. + * src/truetype/ttgxvar.c (tt_set_mm_blend): Fix off-by-one error. - Problem reported by Behdad. + Reported as - * src/sfnt/sfdriver.c (sfnt_get_ps_name): Test - `is_default_instance'. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9412 -2017-09-21 Werner Lemberg +2018-07-12 Werner Lemberg - [truetype] Fix `mmvar' array pointers, part 2. + * src/base/ftoutln.c (FT_Outline_Get_Orientation): Init `cbox'. - The previous commit was incomplete. + Taken from patch #9667, written by Steve Langasek + . - * src/truetype/ttgxvar.c: Properly initialize sub-array offsets for - `master' also. + This fixes a build failure (most probably a bug in gcc) on ppc64el + when building with -O3. -2017-09-21 Werner Lemberg +2018-07-05 Werner Lemberg - [truetype] Fix `mmvar' array pointers. + Fix typo (#54238). - Without this change, clang's AddressSanitizer reports many runtime - errors due to misaligned addresses. + * src/base/ftcolor.c (FT_Palette_Set_Foreground_Color) + [!TT_CONFIG_OPTION_COLOR_LAYERS]: Add return value. - * src/truetype/ttgxvar.c (TT_Get_MM_Var): Use multiples of pointer - size for sub-array offsets into `mmvar'. +2018-07-05 Werner Lemberg -2017-09-20 Werner Lemberg + Adjust table size comparisons (#54242). - [truetype] Integer overflows. + * src/sfnt/ttcpal.c (tt_face_load_cpal): Implement it. - Changes triggered by +2018-07-05 Werner Lemberg - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3429 + Fix more 32bit issues (#54208). - * src/truetype/ttinterp.c (Ins_SHPIX, Ins_DELTAP): Use NEG_LONG. - (Ins_MIAP): Use SUB_LONG. + * src/cff/cffload.c (cff_blend_build_vector): Convert assertion into + run-time error. -2017-09-19 Alexei Podtelezhnikov + * src/truetype/ttgxvar.c (ft_var_to_normalized): Protect against + numeric overflow. - [build] Fix DLL builds in Visual C++ project. +2018-07-04 Werner Lemberg - * build/windows/vc2010/freetype.vcxproj: Use DynamicLibrary in Debug - and Release configurations. - * include/freetype/config/ftconfig.h (FT_EXPORT, FT_EXPORT_DEF) - [_DLL]: Use Visual C++ extensions. + Fix 32bit build warnings (#54239). -2017-09-19 John Tytgat + * src/base/ftbitmap.c (FT_Bitmap_Blend): Add casts to avoid signed + vs. unsigned comparisons. - [cff] Fix family name logic of pure CFF fontdata (#52056). + * srb/sfnt/ttcolr.c (tt_face_get_colr_layer): Ditto. - 1. If `FamilyName' is present in the CFF font, use this for - FT_Face's `family_name'. - 2. Otherwise, use the face name and chop off any subset prefix. - 3. If at this point FT_Face's `family_name' is set, use this - together with the full name to determine the style. - 4. Otherwise, use `CIDFontName' as FT_Face's `family_name'. - 5. If we don't have a valid style, use "Regular". +2018-07-02 Jeff Carey - Previously, FT_Face's `family_name' entry for pure CFF fontdata - nearly always was the fontname itself, instead of the `FamilyName' - entry in the CFF font (assuming there is one). + * src/psnames/psmodule.c (ps_unicodes_init): Fix alloc debugging. - * src/cff/cffobjs.c (cff_face_init) [pure_cff]: Implement it. +2018-07-02 Werner Lemberg -2017-09-18 Alexei Podtelezhnikov + s/palette_types/palette_flags/. - [build] Declutter Visual C++ 2010-2017 project. + Suggested by Behdad. - * build/windows/vc2010/freetype.vcxproj: Use MaxSpeed (/02) - optimization for Release configuration throughout the project. +2018-07-02 Werner Lemberg -2017-09-16 Werner Lemberg + Make `FT_Get_Color_Glyph_Layer' return FT_Bool. - * Version 2.8.1 released. - ========================= + * include/freetype/freetype.h, src/base/ftobjs.c + (FT_Get_Color_Glyph_Layer, FT_Render_Glyph_Internal): Updated. + * include/freetype/internal/sfnt.h (TT_Get_Colr_Layer_Func), + src/sfnt/ttcolr.h, src/sfnt/ttcolr.c (tt_face_get_colr_layer): + Updated. - Tag sources with `VER-2-8-1'. +2018-07-01 Werner Lemberg - * docs/VERSION.TXT: Add entry for version 2.8.1. - * docs/CHANGES: Updated. + * src/base/ftobjs.c (FT_Get_Color_Glyph_Layer): Guard SFNT function. - * README, Jamfile (RefDoc), builds/windows/vc2005/freetype.vcproj, - builds/windows/vc2005/index.html, - builds/windows/vc2008/freetype.vcproj, - builds/windows/vc2008/index.html, - builds/windows/vc2010/freetype.vcxproj, - builds/windows/vc2010/index.html, - builds/windows/visualc/freetype.dsp, - builds/windows/visualc/freetype.vcproj, - builds/windows/visualc/index.html, - builds/windows/visualce/freetype.dsp, - builds/windows/visualce/freetype.vcproj, - builds/windows/visualce/index.html, - builds/wince/vc2005-ce/freetype.vcproj, - builds/wince/vc2005-ce/index.html, - builds/wince/vc2008-ce/freetype.vcproj, - builds/wince/vc2008-ce/index.html: s/2.8/2.8.1/, s/28/281/. + Reported by Behdad. - * include/freetype/freetype.h (FREETYPE_PATCH): Set to 1. +2018-06-28 Alexei Podtelezhnikov - * builds/unix/configure.raw (version_info): Set to 21:0:15. - * CMakeLists.txt (VERSION_PATCH): Set to 1. + * src/base/fttrigon.c (FT_Tan): Improve accuracy. + (FT_Vector_Rotate): Simplify. -2017-09-13 suzuki toshiya +2018-06-28 Alexei Podtelezhnikov - [sfnt] lowest gcc for vectors (e1d0249e) is changed to 4.7. + * src/base/ftobjs.c (FT_Set_Charmap): Robustify. - __builtin_shuffle() was introduced in gcc-4.7. The lowest - gcc to enable vector operation is delayed from 4.6 to 4.7. +2018-06-25 Werner Lemberg - * src/sfnt/pngshim.c (premultiply_data): Fix cpp-macro to - enable the vector operation, to change the lowest gcc version - from 4.6 to 4.7. + [truetype] Fix memory leak. -2017-09-13 suzuki toshiya + * src/truetype/ttgxvar.c (TT_Vary_Apply_Glyph_Deltas): Add initializers. + Fix typo in `goto' destination. - [cache] Fix a possible overflow by signed integer comparison. + Reported as - Improve the code by 5d3ff05615dda6d1325ed612381a17a0df04c975 , - issues are found by Behdad Esfahbod and Werner Lemberg. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9071 - * src/cache/ftcbasic.c (FTC_ImageCache_Lookup): Replace - a subtraction to check higher bit by a bit operation, - and cpp-conditionalize for appropriate systems. Add better - documentation to the comment. - (FTC_ImageCache_LookupScaler): Ditto. - (FTC_SBitCache_Lookup): Ditto. - (FTC_SBitCache_LookupScaler): Ditto. +2018-06-25 Werner Lemberg -2017-09-13 Werner Lemberg + * src/truetype/ttgxvar.c (tt_face_vary_cvt): Add initializers. - [autofit] Really fix #41334 (#52000). + Reported as - * src/autofit/aflatin.c (af_latin_hints_compute_segments): Set - `segment->delta' everywhere. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9070 -2017-09-12 suzuki toshiya +2018-06-24 Werner Lemberg - [autofit, sfnt] Fix for `make multi'. + [truetype] Increase precision while applying VF deltas. - * src/autofit/afshaper.c: Include FT_ADVANCE_H, to use - FT_Get_Advance() in it. - * src/sfnt/ttcmap.c: Include FT_SERVICE_POSTSCRIPT_CMAPS_H - to use PS_Unicodes in it, also include `ttpost.h' to use - tt_face_get_ps_name() in it. + It turned out that we incorrectly round CVT and glyph point deltas + before accumulation, leading to severe positioning errors if there + are many delta values to sum up. -2017-09-11 Azzuro + Problem reported by Akiem Helmling and analyzed + by Behdad. - [build] Improve builds with different MS Visual Studio versions. + * src/truetype/ttgxvar.c (ft_var_readpackeddelta): Return deltas in + 16.16 format. + (tt_face_var_cvt): Collect deltas in `cvt_deltas', which is a 16.16 + format array, and add the accumulated values to the CVT at the end + of the function. + (TT_Vary_Apply_Glyph_Deltas): Store data in `points_org' and + `points_out' in 16.16 format. + Collect deltas in `point_deltas_x' and `point_deltas_y', which are + 16.16 format arrays, and add the accumulated values to the glyph + coordinates at the end of the function. - * builds/windows/vc2010/freetype.vcxproj: Switch platform toolset - according to the Visual Studio version. +2018-06-24 Werner Lemberg -2017-09-11 Werner Lemberg + New base function `FT_Matrix_Check' (#54019). - * src/sfnt/ttkern.c (tt_face_load_kern): Reject format 2 tables. + * src/base/ftcalc.c (FT_Matrix_Check): New base function to properly + reject degenerate font matrices. - Reported by Behdad. + * include/freetype/internal/ftcalc.h: Updated. -2017-09-09 Werner Lemberg + * src/cff/cffparse.c (cff_parse_font_matrix), src/cid/cidload.c + (cid_parse_font_matrix), src/type1/t1load.c (t1_parse_font_matrix), + src/type42/t42parse.c (t42_parse_font_matrix): Use + `FT_Matrix_Check'. - [autofit] Improve communication with ftgrid. +2018-06-23 Werner Lemberg - * src/autofit/afhints.c (af_glyph_hints_get_segment_offset): - Provide values in font units. + Fix typo. -2017-09-08 suzuki toshiya + Reported by Behdad. - [base] Remove a check for resource ID in the resource fork driver. + * src/base/ftcolor.c (FT_Palette_Data_Get) + [!TT_CONFIG_OPTION_COLOR_LAYERS]: s/apalette/apalette_data/. - LastResort.dfont has a marginal resource ID 0xFFFF for sfnt - resource. Inside Macintosh: More Macintosh Toolbox, `Resource IDs' - (1-46), tells that some IDs are reserved and should not be used. - FreeType2 just uses resource ID to sort the fragmented resource. - To accept the marginal fonts, the checking is removed. +2018-06-21 Werner Lemberg - * src/base/ftrfork.c (FT_Raccess_Get_DataOffsets): Remove res_id - validity check, fix a trace message format. + s/FT_PALETTE_USABLE_WITH_/FT_PALETTE_FOR_/. -2017-09-08 suzuki toshiya + * include/freetype/ftcolor.h, include/freetype/internal/sfnt.h, + src/sfnt/ttcolr.c: Do it. - [sfnt, truetype] Register the tags for marginal fonts. +2018-06-19 Werner Lemberg - The first 32bit of standard TrueType variants is 0x00010000, - `OTTO', `ttcf', `true' or `typ1'. 2 marginal dfonts on legacy Mac - OS X, Keyboard.dfont and LastResort.dfont, have the sfnt resources - starting 0xA5 followed by `kbd' or `lst'. Considering the following - data could be parsed as conventional TrueType fonts, the header - checking is updated to allow these tags. It seems that recent Mac - OS X has already switched to normal TTF for these fonts. + [sfnt] Fix CPAL heap buffer overflow. - See the discussion at - http://u88.n24.queensu.ca/exiftool/forum/index.php?topic=3931.0 + Reported as - * include/freetype/tttags.h (TTAG_0xA5kbd, TTAG_0xA5lst): New header - tags for Keyboard.dfont and LastResort.dfont. - * src/sfnt/sfobjs.c (sfnt_open_font): Accept the sfnt resource - starts with TTAG_0xA5kbd or TTAG_0xA5lst. - * src/truetype/ttobjs.c (tt_face_init): Accept the face with the - format tag is TTAG_0xA5kbd or TTAG_0xA5lst. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=8968 -2017-09-05 Werner Lemberg + * src/sfnt/ttcpal.c (tt_face_load_cpal): Guard CPAL version 1 + offsets. - Fix multiple calls of `FT_Bitmap_Convert'. +2018-06-19 Werner Lemberg - The documentation of `FT_Bitmap_Convert' says that multiple calls do - proper reallocation of the target FT_Bitmap object. However, this - failed for the sequence + Doh. Don't use CPAL or COLR data if tables are missing. - non-empty bitmap - empty bitmap - non-empty bitmap + Reported by Alexei. - Reason was that `FT_Bitmap_Convert' only reallocated the bitmap - buffer if it became too small; it didn't make the buffer smaller. - For an empty bitmap following a non-empty one, only the buffer - dimension got set to zero, without deallocation. If the next call - was a non-empty buffer again, an assertion in `ft_mem_qrealloc' was - triggered. + * src/sfnt/ttcolr.c (tt_face_get_colr_layer): Return immediately if + `colr' is NULL. - * src/base/ftbitmap.c (FT_Bitmap_Convert): Always reallocate target - buffer to the correct size. + * src/sfnt/ttcpal.c (tt_face_palette_set): Return immediately, if + `cpal' is NULL. - * docs/CHANGES: Document it. +2018-06-17 Alexei Podtelezhnikov -2017-09-05 Werner Lemberg + [base] Introduce `FT_New_Glyph'. - [bdf] Fix size and resolution handling. + This function facilitates access to full capabilities of FreeType + rendering engine for custom glyphs. This can be quite useful for + consistent rendering of mathematical and chemical formulas, e.g. - * src/bdf/bdfdrivr.c (BDF_Face_Init): Use `SIZE' values if - `POINT_SIZE', `RESOLUTION_X', or `RESOLUTION_Y' properties are - missing. + https://bugs.chromium.org/p/chromium/issues/detail?id=757078 - * docs/CHANGES: Document it. + * include/freetype/ftglyph.h, src/base/ftglyph.c (FT_New_Glyph): New + function. -2017-08-25 Alexei Podtelezhnikov +2018-06-17 Armin Hasitzka - Swap `ALLOC_MULT' arguments (#51833). + [bdf] Fix underflow of an unsigned value. - * src/base/ftbitmap.c (ft_bitmap_assure_buffer): Updated. - * src/winfonts/winfnt.c (FNT_Load_Glyph): Updated. - * src/raster/ftrend1.c (ft_raster1_render): Updated. + bdflib.c:1562 could be reached with `font->glyphs_used == 0'. That + caused an underflow of the unsigned value which results in undefined + behaviour. -2017-08-23 Werner Lemberg + * src/bdf/bdflib.c (_bdf_parse_glyphs): Bail out earlier than before + if the `ENCODING' keyword cannot be found. - [sfnt] Fix clang compilation (#51788). +2018-06-17 Werner Lemberg - * src/sfnt/pngshim.c (premultiply_data): Use vectors instead of - scalars. - (vector_shuffle): New macro to take care of a different built-in - function name on clang. + [base] Add tracing for `FT_Bitmap_Blend'. -2017-08-22 Werner Lemberg + * include/freetype/internal/fttrace.h (trace_bitmap): New + enumeration. - [base] Don't zero out allocated memory twice (#51816). + * src/base/ftbitmap.c (FT_COMPONENT): Define. + (FT_Bitmap_Blend): Add `FT_TRACE5' calls. - Patch applied from bug report. +2018-06-17 Werner Lemberg - * src/base/ftutil.c (ft_mem_qrealloc): Use low-level allocation to - avoid unnecessary overhead. + s/trace_bitmap/trace_checksum/. -2017-08-22 Werner Lemberg + * include/freetype/internal/fttrace.h: s/bitmap/checksum/. - [truetype] Integer overflow. + * src/base/ftobjs.c (FT_COMPONENT): s/trace_bitmap/trace_checksum/. + Adjust code. - Changes triggered by +2018-06-16 Werner Lemberg - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3107 + [sfnt] Fix color glyph layer loading. - * src/truetype/ttinterp.c (Ins_MDRP, Ins_MIRP, Ins_ALIGNPTS): Use - NEG_LONG. + * src/sfnt/ttcolr.c (Colr): Add `table_size' field. + (tt_face_load_colr): Set it. + (tt_face_get_colr_layer): Check pointer limit for layer entries. -2017-08-17 Alexei Podtelezhnikov +2018-06-16 Werner Lemberg - [sfnt] Avoid synthetic unicode for symbol fonts with PUA. + [sfnt] Fix color palette loading. Reported as - https://bugs.chromium.org/p/chromium/issues/detail?id=754574 + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=8933 - * src/sfnt/sfobjs.c (sfnt_load_face): Check for FT_ENCODING_MS_SYMBOL. + * src/sfnt/ttcpal.c (Cpal): Add `table_size' field. + (tt_face_load_cpal): Set it. + (tt_face_palette_set): Check pointer limit for color entries. -2017-08-16 Werner Lemberg +2018-06-16 Werner Lemberg - * src/sfnt/pngshim.c (premultiply_data): Fix compiler warnings. + * src/base/ftbitmap.c (FT_Bitmap_Blend): Avoid integer overflow. -2017-08-15 Behdad Esfahbod +2018-06-16 Werner Lemberg - [sfnt] Speed up PNG image loading. + Add `FT_Bitmap_Blend' API. - This reduces the overhead of `premultiply_data' by 60%. + Still missing: Support for negative bitmap pitch and subpixel offset + of source bitmap. - * src/sfnt/pngshim.c (premultiply_data): Provide code which uses - gcc's (and clang's) `vector_byte' attribute to process 4 pixels at a - time. + * include/freetype/ftbitmap.h, src/base/ftbitmap.c + (FT_Bitmap_Blend): New function. -2017-08-11 Werner Lemberg +2018-06-14 Werner Lemberg - [sfnt, truetype] Improve handling of missing sbits. + Replace `FT_Get_GlyphLayers' with `FT_Get_Color_Glyph_Layer'. - Requested by Behdad. + This avoids any additional allocation of COLR related structures in + a glyph slot. - Modern bitmap-only SFNTs like `NotoColorEmoji.ttf' don't contain - entries in the bitmap strike(s) for empty glyphs. Instead, they - rely that a space glyph gets created from the font's metrics data. - This commit makes FreeType behave accordingly. + * include/freetype/freetype.h (FT_Glyph_Layer, FT_Glyph_LayerRec, + FT_Get_GlyphLayers): Removed. - * include/freetype/fterrdef.h (FT_Err_Missing_Bitmap): New error - code. + * include/freetype/internal/ftobjs.h (FT_Colr_InternalRec): Removed. + (FT_Slot_InternalRec): Remove `color_layers'. - * src/sfnt/ttsbit.c (tt_sbit_decoder_load_image): Change error codes - to make a distinction between a missing bitmap in a composite and a - simple missing bitmap. + * include/freetype/internal/sfnt.h (TT_Load_Colr_Layer_Func): + Removed. + (SFNT_Interface, FT_DEFINE_SFNT_INTERFACE): Remove + `load_colr_layer'. - * src/truetype/ttgload.c (TT_Load_Glyph): For a missing bitmap (in a - bitmap-only font), synthesize an empty bitmap glyph if metrics are - available. + * src/base/ftobjs.c (ft_glyph_slot_done): Updated. + (FT_Render_Glyph_Internal): Use `FT_Get_Color_Glyph_Layer'. + (FT_Get_GlyphLayers): Removed. -2017-08-10 Werner Lemberg + * src/sfnt/sfdriver.c (sfnt_interface): Updated. - [base] Minor API improvement for default variation axis setting. + * src/sfnt/ttcolr.c (tt_face_load_colr_layers): Removed. + * src/sfnt/ttcolr.h: Updated. - * src/base/ftmm.c (FT_Set_MM_Design_Coordinates, - FT_Set_Var_Design_Coordinates, FT_Set_MM_Blend_Coordinates, - FT_Set_Var_Blend_Coordinates): Allow coords==NULL if num_coords==0. + * src/truetype/ttgload.c (TT_Load_Glyph): Updated. - * docs/CHANGES: Updated. +2018-06-14 Werner Lemberg -2017-08-08 Werner Lemberg + Provide iterative API to access `COLR' data. - [psnames] Really fix issue #49949. + This solution doesn't store any data in an `FT_GlyphSlot' object. - We now use a separate preprocessor macro to handle both definition - and declaration of the glyph name arrays. + * include/freetype/freetype.h (FT_LayerIterator): New structure. + (FT_Get_Color_Glyph_Layer): New function. - * src/psnames/psmodule.c (DEFINE_PS_TABLE_DATA): New macro. + * include/freetype/internal/sfnt.h (TT_Get_Colr_Layer_Func): New + function type. + (SFNT_Interface, FT_DEFINE_SFNT_INTERFACE): Add it. - * src/tools/glnames.py (StringTable::dump, - StringTable::dump_sublist): Use `DEFINE_PS_TABLE_DATA'. - (dump_encoding): Ditto. - (main): Use `wb' mode for writing the output file, which works on - Windows also. + * src/base/ftobjs.c (FT_Get_Color_Glyph_Layer): Implement it. - * src/psnames/pstables.h: Regenerated. + * src/sfnt/ttcolr.c (tt_face_get_colr_layer): New function. + * src/sfnt/ttcolr.h: Updated. -2017-08-08 Alexei Podtelezhnikov + * src/sfnt/sfdriver.c (sfnt_interface): Updated. - [smooth] Harmony LCD rendering. +2018-06-14 Werner Lemberg - This is a new technology for LCD-optimized rendering. It capitalizes - on the fact that each color channel grid is shifted by a third of a - pixel. Therefore it is logical to render 3 separate monochrome - bitmaps shifting the outline by 1/3 pixel, and then combine them. - Importantly, the resulting output does not require additional LCD - filtering. + Add glyph index and glyph load flags to glyph slot. - * src/smooth/ftsmooth.c (ft_smooth_render_generic) - [!FT_CONFIG_OPTION_SUBPIXEL_RENDERING]: Implement new LCD-optimized - rendering. + * include/freetype/freetype.h (FT_GlyphSlotRec): Rename unused + `reserved' field to `glyph_index'. - * include/freetype/ftlcdfil.h, include/freetype/freetype.h, - include/freetype/config/ftoption.h, devel/ftoption.h: Updated - documentation. + * include/freetype/internal/ftobjs.h (FT_Slot_InternalRec): Add + `load_flags' field. -2017-08-08 Alexei Podtelezhnikov + * src/base/ftobjs.c (FT_Load_Glyph): Set new fields. - * src/smooth/ftsmooth.c (ft_smooth_render_generic): Clean up. +2018-06-14 Werner Lemberg -2017-08-08 Alexei Podtelezhnikov + [sfnt] Move `CPAL' stuff into separate files. - * src/sfnt/ttpost.c (format): Use otspec-compliant versions. + * src/sfnt/sfdriver.c: Include `ttcpal.h'. + * src/sfnt/sfnt.c: Include `ttcpal.c'. -2017-08-05 Werner Lemberg + * src/sfnt/ttcolr.c, src/sfnt/ttcolr.h: Move CPAL stuff to ... + * src/sfnt/ttcpal.c, src/sfnt/ttcpal.c: ... these new files. - [truetype] Integer overflow. + * src/sfnt/Jamfile (_sources), src/sfnt/rules.mk (SFNT_DRV_SRC): + Updated. - Reported as + * include/freetype/internal/fttrace.h: Add support for `colr' and + `cpal'. + Sort entries. - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2868 +2018-06-13 Werner Lemberg - * src/truetype/ttinterp.c (Ins_ALIGNRP): Use NEG_LONG. + [sfnt] Separate `CPAL' and `COLR' table handling. -2017-08-05 Werner Lemberg + Later on we want to support the `SVG' table also, which needs `CPAL' + (but not `COLR'). - [base, truetype] New function `FT_Get_Var_Axis_Flags'. + * include/freetype/internal/sfnt.h (SFNT_Interface): Add `load_cpal' + and `free_cpal' fields. + (FT_DEFINE_SFNT_INTERFACE): Updated. - The reserved `flags' field got a value in OpenType version 1.8.2; - unfortunately, the public `FT_Var_Axis' structure misses the - corresponding element. Since we can't add a new field, we add an - access function. + * include/freetype/internal/tttypes.h (TT_FaceRec): Replace + `colr_and_cpal' fields with `cpal' and `colr'. - * src/base/ftmm.c (FT_Get_Var_Axis_Flags): New function. + * src/sfnt/sfdriver.c (sfnt_interface): Updated. - * include/freetype/ftmm.h (FT_VAR_AXIS_FLAG_HIDDEN): New macro. - Updated. + * src/sfnt/sfobjs.c (sfnt_load_face, sfnt_done_face): Updated. - * src/truetype/ttgxvar.c (TT_Get_MM_Var): Increase allocated memory - of `mmvar' to hold axis flags. - Fill the axis flags array. + * src/sfnt/ttcolr.c (Colr, Cpal): Add `table' field. + (ColrCpal): Removed. + (tt_face_load_colr): Split off CPAL handling into... + (tt_face_load_cpal): ... this new function. + (tt_face_free_colr): Split off CPAL handling into... + (tt_face_free_cpal): ... this new function. + (tt_face_load_colr_layers, tt_face_palette_set): Updated. - * docs/CHANGES: Updated. + * src/sfnt/ttcolr.h: Updated. -2017-08-03 Nikolaus Waxweiler + * src/truetype/ttgload.c (TT_Load_Glyph): Updated. - [truetype] Fix metrics of B/W hinting in v40 mode. +2018-06-12 Werner Lemberg - Phantom points are now saved outside v40 backwards compatibility - mode. This fixes the jumping glyphs when switching between v35 and - v40 monochrome mode. + [sfnt] Fix `sizeof' thinko. - * src/truetype/ttgload.c (TT_Hint_Glyph): Fix inversed bool logic. + * src/sfnt/ttcolr.c (tt_face_load_colr, tt_face_palette_set): Don't + use `sizeof' for computing array limit. -2017-08-03 Nikolaus Waxweiler +2018-06-12 Werner Lemberg - [truetype] Do not set any ClearType flags in v40 monochrome mode. + Finish CPAL/COLR support (4/4). - This fixes weird behavior of instructions that resulted in rendering - differences between v35 and v40 in monochrome mode, e.g., in - `timesbi.ttf'. + * src/sfnt/ttcolr.c (tt_face_find_color): Removed. + (tt_face_colr_blend_layer): Use `face->palette' instead of calling + `tt_face_find_color'. + Use and set text foreground color. - * src/truetype/ttinterp.c (Ins_GETINFO) - [TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL]: Check - `subpixel_hinting_lean'. +2018-06-12 Werner Lemberg -2017-08-01 Werner Lemberg + Finish CPAL/COLR support (3/4). - * src/truetype/ttgxvar.c (TT_Get_MM_Var): Fix thinko. + * src/base/ftcolor.c: Include FT_INTERNAL_SFNT_H. + (FT_Palette_Select, FT_Palette_Set_Foreground_Color): Implement + functions. -2017-08-01 Behdad Esfahbod +2018-06-12 Werner Lemberg - [truetype] Fix loading of named instances. + Finish CPAL/COLR support (2/4). - * src/truetype/ttgxvar.c (TT_Get_MM_Var): Preserve file position - while loading the `avar' table. + * src/sfnt/ttcolr.c (tt_face_palette_set): New function. + (tt_face_load_colr): Allocate `face->palette' and call + `tt_face_palette_set'. + Adjust return error code in case of error. -2017-08-01 Werner Lemberg + * src/sfnt/ttcolr.h: Updated. - [sfnt, truetype] Minor adjustments for OpenType 1.8.2. + * include/freetype/internal/sfnt.h (TT_Set_Palette_Func): New + function type. + (SFNT_Interface, FT_DEFINE_SFNT_INTERFACE): Add it. - * src/sfnt/sfobjs.c (sfnt_load_face): The units per EM value has now - (tighter) limits. + * src/sfnt/sfdriver.c (sfnt_interface), src/sfnt/sfobjs.c + (sfnt_done_face): Updated. - * src/truetype/ttgload.c (load_truetype_glyph): The new OpenType - version explicitly allows all negative values for the number of - contours if we have a composite glyph (this is for better backwards - compatibility I guess), but it still recommends value -1. +2018-06-12 Werner Lemberg -2017-07-26 Werner Lemberg + Finish CPAL/COLR support (1/4). - [cff] Integer overflow. + * include/freetype/internal/tttypes.h (TT_FaceRec): New fields + `palette_index', `palette', `have_foreground_color' and + `foreground_color'. - Reported as +2018-06-12 Werner Lemberg - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2738 + [sfnt] Minor. - * src/cff/cf2hints.c (cf2_glyphpath_computeOffset, - cf2_glyphpath_curveTo): Use ADD_INT32. + * src/sfnt/ttcolr.c (tt_face_load_colr_layers): + s/palette_index/palette_entry_index/ for consistency. + Adjust return error code in case of error. -2017-07-13 Werner Lemberg +2018-06-11 Alexei Podtelezhnikov - [base] Fix memory leak. + [raster] Clean up. - Reported as + * src/raster/ftraster.c (black_TWorker, SCALED, Set_High_Precision): + Clean up after 5-level gray removal (8dc8635874). + (Vertical_Sweep_Span): Be brief. - https://bugs.chromium.org/p/chromium/issues/detail?id=738362 +2018-06-10 Werner Lemberg - * src/base/ftglyph.c (FT_Get_Glyph): Do proper deallocation in case - of error. + [sfnt] Fix compiler warnings. -2017-07-12 Werner Lemberg + * src/sfnt/ttcolr.c (tt_face_load_colr, tt_face_load_colr_layers, + tt_face_colr_blend_layer): Add `NULL' initializers. - [base] Integer overflow. +2018-06-10 Werner Lemberg - Reported as + s/FT_Palette/FT_Palette_Data/, s/palette/palette_data/. - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2573 + * include/freetype/ftcolor.h, include/freetype/internal/tttypes.h, + src/base/ftcolor.c, src/sfnt/sfobjs.c, src/sfnt/ttcolr.c: Updated. - * src/base/ftobjs.c (ft_glyphslot_grid_fit_metrics): Use - FT_PIX_CEIL_LONG and FT_PIX_ROUND_LONG. +2018-06-10 Nikolaus Waxweiler -2017-07-12 Werner Lemberg + CMakeLists: also accept IOS_PLATFORM=SIMULATOR64 - * src/truetype/ttpload.c (tt_face_get_location): Off-by-one typo. + This might be needed to build FreeType for the iOS simulator. See + https://savannah.nongnu.org/bugs/index.php?54048. Patch contributed + by Steve Robinson. - Also improve tracing message. + * CMakeLists.txt: Accept IOS_PLATFORM=SIMULATOR64 - Problem reported as +2018-06-10 Werner Lemberg - https://bugs.chromium.org/p/chromium/issues/detail?id=738919 + Implement `FT_Palette_Get'. -2017-07-07 Werner Lemberg + * src/base/ftcolor.c: New file. - [cff] Integer overflow. + * src/base/Jamefile (_sources), src/base/rules.mk (BASE_SRC), + src/base/ftbase.c: Add `ftcolor.c'. - Reported as +2018-06-10 Werner Lemberg - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2517 + * src/sfnt/ttcolr.c (tt_face_load_colr): Improve overflow checks. - * src/cff/cf2blues.c (cf2_blues_capture): Use SUB_INT32. +2018-06-09 Alexei Podtelezhnikov -2017-07-05 Werner Lemberg + [raster] Deal with pitch sign earlier. - * src/sfnt/ttcmap.c (tt_cmap_unicode_class_rec): Fix warning. + * src/raster/ftraster.c (black_TWorker): Remove unused `traceG', + s/bTarget/bOrigin/. + (Render_Glyph): Set `ras.bOrigin' at the bottom-left corner. + (Vertical_Sweep_Init, {Vertical,Horizontal}_Sweep_{Span,Drop}): + Updated accordingly. -2017-07-05 Werner Lemberg +2018-06-09 Werner Lemberg - * src/truetype/ttgxvar.c (FT_Stream_SeekSet): Fix warning (#51395). + [sfnt] Read `CPAL' version 1 tables. -2017-07-04 Werner Lemberg + * include/freetype/internal.tttypes.h: Include FT_COLOR_H. + (TT_FaceRec): Add `palette' field. - [truetype] Prevent address overflow (#51365). + * src/sfnt/ttcolr.c: Include FT_COLOR_H. + (Cpal): Remove all data covered by the new `palette' field in + `TT_FaceRec'. + (tt_face_load_colr): Updated. + Read `CPAL' version 1 data. + (tt_face_load_colr_layers, tt_face_find_color): Updated. - * src/truetype/ttgxvar.c (FT_Stream_SeekSet): Add guard. + * src/sfnt/sfobjs.c (sfnt_done_face): Free glyph color palette data. -2017-07-03 Alexei Podtelezhnikov +2018-06-07 Alexei Podtelezhnikov - * src/base/ftlcdfil.c (ft_lcd_filter_fir): Improve code. + [base] API for Harmony LCD rendering. -2017-07-03 Werner Lemberg + This introduces `FT_Library_SetLcdGeometry' for setting up arbitrary + LCD subpixel geometry including non-striped patterns. - [truetype] Integer overflow. + * src/base/ftlcdfil.c (FT_Library_SetLcdGeometry): New function. + * include/freetype/ftlcdfil.h: Document it. + * include/freetype/freetype.h: Minor. + * include/freetype/ftchapters.h: Minor. - Reported as +2018-06-06 Werner Lemberg - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2455 + ftcolor.h: Redesign API. - * src/truetype/ttinterp.c (Ins_SCFS): Use SUB_LONG. + While going to implement it I noticed that I need access to most of + the `CPAL' elements; I thus plan to add a `cpal' field to + `TT_FaceRec', which makes most of the previously suggested API + functions obsolete because the fields will be directly accessible. -2017-07-01 Alexei Podtelezhnikov +2018-06-06 Parth Wazurkar - * src/sfnt/sfobjs.c (sfnt_load_face): Ignore No_Unicode_Glyph_Name. + [bdf, pcf] Remove deprecated FT_FACE_FLAG_FAST_GLYPHS flag. -2017-06-28 Ben Wagner + * src/bdf/bdfdrivr.c (BDF_Face_Init): Remove deprecated + FT_FACE_FLAG_FAST_GLYPHS flag. - Avoid Microsoft compiler warnings (#51331). + * src/pcf/pcfread.c (pcf_load_font): Remove deprecated + FT_FACE_FLAG_FAST_GLYPHS flag. - While clang's sanitizer recommends a cast to unsigned for safe - negation (to handle -INT_MIN), both MSVC and Visualc emit warning - C4146 if an unsigned value gets negated. +2018-06-06 Werner Lemberg - * include/freetype/internal/ftcalc.h (NEG_LONG, NEG_INT32), - src/base/ftcalc.c (FT_MOVE_SIGN): Replace negation with a - subtraction. + [smooth, raster] Limit bitmap size (#54019). -2017-06-27 Werner Lemberg + * src/raster/ftraster.c [STANDALONE] (FT_Outline_Get_CBox): Add + function. + [!STANDALONE]: Include FT_OUTLINE_H. + (ft_black_render): Compute CBox and reject glyphs larger than + 0xFFFF x 0xFFFF. - * src/cff/cffparse.c (do_fixed): Fix typo. + * src/smooth/ftgrays.c (gray_raster_render): Reject glyphs larger + than 0xFFFF x 0xFFFF. - Spotted by chris . +2018-06-03 Armin Hasitzka -2017-06-27 Werner Lemberg + * src/smooth/ftgrays.c (gray_convert_glyph): Remove unused variables. - [truetype] Integer overflows. +2018-06-03 Werner Lemberg - Reported as + * src/tools/glnames.py (main): Emit header in `light' comment style. - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2384 - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2391 +2018-06-02 Alexei Podtelezhnikov - * src/base/ftcalc.c (FT_MulDiv, FT_MulDiv_No_Round, FT_DivFix): Use - NEG_LONG. + [smooth] Attempt to mitigate bug #54019. - * src/truetype/ttinterp.c (Ins_SxVTL): Use NEG_LONG. + The robust rendering of estra large glyphs came with unbearable cost. + The old way of bisecting should fail but fail faster. -2017-06-24 Werner Lemberg + * src/smooth/ftgrays.c (gray_convert_glyph): Switch back to bisecting + in y-direction. - [truetype] Integer overflows. +2018-06-02 Werner Lemberg + + * src/truetype/ttinterp.c (Ins_MIRP): Use SUB_LONG; avoid FT_ABS. Reported as - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2364 + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=8706 - * src/truetype/ttinterp.c (Ins_ISECT): Use NEG_LONG. +2018-06-02 Werner Lemberg -2017-06-22 Werner Lemberg + * src/autofit/afwarp.h: Use AF_CONFIG_OPTION_USE_WARPER (#54033). - [cff, truetype] Integer overflows. +2018-05-31 Werner Lemberg - Reported as + * src/raster/ftraster.c (black_TWorker_): Remove `gTarget' field. - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2323 - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2328 + This is no longer used. - * src/cff/cf2blues.c (cf2_blues_capture): Use ADD_INT32 and - SUB_INT32. +2018-05-31 Werner Lemberg - * src/truetype/ttinterp.c (Ins_SDPVTL): Use SUB_LONG and NEG_LONG. + [sfnt] Get colors from `CPAL' table in right order (#54015). -2017-06-21 Alexei Podtelezhnikov + * src/sfnt/ttcolr.c (tt_face_find_color): Fix it. - [sfnt] Synthesize a Unicode charmap if one is missing. +2018-05-30 Werner Lemberg - * src/sfnt/ttcmap.h (tt_cmap_unicode_class_rec): Declare it. - * src/sfnt/ttcmap.c (tt_get_glyph_name, tt_cmap_unicode_init, - tt_cmap_unicode_done, tt_cmap_unicode_char_index, - tt_cmap_unicode_char_next, tt_cmap_unicode_class_rec): Implement - synthetic Unicode charmap class. - (tt_get_cmap_info): Make sure the callback is available. + ftcolor.h: Improve API design, fix typos (#54011, #54014). - * src/sfnt/sfobjs.c (sfnt_load_face) - [FT_CONFIG_OPTION_POSTSCRIPT_NAMES]: If Unicode charmap is missing, - synthesize one. + * include/freetype/ftcolor.h (FT_Palette_Get_Names): Replace with... + (FT_Palette_Get_Name_IDs): ... this function. + (FT_Palette_Get_Entry_Names): Replace with... + (FT_Palette_Get_Entry_Name_IDs): ... this function + s/FT_Palette_Set_Foreground_COlor/FT_Palette_Set_Foreground_Color/. - * include/freetype/config/ftoption.h: Document it. - * devel/ftoption.h: Ditto. +2018-05-30 Armin Hasitzka -2017-06-20 Tony Theodore + Beautify a3cfed5e87232c933bdc64f43e8ebebcfd18b41b. - Fix pkg-config in freetype-config for cross-compiling (#51274). + * src/autofit/afloader.c (af_loader_load_glyph): Move the + initialisationand declaration of variables into the if-block. - * builds/unix/unix-def.in (PKG_CONFIG): New variable. - (freetype-config): Use it in sed expression. +2018-05-30 Armin Hasitzka - * builds/unix/freetype-config.in: s/pkg-config/%PKG_CONFIG%/. + Fix pointer underflow. -2017-06-20 Werner Lemberg + The declaration of `edge2' can be reached with `edge1 == NULL' and + `axis->edges == 0' which results in undefined behaviour. - [cff, truetype] Integer overflows. + * src/autofit/afloader.c (af_loader_load_glyph): Initialise `edge2' + after checking `axis->num_edges > 1'. `edge1 != NULL' can be assumed. - Reported as +2018-05-30 Werner Lemberg - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2300 - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2313 + Various minor color fixes. - * src/cff/cf2hints.c (cf2_hintmap_adjustHints): Use ADD_INT32. + * include/freetype/config/ftheader.h (FT_COLOR_H): New macro. - * src/truetype/ttinterp.c (Ins_ABS): Avoid FT_ABS. + * include/freetype/internal/ftobjs.h (FT_Colr_Internal): Change + type of `load_flags' to `FT_Int32'. -2017-06-17 Alexei Podtelezhnikov + * include/freetype/internal/sfnt.h (TT_Load_Colr_Layer_Func): Change + type of `idx' to `FT_UInt'. + (TT_Blend_Colr_Func): Change type of `color_index' to `FT_UInt'. - [base, smooth] LCD filtering cleanups. + * src/base/ftobjs.c (FT_Render_Glyph_Internal): Change type of + `load_flags' to `FT_Int32'. - * src/base/ftlcdfil.c (ft_lcd_filter_fir, _ft_lcd_filter_legacy): - Clean up, start filtering from the bottom-left origin. + * src/sfnt/ttcolr.c (find_base_glyph_record, + tt_face_load_colr_layers): Change type of `glyph_id' to `FT_UInt'. + (tt_face_find_color, tt_face_colr_blend_layer): Change type of + `color_index' to `FT_UInt'. + Fix signedness and type issues. - * src/smooth/ftsmooth.c (ft_smooth_render_generic): Updated. + * src/sfnt/ttcolr.h: Updated. -2017-06-16 Werner Lemberg +2018-05-25 Nikhil Ramakrishnan - [truetype] Integer overflows. + [docmaker] Fix missing `Defined in (...)' under Windows/Cygwin. - Reported as + This platform uses backslashes for paths, which docmaker didn't + understand correctly. - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2270 - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2276 + * src/tools/docmaker/tohtml.py (HtmlFormatter::blockEnter): Use + `os.path.normpath' to normalize the path for the platform being + used. - * src/truetype/ttinterp.c (Ins_MDRP, _iup_worker_interpolate): Use - ADD_LONG and SUB_LONG. +2018-05-24 Alexei Podtelezhnikov -2017-06-15 Werner Lemberg + [smooth] Formalize Harmony LCD rendering. - [bdf, cff] Integer overflows. + This generalizes magic outline shifts that make Harmony LCD + rendering work in terms of precise two-dimensional RGB subpixel + positions. These coordinates are now set in time of the `smooth' + module initialization and later used to shift a glyph outline for + rendering. FT_RENDER_MODE_LCD and FT_RENDER_MODE_LCD_V use the same + coordinates. The letter, however, rotates them before using. + The LCD bitmap padding is also calculated using these coordinates. - Reported as + * include/freetype/internal/ftobjs.h (FT_LibraryRec): New array field + `lcd_geometry'. + * src/base/ftlcdfil.c (ft_lcd_padding): Reworked. + * src/base/ftobjs.c (ft_glyphslot_preset_bitmap): Updated accordingly. - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2244 - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2261 + * src/smooth/ftsmooth.c [!FT_CONFIG_OPTION_SUBPIXEL_RENDERING] + (ft_smooth_init): Initialize `lcd_geometry'. + (ft_smooth_render_generic): Formalize outline shifts. - * src/bdf/bdfdrivr.c (BDF_Face_Init): Replace calls to FT_ABS with - direct code to avoid value negation. +2018-05-22 Werner Lemberg - * src/cff/cf2blues.c (cf2_blues_capture): Use SUB_INT32 and - ADD_INT32. + [truetype] Reject elements of composites with invalid glyph indices. -2017-06-13 Werner Lemberg + Reported as - * src/winfonts/winfnt.c (FNT_Face_Init): Don't set active encoding. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=8413 - FreeType only sets a default active encoding for Unicode. + * src/truetype/ttgload.c (TT_Load_Composite_Glyph): Implement it. -2017-06-13 Werner Lemberg +2018-05-22 Werner Lemberg - [cff, truetype] Integer overflows. + * src/truetype/ttgload.c (TT_Load_Simple_Glyph): Trace # of points. - Reported as +2018-05-20 Werner Lemberg - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2216 - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2218 + * include/freetype/ftcolor.h: New file. - * src/cff/cf2fixed.h (cf2_fixedAbs): Use NEG_INT32. + This is an interface to the `CPAL' OpenType table. No + implementation yet. - * src/truetype/ttinterp.c (Ins_IP): Use SUB_LONG. +2018-05-18 Alexei Podtelezhnikov -2017-06-11 Werner Lemberg + * include/freetype/internal/ftcalc.h (FT_MSB): Verified `_MSC_VER'. - [cff] Integer overflows. + Actually `_BitScanReverse' is available since VS2005. - Reported as +2018-05-18 Werner Lemberg - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2200 - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2210 + * include/freetype/internal/ftcalc.h (FT_MSB): Use `_MSC_VER' value. - * src/cff/cf2hints.c (cf2_hintmap_insertHint): Use SUB_INT32 and - ADD_INT32. + Older VC versions don't provide `_BitScanReverse'. We test for VC + 2013. - * src/cff/cf2intrp.c (cf2_interpT2CharString) : Use - ADD_INT32. + Reported by John Emmas . -2017-06-10 Werner Lemberg +2018-05-17 Werner Lemberg - [truetype] Fix TT_Set_Var_Design. + s/inline/__inline/ for MSVC. - Reported by Nikolaus Waxweiler . + Reported by John Emmas . - * src/truetype/ttgxvar.c (TT_Set_Var_Design): Correctly handle the - case where we have less input coordinates than axes. + * include/freetype/internal/ftcalc.h (FT_MSB) [_MSC_VER]: Do it. -2017-06-10 Werner Lemberg +2018-05-16 Werner Lemberg - * src/base/ftcalc.c (FT_DivFix): Fix embarrassing typo. + Add function `FT_Get_GlyphLayers' to access `COLR' table data. - Bug introduced 2017-05-28. + * include/freetype/internal/ftobjs.h (FT_Glyph_LayerRec): Move this + structure to... + * include/freetype/freetype.h (FT_Glyph_LayerRec): ... this + header file. + (FT_Glyph_Layer): New typedef. + Update code to use it where appropriate. -2017-06-09 Werner Lemberg + * src/base/ftobjs.c (FT_Get_GlyphLayers): New function. - [cff, truetype] Integer overflows. +2018-05-15 Alexei Podtelezhnikov - Reported as - - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2144 - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2151 - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2153 - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2173 - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2186 - - * src/cff/cf2blues.c (cf2_blues_init): Use SUB_INT32. - - * src/truetype/ttinterp.c (Round_None, Round_To_Grid, - Round_To_Half_Grid, Round_Down_To_Grid, Round_Up_To_Grid, - Round_To_Double_Grid, Round_Super, Round_Super_45): Use ADD_LONG, - SUB_LONG, NEG_LONG, FT_PIX_ROUND_LONG, FT_PIX_CEIL_LONG, - FT_PAD_ROUND_LONG - (Ins_SxVTL, Ins_MIRP): Use SUB_LONG. - (_iup_worker_shift): Use SUB_LONG and ADD_LONG. - -2017-06-09 Werner Lemberg - - Provide more macros for flooring, ceiling, and rounding. - - These versions don't produce run-time errors due to integer - overflow. + [base] Fix mono bitmap presetting (#53896). - * include/freetype/internal/ftobjs.h: Include FT_INTERNAL_CALC_H. - (FT_PAD_ROUND_LONG, FT_PAD_CEIL_LONG, FT_PIX_ROUND_LONG, - FT_PIX_CEIL_LONG): New macros. - (FT_PAD_ROUND_INT32, FT_PAD_CEIL_INT32, FT_PIX_ROUND_INT32, - FT_PIX_CEIL_INT32): New macros. + It is rather fundamental to set monochrome bitmap based on rounded + CBox because the b/w rasterizer turns on pixels when their centers are + inside the glyph outline. The dropout control is unpredictable and can + distort narrow glyphs if the bitmap is too wide. -2017-06-09 Werner Lemberg + Reported by Chris Liddell. - Remove unused macros. + * src/base/ftobjs.c (ft_glyphslot_preset_bitmap): If BBox boundaries + are too close, adjust them before rounding. - * include/freetype/internal/ftcalc.h (ADD_INT, SUB_INT, MUL_INT, - NEG_INT): Deleted. +2018-05-15 Werner Lemberg -2017-06-09 Werner Lemberg + [psaux] Fix compiler warning (#53915). - */*: Remove `OVERFLOW_' prefix. + * src/psaux/psft.c (cf2_freeT1SeacComponent): Do it. - This increases readability. +2018-05-15 Werner Lemberg -2017-06-07 Werner Lemberg + [sfnt] Fix memory leak in handling `COLR' data. - [cff, truetype] Integer overflows. + * src/truetype/ttgload.c (TT_Load_Glyph): Free old `layers' array + before reassigning allocated memory. + Only allocate `color_layers' if we don't have one already. - Reported as - - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2133 - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2137 - - * src/cff/cf2hints.c (cf2_hint_init): Use OVERFLOW_SUB_INT32. - - * src/truetype/ttinterp.c (PROJECT, DUALPROJ): Use - OVERFLOW_SUB_LONG. +2018-05-15 Werner Lemberg -2017-06-06 Werner Lemberg + [sfnt] If `COLR' is present, don't assume that all glyphs use it. - [cff] Integer overflows. + * src/sfnt/ttcolr.c (tt_face_load_colr_layers): Return FT_Err_Ok if + current glyph is not a `COLR' base glyph. - Reported as + * src/truetype/ttgload.c (TT_Load_Glyph): Don't allocate + `color_layers' if there are no color layers. - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2109 - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2110 - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2122 +2018-05-14 Werner Lemberg - * src/cff/cf2blues.c (cf2_blues_init): Use OVERFLOW_SUB_INT32. + * src/base/ftobjs.c (FT_Load_Glyph): Fix signature of `pixel_modes'. - * src/cff/cf2hints.c (cf2_hintmap_map): Synchronize if-else - branches. +2018-05-14 Werner Lemberg -2017-06-05 Werner Lemberg + Provide dummy functions if `TT_CONFIG_OPTION_SFNT_NAMES' is not set. - [cff] Integer overflow. + * src/base/ftsnames.c [!TT_CONFIG_OPTION_SFNT_NAMES]: Implement it. - Reported as +2018-05-13 Werner Lemberg - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2089 + * src/base/ftobjs.c (FT_Load_Glyph): Improve tracing. - * src/cff/cffload.c (cff_blend_doBlend): User OVERFLOW_ADD_INT32. +2018-05-13 Shao Yu Zhang + Werner Lemberg -2017-06-04 Werner Lemberg + [sfnt] Preliminary support of coloured layer outlines (#44689). - [cff, truetype] Integer overflows. + This commit enables OpenType's COLR/CPAL table handling; a typical + application are color emojis that can be scaled to any size. - Reported as + If the color palette does not exist or is invalid, the rendering + step rasterizes the outline instead. The current implementation + assumes that the foreground is black. - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2075 - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2088 + Enable this by defining option TT_CONFIG_OPTION_COLOR_LAYERS. - * src/cff/cf2font.c (cf2_font_setup): Use OVERFLOW_MUL_INT32. + There are still some issues with metrics; additionally, an API to + fetch color layers is missing. - * src/truetype/ttinterp.c (Ins_ISECT): Use OVERFLOW_MUL_LONG, - OVERFLOW_ADD_LONG, and OVERFLOW_SUB_LONG. + * devel/ftoption.h, include/freetype/config/ftoption.h + (TT_CONFIG_OPTION_COLOR_LAYERS): New macro. -2017-06-03 Werner Lemberg + * include/freetype/internal/ftobjs.h (FT_Glyph_LayerRec, + FT_Colr_InternalRec): New structures. + (FT_Slot_InternalRec): Add `color_layers' field. - [base, cff, truetype] Integer overflows. + * include/freetype/internal/sfnt.h (TT_Load_Colr_Layer_Func, + TT_Blend_Colr_Func): New function types. + (SFNT_Interface): Add `load_colr', `free_colr', `load_colr_layer', + and `colr_blend' fields. - Reported as + * include/freetype/internal/tttypes.h (TT_FaceRec): Add + `colr_and_cpal' field. - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2060 - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2062 - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2063 - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2068 + * include/freetype/internal/tttags. (TTAG_COLR, TTAG_CPAL): New + macros. - * src/base/ftobjs.c (ft_glyphslot_grid_fit_metrics): Use - OVERFLOW_ADD_LONG and OVERFLOW_SUB_LONG. + * src/sfnt/ttcolr.c, src/sfnt/ttcolr.h: New files. - * src/cff/cf2blues.c (cf2_blues_capture), src/cff/cf2hints.c - (cf2_hintmap_adjustHints): Use OVERFLOW_SUB_INT32. + * src/base/ftobjs.c (ft_glyphslot_done, FT_Render_Glyph_Internal): + Handle glyph color layers. - * src/truetype/ttgload.c (compute_glyph_metrics): User - OVERFLOW_SUB_LONG. + * src/sfnt/Jamfile (_sources), src/sfnt/rules.mk (SFNT_DRV_SRC): Add + `ttcolr.c'. - * src/truetype/ttinterp.c (Direct_Move, Direct_Move_Orig, - Direct_Move_X, Direct_Move_Y, Direct_Move_Orig_X, - Direct_Move_Orig_Y, Move_Zp2_Point, Ins_MSIRP): Use - OVERFLOW_ADD_LONG and OVERFLOW_SUB_LONG. + * src/sfnt/sfdriver.c: Include `ttcolr.h'. + (PUT_COLOR_LAYERS): New macro. + Update call to `FT_DEFINE_SFNT_INTERFACE'. -2017-06-03 Werner Lemberg + * src/sfnt/sfnt.c: Include `ttcolr.c'. - * builds/unix/freetype-config.in: Fix pkg-config test (#51162). + * src/sfnt/sfobjs.c (sfnt_load_face): Load `COLR' and `CPAL' tables. + (sfnt_done_face): Updated. - Patch directly taken from bug report. + * src/truetype/ttgload.c (TT_Load_Glyph): Handle color layers. -2017-06-03 Werner Lemberg +2018-05-12 Arkady Shapkin - [bdf] Synchronize sanity checks with pcf driver. + Use MS VC++'s _BitScanReverse to calculate MSB (patch #9636). - Reported as + * include/freetype/internal/ftcalc.h (FT_MSB) [_MSC_VER]: Implement + it. - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2054 - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2058 +2018-05-10 Alan Coopersmith - * src/bdf/bdfdrivr.c (BDF_Face_Init): Check font ascent and descent. - Check AVERAGE_WIDTH, POINT_SIZE, PIXEL_SIZE, RESOLUTION_X, and - RESOLUTION_Y properties. + Fix DLL compilation on Solaris. -2017-06-03 Werner Lemberg + AC_COMPILE_IFELSE only tries to compile a `*.c' to a `*.o'. The + Solaris Studio 12.1 through 12.5 compilers see the + `-fvisibility=hidden' flag, but ignore it with a warning of: - [cff, truetype] Integer overflows. + cc: Warning: Option -fvisibility=hidden passed to ld, + if ld is invoked, ignored otherwise - Reported as + AC_LINK_IFELSE does the compile and then tries to link the result, + at which point the Solaris linker will issue an error: - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2047 - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2057 + ld: fatal: option '-fvisibility=hidden' is incompatible with + building a dynamic executable - * src/cff/cf2hints.c (cf2_hintmap_map): Use OVERFLOW_SUB_INT32. + If we don't use AC_LINK_IFELSE to catch the error, then configure + will fail further tests which attempt to link, such as those testing + dependencies like `libbz2'. - * src/truetype/ttinterp.c (Ins_ADD): Use OVERFLOW_ADD_LONG. - (Ins_SUB): Use OVERFLOW_SUB_LONG. - (Ins_NEG): Use NEG_LONG. + Also, don't try adding `-fvisibility' if we have already added + `-xldscope', just use one of them, since Sun Studio 12 and earlier + compilers only issue a warning, and don't try passing through to the + linker to generate an error, so AC_LINK_IFELSE doesn't catch them. -2017-06-03 Werner Lemberg + Tested on Solaris 11.4 beta with compiler versions: - ftcalc.h: Avoid left-shift of negative numbers. + Sun Studio 8 (Sun C 5.5) + Sun Studio 10 (Sun C 5.7) + Sun Studio 11 (Sun C 5.8) + Sun Studio 12 (Sun C 5.9) + Sun Studio 12.1 (Sun C 5.10) + Oracle Solaris Studio 12.2 (Sun C 5.11) + Oracle Solaris Studio 12.3 (Sun C 5.12) + Oracle Solaris Studio 12.4 (Sun C 5.13) + Oracle Developer Studio 12.5 (Sun C 5.14) + Oracle Developer Studio 12.6 (Sun C 5.15) + gcc 5.5.0 + gcc 7.3.0 - Reported as + and verified the libfreetype.so.6 generated by each of those + compilers exported the same set of symbols. - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2055 + * builds/unix/configure.raw: Implement it. - * include/freetype/internal/ftcalc.h (INT_TO_F26DOT6, - INT_TO_F2DOT14, INT_TO_FIXED, F2DOT14_TO_FIXED): Use multiplication. +2018-05-08 Werner Lemberg -2017-06-02 Werner Lemberg + [autofit] Avoid potential SEGV if running out of memory. - [cff] Even more integer overflows. + Problem reported by Shailesh Mistry . - Reported as + * src/autofit/afshaper.c (af_shaper_buf_create, + af_shaper_buf_destroy) [!FT_CONFIG_OPTION_USE_HARFBUZZ]: Don't + allocate and free a four-byte buffer. Instead, make those functions + no-ops; the calling functions will provide a pointer to a buffer + instead. - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2046 + * src/autofit/afcjk.c (af_cjk_metrics_init_widths, + af_cjk_metrics_init_blues, af_cjk_metrics_check_digits), + src/autofit/aflatin.c (af_latin_metrics_init_widths, + af_latin_metrics_init_blues, af_latin_metrics_check_digits) + [!FT_CONFIG_OPTION_USE_HARFBUZZ]: Use pointer to local variable for + `shaper_buf'. - * src/cff/cf2intrp.c (cf2_doStems, cf2_interpT2CharString): Use - OVERFLOW_ADD_INT32. +2018-05-07 Nikolaus Waxweiler -2017-06-02 Werner Lemberg + [cmake] Allow using project as subfolder in other project. - [cff] More integer overflows. + * CMakeLists.txt: Test for CMake build directory being different + from source directory. Provide other parts of the build system + access the full include directory. - Reported as +2018-05-07 Werner Lemberg - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2032 + [build] Suppress configure's `nothing to be done' message. - * src/cff/cf2blues.c (cf2_blues_init): Use OVERFLOW_SUB_INT32. + This is due to calling the configure script via `make' (within the + top-level `configure' wrapper script). The same can happen for all + other secondary make targets that are used to only modify the + primary one, e.g., `make setup devel'. -2017-06-02 Werner Lemberg + * builds/dos/detect.mk (emx, turboc, watcom, borlandc, borlandc16), + builds/os2/detect (visualage, watcom, borlandc, devel), + builds/unix/detect.mk (devel, lcc, unix), builds/windows/detect.mk + (visualc, watcom, visualage, lcc, mingw32, bcc32, devel-bcc, + devel-gcc): Use no-op recipe. - [bdf] Don't left-shift negative numbers. +2018-05-04 suzuki toshiya - Reported as + Support symbol visibility features of Sun / Oracle C compilers. - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2031 + Reported by Kiyoshi Kanazawa: + https://lists.gnu.org/archive/html/freetype-devel/2018-05/msg00008.html + Thanks to the suggestions by Alexei and Alan Coopersmith. - * src/bdf/bdfdrivr.c (BDF_Face_Init): Use multiplication. + * builds/unix/configure.raw: Check if "-xldscope=hidden" is + accepted, and if so, it is added to CFLAGS. This is the option + making Sun / Oracle C compilers hide the symbols from global + scope. + * include/freetype/config/ftconfig.h: Use "__global" prefix + for FT_EXPORT() macro, if SunPro C is newer than Sun ONE + Studio 8 (2003). + * builds/unix/ftconfig.in: Ditto. + * builds/vms/ftconfig.h: Ditto. -2017-06-02 Werner Lemberg +2018-05-02 Nikolaus Waxweiler - [bdf] Fix integer scanning routines. + Unbreak CMake Windows installation - Reported as + * CMakeLists.txt: Generate ftconfig.h on non-UNIX. - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2029 +2018-05-02 Werner Lemberg - * src/bdf/bdflib.c (_bdf_atoul, _bdf_atol, _bdf_atous, _bdf_atos): - Stop scanning if result would overflow. + Remove FT_CONFIG_OPTION_PIC and related code. -2017-06-02 Werner Lemberg + */* [FT_CONFIG_OPTION_PIC]: Remove all code guarded by this + preprocessor symbol. - [cff] Fix integer overflows. + */*: Replace `XXX_GET' macros (which could be either a function in + PIC mode or an array in non-PIC mode) with `xxx' arrays. - Reported as + * include/freetype/internal/ftpic.h, src/autofit/afpic.c, + src/autofit/afpic.h, src/base/basepic.c, src/base/basepic.h, + src/base/ftpic.c, src/cff/cffpic.c, src/cff/cffpic.h, + src/pshinter/pshpic.c, src/pshinter/pshpic.h, src/psnames/pspic.c, + src/psnames/pspic.h, src/raster/rastpic.c, src/raster/rastpic.h, + src/sfnt/sfntpic.c, src/sfnt/sfntpic.h, src/smooth/ftspic.c, + src/smooth/ftspic.h, src/truetype/ttpic.c, src/truetype/ttpic.h: + Removed. - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2027 - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2028 +2018-05-01 Werner Lemberg - * src/cff/cf2hints.c (cf2_hintmap_insertHint), src/cff/cf2intrp.c - (cf2_doFlex): Use OVERFLOW_ADD_INT32 and OVERFLOW_SUB_INT32. + * Version 2.9.1 released. + ========================= -2017-06-01 Werner Lemberg - [smooth] Some 32bit integer overflow run-time errors. + Tag sources with `VER-2-9-1'. - * src/smooth/ftgrays.c [STANDALONE] (OVERFLOW_ADD_LONG, - OVERFLOW_SUB_LONG, OVERFLOW_MUL_LONG, NEG_LONG): New macros. - [!STANDALONE]: Include FT_INTERNAL_CALC_H. - (gray_render_cubic): Use those macros where appropriate. + * docs/VERSION.TXT: Add entry for version 2.9.1. + * docs/CHANGES: Updated. -2017-06-01 Werner Lemberg + * README, Jamfile (RefDoc), builds/windows/vc2005/freetype.vcproj, + src/base/ftver.rc, builds/windows/vc2005/index.html, + builds/windows/vc2008/freetype.vcproj, + builds/windows/vc2008/index.html, + builds/windows/vc2010/freetype.vcxproj, + builds/windows/vc2010/index.html, + builds/windows/visualc/freetype.dsp, + builds/windows/visualc/freetype.vcproj, + builds/windows/visualc/index.html, + builds/windows/visualce/freetype.dsp, + builds/windows/visualce/freetype.vcproj, + builds/windows/visualce/index.html, + builds/wince/vc2005-ce/freetype.vcproj, + builds/wince/vc2005-ce/index.html, + builds/wince/vc2008-ce/freetype.vcproj, + builds/wince/vc2008-ce/index.html: s/2.9/2.9.1/, s/29/291/. - * src/base/ftglyph.c (FT_Get_Glyph): Check `slot->advance'. + * include/freetype/freetype.h (FREETYPE_PATCH): Set to 1. -2017-06-01 Werner Lemberg + * builds/unix/configure.raw (version_info): Set to 22:1:16. + * CMakeLists.txt (VERSION_PATCH): Set to 1. - [psaux] 32bit integer overflow tun-time errors (#46149). + * include/freetype/ftgasp.h: Use FT_BEGIN_HEADER and FT_END_HEADER. - * src/psaux/t1decode.c (t1_decoder_parse_charstrings): Use - OVERFLOW_ADD_LONG and OVERFLOW_SUB_LONG where appropriate. +2018-04-26 Werner Lemberg -2017-06-01 Werner Lemberg + Another fix for handling invalid format 2 cmaps. - * src/truetype/ttinterp.c (TT_RunIns): Adjust loop counter again. + Sigh. - Problem reported by Marek Kašík . + Reported as - The problematic font that exceeds the old limit is Padauk-Bold, - version 3.002, containing bytecode generated by a buggy version of - ttfautohint. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=8003 -2017-05-31 Werner Lemberg + * src/sfnt/ttcmap.c (tt_cmap2_char_next): Adjust condition to avoid + an endless loop. - [cff] 32bit integer overflow run-time errors 2/2 (#46149). +2018-04-24 Ben Wagner - This commit handles the new engine. + [base] Avoid undefined behaviour in lcd filtering code (#53727). - * include/freetype/internal/ftcalc.h (OVERFLOW_ADD_INT32, - OVERFLOW_SUB_INT32, OVERFLOW_MUL_INT32, NEG_INT, NEG_LONG, - NEG_INT32): New macros. + * src/base/ftlcdfil.c (ft_lcd_filter_fir, _ft_lcd_filter_legacy): + Ensure `height > 0'. - * src/cff/cf2ft.c (cf2_getScaleAndHintFlag): Use OVERFLOW_ADD_INT32. +2018-04-22 Werner Lemberg - * src/cff/cf2hints.c (cf2_getWindingMomentum, cf2_hint_init, - cf2_hintmap_map, cf2_glyphpath_hintPoint, - cf2_glyphpath_computeIntersection, cf2_glyphpath_computeOffset, - cf2_glyphpath_lineTo, cf2_glyphpath_curveTo): Use - OVERFLOW_ADD_INT32, OVERFLOW_SUB_INT32, OVERFLOW_MUL_INT32, and - NEG_INT32 where appropriate. + * src/base/ftoutln.c (FT_Outline_Decompose): Improve error tracing. - * src/cff/cf2intrp.c (cf2_doFlex, cf2_doBlend, - cf2_interpT2CharString): Ditto. - Also add some other code where needed to avoid overflow. +2018-04-22 Alexei Podtelezhnikov -2017-05-30 Werner Lemberg + [base] Fix bitmap emboldening. - [cff] 32bit integer overflow run-time errors 1/2 (#46149). + Bug introduced after release 2.8. - This commit handles the old engine. + * src/base/ftbitmap.c (ft_bitmap_assure_buffer): We use + `FT_QALLOC_MULT', which doesn't zero out the buffer. Adjust the + bitmap copying code to take care of this fact. - * src/cff/cffgload.c: Include FT_INTERNAL_CALC_H. - (cff_decoder_parse_charstrings): Use OVERFLOW_ADD_LONG and - OVERFLOW_SUB_LONG where needed. +2018-04-22 Werner Lemberg - * src/cff/cffparse.c: Include FT_INTERNAL_CALC_H. - (power_ten_limits): New static array. - (do_fixed): Use it to prevent multiplication overflow. - (cff_parser_run): Use OVERFLOW_ADD_LONG. + Another fix for handling invalid format 2 cmaps. -2017-05-30 Werner Lemberg + The previous commit was incomplete. - [psaux] Correctly handle sequences of multiple number signs. + Reported as - * src/psaux/psconv.c (PS_Conv_Strtol, PS_Conv_ToFixed): Return zero - if we encounter more than a single sign. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=7928 -2017-05-29 Werner Lemberg + * src/sfnt/ttcmap.c (tt_cmap2_char_next): Adjust condition to avoid + an endless loop. - [pcf] 32bit integer overflow run-time errors (#46149). +2018-04-19 Werner Lemberg + This will be part of the forthcoming Unicode 11.0. - Handle some integer overflow run-time errors (#46149, #48979). + * src/autofit/afblue.dat: Add blue zone data for Mtavruli. + * src/autofit/afblue.c, src/autofit/afblue.h: Regenerated. - This commit (mainly for 32bit CPUs) is the first of a series of - similar commits to handle known integer overflows. Basically, all - of them are harmless, since they affect rendering of glyphs only, - not posing security threats. It is expected that fuzzying will show - up more overflows, to be fixed in due course. + * src/autofit/afscript.h: Add Mtavruli standard character. - The idea is to mark places where overflows can occur, using macros - that simply cast to unsigned integers, because overflow arithmetic - is well defined in this case. Doing so suppresses run-time errors - of sanitizers without adding computational overhead. +2018-04-18 Werner Lemberg - * include/freetype/internal/ftcalc.h (OVERFLOW_ADD_INT, - OVERFLOW_SUB_INT, OVERFLOW_MUL_INT, OVERFLOW_ADD_LONG, - OVERFLOW_SUB_LONG, OVERFLOW_MUL_LONG): New macros. + Fix handling of invalid format 2 cmaps. - * src/base/ftcalc.c (FT_RoundFix, FT_CeilFix, FT_Matrix_Multiply, - FT_Matrix_Multiply_Scaled, FT_Vector_Transform_Scaled, - ft_corner_orientation): Use new macros. + The problem was introduced after the last release. - * src/base/ftoutln.c (FT_Outline_Get_Orientation): Use new macros. + Reported as -2017-05-28 Werner Lemberg + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=7828 - * include/freetype/internal/ftcalc.h (FLOAT_TO_FIXED): Remove. + * src/sfnt/ttcmap.c (tt_cmap2_char_next): Avoid endless loop. - This macro is not used. +2018-04-17 Werner Lemberg -2017-05-28 Werner Lemberg + [truetype] Integer overflow issues. - [cff] s/cf2_floatToFixed/cf2_doubleToFixed/. + Reported as - The new name better describes what the macro actually does; - additionally, we don't need a trailing `f' for literals (there was - only a single such instance in the code, but this caused a clang - warning because the macro itself uses `double' literals). + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=7739 - * src/cff/cf2blues.c, src/cff/cf2blues.h, src/cff/cf2fixed.h, - src/cff/cf2font.c, src/cff/cf2hints.c: Updated. + * src/truetype/ttinterp.c (Ins_CEILING): Use FT_PIX_CEIL_LONG. -2017-05-28 Werner Lemberg +2018-04-16 Werner Lemberg - Fix negation of INT_MIN and LONG_MIN (#46149). + [truetype] Integer overflow issues. - * src/base/ftcalc.c (FT_MOVE_SIGN): Add argument to pass unsigned - value, to be used as the result. - (FT_MulDiv, FT_MulDiv_No_Round, FT_DivFix, FT_MulFix, - FT_Vector_NormLen): Updated. + Reported as -2017-05-27 Werner Lemberg + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=7718 - [truetype] Fix handling of design coordinates (#51127). + * src/truetype/ttinterp.c (Ins_MIRP): Use ADD_LONG. - * src/truetype/ttgxvar.c (tt_set_mm_blend): Compute all design - coordinates if we have to create the `blends->coord' array. - (TT_Get_MM_Blend, TT_Get_Var_Design): Select default instance - coordinates if no instance is selected yet. +2018-04-15 Alexei Podtelezhnikov -2017-05-24 Werner Lemberg + [build] Use `info' function of make 3.81. - [bdf, pcf] Support ISO646.1991-IRV character encoding (aka ASCII). + * configure, docs/INSTALL, docs/INSTALL.CROSS, docs/INSTALL.GNU, + docs/INSTALL.UNIX, docs/MAKEPP: Bump make version requirements. - Problem reported by Marek Kašík , cf. + * builds/detect.mk (std_setup): Replace `echo' with `info'. + (dos_setup): Removed. + * builds/unix/install.mk, builds/modules.mk, builds/dos/detect.mk, + builds/windows/detect.mk, builds/os2/detect.mk: Updated. + * builds/newline: No longer needed. - https://bugzilla.redhat.com/show_bug.cgi?id=1451795 +2018-04-15 Werner Lemberg - * src/bdf/bdfdrivr.c (BDF_Face_Init), src/pcf/pcfdrivr.c - (PCF_Face_Init): Implement it. + [truetype]: Limit `SLOOP' bytecode argument to 16 bits. -2017-05-20 Nikolaus Waxweiler + This fixes - [truetype] Always use interpreter v35 for B/W rendering (#51051). + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=7707 - * src/truetype/ttgload.c (tt_loader_init) - [TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL]: Adjust - `subpixel_hinting_lean', `grayscale_cleartype', and - `vertical_lcd_lean' accordingly. + * src/truetype/ttinterp.c (Ins_SLOOP): Do it. - * src/truetype/ttinterp.c (Ins_GETINFO): Updated. - (TT_RunIns): Update `backward_compatibility' flag. +2018-04-14 Werner Lemberg -2017-05-20 Alexei Podtelezhnikov + [truetype] Integer overflow issues. - [smooth] Implement minimal dynamic padding for LCD filtering. + Reported as - Extra bitmap padding for LCD filtering depends on the filter. The - default 5-tap filter needs 2 extra subpixels. The light 3-tap filter - needs only 1 extra subpixel. This space could be already available - due to rounding. In order to optimize the padding, we now expand - CBox for the given filter weights before rounding. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=7652 - This change breaks current Skia (and Firefox). + * src/truetype/ttinterp.c (Ins_MDAP): Use SUB_LONG. - * include/freetype/internal/ftobjs.h (FT_LibraryRec) - [FT_CONFIG_OPTION_SUBPIXEL_RENDERING]: Remove `lcd_extra' field. +2018-04-14 Werner Lemberg - * src/base/ftlcdfil.c (FT_Library_SetLcdFilterWeights, - FT_Library_SetLcdFilter): Remove `lcd_extra' initializations. + [autofit] Update to Unicode 11.0.0. - * src/smooth/ftsmooth.c (ft_smooth_render_generic): Implement dymanic - LCD padding. + But no support new scripts (volunteers welcomed). -2017-05-15 Werner Lemberg + * src/autofit/afranges.c (af_arab_nonbase_uniranges, + af_beng_nonbase_uniranges, af_cakm_nonbase_uniranges, + af_deva_nonbase_uniranges, af_geor_uniranges, + af_gujr_nonbase_uniranges, af_mlym_nonbase_uniranges, + af_nkoo_nonbase_uniranges, af_telu_nonbase_uniranges, + af_hani_uniranges): Add new data. - [sfnt] Return proper scaling values for SBIX bitmaps. +2018-04-10 Nikolaus Waxweiler - Problem reported by Hin-Tak Leung . + * CMakeLists.txt, builds/cmake/FindHarfBuzz.cmake: Extensive + modernization measures. - * src/sfnt/ttsbit.c (tt_face_load_strike_metrics): Implement it. + This brings up the minimum required CMake version to 2.8.12. -2017-05-15 Werner Lemberg + The installation paths follow the GNU defaults now, e.g. installing on a + 64 bit host will place binaries into the lib64/ folder on e.g. Fedora. - [truetype] Fix error handling for embedded bitmaps. + Symbols are hidden by default (e.g. `-fvisibility=hidden' on GCC). - Problem reported by Hin-Tak Leung . + CMake will no longer look for a C++ compiler. - * src/truetype/ttgload.c (TT_Load_Glyph) - [TT_CONFIG_OPTION_EMBEDDED_BITMAPS]: Handle error if font is not - scalable. + Library and .so version now match the Autotools build. -2017-05-15 Alexei Podtelezhnikov + Comments in the build file and informational messages now use platform + agnostic example commands. - [autofit] Make autohint warping NORMAL option. + ftoption.h and ftconfig.h are written directly without a redundant `-new' + copy. - This moves warping option from LIGHT to NORMAL mode. This makes LIGHT - truly void of hinting in x-direction, with left side bearing never - changed and right side bearing only altered by advance rounding. - Therefore, LIGHT is now ready to return fractional advance. As a - NORMAL option, warping substitutes normal hinting. + External dependencies are expressed as option()s and will turn up as such + in cmake-gui. - * src/autofit/afcjk.c (af_cjk_hints_apply): Updated. - * src/autofit/aflatin.c (af_latin_hints_apply): Updated. - * src/autofit/aflatin2.c (af_latin2_hints_apply): Updated. + Internal: Properties such as dependencies and include directories are now + privately set on the freetype library instead of globally. - * src/autofit/afloader.c (af_loader_load_glyph): Handle warping - phantom points as normal. + The CPack definitions have been cleaned up, the `make dist' has been + removed. Source packages generated with CPack don't contain Autotools + files and aren't used by the maintainers anyway. -2017-05-14 Werner Lemberg + On Windows, src/base/ftver.rc is compiled to decorate the library with + version and copyright information. - Remove remnants of raster pool. + A pkg-config file is now generated and installed. - * include/freetype/internal/ftobjs.h (FT_LibraryRec): Remove - `raster_pool' and `raster_pool_size' fields. +2018-04-09 Werner Lemberg - * src/base/ftobjs.c (FT_New_Library), src/raster/ftrend1.c - (ft_raster1_init), src/smooth/ftsmooth.c (ft_smooth_init): Updated. + [truetype] Integer overflow issues. -2017-05-13 Werner Lemberg + Reported as - * Version 2.8 released. - ======================= + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=7453 + * src/truetype/ttinterp.c (Round_Super, Round_Super_45): Use + ADD_LONG and SUB_LONG. - Tag sources with `VER-2-8'. +2018-04-06 Alexei Podtelezhnikov - * docs/VERSION.TXT: Add entry for version 2.8. - * docs/CHANGES: Updated. + [windows, wince] Clean up legacy project files. - * README, Jamfile (RefDoc), builds/windows/vc2005/freetype.vcproj, - builds/windows/vc2005/index.html, + * builds/wince/vc2005-ce/freetype.vcproj, + builds/wince/vc2008-ce/freetype.vcproj, + builds/windows/vc2005/freetype.vcproj, builds/windows/vc2008/freetype.vcproj, - builds/windows/vc2008/index.html, - builds/windows/vc2010/freetype.vcxproj, - builds/windows/vc2010/index.html, - builds/windows/visualc/freetype.dsp, - builds/windows/visualc/freetype.vcproj, - builds/windows/visualc/index.html, - builds/windows/visualce/freetype.dsp, builds/windows/visualce/freetype.vcproj, - builds/windows/visualce/index.html, - builds/wince/vc2005-ce/freetype.vcproj, - builds/wince/vc2005-ce/index.html, - builds/wince/vc2008-ce/freetype.vcproj, - builds/wince/vc2008-ce/index.html: s/2.7.1/2.8/, s/271/28/. + builds/windows/visualce/freetype.dsp, + builds/windows/visualc/freetype.vcproj, + builds/windows/visualc/freetype.dsp: Remove per-file compile flags. - * include/freetype/freetype.h (FREETYPE_MINOR): Set to 8. - (FREETYPE_PATCH): Set to 0. +2018-04-04 Werner Lemberg - * builds/unix/configure.raw (version_info): Set to 20:0:14. - * CMakeLists.txt (VERSION_MINOR): Set to 8. - (VERSION_PATCH): Set to 0. + [cff, type1] Sanitize `BlueFuzz' and `BlueShift'. -2017-05-12 Hin-Tak Leung + Reported as - Fix `FT_UINT_TO_POINTER' macro for Windows. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=7371 - * builds/unix/ftconfig.in, builds/vms/ftconfig.h, - include/freetype/config/ftconfig.h (FT_UINT_TO_POINTER) [_WIN64]: - Fix definition. + * src/cff/cffload.c (cff_load_private_dict): Sanitize + `priv->blue_shift' and `priv->blue_fuzz' to avoid overflows later + on. -2017-05-11 Sascha Brawer - Werner Lemberg - * src/autofit/afblue.dat: Add blue zone data for Chakma. - * src/autofit/afblue.c, src/autofit/afblue.h: Regenerated. + * src/truetype/ttobjs.c (trick_names): Add 3 tricky fonts (#53554), + `DFHei-Md-HK-BF', `DFKaiShu-Md-HK-BF' and `DFMing-Bd-HK-BF'. + (tt_check_trickyness_sfnt_ids): Add checksums for 3 tricky fonts + in above. - * src/autofit/afscript.h: Add Chakma standard character. +2018-04-01 Werner Lemberg - * src/autofit/afranges.c, src/autofit/afstyles.h: Add Chakma data. + * builds/toplevel.mk (work): Use $(SEP). -2017-05-10 Sascha Brawer - Werner Lemberg . - * src/autofit/afblue.dat: Add blue zone data for Kayah Li. - * src/autofit/afblue.c, src/autofit/afblue.h: Regenerated. +2018-03-30 Werner Lemberg - * src/autofit/afscript.h: Add Kayah Li standard character. + [truetype] Fix memory leak (only if tracing is on). - * src/autofit/afranges.c, src/autofit/afstyles.h: Add Kayah Li data. + * src/truetype/ttgxvar.c (TT_Get_MM_Var) [FT_DEBUG_LEVEL_TRACE}: Fix + it. -2017-05-10 Sascha Brawer - Werner Lemberg - [autofit] Add support for Bamum script. + [sfnt] Correctly handle missing bitmaps in sbix format (#53404). - * src/autofit/afblue.dat: Add blue zone data for Bamum. - * src/autofit/afblue.c, src/autofit/afblue.h: Regenerated. + * src/sfnt/ttfsbit.c (tt_face_load_sbix_image): Fix return value. - * src/autofit/afscript.h: Add Bamum standard character. +2018-03-23 Ben Wagner - * src/autofit/afranges.c, src/autofit/afstyles.h: Add Bamum data. + [truetype] Fix advance of empty glyphs in bitmap fonts (#53393). -2017-05-10 Sascha Brawer - Werner Lemberg - * src/autofit/afblue.dat: Add blue zone data for Saurashtra. - * src/autofit/afblue.c, src/autofit/afblue.h: Regenerated. + Remove `ftlcdfil.c' and `ftfntfmt.c' from build files (#53415). - * src/autofit/afscript.h: Add Saurashtra standard character. + builds/amiga/makefile, builds/amiga/makefile.os4, + builds/amiga/smakefile, builds/mac/FreeType.m68k_cfm.make.txt, + builds/mac/FreeType.m68k_far.make.txt, + builds/mac/FreeType.ppc_carbon.make.txt, + builds/mac/FreeType.ppc_classic.make.txt, + builds/symbian/freetype.mmp, builds/wince/vc2005-ce/freetype.vcproj, + builds/wince/vc2008-ce/freetype.vcproj, + builds/windows/vc2005/freetype.vcproj, + builds/windows/vc2008/freetype.vcproj, + builds/windows/vc2010/freetype.vcxproj, + builds/windows/vc2010/freetype.vcxproj.filters, + builds/windows/visualc/freetype.dsp, + builds/windows/visualc/freetype.vcproj, + builds/windows/visualce/freetype.dsp, + builds/windows/visualce/freetype.vcproj, vms_make.com: Do it. - * src/autofit/afranges.c, src/autofit/afstyles.h: Add Saurashtra - data. +2018-03-13 Werner Lemberg -2017-05-10 Sascha Brawer - Werner Lemberg - * src/autofit/afblue.dat: Add blue zone data for Buhid. - * src/autofit/afblue.c, src/autofit/afblue.h: Regenerated. + Fix cmap format 2 handling (#53320). - * src/autofit/afscript.h: Add Buhid standard character. + The patch introduced for #52646 was not correct. - * src/autofit/afranges.c, src/autofit/afstyles.h: Add Buhid data. + * src/sfnt/ttcmap.c (tt_cmap2_char_next): Adjust condition. -2017-05-08 Sascha Brawer - Werner Lemberg - [autofit] Add support for Shavian script. + * CMakeLists.txt (BASE_SRCS): Update to changes from 2018-03-05. - * src/autofit/afblue.dat: Add blue zone data for Shavian. - * src/autofit/afblue.c, src/autofit/afblue.h: Regenerated. +2018-03-09 Chun-wei Fan - * src/autofit/afscript.h: Add Shavian standard character. + * CMakeLists.txt [win32]: Allow MSVC DLL builds (#53287). - * src/autofit/afranges.c, src/autofit/afstyles.h: Add Shavian data. + Do not limit DLL builds to MinGW, since we already have + `__declspec(dllexport)' directives in `ftconfig.h'. + Also suppress more warnings for POSIX functions. -2017-05-08 Sascha Brawer - Werner Lemberg - [autofit] Add support for Vai script. + Make installation of `freetype-config' optional (#53093). - * src/autofit/afblue.dat: Add blue zone data for Vai. - * src/autofit/afblue.c, src/autofit/afblue.h: Regenerated. + * builds/unix/configure.raw: Add option `--enable-freetype-config' + and set `INSTALL_FT2_CONFIG'. + * builds/unix/unix-def.in (INSTALL_FT2_CONFIG): Define. + * builds/unix/install.mk (install): Handle it. - * src/autofit/afscript.h: Add Vai standard character. +2018-03-05 Werner Lemberg - * src/autofit/afranges.c, src/autofit/afstyles.h: Add Vai data. + Make `ftlcdfil.c' part of the `base' module. -2017-05-08 Sascha Brawer - Werner Lemberg . - * src/autofit/afblue.dat: Add blue zone data for Osmanya. - * src/autofit/afblue.c, src/autofit/afblue.h: Regenerated. + * modules.cfg (BASE_EXTENSIONS): Don't include `ftlcdfil.c'. - * src/autofit/afscript.h: Add Osmanya standard character. + * src/base/ftbase.c: Include `ftlcdfil.c'. + * src/base/rules.mk (BASE_SRC): Add `ftlcdfil.c'. + * src/base/Jamfile (_sources): Adjusted. - * src/autofit/afranges.c, src/autofit/afstyles.h: Add Osmanya data. + * docs/INSTALL.ANY: Updated. -2017-05-08 Sascha Brawer - Werner Lemberg - [autofit] Add support for Coptic script. + Make `ftfntfmt.c' part of the `base' module. - * src/autofit/afblue.dat: Add blue zone data for Coptic. - * src/autofit/afblue.c, src/autofit/afblue.h: Regenerated. + `ftobjs.c' needs `FT_Get_Font_Format'. - * src/autofit/afscript.h: Add Coptic standard character. + Problem reported by duhuanpeng <548708880@qq.com>. - * src/autofit/afranges.c, src/autofit/afstyles.h: Add Coptic data. + * modules.cfg (BASE_EXTENSIONS): Don't include `ftfntfmt.c'. -2017-05-08 Sascha Brawer - Werner Lemberg - * src/autofit/afscript.h: Add Carian standard character. + * src/truetype/ttinterp.c (TT_RunIns): Fix tracing arguments. - * src/autofit/afranges.c, src/autofit/afstyles.h: Add Carian data. +2018-02-23 Werner Lemberg -2017-05-07 Werner Lemberg + * builds/unix/configure.raw: Need HarfBuzz 1.3.0 or newer. - [truetype] Add tricky font `DFGirl-W6-WIN-BF' (from Dynalab). + Problem reported by Alan Coopersmith . - Reported by Roy Tam . +2018-02-17 Werner Lemberg - * src/truetype/ttobjs.c (tt_check_trickyness_family): Implement it. + [sfnt] Prefer `CBDT'/`CBLC' over `glyf' table (#53154). -2017-05-07 Roy Tam - Werner Lemberg +2018-02-06 Werner Lemberg - [truetype] More tricky fonts (mainly from Dynalab). + [truetype] Integer overflow issues. - * src/truetype/ttobjs.c (tt_check_trickyness_family, - tt_check_trickyness_sfnt_ids): Add them. + Reported as -2017-05-07 Werner Lemberg + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=6027 - [truetype] Add tricky font `DLCHayMedium' (from Dynalab). + * src/truetype/ttinterp.c (Ins_MSIRP, Ins_MIAP, Ins_MIRP): Use + SUB_LONG; avoid FT_ABS. - Reported by Roy Tam . +2018-02-04 Alexei Podtelezhnikov - * src/truetype/ttobjs.c (tt_check_trickyness_family): Implement it. + [unix] Use -fvisibility=hidden. -2017-05-03 Werner Lemberg + It is now widely recommended that ELF shared libraries hide symbols + except those with explicit __attribute__((visibility("default"))). + This is supported by all major compilers and should rather be an + option in libtool. - */*: s/backwards compatibility/backward compatibility/. + * builds/unix/configure.raw: Add -fvisibility=hidden to CFLAGS. + * builds/unix/ftconfig.in, builds/vms/ftconfig.h, + include/freetype/config/ftconfig.h (FT_EXPORT): Use visibility + attribute. -2017-05-03 Sascha Brawer - Werner Lemberg - [autofit] Add support for Unified Canadian Syllabics script. + [truetype] Better protection against invalid VF data. - * src/autofit/afblue.dat: Add blue zone data for Unified Canadian - Syllabics. - * src/autofit/afblue.c, src/autofit/afblue.h: Regenerated. + Reported as - * src/autofit/afscript.h: Add Unified Canadian Syllabics standard - character. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=5739 - * src/autofit/afranges.c, src/autofit/afstyles.h: Add Unified - Canadian Syllabics data. + Bug introduced in commit 08cd62deedefe217f2ea50e392923ce8b5bc7ac7. -2017-05-03 Sascha Brawer - Werner Lemberg + * src/truetype/ttgxvar.c (TT_Set_Var_Design): Always initialize + `normalizedcoords'. - [autofit] Add blue-zone support for Sundanese script. +2018-01-27 Werner Lemberg - This essentially moves the Sundanese script from the `Indic' hinter - to the `Latin' hinter. + * src/truetype/ttinterp.c (Ins_GETVARIATION): Avoid NULL reference. - * src/autofit/afblue.dat: Add blue zone data for Sundanese. + Reported as - * src/autofit/afblue.c, src/autofit/afblue.h: Regenerated. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=5736 - * src/autofit/afscript.h: Add Sundanese standard character and move - data out of AF_CONFIG_OPTION_INDIC block. +2018-01-27 Werner Lemberg - * src/autofit/afranges.c: Move Sundanese data out of - AF_CONFIG_OPTION_INDIC block. + * src/truetype/ttgxvar.c (tt_set_mm_blend): Minor. - * src/autofit/afstyles.h: Update Sundanese data; in particular, use - AF_WRITING_SYSTEM_LATIN. +2018-01-27 Werner Lemberg -2017-05-03 Sascha Brawer - Werner Lemberg - * src/autofit/afscript.h: Add Avestan standard character. + [truetype] Beautify tracing of VF axis records. - * src/autofit/afranges.c, src/autofit/afstyles.h: Add Avestan data. + * src/truetype/ttgxvar.c (TT_Get_MM_Var): Show axis records in a + table-like manner. -2017-05-02 Behdad Esfahbod +2018-01-26 Ben Wagner - [truetype] Make `IUP' gvar deltas do the same as Apple (#50832). + [truetype] Fix multiple calls of `FT_Get_MM_Var' (#52955). - When points are not touched by gvar interpolation deltas, FreeType - gave a slightly different result than Apple's CoreText. + * src/truetype/ttgxvar.c (TT_Get_MM_Var): Set + `face->blend->num_axis' in case we have to initialize the + `face->blend'. - The OpenType working group will update the specification to document - the following behaviour: If the two points with deltas to the `left' - and `right' of the untouched point have the same coordinate, then - the inferred delta for the untouched point should be zero. +2018-01-23 Alexei Podtelezhnikov - * src/truetype/ttgxvar.c (tt_delta_interpolate): Implement new - behaviour. + [apinames] Anonymous version map for GNU linker. -2017-05-02 Werner Lemberg + * src/tools/apinames.c (PROGRAM_VERSION): Set to 0.3. + (OutputFormat): Add `OUTPUT_GNU_VERMAP'. + (names_dump): Handle it. + (usage): Updated. + (main): Handle new command line flag `-wL'. - [autofit] Remove `slight' auto-hint mode again. +2018-01-21 Alexei Podtelezhnikov - A poll on freetype-devel favoured changes directly applied to - `light'. + [unix] Call libtool to clean up. - * include/freetype/freetype.h (FT_LOAD_TARGET_SLIGHT, - FT_RENDER_MODE_SLIGHT): Removed. + * builds/unix/install.mk (clean_project_unix, distclean_project_unix): + Use libtool. + * builds/freetype.mk: Minor. - * src/autofit/afcjk.c (af_cjk_hints_init), src/autofit/aflatin.c - (af_latin_hints_init), src/autofit/aflatin2.c - (af_latin2_hints_init): Revert change from 2017-04-22. +2018-01-18 Alexei Podtelezhnikov - * src/autofit/afloader.c (af_loader_load_glyph) Remove references to - FT_RENDER_MODE_SLIGHT. - [AF_CONFIG_OPTION_TT_SIZE_METRICS]: Enable TrueType-like metrics - unconditionally. + * src/base/ftver.rc: Fix mingw-w64 compilation. - * src/base/ftadvanc.c (LOAD_ADVANCE_FAST_CHECK): Revert change from - 2017-04-22. +2018-01-18 Alexei Podtelezhnikov - * src/base/ftobjs.c (FT_Load_Glyph): Revert change from 2017-04-22. + [build] Enable VERSIONINFO resource for Cygwin/MinGW. - * src/pshinter/pshalgo.c (ps_hints_apply): Revert change from - 2017-04-22. + * builds/unix/configure.raw: Check for resource compiler. + * builds/unix/unix-cc.in: Conditionally set up resource compiler. + * builds/freetype.mk: Add conditional rule for `ftver.rc'. + * src/base/ftver.rc: Copyright notice and year update. - * src/smooth/ftsmooth.c (ft_smooth_render): Revert change from - 2017-04-22. +2018-01-18 Alexei Podtelezhnikov - * docs/CHANGES: Updated. + [build] Move VERSIONINFO resource. -2017-04-30 Werner Lemberg + * builds/windows/vc2010/freetype.vcxproj: Updated. + * builds/windows/ftver.rc: Move file from here... + * src/base/ftver.rc: ... to here. - [autofit] Fix metrics computation. +2018-01-12 Alexei Podtelezhnikov - Problem reported by Markus Trippelsdorf and - Nikolaus Waxweiler . + [build] Expand dllexport/dllimport to Cygwin/MinGW. - * src/base/ftobjs.c (FT_Request_Size): Trigger recomputation of - auto-hinter metrics. Without this change, multiple size changing - calls for a single face fail. + * include/freetype/config/ftconfig.h: Respect DLL_EXPORT, + s/_MSC_VER/_WIN32/. + * builds/unix/ftconfig.in: Replicate here. + * builds/vms/ftconfig.h: Replicate here. -2017-04-29 Werner Lemberg +2018-01-12 Alexei Podtelezhnikov - * src/truetype/ttdriver.c (tt_size_request): Properly check `error'. + [build] Improve and document MSVC build. - Reported by Earnestly in + * include/freetype/config/ftconfig.h: Guard dllexport/dllimport + attributes with _DLL and FT2_DLLIMPORT. + * builds/windows/vc2010/index.html: Update documentation. - https://lists.nongnu.org/archive/html/freetype/2017-04/msg00031.html +2018-01-10 Steve Robinson -2017-04-27 Werner Lemberg + * CMakeLists.txt [win32]: Suppress warnings for POSIX functions. - Introduce AF_CONFIG_OPTION_TT_SIZE_METRICS configuration option. +2018-01-10 Ewald Hew - * include/freetype/config/ftoption.h - (AF_CONFIG_OPTION_TT_SIZE_METRICS): New option, commented out by - default. + [psaux] Correctly handle Flex features (#52846). - * src/autofit/afloader.c (af_loader_load_glyph): Use - AF_CONFIG_OPTION_TT_SIZE_METRICS to guard the corresponding code. + * src/psaux/psintrp.c (cf2_interpT2CharString) : Do not move if doing Flex. -2017-04-26 Werner Lemberg +2018-01-09 Alexei Podtelezhnikov - * include/freetype/freetype.h (FT_Render_Mode): Fix order. + * builds/windows/vc2010/freetype.sln: Synchronize with the project. - This retains backward compatibility. +2018-01-08 Werner Lemberg - Noted by Alexei. + * Version 2.9 released. + ======================= -2017-04-22 Werner Lemberg - [truetype] Do linear scaling for FT_LOAD_NO_HINTING (#50470). + Tag sources with `VER-2-9'. - * src/truetype/ttobjs.h (TT_SizeRec): Add field `hinted_metrics' to - hold hinted metrics. - Make `metrics' a pointer so that `tt_glyph_load' can easily switch - between metrics. + * docs/VERSION.TXT: Add entry for version 2.9. - * src/truetype/ttdriver.c (tt_size_request): Updated. - (tt_glyph_load): Use top-level metrics if FT_LOAD_NO_HINTING is - used. + * README, Jamfile (RefDoc), builds/windows/vc2005/freetype.vcproj, + builds/windows/vc2005/index.html, + builds/windows/vc2008/freetype.vcproj, + builds/windows/vc2008/index.html, + builds/windows/vc2010/freetype.vcxproj, + builds/windows/vc2010/index.html, + builds/windows/visualc/freetype.dsp, + builds/windows/visualc/freetype.vcproj, + builds/windows/visualc/index.html, + builds/windows/visualce/freetype.dsp, + builds/windows/visualce/freetype.vcproj, + builds/windows/visualce/index.html, + builds/windows/ftver.rc, + builds/wince/vc2005-ce/freetype.vcproj, + builds/wince/vc2005-ce/index.html, + builds/wince/vc2008-ce/freetype.vcproj, + builds/wince/vc2008-ce/index.html: s/2.8.1/2.9/, s/281/29/. - * src/truetype/ttgload.c (TT_Hint_Glyph, TT_Process_Simple_Glyph, - TT_Process_Composite_Component, load_truetype_glyph, - compute_glyph_metrics, TT_Load_Glyph): Updated. + * include/freetype/freetype.h (FREETYPE_MINOR): Set to 9. + (FREETYPE_PATCH): Set to 0. - * src/truetype/ttinterp.c (TT_Load_Context): Updated. + * builds/unix/configure.raw (version_info): Set to 22:0:16. + * CMakeLists.txt (VERSION_PATCH): Set to 0. - * src/truetype/ttobjs.c (tt_size_reset): Updated. +2018-01-07 Werner Lemberg - * src/truetype/ttsubpix.c (sph_set_tweaks): Updated. + Add check for librt, needed for `ftbench' (#52824). -2017-04-22 Werner Lemberg + * builds/unix/configure.raw (LIB_CLOCK_GETTIME): Define; this will + hold `-lrt' if necessary. - Add new `slight' auto-hinting mode. + * builds/unix/unix-cc.in (LIB_CLOCK_GETTIME): New variable. - This mode uses fractional advance widths and doesn't scale glyphs - horizontally, only applying vertical scaling and hinting. +2018-01-07 Ewald Hew - At the same time, the behaviour of the `light' auto-hinter gets - restored for backward compatibility: Both vertical and horizontal - scaling is again based on rounded metrics values (this was changed - in a commit from 2017-03-30 as a side effect). To be more precise, - the behaviour is restored for TrueType fonts only; for other font - formats like Type 1, this is a new feature of the `light' hinting - mode. + [psaux] Fix Type 1 glyphs with too many stem hints. - * include/freetype/freetype.h (FT_LOAD_TARGET_SLIGHT): New macro. - (FT_RENDER_MODE_SLIGHT): New render mode. + According to the CFF specification, charstrings can have up to 96 stem + hints. Due to hint replacement routines in Type 1 charstrings, some + glyphs are rejected by the Adobe engine, which implements the above + limit. This fix turns off hinting for such glyphs. - * include/freetype/internal/ftobjs.h (FT_Size_InternalRec): Add - `autohint_mode' and `autohint_metrics' fields. + * src/psaux/pshints.c (cf2_hintmap_build): Reset the error from calling + `cf2_hintmask_setAll' on a problematic Type 1 charstring and turn off + hinting. - * src/autofit/afcjk.c (af_cjk_hints_init), src/autofit/aflatin.c - (af_latin_hints_init), src/autofit/aflatin2 (af_latin2_hints_init): - Updated. +2018-01-06 Werner Lemberg - * src/autofit/afloader.c (af_loader_embolden_glyph_in_slot): Use - `autohint_metrics'. - (af_loader_load_glyph): s/internal/slot_internal/. - Initialize `autohint_metrics' and `autohint_mode' depending on - current auto-hint mode. - Use `autohint_metrics'. - Updated. + Add `FT_Done_MM_Var'. - * src/base/ftadvanc.c (LOAD_ADVANCE_FAST_CHECK): Updated. + This is necessary in case the application's memory routines differ + from FreeType. A typical example is a Python application on Windows + that calls FreeType compiled as a DLL via the `ctypes' interface. - * src/base/ftobjs.c (FT_Load_Glyph): Updated. - (FT_New_Size): Allocate `internal' object. + * include/freetype/ftmm.h, src/base/ftmm.c (FT_Done_MM_Var): Declare + and define. - * src/pshinter/pshalgo.c (ps_hints_apply): Updated. + * docs/CHANGES: Updated. - * src/smooth/ftsmooth.c (ft_smooth_render): Updated. +2018-01-03 Werner Lemberg -2017-04-22 Werner Lemberg + [truetype] Round offsets of glyph components only if hinting is on. - Introduce `FT_Size_InternalRec' structure. + * src/truetype/ttgload.c (TT_Process_Composite_Component): Implement + it. - We are going to extend this later on. +2018-01-03 Werner Lemberg - * include/freetype/internal/ftobjs.h (FT_Size_InternalRec): New - structure with a single field `module_data'. + * src/truetype/ttgxvar.c (ft_var_to_design): Remove dead code. - * src/base/ftobjs.c (FT_New_Size): Allocate `internal' field of - `FT_Size' structure. + This is a better fix than the previous commit, which is now + reverted. - * src/cff/cffgload.c (cff_builder_init, cff_decoder_prepare): Use - `size->internal->module_data' instead of `size->internal'. +2018-01-03 Alexei Podtelezhnikov - * src/cff/cffobjs.c (cff_size_done): Deallocate `module_data'. - (cff_size_init, cff_size_select, cff_size_request): Use - `size->internal->module_data' instead of `size->internal'. + Move internal LCD-related declarations. - * src/cif/cidobjs.c (cid_size_done, cid_size_init, - cid_size_request): Use `size->internal->module_data' instead of - `size->internal'. + * include/freetype/ftlcdfil.h (ft_lcd_padding, ft_lcd_filter_fir): + Move from here... + * include/freetype/internal/ftobjs.h: ... to here. - * src/psaux/psobjs.c (t1_builder_ini): Use - `size->internal->module_data' instead of `size->internal'. +2018-01-03 Alexei Podtelezhnikov - * src/type1/t1objs.c (T1_Size_Done, T1_Size_Init, T1_Size_Request): - Use `size->internal->module_data' instead of `size->internal'. + * include/freetype/config/ftconfig.h (FT_EXPORT, FT_EXPORT_DEF) + [_MSC_VER]: Limit Visual C++ attributes. -2017-04-21 Alexei Podtelezhnikov +2018-01-03 Werner Lemberg - * src/smooth/ftsmooth.h: Remove unused guards and declaration. + [truetype] Make blend/design coordinate round-tripping work. -2017-04-16 Hin-Tak Leung + Behdad reported that setting blend coordinates, then getting design + coordinates did incorrectly return the default instance's + coordinates. - Fix tracing messages. + * src/truetype/ttgxvar.c (tt_set_mm_blend): Fix it. - * src/base/ftobjs.c (FT_Face_GetCharVariantIndex, - FT_Face_GetCharVariantIsDefault, FT_Face_GetVariantsOfChar): Print - correct function name. +2017-12-31 Werner Lemberg -2017-04-08 Sascha Brawer - Werner Lemberg - * src/autofit/afranges.c, src/autofit/afstyles.h: Add Old Turkic data. + Synchronize other Windows project files. -2017-04-08 Sascha Brawer - Werner Lemberg - * src/autofit/afblue.dat: Add blue zone data for Gothic. - * src/autofit/afblue.c, src/autofit/afblue.h: Regenerated. + Update Visual C 2010 project files. - * src/autofit/afscript.h: Add Gothic standard characters. + Problem reported by Hin-Tak. - * src/autofit/afranges.c, src/autofit/afstyles.h: Add Gothic data. + * builds/windows/vc2010/freetype.vcxproj: Add files `ftbdf.c' and + `ftcid.c'. + Sort entries. + * builds/windows/vc2010/freetype.vcxproj.filter: Ditto. + Fix members of `FT_MODULE' group. -2017-04-08 Sascha Brawer - Werner Lemberg - [autofit] Add support for Cypriot script. + * builds/vms/ftconfig.h: Synchronize with unix `ftconfig.in' file. - * src/autofit/afblue.dat: Add blue zone data for Cypriot. - * src/autofit/afblue.c, src/autofit/afblue.h: Regenerated. +2017-12-28 Werner Lemberg - * src/autofit/afscript.h: Add Cypriot standard characters. + * builds/unix/ftconfig.in: Synchronize with main `ftconfig.h' file. - * src/autofit/afranges.c, src/autofit/afstyles.h: Add Cypriot data. + Reported by Nikolaus. -2017-04-08 Sascha Brawer - Werner Lemberg - [autofit] Add support for Deseret script. + Fix compiler warnings. - * src/autofit/afblue.dat: Add blue zone data for Deseret. - * src/autofit/afblue.c, src/autofit/afblue.h: Regenerated. + * src/base/ftbitmap.c (ft_bitmap_assure_buffer): Make `pitch' and + `new_pitch' unsigned. - * src/autofit/afscript.h: Add Deseret standard characters. + * src/base/ftpsprop.c: Include FT_INTERNAL_POSTSCRIPT_PROPS_H. - * src/autofit/afranges.c, src/autofit/afstyles.h: Add Deseret data. +2017-12-27 Werner Lemberg -2017-04-07 Werner Lemberg + Fixes for `make multi'. - [autofit] Fix invalid character range description (#50745). + * include/freetype/internal/ftpsprop.h: Use `FT_BASE_CALLBACK'. + (ps_property_get): Harmonize declaration with corresponding + function typedef. - Also reported as + * include/freety[e/internal/fttrace.h: Add `trace_psprops'. - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1034 + * src/base/ftpsprop.c: Include necessary header files. + (FT_COMPONENT): Define. + (ps_property_set): Tag with `FT_BASE_CALLBACK_DEF'. + (ps_property_get): Tag with `FT_BASE_CALLBACK_DEF'. + Harmonize declaration with corresponding function typedef. - * src/autofit/afranges.c (af_glag_nonbase_uniranges): Fix typo in - recent commit. +2017-12-27 Werner Lemberg -2017-04-07 Werner Lemberg + Provide support for intra-module callback functions. - [ftfuzzer] Fix clang warnings. + This is needed especially for `make multi' with C++. - * src/tools/ftfuzzer/ftfuzzer.cc (LLVMFuzzerTestOneInput): Add - casts. + * include/freetype/config/ftconfig.h (FT_BASE_CALLBACK, + FT_BASE_CALLBACK_DEF): New macros. -2017-04-06 Sascha Brawer - Werner Lemberg - [autofit] Add support for Lisu script. + Move PostScript drivers' property handlers to `base'. - * src/autofit/afblue.dat: Add blue zone data for Lisu. - * src/autofit/afblue.c, src/autofit/afblue.h: Regenerated. + This reduces the amount of duplicated code across PostScript + drivers. - * src/autofit/afscript.h: Add Lisu standard characters. + * src/cff/cffdrivr.c, src/cid/cidriver.c, src/type1/t1driver.c + ({cff,cid,t1}_property_{get,set}): Moved to... + * include/freetype/internal/ftpsprop.h: ...this new file. + (ps_property_{get,set}): New functions to replace moved ones. - * src/autofit/afranges.c, src/autofit/afstyles.h: Add Lisu data. + * src/base/ftpsprop.c: New file that implements above functions. -2017-04-06 Sascha Brawer - Werner Lemberg - * src/autofit/afranges.c, src/autofit/afstyles.h: Add Osage data. + Speed up FT_Set_Var_{Design,Blend}_Coordinates if curr == new. -2017-04-06 Sascha Brawer - Werner Lemberg -2017-04-06 Sascha Brawer - Werner Lemberg - Werner Lemberg - * src/autofit/afblue.dat: Add blue zone data for Tifinagh. - * src/autofit/afblue.c, src/autofit/afblue.h: Regenerated. + [truetype] Fix clamping, minor tracing code beautification. - * src/autofit/afscript.h: Add Tifinagh standard characters. + * src/truetype/ttgxvar.c (ft_var_to_normalized): Trace number of + design coordinates. + Use clamped value. - * src/autofit/afranges.c, src/autofit/afstyles.h: Add Tifinagh data. +2017-12-18 Werner Lemberg -2017-04-06 Sascha Brawer - Werner Lemberg - * src/autofit/afblue.dat: Add blue zone data for N'Ko. - * src/autofit/afblue.c, src/autofit/afblue.h: Regenerated. + * src/truetype/ttgxvar.c (tt_face_vary_cvt): Add size guard (#52688). - * src/autofit/afscript.h: Add N'Ko standard characters. +2017-12-18 Werner Lemberg - * src/autofit/afranges.c, src/autofit/afstyles.h: Add N'Ko data. + [truetype] Fix previous commit. -2017-04-06 Sascha Brawer + * src/truetype/ttgload.c (TT_Process_Simple_Glyph): Correctly handle + unhinted phantom points, which must be properly scaled. - [autofit] Add support for Adlam script. +2017-12-18 Werner Lemberg - * src/autofit/afblue.dat: Add blue zone data for Adlam. - * src/autofit/afblue.c, src/autofit/afblue.h: Regenerated. + [truetype] Don't apply HVAR and VVAR deltas twice (#52683). - * src/autofit/afscript.h: Add Adlam standard characters. + * src/truetype/ttgload.c (TT_Process_Simple_Glyph): Always adjust + `pp1' to `pp4', except if we have an HVAR and/or VVAR table. - * src/autofit/afranges.c, src/autofit/afstyles.h: Add Adlam data. + * src/truetype/ttgxvar.c (TT_Vary_Apply_Glyph_Deltas): Handle + alternative code branch identically w.r.t. presence of an HVAR + and/or VVAR table. -2017-04-06 Sascha Brawer +2017-12-17 Jonathan Kew - [autofit] Add support for Ol Chiki script. + [truetype] Correctly handle variation font phantom points (#52683). - * src/autofit/afblue.dat: Add blue zone data for Ol Chiki. - * src/autofit/afblue.c, src/autofit/afblue.h: Regenerated. + * src/truetype/ttgxvar.c (TT_Vary_Apply_Glyph_Deltas): Fix phantom + point indices. - * src/autofit/afscript.h: Add Ol Chiki standard character. +2017-12-17 Jonathan Kew - * src/autofit/afranges.c, src/autofit/afstyles.h: Add Ol Chiki data. + Fix incorrect advance width scaling (#52683). -2017-04-03 Werner Lemberg + * src/base/ftadvance.c (FT_Get_Advances): Always respect the + FT_LOAD_NO_SCALE flag if present. - [truetype] Avoid reexecution of `fpgm' and `prep' in case of error. +2017-12-16 Alexei Podtelezhnikov - Reported as + * builds/windows/vc2010/freetype.vcxproj: AfterBuild copy. + * objs/.gitignore: Ignore almost everything. - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=981 +2017-12-11 Werner Lemberg - * include/freetype/fterrdef.h (FT_Err_DEF_In_Glyf_Bytecode): New - error code. + Fix compiler warning (#52640). - * src/truetype/ttinterp.c (Ins_FDEF, Ins_IDEF): Prohibit execution - of these two opcodes in `glyf' bytecode. - (TT_RunIns): Don't enforce reexecution of `fpgm' and `prep' bytecode - in case of error since function tables can no longer be modified - (due to the changes in `Ins_FDEF' and `Ins_IDEF'). This change can - enormously speed up handling of broken fonts. + * src/base/ftbitmap.c (ft_bitmap_assure_buffer): Remove unused + variable. -2017-04-02 Alexei Podtelezhnikov +2017-12-08 Azzuro - [autofit] Disable metrics adjustment for `FT_LOAD_TARGET_LCD'. + * builds/windows/vc2010/freetype.vcxproj: Adjust output directory. - * src/autofit/aflatin.c (af_latin_hints_init): Updated. - * src/autofit/aflatin2.c (af_latin2_hints_init): Ditto. + This allows builds with different configurations in parallel. -2017-04-01 Werner Lemberg +2017-12-08 Werner Lemberg - * src/truetype/ttgload.c: Include FT_CONFIG_CONFIG_H. + Fix `make setup dos', second try (#52622). - Otherwise FT_UINT_TO_POINTER might not be defined. + * builds/detect.mk (dos_setup): Don't use literal `>' character at + all. Mixing the different escaping rules from make, dos, and + windows is too fragile. - Problem reported by Alexei. +2017-12-08 Werner Lemberg -2017-03-31 Alexei Podtelezhnikov + [docmaker] Fix code section parsing. - [autofit] Disable stem adjustment for `FT_LOAD_TARGET_LCD'. + Stuff like - * include/freetype/freetype.h (FT_LOAD_TARGET_LCD): Document it. - * src/autofit/afcjk.c (af_cjk_hints_init): Updated. - * src/autofit/aflatin.c (af_latin_hints_init): Ditto. - * src/autofit/aflatin2.c (af_latin2_hints_init): Ditto. + { + + } -2017-03-31 Werner Lemberg + confused the parser, which incorrectly treated `' as a markup + tag. - * src/cff/cffload.c (cff_font_load): Improve fix from 2017-01-04. + * src/tools/docmaker/content.py (ContentProcessor::process_content): + Apply `re_markup_tags' only outside of code sections. - Allow CFFs containing a single font to have an empty font name. +2017-12-08 Werner Lemberg - Problem reported by 張俊芝 <418092625@qq.com> in + New `ftdriver.h' file, covering all driver modules. - https://lists.nongnu.org/archive/html/freetype-devel/2017-03/msg00074.html + This reduces redundancy and increases synergy; it also reduces the + number of header files. -2017-03-30 Werner Lemberg + * include/freetype/config/ftheader.h (FT_DRIVER_H): New macro. + (FT_AUTOHINTER_H, FT_CFF_DRIVER_H, FT_TRUETYPE_DRIVER_H, + FT_PCF_DRIVER_H, FT_TYPE1_DRIVER_H): Make them aliases to + FT_DRIVER_H. - * src/cff/cffparse.h (CFF2_DEFAULT_STACK): Set to 513 also. + * include/freetype/ftautoh.h, include/freetype/ftcffdrv.h, + include/freetype/ftpcfdrv.h, include/freetype/ftt1drv.h, + include/freetype/ftttdrv.h: Replaced with... + * include/freetype/ftdriver.h: ...this new file. + (FT_CFF_HINTING_ADOBE, FT_T1_HINTING_ADOBE): Renamed to... + (FT_HINTING_ADOBE): ... this new macro. + (FT_CFF_HINTING_FREETYPE, FT_T1_HINTING_FREETYPE): Renamed to... + (FT_HINTING_FREETYPE): ... this new macro. - Requested by Dave Arnold. + * src/*/*: Updated accordingly. -2017-03-30 Werner Lemberg +2017-12-08 Werner Lemberg - [truetype] Fix HVAR and VVAR handling (#50678). + Move `ftdriver.h' to `ftdrv.h'. - * src/truetype/ttgxvar.c (tt_hvadvance_adjust): Handle - glyph indices larger than `mapCount' as described in the - specification. + * include/freetype/internal/ftdriver.h: Renamed to... + * include/freetype/internal/ftdrv.h: ... this name. -2017-03-30 Werner Lemberg + * include/freetype/internal/internal.h (FT_INTERNAL_DRIVER_H): + Updated. - [truetype] Allow linear scaling for unhinted rendering (#50470). +2017-12-08 Werner Lemberg - * src/truetype/ttdriver.c (tt_size_request): Revert change from - 2011-07-16; the intended metrics fix seems now to be implemented in - a different way, making the patch unnecessary. Note that this - change was usually patched out by all major GNU/Linux distributions - due to heavy side effects. + Fix access to uninitalized memory (#52613). - * src/truetype/ttgload.c (compute_glyph_metrics, TT_Load_Glyph): - Refer to the metrics of the `TT_Size' object. + Also reported as -2017-03-29 Werner Lemberg + https://bugs.chromium.org/p/chromium/issues/detail?id=791317 - [truetype] Fix thinko related to PS name of default named instance. + * src/base/ftbitmap.c (ft_bitmap_assure_buffer): If increasing the + bitmap size needs a larger bitmap buffer, assure that the new memory + areas are initialized also. - * src/truetype/ttgxvar.c (TT_Get_MM_Var): `strid' and `psid' are - name ID values, not indices into the array of name entries. +2017-12-08 Werner Lemberg -2017-03-27 Werner Lemberg + Fix `make setup dos' (#52622). - [cid, truetype] Don't use `index' as a variable name. + * builds/detect.mk (dos_setup): Properly escape literal `>' + character. - At least on FreeBSD there is a global declaration of `index' in file - `/usr/include/strings.h'. +2017-12-07 Werner Lemberg - * src/cff/cf2intrp.c, src/truetype/ttgload.c: s/index/idx/ where - appropriate. + Fix C++ compilation. -2017-03-27 Wojciech Mamrak + * src/psaux/psauxmod.h: Use FT_CALLBACK_TABLE macro where necessary. - [sfnt] Minor improvement for handling kern tables. + * src/smooth/ftsmooth.c (ft_smooth_render_generic): Fix warning. - * src/sfnt/ttkern.c (tt_face_load_kern): Don't check for - cross-stream kerning tables since we reject format 2 tables later - on anyways. - Modify code for limit test... - (tt_face_get_kerning): ... to avoid a limit test here. +2017-12-07 Werner Lemberg -2017-03-27 Werner Lemberg + Fix `make multi'. - [pcf] Fix compiler warnings. + * include/freetype/internal/fttrace.h: Remove unused tracing macros. + s/pshalgo2/pshalgo/. + Add `trace_cffdecode'. + * src/pshinter/pshalgo.c (FT_COMPONENT): Updated. - Reported by Alexander Hedges . + * src/cff/cffload.c: Include FT_INTERNAL_POSTSCRIPT_AUX_H. + * src/cff/cffobjs.c: Include FT_SERVICE_METRICS_VARIATIONS_H and + FT_SERVICE_CFF_TABLE_LOAD_H. - * src/pcf/pcfdrivr.c (pcf_property_set, pcf_property_get): Tag - `property_name' with `FT_UNUSED' where necessary. + * src/cid/cidriver.c: Include FT_INTERNAL_POSTSCRIPT_AUX_H. -2017-03-26 Werner Lemberg + * src/psaux/cffdecode.c: Include FT_FREETYPE_H and + FT_INTERNAL_DEBUG_H. + (FT_COMPONENT): Define. + * src/psaux/cffdecode.h: Include FT_INTERNAL_POSTSCRIPT_AUX_H. + * src/psaux/psauxmod.h: Include FT_INTERNAL_POSTSCRIPT_AUX_H. + Declare `cff_builder_funcs' and `ps_builder_funcs'. + * src/psaux/psft.c: Include `psobjs.h' and `cffdecode.h'. + * src/psaux/psobjs.c : Include `psauxmod.h'. - * src/psaux/psobjs.c (t1_builder_close_contour): Add safety guard. +2017-12-07 Werner Lemberg - Reported as + * include/freetype/config/ftheader.h: Some clean-up. - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=941 + This commit removes documentation of deprecated macros and does some + minor streamlining. -2017-03-23 Werner Lemberg +2017-12-06 Werner Lemberg - [psaux] Better protect `flex' handling. + * builds/symbian/bld.inf: Updated. - Reported as +2017-12-06 Werner Lemberg - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=935 + New header file `ftparams.h' that collects all parameter tags. - * src/psaux/t1decode.c (t1_decoder_parse_charstrings) - : Since there is not a single flex operator but a - series of subroutine calls, malformed fonts can call arbitrary other - operators after the start of a flex, possibly adding points. For - this reason we have to check the available number of points before - inserting a point. + * include/freetype/config/ftheader.h (FT_PARAMETER_TAGS_H): New + macro. + (FT_TRUETYPE_UNPATENTED_H, FT_UNPATENTED_HINTING_H): Define it to + `ftparams.h'. -2017-03-23 Werner Lemberg + * include/freetype/ftautoh.h, include/freetype/ftcffdrv.h, + include/freetype/ftincrem.h, include/freetype/ftlcdfil.h, + include/freetype/ftsnames.h, include/freetype/ftt1drv.h: Include + FT_PARAMETER_TAGS_H. + Move FT_PARAM_TAG_XXX definitions to... + * include/freetype/ftparams.h: ...this new file. - [sfnt] Fix check for default named instance. + * include/freetype/ttunpat.h: Remove. No longer needed. - * src/sfnt/sfobjs.c (sfnt_init_face): A `fixed' number needs four - bytes, not two... +2017-12-05 Werner Lemberg -2017-03-23 Werner Lemberg + Improve tracing messages by using singular and plural forms. - Make MM fonts work (again). + * src/*/*.c: Implement it. - * src/base/ftmm.c (FT_Set_Var_Design_Coordinates, - FT_Set_MM_Blend_Coordinates, FT_Set_Var_Blend_Coordinates): Ignore - return value of `ft_face_get_mvar_service'; instead, check whether a - service is actually returned. +2017-12-04 Werner Lemberg -2017-03-20 Werner Lemberg + [truetype] Allow shared points in `cvar' table (#52532). - [truetype] Some variable renamings. + * src/truetype/ttgxvar.c (tt_face_vary_cvt): Implement it by copying + and adjusting the corresponding code from + `TT_Vary_Apply_Glyph_Deltas'. - Too much local variables holding different structures were called - `metrics'. +2017-11-28 Werner Lemberg - * src/truetype/ttdriver.c (tt_size_select): s/metrics/size_metrics/. + [truetype] Improving tracing of composite glyphs. - * src/truetype/ttgload.c (tt_get_metrics_incr_overrides, - compute_glyph_metrics): s/metrics/incr_metrics/. - (load_sbit_image): s/metrics/sbit_metrics/. + * src/truetype/ttgload.c (TT_Load_Composite_Glyph) + [FT_DEBUG_LEVEL_TRACE]: Show composite glyph information. - * src/truetype/ttobjs.c (tt_size_run_fpgm): s/metrics/size_metrics/. - (tt_size_init_bytecode): s/metrics/tt_metrics/. - (tt_size_reset): s/metrics/size_metrics/. +2017-11-27 Werner Lemberg -2017-03-20 Werner Lemberg + [type1] Allow (again) `/Encoding' with >256 elements (#52464). - [sfnt] Don't add instances to non-variation fonts. + In version 2.6.1, this has been disallowed to better reject + malformed fonts; however, this restriction was too strong. This + time, we only take the first 256 elements into account, since + encoding arrays are always accessed with a 8bit integer, according + to the PostScript Language Reference. - * src/sfnt/sfobjs.c (sfnt_init_face): Fix it. + * src/type1/t1load.c (parse_encoding): Implement it. -2017-03-20 Werner Lemberg +2017-11-27 Jan Alexander Steffens (heftig) - * src/cff/cffgload.c (cff_builder_init): Add safety guard (#50578). + Fix last commit (#52522). -2017-03-18 Werner Lemberg + * builds/freetype.mk: Set `FT_OPTION_H' and `FTOPTION_FLAG' + properly if we have `ftoption.h' in `BUILD_DIR'. - Introduce FT_UINT_TO_POINTER macro (#50560). +2017-11-24 Werner Lemberg - We have to make a separate case for Windows 64's LLP64 data model. + [unix] Install a massaged `ftoption.h' file (#51780). - * builds/unix/ftconfig.in, builds/vms/ftconfig.h, - include/freetype/config/ftconfig.h (FT_UINT_TO_POINTER): New macro. + * builds/unix/configure.raw (ftoption_set, ftoption_unset): New + auxiliary functions to construct... + (FTOPTION_H_SED): ... this new variable. + Apply it as a sed argument while copying `ftoption.h' to the + `builds/unix' directory (using `AC_CONFIG_FILES'). + Simplify code of test that checks cpp's computation of bit length + (the test previously created an empty `ftoption.h' file and deleted + it immediately afterwards); without this change, it can happen on my + GNU/Linux box that `configure's execution of `config.status' doesn't + create `ftoption.h' (no idea why this happens). - * src/truetype/ttgload.c (load_truetype_glyph): Use it. + * builds/unix/install.mk (install): Install + `builds/unix/ftoption.h'. -2017-03-18 Werner Lemberg + * builds/unix/unix-def.in (DISTCLEAN): Updated. - * src/truetype/ttinterp.c (TT_RunIns): Adjust loop counter (#50573). + * builds/unix/.gitignore: Updated. - The problematic font that exceeds the old limit is Lato-Regular, - version 2.007, containing bytecode generated by a buggy version of - ttfautohint. +2017-11-23 Tor Andersson -2017-03-18 Werner Lemberg + Silence unused function warnings (#52465). - [truetype] Another limitation for bytecode loop count maximum. + Some static function declarations cause unused function warnings if + certain config options are turned off via `ftoption.h'. - Reported as + * src/base/ftbase.h, src/base/ftrfork.c, src/sfnt/ttbdf.h, + src/truetype/ttgxvar.h: Add #ifdef guards around these sections. - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=900 +2017-11-22 Ewald Hew - * src/truetype/ttinterp.c (TT_RunIns): Limit `loopcall_counter_max' - by number of glyphs also. + * src/psaux/psft.c (cf2_setGlyphWidth): Check format before setting. -2017-03-18 Werner Lemberg + Reported as - [ftfuzzer] Minor improvement. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=4377 - * src/tools/ftfuzzer/ftfuzzer.cc: Don't set intermediate axis if - bitmap strikes are active. +2017-11-22 Ewald Hew -2017-03-18 Werner Lemberg + [psaux] Fix CFF advance widths. (#52466) - Improve `make multi'. + Glyph advance widths were being written to the new `PS_Decoder' but not + saved to the underlying format specific decoder. This caused pure CFF + fonts to have bad advance width. - * src/autofit/aflatin2.c: Guard file with FT_OPTION_AUTOFIT2. + * include/freetype/internal/psaux.h (PS_Decoder): Change `glyph_width' + field to pointer. + Remove unused fields. + * src/psaux/psobjs.c (ps_decoder_init): Change `glyph_width' from copy + to reference. + Remove unused. + * src/psaux/psft.c (cf2_setGlyphWidth): Update code. - * src/base/ftmac.c: Guard more parts of the file with FT_MACINTOSH. +2017-11-15 Vlad Tsyrklevich - * src/psaux/afmparse.c: Guard file with T1_CONFIG_OPTION_NO_AFM. + * include/freetype/ftrender.h: Fix `FT_Renderer_RenderFunc' type. - * src/sfnt/pngshim.c: Guard file with - TT_CONFIG_OPTION_EMBEDDED_BITMAPS also. +2017-11-14 Nikolaus Waxweiler - * src/sfnt/ttbdf.c: Avoid empty source file. - * src/sfnt/ttpost.c: Guard file with - TT_CONFIG_OPTION_POSTSCRIPT_NAMES. - * src/sfnt/ttsbit.c: Guard file with - TT_CONFIG_OPTION_EMBEDDED_BITMAPS. + Use Adobe hinting engine for `light' hinting of both CFF and Type 1. - * src/truetype/ttgxvar.c, src/truetype/ttinterp.c: Avoid empty - source file. + Since Ewald Hew factored the Adobe hinting engine out of the CFF + driver code, we can now use it on Type 1 (and CID) font formats, as + both have the same hinting philosophy. - * src/truetype/ttsubpix.c: Guard file with - TT_USE_BYTECODE_INTERPRETER also. + This change activates the Adobe hinter when in LIGHT mode, and + therefore always unless explicitly asking for the auto-hinter. This + makes LIGHT behavior consistent with CFF fonts. As of this commit, + the hinting engine table looks as follows. - * src/type1/t1afm.c: Guard file with T1_CONFIG_OPTION_NO_AFM. + LIGHT NORMAL + ------------------------- + TrueType Auto v40 + CFF Adobe Adobe + Type 1 Adobe Adobe - * src/autofit/autofit.c, src/base/ftbase.c, src/cache/ftcache.c, - src/cff/cff.c, src/cid/type1cid.c, src/gxvalid/gxvalid.c, - src/pcf/pcf.c, src/pfr/pfr.c, src/psaux/psaux.c, - src/pshinter/pshinter.c, src/psnames/psnames.c, src/raster/raster.c, - src/sfnt/sfnt.c, src/smooth/smooth.c, src/truetype/truetype.c, - src/type1/type1.c, src/type42/type42.c: Remove conditionals; sort - entries. +2017-11-10 Yuri Levchenko -2017-03-17 Werner Lemberg + * CMakeLists.txt: Add `DISABLE_FORCE_DEBUG_PREFIX' option. - Fixes for conditional compilation. +2017-11-06 Alexei Podtelezhnikov - * src/autofit/afcjk.c, src/autofit/afindic.c: Include `afcjk.h' - earlier. + * src/base/ftobjs.c (FT_Load_Glyph): Relocate condition. - * src/sfnt/sfobjs.c (sfnt_init_face): Put `memory' variable into - TT_CONFIG_OPTION_GX_VAR_SUPPORT block. - (sfnt_done_face): Protect some code with - TT_CONFIG_OPTION_GX_VAR_SUPPORT. +2017-11-06 Alexei Podtelezhnikov - * src/sfnt/ttsbit.c (tt_face_load_sbix_image): Remove compiler - warning. + * src/smooth/ftgrays.c (gray_set_cell): Fix uninitialized variables. - * src/truetype/ttgload.c (TT_Load_Simple_Glyph): Put `tmp' variable - into TT_USE_BYTECODE_INTERPRETER block. +2017-11-03 Ewald Hew - (tt_loader_init): Put `error' variable into - TT_USE_BYTECODE_INTERPRETER block. + [psaux] Fix PostScript interpreter rewinding in Type 1 mode. (#52251) -2017-03-17 Werner Lemberg + The interpreter in Type 1 mode rewinds the charstring after collecting + all hints for building the initial hintmap (commit d52dd7f). However, + some charstrings use `endchar' in a final subroutine call, rewinding to + the start of that subroutine, and only a small section of the actual + glyph is drawn. - Fix preprocessor warning. + * src/psaux/psintrp.c (cf2_interpT2CharString) : + Ensure we are on the top level charstring before rewinding. - * devel/ftoption.h, include/freetype/config/ftoption.h: Test whether - TT_CONFIG_OPTION_SUBPIXEL_HINTING is defined before checking its - value. +2017-11-03 suzuki toshiya -2017-03-17 Werner Lemberg + [truetype] Add more tricky fonts. - `make multi' fixes; compiler warnings. + See the report by Yang Yinsen. + https://lists.gnu.org/archive/html/freetype-devel/2017-11/msg00000.html - * src/base/ftsnames.c: Include FT_INTERNAL_DEBUG_H. + * src/truetype/ttobjs.c (trick_names): Add `DFGothic-EB', + `DFGyoSho-Lt', `DFHSGothic-W5', `DFHSMincho-W3' and `DFHSMincho-W7'. + (tt_check_trickyness_sfnt_ids): Add checksums for DFGothic-EB, + DFGyoSho-Lt, DFHSGothic-W5, DFHSMincho-W3 and DFHSMincho-W7. Also + add checksums for DLCLiShu and DLCHayBold which their family names + were already listed but their checksums were previously unknown. - * src/cff/cffobjs.c [TT_CONFIG_OPTION_GX_VAR_SUPPORT]: Include - FT_MULTIPLE_MASTERS_H and FT_SERVICE_MULTIPLE_MASTERS_H. +2017-11-01 Alexei Podtelezhnikov - * src/sfnt/sfdriver.c [TT_CONFIG_OPTION_GX_VAR_SUPPORT]: Include - FT_MULTIPLE_MASTERS_H and FT_SERVICE_MULTIPLE_MASTERS_H. - (get_win_string, get_apple_string): Initialize `result'. + [smooth] Fix complex rendering at high ppem. -2017-03-17 Dave Arnold + We used to split large glyphs into horizontal bands and continue + bisecting them still horizontally if that was not enough. This is + guaranteed to fail when a single scanline cannot fit into the + rendering memory pool. Now we bisect the bands vertically so that + the smallest unit is a column of the band height, which is guranteed + to fit into memory. - [cff] Fix potential bugs in default NDV for CFF2. + * src/smooth/ftgrays.c (gray_convert_glyph): Implement it. - * src/cff/cffload.c (cff_blend_build_vector): Explicitly build blend - vector when `lenNDV' is zero; don't rely on zero-init. - Save `lenNDV' as part of cache key even when `lenNDV' is zero. +2017-10-20 Alexei Podtelezhnikov -2017-03-17 Dave Arnold + [smooth] Improve complex rendering at high ppem. - [cff] Fix CFF2 stack allocation. + At large sizes almost but not exactly horizontal segments can quickly + drain the rendering pool. This patch at least avoids filling the pool + with trivial cells. Beyond this, we can only increase the pool size. - * src/cff/cffparse.c (cff_parser_init) add 1 for operator. + Reported, analyzed, and tested by Colin Fahey. -2017-03-16 Werner Lemberg + * src/smooth/ftgrays.c (gray_set_cell): Do not record trivial cells. - * src/truetype/ttgxvar.c (tt_done_blend): Free `vvar_table'. +2017-10-20 Alexei Podtelezhnikov - Reported as + [base] Improve tracing in FT_Load_Glyph, FT_*_Size. - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=883 + * src/base/ftobjs.c (FT_Load_Glyph): Tag tracing messages with + function name, glyph index, and load flags. + (FT_Select_Metrics, FT_Request_Metrics): Remove all tracing. + (FT_Select_Size, FT_Request_Size): Improve tracing. -2017-03-15 Werner Lemberg +2017-10-18 Alexei Podtelezhnikov - Remove clang compiler warnings (#50548). + [base] Improve tracing in FT_Render_Glyph. - * include/freetype/internal/tttypes.h (TT_FaceRec): Make - `var_postscript_prefix_len' unsigned. + * src/base/ftobjs.c (FT_Render_Glyph_Internal): Add total coverage + calculations and downgrade Netpbm dump to bitmap:7. - * src/autofit/afwarp.c (af_warper_compute_line_best): Remove - redundant assignment. +2017-10-15 Ewald Hew - * src/cff/cffload.c (cff_subfont_load): Add casts. + [cff] Fix segfault on missing `psaux' (#52218) - * src/cff/cffparse.c (cff_parse_blend): Remove redundant assignment. + * src/cff/cffload.c (cff_done_blend): Add a check for possible nullptr. - * src/sfnt/sfdriver.c (fmix32, murmur_hash_3_128): Add `static' - keyword. - Add casts. - (fixed2float): Add cast. - (sfnt_get_var_ps_name): Make `p' always initialized. - Add casts. + * modules.cfg: Update dependency list. - * src/truetype/ttgxvar.c (TT_Get_MM_Var): Add casts. +2017-10-15 Alexei Podtelezhnikov -2017-03-15 Werner Lemberg + [base, cff] Fix MSVC warnings. - [ftfuzzer] Limit number of tested faces and instances. + * src/base/ftobjs.c (FT_New_Library): C4702: unreachable code. + (ft_glyphslot_preset_bitmap): C4244: possible loss of data. + * src/cff/cffload.c (cff_blend_doBlend): C4244: possible loss of data. + Turn `sum' into unsigned. - This is inspired by the discussion in and analysis of +2017-10-14 Alexei Podtelezhnikov - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=859 + [base] Netpbm image tracing. - * src/tools/ftfuzzer/ftfuzzer.cc (LLVMFuzzerTestOneInput): Use only - up to 20 face indices. - Use only up to 20 instance indices. + * src/base/ftobjs.c (FT_Load_Glyph): Trace bitmap size. + (FT_Render_Glyph_Internal): Trace bitmap in Netpbm format. -2017-03-15 Werner Lemberg + * src/smooth/ftgrays.c (gray_sweep): Sweep remnants of span tracing. - * src/tools/ftfuzzer/ftfuzzer.cc: Improve readability; formatting. +2017-10-14 Alexei Podtelezhnikov -2017-03-14 Werner Lemberg + * builds/windows/ftdebug.c (FT_Message): Print to stderr. + * builds/wince/ftdebug.c (FT_Message): Ditto. - [sfnt] Implement PS names for font instances [3/3]. +2017-10-14 Behdad Esfahbod - Everything is guarded with TT_CONFIG_OPTION_GX_VAR_SUPPORT. + [afshaper] Delay creating `hb_set' objects until needed. - * include/freetype/internal/tttypes.h (TT_FaceRec): New fields - `var_postscript_prefix' and `var_postscript_prefix_len'. + In runs on Noto Naskh Arabic, this results in 89 sets created + instead of 340 before. Makes auto-hinter setup with HarfBuzz + enabled 20% to 30% faster. - * src/sfnt/sfdriver.c: Include FT_TRUETYPE_IDS_H. - (sfnt_is_alphanumeric): New wrapperfunction for `ft_isalnum'. - (get_win_string, get_apple_string): Remove `const' from return - value. - (MAX_VALUE_DESCRIPTOR_LEN, MAX_PS_NAME_LEN): New macros. - (hexdigits): New array. - (sfnt_get_var_ps_name): New function, implementing Adobe TechNote - 5902 to construct a PS name for a variation font instance. - (sfnt_get_ps_name): Call `sfnt_get_var_ps_name' for font instances. + * src/autofit/afshaper.c (af_shaper_get_coverage): Implement it. - * src/sfnt/sfobjs.c (sfnt_done_face): Updated. +2017-10-12 Ewald Hew - * src/truetype/ttgxvar.c (tt_set_mm_blend): Reset - `face->postscript_name' to trigger recalculation for new instance - parameters. + [type1, cid] Add hinting engine switch. -2017-03-14 Werner Lemberg + Implement property service in `type1' and `cid' drivers to allow + switching between FreeType or Adobe hinting engine when both are + available. - [sfnt] Implement PS names for font instances [2/3]. + * src/cid/cidriver.c (cid_property_{set,get}, cid_services), + src/type1/t1driver.c (t1_property_{set,get}, t1_services): Add + Properties service. - * src/sfnt/sfdriver.c (fix2float) [TT_CONFIG_OPTION_GX_VAR_SUPPORT]: - New function to find the shortest representation of a 16.16 - fractional number. + * src/cid/cidobjs.c (cid_driver_init), src/type1/t1objs.c + (T1_Driver_Init): Add default property values. -2017-03-14 Werner Lemberg +2017-10-12 Ewald Hew - [sfnt] Implement PS names for font instances [1/3]. + Add T1_CONFIG_OPTION_OLD_ENGINE configuration option. - Add 128bit MurmurHash 3 function. + This controls whether the old Type 1 engine gets compiled into FreeType. + It is disabled by default. - Everything is guarded with TT_CONFIG_OPTION_GX_VAR_SUPPORT. + * devel/ftoption.h, include/freetype/config/ftoption.h + (T1_CONFIG_OPTION_OLD_ENGINE): New macro. - * src/sfnt/sfdriver.c (ROTL32): New macro. - (fmix32, murmur_hash_3_128): New functions. + * include/freetype/internal/psaux.h (PS_Decoder): Remove unused field. + * include/freetype/internal/psaux.h, src/cid/cidgload.c + (cid_load_glyph), src/psaux/psauxmod.c, src/psaux/psobjs.c + (ps_builder_add_point), src/psaux/t1decode.c + (t1_lookup_glyph_by_stdcharcode, t1_decoder_parse_glyph, + t1operator_seac, t1_decoder_parse_charstrings), src/psaux/t1decode.h, + src/type1/t1gload.c (T1_Parse_Glyph_And_Get_Char_String): Surround + relevant code with macro. + Minor code changes. -2017-03-13 Werner Lemberg +2017-10-12 Ewald Hew - [truetype] Ignore invalid MVAR tags. + Extract width parsing from Type 1 parser. - Reported as + Duplicate the fast advance width calculations from the old parser. + This is to facilitate adding options for compiling out the old parser. - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=838 + * src/psaux/t1decode.{c,h} (t1_decoder_parse_metrics): New function. + * include/freetype/internal/psaux.h (T1_Decoder_Funcs): New entry + `parse_metrics'. + * src/psaux/psauxmod.c: Set the new entry. - * src/truetype/ttgxvar.c (ft_var_load_mvar): Ignore value and emit - warning for invalid tags. - (tt_apply_mvar): Ignore invalid tags. + * src/type1/t1gload.c (T1_Parse_Glyph_And_Get_Char_String), + src/cid/cidgload.c (cid_load_glyph): Separate + conditional for selecting engine. -2017-03-12 Werner Lemberg +2017-10-09 Werner Lemberg - [truetype] Store and use design coordinates also. + * src/base/ftoutln.c (FT_Outline_Translate): Fix integer overflow. - * include/freetype/internal/services/svmm.h (FT_Get_Var_Blend_Func): - Add `normalizedcoords' argument. + Reported as - * src/truetype/ttgxvar.h (GX_BlendRec): Add `coords' field to store - the design coordinates of the current instance. - Updated. + https://bugs.chromium.org/p/chromium/issues/detail?id=772775 - * src/truetype/ttgxvar.c (TT_Set_MM_Blend): Move functionality to... - (tt_set_mm_blend): ... New function. - Convert data in `normalizedcoords' array to `coords' array on - demand. - (TT_Set_Var_Design): Store argument data in `coords' array. - (TT_Get_Var_Design): Get data from `coords' array. - (tt_get_var_blend): Updated. - (tt_done_blend): Updated. +2017-10-08 Werner Lemberg - * src/cff/cffload.c, src/cff/cffload.h (cff_get_var_blend): Updated. + * src/base/ftobjs.c (ft_glyphslot_preset_bitmap): Integer overflows. - * src/cff/cf2ft.c (cf2_getNormalizedVector): Updated. + Reported as - * src/cff/cffobjs.c (cff_face_init): Updated. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3579 -2017-03-12 Werner Lemberg +2017-10-07 Werner Lemberg - src/truetype/ttgxvar.[ch]: s/avar_checked/avar_loaded/. + [sfnt] Adjust behaviour of PS font names for variation fonts. -2017-03-08 Werner Lemberg + * src/sfnt/sfdriver.c (sfnt_get_var_ps_name): Use a named instance's + PS name only if no variation is applied. - [sfnt] Another fix for buggy variation fonts. +2017-10-07 Werner Lemberg - Reported as + [cff, truetype] Adjust behaviour of named instances. - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=759 + This commit completely separates the interaction between named + instances and variation functions. In particular, resetting the + variation returns to the current named instance (if set) and not to + the base font. - * src/sfnt/sfobjs.c (sfnt_init_face): While setting number of - instances to zero for `CFF' fonts table, ensure that there is no - `CFF2' present also (which gets priority). + As a side effect, variation functions no longer change the named + instance index. -2017-03-07 Werner Lemberg + * src/cff/cffobjs.c (cff_face_init): Use MM service's `set_instance' + function. + Also apply `MVAR' table to named instances. - [sfnt] Improve handling for buggy variation fonts. + * src/truetype/ttgxvar.c (TT_Get_MM_Var): Add cast. + (tt_set_mm_blend): No longer check whether requested variation + coincides with a named instance. + (TT_Set_Var_Design): Use current named instance for default + coordinates. + * src/truetype/ttobjs.c (tt_face_init): Use `TT_Set_Named_Instance'. - Reported as +2017-10-07 Werner Lemberg - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=738 + Make `FT_Set_Named_Instance' work. - * src/sfnt/sfobjs.c (sfnt_init_face): While setting number of - instances to zero for `CFF' fonts table, ensure that there is no - `glyf' table present also (which gets priority). + * src/cff/cffdrivr.c (cff_set_instance): New function. + (cff_service_multi_masters): Register it. -2017-03-06 Werner Lemberg + * src/truetype/ttgxvar.c (TT_Set_Named_Instance): New function. + * src/truetype/ttgxvar.h: Updated. + * src/truetype/ttdriver.c (tt_service_gx_multi_masters): Register + it. - [sfnt, truetype] Always provide default instance. + * src/type1/t1load.c (T1_Reset_MM_Blend): New function. + * src/type1/t1load.h: Updated. + * src/type1/t1driver.c (t1_service_multi_masters): Register it. - As documented in the OpenType specification, an entry for the - default instance may be omitted in the named instance table. In - particular this means that even if there is no named instance table - in the font we actually do have a named instance, namely the default - instance. +2017-10-07 Werner Lemberg - For consistency, we always want the default instance in our list of - named instances. If it is missing, we try to synthesize it. + Make `FT_FACE_FLAG_VARIATION' work. - * src/sfnt/sfobjs.c (sfnt_init_face): Check whether the default - instance is in the table of named instances. Otherwise adjust - number of instances. + * include/freetype/internal/tttypes.h (TT_Face): Remove + `is_default_instance'; this can be replaced with a combination of + `FT_IS_VARIATION' and `FT_IS_INSTANCE'. - * src/truetype/ttgxvar.c: Include FT_TRUETYPE_IDS_H. - (TT_Get_MM_Var): Use `face->root.style_flags' as the number of named - instances. - Sythesize a named instance entry if necessary. - (tt_done_blend): Free `normalized_stylecoords'. + * src/cff/cffdrivr.c (cff_get_advances): Updated. -2017-03-05 Werner Lemberg + * src/sfnt/sfdriver.c (sfnt_get_ps_name), src/sfnt/sfobjs.c + (sfnt_init_face): Updated. - [sfnt] Remove redundant code. + * src/truetype/ttdriver.c (tt_get_advances), src/truetype/ttgload.c + (TT_Process_Simple_Glyph, load_truetype_glyph, IS_DEFAULT_INSTANCE), + src/truetype/ttgxvar.c (tt_set_mm_blend): Updated. + * src/truetype/ttgxvar.c (TT_Set_MM_Blend, TT_Set_Var_Design): + Handle `FT_FACE_FLAG_VARIATION'. - * src/sfnt/sfobjs.c (sfnt_init_face): Remove second test for - `num_instances', which will always succeed. + * src/type1/t1load.c (T1_Set_MM_Blend, T1_Set_MM_Design): Handle + `FT_FACE_FLAG_VARIATION'. -2017-03-04 Werner Lemberg +2017-10-07 Werner Lemberg - [sfnt] Add `get_name_id' service. + New function `FT_Set_Named_Instance'. - * include/freetype/internal/sfnt.h (TT_Get_Name_ID_Func): New - typedef. - (SFNT_Interface): Add `get_name_id' field. - (FT_DEFINE_SFNT_INTERFACE): Updated. + No effect yet. - * src/sfnt/sfdriver.c (search_name_id): Rename to... - (sfnt_get_name_id): ... this. - (sfnt_get_ps_name, sfnt_interface): Updated. + * src/base/ftmm.c (FT_Set_Named_Instance): New function. -2017-03-04 Werner Lemberg + * include/freetype/ftmm.h: Updated. - [truetype] Make `TT_Set_MM_Blend' set named instance index. +2017-10-07 Werner Lemberg - * src/truetype/ttgxvar.h (GX_Blend): New array - `normalized_stylecoords'. + Add macros for checking whether a font variation is active. - * src/truetype/ttgxvar.c (TT_Get_MM_Var): Allocate and fill - `normalized_stylecoords'. - (TT_Set_MM_Blend): Check instance tuple and adjust `face_index' - accordingly. + * include/freetype/freetype.h (FT_FACE_FLAG_VARIATION, + FT_IS_VARIATION): New macros. + No effect yet. -2017-03-02 Werner Lemberg +2017-10-07 Werner Lemberg - [truetype] Split off designer/normalized conversion routines. + Add framework for setting named instance in MM service. - * src/truetype/ttgxvar.c (TT_Set_Var_Design): Split off conversion - code designer->normalized coordinates to... - (ft_var_to_normalized): ... New function. - (TT_Get_Var_Design): Split off conversion code normalized->designer - coordinates to... - (ft_var_to_design): ... New function. + * include/freetype/internal/services/svmm.h (FT_Set_Instance_Func): + New function typedef. + (MultiMasters): Add `set_instance' member. + (FT_DEFINE_SERVICE_MULTIMASTERSREC): Updated. -2017-02-28 Werner Lemberg + * src/cff/cffdrivr.c (cff_service_multi_masters), + src/truetype/ttdriver (tt_service_gx_multi_masters), + src/type1/t1driver.c (t1_service_multi_masters): Updated. - [sfnt] Further generalize `sfnt_get_ps_name'; report invalid data. +2017-10-07 Werner Lemberg - * src/sfnt/sfdriver.c (sfnt_ps_map): New array. - (sfnt_is_postscript): New function. - (char_type_func): New typedef. - (get_win_string, get_apple_string): Add argument to specify - character checking function. - Add argument whether argument checking failures should be reported. - Update callers. - (search_name_id): Fix return value. + [type1] Minor code shuffling. -2017-02-23 Werner Lemberg + * src/type1/t1load.c (T1_Set_MM_Blend): Make it a wrapper of... + (t1_set_mm_blend): ...this new function. + (T1_Set_MM_Design): Use `t1_set_mm_blend'. - [sfnt] Split off another bit of `sfnt_get_ps_name'. +2017-10-05 Werner Lemberg - * src/sfnt/sfdriver.c (sfnt_get_ps_name): Split off some - functionality into... - (search_name_id): ... New function. + * src/base/ftobjs.c (ft_glyphslot_preset_bitmap): Fix integer + overflow. -2017-02-23 Werner Lemberg + Reported as - [sfnt] Modularize `sfnt_get_ps_name'. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3539 - * src/sfnt/sfdriver.c (sfnt_get_ps_name): Split off some - functionality into... - (IS_WIN, IS_APPLE): ... New macros. - (get_win_string, get_apple_string): ... New functions. +2017-10-05 Werner Lemberg -2017-02-23 Werner Lemberg + Fix compiler warnings. - [truetype] Minor improvement. + * src/cff/cffdrivr.c (cff_ps_get_font_extra): Avoid code that relies + on numeric overflow. + Add cast. - * src/truetype/ttgload.c (TT_Process_Simple_Glyph, - load_truetype_glyph): Remove unnecessary tests. + * src/smooth/ftsmooth.c (ft_smooth_render_generic): Fix variable + types, add cast. -2017-02-23 Werner Lemberg +2017-10-04 John Tytgat - * include/freetype/internal/tttypes.h (TT_Face): s/isCFF2/is_cff2/. + [cff] Add support for `FSType'. - For orthogonality with other structure field names. + * include/freetype/internal/cfftypes.h (CFF_FontRec): Add + `font_extra' entry. - Update all users. + * src/cff/cffdrivr.c (cff_ps_get_font_extra): New function to + retrieve FSType info from the embedded PostScript data. + (cff_service_ps_info): Register function. -2017-02-22 Alexei Podtelezhnikov + * src/cff/cffload.c (cff_font_done): Free `font_extra'. - * src/smooth/ftgrays.c (gray_hline): Improve code. +2017-09-30 Alexei Podtelezhnikov -2017-02-20 Dominik Röttsches + Signedness fixes in bitmap presetting. - Fix some `ttnameid.h' entries (#50313). + Reported as - * include/freetype/ttnameid.h: - s/TT_MS_LANGID_SPANISH_INTERNATIONAL_SORT/TT_MS_LANGID_SPANISH_SPAIN_INTERNATIONAL_SORT/, - s/TT_MS_LANGID_MONGOLIAN_MONGOLIA_MONGOLIA/TT_MS_LANGID_MONGOLIAN_MONGOLIA_MONGOLIAN/. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3514. -2017-02-20 Werner Lemberg + * src/raster/ftrend1.c (ft_raster1_render): Explicitly signed height. + * src/smooth/ftsmooth.c (ft_smooth_render_generic): Ditto. + * src/base/ftobjs.c (ft_glyphslot_preset_bitmap): Explicitly unsigned + subtraction. - [cff] Finish support for `random' operator. +2017-09-29 Alexei Podtelezhnikov - * src/cff/cfftypes.h (CFF_SubFontRec): Add `random' field. + Bitmap metrics presetting [2/2]. - * src/cff/cffobjs.c: Updated. - (cff_driver_init): Initialize random seed value. + * src/base/ftobjs.c (FT_Load_Glyph): Preset the bitmap metrics when + appropriate but `FT_Render_Glyph' is not called. + * include/freetype/freetype.h (FT_GlyphSlotRec): Document the change. - * src/cff/cffload.c (cff_random): New function. - (cff_subfont_load): Add `face' argument. - Update all callers. - Initialize random number generator with a proper seed value. - (cff_font_load): Add `face' argument. - Update all callers. +2017-09-28 Alexei Podtelezhnikov - * src/cff/cffload.h: Updated. + [smooth, raster] Miscellaneous cleanups. - * src/cff/cf2intrp.c (CF2_FIXME): Removed. - (cf2_interpT2CharString) : Implement opcode. + * src/raster/ftrend1.c (ft_raster1_render): Clean up the exit. + * src/smooth/ftsmooth.c (ft_smooth_render_generic): Reduce + translations and clean up the exit. + (ft_smooth_render_lcd, ft_smooth_render_lcd): Remove unused `error'. - * src/cff/cffgload.c (cff_decoder_parse_charstrings): Don't - initialize random seed value. - : Use new random seed framework. +2017-09-28 Ben Wagner -2017-02-20 Werner Lemberg + [truetype] Really, really fix #52082. - [cff] Sanitize `initialRandomSeed'. + * src/truetype/ttinterp.c (Ins_MDRP): Correct conditional. - * src/cff/cffload.c (cff_load_private_dict): Make - `initial_random_seed' value always positive. +2017-09-28 Werner Lemberg -2017-02-20 Werner Lemberg + * src/psaux/psintrp.c (cf2_doStems): Fix integer overflow. - [cff] Introduce `random-seed' property (2/2). + Reported as - * src/base/ftobjs.c: Include `FT_CFF_DRIVER_H'. - (open_face): Initialize `face->internal->random_seed'. - (FT_Face_Properties): Handle `FT_PARAM_TAG_RANDOM_SEED'. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3510 - * src/cff/cffdrivr.c (cff_property_set): Handle `random-seed' - property. +2017-09-28 Ewald Hew -2017-02-20 Werner Lemberg + * src/cid/cidgload.c (cid_slot_load_glyph): Fix memory leak. - [cff] Introduce `random-seed' property (1/2). + Reported as - We need this for support of the `random' operator. + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3489 - * include/freetype/ftcffdrv.h (FT_PARAM_TAG_RANDOM_SEED): New macro. +2017-09-28 Alexei Podtelezhnikov - * include/freetype/internal/ftobjs.h (FT_Face_InternalRec): New - field `random_seed'. + Bitmap metrics presetting [1/2]. - * src/cff/cffobjs.h (CFF_DriverRec): New field `random_seed'. + This mainly just extracts the code for presetting the bitmap metrics + from the monochrome, grayscale, and LCD renderers into a separate + function. -2017-02-17 Werner Lemberg + * src/base/ftobjs.c (ft_glyphslot_preset_bitmap): New function that + calculates prospective bitmap metrics for the given rendering mode. + * include/freetype/internal/ftobjs.h (ft_glyphslot_preset_bitmap): + Declare it. - Remove clang warnings. + * src/base/ftlcdfil.c (ft_lcd_padding): New helper function that adds + padding to CBox taking into account pecularities of LCD rendering. + * include/freetype/ftlcdfil.h (ft_lcd_padding): Declare it. - * src/autofit/aflatin.c (af_latin_sort_blue): Add missing `static' - keyword. + * src/raster/ftrend1.c (ft_raster1_render): Reworked to use + `ft_glyphslot_preset_bitmap'. + * src/smooth/ftsmooth.c (ft_smooth_render_generic): Ditto. + (ft_smooth_render_lcd, ft_smooth_render_lcd): The pixel_mode setting + is moved to `ft_glyphslot_preset_bitmap'. - * src/base/ftmm.c (FT_Set_Var_Design_Coordinates, - FT_Set_MM_Blend_Coordinates, FT_Set_Var_Blend_Coordinates): - Initialize some variables. +2017-09-28 Ewald Hew -2017-02-16 Nikolaus Waxweiler - Werner Lemberg + [psaux] Fix compiler warning. - Add face property for stem darkening. + * src/psaux/pshints.c (cf2_hintmap_dump): Add switch for tracing + code. - * include/freetype/ftautoh.h (FT_PARAM_TAG_STEM_DARKENING): New - macro. +2017-09-27 Werner Lemberg - * include/freetype/internal/ftobjs.h (FT_Face_InternalRec): Add - `no_stem_darkening' field. + * src/sfnt/ttload.c (tt_face_load_font_dir): Fix compiler warning. - * src/autofit/afloader.c (af_loader_load_glyph), - src/autofit/afmodule.c (af_property_set): Updated. +2017-09-25 Werner Lemberg - * src/base/ftobjs.c: Include FT_AUTOHINTER_H. - (ft_open_face_internal): Updated. - (FT_Face_Properties): Handle FT_PARAM_TAG_STEM_DARKENING. + [psaux] Fix compiler warnings. - * src/cff/cf2ft.c (cf2_decoder_parse_charstrings): Updated. + * src/psaux/psft.c (cf2_initLocalRegionBuffer): Remove redundant + test. - * src/cff/cffdrivr.c (cff_property_set): Updated. + * src/psaux/psintrp.c (cf2_interpT2CharString) + : Add casts. -2017-02-16 Nikolaus Waxweiler - Werner Lemberg + * src/psaux/psobjs.c (ps_decoder_init): Add cast. - Add face property for LCD filter weights. +2017-09-25 Ewald Hew - * include/freetype/ftlcdfil.h (FT_PARAM_TAG_LCD_FILTER_WEIGHTS, - FT_LCD_FILTER_FIVE_TAPS): New macros. - (FT_LcdFiveTapFilter): New typedef. + [psaux] Minor fixes. - * include/freetype/ftobjs.h (FT_Face_InternalRec) - [FT_CONFIG_OPTION_SUBPIXEL_RENDERING]: Add `lcd_weights' field. - (FT_Bitmap_LcdFilterFunc): Change third argument to weights array. - (ft_lcd_filter_fir): New prototype. - (FT_LibraryRec): Updated. + * include/freetype/internal/psaux.h, src/psaux/psobjs.{c,h}: + Rearrange `ps_builder_init' arguments to conventional order. - * src/base/ftlcdfil.c (_ft_lcd_filter_fir): Renamed to... - (ft_lcd_filter_fir): ... this base function. - Updated. - (_ft_lcd_filter_legacy): Updated. - (FT_Library_SetLcdFilterWeights, FT_Library_SetLcdFilter): Updated. + * src/psaux/psft.c (cf2_decoder_parse_charstrings): Add a check and + notice for `SubFont' in Type 1 mode. - * src/base/ftobjs.c (ft_open_face_internal): Updated. - (FT_Face_Properties): Handle FT_PARAM_TAG_LCD_FILTER_WEIGHTS. +2017-09-25 Ewald Hew - * src/smooth/ftsmooth.c (ft_smooth_render_generic) - [FT_CONFIG_OPTION_SUBPIXEL_RENDERING]: Handle LCD weights from - `FT_Face_Internal'. + [psaux] Move `psdecode' into `psobjs'. -2017-02-14 Nikolaus Waxweiler - Werner Lemberg + As the former only contains a single procedure, move it into + `psobjs' for simplicity. Also change the parameter order to the + conventional one. + + * src/psaux/psdecode.c (ps_decoder_init): Moved to... + * src/psaux/psobjs.c: ...Here. + * src/psaux/psdecode.h, src/psaux/psobjs.h: Ditto. + + * include/freetype/internal/psaux.h (PSAux_ServiceRec): Update + `ps_decoder_init' function signature. + + * src/cff/cffgload.c, src/cid/cidgload.c, src/type1/t1gload.c: + Update calls. - Add new function `FT_Face_Properties'. + * src/psaux/psaux.c, src/psaux/psauxmod.c: Update includes. - This commit provides the framework, to be filled with something - useful in the next commits. + * src/psaux/Jamfile (_sources), src/psaux/rules.mk (PSAUX_DRV_SRC): + Update file references. - * include/freetype/freetype.h (FT_Face_Properties): Declare. +2017-09-25 Ewald Hew - * src/base/ftobjs.c (FT_Face_Properties): New function. + [psaux] Fix Type 1 hinting. -2017-02-13 Werner Lemberg + Type 1 hinting breaks sometimes when mid-charstring hints should + have been in the initial hintmap. This fix adds a preprocessing + pass that reads all hints and builds the correct initial hintmap + first, before proceeding to build the glyph outline. - [autofit] Prevent overlapping blue zones. + * src/psaux/psintrp.c (cf2_interpT2CharString): New + `initial_map_ready' boolean flag. + Ignore outline commands and hint changes on first pass. + : Add section to build hintmap and rewind. - Problem reported as +2017-09-25 Ewald Hew - https://github.com/google/fonts/issues/632 + [psaux] Add tracing for hints. - The font in question (Nunito) has values 705 and 713 for the - reference and overshoot values, respectively, of the first blue - zone. Blue zone 2, however, has value 710 for both the reference - and overshoot. At 12ppem, reference and overshoot of blue zone 0 - becomes 8px, while blue zone 2 becomes 9px. + * src/psaux/pshints.c (cf2_hintmap_dump): New function. + (cf2_hintmap_insertHint): Trace incoming and inserted hints. + (cf2_hintmap_build): Dump hintmap before and after hint adjustment. - A peculiarity of this font is that the tops of isolated vertical - stems like `N' have a slight overshoot also. The auto-hinter tries - to find the nearest blue zone using the *original* coordinates. For - vertical stems, this is value 713. For normal horizontal tops like - in character `E', this is value 710. Since value 713 is mapped to - 8px but value 710 to 9px, `N' and similar characters are one pixel - higher than `E', which looks very bad. +2017-09-25 Ewald Hew - This commit sanitizes blue zones to avoid such a behaviour. + [psaux] Minor fixes. - * src/autofit/aflatin.c (af_latin_sort_blue): New function. - (af_latin_metrics_init_blues): Sort blue values and remove overlaps. + * src/psaux/psintrp.c (cf2_interpT2CharString): Fix check for pop + results. + s/font->decoder/decoder/ where necessary. + : Use + offset parameter in `cf2_doStems' instead of doing correction for + left-sidebearing. -2017-02-12 Alexei Podtelezhnikov +2017-09-25 Ewald Hew - * src/smooth/ftgrays.c (gray_sweep): Improve code. + [cid] Use the new engine. -2017-02-06 Werner Lemberg + * src/cid/cidgload.c: Update includes. + (cid_load_glyph, cid_slot_load_glyph): Implement changes to glyph + loading code as with `type1' module. - [truetype] Implement `VVAR' table support. +2017-09-25 Ewald Hew - * src/truetype/ttgxvar.h (GX_HVarTable): Renamed to... - (GX_HVVarTable): ...This. - (GX_Blend): Add fields for `VVAR' table handling. - Other minor updates. + [cid] Add Adobe engine configuration. - * src/truetype/ttgxvar.c (ft_var_load_hvar): Renamed to... - (ft_var_load_hvvar): ...This. - Handle VVAR loading also (controlled by an additional parameter). - (tt_hadvance_adjust): Renamed to... - (tt_hvadvance_adjust): ...This. - Handle application of advance height also (controlled by an - additional parameter). - (tt_hadvance_adjust, tt_vadvance_adjust): Wrappers for - `tt_hvadvance_adjust'. + This is similar to what was done in the `type1' module. - * src/truetype/ttdriver.c (tt_service_metrics_variations): Updated. + * src/cid/cidriver.c (t1cid_driver_class): Update declaration. + * src/cid/cidobjs.c: Include FT_TYPE1_DRIVER_H. + (cid_driver_init): Update code. -2017-02-05 Werner Lemberg +2017-09-25 Ewald Hew - [autofit] Use better blue zone characters for lowercase latin. + [psaux] Change subfont synthesis for CID fonts. - The number of lowercase characters for computing the top flat blue - zone value was too small (in most cases only `x' and `z'). If one - of the two characters has a large serif, say, it can happen that - FreeType must select between two different values, having a 50% - chance to use the wrong one. As a result, rendering at larger PPEM - values could yield uneven lowercase glyph heights. + Change `t1_make_subfont' to take in the Private dict record as an + argument. This is because Type 1 and CID font records in FreeType + have this in different places. - Problem reported by Christoph Koeberlin . + * src/psaux/psobjs.c (t1_make_subfont): Change `T1_Face' to + `FT_Face' so that CID is also accepted. + Take `PS_Private' as an argument and let caller figure out where the + Private dict actually is. + Update references. - * src/autofit/afblue.dat (AF_BLUE_STRING_LATIN_SMALL): Replaced - with... - (AF_BLUE_STRING_LATIN_SMALL_TOP, AF_BLUE_STRING_LATIN_SMALL_BOTTOM): - ... New, extended sets. - (AF_BLUE_STRINGSET_LATN): Updated. + * include/freetype/internal/psaux.h, src/psaux/psobjs.h: Update + declaration. - * src/autofit/afblue.c, scr/autofit/afblue.h: Regenerated. + * src/type1/t1gload.c (T1_Parse_Glyph_And_Get_Char_String): Update + call. -2017-02-04 Werner Lemberg +2017-09-25 Ewald Hew - Make `freetype-config' a wrapper of `pkg-config' if possible. + [type1] Switch to Adobe engine. - Based on ideas taken from + * src/type1/t1objs.c (T1_Driver_Init): Set default to Adobe engine. - http://pkgs.fedoraproject.org/cgit/rpms/freetype.git/tree/freetype-multilib.patch - http://pkgs.fedoraproject.org/cgit/rpms/freetype.git/tree/freetype-2.5.3-freetype-config-prefix.patch +2017-09-25 Ewald Hew - * builds/unix/freetype-config.in: Rewritten. Use `pkg-config' to - set output variables if program is available. + [psaux] Extend Adobe interpreter (seac). - * docs/CHANGES, docs/freetype-config.1: Updated. + This concludes the changes needed to add Type 1 support. -2017-02-04 Werner Lemberg + * src/psaux/psintrp.c: Update includes. + (cf2_interpT2CharString) : Implement this similarly to + implied seac for CFF. - * builds/unix/unix-def.in (freetype-config): Fix permissions. + * src/psaux/t1decode.c (t1_lookup_glyph_by_stdcharcode_ps): New + function to look up the glyph index. -2017-02-03 Werner Lemberg + * src/psaux/psft.c (cf2_getT1SeacComponent, + cf2_freeT1SeacComponent): New functions to get the charstrings for + seac components. - * src/autofit/afglobal.c (af_face_globals_free): Erase useless code. + * src/psaux/t1decode.h, src/psaux/psft.h: Update declarations. -2017-02-03 Werner Lemberg +2017-09-25 Ewald Hew - * include/freetype/ftgasp.h (FT_GASP_SYMMETRIC_GRIDFIT): Fix value. + [psaux] Extend Adobe interpreter (flex in callothersubr). - Reported by Behdad. + * src/psaux/psintrp.c (cf2_interpT2CharString) + : Fix Flex feature handling (OtherSubrs 0, 1, + 2). + : Do not actually move the `glyphPath' while doing + flex. This is to avoid closing the current contour. -2017-02-02 Werner Lemberg +2017-09-25 Ewald Hew - [truetype] Fix MVAR post-action handling. + [psaux] Extend Adobe interpreter (callothersubr). - Reported as + * src/psaux/psintrp.c (cf2_interpT2CharString) + : Copy code from + `t1_decoder_parse_charstrings' (in `t1decode.c'). + OtherSubr 3 (change hints) should reset the hintmask, so that the + new hints are applied. + Fix function calls and stack access. - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=509 +2017-09-25 Ewald Hew - * src/truetype/ttobjs.c (tt_size_reset): Do nothing for CFF2. This - is important to make `tt_size_reset_iterator' (called in - `tt_apply_mvar') always work. + [psaux] Extend Adobe interpreter (pop). -2017-02-02 Werner Lemberg + * src/psaux/psintrp.c (cf2_interpT2CharString): Change how unhandled + OtherSubr results are stored. Implement the PostScript stack using + an array. + : Ensure that the stack is not cleared after getting + `OtherSubr' results. + Fix stack access. - Make compilation with FT_CONFIG_OPTION_PIC work again. +2017-09-25 Ewald Hew - All code committed here is guarded with `FT_CONFIG_OPTION_PIC'. + [psaux] Extend Adobe interpreter (callsubr). - * include/freetype/internal/services/svmetric.h - (FT_DEFINE_SERVICE_METRICSVARIATIONSREC): Remove trailing semicolon. + * src/psaux/psintrp.c (cf2_interpT2CharString) : + Type 1 mode. - * src/autofit/aflatin.c (af_latin_hints_compute_edges, - af_latin_hint_edges): Provide `globals' variable. + * src/psaux/psft.c (cf2_initLocalRegionBuffer): Add Type 1 mode. - * src/autofit/afloader.c (af_loader_load_glyph): Remove shadowing - variable. +2017-09-25 Ewald Hew - * src/autofit/afmodule.c (AF_SCRIPT_CLASSES_GET, - AF_STYLE_CLASSES_GET): Redefine. + [psaux] Extend Adobe interpreter (div, four-byte numbers). - * src/autofit/aftypes.h (AF_DEFINE_WRITING_SYSTEM_CLASS): Fix typo. + * src/psaux/psintrp.c (cf2_interpT2CharString) : Add + Type 1 mode. Type 1 requires large integers to be followed by + `div'; cf. `Adobe Type 1 Font Format', section 6.2. + : Push Type 1 four-byte numbers as `Int' always. This is + to ensure `div' and `callsubr' get values they can use. - * src/cff/cffparse.c (CFF_FIELD_BLEND): Provide it. +2017-09-25 Ewald Hew - * src/cff/cffpic.h (CffModulePIC): Fix typo. + [psaux] Extend Adobe interpreter (hints). -2017-01-31 Alexei Podtelezhnikov + * src/psaux/psintrp.c (cf2_interpT2CharString) : Add correction for left sidebearing in Type 1 mode. + Allow adding hints mid-charstring. + : Translate into equivalent commands + for three normal stem hints. This requires some recalculation of + stem positions. + Correction for left sidebearing. - * src/smooth/ftgrays.c (gray_render_scanline): Improve code. +2017-09-25 Ewald Hew -2017-01-31 Werner Lemberg + [psaux] Extend Adobe interpreter (hsbw, sbw). - [cff] Provide metrics variation service interface (#50196). + * src/psaux/psintrp.c (cf2_doStems): `hsbw' or `sbw' must be the + first operation in a Type 1 charstring. + (cf2_interpT2CharString): Remove unused variables. + : `hsbw' or `sbw' + must be the first operation in a Type 1 charstring. + : Fix data access and add correction for + left sidebearing. - Only now I've got an OTF with an HVAR table for testing... +2017-09-25 Ewald Hew - The code in `ftmm.c' uses `FT_FACE_LOOKUP_SERVICE' to get the - metrics variations interface. However, this didn't work with - `FT_FACE_FIND_GLOBAL_SERVICE' used in `sfnt_init_face'. + [psaux] Extend Adobe interpreter (setcurrentpoint). - * src/cff/cffdrivr.c: Include FT_SERVICE_METRICS_VARIATIONS_H. - (cff_hadvance_adjust, cff_metrics_adjust): Wrapper functions for - metric service functions from the `truetype' module. - (cff_service_metrics_variations): New service. - (cff_services): Updated. + * src/psaux/psintrp.c (cf2_interpT2CharString) + : Fix stack access. - * src/cff/cffpic.h (CFF_SERVICE_METRICS_VAR_GET): New macro. - [FT_CONFIG_OPTION_PIC]: Synchronize code. +2017-09-25 Ewald Hew - * src/sfnt/sfobjs.c (sfnt_init_face): Replace call to - FT_FACE_FIND_GLOBAL_SERVICE with `ft_module_get_service' to always - load the service from the `truetype' module. + [psaux] Extend Adobe interpreter (closepath). -2017-01-31 Werner Lemberg + * src/psaux/psintrp.c (cf2_interpT2CharString) : + Use the right builder function. We can use the `haveWidth' boolean + already present, instead of implementing `parse_state'. - Add framework to support services with 9 functions. +2017-09-25 Ewald Hew - * include/freetype/internal/ftserv.h (FT_DEFINE_SERVICEDESCREC9): - New macro. + [psaux] Add Type 1 operations to Adobe CFF interpreter. -2017-01-31 Werner Lemberg + The following Type 1 specific ops have been added (copied from + `t1decode'): - [base] Fix error handing in MM functions. + closepath + vstem3 + hstem3 + seac + sbw + callothersubr + pop + setcurrentpoint + hsbw - * src/base/ftmm.c (FT_Set_Var_Design_Coordinates, - FT_Set_MM_Blend_Coordinates, FT_Set_Var_Blend_Coordinates): - Implement it. + The following require a Type 1 mode, because of differences in + specification: -2017-01-31 Werner Lemberg + hstem + vstem + vmoveto + callsubr + div + rmoveto + hmoveto + Numbers - [truetype] Fix sanity check for `gvar' table (#50184). + The subsequent commits will implement these changes and adapt + accesses of data and objects to the new interpreter. + + NOTE: Will not compile in the meantime! + + * src/psaux/psintrp.c: Add opcodes to enum. + (cf2_interpT2CharString): Copy relevant code over from + `t1_decoder_parse_charstrings' (in `t1decode.c'). - * src/truetype/ttgxvar.c (ft_var_load_gvar): There might be missing - variation data for some glyphs. +2017-09-25 Ewald Hew -2017-01-31 Werner Lemberg + [type1] Fixes for rendering. - [autofit] Avoid uninitialized jumps (#50191). + The Type 1 advance width calculation passes null for glyph slot, + etc, which can cause null pointer access in the new interpreter. + Fall back to the old one for now. - * src/autofit/afcjk.c (af_cjk_metrics_check_digits), - src/autofit/aflatin.c (af_latin_metrics_check_digits): Initialize - `advance'. + Fix the large glyph retry code and ensure hinting and scaling flags + are set properly. -2017-01-27 Werner Lemberg + * src/type1/t1gload.c (T1_Parse_Glyph_And_Get_Char_String): Add a + check for metrics_only. + Set the `force_scaling' flag. + (T1_Parse_Glyph): Updated. + (T1_Load_Glyph): Add `hinting' and `scaled' flags. - s/GB2312/PRC/. +2017-09-25 Ewald Hew - * include/freetype/freetype.h (FT_ENCODING_PRC): New enum value. - (FT_ENCODING_GB2312): Deprecated. + [psaux] Add missing objects (2/2). - * include/freetype/ttnameid.h (TT_MS_ID_PRC): New macro. - (TT_MS_ID_GB2312): Deprecated. + Synthesize a `SubFont' object for Type 1 fonts. This is used in the + interpreter to access Private dict data, which are stored in + different places for Type 1 and CFF. This allows the same data to + be used in either mode. - * src/sfnt/sfobjs.c (sfnt_find_encoding): Updated. + * src/psaux/psobjs.c (t1_make_subfont): New procedure to copy + required values to a dummy `CFF_SubFont' object. This is similar to + `cff_make_private_dict'. + * src/psaux/psobjs.h: Add the new declaration. - * docs/CHANGES: Updated. + * include/freetype/internal/psaux.h, src/psaux/psauxmod.c: Ditto. + Add this to the PSAux Service for future use with CID fonts. -2017-01-26 Werner Lemberg + * src/type1/t1gload.c: Include FT_INTERNAL_CFF_TYPES_H. + (T1_Parse_Glyph_And_Get_Char_String): Add the call. - [base] Add `FT_Get_Sfnt_LangTag' function. +2017-09-25 Ewald Hew - * include/freetype/ftsnames.h (FT_SfntLangTag): New structure. - (FT_Get_Sfnt_LangTag): New declaration. + [psaux] Add missing objects for Type 1 (1/2). - * src/base/ftsnames.c (FT_Get_Sfnt_LangTag): New function. + Move `CF2_Font' instance to `PS_Decoder'. This is the context for + the interpreter and since it is currently stored in `CFF_Font', is + unavailable in Type 1 mode. - * docs/CHANGES: Updated. + * include/freetype/internal/psaux.h (T1_Decoder, PS_Decoder): New + `cf2_instance' field. -2017-01-26 Werner Lemberg + * src/psaux/psdecode.c (ps_decoder_init): Copy `cf2_instance' to + `PS_Decoder'. - [sfnt] Support `name' table format 1. + * src/psaux/t1decode.c (t1_decoder_done): Add finalization code. + + * src/psaux/psft.c (cf2_decoder_parse_charstrings): Update accesses. - * include/freetype/internal/tttypes.h (TT_LangTagRec): New - structure. - (TT_NameTableRec): Add fields `numLangTagRecords' and `langTags'. +2017-09-25 Ewald Hew - * src/sfnt/ttload.c (tt_face_load_name): Add support for language - tags. - Reduce array size of name strings in case of invalid entries. - (tt_face_free_name): Updated. + Allow `type1' module to use the Adobe engine. - * docs/CHANGES: Updated. + Add the callback and some conditionals to switch between the two + engines. -2017-01-25 Werner Lemberg + * include/freetype/internal/psaux.h (T1_Decoder_FuncsRec): Change + function declarations. + * src/psaux/psauxmod.c (T1_Decoder_FuncsRec): Register the + callbacks. - [sfnt] s/TT_NameEntry/TT_Name/. + * src/psaux/psobjs.c (ps_builder_add_point): Add conditionals for + number conversion. - * include/freetype/internal/tttypes.h (TT_NameEntryRec): Renamed - to... - (TT_NameRec): This. - (TT_NameTableRec): Updated. + * src/type1/t1gload.c (T1_Parse_Glyph_And_Get_Char_String): Add code + to choose which renderer to use. - * src/base/ftsnames.c (FT_Get_Sfnt_Name): Updated. + * src/cid/cidgload.c (cid_load_glyph): Update call. + * src/base/ftobjs.c, src/psaux/psobjs.c, src/type1/t1gload.c: Update + includes. - * src/sfnt/sfdriver.c (sfnt_get_ps_name): Updated. +2017-09-25 Ewald Hew - * src/sfnt/sfobjs.c (tt_name_entry_ascii_from_utf16, - tt_name_entry_ascii_from_other): Renamed to... - (tt_name_ascii_from_utf16, tt_name_entry_ascii_from_other): This, - respectively. - (TT_NameEntry_ConvertFunc): Renamed to... - (TT_Name_ConvertFunc): This. - (tt_face_get_name): Updated. + [type1] Add Adobe engine configuration. - * src/sfnt/ttload.c (tt_face_load_name, tt_face_free_name): - Updated. + Use the previously changed PS_Driver in type1 module to store + hinting engine configuration. + + * include/freetype/ftt1drv.h: New file. + Duplicate and rename config options from CFF. + * include/freetype/config/ftheader.h (FT_TYPE1_DRIVER_H): New macro. + + * src/type1/t1driver.c (t1_driver_class): Update declaration. + * src/type1/t1objs.c: Include FT_TYPE1_DRIVER_H. + (T1_Driver_Init): Update code. -2017-01-24 Werner Lemberg +2017-09-25 Ewald Hew - [sfnt] Fix Postscript name service for symbol fonts. + [cff] Move and rename `CFF_Driver'. - * src/sfnt/sfdriver.c (sfnt_get_ps_name): Accept PID/EID=3/0 - entries also. + This is so that we can use the same hinting engine parameters for + Type 1. -2017-01-24 Werner Lemberg + * include/freetype/internal/cffotypes.h (CFF_Driver): Rename and + move to... + * include/freetype/internal/psaux.h (PS_Driver): ...here. - [truetype] For OpenType 1.7: s/preferred/typographic/ (sub)family. + * src/cff/cffdrivr.c, src/cff/cffgload.c, src/cff/cffload.c, + src/cff/cffobjs.c, src/cff/cffobjs.h, src/psaux/psft.c, + src/psaux/psobjs.c: Update references. - * include/freetype/ftsnames.h - (FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_FAMILY, - FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_SUBFAMILY): New macros. - (FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY, - FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY): Deprecated. +2017-09-25 Ewald Hew - * include/freetype/ttnameid.h (TT_NAME_ID_TYPOGRAPHIC_FAMILY, - TT_NAME_ID_TYPOGRAPHIC_SUBFAMILY): New macros. - (TT_NAME_ID_PREFERRED_FAMILY, TT_NAME_ID_PREFERRED_SUBFAMILY): - Deprecated. + [psaux, type1] Reorganize object fields. - * src/sfnt/sfobjs.c (sfnt_load_face): Updated. + Make some fields more generic, so that we can access them the same + way regardless of Type 1 or CFF. - * docs/CHANGES: Updated. + * include/freetype/internal/psaux.h (PS_Builder): Change `TT_Face' + to `FT_Face'. + Remove unused fields. + + * src/psaux/psft.c: Update all accesses of `PS_Builder.face'. + Add some asserts to guard against casting `T1_Face' as `TT_Face'. + + * src/type1/t1objs.h (T1_GlyphSlot): Reorder fields to follow + `CFF_GlyphSlot', so that we can pretend they are the same in the + interpreter. + + * src/psaux/psobjs.c (ps_builder_init, ps_builder_add_point): + Updated with above changes. + +2017-09-25 Ewald Hew + + [psaux] Prepare for Type 1 mode. + + Add some checks for Type 1 data passing through. + + * src/psaux/psfont.h (CF2_Font): Add `isT1' flag. + * src/psaux/psfont.c (cf2_font_setup): Skip the variations and blend + code which is not applicable for Type 1. + + * src/psaux/psft.c (cf2_decoder_parse_charstrings): Avoid accessing + `decoder->cff' in Type 1 mode. + Copy `is_t1' flag to `CF2_Font'. + +2017-09-25 Ewald Hew + + [psaux, cff] Use the new objects. + + * include/freetype/internal/psaux.h, src/psaux/psauxmod.c: Fix + switching between new and old engines. + + * src/cff/cffgload.c, src/cff/cffparse.c: Update calls. + + * src/psaux/psblues.c, src/psaux/psfont.c, src/psaux/psfont.h, + src/psaux/psft.c, src/psaux/psft.h, src/psaux/psintrp.c: Update all + to use new objects. + +2017-09-24 Ewald Hew + + [psaux] Objects for new interpreter (part 2). + + Make the new objects copy over values. They are essentially wrapper + types for the different decoders/builders. -2017-01-23 Werner Lemberg + * include/freetype/internal/psaux.h: Update declarations. + (PS_Builder): Add `is_t1' flag. + (PS_Decoder_{Get,Free}_Glyph_Callback): Renamed to... + (CFF_Decoder_{Get,Free}_Glyph_Callback: ... this. + (PS_Decoder): Updated. + Add `t1_parse_callback' member. + (PSAux_ServiceRec): Add `ps_decoder_init' member. - [base] Add `FT_Set_Default_Properties' (#49187). + * src/psaux/psdecode.h, src/psaux/psobjs.h: Update declarations. - * include/freetype/ftmodapi.h: Add declaration. + * src/psaux/psdecode.c, src/psaux/psobjs.c: Implement copy with two + modes. + + * src/psaux/psauxmod.c: Add builder and decoder functions to `PSAux' + service. + +2017-09-24 Ewald Hew + + [psaux] Add objects for new interpreter. + + Introduce `PS_Decoder' and `PS_Builder' which include all fields + from either Type 1 or CFF decoders/builders. - * src/base/ftinit.c (ft_set_default_properties): Renamed to... - (FT_Set_Default_Properties): ... this. - (FT_Init_FreeType): Updated. + * include/freetype/internal/psaux.h (PS_Builder, PS_Decoder): New + structs. - * docs/CHANGES: Updated. + * src/psaux/psobjs.c, src/psaux/psobjs.h: Add `PS_Builder' + functions. -2017-01-23 Werner Lemberg + * src/psaux/psdecode.c, src/psaux/psdecode.h: New files to hold + `PS_Decoder' initialization functions. - [truetype] Minor updates for OpenType 1.8.1. + * src/psaux/psaux.c, src/psaux/Jamfile (_sources), + src/psaux/rules.mk (PSAUX_DRV_SRC): Updated. - * src/truetype/ttgxvar.h (GX_MVarTable): `axisCount' has been - removed from the specification; it is now reserved. +2017-09-24 Ewald Hew - * src/truetype/ttgxvar.c (ft_var_load_mvar): Updated. - (GX_FVar_Head): Remove `countSizePairs'; the corresponding data - field in the `MVAR' table is now reserved. - (fvar_fields): Updated. + [psaux] Rename files. -2017-01-23 Werner Lemberg + Replace the `cf2' file name prefix with `ps' as the Adobe engine + will be used for both PostScript Types 1 and 2 (CFF) instead of just + CFF. - [truetype] Avoid segfault for invalid variation data. + s/cf2/ps/ for all following. - * src/truetype/ttgxvar.c (ft_var_load_item_variation_store): Assure - `itemCount' is not zero. + * src/psaux/cf2*: Rename files. + * src/psaux/*: Update includes. - Reported as + * src/psaux/Jamfile (_sources), src/psaux/rules.mk (PSAUX_DRC_SRC, + PSAUX_DRV_H): Update file references. - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=441 +2017-09-24 Ewald Hew -2017-01-20 Werner Lemberg + [psaux] Minor fix. - * src/truetype/ttinterp.c (TT_RunIns): Adjust loop detector limits. + Use `MultiMasters' service in `psaux' instead of a call to `cff'. + The project builds if CFF_CONFIG_OPTION_OLD_ENGINE is not defined. -2017-01-17 Werner Lemberg + * src/psaux/cf2ft.c: Update includes. + (cf2_getNormalizedVector): Use `mm->get_var_blend' instead of + `cff_get_var_blend'. - * include/freetype/ttnameid.h: Updated to OpenType 1.8.1. +2017-09-24 Ewald Hew - (TT_APPLE_ID_FULL_UNICODE): New macro. + [psaux, cff] Move `cff_random' into `psaux' service. - (TT_MS_LANGID_BOSNIAN_BOSNIA_HERZ_CYRILLIC, - TT_MS_LANGID_UPPER_SORBIAN_GERMANY, - TT_MS_LANGID_LOWER_SORBIAN_GERMANY, TT_MS_LANGID_IRISH_IRELAND, - TT_MS_LANGID_INUKTITUT_CANADA_LATIN, TT_MS_LANGID_BASHKIR_RUSSIA, - TT_MS_LANGID_LUXEMBOURGISH_LUXEMBOURG, - TT_MS_LANGID_GREENLANDIC_GREENLAND, TT_MS_LANGID_MAPUDUNGUN_CHILE, - TT_MS_LANGID_MOHAWK_MOHAWK, TT_MS_LANGID_BRETON_FRANCE, - TT_MS_LANGID_OCCITAN_FRANCE, TT_MS_LANGID_CORSICAN_FRANCE, - TT_MS_LANGID_ALSATIAN_FRANCE, TT_MS_LANGID_YAKUT_RUSSIA, - TT_MS_LANGID_KICHE_GUATEMALA, TT_MS_LANGID_KINYARWANDA_RWANDA, - TT_MS_LANGID_WOLOF_SENEGAL, TT_MS_LANGID_DARI_AFGHANISTAN): New - macros. + NOTE: Does not compile! - (TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_CYRILLIC): Fix value. + Minor fix to allow both `cff' and `psaux' to use `cff_random'. - (TT_MS_LANGID_GERMAN_LIECHTENSTEIN, TT_MS_LANGID_CATALAN_CATALAN, - TT_MS_LANGID_CHINESE_MACAO, TT_MS_LANGID_SPANISH_SPAIN_MODERN_SORT, - TT_MS_LANGID_KOREAN_KOREA, TT_MS_LANGID_ROMANSH_SWITZERLAND, - TT_MS_LANGID_SLOVENIAN_SLOVENIA, TT_MS_LANGID_BASQUE_BASQUE, - TT_MS_LANGID_SETSWANA_SOUTH_AFRICA, - TT_MS_LANGID_ISIXHOSA_SOUTH_AFRICA, - TT_MS_LANGID_ISIZULU_SOUTH_AFRICA, TT_MS_LANGID_KAZAKH_KAZAKHSTAN, - TT_MS_LANGID_KYRGYZ_KYRGYZSTAN, TT_MS_LANGID_KISWAHILI_KENYA, - TT_MS_LANGID_TATAR_RUSSIA, TT_MS_LANGID_ODIA_INDIA, - TT_MS_LANGID_MONGOLIAN_PRC, TT_MS_LANGID_TIBETAN_PRC, - TT_MS_LANGID_WELSH_UNITED_KINGDOM, TT_MS_LANGID_GALICIAN_GALICIAN, - TT_MS_LANGID_SINHALA_SRI_LANKA, TT_MS_LANGID_TAMAZIGHT_ALGERIA, - TT_MS_LANGID_SESOTHO_SA_LEBOA_SOUTH_AFRICA, TT_MS_LANGID_YI_PRC, - TT_MS_LANGID_UIGHUR_PRC): New aliases. + * src/cff/cffload.c (cff_random): Move to... + * src/psaux/psobjs.c: Here. + * src/cff/cffload.h: Move corresponding declaration to + `src/psaux/psobjs.h'. - Remove commented out code. + * include/freetype/internal/psaux.h (PSAux_ServiceRec): Register the + function here... + * src/psaux/psauxmod.c: And here. - (TT_NAME_ID_LIGHT_BACKGROUND, TT_NAME_ID_DARK_BACKGROUND, - TT_NAME_ID_VARIATIONS_PREFIX): New macros. + * src/cff/cffload.c, src/psaux/cf2intrp.c: Update code. - (HAVE_LIMIT_ON_IDENTS): Remove macro (which was useless since many - years), use guarded long macros by default and define short versions - as aliases for the long ones. +2017-09-24 Ewald Hew -2017-01-15 Werner Lemberg + [cff] Move struct declarations to `freetype/internal'. - * src/truetype/ttgxvar.c (tt_apply_var): Handle underline parameters - also. + NOTE: Does not compile! -2017-01-11 Werner Lemberg + This is so that the CFF functions moved to `psaux' can access the + same structs that they need. - * src/base/ftobjs.c (ft_open_face_internal): Improve tracing. + * src/cff/cfftypes.h: Moved to... + * include/freetype/internal/cfftypes.h: ...Here. -2017-01-11 Werner Lemberg + * src/cff/cffobjs.h: Moved the struct declarations to... + * include/freetype/internal/cffotypes.h: ... this new file. - [truetype] Actually use metrics variation service. + * include/freetype/internal/internal.h (FT_INTERNAL_CFF_TYPES_H, + FT_INTERNAL_CFF_OBJECT_TYPES_H): New macros. - * src/base/ftmm.c: Include FT_SERVICE_METRICS_VARIATIONS_H. - (ft_face_get_mvar_service): New auxiliary function to look up - metrics variation service. - (FT_Set_Var_Design_Coordinates, FT_Set_MM_Blend_Coordinates, - FT_Set_Var_Blend_Coordinates): Call metrics variation service. + * src/cff/cffcmap.h, src/cff/cffdrivr.c, src/cff/cffgload.c, + src/cff/cffgload.h, src/cff/cffload.h, src/cff/cffobjs.c, + src/cff/cffobjs.h, src/cff/cffparse.h, src/psaux/psobjs.h, + include/freetype/internal/psaux.h, + include/freetype/internal/services/svcfftl.h: Update includes. - * src/truetype/ttobjs.c (tt_face_init): Use metrics variations for - named instances. + * src/cff/rules.mk (CFF_DRV_H): Updated. -2017-01-11 Werner Lemberg +2017-09-24 Ewald Hew - [truetype] Provide metrics variation service. + [psaux, cff] Add new service for inter-module calls. - * include/freetype/internal/services/svmetric.h - (FT_Metrics_Adjust_Func): Reduce number of necessary parameters. + NOTE: Does not compile! - * src/truetype/ttgxvar.c: Include FT_LIST_H. - (tt_size_reset_iterator): New auxiliary function for... - (tt_apply_var): New function. + This is to allow CFF functions moved to `psaux' to call functions + declared in `src/cff/cffload.h'. - * src/truetype/ttgxvar.h: Updated. + * include/freetype/internal/services/svcfftl.h: New file, setting up + a `CFFLoad' service. - * src/truetype/ttdriver.c (tt_service_metrics_variations): Add - `tt_apply_mvar'. + * include/freetype/internal/ftserv.h (FT_DEFINE_SERVICEDESCREC10, + FT_DEFINE_SERVICEDESCREC): New macros. + (FT_SERVICE_CFF_TABLE_LOAD_H): New macro. - * include/freetype/internal/ftserv.h (FT_ServiceCache): Add metrics - variation service. + * src/cff/cffdrivr.c, src/cff/cffpic.h: Register the new service. -2017-01-11 Werner Lemberg + * src/cff/cfftypes.h (CFF_FontRec), src/psaux/cf2font.h + (CF2_FontRec): Add service interface. - [truetype] Parse `MVAR' table. + * src/cff/cffobjs.c, src/psaux/cf2font.c, src/psaux/cf2ft.c, + src/psaux/cf2intrp.c, src/psaux/cffdecode.c: Use the new service. - * src/truetype/ttgxvar.h (MVAR_TAG_XXX): New macros for MVAR tags. - (GX_Value, GX_MVarTable): New structures. - (GX_Blend): Add it. +2017-09-24 Ewald Hew - * src/truetype/ttgxvar.c (GX_VALUE_SIZE, GX_VALUE_CASE, - GX_GASP_CASE): New macros. - (ft_var_get_value_pointer): New auxiliary function to get a pointer - to a value from various SFNT tables already stored in `TT_Face'. - (ft_var_load_mvar): New function. - (TT_Get_MM_Var): Call it. - (tt_done_blend): Updated. + [psaux, cff] Add callbacks for inter-module calls. -2017-01-11 Werner Lemberg + NOTE: Does not compile! - [truetype] More preparations for MVAR support. + * include/freetype/internal/psaux.h: Add function pointer + declarations. - * src/truetype/ttobjs.c (tt_size_reset): Add argument to make - function only recompute ascender, descender, and height. + * src/psaux/cffdecode.c (cff_decoder_init): Update to take in + callbacks. + * src/psaux/cffdecode.h: Ditto. - * src/truetype/ttobjs.h: Updated. + * src/cff/cffgload.c (cff_compute_max_advance, cff_slot_load): + Update calls to pass in callbacks. + * src/psaux/cf2ft.c, src/psaux/cffdecode.c: Use them. - * src/truetype/ttdriver.c (tt_size_select, tt_size_request): - Updated. +2017-09-24 Ewald Hew -2017-01-09 Werner Lemberg + [psaux, cff] Create new `PSAux' service interface entries. - [pcf] Disable long family names by default. + NOTE: Does not compile! - * include/freetype/config/ftoption.h - (PCF_CONFIG_OPTION_LONG_FAMILY_NAMES): Comment out. + * include/freetype/internal/psaux.h: Include + FT_INTERNAL_TRUETYPE_TYPES_H. + (CFF_Builder_FuncsRec, CFF_Decocer_FuncsRec): New function tables. + (CFF_Builder): Updated. + Fix for forward declaration. + (PSAux_ServiceRec): New field `cff_decoder_funcs'. -2017-01-09 Werner Lemberg + * src/psaux/psauxmod.c (cff_builder_funcs, cff_decoder_funcs): New + function tables. + (PSAux_Interface): Updated. - [pcf] Make long family names configurable. + * include/freetype/internal/tttypes.h (TT_FaceRec): Add `psaux' + service interface. - The change from 2016-09-29 was too radical (except for people using - the openSuSE GNU/Linux distribution). To ameliorate the situation, - PCF_CONFIG_OPTION_LONG_FAMILY_NAMES gets introduced which controls - the feature; if set, a new PCF property option - `no-long-family-names' can be used to switch this feature off. + * src/cff/cffgload.c, src/cff/cffobjs.c, src/cff/cffparse.c: Update + function calls to use psaux service. - * include/freetype/config/ftoption.h, devel/ftoption.h - (PCF_CONFIG_OPTION_LONG_FAMILY_NAMES): New option. +2017-09-24 Ewald Hew - * include/freetype/ftpcfdrv.h: New header file (only containing - comments currently, used for building the documentation). + [psaux, cff] Move CFF builder components into `psaux' module. - * include/freetype/config/ftheader.h (FT_PCF_DRIVER_H): New macro. + NOTE: Does not compile! - * src/pcf/pcf.h (PCF_Driver): Add `no_long_family_names' field. + * src/cff/cffgload.c + (cff_builder_{init,done,add_point,add_point1,add_contour,start_point,close_contour}, + cff_check_points): Move to... + * src/psaux/psobjs.c: Here. - * src/pcf/pcfdrivr.c: Include FT_SERVICE_PROPERTIES_H and - FT_PCF_DRIVER_H. - (pcf_property_set, pcf_property_get): New functions. - (pcf_service_properties): New service. - (pcf_services): Updated. - (pcf_driver_init) [PCF_CONFIG_OPTION_LONG_FAMILY_NAMES]: Handle - `no_long_family_names'. + * src/cff/cffgload.h: Move corresponding declarations to + `src/psaux/psobjs.h'. - * src/pcf/pcfread.c (pcf_load_font): Handle `no_long_family_names' - and PCF_CONFIG_OPTION_LONG_FAMILY_NAMES. + * src/cff/cffgload.h (CFF_Builder): Move struct declaration to... + * include/freetype/internal/psaux.h: Here. - * docs/CHANGES: Updated. +2017-09-24 Ewald Hew -2017-01-09 Werner Lemberg + [psaux, cff] Move CFF decoder components into `psaux' module. - [pcf] Introduce a driver structure. + NOTE: Does not compile! - To be filled later on with something useful. + * src/cff/cffgload.c (CFF_Operator, + CFF_COUNT_{CHECK_WIDTH,EXACT,CLEAR_STACK}, cff_argument_counts, + cff_operator_seac, cff_compute_bias, + cff_lookup_glyph_by_stdcharcode, + cff_decoder_{parse_charstrings,init,prepare}): Move to... + * src/psaux/cffdecode.c: This new file. - * src/pcf/pcf.h (PCF_Driver): New structure. + * src/cff/cffgload.h: Move corresponding declarations to... + * src/psaux/cffdecode.h: This new file. - * src/pcf/pcfdrivr.c (pcf_driver_init, pcf_driver_done): New dummy - functions. - (pcf_driver_class): Updated. + * src/cff/cffgload.h (CFF_MAX_{OPERANDS,SUBRS_CALLS,TRANS_ELEMENTS}, + CFF_Decoder_Zone, CFF_Decoder): Move declarations to... + * include/freetype/internal/psaux.h: Here. -2017-01-08 Werner Lemberg + * src/psaux/cf2ft.h: Update include. - [truetype] Again some GX code shuffling. + * src/psaux/psaux.c, src/psaux/rules.mk (PSAUX_DRV_SRC): Update with + the new file. - We need this later on for MVAR also. +2017-09-24 Ewald Hew - * src/truetype/ttgxvar.c (tt_hadvance_adjust): Split off computing - an item store variation delta into... - (ft_var_get_item_delta): ...new function. + [psaux, cff] Move Adobe's engine components into `psaux' module. -2017-01-08 Werner Lemberg + This is the first patch of a sequence to move the Type 2 charstring + processing capability from the `cff' module to the `psaux' module. - [truetype] Adjust font variation flags for MVAR. + NOTE: Does not compile! - * include/freetype/internal/tttypes.h (TT_FACE_FLAG_VAR_XXX): - Remove all flags related to MVAR; replace it with... - (TT_FACE_FLAG_VAR_MVAR): ...this new macro. - (TT_Face): Remove `mvar_support' field (which was still unused). + * src/cff/cf2*: Move these files to... + * src/psaux/cf2*: Here. -2017-01-06 Werner Lemberg + * src/cff/Jamfile (_sources), src/cff/rules.mk (CFF_DRV_SRC, + CFF_DRV_H), src/cff/cff.c, src/cff/cffgload.c: Remove file + references. - [truetype] More GX code shuffling. + * src/psaux/Jamfile (_sources), src/psaux/rules.mk, src/psaux/psaux.c + (PSAUX_DRV_SRC, PSAUX_DRV_H): Add file references. - We need this later on for MVAR also. +2017-09-24 Alexei Podtelezhnikov - * src/truetype/ttgxvar.c (tt_done_blend): Split off handling of item - variation store into... - (ft_var_done_item_variation_store): ...new function. + Tweak per-face LCD filtering controls. -2017-01-06 Werner Lemberg + Thing are simpler with a NULL-function pointer. - [truetype] More generalization of GX stuff. + * include/freetype/internal/ftobjs.h (FT_Face_InternalRec): New + pointer to the filter function. + (FT_LibraryRec): Remove unused `lcd_filter'. + (FT_Bitmap_LcdFilterFunc, ft_lcd_filter_fir): Move from here... + * include/freetype/ftlcdfil.h (FT_Bitmap_LcdFilterFunc, + ft_lcd_filter_fir): ... to here. - We need this later on for MVAR also. + * src/base/ftobjs.c (ft_open_face_internal): NULL-initialize the + per-face filter. + (FT_Face_Properties): Set it. + * src/smooth/ftsmooth.c (ft_smooth_render_generic): Simplify. - * src/truetype/ttgxvar.c (ft_var_load_delta_set_index_mapping): Add - parameters for delta-set index mapping and item variation store. - (ft_var_load_item_variation_store): Add parameter for item variation - store. - s/hvarData/varData/. - Move allocation of `hvar_table' to... - (ft_var_load_hvar): ...this function. - Updated. + * src/base/ftlcdfil.c (ft_lcd_filter_fir, FT_Libary_SetLcdFilter): + Minor. -2017-01-06 Werner Lemberg +2017-09-24 Jonathan Kew - [truetype] Some GX structure renames for generalization. + [sfnt] Fix `premultiply_data' (#52092). - We need this later on for MVAR also. + * src/sfnt/pngshim.c (premultiply_data): Don't use vector extension + if we have less than 16 bytes of data. - * src/truetype/ttgxvar.h (GX_HVarData): Renamed to... - (GX_ItemVarData): ...this. - (GX_HVarRegion): Renamed to... - (GX_VarRegion): ...this. - (GX_HVStore): Renamed to... - (GX_ItemVarStore): ...this. - (GX_WidthMap): Renamed to... - (GX_DeltaSetIdxMap): ...this. +2017-09-24 Werner Lemberg - (GX_HVarTable): Updated. + [otvalid] Fix handling of ValueRecords. - * src/truetype/ttgxvar.c: Updated. + For GPOS pair positioning format 1 the description of ValueRecords + in the OpenType specification (1.8.2, from today) is wrong – the + offset has to be taken from the parent structure; in this case the + `PairSet' table. -2017-01-06 Werner Lemberg + * src/otvalid/otvgpos.c (otv_PairSet_validate): Set `extra3'. + (otv_PairPos_validate): Adjust. - [truetype] Code shuffling. +2017-09-23 Werner Lemberg - * src/truetype/ttgxvar.c (ft_var_load_hvar): Split off loading of - item variation store and delta set index mapping into... - (ft_var_load_item_variation_store, - ft_var_load_delta_set_index_mapping): ...new functions. + [otvalid] Handle `GSUB' and `GPOS' v1.1 tables. -2017-01-06 Werner Lemberg + * src/otvalid/otvgsub.c (otv_GSUB_validate), src/otvalid/otvgpos.c + (otv_GPOS_validate): Implement it. - [truetype] Add HVAR access without advance width map. +2017-09-23 Werner Lemberg - * src/truetype/ttgxvar.c (ft_var_load_hvar): Handle case where - `offsetToAdvanceWidthMapping' is zero. - (tt_hadvance_adjust): Implement direct deltaSet access by glyph - index. + [otvalid] Update common table handling to OpenType 1.8.2. -2017-01-06 Werner Lemberg + * src/otvalid/otvcommn.c (otv_Device_validate): Handle + VariationIndex subtable. + (otv_Lookup_validate): Handle MarkFilteringSet. - [pcf] Revise driver. +2017-09-23 Alexei Podtelezhnikov - This commit improves tracing and handling of malformed fonts. In - particular, the changes to `pcf_get_properties' fix + [build] Windows-style DLL versioning. - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=379 + * build/windows/ftver.rc: New VERSIONINFO resource. + * build/windows/vc2010/freetype.vcxproj: Further improvements. - * src/pcf/pcfread.c (tableNames): Use long names for better - readability. - (pcf_read_TOC): Allow at most 9 tables. - (pcf_get_properties): Allow at most 256 properties. - Limit strings array length to 256 * (65536 + 1) bytes. - Better tracing. - (pcf_get_metric): Trace metric data. - (pcf_get_metrics): Allow at most 65536 metrics. - Fix comparison of `metrics->ascent' and `metrics->descent' to avoid - potential overflow. - Better tracing. - (pcf_get_bitmaps): Allow at most 65536 bitmaps. - Better tracing. - (pcf_get_encodings, pcf_get_accel): Better tracing. +2017-09-23 Ben Wagner - * src/pcf/pcfdrivr.c (PCF_Glyph_Load): Don't trace `format' details. - These are now shown by `pcf_get_bitmaps'. + [truetype] Really fix #52082. -2017-01-04 Werner Lemberg + * src/truetype/ttinterp.c (Ins_MDRP): Correct conditional. - * src/pcf/pcfdrivr.c (PCF_Face_Init): Trace compression format. +2017-09-23 Werner Lemberg -2017-01-04 Werner Lemberg + [otvalid] Handle `GDEF' v1.2 and v1.3 tables. - [cff] More consistency checks for pure CFFs. + No validation of variation stuff yet. - Reported as + * src/otvalid/otvgdef.c (otv_MarkGlyphSets_validate): New function. + (otv_GDEF_validate): Implement it. - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=378 +2017-09-22 Werner Lemberg - * src/cff/cffload.c (cff_font_load): Check element number and size - of Name and Top DICT indices. + [otvalid] Handle `BASE' v1.1 table. -2017-01-04 Werner Lemberg + No validation of variation stuff yet. - [cff, truetype] Minor tracing improvement. + * src/otvalid/otvbase.c (otv_BASE_validate): Implement it. - * src/cff/cffobjs.c (cff_face_init), src/truetype/ttobjs.c - (tt_face_init): Indent first tracing message from SFNT driver. +2017-09-22 Werner Lemberg -2017-01-03 Werner Lemberg + [otvalid] Macros for 32bit offset support. - [truetype] Various minor fixes. + * src/otvalid/otvcommn.h (OTV_OPTIONAL_TABLE32, + OTV_OPTIONAL_OFFSET32, OTV_SIZE_CHECK32): New macros. - * src/truetype/ttgload.c (TT_Load_Simple_Glyph): Check instruction - size only if we do native hinting. - (TT_Load_Glyph): Trace returned error code. +2017-09-21 Alexei Podtelezhnikov - * src/truetype/ttobjs.c (tt_size_run_fpgm, tt_size_run_prep): Trace - returned error code. - (tt_size_ready_bytecode): Don't run `prep' table if `fpgm' table is - invalid. + [build] Simplify Visual C++ 2010 project. -2017-01-03 Werner Lemberg + * build/windows/vc2010/freetype.vcxproj: Remove fake singlethreaded + configurations and tweak. - [sfnt] Don't fail if PCLT, EBLC (and similar tables) are invalid. +2017-09-21 Werner Lemberg - These tables are optional. + [truetype] Integer overflow (#52082). - * src/sfnt/sfobjs.c (sfnt_load_face): Implement it. + * src/truetype/ttinterp.c (Ins_MDRP): Avoid FT_ABS. -2017-01-03 Werner Lemberg +2017-09-21 Werner Lemberg - * src/cff/cffparse.c (cff_parse_num): Simplify. + [sfnt] Fix postscript name for default instance of variation fonts. -2017-01-03 Werner Lemberg + Problem reported by Behdad. - Various fixes for clang's undefined behaviour sanitizer. + * src/sfnt/sfdriver.c (sfnt_get_ps_name): Test + `is_default_instance'. - * src/cff/cffload.c (FT_fdot14ToFixed): Fix casting. - (cff_blend_doBlend): Don't left-shift negative numbers. - Handle 5-byte numbers byte by byte to avoid alignment issues. +2017-09-21 Werner Lemberg - * src/cff/cffparse.c (cff_parse_num): Handle 5-byte numbers byte by - byte to avoid alignment issues. + [truetype] Fix `mmvar' array pointers, part 2. - * src/cid/cidload (cid_read_subrs): Do nothing if we don't have any - subrs. + The previous commit was incomplete. - * src/psaux/t1decode.c (t1_decode_parse_charstring): Fix tracing. + * src/truetype/ttgxvar.c: Properly initialize sub-array offsets for + `master' also. - * src/tools/glnames.py (main): Put `DEFINE_PSTABLES' guard around - definition of `ft_get_adobe_glyph_index'. +2017-09-21 Werner Lemberg - * src/psnames/pstables.h: Regenerated. + [truetype] Fix `mmvar' array pointers. - * src/psnames/psmodule.c: Include `pstables.h' twice to get both - declaration and definition. + Without this change, clang's AddressSanitizer reports many runtime + errors due to misaligned addresses. - * src/truetype/ttgxvar.c (FT_fdot14ToFixed, FT_intToFixed): Fix - casting. + * src/truetype/ttgxvar.c (TT_Get_MM_Var): Use multiples of pointer + size for sub-array offsets into `mmvar'. -2017-01-01 Werner Lemberg +2017-09-20 Werner Lemberg - [cff] Handle multiple `blend' operators in a row correctly. + [truetype] Integer overflows. - Reported as + Changes triggered by - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=368 + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3429 - * src/cff/cffload.c (cff_blend_doBlend): Adjust `parser->stack' - pointers into `subFont->blend_stack' after reallocation. + * src/truetype/ttinterp.c (Ins_SHPIX, Ins_DELTAP): Use NEG_LONG. + (Ins_MIAP): Use SUB_LONG. -2017-01-01 Werner Lemberg +2017-09-19 Alexei Podtelezhnikov - [sfnt] Return correct number of named instances for TTCs. + [build] Fix DLL builds in Visual C++ project. - Without this patch, requesting information for face index N returned - the data for face index N+1 (or index 0). + * build/windows/vc2010/freetype.vcxproj: Use DynamicLibrary in Debug + and Release configurations. + * include/freetype/config/ftconfig.h (FT_EXPORT, FT_EXPORT_DEF) + [_DLL]: Use Visual C++ extensions. - * src/sfnt/sfobjs.c (sfnt_init_face): Correctly adjust `face_index' - for negative `face_instance_index' values. +2017-09-19 John Tytgat -2016-12-31 Werner Lemberg + [cff] Fix family name logic of pure CFF fontdata (#52056). - */*: Use hex numbers for errors in tracing messages. + 1. If `FamilyName' is present in the CFF font, use this for + FT_Face's `family_name'. + 2. Otherwise, use the face name and chop off any subset prefix. + 3. If at this point FT_Face's `family_name' is set, use this + together with the full name to determine the style. + 4. Otherwise, use `CIDFontName' as FT_Face's `family_name'. + 5. If we don't have a valid style, use "Regular". -2016-12-31 Werner Lemberg + Previously, FT_Face's `family_name' entry for pure CFF fontdata + nearly always was the fontname itself, instead of the `FamilyName' + entry in the CFF font (assuming there is one). - [truetype] Check axis count in HVAR table. + * src/cff/cffobjs.c (cff_face_init) [pure_cff]: Implement it. - Reported as +2017-09-18 Alexei Podtelezhnikov - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=362 + [build] Declutter Visual C++ 2010-2017 project. - * src/truetype/ttgxvar.c (ft_var_load_hvar): Check axis count. - (ft_var_load_avar): Fix tracing message. + * build/windows/vc2010/freetype.vcxproj: Use MaxSpeed (/02) + optimization for Release configuration throughout the project. ---------------------------------------------------------------------------- -Copyright 2016-2018 by +Copyright (C) 2017-2019 by David Turner, Robert Wilhelm, and Werner Lemberg. This file is part of the FreeType project, and may only be used, modified, diff --git a/sdk/lib/3rdparty/freetype/README b/sdk/lib/3rdparty/freetype/README index 1e7ea97d4180a..3391a573f5d4c 100644 --- a/sdk/lib/3rdparty/freetype/README +++ b/sdk/lib/3rdparty/freetype/README @@ -1,5 +1,5 @@ - FreeType 2.9 - ============ + FreeType 2.10.0 + =============== Homepage: https://www.freetype.org @@ -15,8 +15,8 @@ Read the files `docs/INSTALL*' for installation instructions; see the file `docs/LICENSE.TXT' for the available licenses. - The FreeType 2 API reference is located in `docs/reference'; use the - file `ft2-toc.html' as the top entry point. Additional + The FreeType 2 API reference is located in `docs/reference/site'; + use the file `index.html' as the top entry point. Additional documentation is available as a separate package from our sites. Go to @@ -24,13 +24,13 @@ and download one of the following files. - freetype-doc-2.9.tar.bz2 - freetype-doc-2.9.tar.gz - ftdoc29.zip + freetype-doc-2.10.0.tar.bz2 + freetype-doc-2.10.0.tar.gz + ftdoc2100.zip To view the documentation online, go to - https://www.freetype.org/freetype2/documentation.html + https://www.freetype.org/freetype2/docs/ Mailing Lists @@ -71,7 +71,7 @@ ---------------------------------------------------------------------- -Copyright 2006-2018 by +Copyright (C) 2006-2019 by David Turner, Robert Wilhelm, and Werner Lemberg. This file is part of the FreeType project, and may only be used, diff --git a/sdk/lib/3rdparty/freetype/TechNote.txt b/sdk/lib/3rdparty/freetype/TechNote.txt new file mode 100644 index 0000000000000..1a5e8118ffad3 --- /dev/null +++ b/sdk/lib/3rdparty/freetype/TechNote.txt @@ -0,0 +1,10 @@ +# Technical notes on ReactOS FreeType 2.10.0 + +- FreeType in ReactOS is a static library. ftfd.dll (win32ss/drivers/font/ftfd) actually uses FreeType. +- As usual for 3rd party libraries, the parts that differ are wrapped by #ifdef __REACTOS__ ... #endif. +- Stack size is limited, so we have to use malloc/free instead of large stack variables. +- malloc/realloc/free in ftfd.dll are wrappers implemented in win32ss/drivers/font/ftfd/rosglue.c. +- FT_Bitmap_Convert_ReactOS_Hack function is an extension of FT_Bitmap_Convert function. + This hack function is (currently) needed for ReactOS text output. +- Now we can use FT_ENCODING_NONE for FT_Select_Charmap on FON/FNT files. +- Jamfile's and Makefile's in source are useless for ReactOS (search and delete). diff --git a/sdk/lib/3rdparty/freetype/autogen.sh b/sdk/lib/3rdparty/freetype/autogen.sh deleted file mode 100644 index ab90e6417635d..0000000000000 --- a/sdk/lib/3rdparty/freetype/autogen.sh +++ /dev/null @@ -1,165 +0,0 @@ -#!/bin/sh - -# Copyright 2005-2018 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - -run () -{ - echo "running \`$*'" - eval $* - - if test $? != 0 ; then - echo "error while running \`$*'" - exit 1 - fi -} - -get_major_version () -{ - echo $1 | sed -e 's/\([0-9][0-9]*\)\..*/\1/g' -} - -get_minor_version () -{ - echo $1 | sed -e 's/[0-9][0-9]*\.\([0-9][0-9]*\).*/\1/g' -} - -get_patch_version () -{ - # tricky: some version numbers don't include a patch - # separated with a point, but something like 1.4-p6 - patch=`echo $1 | sed -e 's/[0-9][0-9]*\.[0-9][0-9]*\.\([0-9][0-9]*\).*/\1/g'` - if test "$patch" = "$1"; then - patch=`echo $1 | sed -e 's/[0-9][0-9]*\.[0-9][0-9]*\-p\([0-9][0-9]*\).*/\1/g'` - # if there isn't any patch number, default to 0 - if test "$patch" = "$1"; then - patch=0 - fi - fi - echo $patch -} - -# $1: version to check -# $2: minimum version - -compare_to_minimum_version () -{ - MAJOR1=`get_major_version $1` - MAJOR2=`get_major_version $2` - if test $MAJOR1 -lt $MAJOR2; then - echo 0 - return - else - if test $MAJOR1 -gt $MAJOR2; then - echo 1 - return - fi - fi - - MINOR1=`get_minor_version $1` - MINOR2=`get_minor_version $2` - if test $MINOR1 -lt $MINOR2; then - echo 0 - return - else - if test $MINOR1 -gt $MINOR2; then - echo 1 - return - fi - fi - - PATCH1=`get_patch_version $1` - PATCH2=`get_patch_version $2` - if test $PATCH1 -lt $PATCH2; then - echo 0 - else - echo 1 - fi -} - -# check the version of a given tool against a minimum version number -# -# $1: tool path -# $2: tool usual name (e.g. `aclocal') -# $3: tool variable (e.g. `ACLOCAL') -# $4: minimum version to check against -# $5: option field index used to extract the tool version from the -# output of --version - -check_tool_version () -{ - field=$5 - # assume the output of "[TOOL] --version" is "toolname (GNU toolname foo bar) version" - if test "$field"x = x; then - field=3 # default to 3 for all GNU autotools, after filtering enclosed string - fi - version=`$1 --version | head -1 | sed 's/([^)]*)/()/g' | cut -d ' ' -f $field` - version_check=`compare_to_minimum_version $version $4` - if test "$version_check"x = 0x; then - echo "ERROR: Your version of the \`$2' tool is too old." - echo " Minimum version $4 is required (yours is version $version)." - echo " Please upgrade or use the $3 variable to point to a more recent one." - echo "" - exit 1 - fi -} - -if test ! -f ./builds/unix/configure.raw; then - echo "You must be in the same directory as \`autogen.sh'." - echo "Bootstrapping doesn't work if srcdir != builddir." - exit 1 -fi - -# On MacOS X, the GNU libtool is named `glibtool'. -HOSTOS=`uname` -if test "$LIBTOOLIZE"x != x; then - : -elif test "$HOSTOS"x = Darwinx; then - LIBTOOLIZE=glibtoolize -else - LIBTOOLIZE=libtoolize -fi - -if test "$ACLOCAL"x = x; then - ACLOCAL=aclocal -fi - -if test "$AUTOCONF"x = x; then - AUTOCONF=autoconf -fi - -check_tool_version $ACLOCAL aclocal ACLOCAL 1.10.1 -check_tool_version $LIBTOOLIZE libtoolize LIBTOOLIZE 2.2.4 -check_tool_version $AUTOCONF autoconf AUTOCONF 2.62 - -# This sets freetype_major, freetype_minor, and freetype_patch. -eval `sed -nf version.sed include/freetype/freetype.h` - -# We set freetype-patch to an empty value if it is zero. -if test "$freetype_patch" = ".0"; then - freetype_patch= -fi - -cd builds/unix - -echo "generating \`configure.ac'" -sed -e "s;@VERSION@;$freetype_major$freetype_minor$freetype_patch;" \ - < configure.raw > configure.ac - -run aclocal -I . --force -run $LIBTOOLIZE --force --copy --install -run autoconf --force - -chmod +x install-sh - -cd ../.. - -chmod +x ./configure - -# EOF diff --git a/sdk/lib/3rdparty/freetype/configure b/sdk/lib/3rdparty/freetype/configure deleted file mode 100644 index 8ee0d4029571e..0000000000000 --- a/sdk/lib/3rdparty/freetype/configure +++ /dev/null @@ -1,135 +0,0 @@ -#!/bin/sh -# -# Copyright 2002-2018 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. -# -# -# Call the `configure' script located in `builds/unix'. -# - -rm -f config.mk builds/unix/unix-def.mk builds/unix/unix-cc.mk - -# respect GNUMAKE environment variable for backward compatibility -if test "x$GNUMAKE" = x; then - if test "x$MAKE" = x; then - if test "x`make -v 2>/dev/null | egrep 'GNU|makepp'`" = x; then - MAKE=gmake - else - MAKE=make - fi - fi -else - MAKE=$GNUMAKE -fi - -if test "x`$MAKE -v 2>/dev/null | egrep 'GNU|makepp'`" = x; then - echo "GNU make (>= 3.80) or makepp (>= 1.19) is required to build FreeType2." >&2 - echo "Please try" >&2 - echo >&2 - echo " MAKE= $0" >&2 - echo >&2 - echo "or" >&2 - echo >&2 - echo " MAKE=\"makepp --norc-substitution\" $0" >&2 - exit 1 -fi - -# Get `dirname' functionality. This is taken and adapted from autoconf's -# m4sh.m4 (_AS_EXPR_PREPARE, AS_DIRNAME_EXPR, and AS_DIRNAME_SED). - -if expr a : '\(a\)' >/dev/null 2>&1; then - ft_expr=expr -else - ft_expr=false -fi - -ft2_dir=`(dirname "$0") 2>/dev/null || - $ft_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$0" : 'X\(//\)[^/]' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || - echo X"$0" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -abs_curr_dir=`pwd` -abs_ft2_dir=`cd "$ft2_dir" && pwd` - -# `--srcdir=' option can override abs_ft2_dir - -if test $# -gt 0; then - for x in "$@"; do - case x"$x" in - x--srcdir=*) - abs_ft2_dir=`echo $x | sed 's/^--srcdir=//'` ;; - esac - done -fi - -# build a dummy Makefile if we are not building in the source tree; -# we use inodes to avoid issues with symbolic links -inode_src=`ls -id $abs_ft2_dir | awk '{print $1}'` -inode_dst=`ls -id $abs_curr_dir | awk '{print $1}'` - -if test $inode_src -ne $inode_dst; then - if test ! -d reference; then - mkdir reference - fi - if test ! -r $abs_curr_dir/modules.cfg; then - echo "Copying \`modules.cfg'" - cp $abs_ft2_dir/modules.cfg $abs_curr_dir - fi - echo "Generating \`Makefile'" - echo "TOP_DIR := $abs_ft2_dir" > Makefile - echo "OBJ_DIR := $abs_curr_dir" >> Makefile - echo "OBJ_BUILD := \$(OBJ_DIR)" >> Makefile - echo "DOC_DIR := \$(OBJ_DIR)/reference" >> Makefile - echo "FT_LIBTOOL_DIR := \$(OBJ_DIR)" >> Makefile - echo "ifndef FT2DEMOS" >> Makefile - echo " include \$(TOP_DIR)/Makefile" >> Makefile - echo "else" >> Makefile - echo " TOP_DIR_2 := \$(TOP_DIR)/../ft2demos" >> Makefile - echo " PROJECT := freetype" >> Makefile - echo " CONFIG_MK := \$(OBJ_DIR)/config.mk" >> Makefile - echo " include \$(TOP_DIR_2)/Makefile" >> Makefile - echo "endif" >> Makefile -fi - -# call make - -CFG= -# work around zsh bug which doesn't like `${1+"$@"}' -case $# in -0) ;; -*) for x in "$@"; do - case x"$x" in - x--srcdir=* ) CFG="$CFG '$x'/builds/unix" ;; - *) CFG="$CFG '$x'" ;; - esac - done ;; -esac -CFG=$CFG $MAKE setup unix - -# eof diff --git a/sdk/lib/3rdparty/freetype/devel/ft2build.h b/sdk/lib/3rdparty/freetype/devel/ft2build.h deleted file mode 100644 index 1d17141b2ba04..0000000000000 --- a/sdk/lib/3rdparty/freetype/devel/ft2build.h +++ /dev/null @@ -1,40 +0,0 @@ -/***************************************************************************/ -/* */ -/* ft2build.h */ -/* */ -/* FreeType 2 build and setup macros (development version). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /* - * This is a development version of to build the library in - * debug mode. Its only difference to the default version is that it - * includes a local `ftoption.h' header file with different settings for - * many configuration macros. - * - * To use it, simply ensure that the directory containing this file is - * scanned by the compiler before the default FreeType header directory. - * - */ - -#ifndef FT2BUILD_H_ -#define FT2BUILD_H_ - -#define FT_CONFIG_OPTIONS_H - -#include - -#endif /* FT2BUILD_H_ */ - - -/* END */ diff --git a/sdk/lib/3rdparty/freetype/devel/ftoption.h b/sdk/lib/3rdparty/freetype/devel/ftoption.h deleted file mode 100644 index d66e6e06a860b..0000000000000 --- a/sdk/lib/3rdparty/freetype/devel/ftoption.h +++ /dev/null @@ -1,927 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftoption.h (for development) */ -/* */ -/* User-selectable configuration macros (specification only). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#ifndef FTOPTION_H_ -#define FTOPTION_H_ - - -#include - - -FT_BEGIN_HEADER - - /*************************************************************************/ - /* */ - /* USER-SELECTABLE CONFIGURATION MACROS */ - /* */ - /* This file contains the default configuration macro definitions for */ - /* a standard build of the FreeType library. There are three ways to */ - /* use this file to build project-specific versions of the library: */ - /* */ - /* - You can modify this file by hand, but this is not recommended in */ - /* cases where you would like to build several versions of the */ - /* library from a single source directory. */ - /* */ - /* - You can put a copy of this file in your build directory, more */ - /* precisely in `$BUILD/freetype/config/ftoption.h', where `$BUILD' */ - /* is the name of a directory that is included _before_ the FreeType */ - /* include path during compilation. */ - /* */ - /* The default FreeType Makefiles and Jamfiles use the build */ - /* directory `builds/' by default, but you can easily change */ - /* that for your own projects. */ - /* */ - /* - Copy the file to `$BUILD/ft2build.h' and modify it */ - /* slightly to pre-define the macro FT_CONFIG_OPTIONS_H used to */ - /* locate this file during the build. For example, */ - /* */ - /* #define FT_CONFIG_OPTIONS_H */ - /* #include */ - /* */ - /* will use `$BUILD/myftoptions.h' instead of this file for macro */ - /* definitions. */ - /* */ - /* Note also that you can similarly pre-define the macro */ - /* FT_CONFIG_MODULES_H used to locate the file listing of the modules */ - /* that are statically linked to the library at compile time. By */ - /* default, this file is . */ - /* */ - /* We highly recommend using the third method whenever possible. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** G E N E R A L F R E E T Y P E 2 C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* If you enable this configuration option, FreeType recognizes an */ - /* environment variable called `FREETYPE_PROPERTIES', which can be used */ - /* to control the various font drivers and modules. The controllable */ - /* properties are listed in the section `Controlling FreeType Modules' */ - /* in the reference's table of contents; currently there are properties */ - /* for the auto-hinter (file `ftautoh.h'), CFF (file `ftcffdrv.h'), */ - /* TrueType (file `ftttdrv.h'), and PCF (file `ftpcfdrv.h'). */ - /* */ - /* `FREETYPE_PROPERTIES' has the following syntax form (broken here into */ - /* multiple lines for better readability). */ - /* */ - /* */ - /* ':' */ - /* '=' */ - /* */ - /* ':' */ - /* '=' */ - /* ... */ - /* */ - /* Example: */ - /* */ - /* FREETYPE_PROPERTIES=truetype:interpreter-version=35 \ */ - /* cff:no-stem-darkening=1 \ */ - /* autofitter:warping=1 */ - /* */ -//#define FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES - - - /*************************************************************************/ - /* */ - /* Uncomment the line below if you want to activate LCD rendering */ - /* technology similar to ClearType in this build of the library. This */ - /* technology triples the resolution in the direction color subpixels. */ - /* To mitigate color fringes inherent to this technology, you also need */ - /* to explicitly set up LCD filtering. */ - /* */ - /* Note that this feature is covered by several Microsoft patents */ - /* and should not be activated in any default build of the library. */ - /* When this macro is not defined, FreeType offers alternative LCD */ - /* rendering technology that produces excellent output without LCD */ - /* filtering. */ - /* */ -#define FT_CONFIG_OPTION_SUBPIXEL_RENDERING - - - /*************************************************************************/ - /* */ - /* Many compilers provide a non-ANSI 64-bit data type that can be used */ - /* by FreeType to speed up some computations. However, this will create */ - /* some problems when compiling the library in strict ANSI mode. */ - /* */ - /* For this reason, the use of 64-bit integers is normally disabled when */ - /* the __STDC__ macro is defined. You can however disable this by */ - /* defining the macro FT_CONFIG_OPTION_FORCE_INT64 here. */ - /* */ - /* For most compilers, this will only create compilation warnings when */ - /* building the library. */ - /* */ - /* ObNote: The compiler-specific 64-bit integers are detected in the */ - /* file `ftconfig.h' either statically or through the */ - /* `configure' script on supported platforms. */ - /* */ -#undef FT_CONFIG_OPTION_FORCE_INT64 - - - /*************************************************************************/ - /* */ - /* If this macro is defined, do not try to use an assembler version of */ - /* performance-critical functions (e.g. FT_MulFix). You should only do */ - /* that to verify that the assembler function works properly, or to */ - /* execute benchmark tests of the various implementations. */ -/* #define FT_CONFIG_OPTION_NO_ASSEMBLER */ - - - /*************************************************************************/ - /* */ - /* If this macro is defined, try to use an inlined assembler version of */ - /* the `FT_MulFix' function, which is a `hotspot' when loading and */ - /* hinting glyphs, and which should be executed as fast as possible. */ - /* */ - /* Note that if your compiler or CPU is not supported, this will default */ - /* to the standard and portable implementation found in `ftcalc.c'. */ - /* */ -#define FT_CONFIG_OPTION_INLINE_MULFIX - - - /*************************************************************************/ - /* */ - /* LZW-compressed file support. */ - /* */ - /* FreeType now handles font files that have been compressed with the */ - /* `compress' program. This is mostly used to parse many of the PCF */ - /* files that come with various X11 distributions. The implementation */ - /* uses NetBSD's `zopen' to partially uncompress the file on the fly */ - /* (see src/lzw/ftgzip.c). */ - /* */ - /* Define this macro if you want to enable this `feature'. */ - /* */ -#define FT_CONFIG_OPTION_USE_LZW - - - /*************************************************************************/ - /* */ - /* Gzip-compressed file support. */ - /* */ - /* FreeType now handles font files that have been compressed with the */ - /* `gzip' program. This is mostly used to parse many of the PCF files */ - /* that come with XFree86. The implementation uses `zlib' to */ - /* partially uncompress the file on the fly (see src/gzip/ftgzip.c). */ - /* */ - /* Define this macro if you want to enable this `feature'. See also */ - /* the macro FT_CONFIG_OPTION_SYSTEM_ZLIB below. */ - /* */ -#define FT_CONFIG_OPTION_USE_ZLIB - - - /*************************************************************************/ - /* */ - /* ZLib library selection */ - /* */ - /* This macro is only used when FT_CONFIG_OPTION_USE_ZLIB is defined. */ - /* It allows FreeType's `ftgzip' component to link to the system's */ - /* installation of the ZLib library. This is useful on systems like */ - /* Unix or VMS where it generally is already available. */ - /* */ - /* If you let it undefined, the component will use its own copy */ - /* of the zlib sources instead. These have been modified to be */ - /* included directly within the component and *not* export external */ - /* function names. This allows you to link any program with FreeType */ - /* _and_ ZLib without linking conflicts. */ - /* */ - /* Do not #undef this macro here since the build system might define */ - /* it for certain configurations only. */ - /* */ -/* #define FT_CONFIG_OPTION_SYSTEM_ZLIB */ - - - /*************************************************************************/ - /* */ - /* Bzip2-compressed file support. */ - /* */ - /* FreeType now handles font files that have been compressed with the */ - /* `bzip2' program. This is mostly used to parse many of the PCF */ - /* files that come with XFree86. The implementation uses `libbz2' to */ - /* partially uncompress the file on the fly (see src/bzip2/ftbzip2.c). */ - /* Contrary to gzip, bzip2 currently is not included and need to use */ - /* the system available bzip2 implementation. */ - /* */ - /* Define this macro if you want to enable this `feature'. */ - /* */ -#define FT_CONFIG_OPTION_USE_BZIP2 - - - /*************************************************************************/ - /* */ - /* Define to disable the use of file stream functions and types, FILE, */ - /* fopen() etc. Enables the use of smaller system libraries on embedded */ - /* systems that have multiple system libraries, some with or without */ - /* file stream support, in the cases where file stream support is not */ - /* necessary such as memory loading of font files. */ - /* */ -/* #define FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT */ - - - /*************************************************************************/ - /* */ - /* PNG bitmap support. */ - /* */ - /* FreeType now handles loading color bitmap glyphs in the PNG format. */ - /* This requires help from the external libpng library. Uncompressed */ - /* color bitmaps do not need any external libraries and will be */ - /* supported regardless of this configuration. */ - /* */ - /* Define this macro if you want to enable this `feature'. */ - /* */ -#define FT_CONFIG_OPTION_USE_PNG - - - /*************************************************************************/ - /* */ - /* HarfBuzz support. */ - /* */ - /* FreeType uses the HarfBuzz library to improve auto-hinting of */ - /* OpenType fonts. If available, many glyphs not directly addressable */ - /* by a font's character map will be hinted also. */ - /* */ - /* Define this macro if you want to enable this `feature'. */ - /* */ -#define FT_CONFIG_OPTION_USE_HARFBUZZ - - - /*************************************************************************/ - /* */ - /* Glyph Postscript Names handling */ - /* */ - /* By default, FreeType 2 is compiled with the `psnames' module. This */ - /* module is in charge of converting a glyph name string into a */ - /* Unicode value, or return a Macintosh standard glyph name for the */ - /* use with the TrueType `post' table. */ - /* */ - /* Undefine this macro if you do not want `psnames' compiled in your */ - /* build of FreeType. This has the following effects: */ - /* */ - /* - The TrueType driver will provide its own set of glyph names, */ - /* if you build it to support postscript names in the TrueType */ - /* `post' table, but will not synthesize a missing Unicode charmap. */ - /* */ - /* - The Type 1 driver will not be able to synthesize a Unicode */ - /* charmap out of the glyphs found in the fonts. */ - /* */ - /* You would normally undefine this configuration macro when building */ - /* a version of FreeType that doesn't contain a Type 1 or CFF driver. */ - /* */ -#define FT_CONFIG_OPTION_POSTSCRIPT_NAMES - - - /*************************************************************************/ - /* */ - /* Postscript Names to Unicode Values support */ - /* */ - /* By default, FreeType 2 is built with the `PSNames' module compiled */ - /* in. Among other things, the module is used to convert a glyph name */ - /* into a Unicode value. This is especially useful in order to */ - /* synthesize on the fly a Unicode charmap from the CFF/Type 1 driver */ - /* through a big table named the `Adobe Glyph List' (AGL). */ - /* */ - /* Undefine this macro if you do not want the Adobe Glyph List */ - /* compiled in your `PSNames' module. The Type 1 driver will not be */ - /* able to synthesize a Unicode charmap out of the glyphs found in the */ - /* fonts. */ - /* */ -#define FT_CONFIG_OPTION_ADOBE_GLYPH_LIST - - - /*************************************************************************/ - /* */ - /* Support for Mac fonts */ - /* */ - /* Define this macro if you want support for outline fonts in Mac */ - /* format (mac dfont, mac resource, macbinary containing a mac */ - /* resource) on non-Mac platforms. */ - /* */ - /* Note that the `FOND' resource isn't checked. */ - /* */ -#define FT_CONFIG_OPTION_MAC_FONTS - - - /*************************************************************************/ - /* */ - /* Guessing methods to access embedded resource forks */ - /* */ - /* Enable extra Mac fonts support on non-Mac platforms (e.g. */ - /* GNU/Linux). */ - /* */ - /* Resource forks which include fonts data are stored sometimes in */ - /* locations which users or developers don't expected. In some cases, */ - /* resource forks start with some offset from the head of a file. In */ - /* other cases, the actual resource fork is stored in file different */ - /* from what the user specifies. If this option is activated, */ - /* FreeType tries to guess whether such offsets or different file */ - /* names must be used. */ - /* */ - /* Note that normal, direct access of resource forks is controlled via */ - /* the FT_CONFIG_OPTION_MAC_FONTS option. */ - /* */ -#ifdef FT_CONFIG_OPTION_MAC_FONTS -#define FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK -#endif - - - /*************************************************************************/ - /* */ - /* Allow the use of FT_Incremental_Interface to load typefaces that */ - /* contain no glyph data, but supply it via a callback function. */ - /* This is required by clients supporting document formats which */ - /* supply font data incrementally as the document is parsed, such */ - /* as the Ghostscript interpreter for the PostScript language. */ - /* */ -#define FT_CONFIG_OPTION_INCREMENTAL - - - /*************************************************************************/ - /* */ - /* The size in bytes of the render pool used by the scan-line converter */ - /* to do all of its work. */ - /* */ -#define FT_RENDER_POOL_SIZE 16384L - - - /*************************************************************************/ - /* */ - /* FT_MAX_MODULES */ - /* */ - /* The maximum number of modules that can be registered in a single */ - /* FreeType library object. 32 is the default. */ - /* */ -#define FT_MAX_MODULES 32 - - - /*************************************************************************/ - /* */ - /* Debug level */ - /* */ - /* FreeType can be compiled in debug or trace mode. In debug mode, */ - /* errors are reported through the `ftdebug' component. In trace */ - /* mode, additional messages are sent to the standard output during */ - /* execution. */ - /* */ - /* Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode. */ - /* Define FT_DEBUG_LEVEL_TRACE to build it in trace mode. */ - /* */ - /* Don't define any of these macros to compile in `release' mode! */ - /* */ - /* Do not #undef these macros here since the build system might define */ - /* them for certain configurations only. */ - /* */ -#define FT_DEBUG_LEVEL_ERROR -#define FT_DEBUG_LEVEL_TRACE - - - /*************************************************************************/ - /* */ - /* Autofitter debugging */ - /* */ - /* If FT_DEBUG_AUTOFIT is defined, FreeType provides some means to */ - /* control the autofitter behaviour for debugging purposes with global */ - /* boolean variables (consequently, you should *never* enable this */ - /* while compiling in `release' mode): */ - /* */ - /* _af_debug_disable_horz_hints */ - /* _af_debug_disable_vert_hints */ - /* _af_debug_disable_blue_hints */ - /* */ - /* Additionally, the following functions provide dumps of various */ - /* internal autofit structures to stdout (using `printf'): */ - /* */ - /* af_glyph_hints_dump_points */ - /* af_glyph_hints_dump_segments */ - /* af_glyph_hints_dump_edges */ - /* af_glyph_hints_get_num_segments */ - /* af_glyph_hints_get_segment_offset */ - /* */ - /* As an argument, they use another global variable: */ - /* */ - /* _af_debug_hints */ - /* */ - /* Please have a look at the `ftgrid' demo program to see how those */ - /* variables and macros should be used. */ - /* */ - /* Do not #undef these macros here since the build system might define */ - /* them for certain configurations only. */ - /* */ -#define FT_DEBUG_AUTOFIT - - - /*************************************************************************/ - /* */ - /* Memory Debugging */ - /* */ - /* FreeType now comes with an integrated memory debugger that is */ - /* capable of detecting simple errors like memory leaks or double */ - /* deletes. To compile it within your build of the library, you */ - /* should define FT_DEBUG_MEMORY here. */ - /* */ - /* Note that the memory debugger is only activated at runtime when */ - /* when the _environment_ variable `FT2_DEBUG_MEMORY' is defined also! */ - /* */ - /* Do not #undef this macro here since the build system might define */ - /* it for certain configurations only. */ - /* */ -#define FT_DEBUG_MEMORY - - - /*************************************************************************/ - /* */ - /* Module errors */ - /* */ - /* If this macro is set (which is _not_ the default), the higher byte */ - /* of an error code gives the module in which the error has occurred, */ - /* while the lower byte is the real error code. */ - /* */ - /* Setting this macro makes sense for debugging purposes only, since */ - /* it would break source compatibility of certain programs that use */ - /* FreeType 2. */ - /* */ - /* More details can be found in the files ftmoderr.h and fterrors.h. */ - /* */ -#undef FT_CONFIG_OPTION_USE_MODULE_ERRORS - - - /*************************************************************************/ - /* */ - /* Position Independent Code */ - /* */ - /* If this macro is set (which is _not_ the default), FreeType2 will */ - /* avoid creating constants that require address fixups. Instead the */ - /* constants will be moved into a struct and additional intialization */ - /* code will be used. */ - /* */ - /* Setting this macro is needed for systems that prohibit address */ - /* fixups, such as BREW. [Note that standard compilers like gcc or */ - /* clang handle PIC generation automatically; you don't have to set */ - /* FT_CONFIG_OPTION_PIC, which is only necessary for very special */ - /* compilers.] */ - /* */ - /* Note that FT_CONFIG_OPTION_PIC support is not available for all */ - /* modules (see `modules.cfg' for a complete list). For building with */ - /* FT_CONFIG_OPTION_PIC support, do the following. */ - /* */ - /* 0. Clone the repository. */ - /* 1. Define FT_CONFIG_OPTION_PIC. */ - /* 2. Remove all subdirectories in `src' that don't have */ - /* FT_CONFIG_OPTION_PIC support. */ - /* 3. Comment out the corresponding modules in `modules.cfg'. */ - /* 4. Compile. */ - /* */ -/* #define FT_CONFIG_OPTION_PIC */ - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** S F N T D R I V E R C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_EMBEDDED_BITMAPS if you want to support */ - /* embedded bitmaps in all formats using the SFNT module (namely */ - /* TrueType & OpenType). */ - /* */ -#define TT_CONFIG_OPTION_EMBEDDED_BITMAPS - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_POSTSCRIPT_NAMES if you want to be able to */ - /* load and enumerate the glyph Postscript names in a TrueType or */ - /* OpenType file. */ - /* */ - /* Note that when you do not compile the `PSNames' module by undefining */ - /* the above FT_CONFIG_OPTION_POSTSCRIPT_NAMES, the `sfnt' module will */ - /* contain additional code used to read the PS Names table from a font. */ - /* */ - /* (By default, the module uses `PSNames' to extract glyph names.) */ - /* */ -#define TT_CONFIG_OPTION_POSTSCRIPT_NAMES - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_SFNT_NAMES if your applications need to */ - /* access the internal name table in a SFNT-based format like TrueType */ - /* or OpenType. The name table contains various strings used to */ - /* describe the font, like family name, copyright, version, etc. It */ - /* does not contain any glyph name though. */ - /* */ - /* Accessing SFNT names is done through the functions declared in */ - /* `ftsnames.h'. */ - /* */ -#define TT_CONFIG_OPTION_SFNT_NAMES - - - /*************************************************************************/ - /* */ - /* TrueType CMap support */ - /* */ - /* Here you can fine-tune which TrueType CMap table format shall be */ - /* supported. */ -#define TT_CONFIG_CMAP_FORMAT_0 -#define TT_CONFIG_CMAP_FORMAT_2 -#define TT_CONFIG_CMAP_FORMAT_4 -#define TT_CONFIG_CMAP_FORMAT_6 -#define TT_CONFIG_CMAP_FORMAT_8 -#define TT_CONFIG_CMAP_FORMAT_10 -#define TT_CONFIG_CMAP_FORMAT_12 -#define TT_CONFIG_CMAP_FORMAT_13 -#define TT_CONFIG_CMAP_FORMAT_14 - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** T R U E T Y P E D R I V E R C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_BYTECODE_INTERPRETER if you want to compile */ - /* a bytecode interpreter in the TrueType driver. */ - /* */ - /* By undefining this, you will only compile the code necessary to load */ - /* TrueType glyphs without hinting. */ - /* */ - /* Do not #undef this macro here, since the build system might */ - /* define it for certain configurations only. */ - /* */ -#define TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_SUBPIXEL_HINTING if you want to compile */ - /* subpixel hinting support into the TrueType driver. This modifies the */ - /* TrueType hinting mechanism when anything but FT_RENDER_MODE_MONO is */ - /* requested. */ - /* */ - /* In particular, it modifies the bytecode interpreter to interpret (or */ - /* not) instructions in a certain way so that all TrueType fonts look */ - /* like they do in a Windows ClearType (DirectWrite) environment. See */ - /* [1] for a technical overview on what this means. See `ttinterp.h' */ - /* for more details on the LEAN option. */ - /* */ - /* There are three options. */ - /* */ - /* 1. This option is associated with the `Infinality' moniker. */ - /* Contributed by an individual nicknamed Infinality with the goal of */ - /* making TrueType fonts render better than on Windows. A high */ - /* amount of configurability and flexibility, down to rules for */ - /* single glyphs in fonts, but also very slow. Its experimental and */ - /* slow nature and the original developer losing interest meant that */ - /* this option was never enabled in default builds. */ - /* */ - /* 2. The new default mode for the TrueType driver. The Infinality code */ - /* base was stripped to the bare minimum and all configurability */ - /* removed in the name of speed and simplicity. The configurability */ - /* was mainly aimed at legacy fonts like Arial, Times New Roman, or */ - /* Courier. Legacy fonts are fonts that modify vertical stems to */ - /* achieve clean black-and-white bitmaps. The new mode focuses on */ - /* applying a minimal set of rules to all fonts indiscriminately so */ - /* that modern and web fonts render well while legacy fonts render */ - /* okay. */ - /* */ - /* 3. Compile both. */ - /* */ - /* By undefining these, you get rendering behavior like on Windows */ - /* without ClearType, i.e., Windows XP without ClearType enabled and */ - /* Win9x (interpreter version v35). Or not, depending on how much */ - /* hinting blood and testing tears the font designer put into a given */ - /* font. If you define one or both subpixel hinting options, you can */ - /* switch between between v35 and the ones you define. */ - /* */ - /* This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be */ - /* defined. */ - /* */ - /* [1] https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx */ - /* */ -/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING 1 */ -/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING 2 */ -#define TT_CONFIG_OPTION_SUBPIXEL_HINTING ( 1 | 2 ) - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED to compile the */ - /* TrueType glyph loader to use Apple's definition of how to handle */ - /* component offsets in composite glyphs. */ - /* */ - /* Apple and MS disagree on the default behavior of component offsets */ - /* in composites. Apple says that they should be scaled by the scaling */ - /* factors in the transformation matrix (roughly, it's more complex) */ - /* while MS says they should not. OpenType defines two bits in the */ - /* composite flags array which can be used to disambiguate, but old */ - /* fonts will not have them. */ - /* */ - /* https://www.microsoft.com/typography/otspec/glyf.htm */ - /* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6glyf.html */ - /* */ -#undef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_GX_VAR_SUPPORT if you want to include */ - /* support for Apple's distortable font technology (fvar, gvar, cvar, */ - /* and avar tables). This has many similarities to Type 1 Multiple */ - /* Masters support. */ - /* */ -#define TT_CONFIG_OPTION_GX_VAR_SUPPORT - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_BDF if you want to include support for */ - /* an embedded `BDF ' table within SFNT-based bitmap formats. */ - /* */ -#define TT_CONFIG_OPTION_BDF - - - /*************************************************************************/ - /* */ - /* Option TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES controls the maximum */ - /* number of bytecode instructions executed for a single run of the */ - /* bytecode interpreter, needed to prevent infinite loops. You don't */ - /* want to change this except for very special situations (e.g., making */ - /* a library fuzzer spend less time to handle broken fonts). */ - /* */ - /* It is not expected that this value is ever modified by a configuring */ - /* script; instead, it gets surrounded with #ifndef ... #endif so that */ - /* the value can be set as a preprocessor option on the compiler's */ - /* command line. */ - /* */ -#ifndef TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES -#define TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES 1000000L -#endif - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** T Y P E 1 D R I V E R C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* T1_MAX_DICT_DEPTH is the maximum depth of nest dictionaries and */ - /* arrays in the Type 1 stream (see t1load.c). A minimum of 4 is */ - /* required. */ - /* */ -#define T1_MAX_DICT_DEPTH 5 - - - /*************************************************************************/ - /* */ - /* T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine */ - /* calls during glyph loading. */ - /* */ -#define T1_MAX_SUBRS_CALLS 16 - - - /*************************************************************************/ - /* */ - /* T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity. A */ - /* minimum of 16 is required. */ - /* */ - /* The Chinese font MingTiEG-Medium (CNS 11643 character set) needs 256. */ - /* */ -#define T1_MAX_CHARSTRINGS_OPERANDS 256 - - - /*************************************************************************/ - /* */ - /* Define this configuration macro if you want to prevent the */ - /* compilation of `t1afm', which is in charge of reading Type 1 AFM */ - /* files into an existing face. Note that if set, the T1 driver will be */ - /* unable to produce kerning distances. */ - /* */ -#undef T1_CONFIG_OPTION_NO_AFM - - - /*************************************************************************/ - /* */ - /* Define this configuration macro if you want to prevent the */ - /* compilation of the Multiple Masters font support in the Type 1 */ - /* driver. */ - /* */ -#undef T1_CONFIG_OPTION_NO_MM_SUPPORT - - - /*************************************************************************/ - /* */ - /* T1_CONFIG_OPTION_OLD_ENGINE controls whether the pre-Adobe Type 1 */ - /* engine gets compiled into FreeType. If defined, it is possible to */ - /* switch between the two engines using the `hinting-engine' property of */ - /* the type1 driver module. */ - /* */ -//#define T1_CONFIG_OPTION_OLD_ENGINE - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** C F F D R I V E R C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* Using CFF_CONFIG_OPTION_DARKENING_PARAMETER_{X,Y}{1,2,3,4} it is */ - /* possible to set up the default values of the four control points that */ - /* define the stem darkening behaviour of the (new) CFF engine. For */ - /* more details please read the documentation of the */ - /* `darkening-parameters' property of the cff driver module (file */ - /* `ftcffdrv.h'), which allows the control at run-time. */ - /* */ - /* Do *not* undefine these macros! */ - /* */ -#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 500 -#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1 400 - -#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 1000 -#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2 275 - -#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 1667 -#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3 275 - -#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4 2333 -#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4 0 - - - /*************************************************************************/ - /* */ - /* CFF_CONFIG_OPTION_OLD_ENGINE controls whether the pre-Adobe CFF */ - /* engine gets compiled into FreeType. If defined, it is possible to */ - /* switch between the two engines using the `hinting-engine' property of */ - /* the cff driver module. */ - /* */ -#define CFF_CONFIG_OPTION_OLD_ENGINE - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** P C F D R I V E R C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* There are many PCF fonts just called `Fixed' which look completely */ - /* different, and which have nothing to do with each other. When */ - /* selecting `Fixed' in KDE or Gnome one gets results that appear rather */ - /* random, the style changes often if one changes the size and one */ - /* cannot select some fonts at all. This option makes the PCF module */ - /* prepend the foundry name (plus a space) to the family name. */ - /* */ - /* We also check whether we have `wide' characters; all put together, we */ - /* get family names like `Sony Fixed' or `Misc Fixed Wide'. */ - /* */ - /* If this option is activated, it can be controlled with the */ - /* `no-long-family-names' property of the pcf driver module. */ - /* */ -#define PCF_CONFIG_OPTION_LONG_FAMILY_NAMES - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** A U T O F I T M O D U L E C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* Compile autofit module with CJK (Chinese, Japanese, Korean) script */ - /* support. */ - /* */ -#define AF_CONFIG_OPTION_CJK - - /*************************************************************************/ - /* */ - /* Compile autofit module with Indic script support. */ - /* */ -#define AF_CONFIG_OPTION_INDIC - - /*************************************************************************/ - /* */ - /* Compile autofit module with warp hinting. The idea of the warping */ - /* code is to slightly scale and shift a glyph within a single dimension */ - /* so that as much of its segments are aligned (more or less) on the */ - /* grid. To find out the optimal scaling and shifting value, various */ - /* parameter combinations are tried and scored. */ - /* */ - /* This experimental option is active only if the rendering mode is */ - /* FT_RENDER_MODE_LIGHT; you can switch warping on and off with the */ - /* `warping' property of the auto-hinter (see file `ftautoh.h' for more */ - /* information; by default it is switched off). */ - /* */ -#define AF_CONFIG_OPTION_USE_WARPER - - /* */ - - - /* - * This macro is obsolete. Support has been removed in FreeType - * version 2.5. - */ -/* #define FT_CONFIG_OPTION_OLD_INTERNALS */ - - - /* - * This macro is defined if native TrueType hinting is requested by the - * definitions above. - */ -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER -#define TT_USE_BYTECODE_INTERPRETER - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -#if TT_CONFIG_OPTION_SUBPIXEL_HINTING & 1 -#define TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY -#endif - -#if TT_CONFIG_OPTION_SUBPIXEL_HINTING & 2 -#define TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL -#endif -#endif -#endif - - - /* - * Check CFF darkening parameters. The checks are the same as in function - * `cff_property_set' in file `cffdrivr.c'. - */ -#if CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 < 0 || \ - CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 < 0 || \ - CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 < 0 || \ - CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4 < 0 || \ - \ - CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1 < 0 || \ - CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2 < 0 || \ - CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3 < 0 || \ - CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4 < 0 || \ - \ - CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 > \ - CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 || \ - CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 > \ - CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 || \ - CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 > \ - CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4 || \ - \ - CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1 > 500 || \ - CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2 > 500 || \ - CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3 > 500 || \ - CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4 > 500 -#error "Invalid CFF darkening parameters!" -#endif - -FT_END_HEADER - - -#endif /* FTOPTION_H_ */ - - -/* END */ diff --git a/sdk/lib/3rdparty/freetype/freetype.def b/sdk/lib/3rdparty/freetype/freetype.def deleted file mode 100644 index 9a3a89bfb5741..0000000000000 --- a/sdk/lib/3rdparty/freetype/freetype.def +++ /dev/null @@ -1,173 +0,0 @@ -LIBRARY freetype -EXPORTS - FTC_CMapCache_Lookup - FTC_CMapCache_New - FTC_ImageCache_Lookup - FTC_ImageCache_LookupScaler - FTC_ImageCache_New - FTC_Manager_Done - FTC_Manager_LookupFace - FTC_Manager_LookupSize - FTC_Manager_New - FTC_Manager_RemoveFaceID - FTC_Manager_Reset - FTC_Node_Unref - FTC_SBitCache_Lookup - FTC_SBitCache_LookupScaler - FTC_SBitCache_New - FT_Activate_Size - FT_Add_Default_Modules - FT_Add_Module - FT_Angle_Diff - FT_Atan2 - FT_Attach_File - FT_Attach_Stream - FT_Bitmap_Convert - FT_Bitmap_Copy - FT_Bitmap_Done - FT_Bitmap_Embolden - FT_Bitmap_New - FT_CeilFix - FT_ClassicKern_Free - FT_ClassicKern_Validate - FT_Cos - FT_DivFix - FT_Done_Face - FT_Done_FreeType - FT_Done_Glyph - FT_Done_Library - FT_Done_Size - FT_Face_CheckTrueTypePatents - FT_Face_SetUnpatentedHinting - FT_FloorFix - FT_Get_Advance - FT_Get_Advances - FT_Get_BDF_Charset_ID - FT_Get_BDF_Property - FT_Get_CMap_Format - FT_Get_CMap_Language_ID - FT_Get_Char_Index - FT_Get_Charmap_Index - FT_Get_CID_From_Glyph_Index - FT_Get_CID_Is_Internally_CID_Keyed - FT_Get_CID_Registry_Ordering_Supplement - FT_Get_First_Char - FT_Get_FSType_Flags - FT_Get_Glyph - FT_Get_Glyph_Name - FT_Get_Kerning - FT_Get_MM_Var - FT_Get_Module - FT_Get_Multi_Master - FT_Get_Name_Index - FT_Get_Next_Char - FT_Get_PFR_Advance - FT_Get_PFR_Kerning - FT_Get_PFR_Metrics - FT_Get_PS_Font_Info - FT_Get_PS_Font_Private - FT_Get_Postscript_Name - FT_Get_Renderer - FT_Get_Sfnt_Name - FT_Get_Sfnt_Name_Count - FT_Get_Sfnt_Table - FT_Get_SubGlyph_Info - FT_Get_Track_Kerning - FT_Get_TrueType_Engine_Type - FT_Get_WinFNT_Header - FT_GlyphSlot_Embolden - FT_GlyphSlot_Oblique - FT_GlyphSlot_Own_Bitmap - FT_Glyph_Copy - FT_Glyph_Get_CBox - FT_Glyph_Stroke - FT_Glyph_StrokeBorder - FT_Glyph_To_Bitmap - FT_Glyph_Transform - FT_Has_PS_Glyph_Names - FT_Init_FreeType - FT_Library_Version - FT_List_Add - FT_List_Finalize - FT_List_Find - FT_List_Insert - FT_List_Iterate - FT_List_Remove - FT_List_Up - FT_Load_Char - FT_Load_Glyph - FT_Load_Sfnt_Table - FT_Matrix_Invert - FT_Matrix_Multiply - FT_MulDiv - FT_MulFix - FT_New_Face - FT_New_Library - FT_New_Memory_Face - FT_New_Size - FT_OpenType_Free - FT_OpenType_Validate - FT_Open_Face - FT_Outline_Check - FT_Outline_Copy - FT_Outline_Decompose - FT_Outline_Done - FT_Outline_Done_Internal - FT_Outline_Embolden - FT_Outline_GetInsideBorder - FT_Outline_GetOutsideBorder - FT_Outline_Get_BBox - FT_Outline_Get_Bitmap - FT_Outline_Get_CBox - FT_Outline_Get_Orientation - FT_Outline_New - FT_Outline_New_Internal - FT_Outline_Render - FT_Outline_Reverse - FT_Outline_Transform - FT_Outline_Translate - FT_Remove_Module - FT_Render_Glyph - FT_Request_Size - FT_RoundFix - FT_Select_Charmap - FT_Select_Size - FT_Set_Char_Size - FT_Set_Charmap - FT_Set_Debug_Hook - FT_Set_MM_Blend_Coordinates - FT_Set_MM_Design_Coordinates - FT_Set_Pixel_Sizes - FT_Set_Renderer - FT_Set_Transform - FT_Set_Var_Blend_Coordinates - FT_Set_Var_Design_Coordinates - FT_Sfnt_Table_Info - FT_Sin - FT_Stream_OpenGzip - FT_Stream_OpenLZW - FT_Stroker_BeginSubPath - FT_Stroker_ConicTo - FT_Stroker_CubicTo - FT_Stroker_Done - FT_Stroker_EndSubPath - FT_Stroker_Export - FT_Stroker_ExportBorder - FT_Stroker_GetBorderCounts - FT_Stroker_GetCounts - FT_Stroker_LineTo - FT_Stroker_New - FT_Stroker_ParseOutline - FT_Stroker_Rewind - FT_Stroker_Set - FT_Tan - FT_TrueTypeGX_Free - FT_TrueTypeGX_Validate - FT_Vector_From_Polar - FT_Vector_Length - FT_Vector_Polarize - FT_Vector_Rotate - FT_Vector_Transform - FT_Vector_Unit -TT_New_Context -TT_RunIns diff --git a/sdk/lib/3rdparty/freetype/freetype.rc b/sdk/lib/3rdparty/freetype/freetype.rc deleted file mode 100644 index f37ab321911bc..0000000000000 --- a/sdk/lib/3rdparty/freetype/freetype.rc +++ /dev/null @@ -1,8 +0,0 @@ -#define REACTOS_VERSION_DLL -#define REACTOS_STR_FILE_DESCRIPTION "FreeType font handling library\0" -#define REACTOS_STR_INTERNAL_NAME "freetype\0" -#define REACTOS_STR_ORIGINAL_FILENAME "freetype.dll\0" -#define REACTOS_STR_COMPANY_NAME "ReactOS Development Team/FreeType Team\0" -#define REACTOS_STR_LEGAL_COPYRIGHT "Copyright 1998-2011 ReactOS Team\0" -#define REACTOS_STR_ORIGINAL_COPYRIGHT "Copyright 1996-2013 FreeType Team\0" -#include diff --git a/sdk/lib/3rdparty/freetype/freetype_ros.diff b/sdk/lib/3rdparty/freetype/freetype_ros.diff deleted file mode 100644 index 7091ffc216c25..0000000000000 --- a/sdk/lib/3rdparty/freetype/freetype_ros.diff +++ /dev/null @@ -1,473 +0,0 @@ -diff -prudN e:\freetype-2.6\src/autofit/afcjk.c e:\reactos\lib\3rdparty\freetype\src/autofit/afcjk.c ---- e:\freetype-2.6\src/autofit/afcjk.c 2015-04-20 21:52:41 +0100 -+++ e:\reactos\lib\3rdparty\freetype\src/autofit/afcjk.c 2015-09-07 22:38:13 +0100 -@@ -71,7 +71,11 @@ - FT_Face face ) - { - /* scan the array of segments in each direction */ -+#ifdef __REACTOS__ -+ AF_GlyphHintsRec *hints = malloc(sizeof(AF_GlyphHintsRec)); -+#else - AF_GlyphHintsRec hints[1]; -+#endif - - - FT_TRACE5(( "\n" -@@ -90,7 +94,11 @@ - FT_ULong glyph_index; - FT_Long y_offset; - int dim; -+#ifdef __REACTOS__ -+ AF_CJKMetricsRec *dummy = malloc(sizeof(AF_CJKMetricsRec)); -+#else - AF_CJKMetricsRec dummy[1]; -+#endif - AF_Scaler scaler = &dummy->root.scaler; - - #ifdef FT_CONFIG_OPTION_PIC -@@ -243,11 +251,18 @@ - } - #endif - } -+#ifdef __REACTOS__ -+ free(dummy); -+#endif - } - - FT_TRACE5(( "\n" )); - - af_glyph_hints_done( hints ); -+ -+#ifdef __REACTOS__ -+ free(hints); -+#endif - } - - -diff -prudN e:\freetype-2.6\src/autofit/aflatin.c e:\reactos\lib\3rdparty\freetype\src/autofit/aflatin.c ---- e:\freetype-2.6\src/autofit/aflatin.c 2015-04-20 21:52:58 +0100 -+++ e:\reactos\lib\3rdparty\freetype\src/autofit/aflatin.c 2015-09-08 11:08:25 +0100 -@@ -58,7 +58,11 @@ - FT_Face face ) - { - /* scan the array of segments in each direction */ -+#ifdef __REACTOS__ -+ AF_GlyphHintsRec *hints = malloc(sizeof(AF_GlyphHintsRec)); -+#else - AF_GlyphHintsRec hints[1]; -+#endif - - - FT_TRACE5(( "\n" -@@ -77,7 +81,11 @@ - FT_ULong glyph_index; - FT_Long y_offset; - int dim; -+#ifdef __REACTOS__ -+ AF_LatinMetricsRec *dummy = malloc(sizeof(AF_LatinMetricsRec)); -+#else - AF_LatinMetricsRec dummy[1]; -+#endif - AF_Scaler scaler = &dummy->root.scaler; - - #ifdef FT_CONFIG_OPTION_PIC -@@ -243,11 +251,19 @@ - } - #endif - } -+#ifdef __REACTOS__ -+ free(dummy); -+#endif - } - - FT_TRACE5(( "\n" )); - - af_glyph_hints_done( hints ); -+ -+#ifdef __REACTOS__ -+ free(hints); -+#endif -+ - } - - -diff -prudN e:\freetype-2.6\src/autofit/afmodule.c e:\reactos\lib\3rdparty\freetype\src/autofit/afmodule.c ---- e:\freetype-2.6\src/autofit/afmodule.c 2015-06-07 05:44:38 +0100 -+++ e:\reactos\lib\3rdparty\freetype\src/autofit/afmodule.c 2015-09-07 20:58:52 +0100 -@@ -351,9 +351,13 @@ - return error; - - #else /* !FT_DEBUG_AUTOFIT */ -- -+#ifdef __REACTOS__ -+ AF_GlyphHintsRec *hints = malloc(sizeof(AF_GlyphHintsRec)); -+ AF_LoaderRec *loader = malloc(sizeof(AF_LoaderRec)); -+#else - AF_GlyphHintsRec hints[1]; - AF_LoaderRec loader[1]; -+#endif - - FT_UNUSED( size ); - -@@ -367,6 +371,11 @@ - af_loader_done( loader ); - af_glyph_hints_done( hints ); - -+#ifdef __REACTOS__ -+ free(hints); -+ free(loader); -+#endif -+ - return error; - - #endif /* !FT_DEBUG_AUTOFIT */ -diff -prudN e:\freetype-2.6\src/base/ftbitmap.c e:\reactos\lib\3rdparty\freetype\src/base/ftbitmap.c ---- e:\freetype-2.6\src/base/ftbitmap.c 2015-03-11 06:47:11 +0100 -+++ e:\reactos\lib\3rdparty\freetype\src/base/ftbitmap.c 2015-09-07 17:20:37 +0100 -@@ -577,7 +577,16 @@ - { - FT_Int val = ss[0]; /* avoid a byte->int cast on each line */ - -- -+#ifdef __REACTOS__ -+ tt[0] = (FT_Byte)( ( val & 0x80 ) ? 0xff : 0); -+ tt[1] = (FT_Byte)( ( val & 0x40 ) ? 0xff : 0); -+ tt[2] = (FT_Byte)( ( val & 0x20 ) ? 0xff : 0); -+ tt[3] = (FT_Byte)( ( val & 0x10 ) ? 0xff : 0); -+ tt[4] = (FT_Byte)( ( val & 0x08 ) ? 0xff : 0); -+ tt[5] = (FT_Byte)( ( val & 0x04 ) ? 0xff : 0); -+ tt[6] = (FT_Byte)( ( val & 0x02 ) ? 0xff : 0); -+ tt[7] = (FT_Byte)( ( val & 0x01 ) ? 0xff : 0); -+#else - tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7 ); - tt[1] = (FT_Byte)( ( val & 0x40 ) >> 6 ); - tt[2] = (FT_Byte)( ( val & 0x20 ) >> 5 ); -@@ -586,6 +595,7 @@ - tt[5] = (FT_Byte)( ( val & 0x04 ) >> 2 ); - tt[6] = (FT_Byte)( ( val & 0x02 ) >> 1 ); - tt[7] = (FT_Byte)( val & 0x01 ); -+#endif - - tt += 8; - ss += 1; -@@ -600,7 +610,11 @@ - - for ( ; j > 0; j-- ) - { -+#ifdef __REACTOS__ -+ tt[0] = (FT_Byte)( ( val & 0x80 ) ? 0xff : 0); -+#else - tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7); -+#endif - val <<= 1; - tt += 1; - } -diff -prudN e:\freetype-2.6\src/cff/cf2intrp.c e:\reactos\lib\3rdparty\freetype\src/cff/cf2intrp.c ---- e:\freetype-2.6\src/cff/cf2intrp.c 2015-05-12 06:22:36 +0100 -+++ e:\reactos\lib\3rdparty\freetype\src/cff/cf2intrp.c 2015-09-08 10:46:46 +0100 -@@ -463,7 +463,13 @@ - CF2_ArrStackRec vStemHintArray; - - CF2_HintMaskRec hintMask; -+#ifdef __REACTOS__ -+ CF2_GlyphPathRec *glyphPath = malloc(sizeof(CF2_GlyphPathRec)); -+/* Ugly but it allows us to reduce the diff */ -+#define glyphPath (*glyphPath) -+#else - CF2_GlyphPathRec glyphPath; -+#endif - - - /* initialize the remaining objects */ -@@ -1197,7 +1203,13 @@ - * discard `counterMask' and `counterHintMap'. - * - */ -+#ifdef __REACTOS__ -+ CF2_HintMapRec *counterHintMap = malloc(sizeof(CF2_HintMapRec)); -+/* Ugly but it allows us to reduce the diff */ -+#define counterHintMap (*counterHintMap) -+#else - CF2_HintMapRec counterHintMap; -+#endif - CF2_HintMaskRec counterMask; - - -@@ -1218,6 +1230,9 @@ - &counterMask, - 0, - FALSE ); -+#ifdef __REACTOS__ -+ free(&counterHintMap); -+#endif - } - break; - -@@ -1564,6 +1579,12 @@ - - FT_TRACE4(( "\n" )); - -+#ifdef __REACTOS__ -+ free(&glyphPath); -+#undef counterHintMap -+#undef glyphPath -+#endif -+ - return; - } - -diff -prudN e:\freetype-2.6\src/cid/cidgload.c e:\reactos\lib\3rdparty\freetype\src/cid/cidgload.c ---- e:\freetype-2.6\src/cid/cidgload.c 2015-04-16 06:02:23 +0100 -+++ e:\reactos\lib\3rdparty\freetype\src/cid/cidgload.c 2015-09-08 10:59:15 +0100 -@@ -273,7 +273,13 @@ - { - CID_GlyphSlot glyph = (CID_GlyphSlot)cidglyph; - FT_Error error; -+#ifdef __REACTOS__ -+ T1_DecoderRec *decoder = malloc(sizeof(T1_DecoderRec)); -+/* Ugly but it allows us to reduce the diff */ -+#define decoder (*decoder) -+#else - T1_DecoderRec decoder; -+#endif - CID_Face face = (CID_Face)cidglyph->face; - FT_Bool hinting; - -@@ -435,6 +441,10 @@ - } - - Exit: -+#ifdef __REACTOS__ -+ free(&decoder); -+#undef decoder -+#endif - return error; - } - -diff -prudN e:\freetype-2.6\src/raster/ftraster.c e:\reactos\lib\3rdparty\freetype\src/raster/ftraster.c ---- e:\freetype-2.6\src/raster/ftraster.c 2015-06-02 10:21:17 +0100 -+++ e:\reactos\lib\3rdparty\freetype\src/raster/ftraster.c 2015-09-08 11:09:33 +0100 -@@ -3136,9 +3136,15 @@ - const FT_Outline* outline = (const FT_Outline*)params->source; - const FT_Bitmap* target_map = params->target; - -+#ifdef __REACTOS__ -+ FT_Error ret; -+ black_TWorker *worker; -+ Long *buffer; -+#else - black_TWorker worker[1]; - - Long buffer[FT_MAX( FT_RENDER_POOL_SIZE, 2048 ) / sizeof ( Long )]; -+#endif - - - if ( !raster ) -@@ -3175,13 +3181,29 @@ - if ( !target_map->buffer ) - return FT_THROW( Invalid ); - -+#ifdef __REACTOS__ -+ worker = malloc(sizeof(black_TWorker)); -+ buffer = malloc(FT_MAX(FT_RENDER_POOL_SIZE, 2048)); -+#endif -+ - ras.outline = *outline; - ras.target = *target_map; - - worker->buff = buffer; -+#ifdef __REACTOS__ -+ worker->sizeBuff = buffer + (FT_MAX(FT_RENDER_POOL_SIZE, 2048) / sizeof(Long)); -+#else - worker->sizeBuff = (&buffer)[1]; /* Points to right after buffer. */ -+#endif - -+#ifdef __REACTOS__ -+ ret = Render_Glyph(RAS_VAR); -+ free(worker); -+ free(buffer); -+ return ret; -+#else - return Render_Glyph( RAS_VAR ); -+#endif - } - - -diff -prudN e:\freetype-2.6\src/smooth/ftgrays.c e:\reactos\lib\3rdparty\freetype\src/smooth/ftgrays.c ---- e:\freetype-2.6\src/smooth/ftgrays.c 2015-03-11 06:47:11 +0100 -+++ e:\reactos\lib\3rdparty\freetype\src/smooth/ftgrays.c 2015-09-08 09:57:56 +0100 -@@ -1940,10 +1940,17 @@ typedef ptrdiff_t FT_PtrDist; - const FT_Outline* outline = (const FT_Outline*)params->source; - const FT_Bitmap* target_map = params->target; - -+#ifdef __REACTOS__ -+ gray_TWorker *worker; -+ int ret; -+ TCell *buffer; -+ long buffer_size = FT_MAX(FT_RENDER_POOL_SIZE, 2048); -+#else - gray_TWorker worker[1]; - - TCell buffer[FT_MAX( FT_RENDER_POOL_SIZE, 2048 ) / sizeof ( TCell )]; - long buffer_size = sizeof ( buffer ); -+#endif - int band_size = (int)( buffer_size / - (long)( sizeof ( TCell ) * 8 ) ); - -@@ -1983,6 +1990,10 @@ typedef ptrdiff_t FT_PtrDist; - if ( !( params->flags & FT_RASTER_FLAG_AA ) ) - return FT_THROW( Invalid_Mode ); - -+#ifdef __REACTOS__ -+ worker = malloc(sizeof(gray_TWorker)); -+#endif -+ - /* compute clipping box */ - if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) ) - { -@@ -2002,6 +2013,10 @@ typedef ptrdiff_t FT_PtrDist; - ras.clip_box.yMax = 32767L; - } - -+#ifdef __REACTOS__ -+ buffer = malloc(buffer_size); -+#endif -+ - gray_init_cells( RAS_VAR_ buffer, buffer_size ); - - ras.outline = *outline; -@@ -2023,7 +2038,14 @@ typedef ptrdiff_t FT_PtrDist; - ras.render_span_data = &ras; - } - -+#ifdef __REACTOS__ -+ ret = gray_convert_glyph(RAS_VAR); -+ free(worker); -+ free(buffer); -+ return ret; -+#else - return gray_convert_glyph( RAS_VAR ); -+#endif - } - - -diff -prudN e:\freetype-2.6\src/type1/t1gload.c e:\reactos\lib\3rdparty\freetype\src/type1/t1gload.c ---- e:\freetype-2.6\src/type1/t1gload.c 2015-04-13 17:14:02 +0100 -+++ e:\reactos\lib\3rdparty\freetype\src/type1/t1gload.c 2015-09-08 10:55:18 +0100 -@@ -154,7 +154,13 @@ - FT_Pos* max_advance ) - { - FT_Error error; -+#ifdef __REACTOS__ -+ T1_DecoderRec *decoder = malloc(sizeof(T1_DecoderRec)); -+/* Ugly but it allows us to reduce the diff */ -+#define decoder (*decoder) -+#else - T1_DecoderRec decoder; -+#endif - FT_Int glyph_index; - T1_Font type1 = &face->type1; - PSAux_Service psaux = (PSAux_Service)face->psaux; -@@ -175,7 +181,14 @@ - FT_RENDER_MODE_NORMAL, - T1_Parse_Glyph ); - if ( error ) -+#ifdef __REACTOS__ -+ { -+ free(&decoder); -+ return error; -+ } -+#else - return error; -+#endif - - decoder.builder.metrics_only = 1; - decoder.builder.load_points = 0; -@@ -202,7 +215,10 @@ - } - - psaux->t1_decoder_funcs->done( &decoder ); -- -+#ifdef __REACTOS__ -+ free(&decoder); -+#undef decoder -+#endif - return FT_Err_Ok; - } - -@@ -215,7 +231,13 @@ - FT_Fixed* advances ) - { - T1_Face face = (T1_Face)t1face; -+#ifdef __REACTOS__ -+ T1_DecoderRec *decoder = malloc(sizeof(T1_DecoderRec)); -+/* Ugly but it allows us to reduce the diff */ -+#define decoder (*decoder) -+#else - T1_DecoderRec decoder; -+#endif - T1_Font type1 = &face->type1; - PSAux_Service psaux = (PSAux_Service)face->psaux; - FT_UInt nn; -@@ -227,6 +249,9 @@ - for ( nn = 0; nn < count; nn++ ) - advances[nn] = 0; - -+#ifdef __REACTOS__ -+ free(&decoder); -+#endif - return FT_Err_Ok; - } - -@@ -240,7 +265,14 @@ - FT_RENDER_MODE_NORMAL, - T1_Parse_Glyph ); - if ( error ) -+#ifdef __REACTOS__ -+ { -+ free(&decoder); -+ return error; -+ } -+#else - return error; -+#endif - - decoder.builder.metrics_only = 1; - decoder.builder.load_points = 0; -@@ -260,7 +292,10 @@ - else - advances[nn] = 0; - } -- -+#ifdef __REACTOS__ -+ free(&decoder); -+#undef decoder -+#endif - return FT_Err_Ok; - } - -@@ -273,7 +308,13 @@ - { - T1_GlyphSlot glyph = (T1_GlyphSlot)t1glyph; - FT_Error error; -+#ifdef __REACTOS__ -+ T1_DecoderRec *decoder = malloc(sizeof(T1_DecoderRec)); -+/* Ugly but it allows us to reduce the diff */ -+#define decoder (*decoder) -+#else - T1_DecoderRec decoder; -+#endif - T1_Face face = (T1_Face)t1glyph->face; - FT_Bool hinting; - T1_Font type1 = &face->type1; -@@ -512,6 +553,10 @@ - if ( must_finish_decoder ) - decoder_funcs->done( &decoder ); - -+#ifdef __REACTOS__ -+ free(&decoder); -+#undef decoder -+#endif - return error; - } - diff --git a/sdk/lib/3rdparty/freetype/include/freetype/config/ftconfig.h b/sdk/lib/3rdparty/freetype/include/freetype/config/ftconfig.h index 031b4bfdc4b99..94666033775f8 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/config/ftconfig.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/config/ftconfig.h @@ -1,39 +1,38 @@ -/***************************************************************************/ -/* */ -/* ftconfig.h */ -/* */ -/* ANSI-specific configuration file (specification only). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This header file contains a number of macro definitions that are used */ - /* by the rest of the engine. Most of the macros here are automatically */ - /* determined at compile time, and you should not need to change it to */ - /* port FreeType, except to compile the library with a non-ANSI */ - /* compiler. */ - /* */ - /* Note however that if some specific modifications are needed, we */ - /* advise you to place a modified copy in your build directory. */ - /* */ - /* The build directory is usually `builds/', and contains */ - /* system-specific files that are always included first when building */ - /* the library. */ - /* */ - /* This ANSI version should stay in `include/config/'. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * ftconfig.h + * + * ANSI-specific configuration file (specification only). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /************************************************************************** + * + * This header file contains a number of macro definitions that are used by + * the rest of the engine. Most of the macros here are automatically + * determined at compile time, and you should not need to change it to port + * FreeType, except to compile the library with a non-ANSI compiler. + * + * Note however that if some specific modifications are needed, we advise + * you to place a modified copy in your build directory. + * + * The build directory is usually `builds/`, and contains + * system-specific files that are always included first when building the + * library. + * + * This ANSI version should stay in `include/config/`. + * + */ #ifndef FTCONFIG_H_ #define FTCONFIG_H_ @@ -46,32 +45,32 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* PLATFORM-SPECIFIC CONFIGURATION MACROS */ - /* */ - /* These macros can be toggled to suit a specific system. The current */ - /* ones are defaults used to compile FreeType in an ANSI C environment */ - /* (16bit compilers are also supported). Copy this file to your own */ - /* `builds/' directory, and edit it to port the engine. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * PLATFORM-SPECIFIC CONFIGURATION MACROS + * + * These macros can be toggled to suit a specific system. The current ones + * are defaults used to compile FreeType in an ANSI C environment (16bit + * compilers are also supported). Copy this file to your own + * `builds/` directory, and edit it to port the engine. + * + */ - /* There are systems (like the Texas Instruments 'C54x) where a `char' */ - /* has 16 bits. ANSI C says that sizeof(char) is always 1. Since an */ - /* `int' has 16 bits also for this system, sizeof(int) gives 1 which */ - /* is probably unexpected. */ - /* */ - /* `CHAR_BIT' (defined in limits.h) gives the number of bits in a */ - /* `char' type. */ + /* There are systems (like the Texas Instruments 'C54x) where a `char` */ + /* has 16~bits. ANSI~C says that `sizeof(char)` is always~1. Since an */ + /* `int` has 16~bits also for this system, `sizeof(int)` gives~1 which */ + /* is probably unexpected. */ + /* */ + /* `CHAR_BIT` (defined in `limits.h`) gives the number of bits in a */ + /* `char` type. */ #ifndef FT_CHAR_BIT #define FT_CHAR_BIT CHAR_BIT #endif - /* The size of an `int' type. */ + /* The size of an `int` type. */ #if FT_UINT_MAX == 0xFFFFUL #define FT_SIZEOF_INT ( 16 / FT_CHAR_BIT ) #elif FT_UINT_MAX == 0xFFFFFFFFUL @@ -82,7 +81,7 @@ FT_BEGIN_HEADER #error "Unsupported size of `int' type!" #endif - /* The size of a `long' type. A five-byte `long' (as used e.g. on the */ + /* The size of a `long` type. A five-byte `long` (as used e.g. on the */ /* DM642) is recognized but avoided. */ #if FT_ULONG_MAX == 0xFFFFFFFFUL #define FT_SIZEOF_LONG ( 32 / FT_CHAR_BIT ) @@ -95,35 +94,35 @@ FT_BEGIN_HEADER #endif - /* FT_UNUSED is a macro used to indicate that a given parameter is not */ - /* used -- this is only used to get rid of unpleasant compiler warnings */ + /* `FT_UNUSED` indicates that a given parameter is not used -- */ + /* this is only used to get rid of unpleasant compiler warnings. */ #ifndef FT_UNUSED #define FT_UNUSED( arg ) ( (arg) = (arg) ) #endif - /*************************************************************************/ - /* */ - /* AUTOMATIC CONFIGURATION MACROS */ - /* */ - /* These macros are computed from the ones defined above. Don't touch */ - /* their definition, unless you know precisely what you are doing. No */ - /* porter should need to mess with them. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* Mac support */ - /* */ - /* This is the only necessary change, so it is defined here instead */ - /* providing a new configuration file. */ - /* */ + /************************************************************************** + * + * AUTOMATIC CONFIGURATION MACROS + * + * These macros are computed from the ones defined above. Don't touch + * their definition, unless you know precisely what you are doing. No + * porter should need to mess with them. + * + */ + + + /************************************************************************** + * + * Mac support + * + * This is the only necessary change, so it is defined here instead + * providing a new configuration file. + */ #if defined( __APPLE__ ) || ( defined( __MWERKS__ ) && defined( macintosh ) ) - /* no Carbon frameworks for 64bit 10.4.x */ - /* AvailabilityMacros.h is available since Mac OS X 10.2, */ - /* so guess the system version by maximum errno before inclusion */ + /* No Carbon frameworks for 64bit 10.4.x. */ + /* `AvailabilityMacros.h` is available since Mac OS X 10.2, */ + /* so guess the system version by maximum errno before inclusion. */ #include #ifdef ECANCELED /* defined since 10.2 */ #include "AvailabilityMacros.h" @@ -143,7 +142,7 @@ FT_BEGIN_HEADER #endif - /* Fix compiler warning with sgi compiler */ + /* Fix compiler warning with sgi compiler. */ #if defined( __sgi ) && !defined( __GNUC__ ) #if defined( _COMPILER_VERSION ) && ( _COMPILER_VERSION >= 730 ) #pragma set woff 3505 @@ -151,33 +150,33 @@ FT_BEGIN_HEADER #endif - /*************************************************************************/ - /* */ - /*

*/ - /* basic_types */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * @section: + * basic_types + * + */ - /*************************************************************************/ - /* */ - /* */ - /* FT_Int16 */ - /* */ - /* */ - /* A typedef for a 16bit signed integer type. */ - /* */ + /************************************************************************** + * + * @type: + * FT_Int16 + * + * @description: + * A typedef for a 16bit signed integer type. + */ typedef signed short FT_Int16; - /*************************************************************************/ - /* */ - /* */ - /* FT_UInt16 */ - /* */ - /* */ - /* A typedef for a 16bit unsigned integer type. */ - /* */ + /************************************************************************** + * + * @type: + * FT_UInt16 + * + * @description: + * A typedef for a 16bit unsigned integer type. + */ typedef unsigned short FT_UInt16; /* */ @@ -186,50 +185,50 @@ FT_BEGIN_HEADER /* this #if 0 ... #endif clause is for documentation purposes */ #if 0 - /*************************************************************************/ - /* */ - /* */ - /* FT_Int32 */ - /* */ - /* */ - /* A typedef for a 32bit signed integer type. The size depends on */ - /* the configuration. */ - /* */ + /************************************************************************** + * + * @type: + * FT_Int32 + * + * @description: + * A typedef for a 32bit signed integer type. The size depends on the + * configuration. + */ typedef signed XXX FT_Int32; - /*************************************************************************/ - /* */ - /* */ - /* FT_UInt32 */ - /* */ - /* A typedef for a 32bit unsigned integer type. The size depends on */ - /* the configuration. */ - /* */ + /************************************************************************** + * + * @type: + * FT_UInt32 + * + * A typedef for a 32bit unsigned integer type. The size depends on the + * configuration. + */ typedef unsigned XXX FT_UInt32; - /*************************************************************************/ - /* */ - /* */ - /* FT_Int64 */ - /* */ - /* A typedef for a 64bit signed integer type. The size depends on */ - /* the configuration. Only defined if there is real 64bit support; */ - /* otherwise, it gets emulated with a structure (if necessary). */ - /* */ + /************************************************************************** + * + * @type: + * FT_Int64 + * + * A typedef for a 64bit signed integer type. The size depends on the + * configuration. Only defined if there is real 64bit support; + * otherwise, it gets emulated with a structure (if necessary). + */ typedef signed XXX FT_Int64; - /*************************************************************************/ - /* */ - /* */ - /* FT_UInt64 */ - /* */ - /* A typedef for a 64bit unsigned integer type. The size depends on */ - /* the configuration. Only defined if there is real 64bit support; */ - /* otherwise, it gets emulated with a structure (if necessary). */ - /* */ + /************************************************************************** + * + * @type: + * FT_UInt64 + * + * A typedef for a 64bit unsigned integer type. The size depends on the + * configuration. Only defined if there is real 64bit support; + * otherwise, it gets emulated with a structure (if necessary). + */ typedef unsigned XXX FT_UInt64; /* */ @@ -251,7 +250,7 @@ FT_BEGIN_HEADER #endif - /* look up an integer type that is at least 32 bits */ + /* look up an integer type that is at least 32~bits */ #if FT_SIZEOF_INT >= ( 32 / FT_CHAR_BIT ) typedef int FT_Fast; @@ -265,22 +264,22 @@ FT_BEGIN_HEADER #endif - /* determine whether we have a 64-bit int type for platforms without */ - /* Autoconf */ + /* determine whether we have a 64-bit `int` type for platforms without */ + /* Autoconf */ #if FT_SIZEOF_LONG == ( 64 / FT_CHAR_BIT ) - /* FT_LONG64 must be defined if a 64-bit type is available */ + /* `FT_LONG64` must be defined if a 64-bit type is available */ #define FT_LONG64 #define FT_INT64 long #define FT_UINT64 unsigned long - /*************************************************************************/ - /* */ - /* A 64-bit data type may create compilation problems if you compile */ - /* in strict ANSI mode. To avoid them, we disable other 64-bit data */ - /* types if __STDC__ is defined. You can however ignore this rule */ - /* by defining the FT_CONFIG_OPTION_FORCE_INT64 configuration macro. */ - /* */ + /************************************************************************** + * + * A 64-bit data type may create compilation problems if you compile in + * strict ANSI mode. To avoid them, we disable other 64-bit data types if + * `__STDC__` is defined. You can however ignore this rule by defining the + * `FT_CONFIG_OPTION_FORCE_INT64` configuration macro. + */ #elif !defined( __STDC__ ) || defined( FT_CONFIG_OPTION_FORCE_INT64 ) #if defined( __STDC_VERSION__ ) && __STDC_VERSION__ >= 199901L @@ -289,19 +288,19 @@ FT_BEGIN_HEADER #define FT_INT64 long long int #define FT_UINT64 unsigned long long int -#elif defined( _MSC_VER ) && _MSC_VER >= 900 /* Visual C++ (and Intel C++) */ +#elif defined( _MSC_VER ) && _MSC_VER >= 900 /* Visual C++ (and Intel C++) */ - /* this compiler provides the __int64 type */ + /* this compiler provides the `__int64` type */ #define FT_LONG64 #define FT_INT64 __int64 #define FT_UINT64 unsigned __int64 #elif defined( __BORLANDC__ ) /* Borland C++ */ - /* XXXX: We should probably check the value of __BORLANDC__ in order */ - /* to test the compiler version. */ + /* XXXX: We should probably check the value of `__BORLANDC__` in order */ + /* to test the compiler version. */ - /* this compiler provides the __int64 type */ + /* this compiler provides the `__int64` type */ #define FT_LONG64 #define FT_INT64 __int64 #define FT_UINT64 unsigned __int64 @@ -318,7 +317,7 @@ FT_BEGIN_HEADER #elif defined( __GNUC__ ) - /* GCC provides the `long long' type */ + /* GCC provides the `long long` type */ #define FT_LONG64 #define FT_INT64 long long int #define FT_UINT64 unsigned long long int @@ -342,11 +341,11 @@ FT_BEGIN_HEADER #endif - /*************************************************************************/ - /* */ - /* miscellaneous */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * miscellaneous + * + */ #define FT_BEGIN_STMNT do { @@ -354,7 +353,7 @@ FT_BEGIN_HEADER #define FT_DUMMY_STMNT FT_BEGIN_STMNT FT_END_STMNT - /* typeof condition taken from gnulib's `intprops.h' header file */ + /* `typeof` condition taken from gnulib's `intprops.h` header file */ #if ( ( defined( __GNUC__ ) && __GNUC__ >= 2 ) || \ ( defined( __IBMC__ ) && __IBMC__ >= 1210 && \ defined( __IBM__TYPEOF__ ) ) || \ @@ -365,14 +364,14 @@ FT_BEGIN_HEADER #endif - /* Use FT_LOCAL and FT_LOCAL_DEF to declare and define, respectively, */ - /* a function that gets used only within the scope of a module. */ - /* Normally, both the header and source code files for such a */ - /* function are within a single module directory. */ - /* */ - /* Intra-module arrays should be tagged with FT_LOCAL_ARRAY and */ - /* FT_LOCAL_ARRAY_DEF. */ - /* */ + /* Use `FT_LOCAL` and `FT_LOCAL_DEF` to declare and define, */ + /* respectively, a function that gets used only within the scope of a */ + /* module. Normally, both the header and source code files for such a */ + /* function are within a single module directory. */ + /* */ + /* Intra-module arrays should be tagged with `FT_LOCAL_ARRAY` and */ + /* `FT_LOCAL_ARRAY_DEF`. */ + /* */ #ifdef FT_MAKE_OPTION_SINGLE_OBJECT #define FT_LOCAL( x ) static x @@ -394,12 +393,12 @@ FT_BEGIN_HEADER #define FT_LOCAL_ARRAY_DEF( x ) const x - /* Use FT_BASE and FT_BASE_DEF to declare and define, respectively, */ - /* functions that are used in more than a single module. In the */ - /* current setup this implies that the declaration is in a header */ - /* file in the `include/freetype/internal' directory, and the */ - /* function body is in a file in `src/base'. */ - /* */ + /* Use `FT_BASE` and `FT_BASE_DEF` to declare and define, respectively, */ + /* functions that are used in more than a single module. In the */ + /* current setup this implies that the declaration is in a header file */ + /* in the `include/freetype/internal` directory, and the function body */ + /* is in a file in `src/base`. */ + /* */ #ifndef FT_BASE #ifdef __cplusplus @@ -422,55 +421,67 @@ FT_BEGIN_HEADER #endif /* !FT_BASE_DEF */ - /* When compiling FreeType as a DLL, some systems/compilers need a */ - /* special attribute in front OR after the return type of function */ - /* declarations. */ - /* */ - /* Two macros are used within the FreeType source code to define */ - /* exported library functions: FT_EXPORT and FT_EXPORT_DEF. */ - /* */ - /* FT_EXPORT( return_type ) */ - /* */ - /* is used in a function declaration, as in */ - /* */ - /* FT_EXPORT( FT_Error ) */ - /* FT_Init_FreeType( FT_Library* alibrary ); */ - /* */ - /* */ - /* FT_EXPORT_DEF( return_type ) */ - /* */ - /* is used in a function definition, as in */ - /* */ - /* FT_EXPORT_DEF( FT_Error ) */ - /* FT_Init_FreeType( FT_Library* alibrary ) */ - /* { */ - /* ... some code ... */ - /* return FT_Err_Ok; */ - /* } */ - /* */ - /* You can provide your own implementation of FT_EXPORT and */ - /* FT_EXPORT_DEF here if you want. */ - /* */ - /* To export a variable, use FT_EXPORT_VAR. */ - /* */ + /* When compiling FreeType as a DLL or DSO with hidden visibility */ + /* some systems/compilers need a special attribute in front OR after */ + /* the return type of function declarations. */ + /* */ + /* Two macros are used within the FreeType source code to define */ + /* exported library functions: `FT_EXPORT` and `FT_EXPORT_DEF`. */ + /* */ + /* - `FT_EXPORT( return_type )` */ + /* */ + /* is used in a function declaration, as in */ + /* */ + /* ``` */ + /* FT_EXPORT( FT_Error ) */ + /* FT_Init_FreeType( FT_Library* alibrary ); */ + /* ``` */ + /* */ + /* - `FT_EXPORT_DEF( return_type )` */ + /* */ + /* is used in a function definition, as in */ + /* */ + /* ``` */ + /* FT_EXPORT_DEF( FT_Error ) */ + /* FT_Init_FreeType( FT_Library* alibrary ) */ + /* { */ + /* ... some code ... */ + /* return FT_Err_Ok; */ + /* } */ + /* ``` */ + /* */ + /* You can provide your own implementation of `FT_EXPORT` and */ + /* `FT_EXPORT_DEF` here if you want. */ + /* */ + /* To export a variable, use `FT_EXPORT_VAR`. */ + /* */ #ifndef FT_EXPORT -#ifdef __cplusplus +#ifdef FT2_BUILD_LIBRARY + +#if defined( _WIN32 ) && defined( DLL_EXPORT ) +#define FT_EXPORT( x ) __declspec( dllexport ) x +#elif defined( __GNUC__ ) && __GNUC__ >= 4 +#define FT_EXPORT( x ) __attribute__(( visibility( "default" ) )) x +#elif defined( __SUNPRO_C ) && __SUNPRO_C >= 0x550 +#define FT_EXPORT( x ) __global x +#elif defined( __cplusplus ) #define FT_EXPORT( x ) extern "C" x #else #define FT_EXPORT( x ) extern x #endif -#ifndef __REACTOS__ -#ifdef _MSC_VER -#undef FT_EXPORT -#ifdef _DLL -#define FT_EXPORT( x ) __declspec( dllexport ) x #else + +#if defined( _WIN32 ) && defined( DLL_IMPORT ) #define FT_EXPORT( x ) __declspec( dllimport ) x +#elif defined( __cplusplus ) +#define FT_EXPORT( x ) extern "C" x +#else +#define FT_EXPORT( x ) extern x #endif + #endif -#endif /* !__REACTOS__ */ #endif /* !FT_EXPORT */ @@ -501,7 +512,7 @@ FT_BEGIN_HEADER /* C++ compiler and with 16bit compilers. */ /* */ - /* This is special. Within C++, you must specify `extern "C"' for */ + /* This is special. Within C++, you must specify `extern "C"` for */ /* functions which are used via function pointers, and you also */ /* must do that for structures which contain function pointers to */ /* assure C linkage -- it's not possible to have (local) anonymous */ @@ -524,7 +535,7 @@ FT_BEGIN_HEADER /* */ /* */ /* Some 16bit compilers have to redefine these macros to insert */ - /* the infamous `_cdecl' or `__fastcall' declarations. */ + /* the infamous `_cdecl` or `__fastcall` declarations. */ /* */ #ifndef FT_CALLBACK_DEF #ifdef __cplusplus diff --git a/sdk/lib/3rdparty/freetype/include/freetype/config/ftheader.h b/sdk/lib/3rdparty/freetype/include/freetype/config/ftheader.h index 702f77cc4222d..696d6ba906633 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/config/ftheader.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/config/ftheader.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftheader.h */ -/* */ -/* Build macros of the FreeType 2 library. */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftheader.h + * + * Build macros of the FreeType 2 library. + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTHEADER_H_ #define FTHEADER_H_ @@ -27,7 +27,7 @@ /* */ /* This macro is used in association with @FT_END_HEADER in header */ /* files to ensure that the declarations within are properly */ - /* encapsulated in an `extern "C" { .. }' block when included from a */ + /* encapsulated in an `extern "C" { .. }` block when included from a */ /* C++ compiler. */ /* */ #ifdef __cplusplus @@ -45,7 +45,7 @@ /* */ /* This macro is used in association with @FT_BEGIN_HEADER in header */ /* files to ensure that the declarations within are properly */ - /* encapsulated in an `extern "C" { .. }' block when included from a */ + /* encapsulated in an `extern "C" { .. }` block when included from a */ /* C++ compiler. */ /* */ #ifdef __cplusplus @@ -55,54 +55,54 @@ #endif - /*************************************************************************/ - /* */ - /* Aliases for the FreeType 2 public and configuration files. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * Aliases for the FreeType 2 public and configuration files. + * + */ - /*************************************************************************/ - /* */ - /*
*/ - /* header_file_macros */ - /* */ - /* */ - /* Header File Macros */ - /* */ - /* <Abstract> */ - /* Macro definitions used to #include specific header files. */ - /* */ - /* <Description> */ - /* The following macros are defined to the name of specific */ - /* FreeType~2 header files. They can be used directly in #include */ - /* statements as in: */ - /* */ - /* { */ - /* #include FT_FREETYPE_H */ - /* #include FT_MULTIPLE_MASTERS_H */ - /* #include FT_GLYPH_H */ - /* } */ - /* */ - /* There are several reasons why we are now using macros to name */ - /* public header files. The first one is that such macros are not */ - /* limited to the infamous 8.3~naming rule required by DOS (and */ - /* `FT_MULTIPLE_MASTERS_H' is a lot more meaningful than `ftmm.h'). */ - /* */ - /* The second reason is that it allows for more flexibility in the */ - /* way FreeType~2 is installed on a given system. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * @section: + * header_file_macros + * + * @title: + * Header File Macros + * + * @abstract: + * Macro definitions used to `#include` specific header files. + * + * @description: + * The following macros are defined to the name of specific FreeType~2 + * header files. They can be used directly in `#include` statements as + * in: + * + * ``` + * #include FT_FREETYPE_H + * #include FT_MULTIPLE_MASTERS_H + * #include FT_GLYPH_H + * ``` + * + * There are several reasons why we are now using macros to name public + * header files. The first one is that such macros are not limited to + * the infamous 8.3~naming rule required by DOS (and + * `FT_MULTIPLE_MASTERS_H` is a lot more meaningful than `ftmm.h`). + * + * The second reason is that it allows for more flexibility in the way + * FreeType~2 is installed on a given system. + * + */ /* configuration files */ - /************************************************************************* + /************************************************************************** * * @macro: * FT_CONFIG_CONFIG_H * * @description: - * A macro used in #include statements to name the file containing + * A macro used in `#include` statements to name the file containing * FreeType~2 configuration data. * */ @@ -111,13 +111,13 @@ #endif - /************************************************************************* + /************************************************************************** * * @macro: * FT_CONFIG_STANDARD_LIBRARY_H * * @description: - * A macro used in #include statements to name the file containing + * A macro used in `#include` statements to name the file containing * FreeType~2 interface to the standard C library functions. * */ @@ -126,13 +126,13 @@ #endif - /************************************************************************* + /************************************************************************** * * @macro: * FT_CONFIG_OPTIONS_H * * @description: - * A macro used in #include statements to name the file containing + * A macro used in `#include` statements to name the file containing * FreeType~2 project-specific configuration options. * */ @@ -141,13 +141,13 @@ #endif - /************************************************************************* + /************************************************************************** * * @macro: * FT_CONFIG_MODULES_H * * @description: - * A macro used in #include statements to name the file containing the + * A macro used in `#include` statements to name the file containing the * list of FreeType~2 modules that are statically linked to new library * instances in @FT_Init_FreeType. * @@ -160,26 +160,26 @@ /* public headers */ - /************************************************************************* + /************************************************************************** * * @macro: * FT_FREETYPE_H * * @description: - * A macro used in #include statements to name the file containing the + * A macro used in `#include` statements to name the file containing the * base FreeType~2 API. * */ #define FT_FREETYPE_H <freetype/freetype.h> - /************************************************************************* + /************************************************************************** * * @macro: * FT_ERRORS_H * * @description: - * A macro used in #include statements to name the file containing the + * A macro used in `#include` statements to name the file containing the * list of FreeType~2 error codes (and messages). * * It is included by @FT_FREETYPE_H. @@ -188,26 +188,26 @@ #define FT_ERRORS_H <freetype/fterrors.h> - /************************************************************************* + /************************************************************************** * * @macro: * FT_MODULE_ERRORS_H * * @description: - * A macro used in #include statements to name the file containing the + * A macro used in `#include` statements to name the file containing the * list of FreeType~2 module error offsets (and messages). * */ #define FT_MODULE_ERRORS_H <freetype/ftmoderr.h> - /************************************************************************* + /************************************************************************** * * @macro: * FT_SYSTEM_H * * @description: - * A macro used in #include statements to name the file containing the + * A macro used in `#include` statements to name the file containing the * FreeType~2 interface to low-level operations (i.e., memory management * and stream i/o). * @@ -217,13 +217,13 @@ #define FT_SYSTEM_H <freetype/ftsystem.h> - /************************************************************************* + /************************************************************************** * * @macro: * FT_IMAGE_H * * @description: - * A macro used in #include statements to name the file containing type + * A macro used in `#include` statements to name the file containing type * definitions related to glyph images (i.e., bitmaps, outlines, * scan-converter parameters). * @@ -233,13 +233,13 @@ #define FT_IMAGE_H <freetype/ftimage.h> - /************************************************************************* + /************************************************************************** * * @macro: * FT_TYPES_H * * @description: - * A macro used in #include statements to name the file containing the + * A macro used in `#include` statements to name the file containing the * basic data types defined by FreeType~2. * * It is included by @FT_FREETYPE_H. @@ -248,13 +248,13 @@ #define FT_TYPES_H <freetype/fttypes.h> - /************************************************************************* + /************************************************************************** * * @macro: * FT_LIST_H * * @description: - * A macro used in #include statements to name the file containing the + * A macro used in `#include` statements to name the file containing the * list management API of FreeType~2. * * (Most applications will never need to include this file.) @@ -263,151 +263,151 @@ #define FT_LIST_H <freetype/ftlist.h> - /************************************************************************* + /************************************************************************** * * @macro: * FT_OUTLINE_H * * @description: - * A macro used in #include statements to name the file containing the + * A macro used in `#include` statements to name the file containing the * scalable outline management API of FreeType~2. * */ #define FT_OUTLINE_H <freetype/ftoutln.h> - /************************************************************************* + /************************************************************************** * * @macro: * FT_SIZES_H * * @description: - * A macro used in #include statements to name the file containing the + * A macro used in `#include` statements to name the file containing the * API which manages multiple @FT_Size objects per face. * */ #define FT_SIZES_H <freetype/ftsizes.h> - /************************************************************************* + /************************************************************************** * * @macro: * FT_MODULE_H * * @description: - * A macro used in #include statements to name the file containing the + * A macro used in `#include` statements to name the file containing the * module management API of FreeType~2. * */ #define FT_MODULE_H <freetype/ftmodapi.h> - /************************************************************************* + /************************************************************************** * * @macro: * FT_RENDER_H * * @description: - * A macro used in #include statements to name the file containing the + * A macro used in `#include` statements to name the file containing the * renderer module management API of FreeType~2. * */ #define FT_RENDER_H <freetype/ftrender.h> - /************************************************************************* + /************************************************************************** * * @macro: * FT_DRIVER_H * * @description: - * A macro used in #include statements to name the file containing + * A macro used in `#include` statements to name the file containing * structures and macros related to the driver modules. * */ #define FT_DRIVER_H <freetype/ftdriver.h> - /************************************************************************* + /************************************************************************** * * @macro: * FT_AUTOHINTER_H * * @description: - * A macro used in #include statements to name the file containing + * A macro used in `#include` statements to name the file containing * structures and macros related to the auto-hinting module. * - * Deprecated since version 2.9; use @FT_DRIVER_H instead. + * Deprecated since version~2.9; use @FT_DRIVER_H instead. * */ #define FT_AUTOHINTER_H FT_DRIVER_H - /************************************************************************* + /************************************************************************** * * @macro: * FT_CFF_DRIVER_H * * @description: - * A macro used in #include statements to name the file containing + * A macro used in `#include` statements to name the file containing * structures and macros related to the CFF driver module. * - * Deprecated since version 2.9; use @FT_DRIVER_H instead. + * Deprecated since version~2.9; use @FT_DRIVER_H instead. * */ #define FT_CFF_DRIVER_H FT_DRIVER_H - /************************************************************************* + /************************************************************************** * * @macro: * FT_TRUETYPE_DRIVER_H * * @description: - * A macro used in #include statements to name the file containing + * A macro used in `#include` statements to name the file containing * structures and macros related to the TrueType driver module. * - * Deprecated since version 2.9; use @FT_DRIVER_H instead. + * Deprecated since version~2.9; use @FT_DRIVER_H instead. * */ #define FT_TRUETYPE_DRIVER_H FT_DRIVER_H - /************************************************************************* + /************************************************************************** * * @macro: * FT_PCF_DRIVER_H * * @description: - * A macro used in #include statements to name the file containing + * A macro used in `#include` statements to name the file containing * structures and macros related to the PCF driver module. * - * Deprecated since version 2.9; use @FT_DRIVER_H instead. + * Deprecated since version~2.9; use @FT_DRIVER_H instead. * */ #define FT_PCF_DRIVER_H FT_DRIVER_H - /************************************************************************* + /************************************************************************** * * @macro: * FT_TYPE1_TABLES_H * * @description: - * A macro used in #include statements to name the file containing the + * A macro used in `#include` statements to name the file containing the * types and API specific to the Type~1 format. * */ #define FT_TYPE1_TABLES_H <freetype/t1tables.h> - /************************************************************************* + /************************************************************************** * * @macro: * FT_TRUETYPE_IDS_H * * @description: - * A macro used in #include statements to name the file containing the + * A macro used in `#include` statements to name the file containing the * enumeration values which identify name strings, languages, encodings, * etc. This file really contains a _large_ set of constant macro * definitions, taken from the TrueType and OpenType specifications. @@ -416,174 +416,172 @@ #define FT_TRUETYPE_IDS_H <freetype/ttnameid.h> - /************************************************************************* + /************************************************************************** * * @macro: * FT_TRUETYPE_TABLES_H * * @description: - * A macro used in #include statements to name the file containing the + * A macro used in `#include` statements to name the file containing the * types and API specific to the TrueType (as well as OpenType) format. * */ #define FT_TRUETYPE_TABLES_H <freetype/tttables.h> - /************************************************************************* + /************************************************************************** * * @macro: * FT_TRUETYPE_TAGS_H * * @description: - * A macro used in #include statements to name the file containing the - * definitions of TrueType four-byte `tags' which identify blocks in + * A macro used in `#include` statements to name the file containing the + * definitions of TrueType four-byte 'tags' which identify blocks in * SFNT-based font formats (i.e., TrueType and OpenType). * */ #define FT_TRUETYPE_TAGS_H <freetype/tttags.h> - /************************************************************************* + /************************************************************************** * * @macro: * FT_BDF_H * * @description: - * A macro used in #include statements to name the file containing the - * definitions of an API which accesses BDF-specific strings from a - * face. + * A macro used in `#include` statements to name the file containing the + * definitions of an API which accesses BDF-specific strings from a face. * */ #define FT_BDF_H <freetype/ftbdf.h> - /************************************************************************* + /************************************************************************** * * @macro: * FT_CID_H * * @description: - * A macro used in #include statements to name the file containing the - * definitions of an API which access CID font information from a - * face. + * A macro used in `#include` statements to name the file containing the + * definitions of an API which access CID font information from a face. * */ #define FT_CID_H <freetype/ftcid.h> - /************************************************************************* + /************************************************************************** * * @macro: * FT_GZIP_H * * @description: - * A macro used in #include statements to name the file containing the + * A macro used in `#include` statements to name the file containing the * definitions of an API which supports gzip-compressed files. * */ #define FT_GZIP_H <freetype/ftgzip.h> - /************************************************************************* + /************************************************************************** * * @macro: * FT_LZW_H * * @description: - * A macro used in #include statements to name the file containing the + * A macro used in `#include` statements to name the file containing the * definitions of an API which supports LZW-compressed files. * */ #define FT_LZW_H <freetype/ftlzw.h> - /************************************************************************* + /************************************************************************** * * @macro: * FT_BZIP2_H * * @description: - * A macro used in #include statements to name the file containing the + * A macro used in `#include` statements to name the file containing the * definitions of an API which supports bzip2-compressed files. * */ #define FT_BZIP2_H <freetype/ftbzip2.h> - /************************************************************************* + /************************************************************************** * * @macro: * FT_WINFONTS_H * * @description: - * A macro used in #include statements to name the file containing the + * A macro used in `#include` statements to name the file containing the * definitions of an API which supports Windows FNT files. * */ #define FT_WINFONTS_H <freetype/ftwinfnt.h> - /************************************************************************* + /************************************************************************** * * @macro: * FT_GLYPH_H * * @description: - * A macro used in #include statements to name the file containing the + * A macro used in `#include` statements to name the file containing the * API of the optional glyph management component. * */ #define FT_GLYPH_H <freetype/ftglyph.h> - /************************************************************************* + /************************************************************************** * * @macro: * FT_BITMAP_H * * @description: - * A macro used in #include statements to name the file containing the + * A macro used in `#include` statements to name the file containing the * API of the optional bitmap conversion component. * */ #define FT_BITMAP_H <freetype/ftbitmap.h> - /************************************************************************* + /************************************************************************** * * @macro: * FT_BBOX_H * * @description: - * A macro used in #include statements to name the file containing the + * A macro used in `#include` statements to name the file containing the * API of the optional exact bounding box computation routines. * */ #define FT_BBOX_H <freetype/ftbbox.h> - /************************************************************************* + /************************************************************************** * * @macro: * FT_CACHE_H * * @description: - * A macro used in #include statements to name the file containing the + * A macro used in `#include` statements to name the file containing the * API of the optional FreeType~2 cache sub-system. * */ #define FT_CACHE_H <freetype/ftcache.h> - /************************************************************************* + /************************************************************************** * * @macro: * FT_MAC_H * * @description: - * A macro used in #include statements to name the file containing the - * Macintosh-specific FreeType~2 API. The latter is used to access - * fonts embedded in resource forks. + * A macro used in `#include` statements to name the file containing the + * Macintosh-specific FreeType~2 API. The latter is used to access fonts + * embedded in resource forks. * * This header file must be explicitly included by client applications * compiled on the Mac (note that the base API still works though). @@ -592,105 +590,105 @@ #define FT_MAC_H <freetype/ftmac.h> - /************************************************************************* + /************************************************************************** * * @macro: * FT_MULTIPLE_MASTERS_H * * @description: - * A macro used in #include statements to name the file containing the + * A macro used in `#include` statements to name the file containing the * optional multiple-masters management API of FreeType~2. * */ #define FT_MULTIPLE_MASTERS_H <freetype/ftmm.h> - /************************************************************************* + /************************************************************************** * * @macro: * FT_SFNT_NAMES_H * * @description: - * A macro used in #include statements to name the file containing the - * optional FreeType~2 API which accesses embedded `name' strings in + * A macro used in `#include` statements to name the file containing the + * optional FreeType~2 API which accesses embedded 'name' strings in * SFNT-based font formats (i.e., TrueType and OpenType). * */ #define FT_SFNT_NAMES_H <freetype/ftsnames.h> - /************************************************************************* + /************************************************************************** * * @macro: * FT_OPENTYPE_VALIDATE_H * * @description: - * A macro used in #include statements to name the file containing the - * optional FreeType~2 API which validates OpenType tables (BASE, GDEF, - * GPOS, GSUB, JSTF). + * A macro used in `#include` statements to name the file containing the + * optional FreeType~2 API which validates OpenType tables ('BASE', + * 'GDEF', 'GPOS', 'GSUB', 'JSTF'). * */ #define FT_OPENTYPE_VALIDATE_H <freetype/ftotval.h> - /************************************************************************* + /************************************************************************** * * @macro: * FT_GX_VALIDATE_H * * @description: - * A macro used in #include statements to name the file containing the - * optional FreeType~2 API which validates TrueTypeGX/AAT tables (feat, - * mort, morx, bsln, just, kern, opbd, trak, prop). + * A macro used in `#include` statements to name the file containing the + * optional FreeType~2 API which validates TrueTypeGX/AAT tables ('feat', + * 'mort', 'morx', 'bsln', 'just', 'kern', 'opbd', 'trak', 'prop'). * */ #define FT_GX_VALIDATE_H <freetype/ftgxval.h> - /************************************************************************* + /************************************************************************** * * @macro: * FT_PFR_H * * @description: - * A macro used in #include statements to name the file containing the + * A macro used in `#include` statements to name the file containing the * FreeType~2 API which accesses PFR-specific data. * */ #define FT_PFR_H <freetype/ftpfr.h> - /************************************************************************* + /************************************************************************** * * @macro: * FT_STROKER_H * * @description: - * A macro used in #include statements to name the file containing the + * A macro used in `#include` statements to name the file containing the * FreeType~2 API which provides functions to stroke outline paths. */ #define FT_STROKER_H <freetype/ftstroke.h> - /************************************************************************* + /************************************************************************** * * @macro: * FT_SYNTHESIS_H * * @description: - * A macro used in #include statements to name the file containing the + * A macro used in `#include` statements to name the file containing the * FreeType~2 API which performs artificial obliquing and emboldening. */ #define FT_SYNTHESIS_H <freetype/ftsynth.h> - /************************************************************************* + /************************************************************************** * * @macro: * FT_FONT_FORMATS_H * * @description: - * A macro used in #include statements to name the file containing the + * A macro used in `#include` statements to name the file containing the * FreeType~2 API which provides functions specific to font formats. */ #define FT_FONT_FORMATS_H <freetype/ftfntfmt.h> @@ -699,67 +697,79 @@ #define FT_XFREE86_H FT_FONT_FORMATS_H - /************************************************************************* + /************************************************************************** * * @macro: * FT_TRIGONOMETRY_H * * @description: - * A macro used in #include statements to name the file containing the + * A macro used in `#include` statements to name the file containing the * FreeType~2 API which performs trigonometric computations (e.g., * cosines and arc tangents). */ #define FT_TRIGONOMETRY_H <freetype/fttrigon.h> - /************************************************************************* + /************************************************************************** * * @macro: * FT_LCD_FILTER_H * * @description: - * A macro used in #include statements to name the file containing the + * A macro used in `#include` statements to name the file containing the * FreeType~2 API which performs color filtering for subpixel rendering. */ #define FT_LCD_FILTER_H <freetype/ftlcdfil.h> - /************************************************************************* + /************************************************************************** * * @macro: * FT_INCREMENTAL_H * * @description: - * A macro used in #include statements to name the file containing the + * A macro used in `#include` statements to name the file containing the * FreeType~2 API which performs incremental glyph loading. */ #define FT_INCREMENTAL_H <freetype/ftincrem.h> - /************************************************************************* + /************************************************************************** * * @macro: * FT_GASP_H * * @description: - * A macro used in #include statements to name the file containing the + * A macro used in `#include` statements to name the file containing the * FreeType~2 API which returns entries from the TrueType GASP table. */ #define FT_GASP_H <freetype/ftgasp.h> - /************************************************************************* + /************************************************************************** * * @macro: * FT_ADVANCES_H * * @description: - * A macro used in #include statements to name the file containing the + * A macro used in `#include` statements to name the file containing the * FreeType~2 API which returns individual and ranged glyph advances. */ #define FT_ADVANCES_H <freetype/ftadvanc.h> + /************************************************************************** + * + * @macro: + * FT_COLOR_H + * + * @description: + * A macro used in `#include` statements to name the file containing the + * FreeType~2 API which handles the OpenType 'CPAL' table. + */ +#define FT_COLOR_H <freetype/ftcolor.h> + + /* */ /* These header files don't need to be included by the user. */ @@ -770,14 +780,14 @@ #define FT_UNPATENTED_HINTING_H <freetype/ftparams.h> #define FT_TRUETYPE_UNPATENTED_H <freetype/ftparams.h> - /* FT_CACHE_H is the only header file needed for the cache subsystem. */ + /* `FT_CACHE_H` is the only header file needed for the cache subsystem. */ #define FT_CACHE_IMAGE_H FT_CACHE_H #define FT_CACHE_SMALL_BITMAPS_H FT_CACHE_H #define FT_CACHE_CHARMAP_H FT_CACHE_H /* The internals of the cache sub-system are no longer exposed. We */ - /* default to FT_CACHE_H at the moment just in case, but we know of */ - /* no rogue client that uses them. */ + /* default to `FT_CACHE_H` at the moment just in case, but we know */ + /* of no rogue client that uses them. */ /* */ #define FT_CACHE_MANAGER_H FT_CACHE_H #define FT_CACHE_INTERNAL_MRU_H FT_CACHE_H @@ -789,8 +799,8 @@ /* - * Include internal headers definitions from <internal/...> - * only when building the library. + * Include internal headers definitions from `<internal/...>` only when + * building the library. */ #ifdef FT2_BUILD_LIBRARY #define FT_INTERNAL_INTERNAL_H <freetype/internal/internal.h> diff --git a/sdk/lib/3rdparty/freetype/include/freetype/config/ftmodule.h b/sdk/lib/3rdparty/freetype/include/freetype/config/ftmodule.h index 76d271a74b938..7c603e5327567 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/config/ftmodule.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/config/ftmodule.h @@ -1,12 +1,12 @@ /* - * This file registers the FreeType modules compiled into the library. + * This file registers the FreeType modules compiled into the library. * - * If you use GNU make, this file IS NOT USED! Instead, it is created in - * the objects directory (normally `<topdir>/objs/') based on information - * from `<topdir>/modules.cfg'. + * If you use GNU make, this file IS NOT USED! Instead, it is created in + * the objects directory (normally `<topdir>/objs/`) based on information + * from `<topdir>/modules.cfg`. * - * Please read `docs/INSTALL.ANY' and `docs/CUSTOMIZE' how to compile - * FreeType without GNU make. + * Please read `docs/INSTALL.ANY` and `docs/CUSTOMIZE` how to compile + * FreeType without GNU make. * */ diff --git a/sdk/lib/3rdparty/freetype/include/freetype/config/ftoption.h b/sdk/lib/3rdparty/freetype/include/freetype/config/ftoption.h index ae2c8bc38839d..86edef1066b20 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/config/ftoption.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/config/ftoption.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftoption.h */ -/* */ -/* User-selectable configuration macros (specification only). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftoption.h + * + * User-selectable configuration macros (specification only). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTOPTION_H_ @@ -25,45 +25,47 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* USER-SELECTABLE CONFIGURATION MACROS */ - /* */ - /* This file contains the default configuration macro definitions for */ - /* a standard build of the FreeType library. There are three ways to */ - /* use this file to build project-specific versions of the library: */ - /* */ - /* - You can modify this file by hand, but this is not recommended in */ - /* cases where you would like to build several versions of the */ - /* library from a single source directory. */ - /* */ - /* - You can put a copy of this file in your build directory, more */ - /* precisely in `$BUILD/freetype/config/ftoption.h', where `$BUILD' */ - /* is the name of a directory that is included _before_ the FreeType */ - /* include path during compilation. */ - /* */ - /* The default FreeType Makefiles and Jamfiles use the build */ - /* directory `builds/<system>' by default, but you can easily change */ - /* that for your own projects. */ - /* */ - /* - Copy the file <ft2build.h> to `$BUILD/ft2build.h' and modify it */ - /* slightly to pre-define the macro FT_CONFIG_OPTIONS_H used to */ - /* locate this file during the build. For example, */ - /* */ - /* #define FT_CONFIG_OPTIONS_H <myftoptions.h> */ - /* #include <freetype/config/ftheader.h> */ - /* */ - /* will use `$BUILD/myftoptions.h' instead of this file for macro */ - /* definitions. */ - /* */ - /* Note also that you can similarly pre-define the macro */ - /* FT_CONFIG_MODULES_H used to locate the file listing of the modules */ - /* that are statically linked to the library at compile time. By */ - /* default, this file is <freetype/config/ftmodule.h>. */ - /* */ - /* We highly recommend using the third method whenever possible. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * USER-SELECTABLE CONFIGURATION MACROS + * + * This file contains the default configuration macro definitions for a + * standard build of the FreeType library. There are three ways to use + * this file to build project-specific versions of the library: + * + * - You can modify this file by hand, but this is not recommended in + * cases where you would like to build several versions of the library + * from a single source directory. + * + * - You can put a copy of this file in your build directory, more + * precisely in `$BUILD/freetype/config/ftoption.h`, where `$BUILD` is + * the name of a directory that is included _before_ the FreeType include + * path during compilation. + * + * The default FreeType Makefiles and Jamfiles use the build directory + * `builds/<system>` by default, but you can easily change that for your + * own projects. + * + * - Copy the file <ft2build.h> to `$BUILD/ft2build.h` and modify it + * slightly to pre-define the macro `FT_CONFIG_OPTIONS_H` used to locate + * this file during the build. For example, + * + * ``` + * #define FT_CONFIG_OPTIONS_H <myftoptions.h> + * #include <freetype/config/ftheader.h> + * ``` + * + * will use `$BUILD/myftoptions.h` instead of this file for macro + * definitions. + * + * Note also that you can similarly pre-define the macro + * `FT_CONFIG_MODULES_H` used to locate the file listing of the modules + * that are statically linked to the library at compile time. By + * default, this file is `<freetype/config/ftmodule.h>`. + * + * We highly recommend using the third method whenever possible. + * + */ /*************************************************************************/ @@ -75,440 +77,443 @@ FT_BEGIN_HEADER /*************************************************************************/ - /*#***********************************************************************/ - /* */ - /* If you enable this configuration option, FreeType recognizes an */ - /* environment variable called `FREETYPE_PROPERTIES', which can be used */ - /* to control the various font drivers and modules. The controllable */ - /* properties are listed in the section @properties. */ - /* */ - /* `FREETYPE_PROPERTIES' has the following syntax form (broken here into */ - /* multiple lines for better readability). */ - /* */ - /* { */ - /* <optional whitespace> */ - /* <module-name1> ':' */ - /* <property-name1> '=' <property-value1> */ - /* <whitespace> */ - /* <module-name2> ':' */ - /* <property-name2> '=' <property-value2> */ - /* ... */ - /* } */ - /* */ - /* Example: */ - /* */ - /* FREETYPE_PROPERTIES=truetype:interpreter-version=35 \ */ - /* cff:no-stem-darkening=1 \ */ - /* autofitter:warping=1 */ - /* */ -//#define FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES + /*#************************************************************************ + * + * If you enable this configuration option, FreeType recognizes an + * environment variable called `FREETYPE_PROPERTIES`, which can be used to + * control the various font drivers and modules. The controllable + * properties are listed in the section @properties. + * + * You have to undefine this configuration option on platforms that lack + * the concept of environment variables (and thus don't have the `getenv` + * function), for example Windows CE. + * + * `FREETYPE_PROPERTIES` has the following syntax form (broken here into + * multiple lines for better readability). + * + * ``` + * <optional whitespace> + * <module-name1> ':' + * <property-name1> '=' <property-value1> + * <whitespace> + * <module-name2> ':' + * <property-name2> '=' <property-value2> + * ... + * ``` + * + * Example: + * + * ``` + * FREETYPE_PROPERTIES=truetype:interpreter-version=35 \ + * cff:no-stem-darkening=1 \ + * autofitter:warping=1 + * ``` + * + */ +#ifndef __REACTOS__ +#define FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES +#endif - /*************************************************************************/ - /* */ - /* Uncomment the line below if you want to activate LCD rendering */ - /* technology similar to ClearType in this build of the library. This */ - /* technology triples the resolution in the direction color subpixels. */ - /* To mitigate color fringes inherent to this technology, you also need */ - /* to explicitly set up LCD filtering. */ - /* */ - /* Note that this feature is covered by several Microsoft patents */ - /* and should not be activated in any default build of the library. */ - /* When this macro is not defined, FreeType offers alternative LCD */ - /* rendering technology that produces excellent output without LCD */ - /* filtering. */ - /* */ + /************************************************************************** + * + * Uncomment the line below if you want to activate LCD rendering + * technology similar to ClearType in this build of the library. This + * technology triples the resolution in the direction color subpixels. To + * mitigate color fringes inherent to this technology, you also need to + * explicitly set up LCD filtering. + * + * Note that this feature is covered by several Microsoft patents and + * should not be activated in any default build of the library. When this + * macro is not defined, FreeType offers alternative LCD rendering + * technology that produces excellent output without LCD filtering. + */ +#ifdef __REACTOS__ #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING +#else +/* #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ +#endif - /*************************************************************************/ - /* */ - /* Many compilers provide a non-ANSI 64-bit data type that can be used */ - /* by FreeType to speed up some computations. However, this will create */ - /* some problems when compiling the library in strict ANSI mode. */ - /* */ - /* For this reason, the use of 64-bit integers is normally disabled when */ - /* the __STDC__ macro is defined. You can however disable this by */ - /* defining the macro FT_CONFIG_OPTION_FORCE_INT64 here. */ - /* */ - /* For most compilers, this will only create compilation warnings when */ - /* building the library. */ - /* */ - /* ObNote: The compiler-specific 64-bit integers are detected in the */ - /* file `ftconfig.h' either statically or through the */ - /* `configure' script on supported platforms. */ - /* */ + /************************************************************************** + * + * Many compilers provide a non-ANSI 64-bit data type that can be used by + * FreeType to speed up some computations. However, this will create some + * problems when compiling the library in strict ANSI mode. + * + * For this reason, the use of 64-bit integers is normally disabled when + * the `__STDC__` macro is defined. You can however disable this by + * defining the macro `FT_CONFIG_OPTION_FORCE_INT64` here. + * + * For most compilers, this will only create compilation warnings when + * building the library. + * + * ObNote: The compiler-specific 64-bit integers are detected in the + * file `ftconfig.h` either statically or through the `configure` + * script on supported platforms. + */ #undef FT_CONFIG_OPTION_FORCE_INT64 - /*************************************************************************/ - /* */ - /* If this macro is defined, do not try to use an assembler version of */ - /* performance-critical functions (e.g. FT_MulFix). You should only do */ - /* that to verify that the assembler function works properly, or to */ - /* execute benchmark tests of the various implementations. */ + /************************************************************************** + * + * If this macro is defined, do not try to use an assembler version of + * performance-critical functions (e.g., @FT_MulFix). You should only do + * that to verify that the assembler function works properly, or to execute + * benchmark tests of the various implementations. + */ /* #define FT_CONFIG_OPTION_NO_ASSEMBLER */ - /*************************************************************************/ - /* */ - /* If this macro is defined, try to use an inlined assembler version of */ - /* the `FT_MulFix' function, which is a `hotspot' when loading and */ - /* hinting glyphs, and which should be executed as fast as possible. */ - /* */ - /* Note that if your compiler or CPU is not supported, this will default */ - /* to the standard and portable implementation found in `ftcalc.c'. */ - /* */ + /************************************************************************** + * + * If this macro is defined, try to use an inlined assembler version of the + * @FT_MulFix function, which is a 'hotspot' when loading and hinting + * glyphs, and which should be executed as fast as possible. + * + * Note that if your compiler or CPU is not supported, this will default to + * the standard and portable implementation found in `ftcalc.c`. + */ #define FT_CONFIG_OPTION_INLINE_MULFIX - /*************************************************************************/ - /* */ - /* LZW-compressed file support. */ - /* */ - /* FreeType now handles font files that have been compressed with the */ - /* `compress' program. This is mostly used to parse many of the PCF */ - /* files that come with various X11 distributions. The implementation */ - /* uses NetBSD's `zopen' to partially uncompress the file on the fly */ - /* (see src/lzw/ftgzip.c). */ - /* */ - /* Define this macro if you want to enable this `feature'. */ - /* */ + /************************************************************************** + * + * LZW-compressed file support. + * + * FreeType now handles font files that have been compressed with the + * `compress` program. This is mostly used to parse many of the PCF + * files that come with various X11 distributions. The implementation + * uses NetBSD's `zopen` to partially uncompress the file on the fly (see + * `src/lzw/ftgzip.c`). + * + * Define this macro if you want to enable this 'feature'. + */ #define FT_CONFIG_OPTION_USE_LZW - /*************************************************************************/ - /* */ - /* Gzip-compressed file support. */ - /* */ - /* FreeType now handles font files that have been compressed with the */ - /* `gzip' program. This is mostly used to parse many of the PCF files */ - /* that come with XFree86. The implementation uses `zlib' to */ - /* partially uncompress the file on the fly (see src/gzip/ftgzip.c). */ - /* */ - /* Define this macro if you want to enable this `feature'. See also */ - /* the macro FT_CONFIG_OPTION_SYSTEM_ZLIB below. */ - /* */ + /************************************************************************** + * + * Gzip-compressed file support. + * + * FreeType now handles font files that have been compressed with the + * `gzip` program. This is mostly used to parse many of the PCF files + * that come with XFree86. The implementation uses 'zlib' to partially + * uncompress the file on the fly (see `src/gzip/ftgzip.c`). + * + * Define this macro if you want to enable this 'feature'. See also the + * macro `FT_CONFIG_OPTION_SYSTEM_ZLIB` below. + */ #define FT_CONFIG_OPTION_USE_ZLIB - /*************************************************************************/ - /* */ - /* ZLib library selection */ - /* */ - /* This macro is only used when FT_CONFIG_OPTION_USE_ZLIB is defined. */ - /* It allows FreeType's `ftgzip' component to link to the system's */ - /* installation of the ZLib library. This is useful on systems like */ - /* Unix or VMS where it generally is already available. */ - /* */ - /* If you let it undefined, the component will use its own copy */ - /* of the zlib sources instead. These have been modified to be */ - /* included directly within the component and *not* export external */ - /* function names. This allows you to link any program with FreeType */ - /* _and_ ZLib without linking conflicts. */ - /* */ - /* Do not #undef this macro here since the build system might define */ - /* it for certain configurations only. */ - /* */ - /* If you use a build system like cmake or the `configure' script, */ - /* options set by those programs have precendence, overwriting the */ - /* value here with the configured one. */ - /* */ + /************************************************************************** + * + * ZLib library selection + * + * This macro is only used when `FT_CONFIG_OPTION_USE_ZLIB` is defined. + * It allows FreeType's 'ftgzip' component to link to the system's + * installation of the ZLib library. This is useful on systems like + * Unix or VMS where it generally is already available. + * + * If you let it undefined, the component will use its own copy of the + * zlib sources instead. These have been modified to be included + * directly within the component and **not** export external function + * names. This allows you to link any program with FreeType _and_ ZLib + * without linking conflicts. + * + * Do not `#undef` this macro here since the build system might define + * it for certain configurations only. + * + * If you use a build system like cmake or the `configure` script, + * options set by those programs have precedence, overwriting the value + * here with the configured one. + */ /* #define FT_CONFIG_OPTION_SYSTEM_ZLIB */ - /*************************************************************************/ - /* */ - /* Bzip2-compressed file support. */ - /* */ - /* FreeType now handles font files that have been compressed with the */ - /* `bzip2' program. This is mostly used to parse many of the PCF */ - /* files that come with XFree86. The implementation uses `libbz2' to */ - /* partially uncompress the file on the fly (see src/bzip2/ftbzip2.c). */ - /* Contrary to gzip, bzip2 currently is not included and need to use */ - /* the system available bzip2 implementation. */ - /* */ - /* Define this macro if you want to enable this `feature'. */ - /* */ - /* If you use a build system like cmake or the `configure' script, */ - /* options set by those programs have precendence, overwriting the */ - /* value here with the configured one. */ - /* */ + /************************************************************************** + * + * Bzip2-compressed file support. + * + * FreeType now handles font files that have been compressed with the + * `bzip2` program. This is mostly used to parse many of the PCF files + * that come with XFree86. The implementation uses `libbz2` to partially + * uncompress the file on the fly (see `src/bzip2/ftbzip2.c`). Contrary + * to gzip, bzip2 currently is not included and need to use the system + * available bzip2 implementation. + * + * Define this macro if you want to enable this 'feature'. + * + * If you use a build system like cmake or the `configure` script, + * options set by those programs have precedence, overwriting the value + * here with the configured one. + */ /* #define FT_CONFIG_OPTION_USE_BZIP2 */ - /*************************************************************************/ - /* */ - /* Define to disable the use of file stream functions and types, FILE, */ - /* fopen() etc. Enables the use of smaller system libraries on embedded */ - /* systems that have multiple system libraries, some with or without */ - /* file stream support, in the cases where file stream support is not */ - /* necessary such as memory loading of font files. */ - /* */ + /************************************************************************** + * + * Define to disable the use of file stream functions and types, `FILE`, + * `fopen`, etc. Enables the use of smaller system libraries on embedded + * systems that have multiple system libraries, some with or without file + * stream support, in the cases where file stream support is not necessary + * such as memory loading of font files. + */ /* #define FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT */ - /*************************************************************************/ - /* */ - /* PNG bitmap support. */ - /* */ - /* FreeType now handles loading color bitmap glyphs in the PNG format. */ - /* This requires help from the external libpng library. Uncompressed */ - /* color bitmaps do not need any external libraries and will be */ - /* supported regardless of this configuration. */ - /* */ - /* Define this macro if you want to enable this `feature'. */ - /* */ - /* If you use a build system like cmake or the `configure' script, */ - /* options set by those programs have precendence, overwriting the */ - /* value here with the configured one. */ - /* */ + /************************************************************************** + * + * PNG bitmap support. + * + * FreeType now handles loading color bitmap glyphs in the PNG format. + * This requires help from the external libpng library. Uncompressed + * color bitmaps do not need any external libraries and will be supported + * regardless of this configuration. + * + * Define this macro if you want to enable this 'feature'. + * + * If you use a build system like cmake or the `configure` script, + * options set by those programs have precedence, overwriting the value + * here with the configured one. + */ /* #define FT_CONFIG_OPTION_USE_PNG */ - /*************************************************************************/ - /* */ - /* HarfBuzz support. */ - /* */ - /* FreeType uses the HarfBuzz library to improve auto-hinting of */ - /* OpenType fonts. If available, many glyphs not directly addressable */ - /* by a font's character map will be hinted also. */ - /* */ - /* Define this macro if you want to enable this `feature'. */ - /* */ - /* If you use a build system like cmake or the `configure' script, */ - /* options set by those programs have precendence, overwriting the */ - /* value here with the configured one. */ - /* */ + /************************************************************************** + * + * HarfBuzz support. + * + * FreeType uses the HarfBuzz library to improve auto-hinting of OpenType + * fonts. If available, many glyphs not directly addressable by a font's + * character map will be hinted also. + * + * Define this macro if you want to enable this 'feature'. + * + * If you use a build system like cmake or the `configure` script, + * options set by those programs have precedence, overwriting the value + * here with the configured one. + */ /* #define FT_CONFIG_OPTION_USE_HARFBUZZ */ - /*************************************************************************/ - /* */ - /* Glyph Postscript Names handling */ - /* */ - /* By default, FreeType 2 is compiled with the `psnames' module. This */ - /* module is in charge of converting a glyph name string into a */ - /* Unicode value, or return a Macintosh standard glyph name for the */ - /* use with the TrueType `post' table. */ - /* */ - /* Undefine this macro if you do not want `psnames' compiled in your */ - /* build of FreeType. This has the following effects: */ - /* */ - /* - The TrueType driver will provide its own set of glyph names, */ - /* if you build it to support postscript names in the TrueType */ - /* `post' table, but will not synthesize a missing Unicode charmap. */ - /* */ - /* - The Type 1 driver will not be able to synthesize a Unicode */ - /* charmap out of the glyphs found in the fonts. */ - /* */ - /* You would normally undefine this configuration macro when building */ - /* a version of FreeType that doesn't contain a Type 1 or CFF driver. */ - /* */ + /************************************************************************** + * + * Glyph Postscript Names handling + * + * By default, FreeType 2 is compiled with the 'psnames' module. This + * module is in charge of converting a glyph name string into a Unicode + * value, or return a Macintosh standard glyph name for the use with the + * TrueType 'post' table. + * + * Undefine this macro if you do not want 'psnames' compiled in your + * build of FreeType. This has the following effects: + * + * - The TrueType driver will provide its own set of glyph names, if you + * build it to support postscript names in the TrueType 'post' table, + * but will not synthesize a missing Unicode charmap. + * + * - The Type~1 driver will not be able to synthesize a Unicode charmap + * out of the glyphs found in the fonts. + * + * You would normally undefine this configuration macro when building a + * version of FreeType that doesn't contain a Type~1 or CFF driver. + */ #define FT_CONFIG_OPTION_POSTSCRIPT_NAMES - /*************************************************************************/ - /* */ - /* Postscript Names to Unicode Values support */ - /* */ - /* By default, FreeType 2 is built with the `PSNames' module compiled */ - /* in. Among other things, the module is used to convert a glyph name */ - /* into a Unicode value. This is especially useful in order to */ - /* synthesize on the fly a Unicode charmap from the CFF/Type 1 driver */ - /* through a big table named the `Adobe Glyph List' (AGL). */ - /* */ - /* Undefine this macro if you do not want the Adobe Glyph List */ - /* compiled in your `PSNames' module. The Type 1 driver will not be */ - /* able to synthesize a Unicode charmap out of the glyphs found in the */ - /* fonts. */ - /* */ + /************************************************************************** + * + * Postscript Names to Unicode Values support + * + * By default, FreeType~2 is built with the 'psnames' module compiled in. + * Among other things, the module is used to convert a glyph name into a + * Unicode value. This is especially useful in order to synthesize on + * the fly a Unicode charmap from the CFF/Type~1 driver through a big + * table named the 'Adobe Glyph List' (AGL). + * + * Undefine this macro if you do not want the Adobe Glyph List compiled + * in your 'psnames' module. The Type~1 driver will not be able to + * synthesize a Unicode charmap out of the glyphs found in the fonts. + */ #define FT_CONFIG_OPTION_ADOBE_GLYPH_LIST - /*************************************************************************/ - /* */ - /* Support for Mac fonts */ - /* */ - /* Define this macro if you want support for outline fonts in Mac */ - /* format (mac dfont, mac resource, macbinary containing a mac */ - /* resource) on non-Mac platforms. */ - /* */ - /* Note that the `FOND' resource isn't checked. */ - /* */ + /************************************************************************** + * + * Support for Mac fonts + * + * Define this macro if you want support for outline fonts in Mac format + * (mac dfont, mac resource, macbinary containing a mac resource) on + * non-Mac platforms. + * + * Note that the 'FOND' resource isn't checked. + */ #define FT_CONFIG_OPTION_MAC_FONTS - /*************************************************************************/ - /* */ - /* Guessing methods to access embedded resource forks */ - /* */ - /* Enable extra Mac fonts support on non-Mac platforms (e.g. */ - /* GNU/Linux). */ - /* */ - /* Resource forks which include fonts data are stored sometimes in */ - /* locations which users or developers don't expected. In some cases, */ - /* resource forks start with some offset from the head of a file. In */ - /* other cases, the actual resource fork is stored in file different */ - /* from what the user specifies. If this option is activated, */ - /* FreeType tries to guess whether such offsets or different file */ - /* names must be used. */ - /* */ - /* Note that normal, direct access of resource forks is controlled via */ - /* the FT_CONFIG_OPTION_MAC_FONTS option. */ - /* */ + /************************************************************************** + * + * Guessing methods to access embedded resource forks + * + * Enable extra Mac fonts support on non-Mac platforms (e.g., GNU/Linux). + * + * Resource forks which include fonts data are stored sometimes in + * locations which users or developers don't expected. In some cases, + * resource forks start with some offset from the head of a file. In + * other cases, the actual resource fork is stored in file different from + * what the user specifies. If this option is activated, FreeType tries + * to guess whether such offsets or different file names must be used. + * + * Note that normal, direct access of resource forks is controlled via + * the `FT_CONFIG_OPTION_MAC_FONTS` option. + */ #ifdef FT_CONFIG_OPTION_MAC_FONTS #define FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK #endif - /*************************************************************************/ - /* */ - /* Allow the use of FT_Incremental_Interface to load typefaces that */ - /* contain no glyph data, but supply it via a callback function. */ - /* This is required by clients supporting document formats which */ - /* supply font data incrementally as the document is parsed, such */ - /* as the Ghostscript interpreter for the PostScript language. */ - /* */ + /************************************************************************** + * + * Allow the use of `FT_Incremental_Interface` to load typefaces that + * contain no glyph data, but supply it via a callback function. This is + * required by clients supporting document formats which supply font data + * incrementally as the document is parsed, such as the Ghostscript + * interpreter for the PostScript language. + */ #define FT_CONFIG_OPTION_INCREMENTAL - /*************************************************************************/ - /* */ - /* The size in bytes of the render pool used by the scan-line converter */ - /* to do all of its work. */ - /* */ + /************************************************************************** + * + * The size in bytes of the render pool used by the scan-line converter to + * do all of its work. + */ #define FT_RENDER_POOL_SIZE 16384L - /*************************************************************************/ - /* */ - /* FT_MAX_MODULES */ - /* */ - /* The maximum number of modules that can be registered in a single */ - /* FreeType library object. 32 is the default. */ - /* */ + /************************************************************************** + * + * FT_MAX_MODULES + * + * The maximum number of modules that can be registered in a single + * FreeType library object. 32~is the default. + */ #define FT_MAX_MODULES 32 - /*************************************************************************/ - /* */ - /* Debug level */ - /* */ - /* FreeType can be compiled in debug or trace mode. In debug mode, */ - /* errors are reported through the `ftdebug' component. In trace */ - /* mode, additional messages are sent to the standard output during */ - /* execution. */ - /* */ - /* Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode. */ - /* Define FT_DEBUG_LEVEL_TRACE to build it in trace mode. */ - /* */ - /* Don't define any of these macros to compile in `release' mode! */ - /* */ - /* Do not #undef these macros here since the build system might define */ - /* them for certain configurations only. */ - /* */ + /************************************************************************** + * + * Debug level + * + * FreeType can be compiled in debug or trace mode. In debug mode, + * errors are reported through the 'ftdebug' component. In trace mode, + * additional messages are sent to the standard output during execution. + * + * Define `FT_DEBUG_LEVEL_ERROR` to build the library in debug mode. + * Define `FT_DEBUG_LEVEL_TRACE` to build it in trace mode. + * + * Don't define any of these macros to compile in 'release' mode! + * + * Do not `#undef` these macros here since the build system might define + * them for certain configurations only. + */ +#if defined(__REACTOS__) && DBG && !defined(NDEBUG) +#define FT_DEBUG_LEVEL_ERROR +#else /* #define FT_DEBUG_LEVEL_ERROR */ /* #define FT_DEBUG_LEVEL_TRACE */ +#endif - /*************************************************************************/ - /* */ - /* Autofitter debugging */ - /* */ - /* If FT_DEBUG_AUTOFIT is defined, FreeType provides some means to */ - /* control the autofitter behaviour for debugging purposes with global */ - /* boolean variables (consequently, you should *never* enable this */ - /* while compiling in `release' mode): */ - /* */ - /* _af_debug_disable_horz_hints */ - /* _af_debug_disable_vert_hints */ - /* _af_debug_disable_blue_hints */ - /* */ - /* Additionally, the following functions provide dumps of various */ - /* internal autofit structures to stdout (using `printf'): */ - /* */ - /* af_glyph_hints_dump_points */ - /* af_glyph_hints_dump_segments */ - /* af_glyph_hints_dump_edges */ - /* af_glyph_hints_get_num_segments */ - /* af_glyph_hints_get_segment_offset */ - /* */ - /* As an argument, they use another global variable: */ - /* */ - /* _af_debug_hints */ - /* */ - /* Please have a look at the `ftgrid' demo program to see how those */ - /* variables and macros should be used. */ - /* */ - /* Do not #undef these macros here since the build system might define */ - /* them for certain configurations only. */ - /* */ + /************************************************************************** + * + * Autofitter debugging + * + * If `FT_DEBUG_AUTOFIT` is defined, FreeType provides some means to + * control the autofitter behaviour for debugging purposes with global + * boolean variables (consequently, you should **never** enable this + * while compiling in 'release' mode): + * + * ``` + * _af_debug_disable_horz_hints + * _af_debug_disable_vert_hints + * _af_debug_disable_blue_hints + * ``` + * + * Additionally, the following functions provide dumps of various + * internal autofit structures to stdout (using `printf`): + * + * ``` + * af_glyph_hints_dump_points + * af_glyph_hints_dump_segments + * af_glyph_hints_dump_edges + * af_glyph_hints_get_num_segments + * af_glyph_hints_get_segment_offset + * ``` + * + * As an argument, they use another global variable: + * + * ``` + * _af_debug_hints + * ``` + * + * Please have a look at the `ftgrid` demo program to see how those + * variables and macros should be used. + * + * Do not `#undef` these macros here since the build system might define + * them for certain configurations only. + */ /* #define FT_DEBUG_AUTOFIT */ - /*************************************************************************/ - /* */ - /* Memory Debugging */ - /* */ - /* FreeType now comes with an integrated memory debugger that is */ - /* capable of detecting simple errors like memory leaks or double */ - /* deletes. To compile it within your build of the library, you */ - /* should define FT_DEBUG_MEMORY here. */ - /* */ - /* Note that the memory debugger is only activated at runtime when */ - /* when the _environment_ variable `FT2_DEBUG_MEMORY' is defined also! */ - /* */ - /* Do not #undef this macro here since the build system might define */ - /* it for certain configurations only. */ - /* */ + /************************************************************************** + * + * Memory Debugging + * + * FreeType now comes with an integrated memory debugger that is capable + * of detecting simple errors like memory leaks or double deletes. To + * compile it within your build of the library, you should define + * `FT_DEBUG_MEMORY` here. + * + * Note that the memory debugger is only activated at runtime when when + * the _environment_ variable `FT2_DEBUG_MEMORY` is defined also! + * + * Do not `#undef` this macro here since the build system might define it + * for certain configurations only. + */ /* #define FT_DEBUG_MEMORY */ - /*************************************************************************/ - /* */ - /* Module errors */ - /* */ - /* If this macro is set (which is _not_ the default), the higher byte */ - /* of an error code gives the module in which the error has occurred, */ - /* while the lower byte is the real error code. */ - /* */ - /* Setting this macro makes sense for debugging purposes only, since */ - /* it would break source compatibility of certain programs that use */ - /* FreeType 2. */ - /* */ - /* More details can be found in the files ftmoderr.h and fterrors.h. */ - /* */ + /************************************************************************** + * + * Module errors + * + * If this macro is set (which is _not_ the default), the higher byte of + * an error code gives the module in which the error has occurred, while + * the lower byte is the real error code. + * + * Setting this macro makes sense for debugging purposes only, since it + * would break source compatibility of certain programs that use + * FreeType~2. + * + * More details can be found in the files `ftmoderr.h` and `fterrors.h`. + */ #undef FT_CONFIG_OPTION_USE_MODULE_ERRORS - /*************************************************************************/ - /* */ - /* Position Independent Code */ - /* */ - /* If this macro is set (which is _not_ the default), FreeType2 will */ - /* avoid creating constants that require address fixups. Instead the */ - /* constants will be moved into a struct and additional intialization */ - /* code will be used. */ - /* */ - /* Setting this macro is needed for systems that prohibit address */ - /* fixups, such as BREW. [Note that standard compilers like gcc or */ - /* clang handle PIC generation automatically; you don't have to set */ - /* FT_CONFIG_OPTION_PIC, which is only necessary for very special */ - /* compilers.] */ - /* */ - /* Note that FT_CONFIG_OPTION_PIC support is not available for all */ - /* modules (see `modules.cfg' for a complete list). For building with */ - /* FT_CONFIG_OPTION_PIC support, do the following. */ - /* */ - /* 0. Clone the repository. */ - /* 1. Define FT_CONFIG_OPTION_PIC. */ - /* 2. Remove all subdirectories in `src' that don't have */ - /* FT_CONFIG_OPTION_PIC support. */ - /* 3. Comment out the corresponding modules in `modules.cfg'. */ - /* 4. Compile. */ - /* */ -/* #define FT_CONFIG_OPTION_PIC */ + /************************************************************************** + * + * Error Strings + * + * If this macro is set, `FT_Error_String` will return meaningful + * descriptions. This is not enabled by default to reduce the overall + * size of FreeType. + * + * More details can be found in the file `fterrors.h`. + */ +/* #define FT_CONFIG_OPTION_ERROR_STRINGS */ /*************************************************************************/ @@ -520,50 +525,60 @@ FT_BEGIN_HEADER /*************************************************************************/ - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_EMBEDDED_BITMAPS if you want to support */ - /* embedded bitmaps in all formats using the SFNT module (namely */ - /* TrueType & OpenType). */ - /* */ + /************************************************************************** + * + * Define `TT_CONFIG_OPTION_EMBEDDED_BITMAPS` if you want to support + * embedded bitmaps in all formats using the 'sfnt' module (namely + * TrueType~& OpenType). + */ #define TT_CONFIG_OPTION_EMBEDDED_BITMAPS - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_POSTSCRIPT_NAMES if you want to be able to */ - /* load and enumerate the glyph Postscript names in a TrueType or */ - /* OpenType file. */ - /* */ - /* Note that when you do not compile the `PSNames' module by undefining */ - /* the above FT_CONFIG_OPTION_POSTSCRIPT_NAMES, the `sfnt' module will */ - /* contain additional code used to read the PS Names table from a font. */ - /* */ - /* (By default, the module uses `PSNames' to extract glyph names.) */ - /* */ + /************************************************************************** + * + * Define `TT_CONFIG_OPTION_COLOR_LAYERS` if you want to support coloured + * outlines (from the 'COLR'/'CPAL' tables) in all formats using the 'sfnt' + * module (namely TrueType~& OpenType). + */ +#define TT_CONFIG_OPTION_COLOR_LAYERS + + + /************************************************************************** + * + * Define `TT_CONFIG_OPTION_POSTSCRIPT_NAMES` if you want to be able to + * load and enumerate the glyph Postscript names in a TrueType or OpenType + * file. + * + * Note that when you do not compile the 'psnames' module by undefining the + * above `FT_CONFIG_OPTION_POSTSCRIPT_NAMES`, the 'sfnt' module will + * contain additional code used to read the PS Names table from a font. + * + * (By default, the module uses 'psnames' to extract glyph names.) + */ #define TT_CONFIG_OPTION_POSTSCRIPT_NAMES - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_SFNT_NAMES if your applications need to */ - /* access the internal name table in a SFNT-based format like TrueType */ - /* or OpenType. The name table contains various strings used to */ - /* describe the font, like family name, copyright, version, etc. It */ - /* does not contain any glyph name though. */ - /* */ - /* Accessing SFNT names is done through the functions declared in */ - /* `ftsnames.h'. */ - /* */ + /************************************************************************** + * + * Define `TT_CONFIG_OPTION_SFNT_NAMES` if your applications need to access + * the internal name table in a SFNT-based format like TrueType or + * OpenType. The name table contains various strings used to describe the + * font, like family name, copyright, version, etc. It does not contain + * any glyph name though. + * + * Accessing SFNT names is done through the functions declared in + * `ftsnames.h`. + */ #define TT_CONFIG_OPTION_SFNT_NAMES - /*************************************************************************/ - /* */ - /* TrueType CMap support */ - /* */ - /* Here you can fine-tune which TrueType CMap table format shall be */ - /* supported. */ + /************************************************************************** + * + * TrueType CMap support + * + * Here you can fine-tune which TrueType CMap table format shall be + * supported. + */ #define TT_CONFIG_CMAP_FORMAT_0 #define TT_CONFIG_CMAP_FORMAT_2 #define TT_CONFIG_CMAP_FORMAT_4 @@ -583,131 +598,130 @@ FT_BEGIN_HEADER /*************************************************************************/ /*************************************************************************/ - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_BYTECODE_INTERPRETER if you want to compile */ - /* a bytecode interpreter in the TrueType driver. */ - /* */ - /* By undefining this, you will only compile the code necessary to load */ - /* TrueType glyphs without hinting. */ - /* */ - /* Do not #undef this macro here, since the build system might */ - /* define it for certain configurations only. */ - /* */ + /************************************************************************** + * + * Define `TT_CONFIG_OPTION_BYTECODE_INTERPRETER` if you want to compile a + * bytecode interpreter in the TrueType driver. + * + * By undefining this, you will only compile the code necessary to load + * TrueType glyphs without hinting. + * + * Do not `#undef` this macro here, since the build system might define it + * for certain configurations only. + */ #define TT_CONFIG_OPTION_BYTECODE_INTERPRETER - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_SUBPIXEL_HINTING if you want to compile */ - /* subpixel hinting support into the TrueType driver. This modifies the */ - /* TrueType hinting mechanism when anything but FT_RENDER_MODE_MONO is */ - /* requested. */ - /* */ - /* In particular, it modifies the bytecode interpreter to interpret (or */ - /* not) instructions in a certain way so that all TrueType fonts look */ - /* like they do in a Windows ClearType (DirectWrite) environment. See */ - /* [1] for a technical overview on what this means. See `ttinterp.h' */ - /* for more details on the LEAN option. */ - /* */ - /* There are three possible values. */ - /* */ - /* Value 1: */ - /* This value is associated with the `Infinality' moniker, */ - /* contributed by an individual nicknamed Infinality with the goal of */ - /* making TrueType fonts render better than on Windows. A high */ - /* amount of configurability and flexibility, down to rules for */ - /* single glyphs in fonts, but also very slow. Its experimental and */ - /* slow nature and the original developer losing interest meant that */ - /* this option was never enabled in default builds. */ - /* */ - /* The corresponding interpreter version is v38. */ - /* */ - /* Value 2: */ - /* The new default mode for the TrueType driver. The Infinality code */ - /* base was stripped to the bare minimum and all configurability */ - /* removed in the name of speed and simplicity. The configurability */ - /* was mainly aimed at legacy fonts like Arial, Times New Roman, or */ - /* Courier. Legacy fonts are fonts that modify vertical stems to */ - /* achieve clean black-and-white bitmaps. The new mode focuses on */ - /* applying a minimal set of rules to all fonts indiscriminately so */ - /* that modern and web fonts render well while legacy fonts render */ - /* okay. */ - /* */ - /* The corresponding interpreter version is v40. */ - /* */ - /* Value 3: */ - /* Compile both, making both v38 and v40 available (the latter is the */ - /* default). */ - /* */ - /* By undefining these, you get rendering behavior like on Windows */ - /* without ClearType, i.e., Windows XP without ClearType enabled and */ - /* Win9x (interpreter version v35). Or not, depending on how much */ - /* hinting blood and testing tears the font designer put into a given */ - /* font. If you define one or both subpixel hinting options, you can */ - /* switch between between v35 and the ones you define (using */ - /* `FT_Property_Set'). */ - /* */ - /* This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be */ - /* defined. */ - /* */ - /* [1] https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx */ - /* */ + /************************************************************************** + * + * Define `TT_CONFIG_OPTION_SUBPIXEL_HINTING` if you want to compile + * subpixel hinting support into the TrueType driver. This modifies the + * TrueType hinting mechanism when anything but `FT_RENDER_MODE_MONO` is + * requested. + * + * In particular, it modifies the bytecode interpreter to interpret (or + * not) instructions in a certain way so that all TrueType fonts look like + * they do in a Windows ClearType (DirectWrite) environment. See [1] for a + * technical overview on what this means. See `ttinterp.h` for more + * details on the LEAN option. + * + * There are three possible values. + * + * Value 1: + * This value is associated with the 'Infinality' moniker, contributed by + * an individual nicknamed Infinality with the goal of making TrueType + * fonts render better than on Windows. A high amount of configurability + * and flexibility, down to rules for single glyphs in fonts, but also + * very slow. Its experimental and slow nature and the original + * developer losing interest meant that this option was never enabled in + * default builds. + * + * The corresponding interpreter version is v38. + * + * Value 2: + * The new default mode for the TrueType driver. The Infinality code + * base was stripped to the bare minimum and all configurability removed + * in the name of speed and simplicity. The configurability was mainly + * aimed at legacy fonts like 'Arial', 'Times New Roman', or 'Courier'. + * Legacy fonts are fonts that modify vertical stems to achieve clean + * black-and-white bitmaps. The new mode focuses on applying a minimal + * set of rules to all fonts indiscriminately so that modern and web + * fonts render well while legacy fonts render okay. + * + * The corresponding interpreter version is v40. + * + * Value 3: + * Compile both, making both v38 and v40 available (the latter is the + * default). + * + * By undefining these, you get rendering behavior like on Windows without + * ClearType, i.e., Windows XP without ClearType enabled and Win9x + * (interpreter version v35). Or not, depending on how much hinting blood + * and testing tears the font designer put into a given font. If you + * define one or both subpixel hinting options, you can switch between + * between v35 and the ones you define (using `FT_Property_Set`). + * + * This option requires `TT_CONFIG_OPTION_BYTECODE_INTERPRETER` to be + * defined. + * + * [1] + * https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx + */ /* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING 1 */ -/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING 2 */ +#define TT_CONFIG_OPTION_SUBPIXEL_HINTING 2 /* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING ( 1 | 2 ) */ - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED to compile the */ - /* TrueType glyph loader to use Apple's definition of how to handle */ - /* component offsets in composite glyphs. */ - /* */ - /* Apple and MS disagree on the default behavior of component offsets */ - /* in composites. Apple says that they should be scaled by the scaling */ - /* factors in the transformation matrix (roughly, it's more complex) */ - /* while MS says they should not. OpenType defines two bits in the */ - /* composite flags array which can be used to disambiguate, but old */ - /* fonts will not have them. */ - /* */ - /* https://www.microsoft.com/typography/otspec/glyf.htm */ - /* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6glyf.html */ - /* */ + /************************************************************************** + * + * Define `TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED` to compile the + * TrueType glyph loader to use Apple's definition of how to handle + * component offsets in composite glyphs. + * + * Apple and MS disagree on the default behavior of component offsets in + * composites. Apple says that they should be scaled by the scaling + * factors in the transformation matrix (roughly, it's more complex) while + * MS says they should not. OpenType defines two bits in the composite + * flags array which can be used to disambiguate, but old fonts will not + * have them. + * + * https://www.microsoft.com/typography/otspec/glyf.htm + * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6glyf.html + */ #undef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_GX_VAR_SUPPORT if you want to include */ - /* support for Apple's distortable font technology (fvar, gvar, cvar, */ - /* and avar tables). This has many similarities to Type 1 Multiple */ - /* Masters support. */ - /* */ + /************************************************************************** + * + * Define `TT_CONFIG_OPTION_GX_VAR_SUPPORT` if you want to include support + * for Apple's distortable font technology ('fvar', 'gvar', 'cvar', and + * 'avar' tables). Tagged 'Font Variations', this is now part of OpenType + * also. This has many similarities to Type~1 Multiple Masters support. + */ #define TT_CONFIG_OPTION_GX_VAR_SUPPORT - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_BDF if you want to include support for */ - /* an embedded `BDF ' table within SFNT-based bitmap formats. */ - /* */ + /************************************************************************** + * + * Define `TT_CONFIG_OPTION_BDF` if you want to include support for an + * embedded 'BDF~' table within SFNT-based bitmap formats. + */ #define TT_CONFIG_OPTION_BDF - /*************************************************************************/ - /* */ - /* Option TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES controls the maximum */ - /* number of bytecode instructions executed for a single run of the */ - /* bytecode interpreter, needed to prevent infinite loops. You don't */ - /* want to change this except for very special situations (e.g., making */ - /* a library fuzzer spend less time to handle broken fonts). */ - /* */ - /* It is not expected that this value is ever modified by a configuring */ - /* script; instead, it gets surrounded with #ifndef ... #endif so that */ - /* the value can be set as a preprocessor option on the compiler's */ - /* command line. */ - /* */ + /************************************************************************** + * + * Option `TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES` controls the maximum + * number of bytecode instructions executed for a single run of the + * bytecode interpreter, needed to prevent infinite loops. You don't want + * to change this except for very special situations (e.g., making a + * library fuzzer spend less time to handle broken fonts). + * + * It is not expected that this value is ever modified by a configuring + * script; instead, it gets surrounded with `#ifndef ... #endif` so that + * the value can be set as a preprocessor option on the compiler's command + * line. + */ #ifndef TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES #define TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES 1000000L #endif @@ -722,59 +736,58 @@ FT_BEGIN_HEADER /*************************************************************************/ - /*************************************************************************/ - /* */ - /* T1_MAX_DICT_DEPTH is the maximum depth of nest dictionaries and */ - /* arrays in the Type 1 stream (see t1load.c). A minimum of 4 is */ - /* required. */ - /* */ + /************************************************************************** + * + * `T1_MAX_DICT_DEPTH` is the maximum depth of nest dictionaries and arrays + * in the Type~1 stream (see `t1load.c`). A minimum of~4 is required. + */ #define T1_MAX_DICT_DEPTH 5 - /*************************************************************************/ - /* */ - /* T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine */ - /* calls during glyph loading. */ - /* */ + /************************************************************************** + * + * `T1_MAX_SUBRS_CALLS` details the maximum number of nested sub-routine + * calls during glyph loading. + */ #define T1_MAX_SUBRS_CALLS 16 - /*************************************************************************/ - /* */ - /* T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity. A */ - /* minimum of 16 is required. */ - /* */ - /* The Chinese font MingTiEG-Medium (CNS 11643 character set) needs 256. */ - /* */ + /************************************************************************** + * + * `T1_MAX_CHARSTRING_OPERANDS` is the charstring stack's capacity. A + * minimum of~16 is required. + * + * The Chinese font 'MingTiEG-Medium' (covering the CNS 11643 character + * set) needs 256. + */ #define T1_MAX_CHARSTRINGS_OPERANDS 256 - /*************************************************************************/ - /* */ - /* Define this configuration macro if you want to prevent the */ - /* compilation of `t1afm', which is in charge of reading Type 1 AFM */ - /* files into an existing face. Note that if set, the T1 driver will be */ - /* unable to produce kerning distances. */ - /* */ + /************************************************************************** + * + * Define this configuration macro if you want to prevent the compilation + * of the 't1afm' module, which is in charge of reading Type~1 AFM files + * into an existing face. Note that if set, the Type~1 driver will be + * unable to produce kerning distances. + */ #undef T1_CONFIG_OPTION_NO_AFM - /*************************************************************************/ - /* */ - /* Define this configuration macro if you want to prevent the */ - /* compilation of the Multiple Masters font support in the Type 1 */ - /* driver. */ - /* */ + /************************************************************************** + * + * Define this configuration macro if you want to prevent the compilation + * of the Multiple Masters font support in the Type~1 driver. + */ #undef T1_CONFIG_OPTION_NO_MM_SUPPORT - /*************************************************************************/ - /* */ - /* T1_CONFIG_OPTION_OLD_ENGINE controls whether the pre-Adobe Type 1 */ - /* engine gets compiled into FreeType. If defined, it is possible to */ - /* switch between the two engines using the `hinting-engine' property of */ - /* the type1 driver module. */ - /* */ + /************************************************************************** + * + * `T1_CONFIG_OPTION_OLD_ENGINE` controls whether the pre-Adobe Type~1 + * engine gets compiled into FreeType. If defined, it is possible to + * switch between the two engines using the `hinting-engine` property of + * the 'type1' driver module. + */ /* #define T1_CONFIG_OPTION_OLD_ENGINE */ @@ -787,17 +800,16 @@ FT_BEGIN_HEADER /*************************************************************************/ - /*************************************************************************/ - /* */ - /* Using CFF_CONFIG_OPTION_DARKENING_PARAMETER_{X,Y}{1,2,3,4} it is */ - /* possible to set up the default values of the four control points that */ - /* define the stem darkening behaviour of the (new) CFF engine. For */ - /* more details please read the documentation of the */ - /* `darkening-parameters' property (file `ftdriver.h'), which allows the */ - /* control at run-time. */ - /* */ - /* Do *not* undefine these macros! */ - /* */ + /************************************************************************** + * + * Using `CFF_CONFIG_OPTION_DARKENING_PARAMETER_{X,Y}{1,2,3,4}` it is + * possible to set up the default values of the four control points that + * define the stem darkening behaviour of the (new) CFF engine. For more + * details please read the documentation of the `darkening-parameters` + * property (file `ftdriver.h`), which allows the control at run-time. + * + * Do **not** undefine these macros! + */ #define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 500 #define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1 400 @@ -811,13 +823,13 @@ FT_BEGIN_HEADER #define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4 0 - /*************************************************************************/ - /* */ - /* CFF_CONFIG_OPTION_OLD_ENGINE controls whether the pre-Adobe CFF */ - /* engine gets compiled into FreeType. If defined, it is possible to */ - /* switch between the two engines using the `hinting-engine' property of */ - /* the cff driver module. */ - /* */ + /************************************************************************** + * + * `CFF_CONFIG_OPTION_OLD_ENGINE` controls whether the pre-Adobe CFF engine + * gets compiled into FreeType. If defined, it is possible to switch + * between the two engines using the `hinting-engine` property of the 'cff' + * driver module. + */ /* #define CFF_CONFIG_OPTION_OLD_ENGINE */ @@ -830,21 +842,21 @@ FT_BEGIN_HEADER /*************************************************************************/ - /*************************************************************************/ - /* */ - /* There are many PCF fonts just called `Fixed' which look completely */ - /* different, and which have nothing to do with each other. When */ - /* selecting `Fixed' in KDE or Gnome one gets results that appear rather */ - /* random, the style changes often if one changes the size and one */ - /* cannot select some fonts at all. This option makes the PCF module */ - /* prepend the foundry name (plus a space) to the family name. */ - /* */ - /* We also check whether we have `wide' characters; all put together, we */ - /* get family names like `Sony Fixed' or `Misc Fixed Wide'. */ - /* */ - /* If this option is activated, it can be controlled with the */ - /* `no-long-family-names' property of the pcf driver module. */ - /* */ + /************************************************************************** + * + * There are many PCF fonts just called 'Fixed' which look completely + * different, and which have nothing to do with each other. When selecting + * 'Fixed' in KDE or Gnome one gets results that appear rather random, the + * style changes often if one changes the size and one cannot select some + * fonts at all. This option makes the 'pcf' module prepend the foundry + * name (plus a space) to the family name. + * + * We also check whether we have 'wide' characters; all put together, we + * get family names like 'Sony Fixed' or 'Misc Fixed Wide'. + * + * If this option is activated, it can be controlled with the + * `no-long-family-names` property of the 'pcf' driver module. + */ /* #define PCF_CONFIG_OPTION_LONG_FAMILY_NAMES */ @@ -857,69 +869,76 @@ FT_BEGIN_HEADER /*************************************************************************/ - /*************************************************************************/ - /* */ - /* Compile autofit module with CJK (Chinese, Japanese, Korean) script */ - /* support. */ - /* */ + /************************************************************************** + * + * Compile 'autofit' module with CJK (Chinese, Japanese, Korean) script + * support. + */ #define AF_CONFIG_OPTION_CJK - /*************************************************************************/ - /* */ - /* Compile autofit module with fallback Indic script support, covering */ - /* some scripts that the `latin' submodule of the autofit module doesn't */ - /* (yet) handle. */ - /* */ + + /************************************************************************** + * + * Compile 'autofit' module with fallback Indic script support, covering + * some scripts that the 'latin' submodule of the 'autofit' module doesn't + * (yet) handle. + */ #define AF_CONFIG_OPTION_INDIC - /*************************************************************************/ - /* */ - /* Compile autofit module with warp hinting. The idea of the warping */ - /* code is to slightly scale and shift a glyph within a single dimension */ - /* so that as much of its segments are aligned (more or less) on the */ - /* grid. To find out the optimal scaling and shifting value, various */ - /* parameter combinations are tried and scored. */ - /* */ - /* This experimental option is active only if the rendering mode is */ - /* FT_RENDER_MODE_LIGHT; you can switch warping on and off with the */ - /* `warping' property of the auto-hinter (see file `ftdriver.h' for more */ - /* information; by default it is switched off). */ - /* */ + + /************************************************************************** + * + * Compile 'autofit' module with warp hinting. The idea of the warping + * code is to slightly scale and shift a glyph within a single dimension so + * that as much of its segments are aligned (more or less) on the grid. To + * find out the optimal scaling and shifting value, various parameter + * combinations are tried and scored. + * + * You can switch warping on and off with the `warping` property of the + * auto-hinter (see file `ftdriver.h` for more information; by default it + * is switched off). + * + * This experimental option is not active if the rendering mode is + * `FT_RENDER_MODE_LIGHT`. + */ #define AF_CONFIG_OPTION_USE_WARPER - /*************************************************************************/ - /* */ - /* Use TrueType-like size metrics for `light' auto-hinting. */ - /* */ - /* It is strongly recommended to avoid this option, which exists only to */ - /* help some legacy applications retain its appearance and behaviour */ - /* with respect to auto-hinted TrueType fonts. */ - /* */ - /* The very reason this option exists at all are GNU/Linux distributions */ - /* like Fedora that did not un-patch the following change (which was */ - /* present in FreeType between versions 2.4.6 and 2.7.1, inclusive). */ - /* */ - /* 2011-07-16 Steven Chu <steven.f.chu@gmail.com> */ - /* */ - /* [truetype] Fix metrics on size request for scalable fonts. */ - /* */ - /* This problematic commit is now reverted (more or less). */ - /* */ + + /************************************************************************** + * + * Use TrueType-like size metrics for 'light' auto-hinting. + * + * It is strongly recommended to avoid this option, which exists only to + * help some legacy applications retain its appearance and behaviour with + * respect to auto-hinted TrueType fonts. + * + * The very reason this option exists at all are GNU/Linux distributions + * like Fedora that did not un-patch the following change (which was + * present in FreeType between versions 2.4.6 and 2.7.1, inclusive). + * + * ``` + * 2011-07-16 Steven Chu <steven.f.chu@gmail.com> + * + * [truetype] Fix metrics on size request for scalable fonts. + * ``` + * + * This problematic commit is now reverted (more or less). + */ /* #define AF_CONFIG_OPTION_TT_SIZE_METRICS */ /* */ /* - * This macro is obsolete. Support has been removed in FreeType - * version 2.5. + * This macro is obsolete. Support has been removed in FreeType version + * 2.5. */ /* #define FT_CONFIG_OPTION_OLD_INTERNALS */ /* - * This macro is defined if native TrueType hinting is requested by the - * definitions above. + * The next three macros are defined if native TrueType hinting is + * requested by the definitions above. Don't change this. */ #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER #define TT_USE_BYTECODE_INTERPRETER @@ -938,7 +957,7 @@ FT_BEGIN_HEADER /* * Check CFF darkening parameters. The checks are the same as in function - * `cff_property_set' in file `cffdrivr.c'. + * `cff_property_set` in file `cffdrivr.c`. */ #if CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 < 0 || \ CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 < 0 || \ diff --git a/sdk/lib/3rdparty/freetype/include/freetype/config/ftstdlib.h b/sdk/lib/3rdparty/freetype/include/freetype/config/ftstdlib.h index 42f9a06e43975..438b6145d51b8 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/config/ftstdlib.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/config/ftstdlib.h @@ -1,31 +1,31 @@ -/***************************************************************************/ -/* */ -/* ftstdlib.h */ -/* */ -/* ANSI-specific library and header configuration file (specification */ -/* only). */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to group all #includes to the ANSI C library that */ - /* FreeType normally requires. It also defines macros to rename the */ - /* standard functions within the FreeType source code. */ - /* */ - /* Load a file which defines FTSTDLIB_H_ before this one to override it. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * ftstdlib.h + * + * ANSI-specific library and header configuration file (specification + * only). + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /************************************************************************** + * + * This file is used to group all `#includes` to the ANSI~C library that + * FreeType normally requires. It also defines macros to rename the + * standard functions within the FreeType source code. + * + * Load a file which defines `FTSTDLIB_H_` before this one to override it. + * + */ #ifndef FTSTDLIB_H_ @@ -37,23 +37,23 @@ #define ft_ptrdiff_t ptrdiff_t - /**********************************************************************/ - /* */ - /* integer limits */ - /* */ - /* UINT_MAX and ULONG_MAX are used to automatically compute the size */ - /* of `int' and `long' in bytes at compile-time. So far, this works */ - /* for all platforms the library has been tested on. */ - /* */ - /* Note that on the extremely rare platforms that do not provide */ - /* integer types that are _exactly_ 16 and 32 bits wide (e.g. some */ - /* old Crays where `int' is 36 bits), we do not make any guarantee */ - /* about the correct behaviour of FT2 with all fonts. */ - /* */ - /* In these case, `ftconfig.h' will refuse to compile anyway with a */ - /* message like `couldn't find 32-bit type' or something similar. */ - /* */ - /**********************************************************************/ + /************************************************************************** + * + * integer limits + * + * `UINT_MAX` and `ULONG_MAX` are used to automatically compute the size of + * `int` and `long` in bytes at compile-time. So far, this works for all + * platforms the library has been tested on. + * + * Note that on the extremely rare platforms that do not provide integer + * types that are _exactly_ 16 and 32~bits wide (e.g., some old Crays where + * `int` is 36~bits), we do not make any guarantee about the correct + * behaviour of FreeType~2 with all fonts. + * + * In these cases, `ftconfig.h` will refuse to compile anyway with a + * message like 'couldn't find 32-bit type' or something similar. + * + */ #include <limits.h> @@ -68,11 +68,11 @@ #define FT_ULONG_MAX ULONG_MAX - /**********************************************************************/ - /* */ - /* character and string processing */ - /* */ - /**********************************************************************/ + /************************************************************************** + * + * character and string processing + * + */ #include <string.h> @@ -92,11 +92,11 @@ #define ft_strstr strstr - /**********************************************************************/ - /* */ - /* file handling */ - /* */ - /**********************************************************************/ + /************************************************************************** + * + * file handling + * + */ #include <stdio.h> @@ -110,11 +110,11 @@ #define ft_sprintf sprintf - /**********************************************************************/ - /* */ - /* sorting */ - /* */ - /**********************************************************************/ + /************************************************************************** + * + * sorting + * + */ #include <stdlib.h> @@ -122,11 +122,11 @@ #define ft_qsort qsort - /**********************************************************************/ - /* */ - /* memory allocation */ - /* */ - /**********************************************************************/ + /************************************************************************** + * + * memory allocation + * + */ #define ft_scalloc calloc @@ -135,36 +135,36 @@ #define ft_srealloc realloc - /**********************************************************************/ - /* */ - /* miscellaneous */ - /* */ - /**********************************************************************/ + /************************************************************************** + * + * miscellaneous + * + */ #define ft_strtol strtol #define ft_getenv getenv - /**********************************************************************/ - /* */ - /* execution control */ - /* */ - /**********************************************************************/ + /************************************************************************** + * + * execution control + * + */ #include <setjmp.h> -#define ft_jmp_buf jmp_buf /* note: this cannot be a typedef since */ - /* jmp_buf is defined as a macro */ - /* on certain platforms */ +#define ft_jmp_buf jmp_buf /* note: this cannot be a typedef since */ + /* `jmp_buf` is defined as a macro */ + /* on certain platforms */ #define ft_longjmp longjmp #define ft_setjmp( b ) setjmp( *(ft_jmp_buf*) &(b) ) /* same thing here */ - /* the following is only used for debugging purposes, i.e., if */ - /* FT_DEBUG_LEVEL_ERROR or FT_DEBUG_LEVEL_TRACE are defined */ + /* The following is only used for debugging purposes, i.e., if */ + /* `FT_DEBUG_LEVEL_ERROR` or `FT_DEBUG_LEVEL_TRACE` are defined. */ #include <stdarg.h> diff --git a/sdk/lib/3rdparty/freetype/include/freetype/freetype.h b/sdk/lib/3rdparty/freetype/include/freetype/freetype.h index eda95e2abe4ba..4f2eaca691908 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/freetype.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/freetype.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* freetype.h */ -/* */ -/* FreeType high-level API and common types (specification only). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * freetype.h + * + * FreeType high-level API and common types (specification only). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FREETYPE_H_ @@ -39,56 +39,55 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* <Section> */ - /* header_inclusion */ - /* */ - /* <Title> */ - /* FreeType's header inclusion scheme */ - /* */ - /* <Abstract> */ - /* How client applications should include FreeType header files. */ - /* */ - /* <Description> */ - /* To be as flexible as possible (and for historical reasons), */ - /* FreeType uses a very special inclusion scheme to load header */ - /* files, for example */ - /* */ - /* { */ - /* #include <ft2build.h> */ - /* */ - /* #include FT_FREETYPE_H */ - /* #include FT_OUTLINE_H */ - /* } */ - /* */ - /* A compiler and its preprocessor only needs an include path to find */ - /* the file `ft2build.h'; the exact locations and names of the other */ - /* FreeType header files are hidden by preprocessor macro names, */ - /* loaded by `ft2build.h'. The API documentation always gives the */ - /* header macro name needed for a particular function. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * @section: + * header_inclusion + * + * @title: + * FreeType's header inclusion scheme + * + * @abstract: + * How client applications should include FreeType header files. + * + * @description: + * To be as flexible as possible (and for historical reasons), FreeType + * uses a very special inclusion scheme to load header files, for example + * + * ``` + * #include <ft2build.h> + * + * #include FT_FREETYPE_H + * #include FT_OUTLINE_H + * ``` + * + * A compiler and its preprocessor only needs an include path to find the + * file `ft2build.h`; the exact locations and names of the other FreeType + * header files are hidden by @header_file_macros, loaded by + * `ft2build.h`. The API documentation always gives the header macro + * name needed for a particular function. + * + */ - /*************************************************************************/ - /* */ - /* <Section> */ - /* user_allocation */ - /* */ - /* <Title> */ - /* User allocation */ - /* */ - /* <Abstract> */ - /* How client applications should allocate FreeType data structures. */ - /* */ - /* <Description> */ - /* FreeType assumes that structures allocated by the user and passed */ - /* as arguments are zeroed out except for the actual data. In other */ - /* words, it is recommended to use `calloc' (or variants of it) */ - /* instead of `malloc' for allocation. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * @section: + * user_allocation + * + * @title: + * User allocation + * + * @abstract: + * How client applications should allocate FreeType data structures. + * + * @description: + * FreeType assumes that structures allocated by the user and passed as + * arguments are zeroed out except for the actual data. In other words, + * it is recommended to use `calloc` (or variants of it) instead of + * `malloc` for allocation. + * + */ @@ -101,219 +100,219 @@ FT_BEGIN_HEADER /*************************************************************************/ - /*************************************************************************/ - /* */ - /* <Section> */ - /* base_interface */ - /* */ - /* <Title> */ - /* Base Interface */ - /* */ - /* <Abstract> */ - /* The FreeType~2 base font interface. */ - /* */ - /* <Description> */ - /* This section describes the most important public high-level API */ - /* functions of FreeType~2. */ - /* */ - /* <Order> */ - /* FT_Library */ - /* FT_Face */ - /* FT_Size */ - /* FT_GlyphSlot */ - /* FT_CharMap */ - /* FT_Encoding */ - /* FT_ENC_TAG */ - /* */ - /* FT_FaceRec */ - /* */ - /* FT_FACE_FLAG_SCALABLE */ - /* FT_FACE_FLAG_FIXED_SIZES */ - /* FT_FACE_FLAG_FIXED_WIDTH */ - /* FT_FACE_FLAG_HORIZONTAL */ - /* FT_FACE_FLAG_VERTICAL */ - /* FT_FACE_FLAG_COLOR */ - /* FT_FACE_FLAG_SFNT */ - /* FT_FACE_FLAG_CID_KEYED */ - /* FT_FACE_FLAG_TRICKY */ - /* FT_FACE_FLAG_KERNING */ - /* FT_FACE_FLAG_MULTIPLE_MASTERS */ - /* FT_FACE_FLAG_VARIATION */ - /* FT_FACE_FLAG_GLYPH_NAMES */ - /* FT_FACE_FLAG_EXTERNAL_STREAM */ - /* FT_FACE_FLAG_HINTER */ - /* */ - /* FT_HAS_HORIZONTAL */ - /* FT_HAS_VERTICAL */ - /* FT_HAS_KERNING */ - /* FT_HAS_FIXED_SIZES */ - /* FT_HAS_GLYPH_NAMES */ - /* FT_HAS_COLOR */ - /* FT_HAS_MULTIPLE_MASTERS */ - /* */ - /* FT_IS_SFNT */ - /* FT_IS_SCALABLE */ - /* FT_IS_FIXED_WIDTH */ - /* FT_IS_CID_KEYED */ - /* FT_IS_TRICKY */ - /* FT_IS_NAMED_INSTANCE */ - /* FT_IS_VARIATION */ - /* */ - /* FT_STYLE_FLAG_BOLD */ - /* FT_STYLE_FLAG_ITALIC */ - /* */ - /* FT_SizeRec */ - /* FT_Size_Metrics */ - /* */ - /* FT_GlyphSlotRec */ - /* FT_Glyph_Metrics */ - /* FT_SubGlyph */ - /* */ - /* FT_Bitmap_Size */ - /* */ - /* FT_Init_FreeType */ - /* FT_Done_FreeType */ - /* */ - /* FT_New_Face */ - /* FT_Done_Face */ - /* FT_Reference_Face */ - /* FT_New_Memory_Face */ - /* FT_Face_Properties */ - /* FT_Open_Face */ - /* FT_Open_Args */ - /* FT_Parameter */ - /* FT_Attach_File */ - /* FT_Attach_Stream */ - /* */ - /* FT_Set_Char_Size */ - /* FT_Set_Pixel_Sizes */ - /* FT_Request_Size */ - /* FT_Select_Size */ - /* FT_Size_Request_Type */ - /* FT_Size_RequestRec */ - /* FT_Size_Request */ - /* FT_Set_Transform */ - /* FT_Load_Glyph */ - /* FT_Get_Char_Index */ - /* FT_Get_First_Char */ - /* FT_Get_Next_Char */ - /* FT_Get_Name_Index */ - /* FT_Load_Char */ - /* */ - /* FT_OPEN_MEMORY */ - /* FT_OPEN_STREAM */ - /* FT_OPEN_PATHNAME */ - /* FT_OPEN_DRIVER */ - /* FT_OPEN_PARAMS */ - /* */ - /* FT_LOAD_DEFAULT */ - /* FT_LOAD_RENDER */ - /* FT_LOAD_MONOCHROME */ - /* FT_LOAD_LINEAR_DESIGN */ - /* FT_LOAD_NO_SCALE */ - /* FT_LOAD_NO_HINTING */ - /* FT_LOAD_NO_BITMAP */ - /* FT_LOAD_NO_AUTOHINT */ - /* FT_LOAD_COLOR */ - /* */ - /* FT_LOAD_VERTICAL_LAYOUT */ - /* FT_LOAD_IGNORE_TRANSFORM */ - /* FT_LOAD_FORCE_AUTOHINT */ - /* FT_LOAD_NO_RECURSE */ - /* FT_LOAD_PEDANTIC */ - /* */ - /* FT_LOAD_TARGET_NORMAL */ - /* FT_LOAD_TARGET_LIGHT */ - /* FT_LOAD_TARGET_MONO */ - /* FT_LOAD_TARGET_LCD */ - /* FT_LOAD_TARGET_LCD_V */ - /* */ - /* FT_LOAD_TARGET_MODE */ - /* */ - /* FT_Render_Glyph */ - /* FT_Render_Mode */ - /* FT_Get_Kerning */ - /* FT_Kerning_Mode */ - /* FT_Get_Track_Kerning */ - /* FT_Get_Glyph_Name */ - /* FT_Get_Postscript_Name */ - /* */ - /* FT_CharMapRec */ - /* FT_Select_Charmap */ - /* FT_Set_Charmap */ - /* FT_Get_Charmap_Index */ - /* */ - /* FT_Get_FSType_Flags */ - /* FT_Get_SubGlyph_Info */ - /* */ - /* FT_Face_Internal */ - /* FT_Size_Internal */ - /* FT_Slot_Internal */ - /* */ - /* FT_FACE_FLAG_XXX */ - /* FT_STYLE_FLAG_XXX */ - /* FT_OPEN_XXX */ - /* FT_LOAD_XXX */ - /* FT_LOAD_TARGET_XXX */ - /* FT_SUBGLYPH_FLAG_XXX */ - /* FT_FSTYPE_XXX */ - /* */ - /* FT_HAS_FAST_GLYPHS */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * @section: + * base_interface + * + * @title: + * Base Interface + * + * @abstract: + * The FreeType~2 base font interface. + * + * @description: + * This section describes the most important public high-level API + * functions of FreeType~2. + * + * @order: + * FT_Library + * FT_Face + * FT_Size + * FT_GlyphSlot + * FT_CharMap + * FT_Encoding + * FT_ENC_TAG + * + * FT_FaceRec + * + * FT_FACE_FLAG_SCALABLE + * FT_FACE_FLAG_FIXED_SIZES + * FT_FACE_FLAG_FIXED_WIDTH + * FT_FACE_FLAG_HORIZONTAL + * FT_FACE_FLAG_VERTICAL + * FT_FACE_FLAG_COLOR + * FT_FACE_FLAG_SFNT + * FT_FACE_FLAG_CID_KEYED + * FT_FACE_FLAG_TRICKY + * FT_FACE_FLAG_KERNING + * FT_FACE_FLAG_MULTIPLE_MASTERS + * FT_FACE_FLAG_VARIATION + * FT_FACE_FLAG_GLYPH_NAMES + * FT_FACE_FLAG_EXTERNAL_STREAM + * FT_FACE_FLAG_HINTER + * + * FT_HAS_HORIZONTAL + * FT_HAS_VERTICAL + * FT_HAS_KERNING + * FT_HAS_FIXED_SIZES + * FT_HAS_GLYPH_NAMES + * FT_HAS_COLOR + * FT_HAS_MULTIPLE_MASTERS + * + * FT_IS_SFNT + * FT_IS_SCALABLE + * FT_IS_FIXED_WIDTH + * FT_IS_CID_KEYED + * FT_IS_TRICKY + * FT_IS_NAMED_INSTANCE + * FT_IS_VARIATION + * + * FT_STYLE_FLAG_BOLD + * FT_STYLE_FLAG_ITALIC + * + * FT_SizeRec + * FT_Size_Metrics + * + * FT_GlyphSlotRec + * FT_Glyph_Metrics + * FT_SubGlyph + * + * FT_Bitmap_Size + * + * FT_Init_FreeType + * FT_Done_FreeType + * + * FT_New_Face + * FT_Done_Face + * FT_Reference_Face + * FT_New_Memory_Face + * FT_Face_Properties + * FT_Open_Face + * FT_Open_Args + * FT_Parameter + * FT_Attach_File + * FT_Attach_Stream + * + * FT_Set_Char_Size + * FT_Set_Pixel_Sizes + * FT_Request_Size + * FT_Select_Size + * FT_Size_Request_Type + * FT_Size_RequestRec + * FT_Size_Request + * FT_Set_Transform + * FT_Load_Glyph + * FT_Get_Char_Index + * FT_Get_First_Char + * FT_Get_Next_Char + * FT_Get_Name_Index + * FT_Load_Char + * + * FT_OPEN_MEMORY + * FT_OPEN_STREAM + * FT_OPEN_PATHNAME + * FT_OPEN_DRIVER + * FT_OPEN_PARAMS + * + * FT_LOAD_DEFAULT + * FT_LOAD_RENDER + * FT_LOAD_MONOCHROME + * FT_LOAD_LINEAR_DESIGN + * FT_LOAD_NO_SCALE + * FT_LOAD_NO_HINTING + * FT_LOAD_NO_BITMAP + * FT_LOAD_NO_AUTOHINT + * FT_LOAD_COLOR + * + * FT_LOAD_VERTICAL_LAYOUT + * FT_LOAD_IGNORE_TRANSFORM + * FT_LOAD_FORCE_AUTOHINT + * FT_LOAD_NO_RECURSE + * FT_LOAD_PEDANTIC + * + * FT_LOAD_TARGET_NORMAL + * FT_LOAD_TARGET_LIGHT + * FT_LOAD_TARGET_MONO + * FT_LOAD_TARGET_LCD + * FT_LOAD_TARGET_LCD_V + * + * FT_LOAD_TARGET_MODE + * + * FT_Render_Glyph + * FT_Render_Mode + * FT_Get_Kerning + * FT_Kerning_Mode + * FT_Get_Track_Kerning + * FT_Get_Glyph_Name + * FT_Get_Postscript_Name + * + * FT_CharMapRec + * FT_Select_Charmap + * FT_Set_Charmap + * FT_Get_Charmap_Index + * + * FT_Get_FSType_Flags + * FT_Get_SubGlyph_Info + * + * FT_Face_Internal + * FT_Size_Internal + * FT_Slot_Internal + * + * FT_FACE_FLAG_XXX + * FT_STYLE_FLAG_XXX + * FT_OPEN_XXX + * FT_LOAD_XXX + * FT_LOAD_TARGET_XXX + * FT_SUBGLYPH_FLAG_XXX + * FT_FSTYPE_XXX + * + * FT_HAS_FAST_GLYPHS + * + */ - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Glyph_Metrics */ - /* */ - /* <Description> */ - /* A structure to model the metrics of a single glyph. The values */ - /* are expressed in 26.6 fractional pixel format; if the flag */ - /* @FT_LOAD_NO_SCALE has been used while loading the glyph, values */ - /* are expressed in font units instead. */ - /* */ - /* <Fields> */ - /* width :: */ - /* The glyph's width. */ - /* */ - /* height :: */ - /* The glyph's height. */ - /* */ - /* horiBearingX :: */ - /* Left side bearing for horizontal layout. */ - /* */ - /* horiBearingY :: */ - /* Top side bearing for horizontal layout. */ - /* */ - /* horiAdvance :: */ - /* Advance width for horizontal layout. */ - /* */ - /* vertBearingX :: */ - /* Left side bearing for vertical layout. */ - /* */ - /* vertBearingY :: */ - /* Top side bearing for vertical layout. Larger positive values */ - /* mean further below the vertical glyph origin. */ - /* */ - /* vertAdvance :: */ - /* Advance height for vertical layout. Positive values mean the */ - /* glyph has a positive advance downward. */ - /* */ - /* <Note> */ - /* If not disabled with @FT_LOAD_NO_HINTING, the values represent */ - /* dimensions of the hinted glyph (in case hinting is applicable). */ - /* */ - /* Stroking a glyph with an outside border does not increase */ - /* `horiAdvance' or `vertAdvance'; you have to manually adjust these */ - /* values to account for the added width and height. */ - /* */ - /* FreeType doesn't use the `VORG' table data for CFF fonts because */ - /* it doesn't have an interface to quickly retrieve the glyph height. */ - /* The y~coordinate of the vertical origin can be simply computed as */ - /* `vertBearingY + height' after loading a glyph. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_Glyph_Metrics + * + * @description: + * A structure to model the metrics of a single glyph. The values are + * expressed in 26.6 fractional pixel format; if the flag + * @FT_LOAD_NO_SCALE has been used while loading the glyph, values are + * expressed in font units instead. + * + * @fields: + * width :: + * The glyph's width. + * + * height :: + * The glyph's height. + * + * horiBearingX :: + * Left side bearing for horizontal layout. + * + * horiBearingY :: + * Top side bearing for horizontal layout. + * + * horiAdvance :: + * Advance width for horizontal layout. + * + * vertBearingX :: + * Left side bearing for vertical layout. + * + * vertBearingY :: + * Top side bearing for vertical layout. Larger positive values mean + * further below the vertical glyph origin. + * + * vertAdvance :: + * Advance height for vertical layout. Positive values mean the glyph + * has a positive advance downward. + * + * @note: + * If not disabled with @FT_LOAD_NO_HINTING, the values represent + * dimensions of the hinted glyph (in case hinting is applicable). + * + * Stroking a glyph with an outside border does not increase + * `horiAdvance` or `vertAdvance`; you have to manually adjust these + * values to account for the added width and height. + * + * FreeType doesn't use the 'VORG' table data for CFF fonts because it + * doesn't have an interface to quickly retrieve the glyph height. The + * y~coordinate of the vertical origin can be simply computed as + * `vertBearingY + height` after loading a glyph. + */ typedef struct FT_Glyph_Metrics_ { FT_Pos width; @@ -330,44 +329,45 @@ FT_BEGIN_HEADER } FT_Glyph_Metrics; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Bitmap_Size */ - /* */ - /* <Description> */ - /* This structure models the metrics of a bitmap strike (i.e., a set */ - /* of glyphs for a given point size and resolution) in a bitmap font. */ - /* It is used for the `available_sizes' field of @FT_Face. */ - /* */ - /* <Fields> */ - /* height :: The vertical distance, in pixels, between two */ - /* consecutive baselines. It is always positive. */ - /* */ - /* width :: The average width, in pixels, of all glyphs in the */ - /* strike. */ - /* */ - /* size :: The nominal size of the strike in 26.6 fractional */ - /* points. This field is not very useful. */ - /* */ - /* x_ppem :: The horizontal ppem (nominal width) in 26.6 fractional */ - /* pixels. */ - /* */ - /* y_ppem :: The vertical ppem (nominal height) in 26.6 fractional */ - /* pixels. */ - /* */ - /* <Note> */ - /* Windows FNT: */ - /* The nominal size given in a FNT font is not reliable. If the */ - /* driver finds it incorrect, it sets `size' to some calculated */ - /* values, and `x_ppem' and `y_ppem' to the pixel width and height */ - /* given in the font, respectively. */ - /* */ - /* TrueType embedded bitmaps: */ - /* `size', `width', and `height' values are not contained in the */ - /* bitmap strike itself. They are computed from the global font */ - /* parameters. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_Bitmap_Size + * + * @description: + * This structure models the metrics of a bitmap strike (i.e., a set of + * glyphs for a given point size and resolution) in a bitmap font. It is + * used for the `available_sizes` field of @FT_Face. + * + * @fields: + * height :: + * The vertical distance, in pixels, between two consecutive baselines. + * It is always positive. + * + * width :: + * The average width, in pixels, of all glyphs in the strike. + * + * size :: + * The nominal size of the strike in 26.6 fractional points. This + * field is not very useful. + * + * x_ppem :: + * The horizontal ppem (nominal width) in 26.6 fractional pixels. + * + * y_ppem :: + * The vertical ppem (nominal height) in 26.6 fractional pixels. + * + * @note: + * Windows FNT: + * The nominal size given in a FNT font is not reliable. If the driver + * finds it incorrect, it sets `size` to some calculated values, and + * `x_ppem` and `y_ppem` to the pixel width and height given in the + * font, respectively. + * + * TrueType embedded bitmaps: + * `size`, `width`, and `height` values are not contained in the bitmap + * strike itself. They are computed from the global font parameters. + */ typedef struct FT_Bitmap_Size_ { FT_Short height; @@ -389,225 +389,218 @@ FT_BEGIN_HEADER /*************************************************************************/ /*************************************************************************/ - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Library */ - /* */ - /* <Description> */ - /* A handle to a FreeType library instance. Each `library' is */ - /* completely independent from the others; it is the `root' of a set */ - /* of objects like fonts, faces, sizes, etc. */ - /* */ - /* It also embeds a memory manager (see @FT_Memory), as well as a */ - /* scan-line converter object (see @FT_Raster). */ - /* */ - /* In multi-threaded applications it is easiest to use one */ - /* `FT_Library' object per thread. In case this is too cumbersome, */ - /* a single `FT_Library' object across threads is possible also */ - /* (since FreeType version 2.5.6), as long as a mutex lock is used */ - /* around @FT_New_Face and @FT_Done_Face. */ - /* */ - /* <Note> */ - /* Library objects are normally created by @FT_Init_FreeType, and */ - /* destroyed with @FT_Done_FreeType. If you need reference-counting */ - /* (cf. @FT_Reference_Library), use @FT_New_Library and */ - /* @FT_Done_Library. */ - /* */ + /************************************************************************** + * + * @type: + * FT_Library + * + * @description: + * A handle to a FreeType library instance. Each 'library' is completely + * independent from the others; it is the 'root' of a set of objects like + * fonts, faces, sizes, etc. + * + * It also embeds a memory manager (see @FT_Memory), as well as a + * scan-line converter object (see @FT_Raster). + * + * [Since 2.5.6] In multi-threaded applications it is easiest to use one + * `FT_Library` object per thread. In case this is too cumbersome, a + * single `FT_Library` object across threads is possible also, as long as + * a mutex lock is used around @FT_New_Face and @FT_Done_Face. + * + * @note: + * Library objects are normally created by @FT_Init_FreeType, and + * destroyed with @FT_Done_FreeType. If you need reference-counting + * (cf. @FT_Reference_Library), use @FT_New_Library and @FT_Done_Library. + */ typedef struct FT_LibraryRec_ *FT_Library; - /*************************************************************************/ - /* */ - /* <Section> */ - /* module_management */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * @section: + * module_management + * + */ - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Module */ - /* */ - /* <Description> */ - /* A handle to a given FreeType module object. A module can be a */ - /* font driver, a renderer, or anything else that provides services */ - /* to the former. */ - /* */ + /************************************************************************** + * + * @type: + * FT_Module + * + * @description: + * A handle to a given FreeType module object. A module can be a font + * driver, a renderer, or anything else that provides services to the + * former. + */ typedef struct FT_ModuleRec_* FT_Module; - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Driver */ - /* */ - /* <Description> */ - /* A handle to a given FreeType font driver object. A font driver */ - /* is a module capable of creating faces from font files. */ - /* */ + /************************************************************************** + * + * @type: + * FT_Driver + * + * @description: + * A handle to a given FreeType font driver object. A font driver is a + * module capable of creating faces from font files. + */ typedef struct FT_DriverRec_* FT_Driver; - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Renderer */ - /* */ - /* <Description> */ - /* A handle to a given FreeType renderer. A renderer is a module in */ - /* charge of converting a glyph's outline image to a bitmap. It */ - /* supports a single glyph image format, and one or more target */ - /* surface depths. */ - /* */ + /************************************************************************** + * + * @type: + * FT_Renderer + * + * @description: + * A handle to a given FreeType renderer. A renderer is a module in + * charge of converting a glyph's outline image to a bitmap. It supports + * a single glyph image format, and one or more target surface depths. + */ typedef struct FT_RendererRec_* FT_Renderer; - /*************************************************************************/ - /* */ - /* <Section> */ - /* base_interface */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * @section: + * base_interface + * + */ - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Face */ - /* */ - /* <Description> */ - /* A handle to a typographic face object. A face object models a */ - /* given typeface, in a given style. */ - /* */ - /* <Note> */ - /* A face object also owns a single @FT_GlyphSlot object, as well */ - /* as one or more @FT_Size objects. */ - /* */ - /* Use @FT_New_Face or @FT_Open_Face to create a new face object from */ - /* a given filepath or a custom input stream. */ - /* */ - /* Use @FT_Done_Face to destroy it (along with its slot and sizes). */ - /* */ - /* An `FT_Face' object can only be safely used from one thread at a */ - /* time. Similarly, creation and destruction of `FT_Face' with the */ - /* same @FT_Library object can only be done from one thread at a */ - /* time. On the other hand, functions like @FT_Load_Glyph and its */ - /* siblings are thread-safe and do not need the lock to be held as */ - /* long as the same `FT_Face' object is not used from multiple */ - /* threads at the same time. */ - /* */ - /* <Also> */ - /* See @FT_FaceRec for the publicly accessible fields of a given face */ - /* object. */ - /* */ + /************************************************************************** + * + * @type: + * FT_Face + * + * @description: + * A handle to a typographic face object. A face object models a given + * typeface, in a given style. + * + * @note: + * A face object also owns a single @FT_GlyphSlot object, as well as one + * or more @FT_Size objects. + * + * Use @FT_New_Face or @FT_Open_Face to create a new face object from a + * given filepath or a custom input stream. + * + * Use @FT_Done_Face to destroy it (along with its slot and sizes). + * + * An `FT_Face` object can only be safely used from one thread at a time. + * Similarly, creation and destruction of `FT_Face` with the same + * @FT_Library object can only be done from one thread at a time. On the + * other hand, functions like @FT_Load_Glyph and its siblings are + * thread-safe and do not need the lock to be held as long as the same + * `FT_Face` object is not used from multiple threads at the same time. + * + * @also: + * See @FT_FaceRec for the publicly accessible fields of a given face + * object. + */ typedef struct FT_FaceRec_* FT_Face; - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Size */ - /* */ - /* <Description> */ - /* A handle to an object that models a face scaled to a given */ - /* character size. */ - /* */ - /* <Note> */ - /* An @FT_Face has one _active_ @FT_Size object that is used by */ - /* functions like @FT_Load_Glyph to determine the scaling */ - /* transformation that in turn is used to load and hint glyphs and */ - /* metrics. */ - /* */ - /* You can use @FT_Set_Char_Size, @FT_Set_Pixel_Sizes, */ - /* @FT_Request_Size or even @FT_Select_Size to change the content */ - /* (i.e., the scaling values) of the active @FT_Size. */ - /* */ - /* You can use @FT_New_Size to create additional size objects for a */ - /* given @FT_Face, but they won't be used by other functions until */ - /* you activate it through @FT_Activate_Size. Only one size can be */ - /* activated at any given time per face. */ - /* */ - /* <Also> */ - /* See @FT_SizeRec for the publicly accessible fields of a given size */ - /* object. */ - /* */ + /************************************************************************** + * + * @type: + * FT_Size + * + * @description: + * A handle to an object that models a face scaled to a given character + * size. + * + * @note: + * An @FT_Face has one _active_ @FT_Size object that is used by functions + * like @FT_Load_Glyph to determine the scaling transformation that in + * turn is used to load and hint glyphs and metrics. + * + * You can use @FT_Set_Char_Size, @FT_Set_Pixel_Sizes, @FT_Request_Size + * or even @FT_Select_Size to change the content (i.e., the scaling + * values) of the active @FT_Size. + * + * You can use @FT_New_Size to create additional size objects for a given + * @FT_Face, but they won't be used by other functions until you activate + * it through @FT_Activate_Size. Only one size can be activated at any + * given time per face. + * + * @also: + * See @FT_SizeRec for the publicly accessible fields of a given size + * object. + */ typedef struct FT_SizeRec_* FT_Size; - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_GlyphSlot */ - /* */ - /* <Description> */ - /* A handle to a given `glyph slot'. A slot is a container that can */ - /* hold any of the glyphs contained in its parent face. */ - /* */ - /* In other words, each time you call @FT_Load_Glyph or */ - /* @FT_Load_Char, the slot's content is erased by the new glyph data, */ - /* i.e., the glyph's metrics, its image (bitmap or outline), and */ - /* other control information. */ - /* */ - /* <Also> */ - /* See @FT_GlyphSlotRec for the publicly accessible glyph fields. */ - /* */ + /************************************************************************** + * + * @type: + * FT_GlyphSlot + * + * @description: + * A handle to a given 'glyph slot'. A slot is a container that can hold + * any of the glyphs contained in its parent face. + * + * In other words, each time you call @FT_Load_Glyph or @FT_Load_Char, + * the slot's content is erased by the new glyph data, i.e., the glyph's + * metrics, its image (bitmap or outline), and other control information. + * + * @also: + * See @FT_GlyphSlotRec for the publicly accessible glyph fields. + */ typedef struct FT_GlyphSlotRec_* FT_GlyphSlot; - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_CharMap */ - /* */ - /* <Description> */ - /* A handle to a character map (usually abbreviated to `charmap'). A */ - /* charmap is used to translate character codes in a given encoding */ - /* into glyph indexes for its parent's face. Some font formats may */ - /* provide several charmaps per font. */ - /* */ - /* Each face object owns zero or more charmaps, but only one of them */ - /* can be `active', providing the data used by @FT_Get_Char_Index or */ - /* @FT_Load_Char. */ - /* */ - /* The list of available charmaps in a face is available through the */ - /* `face->num_charmaps' and `face->charmaps' fields of @FT_FaceRec. */ - /* */ - /* The currently active charmap is available as `face->charmap'. */ - /* You should call @FT_Set_Charmap to change it. */ - /* */ - /* <Note> */ - /* When a new face is created (either through @FT_New_Face or */ - /* @FT_Open_Face), the library looks for a Unicode charmap within */ - /* the list and automatically activates it. If there is no Unicode */ - /* charmap, FreeType doesn't set an `active' charmap. */ - /* */ - /* <Also> */ - /* See @FT_CharMapRec for the publicly accessible fields of a given */ - /* character map. */ - /* */ + /************************************************************************** + * + * @type: + * FT_CharMap + * + * @description: + * A handle to a character map (usually abbreviated to 'charmap'). A + * charmap is used to translate character codes in a given encoding into + * glyph indexes for its parent's face. Some font formats may provide + * several charmaps per font. + * + * Each face object owns zero or more charmaps, but only one of them can + * be 'active', providing the data used by @FT_Get_Char_Index or + * @FT_Load_Char. + * + * The list of available charmaps in a face is available through the + * `face->num_charmaps` and `face->charmaps` fields of @FT_FaceRec. + * + * The currently active charmap is available as `face->charmap`. You + * should call @FT_Set_Charmap to change it. + * + * @note: + * When a new face is created (either through @FT_New_Face or + * @FT_Open_Face), the library looks for a Unicode charmap within the + * list and automatically activates it. If there is no Unicode charmap, + * FreeType doesn't set an 'active' charmap. + * + * @also: + * See @FT_CharMapRec for the publicly accessible fields of a given + * character map. + */ typedef struct FT_CharMapRec_* FT_CharMap; - /*************************************************************************/ - /* */ - /* <Macro> */ - /* FT_ENC_TAG */ - /* */ - /* <Description> */ - /* This macro converts four-letter tags into an unsigned long. It is */ - /* used to define `encoding' identifiers (see @FT_Encoding). */ - /* */ - /* <Note> */ - /* Since many 16-bit compilers don't like 32-bit enumerations, you */ - /* should redefine this macro in case of problems to something like */ - /* this: */ - /* */ - /* { */ - /* #define FT_ENC_TAG( value, a, b, c, d ) value */ - /* } */ - /* */ - /* to get a simple enumeration without assigning special numbers. */ - /* */ + /************************************************************************** + * + * @macro: + * FT_ENC_TAG + * + * @description: + * This macro converts four-letter tags into an unsigned long. It is + * used to define 'encoding' identifiers (see @FT_Encoding). + * + * @note: + * Since many 16-bit compilers don't like 32-bit enumerations, you should + * redefine this macro in case of problems to something like this: + * + * ``` + * #define FT_ENC_TAG( value, a, b, c, d ) value + * ``` + * + * to get a simple enumeration without assigning special numbers. + */ #ifndef FT_ENC_TAG #define FT_ENC_TAG( value, a, b, c, d ) \ @@ -619,149 +612,147 @@ FT_BEGIN_HEADER #endif /* FT_ENC_TAG */ - /*************************************************************************/ - /* */ - /* <Enum> */ - /* FT_Encoding */ - /* */ - /* <Description> */ - /* An enumeration to specify character sets supported by charmaps. */ - /* Used in the @FT_Select_Charmap API function. */ - /* */ - /* <Note> */ - /* Despite the name, this enumeration lists specific character */ - /* repertories (i.e., charsets), and not text encoding methods (e.g., */ - /* UTF-8, UTF-16, etc.). */ - /* */ - /* Other encodings might be defined in the future. */ - /* */ - /* <Values> */ - /* FT_ENCODING_NONE :: */ - /* The encoding value~0 is reserved. */ - /* */ - /* FT_ENCODING_UNICODE :: */ - /* The Unicode character set. This value covers all versions of */ - /* the Unicode repertoire, including ASCII and Latin-1. Most fonts */ - /* include a Unicode charmap, but not all of them. */ - /* */ - /* For example, if you want to access Unicode value U+1F028 (and */ - /* the font contains it), use value 0x1F028 as the input value for */ - /* @FT_Get_Char_Index. */ - /* */ - /* FT_ENCODING_MS_SYMBOL :: */ - /* Microsoft Symbol encoding, used to encode mathematical symbols */ - /* and wingdings. For more information, see */ - /* `https://www.microsoft.com/typography/otspec/recom.htm', */ - /* `http://www.kostis.net/charsets/symbol.htm', and */ - /* `http://www.kostis.net/charsets/wingding.htm'. */ - /* */ - /* This encoding uses character codes from the PUA (Private Unicode */ - /* Area) in the range U+F020-U+F0FF. */ - /* */ - /* FT_ENCODING_SJIS :: */ - /* Shift JIS encoding for Japanese. More info at */ - /* `https://en.wikipedia.org/wiki/Shift_JIS'. See note on */ - /* multi-byte encodings below. */ - /* */ - /* FT_ENCODING_PRC :: */ - /* Corresponds to encoding systems mainly for Simplified Chinese as */ - /* used in People's Republic of China (PRC). The encoding layout */ - /* is based on GB~2312 and its supersets GBK and GB~18030. */ - /* */ - /* FT_ENCODING_BIG5 :: */ - /* Corresponds to an encoding system for Traditional Chinese as */ - /* used in Taiwan and Hong Kong. */ - /* */ - /* FT_ENCODING_WANSUNG :: */ - /* Corresponds to the Korean encoding system known as Extended */ - /* Wansung (MS Windows code page 949). */ - /* For more information see */ - /* `https://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WindowsBestFit/bestfit949.txt'. */ - /* */ - /* FT_ENCODING_JOHAB :: */ - /* The Korean standard character set (KS~C 5601-1992), which */ - /* corresponds to MS Windows code page 1361. This character set */ - /* includes all possible Hangul character combinations. */ - /* */ - /* FT_ENCODING_ADOBE_LATIN_1 :: */ - /* Corresponds to a Latin-1 encoding as defined in a Type~1 */ - /* PostScript font. It is limited to 256 character codes. */ - /* */ - /* FT_ENCODING_ADOBE_STANDARD :: */ - /* Adobe Standard encoding, as found in Type~1, CFF, and */ - /* OpenType/CFF fonts. It is limited to 256 character codes. */ - /* */ - /* FT_ENCODING_ADOBE_EXPERT :: */ - /* Adobe Expert encoding, as found in Type~1, CFF, and OpenType/CFF */ - /* fonts. It is limited to 256 character codes. */ - /* */ - /* FT_ENCODING_ADOBE_CUSTOM :: */ - /* Corresponds to a custom encoding, as found in Type~1, CFF, and */ - /* OpenType/CFF fonts. It is limited to 256 character codes. */ - /* */ - /* FT_ENCODING_APPLE_ROMAN :: */ - /* Apple roman encoding. Many TrueType and OpenType fonts contain */ - /* a charmap for this 8-bit encoding, since older versions of Mac */ - /* OS are able to use it. */ - /* */ - /* FT_ENCODING_OLD_LATIN_2 :: */ - /* This value is deprecated and was neither used nor reported by */ - /* FreeType. Don't use or test for it. */ - /* */ - /* FT_ENCODING_MS_SJIS :: */ - /* Same as FT_ENCODING_SJIS. Deprecated. */ - /* */ - /* FT_ENCODING_MS_GB2312 :: */ - /* Same as FT_ENCODING_PRC. Deprecated. */ - /* */ - /* FT_ENCODING_MS_BIG5 :: */ - /* Same as FT_ENCODING_BIG5. Deprecated. */ - /* */ - /* FT_ENCODING_MS_WANSUNG :: */ - /* Same as FT_ENCODING_WANSUNG. Deprecated. */ - /* */ - /* FT_ENCODING_MS_JOHAB :: */ - /* Same as FT_ENCODING_JOHAB. Deprecated. */ - /* */ - /* <Note> */ - /* By default, FreeType automatically synthesizes a Unicode charmap */ - /* for PostScript fonts, using their glyph name dictionaries. */ - /* However, it also reports the encodings defined explicitly in the */ - /* font file, for the cases when they are needed, with the Adobe */ - /* values as well. */ - /* */ - /* FT_ENCODING_NONE is set by the BDF and PCF drivers if the charmap */ - /* is neither Unicode nor ISO-8859-1 (otherwise it is set to */ - /* FT_ENCODING_UNICODE). Use @FT_Get_BDF_Charset_ID to find out */ - /* which encoding is really present. If, for example, the */ - /* `cs_registry' field is `KOI8' and the `cs_encoding' field is `R', */ - /* the font is encoded in KOI8-R. */ - /* */ - /* FT_ENCODING_NONE is always set (with a single exception) by the */ - /* winfonts driver. Use @FT_Get_WinFNT_Header and examine the */ - /* `charset' field of the @FT_WinFNT_HeaderRec structure to find out */ - /* which encoding is really present. For example, */ - /* @FT_WinFNT_ID_CP1251 (204) means Windows code page 1251 (for */ - /* Russian). */ - /* */ - /* FT_ENCODING_NONE is set if `platform_id' is @TT_PLATFORM_MACINTOSH */ - /* and `encoding_id' is not `TT_MAC_ID_ROMAN' (otherwise it is set to */ - /* FT_ENCODING_APPLE_ROMAN). */ - /* */ - /* If `platform_id' is @TT_PLATFORM_MACINTOSH, use the function */ - /* @FT_Get_CMap_Language_ID to query the Mac language ID that may */ - /* be needed to be able to distinguish Apple encoding variants. See */ - /* */ - /* https://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/Readme.txt */ - /* */ - /* to get an idea how to do that. Basically, if the language ID */ - /* is~0, don't use it, otherwise subtract 1 from the language ID. */ - /* Then examine `encoding_id'. If, for example, `encoding_id' is */ - /* `TT_MAC_ID_ROMAN' and the language ID (minus~1) is */ - /* `TT_MAC_LANGID_GREEK', it is the Greek encoding, not Roman. */ - /* `TT_MAC_ID_ARABIC' with `TT_MAC_LANGID_FARSI' means the Farsi */ - /* variant the Arabic encoding. */ - /* */ + /************************************************************************** + * + * @enum: + * FT_Encoding + * + * @description: + * An enumeration to specify character sets supported by charmaps. Used + * in the @FT_Select_Charmap API function. + * + * @note: + * Despite the name, this enumeration lists specific character + * repertories (i.e., charsets), and not text encoding methods (e.g., + * UTF-8, UTF-16, etc.). + * + * Other encodings might be defined in the future. + * + * @values: + * FT_ENCODING_NONE :: + * The encoding value~0 is reserved for all formats except BDF, PCF, + * and Windows FNT; see below for more information. + * + * FT_ENCODING_UNICODE :: + * The Unicode character set. This value covers all versions of the + * Unicode repertoire, including ASCII and Latin-1. Most fonts include + * a Unicode charmap, but not all of them. + * + * For example, if you want to access Unicode value U+1F028 (and the + * font contains it), use value 0x1F028 as the input value for + * @FT_Get_Char_Index. + * + * FT_ENCODING_MS_SYMBOL :: + * Microsoft Symbol encoding, used to encode mathematical symbols and + * wingdings. For more information, see + * 'https://www.microsoft.com/typography/otspec/recom.htm', + * 'http://www.kostis.net/charsets/symbol.htm', and + * 'http://www.kostis.net/charsets/wingding.htm'. + * + * This encoding uses character codes from the PUA (Private Unicode + * Area) in the range U+F020-U+F0FF. + * + * FT_ENCODING_SJIS :: + * Shift JIS encoding for Japanese. More info at + * 'https://en.wikipedia.org/wiki/Shift_JIS'. See note on multi-byte + * encodings below. + * + * FT_ENCODING_PRC :: + * Corresponds to encoding systems mainly for Simplified Chinese as + * used in People's Republic of China (PRC). The encoding layout is + * based on GB~2312 and its supersets GBK and GB~18030. + * + * FT_ENCODING_BIG5 :: + * Corresponds to an encoding system for Traditional Chinese as used in + * Taiwan and Hong Kong. + * + * FT_ENCODING_WANSUNG :: + * Corresponds to the Korean encoding system known as Extended Wansung + * (MS Windows code page 949). For more information see + * 'https://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WindowsBestFit/bestfit949.txt'. + * + * FT_ENCODING_JOHAB :: + * The Korean standard character set (KS~C 5601-1992), which + * corresponds to MS Windows code page 1361. This character set + * includes all possible Hangul character combinations. + * + * FT_ENCODING_ADOBE_LATIN_1 :: + * Corresponds to a Latin-1 encoding as defined in a Type~1 PostScript + * font. It is limited to 256 character codes. + * + * FT_ENCODING_ADOBE_STANDARD :: + * Adobe Standard encoding, as found in Type~1, CFF, and OpenType/CFF + * fonts. It is limited to 256 character codes. + * + * FT_ENCODING_ADOBE_EXPERT :: + * Adobe Expert encoding, as found in Type~1, CFF, and OpenType/CFF + * fonts. It is limited to 256 character codes. + * + * FT_ENCODING_ADOBE_CUSTOM :: + * Corresponds to a custom encoding, as found in Type~1, CFF, and + * OpenType/CFF fonts. It is limited to 256 character codes. + * + * FT_ENCODING_APPLE_ROMAN :: + * Apple roman encoding. Many TrueType and OpenType fonts contain a + * charmap for this 8-bit encoding, since older versions of Mac OS are + * able to use it. + * + * FT_ENCODING_OLD_LATIN_2 :: + * This value is deprecated and was neither used nor reported by + * FreeType. Don't use or test for it. + * + * FT_ENCODING_MS_SJIS :: + * Same as FT_ENCODING_SJIS. Deprecated. + * + * FT_ENCODING_MS_GB2312 :: + * Same as FT_ENCODING_PRC. Deprecated. + * + * FT_ENCODING_MS_BIG5 :: + * Same as FT_ENCODING_BIG5. Deprecated. + * + * FT_ENCODING_MS_WANSUNG :: + * Same as FT_ENCODING_WANSUNG. Deprecated. + * + * FT_ENCODING_MS_JOHAB :: + * Same as FT_ENCODING_JOHAB. Deprecated. + * + * @note: + * By default, FreeType enables a Unicode charmap and tags it with + * `FT_ENCODING_UNICODE` when it is either provided or can be generated + * from PostScript glyph name dictionaries in the font file. All other + * encodings are considered legacy and tagged only if explicitly defined + * in the font file. Otherwise, `FT_ENCODING_NONE` is used. + * + * `FT_ENCODING_NONE` is set by the BDF and PCF drivers if the charmap is + * neither Unicode nor ISO-8859-1 (otherwise it is set to + * `FT_ENCODING_UNICODE`). Use @FT_Get_BDF_Charset_ID to find out which + * encoding is really present. If, for example, the `cs_registry` field + * is 'KOI8' and the `cs_encoding` field is 'R', the font is encoded in + * KOI8-R. + * + * `FT_ENCODING_NONE` is always set (with a single exception) by the + * winfonts driver. Use @FT_Get_WinFNT_Header and examine the `charset` + * field of the @FT_WinFNT_HeaderRec structure to find out which encoding + * is really present. For example, @FT_WinFNT_ID_CP1251 (204) means + * Windows code page 1251 (for Russian). + * + * `FT_ENCODING_NONE` is set if `platform_id` is @TT_PLATFORM_MACINTOSH + * and `encoding_id` is not `TT_MAC_ID_ROMAN` (otherwise it is set to + * `FT_ENCODING_APPLE_ROMAN`). + * + * If `platform_id` is @TT_PLATFORM_MACINTOSH, use the function + * @FT_Get_CMap_Language_ID to query the Mac language ID that may be + * needed to be able to distinguish Apple encoding variants. See + * + * https://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/Readme.txt + * + * to get an idea how to do that. Basically, if the language ID is~0, + * don't use it, otherwise subtract 1 from the language ID. Then examine + * `encoding_id`. If, for example, `encoding_id` is `TT_MAC_ID_ROMAN` + * and the language ID (minus~1) is `TT_MAC_LANGID_GREEK`, it is the + * Greek encoding, not Roman. `TT_MAC_ID_ARABIC` with + * `TT_MAC_LANGID_FARSI` means the Farsi variant the Arabic encoding. + */ typedef enum FT_Encoding_ { FT_ENC_TAG( FT_ENCODING_NONE, 0, 0, 0, 0 ), @@ -795,7 +786,7 @@ FT_BEGIN_HEADER } FT_Encoding; - /* these constants are deprecated; use the corresponding `FT_Encoding' */ + /* these constants are deprecated; use the corresponding `FT_Encoding` */ /* values instead */ #define ft_encoding_none FT_ENCODING_NONE #define ft_encoding_unicode FT_ENCODING_UNICODE @@ -814,29 +805,31 @@ FT_BEGIN_HEADER #define ft_encoding_apple_roman FT_ENCODING_APPLE_ROMAN - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_CharMapRec */ - /* */ - /* <Description> */ - /* The base charmap structure. */ - /* */ - /* <Fields> */ - /* face :: A handle to the parent face object. */ - /* */ - /* encoding :: An @FT_Encoding tag identifying the charmap. Use */ - /* this with @FT_Select_Charmap. */ - /* */ - /* platform_id :: An ID number describing the platform for the */ - /* following encoding ID. This comes directly from */ - /* the TrueType specification and gets emulated for */ - /* other formats. */ - /* */ - /* encoding_id :: A platform specific encoding number. This also */ - /* comes from the TrueType specification and gets */ - /* emulated similarly. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_CharMapRec + * + * @description: + * The base charmap structure. + * + * @fields: + * face :: + * A handle to the parent face object. + * + * encoding :: + * An @FT_Encoding tag identifying the charmap. Use this with + * @FT_Select_Charmap. + * + * platform_id :: + * An ID number describing the platform for the following encoding ID. + * This comes directly from the TrueType specification and gets + * emulated for other formats. + * + * encoding_id :: + * A platform-specific encoding number. This also comes from the + * TrueType specification and gets emulated similarly. + */ typedef struct FT_CharMapRec_ { FT_Face face; @@ -856,215 +849,195 @@ FT_BEGIN_HEADER /*************************************************************************/ - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Face_Internal */ - /* */ - /* <Description> */ - /* An opaque handle to an `FT_Face_InternalRec' structure that models */ - /* the private data of a given @FT_Face object. */ - /* */ - /* This structure might change between releases of FreeType~2 and is */ - /* not generally available to client applications. */ - /* */ + /************************************************************************** + * + * @type: + * FT_Face_Internal + * + * @description: + * An opaque handle to an `FT_Face_InternalRec` structure that models the + * private data of a given @FT_Face object. + * + * This structure might change between releases of FreeType~2 and is not + * generally available to client applications. + */ typedef struct FT_Face_InternalRec_* FT_Face_Internal; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_FaceRec */ - /* */ - /* <Description> */ - /* FreeType root face class structure. A face object models a */ - /* typeface in a font file. */ - /* */ - /* <Fields> */ - /* num_faces :: The number of faces in the font file. Some */ - /* font formats can have multiple faces in */ - /* a single font file. */ - /* */ - /* face_index :: This field holds two different values. */ - /* Bits 0-15 are the index of the face in the */ - /* font file (starting with value~0). They */ - /* are set to~0 if there is only one face in */ - /* the font file. */ - /* */ - /* [Since 2.6.1] Bits 16-30 are relevant to GX */ - /* and OpenType variation fonts only, holding */ - /* the named instance index for the current */ - /* face index (starting with value~1; value~0 */ - /* indicates font access without a named */ - /* instance). For non-variation fonts, bits */ - /* 16-30 are ignored. If we have the third */ - /* named instance of face~4, say, `face_index' */ - /* is set to 0x00030004. */ - /* */ - /* Bit 31 is always zero (this is, */ - /* `face_index' is always a positive value). */ - /* */ - /* [Since 2.9] Changing the design coordinates */ - /* with @FT_Set_Var_Design_Coordinates or */ - /* @FT_Set_Var_Blend_Coordinates does not */ - /* influence the named instance index value */ - /* (only @FT_Set_Named_Instance does that). */ - /* */ - /* face_flags :: A set of bit flags that give important */ - /* information about the face; see */ - /* @FT_FACE_FLAG_XXX for the details. */ - /* */ - /* style_flags :: The lower 16~bits contain a set of bit */ - /* flags indicating the style of the face; see */ - /* @FT_STYLE_FLAG_XXX for the details. */ - /* */ - /* [Since 2.6.1] Bits 16-30 hold the number */ - /* of named instances available for the */ - /* current face if we have a GX or OpenType */ - /* variation (sub)font. Bit 31 is always zero */ - /* (this is, `style_flags' is always a */ - /* positive value). Note that a variation */ - /* font has always at least one named */ - /* instance, namely the default instance. */ - /* */ - /* num_glyphs :: The number of glyphs in the face. If the */ - /* face is scalable and has sbits (see */ - /* `num_fixed_sizes'), it is set to the number */ - /* of outline glyphs. */ - /* */ - /* For CID-keyed fonts (not in an SFNT */ - /* wrapper) this value gives the highest CID */ - /* used in the font. */ - /* */ - /* family_name :: The face's family name. This is an ASCII */ - /* string, usually in English, that describes */ - /* the typeface's family (like `Times New */ - /* Roman', `Bodoni', `Garamond', etc). This */ - /* is a least common denominator used to list */ - /* fonts. Some formats (TrueType & OpenType) */ - /* provide localized and Unicode versions of */ - /* this string. Applications should use the */ - /* format specific interface to access them. */ - /* Can be NULL (e.g., in fonts embedded in a */ - /* PDF file). */ - /* */ - /* In case the font doesn't provide a specific */ - /* family name entry, FreeType tries to */ - /* synthesize one, deriving it from other name */ - /* entries. */ - /* */ - /* style_name :: The face's style name. This is an ASCII */ - /* string, usually in English, that describes */ - /* the typeface's style (like `Italic', */ - /* `Bold', `Condensed', etc). Not all font */ - /* formats provide a style name, so this field */ - /* is optional, and can be set to NULL. As */ - /* for `family_name', some formats provide */ - /* localized and Unicode versions of this */ - /* string. Applications should use the format */ - /* specific interface to access them. */ - /* */ - /* num_fixed_sizes :: The number of bitmap strikes in the face. */ - /* Even if the face is scalable, there might */ - /* still be bitmap strikes, which are called */ - /* `sbits' in that case. */ - /* */ - /* available_sizes :: An array of @FT_Bitmap_Size for all bitmap */ - /* strikes in the face. It is set to NULL if */ - /* there is no bitmap strike. */ - /* */ - /* Note that FreeType tries to sanitize the */ - /* strike data since they are sometimes sloppy */ - /* or incorrect, but this can easily fail. */ - /* */ - /* num_charmaps :: The number of charmaps in the face. */ - /* */ - /* charmaps :: An array of the charmaps of the face. */ - /* */ - /* generic :: A field reserved for client uses. See the */ - /* @FT_Generic type description. */ - /* */ - /* bbox :: The font bounding box. Coordinates are */ - /* expressed in font units (see */ - /* `units_per_EM'). The box is large enough */ - /* to contain any glyph from the font. Thus, */ - /* `bbox.yMax' can be seen as the `maximum */ - /* ascender', and `bbox.yMin' as the `minimum */ - /* descender'. Only relevant for scalable */ - /* formats. */ - /* */ - /* Note that the bounding box might be off by */ - /* (at least) one pixel for hinted fonts. See */ - /* @FT_Size_Metrics for further discussion. */ - /* */ - /* units_per_EM :: The number of font units per EM square for */ - /* this face. This is typically 2048 for */ - /* TrueType fonts, and 1000 for Type~1 fonts. */ - /* Only relevant for scalable formats. */ - /* */ - /* ascender :: The typographic ascender of the face, */ - /* expressed in font units. For font formats */ - /* not having this information, it is set to */ - /* `bbox.yMax'. Only relevant for scalable */ - /* formats. */ - /* */ - /* descender :: The typographic descender of the face, */ - /* expressed in font units. For font formats */ - /* not having this information, it is set to */ - /* `bbox.yMin'. Note that this field is */ - /* negative for values below the baseline. */ - /* Only relevant for scalable formats. */ - /* */ - /* height :: This value is the vertical distance */ - /* between two consecutive baselines, */ - /* expressed in font units. It is always */ - /* positive. Only relevant for scalable */ - /* formats. */ - /* */ - /* If you want the global glyph height, use */ - /* `ascender - descender'. */ - /* */ - /* max_advance_width :: The maximum advance width, in font units, */ - /* for all glyphs in this face. This can be */ - /* used to make word wrapping computations */ - /* faster. Only relevant for scalable */ - /* formats. */ - /* */ - /* max_advance_height :: The maximum advance height, in font units, */ - /* for all glyphs in this face. This is only */ - /* relevant for vertical layouts, and is set */ - /* to `height' for fonts that do not provide */ - /* vertical metrics. Only relevant for */ - /* scalable formats. */ - /* */ - /* underline_position :: The position, in font units, of the */ - /* underline line for this face. It is the */ - /* center of the underlining stem. Only */ - /* relevant for scalable formats. */ - /* */ - /* underline_thickness :: The thickness, in font units, of the */ - /* underline for this face. Only relevant for */ - /* scalable formats. */ - /* */ - /* glyph :: The face's associated glyph slot(s). */ - /* */ - /* size :: The current active size for this face. */ - /* */ - /* charmap :: The current active charmap for this face. */ - /* */ - /* <Note> */ - /* Fields may be changed after a call to @FT_Attach_File or */ - /* @FT_Attach_Stream. */ - /* */ - /* For an OpenType variation font, the values of the following fields */ - /* can change after a call to @FT_Set_Var_Design_Coordinates (and */ - /* friends) if the font contains an `MVAR' table: `ascender', */ - /* `descender', `height', `underline_position', and */ - /* `underline_thickness'. */ - /* */ - /* Especially for TrueType fonts see also the documentation for */ - /* @FT_Size_Metrics. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_FaceRec + * + * @description: + * FreeType root face class structure. A face object models a typeface + * in a font file. + * + * @fields: + * num_faces :: + * The number of faces in the font file. Some font formats can have + * multiple faces in a single font file. + * + * face_index :: + * This field holds two different values. Bits 0-15 are the index of + * the face in the font file (starting with value~0). They are set + * to~0 if there is only one face in the font file. + * + * [Since 2.6.1] Bits 16-30 are relevant to GX and OpenType variation + * fonts only, holding the named instance index for the current face + * index (starting with value~1; value~0 indicates font access without + * a named instance). For non-variation fonts, bits 16-30 are ignored. + * If we have the third named instance of face~4, say, `face_index` is + * set to 0x00030004. + * + * Bit 31 is always zero (this is, `face_index` is always a positive + * value). + * + * [Since 2.9] Changing the design coordinates with + * @FT_Set_Var_Design_Coordinates or @FT_Set_Var_Blend_Coordinates does + * not influence the named instance index value (only + * @FT_Set_Named_Instance does that). + * + * face_flags :: + * A set of bit flags that give important information about the face; + * see @FT_FACE_FLAG_XXX for the details. + * + * style_flags :: + * The lower 16~bits contain a set of bit flags indicating the style of + * the face; see @FT_STYLE_FLAG_XXX for the details. + * + * [Since 2.6.1] Bits 16-30 hold the number of named instances + * available for the current face if we have a GX or OpenType variation + * (sub)font. Bit 31 is always zero (this is, `style_flags` is always + * a positive value). Note that a variation font has always at least + * one named instance, namely the default instance. + * + * num_glyphs :: + * The number of glyphs in the face. If the face is scalable and has + * sbits (see `num_fixed_sizes`), it is set to the number of outline + * glyphs. + * + * For CID-keyed fonts (not in an SFNT wrapper) this value gives the + * highest CID used in the font. + * + * family_name :: + * The face's family name. This is an ASCII string, usually in + * English, that describes the typeface's family (like 'Times New + * Roman', 'Bodoni', 'Garamond', etc). This is a least common + * denominator used to list fonts. Some formats (TrueType & OpenType) + * provide localized and Unicode versions of this string. Applications + * should use the format-specific interface to access them. Can be + * `NULL` (e.g., in fonts embedded in a PDF file). + * + * In case the font doesn't provide a specific family name entry, + * FreeType tries to synthesize one, deriving it from other name + * entries. + * + * style_name :: + * The face's style name. This is an ASCII string, usually in English, + * that describes the typeface's style (like 'Italic', 'Bold', + * 'Condensed', etc). Not all font formats provide a style name, so + * this field is optional, and can be set to `NULL`. As for + * `family_name`, some formats provide localized and Unicode versions + * of this string. Applications should use the format-specific + * interface to access them. + * + * num_fixed_sizes :: + * The number of bitmap strikes in the face. Even if the face is + * scalable, there might still be bitmap strikes, which are called + * 'sbits' in that case. + * + * available_sizes :: + * An array of @FT_Bitmap_Size for all bitmap strikes in the face. It + * is set to `NULL` if there is no bitmap strike. + * + * Note that FreeType tries to sanitize the strike data since they are + * sometimes sloppy or incorrect, but this can easily fail. + * + * num_charmaps :: + * The number of charmaps in the face. + * + * charmaps :: + * An array of the charmaps of the face. + * + * generic :: + * A field reserved for client uses. See the @FT_Generic type + * description. + * + * bbox :: + * The font bounding box. Coordinates are expressed in font units (see + * `units_per_EM`). The box is large enough to contain any glyph from + * the font. Thus, `bbox.yMax` can be seen as the 'maximum ascender', + * and `bbox.yMin` as the 'minimum descender'. Only relevant for + * scalable formats. + * + * Note that the bounding box might be off by (at least) one pixel for + * hinted fonts. See @FT_Size_Metrics for further discussion. + * + * units_per_EM :: + * The number of font units per EM square for this face. This is + * typically 2048 for TrueType fonts, and 1000 for Type~1 fonts. Only + * relevant for scalable formats. + * + * ascender :: + * The typographic ascender of the face, expressed in font units. For + * font formats not having this information, it is set to `bbox.yMax`. + * Only relevant for scalable formats. + * + * descender :: + * The typographic descender of the face, expressed in font units. For + * font formats not having this information, it is set to `bbox.yMin`. + * Note that this field is negative for values below the baseline. + * Only relevant for scalable formats. + * + * height :: + * This value is the vertical distance between two consecutive + * baselines, expressed in font units. It is always positive. Only + * relevant for scalable formats. + * + * If you want the global glyph height, use `ascender - descender`. + * + * max_advance_width :: + * The maximum advance width, in font units, for all glyphs in this + * face. This can be used to make word wrapping computations faster. + * Only relevant for scalable formats. + * + * max_advance_height :: + * The maximum advance height, in font units, for all glyphs in this + * face. This is only relevant for vertical layouts, and is set to + * `height` for fonts that do not provide vertical metrics. Only + * relevant for scalable formats. + * + * underline_position :: + * The position, in font units, of the underline line for this face. + * It is the center of the underlining stem. Only relevant for + * scalable formats. + * + * underline_thickness :: + * The thickness, in font units, of the underline for this face. Only + * relevant for scalable formats. + * + * glyph :: + * The face's associated glyph slot(s). + * + * size :: + * The current active size for this face. + * + * charmap :: + * The current active charmap for this face. + * + * @note: + * Fields may be changed after a call to @FT_Attach_File or + * @FT_Attach_Stream. + * + * For an OpenType variation font, the values of the following fields can + * change after a call to @FT_Set_Var_Design_Coordinates (and friends) if + * the font contains an 'MVAR' table: `ascender`, `descender`, `height`, + * `underline_position`, and `underline_thickness`. + * + * Especially for TrueType fonts see also the documentation for + * @FT_Size_Metrics. + */ typedef struct FT_FaceRec_ { FT_Long num_faces; @@ -1086,7 +1059,7 @@ FT_BEGIN_HEADER FT_Generic generic; - /*# The following member variables (down to `underline_thickness') */ + /*# The following member variables (down to `underline_thickness`) */ /*# are only relevant to scalable outlines; cf. @FT_Bitmap_Size */ /*# for bitmap fonts. */ FT_BBox bbox; @@ -1124,117 +1097,116 @@ FT_BEGIN_HEADER } FT_FaceRec; - /*************************************************************************/ - /* */ - /* <Enum> */ - /* FT_FACE_FLAG_XXX */ - /* */ - /* <Description> */ - /* A list of bit flags used in the `face_flags' field of the */ - /* @FT_FaceRec structure. They inform client applications of */ - /* properties of the corresponding face. */ - /* */ - /* <Values> */ - /* FT_FACE_FLAG_SCALABLE :: */ - /* The face contains outline glyphs. Note that a face can contain */ - /* bitmap strikes also, i.e., a face can have both this flag and */ - /* @FT_FACE_FLAG_FIXED_SIZES set. */ - /* */ - /* FT_FACE_FLAG_FIXED_SIZES :: */ - /* The face contains bitmap strikes. See also the */ - /* `num_fixed_sizes' and `available_sizes' fields of @FT_FaceRec. */ - /* */ - /* FT_FACE_FLAG_FIXED_WIDTH :: */ - /* The face contains fixed-width characters (like Courier, Lucida, */ - /* MonoType, etc.). */ - /* */ - /* FT_FACE_FLAG_SFNT :: */ - /* The face uses the SFNT storage scheme. For now, this means */ - /* TrueType and OpenType. */ - /* */ - /* FT_FACE_FLAG_HORIZONTAL :: */ - /* The face contains horizontal glyph metrics. This should be set */ - /* for all common formats. */ - /* */ - /* FT_FACE_FLAG_VERTICAL :: */ - /* The face contains vertical glyph metrics. This is only */ - /* available in some formats, not all of them. */ - /* */ - /* FT_FACE_FLAG_KERNING :: */ - /* The face contains kerning information. If set, the kerning */ - /* distance can be retrieved using the function @FT_Get_Kerning. */ - /* Otherwise the function always return the vector (0,0). Note */ - /* that FreeType doesn't handle kerning data from the SFNT `GPOS' */ - /* table (as present in many OpenType fonts). */ - /* */ - /* FT_FACE_FLAG_FAST_GLYPHS :: */ - /* THIS FLAG IS DEPRECATED. DO NOT USE OR TEST IT. */ - /* */ - /* FT_FACE_FLAG_MULTIPLE_MASTERS :: */ - /* The face contains multiple masters and is capable of */ - /* interpolating between them. Supported formats are Adobe MM, */ - /* TrueType GX, and OpenType variation fonts. */ - /* */ - /* See the multiple-masters specific API for details. */ - /* */ - /* FT_FACE_FLAG_GLYPH_NAMES :: */ - /* The face contains glyph names, which can be retrieved using */ - /* @FT_Get_Glyph_Name. Note that some TrueType fonts contain */ - /* broken glyph name tables. Use the function */ - /* @FT_Has_PS_Glyph_Names when needed. */ - /* */ - /* FT_FACE_FLAG_EXTERNAL_STREAM :: */ - /* Used internally by FreeType to indicate that a face's stream was */ - /* provided by the client application and should not be destroyed */ - /* when @FT_Done_Face is called. Don't read or test this flag. */ - /* */ - /* FT_FACE_FLAG_HINTER :: */ - /* The font driver has a hinting machine of its own. For example, */ - /* with TrueType fonts, it makes sense to use data from the SFNT */ - /* `gasp' table only if the native TrueType hinting engine (with */ - /* the bytecode interpreter) is available and active. */ - /* */ - /* FT_FACE_FLAG_CID_KEYED :: */ - /* The face is CID-keyed. In that case, the face is not accessed */ - /* by glyph indices but by CID values. For subsetted CID-keyed */ - /* fonts this has the consequence that not all index values are a */ - /* valid argument to @FT_Load_Glyph. Only the CID values for which */ - /* corresponding glyphs in the subsetted font exist make */ - /* `FT_Load_Glyph' return successfully; in all other cases you get */ - /* an `FT_Err_Invalid_Argument' error. */ - /* */ - /* Note that CID-keyed fonts that are in an SFNT wrapper (this is, */ - /* all OpenType/CFF fonts) don't have this flag set since the */ - /* glyphs are accessed in the normal way (using contiguous */ - /* indices); the `CID-ness' isn't visible to the application. */ - /* */ - /* FT_FACE_FLAG_TRICKY :: */ - /* The face is `tricky', this is, it always needs the font format's */ - /* native hinting engine to get a reasonable result. A typical */ - /* example is the old Chinese font `mingli.ttf' (but not */ - /* `mingliu.ttc') that uses TrueType bytecode instructions to move */ - /* and scale all of its subglyphs. */ - /* */ - /* It is not possible to auto-hint such fonts using */ - /* @FT_LOAD_FORCE_AUTOHINT; it will also ignore */ - /* @FT_LOAD_NO_HINTING. You have to set both @FT_LOAD_NO_HINTING */ - /* and @FT_LOAD_NO_AUTOHINT to really disable hinting; however, you */ - /* probably never want this except for demonstration purposes. */ - /* */ - /* Currently, there are about a dozen TrueType fonts in the list of */ - /* tricky fonts; they are hard-coded in file `ttobjs.c'. */ - /* */ - /* FT_FACE_FLAG_COLOR :: */ - /* [Since 2.5.1] The face has color glyph tables. To access color */ - /* glyphs use @FT_LOAD_COLOR. */ - /* */ - /* FT_FACE_FLAG_VARIATION :: */ - /* [Since 2.9] Set if the current face (or named instance) has been */ - /* altered with @FT_Set_MM_Design_Coordinates, */ - /* @FT_Set_Var_Design_Coordinates, or */ - /* @FT_Set_Var_Blend_Coordinates. This flag is unset by a call to */ - /* @FT_Set_Named_Instance. */ - /* */ + /************************************************************************** + * + * @enum: + * FT_FACE_FLAG_XXX + * + * @description: + * A list of bit flags used in the `face_flags` field of the @FT_FaceRec + * structure. They inform client applications of properties of the + * corresponding face. + * + * @values: + * FT_FACE_FLAG_SCALABLE :: + * The face contains outline glyphs. Note that a face can contain + * bitmap strikes also, i.e., a face can have both this flag and + * @FT_FACE_FLAG_FIXED_SIZES set. + * + * FT_FACE_FLAG_FIXED_SIZES :: + * The face contains bitmap strikes. See also the `num_fixed_sizes` + * and `available_sizes` fields of @FT_FaceRec. + * + * FT_FACE_FLAG_FIXED_WIDTH :: + * The face contains fixed-width characters (like Courier, Lucida, + * MonoType, etc.). + * + * FT_FACE_FLAG_SFNT :: + * The face uses the SFNT storage scheme. For now, this means TrueType + * and OpenType. + * + * FT_FACE_FLAG_HORIZONTAL :: + * The face contains horizontal glyph metrics. This should be set for + * all common formats. + * + * FT_FACE_FLAG_VERTICAL :: + * The face contains vertical glyph metrics. This is only available in + * some formats, not all of them. + * + * FT_FACE_FLAG_KERNING :: + * The face contains kerning information. If set, the kerning distance + * can be retrieved using the function @FT_Get_Kerning. Otherwise the + * function always return the vector (0,0). Note that FreeType doesn't + * handle kerning data from the SFNT 'GPOS' table (as present in many + * OpenType fonts). + * + * FT_FACE_FLAG_FAST_GLYPHS :: + * THIS FLAG IS DEPRECATED. DO NOT USE OR TEST IT. + * + * FT_FACE_FLAG_MULTIPLE_MASTERS :: + * The face contains multiple masters and is capable of interpolating + * between them. Supported formats are Adobe MM, TrueType GX, and + * OpenType variation fonts. + * + * See section @multiple_masters for API details. + * + * FT_FACE_FLAG_GLYPH_NAMES :: + * The face contains glyph names, which can be retrieved using + * @FT_Get_Glyph_Name. Note that some TrueType fonts contain broken + * glyph name tables. Use the function @FT_Has_PS_Glyph_Names when + * needed. + * + * FT_FACE_FLAG_EXTERNAL_STREAM :: + * Used internally by FreeType to indicate that a face's stream was + * provided by the client application and should not be destroyed when + * @FT_Done_Face is called. Don't read or test this flag. + * + * FT_FACE_FLAG_HINTER :: + * The font driver has a hinting machine of its own. For example, with + * TrueType fonts, it makes sense to use data from the SFNT 'gasp' + * table only if the native TrueType hinting engine (with the bytecode + * interpreter) is available and active. + * + * FT_FACE_FLAG_CID_KEYED :: + * The face is CID-keyed. In that case, the face is not accessed by + * glyph indices but by CID values. For subsetted CID-keyed fonts this + * has the consequence that not all index values are a valid argument + * to @FT_Load_Glyph. Only the CID values for which corresponding + * glyphs in the subsetted font exist make `FT_Load_Glyph` return + * successfully; in all other cases you get an + * `FT_Err_Invalid_Argument` error. + * + * Note that CID-keyed fonts that are in an SFNT wrapper (this is, all + * OpenType/CFF fonts) don't have this flag set since the glyphs are + * accessed in the normal way (using contiguous indices); the + * 'CID-ness' isn't visible to the application. + * + * FT_FACE_FLAG_TRICKY :: + * The face is 'tricky', this is, it always needs the font format's + * native hinting engine to get a reasonable result. A typical example + * is the old Chinese font `mingli.ttf` (but not `mingliu.ttc`) that + * uses TrueType bytecode instructions to move and scale all of its + * subglyphs. + * + * It is not possible to auto-hint such fonts using + * @FT_LOAD_FORCE_AUTOHINT; it will also ignore @FT_LOAD_NO_HINTING. + * You have to set both @FT_LOAD_NO_HINTING and @FT_LOAD_NO_AUTOHINT to + * really disable hinting; however, you probably never want this except + * for demonstration purposes. + * + * Currently, there are about a dozen TrueType fonts in the list of + * tricky fonts; they are hard-coded in file `ttobjs.c`. + * + * FT_FACE_FLAG_COLOR :: + * [Since 2.5.1] The face has color glyph tables. See @FT_LOAD_COLOR + * for more information. + * + * FT_FACE_FLAG_VARIATION :: + * [Since 2.9] Set if the current face (or named instance) has been + * altered with @FT_Set_MM_Design_Coordinates, + * @FT_Set_Var_Design_Coordinates, or @FT_Set_Var_Blend_Coordinates. + * This flag is unset by a call to @FT_Set_Named_Instance. + */ #define FT_FACE_FLAG_SCALABLE ( 1L << 0 ) #define FT_FACE_FLAG_FIXED_SIZES ( 1L << 1 ) #define FT_FACE_FLAG_FIXED_WIDTH ( 1L << 2 ) @@ -1253,14 +1225,14 @@ FT_BEGIN_HEADER #define FT_FACE_FLAG_VARIATION ( 1L << 15 ) - /************************************************************************* + /************************************************************************** * * @macro: - * FT_HAS_HORIZONTAL( face ) + * FT_HAS_HORIZONTAL * * @description: - * A macro that returns true whenever a face object contains - * horizontal metrics (this is true for all font formats though). + * A macro that returns true whenever a face object contains horizontal + * metrics (this is true for all font formats though). * * @also: * @FT_HAS_VERTICAL can be used to check for vertical metrics. @@ -1270,10 +1242,10 @@ FT_BEGIN_HEADER ( (face)->face_flags & FT_FACE_FLAG_HORIZONTAL ) - /************************************************************************* + /************************************************************************** * * @macro: - * FT_HAS_VERTICAL( face ) + * FT_HAS_VERTICAL * * @description: * A macro that returns true whenever a face object contains real @@ -1284,45 +1256,45 @@ FT_BEGIN_HEADER ( (face)->face_flags & FT_FACE_FLAG_VERTICAL ) - /************************************************************************* + /************************************************************************** * * @macro: - * FT_HAS_KERNING( face ) + * FT_HAS_KERNING * * @description: - * A macro that returns true whenever a face object contains kerning - * data that can be accessed with @FT_Get_Kerning. + * A macro that returns true whenever a face object contains kerning data + * that can be accessed with @FT_Get_Kerning. * */ #define FT_HAS_KERNING( face ) \ ( (face)->face_flags & FT_FACE_FLAG_KERNING ) - /************************************************************************* + /************************************************************************** * * @macro: - * FT_IS_SCALABLE( face ) + * FT_IS_SCALABLE * * @description: * A macro that returns true whenever a face object contains a scalable - * font face (true for TrueType, Type~1, Type~42, CID, OpenType/CFF, - * and PFR font formats). + * font face (true for TrueType, Type~1, Type~42, CID, OpenType/CFF, and + * PFR font formats). * */ #define FT_IS_SCALABLE( face ) \ ( (face)->face_flags & FT_FACE_FLAG_SCALABLE ) - /************************************************************************* + /************************************************************************** * * @macro: - * FT_IS_SFNT( face ) + * FT_IS_SFNT * * @description: - * A macro that returns true whenever a face object contains a font - * whose format is based on the SFNT storage scheme. This usually - * means: TrueType fonts, OpenType fonts, as well as SFNT-based embedded - * bitmap fonts. + * A macro that returns true whenever a face object contains a font whose + * format is based on the SFNT storage scheme. This usually means: + * TrueType fonts, OpenType fonts, as well as SFNT-based embedded bitmap + * fonts. * * If this macro is true, all functions defined in @FT_SFNT_NAMES_H and * @FT_TRUETYPE_TABLES_H are available. @@ -1332,14 +1304,14 @@ FT_BEGIN_HEADER ( (face)->face_flags & FT_FACE_FLAG_SFNT ) - /************************************************************************* + /************************************************************************** * * @macro: - * FT_IS_FIXED_WIDTH( face ) + * FT_IS_FIXED_WIDTH * * @description: * A macro that returns true whenever a face object contains a font face - * that contains fixed-width (or `monospace', `fixed-pitch', etc.) + * that contains fixed-width (or 'monospace', 'fixed-pitch', etc.) * glyphs. * */ @@ -1347,25 +1319,25 @@ FT_BEGIN_HEADER ( (face)->face_flags & FT_FACE_FLAG_FIXED_WIDTH ) - /************************************************************************* + /************************************************************************** * * @macro: - * FT_HAS_FIXED_SIZES( face ) + * FT_HAS_FIXED_SIZES * * @description: * A macro that returns true whenever a face object contains some - * embedded bitmaps. See the `available_sizes' field of the - * @FT_FaceRec structure. + * embedded bitmaps. See the `available_sizes` field of the @FT_FaceRec + * structure. * */ #define FT_HAS_FIXED_SIZES( face ) \ ( (face)->face_flags & FT_FACE_FLAG_FIXED_SIZES ) - /************************************************************************* + /************************************************************************** * * @macro: - * FT_HAS_FAST_GLYPHS( face ) + * FT_HAS_FAST_GLYPHS * * @description: * Deprecated. @@ -1374,10 +1346,10 @@ FT_BEGIN_HEADER #define FT_HAS_FAST_GLYPHS( face ) 0 - /************************************************************************* + /************************************************************************** * * @macro: - * FT_HAS_GLYPH_NAMES( face ) + * FT_HAS_GLYPH_NAMES * * @description: * A macro that returns true whenever a face object contains some glyph @@ -1388,10 +1360,10 @@ FT_BEGIN_HEADER ( (face)->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) - /************************************************************************* + /************************************************************************** * * @macro: - * FT_HAS_MULTIPLE_MASTERS( face ) + * FT_HAS_MULTIPLE_MASTERS * * @description: * A macro that returns true whenever a face object contains some @@ -1403,10 +1375,10 @@ FT_BEGIN_HEADER ( (face)->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS ) - /************************************************************************* + /************************************************************************** * * @macro: - * FT_IS_NAMED_INSTANCE( face ) + * FT_IS_NAMED_INSTANCE * * @description: * A macro that returns true whenever a face object is a named instance @@ -1425,14 +1397,14 @@ FT_BEGIN_HEADER ( (face)->face_index & 0x7FFF0000L ) - /************************************************************************* + /************************************************************************** * * @macro: - * FT_IS_VARIATION( face ) + * FT_IS_VARIATION * * @description: - * A macro that returns true whenever a face object has been altered - * by @FT_Set_MM_Design_Coordinates, @FT_Set_Var_Design_Coordinates, or + * A macro that returns true whenever a face object has been altered by + * @FT_Set_MM_Design_Coordinates, @FT_Set_Var_Design_Coordinates, or * @FT_Set_Var_Blend_Coordinates. * * @since: @@ -1443,15 +1415,14 @@ FT_BEGIN_HEADER ( (face)->face_flags & FT_FACE_FLAG_VARIATION ) - /************************************************************************* + /************************************************************************** * * @macro: - * FT_IS_CID_KEYED( face ) + * FT_IS_CID_KEYED * * @description: * A macro that returns true whenever a face object contains a CID-keyed - * font. See the discussion of @FT_FACE_FLAG_CID_KEYED for more - * details. + * font. See the discussion of @FT_FACE_FLAG_CID_KEYED for more details. * * If this macro is true, all functions defined in @FT_CID_H are * available. @@ -1461,13 +1432,13 @@ FT_BEGIN_HEADER ( (face)->face_flags & FT_FACE_FLAG_CID_KEYED ) - /************************************************************************* + /************************************************************************** * * @macro: - * FT_IS_TRICKY( face ) + * FT_IS_TRICKY * * @description: - * A macro that returns true whenever a face represents a `tricky' font. + * A macro that returns true whenever a face represents a 'tricky' font. * See the discussion of @FT_FACE_FLAG_TRICKY for more details. * */ @@ -1475,14 +1446,14 @@ FT_BEGIN_HEADER ( (face)->face_flags & FT_FACE_FLAG_TRICKY ) - /************************************************************************* + /************************************************************************** * * @macro: - * FT_HAS_COLOR( face ) + * FT_HAS_COLOR * * @description: - * A macro that returns true whenever a face object contains - * tables for color glyphs. + * A macro that returns true whenever a face object contains tables for + * color glyphs. * * @since: * 2.5.1 @@ -1492,149 +1463,148 @@ FT_BEGIN_HEADER ( (face)->face_flags & FT_FACE_FLAG_COLOR ) - /*************************************************************************/ - /* */ - /* <Const> */ - /* FT_STYLE_FLAG_XXX */ - /* */ - /* <Description> */ - /* A list of bit flags to indicate the style of a given face. These */ - /* are used in the `style_flags' field of @FT_FaceRec. */ - /* */ - /* <Values> */ - /* FT_STYLE_FLAG_ITALIC :: */ - /* The face style is italic or oblique. */ - /* */ - /* FT_STYLE_FLAG_BOLD :: */ - /* The face is bold. */ - /* */ - /* <Note> */ - /* The style information as provided by FreeType is very basic. More */ - /* details are beyond the scope and should be done on a higher level */ - /* (for example, by analyzing various fields of the `OS/2' table in */ - /* SFNT based fonts). */ - /* */ + /************************************************************************** + * + * @enum: + * FT_STYLE_FLAG_XXX + * + * @description: + * A list of bit flags to indicate the style of a given face. These are + * used in the `style_flags` field of @FT_FaceRec. + * + * @values: + * FT_STYLE_FLAG_ITALIC :: + * The face style is italic or oblique. + * + * FT_STYLE_FLAG_BOLD :: + * The face is bold. + * + * @note: + * The style information as provided by FreeType is very basic. More + * details are beyond the scope and should be done on a higher level (for + * example, by analyzing various fields of the 'OS/2' table in SFNT based + * fonts). + */ #define FT_STYLE_FLAG_ITALIC ( 1 << 0 ) #define FT_STYLE_FLAG_BOLD ( 1 << 1 ) - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Size_Internal */ - /* */ - /* <Description> */ - /* An opaque handle to an `FT_Size_InternalRec' structure, used to */ - /* model private data of a given @FT_Size object. */ - /* */ + /************************************************************************** + * + * @type: + * FT_Size_Internal + * + * @description: + * An opaque handle to an `FT_Size_InternalRec` structure, used to model + * private data of a given @FT_Size object. + */ typedef struct FT_Size_InternalRec_* FT_Size_Internal; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Size_Metrics */ - /* */ - /* <Description> */ - /* The size metrics structure gives the metrics of a size object. */ - /* */ - /* <Fields> */ - /* x_ppem :: The width of the scaled EM square in pixels, hence */ - /* the term `ppem' (pixels per EM). It is also */ - /* referred to as `nominal width'. */ - /* */ - /* y_ppem :: The height of the scaled EM square in pixels, */ - /* hence the term `ppem' (pixels per EM). It is also */ - /* referred to as `nominal height'. */ - /* */ - /* x_scale :: A 16.16 fractional scaling value to convert */ - /* horizontal metrics from font units to 26.6 */ - /* fractional pixels. Only relevant for scalable */ - /* font formats. */ - /* */ - /* y_scale :: A 16.16 fractional scaling value to convert */ - /* vertical metrics from font units to 26.6 */ - /* fractional pixels. Only relevant for scalable */ - /* font formats. */ - /* */ - /* ascender :: The ascender in 26.6 fractional pixels, rounded up */ - /* to an integer value. See @FT_FaceRec for the */ - /* details. */ - /* */ - /* descender :: The descender in 26.6 fractional pixels, rounded */ - /* down to an integer value. See @FT_FaceRec for the */ - /* details. */ - /* */ - /* height :: The height in 26.6 fractional pixels, rounded to */ - /* an integer value. See @FT_FaceRec for the */ - /* details. */ - /* */ - /* max_advance :: The maximum advance width in 26.6 fractional */ - /* pixels, rounded to an integer value. See */ - /* @FT_FaceRec for the details. */ - /* */ - /* <Note> */ - /* The scaling values, if relevant, are determined first during a */ - /* size changing operation. The remaining fields are then set by the */ - /* driver. For scalable formats, they are usually set to scaled */ - /* values of the corresponding fields in @FT_FaceRec. Some values */ - /* like ascender or descender are rounded for historical reasons; */ - /* more precise values (for outline fonts) can be derived by scaling */ - /* the corresponding @FT_FaceRec values manually, with code similar */ - /* to the following. */ - /* */ - /* { */ - /* scaled_ascender = FT_MulFix( face->ascender, */ - /* size_metrics->y_scale ); */ - /* } */ - /* */ - /* Note that due to glyph hinting and the selected rendering mode */ - /* these values are usually not exact; consequently, they must be */ - /* treated as unreliable with an error margin of at least one pixel! */ - /* */ - /* Indeed, the only way to get the exact metrics is to render _all_ */ - /* glyphs. As this would be a definite performance hit, it is up to */ - /* client applications to perform such computations. */ - /* */ - /* The `FT_Size_Metrics' structure is valid for bitmap fonts also. */ - /* */ - /* */ - /* *TrueType* *fonts* *with* *native* *bytecode* *hinting* */ - /* */ - /* All applications that handle TrueType fonts with native hinting */ - /* must be aware that TTFs expect different rounding of vertical font */ - /* dimensions. The application has to cater for this, especially if */ - /* it wants to rely on a TTF's vertical data (for example, to */ - /* properly align box characters vertically). */ - /* */ - /* Only the application knows _in_ _advance_ that it is going to use */ - /* native hinting for TTFs! FreeType, on the other hand, selects the */ - /* hinting mode not at the time of creating an @FT_Size object but */ - /* much later, namely while calling @FT_Load_Glyph. */ - /* */ - /* Here is some pseudo code that illustrates a possible solution. */ - /* */ - /* { */ - /* font_format = FT_Get_Font_Format( face ); */ - /* */ - /* if ( !strcmp( font_format, "TrueType" ) && */ - /* do_native_bytecode_hinting ) */ - /* { */ - /* ascender = ROUND( FT_MulFix( face->ascender, */ - /* size_metrics->y_scale ) ); */ - /* descender = ROUND( FT_MulFix( face->descender, */ - /* size_metrics->y_scale ) ); */ - /* } */ - /* else */ - /* { */ - /* ascender = size_metrics->ascender; */ - /* descender = size_metrics->descender; */ - /* } */ - /* */ - /* height = size_metrics->height; */ - /* max_advance = size_metrics->max_advance; */ - /* } */ - /* */ + /************************************************************************** + * + * @struct: + * FT_Size_Metrics + * + * @description: + * The size metrics structure gives the metrics of a size object. + * + * @fields: + * x_ppem :: + * The width of the scaled EM square in pixels, hence the term 'ppem' + * (pixels per EM). It is also referred to as 'nominal width'. + * + * y_ppem :: + * The height of the scaled EM square in pixels, hence the term 'ppem' + * (pixels per EM). It is also referred to as 'nominal height'. + * + * x_scale :: + * A 16.16 fractional scaling value to convert horizontal metrics from + * font units to 26.6 fractional pixels. Only relevant for scalable + * font formats. + * + * y_scale :: + * A 16.16 fractional scaling value to convert vertical metrics from + * font units to 26.6 fractional pixels. Only relevant for scalable + * font formats. + * + * ascender :: + * The ascender in 26.6 fractional pixels, rounded up to an integer + * value. See @FT_FaceRec for the details. + * + * descender :: + * The descender in 26.6 fractional pixels, rounded down to an integer + * value. See @FT_FaceRec for the details. + * + * height :: + * The height in 26.6 fractional pixels, rounded to an integer value. + * See @FT_FaceRec for the details. + * + * max_advance :: + * The maximum advance width in 26.6 fractional pixels, rounded to an + * integer value. See @FT_FaceRec for the details. + * + * @note: + * The scaling values, if relevant, are determined first during a size + * changing operation. The remaining fields are then set by the driver. + * For scalable formats, they are usually set to scaled values of the + * corresponding fields in @FT_FaceRec. Some values like ascender or + * descender are rounded for historical reasons; more precise values (for + * outline fonts) can be derived by scaling the corresponding @FT_FaceRec + * values manually, with code similar to the following. + * + * ``` + * scaled_ascender = FT_MulFix( face->ascender, + * size_metrics->y_scale ); + * ``` + * + * Note that due to glyph hinting and the selected rendering mode these + * values are usually not exact; consequently, they must be treated as + * unreliable with an error margin of at least one pixel! + * + * Indeed, the only way to get the exact metrics is to render _all_ + * glyphs. As this would be a definite performance hit, it is up to + * client applications to perform such computations. + * + * The `FT_Size_Metrics` structure is valid for bitmap fonts also. + * + * + * **TrueType fonts with native bytecode hinting** + * + * All applications that handle TrueType fonts with native hinting must + * be aware that TTFs expect different rounding of vertical font + * dimensions. The application has to cater for this, especially if it + * wants to rely on a TTF's vertical data (for example, to properly align + * box characters vertically). + * + * Only the application knows _in advance_ that it is going to use native + * hinting for TTFs! FreeType, on the other hand, selects the hinting + * mode not at the time of creating an @FT_Size object but much later, + * namely while calling @FT_Load_Glyph. + * + * Here is some pseudo code that illustrates a possible solution. + * + * ``` + * font_format = FT_Get_Font_Format( face ); + * + * if ( !strcmp( font_format, "TrueType" ) && + * do_native_bytecode_hinting ) + * { + * ascender = ROUND( FT_MulFix( face->ascender, + * size_metrics->y_scale ) ); + * descender = ROUND( FT_MulFix( face->descender, + * size_metrics->y_scale ) ); + * } + * else + * { + * ascender = size_metrics->ascender; + * descender = size_metrics->descender; + * } + * + * height = size_metrics->height; + * max_advance = size_metrics->max_advance; + * ``` + */ typedef struct FT_Size_Metrics_ { FT_UShort x_ppem; /* horizontal pixels per EM */ @@ -1651,25 +1621,27 @@ FT_BEGIN_HEADER } FT_Size_Metrics; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_SizeRec */ - /* */ - /* <Description> */ - /* FreeType root size class structure. A size object models a face */ - /* object at a given size. */ - /* */ - /* <Fields> */ - /* face :: Handle to the parent face object. */ - /* */ - /* generic :: A typeless pointer, unused by the FreeType library or */ - /* any of its drivers. It can be used by client */ - /* applications to link their own data to each size */ - /* object. */ - /* */ - /* metrics :: Metrics for this size object. This field is read-only. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_SizeRec + * + * @description: + * FreeType root size class structure. A size object models a face + * object at a given size. + * + * @fields: + * face :: + * Handle to the parent face object. + * + * generic :: + * A typeless pointer, unused by the FreeType library or any of its + * drivers. It can be used by client applications to link their own + * data to each size object. + * + * metrics :: + * Metrics for this size object. This field is read-only. + */ typedef struct FT_SizeRec_ { FT_Face face; /* parent face object */ @@ -1680,237 +1652,234 @@ FT_BEGIN_HEADER } FT_SizeRec; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_SubGlyph */ - /* */ - /* <Description> */ - /* The subglyph structure is an internal object used to describe */ - /* subglyphs (for example, in the case of composites). */ - /* */ - /* <Note> */ - /* The subglyph implementation is not part of the high-level API, */ - /* hence the forward structure declaration. */ - /* */ - /* You can however retrieve subglyph information with */ - /* @FT_Get_SubGlyph_Info. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_SubGlyph + * + * @description: + * The subglyph structure is an internal object used to describe + * subglyphs (for example, in the case of composites). + * + * @note: + * The subglyph implementation is not part of the high-level API, hence + * the forward structure declaration. + * + * You can however retrieve subglyph information with + * @FT_Get_SubGlyph_Info. + */ typedef struct FT_SubGlyphRec_* FT_SubGlyph; - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Slot_Internal */ - /* */ - /* <Description> */ - /* An opaque handle to an `FT_Slot_InternalRec' structure, used to */ - /* model private data of a given @FT_GlyphSlot object. */ - /* */ + /************************************************************************** + * + * @type: + * FT_Slot_Internal + * + * @description: + * An opaque handle to an `FT_Slot_InternalRec` structure, used to model + * private data of a given @FT_GlyphSlot object. + */ typedef struct FT_Slot_InternalRec_* FT_Slot_Internal; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_GlyphSlotRec */ - /* */ - /* <Description> */ - /* FreeType root glyph slot class structure. A glyph slot is a */ - /* container where individual glyphs can be loaded, be they in */ - /* outline or bitmap format. */ - /* */ - /* <Fields> */ - /* library :: A handle to the FreeType library instance */ - /* this slot belongs to. */ - /* */ - /* face :: A handle to the parent face object. */ - /* */ - /* next :: In some cases (like some font tools), several */ - /* glyph slots per face object can be a good */ - /* thing. As this is rare, the glyph slots are */ - /* listed through a direct, single-linked list */ - /* using its `next' field. */ - /* */ - /* generic :: A typeless pointer unused by the FreeType */ - /* library or any of its drivers. It can be */ - /* used by client applications to link their own */ - /* data to each glyph slot object. */ - /* */ - /* metrics :: The metrics of the last loaded glyph in the */ - /* slot. The returned values depend on the last */ - /* load flags (see the @FT_Load_Glyph API */ - /* function) and can be expressed either in 26.6 */ - /* fractional pixels or font units. */ - /* */ - /* Note that even when the glyph image is */ - /* transformed, the metrics are not. */ - /* */ - /* linearHoriAdvance :: The advance width of the unhinted glyph. */ - /* Its value is expressed in 16.16 fractional */ - /* pixels, unless @FT_LOAD_LINEAR_DESIGN is set */ - /* when loading the glyph. This field can be */ - /* important to perform correct WYSIWYG layout. */ - /* Only relevant for outline glyphs. */ - /* */ - /* linearVertAdvance :: The advance height of the unhinted glyph. */ - /* Its value is expressed in 16.16 fractional */ - /* pixels, unless @FT_LOAD_LINEAR_DESIGN is set */ - /* when loading the glyph. This field can be */ - /* important to perform correct WYSIWYG layout. */ - /* Only relevant for outline glyphs. */ - /* */ - /* advance :: This shorthand is, depending on */ - /* @FT_LOAD_IGNORE_TRANSFORM, the transformed */ - /* (hinted) advance width for the glyph, in 26.6 */ - /* fractional pixel format. As specified with */ - /* @FT_LOAD_VERTICAL_LAYOUT, it uses either the */ - /* `horiAdvance' or the `vertAdvance' value of */ - /* `metrics' field. */ - /* */ - /* format :: This field indicates the format of the image */ - /* contained in the glyph slot. Typically */ - /* @FT_GLYPH_FORMAT_BITMAP, */ - /* @FT_GLYPH_FORMAT_OUTLINE, or */ - /* @FT_GLYPH_FORMAT_COMPOSITE, but other values */ - /* are possible. */ - /* */ - /* bitmap :: This field is used as a bitmap descriptor. */ - /* Note that the address and content of the */ - /* bitmap buffer can change between calls of */ - /* @FT_Load_Glyph and a few other functions. */ - /* */ - /* bitmap_left :: The bitmap's left bearing expressed in */ - /* integer pixels. */ - /* */ - /* bitmap_top :: The bitmap's top bearing expressed in integer */ - /* pixels. This is the distance from the */ - /* baseline to the top-most glyph scanline, */ - /* upwards y~coordinates being *positive*. */ - /* */ - /* outline :: The outline descriptor for the current glyph */ - /* image if its format is */ - /* @FT_GLYPH_FORMAT_OUTLINE. Once a glyph is */ - /* loaded, `outline' can be transformed, */ - /* distorted, emboldened, etc. However, it must */ - /* not be freed. */ - /* */ - /* num_subglyphs :: The number of subglyphs in a composite glyph. */ - /* This field is only valid for the composite */ - /* glyph format that should normally only be */ - /* loaded with the @FT_LOAD_NO_RECURSE flag. */ - /* */ - /* subglyphs :: An array of subglyph descriptors for */ - /* composite glyphs. There are `num_subglyphs' */ - /* elements in there. Currently internal to */ - /* FreeType. */ - /* */ - /* control_data :: Certain font drivers can also return the */ - /* control data for a given glyph image (e.g. */ - /* TrueType bytecode, Type~1 charstrings, etc.). */ - /* This field is a pointer to such data; it is */ - /* currently internal to FreeType. */ - /* */ - /* control_len :: This is the length in bytes of the control */ - /* data. Currently internal to FreeType. */ - /* */ - /* other :: Reserved. */ - /* */ - /* lsb_delta :: The difference between hinted and unhinted */ - /* left side bearing while auto-hinting is */ - /* active. Zero otherwise. */ - /* */ - /* rsb_delta :: The difference between hinted and unhinted */ - /* right side bearing while auto-hinting is */ - /* active. Zero otherwise. */ - /* */ - /* <Note> */ - /* If @FT_Load_Glyph is called with default flags (see */ - /* @FT_LOAD_DEFAULT) the glyph image is loaded in the glyph slot in */ - /* its native format (e.g., an outline glyph for TrueType and Type~1 */ - /* formats). [Since 2.9] The prospective bitmap metrics are */ - /* calculated according to @FT_LOAD_TARGET_XXX and other flags even */ - /* for the outline glyph, even if @FT_LOAD_RENDER is not set. */ - /* */ - /* This image can later be converted into a bitmap by calling */ - /* @FT_Render_Glyph. This function searches the current renderer for */ - /* the native image's format, then invokes it. */ - /* */ - /* The renderer is in charge of transforming the native image through */ - /* the slot's face transformation fields, then converting it into a */ - /* bitmap that is returned in `slot->bitmap'. */ - /* */ - /* Note that `slot->bitmap_left' and `slot->bitmap_top' are also used */ - /* to specify the position of the bitmap relative to the current pen */ - /* position (e.g., coordinates (0,0) on the baseline). Of course, */ - /* `slot->format' is also changed to @FT_GLYPH_FORMAT_BITMAP. */ - /* */ - /* Here is a small pseudo code fragment that shows how to use */ - /* `lsb_delta' and `rsb_delta' to do fractional positioning of */ - /* glyphs: */ - /* */ - /* { */ - /* FT_GlyphSlot slot = face->glyph; */ - /* FT_Pos origin_x = 0; */ - /* */ - /* */ - /* for all glyphs do */ - /* <load glyph with `FT_Load_Glyph'> */ - /* */ - /* FT_Outline_Translate( slot->outline, origin_x & 63, 0 ); */ - /* */ - /* <save glyph image, or render glyph, or ...> */ - /* */ - /* <compute kern between current and next glyph */ - /* and add it to `origin_x'> */ - /* */ - /* origin_x += slot->advance.x; */ - /* origin_x += slot->rsb_delta - slot->lsb_delta; */ - /* endfor */ - /* } */ - /* */ - /* Here is another small pseudo code fragment that shows how to use */ - /* `lsb_delta' and `rsb_delta' to improve integer positioning of */ - /* glyphs: */ - /* */ - /* { */ - /* FT_GlyphSlot slot = face->glyph; */ - /* FT_Pos origin_x = 0; */ - /* FT_Pos prev_rsb_delta = 0; */ - /* */ - /* */ - /* for all glyphs do */ - /* <compute kern between current and previous glyph */ - /* and add it to `origin_x'> */ - /* */ - /* <load glyph with `FT_Load_Glyph'> */ - /* */ - /* if ( prev_rsb_delta - slot->lsb_delta > 32 ) */ - /* origin_x -= 64; */ - /* else if ( prev_rsb_delta - slot->lsb_delta < -31 ) */ - /* origin_x += 64; */ - /* */ - /* prev_rsb_delta = slot->rsb_delta; */ - /* */ - /* <save glyph image, or render glyph, or ...> */ - /* */ - /* origin_x += slot->advance.x; */ - /* endfor */ - /* } */ - /* */ - /* If you use strong auto-hinting, you *must* apply these delta */ - /* values! Otherwise you will experience far too large inter-glyph */ - /* spacing at small rendering sizes in most cases. Note that it */ - /* doesn't harm to use the above code for other hinting modes also, */ - /* since the delta values are zero then. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_GlyphSlotRec + * + * @description: + * FreeType root glyph slot class structure. A glyph slot is a container + * where individual glyphs can be loaded, be they in outline or bitmap + * format. + * + * @fields: + * library :: + * A handle to the FreeType library instance this slot belongs to. + * + * face :: + * A handle to the parent face object. + * + * next :: + * In some cases (like some font tools), several glyph slots per face + * object can be a good thing. As this is rare, the glyph slots are + * listed through a direct, single-linked list using its `next` field. + * + * glyph_index :: + * [Since 2.10] The glyph index passed as an argument to @FT_Load_Glyph + * while initializing the glyph slot. + * + * generic :: + * A typeless pointer unused by the FreeType library or any of its + * drivers. It can be used by client applications to link their own + * data to each glyph slot object. + * + * metrics :: + * The metrics of the last loaded glyph in the slot. The returned + * values depend on the last load flags (see the @FT_Load_Glyph API + * function) and can be expressed either in 26.6 fractional pixels or + * font units. + * + * Note that even when the glyph image is transformed, the metrics are + * not. + * + * linearHoriAdvance :: + * The advance width of the unhinted glyph. Its value is expressed in + * 16.16 fractional pixels, unless @FT_LOAD_LINEAR_DESIGN is set when + * loading the glyph. This field can be important to perform correct + * WYSIWYG layout. Only relevant for outline glyphs. + * + * linearVertAdvance :: + * The advance height of the unhinted glyph. Its value is expressed in + * 16.16 fractional pixels, unless @FT_LOAD_LINEAR_DESIGN is set when + * loading the glyph. This field can be important to perform correct + * WYSIWYG layout. Only relevant for outline glyphs. + * + * advance :: + * This shorthand is, depending on @FT_LOAD_IGNORE_TRANSFORM, the + * transformed (hinted) advance width for the glyph, in 26.6 fractional + * pixel format. As specified with @FT_LOAD_VERTICAL_LAYOUT, it uses + * either the `horiAdvance` or the `vertAdvance` value of `metrics` + * field. + * + * format :: + * This field indicates the format of the image contained in the glyph + * slot. Typically @FT_GLYPH_FORMAT_BITMAP, @FT_GLYPH_FORMAT_OUTLINE, + * or @FT_GLYPH_FORMAT_COMPOSITE, but other values are possible. + * + * bitmap :: + * This field is used as a bitmap descriptor. Note that the address + * and content of the bitmap buffer can change between calls of + * @FT_Load_Glyph and a few other functions. + * + * bitmap_left :: + * The bitmap's left bearing expressed in integer pixels. + * + * bitmap_top :: + * The bitmap's top bearing expressed in integer pixels. This is the + * distance from the baseline to the top-most glyph scanline, upwards + * y~coordinates being **positive**. + * + * outline :: + * The outline descriptor for the current glyph image if its format is + * @FT_GLYPH_FORMAT_OUTLINE. Once a glyph is loaded, `outline` can be + * transformed, distorted, emboldened, etc. However, it must not be + * freed. + * + * num_subglyphs :: + * The number of subglyphs in a composite glyph. This field is only + * valid for the composite glyph format that should normally only be + * loaded with the @FT_LOAD_NO_RECURSE flag. + * + * subglyphs :: + * An array of subglyph descriptors for composite glyphs. There are + * `num_subglyphs` elements in there. Currently internal to FreeType. + * + * control_data :: + * Certain font drivers can also return the control data for a given + * glyph image (e.g. TrueType bytecode, Type~1 charstrings, etc.). + * This field is a pointer to such data; it is currently internal to + * FreeType. + * + * control_len :: + * This is the length in bytes of the control data. Currently internal + * to FreeType. + * + * other :: + * Reserved. + * + * lsb_delta :: + * The difference between hinted and unhinted left side bearing while + * auto-hinting is active. Zero otherwise. + * + * rsb_delta :: + * The difference between hinted and unhinted right side bearing while + * auto-hinting is active. Zero otherwise. + * + * @note: + * If @FT_Load_Glyph is called with default flags (see @FT_LOAD_DEFAULT) + * the glyph image is loaded in the glyph slot in its native format + * (e.g., an outline glyph for TrueType and Type~1 formats). [Since 2.9] + * The prospective bitmap metrics are calculated according to + * @FT_LOAD_TARGET_XXX and other flags even for the outline glyph, even + * if @FT_LOAD_RENDER is not set. + * + * This image can later be converted into a bitmap by calling + * @FT_Render_Glyph. This function searches the current renderer for the + * native image's format, then invokes it. + * + * The renderer is in charge of transforming the native image through the + * slot's face transformation fields, then converting it into a bitmap + * that is returned in `slot->bitmap`. + * + * Note that `slot->bitmap_left` and `slot->bitmap_top` are also used to + * specify the position of the bitmap relative to the current pen + * position (e.g., coordinates (0,0) on the baseline). Of course, + * `slot->format` is also changed to @FT_GLYPH_FORMAT_BITMAP. + * + * Here is a small pseudo code fragment that shows how to use `lsb_delta` + * and `rsb_delta` to do fractional positioning of glyphs: + * + * ``` + * FT_GlyphSlot slot = face->glyph; + * FT_Pos origin_x = 0; + * + * + * for all glyphs do + * <load glyph with `FT_Load_Glyph'> + * + * FT_Outline_Translate( slot->outline, origin_x & 63, 0 ); + * + * <save glyph image, or render glyph, or ...> + * + * <compute kern between current and next glyph + * and add it to `origin_x'> + * + * origin_x += slot->advance.x; + * origin_x += slot->lsb_delta - slot->rsb_delta; + * endfor + * ``` + * + * Here is another small pseudo code fragment that shows how to use + * `lsb_delta` and `rsb_delta` to improve integer positioning of glyphs: + * + * ``` + * FT_GlyphSlot slot = face->glyph; + * FT_Pos origin_x = 0; + * FT_Pos prev_rsb_delta = 0; + * + * + * for all glyphs do + * <compute kern between current and previous glyph + * and add it to `origin_x'> + * + * <load glyph with `FT_Load_Glyph'> + * + * if ( prev_rsb_delta - slot->lsb_delta > 32 ) + * origin_x -= 64; + * else if ( prev_rsb_delta - slot->lsb_delta < -31 ) + * origin_x += 64; + * + * prev_rsb_delta = slot->rsb_delta; + * + * <save glyph image, or render glyph, or ...> + * + * origin_x += slot->advance.x; + * endfor + * ``` + * + * If you use strong auto-hinting, you **must** apply these delta values! + * Otherwise you will experience far too large inter-glyph spacing at + * small rendering sizes in most cases. Note that it doesn't harm to use + * the above code for other hinting modes also, since the delta values + * are zero then. + */ typedef struct FT_GlyphSlotRec_ { FT_Library library; FT_Face face; FT_GlyphSlot next; - FT_UInt reserved; /* retained for binary compatibility */ + FT_UInt glyph_index; /* new in 2.10; was reserved previously */ FT_Generic generic; FT_Glyph_Metrics metrics; @@ -1951,86 +1920,92 @@ FT_BEGIN_HEADER /*************************************************************************/ - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Init_FreeType */ - /* */ - /* <Description> */ - /* Initialize a new FreeType library object. The set of modules */ - /* that are registered by this function is determined at build time. */ - /* */ - /* <Output> */ - /* alibrary :: A handle to a new library object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* In case you want to provide your own memory allocating routines, */ - /* use @FT_New_Library instead, followed by a call to */ - /* @FT_Add_Default_Modules (or a series of calls to @FT_Add_Module) */ - /* and @FT_Set_Default_Properties. */ - /* */ - /* See the documentation of @FT_Library and @FT_Face for */ - /* multi-threading issues. */ - /* */ - /* If you need reference-counting (cf. @FT_Reference_Library), use */ - /* @FT_New_Library and @FT_Done_Library. */ - /* */ - /* If compilation option FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES is */ - /* set, this function reads the `FREETYPE_PROPERTIES' environment */ - /* variable to control driver properties. See section @properties */ - /* for more. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Init_FreeType + * + * @description: + * Initialize a new FreeType library object. The set of modules that are + * registered by this function is determined at build time. + * + * @output: + * alibrary :: + * A handle to a new library object. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * In case you want to provide your own memory allocating routines, use + * @FT_New_Library instead, followed by a call to @FT_Add_Default_Modules + * (or a series of calls to @FT_Add_Module) and + * @FT_Set_Default_Properties. + * + * See the documentation of @FT_Library and @FT_Face for multi-threading + * issues. + * + * If you need reference-counting (cf. @FT_Reference_Library), use + * @FT_New_Library and @FT_Done_Library. + * + * If compilation option `FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES` is + * set, this function reads the `FREETYPE_PROPERTIES` environment + * variable to control driver properties. See section @properties for + * more. + */ FT_EXPORT( FT_Error ) FT_Init_FreeType( FT_Library *alibrary ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Done_FreeType */ - /* */ - /* <Description> */ - /* Destroy a given FreeType library object and all of its children, */ - /* including resources, drivers, faces, sizes, etc. */ - /* */ - /* <Input> */ - /* library :: A handle to the target library object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Done_FreeType + * + * @description: + * Destroy a given FreeType library object and all of its children, + * including resources, drivers, faces, sizes, etc. + * + * @input: + * library :: + * A handle to the target library object. + * + * @return: + * FreeType error code. 0~means success. + */ FT_EXPORT( FT_Error ) FT_Done_FreeType( FT_Library library ); - /*************************************************************************/ - /* */ - /* <Enum> */ - /* FT_OPEN_XXX */ - /* */ - /* <Description> */ - /* A list of bit field constants used within the `flags' field of the */ - /* @FT_Open_Args structure. */ - /* */ - /* <Values> */ - /* FT_OPEN_MEMORY :: This is a memory-based stream. */ - /* */ - /* FT_OPEN_STREAM :: Copy the stream from the `stream' field. */ - /* */ - /* FT_OPEN_PATHNAME :: Create a new input stream from a C~path */ - /* name. */ - /* */ - /* FT_OPEN_DRIVER :: Use the `driver' field. */ - /* */ - /* FT_OPEN_PARAMS :: Use the `num_params' and `params' fields. */ - /* */ - /* <Note> */ - /* The `FT_OPEN_MEMORY', `FT_OPEN_STREAM', and `FT_OPEN_PATHNAME' */ - /* flags are mutually exclusive. */ - /* */ + /************************************************************************** + * + * @enum: + * FT_OPEN_XXX + * + * @description: + * A list of bit field constants used within the `flags` field of the + * @FT_Open_Args structure. + * + * @values: + * FT_OPEN_MEMORY :: + * This is a memory-based stream. + * + * FT_OPEN_STREAM :: + * Copy the stream from the `stream` field. + * + * FT_OPEN_PATHNAME :: + * Create a new input stream from a C~path name. + * + * FT_OPEN_DRIVER :: + * Use the `driver` field. + * + * FT_OPEN_PARAMS :: + * Use the `num_params` and `params` fields. + * + * @note: + * The `FT_OPEN_MEMORY`, `FT_OPEN_STREAM`, and `FT_OPEN_PATHNAME` flags + * are mutually exclusive. + */ #define FT_OPEN_MEMORY 0x1 #define FT_OPEN_STREAM 0x2 #define FT_OPEN_PATHNAME 0x4 @@ -2038,7 +2013,7 @@ FT_BEGIN_HEADER #define FT_OPEN_PARAMS 0x10 - /* these constants are deprecated; use the corresponding `FT_OPEN_XXX' */ + /* these constants are deprecated; use the corresponding `FT_OPEN_XXX` */ /* values instead */ #define ft_open_memory FT_OPEN_MEMORY #define ft_open_stream FT_OPEN_STREAM @@ -2047,91 +2022,97 @@ FT_BEGIN_HEADER #define ft_open_params FT_OPEN_PARAMS - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Parameter */ - /* */ - /* <Description> */ - /* A simple structure to pass more or less generic parameters to */ - /* @FT_Open_Face and @FT_Face_Properties. */ - /* */ - /* <Fields> */ - /* tag :: A four-byte identification tag. */ - /* */ - /* data :: A pointer to the parameter data. */ - /* */ - /* <Note> */ - /* The ID and function of parameters are driver-specific. See the */ - /* various FT_PARAM_TAG_XXX flags for more information. */ - /* */ - typedef struct FT_Parameter_ - { - FT_ULong tag; + /************************************************************************** + * + * @struct: + * FT_Parameter + * + * @description: + * A simple structure to pass more or less generic parameters to + * @FT_Open_Face and @FT_Face_Properties. + * + * @fields: + * tag :: + * A four-byte identification tag. + * + * data :: + * A pointer to the parameter data. + * + * @note: + * The ID and function of parameters are driver-specific. See section + * @parameter_tags for more information. + */ + typedef struct FT_Parameter_ + { + FT_ULong tag; FT_Pointer data; } FT_Parameter; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Open_Args */ - /* */ - /* <Description> */ - /* A structure to indicate how to open a new font file or stream. A */ - /* pointer to such a structure can be used as a parameter for the */ - /* functions @FT_Open_Face and @FT_Attach_Stream. */ - /* */ - /* <Fields> */ - /* flags :: A set of bit flags indicating how to use the */ - /* structure. */ - /* */ - /* memory_base :: The first byte of the file in memory. */ - /* */ - /* memory_size :: The size in bytes of the file in memory. */ - /* */ - /* pathname :: A pointer to an 8-bit file pathname. */ - /* */ - /* stream :: A handle to a source stream object. */ - /* */ - /* driver :: This field is exclusively used by @FT_Open_Face; */ - /* it simply specifies the font driver to use for */ - /* opening the face. If set to NULL, FreeType tries */ - /* to load the face with each one of the drivers in */ - /* its list. */ - /* */ - /* num_params :: The number of extra parameters. */ - /* */ - /* params :: Extra parameters passed to the font driver when */ - /* opening a new face. */ - /* */ - /* <Note> */ - /* The stream type is determined by the contents of `flags' that */ - /* are tested in the following order by @FT_Open_Face: */ - /* */ - /* If the @FT_OPEN_MEMORY bit is set, assume that this is a */ - /* memory file of `memory_size' bytes, located at `memory_address'. */ - /* The data are not copied, and the client is responsible for */ - /* releasing and destroying them _after_ the corresponding call to */ - /* @FT_Done_Face. */ - /* */ - /* Otherwise, if the @FT_OPEN_STREAM bit is set, assume that a */ - /* custom input stream `stream' is used. */ - /* */ - /* Otherwise, if the @FT_OPEN_PATHNAME bit is set, assume that this */ - /* is a normal file and use `pathname' to open it. */ - /* */ - /* If the @FT_OPEN_DRIVER bit is set, @FT_Open_Face only tries to */ - /* open the file with the driver whose handler is in `driver'. */ - /* */ - /* If the @FT_OPEN_PARAMS bit is set, the parameters given by */ - /* `num_params' and `params' is used. They are ignored otherwise. */ - /* */ - /* Ideally, both the `pathname' and `params' fields should be tagged */ - /* as `const'; this is missing for API backward compatibility. In */ - /* other words, applications should treat them as read-only. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_Open_Args + * + * @description: + * A structure to indicate how to open a new font file or stream. A + * pointer to such a structure can be used as a parameter for the + * functions @FT_Open_Face and @FT_Attach_Stream. + * + * @fields: + * flags :: + * A set of bit flags indicating how to use the structure. + * + * memory_base :: + * The first byte of the file in memory. + * + * memory_size :: + * The size in bytes of the file in memory. + * + * pathname :: + * A pointer to an 8-bit file pathname. + * + * stream :: + * A handle to a source stream object. + * + * driver :: + * This field is exclusively used by @FT_Open_Face; it simply specifies + * the font driver to use for opening the face. If set to `NULL`, + * FreeType tries to load the face with each one of the drivers in its + * list. + * + * num_params :: + * The number of extra parameters. + * + * params :: + * Extra parameters passed to the font driver when opening a new face. + * + * @note: + * The stream type is determined by the contents of `flags` that are + * tested in the following order by @FT_Open_Face: + * + * If the @FT_OPEN_MEMORY bit is set, assume that this is a memory file + * of `memory_size` bytes, located at `memory_address`. The data are not + * copied, and the client is responsible for releasing and destroying + * them _after_ the corresponding call to @FT_Done_Face. + * + * Otherwise, if the @FT_OPEN_STREAM bit is set, assume that a custom + * input stream `stream` is used. + * + * Otherwise, if the @FT_OPEN_PATHNAME bit is set, assume that this is a + * normal file and use `pathname` to open it. + * + * If the @FT_OPEN_DRIVER bit is set, @FT_Open_Face only tries to open + * the file with the driver whose handler is in `driver`. + * + * If the @FT_OPEN_PARAMS bit is set, the parameters given by + * `num_params` and `params` is used. They are ignored otherwise. + * + * Ideally, both the `pathname` and `params` fields should be tagged as + * 'const'; this is missing for API backward compatibility. In other + * words, applications should treat them as read-only. + */ typedef struct FT_Open_Args_ { FT_UInt flags; @@ -2146,34 +2127,37 @@ FT_BEGIN_HEADER } FT_Open_Args; - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_New_Face */ - /* */ - /* <Description> */ - /* Call @FT_Open_Face to open a font by its pathname. */ - /* */ - /* <InOut> */ - /* library :: A handle to the library resource. */ - /* */ - /* <Input> */ - /* pathname :: A path to the font file. */ - /* */ - /* face_index :: See @FT_Open_Face for a detailed description of this */ - /* parameter. */ - /* */ - /* <Output> */ - /* aface :: A handle to a new face object. If `face_index' is */ - /* greater than or equal to zero, it must be non-NULL. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* Use @FT_Done_Face to destroy the created @FT_Face object (along */ - /* with its slot and sizes). */ - /* */ + /************************************************************************** + * + * @function: + * FT_New_Face + * + * @description: + * Call @FT_Open_Face to open a font by its pathname. + * + * @inout: + * library :: + * A handle to the library resource. + * + * @input: + * pathname :: + * A path to the font file. + * + * face_index :: + * See @FT_Open_Face for a detailed description of this parameter. + * + * @output: + * aface :: + * A handle to a new face object. If `face_index` is greater than or + * equal to zero, it must be non-`NULL`. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * Use @FT_Done_Face to destroy the created @FT_Face object (along with + * its slot and sizes). + */ FT_EXPORT( FT_Error ) FT_New_Face( FT_Library library, const char* filepathname, @@ -2181,36 +2165,39 @@ FT_BEGIN_HEADER FT_Face *aface ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_New_Memory_Face */ - /* */ - /* <Description> */ - /* Call @FT_Open_Face to open a font that has been loaded into */ - /* memory. */ - /* */ - /* <InOut> */ - /* library :: A handle to the library resource. */ - /* */ - /* <Input> */ - /* file_base :: A pointer to the beginning of the font data. */ - /* */ - /* file_size :: The size of the memory chunk used by the font data. */ - /* */ - /* face_index :: See @FT_Open_Face for a detailed description of this */ - /* parameter. */ - /* */ - /* <Output> */ - /* aface :: A handle to a new face object. If `face_index' is */ - /* greater than or equal to zero, it must be non-NULL. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* You must not deallocate the memory before calling @FT_Done_Face. */ - /* */ + /************************************************************************** + * + * @function: + * FT_New_Memory_Face + * + * @description: + * Call @FT_Open_Face to open a font that has been loaded into memory. + * + * @inout: + * library :: + * A handle to the library resource. + * + * @input: + * file_base :: + * A pointer to the beginning of the font data. + * + * file_size :: + * The size of the memory chunk used by the font data. + * + * face_index :: + * See @FT_Open_Face for a detailed description of this parameter. + * + * @output: + * aface :: + * A handle to a new face object. If `face_index` is greater than or + * equal to zero, it must be non-`NULL`. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * You must not deallocate the memory before calling @FT_Done_Face. + */ FT_EXPORT( FT_Error ) FT_New_Memory_Face( FT_Library library, const FT_Byte* file_base, @@ -2219,147 +2206,143 @@ FT_BEGIN_HEADER FT_Face *aface ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Open_Face */ - /* */ - /* <Description> */ - /* Create a face object from a given resource described by */ - /* @FT_Open_Args. */ - /* */ - /* <InOut> */ - /* library :: A handle to the library resource. */ - /* */ - /* <Input> */ - /* args :: A pointer to an `FT_Open_Args' structure that must */ - /* be filled by the caller. */ - /* */ - /* face_index :: This field holds two different values. Bits 0-15 */ - /* are the index of the face in the font file (starting */ - /* with value~0). Set it to~0 if there is only one */ - /* face in the font file. */ - /* */ - /* [Since 2.6.1] Bits 16-30 are relevant to GX and */ - /* OpenType variation fonts only, specifying the named */ - /* instance index for the current face index (starting */ - /* with value~1; value~0 makes FreeType ignore named */ - /* instances). For non-variation fonts, bits 16-30 are */ - /* ignored. Assuming that you want to access the third */ - /* named instance in face~4, `face_index' should be set */ - /* to 0x00030004. If you want to access face~4 without */ - /* variation handling, simply set `face_index' to */ - /* value~4. */ - /* */ - /* `FT_Open_Face' and its siblings can be used to */ - /* quickly check whether the font format of a given */ - /* font resource is supported by FreeType. In general, */ - /* if the `face_index' argument is negative, the */ - /* function's return value is~0 if the font format is */ - /* recognized, or non-zero otherwise. The function */ - /* allocates a more or less empty face handle in */ - /* `*aface' (if `aface' isn't NULL); the only two */ - /* useful fields in this special case are */ - /* `face->num_faces' and `face->style_flags'. For any */ - /* negative value of `face_index', `face->num_faces' */ - /* gives the number of faces within the font file. For */ - /* the negative value `-(N+1)' (with `N' a non-negative */ - /* 16-bit value), bits 16-30 in `face->style_flags' */ - /* give the number of named instances in face `N' if we */ - /* have a variation font (or zero otherwise). After */ - /* examination, the returned @FT_Face structure should */ - /* be deallocated with a call to @FT_Done_Face. */ - /* */ - /* <Output> */ - /* aface :: A handle to a new face object. If `face_index' is */ - /* greater than or equal to zero, it must be non-NULL. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* Unlike FreeType 1.x, this function automatically creates a glyph */ - /* slot for the face object that can be accessed directly through */ - /* `face->glyph'. */ - /* */ - /* Each new face object created with this function also owns a */ - /* default @FT_Size object, accessible as `face->size'. */ - /* */ - /* One @FT_Library instance can have multiple face objects, this is, */ - /* @FT_Open_Face and its siblings can be called multiple times using */ - /* the same `library' argument. */ - /* */ - /* See the discussion of reference counters in the description of */ - /* @FT_Reference_Face. */ - /* */ - /* To loop over all faces, use code similar to the following snippet */ - /* (omitting the error handling). */ - /* */ - /* { */ - /* ... */ - /* FT_Face face; */ - /* FT_Long i, num_faces; */ - /* */ - /* */ - /* error = FT_Open_Face( library, args, -1, &face ); */ - /* if ( error ) { ... } */ - /* */ - /* num_faces = face->num_faces; */ - /* FT_Done_Face( face ); */ - /* */ - /* for ( i = 0; i < num_faces; i++ ) */ - /* { */ - /* ... */ - /* error = FT_Open_Face( library, args, i, &face ); */ - /* ... */ - /* FT_Done_Face( face ); */ - /* ... */ - /* } */ - /* } */ - /* */ - /* To loop over all valid values for `face_index', use something */ - /* similar to the following snippet, again without error handling. */ - /* The code accesses all faces immediately (thus only a single call */ - /* of `FT_Open_Face' within the do-loop), with and without named */ - /* instances. */ - /* */ - /* { */ - /* ... */ - /* FT_Face face; */ - /* */ - /* FT_Long num_faces = 0; */ - /* FT_Long num_instances = 0; */ - /* */ - /* FT_Long face_idx = 0; */ - /* FT_Long instance_idx = 0; */ - /* */ - /* */ - /* do */ - /* { */ - /* FT_Long id = ( instance_idx << 16 ) + face_idx; */ - /* */ - /* */ - /* error = FT_Open_Face( library, args, id, &face ); */ - /* if ( error ) { ... } */ - /* */ - /* num_faces = face->num_faces; */ - /* num_instances = face->style_flags >> 16; */ - /* */ - /* ... */ - /* */ - /* FT_Done_Face( face ); */ - /* */ - /* if ( instance_idx < num_instances ) */ - /* instance_idx++; */ - /* else */ - /* { */ - /* face_idx++; */ - /* instance_idx = 0; */ - /* } */ - /* */ - /* } while ( face_idx < num_faces ) */ - /* } */ - /* */ + /************************************************************************** + * + * @function: + * FT_Open_Face + * + * @description: + * Create a face object from a given resource described by @FT_Open_Args. + * + * @inout: + * library :: + * A handle to the library resource. + * + * @input: + * args :: + * A pointer to an `FT_Open_Args` structure that must be filled by the + * caller. + * + * face_index :: + * This field holds two different values. Bits 0-15 are the index of + * the face in the font file (starting with value~0). Set it to~0 if + * there is only one face in the font file. + * + * [Since 2.6.1] Bits 16-30 are relevant to GX and OpenType variation + * fonts only, specifying the named instance index for the current face + * index (starting with value~1; value~0 makes FreeType ignore named + * instances). For non-variation fonts, bits 16-30 are ignored. + * Assuming that you want to access the third named instance in face~4, + * `face_index` should be set to 0x00030004. If you want to access + * face~4 without variation handling, simply set `face_index` to + * value~4. + * + * `FT_Open_Face` and its siblings can be used to quickly check whether + * the font format of a given font resource is supported by FreeType. + * In general, if the `face_index` argument is negative, the function's + * return value is~0 if the font format is recognized, or non-zero + * otherwise. The function allocates a more or less empty face handle + * in `*aface` (if `aface` isn't `NULL`); the only two useful fields in + * this special case are `face->num_faces` and `face->style_flags`. + * For any negative value of `face_index`, `face->num_faces` gives the + * number of faces within the font file. For the negative value + * '-(N+1)' (with 'N' a non-negative 16-bit value), bits 16-30 in + * `face->style_flags` give the number of named instances in face 'N' + * if we have a variation font (or zero otherwise). After examination, + * the returned @FT_Face structure should be deallocated with a call to + * @FT_Done_Face. + * + * @output: + * aface :: + * A handle to a new face object. If `face_index` is greater than or + * equal to zero, it must be non-`NULL`. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * Unlike FreeType 1.x, this function automatically creates a glyph slot + * for the face object that can be accessed directly through + * `face->glyph`. + * + * Each new face object created with this function also owns a default + * @FT_Size object, accessible as `face->size`. + * + * One @FT_Library instance can have multiple face objects, this is, + * @FT_Open_Face and its siblings can be called multiple times using the + * same `library` argument. + * + * See the discussion of reference counters in the description of + * @FT_Reference_Face. + * + * @example: + * To loop over all faces, use code similar to the following snippet + * (omitting the error handling). + * + * ``` + * ... + * FT_Face face; + * FT_Long i, num_faces; + * + * + * error = FT_Open_Face( library, args, -1, &face ); + * if ( error ) { ... } + * + * num_faces = face->num_faces; + * FT_Done_Face( face ); + * + * for ( i = 0; i < num_faces; i++ ) + * { + * ... + * error = FT_Open_Face( library, args, i, &face ); + * ... + * FT_Done_Face( face ); + * ... + * } + * ``` + * + * To loop over all valid values for `face_index`, use something similar + * to the following snippet, again without error handling. The code + * accesses all faces immediately (thus only a single call of + * `FT_Open_Face` within the do-loop), with and without named instances. + * + * ``` + * ... + * FT_Face face; + * + * FT_Long num_faces = 0; + * FT_Long num_instances = 0; + * + * FT_Long face_idx = 0; + * FT_Long instance_idx = 0; + * + * + * do + * { + * FT_Long id = ( instance_idx << 16 ) + face_idx; + * + * + * error = FT_Open_Face( library, args, id, &face ); + * if ( error ) { ... } + * + * num_faces = face->num_faces; + * num_instances = face->style_flags >> 16; + * + * ... + * + * FT_Done_Face( face ); + * + * if ( instance_idx < num_instances ) + * instance_idx++; + * else + * { + * face_idx++; + * instance_idx = 0; + * } + * + * } while ( face_idx < num_faces ) + * ``` + */ FT_EXPORT( FT_Error ) FT_Open_Face( FT_Library library, const FT_Open_Args* args, @@ -2367,204 +2350,208 @@ FT_BEGIN_HEADER FT_Face *aface ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Attach_File */ - /* */ - /* <Description> */ - /* Call @FT_Attach_Stream to attach a file. */ - /* */ - /* <InOut> */ - /* face :: The target face object. */ - /* */ - /* <Input> */ - /* filepathname :: The pathname. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Attach_File + * + * @description: + * Call @FT_Attach_Stream to attach a file. + * + * @inout: + * face :: + * The target face object. + * + * @input: + * filepathname :: + * The pathname. + * + * @return: + * FreeType error code. 0~means success. + */ FT_EXPORT( FT_Error ) FT_Attach_File( FT_Face face, const char* filepathname ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Attach_Stream */ - /* */ - /* <Description> */ - /* `Attach' data to a face object. Normally, this is used to read */ - /* additional information for the face object. For example, you can */ - /* attach an AFM file that comes with a Type~1 font to get the */ - /* kerning values and other metrics. */ - /* */ - /* <InOut> */ - /* face :: The target face object. */ - /* */ - /* <Input> */ - /* parameters :: A pointer to @FT_Open_Args that must be filled by */ - /* the caller. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* The meaning of the `attach' (i.e., what really happens when the */ - /* new file is read) is not fixed by FreeType itself. It really */ - /* depends on the font format (and thus the font driver). */ - /* */ - /* Client applications are expected to know what they are doing */ - /* when invoking this function. Most drivers simply do not implement */ - /* file or stream attachments. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Attach_Stream + * + * @description: + * 'Attach' data to a face object. Normally, this is used to read + * additional information for the face object. For example, you can + * attach an AFM file that comes with a Type~1 font to get the kerning + * values and other metrics. + * + * @inout: + * face :: + * The target face object. + * + * @input: + * parameters :: + * A pointer to @FT_Open_Args that must be filled by the caller. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The meaning of the 'attach' (i.e., what really happens when the new + * file is read) is not fixed by FreeType itself. It really depends on + * the font format (and thus the font driver). + * + * Client applications are expected to know what they are doing when + * invoking this function. Most drivers simply do not implement file or + * stream attachments. + */ FT_EXPORT( FT_Error ) FT_Attach_Stream( FT_Face face, FT_Open_Args* parameters ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Reference_Face */ - /* */ - /* <Description> */ - /* A counter gets initialized to~1 at the time an @FT_Face structure */ - /* is created. This function increments the counter. @FT_Done_Face */ - /* then only destroys a face if the counter is~1, otherwise it simply */ - /* decrements the counter. */ - /* */ - /* This function helps in managing life-cycles of structures that */ - /* reference @FT_Face objects. */ - /* */ - /* <Input> */ - /* face :: A handle to a target face object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Since> */ - /* 2.4.2 */ - /* */ + /************************************************************************** + * + * @function: + * FT_Reference_Face + * + * @description: + * A counter gets initialized to~1 at the time an @FT_Face structure is + * created. This function increments the counter. @FT_Done_Face then + * only destroys a face if the counter is~1, otherwise it simply + * decrements the counter. + * + * This function helps in managing life-cycles of structures that + * reference @FT_Face objects. + * + * @input: + * face :: + * A handle to a target face object. + * + * @return: + * FreeType error code. 0~means success. + * + * @since: + * 2.4.2 + */ FT_EXPORT( FT_Error ) FT_Reference_Face( FT_Face face ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Done_Face */ - /* */ - /* <Description> */ - /* Discard a given face object, as well as all of its child slots and */ - /* sizes. */ - /* */ - /* <Input> */ - /* face :: A handle to a target face object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* See the discussion of reference counters in the description of */ - /* @FT_Reference_Face. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Done_Face + * + * @description: + * Discard a given face object, as well as all of its child slots and + * sizes. + * + * @input: + * face :: + * A handle to a target face object. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * See the discussion of reference counters in the description of + * @FT_Reference_Face. + */ FT_EXPORT( FT_Error ) FT_Done_Face( FT_Face face ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Select_Size */ - /* */ - /* <Description> */ - /* Select a bitmap strike. To be more precise, this function sets */ - /* the scaling factors of the active @FT_Size object in a face so */ - /* that bitmaps from this particular strike are taken by */ - /* @FT_Load_Glyph and friends. */ - /* */ - /* <InOut> */ - /* face :: A handle to a target face object. */ - /* */ - /* <Input> */ - /* strike_index :: The index of the bitmap strike in the */ - /* `available_sizes' field of @FT_FaceRec structure. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* For bitmaps embedded in outline fonts it is common that only a */ - /* subset of the available glyphs at a given ppem value is available. */ - /* FreeType silently uses outlines if there is no bitmap for a given */ - /* glyph index. */ - /* */ - /* For GX and OpenType variation fonts, a bitmap strike makes sense */ - /* only if the default instance is active (this is, no glyph */ - /* variation takes place); otherwise, FreeType simply ignores bitmap */ - /* strikes. The same is true for all named instances that are */ - /* different from the default instance. */ - /* */ - /* Don't use this function if you are using the FreeType cache API. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Select_Size + * + * @description: + * Select a bitmap strike. To be more precise, this function sets the + * scaling factors of the active @FT_Size object in a face so that + * bitmaps from this particular strike are taken by @FT_Load_Glyph and + * friends. + * + * @inout: + * face :: + * A handle to a target face object. + * + * @input: + * strike_index :: + * The index of the bitmap strike in the `available_sizes` field of + * @FT_FaceRec structure. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * For bitmaps embedded in outline fonts it is common that only a subset + * of the available glyphs at a given ppem value is available. FreeType + * silently uses outlines if there is no bitmap for a given glyph index. + * + * For GX and OpenType variation fonts, a bitmap strike makes sense only + * if the default instance is active (this is, no glyph variation takes + * place); otherwise, FreeType simply ignores bitmap strikes. The same + * is true for all named instances that are different from the default + * instance. + * + * Don't use this function if you are using the FreeType cache API. + */ FT_EXPORT( FT_Error ) FT_Select_Size( FT_Face face, FT_Int strike_index ); - /*************************************************************************/ - /* */ - /* <Enum> */ - /* FT_Size_Request_Type */ - /* */ - /* <Description> */ - /* An enumeration type that lists the supported size request types, */ - /* i.e., what input size (in font units) maps to the requested output */ - /* size (in pixels, as computed from the arguments of */ - /* @FT_Size_Request). */ - /* */ - /* <Values> */ - /* FT_SIZE_REQUEST_TYPE_NOMINAL :: */ - /* The nominal size. The `units_per_EM' field of @FT_FaceRec is */ - /* used to determine both scaling values. */ - /* */ - /* This is the standard scaling found in most applications. In */ - /* particular, use this size request type for TrueType fonts if */ - /* they provide optical scaling or something similar. Note, */ - /* however, that `units_per_EM' is a rather abstract value which */ - /* bears no relation to the actual size of the glyphs in a font. */ - /* */ - /* FT_SIZE_REQUEST_TYPE_REAL_DIM :: */ - /* The real dimension. The sum of the `ascender' and (minus of) */ - /* the `descender' fields of @FT_FaceRec is used to determine both */ - /* scaling values. */ - /* */ - /* FT_SIZE_REQUEST_TYPE_BBOX :: */ - /* The font bounding box. The width and height of the `bbox' field */ - /* of @FT_FaceRec are used to determine the horizontal and vertical */ - /* scaling value, respectively. */ - /* */ - /* FT_SIZE_REQUEST_TYPE_CELL :: */ - /* The `max_advance_width' field of @FT_FaceRec is used to */ - /* determine the horizontal scaling value; the vertical scaling */ - /* value is determined the same way as */ - /* @FT_SIZE_REQUEST_TYPE_REAL_DIM does. Finally, both scaling */ - /* values are set to the smaller one. This type is useful if you */ - /* want to specify the font size for, say, a window of a given */ - /* dimension and 80x24 cells. */ - /* */ - /* FT_SIZE_REQUEST_TYPE_SCALES :: */ - /* Specify the scaling values directly. */ - /* */ - /* <Note> */ - /* The above descriptions only apply to scalable formats. For bitmap */ - /* formats, the behaviour is up to the driver. */ - /* */ - /* See the note section of @FT_Size_Metrics if you wonder how size */ - /* requesting relates to scaling values. */ - /* */ + /************************************************************************** + * + * @enum: + * FT_Size_Request_Type + * + * @description: + * An enumeration type that lists the supported size request types, i.e., + * what input size (in font units) maps to the requested output size (in + * pixels, as computed from the arguments of @FT_Size_Request). + * + * @values: + * FT_SIZE_REQUEST_TYPE_NOMINAL :: + * The nominal size. The `units_per_EM` field of @FT_FaceRec is used + * to determine both scaling values. + * + * This is the standard scaling found in most applications. In + * particular, use this size request type for TrueType fonts if they + * provide optical scaling or something similar. Note, however, that + * `units_per_EM` is a rather abstract value which bears no relation to + * the actual size of the glyphs in a font. + * + * FT_SIZE_REQUEST_TYPE_REAL_DIM :: + * The real dimension. The sum of the `ascender` and (minus of) the + * `descender` fields of @FT_FaceRec is used to determine both scaling + * values. + * + * FT_SIZE_REQUEST_TYPE_BBOX :: + * The font bounding box. The width and height of the `bbox` field of + * @FT_FaceRec are used to determine the horizontal and vertical + * scaling value, respectively. + * + * FT_SIZE_REQUEST_TYPE_CELL :: + * The `max_advance_width` field of @FT_FaceRec is used to determine + * the horizontal scaling value; the vertical scaling value is + * determined the same way as @FT_SIZE_REQUEST_TYPE_REAL_DIM does. + * Finally, both scaling values are set to the smaller one. This type + * is useful if you want to specify the font size for, say, a window of + * a given dimension and 80x24 cells. + * + * FT_SIZE_REQUEST_TYPE_SCALES :: + * Specify the scaling values directly. + * + * @note: + * The above descriptions only apply to scalable formats. For bitmap + * formats, the behaviour is up to the driver. + * + * See the note section of @FT_Size_Metrics if you wonder how size + * requesting relates to scaling values. + */ typedef enum FT_Size_Request_Type_ { FT_SIZE_REQUEST_TYPE_NOMINAL, @@ -2578,42 +2565,45 @@ FT_BEGIN_HEADER } FT_Size_Request_Type; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Size_RequestRec */ - /* */ - /* <Description> */ - /* A structure to model a size request. */ - /* */ - /* <Fields> */ - /* type :: See @FT_Size_Request_Type. */ - /* */ - /* width :: The desired width, given as a 26.6 fractional */ - /* point value (with 72pt = 1in). */ - /* */ - /* height :: The desired height, given as a 26.6 fractional */ - /* point value (with 72pt = 1in). */ - /* */ - /* horiResolution :: The horizontal resolution (dpi, i.e., pixels per */ - /* inch). If set to zero, `width' is treated as a */ - /* 26.6 fractional *pixel* value, which gets */ - /* internally rounded to an integer. */ - /* */ - /* vertResolution :: The vertical resolution (dpi, i.e., pixels per */ - /* inch). If set to zero, `height' is treated as a */ - /* 26.6 fractional *pixel* value, which gets */ - /* internally rounded to an integer. */ - /* */ - /* <Note> */ - /* If `width' is zero, the horizontal scaling value is set equal */ - /* to the vertical scaling value, and vice versa. */ - /* */ - /* If `type' is FT_SIZE_REQUEST_TYPE_SCALES, `width' and `height' are */ - /* interpreted directly as 16.16 fractional scaling values, without */ - /* any further modification, and both `horiResolution' and */ - /* `vertResolution' are ignored. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_Size_RequestRec + * + * @description: + * A structure to model a size request. + * + * @fields: + * type :: + * See @FT_Size_Request_Type. + * + * width :: + * The desired width, given as a 26.6 fractional point value (with 72pt + * = 1in). + * + * height :: + * The desired height, given as a 26.6 fractional point value (with + * 72pt = 1in). + * + * horiResolution :: + * The horizontal resolution (dpi, i.e., pixels per inch). If set to + * zero, `width` is treated as a 26.6 fractional **pixel** value, which + * gets internally rounded to an integer. + * + * vertResolution :: + * The vertical resolution (dpi, i.e., pixels per inch). If set to + * zero, `height` is treated as a 26.6 fractional **pixel** value, + * which gets internally rounded to an integer. + * + * @note: + * If `width` is zero, the horizontal scaling value is set equal to the + * vertical scaling value, and vice versa. + * + * If `type` is `FT_SIZE_REQUEST_TYPE_SCALES`, `width` and `height` are + * interpreted directly as 16.16 fractional scaling values, without any + * further modification, and both `horiResolution` and `vertResolution` + * are ignored. + */ typedef struct FT_Size_RequestRec_ { FT_Size_Request_Type type; @@ -2625,96 +2615,102 @@ FT_BEGIN_HEADER } FT_Size_RequestRec; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Size_Request */ - /* */ - /* <Description> */ - /* A handle to a size request structure. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_Size_Request + * + * @description: + * A handle to a size request structure. + */ typedef struct FT_Size_RequestRec_ *FT_Size_Request; - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Request_Size */ - /* */ - /* <Description> */ - /* Resize the scale of the active @FT_Size object in a face. */ - /* */ - /* <InOut> */ - /* face :: A handle to a target face object. */ - /* */ - /* <Input> */ - /* req :: A pointer to a @FT_Size_RequestRec. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* Although drivers may select the bitmap strike matching the */ - /* request, you should not rely on this if you intend to select a */ - /* particular bitmap strike. Use @FT_Select_Size instead in that */ - /* case. */ - /* */ - /* The relation between the requested size and the resulting glyph */ - /* size is dependent entirely on how the size is defined in the */ - /* source face. The font designer chooses the final size of each */ - /* glyph relative to this size. For more information refer to */ - /* `https://www.freetype.org/freetype2/docs/glyphs/glyphs-2.html'. */ - /* */ - /* Contrary to @FT_Set_Char_Size, this function doesn't have special */ - /* code to normalize zero-valued widths, heights, or resolutions */ - /* (which lead to errors in most cases). */ - /* */ - /* Don't use this function if you are using the FreeType cache API. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Request_Size + * + * @description: + * Resize the scale of the active @FT_Size object in a face. + * + * @inout: + * face :: + * A handle to a target face object. + * + * @input: + * req :: + * A pointer to a @FT_Size_RequestRec. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * Although drivers may select the bitmap strike matching the request, + * you should not rely on this if you intend to select a particular + * bitmap strike. Use @FT_Select_Size instead in that case. + * + * The relation between the requested size and the resulting glyph size + * is dependent entirely on how the size is defined in the source face. + * The font designer chooses the final size of each glyph relative to + * this size. For more information refer to + * 'https://www.freetype.org/freetype2/docs/glyphs/glyphs-2.html'. + * + * Contrary to @FT_Set_Char_Size, this function doesn't have special code + * to normalize zero-valued widths, heights, or resolutions (which lead + * to errors in most cases). + * + * Don't use this function if you are using the FreeType cache API. + */ FT_EXPORT( FT_Error ) FT_Request_Size( FT_Face face, FT_Size_Request req ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Set_Char_Size */ - /* */ - /* <Description> */ - /* Call @FT_Request_Size to request the nominal size (in points). */ - /* */ - /* <InOut> */ - /* face :: A handle to a target face object. */ - /* */ - /* <Input> */ - /* char_width :: The nominal width, in 26.6 fractional points. */ - /* */ - /* char_height :: The nominal height, in 26.6 fractional points. */ - /* */ - /* horz_resolution :: The horizontal resolution in dpi. */ - /* */ - /* vert_resolution :: The vertical resolution in dpi. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* While this function allows fractional points as input values, the */ - /* resulting ppem value for the given resolution is always rounded to */ - /* the nearest integer. */ - /* */ - /* If either the character width or height is zero, it is set equal */ - /* to the other value. */ - /* */ - /* If either the horizontal or vertical resolution is zero, it is set */ - /* equal to the other value. */ - /* */ - /* A character width or height smaller than 1pt is set to 1pt; if */ - /* both resolution values are zero, they are set to 72dpi. */ - /* */ - /* Don't use this function if you are using the FreeType cache API. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Set_Char_Size + * + * @description: + * Call @FT_Request_Size to request the nominal size (in points). + * + * @inout: + * face :: + * A handle to a target face object. + * + * @input: + * char_width :: + * The nominal width, in 26.6 fractional points. + * + * char_height :: + * The nominal height, in 26.6 fractional points. + * + * horz_resolution :: + * The horizontal resolution in dpi. + * + * vert_resolution :: + * The vertical resolution in dpi. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * While this function allows fractional points as input values, the + * resulting ppem value for the given resolution is always rounded to the + * nearest integer. + * + * If either the character width or height is zero, it is set equal to + * the other value. + * + * If either the horizontal or vertical resolution is zero, it is set + * equal to the other value. + * + * A character width or height smaller than 1pt is set to 1pt; if both + * resolution values are zero, they are set to 72dpi. + * + * Don't use this function if you are using the FreeType cache API. + */ FT_EXPORT( FT_Error ) FT_Set_Char_Size( FT_Face face, FT_F26Dot6 char_width, @@ -2723,130 +2719,138 @@ FT_BEGIN_HEADER FT_UInt vert_resolution ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Set_Pixel_Sizes */ - /* */ - /* <Description> */ - /* Call @FT_Request_Size to request the nominal size (in pixels). */ - /* */ - /* <InOut> */ - /* face :: A handle to the target face object. */ - /* */ - /* <Input> */ - /* pixel_width :: The nominal width, in pixels. */ - /* */ - /* pixel_height :: The nominal height, in pixels. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* You should not rely on the resulting glyphs matching or being */ - /* constrained to this pixel size. Refer to @FT_Request_Size to */ - /* understand how requested sizes relate to actual sizes. */ - /* */ - /* Don't use this function if you are using the FreeType cache API. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Set_Pixel_Sizes + * + * @description: + * Call @FT_Request_Size to request the nominal size (in pixels). + * + * @inout: + * face :: + * A handle to the target face object. + * + * @input: + * pixel_width :: + * The nominal width, in pixels. + * + * pixel_height :: + * The nominal height, in pixels. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * You should not rely on the resulting glyphs matching or being + * constrained to this pixel size. Refer to @FT_Request_Size to + * understand how requested sizes relate to actual sizes. + * + * Don't use this function if you are using the FreeType cache API. + */ FT_EXPORT( FT_Error ) FT_Set_Pixel_Sizes( FT_Face face, FT_UInt pixel_width, FT_UInt pixel_height ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Load_Glyph */ - /* */ - /* <Description> */ - /* Load a glyph into the glyph slot of a face object. */ - /* */ - /* <InOut> */ - /* face :: A handle to the target face object where the glyph */ - /* is loaded. */ - /* */ - /* <Input> */ - /* glyph_index :: The index of the glyph in the font file. For */ - /* CID-keyed fonts (either in PS or in CFF format) */ - /* this argument specifies the CID value. */ - /* */ - /* load_flags :: A flag indicating what to load for this glyph. The */ - /* @FT_LOAD_XXX constants can be used to control the */ - /* glyph loading process (e.g., whether the outline */ - /* should be scaled, whether to load bitmaps or not, */ - /* whether to hint the outline, etc). */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* The loaded glyph may be transformed. See @FT_Set_Transform for */ - /* the details. */ - /* */ - /* For subsetted CID-keyed fonts, `FT_Err_Invalid_Argument' is */ - /* returned for invalid CID values (this is, for CID values that */ - /* don't have a corresponding glyph in the font). See the discussion */ - /* of the @FT_FACE_FLAG_CID_KEYED flag for more details. */ - /* */ - /* If you receive `FT_Err_Glyph_Too_Big', try getting the glyph */ - /* outline at EM size, then scale it manually and fill it as a */ - /* graphics operation. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Load_Glyph + * + * @description: + * Load a glyph into the glyph slot of a face object. + * + * @inout: + * face :: + * A handle to the target face object where the glyph is loaded. + * + * @input: + * glyph_index :: + * The index of the glyph in the font file. For CID-keyed fonts + * (either in PS or in CFF format) this argument specifies the CID + * value. + * + * load_flags :: + * A flag indicating what to load for this glyph. The @FT_LOAD_XXX + * constants can be used to control the glyph loading process (e.g., + * whether the outline should be scaled, whether to load bitmaps or + * not, whether to hint the outline, etc). + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The loaded glyph may be transformed. See @FT_Set_Transform for the + * details. + * + * For subsetted CID-keyed fonts, `FT_Err_Invalid_Argument` is returned + * for invalid CID values (this is, for CID values that don't have a + * corresponding glyph in the font). See the discussion of the + * @FT_FACE_FLAG_CID_KEYED flag for more details. + * + * If you receive `FT_Err_Glyph_Too_Big`, try getting the glyph outline + * at EM size, then scale it manually and fill it as a graphics + * operation. + */ FT_EXPORT( FT_Error ) FT_Load_Glyph( FT_Face face, FT_UInt glyph_index, FT_Int32 load_flags ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Load_Char */ - /* */ - /* <Description> */ - /* Load a glyph into the glyph slot of a face object, accessed by its */ - /* character code. */ - /* */ - /* <InOut> */ - /* face :: A handle to a target face object where the glyph */ - /* is loaded. */ - /* */ - /* <Input> */ - /* char_code :: The glyph's character code, according to the */ - /* current charmap used in the face. */ - /* */ - /* load_flags :: A flag indicating what to load for this glyph. The */ - /* @FT_LOAD_XXX constants can be used to control the */ - /* glyph loading process (e.g., whether the outline */ - /* should be scaled, whether to load bitmaps or not, */ - /* whether to hint the outline, etc). */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* This function simply calls @FT_Get_Char_Index and @FT_Load_Glyph. */ - /* */ - /* Many fonts contain glyphs that can't be loaded by this function */ - /* since its glyph indices are not listed in any of the font's */ - /* charmaps. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Load_Char + * + * @description: + * Load a glyph into the glyph slot of a face object, accessed by its + * character code. + * + * @inout: + * face :: + * A handle to a target face object where the glyph is loaded. + * + * @input: + * char_code :: + * The glyph's character code, according to the current charmap used in + * the face. + * + * load_flags :: + * A flag indicating what to load for this glyph. The @FT_LOAD_XXX + * constants can be used to control the glyph loading process (e.g., + * whether the outline should be scaled, whether to load bitmaps or + * not, whether to hint the outline, etc). + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function simply calls @FT_Get_Char_Index and @FT_Load_Glyph. + * + * Many fonts contain glyphs that can't be loaded by this function since + * its glyph indices are not listed in any of the font's charmaps. + * + * If no active cmap is set up (i.e., `face->charmap` is zero), the call + * to @FT_Get_Char_Index is omitted, and the function behaves identically + * to @FT_Load_Glyph. + */ FT_EXPORT( FT_Error ) FT_Load_Char( FT_Face face, FT_ULong char_code, FT_Int32 load_flags ); - /************************************************************************* + /************************************************************************** * * @enum: * FT_LOAD_XXX * * @description: - * A list of bit field constants for @FT_Load_Glyph to indicate what - * kind of operations to perform during glyph loading. + * A list of bit field constants for @FT_Load_Glyph to indicate what kind + * of operations to perform during glyph loading. * * @values: * FT_LOAD_DEFAULT :: @@ -2854,15 +2858,14 @@ FT_BEGIN_HEADER * operation. In this case, the following happens: * * 1. FreeType looks for a bitmap for the glyph corresponding to the - * face's current size. If one is found, the function returns. - * The bitmap data can be accessed from the glyph slot (see note - * below). + * face's current size. If one is found, the function returns. The + * bitmap data can be accessed from the glyph slot (see note below). * * 2. If no embedded bitmap is searched for or found, FreeType looks - * for a scalable outline. If one is found, it is loaded from - * the font file, scaled to device pixels, then `hinted' to the - * pixel grid in order to optimize it. The outline data can be - * accessed from the glyph slot (see note below). + * for a scalable outline. If one is found, it is loaded from the font + * file, scaled to device pixels, then 'hinted' to the pixel grid in + * order to optimize it. The outline data can be accessed from the + * glyph slot (see note below). * * Note that by default the glyph loader doesn't render outlines into * bitmaps. The following flags are used to modify this default @@ -2874,14 +2877,14 @@ FT_BEGIN_HEADER * This flag implies @FT_LOAD_NO_HINTING and @FT_LOAD_NO_BITMAP, and * unsets @FT_LOAD_RENDER. * - * If the font is `tricky' (see @FT_FACE_FLAG_TRICKY for more), using - * FT_LOAD_NO_SCALE usually yields meaningless outlines because the - * subglyphs must be scaled and positioned with hinting instructions. - * This can be solved by loading the font without FT_LOAD_NO_SCALE and - * setting the character size to `font->units_per_EM'. + * If the font is 'tricky' (see @FT_FACE_FLAG_TRICKY for more), using + * `FT_LOAD_NO_SCALE` usually yields meaningless outlines because the + * subglyphs must be scaled and positioned with hinting instructions. + * This can be solved by loading the font without `FT_LOAD_NO_SCALE` + * and setting the character size to `font->units_per_EM`. * * FT_LOAD_NO_HINTING :: - * Disable hinting. This generally generates `blurrier' bitmap glyphs + * Disable hinting. This generally generates 'blurrier' bitmap glyphs * when the glyph are rendered in any of the anti-aliased modes. See * also the note below. * @@ -2902,34 +2905,37 @@ FT_BEGIN_HEADER * * FT_LOAD_VERTICAL_LAYOUT :: * Load the glyph for vertical text layout. In particular, the - * `advance' value in the @FT_GlyphSlotRec structure is set to the - * `vertAdvance' value of the `metrics' field. + * `advance` value in the @FT_GlyphSlotRec structure is set to the + * `vertAdvance` value of the `metrics` field. * - * In case @FT_HAS_VERTICAL doesn't return true, you shouldn't use - * this flag currently. Reason is that in this case vertical metrics - * get synthesized, and those values are not always consistent across + * In case @FT_HAS_VERTICAL doesn't return true, you shouldn't use this + * flag currently. Reason is that in this case vertical metrics get + * synthesized, and those values are not always consistent across * various font formats. * * FT_LOAD_FORCE_AUTOHINT :: - * Prefer the auto-hinter over the font's native hinter. See also - * the note below. + * Prefer the auto-hinter over the font's native hinter. See also the + * note below. * * FT_LOAD_PEDANTIC :: * Make the font driver perform pedantic verifications during glyph - * loading. This is mostly used to detect broken glyphs in fonts. - * By default, FreeType tries to handle broken fonts also. + * loading and hinting. This is mostly used to detect broken glyphs in + * fonts. By default, FreeType tries to handle broken fonts also. * * In particular, errors from the TrueType bytecode engine are not - * passed to the application if this flag is not set; this might - * result in partially hinted or distorted glyphs in case a glyph's - * bytecode is buggy. + * passed to the application if this flag is not set; this might result + * in partially hinted or distorted glyphs in case a glyph's bytecode + * is buggy. * * FT_LOAD_NO_RECURSE :: - * Don't load composite glyphs recursively. Instead, the font - * driver should set the `num_subglyph' and `subglyphs' values of - * the glyph slot accordingly, and set `glyph->format' to - * @FT_GLYPH_FORMAT_COMPOSITE. The description of subglyphs can - * then be accessed with @FT_Get_SubGlyph_Info. + * Don't load composite glyphs recursively. Instead, the font driver + * fills the `num_subglyph` and `subglyphs` values of the glyph slot; + * it also sets `glyph->format` to @FT_GLYPH_FORMAT_COMPOSITE. The + * description of subglyphs can then be accessed with + * @FT_Get_SubGlyph_Info. + * + * Don't use this flag for retrieving metrics information since some + * font drivers only return rudimentary data. * * This flag implies @FT_LOAD_NO_SCALE and @FT_LOAD_IGNORE_TRANSFORM. * @@ -2946,23 +2952,35 @@ FT_BEGIN_HEADER * monochrome-optimized hinting algorithm is used. * * FT_LOAD_LINEAR_DESIGN :: - * Keep `linearHoriAdvance' and `linearVertAdvance' fields of - * @FT_GlyphSlotRec in font units. See @FT_GlyphSlotRec for - * details. + * Keep `linearHoriAdvance` and `linearVertAdvance` fields of + * @FT_GlyphSlotRec in font units. See @FT_GlyphSlotRec for details. * * FT_LOAD_NO_AUTOHINT :: * Disable the auto-hinter. See also the note below. * * FT_LOAD_COLOR :: + * Load colored glyphs. There are slight differences depending on the + * font format. + * * [Since 2.5] Load embedded color bitmap images. The resulting color - * bitmaps, if available, will have the @FT_PIXEL_MODE_BGRA format. - * If the flag is not set and color bitmaps are found, they are - * converted to 256-level gray bitmaps transparently, using the - * @FT_PIXEL_MODE_GRAY format. + * bitmaps, if available, will have the @FT_PIXEL_MODE_BGRA format, + * with pre-multiplied color channels. If the flag is not set and + * color bitmaps are found, they are converted to 256-level gray + * bitmaps, using the @FT_PIXEL_MODE_GRAY format. + * + * [Since 2.10, experimental] If the glyph index contains an entry in + * the face's 'COLR' table with a 'CPAL' palette table (as defined in + * the OpenType specification), make @FT_Render_Glyph provide a default + * blending of the color glyph layers associated with the glyph index, + * using the same bitmap format as embedded color bitmap images. This + * is mainly for convenience; for full control of color layers use + * @FT_Get_Color_Glyph_Layer and FreeType's color functions like + * @FT_Palette_Select instead of setting @FT_LOAD_COLOR for rendering + * so that the client application can handle blending by itself. * * FT_LOAD_COMPUTE_METRICS :: - * [Since 2.6.1] Compute glyph metrics from the glyph data, without - * the use of bundled metrics tables (for example, the `hdmx' table in + * [Since 2.6.1] Compute glyph metrics from the glyph data, without the + * use of bundled metrics tables (for example, the 'hdmx' table in * TrueType fonts). This flag is mainly used by font validating or * font editing applications, which need to ignore, verify, or edit * those tables. @@ -2971,9 +2989,9 @@ FT_BEGIN_HEADER * * FT_LOAD_BITMAP_METRICS_ONLY :: * [Since 2.7.1] Request loading of the metrics and bitmap image - * information of a (possibly embedded) bitmap glyph without - * allocating or copying the bitmap image data itself. No effect if - * the target glyph is not a bitmap image. + * information of a (possibly embedded) bitmap glyph without allocating + * or copying the bitmap image data itself. No effect if the target + * glyph is not a bitmap image. * * This flag unsets @FT_LOAD_RENDER. * @@ -2988,8 +3006,8 @@ FT_BEGIN_HEADER * @FT_FACE_FLAG_HINTER) is preferred over the auto-hinter. You can * disable hinting by setting @FT_LOAD_NO_HINTING or change the * precedence by setting @FT_LOAD_FORCE_AUTOHINT. You can also set - * @FT_LOAD_NO_AUTOHINT in case you don't want the auto-hinter to be - * used at all. + * @FT_LOAD_NO_AUTOHINT in case you don't want the auto-hinter to be used + * at all. * * See the description of @FT_FACE_FLAG_TRICKY for a special exception * (affecting only a handful of Asian fonts). @@ -3000,7 +3018,7 @@ FT_BEGIN_HEADER * Note that the auto-hinter needs a valid Unicode cmap (either a native * one or synthesized by FreeType) for producing correct results. If a * font provides an incorrect mapping (for example, assigning the - * character code U+005A, LATIN CAPITAL LETTER Z, to a glyph depicting a + * character code U+005A, LATIN CAPITAL LETTER~Z, to a glyph depicting a * mathematical integral sign), the auto-hinter might produce useless * results. * @@ -3020,7 +3038,7 @@ FT_BEGIN_HEADER #define FT_LOAD_MONOCHROME ( 1L << 12 ) #define FT_LOAD_LINEAR_DESIGN ( 1L << 13 ) #define FT_LOAD_NO_AUTOHINT ( 1L << 15 ) - /* Bits 16-19 are used by `FT_LOAD_TARGET_' */ + /* Bits 16-19 are used by `FT_LOAD_TARGET_` */ #define FT_LOAD_COLOR ( 1L << 20 ) #define FT_LOAD_COMPUTE_METRICS ( 1L << 21 ) #define FT_LOAD_BITMAP_METRICS_ONLY ( 1L << 22 ) @@ -3039,19 +3057,17 @@ FT_BEGIN_HEADER * * @description: * A list of values to select a specific hinting algorithm for the - * hinter. You should OR one of these values to your `load_flags' - * when calling @FT_Load_Glyph. + * hinter. You should OR one of these values to your `load_flags` when + * calling @FT_Load_Glyph. * - * Note that a font's native hinters may ignore the hinting algorithm - * you have specified (e.g., the TrueType bytecode interpreter). You - * can set @FT_LOAD_FORCE_AUTOHINT to ensure that the auto-hinter is - * used. + * Note that a font's native hinters may ignore the hinting algorithm you + * have specified (e.g., the TrueType bytecode interpreter). You can set + * @FT_LOAD_FORCE_AUTOHINT to ensure that the auto-hinter is used. * * @values: * FT_LOAD_TARGET_NORMAL :: * The default hinting algorithm, optimized for standard gray-level - * rendering. For monochrome output, use @FT_LOAD_TARGET_MONO - * instead. + * rendering. For monochrome output, use @FT_LOAD_TARGET_MONO instead. * * FT_LOAD_TARGET_LIGHT :: * A lighter hinting algorithm for gray-level modes. Many generated @@ -3064,13 +3080,13 @@ FT_BEGIN_HEADER * auto-hinter. * * Advance widths are rounded to integer values; however, using the - * `lsb_delta' and `rsb_delta' fields of @FT_GlyphSlotRec, it is - * possible to get fractional advance widths for sub-pixel positioning + * `lsb_delta` and `rsb_delta` fields of @FT_GlyphSlotRec, it is + * possible to get fractional advance widths for subpixel positioning * (which is recommended to use). * - * If configuration option AF_CONFIG_OPTION_TT_SIZE_METRICS is active, - * TrueType-like metrics are used to make this mode behave similarly - * as in unpatched FreeType versions between 2.4.6 and 2.7.1 + * If configuration option `AF_CONFIG_OPTION_TT_SIZE_METRICS` is + * active, TrueType-like metrics are used to make this mode behave + * similarly as in unpatched FreeType versions between 2.4.6 and 2.7.1 * (inclusive). * * FT_LOAD_TARGET_MONO :: @@ -3078,6 +3094,12 @@ FT_BEGIN_HEADER * output. The result is probably unpleasant if the glyph is rendered * in non-monochrome modes. * + * Note that for outline fonts only the TrueType font driver has proper + * monochrome hinting support, provided the TTFs contain hints for B/W + * rendering (which most fonts no longer provide). If these conditions + * are not met it is very likely that you get ugly results at smaller + * sizes. + * * FT_LOAD_TARGET_LCD :: * A variant of @FT_LOAD_TARGET_LIGHT optimized for horizontally * decimated LCD displays. @@ -3087,25 +3109,25 @@ FT_BEGIN_HEADER * decimated LCD displays. * * @note: - * You should use only _one_ of the FT_LOAD_TARGET_XXX values in your - * `load_flags'. They can't be ORed. + * You should use only _one_ of the `FT_LOAD_TARGET_XXX` values in your + * `load_flags`. They can't be ORed. * * If @FT_LOAD_RENDER is also set, the glyph is rendered in the * corresponding mode (i.e., the mode that matches the used algorithm - * best). An exception is FT_LOAD_TARGET_MONO since it implies + * best). An exception is `FT_LOAD_TARGET_MONO` since it implies * @FT_LOAD_MONOCHROME. * * You can use a hinting algorithm that doesn't correspond to the same - * rendering mode. As an example, it is possible to use the `light' + * rendering mode. As an example, it is possible to use the 'light' * hinting algorithm and have the results rendered in horizontal LCD * pixel mode, with code like * - * { - * FT_Load_Glyph( face, glyph_index, - * load_flags | FT_LOAD_TARGET_LIGHT ); + * ``` + * FT_Load_Glyph( face, glyph_index, + * load_flags | FT_LOAD_TARGET_LIGHT ); * - * FT_Render_Glyph( face->glyph, FT_RENDER_MODE_LCD ); - * } + * FT_Render_Glyph( face->glyph, FT_RENDER_MODE_LCD ); + * ``` * * In general, you should stick with one rendering mode. For example, * switching between @FT_LOAD_TARGET_NORMAL and @FT_LOAD_TARGET_MONO @@ -3137,98 +3159,98 @@ FT_BEGIN_HEADER #define FT_LOAD_TARGET_MODE( x ) ( (FT_Render_Mode)( ( (x) >> 16 ) & 15 ) ) - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Set_Transform */ - /* */ - /* <Description> */ - /* Set the transformation that is applied to glyph images when they */ - /* are loaded into a glyph slot through @FT_Load_Glyph. */ - /* */ - /* <InOut> */ - /* face :: A handle to the source face object. */ - /* */ - /* <Input> */ - /* matrix :: A pointer to the transformation's 2x2 matrix. Use NULL */ - /* for the identity matrix. */ - /* delta :: A pointer to the translation vector. Use NULL for the */ - /* null vector. */ - /* */ - /* <Note> */ - /* The transformation is only applied to scalable image formats after */ - /* the glyph has been loaded. It means that hinting is unaltered by */ - /* the transformation and is performed on the character size given in */ - /* the last call to @FT_Set_Char_Size or @FT_Set_Pixel_Sizes. */ - /* */ - /* Note that this also transforms the `face.glyph.advance' field, but */ - /* *not* the values in `face.glyph.metrics'. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Set_Transform + * + * @description: + * Set the transformation that is applied to glyph images when they are + * loaded into a glyph slot through @FT_Load_Glyph. + * + * @inout: + * face :: + * A handle to the source face object. + * + * @input: + * matrix :: + * A pointer to the transformation's 2x2 matrix. Use `NULL` for the + * identity matrix. + * delta :: + * A pointer to the translation vector. Use `NULL` for the null vector. + * + * @note: + * The transformation is only applied to scalable image formats after the + * glyph has been loaded. It means that hinting is unaltered by the + * transformation and is performed on the character size given in the + * last call to @FT_Set_Char_Size or @FT_Set_Pixel_Sizes. + * + * Note that this also transforms the `face.glyph.advance` field, but + * **not** the values in `face.glyph.metrics`. + */ FT_EXPORT( void ) FT_Set_Transform( FT_Face face, FT_Matrix* matrix, FT_Vector* delta ); - /*************************************************************************/ - /* */ - /* <Enum> */ - /* FT_Render_Mode */ - /* */ - /* <Description> */ - /* Render modes supported by FreeType~2. Each mode corresponds to a */ - /* specific type of scanline conversion performed on the outline. */ - /* */ - /* For bitmap fonts and embedded bitmaps the `bitmap->pixel_mode' */ - /* field in the @FT_GlyphSlotRec structure gives the format of the */ - /* returned bitmap. */ - /* */ - /* All modes except @FT_RENDER_MODE_MONO use 256 levels of opacity, */ - /* indicating pixel coverage. Use linear alpha blending and gamma */ - /* correction to correctly render non-monochrome glyph bitmaps onto a */ - /* surface; see @FT_Render_Glyph. */ - /* */ - /* <Values> */ - /* FT_RENDER_MODE_NORMAL :: */ - /* Default render mode; it corresponds to 8-bit anti-aliased */ - /* bitmaps. */ - /* */ - /* FT_RENDER_MODE_LIGHT :: */ - /* This is equivalent to @FT_RENDER_MODE_NORMAL. It is only */ - /* defined as a separate value because render modes are also used */ - /* indirectly to define hinting algorithm selectors. See */ - /* @FT_LOAD_TARGET_XXX for details. */ - /* */ - /* FT_RENDER_MODE_MONO :: */ - /* This mode corresponds to 1-bit bitmaps (with 2~levels of */ - /* opacity). */ - /* */ - /* FT_RENDER_MODE_LCD :: */ - /* This mode corresponds to horizontal RGB and BGR sub-pixel */ - /* displays like LCD screens. It produces 8-bit bitmaps that are */ - /* 3~times the width of the original glyph outline in pixels, and */ - /* which use the @FT_PIXEL_MODE_LCD mode. */ - /* */ - /* FT_RENDER_MODE_LCD_V :: */ - /* This mode corresponds to vertical RGB and BGR sub-pixel displays */ - /* (like PDA screens, rotated LCD displays, etc.). It produces */ - /* 8-bit bitmaps that are 3~times the height of the original */ - /* glyph outline in pixels and use the @FT_PIXEL_MODE_LCD_V mode. */ - /* */ - /* <Note> */ - /* Should you define FT_CONFIG_OPTION_SUBPIXEL_RENDERING in your */ - /* `ftoption.h', which enables patented ClearType-style rendering, */ - /* the LCD-optimized glyph bitmaps should be filtered to reduce color */ - /* fringes inherent to this technology. You can either set up LCD */ - /* filtering with @FT_Library_SetLcdFilter or @FT_Face_Properties, */ - /* or do the filtering yourself. The default FreeType LCD rendering */ - /* technology does not require filtering. */ - /* */ - /* The selected render mode only affects vector glyphs of a font. */ - /* Embedded bitmaps often have a different pixel mode like */ - /* @FT_PIXEL_MODE_MONO. You can use @FT_Bitmap_Convert to transform */ - /* them into 8-bit pixmaps. */ - /* */ + /************************************************************************** + * + * @enum: + * FT_Render_Mode + * + * @description: + * Render modes supported by FreeType~2. Each mode corresponds to a + * specific type of scanline conversion performed on the outline. + * + * For bitmap fonts and embedded bitmaps the `bitmap->pixel_mode` field + * in the @FT_GlyphSlotRec structure gives the format of the returned + * bitmap. + * + * All modes except @FT_RENDER_MODE_MONO use 256 levels of opacity, + * indicating pixel coverage. Use linear alpha blending and gamma + * correction to correctly render non-monochrome glyph bitmaps onto a + * surface; see @FT_Render_Glyph. + * + * @values: + * FT_RENDER_MODE_NORMAL :: + * Default render mode; it corresponds to 8-bit anti-aliased bitmaps. + * + * FT_RENDER_MODE_LIGHT :: + * This is equivalent to @FT_RENDER_MODE_NORMAL. It is only defined as + * a separate value because render modes are also used indirectly to + * define hinting algorithm selectors. See @FT_LOAD_TARGET_XXX for + * details. + * + * FT_RENDER_MODE_MONO :: + * This mode corresponds to 1-bit bitmaps (with 2~levels of opacity). + * + * FT_RENDER_MODE_LCD :: + * This mode corresponds to horizontal RGB and BGR subpixel displays + * like LCD screens. It produces 8-bit bitmaps that are 3~times the + * width of the original glyph outline in pixels, and which use the + * @FT_PIXEL_MODE_LCD mode. + * + * FT_RENDER_MODE_LCD_V :: + * This mode corresponds to vertical RGB and BGR subpixel displays + * (like PDA screens, rotated LCD displays, etc.). It produces 8-bit + * bitmaps that are 3~times the height of the original glyph outline in + * pixels and use the @FT_PIXEL_MODE_LCD_V mode. + * + * @note: + * Should you define `FT_CONFIG_OPTION_SUBPIXEL_RENDERING` in your + * `ftoption.h`, which enables patented ClearType-style rendering, the + * LCD-optimized glyph bitmaps should be filtered to reduce color fringes + * inherent to this technology. You can either set up LCD filtering with + * @FT_Library_SetLcdFilter or @FT_Face_Properties, or do the filtering + * yourself. The default FreeType LCD rendering technology does not + * require filtering. + * + * The selected render mode only affects vector glyphs of a font. + * Embedded bitmaps often have a different pixel mode like + * @FT_PIXEL_MODE_MONO. You can use @FT_Bitmap_Convert to transform them + * into 8-bit pixmaps. + */ typedef enum FT_Render_Mode_ { FT_RENDER_MODE_NORMAL = 0, @@ -3243,147 +3265,149 @@ FT_BEGIN_HEADER /* these constants are deprecated; use the corresponding */ - /* `FT_Render_Mode' values instead */ + /* `FT_Render_Mode` values instead */ #define ft_render_mode_normal FT_RENDER_MODE_NORMAL #define ft_render_mode_mono FT_RENDER_MODE_MONO - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Render_Glyph */ - /* */ - /* <Description> */ - /* Convert a given glyph image to a bitmap. It does so by inspecting */ - /* the glyph image format, finding the relevant renderer, and */ - /* invoking it. */ - /* */ - /* <InOut> */ - /* slot :: A handle to the glyph slot containing the image to */ - /* convert. */ - /* */ - /* <Input> */ - /* render_mode :: The render mode used to render the glyph image into */ - /* a bitmap. See @FT_Render_Mode for a list of */ - /* possible values. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* To get meaningful results, font scaling values must be set with */ - /* functions like @FT_Set_Char_Size before calling `FT_Render_Glyph'. */ - /* */ - /* When FreeType outputs a bitmap of a glyph, it really outputs an */ - /* alpha coverage map. If a pixel is completely covered by a */ - /* filled-in outline, the bitmap contains 0xFF at that pixel, meaning */ - /* that 0xFF/0xFF fraction of that pixel is covered, meaning the */ - /* pixel is 100% black (or 0% bright). If a pixel is only 50% */ - /* covered (value 0x80), the pixel is made 50% black (50% bright or a */ - /* middle shade of grey). 0% covered means 0% black (100% bright or */ - /* white). */ - /* */ - /* On high-DPI screens like on smartphones and tablets, the pixels */ - /* are so small that their chance of being completely covered and */ - /* therefore completely black are fairly good. On the low-DPI */ - /* screens, however, the situation is different. The pixels are too */ - /* large for most of the details of a glyph and shades of gray are */ - /* the norm rather than the exception. */ - /* */ - /* This is relevant because all our screens have a second problem: */ - /* they are not linear. 1~+~1 is not~2. Twice the value does not */ - /* result in twice the brightness. When a pixel is only 50% covered, */ - /* the coverage map says 50% black, and this translates to a pixel */ - /* value of 128 when you use 8~bits per channel (0-255). However, */ - /* this does not translate to 50% brightness for that pixel on our */ - /* sRGB and gamma~2.2 screens. Due to their non-linearity, they */ - /* dwell longer in the darks and only a pixel value of about 186 */ - /* results in 50% brightness -- 128 ends up too dark on both bright */ - /* and dark backgrounds. The net result is that dark text looks */ - /* burnt-out, pixely and blotchy on bright background, bright text */ - /* too frail on dark backgrounds, and colored text on colored */ - /* background (for example, red on green) seems to have dark halos or */ - /* `dirt' around it. The situation is especially ugly for diagonal */ - /* stems like in `w' glyph shapes where the quality of FreeType's */ - /* anti-aliasing depends on the correct display of grays. On */ - /* high-DPI screens where smaller, fully black pixels reign supreme, */ - /* this doesn't matter, but on our low-DPI screens with all the gray */ - /* shades, it does. 0% and 100% brightness are the same things in */ - /* linear and non-linear space, just all the shades in-between */ - /* aren't. */ - /* */ - /* The blending function for placing text over a background is */ - /* */ - /* { */ - /* dst = alpha * src + (1 - alpha) * dst , */ - /* } */ - /* */ - /* which is known as the OVER operator. */ - /* */ - /* To correctly composite an antialiased pixel of a glyph onto a */ - /* surface, */ - /* */ - /* 1. take the foreground and background colors (e.g., in sRGB space) */ - /* and apply gamma to get them in a linear space, */ - /* */ - /* 2. use OVER to blend the two linear colors using the glyph pixel */ - /* as the alpha value (remember, the glyph bitmap is an alpha */ - /* coverage bitmap), and */ - /* */ - /* 3. apply inverse gamma to the blended pixel and write it back to */ - /* the image. */ - /* */ - /* Internal testing at Adobe found that a target inverse gamma of~1.8 */ - /* for step~3 gives good results across a wide range of displays with */ - /* an sRGB gamma curve or a similar one. */ - /* */ - /* This process can cost performance. There is an approximation that */ - /* does not need to know about the background color; see */ - /* https://bel.fi/alankila/lcd/ and */ - /* https://bel.fi/alankila/lcd/alpcor.html for details. */ - /* */ - /* *ATTENTION*: Linear blending is even more important when dealing */ - /* with subpixel-rendered glyphs to prevent color-fringing! A */ - /* subpixel-rendered glyph must first be filtered with a filter that */ - /* gives equal weight to the three color primaries and does not */ - /* exceed a sum of 0x100, see section @lcd_filtering. Then the */ - /* only difference to gray linear blending is that subpixel-rendered */ - /* linear blending is done 3~times per pixel: red foreground subpixel */ - /* to red background subpixel and so on for green and blue. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Render_Glyph + * + * @description: + * Convert a given glyph image to a bitmap. It does so by inspecting the + * glyph image format, finding the relevant renderer, and invoking it. + * + * @inout: + * slot :: + * A handle to the glyph slot containing the image to convert. + * + * @input: + * render_mode :: + * The render mode used to render the glyph image into a bitmap. See + * @FT_Render_Mode for a list of possible values. + * + * If @FT_RENDER_MODE_NORMAL is used, a previous call of @FT_Load_Glyph + * with flag @FT_LOAD_COLOR makes FT_Render_Glyph provide a default + * blending of colored glyph layers associated with the current glyph + * slot (provided the font contains such layers) instead of rendering + * the glyph slot's outline. This is an experimental feature; see + * @FT_LOAD_COLOR for more information. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * To get meaningful results, font scaling values must be set with + * functions like @FT_Set_Char_Size before calling `FT_Render_Glyph`. + * + * When FreeType outputs a bitmap of a glyph, it really outputs an alpha + * coverage map. If a pixel is completely covered by a filled-in + * outline, the bitmap contains 0xFF at that pixel, meaning that + * 0xFF/0xFF fraction of that pixel is covered, meaning the pixel is 100% + * black (or 0% bright). If a pixel is only 50% covered (value 0x80), + * the pixel is made 50% black (50% bright or a middle shade of grey). + * 0% covered means 0% black (100% bright or white). + * + * On high-DPI screens like on smartphones and tablets, the pixels are so + * small that their chance of being completely covered and therefore + * completely black are fairly good. On the low-DPI screens, however, + * the situation is different. The pixels are too large for most of the + * details of a glyph and shades of gray are the norm rather than the + * exception. + * + * This is relevant because all our screens have a second problem: they + * are not linear. 1~+~1 is not~2. Twice the value does not result in + * twice the brightness. When a pixel is only 50% covered, the coverage + * map says 50% black, and this translates to a pixel value of 128 when + * you use 8~bits per channel (0-255). However, this does not translate + * to 50% brightness for that pixel on our sRGB and gamma~2.2 screens. + * Due to their non-linearity, they dwell longer in the darks and only a + * pixel value of about 186 results in 50% brightness -- 128 ends up too + * dark on both bright and dark backgrounds. The net result is that dark + * text looks burnt-out, pixely and blotchy on bright background, bright + * text too frail on dark backgrounds, and colored text on colored + * background (for example, red on green) seems to have dark halos or + * 'dirt' around it. The situation is especially ugly for diagonal stems + * like in 'w' glyph shapes where the quality of FreeType's anti-aliasing + * depends on the correct display of grays. On high-DPI screens where + * smaller, fully black pixels reign supreme, this doesn't matter, but on + * our low-DPI screens with all the gray shades, it does. 0% and 100% + * brightness are the same things in linear and non-linear space, just + * all the shades in-between aren't. + * + * The blending function for placing text over a background is + * + * ``` + * dst = alpha * src + (1 - alpha) * dst , + * ``` + * + * which is known as the OVER operator. + * + * To correctly composite an antialiased pixel of a glyph onto a surface, + * + * 1. take the foreground and background colors (e.g., in sRGB space) + * and apply gamma to get them in a linear space, + * + * 2. use OVER to blend the two linear colors using the glyph pixel + * as the alpha value (remember, the glyph bitmap is an alpha coverage + * bitmap), and + * + * 3. apply inverse gamma to the blended pixel and write it back to + * the image. + * + * Internal testing at Adobe found that a target inverse gamma of~1.8 for + * step~3 gives good results across a wide range of displays with an sRGB + * gamma curve or a similar one. + * + * This process can cost performance. There is an approximation that + * does not need to know about the background color; see + * https://bel.fi/alankila/lcd/ and + * https://bel.fi/alankila/lcd/alpcor.html for details. + * + * **ATTENTION**: Linear blending is even more important when dealing + * with subpixel-rendered glyphs to prevent color-fringing! A + * subpixel-rendered glyph must first be filtered with a filter that + * gives equal weight to the three color primaries and does not exceed a + * sum of 0x100, see section @lcd_rendering. Then the only difference to + * gray linear blending is that subpixel-rendered linear blending is done + * 3~times per pixel: red foreground subpixel to red background subpixel + * and so on for green and blue. + */ FT_EXPORT( FT_Error ) FT_Render_Glyph( FT_GlyphSlot slot, FT_Render_Mode render_mode ); - /*************************************************************************/ - /* */ - /* <Enum> */ - /* FT_Kerning_Mode */ - /* */ - /* <Description> */ - /* An enumeration to specify the format of kerning values returned by */ - /* @FT_Get_Kerning. */ - /* */ - /* <Values> */ - /* FT_KERNING_DEFAULT :: Return grid-fitted kerning distances in */ - /* 26.6 fractional pixels. */ - /* */ - /* FT_KERNING_UNFITTED :: Return un-grid-fitted kerning distances in */ - /* 26.6 fractional pixels. */ - /* */ - /* FT_KERNING_UNSCALED :: Return the kerning vector in original font */ - /* units. */ - /* */ - /* <Note> */ - /* FT_KERNING_DEFAULT returns full pixel values; it also makes */ - /* FreeType heuristically scale down kerning distances at small ppem */ - /* values so that they don't become too big. */ - /* */ - /* Both FT_KERNING_DEFAULT and FT_KERNING_UNFITTED use the current */ - /* horizontal scaling factor (as set e.g. with @FT_Set_Char_Size) to */ - /* convert font units to pixels. */ - /* */ + /************************************************************************** + * + * @enum: + * FT_Kerning_Mode + * + * @description: + * An enumeration to specify the format of kerning values returned by + * @FT_Get_Kerning. + * + * @values: + * FT_KERNING_DEFAULT :: + * Return grid-fitted kerning distances in 26.6 fractional pixels. + * + * FT_KERNING_UNFITTED :: + * Return un-grid-fitted kerning distances in 26.6 fractional pixels. + * + * FT_KERNING_UNSCALED :: + * Return the kerning vector in original font units. + * + * @note: + * `FT_KERNING_DEFAULT` returns full pixel values; it also makes FreeType + * heuristically scale down kerning distances at small ppem values so + * that they don't become too big. + * + * Both `FT_KERNING_DEFAULT` and `FT_KERNING_UNFITTED` use the current + * horizontal scaling factor (as set e.g. with @FT_Set_Char_Size) to + * convert font units to pixels. + */ typedef enum FT_Kerning_Mode_ { FT_KERNING_DEFAULT = 0, @@ -3394,50 +3418,53 @@ FT_BEGIN_HEADER /* these constants are deprecated; use the corresponding */ - /* `FT_Kerning_Mode' values instead */ + /* `FT_Kerning_Mode` values instead */ #define ft_kerning_default FT_KERNING_DEFAULT #define ft_kerning_unfitted FT_KERNING_UNFITTED #define ft_kerning_unscaled FT_KERNING_UNSCALED - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_Kerning */ - /* */ - /* <Description> */ - /* Return the kerning vector between two glyphs of the same face. */ - /* */ - /* <Input> */ - /* face :: A handle to a source face object. */ - /* */ - /* left_glyph :: The index of the left glyph in the kern pair. */ - /* */ - /* right_glyph :: The index of the right glyph in the kern pair. */ - /* */ - /* kern_mode :: See @FT_Kerning_Mode for more information. */ - /* Determines the scale and dimension of the returned */ - /* kerning vector. */ - /* */ - /* <Output> */ - /* akerning :: The kerning vector. This is either in font units, */ - /* fractional pixels (26.6 format), or pixels for */ - /* scalable formats, and in pixels for fixed-sizes */ - /* formats. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* Only horizontal layouts (left-to-right & right-to-left) are */ - /* supported by this method. Other layouts, or more sophisticated */ - /* kernings, are out of the scope of this API function -- they can be */ - /* implemented through format-specific interfaces. */ - /* */ - /* Kerning for OpenType fonts implemented in a `GPOS' table is not */ - /* supported; use @FT_HAS_KERNING to find out whether a font has data */ - /* that can be extracted with `FT_Get_Kerning'. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Get_Kerning + * + * @description: + * Return the kerning vector between two glyphs of the same face. + * + * @input: + * face :: + * A handle to a source face object. + * + * left_glyph :: + * The index of the left glyph in the kern pair. + * + * right_glyph :: + * The index of the right glyph in the kern pair. + * + * kern_mode :: + * See @FT_Kerning_Mode for more information. Determines the scale and + * dimension of the returned kerning vector. + * + * @output: + * akerning :: + * The kerning vector. This is either in font units, fractional pixels + * (26.6 format), or pixels for scalable formats, and in pixels for + * fixed-sizes formats. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * Only horizontal layouts (left-to-right & right-to-left) are supported + * by this method. Other layouts, or more sophisticated kernings, are + * out of the scope of this API function -- they can be implemented + * through format-specific interfaces. + * + * Kerning for OpenType fonts implemented in a 'GPOS' table is not + * supported; use @FT_HAS_KERNING to find out whether a font has data + * that can be extracted with `FT_Get_Kerning`. + */ FT_EXPORT( FT_Error ) FT_Get_Kerning( FT_Face face, FT_UInt left_glyph, @@ -3446,39 +3473,42 @@ FT_BEGIN_HEADER FT_Vector *akerning ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_Track_Kerning */ - /* */ - /* <Description> */ - /* Return the track kerning for a given face object at a given size. */ - /* */ - /* <Input> */ - /* face :: A handle to a source face object. */ - /* */ - /* point_size :: The point size in 16.16 fractional points. */ - /* */ - /* degree :: The degree of tightness. Increasingly negative */ - /* values represent tighter track kerning, while */ - /* increasingly positive values represent looser track */ - /* kerning. Value zero means no track kerning. */ - /* */ - /* <Output> */ - /* akerning :: The kerning in 16.16 fractional points, to be */ - /* uniformly applied between all glyphs. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* Currently, only the Type~1 font driver supports track kerning, */ - /* using data from AFM files (if attached with @FT_Attach_File or */ - /* @FT_Attach_Stream). */ - /* */ - /* Only very few AFM files come with track kerning data; please refer */ - /* to Adobe's AFM specification for more details. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Get_Track_Kerning + * + * @description: + * Return the track kerning for a given face object at a given size. + * + * @input: + * face :: + * A handle to a source face object. + * + * point_size :: + * The point size in 16.16 fractional points. + * + * degree :: + * The degree of tightness. Increasingly negative values represent + * tighter track kerning, while increasingly positive values represent + * looser track kerning. Value zero means no track kerning. + * + * @output: + * akerning :: + * The kerning in 16.16 fractional points, to be uniformly applied + * between all glyphs. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * Currently, only the Type~1 font driver supports track kerning, using + * data from AFM files (if attached with @FT_Attach_File or + * @FT_Attach_Stream). + * + * Only very few AFM files come with track kerning data; please refer to + * Adobe's AFM specification for more details. + */ FT_EXPORT( FT_Error ) FT_Get_Track_Kerning( FT_Face face, FT_Fixed point_size, @@ -3486,45 +3516,46 @@ FT_BEGIN_HEADER FT_Fixed* akerning ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_Glyph_Name */ - /* */ - /* <Description> */ - /* Retrieve the ASCII name of a given glyph in a face. This only */ - /* works for those faces where @FT_HAS_GLYPH_NAMES(face) returns~1. */ - /* */ - /* <Input> */ - /* face :: A handle to a source face object. */ - /* */ - /* glyph_index :: The glyph index. */ - /* */ - /* buffer_max :: The maximum number of bytes available in the */ - /* buffer. */ - /* */ - /* <Output> */ - /* buffer :: A pointer to a target buffer where the name is */ - /* copied to. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* An error is returned if the face doesn't provide glyph names or if */ - /* the glyph index is invalid. In all cases of failure, the first */ - /* byte of `buffer' is set to~0 to indicate an empty name. */ - /* */ - /* The glyph name is truncated to fit within the buffer if it is too */ - /* long. The returned string is always zero-terminated. */ - /* */ - /* Be aware that FreeType reorders glyph indices internally so that */ - /* glyph index~0 always corresponds to the `missing glyph' (called */ - /* `.notdef'). */ - /* */ - /* This function always returns an error if the config macro */ - /* `FT_CONFIG_OPTION_NO_GLYPH_NAMES' is not defined in `ftoption.h'. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Get_Glyph_Name + * + * @description: + * Retrieve the ASCII name of a given glyph in a face. This only works + * for those faces where @FT_HAS_GLYPH_NAMES(face) returns~1. + * + * @input: + * face :: + * A handle to a source face object. + * + * glyph_index :: + * The glyph index. + * + * buffer_max :: + * The maximum number of bytes available in the buffer. + * + * @output: + * buffer :: + * A pointer to a target buffer where the name is copied to. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * An error is returned if the face doesn't provide glyph names or if the + * glyph index is invalid. In all cases of failure, the first byte of + * `buffer` is set to~0 to indicate an empty name. + * + * The glyph name is truncated to fit within the buffer if it is too + * long. The returned string is always zero-terminated. + * + * Be aware that FreeType reorders glyph indices internally so that glyph + * index~0 always corresponds to the 'missing glyph' (called '.notdef'). + * + * This function always returns an error if the config macro + * `FT_CONFIG_OPTION_NO_GLYPH_NAMES` is not defined in `ftoption.h`. + */ FT_EXPORT( FT_Error ) FT_Get_Glyph_Name( FT_Face face, FT_UInt glyph_index, @@ -3532,107 +3563,109 @@ FT_BEGIN_HEADER FT_UInt buffer_max ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_Postscript_Name */ - /* */ - /* <Description> */ - /* Retrieve the ASCII PostScript name of a given face, if available. */ - /* This only works with PostScript, TrueType, and OpenType fonts. */ - /* */ - /* <Input> */ - /* face :: A handle to the source face object. */ - /* */ - /* <Return> */ - /* A pointer to the face's PostScript name. NULL if unavailable. */ - /* */ - /* <Note> */ - /* The returned pointer is owned by the face and is destroyed with */ - /* it. */ - /* */ - /* For variation fonts, this string changes if you select a different */ - /* instance, and you have to call `FT_Get_PostScript_Name' again to */ - /* retrieve it. FreeType follows Adobe TechNote #5902, `Generating */ - /* PostScript Names for Fonts Using OpenType Font Variations'. */ - /* */ - /* https://download.macromedia.com/pub/developer/opentype/tech-notes/5902.AdobePSNameGeneration.html */ - /* */ - /* [Since 2.9] Special PostScript names for named instances are only */ - /* returned if the named instance is set with @FT_Set_Named_Instance */ - /* (and the font has corresponding entries in its `fvar' table). If */ - /* @FT_IS_VARIATION returns true, the algorithmically derived */ - /* PostScript name is provided, not looking up special entries for */ - /* named instances. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Get_Postscript_Name + * + * @description: + * Retrieve the ASCII PostScript name of a given face, if available. + * This only works with PostScript, TrueType, and OpenType fonts. + * + * @input: + * face :: + * A handle to the source face object. + * + * @return: + * A pointer to the face's PostScript name. `NULL` if unavailable. + * + * @note: + * The returned pointer is owned by the face and is destroyed with it. + * + * For variation fonts, this string changes if you select a different + * instance, and you have to call `FT_Get_PostScript_Name` again to + * retrieve it. FreeType follows Adobe TechNote #5902, 'Generating + * PostScript Names for Fonts Using OpenType Font Variations'. + * + * https://download.macromedia.com/pub/developer/opentype/tech-notes/5902.AdobePSNameGeneration.html + * + * [Since 2.9] Special PostScript names for named instances are only + * returned if the named instance is set with @FT_Set_Named_Instance (and + * the font has corresponding entries in its 'fvar' table). If + * @FT_IS_VARIATION returns true, the algorithmically derived PostScript + * name is provided, not looking up special entries for named instances. + */ FT_EXPORT( const char* ) FT_Get_Postscript_Name( FT_Face face ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Select_Charmap */ - /* */ - /* <Description> */ - /* Select a given charmap by its encoding tag (as listed in */ - /* `freetype.h'). */ - /* */ - /* <InOut> */ - /* face :: A handle to the source face object. */ - /* */ - /* <Input> */ - /* encoding :: A handle to the selected encoding. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* This function returns an error if no charmap in the face */ - /* corresponds to the encoding queried here. */ - /* */ - /* Because many fonts contain more than a single cmap for Unicode */ - /* encoding, this function has some special code to select the one */ - /* that covers Unicode best (`best' in the sense that a UCS-4 cmap is */ - /* preferred to a UCS-2 cmap). It is thus preferable to */ - /* @FT_Set_Charmap in this case. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Select_Charmap + * + * @description: + * Select a given charmap by its encoding tag (as listed in + * `freetype.h`). + * + * @inout: + * face :: + * A handle to the source face object. + * + * @input: + * encoding :: + * A handle to the selected encoding. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function returns an error if no charmap in the face corresponds + * to the encoding queried here. + * + * Because many fonts contain more than a single cmap for Unicode + * encoding, this function has some special code to select the one that + * covers Unicode best ('best' in the sense that a UCS-4 cmap is + * preferred to a UCS-2 cmap). It is thus preferable to @FT_Set_Charmap + * in this case. + */ FT_EXPORT( FT_Error ) FT_Select_Charmap( FT_Face face, FT_Encoding encoding ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Set_Charmap */ - /* */ - /* <Description> */ - /* Select a given charmap for character code to glyph index mapping. */ - /* */ - /* <InOut> */ - /* face :: A handle to the source face object. */ - /* */ - /* <Input> */ - /* charmap :: A handle to the selected charmap. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* This function returns an error if the charmap is not part of */ - /* the face (i.e., if it is not listed in the `face->charmaps' */ - /* table). */ - /* */ - /* It also fails if an OpenType type~14 charmap is selected (which */ - /* doesn't map character codes to glyph indices at all). */ - /* */ + /************************************************************************** + * + * @function: + * FT_Set_Charmap + * + * @description: + * Select a given charmap for character code to glyph index mapping. + * + * @inout: + * face :: + * A handle to the source face object. + * + * @input: + * charmap :: + * A handle to the selected charmap. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function returns an error if the charmap is not part of the face + * (i.e., if it is not listed in the `face->charmaps` table). + * + * It also fails if an OpenType type~14 charmap is selected (which + * doesn't map character codes to glyph indices at all). + */ FT_EXPORT( FT_Error ) FT_Set_Charmap( FT_Face face, FT_CharMap charmap ); - /************************************************************************* + /************************************************************************** * * @function: * FT_Get_Charmap_Index @@ -3646,139 +3679,143 @@ FT_BEGIN_HEADER * * @return: * The index into the array of character maps within the face to which - * `charmap' belongs. If an error occurs, -1 is returned. + * `charmap` belongs. If an error occurs, -1 is returned. * */ FT_EXPORT( FT_Int ) FT_Get_Charmap_Index( FT_CharMap charmap ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_Char_Index */ - /* */ - /* <Description> */ - /* Return the glyph index of a given character code. This function */ - /* uses the currently selected charmap to do the mapping. */ - /* */ - /* <Input> */ - /* face :: A handle to the source face object. */ - /* */ - /* charcode :: The character code. */ - /* */ - /* <Return> */ - /* The glyph index. 0~means `undefined character code'. */ - /* */ - /* <Note> */ - /* If you use FreeType to manipulate the contents of font files */ - /* directly, be aware that the glyph index returned by this function */ - /* doesn't always correspond to the internal indices used within the */ - /* file. This is done to ensure that value~0 always corresponds to */ - /* the `missing glyph'. If the first glyph is not named `.notdef', */ - /* then for Type~1 and Type~42 fonts, `.notdef' will be moved into */ - /* the glyph ID~0 position, and whatever was there will be moved to */ - /* the position `.notdef' had. For Type~1 fonts, if there is no */ - /* `.notdef' glyph at all, then one will be created at index~0 and */ - /* whatever was there will be moved to the last index -- Type~42 */ - /* fonts are considered invalid under this condition. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Get_Char_Index + * + * @description: + * Return the glyph index of a given character code. This function uses + * the currently selected charmap to do the mapping. + * + * @input: + * face :: + * A handle to the source face object. + * + * charcode :: + * The character code. + * + * @return: + * The glyph index. 0~means 'undefined character code'. + * + * @note: + * If you use FreeType to manipulate the contents of font files directly, + * be aware that the glyph index returned by this function doesn't always + * correspond to the internal indices used within the file. This is done + * to ensure that value~0 always corresponds to the 'missing glyph'. If + * the first glyph is not named '.notdef', then for Type~1 and Type~42 + * fonts, '.notdef' will be moved into the glyph ID~0 position, and + * whatever was there will be moved to the position '.notdef' had. For + * Type~1 fonts, if there is no '.notdef' glyph at all, then one will be + * created at index~0 and whatever was there will be moved to the last + * index -- Type~42 fonts are considered invalid under this condition. + */ FT_EXPORT( FT_UInt ) FT_Get_Char_Index( FT_Face face, FT_ULong charcode ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_First_Char */ - /* */ - /* <Description> */ - /* Return the first character code in the current charmap of a given */ - /* face, together with its corresponding glyph index. */ - /* */ - /* <Input> */ - /* face :: A handle to the source face object. */ - /* */ - /* <Output> */ - /* agindex :: Glyph index of first character code. 0~if charmap is */ - /* empty. */ - /* */ - /* <Return> */ - /* The charmap's first character code. */ - /* */ - /* <Note> */ - /* You should use this function together with @FT_Get_Next_Char to */ - /* parse all character codes available in a given charmap. The code */ - /* should look like this: */ - /* */ - /* { */ - /* FT_ULong charcode; */ - /* FT_UInt gindex; */ - /* */ - /* */ - /* charcode = FT_Get_First_Char( face, &gindex ); */ - /* while ( gindex != 0 ) */ - /* { */ - /* ... do something with (charcode,gindex) pair ... */ - /* */ - /* charcode = FT_Get_Next_Char( face, charcode, &gindex ); */ - /* } */ - /* } */ - /* */ - /* Be aware that character codes can have values up to 0xFFFFFFFF; */ - /* this might happen for non-Unicode or malformed cmaps. However, */ - /* even with regular Unicode encoding, so-called `last resort fonts' */ - /* (using SFNT cmap format 13, see function @FT_Get_CMap_Format) */ - /* normally have entries for all Unicode characters up to 0x1FFFFF, */ - /* which can cause *a lot* of iterations. */ - /* */ - /* Note that `*agindex' is set to~0 if the charmap is empty. The */ - /* result itself can be~0 in two cases: if the charmap is empty or */ - /* if the value~0 is the first valid character code. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Get_First_Char + * + * @description: + * Return the first character code in the current charmap of a given + * face, together with its corresponding glyph index. + * + * @input: + * face :: + * A handle to the source face object. + * + * @output: + * agindex :: + * Glyph index of first character code. 0~if charmap is empty. + * + * @return: + * The charmap's first character code. + * + * @note: + * You should use this function together with @FT_Get_Next_Char to parse + * all character codes available in a given charmap. The code should + * look like this: + * + * ``` + * FT_ULong charcode; + * FT_UInt gindex; + * + * + * charcode = FT_Get_First_Char( face, &gindex ); + * while ( gindex != 0 ) + * { + * ... do something with (charcode,gindex) pair ... + * + * charcode = FT_Get_Next_Char( face, charcode, &gindex ); + * } + * ``` + * + * Be aware that character codes can have values up to 0xFFFFFFFF; this + * might happen for non-Unicode or malformed cmaps. However, even with + * regular Unicode encoding, so-called 'last resort fonts' (using SFNT + * cmap format 13, see function @FT_Get_CMap_Format) normally have + * entries for all Unicode characters up to 0x1FFFFF, which can cause *a + * lot* of iterations. + * + * Note that `*agindex` is set to~0 if the charmap is empty. The result + * itself can be~0 in two cases: if the charmap is empty or if the + * value~0 is the first valid character code. + */ FT_EXPORT( FT_ULong ) FT_Get_First_Char( FT_Face face, FT_UInt *agindex ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_Next_Char */ - /* */ - /* <Description> */ - /* Return the next character code in the current charmap of a given */ - /* face following the value `char_code', as well as the corresponding */ - /* glyph index. */ - /* */ - /* <Input> */ - /* face :: A handle to the source face object. */ - /* */ - /* char_code :: The starting character code. */ - /* */ - /* <Output> */ - /* agindex :: Glyph index of next character code. 0~if charmap */ - /* is empty. */ - /* */ - /* <Return> */ - /* The charmap's next character code. */ - /* */ - /* <Note> */ - /* You should use this function with @FT_Get_First_Char to walk */ - /* over all character codes available in a given charmap. See the */ - /* note for that function for a simple code example. */ - /* */ - /* Note that `*agindex' is set to~0 when there are no more codes in */ - /* the charmap. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Get_Next_Char + * + * @description: + * Return the next character code in the current charmap of a given face + * following the value `char_code`, as well as the corresponding glyph + * index. + * + * @input: + * face :: + * A handle to the source face object. + * + * char_code :: + * The starting character code. + * + * @output: + * agindex :: + * Glyph index of next character code. 0~if charmap is empty. + * + * @return: + * The charmap's next character code. + * + * @note: + * You should use this function with @FT_Get_First_Char to walk over all + * character codes available in a given charmap. See the note for that + * function for a simple code example. + * + * Note that `*agindex` is set to~0 when there are no more codes in the + * charmap. + */ FT_EXPORT( FT_ULong ) FT_Get_Next_Char( FT_Face face, FT_ULong char_code, FT_UInt *agindex ); - /************************************************************************* + /************************************************************************** * * @function: * FT_Face_Properties @@ -3786,27 +3823,26 @@ FT_BEGIN_HEADER * @description: * Set or override certain (library or module-wide) properties on a * face-by-face basis. Useful for finer-grained control and avoiding - * locks on shared structures (threads can modify their own faces as - * they see fit). + * locks on shared structures (threads can modify their own faces as they + * see fit). * - * Contrary to @FT_Property_Set, this function uses @FT_Parameter so - * that you can pass multiple properties to the target face in one call. - * Note that only a subset of the available properties can be - * controlled. + * Contrary to @FT_Property_Set, this function uses @FT_Parameter so that + * you can pass multiple properties to the target face in one call. Note + * that only a subset of the available properties can be controlled. * * * @FT_PARAM_TAG_STEM_DARKENING (stem darkening, corresponding to the - * property `no-stem-darkening' provided by the `autofit', `cff', - * `type1', and `t1cid' modules; see @no-stem-darkening). + * property `no-stem-darkening` provided by the 'autofit', 'cff', + * 'type1', and 't1cid' modules; see @no-stem-darkening). * * * @FT_PARAM_TAG_LCD_FILTER_WEIGHTS (LCD filter weights, corresponding * to function @FT_Library_SetLcdFilterWeights). * * * @FT_PARAM_TAG_RANDOM_SEED (seed value for the CFF, Type~1, and CID - * `random' operator, corresponding to the `random-seed' property - * provided by the `cff', `type1', and `t1cid' modules; see + * 'random' operator, corresponding to the `random-seed` property + * provided by the 'cff', 'type1', and 't1cid' modules; see * @random-seed). * - * Pass NULL as `data' in @FT_Parameter for a given tag to reset the + * Pass `NULL` as `data` in @FT_Parameter for a given tag to reset the * option and use the library or module default again. * * @input: @@ -3817,17 +3853,17 @@ FT_BEGIN_HEADER * The number of properties that follow. * * properties :: - * A handle to an @FT_Parameter array with `num_properties' elements. + * A handle to an @FT_Parameter array with `num_properties` elements. * * @return: * FreeType error code. 0~means success. * - * @note: - * Here an example that sets three properties. You must define - * FT_CONFIG_OPTION_SUBPIXEL_RENDERING to make the LCD filter examples + * @example: + * Here is an example that sets three properties. You must define + * `FT_CONFIG_OPTION_SUBPIXEL_RENDERING` to make the LCD filter examples * work. * - * { + * ``` * FT_Parameter property1; * FT_Bool darken_stems = 1; * @@ -3853,11 +3889,11 @@ FT_BEGIN_HEADER * property3.data = &random_seed; * * FT_Face_Properties( face, 3, properties ); - * } + * ``` * * The next example resets a single property to its default value. * - * { + * ``` * FT_Parameter property; * * @@ -3865,7 +3901,7 @@ FT_BEGIN_HEADER * property.data = NULL; * * FT_Face_Properties( face, 1, &property ); - * } + * ``` * * @since: * 2.8 @@ -3877,37 +3913,40 @@ FT_BEGIN_HEADER FT_Parameter* properties ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_Name_Index */ - /* */ - /* <Description> */ - /* Return the glyph index of a given glyph name. */ - /* */ - /* <Input> */ - /* face :: A handle to the source face object. */ - /* */ - /* glyph_name :: The glyph name. */ - /* */ - /* <Return> */ - /* The glyph index. 0~means `undefined character code'. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Get_Name_Index + * + * @description: + * Return the glyph index of a given glyph name. + * + * @input: + * face :: + * A handle to the source face object. + * + * glyph_name :: + * The glyph name. + * + * @return: + * The glyph index. 0~means 'undefined character code'. + */ FT_EXPORT( FT_UInt ) FT_Get_Name_Index( FT_Face face, FT_String* glyph_name ); - /************************************************************************* + /************************************************************************** * - * @macro: + * @enum: * FT_SUBGLYPH_FLAG_XXX * * @description: - * A list of constants describing subglyphs. Please refer to the - * `glyf' table description in the OpenType specification for the - * meaning of the various flags (which get synthesized for - * non-OpenType subglyphs). + * A list of constants describing subglyphs. Please refer to the 'glyf' + * table description in the OpenType specification for the meaning of the + * various flags (which get synthesized for non-OpenType subglyphs). + * + * https://docs.microsoft.com/en-us/typography/opentype/spec/glyf#composite-glyph-description * * @values: * FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS :: @@ -3928,112 +3967,283 @@ FT_BEGIN_HEADER #define FT_SUBGLYPH_FLAG_USE_MY_METRICS 0x200 - /************************************************************************* + /************************************************************************** + * + * @function: + * FT_Get_SubGlyph_Info + * + * @description: + * Retrieve a description of a given subglyph. Only use it if + * `glyph->format` is @FT_GLYPH_FORMAT_COMPOSITE; an error is returned + * otherwise. + * + * @input: + * glyph :: + * The source glyph slot. + * + * sub_index :: + * The index of the subglyph. Must be less than + * `glyph->num_subglyphs`. + * + * @output: + * p_index :: + * The glyph index of the subglyph. + * + * p_flags :: + * The subglyph flags, see @FT_SUBGLYPH_FLAG_XXX. + * + * p_arg1 :: + * The subglyph's first argument (if any). + * + * p_arg2 :: + * The subglyph's second argument (if any). + * + * p_transform :: + * The subglyph transformation (if any). + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The values of `*p_arg1`, `*p_arg2`, and `*p_transform` must be + * interpreted depending on the flags returned in `*p_flags`. See the + * OpenType specification for details. + * + * https://docs.microsoft.com/en-us/typography/opentype/spec/glyf#composite-glyph-description + * + */ + FT_EXPORT( FT_Error ) + FT_Get_SubGlyph_Info( FT_GlyphSlot glyph, + FT_UInt sub_index, + FT_Int *p_index, + FT_UInt *p_flags, + FT_Int *p_arg1, + FT_Int *p_arg2, + FT_Matrix *p_transform ); + + + /************************************************************************** + * + * @section: + * layer_management + * + * @title: + * Glyph Layer Management + * + * @abstract: + * Retrieving and manipulating OpenType's 'COLR' table data. + * + * @description: + * The functions described here allow access of colored glyph layer data + * in OpenType's 'COLR' tables. + */ + + + /************************************************************************** + * + * @struct: + * FT_LayerIterator + * + * @description: + * This iterator object is needed for @FT_Get_Color_Glyph_Layer. + * + * @fields: + * num_layers :: + * The number of glyph layers for the requested glyph index. Will be + * set by @FT_Get_Color_Glyph_Layer. + * + * layer :: + * The current layer. Will be set by @FT_Get_Color_Glyph_Layer. + * + * p :: + * An opaque pointer into 'COLR' table data. The caller must set this + * to `NULL` before the first call of @FT_Get_Color_Glyph_Layer. + */ + typedef struct FT_LayerIterator_ + { + FT_UInt num_layers; + FT_UInt layer; + FT_Byte* p; + + } FT_LayerIterator; + + + /************************************************************************** * - * @func: - * FT_Get_SubGlyph_Info + * @function: + * FT_Get_Color_Glyph_Layer * * @description: - * Retrieve a description of a given subglyph. Only use it if - * `glyph->format' is @FT_GLYPH_FORMAT_COMPOSITE; an error is - * returned otherwise. + * This is an interface to the 'COLR' table in OpenType fonts to + * iteratively retrieve the colored glyph layers associated with the + * current glyph slot. * - * @input: - * glyph :: - * The source glyph slot. + * https://docs.microsoft.com/en-us/typography/opentype/spec/colr * - * sub_index :: - * The index of the subglyph. Must be less than - * `glyph->num_subglyphs'. + * The glyph layer data for a given glyph index, if present, provides an + * alternative, multi-colour glyph representation: Instead of rendering + * the outline or bitmap with the given glyph index, glyphs with the + * indices and colors returned by this function are rendered layer by + * layer. * - * @output: - * p_index :: - * The glyph index of the subglyph. + * The returned elements are ordered in the z~direction from bottom to + * top; the 'n'th element should be rendered with the associated palette + * color and blended on top of the already rendered layers (elements 0, + * 1, ..., n-1). * - * p_flags :: - * The subglyph flags, see @FT_SUBGLYPH_FLAG_XXX. + * @input: + * face :: + * A handle to the parent face object. * - * p_arg1 :: - * The subglyph's first argument (if any). + * base_glyph :: + * The glyph index the colored glyph layers are associated with. * - * p_arg2 :: - * The subglyph's second argument (if any). + * @inout: + * iterator :: + * An @FT_LayerIterator object. For the first call you should set + * `iterator->p` to `NULL`. For all following calls, simply use the + * same object again. * - * p_transform :: - * The subglyph transformation (if any). + * @output: + * aglyph_index :: + * The glyph index of the current layer. + * + * acolor_index :: + * The color index into the font face's color palette of the current + * layer. The value 0xFFFF is special; it doesn't reference a palette + * entry but indicates that the text foreground color should be used + * instead (to be set up by the application outside of FreeType). + * + * The color palette can be retrieved with @FT_Palette_Select. * * @return: - * FreeType error code. 0~means success. + * Value~1 if everything is OK. If there are no more layers (or if there + * are no layers at all), value~0 gets returned. In case of an error, + * value~0 is returned also. * * @note: - * The values of `*p_arg1', `*p_arg2', and `*p_transform' must be - * interpreted depending on the flags returned in `*p_flags'. See the - * OpenType specification for details. + * This function is necessary if you want to handle glyph layers by + * yourself. In particular, functions that operate with @FT_GlyphRec + * objects (like @FT_Get_Glyph or @FT_Glyph_To_Bitmap) don't have access + * to this information. + * + * Note that @FT_Render_Glyph is able to handle colored glyph layers + * automatically if the @FT_LOAD_COLOR flag is passed to a previous call + * to @FT_Load_Glyph. [This is an experimental feature.] + * + * @example: + * ``` + * FT_Color* palette; + * FT_LayerIterator iterator; + * + * FT_Bool have_layers; + * FT_UInt layer_glyph_index; + * FT_UInt layer_color_index; + * + * + * error = FT_Palette_Select( face, palette_index, &palette ); + * if ( error ) + * palette = NULL; * + * iterator.p = NULL; + * have_layers = FT_Get_Color_Glyph_Layer( face, + * glyph_index, + * &layer_glyph_index, + * &layer_color_index, + * &iterator ); + * + * if ( palette && have_layers ) + * { + * do + * { + * FT_Color layer_color; + * + * + * if ( layer_color_index == 0xFFFF ) + * layer_color = text_foreground_color; + * else + * layer_color = palette[layer_color_index]; + * + * // Load and render glyph `layer_glyph_index', then + * // blend resulting pixmap (using color `layer_color') + * // with previously created pixmaps. + * + * } while ( FT_Get_Color_Glyph_Layer( face, + * glyph_index, + * &layer_glyph_index, + * &layer_color_index, + * &iterator ) ); + * } + * ``` */ - FT_EXPORT( FT_Error ) - FT_Get_SubGlyph_Info( FT_GlyphSlot glyph, - FT_UInt sub_index, - FT_Int *p_index, - FT_UInt *p_flags, - FT_Int *p_arg1, - FT_Int *p_arg2, - FT_Matrix *p_transform ); + FT_EXPORT( FT_Bool ) + FT_Get_Color_Glyph_Layer( FT_Face face, + FT_UInt base_glyph, + FT_UInt *aglyph_index, + FT_UInt *acolor_index, + FT_LayerIterator* iterator ); - /*************************************************************************/ - /* */ - /* <Enum> */ - /* FT_FSTYPE_XXX */ - /* */ - /* <Description> */ - /* A list of bit flags used in the `fsType' field of the OS/2 table */ - /* in a TrueType or OpenType font and the `FSType' entry in a */ - /* PostScript font. These bit flags are returned by */ - /* @FT_Get_FSType_Flags; they inform client applications of embedding */ - /* and subsetting restrictions associated with a font. */ - /* */ - /* See */ - /* https://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/FontPolicies.pdf */ - /* for more details. */ - /* */ - /* <Values> */ - /* FT_FSTYPE_INSTALLABLE_EMBEDDING :: */ - /* Fonts with no fsType bit set may be embedded and permanently */ - /* installed on the remote system by an application. */ - /* */ - /* FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING :: */ - /* Fonts that have only this bit set must not be modified, embedded */ - /* or exchanged in any manner without first obtaining permission of */ - /* the font software copyright owner. */ - /* */ - /* FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING :: */ - /* The font may be embedded and temporarily loaded on the remote */ - /* system. Documents containing Preview & Print fonts must be */ - /* opened `read-only'; no edits can be applied to the document. */ - /* */ - /* FT_FSTYPE_EDITABLE_EMBEDDING :: */ - /* The font may be embedded but must only be installed temporarily */ - /* on other systems. In contrast to Preview & Print fonts, */ - /* documents containing editable fonts may be opened for reading, */ - /* editing is permitted, and changes may be saved. */ - /* */ - /* FT_FSTYPE_NO_SUBSETTING :: */ - /* The font may not be subsetted prior to embedding. */ - /* */ - /* FT_FSTYPE_BITMAP_EMBEDDING_ONLY :: */ - /* Only bitmaps contained in the font may be embedded; no outline */ - /* data may be embedded. If there are no bitmaps available in the */ - /* font, then the font is unembeddable. */ - /* */ - /* <Note> */ - /* The flags are ORed together, thus more than a single value can be */ - /* returned. */ - /* */ - /* While the `fsType' flags can indicate that a font may be embedded, */ - /* a license with the font vendor may be separately required to use */ - /* the font in this way. */ - /* */ + /************************************************************************** + * + * @section: + * base_interface + * + */ + + /************************************************************************** + * + * @enum: + * FT_FSTYPE_XXX + * + * @description: + * A list of bit flags used in the `fsType` field of the OS/2 table in a + * TrueType or OpenType font and the `FSType` entry in a PostScript font. + * These bit flags are returned by @FT_Get_FSType_Flags; they inform + * client applications of embedding and subsetting restrictions + * associated with a font. + * + * See + * https://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/FontPolicies.pdf + * for more details. + * + * @values: + * FT_FSTYPE_INSTALLABLE_EMBEDDING :: + * Fonts with no fsType bit set may be embedded and permanently + * installed on the remote system by an application. + * + * FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING :: + * Fonts that have only this bit set must not be modified, embedded or + * exchanged in any manner without first obtaining permission of the + * font software copyright owner. + * + * FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING :: + * The font may be embedded and temporarily loaded on the remote + * system. Documents containing Preview & Print fonts must be opened + * 'read-only'; no edits can be applied to the document. + * + * FT_FSTYPE_EDITABLE_EMBEDDING :: + * The font may be embedded but must only be installed temporarily on + * other systems. In contrast to Preview & Print fonts, documents + * containing editable fonts may be opened for reading, editing is + * permitted, and changes may be saved. + * + * FT_FSTYPE_NO_SUBSETTING :: + * The font may not be subsetted prior to embedding. + * + * FT_FSTYPE_BITMAP_EMBEDDING_ONLY :: + * Only bitmaps contained in the font may be embedded; no outline data + * may be embedded. If there are no bitmaps available in the font, + * then the font is unembeddable. + * + * @note: + * The flags are ORed together, thus more than a single value can be + * returned. + * + * While the `fsType` flags can indicate that a font may be embedded, a + * license with the font vendor may be separately required to use the + * font in this way. + */ #define FT_FSTYPE_INSTALLABLE_EMBEDDING 0x0000 #define FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING 0x0002 #define FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING 0x0004 @@ -4042,548 +4252,563 @@ FT_BEGIN_HEADER #define FT_FSTYPE_BITMAP_EMBEDDING_ONLY 0x0200 - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_FSType_Flags */ - /* */ - /* <Description> */ - /* Return the `fsType' flags for a font. */ - /* */ - /* <Input> */ - /* face :: A handle to the source face object. */ - /* */ - /* <Return> */ - /* The `fsType' flags, see @FT_FSTYPE_XXX. */ - /* */ - /* <Note> */ - /* Use this function rather than directly reading the `fs_type' field */ - /* in the @PS_FontInfoRec structure, which is only guaranteed to */ - /* return the correct results for Type~1 fonts. */ - /* */ - /* <Since> */ - /* 2.3.8 */ - /* */ + /************************************************************************** + * + * @function: + * FT_Get_FSType_Flags + * + * @description: + * Return the `fsType` flags for a font. + * + * @input: + * face :: + * A handle to the source face object. + * + * @return: + * The `fsType` flags, see @FT_FSTYPE_XXX. + * + * @note: + * Use this function rather than directly reading the `fs_type` field in + * the @PS_FontInfoRec structure, which is only guaranteed to return the + * correct results for Type~1 fonts. + * + * @since: + * 2.3.8 + */ FT_EXPORT( FT_UShort ) FT_Get_FSType_Flags( FT_Face face ); - /*************************************************************************/ - /* */ - /* <Section> */ - /* glyph_variants */ - /* */ - /* <Title> */ - /* Unicode Variation Sequences */ - /* */ - /* <Abstract> */ - /* The FreeType~2 interface to Unicode Variation Sequences (UVS), */ - /* using the SFNT cmap format~14. */ - /* */ - /* <Description> */ - /* Many characters, especially for CJK scripts, have variant forms. */ - /* They are a sort of grey area somewhere between being totally */ - /* irrelevant and semantically distinct; for this reason, the Unicode */ - /* consortium decided to introduce Variation Sequences (VS), */ - /* consisting of a Unicode base character and a variation selector */ - /* instead of further extending the already huge number of */ - /* characters. */ - /* */ - /* Unicode maintains two different sets, namely `Standardized */ - /* Variation Sequences' and registered `Ideographic Variation */ - /* Sequences' (IVS), collected in the `Ideographic Variation */ - /* Database' (IVD). */ - /* */ - /* https://unicode.org/Public/UCD/latest/ucd/StandardizedVariants.txt */ - /* https://unicode.org/reports/tr37/ */ - /* https://unicode.org/ivd/ */ - /* */ - /* To date (January 2017), the character with the most ideographic */ - /* variations is U+9089, having 32 such IVS. */ - /* */ - /* Three Mongolian Variation Selectors have the values U+180B-U+180D; */ - /* 256 generic Variation Selectors are encoded in the ranges */ - /* U+FE00-U+FE0F and U+E0100-U+E01EF. IVS currently use Variation */ - /* Selectors from the range U+E0100-U+E01EF only. */ - /* */ - /* A VS consists of the base character value followed by a single */ - /* Variation Selector. For example, to get the first variation of */ - /* U+9089, you have to write the character sequence `U+9089 U+E0100'. */ - /* */ - /* Adobe and MS decided to support both standardized and ideographic */ - /* VS with a new cmap subtable (format~14). It is an odd subtable */ - /* because it is not a mapping of input code points to glyphs, but */ - /* contains lists of all variations supported by the font. */ - /* */ - /* A variation may be either `default' or `non-default' for a given */ - /* font. A default variation is the one you will get for that code */ - /* point if you look it up in the standard Unicode cmap. A */ - /* non-default variation is a different glyph. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * @section: + * glyph_variants + * + * @title: + * Unicode Variation Sequences + * + * @abstract: + * The FreeType~2 interface to Unicode Variation Sequences (UVS), using + * the SFNT cmap format~14. + * + * @description: + * Many characters, especially for CJK scripts, have variant forms. They + * are a sort of grey area somewhere between being totally irrelevant and + * semantically distinct; for this reason, the Unicode consortium decided + * to introduce Variation Sequences (VS), consisting of a Unicode base + * character and a variation selector instead of further extending the + * already huge number of characters. + * + * Unicode maintains two different sets, namely 'Standardized Variation + * Sequences' and registered 'Ideographic Variation Sequences' (IVS), + * collected in the 'Ideographic Variation Database' (IVD). + * + * https://unicode.org/Public/UCD/latest/ucd/StandardizedVariants.txt + * https://unicode.org/reports/tr37/ https://unicode.org/ivd/ + * + * To date (January 2017), the character with the most ideographic + * variations is U+9089, having 32 such IVS. + * + * Three Mongolian Variation Selectors have the values U+180B-U+180D; 256 + * generic Variation Selectors are encoded in the ranges U+FE00-U+FE0F + * and U+E0100-U+E01EF. IVS currently use Variation Selectors from the + * range U+E0100-U+E01EF only. + * + * A VS consists of the base character value followed by a single + * Variation Selector. For example, to get the first variation of + * U+9089, you have to write the character sequence `U+9089 U+E0100`. + * + * Adobe and MS decided to support both standardized and ideographic VS + * with a new cmap subtable (format~14). It is an odd subtable because + * it is not a mapping of input code points to glyphs, but contains lists + * of all variations supported by the font. + * + * A variation may be either 'default' or 'non-default' for a given font. + * A default variation is the one you will get for that code point if you + * look it up in the standard Unicode cmap. A non-default variation is a + * different glyph. + * + */ - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Face_GetCharVariantIndex */ - /* */ - /* <Description> */ - /* Return the glyph index of a given character code as modified by */ - /* the variation selector. */ - /* */ - /* <Input> */ - /* face :: */ - /* A handle to the source face object. */ - /* */ - /* charcode :: */ - /* The character code point in Unicode. */ - /* */ - /* variantSelector :: */ - /* The Unicode code point of the variation selector. */ - /* */ - /* <Return> */ - /* The glyph index. 0~means either `undefined character code', or */ - /* `undefined selector code', or `no variation selector cmap */ - /* subtable', or `current CharMap is not Unicode'. */ - /* */ - /* <Note> */ - /* If you use FreeType to manipulate the contents of font files */ - /* directly, be aware that the glyph index returned by this function */ - /* doesn't always correspond to the internal indices used within */ - /* the file. This is done to ensure that value~0 always corresponds */ - /* to the `missing glyph'. */ - /* */ - /* This function is only meaningful if */ - /* a) the font has a variation selector cmap sub table, */ - /* and */ - /* b) the current charmap has a Unicode encoding. */ - /* */ - /* <Since> */ - /* 2.3.6 */ - /* */ + /************************************************************************** + * + * @function: + * FT_Face_GetCharVariantIndex + * + * @description: + * Return the glyph index of a given character code as modified by the + * variation selector. + * + * @input: + * face :: + * A handle to the source face object. + * + * charcode :: + * The character code point in Unicode. + * + * variantSelector :: + * The Unicode code point of the variation selector. + * + * @return: + * The glyph index. 0~means either 'undefined character code', or + * 'undefined selector code', or 'no variation selector cmap subtable', + * or 'current CharMap is not Unicode'. + * + * @note: + * If you use FreeType to manipulate the contents of font files directly, + * be aware that the glyph index returned by this function doesn't always + * correspond to the internal indices used within the file. This is done + * to ensure that value~0 always corresponds to the 'missing glyph'. + * + * This function is only meaningful if + * a) the font has a variation selector cmap sub table, and + * b) the current charmap has a Unicode encoding. + * + * @since: + * 2.3.6 + */ FT_EXPORT( FT_UInt ) FT_Face_GetCharVariantIndex( FT_Face face, FT_ULong charcode, FT_ULong variantSelector ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Face_GetCharVariantIsDefault */ - /* */ - /* <Description> */ - /* Check whether this variation of this Unicode character is the one */ - /* to be found in the `cmap'. */ - /* */ - /* <Input> */ - /* face :: */ - /* A handle to the source face object. */ - /* */ - /* charcode :: */ - /* The character codepoint in Unicode. */ - /* */ - /* variantSelector :: */ - /* The Unicode codepoint of the variation selector. */ - /* */ - /* <Return> */ - /* 1~if found in the standard (Unicode) cmap, 0~if found in the */ - /* variation selector cmap, or -1 if it is not a variation. */ - /* */ - /* <Note> */ - /* This function is only meaningful if the font has a variation */ - /* selector cmap subtable. */ - /* */ - /* <Since> */ - /* 2.3.6 */ - /* */ + /************************************************************************** + * + * @function: + * FT_Face_GetCharVariantIsDefault + * + * @description: + * Check whether this variation of this Unicode character is the one to + * be found in the charmap. + * + * @input: + * face :: + * A handle to the source face object. + * + * charcode :: + * The character codepoint in Unicode. + * + * variantSelector :: + * The Unicode codepoint of the variation selector. + * + * @return: + * 1~if found in the standard (Unicode) cmap, 0~if found in the variation + * selector cmap, or -1 if it is not a variation. + * + * @note: + * This function is only meaningful if the font has a variation selector + * cmap subtable. + * + * @since: + * 2.3.6 + */ FT_EXPORT( FT_Int ) FT_Face_GetCharVariantIsDefault( FT_Face face, FT_ULong charcode, FT_ULong variantSelector ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Face_GetVariantSelectors */ - /* */ - /* <Description> */ - /* Return a zero-terminated list of Unicode variation selectors found */ - /* in the font. */ - /* */ - /* <Input> */ - /* face :: */ - /* A handle to the source face object. */ - /* */ - /* <Return> */ - /* A pointer to an array of selector code points, or NULL if there is */ - /* no valid variation selector cmap subtable. */ - /* */ - /* <Note> */ - /* The last item in the array is~0; the array is owned by the */ - /* @FT_Face object but can be overwritten or released on the next */ - /* call to a FreeType function. */ - /* */ - /* <Since> */ - /* 2.3.6 */ - /* */ + /************************************************************************** + * + * @function: + * FT_Face_GetVariantSelectors + * + * @description: + * Return a zero-terminated list of Unicode variation selectors found in + * the font. + * + * @input: + * face :: + * A handle to the source face object. + * + * @return: + * A pointer to an array of selector code points, or `NULL` if there is + * no valid variation selector cmap subtable. + * + * @note: + * The last item in the array is~0; the array is owned by the @FT_Face + * object but can be overwritten or released on the next call to a + * FreeType function. + * + * @since: + * 2.3.6 + */ FT_EXPORT( FT_UInt32* ) FT_Face_GetVariantSelectors( FT_Face face ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Face_GetVariantsOfChar */ - /* */ - /* <Description> */ - /* Return a zero-terminated list of Unicode variation selectors found */ - /* for the specified character code. */ - /* */ - /* <Input> */ - /* face :: */ - /* A handle to the source face object. */ - /* */ - /* charcode :: */ - /* The character codepoint in Unicode. */ - /* */ - /* <Return> */ - /* A pointer to an array of variation selector code points that are */ - /* active for the given character, or NULL if the corresponding list */ - /* is empty. */ - /* */ - /* <Note> */ - /* The last item in the array is~0; the array is owned by the */ - /* @FT_Face object but can be overwritten or released on the next */ - /* call to a FreeType function. */ - /* */ - /* <Since> */ - /* 2.3.6 */ - /* */ + /************************************************************************** + * + * @function: + * FT_Face_GetVariantsOfChar + * + * @description: + * Return a zero-terminated list of Unicode variation selectors found for + * the specified character code. + * + * @input: + * face :: + * A handle to the source face object. + * + * charcode :: + * The character codepoint in Unicode. + * + * @return: + * A pointer to an array of variation selector code points that are + * active for the given character, or `NULL` if the corresponding list is + * empty. + * + * @note: + * The last item in the array is~0; the array is owned by the @FT_Face + * object but can be overwritten or released on the next call to a + * FreeType function. + * + * @since: + * 2.3.6 + */ FT_EXPORT( FT_UInt32* ) FT_Face_GetVariantsOfChar( FT_Face face, FT_ULong charcode ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Face_GetCharsOfVariant */ - /* */ - /* <Description> */ - /* Return a zero-terminated list of Unicode character codes found for */ - /* the specified variation selector. */ - /* */ - /* <Input> */ - /* face :: */ - /* A handle to the source face object. */ - /* */ - /* variantSelector :: */ - /* The variation selector code point in Unicode. */ - /* */ - /* <Return> */ - /* A list of all the code points that are specified by this selector */ - /* (both default and non-default codes are returned) or NULL if there */ - /* is no valid cmap or the variation selector is invalid. */ - /* */ - /* <Note> */ - /* The last item in the array is~0; the array is owned by the */ - /* @FT_Face object but can be overwritten or released on the next */ - /* call to a FreeType function. */ - /* */ - /* <Since> */ - /* 2.3.6 */ - /* */ + /************************************************************************** + * + * @function: + * FT_Face_GetCharsOfVariant + * + * @description: + * Return a zero-terminated list of Unicode character codes found for the + * specified variation selector. + * + * @input: + * face :: + * A handle to the source face object. + * + * variantSelector :: + * The variation selector code point in Unicode. + * + * @return: + * A list of all the code points that are specified by this selector + * (both default and non-default codes are returned) or `NULL` if there + * is no valid cmap or the variation selector is invalid. + * + * @note: + * The last item in the array is~0; the array is owned by the @FT_Face + * object but can be overwritten or released on the next call to a + * FreeType function. + * + * @since: + * 2.3.6 + */ FT_EXPORT( FT_UInt32* ) FT_Face_GetCharsOfVariant( FT_Face face, FT_ULong variantSelector ); - /*************************************************************************/ - /* */ - /* <Section> */ - /* computations */ - /* */ - /* <Title> */ - /* Computations */ - /* */ - /* <Abstract> */ - /* Crunching fixed numbers and vectors. */ - /* */ - /* <Description> */ - /* This section contains various functions used to perform */ - /* computations on 16.16 fixed-float numbers or 2d vectors. */ - /* */ - /* <Order> */ - /* FT_MulDiv */ - /* FT_MulFix */ - /* FT_DivFix */ - /* FT_RoundFix */ - /* FT_CeilFix */ - /* FT_FloorFix */ - /* FT_Vector_Transform */ - /* FT_Matrix_Multiply */ - /* FT_Matrix_Invert */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * @section: + * computations + * + * @title: + * Computations + * + * @abstract: + * Crunching fixed numbers and vectors. + * + * @description: + * This section contains various functions used to perform computations + * on 16.16 fixed-float numbers or 2d vectors. + * + * **Attention**: Most arithmetic functions take `FT_Long` as arguments. + * For historical reasons, FreeType was designed under the assumption + * that `FT_Long` is a 32-bit integer; results can thus be undefined if + * the arguments don't fit into 32 bits. + * + * @order: + * FT_MulDiv + * FT_MulFix + * FT_DivFix + * FT_RoundFix + * FT_CeilFix + * FT_FloorFix + * FT_Vector_Transform + * FT_Matrix_Multiply + * FT_Matrix_Invert + * + */ - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_MulDiv */ - /* */ - /* <Description> */ - /* Compute `(a*b)/c' with maximum accuracy, using a 64-bit */ - /* intermediate integer whenever necessary. */ - /* */ - /* This function isn't necessarily as fast as some processor specific */ - /* operations, but is at least completely portable. */ - /* */ - /* <Input> */ - /* a :: The first multiplier. */ - /* */ - /* b :: The second multiplier. */ - /* */ - /* c :: The divisor. */ - /* */ - /* <Return> */ - /* The result of `(a*b)/c'. This function never traps when trying to */ - /* divide by zero; it simply returns `MaxInt' or `MinInt' depending */ - /* on the signs of `a' and `b'. */ - /* */ + /************************************************************************** + * + * @function: + * FT_MulDiv + * + * @description: + * Compute `(a*b)/c` with maximum accuracy, using a 64-bit intermediate + * integer whenever necessary. + * + * This function isn't necessarily as fast as some processor-specific + * operations, but is at least completely portable. + * + * @input: + * a :: + * The first multiplier. + * + * b :: + * The second multiplier. + * + * c :: + * The divisor. + * + * @return: + * The result of `(a*b)/c`. This function never traps when trying to + * divide by zero; it simply returns 'MaxInt' or 'MinInt' depending on + * the signs of `a` and `b`. + */ FT_EXPORT( FT_Long ) FT_MulDiv( FT_Long a, FT_Long b, FT_Long c ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_MulFix */ - /* */ - /* <Description> */ - /* Compute `(a*b)/0x10000' with maximum accuracy. Its main use is to */ - /* multiply a given value by a 16.16 fixed-point factor. */ - /* */ - /* <Input> */ - /* a :: The first multiplier. */ - /* */ - /* b :: The second multiplier. Use a 16.16 factor here whenever */ - /* possible (see note below). */ - /* */ - /* <Return> */ - /* The result of `(a*b)/0x10000'. */ - /* */ - /* <Note> */ - /* This function has been optimized for the case where the absolute */ - /* value of `a' is less than 2048, and `b' is a 16.16 scaling factor. */ - /* As this happens mainly when scaling from notional units to */ - /* fractional pixels in FreeType, it resulted in noticeable speed */ - /* improvements between versions 2.x and 1.x. */ - /* */ - /* As a conclusion, always try to place a 16.16 factor as the */ - /* _second_ argument of this function; this can make a great */ - /* difference. */ - /* */ + /************************************************************************** + * + * @function: + * FT_MulFix + * + * @description: + * Compute `(a*b)/0x10000` with maximum accuracy. Its main use is to + * multiply a given value by a 16.16 fixed-point factor. + * + * @input: + * a :: + * The first multiplier. + * + * b :: + * The second multiplier. Use a 16.16 factor here whenever possible + * (see note below). + * + * @return: + * The result of `(a*b)/0x10000`. + * + * @note: + * This function has been optimized for the case where the absolute value + * of `a` is less than 2048, and `b` is a 16.16 scaling factor. As this + * happens mainly when scaling from notional units to fractional pixels + * in FreeType, it resulted in noticeable speed improvements between + * versions 2.x and 1.x. + * + * As a conclusion, always try to place a 16.16 factor as the _second_ + * argument of this function; this can make a great difference. + */ FT_EXPORT( FT_Long ) FT_MulFix( FT_Long a, FT_Long b ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_DivFix */ - /* */ - /* <Description> */ - /* Compute `(a*0x10000)/b' with maximum accuracy. Its main use is to */ - /* divide a given value by a 16.16 fixed-point factor. */ - /* */ - /* <Input> */ - /* a :: The numerator. */ - /* */ - /* b :: The denominator. Use a 16.16 factor here. */ - /* */ - /* <Return> */ - /* The result of `(a*0x10000)/b'. */ - /* */ + /************************************************************************** + * + * @function: + * FT_DivFix + * + * @description: + * Compute `(a*0x10000)/b` with maximum accuracy. Its main use is to + * divide a given value by a 16.16 fixed-point factor. + * + * @input: + * a :: + * The numerator. + * + * b :: + * The denominator. Use a 16.16 factor here. + * + * @return: + * The result of `(a*0x10000)/b`. + */ FT_EXPORT( FT_Long ) FT_DivFix( FT_Long a, FT_Long b ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_RoundFix */ - /* */ - /* <Description> */ - /* Round a 16.16 fixed number. */ - /* */ - /* <Input> */ - /* a :: The number to be rounded. */ - /* */ - /* <Return> */ - /* `a' rounded to the nearest 16.16 fixed integer, halfway cases away */ - /* from zero. */ - /* */ - /* <Note> */ - /* The function uses wrap-around arithmetic. */ - /* */ + /************************************************************************** + * + * @function: + * FT_RoundFix + * + * @description: + * Round a 16.16 fixed number. + * + * @input: + * a :: + * The number to be rounded. + * + * @return: + * `a` rounded to the nearest 16.16 fixed integer, halfway cases away + * from zero. + * + * @note: + * The function uses wrap-around arithmetic. + */ FT_EXPORT( FT_Fixed ) FT_RoundFix( FT_Fixed a ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_CeilFix */ - /* */ - /* <Description> */ - /* Compute the smallest following integer of a 16.16 fixed number. */ - /* */ - /* <Input> */ - /* a :: The number for which the ceiling function is to be computed. */ - /* */ - /* <Return> */ - /* `a' rounded towards plus infinity. */ - /* */ - /* <Note> */ - /* The function uses wrap-around arithmetic. */ - /* */ + /************************************************************************** + * + * @function: + * FT_CeilFix + * + * @description: + * Compute the smallest following integer of a 16.16 fixed number. + * + * @input: + * a :: + * The number for which the ceiling function is to be computed. + * + * @return: + * `a` rounded towards plus infinity. + * + * @note: + * The function uses wrap-around arithmetic. + */ FT_EXPORT( FT_Fixed ) FT_CeilFix( FT_Fixed a ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_FloorFix */ - /* */ - /* <Description> */ - /* Compute the largest previous integer of a 16.16 fixed number. */ - /* */ - /* <Input> */ - /* a :: The number for which the floor function is to be computed. */ - /* */ - /* <Return> */ - /* `a' rounded towards minus infinity. */ - /* */ + /************************************************************************** + * + * @function: + * FT_FloorFix + * + * @description: + * Compute the largest previous integer of a 16.16 fixed number. + * + * @input: + * a :: + * The number for which the floor function is to be computed. + * + * @return: + * `a` rounded towards minus infinity. + */ FT_EXPORT( FT_Fixed ) FT_FloorFix( FT_Fixed a ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Vector_Transform */ - /* */ - /* <Description> */ - /* Transform a single vector through a 2x2 matrix. */ - /* */ - /* <InOut> */ - /* vector :: The target vector to transform. */ - /* */ - /* <Input> */ - /* matrix :: A pointer to the source 2x2 matrix. */ - /* */ - /* <Note> */ - /* The result is undefined if either `vector' or `matrix' is invalid. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Vector_Transform + * + * @description: + * Transform a single vector through a 2x2 matrix. + * + * @inout: + * vector :: + * The target vector to transform. + * + * @input: + * matrix :: + * A pointer to the source 2x2 matrix. + * + * @note: + * The result is undefined if either `vector` or `matrix` is invalid. + */ FT_EXPORT( void ) - FT_Vector_Transform( FT_Vector* vec, + FT_Vector_Transform( FT_Vector* vector, const FT_Matrix* matrix ); - /*************************************************************************/ - /* */ - /* <Section> */ - /* version */ - /* */ - /* <Title> */ - /* FreeType Version */ - /* */ - /* <Abstract> */ - /* Functions and macros related to FreeType versions. */ - /* */ - /* <Description> */ - /* Note that those functions and macros are of limited use because */ - /* even a new release of FreeType with only documentation changes */ - /* increases the version number. */ - /* */ - /* <Order> */ - /* FT_Library_Version */ - /* */ - /* FREETYPE_MAJOR */ - /* FREETYPE_MINOR */ - /* FREETYPE_PATCH */ - /* */ - /* FT_Face_CheckTrueTypePatents */ - /* FT_Face_SetUnpatentedHinting */ - /* */ - /* FREETYPE_XXX */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * @section: + * version + * + * @title: + * FreeType Version + * + * @abstract: + * Functions and macros related to FreeType versions. + * + * @description: + * Note that those functions and macros are of limited use because even a + * new release of FreeType with only documentation changes increases the + * version number. + * + * @order: + * FT_Library_Version + * + * FREETYPE_MAJOR + * FREETYPE_MINOR + * FREETYPE_PATCH + * + * FT_Face_CheckTrueTypePatents + * FT_Face_SetUnpatentedHinting + * + */ - /************************************************************************* + /************************************************************************** * * @enum: * FREETYPE_XXX * * @description: - * These three macros identify the FreeType source code version. - * Use @FT_Library_Version to access them at runtime. + * These three macros identify the FreeType source code version. Use + * @FT_Library_Version to access them at runtime. * * @values: - * FREETYPE_MAJOR :: The major version number. - * FREETYPE_MINOR :: The minor version number. - * FREETYPE_PATCH :: The patch level. + * FREETYPE_MAJOR :: + * The major version number. + * FREETYPE_MINOR :: + * The minor version number. + * FREETYPE_PATCH :: + * The patch level. * * @note: - * The version number of FreeType if built as a dynamic link library - * with the `libtool' package is _not_ controlled by these three - * macros. + * The version number of FreeType if built as a dynamic link library with + * the 'libtool' package is _not_ controlled by these three macros. * */ #define FREETYPE_MAJOR 2 -#define FREETYPE_MINOR 9 +#define FREETYPE_MINOR 10 #define FREETYPE_PATCH 0 - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Library_Version */ - /* */ - /* <Description> */ - /* Return the version of the FreeType library being used. This is */ - /* useful when dynamically linking to the library, since one cannot */ - /* use the macros @FREETYPE_MAJOR, @FREETYPE_MINOR, and */ - /* @FREETYPE_PATCH. */ - /* */ - /* <Input> */ - /* library :: A source library handle. */ - /* */ - /* <Output> */ - /* amajor :: The major version number. */ - /* */ - /* aminor :: The minor version number. */ - /* */ - /* apatch :: The patch version number. */ - /* */ - /* <Note> */ - /* The reason why this function takes a `library' argument is because */ - /* certain programs implement library initialization in a custom way */ - /* that doesn't use @FT_Init_FreeType. */ - /* */ - /* In such cases, the library version might not be available before */ - /* the library object has been created. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Library_Version + * + * @description: + * Return the version of the FreeType library being used. This is useful + * when dynamically linking to the library, since one cannot use the + * macros @FREETYPE_MAJOR, @FREETYPE_MINOR, and @FREETYPE_PATCH. + * + * @input: + * library :: + * A source library handle. + * + * @output: + * amajor :: + * The major version number. + * + * aminor :: + * The minor version number. + * + * apatch :: + * The patch version number. + * + * @note: + * The reason why this function takes a `library` argument is because + * certain programs implement library initialization in a custom way that + * doesn't use @FT_Init_FreeType. + * + * In such cases, the library version might not be available before the + * library object has been created. + */ FT_EXPORT( void ) FT_Library_Version( FT_Library library, FT_Int *amajor, @@ -4591,52 +4816,55 @@ FT_BEGIN_HEADER FT_Int *apatch ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Face_CheckTrueTypePatents */ - /* */ - /* <Description> */ - /* Deprecated, does nothing. */ - /* */ - /* <Input> */ - /* face :: A face handle. */ - /* */ - /* <Return> */ - /* Always returns false. */ - /* */ - /* <Note> */ - /* Since May 2010, TrueType hinting is no longer patented. */ - /* */ - /* <Since> */ - /* 2.3.5 */ - /* */ + /************************************************************************** + * + * @function: + * FT_Face_CheckTrueTypePatents + * + * @description: + * Deprecated, does nothing. + * + * @input: + * face :: + * A face handle. + * + * @return: + * Always returns false. + * + * @note: + * Since May 2010, TrueType hinting is no longer patented. + * + * @since: + * 2.3.5 + */ FT_EXPORT( FT_Bool ) FT_Face_CheckTrueTypePatents( FT_Face face ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Face_SetUnpatentedHinting */ - /* */ - /* <Description> */ - /* Deprecated, does nothing. */ - /* */ - /* <Input> */ - /* face :: A face handle. */ - /* */ - /* value :: New boolean setting. */ - /* */ - /* <Return> */ - /* Always returns false. */ - /* */ - /* <Note> */ - /* Since May 2010, TrueType hinting is no longer patented. */ - /* */ - /* <Since> */ - /* 2.3.5 */ - /* */ + /************************************************************************** + * + * @function: + * FT_Face_SetUnpatentedHinting + * + * @description: + * Deprecated, does nothing. + * + * @input: + * face :: + * A face handle. + * + * value :: + * New boolean setting. + * + * @return: + * Always returns false. + * + * @note: + * Since May 2010, TrueType hinting is no longer patented. + * + * @since: + * 2.3.5 + */ FT_EXPORT( FT_Bool ) FT_Face_SetUnpatentedHinting( FT_Face face, FT_Bool value ); diff --git a/sdk/lib/3rdparty/freetype/include/freetype/ftadvanc.h b/sdk/lib/3rdparty/freetype/include/freetype/ftadvanc.h index f78e8b1a9d16e..95c38f92bdd22 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/ftadvanc.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/ftadvanc.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftadvanc.h */ -/* */ -/* Quick computation of advance widths (specification only). */ -/* */ -/* Copyright 2008-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftadvanc.h + * + * Quick computation of advance widths (specification only). + * + * Copyright (C) 2008-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTADVANC_H_ @@ -56,68 +56,67 @@ FT_BEGIN_HEADER */ - /*************************************************************************/ - /* */ - /* <Const> */ - /* FT_ADVANCE_FLAG_FAST_ONLY */ - /* */ - /* <Description> */ - /* A bit-flag to be OR-ed with the `flags' parameter of the */ - /* @FT_Get_Advance and @FT_Get_Advances functions. */ - /* */ - /* If set, it indicates that you want these functions to fail if the */ - /* corresponding hinting mode or font driver doesn't allow for very */ - /* quick advance computation. */ - /* */ - /* Typically, glyphs that are either unscaled, unhinted, bitmapped, */ - /* or light-hinted can have their advance width computed very */ - /* quickly. */ - /* */ - /* Normal and bytecode hinted modes that require loading, scaling, */ - /* and hinting of the glyph outline, are extremely slow by */ - /* comparison. */ - /* */ + /************************************************************************** + * + * @enum: + * FT_ADVANCE_FLAG_FAST_ONLY + * + * @description: + * A bit-flag to be OR-ed with the `flags` parameter of the + * @FT_Get_Advance and @FT_Get_Advances functions. + * + * If set, it indicates that you want these functions to fail if the + * corresponding hinting mode or font driver doesn't allow for very quick + * advance computation. + * + * Typically, glyphs that are either unscaled, unhinted, bitmapped, or + * light-hinted can have their advance width computed very quickly. + * + * Normal and bytecode hinted modes that require loading, scaling, and + * hinting of the glyph outline, are extremely slow by comparison. + */ #define FT_ADVANCE_FLAG_FAST_ONLY 0x20000000L - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_Advance */ - /* */ - /* <Description> */ - /* Retrieve the advance value of a given glyph outline in an */ - /* @FT_Face. */ - /* */ - /* <Input> */ - /* face :: The source @FT_Face handle. */ - /* */ - /* gindex :: The glyph index. */ - /* */ - /* load_flags :: A set of bit flags similar to those used when */ - /* calling @FT_Load_Glyph, used to determine what kind */ - /* of advances you need. */ - /* <Output> */ - /* padvance :: The advance value. If scaling is performed (based on */ - /* the value of `load_flags'), the advance value is in */ - /* 16.16 format. Otherwise, it is in font units. */ - /* */ - /* If @FT_LOAD_VERTICAL_LAYOUT is set, this is the */ - /* vertical advance corresponding to a vertical layout. */ - /* Otherwise, it is the horizontal advance in a */ - /* horizontal layout. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - /* <Note> */ - /* This function may fail if you use @FT_ADVANCE_FLAG_FAST_ONLY and */ - /* if the corresponding font backend doesn't have a quick way to */ - /* retrieve the advances. */ - /* */ - /* A scaled advance is returned in 16.16 format but isn't transformed */ - /* by the affine transformation specified by @FT_Set_Transform. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Get_Advance + * + * @description: + * Retrieve the advance value of a given glyph outline in an @FT_Face. + * + * @input: + * face :: + * The source @FT_Face handle. + * + * gindex :: + * The glyph index. + * + * load_flags :: + * A set of bit flags similar to those used when calling + * @FT_Load_Glyph, used to determine what kind of advances you need. + * @output: + * padvance :: + * The advance value. If scaling is performed (based on the value of + * `load_flags`), the advance value is in 16.16 format. Otherwise, it + * is in font units. + * + * If @FT_LOAD_VERTICAL_LAYOUT is set, this is the vertical advance + * corresponding to a vertical layout. Otherwise, it is the horizontal + * advance in a horizontal layout. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * This function may fail if you use @FT_ADVANCE_FLAG_FAST_ONLY and if + * the corresponding font backend doesn't have a quick way to retrieve + * the advances. + * + * A scaled advance is returned in 16.16 format but isn't transformed by + * the affine transformation specified by @FT_Set_Transform. + */ FT_EXPORT( FT_Error ) FT_Get_Advance( FT_Face face, FT_UInt gindex, @@ -125,50 +124,52 @@ FT_BEGIN_HEADER FT_Fixed *padvance ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_Advances */ - /* */ - /* <Description> */ - /* Retrieve the advance values of several glyph outlines in an */ - /* @FT_Face. */ - /* */ - /* <Input> */ - /* face :: The source @FT_Face handle. */ - /* */ - /* start :: The first glyph index. */ - /* */ - /* count :: The number of advance values you want to retrieve. */ - /* */ - /* load_flags :: A set of bit flags similar to those used when */ - /* calling @FT_Load_Glyph. */ - /* */ - /* <Output> */ - /* padvance :: The advance values. This array, to be provided by the */ - /* caller, must contain at least `count' elements. */ - /* */ - /* If scaling is performed (based on the value of */ - /* `load_flags'), the advance values are in 16.16 format. */ - /* Otherwise, they are in font units. */ - /* */ - /* If @FT_LOAD_VERTICAL_LAYOUT is set, these are the */ - /* vertical advances corresponding to a vertical layout. */ - /* Otherwise, they are the horizontal advances in a */ - /* horizontal layout. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - /* <Note> */ - /* This function may fail if you use @FT_ADVANCE_FLAG_FAST_ONLY and */ - /* if the corresponding font backend doesn't have a quick way to */ - /* retrieve the advances. */ - /* */ - /* Scaled advances are returned in 16.16 format but aren't */ - /* transformed by the affine transformation specified by */ - /* @FT_Set_Transform. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Get_Advances + * + * @description: + * Retrieve the advance values of several glyph outlines in an @FT_Face. + * + * @input: + * face :: + * The source @FT_Face handle. + * + * start :: + * The first glyph index. + * + * count :: + * The number of advance values you want to retrieve. + * + * load_flags :: + * A set of bit flags similar to those used when calling + * @FT_Load_Glyph. + * + * @output: + * padvance :: + * The advance values. This array, to be provided by the caller, must + * contain at least `count` elements. + * + * If scaling is performed (based on the value of `load_flags`), the + * advance values are in 16.16 format. Otherwise, they are in font + * units. + * + * If @FT_LOAD_VERTICAL_LAYOUT is set, these are the vertical advances + * corresponding to a vertical layout. Otherwise, they are the + * horizontal advances in a horizontal layout. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * This function may fail if you use @FT_ADVANCE_FLAG_FAST_ONLY and if + * the corresponding font backend doesn't have a quick way to retrieve + * the advances. + * + * Scaled advances are returned in 16.16 format but aren't transformed by + * the affine transformation specified by @FT_Set_Transform. + */ FT_EXPORT( FT_Error ) FT_Get_Advances( FT_Face face, FT_UInt start, diff --git a/sdk/lib/3rdparty/freetype/include/freetype/ftbbox.h b/sdk/lib/3rdparty/freetype/include/freetype/ftbbox.h index f9eb70b137360..22da70c0dc34b 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/ftbbox.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/ftbbox.h @@ -1,30 +1,30 @@ -/***************************************************************************/ -/* */ -/* ftbbox.h */ -/* */ -/* FreeType exact bbox computation (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This component has a _single_ role: to compute exact outline bounding */ - /* boxes. */ - /* */ - /* It is separated from the rest of the engine for various technical */ - /* reasons. It may well be integrated in `ftoutln' later. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * ftbbox.h + * + * FreeType exact bbox computation (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /************************************************************************** + * + * This component has a _single_ role: to compute exact outline bounding + * boxes. + * + * It is separated from the rest of the engine for various technical + * reasons. It may well be integrated in 'ftoutln' later. + * + */ #ifndef FTBBOX_H_ @@ -44,43 +44,44 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* <Section> */ - /* outline_processing */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Outline_Get_BBox */ - /* */ - /* <Description> */ - /* Compute the exact bounding box of an outline. This is slower */ - /* than computing the control box. However, it uses an advanced */ - /* algorithm that returns _very_ quickly when the two boxes */ - /* coincide. Otherwise, the outline Bezier arcs are traversed to */ - /* extract their extrema. */ - /* */ - /* <Input> */ - /* outline :: A pointer to the source outline. */ - /* */ - /* <Output> */ - /* abbox :: The outline's exact bounding box. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* If the font is tricky and the glyph has been loaded with */ - /* @FT_LOAD_NO_SCALE, the resulting BBox is meaningless. To get */ - /* reasonable values for the BBox it is necessary to load the glyph */ - /* at a large ppem value (so that the hinting instructions can */ - /* properly shift and scale the subglyphs), then extracting the BBox, */ - /* which can be eventually converted back to font units. */ - /* */ + /************************************************************************** + * + * @section: + * outline_processing + * + */ + + + /************************************************************************** + * + * @function: + * FT_Outline_Get_BBox + * + * @description: + * Compute the exact bounding box of an outline. This is slower than + * computing the control box. However, it uses an advanced algorithm + * that returns _very_ quickly when the two boxes coincide. Otherwise, + * the outline Bezier arcs are traversed to extract their extrema. + * + * @input: + * outline :: + * A pointer to the source outline. + * + * @output: + * abbox :: + * The outline's exact bounding box. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * If the font is tricky and the glyph has been loaded with + * @FT_LOAD_NO_SCALE, the resulting BBox is meaningless. To get + * reasonable values for the BBox it is necessary to load the glyph at a + * large ppem value (so that the hinting instructions can properly shift + * and scale the subglyphs), then extracting the BBox, which can be + * eventually converted back to font units. + */ FT_EXPORT( FT_Error ) FT_Outline_Get_BBox( FT_Outline* outline, FT_BBox *abbox ); diff --git a/sdk/lib/3rdparty/freetype/include/freetype/ftbdf.h b/sdk/lib/3rdparty/freetype/include/freetype/ftbdf.h index 1b6dea65863ad..1c46da5985d95 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/ftbdf.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/ftbdf.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftbdf.h */ -/* */ -/* FreeType API for accessing BDF-specific strings (specification). */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftbdf.h + * + * FreeType API for accessing BDF-specific strings (specification). + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTBDF_H_ @@ -32,25 +32,25 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* <Section> */ - /* bdf_fonts */ - /* */ - /* <Title> */ - /* BDF and PCF Files */ - /* */ - /* <Abstract> */ - /* BDF and PCF specific API. */ - /* */ - /* <Description> */ - /* This section contains the declaration of functions specific to BDF */ - /* and PCF fonts. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * @section: + * bdf_fonts + * + * @title: + * BDF and PCF Files + * + * @abstract: + * BDF and PCF specific API. + * + * @description: + * This section contains the declaration of functions specific to BDF and + * PCF fonts. + * + */ - /********************************************************************** + /************************************************************************** * * @enum: * BDF_PropertyType @@ -81,40 +81,40 @@ FT_BEGIN_HEADER } BDF_PropertyType; - /********************************************************************** + /************************************************************************** * * @type: * BDF_Property * * @description: - * A handle to a @BDF_PropertyRec structure to model a given - * BDF/PCF property. + * A handle to a @BDF_PropertyRec structure to model a given BDF/PCF + * property. */ typedef struct BDF_PropertyRec_* BDF_Property; - /********************************************************************** - * - * @struct: - * BDF_PropertyRec - * - * @description: - * This structure models a given BDF/PCF property. - * - * @fields: - * type :: - * The property type. - * - * u.atom :: - * The atom string, if type is @BDF_PROPERTY_TYPE_ATOM. May be - * NULL, indicating an empty string. - * - * u.integer :: - * A signed integer, if type is @BDF_PROPERTY_TYPE_INTEGER. - * - * u.cardinal :: - * An unsigned integer, if type is @BDF_PROPERTY_TYPE_CARDINAL. - */ + /************************************************************************** + * + * @struct: + * BDF_PropertyRec + * + * @description: + * This structure models a given BDF/PCF property. + * + * @fields: + * type :: + * The property type. + * + * u.atom :: + * The atom string, if type is @BDF_PROPERTY_TYPE_ATOM. May be + * `NULL`, indicating an empty string. + * + * u.integer :: + * A signed integer, if type is @BDF_PROPERTY_TYPE_INTEGER. + * + * u.cardinal :: + * An unsigned integer, if type is @BDF_PROPERTY_TYPE_CARDINAL. + */ typedef struct BDF_PropertyRec_ { BDF_PropertyType type; @@ -128,73 +128,76 @@ FT_BEGIN_HEADER } BDF_PropertyRec; - /********************************************************************** - * - * @function: - * FT_Get_BDF_Charset_ID - * - * @description: - * Retrieve a BDF font character set identity, according to - * the BDF specification. - * - * @input: - * face :: - * A handle to the input face. - * - * @output: - * acharset_encoding :: - * Charset encoding, as a C~string, owned by the face. - * - * acharset_registry :: - * Charset registry, as a C~string, owned by the face. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * This function only works with BDF faces, returning an error otherwise. - */ + /************************************************************************** + * + * @function: + * FT_Get_BDF_Charset_ID + * + * @description: + * Retrieve a BDF font character set identity, according to the BDF + * specification. + * + * @input: + * face :: + * A handle to the input face. + * + * @output: + * acharset_encoding :: + * Charset encoding, as a C~string, owned by the face. + * + * acharset_registry :: + * Charset registry, as a C~string, owned by the face. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with BDF faces, returning an error otherwise. + */ FT_EXPORT( FT_Error ) FT_Get_BDF_Charset_ID( FT_Face face, const char* *acharset_encoding, const char* *acharset_registry ); - /********************************************************************** - * - * @function: - * FT_Get_BDF_Property - * - * @description: - * Retrieve a BDF property from a BDF or PCF font file. - * - * @input: - * face :: A handle to the input face. - * - * name :: The property name. - * - * @output: - * aproperty :: The property. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * This function works with BDF _and_ PCF fonts. It returns an error - * otherwise. It also returns an error if the property is not in the - * font. - * - * A `property' is a either key-value pair within the STARTPROPERTIES - * ... ENDPROPERTIES block of a BDF font or a key-value pair from the - * `info->props' array within a `FontRec' structure of a PCF font. - * - * Integer properties are always stored as `signed' within PCF fonts; - * consequently, @BDF_PROPERTY_TYPE_CARDINAL is a possible return value - * for BDF fonts only. - * - * In case of error, `aproperty->type' is always set to - * @BDF_PROPERTY_TYPE_NONE. - */ + /************************************************************************** + * + * @function: + * FT_Get_BDF_Property + * + * @description: + * Retrieve a BDF property from a BDF or PCF font file. + * + * @input: + * face :: + * A handle to the input face. + * + * name :: + * The property name. + * + * @output: + * aproperty :: + * The property. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function works with BDF _and_ PCF fonts. It returns an error + * otherwise. It also returns an error if the property is not in the + * font. + * + * A 'property' is a either key-value pair within the STARTPROPERTIES + * ... ENDPROPERTIES block of a BDF font or a key-value pair from the + * `info->props` array within a `FontRec` structure of a PCF font. + * + * Integer properties are always stored as 'signed' within PCF fonts; + * consequently, @BDF_PROPERTY_TYPE_CARDINAL is a possible return value + * for BDF fonts only. + * + * In case of error, `aproperty->type` is always set to + * @BDF_PROPERTY_TYPE_NONE. + */ FT_EXPORT( FT_Error ) FT_Get_BDF_Property( FT_Face face, const char* prop_name, diff --git a/sdk/lib/3rdparty/freetype/include/freetype/ftbitmap.h b/sdk/lib/3rdparty/freetype/include/freetype/ftbitmap.h index a43187cad4776..9a9208e81903e 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/ftbitmap.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/ftbitmap.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftbitmap.h */ -/* */ -/* FreeType utility functions for bitmaps (specification). */ -/* */ -/* Copyright 2004-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftbitmap.h + * + * FreeType utility functions for bitmaps (specification). + * + * Copyright (C) 2004-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTBITMAP_H_ @@ -22,6 +22,7 @@ #include <ft2build.h> #include FT_FREETYPE_H +#include FT_COLOR_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" @@ -33,39 +34,46 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* <Section> */ - /* bitmap_handling */ - /* */ - /* <Title> */ - /* Bitmap Handling */ - /* */ - /* <Abstract> */ - /* Handling FT_Bitmap objects. */ - /* */ - /* <Description> */ - /* This section contains functions for handling @FT_Bitmap objects. */ - /* Note that none of the functions changes the bitmap's `flow' (as */ - /* indicated by the sign of the `pitch' field in `FT_Bitmap'). */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Bitmap_Init */ - /* */ - /* <Description> */ - /* Initialize a pointer to an @FT_Bitmap structure. */ - /* */ - /* <InOut> */ - /* abitmap :: A pointer to the bitmap structure. */ - /* */ - /* <Note> */ - /* A deprecated name for the same function is `FT_Bitmap_New'. */ - /* */ + /************************************************************************** + * + * @section: + * bitmap_handling + * + * @title: + * Bitmap Handling + * + * @abstract: + * Handling FT_Bitmap objects. + * + * @description: + * This section contains functions for handling @FT_Bitmap objects, + * automatically adjusting the target's bitmap buffer size as needed. + * + * Note that none of the functions changes the bitmap's 'flow' (as + * indicated by the sign of the `pitch` field in @FT_Bitmap). + * + * To set the flow, assign an appropriate positive or negative value to + * the `pitch` field of the target @FT_Bitmap object after calling + * @FT_Bitmap_Init but before calling any of the other functions + * described here. + */ + + + /************************************************************************** + * + * @function: + * FT_Bitmap_Init + * + * @description: + * Initialize a pointer to an @FT_Bitmap structure. + * + * @inout: + * abitmap :: + * A pointer to the bitmap structure. + * + * @note: + * A deprecated name for the same function is `FT_Bitmap_New`. + */ FT_EXPORT( void ) FT_Bitmap_Init( FT_Bitmap *abitmap ); @@ -75,66 +83,77 @@ FT_BEGIN_HEADER FT_Bitmap_New( FT_Bitmap *abitmap ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Bitmap_Copy */ - /* */ - /* <Description> */ - /* Copy a bitmap into another one. */ - /* */ - /* <Input> */ - /* library :: A handle to a library object. */ - /* */ - /* source :: A handle to the source bitmap. */ - /* */ - /* <Output> */ - /* target :: A handle to the target bitmap. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Bitmap_Copy + * + * @description: + * Copy a bitmap into another one. + * + * @input: + * library :: + * A handle to a library object. + * + * source :: + * A handle to the source bitmap. + * + * @output: + * target :: + * A handle to the target bitmap. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * `source->buffer` and `target->buffer` must neither be equal nor + * overlap. + */ FT_EXPORT( FT_Error ) FT_Bitmap_Copy( FT_Library library, const FT_Bitmap *source, FT_Bitmap *target ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Bitmap_Embolden */ - /* */ - /* <Description> */ - /* Embolden a bitmap. The new bitmap will be about `xStrength' */ - /* pixels wider and `yStrength' pixels higher. The left and bottom */ - /* borders are kept unchanged. */ - /* */ - /* <Input> */ - /* library :: A handle to a library object. */ - /* */ - /* xStrength :: How strong the glyph is emboldened horizontally. */ - /* Expressed in 26.6 pixel format. */ - /* */ - /* yStrength :: How strong the glyph is emboldened vertically. */ - /* Expressed in 26.6 pixel format. */ - /* */ - /* <InOut> */ - /* bitmap :: A handle to the target bitmap. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* The current implementation restricts `xStrength' to be less than */ - /* or equal to~8 if bitmap is of pixel_mode @FT_PIXEL_MODE_MONO. */ - /* */ - /* If you want to embolden the bitmap owned by a @FT_GlyphSlotRec, */ - /* you should call @FT_GlyphSlot_Own_Bitmap on the slot first. */ - /* */ - /* Bitmaps in @FT_PIXEL_MODE_GRAY2 and @FT_PIXEL_MODE_GRAY@ format */ - /* are converted to @FT_PIXEL_MODE_GRAY format (i.e., 8bpp). */ - /* */ + /************************************************************************** + * + * @function: + * FT_Bitmap_Embolden + * + * @description: + * Embolden a bitmap. The new bitmap will be about `xStrength` pixels + * wider and `yStrength` pixels higher. The left and bottom borders are + * kept unchanged. + * + * @input: + * library :: + * A handle to a library object. + * + * xStrength :: + * How strong the glyph is emboldened horizontally. Expressed in 26.6 + * pixel format. + * + * yStrength :: + * How strong the glyph is emboldened vertically. Expressed in 26.6 + * pixel format. + * + * @inout: + * bitmap :: + * A handle to the target bitmap. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The current implementation restricts `xStrength` to be less than or + * equal to~8 if bitmap is of pixel_mode @FT_PIXEL_MODE_MONO. + * + * If you want to embolden the bitmap owned by a @FT_GlyphSlotRec, you + * should call @FT_GlyphSlot_Own_Bitmap on the slot first. + * + * Bitmaps in @FT_PIXEL_MODE_GRAY2 and @FT_PIXEL_MODE_GRAY@ format are + * converted to @FT_PIXEL_MODE_GRAY format (i.e., 8bpp). + */ FT_EXPORT( FT_Error ) FT_Bitmap_Embolden( FT_Library library, FT_Bitmap* bitmap, @@ -142,88 +161,167 @@ FT_BEGIN_HEADER FT_Pos yStrength ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Bitmap_Convert */ - /* */ - /* <Description> */ - /* Convert a bitmap object with depth 1bpp, 2bpp, 4bpp, 8bpp or 32bpp */ - /* to a bitmap object with depth 8bpp, making the number of used */ - /* bytes line (a.k.a. the `pitch') a multiple of `alignment'. */ - /* */ - /* <Input> */ - /* library :: A handle to a library object. */ - /* */ - /* source :: The source bitmap. */ - /* */ - /* alignment :: The pitch of the bitmap is a multiple of this */ - /* parameter. Common values are 1, 2, or 4. */ - /* */ - /* <Output> */ - /* target :: The target bitmap. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* It is possible to call @FT_Bitmap_Convert multiple times without */ - /* calling @FT_Bitmap_Done (the memory is simply reallocated). */ - /* */ - /* Use @FT_Bitmap_Done to finally remove the bitmap object. */ - /* */ - /* The `library' argument is taken to have access to FreeType's */ - /* memory handling functions. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Bitmap_Convert + * + * @description: + * Convert a bitmap object with depth 1bpp, 2bpp, 4bpp, 8bpp or 32bpp to + * a bitmap object with depth 8bpp, making the number of used bytes per + * line (a.k.a. the 'pitch') a multiple of `alignment`. + * + * @input: + * library :: + * A handle to a library object. + * + * source :: + * The source bitmap. + * + * alignment :: + * The pitch of the bitmap is a multiple of this argument. Common + * values are 1, 2, or 4. + * + * @output: + * target :: + * The target bitmap. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * It is possible to call @FT_Bitmap_Convert multiple times without + * calling @FT_Bitmap_Done (the memory is simply reallocated). + * + * Use @FT_Bitmap_Done to finally remove the bitmap object. + * + * The `library` argument is taken to have access to FreeType's memory + * handling functions. + * + * `source->buffer` and `target->buffer` must neither be equal nor + * overlap. + */ FT_EXPORT( FT_Error ) FT_Bitmap_Convert( FT_Library library, const FT_Bitmap *source, FT_Bitmap *target, FT_Int alignment ); +#ifdef __REACTOS__ + FT_EXPORT( FT_Error ) + FT_Bitmap_Convert_ReactOS_Hack( FT_Library library, + const FT_Bitmap *source, + FT_Bitmap *target, + FT_Int alignment, + FT_Bool hack ); +#endif + + /************************************************************************** + * + * @function: + * FT_Bitmap_Blend + * + * @description: + * Blend a bitmap onto another bitmap, using a given color. + * + * @input: + * library :: + * A handle to a library object. + * + * source :: + * The source bitmap, which can have any @FT_Pixel_Mode format. + * + * source_offset :: + * The offset vector to the upper left corner of the source bitmap in + * 26.6 pixel format. It should represent an integer offset; the + * function will set the lowest six bits to zero to enforce that. + * + * color :: + * The color used to draw `source` onto `target`. + * + * @inout: + * target :: + * A handle to an `FT_Bitmap` object. It should be either initialized + * as empty with a call to @FT_Bitmap_Init, or it should be of type + * @FT_PIXEL_MODE_BGRA. + * + * atarget_offset :: + * The offset vector to the upper left corner of the target bitmap in + * 26.6 pixel format. It should represent an integer offset; the + * function will set the lowest six bits to zero to enforce that. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function doesn't perform clipping. + * + * The bitmap in `target` gets allocated or reallocated as needed; the + * vector `atarget_offset` is updated accordingly. + * + * In case of allocation or reallocation, the bitmap's pitch is set to + * `4 * width`. Both `source` and `target` must have the same bitmap + * flow (as indicated by the sign of the `pitch` field). + * + * `source->buffer` and `target->buffer` must neither be equal nor + * overlap. + * + * @since: + * 2.10 + */ + FT_EXPORT( FT_Error ) + FT_Bitmap_Blend( FT_Library library, + const FT_Bitmap* source, + const FT_Vector source_offset, + FT_Bitmap* target, + FT_Vector *atarget_offset, + FT_Color color ); + - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_GlyphSlot_Own_Bitmap */ - /* */ - /* <Description> */ - /* Make sure that a glyph slot owns `slot->bitmap'. */ - /* */ - /* <Input> */ - /* slot :: The glyph slot. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* This function is to be used in combination with */ - /* @FT_Bitmap_Embolden. */ - /* */ + /************************************************************************** + * + * @function: + * FT_GlyphSlot_Own_Bitmap + * + * @description: + * Make sure that a glyph slot owns `slot->bitmap`. + * + * @input: + * slot :: + * The glyph slot. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function is to be used in combination with @FT_Bitmap_Embolden. + */ FT_EXPORT( FT_Error ) FT_GlyphSlot_Own_Bitmap( FT_GlyphSlot slot ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Bitmap_Done */ - /* */ - /* <Description> */ - /* Destroy a bitmap object initialized with @FT_Bitmap_Init. */ - /* */ - /* <Input> */ - /* library :: A handle to a library object. */ - /* */ - /* bitmap :: The bitmap object to be freed. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* The `library' argument is taken to have access to FreeType's */ - /* memory handling functions. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Bitmap_Done + * + * @description: + * Destroy a bitmap object initialized with @FT_Bitmap_Init. + * + * @input: + * library :: + * A handle to a library object. + * + * bitmap :: + * The bitmap object to be freed. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The `library` argument is taken to have access to FreeType's memory + * handling functions. + */ FT_EXPORT( FT_Error ) FT_Bitmap_Done( FT_Library library, FT_Bitmap *bitmap ); diff --git a/sdk/lib/3rdparty/freetype/include/freetype/ftbzip2.h b/sdk/lib/3rdparty/freetype/include/freetype/ftbzip2.h index 6edfa031b50d4..ae88cfdbdb982 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/ftbzip2.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/ftbzip2.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftbzip2.h */ -/* */ -/* Bzip2-compressed stream support. */ -/* */ -/* Copyright 2010-2018 by */ -/* Joel Klinghed. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftbzip2.h + * + * Bzip2-compressed stream support. + * + * Copyright (C) 2010-2019 by + * Joel Klinghed. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTBZIP2_H_ @@ -31,62 +31,62 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* <Section> */ - /* bzip2 */ - /* */ - /* <Title> */ - /* BZIP2 Streams */ - /* */ - /* <Abstract> */ - /* Using bzip2-compressed font files. */ - /* */ - /* <Description> */ - /* This section contains the declaration of Bzip2-specific functions. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * @section: + * bzip2 + * + * @title: + * BZIP2 Streams + * + * @abstract: + * Using bzip2-compressed font files. + * + * @description: + * This section contains the declaration of Bzip2-specific functions. + * + */ - /************************************************************************ - * - * @function: - * FT_Stream_OpenBzip2 - * - * @description: - * Open a new stream to parse bzip2-compressed font files. This is - * mainly used to support the compressed `*.pcf.bz2' fonts that come - * with XFree86. - * - * @input: - * stream :: - * The target embedding stream. - * - * source :: - * The source stream. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * The source stream must be opened _before_ calling this function. - * - * Calling the internal function `FT_Stream_Close' on the new stream will - * *not* call `FT_Stream_Close' on the source stream. None of the stream - * objects will be released to the heap. - * - * The stream implementation is very basic and resets the decompression - * process each time seeking backwards is needed within the stream. - * - * In certain builds of the library, bzip2 compression recognition is - * automatically handled when calling @FT_New_Face or @FT_Open_Face. - * This means that if no font driver is capable of handling the raw - * compressed file, the library will try to open a bzip2 compressed stream - * from it and re-open the face with it. - * - * This function may return `FT_Err_Unimplemented_Feature' if your build - * of FreeType was not compiled with bzip2 support. - */ + /************************************************************************** + * + * @function: + * FT_Stream_OpenBzip2 + * + * @description: + * Open a new stream to parse bzip2-compressed font files. This is + * mainly used to support the compressed `*.pcf.bz2` fonts that come with + * XFree86. + * + * @input: + * stream :: + * The target embedding stream. + * + * source :: + * The source stream. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The source stream must be opened _before_ calling this function. + * + * Calling the internal function `FT_Stream_Close` on the new stream will + * **not** call `FT_Stream_Close` on the source stream. None of the + * stream objects will be released to the heap. + * + * The stream implementation is very basic and resets the decompression + * process each time seeking backwards is needed within the stream. + * + * In certain builds of the library, bzip2 compression recognition is + * automatically handled when calling @FT_New_Face or @FT_Open_Face. + * This means that if no font driver is capable of handling the raw + * compressed file, the library will try to open a bzip2 compressed + * stream from it and re-open the face with it. + * + * This function may return `FT_Err_Unimplemented_Feature` if your build + * of FreeType was not compiled with bzip2 support. + */ FT_EXPORT( FT_Error ) FT_Stream_OpenBzip2( FT_Stream stream, FT_Stream source ); diff --git a/sdk/lib/3rdparty/freetype/include/freetype/ftcache.h b/sdk/lib/3rdparty/freetype/include/freetype/ftcache.h index 52d5f00e06897..0d589d0b34a74 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/ftcache.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/ftcache.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftcache.h */ -/* */ -/* FreeType Cache subsystem (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftcache.h + * + * FreeType Cache subsystem (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTCACHE_H_ @@ -27,24 +27,24 @@ FT_BEGIN_HEADER - /************************************************************************* + /************************************************************************** * - * <Section> - * cache_subsystem + * @section: + * cache_subsystem * - * <Title> - * Cache Sub-System + * @title: + * Cache Sub-System * - * <Abstract> - * How to cache face, size, and glyph data with FreeType~2. + * @abstract: + * How to cache face, size, and glyph data with FreeType~2. * - * <Description> + * @description: * This section describes the FreeType~2 cache sub-system, which is used * to limit the number of concurrently opened @FT_Face and @FT_Size * objects, as well as caching information like character maps and glyph * images while limiting their maximum memory usage. * - * Note that all types and functions begin with the `FTC_' prefix. + * Note that all types and functions begin with the `FTC_` prefix. * * The cache is highly portable and thus doesn't know anything about the * fonts installed on your system, or how to access them. This implies @@ -59,7 +59,7 @@ FT_BEGIN_HEADER * to convert an @FTC_FaceID into a new @FT_Face object. The latter is * then completely managed by the cache, including its termination * through @FT_Done_Face. To monitor termination of face objects, the - * finalizer callback in the `generic' field of the @FT_Face object can + * finalizer callback in the `generic` field of the @FT_Face object can * be used, which might also be used to store the @FTC_FaceID of the * face. * @@ -69,14 +69,14 @@ FT_BEGIN_HEADER * possible. * * Note that for the cache to work correctly, the face ID values must be - * *persistent*, which means that the contents they point to should not + * **persistent**, which means that the contents they point to should not * change at runtime, or that their value should not become invalid. * * If this is unavoidable (e.g., when a font is uninstalled at runtime), * you should call @FTC_Manager_RemoveFaceID as soon as possible, to let - * the cache get rid of any references to the old @FTC_FaceID it may - * keep internally. Failure to do so will lead to incorrect behaviour - * or even crashes. + * the cache get rid of any references to the old @FTC_FaceID it may keep + * internally. Failure to do so will lead to incorrect behaviour or even + * crashes. * * To use the cache, start with calling @FTC_Manager_New to create a new * @FTC_Manager object, which models a single cache instance. You can @@ -91,16 +91,16 @@ FT_BEGIN_HEADER * later use @FTC_ImageCache_Lookup to retrieve the corresponding * @FT_Glyph objects from the cache. * - * If you need lots of small bitmaps, it is much more memory efficient - * to call @FTC_SBitCache_New followed by @FTC_SBitCache_Lookup. This - * returns @FTC_SBitRec structures, which are used to store small - * bitmaps directly. (A small bitmap is one whose metrics and - * dimensions all fit into 8-bit integers). + * If you need lots of small bitmaps, it is much more memory efficient to + * call @FTC_SBitCache_New followed by @FTC_SBitCache_Lookup. This + * returns @FTC_SBitRec structures, which are used to store small bitmaps + * directly. (A small bitmap is one whose metrics and dimensions all fit + * into 8-bit integers). * * We hope to also provide a kerning cache in the near future. * * - * <Order> + * @order: * FTC_Manager * FTC_FaceID * FTC_Face_Requester @@ -142,19 +142,20 @@ FT_BEGIN_HEADER /*************************************************************************/ - /************************************************************************* + /************************************************************************** * - * @type: FTC_FaceID + * @type: + * FTC_FaceID * * @description: * An opaque pointer type that is used to identity face objects. The * contents of such objects is application-dependent. * - * These pointers are typically used to point to a user-defined - * structure containing a font file path, and face index. + * These pointers are typically used to point to a user-defined structure + * containing a font file path, and face index. * * @note: - * Never use NULL as a valid @FTC_FaceID. + * Never use `NULL` as a valid @FTC_FaceID. * * Face IDs are passed by the client to the cache manager that calls, * when needed, the @FTC_Face_Requester to translate them into new @@ -165,13 +166,13 @@ FT_BEGIN_HEADER * immediately call @FTC_Manager_RemoveFaceID before any other cache * function. * - * Failure to do so will result in incorrect behaviour or even - * memory leaks and crashes. + * Failure to do so will result in incorrect behaviour or even memory + * leaks and crashes. */ typedef FT_Pointer FTC_FaceID; - /************************************************************************ + /************************************************************************** * * @functype: * FTC_Face_Requester @@ -181,7 +182,7 @@ FT_BEGIN_HEADER * the cache manager to translate a given @FTC_FaceID into a new valid * @FT_Face object, on demand. * - * <Input> + * @input: * face_id :: * The face ID to resolve. * @@ -191,15 +192,15 @@ FT_BEGIN_HEADER * req_data :: * Application-provided request data (see note below). * - * <Output> + * @output: * aface :: * A new @FT_Face handle. * - * <Return> + * @return: * FreeType error code. 0~means success. * - * <Note> - * The third parameter `req_data' is the same as the one passed by the + * @note: + * The third parameter `req_data` is the same as the one passed by the * client when @FTC_Manager_New is called. * * The face requester should not perform funny things on the returned @@ -226,84 +227,90 @@ FT_BEGIN_HEADER /*************************************************************************/ - /*************************************************************************/ - /* */ - /* <Type> */ - /* FTC_Manager */ - /* */ - /* <Description> */ - /* This object corresponds to one instance of the cache-subsystem. */ - /* It is used to cache one or more @FT_Face objects, along with */ - /* corresponding @FT_Size objects. */ - /* */ - /* The manager intentionally limits the total number of opened */ - /* @FT_Face and @FT_Size objects to control memory usage. See the */ - /* `max_faces' and `max_sizes' parameters of @FTC_Manager_New. */ - /* */ - /* The manager is also used to cache `nodes' of various types while */ - /* limiting their total memory usage. */ - /* */ - /* All limitations are enforced by keeping lists of managed objects */ - /* in most-recently-used order, and flushing old nodes to make room */ - /* for new ones. */ - /* */ + /************************************************************************** + * + * @type: + * FTC_Manager + * + * @description: + * This object corresponds to one instance of the cache-subsystem. It is + * used to cache one or more @FT_Face objects, along with corresponding + * @FT_Size objects. + * + * The manager intentionally limits the total number of opened @FT_Face + * and @FT_Size objects to control memory usage. See the `max_faces` and + * `max_sizes` parameters of @FTC_Manager_New. + * + * The manager is also used to cache 'nodes' of various types while + * limiting their total memory usage. + * + * All limitations are enforced by keeping lists of managed objects in + * most-recently-used order, and flushing old nodes to make room for new + * ones. + */ typedef struct FTC_ManagerRec_* FTC_Manager; - /*************************************************************************/ - /* */ - /* <Type> */ - /* FTC_Node */ - /* */ - /* <Description> */ - /* An opaque handle to a cache node object. Each cache node is */ - /* reference-counted. A node with a count of~0 might be flushed */ - /* out of a full cache whenever a lookup request is performed. */ - /* */ - /* If you look up nodes, you have the ability to `acquire' them, */ - /* i.e., to increment their reference count. This will prevent the */ - /* node from being flushed out of the cache until you explicitly */ - /* `release' it (see @FTC_Node_Unref). */ - /* */ - /* See also @FTC_SBitCache_Lookup and @FTC_ImageCache_Lookup. */ - /* */ + /************************************************************************** + * + * @type: + * FTC_Node + * + * @description: + * An opaque handle to a cache node object. Each cache node is + * reference-counted. A node with a count of~0 might be flushed out of a + * full cache whenever a lookup request is performed. + * + * If you look up nodes, you have the ability to 'acquire' them, i.e., to + * increment their reference count. This will prevent the node from + * being flushed out of the cache until you explicitly 'release' it (see + * @FTC_Node_Unref). + * + * See also @FTC_SBitCache_Lookup and @FTC_ImageCache_Lookup. + */ typedef struct FTC_NodeRec_* FTC_Node; - /*************************************************************************/ - /* */ - /* <Function> */ - /* FTC_Manager_New */ - /* */ - /* <Description> */ - /* Create a new cache manager. */ - /* */ - /* <Input> */ - /* library :: The parent FreeType library handle to use. */ - /* */ - /* max_faces :: Maximum number of opened @FT_Face objects managed by */ - /* this cache instance. Use~0 for defaults. */ - /* */ - /* max_sizes :: Maximum number of opened @FT_Size objects managed by */ - /* this cache instance. Use~0 for defaults. */ - /* */ - /* max_bytes :: Maximum number of bytes to use for cached data nodes. */ - /* Use~0 for defaults. Note that this value does not */ - /* account for managed @FT_Face and @FT_Size objects. */ - /* */ - /* requester :: An application-provided callback used to translate */ - /* face IDs into real @FT_Face objects. */ - /* */ - /* req_data :: A generic pointer that is passed to the requester */ - /* each time it is called (see @FTC_Face_Requester). */ - /* */ - /* <Output> */ - /* amanager :: A handle to a new manager object. 0~in case of */ - /* failure. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ + /************************************************************************** + * + * @function: + * FTC_Manager_New + * + * @description: + * Create a new cache manager. + * + * @input: + * library :: + * The parent FreeType library handle to use. + * + * max_faces :: + * Maximum number of opened @FT_Face objects managed by this cache + * instance. Use~0 for defaults. + * + * max_sizes :: + * Maximum number of opened @FT_Size objects managed by this cache + * instance. Use~0 for defaults. + * + * max_bytes :: + * Maximum number of bytes to use for cached data nodes. Use~0 for + * defaults. Note that this value does not account for managed + * @FT_Face and @FT_Size objects. + * + * requester :: + * An application-provided callback used to translate face IDs into + * real @FT_Face objects. + * + * req_data :: + * A generic pointer that is passed to the requester each time it is + * called (see @FTC_Face_Requester). + * + * @output: + * amanager :: + * A handle to a new manager object. 0~in case of failure. + * + * @return: + * FreeType error code. 0~means success. + */ FT_EXPORT( FT_Error ) FTC_Manager_New( FT_Library library, FT_UInt max_faces, @@ -314,114 +321,124 @@ FT_BEGIN_HEADER FTC_Manager *amanager ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FTC_Manager_Reset */ - /* */ - /* <Description> */ - /* Empty a given cache manager. This simply gets rid of all the */ - /* currently cached @FT_Face and @FT_Size objects within the manager. */ - /* */ - /* <InOut> */ - /* manager :: A handle to the manager. */ - /* */ + /************************************************************************** + * + * @function: + * FTC_Manager_Reset + * + * @description: + * Empty a given cache manager. This simply gets rid of all the + * currently cached @FT_Face and @FT_Size objects within the manager. + * + * @inout: + * manager :: + * A handle to the manager. + */ FT_EXPORT( void ) FTC_Manager_Reset( FTC_Manager manager ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FTC_Manager_Done */ - /* */ - /* <Description> */ - /* Destroy a given manager after emptying it. */ - /* */ - /* <Input> */ - /* manager :: A handle to the target cache manager object. */ - /* */ + /************************************************************************** + * + * @function: + * FTC_Manager_Done + * + * @description: + * Destroy a given manager after emptying it. + * + * @input: + * manager :: + * A handle to the target cache manager object. + */ FT_EXPORT( void ) FTC_Manager_Done( FTC_Manager manager ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FTC_Manager_LookupFace */ - /* */ - /* <Description> */ - /* Retrieve the @FT_Face object that corresponds to a given face ID */ - /* through a cache manager. */ - /* */ - /* <Input> */ - /* manager :: A handle to the cache manager. */ - /* */ - /* face_id :: The ID of the face object. */ - /* */ - /* <Output> */ - /* aface :: A handle to the face object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* The returned @FT_Face object is always owned by the manager. You */ - /* should never try to discard it yourself. */ - /* */ - /* The @FT_Face object doesn't necessarily have a current size object */ - /* (i.e., face->size can be~0). If you need a specific `font size', */ - /* use @FTC_Manager_LookupSize instead. */ - /* */ - /* Never change the face's transformation matrix (i.e., never call */ - /* the @FT_Set_Transform function) on a returned face! If you need */ - /* to transform glyphs, do it yourself after glyph loading. */ - /* */ - /* When you perform a lookup, out-of-memory errors are detected */ - /* _within_ the lookup and force incremental flushes of the cache */ - /* until enough memory is released for the lookup to succeed. */ - /* */ - /* If a lookup fails with `FT_Err_Out_Of_Memory' the cache has */ - /* already been completely flushed, and still no memory was available */ - /* for the operation. */ - /* */ + /************************************************************************** + * + * @function: + * FTC_Manager_LookupFace + * + * @description: + * Retrieve the @FT_Face object that corresponds to a given face ID + * through a cache manager. + * + * @input: + * manager :: + * A handle to the cache manager. + * + * face_id :: + * The ID of the face object. + * + * @output: + * aface :: + * A handle to the face object. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The returned @FT_Face object is always owned by the manager. You + * should never try to discard it yourself. + * + * The @FT_Face object doesn't necessarily have a current size object + * (i.e., face->size can be~0). If you need a specific 'font size', use + * @FTC_Manager_LookupSize instead. + * + * Never change the face's transformation matrix (i.e., never call the + * @FT_Set_Transform function) on a returned face! If you need to + * transform glyphs, do it yourself after glyph loading. + * + * When you perform a lookup, out-of-memory errors are detected _within_ + * the lookup and force incremental flushes of the cache until enough + * memory is released for the lookup to succeed. + * + * If a lookup fails with `FT_Err_Out_Of_Memory` the cache has already + * been completely flushed, and still no memory was available for the + * operation. + */ FT_EXPORT( FT_Error ) FTC_Manager_LookupFace( FTC_Manager manager, FTC_FaceID face_id, FT_Face *aface ); - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FTC_ScalerRec */ - /* */ - /* <Description> */ - /* A structure used to describe a given character size in either */ - /* pixels or points to the cache manager. See */ - /* @FTC_Manager_LookupSize. */ - /* */ - /* <Fields> */ - /* face_id :: The source face ID. */ - /* */ - /* width :: The character width. */ - /* */ - /* height :: The character height. */ - /* */ - /* pixel :: A Boolean. If 1, the `width' and `height' fields are */ - /* interpreted as integer pixel character sizes. */ - /* Otherwise, they are expressed as 1/64th of points. */ - /* */ - /* x_res :: Only used when `pixel' is value~0 to indicate the */ - /* horizontal resolution in dpi. */ - /* */ - /* y_res :: Only used when `pixel' is value~0 to indicate the */ - /* vertical resolution in dpi. */ - /* */ - /* <Note> */ - /* This type is mainly used to retrieve @FT_Size objects through the */ - /* cache manager. */ - /* */ + /************************************************************************** + * + * @struct: + * FTC_ScalerRec + * + * @description: + * A structure used to describe a given character size in either pixels + * or points to the cache manager. See @FTC_Manager_LookupSize. + * + * @fields: + * face_id :: + * The source face ID. + * + * width :: + * The character width. + * + * height :: + * The character height. + * + * pixel :: + * A Boolean. If 1, the `width` and `height` fields are interpreted as + * integer pixel character sizes. Otherwise, they are expressed as + * 1/64th of points. + * + * x_res :: + * Only used when `pixel` is value~0 to indicate the horizontal + * resolution in dpi. + * + * y_res :: + * Only used when `pixel` is value~0 to indicate the vertical + * resolution in dpi. + * + * @note: + * This type is mainly used to retrieve @FT_Size objects through the + * cache manager. + */ typedef struct FTC_ScalerRec_ { FTC_FaceID face_id; @@ -434,89 +451,93 @@ FT_BEGIN_HEADER } FTC_ScalerRec; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FTC_Scaler */ - /* */ - /* <Description> */ - /* A handle to an @FTC_ScalerRec structure. */ - /* */ + /************************************************************************** + * + * @struct: + * FTC_Scaler + * + * @description: + * A handle to an @FTC_ScalerRec structure. + */ typedef struct FTC_ScalerRec_* FTC_Scaler; - /*************************************************************************/ - /* */ - /* <Function> */ - /* FTC_Manager_LookupSize */ - /* */ - /* <Description> */ - /* Retrieve the @FT_Size object that corresponds to a given */ - /* @FTC_ScalerRec pointer through a cache manager. */ - /* */ - /* <Input> */ - /* manager :: A handle to the cache manager. */ - /* */ - /* scaler :: A scaler handle. */ - /* */ - /* <Output> */ - /* asize :: A handle to the size object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* The returned @FT_Size object is always owned by the manager. You */ - /* should never try to discard it by yourself. */ - /* */ - /* You can access the parent @FT_Face object simply as `size->face' */ - /* if you need it. Note that this object is also owned by the */ - /* manager. */ - /* */ - /* <Note> */ - /* When you perform a lookup, out-of-memory errors are detected */ - /* _within_ the lookup and force incremental flushes of the cache */ - /* until enough memory is released for the lookup to succeed. */ - /* */ - /* If a lookup fails with `FT_Err_Out_Of_Memory' the cache has */ - /* already been completely flushed, and still no memory is available */ - /* for the operation. */ - /* */ + /************************************************************************** + * + * @function: + * FTC_Manager_LookupSize + * + * @description: + * Retrieve the @FT_Size object that corresponds to a given + * @FTC_ScalerRec pointer through a cache manager. + * + * @input: + * manager :: + * A handle to the cache manager. + * + * scaler :: + * A scaler handle. + * + * @output: + * asize :: + * A handle to the size object. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The returned @FT_Size object is always owned by the manager. You + * should never try to discard it by yourself. + * + * You can access the parent @FT_Face object simply as `size->face` if + * you need it. Note that this object is also owned by the manager. + * + * @note: + * When you perform a lookup, out-of-memory errors are detected _within_ + * the lookup and force incremental flushes of the cache until enough + * memory is released for the lookup to succeed. + * + * If a lookup fails with `FT_Err_Out_Of_Memory` the cache has already + * been completely flushed, and still no memory is available for the + * operation. + */ FT_EXPORT( FT_Error ) FTC_Manager_LookupSize( FTC_Manager manager, FTC_Scaler scaler, FT_Size *asize ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FTC_Node_Unref */ - /* */ - /* <Description> */ - /* Decrement a cache node's internal reference count. When the count */ - /* reaches 0, it is not destroyed but becomes eligible for subsequent */ - /* cache flushes. */ - /* */ - /* <Input> */ - /* node :: The cache node handle. */ - /* */ - /* manager :: The cache manager handle. */ - /* */ + /************************************************************************** + * + * @function: + * FTC_Node_Unref + * + * @description: + * Decrement a cache node's internal reference count. When the count + * reaches 0, it is not destroyed but becomes eligible for subsequent + * cache flushes. + * + * @input: + * node :: + * The cache node handle. + * + * manager :: + * The cache manager handle. + */ FT_EXPORT( void ) FTC_Node_Unref( FTC_Node node, FTC_Manager manager ); - /************************************************************************* + /************************************************************************** * * @function: * FTC_Manager_RemoveFaceID * * @description: - * A special function used to indicate to the cache manager that - * a given @FTC_FaceID is no longer valid, either because its - * content changed, or because it was deallocated or uninstalled. + * A special function used to indicate to the cache manager that a given + * @FTC_FaceID is no longer valid, either because its content changed, or + * because it was deallocated or uninstalled. * * @input: * manager :: @@ -527,11 +548,11 @@ FT_BEGIN_HEADER * * @note: * This function flushes all nodes from the cache corresponding to this - * `face_id', with the exception of nodes with a non-null reference + * `face_id`, with the exception of nodes with a non-null reference * count. * - * Such nodes are however modified internally so as to never appear - * in later lookups with the same `face_id' value, and to be immediately + * Such nodes are however modified internally so as to never appear in + * later lookups with the same `face_id` value, and to be immediately * destroyed when released by all their users. * */ @@ -540,20 +561,20 @@ FT_BEGIN_HEADER FTC_FaceID face_id ); - /************************************************************************* + /************************************************************************** * * @type: * FTC_CMapCache * * @description: - * An opaque handle used to model a charmap cache. This cache is to - * hold character codes -> glyph indices mappings. + * An opaque handle used to model a charmap cache. This cache is to hold + * character codes -> glyph indices mappings. * */ typedef struct FTC_CMapCacheRec_* FTC_CMapCache; - /************************************************************************* + /************************************************************************** * * @function: * FTC_CMapCache_New @@ -567,7 +588,7 @@ FT_BEGIN_HEADER * * @output: * acache :: - * A new cache handle. NULL in case of error. + * A new cache handle. `NULL` in case of error. * * @return: * FreeType error code. 0~means success. @@ -582,7 +603,7 @@ FT_BEGIN_HEADER FTC_CMapCache *acache ); - /************************************************************************ + /************************************************************************** * * @function: * FTC_CMapCache_Lookup @@ -606,7 +627,7 @@ FT_BEGIN_HEADER * The character code (in the corresponding charmap). * * @return: - * Glyph index. 0~means `no glyph'. + * Glyph index. 0~means 'no glyph'. * */ FT_EXPORT( FT_UInt ) @@ -627,7 +648,7 @@ FT_BEGIN_HEADER /*************************************************************************/ - /************************************************************************* + /************************************************************************** * * @struct: * FTC_ImageTypeRec @@ -659,7 +680,7 @@ FT_BEGIN_HEADER } FTC_ImageTypeRec; - /************************************************************************* + /************************************************************************** * * @type: * FTC_ImageType @@ -680,83 +701,87 @@ FT_BEGIN_HEADER (d1)->flags == (d2)->flags ) - /*************************************************************************/ - /* */ - /* <Type> */ - /* FTC_ImageCache */ - /* */ - /* <Description> */ - /* A handle to a glyph image cache object. They are designed to */ - /* hold many distinct glyph images while not exceeding a certain */ - /* memory threshold. */ - /* */ + /************************************************************************** + * + * @type: + * FTC_ImageCache + * + * @description: + * A handle to a glyph image cache object. They are designed to hold + * many distinct glyph images while not exceeding a certain memory + * threshold. + */ typedef struct FTC_ImageCacheRec_* FTC_ImageCache; - /*************************************************************************/ - /* */ - /* <Function> */ - /* FTC_ImageCache_New */ - /* */ - /* <Description> */ - /* Create a new glyph image cache. */ - /* */ - /* <Input> */ - /* manager :: The parent manager for the image cache. */ - /* */ - /* <Output> */ - /* acache :: A handle to the new glyph image cache object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ + /************************************************************************** + * + * @function: + * FTC_ImageCache_New + * + * @description: + * Create a new glyph image cache. + * + * @input: + * manager :: + * The parent manager for the image cache. + * + * @output: + * acache :: + * A handle to the new glyph image cache object. + * + * @return: + * FreeType error code. 0~means success. + */ FT_EXPORT( FT_Error ) FTC_ImageCache_New( FTC_Manager manager, FTC_ImageCache *acache ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FTC_ImageCache_Lookup */ - /* */ - /* <Description> */ - /* Retrieve a given glyph image from a glyph image cache. */ - /* */ - /* <Input> */ - /* cache :: A handle to the source glyph image cache. */ - /* */ - /* type :: A pointer to a glyph image type descriptor. */ - /* */ - /* gindex :: The glyph index to retrieve. */ - /* */ - /* <Output> */ - /* aglyph :: The corresponding @FT_Glyph object. 0~in case of */ - /* failure. */ - /* */ - /* anode :: Used to return the address of the corresponding cache */ - /* node after incrementing its reference count (see note */ - /* below). */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* The returned glyph is owned and managed by the glyph image cache. */ - /* Never try to transform or discard it manually! You can however */ - /* create a copy with @FT_Glyph_Copy and modify the new one. */ - /* */ - /* If `anode' is _not_ NULL, it receives the address of the cache */ - /* node containing the glyph image, after increasing its reference */ - /* count. This ensures that the node (as well as the @FT_Glyph) will */ - /* always be kept in the cache until you call @FTC_Node_Unref to */ - /* `release' it. */ - /* */ - /* If `anode' is NULL, the cache node is left unchanged, which means */ - /* that the @FT_Glyph could be flushed out of the cache on the next */ - /* call to one of the caching sub-system APIs. Don't assume that it */ - /* is persistent! */ - /* */ + /************************************************************************** + * + * @function: + * FTC_ImageCache_Lookup + * + * @description: + * Retrieve a given glyph image from a glyph image cache. + * + * @input: + * cache :: + * A handle to the source glyph image cache. + * + * type :: + * A pointer to a glyph image type descriptor. + * + * gindex :: + * The glyph index to retrieve. + * + * @output: + * aglyph :: + * The corresponding @FT_Glyph object. 0~in case of failure. + * + * anode :: + * Used to return the address of the corresponding cache node after + * incrementing its reference count (see note below). + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The returned glyph is owned and managed by the glyph image cache. + * Never try to transform or discard it manually! You can however create + * a copy with @FT_Glyph_Copy and modify the new one. + * + * If `anode` is _not_ `NULL`, it receives the address of the cache node + * containing the glyph image, after increasing its reference count. + * This ensures that the node (as well as the @FT_Glyph) will always be + * kept in the cache until you call @FTC_Node_Unref to 'release' it. + * + * If `anode` is `NULL`, the cache node is left unchanged, which means + * that the @FT_Glyph could be flushed out of the cache on the next call + * to one of the caching sub-system APIs. Don't assume that it is + * persistent! + */ FT_EXPORT( FT_Error ) FTC_ImageCache_Lookup( FTC_ImageCache cache, FTC_ImageType type, @@ -765,54 +790,57 @@ FT_BEGIN_HEADER FTC_Node *anode ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FTC_ImageCache_LookupScaler */ - /* */ - /* <Description> */ - /* A variant of @FTC_ImageCache_Lookup that uses an @FTC_ScalerRec */ - /* to specify the face ID and its size. */ - /* */ - /* <Input> */ - /* cache :: A handle to the source glyph image cache. */ - /* */ - /* scaler :: A pointer to a scaler descriptor. */ - /* */ - /* load_flags :: The corresponding load flags. */ - /* */ - /* gindex :: The glyph index to retrieve. */ - /* */ - /* <Output> */ - /* aglyph :: The corresponding @FT_Glyph object. 0~in case of */ - /* failure. */ - /* */ - /* anode :: Used to return the address of the corresponding */ - /* cache node after incrementing its reference count */ - /* (see note below). */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* The returned glyph is owned and managed by the glyph image cache. */ - /* Never try to transform or discard it manually! You can however */ - /* create a copy with @FT_Glyph_Copy and modify the new one. */ - /* */ - /* If `anode' is _not_ NULL, it receives the address of the cache */ - /* node containing the glyph image, after increasing its reference */ - /* count. This ensures that the node (as well as the @FT_Glyph) will */ - /* always be kept in the cache until you call @FTC_Node_Unref to */ - /* `release' it. */ - /* */ - /* If `anode' is NULL, the cache node is left unchanged, which means */ - /* that the @FT_Glyph could be flushed out of the cache on the next */ - /* call to one of the caching sub-system APIs. Don't assume that it */ - /* is persistent! */ - /* */ - /* Calls to @FT_Set_Char_Size and friends have no effect on cached */ - /* glyphs; you should always use the FreeType cache API instead. */ - /* */ + /************************************************************************** + * + * @function: + * FTC_ImageCache_LookupScaler + * + * @description: + * A variant of @FTC_ImageCache_Lookup that uses an @FTC_ScalerRec to + * specify the face ID and its size. + * + * @input: + * cache :: + * A handle to the source glyph image cache. + * + * scaler :: + * A pointer to a scaler descriptor. + * + * load_flags :: + * The corresponding load flags. + * + * gindex :: + * The glyph index to retrieve. + * + * @output: + * aglyph :: + * The corresponding @FT_Glyph object. 0~in case of failure. + * + * anode :: + * Used to return the address of the corresponding cache node after + * incrementing its reference count (see note below). + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The returned glyph is owned and managed by the glyph image cache. + * Never try to transform or discard it manually! You can however create + * a copy with @FT_Glyph_Copy and modify the new one. + * + * If `anode` is _not_ `NULL`, it receives the address of the cache node + * containing the glyph image, after increasing its reference count. + * This ensures that the node (as well as the @FT_Glyph) will always be + * kept in the cache until you call @FTC_Node_Unref to 'release' it. + * + * If `anode` is `NULL`, the cache node is left unchanged, which means + * that the @FT_Glyph could be flushed out of the cache on the next call + * to one of the caching sub-system APIs. Don't assume that it is + * persistent! + * + * Calls to @FT_Set_Char_Size and friends have no effect on cached + * glyphs; you should always use the FreeType cache API instead. + */ FT_EXPORT( FT_Error ) FTC_ImageCache_LookupScaler( FTC_ImageCache cache, FTC_Scaler scaler, @@ -822,53 +850,60 @@ FT_BEGIN_HEADER FTC_Node *anode ); - /*************************************************************************/ - /* */ - /* <Type> */ - /* FTC_SBit */ - /* */ - /* <Description> */ - /* A handle to a small bitmap descriptor. See the @FTC_SBitRec */ - /* structure for details. */ - /* */ + /************************************************************************** + * + * @type: + * FTC_SBit + * + * @description: + * A handle to a small bitmap descriptor. See the @FTC_SBitRec structure + * for details. + */ typedef struct FTC_SBitRec_* FTC_SBit; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FTC_SBitRec */ - /* */ - /* <Description> */ - /* A very compact structure used to describe a small glyph bitmap. */ - /* */ - /* <Fields> */ - /* width :: The bitmap width in pixels. */ - /* */ - /* height :: The bitmap height in pixels. */ - /* */ - /* left :: The horizontal distance from the pen position to the */ - /* left bitmap border (a.k.a. `left side bearing', or */ - /* `lsb'). */ - /* */ - /* top :: The vertical distance from the pen position (on the */ - /* baseline) to the upper bitmap border (a.k.a. `top */ - /* side bearing'). The distance is positive for upwards */ - /* y~coordinates. */ - /* */ - /* format :: The format of the glyph bitmap (monochrome or gray). */ - /* */ - /* max_grays :: Maximum gray level value (in the range 1 to~255). */ - /* */ - /* pitch :: The number of bytes per bitmap line. May be positive */ - /* or negative. */ - /* */ - /* xadvance :: The horizontal advance width in pixels. */ - /* */ - /* yadvance :: The vertical advance height in pixels. */ - /* */ - /* buffer :: A pointer to the bitmap pixels. */ - /* */ + /************************************************************************** + * + * @struct: + * FTC_SBitRec + * + * @description: + * A very compact structure used to describe a small glyph bitmap. + * + * @fields: + * width :: + * The bitmap width in pixels. + * + * height :: + * The bitmap height in pixels. + * + * left :: + * The horizontal distance from the pen position to the left bitmap + * border (a.k.a. 'left side bearing', or 'lsb'). + * + * top :: + * The vertical distance from the pen position (on the baseline) to the + * upper bitmap border (a.k.a. 'top side bearing'). The distance is + * positive for upwards y~coordinates. + * + * format :: + * The format of the glyph bitmap (monochrome or gray). + * + * max_grays :: + * Maximum gray level value (in the range 1 to~255). + * + * pitch :: + * The number of bytes per bitmap line. May be positive or negative. + * + * xadvance :: + * The horizontal advance width in pixels. + * + * yadvance :: + * The vertical advance height in pixels. + * + * buffer :: + * A pointer to the bitmap pixels. + */ typedef struct FTC_SBitRec_ { FT_Byte width; @@ -887,87 +922,93 @@ FT_BEGIN_HEADER } FTC_SBitRec; - /*************************************************************************/ - /* */ - /* <Type> */ - /* FTC_SBitCache */ - /* */ - /* <Description> */ - /* A handle to a small bitmap cache. These are special cache objects */ - /* used to store small glyph bitmaps (and anti-aliased pixmaps) in a */ - /* much more efficient way than the traditional glyph image cache */ - /* implemented by @FTC_ImageCache. */ - /* */ + /************************************************************************** + * + * @type: + * FTC_SBitCache + * + * @description: + * A handle to a small bitmap cache. These are special cache objects + * used to store small glyph bitmaps (and anti-aliased pixmaps) in a much + * more efficient way than the traditional glyph image cache implemented + * by @FTC_ImageCache. + */ typedef struct FTC_SBitCacheRec_* FTC_SBitCache; - /*************************************************************************/ - /* */ - /* <Function> */ - /* FTC_SBitCache_New */ - /* */ - /* <Description> */ - /* Create a new cache to store small glyph bitmaps. */ - /* */ - /* <Input> */ - /* manager :: A handle to the source cache manager. */ - /* */ - /* <Output> */ - /* acache :: A handle to the new sbit cache. NULL in case of error. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ + /************************************************************************** + * + * @function: + * FTC_SBitCache_New + * + * @description: + * Create a new cache to store small glyph bitmaps. + * + * @input: + * manager :: + * A handle to the source cache manager. + * + * @output: + * acache :: + * A handle to the new sbit cache. `NULL` in case of error. + * + * @return: + * FreeType error code. 0~means success. + */ FT_EXPORT( FT_Error ) FTC_SBitCache_New( FTC_Manager manager, FTC_SBitCache *acache ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FTC_SBitCache_Lookup */ - /* */ - /* <Description> */ - /* Look up a given small glyph bitmap in a given sbit cache and */ - /* `lock' it to prevent its flushing from the cache until needed. */ - /* */ - /* <Input> */ - /* cache :: A handle to the source sbit cache. */ - /* */ - /* type :: A pointer to the glyph image type descriptor. */ - /* */ - /* gindex :: The glyph index. */ - /* */ - /* <Output> */ - /* sbit :: A handle to a small bitmap descriptor. */ - /* */ - /* anode :: Used to return the address of the corresponding cache */ - /* node after incrementing its reference count (see note */ - /* below). */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* The small bitmap descriptor and its bit buffer are owned by the */ - /* cache and should never be freed by the application. They might */ - /* as well disappear from memory on the next cache lookup, so don't */ - /* treat them as persistent data. */ - /* */ - /* The descriptor's `buffer' field is set to~0 to indicate a missing */ - /* glyph bitmap. */ - /* */ - /* If `anode' is _not_ NULL, it receives the address of the cache */ - /* node containing the bitmap, after increasing its reference count. */ - /* This ensures that the node (as well as the image) will always be */ - /* kept in the cache until you call @FTC_Node_Unref to `release' it. */ - /* */ - /* If `anode' is NULL, the cache node is left unchanged, which means */ - /* that the bitmap could be flushed out of the cache on the next */ - /* call to one of the caching sub-system APIs. Don't assume that it */ - /* is persistent! */ - /* */ + /************************************************************************** + * + * @function: + * FTC_SBitCache_Lookup + * + * @description: + * Look up a given small glyph bitmap in a given sbit cache and 'lock' it + * to prevent its flushing from the cache until needed. + * + * @input: + * cache :: + * A handle to the source sbit cache. + * + * type :: + * A pointer to the glyph image type descriptor. + * + * gindex :: + * The glyph index. + * + * @output: + * sbit :: + * A handle to a small bitmap descriptor. + * + * anode :: + * Used to return the address of the corresponding cache node after + * incrementing its reference count (see note below). + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The small bitmap descriptor and its bit buffer are owned by the cache + * and should never be freed by the application. They might as well + * disappear from memory on the next cache lookup, so don't treat them as + * persistent data. + * + * The descriptor's `buffer` field is set to~0 to indicate a missing + * glyph bitmap. + * + * If `anode` is _not_ `NULL`, it receives the address of the cache node + * containing the bitmap, after increasing its reference count. This + * ensures that the node (as well as the image) will always be kept in + * the cache until you call @FTC_Node_Unref to 'release' it. + * + * If `anode` is `NULL`, the cache node is left unchanged, which means + * that the bitmap could be flushed out of the cache on the next call to + * one of the caching sub-system APIs. Don't assume that it is + * persistent! + */ FT_EXPORT( FT_Error ) FTC_SBitCache_Lookup( FTC_SBitCache cache, FTC_ImageType type, @@ -976,53 +1017,58 @@ FT_BEGIN_HEADER FTC_Node *anode ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FTC_SBitCache_LookupScaler */ - /* */ - /* <Description> */ - /* A variant of @FTC_SBitCache_Lookup that uses an @FTC_ScalerRec */ - /* to specify the face ID and its size. */ - /* */ - /* <Input> */ - /* cache :: A handle to the source sbit cache. */ - /* */ - /* scaler :: A pointer to the scaler descriptor. */ - /* */ - /* load_flags :: The corresponding load flags. */ - /* */ - /* gindex :: The glyph index. */ - /* */ - /* <Output> */ - /* sbit :: A handle to a small bitmap descriptor. */ - /* */ - /* anode :: Used to return the address of the corresponding */ - /* cache node after incrementing its reference count */ - /* (see note below). */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* The small bitmap descriptor and its bit buffer are owned by the */ - /* cache and should never be freed by the application. They might */ - /* as well disappear from memory on the next cache lookup, so don't */ - /* treat them as persistent data. */ - /* */ - /* The descriptor's `buffer' field is set to~0 to indicate a missing */ - /* glyph bitmap. */ - /* */ - /* If `anode' is _not_ NULL, it receives the address of the cache */ - /* node containing the bitmap, after increasing its reference count. */ - /* This ensures that the node (as well as the image) will always be */ - /* kept in the cache until you call @FTC_Node_Unref to `release' it. */ - /* */ - /* If `anode' is NULL, the cache node is left unchanged, which means */ - /* that the bitmap could be flushed out of the cache on the next */ - /* call to one of the caching sub-system APIs. Don't assume that it */ - /* is persistent! */ - /* */ + /************************************************************************** + * + * @function: + * FTC_SBitCache_LookupScaler + * + * @description: + * A variant of @FTC_SBitCache_Lookup that uses an @FTC_ScalerRec to + * specify the face ID and its size. + * + * @input: + * cache :: + * A handle to the source sbit cache. + * + * scaler :: + * A pointer to the scaler descriptor. + * + * load_flags :: + * The corresponding load flags. + * + * gindex :: + * The glyph index. + * + * @output: + * sbit :: + * A handle to a small bitmap descriptor. + * + * anode :: + * Used to return the address of the corresponding cache node after + * incrementing its reference count (see note below). + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The small bitmap descriptor and its bit buffer are owned by the cache + * and should never be freed by the application. They might as well + * disappear from memory on the next cache lookup, so don't treat them as + * persistent data. + * + * The descriptor's `buffer` field is set to~0 to indicate a missing + * glyph bitmap. + * + * If `anode` is _not_ `NULL`, it receives the address of the cache node + * containing the bitmap, after increasing its reference count. This + * ensures that the node (as well as the image) will always be kept in + * the cache until you call @FTC_Node_Unref to 'release' it. + * + * If `anode` is `NULL`, the cache node is left unchanged, which means + * that the bitmap could be flushed out of the cache on the next call to + * one of the caching sub-system APIs. Don't assume that it is + * persistent! + */ FT_EXPORT( FT_Error ) FTC_SBitCache_LookupScaler( FTC_SBitCache cache, FTC_Scaler scaler, diff --git a/sdk/lib/3rdparty/freetype/include/freetype/ftchapters.h b/sdk/lib/3rdparty/freetype/include/freetype/ftchapters.h index 51257bb7ca83f..2ee26973e4684 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/ftchapters.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/ftchapters.h @@ -1,139 +1,145 @@ -/***************************************************************************/ -/* */ -/* This file defines the structure of the FreeType reference. */ -/* It is used by the python script that generates the HTML files. */ -/* */ -/***************************************************************************/ - - -/***************************************************************************/ -/* */ -/* <Chapter> */ -/* general_remarks */ -/* */ -/* <Title> */ -/* General Remarks */ -/* */ -/* <Sections> */ -/* header_inclusion */ -/* user_allocation */ -/* */ -/***************************************************************************/ - - -/***************************************************************************/ -/* */ -/* <Chapter> */ -/* core_api */ -/* */ -/* <Title> */ -/* Core API */ -/* */ -/* <Sections> */ -/* version */ -/* basic_types */ -/* base_interface */ -/* glyph_variants */ -/* glyph_management */ -/* mac_specific */ -/* sizes_management */ -/* header_file_macros */ -/* */ -/***************************************************************************/ - - -/***************************************************************************/ -/* */ -/* <Chapter> */ -/* format_specific */ -/* */ -/* <Title> */ -/* Format-Specific API */ -/* */ -/* <Sections> */ -/* multiple_masters */ -/* truetype_tables */ -/* type1_tables */ -/* sfnt_names */ -/* bdf_fonts */ -/* cid_fonts */ -/* pfr_fonts */ -/* winfnt_fonts */ -/* font_formats */ -/* gasp_table */ -/* */ -/***************************************************************************/ - - -/***************************************************************************/ -/* */ -/* <Chapter> */ -/* module_specific */ -/* */ -/* <Title> */ -/* Controlling FreeType Modules */ -/* */ -/* <Sections> */ -/* auto_hinter */ -/* cff_driver */ -/* t1_cid_driver */ -/* tt_driver */ -/* pcf_driver */ -/* properties */ -/* parameter_tags */ -/* */ -/***************************************************************************/ - - -/***************************************************************************/ -/* */ -/* <Chapter> */ -/* cache_subsystem */ -/* */ -/* <Title> */ -/* Cache Sub-System */ -/* */ -/* <Sections> */ -/* cache_subsystem */ -/* */ -/***************************************************************************/ - - -/***************************************************************************/ -/* */ -/* <Chapter> */ -/* support_api */ -/* */ -/* <Title> */ -/* Support API */ -/* */ -/* <Sections> */ -/* computations */ -/* list_processing */ -/* outline_processing */ -/* quick_advance */ -/* bitmap_handling */ -/* raster */ -/* glyph_stroker */ -/* system_interface */ -/* module_management */ -/* gzip */ -/* lzw */ -/* bzip2 */ -/* lcd_filtering */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* <Chapter> */ -/* error_codes */ -/* */ -/* <Title> */ -/* Error Codes */ -/* */ -/* <Sections> */ -/* error_enumerations */ -/* error_code_values */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * This file defines the structure of the FreeType reference. + * It is used by the python script that generates the HTML files. + * + */ + + + /************************************************************************** + * + * @chapter: + * general_remarks + * + * @title: + * General Remarks + * + * @sections: + * header_inclusion + * user_allocation + * + */ + + + /************************************************************************** + * + * @chapter: + * core_api + * + * @title: + * Core API + * + * @sections: + * version + * basic_types + * base_interface + * glyph_variants + * color_management + * layer_management + * glyph_management + * mac_specific + * sizes_management + * header_file_macros + * + */ + + + /************************************************************************** + * + * @chapter: + * format_specific + * + * @title: + * Format-Specific API + * + * @sections: + * multiple_masters + * truetype_tables + * type1_tables + * sfnt_names + * bdf_fonts + * cid_fonts + * pfr_fonts + * winfnt_fonts + * font_formats + * gasp_table + * + */ + + + /************************************************************************** + * + * @chapter: + * module_specific + * + * @title: + * Controlling FreeType Modules + * + * @sections: + * auto_hinter + * cff_driver + * t1_cid_driver + * tt_driver + * pcf_driver + * properties + * parameter_tags + * lcd_rendering + * + */ + + + /************************************************************************** + * + * @chapter: + * cache_subsystem + * + * @title: + * Cache Sub-System + * + * @sections: + * cache_subsystem + * + */ + + + /************************************************************************** + * + * @chapter: + * support_api + * + * @title: + * Support API + * + * @sections: + * computations + * list_processing + * outline_processing + * quick_advance + * bitmap_handling + * raster + * glyph_stroker + * system_interface + * module_management + * gzip + * lzw + * bzip2 + * + */ + + + /************************************************************************** + * + * @chapter: + * error_codes + * + * @title: + * Error Codes + * + * @sections: + * error_enumerations + * error_code_values + * + */ + + +/* END */ diff --git a/sdk/lib/3rdparty/freetype/include/freetype/ftcid.h b/sdk/lib/3rdparty/freetype/include/freetype/ftcid.h index 5e9100a67cb66..8eafc1c78fd8b 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/ftcid.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/ftcid.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftcid.h */ -/* */ -/* FreeType API for accessing CID font information (specification). */ -/* */ -/* Copyright 2007-2018 by */ -/* Dereg Clegg and Michael Toftdal. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftcid.h + * + * FreeType API for accessing CID font information (specification). + * + * Copyright (C) 2007-2019 by + * Dereg Clegg and Michael Toftdal. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTCID_H_ @@ -32,25 +32,25 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* <Section> */ - /* cid_fonts */ - /* */ - /* <Title> */ - /* CID Fonts */ - /* */ - /* <Abstract> */ - /* CID-keyed font specific API. */ - /* */ - /* <Description> */ - /* This section contains the declaration of CID-keyed font specific */ - /* functions. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * @section: + * cid_fonts + * + * @title: + * CID Fonts + * + * @abstract: + * CID-keyed font-specific API. + * + * @description: + * This section contains the declaration of CID-keyed font-specific + * functions. + * + */ - /********************************************************************** + /************************************************************************** * * @function: * FT_Get_CID_Registry_Ordering_Supplement @@ -61,17 +61,17 @@ FT_BEGIN_HEADER * * @input: * face :: - * A handle to the input face. + * A handle to the input face. * * @output: * registry :: - * The registry, as a C~string, owned by the face. + * The registry, as a C~string, owned by the face. * * ordering :: - * The ordering, as a C~string, owned by the face. + * The ordering, as a C~string, owned by the face. * * supplement :: - * The supplement. + * The supplement. * * @return: * FreeType error code. 0~means success. @@ -90,30 +90,30 @@ FT_BEGIN_HEADER FT_Int *supplement ); - /********************************************************************** + /************************************************************************** * * @function: * FT_Get_CID_Is_Internally_CID_Keyed * * @description: - * Retrieve the type of the input face, CID keyed or not. In - * contrast to the @FT_IS_CID_KEYED macro this function returns - * successfully also for CID-keyed fonts in an SFNT wrapper. + * Retrieve the type of the input face, CID keyed or not. In contrast + * to the @FT_IS_CID_KEYED macro this function returns successfully also + * for CID-keyed fonts in an SFNT wrapper. * * @input: * face :: - * A handle to the input face. + * A handle to the input face. * * @output: * is_cid :: - * The type of the face as an @FT_Bool. + * The type of the face as an @FT_Bool. * * @return: * FreeType error code. 0~means success. * * @note: - * This function only works with CID faces and OpenType fonts, - * returning an error otherwise. + * This function only works with CID faces and OpenType fonts, returning + * an error otherwise. * * @since: * 2.3.9 @@ -123,7 +123,7 @@ FT_BEGIN_HEADER FT_Bool *is_cid ); - /********************************************************************** + /************************************************************************** * * @function: * FT_Get_CID_From_Glyph_Index @@ -133,21 +133,21 @@ FT_BEGIN_HEADER * * @input: * face :: - * A handle to the input face. + * A handle to the input face. * * glyph_index :: - * The input glyph index. + * The input glyph index. * * @output: * cid :: - * The CID as an @FT_UInt. + * The CID as an @FT_UInt. * * @return: * FreeType error code. 0~means success. * * @note: - * This function only works with CID faces and OpenType fonts, - * returning an error otherwise. + * This function only works with CID faces and OpenType fonts, returning + * an error otherwise. * * @since: * 2.3.9 diff --git a/sdk/lib/3rdparty/freetype/include/freetype/ftcolor.h b/sdk/lib/3rdparty/freetype/include/freetype/ftcolor.h new file mode 100644 index 0000000000000..cf18021953262 --- /dev/null +++ b/sdk/lib/3rdparty/freetype/include/freetype/ftcolor.h @@ -0,0 +1,311 @@ +/**************************************************************************** + * + * ftcolor.h + * + * FreeType's glyph color management (specification). + * + * Copyright (C) 2018-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + +#ifndef FTCOLOR_H_ +#define FTCOLOR_H_ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /************************************************************************** + * + * @section: + * color_management + * + * @title: + * Glyph Color Management + * + * @abstract: + * Retrieving and manipulating OpenType's 'CPAL' table data. + * + * @description: + * The functions described here allow access and manipulation of color + * palette entries in OpenType's 'CPAL' tables. + */ + + + /************************************************************************** + * + * @struct: + * FT_Color + * + * @description: + * This structure models a BGRA color value of a 'CPAL' palette entry. + * + * The used color space is sRGB; the colors are not pre-multiplied, and + * alpha values must be explicitly set. + * + * @fields: + * blue :: + * Blue value. + * + * green :: + * Green value. + * + * red :: + * Red value. + * + * alpha :: + * Alpha value, giving the red, green, and blue color's opacity. + * + * @since: + * 2.10 + */ + typedef struct FT_Color_ + { + FT_Byte blue; + FT_Byte green; + FT_Byte red; + FT_Byte alpha; + + } FT_Color; + + + /************************************************************************** + * + * @enum: + * FT_PALETTE_XXX + * + * @description: + * A list of bit field constants used in the `palette_flags` array of the + * @FT_Palette_Data structure to indicate for which background a palette + * with a given index is usable. + * + * @values: + * FT_PALETTE_FOR_LIGHT_BACKGROUND :: + * The palette is appropriate to use when displaying the font on a + * light background such as white. + * + * FT_PALETTE_FOR_DARK_BACKGROUND :: + * The palette is appropriate to use when displaying the font on a dark + * background such as black. + * + * @since: + * 2.10 + */ +#define FT_PALETTE_FOR_LIGHT_BACKGROUND 0x01 +#define FT_PALETTE_FOR_DARK_BACKGROUND 0x02 + + + /************************************************************************** + * + * @struct: + * FT_Palette_Data + * + * @description: + * This structure holds the data of the 'CPAL' table. + * + * @fields: + * num_palettes :: + * The number of palettes. + * + * palette_name_ids :: + * A read-only array of palette name IDs with `num_palettes` elements, + * corresponding to entries like 'dark' or 'light' in the font's 'name' + * table. + * + * An empty name ID in the 'CPAL' table gets represented as value + * 0xFFFF. + * + * `NULL` if the font's 'CPAL' table doesn't contain appropriate data. + * + * palette_flags :: + * A read-only array of palette flags with `num_palettes` elements. + * Possible values are an ORed combination of + * @FT_PALETTE_FOR_LIGHT_BACKGROUND and + * @FT_PALETTE_FOR_DARK_BACKGROUND. + * + * `NULL` if the font's 'CPAL' table doesn't contain appropriate data. + * + * num_palette_entries :: + * The number of entries in a single palette. All palettes have the + * same size. + * + * palette_entry_name_ids :: + * A read-only array of palette entry name IDs with + * `num_palette_entries`. In each palette, entries with the same index + * have the same function. For example, index~0 might correspond to + * string 'outline' in the font's 'name' table to indicate that this + * palette entry is used for outlines, index~1 might correspond to + * 'fill' to indicate the filling color palette entry, etc. + * + * An empty entry name ID in the 'CPAL' table gets represented as value + * 0xFFFF. + * + * `NULL` if the font's 'CPAL' table doesn't contain appropriate data. + * + * @note: + * Use function @FT_Get_Sfnt_Name to map name IDs and entry name IDs to + * name strings. + * + * @since: + * 2.10 + */ + typedef struct FT_Palette_Data_ { + FT_UShort num_palettes; + const FT_UShort* palette_name_ids; + const FT_UShort* palette_flags; + + FT_UShort num_palette_entries; + const FT_UShort* palette_entry_name_ids; + + } FT_Palette_Data; + + + /************************************************************************** + * + * @function: + * FT_Palette_Data_Get + * + * @description: + * Retrieve the face's color palette data. + * + * @input: + * face :: + * The source face handle. + * + * @output: + * apalette :: + * A pointer to an @FT_Palette_Data structure. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * All arrays in the returned @FT_Palette_Data structure are read-only. + * + * This function always returns an error if the config macro + * `TT_CONFIG_OPTION_COLOR_LAYERS` is not defined in `ftoption.h`. + * + * @since: + * 2.10 + */ + FT_EXPORT( FT_Error ) + FT_Palette_Data_Get( FT_Face face, + FT_Palette_Data *apalette ); + + + /************************************************************************** + * + * @function: + * FT_Palette_Select + * + * @description: + * This function has two purposes. + * + * (1) It activates a palette for rendering color glyphs, and + * + * (2) it retrieves all (unmodified) color entries of this palette. This + * function returns a read-write array, which means that a calling + * application can modify the palette entries on demand. + * + * A corollary of (2) is that calling the function, then modifying some + * values, then calling the function again with the same arguments resets + * all color entries to the original 'CPAL' values; all user modifications + * are lost. + * + * @input: + * face :: + * The source face handle. + * + * palette_index :: + * The palette index. + * + * @output: + * apalette :: + * An array of color entries for a palette with index `palette_index`, + * having `num_palette_entries` elements (as found in the + * `FT_Palette_Data` structure). If `apalette` is set to `NULL`, no + * array gets returned (and no color entries can be modified). + * + * In case the font doesn't support color palettes, `NULL` is returned. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The array pointed to by `apalette_entries` is owned and managed by + * FreeType. + * + * This function always returns an error if the config macro + * `TT_CONFIG_OPTION_COLOR_LAYERS` is not defined in `ftoption.h`. + * + * @since: + * 2.10 + */ + FT_EXPORT( FT_Error ) + FT_Palette_Select( FT_Face face, + FT_UShort palette_index, + FT_Color* *apalette ); + + + /************************************************************************** + * + * @function: + * FT_Palette_Set_Foreground_Color + * + * @description: + * 'COLR' uses palette index 0xFFFF to indicate a 'text foreground + * color'. This function sets this value. + * + * @input: + * face :: + * The source face handle. + * + * foreground_color :: + * An `FT_Color` structure to define the text foreground color. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * If this function isn't called, the text foreground color is set to + * white opaque (BGRA value 0xFFFFFFFF) if + * @FT_PALETTE_FOR_DARK_BACKGROUND is present for the current palette, + * and black opaque (BGRA value 0x000000FF) otherwise, including the case + * that no palette types are available in the 'CPAL' table. + * + * This function always returns an error if the config macro + * `TT_CONFIG_OPTION_COLOR_LAYERS` is not defined in `ftoption.h`. + * + * @since: + * 2.10 + */ + FT_EXPORT( FT_Error ) + FT_Palette_Set_Foreground_Color( FT_Face face, + FT_Color foreground_color ); + + /* */ + + +FT_END_HEADER + +#endif /* FTCOLOR_H_ */ + + +/* END */ diff --git a/sdk/lib/3rdparty/freetype/include/freetype/ftdriver.h b/sdk/lib/3rdparty/freetype/include/freetype/ftdriver.h index be4fe235d0209..497bde9f6ed15 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/ftdriver.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/ftdriver.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftdriver.h */ -/* */ -/* FreeType API for controlling driver modules (specification only). */ -/* */ -/* Copyright 2017-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftdriver.h + * + * FreeType API for controlling driver modules (specification only). + * + * Copyright (C) 2017-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTDRIVER_H_ @@ -50,8 +50,8 @@ FT_BEGIN_HEADER * @FT_Property_Get. The following lists the available properties * together with the necessary macros and structures. * - * Note that the auto-hinter's module name is `autofitter' for - * historical reasons. + * Note that the auto-hinter's module name is 'autofitter' for historical + * reasons. * * Available properties are @increase-x-height, @no-stem-darkening * (experimental), @darkening-parameters (experimental), @warping @@ -74,18 +74,18 @@ FT_BEGIN_HEADER * Controlling the CFF driver module. * * @description: - * While FreeType's CFF driver doesn't expose API functions by itself, - * it is possible to control its behaviour with @FT_Property_Set and + * While FreeType's CFF driver doesn't expose API functions by itself, it + * is possible to control its behaviour with @FT_Property_Set and * @FT_Property_Get. * - * The CFF driver's module name is `cff'. + * The CFF driver's module name is 'cff'. * * Available properties are @hinting-engine, @no-stem-darkening, * @darkening-parameters, and @random-seed, as documented in the * @properties section. * * - * *Hinting* *and* *antialiasing* *principles* *of* *the* *new* *engine* + * **Hinting and antialiasing principles of the new engine** * * The rasterizer is positioning horizontal features (e.g., ascender * height & x-height, or crossbars) on the pixel grid and minimizing the @@ -93,35 +93,34 @@ FT_BEGIN_HEADER * features (vertical stems) on the pixel grid without hinting, thus * representing the stem position and weight accurately. Sometimes the * vertical stems may be only partially black. In this context, - * `antialiasing' means that stems are not positioned exactly on pixel + * 'antialiasing' means that stems are not positioned exactly on pixel * borders, causing a fuzzy appearance. * * There are two principles behind this approach. * - * 1) No hinting in the horizontal direction: Unlike `superhinted' + * 1) No hinting in the horizontal direction: Unlike 'superhinted' * TrueType, which changes glyph widths to accommodate regular - * inter-glyph spacing, Adobe's approach is `faithful to the design' in - * representing both the glyph width and the inter-glyph spacing - * designed for the font. This makes the screen display as close as it - * can be to the result one would get with infinite resolution, while - * preserving what is considered the key characteristics of each glyph. - * Note that the distances between unhinted and grid-fitted positions at - * small sizes are comparable to kerning values and thus would be - * noticeable (and distracting) while reading if hinting were applied. + * inter-glyph spacing, Adobe's approach is 'faithful to the design' in + * representing both the glyph width and the inter-glyph spacing designed + * for the font. This makes the screen display as close as it can be to + * the result one would get with infinite resolution, while preserving + * what is considered the key characteristics of each glyph. Note that + * the distances between unhinted and grid-fitted positions at small + * sizes are comparable to kerning values and thus would be noticeable + * (and distracting) while reading if hinting were applied. * * One of the reasons to not hint horizontally is antialiasing for LCD - * screens: The pixel geometry of modern displays supplies three - * vertical sub-pixels as the eye moves horizontally across each visible - * pixel. On devices where we can be certain this characteristic is - * present a rasterizer can take advantage of the sub-pixels to add - * increments of weight. In Western writing systems this turns out to - * be the more critical direction anyway; the weights and spacing of - * vertical stems (see above) are central to Armenian, Cyrillic, Greek, - * and Latin type designs. Even when the rasterizer uses greyscale - * antialiasing instead of color (a necessary compromise when one - * doesn't know the screen characteristics), the unhinted vertical - * features preserve the design's weight and spacing much better than - * aliased type would. + * screens: The pixel geometry of modern displays supplies three vertical + * subpixels as the eye moves horizontally across each visible pixel. On + * devices where we can be certain this characteristic is present a + * rasterizer can take advantage of the subpixels to add increments of + * weight. In Western writing systems this turns out to be the more + * critical direction anyway; the weights and spacing of vertical stems + * (see above) are central to Armenian, Cyrillic, Greek, and Latin type + * designs. Even when the rasterizer uses greyscale antialiasing instead + * of color (a necessary compromise when one doesn't know the screen + * characteristics), the unhinted vertical features preserve the design's + * weight and spacing much better than aliased type would. * * 2) Alignment in the vertical direction: Weights and spacing along the * y~axis are less critical; what is much more important is the visual @@ -132,16 +131,16 @@ FT_BEGIN_HEADER * * On the technical side, horizontal alignment zones for ascender, * x-height, and other important height values (traditionally called - * `blue zones') as defined in the font are positioned independently, - * each being rounded to the nearest pixel edge, taking care of - * overshoot suppression at small sizes, stem darkening, and scaling. + * 'blue zones') as defined in the font are positioned independently, + * each being rounded to the nearest pixel edge, taking care of overshoot + * suppression at small sizes, stem darkening, and scaling. * * Hstems (this is, hint values defined in the font to help align * horizontal features) that fall within a blue zone are said to be - * `captured' and are aligned to that zone. Uncaptured stems are moved + * 'captured' and are aligned to that zone. Uncaptured stems are moved * in one of four ways, top edge up or down, bottom edge up or down. - * Unless there are conflicting hstems, the smallest movement is taken - * to minimize distortion. + * Unless there are conflicting hstems, the smallest movement is taken to + * minimize distortion. * */ @@ -158,13 +157,13 @@ FT_BEGIN_HEADER * Controlling the PCF driver module. * * @description: - * While FreeType's PCF driver doesn't expose API functions by itself, - * it is possible to control its behaviour with @FT_Property_Set and + * While FreeType's PCF driver doesn't expose API functions by itself, it + * is possible to control its behaviour with @FT_Property_Set and * @FT_Property_Get. Right now, there is a single property * @no-long-family-names available if FreeType is compiled with * PCF_CONFIG_OPTION_LONG_FAMILY_NAMES. * - * The PCF driver's module name is `pcf'. + * The PCF driver's module name is 'pcf'. * */ @@ -187,15 +186,15 @@ FT_BEGIN_HEADER * Behind the scenes, both drivers use the Adobe CFF engine for hinting; * however, the used properties must be specified separately. * - * The Type~1 driver's module name is `type1'; the CID driver's module - * name is `t1cid'. + * The Type~1 driver's module name is 'type1'; the CID driver's module + * name is 't1cid'. * * Available properties are @hinting-engine, @no-stem-darkening, * @darkening-parameters, and @random-seed, as documented in the * @properties section. * - * Please see the @cff_driver section for more details on the new - * hinting engine. + * Please see the @cff_driver section for more details on the new hinting + * engine. * */ @@ -217,7 +216,7 @@ FT_BEGIN_HEADER * and @FT_Property_Get. The following lists the available properties * together with the necessary macros and structures. * - * The TrueType driver's module name is `truetype'. + * The TrueType driver's module name is 'truetype'. * * A single property @interpreter-version is available, as documented in * the @properties section. @@ -225,36 +224,36 @@ FT_BEGIN_HEADER * We start with a list of definitions, kindly provided by Greg * Hitchcock. * - * _Bi-Level_ _Rendering_ + * _Bi-Level Rendering_ * * Monochromatic rendering, exclusively used in the early days of * TrueType by both Apple and Microsoft. Microsoft's GDI interface * supported hinting of the right-side bearing point, such that the * advance width could be non-linear. Most often this was done to * achieve some level of glyph symmetry. To enable reasonable - * performance (e.g., not having to run hinting on all glyphs just to - * get the widths) there was a bit in the head table indicating if the - * side bearing was hinted, and additional tables, `hdmx' and `LTSH', to - * cache hinting widths across multiple sizes and device aspect ratios. + * performance (e.g., not having to run hinting on all glyphs just to get + * the widths) there was a bit in the head table indicating if the side + * bearing was hinted, and additional tables, 'hdmx' and 'LTSH', to cache + * hinting widths across multiple sizes and device aspect ratios. * - * _Font_ _Smoothing_ + * _Font Smoothing_ * * Microsoft's GDI implementation of anti-aliasing. Not traditional * anti-aliasing as the outlines were hinted before the sampling. The * widths matched the bi-level rendering. * - * _ClearType_ _Rendering_ + * _ClearType Rendering_ * * Technique that uses physical subpixels to improve rendering on LCD * (and other) displays. Because of the higher resolution, many methods - * of improving symmetry in glyphs through hinting the right-side - * bearing were no longer necessary. This lead to what GDI calls - * `natural widths' ClearType, see - * http://www.beatstamm.com/typography/RTRCh4.htm#Sec21. Since hinting + * of improving symmetry in glyphs through hinting the right-side bearing + * were no longer necessary. This lead to what GDI calls 'natural + * widths' ClearType, see + * http://rastertragedy.com/RTRCh4.htm#Sec21. Since hinting * has extra resolution, most non-linearity went away, but it is still * possible for hints to change the advance widths in this mode. * - * _ClearType_ _Compatible_ _Widths_ + * _ClearType Compatible Widths_ * * One of the earliest challenges with ClearType was allowing the * implementation in GDI to be selected without requiring all UI and @@ -263,41 +262,41 @@ FT_BEGIN_HEADER * to determine the width in bi-level rendering, and then re-run in * ClearType, with the difference in widths being absorbed in the font * hints for ClearType (mostly in the white space of hints); see - * http://www.beatstamm.com/typography/RTRCh4.htm#Sec20. Somewhat by + * http://rastertragedy.com/RTRCh4.htm#Sec20. Somewhat by * definition, compatible width ClearType allows for non-linear widths, * but only when the bi-level version has non-linear widths. * - * _ClearType_ _Subpixel_ _Positioning_ + * _ClearType Subpixel Positioning_ * * One of the nice benefits of ClearType is the ability to more crisply * display fractional widths; unfortunately, the GDI model of integer * bitmaps did not support this. However, the WPF and Direct Write - * frameworks do support fractional widths. DWrite calls this `natural - * mode', not to be confused with GDI's `natural widths'. Subpixel + * frameworks do support fractional widths. DWrite calls this 'natural + * mode', not to be confused with GDI's 'natural widths'. Subpixel * positioning, in the current implementation of Direct Write, * unfortunately does not support hinted advance widths, see - * http://www.beatstamm.com/typography/RTRCh4.htm#Sec22. Note that the + * http://rastertragedy.com/RTRCh4.htm#Sec22. Note that the * TrueType interpreter fully allows the advance width to be adjusted in * this mode, just the DWrite client will ignore those changes. * - * _ClearType_ _Backward_ _Compatibility_ + * _ClearType Backward Compatibility_ * * This is a set of exceptions made in the TrueType interpreter to * minimize hinting techniques that were problematic with the extra * resolution of ClearType; see - * http://www.beatstamm.com/typography/RTRCh4.htm#Sec1 and + * http://rastertragedy.com/RTRCh4.htm#Sec1 and * https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx. - * This technique is not to be confused with ClearType compatible - * widths. ClearType backward compatibility has no direct impact on - * changing advance widths, but there might be an indirect impact on - * disabling some deltas. This could be worked around in backward - * compatibility mode. + * This technique is not to be confused with ClearType compatible widths. + * ClearType backward compatibility has no direct impact on changing + * advance widths, but there might be an indirect impact on disabling + * some deltas. This could be worked around in backward compatibility + * mode. * - * _Native_ _ClearType_ _Mode_ + * _Native ClearType Mode_ * - * (Not to be confused with `natural widths'.) This mode removes all - * the exceptions in the TrueType interpreter when running with - * ClearType. Any issues on widths would still apply, though. + * (Not to be confused with 'natural widths'.) This mode removes all the + * exceptions in the TrueType interpreter when running with ClearType. + * Any issues on widths would still apply, though. * */ @@ -328,8 +327,8 @@ FT_BEGIN_HEADER * FT_HINTING_XXX * * @description: - * A list of constants used for the @hinting-engine property to - * select the hinting engine for CFF, Type~1, and CID fonts. + * A list of constants used for the @hinting-engine property to select + * the hinting engine for CFF, Type~1, and CID fonts. * * @values: * FT_HINTING_FREETYPE :: @@ -356,45 +355,46 @@ FT_BEGIN_HEADER * hinting-engine * * @description: - * Thanks to Adobe, which contributed a new hinting (and parsing) - * engine, an application can select between `freetype' and `adobe' if - * compiled with CFF_CONFIG_OPTION_OLD_ENGINE. If this configuration - * macro isn't defined, `hinting-engine' does nothing. + * Thanks to Adobe, which contributed a new hinting (and parsing) engine, + * an application can select between 'freetype' and 'adobe' if compiled + * with `CFF_CONFIG_OPTION_OLD_ENGINE`. If this configuration macro + * isn't defined, 'hinting-engine' does nothing. * * The same holds for the Type~1 and CID modules if compiled with - * T1_CONFIG_OPTION_OLD_ENGINE. + * `T1_CONFIG_OPTION_OLD_ENGINE`. * - * For the `cff' module, the default engine is `freetype' if - * CFF_CONFIG_OPTION_OLD_ENGINE is defined, and `adobe' otherwise. + * For the 'cff' module, the default engine is 'freetype' if + * `CFF_CONFIG_OPTION_OLD_ENGINE` is defined, and 'adobe' otherwise. * - * For both the `type1' and `t1cid' modules, the default engine is - * `freetype' if T1_CONFIG_OPTION_OLD_ENGINE is defined, and `adobe' + * For both the 'type1' and 't1cid' modules, the default engine is + * 'freetype' if `T1_CONFIG_OPTION_OLD_ENGINE` is defined, and 'adobe' * otherwise. * + * @note: + * This property can be used with @FT_Property_Get also. + * + * This property can be set via the `FREETYPE_PROPERTIES` environment + * variable (using values 'adobe' or 'freetype'). + * + * @example: * The following example code demonstrates how to select Adobe's hinting - * engine for the `cff' module (omitting the error handling). + * engine for the 'cff' module (omitting the error handling). * - * { + * ``` * FT_Library library; - * FT_UInt hinting_engine = FT_CFF_HINTING_ADOBE; + * FT_UInt hinting_engine = FT_HINTING_ADOBE; * * * FT_Init_FreeType( &library ); * * FT_Property_Set( library, "cff", * "hinting-engine", &hinting_engine ); - * } - * - * @note: - * This property can be used with @FT_Property_Get also. - * - * This property can be set via the `FREETYPE_PROPERTIES' environment - * variable (using values `adobe' or `freetype'). + * ``` * * @since: - * 2.4.12 (for `cff' module) + * 2.4.12 (for 'cff' module) * - * 2.9 (for `type1' and `t1cid' modules) + * 2.9 (for 'type1' and 't1cid' modules) * */ @@ -405,10 +405,10 @@ FT_BEGIN_HEADER * no-stem-darkening * * @description: - * All glyphs that pass through the auto-hinter will be emboldened - * unless this property is set to TRUE. The same is true for the CFF, - * Type~1, and CID font modules if the `Adobe' engine is selected (which - * is the default). + * All glyphs that pass through the auto-hinter will be emboldened unless + * this property is set to TRUE. The same is true for the CFF, Type~1, + * and CID font modules if the 'Adobe' engine is selected (which is the + * default). * * Stem darkening emboldens glyphs at smaller sizes to make them more * readable on common low-DPI screens when using linear alpha blending @@ -419,30 +419,38 @@ FT_BEGIN_HEADER * Gamma correction essentially lightens fonts since shades of grey are * shifted to higher pixel values (=~higher brightness) to match the * original intention to the reality of our screens. The side-effect is - * that glyphs `thin out'. Mac OS~X and Adobe's proprietary font + * that glyphs 'thin out'. Mac OS~X and Adobe's proprietary font * rendering library implement a counter-measure: stem darkening at * smaller sizes where shades of gray dominate. By emboldening a glyph * slightly in relation to its pixel size, individual pixels get higher - * coverage of filled-in outlines and are therefore `blacker'. This - * counteracts the `thinning out' of glyphs, making text remain readable + * coverage of filled-in outlines and are therefore 'blacker'. This + * counteracts the 'thinning out' of glyphs, making text remain readable * at smaller sizes. * * By default, the Adobe engines for CFF, Type~1, and CID fonts darken * stems at smaller sizes, regardless of hinting, to enhance contrast. * Setting this property, stem darkening gets switched off. * - * For the auto-hinter, stem-darkening is experimental currently and - * thus switched off by default (this is, `no-stem-darkening' is set to - * TRUE by default). Total consistency with the CFF driver is not - * achieved right now because the emboldening method differs and glyphs - * must be scaled down on the Y-axis to keep outline points inside their + * For the auto-hinter, stem-darkening is experimental currently and thus + * switched off by default (this is, `no-stem-darkening` is set to TRUE + * by default). Total consistency with the CFF driver is not achieved + * right now because the emboldening method differs and glyphs must be + * scaled down on the Y-axis to keep outline points inside their * precomputed blue zones. The smaller the size (especially 9ppem and * down), the higher the loss of emboldening versus the CFF driver. * - * Note that stem darkening is never applied if @FT_LOAD_NO_SCALE is - * set. + * Note that stem darkening is never applied if @FT_LOAD_NO_SCALE is set. + * + * @note: + * This property can be used with @FT_Property_Get also. + * + * This property can be set via the `FREETYPE_PROPERTIES` environment + * variable (using values 1 and 0 for 'on' and 'off', respectively). It + * can also be set per face using @FT_Face_Properties with + * @FT_PARAM_TAG_STEM_DARKENING. * - * { + * @example: + * ``` * FT_Library library; * FT_Bool no_stem_darkening = TRUE; * @@ -451,22 +459,14 @@ FT_BEGIN_HEADER * * FT_Property_Set( library, "cff", * "no-stem-darkening", &no_stem_darkening ); - * } - * - * @note: - * This property can be used with @FT_Property_Get also. - * - * This property can be set via the `FREETYPE_PROPERTIES' environment - * variable (using values 1 and 0 for `on' and `off', respectively). - * It can also be set per face using @FT_Face_Properties with - * @FT_PARAM_TAG_STEM_DARKENING. + * ``` * * @since: - * 2.4.12 (for `cff' module) + * 2.4.12 (for 'cff' module) * - * 2.6.2 (for `autofitter' module) + * 2.6.2 (for 'autofitter' module) * - * 2.9 (for `type1' and `t1cid' modules) + * 2.9 (for 'type1' and 't1cid' modules) * */ @@ -478,43 +478,29 @@ FT_BEGIN_HEADER * * @description: * By default, the Adobe hinting engine, as used by the CFF, Type~1, and - * CID font drivers, darkens stems as follows (if the - * `no-stem-darkening' property isn't set): + * CID font drivers, darkens stems as follows (if the `no-stem-darkening` + * property isn't set): * - * { + * ``` * stem width <= 0.5px: darkening amount = 0.4px * stem width = 1px: darkening amount = 0.275px * stem width = 1.667px: darkening amount = 0.275px * stem width >= 2.333px: darkening amount = 0px - * } + * ``` * * and piecewise linear in-between. At configuration time, these four * control points can be set with the macro - * `CFF_CONFIG_OPTION_DARKENING_PARAMETERS'; the CFF, Type~1, and CID + * `CFF_CONFIG_OPTION_DARKENING_PARAMETERS`; the CFF, Type~1, and CID * drivers share these values. At runtime, the control points can be - * changed using the `darkening-parameters' property, as the following - * example demonstrates for the Type~1 driver. - * - * { - * FT_Library library; - * FT_Int darken_params[8] = { 500, 300, // x1, y1 - * 1000, 200, // x2, y2 - * 1500, 100, // x3, y3 - * 2000, 0 }; // x4, y4 - * - * - * FT_Init_FreeType( &library ); - * - * FT_Property_Set( library, "type1", - * "darkening-parameters", darken_params ); - * } + * changed using the `darkening-parameters` property (see the example + * below that demonstrates this for the Type~1 driver). * * The x~values give the stem width, and the y~values the darkening * amount. The unit is 1000th of pixels. All coordinate values must be - * positive; the x~values must be monotonically increasing; the - * y~values must be monotonically decreasing and smaller than or - * equal to 500 (corresponding to half a pixel); the slope of each - * linear piece must be shallower than -1 (e.g., -.4). + * positive; the x~values must be monotonically increasing; the y~values + * must be monotonically decreasing and smaller than or equal to 500 + * (corresponding to half a pixel); the slope of each linear piece must + * be shallower than -1 (e.g., -.4). * * The auto-hinter provides this property, too, as an experimental * feature. See @no-stem-darkening for more. @@ -522,21 +508,36 @@ FT_BEGIN_HEADER * @note: * This property can be used with @FT_Property_Get also. * - * This property can be set via the `FREETYPE_PROPERTIES' environment + * This property can be set via the `FREETYPE_PROPERTIES` environment * variable, using eight comma-separated integers without spaces. Here - * the above example, using `\' to break the line for readability. + * the above example, using `\` to break the line for readability. * - * { + * ``` * FREETYPE_PROPERTIES=\ * type1:darkening-parameters=500,300,1000,200,1500,100,2000,0 - * } + * ``` + * + * @example: + * ``` + * FT_Library library; + * FT_Int darken_params[8] = { 500, 300, // x1, y1 + * 1000, 200, // x2, y2 + * 1500, 100, // x3, y3 + * 2000, 0 }; // x4, y4 + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "type1", + * "darkening-parameters", darken_params ); + * ``` * * @since: - * 2.5.1 (for `cff' module) + * 2.5.1 (for 'cff' module) * - * 2.6.2 (for `autofitter' module) + * 2.6.2 (for 'autofitter' module) * - * 2.9 (for `type1' and `t1cid' modules) + * 2.9 (for 'type1' and 't1cid' modules) * */ @@ -547,29 +548,29 @@ FT_BEGIN_HEADER * random-seed * * @description: - * By default, the seed value for the CFF `random' operator and the - * similar `0 28 callothersubr pop' command for the Type~1 and CID + * By default, the seed value for the CFF 'random' operator and the + * similar '0 28 callothersubr pop' command for the Type~1 and CID * drivers is set to a random value. However, mainly for debugging - * purposes, it is often necessary to use a known value as a seed so - * that the pseudo-random number sequences generated by `random' are + * purposes, it is often necessary to use a known value as a seed so that + * the pseudo-random number sequences generated by 'random' are * repeatable. * - * The `random-seed' property does that. Its argument is a signed 32bit + * The `random-seed` property does that. Its argument is a signed 32bit * integer; if the value is zero or negative, the seed given by the - * `intitialRandomSeed' private DICT operator in a CFF file gets used - * (or a default value if there is no such operator). If the value is - * positive, use it instead of `initialRandomSeed', which is - * consequently ignored. + * `intitialRandomSeed` private DICT operator in a CFF file gets used (or + * a default value if there is no such operator). If the value is + * positive, use it instead of `initialRandomSeed`, which is consequently + * ignored. * * @note: - * This property can be set via the `FREETYPE_PROPERTIES' environment + * This property can be set via the `FREETYPE_PROPERTIES` environment * variable. It can also be set per face using @FT_Face_Properties with * @FT_PARAM_TAG_RANDOM_SEED. * * @since: - * 2.8 (for `cff' module) + * 2.8 (for 'cff' module) * - * 2.9 (for `type1' and `t1cid' modules) + * 2.9 (for 'type1' and 't1cid' modules) * */ @@ -580,21 +581,28 @@ FT_BEGIN_HEADER * no-long-family-names * * @description: - * If PCF_CONFIG_OPTION_LONG_FAMILY_NAMES is active while compiling + * If `PCF_CONFIG_OPTION_LONG_FAMILY_NAMES` is active while compiling * FreeType, the PCF driver constructs long family names. * - * There are many PCF fonts just called `Fixed' which look completely + * There are many PCF fonts just called 'Fixed' which look completely * different, and which have nothing to do with each other. When - * selecting `Fixed' in KDE or Gnome one gets results that appear rather - * random, the style changes often if one changes the size and one - * cannot select some fonts at all. The improve this situation, the PCF - * module prepends the foundry name (plus a space) to the family name. - * It also checks whether there are `wide' characters; all put together, - * family names like `Sony Fixed' or `Misc Fixed Wide' are constructed. + * selecting 'Fixed' in KDE or Gnome one gets results that appear rather + * random, the style changes often if one changes the size and one cannot + * select some fonts at all. The improve this situation, the PCF module + * prepends the foundry name (plus a space) to the family name. It also + * checks whether there are 'wide' characters; all put together, family + * names like 'Sony Fixed' or 'Misc Fixed Wide' are constructed. + * + * If `no-long-family-names` is set, this feature gets switched off. * - * If `no-long-family-names' is set, this feature gets switched off. + * @note: + * This property can be used with @FT_Property_Get also. * - * { + * This property can be set via the `FREETYPE_PROPERTIES` environment + * variable (using values 1 and 0 for 'on' and 'off', respectively). + * + * @example: + * ``` * FT_Library library; * FT_Bool no_long_family_names = TRUE; * @@ -604,13 +612,7 @@ FT_BEGIN_HEADER * FT_Property_Set( library, "pcf", * "no-long-family-names", * &no_long_family_names ); - * } - * - * @note: - * This property can be used with @FT_Property_Get also. - * - * This property can be set via the `FREETYPE_PROPERTIES' environment - * variable (using values 1 and 0 for `on' and `off', respectively). + * ``` * * @since: * 2.8 @@ -626,8 +628,8 @@ FT_BEGIN_HEADER * A list of constants used for the @interpreter-version property to * select the hinting engine for Truetype fonts. * - * The numeric value in the constant names represents the version - * number as returned by the `GETINFO' bytecode instruction. + * The numeric value in the constant names represents the version number + * as returned by the 'GETINFO' bytecode instruction. * * @values: * TT_INTERPRETER_VERSION_35 :: @@ -638,38 +640,37 @@ FT_BEGIN_HEADER * Version~38 corresponds to MS rasterizer v.1.9; it is roughly * equivalent to the hinting provided by DirectWrite ClearType (as can * be found, for example, in the Internet Explorer~9 running on - * Windows~7). It is used in FreeType to select the `Infinality' - * subpixel hinting code. The code may be removed in a future - * version. + * Windows~7). It is used in FreeType to select the 'Infinality' + * subpixel hinting code. The code may be removed in a future version. * * TT_INTERPRETER_VERSION_40 :: * Version~40 corresponds to MS rasterizer v.2.1; it is roughly * equivalent to the hinting provided by DirectWrite ClearType (as can * be found, for example, in Microsoft's Edge Browser on Windows~10). - * It is used in FreeType to select the `minimal' subpixel hinting + * It is used in FreeType to select the 'minimal' subpixel hinting * code, a stripped-down and higher performance version of the - * `Infinality' code. + * 'Infinality' code. * * @note: - * This property controls the behaviour of the bytecode interpreter - * and thus how outlines get hinted. It does *not* control how glyph - * get rasterized! In particular, it does not control subpixel color + * This property controls the behaviour of the bytecode interpreter and + * thus how outlines get hinted. It does **not** control how glyph get + * rasterized! In particular, it does not control subpixel color * filtering. * * If FreeType has not been compiled with the configuration option - * TT_CONFIG_OPTION_SUBPIXEL_HINTING, selecting version~38 or~40 causes - * an `FT_Err_Unimplemented_Feature' error. + * `TT_CONFIG_OPTION_SUBPIXEL_HINTING`, selecting version~38 or~40 causes + * an `FT_Err_Unimplemented_Feature` error. * - * Depending on the graphics framework, Microsoft uses different - * bytecode and rendering engines. As a consequence, the version - * numbers returned by a call to the `GETINFO' bytecode instruction are - * more convoluted than desired. + * Depending on the graphics framework, Microsoft uses different bytecode + * and rendering engines. As a consequence, the version numbers returned + * by a call to the 'GETINFO' bytecode instruction are more convoluted + * than desired. * - * Here are two tables that try to shed some light on the possible - * values for the MS rasterizer engine, together with the additional - * features introduced by it. + * Here are two tables that try to shed some light on the possible values + * for the MS rasterizer engine, together with the additional features + * introduced by it. * - * { + * ``` * GETINFO framework version feature * ------------------------------------------------------------------- * 3 GDI (Win 3.1), v1.0 16-bit, first version @@ -692,15 +693,15 @@ FT_BEGIN_HEADER * 40 GDI+ (after Win 7), v2.1 Y-direction ClearType flag * DWrite (Win 8) in GETINFO opcode, * Gray ClearType - * } + * ``` * - * The `version' field gives a rough orientation only, since some + * The 'version' field gives a rough orientation only, since some * applications provided certain features much earlier (as an example, * Microsoft Reader used subpixel and Y-direction ClearType already in * Windows 2000). Similarly, updates to a given framework might include * improved hinting support. * - * { + * ``` * version sampling rendering comment * x y x y * -------------------------------------------------------------- @@ -710,38 +711,38 @@ FT_BEGIN_HEADER * v1.9 high high color-filter gray Color ClearType * v2.1 high normal gray B/W Gray ClearType * v2.1 high high gray gray Gray ClearType - * } + * ``` * * Color and Gray ClearType are the two available variants of - * `Y-direction ClearType', meaning grayscale rasterization along the + * 'Y-direction ClearType', meaning grayscale rasterization along the * Y-direction; the name used in the TrueType specification for this - * feature is `symmetric smoothing'. `Classic ClearType' is the - * original algorithm used before introducing a modified version in - * Win~XP. Another name for v1.6's grayscale rendering is `font - * smoothing', and `Color ClearType' is sometimes also called `DWrite - * ClearType'. To differentiate between today's Color ClearType and the - * earlier ClearType variant with B/W rendering along the vertical axis, - * the latter is sometimes called `GDI ClearType'. - * - * `Normal' and `high' sampling describe the (virtual) resolution to - * access the rasterized outline after the hinting process. `Normal' + * feature is 'symmetric smoothing'. 'Classic ClearType' is the original + * algorithm used before introducing a modified version in Win~XP. + * Another name for v1.6's grayscale rendering is 'font smoothing', and + * 'Color ClearType' is sometimes also called 'DWrite ClearType'. To + * differentiate between today's Color ClearType and the earlier + * ClearType variant with B/W rendering along the vertical axis, the + * latter is sometimes called 'GDI ClearType'. + * + * 'Normal' and 'high' sampling describe the (virtual) resolution to + * access the rasterized outline after the hinting process. 'Normal' * means 1 sample per grid line (i.e., B/W). In the current Microsoft - * implementation, `high' means an extra virtual resolution of 16x16 (or - * 16x1) grid lines per pixel for bytecode instructions like `MIRP'. + * implementation, 'high' means an extra virtual resolution of 16x16 (or + * 16x1) grid lines per pixel for bytecode instructions like 'MIRP'. * After hinting, these 16 grid lines are mapped to 6x5 (or 6x1) grid * lines for color filtering if Color ClearType is activated. * - * Note that `Gray ClearType' is essentially the same as v1.6's - * grayscale rendering. However, the GETINFO instruction handles it - * differently: v1.6 returns bit~12 (hinting for grayscale), while v2.1 - * returns bits~13 (hinting for ClearType), 18 (symmetrical smoothing), - * and~19 (Gray ClearType). Also, this mode respects bits 2 and~3 for - * the version~1 gasp table exclusively (like Color ClearType), while - * v1.6 only respects the values of version~0 (bits 0 and~1). + * Note that 'Gray ClearType' is essentially the same as v1.6's grayscale + * rendering. However, the GETINFO instruction handles it differently: + * v1.6 returns bit~12 (hinting for grayscale), while v2.1 returns + * bits~13 (hinting for ClearType), 18 (symmetrical smoothing), and~19 + * (Gray ClearType). Also, this mode respects bits 2 and~3 for the + * version~1 gasp table exclusively (like Color ClearType), while v1.6 + * only respects the values of version~0 (bits 0 and~1). * - * Keep in mind that the features of the above interpreter versions - * might not map exactly to FreeType features or behavior because it is - * a fundamentally different library with different internals. + * Keep in mind that the features of the above interpreter versions might + * not map exactly to FreeType features or behavior because it is a + * fundamentally different library with different internals. * */ #define TT_INTERPRETER_VERSION_35 35 @@ -755,33 +756,40 @@ FT_BEGIN_HEADER * interpreter-version * * @description: - * Currently, three versions are available, two representing the - * bytecode interpreter with subpixel hinting support (old `Infinality' - * code and new stripped-down and higher performance `minimal' code) and - * one without, respectively. The default is subpixel support if - * TT_CONFIG_OPTION_SUBPIXEL_HINTING is defined, and no subpixel support - * otherwise (since it isn't available then). + * Currently, three versions are available, two representing the bytecode + * interpreter with subpixel hinting support (old 'Infinality' code and + * new stripped-down and higher performance 'minimal' code) and one + * without, respectively. The default is subpixel support if + * `TT_CONFIG_OPTION_SUBPIXEL_HINTING` is defined, and no subpixel + * support otherwise (since it isn't available then). * * If subpixel hinting is on, many TrueType bytecode instructions behave - * differently compared to B/W or grayscale rendering (except if `native + * differently compared to B/W or grayscale rendering (except if 'native * ClearType' is selected by the font). Microsoft's main idea is to * render at a much increased horizontal resolution, then sampling down * the created output to subpixel precision. However, many older fonts - * are not suited to this and must be specially taken care of by - * applying (hardcoded) tweaks in Microsoft's interpreter. + * are not suited to this and must be specially taken care of by applying + * (hardcoded) tweaks in Microsoft's interpreter. * * Details on subpixel hinting and some of the necessary tweaks can be * found in Greg Hitchcock's whitepaper at - * `https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx'. - * Note that FreeType currently doesn't really `subpixel hint' (6x1, 6x2, + * 'https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx'. + * Note that FreeType currently doesn't really 'subpixel hint' (6x1, 6x2, * or 6x5 supersampling) like discussed in the paper. Depending on the * chosen interpreter, it simply ignores instructions on vertical stems * to arrive at very similar results. * + * @note: + * This property can be used with @FT_Property_Get also. + * + * This property can be set via the `FREETYPE_PROPERTIES` environment + * variable (using values '35', '38', or '40'). + * + * @example: * The following example code demonstrates how to deactivate subpixel * hinting (omitting the error handling). * - * { + * ``` * FT_Library library; * FT_Face face; * FT_UInt interpreter_version = TT_INTERPRETER_VERSION_35; @@ -792,13 +800,7 @@ FT_BEGIN_HEADER * FT_Property_Set( library, "truetype", * "interpreter-version", * &interpreter_version ); - * } - * - * @note: - * This property can be used with @FT_Property_Get also. - * - * This property can be set via the `FREETYPE_PROPERTIES' environment - * variable (using values `35', `38', or `40'). + * ``` * * @since: * 2.5 @@ -811,7 +813,7 @@ FT_BEGIN_HEADER * glyph-to-script-map * * @description: - * *Experimental* *only* + * **Experimental only** * * The auto-hinter provides various script modules to hint glyphs. * Examples of supported scripts are Latin or CJK. Before a glyph is @@ -819,25 +821,26 @@ FT_BEGIN_HEADER * the script is then determined based on Unicode character ranges, see * below. * - * OpenType fonts, however, often provide much more glyphs than - * character codes (small caps, superscripts, ligatures, swashes, etc.), - * to be controlled by so-called `features'. Handling OpenType features - * can be quite complicated and thus needs a separate library on top of + * OpenType fonts, however, often provide much more glyphs than character + * codes (small caps, superscripts, ligatures, swashes, etc.), to be + * controlled by so-called 'features'. Handling OpenType features can be + * quite complicated and thus needs a separate library on top of * FreeType. * * The mapping between glyph indices and scripts (in the auto-hinter - * sense, see the @FT_AUTOHINTER_SCRIPT_XXX values) is stored as an - * array with `num_glyphs' elements, as found in the font's @FT_Face - * structure. The `glyph-to-script-map' property returns a pointer to - * this array, which can be modified as needed. Note that the - * modification should happen before the first glyph gets processed by - * the auto-hinter so that the global analysis of the font shapes - * actually uses the modified mapping. - * - * The following example code demonstrates how to access it (omitting - * the error handling). - * - * { + * sense, see the @FT_AUTOHINTER_SCRIPT_XXX values) is stored as an array + * with `num_glyphs` elements, as found in the font's @FT_Face structure. + * The `glyph-to-script-map` property returns a pointer to this array, + * which can be modified as needed. Note that the modification should + * happen before the first glyph gets processed by the auto-hinter so + * that the global analysis of the font shapes actually uses the modified + * mapping. + * + * @example: + * The following example code demonstrates how to access it (omitting the + * error handling). + * + * ``` * FT_Library library; * FT_Face face; * FT_Prop_GlyphToScriptMap prop; @@ -854,7 +857,7 @@ FT_BEGIN_HEADER * // adjust `prop.map' as needed right here * * FT_Load_Glyph( face, ..., FT_LOAD_FORCE_AUTOHINT ); - * } + * ``` * * @since: * 2.4.11 @@ -868,7 +871,7 @@ FT_BEGIN_HEADER * FT_AUTOHINTER_SCRIPT_XXX * * @description: - * *Experimental* *only* + * **Experimental only** * * A list of constants used for the @glyph-to-script-map property to * specify the script submodule the auto-hinter should use for hinting a @@ -879,14 +882,14 @@ FT_BEGIN_HEADER * Don't auto-hint this glyph. * * FT_AUTOHINTER_SCRIPT_LATIN :: - * Apply the latin auto-hinter. For the auto-hinter, `latin' is a - * very broad term, including Cyrillic and Greek also since characters - * from those scripts share the same design constraints. + * Apply the latin auto-hinter. For the auto-hinter, 'latin' is a very + * broad term, including Cyrillic and Greek also since characters from + * those scripts share the same design constraints. * * By default, characters from the following Unicode ranges are * assigned to this submodule. * - * { + * ``` * U+0020 - U+007F // Basic Latin (no control characters) * U+00A0 - U+00FF // Latin-1 Supplement (no control characters) * U+0100 - U+017F // Latin Extended-A @@ -915,7 +918,7 @@ FT_BEGIN_HEADER * U+FB00 - U+FB06 // Alphab. Present. Forms (Latin Ligatures) * U+1D400 - U+1D7FF // Mathematical Alphanumeric Symbols * U+1F100 - U+1F1FF // Enclosed Alphanumeric Supplement - * } + * ``` * * FT_AUTOHINTER_SCRIPT_CJK :: * Apply the CJK auto-hinter, covering Chinese, Japanese, Korean, old @@ -924,7 +927,7 @@ FT_BEGIN_HEADER * By default, characters from the following Unicode ranges are * assigned to this submodule. * - * { + * ``` * U+1100 - U+11FF // Hangul Jamo * U+2E80 - U+2EFF // CJK Radicals Supplement * U+2F00 - U+2FDF // Kangxi Radicals @@ -957,7 +960,7 @@ FT_BEGIN_HEADER * U+2A700 - U+2B73F // CJK Unified Ideographs Extension C * U+2B740 - U+2B81F // CJK Unified Ideographs Extension D * U+2F800 - U+2FA1F // CJK Compatibility Ideographs Supplement - * } + * ``` * * FT_AUTOHINTER_SCRIPT_INDIC :: * Apply the indic auto-hinter, covering all major scripts from the @@ -967,7 +970,7 @@ FT_BEGIN_HEADER * By default, characters from the following Unicode ranges are * assigned to this submodule. * - * { + * ``` * U+0900 - U+0DFF // Indic Range * U+0F00 - U+0FFF // Tibetan * U+1900 - U+194F // Limbu @@ -975,7 +978,7 @@ FT_BEGIN_HEADER * U+A800 - U+A82F // Syloti Nagri * U+ABC0 - U+ABFF // Meetei Mayek * U+11800 - U+118DF // Sharada - * } + * ``` * * Note that currently Indic support is rudimentary only, missing blue * zone support. @@ -996,7 +999,7 @@ FT_BEGIN_HEADER * FT_Prop_GlyphToScriptMap * * @description: - * *Experimental* *only* + * **Experimental only** * * The data exchange structure for the @glyph-to-script-map property. * @@ -1018,36 +1021,36 @@ FT_BEGIN_HEADER * fallback-script * * @description: - * *Experimental* *only* - * - * If no auto-hinter script module can be assigned to a glyph, a - * fallback script gets assigned to it (see also the - * @glyph-to-script-map property). By default, this is - * @FT_AUTOHINTER_SCRIPT_CJK. Using the `fallback-script' property, - * this fallback value can be changed. - * - * { - * FT_Library library; - * FT_UInt fallback_script = FT_AUTOHINTER_SCRIPT_NONE; - * - * - * FT_Init_FreeType( &library ); + * **Experimental only** * - * FT_Property_Set( library, "autofitter", - * "fallback-script", &fallback_script ); - * } + * If no auto-hinter script module can be assigned to a glyph, a fallback + * script gets assigned to it (see also the @glyph-to-script-map + * property). By default, this is @FT_AUTOHINTER_SCRIPT_CJK. Using the + * `fallback-script` property, this fallback value can be changed. * * @note: * This property can be used with @FT_Property_Get also. * * It's important to use the right timing for changing this value: The - * creation of the glyph-to-script map that eventually uses the - * fallback script value gets triggered either by setting or reading a + * creation of the glyph-to-script map that eventually uses the fallback + * script value gets triggered either by setting or reading a * face-specific property like @glyph-to-script-map, or by auto-hinting * any glyph from that face. In particular, if you have already created * an @FT_Face structure but not loaded any glyph (using the * auto-hinter), a change of the fallback script will affect this face. * + * @example: + * ``` + * FT_Library library; + * FT_UInt fallback_script = FT_AUTOHINTER_SCRIPT_NONE; + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "autofitter", + * "fallback-script", &fallback_script ); + * ``` + * * @since: * 2.4.11 * @@ -1060,42 +1063,43 @@ FT_BEGIN_HEADER * default-script * * @description: - * *Experimental* *only* + * **Experimental only** * - * If FreeType gets compiled with FT_CONFIG_OPTION_USE_HARFBUZZ to make - * the HarfBuzz library access OpenType features for getting better - * glyph coverages, this property sets the (auto-fitter) script to be - * used for the default (OpenType) script data of a font's GSUB table. - * Features for the default script are intended for all scripts not - * explicitly handled in GSUB; an example is a `dlig' feature, - * containing the combination of the characters `T', `E', and `L' to - * form a `TEL' ligature. + * If FreeType gets compiled with `FT_CONFIG_OPTION_USE_HARFBUZZ` to make + * the HarfBuzz library access OpenType features for getting better glyph + * coverages, this property sets the (auto-fitter) script to be used for + * the default (OpenType) script data of a font's GSUB table. Features + * for the default script are intended for all scripts not explicitly + * handled in GSUB; an example is a 'dlig' feature, containing the + * combination of the characters 'T', 'E', and 'L' to form a 'TEL' + * ligature. * * By default, this is @FT_AUTOHINTER_SCRIPT_LATIN. Using the - * `default-script' property, this default value can be changed. - * - * { - * FT_Library library; - * FT_UInt default_script = FT_AUTOHINTER_SCRIPT_NONE; - * - * - * FT_Init_FreeType( &library ); - * - * FT_Property_Set( library, "autofitter", - * "default-script", &default_script ); - * } + * `default-script` property, this default value can be changed. * * @note: * This property can be used with @FT_Property_Get also. * * It's important to use the right timing for changing this value: The - * creation of the glyph-to-script map that eventually uses the - * default script value gets triggered either by setting or reading a + * creation of the glyph-to-script map that eventually uses the default + * script value gets triggered either by setting or reading a * face-specific property like @glyph-to-script-map, or by auto-hinting * any glyph from that face. In particular, if you have already created * an @FT_Face structure but not loaded any glyph (using the * auto-hinter), a change of the default script will affect this face. * + * @example: + * ``` + * FT_Library library; + * FT_UInt default_script = FT_AUTOHINTER_SCRIPT_NONE; + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "autofitter", + * "default-script", &default_script ); + * ``` + * * @since: * 2.5.3 * @@ -1108,13 +1112,20 @@ FT_BEGIN_HEADER * increase-x-height * * @description: - * For ppem values in the range 6~<= ppem <= `increase-x-height', round - * up the font's x~height much more often than normally. If the value - * is set to~0, which is the default, this feature is switched off. Use + * For ppem values in the range 6~<= ppem <= `increase-x-height`, round + * up the font's x~height much more often than normally. If the value is + * set to~0, which is the default, this feature is switched off. Use * this property to improve the legibility of small font sizes if * necessary. * - * { + * @note: + * This property can be used with @FT_Property_Get also. + * + * Set this value right after calling @FT_Set_Char_Size, but before + * loading any glyph (using the auto-hinter). + * + * @example: + * ``` * FT_Library library; * FT_Face face; * FT_Prop_IncreaseXHeight prop; @@ -1129,13 +1140,7 @@ FT_BEGIN_HEADER * * FT_Property_Set( library, "autofitter", * "increase-x-height", &prop ); - * } - * - * @note: - * This property can be used with @FT_Property_Get also. - * - * Set this value right after calling @FT_Set_Char_Size, but before - * loading any glyph (using the auto-hinter). + * ``` * * @since: * 2.4.11 @@ -1166,46 +1171,48 @@ FT_BEGIN_HEADER * warping * * @description: - * *Experimental* *only* + * **Experimental only** * - * If FreeType gets compiled with option AF_CONFIG_OPTION_USE_WARPER to + * If FreeType gets compiled with option `AF_CONFIG_OPTION_USE_WARPER` to * activate the warp hinting code in the auto-hinter, this property * switches warping on and off. * - * Warping only works in `normal' auto-hinting mode replacing it. - * The idea of the code is to slightly scale and shift a glyph along - * the non-hinted dimension (which is usually the horizontal axis) so - * that as much of its segments are aligned (more or less) to the grid. - * To find out a glyph's optimal scaling and shifting value, various - * parameter combinations are tried and scored. + * Warping only works in 'normal' auto-hinting mode replacing it. The + * idea of the code is to slightly scale and shift a glyph along the + * non-hinted dimension (which is usually the horizontal axis) so that as + * much of its segments are aligned (more or less) to the grid. To find + * out a glyph's optimal scaling and shifting value, various parameter + * combinations are tried and scored. * - * By default, warping is off. The example below shows how to switch on - * warping (omitting the error handling). - * - * { - * FT_Library library; - * FT_Bool warping = 1; - * - * - * FT_Init_FreeType( &library ); - * - * FT_Property_Set( library, "autofitter", - * "warping", &warping ); - * } + * By default, warping is off. * * @note: * This property can be used with @FT_Property_Get also. * - * This property can be set via the `FREETYPE_PROPERTIES' environment - * variable (using values 1 and 0 for `on' and `off', respectively). + * This property can be set via the `FREETYPE_PROPERTIES` environment + * variable (using values 1 and 0 for 'on' and 'off', respectively). * * The warping code can also change advance widths. Have a look at the - * `lsb_delta' and `rsb_delta' fields in the @FT_GlyphSlotRec structure + * `lsb_delta` and `rsb_delta` fields in the @FT_GlyphSlotRec structure * for details on improving inter-glyph distances while rendering. * * Since warping is a global property of the auto-hinter it is best to * change its value before rendering any face. Otherwise, you should - * reload all faces that get auto-hinted in `normal' hinting mode. + * reload all faces that get auto-hinted in 'normal' hinting mode. + * + * @example: + * This example shows how to switch on warping (omitting the error + * handling). + * + * ``` + * FT_Library library; + * FT_Bool warping = 1; + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "autofitter", "warping", &warping ); + * ``` * * @since: * 2.6 diff --git a/sdk/lib/3rdparty/freetype/include/freetype/fterrdef.h b/sdk/lib/3rdparty/freetype/include/freetype/fterrdef.h index 8ffd346ca8f39..9bc7dc65e32c9 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/fterrdef.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/fterrdef.h @@ -1,58 +1,57 @@ -/***************************************************************************/ -/* */ -/* fterrdef.h */ -/* */ -/* FreeType error codes (specification). */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * fterrdef.h + * + * FreeType error codes (specification). + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ - /*************************************************************************/ - /* */ - /* <Section> */ - /* error_code_values */ - /* */ - /* <Title> */ - /* Error Code Values */ - /* */ - /* <Abstract> */ - /* All possible error codes returned by FreeType functions. */ - /* */ - /* <Description> */ - /* The list below is taken verbatim from the file `fterrdef.h' */ - /* (loaded automatically by including `FT_FREETYPE_H'). The first */ - /* argument of the `FT_ERROR_DEF_' macro is the error label; by */ - /* default, the prefix `FT_Err_' gets added so that you get error */ - /* names like `FT_Err_Cannot_Open_Resource'. The second argument is */ - /* the error code, and the last argument an error string, which is not */ - /* used by FreeType. */ - /* */ - /* Within your application you should *only* use error names and */ - /* *never* its numeric values! The latter might (and actually do) */ - /* change in forthcoming FreeType versions. */ - /* */ - /* Macro `FT_NOERRORDEF_' defines `FT_Err_Ok', which is always zero. */ - /* See the `Error Enumerations' subsection how to automatically */ - /* generate a list of error strings. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * @section: + * error_code_values + * + * @title: + * Error Code Values + * + * @abstract: + * All possible error codes returned by FreeType functions. + * + * @description: + * The list below is taken verbatim from the file `fterrdef.h` (loaded + * automatically by including `FT_FREETYPE_H`). The first argument of the + * `FT_ERROR_DEF_` macro is the error label; by default, the prefix + * `FT_Err_` gets added so that you get error names like + * `FT_Err_Cannot_Open_Resource`. The second argument is the error code, + * and the last argument an error string, which is not used by FreeType. + * + * Within your application you should **only** use error names and + * **never** its numeric values! The latter might (and actually do) + * change in forthcoming FreeType versions. + * + * Macro `FT_NOERRORDEF_` defines `FT_Err_Ok`, which is always zero. See + * the 'Error Enumerations' subsection how to automatically generate a + * list of error strings. + * + */ - /*************************************************************************/ - /* */ - /* <Enum> */ - /* FT_Err_XXX */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * @enum: + * FT_Err_XXX + * + */ /* generic errors */ diff --git a/sdk/lib/3rdparty/freetype/include/freetype/fterrors.h b/sdk/lib/3rdparty/freetype/include/freetype/fterrors.h index f6ee5c24e2812..58f5a3ead12e4 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/fterrors.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/fterrors.h @@ -1,110 +1,120 @@ -/***************************************************************************/ -/* */ -/* fterrors.h */ -/* */ -/* FreeType error code handling (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* error_enumerations */ - /* */ - /* <Title> */ - /* Error Enumerations */ - /* */ - /* <Abstract> */ - /* How to handle errors and error strings. */ - /* */ - /* <Description> */ - /* The header file `fterrors.h' (which is automatically included by */ - /* `freetype.h' defines the handling of FreeType's enumeration */ - /* constants. It can also be used to generate error message strings */ - /* with a small macro trick explained below. */ - /* */ - /* *Error* *Formats* */ - /* */ - /* The configuration macro FT_CONFIG_OPTION_USE_MODULE_ERRORS can be */ - /* defined in `ftoption.h' in order to make the higher byte indicate */ - /* the module where the error has happened (this is not compatible */ - /* with standard builds of FreeType~2, however). See the file */ - /* `ftmoderr.h' for more details. */ - /* */ - /* *Error* *Message* *Strings* */ - /* */ - /* Error definitions are set up with special macros that allow client */ - /* applications to build a table of error message strings. The */ - /* strings are not included in a normal build of FreeType~2 to save */ - /* space (most client applications do not use them). */ - /* */ - /* To do so, you have to define the following macros before including */ - /* this file. */ - /* */ - /* { */ - /* FT_ERROR_START_LIST */ - /* } */ - /* */ - /* This macro is called before anything else to define the start of */ - /* the error list. It is followed by several FT_ERROR_DEF calls. */ - /* */ - /* { */ - /* FT_ERROR_DEF( e, v, s ) */ - /* } */ - /* */ - /* This macro is called to define one single error. `e' is the error */ - /* code identifier (e.g., `Invalid_Argument'), `v' is the error's */ - /* numerical value, and `s' is the corresponding error string. */ - /* */ - /* { */ - /* FT_ERROR_END_LIST */ - /* } */ - /* */ - /* This macro ends the list. */ - /* */ - /* Additionally, you have to undefine `FTERRORS_H_' before #including */ - /* this file. */ - /* */ - /* Here is a simple example. */ - /* */ - /* { */ - /* #undef FTERRORS_H_ */ - /* #define FT_ERRORDEF( e, v, s ) { e, s }, */ - /* #define FT_ERROR_START_LIST { */ - /* #define FT_ERROR_END_LIST { 0, NULL } }; */ - /* */ - /* const struct */ - /* { */ - /* int err_code; */ - /* const char* err_msg; */ - /* } ft_errors[] = */ - /* */ - /* #include FT_ERRORS_H */ - /* } */ - /* */ - /* Note that `FT_Err_Ok' is _not_ defined with `FT_ERRORDEF' but with */ - /* `FT_NOERRORDEF'; it is always zero. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * fterrors.h + * + * FreeType error code handling (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /************************************************************************** + * + * @section: + * error_enumerations + * + * @title: + * Error Enumerations + * + * @abstract: + * How to handle errors and error strings. + * + * @description: + * The header file `fterrors.h` (which is automatically included by + * `freetype.h` defines the handling of FreeType's enumeration + * constants. It can also be used to generate error message strings + * with a small macro trick explained below. + * + * **Error Formats** + * + * The configuration macro `FT_CONFIG_OPTION_USE_MODULE_ERRORS` can be + * defined in `ftoption.h` in order to make the higher byte indicate the + * module where the error has happened (this is not compatible with + * standard builds of FreeType~2, however). See the file `ftmoderr.h` + * for more details. + * + * **Error Message Strings** + * + * Error definitions are set up with special macros that allow client + * applications to build a table of error message strings. The strings + * are not included in a normal build of FreeType~2 to save space (most + * client applications do not use them). + * + * To do so, you have to define the following macros before including + * this file. + * + * ``` + * FT_ERROR_START_LIST + * ``` + * + * This macro is called before anything else to define the start of the + * error list. It is followed by several `FT_ERROR_DEF` calls. + * + * ``` + * FT_ERROR_DEF( e, v, s ) + * ``` + * + * This macro is called to define one single error. 'e' is the error + * code identifier (e.g., `Invalid_Argument`), 'v' is the error's + * numerical value, and 's' is the corresponding error string. + * + * ``` + * FT_ERROR_END_LIST + * ``` + * + * This macro ends the list. + * + * Additionally, you have to undefine `FTERRORS_H_` before #including + * this file. + * + * Here is a simple example. + * + * ``` + * #undef FTERRORS_H_ + * #define FT_ERRORDEF( e, v, s ) { e, s }, + * #define FT_ERROR_START_LIST { + * #define FT_ERROR_END_LIST { 0, NULL } }; + * + * const struct + * { + * int err_code; + * const char* err_msg; + * } ft_errors[] = + * + * #include FT_ERRORS_H + * ``` + * + * An alternative to using an array is a switch statement. + * + * ``` + * #undef FTERRORS_H_ + * #define FT_ERROR_START_LIST switch ( error_code ) { + * #define FT_ERRORDEF( e, v, s ) case v: return s; + * #define FT_ERROR_END_LIST } + * ``` + * + * If you use `FT_CONFIG_OPTION_USE_MODULE_ERRORS`, `error_code` should + * be replaced with `FT_ERROR_BASE(error_code)` in the last example. + */ /* */ - /* In previous FreeType versions we used `__FTERRORS_H__'. However, */ + /* In previous FreeType versions we used `__FTERRORS_H__`. However, */ /* using two successive underscores in a non-system symbol name */ /* violates the C (and C++) standard, so it was changed to the */ /* current form. In spite of this, we have to make */ /* */ + /* ``` */ /* #undefine __FTERRORS_H__ */ + /* ``` */ /* */ /* work for backward compatibility. */ /* */ @@ -130,7 +140,7 @@ /* FT_ERR_PREFIX is used as a prefix for error identifiers. */ - /* By default, we use `FT_Err_'. */ + /* By default, we use `FT_Err_`. */ /* */ #ifndef FT_ERR_PREFIX #define FT_ERR_PREFIX FT_Err_ @@ -158,6 +168,8 @@ /* */ #ifndef FT_ERRORDEF +#define FT_INCLUDE_ERR_PROTOS + #define FT_ERRORDEF( e, v, s ) e = v, #define FT_ERROR_START_LIST enum { #define FT_ERROR_END_LIST FT_ERR_CAT( FT_ERR_PREFIX, Max ) }; @@ -220,6 +232,53 @@ #undef FT_ERR_PREFIX #endif + /* FT_INCLUDE_ERR_PROTOS: Control if function prototypes should be */ + /* included with `#include FT_ERRORS_H'. This is */ + /* only true where `FT_ERRORDEF` is undefined. */ + /* FT_ERR_PROTOS_DEFINED: Actual multiple-inclusion protection of */ + /* `fterrors.h`. */ +#ifdef FT_INCLUDE_ERR_PROTOS +#undef FT_INCLUDE_ERR_PROTOS + +#ifndef FT_ERR_PROTOS_DEFINED +#define FT_ERR_PROTOS_DEFINED + + + /************************************************************************** + * + * @function: + * FT_Error_String + * + * @description: + * Retrieve the description of a valid FreeType error code. + * + * @input: + * error_code :: + * A valid FreeType error code. + * + * @return: + * A C~string or `NULL`, if any error occurred. + * + * @note: + * FreeType has to be compiled with `FT_CONFIG_OPTION_ERROR_STRINGS` or + * `FT_DEBUG_LEVEL_ERROR` to get meaningful descriptions. + * 'error_string' will be `NULL` otherwise. + * + * Module identification will be ignored: + * + * ```c + * strcmp( FT_Error_String( FT_Err_Unknown_File_Format ), + * FT_Error_String( BDF_Err_Unknown_File_Format ) ) == 0; + * ``` + */ + FT_EXPORT( const char* ) + FT_Error_String( FT_Error error_code ); + + +#endif /* FT_ERR_PROTOS_DEFINED */ + +#endif /* FT_INCLUDE_ERR_PROTOS */ + #endif /* !(FTERRORS_H_ && __FTERRORS_H__) */ diff --git a/sdk/lib/3rdparty/freetype/include/freetype/ftfntfmt.h b/sdk/lib/3rdparty/freetype/include/freetype/ftfntfmt.h index cc86efac23b92..aae0b1326492f 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/ftfntfmt.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/ftfntfmt.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftfntfmt.h */ -/* */ -/* Support functions for font formats. */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftfntfmt.h + * + * Support functions for font formats. + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTFNTFMT_H_ @@ -32,49 +32,48 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* <Section> */ - /* font_formats */ - /* */ - /* <Title> */ - /* Font Formats */ - /* */ - /* <Abstract> */ - /* Getting the font format. */ - /* */ - /* <Description> */ - /* The single function in this section can be used to get the font */ - /* format. Note that this information is not needed normally; */ - /* however, there are special cases (like in PDF devices) where it is */ - /* important to differentiate, in spite of FreeType's uniform API. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_Font_Format */ - /* */ - /* <Description> */ - /* Return a string describing the format of a given face. Possible */ - /* values are `TrueType', `Type~1', `BDF', `PCF', `Type~42', */ - /* `CID~Type~1', `CFF', `PFR', and `Windows~FNT'. */ - /* */ - /* The return value is suitable to be used as an X11 FONT_PROPERTY. */ - /* */ - /* <Input> */ - /* face :: */ - /* Input face handle. */ - /* */ - /* <Return> */ - /* Font format string. NULL in case of error. */ - /* */ - /* <Note> */ - /* A deprecated name for the same function is */ - /* `FT_Get_X11_Font_Format'. */ - /* */ + /************************************************************************** + * + * @section: + * font_formats + * + * @title: + * Font Formats + * + * @abstract: + * Getting the font format. + * + * @description: + * The single function in this section can be used to get the font format. + * Note that this information is not needed normally; however, there are + * special cases (like in PDF devices) where it is important to + * differentiate, in spite of FreeType's uniform API. + * + */ + + + /************************************************************************** + * + * @function: + * FT_Get_Font_Format + * + * @description: + * Return a string describing the format of a given face. Possible values + * are 'TrueType', 'Type~1', 'BDF', 'PCF', 'Type~42', 'CID~Type~1', 'CFF', + * 'PFR', and 'Windows~FNT'. + * + * The return value is suitable to be used as an X11 FONT_PROPERTY. + * + * @input: + * face :: + * Input face handle. + * + * @return: + * Font format string. `NULL` in case of error. + * + * @note: + * A deprecated name for the same function is `FT_Get_X11_Font_Format`. + */ FT_EXPORT( const char* ) FT_Get_Font_Format( FT_Face face ); diff --git a/sdk/lib/3rdparty/freetype/include/freetype/ftgasp.h b/sdk/lib/3rdparty/freetype/include/freetype/ftgasp.h index 9b54fc86a085c..24673d8ce1697 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/ftgasp.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/ftgasp.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftgasp.h */ -/* */ -/* Access of TrueType's `gasp' table (specification). */ -/* */ -/* Copyright 2007-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftgasp.h + * + * Access of TrueType's 'gasp' table (specification). + * + * Copyright (C) 2007-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTGASP_H_ @@ -29,7 +29,10 @@ #endif - /*************************************************************************** +FT_BEGIN_HEADER + + + /************************************************************************** * * @section: * gasp_table @@ -38,16 +41,16 @@ * Gasp Table * * @abstract: - * Retrieving TrueType `gasp' table entries. + * Retrieving TrueType 'gasp' table entries. * * @description: * The function @FT_Get_Gasp can be used to query a TrueType or OpenType - * font for specific entries in its `gasp' table, if any. This is - * mainly useful when implementing native TrueType hinting with the - * bytecode interpreter to duplicate the Windows text rendering results. + * font for specific entries in its 'gasp' table, if any. This is mainly + * useful when implementing native TrueType hinting with the bytecode + * interpreter to duplicate the Windows text rendering results. */ - /************************************************************************* + /************************************************************************** * * @enum: * FT_GASP_XXX @@ -63,7 +66,7 @@ * * FT_GASP_DO_GRIDFIT :: * Grid-fitting and hinting should be performed at the specified ppem. - * This *really* means TrueType bytecode interpretation. If this bit + * This **really** means TrueType bytecode interpretation. If this bit * is not set, no hinting gets applied. * * FT_GASP_DO_GRAY :: @@ -77,13 +80,13 @@ * Grid-fitting must be used with ClearType's symmetric smoothing. * * @note: - * The bit-flags `FT_GASP_DO_GRIDFIT' and `FT_GASP_DO_GRAY' are to be + * The bit-flags `FT_GASP_DO_GRIDFIT` and `FT_GASP_DO_GRAY` are to be * used for standard font rasterization only. Independently of that, - * `FT_GASP_SYMMETRIC_SMOOTHING' and `FT_GASP_SYMMETRIC_GRIDFIT' are to - * be used if ClearType is enabled (and `FT_GASP_DO_GRIDFIT' and - * `FT_GASP_DO_GRAY' are consequently ignored). + * `FT_GASP_SYMMETRIC_SMOOTHING` and `FT_GASP_SYMMETRIC_GRIDFIT` are to + * be used if ClearType is enabled (and `FT_GASP_DO_GRIDFIT` and + * `FT_GASP_DO_GRAY` are consequently ignored). * - * `ClearType' is Microsoft's implementation of LCD rendering, partly + * 'ClearType' is Microsoft's implementation of LCD rendering, partly * protected by patents. * * @since: @@ -96,29 +99,31 @@ #define FT_GASP_SYMMETRIC_SMOOTHING 0x08 - /************************************************************************* + /************************************************************************** * - * @func: + * @function: * FT_Get_Gasp * * @description: * For a TrueType or OpenType font file, return the rasterizer behaviour - * flags from the font's `gasp' table corresponding to a given - * character pixel size. + * flags from the font's 'gasp' table corresponding to a given character + * pixel size. * * @input: - * face :: The source face handle. + * face :: + * The source face handle. * - * ppem :: The vertical character pixel size. + * ppem :: + * The vertical character pixel size. * * @return: * Bit flags (see @FT_GASP_XXX), or @FT_GASP_NO_TABLE if there is no - * `gasp' table in the face. + * 'gasp' table in the face. * * @note: * If you want to use the MM functionality of OpenType variation fonts * (i.e., using @FT_Set_Var_Design_Coordinates and friends), call this - * function *after* setting an instance since the return values can + * function **after** setting an instance since the return values can * change. * * @since: @@ -131,6 +136,8 @@ /* */ +FT_END_HEADER + #endif /* FTGASP_H_ */ diff --git a/sdk/lib/3rdparty/freetype/include/freetype/ftglyph.h b/sdk/lib/3rdparty/freetype/include/freetype/ftglyph.h index 5f3fc009cd439..4067c2e62fa21 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/ftglyph.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/ftglyph.h @@ -1,32 +1,32 @@ -/***************************************************************************/ -/* */ -/* ftglyph.h */ -/* */ -/* FreeType convenience functions to handle glyphs (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file contains the definition of several convenience functions */ - /* that can be used by client applications to easily retrieve glyph */ - /* bitmaps and outlines from a given face. */ - /* */ - /* These functions should be optional if you are writing a font server */ - /* or text layout engine on top of FreeType. However, they are pretty */ - /* handy for many other simple uses of the library. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * ftglyph.h + * + * FreeType convenience functions to handle glyphs (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /************************************************************************** + * + * This file contains the definition of several convenience functions that + * can be used by client applications to easily retrieve glyph bitmaps and + * outlines from a given face. + * + * These functions should be optional if you are writing a font server or + * text layout engine on top of FreeType. However, they are pretty handy + * for many other simple uses of the library. + * + */ #ifndef FTGLYPH_H_ @@ -46,65 +46,70 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* <Section> */ - /* glyph_management */ - /* */ - /* <Title> */ - /* Glyph Management */ - /* */ - /* <Abstract> */ - /* Generic interface to manage individual glyph data. */ - /* */ - /* <Description> */ - /* This section contains definitions used to manage glyph data */ - /* through generic FT_Glyph objects. Each of them can contain a */ - /* bitmap, a vector outline, or even images in other formats. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * @section: + * glyph_management + * + * @title: + * Glyph Management + * + * @abstract: + * Generic interface to manage individual glyph data. + * + * @description: + * This section contains definitions used to manage glyph data through + * generic @FT_Glyph objects. Each of them can contain a bitmap, + * a vector outline, or even images in other formats. These objects are + * detached from @FT_Face, contrary to @FT_GlyphSlot. + * + */ /* forward declaration to a private type */ typedef struct FT_Glyph_Class_ FT_Glyph_Class; - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Glyph */ - /* */ - /* <Description> */ - /* Handle to an object used to model generic glyph images. It is a */ - /* pointer to the @FT_GlyphRec structure and can contain a glyph */ - /* bitmap or pointer. */ - /* */ - /* <Note> */ - /* Glyph objects are not owned by the library. You must thus release */ - /* them manually (through @FT_Done_Glyph) _before_ calling */ - /* @FT_Done_FreeType. */ - /* */ + /************************************************************************** + * + * @type: + * FT_Glyph + * + * @description: + * Handle to an object used to model generic glyph images. It is a + * pointer to the @FT_GlyphRec structure and can contain a glyph bitmap + * or pointer. + * + * @note: + * Glyph objects are not owned by the library. You must thus release + * them manually (through @FT_Done_Glyph) _before_ calling + * @FT_Done_FreeType. + */ typedef struct FT_GlyphRec_* FT_Glyph; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_GlyphRec */ - /* */ - /* <Description> */ - /* The root glyph structure contains a given glyph image plus its */ - /* advance width in 16.16 fixed-point format. */ - /* */ - /* <Fields> */ - /* library :: A handle to the FreeType library object. */ - /* */ - /* clazz :: A pointer to the glyph's class. Private. */ - /* */ - /* format :: The format of the glyph's image. */ - /* */ - /* advance :: A 16.16 vector that gives the glyph's advance width. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_GlyphRec + * + * @description: + * The root glyph structure contains a given glyph image plus its advance + * width in 16.16 fixed-point format. + * + * @fields: + * library :: + * A handle to the FreeType library object. + * + * clazz :: + * A pointer to the glyph's class. Private. + * + * format :: + * The format of the glyph's image. + * + * advance :: + * A 16.16 vector that gives the glyph's advance width. + */ typedef struct FT_GlyphRec_ { FT_Library library; @@ -115,48 +120,51 @@ FT_BEGIN_HEADER } FT_GlyphRec; - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_BitmapGlyph */ - /* */ - /* <Description> */ - /* A handle to an object used to model a bitmap glyph image. This is */ - /* a sub-class of @FT_Glyph, and a pointer to @FT_BitmapGlyphRec. */ - /* */ + /************************************************************************** + * + * @type: + * FT_BitmapGlyph + * + * @description: + * A handle to an object used to model a bitmap glyph image. This is a + * sub-class of @FT_Glyph, and a pointer to @FT_BitmapGlyphRec. + */ typedef struct FT_BitmapGlyphRec_* FT_BitmapGlyph; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_BitmapGlyphRec */ - /* */ - /* <Description> */ - /* A structure used for bitmap glyph images. This really is a */ - /* `sub-class' of @FT_GlyphRec. */ - /* */ - /* <Fields> */ - /* root :: The root @FT_Glyph fields. */ - /* */ - /* left :: The left-side bearing, i.e., the horizontal distance */ - /* from the current pen position to the left border of the */ - /* glyph bitmap. */ - /* */ - /* top :: The top-side bearing, i.e., the vertical distance from */ - /* the current pen position to the top border of the glyph */ - /* bitmap. This distance is positive for upwards~y! */ - /* */ - /* bitmap :: A descriptor for the bitmap. */ - /* */ - /* <Note> */ - /* You can typecast an @FT_Glyph to @FT_BitmapGlyph if you have */ - /* `glyph->format == FT_GLYPH_FORMAT_BITMAP'. This lets you access */ - /* the bitmap's contents easily. */ - /* */ - /* The corresponding pixel buffer is always owned by @FT_BitmapGlyph */ - /* and is thus created and destroyed with it. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_BitmapGlyphRec + * + * @description: + * A structure used for bitmap glyph images. This really is a + * 'sub-class' of @FT_GlyphRec. + * + * @fields: + * root :: + * The root @FT_Glyph fields. + * + * left :: + * The left-side bearing, i.e., the horizontal distance from the + * current pen position to the left border of the glyph bitmap. + * + * top :: + * The top-side bearing, i.e., the vertical distance from the current + * pen position to the top border of the glyph bitmap. This distance + * is positive for upwards~y! + * + * bitmap :: + * A descriptor for the bitmap. + * + * @note: + * You can typecast an @FT_Glyph to @FT_BitmapGlyph if you have + * `glyph->format == FT_GLYPH_FORMAT_BITMAP`. This lets you access the + * bitmap's contents easily. + * + * The corresponding pixel buffer is always owned by @FT_BitmapGlyph and + * is thus created and destroyed with it. + */ typedef struct FT_BitmapGlyphRec_ { FT_GlyphRec root; @@ -167,44 +175,46 @@ FT_BEGIN_HEADER } FT_BitmapGlyphRec; - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_OutlineGlyph */ - /* */ - /* <Description> */ - /* A handle to an object used to model an outline glyph image. This */ - /* is a sub-class of @FT_Glyph, and a pointer to @FT_OutlineGlyphRec. */ - /* */ + /************************************************************************** + * + * @type: + * FT_OutlineGlyph + * + * @description: + * A handle to an object used to model an outline glyph image. This is a + * sub-class of @FT_Glyph, and a pointer to @FT_OutlineGlyphRec. + */ typedef struct FT_OutlineGlyphRec_* FT_OutlineGlyph; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_OutlineGlyphRec */ - /* */ - /* <Description> */ - /* A structure used for outline (vectorial) glyph images. This */ - /* really is a `sub-class' of @FT_GlyphRec. */ - /* */ - /* <Fields> */ - /* root :: The root @FT_Glyph fields. */ - /* */ - /* outline :: A descriptor for the outline. */ - /* */ - /* <Note> */ - /* You can typecast an @FT_Glyph to @FT_OutlineGlyph if you have */ - /* `glyph->format == FT_GLYPH_FORMAT_OUTLINE'. This lets you access */ - /* the outline's content easily. */ - /* */ - /* As the outline is extracted from a glyph slot, its coordinates are */ - /* expressed normally in 26.6 pixels, unless the flag */ - /* @FT_LOAD_NO_SCALE was used in @FT_Load_Glyph() or @FT_Load_Char(). */ - /* */ - /* The outline's tables are always owned by the object and are */ - /* destroyed with it. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_OutlineGlyphRec + * + * @description: + * A structure used for outline (vectorial) glyph images. This really is + * a 'sub-class' of @FT_GlyphRec. + * + * @fields: + * root :: + * The root @FT_Glyph fields. + * + * outline :: + * A descriptor for the outline. + * + * @note: + * You can typecast an @FT_Glyph to @FT_OutlineGlyph if you have + * `glyph->format == FT_GLYPH_FORMAT_OUTLINE`. This lets you access the + * outline's content easily. + * + * As the outline is extracted from a glyph slot, its coordinates are + * expressed normally in 26.6 pixels, unless the flag @FT_LOAD_NO_SCALE + * was used in @FT_Load_Glyph() or @FT_Load_Char(). + * + * The outline's tables are always owned by the object and are destroyed + * with it. + */ typedef struct FT_OutlineGlyphRec_ { FT_GlyphRec root; @@ -213,113 +223,150 @@ FT_BEGIN_HEADER } FT_OutlineGlyphRec; - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_Glyph */ - /* */ - /* <Description> */ - /* A function used to extract a glyph image from a slot. Note that */ - /* the created @FT_Glyph object must be released with @FT_Done_Glyph. */ - /* */ - /* <Input> */ - /* slot :: A handle to the source glyph slot. */ - /* */ - /* <Output> */ - /* aglyph :: A handle to the glyph object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* Because `*aglyph->advance.x' and '*aglyph->advance.y' are 16.16 */ - /* fixed-point numbers, `slot->advance.x' and `slot->advance.y' */ - /* (which are in 26.6 fixed-point format) must be in the range */ - /* ]-32768;32768[. */ - /* */ + /************************************************************************** + * + * @function: + * FT_New_Glyph + * + * @description: + * A function used to create a new empty glyph image. Note that the + * created @FT_Glyph object must be released with @FT_Done_Glyph. + * + * @input: + * library :: + * A handle to the FreeType library object. + * + * format :: + * The format of the glyph's image. + * + * @output: + * aglyph :: + * A handle to the glyph object. + * + * @return: + * FreeType error code. 0~means success. + * + * @since: + * 2.10 + */ + FT_EXPORT( FT_Error ) + FT_New_Glyph( FT_Library library, + FT_Glyph_Format format, + FT_Glyph *aglyph ); + + + /************************************************************************** + * + * @function: + * FT_Get_Glyph + * + * @description: + * A function used to extract a glyph image from a slot. Note that the + * created @FT_Glyph object must be released with @FT_Done_Glyph. + * + * @input: + * slot :: + * A handle to the source glyph slot. + * + * @output: + * aglyph :: + * A handle to the glyph object. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * Because `*aglyph->advance.x` and `*aglyph->advance.y` are 16.16 + * fixed-point numbers, `slot->advance.x` and `slot->advance.y` (which + * are in 26.6 fixed-point format) must be in the range ]-32768;32768[. + */ FT_EXPORT( FT_Error ) FT_Get_Glyph( FT_GlyphSlot slot, FT_Glyph *aglyph ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Glyph_Copy */ - /* */ - /* <Description> */ - /* A function used to copy a glyph image. Note that the created */ - /* @FT_Glyph object must be released with @FT_Done_Glyph. */ - /* */ - /* <Input> */ - /* source :: A handle to the source glyph object. */ - /* */ - /* <Output> */ - /* target :: A handle to the target glyph object. 0~in case of */ - /* error. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Glyph_Copy + * + * @description: + * A function used to copy a glyph image. Note that the created + * @FT_Glyph object must be released with @FT_Done_Glyph. + * + * @input: + * source :: + * A handle to the source glyph object. + * + * @output: + * target :: + * A handle to the target glyph object. 0~in case of error. + * + * @return: + * FreeType error code. 0~means success. + */ FT_EXPORT( FT_Error ) FT_Glyph_Copy( FT_Glyph source, FT_Glyph *target ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Glyph_Transform */ - /* */ - /* <Description> */ - /* Transform a glyph image if its format is scalable. */ - /* */ - /* <InOut> */ - /* glyph :: A handle to the target glyph object. */ - /* */ - /* <Input> */ - /* matrix :: A pointer to a 2x2 matrix to apply. */ - /* */ - /* delta :: A pointer to a 2d vector to apply. Coordinates are */ - /* expressed in 1/64th of a pixel. */ - /* */ - /* <Return> */ - /* FreeType error code (if not 0, the glyph format is not scalable). */ - /* */ - /* <Note> */ - /* The 2x2 transformation matrix is also applied to the glyph's */ - /* advance vector. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Glyph_Transform + * + * @description: + * Transform a glyph image if its format is scalable. + * + * @inout: + * glyph :: + * A handle to the target glyph object. + * + * @input: + * matrix :: + * A pointer to a 2x2 matrix to apply. + * + * delta :: + * A pointer to a 2d vector to apply. Coordinates are expressed in + * 1/64th of a pixel. + * + * @return: + * FreeType error code (if not 0, the glyph format is not scalable). + * + * @note: + * The 2x2 transformation matrix is also applied to the glyph's advance + * vector. + */ FT_EXPORT( FT_Error ) FT_Glyph_Transform( FT_Glyph glyph, FT_Matrix* matrix, FT_Vector* delta ); - /*************************************************************************/ - /* */ - /* <Enum> */ - /* FT_Glyph_BBox_Mode */ - /* */ - /* <Description> */ - /* The mode how the values of @FT_Glyph_Get_CBox are returned. */ - /* */ - /* <Values> */ - /* FT_GLYPH_BBOX_UNSCALED :: */ - /* Return unscaled font units. */ - /* */ - /* FT_GLYPH_BBOX_SUBPIXELS :: */ - /* Return unfitted 26.6 coordinates. */ - /* */ - /* FT_GLYPH_BBOX_GRIDFIT :: */ - /* Return grid-fitted 26.6 coordinates. */ - /* */ - /* FT_GLYPH_BBOX_TRUNCATE :: */ - /* Return coordinates in integer pixels. */ - /* */ - /* FT_GLYPH_BBOX_PIXELS :: */ - /* Return grid-fitted pixel coordinates. */ - /* */ + /************************************************************************** + * + * @enum: + * FT_Glyph_BBox_Mode + * + * @description: + * The mode how the values of @FT_Glyph_Get_CBox are returned. + * + * @values: + * FT_GLYPH_BBOX_UNSCALED :: + * Return unscaled font units. + * + * FT_GLYPH_BBOX_SUBPIXELS :: + * Return unfitted 26.6 coordinates. + * + * FT_GLYPH_BBOX_GRIDFIT :: + * Return grid-fitted 26.6 coordinates. + * + * FT_GLYPH_BBOX_TRUNCATE :: + * Return coordinates in integer pixels. + * + * FT_GLYPH_BBOX_PIXELS :: + * Return grid-fitted pixel coordinates. + */ typedef enum FT_Glyph_BBox_Mode_ { FT_GLYPH_BBOX_UNSCALED = 0, @@ -332,7 +379,7 @@ FT_BEGIN_HEADER /* these constants are deprecated; use the corresponding */ - /* `FT_Glyph_BBox_Mode' values instead */ + /* `FT_Glyph_BBox_Mode` values instead */ #define ft_glyph_bbox_unscaled FT_GLYPH_BBOX_UNSCALED #define ft_glyph_bbox_subpixels FT_GLYPH_BBOX_SUBPIXELS #define ft_glyph_bbox_gridfit FT_GLYPH_BBOX_GRIDFIT @@ -340,187 +387,188 @@ FT_BEGIN_HEADER #define ft_glyph_bbox_pixels FT_GLYPH_BBOX_PIXELS - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Glyph_Get_CBox */ - /* */ - /* <Description> */ - /* Return a glyph's `control box'. The control box encloses all the */ - /* outline's points, including Bezier control points. Though it */ - /* coincides with the exact bounding box for most glyphs, it can be */ - /* slightly larger in some situations (like when rotating an outline */ - /* that contains Bezier outside arcs). */ - /* */ - /* Computing the control box is very fast, while getting the bounding */ - /* box can take much more time as it needs to walk over all segments */ - /* and arcs in the outline. To get the latter, you can use the */ - /* `ftbbox' component, which is dedicated to this single task. */ - /* */ - /* <Input> */ - /* glyph :: A handle to the source glyph object. */ - /* */ - /* mode :: The mode that indicates how to interpret the returned */ - /* bounding box values. */ - /* */ - /* <Output> */ - /* acbox :: The glyph coordinate bounding box. Coordinates are */ - /* expressed in 1/64th of pixels if it is grid-fitted. */ - /* */ - /* <Note> */ - /* Coordinates are relative to the glyph origin, using the y~upwards */ - /* convention. */ - /* */ - /* If the glyph has been loaded with @FT_LOAD_NO_SCALE, `bbox_mode' */ - /* must be set to @FT_GLYPH_BBOX_UNSCALED to get unscaled font */ - /* units in 26.6 pixel format. The value @FT_GLYPH_BBOX_SUBPIXELS */ - /* is another name for this constant. */ - /* */ - /* If the font is tricky and the glyph has been loaded with */ - /* @FT_LOAD_NO_SCALE, the resulting CBox is meaningless. To get */ - /* reasonable values for the CBox it is necessary to load the glyph */ - /* at a large ppem value (so that the hinting instructions can */ - /* properly shift and scale the subglyphs), then extracting the CBox, */ - /* which can be eventually converted back to font units. */ - /* */ - /* Note that the maximum coordinates are exclusive, which means that */ - /* one can compute the width and height of the glyph image (be it in */ - /* integer or 26.6 pixels) as: */ - /* */ - /* { */ - /* width = bbox.xMax - bbox.xMin; */ - /* height = bbox.yMax - bbox.yMin; */ - /* } */ - /* */ - /* Note also that for 26.6 coordinates, if `bbox_mode' is set to */ - /* @FT_GLYPH_BBOX_GRIDFIT, the coordinates will also be grid-fitted, */ - /* which corresponds to: */ - /* */ - /* { */ - /* bbox.xMin = FLOOR(bbox.xMin); */ - /* bbox.yMin = FLOOR(bbox.yMin); */ - /* bbox.xMax = CEILING(bbox.xMax); */ - /* bbox.yMax = CEILING(bbox.yMax); */ - /* } */ - /* */ - /* To get the bbox in pixel coordinates, set `bbox_mode' to */ - /* @FT_GLYPH_BBOX_TRUNCATE. */ - /* */ - /* To get the bbox in grid-fitted pixel coordinates, set `bbox_mode' */ - /* to @FT_GLYPH_BBOX_PIXELS. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Glyph_Get_CBox + * + * @description: + * Return a glyph's 'control box'. The control box encloses all the + * outline's points, including Bezier control points. Though it + * coincides with the exact bounding box for most glyphs, it can be + * slightly larger in some situations (like when rotating an outline that + * contains Bezier outside arcs). + * + * Computing the control box is very fast, while getting the bounding box + * can take much more time as it needs to walk over all segments and arcs + * in the outline. To get the latter, you can use the 'ftbbox' + * component, which is dedicated to this single task. + * + * @input: + * glyph :: + * A handle to the source glyph object. + * + * mode :: + * The mode that indicates how to interpret the returned bounding box + * values. + * + * @output: + * acbox :: + * The glyph coordinate bounding box. Coordinates are expressed in + * 1/64th of pixels if it is grid-fitted. + * + * @note: + * Coordinates are relative to the glyph origin, using the y~upwards + * convention. + * + * If the glyph has been loaded with @FT_LOAD_NO_SCALE, `bbox_mode` must + * be set to @FT_GLYPH_BBOX_UNSCALED to get unscaled font units in 26.6 + * pixel format. The value @FT_GLYPH_BBOX_SUBPIXELS is another name for + * this constant. + * + * If the font is tricky and the glyph has been loaded with + * @FT_LOAD_NO_SCALE, the resulting CBox is meaningless. To get + * reasonable values for the CBox it is necessary to load the glyph at a + * large ppem value (so that the hinting instructions can properly shift + * and scale the subglyphs), then extracting the CBox, which can be + * eventually converted back to font units. + * + * Note that the maximum coordinates are exclusive, which means that one + * can compute the width and height of the glyph image (be it in integer + * or 26.6 pixels) as: + * + * ``` + * width = bbox.xMax - bbox.xMin; + * height = bbox.yMax - bbox.yMin; + * ``` + * + * Note also that for 26.6 coordinates, if `bbox_mode` is set to + * @FT_GLYPH_BBOX_GRIDFIT, the coordinates will also be grid-fitted, + * which corresponds to: + * + * ``` + * bbox.xMin = FLOOR(bbox.xMin); + * bbox.yMin = FLOOR(bbox.yMin); + * bbox.xMax = CEILING(bbox.xMax); + * bbox.yMax = CEILING(bbox.yMax); + * ``` + * + * To get the bbox in pixel coordinates, set `bbox_mode` to + * @FT_GLYPH_BBOX_TRUNCATE. + * + * To get the bbox in grid-fitted pixel coordinates, set `bbox_mode` to + * @FT_GLYPH_BBOX_PIXELS. + */ FT_EXPORT( void ) FT_Glyph_Get_CBox( FT_Glyph glyph, FT_UInt bbox_mode, FT_BBox *acbox ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Glyph_To_Bitmap */ - /* */ - /* <Description> */ - /* Convert a given glyph object to a bitmap glyph object. */ - /* */ - /* <InOut> */ - /* the_glyph :: A pointer to a handle to the target glyph. */ - /* */ - /* <Input> */ - /* render_mode :: An enumeration that describes how the data is */ - /* rendered. */ - /* */ - /* origin :: A pointer to a vector used to translate the glyph */ - /* image before rendering. Can be~0 (if no */ - /* translation). The origin is expressed in */ - /* 26.6 pixels. */ - /* */ - /* destroy :: A boolean that indicates that the original glyph */ - /* image should be destroyed by this function. It is */ - /* never destroyed in case of error. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* This function does nothing if the glyph format isn't scalable. */ - /* */ - /* The glyph image is translated with the `origin' vector before */ - /* rendering. */ - /* */ - /* The first parameter is a pointer to an @FT_Glyph handle, that will */ - /* be _replaced_ by this function (with newly allocated data). */ - /* Typically, you would use (omitting error handling): */ - /* */ - /* */ - /* { */ - /* FT_Glyph glyph; */ - /* FT_BitmapGlyph glyph_bitmap; */ - /* */ - /* */ - /* // load glyph */ - /* error = FT_Load_Char( face, glyph_index, FT_LOAD_DEFAULT ); */ - /* */ - /* // extract glyph image */ - /* error = FT_Get_Glyph( face->glyph, &glyph ); */ - /* */ - /* // convert to a bitmap (default render mode + destroying old) */ - /* if ( glyph->format != FT_GLYPH_FORMAT_BITMAP ) */ - /* { */ - /* error = FT_Glyph_To_Bitmap( &glyph, FT_RENDER_MODE_NORMAL, */ - /* 0, 1 ); */ - /* if ( error ) // `glyph' unchanged */ - /* ... */ - /* } */ - /* */ - /* // access bitmap content by typecasting */ - /* glyph_bitmap = (FT_BitmapGlyph)glyph; */ - /* */ - /* // do funny stuff with it, like blitting/drawing */ - /* ... */ - /* */ - /* // discard glyph image (bitmap or not) */ - /* FT_Done_Glyph( glyph ); */ - /* } */ - /* */ - /* */ - /* Here another example, again without error handling: */ - /* */ - /* */ - /* { */ - /* FT_Glyph glyphs[MAX_GLYPHS] */ - /* */ - /* */ - /* ... */ - /* */ - /* for ( idx = 0; i < MAX_GLYPHS; i++ ) */ - /* error = FT_Load_Glyph( face, idx, FT_LOAD_DEFAULT ) || */ - /* FT_Get_Glyph ( face->glyph, &glyph[idx] ); */ - /* */ - /* ... */ - /* */ - /* for ( idx = 0; i < MAX_GLYPHS; i++ ) */ - /* { */ - /* FT_Glyph bitmap = glyphs[idx]; */ - /* */ - /* */ - /* ... */ - /* */ - /* // after this call, `bitmap' no longer points into */ - /* // the `glyphs' array (and the old value isn't destroyed) */ - /* FT_Glyph_To_Bitmap( &bitmap, FT_RENDER_MODE_MONO, 0, 0 ); */ - /* */ - /* ... */ - /* */ - /* FT_Done_Glyph( bitmap ); */ - /* } */ - /* */ - /* ... */ - /* */ - /* for ( idx = 0; i < MAX_GLYPHS; i++ ) */ - /* FT_Done_Glyph( glyphs[idx] ); */ - /* } */ - /* */ + /************************************************************************** + * + * @function: + * FT_Glyph_To_Bitmap + * + * @description: + * Convert a given glyph object to a bitmap glyph object. + * + * @inout: + * the_glyph :: + * A pointer to a handle to the target glyph. + * + * @input: + * render_mode :: + * An enumeration that describes how the data is rendered. + * + * origin :: + * A pointer to a vector used to translate the glyph image before + * rendering. Can be~0 (if no translation). The origin is expressed + * in 26.6 pixels. + * + * destroy :: + * A boolean that indicates that the original glyph image should be + * destroyed by this function. It is never destroyed in case of error. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function does nothing if the glyph format isn't scalable. + * + * The glyph image is translated with the `origin` vector before + * rendering. + * + * The first parameter is a pointer to an @FT_Glyph handle, that will be + * _replaced_ by this function (with newly allocated data). Typically, + * you would use (omitting error handling): + * + * ``` + * FT_Glyph glyph; + * FT_BitmapGlyph glyph_bitmap; + * + * + * // load glyph + * error = FT_Load_Char( face, glyph_index, FT_LOAD_DEFAULT ); + * + * // extract glyph image + * error = FT_Get_Glyph( face->glyph, &glyph ); + * + * // convert to a bitmap (default render mode + destroying old) + * if ( glyph->format != FT_GLYPH_FORMAT_BITMAP ) + * { + * error = FT_Glyph_To_Bitmap( &glyph, FT_RENDER_MODE_NORMAL, + * 0, 1 ); + * if ( error ) // `glyph' unchanged + * ... + * } + * + * // access bitmap content by typecasting + * glyph_bitmap = (FT_BitmapGlyph)glyph; + * + * // do funny stuff with it, like blitting/drawing + * ... + * + * // discard glyph image (bitmap or not) + * FT_Done_Glyph( glyph ); + * ``` + * + * Here is another example, again without error handling: + * + * ``` + * FT_Glyph glyphs[MAX_GLYPHS] + * + * + * ... + * + * for ( idx = 0; i < MAX_GLYPHS; i++ ) + * error = FT_Load_Glyph( face, idx, FT_LOAD_DEFAULT ) || + * FT_Get_Glyph ( face->glyph, &glyphs[idx] ); + * + * ... + * + * for ( idx = 0; i < MAX_GLYPHS; i++ ) + * { + * FT_Glyph bitmap = glyphs[idx]; + * + * + * ... + * + * // after this call, `bitmap' no longer points into + * // the `glyphs' array (and the old value isn't destroyed) + * FT_Glyph_To_Bitmap( &bitmap, FT_RENDER_MODE_MONO, 0, 0 ); + * + * ... + * + * FT_Done_Glyph( bitmap ); + * } + * + * ... + * + * for ( idx = 0; i < MAX_GLYPHS; i++ ) + * FT_Done_Glyph( glyphs[idx] ); + * ``` + */ FT_EXPORT( FT_Error ) FT_Glyph_To_Bitmap( FT_Glyph* the_glyph, FT_Render_Mode render_mode, @@ -528,17 +576,18 @@ FT_BEGIN_HEADER FT_Bool destroy ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Done_Glyph */ - /* */ - /* <Description> */ - /* Destroy a given glyph. */ - /* */ - /* <Input> */ - /* glyph :: A handle to the target glyph object. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Done_Glyph + * + * @description: + * Destroy a given glyph. + * + * @input: + * glyph :: + * A handle to the target glyph object. + */ FT_EXPORT( void ) FT_Done_Glyph( FT_Glyph glyph ); @@ -547,54 +596,56 @@ FT_BEGIN_HEADER /* other helpful functions */ - /*************************************************************************/ - /* */ - /* <Section> */ - /* computations */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Matrix_Multiply */ - /* */ - /* <Description> */ - /* Perform the matrix operation `b = a*b'. */ - /* */ - /* <Input> */ - /* a :: A pointer to matrix `a'. */ - /* */ - /* <InOut> */ - /* b :: A pointer to matrix `b'. */ - /* */ - /* <Note> */ - /* The result is undefined if either `a' or `b' is zero. */ - /* */ - /* Since the function uses wrap-around arithmetic, results become */ - /* meaningless if the arguments are very large. */ - /* */ + /************************************************************************** + * + * @section: + * computations + * + */ + + + /************************************************************************** + * + * @function: + * FT_Matrix_Multiply + * + * @description: + * Perform the matrix operation `b = a*b`. + * + * @input: + * a :: + * A pointer to matrix `a`. + * + * @inout: + * b :: + * A pointer to matrix `b`. + * + * @note: + * The result is undefined if either `a` or `b` is zero. + * + * Since the function uses wrap-around arithmetic, results become + * meaningless if the arguments are very large. + */ FT_EXPORT( void ) FT_Matrix_Multiply( const FT_Matrix* a, FT_Matrix* b ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Matrix_Invert */ - /* */ - /* <Description> */ - /* Invert a 2x2 matrix. Return an error if it can't be inverted. */ - /* */ - /* <InOut> */ - /* matrix :: A pointer to the target matrix. Remains untouched in */ - /* case of error. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Matrix_Invert + * + * @description: + * Invert a 2x2 matrix. Return an error if it can't be inverted. + * + * @inout: + * matrix :: + * A pointer to the target matrix. Remains untouched in case of error. + * + * @return: + * FreeType error code. 0~means success. + */ FT_EXPORT( FT_Error ) FT_Matrix_Invert( FT_Matrix* matrix ); diff --git a/sdk/lib/3rdparty/freetype/include/freetype/ftgxval.h b/sdk/lib/3rdparty/freetype/include/freetype/ftgxval.h index 8382d599545c6..b14f637c569f2 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/ftgxval.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/ftgxval.h @@ -1,28 +1,28 @@ -/***************************************************************************/ -/* */ -/* ftgxval.h */ -/* */ -/* FreeType API for validating TrueTypeGX/AAT tables (specification). */ -/* */ -/* Copyright 2004-2018 by */ -/* Masatake YAMATO, Redhat K.K, */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftgxval.h + * + * FreeType API for validating TrueTypeGX/AAT tables (specification). + * + * Copyright (C) 2004-2019 by + * Masatake YAMATO, Redhat K.K, + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + +/**************************************************************************** + * + * gxvalid is derived from both gxlayout module and otvalid module. + * Development of gxlayout is supported by the Information-technology + * Promotion Agency(IPA), Japan. + * + */ #ifndef FTGXVAL_H_ @@ -41,43 +41,43 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* <Section> */ - /* gx_validation */ - /* */ - /* <Title> */ - /* TrueTypeGX/AAT Validation */ - /* */ - /* <Abstract> */ - /* An API to validate TrueTypeGX/AAT tables. */ - /* */ - /* <Description> */ - /* This section contains the declaration of functions to validate */ - /* some TrueTypeGX tables (feat, mort, morx, bsln, just, kern, opbd, */ - /* trak, prop, lcar). */ - /* */ - /* <Order> */ - /* FT_TrueTypeGX_Validate */ - /* FT_TrueTypeGX_Free */ - /* */ - /* FT_ClassicKern_Validate */ - /* FT_ClassicKern_Free */ - /* */ - /* FT_VALIDATE_GX_LENGTH */ - /* FT_VALIDATE_GXXXX */ - /* FT_VALIDATE_CKERNXXX */ - /* */ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* */ - /* Warning: Use FT_VALIDATE_XXX to validate a table. */ - /* Following definitions are for gxvalid developers. */ - /* */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * @section: + * gx_validation + * + * @title: + * TrueTypeGX/AAT Validation + * + * @abstract: + * An API to validate TrueTypeGX/AAT tables. + * + * @description: + * This section contains the declaration of functions to validate some + * TrueTypeGX tables (feat, mort, morx, bsln, just, kern, opbd, trak, + * prop, lcar). + * + * @order: + * FT_TrueTypeGX_Validate + * FT_TrueTypeGX_Free + * + * FT_ClassicKern_Validate + * FT_ClassicKern_Free + * + * FT_VALIDATE_GX_LENGTH + * FT_VALIDATE_GXXXX + * FT_VALIDATE_CKERNXXX + * + */ + + /************************************************************************** + * + * + * Warning: Use `FT_VALIDATE_XXX` to validate a table. + * Following definitions are for gxvalid developers. + * + * + */ #define FT_VALIDATE_feat_INDEX 0 #define FT_VALIDATE_mort_INDEX 1 @@ -92,14 +92,14 @@ FT_BEGIN_HEADER #define FT_VALIDATE_GX_LAST_INDEX FT_VALIDATE_lcar_INDEX - /************************************************************************* + /************************************************************************** * * @macro: * FT_VALIDATE_GX_LENGTH * * @description: * The number of tables checked in this module. Use it as a parameter - * for the `table-length' argument of function @FT_TrueTypeGX_Validate. + * for the `table-length` argument of function @FT_TrueTypeGX_Validate. */ #define FT_VALIDATE_GX_LENGTH ( FT_VALIDATE_GX_LAST_INDEX + 1 ) @@ -112,51 +112,51 @@ FT_BEGIN_HEADER ( FT_VALIDATE_GX_START << FT_VALIDATE_##tag##_INDEX ) - /********************************************************************** - * - * @enum: - * FT_VALIDATE_GXXXX - * - * @description: - * A list of bit-field constants used with @FT_TrueTypeGX_Validate to - * indicate which TrueTypeGX/AAT Type tables should be validated. - * - * @values: - * FT_VALIDATE_feat :: - * Validate `feat' table. - * - * FT_VALIDATE_mort :: - * Validate `mort' table. - * - * FT_VALIDATE_morx :: - * Validate `morx' table. - * - * FT_VALIDATE_bsln :: - * Validate `bsln' table. - * - * FT_VALIDATE_just :: - * Validate `just' table. - * - * FT_VALIDATE_kern :: - * Validate `kern' table. - * - * FT_VALIDATE_opbd :: - * Validate `opbd' table. - * - * FT_VALIDATE_trak :: - * Validate `trak' table. - * - * FT_VALIDATE_prop :: - * Validate `prop' table. - * - * FT_VALIDATE_lcar :: - * Validate `lcar' table. - * - * FT_VALIDATE_GX :: - * Validate all TrueTypeGX tables (feat, mort, morx, bsln, just, kern, - * opbd, trak, prop and lcar). - * - */ + /************************************************************************** + * + * @enum: + * FT_VALIDATE_GXXXX + * + * @description: + * A list of bit-field constants used with @FT_TrueTypeGX_Validate to + * indicate which TrueTypeGX/AAT Type tables should be validated. + * + * @values: + * FT_VALIDATE_feat :: + * Validate 'feat' table. + * + * FT_VALIDATE_mort :: + * Validate 'mort' table. + * + * FT_VALIDATE_morx :: + * Validate 'morx' table. + * + * FT_VALIDATE_bsln :: + * Validate 'bsln' table. + * + * FT_VALIDATE_just :: + * Validate 'just' table. + * + * FT_VALIDATE_kern :: + * Validate 'kern' table. + * + * FT_VALIDATE_opbd :: + * Validate 'opbd' table. + * + * FT_VALIDATE_trak :: + * Validate 'trak' table. + * + * FT_VALIDATE_prop :: + * Validate 'prop' table. + * + * FT_VALIDATE_lcar :: + * Validate 'lcar' table. + * + * FT_VALIDATE_GX :: + * Validate all TrueTypeGX tables (feat, mort, morx, bsln, just, kern, + * opbd, trak, prop and lcar). + * + */ #define FT_VALIDATE_feat FT_VALIDATE_GX_BITFIELD( feat ) #define FT_VALIDATE_mort FT_VALIDATE_GX_BITFIELD( mort ) @@ -181,47 +181,47 @@ FT_BEGIN_HEADER FT_VALIDATE_lcar ) - /********************************************************************** - * - * @function: - * FT_TrueTypeGX_Validate - * - * @description: - * Validate various TrueTypeGX tables to assure that all offsets and - * indices are valid. The idea is that a higher-level library that - * actually does the text layout can access those tables without - * error checking (which can be quite time consuming). - * - * @input: - * face :: - * A handle to the input face. - * - * validation_flags :: - * A bit field that specifies the tables to be validated. See - * @FT_VALIDATE_GXXXX for possible values. - * - * table_length :: - * The size of the `tables' array. Normally, @FT_VALIDATE_GX_LENGTH - * should be passed. - * - * @output: - * tables :: - * The array where all validated sfnt tables are stored. - * The array itself must be allocated by a client. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * This function only works with TrueTypeGX fonts, returning an error - * otherwise. - * - * After use, the application should deallocate the buffers pointed to by - * each `tables' element, by calling @FT_TrueTypeGX_Free. A NULL value - * indicates that the table either doesn't exist in the font, the - * application hasn't asked for validation, or the validator doesn't have - * the ability to validate the sfnt table. - */ + /************************************************************************** + * + * @function: + * FT_TrueTypeGX_Validate + * + * @description: + * Validate various TrueTypeGX tables to assure that all offsets and + * indices are valid. The idea is that a higher-level library that + * actually does the text layout can access those tables without error + * checking (which can be quite time consuming). + * + * @input: + * face :: + * A handle to the input face. + * + * validation_flags :: + * A bit field that specifies the tables to be validated. See + * @FT_VALIDATE_GXXXX for possible values. + * + * table_length :: + * The size of the `tables` array. Normally, @FT_VALIDATE_GX_LENGTH + * should be passed. + * + * @output: + * tables :: + * The array where all validated sfnt tables are stored. The array + * itself must be allocated by a client. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with TrueTypeGX fonts, returning an error + * otherwise. + * + * After use, the application should deallocate the buffers pointed to by + * each `tables` element, by calling @FT_TrueTypeGX_Free. A `NULL` value + * indicates that the table either doesn't exist in the font, the + * application hasn't asked for validation, or the validator doesn't have + * the ability to validate the sfnt table. + */ FT_EXPORT( FT_Error ) FT_TrueTypeGX_Validate( FT_Face face, FT_UInt validation_flags, @@ -229,119 +229,117 @@ FT_BEGIN_HEADER FT_UInt table_length ); - /********************************************************************** - * - * @function: - * FT_TrueTypeGX_Free - * - * @description: - * Free the buffer allocated by TrueTypeGX validator. - * - * @input: - * face :: - * A handle to the input face. - * - * table :: - * The pointer to the buffer allocated by - * @FT_TrueTypeGX_Validate. - * - * @note: - * This function must be used to free the buffer allocated by - * @FT_TrueTypeGX_Validate only. - */ + /************************************************************************** + * + * @function: + * FT_TrueTypeGX_Free + * + * @description: + * Free the buffer allocated by TrueTypeGX validator. + * + * @input: + * face :: + * A handle to the input face. + * + * table :: + * The pointer to the buffer allocated by @FT_TrueTypeGX_Validate. + * + * @note: + * This function must be used to free the buffer allocated by + * @FT_TrueTypeGX_Validate only. + */ FT_EXPORT( void ) FT_TrueTypeGX_Free( FT_Face face, FT_Bytes table ); - /********************************************************************** - * - * @enum: - * FT_VALIDATE_CKERNXXX - * - * @description: - * A list of bit-field constants used with @FT_ClassicKern_Validate - * to indicate the classic kern dialect or dialects. If the selected - * type doesn't fit, @FT_ClassicKern_Validate regards the table as - * invalid. - * - * @values: - * FT_VALIDATE_MS :: - * Handle the `kern' table as a classic Microsoft kern table. - * - * FT_VALIDATE_APPLE :: - * Handle the `kern' table as a classic Apple kern table. - * - * FT_VALIDATE_CKERN :: - * Handle the `kern' as either classic Apple or Microsoft kern table. - */ + /************************************************************************** + * + * @enum: + * FT_VALIDATE_CKERNXXX + * + * @description: + * A list of bit-field constants used with @FT_ClassicKern_Validate to + * indicate the classic kern dialect or dialects. If the selected type + * doesn't fit, @FT_ClassicKern_Validate regards the table as invalid. + * + * @values: + * FT_VALIDATE_MS :: + * Handle the 'kern' table as a classic Microsoft kern table. + * + * FT_VALIDATE_APPLE :: + * Handle the 'kern' table as a classic Apple kern table. + * + * FT_VALIDATE_CKERN :: + * Handle the 'kern' as either classic Apple or Microsoft kern table. + */ #define FT_VALIDATE_MS ( FT_VALIDATE_GX_START << 0 ) #define FT_VALIDATE_APPLE ( FT_VALIDATE_GX_START << 1 ) #define FT_VALIDATE_CKERN ( FT_VALIDATE_MS | FT_VALIDATE_APPLE ) - /********************************************************************** - * - * @function: - * FT_ClassicKern_Validate - * - * @description: - * Validate classic (16-bit format) kern table to assure that the offsets - * and indices are valid. The idea is that a higher-level library that - * actually does the text layout can access those tables without error - * checking (which can be quite time consuming). - * - * The `kern' table validator in @FT_TrueTypeGX_Validate deals with both - * the new 32-bit format and the classic 16-bit format, while - * FT_ClassicKern_Validate only supports the classic 16-bit format. - * - * @input: - * face :: - * A handle to the input face. - * - * validation_flags :: - * A bit field that specifies the dialect to be validated. See - * @FT_VALIDATE_CKERNXXX for possible values. - * - * @output: - * ckern_table :: - * A pointer to the kern table. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * After use, the application should deallocate the buffers pointed to by - * `ckern_table', by calling @FT_ClassicKern_Free. A NULL value - * indicates that the table doesn't exist in the font. - */ + /************************************************************************** + * + * @function: + * FT_ClassicKern_Validate + * + * @description: + * Validate classic (16-bit format) kern table to assure that the + * offsets and indices are valid. The idea is that a higher-level + * library that actually does the text layout can access those tables + * without error checking (which can be quite time consuming). + * + * The 'kern' table validator in @FT_TrueTypeGX_Validate deals with both + * the new 32-bit format and the classic 16-bit format, while + * FT_ClassicKern_Validate only supports the classic 16-bit format. + * + * @input: + * face :: + * A handle to the input face. + * + * validation_flags :: + * A bit field that specifies the dialect to be validated. See + * @FT_VALIDATE_CKERNXXX for possible values. + * + * @output: + * ckern_table :: + * A pointer to the kern table. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * After use, the application should deallocate the buffers pointed to by + * `ckern_table`, by calling @FT_ClassicKern_Free. A `NULL` value + * indicates that the table doesn't exist in the font. + */ FT_EXPORT( FT_Error ) FT_ClassicKern_Validate( FT_Face face, FT_UInt validation_flags, FT_Bytes *ckern_table ); - /********************************************************************** - * - * @function: - * FT_ClassicKern_Free - * - * @description: - * Free the buffer allocated by classic Kern validator. - * - * @input: - * face :: - * A handle to the input face. - * - * table :: - * The pointer to the buffer that is allocated by - * @FT_ClassicKern_Validate. - * - * @note: - * This function must be used to free the buffer allocated by - * @FT_ClassicKern_Validate only. - */ + /************************************************************************** + * + * @function: + * FT_ClassicKern_Free + * + * @description: + * Free the buffer allocated by classic Kern validator. + * + * @input: + * face :: + * A handle to the input face. + * + * table :: + * The pointer to the buffer that is allocated by + * @FT_ClassicKern_Validate. + * + * @note: + * This function must be used to free the buffer allocated by + * @FT_ClassicKern_Validate only. + */ FT_EXPORT( void ) FT_ClassicKern_Free( FT_Face face, FT_Bytes table ); diff --git a/sdk/lib/3rdparty/freetype/include/freetype/ftgzip.h b/sdk/lib/3rdparty/freetype/include/freetype/ftgzip.h index db033da0ed2e9..418c61228ea92 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/ftgzip.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/ftgzip.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftgzip.h */ -/* */ -/* Gzip-compressed stream support. */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftgzip.h + * + * Gzip-compressed stream support. + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTGZIP_H_ @@ -31,108 +31,108 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* <Section> */ - /* gzip */ - /* */ - /* <Title> */ - /* GZIP Streams */ - /* */ - /* <Abstract> */ - /* Using gzip-compressed font files. */ - /* */ - /* <Description> */ - /* This section contains the declaration of Gzip-specific functions. */ - /* */ - /*************************************************************************/ - - - /************************************************************************ - * - * @function: - * FT_Stream_OpenGzip - * - * @description: - * Open a new stream to parse gzip-compressed font files. This is - * mainly used to support the compressed `*.pcf.gz' fonts that come - * with XFree86. - * - * @input: - * stream :: - * The target embedding stream. - * - * source :: - * The source stream. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * The source stream must be opened _before_ calling this function. - * - * Calling the internal function `FT_Stream_Close' on the new stream will - * *not* call `FT_Stream_Close' on the source stream. None of the stream - * objects will be released to the heap. - * - * The stream implementation is very basic and resets the decompression - * process each time seeking backwards is needed within the stream. - * - * In certain builds of the library, gzip compression recognition is - * automatically handled when calling @FT_New_Face or @FT_Open_Face. - * This means that if no font driver is capable of handling the raw - * compressed file, the library will try to open a gzipped stream from - * it and re-open the face with it. - * - * This function may return `FT_Err_Unimplemented_Feature' if your build - * of FreeType was not compiled with zlib support. - */ + /************************************************************************** + * + * @section: + * gzip + * + * @title: + * GZIP Streams + * + * @abstract: + * Using gzip-compressed font files. + * + * @description: + * This section contains the declaration of Gzip-specific functions. + * + */ + + + /************************************************************************** + * + * @function: + * FT_Stream_OpenGzip + * + * @description: + * Open a new stream to parse gzip-compressed font files. This is mainly + * used to support the compressed `*.pcf.gz` fonts that come with + * XFree86. + * + * @input: + * stream :: + * The target embedding stream. + * + * source :: + * The source stream. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The source stream must be opened _before_ calling this function. + * + * Calling the internal function `FT_Stream_Close` on the new stream will + * **not** call `FT_Stream_Close` on the source stream. None of the + * stream objects will be released to the heap. + * + * The stream implementation is very basic and resets the decompression + * process each time seeking backwards is needed within the stream. + * + * In certain builds of the library, gzip compression recognition is + * automatically handled when calling @FT_New_Face or @FT_Open_Face. + * This means that if no font driver is capable of handling the raw + * compressed file, the library will try to open a gzipped stream from it + * and re-open the face with it. + * + * This function may return `FT_Err_Unimplemented_Feature` if your build + * of FreeType was not compiled with zlib support. + */ FT_EXPORT( FT_Error ) FT_Stream_OpenGzip( FT_Stream stream, FT_Stream source ); - /************************************************************************ - * - * @function: - * FT_Gzip_Uncompress - * - * @description: - * Decompress a zipped input buffer into an output buffer. This function - * is modeled after zlib's `uncompress' function. - * - * @input: - * memory :: - * A FreeType memory handle. - * - * input :: - * The input buffer. - * - * input_len :: - * The length of the input buffer. - * - * @output: - * output:: - * The output buffer. - * - * @inout: - * output_len :: - * Before calling the function, this is the total size of the output - * buffer, which must be large enough to hold the entire uncompressed - * data (so the size of the uncompressed data must be known in - * advance). After calling the function, `output_len' is the size of - * the used data in `output'. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * This function may return `FT_Err_Unimplemented_Feature' if your build - * of FreeType was not compiled with zlib support. - * - * @since: - * 2.5.1 - */ + /************************************************************************** + * + * @function: + * FT_Gzip_Uncompress + * + * @description: + * Decompress a zipped input buffer into an output buffer. This function + * is modeled after zlib's `uncompress` function. + * + * @input: + * memory :: + * A FreeType memory handle. + * + * input :: + * The input buffer. + * + * input_len :: + * The length of the input buffer. + * + * @output: + * output :: + * The output buffer. + * + * @inout: + * output_len :: + * Before calling the function, this is the total size of the output + * buffer, which must be large enough to hold the entire uncompressed + * data (so the size of the uncompressed data must be known in + * advance). After calling the function, `output_len` is the size of + * the used data in `output`. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function may return `FT_Err_Unimplemented_Feature` if your build + * of FreeType was not compiled with zlib support. + * + * @since: + * 2.5.1 + */ FT_EXPORT( FT_Error ) FT_Gzip_Uncompress( FT_Memory memory, FT_Byte* output, diff --git a/sdk/lib/3rdparty/freetype/include/freetype/ftimage.h b/sdk/lib/3rdparty/freetype/include/freetype/ftimage.h index 79ede1959d706..d640b0b0aa959 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/ftimage.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/ftimage.h @@ -1,27 +1,27 @@ -/***************************************************************************/ -/* */ -/* ftimage.h */ -/* */ -/* FreeType glyph image formats and default raster interface */ -/* (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - /*************************************************************************/ - /* */ - /* Note: A `raster' is simply a scan-line converter, used to render */ - /* FT_Outlines into FT_Bitmaps. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * ftimage.h + * + * FreeType glyph image formats and default raster interface + * (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + /************************************************************************** + * + * Note: A 'raster' is simply a scan-line converter, used to render + * FT_Outlines into FT_Bitmaps. + * + */ #ifndef FTIMAGE_H_ @@ -37,40 +37,42 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* <Section> */ - /* basic_types */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Pos */ - /* */ - /* <Description> */ - /* The type FT_Pos is used to store vectorial coordinates. Depending */ - /* on the context, these can represent distances in integer font */ - /* units, or 16.16, or 26.6 fixed-point pixel coordinates. */ - /* */ + /************************************************************************** + * + * @section: + * basic_types + * + */ + + + /************************************************************************** + * + * @type: + * FT_Pos + * + * @description: + * The type FT_Pos is used to store vectorial coordinates. Depending on + * the context, these can represent distances in integer font units, or + * 16.16, or 26.6 fixed-point pixel coordinates. + */ typedef signed long FT_Pos; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Vector */ - /* */ - /* <Description> */ - /* A simple structure used to store a 2D vector; coordinates are of */ - /* the FT_Pos type. */ - /* */ - /* <Fields> */ - /* x :: The horizontal coordinate. */ - /* y :: The vertical coordinate. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_Vector + * + * @description: + * A simple structure used to store a 2D vector; coordinates are of the + * FT_Pos type. + * + * @fields: + * x :: + * The horizontal coordinate. + * y :: + * The vertical coordinate. + */ typedef struct FT_Vector_ { FT_Pos x; @@ -79,39 +81,41 @@ FT_BEGIN_HEADER } FT_Vector; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_BBox */ - /* */ - /* <Description> */ - /* A structure used to hold an outline's bounding box, i.e., the */ - /* coordinates of its extrema in the horizontal and vertical */ - /* directions. */ - /* */ - /* <Fields> */ - /* xMin :: The horizontal minimum (left-most). */ - /* */ - /* yMin :: The vertical minimum (bottom-most). */ - /* */ - /* xMax :: The horizontal maximum (right-most). */ - /* */ - /* yMax :: The vertical maximum (top-most). */ - /* */ - /* <Note> */ - /* The bounding box is specified with the coordinates of the lower */ - /* left and the upper right corner. In PostScript, those values are */ - /* often called (llx,lly) and (urx,ury), respectively. */ - /* */ - /* If `yMin' is negative, this value gives the glyph's descender. */ - /* Otherwise, the glyph doesn't descend below the baseline. */ - /* Similarly, if `ymax' is positive, this value gives the glyph's */ - /* ascender. */ - /* */ - /* `xMin' gives the horizontal distance from the glyph's origin to */ - /* the left edge of the glyph's bounding box. If `xMin' is negative, */ - /* the glyph extends to the left of the origin. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_BBox + * + * @description: + * A structure used to hold an outline's bounding box, i.e., the + * coordinates of its extrema in the horizontal and vertical directions. + * + * @fields: + * xMin :: + * The horizontal minimum (left-most). + * + * yMin :: + * The vertical minimum (bottom-most). + * + * xMax :: + * The horizontal maximum (right-most). + * + * yMax :: + * The vertical maximum (top-most). + * + * @note: + * The bounding box is specified with the coordinates of the lower left + * and the upper right corner. In PostScript, those values are often + * called (llx,lly) and (urx,ury), respectively. + * + * If `yMin` is negative, this value gives the glyph's descender. + * Otherwise, the glyph doesn't descend below the baseline. Similarly, + * if `ymax` is positive, this value gives the glyph's ascender. + * + * `xMin` gives the horizontal distance from the glyph's origin to the + * left edge of the glyph's bounding box. If `xMin` is negative, the + * glyph extends to the left of the origin. + */ typedef struct FT_BBox_ { FT_Pos xMin, yMin; @@ -120,63 +124,60 @@ FT_BEGIN_HEADER } FT_BBox; - /*************************************************************************/ - /* */ - /* <Enum> */ - /* FT_Pixel_Mode */ - /* */ - /* <Description> */ - /* An enumeration type used to describe the format of pixels in a */ - /* given bitmap. Note that additional formats may be added in the */ - /* future. */ - /* */ - /* <Values> */ - /* FT_PIXEL_MODE_NONE :: */ - /* Value~0 is reserved. */ - /* */ - /* FT_PIXEL_MODE_MONO :: */ - /* A monochrome bitmap, using 1~bit per pixel. Note that pixels */ - /* are stored in most-significant order (MSB), which means that */ - /* the left-most pixel in a byte has value 128. */ - /* */ - /* FT_PIXEL_MODE_GRAY :: */ - /* An 8-bit bitmap, generally used to represent anti-aliased glyph */ - /* images. Each pixel is stored in one byte. Note that the number */ - /* of `gray' levels is stored in the `num_grays' field of the */ - /* @FT_Bitmap structure (it generally is 256). */ - /* */ - /* FT_PIXEL_MODE_GRAY2 :: */ - /* A 2-bit per pixel bitmap, used to represent embedded */ - /* anti-aliased bitmaps in font files according to the OpenType */ - /* specification. We haven't found a single font using this */ - /* format, however. */ - /* */ - /* FT_PIXEL_MODE_GRAY4 :: */ - /* A 4-bit per pixel bitmap, representing embedded anti-aliased */ - /* bitmaps in font files according to the OpenType specification. */ - /* We haven't found a single font using this format, however. */ - /* */ - /* FT_PIXEL_MODE_LCD :: */ - /* An 8-bit bitmap, representing RGB or BGR decimated glyph images */ - /* used for display on LCD displays; the bitmap is three times */ - /* wider than the original glyph image. See also */ - /* @FT_RENDER_MODE_LCD. */ - /* */ - /* FT_PIXEL_MODE_LCD_V :: */ - /* An 8-bit bitmap, representing RGB or BGR decimated glyph images */ - /* used for display on rotated LCD displays; the bitmap is three */ - /* times taller than the original glyph image. See also */ - /* @FT_RENDER_MODE_LCD_V. */ - /* */ - /* FT_PIXEL_MODE_BGRA :: */ - /* [Since 2.5] An image with four 8-bit channels per pixel, */ - /* representing a color image (such as emoticons) with alpha */ - /* channel. For each pixel, the format is BGRA, which means, the */ - /* blue channel comes first in memory. The color channels are */ - /* pre-multiplied and in the sRGB colorspace. For example, full */ - /* red at half-translucent opacity will be represented as */ - /* `00,00,80,80', not `00,00,FF,80'. See also @FT_LOAD_COLOR. */ - /* */ + /************************************************************************** + * + * @enum: + * FT_Pixel_Mode + * + * @description: + * An enumeration type used to describe the format of pixels in a given + * bitmap. Note that additional formats may be added in the future. + * + * @values: + * FT_PIXEL_MODE_NONE :: + * Value~0 is reserved. + * + * FT_PIXEL_MODE_MONO :: + * A monochrome bitmap, using 1~bit per pixel. Note that pixels are + * stored in most-significant order (MSB), which means that the + * left-most pixel in a byte has value 128. + * + * FT_PIXEL_MODE_GRAY :: + * An 8-bit bitmap, generally used to represent anti-aliased glyph + * images. Each pixel is stored in one byte. Note that the number of + * 'gray' levels is stored in the `num_grays` field of the @FT_Bitmap + * structure (it generally is 256). + * + * FT_PIXEL_MODE_GRAY2 :: + * A 2-bit per pixel bitmap, used to represent embedded anti-aliased + * bitmaps in font files according to the OpenType specification. We + * haven't found a single font using this format, however. + * + * FT_PIXEL_MODE_GRAY4 :: + * A 4-bit per pixel bitmap, representing embedded anti-aliased bitmaps + * in font files according to the OpenType specification. We haven't + * found a single font using this format, however. + * + * FT_PIXEL_MODE_LCD :: + * An 8-bit bitmap, representing RGB or BGR decimated glyph images used + * for display on LCD displays; the bitmap is three times wider than + * the original glyph image. See also @FT_RENDER_MODE_LCD. + * + * FT_PIXEL_MODE_LCD_V :: + * An 8-bit bitmap, representing RGB or BGR decimated glyph images used + * for display on rotated LCD displays; the bitmap is three times + * taller than the original glyph image. See also + * @FT_RENDER_MODE_LCD_V. + * + * FT_PIXEL_MODE_BGRA :: + * [Since 2.5] An image with four 8-bit channels per pixel, + * representing a color image (such as emoticons) with alpha channel. + * For each pixel, the format is BGRA, which means, the blue channel + * comes first in memory. The color channels are pre-multiplied and in + * the sRGB colorspace. For example, full red at half-translucent + * opacity will be represented as '00,00,80,80', not '00,00,FF,80'. + * See also @FT_LOAD_COLOR. + */ typedef enum FT_Pixel_Mode_ { FT_PIXEL_MODE_NONE = 0, @@ -193,7 +194,7 @@ FT_BEGIN_HEADER } FT_Pixel_Mode; - /* these constants are deprecated; use the corresponding `FT_Pixel_Mode' */ + /* these constants are deprecated; use the corresponding `FT_Pixel_Mode` */ /* values instead. */ #define ft_pixel_mode_none FT_PIXEL_MODE_NONE #define ft_pixel_mode_mono FT_PIXEL_MODE_MONO @@ -202,62 +203,61 @@ FT_BEGIN_HEADER #define ft_pixel_mode_pal4 FT_PIXEL_MODE_GRAY4 - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Bitmap */ - /* */ - /* <Description> */ - /* A structure used to describe a bitmap or pixmap to the raster. */ - /* Note that we now manage pixmaps of various depths through the */ - /* `pixel_mode' field. */ - /* */ - /* <Fields> */ - /* rows :: The number of bitmap rows. */ - /* */ - /* width :: The number of pixels in bitmap row. */ - /* */ - /* pitch :: The pitch's absolute value is the number of bytes */ - /* taken by one bitmap row, including padding. */ - /* However, the pitch is positive when the bitmap has */ - /* a `down' flow, and negative when it has an `up' */ - /* flow. In all cases, the pitch is an offset to add */ - /* to a bitmap pointer in order to go down one row. */ - /* */ - /* Note that `padding' means the alignment of a */ - /* bitmap to a byte border, and FreeType functions */ - /* normally align to the smallest possible integer */ - /* value. */ - /* */ - /* For the B/W rasterizer, `pitch' is always an even */ - /* number. */ - /* */ - /* To change the pitch of a bitmap (say, to make it a */ - /* multiple of 4), use @FT_Bitmap_Convert. */ - /* Alternatively, you might use callback functions to */ - /* directly render to the application's surface; see */ - /* the file `example2.cpp' in the tutorial for a */ - /* demonstration. */ - /* */ - /* buffer :: A typeless pointer to the bitmap buffer. This */ - /* value should be aligned on 32-bit boundaries in */ - /* most cases. */ - /* */ - /* num_grays :: This field is only used with */ - /* @FT_PIXEL_MODE_GRAY; it gives the number of gray */ - /* levels used in the bitmap. */ - /* */ - /* pixel_mode :: The pixel mode, i.e., how pixel bits are stored. */ - /* See @FT_Pixel_Mode for possible values. */ - /* */ - /* palette_mode :: This field is intended for paletted pixel modes; */ - /* it indicates how the palette is stored. Not */ - /* used currently. */ - /* */ - /* palette :: A typeless pointer to the bitmap palette; this */ - /* field is intended for paletted pixel modes. Not */ - /* used currently. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_Bitmap + * + * @description: + * A structure used to describe a bitmap or pixmap to the raster. Note + * that we now manage pixmaps of various depths through the `pixel_mode` + * field. + * + * @fields: + * rows :: + * The number of bitmap rows. + * + * width :: + * The number of pixels in bitmap row. + * + * pitch :: + * The pitch's absolute value is the number of bytes taken by one + * bitmap row, including padding. However, the pitch is positive when + * the bitmap has a 'down' flow, and negative when it has an 'up' flow. + * In all cases, the pitch is an offset to add to a bitmap pointer in + * order to go down one row. + * + * Note that 'padding' means the alignment of a bitmap to a byte + * border, and FreeType functions normally align to the smallest + * possible integer value. + * + * For the B/W rasterizer, `pitch` is always an even number. + * + * To change the pitch of a bitmap (say, to make it a multiple of 4), + * use @FT_Bitmap_Convert. Alternatively, you might use callback + * functions to directly render to the application's surface; see the + * file `example2.cpp` in the tutorial for a demonstration. + * + * buffer :: + * A typeless pointer to the bitmap buffer. This value should be + * aligned on 32-bit boundaries in most cases. + * + * num_grays :: + * This field is only used with @FT_PIXEL_MODE_GRAY; it gives the + * number of gray levels used in the bitmap. + * + * pixel_mode :: + * The pixel mode, i.e., how pixel bits are stored. See @FT_Pixel_Mode + * for possible values. + * + * palette_mode :: + * This field is intended for paletted pixel modes; it indicates how + * the palette is stored. Not used currently. + * + * palette :: + * A typeless pointer to the bitmap palette; this field is intended for + * paletted pixel modes. Not used currently. + */ typedef struct FT_Bitmap_ { unsigned int rows; @@ -272,65 +272,68 @@ FT_BEGIN_HEADER } FT_Bitmap; - /*************************************************************************/ - /* */ - /* <Section> */ - /* outline_processing */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Outline */ - /* */ - /* <Description> */ - /* This structure is used to describe an outline to the scan-line */ - /* converter. */ - /* */ - /* <Fields> */ - /* n_contours :: The number of contours in the outline. */ - /* */ - /* n_points :: The number of points in the outline. */ - /* */ - /* points :: A pointer to an array of `n_points' @FT_Vector */ - /* elements, giving the outline's point coordinates. */ - /* */ - /* tags :: A pointer to an array of `n_points' chars, giving */ - /* each outline point's type. */ - /* */ - /* If bit~0 is unset, the point is `off' the curve, */ - /* i.e., a Bezier control point, while it is `on' if */ - /* set. */ - /* */ - /* Bit~1 is meaningful for `off' points only. If set, */ - /* it indicates a third-order Bezier arc control point; */ - /* and a second-order control point if unset. */ - /* */ - /* If bit~2 is set, bits 5-7 contain the drop-out mode */ - /* (as defined in the OpenType specification; the value */ - /* is the same as the argument to the SCANMODE */ - /* instruction). */ - /* */ - /* Bits 3 and~4 are reserved for internal purposes. */ - /* */ - /* contours :: An array of `n_contours' shorts, giving the end */ - /* point of each contour within the outline. For */ - /* example, the first contour is defined by the points */ - /* `0' to `contours[0]', the second one is defined by */ - /* the points `contours[0]+1' to `contours[1]', etc. */ - /* */ - /* flags :: A set of bit flags used to characterize the outline */ - /* and give hints to the scan-converter and hinter on */ - /* how to convert/grid-fit it. See @FT_OUTLINE_XXX. */ - /* */ - /* <Note> */ - /* The B/W rasterizer only checks bit~2 in the `tags' array for the */ - /* first point of each contour. The drop-out mode as given with */ - /* @FT_OUTLINE_IGNORE_DROPOUTS, @FT_OUTLINE_SMART_DROPOUTS, and */ - /* @FT_OUTLINE_INCLUDE_STUBS in `flags' is then overridden. */ - /* */ + /************************************************************************** + * + * @section: + * outline_processing + * + */ + + + /************************************************************************** + * + * @struct: + * FT_Outline + * + * @description: + * This structure is used to describe an outline to the scan-line + * converter. + * + * @fields: + * n_contours :: + * The number of contours in the outline. + * + * n_points :: + * The number of points in the outline. + * + * points :: + * A pointer to an array of `n_points` @FT_Vector elements, giving the + * outline's point coordinates. + * + * tags :: + * A pointer to an array of `n_points` chars, giving each outline + * point's type. + * + * If bit~0 is unset, the point is 'off' the curve, i.e., a Bezier + * control point, while it is 'on' if set. + * + * Bit~1 is meaningful for 'off' points only. If set, it indicates a + * third-order Bezier arc control point; and a second-order control + * point if unset. + * + * If bit~2 is set, bits 5-7 contain the drop-out mode (as defined in + * the OpenType specification; the value is the same as the argument to + * the 'SCANMODE' instruction). + * + * Bits 3 and~4 are reserved for internal purposes. + * + * contours :: + * An array of `n_contours` shorts, giving the end point of each + * contour within the outline. For example, the first contour is + * defined by the points '0' to `contours[0]`, the second one is + * defined by the points `contours[0]+1` to `contours[1]`, etc. + * + * flags :: + * A set of bit flags used to characterize the outline and give hints + * to the scan-converter and hinter on how to convert/grid-fit it. See + * @FT_OUTLINE_XXX. + * + * @note: + * The B/W rasterizer only checks bit~2 in the `tags` array for the first + * point of each contour. The drop-out mode as given with + * @FT_OUTLINE_IGNORE_DROPOUTS, @FT_OUTLINE_SMART_DROPOUTS, and + * @FT_OUTLINE_INCLUDE_STUBS in `flags` is then overridden. + */ typedef struct FT_Outline_ { short n_contours; /* number of contours in glyph */ @@ -352,78 +355,76 @@ FT_BEGIN_HEADER #define FT_OUTLINE_POINTS_MAX SHRT_MAX - /*************************************************************************/ - /* */ - /* <Enum> */ - /* FT_OUTLINE_XXX */ - /* */ - /* <Description> */ - /* A list of bit-field constants use for the flags in an outline's */ - /* `flags' field. */ - /* */ - /* <Values> */ - /* FT_OUTLINE_NONE :: */ - /* Value~0 is reserved. */ - /* */ - /* FT_OUTLINE_OWNER :: */ - /* If set, this flag indicates that the outline's field arrays */ - /* (i.e., `points', `flags', and `contours') are `owned' by the */ - /* outline object, and should thus be freed when it is destroyed. */ - /* */ - /* FT_OUTLINE_EVEN_ODD_FILL :: */ - /* By default, outlines are filled using the non-zero winding rule. */ - /* If set to 1, the outline will be filled using the even-odd fill */ - /* rule (only works with the smooth rasterizer). */ - /* */ - /* FT_OUTLINE_REVERSE_FILL :: */ - /* By default, outside contours of an outline are oriented in */ - /* clock-wise direction, as defined in the TrueType specification. */ - /* This flag is set if the outline uses the opposite direction */ - /* (typically for Type~1 fonts). This flag is ignored by the scan */ - /* converter. */ - /* */ - /* FT_OUTLINE_IGNORE_DROPOUTS :: */ - /* By default, the scan converter will try to detect drop-outs in */ - /* an outline and correct the glyph bitmap to ensure consistent */ - /* shape continuity. If set, this flag hints the scan-line */ - /* converter to ignore such cases. See below for more information. */ - /* */ - /* FT_OUTLINE_SMART_DROPOUTS :: */ - /* Select smart dropout control. If unset, use simple dropout */ - /* control. Ignored if @FT_OUTLINE_IGNORE_DROPOUTS is set. See */ - /* below for more information. */ - /* */ - /* FT_OUTLINE_INCLUDE_STUBS :: */ - /* If set, turn pixels on for `stubs', otherwise exclude them. */ - /* Ignored if @FT_OUTLINE_IGNORE_DROPOUTS is set. See below for */ - /* more information. */ - /* */ - /* FT_OUTLINE_HIGH_PRECISION :: */ - /* This flag indicates that the scan-line converter should try to */ - /* convert this outline to bitmaps with the highest possible */ - /* quality. It is typically set for small character sizes. Note */ - /* that this is only a hint that might be completely ignored by a */ - /* given scan-converter. */ - /* */ - /* FT_OUTLINE_SINGLE_PASS :: */ - /* This flag is set to force a given scan-converter to only use a */ - /* single pass over the outline to render a bitmap glyph image. */ - /* Normally, it is set for very large character sizes. It is only */ - /* a hint that might be completely ignored by a given */ - /* scan-converter. */ - /* */ - /* <Note> */ - /* The flags @FT_OUTLINE_IGNORE_DROPOUTS, @FT_OUTLINE_SMART_DROPOUTS, */ - /* and @FT_OUTLINE_INCLUDE_STUBS are ignored by the smooth */ - /* rasterizer. */ - /* */ - /* There exists a second mechanism to pass the drop-out mode to the */ - /* B/W rasterizer; see the `tags' field in @FT_Outline. */ - /* */ - /* Please refer to the description of the `SCANTYPE' instruction in */ - /* the OpenType specification (in file `ttinst1.doc') how simple */ - /* drop-outs, smart drop-outs, and stubs are defined. */ - /* */ + /************************************************************************** + * + * @enum: + * FT_OUTLINE_XXX + * + * @description: + * A list of bit-field constants used for the flags in an outline's + * `flags` field. + * + * @values: + * FT_OUTLINE_NONE :: + * Value~0 is reserved. + * + * FT_OUTLINE_OWNER :: + * If set, this flag indicates that the outline's field arrays (i.e., + * `points`, `flags`, and `contours`) are 'owned' by the outline + * object, and should thus be freed when it is destroyed. + * + * FT_OUTLINE_EVEN_ODD_FILL :: + * By default, outlines are filled using the non-zero winding rule. If + * set to 1, the outline will be filled using the even-odd fill rule + * (only works with the smooth rasterizer). + * + * FT_OUTLINE_REVERSE_FILL :: + * By default, outside contours of an outline are oriented in + * clock-wise direction, as defined in the TrueType specification. + * This flag is set if the outline uses the opposite direction + * (typically for Type~1 fonts). This flag is ignored by the scan + * converter. + * + * FT_OUTLINE_IGNORE_DROPOUTS :: + * By default, the scan converter will try to detect drop-outs in an + * outline and correct the glyph bitmap to ensure consistent shape + * continuity. If set, this flag hints the scan-line converter to + * ignore such cases. See below for more information. + * + * FT_OUTLINE_SMART_DROPOUTS :: + * Select smart dropout control. If unset, use simple dropout control. + * Ignored if @FT_OUTLINE_IGNORE_DROPOUTS is set. See below for more + * information. + * + * FT_OUTLINE_INCLUDE_STUBS :: + * If set, turn pixels on for 'stubs', otherwise exclude them. Ignored + * if @FT_OUTLINE_IGNORE_DROPOUTS is set. See below for more + * information. + * + * FT_OUTLINE_HIGH_PRECISION :: + * This flag indicates that the scan-line converter should try to + * convert this outline to bitmaps with the highest possible quality. + * It is typically set for small character sizes. Note that this is + * only a hint that might be completely ignored by a given + * scan-converter. + * + * FT_OUTLINE_SINGLE_PASS :: + * This flag is set to force a given scan-converter to only use a + * single pass over the outline to render a bitmap glyph image. + * Normally, it is set for very large character sizes. It is only a + * hint that might be completely ignored by a given scan-converter. + * + * @note: + * The flags @FT_OUTLINE_IGNORE_DROPOUTS, @FT_OUTLINE_SMART_DROPOUTS, and + * @FT_OUTLINE_INCLUDE_STUBS are ignored by the smooth rasterizer. + * + * There exists a second mechanism to pass the drop-out mode to the B/W + * rasterizer; see the `tags` field in @FT_Outline. + * + * Please refer to the description of the 'SCANTYPE' instruction in the + * OpenType specification (in file `ttinst1.doc`) how simple drop-outs, + * smart drop-outs, and stubs are defined. + */ #define FT_OUTLINE_NONE 0x0 #define FT_OUTLINE_OWNER 0x1 #define FT_OUTLINE_EVEN_ODD_FILL 0x2 @@ -437,7 +438,7 @@ FT_BEGIN_HEADER /* these constants are deprecated; use the corresponding */ - /* `FT_OUTLINE_XXX' values instead */ + /* `FT_OUTLINE_XXX` values instead */ #define ft_outline_none FT_OUTLINE_NONE #define ft_outline_owner FT_OUTLINE_OWNER #define ft_outline_even_odd_fill FT_OUTLINE_EVEN_ODD_FILL @@ -448,20 +449,25 @@ FT_BEGIN_HEADER /* */ -#define FT_CURVE_TAG( flag ) ( flag & 3 ) +#define FT_CURVE_TAG( flag ) ( flag & 0x03 ) -#define FT_CURVE_TAG_ON 1 -#define FT_CURVE_TAG_CONIC 0 -#define FT_CURVE_TAG_CUBIC 2 + /* see the `tags` field in `FT_Outline` for a description of the values */ +#define FT_CURVE_TAG_ON 0x01 +#define FT_CURVE_TAG_CONIC 0x00 +#define FT_CURVE_TAG_CUBIC 0x02 -#define FT_CURVE_TAG_HAS_SCANMODE 4 +#define FT_CURVE_TAG_HAS_SCANMODE 0x04 -#define FT_CURVE_TAG_TOUCH_X 8 /* reserved for the TrueType hinter */ -#define FT_CURVE_TAG_TOUCH_Y 16 /* reserved for the TrueType hinter */ +#define FT_CURVE_TAG_TOUCH_X 0x08 /* reserved for TrueType hinter */ +#define FT_CURVE_TAG_TOUCH_Y 0x10 /* reserved for TrueType hinter */ #define FT_CURVE_TAG_TOUCH_BOTH ( FT_CURVE_TAG_TOUCH_X | \ FT_CURVE_TAG_TOUCH_Y ) + /* values 0x20, 0x40, and 0x80 are reserved */ + + /* these constants are deprecated; use the corresponding */ + /* `FT_CURVE_TAG_XXX` values instead */ #define FT_Curve_Tag_On FT_CURVE_TAG_ON #define FT_Curve_Tag_Conic FT_CURVE_TAG_CONIC #define FT_Curve_Tag_Cubic FT_CURVE_TAG_CUBIC @@ -469,26 +475,28 @@ FT_BEGIN_HEADER #define FT_Curve_Tag_Touch_Y FT_CURVE_TAG_TOUCH_Y - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_Outline_MoveToFunc */ - /* */ - /* <Description> */ - /* A function pointer type used to describe the signature of a `move */ - /* to' function during outline walking/decomposition. */ - /* */ - /* A `move to' is emitted to start a new contour in an outline. */ - /* */ - /* <Input> */ - /* to :: A pointer to the target point of the `move to'. */ - /* */ - /* user :: A typeless pointer, which is passed from the caller of the */ - /* decomposition function. */ - /* */ - /* <Return> */ - /* Error code. 0~means success. */ - /* */ + /************************************************************************** + * + * @functype: + * FT_Outline_MoveToFunc + * + * @description: + * A function pointer type used to describe the signature of a 'move to' + * function during outline walking/decomposition. + * + * A 'move to' is emitted to start a new contour in an outline. + * + * @input: + * to :: + * A pointer to the target point of the 'move to'. + * + * user :: + * A typeless pointer, which is passed from the caller of the + * decomposition function. + * + * @return: + * Error code. 0~means success. + */ typedef int (*FT_Outline_MoveToFunc)( const FT_Vector* to, void* user ); @@ -496,26 +504,28 @@ FT_BEGIN_HEADER #define FT_Outline_MoveTo_Func FT_Outline_MoveToFunc - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_Outline_LineToFunc */ - /* */ - /* <Description> */ - /* A function pointer type used to describe the signature of a `line */ - /* to' function during outline walking/decomposition. */ - /* */ - /* A `line to' is emitted to indicate a segment in the outline. */ - /* */ - /* <Input> */ - /* to :: A pointer to the target point of the `line to'. */ - /* */ - /* user :: A typeless pointer, which is passed from the caller of the */ - /* decomposition function. */ - /* */ - /* <Return> */ - /* Error code. 0~means success. */ - /* */ + /************************************************************************** + * + * @functype: + * FT_Outline_LineToFunc + * + * @description: + * A function pointer type used to describe the signature of a 'line to' + * function during outline walking/decomposition. + * + * A 'line to' is emitted to indicate a segment in the outline. + * + * @input: + * to :: + * A pointer to the target point of the 'line to'. + * + * user :: + * A typeless pointer, which is passed from the caller of the + * decomposition function. + * + * @return: + * Error code. 0~means success. + */ typedef int (*FT_Outline_LineToFunc)( const FT_Vector* to, void* user ); @@ -523,30 +533,33 @@ FT_BEGIN_HEADER #define FT_Outline_LineTo_Func FT_Outline_LineToFunc - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_Outline_ConicToFunc */ - /* */ - /* <Description> */ - /* A function pointer type used to describe the signature of a `conic */ - /* to' function during outline walking or decomposition. */ - /* */ - /* A `conic to' is emitted to indicate a second-order Bezier arc in */ - /* the outline. */ - /* */ - /* <Input> */ - /* control :: An intermediate control point between the last position */ - /* and the new target in `to'. */ - /* */ - /* to :: A pointer to the target end point of the conic arc. */ - /* */ - /* user :: A typeless pointer, which is passed from the caller of */ - /* the decomposition function. */ - /* */ - /* <Return> */ - /* Error code. 0~means success. */ - /* */ + /************************************************************************** + * + * @functype: + * FT_Outline_ConicToFunc + * + * @description: + * A function pointer type used to describe the signature of a 'conic to' + * function during outline walking or decomposition. + * + * A 'conic to' is emitted to indicate a second-order Bezier arc in the + * outline. + * + * @input: + * control :: + * An intermediate control point between the last position and the new + * target in `to`. + * + * to :: + * A pointer to the target end point of the conic arc. + * + * user :: + * A typeless pointer, which is passed from the caller of the + * decomposition function. + * + * @return: + * Error code. 0~means success. + */ typedef int (*FT_Outline_ConicToFunc)( const FT_Vector* control, const FT_Vector* to, @@ -555,30 +568,34 @@ FT_BEGIN_HEADER #define FT_Outline_ConicTo_Func FT_Outline_ConicToFunc - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_Outline_CubicToFunc */ - /* */ - /* <Description> */ - /* A function pointer type used to describe the signature of a `cubic */ - /* to' function during outline walking or decomposition. */ - /* */ - /* A `cubic to' is emitted to indicate a third-order Bezier arc. */ - /* */ - /* <Input> */ - /* control1 :: A pointer to the first Bezier control point. */ - /* */ - /* control2 :: A pointer to the second Bezier control point. */ - /* */ - /* to :: A pointer to the target end point. */ - /* */ - /* user :: A typeless pointer, which is passed from the caller of */ - /* the decomposition function. */ - /* */ - /* <Return> */ - /* Error code. 0~means success. */ - /* */ + /************************************************************************** + * + * @functype: + * FT_Outline_CubicToFunc + * + * @description: + * A function pointer type used to describe the signature of a 'cubic to' + * function during outline walking or decomposition. + * + * A 'cubic to' is emitted to indicate a third-order Bezier arc. + * + * @input: + * control1 :: + * A pointer to the first Bezier control point. + * + * control2 :: + * A pointer to the second Bezier control point. + * + * to :: + * A pointer to the target end point. + * + * user :: + * A typeless pointer, which is passed from the caller of the + * decomposition function. + * + * @return: + * Error code. 0~means success. + */ typedef int (*FT_Outline_CubicToFunc)( const FT_Vector* control1, const FT_Vector* control2, @@ -588,43 +605,49 @@ FT_BEGIN_HEADER #define FT_Outline_CubicTo_Func FT_Outline_CubicToFunc - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Outline_Funcs */ - /* */ - /* <Description> */ - /* A structure to hold various function pointers used during outline */ - /* decomposition in order to emit segments, conic, and cubic Beziers. */ - /* */ - /* <Fields> */ - /* move_to :: The `move to' emitter. */ - /* */ - /* line_to :: The segment emitter. */ - /* */ - /* conic_to :: The second-order Bezier arc emitter. */ - /* */ - /* cubic_to :: The third-order Bezier arc emitter. */ - /* */ - /* shift :: The shift that is applied to coordinates before they */ - /* are sent to the emitter. */ - /* */ - /* delta :: The delta that is applied to coordinates before they */ - /* are sent to the emitter, but after the shift. */ - /* */ - /* <Note> */ - /* The point coordinates sent to the emitters are the transformed */ - /* version of the original coordinates (this is important for high */ - /* accuracy during scan-conversion). The transformation is simple: */ - /* */ - /* { */ - /* x' = (x << shift) - delta */ - /* y' = (y << shift) - delta */ - /* } */ - /* */ - /* Set the values of `shift' and `delta' to~0 to get the original */ - /* point coordinates. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_Outline_Funcs + * + * @description: + * A structure to hold various function pointers used during outline + * decomposition in order to emit segments, conic, and cubic Beziers. + * + * @fields: + * move_to :: + * The 'move to' emitter. + * + * line_to :: + * The segment emitter. + * + * conic_to :: + * The second-order Bezier arc emitter. + * + * cubic_to :: + * The third-order Bezier arc emitter. + * + * shift :: + * The shift that is applied to coordinates before they are sent to the + * emitter. + * + * delta :: + * The delta that is applied to coordinates before they are sent to the + * emitter, but after the shift. + * + * @note: + * The point coordinates sent to the emitters are the transformed version + * of the original coordinates (this is important for high accuracy + * during scan-conversion). The transformation is simple: + * + * ``` + * x' = (x << shift) - delta + * y' = (y << shift) - delta + * ``` + * + * Set the values of `shift` and `delta` to~0 to get the original point + * coordinates. + */ typedef struct FT_Outline_Funcs_ { FT_Outline_MoveToFunc move_to; @@ -638,33 +661,32 @@ FT_BEGIN_HEADER } FT_Outline_Funcs; - /*************************************************************************/ - /* */ - /* <Section> */ - /* basic_types */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Macro> */ - /* FT_IMAGE_TAG */ - /* */ - /* <Description> */ - /* This macro converts four-letter tags to an unsigned long type. */ - /* */ - /* <Note> */ - /* Since many 16-bit compilers don't like 32-bit enumerations, you */ - /* should redefine this macro in case of problems to something like */ - /* this: */ - /* */ - /* { */ - /* #define FT_IMAGE_TAG( value, _x1, _x2, _x3, _x4 ) value */ - /* } */ - /* */ - /* to get a simple enumeration without assigning special numbers. */ - /* */ + /************************************************************************** + * + * @section: + * basic_types + * + */ + + + /************************************************************************** + * + * @macro: + * FT_IMAGE_TAG + * + * @description: + * This macro converts four-letter tags to an unsigned long type. + * + * @note: + * Since many 16-bit compilers don't like 32-bit enumerations, you should + * redefine this macro in case of problems to something like this: + * + * ``` + * #define FT_IMAGE_TAG( value, _x1, _x2, _x3, _x4 ) value + * ``` + * + * to get a simple enumeration without assigning special numbers. + */ #ifndef FT_IMAGE_TAG #define FT_IMAGE_TAG( value, _x1, _x2, _x3, _x4 ) \ value = ( ( (unsigned long)_x1 << 24 ) | \ @@ -674,44 +696,43 @@ FT_BEGIN_HEADER #endif /* FT_IMAGE_TAG */ - /*************************************************************************/ - /* */ - /* <Enum> */ - /* FT_Glyph_Format */ - /* */ - /* <Description> */ - /* An enumeration type used to describe the format of a given glyph */ - /* image. Note that this version of FreeType only supports two image */ - /* formats, even though future font drivers will be able to register */ - /* their own format. */ - /* */ - /* <Values> */ - /* FT_GLYPH_FORMAT_NONE :: */ - /* The value~0 is reserved. */ - /* */ - /* FT_GLYPH_FORMAT_COMPOSITE :: */ - /* The glyph image is a composite of several other images. This */ - /* format is _only_ used with @FT_LOAD_NO_RECURSE, and is used to */ - /* report compound glyphs (like accented characters). */ - /* */ - /* FT_GLYPH_FORMAT_BITMAP :: */ - /* The glyph image is a bitmap, and can be described as an */ - /* @FT_Bitmap. You generally need to access the `bitmap' field of */ - /* the @FT_GlyphSlotRec structure to read it. */ - /* */ - /* FT_GLYPH_FORMAT_OUTLINE :: */ - /* The glyph image is a vectorial outline made of line segments */ - /* and Bezier arcs; it can be described as an @FT_Outline; you */ - /* generally want to access the `outline' field of the */ - /* @FT_GlyphSlotRec structure to read it. */ - /* */ - /* FT_GLYPH_FORMAT_PLOTTER :: */ - /* The glyph image is a vectorial path with no inside and outside */ - /* contours. Some Type~1 fonts, like those in the Hershey family, */ - /* contain glyphs in this format. These are described as */ - /* @FT_Outline, but FreeType isn't currently capable of rendering */ - /* them correctly. */ - /* */ + /************************************************************************** + * + * @enum: + * FT_Glyph_Format + * + * @description: + * An enumeration type used to describe the format of a given glyph + * image. Note that this version of FreeType only supports two image + * formats, even though future font drivers will be able to register + * their own format. + * + * @values: + * FT_GLYPH_FORMAT_NONE :: + * The value~0 is reserved. + * + * FT_GLYPH_FORMAT_COMPOSITE :: + * The glyph image is a composite of several other images. This format + * is _only_ used with @FT_LOAD_NO_RECURSE, and is used to report + * compound glyphs (like accented characters). + * + * FT_GLYPH_FORMAT_BITMAP :: + * The glyph image is a bitmap, and can be described as an @FT_Bitmap. + * You generally need to access the `bitmap` field of the + * @FT_GlyphSlotRec structure to read it. + * + * FT_GLYPH_FORMAT_OUTLINE :: + * The glyph image is a vectorial outline made of line segments and + * Bezier arcs; it can be described as an @FT_Outline; you generally + * want to access the `outline` field of the @FT_GlyphSlotRec structure + * to read it. + * + * FT_GLYPH_FORMAT_PLOTTER :: + * The glyph image is a vectorial path with no inside and outside + * contours. Some Type~1 fonts, like those in the Hershey family, + * contain glyphs in this format. These are described as @FT_Outline, + * but FreeType isn't currently capable of rendering them correctly. + */ typedef enum FT_Glyph_Format_ { FT_IMAGE_TAG( FT_GLYPH_FORMAT_NONE, 0, 0, 0, 0 ), @@ -725,7 +746,7 @@ FT_BEGIN_HEADER /* these constants are deprecated; use the corresponding */ - /* `FT_Glyph_Format' values instead. */ + /* `FT_Glyph_Format` values instead. */ #define ft_glyph_format_none FT_GLYPH_FORMAT_NONE #define ft_glyph_format_composite FT_GLYPH_FORMAT_COMPOSITE #define ft_glyph_format_bitmap FT_GLYPH_FORMAT_BITMAP @@ -744,87 +765,89 @@ FT_BEGIN_HEADER /*************************************************************************/ - /*************************************************************************/ - /* */ - /* A raster is a scan converter, in charge of rendering an outline into */ - /* a bitmap. This section contains the public API for rasters. */ - /* */ - /* Note that in FreeType 2, all rasters are now encapsulated within */ - /* specific modules called `renderers'. See `ftrender.h' for more */ - /* details on renderers. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* raster */ - /* */ - /* <Title> */ - /* Scanline Converter */ - /* */ - /* <Abstract> */ - /* How vectorial outlines are converted into bitmaps and pixmaps. */ - /* */ - /* <Description> */ - /* This section contains technical definitions. */ - /* */ - /* <Order> */ - /* FT_Raster */ - /* FT_Span */ - /* FT_SpanFunc */ - /* */ - /* FT_Raster_Params */ - /* FT_RASTER_FLAG_XXX */ - /* */ - /* FT_Raster_NewFunc */ - /* FT_Raster_DoneFunc */ - /* FT_Raster_ResetFunc */ - /* FT_Raster_SetModeFunc */ - /* FT_Raster_RenderFunc */ - /* FT_Raster_Funcs */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Raster */ - /* */ - /* <Description> */ - /* An opaque handle (pointer) to a raster object. Each object can be */ - /* used independently to convert an outline into a bitmap or pixmap. */ - /* */ + /************************************************************************** + * + * A raster is a scan converter, in charge of rendering an outline into a + * bitmap. This section contains the public API for rasters. + * + * Note that in FreeType 2, all rasters are now encapsulated within + * specific modules called 'renderers'. See `ftrender.h` for more details + * on renderers. + * + */ + + + /************************************************************************** + * + * @section: + * raster + * + * @title: + * Scanline Converter + * + * @abstract: + * How vectorial outlines are converted into bitmaps and pixmaps. + * + * @description: + * This section contains technical definitions. + * + * @order: + * FT_Raster + * FT_Span + * FT_SpanFunc + * + * FT_Raster_Params + * FT_RASTER_FLAG_XXX + * + * FT_Raster_NewFunc + * FT_Raster_DoneFunc + * FT_Raster_ResetFunc + * FT_Raster_SetModeFunc + * FT_Raster_RenderFunc + * FT_Raster_Funcs + * + */ + + + /************************************************************************** + * + * @type: + * FT_Raster + * + * @description: + * An opaque handle (pointer) to a raster object. Each object can be + * used independently to convert an outline into a bitmap or pixmap. + */ typedef struct FT_RasterRec_* FT_Raster; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Span */ - /* */ - /* <Description> */ - /* A structure used to model a single span of gray pixels when */ - /* rendering an anti-aliased bitmap. */ - /* */ - /* <Fields> */ - /* x :: The span's horizontal start position. */ - /* */ - /* len :: The span's length in pixels. */ - /* */ - /* coverage :: The span color/coverage, ranging from 0 (background) */ - /* to 255 (foreground). */ - /* */ - /* <Note> */ - /* This structure is used by the span drawing callback type named */ - /* @FT_SpanFunc that takes the y~coordinate of the span as a */ - /* parameter. */ - /* */ - /* The coverage value is always between 0 and 255. If you want less */ - /* gray values, the callback function has to reduce them. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_Span + * + * @description: + * A structure used to model a single span of gray pixels when rendering + * an anti-aliased bitmap. + * + * @fields: + * x :: + * The span's horizontal start position. + * + * len :: + * The span's length in pixels. + * + * coverage :: + * The span color/coverage, ranging from 0 (background) to 255 + * (foreground). + * + * @note: + * This structure is used by the span drawing callback type named + * @FT_SpanFunc that takes the y~coordinate of the span as a parameter. + * + * The coverage value is always between 0 and 255. If you want less gray + * values, the callback function has to reduce them. + */ typedef struct FT_Span_ { short x; @@ -834,32 +857,36 @@ FT_BEGIN_HEADER } FT_Span; - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_SpanFunc */ - /* */ - /* <Description> */ - /* A function used as a call-back by the anti-aliased renderer in */ - /* order to let client applications draw themselves the gray pixel */ - /* spans on each scan line. */ - /* */ - /* <Input> */ - /* y :: The scanline's y~coordinate. */ - /* */ - /* count :: The number of spans to draw on this scanline. */ - /* */ - /* spans :: A table of `count' spans to draw on the scanline. */ - /* */ - /* user :: User-supplied data that is passed to the callback. */ - /* */ - /* <Note> */ - /* This callback allows client applications to directly render the */ - /* gray spans of the anti-aliased bitmap to any kind of surfaces. */ - /* */ - /* This can be used to write anti-aliased outlines directly to a */ - /* given background bitmap, and even perform translucency. */ - /* */ + /************************************************************************** + * + * @functype: + * FT_SpanFunc + * + * @description: + * A function used as a call-back by the anti-aliased renderer in order + * to let client applications draw themselves the gray pixel spans on + * each scan line. + * + * @input: + * y :: + * The scanline's y~coordinate. + * + * count :: + * The number of spans to draw on this scanline. + * + * spans :: + * A table of `count` spans to draw on the scanline. + * + * user :: + * User-supplied data that is passed to the callback. + * + * @note: + * This callback allows client applications to directly render the gray + * spans of the anti-aliased bitmap to any kind of surfaces. + * + * This can be used to write anti-aliased outlines directly to a given + * background bitmap, and even perform translucency. + */ typedef void (*FT_SpanFunc)( int y, int count, @@ -869,131 +896,131 @@ FT_BEGIN_HEADER #define FT_Raster_Span_Func FT_SpanFunc - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_Raster_BitTest_Func */ - /* */ - /* <Description> */ - /* Deprecated, unimplemented. */ - /* */ + /************************************************************************** + * + * @functype: + * FT_Raster_BitTest_Func + * + * @description: + * Deprecated, unimplemented. + */ typedef int (*FT_Raster_BitTest_Func)( int y, int x, void* user ); - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_Raster_BitSet_Func */ - /* */ - /* <Description> */ - /* Deprecated, unimplemented. */ - /* */ + /************************************************************************** + * + * @functype: + * FT_Raster_BitSet_Func + * + * @description: + * Deprecated, unimplemented. + */ typedef void (*FT_Raster_BitSet_Func)( int y, int x, void* user ); - /*************************************************************************/ - /* */ - /* <Enum> */ - /* FT_RASTER_FLAG_XXX */ - /* */ - /* <Description> */ - /* A list of bit flag constants as used in the `flags' field of a */ - /* @FT_Raster_Params structure. */ - /* */ - /* <Values> */ - /* FT_RASTER_FLAG_DEFAULT :: This value is 0. */ - /* */ - /* FT_RASTER_FLAG_AA :: This flag is set to indicate that an */ - /* anti-aliased glyph image should be */ - /* generated. Otherwise, it will be */ - /* monochrome (1-bit). */ - /* */ - /* FT_RASTER_FLAG_DIRECT :: This flag is set to indicate direct */ - /* rendering. In this mode, client */ - /* applications must provide their own span */ - /* callback. This lets them directly */ - /* draw or compose over an existing bitmap. */ - /* If this bit is not set, the target */ - /* pixmap's buffer _must_ be zeroed before */ - /* rendering. */ - /* */ - /* Direct rendering is only possible with */ - /* anti-aliased glyphs. */ - /* */ - /* FT_RASTER_FLAG_CLIP :: This flag is only used in direct */ - /* rendering mode. If set, the output will */ - /* be clipped to a box specified in the */ - /* `clip_box' field of the */ - /* @FT_Raster_Params structure. */ - /* */ - /* Note that by default, the glyph bitmap */ - /* is clipped to the target pixmap, except */ - /* in direct rendering mode where all spans */ - /* are generated if no clipping box is set. */ - /* */ + /************************************************************************** + * + * @enum: + * FT_RASTER_FLAG_XXX + * + * @description: + * A list of bit flag constants as used in the `flags` field of a + * @FT_Raster_Params structure. + * + * @values: + * FT_RASTER_FLAG_DEFAULT :: + * This value is 0. + * + * FT_RASTER_FLAG_AA :: + * This flag is set to indicate that an anti-aliased glyph image should + * be generated. Otherwise, it will be monochrome (1-bit). + * + * FT_RASTER_FLAG_DIRECT :: + * This flag is set to indicate direct rendering. In this mode, client + * applications must provide their own span callback. This lets them + * directly draw or compose over an existing bitmap. If this bit is + * not set, the target pixmap's buffer _must_ be zeroed before + * rendering. + * + * Direct rendering is only possible with anti-aliased glyphs. + * + * FT_RASTER_FLAG_CLIP :: + * This flag is only used in direct rendering mode. If set, the output + * will be clipped to a box specified in the `clip_box` field of the + * @FT_Raster_Params structure. + * + * Note that by default, the glyph bitmap is clipped to the target + * pixmap, except in direct rendering mode where all spans are + * generated if no clipping box is set. + */ #define FT_RASTER_FLAG_DEFAULT 0x0 #define FT_RASTER_FLAG_AA 0x1 #define FT_RASTER_FLAG_DIRECT 0x2 #define FT_RASTER_FLAG_CLIP 0x4 /* these constants are deprecated; use the corresponding */ - /* `FT_RASTER_FLAG_XXX' values instead */ + /* `FT_RASTER_FLAG_XXX` values instead */ #define ft_raster_flag_default FT_RASTER_FLAG_DEFAULT #define ft_raster_flag_aa FT_RASTER_FLAG_AA #define ft_raster_flag_direct FT_RASTER_FLAG_DIRECT #define ft_raster_flag_clip FT_RASTER_FLAG_CLIP - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Raster_Params */ - /* */ - /* <Description> */ - /* A structure to hold the arguments used by a raster's render */ - /* function. */ - /* */ - /* <Fields> */ - /* target :: The target bitmap. */ - /* */ - /* source :: A pointer to the source glyph image (e.g., an */ - /* @FT_Outline). */ - /* */ - /* flags :: The rendering flags. */ - /* */ - /* gray_spans :: The gray span drawing callback. */ - /* */ - /* black_spans :: Unused. */ - /* */ - /* bit_test :: Unused. */ - /* */ - /* bit_set :: Unused. */ - /* */ - /* user :: User-supplied data that is passed to each drawing */ - /* callback. */ - /* */ - /* clip_box :: An optional clipping box. It is only used in */ - /* direct rendering mode. Note that coordinates here */ - /* should be expressed in _integer_ pixels (and not in */ - /* 26.6 fixed-point units). */ - /* */ - /* <Note> */ - /* An anti-aliased glyph bitmap is drawn if the @FT_RASTER_FLAG_AA */ - /* bit flag is set in the `flags' field, otherwise a monochrome */ - /* bitmap is generated. */ - /* */ - /* If the @FT_RASTER_FLAG_DIRECT bit flag is set in `flags', the */ - /* raster will call the `gray_spans' callback to draw gray pixel */ - /* spans. This allows direct composition over a pre-existing bitmap */ - /* through user-provided callbacks to perform the span drawing and */ - /* composition. Not supported by the monochrome rasterizer. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_Raster_Params + * + * @description: + * A structure to hold the arguments used by a raster's render function. + * + * @fields: + * target :: + * The target bitmap. + * + * source :: + * A pointer to the source glyph image (e.g., an @FT_Outline). + * + * flags :: + * The rendering flags. + * + * gray_spans :: + * The gray span drawing callback. + * + * black_spans :: + * Unused. + * + * bit_test :: + * Unused. + * + * bit_set :: + * Unused. + * + * user :: + * User-supplied data that is passed to each drawing callback. + * + * clip_box :: + * An optional clipping box. It is only used in direct rendering mode. + * Note that coordinates here should be expressed in _integer_ pixels + * (and not in 26.6 fixed-point units). + * + * @note: + * An anti-aliased glyph bitmap is drawn if the @FT_RASTER_FLAG_AA bit + * flag is set in the `flags` field, otherwise a monochrome bitmap is + * generated. + * + * If the @FT_RASTER_FLAG_DIRECT bit flag is set in `flags`, the raster + * will call the `gray_spans` callback to draw gray pixel spans. This + * allows direct composition over a pre-existing bitmap through + * user-provided callbacks to perform the span drawing and composition. + * Not supported by the monochrome rasterizer. + */ typedef struct FT_Raster_Params_ { const FT_Bitmap* target; @@ -1009,30 +1036,32 @@ FT_BEGIN_HEADER } FT_Raster_Params; - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_Raster_NewFunc */ - /* */ - /* <Description> */ - /* A function used to create a new raster object. */ - /* */ - /* <Input> */ - /* memory :: A handle to the memory allocator. */ - /* */ - /* <Output> */ - /* raster :: A handle to the new raster object. */ - /* */ - /* <Return> */ - /* Error code. 0~means success. */ - /* */ - /* <Note> */ - /* The `memory' parameter is a typeless pointer in order to avoid */ - /* un-wanted dependencies on the rest of the FreeType code. In */ - /* practice, it is an @FT_Memory object, i.e., a handle to the */ - /* standard FreeType memory allocator. However, this field can be */ - /* completely ignored by a given raster implementation. */ - /* */ + /************************************************************************** + * + * @functype: + * FT_Raster_NewFunc + * + * @description: + * A function used to create a new raster object. + * + * @input: + * memory :: + * A handle to the memory allocator. + * + * @output: + * raster :: + * A handle to the new raster object. + * + * @return: + * Error code. 0~means success. + * + * @note: + * The `memory` parameter is a typeless pointer in order to avoid + * un-wanted dependencies on the rest of the FreeType code. In practice, + * it is an @FT_Memory object, i.e., a handle to the standard FreeType + * memory allocator. However, this field can be completely ignored by a + * given raster implementation. + */ typedef int (*FT_Raster_NewFunc)( void* memory, FT_Raster* raster ); @@ -1040,49 +1069,52 @@ FT_BEGIN_HEADER #define FT_Raster_New_Func FT_Raster_NewFunc - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_Raster_DoneFunc */ - /* */ - /* <Description> */ - /* A function used to destroy a given raster object. */ - /* */ - /* <Input> */ - /* raster :: A handle to the raster object. */ - /* */ + /************************************************************************** + * + * @functype: + * FT_Raster_DoneFunc + * + * @description: + * A function used to destroy a given raster object. + * + * @input: + * raster :: + * A handle to the raster object. + */ typedef void (*FT_Raster_DoneFunc)( FT_Raster raster ); #define FT_Raster_Done_Func FT_Raster_DoneFunc - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_Raster_ResetFunc */ - /* */ - /* <Description> */ - /* FreeType used to provide an area of memory called the `render */ - /* pool' available to all registered rasterizers. This was not */ - /* thread safe, however, and now FreeType never allocates this pool. */ - /* */ - /* This function is called after a new raster object is created. */ - /* */ - /* <Input> */ - /* raster :: A handle to the new raster object. */ - /* */ - /* pool_base :: Previously, the address in memory of the render pool. */ - /* Set this to NULL. */ - /* */ - /* pool_size :: Previously, the size in bytes of the render pool. */ - /* Set this to 0. */ - /* */ - /* <Note> */ - /* Rasterizers should rely on dynamic or stack allocation if they */ - /* want to (a handle to the memory allocator is passed to the */ - /* rasterizer constructor). */ - /* */ + /************************************************************************** + * + * @functype: + * FT_Raster_ResetFunc + * + * @description: + * FreeType used to provide an area of memory called the 'render pool' + * available to all registered rasterizers. This was not thread safe, + * however, and now FreeType never allocates this pool. + * + * This function is called after a new raster object is created. + * + * @input: + * raster :: + * A handle to the new raster object. + * + * pool_base :: + * Previously, the address in memory of the render pool. Set this to + * `NULL`. + * + * pool_size :: + * Previously, the size in bytes of the render pool. Set this to 0. + * + * @note: + * Rasterizers should rely on dynamic or stack allocation if they want to + * (a handle to the memory allocator is passed to the rasterizer + * constructor). + */ typedef void (*FT_Raster_ResetFunc)( FT_Raster raster, unsigned char* pool_base, @@ -1091,24 +1123,26 @@ FT_BEGIN_HEADER #define FT_Raster_Reset_Func FT_Raster_ResetFunc - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_Raster_SetModeFunc */ - /* */ - /* <Description> */ - /* This function is a generic facility to change modes or attributes */ - /* in a given raster. This can be used for debugging purposes, or */ - /* simply to allow implementation-specific `features' in a given */ - /* raster module. */ - /* */ - /* <Input> */ - /* raster :: A handle to the new raster object. */ - /* */ - /* mode :: A 4-byte tag used to name the mode or property. */ - /* */ - /* args :: A pointer to the new mode/property to use. */ - /* */ + /************************************************************************** + * + * @functype: + * FT_Raster_SetModeFunc + * + * @description: + * This function is a generic facility to change modes or attributes in a + * given raster. This can be used for debugging purposes, or simply to + * allow implementation-specific 'features' in a given raster module. + * + * @input: + * raster :: + * A handle to the new raster object. + * + * mode :: + * A 4-byte tag used to name the mode or property. + * + * args :: + * A pointer to the new mode/property to use. + */ typedef int (*FT_Raster_SetModeFunc)( FT_Raster raster, unsigned long mode, @@ -1117,40 +1151,36 @@ FT_BEGIN_HEADER #define FT_Raster_Set_Mode_Func FT_Raster_SetModeFunc - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_Raster_RenderFunc */ - /* */ - /* <Description> */ - /* Invoke a given raster to scan-convert a given glyph image into a */ - /* target bitmap. */ - /* */ - /* <Input> */ - /* raster :: A handle to the raster object. */ - /* */ - /* params :: A pointer to an @FT_Raster_Params structure used to */ - /* store the rendering parameters. */ - /* */ - /* <Return> */ - /* Error code. 0~means success. */ - /* */ - /* <Note> */ - /* The exact format of the source image depends on the raster's glyph */ - /* format defined in its @FT_Raster_Funcs structure. It can be an */ - /* @FT_Outline or anything else in order to support a large array of */ - /* glyph formats. */ - /* */ - /* Note also that the render function can fail and return a */ - /* `FT_Err_Unimplemented_Feature' error code if the raster used does */ - /* not support direct composition. */ - /* */ - /* XXX: For now, the standard raster doesn't support direct */ - /* composition but this should change for the final release (see */ - /* the files `demos/src/ftgrays.c' and `demos/src/ftgrays2.c' */ - /* for examples of distinct implementations that support direct */ - /* composition). */ - /* */ + /************************************************************************** + * + * @functype: + * FT_Raster_RenderFunc + * + * @description: + * Invoke a given raster to scan-convert a given glyph image into a + * target bitmap. + * + * @input: + * raster :: + * A handle to the raster object. + * + * params :: + * A pointer to an @FT_Raster_Params structure used to store the + * rendering parameters. + * + * @return: + * Error code. 0~means success. + * + * @note: + * The exact format of the source image depends on the raster's glyph + * format defined in its @FT_Raster_Funcs structure. It can be an + * @FT_Outline or anything else in order to support a large array of + * glyph formats. + * + * Note also that the render function can fail and return a + * `FT_Err_Unimplemented_Feature` error code if the raster used does not + * support direct composition. + */ typedef int (*FT_Raster_RenderFunc)( FT_Raster raster, const FT_Raster_Params* params ); @@ -1158,25 +1188,30 @@ FT_BEGIN_HEADER #define FT_Raster_Render_Func FT_Raster_RenderFunc - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Raster_Funcs */ - /* */ - /* <Description> */ - /* A structure used to describe a given raster class to the library. */ - /* */ - /* <Fields> */ - /* glyph_format :: The supported glyph format for this raster. */ - /* */ - /* raster_new :: The raster constructor. */ - /* */ - /* raster_reset :: Used to reset the render pool within the raster. */ - /* */ - /* raster_render :: A function to render a glyph into a given bitmap. */ - /* */ - /* raster_done :: The raster destructor. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_Raster_Funcs + * + * @description: + * A structure used to describe a given raster class to the library. + * + * @fields: + * glyph_format :: + * The supported glyph format for this raster. + * + * raster_new :: + * The raster constructor. + * + * raster_reset :: + * Used to reset the render pool within the raster. + * + * raster_render :: + * A function to render a glyph into a given bitmap. + * + * raster_done :: + * The raster destructor. + */ typedef struct FT_Raster_Funcs_ { FT_Glyph_Format glyph_format; diff --git a/sdk/lib/3rdparty/freetype/include/freetype/ftincrem.h b/sdk/lib/3rdparty/freetype/include/freetype/ftincrem.h index 44619f941e7a2..a4db02b585b2c 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/ftincrem.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/ftincrem.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftincrem.h */ -/* */ -/* FreeType incremental loading (specification). */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftincrem.h + * + * FreeType incremental loading (specification). + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTINCREM_H_ @@ -32,7 +32,7 @@ FT_BEGIN_HEADER - /*************************************************************************** + /************************************************************************** * * @section: * incremental @@ -45,7 +45,7 @@ FT_BEGIN_HEADER * * @description: * This section contains various functions used to perform so-called - * `incremental' glyph loading. This is a mode where all glyphs loaded + * 'incremental' glyph loading. This is a mode where all glyphs loaded * from a given @FT_Face are provided by the client application. * * Apart from that, all other tables are loaded normally from the font @@ -60,23 +60,24 @@ FT_BEGIN_HEADER */ - /*************************************************************************** + /************************************************************************** * * @type: * FT_Incremental * * @description: * An opaque type describing a user-provided object used to implement - * `incremental' glyph loading within FreeType. This is used to support - * embedded fonts in certain environments (e.g., PostScript interpreters), - * where the glyph data isn't in the font file, or must be overridden by - * different values. + * 'incremental' glyph loading within FreeType. This is used to support + * embedded fonts in certain environments (e.g., PostScript + * interpreters), where the glyph data isn't in the font file, or must be + * overridden by different values. * * @note: - * It is up to client applications to create and implement @FT_Incremental - * objects, as long as they provide implementations for the methods - * @FT_Incremental_GetGlyphDataFunc, @FT_Incremental_FreeGlyphDataFunc - * and @FT_Incremental_GetGlyphMetricsFunc. + * It is up to client applications to create and implement + * @FT_Incremental objects, as long as they provide implementations for + * the methods @FT_Incremental_GetGlyphDataFunc, + * @FT_Incremental_FreeGlyphDataFunc and + * @FT_Incremental_GetGlyphMetricsFunc. * * See the description of @FT_Incremental_InterfaceRec to understand how * to use incremental objects with FreeType. @@ -85,14 +86,14 @@ FT_BEGIN_HEADER typedef struct FT_IncrementalRec_* FT_Incremental; - /*************************************************************************** + /************************************************************************** * * @struct: * FT_Incremental_MetricsRec * * @description: - * A small structure used to contain the basic glyph metrics returned - * by the @FT_Incremental_GetGlyphMetricsFunc method. + * A small structure used to contain the basic glyph metrics returned by + * the @FT_Incremental_GetGlyphMetricsFunc method. * * @fields: * bearing_x :: @@ -109,7 +110,7 @@ FT_BEGIN_HEADER * * @note: * These correspond to horizontal or vertical metrics depending on the - * value of the `vertical' argument to the function + * value of the `vertical` argument to the function * @FT_Incremental_GetGlyphMetricsFunc. * */ @@ -123,7 +124,7 @@ FT_BEGIN_HEADER } FT_Incremental_MetricsRec; - /*************************************************************************** + /************************************************************************** * * @struct: * FT_Incremental_Metrics @@ -135,7 +136,7 @@ FT_BEGIN_HEADER typedef struct FT_Incremental_MetricsRec_* FT_Incremental_Metrics; - /*************************************************************************** + /************************************************************************** * * @type: * FT_Incremental_GetGlyphDataFunc @@ -147,8 +148,8 @@ FT_BEGIN_HEADER * * Note that the format of the glyph's data bytes depends on the font * file format. For TrueType, it must correspond to the raw bytes within - * the `glyf' table. For PostScript formats, it must correspond to the - * *unencrypted* charstring bytes, without any `lenIV' header. It is + * the 'glyf' table. For PostScript formats, it must correspond to the + * **unencrypted** charstring bytes, without any `lenIV` header. It is * undefined for any other format. * * @input: @@ -169,8 +170,8 @@ FT_BEGIN_HEADER * * @note: * If this function returns successfully the method - * @FT_Incremental_FreeGlyphDataFunc will be called later to release - * the data bytes. + * @FT_Incremental_FreeGlyphDataFunc will be called later to release the + * data bytes. * * Nested calls to @FT_Incremental_GetGlyphDataFunc can happen for * compound glyphs. @@ -182,7 +183,7 @@ FT_BEGIN_HEADER FT_Data* adata ); - /*************************************************************************** + /************************************************************************** * * @type: * FT_Incremental_FreeGlyphDataFunc @@ -206,7 +207,7 @@ FT_BEGIN_HEADER FT_Data* data ); - /*************************************************************************** + /************************************************************************** * * @type: * FT_Incremental_GetGlyphMetricsFunc @@ -214,8 +215,8 @@ FT_BEGIN_HEADER * @description: * A function used to retrieve the basic metrics of a given glyph index * before accessing its data. This is necessary because, in certain - * formats like TrueType, the metrics are stored in a different place from - * the glyph images proper. + * formats like TrueType, the metrics are stored in a different place + * from the glyph images proper. * * @input: * incremental :: @@ -229,9 +230,9 @@ FT_BEGIN_HEADER * If true, return vertical metrics. * * ametrics :: - * This parameter is used for both input and output. - * The original glyph metrics, if any, in font units. If metrics are - * not available all the values must be set to zero. + * This parameter is used for both input and output. The original + * glyph metrics, if any, in font units. If metrics are not available + * all the values must be set to zero. * * @output: * ametrics :: @@ -252,8 +253,8 @@ FT_BEGIN_HEADER * FT_Incremental_FuncsRec * * @description: - * A table of functions for accessing fonts that load data - * incrementally. Used in @FT_Incremental_InterfaceRec. + * A table of functions for accessing fonts that load data incrementally. + * Used in @FT_Incremental_InterfaceRec. * * @fields: * get_glyph_data :: @@ -263,8 +264,8 @@ FT_BEGIN_HEADER * The function to release glyph data. Must not be null. * * get_glyph_metrics :: - * The function to get glyph metrics. May be null if the font does - * not provide overriding glyph metrics. + * The function to get glyph metrics. May be null if the font does not + * provide overriding glyph metrics. * */ typedef struct FT_Incremental_FuncsRec_ @@ -276,7 +277,7 @@ FT_BEGIN_HEADER } FT_Incremental_FuncsRec; - /*************************************************************************** + /************************************************************************** * * @struct: * FT_Incremental_InterfaceRec @@ -286,30 +287,30 @@ FT_BEGIN_HEADER * wants to support incremental glyph loading. You should use it with * @FT_PARAM_TAG_INCREMENTAL as in the following example: * - * { - * FT_Incremental_InterfaceRec inc_int; - * FT_Parameter parameter; - * FT_Open_Args open_args; + * ``` + * FT_Incremental_InterfaceRec inc_int; + * FT_Parameter parameter; + * FT_Open_Args open_args; * * - * // set up incremental descriptor - * inc_int.funcs = my_funcs; - * inc_int.object = my_object; + * // set up incremental descriptor + * inc_int.funcs = my_funcs; + * inc_int.object = my_object; * - * // set up optional parameter - * parameter.tag = FT_PARAM_TAG_INCREMENTAL; - * parameter.data = &inc_int; + * // set up optional parameter + * parameter.tag = FT_PARAM_TAG_INCREMENTAL; + * parameter.data = &inc_int; * - * // set up FT_Open_Args structure - * open_args.flags = FT_OPEN_PATHNAME | FT_OPEN_PARAMS; - * open_args.pathname = my_font_pathname; - * open_args.num_params = 1; - * open_args.params = ¶meter; // we use one optional argument + * // set up FT_Open_Args structure + * open_args.flags = FT_OPEN_PATHNAME | FT_OPEN_PARAMS; + * open_args.pathname = my_font_pathname; + * open_args.num_params = 1; + * open_args.params = ¶meter; // we use one optional argument * - * // open the font - * error = FT_Open_Face( library, &open_args, index, &face ); - * ... - * } + * // open the font + * error = FT_Open_Face( library, &open_args, index, &face ); + * ... + * ``` * */ typedef struct FT_Incremental_InterfaceRec_ @@ -320,7 +321,7 @@ FT_BEGIN_HEADER } FT_Incremental_InterfaceRec; - /*************************************************************************** + /************************************************************************** * * @type: * FT_Incremental_Interface diff --git a/sdk/lib/3rdparty/freetype/include/freetype/ftlcdfil.h b/sdk/lib/3rdparty/freetype/include/freetype/ftlcdfil.h index 2a27196cbb840..3a19d043bbefe 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/ftlcdfil.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/ftlcdfil.h @@ -1,20 +1,20 @@ -/***************************************************************************/ -/* */ -/* ftlcdfil.h */ -/* */ -/* FreeType API for color filtering of subpixel bitmap glyphs */ -/* (specification). */ -/* */ -/* Copyright 2006-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftlcdfil.h + * + * FreeType API for color filtering of subpixel bitmap glyphs + * (specification). + * + * Copyright (C) 2006-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTLCDFIL_H_ @@ -33,105 +33,98 @@ FT_BEGIN_HEADER - /*************************************************************************** + /************************************************************************** * * @section: - * lcd_filtering + * lcd_rendering * * @title: - * LCD Filtering + * Subpixel Rendering * * @abstract: - * Reduce color fringes of subpixel-rendered bitmaps. + * API to control subpixel rendering. * * @description: - * Should you #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING in your - * `ftoption.h', which enables patented ClearType-style rendering, - * the LCD-optimized glyph bitmaps should be filtered to reduce color - * fringes inherent to this technology. The default FreeType LCD - * rendering uses different technology, and API described below, - * although available, does nothing. + * FreeType provides two alternative subpixel rendering technologies. + * Should you define `FT_CONFIG_OPTION_SUBPIXEL_RENDERING` in your + * `ftoption.h` file, this enables patented ClearType-style rendering. + * Otherwise, Harmony LCD rendering is enabled. These technologies are + * controlled differently and API described below, although always + * available, performs its function when appropriate method is enabled + * and does nothing otherwise. * * ClearType-style LCD rendering exploits the color-striped structure of * LCD pixels, increasing the available resolution in the direction of - * the stripe (usually horizontal RGB) by a factor of~3. Since these - * subpixels are color pixels, using them unfiltered creates severe - * color fringes. Use the @FT_Library_SetLcdFilter API to specify a - * low-pass filter, which is then applied to subpixel-rendered bitmaps - * generated through @FT_Render_Glyph. The filter sacrifices some of - * the higher resolution to reduce color fringes, making the glyph image - * slightly blurrier. Positional improvements will remain. - * - * A filter should have two properties: - * - * 1) It should be normalized, meaning the sum of the 5~components - * should be 256 (0x100). It is possible to go above or under this - * target sum, however: going under means tossing out contrast, going - * over means invoking clamping and thereby non-linearities that - * increase contrast somewhat at the expense of greater distortion - * and color-fringing. Contrast is better enhanced through stem - * darkening. - * - * 2) It should be color-balanced, meaning a filter `{~a, b, c, b, a~}' - * where a~+ b~=~c. It distributes the computed coverage for one - * subpixel to all subpixels equally, sacrificing some won resolution - * but drastically reducing color-fringing. Positioning improvements - * remain! Note that color-fringing can only really be minimized - * when using a color-balanced filter and alpha-blending the glyph - * onto a surface in linear space; see @FT_Render_Glyph. - * - * Regarding the form, a filter can be a `boxy' filter or a `beveled' - * filter. Boxy filters are sharper but are less forgiving of non-ideal - * gamma curves of a screen (viewing angles!), beveled filters are - * fuzzier but more tolerant. - * - * Examples: - * - * - [0x10 0x40 0x70 0x40 0x10] is beveled and neither balanced nor - * normalized. - * - * - [0x1A 0x33 0x4D 0x33 0x1A] is beveled and balanced but not - * normalized. - * - * - [0x19 0x33 0x66 0x4c 0x19] is beveled and normalized but not - * balanced. - * - * - [0x00 0x4c 0x66 0x4c 0x00] is boxily beveled and normalized but not - * balanced. - * - * - [0x00 0x55 0x56 0x55 0x00] is boxy, normalized, and almost - * balanced. - * - * - [0x08 0x4D 0x56 0x4D 0x08] is beveled, normalized and, almost - * balanced. - * - * The filter affects glyph bitmaps rendered through @FT_Render_Glyph, - * @FT_Load_Glyph, and @FT_Load_Char. It does _not_ affect the output - * of @FT_Outline_Render and @FT_Outline_Get_Bitmap. - * - * If this feature is activated, the dimensions of LCD glyph bitmaps are - * either wider or taller than the dimensions of the corresponding - * outline with regard to the pixel grid. For example, for - * @FT_RENDER_MODE_LCD, the filter adds 3~subpixels to the left, and - * 3~subpixels to the right. The bitmap offset values are adjusted - * accordingly, so clients shouldn't need to modify their layout and - * glyph positioning code when enabling the filter. - * - * It is important to understand that linear alpha blending and gamma - * correction is critical for correctly rendering glyphs onto surfaces - * without artifacts and even more critical when subpixel rendering is - * involved. - * - * Each of the 3~alpha values (subpixels) is independently used to blend - * one color channel. That is, red alpha blends the red channel of the - * text color with the red channel of the background pixel. The - * distribution of density values by the color-balanced filter assumes - * alpha blending is done in linear space; only then color artifacts - * cancel out. + * the stripe (usually horizontal RGB) by a factor of~3. Using the + * subpixels coverages unfiltered can create severe color fringes + * especially when rendering thin features. Indeed, to produce + * black-on-white text, the nearby color subpixels must be dimmed + * equally. + * + * A good 5-tap FIR filter should be applied to subpixel coverages + * regardless of pixel boundaries and should have these properties: + * + * 1. It should be symmetrical, like {~a, b, c, b, a~}, to avoid + * any shifts in appearance. + * + * 2. It should be color-balanced, meaning a~+ b~=~c, to reduce color + * fringes by distributing the computed coverage for one subpixel to + * all subpixels equally. + * + * 3. It should be normalized, meaning 2a~+ 2b~+ c~=~1.0 to maintain + * overall brightness. + * + * Boxy 3-tap filter {0, 1/3, 1/3, 1/3, 0} is sharper but is less + * forgiving of non-ideal gamma curves of a screen (and viewing angles), + * beveled filters are fuzzier but more tolerant. + * + * Use the @FT_Library_SetLcdFilter or @FT_Library_SetLcdFilterWeights + * API to specify a low-pass filter, which is then applied to + * subpixel-rendered bitmaps generated through @FT_Render_Glyph. + * + * Harmony LCD rendering is suitable to panels with any regular subpixel + * structure, not just monitors with 3 color striped subpixels, as long + * as the color subpixels have fixed positions relative to the pixel + * center. In this case, each color channel is then rendered separately + * after shifting the outline opposite to the subpixel shift so that the + * coverage maps are aligned. This method is immune to color fringes + * because the shifts do not change integral coverage. + * + * The subpixel geometry must be specified by xy-coordinates for each + * subpixel. By convention they may come in the RGB order: {{-1/3, 0}, + * {0, 0}, {1/3, 0}} for standard RGB striped panel or {{-1/6, 1/4}, + * {-1/6, -1/4}, {1/3, 0}} for a certain PenTile panel. + * + * Use the @FT_Library_SetLcdGeometry API to specify subpixel positions. + * If one follows the RGB order convention, the same order applies to the + * resulting @FT_PIXEL_MODE_LCD and @FT_PIXEL_MODE_LCD_V bitmaps. Note, + * however, that the coordinate frame for the latter must be rotated + * clockwise. Harmony with default LCD geometry is equivalent to + * ClearType with light filter. + * + * As a result of ClearType filtering or Harmony rendering, the + * dimensions of LCD bitmaps can be either wider or taller than the + * dimensions of the corresponding outline with regard to the pixel grid. + * For example, for @FT_RENDER_MODE_LCD, the filter adds 2~subpixels to + * the left, and 2~subpixels to the right. The bitmap offset values are + * adjusted accordingly, so clients shouldn't need to modify their layout + * and glyph positioning code when enabling the filter. + * + * The ClearType and Harmony rendering is applicable to glyph bitmaps + * rendered through @FT_Render_Glyph, @FT_Load_Glyph, @FT_Load_Char, and + * @FT_Glyph_To_Bitmap, when @FT_RENDER_MODE_LCD or @FT_RENDER_MODE_LCD_V + * is specified. This API does not control @FT_Outline_Render and + * @FT_Outline_Get_Bitmap. + * + * The described algorithms can completely remove color artefacts when + * combined with gamma-corrected alpha blending in linear space. Each of + * the 3~alpha values (subpixels) must by independently used to blend one + * color channel. That is, red alpha blends the red channel of the text + * color with the red channel of the background pixel. */ - /**************************************************************************** + /************************************************************************** * * @enum: * FT_LcdFilter @@ -145,47 +138,25 @@ FT_BEGIN_HEADER * results in sometimes severe color fringes. * * FT_LCD_FILTER_DEFAULT :: - * The default filter reduces color fringes considerably, at the cost - * of a slight blurriness in the output. - * - * It is a beveled, normalized, and color-balanced five-tap filter - * that is more forgiving to screens with non-ideal gamma curves and - * viewing angles. Note that while color-fringing is reduced, it can - * only be minimized by using linear alpha blending and gamma - * correction to render glyphs onto surfaces. The default filter - * weights are [0x08 0x4D 0x56 0x4D 0x08]. + * This is a beveled, normalized, and color-balanced five-tap filter + * with weights of [0x08 0x4D 0x56 0x4D 0x08] in 1/256th units. * * FT_LCD_FILTER_LIGHT :: - * The light filter is a variant that is sharper at the cost of - * slightly more color fringes than the default one. - * - * It is a boxy, normalized, and color-balanced three-tap filter that - * is less forgiving to screens with non-ideal gamma curves and - * viewing angles. This filter works best when the rendering system - * uses linear alpha blending and gamma correction to render glyphs - * onto surfaces. The light filter weights are - * [0x00 0x55 0x56 0x55 0x00]. + * this is a boxy, normalized, and color-balanced three-tap filter with + * weights of [0x00 0x55 0x56 0x55 0x00] in 1/256th units. * * FT_LCD_FILTER_LEGACY :: + * FT_LCD_FILTER_LEGACY1 :: * This filter corresponds to the original libXft color filter. It * provides high contrast output but can exhibit really bad color * fringes if glyphs are not extremely well hinted to the pixel grid. - * In other words, it only works well if the TrueType bytecode - * interpreter is enabled *and* high-quality hinted fonts are used. - * * This filter is only provided for comparison purposes, and might be - * disabled or stay unsupported in the future. - * - * FT_LCD_FILTER_LEGACY1 :: - * For historical reasons, the FontConfig library returns a different - * enumeration value for legacy LCD filtering. To make code work that - * (incorrectly) forwards FontConfig's enumeration value to - * @FT_Library_SetLcdFilter without proper mapping, it is thus easiest - * to have another enumeration value, which is completely equal to - * `FT_LCD_FILTER_LEGACY'. + * disabled or stay unsupported in the future. The second value is + * provided for compatibility with FontConfig, which historically used + * different enumeration, sometimes incorrectly forwarded to FreeType. * * @since: - * 2.3.0 (`FT_LCD_FILTER_LEGACY1' since 2.6.2) + * 2.3.0 (`FT_LCD_FILTER_LEGACY1` since 2.6.2) */ typedef enum FT_LcdFilter_ { @@ -202,7 +173,7 @@ FT_BEGIN_HEADER /************************************************************************** * - * @func: + * @function: * FT_Library_SetLcdFilter * * @description: @@ -218,20 +189,20 @@ FT_BEGIN_HEADER * The filter type. * * You can use @FT_LCD_FILTER_NONE here to disable this feature, or - * @FT_LCD_FILTER_DEFAULT to use a default filter that should work - * well on most LCD screens. + * @FT_LCD_FILTER_DEFAULT to use a default filter that should work well + * on most LCD screens. * * @return: * FreeType error code. 0~means success. * * @note: * This feature is always disabled by default. Clients must make an - * explicit call to this function with a `filter' value other than + * explicit call to this function with a `filter` value other than * @FT_LCD_FILTER_NONE in order to enable it. * - * Due to *PATENTS* covering subpixel rendering, this function doesn't - * do anything except returning `FT_Err_Unimplemented_Feature' if the - * configuration macro FT_CONFIG_OPTION_SUBPIXEL_RENDERING is not + * Due to **PATENTS** covering subpixel rendering, this function doesn't + * do anything except returning `FT_Err_Unimplemented_Feature` if the + * configuration macro `FT_CONFIG_OPTION_SUBPIXEL_RENDERING` is not * defined in your build of the library, which should correspond to all * default builds of FreeType. * @@ -245,7 +216,7 @@ FT_BEGIN_HEADER /************************************************************************** * - * @func: + * @function: * FT_Library_SetLcdFilterWeights * * @description: @@ -258,15 +229,15 @@ FT_BEGIN_HEADER * * weights :: * A pointer to an array; the function copies the first five bytes and - * uses them to specify the filter weights. + * uses them to specify the filter weights in 1/256th units. * * @return: * FreeType error code. 0~means success. * * @note: - * Due to *PATENTS* covering subpixel rendering, this function doesn't - * do anything except returning `FT_Err_Unimplemented_Feature' if the - * configuration macro FT_CONFIG_OPTION_SUBPIXEL_RENDERING is not + * Due to **PATENTS** covering subpixel rendering, this function doesn't + * do anything except returning `FT_Err_Unimplemented_Feature` if the + * configuration macro `FT_CONFIG_OPTION_SUBPIXEL_RENDERING` is not * defined in your build of the library, which should correspond to all * default builds of FreeType. * @@ -281,7 +252,8 @@ FT_BEGIN_HEADER unsigned char *weights ); - /* + /************************************************************************** + * * @type: * FT_LcdFiveTapFilter * @@ -298,6 +270,53 @@ FT_BEGIN_HEADER typedef FT_Byte FT_LcdFiveTapFilter[FT_LCD_FILTER_FIVE_TAPS]; + /************************************************************************** + * + * @function: + * FT_Library_SetLcdGeometry + * + * @description: + * This function can be used to modify default positions of color + * subpixels, which controls Harmony LCD rendering. + * + * @input: + * library :: + * A handle to the target library instance. + * + * sub :: + * A pointer to an array of 3 vectors in 26.6 fractional pixel format; + * the function modifies the default values, see the note below. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * Subpixel geometry examples: + * + * - {{-21, 0}, {0, 0}, {21, 0}} is the default, corresponding to 3 color + * stripes shifted by a third of a pixel. This could be an RGB panel. + * + * - {{21, 0}, {0, 0}, {-21, 0}} looks the same as the default but can + * specify a BGR panel instead, while keeping the bitmap in the same + * RGB888 format. + * + * - {{0, 21}, {0, 0}, {0, -21}} is the vertical RGB, but the bitmap + * stays RGB888 as a result. + * + * - {{-11, 16}, {-11, -16}, {22, 0}} is a certain PenTile arrangement. + * + * This function does nothing and returns `FT_Err_Unimplemented_Feature` + * in the context of ClearType-style subpixel rendering when + * `FT_CONFIG_OPTION_SUBPIXEL_RENDERING` is defined in your build of the + * library. + * + * @since: + * 2.10.0 + */ + FT_EXPORT( FT_Error ) + FT_Library_SetLcdGeometry( FT_Library library, + FT_Vector sub[3] ); + /* */ diff --git a/sdk/lib/3rdparty/freetype/include/freetype/ftlist.h b/sdk/lib/3rdparty/freetype/include/freetype/ftlist.h index 117473b96a2c9..4782892d1a7bc 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/ftlist.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/ftlist.h @@ -1,27 +1,27 @@ -/***************************************************************************/ -/* */ -/* ftlist.h */ -/* */ -/* Generic list support for FreeType (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file implements functions relative to list processing. Its */ - /* data structures are defined in `freetype.h'. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * ftlist.h + * + * Generic list support for FreeType (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /************************************************************************** + * + * This file implements functions relative to list processing. Its data + * structures are defined in `freetype.h`. + * + */ #ifndef FTLIST_H_ @@ -41,224 +41,245 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* <Section> */ - /* list_processing */ - /* */ - /* <Title> */ - /* List Processing */ - /* */ - /* <Abstract> */ - /* Simple management of lists. */ - /* */ - /* <Description> */ - /* This section contains various definitions related to list */ - /* processing using doubly-linked nodes. */ - /* */ - /* <Order> */ - /* FT_List */ - /* FT_ListNode */ - /* FT_ListRec */ - /* FT_ListNodeRec */ - /* */ - /* FT_List_Add */ - /* FT_List_Insert */ - /* FT_List_Find */ - /* FT_List_Remove */ - /* FT_List_Up */ - /* FT_List_Iterate */ - /* FT_List_Iterator */ - /* FT_List_Finalize */ - /* FT_List_Destructor */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_List_Find */ - /* */ - /* <Description> */ - /* Find the list node for a given listed object. */ - /* */ - /* <Input> */ - /* list :: A pointer to the parent list. */ - /* data :: The address of the listed object. */ - /* */ - /* <Return> */ - /* List node. NULL if it wasn't found. */ - /* */ + /************************************************************************** + * + * @section: + * list_processing + * + * @title: + * List Processing + * + * @abstract: + * Simple management of lists. + * + * @description: + * This section contains various definitions related to list processing + * using doubly-linked nodes. + * + * @order: + * FT_List + * FT_ListNode + * FT_ListRec + * FT_ListNodeRec + * + * FT_List_Add + * FT_List_Insert + * FT_List_Find + * FT_List_Remove + * FT_List_Up + * FT_List_Iterate + * FT_List_Iterator + * FT_List_Finalize + * FT_List_Destructor + * + */ + + + /************************************************************************** + * + * @function: + * FT_List_Find + * + * @description: + * Find the list node for a given listed object. + * + * @input: + * list :: + * A pointer to the parent list. + * data :: + * The address of the listed object. + * + * @return: + * List node. `NULL` if it wasn't found. + */ FT_EXPORT( FT_ListNode ) FT_List_Find( FT_List list, void* data ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_List_Add */ - /* */ - /* <Description> */ - /* Append an element to the end of a list. */ - /* */ - /* <InOut> */ - /* list :: A pointer to the parent list. */ - /* node :: The node to append. */ - /* */ + /************************************************************************** + * + * @function: + * FT_List_Add + * + * @description: + * Append an element to the end of a list. + * + * @inout: + * list :: + * A pointer to the parent list. + * node :: + * The node to append. + */ FT_EXPORT( void ) FT_List_Add( FT_List list, FT_ListNode node ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_List_Insert */ - /* */ - /* <Description> */ - /* Insert an element at the head of a list. */ - /* */ - /* <InOut> */ - /* list :: A pointer to parent list. */ - /* node :: The node to insert. */ - /* */ + /************************************************************************** + * + * @function: + * FT_List_Insert + * + * @description: + * Insert an element at the head of a list. + * + * @inout: + * list :: + * A pointer to parent list. + * node :: + * The node to insert. + */ FT_EXPORT( void ) FT_List_Insert( FT_List list, FT_ListNode node ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_List_Remove */ - /* */ - /* <Description> */ - /* Remove a node from a list. This function doesn't check whether */ - /* the node is in the list! */ - /* */ - /* <Input> */ - /* node :: The node to remove. */ - /* */ - /* <InOut> */ - /* list :: A pointer to the parent list. */ - /* */ + /************************************************************************** + * + * @function: + * FT_List_Remove + * + * @description: + * Remove a node from a list. This function doesn't check whether the + * node is in the list! + * + * @input: + * node :: + * The node to remove. + * + * @inout: + * list :: + * A pointer to the parent list. + */ FT_EXPORT( void ) FT_List_Remove( FT_List list, FT_ListNode node ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_List_Up */ - /* */ - /* <Description> */ - /* Move a node to the head/top of a list. Used to maintain LRU */ - /* lists. */ - /* */ - /* <InOut> */ - /* list :: A pointer to the parent list. */ - /* node :: The node to move. */ - /* */ + /************************************************************************** + * + * @function: + * FT_List_Up + * + * @description: + * Move a node to the head/top of a list. Used to maintain LRU lists. + * + * @inout: + * list :: + * A pointer to the parent list. + * node :: + * The node to move. + */ FT_EXPORT( void ) FT_List_Up( FT_List list, FT_ListNode node ); - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_List_Iterator */ - /* */ - /* <Description> */ - /* An FT_List iterator function that is called during a list parse */ - /* by @FT_List_Iterate. */ - /* */ - /* <Input> */ - /* node :: The current iteration list node. */ - /* */ - /* user :: A typeless pointer passed to @FT_List_Iterate. */ - /* Can be used to point to the iteration's state. */ - /* */ + /************************************************************************** + * + * @functype: + * FT_List_Iterator + * + * @description: + * An FT_List iterator function that is called during a list parse by + * @FT_List_Iterate. + * + * @input: + * node :: + * The current iteration list node. + * + * user :: + * A typeless pointer passed to @FT_List_Iterate. Can be used to point + * to the iteration's state. + */ typedef FT_Error (*FT_List_Iterator)( FT_ListNode node, void* user ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_List_Iterate */ - /* */ - /* <Description> */ - /* Parse a list and calls a given iterator function on each element. */ - /* Note that parsing is stopped as soon as one of the iterator calls */ - /* returns a non-zero value. */ - /* */ - /* <Input> */ - /* list :: A handle to the list. */ - /* iterator :: An iterator function, called on each node of the list. */ - /* user :: A user-supplied field that is passed as the second */ - /* argument to the iterator. */ - /* */ - /* <Return> */ - /* The result (a FreeType error code) of the last iterator call. */ - /* */ + /************************************************************************** + * + * @function: + * FT_List_Iterate + * + * @description: + * Parse a list and calls a given iterator function on each element. + * Note that parsing is stopped as soon as one of the iterator calls + * returns a non-zero value. + * + * @input: + * list :: + * A handle to the list. + * iterator :: + * An iterator function, called on each node of the list. + * user :: + * A user-supplied field that is passed as the second argument to the + * iterator. + * + * @return: + * The result (a FreeType error code) of the last iterator call. + */ FT_EXPORT( FT_Error ) FT_List_Iterate( FT_List list, FT_List_Iterator iterator, void* user ); - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_List_Destructor */ - /* */ - /* <Description> */ - /* An @FT_List iterator function that is called during a list */ - /* finalization by @FT_List_Finalize to destroy all elements in a */ - /* given list. */ - /* */ - /* <Input> */ - /* system :: The current system object. */ - /* */ - /* data :: The current object to destroy. */ - /* */ - /* user :: A typeless pointer passed to @FT_List_Iterate. It can */ - /* be used to point to the iteration's state. */ - /* */ + /************************************************************************** + * + * @functype: + * FT_List_Destructor + * + * @description: + * An @FT_List iterator function that is called during a list + * finalization by @FT_List_Finalize to destroy all elements in a given + * list. + * + * @input: + * system :: + * The current system object. + * + * data :: + * The current object to destroy. + * + * user :: + * A typeless pointer passed to @FT_List_Iterate. It can be used to + * point to the iteration's state. + */ typedef void (*FT_List_Destructor)( FT_Memory memory, void* data, void* user ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_List_Finalize */ - /* */ - /* <Description> */ - /* Destroy all elements in the list as well as the list itself. */ - /* */ - /* <Input> */ - /* list :: A handle to the list. */ - /* */ - /* destroy :: A list destructor that will be applied to each element */ - /* of the list. Set this to NULL if not needed. */ - /* */ - /* memory :: The current memory object that handles deallocation. */ - /* */ - /* user :: A user-supplied field that is passed as the last */ - /* argument to the destructor. */ - /* */ - /* <Note> */ - /* This function expects that all nodes added by @FT_List_Add or */ - /* @FT_List_Insert have been dynamically allocated. */ - /* */ + /************************************************************************** + * + * @function: + * FT_List_Finalize + * + * @description: + * Destroy all elements in the list as well as the list itself. + * + * @input: + * list :: + * A handle to the list. + * + * destroy :: + * A list destructor that will be applied to each element of the list. + * Set this to `NULL` if not needed. + * + * memory :: + * The current memory object that handles deallocation. + * + * user :: + * A user-supplied field that is passed as the last argument to the + * destructor. + * + * @note: + * This function expects that all nodes added by @FT_List_Add or + * @FT_List_Insert have been dynamically allocated. + */ FT_EXPORT( void ) FT_List_Finalize( FT_List list, FT_List_Destructor destroy, diff --git a/sdk/lib/3rdparty/freetype/include/freetype/ftlzw.h b/sdk/lib/3rdparty/freetype/include/freetype/ftlzw.h index 1615912d62a8e..fd22968f5a5d8 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/ftlzw.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/ftlzw.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftlzw.h */ -/* */ -/* LZW-compressed stream support. */ -/* */ -/* Copyright 2004-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftlzw.h + * + * LZW-compressed stream support. + * + * Copyright (C) 2004-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTLZW_H_ @@ -31,59 +31,60 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* <Section> */ - /* lzw */ - /* */ - /* <Title> */ - /* LZW Streams */ - /* */ - /* <Abstract> */ - /* Using LZW-compressed font files. */ - /* */ - /* <Description> */ - /* This section contains the declaration of LZW-specific functions. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * @section: + * lzw + * + * @title: + * LZW Streams + * + * @abstract: + * Using LZW-compressed font files. + * + * @description: + * This section contains the declaration of LZW-specific functions. + * + */ - /************************************************************************ - * - * @function: - * FT_Stream_OpenLZW - * - * @description: - * Open a new stream to parse LZW-compressed font files. This is - * mainly used to support the compressed `*.pcf.Z' fonts that come - * with XFree86. - * - * @input: - * stream :: The target embedding stream. - * - * source :: The source stream. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * The source stream must be opened _before_ calling this function. - * - * Calling the internal function `FT_Stream_Close' on the new stream will - * *not* call `FT_Stream_Close' on the source stream. None of the stream - * objects will be released to the heap. - * - * The stream implementation is very basic and resets the decompression - * process each time seeking backwards is needed within the stream - * - * In certain builds of the library, LZW compression recognition is - * automatically handled when calling @FT_New_Face or @FT_Open_Face. - * This means that if no font driver is capable of handling the raw - * compressed file, the library will try to open a LZW stream from it - * and re-open the face with it. - * - * This function may return `FT_Err_Unimplemented_Feature' if your build - * of FreeType was not compiled with LZW support. - */ + /************************************************************************** + * + * @function: + * FT_Stream_OpenLZW + * + * @description: + * Open a new stream to parse LZW-compressed font files. This is mainly + * used to support the compressed `*.pcf.Z` fonts that come with XFree86. + * + * @input: + * stream :: + * The target embedding stream. + * + * source :: + * The source stream. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The source stream must be opened _before_ calling this function. + * + * Calling the internal function `FT_Stream_Close` on the new stream will + * **not** call `FT_Stream_Close` on the source stream. None of the + * stream objects will be released to the heap. + * + * The stream implementation is very basic and resets the decompression + * process each time seeking backwards is needed within the stream + * + * In certain builds of the library, LZW compression recognition is + * automatically handled when calling @FT_New_Face or @FT_Open_Face. + * This means that if no font driver is capable of handling the raw + * compressed file, the library will try to open a LZW stream from it and + * re-open the face with it. + * + * This function may return `FT_Err_Unimplemented_Feature` if your build + * of FreeType was not compiled with LZW support. + */ FT_EXPORT( FT_Error ) FT_Stream_OpenLZW( FT_Stream stream, FT_Stream source ); diff --git a/sdk/lib/3rdparty/freetype/include/freetype/ftmac.h b/sdk/lib/3rdparty/freetype/include/freetype/ftmac.h index c1e497ca2db47..92b9f3dc0fa16 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/ftmac.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/ftmac.h @@ -1,28 +1,28 @@ -/***************************************************************************/ -/* */ -/* ftmac.h */ -/* */ -/* Additional Mac-specific API. */ -/* */ -/* Copyright 1996-2018 by */ -/* Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftmac.h + * + * Additional Mac-specific API. + * + * Copyright (C) 1996-2019 by + * Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ -/***************************************************************************/ -/* */ -/* NOTE: Include this file after FT_FREETYPE_H and after any */ -/* Mac-specific headers (because this header uses Mac types such as */ -/* Handle, FSSpec, FSRef, etc.) */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * NOTE: Include this file after `FT_FREETYPE_H` and after any + * Mac-specific headers (because this header uses Mac types such as + * 'Handle', 'FSSpec', 'FSRef', etc.) + * + */ #ifndef FTMAC_H_ @@ -47,56 +47,59 @@ FT_BEGIN_HEADER #endif - /*************************************************************************/ - /* */ - /* <Section> */ - /* mac_specific */ - /* */ - /* <Title> */ - /* Mac Specific Interface */ - /* */ - /* <Abstract> */ - /* Only available on the Macintosh. */ - /* */ - /* <Description> */ - /* The following definitions are only available if FreeType is */ - /* compiled on a Macintosh. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * @section: + * mac_specific + * + * @title: + * Mac Specific Interface + * + * @abstract: + * Only available on the Macintosh. + * + * @description: + * The following definitions are only available if FreeType is compiled + * on a Macintosh. + * + */ - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_New_Face_From_FOND */ - /* */ - /* <Description> */ - /* Create a new face object from a FOND resource. */ - /* */ - /* <InOut> */ - /* library :: A handle to the library resource. */ - /* */ - /* <Input> */ - /* fond :: A FOND resource. */ - /* */ - /* face_index :: Only supported for the -1 `sanity check' special */ - /* case. */ - /* */ - /* <Output> */ - /* aface :: A handle to a new face object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Notes> */ - /* This function can be used to create @FT_Face objects from fonts */ - /* that are installed in the system as follows. */ - /* */ - /* { */ - /* fond = GetResource( 'FOND', fontName ); */ - /* error = FT_New_Face_From_FOND( library, fond, 0, &face ); */ - /* } */ - /* */ + /************************************************************************** + * + * @function: + * FT_New_Face_From_FOND + * + * @description: + * Create a new face object from a FOND resource. + * + * @inout: + * library :: + * A handle to the library resource. + * + * @input: + * fond :: + * A FOND resource. + * + * face_index :: + * Only supported for the -1 'sanity check' special case. + * + * @output: + * aface :: + * A handle to a new face object. + * + * @return: + * FreeType error code. 0~means success. + * + * @example: + * This function can be used to create @FT_Face objects from fonts that + * are installed in the system as follows. + * + * ``` + * fond = GetResource( 'FOND', fontName ); + * error = FT_New_Face_From_FOND( library, fond, 0, &face ); + * ``` + */ FT_EXPORT( FT_Error ) FT_New_Face_From_FOND( FT_Library library, Handle fond, @@ -105,28 +108,28 @@ FT_BEGIN_HEADER FT_DEPRECATED_ATTRIBUTE; - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_GetFile_From_Mac_Name */ - /* */ - /* <Description> */ - /* Return an FSSpec for the disk file containing the named font. */ - /* */ - /* <Input> */ - /* fontName :: Mac OS name of the font (e.g., Times New Roman */ - /* Bold). */ - /* */ - /* <Output> */ - /* pathSpec :: FSSpec to the file. For passing to */ - /* @FT_New_Face_From_FSSpec. */ - /* */ - /* face_index :: Index of the face. For passing to */ - /* @FT_New_Face_From_FSSpec. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ + /************************************************************************** + * + * @function: + * FT_GetFile_From_Mac_Name + * + * @description: + * Return an FSSpec for the disk file containing the named font. + * + * @input: + * fontName :: + * Mac OS name of the font (e.g., Times New Roman Bold). + * + * @output: + * pathSpec :: + * FSSpec to the file. For passing to @FT_New_Face_From_FSSpec. + * + * face_index :: + * Index of the face. For passing to @FT_New_Face_From_FSSpec. + * + * @return: + * FreeType error code. 0~means success. + */ FT_EXPORT( FT_Error ) FT_GetFile_From_Mac_Name( const char* fontName, FSSpec* pathSpec, @@ -134,27 +137,28 @@ FT_BEGIN_HEADER FT_DEPRECATED_ATTRIBUTE; - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_GetFile_From_Mac_ATS_Name */ - /* */ - /* <Description> */ - /* Return an FSSpec for the disk file containing the named font. */ - /* */ - /* <Input> */ - /* fontName :: Mac OS name of the font in ATS framework. */ - /* */ - /* <Output> */ - /* pathSpec :: FSSpec to the file. For passing to */ - /* @FT_New_Face_From_FSSpec. */ - /* */ - /* face_index :: Index of the face. For passing to */ - /* @FT_New_Face_From_FSSpec. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ + /************************************************************************** + * + * @function: + * FT_GetFile_From_Mac_ATS_Name + * + * @description: + * Return an FSSpec for the disk file containing the named font. + * + * @input: + * fontName :: + * Mac OS name of the font in ATS framework. + * + * @output: + * pathSpec :: + * FSSpec to the file. For passing to @FT_New_Face_From_FSSpec. + * + * face_index :: + * Index of the face. For passing to @FT_New_Face_From_FSSpec. + * + * @return: + * FreeType error code. 0~means success. + */ FT_EXPORT( FT_Error ) FT_GetFile_From_Mac_ATS_Name( const char* fontName, FSSpec* pathSpec, @@ -162,30 +166,33 @@ FT_BEGIN_HEADER FT_DEPRECATED_ATTRIBUTE; - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_GetFilePath_From_Mac_ATS_Name */ - /* */ - /* <Description> */ - /* Return a pathname of the disk file and face index for given font */ - /* name that is handled by ATS framework. */ - /* */ - /* <Input> */ - /* fontName :: Mac OS name of the font in ATS framework. */ - /* */ - /* <Output> */ - /* path :: Buffer to store pathname of the file. For passing */ - /* to @FT_New_Face. The client must allocate this */ - /* buffer before calling this function. */ - /* */ - /* maxPathSize :: Lengths of the buffer `path' that client allocated. */ - /* */ - /* face_index :: Index of the face. For passing to @FT_New_Face. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ + /************************************************************************** + * + * @function: + * FT_GetFilePath_From_Mac_ATS_Name + * + * @description: + * Return a pathname of the disk file and face index for given font name + * that is handled by ATS framework. + * + * @input: + * fontName :: + * Mac OS name of the font in ATS framework. + * + * @output: + * path :: + * Buffer to store pathname of the file. For passing to @FT_New_Face. + * The client must allocate this buffer before calling this function. + * + * maxPathSize :: + * Lengths of the buffer `path` that client allocated. + * + * face_index :: + * Index of the face. For passing to @FT_New_Face. + * + * @return: + * FreeType error code. 0~means success. + */ FT_EXPORT( FT_Error ) FT_GetFilePath_From_Mac_ATS_Name( const char* fontName, UInt8* path, @@ -194,33 +201,37 @@ FT_BEGIN_HEADER FT_DEPRECATED_ATTRIBUTE; - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_New_Face_From_FSSpec */ - /* */ - /* <Description> */ - /* Create a new face object from a given resource and typeface index */ - /* using an FSSpec to the font file. */ - /* */ - /* <InOut> */ - /* library :: A handle to the library resource. */ - /* */ - /* <Input> */ - /* spec :: FSSpec to the font file. */ - /* */ - /* face_index :: The index of the face within the resource. The */ - /* first face has index~0. */ - /* <Output> */ - /* aface :: A handle to a new face object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* @FT_New_Face_From_FSSpec is identical to @FT_New_Face except */ - /* it accepts an FSSpec instead of a path. */ - /* */ + /************************************************************************** + * + * @function: + * FT_New_Face_From_FSSpec + * + * @description: + * Create a new face object from a given resource and typeface index + * using an FSSpec to the font file. + * + * @inout: + * library :: + * A handle to the library resource. + * + * @input: + * spec :: + * FSSpec to the font file. + * + * face_index :: + * The index of the face within the resource. The first face has + * index~0. + * @output: + * aface :: + * A handle to a new face object. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * @FT_New_Face_From_FSSpec is identical to @FT_New_Face except it + * accepts an FSSpec instead of a path. + */ FT_EXPORT( FT_Error ) FT_New_Face_From_FSSpec( FT_Library library, const FSSpec *spec, @@ -229,33 +240,37 @@ FT_BEGIN_HEADER FT_DEPRECATED_ATTRIBUTE; - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_New_Face_From_FSRef */ - /* */ - /* <Description> */ - /* Create a new face object from a given resource and typeface index */ - /* using an FSRef to the font file. */ - /* */ - /* <InOut> */ - /* library :: A handle to the library resource. */ - /* */ - /* <Input> */ - /* spec :: FSRef to the font file. */ - /* */ - /* face_index :: The index of the face within the resource. The */ - /* first face has index~0. */ - /* <Output> */ - /* aface :: A handle to a new face object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* @FT_New_Face_From_FSRef is identical to @FT_New_Face except */ - /* it accepts an FSRef instead of a path. */ - /* */ + /************************************************************************** + * + * @function: + * FT_New_Face_From_FSRef + * + * @description: + * Create a new face object from a given resource and typeface index + * using an FSRef to the font file. + * + * @inout: + * library :: + * A handle to the library resource. + * + * @input: + * spec :: + * FSRef to the font file. + * + * face_index :: + * The index of the face within the resource. The first face has + * index~0. + * @output: + * aface :: + * A handle to a new face object. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * @FT_New_Face_From_FSRef is identical to @FT_New_Face except it accepts + * an FSRef instead of a path. + */ FT_EXPORT( FT_Error ) FT_New_Face_From_FSRef( FT_Library library, const FSRef *ref, diff --git a/sdk/lib/3rdparty/freetype/include/freetype/ftmm.h b/sdk/lib/3rdparty/freetype/include/freetype/ftmm.h index 9948102c14f3e..f2e16b6408746 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/ftmm.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/ftmm.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftmm.h */ -/* */ -/* FreeType Multiple Master font interface (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftmm.h + * + * FreeType Multiple Master font interface (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTMM_H_ @@ -27,49 +27,52 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* <Section> */ - /* multiple_masters */ - /* */ - /* <Title> */ - /* Multiple Masters */ - /* */ - /* <Abstract> */ - /* How to manage Multiple Masters fonts. */ - /* */ - /* <Description> */ - /* The following types and functions are used to manage Multiple */ - /* Master fonts, i.e., the selection of specific design instances by */ - /* setting design axis coordinates. */ - /* */ - /* Besides Adobe MM fonts, the interface supports Apple's TrueType GX */ - /* and OpenType variation fonts. Some of the routines only work with */ - /* Adobe MM fonts, others will work with all three types. They are */ - /* similar enough that a consistent interface makes sense. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_MM_Axis */ - /* */ - /* <Description> */ - /* A structure to model a given axis in design space for Multiple */ - /* Masters fonts. */ - /* */ - /* This structure can't be used for TrueType GX or OpenType variation */ - /* fonts. */ - /* */ - /* <Fields> */ - /* name :: The axis's name. */ - /* */ - /* minimum :: The axis's minimum design coordinate. */ - /* */ - /* maximum :: The axis's maximum design coordinate. */ - /* */ + /************************************************************************** + * + * @section: + * multiple_masters + * + * @title: + * Multiple Masters + * + * @abstract: + * How to manage Multiple Masters fonts. + * + * @description: + * The following types and functions are used to manage Multiple Master + * fonts, i.e., the selection of specific design instances by setting + * design axis coordinates. + * + * Besides Adobe MM fonts, the interface supports Apple's TrueType GX and + * OpenType variation fonts. Some of the routines only work with Adobe + * MM fonts, others will work with all three types. They are similar + * enough that a consistent interface makes sense. + * + */ + + + /************************************************************************** + * + * @struct: + * FT_MM_Axis + * + * @description: + * A structure to model a given axis in design space for Multiple Masters + * fonts. + * + * This structure can't be used for TrueType GX or OpenType variation + * fonts. + * + * @fields: + * name :: + * The axis's name. + * + * minimum :: + * The axis's minimum design coordinate. + * + * maximum :: + * The axis's maximum design coordinate. + */ typedef struct FT_MM_Axis_ { FT_String* name; @@ -79,28 +82,29 @@ FT_BEGIN_HEADER } FT_MM_Axis; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Multi_Master */ - /* */ - /* <Description> */ - /* A structure to model the axes and space of a Multiple Masters */ - /* font. */ - /* */ - /* This structure can't be used for TrueType GX or OpenType variation */ - /* fonts. */ - /* */ - /* <Fields> */ - /* num_axis :: Number of axes. Cannot exceed~4. */ - /* */ - /* num_designs :: Number of designs; should be normally 2^num_axis */ - /* even though the Type~1 specification strangely */ - /* allows for intermediate designs to be present. */ - /* This number cannot exceed~16. */ - /* */ - /* axis :: A table of axis descriptors. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_Multi_Master + * + * @description: + * A structure to model the axes and space of a Multiple Masters font. + * + * This structure can't be used for TrueType GX or OpenType variation + * fonts. + * + * @fields: + * num_axis :: + * Number of axes. Cannot exceed~4. + * + * num_designs :: + * Number of designs; should be normally 2^num_axis even though the + * Type~1 specification strangely allows for intermediate designs to be + * present. This number cannot exceed~16. + * + * axis :: + * A table of axis descriptors. + */ typedef struct FT_Multi_Master_ { FT_UInt num_axis; @@ -110,42 +114,45 @@ FT_BEGIN_HEADER } FT_Multi_Master; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Var_Axis */ - /* */ - /* <Description> */ - /* A structure to model a given axis in design space for Multiple */ - /* Masters, TrueType GX, and OpenType variation fonts. */ - /* */ - /* <Fields> */ - /* name :: The axis's name. */ - /* Not always meaningful for TrueType GX or OpenType */ - /* variation fonts. */ - /* */ - /* minimum :: The axis's minimum design coordinate. */ - /* */ - /* def :: The axis's default design coordinate. */ - /* FreeType computes meaningful default values for Adobe */ - /* MM fonts. */ - /* */ - /* maximum :: The axis's maximum design coordinate. */ - /* */ - /* tag :: The axis's tag (the equivalent to `name' for TrueType */ - /* GX and OpenType variation fonts). FreeType provides */ - /* default values for Adobe MM fonts if possible. */ - /* */ - /* strid :: The axis name entry in the font's `name' table. This */ - /* is another (and often better) version of the `name' */ - /* field for TrueType GX or OpenType variation fonts. Not */ - /* meaningful for Adobe MM fonts. */ - /* */ - /* <Note> */ - /* The fields `minimum', `def', and `maximum' are 16.16 fractional */ - /* values for TrueType GX and OpenType variation fonts. For Adobe MM */ - /* fonts, the values are integers. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_Var_Axis + * + * @description: + * A structure to model a given axis in design space for Multiple + * Masters, TrueType GX, and OpenType variation fonts. + * + * @fields: + * name :: + * The axis's name. Not always meaningful for TrueType GX or OpenType + * variation fonts. + * + * minimum :: + * The axis's minimum design coordinate. + * + * def :: + * The axis's default design coordinate. FreeType computes meaningful + * default values for Adobe MM fonts. + * + * maximum :: + * The axis's maximum design coordinate. + * + * tag :: + * The axis's tag (the equivalent to 'name' for TrueType GX and + * OpenType variation fonts). FreeType provides default values for + * Adobe MM fonts if possible. + * + * strid :: + * The axis name entry in the font's 'name' table. This is another + * (and often better) version of the 'name' field for TrueType GX or + * OpenType variation fonts. Not meaningful for Adobe MM fonts. + * + * @note: + * The fields `minimum`, `def`, and `maximum` are 16.16 fractional values + * for TrueType GX and OpenType variation fonts. For Adobe MM fonts, the + * values are integers. + */ typedef struct FT_Var_Axis_ { FT_String* name; @@ -160,27 +167,29 @@ FT_BEGIN_HEADER } FT_Var_Axis; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Var_Named_Style */ - /* */ - /* <Description> */ - /* A structure to model a named instance in a TrueType GX or OpenType */ - /* variation font. */ - /* */ - /* This structure can't be used for Adobe MM fonts. */ - /* */ - /* <Fields> */ - /* coords :: The design coordinates for this instance. */ - /* This is an array with one entry for each axis. */ - /* */ - /* strid :: The entry in `name' table identifying this instance. */ - /* */ - /* psid :: The entry in `name' table identifying a PostScript name */ - /* for this instance. Value 0xFFFF indicates a missing */ - /* entry. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_Var_Named_Style + * + * @description: + * A structure to model a named instance in a TrueType GX or OpenType + * variation font. + * + * This structure can't be used for Adobe MM fonts. + * + * @fields: + * coords :: + * The design coordinates for this instance. This is an array with one + * entry for each axis. + * + * strid :: + * The entry in 'name' table identifying this instance. + * + * psid :: + * The entry in 'name' table identifying a PostScript name for this + * instance. Value 0xFFFF indicates a missing entry. + */ typedef struct FT_Var_Named_Style_ { FT_Fixed* coords; @@ -190,50 +199,47 @@ FT_BEGIN_HEADER } FT_Var_Named_Style; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_MM_Var */ - /* */ - /* <Description> */ - /* A structure to model the axes and space of an Adobe MM, TrueType */ - /* GX, or OpenType variation font. */ - /* */ - /* Some fields are specific to one format and not to the others. */ - /* */ - /* <Fields> */ - /* num_axis :: The number of axes. The maximum value is~4 for */ - /* Adobe MM fonts; no limit in TrueType GX or */ - /* OpenType variation fonts. */ - /* */ - /* num_designs :: The number of designs; should be normally */ - /* 2^num_axis for Adobe MM fonts. Not meaningful */ - /* for TrueType GX or OpenType variation fonts */ - /* (where every glyph could have a different */ - /* number of designs). */ - /* */ - /* num_namedstyles :: The number of named styles; a `named style' is */ - /* a tuple of design coordinates that has a string */ - /* ID (in the `name' table) associated with it. */ - /* The font can tell the user that, for example, */ - /* [Weight=1.5,Width=1.1] is `Bold'. Another name */ - /* for `named style' is `named instance'. */ - /* */ - /* For Adobe Multiple Masters fonts, this value is */ - /* always zero because the format does not support */ - /* named styles. */ - /* */ - /* axis :: An axis descriptor table. */ - /* TrueType GX and OpenType variation fonts */ - /* contain slightly more data than Adobe MM fonts. */ - /* Memory management of this pointer is done */ - /* internally by FreeType. */ - /* */ - /* namedstyle :: A named style (instance) table. */ - /* Only meaningful for TrueType GX and OpenType */ - /* variation fonts. Memory management of this */ - /* pointer is done internally by FreeType. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_MM_Var + * + * @description: + * A structure to model the axes and space of an Adobe MM, TrueType GX, + * or OpenType variation font. + * + * Some fields are specific to one format and not to the others. + * + * @fields: + * num_axis :: + * The number of axes. The maximum value is~4 for Adobe MM fonts; no + * limit in TrueType GX or OpenType variation fonts. + * + * num_designs :: + * The number of designs; should be normally 2^num_axis for Adobe MM + * fonts. Not meaningful for TrueType GX or OpenType variation fonts + * (where every glyph could have a different number of designs). + * + * num_namedstyles :: + * The number of named styles; a 'named style' is a tuple of design + * coordinates that has a string ID (in the 'name' table) associated + * with it. The font can tell the user that, for example, + * [Weight=1.5,Width=1.1] is 'Bold'. Another name for 'named style' is + * 'named instance'. + * + * For Adobe Multiple Masters fonts, this value is always zero because + * the format does not support named styles. + * + * axis :: + * An axis descriptor table. TrueType GX and OpenType variation fonts + * contain slightly more data than Adobe MM fonts. Memory management + * of this pointer is done internally by FreeType. + * + * namedstyle :: + * A named style (instance) table. Only meaningful for TrueType GX and + * OpenType variation fonts. Memory management of this pointer is done + * internally by FreeType. + */ typedef struct FT_MM_Var_ { FT_UInt num_axis; @@ -245,384 +251,493 @@ FT_BEGIN_HEADER } FT_MM_Var; - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_Multi_Master */ - /* */ - /* <Description> */ - /* Retrieve a variation descriptor of a given Adobe MM font. */ - /* */ - /* This function can't be used with TrueType GX or OpenType variation */ - /* fonts. */ - /* */ - /* <Input> */ - /* face :: A handle to the source face. */ - /* */ - /* <Output> */ - /* amaster :: The Multiple Masters descriptor. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Get_Multi_Master + * + * @description: + * Retrieve a variation descriptor of a given Adobe MM font. + * + * This function can't be used with TrueType GX or OpenType variation + * fonts. + * + * @input: + * face :: + * A handle to the source face. + * + * @output: + * amaster :: + * The Multiple Masters descriptor. + * + * @return: + * FreeType error code. 0~means success. + */ FT_EXPORT( FT_Error ) FT_Get_Multi_Master( FT_Face face, FT_Multi_Master *amaster ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_MM_Var */ - /* */ - /* <Description> */ - /* Retrieve a variation descriptor for a given font. */ - /* */ - /* This function works with all supported variation formats. */ - /* */ - /* <Input> */ - /* face :: A handle to the source face. */ - /* */ - /* <Output> */ - /* amaster :: The variation descriptor. */ - /* Allocates a data structure, which the user must */ - /* deallocate with a call to @FT_Done_MM_Var after use. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Get_MM_Var + * + * @description: + * Retrieve a variation descriptor for a given font. + * + * This function works with all supported variation formats. + * + * @input: + * face :: + * A handle to the source face. + * + * @output: + * amaster :: + * The variation descriptor. Allocates a data structure, which the + * user must deallocate with a call to @FT_Done_MM_Var after use. + * + * @return: + * FreeType error code. 0~means success. + */ FT_EXPORT( FT_Error ) FT_Get_MM_Var( FT_Face face, FT_MM_Var* *amaster ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Done_MM_Var */ - /* */ - /* <Description> */ - /* Free the memory allocated by @FT_Get_MM_Var. */ - /* */ - /* <Input> */ - /* library :: A handle of the face's parent library object that was */ - /* used in the call to @FT_Get_MM_Var to create `amaster'. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Done_MM_Var + * + * @description: + * Free the memory allocated by @FT_Get_MM_Var. + * + * @input: + * library :: + * A handle of the face's parent library object that was used in the + * call to @FT_Get_MM_Var to create `amaster`. + * + * @return: + * FreeType error code. 0~means success. + */ FT_EXPORT( FT_Error ) FT_Done_MM_Var( FT_Library library, FT_MM_Var *amaster ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Set_MM_Design_Coordinates */ - /* */ - /* <Description> */ - /* For Adobe MM fonts, choose an interpolated font design through */ - /* design coordinates. */ - /* */ - /* This function can't be used with TrueType GX or OpenType variation */ - /* fonts. */ - /* */ - /* <InOut> */ - /* face :: A handle to the source face. */ - /* */ - /* <Input> */ - /* num_coords :: The number of available design coordinates. If it */ - /* is larger than the number of axes, ignore the excess */ - /* values. If it is smaller than the number of axes, */ - /* use default values for the remaining axes. */ - /* */ - /* coords :: An array of design coordinates. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* [Since 2.8.1] To reset all axes to the default values, call the */ - /* function with `num_coords' set to zero and `coords' set to NULL. */ - /* */ - /* [Since 2.9] If `num_coords' is larger than zero, this function */ - /* sets the @FT_FACE_FLAG_VARIATION bit in @FT_Face's `face_flags' */ - /* field (i.e., @FT_IS_VARIATION will return true). If `num_coords' */ - /* is zero, this bit flag gets unset. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Set_MM_Design_Coordinates + * + * @description: + * For Adobe MM fonts, choose an interpolated font design through design + * coordinates. + * + * This function can't be used with TrueType GX or OpenType variation + * fonts. + * + * @inout: + * face :: + * A handle to the source face. + * + * @input: + * num_coords :: + * The number of available design coordinates. If it is larger than + * the number of axes, ignore the excess values. If it is smaller than + * the number of axes, use default values for the remaining axes. + * + * coords :: + * An array of design coordinates. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * [Since 2.8.1] To reset all axes to the default values, call the + * function with `num_coords` set to zero and `coords` set to `NULL`. + * + * [Since 2.9] If `num_coords` is larger than zero, this function sets + * the @FT_FACE_FLAG_VARIATION bit in @FT_Face's `face_flags` field + * (i.e., @FT_IS_VARIATION will return true). If `num_coords` is zero, + * this bit flag gets unset. + */ FT_EXPORT( FT_Error ) FT_Set_MM_Design_Coordinates( FT_Face face, FT_UInt num_coords, FT_Long* coords ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Set_Var_Design_Coordinates */ - /* */ - /* <Description> */ - /* Choose an interpolated font design through design coordinates. */ - /* */ - /* This function works with all supported variation formats. */ - /* */ - /* <InOut> */ - /* face :: A handle to the source face. */ - /* */ - /* <Input> */ - /* num_coords :: The number of available design coordinates. If it */ - /* is larger than the number of axes, ignore the excess */ - /* values. If it is smaller than the number of axes, */ - /* use default values for the remaining axes. */ - /* */ - /* coords :: An array of design coordinates. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* [Since 2.8.1] To reset all axes to the default values, call the */ - /* function with `num_coords' set to zero and `coords' set to NULL. */ - /* [Since 2.9] `Default values' means the currently selected named */ - /* instance (or the base font if no named instance is selected). */ - /* */ - /* [Since 2.9] If `num_coords' is larger than zero, this function */ - /* sets the @FT_FACE_FLAG_VARIATION bit in @FT_Face's `face_flags' */ - /* field (i.e., @FT_IS_VARIATION will return true). If `num_coords' */ - /* is zero, this bit flag gets unset. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Set_Var_Design_Coordinates + * + * @description: + * Choose an interpolated font design through design coordinates. + * + * This function works with all supported variation formats. + * + * @inout: + * face :: + * A handle to the source face. + * + * @input: + * num_coords :: + * The number of available design coordinates. If it is larger than + * the number of axes, ignore the excess values. If it is smaller than + * the number of axes, use default values for the remaining axes. + * + * coords :: + * An array of design coordinates. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * [Since 2.8.1] To reset all axes to the default values, call the + * function with `num_coords` set to zero and `coords` set to `NULL`. + * [Since 2.9] 'Default values' means the currently selected named + * instance (or the base font if no named instance is selected). + * + * [Since 2.9] If `num_coords` is larger than zero, this function sets + * the @FT_FACE_FLAG_VARIATION bit in @FT_Face's `face_flags` field + * (i.e., @FT_IS_VARIATION will return true). If `num_coords` is zero, + * this bit flag gets unset. + */ FT_EXPORT( FT_Error ) FT_Set_Var_Design_Coordinates( FT_Face face, FT_UInt num_coords, FT_Fixed* coords ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_Var_Design_Coordinates */ - /* */ - /* <Description> */ - /* Get the design coordinates of the currently selected interpolated */ - /* font. */ - /* */ - /* This function works with all supported variation formats. */ - /* */ - /* <Input> */ - /* face :: A handle to the source face. */ - /* */ - /* num_coords :: The number of design coordinates to retrieve. If it */ - /* is larger than the number of axes, set the excess */ - /* values to~0. */ - /* */ - /* <Output> */ - /* coords :: The design coordinates array. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Since> */ - /* 2.7.1 */ - /* */ + /************************************************************************** + * + * @function: + * FT_Get_Var_Design_Coordinates + * + * @description: + * Get the design coordinates of the currently selected interpolated + * font. + * + * This function works with all supported variation formats. + * + * @input: + * face :: + * A handle to the source face. + * + * num_coords :: + * The number of design coordinates to retrieve. If it is larger than + * the number of axes, set the excess values to~0. + * + * @output: + * coords :: + * The design coordinates array. + * + * @return: + * FreeType error code. 0~means success. + * + * @since: + * 2.7.1 + */ FT_EXPORT( FT_Error ) FT_Get_Var_Design_Coordinates( FT_Face face, FT_UInt num_coords, FT_Fixed* coords ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Set_MM_Blend_Coordinates */ - /* */ - /* <Description> */ - /* Choose an interpolated font design through normalized blend */ - /* coordinates. */ - /* */ - /* This function works with all supported variation formats. */ - /* */ - /* <InOut> */ - /* face :: A handle to the source face. */ - /* */ - /* <Input> */ - /* num_coords :: The number of available design coordinates. If it */ - /* is larger than the number of axes, ignore the excess */ - /* values. If it is smaller than the number of axes, */ - /* use default values for the remaining axes. */ - /* */ - /* coords :: The design coordinates array (each element must be */ - /* between 0 and 1.0 for Adobe MM fonts, and between */ - /* -1.0 and 1.0 for TrueType GX and OpenType variation */ - /* fonts). */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* [Since 2.8.1] To reset all axes to the default values, call the */ - /* function with `num_coords' set to zero and `coords' set to NULL. */ - /* [Since 2.9] `Default values' means the currently selected named */ - /* instance (or the base font if no named instance is selected). */ - /* */ - /* [Since 2.9] If `num_coords' is larger than zero, this function */ - /* sets the @FT_FACE_FLAG_VARIATION bit in @FT_Face's `face_flags' */ - /* field (i.e., @FT_IS_VARIATION will return true). If `num_coords' */ - /* is zero, this bit flag gets unset. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Set_MM_Blend_Coordinates + * + * @description: + * Choose an interpolated font design through normalized blend + * coordinates. + * + * This function works with all supported variation formats. + * + * @inout: + * face :: + * A handle to the source face. + * + * @input: + * num_coords :: + * The number of available design coordinates. If it is larger than + * the number of axes, ignore the excess values. If it is smaller than + * the number of axes, use default values for the remaining axes. + * + * coords :: + * The design coordinates array (each element must be between 0 and 1.0 + * for Adobe MM fonts, and between -1.0 and 1.0 for TrueType GX and + * OpenType variation fonts). + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * [Since 2.8.1] To reset all axes to the default values, call the + * function with `num_coords` set to zero and `coords` set to `NULL`. + * [Since 2.9] 'Default values' means the currently selected named + * instance (or the base font if no named instance is selected). + * + * [Since 2.9] If `num_coords` is larger than zero, this function sets + * the @FT_FACE_FLAG_VARIATION bit in @FT_Face's `face_flags` field + * (i.e., @FT_IS_VARIATION will return true). If `num_coords` is zero, + * this bit flag gets unset. + */ FT_EXPORT( FT_Error ) FT_Set_MM_Blend_Coordinates( FT_Face face, FT_UInt num_coords, FT_Fixed* coords ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_MM_Blend_Coordinates */ - /* */ - /* <Description> */ - /* Get the normalized blend coordinates of the currently selected */ - /* interpolated font. */ - /* */ - /* This function works with all supported variation formats. */ - /* */ - /* <Input> */ - /* face :: A handle to the source face. */ - /* */ - /* num_coords :: The number of normalized blend coordinates to */ - /* retrieve. If it is larger than the number of axes, */ - /* set the excess values to~0.5 for Adobe MM fonts, and */ - /* to~0 for TrueType GX and OpenType variation fonts. */ - /* */ - /* <Output> */ - /* coords :: The normalized blend coordinates array. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Since> */ - /* 2.7.1 */ - /* */ + /************************************************************************** + * + * @function: + * FT_Get_MM_Blend_Coordinates + * + * @description: + * Get the normalized blend coordinates of the currently selected + * interpolated font. + * + * This function works with all supported variation formats. + * + * @input: + * face :: + * A handle to the source face. + * + * num_coords :: + * The number of normalized blend coordinates to retrieve. If it is + * larger than the number of axes, set the excess values to~0.5 for + * Adobe MM fonts, and to~0 for TrueType GX and OpenType variation + * fonts. + * + * @output: + * coords :: + * The normalized blend coordinates array. + * + * @return: + * FreeType error code. 0~means success. + * + * @since: + * 2.7.1 + */ FT_EXPORT( FT_Error ) FT_Get_MM_Blend_Coordinates( FT_Face face, FT_UInt num_coords, FT_Fixed* coords ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Set_Var_Blend_Coordinates */ - /* */ - /* <Description> */ - /* This is another name of @FT_Set_MM_Blend_Coordinates. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Set_Var_Blend_Coordinates + * + * @description: + * This is another name of @FT_Set_MM_Blend_Coordinates. + */ FT_EXPORT( FT_Error ) FT_Set_Var_Blend_Coordinates( FT_Face face, FT_UInt num_coords, FT_Fixed* coords ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_Var_Blend_Coordinates */ - /* */ - /* <Description> */ - /* This is another name of @FT_Get_MM_Blend_Coordinates. */ - /* */ - /* <Since> */ - /* 2.7.1 */ - /* */ + /************************************************************************** + * + * @function: + * FT_Get_Var_Blend_Coordinates + * + * @description: + * This is another name of @FT_Get_MM_Blend_Coordinates. + * + * @since: + * 2.7.1 + */ FT_EXPORT( FT_Error ) FT_Get_Var_Blend_Coordinates( FT_Face face, FT_UInt num_coords, FT_Fixed* coords ); - /*************************************************************************/ - /* */ - /* <Enum> */ - /* FT_VAR_AXIS_FLAG_XXX */ - /* */ - /* <Description> */ - /* A list of bit flags used in the return value of */ - /* @FT_Get_Var_Axis_Flags. */ - /* */ - /* <Values> */ - /* FT_VAR_AXIS_FLAG_HIDDEN :: */ - /* The variation axis should not be exposed to user interfaces. */ - /* */ - /* <Since> */ - /* 2.8.1 */ - /* */ + /************************************************************************** + * + * @function: + * FT_Set_MM_WeightVector + * + * @description: + * For Adobe MM fonts, choose an interpolated font design by directly + * setting the weight vector. + * + * This function can't be used with TrueType GX or OpenType variation + * fonts. + * + * @inout: + * face :: + * A handle to the source face. + * + * @input: + * len :: + * The length of the weight vector array. If it is larger than the + * number of designs, the extra values are ignored. If it is less than + * the number of designs, the remaining values are set to zero. + * + * weightvector :: + * An array representing the weight vector. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * Adobe Multiple Master fonts limit the number of designs, and thus the + * length of the weight vector to~16. + * + * If `len` is zero and `weightvector` is `NULL`, the weight vector array + * is reset to the default values. + * + * The Adobe documentation also states that the values in the + * WeightVector array must total 1.0 +/-~0.001. In practice this does + * not seem to be enforced, so is not enforced here, either. + * + * @since: + * 2.10 + */ + FT_EXPORT( FT_Error ) + FT_Set_MM_WeightVector( FT_Face face, + FT_UInt len, + FT_Fixed* weightvector ); + + + /************************************************************************** + * + * @function: + * FT_Get_MM_WeightVector + * + * @description: + * For Adobe MM fonts, retrieve the current weight vector of the font. + * + * This function can't be used with TrueType GX or OpenType variation + * fonts. + * + * @inout: + * face :: + * A handle to the source face. + * + * len :: + * A pointer to the size of the array to be filled. If the size of the + * array is less than the number of designs, `FT_Err_Invalid_Argument` + * is returned, and `len` is set to the required size (the number of + * designs). If the size of the array is greater than the number of + * designs, the remaining entries are set to~0. On successful + * completion, `len` is set to the number of designs (i.e., the number + * of values written to the array). + * + * @output: + * weightvector :: + * An array to be filled. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * Adobe Multiple Master fonts limit the number of designs, and thus the + * length of the WeightVector to~16. + * + * @since: + * 2.10 + */ + FT_EXPORT( FT_Error ) + FT_Get_MM_WeightVector( FT_Face face, + FT_UInt* len, + FT_Fixed* weightvector ); + + + /************************************************************************** + * + * @enum: + * FT_VAR_AXIS_FLAG_XXX + * + * @description: + * A list of bit flags used in the return value of + * @FT_Get_Var_Axis_Flags. + * + * @values: + * FT_VAR_AXIS_FLAG_HIDDEN :: + * The variation axis should not be exposed to user interfaces. + * + * @since: + * 2.8.1 + */ #define FT_VAR_AXIS_FLAG_HIDDEN 1 - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_Var_Axis_Flags */ - /* */ - /* <Description> */ - /* Get the `flags' field of an OpenType Variation Axis Record. */ - /* */ - /* Not meaningful for Adobe MM fonts (`*flags' is always zero). */ - /* */ - /* <Input> */ - /* master :: The variation descriptor. */ - /* */ - /* axis_index :: The index of the requested variation axis. */ - /* */ - /* <Output> */ - /* flags :: The `flags' field. See @FT_VAR_AXIS_FLAG_XXX for */ - /* possible values. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Since> */ - /* 2.8.1 */ - /* */ + /************************************************************************** + * + * @function: + * FT_Get_Var_Axis_Flags + * + * @description: + * Get the 'flags' field of an OpenType Variation Axis Record. + * + * Not meaningful for Adobe MM fonts (`*flags` is always zero). + * + * @input: + * master :: + * The variation descriptor. + * + * axis_index :: + * The index of the requested variation axis. + * + * @output: + * flags :: + * The 'flags' field. See @FT_VAR_AXIS_FLAG_XXX for possible values. + * + * @return: + * FreeType error code. 0~means success. + * + * @since: + * 2.8.1 + */ FT_EXPORT( FT_Error ) FT_Get_Var_Axis_Flags( FT_MM_Var* master, FT_UInt axis_index, FT_UInt* flags ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Set_Named_Instance */ - /* */ - /* <Description> */ - /* Set or change the current named instance. */ - /* */ - /* <Input> */ - /* face :: A handle to the source face. */ - /* */ - /* instance_index :: The index of the requested instance, starting */ - /* with value 1. If set to value 0, FreeType */ - /* switches to font access without a named */ - /* instance. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* The function uses the value of `instance_index' to set bits 16-30 */ - /* of the face's `face_index' field. It also resets any variation */ - /* applied to the font, and the @FT_FACE_FLAG_VARIATION bit of the */ - /* face's `face_flags' field gets reset to zero (i.e., */ - /* @FT_IS_VARIATION will return false). */ - /* */ - /* For Adobe MM fonts (which don't have named instances) this */ - /* function simply resets the current face to the default instance. */ - /* */ - /* <Since> */ - /* 2.9 */ - /* */ + /************************************************************************** + * + * @function: + * FT_Set_Named_Instance + * + * @description: + * Set or change the current named instance. + * + * @input: + * face :: + * A handle to the source face. + * + * instance_index :: + * The index of the requested instance, starting with value 1. If set + * to value 0, FreeType switches to font access without a named + * instance. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The function uses the value of `instance_index` to set bits 16-30 of + * the face's `face_index` field. It also resets any variation applied + * to the font, and the @FT_FACE_FLAG_VARIATION bit of the face's + * `face_flags` field gets reset to zero (i.e., @FT_IS_VARIATION will + * return false). + * + * For Adobe MM fonts (which don't have named instances) this function + * simply resets the current face to the default instance. + * + * @since: + * 2.9 + */ FT_EXPORT( FT_Error ) FT_Set_Named_Instance( FT_Face face, FT_UInt instance_index ); diff --git a/sdk/lib/3rdparty/freetype/include/freetype/ftmodapi.h b/sdk/lib/3rdparty/freetype/include/freetype/ftmodapi.h index a6eb876ebe305..88488bfe89c18 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/ftmodapi.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/ftmodapi.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftmodapi.h */ -/* */ -/* FreeType modules public interface (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftmodapi.h + * + * FreeType modules public interface (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTMODAPI_H_ @@ -33,77 +33,77 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* <Section> */ - /* module_management */ - /* */ - /* <Title> */ - /* Module Management */ - /* */ - /* <Abstract> */ - /* How to add, upgrade, remove, and control modules from FreeType. */ - /* */ - /* <Description> */ - /* The definitions below are used to manage modules within FreeType. */ - /* Modules can be added, upgraded, and removed at runtime. */ - /* Additionally, some module properties can be controlled also. */ - /* */ - /* Here is a list of possible values of the `module_name' field in */ - /* the @FT_Module_Class structure. */ - /* */ - /* { */ - /* autofitter */ - /* bdf */ - /* cff */ - /* gxvalid */ - /* otvalid */ - /* pcf */ - /* pfr */ - /* psaux */ - /* pshinter */ - /* psnames */ - /* raster1 */ - /* sfnt */ - /* smooth, smooth-lcd, smooth-lcdv */ - /* truetype */ - /* type1 */ - /* type42 */ - /* t1cid */ - /* winfonts */ - /* } */ - /* */ - /* Note that the FreeType Cache sub-system is not a FreeType module. */ - /* */ - /* <Order> */ - /* FT_Module */ - /* FT_Module_Constructor */ - /* FT_Module_Destructor */ - /* FT_Module_Requester */ - /* FT_Module_Class */ - /* */ - /* FT_Add_Module */ - /* FT_Get_Module */ - /* FT_Remove_Module */ - /* FT_Add_Default_Modules */ - /* */ - /* FT_Property_Set */ - /* FT_Property_Get */ - /* FT_Set_Default_Properties */ - /* */ - /* FT_New_Library */ - /* FT_Done_Library */ - /* FT_Reference_Library */ - /* */ - /* FT_Renderer */ - /* FT_Renderer_Class */ - /* */ - /* FT_Get_Renderer */ - /* FT_Set_Renderer */ - /* */ - /* FT_Set_Debug_Hook */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * @section: + * module_management + * + * @title: + * Module Management + * + * @abstract: + * How to add, upgrade, remove, and control modules from FreeType. + * + * @description: + * The definitions below are used to manage modules within FreeType. + * Modules can be added, upgraded, and removed at runtime. Additionally, + * some module properties can be controlled also. + * + * Here is a list of possible values of the `module_name` field in the + * @FT_Module_Class structure. + * + * ``` + * autofitter + * bdf + * cff + * gxvalid + * otvalid + * pcf + * pfr + * psaux + * pshinter + * psnames + * raster1 + * sfnt + * smooth, smooth-lcd, smooth-lcdv + * truetype + * type1 + * type42 + * t1cid + * winfonts + * ``` + * + * Note that the FreeType Cache sub-system is not a FreeType module. + * + * @order: + * FT_Module + * FT_Module_Constructor + * FT_Module_Destructor + * FT_Module_Requester + * FT_Module_Class + * + * FT_Add_Module + * FT_Get_Module + * FT_Remove_Module + * FT_Add_Default_Modules + * + * FT_Property_Set + * FT_Property_Get + * FT_Set_Default_Properties + * + * FT_New_Library + * FT_Done_Library + * FT_Reference_Library + * + * FT_Renderer + * FT_Renderer_Class + * + * FT_Get_Renderer + * FT_Set_Renderer + * + * FT_Set_Debug_Hook + * + */ /* module bit flags */ @@ -137,83 +137,99 @@ FT_BEGIN_HEADER typedef FT_Pointer FT_Module_Interface; - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_Module_Constructor */ - /* */ - /* <Description> */ - /* A function used to initialize (not create) a new module object. */ - /* */ - /* <Input> */ - /* module :: The module to initialize. */ - /* */ + /************************************************************************** + * + * @functype: + * FT_Module_Constructor + * + * @description: + * A function used to initialize (not create) a new module object. + * + * @input: + * module :: + * The module to initialize. + */ typedef FT_Error (*FT_Module_Constructor)( FT_Module module ); - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_Module_Destructor */ - /* */ - /* <Description> */ - /* A function used to finalize (not destroy) a given module object. */ - /* */ - /* <Input> */ - /* module :: The module to finalize. */ - /* */ + /************************************************************************** + * + * @functype: + * FT_Module_Destructor + * + * @description: + * A function used to finalize (not destroy) a given module object. + * + * @input: + * module :: + * The module to finalize. + */ typedef void (*FT_Module_Destructor)( FT_Module module ); - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_Module_Requester */ - /* */ - /* <Description> */ - /* A function used to query a given module for a specific interface. */ - /* */ - /* <Input> */ - /* module :: The module to be searched. */ - /* */ - /* name :: The name of the interface in the module. */ - /* */ + /************************************************************************** + * + * @functype: + * FT_Module_Requester + * + * @description: + * A function used to query a given module for a specific interface. + * + * @input: + * module :: + * The module to be searched. + * + * name :: + * The name of the interface in the module. + */ typedef FT_Module_Interface (*FT_Module_Requester)( FT_Module module, const char* name ); - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Module_Class */ - /* */ - /* <Description> */ - /* The module class descriptor. */ - /* */ - /* <Fields> */ - /* module_flags :: Bit flags describing the module. */ - /* */ - /* module_size :: The size of one module object/instance in */ - /* bytes. */ - /* */ - /* module_name :: The name of the module. */ - /* */ - /* module_version :: The version, as a 16.16 fixed number */ - /* (major.minor). */ - /* */ - /* module_requires :: The version of FreeType this module requires, */ - /* as a 16.16 fixed number (major.minor). Starts */ - /* at version 2.0, i.e., 0x20000. */ - /* */ - /* module_init :: The initializing function. */ - /* */ - /* module_done :: The finalizing function. */ - /* */ - /* get_interface :: The interface requesting function. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_Module_Class + * + * @description: + * The module class descriptor. While being a public structure necessary + * for FreeType's module bookkeeping, most of the fields are essentially + * internal, not to be used directly by an application. + * + * @fields: + * module_flags :: + * Bit flags describing the module. + * + * module_size :: + * The size of one module object/instance in bytes. + * + * module_name :: + * The name of the module. + * + * module_version :: + * The version, as a 16.16 fixed number (major.minor). + * + * module_requires :: + * The version of FreeType this module requires, as a 16.16 fixed + * number (major.minor). Starts at version 2.0, i.e., 0x20000. + * + * module_interface :: + * A typeless pointer to a structure (which varies between different + * modules) that holds the module's interface functions. This is + * essentially what `get_interface` returns. + * + * module_init :: + * The initializing function. + * + * module_done :: + * The finalizing function. + * + * get_interface :: + * The interface requesting function. + */ typedef struct FT_Module_Class_ { FT_ULong module_flags; @@ -231,83 +247,89 @@ FT_BEGIN_HEADER } FT_Module_Class; - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Add_Module */ - /* */ - /* <Description> */ - /* Add a new module to a given library instance. */ - /* */ - /* <InOut> */ - /* library :: A handle to the library object. */ - /* */ - /* <Input> */ - /* clazz :: A pointer to class descriptor for the module. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* An error will be returned if a module already exists by that name, */ - /* or if the module requires a version of FreeType that is too great. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Add_Module + * + * @description: + * Add a new module to a given library instance. + * + * @inout: + * library :: + * A handle to the library object. + * + * @input: + * clazz :: + * A pointer to class descriptor for the module. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * An error will be returned if a module already exists by that name, or + * if the module requires a version of FreeType that is too great. + */ FT_EXPORT( FT_Error ) FT_Add_Module( FT_Library library, const FT_Module_Class* clazz ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_Module */ - /* */ - /* <Description> */ - /* Find a module by its name. */ - /* */ - /* <Input> */ - /* library :: A handle to the library object. */ - /* */ - /* module_name :: The module's name (as an ASCII string). */ - /* */ - /* <Return> */ - /* A module handle. 0~if none was found. */ - /* */ - /* <Note> */ - /* FreeType's internal modules aren't documented very well, and you */ - /* should look up the source code for details. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Get_Module + * + * @description: + * Find a module by its name. + * + * @input: + * library :: + * A handle to the library object. + * + * module_name :: + * The module's name (as an ASCII string). + * + * @return: + * A module handle. 0~if none was found. + * + * @note: + * FreeType's internal modules aren't documented very well, and you + * should look up the source code for details. + */ FT_EXPORT( FT_Module ) FT_Get_Module( FT_Library library, const char* module_name ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Remove_Module */ - /* */ - /* <Description> */ - /* Remove a given module from a library instance. */ - /* */ - /* <InOut> */ - /* library :: A handle to a library object. */ - /* */ - /* <Input> */ - /* module :: A handle to a module object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* The module object is destroyed by the function in case of success. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Remove_Module + * + * @description: + * Remove a given module from a library instance. + * + * @inout: + * library :: + * A handle to a library object. + * + * @input: + * module :: + * A handle to a module object. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The module object is destroyed by the function in case of success. + */ FT_EXPORT( FT_Error ) FT_Remove_Module( FT_Library library, FT_Module module ); - /********************************************************************** + /************************************************************************** * * @function: * FT_Property_Set @@ -317,53 +339,51 @@ FT_BEGIN_HEADER * * @input: * library :: - * A handle to the library the module is part of. + * A handle to the library the module is part of. * * module_name :: - * The module name. + * The module name. * * property_name :: - * The property name. Properties are described in section - * @properties. + * The property name. Properties are described in section + * @properties. * - * Note that only a few modules have properties. + * Note that only a few modules have properties. * * value :: - * A generic pointer to a variable or structure that gives the new - * value of the property. The exact definition of `value' is - * dependent on the property; see section @properties. + * A generic pointer to a variable or structure that gives the new + * value of the property. The exact definition of `value` is + * dependent on the property; see section @properties. * * @return: * FreeType error code. 0~means success. * * @note: - * If `module_name' isn't a valid module name, or `property_name' - * doesn't specify a valid property, or if `value' doesn't represent a + * If `module_name` isn't a valid module name, or `property_name` + * doesn't specify a valid property, or if `value` doesn't represent a * valid value for the given property, an error is returned. * - * The following example sets property `bar' (a simple integer) in - * module `foo' to value~1. + * The following example sets property 'bar' (a simple integer) in + * module 'foo' to value~1. * - * { + * ``` * FT_UInt bar; * * * bar = 1; * FT_Property_Set( library, "foo", "bar", &bar ); - * } + * ``` * * Note that the FreeType Cache sub-system doesn't recognize module * property changes. To avoid glyph lookup confusion within the cache - * you should call @FTC_Manager_Reset to completely flush the cache if - * a module property gets changed after @FTC_Manager_New has been - * called. + * you should call @FTC_Manager_Reset to completely flush the cache if a + * module property gets changed after @FTC_Manager_New has been called. * - * It is not possible to set properties of the FreeType Cache - * sub-system itself with FT_Property_Set; use @FTC_Property_Set - * instead. + * It is not possible to set properties of the FreeType Cache sub-system + * itself with FT_Property_Set; use @FTC_Property_Set instead. * - * @since: - * 2.4.11 + * @since: + * 2.4.11 * */ FT_EXPORT( FT_Error ) @@ -373,7 +393,7 @@ FT_BEGIN_HEADER const void* value ); - /********************************************************************** + /************************************************************************** * * @function: * FT_Property_Get @@ -383,32 +403,32 @@ FT_BEGIN_HEADER * * @input: * library :: - * A handle to the library the module is part of. + * A handle to the library the module is part of. * * module_name :: - * The module name. + * The module name. * * property_name :: - * The property name. Properties are described in section - * @properties. + * The property name. Properties are described in section + * @properties. * * @inout: * value :: - * A generic pointer to a variable or structure that gives the - * value of the property. The exact definition of `value' is - * dependent on the property; see section @properties. + * A generic pointer to a variable or structure that gives the value + * of the property. The exact definition of `value` is dependent on + * the property; see section @properties. * * @return: * FreeType error code. 0~means success. * * @note: - * If `module_name' isn't a valid module name, or `property_name' - * doesn't specify a valid property, or if `value' doesn't represent a + * If `module_name` isn't a valid module name, or `property_name` + * doesn't specify a valid property, or if `value` doesn't represent a * valid value for the given property, an error is returned. * - * The following example gets property `baz' (a range) in module `foo'. + * The following example gets property 'baz' (a range) in module 'foo'. * - * { + * ``` * typedef range_ * { * FT_Int32 min; @@ -420,13 +440,13 @@ FT_BEGIN_HEADER * * * FT_Property_Get( library, "foo", "baz", &baz ); - * } + * ``` * * It is not possible to retrieve properties of the FreeType Cache * sub-system with FT_Property_Get; use @FTC_Property_Get instead. * - * @since: - * 2.4.11 + * @since: + * 2.4.11 * */ FT_EXPORT( FT_Error ) @@ -436,189 +456,243 @@ FT_BEGIN_HEADER void* value ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Set_Default_Properties */ - /* */ - /* <Description> */ - /* If compilation option FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES is */ - /* set, this function reads the `FREETYPE_PROPERTIES' environment */ - /* variable to control driver properties. See section @properties */ - /* for more. */ - /* */ - /* If the compilation option is not set, this function does nothing. */ - /* */ - /* `FREETYPE_PROPERTIES' has the following syntax form (broken here */ - /* into multiple lines for better readability). */ - /* */ - /* { */ - /* <optional whitespace> */ - /* <module-name1> ':' */ - /* <property-name1> '=' <property-value1> */ - /* <whitespace> */ - /* <module-name2> ':' */ - /* <property-name2> '=' <property-value2> */ - /* ... */ - /* } */ - /* */ - /* Example: */ - /* */ - /* { */ - /* FREETYPE_PROPERTIES=truetype:interpreter-version=35 \ */ - /* cff:no-stem-darkening=1 \ */ - /* autofitter:warping=1 */ - /* } */ - /* */ - /* <InOut> */ - /* library :: A handle to a new library object. */ - /* */ - /* <Since> */ - /* 2.8 */ - /* */ + /************************************************************************** + * + * @function: + * FT_Set_Default_Properties + * + * @description: + * If compilation option `FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES` is + * set, this function reads the `FREETYPE_PROPERTIES` environment + * variable to control driver properties. See section @properties for + * more. + * + * If the compilation option is not set, this function does nothing. + * + * `FREETYPE_PROPERTIES` has the following syntax form (broken here into + * multiple lines for better readability). + * + * ``` + * <optional whitespace> + * <module-name1> ':' + * <property-name1> '=' <property-value1> + * <whitespace> + * <module-name2> ':' + * <property-name2> '=' <property-value2> + * ... + * ``` + * + * Example: + * + * ``` + * FREETYPE_PROPERTIES=truetype:interpreter-version=35 \ + * cff:no-stem-darkening=1 \ + * autofitter:warping=1 + * ``` + * + * @inout: + * library :: + * A handle to a new library object. + * + * @since: + * 2.8 + */ FT_EXPORT( void ) FT_Set_Default_Properties( FT_Library library ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Reference_Library */ - /* */ - /* <Description> */ - /* A counter gets initialized to~1 at the time an @FT_Library */ - /* structure is created. This function increments the counter. */ - /* @FT_Done_Library then only destroys a library if the counter is~1, */ - /* otherwise it simply decrements the counter. */ - /* */ - /* This function helps in managing life-cycles of structures that */ - /* reference @FT_Library objects. */ - /* */ - /* <Input> */ - /* library :: A handle to a target library object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Since> */ - /* 2.4.2 */ - /* */ + /************************************************************************** + * + * @function: + * FT_Reference_Library + * + * @description: + * A counter gets initialized to~1 at the time an @FT_Library structure + * is created. This function increments the counter. @FT_Done_Library + * then only destroys a library if the counter is~1, otherwise it simply + * decrements the counter. + * + * This function helps in managing life-cycles of structures that + * reference @FT_Library objects. + * + * @input: + * library :: + * A handle to a target library object. + * + * @return: + * FreeType error code. 0~means success. + * + * @since: + * 2.4.2 + */ FT_EXPORT( FT_Error ) FT_Reference_Library( FT_Library library ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_New_Library */ - /* */ - /* <Description> */ - /* This function is used to create a new FreeType library instance */ - /* from a given memory object. It is thus possible to use libraries */ - /* with distinct memory allocators within the same program. Note, */ - /* however, that the used @FT_Memory structure is expected to remain */ - /* valid for the life of the @FT_Library object. */ - /* */ - /* Normally, you would call this function (followed by a call to */ - /* @FT_Add_Default_Modules or a series of calls to @FT_Add_Module, */ - /* and a call to @FT_Set_Default_Properties) instead of */ - /* @FT_Init_FreeType to initialize the FreeType library. */ - /* */ - /* Don't use @FT_Done_FreeType but @FT_Done_Library to destroy a */ - /* library instance. */ - /* */ - /* <Input> */ - /* memory :: A handle to the original memory object. */ - /* */ - /* <Output> */ - /* alibrary :: A pointer to handle of a new library object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* See the discussion of reference counters in the description of */ - /* @FT_Reference_Library. */ - /* */ + /************************************************************************** + * + * @function: + * FT_New_Library + * + * @description: + * This function is used to create a new FreeType library instance from a + * given memory object. It is thus possible to use libraries with + * distinct memory allocators within the same program. Note, however, + * that the used @FT_Memory structure is expected to remain valid for the + * life of the @FT_Library object. + * + * Normally, you would call this function (followed by a call to + * @FT_Add_Default_Modules or a series of calls to @FT_Add_Module, and a + * call to @FT_Set_Default_Properties) instead of @FT_Init_FreeType to + * initialize the FreeType library. + * + * Don't use @FT_Done_FreeType but @FT_Done_Library to destroy a library + * instance. + * + * @input: + * memory :: + * A handle to the original memory object. + * + * @output: + * alibrary :: + * A pointer to handle of a new library object. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * See the discussion of reference counters in the description of + * @FT_Reference_Library. + */ FT_EXPORT( FT_Error ) FT_New_Library( FT_Memory memory, FT_Library *alibrary ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Done_Library */ - /* */ - /* <Description> */ - /* Discard a given library object. This closes all drivers and */ - /* discards all resource objects. */ - /* */ - /* <Input> */ - /* library :: A handle to the target library. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* See the discussion of reference counters in the description of */ - /* @FT_Reference_Library. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Done_Library + * + * @description: + * Discard a given library object. This closes all drivers and discards + * all resource objects. + * + * @input: + * library :: + * A handle to the target library. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * See the discussion of reference counters in the description of + * @FT_Reference_Library. + */ FT_EXPORT( FT_Error ) FT_Done_Library( FT_Library library ); - /* */ + /************************************************************************** + * + * @functype: + * FT_DebugHook_Func + * + * @description: + * A drop-in replacement (or rather a wrapper) for the bytecode or + * charstring interpreter's main loop function. + * + * Its job is essentially + * + * - to activate debug mode to enforce single-stepping, + * + * - to call the main loop function to interpret the next opcode, and + * + * - to show the changed context to the user. + * + * An example for such a main loop function is `TT_RunIns` (declared in + * FreeType's internal header file `src/truetype/ttinterp.h`). + * + * Have a look at the source code of the `ttdebug` FreeType demo program + * for an example of a drop-in replacement. + * + * @inout: + * arg :: + * A typeless pointer, to be cast to the main loop function's data + * structure (which depends on the font module). For TrueType fonts + * it is bytecode interpreter's execution context, `TT_ExecContext`, + * which is declared in FreeType's internal header file `tttypes.h`. + */ typedef void (*FT_DebugHook_Func)( void* arg ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Set_Debug_Hook */ - /* */ - /* <Description> */ - /* Set a debug hook function for debugging the interpreter of a font */ - /* format. */ - /* */ - /* <InOut> */ - /* library :: A handle to the library object. */ - /* */ - /* <Input> */ - /* hook_index :: The index of the debug hook. You should use the */ - /* values defined in `ftobjs.h', e.g., */ - /* `FT_DEBUG_HOOK_TRUETYPE'. */ - /* */ - /* debug_hook :: The function used to debug the interpreter. */ - /* */ - /* <Note> */ - /* Currently, four debug hook slots are available, but only two (for */ - /* the TrueType and the Type~1 interpreter) are defined. */ - /* */ - /* Since the internal headers of FreeType are no longer installed, */ - /* the symbol `FT_DEBUG_HOOK_TRUETYPE' isn't available publicly. */ - /* This is a bug and will be fixed in a forthcoming release. */ - /* */ + /************************************************************************** + * + * @enum: + * FT_DEBUG_HOOK_XXX + * + * @description: + * A list of named debug hook indices. + * + * @values: + * FT_DEBUG_HOOK_TRUETYPE:: + * This hook index identifies the TrueType bytecode debugger. + */ +#define FT_DEBUG_HOOK_TRUETYPE 0 + + + /************************************************************************** + * + * @function: + * FT_Set_Debug_Hook + * + * @description: + * Set a debug hook function for debugging the interpreter of a font + * format. + * + * While this is a public API function, an application needs access to + * FreeType's internal header files to do something useful. + * + * Have a look at the source code of the `ttdebug` FreeType demo program + * for an example of its usage. + * + * @inout: + * library :: + * A handle to the library object. + * + * @input: + * hook_index :: + * The index of the debug hook. You should use defined enumeration + * macros like @FT_DEBUG_HOOK_TRUETYPE. + * + * debug_hook :: + * The function used to debug the interpreter. + * + * @note: + * Currently, four debug hook slots are available, but only one (for the + * TrueType interpreter) is defined. + */ FT_EXPORT( void ) FT_Set_Debug_Hook( FT_Library library, FT_UInt hook_index, FT_DebugHook_Func debug_hook ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Add_Default_Modules */ - /* */ - /* <Description> */ - /* Add the set of default drivers to a given library object. */ - /* This is only useful when you create a library object with */ - /* @FT_New_Library (usually to plug a custom memory manager). */ - /* */ - /* <InOut> */ - /* library :: A handle to a new library object. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Add_Default_Modules + * + * @description: + * Add the set of default drivers to a given library object. This is + * only useful when you create a library object with @FT_New_Library + * (usually to plug a custom memory manager). + * + * @inout: + * library :: + * A handle to a new library object. + */ FT_EXPORT( void ) FT_Add_Default_Modules( FT_Library library ); @@ -644,28 +718,28 @@ FT_BEGIN_HEADER /************************************************************************** * - * @enum: - * FT_TrueTypeEngineType + * @enum: + * FT_TrueTypeEngineType * - * @description: - * A list of values describing which kind of TrueType bytecode - * engine is implemented in a given FT_Library instance. It is used - * by the @FT_Get_TrueType_Engine_Type function. + * @description: + * A list of values describing which kind of TrueType bytecode engine is + * implemented in a given FT_Library instance. It is used by the + * @FT_Get_TrueType_Engine_Type function. * - * @values: - * FT_TRUETYPE_ENGINE_TYPE_NONE :: - * The library doesn't implement any kind of bytecode interpreter. + * @values: + * FT_TRUETYPE_ENGINE_TYPE_NONE :: + * The library doesn't implement any kind of bytecode interpreter. * - * FT_TRUETYPE_ENGINE_TYPE_UNPATENTED :: - * Deprecated and removed. + * FT_TRUETYPE_ENGINE_TYPE_UNPATENTED :: + * Deprecated and removed. * - * FT_TRUETYPE_ENGINE_TYPE_PATENTED :: - * The library implements a bytecode interpreter that covers - * the full instruction set of the TrueType virtual machine (this - * was governed by patents until May 2010, hence the name). + * FT_TRUETYPE_ENGINE_TYPE_PATENTED :: + * The library implements a bytecode interpreter that covers the full + * instruction set of the TrueType virtual machine (this was governed + * by patents until May 2010, hence the name). * - * @since: - * 2.2 + * @since: + * 2.2 * */ typedef enum FT_TrueTypeEngineType_ @@ -679,22 +753,22 @@ FT_BEGIN_HEADER /************************************************************************** * - * @func: - * FT_Get_TrueType_Engine_Type + * @function: + * FT_Get_TrueType_Engine_Type * - * @description: - * Return an @FT_TrueTypeEngineType value to indicate which level of - * the TrueType virtual machine a given library instance supports. + * @description: + * Return an @FT_TrueTypeEngineType value to indicate which level of the + * TrueType virtual machine a given library instance supports. * - * @input: - * library :: - * A library instance. + * @input: + * library :: + * A library instance. * - * @return: - * A value indicating which level is supported. + * @return: + * A value indicating which level is supported. * - * @since: - * 2.2 + * @since: + * 2.2 * */ FT_EXPORT( FT_TrueTypeEngineType ) diff --git a/sdk/lib/3rdparty/freetype/include/freetype/ftmoderr.h b/sdk/lib/3rdparty/freetype/include/freetype/ftmoderr.h index e0fc1312bd491..e16993572c802 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/ftmoderr.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/ftmoderr.h @@ -1,94 +1,103 @@ -/***************************************************************************/ -/* */ -/* ftmoderr.h */ -/* */ -/* FreeType module error offsets (specification). */ -/* */ -/* Copyright 2001-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to define the FreeType module error codes. */ - /* */ - /* If the macro FT_CONFIG_OPTION_USE_MODULE_ERRORS in `ftoption.h' is */ - /* set, the lower byte of an error value identifies the error code as */ - /* usual. In addition, the higher byte identifies the module. For */ - /* example, the error `FT_Err_Invalid_File_Format' has value 0x0003, the */ - /* error `TT_Err_Invalid_File_Format' has value 0x1303, the error */ - /* `T1_Err_Invalid_File_Format' has value 0x1403, etc. */ - /* */ - /* Note that `FT_Err_Ok', `TT_Err_Ok', etc. are always equal to zero, */ - /* including the high byte. */ - /* */ - /* If FT_CONFIG_OPTION_USE_MODULE_ERRORS isn't set, the higher byte of */ - /* an error value is set to zero. */ - /* */ - /* To hide the various `XXX_Err_' prefixes in the source code, FreeType */ - /* provides some macros in `fttypes.h'. */ - /* */ - /* FT_ERR( err ) */ - /* Add current error module prefix (as defined with the */ - /* `FT_ERR_PREFIX' macro) to `err'. For example, in the BDF module */ - /* the line */ - /* */ - /* error = FT_ERR( Invalid_Outline ); */ - /* */ - /* expands to */ - /* */ - /* error = BDF_Err_Invalid_Outline; */ - /* */ - /* For simplicity, you can always use `FT_Err_Ok' directly instead */ - /* of `FT_ERR( Ok )'. */ - /* */ - /* FT_ERR_EQ( errcode, err ) */ - /* FT_ERR_NEQ( errcode, err ) */ - /* Compare error code `errcode' with the error `err' for equality */ - /* and inequality, respectively. Example: */ - /* */ - /* if ( FT_ERR_EQ( error, Invalid_Outline ) ) */ - /* ... */ - /* */ - /* Using this macro you don't have to think about error prefixes. */ - /* Of course, if module errors are not active, the above example is */ - /* the same as */ - /* */ - /* if ( error == FT_Err_Invalid_Outline ) */ - /* ... */ - /* */ - /* FT_ERROR_BASE( errcode ) */ - /* FT_ERROR_MODULE( errcode ) */ - /* Get base error and module error code, respectively. */ - /* */ - /* */ - /* It can also be used to create a module error message table easily */ - /* with something like */ - /* */ - /* { */ - /* #undef FTMODERR_H_ */ - /* #define FT_MODERRDEF( e, v, s ) { FT_Mod_Err_ ## e, s }, */ - /* #define FT_MODERR_START_LIST { */ - /* #define FT_MODERR_END_LIST { 0, 0 } }; */ - /* */ - /* const struct */ - /* { */ - /* int mod_err_offset; */ - /* const char* mod_err_msg */ - /* } ft_mod_errors[] = */ - /* */ - /* #include FT_MODULE_ERRORS_H */ - /* } */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * ftmoderr.h + * + * FreeType module error offsets (specification). + * + * Copyright (C) 2001-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /************************************************************************** + * + * This file is used to define the FreeType module error codes. + * + * If the macro `FT_CONFIG_OPTION_USE_MODULE_ERRORS` in `ftoption.h` is + * set, the lower byte of an error value identifies the error code as + * usual. In addition, the higher byte identifies the module. For + * example, the error `FT_Err_Invalid_File_Format` has value 0x0003, the + * error `TT_Err_Invalid_File_Format` has value 0x1303, the error + * `T1_Err_Invalid_File_Format` has value 0x1403, etc. + * + * Note that `FT_Err_Ok`, `TT_Err_Ok`, etc. are always equal to zero, + * including the high byte. + * + * If `FT_CONFIG_OPTION_USE_MODULE_ERRORS` isn't set, the higher byte of an + * error value is set to zero. + * + * To hide the various `XXX_Err_` prefixes in the source code, FreeType + * provides some macros in `fttypes.h`. + * + * FT_ERR( err ) + * + * Add current error module prefix (as defined with the `FT_ERR_PREFIX` + * macro) to `err`. For example, in the BDF module the line + * + * ``` + * error = FT_ERR( Invalid_Outline ); + * ``` + * + * expands to + * + * ``` + * error = BDF_Err_Invalid_Outline; + * ``` + * + * For simplicity, you can always use `FT_Err_Ok` directly instead of + * `FT_ERR( Ok )`. + * + * FT_ERR_EQ( errcode, err ) + * FT_ERR_NEQ( errcode, err ) + * + * Compare error code `errcode` with the error `err` for equality and + * inequality, respectively. Example: + * + * ``` + * if ( FT_ERR_EQ( error, Invalid_Outline ) ) + * ... + * ``` + * + * Using this macro you don't have to think about error prefixes. Of + * course, if module errors are not active, the above example is the + * same as + * + * ``` + * if ( error == FT_Err_Invalid_Outline ) + * ... + * ``` + * + * FT_ERROR_BASE( errcode ) + * FT_ERROR_MODULE( errcode ) + * + * Get base error and module error code, respectively. + * + * It can also be used to create a module error message table easily with + * something like + * + * ``` + * #undef FTMODERR_H_ + * #define FT_MODERRDEF( e, v, s ) { FT_Mod_Err_ ## e, s }, + * #define FT_MODERR_START_LIST { + * #define FT_MODERR_END_LIST { 0, 0 } }; + * + * const struct + * { + * int mod_err_offset; + * const char* mod_err_msg + * } ft_mod_errors[] = + * + * #include FT_MODULE_ERRORS_H + * ``` + * + */ #ifndef FTMODERR_H_ diff --git a/sdk/lib/3rdparty/freetype/include/freetype/ftotval.h b/sdk/lib/3rdparty/freetype/include/freetype/ftotval.h index 26731c2b9f58d..c034f489596c9 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/ftotval.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/ftotval.h @@ -1,30 +1,30 @@ -/***************************************************************************/ -/* */ -/* ftotval.h */ -/* */ -/* FreeType API for validating OpenType tables (specification). */ -/* */ -/* Copyright 2004-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -/***************************************************************************/ -/* */ -/* */ -/* Warning: This module might be moved to a different library in the */ -/* future to avoid a tight dependency between FreeType and the */ -/* OpenType specification. */ -/* */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftotval.h + * + * FreeType API for validating OpenType tables (specification). + * + * Copyright (C) 2004-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + +/**************************************************************************** + * + * + * Warning: This module might be moved to a different library in the + * future to avoid a tight dependency between FreeType and the + * OpenType specification. + * + * + */ #ifndef FTOTVAL_H_ @@ -43,62 +43,62 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* <Section> */ - /* ot_validation */ - /* */ - /* <Title> */ - /* OpenType Validation */ - /* */ - /* <Abstract> */ - /* An API to validate OpenType tables. */ - /* */ - /* <Description> */ - /* This section contains the declaration of functions to validate */ - /* some OpenType tables (BASE, GDEF, GPOS, GSUB, JSTF, MATH). */ - /* */ - /* <Order> */ - /* FT_OpenType_Validate */ - /* FT_OpenType_Free */ - /* */ - /* FT_VALIDATE_OTXXX */ - /* */ - /*************************************************************************/ - - - /********************************************************************** - * - * @enum: - * FT_VALIDATE_OTXXX - * - * @description: - * A list of bit-field constants used with @FT_OpenType_Validate to - * indicate which OpenType tables should be validated. - * - * @values: - * FT_VALIDATE_BASE :: - * Validate BASE table. - * - * FT_VALIDATE_GDEF :: - * Validate GDEF table. - * - * FT_VALIDATE_GPOS :: - * Validate GPOS table. - * - * FT_VALIDATE_GSUB :: - * Validate GSUB table. - * - * FT_VALIDATE_JSTF :: - * Validate JSTF table. - * - * FT_VALIDATE_MATH :: - * Validate MATH table. - * - * FT_VALIDATE_OT :: - * Validate all OpenType tables (BASE, GDEF, GPOS, GSUB, JSTF, MATH). - * - */ + /************************************************************************** + * + * @section: + * ot_validation + * + * @title: + * OpenType Validation + * + * @abstract: + * An API to validate OpenType tables. + * + * @description: + * This section contains the declaration of functions to validate some + * OpenType tables (BASE, GDEF, GPOS, GSUB, JSTF, MATH). + * + * @order: + * FT_OpenType_Validate + * FT_OpenType_Free + * + * FT_VALIDATE_OTXXX + * + */ + + + /************************************************************************** + * + * @enum: + * FT_VALIDATE_OTXXX + * + * @description: + * A list of bit-field constants used with @FT_OpenType_Validate to + * indicate which OpenType tables should be validated. + * + * @values: + * FT_VALIDATE_BASE :: + * Validate BASE table. + * + * FT_VALIDATE_GDEF :: + * Validate GDEF table. + * + * FT_VALIDATE_GPOS :: + * Validate GPOS table. + * + * FT_VALIDATE_GSUB :: + * Validate GSUB table. + * + * FT_VALIDATE_JSTF :: + * Validate JSTF table. + * + * FT_VALIDATE_MATH :: + * Validate MATH table. + * + * FT_VALIDATE_OT :: + * Validate all OpenType tables (BASE, GDEF, GPOS, GSUB, JSTF, MATH). + * + */ #define FT_VALIDATE_BASE 0x0100 #define FT_VALIDATE_GDEF 0x0200 #define FT_VALIDATE_GPOS 0x0400 @@ -113,53 +113,54 @@ FT_BEGIN_HEADER FT_VALIDATE_JSTF | \ FT_VALIDATE_MATH ) - /********************************************************************** - * - * @function: - * FT_OpenType_Validate - * - * @description: - * Validate various OpenType tables to assure that all offsets and - * indices are valid. The idea is that a higher-level library that - * actually does the text layout can access those tables without - * error checking (which can be quite time consuming). - * - * @input: - * face :: - * A handle to the input face. - * - * validation_flags :: - * A bit field that specifies the tables to be validated. See - * @FT_VALIDATE_OTXXX for possible values. - * - * @output: - * BASE_table :: - * A pointer to the BASE table. - * - * GDEF_table :: - * A pointer to the GDEF table. - * - * GPOS_table :: - * A pointer to the GPOS table. - * - * GSUB_table :: - * A pointer to the GSUB table. - * - * JSTF_table :: - * A pointer to the JSTF table. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * This function only works with OpenType fonts, returning an error - * otherwise. - * - * After use, the application should deallocate the five tables with - * @FT_OpenType_Free. A NULL value indicates that the table either - * doesn't exist in the font, or the application hasn't asked for - * validation. - */ + + /************************************************************************** + * + * @function: + * FT_OpenType_Validate + * + * @description: + * Validate various OpenType tables to assure that all offsets and + * indices are valid. The idea is that a higher-level library that + * actually does the text layout can access those tables without error + * checking (which can be quite time consuming). + * + * @input: + * face :: + * A handle to the input face. + * + * validation_flags :: + * A bit field that specifies the tables to be validated. See + * @FT_VALIDATE_OTXXX for possible values. + * + * @output: + * BASE_table :: + * A pointer to the BASE table. + * + * GDEF_table :: + * A pointer to the GDEF table. + * + * GPOS_table :: + * A pointer to the GPOS table. + * + * GSUB_table :: + * A pointer to the GSUB table. + * + * JSTF_table :: + * A pointer to the JSTF table. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with OpenType fonts, returning an error + * otherwise. + * + * After use, the application should deallocate the five tables with + * @FT_OpenType_Free. A `NULL` value indicates that the table either + * doesn't exist in the font, or the application hasn't asked for + * validation. + */ FT_EXPORT( FT_Error ) FT_OpenType_Validate( FT_Face face, FT_UInt validation_flags, @@ -169,30 +170,32 @@ FT_BEGIN_HEADER FT_Bytes *GSUB_table, FT_Bytes *JSTF_table ); - /********************************************************************** - * - * @function: - * FT_OpenType_Free - * - * @description: - * Free the buffer allocated by OpenType validator. - * - * @input: - * face :: - * A handle to the input face. - * - * table :: - * The pointer to the buffer that is allocated by - * @FT_OpenType_Validate. - * - * @note: - * This function must be used to free the buffer allocated by - * @FT_OpenType_Validate only. - */ + + /************************************************************************** + * + * @function: + * FT_OpenType_Free + * + * @description: + * Free the buffer allocated by OpenType validator. + * + * @input: + * face :: + * A handle to the input face. + * + * table :: + * The pointer to the buffer that is allocated by + * @FT_OpenType_Validate. + * + * @note: + * This function must be used to free the buffer allocated by + * @FT_OpenType_Validate only. + */ FT_EXPORT( void ) FT_OpenType_Free( FT_Face face, FT_Bytes table ); + /* */ diff --git a/sdk/lib/3rdparty/freetype/include/freetype/ftoutln.h b/sdk/lib/3rdparty/freetype/include/freetype/ftoutln.h index 89389a49b7c74..75c3d015968a9 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/ftoutln.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/ftoutln.h @@ -1,20 +1,20 @@ -/***************************************************************************/ -/* */ -/* ftoutln.h */ -/* */ -/* Support for the FT_Outline type used to store glyph shapes of */ -/* most scalable font formats (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftoutln.h + * + * Support for the FT_Outline type used to store glyph shapes of + * most scalable font formats (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTOUTLN_H_ @@ -34,127 +34,131 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* <Section> */ - /* outline_processing */ - /* */ - /* <Title> */ - /* Outline Processing */ - /* */ - /* <Abstract> */ - /* Functions to create, transform, and render vectorial glyph images. */ - /* */ - /* <Description> */ - /* This section contains routines used to create and destroy scalable */ - /* glyph images known as `outlines'. These can also be measured, */ - /* transformed, and converted into bitmaps and pixmaps. */ - /* */ - /* <Order> */ - /* FT_Outline */ - /* FT_Outline_New */ - /* FT_Outline_Done */ - /* FT_Outline_Copy */ - /* FT_Outline_Translate */ - /* FT_Outline_Transform */ - /* FT_Outline_Embolden */ - /* FT_Outline_EmboldenXY */ - /* FT_Outline_Reverse */ - /* FT_Outline_Check */ - /* */ - /* FT_Outline_Get_CBox */ - /* FT_Outline_Get_BBox */ - /* */ - /* FT_Outline_Get_Bitmap */ - /* FT_Outline_Render */ - /* FT_Outline_Decompose */ - /* FT_Outline_Funcs */ - /* FT_Outline_MoveToFunc */ - /* FT_Outline_LineToFunc */ - /* FT_Outline_ConicToFunc */ - /* FT_Outline_CubicToFunc */ - /* */ - /* FT_Orientation */ - /* FT_Outline_Get_Orientation */ - /* */ - /* FT_OUTLINE_XXX */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Outline_Decompose */ - /* */ - /* <Description> */ - /* Walk over an outline's structure to decompose it into individual */ - /* segments and Bezier arcs. This function also emits `move to' */ - /* operations to indicate the start of new contours in the outline. */ - /* */ - /* <Input> */ - /* outline :: A pointer to the source target. */ - /* */ - /* func_interface :: A table of `emitters', i.e., function pointers */ - /* called during decomposition to indicate path */ - /* operations. */ - /* */ - /* <InOut> */ - /* user :: A typeless pointer that is passed to each */ - /* emitter during the decomposition. It can be */ - /* used to store the state during the */ - /* decomposition. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* A contour that contains a single point only is represented by a */ - /* `move to' operation followed by `line to' to the same point. In */ - /* most cases, it is best to filter this out before using the */ - /* outline for stroking purposes (otherwise it would result in a */ - /* visible dot when round caps are used). */ - /* */ - /* Similarly, the function returns success for an empty outline also */ - /* (doing nothing, this is, not calling any emitter); if necessary, */ - /* you should filter this out, too. */ - /* */ + /************************************************************************** + * + * @section: + * outline_processing + * + * @title: + * Outline Processing + * + * @abstract: + * Functions to create, transform, and render vectorial glyph images. + * + * @description: + * This section contains routines used to create and destroy scalable + * glyph images known as 'outlines'. These can also be measured, + * transformed, and converted into bitmaps and pixmaps. + * + * @order: + * FT_Outline + * FT_Outline_New + * FT_Outline_Done + * FT_Outline_Copy + * FT_Outline_Translate + * FT_Outline_Transform + * FT_Outline_Embolden + * FT_Outline_EmboldenXY + * FT_Outline_Reverse + * FT_Outline_Check + * + * FT_Outline_Get_CBox + * FT_Outline_Get_BBox + * + * FT_Outline_Get_Bitmap + * FT_Outline_Render + * FT_Outline_Decompose + * FT_Outline_Funcs + * FT_Outline_MoveToFunc + * FT_Outline_LineToFunc + * FT_Outline_ConicToFunc + * FT_Outline_CubicToFunc + * + * FT_Orientation + * FT_Outline_Get_Orientation + * + * FT_OUTLINE_XXX + * + */ + + + /************************************************************************** + * + * @function: + * FT_Outline_Decompose + * + * @description: + * Walk over an outline's structure to decompose it into individual + * segments and Bezier arcs. This function also emits 'move to' + * operations to indicate the start of new contours in the outline. + * + * @input: + * outline :: + * A pointer to the source target. + * + * func_interface :: + * A table of 'emitters', i.e., function pointers called during + * decomposition to indicate path operations. + * + * @inout: + * user :: + * A typeless pointer that is passed to each emitter during the + * decomposition. It can be used to store the state during the + * decomposition. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * A contour that contains a single point only is represented by a 'move + * to' operation followed by 'line to' to the same point. In most cases, + * it is best to filter this out before using the outline for stroking + * purposes (otherwise it would result in a visible dot when round caps + * are used). + * + * Similarly, the function returns success for an empty outline also + * (doing nothing, this is, not calling any emitter); if necessary, you + * should filter this out, too. + */ FT_EXPORT( FT_Error ) FT_Outline_Decompose( FT_Outline* outline, const FT_Outline_Funcs* func_interface, void* user ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Outline_New */ - /* */ - /* <Description> */ - /* Create a new outline of a given size. */ - /* */ - /* <Input> */ - /* library :: A handle to the library object from where the */ - /* outline is allocated. Note however that the new */ - /* outline will *not* necessarily be *freed*, when */ - /* destroying the library, by @FT_Done_FreeType. */ - /* */ - /* numPoints :: The maximum number of points within the outline. */ - /* Must be smaller than or equal to 0xFFFF (65535). */ - /* */ - /* numContours :: The maximum number of contours within the outline. */ - /* This value must be in the range 0 to `numPoints'. */ - /* */ - /* <Output> */ - /* anoutline :: A handle to the new outline. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* The reason why this function takes a `library' parameter is simply */ - /* to use the library's memory allocator. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Outline_New + * + * @description: + * Create a new outline of a given size. + * + * @input: + * library :: + * A handle to the library object from where the outline is allocated. + * Note however that the new outline will **not** necessarily be + * **freed**, when destroying the library, by @FT_Done_FreeType. + * + * numPoints :: + * The maximum number of points within the outline. Must be smaller + * than or equal to 0xFFFF (65535). + * + * numContours :: + * The maximum number of contours within the outline. This value must + * be in the range 0 to `numPoints`. + * + * @output: + * anoutline :: + * A handle to the new outline. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The reason why this function takes a `library` parameter is simply to + * use the library's memory allocator. + */ FT_EXPORT( FT_Error ) FT_Outline_New( FT_Library library, FT_UInt numPoints, @@ -162,372 +166,378 @@ FT_BEGIN_HEADER FT_Outline *anoutline ); - FT_EXPORT( FT_Error ) - FT_Outline_New_Internal( FT_Memory memory, - FT_UInt numPoints, - FT_Int numContours, - FT_Outline *anoutline ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Outline_Done */ - /* */ - /* <Description> */ - /* Destroy an outline created with @FT_Outline_New. */ - /* */ - /* <Input> */ - /* library :: A handle of the library object used to allocate the */ - /* outline. */ - /* */ - /* outline :: A pointer to the outline object to be discarded. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* If the outline's `owner' field is not set, only the outline */ - /* descriptor will be released. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Outline_Done + * + * @description: + * Destroy an outline created with @FT_Outline_New. + * + * @input: + * library :: + * A handle of the library object used to allocate the outline. + * + * outline :: + * A pointer to the outline object to be discarded. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * If the outline's 'owner' field is not set, only the outline descriptor + * will be released. + */ FT_EXPORT( FT_Error ) FT_Outline_Done( FT_Library library, FT_Outline* outline ); - FT_EXPORT( FT_Error ) - FT_Outline_Done_Internal( FT_Memory memory, - FT_Outline* outline ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Outline_Check */ - /* */ - /* <Description> */ - /* Check the contents of an outline descriptor. */ - /* */ - /* <Input> */ - /* outline :: A handle to a source outline. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* An empty outline, or an outline with a single point only is also */ - /* valid. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Outline_Check + * + * @description: + * Check the contents of an outline descriptor. + * + * @input: + * outline :: + * A handle to a source outline. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * An empty outline, or an outline with a single point only is also + * valid. + */ FT_EXPORT( FT_Error ) FT_Outline_Check( FT_Outline* outline ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Outline_Get_CBox */ - /* */ - /* <Description> */ - /* Return an outline's `control box'. The control box encloses all */ - /* the outline's points, including Bezier control points. Though it */ - /* coincides with the exact bounding box for most glyphs, it can be */ - /* slightly larger in some situations (like when rotating an outline */ - /* that contains Bezier outside arcs). */ - /* */ - /* Computing the control box is very fast, while getting the bounding */ - /* box can take much more time as it needs to walk over all segments */ - /* and arcs in the outline. To get the latter, you can use the */ - /* `ftbbox' component, which is dedicated to this single task. */ - /* */ - /* <Input> */ - /* outline :: A pointer to the source outline descriptor. */ - /* */ - /* <Output> */ - /* acbox :: The outline's control box. */ - /* */ - /* <Note> */ - /* See @FT_Glyph_Get_CBox for a discussion of tricky fonts. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Outline_Get_CBox + * + * @description: + * Return an outline's 'control box'. The control box encloses all the + * outline's points, including Bezier control points. Though it + * coincides with the exact bounding box for most glyphs, it can be + * slightly larger in some situations (like when rotating an outline that + * contains Bezier outside arcs). + * + * Computing the control box is very fast, while getting the bounding box + * can take much more time as it needs to walk over all segments and arcs + * in the outline. To get the latter, you can use the 'ftbbox' + * component, which is dedicated to this single task. + * + * @input: + * outline :: + * A pointer to the source outline descriptor. + * + * @output: + * acbox :: + * The outline's control box. + * + * @note: + * See @FT_Glyph_Get_CBox for a discussion of tricky fonts. + */ FT_EXPORT( void ) FT_Outline_Get_CBox( const FT_Outline* outline, FT_BBox *acbox ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Outline_Translate */ - /* */ - /* <Description> */ - /* Apply a simple translation to the points of an outline. */ - /* */ - /* <InOut> */ - /* outline :: A pointer to the target outline descriptor. */ - /* */ - /* <Input> */ - /* xOffset :: The horizontal offset. */ - /* */ - /* yOffset :: The vertical offset. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Outline_Translate + * + * @description: + * Apply a simple translation to the points of an outline. + * + * @inout: + * outline :: + * A pointer to the target outline descriptor. + * + * @input: + * xOffset :: + * The horizontal offset. + * + * yOffset :: + * The vertical offset. + */ FT_EXPORT( void ) FT_Outline_Translate( const FT_Outline* outline, FT_Pos xOffset, FT_Pos yOffset ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Outline_Copy */ - /* */ - /* <Description> */ - /* Copy an outline into another one. Both objects must have the */ - /* same sizes (number of points & number of contours) when this */ - /* function is called. */ - /* */ - /* <Input> */ - /* source :: A handle to the source outline. */ - /* */ - /* <Output> */ - /* target :: A handle to the target outline. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Outline_Copy + * + * @description: + * Copy an outline into another one. Both objects must have the same + * sizes (number of points & number of contours) when this function is + * called. + * + * @input: + * source :: + * A handle to the source outline. + * + * @output: + * target :: + * A handle to the target outline. + * + * @return: + * FreeType error code. 0~means success. + */ FT_EXPORT( FT_Error ) FT_Outline_Copy( const FT_Outline* source, FT_Outline *target ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Outline_Transform */ - /* */ - /* <Description> */ - /* Apply a simple 2x2 matrix to all of an outline's points. Useful */ - /* for applying rotations, slanting, flipping, etc. */ - /* */ - /* <InOut> */ - /* outline :: A pointer to the target outline descriptor. */ - /* */ - /* <Input> */ - /* matrix :: A pointer to the transformation matrix. */ - /* */ - /* <Note> */ - /* You can use @FT_Outline_Translate if you need to translate the */ - /* outline's points. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Outline_Transform + * + * @description: + * Apply a simple 2x2 matrix to all of an outline's points. Useful for + * applying rotations, slanting, flipping, etc. + * + * @inout: + * outline :: + * A pointer to the target outline descriptor. + * + * @input: + * matrix :: + * A pointer to the transformation matrix. + * + * @note: + * You can use @FT_Outline_Translate if you need to translate the + * outline's points. + */ FT_EXPORT( void ) FT_Outline_Transform( const FT_Outline* outline, const FT_Matrix* matrix ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Outline_Embolden */ - /* */ - /* <Description> */ - /* Embolden an outline. The new outline will be at most 4~times */ - /* `strength' pixels wider and higher. You may think of the left and */ - /* bottom borders as unchanged. */ - /* */ - /* Negative `strength' values to reduce the outline thickness are */ - /* possible also. */ - /* */ - /* <InOut> */ - /* outline :: A handle to the target outline. */ - /* */ - /* <Input> */ - /* strength :: How strong the glyph is emboldened. Expressed in */ - /* 26.6 pixel format. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* The used algorithm to increase or decrease the thickness of the */ - /* glyph doesn't change the number of points; this means that certain */ - /* situations like acute angles or intersections are sometimes */ - /* handled incorrectly. */ - /* */ - /* If you need `better' metrics values you should call */ - /* @FT_Outline_Get_CBox or @FT_Outline_Get_BBox. */ - /* */ - /* Example call: */ - /* */ - /* { */ - /* FT_Load_Glyph( face, index, FT_LOAD_DEFAULT ); */ - /* if ( face->glyph->format == FT_GLYPH_FORMAT_OUTLINE ) */ - /* FT_Outline_Embolden( &face->glyph->outline, strength ); */ - /* } */ - /* */ - /* To get meaningful results, font scaling values must be set with */ - /* functions like @FT_Set_Char_Size before calling FT_Render_Glyph. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Outline_Embolden + * + * @description: + * Embolden an outline. The new outline will be at most 4~times + * `strength` pixels wider and higher. You may think of the left and + * bottom borders as unchanged. + * + * Negative `strength` values to reduce the outline thickness are + * possible also. + * + * @inout: + * outline :: + * A handle to the target outline. + * + * @input: + * strength :: + * How strong the glyph is emboldened. Expressed in 26.6 pixel format. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The used algorithm to increase or decrease the thickness of the glyph + * doesn't change the number of points; this means that certain + * situations like acute angles or intersections are sometimes handled + * incorrectly. + * + * If you need 'better' metrics values you should call + * @FT_Outline_Get_CBox or @FT_Outline_Get_BBox. + * + * To get meaningful results, font scaling values must be set with + * functions like @FT_Set_Char_Size before calling FT_Render_Glyph. + * + * @example: + * ``` + * FT_Load_Glyph( face, index, FT_LOAD_DEFAULT ); + * + * if ( face->glyph->format == FT_GLYPH_FORMAT_OUTLINE ) + * FT_Outline_Embolden( &face->glyph->outline, strength ); + * ``` + * + */ FT_EXPORT( FT_Error ) FT_Outline_Embolden( FT_Outline* outline, FT_Pos strength ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Outline_EmboldenXY */ - /* */ - /* <Description> */ - /* Embolden an outline. The new outline will be `xstrength' pixels */ - /* wider and `ystrength' pixels higher. Otherwise, it is similar to */ - /* @FT_Outline_Embolden, which uses the same strength in both */ - /* directions. */ - /* */ - /* <Since> */ - /* 2.4.10 */ - /* */ + /************************************************************************** + * + * @function: + * FT_Outline_EmboldenXY + * + * @description: + * Embolden an outline. The new outline will be `xstrength` pixels wider + * and `ystrength` pixels higher. Otherwise, it is similar to + * @FT_Outline_Embolden, which uses the same strength in both directions. + * + * @since: + * 2.4.10 + */ FT_EXPORT( FT_Error ) FT_Outline_EmboldenXY( FT_Outline* outline, FT_Pos xstrength, FT_Pos ystrength ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Outline_Reverse */ - /* */ - /* <Description> */ - /* Reverse the drawing direction of an outline. This is used to */ - /* ensure consistent fill conventions for mirrored glyphs. */ - /* */ - /* <InOut> */ - /* outline :: A pointer to the target outline descriptor. */ - /* */ - /* <Note> */ - /* This function toggles the bit flag @FT_OUTLINE_REVERSE_FILL in */ - /* the outline's `flags' field. */ - /* */ - /* It shouldn't be used by a normal client application, unless it */ - /* knows what it is doing. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Outline_Reverse + * + * @description: + * Reverse the drawing direction of an outline. This is used to ensure + * consistent fill conventions for mirrored glyphs. + * + * @inout: + * outline :: + * A pointer to the target outline descriptor. + * + * @note: + * This function toggles the bit flag @FT_OUTLINE_REVERSE_FILL in the + * outline's `flags` field. + * + * It shouldn't be used by a normal client application, unless it knows + * what it is doing. + */ FT_EXPORT( void ) FT_Outline_Reverse( FT_Outline* outline ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Outline_Get_Bitmap */ - /* */ - /* <Description> */ - /* Render an outline within a bitmap. The outline's image is simply */ - /* OR-ed to the target bitmap. */ - /* */ - /* <Input> */ - /* library :: A handle to a FreeType library object. */ - /* */ - /* outline :: A pointer to the source outline descriptor. */ - /* */ - /* <InOut> */ - /* abitmap :: A pointer to the target bitmap descriptor. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* This function does NOT CREATE the bitmap, it only renders an */ - /* outline image within the one you pass to it! Consequently, the */ - /* various fields in `abitmap' should be set accordingly. */ - /* */ - /* It will use the raster corresponding to the default glyph format. */ - /* */ - /* The value of the `num_grays' field in `abitmap' is ignored. If */ - /* you select the gray-level rasterizer, and you want less than 256 */ - /* gray levels, you have to use @FT_Outline_Render directly. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Outline_Get_Bitmap + * + * @description: + * Render an outline within a bitmap. The outline's image is simply + * OR-ed to the target bitmap. + * + * @input: + * library :: + * A handle to a FreeType library object. + * + * outline :: + * A pointer to the source outline descriptor. + * + * @inout: + * abitmap :: + * A pointer to the target bitmap descriptor. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function does **not create** the bitmap, it only renders an + * outline image within the one you pass to it! Consequently, the + * various fields in `abitmap` should be set accordingly. + * + * It will use the raster corresponding to the default glyph format. + * + * The value of the `num_grays` field in `abitmap` is ignored. If you + * select the gray-level rasterizer, and you want less than 256 gray + * levels, you have to use @FT_Outline_Render directly. + */ FT_EXPORT( FT_Error ) FT_Outline_Get_Bitmap( FT_Library library, FT_Outline* outline, const FT_Bitmap *abitmap ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Outline_Render */ - /* */ - /* <Description> */ - /* Render an outline within a bitmap using the current scan-convert. */ - /* This function uses an @FT_Raster_Params structure as an argument, */ - /* allowing advanced features like direct composition, translucency, */ - /* etc. */ - /* */ - /* <Input> */ - /* library :: A handle to a FreeType library object. */ - /* */ - /* outline :: A pointer to the source outline descriptor. */ - /* */ - /* <InOut> */ - /* params :: A pointer to an @FT_Raster_Params structure used to */ - /* describe the rendering operation. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* You should know what you are doing and how @FT_Raster_Params works */ - /* to use this function. */ - /* */ - /* The field `params.source' will be set to `outline' before the scan */ - /* converter is called, which means that the value you give to it is */ - /* actually ignored. */ - /* */ - /* The gray-level rasterizer always uses 256 gray levels. If you */ - /* want less gray levels, you have to provide your own span callback. */ - /* See the @FT_RASTER_FLAG_DIRECT value of the `flags' field in the */ - /* @FT_Raster_Params structure for more details. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Outline_Render + * + * @description: + * Render an outline within a bitmap using the current scan-convert. + * This function uses an @FT_Raster_Params structure as an argument, + * allowing advanced features like direct composition, translucency, etc. + * + * @input: + * library :: + * A handle to a FreeType library object. + * + * outline :: + * A pointer to the source outline descriptor. + * + * @inout: + * params :: + * A pointer to an @FT_Raster_Params structure used to describe the + * rendering operation. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * You should know what you are doing and how @FT_Raster_Params works to + * use this function. + * + * The field `params.source` will be set to `outline` before the scan + * converter is called, which means that the value you give to it is + * actually ignored. + * + * The gray-level rasterizer always uses 256 gray levels. If you want + * less gray levels, you have to provide your own span callback. See the + * @FT_RASTER_FLAG_DIRECT value of the `flags` field in the + * @FT_Raster_Params structure for more details. + */ FT_EXPORT( FT_Error ) FT_Outline_Render( FT_Library library, FT_Outline* outline, FT_Raster_Params* params ); - /************************************************************************** - * - * @enum: - * FT_Orientation - * - * @description: - * A list of values used to describe an outline's contour orientation. - * - * The TrueType and PostScript specifications use different conventions - * to determine whether outline contours should be filled or unfilled. - * - * @values: - * FT_ORIENTATION_TRUETYPE :: - * According to the TrueType specification, clockwise contours must - * be filled, and counter-clockwise ones must be unfilled. - * - * FT_ORIENTATION_POSTSCRIPT :: - * According to the PostScript specification, counter-clockwise contours - * must be filled, and clockwise ones must be unfilled. - * - * FT_ORIENTATION_FILL_RIGHT :: - * This is identical to @FT_ORIENTATION_TRUETYPE, but is used to - * remember that in TrueType, everything that is to the right of - * the drawing direction of a contour must be filled. - * - * FT_ORIENTATION_FILL_LEFT :: - * This is identical to @FT_ORIENTATION_POSTSCRIPT, but is used to - * remember that in PostScript, everything that is to the left of - * the drawing direction of a contour must be filled. - * - * FT_ORIENTATION_NONE :: - * The orientation cannot be determined. That is, different parts of - * the glyph have different orientation. - * - */ + /************************************************************************** + * + * @enum: + * FT_Orientation + * + * @description: + * A list of values used to describe an outline's contour orientation. + * + * The TrueType and PostScript specifications use different conventions + * to determine whether outline contours should be filled or unfilled. + * + * @values: + * FT_ORIENTATION_TRUETYPE :: + * According to the TrueType specification, clockwise contours must be + * filled, and counter-clockwise ones must be unfilled. + * + * FT_ORIENTATION_POSTSCRIPT :: + * According to the PostScript specification, counter-clockwise + * contours must be filled, and clockwise ones must be unfilled. + * + * FT_ORIENTATION_FILL_RIGHT :: + * This is identical to @FT_ORIENTATION_TRUETYPE, but is used to + * remember that in TrueType, everything that is to the right of the + * drawing direction of a contour must be filled. + * + * FT_ORIENTATION_FILL_LEFT :: + * This is identical to @FT_ORIENTATION_POSTSCRIPT, but is used to + * remember that in PostScript, everything that is to the left of the + * drawing direction of a contour must be filled. + * + * FT_ORIENTATION_NONE :: + * The orientation cannot be determined. That is, different parts of + * the glyph have different orientation. + * + */ typedef enum FT_Orientation_ { FT_ORIENTATION_TRUETYPE = 0, @@ -539,33 +549,34 @@ FT_BEGIN_HEADER } FT_Orientation; - /************************************************************************** - * - * @function: - * FT_Outline_Get_Orientation - * - * @description: - * This function analyzes a glyph outline and tries to compute its - * fill orientation (see @FT_Orientation). This is done by integrating - * the total area covered by the outline. The positive integral - * corresponds to the clockwise orientation and @FT_ORIENTATION_POSTSCRIPT - * is returned. The negative integral corresponds to the counter-clockwise - * orientation and @FT_ORIENTATION_TRUETYPE is returned. - * - * Note that this will return @FT_ORIENTATION_TRUETYPE for empty - * outlines. - * - * @input: - * outline :: - * A handle to the source outline. - * - * @return: - * The orientation. - * - */ + /************************************************************************** + * + * @function: + * FT_Outline_Get_Orientation + * + * @description: + * This function analyzes a glyph outline and tries to compute its fill + * orientation (see @FT_Orientation). This is done by integrating the + * total area covered by the outline. The positive integral corresponds + * to the clockwise orientation and @FT_ORIENTATION_POSTSCRIPT is + * returned. The negative integral corresponds to the counter-clockwise + * orientation and @FT_ORIENTATION_TRUETYPE is returned. + * + * Note that this will return @FT_ORIENTATION_TRUETYPE for empty + * outlines. + * + * @input: + * outline :: + * A handle to the source outline. + * + * @return: + * The orientation. + * + */ FT_EXPORT( FT_Orientation ) FT_Outline_Get_Orientation( FT_Outline* outline ); + /* */ diff --git a/sdk/lib/3rdparty/freetype/include/freetype/ftparams.h b/sdk/lib/3rdparty/freetype/include/freetype/ftparams.h index 5a9006c505dac..c374ee2f2ffb7 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/ftparams.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/ftparams.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftparams.h */ -/* */ -/* FreeType API for possible FT_Parameter tags (specification only). */ -/* */ -/* Copyright 2017-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftparams.h + * + * FreeType API for possible FT_Parameter tags (specification only). + * + * Copyright (C) 2017-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTPARAMS_H_ @@ -51,16 +51,16 @@ FT_BEGIN_HEADER */ - /*************************************************************************** + /************************************************************************** * - * @constant: + * @enum: * FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_FAMILY * * @description: * A tag for @FT_Parameter to make @FT_Open_Face ignore typographic - * family names in the `name' table (introduced in OpenType version - * 1.4). Use this for backward compatibility with legacy systems that - * have a four-faces-per-family restriction. + * family names in the 'name' table (introduced in OpenType version 1.4). + * Use this for backward compatibility with legacy systems that have a + * four-faces-per-family restriction. * * @since: * 2.8 @@ -75,14 +75,14 @@ FT_BEGIN_HEADER FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_FAMILY - /*************************************************************************** + /************************************************************************** * - * @constant: + * @enum: * FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_SUBFAMILY * * @description: * A tag for @FT_Parameter to make @FT_Open_Face ignore typographic - * subfamily names in the `name' table (introduced in OpenType version + * subfamily names in the 'name' table (introduced in OpenType version * 1.4). Use this for backward compatibility with legacy systems that * have a four-faces-per-family restriction. * @@ -99,9 +99,9 @@ FT_BEGIN_HEADER FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_SUBFAMILY - /*************************************************************************** + /************************************************************************** * - * @constant: + * @enum: * FT_PARAM_TAG_INCREMENTAL * * @description: @@ -115,14 +115,14 @@ FT_BEGIN_HEADER /************************************************************************** * - * @constant: + * @enum: * FT_PARAM_TAG_LCD_FILTER_WEIGHTS * * @description: * An @FT_Parameter tag to be used with @FT_Face_Properties. The * corresponding argument specifies the five LCD filter weights for a - * given face (if using @FT_LOAD_TARGET_LCD, for example), overriding - * the global default values or the values set up with + * given face (if using @FT_LOAD_TARGET_LCD, for example), overriding the + * global default values or the values set up with * @FT_Library_SetLcdFilterWeights. * * @since: @@ -135,14 +135,13 @@ FT_BEGIN_HEADER /************************************************************************** * - * @constant: + * @enum: * FT_PARAM_TAG_RANDOM_SEED * * @description: * An @FT_Parameter tag to be used with @FT_Face_Properties. The * corresponding 32bit signed integer argument overrides the font - * driver's random seed value with a face-specific one; see - * @random-seed. + * driver's random seed value with a face-specific one; see @random-seed. * * @since: * 2.8 @@ -154,7 +153,7 @@ FT_BEGIN_HEADER /************************************************************************** * - * @constant: + * @enum: * FT_PARAM_TAG_STEM_DARKENING * * @description: @@ -163,10 +162,10 @@ FT_BEGIN_HEADER * darkening, overriding the global default values or the values set up * with @FT_Property_Set (see @no-stem-darkening). * - * This is a passive setting that only takes effect if the font driver - * or autohinter honors it, which the CFF, Type~1, and CID drivers - * always do, but the autohinter only in `light' hinting mode (as of - * version 2.9). + * This is a passive setting that only takes effect if the font driver or + * autohinter honors it, which the CFF, Type~1, and CID drivers always + * do, but the autohinter only in 'light' hinting mode (as of version + * 2.9). * * @since: * 2.8 @@ -176,19 +175,19 @@ FT_BEGIN_HEADER FT_MAKE_TAG( 'd', 'a', 'r', 'k' ) - /*************************************************************************** - * - * @constant: - * FT_PARAM_TAG_UNPATENTED_HINTING - * - * @description: - * Deprecated, no effect. - * - * Previously: A constant used as the tag of an @FT_Parameter structure to - * indicate that unpatented methods only should be used by the TrueType - * bytecode interpreter for a typeface opened by @FT_Open_Face. - * - */ + /************************************************************************** + * + * @enum: + * FT_PARAM_TAG_UNPATENTED_HINTING + * + * @description: + * Deprecated, no effect. + * + * Previously: A constant used as the tag of an @FT_Parameter structure + * to indicate that unpatented methods only should be used by the + * TrueType bytecode interpreter for a typeface opened by @FT_Open_Face. + * + */ #define FT_PARAM_TAG_UNPATENTED_HINTING \ FT_MAKE_TAG( 'u', 'n', 'p', 'a' ) diff --git a/sdk/lib/3rdparty/freetype/include/freetype/ftpfr.h b/sdk/lib/3rdparty/freetype/include/freetype/ftpfr.h index ce60eb4a8adda..b4eca76eb7dad 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/ftpfr.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/ftpfr.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftpfr.h */ -/* */ -/* FreeType API for accessing PFR-specific data (specification only). */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftpfr.h + * + * FreeType API for accessing PFR-specific data (specification only). + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTPFR_H_ @@ -32,60 +32,61 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* <Section> */ - /* pfr_fonts */ - /* */ - /* <Title> */ - /* PFR Fonts */ - /* */ - /* <Abstract> */ - /* PFR/TrueDoc specific API. */ - /* */ - /* <Description> */ - /* This section contains the declaration of PFR-specific functions. */ - /* */ - /*************************************************************************/ - - - /********************************************************************** - * - * @function: - * FT_Get_PFR_Metrics - * - * @description: - * Return the outline and metrics resolutions of a given PFR face. - * - * @input: - * face :: Handle to the input face. It can be a non-PFR face. - * - * @output: - * aoutline_resolution :: - * Outline resolution. This is equivalent to `face->units_per_EM' - * for non-PFR fonts. Optional (parameter can be NULL). - * - * ametrics_resolution :: - * Metrics resolution. This is equivalent to `outline_resolution' - * for non-PFR fonts. Optional (parameter can be NULL). - * - * ametrics_x_scale :: - * A 16.16 fixed-point number used to scale distance expressed - * in metrics units to device sub-pixels. This is equivalent to - * `face->size->x_scale', but for metrics only. Optional (parameter - * can be NULL). - * - * ametrics_y_scale :: - * Same as `ametrics_x_scale' but for the vertical direction. - * optional (parameter can be NULL). - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * If the input face is not a PFR, this function will return an error. - * However, in all cases, it will return valid values. - */ + /************************************************************************** + * + * @section: + * pfr_fonts + * + * @title: + * PFR Fonts + * + * @abstract: + * PFR/TrueDoc-specific API. + * + * @description: + * This section contains the declaration of PFR-specific functions. + * + */ + + + /************************************************************************** + * + * @function: + * FT_Get_PFR_Metrics + * + * @description: + * Return the outline and metrics resolutions of a given PFR face. + * + * @input: + * face :: + * Handle to the input face. It can be a non-PFR face. + * + * @output: + * aoutline_resolution :: + * Outline resolution. This is equivalent to `face->units_per_EM` for + * non-PFR fonts. Optional (parameter can be `NULL`). + * + * ametrics_resolution :: + * Metrics resolution. This is equivalent to `outline_resolution` for + * non-PFR fonts. Optional (parameter can be `NULL`). + * + * ametrics_x_scale :: + * A 16.16 fixed-point number used to scale distance expressed in + * metrics units to device subpixels. This is equivalent to + * `face->size->x_scale`, but for metrics only. Optional (parameter + * can be `NULL`). + * + * ametrics_y_scale :: + * Same as `ametrics_x_scale` but for the vertical direction. + * optional (parameter can be `NULL`). + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * If the input face is not a PFR, this function will return an error. + * However, in all cases, it will return valid values. + */ FT_EXPORT( FT_Error ) FT_Get_PFR_Metrics( FT_Face face, FT_UInt *aoutline_resolution, @@ -94,37 +95,41 @@ FT_BEGIN_HEADER FT_Fixed *ametrics_y_scale ); - /********************************************************************** - * - * @function: - * FT_Get_PFR_Kerning - * - * @description: - * Return the kerning pair corresponding to two glyphs in a PFR face. - * The distance is expressed in metrics units, unlike the result of - * @FT_Get_Kerning. - * - * @input: - * face :: A handle to the input face. - * - * left :: Index of the left glyph. - * - * right :: Index of the right glyph. - * - * @output: - * avector :: A kerning vector. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * This function always return distances in original PFR metrics - * units. This is unlike @FT_Get_Kerning with the @FT_KERNING_UNSCALED - * mode, which always returns distances converted to outline units. - * - * You can use the value of the `x_scale' and `y_scale' parameters - * returned by @FT_Get_PFR_Metrics to scale these to device sub-pixels. - */ + /************************************************************************** + * + * @function: + * FT_Get_PFR_Kerning + * + * @description: + * Return the kerning pair corresponding to two glyphs in a PFR face. + * The distance is expressed in metrics units, unlike the result of + * @FT_Get_Kerning. + * + * @input: + * face :: + * A handle to the input face. + * + * left :: + * Index of the left glyph. + * + * right :: + * Index of the right glyph. + * + * @output: + * avector :: + * A kerning vector. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function always return distances in original PFR metrics units. + * This is unlike @FT_Get_Kerning with the @FT_KERNING_UNSCALED mode, + * which always returns distances converted to outline units. + * + * You can use the value of the `x_scale` and `y_scale` parameters + * returned by @FT_Get_PFR_Metrics to scale these to device subpixels. + */ FT_EXPORT( FT_Error ) FT_Get_PFR_Kerning( FT_Face face, FT_UInt left, @@ -132,30 +137,33 @@ FT_BEGIN_HEADER FT_Vector *avector ); - /********************************************************************** - * - * @function: - * FT_Get_PFR_Advance - * - * @description: - * Return a given glyph advance, expressed in original metrics units, - * from a PFR font. - * - * @input: - * face :: A handle to the input face. - * - * gindex :: The glyph index. - * - * @output: - * aadvance :: The glyph advance in metrics units. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * You can use the `x_scale' or `y_scale' results of @FT_Get_PFR_Metrics - * to convert the advance to device sub-pixels (i.e., 1/64th of pixels). - */ + /************************************************************************** + * + * @function: + * FT_Get_PFR_Advance + * + * @description: + * Return a given glyph advance, expressed in original metrics units, + * from a PFR font. + * + * @input: + * face :: + * A handle to the input face. + * + * gindex :: + * The glyph index. + * + * @output: + * aadvance :: + * The glyph advance in metrics units. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * You can use the `x_scale` or `y_scale` results of @FT_Get_PFR_Metrics + * to convert the advance to device subpixels (i.e., 1/64th of pixels). + */ FT_EXPORT( FT_Error ) FT_Get_PFR_Advance( FT_Face face, FT_UInt gindex, diff --git a/sdk/lib/3rdparty/freetype/include/freetype/ftrender.h b/sdk/lib/3rdparty/freetype/include/freetype/ftrender.h index fa8ad22b9878b..a01c774272ec8 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/ftrender.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/ftrender.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftrender.h */ -/* */ -/* FreeType renderer modules public interface (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftrender.h + * + * FreeType renderer modules public interface (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTRENDER_H_ @@ -28,12 +28,12 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* <Section> */ - /* module_management */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * @section: + * module_management + * + */ /* create a new glyph object */ @@ -116,32 +116,38 @@ FT_BEGIN_HEADER #define FTRenderer_setMode FT_Renderer_SetModeFunc - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Renderer_Class */ - /* */ - /* <Description> */ - /* The renderer module class descriptor. */ - /* */ - /* <Fields> */ - /* root :: The root @FT_Module_Class fields. */ - /* */ - /* glyph_format :: The glyph image format this renderer handles. */ - /* */ - /* render_glyph :: A method used to render the image that is in a */ - /* given glyph slot into a bitmap. */ - /* */ - /* transform_glyph :: A method used to transform the image that is in */ - /* a given glyph slot. */ - /* */ - /* get_glyph_cbox :: A method used to access the glyph's cbox. */ - /* */ - /* set_mode :: A method used to pass additional parameters. */ - /* */ - /* raster_class :: For @FT_GLYPH_FORMAT_OUTLINE renderers only. */ - /* This is a pointer to its raster's class. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_Renderer_Class + * + * @description: + * The renderer module class descriptor. + * + * @fields: + * root :: + * The root @FT_Module_Class fields. + * + * glyph_format :: + * The glyph image format this renderer handles. + * + * render_glyph :: + * A method used to render the image that is in a given glyph slot into + * a bitmap. + * + * transform_glyph :: + * A method used to transform the image that is in a given glyph slot. + * + * get_glyph_cbox :: + * A method used to access the glyph's cbox. + * + * set_mode :: + * A method used to pass additional parameters. + * + * raster_class :: + * For @FT_GLYPH_FORMAT_OUTLINE renderers only. This is a pointer to + * its raster's class. + */ typedef struct FT_Renderer_Class_ { FT_Module_Class root; @@ -158,64 +164,70 @@ FT_BEGIN_HEADER } FT_Renderer_Class; - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_Renderer */ - /* */ - /* <Description> */ - /* Retrieve the current renderer for a given glyph format. */ - /* */ - /* <Input> */ - /* library :: A handle to the library object. */ - /* */ - /* format :: The glyph format. */ - /* */ - /* <Return> */ - /* A renderer handle. 0~if none found. */ - /* */ - /* <Note> */ - /* An error will be returned if a module already exists by that name, */ - /* or if the module requires a version of FreeType that is too great. */ - /* */ - /* To add a new renderer, simply use @FT_Add_Module. To retrieve a */ - /* renderer by its name, use @FT_Get_Module. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Get_Renderer + * + * @description: + * Retrieve the current renderer for a given glyph format. + * + * @input: + * library :: + * A handle to the library object. + * + * format :: + * The glyph format. + * + * @return: + * A renderer handle. 0~if none found. + * + * @note: + * An error will be returned if a module already exists by that name, or + * if the module requires a version of FreeType that is too great. + * + * To add a new renderer, simply use @FT_Add_Module. To retrieve a + * renderer by its name, use @FT_Get_Module. + */ FT_EXPORT( FT_Renderer ) FT_Get_Renderer( FT_Library library, FT_Glyph_Format format ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Set_Renderer */ - /* */ - /* <Description> */ - /* Set the current renderer to use, and set additional mode. */ - /* */ - /* <InOut> */ - /* library :: A handle to the library object. */ - /* */ - /* <Input> */ - /* renderer :: A handle to the renderer object. */ - /* */ - /* num_params :: The number of additional parameters. */ - /* */ - /* parameters :: Additional parameters. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* In case of success, the renderer will be used to convert glyph */ - /* images in the renderer's known format into bitmaps. */ - /* */ - /* This doesn't change the current renderer for other formats. */ - /* */ - /* Currently, no FreeType renderer module uses `parameters'; you */ - /* should thus always pass NULL as the value. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Set_Renderer + * + * @description: + * Set the current renderer to use, and set additional mode. + * + * @inout: + * library :: + * A handle to the library object. + * + * @input: + * renderer :: + * A handle to the renderer object. + * + * num_params :: + * The number of additional parameters. + * + * parameters :: + * Additional parameters. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * In case of success, the renderer will be used to convert glyph images + * in the renderer's known format into bitmaps. + * + * This doesn't change the current renderer for other formats. + * + * Currently, no FreeType renderer module uses `parameters`; you should + * thus always pass `NULL` as the value. + */ FT_EXPORT( FT_Error ) FT_Set_Renderer( FT_Library library, FT_Renderer renderer, diff --git a/sdk/lib/3rdparty/freetype/include/freetype/ftsizes.h b/sdk/lib/3rdparty/freetype/include/freetype/ftsizes.h index 72cb08bf2a764..6c63cef2bfa99 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/ftsizes.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/ftsizes.h @@ -1,28 +1,28 @@ -/***************************************************************************/ -/* */ -/* ftsizes.h */ -/* */ -/* FreeType size objects management (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* Typical application would normally not need to use these functions. */ - /* However, they have been placed in a public API for the rare cases */ - /* where they are needed. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * ftsizes.h + * + * FreeType size objects management (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /************************************************************************** + * + * Typical application would normally not need to use these functions. + * However, they have been placed in a public API for the rare cases where + * they are needed. + * + */ #ifndef FTSIZES_H_ @@ -42,109 +42,110 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* <Section> */ - /* sizes_management */ - /* */ - /* <Title> */ - /* Size Management */ - /* */ - /* <Abstract> */ - /* Managing multiple sizes per face. */ - /* */ - /* <Description> */ - /* When creating a new face object (e.g., with @FT_New_Face), an */ - /* @FT_Size object is automatically created and used to store all */ - /* pixel-size dependent information, available in the `face->size' */ - /* field. */ - /* */ - /* It is however possible to create more sizes for a given face, */ - /* mostly in order to manage several character pixel sizes of the */ - /* same font family and style. See @FT_New_Size and @FT_Done_Size. */ - /* */ - /* Note that @FT_Set_Pixel_Sizes and @FT_Set_Char_Size only */ - /* modify the contents of the current `active' size; you thus need */ - /* to use @FT_Activate_Size to change it. */ - /* */ - /* 99% of applications won't need the functions provided here, */ - /* especially if they use the caching sub-system, so be cautious */ - /* when using these. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_New_Size */ - /* */ - /* <Description> */ - /* Create a new size object from a given face object. */ - /* */ - /* <Input> */ - /* face :: A handle to a parent face object. */ - /* */ - /* <Output> */ - /* asize :: A handle to a new size object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* You need to call @FT_Activate_Size in order to select the new size */ - /* for upcoming calls to @FT_Set_Pixel_Sizes, @FT_Set_Char_Size, */ - /* @FT_Load_Glyph, @FT_Load_Char, etc. */ - /* */ + /************************************************************************** + * + * @section: + * sizes_management + * + * @title: + * Size Management + * + * @abstract: + * Managing multiple sizes per face. + * + * @description: + * When creating a new face object (e.g., with @FT_New_Face), an @FT_Size + * object is automatically created and used to store all pixel-size + * dependent information, available in the `face->size` field. + * + * It is however possible to create more sizes for a given face, mostly + * in order to manage several character pixel sizes of the same font + * family and style. See @FT_New_Size and @FT_Done_Size. + * + * Note that @FT_Set_Pixel_Sizes and @FT_Set_Char_Size only modify the + * contents of the current 'active' size; you thus need to use + * @FT_Activate_Size to change it. + * + * 99% of applications won't need the functions provided here, especially + * if they use the caching sub-system, so be cautious when using these. + * + */ + + + /************************************************************************** + * + * @function: + * FT_New_Size + * + * @description: + * Create a new size object from a given face object. + * + * @input: + * face :: + * A handle to a parent face object. + * + * @output: + * asize :: + * A handle to a new size object. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * You need to call @FT_Activate_Size in order to select the new size for + * upcoming calls to @FT_Set_Pixel_Sizes, @FT_Set_Char_Size, + * @FT_Load_Glyph, @FT_Load_Char, etc. + */ FT_EXPORT( FT_Error ) FT_New_Size( FT_Face face, FT_Size* size ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Done_Size */ - /* */ - /* <Description> */ - /* Discard a given size object. Note that @FT_Done_Face */ - /* automatically discards all size objects allocated with */ - /* @FT_New_Size. */ - /* */ - /* <Input> */ - /* size :: A handle to a target size object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Done_Size + * + * @description: + * Discard a given size object. Note that @FT_Done_Face automatically + * discards all size objects allocated with @FT_New_Size. + * + * @input: + * size :: + * A handle to a target size object. + * + * @return: + * FreeType error code. 0~means success. + */ FT_EXPORT( FT_Error ) FT_Done_Size( FT_Size size ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Activate_Size */ - /* */ - /* <Description> */ - /* Even though it is possible to create several size objects for a */ - /* given face (see @FT_New_Size for details), functions like */ - /* @FT_Load_Glyph or @FT_Load_Char only use the one that has been */ - /* activated last to determine the `current character pixel size'. */ - /* */ - /* This function can be used to `activate' a previously created size */ - /* object. */ - /* */ - /* <Input> */ - /* size :: A handle to a target size object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* If `face' is the size's parent face object, this function changes */ - /* the value of `face->size' to the input size handle. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Activate_Size + * + * @description: + * Even though it is possible to create several size objects for a given + * face (see @FT_New_Size for details), functions like @FT_Load_Glyph or + * @FT_Load_Char only use the one that has been activated last to + * determine the 'current character pixel size'. + * + * This function can be used to 'activate' a previously created size + * object. + * + * @input: + * size :: + * A handle to a target size object. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * If `face` is the size's parent face object, this function changes the + * value of `face->size` to the input size handle. + */ FT_EXPORT( FT_Error ) FT_Activate_Size( FT_Size size ); diff --git a/sdk/lib/3rdparty/freetype/include/freetype/ftsnames.h b/sdk/lib/3rdparty/freetype/include/freetype/ftsnames.h index 8eb8d70ff7f41..4d43602a42435 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/ftsnames.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/ftsnames.h @@ -1,22 +1,22 @@ -/***************************************************************************/ -/* */ -/* ftsnames.h */ -/* */ -/* Simple interface to access SFNT `name' tables (which are used */ -/* to hold font names, copyright info, notices, etc.) (specification). */ -/* */ -/* This is _not_ used to retrieve glyph names! */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftsnames.h + * + * Simple interface to access SFNT 'name' tables (which are used + * to hold font names, copyright info, notices, etc.) (specification). + * + * This is _not_ used to retrieve glyph names! + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTSNAMES_H_ @@ -37,72 +37,74 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* <Section> */ - /* sfnt_names */ - /* */ - /* <Title> */ - /* SFNT Names */ - /* */ - /* <Abstract> */ - /* Access the names embedded in TrueType and OpenType files. */ - /* */ - /* <Description> */ - /* The TrueType and OpenType specifications allow the inclusion of */ - /* a special names table (`name') in font files. This table contains */ - /* textual (and internationalized) information regarding the font, */ - /* like family name, copyright, version, etc. */ - /* */ - /* The definitions below are used to access them if available. */ - /* */ - /* Note that this has nothing to do with glyph names! */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_SfntName */ - /* */ - /* <Description> */ - /* A structure used to model an SFNT `name' table entry. */ - /* */ - /* <Fields> */ - /* platform_id :: The platform ID for `string'. */ - /* See @TT_PLATFORM_XXX for possible values. */ - /* */ - /* encoding_id :: The encoding ID for `string'. */ - /* See @TT_APPLE_ID_XXX, @TT_MAC_ID_XXX, */ - /* @TT_ISO_ID_XXX, @TT_MS_ID_XXX, and @TT_ADOBE_ID_XXX */ - /* for possible values. */ - /* */ - /* language_id :: The language ID for `string'. */ - /* See @TT_MAC_LANGID_XXX and @TT_MS_LANGID_XXX for */ - /* possible values. */ - /* */ - /* Registered OpenType values for `language_id' are */ - /* always smaller than 0x8000; values equal or larger */ - /* than 0x8000 usually indicate a language tag string */ - /* (introduced in OpenType version 1.6). Use function */ - /* @FT_Get_Sfnt_LangTag with `language_id' as its */ - /* argument to retrieve the associated language tag. */ - /* */ - /* name_id :: An identifier for `string'. */ - /* See @TT_NAME_ID_XXX for possible values. */ - /* */ - /* string :: The `name' string. Note that its format differs */ - /* depending on the (platform,encoding) pair, being */ - /* either a string of bytes (without a terminating */ - /* NULL byte) or containing UTF-16BE entities. */ - /* */ - /* string_len :: The length of `string' in bytes. */ - /* */ - /* <Note> */ - /* Please refer to the TrueType or OpenType specification for more */ - /* details. */ - /* */ + /************************************************************************** + * + * @section: + * sfnt_names + * + * @title: + * SFNT Names + * + * @abstract: + * Access the names embedded in TrueType and OpenType files. + * + * @description: + * The TrueType and OpenType specifications allow the inclusion of a + * special names table ('name') in font files. This table contains + * textual (and internationalized) information regarding the font, like + * family name, copyright, version, etc. + * + * The definitions below are used to access them if available. + * + * Note that this has nothing to do with glyph names! + * + */ + + + /************************************************************************** + * + * @struct: + * FT_SfntName + * + * @description: + * A structure used to model an SFNT 'name' table entry. + * + * @fields: + * platform_id :: + * The platform ID for `string`. See @TT_PLATFORM_XXX for possible + * values. + * + * encoding_id :: + * The encoding ID for `string`. See @TT_APPLE_ID_XXX, @TT_MAC_ID_XXX, + * @TT_ISO_ID_XXX, @TT_MS_ID_XXX, and @TT_ADOBE_ID_XXX for possible + * values. + * + * language_id :: + * The language ID for `string`. See @TT_MAC_LANGID_XXX and + * @TT_MS_LANGID_XXX for possible values. + * + * Registered OpenType values for `language_id` are always smaller than + * 0x8000; values equal or larger than 0x8000 usually indicate a + * language tag string (introduced in OpenType version 1.6). Use + * function @FT_Get_Sfnt_LangTag with `language_id` as its argument to + * retrieve the associated language tag. + * + * name_id :: + * An identifier for `string`. See @TT_NAME_ID_XXX for possible + * values. + * + * string :: + * The 'name' string. Note that its format differs depending on the + * (platform,encoding) pair, being either a string of bytes (without a + * terminating `NULL` byte) or containing UTF-16BE entities. + * + * string_len :: + * The length of `string` in bytes. + * + * @note: + * Please refer to the TrueType or OpenType specification for more + * details. + */ typedef struct FT_SfntName_ { FT_UShort platform_id; @@ -116,83 +118,95 @@ FT_BEGIN_HEADER } FT_SfntName; - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_Sfnt_Name_Count */ - /* */ - /* <Description> */ - /* Retrieve the number of name strings in the SFNT `name' table. */ - /* */ - /* <Input> */ - /* face :: A handle to the source face. */ - /* */ - /* <Return> */ - /* The number of strings in the `name' table. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Get_Sfnt_Name_Count + * + * @description: + * Retrieve the number of name strings in the SFNT 'name' table. + * + * @input: + * face :: + * A handle to the source face. + * + * @return: + * The number of strings in the 'name' table. + * + * @note: + * This function always returns an error if the config macro + * `TT_CONFIG_OPTION_SFNT_NAMES` is not defined in `ftoption.h`. + */ FT_EXPORT( FT_UInt ) FT_Get_Sfnt_Name_Count( FT_Face face ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_Sfnt_Name */ - /* */ - /* <Description> */ - /* Retrieve a string of the SFNT `name' table for a given index. */ - /* */ - /* <Input> */ - /* face :: A handle to the source face. */ - /* */ - /* idx :: The index of the `name' string. */ - /* */ - /* <Output> */ - /* aname :: The indexed @FT_SfntName structure. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* The `string' array returned in the `aname' structure is not */ - /* null-terminated. Note that you don't have to deallocate `string' */ - /* by yourself; FreeType takes care of it if you call @FT_Done_Face. */ - /* */ - /* Use @FT_Get_Sfnt_Name_Count to get the total number of available */ - /* `name' table entries, then do a loop until you get the right */ - /* platform, encoding, and name ID. */ - /* */ - /* `name' table format~1 entries can use language tags also, see */ - /* @FT_Get_Sfnt_LangTag. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Get_Sfnt_Name + * + * @description: + * Retrieve a string of the SFNT 'name' table for a given index. + * + * @input: + * face :: + * A handle to the source face. + * + * idx :: + * The index of the 'name' string. + * + * @output: + * aname :: + * The indexed @FT_SfntName structure. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The `string` array returned in the `aname` structure is not + * null-terminated. Note that you don't have to deallocate `string` by + * yourself; FreeType takes care of it if you call @FT_Done_Face. + * + * Use @FT_Get_Sfnt_Name_Count to get the total number of available + * 'name' table entries, then do a loop until you get the right platform, + * encoding, and name ID. + * + * 'name' table format~1 entries can use language tags also, see + * @FT_Get_Sfnt_LangTag. + * + * This function always returns an error if the config macro + * `TT_CONFIG_OPTION_SFNT_NAMES` is not defined in `ftoption.h`. + */ FT_EXPORT( FT_Error ) FT_Get_Sfnt_Name( FT_Face face, FT_UInt idx, FT_SfntName *aname ); - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_SfntLangTag */ - /* */ - /* <Description> */ - /* A structure to model a language tag entry from an SFNT `name' */ - /* table. */ - /* */ - /* <Fields> */ - /* string :: The language tag string, encoded in UTF-16BE */ - /* (without trailing NULL bytes). */ - /* */ - /* string_len :: The length of `string' in *bytes*. */ - /* */ - /* <Note> */ - /* Please refer to the TrueType or OpenType specification for more */ - /* details. */ - /* */ - /* <Since> */ - /* 2.8 */ - /* */ + /************************************************************************** + * + * @struct: + * FT_SfntLangTag + * + * @description: + * A structure to model a language tag entry from an SFNT 'name' table. + * + * @fields: + * string :: + * The language tag string, encoded in UTF-16BE (without trailing + * `NULL` bytes). + * + * string_len :: + * The length of `string` in **bytes**. + * + * @note: + * Please refer to the TrueType or OpenType specification for more + * details. + * + * @since: + * 2.8 + */ typedef struct FT_SfntLangTag_ { FT_Byte* string; /* this string is *not* null-terminated! */ @@ -201,41 +215,47 @@ FT_BEGIN_HEADER } FT_SfntLangTag; - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_Sfnt_LangTag */ - /* */ - /* <Description> */ - /* Retrieve the language tag associated with a language ID of an SFNT */ - /* `name' table entry. */ - /* */ - /* <Input> */ - /* face :: A handle to the source face. */ - /* */ - /* langID :: The language ID, as returned by @FT_Get_Sfnt_Name. */ - /* This is always a value larger than 0x8000. */ - /* */ - /* <Output> */ - /* alangTag :: The language tag associated with the `name' table */ - /* entry's language ID. */ - /* */ - /* <Return> */ - /* FreeType error code. 0~means success. */ - /* */ - /* <Note> */ - /* The `string' array returned in the `alangTag' structure is not */ - /* null-terminated. Note that you don't have to deallocate `string' */ - /* by yourself; FreeType takes care of it if you call @FT_Done_Face. */ - /* */ - /* Only `name' table format~1 supports language tags. For format~0 */ - /* tables, this function always returns FT_Err_Invalid_Table. For */ - /* invalid format~1 language ID values, FT_Err_Invalid_Argument is */ - /* returned. */ - /* */ - /* <Since> */ - /* 2.8 */ - /* */ + /************************************************************************** + * + * @function: + * FT_Get_Sfnt_LangTag + * + * @description: + * Retrieve the language tag associated with a language ID of an SFNT + * 'name' table entry. + * + * @input: + * face :: + * A handle to the source face. + * + * langID :: + * The language ID, as returned by @FT_Get_Sfnt_Name. This is always a + * value larger than 0x8000. + * + * @output: + * alangTag :: + * The language tag associated with the 'name' table entry's language + * ID. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The `string` array returned in the `alangTag` structure is not + * null-terminated. Note that you don't have to deallocate `string` by + * yourself; FreeType takes care of it if you call @FT_Done_Face. + * + * Only 'name' table format~1 supports language tags. For format~0 + * tables, this function always returns FT_Err_Invalid_Table. For + * invalid format~1 language ID values, FT_Err_Invalid_Argument is + * returned. + * + * This function always returns an error if the config macro + * `TT_CONFIG_OPTION_SFNT_NAMES` is not defined in `ftoption.h`. + * + * @since: + * 2.8 + */ FT_EXPORT( FT_Error ) FT_Get_Sfnt_LangTag( FT_Face face, FT_UInt langID, diff --git a/sdk/lib/3rdparty/freetype/include/freetype/ftstroke.h b/sdk/lib/3rdparty/freetype/include/freetype/ftstroke.h index 44b6fbe19ff1c..01a9c1811c05c 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/ftstroke.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/ftstroke.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftstroke.h */ -/* */ -/* FreeType path stroker (specification). */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftstroke.h + * + * FreeType path stroker (specification). + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTSTROKE_H_ @@ -27,116 +27,113 @@ FT_BEGIN_HEADER - /************************************************************************ - * - * @section: - * glyph_stroker - * - * @title: - * Glyph Stroker - * - * @abstract: - * Generating bordered and stroked glyphs. - * - * @description: - * This component generates stroked outlines of a given vectorial - * glyph. It also allows you to retrieve the `outside' and/or the - * `inside' borders of the stroke. - * - * This can be useful to generate `bordered' glyph, i.e., glyphs - * displayed with a coloured (and anti-aliased) border around their - * shape. - * - * @order: - * FT_Stroker - * - * FT_Stroker_LineJoin - * FT_Stroker_LineCap - * FT_StrokerBorder - * - * FT_Outline_GetInsideBorder - * FT_Outline_GetOutsideBorder - * - * FT_Glyph_Stroke - * FT_Glyph_StrokeBorder - * - * FT_Stroker_New - * FT_Stroker_Set - * FT_Stroker_Rewind - * FT_Stroker_ParseOutline - * FT_Stroker_Done - * - * FT_Stroker_BeginSubPath - * FT_Stroker_EndSubPath - * - * FT_Stroker_LineTo - * FT_Stroker_ConicTo - * FT_Stroker_CubicTo - * - * FT_Stroker_GetBorderCounts - * FT_Stroker_ExportBorder - * FT_Stroker_GetCounts - * FT_Stroker_Export - * - */ - - - /************************************************************** - * - * @type: - * FT_Stroker - * - * @description: - * Opaque handle to a path stroker object. - */ + /************************************************************************** + * + * @section: + * glyph_stroker + * + * @title: + * Glyph Stroker + * + * @abstract: + * Generating bordered and stroked glyphs. + * + * @description: + * This component generates stroked outlines of a given vectorial glyph. + * It also allows you to retrieve the 'outside' and/or the 'inside' + * borders of the stroke. + * + * This can be useful to generate 'bordered' glyph, i.e., glyphs + * displayed with a coloured (and anti-aliased) border around their + * shape. + * + * @order: + * FT_Stroker + * + * FT_Stroker_LineJoin + * FT_Stroker_LineCap + * FT_StrokerBorder + * + * FT_Outline_GetInsideBorder + * FT_Outline_GetOutsideBorder + * + * FT_Glyph_Stroke + * FT_Glyph_StrokeBorder + * + * FT_Stroker_New + * FT_Stroker_Set + * FT_Stroker_Rewind + * FT_Stroker_ParseOutline + * FT_Stroker_Done + * + * FT_Stroker_BeginSubPath + * FT_Stroker_EndSubPath + * + * FT_Stroker_LineTo + * FT_Stroker_ConicTo + * FT_Stroker_CubicTo + * + * FT_Stroker_GetBorderCounts + * FT_Stroker_ExportBorder + * FT_Stroker_GetCounts + * FT_Stroker_Export + * + */ + + + /************************************************************************** + * + * @type: + * FT_Stroker + * + * @description: + * Opaque handle to a path stroker object. + */ typedef struct FT_StrokerRec_* FT_Stroker; - /************************************************************** + /************************************************************************** * * @enum: * FT_Stroker_LineJoin * * @description: - * These values determine how two joining lines are rendered - * in a stroker. + * These values determine how two joining lines are rendered in a + * stroker. * * @values: * FT_STROKER_LINEJOIN_ROUND :: - * Used to render rounded line joins. Circular arcs are used - * to join two lines smoothly. + * Used to render rounded line joins. Circular arcs are used to join + * two lines smoothly. * * FT_STROKER_LINEJOIN_BEVEL :: - * Used to render beveled line joins. The outer corner of - * the joined lines is filled by enclosing the triangular - * region of the corner with a straight line between the - * outer corners of each stroke. + * Used to render beveled line joins. The outer corner of the joined + * lines is filled by enclosing the triangular region of the corner + * with a straight line between the outer corners of each stroke. * * FT_STROKER_LINEJOIN_MITER_FIXED :: - * Used to render mitered line joins, with fixed bevels if the - * miter limit is exceeded. The outer edges of the strokes - * for the two segments are extended until they meet at an - * angle. If the segments meet at too sharp an angle (such - * that the miter would extend from the intersection of the - * segments a distance greater than the product of the miter - * limit value and the border radius), then a bevel join (see - * above) is used instead. This prevents long spikes being - * created. FT_STROKER_LINEJOIN_MITER_FIXED generates a miter - * line join as used in PostScript and PDF. + * Used to render mitered line joins, with fixed bevels if the miter + * limit is exceeded. The outer edges of the strokes for the two + * segments are extended until they meet at an angle. If the segments + * meet at too sharp an angle (such that the miter would extend from + * the intersection of the segments a distance greater than the product + * of the miter limit value and the border radius), then a bevel join + * (see above) is used instead. This prevents long spikes being + * created. `FT_STROKER_LINEJOIN_MITER_FIXED` generates a miter line + * join as used in PostScript and PDF. * * FT_STROKER_LINEJOIN_MITER_VARIABLE :: * FT_STROKER_LINEJOIN_MITER :: - * Used to render mitered line joins, with variable bevels if - * the miter limit is exceeded. The intersection of the - * strokes is clipped at a line perpendicular to the bisector - * of the angle between the strokes, at the distance from the - * intersection of the segments equal to the product of the - * miter limit value and the border radius. This prevents - * long spikes being created. - * FT_STROKER_LINEJOIN_MITER_VARIABLE generates a mitered line - * join as used in XPS. FT_STROKER_LINEJOIN_MITER is an alias - * for FT_STROKER_LINEJOIN_MITER_VARIABLE, retained for - * backward compatibility. + * Used to render mitered line joins, with variable bevels if the miter + * limit is exceeded. The intersection of the strokes is clipped at a + * line perpendicular to the bisector of the angle between the strokes, + * at the distance from the intersection of the segments equal to the + * product of the miter limit value and the border radius. This + * prevents long spikes being created. + * `FT_STROKER_LINEJOIN_MITER_VARIABLE` generates a mitered line join + * as used in XPS. `FT_STROKER_LINEJOIN_MITER` is an alias for + * `FT_STROKER_LINEJOIN_MITER_VARIABLE`, retained for backward + * compatibility. */ typedef enum FT_Stroker_LineJoin_ { @@ -149,27 +146,25 @@ FT_BEGIN_HEADER } FT_Stroker_LineJoin; - /************************************************************** + /************************************************************************** * * @enum: * FT_Stroker_LineCap * * @description: - * These values determine how the end of opened sub-paths are - * rendered in a stroke. + * These values determine how the end of opened sub-paths are rendered in + * a stroke. * * @values: * FT_STROKER_LINECAP_BUTT :: - * The end of lines is rendered as a full stop on the last - * point itself. + * The end of lines is rendered as a full stop on the last point + * itself. * * FT_STROKER_LINECAP_ROUND :: - * The end of lines is rendered as a half-circle around the - * last point. + * The end of lines is rendered as a half-circle around the last point. * * FT_STROKER_LINECAP_SQUARE :: - * The end of lines is rendered as a square around the - * last point. + * The end of lines is rendered as a square around the last point. */ typedef enum FT_Stroker_LineCap_ { @@ -180,14 +175,14 @@ FT_BEGIN_HEADER } FT_Stroker_LineCap; - /************************************************************** + /************************************************************************** * * @enum: * FT_StrokerBorder * * @description: - * These values are used to select a given stroke border - * in @FT_Stroker_GetBorderCounts and @FT_Stroker_ExportBorder. + * These values are used to select a given stroke border in + * @FT_Stroker_GetBorderCounts and @FT_Stroker_ExportBorder. * * @values: * FT_STROKER_BORDER_LEFT :: @@ -197,9 +192,9 @@ FT_BEGIN_HEADER * Select the right border, relative to the drawing direction. * * @note: - * Applications are generally interested in the `inside' and `outside' + * Applications are generally interested in the 'inside' and 'outside' * borders. However, there is no direct mapping between these and the - * `left' and `right' ones, since this really depends on the glyph's + * 'left' and 'right' ones, since this really depends on the glyph's * drawing orientation, which varies between font formats. * * You can however use @FT_Outline_GetInsideBorder and @@ -213,14 +208,14 @@ FT_BEGIN_HEADER } FT_StrokerBorder; - /************************************************************** + /************************************************************************** * * @function: * FT_Outline_GetInsideBorder * * @description: - * Retrieve the @FT_StrokerBorder value corresponding to the - * `inside' borders of a given outline. + * Retrieve the @FT_StrokerBorder value corresponding to the 'inside' + * borders of a given outline. * * @input: * outline :: @@ -234,14 +229,14 @@ FT_BEGIN_HEADER FT_Outline_GetInsideBorder( FT_Outline* outline ); - /************************************************************** + /************************************************************************** * * @function: * FT_Outline_GetOutsideBorder * * @description: - * Retrieve the @FT_StrokerBorder value corresponding to the - * `outside' borders of a given outline. + * Retrieve the @FT_StrokerBorder value corresponding to the 'outside' + * borders of a given outline. * * @input: * outline :: @@ -255,7 +250,7 @@ FT_BEGIN_HEADER FT_Outline_GetOutsideBorder( FT_Outline* outline ); - /************************************************************** + /************************************************************************** * * @function: * FT_Stroker_New @@ -269,7 +264,7 @@ FT_BEGIN_HEADER * * @output: * astroker :: - * A new stroker object handle. NULL in case of error. + * A new stroker object handle. `NULL` in case of error. * * @return: * FreeType error code. 0~means success. @@ -279,7 +274,7 @@ FT_BEGIN_HEADER FT_Stroker *astroker ); - /************************************************************** + /************************************************************************** * * @function: * FT_Stroker_Set @@ -301,13 +296,12 @@ FT_BEGIN_HEADER * The line join style. * * miter_limit :: - * The miter limit for the FT_STROKER_LINEJOIN_MITER_FIXED and - * FT_STROKER_LINEJOIN_MITER_VARIABLE line join styles, - * expressed as 16.16 fixed-point value. + * The miter limit for the `FT_STROKER_LINEJOIN_MITER_FIXED` and + * `FT_STROKER_LINEJOIN_MITER_VARIABLE` line join styles, expressed as + * 16.16 fixed-point value. * * @note: - * The radius is expressed in the same units as the outline - * coordinates. + * The radius is expressed in the same units as the outline coordinates. * * This function calls @FT_Stroker_Rewind automatically. */ @@ -319,16 +313,15 @@ FT_BEGIN_HEADER FT_Fixed miter_limit ); - /************************************************************** + /************************************************************************** * * @function: * FT_Stroker_Rewind * * @description: - * Reset a stroker object without changing its attributes. - * You should call this function before beginning a new - * series of calls to @FT_Stroker_BeginSubPath or - * @FT_Stroker_EndSubPath. + * Reset a stroker object without changing its attributes. You should + * call this function before beginning a new series of calls to + * @FT_Stroker_BeginSubPath or @FT_Stroker_EndSubPath. * * @input: * stroker :: @@ -338,15 +331,15 @@ FT_BEGIN_HEADER FT_Stroker_Rewind( FT_Stroker stroker ); - /************************************************************** + /************************************************************************** * * @function: * FT_Stroker_ParseOutline * * @description: - * A convenience function used to parse a whole outline with - * the stroker. The resulting outline(s) can be retrieved - * later by functions like @FT_Stroker_GetCounts and @FT_Stroker_Export. + * A convenience function used to parse a whole outline with the stroker. + * The resulting outline(s) can be retrieved later by functions like + * @FT_Stroker_GetCounts and @FT_Stroker_Export. * * @input: * stroker :: @@ -356,18 +349,18 @@ FT_BEGIN_HEADER * The source outline. * * opened :: - * A boolean. If~1, the outline is treated as an open path instead - * of a closed one. + * A boolean. If~1, the outline is treated as an open path instead of + * a closed one. * * @return: * FreeType error code. 0~means success. * * @note: - * If `opened' is~0 (the default), the outline is treated as a closed - * path, and the stroker generates two distinct `border' outlines. + * If `opened` is~0 (the default), the outline is treated as a closed + * path, and the stroker generates two distinct 'border' outlines. * - * If `opened' is~1, the outline is processed as an open path, and the - * stroker generates a single `stroke' outline. + * If `opened` is~1, the outline is processed as an open path, and the + * stroker generates a single 'stroke' outline. * * This function calls @FT_Stroker_Rewind automatically. */ @@ -377,7 +370,7 @@ FT_BEGIN_HEADER FT_Bool opened ); - /************************************************************** + /************************************************************************** * * @function: * FT_Stroker_BeginSubPath @@ -399,8 +392,8 @@ FT_BEGIN_HEADER * FreeType error code. 0~means success. * * @note: - * This function is useful when you need to stroke a path that is - * not stored as an @FT_Outline object. + * This function is useful when you need to stroke a path that is not + * stored as an @FT_Outline object. */ FT_EXPORT( FT_Error ) FT_Stroker_BeginSubPath( FT_Stroker stroker, @@ -408,7 +401,7 @@ FT_BEGIN_HEADER FT_Bool open ); - /************************************************************** + /************************************************************************** * * @function: * FT_Stroker_EndSubPath @@ -424,22 +417,22 @@ FT_BEGIN_HEADER * FreeType error code. 0~means success. * * @note: - * You should call this function after @FT_Stroker_BeginSubPath. - * If the subpath was not `opened', this function `draws' a - * single line segment to the start position when needed. + * You should call this function after @FT_Stroker_BeginSubPath. If the + * subpath was not 'opened', this function 'draws' a single line segment + * to the start position when needed. */ FT_EXPORT( FT_Error ) FT_Stroker_EndSubPath( FT_Stroker stroker ); - /************************************************************** + /************************************************************************** * * @function: * FT_Stroker_LineTo * * @description: - * `Draw' a single line segment in the stroker's current sub-path, - * from the last position. + * 'Draw' a single line segment in the stroker's current sub-path, from + * the last position. * * @input: * stroker :: @@ -460,13 +453,13 @@ FT_BEGIN_HEADER FT_Vector* to ); - /************************************************************** + /************************************************************************** * * @function: * FT_Stroker_ConicTo * * @description: - * `Draw' a single quadratic Bezier in the stroker's current sub-path, + * 'Draw' a single quadratic Bezier in the stroker's current sub-path, * from the last position. * * @input: @@ -492,14 +485,14 @@ FT_BEGIN_HEADER FT_Vector* to ); - /************************************************************** + /************************************************************************** * * @function: * FT_Stroker_CubicTo * * @description: - * `Draw' a single cubic Bezier in the stroker's current sub-path, - * from the last position. + * 'Draw' a single cubic Bezier in the stroker's current sub-path, from + * the last position. * * @input: * stroker :: @@ -528,16 +521,16 @@ FT_BEGIN_HEADER FT_Vector* to ); - /************************************************************** + /************************************************************************** * * @function: * FT_Stroker_GetBorderCounts * * @description: - * Call this function once you have finished parsing your paths - * with the stroker. It returns the number of points and - * contours necessary to export one of the `border' or `stroke' - * outlines generated by the stroker. + * Call this function once you have finished parsing your paths with the + * stroker. It returns the number of points and contours necessary to + * export one of the 'border' or 'stroke' outlines generated by the + * stroker. * * @input: * stroker :: @@ -557,15 +550,15 @@ FT_BEGIN_HEADER * FreeType error code. 0~means success. * * @note: - * When an outline, or a sub-path, is `closed', the stroker generates - * two independent `border' outlines, named `left' and `right'. + * When an outline, or a sub-path, is 'closed', the stroker generates two + * independent 'border' outlines, named 'left' and 'right'. * - * When the outline, or a sub-path, is `opened', the stroker merges - * the `border' outlines with caps. The `left' border receives all - * points, while the `right' border becomes empty. + * When the outline, or a sub-path, is 'opened', the stroker merges the + * 'border' outlines with caps. The 'left' border receives all points, + * while the 'right' border becomes empty. * - * Use the function @FT_Stroker_GetCounts instead if you want to - * retrieve the counts associated to both borders. + * Use the function @FT_Stroker_GetCounts instead if you want to retrieve + * the counts associated to both borders. */ FT_EXPORT( FT_Error ) FT_Stroker_GetBorderCounts( FT_Stroker stroker, @@ -574,19 +567,17 @@ FT_BEGIN_HEADER FT_UInt *anum_contours ); - /************************************************************** + /************************************************************************** * * @function: * FT_Stroker_ExportBorder * * @description: - * Call this function after @FT_Stroker_GetBorderCounts to - * export the corresponding border to your own @FT_Outline - * structure. + * Call this function after @FT_Stroker_GetBorderCounts to export the + * corresponding border to your own @FT_Outline structure. * - * Note that this function appends the border points and - * contours to your outline, but does not try to resize its - * arrays. + * Note that this function appends the border points and contours to your + * outline, but does not try to resize its arrays. * * @input: * stroker :: @@ -599,19 +590,19 @@ FT_BEGIN_HEADER * The target outline handle. * * @note: - * Always call this function after @FT_Stroker_GetBorderCounts to - * get sure that there is enough room in your @FT_Outline object to - * receive all new data. + * Always call this function after @FT_Stroker_GetBorderCounts to get + * sure that there is enough room in your @FT_Outline object to receive + * all new data. * - * When an outline, or a sub-path, is `closed', the stroker generates - * two independent `border' outlines, named `left' and `right'. + * When an outline, or a sub-path, is 'closed', the stroker generates two + * independent 'border' outlines, named 'left' and 'right'. * - * When the outline, or a sub-path, is `opened', the stroker merges - * the `border' outlines with caps. The `left' border receives all - * points, while the `right' border becomes empty. + * When the outline, or a sub-path, is 'opened', the stroker merges the + * 'border' outlines with caps. The 'left' border receives all points, + * while the 'right' border becomes empty. * - * Use the function @FT_Stroker_Export instead if you want to - * retrieve all borders at once. + * Use the function @FT_Stroker_Export instead if you want to retrieve + * all borders at once. */ FT_EXPORT( void ) FT_Stroker_ExportBorder( FT_Stroker stroker, @@ -619,16 +610,15 @@ FT_BEGIN_HEADER FT_Outline* outline ); - /************************************************************** + /************************************************************************** * * @function: * FT_Stroker_GetCounts * * @description: - * Call this function once you have finished parsing your paths - * with the stroker. It returns the number of points and - * contours necessary to export all points/borders from the stroked - * outline/path. + * Call this function once you have finished parsing your paths with the + * stroker. It returns the number of points and contours necessary to + * export all points/borders from the stroked outline/path. * * @input: * stroker :: @@ -650,18 +640,17 @@ FT_BEGIN_HEADER FT_UInt *anum_contours ); - /************************************************************** + /************************************************************************** * * @function: * FT_Stroker_Export * * @description: - * Call this function after @FT_Stroker_GetBorderCounts to - * export all borders to your own @FT_Outline structure. + * Call this function after @FT_Stroker_GetBorderCounts to export all + * borders to your own @FT_Outline structure. * - * Note that this function appends the border points and - * contours to your outline, but does not try to resize its - * arrays. + * Note that this function appends the border points and contours to your + * outline, but does not try to resize its arrays. * * @input: * stroker :: @@ -675,7 +664,7 @@ FT_BEGIN_HEADER FT_Outline* outline ); - /************************************************************** + /************************************************************************** * * @function: * FT_Stroker_Done @@ -685,13 +674,13 @@ FT_BEGIN_HEADER * * @input: * stroker :: - * A stroker handle. Can be NULL. + * A stroker handle. Can be `NULL`. */ FT_EXPORT( void ) FT_Stroker_Done( FT_Stroker stroker ); - /************************************************************** + /************************************************************************** * * @function: * FT_Glyph_Stroke @@ -708,8 +697,7 @@ FT_BEGIN_HEADER * A stroker handle. * * destroy :: - * A Boolean. If~1, the source glyph object is destroyed - * on success. + * A Boolean. If~1, the source glyph object is destroyed on success. * * @return: * FreeType error code. 0~means success. @@ -719,8 +707,8 @@ FT_BEGIN_HEADER * * Adding stroke may yield a significantly wider and taller glyph * depending on how large of a radius was used to stroke the glyph. You - * may need to manually adjust horizontal and vertical advance amounts - * to account for this added size. + * may need to manually adjust horizontal and vertical advance amounts to + * account for this added size. */ FT_EXPORT( FT_Error ) FT_Glyph_Stroke( FT_Glyph *pglyph, @@ -728,14 +716,14 @@ FT_BEGIN_HEADER FT_Bool destroy ); - /************************************************************** + /************************************************************************** * * @function: * FT_Glyph_StrokeBorder * * @description: - * Stroke a given outline glyph object with a given stroker, but - * only return either its inside or outside border. + * Stroke a given outline glyph object with a given stroker, but only + * return either its inside or outside border. * * @inout: * pglyph :: @@ -746,12 +734,11 @@ FT_BEGIN_HEADER * A stroker handle. * * inside :: - * A Boolean. If~1, return the inside border, otherwise - * the outside border. + * A Boolean. If~1, return the inside border, otherwise the outside + * border. * * destroy :: - * A Boolean. If~1, the source glyph object is destroyed - * on success. + * A Boolean. If~1, the source glyph object is destroyed on success. * * @return: * FreeType error code. 0~means success. @@ -761,8 +748,8 @@ FT_BEGIN_HEADER * * Adding stroke may yield a significantly wider and taller glyph * depending on how large of a radius was used to stroke the glyph. You - * may need to manually adjust horizontal and vertical advance amounts - * to account for this added size. + * may need to manually adjust horizontal and vertical advance amounts to + * account for this added size. */ FT_EXPORT( FT_Error ) FT_Glyph_StrokeBorder( FT_Glyph *pglyph, diff --git a/sdk/lib/3rdparty/freetype/include/freetype/ftsynth.h b/sdk/lib/3rdparty/freetype/include/freetype/ftsynth.h index ff9fb43d964b0..8754f97ceefe0 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/ftsynth.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/ftsynth.h @@ -1,20 +1,20 @@ -/***************************************************************************/ -/* */ -/* ftsynth.h */ -/* */ -/* FreeType synthesizing code for emboldening and slanting */ -/* (specification). */ -/* */ -/* Copyright 2000-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftsynth.h + * + * FreeType synthesizing code for emboldening and slanting + * (specification). + * + * Copyright (C) 2000-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ /*************************************************************************/ @@ -35,7 +35,7 @@ /* Main reason for not lifting the functions in this module to a */ - /* `standard' API is that the used parameters for emboldening and */ + /* 'standard' API is that the used parameters for emboldening and */ /* slanting are not configurable. Consider the functions as a */ /* code resource that should be copied into the application and */ /* adapted to the particular needs. */ @@ -57,7 +57,7 @@ FT_BEGIN_HEADER - /* Embolden a glyph by a `reasonable' value (which is highly a matter of */ + /* Embolden a glyph by a 'reasonable' value (which is highly a matter of */ /* taste). This function is actually a convenience function, providing */ /* a wrapper for @FT_Outline_Embolden and @FT_Bitmap_Embolden. */ /* */ diff --git a/sdk/lib/3rdparty/freetype/include/freetype/ftsystem.h b/sdk/lib/3rdparty/freetype/include/freetype/ftsystem.h index f6b1629ef239e..889a6ba17263c 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/ftsystem.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/ftsystem.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftsystem.h */ -/* */ -/* FreeType low-level system interface definition (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftsystem.h + * + * FreeType low-level system interface definition (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTSYSTEM_H_ @@ -26,34 +26,33 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* <Section> */ - /* system_interface */ - /* */ - /* <Title> */ - /* System Interface */ - /* */ - /* <Abstract> */ - /* How FreeType manages memory and i/o. */ - /* */ - /* <Description> */ - /* This section contains various definitions related to memory */ - /* management and i/o access. You need to understand this */ - /* information if you want to use a custom memory manager or you own */ - /* i/o streams. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * @section: + * system_interface + * + * @title: + * System Interface + * + * @abstract: + * How FreeType manages memory and i/o. + * + * @description: + * This section contains various definitions related to memory management + * and i/o access. You need to understand this information if you want to + * use a custom memory manager or you own i/o streams. + * + */ - /*************************************************************************/ - /* */ - /* M E M O R Y M A N A G E M E N T */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * M E M O R Y M A N A G E M E N T + * + */ - /************************************************************************* + /************************************************************************** * * @type: * FT_Memory @@ -66,13 +65,13 @@ FT_BEGIN_HEADER typedef struct FT_MemoryRec_* FT_Memory; - /************************************************************************* + /************************************************************************** * * @functype: * FT_Alloc_Func * * @description: - * A function used to allocate `size' bytes from `memory'. + * A function used to allocate `size` bytes from `memory`. * * @input: * memory :: @@ -90,7 +89,7 @@ FT_BEGIN_HEADER long size ); - /************************************************************************* + /************************************************************************** * * @functype: * FT_Free_Func @@ -111,7 +110,7 @@ FT_BEGIN_HEADER void* block ); - /************************************************************************* + /************************************************************************** * * @functype: * FT_Realloc_Func @@ -146,7 +145,7 @@ FT_BEGIN_HEADER void* block ); - /************************************************************************* + /************************************************************************** * * @struct: * FT_MemoryRec @@ -177,14 +176,14 @@ FT_BEGIN_HEADER }; - /*************************************************************************/ - /* */ - /* I / O M A N A G E M E N T */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * I / O M A N A G E M E N T + * + */ - /************************************************************************* + /************************************************************************** * * @type: * FT_Stream @@ -193,21 +192,21 @@ FT_BEGIN_HEADER * A handle to an input stream. * * @also: - * See @FT_StreamRec for the publicly accessible fields of a given - * stream object. + * See @FT_StreamRec for the publicly accessible fields of a given stream + * object. * */ typedef struct FT_StreamRec_* FT_Stream; - /************************************************************************* + /************************************************************************** * * @struct: * FT_StreamDesc * * @description: * A union type used to store either a long or a pointer. This is used - * to store a file descriptor or a `FILE*' in an input stream. + * to store a file descriptor or a `FILE*` in an input stream. * */ typedef union FT_StreamDesc_ @@ -218,7 +217,7 @@ FT_BEGIN_HEADER } FT_StreamDesc; - /************************************************************************* + /************************************************************************** * * @functype: * FT_Stream_IoFunc @@ -243,9 +242,8 @@ FT_BEGIN_HEADER * The number of bytes effectively read by the stream. * * @note: - * This function might be called to perform a seek or skip operation - * with a `count' of~0. A non-zero return value then indicates an - * error. + * This function might be called to perform a seek or skip operation with + * a `count` of~0. A non-zero return value then indicates an error. * */ typedef unsigned long @@ -255,7 +253,7 @@ FT_BEGIN_HEADER unsigned long count ); - /************************************************************************* + /************************************************************************** * * @functype: * FT_Stream_CloseFunc @@ -265,14 +263,14 @@ FT_BEGIN_HEADER * * @input: * stream :: - * A handle to the target stream. + * A handle to the target stream. * */ typedef void (*FT_Stream_CloseFunc)( FT_Stream stream ); - /************************************************************************* + /************************************************************************** * * @struct: * FT_StreamRec @@ -283,7 +281,7 @@ FT_BEGIN_HEADER * @input: * base :: * For memory-based streams, this is the address of the first stream - * byte in memory. This field should always be set to NULL for + * byte in memory. This field should always be set to `NULL` for * disk-based streams. * * size :: @@ -299,7 +297,7 @@ FT_BEGIN_HEADER * * descriptor :: * This field is a union that can hold an integer or a pointer. It is - * used by stream implementations to store file descriptors or `FILE*' + * used by stream implementations to store file descriptors or `FILE*` * pointers. * * pathname :: @@ -314,13 +312,13 @@ FT_BEGIN_HEADER * The stream's close function. * * memory :: - * The memory manager to use to preload frames. This is set - * internally by FreeType and shouldn't be touched by stream - * implementations. + * The memory manager to use to preload frames. This is set internally + * by FreeType and shouldn't be touched by stream implementations. * * cursor :: * This field is set and used internally by FreeType when parsing - * frames. + * frames. In particular, the `FT_GET_XXX` macros use this instead of + * the `pos` field. * * limit :: * This field is set and used internally by FreeType when parsing diff --git a/sdk/lib/3rdparty/freetype/include/freetype/fttrigon.h b/sdk/lib/3rdparty/freetype/include/freetype/fttrigon.h index 2e3f3f1f73770..37e1412fdfbea 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/fttrigon.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/fttrigon.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* fttrigon.h */ -/* */ -/* FreeType trigonometric functions (specification). */ -/* */ -/* Copyright 2001-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * fttrigon.h + * + * FreeType trigonometric functions (specification). + * + * Copyright (C) 2001-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTTRIGON_H_ @@ -31,15 +31,15 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* <Section> */ - /* computations */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * @section: + * computations + * + */ - /************************************************************************* + /************************************************************************** * * @type: * FT_Angle @@ -52,7 +52,7 @@ FT_BEGIN_HEADER typedef FT_Fixed FT_Angle; - /************************************************************************* + /************************************************************************** * * @macro: * FT_ANGLE_PI @@ -64,7 +64,7 @@ FT_BEGIN_HEADER #define FT_ANGLE_PI ( 180L << 16 ) - /************************************************************************* + /************************************************************************** * * @macro: * FT_ANGLE_2PI @@ -76,7 +76,7 @@ FT_BEGIN_HEADER #define FT_ANGLE_2PI ( FT_ANGLE_PI * 2 ) - /************************************************************************* + /************************************************************************** * * @macro: * FT_ANGLE_PI2 @@ -88,7 +88,7 @@ FT_BEGIN_HEADER #define FT_ANGLE_PI2 ( FT_ANGLE_PI / 2 ) - /************************************************************************* + /************************************************************************** * * @macro: * FT_ANGLE_PI4 @@ -100,7 +100,7 @@ FT_BEGIN_HEADER #define FT_ANGLE_PI4 ( FT_ANGLE_PI / 4 ) - /************************************************************************* + /************************************************************************** * * @function: * FT_Sin @@ -124,7 +124,7 @@ FT_BEGIN_HEADER FT_Sin( FT_Angle angle ); - /************************************************************************* + /************************************************************************** * * @function: * FT_Cos @@ -148,7 +148,7 @@ FT_BEGIN_HEADER FT_Cos( FT_Angle angle ); - /************************************************************************* + /************************************************************************** * * @function: * FT_Tan @@ -168,14 +168,14 @@ FT_BEGIN_HEADER FT_Tan( FT_Angle angle ); - /************************************************************************* + /************************************************************************** * * @function: * FT_Atan2 * * @description: - * Return the arc-tangent corresponding to a given vector (x,y) in - * the 2d plane. + * Return the arc-tangent corresponding to a given vector (x,y) in the 2d + * plane. * * @input: * x :: @@ -193,7 +193,7 @@ FT_BEGIN_HEADER FT_Fixed y ); - /************************************************************************* + /************************************************************************** * * @function: * FT_Angle_Diff @@ -210,7 +210,7 @@ FT_BEGIN_HEADER * Second angle. * * @return: - * Constrained value of `value2-value1'. + * Constrained value of `angle2-angle1`. * */ FT_EXPORT( FT_Angle ) @@ -218,15 +218,15 @@ FT_BEGIN_HEADER FT_Angle angle2 ); - /************************************************************************* + /************************************************************************** * * @function: * FT_Vector_Unit * * @description: * Return the unit vector corresponding to a given angle. After the - * call, the value of `vec.x' will be `cos(angle)', and the value of - * `vec.y' will be `sin(angle)'. + * call, the value of `vec.x` will be `cos(angle)`, and the value of + * `vec.y` will be `sin(angle)`. * * This function is useful to retrieve both the sinus and cosinus of a * given angle quickly. @@ -245,7 +245,7 @@ FT_BEGIN_HEADER FT_Angle angle ); - /************************************************************************* + /************************************************************************** * * @function: * FT_Vector_Rotate @@ -267,7 +267,7 @@ FT_BEGIN_HEADER FT_Angle angle ); - /************************************************************************* + /************************************************************************** * * @function: * FT_Vector_Length @@ -288,7 +288,7 @@ FT_BEGIN_HEADER FT_Vector_Length( FT_Vector* vec ); - /************************************************************************* + /************************************************************************** * * @function: * FT_Vector_Polarize @@ -314,7 +314,7 @@ FT_BEGIN_HEADER FT_Angle *angle ); - /************************************************************************* + /************************************************************************** * * @function: * FT_Vector_From_Polar diff --git a/sdk/lib/3rdparty/freetype/include/freetype/fttypes.h b/sdk/lib/3rdparty/freetype/include/freetype/fttypes.h index f638c2e54fde5..10571505a58c2 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/fttypes.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/fttypes.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* fttypes.h */ -/* */ -/* FreeType simple types definitions (specification only). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * fttypes.h + * + * FreeType simple types definitions (specification only). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTTYPES_H_ @@ -31,326 +31,327 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* <Section> */ - /* basic_types */ - /* */ - /* <Title> */ - /* Basic Data Types */ - /* */ - /* <Abstract> */ - /* The basic data types defined by the library. */ - /* */ - /* <Description> */ - /* This section contains the basic data types defined by FreeType~2, */ - /* ranging from simple scalar types to bitmap descriptors. More */ - /* font-specific structures are defined in a different section. */ - /* */ - /* <Order> */ - /* FT_Byte */ - /* FT_Bytes */ - /* FT_Char */ - /* FT_Int */ - /* FT_UInt */ - /* FT_Int16 */ - /* FT_UInt16 */ - /* FT_Int32 */ - /* FT_UInt32 */ - /* FT_Int64 */ - /* FT_UInt64 */ - /* FT_Short */ - /* FT_UShort */ - /* FT_Long */ - /* FT_ULong */ - /* FT_Bool */ - /* FT_Offset */ - /* FT_PtrDist */ - /* FT_String */ - /* FT_Tag */ - /* FT_Error */ - /* FT_Fixed */ - /* FT_Pointer */ - /* FT_Pos */ - /* FT_Vector */ - /* FT_BBox */ - /* FT_Matrix */ - /* FT_FWord */ - /* FT_UFWord */ - /* FT_F2Dot14 */ - /* FT_UnitVector */ - /* FT_F26Dot6 */ - /* FT_Data */ - /* */ - /* FT_MAKE_TAG */ - /* */ - /* FT_Generic */ - /* FT_Generic_Finalizer */ - /* */ - /* FT_Bitmap */ - /* FT_Pixel_Mode */ - /* FT_Palette_Mode */ - /* FT_Glyph_Format */ - /* FT_IMAGE_TAG */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Bool */ - /* */ - /* <Description> */ - /* A typedef of unsigned char, used for simple booleans. As usual, */ - /* values 1 and~0 represent true and false, respectively. */ - /* */ + /************************************************************************** + * + * @section: + * basic_types + * + * @title: + * Basic Data Types + * + * @abstract: + * The basic data types defined by the library. + * + * @description: + * This section contains the basic data types defined by FreeType~2, + * ranging from simple scalar types to bitmap descriptors. More + * font-specific structures are defined in a different section. + * + * @order: + * FT_Byte + * FT_Bytes + * FT_Char + * FT_Int + * FT_UInt + * FT_Int16 + * FT_UInt16 + * FT_Int32 + * FT_UInt32 + * FT_Int64 + * FT_UInt64 + * FT_Short + * FT_UShort + * FT_Long + * FT_ULong + * FT_Bool + * FT_Offset + * FT_PtrDist + * FT_String + * FT_Tag + * FT_Error + * FT_Fixed + * FT_Pointer + * FT_Pos + * FT_Vector + * FT_BBox + * FT_Matrix + * FT_FWord + * FT_UFWord + * FT_F2Dot14 + * FT_UnitVector + * FT_F26Dot6 + * FT_Data + * + * FT_MAKE_TAG + * + * FT_Generic + * FT_Generic_Finalizer + * + * FT_Bitmap + * FT_Pixel_Mode + * FT_Palette_Mode + * FT_Glyph_Format + * FT_IMAGE_TAG + * + */ + + + /************************************************************************** + * + * @type: + * FT_Bool + * + * @description: + * A typedef of unsigned char, used for simple booleans. As usual, + * values 1 and~0 represent true and false, respectively. + */ typedef unsigned char FT_Bool; - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_FWord */ - /* */ - /* <Description> */ - /* A signed 16-bit integer used to store a distance in original font */ - /* units. */ - /* */ + /************************************************************************** + * + * @type: + * FT_FWord + * + * @description: + * A signed 16-bit integer used to store a distance in original font + * units. + */ typedef signed short FT_FWord; /* distance in FUnits */ - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_UFWord */ - /* */ - /* <Description> */ - /* An unsigned 16-bit integer used to store a distance in original */ - /* font units. */ - /* */ + /************************************************************************** + * + * @type: + * FT_UFWord + * + * @description: + * An unsigned 16-bit integer used to store a distance in original font + * units. + */ typedef unsigned short FT_UFWord; /* unsigned distance */ - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Char */ - /* */ - /* <Description> */ - /* A simple typedef for the _signed_ char type. */ - /* */ + /************************************************************************** + * + * @type: + * FT_Char + * + * @description: + * A simple typedef for the _signed_ char type. + */ typedef signed char FT_Char; - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Byte */ - /* */ - /* <Description> */ - /* A simple typedef for the _unsigned_ char type. */ - /* */ + /************************************************************************** + * + * @type: + * FT_Byte + * + * @description: + * A simple typedef for the _unsigned_ char type. + */ typedef unsigned char FT_Byte; - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Bytes */ - /* */ - /* <Description> */ - /* A typedef for constant memory areas. */ - /* */ + /************************************************************************** + * + * @type: + * FT_Bytes + * + * @description: + * A typedef for constant memory areas. + */ typedef const FT_Byte* FT_Bytes; - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Tag */ - /* */ - /* <Description> */ - /* A typedef for 32-bit tags (as used in the SFNT format). */ - /* */ + /************************************************************************** + * + * @type: + * FT_Tag + * + * @description: + * A typedef for 32-bit tags (as used in the SFNT format). + */ typedef FT_UInt32 FT_Tag; - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_String */ - /* */ - /* <Description> */ - /* A simple typedef for the char type, usually used for strings. */ - /* */ + /************************************************************************** + * + * @type: + * FT_String + * + * @description: + * A simple typedef for the char type, usually used for strings. + */ typedef char FT_String; - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Short */ - /* */ - /* <Description> */ - /* A typedef for signed short. */ - /* */ + /************************************************************************** + * + * @type: + * FT_Short + * + * @description: + * A typedef for signed short. + */ typedef signed short FT_Short; - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_UShort */ - /* */ - /* <Description> */ - /* A typedef for unsigned short. */ - /* */ + /************************************************************************** + * + * @type: + * FT_UShort + * + * @description: + * A typedef for unsigned short. + */ typedef unsigned short FT_UShort; - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Int */ - /* */ - /* <Description> */ - /* A typedef for the int type. */ - /* */ + /************************************************************************** + * + * @type: + * FT_Int + * + * @description: + * A typedef for the int type. + */ typedef signed int FT_Int; - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_UInt */ - /* */ - /* <Description> */ - /* A typedef for the unsigned int type. */ - /* */ + /************************************************************************** + * + * @type: + * FT_UInt + * + * @description: + * A typedef for the unsigned int type. + */ typedef unsigned int FT_UInt; - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Long */ - /* */ - /* <Description> */ - /* A typedef for signed long. */ - /* */ + /************************************************************************** + * + * @type: + * FT_Long + * + * @description: + * A typedef for signed long. + */ typedef signed long FT_Long; - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_ULong */ - /* */ - /* <Description> */ - /* A typedef for unsigned long. */ - /* */ + /************************************************************************** + * + * @type: + * FT_ULong + * + * @description: + * A typedef for unsigned long. + */ typedef unsigned long FT_ULong; - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_F2Dot14 */ - /* */ - /* <Description> */ - /* A signed 2.14 fixed-point type used for unit vectors. */ - /* */ + /************************************************************************** + * + * @type: + * FT_F2Dot14 + * + * @description: + * A signed 2.14 fixed-point type used for unit vectors. + */ typedef signed short FT_F2Dot14; - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_F26Dot6 */ - /* */ - /* <Description> */ - /* A signed 26.6 fixed-point type used for vectorial pixel */ - /* coordinates. */ - /* */ + /************************************************************************** + * + * @type: + * FT_F26Dot6 + * + * @description: + * A signed 26.6 fixed-point type used for vectorial pixel coordinates. + */ typedef signed long FT_F26Dot6; - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Fixed */ - /* */ - /* <Description> */ - /* This type is used to store 16.16 fixed-point values, like scaling */ - /* values or matrix coefficients. */ - /* */ + /************************************************************************** + * + * @type: + * FT_Fixed + * + * @description: + * This type is used to store 16.16 fixed-point values, like scaling + * values or matrix coefficients. + */ typedef signed long FT_Fixed; - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Error */ - /* */ - /* <Description> */ - /* The FreeType error code type. A value of~0 is always interpreted */ - /* as a successful operation. */ - /* */ + /************************************************************************** + * + * @type: + * FT_Error + * + * @description: + * The FreeType error code type. A value of~0 is always interpreted as a + * successful operation. + */ typedef int FT_Error; - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Pointer */ - /* */ - /* <Description> */ - /* A simple typedef for a typeless pointer. */ - /* */ + /************************************************************************** + * + * @type: + * FT_Pointer + * + * @description: + * A simple typedef for a typeless pointer. + */ typedef void* FT_Pointer; - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_Offset */ - /* */ - /* <Description> */ - /* This is equivalent to the ANSI~C `size_t' type, i.e., the largest */ - /* _unsigned_ integer type used to express a file size or position, */ - /* or a memory block size. */ - /* */ + /************************************************************************** + * + * @type: + * FT_Offset + * + * @description: + * This is equivalent to the ANSI~C `size_t` type, i.e., the largest + * _unsigned_ integer type used to express a file size or position, or a + * memory block size. + */ typedef size_t FT_Offset; - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_PtrDist */ - /* */ - /* <Description> */ - /* This is equivalent to the ANSI~C `ptrdiff_t' type, i.e., the */ - /* largest _signed_ integer type used to express the distance */ - /* between two pointers. */ - /* */ + /************************************************************************** + * + * @type: + * FT_PtrDist + * + * @description: + * This is equivalent to the ANSI~C `ptrdiff_t` type, i.e., the largest + * _signed_ integer type used to express the distance between two + * pointers. + */ typedef ft_ptrdiff_t FT_PtrDist; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_UnitVector */ - /* */ - /* <Description> */ - /* A simple structure used to store a 2D vector unit vector. Uses */ - /* FT_F2Dot14 types. */ - /* */ - /* <Fields> */ - /* x :: Horizontal coordinate. */ - /* */ - /* y :: Vertical coordinate. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_UnitVector + * + * @description: + * A simple structure used to store a 2D vector unit vector. Uses + * FT_F2Dot14 types. + * + * @fields: + * x :: + * Horizontal coordinate. + * + * y :: + * Vertical coordinate. + */ typedef struct FT_UnitVector_ { FT_F2Dot14 x; @@ -359,29 +360,33 @@ FT_BEGIN_HEADER } FT_UnitVector; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Matrix */ - /* */ - /* <Description> */ - /* A simple structure used to store a 2x2 matrix. Coefficients are */ - /* in 16.16 fixed-point format. The computation performed is: */ - /* */ - /* { */ - /* x' = x*xx + y*xy */ - /* y' = x*yx + y*yy */ - /* } */ - /* */ - /* <Fields> */ - /* xx :: Matrix coefficient. */ - /* */ - /* xy :: Matrix coefficient. */ - /* */ - /* yx :: Matrix coefficient. */ - /* */ - /* yy :: Matrix coefficient. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_Matrix + * + * @description: + * A simple structure used to store a 2x2 matrix. Coefficients are in + * 16.16 fixed-point format. The computation performed is: + * + * ``` + * x' = x*xx + y*xy + * y' = x*yx + y*yy + * ``` + * + * @fields: + * xx :: + * Matrix coefficient. + * + * xy :: + * Matrix coefficient. + * + * yx :: + * Matrix coefficient. + * + * yy :: + * Matrix coefficient. + */ typedef struct FT_Matrix_ { FT_Fixed xx, xy; @@ -390,19 +395,21 @@ FT_BEGIN_HEADER } FT_Matrix; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Data */ - /* */ - /* <Description> */ - /* Read-only binary data represented as a pointer and a length. */ - /* */ - /* <Fields> */ - /* pointer :: The data. */ - /* */ - /* length :: The length of the data in bytes. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_Data + * + * @description: + * Read-only binary data represented as a pointer and a length. + * + * @fields: + * pointer :: + * The data. + * + * length :: + * The length of the data in bytes. + */ typedef struct FT_Data_ { const FT_Byte* pointer; @@ -411,51 +418,52 @@ FT_BEGIN_HEADER } FT_Data; - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_Generic_Finalizer */ - /* */ - /* <Description> */ - /* Describe a function used to destroy the `client' data of any */ - /* FreeType object. See the description of the @FT_Generic type for */ - /* details of usage. */ - /* */ - /* <Input> */ - /* The address of the FreeType object that is under finalization. */ - /* Its client data is accessed through its `generic' field. */ - /* */ + /************************************************************************** + * + * @functype: + * FT_Generic_Finalizer + * + * @description: + * Describe a function used to destroy the 'client' data of any FreeType + * object. See the description of the @FT_Generic type for details of + * usage. + * + * @input: + * The address of the FreeType object that is under finalization. Its + * client data is accessed through its `generic` field. + */ typedef void (*FT_Generic_Finalizer)( void* object ); - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Generic */ - /* */ - /* <Description> */ - /* Client applications often need to associate their own data to a */ - /* variety of FreeType core objects. For example, a text layout API */ - /* might want to associate a glyph cache to a given size object. */ - /* */ - /* Some FreeType object contains a `generic' field, of type */ - /* FT_Generic, which usage is left to client applications and font */ - /* servers. */ - /* */ - /* It can be used to store a pointer to client-specific data, as well */ - /* as the address of a `finalizer' function, which will be called by */ - /* FreeType when the object is destroyed (for example, the previous */ - /* client example would put the address of the glyph cache destructor */ - /* in the `finalizer' field). */ - /* */ - /* <Fields> */ - /* data :: A typeless pointer to any client-specified data. This */ - /* field is completely ignored by the FreeType library. */ - /* */ - /* finalizer :: A pointer to a `generic finalizer' function, which */ - /* will be called when the object is destroyed. If this */ - /* field is set to NULL, no code will be called. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_Generic + * + * @description: + * Client applications often need to associate their own data to a + * variety of FreeType core objects. For example, a text layout API + * might want to associate a glyph cache to a given size object. + * + * Some FreeType object contains a `generic` field, of type `FT_Generic`, + * which usage is left to client applications and font servers. + * + * It can be used to store a pointer to client-specific data, as well as + * the address of a 'finalizer' function, which will be called by + * FreeType when the object is destroyed (for example, the previous + * client example would put the address of the glyph cache destructor in + * the `finalizer` field). + * + * @fields: + * data :: + * A typeless pointer to any client-specified data. This field is + * completely ignored by the FreeType library. + * + * finalizer :: + * A pointer to a 'generic finalizer' function, which will be called + * when the object is destroyed. If this field is set to `NULL`, no + * code will be called. + */ typedef struct FT_Generic_ { void* data; @@ -464,19 +472,19 @@ FT_BEGIN_HEADER } FT_Generic; - /*************************************************************************/ - /* */ - /* <Macro> */ - /* FT_MAKE_TAG */ - /* */ - /* <Description> */ - /* This macro converts four-letter tags that are used to label */ - /* TrueType tables into an unsigned long, to be used within FreeType. */ - /* */ - /* <Note> */ - /* The produced values *must* be 32-bit integers. Don't redefine */ - /* this macro. */ - /* */ + /************************************************************************** + * + * @macro: + * FT_MAKE_TAG + * + * @description: + * This macro converts four-letter tags that are used to label TrueType + * tables into an unsigned long, to be used within FreeType. + * + * @note: + * The produced values **must** be 32-bit integers. Don't redefine this + * macro. + */ #define FT_MAKE_TAG( _x1, _x2, _x3, _x4 ) \ (FT_Tag) \ ( ( (FT_ULong)_x1 << 24 ) | \ @@ -494,53 +502,56 @@ FT_BEGIN_HEADER /*************************************************************************/ - /*************************************************************************/ - /* */ - /* <Section> */ - /* list_processing */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * @section: + * list_processing + * + */ - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_ListNode */ - /* */ - /* <Description> */ - /* Many elements and objects in FreeType are listed through an */ - /* @FT_List record (see @FT_ListRec). As its name suggests, an */ - /* FT_ListNode is a handle to a single list element. */ - /* */ + /************************************************************************** + * + * @type: + * FT_ListNode + * + * @description: + * Many elements and objects in FreeType are listed through an @FT_List + * record (see @FT_ListRec). As its name suggests, an FT_ListNode is a + * handle to a single list element. + */ typedef struct FT_ListNodeRec_* FT_ListNode; - /*************************************************************************/ - /* */ - /* <Type> */ - /* FT_List */ - /* */ - /* <Description> */ - /* A handle to a list record (see @FT_ListRec). */ - /* */ + /************************************************************************** + * + * @type: + * FT_List + * + * @description: + * A handle to a list record (see @FT_ListRec). + */ typedef struct FT_ListRec_* FT_List; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_ListNodeRec */ - /* */ - /* <Description> */ - /* A structure used to hold a single list element. */ - /* */ - /* <Fields> */ - /* prev :: The previous element in the list. NULL if first. */ - /* */ - /* next :: The next element in the list. NULL if last. */ - /* */ - /* data :: A typeless pointer to the listed object. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_ListNodeRec + * + * @description: + * A structure used to hold a single list element. + * + * @fields: + * prev :: + * The previous element in the list. `NULL` if first. + * + * next :: + * The next element in the list. `NULL` if last. + * + * data :: + * A typeless pointer to the listed object. + */ typedef struct FT_ListNodeRec_ { FT_ListNode prev; @@ -550,20 +561,22 @@ FT_BEGIN_HEADER } FT_ListNodeRec; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_ListRec */ - /* */ - /* <Description> */ - /* A structure used to hold a simple doubly-linked list. These are */ - /* used in many parts of FreeType. */ - /* */ - /* <Fields> */ - /* head :: The head (first element) of doubly-linked list. */ - /* */ - /* tail :: The tail (last element) of doubly-linked list. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_ListRec + * + * @description: + * A structure used to hold a simple doubly-linked list. These are used + * in many parts of FreeType. + * + * @fields: + * head :: + * The head (first element) of doubly-linked list. + * + * tail :: + * The tail (last element) of doubly-linked list. + */ typedef struct FT_ListRec_ { FT_ListNode head; @@ -575,13 +588,13 @@ FT_BEGIN_HEADER #define FT_IS_EMPTY( list ) ( (list).head == 0 ) -#define FT_BOOL( x ) ( (FT_Bool)( x ) ) +#define FT_BOOL( x ) ( (FT_Bool)( (x) != 0 ) ) /* concatenate C tokens */ #define FT_ERR_XCAT( x, y ) x ## y #define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) - /* see `ftmoderr.h' for descriptions of the following macros */ + /* see `ftmoderr.h` for descriptions of the following macros */ #define FT_ERR( e ) FT_ERR_CAT( FT_ERR_PREFIX, e ) diff --git a/sdk/lib/3rdparty/freetype/include/freetype/ftwinfnt.h b/sdk/lib/3rdparty/freetype/include/freetype/ftwinfnt.h index 461c65b779152..3437913d53afd 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/ftwinfnt.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/ftwinfnt.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftwinfnt.h */ -/* */ -/* FreeType API for accessing Windows fnt-specific data. */ -/* */ -/* Copyright 2003-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftwinfnt.h + * + * FreeType API for accessing Windows fnt-specific data. + * + * Copyright (C) 2003-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTWINFNT_H_ @@ -32,44 +32,43 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* <Section> */ - /* winfnt_fonts */ - /* */ - /* <Title> */ - /* Window FNT Files */ - /* */ - /* <Abstract> */ - /* Windows FNT specific API. */ - /* */ - /* <Description> */ - /* This section contains the declaration of Windows FNT specific */ - /* functions. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * @section: + * winfnt_fonts + * + * @title: + * Window FNT Files + * + * @abstract: + * Windows FNT-specific API. + * + * @description: + * This section contains the declaration of Windows FNT-specific + * functions. + * + */ - /************************************************************************* + /************************************************************************** * * @enum: * FT_WinFNT_ID_XXX * * @description: - * A list of valid values for the `charset' byte in - * @FT_WinFNT_HeaderRec. Exact mapping tables for the various cpXXXX - * encodings (except for cp1361) can be found at - * ftp://ftp.unicode.org/Public in the MAPPINGS/VENDORS/MICSFT/WINDOWS - * subdirectory. cp1361 is roughly a superset of - * MAPPINGS/OBSOLETE/EASTASIA/KSC/JOHAB.TXT. + * A list of valid values for the `charset` byte in @FT_WinFNT_HeaderRec. + * Exact mapping tables for the various 'cpXXXX' encodings (except for + * 'cp1361') can be found at 'ftp://ftp.unicode.org/Public' in the + * `MAPPINGS/VENDORS/MICSFT/WINDOWS` subdirectory. 'cp1361' is roughly a + * superset of `MAPPINGS/OBSOLETE/EASTASIA/KSC/JOHAB.TXT`. * * @values: * FT_WinFNT_ID_DEFAULT :: - * This is used for font enumeration and font creation as a - * `don't care' value. Valid font files don't contain this value. - * When querying for information about the character set of the font - * that is currently selected into a specified device context, this - * return value (of the related Windows API) simply denotes failure. + * This is used for font enumeration and font creation as a 'don't + * care' value. Valid font files don't contain this value. When + * querying for information about the character set of the font that is + * currently selected into a specified device context, this return + * value (of the related Windows API) simply denotes failure. * * FT_WinFNT_ID_SYMBOL :: * There is no known mapping table available. @@ -80,26 +79,27 @@ FT_BEGIN_HEADER * FT_WinFNT_ID_OEM :: * From Michael Poettgen <michael@poettgen.de>: * - * The `Windows Font Mapping' article says that FT_WinFNT_ID_OEM - * is used for the charset of vector fonts, like `modern.fon', - * `roman.fon', and `script.fon' on Windows. + * The 'Windows Font Mapping' article says that `FT_WinFNT_ID_OEM` is + * used for the charset of vector fonts, like `modern.fon`, + * `roman.fon`, and `script.fon` on Windows. * - * The `CreateFont' documentation says: The FT_WinFNT_ID_OEM value - * specifies a character set that is operating-system dependent. + * The 'CreateFont' documentation says: The `FT_WinFNT_ID_OEM` value + * specifies a character set that is operating-system dependent. * - * The `IFIMETRICS' documentation from the `Windows Driver - * Development Kit' says: This font supports an OEM-specific - * character set. The OEM character set is system dependent. + * The 'IFIMETRICS' documentation from the 'Windows Driver Development + * Kit' says: This font supports an OEM-specific character set. The + * OEM character set is system dependent. * - * In general OEM, as opposed to ANSI (i.e., cp1252), denotes the - * second default codepage that most international versions of - * Windows have. It is one of the OEM codepages from + * In general OEM, as opposed to ANSI (i.e., 'cp1252'), denotes the + * second default codepage that most international versions of Windows + * have. It is one of the OEM codepages from * - * https://msdn.microsoft.com/en-us/goglobal/bb964655, + * https://docs.microsoft.com/en-us/windows/desktop/intl/code-page-identifiers + * , * - * and is used for the `DOS boxes', to support legacy applications. - * A German Windows version for example usually uses ANSI codepage - * 1252 and OEM codepage 850. + * and is used for the 'DOS boxes', to support legacy applications. A + * German Windows version for example usually uses ANSI codepage 1252 + * and OEM codepage 850. * * FT_WinFNT_ID_CP874 :: * A superset of Thai TIS 620 and ISO 8859-11. @@ -112,8 +112,8 @@ FT_BEGIN_HEADER * ordering and minor deviations). * * FT_WinFNT_ID_CP949 :: - * A superset of Korean Hangul KS~C 5601-1987 (with different - * ordering and minor deviations). + * A superset of Korean Hangul KS~C 5601-1987 (with different ordering + * and minor deviations). * * FT_WinFNT_ID_CP950 :: * A superset of traditional Chinese Big~5 ETen (with different @@ -173,14 +173,14 @@ FT_BEGIN_HEADER #define FT_WinFNT_ID_OEM 255 - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_WinFNT_HeaderRec */ - /* */ - /* <Description> */ - /* Windows FNT Header info. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_WinFNT_HeaderRec + * + * @description: + * Windows FNT Header info. + */ typedef struct FT_WinFNT_HeaderRec_ { FT_UShort version; @@ -223,18 +223,18 @@ FT_BEGIN_HEADER } FT_WinFNT_HeaderRec; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_WinFNT_Header */ - /* */ - /* <Description> */ - /* A handle to an @FT_WinFNT_HeaderRec structure. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_WinFNT_Header + * + * @description: + * A handle to an @FT_WinFNT_HeaderRec structure. + */ typedef struct FT_WinFNT_HeaderRec_* FT_WinFNT_Header; - /********************************************************************** + /************************************************************************** * * @function: * FT_Get_WinFNT_Header @@ -243,10 +243,12 @@ FT_BEGIN_HEADER * Retrieve a Windows FNT font info header. * * @input: - * face :: A handle to the input face. + * face :: + * A handle to the input face. * * @output: - * aheader :: The WinFNT header. + * aheader :: + * The WinFNT header. * * @return: * FreeType error code. 0~means success. diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/autohint.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/autohint.h index f4d308f68c26d..f64c28bb2caed 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/autohint.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/autohint.h @@ -1,73 +1,73 @@ -/***************************************************************************/ -/* */ -/* autohint.h */ -/* */ -/* High-level `autohint' module-specific interface (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* The auto-hinter is used to load and automatically hint glyphs if a */ - /* format-specific hinter isn't available. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * autohint.h + * + * High-level 'autohint' module-specific interface (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /************************************************************************** + * + * The auto-hinter is used to load and automatically hint glyphs if a + * format-specific hinter isn't available. + * + */ #ifndef AUTOHINT_H_ #define AUTOHINT_H_ - /*************************************************************************/ - /* */ - /* A small technical note regarding automatic hinting in order to */ - /* clarify this module interface. */ - /* */ - /* An automatic hinter might compute two kinds of data for a given face: */ - /* */ - /* - global hints: Usually some metrics that describe global properties */ - /* of the face. It is computed by scanning more or less */ - /* aggressively the glyphs in the face, and thus can be */ - /* very slow to compute (even if the size of global */ - /* hints is really small). */ - /* */ - /* - glyph hints: These describe some important features of the glyph */ - /* outline, as well as how to align them. They are */ - /* generally much faster to compute than global hints. */ - /* */ - /* The current FreeType auto-hinter does a pretty good job while */ - /* performing fast computations for both global and glyph hints. */ - /* However, we might be interested in introducing more complex and */ - /* powerful algorithms in the future, like the one described in the John */ - /* D. Hobby paper, which unfortunately requires a lot more horsepower. */ - /* */ - /* Because a sufficiently sophisticated font management system would */ - /* typically implement an LRU cache of opened face objects to reduce */ - /* memory usage, it is a good idea to be able to avoid recomputing */ - /* global hints every time the same face is re-opened. */ - /* */ - /* We thus provide the ability to cache global hints outside of the face */ - /* object, in order to speed up font re-opening time. Of course, this */ - /* feature is purely optional, so most client programs won't even notice */ - /* it. */ - /* */ - /* I initially thought that it would be a good idea to cache the glyph */ - /* hints too. However, my general idea now is that if you really need */ - /* to cache these too, you are simply in need of a new font format, */ - /* where all this information could be stored within the font file and */ - /* decoded on the fly. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * A small technical note regarding automatic hinting in order to clarify + * this module interface. + * + * An automatic hinter might compute two kinds of data for a given face: + * + * - global hints: Usually some metrics that describe global properties + * of the face. It is computed by scanning more or less + * aggressively the glyphs in the face, and thus can be + * very slow to compute (even if the size of global hints + * is really small). + * + * - glyph hints: These describe some important features of the glyph + * outline, as well as how to align them. They are + * generally much faster to compute than global hints. + * + * The current FreeType auto-hinter does a pretty good job while performing + * fast computations for both global and glyph hints. However, we might be + * interested in introducing more complex and powerful algorithms in the + * future, like the one described in the John D. Hobby paper, which + * unfortunately requires a lot more horsepower. + * + * Because a sufficiently sophisticated font management system would + * typically implement an LRU cache of opened face objects to reduce memory + * usage, it is a good idea to be able to avoid recomputing global hints + * every time the same face is re-opened. + * + * We thus provide the ability to cache global hints outside of the face + * object, in order to speed up font re-opening time. Of course, this + * feature is purely optional, so most client programs won't even notice + * it. + * + * I initially thought that it would be a good idea to cache the glyph + * hints too. However, my general idea now is that if you really need to + * cache these too, you are simply in need of a new font format, where all + * this information could be stored within the font file and decoded on the + * fly. + * + */ #include <ft2build.h> @@ -80,27 +80,31 @@ FT_BEGIN_HEADER typedef struct FT_AutoHinterRec_ *FT_AutoHinter; - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_AutoHinter_GlobalGetFunc */ - /* */ - /* <Description> */ - /* Retrieve the global hints computed for a given face object. The */ - /* resulting data is dissociated from the face and will survive a */ - /* call to FT_Done_Face(). It must be discarded through the API */ - /* FT_AutoHinter_GlobalDoneFunc(). */ - /* */ - /* <Input> */ - /* hinter :: A handle to the source auto-hinter. */ - /* */ - /* face :: A handle to the source face object. */ - /* */ - /* <Output> */ - /* global_hints :: A typeless pointer to the global hints. */ - /* */ - /* global_len :: The size in bytes of the global hints. */ - /* */ + /************************************************************************** + * + * @functype: + * FT_AutoHinter_GlobalGetFunc + * + * @description: + * Retrieve the global hints computed for a given face object. The + * resulting data is dissociated from the face and will survive a call to + * FT_Done_Face(). It must be discarded through the API + * FT_AutoHinter_GlobalDoneFunc(). + * + * @input: + * hinter :: + * A handle to the source auto-hinter. + * + * face :: + * A handle to the source face object. + * + * @output: + * global_hints :: + * A typeless pointer to the global hints. + * + * global_len :: + * The size in bytes of the global hints. + */ typedef void (*FT_AutoHinter_GlobalGetFunc)( FT_AutoHinter hinter, FT_Face face, @@ -108,69 +112,76 @@ FT_BEGIN_HEADER long* global_len ); - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_AutoHinter_GlobalDoneFunc */ - /* */ - /* <Description> */ - /* Discard the global hints retrieved through */ - /* FT_AutoHinter_GlobalGetFunc(). This is the only way these hints */ - /* are freed from memory. */ - /* */ - /* <Input> */ - /* hinter :: A handle to the auto-hinter module. */ - /* */ - /* global :: A pointer to retrieved global hints to discard. */ - /* */ + /************************************************************************** + * + * @functype: + * FT_AutoHinter_GlobalDoneFunc + * + * @description: + * Discard the global hints retrieved through + * FT_AutoHinter_GlobalGetFunc(). This is the only way these hints are + * freed from memory. + * + * @input: + * hinter :: + * A handle to the auto-hinter module. + * + * global :: + * A pointer to retrieved global hints to discard. + */ typedef void (*FT_AutoHinter_GlobalDoneFunc)( FT_AutoHinter hinter, void* global ); - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_AutoHinter_GlobalResetFunc */ - /* */ - /* <Description> */ - /* This function is used to recompute the global metrics in a given */ - /* font. This is useful when global font data changes (e.g. Multiple */ - /* Masters fonts where blend coordinates change). */ - /* */ - /* <Input> */ - /* hinter :: A handle to the source auto-hinter. */ - /* */ - /* face :: A handle to the face. */ - /* */ + /************************************************************************** + * + * @functype: + * FT_AutoHinter_GlobalResetFunc + * + * @description: + * This function is used to recompute the global metrics in a given font. + * This is useful when global font data changes (e.g. Multiple Masters + * fonts where blend coordinates change). + * + * @input: + * hinter :: + * A handle to the source auto-hinter. + * + * face :: + * A handle to the face. + */ typedef void (*FT_AutoHinter_GlobalResetFunc)( FT_AutoHinter hinter, FT_Face face ); - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_AutoHinter_GlyphLoadFunc */ - /* */ - /* <Description> */ - /* This function is used to load, scale, and automatically hint a */ - /* glyph from a given face. */ - /* */ - /* <Input> */ - /* face :: A handle to the face. */ - /* */ - /* glyph_index :: The glyph index. */ - /* */ - /* load_flags :: The load flags. */ - /* */ - /* <Note> */ - /* This function is capable of loading composite glyphs by hinting */ - /* each sub-glyph independently (which improves quality). */ - /* */ - /* It will call the font driver with @FT_Load_Glyph, with */ - /* @FT_LOAD_NO_SCALE set. */ - /* */ + /************************************************************************** + * + * @functype: + * FT_AutoHinter_GlyphLoadFunc + * + * @description: + * This function is used to load, scale, and automatically hint a glyph + * from a given face. + * + * @input: + * face :: + * A handle to the face. + * + * glyph_index :: + * The glyph index. + * + * load_flags :: + * The load flags. + * + * @note: + * This function is capable of loading composite glyphs by hinting each + * sub-glyph independently (which improves quality). + * + * It will call the font driver with @FT_Load_Glyph, with + * @FT_LOAD_NO_SCALE set. + */ typedef FT_Error (*FT_AutoHinter_GlyphLoadFunc)( FT_AutoHinter hinter, FT_GlyphSlot slot, @@ -179,14 +190,14 @@ FT_BEGIN_HEADER FT_Int32 load_flags ); - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_AutoHinter_InterfaceRec */ - /* */ - /* <Description> */ - /* The auto-hinter module's interface. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_AutoHinter_InterfaceRec + * + * @description: + * The auto-hinter module's interface. + */ typedef struct FT_AutoHinter_InterfaceRec_ { FT_AutoHinter_GlobalResetFunc reset_face; @@ -197,8 +208,6 @@ FT_BEGIN_HEADER } FT_AutoHinter_InterfaceRec, *FT_AutoHinter_Interface; -#ifndef FT_CONFIG_OPTION_PIC - #define FT_DEFINE_AUTOHINTER_INTERFACE( \ class_, \ reset_face_, \ @@ -214,27 +223,6 @@ FT_BEGIN_HEADER load_glyph_ \ }; -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DEFINE_AUTOHINTER_INTERFACE( \ - class_, \ - reset_face_, \ - get_global_hints_, \ - done_global_hints_, \ - load_glyph_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Library library, \ - FT_AutoHinter_InterfaceRec* clazz ) \ - { \ - FT_UNUSED( library ); \ - \ - clazz->reset_face = reset_face_; \ - clazz->get_global_hints = get_global_hints_; \ - clazz->done_global_hints = done_global_hints_; \ - clazz->load_glyph = load_glyph_; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ FT_END_HEADER diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/cffotypes.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/cffotypes.h index 57e7591d41a3e..b26893eab3b58 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/cffotypes.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/cffotypes.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* cffotypes.h */ -/* */ -/* Basic OpenType/CFF object type definitions (specification). */ -/* */ -/* Copyright 2017-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * cffotypes.h + * + * Basic OpenType/CFF object type definitions (specification). + * + * Copyright (C) 2017-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef CFFOTYPES_H_ @@ -33,14 +33,14 @@ FT_BEGIN_HEADER typedef TT_Face CFF_Face; - /*************************************************************************/ - /* */ - /* <Type> */ - /* CFF_Size */ - /* */ - /* <Description> */ - /* A handle to an OpenType size object. */ - /* */ + /************************************************************************** + * + * @type: + * CFF_Size + * + * @description: + * A handle to an OpenType size object. + */ typedef struct CFF_SizeRec_ { FT_SizeRec root; @@ -49,14 +49,14 @@ FT_BEGIN_HEADER } CFF_SizeRec, *CFF_Size; - /*************************************************************************/ - /* */ - /* <Type> */ - /* CFF_GlyphSlot */ - /* */ - /* <Description> */ - /* A handle to an OpenType glyph slot object. */ - /* */ + /************************************************************************** + * + * @type: + * CFF_GlyphSlot + * + * @description: + * A handle to an OpenType glyph slot object. + */ typedef struct CFF_GlyphSlotRec_ { FT_GlyphSlotRec root; @@ -70,14 +70,14 @@ FT_BEGIN_HEADER } CFF_GlyphSlotRec, *CFF_GlyphSlot; - /*************************************************************************/ - /* */ - /* <Type> */ - /* CFF_Internal */ - /* */ - /* <Description> */ - /* The interface to the `internal' field of `FT_Size'. */ - /* */ + /************************************************************************** + * + * @type: + * CFF_Internal + * + * @description: + * The interface to the 'internal' field of `FT_Size`. + */ typedef struct CFF_InternalRec_ { PSH_Globals topfont; @@ -86,10 +86,10 @@ FT_BEGIN_HEADER } CFF_InternalRec, *CFF_Internal; - /*************************************************************************/ - /* */ - /* Subglyph transformation record. */ - /* */ + /************************************************************************** + * + * Subglyph transformation record. + */ typedef struct CFF_Transform_ { FT_Fixed xx, xy; /* transformation matrix coefficients */ diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/cfftypes.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/cfftypes.h index 7c07e1a3768a8..2fc905ec7951b 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/cfftypes.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/cfftypes.h @@ -1,20 +1,20 @@ -/***************************************************************************/ -/* */ -/* cfftypes.h */ -/* */ -/* Basic OpenType/CFF type definitions and interface (specification */ -/* only). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * cfftypes.h + * + * Basic OpenType/CFF type definitions and interface (specification + * only). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef CFFTYPES_H_ @@ -33,34 +33,39 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* <Struct> */ - /* CFF_IndexRec */ - /* */ - /* <Description> */ - /* A structure used to model a CFF Index table. */ - /* */ - /* <Fields> */ - /* stream :: The source input stream. */ - /* */ - /* start :: The position of the first index byte in the */ - /* input stream. */ - /* */ - /* count :: The number of elements in the index. */ - /* */ - /* off_size :: The size in bytes of object offsets in index. */ - /* */ - /* data_offset :: The position of first data byte in the index's */ - /* bytes. */ - /* */ - /* data_size :: The size of the data table in this index. */ - /* */ - /* offsets :: A table of element offsets in the index. Must be */ - /* loaded explicitly. */ - /* */ - /* bytes :: If the index is loaded in memory, its bytes. */ - /* */ + /************************************************************************** + * + * @struct: + * CFF_IndexRec + * + * @description: + * A structure used to model a CFF Index table. + * + * @fields: + * stream :: + * The source input stream. + * + * start :: + * The position of the first index byte in the input stream. + * + * count :: + * The number of elements in the index. + * + * off_size :: + * The size in bytes of object offsets in index. + * + * data_offset :: + * The position of first data byte in the index's bytes. + * + * data_size :: + * The size of the data table in this index. + * + * offsets :: + * A table of element offsets in the index. Must be loaded explicitly. + * + * bytes :: + * If the index is loaded in memory, its bytes. + */ typedef struct CFF_IndexRec_ { FT_Stream stream; diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/ftcalc.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/ftcalc.h index 818a812359d35..2986ec359b180 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/ftcalc.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/ftcalc.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftcalc.h */ -/* */ -/* Arithmetic computations (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftcalc.h + * + * Arithmetic computations (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTCALC_H_ @@ -27,11 +27,11 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* FT_MulDiv() and FT_MulFix() are declared in freetype.h. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * FT_MulDiv() and FT_MulFix() are declared in freetype.h. + * + */ #ifndef FT_CONFIG_OPTION_NO_ASSEMBLER /* Provide assembler fragments for performance-critical functions. */ @@ -246,29 +246,32 @@ FT_BEGIN_HEADER #endif - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_MulDiv_No_Round */ - /* */ - /* <Description> */ - /* A very simple function used to perform the computation `(a*b)/c' */ - /* (without rounding) with maximum accuracy (it uses a 64-bit */ - /* intermediate integer whenever necessary). */ - /* */ - /* This function isn't necessarily as fast as some processor specific */ - /* operations, but is at least completely portable. */ - /* */ - /* <Input> */ - /* a :: The first multiplier. */ - /* b :: The second multiplier. */ - /* c :: The divisor. */ - /* */ - /* <Return> */ - /* The result of `(a*b)/c'. This function never traps when trying to */ - /* divide by zero; it simply returns `MaxInt' or `MinInt' depending */ - /* on the signs of `a' and `b'. */ - /* */ + /************************************************************************** + * + * @function: + * FT_MulDiv_No_Round + * + * @description: + * A very simple function used to perform the computation '(a*b)/c' + * (without rounding) with maximum accuracy (it uses a 64-bit + * intermediate integer whenever necessary). + * + * This function isn't necessarily as fast as some processor-specific + * operations, but is at least completely portable. + * + * @input: + * a :: + * The first multiplier. + * b :: + * The second multiplier. + * c :: + * The divisor. + * + * @return: + * The result of '(a*b)/c'. This function never traps when trying to + * divide by zero; it simply returns 'MaxInt' or 'MinInt' depending on + * the signs of 'a' and 'b'. + */ FT_BASE( FT_Long ) FT_MulDiv_No_Round( FT_Long a, FT_Long b, @@ -276,12 +279,11 @@ FT_BEGIN_HEADER /* - * A variant of FT_Matrix_Multiply which scales its result afterwards. - * The idea is that both `a' and `b' are scaled by factors of 10 so that - * the values are as precise as possible to get a correct result during - * the 64bit multiplication. Let `sa' and `sb' be the scaling factors of - * `a' and `b', respectively, then the scaling factor of the result is - * `sa*sb'. + * A variant of FT_Matrix_Multiply which scales its result afterwards. The + * idea is that both `a' and `b' are scaled by factors of 10 so that the + * values are as precise as possible to get a correct result during the + * 64bit multiplication. Let `sa' and `sb' be the scaling factors of `a' + * and `b', respectively, then the scaling factor of the result is `sa*sb'. */ FT_BASE( void ) FT_Matrix_Multiply_Scaled( const FT_Matrix* a, @@ -290,8 +292,23 @@ FT_BEGIN_HEADER /* - * A variant of FT_Vector_Transform. See comments for - * FT_Matrix_Multiply_Scaled. + * Check a matrix. If the transformation would lead to extreme shear or + * extreme scaling, for example, return 0. If everything is OK, return 1. + * + * Based on geometric considerations we use the following inequality to + * identify a degenerate matrix. + * + * 50 * abs(xx*yy - xy*yx) < xx^2 + xy^2 + yx^2 + yy^2 + * + * Value 50 is heuristic. + */ + FT_BASE( FT_Bool ) + FT_Matrix_Check( const FT_Matrix* matrix ); + + + /* + * A variant of FT_Vector_Transform. See comments for + * FT_Matrix_Multiply_Scaled. */ FT_BASE( void ) FT_Vector_Transform_Scaled( FT_Vector* vector, @@ -300,22 +317,22 @@ FT_BEGIN_HEADER /* - * This function normalizes a vector and returns its original length. - * The normalized vector is a 16.16 fixed-point unit vector with length - * close to 0x10000. The accuracy of the returned length is limited to - * 16 bits also. The function utilizes quick inverse square root - * approximation without divisions and square roots relying on Newton's - * iterations instead. + * This function normalizes a vector and returns its original length. The + * normalized vector is a 16.16 fixed-point unit vector with length close + * to 0x10000. The accuracy of the returned length is limited to 16 bits + * also. The function utilizes quick inverse square root approximation + * without divisions and square roots relying on Newton's iterations + * instead. */ FT_BASE( FT_UInt32 ) FT_Vector_NormLen( FT_Vector* vector ); /* - * Return -1, 0, or +1, depending on the orientation of a given corner. - * We use the Cartesian coordinate system, with positive vertical values - * going upwards. The function returns +1 if the corner turns to the - * left, -1 to the right, and 0 for undecidable cases. + * Return -1, 0, or +1, depending on the orientation of a given corner. We + * use the Cartesian coordinate system, with positive vertical values going + * upwards. The function returns +1 if the corner turns to the left, -1 to + * the right, and 0 for undecidable cases. */ FT_BASE( FT_Int ) ft_corner_orientation( FT_Pos in_x, @@ -325,9 +342,9 @@ FT_BEGIN_HEADER /* - * Return TRUE if a corner is flat or nearly flat. This is equivalent to - * saying that the corner point is close to its neighbors, or inside an - * ellipse defined by the neighbor focal points to be more precise. + * Return TRUE if a corner is flat or nearly flat. This is equivalent to + * saying that the corner point is close to its neighbors, or inside an + * ellipse defined by the neighbor focal points to be more precise. */ FT_BASE( FT_Int ) ft_corner_is_flat( FT_Pos in_x, @@ -337,10 +354,11 @@ FT_BEGIN_HEADER /* - * Return the most significant bit index. + * Return the most significant bit index. */ #ifndef FT_CONFIG_OPTION_NO_ASSEMBLER + #if defined( __GNUC__ ) && \ ( __GNUC__ > 3 || ( __GNUC__ == 3 && __GNUC_MINOR__ >= 4 ) ) @@ -352,9 +370,34 @@ FT_BEGIN_HEADER #define FT_MSB( x ) ( 31 - __builtin_clzl( x ) ) +#endif /* __GNUC__ */ + + +#elif defined( _MSC_VER ) && ( _MSC_VER >= 1400 ) + +#if FT_SIZEOF_INT == 4 + +#include <intrin.h> + + static __inline FT_Int32 + FT_MSB_i386( FT_UInt32 x ) + { + unsigned long where; + + + /* not available in older VC versions */ + _BitScanReverse( &where, x ); + + return (FT_Int32)where; + } + +#define FT_MSB( x ) ( FT_MSB_i386( x ) ) + #endif -#endif /* __GNUC__ */ +#endif /* _MSC_VER */ + + #endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */ #ifndef FT_MSB @@ -366,8 +409,8 @@ FT_BEGIN_HEADER /* - * Return sqrt(x*x+y*y), which is the same as `FT_Vector_Length' but uses - * two fixed-point arguments instead. + * Return sqrt(x*x+y*y), which is the same as `FT_Vector_Length' but uses + * two fixed-point arguments instead. */ FT_BASE( FT_Fixed ) FT_Hypot( FT_Fixed x, @@ -376,23 +419,24 @@ FT_BEGIN_HEADER #if 0 - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_SqrtFixed */ - /* */ - /* <Description> */ - /* Computes the square root of a 16.16 fixed-point value. */ - /* */ - /* <Input> */ - /* x :: The value to compute the root for. */ - /* */ - /* <Return> */ - /* The result of `sqrt(x)'. */ - /* */ - /* <Note> */ - /* This function is not very fast. */ - /* */ + /************************************************************************** + * + * @function: + * FT_SqrtFixed + * + * @description: + * Computes the square root of a 16.16 fixed-point value. + * + * @input: + * x :: + * The value to compute the root for. + * + * @return: + * The result of 'sqrt(x)'. + * + * @note: + * This function is not very fast. + */ FT_BASE( FT_Int32 ) FT_SqrtFixed( FT_Int32 x ); @@ -409,14 +453,23 @@ FT_BEGIN_HEADER : ( -( ( 32 - (x) ) & -64 ) ) ) /* - * The following macros have two purposes. + * The following macros have two purposes. * - * . Tag places where overflow is expected and harmless. + * - Tag places where overflow is expected and harmless. * - * . Avoid run-time sanitizer errors. + * - Avoid run-time sanitizer errors. * - * Use with care! + * Use with care! */ +#define ADD_INT( a, b ) \ + (FT_Int)( (FT_UInt)(a) + (FT_UInt)(b) ) +#define SUB_INT( a, b ) \ + (FT_Int)( (FT_UInt)(a) - (FT_UInt)(b) ) +#define MUL_INT( a, b ) \ + (FT_Int)( (FT_UInt)(a) * (FT_UInt)(b) ) +#define NEG_INT( a ) \ + (FT_Int)( (FT_UInt)0 - (FT_UInt)(a) ) + #define ADD_LONG( a, b ) \ (FT_Long)( (FT_ULong)(a) + (FT_ULong)(b) ) #define SUB_LONG( a, b ) \ @@ -435,6 +488,19 @@ FT_BEGIN_HEADER #define NEG_INT32( a ) \ (FT_Int32)( (FT_UInt32)0 - (FT_UInt32)(a) ) +#ifdef FT_LONG64 + +#define ADD_INT64( a, b ) \ + (FT_Int64)( (FT_UInt64)(a) + (FT_UInt64)(b) ) +#define SUB_INT64( a, b ) \ + (FT_Int64)( (FT_UInt64)(a) - (FT_UInt64)(b) ) +#define MUL_INT64( a, b ) \ + (FT_Int64)( (FT_UInt64)(a) * (FT_UInt64)(b) ) +#define NEG_INT64( a ) \ + (FT_Int64)( (FT_UInt64)0 - (FT_UInt64)(a) ) + +#endif /* FT_LONG64 */ + FT_END_HEADER diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/ftdebug.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/ftdebug.h index 292a4eedb8ba6..7e37ad2a0af4b 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/ftdebug.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/ftdebug.h @@ -1,24 +1,24 @@ -/***************************************************************************/ -/* */ -/* ftdebug.h */ -/* */ -/* Debugging and logging component (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/* */ -/* IMPORTANT: A description of FreeType's debugging support can be */ -/* found in `docs/DEBUG.TXT'. Read it if you need to use or */ -/* understand this code. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftdebug.h + * + * Debugging and logging component (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * IMPORTANT: A description of FreeType's debugging support can be + * found in 'docs/DEBUG.TXT'. Read it if you need to use or + * understand this code. + * + */ #ifndef FTDEBUG_H_ @@ -42,12 +42,12 @@ FT_BEGIN_HEADER #endif - /*************************************************************************/ - /* */ - /* Define the trace enums as well as the trace levels array when they */ - /* are needed. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * Define the trace enums as well as the trace levels array when they are + * needed. + * + */ #ifdef FT_DEBUG_LEVEL_TRACE @@ -62,32 +62,37 @@ FT_BEGIN_HEADER } FT_Trace; - /* defining the array of trace levels, provided by `src/base/ftdebug.c' */ - extern int ft_trace_levels[trace_count]; + /* a pointer to the array of trace levels, */ + /* provided by `src/base/ftdebug.c' */ + extern int* ft_trace_levels; #undef FT_TRACE_DEF #endif /* FT_DEBUG_LEVEL_TRACE */ - /*************************************************************************/ - /* */ - /* Define the FT_TRACE macro */ - /* */ - /* IMPORTANT! */ - /* */ - /* Each component must define the macro FT_COMPONENT to a valid FT_Trace */ - /* value before using any TRACE macro. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * Define the FT_TRACE macro + * + * IMPORTANT! + * + * Each component must define the macro FT_COMPONENT to a valid FT_Trace + * value before using any TRACE macro. + * + */ #ifdef FT_DEBUG_LEVEL_TRACE -#define FT_TRACE( level, varformat ) \ - do \ - { \ - if ( ft_trace_levels[FT_COMPONENT] >= level ) \ - FT_Message varformat; \ + /* we need two macros here to make cpp expand `FT_COMPONENT' */ +#define FT_TRACE_COMP( x ) FT_TRACE_COMP_( x ) +#define FT_TRACE_COMP_( x ) trace_ ## x + +#define FT_TRACE( level, varformat ) \ + do \ + { \ + if ( ft_trace_levels[FT_TRACE_COMP( FT_COMPONENT )] >= level ) \ + FT_Message varformat; \ } while ( 0 ) #else /* !FT_DEBUG_LEVEL_TRACE */ @@ -97,62 +102,85 @@ FT_BEGIN_HEADER #endif /* !FT_DEBUG_LEVEL_TRACE */ - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Trace_Get_Count */ - /* */ - /* <Description> */ - /* Return the number of available trace components. */ - /* */ - /* <Return> */ - /* The number of trace components. 0 if FreeType 2 is not built with */ - /* FT_DEBUG_LEVEL_TRACE definition. */ - /* */ - /* <Note> */ - /* This function may be useful if you want to access elements of */ - /* the internal `ft_trace_levels' array by an index. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Trace_Get_Count + * + * @description: + * Return the number of available trace components. + * + * @return: + * The number of trace components. 0 if FreeType 2 is not built with + * FT_DEBUG_LEVEL_TRACE definition. + * + * @note: + * This function may be useful if you want to access elements of the + * internal trace levels array by an index. + */ FT_BASE( FT_Int ) FT_Trace_Get_Count( void ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Trace_Get_Name */ - /* */ - /* <Description> */ - /* Return the name of a trace component. */ - /* */ - /* <Input> */ - /* The index of the trace component. */ - /* */ - /* <Return> */ - /* The name of the trace component. This is a statically allocated */ - /* C string, so do not free it after use. NULL if FreeType 2 is not */ - /* built with FT_DEBUG_LEVEL_TRACE definition. */ - /* */ - /* <Note> */ - /* Use @FT_Trace_Get_Count to get the number of available trace */ - /* components. */ - /* */ - /* This function may be useful if you want to control FreeType 2's */ - /* debug level in your application. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Trace_Get_Name + * + * @description: + * Return the name of a trace component. + * + * @input: + * The index of the trace component. + * + * @return: + * The name of the trace component. This is a statically allocated + * C~string, so do not free it after use. `NULL` if FreeType is not + * built with FT_DEBUG_LEVEL_TRACE definition. + * + * @note: + * Use @FT_Trace_Get_Count to get the number of available trace + * components. + */ FT_BASE( const char* ) FT_Trace_Get_Name( FT_Int idx ); - /*************************************************************************/ - /* */ - /* You need two opening and closing parentheses! */ - /* */ - /* Example: FT_TRACE0(( "Value is %i", foo )) */ - /* */ - /* Output of the FT_TRACEX macros is sent to stderr. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * @function: + * FT_Trace_Disable + * + * @description: + * Switch off tracing temporarily. It can be activated again with + * @FT_Trace_Enable. + */ + FT_BASE( void ) + FT_Trace_Disable( void ); + + + /************************************************************************** + * + * @function: + * FT_Trace_Enable + * + * @description: + * Activate tracing. Use it after tracing has been switched off with + * @FT_Trace_Disable. + */ + FT_BASE( void ) + FT_Trace_Enable( void ); + + + /************************************************************************** + * + * You need two opening and closing parentheses! + * + * Example: FT_TRACE0(( "Value is %i", foo )) + * + * Output of the FT_TRACEX macros is sent to stderr. + * + */ #define FT_TRACE0( varformat ) FT_TRACE( 0, varformat ) #define FT_TRACE1( varformat ) FT_TRACE( 1, varformat ) @@ -164,13 +192,13 @@ FT_BEGIN_HEADER #define FT_TRACE7( varformat ) FT_TRACE( 7, varformat ) - /*************************************************************************/ - /* */ - /* Define the FT_ERROR macro. */ - /* */ - /* Output of this macro is sent to stderr. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * Define the FT_ERROR macro. + * + * Output of this macro is sent to stderr. + * + */ #ifdef FT_DEBUG_LEVEL_ERROR @@ -183,12 +211,12 @@ FT_BEGIN_HEADER #endif /* !FT_DEBUG_LEVEL_ERROR */ - /*************************************************************************/ - /* */ - /* Define the FT_ASSERT and FT_THROW macros. The call to `FT_Throw' */ - /* makes it possible to easily set a breakpoint at this function. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * Define the FT_ASSERT and FT_THROW macros. The call to `FT_Throw` makes + * it possible to easily set a breakpoint at this function. + * + */ #ifdef FT_DEBUG_LEVEL_ERROR @@ -215,16 +243,17 @@ FT_BEGIN_HEADER #endif /* !FT_DEBUG_LEVEL_ERROR */ - /*************************************************************************/ - /* */ - /* Define `FT_Message' and `FT_Panic' when needed. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * Define `FT_Message` and `FT_Panic` when needed. + * + */ #ifdef FT_DEBUG_LEVEL_ERROR #include "stdio.h" /* for vfprintf() */ + /* print a message */ FT_BASE( void ) FT_Message( const char* fmt, diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/ftdrv.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/ftdrv.h index 58dd35a933772..09e846e1c794f 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/ftdrv.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/ftdrv.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftdrv.h */ -/* */ -/* FreeType internal font driver interface (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftdrv.h + * + * FreeType internal font driver interface (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTDRV_H_ @@ -87,73 +87,80 @@ FT_BEGIN_HEADER FT_Fixed* advances ); - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Driver_ClassRec */ - /* */ - /* <Description> */ - /* The font driver class. This structure mostly contains pointers to */ - /* driver methods. */ - /* */ - /* <Fields> */ - /* root :: The parent module. */ - /* */ - /* face_object_size :: The size of a face object in bytes. */ - /* */ - /* size_object_size :: The size of a size object in bytes. */ - /* */ - /* slot_object_size :: The size of a glyph object in bytes. */ - /* */ - /* init_face :: The format-specific face constructor. */ - /* */ - /* done_face :: The format-specific face destructor. */ - /* */ - /* init_size :: The format-specific size constructor. */ - /* */ - /* done_size :: The format-specific size destructor. */ - /* */ - /* init_slot :: The format-specific slot constructor. */ - /* */ - /* done_slot :: The format-specific slot destructor. */ - /* */ - /* */ - /* load_glyph :: A function handle to load a glyph to a slot. */ - /* This field is mandatory! */ - /* */ - /* get_kerning :: A function handle to return the unscaled */ - /* kerning for a given pair of glyphs. Can be */ - /* set to 0 if the format doesn't support */ - /* kerning. */ - /* */ - /* attach_file :: This function handle is used to read */ - /* additional data for a face from another */ - /* file/stream. For example, this can be used to */ - /* add data from AFM or PFM files on a Type 1 */ - /* face, or a CIDMap on a CID-keyed face. */ - /* */ - /* get_advances :: A function handle used to return advance */ - /* widths of `count' glyphs (in font units), */ - /* starting at `first'. The `vertical' flag must */ - /* be set to get vertical advance heights. The */ - /* `advances' buffer is caller-allocated. */ - /* The idea of this function is to be able to */ - /* perform device-independent text layout without */ - /* loading a single glyph image. */ - /* */ - /* request_size :: A handle to a function used to request the new */ - /* character size. Can be set to 0 if the */ - /* scaling done in the base layer suffices. */ - /* */ - /* select_size :: A handle to a function used to select a new */ - /* fixed size. It is used only if */ - /* @FT_FACE_FLAG_FIXED_SIZES is set. Can be set */ - /* to 0 if the scaling done in the base layer */ - /* suffices. */ - /* <Note> */ - /* Most function pointers, with the exception of `load_glyph', can be */ - /* set to 0 to indicate a default behaviour. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_Driver_ClassRec + * + * @description: + * The font driver class. This structure mostly contains pointers to + * driver methods. + * + * @fields: + * root :: + * The parent module. + * + * face_object_size :: + * The size of a face object in bytes. + * + * size_object_size :: + * The size of a size object in bytes. + * + * slot_object_size :: + * The size of a glyph object in bytes. + * + * init_face :: + * The format-specific face constructor. + * + * done_face :: + * The format-specific face destructor. + * + * init_size :: + * The format-specific size constructor. + * + * done_size :: + * The format-specific size destructor. + * + * init_slot :: + * The format-specific slot constructor. + * + * done_slot :: + * The format-specific slot destructor. + * + * + * load_glyph :: + * A function handle to load a glyph to a slot. This field is + * mandatory! + * + * get_kerning :: + * A function handle to return the unscaled kerning for a given pair of + * glyphs. Can be set to 0 if the format doesn't support kerning. + * + * attach_file :: + * This function handle is used to read additional data for a face from + * another file/stream. For example, this can be used to add data from + * AFM or PFM files on a Type 1 face, or a CIDMap on a CID-keyed face. + * + * get_advances :: + * A function handle used to return advance widths of 'count' glyphs + * (in font units), starting at 'first'. The 'vertical' flag must be + * set to get vertical advance heights. The 'advances' buffer is + * caller-allocated. The idea of this function is to be able to + * perform device-independent text layout without loading a single + * glyph image. + * + * request_size :: + * A handle to a function used to request the new character size. Can + * be set to 0 if the scaling done in the base layer suffices. + * + * select_size :: + * A handle to a function used to select a new fixed size. It is used + * only if @FT_FACE_FLAG_FIXED_SIZES is set. Can be set to 0 if the + * scaling done in the base layer suffices. + * @note: + * Most function pointers, with the exception of `load_glyph`, can be set + * to 0 to indicate a default behaviour. + */ typedef struct FT_Driver_ClassRec_ { FT_Module_Class root; @@ -184,45 +191,28 @@ FT_BEGIN_HEADER } FT_Driver_ClassRec, *FT_Driver_Class; - /*************************************************************************/ - /* */ - /* <Macro> */ - /* FT_DECLARE_DRIVER */ - /* */ - /* <Description> */ - /* Used to create a forward declaration of an FT_Driver_ClassRec */ - /* struct instance. */ - /* */ - /* <Macro> */ - /* FT_DEFINE_DRIVER */ - /* */ - /* <Description> */ - /* Used to initialize an instance of FT_Driver_ClassRec struct. */ - /* */ - /* When FT_CONFIG_OPTION_PIC is defined a `create' function has to be */ - /* called with a pointer where the allocated structure is returned. */ - /* And when it is no longer needed a `destroy' function needs to be */ - /* called to release that allocation. */ - /* */ - /* `ftinit.c' (ft_create_default_module_classes) already contains a */ - /* mechanism to call these functions for the default modules */ - /* described in `ftmodule.h'. */ - /* */ - /* Notice that the created `create' and `destroy' functions call */ - /* `pic_init' and `pic_free' to allow you to manually allocate and */ - /* initialize any additional global data, like a module specific */ - /* interface, and put them in the global pic container defined in */ - /* `ftpic.h'. If you don't need them just implement the functions as */ - /* empty to resolve the link error. Also the `pic_init' and */ - /* `pic_free' functions should be declared in `pic.h', to be referred */ - /* by driver definition calling `FT_DEFINE_DRIVER' in following. */ - /* */ - /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ - /* allocated in the global scope (or the scope where the macro is */ - /* used). */ - /* */ -#ifndef FT_CONFIG_OPTION_PIC - + /************************************************************************** + * + * @macro: + * FT_DECLARE_DRIVER + * + * @description: + * Used to create a forward declaration of an FT_Driver_ClassRec struct + * instance. + * + * @macro: + * FT_DEFINE_DRIVER + * + * @description: + * Used to initialize an instance of FT_Driver_ClassRec struct. + * + * `ftinit.c` (ft_create_default_module_classes) already contains a + * mechanism to call these functions for the default modules described in + * `ftmodule.h`. + * + * The struct will be allocated in the global scope (or the scope where + * the macro is used). + */ #define FT_DECLARE_DRIVER( class_ ) \ FT_CALLBACK_TABLE \ const FT_Driver_ClassRec class_; @@ -289,108 +279,6 @@ FT_BEGIN_HEADER select_size_ \ }; -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DECLARE_DRIVER( class_ ) FT_DECLARE_MODULE( class_ ) - -#define FT_DEFINE_DRIVER( \ - class_, \ - flags_, \ - size_, \ - name_, \ - version_, \ - requires_, \ - interface_, \ - init_, \ - done_, \ - get_interface_, \ - face_object_size_, \ - size_object_size_, \ - slot_object_size_, \ - init_face_, \ - done_face_, \ - init_size_, \ - done_size_, \ - init_slot_, \ - done_slot_, \ - load_glyph_, \ - get_kerning_, \ - attach_file_, \ - get_advances_, \ - request_size_, \ - select_size_ ) \ - void \ - FT_Destroy_Class_ ## class_( FT_Library library, \ - FT_Module_Class* clazz ) \ - { \ - FT_Memory memory = library->memory; \ - FT_Driver_Class dclazz = (FT_Driver_Class)clazz; \ - \ - \ - class_ ## _pic_free( library ); \ - if ( dclazz ) \ - FT_FREE( dclazz ); \ - } \ - \ - \ - FT_Error \ - FT_Create_Class_ ## class_( FT_Library library, \ - FT_Module_Class** output_class ) \ - { \ - FT_Driver_Class clazz = NULL; \ - FT_Error error; \ - FT_Memory memory = library->memory; \ - \ - \ - if ( FT_ALLOC( clazz, sizeof ( *clazz ) ) ) \ - return error; \ - \ - error = class_ ## _pic_init( library ); \ - if ( error ) \ - { \ - FT_FREE( clazz ); \ - return error; \ - } \ - \ - FT_DEFINE_ROOT_MODULE( flags_, \ - size_, \ - name_, \ - version_, \ - requires_, \ - interface_, \ - init_, \ - done_, \ - get_interface_ ) \ - \ - clazz->face_object_size = face_object_size_; \ - clazz->size_object_size = size_object_size_; \ - clazz->slot_object_size = slot_object_size_; \ - \ - clazz->init_face = init_face_; \ - clazz->done_face = done_face_; \ - \ - clazz->init_size = init_size_; \ - clazz->done_size = done_size_; \ - \ - clazz->init_slot = init_slot_; \ - clazz->done_slot = done_slot_; \ - \ - clazz->load_glyph = load_glyph_; \ - \ - clazz->get_kerning = get_kerning_; \ - clazz->attach_file = attach_file_; \ - clazz->get_advances = get_advances_; \ - \ - clazz->request_size = request_size_; \ - clazz->select_size = select_size_; \ - \ - *output_class = (FT_Module_Class*)clazz; \ - \ - return FT_Err_Ok; \ - } - - -#endif /* FT_CONFIG_OPTION_PIC */ FT_END_HEADER diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/ftgloadr.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/ftgloadr.h index a002fdbfca3cd..770871d81be0e 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/ftgloadr.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/ftgloadr.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftgloadr.h */ -/* */ -/* The FreeType glyph loader (specification). */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftgloadr.h + * + * The FreeType glyph loader (specification). + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTGLOADR_H_ @@ -27,15 +27,15 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_GlyphLoader */ - /* */ - /* <Description> */ - /* The glyph loader is an internal object used to load several glyphs */ - /* together (for example, in the case of composites). */ - /* */ + /************************************************************************** + * + * @struct: + * FT_GlyphLoader + * + * @description: + * The glyph loader is an internal object used to load several glyphs + * together (for example, in the case of composites). + */ typedef struct FT_SubGlyphRec_ { FT_Int index; @@ -138,11 +138,6 @@ FT_BEGIN_HEADER FT_BASE( void ) FT_GlyphLoader_Add( FT_GlyphLoader loader ); - /* copy points from one glyph loader to another */ - FT_BASE( FT_Error ) - FT_GlyphLoader_CopyPoints( FT_GlyphLoader target, - FT_GlyphLoader source ); - /* */ diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/fthash.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/fthash.h index f22f9d5d39024..249188040b3ae 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/fthash.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/fthash.h @@ -1,10 +1,10 @@ -/***************************************************************************/ -/* */ -/* fthash.h */ -/* */ -/* Hashing functions (specification). */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * fthash.h + * + * Hashing functions (specification). + * + */ /* * Copyright 2000 Computing Research Labs, New Mexico State University @@ -30,13 +30,13 @@ * THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - /*************************************************************************/ - /* */ - /* This file is based on code from bdf.c,v 1.22 2000/03/16 20:08:50 */ - /* */ - /* taken from Mark Leisher's xmbdfed package */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * This file is based on code from bdf.c,v 1.22 2000/03/16 20:08:50 + * + * taken from Mark Leisher's xmbdfed package + * + */ #ifndef FTHASH_H_ diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/ftmemory.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/ftmemory.h index 054eaec31f7db..78bd3bc229f81 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/ftmemory.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/ftmemory.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftmemory.h */ -/* */ -/* The FreeType memory management macros (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftmemory.h + * + * The FreeType memory management macros (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTMEMORY_H_ @@ -28,16 +28,16 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* <Macro> */ - /* FT_SET_ERROR */ - /* */ - /* <Description> */ - /* This macro is used to set an implicit `error' variable to a given */ - /* expression's value (usually a function call), and convert it to a */ - /* boolean which is set whenever the value is != 0. */ - /* */ + /************************************************************************** + * + * @macro: + * FT_SET_ERROR + * + * @description: + * This macro is used to set an implicit 'error' variable to a given + * expression's value (usually a function call), and convert it to a + * boolean which is set whenever the value is != 0. + */ #undef FT_SET_ERROR #define FT_SET_ERROR( expression ) \ ( ( error = (expression) ) != 0 ) @@ -58,9 +58,9 @@ FT_BEGIN_HEADER /* - * C++ refuses to handle statements like p = (void*)anything, with `p' a - * typed pointer. Since we don't have a `typeof' operator in standard - * C++, we have to use a template to emulate it. + * C++ refuses to handle statements like p = (void*)anything, with `p' a + * typed pointer. Since we don't have a `typeof' operator in standard C++, + * we have to use a template to emulate it. */ #ifdef __cplusplus @@ -107,8 +107,8 @@ extern "C++" /* - * The allocation functions return a pointer, and the error code - * is written to through the `p_error' parameter. + * The allocation functions return a pointer, and the error code is written + * to through the `p_error' parameter. */ /* The `q' variants of the functions below (`q' for `quick') don't fill */ @@ -253,20 +253,19 @@ extern "C++" /* - * Return the maximum number of addressable elements in an array. - * We limit ourselves to INT_MAX, rather than UINT_MAX, to avoid - * any problems. + * Return the maximum number of addressable elements in an array. We limit + * ourselves to INT_MAX, rather than UINT_MAX, to avoid any problems. */ #define FT_ARRAY_MAX( ptr ) ( FT_INT_MAX / sizeof ( *(ptr) ) ) #define FT_ARRAY_CHECK( ptr, count ) ( (count) <= FT_ARRAY_MAX( ptr ) ) - /*************************************************************************/ - /* */ - /* The following functions macros expect that their pointer argument is */ - /* _typed_ in order to automatically compute array element sizes. */ - /* */ + /************************************************************************** + * + * The following functions macros expect that their pointer argument is + * _typed_ in order to automatically compute array element sizes. + */ #define FT_MEM_NEW_ARRAY( ptr, count ) \ FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, \ diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/ftobjs.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/ftobjs.h index 37c6baffe6feb..f3a41b35aba5b 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/ftobjs.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/ftobjs.h @@ -1,26 +1,26 @@ -/***************************************************************************/ -/* */ -/* ftobjs.h */ -/* */ -/* The FreeType private base classes (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file contains the definition of all internal FreeType classes. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * ftobjs.h + * + * The FreeType private base classes (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /************************************************************************** + * + * This file contains the definition of all internal FreeType classes. + * + */ #ifndef FTOBJS_H_ @@ -35,7 +35,6 @@ #include FT_INTERNAL_DRIVER_H #include FT_INTERNAL_AUTOHINT_H #include FT_INTERNAL_SERVICE_H -#include FT_INTERNAL_PIC_H #include FT_INTERNAL_CALC_H #ifdef FT_CONFIG_OPTION_INCREMENTAL @@ -46,10 +45,10 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* Some generic definitions. */ - /* */ + /************************************************************************** + * + * Some generic definitions. + */ #ifndef TRUE #define TRUE 1 #endif @@ -63,20 +62,20 @@ FT_BEGIN_HEADER #endif - /*************************************************************************/ - /* */ - /* The min and max functions missing in C. As usual, be careful not to */ - /* write things like FT_MIN( a++, b++ ) to avoid side effects. */ - /* */ + /************************************************************************** + * + * The min and max functions missing in C. As usual, be careful not to + * write things like FT_MIN( a++, b++ ) to avoid side effects. + */ #define FT_MIN( a, b ) ( (a) < (b) ? (a) : (b) ) #define FT_MAX( a, b ) ( (a) > (b) ? (a) : (b) ) #define FT_ABS( a ) ( (a) < 0 ? -(a) : (a) ) /* - * Approximate sqrt(x*x+y*y) using the `alpha max plus beta min' - * algorithm. We use alpha = 1, beta = 3/8, giving us results with a - * largest error less than 7% compared to the exact value. + * Approximate sqrt(x*x+y*y) using the `alpha max plus beta min' algorithm. + * We use alpha = 1, beta = 3/8, giving us results with a largest error + * less than 7% compared to the exact value. */ #define FT_HYPOT( x, y ) \ ( x = FT_ABS( x ), \ @@ -111,9 +110,8 @@ FT_BEGIN_HEADER /* - * character classification functions -- since these are used to parse - * font files, we must not use those in <ctypes.h> which are - * locale-dependent + * character classification functions -- since these are used to parse font + * files, we must not use those in <ctypes.h> which are locale-dependent */ #define ft_isdigit( x ) ( ( (unsigned)(x) - '0' ) < 10U ) @@ -155,7 +153,7 @@ FT_BEGIN_HEADER } FT_CMapRec; - /* typecase any pointer to a charmap handle */ + /* typecast any pointer to a charmap handle */ #define FT_CMAP( x ) ( (FT_CMap)( x ) ) /* obvious macros */ @@ -187,7 +185,7 @@ FT_BEGIN_HEADER FT_UInt32 char_code, FT_UInt32 variant_selector ); - typedef FT_Bool + typedef FT_Int (*FT_CMap_CharVarIsDefaultFunc)( FT_CMap cmap, FT_UInt32 char_code, FT_UInt32 variant_selector ); @@ -228,8 +226,6 @@ FT_BEGIN_HEADER } FT_CMap_ClassRec; -#ifndef FT_CONFIG_OPTION_PIC - #define FT_DECLARE_CMAP_CLASS( class_ ) \ FT_CALLBACK_TABLE const FT_CMap_ClassRec class_; @@ -260,45 +256,6 @@ FT_BEGIN_HEADER variantchar_list_ \ }; -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DECLARE_CMAP_CLASS( class_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Library library, \ - FT_CMap_ClassRec* clazz ); - -#define FT_DEFINE_CMAP_CLASS( \ - class_, \ - size_, \ - init_, \ - done_, \ - char_index_, \ - char_next_, \ - char_var_index_, \ - char_var_default_, \ - variant_list_, \ - charvariant_list_, \ - variantchar_list_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Library library, \ - FT_CMap_ClassRec* clazz ) \ - { \ - FT_UNUSED( library ); \ - \ - clazz->size = size_; \ - clazz->init = init_; \ - clazz->done = done_; \ - clazz->char_index = char_index_; \ - clazz->char_next = char_next_; \ - clazz->char_var_index = char_var_index_; \ - clazz->char_var_default = char_var_default_; \ - clazz->variant_list = variant_list_; \ - clazz->charvariant_list = charvariant_list_; \ - clazz->variantchar_list = variantchar_list_; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - /* create a new charmap and add it to charmap->face */ FT_BASE( FT_Error ) @@ -312,11 +269,11 @@ FT_BEGIN_HEADER FT_CMap_Done( FT_CMap cmap ); - /* adds LCD padding to Min and Max boundaries */ + /* add LCD padding to CBox */ FT_BASE( void ) - ft_lcd_padding( FT_Pos* Min, - FT_Pos* Max, - FT_GlyphSlot slot ); + ft_lcd_padding( FT_BBox* cbox, + FT_GlyphSlot slot, + FT_Render_Mode mode ); #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING @@ -333,74 +290,72 @@ FT_BEGIN_HEADER #endif /* FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Face_InternalRec */ - /* */ - /* <Description> */ - /* This structure contains the internal fields of each FT_Face */ - /* object. These fields may change between different releases of */ - /* FreeType. */ - /* */ - /* <Fields> */ - /* max_points :: */ - /* The maximum number of points used to store the vectorial outline */ - /* of any glyph in this face. If this value cannot be known in */ - /* advance, or if the face isn't scalable, this should be set to 0. */ - /* Only relevant for scalable formats. */ - /* */ - /* max_contours :: */ - /* The maximum number of contours used to store the vectorial */ - /* outline of any glyph in this face. If this value cannot be */ - /* known in advance, or if the face isn't scalable, this should be */ - /* set to 0. Only relevant for scalable formats. */ - /* */ - /* transform_matrix :: */ - /* A 2x2 matrix of 16.16 coefficients used to transform glyph */ - /* outlines after they are loaded from the font. Only used by the */ - /* convenience functions. */ - /* */ - /* transform_delta :: */ - /* A translation vector used to transform glyph outlines after they */ - /* are loaded from the font. Only used by the convenience */ - /* functions. */ - /* */ - /* transform_flags :: */ - /* Some flags used to classify the transform. Only used by the */ - /* convenience functions. */ - /* */ - /* services :: */ - /* A cache for frequently used services. It should be only */ - /* accessed with the macro `FT_FACE_LOOKUP_SERVICE'. */ - /* */ - /* incremental_interface :: */ - /* If non-null, the interface through which glyph data and metrics */ - /* are loaded incrementally for faces that do not provide all of */ - /* this data when first opened. This field exists only if */ - /* @FT_CONFIG_OPTION_INCREMENTAL is defined. */ - /* */ - /* no_stem_darkening :: */ - /* Overrides the module-level default, see @stem-darkening[cff], */ - /* for example. FALSE and TRUE toggle stem darkening on and off, */ - /* respectively, value~-1 means to use the module/driver default. */ - /* */ - /* random_seed :: */ - /* If positive, override the seed value for the CFF `random' */ - /* operator. Value~0 means to use the font's value. Value~-1 */ - /* means to use the CFF driver's default. */ - /* */ - /* lcd_weights :: */ - /* lcd_filter_func :: */ - /* If subpixel rendering is activated, the LCD filtering weights */ - /* and callback function. */ - /* */ - /* refcount :: */ - /* A counter initialized to~1 at the time an @FT_Face structure is */ - /* created. @FT_Reference_Face increments this counter, and */ - /* @FT_Done_Face only destroys a face if the counter is~1, */ - /* otherwise it simply decrements it. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_Face_InternalRec + * + * @description: + * This structure contains the internal fields of each FT_Face object. + * These fields may change between different releases of FreeType. + * + * @fields: + * max_points :: + * The maximum number of points used to store the vectorial outline of + * any glyph in this face. If this value cannot be known in advance, + * or if the face isn't scalable, this should be set to 0. Only + * relevant for scalable formats. + * + * max_contours :: + * The maximum number of contours used to store the vectorial outline + * of any glyph in this face. If this value cannot be known in + * advance, or if the face isn't scalable, this should be set to 0. + * Only relevant for scalable formats. + * + * transform_matrix :: + * A 2x2 matrix of 16.16 coefficients used to transform glyph outlines + * after they are loaded from the font. Only used by the convenience + * functions. + * + * transform_delta :: + * A translation vector used to transform glyph outlines after they are + * loaded from the font. Only used by the convenience functions. + * + * transform_flags :: + * Some flags used to classify the transform. Only used by the + * convenience functions. + * + * services :: + * A cache for frequently used services. It should be only accessed + * with the macro `FT_FACE_LOOKUP_SERVICE`. + * + * incremental_interface :: + * If non-null, the interface through which glyph data and metrics are + * loaded incrementally for faces that do not provide all of this data + * when first opened. This field exists only if + * @FT_CONFIG_OPTION_INCREMENTAL is defined. + * + * no_stem_darkening :: + * Overrides the module-level default, see @stem-darkening[cff], for + * example. FALSE and TRUE toggle stem darkening on and off, + * respectively, value~-1 means to use the module/driver default. + * + * random_seed :: + * If positive, override the seed value for the CFF 'random' operator. + * Value~0 means to use the font's value. Value~-1 means to use the + * CFF driver's default. + * + * lcd_weights :: + * lcd_filter_func :: + * These fields specify the LCD filtering weights and callback function + * for ClearType-style subpixel rendering. + * + * refcount :: + * A counter initialized to~1 at the time an @FT_Face structure is + * created. @FT_Reference_Face increments this counter, and + * @FT_Done_Face only destroys a face if the counter is~1, otherwise it + * simply decrements it. + */ typedef struct FT_Face_InternalRec_ { FT_Matrix transform_matrix; @@ -426,39 +381,44 @@ FT_BEGIN_HEADER } FT_Face_InternalRec; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Slot_InternalRec */ - /* */ - /* <Description> */ - /* This structure contains the internal fields of each FT_GlyphSlot */ - /* object. These fields may change between different releases of */ - /* FreeType. */ - /* */ - /* <Fields> */ - /* loader :: The glyph loader object used to load outlines */ - /* into the glyph slot. */ - /* */ - /* flags :: Possible values are zero or */ - /* FT_GLYPH_OWN_BITMAP. The latter indicates */ - /* that the FT_GlyphSlot structure owns the */ - /* bitmap buffer. */ - /* */ - /* glyph_transformed :: Boolean. Set to TRUE when the loaded glyph */ - /* must be transformed through a specific */ - /* font transformation. This is _not_ the same */ - /* as the face transform set through */ - /* FT_Set_Transform(). */ - /* */ - /* glyph_matrix :: The 2x2 matrix corresponding to the glyph */ - /* transformation, if necessary. */ - /* */ - /* glyph_delta :: The 2d translation vector corresponding to */ - /* the glyph transformation, if necessary. */ - /* */ - /* glyph_hints :: Format-specific glyph hints management. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_Slot_InternalRec + * + * @description: + * This structure contains the internal fields of each FT_GlyphSlot + * object. These fields may change between different releases of + * FreeType. + * + * @fields: + * loader :: + * The glyph loader object used to load outlines into the glyph slot. + * + * flags :: + * Possible values are zero or FT_GLYPH_OWN_BITMAP. The latter + * indicates that the FT_GlyphSlot structure owns the bitmap buffer. + * + * glyph_transformed :: + * Boolean. Set to TRUE when the loaded glyph must be transformed + * through a specific font transformation. This is _not_ the same as + * the face transform set through FT_Set_Transform(). + * + * glyph_matrix :: + * The 2x2 matrix corresponding to the glyph transformation, if + * necessary. + * + * glyph_delta :: + * The 2d translation vector corresponding to the glyph transformation, + * if necessary. + * + * glyph_hints :: + * Format-specific glyph hints management. + * + * load_flags :: + * The load flags passed as an argument to @FT_Load_Glyph while + * initializing the glyph slot. + */ #define FT_GLYPH_OWN_BITMAP 0x1U @@ -471,26 +431,30 @@ FT_BEGIN_HEADER FT_Vector glyph_delta; void* glyph_hints; + FT_Int32 load_flags; + } FT_GlyphSlot_InternalRec; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_Size_InternalRec */ - /* */ - /* <Description> */ - /* This structure contains the internal fields of each FT_Size */ - /* object. */ - /* */ - /* <Fields> */ - /* module_data :: Data specific to a driver module. */ - /* */ - /* autohint_mode :: The used auto-hinting mode. */ - /* */ - /* autohint_metrics :: Metrics used by the auto-hinter. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * @struct: + * FT_Size_InternalRec + * + * @description: + * This structure contains the internal fields of each FT_Size object. + * + * @fields: + * module_data :: + * Data specific to a driver module. + * + * autohint_mode :: + * The used auto-hinting mode. + * + * autohint_metrics :: + * Metrics used by the auto-hinter. + * + */ typedef struct FT_Size_InternalRec_ { @@ -515,21 +479,24 @@ FT_BEGIN_HEADER /*************************************************************************/ - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_ModuleRec */ - /* */ - /* <Description> */ - /* A module object instance. */ - /* */ - /* <Fields> */ - /* clazz :: A pointer to the module's class. */ - /* */ - /* library :: A handle to the parent library object. */ - /* */ - /* memory :: A handle to the memory manager. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_ModuleRec + * + * @description: + * A module object instance. + * + * @fields: + * clazz :: + * A pointer to the module's class. + * + * library :: + * A handle to the parent library object. + * + * memory :: + * A handle to the memory manager. + */ typedef struct FT_ModuleRec_ { FT_Module_Class* clazz; @@ -572,27 +539,29 @@ FT_BEGIN_HEADER FT_MODULE_DRIVER_HINTS_LIGHTLY ) - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_Module_Interface */ - /* */ - /* <Description> */ - /* Finds a module and returns its specific interface as a typeless */ - /* pointer. */ - /* */ - /* <Input> */ - /* library :: A handle to the library object. */ - /* */ - /* module_name :: The module's name (as an ASCII string). */ - /* */ - /* <Return> */ - /* A module-specific interface if available, 0 otherwise. */ - /* */ - /* <Note> */ - /* You should better be familiar with FreeType internals to know */ - /* which module to look for, and what its interface is :-) */ - /* */ + /************************************************************************** + * + * @function: + * FT_Get_Module_Interface + * + * @description: + * Finds a module and returns its specific interface as a typeless + * pointer. + * + * @input: + * library :: + * A handle to the library object. + * + * module_name :: + * The module's name (as an ASCII string). + * + * @return: + * A module-specific interface if available, 0 otherwise. + * + * @note: + * You should better be familiar with FreeType internals to know which + * module to look for, and what its interface is :-) + */ FT_BASE( const void* ) FT_Get_Module_Interface( FT_Library library, const char* mod_name ); @@ -643,44 +612,46 @@ FT_BEGIN_HEADER #define FT_FACE_SIZE( x ) FT_FACE( x )->size - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_New_GlyphSlot */ - /* */ - /* <Description> */ - /* It is sometimes useful to have more than one glyph slot for a */ - /* given face object. This function is used to create additional */ - /* slots. All of them are automatically discarded when the face is */ - /* destroyed. */ - /* */ - /* <Input> */ - /* face :: A handle to a parent face object. */ - /* */ - /* <Output> */ - /* aslot :: A handle to a new glyph slot object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @function: + * FT_New_GlyphSlot + * + * @description: + * It is sometimes useful to have more than one glyph slot for a given + * face object. This function is used to create additional slots. All + * of them are automatically discarded when the face is destroyed. + * + * @input: + * face :: + * A handle to a parent face object. + * + * @output: + * aslot :: + * A handle to a new glyph slot object. + * + * @return: + * FreeType error code. 0 means success. + */ FT_BASE( FT_Error ) FT_New_GlyphSlot( FT_Face face, FT_GlyphSlot *aslot ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Done_GlyphSlot */ - /* */ - /* <Description> */ - /* Destroys a given glyph slot. Remember however that all slots are */ - /* automatically destroyed with its parent. Using this function is */ - /* not always mandatory. */ - /* */ - /* <Input> */ - /* slot :: A handle to a target glyph slot. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Done_GlyphSlot + * + * @description: + * Destroys a given glyph slot. Remember however that all slots are + * automatically destroyed with its parent. Using this function is not + * always mandatory. + * + * @input: + * slot :: + * A handle to a target glyph slot. + */ FT_BASE( void ) FT_Done_GlyphSlot( FT_GlyphSlot slot ); @@ -730,8 +701,9 @@ FT_BEGIN_HEADER ft_glyphslot_free_bitmap( FT_GlyphSlot slot ); - /* Preset bitmap metrics of an outline glyphslot prior to rendering. */ - FT_BASE( void ) + /* Preset bitmap metrics of an outline glyphslot prior to rendering */ + /* and check whether the truncated bbox is too large for rendering. */ + FT_BASE( FT_Bool ) ft_glyphslot_preset_bitmap( FT_GlyphSlot slot, FT_Render_Mode mode, const FT_Vector* origin ); @@ -802,28 +774,30 @@ FT_BEGIN_HEADER #define FT_DRIVER_CLASS( x ) FT_DRIVER( x )->clazz - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_DriverRec */ - /* */ - /* <Description> */ - /* The root font driver class. A font driver is responsible for */ - /* managing and loading font files of a given format. */ - /* */ - /* <Fields> */ - /* root :: Contains the fields of the root module class. */ - /* */ - /* clazz :: A pointer to the font driver's class. Note that */ - /* this is NOT root.clazz. `class' wasn't used */ - /* as it is a reserved word in C++. */ - /* */ - /* faces_list :: The list of faces currently opened by this */ - /* driver. */ - /* */ - /* glyph_loader :: Unused. Used to be glyph loader for all faces */ - /* managed by this driver. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_DriverRec + * + * @description: + * The root font driver class. A font driver is responsible for managing + * and loading font files of a given format. + * + * @fields: + * root :: + * Contains the fields of the root module class. + * + * clazz :: + * A pointer to the font driver's class. Note that this is NOT + * root.clazz. 'class' wasn't used as it is a reserved word in C++. + * + * faces_list :: + * The list of faces currently opened by this driver. + * + * glyph_loader :: + * Unused. Used to be glyph loader for all faces managed by this + * driver. + */ typedef struct FT_DriverRec_ { FT_ModuleRec root; @@ -847,72 +821,77 @@ FT_BEGIN_HEADER /*************************************************************************/ - /* This hook is used by the TrueType debugger. It must be set to an */ - /* alternate truetype bytecode interpreter function. */ -#define FT_DEBUG_HOOK_TRUETYPE 0 - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_LibraryRec */ - /* */ - /* <Description> */ - /* The FreeType library class. This is the root of all FreeType */ - /* data. Use FT_New_Library() to create a library object, and */ - /* FT_Done_Library() to discard it and all child objects. */ - /* */ - /* <Fields> */ - /* memory :: The library's memory object. Manages memory */ - /* allocation. */ - /* */ - /* version_major :: The major version number of the library. */ - /* */ - /* version_minor :: The minor version number of the library. */ - /* */ - /* version_patch :: The current patch level of the library. */ - /* */ - /* num_modules :: The number of modules currently registered */ - /* within this library. This is set to 0 for new */ - /* libraries. New modules are added through the */ - /* FT_Add_Module() API function. */ - /* */ - /* modules :: A table used to store handles to the currently */ - /* registered modules. Note that each font driver */ - /* contains a list of its opened faces. */ - /* */ - /* renderers :: The list of renderers currently registered */ - /* within the library. */ - /* */ - /* cur_renderer :: The current outline renderer. This is a */ - /* shortcut used to avoid parsing the list on */ - /* each call to FT_Outline_Render(). It is a */ - /* handle to the current renderer for the */ - /* FT_GLYPH_FORMAT_OUTLINE format. */ - /* */ - /* auto_hinter :: The auto-hinter module interface. */ - /* */ - /* debug_hooks :: An array of four function pointers that allow */ - /* debuggers to hook into a font format's */ - /* interpreter. Currently, only the TrueType */ - /* bytecode debugger uses this. */ - /* */ - /* lcd_weights :: If subpixel rendering is activated, the LCD */ - /* filter weights, if any. */ - /* */ - /* lcd_filter_func :: If subpixel rendering is activated, the LCD */ - /* filtering callback function. */ - /* */ - /* pic_container :: Contains global structs and tables, instead */ - /* of defining them globally. */ - /* */ - /* refcount :: A counter initialized to~1 at the time an */ - /* @FT_Library structure is created. */ - /* @FT_Reference_Library increments this counter, */ - /* and @FT_Done_Library only destroys a library */ - /* if the counter is~1, otherwise it simply */ - /* decrements it. */ - /* */ + /************************************************************************** + * + * @struct: + * FT_LibraryRec + * + * @description: + * The FreeType library class. This is the root of all FreeType data. + * Use FT_New_Library() to create a library object, and FT_Done_Library() + * to discard it and all child objects. + * + * @fields: + * memory :: + * The library's memory object. Manages memory allocation. + * + * version_major :: + * The major version number of the library. + * + * version_minor :: + * The minor version number of the library. + * + * version_patch :: + * The current patch level of the library. + * + * num_modules :: + * The number of modules currently registered within this library. + * This is set to 0 for new libraries. New modules are added through + * the FT_Add_Module() API function. + * + * modules :: + * A table used to store handles to the currently registered + * modules. Note that each font driver contains a list of its opened + * faces. + * + * renderers :: + * The list of renderers currently registered within the library. + * + * cur_renderer :: + * The current outline renderer. This is a shortcut used to avoid + * parsing the list on each call to FT_Outline_Render(). It is a + * handle to the current renderer for the FT_GLYPH_FORMAT_OUTLINE + * format. + * + * auto_hinter :: + * The auto-hinter module interface. + * + * debug_hooks :: + * An array of four function pointers that allow debuggers to hook into + * a font format's interpreter. Currently, only the TrueType bytecode + * debugger uses this. + * + * lcd_weights :: + * The LCD filter weights for ClearType-style subpixel rendering. + * + * lcd_filter_func :: + * The LCD filtering callback function for for ClearType-style subpixel + * rendering. + * + * lcd_geometry :: + * This array specifies LCD subpixel geometry and controls Harmony LCD + * rendering technique, alternative to ClearType. + * + * pic_container :: + * Contains global structs and tables, instead of defining them + * globally. + * + * refcount :: + * A counter initialized to~1 at the time an @FT_Library structure is + * created. @FT_Reference_Library increments this counter, and + * @FT_Done_Library only destroys a library if the counter is~1, + * otherwise it simply decrements it. + */ typedef struct FT_LibraryRec_ { FT_Memory memory; /* library's memory manager */ @@ -933,10 +912,8 @@ FT_BEGIN_HEADER #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING FT_LcdFiveTapFilter lcd_weights; /* filter weights, if any */ FT_Bitmap_LcdFilterFunc lcd_filter_func; /* filtering callback */ -#endif - -#ifdef FT_CONFIG_OPTION_PIC - FT_PIC_Container pic_container; +#else + FT_Vector lcd_geometry[3]; /* RGB subpixel positions */ #endif FT_Int refcount; @@ -970,32 +947,33 @@ FT_BEGIN_HEADER #ifndef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_New_Memory */ - /* */ - /* <Description> */ - /* Creates a new memory object. */ - /* */ - /* <Return> */ - /* A pointer to the new memory object. 0 in case of error. */ - /* */ + /************************************************************************** + * + * @function: + * FT_New_Memory + * + * @description: + * Creates a new memory object. + * + * @return: + * A pointer to the new memory object. 0 in case of error. + */ FT_BASE( FT_Memory ) FT_New_Memory( void ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Done_Memory */ - /* */ - /* <Description> */ - /* Discards memory manager. */ - /* */ - /* <Input> */ - /* memory :: A handle to the memory manager. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Done_Memory + * + * @description: + * Discards memory manager. + * + * @input: + * memory :: + * A handle to the memory manager. + */ FT_BASE( void ) FT_Done_Memory( FT_Memory memory ); @@ -1013,37 +991,16 @@ FT_BEGIN_HEADER #endif - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** P I C S U P P O R T ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /* PIC support macros for ftimage.h */ - - - /*************************************************************************/ - /* */ - /* <Macro> */ - /* FT_DEFINE_OUTLINE_FUNCS */ - /* */ - /* <Description> */ - /* Used to initialize an instance of FT_Outline_Funcs struct. */ - /* When FT_CONFIG_OPTION_PIC is defined an init function will need */ - /* to be called with a pre-allocated structure to be filled. */ - /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ - /* allocated in the global scope (or the scope where the macro */ - /* is used). */ - /* */ -#ifndef FT_CONFIG_OPTION_PIC - + /************************************************************************** + * + * @macro: + * FT_DEFINE_OUTLINE_FUNCS + * + * @description: + * Used to initialize an instance of FT_Outline_Funcs struct. The struct + * will be allocated in the global scope (or the scope where the macro is + * used). + */ #define FT_DEFINE_OUTLINE_FUNCS( \ class_, \ move_to_, \ @@ -1062,47 +1019,17 @@ FT_BEGIN_HEADER delta_ \ }; -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DEFINE_OUTLINE_FUNCS( \ - class_, \ - move_to_, \ - line_to_, \ - conic_to_, \ - cubic_to_, \ - shift_, \ - delta_ ) \ - static FT_Error \ - Init_Class_ ## class_( FT_Outline_Funcs* clazz ) \ - { \ - clazz->move_to = move_to_; \ - clazz->line_to = line_to_; \ - clazz->conic_to = conic_to_; \ - clazz->cubic_to = cubic_to_; \ - clazz->shift = shift_; \ - clazz->delta = delta_; \ - \ - return FT_Err_Ok; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - - /*************************************************************************/ - /* */ - /* <Macro> */ - /* FT_DEFINE_RASTER_FUNCS */ - /* */ - /* <Description> */ - /* Used to initialize an instance of FT_Raster_Funcs struct. */ - /* When FT_CONFIG_OPTION_PIC is defined an init function will need */ - /* to be called with a pre-allocated structure to be filled. */ - /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ - /* allocated in the global scope (or the scope where the macro */ - /* is used). */ - /* */ -#ifndef FT_CONFIG_OPTION_PIC + /************************************************************************** + * + * @macro: + * FT_DEFINE_RASTER_FUNCS + * + * @description: + * Used to initialize an instance of FT_Raster_Funcs struct. The struct + * will be allocated in the global scope (or the scope where the macro is + * used). + */ #define FT_DEFINE_RASTER_FUNCS( \ class_, \ glyph_format_, \ @@ -1121,48 +1048,17 @@ FT_BEGIN_HEADER raster_done_ \ }; -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DEFINE_RASTER_FUNCS( \ - class_, \ - glyph_format_, \ - raster_new_, \ - raster_reset_, \ - raster_set_mode_, \ - raster_render_, \ - raster_done_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Raster_Funcs* clazz ) \ - { \ - clazz->glyph_format = glyph_format_; \ - clazz->raster_new = raster_new_; \ - clazz->raster_reset = raster_reset_; \ - clazz->raster_set_mode = raster_set_mode_; \ - clazz->raster_render = raster_render_; \ - clazz->raster_done = raster_done_; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - /* PIC support macros for ftrender.h */ - - - /*************************************************************************/ - /* */ - /* <Macro> */ - /* FT_DEFINE_GLYPH */ - /* */ - /* <Description> */ - /* Used to initialize an instance of FT_Glyph_Class struct. */ - /* When FT_CONFIG_OPTION_PIC is defined an init function will need */ - /* to be called with a pre-allocated structure to be filled. */ - /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ - /* allocated in the global scope (or the scope where the macro */ - /* is used). */ - /* */ -#ifndef FT_CONFIG_OPTION_PIC - + /************************************************************************** + * + * @macro: + * FT_DEFINE_GLYPH + * + * @description: + * The struct will be allocated in the global scope (or the scope where + * the macro is used). + */ #define FT_DEFINE_GLYPH( \ class_, \ size_, \ @@ -1186,73 +1082,25 @@ FT_BEGIN_HEADER prepare_ \ }; -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DEFINE_GLYPH( \ - class_, \ - size_, \ - format_, \ - init_, \ - done_, \ - copy_, \ - transform_, \ - bbox_, \ - prepare_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Glyph_Class* clazz ) \ - { \ - clazz->glyph_size = size_; \ - clazz->glyph_format = format_; \ - clazz->glyph_init = init_; \ - clazz->glyph_done = done_; \ - clazz->glyph_copy = copy_; \ - clazz->glyph_transform = transform_; \ - clazz->glyph_bbox = bbox_; \ - clazz->glyph_prepare = prepare_; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - - /*************************************************************************/ - /* */ - /* <Macro> */ - /* FT_DECLARE_RENDERER */ - /* */ - /* <Description> */ - /* Used to create a forward declaration of a */ - /* FT_Renderer_Class struct instance. */ - /* */ - /* <Macro> */ - /* FT_DEFINE_RENDERER */ - /* */ - /* <Description> */ - /* Used to initialize an instance of FT_Renderer_Class struct. */ - /* */ - /* When FT_CONFIG_OPTION_PIC is defined a `create' function will */ - /* need to be called with a pointer where the allocated structure is */ - /* returned. And when it is no longer needed a `destroy' function */ - /* needs to be called to release that allocation. */ - /* `ftinit.c' (ft_create_default_module_classes) already contains */ - /* a mechanism to call these functions for the default modules */ - /* described in `ftmodule.h'. */ - /* */ - /* Notice that the created `create' and `destroy' functions call */ - /* `pic_init' and `pic_free' to allow you to manually allocate and */ - /* initialize any additional global data, like a module specific */ - /* interface, and put them in the global pic container defined in */ - /* `ftpic.h'. If you don't need them just implement the functions as */ - /* empty to resolve the link error. Also the `pic_init' and */ - /* `pic_free' functions should be declared in `pic.h', to be referred */ - /* by the renderer definition calling `FT_DEFINE_RENDERER' in the */ - /* following. */ - /* */ - /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ - /* allocated in the global scope (or the scope where the macro */ - /* is used). */ - /* */ -#ifndef FT_CONFIG_OPTION_PIC + /************************************************************************** + * + * @macro: + * FT_DECLARE_RENDERER + * + * @description: + * Used to create a forward declaration of a FT_Renderer_Class struct + * instance. + * + * @macro: + * FT_DEFINE_RENDERER + * + * @description: + * Used to initialize an instance of FT_Renderer_Class struct. + * + * The struct will be allocated in the global scope (or the scope where + * the macro is used). + */ #define FT_DECLARE_RENDERER( class_ ) \ FT_EXPORT_VAR( const FT_Renderer_Class ) class_; @@ -1295,176 +1143,33 @@ FT_BEGIN_HEADER raster_class_ \ }; -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DECLARE_RENDERER( class_ ) FT_DECLARE_MODULE( class_ ) - -#define FT_DEFINE_RENDERER( \ - class_, \ - flags_, \ - size_, \ - name_, \ - version_, \ - requires_, \ - interface_, \ - init_, \ - done_, \ - get_interface_, \ - glyph_format_, \ - render_glyph_, \ - transform_glyph_, \ - get_glyph_cbox_, \ - set_mode_, \ - raster_class_ ) \ - void \ - FT_Destroy_Class_ ## class_( FT_Library library, \ - FT_Module_Class* clazz ) \ - { \ - FT_Renderer_Class* rclazz = (FT_Renderer_Class*)clazz; \ - FT_Memory memory = library->memory; \ - \ - \ - class_ ## _pic_free( library ); \ - if ( rclazz ) \ - FT_FREE( rclazz ); \ - } \ - \ - \ - FT_Error \ - FT_Create_Class_ ## class_( FT_Library library, \ - FT_Module_Class** output_class ) \ - { \ - FT_Renderer_Class* clazz = NULL; \ - FT_Error error; \ - FT_Memory memory = library->memory; \ - \ - \ - if ( FT_ALLOC( clazz, sizeof ( *clazz ) ) ) \ - return error; \ - \ - error = class_ ## _pic_init( library ); \ - if ( error ) \ - { \ - FT_FREE( clazz ); \ - return error; \ - } \ - \ - FT_DEFINE_ROOT_MODULE( flags_, \ - size_, \ - name_, \ - version_, \ - requires_, \ - interface_, \ - init_, \ - done_, \ - get_interface_ ) \ - \ - clazz->glyph_format = glyph_format_; \ - \ - clazz->render_glyph = render_glyph_; \ - clazz->transform_glyph = transform_glyph_; \ - clazz->get_glyph_cbox = get_glyph_cbox_; \ - clazz->set_mode = set_mode_; \ - \ - clazz->raster_class = raster_class_; \ - \ - *output_class = (FT_Module_Class*)clazz; \ - \ - return FT_Err_Ok; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - - /* PIC support macros for ftmodapi.h **/ - - -#ifdef FT_CONFIG_OPTION_PIC - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_Module_Creator */ - /* */ - /* <Description> */ - /* A function used to create (allocate) a new module class object. */ - /* The object's members are initialized, but the module itself is */ - /* not. */ - /* */ - /* <Input> */ - /* memory :: A handle to the memory manager. */ - /* output_class :: Initialized with the newly allocated class. */ - /* */ - typedef FT_Error - (*FT_Module_Creator)( FT_Memory memory, - FT_Module_Class** output_class ); - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* FT_Module_Destroyer */ - /* */ - /* <Description> */ - /* A function used to destroy (deallocate) a module class object. */ - /* */ - /* <Input> */ - /* memory :: A handle to the memory manager. */ - /* clazz :: Module class to destroy. */ - /* */ - typedef void - (*FT_Module_Destroyer)( FT_Memory memory, - FT_Module_Class* clazz ); - -#endif - - - /*************************************************************************/ - /* */ - /* <Macro> */ - /* FT_DECLARE_MODULE */ - /* */ - /* <Description> */ - /* Used to create a forward declaration of a */ - /* FT_Module_Class struct instance. */ - /* */ - /* <Macro> */ - /* FT_DEFINE_MODULE */ - /* */ - /* <Description> */ - /* Used to initialize an instance of an FT_Module_Class struct. */ - /* */ - /* When FT_CONFIG_OPTION_PIC is defined a `create' function needs */ - /* to be called with a pointer where the allocated structure is */ - /* returned. And when it is no longer needed a `destroy' function */ - /* needs to be called to release that allocation. */ - /* `ftinit.c' (ft_create_default_module_classes) already contains */ - /* a mechanism to call these functions for the default modules */ - /* described in `ftmodule.h'. */ - /* */ - /* Notice that the created `create' and `destroy' functions call */ - /* `pic_init' and `pic_free' to allow you to manually allocate and */ - /* initialize any additional global data, like a module specific */ - /* interface, and put them in the global pic container defined in */ - /* `ftpic.h'. If you don't need them just implement the functions as */ - /* empty to resolve the link error. Also the `pic_init' and */ - /* `pic_free' functions should be declared in `pic.h', to be referred */ - /* by the module definition calling `FT_DEFINE_MODULE' in the */ - /* following. */ - /* */ - /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ - /* allocated in the global scope (or the scope where the macro */ - /* is used). */ - /* */ - /* <Macro> */ - /* FT_DEFINE_ROOT_MODULE */ - /* */ - /* <Description> */ - /* Used to initialize an instance of an FT_Module_Class struct inside */ - /* another struct that contains it or in a function that initializes */ - /* that containing struct. */ - /* */ -#ifndef FT_CONFIG_OPTION_PIC + /************************************************************************** + * + * @macro: + * FT_DECLARE_MODULE + * + * @description: + * Used to create a forward declaration of a FT_Module_Class struct + * instance. + * + * @macro: + * FT_DEFINE_MODULE + * + * @description: + * Used to initialize an instance of an FT_Module_Class struct. + * + * The struct will be allocated in the global scope (or the scope where + * the macro is used). + * + * @macro: + * FT_DEFINE_ROOT_MODULE + * + * @description: + * Used to initialize an instance of an FT_Module_Class struct inside + * another struct that contains it or in a function that initializes that + * containing struct. + */ #define FT_DECLARE_MODULE( class_ ) \ FT_CALLBACK_TABLE \ const FT_Module_Class class_; @@ -1523,100 +1228,6 @@ FT_BEGIN_HEADER }; -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DECLARE_MODULE( class_ ) \ - FT_Error \ - FT_Create_Class_ ## class_( FT_Library library, \ - FT_Module_Class** output_class ); \ - void \ - FT_Destroy_Class_ ## class_( FT_Library library, \ - FT_Module_Class* clazz ); - -#define FT_DEFINE_ROOT_MODULE( \ - flags_, \ - size_, \ - name_, \ - version_, \ - requires_, \ - interface_, \ - init_, \ - done_, \ - get_interface_ ) \ - clazz->root.module_flags = flags_; \ - clazz->root.module_size = size_; \ - clazz->root.module_name = name_; \ - clazz->root.module_version = version_; \ - clazz->root.module_requires = requires_; \ - \ - clazz->root.module_interface = interface_; \ - \ - clazz->root.module_init = init_; \ - clazz->root.module_done = done_; \ - clazz->root.get_interface = get_interface_; - -#define FT_DEFINE_MODULE( \ - class_, \ - flags_, \ - size_, \ - name_, \ - version_, \ - requires_, \ - interface_, \ - init_, \ - done_, \ - get_interface_ ) \ - void \ - FT_Destroy_Class_ ## class_( FT_Library library, \ - FT_Module_Class* clazz ) \ - { \ - FT_Memory memory = library->memory; \ - \ - \ - class_ ## _pic_free( library ); \ - if ( clazz ) \ - FT_FREE( clazz ); \ - } \ - \ - \ - FT_Error \ - FT_Create_Class_ ## class_( FT_Library library, \ - FT_Module_Class** output_class ) \ - { \ - FT_Memory memory = library->memory; \ - FT_Module_Class* clazz = NULL; \ - FT_Error error; \ - \ - \ - if ( FT_ALLOC( clazz, sizeof ( *clazz ) ) ) \ - return error; \ - error = class_ ## _pic_init( library ); \ - if ( error ) \ - { \ - FT_FREE( clazz ); \ - return error; \ - } \ - \ - clazz->module_flags = flags_; \ - clazz->module_size = size_; \ - clazz->module_name = name_; \ - clazz->module_version = version_; \ - clazz->module_requires = requires_; \ - \ - clazz->module_interface = interface_; \ - \ - clazz->module_init = init_; \ - clazz->module_done = done_; \ - clazz->get_interface = get_interface_; \ - \ - *output_class = clazz; \ - \ - return FT_Err_Ok; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - FT_END_HEADER #endif /* FTOBJS_H_ */ diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/ftpic.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/ftpic.h deleted file mode 100644 index 5214f05989133..0000000000000 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/ftpic.h +++ /dev/null @@ -1,71 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftpic.h */ -/* */ -/* The FreeType position independent code services (declaration). */ -/* */ -/* Copyright 2009-2018 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - /*************************************************************************/ - /* */ - /* Modules that ordinarily have const global data that need address */ - /* can instead define pointers here. */ - /* */ - /*************************************************************************/ - - -#ifndef FTPIC_H_ -#define FTPIC_H_ - - -FT_BEGIN_HEADER - -#ifdef FT_CONFIG_OPTION_PIC - - typedef struct FT_PIC_Container_ - { - /* pic containers for base */ - void* base; - - /* pic containers for modules */ - void* autofit; - void* cff; - void* pshinter; - void* psnames; - void* raster; - void* sfnt; - void* smooth; - void* truetype; - - } FT_PIC_Container; - - - /* Initialize the various function tables, structs, etc. */ - /* stored in the container. */ - FT_BASE( FT_Error ) - ft_pic_container_init( FT_Library library ); - - - /* Destroy the contents of the container. */ - FT_BASE( void ) - ft_pic_container_destroy( FT_Library library ); - -#endif /* FT_CONFIG_OPTION_PIC */ - - /* */ - -FT_END_HEADER - -#endif /* FTPIC_H_ */ - - -/* END */ diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/ftpsprop.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/ftpsprop.h index abbb62862b339..574837f6d4027 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/ftpsprop.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/ftpsprop.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftpsprop.h */ -/* */ -/* Get and set properties of PostScript drivers (specification). */ -/* */ -/* Copyright 2017-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftpsprop.h + * + * Get and set properties of PostScript drivers (specification). + * + * Copyright (C) 2017-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTPSPROP_H_ diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/ftrfork.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/ftrfork.h index 1aca48a0e7beb..75b3e531bb9ae 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/ftrfork.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/ftrfork.h @@ -1,24 +1,24 @@ -/***************************************************************************/ -/* */ -/* ftrfork.h */ -/* */ -/* Embedded resource forks accessor (specification). */ -/* */ -/* Copyright 2004-2018 by */ -/* Masatake YAMATO and Redhat K.K. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* Development of the code in this file is support of */ -/* Information-technology Promotion Agency, Japan. */ -/***************************************************************************/ +/**************************************************************************** + * + * ftrfork.h + * + * Embedded resource forks accessor (specification). + * + * Copyright (C) 2004-2019 by + * Masatake YAMATO and Redhat K.K. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + +/**************************************************************************** + * Development of the code in this file is support of + * Information-technology Promotion Agency, Japan. + */ #ifndef FTRFORK_H_ @@ -72,85 +72,65 @@ FT_BEGIN_HEADER } FT_RFork_Rule; /* For fast translation between rule index and rule type, - * the macros FT_RFORK_xxx should be kept consistent with - * the raccess_guess_funcs table + * the macros FT_RFORK_xxx should be kept consistent with the + * raccess_guess_funcs table */ typedef struct ft_raccess_guess_rec_ { ft_raccess_guess_func func; FT_RFork_Rule type; } ft_raccess_guess_rec; -#ifndef FT_CONFIG_OPTION_PIC - /* this array is a storage in non-PIC mode, so ; is needed in END */ #define CONST_FT_RFORK_RULE_ARRAY_BEGIN( name, type ) \ static const type name[] = { #define CONST_FT_RFORK_RULE_ARRAY_ENTRY( func_suffix, type_suffix ) \ { raccess_guess_ ## func_suffix, \ FT_RFork_Rule_ ## type_suffix }, + /* this array is a storage, thus a final `;' is needed */ #define CONST_FT_RFORK_RULE_ARRAY_END }; -#else /* FT_CONFIG_OPTION_PIC */ - - /* this array is a function in PIC mode, so no ; is needed in END */ -#define CONST_FT_RFORK_RULE_ARRAY_BEGIN( name, type ) \ - void \ - FT_Init_Table_ ## name( type* storage ) \ - { \ - type* local = storage; \ - \ - \ - int i = 0; -#define CONST_FT_RFORK_RULE_ARRAY_ENTRY( func_suffix, type_suffix ) \ - local[i].func = raccess_guess_ ## func_suffix; \ - local[i].type = FT_RFork_Rule_ ## type_suffix; \ - i++; -#define CONST_FT_RFORK_RULE_ARRAY_END } - -#endif /* FT_CONFIG_OPTION_PIC */ - #endif /* FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */ - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Raccess_Guess */ - /* */ - /* <Description> */ - /* Guess a file name and offset where the actual resource fork is */ - /* stored. The macro FT_RACCESS_N_RULES holds the number of */ - /* guessing rules; the guessed result for the Nth rule is */ - /* represented as a triplet: a new file name (new_names[N]), a file */ - /* offset (offsets[N]), and an error code (errors[N]). */ - /* */ - /* <Input> */ - /* library :: */ - /* A FreeType library instance. */ - /* */ - /* stream :: */ - /* A file stream containing the resource fork. */ - /* */ - /* base_name :: */ - /* The (base) file name of the resource fork used for some */ - /* guessing rules. */ - /* */ - /* <Output> */ - /* new_names :: */ - /* An array of guessed file names in which the resource forks may */ - /* exist. If `new_names[N]' is NULL, the guessed file name is */ - /* equal to `base_name'. */ - /* */ - /* offsets :: */ - /* An array of guessed file offsets. `offsets[N]' holds the file */ - /* offset of the possible start of the resource fork in file */ - /* `new_names[N]'. */ - /* */ - /* errors :: */ - /* An array of FreeType error codes. `errors[N]' is the error */ - /* code of Nth guessing rule function. If `errors[N]' is not */ - /* FT_Err_Ok, `new_names[N]' and `offsets[N]' are meaningless. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Raccess_Guess + * + * @description: + * Guess a file name and offset where the actual resource fork is stored. + * The macro FT_RACCESS_N_RULES holds the number of guessing rules; the + * guessed result for the Nth rule is represented as a triplet: a new + * file name (new_names[N]), a file offset (offsets[N]), and an error + * code (errors[N]). + * + * @input: + * library :: + * A FreeType library instance. + * + * stream :: + * A file stream containing the resource fork. + * + * base_name :: + * The (base) file name of the resource fork used for some guessing + * rules. + * + * @output: + * new_names :: + * An array of guessed file names in which the resource forks may + * exist. If 'new_names[N]' is `NULL`, the guessed file name is equal + * to `base_name`. + * + * offsets :: + * An array of guessed file offsets. 'offsets[N]' holds the file + * offset of the possible start of the resource fork in file + * 'new_names[N]'. + * + * errors :: + * An array of FreeType error codes. 'errors[N]' is the error code of + * Nth guessing rule function. If 'errors[N]' is not FT_Err_Ok, + * 'new_names[N]' and 'offsets[N]' are meaningless. + */ FT_BASE( void ) FT_Raccess_Guess( FT_Library library, FT_Stream stream, @@ -160,37 +140,37 @@ FT_BEGIN_HEADER FT_Error* errors ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Raccess_Get_HeaderInfo */ - /* */ - /* <Description> */ - /* Get the information from the header of resource fork. The */ - /* information includes the file offset where the resource map */ - /* starts, and the file offset where the resource data starts. */ - /* `FT_Raccess_Get_DataOffsets' requires these two data. */ - /* */ - /* <Input> */ - /* library :: */ - /* A FreeType library instance. */ - /* */ - /* stream :: */ - /* A file stream containing the resource fork. */ - /* */ - /* rfork_offset :: */ - /* The file offset where the resource fork starts. */ - /* */ - /* <Output> */ - /* map_offset :: */ - /* The file offset where the resource map starts. */ - /* */ - /* rdata_pos :: */ - /* The file offset where the resource data starts. */ - /* */ - /* <Return> */ - /* FreeType error code. FT_Err_Ok means success. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Raccess_Get_HeaderInfo + * + * @description: + * Get the information from the header of resource fork. The information + * includes the file offset where the resource map starts, and the file + * offset where the resource data starts. `FT_Raccess_Get_DataOffsets` + * requires these two data. + * + * @input: + * library :: + * A FreeType library instance. + * + * stream :: + * A file stream containing the resource fork. + * + * rfork_offset :: + * The file offset where the resource fork starts. + * + * @output: + * map_offset :: + * The file offset where the resource map starts. + * + * rdata_pos :: + * The file offset where the resource data starts. + * + * @return: + * FreeType error code. FT_Err_Ok means success. + */ FT_BASE( FT_Error ) FT_Raccess_Get_HeaderInfo( FT_Library library, FT_Stream stream, @@ -199,55 +179,54 @@ FT_BEGIN_HEADER FT_Long *rdata_pos ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Raccess_Get_DataOffsets */ - /* */ - /* <Description> */ - /* Get the data offsets for a tag in a resource fork. Offsets are */ - /* stored in an array because, in some cases, resources in a resource */ - /* fork have the same tag. */ - /* */ - /* <Input> */ - /* library :: */ - /* A FreeType library instance. */ - /* */ - /* stream :: */ - /* A file stream containing the resource fork. */ - /* */ - /* map_offset :: */ - /* The file offset where the resource map starts. */ - /* */ - /* rdata_pos :: */ - /* The file offset where the resource data starts. */ - /* */ - /* tag :: */ - /* The resource tag. */ - /* */ - /* sort_by_res_id :: */ - /* A Boolean to sort the fragmented resource by their ids. */ - /* The fragmented resources for `POST' resource should be sorted */ - /* to restore Type1 font properly. For `sfnt' resources, sorting */ - /* may induce a different order of the faces in comparison to that */ - /* by QuickDraw API. */ - /* */ - /* <Output> */ - /* offsets :: */ - /* The stream offsets for the resource data specified by `tag'. */ - /* This array is allocated by the function, so you have to call */ - /* @ft_mem_free after use. */ - /* */ - /* count :: */ - /* The length of offsets array. */ - /* */ - /* <Return> */ - /* FreeType error code. FT_Err_Ok means success. */ - /* */ - /* <Note> */ - /* Normally you should use `FT_Raccess_Get_HeaderInfo' to get the */ - /* value for `map_offset' and `rdata_pos'. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Raccess_Get_DataOffsets + * + * @description: + * Get the data offsets for a tag in a resource fork. Offsets are stored + * in an array because, in some cases, resources in a resource fork have + * the same tag. + * + * @input: + * library :: + * A FreeType library instance. + * + * stream :: + * A file stream containing the resource fork. + * + * map_offset :: + * The file offset where the resource map starts. + * + * rdata_pos :: + * The file offset where the resource data starts. + * + * tag :: + * The resource tag. + * + * sort_by_res_id :: + * A Boolean to sort the fragmented resource by their ids. The + * fragmented resources for 'POST' resource should be sorted to restore + * Type1 font properly. For 'sfnt' resources, sorting may induce a + * different order of the faces in comparison to that by QuickDraw API. + * + * @output: + * offsets :: + * The stream offsets for the resource data specified by 'tag'. This + * array is allocated by the function, so you have to call @ft_mem_free + * after use. + * + * count :: + * The length of offsets array. + * + * @return: + * FreeType error code. FT_Err_Ok means success. + * + * @note: + * Normally you should use `FT_Raccess_Get_HeaderInfo` to get the value + * for `map_offset` and `rdata_pos`. + */ FT_BASE( FT_Error ) FT_Raccess_Get_DataOffsets( FT_Library library, FT_Stream stream, diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/ftserv.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/ftserv.h index e01c1679b51ad..8836cf3f18d53 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/ftserv.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/ftserv.h @@ -1,31 +1,31 @@ -/***************************************************************************/ -/* */ -/* ftserv.h */ -/* */ -/* The FreeType services (specification only). */ -/* */ -/* Copyright 2003-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - /*************************************************************************/ - /* */ - /* Each module can export one or more `services'. Each service is */ - /* identified by a constant string and modeled by a pointer; the latter */ - /* generally corresponds to a structure containing function pointers. */ - /* */ - /* Note that a service's data cannot be a mere function pointer because */ - /* in C it is possible that function pointers might be implemented */ - /* differently than data pointers (e.g. 48 bits instead of 32). */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * ftserv.h + * + * The FreeType services (specification only). + * + * Copyright (C) 2003-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + /************************************************************************** + * + * Each module can export one or more 'services'. Each service is + * identified by a constant string and modeled by a pointer; the latter + * generally corresponds to a structure containing function pointers. + * + * Note that a service's data cannot be a mere function pointer because in + * C it is possible that function pointers might be implemented differently + * than data pointers (e.g. 48 bits instead of 32). + * + */ #ifndef FTSERV_H_ @@ -34,7 +34,8 @@ FT_BEGIN_HEADER - /* + /************************************************************************** + * * @macro: * FT_FACE_FIND_SERVICE * @@ -46,15 +47,15 @@ FT_BEGIN_HEADER * The source face handle. * * id :: - * A string describing the service as defined in the service's - * header files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to - * `multi-masters'). It is automatically prefixed with - * `FT_SERVICE_ID_'. + * A string describing the service as defined in the service's header + * files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to + * 'multi-masters'). It is automatically prefixed with + * `FT_SERVICE_ID_`. * * @output: * ptr :: - * A variable that receives the service pointer. Will be NULL - * if not found. + * A variable that receives the service pointer. Will be `NULL` if not + * found. */ #ifdef __cplusplus @@ -85,7 +86,8 @@ FT_BEGIN_HEADER #endif /* !C++ */ - /* + /************************************************************************** + * * @macro: * FT_FACE_FIND_GLOBAL_SERVICE * @@ -97,15 +99,15 @@ FT_BEGIN_HEADER * The source face handle. * * id :: - * A string describing the service as defined in the service's - * header files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to - * `multi-masters'). It is automatically prefixed with - * `FT_SERVICE_ID_'. + * A string describing the service as defined in the service's header + * files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to + * 'multi-masters'). It is automatically prefixed with + * `FT_SERVICE_ID_`. * * @output: * ptr :: - * A variable that receives the service pointer. Will be NULL - * if not found. + * A variable that receives the service pointer. Will be `NULL` if not + * found. */ #ifdef __cplusplus @@ -144,8 +146,8 @@ FT_BEGIN_HEADER /*************************************************************************/ /* - * The following structure is used to _describe_ a given service - * to the library. This is useful to build simple static service lists. + * The following structure is used to _describe_ a given service to the + * library. This is useful to build simple static service lists. */ typedef struct FT_ServiceDescRec_ { @@ -157,35 +159,26 @@ FT_BEGIN_HEADER typedef const FT_ServiceDescRec* FT_ServiceDesc; - /*************************************************************************/ - /* */ - /* <Macro> */ - /* FT_DEFINE_SERVICEDESCREC1 */ - /* FT_DEFINE_SERVICEDESCREC2 */ - /* FT_DEFINE_SERVICEDESCREC3 */ - /* FT_DEFINE_SERVICEDESCREC4 */ - /* FT_DEFINE_SERVICEDESCREC5 */ - /* FT_DEFINE_SERVICEDESCREC6 */ - /* FT_DEFINE_SERVICEDESCREC7 */ - /* FT_DEFINE_SERVICEDESCREC8 */ - /* */ - /* <Description> */ - /* Used to initialize an array of FT_ServiceDescRec structures. */ - /* */ - /* When FT_CONFIG_OPTION_PIC is defined a `create' function needs to */ - /* be called with a pointer to return an allocated array. As soon as */ - /* it is no longer needed, a `destroy' function needs to be called to */ - /* release that allocation. */ - /* */ - /* These functions should be manually called from the `pic_init' and */ - /* `pic_free' functions of your module (see FT_DEFINE_MODULE). */ - /* */ - /* When FT_CONFIG_OPTION_PIC is not defined the array will be */ - /* allocated in the global scope (or the scope where the macro is */ - /* used). */ - /* */ -#ifndef FT_CONFIG_OPTION_PIC - + /************************************************************************** + * + * @macro: + * FT_DEFINE_SERVICEDESCREC1 + * FT_DEFINE_SERVICEDESCREC2 + * FT_DEFINE_SERVICEDESCREC3 + * FT_DEFINE_SERVICEDESCREC4 + * FT_DEFINE_SERVICEDESCREC5 + * FT_DEFINE_SERVICEDESCREC6 + * FT_DEFINE_SERVICEDESCREC7 + * FT_DEFINE_SERVICEDESCREC8 + * FT_DEFINE_SERVICEDESCREC9 + * FT_DEFINE_SERVICEDESCREC10 + * + * @description: + * Used to initialize an array of FT_ServiceDescRec structures. + * + * The array will be allocated in the global scope (or the scope where + * the macro is used). + */ #define FT_DEFINE_SERVICEDESCREC1( class_, \ serv_id_1, serv_data_1 ) \ static const FT_ServiceDescRec class_[] = \ @@ -356,504 +349,15 @@ FT_BEGIN_HEADER { NULL, NULL } \ }; -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DEFINE_SERVICEDESCREC1( class_, \ - serv_id_1, serv_data_1 ) \ - void \ - FT_Destroy_Class_ ## class_( FT_Library library, \ - FT_ServiceDescRec* clazz ) \ - { \ - FT_Memory memory = library->memory; \ - \ - \ - if ( clazz ) \ - FT_FREE( clazz ); \ - } \ - \ - FT_Error \ - FT_Create_Class_ ## class_( FT_Library library, \ - FT_ServiceDescRec** output_class ) \ - { \ - FT_ServiceDescRec* clazz = NULL; \ - FT_Error error; \ - FT_Memory memory = library->memory; \ - \ - \ - if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 2 ) ) \ - return error; \ - \ - clazz[0].serv_id = serv_id_1; \ - clazz[0].serv_data = serv_data_1; \ - clazz[1].serv_id = NULL; \ - clazz[1].serv_data = NULL; \ - \ - *output_class = clazz; \ - \ - return FT_Err_Ok; \ - } - -#define FT_DEFINE_SERVICEDESCREC2( class_, \ - serv_id_1, serv_data_1, \ - serv_id_2, serv_data_2 ) \ - void \ - FT_Destroy_Class_ ## class_( FT_Library library, \ - FT_ServiceDescRec* clazz ) \ - { \ - FT_Memory memory = library->memory; \ - \ - \ - if ( clazz ) \ - FT_FREE( clazz ); \ - } \ - \ - FT_Error \ - FT_Create_Class_ ## class_( FT_Library library, \ - FT_ServiceDescRec** output_class ) \ - { \ - FT_ServiceDescRec* clazz = NULL; \ - FT_Error error; \ - FT_Memory memory = library->memory; \ - \ - \ - if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 3 ) ) \ - return error; \ - \ - clazz[0].serv_id = serv_id_1; \ - clazz[0].serv_data = serv_data_1; \ - clazz[1].serv_id = serv_id_2; \ - clazz[1].serv_data = serv_data_2; \ - clazz[2].serv_id = NULL; \ - clazz[2].serv_data = NULL; \ - \ - *output_class = clazz; \ - \ - return FT_Err_Ok; \ - } - -#define FT_DEFINE_SERVICEDESCREC3( class_, \ - serv_id_1, serv_data_1, \ - serv_id_2, serv_data_2, \ - serv_id_3, serv_data_3 ) \ - void \ - FT_Destroy_Class_ ## class_( FT_Library library, \ - FT_ServiceDescRec* clazz ) \ - { \ - FT_Memory memory = library->memory; \ - \ - \ - if ( clazz ) \ - FT_FREE( clazz ); \ - } \ - \ - FT_Error \ - FT_Create_Class_ ## class_( FT_Library library, \ - FT_ServiceDescRec** output_class ) \ - { \ - FT_ServiceDescRec* clazz = NULL; \ - FT_Error error; \ - FT_Memory memory = library->memory; \ - \ - \ - if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 4 ) ) \ - return error; \ - \ - clazz[0].serv_id = serv_id_1; \ - clazz[0].serv_data = serv_data_1; \ - clazz[1].serv_id = serv_id_2; \ - clazz[1].serv_data = serv_data_2; \ - clazz[2].serv_id = serv_id_3; \ - clazz[2].serv_data = serv_data_3; \ - clazz[3].serv_id = NULL; \ - clazz[3].serv_data = NULL; \ - \ - *output_class = clazz; \ - \ - return FT_Err_Ok; \ - } - -#define FT_DEFINE_SERVICEDESCREC4( class_, \ - serv_id_1, serv_data_1, \ - serv_id_2, serv_data_2, \ - serv_id_3, serv_data_3, \ - serv_id_4, serv_data_4 ) \ - void \ - FT_Destroy_Class_ ## class_( FT_Library library, \ - FT_ServiceDescRec* clazz ) \ - { \ - FT_Memory memory = library->memory; \ - \ - \ - if ( clazz ) \ - FT_FREE( clazz ); \ - } \ - \ - FT_Error \ - FT_Create_Class_ ## class_( FT_Library library, \ - FT_ServiceDescRec** output_class ) \ - { \ - FT_ServiceDescRec* clazz = NULL; \ - FT_Error error; \ - FT_Memory memory = library->memory; \ - \ - \ - if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 5 ) ) \ - return error; \ - \ - clazz[0].serv_id = serv_id_1; \ - clazz[0].serv_data = serv_data_1; \ - clazz[1].serv_id = serv_id_2; \ - clazz[1].serv_data = serv_data_2; \ - clazz[2].serv_id = serv_id_3; \ - clazz[2].serv_data = serv_data_3; \ - clazz[3].serv_id = serv_id_4; \ - clazz[3].serv_data = serv_data_4; \ - clazz[4].serv_id = NULL; \ - clazz[4].serv_data = NULL; \ - \ - *output_class = clazz; \ - \ - return FT_Err_Ok; \ - } - -#define FT_DEFINE_SERVICEDESCREC5( class_, \ - serv_id_1, serv_data_1, \ - serv_id_2, serv_data_2, \ - serv_id_3, serv_data_3, \ - serv_id_4, serv_data_4, \ - serv_id_5, serv_data_5 ) \ - void \ - FT_Destroy_Class_ ## class_( FT_Library library, \ - FT_ServiceDescRec* clazz ) \ - { \ - FT_Memory memory = library->memory; \ - \ - \ - if ( clazz ) \ - FT_FREE( clazz ); \ - } \ - \ - FT_Error \ - FT_Create_Class_ ## class_( FT_Library library, \ - FT_ServiceDescRec** output_class ) \ - { \ - FT_ServiceDescRec* clazz = NULL; \ - FT_Error error; \ - FT_Memory memory = library->memory; \ - \ - \ - if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 6 ) ) \ - return error; \ - \ - clazz[0].serv_id = serv_id_1; \ - clazz[0].serv_data = serv_data_1; \ - clazz[1].serv_id = serv_id_2; \ - clazz[1].serv_data = serv_data_2; \ - clazz[2].serv_id = serv_id_3; \ - clazz[2].serv_data = serv_data_3; \ - clazz[3].serv_id = serv_id_4; \ - clazz[3].serv_data = serv_data_4; \ - clazz[4].serv_id = serv_id_5; \ - clazz[4].serv_data = serv_data_5; \ - clazz[5].serv_id = NULL; \ - clazz[5].serv_data = NULL; \ - \ - *output_class = clazz; \ - \ - return FT_Err_Ok; \ - } - -#define FT_DEFINE_SERVICEDESCREC6( class_, \ - serv_id_1, serv_data_1, \ - serv_id_2, serv_data_2, \ - serv_id_3, serv_data_3, \ - serv_id_4, serv_data_4, \ - serv_id_5, serv_data_5, \ - serv_id_6, serv_data_6 ) \ - void \ - FT_Destroy_Class_ ## class_( FT_Library library, \ - FT_ServiceDescRec* clazz ) \ - { \ - FT_Memory memory = library->memory; \ - \ - \ - if ( clazz ) \ - FT_FREE( clazz ); \ - } \ - \ - FT_Error \ - FT_Create_Class_ ## class_( FT_Library library, \ - FT_ServiceDescRec** output_class ) \ - { \ - FT_ServiceDescRec* clazz = NULL; \ - FT_Error error; \ - FT_Memory memory = library->memory; \ - \ - \ - if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 7 ) ) \ - return error; \ - \ - clazz[0].serv_id = serv_id_1; \ - clazz[0].serv_data = serv_data_1; \ - clazz[1].serv_id = serv_id_2; \ - clazz[1].serv_data = serv_data_2; \ - clazz[2].serv_id = serv_id_3; \ - clazz[2].serv_data = serv_data_3; \ - clazz[3].serv_id = serv_id_4; \ - clazz[3].serv_data = serv_data_4; \ - clazz[4].serv_id = serv_id_5; \ - clazz[4].serv_data = serv_data_5; \ - clazz[5].serv_id = serv_id_6; \ - clazz[5].serv_data = serv_data_6; \ - clazz[6].serv_id = NULL; \ - clazz[6].serv_data = NULL; \ - \ - *output_class = clazz; \ - \ - return FT_Err_Ok; \ - } - -#define FT_DEFINE_SERVICEDESCREC7( class_, \ - serv_id_1, serv_data_1, \ - serv_id_2, serv_data_2, \ - serv_id_3, serv_data_3, \ - serv_id_4, serv_data_4, \ - serv_id_5, serv_data_5, \ - serv_id_6, serv_data_6, \ - serv_id_7, serv_data_7 ) \ - void \ - FT_Destroy_Class_ ## class_( FT_Library library, \ - FT_ServiceDescRec* clazz ) \ - { \ - FT_Memory memory = library->memory; \ - \ - \ - if ( clazz ) \ - FT_FREE( clazz ); \ - } \ - \ - FT_Error \ - FT_Create_Class_ ## class_( FT_Library library, \ - FT_ServiceDescRec** output_class ) \ - { \ - FT_ServiceDescRec* clazz = NULL; \ - FT_Error error; \ - FT_Memory memory = library->memory; \ - \ - \ - if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 8 ) ) \ - return error; \ - \ - clazz[0].serv_id = serv_id_1; \ - clazz[0].serv_data = serv_data_1; \ - clazz[1].serv_id = serv_id_2; \ - clazz[1].serv_data = serv_data_2; \ - clazz[2].serv_id = serv_id_3; \ - clazz[2].serv_data = serv_data_3; \ - clazz[3].serv_id = serv_id_4; \ - clazz[3].serv_data = serv_data_4; \ - clazz[4].serv_id = serv_id_5; \ - clazz[4].serv_data = serv_data_5; \ - clazz[5].serv_id = serv_id_6; \ - clazz[5].serv_data = serv_data_6; \ - clazz[6].serv_id = serv_id_7; \ - clazz[6].serv_data = serv_data_7; \ - clazz[7].serv_id = NULL; \ - clazz[7].serv_data = NULL; \ - \ - *output_class = clazz; \ - \ - return FT_Err_Ok; \ - } - -#define FT_DEFINE_SERVICEDESCREC8( class_, \ - serv_id_1, serv_data_1, \ - serv_id_2, serv_data_2, \ - serv_id_3, serv_data_3, \ - serv_id_4, serv_data_4, \ - serv_id_5, serv_data_5, \ - serv_id_6, serv_data_6, \ - serv_id_7, serv_data_7, \ - serv_id_8, serv_data_8 ) \ - void \ - FT_Destroy_Class_ ## class_( FT_Library library, \ - FT_ServiceDescRec* clazz ) \ - { \ - FT_Memory memory = library->memory; \ - \ - \ - if ( clazz ) \ - FT_FREE( clazz ); \ - } \ - \ - FT_Error \ - FT_Create_Class_ ## class_( FT_Library library, \ - FT_ServiceDescRec** output_class ) \ - { \ - FT_ServiceDescRec* clazz = NULL; \ - FT_Error error; \ - FT_Memory memory = library->memory; \ - \ - \ - if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 9 ) ) \ - return error; \ - \ - clazz[0].serv_id = serv_id_1; \ - clazz[0].serv_data = serv_data_1; \ - clazz[1].serv_id = serv_id_2; \ - clazz[1].serv_data = serv_data_2; \ - clazz[2].serv_id = serv_id_3; \ - clazz[2].serv_data = serv_data_3; \ - clazz[3].serv_id = serv_id_4; \ - clazz[3].serv_data = serv_data_4; \ - clazz[4].serv_id = serv_id_5; \ - clazz[4].serv_data = serv_data_5; \ - clazz[5].serv_id = serv_id_6; \ - clazz[5].serv_data = serv_data_6; \ - clazz[6].serv_id = serv_id_7; \ - clazz[6].serv_data = serv_data_7; \ - clazz[7].serv_id = serv_id_8; \ - clazz[7].serv_data = serv_data_8; \ - clazz[8].serv_id = NULL; \ - clazz[8].serv_data = NULL; \ - \ - *output_class = clazz; \ - \ - return FT_Err_Ok; \ - } - -#define FT_DEFINE_SERVICEDESCREC9( class_, \ - serv_id_1, serv_data_1, \ - serv_id_2, serv_data_2, \ - serv_id_3, serv_data_3, \ - serv_id_4, serv_data_4, \ - serv_id_5, serv_data_5, \ - serv_id_6, serv_data_6, \ - serv_id_7, serv_data_7, \ - serv_id_8, serv_data_8, \ - serv_id_9, serv_data_9 ) \ - void \ - FT_Destroy_Class_ ## class_( FT_Library library, \ - FT_ServiceDescRec* clazz ) \ - { \ - FT_Memory memory = library->memory; \ - \ - \ - if ( clazz ) \ - FT_FREE( clazz ); \ - } \ - \ - FT_Error \ - FT_Create_Class_ ## class_( FT_Library library, \ - FT_ServiceDescRec** output_class ) \ - { \ - FT_ServiceDescRec* clazz = NULL; \ - FT_Error error; \ - FT_Memory memory = library->memory; \ - \ - \ - if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 10 ) ) \ - return error; \ - \ - clazz[0].serv_id = serv_id_1; \ - clazz[0].serv_data = serv_data_1; \ - clazz[1].serv_id = serv_id_2; \ - clazz[1].serv_data = serv_data_2; \ - clazz[2].serv_id = serv_id_3; \ - clazz[2].serv_data = serv_data_3; \ - clazz[3].serv_id = serv_id_4; \ - clazz[3].serv_data = serv_data_4; \ - clazz[4].serv_id = serv_id_5; \ - clazz[4].serv_data = serv_data_5; \ - clazz[5].serv_id = serv_id_6; \ - clazz[5].serv_data = serv_data_6; \ - clazz[6].serv_id = serv_id_7; \ - clazz[6].serv_data = serv_data_7; \ - clazz[7].serv_id = serv_id_8; \ - clazz[7].serv_data = serv_data_8; \ - clazz[8].serv_id = serv_id_9; \ - clazz[8].serv_data = serv_data_9; \ - clazz[9].serv_id = NULL; \ - clazz[9].serv_data = NULL; \ - \ - *output_class = clazz; \ - \ - return FT_Err_Ok; \ - } - -#define FT_DEFINE_SERVICEDESCREC10( class_, \ - serv_id_1, serv_data_1, \ - serv_id_2, serv_data_2, \ - serv_id_3, serv_data_3, \ - serv_id_4, serv_data_4, \ - serv_id_5, serv_data_5, \ - serv_id_6, serv_data_6, \ - serv_id_7, serv_data_7, \ - serv_id_8, serv_data_8, \ - serv_id_9, serv_data_9, \ - serv_id_10, serv_data_10 ) \ - void \ - FT_Destroy_Class_ ## class_( FT_Library library, \ - FT_ServiceDescRec* clazz ) \ - { \ - FT_Memory memory = library->memory; \ - \ - \ - if ( clazz ) \ - FT_FREE( clazz ); \ - } \ - \ - FT_Error \ - FT_Create_Class_ ## class_( FT_Library library, \ - FT_ServiceDescRec** output_class ) \ - { \ - FT_ServiceDescRec* clazz = NULL; \ - FT_Error error; \ - FT_Memory memory = library->memory; \ - \ - \ - if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 11 ) ) \ - return error; \ - \ - clazz[ 0].serv_id = serv_id_1; \ - clazz[ 0].serv_data = serv_data_1; \ - clazz[ 1].serv_id = serv_id_2; \ - clazz[ 1].serv_data = serv_data_2; \ - clazz[ 2].serv_id = serv_id_3; \ - clazz[ 2].serv_data = serv_data_3; \ - clazz[ 3].serv_id = serv_id_4; \ - clazz[ 3].serv_data = serv_data_4; \ - clazz[ 4].serv_id = serv_id_5; \ - clazz[ 4].serv_data = serv_data_5; \ - clazz[ 5].serv_id = serv_id_6; \ - clazz[ 5].serv_data = serv_data_6; \ - clazz[ 6].serv_id = serv_id_7; \ - clazz[ 6].serv_data = serv_data_7; \ - clazz[ 7].serv_id = serv_id_8; \ - clazz[ 7].serv_data = serv_data_8; \ - clazz[ 8].serv_id = serv_id_9; \ - clazz[ 8].serv_data = serv_data_9; \ - clazz[ 9].serv_id = serv_id_10; \ - clazz[ 9].serv_data = serv_data_10; \ - clazz[10].serv_id = NULL; \ - clazz[10].serv_data = NULL; \ - \ - *output_class = clazz; \ - \ - return FT_Err_Ok; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - /* - * Parse a list of FT_ServiceDescRec descriptors and look for - * a specific service by ID. Note that the last element in the - * array must be { NULL, NULL }, and that the function should - * return NULL if the service isn't available. + * Parse a list of FT_ServiceDescRec descriptors and look for a specific + * service by ID. Note that the last element in the array must be { NULL, + * NULL }, and that the function should return NULL if the service isn't + * available. * - * This function can be used by modules to implement their - * `get_service' method. + * This function can be used by modules to implement their `get_service' + * method. */ FT_BASE( FT_Pointer ) ft_service_list_lookup( FT_ServiceDesc service_descriptors, @@ -869,16 +373,16 @@ FT_BEGIN_HEADER /*************************************************************************/ /* - * This structure is used to store a cache for several frequently used - * services. It is the type of `face->internal->services'. You - * should only use FT_FACE_LOOKUP_SERVICE to access it. + * This structure is used to store a cache for several frequently used + * services. It is the type of `face->internal->services'. You should + * only use FT_FACE_LOOKUP_SERVICE to access it. * - * All fields should have the type FT_Pointer to relax compilation - * dependencies. We assume the developer isn't completely stupid. + * All fields should have the type FT_Pointer to relax compilation + * dependencies. We assume the developer isn't completely stupid. * - * Each field must be named `service_XXXX' where `XXX' corresponds to - * the correct FT_SERVICE_ID_XXXX macro. See the definition of - * FT_FACE_LOOKUP_SERVICE below how this is implemented. + * Each field must be named `service_XXXX' where `XXX' corresponds to the + * correct FT_SERVICE_ID_XXXX macro. See the definition of + * FT_FACE_LOOKUP_SERVICE below how this is implemented. * */ typedef struct FT_ServiceCacheRec_ @@ -894,14 +398,15 @@ FT_BEGIN_HEADER /* - * A magic number used within the services cache. + * A magic number used within the services cache. */ /* ensure that value `1' has the same width as a pointer */ #define FT_SERVICE_UNAVAILABLE ((FT_Pointer)~(FT_PtrDist)1) - /* + /************************************************************************** + * * @macro: * FT_FACE_LOOKUP_SERVICE * @@ -910,7 +415,7 @@ FT_BEGIN_HEADER * using its cache. * * @input: - * face:: + * face :: * The source face handle containing the cache. * * field :: @@ -921,7 +426,7 @@ FT_BEGIN_HEADER * * @output: * ptr :: - * A variable receiving the service data. NULL if not available. + * A variable receiving the service data. `NULL` if not available. */ #ifdef __cplusplus @@ -969,7 +474,7 @@ FT_BEGIN_HEADER #endif /* !C++ */ /* - * A macro used to define new service structure types. + * A macro used to define new service structure types. */ #define FT_DEFINE_SERVICE( name ) \ @@ -982,7 +487,7 @@ FT_BEGIN_HEADER /* */ /* - * The header files containing the services. + * The header files containing the services. */ #define FT_SERVICE_BDF_H <freetype/internal/services/svbdf.h> diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/ftstream.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/ftstream.h index f90002fe774b7..e4dca0b0a5d97 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/ftstream.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/ftstream.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftstream.h */ -/* */ -/* Stream handling (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftstream.h + * + * Stream handling (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTSTREAM_H_ @@ -96,13 +96,13 @@ FT_BEGIN_HEADER /* The structure type must be set in the FT_STRUCTURE macro before */ /* calling the FT_FRAME_START() macro. */ /* */ -#define FT_FIELD_SIZE( f ) \ +#define FT_FIELD_SIZE( f ) \ (FT_Byte)sizeof ( ((FT_STRUCTURE*)0)->f ) -#define FT_FIELD_SIZE_DELTA( f ) \ +#define FT_FIELD_SIZE_DELTA( f ) \ (FT_Byte)sizeof ( ((FT_STRUCTURE*)0)->f[0] ) -#define FT_FIELD_OFFSET( f ) \ +#define FT_FIELD_OFFSET( f ) \ (FT_UShort)( offsetof( FT_STRUCTURE, f ) ) #define FT_FRAME_FIELD( frame_op, field ) \ @@ -147,11 +147,11 @@ FT_BEGIN_HEADER #define FT_FRAME_SKIP_BYTES( count ) { ft_frame_skip, count, 0 } - /*************************************************************************/ - /* */ - /* Integer extraction macros -- the `buffer' parameter must ALWAYS be of */ - /* type `char*' or equivalent (1-byte elements). */ - /* */ + /************************************************************************** + * + * Integer extraction macros -- the 'buffer' parameter must ALWAYS be of + * type 'char*' or equivalent (1-byte elements). + */ #define FT_BYTE_( p, i ) ( ((const FT_Byte*)(p))[(i)] ) @@ -165,6 +165,10 @@ FT_BEGIN_HEADER #define FT_BYTE_U32( p, i, s ) ( FT_UINT32( FT_BYTE_( p, i ) ) << (s) ) + /* + * `FT_PEEK_XXX' are generic macros to get data from a buffer position. No + * safety checks are performed. + */ #define FT_PEEK_SHORT( p ) FT_INT16( FT_BYTE_U16( p, 0, 8 ) | \ FT_BYTE_U16( p, 1, 0 ) ) @@ -213,7 +217,10 @@ FT_BEGIN_HEADER FT_BYTE_U32( p, 1, 8 ) | \ FT_BYTE_U32( p, 0, 0 ) ) - + /* + * `FT_NEXT_XXX' are generic macros to get data from a buffer position + * which is then increased appropriately. No safety checks are performed. + */ #define FT_NEXT_CHAR( buffer ) \ ( (signed char)*buffer++ ) @@ -258,10 +265,14 @@ FT_BEGIN_HEADER ( (unsigned long)( buffer += 4, FT_PEEK_ULONG_LE( buffer - 4 ) ) ) - /*************************************************************************/ - /* */ - /* Each GET_xxxx() macro uses an implicit `stream' variable. */ - /* */ + /************************************************************************** + * + * The `FT_GET_XXX` macros use an implicit 'stream' variable. + * + * Note that a call to `FT_STREAM_SEEK` or `FT_STREAM_POS` has **no** + * effect on `FT_GET_XXX`! They operate on `stream->pos`, while + * `FT_GET_XXX` use `stream->cursor`. + */ #if 0 #define FT_GET_MACRO( type ) FT_NEXT_ ## type ( stream->cursor ) @@ -299,10 +310,18 @@ FT_BEGIN_HEADER #define FT_GET_ULONG_LE() FT_GET_MACRO( FT_Stream_GetULongLE, FT_ULong ) #endif + #define FT_READ_MACRO( func, type, var ) \ ( var = (type)func( stream, &error ), \ error != FT_Err_Ok ) + /* + * The `FT_READ_XXX' macros use implicit `stream' and `error' variables. + * + * `FT_READ_XXX' can be controlled with `FT_STREAM_SEEK' and + * `FT_STREAM_POS'. They use the full machinery to check whether a read is + * valid. + */ #define FT_READ_BYTE( var ) FT_READ_MACRO( FT_Stream_ReadChar, FT_Byte, var ) #define FT_READ_CHAR( var ) FT_READ_MACRO( FT_Stream_ReadChar, FT_Char, var ) #define FT_READ_SHORT( var ) FT_READ_MACRO( FT_Stream_ReadUShort, FT_Short, var ) @@ -387,12 +406,14 @@ FT_BEGIN_HEADER /* Enter a frame of `count' consecutive bytes in a stream. Returns an */ /* error if the frame could not be read/accessed. The caller can use */ - /* the FT_Stream_Get_XXX functions to retrieve frame data without */ + /* the `FT_Stream_GetXXX' functions to retrieve frame data without */ /* error checks. */ /* */ - /* You must _always_ call FT_Stream_ExitFrame() once you have entered */ + /* You must _always_ call `FT_Stream_ExitFrame' once you have entered */ /* a stream frame! */ /* */ + /* Nested frames are not permitted. */ + /* */ FT_BASE( FT_Error ) FT_Stream_EnterFrame( FT_Stream stream, FT_ULong count ); @@ -401,25 +422,29 @@ FT_BEGIN_HEADER FT_BASE( void ) FT_Stream_ExitFrame( FT_Stream stream ); + /* Extract a stream frame. If the stream is disk-based, a heap block */ /* is allocated and the frame bytes are read into it. If the stream */ - /* is memory-based, this function simply set a pointer to the data. */ + /* is memory-based, this function simply sets a pointer to the data. */ /* */ /* Useful to optimize access to memory-based streams transparently. */ /* */ - /* All extracted frames must be `freed' with a call to the function */ - /* FT_Stream_ReleaseFrame(). */ + /* `FT_Stream_GetXXX' functions can't be used. */ + /* */ + /* An extracted frame must be `freed' with a call to the function */ + /* `FT_Stream_ReleaseFrame'. */ /* */ FT_BASE( FT_Error ) FT_Stream_ExtractFrame( FT_Stream stream, FT_ULong count, FT_Byte** pbytes ); - /* release an extract frame (see FT_Stream_ExtractFrame) */ + /* release an extract frame (see `FT_Stream_ExtractFrame') */ FT_BASE( void ) FT_Stream_ReleaseFrame( FT_Stream stream, FT_Byte** pbytes ); + /* read a byte from an entered frame */ FT_BASE( FT_Char ) FT_Stream_GetChar( FT_Stream stream ); diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/fttrace.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/fttrace.h index 8092e41fd73dd..8089babfb6c20 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/fttrace.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/fttrace.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* fttrace.h */ -/* */ -/* Tracing handling (specification only). */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * fttrace.h + * + * Tracing handling (specification only). + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ /* definitions of trace levels for FreeType 2 */ @@ -23,23 +23,24 @@ FT_TRACE_DEF( any ) /* base components */ FT_TRACE_DEF( calc ) /* calculations (ftcalc.c) */ +FT_TRACE_DEF( gloader ) /* glyph loader (ftgloadr.c) */ +FT_TRACE_DEF( glyph ) /* glyph management (ftglyph.c) */ FT_TRACE_DEF( memory ) /* memory manager (ftobjs.c) */ -FT_TRACE_DEF( stream ) /* stream manager (ftstream.c) */ +FT_TRACE_DEF( init ) /* initialization (ftinit.c) */ FT_TRACE_DEF( io ) /* i/o interface (ftsystem.c) */ FT_TRACE_DEF( list ) /* list management (ftlist.c) */ -FT_TRACE_DEF( init ) /* initialization (ftinit.c) */ FT_TRACE_DEF( objs ) /* base objects (ftobjs.c) */ FT_TRACE_DEF( outline ) /* outline management (ftoutln.c) */ -FT_TRACE_DEF( glyph ) /* glyph management (ftglyph.c) */ -FT_TRACE_DEF( gloader ) /* glyph loader (ftgloadr.c) */ +FT_TRACE_DEF( stream ) /* stream manager (ftstream.c) */ -FT_TRACE_DEF( raster ) /* monochrome rasterizer (ftraster.c) */ -FT_TRACE_DEF( smooth ) /* anti-aliasing raster (ftgrays.c) */ +FT_TRACE_DEF( bitmap ) /* bitmap manipulation (ftbitmap.c) */ +FT_TRACE_DEF( checksum ) /* bitmap checksum (ftobjs.c) */ FT_TRACE_DEF( mm ) /* MM interface (ftmm.c) */ +FT_TRACE_DEF( psprops ) /* PS driver properties (ftpsprop.c) */ FT_TRACE_DEF( raccess ) /* resource fork accessor (ftrfork.c) */ +FT_TRACE_DEF( raster ) /* monochrome rasterizer (ftraster.c) */ +FT_TRACE_DEF( smooth ) /* anti-aliasing raster (ftgrays.c) */ FT_TRACE_DEF( synth ) /* bold/slant synthesizer (ftsynth.c) */ -FT_TRACE_DEF( bitmap ) /* bitmap checksum (ftobjs.c) */ -FT_TRACE_DEF( psprops ) /* PS driver properties (ftpsprop.c) */ /* Cache sub-system */ FT_TRACE_DEF( cache ) /* cache sub-system (ftcache.c, etc.) */ @@ -47,21 +48,23 @@ FT_TRACE_DEF( cache ) /* cache sub-system (ftcache.c, etc.) */ /* SFNT driver components */ FT_TRACE_DEF( sfdriver ) /* SFNT font driver (sfdriver.c) */ FT_TRACE_DEF( sfobjs ) /* SFNT object handler (sfobjs.c) */ +FT_TRACE_DEF( ttbdf ) /* TrueType embedded BDF (ttbdf.c) */ FT_TRACE_DEF( ttcmap ) /* charmap handler (ttcmap.c) */ +FT_TRACE_DEF( ttcolr ) /* glyph layer table (ttcolr.c) */ +FT_TRACE_DEF( ttcpal ) /* color palette table (ttcpal.c) */ FT_TRACE_DEF( ttkern ) /* kerning handler (ttkern.c) */ FT_TRACE_DEF( ttload ) /* basic TrueType tables (ttload.c) */ FT_TRACE_DEF( ttmtx ) /* metrics-related tables (ttmtx.c) */ FT_TRACE_DEF( ttpost ) /* PS table processing (ttpost.c) */ FT_TRACE_DEF( ttsbit ) /* TrueType sbit handling (ttsbit.c) */ -FT_TRACE_DEF( ttbdf ) /* TrueType embedded BDF (ttbdf.c) */ /* TrueType driver components */ FT_TRACE_DEF( ttdriver ) /* TT font driver (ttdriver.c) */ FT_TRACE_DEF( ttgload ) /* TT glyph loader (ttgload.c) */ +FT_TRACE_DEF( ttgxvar ) /* TrueType GX var handler (ttgxvar.c) */ FT_TRACE_DEF( ttinterp ) /* bytecode interpreter (ttinterp.c) */ FT_TRACE_DEF( ttobjs ) /* TT objects manager (ttobjs.c) */ FT_TRACE_DEF( ttpload ) /* TT data/program loader (ttpload.c) */ -FT_TRACE_DEF( ttgxvar ) /* TrueType GX var handler (ttgxvar.c) */ /* Type 1 driver components */ FT_TRACE_DEF( t1afm ) @@ -72,14 +75,14 @@ FT_TRACE_DEF( t1objs ) FT_TRACE_DEF( t1parse ) /* PostScript helper module `psaux' */ -FT_TRACE_DEF( t1decode ) FT_TRACE_DEF( cffdecode ) -FT_TRACE_DEF( psobjs ) FT_TRACE_DEF( psconv ) +FT_TRACE_DEF( psobjs ) +FT_TRACE_DEF( t1decode ) /* PostScript hinting module `pshinter' */ -FT_TRACE_DEF( pshrec ) FT_TRACE_DEF( pshalgo ) +FT_TRACE_DEF( pshrec ) /* Type 2 driver components */ FT_TRACE_DEF( cffdriver ) @@ -117,7 +120,6 @@ FT_TRACE_DEF( bdflib ) FT_TRACE_DEF( pfr ) /* OpenType validation components */ -FT_TRACE_DEF( otvmodule ) FT_TRACE_DEF( otvcommon ) FT_TRACE_DEF( otvbase ) FT_TRACE_DEF( otvgdef ) @@ -125,29 +127,30 @@ FT_TRACE_DEF( otvgpos ) FT_TRACE_DEF( otvgsub ) FT_TRACE_DEF( otvjstf ) FT_TRACE_DEF( otvmath ) +FT_TRACE_DEF( otvmodule ) /* TrueTypeGX/AAT validation components */ -FT_TRACE_DEF( gxvmodule ) +FT_TRACE_DEF( gxvbsln ) FT_TRACE_DEF( gxvcommon ) FT_TRACE_DEF( gxvfeat ) -FT_TRACE_DEF( gxvmort ) -FT_TRACE_DEF( gxvmorx ) -FT_TRACE_DEF( gxvbsln ) FT_TRACE_DEF( gxvjust ) FT_TRACE_DEF( gxvkern ) +FT_TRACE_DEF( gxvmodule ) +FT_TRACE_DEF( gxvmort ) +FT_TRACE_DEF( gxvmorx ) +FT_TRACE_DEF( gxvlcar ) FT_TRACE_DEF( gxvopbd ) -FT_TRACE_DEF( gxvtrak ) FT_TRACE_DEF( gxvprop ) -FT_TRACE_DEF( gxvlcar ) +FT_TRACE_DEF( gxvtrak ) /* autofit components */ -FT_TRACE_DEF( afmodule ) -FT_TRACE_DEF( afhints ) FT_TRACE_DEF( afcjk ) +FT_TRACE_DEF( afglobal ) +FT_TRACE_DEF( afhints ) +FT_TRACE_DEF( afmodule ) FT_TRACE_DEF( aflatin ) FT_TRACE_DEF( aflatin2 ) -FT_TRACE_DEF( afwarp ) FT_TRACE_DEF( afshaper ) -FT_TRACE_DEF( afglobal ) +FT_TRACE_DEF( afwarp ) /* END */ diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/ftvalid.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/ftvalid.h index cad47a556d3ca..38aa06cc4e9af 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/ftvalid.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/ftvalid.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftvalid.h */ -/* */ -/* FreeType validation support (specification). */ -/* */ -/* Copyright 2004-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftvalid.h + * + * FreeType validation support (specification). + * + * Copyright (C) 2004-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTVALID_H_ @@ -42,31 +42,31 @@ FT_BEGIN_HEADER typedef struct FT_ValidatorRec_ volatile* FT_Validator; - /*************************************************************************/ - /* */ - /* There are three distinct validation levels defined here: */ - /* */ - /* FT_VALIDATE_DEFAULT :: */ - /* A table that passes this validation level can be used reliably by */ - /* FreeType. It generally means that all offsets have been checked to */ - /* prevent out-of-bound reads, that array counts are correct, etc. */ - /* */ - /* FT_VALIDATE_TIGHT :: */ - /* A table that passes this validation level can be used reliably and */ - /* doesn't contain invalid data. For example, a charmap table that */ - /* returns invalid glyph indices will not pass, even though it can */ - /* be used with FreeType in default mode (the library will simply */ - /* return an error later when trying to load the glyph). */ - /* */ - /* It also checks that fields which must be a multiple of 2, 4, or 8, */ - /* don't have incorrect values, etc. */ - /* */ - /* FT_VALIDATE_PARANOID :: */ - /* Only for font debugging. Checks that a table follows the */ - /* specification by 100%. Very few fonts will be able to pass this */ - /* level anyway but it can be useful for certain tools like font */ - /* editors/converters. */ - /* */ + /************************************************************************** + * + * There are three distinct validation levels defined here: + * + * FT_VALIDATE_DEFAULT :: + * A table that passes this validation level can be used reliably by + * FreeType. It generally means that all offsets have been checked to + * prevent out-of-bound reads, that array counts are correct, etc. + * + * FT_VALIDATE_TIGHT :: + * A table that passes this validation level can be used reliably and + * doesn't contain invalid data. For example, a charmap table that + * returns invalid glyph indices will not pass, even though it can be + * used with FreeType in default mode (the library will simply return an + * error later when trying to load the glyph). + * + * It also checks that fields which must be a multiple of 2, 4, or 8, + * don't have incorrect values, etc. + * + * FT_VALIDATE_PARANOID :: + * Only for font debugging. Checks that a table follows the + * specification by 100%. Very few fonts will be able to pass this level + * anyway but it can be useful for certain tools like font + * editors/converters. + */ typedef enum FT_ValidationLevel_ { FT_VALIDATE_DEFAULT = 0, diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/internal.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/internal.h index 8f546e443ba8a..173d8ad906d5a 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/internal.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/internal.h @@ -1,31 +1,30 @@ -/***************************************************************************/ -/* */ -/* internal.h */ -/* */ -/* Internal header files (specification only). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * internal.h + * + * Internal header files (specification only). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ - /*************************************************************************/ - /* */ - /* This file is automatically included by `ft2build.h'. */ - /* Do not include it manually! */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * This file is automatically included by `ft2build.h`. Do not include it + * manually! + * + */ #define FT_INTERNAL_OBJECTS_H <freetype/internal/ftobjs.h> -#define FT_INTERNAL_PIC_H <freetype/internal/ftpic.h> #define FT_INTERNAL_STREAM_H <freetype/internal/ftstream.h> #define FT_INTERNAL_MEMORY_H <freetype/internal/ftmemory.h> #define FT_INTERNAL_DEBUG_H <freetype/internal/ftdebug.h> diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/psaux.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/psaux.h index f77380d25ff01..3ab01c3e688b7 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/psaux.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/psaux.h @@ -1,20 +1,20 @@ -/***************************************************************************/ -/* */ -/* psaux.h */ -/* */ -/* Auxiliary functions and data structures related to PostScript fonts */ -/* (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * psaux.h + * + * Auxiliary functions and data structures related to PostScript fonts + * (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef PSAUX_H_ @@ -35,10 +35,10 @@ FT_BEGIN_HEADER - /***********************************************************************/ - /* */ - /* PostScript modules driver class. */ - /* */ + /************************************************************************** + * + * PostScript modules driver class. + */ typedef struct PS_DriverRec_ { FT_DriverRec root; @@ -64,23 +64,27 @@ FT_BEGIN_HEADER typedef const struct PS_Table_FuncsRec_* PS_Table_Funcs; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* PS_Table_FuncsRec */ - /* */ - /* <Description> */ - /* A set of function pointers to manage PS_Table objects. */ - /* */ - /* <Fields> */ - /* table_init :: Used to initialize a table. */ - /* */ - /* table_done :: Finalizes resp. destroy a given table. */ - /* */ - /* table_add :: Adds a new object to a table. */ - /* */ - /* table_release :: Releases table data, then finalizes it. */ - /* */ + /************************************************************************** + * + * @struct: + * PS_Table_FuncsRec + * + * @description: + * A set of function pointers to manage PS_Table objects. + * + * @fields: + * table_init :: + * Used to initialize a table. + * + * table_done :: + * Finalizes resp. destroy a given table. + * + * table_add :: + * Adds a new object to a table. + * + * table_release :: + * Releases table data, then finalizes it. + */ typedef struct PS_Table_FuncsRec_ { FT_Error @@ -103,41 +107,47 @@ FT_BEGIN_HEADER } PS_Table_FuncsRec; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* PS_TableRec */ - /* */ - /* <Description> */ - /* A PS_Table is a simple object used to store an array of objects in */ - /* a single memory block. */ - /* */ - /* <Fields> */ - /* block :: The address in memory of the growheap's block. This */ - /* can change between two object adds, due to */ - /* reallocation. */ - /* */ - /* cursor :: The current top of the grow heap within its block. */ - /* */ - /* capacity :: The current size of the heap block. Increments by */ - /* 1kByte chunks. */ - /* */ - /* init :: Set to 0xDEADBEEF if `elements' and `lengths' have */ - /* been allocated. */ - /* */ - /* max_elems :: The maximum number of elements in table. */ - /* */ - /* num_elems :: The current number of elements in table. */ - /* */ - /* elements :: A table of element addresses within the block. */ - /* */ - /* lengths :: A table of element sizes within the block. */ - /* */ - /* memory :: The object used for memory operations */ - /* (alloc/realloc). */ - /* */ - /* funcs :: A table of method pointers for this object. */ - /* */ + /************************************************************************** + * + * @struct: + * PS_TableRec + * + * @description: + * A PS_Table is a simple object used to store an array of objects in a + * single memory block. + * + * @fields: + * block :: + * The address in memory of the growheap's block. This can change + * between two object adds, due to reallocation. + * + * cursor :: + * The current top of the grow heap within its block. + * + * capacity :: + * The current size of the heap block. Increments by 1kByte chunks. + * + * init :: + * Set to 0xDEADBEEF if 'elements' and 'lengths' have been allocated. + * + * max_elems :: + * The maximum number of elements in table. + * + * num_elems :: + * The current number of elements in table. + * + * elements :: + * A table of element addresses within the block. + * + * lengths :: + * A table of element sizes within the block. + * + * memory :: + * The object used for memory operations (alloc/realloc). + * + * funcs :: + * A table of method pointers for this object. + */ typedef struct PS_TableRec_ { FT_Byte* block; /* current memory block */ @@ -425,27 +435,33 @@ FT_BEGIN_HEADER } PS_Parser_FuncsRec; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* PS_ParserRec */ - /* */ - /* <Description> */ - /* A PS_Parser is an object used to parse a Type 1 font very quickly. */ - /* */ - /* <Fields> */ - /* cursor :: The current position in the text. */ - /* */ - /* base :: Start of the processed text. */ - /* */ - /* limit :: End of the processed text. */ - /* */ - /* error :: The last error returned. */ - /* */ - /* memory :: The object used for memory operations (alloc/realloc). */ - /* */ - /* funcs :: A table of functions for the parser. */ - /* */ + /************************************************************************** + * + * @struct: + * PS_ParserRec + * + * @description: + * A PS_Parser is an object used to parse a Type 1 font very quickly. + * + * @fields: + * cursor :: + * The current position in the text. + * + * base :: + * Start of the processed text. + * + * limit :: + * End of the processed text. + * + * error :: + * The last error returned. + * + * memory :: + * The object used for memory operations (alloc/realloc). + * + * funcs :: + * A table of functions for the parser. + */ typedef struct PS_ParserRec_ { FT_Byte* cursor; @@ -484,51 +500,67 @@ FT_BEGIN_HEADER } PS_Builder_FuncsRec; - /*************************************************************************/ - /* */ - /* <Structure> */ - /* PS_Builder */ - /* */ - /* <Description> */ - /* A structure used during glyph loading to store its outline. */ - /* */ - /* <Fields> */ - /* memory :: The current memory object. */ - /* */ - /* face :: The current face object. */ - /* */ - /* glyph :: The current glyph slot. */ - /* */ - /* loader :: XXX */ - /* */ - /* base :: The base glyph outline. */ - /* */ - /* current :: The current glyph outline. */ - /* */ - /* pos_x :: The horizontal translation (if composite glyph). */ - /* */ - /* pos_y :: The vertical translation (if composite glyph). */ - /* */ - /* left_bearing :: The left side bearing point. */ - /* */ - /* advance :: The horizontal advance vector. */ - /* */ - /* bbox :: Unused. */ - /* */ - /* path_begun :: A flag which indicates that a new path has begun. */ - /* */ - /* load_points :: If this flag is not set, no points are loaded. */ - /* */ - /* no_recurse :: Set but not used. */ - /* */ - /* metrics_only :: A boolean indicating that we only want to compute */ - /* the metrics of a given glyph, not load all of its */ - /* points. */ - /* */ - /* is_t1 :: Set if current font type is Type 1. */ - /* */ - /* funcs :: An array of function pointers for the builder. */ - /* */ + /************************************************************************** + * + * @struct: + * PS_Builder + * + * @description: + * A structure used during glyph loading to store its outline. + * + * @fields: + * memory :: + * The current memory object. + * + * face :: + * The current face object. + * + * glyph :: + * The current glyph slot. + * + * loader :: + * XXX + * + * base :: + * The base glyph outline. + * + * current :: + * The current glyph outline. + * + * pos_x :: + * The horizontal translation (if composite glyph). + * + * pos_y :: + * The vertical translation (if composite glyph). + * + * left_bearing :: + * The left side bearing point. + * + * advance :: + * The horizontal advance vector. + * + * bbox :: + * Unused. + * + * path_begun :: + * A flag which indicates that a new path has begun. + * + * load_points :: + * If this flag is not set, no points are loaded. + * + * no_recurse :: + * Set but not used. + * + * metrics_only :: + * A boolean indicating that we only want to compute the metrics of a + * given glyph, not load all of its points. + * + * is_t1 :: + * Set if current font type is Type 1. + * + * funcs :: + * An array of function pointers for the builder. + */ struct PS_Builder_ { FT_Memory memory; @@ -729,54 +761,70 @@ FT_BEGIN_HEADER } T1_ParseState; - /*************************************************************************/ - /* */ - /* <Structure> */ - /* T1_BuilderRec */ - /* */ - /* <Description> */ - /* A structure used during glyph loading to store its outline. */ - /* */ - /* <Fields> */ - /* memory :: The current memory object. */ - /* */ - /* face :: The current face object. */ - /* */ - /* glyph :: The current glyph slot. */ - /* */ - /* loader :: XXX */ - /* */ - /* base :: The base glyph outline. */ - /* */ - /* current :: The current glyph outline. */ - /* */ - /* max_points :: maximum points in builder outline */ - /* */ - /* max_contours :: Maximum number of contours in builder outline. */ - /* */ - /* pos_x :: The horizontal translation (if composite glyph). */ - /* */ - /* pos_y :: The vertical translation (if composite glyph). */ - /* */ - /* left_bearing :: The left side bearing point. */ - /* */ - /* advance :: The horizontal advance vector. */ - /* */ - /* bbox :: Unused. */ - /* */ - /* parse_state :: An enumeration which controls the charstring */ - /* parsing state. */ - /* */ - /* load_points :: If this flag is not set, no points are loaded. */ - /* */ - /* no_recurse :: Set but not used. */ - /* */ - /* metrics_only :: A boolean indicating that we only want to compute */ - /* the metrics of a given glyph, not load all of its */ - /* points. */ - /* */ - /* funcs :: An array of function pointers for the builder. */ - /* */ + /************************************************************************** + * + * @struct: + * T1_BuilderRec + * + * @description: + * A structure used during glyph loading to store its outline. + * + * @fields: + * memory :: + * The current memory object. + * + * face :: + * The current face object. + * + * glyph :: + * The current glyph slot. + * + * loader :: + * XXX + * + * base :: + * The base glyph outline. + * + * current :: + * The current glyph outline. + * + * max_points :: + * maximum points in builder outline + * + * max_contours :: + * Maximum number of contours in builder outline. + * + * pos_x :: + * The horizontal translation (if composite glyph). + * + * pos_y :: + * The vertical translation (if composite glyph). + * + * left_bearing :: + * The left side bearing point. + * + * advance :: + * The horizontal advance vector. + * + * bbox :: + * Unused. + * + * parse_state :: + * An enumeration which controls the charstring parsing state. + * + * load_points :: + * If this flag is not set, no points are loaded. + * + * no_recurse :: + * Set but not used. + * + * metrics_only :: + * A boolean indicating that we only want to compute the metrics of a + * given glyph, not load all of its points. + * + * funcs :: + * An array of function pointers for the builder. + */ typedef struct T1_BuilderRec_ { FT_Memory memory; @@ -817,19 +865,19 @@ FT_BEGIN_HEADER #if 0 - /*************************************************************************/ - /* */ - /* T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine */ - /* calls during glyph loading. */ - /* */ + /************************************************************************** + * + * T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine + * calls during glyph loading. + */ #define T1_MAX_SUBRS_CALLS 8 - /*************************************************************************/ - /* */ - /* T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity. A */ - /* minimum of 16 is required. */ - /* */ + /************************************************************************** + * + * T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity. A + * minimum of 16 is required. + */ #define T1_MAX_CHARSTRINGS_OPERANDS 32 #endif /* 0 */ @@ -993,53 +1041,70 @@ FT_BEGIN_HEADER } CFF_Builder_FuncsRec; - /*************************************************************************/ - /* */ - /* <Structure> */ - /* CFF_Builder */ - /* */ - /* <Description> */ - /* A structure used during glyph loading to store its outline. */ - /* */ - /* <Fields> */ - /* memory :: The current memory object. */ - /* */ - /* face :: The current face object. */ - /* */ - /* glyph :: The current glyph slot. */ - /* */ - /* loader :: The current glyph loader. */ - /* */ - /* base :: The base glyph outline. */ - /* */ - /* current :: The current glyph outline. */ - /* */ - /* pos_x :: The horizontal translation (if composite glyph). */ - /* */ - /* pos_y :: The vertical translation (if composite glyph). */ - /* */ - /* left_bearing :: The left side bearing point. */ - /* */ - /* advance :: The horizontal advance vector. */ - /* */ - /* bbox :: Unused. */ - /* */ - /* path_begun :: A flag which indicates that a new path has begun. */ - /* */ - /* load_points :: If this flag is not set, no points are loaded. */ - /* */ - /* no_recurse :: Set but not used. */ - /* */ - /* metrics_only :: A boolean indicating that we only want to compute */ - /* the metrics of a given glyph, not load all of its */ - /* points. */ - /* */ - /* hints_funcs :: Auxiliary pointer for hinting. */ - /* */ - /* hints_globals :: Auxiliary pointer for hinting. */ - /* */ - /* funcs :: A table of method pointers for this object. */ - /* */ + /************************************************************************** + * + * @struct: + * CFF_Builder + * + * @description: + * A structure used during glyph loading to store its outline. + * + * @fields: + * memory :: + * The current memory object. + * + * face :: + * The current face object. + * + * glyph :: + * The current glyph slot. + * + * loader :: + * The current glyph loader. + * + * base :: + * The base glyph outline. + * + * current :: + * The current glyph outline. + * + * pos_x :: + * The horizontal translation (if composite glyph). + * + * pos_y :: + * The vertical translation (if composite glyph). + * + * left_bearing :: + * The left side bearing point. + * + * advance :: + * The horizontal advance vector. + * + * bbox :: + * Unused. + * + * path_begun :: + * A flag which indicates that a new path has begun. + * + * load_points :: + * If this flag is not set, no points are loaded. + * + * no_recurse :: + * Set but not used. + * + * metrics_only :: + * A boolean indicating that we only want to compute the metrics of a + * given glyph, not load all of its points. + * + * hints_funcs :: + * Auxiliary pointer for hinting. + * + * hints_globals :: + * Auxiliary pointer for hinting. + * + * funcs :: + * A table of method pointers for this object. + */ struct CFF_Builder_ { FT_Memory memory; @@ -1211,25 +1276,27 @@ FT_BEGIN_HEADER typedef struct AFM_StreamRec_* AFM_Stream; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* AFM_ParserRec */ - /* */ - /* <Description> */ - /* An AFM_Parser is a parser for the AFM files. */ - /* */ - /* <Fields> */ - /* memory :: The object used for memory operations (alloc and */ - /* realloc). */ - /* */ - /* stream :: This is an opaque object. */ - /* */ - /* FontInfo :: The result will be stored here. */ - /* */ - /* get_index :: A user provided function to get a glyph index by its */ - /* name. */ - /* */ + /************************************************************************** + * + * @struct: + * AFM_ParserRec + * + * @description: + * An AFM_Parser is a parser for the AFM files. + * + * @fields: + * memory :: + * The object used for memory operations (alloc and realloc). + * + * stream :: + * This is an opaque object. + * + * FontInfo :: + * The result will be stored here. + * + * get_index :: + * A user provided function to get a glyph index by its name. + */ typedef struct AFM_ParserRec_ { FT_Memory memory; diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/pshints.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/pshints.h index d29314ec2efb8..699acea6f52c2 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/pshints.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/pshints.h @@ -1,21 +1,21 @@ -/***************************************************************************/ -/* */ -/* pshints.h */ -/* */ -/* Interface to Postscript-specific (Type 1 and Type 2) hints */ -/* recorders (specification only). These are used to support native */ -/* T1/T2 hints in the `type1', `cid', and `cff' font drivers. */ -/* */ -/* Copyright 2001-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * pshints.h + * + * Interface to Postscript-specific (Type 1 and Type 2) hints + * recorders (specification only). These are used to support native + * T1/T2 hints in the 'type1', 'cid', and 'cff' font drivers. + * + * Copyright (C) 2001-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef PSHINTS_H_ @@ -73,7 +73,7 @@ FT_BEGIN_HEADER /*************************************************************************/ /*************************************************************************/ - /************************************************************************* + /************************************************************************** * * @type: * T1_Hints @@ -86,16 +86,16 @@ FT_BEGIN_HEADER * @T1_Hints_FuncsRec structure. Recording glyph hints is normally * achieved through the following scheme: * - * - Open a new hint recording session by calling the `open' method. + * - Open a new hint recording session by calling the 'open' method. * This rewinds the recorder and prepare it for new input. * * - For each hint found in the glyph charstring, call the corresponding - * method (`stem', `stem3', or `reset'). Note that these functions do + * method ('stem', 'stem3', or 'reset'). Note that these functions do * not return an error code. * - * - Close the recording session by calling the `close' method. It - * returns an error code if the hints were invalid or something - * strange happened (e.g., memory shortage). + * - Close the recording session by calling the 'close' method. It + * returns an error code if the hints were invalid or something strange + * happened (e.g., memory shortage). * * The hints accumulated in the object can later be used by the * PostScript hinter. @@ -104,7 +104,7 @@ FT_BEGIN_HEADER typedef struct T1_HintsRec_* T1_Hints; - /************************************************************************* + /************************************************************************** * * @type: * T1_Hints_Funcs @@ -117,7 +117,7 @@ FT_BEGIN_HEADER typedef const struct T1_Hints_FuncsRec_* T1_Hints_Funcs; - /************************************************************************* + /************************************************************************** * * @functype: * T1_Hints_OpenFunc @@ -139,14 +139,14 @@ FT_BEGIN_HEADER (*T1_Hints_OpenFunc)( T1_Hints hints ); - /************************************************************************* + /************************************************************************** * * @functype: * T1_Hints_SetStemFunc * * @description: * A method of the @T1_Hints class used to record a new horizontal or - * vertical stem. This corresponds to the Type 1 `hstem' and `vstem' + * vertical stem. This corresponds to the Type 1 'hstem' and 'vstem' * operators. * * @input: @@ -164,15 +164,15 @@ FT_BEGIN_HEADER * Use vertical coordinates (y) for horizontal stems (dim=0). Use * horizontal coordinates (x) for vertical stems (dim=1). * - * `coords[0]' is the absolute stem position (lowest coordinate); - * `coords[1]' is the length. + * 'coords[0]' is the absolute stem position (lowest coordinate); + * 'coords[1]' is the length. * * The length can be negative, in which case it must be either -20 or - * -21. It is interpreted as a `ghost' stem, according to the Type 1 + * -21. It is interpreted as a 'ghost' stem, according to the Type 1 * specification. * - * If the length is -21 (corresponding to a bottom ghost stem), then - * the real stem position is `coords[0]+coords[1]'. + * If the length is -21 (corresponding to a bottom ghost stem), then the + * real stem position is 'coords[0]+coords[1]'. * */ typedef void @@ -181,7 +181,7 @@ FT_BEGIN_HEADER FT_Fixed* coords ); - /************************************************************************* + /************************************************************************** * * @functype: * T1_Hints_SetStem3Func @@ -215,7 +215,7 @@ FT_BEGIN_HEADER FT_Fixed* coords ); - /************************************************************************* + /************************************************************************** * * @functype: * T1_Hints_ResetFunc @@ -238,7 +238,7 @@ FT_BEGIN_HEADER FT_UInt end_point ); - /************************************************************************* + /************************************************************************** * * @functype: * T1_Hints_CloseFunc @@ -267,7 +267,7 @@ FT_BEGIN_HEADER FT_UInt end_point ); - /************************************************************************* + /************************************************************************** * * @functype: * T1_Hints_ApplyFunc @@ -297,7 +297,7 @@ FT_BEGIN_HEADER * On input, all points within the outline are in font coordinates. On * output, they are in 1/64th of pixels. * - * The scaling transformation is taken from the `globals' object which + * The scaling transformation is taken from the 'globals' object which * must correspond to the same font as the glyph. * */ @@ -308,7 +308,7 @@ FT_BEGIN_HEADER FT_Render_Mode hint_mode ); - /************************************************************************* + /************************************************************************** * * @struct: * T1_Hints_FuncsRec @@ -360,7 +360,7 @@ FT_BEGIN_HEADER /*************************************************************************/ /*************************************************************************/ - /************************************************************************* + /************************************************************************** * * @type: * T2_Hints @@ -373,16 +373,16 @@ FT_BEGIN_HEADER * @T2_Hints_FuncsRec structure. Recording glyph hints is normally * achieved through the following scheme: * - * - Open a new hint recording session by calling the `open' method. + * - Open a new hint recording session by calling the 'open' method. * This rewinds the recorder and prepare it for new input. * * - For each hint found in the glyph charstring, call the corresponding - * method (`stems', `hintmask', `counters'). Note that these - * functions do not return an error code. + * method ('stems', 'hintmask', 'counters'). Note that these functions + * do not return an error code. * - * - Close the recording session by calling the `close' method. It - * returns an error code if the hints were invalid or something - * strange happened (e.g., memory shortage). + * - Close the recording session by calling the 'close' method. It + * returns an error code if the hints were invalid or something strange + * happened (e.g., memory shortage). * * The hints accumulated in the object can later be used by the * Postscript hinter. @@ -391,7 +391,7 @@ FT_BEGIN_HEADER typedef struct T2_HintsRec_* T2_Hints; - /************************************************************************* + /************************************************************************** * * @type: * T2_Hints_Funcs @@ -404,7 +404,7 @@ FT_BEGIN_HEADER typedef const struct T2_Hints_FuncsRec_* T2_Hints_Funcs; - /************************************************************************* + /************************************************************************** * * @functype: * T2_Hints_OpenFunc @@ -426,7 +426,7 @@ FT_BEGIN_HEADER (*T2_Hints_OpenFunc)( T2_Hints hints ); - /************************************************************************* + /************************************************************************** * * @functype: * T2_Hints_StemsFunc @@ -434,7 +434,7 @@ FT_BEGIN_HEADER * @description: * A method of the @T2_Hints class used to set the table of stems in * either the vertical or horizontal dimension. Equivalent to the - * `hstem', `vstem', `hstemhm', and `vstemhm' Type 2 operators. + * 'hstem', 'vstem', 'hstemhm', and 'vstemhm' Type 2 operators. * * @input: * hints :: @@ -447,18 +447,18 @@ FT_BEGIN_HEADER * The number of stems. * * coords :: - * An array of `count' (position,length) pairs in 16.16 format. + * An array of 'count' (position,length) pairs in 16.16 format. * * @note: * Use vertical coordinates (y) for horizontal stems (dim=0). Use * horizontal coordinates (x) for vertical stems (dim=1). * - * There are `2*count' elements in the `coords' array. Each even - * element is an absolute position in font units, each odd element is a - * length in font units. + * There are '2*count' elements in the 'coords' array. Each even element + * is an absolute position in font units, each odd element is a length in + * font units. * - * A length can be negative, in which case it must be either -20 or - * -21. It is interpreted as a `ghost' stem, according to the Type 1 + * A length can be negative, in which case it must be either -20 or -21. + * It is interpreted as a 'ghost' stem, according to the Type 1 * specification. * */ @@ -469,22 +469,22 @@ FT_BEGIN_HEADER FT_Fixed* coordinates ); - /************************************************************************* + /************************************************************************** * * @functype: * T2_Hints_MaskFunc * * @description: * A method of the @T2_Hints class used to set a given hintmask (this - * corresponds to the `hintmask' Type 2 operator). + * corresponds to the 'hintmask' Type 2 operator). * * @input: * hints :: * A handle to the Type 2 hints recorder. * * end_point :: - * The glyph index of the last point to which the previously defined - * or activated hints apply. + * The glyph index of the last point to which the previously defined or + * activated hints apply. * * bit_count :: * The number of bits in the hint mask. @@ -494,13 +494,13 @@ FT_BEGIN_HEADER * * @note: * If the hintmask starts the charstring (before any glyph point - * definition), the value of `end_point' should be 0. + * definition), the value of `end_point` should be 0. * - * `bit_count' is the number of meaningful bits in the `bytes' array; it + * `bit_count` is the number of meaningful bits in the 'bytes' array; it * must be equal to the total number of hints defined so far (i.e., * horizontal+verticals). * - * The `bytes' array can come directly from the Type 2 charstring and + * The 'bytes' array can come directly from the Type 2 charstring and * respects the same format. * */ @@ -511,14 +511,14 @@ FT_BEGIN_HEADER const FT_Byte* bytes ); - /************************************************************************* + /************************************************************************** * * @functype: * T2_Hints_CounterFunc * * @description: - * A method of the @T2_Hints class used to set a given counter mask - * (this corresponds to the `hintmask' Type 2 operator). + * A method of the @T2_Hints class used to set a given counter mask (this + * corresponds to the 'hintmask' Type 2 operator). * * @input: * hints :: @@ -536,13 +536,13 @@ FT_BEGIN_HEADER * * @note: * If the hintmask starts the charstring (before any glyph point - * definition), the value of `end_point' should be 0. + * definition), the value of `end_point` should be 0. * - * `bit_count' is the number of meaningful bits in the `bytes' array; it + * `bit_count` is the number of meaningful bits in the 'bytes' array; it * must be equal to the total number of hints defined so far (i.e., * horizontal+verticals). * - * The `bytes' array can come directly from the Type 2 charstring and + * The 'bytes' array can come directly from the Type 2 charstring and * respects the same format. * */ @@ -552,7 +552,7 @@ FT_BEGIN_HEADER const FT_Byte* bytes ); - /************************************************************************* + /************************************************************************** * * @functype: * T2_Hints_CloseFunc @@ -581,15 +581,14 @@ FT_BEGIN_HEADER FT_UInt end_point ); - /************************************************************************* + /************************************************************************** * * @functype: * T2_Hints_ApplyFunc * * @description: * A method of the @T2_Hints class used to apply hints to the - * corresponding glyph outline. Must be called after the `close' - * method. + * corresponding glyph outline. Must be called after the 'close' method. * * @input: * hints :: @@ -611,7 +610,7 @@ FT_BEGIN_HEADER * On input, all points within the outline are in font coordinates. On * output, they are in 1/64th of pixels. * - * The scaling transformation is taken from the `globals' object which + * The scaling transformation is taken from the 'globals' object which * must correspond to the same font than the glyph. * */ @@ -622,7 +621,7 @@ FT_BEGIN_HEADER FT_Render_Mode hint_mode ); - /************************************************************************* + /************************************************************************** * * @struct: * T2_Hints_FuncsRec @@ -680,8 +679,6 @@ FT_BEGIN_HEADER typedef PSHinter_Interface* PSHinter_Service; -#ifndef FT_CONFIG_OPTION_PIC - #define FT_DEFINE_PSHINTER_INTERFACE( \ class_, \ get_globals_funcs_, \ @@ -694,25 +691,6 @@ FT_BEGIN_HEADER get_t2_funcs_ \ }; -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DEFINE_PSHINTER_INTERFACE( \ - class_, \ - get_globals_funcs_, \ - get_t1_funcs_, \ - get_t2_funcs_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Library library, \ - PSHinter_Interface* clazz ) \ - { \ - FT_UNUSED( library ); \ - \ - clazz->get_globals_funcs = get_globals_funcs_; \ - clazz->get_t1_funcs = get_t1_funcs_; \ - clazz->get_t2_funcs = get_t2_funcs_; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ FT_END_HEADER diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svbdf.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svbdf.h index 4a9ec2007556f..e4786ed038342 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svbdf.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svbdf.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* svbdf.h */ -/* */ -/* The FreeType BDF services (specification). */ -/* */ -/* Copyright 2003-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * svbdf.h + * + * The FreeType BDF services (specification). + * + * Copyright (C) 2003-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef SVBDF_H_ @@ -46,8 +46,6 @@ FT_BEGIN_HEADER }; -#ifndef FT_CONFIG_OPTION_PIC - #define FT_DEFINE_SERVICE_BDFRec( class_, \ get_charset_id_, \ get_property_ ) \ @@ -56,20 +54,6 @@ FT_BEGIN_HEADER get_charset_id_, get_property_ \ }; -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DEFINE_SERVICE_BDFRec( class_, \ - get_charset_id_, \ - get_property_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Service_BDFRec* clazz ) \ - { \ - clazz->get_charset_id = get_charset_id_; \ - clazz->get_property = get_property_; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - /* */ diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svcfftl.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svcfftl.h index db623e684059c..6c621732da2e2 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svcfftl.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svcfftl.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* svcfftl.h */ -/* */ -/* The FreeType CFF tables loader service (specification). */ -/* */ -/* Copyright 2017-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * svcfftl.h + * + * The FreeType CFF tables loader service (specification). + * + * Copyright (C) 2017-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef SVCFFTL_H_ @@ -65,8 +65,6 @@ FT_BEGIN_HEADER }; -#ifndef FT_CONFIG_OPTION_PIC - #define FT_DEFINE_SERVICE_CFFLOADREC( class_, \ get_standard_encoding_, \ load_private_dict_, \ @@ -82,26 +80,6 @@ FT_BEGIN_HEADER blend_build_vector_ \ }; -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DEFINE_SERVICE_CFFLOADREC( class_, \ - get_standard_encoding_, \ - load_private_dict_, \ - fd_select_get_, \ - blend_check_vector_, \ - blend_build_vector_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Service_CFFLoadRec* clazz ) \ - { \ - clazz->get_standard_encoding = get_standard_encoding_; \ - clazz->load_private_dict = load_private_dict_; \ - clazz->fd_select_get = fd_select_get_; \ - clazz->blend_check_vector = blend_check_vector_; \ - clazz->blend_build_vector = blend_build_vector_; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - FT_END_HEADER diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svcid.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svcid.h index cb59ac6a295ba..555a5af5b9b05 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svcid.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svcid.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* svcid.h */ -/* */ -/* The FreeType CID font services (specification). */ -/* */ -/* Copyright 2007-2018 by */ -/* Derek Clegg and Michael Toftdal. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * svcid.h + * + * The FreeType CID font services (specification). + * + * Copyright (C) 2007-2019 by + * Derek Clegg and Michael Toftdal. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef SVCID_H_ @@ -48,8 +48,6 @@ FT_BEGIN_HEADER }; -#ifndef FT_CONFIG_OPTION_PIC - #define FT_DEFINE_SERVICE_CIDREC( class_, \ get_ros_, \ get_is_cid_, \ @@ -59,25 +57,6 @@ FT_BEGIN_HEADER get_ros_, get_is_cid_, get_cid_from_glyph_index_ \ }; -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DEFINE_SERVICE_CIDREC( class_, \ - get_ros_, \ - get_is_cid_, \ - get_cid_from_glyph_index_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Library library, \ - FT_Service_CIDRec* clazz ) \ - { \ - FT_UNUSED( library ); \ - \ - clazz->get_ros = get_ros_; \ - clazz->get_is_cid = get_is_cid_; \ - clazz->get_cid_from_glyph_index = get_cid_from_glyph_index_; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - /* */ diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svfntfmt.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svfntfmt.h index 3b732be1a170a..6f4285ea8c326 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svfntfmt.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svfntfmt.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* svfntfmt.h */ -/* */ -/* The FreeType font format service (specification only). */ -/* */ -/* Copyright 2003-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * svfntfmt.h + * + * The FreeType font format service (specification only). + * + * Copyright (C) 2003-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef SVFNTFMT_H_ @@ -26,9 +26,9 @@ FT_BEGIN_HEADER /* - * A trivial service used to return the name of a face's font driver, - * according to the XFree86 nomenclature. Note that the service data - * is a simple constant string pointer. + * A trivial service used to return the name of a face's font driver, + * according to the XFree86 nomenclature. Note that the service data is a + * simple constant string pointer. */ #define FT_SERVICE_ID_FONT_FORMAT "font-format" diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svgldict.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svgldict.h index f1a68e31107d9..ca8edf0eb5535 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svgldict.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svgldict.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* svgldict.h */ -/* */ -/* The FreeType glyph dictionary services (specification). */ -/* */ -/* Copyright 2003-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * svgldict.h + * + * The FreeType glyph dictionary services (specification). + * + * Copyright (C) 2003-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef SVGLDICT_H_ @@ -26,8 +26,8 @@ FT_BEGIN_HEADER /* - * A service used to retrieve glyph names, as well as to find the - * index of a given glyph name in a font. + * A service used to retrieve glyph names, as well as to find the index of + * a given glyph name in a font. * */ @@ -52,8 +52,6 @@ FT_BEGIN_HEADER }; -#ifndef FT_CONFIG_OPTION_PIC - #define FT_DEFINE_SERVICE_GLYPHDICTREC( class_, \ get_name_, \ name_index_ ) \ @@ -62,23 +60,6 @@ FT_BEGIN_HEADER get_name_, name_index_ \ }; -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DEFINE_SERVICE_GLYPHDICTREC( class_, \ - get_name_, \ - name_index_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Library library, \ - FT_Service_GlyphDictRec* clazz ) \ - { \ - FT_UNUSED( library ); \ - \ - clazz->get_name = get_name_; \ - clazz->name_index = name_index_; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - /* */ diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svgxval.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svgxval.h index ed79ebeaa8e8f..0bb76f3144176 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svgxval.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svgxval.h @@ -1,28 +1,28 @@ -/***************************************************************************/ -/* */ -/* svgxval.h */ -/* */ -/* FreeType API for validating TrueTypeGX/AAT tables (specification). */ -/* */ -/* Copyright 2004-2018 by */ -/* Masatake YAMATO, Red Hat K.K., */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * svgxval.h + * + * FreeType API for validating TrueTypeGX/AAT tables (specification). + * + * Copyright (C) 2004-2019 by + * Masatake YAMATO, Red Hat K.K., + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + +/**************************************************************************** + * + * gxvalid is derived from both gxlayout module and otvalid module. + * Development of gxlayout is supported by the Information-technology + * Promotion Agency(IPA), Japan. + * + */ #ifndef SVGXVAL_H_ diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svkern.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svkern.h index c7e8f6ef275eb..f992a327c1a1a 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svkern.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svkern.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* svkern.h */ -/* */ -/* The FreeType Kerning service (specification). */ -/* */ -/* Copyright 2006-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * svkern.h + * + * The FreeType Kerning service (specification). + * + * Copyright (C) 2006-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef SVKERN_H_ diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svmetric.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svmetric.h index abaacddbbe778..d688bc7c601bf 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svmetric.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svmetric.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* svmetric.h */ -/* */ -/* The FreeType services for metrics variations (specification). */ -/* */ -/* Copyright 2016-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * svmetric.h + * + * The FreeType services for metrics variations (specification). + * + * Copyright (C) 2016-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef SVMETRIC_H_ @@ -26,7 +26,7 @@ FT_BEGIN_HEADER /* - * A service to manage the `HVAR, `MVAR', and `VVAR' OpenType tables. + * A service to manage the `HVAR, `MVAR', and `VVAR' OpenType tables. * */ @@ -93,8 +93,6 @@ FT_BEGIN_HEADER }; -#ifndef FT_CONFIG_OPTION_PIC - #define FT_DEFINE_SERVICE_METRICSVARIATIONSREC( class_, \ hadvance_adjust_, \ lsb_adjust_, \ @@ -116,32 +114,6 @@ FT_BEGIN_HEADER metrics_adjust_ \ }; -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DEFINE_SERVICE_METRICSVARIATIONSREC( class_, \ - hadvance_adjust_, \ - lsb_adjust_, \ - rsb_adjust_, \ - vadvance_adjust_, \ - tsb_adjust_, \ - bsb_adjust_, \ - vorg_adjust_, \ - metrics_adjust_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Service_MetricsVariationsRec* clazz ) \ - { \ - clazz->hadvance_adjust = hadvance_adjust_; \ - clazz->lsb_adjust = lsb_adjust_; \ - clazz->rsb_adjust = rsb_adjust_; \ - clazz->vadvance_adjust = vadvance_adjust_; \ - clazz->tsb_adjust = tsb_adjust_; \ - clazz->bsb_adjust = bsb_adjust_; \ - clazz->vorg_adjust = vorg_adjust_; \ - clazz->metrics_adjust = metrics_adjust_; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - /* */ diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svmm.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svmm.h index bcbb38e2ce201..3652f2050a05f 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svmm.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svmm.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* svmm.h */ -/* */ -/* The FreeType Multiple Masters and GX var services (specification). */ -/* */ -/* Copyright 2003-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * svmm.h + * + * The FreeType Multiple Masters and GX var services (specification). + * + * Copyright (C) 2003-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef SVMM_H_ @@ -26,9 +26,9 @@ FT_BEGIN_HEADER /* - * A service used to manage multiple-masters data in a given face. + * A service used to manage multiple-masters data in a given face. * - * See the related APIs in `ftmm.h' (FT_MULTIPLE_MASTERS_H). + * See the related APIs in `ftmm.h' (FT_MULTIPLE_MASTERS_H). * */ @@ -86,81 +86,65 @@ FT_BEGIN_HEADER typedef void (*FT_Done_Blend_Func)( FT_Face ); + typedef FT_Error + (*FT_Set_MM_WeightVector_Func)( FT_Face face, + FT_UInt len, + FT_Fixed* weight_vector ); + + typedef FT_Error + (*FT_Get_MM_WeightVector_Func)( FT_Face face, + FT_UInt* len, + FT_Fixed* weight_vector ); + FT_DEFINE_SERVICE( MultiMasters ) { - FT_Get_MM_Func get_mm; - FT_Set_MM_Design_Func set_mm_design; - FT_Set_MM_Blend_Func set_mm_blend; - FT_Get_MM_Blend_Func get_mm_blend; - FT_Get_MM_Var_Func get_mm_var; - FT_Set_Var_Design_Func set_var_design; - FT_Get_Var_Design_Func get_var_design; - FT_Set_Instance_Func set_instance; + FT_Get_MM_Func get_mm; + FT_Set_MM_Design_Func set_mm_design; + FT_Set_MM_Blend_Func set_mm_blend; + FT_Get_MM_Blend_Func get_mm_blend; + FT_Get_MM_Var_Func get_mm_var; + FT_Set_Var_Design_Func set_var_design; + FT_Get_Var_Design_Func get_var_design; + FT_Set_Instance_Func set_instance; + FT_Set_MM_WeightVector_Func set_mm_weightvector; + FT_Get_MM_WeightVector_Func get_mm_weightvector; /* for internal use; only needed for code sharing between modules */ - FT_Get_Var_Blend_Func get_var_blend; - FT_Done_Blend_Func done_blend; + FT_Get_Var_Blend_Func get_var_blend; + FT_Done_Blend_Func done_blend; }; -#ifndef FT_CONFIG_OPTION_PIC - -#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_, \ - get_mm_, \ - set_mm_design_, \ - set_mm_blend_, \ - get_mm_blend_, \ - get_mm_var_, \ - set_var_design_, \ - get_var_design_, \ - set_instance_, \ - get_var_blend_, \ - done_blend_ ) \ - static const FT_Service_MultiMastersRec class_ = \ - { \ - get_mm_, \ - set_mm_design_, \ - set_mm_blend_, \ - get_mm_blend_, \ - get_mm_var_, \ - set_var_design_, \ - get_var_design_, \ - set_instance_, \ - get_var_blend_, \ - done_blend_ \ +#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_, \ + get_mm_, \ + set_mm_design_, \ + set_mm_blend_, \ + get_mm_blend_, \ + get_mm_var_, \ + set_var_design_, \ + get_var_design_, \ + set_instance_, \ + set_weightvector_, \ + get_weightvector_, \ + get_var_blend_, \ + done_blend_ ) \ + static const FT_Service_MultiMastersRec class_ = \ + { \ + get_mm_, \ + set_mm_design_, \ + set_mm_blend_, \ + get_mm_blend_, \ + get_mm_var_, \ + set_var_design_, \ + get_var_design_, \ + set_instance_, \ + set_weightvector_, \ + get_weightvector_, \ + get_var_blend_, \ + done_blend_ \ }; -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_, \ - get_mm_, \ - set_mm_design_, \ - set_mm_blend_, \ - get_mm_blend_, \ - get_mm_var_, \ - set_var_design_, \ - get_var_design_, \ - set_instance_, \ - get_var_blend_, \ - done_blend_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Service_MultiMastersRec* clazz ) \ - { \ - clazz->get_mm = get_mm_; \ - clazz->set_mm_design = set_mm_design_; \ - clazz->set_mm_blend = set_mm_blend_; \ - clazz->get_mm_blend = get_mm_blend_; \ - clazz->get_mm_var = get_mm_var_; \ - clazz->set_var_design = set_var_design_; \ - clazz->get_var_design = get_var_design_; \ - clazz->set_instance = set_instance_; \ - clazz->get_var_blend = get_var_blend_; \ - clazz->done_blend = done_blend_; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - /* */ diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svotval.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svotval.h index 31294296a6d97..cab4c6efbb1ab 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svotval.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svotval.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* svotval.h */ -/* */ -/* The FreeType OpenType validation service (specification). */ -/* */ -/* Copyright 2004-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * svotval.h + * + * The FreeType OpenType validation service (specification). + * + * Copyright (C) 2004-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef SVOTVAL_H_ diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svpfr.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svpfr.h index e65d57e91baa3..fd01d614ddda7 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svpfr.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svpfr.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* svpfr.h */ -/* */ -/* Internal PFR service functions (specification). */ -/* */ -/* Copyright 2003-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * svpfr.h + * + * Internal PFR service functions (specification). + * + * Copyright (C) 2003-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef SVPFR_H_ diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svpostnm.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svpostnm.h index 4a49d8b053285..18e3843cbe7a1 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svpostnm.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svpostnm.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* svpostnm.h */ -/* */ -/* The FreeType PostScript name services (specification). */ -/* */ -/* Copyright 2003-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * svpostnm.h + * + * The FreeType PostScript name services (specification). + * + * Copyright (C) 2003-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef SVPOSTNM_H_ @@ -25,13 +25,13 @@ FT_BEGIN_HEADER /* - * A trivial service used to retrieve the PostScript name of a given - * font when available. The `get_name' field should never be NULL. + * A trivial service used to retrieve the PostScript name of a given font + * when available. The `get_name' field should never be `NULL`. * - * The corresponding function can return NULL to indicate that the - * PostScript name is not available. + * The corresponding function can return `NULL` to indicate that the + * PostScript name is not available. * - * The name is owned by the face and will be destroyed with it. + * The name is owned by the face and will be destroyed with it. */ #define FT_SERVICE_ID_POSTSCRIPT_FONT_NAME "postscript-font-name" @@ -47,28 +47,12 @@ FT_BEGIN_HEADER }; -#ifndef FT_CONFIG_OPTION_PIC - #define FT_DEFINE_SERVICE_PSFONTNAMEREC( class_, get_ps_font_name_ ) \ static const FT_Service_PsFontNameRec class_ = \ { \ get_ps_font_name_ \ }; -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DEFINE_SERVICE_PSFONTNAMEREC( class_, get_ps_font_name_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Library library, \ - FT_Service_PsFontNameRec* clazz ) \ - { \ - FT_UNUSED( library ); \ - \ - clazz->get_ps_font_name = get_ps_font_name_; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - /* */ diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svprop.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svprop.h index adc0bcf4398f0..e48d0151ec053 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svprop.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svprop.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* svprop.h */ -/* */ -/* The FreeType property service (specification). */ -/* */ -/* Copyright 2012-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * svprop.h + * + * The FreeType property service (specification). + * + * Copyright (C) 2012-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef SVPROP_H_ @@ -45,8 +45,6 @@ FT_BEGIN_HEADER }; -#ifndef FT_CONFIG_OPTION_PIC - #define FT_DEFINE_SERVICE_PROPERTIESREC( class_, \ set_property_, \ get_property_ ) \ @@ -56,20 +54,6 @@ FT_BEGIN_HEADER get_property_ \ }; -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DEFINE_SERVICE_PROPERTIESREC( class_, \ - set_property_, \ - get_property_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Service_PropertiesRec* clazz ) \ - { \ - clazz->set_property = set_property_; \ - clazz->get_property = get_property_; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - /* */ diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svpscmap.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svpscmap.h index 5589575b92a5a..dfac3bafa98e6 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svpscmap.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svpscmap.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* svpscmap.h */ -/* */ -/* The FreeType PostScript charmap service (specification). */ -/* */ -/* Copyright 2003-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * svpscmap.h + * + * The FreeType PostScript charmap service (specification). + * + * Copyright (C) 2003-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef SVPSCMAP_H_ @@ -29,27 +29,26 @@ FT_BEGIN_HEADER /* - * Adobe glyph name to unicode value. + * Adobe glyph name to unicode value. */ typedef FT_UInt32 (*PS_Unicode_ValueFunc)( const char* glyph_name ); /* - * Macintosh name id to glyph name. NULL if invalid index. + * Macintosh name id to glyph name. `NULL` if invalid index. */ typedef const char* (*PS_Macintosh_NameFunc)( FT_UInt name_index ); /* - * Adobe standard string ID to glyph name. NULL if invalid index. + * Adobe standard string ID to glyph name. `NULL` if invalid index. */ typedef const char* (*PS_Adobe_Std_StringsFunc)( FT_UInt string_index ); /* - * Simple unicode -> glyph index charmap built from font glyph names - * table. + * Simple unicode -> glyph index charmap built from font glyph names table. */ typedef struct PS_UniMap_ { @@ -71,16 +70,16 @@ FT_BEGIN_HEADER /* - * A function which returns a glyph name for a given index. Returns - * NULL if invalid index. + * A function which returns a glyph name for a given index. Returns + * `NULL` if invalid index. */ typedef const char* (*PS_GetGlyphNameFunc)( FT_Pointer data, FT_UInt string_index ); /* - * A function used to release the glyph name returned by - * PS_GetGlyphNameFunc, when needed + * A function used to release the glyph name returned by + * PS_GetGlyphNameFunc, when needed */ typedef void (*PS_FreeGlyphNameFunc)( FT_Pointer data, @@ -118,8 +117,6 @@ FT_BEGIN_HEADER }; -#ifndef FT_CONFIG_OPTION_PIC - #define FT_DEFINE_SERVICE_PSCMAPSREC( class_, \ unicode_value_, \ unicodes_init_, \ @@ -136,35 +133,6 @@ FT_BEGIN_HEADER adobe_std_strings_, adobe_std_encoding_, adobe_expert_encoding_ \ }; -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DEFINE_SERVICE_PSCMAPSREC( class_, \ - unicode_value_, \ - unicodes_init_, \ - unicodes_char_index_, \ - unicodes_char_next_, \ - macintosh_name_, \ - adobe_std_strings_, \ - adobe_std_encoding_, \ - adobe_expert_encoding_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Library library, \ - FT_Service_PsCMapsRec* clazz ) \ - { \ - FT_UNUSED( library ); \ - \ - clazz->unicode_value = unicode_value_; \ - clazz->unicodes_init = unicodes_init_; \ - clazz->unicodes_char_index = unicodes_char_index_; \ - clazz->unicodes_char_next = unicodes_char_next_; \ - clazz->macintosh_name = macintosh_name_; \ - clazz->adobe_std_strings = adobe_std_strings_; \ - clazz->adobe_std_encoding = adobe_std_encoding_; \ - clazz->adobe_expert_encoding = adobe_expert_encoding_; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - /* */ diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svpsinfo.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svpsinfo.h index 408f406dfa291..fb4e0e3fa9fd6 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svpsinfo.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svpsinfo.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* svpsinfo.h */ -/* */ -/* The FreeType PostScript info service (specification). */ -/* */ -/* Copyright 2003-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * svpsinfo.h + * + * The FreeType PostScript info service (specification). + * + * Copyright (C) 2003-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef SVPSINFO_H_ @@ -62,8 +62,6 @@ FT_BEGIN_HEADER }; -#ifndef FT_CONFIG_OPTION_PIC - #define FT_DEFINE_SERVICE_PSINFOREC( class_, \ get_font_info_, \ ps_get_font_extra_, \ @@ -76,29 +74,6 @@ FT_BEGIN_HEADER get_font_private_, get_font_value_ \ }; -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DEFINE_SERVICE_PSINFOREC( class_, \ - get_font_info_, \ - ps_get_font_extra_, \ - has_glyph_names_, \ - get_font_private_, \ - get_font_value_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Library library, \ - FT_Service_PsInfoRec* clazz ) \ - { \ - FT_UNUSED( library ); \ - \ - clazz->ps_get_font_info = get_font_info_; \ - clazz->ps_get_font_extra = ps_get_font_extra_; \ - clazz->ps_has_glyph_names = has_glyph_names_; \ - clazz->ps_get_font_private = get_font_private_; \ - clazz->ps_get_font_value = get_font_value_; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - /* */ diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svsfnt.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svsfnt.h index e8b37bc47f8ad..464aa209f7f63 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svsfnt.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svsfnt.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* svsfnt.h */ -/* */ -/* The FreeType SFNT table loading service (specification). */ -/* */ -/* Copyright 2003-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * svsfnt.h + * + * The FreeType SFNT table loading service (specification). + * + * Copyright (C) 2003-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef SVSFNT_H_ @@ -27,7 +27,7 @@ FT_BEGIN_HEADER /* - * SFNT table loading service. + * SFNT table loading service. */ #define FT_SERVICE_ID_SFNT_TABLE "sfnt-table" @@ -70,27 +70,12 @@ FT_BEGIN_HEADER }; -#ifndef FT_CONFIG_OPTION_PIC - #define FT_DEFINE_SERVICE_SFNT_TABLEREC( class_, load_, get_, info_ ) \ static const FT_Service_SFNT_TableRec class_ = \ { \ load_, get_, info_ \ }; -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DEFINE_SERVICE_SFNT_TABLEREC( class_, load_, get_, info_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Service_SFNT_TableRec* clazz ) \ - { \ - clazz->load_table = load_; \ - clazz->get_table = get_; \ - clazz->table_info = info_; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - /* */ diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svttcmap.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svttcmap.h index cd0e6fda6f9e4..0fcb81371d6e0 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svttcmap.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svttcmap.h @@ -1,20 +1,20 @@ -/***************************************************************************/ -/* */ -/* svttcmap.h */ -/* */ -/* The FreeType TrueType/sfnt cmap extra information service. */ -/* */ -/* Copyright 2003-2018 by */ -/* Masatake YAMATO, Redhat K.K., */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * svttcmap.h + * + * The FreeType TrueType/sfnt cmap extra information service. + * + * Copyright (C) 2003-2019 by + * Masatake YAMATO, Redhat K.K., + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ /* Development of this service is support of Information-technology Promotion Agency, Japan. */ @@ -32,29 +32,28 @@ FT_BEGIN_HEADER #define FT_SERVICE_ID_TT_CMAP "tt-cmaps" - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_CMapInfo */ - /* */ - /* <Description> */ - /* A structure used to store TrueType/sfnt specific cmap information */ - /* which is not covered by the generic @FT_CharMap structure. This */ - /* structure can be accessed with the @FT_Get_TT_CMap_Info function. */ - /* */ - /* <Fields> */ - /* language :: */ - /* The language ID used in Mac fonts. Definitions of values are in */ - /* `ttnameid.h'. */ - /* */ - /* format :: */ - /* The cmap format. OpenType 1.6 defines the formats 0 (byte */ - /* encoding table), 2~(high-byte mapping through table), 4~(segment */ - /* mapping to delta values), 6~(trimmed table mapping), 8~(mixed */ - /* 16-bit and 32-bit coverage), 10~(trimmed array), 12~(segmented */ - /* coverage), 13~(last resort font), and 14 (Unicode Variation */ - /* Sequences). */ - /* */ + /************************************************************************** + * + * @struct: + * TT_CMapInfo + * + * @description: + * A structure used to store TrueType/sfnt specific cmap information + * which is not covered by the generic @FT_CharMap structure. This + * structure can be accessed with the @FT_Get_TT_CMap_Info function. + * + * @fields: + * language :: + * The language ID used in Mac fonts. Definitions of values are in + * `ttnameid.h`. + * + * format :: + * The cmap format. OpenType 1.6 defines the formats 0 (byte encoding + * table), 2~(high-byte mapping through table), 4~(segment mapping to + * delta values), 6~(trimmed table mapping), 8~(mixed 16-bit and 32-bit + * coverage), 10~(trimmed array), 12~(segmented coverage), 13~(last + * resort font), and 14 (Unicode Variation Sequences). + */ typedef struct TT_CMapInfo_ { FT_ULong language; @@ -73,7 +72,6 @@ FT_BEGIN_HEADER TT_CMap_Info_GetFunc get_cmap_info; }; -#ifndef FT_CONFIG_OPTION_PIC #define FT_DEFINE_SERVICE_TTCMAPSREC( class_, get_cmap_info_ ) \ static const FT_Service_TTCMapsRec class_ = \ @@ -81,20 +79,6 @@ FT_BEGIN_HEADER get_cmap_info_ \ }; -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DEFINE_SERVICE_TTCMAPSREC( class_, get_cmap_info_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Library library, \ - FT_Service_TTCMapsRec* clazz ) \ - { \ - FT_UNUSED( library ); \ - \ - clazz->get_cmap_info = get_cmap_info_; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - /* */ diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svtteng.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svtteng.h index 92e3c541f539b..a852f5c6fb6e4 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svtteng.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svtteng.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* svtteng.h */ -/* */ -/* The FreeType TrueType engine query service (specification). */ -/* */ -/* Copyright 2006-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * svtteng.h + * + * The FreeType TrueType engine query service (specification). + * + * Copyright (C) 2006-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef SVTTENG_H_ @@ -27,7 +27,7 @@ FT_BEGIN_HEADER /* - * SFNT table loading service. + * SFNT table loading service. */ #define FT_SERVICE_ID_TRUETYPE_ENGINE "truetype-engine" diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svttglyf.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svttglyf.h index 16fac1ca18b98..c8798771fbbcc 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svttglyf.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svttglyf.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* svttglyf.h */ -/* */ -/* The FreeType TrueType glyph service. */ -/* */ -/* Copyright 2007-2018 by */ -/* David Turner. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * svttglyf.h + * + * The FreeType TrueType glyph service. + * + * Copyright (C) 2007-2019 by + * David Turner. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef SVTTGLYF_H_ #define SVTTGLYF_H_ @@ -39,25 +39,12 @@ FT_BEGIN_HEADER }; -#ifndef FT_CONFIG_OPTION_PIC - #define FT_DEFINE_SERVICE_TTGLYFREC( class_, get_location_ ) \ static const FT_Service_TTGlyfRec class_ = \ { \ get_location_ \ }; -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DEFINE_SERVICE_TTGLYFREC( class_, get_location_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Service_TTGlyfRec* clazz ) \ - { \ - clazz->get_location = get_location_; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - /* */ diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svwinfnt.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svwinfnt.h index 80d481cbd1162..38ee0209657fb 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svwinfnt.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svwinfnt.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* svwinfnt.h */ -/* */ -/* The FreeType Windows FNT/FONT service (specification). */ -/* */ -/* Copyright 2003-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * svwinfnt.h + * + * The FreeType Windows FNT/FONT service (specification). + * + * Copyright (C) 2003-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef SVWINFNT_H_ diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/sfnt.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/sfnt.h index fb1e327aeb0c7..225f40df6eb23 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/sfnt.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/sfnt.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* sfnt.h */ -/* */ -/* High-level `sfnt' driver interface (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * sfnt.h + * + * High-level 'sfnt' driver interface (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef SFNT_H_ @@ -28,43 +28,46 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_Init_Face_Func */ - /* */ - /* <Description> */ - /* First part of the SFNT face object initialization. This finds */ - /* the face in a SFNT file or collection, and load its format tag in */ - /* face->format_tag. */ - /* */ - /* <Input> */ - /* stream :: The input stream. */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* face_index :: The index of the TrueType font, if we are opening a */ - /* collection, in bits 0-15. The numbered instance */ - /* index~+~1 of a GX (sub)font, if applicable, in bits */ - /* 16-30. */ - /* */ - /* num_params :: The number of additional parameters. */ - /* */ - /* params :: Optional additional parameters. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - /* <Note> */ - /* The stream cursor must be at the font file's origin. */ - /* */ - /* This function recognizes fonts embedded in a `TrueType */ - /* collection'. */ - /* */ - /* Once the format tag has been validated by the font driver, it */ - /* should then call the TT_Load_Face_Func() callback to read the rest */ - /* of the SFNT tables in the object. */ - /* */ + /************************************************************************** + * + * @functype: + * TT_Init_Face_Func + * + * @description: + * First part of the SFNT face object initialization. This finds the + * face in a SFNT file or collection, and load its format tag in + * face->format_tag. + * + * @input: + * stream :: + * The input stream. + * + * face :: + * A handle to the target face object. + * + * face_index :: + * The index of the TrueType font, if we are opening a collection, in + * bits 0-15. The numbered instance index~+~1 of a GX (sub)font, if + * applicable, in bits 16-30. + * + * num_params :: + * The number of additional parameters. + * + * params :: + * Optional additional parameters. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * The stream cursor must be at the font file's origin. + * + * This function recognizes fonts embedded in a 'TrueType collection'. + * + * Once the format tag has been validated by the font driver, it should + * then call the TT_Load_Face_Func() callback to read the rest of the + * SFNT tables in the object. + */ typedef FT_Error (*TT_Init_Face_Func)( FT_Stream stream, TT_Face face, @@ -73,36 +76,40 @@ FT_BEGIN_HEADER FT_Parameter* params ); - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_Load_Face_Func */ - /* */ - /* <Description> */ - /* Second part of the SFNT face object initialization. This loads */ - /* the common SFNT tables (head, OS/2, maxp, metrics, etc.) in the */ - /* face object. */ - /* */ - /* <Input> */ - /* stream :: The input stream. */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* face_index :: The index of the TrueType font, if we are opening a */ - /* collection, in bits 0-15. The numbered instance */ - /* index~+~1 of a GX (sub)font, if applicable, in bits */ - /* 16-30. */ - /* */ - /* num_params :: The number of additional parameters. */ - /* */ - /* params :: Optional additional parameters. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - /* <Note> */ - /* This function must be called after TT_Init_Face_Func(). */ - /* */ + /************************************************************************** + * + * @functype: + * TT_Load_Face_Func + * + * @description: + * Second part of the SFNT face object initialization. This loads the + * common SFNT tables (head, OS/2, maxp, metrics, etc.) in the face + * object. + * + * @input: + * stream :: + * The input stream. + * + * face :: + * A handle to the target face object. + * + * face_index :: + * The index of the TrueType font, if we are opening a collection, in + * bits 0-15. The numbered instance index~+~1 of a GX (sub)font, if + * applicable, in bits 16-30. + * + * num_params :: + * The number of additional parameters. + * + * params :: + * Optional additional parameters. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * This function must be called after TT_Init_Face_Func(). + */ typedef FT_Error (*TT_Load_Face_Func)( FT_Stream stream, TT_Face face, @@ -111,64 +118,64 @@ FT_BEGIN_HEADER FT_Parameter* params ); - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_Done_Face_Func */ - /* */ - /* <Description> */ - /* A callback used to delete the common SFNT data from a face. */ - /* */ - /* <Input> */ - /* face :: A handle to the target face object. */ - /* */ - /* <Note> */ - /* This function does NOT destroy the face object. */ - /* */ + /************************************************************************** + * + * @functype: + * TT_Done_Face_Func + * + * @description: + * A callback used to delete the common SFNT data from a face. + * + * @input: + * face :: + * A handle to the target face object. + * + * @note: + * This function does NOT destroy the face object. + */ typedef void (*TT_Done_Face_Func)( TT_Face face ); - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_Load_Any_Func */ - /* */ - /* <Description> */ - /* Load any font table into client memory. */ - /* */ - /* <Input> */ - /* face :: The face object to look for. */ - /* */ - /* tag :: The tag of table to load. Use the value 0 if you want */ - /* to access the whole font file, else set this parameter */ - /* to a valid TrueType table tag that you can forge with */ - /* the MAKE_TT_TAG macro. */ - /* */ - /* offset :: The starting offset in the table (or the file if */ - /* tag == 0). */ - /* */ - /* length :: The address of the decision variable: */ - /* */ - /* If length == NULL: */ - /* Loads the whole table. Returns an error if */ - /* `offset' == 0! */ - /* */ - /* If *length == 0: */ - /* Exits immediately; returning the length of the given */ - /* table or of the font file, depending on the value of */ - /* `tag'. */ - /* */ - /* If *length != 0: */ - /* Loads the next `length' bytes of table or font, */ - /* starting at offset `offset' (in table or font too). */ - /* */ - /* <Output> */ - /* buffer :: The address of target buffer. */ - /* */ - /* <Return> */ - /* TrueType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @functype: + * TT_Load_Any_Func + * + * @description: + * Load any font table into client memory. + * + * @input: + * face :: + * The face object to look for. + * + * tag :: + * The tag of table to load. Use the value 0 if you want to access the + * whole font file, else set this parameter to a valid TrueType table + * tag that you can forge with the MAKE_TT_TAG macro. + * + * offset :: + * The starting offset in the table (or the file if tag == 0). + * + * length :: + * The address of the decision variable: + * + * If `length == NULL`: Loads the whole table. Returns an error if + * 'offset' == 0! + * + * If `*length == 0`: Exits immediately; returning the length of the + * given table or of the font file, depending on the value of 'tag'. + * + * If `*length != 0`: Loads the next 'length' bytes of table or font, + * starting at offset 'offset' (in table or font too). + * + * @output: + * buffer :: + * The address of target buffer. + * + * @return: + * TrueType error code. 0 means success. + */ typedef FT_Error (*TT_Load_Any_Func)( TT_Face face, FT_ULong tag, @@ -177,34 +184,39 @@ FT_BEGIN_HEADER FT_ULong* length ); - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_Find_SBit_Image_Func */ - /* */ - /* <Description> */ - /* Check whether an embedded bitmap (an `sbit') exists for a given */ - /* glyph, at a given strike. */ - /* */ - /* <Input> */ - /* face :: The target face object. */ - /* */ - /* glyph_index :: The glyph index. */ - /* */ - /* strike_index :: The current strike index. */ - /* */ - /* <Output> */ - /* arange :: The SBit range containing the glyph index. */ - /* */ - /* astrike :: The SBit strike containing the glyph index. */ - /* */ - /* aglyph_offset :: The offset of the glyph data in `EBDT' table. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. Returns */ - /* SFNT_Err_Invalid_Argument if no sbit exists for the requested */ - /* glyph. */ - /* */ + /************************************************************************** + * + * @functype: + * TT_Find_SBit_Image_Func + * + * @description: + * Check whether an embedded bitmap (an 'sbit') exists for a given glyph, + * at a given strike. + * + * @input: + * face :: + * The target face object. + * + * glyph_index :: + * The glyph index. + * + * strike_index :: + * The current strike index. + * + * @output: + * arange :: + * The SBit range containing the glyph index. + * + * astrike :: + * The SBit strike containing the glyph index. + * + * aglyph_offset :: + * The offset of the glyph data in 'EBDT' table. + * + * @return: + * FreeType error code. 0 means success. Returns + * SFNT_Err_Invalid_Argument if no sbit exists for the requested glyph. + */ typedef FT_Error (*TT_Find_SBit_Image_Func)( TT_Face face, FT_UInt glyph_index, @@ -214,78 +226,81 @@ FT_BEGIN_HEADER FT_ULong *aglyph_offset ); - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_Load_SBit_Metrics_Func */ - /* */ - /* <Description> */ - /* Get the big metrics for a given embedded bitmap. */ - /* */ - /* <Input> */ - /* stream :: The input stream. */ - /* */ - /* range :: The SBit range containing the glyph. */ - /* */ - /* <Output> */ - /* big_metrics :: A big SBit metrics structure for the glyph. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - /* <Note> */ - /* The stream cursor must be positioned at the glyph's offset within */ - /* the `EBDT' table before the call. */ - /* */ - /* If the image format uses variable metrics, the stream cursor is */ - /* positioned just after the metrics header in the `EBDT' table on */ - /* function exit. */ - /* */ + /************************************************************************** + * + * @functype: + * TT_Load_SBit_Metrics_Func + * + * @description: + * Get the big metrics for a given embedded bitmap. + * + * @input: + * stream :: + * The input stream. + * + * range :: + * The SBit range containing the glyph. + * + * @output: + * big_metrics :: + * A big SBit metrics structure for the glyph. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * The stream cursor must be positioned at the glyph's offset within the + * 'EBDT' table before the call. + * + * If the image format uses variable metrics, the stream cursor is + * positioned just after the metrics header in the 'EBDT' table on + * function exit. + */ typedef FT_Error (*TT_Load_SBit_Metrics_Func)( FT_Stream stream, TT_SBit_Range range, TT_SBit_Metrics metrics ); - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_Load_SBit_Image_Func */ - /* */ - /* <Description> */ - /* Load a given glyph sbit image from the font resource. This also */ - /* returns its metrics. */ - /* */ - /* <Input> */ - /* face :: */ - /* The target face object. */ - /* */ - /* strike_index :: */ - /* The strike index. */ - /* */ - /* glyph_index :: */ - /* The current glyph index. */ - /* */ - /* load_flags :: */ - /* The current load flags. */ - /* */ - /* stream :: */ - /* The input stream. */ - /* */ - /* <Output> */ - /* amap :: */ - /* The target pixmap. */ - /* */ - /* ametrics :: */ - /* A big sbit metrics structure for the glyph image. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. Returns an error if no */ - /* glyph sbit exists for the index. */ - /* */ - /* <Note> */ - /* The `map.buffer' field is always freed before the glyph is loaded. */ - /* */ + /************************************************************************** + * + * @functype: + * TT_Load_SBit_Image_Func + * + * @description: + * Load a given glyph sbit image from the font resource. This also + * returns its metrics. + * + * @input: + * face :: + * The target face object. + * + * strike_index :: + * The strike index. + * + * glyph_index :: + * The current glyph index. + * + * load_flags :: + * The current load flags. + * + * stream :: + * The input stream. + * + * @output: + * amap :: + * The target pixmap. + * + * ametrics :: + * A big sbit metrics structure for the glyph image. + * + * @return: + * FreeType error code. 0 means success. Returns an error if no glyph + * sbit exists for the index. + * + * @note: + * The `map.buffer` field is always freed before the glyph is loaded. + */ typedef FT_Error (*TT_Load_SBit_Image_Func)( TT_Face face, FT_ULong strike_index, @@ -296,130 +311,144 @@ FT_BEGIN_HEADER TT_SBit_MetricsRec *ametrics ); - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_Set_SBit_Strike_Func */ - /* */ - /* <Description> */ - /* Select an sbit strike for a given size request. */ - /* */ - /* <Input> */ - /* face :: The target face object. */ - /* */ - /* req :: The size request. */ - /* */ - /* <Output> */ - /* astrike_index :: The index of the sbit strike. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. Returns an error if no */ - /* sbit strike exists for the selected ppem values. */ - /* */ + /************************************************************************** + * + * @functype: + * TT_Set_SBit_Strike_Func + * + * @description: + * Select an sbit strike for a given size request. + * + * @input: + * face :: + * The target face object. + * + * req :: + * The size request. + * + * @output: + * astrike_index :: + * The index of the sbit strike. + * + * @return: + * FreeType error code. 0 means success. Returns an error if no sbit + * strike exists for the selected ppem values. + */ typedef FT_Error (*TT_Set_SBit_Strike_Func)( TT_Face face, FT_Size_Request req, FT_ULong* astrike_index ); - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_Load_Strike_Metrics_Func */ - /* */ - /* <Description> */ - /* Load the metrics of a given strike. */ - /* */ - /* <Input> */ - /* face :: The target face object. */ - /* */ - /* strike_index :: The strike index. */ - /* */ - /* <Output> */ - /* metrics :: the metrics of the strike. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. Returns an error if no */ - /* such sbit strike exists. */ - /* */ + /************************************************************************** + * + * @functype: + * TT_Load_Strike_Metrics_Func + * + * @description: + * Load the metrics of a given strike. + * + * @input: + * face :: + * The target face object. + * + * strike_index :: + * The strike index. + * + * @output: + * metrics :: + * the metrics of the strike. + * + * @return: + * FreeType error code. 0 means success. Returns an error if no such + * sbit strike exists. + */ typedef FT_Error (*TT_Load_Strike_Metrics_Func)( TT_Face face, FT_ULong strike_index, FT_Size_Metrics* metrics ); - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_Get_PS_Name_Func */ - /* */ - /* <Description> */ - /* Get the PostScript glyph name of a glyph. */ - /* */ - /* <Input> */ - /* idx :: The glyph index. */ - /* */ - /* PSname :: The address of a string pointer. Will be NULL in case */ - /* of error, otherwise it is a pointer to the glyph name. */ - /* */ - /* You must not modify the returned string! */ - /* */ - /* <Output> */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @functype: + * TT_Get_PS_Name_Func + * + * @description: + * Get the PostScript glyph name of a glyph. + * + * @input: + * idx :: + * The glyph index. + * + * PSname :: + * The address of a string pointer. Will be `NULL` in case of error, + * otherwise it is a pointer to the glyph name. + * + * You must not modify the returned string! + * + * @output: + * FreeType error code. 0 means success. + */ typedef FT_Error (*TT_Get_PS_Name_Func)( TT_Face face, FT_UInt idx, FT_String** PSname ); - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_Load_Metrics_Func */ - /* */ - /* <Description> */ - /* Load a metrics table, which is a table with a horizontal and a */ - /* vertical version. */ - /* */ - /* <Input> */ - /* face :: A handle to the target face object. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* vertical :: A boolean flag. If set, load the vertical one. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @functype: + * TT_Load_Metrics_Func + * + * @description: + * Load a metrics table, which is a table with a horizontal and a + * vertical version. + * + * @input: + * face :: + * A handle to the target face object. + * + * stream :: + * The input stream. + * + * vertical :: + * A boolean flag. If set, load the vertical one. + * + * @return: + * FreeType error code. 0 means success. + */ typedef FT_Error (*TT_Load_Metrics_Func)( TT_Face face, FT_Stream stream, FT_Bool vertical ); - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_Get_Metrics_Func */ - /* */ - /* <Description> */ - /* Load the horizontal or vertical header in a face object. */ - /* */ - /* <Input> */ - /* face :: A handle to the target face object. */ - /* */ - /* vertical :: A boolean flag. If set, load vertical metrics. */ - /* */ - /* gindex :: The glyph index. */ - /* */ - /* <Output> */ - /* abearing :: The horizontal (or vertical) bearing. Set to zero in */ - /* case of error. */ - /* */ - /* aadvance :: The horizontal (or vertical) advance. Set to zero in */ - /* case of error. */ - /* */ + /************************************************************************** + * + * @functype: + * TT_Get_Metrics_Func + * + * @description: + * Load the horizontal or vertical header in a face object. + * + * @input: + * face :: + * A handle to the target face object. + * + * vertical :: + * A boolean flag. If set, load vertical metrics. + * + * gindex :: + * The glyph index. + * + * @output: + * abearing :: + * The horizontal (or vertical) bearing. Set to zero in case of error. + * + * aadvance :: + * The horizontal (or vertical) advance. Set to zero in case of error. + */ typedef void (*TT_Get_Metrics_Func)( TT_Face face, FT_Bool vertical, @@ -428,57 +457,168 @@ FT_BEGIN_HEADER FT_UShort* aadvance ); - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_Get_Name_Func */ - /* */ - /* <Description> */ - /* From the `name' table, return a given ENGLISH name record in */ - /* ASCII. */ - /* */ - /* <Input> */ - /* face :: A handle to the source face object. */ - /* */ - /* nameid :: The name id of the name record to return. */ - /* */ - /* <InOut> */ - /* name :: The address of an allocated string pointer. NULL if */ - /* no name is present. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @functype: + * TT_Set_Palette_Func + * + * @description: + * Load the colors into `face->palette` for a given palette index. + * + * @input: + * face :: + * The target face object. + * + * idx :: + * The palette index. + * + * @return: + * FreeType error code. 0 means success. + */ + typedef FT_Error + (*TT_Set_Palette_Func)( TT_Face face, + FT_UInt idx ); + + + /************************************************************************** + * + * @functype: + * TT_Get_Colr_Layer_Func + * + * @description: + * Iteratively get the color layer data of a given glyph index. + * + * @input: + * face :: + * The target face object. + * + * base_glyph :: + * The glyph index the colored glyph layers are associated with. + * + * @inout: + * iterator :: + * An @FT_LayerIterator object. For the first call you should set + * `iterator->p` to `NULL`. For all following calls, simply use the + * same object again. + * + * @output: + * aglyph_index :: + * The glyph index of the current layer. + * + * acolor_index :: + * The color index into the font face's color palette of the current + * layer. The value 0xFFFF is special; it doesn't reference a palette + * entry but indicates that the text foreground color should be used + * instead (to be set up by the application outside of FreeType). + * + * @return: + * Value~1 if everything is OK. If there are no more layers (or if there + * are no layers at all), value~0 gets returned. In case of an error, + * value~0 is returned also. + */ + typedef FT_Bool + (*TT_Get_Colr_Layer_Func)( TT_Face face, + FT_UInt base_glyph, + FT_UInt *aglyph_index, + FT_UInt *acolor_index, + FT_LayerIterator* iterator ); + + + /************************************************************************** + * + * @functype: + * TT_Blend_Colr_Func + * + * @description: + * Blend the bitmap in `new_glyph` into `base_glyph` using the color + * specified by `color_index`. If `color_index` is 0xFFFF, use + * `face->foreground_color` if `face->have_foreground_color` is set. + * Otherwise check `face->palette_data.palette_flags`: If present and + * @FT_PALETTE_FOR_DARK_BACKGROUND is set, use BGRA value 0xFFFFFFFF + * (white opaque). Otherwise use BGRA value 0x000000FF (black opaque). + * + * @input: + * face :: + * The target face object. + * + * color_index :: + * Color index from the COLR table. + * + * base_glyph :: + * Slot for bitmap to be merged into. The underlying bitmap may get + * reallocated. + * + * new_glyph :: + * Slot to be incooperated into `base_glyph`. + * + * @return: + * FreeType error code. 0 means success. Returns an error if + * color_index is invalid or reallocation fails. + */ + typedef FT_Error + (*TT_Blend_Colr_Func)( TT_Face face, + FT_UInt color_index, + FT_GlyphSlot base_glyph, + FT_GlyphSlot new_glyph ); + + + /************************************************************************** + * + * @functype: + * TT_Get_Name_Func + * + * @description: + * From the 'name' table, return a given ENGLISH name record in ASCII. + * + * @input: + * face :: + * A handle to the source face object. + * + * nameid :: + * The name id of the name record to return. + * + * @inout: + * name :: + * The address of an allocated string pointer. `NULL` if no name is + * present. + * + * @return: + * FreeType error code. 0 means success. + */ typedef FT_Error (*TT_Get_Name_Func)( TT_Face face, FT_UShort nameid, FT_String** name ); - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_Get_Name_ID_Func */ - /* */ - /* <Description> */ - /* Search whether an ENGLISH version for a given name ID is in the */ - /* `name' table. */ - /* */ - /* <Input> */ - /* face :: A handle to the source face object. */ - /* */ - /* nameid :: The name id of the name record to return. */ - /* */ - /* <Out> */ - /* win :: If non-negative, an index into the `name' table with */ - /* the corresponding (3,1) or (3,0) Windows entry. */ - /* */ - /* apple :: If non-negative, an index into the `name' table with */ - /* the corresponding (1,0) Apple entry. */ - /* */ - /* <Return> */ - /* 1 if there is either a win or apple entry (or both), 0 otheriwse. */ - /* */ + /************************************************************************** + * + * @functype: + * TT_Get_Name_ID_Func + * + * @description: + * Search whether an ENGLISH version for a given name ID is in the 'name' + * table. + * + * @input: + * face :: + * A handle to the source face object. + * + * nameid :: + * The name id of the name record to return. + * + * @output: + * win :: + * If non-negative, an index into the 'name' table with the + * corresponding (3,1) or (3,0) Windows entry. + * + * apple :: + * If non-negative, an index into the 'name' table with the + * corresponding (1,0) Apple entry. + * + * @return: + * 1 if there is either a win or apple entry (or both), 0 otheriwse. + */ typedef FT_Bool (*TT_Get_Name_ID_Func)( TT_Face face, FT_UShort nameid, @@ -486,42 +626,45 @@ FT_BEGIN_HEADER FT_Int *apple ); - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_Load_Table_Func */ - /* */ - /* <Description> */ - /* Load a given TrueType table. */ - /* */ - /* <Input> */ - /* face :: A handle to the target face object. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - /* <Note> */ - /* The function uses `face->goto_table' to seek the stream to the */ - /* start of the table, except while loading the font directory. */ - /* */ + /************************************************************************** + * + * @functype: + * TT_Load_Table_Func + * + * @description: + * Load a given TrueType table. + * + * @input: + * face :: + * A handle to the target face object. + * + * stream :: + * The input stream. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * The function uses `face->goto_table` to seek the stream to the start + * of the table, except while loading the font directory. + */ typedef FT_Error (*TT_Load_Table_Func)( TT_Face face, FT_Stream stream ); - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_Free_Table_Func */ - /* */ - /* <Description> */ - /* Free a given TrueType table. */ - /* */ - /* <Input> */ - /* face :: A handle to the target face object. */ - /* */ + /************************************************************************** + * + * @functype: + * TT_Free_Table_Func + * + * @description: + * Free a given TrueType table. + * + * @input: + * face :: + * A handle to the target face object. + */ typedef void (*TT_Free_Table_Func)( TT_Face face ); @@ -534,9 +677,14 @@ FT_BEGIN_HEADER * Return the horizontal kerning value between two glyphs. * * @input: - * face :: A handle to the source face object. - * left_glyph :: The left glyph index. - * right_glyph :: The right glyph index. + * face :: + * A handle to the source face object. + * + * left_glyph :: + * The left glyph index. + * + * right_glyph :: + * The right glyph index. * * @return: * The kerning value in font units. @@ -547,18 +695,18 @@ FT_BEGIN_HEADER FT_UInt right_glyph ); - /*************************************************************************/ - /* */ - /* <Struct> */ - /* SFNT_Interface */ - /* */ - /* <Description> */ - /* This structure holds pointers to the functions used to load and */ - /* free the basic tables that are required in a `sfnt' font file. */ - /* */ - /* <Fields> */ - /* Check the various xxx_Func() descriptions for details. */ - /* */ + /************************************************************************** + * + * @struct: + * SFNT_Interface + * + * @description: + * This structure holds pointers to the functions used to load and free + * the basic tables that are required in a 'sfnt' font file. + * + * @fields: + * Check the various xxx_Func() descriptions for details. + */ typedef struct SFNT_Interface_ { TT_Loader_GotoTableFunc goto_table; @@ -616,6 +764,14 @@ FT_BEGIN_HEADER TT_Set_SBit_Strike_Func set_sbit_strike; TT_Load_Strike_Metrics_Func load_strike_metrics; + TT_Load_Table_Func load_cpal; + TT_Load_Table_Func load_colr; + TT_Free_Table_Func free_cpal; + TT_Free_Table_Func free_colr; + TT_Set_Palette_Func set_palette; + TT_Get_Colr_Layer_Func get_colr_layer; + TT_Blend_Colr_Func colr_blend; + TT_Get_Metrics_Func get_metrics; TT_Get_Name_Func get_name; @@ -627,7 +783,6 @@ FT_BEGIN_HEADER /* transitional */ typedef SFNT_Interface* SFNT_Service; -#ifndef FT_CONFIG_OPTION_PIC #define FT_DEFINE_SFNT_INTERFACE( \ class_, \ @@ -659,6 +814,13 @@ FT_BEGIN_HEADER free_eblc_, \ set_sbit_strike_, \ load_strike_metrics_, \ + load_cpal_, \ + load_colr_, \ + free_cpal_, \ + free_colr_, \ + set_palette_, \ + get_colr_layer_, \ + colr_blend_, \ get_metrics_, \ get_name_, \ get_name_id_ ) \ @@ -692,89 +854,18 @@ FT_BEGIN_HEADER free_eblc_, \ set_sbit_strike_, \ load_strike_metrics_, \ + load_cpal_, \ + load_colr_, \ + free_cpal_, \ + free_colr_, \ + set_palette_, \ + get_colr_layer_, \ + colr_blend_, \ get_metrics_, \ get_name_, \ get_name_id_ \ }; -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_INTERNAL( a, a_ ) \ - clazz->a = a_; - -#define FT_DEFINE_SFNT_INTERFACE( \ - class_, \ - goto_table_, \ - init_face_, \ - load_face_, \ - done_face_, \ - get_interface_, \ - load_any_, \ - load_head_, \ - load_hhea_, \ - load_cmap_, \ - load_maxp_, \ - load_os2_, \ - load_post_, \ - load_name_, \ - free_name_, \ - load_kern_, \ - load_gasp_, \ - load_pclt_, \ - load_bhed_, \ - load_sbit_image_, \ - get_psname_, \ - free_psnames_, \ - get_kerning_, \ - load_font_dir_, \ - load_hmtx_, \ - load_eblc_, \ - free_eblc_, \ - set_sbit_strike_, \ - load_strike_metrics_, \ - get_metrics_, \ - get_name_, \ - get_name_id_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Library library, \ - SFNT_Interface* clazz ) \ - { \ - FT_UNUSED( library ); \ - \ - clazz->goto_table = goto_table_; \ - clazz->init_face = init_face_; \ - clazz->load_face = load_face_; \ - clazz->done_face = done_face_; \ - clazz->get_interface = get_interface_; \ - clazz->load_any = load_any_; \ - clazz->load_head = load_head_; \ - clazz->load_hhea = load_hhea_; \ - clazz->load_cmap = load_cmap_; \ - clazz->load_maxp = load_maxp_; \ - clazz->load_os2 = load_os2_; \ - clazz->load_post = load_post_; \ - clazz->load_name = load_name_; \ - clazz->free_name = free_name_; \ - clazz->load_kern = load_kern_; \ - clazz->load_gasp = load_gasp_; \ - clazz->load_pclt = load_pclt_; \ - clazz->load_bhed = load_bhed_; \ - clazz->load_sbit_image = load_sbit_image_; \ - clazz->get_psname = get_psname_; \ - clazz->free_psnames = free_psnames_; \ - clazz->get_kerning = get_kerning_; \ - clazz->load_font_dir = load_font_dir_; \ - clazz->load_hmtx = load_hmtx_; \ - clazz->load_eblc = load_eblc_; \ - clazz->free_eblc = free_eblc_; \ - clazz->set_sbit_strike = set_sbit_strike_; \ - clazz->load_strike_metrics = load_strike_metrics_; \ - clazz->get_metrics = get_metrics_; \ - clazz->get_name = get_name_; \ - clazz->get_name_id = get_name_id_; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ FT_END_HEADER diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/t1types.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/t1types.h index 2118e33674934..e197a1afca3dc 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/t1types.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/t1types.h @@ -1,20 +1,20 @@ -/***************************************************************************/ -/* */ -/* t1types.h */ -/* */ -/* Basic Type1/Type2 type definitions and interface (specification */ -/* only). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * t1types.h + * + * Basic Type1/Type2 type definitions and interface (specification + * only). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef T1TYPES_H_ @@ -45,28 +45,31 @@ FT_BEGIN_HEADER /*************************************************************************/ - /*************************************************************************/ - /* */ - /* <Struct> */ - /* T1_EncodingRec */ - /* */ - /* <Description> */ - /* A structure modeling a custom encoding. */ - /* */ - /* <Fields> */ - /* num_chars :: The number of character codes in the encoding. */ - /* Usually 256. */ - /* */ - /* code_first :: The lowest valid character code in the encoding. */ - /* */ - /* code_last :: The highest valid character code in the encoding */ - /* + 1. When equal to code_first there are no valid */ - /* character codes. */ - /* */ - /* char_index :: An array of corresponding glyph indices. */ - /* */ - /* char_name :: An array of corresponding glyph names. */ - /* */ + /************************************************************************** + * + * @struct: + * T1_EncodingRec + * + * @description: + * A structure modeling a custom encoding. + * + * @fields: + * num_chars :: + * The number of character codes in the encoding. Usually 256. + * + * code_first :: + * The lowest valid character code in the encoding. + * + * code_last :: + * The highest valid character code in the encoding + 1. When equal to + * code_first there are no valid character codes. + * + * char_index :: + * An array of corresponding glyph indices. + * + * char_name :: + * An array of corresponding glyph names. + */ typedef struct T1_EncodingRecRec_ { FT_Int num_chars; diff --git a/sdk/lib/3rdparty/freetype/include/freetype/internal/tttypes.h b/sdk/lib/3rdparty/freetype/include/freetype/internal/tttypes.h index 10dd336a89981..5e9f40ec3f752 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/internal/tttypes.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/internal/tttypes.h @@ -1,20 +1,20 @@ -/***************************************************************************/ -/* */ -/* tttypes.h */ -/* */ -/* Basic SFNT/TrueType type definitions and interface (specification */ -/* only). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * tttypes.h + * + * Basic SFNT/TrueType type definitions and interface (specification + * only). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef TTTYPES_H_ @@ -24,6 +24,7 @@ #include <ft2build.h> #include FT_TRUETYPE_TABLES_H #include FT_INTERNAL_OBJECTS_H +#include FT_COLOR_H #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT #include FT_MULTIPLE_MASTERS_H @@ -46,27 +47,30 @@ FT_BEGIN_HEADER /*************************************************************************/ - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TTC_HeaderRec */ - /* */ - /* <Description> */ - /* TrueType collection header. This table contains the offsets of */ - /* the font headers of each distinct TrueType face in the file. */ - /* */ - /* <Fields> */ - /* tag :: Must be `ttc ' to indicate a TrueType collection. */ - /* */ - /* version :: The version number. */ - /* */ - /* count :: The number of faces in the collection. The */ - /* specification says this should be an unsigned long, but */ - /* we use a signed long since we need the value -1 for */ - /* specific purposes. */ - /* */ - /* offsets :: The offsets of the font headers, one per face. */ - /* */ + /************************************************************************** + * + * @struct: + * TTC_HeaderRec + * + * @description: + * TrueType collection header. This table contains the offsets of the + * font headers of each distinct TrueType face in the file. + * + * @fields: + * tag :: + * Must be 'ttc~' to indicate a TrueType collection. + * + * version :: + * The version number. + * + * count :: + * The number of faces in the collection. The specification says this + * should be an unsigned long, but we use a signed long since we need + * the value -1 for specific purposes. + * + * offsets :: + * The offsets of the font headers, one per face. + */ typedef struct TTC_HeaderRec_ { FT_ULong tag; @@ -77,25 +81,30 @@ FT_BEGIN_HEADER } TTC_HeaderRec; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* SFNT_HeaderRec */ - /* */ - /* <Description> */ - /* SFNT file format header. */ - /* */ - /* <Fields> */ - /* format_tag :: The font format tag. */ - /* */ - /* num_tables :: The number of tables in file. */ - /* */ - /* search_range :: Must be `16 * (max power of 2 <= num_tables)'. */ - /* */ - /* entry_selector :: Must be log2 of `search_range / 16'. */ - /* */ - /* range_shift :: Must be `num_tables * 16 - search_range'. */ - /* */ + /************************************************************************** + * + * @struct: + * SFNT_HeaderRec + * + * @description: + * SFNT file format header. + * + * @fields: + * format_tag :: + * The font format tag. + * + * num_tables :: + * The number of tables in file. + * + * search_range :: + * Must be '16 * (max power of 2 <= num_tables)'. + * + * entry_selector :: + * Must be log2 of 'search_range / 16'. + * + * range_shift :: + * Must be 'num_tables * 16 - search_range'. + */ typedef struct SFNT_HeaderRec_ { FT_ULong format_tag; @@ -109,24 +118,28 @@ FT_BEGIN_HEADER } SFNT_HeaderRec, *SFNT_Header; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_TableRec */ - /* */ - /* <Description> */ - /* This structure describes a given table of a TrueType font. */ - /* */ - /* <Fields> */ - /* Tag :: A four-bytes tag describing the table. */ - /* */ - /* CheckSum :: The table checksum. This value can be ignored. */ - /* */ - /* Offset :: The offset of the table from the start of the TrueType */ - /* font in its resource. */ - /* */ - /* Length :: The table length (in bytes). */ - /* */ + /************************************************************************** + * + * @struct: + * TT_TableRec + * + * @description: + * This structure describes a given table of a TrueType font. + * + * @fields: + * Tag :: + * A four-bytes tag describing the table. + * + * CheckSum :: + * The table checksum. This value can be ignored. + * + * Offset :: + * The offset of the table from the start of the TrueType font in its + * resource. + * + * Length :: + * The table length (in bytes). + */ typedef struct TT_TableRec_ { FT_ULong Tag; /* table type */ @@ -137,19 +150,19 @@ FT_BEGIN_HEADER } TT_TableRec, *TT_Table; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* WOFF_HeaderRec */ - /* */ - /* <Description> */ - /* WOFF file format header. */ - /* */ - /* <Fields> */ - /* See */ - /* */ - /* https://www.w3.org/TR/WOFF/#WOFFHeader */ - /* */ + /************************************************************************** + * + * @struct: + * WOFF_HeaderRec + * + * @description: + * WOFF file format header. + * + * @fields: + * See + * + * https://www.w3.org/TR/WOFF/#WOFFHeader + */ typedef struct WOFF_HeaderRec_ { FT_ULong signature; @@ -169,30 +182,36 @@ FT_BEGIN_HEADER } WOFF_HeaderRec, *WOFF_Header; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* WOFF_TableRec */ - /* */ - /* <Description> */ - /* This structure describes a given table of a WOFF font. */ - /* */ - /* <Fields> */ - /* Tag :: A four-bytes tag describing the table. */ - /* */ - /* Offset :: The offset of the table from the start of the WOFF */ - /* font in its resource. */ - /* */ - /* CompLength :: Compressed table length (in bytes). */ - /* */ - /* OrigLength :: Uncompressed table length (in bytes). */ - /* */ - /* CheckSum :: The table checksum. This value can be ignored. */ - /* */ - /* OrigOffset :: The uncompressed table file offset. This value gets */ - /* computed while constructing the (uncompressed) SFNT */ - /* header. It is not contained in the WOFF file. */ - /* */ + /************************************************************************** + * + * @struct: + * WOFF_TableRec + * + * @description: + * This structure describes a given table of a WOFF font. + * + * @fields: + * Tag :: + * A four-bytes tag describing the table. + * + * Offset :: + * The offset of the table from the start of the WOFF font in its + * resource. + * + * CompLength :: + * Compressed table length (in bytes). + * + * OrigLength :: + * Uncompressed table length (in bytes). + * + * CheckSum :: + * The table checksum. This value can be ignored. + * + * OrigOffset :: + * The uncompressed table file offset. This value gets computed while + * constructing the (uncompressed) SFNT header. It is not contained in + * the WOFF file. + */ typedef struct WOFF_TableRec_ { FT_ULong Tag; /* table ID */ @@ -206,20 +225,22 @@ FT_BEGIN_HEADER } WOFF_TableRec, *WOFF_Table; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_LongMetricsRec */ - /* */ - /* <Description> */ - /* A structure modeling the long metrics of the `hmtx' and `vmtx' */ - /* TrueType tables. The values are expressed in font units. */ - /* */ - /* <Fields> */ - /* advance :: The advance width or height for the glyph. */ - /* */ - /* bearing :: The left-side or top-side bearing for the glyph. */ - /* */ + /************************************************************************** + * + * @struct: + * TT_LongMetricsRec + * + * @description: + * A structure modeling the long metrics of the 'hmtx' and 'vmtx' + * TrueType tables. The values are expressed in font units. + * + * @fields: + * advance :: + * The advance width or height for the glyph. + * + * bearing :: + * The left-side or top-side bearing for the glyph. + */ typedef struct TT_LongMetricsRec_ { FT_UShort advance; @@ -228,45 +249,51 @@ FT_BEGIN_HEADER } TT_LongMetricsRec, *TT_LongMetrics; - /*************************************************************************/ - /* */ - /* <Type> */ - /* TT_ShortMetrics */ - /* */ - /* <Description> */ - /* A simple type to model the short metrics of the `hmtx' and `vmtx' */ - /* tables. */ - /* */ + /************************************************************************** + * + * @type: + * TT_ShortMetrics + * + * @description: + * A simple type to model the short metrics of the 'hmtx' and 'vmtx' + * tables. + */ typedef FT_Short TT_ShortMetrics; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_NameRec */ - /* */ - /* <Description> */ - /* A structure modeling TrueType name records. Name records are used */ - /* to store important strings like family name, style name, */ - /* copyright, etc. in _localized_ versions (i.e., language, encoding, */ - /* etc). */ - /* */ - /* <Fields> */ - /* platformID :: The ID of the name's encoding platform. */ - /* */ - /* encodingID :: The platform-specific ID for the name's encoding. */ - /* */ - /* languageID :: The platform-specific ID for the name's language. */ - /* */ - /* nameID :: The ID specifying what kind of name this is. */ - /* */ - /* stringLength :: The length of the string in bytes. */ - /* */ - /* stringOffset :: The offset to the string in the `name' table. */ - /* */ - /* string :: A pointer to the string's bytes. Note that these */ - /* are usually UTF-16 encoded characters. */ - /* */ + /************************************************************************** + * + * @struct: + * TT_NameRec + * + * @description: + * A structure modeling TrueType name records. Name records are used to + * store important strings like family name, style name, copyright, + * etc. in _localized_ versions (i.e., language, encoding, etc). + * + * @fields: + * platformID :: + * The ID of the name's encoding platform. + * + * encodingID :: + * The platform-specific ID for the name's encoding. + * + * languageID :: + * The platform-specific ID for the name's language. + * + * nameID :: + * The ID specifying what kind of name this is. + * + * stringLength :: + * The length of the string in bytes. + * + * stringOffset :: + * The offset to the string in the 'name' table. + * + * string :: + * A pointer to the string's bytes. Note that these are usually UTF-16 + * encoded characters. + */ typedef struct TT_NameRec_ { FT_UShort platformID; @@ -284,23 +311,26 @@ FT_BEGIN_HEADER } TT_NameRec, *TT_Name; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_LangTagRec */ - /* */ - /* <Description> */ - /* A structure modeling language tag records in SFNT `name' tables, */ - /* introduced in OpenType version 1.6. */ - /* */ - /* <Fields> */ - /* stringLength :: The length of the string in bytes. */ - /* */ - /* stringOffset :: The offset to the string in the `name' table. */ - /* */ - /* string :: A pointer to the string's bytes. Note that these */ - /* are UTF-16BE encoded characters. */ - /* */ + /************************************************************************** + * + * @struct: + * TT_LangTagRec + * + * @description: + * A structure modeling language tag records in SFNT 'name' tables, + * introduced in OpenType version 1.6. + * + * @fields: + * stringLength :: + * The length of the string in bytes. + * + * stringOffset :: + * The offset to the string in the 'name' table. + * + * string :: + * A pointer to the string's bytes. Note that these are UTF-16BE + * encoded characters. + */ typedef struct TT_LangTagRec_ { FT_UShort stringLength; @@ -314,30 +344,36 @@ FT_BEGIN_HEADER } TT_LangTagRec, *TT_LangTag; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_NameTableRec */ - /* */ - /* <Description> */ - /* A structure modeling the TrueType name table. */ - /* */ - /* <Fields> */ - /* format :: The format of the name table. */ - /* */ - /* numNameRecords :: The number of names in table. */ - /* */ - /* storageOffset :: The offset of the name table in the `name' */ - /* TrueType table. */ - /* */ - /* names :: An array of name records. */ - /* */ - /* numLangTagRecords :: The number of language tags in table. */ - /* */ - /* langTags :: An array of language tag records. */ - /* */ - /* stream :: The file's input stream. */ - /* */ + /************************************************************************** + * + * @struct: + * TT_NameTableRec + * + * @description: + * A structure modeling the TrueType name table. + * + * @fields: + * format :: + * The format of the name table. + * + * numNameRecords :: + * The number of names in table. + * + * storageOffset :: + * The offset of the name table in the 'name' TrueType table. + * + * names :: + * An array of name records. + * + * numLangTagRecords :: + * The number of language tags in table. + * + * langTags :: + * An array of language tag records. + * + * stream :: + * The file's input stream. + */ typedef struct TT_NameTableRec_ { FT_UShort format; @@ -364,21 +400,23 @@ FT_BEGIN_HEADER /*************************************************************************/ - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_GaspRangeRec */ - /* */ - /* <Description> */ - /* A tiny structure used to model a gasp range according to the */ - /* TrueType specification. */ - /* */ - /* <Fields> */ - /* maxPPEM :: The maximum ppem value to which `gaspFlag' applies. */ - /* */ - /* gaspFlag :: A flag describing the grid-fitting and anti-aliasing */ - /* modes to be used. */ - /* */ + /************************************************************************** + * + * @struct: + * TT_GaspRangeRec + * + * @description: + * A tiny structure used to model a gasp range according to the TrueType + * specification. + * + * @fields: + * maxPPEM :: + * The maximum ppem value to which `gaspFlag` applies. + * + * gaspFlag :: + * A flag describing the grid-fitting and anti-aliasing modes to be + * used. + */ typedef struct TT_GaspRangeRec_ { FT_UShort maxPPEM; @@ -391,22 +429,25 @@ FT_BEGIN_HEADER #define TT_GASP_DOGRAY 0x02 - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_GaspRec */ - /* */ - /* <Description> */ - /* A structure modeling the TrueType `gasp' table used to specify */ - /* grid-fitting and anti-aliasing behaviour. */ - /* */ - /* <Fields> */ - /* version :: The version number. */ - /* */ - /* numRanges :: The number of gasp ranges in table. */ - /* */ - /* gaspRanges :: An array of gasp ranges. */ - /* */ + /************************************************************************** + * + * @struct: + * TT_GaspRec + * + * @description: + * A structure modeling the TrueType 'gasp' table used to specify + * grid-fitting and anti-aliasing behaviour. + * + * @fields: + * version :: + * The version number. + * + * numRanges :: + * The number of gasp ranges in table. + * + * gaspRanges :: + * An array of gasp ranges. + */ typedef struct TT_Gasp_ { FT_UShort version; @@ -429,33 +470,41 @@ FT_BEGIN_HEADER /*************************************************************************/ - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_SBit_MetricsRec */ - /* */ - /* <Description> */ - /* A structure used to hold the big metrics of a given glyph bitmap */ - /* in a TrueType or OpenType font. These are usually found in the */ - /* `EBDT' (Microsoft) or `bloc' (Apple) table. */ - /* */ - /* <Fields> */ - /* height :: The glyph height in pixels. */ - /* */ - /* width :: The glyph width in pixels. */ - /* */ - /* horiBearingX :: The horizontal left bearing. */ - /* */ - /* horiBearingY :: The horizontal top bearing. */ - /* */ - /* horiAdvance :: The horizontal advance. */ - /* */ - /* vertBearingX :: The vertical left bearing. */ - /* */ - /* vertBearingY :: The vertical top bearing. */ - /* */ - /* vertAdvance :: The vertical advance. */ - /* */ + /************************************************************************** + * + * @struct: + * TT_SBit_MetricsRec + * + * @description: + * A structure used to hold the big metrics of a given glyph bitmap in a + * TrueType or OpenType font. These are usually found in the 'EBDT' + * (Microsoft) or 'bloc' (Apple) table. + * + * @fields: + * height :: + * The glyph height in pixels. + * + * width :: + * The glyph width in pixels. + * + * horiBearingX :: + * The horizontal left bearing. + * + * horiBearingY :: + * The horizontal top bearing. + * + * horiAdvance :: + * The horizontal advance. + * + * vertBearingX :: + * The vertical left bearing. + * + * vertBearingY :: + * The vertical top bearing. + * + * vertAdvance :: + * The vertical advance. + */ typedef struct TT_SBit_MetricsRec_ { FT_UShort height; @@ -472,27 +521,32 @@ FT_BEGIN_HEADER } TT_SBit_MetricsRec, *TT_SBit_Metrics; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_SBit_SmallMetricsRec */ - /* */ - /* <Description> */ - /* A structure used to hold the small metrics of a given glyph bitmap */ - /* in a TrueType or OpenType font. These are usually found in the */ - /* `EBDT' (Microsoft) or the `bdat' (Apple) table. */ - /* */ - /* <Fields> */ - /* height :: The glyph height in pixels. */ - /* */ - /* width :: The glyph width in pixels. */ - /* */ - /* bearingX :: The left-side bearing. */ - /* */ - /* bearingY :: The top-side bearing. */ - /* */ - /* advance :: The advance width or height. */ - /* */ + /************************************************************************** + * + * @struct: + * TT_SBit_SmallMetricsRec + * + * @description: + * A structure used to hold the small metrics of a given glyph bitmap in + * a TrueType or OpenType font. These are usually found in the 'EBDT' + * (Microsoft) or the 'bdat' (Apple) table. + * + * @fields: + * height :: + * The glyph height in pixels. + * + * width :: + * The glyph width in pixels. + * + * bearingX :: + * The left-side bearing. + * + * bearingY :: + * The top-side bearing. + * + * advance :: + * The advance width or height. + */ typedef struct TT_SBit_Small_Metrics_ { FT_Byte height; @@ -505,57 +559,60 @@ FT_BEGIN_HEADER } TT_SBit_SmallMetricsRec, *TT_SBit_SmallMetrics; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_SBit_LineMetricsRec */ - /* */ - /* <Description> */ - /* A structure used to describe the text line metrics of a given */ - /* bitmap strike, for either a horizontal or vertical layout. */ - /* */ - /* <Fields> */ - /* ascender :: The ascender in pixels. */ - /* */ - /* descender :: The descender in pixels. */ - /* */ - /* max_width :: The maximum glyph width in pixels. */ - /* */ - /* caret_slope_enumerator :: Rise of the caret slope, typically set */ - /* to 1 for non-italic fonts. */ - /* */ - /* caret_slope_denominator :: Rise of the caret slope, typically set */ - /* to 0 for non-italic fonts. */ - /* */ - /* caret_offset :: Offset in pixels to move the caret for */ - /* proper positioning. */ - /* */ - /* min_origin_SB :: Minimum of horiBearingX (resp. */ - /* vertBearingY). */ - /* min_advance_SB :: Minimum of */ - /* */ - /* horizontal advance - */ - /* ( horiBearingX + width ) */ - /* */ - /* resp. */ - /* */ - /* vertical advance - */ - /* ( vertBearingY + height ) */ - /* */ - /* max_before_BL :: Maximum of horiBearingY (resp. */ - /* vertBearingY). */ - /* */ - /* min_after_BL :: Minimum of */ - /* */ - /* horiBearingY - height */ - /* */ - /* resp. */ - /* */ - /* vertBearingX - width */ - /* */ - /* pads :: Unused (to make the size of the record */ - /* a multiple of 32 bits. */ - /* */ + /************************************************************************** + * + * @struct: + * TT_SBit_LineMetricsRec + * + * @description: + * A structure used to describe the text line metrics of a given bitmap + * strike, for either a horizontal or vertical layout. + * + * @fields: + * ascender :: + * The ascender in pixels. + * + * descender :: + * The descender in pixels. + * + * max_width :: + * The maximum glyph width in pixels. + * + * caret_slope_enumerator :: + * Rise of the caret slope, typically set to 1 for non-italic fonts. + * + * caret_slope_denominator :: + * Rise of the caret slope, typically set to 0 for non-italic fonts. + * + * caret_offset :: + * Offset in pixels to move the caret for proper positioning. + * + * min_origin_SB :: + * Minimum of horiBearingX (resp. vertBearingY). + * min_advance_SB :: + * Minimum of + * + * horizontal advance - ( horiBearingX + width ) + * + * resp. + * + * vertical advance - ( vertBearingY + height ) + * + * max_before_BL :: + * Maximum of horiBearingY (resp. vertBearingY). + * + * min_after_BL :: + * Minimum of + * + * horiBearingY - height + * + * resp. + * + * vertBearingX - width + * + * pads :: + * Unused (to make the size of the record a multiple of 32 bits. + */ typedef struct TT_SBit_LineMetricsRec_ { FT_Char ascender; @@ -573,43 +630,53 @@ FT_BEGIN_HEADER } TT_SBit_LineMetricsRec, *TT_SBit_LineMetrics; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_SBit_RangeRec */ - /* */ - /* <Description> */ - /* A TrueType/OpenType subIndexTable as defined in the `EBLC' */ - /* (Microsoft) or `bloc' (Apple) tables. */ - /* */ - /* <Fields> */ - /* first_glyph :: The first glyph index in the range. */ - /* */ - /* last_glyph :: The last glyph index in the range. */ - /* */ - /* index_format :: The format of index table. Valid values are 1 */ - /* to 5. */ - /* */ - /* image_format :: The format of `EBDT' image data. */ - /* */ - /* image_offset :: The offset to image data in `EBDT'. */ - /* */ - /* image_size :: For index formats 2 and 5. This is the size in */ - /* bytes of each glyph bitmap. */ - /* */ - /* big_metrics :: For index formats 2 and 5. This is the big */ - /* metrics for each glyph bitmap. */ - /* */ - /* num_glyphs :: For index formats 4 and 5. This is the number of */ - /* glyphs in the code array. */ - /* */ - /* glyph_offsets :: For index formats 1 and 3. */ - /* */ - /* glyph_codes :: For index formats 4 and 5. */ - /* */ - /* table_offset :: The offset of the index table in the `EBLC' */ - /* table. Only used during strike loading. */ - /* */ + /************************************************************************** + * + * @struct: + * TT_SBit_RangeRec + * + * @description: + * A TrueType/OpenType subIndexTable as defined in the 'EBLC' (Microsoft) + * or 'bloc' (Apple) tables. + * + * @fields: + * first_glyph :: + * The first glyph index in the range. + * + * last_glyph :: + * The last glyph index in the range. + * + * index_format :: + * The format of index table. Valid values are 1 to 5. + * + * image_format :: + * The format of 'EBDT' image data. + * + * image_offset :: + * The offset to image data in 'EBDT'. + * + * image_size :: + * For index formats 2 and 5. This is the size in bytes of each glyph + * bitmap. + * + * big_metrics :: + * For index formats 2 and 5. This is the big metrics for each glyph + * bitmap. + * + * num_glyphs :: + * For index formats 4 and 5. This is the number of glyphs in the code + * array. + * + * glyph_offsets :: + * For index formats 1 and 3. + * + * glyph_codes :: + * For index formats 4 and 5. + * + * table_offset :: + * The offset of the index table in the 'EBLC' table. Only used during + * strike loading. + */ typedef struct TT_SBit_RangeRec_ { FT_UShort first_glyph; @@ -631,47 +698,55 @@ FT_BEGIN_HEADER } TT_SBit_RangeRec, *TT_SBit_Range; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_SBit_StrikeRec */ - /* */ - /* <Description> */ - /* A structure used describe a given bitmap strike in the `EBLC' */ - /* (Microsoft) or `bloc' (Apple) tables. */ - /* */ - /* <Fields> */ - /* num_index_ranges :: The number of index ranges. */ - /* */ - /* index_ranges :: An array of glyph index ranges. */ - /* */ - /* color_ref :: Unused. `color_ref' is put in for future */ - /* enhancements, but these fields are already */ - /* in use by other platforms (e.g. Newton). */ - /* For details, please see */ - /* */ - /* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6bloc.html */ - /* */ - /* hori :: The line metrics for horizontal layouts. */ - /* */ - /* vert :: The line metrics for vertical layouts. */ - /* */ - /* start_glyph :: The lowest glyph index for this strike. */ - /* */ - /* end_glyph :: The highest glyph index for this strike. */ - /* */ - /* x_ppem :: The number of horizontal pixels per EM. */ - /* */ - /* y_ppem :: The number of vertical pixels per EM. */ - /* */ - /* bit_depth :: The bit depth. Valid values are 1, 2, 4, */ - /* and 8. */ - /* */ - /* flags :: Is this a vertical or horizontal strike? For */ - /* details, please see */ - /* */ - /* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6bloc.html */ - /* */ + /************************************************************************** + * + * @struct: + * TT_SBit_StrikeRec + * + * @description: + * A structure used describe a given bitmap strike in the 'EBLC' + * (Microsoft) or 'bloc' (Apple) tables. + * + * @fields: + * num_index_ranges :: + * The number of index ranges. + * + * index_ranges :: + * An array of glyph index ranges. + * + * color_ref :: + * Unused. `color_ref` is put in for future enhancements, but these + * fields are already in use by other platforms (e.g. Newton). For + * details, please see + * + * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6bloc.html + * + * hori :: + * The line metrics for horizontal layouts. + * + * vert :: + * The line metrics for vertical layouts. + * + * start_glyph :: + * The lowest glyph index for this strike. + * + * end_glyph :: + * The highest glyph index for this strike. + * + * x_ppem :: + * The number of horizontal pixels per EM. + * + * y_ppem :: + * The number of vertical pixels per EM. + * + * bit_depth :: + * The bit depth. Valid values are 1, 2, 4, and 8. + * + * flags :: + * Is this a vertical or horizontal strike? For details, please see + * + * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6bloc.html + */ typedef struct TT_SBit_StrikeRec_ { FT_Int num_ranges; @@ -695,21 +770,24 @@ FT_BEGIN_HEADER } TT_SBit_StrikeRec, *TT_SBit_Strike; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_SBit_ComponentRec */ - /* */ - /* <Description> */ - /* A simple structure to describe a compound sbit element. */ - /* */ - /* <Fields> */ - /* glyph_code :: The element's glyph index. */ - /* */ - /* x_offset :: The element's left bearing. */ - /* */ - /* y_offset :: The element's top bearing. */ - /* */ + /************************************************************************** + * + * @struct: + * TT_SBit_ComponentRec + * + * @description: + * A simple structure to describe a compound sbit element. + * + * @fields: + * glyph_code :: + * The element's glyph index. + * + * x_offset :: + * The element's left bearing. + * + * y_offset :: + * The element's top bearing. + */ typedef struct TT_SBit_ComponentRec_ { FT_UShort glyph_code; @@ -719,28 +797,34 @@ FT_BEGIN_HEADER } TT_SBit_ComponentRec, *TT_SBit_Component; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_SBit_ScaleRec */ - /* */ - /* <Description> */ - /* A structure used describe a given bitmap scaling table, as defined */ - /* in the `EBSC' table. */ - /* */ - /* <Fields> */ - /* hori :: The horizontal line metrics. */ - /* */ - /* vert :: The vertical line metrics. */ - /* */ - /* x_ppem :: The number of horizontal pixels per EM. */ - /* */ - /* y_ppem :: The number of vertical pixels per EM. */ - /* */ - /* x_ppem_substitute :: Substitution x_ppem value. */ - /* */ - /* y_ppem_substitute :: Substitution y_ppem value. */ - /* */ + /************************************************************************** + * + * @struct: + * TT_SBit_ScaleRec + * + * @description: + * A structure used describe a given bitmap scaling table, as defined in + * the 'EBSC' table. + * + * @fields: + * hori :: + * The horizontal line metrics. + * + * vert :: + * The vertical line metrics. + * + * x_ppem :: + * The number of horizontal pixels per EM. + * + * y_ppem :: + * The number of vertical pixels per EM. + * + * x_ppem_substitute :: + * Substitution x_ppem value. + * + * y_ppem_substitute :: + * Substitution y_ppem value. + */ typedef struct TT_SBit_ScaleRec_ { TT_SBit_LineMetricsRec hori; @@ -768,24 +852,28 @@ FT_BEGIN_HEADER /*************************************************************************/ - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_Post_20Rec */ - /* */ - /* <Description> */ - /* Postscript names sub-table, format 2.0. Stores the PS name of */ - /* each glyph in the font face. */ - /* */ - /* <Fields> */ - /* num_glyphs :: The number of named glyphs in the table. */ - /* */ - /* num_names :: The number of PS names stored in the table. */ - /* */ - /* glyph_indices :: The indices of the glyphs in the names arrays. */ - /* */ - /* glyph_names :: The PS names not in Mac Encoding. */ - /* */ + /************************************************************************** + * + * @struct: + * TT_Post_20Rec + * + * @description: + * Postscript names sub-table, format 2.0. Stores the PS name of each + * glyph in the font face. + * + * @fields: + * num_glyphs :: + * The number of named glyphs in the table. + * + * num_names :: + * The number of PS names stored in the table. + * + * glyph_indices :: + * The indices of the glyphs in the names arrays. + * + * glyph_names :: + * The PS names not in Mac Encoding. + */ typedef struct TT_Post_20Rec_ { FT_UShort num_glyphs; @@ -796,21 +884,22 @@ FT_BEGIN_HEADER } TT_Post_20Rec, *TT_Post_20; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_Post_25Rec */ - /* */ - /* <Description> */ - /* Postscript names sub-table, format 2.5. Stores the PS name of */ - /* each glyph in the font face. */ - /* */ - /* <Fields> */ - /* num_glyphs :: The number of glyphs in the table. */ - /* */ - /* offsets :: An array of signed offsets in a normal Mac */ - /* Postscript name encoding. */ - /* */ + /************************************************************************** + * + * @struct: + * TT_Post_25Rec + * + * @description: + * Postscript names sub-table, format 2.5. Stores the PS name of each + * glyph in the font face. + * + * @fields: + * num_glyphs :: + * The number of glyphs in the table. + * + * offsets :: + * An array of signed offsets in a normal Mac Postscript name encoding. + */ typedef struct TT_Post_25_ { FT_UShort num_glyphs; @@ -819,21 +908,24 @@ FT_BEGIN_HEADER } TT_Post_25Rec, *TT_Post_25; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_Post_NamesRec */ - /* */ - /* <Description> */ - /* Postscript names table, either format 2.0 or 2.5. */ - /* */ - /* <Fields> */ - /* loaded :: A flag to indicate whether the PS names are loaded. */ - /* */ - /* format_20 :: The sub-table used for format 2.0. */ - /* */ - /* format_25 :: The sub-table used for format 2.5. */ - /* */ + /************************************************************************** + * + * @struct: + * TT_Post_NamesRec + * + * @description: + * Postscript names table, either format 2.0 or 2.5. + * + * @fields: + * loaded :: + * A flag to indicate whether the PS names are loaded. + * + * format_20 :: + * The sub-table used for format 2.0. + * + * format_25 :: + * The sub-table used for format 2.5. + */ typedef struct TT_Post_NamesRec_ { FT_Bool loaded; @@ -879,25 +971,25 @@ FT_BEGIN_HEADER /* * These types are used to support a `BDF ' table that isn't part of the - * official TrueType specification. It is mainly used in SFNT-based - * bitmap fonts that were generated from a set of BDF fonts. + * official TrueType specification. It is mainly used in SFNT-based bitmap + * fonts that were generated from a set of BDF fonts. * * The format of the table is as follows. * - * USHORT version `BDF ' table version number, should be 0x0001. - * USHORT strikeCount Number of strikes (bitmap sizes) in this table. - * ULONG stringTable Offset (from start of BDF table) to string + * USHORT version `BDF ' table version number, should be 0x0001. USHORT + * strikeCount Number of strikes (bitmap sizes) in this table. ULONG + * stringTable Offset (from start of BDF table) to string * table. * * This is followed by an array of `strikeCount' descriptors, having the * following format. * - * USHORT ppem Vertical pixels per EM for this strike. - * USHORT numItems Number of items for this strike (properties and + * USHORT ppem Vertical pixels per EM for this strike. USHORT numItems + * Number of items for this strike (properties and * atoms). Maximum is 255. * - * This array in turn is followed by `strikeCount' value sets. Each - * `value set' is an array of `numItems' items with the following format. + * This array in turn is followed by `strikeCount' value sets. Each `value + * set' is an array of `numItems' items with the following format. * * ULONG item_name Offset in string table to item name. * USHORT item_type The item type. Possible values are @@ -945,31 +1037,30 @@ FT_BEGIN_HEADER /*************************************************************************/ - /*************************************************************************/ - /* */ - /* This structure/class is defined here because it is common to the */ - /* following formats: TTF, OpenType-TT, and OpenType-CFF. */ - /* */ - /* Note, however, that the classes TT_Size and TT_GlyphSlot are not */ - /* shared between font drivers, and are thus defined in `ttobjs.h'. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * This structure/class is defined here because it is common to the + * following formats: TTF, OpenType-TT, and OpenType-CFF. + * + * Note, however, that the classes TT_Size and TT_GlyphSlot are not shared + * between font drivers, and are thus defined in `ttobjs.h`. + * + */ - /*************************************************************************/ - /* */ - /* <Type> */ - /* TT_Face */ - /* */ - /* <Description> */ - /* A handle to a TrueType face/font object. A TT_Face encapsulates */ - /* the resolution and scaling independent parts of a TrueType font */ - /* resource. */ - /* */ - /* <Note> */ - /* The TT_Face structure is also used as a `parent class' for the */ - /* OpenType-CFF class (T2_Face). */ - /* */ + /************************************************************************** + * + * @type: + * TT_Face + * + * @description: + * A handle to a TrueType face/font object. A TT_Face encapsulates the + * resolution and scaling independent parts of a TrueType font resource. + * + * @note: + * The TT_Face structure is also used as a 'parent class' for the + * OpenType-CFF class (T2_Face). + */ typedef struct TT_FaceRec_* TT_Face; @@ -981,31 +1072,34 @@ FT_BEGIN_HEADER typedef struct TT_LoaderRec_* TT_Loader; - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_Loader_GotoTableFunc */ - /* */ - /* <Description> */ - /* Seeks a stream to the start of a given TrueType table. */ - /* */ - /* <Input> */ - /* face :: A handle to the target face object. */ - /* */ - /* tag :: A 4-byte tag used to name the table. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* <Output> */ - /* length :: The length of the table in bytes. Set to 0 if not */ - /* needed. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - /* <Note> */ - /* The stream cursor must be at the font file's origin. */ - /* */ + /************************************************************************** + * + * @functype: + * TT_Loader_GotoTableFunc + * + * @description: + * Seeks a stream to the start of a given TrueType table. + * + * @input: + * face :: + * A handle to the target face object. + * + * tag :: + * A 4-byte tag used to name the table. + * + * stream :: + * The input stream. + * + * @output: + * length :: + * The length of the table in bytes. Set to 0 if not needed. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * The stream cursor must be at the font file's origin. + */ typedef FT_Error (*TT_Loader_GotoTableFunc)( TT_Face face, FT_ULong tag, @@ -1013,34 +1107,36 @@ FT_BEGIN_HEADER FT_ULong* length ); - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_Loader_StartGlyphFunc */ - /* */ - /* <Description> */ - /* Seeks a stream to the start of a given glyph element, and opens a */ - /* frame for it. */ - /* */ - /* <Input> */ - /* loader :: The current TrueType glyph loader object. */ - /* */ - /* glyph index :: The index of the glyph to access. */ - /* */ - /* offset :: The offset of the glyph according to the */ - /* `locations' table. */ - /* */ - /* byte_count :: The size of the frame in bytes. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - /* <Note> */ - /* This function is normally equivalent to FT_STREAM_SEEK(offset) */ - /* followed by FT_FRAME_ENTER(byte_count) with the loader's stream, */ - /* but alternative formats (e.g. compressed ones) might use something */ - /* different. */ - /* */ + /************************************************************************** + * + * @functype: + * TT_Loader_StartGlyphFunc + * + * @description: + * Seeks a stream to the start of a given glyph element, and opens a + * frame for it. + * + * @input: + * loader :: + * The current TrueType glyph loader object. + * + * glyph index :: The index of the glyph to access. + * + * offset :: + * The offset of the glyph according to the 'locations' table. + * + * byte_count :: + * The size of the frame in bytes. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * This function is normally equivalent to FT_STREAM_SEEK(offset) + * followed by FT_FRAME_ENTER(byte_count) with the loader's stream, but + * alternative formats (e.g. compressed ones) might use something + * different. + */ typedef FT_Error (*TT_Loader_StartGlyphFunc)( TT_Loader loader, FT_UInt glyph_index, @@ -1048,36 +1144,38 @@ FT_BEGIN_HEADER FT_UInt byte_count ); - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_Loader_ReadGlyphFunc */ - /* */ - /* <Description> */ - /* Reads one glyph element (its header, a simple glyph, or a */ - /* composite) from the loader's current stream frame. */ - /* */ - /* <Input> */ - /* loader :: The current TrueType glyph loader object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @functype: + * TT_Loader_ReadGlyphFunc + * + * @description: + * Reads one glyph element (its header, a simple glyph, or a composite) + * from the loader's current stream frame. + * + * @input: + * loader :: + * The current TrueType glyph loader object. + * + * @return: + * FreeType error code. 0 means success. + */ typedef FT_Error (*TT_Loader_ReadGlyphFunc)( TT_Loader loader ); - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_Loader_EndGlyphFunc */ - /* */ - /* <Description> */ - /* Closes the current loader stream frame for the glyph. */ - /* */ - /* <Input> */ - /* loader :: The current TrueType glyph loader object. */ - /* */ + /************************************************************************** + * + * @functype: + * TT_Loader_EndGlyphFunc + * + * @description: + * Closes the current loader stream frame for the glyph. + * + * @input: + * loader :: + * The current TrueType glyph loader object. + */ typedef void (*TT_Loader_EndGlyphFunc)( TT_Loader loader ); @@ -1124,270 +1222,317 @@ FT_BEGIN_HEADER #define TT_FACE_FLAG_VAR_MVAR ( 1 << 8 ) - /*************************************************************************/ - /* */ - /* TrueType Face Type */ - /* */ - /* <Struct> */ - /* TT_Face */ - /* */ - /* <Description> */ - /* The TrueType face class. These objects model the resolution and */ - /* point-size independent data found in a TrueType font file. */ - /* */ - /* <Fields> */ - /* root :: The base FT_Face structure, managed by the */ - /* base layer. */ - /* */ - /* ttc_header :: The TrueType collection header, used when */ - /* the file is a `ttc' rather than a `ttf'. */ - /* For ordinary font files, the field */ - /* `ttc_header.count' is set to 0. */ - /* */ - /* format_tag :: The font format tag. */ - /* */ - /* num_tables :: The number of TrueType tables in this font */ - /* file. */ - /* */ - /* dir_tables :: The directory of TrueType tables for this */ - /* font file. */ - /* */ - /* header :: The font's font header (`head' table). */ - /* Read on font opening. */ - /* */ - /* horizontal :: The font's horizontal header (`hhea' */ - /* table). This field also contains the */ - /* associated horizontal metrics table */ - /* (`hmtx'). */ - /* */ - /* max_profile :: The font's maximum profile table. Read on */ - /* font opening. Note that some maximum */ - /* values cannot be taken directly from this */ - /* table. We thus define additional fields */ - /* below to hold the computed maxima. */ - /* */ - /* vertical_info :: A boolean which is set when the font file */ - /* contains vertical metrics. If not, the */ - /* value of the `vertical' field is */ - /* undefined. */ - /* */ - /* vertical :: The font's vertical header (`vhea' table). */ - /* This field also contains the associated */ - /* vertical metrics table (`vmtx'), if found. */ - /* IMPORTANT: The contents of this field is */ - /* undefined if the `vertical_info' field is */ - /* unset. */ - /* */ - /* num_names :: The number of name records within this */ - /* TrueType font. */ - /* */ - /* name_table :: The table of name records (`name'). */ - /* */ - /* os2 :: The font's OS/2 table (`OS/2'). */ - /* */ - /* postscript :: The font's PostScript table (`post' */ - /* table). The PostScript glyph names are */ - /* not loaded by the driver on face opening. */ - /* See the `ttpost' module for more details. */ - /* */ - /* cmap_table :: Address of the face's `cmap' SFNT table */ - /* in memory (it's an extracted frame). */ - /* */ - /* cmap_size :: The size in bytes of the `cmap_table' */ - /* described above. */ - /* */ - /* goto_table :: A function called by each TrueType table */ - /* loader to position a stream's cursor to */ - /* the start of a given table according to */ - /* its tag. It defaults to TT_Goto_Face but */ - /* can be different for strange formats (e.g. */ - /* Type 42). */ - /* */ - /* access_glyph_frame :: A function used to access the frame of a */ - /* given glyph within the face's font file. */ - /* */ - /* forget_glyph_frame :: A function used to forget the frame of a */ - /* given glyph when all data has been loaded. */ - /* */ - /* read_glyph_header :: A function used to read a glyph header. */ - /* It must be called between an `access' and */ - /* `forget'. */ - /* */ - /* read_simple_glyph :: A function used to read a simple glyph. */ - /* It must be called after the header was */ - /* read, and before the `forget'. */ - /* */ - /* read_composite_glyph :: A function used to read a composite glyph. */ - /* It must be called after the header was */ - /* read, and before the `forget'. */ - /* */ - /* sfnt :: A pointer to the SFNT service. */ - /* */ - /* psnames :: A pointer to the PostScript names service. */ - /* */ - /* mm :: A pointer to the Multiple Masters service. */ - /* */ - /* var :: A pointer to the Metrics Variations */ - /* service. */ - /* */ - /* hdmx :: The face's horizontal device metrics */ - /* (`hdmx' table). This table is optional in */ - /* TrueType/OpenType fonts. */ - /* */ - /* gasp :: The grid-fitting and scaling properties */ - /* table (`gasp'). This table is optional in */ - /* TrueType/OpenType fonts. */ - /* */ - /* pclt :: The `pclt' SFNT table. */ - /* */ - /* num_sbit_scales :: The number of sbit scales for this font. */ - /* */ - /* sbit_scales :: Array of sbit scales embedded in this */ - /* font. This table is optional in a */ - /* TrueType/OpenType font. */ - /* */ - /* postscript_names :: A table used to store the Postscript names */ - /* of the glyphs for this font. See the */ - /* file `ttconfig.h' for comments on the */ - /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES option. */ - /* */ - /* font_program_size :: Size in bytecodes of the face's font */ - /* program. 0 if none defined. Ignored for */ - /* Type 2 fonts. */ - /* */ - /* font_program :: The face's font program (bytecode stream) */ - /* executed at load time, also used during */ - /* glyph rendering. Comes from the `fpgm' */ - /* table. Ignored for Type 2 font fonts. */ - /* */ - /* cvt_program_size :: The size in bytecodes of the face's cvt */ - /* program. Ignored for Type 2 fonts. */ - /* */ - /* cvt_program :: The face's cvt program (bytecode stream) */ - /* executed each time an instance/size is */ - /* changed/reset. Comes from the `prep' */ - /* table. Ignored for Type 2 fonts. */ - /* */ - /* cvt_size :: Size of the control value table (in */ - /* entries). Ignored for Type 2 fonts. */ - /* */ - /* cvt :: The face's original control value table. */ - /* Coordinates are expressed in unscaled font */ - /* units. Comes from the `cvt ' table. */ - /* Ignored for Type 2 fonts. */ - /* */ - /* interpreter :: A pointer to the TrueType bytecode */ - /* interpreters field is also used to hook */ - /* the debugger in `ttdebug'. */ - /* */ - /* extra :: Reserved for third-party font drivers. */ - /* */ - /* postscript_name :: The PS name of the font. Used by the */ - /* postscript name service. */ - /* */ - /* glyf_len :: The length of the `glyf' table. Needed */ - /* for malformed `loca' tables. */ - /* */ - /* glyf_offset :: The file offset of the `glyf' table. */ - /* */ - /* is_cff2 :: Set if the font format is CFF2. */ - /* */ - /* doblend :: A boolean which is set if the font should */ - /* be blended (this is for GX var). */ - /* */ - /* blend :: Contains the data needed to control GX */ - /* variation tables (rather like Multiple */ - /* Master data). */ - /* */ - /* variation_support :: Flags that indicate which OpenType */ - /* functionality related to font variation */ - /* support is present, valid, and usable. */ - /* For example, TT_FACE_FLAG_VAR_FVAR is only */ - /* set if we have at least one design axis. */ - /* */ - /* var_postscript_prefix :: */ - /* The PostScript name prefix needed for */ - /* constructing a variation font instance's */ - /* PS name . */ - /* */ - /* var_postscript_prefix_len :: */ - /* The length of the `var_postscript_prefix' */ - /* string. */ - /* */ - /* horz_metrics_size :: The size of the `hmtx' table. */ - /* */ - /* vert_metrics_size :: The size of the `vmtx' table. */ - /* */ - /* num_locations :: The number of glyph locations in this */ - /* TrueType file. This should be */ - /* identical to the number of glyphs. */ - /* Ignored for Type 2 fonts. */ - /* */ - /* glyph_locations :: An array of longs. These are offsets to */ - /* glyph data within the `glyf' table. */ - /* Ignored for Type 2 font faces. */ - /* */ - /* hdmx_table :: A pointer to the `hdmx' table. */ - /* */ - /* hdmx_table_size :: The size of the `hdmx' table. */ - /* */ - /* hdmx_record_count :: The number of hdmx records. */ - /* */ - /* hdmx_record_size :: The size of a single hdmx record. */ - /* */ - /* hdmx_record_sizes :: An array holding the ppem sizes available */ - /* in the `hdmx' table. */ - /* */ - /* sbit_table :: A pointer to the font's embedded bitmap */ - /* location table. */ - /* */ - /* sbit_table_size :: The size of `sbit_table'. */ - /* */ - /* sbit_table_type :: The sbit table type (CBLC, sbix, etc.). */ - /* */ - /* sbit_num_strikes :: The number of sbit strikes exposed by */ - /* FreeType's API, omitting invalid strikes. */ - /* */ - /* sbit_strike_map :: A mapping between the strike indices */ - /* exposed by the API and the indices used in */ - /* the font's sbit table. */ - /* */ - /* kern_table :: A pointer to the `kern' table. */ - /* */ - /* kern_table_size :: The size of the `kern' table. */ - /* */ - /* num_kern_tables :: The number of supported kern subtables */ - /* (up to 32; FreeType recognizes only */ - /* horizontal ones with format 0). */ - /* */ - /* kern_avail_bits :: The availability status of kern subtables; */ - /* if bit n is set, table n is available. */ - /* */ - /* kern_order_bits :: The sortedness status of kern subtables; */ - /* if bit n is set, table n is sorted. */ - /* */ - /* bdf :: Data related to an SFNT font's `bdf' */ - /* table; see `tttypes.h'. */ - /* */ - /* horz_metrics_offset :: The file offset of the `hmtx' table. */ - /* */ - /* vert_metrics_offset :: The file offset of the `vmtx' table. */ - /* */ - /* sph_found_func_flags :: Flags identifying special bytecode */ - /* functions (used by the v38 implementation */ - /* of the bytecode interpreter). */ - /* */ - /* sph_compatibility_mode :: */ - /* This flag is set if we are in ClearType */ - /* backward compatibility mode (used by the */ - /* v38 implementation of the bytecode */ - /* interpreter). */ - /* */ - /* ebdt_start :: The file offset of the sbit data table */ - /* (CBDT, bdat, etc.). */ - /* */ - /* ebdt_size :: The size of the sbit data table. */ - /* */ + /************************************************************************** + * + * TrueType Face Type + * + * @struct: + * TT_Face + * + * @description: + * The TrueType face class. These objects model the resolution and + * point-size independent data found in a TrueType font file. + * + * @fields: + * root :: + * The base FT_Face structure, managed by the base layer. + * + * ttc_header :: + * The TrueType collection header, used when the file is a 'ttc' rather + * than a 'ttf'. For ordinary font files, the field `ttc_header.count` + * is set to 0. + * + * format_tag :: + * The font format tag. + * + * num_tables :: + * The number of TrueType tables in this font file. + * + * dir_tables :: + * The directory of TrueType tables for this font file. + * + * header :: + * The font's font header ('head' table). Read on font opening. + * + * horizontal :: + * The font's horizontal header ('hhea' table). This field also + * contains the associated horizontal metrics table ('hmtx'). + * + * max_profile :: + * The font's maximum profile table. Read on font opening. Note that + * some maximum values cannot be taken directly from this table. We + * thus define additional fields below to hold the computed maxima. + * + * vertical_info :: + * A boolean which is set when the font file contains vertical metrics. + * If not, the value of the 'vertical' field is undefined. + * + * vertical :: + * The font's vertical header ('vhea' table). This field also contains + * the associated vertical metrics table ('vmtx'), if found. + * IMPORTANT: The contents of this field is undefined if the + * `vertical_info` field is unset. + * + * num_names :: + * The number of name records within this TrueType font. + * + * name_table :: + * The table of name records ('name'). + * + * os2 :: + * The font's OS/2 table ('OS/2'). + * + * postscript :: + * The font's PostScript table ('post' table). The PostScript glyph + * names are not loaded by the driver on face opening. See the + * 'ttpost' module for more details. + * + * cmap_table :: + * Address of the face's 'cmap' SFNT table in memory (it's an extracted + * frame). + * + * cmap_size :: + * The size in bytes of the `cmap_table` described above. + * + * goto_table :: + * A function called by each TrueType table loader to position a + * stream's cursor to the start of a given table according to its tag. + * It defaults to TT_Goto_Face but can be different for strange formats + * (e.g. Type 42). + * + * access_glyph_frame :: + * A function used to access the frame of a given glyph within the + * face's font file. + * + * forget_glyph_frame :: + * A function used to forget the frame of a given glyph when all data + * has been loaded. + * + * read_glyph_header :: + * A function used to read a glyph header. It must be called between + * an 'access' and 'forget'. + * + * read_simple_glyph :: + * A function used to read a simple glyph. It must be called after the + * header was read, and before the 'forget'. + * + * read_composite_glyph :: + * A function used to read a composite glyph. It must be called after + * the header was read, and before the 'forget'. + * + * sfnt :: + * A pointer to the SFNT service. + * + * psnames :: + * A pointer to the PostScript names service. + * + * mm :: + * A pointer to the Multiple Masters service. + * + * var :: + * A pointer to the Metrics Variations service. + * + * hdmx :: + * The face's horizontal device metrics ('hdmx' table). This table is + * optional in TrueType/OpenType fonts. + * + * gasp :: + * The grid-fitting and scaling properties table ('gasp'). This table + * is optional in TrueType/OpenType fonts. + * + * pclt :: + * The 'pclt' SFNT table. + * + * num_sbit_scales :: + * The number of sbit scales for this font. + * + * sbit_scales :: + * Array of sbit scales embedded in this font. This table is optional + * in a TrueType/OpenType font. + * + * postscript_names :: + * A table used to store the Postscript names of the glyphs for this + * font. See the file `ttconfig.h` for comments on the + * TT_CONFIG_OPTION_POSTSCRIPT_NAMES option. + * + * palette_data :: + * Some fields from the 'CPAL' table that are directly indexed. + * + * palette_index :: + * The current palette index, as set by @FT_Palette_Select. + * + * palette :: + * An array containing the current palette's colors. + * + * have_foreground_color :: + * There was a call to @FT_Palette_Set_Foreground_Color. + * + * foreground_color :: + * The current foreground color corresponding to 'CPAL' color index + * 0xFFFF. Only valid if `have_foreground_color` is set. + * + * font_program_size :: + * Size in bytecodes of the face's font program. 0 if none defined. + * Ignored for Type 2 fonts. + * + * font_program :: + * The face's font program (bytecode stream) executed at load time, + * also used during glyph rendering. Comes from the 'fpgm' table. + * Ignored for Type 2 font fonts. + * + * cvt_program_size :: + * The size in bytecodes of the face's cvt program. Ignored for Type 2 + * fonts. + * + * cvt_program :: + * The face's cvt program (bytecode stream) executed each time an + * instance/size is changed/reset. Comes from the 'prep' table. + * Ignored for Type 2 fonts. + * + * cvt_size :: + * Size of the control value table (in entries). Ignored for Type 2 + * fonts. + * + * cvt :: + * The face's original control value table. Coordinates are expressed + * in unscaled font units. Comes from the 'cvt~' table. Ignored for + * Type 2 fonts. + * + * interpreter :: + * A pointer to the TrueType bytecode interpreters field is also used + * to hook the debugger in 'ttdebug'. + * + * extra :: + * Reserved for third-party font drivers. + * + * postscript_name :: + * The PS name of the font. Used by the postscript name service. + * + * glyf_len :: + * The length of the 'glyf' table. Needed for malformed 'loca' tables. + * + * glyf_offset :: + * The file offset of the 'glyf' table. + * + * is_cff2 :: + * Set if the font format is CFF2. + * + * doblend :: + * A boolean which is set if the font should be blended (this is for GX + * var). + * + * blend :: + * Contains the data needed to control GX variation tables (rather like + * Multiple Master data). + * + * variation_support :: + * Flags that indicate which OpenType functionality related to font + * variation support is present, valid, and usable. For example, + * TT_FACE_FLAG_VAR_FVAR is only set if we have at least one design + * axis. + * + * var_postscript_prefix :: + * The PostScript name prefix needed for constructing a variation font + * instance's PS name . + * + * var_postscript_prefix_len :: + * The length of the `var_postscript_prefix` string. + * + * horz_metrics_size :: + * The size of the 'hmtx' table. + * + * vert_metrics_size :: + * The size of the 'vmtx' table. + * + * num_locations :: + * The number of glyph locations in this TrueType file. This should be + * identical to the number of glyphs. Ignored for Type 2 fonts. + * + * glyph_locations :: + * An array of longs. These are offsets to glyph data within the + * 'glyf' table. Ignored for Type 2 font faces. + * + * hdmx_table :: + * A pointer to the 'hdmx' table. + * + * hdmx_table_size :: + * The size of the 'hdmx' table. + * + * hdmx_record_count :: + * The number of hdmx records. + * + * hdmx_record_size :: + * The size of a single hdmx record. + * + * hdmx_record_sizes :: + * An array holding the ppem sizes available in the 'hdmx' table. + * + * sbit_table :: + * A pointer to the font's embedded bitmap location table. + * + * sbit_table_size :: + * The size of `sbit_table`. + * + * sbit_table_type :: + * The sbit table type (CBLC, sbix, etc.). + * + * sbit_num_strikes :: + * The number of sbit strikes exposed by FreeType's API, omitting + * invalid strikes. + * + * sbit_strike_map :: + * A mapping between the strike indices exposed by the API and the + * indices used in the font's sbit table. + * + * cpal :: + * A pointer to data related to the 'CPAL' table. `NULL` if the table + * is not available. + * + * colr :: + * A pointer to data related to the 'COLR' table. `NULL` if the table + * is not available. + * + * kern_table :: + * A pointer to the 'kern' table. + * + * kern_table_size :: + * The size of the 'kern' table. + * + * num_kern_tables :: + * The number of supported kern subtables (up to 32; FreeType + * recognizes only horizontal ones with format 0). + * + * kern_avail_bits :: + * The availability status of kern subtables; if bit n is set, table n + * is available. + * + * kern_order_bits :: + * The sortedness status of kern subtables; if bit n is set, table n is + * sorted. + * + * bdf :: + * Data related to an SFNT font's 'bdf' table; see `tttypes.h`. + * + * horz_metrics_offset :: + * The file offset of the 'hmtx' table. + * + * vert_metrics_offset :: + * The file offset of the 'vmtx' table. + * + * sph_found_func_flags :: + * Flags identifying special bytecode functions (used by the v38 + * implementation of the bytecode interpreter). + * + * sph_compatibility_mode :: + * This flag is set if we are in ClearType backward compatibility mode + * (used by the v38 implementation of the bytecode interpreter). + * + * ebdt_start :: + * The file offset of the sbit data table (CBDT, bdat, etc.). + * + * ebdt_size :: + * The size of the sbit data table. + */ typedef struct TT_FaceRec_ { FT_FaceRec root; @@ -1445,11 +1590,11 @@ FT_BEGIN_HEADER void* psaux; - /***********************************************************************/ - /* */ - /* Optional TrueType/OpenType tables */ - /* */ - /***********************************************************************/ + /************************************************************************ + * + * Optional TrueType/OpenType tables + * + */ /* grid-fitting and scaling table */ TT_GaspRec gasp; /* the `gasp' table */ @@ -1464,12 +1609,19 @@ FT_BEGIN_HEADER /* postscript names table */ TT_Post_NamesRec postscript_names; + /* glyph colors */ + FT_Palette_Data palette_data; /* since 2.10 */ + FT_UShort palette_index; + FT_Color* palette; + FT_Bool have_foreground_color; + FT_Color foreground_color; + - /***********************************************************************/ - /* */ - /* TrueType-specific fields (ignored by the CFF driver) */ - /* */ - /***********************************************************************/ + /************************************************************************ + * + * TrueType-specific fields (ignored by the CFF driver) + * + */ /* the font program, if any */ FT_ULong font_program_size; @@ -1488,12 +1640,12 @@ FT_BEGIN_HEADER TT_Interpreter interpreter; - /***********************************************************************/ - /* */ - /* Other tables or fields. This is used by derivative formats like */ - /* OpenType. */ - /* */ - /***********************************************************************/ + /************************************************************************ + * + * Other tables or fields. This is used by derivative formats like + * OpenType. + * + */ FT_Generic extra; @@ -1562,40 +1714,53 @@ FT_BEGIN_HEADER FT_ULong ebdt_size; #endif + /* since 2.10 */ + void* cpal; + void* colr; + } TT_FaceRec; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_GlyphZoneRec */ - /* */ - /* <Description> */ - /* A glyph zone is used to load, scale and hint glyph outline */ - /* coordinates. */ - /* */ - /* <Fields> */ - /* memory :: A handle to the memory manager. */ - /* */ - /* max_points :: The maximum size in points of the zone. */ - /* */ - /* max_contours :: Max size in links contours of the zone. */ - /* */ - /* n_points :: The current number of points in the zone. */ - /* */ - /* n_contours :: The current number of contours in the zone. */ - /* */ - /* org :: The original glyph coordinates (font */ - /* units/scaled). */ - /* */ - /* cur :: The current glyph coordinates (scaled/hinted). */ - /* */ - /* tags :: The point control tags. */ - /* */ - /* contours :: The contours end points. */ - /* */ - /* first_point :: Offset of the current subglyph's first point. */ - /* */ + /************************************************************************** + * + * @struct: + * TT_GlyphZoneRec + * + * @description: + * A glyph zone is used to load, scale and hint glyph outline + * coordinates. + * + * @fields: + * memory :: + * A handle to the memory manager. + * + * max_points :: + * The maximum size in points of the zone. + * + * max_contours :: + * Max size in links contours of the zone. + * + * n_points :: + * The current number of points in the zone. + * + * n_contours :: + * The current number of contours in the zone. + * + * org :: + * The original glyph coordinates (font units/scaled). + * + * cur :: + * The current glyph coordinates (scaled/hinted). + * + * tags :: + * The point control tags. + * + * contours :: + * The contours end points. + * + * first_point :: + * Offset of the current subglyph's first point. + */ typedef struct TT_GlyphZoneRec_ { FT_Memory memory; @@ -1620,14 +1785,14 @@ FT_BEGIN_HEADER typedef struct TT_ExecContextRec_* TT_ExecContext; - /*************************************************************************/ - /* */ - /* <Type> */ - /* TT_Size */ - /* */ - /* <Description> */ - /* A handle to a TrueType size object. */ - /* */ + /************************************************************************** + * + * @type: + * TT_Size + * + * @description: + * A handle to a TrueType size object. + */ typedef struct TT_SizeRec_* TT_Size; diff --git a/sdk/lib/3rdparty/freetype/include/freetype/t1tables.h b/sdk/lib/3rdparty/freetype/include/freetype/t1tables.h index 3503c2616bdd5..645e6457201de 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/t1tables.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/t1tables.h @@ -1,20 +1,20 @@ -/***************************************************************************/ -/* */ -/* t1tables.h */ -/* */ -/* Basic Type 1/Type 2 tables definitions and interface (specification */ -/* only). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * t1tables.h + * + * Basic Type 1/Type 2 tables definitions and interface (specification + * only). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef T1TABLES_H_ @@ -34,58 +34,58 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* <Section> */ - /* type1_tables */ - /* */ - /* <Title> */ - /* Type 1 Tables */ - /* */ - /* <Abstract> */ - /* Type~1 (PostScript) specific font tables. */ - /* */ - /* <Description> */ - /* This section contains the definition of Type 1-specific tables, */ - /* including structures related to other PostScript font formats. */ - /* */ - /* <Order> */ - /* PS_FontInfoRec */ - /* PS_FontInfo */ - /* PS_PrivateRec */ - /* PS_Private */ - /* */ - /* CID_FaceDictRec */ - /* CID_FaceDict */ - /* CID_FaceInfoRec */ - /* CID_FaceInfo */ - /* */ - /* FT_Has_PS_Glyph_Names */ - /* FT_Get_PS_Font_Info */ - /* FT_Get_PS_Font_Private */ - /* FT_Get_PS_Font_Value */ - /* */ - /* T1_Blend_Flags */ - /* T1_EncodingType */ - /* PS_Dict_Keys */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * @section: + * type1_tables + * + * @title: + * Type 1 Tables + * + * @abstract: + * Type~1-specific font tables. + * + * @description: + * This section contains the definition of Type~1-specific tables, + * including structures related to other PostScript font formats. + * + * @order: + * PS_FontInfoRec + * PS_FontInfo + * PS_PrivateRec + * PS_Private + * + * CID_FaceDictRec + * CID_FaceDict + * CID_FaceInfoRec + * CID_FaceInfo + * + * FT_Has_PS_Glyph_Names + * FT_Get_PS_Font_Info + * FT_Get_PS_Font_Private + * FT_Get_PS_Font_Value + * + * T1_Blend_Flags + * T1_EncodingType + * PS_Dict_Keys + * + */ /* Note that we separate font data in PS_FontInfoRec and PS_PrivateRec */ /* structures in order to support Multiple Master fonts. */ - /*************************************************************************/ - /* */ - /* <Struct> */ - /* PS_FontInfoRec */ - /* */ - /* <Description> */ - /* A structure used to model a Type~1 or Type~2 FontInfo dictionary. */ - /* Note that for Multiple Master fonts, each instance has its own */ - /* FontInfo dictionary. */ - /* */ + /************************************************************************** + * + * @struct: + * PS_FontInfoRec + * + * @description: + * A structure used to model a Type~1 or Type~2 FontInfo dictionary. + * Note that for Multiple Master fonts, each instance has its own + * FontInfo dictionary. + */ typedef struct PS_FontInfoRec_ { FT_String* version; @@ -101,40 +101,39 @@ FT_BEGIN_HEADER } PS_FontInfoRec; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* PS_FontInfo */ - /* */ - /* <Description> */ - /* A handle to a @PS_FontInfoRec structure. */ - /* */ + /************************************************************************** + * + * @struct: + * PS_FontInfo + * + * @description: + * A handle to a @PS_FontInfoRec structure. + */ typedef struct PS_FontInfoRec_* PS_FontInfo; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* T1_FontInfo */ - /* */ - /* <Description> */ - /* This type is equivalent to @PS_FontInfoRec. It is deprecated but */ - /* kept to maintain source compatibility between various versions of */ - /* FreeType. */ - /* */ + /************************************************************************** + * + * @struct: + * T1_FontInfo + * + * @description: + * This type is equivalent to @PS_FontInfoRec. It is deprecated but kept + * to maintain source compatibility between various versions of FreeType. + */ typedef PS_FontInfoRec T1_FontInfo; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* PS_PrivateRec */ - /* */ - /* <Description> */ - /* A structure used to model a Type~1 or Type~2 private dictionary. */ - /* Note that for Multiple Master fonts, each instance has its own */ - /* Private dictionary. */ - /* */ + /************************************************************************** + * + * @struct: + * PS_PrivateRec + * + * @description: + * A structure used to model a Type~1 or Type~2 private dictionary. Note + * that for Multiple Master fonts, each instance has its own Private + * dictionary. + */ typedef struct PS_PrivateRec_ { FT_Int unique_id; @@ -176,56 +175,55 @@ FT_BEGIN_HEADER } PS_PrivateRec; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* PS_Private */ - /* */ - /* <Description> */ - /* A handle to a @PS_PrivateRec structure. */ - /* */ + /************************************************************************** + * + * @struct: + * PS_Private + * + * @description: + * A handle to a @PS_PrivateRec structure. + */ typedef struct PS_PrivateRec_* PS_Private; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* T1_Private */ - /* */ - /* <Description> */ - /* This type is equivalent to @PS_PrivateRec. It is deprecated but */ - /* kept to maintain source compatibility between various versions of */ - /* FreeType. */ - /* */ + /************************************************************************** + * + * @struct: + * T1_Private + * + * @description: + * This type is equivalent to @PS_PrivateRec. It is deprecated but kept + * to maintain source compatibility between various versions of FreeType. + */ typedef PS_PrivateRec T1_Private; - /*************************************************************************/ - /* */ - /* <Enum> */ - /* T1_Blend_Flags */ - /* */ - /* <Description> */ - /* A set of flags used to indicate which fields are present in a */ - /* given blend dictionary (font info or private). Used to support */ - /* Multiple Masters fonts. */ - /* */ - /* <Values> */ - /* T1_BLEND_UNDERLINE_POSITION :: */ - /* T1_BLEND_UNDERLINE_THICKNESS :: */ - /* T1_BLEND_ITALIC_ANGLE :: */ - /* T1_BLEND_BLUE_VALUES :: */ - /* T1_BLEND_OTHER_BLUES :: */ - /* T1_BLEND_STANDARD_WIDTH :: */ - /* T1_BLEND_STANDARD_HEIGHT :: */ - /* T1_BLEND_STEM_SNAP_WIDTHS :: */ - /* T1_BLEND_STEM_SNAP_HEIGHTS :: */ - /* T1_BLEND_BLUE_SCALE :: */ - /* T1_BLEND_BLUE_SHIFT :: */ - /* T1_BLEND_FAMILY_BLUES :: */ - /* T1_BLEND_FAMILY_OTHER_BLUES :: */ - /* T1_BLEND_FORCE_BOLD :: */ - /* */ + /************************************************************************** + * + * @enum: + * T1_Blend_Flags + * + * @description: + * A set of flags used to indicate which fields are present in a given + * blend dictionary (font info or private). Used to support Multiple + * Masters fonts. + * + * @values: + * T1_BLEND_UNDERLINE_POSITION :: + * T1_BLEND_UNDERLINE_THICKNESS :: + * T1_BLEND_ITALIC_ANGLE :: + * T1_BLEND_BLUE_VALUES :: + * T1_BLEND_OTHER_BLUES :: + * T1_BLEND_STANDARD_WIDTH :: + * T1_BLEND_STANDARD_HEIGHT :: + * T1_BLEND_STEM_SNAP_WIDTHS :: + * T1_BLEND_STEM_SNAP_HEIGHTS :: + * T1_BLEND_BLUE_SCALE :: + * T1_BLEND_BLUE_SHIFT :: + * T1_BLEND_FAMILY_BLUES :: + * T1_BLEND_FAMILY_OTHER_BLUES :: + * T1_BLEND_FORCE_BOLD :: + */ typedef enum T1_Blend_Flags_ { /* required fields in a FontInfo blend dictionary */ @@ -252,7 +250,7 @@ FT_BEGIN_HEADER /* these constants are deprecated; use the corresponding */ - /* `T1_Blend_Flags' values instead */ + /* `T1_Blend_Flags` values instead */ #define t1_blend_underline_position T1_BLEND_UNDERLINE_POSITION #define t1_blend_underline_thickness T1_BLEND_UNDERLINE_THICKNESS #define t1_blend_italic_angle T1_BLEND_ITALIC_ANGLE @@ -330,14 +328,23 @@ FT_BEGIN_HEADER typedef PS_BlendRec T1_Blend; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* CID_FaceDictRec */ - /* */ - /* <Description> */ - /* A structure used to represent data in a CID top-level dictionary. */ - /* */ + /************************************************************************** + * + * @struct: + * CID_FaceDictRec + * + * @description: + * A structure used to represent data in a CID top-level dictionary. In + * most cases, they are part of the font's '/FDArray' array. Within a + * CID font file, such (internal) subfont dictionaries are enclosed by + * '%ADOBeginFontDict' and '%ADOEndFontDict' comments. + * + * Note that `CID_FaceDictRec` misses a field for the '/FontName' + * keyword, specifying the subfont's name (the top-level font name is + * given by the '/CIDFontName' keyword). This is an oversight, but it + * doesn't limit the 'cid' font module's functionality because FreeType + * neither needs this entry nor gives access to CID subfonts. + */ typedef struct CID_FaceDictRec_ { PS_PrivateRec private_dict; @@ -345,8 +352,8 @@ FT_BEGIN_HEADER FT_UInt len_buildchar; FT_Fixed forcebold_threshold; FT_Pos stroke_width; - FT_Fixed expansion_factor; - + FT_Fixed expansion_factor; /* this is a duplicate of */ + /* `private_dict->expansion_factor' */ FT_Byte paint_type; FT_Byte font_type; FT_Matrix font_matrix; @@ -359,38 +366,38 @@ FT_BEGIN_HEADER } CID_FaceDictRec; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* CID_FaceDict */ - /* */ - /* <Description> */ - /* A handle to a @CID_FaceDictRec structure. */ - /* */ + /************************************************************************** + * + * @struct: + * CID_FaceDict + * + * @description: + * A handle to a @CID_FaceDictRec structure. + */ typedef struct CID_FaceDictRec_* CID_FaceDict; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* CID_FontDict */ - /* */ - /* <Description> */ - /* This type is equivalent to @CID_FaceDictRec. It is deprecated but */ - /* kept to maintain source compatibility between various versions of */ - /* FreeType. */ - /* */ + /************************************************************************** + * + * @struct: + * CID_FontDict + * + * @description: + * This type is equivalent to @CID_FaceDictRec. It is deprecated but + * kept to maintain source compatibility between various versions of + * FreeType. + */ typedef CID_FaceDictRec CID_FontDict; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* CID_FaceInfoRec */ - /* */ - /* <Description> */ - /* A structure used to represent CID Face information. */ - /* */ + /************************************************************************** + * + * @struct: + * CID_FaceInfoRec + * + * @description: + * A structure used to represent CID Face information. + */ typedef struct CID_FaceInfoRec_ { FT_String* cid_font_name; @@ -421,47 +428,45 @@ FT_BEGIN_HEADER } CID_FaceInfoRec; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* CID_FaceInfo */ - /* */ - /* <Description> */ - /* A handle to a @CID_FaceInfoRec structure. */ - /* */ + /************************************************************************** + * + * @struct: + * CID_FaceInfo + * + * @description: + * A handle to a @CID_FaceInfoRec structure. + */ typedef struct CID_FaceInfoRec_* CID_FaceInfo; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* CID_Info */ - /* */ - /* <Description> */ - /* This type is equivalent to @CID_FaceInfoRec. It is deprecated but */ - /* kept to maintain source compatibility between various versions of */ - /* FreeType. */ - /* */ + /************************************************************************** + * + * @struct: + * CID_Info + * + * @description: + * This type is equivalent to @CID_FaceInfoRec. It is deprecated but kept + * to maintain source compatibility between various versions of FreeType. + */ typedef CID_FaceInfoRec CID_Info; - /************************************************************************ + /************************************************************************** * * @function: * FT_Has_PS_Glyph_Names * * @description: - * Return true if a given face provides reliable PostScript glyph - * names. This is similar to using the @FT_HAS_GLYPH_NAMES macro, - * except that certain fonts (mostly TrueType) contain incorrect - * glyph name tables. + * Return true if a given face provides reliable PostScript glyph names. + * This is similar to using the @FT_HAS_GLYPH_NAMES macro, except that + * certain fonts (mostly TrueType) contain incorrect glyph name tables. * * When this function returns true, the caller is sure that the glyph * names returned by @FT_Get_Glyph_Name are reliable. * * @input: * face :: - * face handle + * face handle * * @return: * Boolean. True if glyph names are reliable. @@ -471,7 +476,7 @@ FT_BEGIN_HEADER FT_Has_PS_Glyph_Names( FT_Face face ); - /************************************************************************ + /************************************************************************** * * @function: * FT_Get_PS_Font_Info @@ -482,22 +487,22 @@ FT_BEGIN_HEADER * * @input: * face :: - * PostScript face handle. + * PostScript face handle. * * @output: * afont_info :: - * Output font info structure pointer. + * Output font info structure pointer. * * @return: * FreeType error code. 0~means success. * * @note: - * String pointers within the @PS_FontInfoRec structure are owned by - * the face and don't need to be freed by the caller. Missing entries - * in the font's FontInfo dictionary are represented by NULL pointers. + * String pointers within the @PS_FontInfoRec structure are owned by the + * face and don't need to be freed by the caller. Missing entries in + * the font's FontInfo dictionary are represented by `NULL` pointers. * * If the font's format is not PostScript-based, this function will - * return the `FT_Err_Invalid_Argument' error code. + * return the `FT_Err_Invalid_Argument` error code. * */ FT_EXPORT( FT_Error ) @@ -505,7 +510,7 @@ FT_BEGIN_HEADER PS_FontInfo afont_info ); - /************************************************************************ + /************************************************************************** * * @function: * FT_Get_PS_Font_Private @@ -516,11 +521,11 @@ FT_BEGIN_HEADER * * @input: * face :: - * PostScript face handle. + * PostScript face handle. * * @output: * afont_private :: - * Output private dictionary structure pointer. + * Output private dictionary structure pointer. * * @return: * FreeType error code. 0~means success. @@ -530,7 +535,7 @@ FT_BEGIN_HEADER * the face and don't need to be freed by the caller. * * If the font's format is not PostScript-based, this function returns - * the `FT_Err_Invalid_Argument' error code. + * the `FT_Err_Invalid_Argument` error code. * */ FT_EXPORT( FT_Error ) @@ -538,25 +543,24 @@ FT_BEGIN_HEADER PS_Private afont_private ); - /*************************************************************************/ - /* */ - /* <Enum> */ - /* T1_EncodingType */ - /* */ - /* <Description> */ - /* An enumeration describing the `Encoding' entry in a Type 1 */ - /* dictionary. */ - /* */ - /* <Values> */ - /* T1_ENCODING_TYPE_NONE :: */ - /* T1_ENCODING_TYPE_ARRAY :: */ - /* T1_ENCODING_TYPE_STANDARD :: */ - /* T1_ENCODING_TYPE_ISOLATIN1 :: */ - /* T1_ENCODING_TYPE_EXPERT :: */ - /* */ - /* <Since> */ - /* 2.4.8 */ - /* */ + /************************************************************************** + * + * @enum: + * T1_EncodingType + * + * @description: + * An enumeration describing the 'Encoding' entry in a Type 1 dictionary. + * + * @values: + * T1_ENCODING_TYPE_NONE :: + * T1_ENCODING_TYPE_ARRAY :: + * T1_ENCODING_TYPE_STANDARD :: + * T1_ENCODING_TYPE_ISOLATIN1 :: + * T1_ENCODING_TYPE_EXPERT :: + * + * @since: + * 2.4.8 + */ typedef enum T1_EncodingType_ { T1_ENCODING_TYPE_NONE = 0, @@ -568,66 +572,66 @@ FT_BEGIN_HEADER } T1_EncodingType; - /*************************************************************************/ - /* */ - /* <Enum> */ - /* PS_Dict_Keys */ - /* */ - /* <Description> */ - /* An enumeration used in calls to @FT_Get_PS_Font_Value to identify */ - /* the Type~1 dictionary entry to retrieve. */ - /* */ - /* <Values> */ - /* PS_DICT_FONT_TYPE :: */ - /* PS_DICT_FONT_MATRIX :: */ - /* PS_DICT_FONT_BBOX :: */ - /* PS_DICT_PAINT_TYPE :: */ - /* PS_DICT_FONT_NAME :: */ - /* PS_DICT_UNIQUE_ID :: */ - /* PS_DICT_NUM_CHAR_STRINGS :: */ - /* PS_DICT_CHAR_STRING_KEY :: */ - /* PS_DICT_CHAR_STRING :: */ - /* PS_DICT_ENCODING_TYPE :: */ - /* PS_DICT_ENCODING_ENTRY :: */ - /* PS_DICT_NUM_SUBRS :: */ - /* PS_DICT_SUBR :: */ - /* PS_DICT_STD_HW :: */ - /* PS_DICT_STD_VW :: */ - /* PS_DICT_NUM_BLUE_VALUES :: */ - /* PS_DICT_BLUE_VALUE :: */ - /* PS_DICT_BLUE_FUZZ :: */ - /* PS_DICT_NUM_OTHER_BLUES :: */ - /* PS_DICT_OTHER_BLUE :: */ - /* PS_DICT_NUM_FAMILY_BLUES :: */ - /* PS_DICT_FAMILY_BLUE :: */ - /* PS_DICT_NUM_FAMILY_OTHER_BLUES :: */ - /* PS_DICT_FAMILY_OTHER_BLUE :: */ - /* PS_DICT_BLUE_SCALE :: */ - /* PS_DICT_BLUE_SHIFT :: */ - /* PS_DICT_NUM_STEM_SNAP_H :: */ - /* PS_DICT_STEM_SNAP_H :: */ - /* PS_DICT_NUM_STEM_SNAP_V :: */ - /* PS_DICT_STEM_SNAP_V :: */ - /* PS_DICT_FORCE_BOLD :: */ - /* PS_DICT_RND_STEM_UP :: */ - /* PS_DICT_MIN_FEATURE :: */ - /* PS_DICT_LEN_IV :: */ - /* PS_DICT_PASSWORD :: */ - /* PS_DICT_LANGUAGE_GROUP :: */ - /* PS_DICT_VERSION :: */ - /* PS_DICT_NOTICE :: */ - /* PS_DICT_FULL_NAME :: */ - /* PS_DICT_FAMILY_NAME :: */ - /* PS_DICT_WEIGHT :: */ - /* PS_DICT_IS_FIXED_PITCH :: */ - /* PS_DICT_UNDERLINE_POSITION :: */ - /* PS_DICT_UNDERLINE_THICKNESS :: */ - /* PS_DICT_FS_TYPE :: */ - /* PS_DICT_ITALIC_ANGLE :: */ - /* */ - /* <Since> */ - /* 2.4.8 */ - /* */ + /************************************************************************** + * + * @enum: + * PS_Dict_Keys + * + * @description: + * An enumeration used in calls to @FT_Get_PS_Font_Value to identify the + * Type~1 dictionary entry to retrieve. + * + * @values: + * PS_DICT_FONT_TYPE :: + * PS_DICT_FONT_MATRIX :: + * PS_DICT_FONT_BBOX :: + * PS_DICT_PAINT_TYPE :: + * PS_DICT_FONT_NAME :: + * PS_DICT_UNIQUE_ID :: + * PS_DICT_NUM_CHAR_STRINGS :: + * PS_DICT_CHAR_STRING_KEY :: + * PS_DICT_CHAR_STRING :: + * PS_DICT_ENCODING_TYPE :: + * PS_DICT_ENCODING_ENTRY :: + * PS_DICT_NUM_SUBRS :: + * PS_DICT_SUBR :: + * PS_DICT_STD_HW :: + * PS_DICT_STD_VW :: + * PS_DICT_NUM_BLUE_VALUES :: + * PS_DICT_BLUE_VALUE :: + * PS_DICT_BLUE_FUZZ :: + * PS_DICT_NUM_OTHER_BLUES :: + * PS_DICT_OTHER_BLUE :: + * PS_DICT_NUM_FAMILY_BLUES :: + * PS_DICT_FAMILY_BLUE :: + * PS_DICT_NUM_FAMILY_OTHER_BLUES :: + * PS_DICT_FAMILY_OTHER_BLUE :: + * PS_DICT_BLUE_SCALE :: + * PS_DICT_BLUE_SHIFT :: + * PS_DICT_NUM_STEM_SNAP_H :: + * PS_DICT_STEM_SNAP_H :: + * PS_DICT_NUM_STEM_SNAP_V :: + * PS_DICT_STEM_SNAP_V :: + * PS_DICT_FORCE_BOLD :: + * PS_DICT_RND_STEM_UP :: + * PS_DICT_MIN_FEATURE :: + * PS_DICT_LEN_IV :: + * PS_DICT_PASSWORD :: + * PS_DICT_LANGUAGE_GROUP :: + * PS_DICT_VERSION :: + * PS_DICT_NOTICE :: + * PS_DICT_FULL_NAME :: + * PS_DICT_FAMILY_NAME :: + * PS_DICT_WEIGHT :: + * PS_DICT_IS_FIXED_PITCH :: + * PS_DICT_UNDERLINE_POSITION :: + * PS_DICT_UNDERLINE_THICKNESS :: + * PS_DICT_FS_TYPE :: + * PS_DICT_ITALIC_ANGLE :: + * + * @since: + * 2.4.8 + */ typedef enum PS_Dict_Keys_ { /* conventionally in the font dictionary */ @@ -687,7 +691,7 @@ FT_BEGIN_HEADER } PS_Dict_Keys; - /************************************************************************ + /************************************************************************** * * @function: * FT_Get_PS_Font_Value @@ -697,57 +701,57 @@ FT_BEGIN_HEADER * * @input: * face :: - * PostScript face handle. + * PostScript face handle. * * key :: - * An enumeration value representing the dictionary key to retrieve. + * An enumeration value representing the dictionary key to retrieve. * * idx :: - * For array values, this specifies the index to be returned. + * For array values, this specifies the index to be returned. * * value :: - * A pointer to memory into which to write the value. + * A pointer to memory into which to write the value. * * valen_len :: - * The size, in bytes, of the memory supplied for the value. + * The size, in bytes, of the memory supplied for the value. * * @output: * value :: - * The value matching the above key, if it exists. + * The value matching the above key, if it exists. * * @return: - * The amount of memory (in bytes) required to hold the requested - * value (if it exists, -1 otherwise). + * The amount of memory (in bytes) required to hold the requested value + * (if it exists, -1 otherwise). * * @note: * The values returned are not pointers into the internal structures of - * the face, but are `fresh' copies, so that the memory containing them + * the face, but are 'fresh' copies, so that the memory containing them * belongs to the calling application. This also enforces the - * `read-only' nature of these values, i.e., this function cannot be + * 'read-only' nature of these values, i.e., this function cannot be * used to manipulate the face. * - * `value' is a void pointer because the values returned can be of + * `value` is a void pointer because the values returned can be of * various types. * - * If either `value' is NULL or `value_len' is too small, just the + * If either `value` is `NULL` or `value_len` is too small, just the * required memory size for the requested entry is returned. * - * The `idx' parameter is used, not only to retrieve elements of, for + * The `idx` parameter is used, not only to retrieve elements of, for * example, the FontMatrix or FontBBox, but also to retrieve name keys * from the CharStrings dictionary, and the charstrings themselves. It * is ignored for atomic values. * - * PS_DICT_BLUE_SCALE returns a value that is scaled up by 1000. To - * get the value as in the font stream, you need to divide by - * 65536000.0 (to remove the FT_Fixed scale, and the x1000 scale). + * `PS_DICT_BLUE_SCALE` returns a value that is scaled up by 1000. To + * get the value as in the font stream, you need to divide by 65536000.0 + * (to remove the FT_Fixed scale, and the x1000 scale). * * IMPORTANT: Only key/value pairs read by the FreeType interpreter can - * be retrieved. So, for example, PostScript procedures such as NP, - * ND, and RD are not available. Arbitrary keys are, obviously, not be + * be retrieved. So, for example, PostScript procedures such as NP, ND, + * and RD are not available. Arbitrary keys are, obviously, not be * available either. * * If the font's format is not PostScript-based, this function returns - * the `FT_Err_Invalid_Argument' error code. + * the `FT_Err_Invalid_Argument` error code. * * @since: * 2.4.8 diff --git a/sdk/lib/3rdparty/freetype/include/freetype/ttnameid.h b/sdk/lib/3rdparty/freetype/include/freetype/ttnameid.h index 8605183dc700b..cc677de75adc6 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/ttnameid.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/ttnameid.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ttnameid.h */ -/* */ -/* TrueType name ID definitions (specification only). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ttnameid.h + * + * TrueType name ID definitions (specification only). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef TTNAMEID_H_ @@ -26,53 +26,54 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* <Section> */ - /* truetype_tables */ - /* */ + /************************************************************************** + * + * @section: + * truetype_tables + */ - /*************************************************************************/ - /* */ - /* Possible values for the `platform' identifier code in the name */ - /* records of an SFNT `name' table. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * Possible values for the 'platform' identifier code in the name records + * of an SFNT 'name' table. + * + */ - /*********************************************************************** + /************************************************************************** * * @enum: * TT_PLATFORM_XXX * * @description: - * A list of valid values for the `platform_id' identifier code in + * A list of valid values for the `platform_id` identifier code in * @FT_CharMapRec and @FT_SfntName structures. * * @values: * TT_PLATFORM_APPLE_UNICODE :: * Used by Apple to indicate a Unicode character map and/or name entry. - * See @TT_APPLE_ID_XXX for corresponding `encoding_id' values. Note + * See @TT_APPLE_ID_XXX for corresponding `encoding_id` values. Note * that name entries in this format are coded as big-endian UCS-2 * character codes _only_. * * TT_PLATFORM_MACINTOSH :: - * Used by Apple to indicate a MacOS-specific charmap and/or name entry. - * See @TT_MAC_ID_XXX for corresponding `encoding_id' values. Note that - * most TrueType fonts contain an Apple roman charmap to be usable on - * MacOS systems (even if they contain a Microsoft charmap as well). + * Used by Apple to indicate a MacOS-specific charmap and/or name + * entry. See @TT_MAC_ID_XXX for corresponding `encoding_id` values. + * Note that most TrueType fonts contain an Apple roman charmap to be + * usable on MacOS systems (even if they contain a Microsoft charmap as + * well). * * TT_PLATFORM_ISO :: - * This value was used to specify ISO/IEC 10646 charmaps. It is however - * now deprecated. See @TT_ISO_ID_XXX for a list of corresponding - * `encoding_id' values. + * This value was used to specify ISO/IEC 10646 charmaps. It is + * however now deprecated. See @TT_ISO_ID_XXX for a list of + * corresponding `encoding_id` values. * * TT_PLATFORM_MICROSOFT :: * Used by Microsoft to indicate Windows-specific charmaps. See - * @TT_MS_ID_XXX for a list of corresponding `encoding_id' values. + * @TT_MS_ID_XXX for a list of corresponding `encoding_id` values. * Note that most fonts contain a Unicode charmap using - * (TT_PLATFORM_MICROSOFT, @TT_MS_ID_UNICODE_CS). + * (`TT_PLATFORM_MICROSOFT`, @TT_MS_ID_UNICODE_CS). * * TT_PLATFORM_CUSTOM :: * Used to indicate application-specific charmaps. @@ -91,13 +92,13 @@ FT_BEGIN_HEADER #define TT_PLATFORM_ADOBE 7 /* artificial */ - /*********************************************************************** + /************************************************************************** * * @enum: * TT_APPLE_ID_XXX * * @description: - * A list of valid values for the `encoding_id' for + * A list of valid values for the `encoding_id` for * @TT_PLATFORM_APPLE_UNICODE charmaps and name entries. * * @values: @@ -117,8 +118,8 @@ FT_BEGIN_HEADER * Unicode 3.1 and beyond, using UTF-32. * * TT_APPLE_ID_VARIANT_SELECTOR :: - * From Adobe, not Apple. Not a normal cmap. Specifies variations - * on a real cmap. + * From Adobe, not Apple. Not a normal cmap. Specifies variations on + * a real cmap. * * TT_APPLE_ID_FULL_UNICODE :: * Used for fallback fonts that provide complete Unicode coverage with @@ -134,13 +135,13 @@ FT_BEGIN_HEADER #define TT_APPLE_ID_FULL_UNICODE 6 /* used with type 13 cmaps */ - /*********************************************************************** + /************************************************************************** * * @enum: * TT_MAC_ID_XXX * * @description: - * A list of valid values for the `encoding_id' for + * A list of valid values for the `encoding_id` for * @TT_PLATFORM_MACINTOSH charmaps and name entries. */ @@ -180,14 +181,14 @@ FT_BEGIN_HEADER #define TT_MAC_ID_UNINTERP 32 - /*********************************************************************** + /************************************************************************** * * @enum: * TT_ISO_ID_XXX * * @description: - * A list of valid values for the `encoding_id' for - * @TT_PLATFORM_ISO charmaps and name entries. + * A list of valid values for the `encoding_id` for @TT_PLATFORM_ISO + * charmaps and name entries. * * Their use is now deprecated. * @@ -205,13 +206,13 @@ FT_BEGIN_HEADER #define TT_ISO_ID_8859_1 2 - /*********************************************************************** + /************************************************************************** * * @enum: * TT_MS_ID_XXX * * @description: - * A list of valid values for the `encoding_id' for + * A list of valid values for the `encoding_id` for * @TT_PLATFORM_MICROSOFT charmaps and name entries. * * @values: @@ -219,16 +220,15 @@ FT_BEGIN_HEADER * Microsoft symbol encoding. See @FT_ENCODING_MS_SYMBOL. * * TT_MS_ID_UNICODE_CS :: - * Microsoft WGL4 charmap, matching Unicode. See - * @FT_ENCODING_UNICODE. + * Microsoft WGL4 charmap, matching Unicode. See @FT_ENCODING_UNICODE. * * TT_MS_ID_SJIS :: * Shift JIS Japanese encoding. See @FT_ENCODING_SJIS. * * TT_MS_ID_PRC :: * Chinese encodings as used in the People's Republic of China (PRC). - * This means the encodings GB~2312 and its supersets GBK and - * GB~18030. See @FT_ENCODING_PRC. + * This means the encodings GB~2312 and its supersets GBK and GB~18030. + * See @FT_ENCODING_PRC. * * TT_MS_ID_BIG_5 :: * Traditional Chinese as used in Taiwan and Hong Kong. See @@ -258,14 +258,14 @@ FT_BEGIN_HEADER #define TT_MS_ID_GB2312 TT_MS_ID_PRC - /*********************************************************************** + /************************************************************************** * * @enum: * TT_ADOBE_ID_XXX * * @description: - * A list of valid values for the `encoding_id' for - * @TT_PLATFORM_ADOBE charmaps. This is a FreeType-specific extension! + * A list of valid values for the `encoding_id` for @TT_PLATFORM_ADOBE + * charmaps. This is a FreeType-specific extension! * * @values: * TT_ADOBE_ID_STANDARD :: @@ -284,14 +284,14 @@ FT_BEGIN_HEADER #define TT_ADOBE_ID_LATIN_1 3 - /*********************************************************************** + /************************************************************************** * * @enum: * TT_MAC_LANGID_XXX * * @description: * Possible values of the language identifier field in the name records - * of the SFNT `name' table if the `platform' identifier code is + * of the SFNT 'name' table if the 'platform' identifier code is * @TT_PLATFORM_MACINTOSH. These values are also used as return values * for function @FT_Get_CMap_Language_ID. * @@ -424,24 +424,24 @@ FT_BEGIN_HEADER #define TT_MAC_LANGID_AZERBAIJANI_ROMAN_SCRIPT 150 - /*********************************************************************** + /************************************************************************** * * @enum: * TT_MS_LANGID_XXX * * @description: * Possible values of the language identifier field in the name records - * of the SFNT `name' table if the `platform' identifier code is + * of the SFNT 'name' table if the 'platform' identifier code is * @TT_PLATFORM_MICROSOFT. These values are also used as return values * for function @FT_Get_CMap_Language_ID. * * The canonical source for Microsoft's IDs is * - * https://www.microsoft.com/globaldev/reference/lcid-all.mspx , + * https://docs.microsoft.com/en-us/windows/desktop/Intl/language-identifier-constants-and-strings , * * however, we only provide macros for language identifiers present in * the OpenType specification: Microsoft has abandoned the concept of - * LCIDs (language code identifiers), and format~1 of the `name' table + * LCIDs (language code identifiers), and format~1 of the 'name' table * provides a better mechanism for languages not covered here. * * More legacy values not listed in the reference can be found in the @@ -780,14 +780,14 @@ FT_BEGIN_HEADER TT_MS_LANGID_UIGHUR_PRC - /*********************************************************************** + /************************************************************************** * * @enum: * TT_NAME_ID_XXX * * @description: - * Possible values of the `name' identifier field in the name records of - * an SFNT `name' table. These values are platform independent. + * Possible values of the 'name' identifier field in the name records of + * an SFNT 'name' table. These values are platform independent. */ #define TT_NAME_ID_COPYRIGHT 0 @@ -834,14 +834,14 @@ FT_BEGIN_HEADER #define TT_NAME_ID_PREFERRED_SUBFAMILY TT_NAME_ID_TYPOGRAPHIC_SUBFAMILY - /*********************************************************************** + /************************************************************************** * * @enum: * TT_UCR_XXX * * @description: - * Possible bit mask values for the `ulUnicodeRangeX' fields in an SFNT - * `OS/2' table. + * Possible bit mask values for the `ulUnicodeRangeX` fields in an SFNT + * 'OS/2' table. */ /* ulUnicodeRange1 */ diff --git a/sdk/lib/3rdparty/freetype/include/freetype/tttables.h b/sdk/lib/3rdparty/freetype/include/freetype/tttables.h index ce6a61779c4a1..d04f8102184e0 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/tttables.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/tttables.h @@ -1,20 +1,20 @@ -/***************************************************************************/ -/* */ -/* tttables.h */ -/* */ -/* Basic SFNT/TrueType tables definitions and interface */ -/* (specification only). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * tttables.h + * + * Basic SFNT/TrueType tables definitions and interface + * (specification only). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef TTTABLES_H_ @@ -33,53 +33,55 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* <Section> */ - /* truetype_tables */ - /* */ - /* <Title> */ - /* TrueType Tables */ - /* */ - /* <Abstract> */ - /* TrueType specific table types and functions. */ - /* */ - /* <Description> */ - /* This section contains definitions of some basic tables specific to */ - /* TrueType and OpenType as well as some routines used to access and */ - /* process them. */ - /* */ - /* <Order> */ - /* TT_Header */ - /* TT_HoriHeader */ - /* TT_VertHeader */ - /* TT_OS2 */ - /* TT_Postscript */ - /* TT_PCLT */ - /* TT_MaxProfile */ - /* */ - /* FT_Sfnt_Tag */ - /* FT_Get_Sfnt_Table */ - /* FT_Load_Sfnt_Table */ - /* FT_Sfnt_Table_Info */ - /* */ - /* FT_Get_CMap_Language_ID */ - /* FT_Get_CMap_Format */ - /* */ - /* FT_PARAM_TAG_UNPATENTED_HINTING */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_Header */ - /* */ - /* <Description> */ - /* A structure to model a TrueType font header table. All fields */ - /* follow the OpenType specification. */ - /* */ + /************************************************************************** + * + * @section: + * truetype_tables + * + * @title: + * TrueType Tables + * + * @abstract: + * TrueType-specific table types and functions. + * + * @description: + * This section contains definitions of some basic tables specific to + * TrueType and OpenType as well as some routines used to access and + * process them. + * + * @order: + * TT_Header + * TT_HoriHeader + * TT_VertHeader + * TT_OS2 + * TT_Postscript + * TT_PCLT + * TT_MaxProfile + * + * FT_Sfnt_Tag + * FT_Get_Sfnt_Table + * FT_Load_Sfnt_Table + * FT_Sfnt_Table_Info + * + * FT_Get_CMap_Language_ID + * FT_Get_CMap_Format + * + * FT_PARAM_TAG_UNPATENTED_HINTING + * + */ + + + /************************************************************************** + * + * @struct: + * TT_Header + * + * @description: + * A structure to model a TrueType font header table. All fields follow + * the OpenType specification. The 64-bit timestamps are stored in + * two-element arrays `Created` and `Modified`, first the upper then + * the lower 32~bits. + */ typedef struct TT_Header_ { FT_Fixed Table_Version; @@ -91,8 +93,8 @@ FT_BEGIN_HEADER FT_UShort Flags; FT_UShort Units_Per_EM; - FT_Long Created [2]; - FT_Long Modified[2]; + FT_ULong Created [2]; + FT_ULong Modified[2]; FT_Short xMin; FT_Short yMin; @@ -109,93 +111,93 @@ FT_BEGIN_HEADER } TT_Header; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_HoriHeader */ - /* */ - /* <Description> */ - /* A structure to model a TrueType horizontal header, the `hhea' */ - /* table, as well as the corresponding horizontal metrics table, */ - /* `hmtx'. */ - /* */ - /* <Fields> */ - /* Version :: The table version. */ - /* */ - /* Ascender :: The font's ascender, i.e., the distance */ - /* from the baseline to the top-most of all */ - /* glyph points found in the font. */ - /* */ - /* This value is invalid in many fonts, as */ - /* it is usually set by the font designer, */ - /* and often reflects only a portion of the */ - /* glyphs found in the font (maybe ASCII). */ - /* */ - /* You should use the `sTypoAscender' field */ - /* of the `OS/2' table instead if you want */ - /* the correct one. */ - /* */ - /* Descender :: The font's descender, i.e., the distance */ - /* from the baseline to the bottom-most of */ - /* all glyph points found in the font. It */ - /* is negative. */ - /* */ - /* This value is invalid in many fonts, as */ - /* it is usually set by the font designer, */ - /* and often reflects only a portion of the */ - /* glyphs found in the font (maybe ASCII). */ - /* */ - /* You should use the `sTypoDescender' */ - /* field of the `OS/2' table instead if you */ - /* want the correct one. */ - /* */ - /* Line_Gap :: The font's line gap, i.e., the distance */ - /* to add to the ascender and descender to */ - /* get the BTB, i.e., the */ - /* baseline-to-baseline distance for the */ - /* font. */ - /* */ - /* advance_Width_Max :: This field is the maximum of all advance */ - /* widths found in the font. It can be */ - /* used to compute the maximum width of an */ - /* arbitrary string of text. */ - /* */ - /* min_Left_Side_Bearing :: The minimum left side bearing of all */ - /* glyphs within the font. */ - /* */ - /* min_Right_Side_Bearing :: The minimum right side bearing of all */ - /* glyphs within the font. */ - /* */ - /* xMax_Extent :: The maximum horizontal extent (i.e., the */ - /* `width' of a glyph's bounding box) for */ - /* all glyphs in the font. */ - /* */ - /* caret_Slope_Rise :: The rise coefficient of the cursor's */ - /* slope of the cursor (slope=rise/run). */ - /* */ - /* caret_Slope_Run :: The run coefficient of the cursor's */ - /* slope. */ - /* */ - /* caret_Offset :: The cursor's offset for slanted fonts. */ - /* */ - /* Reserved :: 8~reserved bytes. */ - /* */ - /* metric_Data_Format :: Always~0. */ - /* */ - /* number_Of_HMetrics :: Number of HMetrics entries in the `hmtx' */ - /* table -- this value can be smaller than */ - /* the total number of glyphs in the font. */ - /* */ - /* long_metrics :: A pointer into the `hmtx' table. */ - /* */ - /* short_metrics :: A pointer into the `hmtx' table. */ - /* */ - /* <Note> */ - /* For an OpenType variation font, the values of the following fields */ - /* can change after a call to @FT_Set_Var_Design_Coordinates (and */ - /* friends) if the font contains an `MVAR' table: `caret_Slope_Rise', */ - /* `caret_Slope_Run', and `caret_Offset'. */ - /* */ + /************************************************************************** + * + * @struct: + * TT_HoriHeader + * + * @description: + * A structure to model a TrueType horizontal header, the 'hhea' table, + * as well as the corresponding horizontal metrics table, 'hmtx'. + * + * @fields: + * Version :: + * The table version. + * + * Ascender :: + * The font's ascender, i.e., the distance from the baseline to the + * top-most of all glyph points found in the font. + * + * This value is invalid in many fonts, as it is usually set by the + * font designer, and often reflects only a portion of the glyphs found + * in the font (maybe ASCII). + * + * You should use the `sTypoAscender` field of the 'OS/2' table instead + * if you want the correct one. + * + * Descender :: + * The font's descender, i.e., the distance from the baseline to the + * bottom-most of all glyph points found in the font. It is negative. + * + * This value is invalid in many fonts, as it is usually set by the + * font designer, and often reflects only a portion of the glyphs found + * in the font (maybe ASCII). + * + * You should use the `sTypoDescender` field of the 'OS/2' table + * instead if you want the correct one. + * + * Line_Gap :: + * The font's line gap, i.e., the distance to add to the ascender and + * descender to get the BTB, i.e., the baseline-to-baseline distance + * for the font. + * + * advance_Width_Max :: + * This field is the maximum of all advance widths found in the font. + * It can be used to compute the maximum width of an arbitrary string + * of text. + * + * min_Left_Side_Bearing :: + * The minimum left side bearing of all glyphs within the font. + * + * min_Right_Side_Bearing :: + * The minimum right side bearing of all glyphs within the font. + * + * xMax_Extent :: + * The maximum horizontal extent (i.e., the 'width' of a glyph's + * bounding box) for all glyphs in the font. + * + * caret_Slope_Rise :: + * The rise coefficient of the cursor's slope of the cursor + * (slope=rise/run). + * + * caret_Slope_Run :: + * The run coefficient of the cursor's slope. + * + * caret_Offset :: + * The cursor's offset for slanted fonts. + * + * Reserved :: + * 8~reserved bytes. + * + * metric_Data_Format :: + * Always~0. + * + * number_Of_HMetrics :: + * Number of HMetrics entries in the 'hmtx' table -- this value can be + * smaller than the total number of glyphs in the font. + * + * long_metrics :: + * A pointer into the 'hmtx' table. + * + * short_metrics :: + * A pointer into the 'hmtx' table. + * + * @note: + * For an OpenType variation font, the values of the following fields can + * change after a call to @FT_Set_Var_Design_Coordinates (and friends) if + * the font contains an 'MVAR' table: `caret_Slope_Rise`, + * `caret_Slope_Run`, and `caret_Offset`. + */ typedef struct TT_HoriHeader_ { FT_Fixed Version; @@ -219,7 +221,7 @@ FT_BEGIN_HEADER /* The following fields are not defined by the OpenType specification */ /* but they are used to connect the metrics header to the relevant */ - /* `hmtx' table. */ + /* 'hmtx' table. */ void* long_metrics; void* short_metrics; @@ -227,97 +229,93 @@ FT_BEGIN_HEADER } TT_HoriHeader; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_VertHeader */ - /* */ - /* <Description> */ - /* A structure used to model a TrueType vertical header, the `vhea' */ - /* table, as well as the corresponding vertical metrics table, */ - /* `vmtx'. */ - /* */ - /* <Fields> */ - /* Version :: The table version. */ - /* */ - /* Ascender :: The font's ascender, i.e., the distance */ - /* from the baseline to the top-most of */ - /* all glyph points found in the font. */ - /* */ - /* This value is invalid in many fonts, as */ - /* it is usually set by the font designer, */ - /* and often reflects only a portion of */ - /* the glyphs found in the font (maybe */ - /* ASCII). */ - /* */ - /* You should use the `sTypoAscender' */ - /* field of the `OS/2' table instead if */ - /* you want the correct one. */ - /* */ - /* Descender :: The font's descender, i.e., the */ - /* distance from the baseline to the */ - /* bottom-most of all glyph points found */ - /* in the font. It is negative. */ - /* */ - /* This value is invalid in many fonts, as */ - /* it is usually set by the font designer, */ - /* and often reflects only a portion of */ - /* the glyphs found in the font (maybe */ - /* ASCII). */ - /* */ - /* You should use the `sTypoDescender' */ - /* field of the `OS/2' table instead if */ - /* you want the correct one. */ - /* */ - /* Line_Gap :: The font's line gap, i.e., the distance */ - /* to add to the ascender and descender to */ - /* get the BTB, i.e., the */ - /* baseline-to-baseline distance for the */ - /* font. */ - /* */ - /* advance_Height_Max :: This field is the maximum of all */ - /* advance heights found in the font. It */ - /* can be used to compute the maximum */ - /* height of an arbitrary string of text. */ - /* */ - /* min_Top_Side_Bearing :: The minimum top side bearing of all */ - /* glyphs within the font. */ - /* */ - /* min_Bottom_Side_Bearing :: The minimum bottom side bearing of all */ - /* glyphs within the font. */ - /* */ - /* yMax_Extent :: The maximum vertical extent (i.e., the */ - /* `height' of a glyph's bounding box) for */ - /* all glyphs in the font. */ - /* */ - /* caret_Slope_Rise :: The rise coefficient of the cursor's */ - /* slope of the cursor (slope=rise/run). */ - /* */ - /* caret_Slope_Run :: The run coefficient of the cursor's */ - /* slope. */ - /* */ - /* caret_Offset :: The cursor's offset for slanted fonts. */ - /* */ - /* Reserved :: 8~reserved bytes. */ - /* */ - /* metric_Data_Format :: Always~0. */ - /* */ - /* number_Of_VMetrics :: Number of VMetrics entries in the */ - /* `vmtx' table -- this value can be */ - /* smaller than the total number of glyphs */ - /* in the font. */ - /* */ - /* long_metrics :: A pointer into the `vmtx' table. */ - /* */ - /* short_metrics :: A pointer into the `vmtx' table. */ - /* */ - /* <Note> */ - /* For an OpenType variation font, the values of the following fields */ - /* can change after a call to @FT_Set_Var_Design_Coordinates (and */ - /* friends) if the font contains an `MVAR' table: `Ascender', */ - /* `Descender', `Line_Gap', `caret_Slope_Rise', `caret_Slope_Run', */ - /* and `caret_Offset'. */ - /* */ + /************************************************************************** + * + * @struct: + * TT_VertHeader + * + * @description: + * A structure used to model a TrueType vertical header, the 'vhea' + * table, as well as the corresponding vertical metrics table, 'vmtx'. + * + * @fields: + * Version :: + * The table version. + * + * Ascender :: + * The font's ascender, i.e., the distance from the baseline to the + * top-most of all glyph points found in the font. + * + * This value is invalid in many fonts, as it is usually set by the + * font designer, and often reflects only a portion of the glyphs found + * in the font (maybe ASCII). + * + * You should use the `sTypoAscender` field of the 'OS/2' table instead + * if you want the correct one. + * + * Descender :: + * The font's descender, i.e., the distance from the baseline to the + * bottom-most of all glyph points found in the font. It is negative. + * + * This value is invalid in many fonts, as it is usually set by the + * font designer, and often reflects only a portion of the glyphs found + * in the font (maybe ASCII). + * + * You should use the `sTypoDescender` field of the 'OS/2' table + * instead if you want the correct one. + * + * Line_Gap :: + * The font's line gap, i.e., the distance to add to the ascender and + * descender to get the BTB, i.e., the baseline-to-baseline distance + * for the font. + * + * advance_Height_Max :: + * This field is the maximum of all advance heights found in the font. + * It can be used to compute the maximum height of an arbitrary string + * of text. + * + * min_Top_Side_Bearing :: + * The minimum top side bearing of all glyphs within the font. + * + * min_Bottom_Side_Bearing :: + * The minimum bottom side bearing of all glyphs within the font. + * + * yMax_Extent :: + * The maximum vertical extent (i.e., the 'height' of a glyph's + * bounding box) for all glyphs in the font. + * + * caret_Slope_Rise :: + * The rise coefficient of the cursor's slope of the cursor + * (slope=rise/run). + * + * caret_Slope_Run :: + * The run coefficient of the cursor's slope. + * + * caret_Offset :: + * The cursor's offset for slanted fonts. + * + * Reserved :: + * 8~reserved bytes. + * + * metric_Data_Format :: + * Always~0. + * + * number_Of_VMetrics :: + * Number of VMetrics entries in the 'vmtx' table -- this value can be + * smaller than the total number of glyphs in the font. + * + * long_metrics :: + * A pointer into the 'vmtx' table. + * + * short_metrics :: + * A pointer into the 'vmtx' table. + * + * @note: + * For an OpenType variation font, the values of the following fields can + * change after a call to @FT_Set_Var_Design_Coordinates (and friends) if + * the font contains an 'MVAR' table: `Ascender`, `Descender`, + * `Line_Gap`, `caret_Slope_Rise`, `caret_Slope_Run`, and `caret_Offset`. + */ typedef struct TT_VertHeader_ { FT_Fixed Version; @@ -341,7 +339,7 @@ FT_BEGIN_HEADER /* The following fields are not defined by the OpenType specification */ /* but they are used to connect the metrics header to the relevant */ - /* `vmtx' table. */ + /* 'vmtx' table. */ void* long_metrics; void* short_metrics; @@ -349,33 +347,31 @@ FT_BEGIN_HEADER } TT_VertHeader; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_OS2 */ - /* */ - /* <Description> */ - /* A structure to model a TrueType `OS/2' table. All fields comply */ - /* to the OpenType specification. */ - /* */ - /* Note that we now support old Mac fonts that do not include an */ - /* `OS/2' table. In this case, the `version' field is always set to */ - /* 0xFFFF. */ - /* */ - /* <Note> */ - /* For an OpenType variation font, the values of the following fields */ - /* can change after a call to @FT_Set_Var_Design_Coordinates (and */ - /* friends) if the font contains an `MVAR' table: `sCapHeight', */ - /* `sTypoAscender', `sTypoDescender', `sTypoLineGap', `sxHeight', */ - /* `usWinAscent', `usWinDescent', `yStrikeoutPosition', */ - /* `yStrikeoutSize', `ySubscriptXOffset', `ySubScriptXSize', */ - /* `ySubscriptYOffset', `ySubscriptYSize', `ySuperscriptXOffset', */ - /* `ySuperscriptXSize', `ySuperscriptYOffset', and */ - /* `ySuperscriptYSize'. */ - /* */ - /* Possible values for bits in the `ulUnicodeRangeX' fields are given */ - /* by the @TT_UCR_XXX macros. */ - /* */ + /************************************************************************** + * + * @struct: + * TT_OS2 + * + * @description: + * A structure to model a TrueType 'OS/2' table. All fields comply to + * the OpenType specification. + * + * Note that we now support old Mac fonts that do not include an 'OS/2' + * table. In this case, the `version` field is always set to 0xFFFF. + * + * @note: + * For an OpenType variation font, the values of the following fields can + * change after a call to @FT_Set_Var_Design_Coordinates (and friends) if + * the font contains an 'MVAR' table: `sCapHeight`, `sTypoAscender`, + * `sTypoDescender`, `sTypoLineGap`, `sxHeight`, `usWinAscent`, + * `usWinDescent`, `yStrikeoutPosition`, `yStrikeoutSize`, + * `ySubscriptXOffset`, `ySubScriptXSize`, `ySubscriptYOffset`, + * `ySubscriptYSize`, `ySuperscriptXOffset`, `ySuperscriptXSize`, + * `ySuperscriptYOffset`, and `ySuperscriptYSize`. + * + * Possible values for bits in the `ulUnicodeRangeX` fields are given by + * the @TT_UCR_XXX macros. + */ typedef struct TT_OS2_ { @@ -435,23 +431,23 @@ FT_BEGIN_HEADER } TT_OS2; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_Postscript */ - /* */ - /* <Description> */ - /* A structure to model a TrueType `post' table. All fields comply */ - /* to the OpenType specification. This structure does not reference */ - /* a font's PostScript glyph names; use @FT_Get_Glyph_Name to */ - /* retrieve them. */ - /* */ - /* <Note> */ - /* For an OpenType variation font, the values of the following fields */ - /* can change after a call to @FT_Set_Var_Design_Coordinates (and */ - /* friends) if the font contains an `MVAR' table: `underlinePosition' */ - /* and `underlineThickness'. */ - /* */ + /************************************************************************** + * + * @struct: + * TT_Postscript + * + * @description: + * A structure to model a TrueType 'post' table. All fields comply to + * the OpenType specification. This structure does not reference a + * font's PostScript glyph names; use @FT_Get_Glyph_Name to retrieve + * them. + * + * @note: + * For an OpenType variation font, the values of the following fields can + * change after a call to @FT_Set_Var_Design_Coordinates (and friends) if + * the font contains an 'MVAR' table: `underlinePosition` and + * `underlineThickness`. + */ typedef struct TT_Postscript_ { FT_Fixed FormatType; @@ -464,21 +460,21 @@ FT_BEGIN_HEADER FT_ULong minMemType1; FT_ULong maxMemType1; - /* Glyph names follow in the `post' table, but we don't */ + /* Glyph names follow in the 'post' table, but we don't */ /* load them by default. */ } TT_Postscript; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_PCLT */ - /* */ - /* <Description> */ - /* A structure to model a TrueType `PCLT' table. All fields comply */ - /* to the OpenType specification. */ - /* */ + /************************************************************************** + * + * @struct: + * TT_PCLT + * + * @description: + * A structure to model a TrueType 'PCLT' table. All fields comply to + * the OpenType specification. + */ typedef struct TT_PCLT_ { FT_Fixed Version; @@ -500,70 +496,75 @@ FT_BEGIN_HEADER } TT_PCLT; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_MaxProfile */ - /* */ - /* <Description> */ - /* The maximum profile (`maxp') table contains many max values, which */ - /* can be used to pre-allocate arrays for speeding up glyph loading */ - /* and hinting. */ - /* */ - /* <Fields> */ - /* version :: The version number. */ - /* */ - /* numGlyphs :: The number of glyphs in this TrueType */ - /* font. */ - /* */ - /* maxPoints :: The maximum number of points in a */ - /* non-composite TrueType glyph. See also */ - /* `maxCompositePoints'. */ - /* */ - /* maxContours :: The maximum number of contours in a */ - /* non-composite TrueType glyph. See also */ - /* `maxCompositeContours'. */ - /* */ - /* maxCompositePoints :: The maximum number of points in a */ - /* composite TrueType glyph. See also */ - /* `maxPoints'. */ - /* */ - /* maxCompositeContours :: The maximum number of contours in a */ - /* composite TrueType glyph. See also */ - /* `maxContours'. */ - /* */ - /* maxZones :: The maximum number of zones used for */ - /* glyph hinting. */ - /* */ - /* maxTwilightPoints :: The maximum number of points in the */ - /* twilight zone used for glyph hinting. */ - /* */ - /* maxStorage :: The maximum number of elements in the */ - /* storage area used for glyph hinting. */ - /* */ - /* maxFunctionDefs :: The maximum number of function */ - /* definitions in the TrueType bytecode for */ - /* this font. */ - /* */ - /* maxInstructionDefs :: The maximum number of instruction */ - /* definitions in the TrueType bytecode for */ - /* this font. */ - /* */ - /* maxStackElements :: The maximum number of stack elements used */ - /* during bytecode interpretation. */ - /* */ - /* maxSizeOfInstructions :: The maximum number of TrueType opcodes */ - /* used for glyph hinting. */ - /* */ - /* maxComponentElements :: The maximum number of simple (i.e., non- */ - /* composite) glyphs in a composite glyph. */ - /* */ - /* maxComponentDepth :: The maximum nesting depth of composite */ - /* glyphs. */ - /* */ - /* <Note> */ - /* This structure is only used during font loading. */ - /* */ + /************************************************************************** + * + * @struct: + * TT_MaxProfile + * + * @description: + * The maximum profile ('maxp') table contains many max values, which can + * be used to pre-allocate arrays for speeding up glyph loading and + * hinting. + * + * @fields: + * version :: + * The version number. + * + * numGlyphs :: + * The number of glyphs in this TrueType font. + * + * maxPoints :: + * The maximum number of points in a non-composite TrueType glyph. See + * also `maxCompositePoints`. + * + * maxContours :: + * The maximum number of contours in a non-composite TrueType glyph. + * See also `maxCompositeContours`. + * + * maxCompositePoints :: + * The maximum number of points in a composite TrueType glyph. See + * also `maxPoints`. + * + * maxCompositeContours :: + * The maximum number of contours in a composite TrueType glyph. See + * also `maxContours`. + * + * maxZones :: + * The maximum number of zones used for glyph hinting. + * + * maxTwilightPoints :: + * The maximum number of points in the twilight zone used for glyph + * hinting. + * + * maxStorage :: + * The maximum number of elements in the storage area used for glyph + * hinting. + * + * maxFunctionDefs :: + * The maximum number of function definitions in the TrueType bytecode + * for this font. + * + * maxInstructionDefs :: + * The maximum number of instruction definitions in the TrueType + * bytecode for this font. + * + * maxStackElements :: + * The maximum number of stack elements used during bytecode + * interpretation. + * + * maxSizeOfInstructions :: + * The maximum number of TrueType opcodes used for glyph hinting. + * + * maxComponentElements :: + * The maximum number of simple (i.e., non-composite) glyphs in a + * composite glyph. + * + * maxComponentDepth :: + * The maximum nesting depth of composite glyphs. + * + * @note: + * This structure is only used during font loading. + */ typedef struct TT_MaxProfile_ { FT_Fixed version; @@ -585,31 +586,38 @@ FT_BEGIN_HEADER } TT_MaxProfile; - /*************************************************************************/ - /* */ - /* <Enum> */ - /* FT_Sfnt_Tag */ - /* */ - /* <Description> */ - /* An enumeration to specify indices of SFNT tables loaded and parsed */ - /* by FreeType during initialization of an SFNT font. Used in the */ - /* @FT_Get_Sfnt_Table API function. */ - /* */ - /* <Values> */ - /* FT_SFNT_HEAD :: To access the font's @TT_Header structure. */ - /* */ - /* FT_SFNT_MAXP :: To access the font's @TT_MaxProfile structure. */ - /* */ - /* FT_SFNT_OS2 :: To access the font's @TT_OS2 structure. */ - /* */ - /* FT_SFNT_HHEA :: To access the font's @TT_HoriHeader structure. */ - /* */ - /* FT_SFNT_VHEA :: To access the font's @TT_VertHeader structure. */ - /* */ - /* FT_SFNT_POST :: To access the font's @TT_Postscript structure. */ - /* */ - /* FT_SFNT_PCLT :: To access the font's @TT_PCLT structure. */ - /* */ + /************************************************************************** + * + * @enum: + * FT_Sfnt_Tag + * + * @description: + * An enumeration to specify indices of SFNT tables loaded and parsed by + * FreeType during initialization of an SFNT font. Used in the + * @FT_Get_Sfnt_Table API function. + * + * @values: + * FT_SFNT_HEAD :: + * To access the font's @TT_Header structure. + * + * FT_SFNT_MAXP :: + * To access the font's @TT_MaxProfile structure. + * + * FT_SFNT_OS2 :: + * To access the font's @TT_OS2 structure. + * + * FT_SFNT_HHEA :: + * To access the font's @TT_HoriHeader structure. + * + * FT_SFNT_VHEA :: + * To access the font's @TT_VertHeader structure. + * + * FT_SFNT_POST :: + * To access the font's @TT_Postscript structure. + * + * FT_SFNT_PCLT :: + * To access the font's @TT_PCLT structure. + */ typedef enum FT_Sfnt_Tag_ { FT_SFNT_HEAD, @@ -624,7 +632,7 @@ FT_BEGIN_HEADER } FT_Sfnt_Tag; - /* these constants are deprecated; use the corresponding `FT_Sfnt_Tag' */ + /* these constants are deprecated; use the corresponding `FT_Sfnt_Tag` */ /* values instead */ #define ft_sfnt_head FT_SFNT_HEAD #define ft_sfnt_maxp FT_SFNT_MAXP @@ -635,44 +643,46 @@ FT_BEGIN_HEADER #define ft_sfnt_pclt FT_SFNT_PCLT - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_Sfnt_Table */ - /* */ - /* <Description> */ - /* Return a pointer to a given SFNT table stored within a face. */ - /* */ - /* <Input> */ - /* face :: A handle to the source. */ - /* */ - /* tag :: The index of the SFNT table. */ - /* */ - /* <Return> */ - /* A type-less pointer to the table. This will be NULL in case of */ - /* error, or if the corresponding table was not found *OR* loaded */ - /* from the file. */ - /* */ - /* Use a typecast according to `tag' to access the structure */ - /* elements. */ - /* */ - /* <Note> */ - /* The table is owned by the face object and disappears with it. */ - /* */ - /* This function is only useful to access SFNT tables that are loaded */ - /* by the sfnt, truetype, and opentype drivers. See @FT_Sfnt_Tag for */ - /* a list. */ - /* */ - /* Here an example how to access the `vhea' table: */ - /* */ - /* { */ - /* TT_VertHeader* vert_header; */ - /* */ - /* */ - /* vert_header = */ - /* (TT_VertHeader*)FT_Get_Sfnt_Table( face, FT_SFNT_VHEA ); */ - /* } */ - /* */ + /************************************************************************** + * + * @function: + * FT_Get_Sfnt_Table + * + * @description: + * Return a pointer to a given SFNT table stored within a face. + * + * @input: + * face :: + * A handle to the source. + * + * tag :: + * The index of the SFNT table. + * + * @return: + * A type-less pointer to the table. This will be `NULL` in case of + * error, or if the corresponding table was not found **OR** loaded from + * the file. + * + * Use a typecast according to `tag` to access the structure elements. + * + * @note: + * The table is owned by the face object and disappears with it. + * + * This function is only useful to access SFNT tables that are loaded by + * the sfnt, truetype, and opentype drivers. See @FT_Sfnt_Tag for a + * list. + * + * @example: + * Here is an example demonstrating access to the 'vhea' table. + * + * ``` + * TT_VertHeader* vert_header; + * + * + * vert_header = + * (TT_VertHeader*)FT_Get_Sfnt_Table( face, FT_SFNT_VHEA ); + * ``` + */ FT_EXPORT( void* ) FT_Get_Sfnt_Table( FT_Face face, FT_Sfnt_Tag tag ); @@ -691,8 +701,8 @@ FT_BEGIN_HEADER * A handle to the source face. * * tag :: - * The four-byte tag of the table to load. Use value~0 if you want - * to access the whole font file. Otherwise, you can use one of the + * The four-byte tag of the table to load. Use value~0 if you want to + * access the whole font file. Otherwise, you can use one of the * definitions found in the @FT_TRUETYPE_TAGS_H file, or forge a new * one with @FT_MAKE_TAG. * @@ -706,10 +716,10 @@ FT_BEGIN_HEADER * * @inout: * length :: - * If the `length' parameter is NULL, try to load the whole table. + * If the `length` parameter is `NULL`, try to load the whole table. * Return an error code if it fails. * - * Else, if `*length' is~0, exit immediately while returning the + * Else, if `*length` is~0, exit immediately while returning the * table's (or file) full size in it. * * Else the number of bytes to read from the table or file, from the @@ -720,21 +730,21 @@ FT_BEGIN_HEADER * * @note: * If you need to determine the table's length you should first call this - * function with `*length' set to~0, as in the following example: + * function with `*length` set to~0, as in the following example: * - * { - * FT_ULong length = 0; + * ``` + * FT_ULong length = 0; * * - * error = FT_Load_Sfnt_Table( face, tag, 0, NULL, &length ); - * if ( error ) { ... table does not exist ... } + * error = FT_Load_Sfnt_Table( face, tag, 0, NULL, &length ); + * if ( error ) { ... table does not exist ... } * - * buffer = malloc( length ); - * if ( buffer == NULL ) { ... not enough memory ... } + * buffer = malloc( length ); + * if ( buffer == NULL ) { ... not enough memory ... } * - * error = FT_Load_Sfnt_Table( face, tag, 0, buffer, &length ); - * if ( error ) { ... could not load table ... } - * } + * error = FT_Load_Sfnt_Table( face, tag, 0, buffer, &length ); + * if ( error ) { ... could not load table ... } + * ``` * * Note that structures like @TT_Header or @TT_OS2 can't be used with * this function; they are limited to @FT_Get_Sfnt_Table. Reason is that @@ -768,14 +778,14 @@ FT_BEGIN_HEADER * * @inout: * tag :: - * The name tag of the SFNT table. If the value is NULL, `table_index' - * is ignored, and `length' returns the number of SFNT tables in the - * font. + * The name tag of the SFNT table. If the value is `NULL`, + * `table_index` is ignored, and `length` returns the number of SFNT + * tables in the font. * * @output: * length :: - * The length of the SFNT table (or the number of SFNT tables, depending - * on `tag'). + * The length of the SFNT table (or the number of SFNT tables, + * depending on `tag`). * * @return: * FreeType error code. 0~means success. @@ -792,46 +802,46 @@ FT_BEGIN_HEADER FT_ULong *length ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_CMap_Language_ID */ - /* */ - /* <Description> */ - /* Return cmap language ID as specified in the OpenType standard. */ - /* Definitions of language ID values are in file @FT_TRUETYPE_IDS_H. */ - /* */ - /* <Input> */ - /* charmap :: */ - /* The target charmap. */ - /* */ - /* <Return> */ - /* The language ID of `charmap'. If `charmap' doesn't belong to an */ - /* SFNT face, just return~0 as the default value. */ - /* */ - /* For a format~14 cmap (to access Unicode IVS), the return value is */ - /* 0xFFFFFFFF. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Get_CMap_Language_ID + * + * @description: + * Return cmap language ID as specified in the OpenType standard. + * Definitions of language ID values are in file @FT_TRUETYPE_IDS_H. + * + * @input: + * charmap :: + * The target charmap. + * + * @return: + * The language ID of `charmap`. If `charmap` doesn't belong to an SFNT + * face, just return~0 as the default value. + * + * For a format~14 cmap (to access Unicode IVS), the return value is + * 0xFFFFFFFF. + */ FT_EXPORT( FT_ULong ) FT_Get_CMap_Language_ID( FT_CharMap charmap ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Get_CMap_Format */ - /* */ - /* <Description> */ - /* Return the format of an SFNT `cmap' table. */ - /* */ - /* <Input> */ - /* charmap :: */ - /* The target charmap. */ - /* */ - /* <Return> */ - /* The format of `charmap'. If `charmap' doesn't belong to an SFNT */ - /* face, return -1. */ - /* */ + /************************************************************************** + * + * @function: + * FT_Get_CMap_Format + * + * @description: + * Return the format of an SFNT 'cmap' table. + * + * @input: + * charmap :: + * The target charmap. + * + * @return: + * The format of `charmap`. If `charmap` doesn't belong to an SFNT face, + * return -1. + */ FT_EXPORT( FT_Long ) FT_Get_CMap_Format( FT_CharMap charmap ); diff --git a/sdk/lib/3rdparty/freetype/include/freetype/tttags.h b/sdk/lib/3rdparty/freetype/include/freetype/tttags.h index e5cee68a1591c..bd0986eff0963 100644 --- a/sdk/lib/3rdparty/freetype/include/freetype/tttags.h +++ b/sdk/lib/3rdparty/freetype/include/freetype/tttags.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* tttags.h */ -/* */ -/* Tags for TrueType and OpenType tables (specification only). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * tttags.h + * + * Tags for TrueType and OpenType tables (specification only). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef TTAGS_H_ @@ -46,6 +46,8 @@ FT_BEGIN_HEADER #define TTAG_CFF2 FT_MAKE_TAG( 'C', 'F', 'F', '2' ) #define TTAG_CID FT_MAKE_TAG( 'C', 'I', 'D', ' ' ) #define TTAG_cmap FT_MAKE_TAG( 'c', 'm', 'a', 'p' ) +#define TTAG_COLR FT_MAKE_TAG( 'C', 'O', 'L', 'R' ) +#define TTAG_CPAL FT_MAKE_TAG( 'C', 'P', 'A', 'L' ) #define TTAG_cvar FT_MAKE_TAG( 'c', 'v', 'a', 'r' ) #define TTAG_cvt FT_MAKE_TAG( 'c', 'v', 't', ' ' ) #define TTAG_DSIG FT_MAKE_TAG( 'D', 'S', 'I', 'G' ) diff --git a/sdk/lib/3rdparty/freetype/include/ft2build.h b/sdk/lib/3rdparty/freetype/include/ft2build.h index e7ce99bc9460d..e3f4887943f29 100644 --- a/sdk/lib/3rdparty/freetype/include/ft2build.h +++ b/sdk/lib/3rdparty/freetype/include/ft2build.h @@ -1,34 +1,36 @@ -/***************************************************************************/ -/* */ -/* ft2build.h */ -/* */ -/* FreeType 2 build and setup macros. */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This is the `entry point' for FreeType header file inclusions. It is */ - /* the only header file which should be included directly; all other */ - /* FreeType header files should be accessed with macro names (after */ - /* including `ft2build.h'). */ - /* */ - /* A typical example is */ - /* */ - /* #include <ft2build.h> */ - /* #include FT_FREETYPE_H */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * ft2build.h + * + * FreeType 2 build and setup macros. + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /************************************************************************** + * + * This is the 'entry point' for FreeType header file inclusions. It is + * the only header file which should be included directly; all other + * FreeType header files should be accessed with macro names (after + * including `ft2build.h`). + * + * A typical example is + * + * ``` + * #include <ft2build.h> + * #include FT_FREETYPE_H + * ``` + * + */ #ifndef FT2BUILD_H_ diff --git a/sdk/lib/3rdparty/freetype/modules.cfg b/sdk/lib/3rdparty/freetype/modules.cfg deleted file mode 100644 index 6ce0f3edbe26e..0000000000000 --- a/sdk/lib/3rdparty/freetype/modules.cfg +++ /dev/null @@ -1,270 +0,0 @@ -# modules.cfg -# -# Copyright 2005-2018 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. -# -# -# In case you compile the FreeType library with GNU make or makepp, this -# file controls which components are built into the library. Otherwise, -# please read this file for information on the various modules and its -# dependencies, then follow the instructions in the file `docs/INSTALL.ANY'. -# -# To deactivate a module, simply comment out the corresponding line. To -# activate a module, remove the comment character. -# -# Note that many modules and components are further controlled with macros -# in the file `include/freetype/config/ftoption.h'. - - -#### -#### font modules -- at least one is required -#### -#### The order given here (from top to down) is the order used for testing -#### font formats in the compiled library. -#### - -# TrueType font driver. -# -# This driver needs the `sfnt' module. -FONT_MODULES += truetype - -# PostScript Type 1 font driver. -# -# This driver needs the `psaux', `pshinter', and `psnames' modules. -# No FT_CONFIG_OPTION_PIC support. -FONT_MODULES += type1 - -# CFF/OpenType font driver. -# -# This driver needs the `sfnt', `psaux', `pshinter', and `psnames' modules. -FONT_MODULES += cff - -# Type 1 CID-keyed font driver. -# -# This driver needs the `psaux', `pshinter', and `psnames' modules. -# No FT_CONFIG_OPTION_PIC support. -FONT_MODULES += cid - -# PFR/TrueDoc font driver. See optional extension ftpfr.c below also. -# No FT_CONFIG_OPTION_PIC support. -FONT_MODULES += pfr - -# PostScript Type 42 font driver. -# -# This driver needs the `truetype' and `psaux' modules. -# No FT_CONFIG_OPTION_PIC support. -FONT_MODULES += type42 - -# Windows FONT/FNT font driver. See optional extension ftwinfnt.c below -# also. -# No FT_CONFIG_OPTION_PIC support. -FONT_MODULES += winfonts - -# PCF font driver. -# No FT_CONFIG_OPTION_PIC support. -FONT_MODULES += pcf - -# BDF font driver. See optional extension ftbdf.c below also. -# No FT_CONFIG_OPTION_PIC support. -FONT_MODULES += bdf - -# SFNT files support. If used without `truetype' or `cff', it supports -# bitmap-only fonts within an SFNT wrapper. -# -# This driver needs the `psnames' module. -FONT_MODULES += sfnt - - -#### -#### hinting modules -#### - -# FreeType's auto hinter. -HINTING_MODULES += autofit - -# PostScript hinter. -HINTING_MODULES += pshinter - -# The TrueType hinting engine doesn't have a module of its own but is -# controlled in file include/freetype/config/ftoption.h -# (TT_CONFIG_OPTION_BYTECODE_INTERPRETER and friends). - - -#### -#### raster modules -- at least one is required for vector font formats -#### - -# Monochrome rasterizer. -RASTER_MODULES += raster - -# Anti-aliasing rasterizer. -RASTER_MODULES += smooth - - -#### -#### auxiliary modules -#### - -# FreeType's cache sub-system (quite stable but still in beta -- this means -# that its public API is subject to change if necessary). See -# include/freetype/ftcache.h. Needs ftglyph.c. -# No FT_CONFIG_OPTION_PIC support. -AUX_MODULES += cache - -# TrueType GX/AAT table validation. Needs ftgxval.c below. -# -# No FT_CONFIG_OPTION_PIC support. -# AUX_MODULES += gxvalid - -# Support for streams compressed with gzip (files with suffix .gz). -# -# See include/freetype/ftgzip.h for the API. -# No FT_CONFIG_OPTION_PIC support. -AUX_MODULES += gzip - -# Support for streams compressed with LZW (files with suffix .Z). -# -# See include/freetype/ftlzw.h for the API. -# No FT_CONFIG_OPTION_PIC support. -AUX_MODULES += lzw - -# Support for streams compressed with bzip2 (files with suffix .bz2). -# -# See include/freetype/ftbzip2.h for the API. -# No FT_CONFIG_OPTION_PIC support. -AUX_MODULES += bzip2 - -# OpenType table validation. Needs ftotval.c below. -# -# No FT_CONFIG_OPTION_PIC support. -# AUX_MODULES += otvalid - -# Auxiliary PostScript driver component to share common code. -# -# This module depends on `psnames'. -# No FT_CONFIG_OPTION_PIC support. -AUX_MODULES += psaux - -# Support for PostScript glyph names. -# -# This module can be controlled in ftconfig.h -# (FT_CONFIG_OPTION_POSTSCRIPT_NAMES). -AUX_MODULES += psnames - - -#### -#### base module extensions -#### - -# Exact bounding box calculation. -# -# See include/freetype/ftbbox.h for the API. -BASE_EXTENSIONS += ftbbox.c - -# Access BDF-specific strings. Needs BDF font driver. -# -# See include/freetype/ftbdf.h for the API. -BASE_EXTENSIONS += ftbdf.c - -# Utility functions for converting 1bpp, 2bpp, 4bpp, and 8bpp bitmaps into -# 8bpp format, and for emboldening of bitmap glyphs. -# -# See include/freetype/ftbitmap.h for the API. -BASE_EXTENSIONS += ftbitmap.c - -# Access CID font information. -# -# See include/freetype/ftcid.h for the API. -BASE_EXTENSIONS += ftcid.c - -# Support functions for font formats. -# -# See include/freetype/ftfntfmt.h for the API. -BASE_EXTENSIONS += ftfntfmt.c - -# Access FSType information. Needs fttype1.c. -# -# See include/freetype/freetype.h for the API. -BASE_EXTENSIONS += ftfstype.c - -# Support for GASP table queries. -# -# See include/freetype/ftgasp.h for the API. -BASE_EXTENSIONS += ftgasp.c - -# Convenience functions to handle glyphs. Needs ftbitmap.c. -# -# See include/freetype/ftglyph.h for the API. -BASE_EXTENSIONS += ftglyph.c - -# Interface for gxvalid module. -# -# See include/freetype/ftgxval.h for the API. -BASE_EXTENSIONS += ftgxval.c - -# Support for LCD color filtering of subpixel bitmaps. -# -# See include/freetype/ftlcdfil.h for the API. -BASE_EXTENSIONS += ftlcdfil.c - -# Multiple Master font interface. -# -# See include/freetype/ftmm.h for the API. -BASE_EXTENSIONS += ftmm.c - -# Interface for otvalid module. -# -# See include/freetype/ftotval.h for the API. -BASE_EXTENSIONS += ftotval.c - -# Support for FT_Face_CheckTrueTypePatents. -# -# See include/freetype/freetype.h for the API. -BASE_EXTENSIONS += ftpatent.c - -# Interface for accessing PFR-specific data. Needs PFR font driver. -# -# See include/freetype/ftpfr.h for the API. -BASE_EXTENSIONS += ftpfr.c - -# Path stroker. Needs ftglyph.c. -# -# See include/freetype/ftstroke.h for the API. -BASE_EXTENSIONS += ftstroke.c - -# Support for synthetic emboldening and slanting of fonts. Needs ftbitmap.c. -# -# See include/freetype/ftsynth.h for the API. -BASE_EXTENSIONS += ftsynth.c - -# Interface to access data specific to PostScript Type 1 and Type 2 (CFF) -# fonts. -# -# See include/freetype/t1tables.h for the API. -BASE_EXTENSIONS += fttype1.c - -# Interface for accessing data specific to Windows FNT files. Needs winfnt -# driver. -# -# See include/freetype/ftwinfnt.h for the API. -BASE_EXTENSIONS += ftwinfnt.c - -#### -#### The components `ftsystem.c' (for memory allocation and stream I/O -#### management) and `ftdebug.c' (for emitting debug messages to the user) -#### are controlled with the following variables. -#### -#### ftsystem.c: $(FTSYS_SRC) -#### ftdebug.c: $(FTDEBUG_SRC) -#### -#### Please refer to docs/CUSTOMIZE for details. -#### - - -# EOF diff --git a/sdk/lib/3rdparty/freetype/objs/README b/sdk/lib/3rdparty/freetype/objs/README deleted file mode 100644 index befb63e049201..0000000000000 --- a/sdk/lib/3rdparty/freetype/objs/README +++ /dev/null @@ -1,2 +0,0 @@ -This directory contains all the object files created when building the -library. diff --git a/sdk/lib/3rdparty/freetype/src/autofit/afangles.c b/sdk/lib/3rdparty/freetype/src/autofit/afangles.c index c65a3ae23e92e..9e1f7a21ffd74 100644 --- a/sdk/lib/3rdparty/freetype/src/autofit/afangles.c +++ b/sdk/lib/3rdparty/freetype/src/autofit/afangles.c @@ -1,28 +1,28 @@ -/***************************************************************************/ -/* */ -/* afangles.c */ -/* */ -/* Routines used to compute vector angles with limited accuracy */ -/* and very high speed. It also contains sorting routines (body). */ -/* */ -/* Copyright 2003-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * afangles.c + * + * Routines used to compute vector angles with limited accuracy + * and very high speed. It also contains sorting routines (body). + * + * Copyright (C) 2003-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include "aftypes.h" /* - * We are not using `af_angle_atan' anymore, but we keep the source - * code below just in case... + * We are not using `af_angle_atan' anymore, but we keep the source + * code below just in case... */ @@ -30,16 +30,16 @@ /* - * The trick here is to realize that we don't need a very accurate angle - * approximation. We are going to use the result of `af_angle_atan' to - * only compare the sign of angle differences, or check whether its - * magnitude is very small. + * The trick here is to realize that we don't need a very accurate angle + * approximation. We are going to use the result of `af_angle_atan' to + * only compare the sign of angle differences, or check whether its + * magnitude is very small. * - * The approximation + * The approximation * - * dy * PI / (|dx|+|dy|) + * dy * PI / (|dx|+|dy|) * - * should be enough, and much faster to compute. + * should be enough, and much faster to compute. */ FT_LOCAL_DEF( AF_Angle ) af_angle_atan( FT_Fixed dx, diff --git a/sdk/lib/3rdparty/freetype/src/autofit/afangles.h b/sdk/lib/3rdparty/freetype/src/autofit/afangles.h index f33f9e108e32e..18d7dae3a6b1c 100644 --- a/sdk/lib/3rdparty/freetype/src/autofit/afangles.h +++ b/sdk/lib/3rdparty/freetype/src/autofit/afangles.h @@ -1,7 +1,7 @@ /* - * afangles.h + * afangles.h * - * This is a dummy file, used to please the build system. It is never - * included by the auto-fitter sources. + * This is a dummy file, used to please the build system. It is never + * included by the auto-fitter sources. * */ diff --git a/sdk/lib/3rdparty/freetype/src/autofit/afblue.c b/sdk/lib/3rdparty/freetype/src/autofit/afblue.c index 61ab7957f0ceb..28da159008e11 100644 --- a/sdk/lib/3rdparty/freetype/src/autofit/afblue.c +++ b/sdk/lib/3rdparty/freetype/src/autofit/afblue.c @@ -1,22 +1,22 @@ /* This file has been generated by the Perl script `afblue.pl', */ /* using data from file `afblue.dat'. */ -/***************************************************************************/ -/* */ -/* afblue.c */ -/* */ -/* Auto-fitter data for blue strings (body). */ -/* */ -/* Copyright 2013-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * afblue.c + * + * Auto-fitter data for blue strings (body). + * + * Copyright (C) 2013-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include "aftypes.h" @@ -166,6 +166,10 @@ '\0', '\xE2', '\xB4', '\x84', ' ', '\xE2', '\xB4', '\x85', ' ', '\xE2', '\xB4', '\x94', ' ', '\xE2', '\xB4', '\x95', ' ', '\xE2', '\xB4', '\x81', ' ', '\xE2', '\xB4', '\x82', ' ', '\xE2', '\xB4', '\x98', ' ', '\xE2', '\xB4', '\x9D', /* ⴄ ⴅ ⴔ ⴕ ⴁ ⴂ ⴘ ⴝ */ '\0', + '\xE1', '\xB2', '\x9C', ' ', '\xE1', '\xB2', '\x9F', ' ', '\xE1', '\xB2', '\xB3', ' ', '\xE1', '\xB2', '\xB8', ' ', '\xE1', '\xB2', '\x92', ' ', '\xE1', '\xB2', '\x94', ' ', '\xE1', '\xB2', '\x9D', ' ', '\xE1', '\xB2', '\xB4', /* Ნ Ჟ Ჳ Ჸ Გ Ე Ო Ჴ */ + '\0', + '\xE1', '\xB2', '\x98', ' ', '\xE1', '\xB2', '\xB2', ' ', '\xE1', '\xB2', '\x9D', ' ', '\xE1', '\xB2', '\xA9', ' ', '\xE1', '\xB2', '\x9B', ' ', '\xE1', '\xB2', '\xA8', ' ', '\xE1', '\xB2', '\xAF', ' ', '\xE1', '\xB2', '\xBD', /* Ი Ჲ Ო Ჩ Მ Შ Ჯ Ჽ */ + '\0', '\xE2', '\xB0', '\x85', ' ', '\xE2', '\xB0', '\x94', ' ', '\xE2', '\xB0', '\xAA', ' ', '\xE2', '\xB0', '\x84', ' ', '\xE2', '\xB0', '\x82', ' ', '\xE2', '\xB0', '\x8A', ' ', '\xE2', '\xB0', '\xAB', ' ', '\xE2', '\xB0', '\x8B', /* Ⰵ Ⱄ Ⱚ Ⰴ Ⰲ Ⰺ Ⱛ Ⰻ */ '\0', '\xE2', '\xB0', '\x85', ' ', '\xE2', '\xB0', '\x84', ' ', '\xE2', '\xB0', '\x82', ' ', '\xE2', '\xB0', '\xAA', ' ', '\xE2', '\xB0', '\x9E', ' ', '\xE2', '\xB0', '\xA1', ' ', '\xE2', '\xB0', '\x8A', ' ', '\xE2', '\xB0', '\x94', /* Ⰵ Ⰴ Ⰲ Ⱚ Ⱎ Ⱑ Ⰺ Ⱄ */ @@ -539,6 +543,8 @@ { AF_BLUE_STRING_GEORGIAN_MKHEDRULI_BOTTOM, 0 }, { AF_BLUE_STRING_GEORGIAN_MKHEDRULI_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }, { AF_BLUE_STRING_GEORGIAN_MKHEDRULI_DESCENDER, 0 }, + { AF_BLUE_STRING_GEORGIAN_MTAVRULI_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_GEORGIAN_MTAVRULI_BOTTOM, 0 }, { AF_BLUE_STRING_MAX, 0 }, { AF_BLUE_STRING_GEORGIAN_ASOMTAVRULI_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, { AF_BLUE_STRING_GEORGIAN_ASOMTAVRULI_BOTTOM, 0 }, diff --git a/sdk/lib/3rdparty/freetype/src/autofit/afblue.cin b/sdk/lib/3rdparty/freetype/src/autofit/afblue.cin index 4913e2eb6f231..6545d1fd433b0 100644 --- a/sdk/lib/3rdparty/freetype/src/autofit/afblue.cin +++ b/sdk/lib/3rdparty/freetype/src/autofit/afblue.cin @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* afblue.c */ -/* */ -/* Auto-fitter data for blue strings (body). */ -/* */ -/* Copyright 2013-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * afblue.c + * + * Auto-fitter data for blue strings (body). + * + * Copyright (C) 2013-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include "aftypes.h" diff --git a/sdk/lib/3rdparty/freetype/src/autofit/afblue.dat b/sdk/lib/3rdparty/freetype/src/autofit/afblue.dat index d3cc4284b87e0..14a0993b61d93 100644 --- a/sdk/lib/3rdparty/freetype/src/autofit/afblue.dat +++ b/sdk/lib/3rdparty/freetype/src/autofit/afblue.dat @@ -1,15 +1,15 @@ -// afblue.dat +// afblue.dat // -// Auto-fitter data for blue strings. +// Auto-fitter data for blue strings. // -// Copyright 2013-2018 by -// David Turner, Robert Wilhelm, and Werner Lemberg. +// Copyright (C) 2013-2019 by +// David Turner, Robert Wilhelm, and Werner Lemberg. // -// This file is part of the FreeType project, and may only be used, -// modified, and distributed under the terms of the FreeType project -// license, LICENSE.TXT. By continuing to use, modify, or distribute -// this file you indicate that you have read the license and -// understand and accept it fully. +// This file is part of the FreeType project, and may only be used, +// modified, and distributed under the terms of the FreeType project +// license, LICENSE.TXT. By continuing to use, modify, or distribute +// this file you indicate that you have read the license and +// understand and accept it fully. // This file contains data specific to blue zones. It gets processed by @@ -242,6 +242,11 @@ AF_BLUE_STRING_ENUM AF_BLUE_STRINGS_ARRAY AF_BLUE_STRING_MAX_LEN: AF_BLUE_STRING_GEORGIAN_NUSKHURI_DESCENDER "ⴄ ⴅ ⴔ ⴕ ⴁ ⴂ ⴘ ⴝ" + AF_BLUE_STRING_GEORGIAN_MTAVRULI_TOP + "Ნ Ჟ Ჳ Ჸ Გ Ე Ო Ჴ" + AF_BLUE_STRING_GEORGIAN_MTAVRULI_BOTTOM + "Ი Ჲ Ო Ჩ Მ Შ Ჯ Ჽ" + AF_BLUE_STRING_GLAGOLITIC_CAPITAL_TOP "Ⰵ Ⱄ Ⱚ Ⰴ Ⰲ Ⰺ Ⱛ Ⰻ" AF_BLUE_STRING_GLAGOLITIC_CAPITAL_BOTTOM @@ -795,13 +800,14 @@ AF_BLUE_STRINGSET_ENUM AF_BLUE_STRINGSETS_ARRAY AF_BLUE_STRINGSET_MAX_LEN: { AF_BLUE_STRING_ETHIOPIC_BOTTOM, 0 } { AF_BLUE_STRING_MAX, 0 } - // blue zones for Mtavruli are missing (not yet defined in Unicode) AF_BLUE_STRINGSET_GEOR { AF_BLUE_STRING_GEORGIAN_MKHEDRULI_TOP, AF_BLUE_PROPERTY_LATIN_TOP | AF_BLUE_PROPERTY_LATIN_X_HEIGHT } { AF_BLUE_STRING_GEORGIAN_MKHEDRULI_BOTTOM, 0 } { AF_BLUE_STRING_GEORGIAN_MKHEDRULI_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP } { AF_BLUE_STRING_GEORGIAN_MKHEDRULI_DESCENDER, 0 } + { AF_BLUE_STRING_GEORGIAN_MTAVRULI_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_GEORGIAN_MTAVRULI_BOTTOM, 0 } { AF_BLUE_STRING_MAX, 0 } AF_BLUE_STRINGSET_GEOK diff --git a/sdk/lib/3rdparty/freetype/src/autofit/afblue.h b/sdk/lib/3rdparty/freetype/src/autofit/afblue.h index 56b591aa8df6b..a2ff597b8eb84 100644 --- a/sdk/lib/3rdparty/freetype/src/autofit/afblue.h +++ b/sdk/lib/3rdparty/freetype/src/autofit/afblue.h @@ -1,22 +1,22 @@ /* This file has been generated by the Perl script `afblue.pl', */ /* using data from file `afblue.dat'. */ -/***************************************************************************/ -/* */ -/* afblue.h */ -/* */ -/* Auto-fitter data for blue strings (specification). */ -/* */ -/* Copyright 2013-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * afblue.h + * + * Auto-fitter data for blue strings (specification). + * + * Copyright (C) 2013-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef AFBLUE_H_ @@ -147,119 +147,121 @@ FT_BEGIN_HEADER AF_BLUE_STRING_GEORGIAN_NUSKHURI_BOTTOM = 1813, AF_BLUE_STRING_GEORGIAN_NUSKHURI_ASCENDER = 1845, AF_BLUE_STRING_GEORGIAN_NUSKHURI_DESCENDER = 1877, - AF_BLUE_STRING_GLAGOLITIC_CAPITAL_TOP = 1909, - AF_BLUE_STRING_GLAGOLITIC_CAPITAL_BOTTOM = 1941, - AF_BLUE_STRING_GLAGOLITIC_SMALL_TOP = 1973, - AF_BLUE_STRING_GLAGOLITIC_SMALL_BOTTOM = 2005, - AF_BLUE_STRING_GOTHIC_TOP = 2037, - AF_BLUE_STRING_GOTHIC_BOTTOM = 2077, - AF_BLUE_STRING_GREEK_CAPITAL_TOP = 2097, - AF_BLUE_STRING_GREEK_CAPITAL_BOTTOM = 2118, - AF_BLUE_STRING_GREEK_SMALL_BETA_TOP = 2136, - AF_BLUE_STRING_GREEK_SMALL = 2154, - AF_BLUE_STRING_GREEK_SMALL_DESCENDER = 2178, - AF_BLUE_STRING_GUJARATI_TOP = 2202, - AF_BLUE_STRING_GUJARATI_BOTTOM = 2234, - AF_BLUE_STRING_GUJARATI_ASCENDER = 2266, - AF_BLUE_STRING_GUJARATI_DESCENDER = 2316, - AF_BLUE_STRING_GUJARATI_DIGIT_TOP = 2349, - AF_BLUE_STRING_GURMUKHI_BASE = 2369, - AF_BLUE_STRING_GURMUKHI_HEAD = 2401, - AF_BLUE_STRING_GURMUKHI_TOP = 2433, - AF_BLUE_STRING_GURMUKHI_BOTTOM = 2465, - AF_BLUE_STRING_GURMUKHI_DIGIT_TOP = 2497, - AF_BLUE_STRING_HEBREW_TOP = 2517, - AF_BLUE_STRING_HEBREW_BOTTOM = 2541, - AF_BLUE_STRING_HEBREW_DESCENDER = 2559, - AF_BLUE_STRING_KANNADA_TOP = 2574, - AF_BLUE_STRING_KANNADA_BOTTOM = 2618, - AF_BLUE_STRING_KAYAH_LI_TOP = 2650, - AF_BLUE_STRING_KAYAH_LI_BOTTOM = 2674, - AF_BLUE_STRING_KAYAH_LI_ASCENDER = 2694, - AF_BLUE_STRING_KAYAH_LI_DESCENDER = 2702, - AF_BLUE_STRING_KAYAH_LI_LARGE_DESCENDER = 2714, - AF_BLUE_STRING_KHMER_TOP = 2735, - AF_BLUE_STRING_KHMER_SUBSCRIPT_TOP = 2759, - AF_BLUE_STRING_KHMER_BOTTOM = 2799, - AF_BLUE_STRING_KHMER_DESCENDER = 2831, - AF_BLUE_STRING_KHMER_LARGE_DESCENDER = 2865, - AF_BLUE_STRING_KHMER_SYMBOLS_WAXING_TOP = 2952, - AF_BLUE_STRING_KHMER_SYMBOLS_WANING_BOTTOM = 2960, - AF_BLUE_STRING_LAO_TOP = 2968, - AF_BLUE_STRING_LAO_BOTTOM = 3000, - AF_BLUE_STRING_LAO_ASCENDER = 3032, - AF_BLUE_STRING_LAO_LARGE_ASCENDER = 3048, - AF_BLUE_STRING_LAO_DESCENDER = 3060, - AF_BLUE_STRING_LATIN_CAPITAL_TOP = 3084, - AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM = 3100, - AF_BLUE_STRING_LATIN_SMALL_F_TOP = 3116, - AF_BLUE_STRING_LATIN_SMALL_TOP = 3130, - AF_BLUE_STRING_LATIN_SMALL_BOTTOM = 3146, - AF_BLUE_STRING_LATIN_SMALL_DESCENDER = 3162, - AF_BLUE_STRING_LATIN_SUBS_CAPITAL_TOP = 3172, - AF_BLUE_STRING_LATIN_SUBS_CAPITAL_BOTTOM = 3192, - AF_BLUE_STRING_LATIN_SUBS_SMALL_F_TOP = 3212, - AF_BLUE_STRING_LATIN_SUBS_SMALL = 3232, - AF_BLUE_STRING_LATIN_SUBS_SMALL_DESCENDER = 3268, - AF_BLUE_STRING_LATIN_SUPS_CAPITAL_TOP = 3288, - AF_BLUE_STRING_LATIN_SUPS_CAPITAL_BOTTOM = 3319, - AF_BLUE_STRING_LATIN_SUPS_SMALL_F_TOP = 3348, - AF_BLUE_STRING_LATIN_SUPS_SMALL = 3374, - AF_BLUE_STRING_LATIN_SUPS_SMALL_DESCENDER = 3399, - AF_BLUE_STRING_LISU_TOP = 3410, - AF_BLUE_STRING_LISU_BOTTOM = 3442, - AF_BLUE_STRING_MALAYALAM_TOP = 3474, - AF_BLUE_STRING_MALAYALAM_BOTTOM = 3518, - AF_BLUE_STRING_MYANMAR_TOP = 3550, - AF_BLUE_STRING_MYANMAR_BOTTOM = 3582, - AF_BLUE_STRING_MYANMAR_ASCENDER = 3614, - AF_BLUE_STRING_MYANMAR_DESCENDER = 3642, - AF_BLUE_STRING_NKO_TOP = 3674, - AF_BLUE_STRING_NKO_BOTTOM = 3698, - AF_BLUE_STRING_NKO_SMALL_TOP = 3713, - AF_BLUE_STRING_NKO_SMALL_BOTTOM = 3722, - AF_BLUE_STRING_OL_CHIKI = 3734, - AF_BLUE_STRING_OLD_TURKIC_TOP = 3758, - AF_BLUE_STRING_OLD_TURKIC_BOTTOM = 3773, - AF_BLUE_STRING_OSAGE_CAPITAL_TOP = 3793, - AF_BLUE_STRING_OSAGE_CAPITAL_BOTTOM = 3833, - AF_BLUE_STRING_OSAGE_CAPITAL_DESCENDER = 3863, - AF_BLUE_STRING_OSAGE_SMALL_TOP = 3878, - AF_BLUE_STRING_OSAGE_SMALL_BOTTOM = 3918, - AF_BLUE_STRING_OSAGE_SMALL_ASCENDER = 3958, - AF_BLUE_STRING_OSAGE_SMALL_DESCENDER = 3983, - AF_BLUE_STRING_OSMANYA_TOP = 3998, - AF_BLUE_STRING_OSMANYA_BOTTOM = 4038, - AF_BLUE_STRING_SAURASHTRA_TOP = 4078, - AF_BLUE_STRING_SAURASHTRA_BOTTOM = 4110, - AF_BLUE_STRING_SHAVIAN_TOP = 4130, - AF_BLUE_STRING_SHAVIAN_BOTTOM = 4140, - AF_BLUE_STRING_SHAVIAN_DESCENDER = 4165, - AF_BLUE_STRING_SHAVIAN_SMALL_TOP = 4175, - AF_BLUE_STRING_SHAVIAN_SMALL_BOTTOM = 4210, - AF_BLUE_STRING_SINHALA_TOP = 4225, - AF_BLUE_STRING_SINHALA_BOTTOM = 4257, - AF_BLUE_STRING_SINHALA_DESCENDER = 4289, - AF_BLUE_STRING_SUNDANESE_TOP = 4333, - AF_BLUE_STRING_SUNDANESE_BOTTOM = 4357, - AF_BLUE_STRING_SUNDANESE_DESCENDER = 4389, - AF_BLUE_STRING_TAI_VIET_TOP = 4397, - AF_BLUE_STRING_TAI_VIET_BOTTOM = 4417, - AF_BLUE_STRING_TAMIL_TOP = 4429, - AF_BLUE_STRING_TAMIL_BOTTOM = 4461, - AF_BLUE_STRING_TELUGU_TOP = 4493, - AF_BLUE_STRING_TELUGU_BOTTOM = 4521, - AF_BLUE_STRING_THAI_TOP = 4549, - AF_BLUE_STRING_THAI_BOTTOM = 4573, - AF_BLUE_STRING_THAI_ASCENDER = 4601, - AF_BLUE_STRING_THAI_LARGE_ASCENDER = 4613, - AF_BLUE_STRING_THAI_DESCENDER = 4625, - AF_BLUE_STRING_THAI_LARGE_DESCENDER = 4641, - AF_BLUE_STRING_THAI_DIGIT_TOP = 4649, - AF_BLUE_STRING_TIFINAGH = 4661, - AF_BLUE_STRING_VAI_TOP = 4693, - AF_BLUE_STRING_VAI_BOTTOM = 4725, - af_blue_1_1 = 4756, + AF_BLUE_STRING_GEORGIAN_MTAVRULI_TOP = 1909, + AF_BLUE_STRING_GEORGIAN_MTAVRULI_BOTTOM = 1941, + AF_BLUE_STRING_GLAGOLITIC_CAPITAL_TOP = 1973, + AF_BLUE_STRING_GLAGOLITIC_CAPITAL_BOTTOM = 2005, + AF_BLUE_STRING_GLAGOLITIC_SMALL_TOP = 2037, + AF_BLUE_STRING_GLAGOLITIC_SMALL_BOTTOM = 2069, + AF_BLUE_STRING_GOTHIC_TOP = 2101, + AF_BLUE_STRING_GOTHIC_BOTTOM = 2141, + AF_BLUE_STRING_GREEK_CAPITAL_TOP = 2161, + AF_BLUE_STRING_GREEK_CAPITAL_BOTTOM = 2182, + AF_BLUE_STRING_GREEK_SMALL_BETA_TOP = 2200, + AF_BLUE_STRING_GREEK_SMALL = 2218, + AF_BLUE_STRING_GREEK_SMALL_DESCENDER = 2242, + AF_BLUE_STRING_GUJARATI_TOP = 2266, + AF_BLUE_STRING_GUJARATI_BOTTOM = 2298, + AF_BLUE_STRING_GUJARATI_ASCENDER = 2330, + AF_BLUE_STRING_GUJARATI_DESCENDER = 2380, + AF_BLUE_STRING_GUJARATI_DIGIT_TOP = 2413, + AF_BLUE_STRING_GURMUKHI_BASE = 2433, + AF_BLUE_STRING_GURMUKHI_HEAD = 2465, + AF_BLUE_STRING_GURMUKHI_TOP = 2497, + AF_BLUE_STRING_GURMUKHI_BOTTOM = 2529, + AF_BLUE_STRING_GURMUKHI_DIGIT_TOP = 2561, + AF_BLUE_STRING_HEBREW_TOP = 2581, + AF_BLUE_STRING_HEBREW_BOTTOM = 2605, + AF_BLUE_STRING_HEBREW_DESCENDER = 2623, + AF_BLUE_STRING_KANNADA_TOP = 2638, + AF_BLUE_STRING_KANNADA_BOTTOM = 2682, + AF_BLUE_STRING_KAYAH_LI_TOP = 2714, + AF_BLUE_STRING_KAYAH_LI_BOTTOM = 2738, + AF_BLUE_STRING_KAYAH_LI_ASCENDER = 2758, + AF_BLUE_STRING_KAYAH_LI_DESCENDER = 2766, + AF_BLUE_STRING_KAYAH_LI_LARGE_DESCENDER = 2778, + AF_BLUE_STRING_KHMER_TOP = 2799, + AF_BLUE_STRING_KHMER_SUBSCRIPT_TOP = 2823, + AF_BLUE_STRING_KHMER_BOTTOM = 2863, + AF_BLUE_STRING_KHMER_DESCENDER = 2895, + AF_BLUE_STRING_KHMER_LARGE_DESCENDER = 2929, + AF_BLUE_STRING_KHMER_SYMBOLS_WAXING_TOP = 3016, + AF_BLUE_STRING_KHMER_SYMBOLS_WANING_BOTTOM = 3024, + AF_BLUE_STRING_LAO_TOP = 3032, + AF_BLUE_STRING_LAO_BOTTOM = 3064, + AF_BLUE_STRING_LAO_ASCENDER = 3096, + AF_BLUE_STRING_LAO_LARGE_ASCENDER = 3112, + AF_BLUE_STRING_LAO_DESCENDER = 3124, + AF_BLUE_STRING_LATIN_CAPITAL_TOP = 3148, + AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM = 3164, + AF_BLUE_STRING_LATIN_SMALL_F_TOP = 3180, + AF_BLUE_STRING_LATIN_SMALL_TOP = 3194, + AF_BLUE_STRING_LATIN_SMALL_BOTTOM = 3210, + AF_BLUE_STRING_LATIN_SMALL_DESCENDER = 3226, + AF_BLUE_STRING_LATIN_SUBS_CAPITAL_TOP = 3236, + AF_BLUE_STRING_LATIN_SUBS_CAPITAL_BOTTOM = 3256, + AF_BLUE_STRING_LATIN_SUBS_SMALL_F_TOP = 3276, + AF_BLUE_STRING_LATIN_SUBS_SMALL = 3296, + AF_BLUE_STRING_LATIN_SUBS_SMALL_DESCENDER = 3332, + AF_BLUE_STRING_LATIN_SUPS_CAPITAL_TOP = 3352, + AF_BLUE_STRING_LATIN_SUPS_CAPITAL_BOTTOM = 3383, + AF_BLUE_STRING_LATIN_SUPS_SMALL_F_TOP = 3412, + AF_BLUE_STRING_LATIN_SUPS_SMALL = 3438, + AF_BLUE_STRING_LATIN_SUPS_SMALL_DESCENDER = 3463, + AF_BLUE_STRING_LISU_TOP = 3474, + AF_BLUE_STRING_LISU_BOTTOM = 3506, + AF_BLUE_STRING_MALAYALAM_TOP = 3538, + AF_BLUE_STRING_MALAYALAM_BOTTOM = 3582, + AF_BLUE_STRING_MYANMAR_TOP = 3614, + AF_BLUE_STRING_MYANMAR_BOTTOM = 3646, + AF_BLUE_STRING_MYANMAR_ASCENDER = 3678, + AF_BLUE_STRING_MYANMAR_DESCENDER = 3706, + AF_BLUE_STRING_NKO_TOP = 3738, + AF_BLUE_STRING_NKO_BOTTOM = 3762, + AF_BLUE_STRING_NKO_SMALL_TOP = 3777, + AF_BLUE_STRING_NKO_SMALL_BOTTOM = 3786, + AF_BLUE_STRING_OL_CHIKI = 3798, + AF_BLUE_STRING_OLD_TURKIC_TOP = 3822, + AF_BLUE_STRING_OLD_TURKIC_BOTTOM = 3837, + AF_BLUE_STRING_OSAGE_CAPITAL_TOP = 3857, + AF_BLUE_STRING_OSAGE_CAPITAL_BOTTOM = 3897, + AF_BLUE_STRING_OSAGE_CAPITAL_DESCENDER = 3927, + AF_BLUE_STRING_OSAGE_SMALL_TOP = 3942, + AF_BLUE_STRING_OSAGE_SMALL_BOTTOM = 3982, + AF_BLUE_STRING_OSAGE_SMALL_ASCENDER = 4022, + AF_BLUE_STRING_OSAGE_SMALL_DESCENDER = 4047, + AF_BLUE_STRING_OSMANYA_TOP = 4062, + AF_BLUE_STRING_OSMANYA_BOTTOM = 4102, + AF_BLUE_STRING_SAURASHTRA_TOP = 4142, + AF_BLUE_STRING_SAURASHTRA_BOTTOM = 4174, + AF_BLUE_STRING_SHAVIAN_TOP = 4194, + AF_BLUE_STRING_SHAVIAN_BOTTOM = 4204, + AF_BLUE_STRING_SHAVIAN_DESCENDER = 4229, + AF_BLUE_STRING_SHAVIAN_SMALL_TOP = 4239, + AF_BLUE_STRING_SHAVIAN_SMALL_BOTTOM = 4274, + AF_BLUE_STRING_SINHALA_TOP = 4289, + AF_BLUE_STRING_SINHALA_BOTTOM = 4321, + AF_BLUE_STRING_SINHALA_DESCENDER = 4353, + AF_BLUE_STRING_SUNDANESE_TOP = 4397, + AF_BLUE_STRING_SUNDANESE_BOTTOM = 4421, + AF_BLUE_STRING_SUNDANESE_DESCENDER = 4453, + AF_BLUE_STRING_TAI_VIET_TOP = 4461, + AF_BLUE_STRING_TAI_VIET_BOTTOM = 4481, + AF_BLUE_STRING_TAMIL_TOP = 4493, + AF_BLUE_STRING_TAMIL_BOTTOM = 4525, + AF_BLUE_STRING_TELUGU_TOP = 4557, + AF_BLUE_STRING_TELUGU_BOTTOM = 4585, + AF_BLUE_STRING_THAI_TOP = 4613, + AF_BLUE_STRING_THAI_BOTTOM = 4637, + AF_BLUE_STRING_THAI_ASCENDER = 4665, + AF_BLUE_STRING_THAI_LARGE_ASCENDER = 4677, + AF_BLUE_STRING_THAI_DESCENDER = 4689, + AF_BLUE_STRING_THAI_LARGE_DESCENDER = 4705, + AF_BLUE_STRING_THAI_DIGIT_TOP = 4713, + AF_BLUE_STRING_TIFINAGH = 4725, + AF_BLUE_STRING_VAI_TOP = 4757, + AF_BLUE_STRING_VAI_BOTTOM = 4789, + af_blue_1_1 = 4820, #ifdef AF_CONFIG_OPTION_CJK AF_BLUE_STRING_CJK_TOP = af_blue_1_1 + 1, AF_BLUE_STRING_CJK_BOTTOM = af_blue_1_1 + 203, @@ -336,41 +338,41 @@ FT_BEGIN_HEADER AF_BLUE_STRINGSET_DSRT = 75, AF_BLUE_STRINGSET_ETHI = 80, AF_BLUE_STRINGSET_GEOR = 83, - AF_BLUE_STRINGSET_GEOK = 88, - AF_BLUE_STRINGSET_GLAG = 95, - AF_BLUE_STRINGSET_GOTH = 100, - AF_BLUE_STRINGSET_GREK = 103, - AF_BLUE_STRINGSET_GUJR = 110, - AF_BLUE_STRINGSET_GURU = 116, - AF_BLUE_STRINGSET_HEBR = 122, - AF_BLUE_STRINGSET_KALI = 126, - AF_BLUE_STRINGSET_KHMR = 132, - AF_BLUE_STRINGSET_KHMS = 138, - AF_BLUE_STRINGSET_KNDA = 141, - AF_BLUE_STRINGSET_LAO = 144, - AF_BLUE_STRINGSET_LATN = 150, - AF_BLUE_STRINGSET_LATB = 157, - AF_BLUE_STRINGSET_LATP = 164, - AF_BLUE_STRINGSET_LISU = 171, - AF_BLUE_STRINGSET_MLYM = 174, - AF_BLUE_STRINGSET_MYMR = 177, - AF_BLUE_STRINGSET_NKOO = 182, - AF_BLUE_STRINGSET_NONE = 187, - AF_BLUE_STRINGSET_OLCK = 188, - AF_BLUE_STRINGSET_ORKH = 191, - AF_BLUE_STRINGSET_OSGE = 194, - AF_BLUE_STRINGSET_OSMA = 202, - AF_BLUE_STRINGSET_SAUR = 205, - AF_BLUE_STRINGSET_SHAW = 208, - AF_BLUE_STRINGSET_SINH = 214, - AF_BLUE_STRINGSET_SUND = 218, - AF_BLUE_STRINGSET_TAML = 222, - AF_BLUE_STRINGSET_TAVT = 225, - AF_BLUE_STRINGSET_TELU = 228, - AF_BLUE_STRINGSET_TFNG = 231, - AF_BLUE_STRINGSET_THAI = 234, - AF_BLUE_STRINGSET_VAII = 242, - af_blue_2_1 = 245, + AF_BLUE_STRINGSET_GEOK = 90, + AF_BLUE_STRINGSET_GLAG = 97, + AF_BLUE_STRINGSET_GOTH = 102, + AF_BLUE_STRINGSET_GREK = 105, + AF_BLUE_STRINGSET_GUJR = 112, + AF_BLUE_STRINGSET_GURU = 118, + AF_BLUE_STRINGSET_HEBR = 124, + AF_BLUE_STRINGSET_KALI = 128, + AF_BLUE_STRINGSET_KHMR = 134, + AF_BLUE_STRINGSET_KHMS = 140, + AF_BLUE_STRINGSET_KNDA = 143, + AF_BLUE_STRINGSET_LAO = 146, + AF_BLUE_STRINGSET_LATN = 152, + AF_BLUE_STRINGSET_LATB = 159, + AF_BLUE_STRINGSET_LATP = 166, + AF_BLUE_STRINGSET_LISU = 173, + AF_BLUE_STRINGSET_MLYM = 176, + AF_BLUE_STRINGSET_MYMR = 179, + AF_BLUE_STRINGSET_NKOO = 184, + AF_BLUE_STRINGSET_NONE = 189, + AF_BLUE_STRINGSET_OLCK = 190, + AF_BLUE_STRINGSET_ORKH = 193, + AF_BLUE_STRINGSET_OSGE = 196, + AF_BLUE_STRINGSET_OSMA = 204, + AF_BLUE_STRINGSET_SAUR = 207, + AF_BLUE_STRINGSET_SHAW = 210, + AF_BLUE_STRINGSET_SINH = 216, + AF_BLUE_STRINGSET_SUND = 220, + AF_BLUE_STRINGSET_TAML = 224, + AF_BLUE_STRINGSET_TAVT = 227, + AF_BLUE_STRINGSET_TELU = 230, + AF_BLUE_STRINGSET_TFNG = 233, + AF_BLUE_STRINGSET_THAI = 236, + AF_BLUE_STRINGSET_VAII = 244, + af_blue_2_1 = 247, #ifdef AF_CONFIG_OPTION_CJK AF_BLUE_STRINGSET_HANI = af_blue_2_1 + 0, af_blue_2_1_1 = af_blue_2_1 + 2, diff --git a/sdk/lib/3rdparty/freetype/src/autofit/afblue.hin b/sdk/lib/3rdparty/freetype/src/autofit/afblue.hin index 682147cb30dba..30a28dafa5347 100644 --- a/sdk/lib/3rdparty/freetype/src/autofit/afblue.hin +++ b/sdk/lib/3rdparty/freetype/src/autofit/afblue.hin @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* afblue.h */ -/* */ -/* Auto-fitter data for blue strings (specification). */ -/* */ -/* Copyright 2013-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * afblue.h + * + * Auto-fitter data for blue strings (specification). + * + * Copyright (C) 2013-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef AFBLUE_H_ diff --git a/sdk/lib/3rdparty/freetype/src/autofit/afcjk.c b/sdk/lib/3rdparty/freetype/src/autofit/afcjk.c index 40b14ac88cce8..7847ecc8829b7 100644 --- a/sdk/lib/3rdparty/freetype/src/autofit/afcjk.c +++ b/sdk/lib/3rdparty/freetype/src/autofit/afcjk.c @@ -1,24 +1,24 @@ -/***************************************************************************/ -/* */ -/* afcjk.c */ -/* */ -/* Auto-fitter hinting routines for CJK writing system (body). */ -/* */ -/* Copyright 2006-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * afcjk.c + * + * Auto-fitter hinting routines for CJK writing system (body). + * + * Copyright (C) 2006-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ /* - * The algorithm is based on akito's autohint patch, archived at + * The algorithm is based on akito's autohint patch, archived at * - * https://web.archive.org/web/20051219160454/http://www.kde.gr.jp:80/~akito/patch/freetype2/2.1.7/ + * https://web.archive.org/web/20051219160454/http://www.kde.gr.jp:80/~akito/patch/freetype2/2.1.7/ * */ @@ -27,7 +27,6 @@ #include FT_INTERNAL_DEBUG_H #include "afglobal.h" -#include "afpic.h" #include "aflatin.h" #include "afcjk.h" @@ -44,14 +43,14 @@ #endif - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_afcjk +#define FT_COMPONENT afcjk /*************************************************************************/ @@ -72,13 +71,12 @@ { /* scan the array of segments in each direction */ #ifdef __REACTOS__ - AF_GlyphHintsRec *hints = malloc(sizeof(AF_GlyphHintsRec)); + AF_GlyphHintsRec *hints = malloc(sizeof(*hints)); if (!hints) return; #else AF_GlyphHintsRec hints[1]; #endif - FT_TRACE5(( "\n" "cjk standard widths computation (style `%s')\n" "===================================================\n" @@ -95,7 +93,7 @@ FT_ULong glyph_index; int dim; #ifdef __REACTOS__ - AF_CJKMetricsRec *dummy = malloc(sizeof(AF_CJKMetricsRec)); + AF_CJKMetricsRec *dummy = malloc(sizeof(*dummy)); if (!dummy) goto Exit; { @@ -104,23 +102,29 @@ #endif AF_Scaler scaler = &dummy->root.scaler; -#ifdef FT_CONFIG_OPTION_PIC - AF_FaceGlobals globals = metrics->root.globals; -#endif - AF_StyleClass style_class = metrics->root.style_class; - AF_ScriptClass script_class = AF_SCRIPT_CLASSES_GET - [style_class->script]; + AF_ScriptClass script_class = af_script_classes[style_class->script]; + + /* If HarfBuzz is not available, we need a pointer to a single */ + /* unsigned long value. */ +#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ + void* shaper_buf; +#else + FT_ULong shaper_buf_; + void* shaper_buf = &shaper_buf_; +#endif - void* shaper_buf; const char* p; #ifdef FT_DEBUG_LEVEL_TRACE FT_ULong ch = 0; #endif - p = script_class->standard_charstring; + p = script_class->standard_charstring; + +#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ shaper_buf = af_shaper_buf_create( face ); +#endif /* We check a list of standard characters. The first match wins. */ @@ -205,10 +209,10 @@ goto Exit; /* - * We assume that the glyphs selected for the stem width - * computation are `featureless' enough so that the linking - * algorithm works fine without adjustments of its scoring - * function. + * We assume that the glyphs selected for the stem width + * computation are `featureless' enough so that the linking + * algorithm works fine without adjustments of its scoring + * function. */ af_latin_hints_link_segments( hints, 0, @@ -285,7 +289,6 @@ FT_TRACE5(( "\n" )); af_glyph_hints_done( hints ); - #ifdef __REACTOS__ free(hints); #endif @@ -316,7 +319,14 @@ AF_Blue_Stringset bss = sc->blue_stringset; const AF_Blue_StringRec* bs = &af_blue_stringsets[bss]; - void* shaper_buf; + /* If HarfBuzz is not available, we need a pointer to a single */ + /* unsigned long value. */ +#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ + void* shaper_buf; +#else + FT_ULong shaper_buf_; + void* shaper_buf = &shaper_buf_; +#endif /* we walk over the blue character strings as specified in the */ @@ -327,7 +337,9 @@ "==========================\n" "\n" )); +#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ shaper_buf = af_shaper_buf_create( face ); +#endif for ( ; bs->string != AF_BLUE_STRING_MAX; bs++ ) { @@ -503,8 +515,8 @@ if ( num_flats == 0 && num_fills == 0 ) { /* - * we couldn't find a single glyph to compute this blue zone, - * we will simply ignore it then + * we couldn't find a single glyph to compute this blue zone, + * we will simply ignore it then */ FT_TRACE5(( " empty\n" )); continue; @@ -585,15 +597,25 @@ FT_Bool started = 0, same_width = 1; FT_Fixed advance = 0, old_advance = 0; - void* shaper_buf; + /* If HarfBuzz is not available, we need a pointer to a single */ + /* unsigned long value. */ +#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ + void* shaper_buf; +#else + FT_ULong shaper_buf_; + void* shaper_buf = &shaper_buf_; +#endif /* in all supported charmaps, digits have character codes 0x30-0x39 */ const char digits[] = "0 1 2 3 4 5 6 7 8 9"; const char* p; - p = digits; + p = digits; + +#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ shaper_buf = af_shaper_buf_create( face ); +#endif while ( *p ) { @@ -910,11 +932,11 @@ } /* - * now compute the `serif' segments + * now compute the `serif' segments * - * In Hanzi, some strokes are wider on one or both of the ends. - * We either identify the stems on the ends as serifs or remove - * the linkage, depending on the length of the stems. + * In Hanzi, some strokes are wider on one or both of the ends. + * We either identify the stems on the ends as serifs or remove + * the linkage, depending on the length of the stems. * */ @@ -1020,21 +1042,21 @@ scale = ( dim == AF_DIMENSION_HORZ ) ? hints->x_scale : hints->y_scale; - /*********************************************************************/ - /* */ - /* We begin by generating a sorted table of edges for the current */ - /* direction. To do so, we simply scan each segment and try to find */ - /* an edge in our table that corresponds to its position. */ - /* */ - /* If no edge is found, we create and insert a new edge in the */ - /* sorted table. Otherwise, we simply add the segment to the edge's */ - /* list which is then processed in the second step to compute the */ - /* edge's properties. */ - /* */ - /* Note that the edges table is sorted along the segment/edge */ - /* position. */ - /* */ - /*********************************************************************/ + /********************************************************************** + * + * We begin by generating a sorted table of edges for the current + * direction. To do so, we simply scan each segment and try to find + * an edge in our table that corresponds to its position. + * + * If no edge is found, we create and insert a new edge in the + * sorted table. Otherwise, we simply add the segment to the edge's + * list which is then processed in the second step to compute the + * edge's properties. + * + * Note that the edges table is sorted along the segment/edge + * position. + * + */ edge_distance_threshold = FT_MulFix( laxis->edge_distance_threshold, scale ); @@ -1134,17 +1156,17 @@ } } - /******************************************************************/ - /* */ - /* Good, we now compute each edge's properties according to the */ - /* segments found on its position. Basically, these are */ - /* */ - /* - the edge's main direction */ - /* - stem edge, serif edge or both (which defaults to stem then) */ - /* - rounded edge, straight or both (which defaults to straight) */ - /* - link for edge */ - /* */ - /******************************************************************/ + /******************************************************************* + * + * Good, we now compute each edge's properties according to the + * segments found on its position. Basically, these are + * + * - the edge's main direction + * - stem edge, serif edge or both (which defaults to stem then) + * - rounded edge, straight or both (which defaults to straight) + * - link for edge + * + */ /* first of all, set the `edge' field in each segment -- this is */ /* required in order to compute edge links */ @@ -1194,7 +1216,7 @@ /* check for links -- if seg->serif is set, then seg->link must */ /* be ignored */ - is_serif = (FT_Bool)( seg->serif && seg->serif->edge != edge ); + is_serif = FT_BOOL( seg->serif && seg->serif->edge != edge ); if ( seg->link || is_serif ) { @@ -1384,8 +1406,8 @@ af_glyph_hints_rescale( hints, (AF_StyleMetrics)metrics ); /* - * correct x_scale and y_scale when needed, since they may have - * been modified af_cjk_scale_dim above + * correct x_scale and y_scale when needed, since they may have + * been modified af_cjk_scale_dim above */ hints->x_scale = metrics->axis[AF_DIMENSION_HORZ].scale; hints->x_delta = metrics->axis[AF_DIMENSION_HORZ].delta; @@ -1404,21 +1426,21 @@ other_flags = 0; /* - * We snap the width of vertical stems for the monochrome and - * horizontal LCD rendering targets only. + * We snap the width of vertical stems for the monochrome and + * horizontal LCD rendering targets only. */ if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD ) other_flags |= AF_LATIN_HINTS_HORZ_SNAP; /* - * We snap the width of horizontal stems for the monochrome and - * vertical LCD rendering targets only. + * We snap the width of horizontal stems for the monochrome and + * vertical LCD rendering targets only. */ if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD_V ) other_flags |= AF_LATIN_HINTS_VERT_SNAP; /* - * We adjust stems to full pixels unless in `light' or `lcd' mode. + * We adjust stems to full pixels unless in `light' or `lcd' mode. */ if ( mode != FT_RENDER_MODE_LIGHT && mode != FT_RENDER_MODE_LCD ) other_flags |= AF_LATIN_HINTS_STEM_ADJUST; @@ -2114,8 +2136,8 @@ goto Exit; /* - * now hint the remaining edges (serifs and single) in order - * to complete our processing + * now hint the remaining edges (serifs and single) in order + * to complete our processing */ for ( edge = edges; edge < edge_limit; edge++ ) { diff --git a/sdk/lib/3rdparty/freetype/src/autofit/afcjk.h b/sdk/lib/3rdparty/freetype/src/autofit/afcjk.h index d229c0c9cff30..59acae5342905 100644 --- a/sdk/lib/3rdparty/freetype/src/autofit/afcjk.h +++ b/sdk/lib/3rdparty/freetype/src/autofit/afcjk.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* afcjk.h */ -/* */ -/* Auto-fitter hinting routines for CJK writing system (specification). */ -/* */ -/* Copyright 2006-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * afcjk.h + * + * Auto-fitter hinting routines for CJK writing system (specification). + * + * Copyright (C) 2006-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef AFCJK_H_ @@ -41,9 +41,9 @@ FT_BEGIN_HEADER /* - * CJK glyphs tend to fill the square. So we have both vertical and - * horizontal blue zones. But some glyphs have flat bounding strokes that - * leave some space between neighbour glyphs. + * CJK glyphs tend to fill the square. So we have both vertical and + * horizontal blue zones. But some glyphs have flat bounding strokes that + * leave some space between neighbour glyphs. */ #define AF_CJK_IS_TOP_BLUE( b ) \ diff --git a/sdk/lib/3rdparty/freetype/src/autofit/afcover.h b/sdk/lib/3rdparty/freetype/src/autofit/afcover.h index 6eeb8fc9fb71f..ff207a97e0897 100644 --- a/sdk/lib/3rdparty/freetype/src/autofit/afcover.h +++ b/sdk/lib/3rdparty/freetype/src/autofit/afcover.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* afcover.h */ -/* */ -/* Auto-fitter coverages (specification only). */ -/* */ -/* Copyright 2013-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * afcover.h + * + * Auto-fitter coverages (specification only). + * + * Copyright (C) 2013-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ /* This header file can be included multiple times. */ diff --git a/sdk/lib/3rdparty/freetype/src/autofit/afdummy.c b/sdk/lib/3rdparty/freetype/src/autofit/afdummy.c index f30c517cbb3a1..7e07a41e7dac0 100644 --- a/sdk/lib/3rdparty/freetype/src/autofit/afdummy.c +++ b/sdk/lib/3rdparty/freetype/src/autofit/afdummy.c @@ -1,20 +1,20 @@ -/***************************************************************************/ -/* */ -/* afdummy.c */ -/* */ -/* Auto-fitter dummy routines to be used if no hinting should be */ -/* performed (body). */ -/* */ -/* Copyright 2003-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * afdummy.c + * + * Auto-fitter dummy routines to be used if no hinting should be + * performed (body). + * + * Copyright (C) 2003-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include "afdummy.h" @@ -38,13 +38,15 @@ static FT_Error - af_dummy_hints_apply( FT_UInt glyph_index, - AF_GlyphHints hints, - FT_Outline* outline ) + af_dummy_hints_apply( FT_UInt glyph_index, + AF_GlyphHints hints, + FT_Outline* outline, + AF_StyleMetrics metrics ) { FT_Error error; FT_UNUSED( glyph_index ); + FT_UNUSED( metrics ); error = af_glyph_hints_reload( hints, outline ); diff --git a/sdk/lib/3rdparty/freetype/src/autofit/afdummy.h b/sdk/lib/3rdparty/freetype/src/autofit/afdummy.h index b382acd92ae98..ab9227d35d968 100644 --- a/sdk/lib/3rdparty/freetype/src/autofit/afdummy.h +++ b/sdk/lib/3rdparty/freetype/src/autofit/afdummy.h @@ -1,20 +1,20 @@ -/***************************************************************************/ -/* */ -/* afdummy.h */ -/* */ -/* Auto-fitter dummy routines to be used if no hinting should be */ -/* performed (specification). */ -/* */ -/* Copyright 2003-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * afdummy.h + * + * Auto-fitter dummy routines to be used if no hinting should be + * performed (specification). + * + * Copyright (C) 2003-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef AFDUMMY_H_ diff --git a/sdk/lib/3rdparty/freetype/src/autofit/aferrors.h b/sdk/lib/3rdparty/freetype/src/autofit/aferrors.h index e5de54360f710..2ec336f72c669 100644 --- a/sdk/lib/3rdparty/freetype/src/autofit/aferrors.h +++ b/sdk/lib/3rdparty/freetype/src/autofit/aferrors.h @@ -1,27 +1,27 @@ -/***************************************************************************/ -/* */ -/* aferrors.h */ -/* */ -/* Autofitter error codes (specification only). */ -/* */ -/* Copyright 2005-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to define the Autofitter error enumeration */ - /* constants. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * aferrors.h + * + * Autofitter error codes (specification only). + * + * Copyright (C) 2005-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /************************************************************************** + * + * This file is used to define the Autofitter error enumeration + * constants. + * + */ #ifndef AFERRORS_H_ #define AFERRORS_H_ diff --git a/sdk/lib/3rdparty/freetype/src/autofit/afglobal.c b/sdk/lib/3rdparty/freetype/src/autofit/afglobal.c index 3d09c53e8a0c7..7183ce4a780f5 100644 --- a/sdk/lib/3rdparty/freetype/src/autofit/afglobal.c +++ b/sdk/lib/3rdparty/freetype/src/autofit/afglobal.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* afglobal.c */ -/* */ -/* Auto-fitter routines to compute global hinting values (body). */ -/* */ -/* Copyright 2003-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * afglobal.c + * + * Auto-fitter routines to compute global hinting values (body). + * + * Copyright (C) 2003-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include "afglobal.h" @@ -22,14 +22,14 @@ #include FT_INTERNAL_DEBUG_H - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_afglobal +#define FT_COMPONENT afglobal /* get writing system specific header files */ @@ -38,7 +38,6 @@ #include "afwrtsys.h" #include "aferrors.h" -#include "afpic.h" #undef SCRIPT @@ -67,8 +66,6 @@ #include "afstyles.h" -#ifndef FT_CONFIG_OPTION_PIC - #undef WRITING_SYSTEM #define WRITING_SYSTEM( ws, WS ) \ &af_ ## ws ## _writing_system_class, @@ -110,8 +107,6 @@ NULL /* do not remove */ }; -#endif /* !FT_CONFIG_OPTION_PIC */ - #ifdef FT_DEBUG_LEVEL_TRACE @@ -159,12 +154,12 @@ } /* scan each style in a Unicode charmap */ - for ( ss = 0; AF_STYLE_CLASSES_GET[ss]; ss++ ) + for ( ss = 0; af_style_classes[ss]; ss++ ) { AF_StyleClass style_class = - AF_STYLE_CLASSES_GET[ss]; + af_style_classes[ss]; AF_ScriptClass script_class = - AF_SCRIPT_CLASSES_GET[style_class->script]; + af_script_classes[style_class->script]; AF_Script_UniRange range; @@ -172,8 +167,8 @@ continue; /* - * Scan all Unicode points in the range and set the corresponding - * glyph style index. + * Scan all Unicode points in the range and set the corresponding + * glyph style index. */ if ( style_class->coverage == AF_COVERAGE_DEFAULT ) { @@ -246,9 +241,9 @@ } /* handle the remaining default OpenType features ... */ - for ( ss = 0; AF_STYLE_CLASSES_GET[ss]; ss++ ) + for ( ss = 0; af_style_classes[ss]; ss++ ) { - AF_StyleClass style_class = AF_STYLE_CLASSES_GET[ss]; + AF_StyleClass style_class = af_style_classes[ss]; if ( style_class->coverage == AF_COVERAGE_DEFAULT ) @@ -256,7 +251,7 @@ } /* ... and finally the default OpenType features of the default script */ - af_shaper_get_coverage( globals, AF_STYLE_CLASSES_GET[dflt], gstyles, 1 ); + af_shaper_get_coverage( globals, af_style_classes[dflt], gstyles, 1 ); /* mark ASCII digits */ for ( i = 0x30; i <= 0x39; i++ ) @@ -270,8 +265,8 @@ Exit: /* - * By default, all uncovered glyphs are set to the fallback style. - * XXX: Shouldn't we disable hinting or do something similar? + * By default, all uncovered glyphs are set to the fallback style. + * XXX: Shouldn't we disable hinting or do something similar? */ if ( globals->module->fallback_style != AF_STYLE_UNASSIGNED ) { @@ -295,9 +290,9 @@ "==============\n" "\n" )); - for ( ss = 0; AF_STYLE_CLASSES_GET[ss]; ss++ ) + for ( ss = 0; af_style_classes[ss]; ss++ ) { - AF_StyleClass style_class = AF_STYLE_CLASSES_GET[ss]; + AF_StyleClass style_class = af_style_classes[ss]; FT_UInt count = 0; FT_Long idx; @@ -397,9 +392,9 @@ if ( globals->metrics[nn] ) { AF_StyleClass style_class = - AF_STYLE_CLASSES_GET[nn]; + af_style_classes[nn]; AF_WritingSystemClass writing_system_class = - AF_WRITING_SYSTEM_CLASSES_GET[style_class->writing_system]; + af_writing_system_classes[style_class->writing_system]; if ( writing_system_class->style_metrics_done ) @@ -448,8 +443,8 @@ style = (AF_Style)( globals->glyph_styles[gindex] & AF_STYLE_UNASSIGNED ); - style_class = AF_STYLE_CLASSES_GET[style]; - writing_system_class = AF_WRITING_SYSTEM_CLASSES_GET + style_class = af_style_classes[style]; + writing_system_class = af_writing_system_classes [style_class->writing_system]; metrics = globals->metrics[style]; @@ -494,9 +489,9 @@ FT_UInt gindex ) { if ( gindex < (FT_ULong)globals->glyph_count ) - return (FT_Bool)( globals->glyph_styles[gindex] & AF_DIGIT ); + return FT_BOOL( globals->glyph_styles[gindex] & AF_DIGIT ); - return (FT_Bool)0; + return FT_BOOL( 0 ); } diff --git a/sdk/lib/3rdparty/freetype/src/autofit/afglobal.h b/sdk/lib/3rdparty/freetype/src/autofit/afglobal.h index 489ed46d9ee8e..52f38350db30a 100644 --- a/sdk/lib/3rdparty/freetype/src/autofit/afglobal.h +++ b/sdk/lib/3rdparty/freetype/src/autofit/afglobal.h @@ -1,20 +1,20 @@ -/***************************************************************************/ -/* */ -/* afglobal.h */ -/* */ -/* Auto-fitter routines to compute global hinting values */ -/* (specification). */ -/* */ -/* Copyright 2003-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * afglobal.h + * + * Auto-fitter routines to compute global hinting values + * (specification). + * + * Copyright (C) 2003-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef AFGLOBAL_H_ @@ -60,8 +60,8 @@ FT_BEGIN_HEADER /* - * Default values and flags for both autofitter globals (found in - * AF_ModuleRec) and face globals (in AF_FaceGlobalsRec). + * Default values and flags for both autofitter globals (found in + * AF_ModuleRec) and face globals (in AF_FaceGlobalsRec). */ /* index of fallback style in `af_style_classes' */ @@ -98,8 +98,8 @@ FT_BEGIN_HEADER /* - * Note that glyph_styles[] maps each glyph to an index into the - * `af_style_classes' array. + * Note that glyph_styles[] maps each glyph to an index into the + * `af_style_classes' array. * */ typedef struct AF_FaceGlobalsRec_ @@ -140,8 +140,8 @@ FT_BEGIN_HEADER /* - * model the global hints data for a given face, decomposed into - * style-specific items + * model the global hints data for a given face, decomposed into + * style-specific items */ FT_LOCAL( FT_Error ) diff --git a/sdk/lib/3rdparty/freetype/src/autofit/afhints.c b/sdk/lib/3rdparty/freetype/src/autofit/afhints.c index 0666dbc8e20c7..ed111c41176dc 100644 --- a/sdk/lib/3rdparty/freetype/src/autofit/afhints.c +++ b/sdk/lib/3rdparty/freetype/src/autofit/afhints.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* afhints.c */ -/* */ -/* Auto-fitter hinting routines (body). */ -/* */ -/* Copyright 2003-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * afhints.c + * + * Auto-fitter hinting routines (body). + * + * Copyright (C) 2003-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include "afhints.h" @@ -22,14 +22,14 @@ #include FT_INTERNAL_DEBUG_H - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_afhints +#define FT_COMPONENT afhints /* Get new segment for given axis. */ @@ -297,6 +297,19 @@ } + static int + af_get_strong_edge_index( AF_GlyphHints hints, + AF_Edge* strong_edges, + int dimension ) + { + AF_AxisHints axis = &hints->axis[dimension]; + AF_Edge edges = axis->edges; + + + return AF_INDEX_NUM( strong_edges[dimension], edges ); + } + + #ifdef __cplusplus extern "C" { #endif @@ -317,8 +330,10 @@ { AF_DUMP(( " index hedge hseg vedge vseg flags " /* " XXXXX XXXXX XXXXX XXXXX XXXXX XXXXXX" */ - " xorg yorg xscale yscale xfit yfit" )); + " xorg yorg xscale yscale xfit yfit " /* " XXXXX XXXXX XXXX.XX XXXX.XX XXXX.XX XXXX.XX" */ + " hbef haft vbef vaft" )); + /* " XXXXX XXXXX XXXXX XXXXX" */ } else AF_DUMP(( " (none)\n" )); @@ -330,6 +345,7 @@ int segment_idx_1 = af_get_segment_index( hints, point_idx, 1 ); char buf1[16], buf2[16], buf3[16], buf4[16]; + char buf5[16], buf6[16], buf7[16], buf8[16]; /* insert extra newline at the beginning of a contour */ @@ -340,7 +356,8 @@ } AF_DUMP(( " %5d %5s %5s %5s %5s %s" - " %5d %5d %7.2f %7.2f %7.2f %7.2f\n", + " %5d %5d %7.2f %7.2f %7.2f %7.2f" + " %5s %5s %5s %5s\n", point_idx, af_print_idx( buf1, af_get_edge_index( hints, segment_idx_1, 1 ) ), @@ -359,7 +376,20 @@ point->ox / 64.0, point->oy / 64.0, point->x / 64.0, - point->y / 64.0 )); + point->y / 64.0, + + af_print_idx( buf5, af_get_strong_edge_index( hints, + point->before, + 1 ) ), + af_print_idx( buf6, af_get_strong_edge_index( hints, + point->after, + 1 ) ), + af_print_idx( buf7, af_get_strong_edge_index( hints, + point->before, + 0 ) ), + af_print_idx( buf8, af_get_strong_edge_index( hints, + point->after, + 0 ) ) )); } AF_DUMP(( "\n" )); } @@ -519,7 +549,7 @@ *offset = ( dim == AF_DIMENSION_HORZ ) ? seg->first->fx : seg->first->fy; if ( seg->edge ) - *is_blue = (FT_Bool)( seg->edge->blue_edge != 0 ); + *is_blue = FT_BOOL( seg->edge->blue_edge ); else *is_blue = FALSE; @@ -558,8 +588,8 @@ /* - * note: AF_DIMENSION_HORZ corresponds to _vertical_ edges - * since they have a constant X coordinate. + * note: AF_DIMENSION_HORZ corresponds to _vertical_ edges + * since they have a constant X coordinate. */ if ( dimension == AF_DIMENSION_HORZ ) AF_DUMP(( "Table of %s edges (1px=%.2fu, 10u=%.2fpx):\n", @@ -681,8 +711,8 @@ memory = hints->memory; /* - * note that we don't need to free the segment and edge - * buffers since they are really within the hints->points array + * note that we don't need to free the segment and edge + * buffers since they are really within the hints->points array */ for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) { @@ -776,9 +806,9 @@ } /* - * then reallocate the points arrays if necessary -- - * note that we reserve two additional point positions, used to - * hint metrics appropriately + * then reallocate the points arrays if necessary -- + * note that we reserve two additional point positions, used to + * hint metrics appropriately */ new_max = (FT_UInt)( outline->n_points + 2 ); old_max = (FT_UInt)hints->max_points; @@ -898,6 +928,14 @@ prev = end; } } + +#ifdef FT_DEBUG_AUTOFIT + point->before[0] = NULL; + point->before[1] = NULL; + point->after[0] = NULL; + point->after[1] = NULL; +#endif + } } @@ -918,15 +956,15 @@ { /* - * Compute directions of `in' and `out' vectors. + * Compute directions of `in' and `out' vectors. * - * Note that distances between points that are very near to each - * other are accumulated. In other words, the auto-hinter either - * prepends the small vectors between near points to the first - * non-near vector, or the sum of small vector lengths exceeds a - * threshold, thus `grouping' the small vectors. All intermediate - * points are tagged as weak; the directions are adjusted also to - * be equal to the accumulated one. + * Note that distances between points that are very near to each + * other are accumulated. In other words, the auto-hinter either + * prepends the small vectors between near points to the first + * non-near vector, or the sum of small vector lengths exceeds a + * threshold, thus `grouping' the small vectors. All intermediate + * points are tagged as weak; the directions are adjusted also to + * be equal to the accumulated one. */ FT_Int near_limit2 = 2 * near_limit - 1; @@ -956,12 +994,12 @@ out_y = point->fy - prev->fy; /* - * We use Taxicab metrics to measure the vector length. + * We use Taxicab metrics to measure the vector length. * - * Note that the accumulated distances so far could have the - * opposite direction of the distance measured here. For this - * reason we use `near_limit2' for the comparison to get a - * non-near point even in the worst case. + * Note that the accumulated distances so far could have the + * opposite direction of the distance measured here. For this + * reason we use `near_limit2' for the comparison to get a + * non-near point even in the worst case. */ if ( FT_ABS( out_x ) + FT_ABS( out_y ) >= near_limit2 ) break; @@ -979,11 +1017,11 @@ curr = first; /* - * We abuse the `u' and `v' fields to store index deltas to the - * next and previous non-near point, respectively. + * We abuse the `u' and `v' fields to store index deltas to the + * next and previous non-near point, respectively. * - * To avoid problems with not having non-near points, we point to - * `first' by default as the next non-near point. + * To avoid problems with not having non-near points, we point to + * `first' by default as the next non-near point. * */ curr->u = (FT_Pos)( first - curr ); @@ -1035,12 +1073,12 @@ } /* - * The next step is to `simplify' an outline's topology so that we - * can identify local extrema more reliably: A series of - * non-horizontal or non-vertical vectors pointing into the same - * quadrant are handled as a single, long vector. From a - * topological point of the view, the intermediate points are of no - * interest and thus tagged as weak. + * The next step is to `simplify' an outline's topology so that we + * can identify local extrema more reliably: A series of + * non-horizontal or non-vertical vectors pointing into the same + * quadrant are handled as a single, long vector. From a + * topological point of the view, the intermediate points are of no + * interest and thus tagged as weak. */ for ( point = points; point < point_limit; point++ ) @@ -1080,9 +1118,9 @@ } /* - * Finally, check for remaining weak points. Everything else not - * collected in edges so far is then implicitly classified as strong - * points. + * Finally, check for remaining weak points. Everything else not + * collected in edges so far is then implicitly classified as strong + * points. */ for ( point = points; point < point_limit; point++ ) @@ -1309,6 +1347,12 @@ if ( delta >= 0 ) { u = edge->pos - ( edge->opos - ou ); + +#ifdef FT_DEBUG_AUTOFIT + point->before[dim] = edge; + point->after[dim] = NULL; +#endif + goto Store_Point; } @@ -1318,6 +1362,12 @@ if ( delta >= 0 ) { u = edge->pos + ( ou - edge->opos ); + +#ifdef FT_DEBUG_AUTOFIT + point->before[dim] = NULL; + point->after[dim] = edge; +#endif + goto Store_Point; } @@ -1364,6 +1414,12 @@ { /* we are on the edge */ u = edge->pos; + +#ifdef FT_DEBUG_AUTOFIT + point->before[dim] = NULL; + point->after[dim] = NULL; +#endif + goto Store_Point; } } @@ -1374,6 +1430,11 @@ AF_Edge after = edges + min + 0; +#ifdef FT_DEBUG_AUTOFIT + point->before[dim] = before; + point->after[dim] = after; +#endif + /* assert( before && after && before != after ) */ if ( before->scale == 0 ) before->scale = FT_DivFix( after->pos - before->pos, diff --git a/sdk/lib/3rdparty/freetype/src/autofit/afhints.h b/sdk/lib/3rdparty/freetype/src/autofit/afhints.h index 3326ebc44e758..e0cf612f0c542 100644 --- a/sdk/lib/3rdparty/freetype/src/autofit/afhints.h +++ b/sdk/lib/3rdparty/freetype/src/autofit/afhints.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* afhints.h */ -/* */ -/* Auto-fitter hinting routines (specification). */ -/* */ -/* Copyright 2003-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * afhints.h + * + * Auto-fitter hinting routines (specification). + * + * Copyright (C) 2003-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef AFHINTS_H_ @@ -26,8 +26,8 @@ FT_BEGIN_HEADER /* - * The definition of outline glyph hints. These are shared by all - * writing system analysis routines (until now). + * The definition of outline glyph hints. These are shared by all + * writing system analysis routines (until now). */ typedef enum AF_Dimension_ @@ -56,153 +56,153 @@ FT_BEGIN_HEADER /* - * The following explanations are mostly taken from the article + * The following explanations are mostly taken from the article * - * Real-Time Grid Fitting of Typographic Outlines + * Real-Time Grid Fitting of Typographic Outlines * - * by David Turner and Werner Lemberg + * by David Turner and Werner Lemberg * - * https://www.tug.org/TUGboat/Articles/tb24-3/lemberg.pdf + * https://www.tug.org/TUGboat/Articles/tb24-3/lemberg.pdf * - * with appropriate updates. + * with appropriate updates. * * - * Segments + * Segments * - * `af_{cjk,latin,...}_hints_compute_segments' are the functions to - * find segments in an outline. + * `af_{cjk,latin,...}_hints_compute_segments' are the functions to + * find segments in an outline. * - * A segment is a series of at least two consecutive points that are - * approximately aligned along a coordinate axis. The analysis to do - * so is specific to a writing system. + * A segment is a series of at least two consecutive points that are + * approximately aligned along a coordinate axis. The analysis to do + * so is specific to a writing system. * * - * Edges + * Edges * - * `af_{cjk,latin,...}_hints_compute_edges' are the functions to find - * edges. + * `af_{cjk,latin,...}_hints_compute_edges' are the functions to find + * edges. * - * As soon as segments are defined, the auto-hinter groups them into - * edges. An edge corresponds to a single position on the main - * dimension that collects one or more segments (allowing for a small - * threshold). + * As soon as segments are defined, the auto-hinter groups them into + * edges. An edge corresponds to a single position on the main + * dimension that collects one or more segments (allowing for a small + * threshold). * - * As an example, the `latin' writing system first tries to grid-fit - * edges, then to align segments on the edges unless it detects that - * they form a serif. + * As an example, the `latin' writing system first tries to grid-fit + * edges, then to align segments on the edges unless it detects that + * they form a serif. * * - * A H - * | | - * | | - * | | - * | | - * C | | F - * +------<-----+ +-----<------+ - * | B G | - * | | - * | | - * +--------------->------------------+ - * D E + * A H + * | | + * | | + * | | + * | | + * C | | F + * +------<-----+ +-----<------+ + * | B G | + * | | + * | | + * +--------------->------------------+ + * D E * * - * Stems + * Stems * - * Stems are detected by `af_{cjk,latin,...}_hint_edges'. + * Stems are detected by `af_{cjk,latin,...}_hint_edges'. * - * Segments need to be `linked' to other ones in order to detect stems. - * A stem is made of two segments that face each other in opposite - * directions and that are sufficiently close to each other. Using - * vocabulary from the TrueType specification, stem segments form a - * `black distance'. + * Segments need to be `linked' to other ones in order to detect stems. + * A stem is made of two segments that face each other in opposite + * directions and that are sufficiently close to each other. Using + * vocabulary from the TrueType specification, stem segments form a + * `black distance'. * - * In the above ASCII drawing, the horizontal segments are BC, DE, and - * FG; the vertical segments are AB, CD, EF, and GH. + * In the above ASCII drawing, the horizontal segments are BC, DE, and + * FG; the vertical segments are AB, CD, EF, and GH. * - * Each segment has at most one `best' candidate to form a black - * distance, or no candidate at all. Notice that two distinct segments - * can have the same candidate, which frequently means a serif. + * Each segment has at most one `best' candidate to form a black + * distance, or no candidate at all. Notice that two distinct segments + * can have the same candidate, which frequently means a serif. * - * A stem is recognized by the following condition: + * A stem is recognized by the following condition: * - * best segment_1 = segment_2 && best segment_2 = segment_1 + * best segment_1 = segment_2 && best segment_2 = segment_1 * - * The best candidate is stored in field `link' in structure - * `AF_Segment'. + * The best candidate is stored in field `link' in structure + * `AF_Segment'. * - * In the above ASCII drawing, the best candidate for both AB and CD is - * GH, while the best candidate for GH is AB. Similarly, the best - * candidate for EF and GH is AB, while the best candidate for AB is - * GH. + * In the above ASCII drawing, the best candidate for both AB and CD is + * GH, while the best candidate for GH is AB. Similarly, the best + * candidate for EF and GH is AB, while the best candidate for AB is + * GH. * - * The detection and handling of stems is dependent on the writing - * system. + * The detection and handling of stems is dependent on the writing + * system. * * - * Serifs + * Serifs * - * Serifs are detected by `af_{cjk,latin,...}_hint_edges'. + * Serifs are detected by `af_{cjk,latin,...}_hint_edges'. * - * In comparison to a stem, a serif (as handled by the auto-hinter - * module that takes care of the `latin' writing system) has + * In comparison to a stem, a serif (as handled by the auto-hinter + * module that takes care of the `latin' writing system) has * - * best segment_1 = segment_2 && best segment_2 != segment_1 + * best segment_1 = segment_2 && best segment_2 != segment_1 * - * where segment_1 corresponds to the serif segment (CD and EF in the - * above ASCII drawing). + * where segment_1 corresponds to the serif segment (CD and EF in the + * above ASCII drawing). * - * The best candidate is stored in field `serif' in structure - * `AF_Segment' (and `link' is set to NULL). + * The best candidate is stored in field `serif' in structure + * `AF_Segment' (and `link' is set to NULL). * * - * Touched points + * Touched points * - * A point is called `touched' if it has been processed somehow by the - * auto-hinter. It basically means that it shouldn't be moved again - * (or moved only under certain constraints to preserve the already - * applied processing). + * A point is called `touched' if it has been processed somehow by the + * auto-hinter. It basically means that it shouldn't be moved again + * (or moved only under certain constraints to preserve the already + * applied processing). * * - * Flat and round segments + * Flat and round segments * - * Segments are `round' or `flat', depending on the series of points - * that define them. A segment is round if the next and previous point - * of an extremum (which can be either a single point or sequence of - * points) are both conic or cubic control points. Otherwise, a - * segment with an extremum is flat. + * Segments are `round' or `flat', depending on the series of points + * that define them. A segment is round if the next and previous point + * of an extremum (which can be either a single point or sequence of + * points) are both conic or cubic control points. Otherwise, a + * segment with an extremum is flat. * * - * Strong Points + * Strong Points * - * Experience has shown that points not part of an edge need to be - * interpolated linearly between their two closest edges, even if these - * are not part of the contour of those particular points. Typical - * candidates for this are + * Experience has shown that points not part of an edge need to be + * interpolated linearly between their two closest edges, even if these + * are not part of the contour of those particular points. Typical + * candidates for this are * - * - angle points (i.e., points where the `in' and `out' direction - * differ greatly) + * - angle points (i.e., points where the `in' and `out' direction + * differ greatly) * - * - inflection points (i.e., where the `in' and `out' angles are the - * same, but the curvature changes sign) [currently, such points - * aren't handled specially in the auto-hinter] + * - inflection points (i.e., where the `in' and `out' angles are the + * same, but the curvature changes sign) [currently, such points + * aren't handled specially in the auto-hinter] * - * `af_glyph_hints_align_strong_points' is the function that takes - * care of such situations; it is equivalent to the TrueType `IP' - * hinting instruction. + * `af_glyph_hints_align_strong_points' is the function that takes + * care of such situations; it is equivalent to the TrueType `IP' + * hinting instruction. * * - * Weak Points + * Weak Points * - * Other points in the outline must be interpolated using the - * coordinates of their previous and next unfitted contour neighbours. - * These are called `weak points' and are touched by the function - * `af_glyph_hints_align_weak_points', equivalent to the TrueType `IUP' - * hinting instruction. Typical candidates are control points and - * points on the contour without a major direction. + * Other points in the outline must be interpolated using the + * coordinates of their previous and next unfitted contour neighbours. + * These are called `weak points' and are touched by the function + * `af_glyph_hints_align_weak_points', equivalent to the TrueType `IUP' + * hinting instruction. Typical candidates are control points and + * points on the contour without a major direction. * - * The major effect is to reduce possible distortion caused by - * alignment of edges and strong points, thus weak points are processed - * after strong points. + * The major effect is to reduce possible distortion caused by + * alignment of edges and strong points, thus weak points are processed + * after strong points. */ @@ -252,6 +252,12 @@ FT_BEGIN_HEADER AF_Point next; /* next point in contour */ AF_Point prev; /* previous point in contour */ +#ifdef FT_DEBUG_AUTOFIT + /* track `before' and `after' edges for strong points */ + AF_Edge before[2]; + AF_Edge after[2]; +#endif + } AF_PointRec; diff --git a/sdk/lib/3rdparty/freetype/src/autofit/afindic.c b/sdk/lib/3rdparty/freetype/src/autofit/afindic.c index dfbea5f34c189..a17117c7129d8 100644 --- a/sdk/lib/3rdparty/freetype/src/autofit/afindic.c +++ b/sdk/lib/3rdparty/freetype/src/autofit/afindic.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* afindic.c */ -/* */ -/* Auto-fitter hinting routines for Indic writing system (body). */ -/* */ -/* Copyright 2007-2018 by */ -/* Rahul Bhalerao <rahul.bhalerao@redhat.com>, <b.rahul.pm@gmail.com>. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * afindic.c + * + * Auto-fitter hinting routines for Indic writing system (body). + * + * Copyright (C) 2007-2019 by + * Rahul Bhalerao <rahul.bhalerao@redhat.com>, <b.rahul.pm@gmail.com>. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include "aftypes.h" diff --git a/sdk/lib/3rdparty/freetype/src/autofit/afindic.h b/sdk/lib/3rdparty/freetype/src/autofit/afindic.h index 5688738e6e0f0..bc5bc59fa5561 100644 --- a/sdk/lib/3rdparty/freetype/src/autofit/afindic.h +++ b/sdk/lib/3rdparty/freetype/src/autofit/afindic.h @@ -1,20 +1,20 @@ -/***************************************************************************/ -/* */ -/* afindic.h */ -/* */ -/* Auto-fitter hinting routines for Indic writing system */ -/* (specification). */ -/* */ -/* Copyright 2007-2018 by */ -/* Rahul Bhalerao <rahul.bhalerao@redhat.com>, <b.rahul.pm@gmail.com>. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * afindic.h + * + * Auto-fitter hinting routines for Indic writing system + * (specification). + * + * Copyright (C) 2007-2019 by + * Rahul Bhalerao <rahul.bhalerao@redhat.com>, <b.rahul.pm@gmail.com>. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef AFINDIC_H_ diff --git a/sdk/lib/3rdparty/freetype/src/autofit/aflatin.c b/sdk/lib/3rdparty/freetype/src/autofit/aflatin.c index 0fa6233b9451f..d46755680d6eb 100644 --- a/sdk/lib/3rdparty/freetype/src/autofit/aflatin.c +++ b/sdk/lib/3rdparty/freetype/src/autofit/aflatin.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* aflatin.c */ -/* */ -/* Auto-fitter hinting routines for latin writing system (body). */ -/* */ -/* Copyright 2003-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * aflatin.c + * + * Auto-fitter hinting routines for latin writing system (body). + * + * Copyright (C) 2003-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -21,7 +21,6 @@ #include FT_INTERNAL_DEBUG_H #include "afglobal.h" -#include "afpic.h" #include "aflatin.h" #include "aferrors.h" @@ -31,14 +30,14 @@ #endif - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_aflatin +#define FT_COMPONENT aflatin /* needed for computation of round vs. flat segments */ @@ -63,7 +62,7 @@ { /* scan the array of segments in each direction */ #ifdef __REACTOS__ - AF_GlyphHintsRec *hints = malloc(sizeof(AF_GlyphHintsRec)); + AF_GlyphHintsRec *hints = malloc(sizeof(*hints)); if (!hints) return; #else AF_GlyphHintsRec hints[1]; @@ -86,7 +85,7 @@ FT_ULong glyph_index; int dim; #ifdef __REACTOS__ - AF_LatinMetricsRec *dummy = malloc(sizeof(AF_LatinMetricsRec)); + AF_LatinMetricsRec *dummy = malloc(sizeof(*dummy)); if (!dummy) goto Exit; { @@ -95,24 +94,30 @@ #endif AF_Scaler scaler = &dummy->root.scaler; -#ifdef FT_CONFIG_OPTION_PIC - AF_FaceGlobals globals = metrics->root.globals; -#endif - AF_StyleClass style_class = metrics->root.style_class; - AF_ScriptClass script_class = AF_SCRIPT_CLASSES_GET - [style_class->script]; + AF_ScriptClass script_class = af_script_classes[style_class->script]; + + /* If HarfBuzz is not available, we need a pointer to a single */ + /* unsigned long value. */ +#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ + void* shaper_buf; +#else + FT_ULong shaper_buf_; + void* shaper_buf = &shaper_buf_; +#endif - void* shaper_buf; const char* p; #ifdef FT_DEBUG_LEVEL_TRACE FT_ULong ch = 0; #endif - p = script_class->standard_charstring; - shaper_buf = af_shaper_buf_create( face ); + p = script_class->standard_charstring; + +#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ + shaper_buf = af_shaper_buf_create( face ); +#endif /* * We check a list of standard characters to catch features like * `c2sc' (small caps from caps) that don't contain lowercase letters @@ -198,10 +203,10 @@ goto Exit; /* - * We assume that the glyphs selected for the stem width - * computation are `featureless' enough so that the linking - * algorithm works fine without adjustments of its scoring - * function. + * We assume that the glyphs selected for the stem width + * computation are `featureless' enough so that the linking + * algorithm works fine without adjustments of its scoring + * function. */ af_latin_hints_link_segments( hints, 0, @@ -282,7 +287,6 @@ #ifdef __REACTOS__ free(hints); #endif - } @@ -350,7 +354,14 @@ FT_Pos flat_threshold = FLAT_THRESHOLD( metrics->units_per_em ); - void* shaper_buf; + /* If HarfBuzz is not available, we need a pointer to a single */ + /* unsigned long value. */ +#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ + void* shaper_buf; +#else + FT_ULong shaper_buf_; + void* shaper_buf = &shaper_buf_; +#endif /* we walk over the blue character strings as specified in the */ @@ -360,7 +371,9 @@ "============================\n" "\n" )); +#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ shaper_buf = af_shaper_buf_create( face ); +#endif for ( ; bs->string != AF_BLUE_STRING_MAX; bs++ ) { @@ -905,8 +918,8 @@ if ( num_flats == 0 && num_rounds == 0 ) { /* - * we couldn't find a single glyph to compute this blue zone, - * we will simply ignore it then + * we couldn't find a single glyph to compute this blue zone, + * we will simply ignore it then */ FT_TRACE5(( " empty\n" )); continue; @@ -1057,15 +1070,25 @@ FT_Bool started = 0, same_width = 1; FT_Fixed advance = 0, old_advance = 0; - void* shaper_buf; + /* If HarfBuzz is not available, we need a pointer to a single */ + /* unsigned long value. */ +#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ + void* shaper_buf; +#else + FT_ULong shaper_buf_; + void* shaper_buf = &shaper_buf_; +#endif /* in all supported charmaps, digits have character codes 0x30-0x39 */ const char digits[] = "0 1 2 3 4 5 6 7 8 9"; const char* p; - p = digits; + p = digits; + +#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ shaper_buf = af_shaper_buf_create( face ); +#endif while ( *p ) { @@ -1304,7 +1327,7 @@ /* an extra-light axis corresponds to a standard width that is */ /* smaller than 5/8 pixels */ axis->extra_light = - (FT_Bool)( FT_MulFix( axis->standard_width, scale ) < 32 + 8 ); + FT_BOOL( FT_MulFix( axis->standard_width, scale ) < 32 + 8 ); #ifdef FT_DEBUG_LEVEL_TRACE if ( axis->extra_light ) @@ -1988,17 +2011,17 @@ if ( len >= len_threshold ) { /* - * The score is the sum of two demerits indicating the - * `badness' of a fit, measured along the segments' main axis - * and orthogonal to it, respectively. + * The score is the sum of two demerits indicating the + * `badness' of a fit, measured along the segments' main axis + * and orthogonal to it, respectively. * - * o The less overlapping along the main axis, the worse it - * is, causing a larger demerit. + * - The less overlapping along the main axis, the worse it + * is, causing a larger demerit. * - * o The nearer the orthogonal distance to a stem width, the - * better it is, causing a smaller demerit. For simplicity, - * however, we only increase the demerit for values that - * exceed the largest stem width. + * - The nearer the orthogonal distance to a stem width, the + * better it is, causing a smaller demerit. For simplicity, + * however, we only increase the demerit for values that + * exceed the largest stem width. */ FT_Pos dist = pos2 - pos1; @@ -2070,13 +2093,8 @@ FT_Memory memory = hints->memory; AF_LatinAxis laxis = &((AF_LatinMetrics)hints->metrics)->axis[dim]; -#ifdef FT_CONFIG_OPTION_PIC - AF_FaceGlobals globals = hints->metrics->globals; -#endif - AF_StyleClass style_class = hints->metrics->style_class; - AF_ScriptClass script_class = AF_SCRIPT_CLASSES_GET - [style_class->script]; + AF_ScriptClass script_class = af_script_classes[style_class->script]; FT_Bool top_to_bottom_hinting = 0; @@ -2107,9 +2125,9 @@ top_to_bottom_hinting = script_class->top_to_bottom_hinting; /* - * We ignore all segments that are less than 1 pixel in length - * to avoid many problems with serif fonts. We compute the - * corresponding threshold in font units. + * We ignore all segments that are less than 1 pixel in length + * to avoid many problems with serif fonts. We compute the + * corresponding threshold in font units. */ if ( dim == AF_DIMENSION_HORZ ) segment_length_threshold = FT_DivFix( 64, hints->y_scale ); @@ -2117,26 +2135,26 @@ segment_length_threshold = 0; /* - * Similarly, we ignore segments that have a width delta - * larger than 0.5px (i.e., a width larger than 1px). + * Similarly, we ignore segments that have a width delta + * larger than 0.5px (i.e., a width larger than 1px). */ segment_width_threshold = FT_DivFix( 32, scale ); - /*********************************************************************/ - /* */ - /* We begin by generating a sorted table of edges for the current */ - /* direction. To do so, we simply scan each segment and try to find */ - /* an edge in our table that corresponds to its position. */ - /* */ - /* If no edge is found, we create and insert a new edge in the */ - /* sorted table. Otherwise, we simply add the segment to the edge's */ - /* list which gets processed in the second step to compute the */ - /* edge's properties. */ - /* */ - /* Note that the table of edges is sorted along the segment/edge */ - /* position. */ - /* */ - /*********************************************************************/ + /********************************************************************** + * + * We begin by generating a sorted table of edges for the current + * direction. To do so, we simply scan each segment and try to find + * an edge in our table that corresponds to its position. + * + * If no edge is found, we create and insert a new edge in the + * sorted table. Otherwise, we simply add the segment to the edge's + * list which gets processed in the second step to compute the + * edge's properties. + * + * Note that the table of edges is sorted along the segment/edge + * position. + * + */ /* assure that edge distance threshold is at most 0.25px */ edge_distance_threshold = FT_MulFix( laxis->edge_distance_threshold, @@ -2258,17 +2276,17 @@ } - /******************************************************************/ - /* */ - /* Good, we now compute each edge's properties according to the */ - /* segments found on its position. Basically, these are */ - /* */ - /* - the edge's main direction */ - /* - stem edge, serif edge or both (which defaults to stem then) */ - /* - rounded edge, straight or both (which defaults to straight) */ - /* - link for edge */ - /* */ - /******************************************************************/ + /******************************************************************* + * + * Good, we now compute each edge's properties according to the + * segments found on its position. Basically, these are + * + * - the edge's main direction + * - stem edge, serif edge or both (which defaults to stem then) + * - rounded edge, straight or both (which defaults to straight) + * - link for edge + * + */ /* first of all, set the `edge' field in each segment -- this is */ /* required in order to compute edge links */ @@ -2330,9 +2348,9 @@ /* check for links -- if seg->serif is set, then seg->link must */ /* be ignored */ - is_serif = (FT_Bool)( seg->serif && - seg->serif->edge && - seg->serif->edge != edge ); + is_serif = FT_BOOL( seg->serif && + seg->serif->edge && + seg->serif->edge != edge ); if ( ( seg->link && seg->link->edge ) || is_serif ) { @@ -2567,8 +2585,8 @@ af_glyph_hints_rescale( hints, (AF_StyleMetrics)metrics ); /* - * correct x_scale and y_scale if needed, since they may have - * been modified by `af_latin_metrics_scale_dim' above + * correct x_scale and y_scale if needed, since they may have + * been modified by `af_latin_metrics_scale_dim' above */ hints->x_scale = metrics->axis[AF_DIMENSION_HORZ].scale; hints->x_delta = metrics->axis[AF_DIMENSION_HORZ].delta; @@ -2587,21 +2605,21 @@ other_flags = 0; /* - * We snap the width of vertical stems for the monochrome and - * horizontal LCD rendering targets only. + * We snap the width of vertical stems for the monochrome and + * horizontal LCD rendering targets only. */ if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD ) other_flags |= AF_LATIN_HINTS_HORZ_SNAP; /* - * We snap the width of horizontal stems for the monochrome and - * vertical LCD rendering targets only. + * We snap the width of horizontal stems for the monochrome and + * vertical LCD rendering targets only. */ if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD_V ) other_flags |= AF_LATIN_HINTS_VERT_SNAP; /* - * We adjust stems to full pixels unless in `light' or `lcd' mode. + * We adjust stems to full pixels unless in `light' or `lcd' mode. */ if ( mode != FT_RENDER_MODE_LIGHT && mode != FT_RENDER_MODE_LCD ) other_flags |= AF_LATIN_HINTS_STEM_ADJUST; @@ -2610,11 +2628,11 @@ other_flags |= AF_LATIN_HINTS_MONO; /* - * In `light' or `lcd' mode we disable horizontal hinting completely. - * We also do it if the face is italic. + * In `light' or `lcd' mode we disable horizontal hinting completely. + * We also do it if the face is italic. * - * However, if warping is enabled (which only works in `light' hinting - * mode), advance widths get adjusted, too. + * However, if warping is enabled (which only works in `light' hinting + * mode), advance widths get adjusted, too. */ if ( mode == FT_RENDER_MODE_LIGHT || mode == FT_RENDER_MODE_LCD || ( face->style_flags & FT_STYLE_FLAG_ITALIC ) != 0 ) @@ -2957,13 +2975,8 @@ AF_Edge anchor = NULL; FT_Int has_serifs = 0; -#ifdef FT_CONFIG_OPTION_PIC - AF_FaceGlobals globals = hints->metrics->globals; -#endif - AF_StyleClass style_class = hints->metrics->style_class; - AF_ScriptClass script_class = AF_SCRIPT_CLASSES_GET - [style_class->script]; + AF_ScriptClass script_class = af_script_classes[style_class->script]; FT_Bool top_to_bottom_hinting = 0; @@ -2997,12 +3010,12 @@ edge2 = edge->link; /* - * If a stem contains both a neutral and a non-neutral blue zone, - * skip the neutral one. Otherwise, outlines with different - * directions might be incorrectly aligned at the same vertical - * position. + * If a stem contains both a neutral and a non-neutral blue zone, + * skip the neutral one. Otherwise, outlines with different + * directions might be incorrectly aligned at the same vertical + * position. * - * If we have two neutral blue zones, skip one of them. + * If we have two neutral blue zones, skip one of them. * */ if ( edge->blue_edge && edge2 && edge2->blue_edge ) @@ -3365,8 +3378,8 @@ if ( has_serifs || !anchor ) { /* - * now hint the remaining edges (serifs and single) in order - * to complete our processing + * now hint the remaining edges (serifs and single) in order + * to complete our processing */ for ( edge = edges; edge < edge_limit; edge++ ) { diff --git a/sdk/lib/3rdparty/freetype/src/autofit/aflatin.h b/sdk/lib/3rdparty/freetype/src/autofit/aflatin.h index 432cccce4e219..40479538c25df 100644 --- a/sdk/lib/3rdparty/freetype/src/autofit/aflatin.h +++ b/sdk/lib/3rdparty/freetype/src/autofit/aflatin.h @@ -1,20 +1,20 @@ -/***************************************************************************/ -/* */ -/* aflatin.h */ -/* */ -/* Auto-fitter hinting routines for latin writing system */ -/* (specification). */ -/* */ -/* Copyright 2003-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * aflatin.h + * + * Auto-fitter hinting routines for latin writing system + * (specification). + * + * Copyright (C) 2003-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef AFLATIN_H_ @@ -45,9 +45,9 @@ FT_BEGIN_HEADER /* - * The following declarations could be embedded in the file `aflatin.c'; - * they have been made semi-public to allow alternate writing system - * hinters to re-use some of them. + * The following declarations could be embedded in the file `aflatin.c'; + * they have been made semi-public to allow alternate writing system + * hinters to re-use some of them. */ @@ -161,8 +161,8 @@ FT_BEGIN_HEADER /* - * The next functions shouldn't normally be exported. However, other - * writing systems might like to use these functions as-is. + * The next functions shouldn't normally be exported. However, other + * writing systems might like to use these functions as-is. */ FT_LOCAL( FT_Error ) af_latin_hints_compute_segments( AF_GlyphHints hints, diff --git a/sdk/lib/3rdparty/freetype/src/autofit/aflatin2.c b/sdk/lib/3rdparty/freetype/src/autofit/aflatin2.c index 5c713781189c5..5d4e055b8f34e 100644 --- a/sdk/lib/3rdparty/freetype/src/autofit/aflatin2.c +++ b/sdk/lib/3rdparty/freetype/src/autofit/aflatin2.c @@ -3,22 +3,22 @@ /* marked as experimental. */ -/***************************************************************************/ -/* */ -/* aflatin2.c */ -/* */ -/* Auto-fitter hinting routines for latin writing system (body). */ -/* */ -/* Copyright 2003-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * aflatin2.c + * + * Auto-fitter hinting routines for latin writing system (body). + * + * Copyright (C) 2003-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include FT_ADVANCES_H @@ -37,14 +37,14 @@ #endif - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_aflatin2 +#define FT_COMPONENT aflatin2 FT_LOCAL_DEF( FT_Error ) @@ -68,7 +68,12 @@ FT_Face face ) { /* scan the array of segments in each direction */ +#ifdef __REACTOS__ + AF_GlyphHintsRec *hints = malloc(sizeof(*hints)); + if (!hints) return; +#else AF_GlyphHintsRec hints[1]; +#endif af_glyph_hints_init( hints, face->memory ); @@ -80,7 +85,13 @@ FT_Error error; FT_UInt glyph_index; int dim; +#ifdef __REACTOS__ + AF_LatinMetricsRec *dummy = malloc(sizeof(*dummy)); + if (dummy) goto Exit; + { +#else AF_LatinMetricsRec dummy[1]; +#endif AF_Scaler scaler = &dummy->root.scaler; @@ -167,9 +178,16 @@ axis->standard_width = stdw; axis->extra_light = 0; } +#ifdef __REACTOS__ + free(dummy); + } +#endif } af_glyph_hints_done( hints ); +#ifdef __REACTOS__ + free(hints); +#endif } @@ -265,7 +283,7 @@ /* Avoid single-point contours since they are never rasterized. */ /* In some fonts, they correspond to mark attachment points */ /* which are way outside of the glyph's real outline. */ - if ( last == first ) + if ( last <= first ) continue; if ( AF_LATIN_IS_TOP_BLUE( bb ) ) @@ -299,6 +317,7 @@ /* now check whether the point belongs to a straight or round */ /* segment; we first need to find in which contour the extremum */ /* lies, then inspect its previous and next points */ + if ( best_point >= 0 ) { FT_Pos best_x = points[best_point].x; FT_Int start, end, prev, next; @@ -358,8 +377,8 @@ if ( num_flats == 0 && num_rounds == 0 ) { /* - * we couldn't find a single glyph to compute this blue zone, - * we will simply ignore it then + * we couldn't find a single glyph to compute this blue zone, + * we will simply ignore it then */ FT_TRACE5(( " empty\n" )); continue; @@ -632,7 +651,7 @@ /* an extra-light axis corresponds to a standard width that is */ /* smaller than 5/8 pixels */ axis->extra_light = - (FT_Bool)( FT_MulFix( axis->standard_width, scale ) < 32 + 8 ); + FT_BOOL( FT_MulFix( axis->standard_width, scale ) < 32 + 8 ); if ( dim == AF_DIMENSION_VERT ) { @@ -1108,13 +1127,13 @@ : AF_DIR_RIGHT; /* - * We want to ignore very small (mostly serif) segments, we do that - * by ignoring those that whose length is less than a given fraction - * of the standard width. If there is no standard width, we ignore - * those that are less than a given size in pixels + * We want to ignore very small (mostly serif) segments, we do that + * by ignoring those that whose length is less than a given fraction + * of the standard width. If there is no standard width, we ignore + * those that are less than a given size in pixels * - * also, unlink serif segments that are linked to segments farther - * than 50% of the standard width + * also, unlink serif segments that are linked to segments farther + * than 50% of the standard width */ if ( dim == AF_DIMENSION_HORZ ) { @@ -1126,21 +1145,21 @@ else segment_length_threshold = 0; - /*********************************************************************/ - /* */ - /* We will begin by generating a sorted table of edges for the */ - /* current direction. To do so, we simply scan each segment and try */ - /* to find an edge in our table that corresponds to its position. */ - /* */ - /* If no edge is found, we create and insert a new edge in the */ - /* sorted table. Otherwise, we simply add the segment to the edge's */ - /* list which will be processed in the second step to compute the */ - /* edge's properties. */ - /* */ - /* Note that the edges table is sorted along the segment/edge */ - /* position. */ - /* */ - /*********************************************************************/ + /********************************************************************** + * + * We will begin by generating a sorted table of edges for the + * current direction. To do so, we simply scan each segment and try + * to find an edge in our table that corresponds to its position. + * + * If no edge is found, we create and insert a new edge in the + * sorted table. Otherwise, we simply add the segment to the edge's + * list which will be processed in the second step to compute the + * edge's properties. + * + * Note that the edges table is sorted along the segment/edge + * position. + * + */ edge_distance_threshold = FT_MulFix( laxis->edge_distance_threshold, scale ); @@ -1230,17 +1249,17 @@ } - /*********************************************************************/ - /* */ - /* Good, we will now compute each edge's properties according to */ - /* segments found on its position. Basically, these are: */ - /* */ - /* - edge's main direction */ - /* - stem edge, serif edge or both (which defaults to stem then) */ - /* - rounded edge, straight or both (which defaults to straight) */ - /* - link for edge */ - /* */ - /*********************************************************************/ + /********************************************************************** + * + * Good, we will now compute each edge's properties according to + * segments found on its position. Basically, these are: + * + * - edge's main direction + * - stem edge, serif edge or both (which defaults to stem then) + * - rounded edge, straight or both (which defaults to straight) + * - link for edge + * + */ /* first of all, set the `edge' field in each segment -- this is */ /* required in order to compute edge links */ @@ -1302,9 +1321,9 @@ /* check for links -- if seg->serif is set, then seg->link must */ /* be ignored */ - is_serif = (FT_Bool)( seg->serif && - seg->serif->edge && - seg->serif->edge != edge ); + is_serif = FT_BOOL( seg->serif && + seg->serif->edge && + seg->serif->edge != edge ); if ( ( seg->link && seg->link->edge ) || is_serif ) { @@ -1524,8 +1543,8 @@ af_glyph_hints_rescale( hints, (AF_StyleMetrics)metrics ); /* - * correct x_scale and y_scale if needed, since they may have - * been modified `af_latin2_metrics_scale_dim' above + * correct x_scale and y_scale if needed, since they may have + * been modified `af_latin2_metrics_scale_dim' above */ hints->x_scale = metrics->axis[AF_DIMENSION_HORZ].scale; hints->x_delta = metrics->axis[AF_DIMENSION_HORZ].delta; @@ -1544,21 +1563,21 @@ other_flags = 0; /* - * We snap the width of vertical stems for the monochrome and - * horizontal LCD rendering targets only. + * We snap the width of vertical stems for the monochrome and + * horizontal LCD rendering targets only. */ if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD ) other_flags |= AF_LATIN_HINTS_HORZ_SNAP; /* - * We snap the width of horizontal stems for the monochrome and - * vertical LCD rendering targets only. + * We snap the width of horizontal stems for the monochrome and + * vertical LCD rendering targets only. */ if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD_V ) other_flags |= AF_LATIN_HINTS_VERT_SNAP; /* - * We adjust stems to full pixels unless in `light' or `lcd' mode. + * We adjust stems to full pixels unless in `light' or `lcd' mode. */ if ( mode != FT_RENDER_MODE_LIGHT && mode != FT_RENDER_MODE_LCD ) other_flags |= AF_LATIN_HINTS_STEM_ADJUST; @@ -1567,8 +1586,8 @@ other_flags |= AF_LATIN_HINTS_MONO; /* - * In `light' or `lcd' mode we disable horizontal hinting completely. - * We also do it if the face is italic. + * In `light' or `lcd' mode we disable horizontal hinting completely. + * We also do it if the face is italic. */ if ( mode == FT_RENDER_MODE_LIGHT || mode == FT_RENDER_MODE_LCD || ( face->style_flags & FT_STYLE_FLAG_ITALIC ) != 0 ) @@ -2233,8 +2252,8 @@ if ( has_serifs || !anchor ) { /* - * now hint the remaining edges (serifs and single) in order - * to complete our processing + * now hint the remaining edges (serifs and single) in order + * to complete our processing */ for ( edge = edges; edge < edge_limit; edge++ ) { diff --git a/sdk/lib/3rdparty/freetype/src/autofit/aflatin2.h b/sdk/lib/3rdparty/freetype/src/autofit/aflatin2.h index 0129dc707e6b5..507cef3df2bf7 100644 --- a/sdk/lib/3rdparty/freetype/src/autofit/aflatin2.h +++ b/sdk/lib/3rdparty/freetype/src/autofit/aflatin2.h @@ -3,23 +3,23 @@ /* marked as experimental. */ -/***************************************************************************/ -/* */ -/* aflatin2.h */ -/* */ -/* Auto-fitter hinting routines for latin writing system */ -/* (specification). */ -/* */ -/* Copyright 2003-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * aflatin2.h + * + * Auto-fitter hinting routines for latin writing system + * (specification). + * + * Copyright (C) 2003-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef AFLATIN2_H_ diff --git a/sdk/lib/3rdparty/freetype/src/autofit/afloader.c b/sdk/lib/3rdparty/freetype/src/autofit/afloader.c index a55550b3385f6..83743b7be15eb 100644 --- a/sdk/lib/3rdparty/freetype/src/autofit/afloader.c +++ b/sdk/lib/3rdparty/freetype/src/autofit/afloader.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* afloader.c */ -/* */ -/* Auto-fitter glyph loading routines (body). */ -/* */ -/* Copyright 2003-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * afloader.c + * + * Auto-fitter glyph loading routines (body). + * + * Copyright (C) 2003-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include "afglobal.h" @@ -21,7 +21,6 @@ #include "afhints.h" #include "aferrors.h" #include "afmodule.h" -#include "afpic.h" #include FT_INTERNAL_CALC_H @@ -119,12 +118,12 @@ } /* - * We depend on the writing system (script analyzers) to supply - * standard widths for the script of the glyph we are looking at. If - * it can't deliver, stem darkening is disabled. + * We depend on the writing system (script analyzers) to supply + * standard widths for the script of the glyph we are looking at. If + * it can't deliver, stem darkening is disabled. */ writing_system_class = - AF_WRITING_SYSTEM_CLASSES_GET[style_metrics->style_class->writing_system]; + af_writing_system_classes[style_metrics->style_class->writing_system]; if ( writing_system_class->style_metrics_getstdw ) writing_system_class->style_metrics_getstdw( style_metrics, @@ -174,22 +173,22 @@ globals->darken_y = af_fixedToInt( darken_y ); /* - * Scale outlines down on the Y-axis to keep them inside their blue - * zones. The stronger the emboldening, the stronger the downscaling - * (plus heuristical padding to prevent outlines still falling out - * their zones due to rounding). + * Scale outlines down on the Y-axis to keep them inside their blue + * zones. The stronger the emboldening, the stronger the downscaling + * (plus heuristical padding to prevent outlines still falling out + * their zones due to rounding). * - * Reason: `FT_Outline_Embolden' works by shifting the rightmost - * points of stems farther to the right, and topmost points farther - * up. This positions points on the Y-axis outside their - * pre-computed blue zones and leads to distortion when applying the - * hints in the code further below. Code outside this emboldening - * block doesn't know we are presenting it with modified outlines the - * analyzer didn't see! + * Reason: `FT_Outline_Embolden' works by shifting the rightmost + * points of stems farther to the right, and topmost points farther + * up. This positions points on the Y-axis outside their + * pre-computed blue zones and leads to distortion when applying the + * hints in the code further below. Code outside this emboldening + * block doesn't know we are presenting it with modified outlines the + * analyzer didn't see! * - * An unfortunate side effect of downscaling is that the emboldening - * effect is slightly decreased. The loss becomes more pronounced - * versus the CFF driver at smaller sizes, e.g., at 9ppem and below. + * An unfortunate side effect of downscaling is that the emboldening + * effect is slightly decreased. The loss becomes more pronounced + * versus the CFF driver at smaller sizes, e.g., at 9ppem and below. */ globals->scale_down_factor = FT_DivFix( em_size - ( darken_by_font_units_y + af_intToFixed( 8 ) ), @@ -232,10 +231,6 @@ AF_StyleClass style_class; AF_WritingSystemClass writing_system_class; -#ifdef FT_CONFIG_OPTION_PIC - AF_FaceGlobals globals = loader->globals; -#endif - if ( !size ) return FT_THROW( Invalid_Size_Handle ); @@ -282,13 +277,13 @@ } /* - * TODO: This code currently doesn't support fractional advance widths, - * i.e., placing hinted glyphs at anything other than integer - * x-positions. This is only relevant for the warper code, which - * scales and shifts glyphs to optimize blackness of stems (hinting on - * the x-axis by nature places things on pixel integers, hinting on the - * y-axis only, i.e., LIGHT mode, doesn't touch the x-axis). The delta - * values of the scaler would need to be adjusted. + * TODO: This code currently doesn't support fractional advance widths, + * i.e., placing hinted glyphs at anything other than integer + * x-positions. This is only relevant for the warper code, which + * scales and shifts glyphs to optimize blackness of stems (hinting on + * the x-axis by nature places things on pixel integers, hinting on the + * y-axis only, i.e., LIGHT mode, doesn't touch the x-axis). The delta + * values of the scaler would need to be adjusted. */ scaler.face = face; scaler.x_scale = size_internal->autohint_metrics.x_scale; @@ -312,10 +307,10 @@ #endif /* - * Glyphs (really code points) are assigned to scripts. Script - * analysis is done lazily: For each glyph that passes through here, - * the corresponding script analyzer is called, but returns immediately - * if it has been run already. + * Glyphs (really code points) are assigned to scripts. Script + * analysis is done lazily: For each glyph that passes through here, + * the corresponding script analyzer is called, but returns immediately + * if it has been run already. */ error = af_face_globals_get_metrics( loader->globals, glyph_index, style_options, &style_metrics ); @@ -324,7 +319,7 @@ style_class = style_metrics->style_class; writing_system_class = - AF_WRITING_SYSTEM_CLASSES_GET[style_class->writing_system]; + af_writing_system_classes[style_class->writing_system]; loader->metrics = style_metrics; @@ -342,11 +337,11 @@ } /* - * Do the main work of `af_loader_load_glyph'. Note that we never have - * to deal with composite glyphs as those get loaded into - * FT_GLYPH_FORMAT_OUTLINE by the recursed `FT_Load_Glyph' function. - * In the rare cases where FT_LOAD_NO_RECURSE is set, it implies - * FT_LOAD_NO_SCALE and as such the auto-hinter is never called. + * Do the main work of `af_loader_load_glyph'. Note that we never have + * to deal with composite glyphs as those get loaded into + * FT_GLYPH_FORMAT_OUTLINE by the recursed `FT_Load_Glyph' function. + * In the rare cases where FT_LOAD_NO_RECURSE is set, it implies + * FT_LOAD_NO_SCALE and as such the auto-hinter is never called. */ load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_TRANSFORM | @@ -358,26 +353,26 @@ goto Exit; /* - * Apply stem darkening (emboldening) here before hints are applied to - * the outline. Glyphs are scaled down proportionally to the - * emboldening so that curve points don't fall outside their - * precomputed blue zones. + * Apply stem darkening (emboldening) here before hints are applied to + * the outline. Glyphs are scaled down proportionally to the + * emboldening so that curve points don't fall outside their + * precomputed blue zones. * - * Any emboldening done by the font driver (e.g., the CFF driver) - * doesn't reach here because the autohinter loads the unprocessed - * glyphs in font units for analysis (functions `af_*_metrics_init_*') - * and then above to prepare it for the rasterizers by itself, - * independently of the font driver. So emboldening must be done here, - * within the autohinter. + * Any emboldening done by the font driver (e.g., the CFF driver) + * doesn't reach here because the autohinter loads the unprocessed + * glyphs in font units for analysis (functions `af_*_metrics_init_*') + * and then above to prepare it for the rasterizers by itself, + * independently of the font driver. So emboldening must be done here, + * within the autohinter. * - * All glyphs to be autohinted pass through here one by one. The - * standard widths can therefore change from one glyph to the next, - * depending on what script a glyph is assigned to (each script has its - * own set of standard widths and other metrics). The darkening amount - * must therefore be recomputed for each size and - * `standard_{vertical,horizontal}_width' change. + * All glyphs to be autohinted pass through here one by one. The + * standard widths can therefore change from one glyph to the next, + * depending on what script a glyph is assigned to (each script has its + * own set of standard widths and other metrics). The darkening amount + * must therefore be recomputed for each size and + * `standard_{vertical,horizontal}_width' change. * - * Ignore errors and carry on without emboldening. + * Ignore errors and carry on without emboldening. * */ @@ -426,35 +421,39 @@ /* now load the slot image into the auto-outline */ /* and run the automatic hinting process */ if ( writing_system_class->style_hints_apply ) - writing_system_class->style_hints_apply( glyph_index, - hints, - &gloader->base.outline, - style_metrics ); + { + error = writing_system_class->style_hints_apply( + glyph_index, + hints, + &gloader->base.outline, + style_metrics ); + if ( error ) + goto Exit; + } /* we now need to adjust the metrics according to the change in */ /* width/positioning that occurred during the hinting process */ if ( scaler.render_mode != FT_RENDER_MODE_LIGHT ) { - FT_Pos old_rsb, old_lsb, new_lsb; - FT_Pos pp1x_uh, pp2x_uh; - AF_AxisHints axis = &hints->axis[AF_DIMENSION_HORZ]; - AF_Edge edge1 = axis->edges; /* leftmost edge */ - AF_Edge edge2 = edge1 + - axis->num_edges - 1; /* rightmost edge */ if ( axis->num_edges > 1 && AF_HINTS_DO_ADVANCE( hints ) ) { - old_rsb = loader->pp2.x - edge2->opos; + AF_Edge edge1 = axis->edges; /* leftmost edge */ + AF_Edge edge2 = edge1 + + axis->num_edges - 1; /* rightmost edge */ + + FT_Pos old_rsb = loader->pp2.x - edge2->opos; /* loader->pp1.x is always zero at this point of time */ - old_lsb = edge1->opos /* - loader->pp1.x */; - new_lsb = edge1->pos; + FT_Pos old_lsb = edge1->opos; /* - loader->pp1.x */ + FT_Pos new_lsb = edge1->pos; /* remember unhinted values to later account */ /* for rounding errors */ - pp1x_uh = new_lsb - old_lsb; - pp2x_uh = edge2->pos + old_rsb; + FT_Pos pp1x_uh = new_lsb - old_lsb; + FT_Pos pp2x_uh = edge2->pos + old_rsb; + /* prefer too much space over too little space */ /* for very small sizes */ diff --git a/sdk/lib/3rdparty/freetype/src/autofit/afloader.h b/sdk/lib/3rdparty/freetype/src/autofit/afloader.h index d4d72d158303f..d1e0f3c093dc8 100644 --- a/sdk/lib/3rdparty/freetype/src/autofit/afloader.h +++ b/sdk/lib/3rdparty/freetype/src/autofit/afloader.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* afloader.h */ -/* */ -/* Auto-fitter glyph loading routines (specification). */ -/* */ -/* Copyright 2003-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * afloader.h + * + * Auto-fitter glyph loading routines (specification). + * + * Copyright (C) 2003-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef AFLOADER_H_ @@ -27,11 +27,11 @@ FT_BEGIN_HEADER /* - * The autofitter module's (global) data structure to communicate with - * actual fonts. If necessary, `local' data like the current face, the - * current face's auto-hint data, or the current glyph's parameters - * relevant to auto-hinting are `swapped in'. Cf. functions like - * `af_loader_reset' and `af_loader_load_g'. + * The autofitter module's (global) data structure to communicate with + * actual fonts. If necessary, `local' data like the current face, the + * current face's auto-hint data, or the current glyph's parameters + * relevant to auto-hinting are `swapped in'. Cf. functions like + * `af_loader_reset' and `af_loader_load_g'. */ typedef struct AF_LoaderRec_ diff --git a/sdk/lib/3rdparty/freetype/src/autofit/afmodule.c b/sdk/lib/3rdparty/freetype/src/autofit/afmodule.c index 1360284ac55d7..fa43e58b945d5 100644 --- a/sdk/lib/3rdparty/freetype/src/autofit/afmodule.c +++ b/sdk/lib/3rdparty/freetype/src/autofit/afmodule.c @@ -1,26 +1,25 @@ -/***************************************************************************/ -/* */ -/* afmodule.c */ -/* */ -/* Auto-fitter module implementation (body). */ -/* */ -/* Copyright 2003-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * afmodule.c + * + * Auto-fitter module implementation (body). + * + * Copyright (C) 2003-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include "afglobal.h" #include "afmodule.h" #include "afloader.h" #include "aferrors.h" -#include "afpic.h" #ifdef FT_DEBUG_AUTOFIT @@ -60,14 +59,14 @@ #include FT_SERVICE_PROPERTIES_H - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_afmodule +#define FT_COMPONENT afmodule static FT_Error @@ -104,19 +103,6 @@ } -#ifdef FT_CONFIG_OPTION_PIC - -#undef AF_SCRIPT_CLASSES_GET -#define AF_SCRIPT_CLASSES_GET \ - ( GET_PIC( ft_module->library )->af_script_classes ) - -#undef AF_STYLE_CLASSES_GET -#define AF_STYLE_CLASSES_GET \ - ( GET_PIC( ft_module->library )->af_style_classes ) - -#endif - - static FT_Error af_property_set( FT_Module ft_module, const char* property_name, @@ -147,9 +133,9 @@ /* We translate the fallback script to a fallback style that uses */ /* `fallback-script' as its script and `AF_COVERAGE_NONE' as its */ /* coverage value. */ - for ( ss = 0; AF_STYLE_CLASSES_GET[ss]; ss++ ) + for ( ss = 0; af_style_classes[ss]; ss++ ) { - AF_StyleClass style_class = AF_STYLE_CLASSES_GET[ss]; + AF_StyleClass style_class = af_style_classes[ss]; if ( (FT_UInt)style_class->script == *fallback_script && @@ -160,7 +146,7 @@ } } - if ( !AF_STYLE_CLASSES_GET[ss] ) + if ( !af_style_classes[ss] ) { FT_TRACE0(( "af_property_set: Invalid value %d for property `%s'\n", fallback_script, property_name )); @@ -357,7 +343,7 @@ { FT_UInt* val = (FT_UInt*)value; - AF_StyleClass style_class = AF_STYLE_CLASSES_GET[fallback_style]; + AF_StyleClass style_class = af_style_classes[fallback_style]; *val = style_class->script; @@ -440,28 +426,16 @@ FT_DEFINE_SERVICEDESCREC1( af_services, - FT_SERVICE_ID_PROPERTIES, &AF_SERVICE_PROPERTIES_GET ) + FT_SERVICE_ID_PROPERTIES, &af_service_properties ) FT_CALLBACK_DEF( FT_Module_Interface ) af_get_interface( FT_Module module, const char* module_interface ) { - /* AF_SERVICES_GET dereferences `library' in PIC mode */ -#ifdef FT_CONFIG_OPTION_PIC - FT_Library library; - - - if ( !module ) - return NULL; - library = module->library; - if ( !library ) - return NULL; -#else FT_UNUSED( module ); -#endif - return ft_service_list_lookup( AF_SERVICES_GET, module_interface ); + return ft_service_list_lookup( af_services, module_interface ); } @@ -518,7 +492,13 @@ /* in debug mode, we use a global object that survives this routine */ AF_GlyphHints hints = _af_debug_hints_rec; +#ifdef __REACTOS__ + AF_LoaderRec *loader = malloc(sizeof(*loader)); + if (!loader) + return FT_Err_Out_Of_Memory; +#else AF_LoaderRec loader[1]; +#endif FT_UNUSED( size ); @@ -533,7 +513,7 @@ glyph_index, load_flags ); #ifdef FT_DEBUG_LEVEL_TRACE - if ( ft_trace_levels[FT_COMPONENT] ) + if ( ft_trace_levels[FT_TRACE_COMP( FT_COMPONENT )] ) { #endif af_glyph_hints_dump_points( hints, 0 ); @@ -545,16 +525,21 @@ af_loader_done( loader ); +#ifdef __REACTOS__ + free(loader); +#endif return error; #else /* !FT_DEBUG_AUTOFIT */ #ifdef __REACTOS__ - AF_GlyphHintsRec *hints = malloc(sizeof(AF_GlyphHintsRec)); - AF_LoaderRec *loader = malloc(sizeof(AF_LoaderRec)); + AF_GlyphHintsRec *hints = malloc(sizeof(*hints)); + AF_LoaderRec *loader = malloc(sizeof(*loader)); if (!hints || !loader) { - error = FT_Err_Out_Of_Memory; + free(hints); + free(loader); + error = FT_Err_Out_Of_Memory; goto Exit; } #else @@ -579,7 +564,6 @@ free(hints); free(loader); #endif - return error; #endif /* !FT_DEBUG_AUTOFIT */ @@ -605,7 +589,7 @@ 0x10000L, /* version 1.0 of the autofitter */ 0x20000L, /* requires FreeType 2.0 or above */ - (const void*)&AF_INTERFACE_GET, + (const void*)&af_autofitter_interface, (FT_Module_Constructor)af_autofitter_init, /* module_init */ (FT_Module_Destructor) af_autofitter_done, /* module_done */ diff --git a/sdk/lib/3rdparty/freetype/src/autofit/afmodule.h b/sdk/lib/3rdparty/freetype/src/autofit/afmodule.h index 56f64eaf23141..b410809aa83cd 100644 --- a/sdk/lib/3rdparty/freetype/src/autofit/afmodule.h +++ b/sdk/lib/3rdparty/freetype/src/autofit/afmodule.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* afmodule.h */ -/* */ -/* Auto-fitter module implementation (specification). */ -/* */ -/* Copyright 2003-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * afmodule.h + * + * Auto-fitter module implementation (specification). + * + * Copyright (C) 2003-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef AFMODULE_H_ @@ -28,8 +28,8 @@ FT_BEGIN_HEADER /* - * This is the `extended' FT_Module structure that holds the - * autofitter's global data. + * This is the `extended' FT_Module structure that holds the + * autofitter's global data. */ typedef struct AF_ModuleRec_ diff --git a/sdk/lib/3rdparty/freetype/src/autofit/afpic.c b/sdk/lib/3rdparty/freetype/src/autofit/afpic.c deleted file mode 100644 index d48d016a0e8b6..0000000000000 --- a/sdk/lib/3rdparty/freetype/src/autofit/afpic.c +++ /dev/null @@ -1,152 +0,0 @@ -/***************************************************************************/ -/* */ -/* afpic.c */ -/* */ -/* The FreeType position independent code services for autofit module. */ -/* */ -/* Copyright 2009-2018 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_FREETYPE_H -#include FT_INTERNAL_OBJECTS_H -#include "afpic.h" -#include "afglobal.h" -#include "aferrors.h" - - -#ifdef FT_CONFIG_OPTION_PIC - - /* forward declaration of PIC init functions from afmodule.c */ - FT_Error - FT_Create_Class_af_services( FT_Library library, - FT_ServiceDescRec** output_class ); - - void - FT_Destroy_Class_af_services( FT_Library library, - FT_ServiceDescRec* clazz ); - - void - FT_Init_Class_af_service_properties( FT_Service_PropertiesRec* clazz ); - - void FT_Init_Class_af_autofitter_interface( - FT_Library library, - FT_AutoHinter_InterfaceRec* clazz ); - - - /* forward declaration of PIC init functions from writing system classes */ -#undef WRITING_SYSTEM -#define WRITING_SYSTEM( ws, WS ) /* empty */ - -#include "afwrtsys.h" - - - void - autofit_module_class_pic_free( FT_Library library ) - { - FT_PIC_Container* pic_container = &library->pic_container; - FT_Memory memory = library->memory; - - - if ( pic_container->autofit ) - { - AFModulePIC* container = (AFModulePIC*)pic_container->autofit; - - - if ( container->af_services ) - FT_Destroy_Class_af_services( library, - container->af_services ); - container->af_services = NULL; - - FT_FREE( container ); - pic_container->autofit = NULL; - } - } - - - FT_Error - autofit_module_class_pic_init( FT_Library library ) - { - FT_PIC_Container* pic_container = &library->pic_container; - FT_UInt ss; - FT_Error error = FT_Err_Ok; - AFModulePIC* container = NULL; - FT_Memory memory = library->memory; - - - /* allocate pointer, clear and set global container pointer */ - if ( FT_ALLOC ( container, sizeof ( *container ) ) ) - return error; - FT_MEM_SET( container, 0, sizeof ( *container ) ); - pic_container->autofit = container; - - /* initialize pointer table - */ - /* this is how the module usually expects this data */ - error = FT_Create_Class_af_services( library, - &container->af_services ); - if ( error ) - goto Exit; - - FT_Init_Class_af_service_properties( &container->af_service_properties ); - - for ( ss = 0; ss < AF_WRITING_SYSTEM_MAX; ss++ ) - container->af_writing_system_classes[ss] = - &container->af_writing_system_classes_rec[ss]; - container->af_writing_system_classes[AF_WRITING_SYSTEM_MAX] = NULL; - - for ( ss = 0; ss < AF_SCRIPT_MAX; ss++ ) - container->af_script_classes[ss] = - &container->af_script_classes_rec[ss]; - container->af_script_classes[AF_SCRIPT_MAX] = NULL; - - for ( ss = 0; ss < AF_STYLE_MAX; ss++ ) - container->af_style_classes[ss] = - &container->af_style_classes_rec[ss]; - container->af_style_classes[AF_STYLE_MAX] = NULL; - -#undef WRITING_SYSTEM -#define WRITING_SYSTEM( ws, WS ) \ - FT_Init_Class_af_ ## ws ## _writing_system_class( \ - &container->af_writing_system_classes_rec[ss++] ); - - ss = 0; -#include "afwrtsys.h" - -#undef SCRIPT -#define SCRIPT( s, S, d, h, H, sss ) \ - FT_Init_Class_af_ ## s ## _script_class( \ - &container->af_script_classes_rec[ss++] ); - - ss = 0; -#include "afscript.h" - -#undef STYLE -#define STYLE( s, S, d, ws, sc, bss, c ) \ - FT_Init_Class_af_ ## s ## _style_class( \ - &container->af_style_classes_rec[ss++] ); - - ss = 0; -#include "afstyles.h" - - FT_Init_Class_af_autofitter_interface( - library, &container->af_autofitter_interface ); - - Exit: - if ( error ) - autofit_module_class_pic_free( library ); - return error; - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - -/* END */ diff --git a/sdk/lib/3rdparty/freetype/src/autofit/afpic.h b/sdk/lib/3rdparty/freetype/src/autofit/afpic.h deleted file mode 100644 index 0c7345678597d..0000000000000 --- a/sdk/lib/3rdparty/freetype/src/autofit/afpic.h +++ /dev/null @@ -1,105 +0,0 @@ -/***************************************************************************/ -/* */ -/* afpic.h */ -/* */ -/* The FreeType position independent code services for autofit module. */ -/* */ -/* Copyright 2009-2018 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#ifndef AFPIC_H_ -#define AFPIC_H_ - - -#include FT_INTERNAL_PIC_H - - -#ifndef FT_CONFIG_OPTION_PIC - -#define AF_SERVICES_GET af_services -#define AF_SERVICE_PROPERTIES_GET af_service_properties - -#define AF_WRITING_SYSTEM_CLASSES_GET af_writing_system_classes -#define AF_SCRIPT_CLASSES_GET af_script_classes -#define AF_STYLE_CLASSES_GET af_style_classes -#define AF_INTERFACE_GET af_autofitter_interface - -#else /* FT_CONFIG_OPTION_PIC */ - - /* some include files required for members of AFModulePIC */ -#include FT_SERVICE_PROPERTIES_H - -#include "aftypes.h" - - -FT_BEGIN_HEADER - - typedef struct AFModulePIC_ - { - FT_ServiceDescRec* af_services; - FT_Service_PropertiesRec af_service_properties; - - AF_WritingSystemClass af_writing_system_classes - [AF_WRITING_SYSTEM_MAX + 1]; - AF_WritingSystemClassRec af_writing_system_classes_rec - [AF_WRITING_SYSTEM_MAX]; - - AF_ScriptClass af_script_classes - [AF_SCRIPT_MAX + 1]; - AF_ScriptClassRec af_script_classes_rec - [AF_SCRIPT_MAX]; - - AF_StyleClass af_style_classes - [AF_STYLE_MAX + 1]; - AF_StyleClassRec af_style_classes_rec - [AF_STYLE_MAX]; - - FT_AutoHinter_InterfaceRec af_autofitter_interface; - - } AFModulePIC; - - -#define GET_PIC( lib ) \ - ( (AFModulePIC*)( (lib)->pic_container.autofit ) ) - -#define AF_SERVICES_GET \ - ( GET_PIC( library )->af_services ) -#define AF_SERVICE_PROPERTIES_GET \ - ( GET_PIC( library )->af_service_properties ) - -#define AF_WRITING_SYSTEM_CLASSES_GET \ - ( GET_PIC( FT_FACE_LIBRARY( globals->face ) )->af_writing_system_classes ) -#define AF_SCRIPT_CLASSES_GET \ - ( GET_PIC( FT_FACE_LIBRARY( globals->face ) )->af_script_classes ) -#define AF_STYLE_CLASSES_GET \ - ( GET_PIC( FT_FACE_LIBRARY( globals->face ) )->af_style_classes ) -#define AF_INTERFACE_GET \ - ( GET_PIC( library )->af_autofitter_interface ) - - - /* see afpic.c for the implementation */ - void - autofit_module_class_pic_free( FT_Library library ); - - FT_Error - autofit_module_class_pic_init( FT_Library library ); - -FT_END_HEADER - -#endif /* FT_CONFIG_OPTION_PIC */ - - /* */ - -#endif /* AFPIC_H_ */ - - -/* END */ diff --git a/sdk/lib/3rdparty/freetype/src/autofit/afranges.c b/sdk/lib/3rdparty/freetype/src/autofit/afranges.c index 1355c5e7cc35e..c0dba818a1346 100644 --- a/sdk/lib/3rdparty/freetype/src/autofit/afranges.c +++ b/sdk/lib/3rdparty/freetype/src/autofit/afranges.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* afranges.c */ -/* */ -/* Auto-fitter Unicode script ranges (body). */ -/* */ -/* Copyright 2013-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * afranges.c + * + * Auto-fitter Unicode script ranges (body). + * + * Copyright (C) 2013-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include "afranges.h" @@ -91,7 +91,7 @@ AF_UNIRANGE_REC( 0x06E7, 0x06E8 ), AF_UNIRANGE_REC( 0x06EA, 0x06ED ), AF_UNIRANGE_REC( 0x08D4, 0x08E1 ), - AF_UNIRANGE_REC( 0x08E3, 0x08FF ), + AF_UNIRANGE_REC( 0x08D3, 0x08FF ), AF_UNIRANGE_REC( 0xFBB2, 0xFBC1 ), AF_UNIRANGE_REC( 0xFE70, 0xFE70 ), AF_UNIRANGE_REC( 0xFE72, 0xFE72 ), @@ -163,6 +163,7 @@ AF_UNIRANGE_REC( 0x09C1, 0x09C4 ), AF_UNIRANGE_REC( 0x09CD, 0x09CD ), AF_UNIRANGE_REC( 0x09E2, 0x09E3 ), + AF_UNIRANGE_REC( 0x09FE, 0x09FE ), AF_UNIRANGE_REC( 0, 0 ) }; @@ -190,6 +191,7 @@ { AF_UNIRANGE_REC( 0x11100, 0x11102 ), AF_UNIRANGE_REC( 0x11127, 0x11134 ), + AF_UNIRANGE_REC( 0x11146, 0x11146 ), AF_UNIRANGE_REC( 0, 0 ) }; @@ -304,6 +306,7 @@ AF_UNIRANGE_REC( 0x0953, 0x0957 ), AF_UNIRANGE_REC( 0x0962, 0x0963 ), AF_UNIRANGE_REC( 0xA8E0, 0xA8F1 ), + AF_UNIRANGE_REC( 0xA8FF, 0xA8FF ), AF_UNIRANGE_REC( 0, 0 ) }; @@ -338,11 +341,8 @@ const AF_Script_UniRangeRec af_geor_uniranges[] = { - AF_UNIRANGE_REC( 0x10D0, 0x10FF ), /* Georgian (Mkhedruli) */ -#if 0 - /* the following range is proposed for inclusion in Unicode */ - AF_UNIRANGE_REC( 0x1C90, 0x1CBF ), /* Georgian (Mtavruli) */ -#endif + AF_UNIRANGE_REC( 0x10D0, 0x10FF ), /* Georgian (Mkhedruli) */ + AF_UNIRANGE_REC( 0x1C90, 0x1CBF ), /* Georgian Extended (Mtavruli) */ AF_UNIRANGE_REC( 0, 0 ) }; @@ -355,8 +355,8 @@ const AF_Script_UniRangeRec af_geok_uniranges[] = { /* Khutsuri */ - AF_UNIRANGE_REC( 0x10A0, 0x10CD ), /* Georgian (Asomtavruli) */ - AF_UNIRANGE_REC( 0x2D00, 0x2D2D ), /* Georgian (Nuskhuri) */ + AF_UNIRANGE_REC( 0x10A0, 0x10CD ), /* Georgian (Asomtavruli) */ + AF_UNIRANGE_REC( 0x2D00, 0x2D2D ), /* Georgian Supplement (Nuskhuri) */ AF_UNIRANGE_REC( 0, 0 ) }; @@ -425,6 +425,7 @@ AF_UNIRANGE_REC( 0x0AC1, 0x0AC8 ), AF_UNIRANGE_REC( 0x0ACD, 0x0ACD ), AF_UNIRANGE_REC( 0x0AE2, 0x0AE3 ), + AF_UNIRANGE_REC( 0x0AFA, 0x0AFF ), AF_UNIRANGE_REC( 0, 0 ) }; @@ -655,7 +656,8 @@ const AF_Script_UniRangeRec af_mlym_nonbase_uniranges[] = { - AF_UNIRANGE_REC( 0x0D01, 0x0D01 ), + AF_UNIRANGE_REC( 0x0D00, 0x0D01 ), + AF_UNIRANGE_REC( 0x0D3B, 0x0D3C ), AF_UNIRANGE_REC( 0x0D4D, 0x0D4E ), AF_UNIRANGE_REC( 0x0D62, 0x0D63 ), AF_UNIRANGE_REC( 0, 0 ) @@ -697,6 +699,7 @@ const AF_Script_UniRangeRec af_nkoo_nonbase_uniranges[] = { AF_UNIRANGE_REC( 0x07EB, 0x07F5 ), + AF_UNIRANGE_REC( 0x07FD, 0x07FD ), AF_UNIRANGE_REC( 0, 0 ) }; @@ -856,6 +859,7 @@ const AF_Script_UniRangeRec af_telu_nonbase_uniranges[] = { AF_UNIRANGE_REC( 0x0C00, 0x0C00 ), + AF_UNIRANGE_REC( 0x0C04, 0x0C04 ), AF_UNIRANGE_REC( 0x0C3E, 0x0C40 ), AF_UNIRANGE_REC( 0x0C46, 0x0C56 ), AF_UNIRANGE_REC( 0x0C62, 0x0C63 ), @@ -1006,10 +1010,13 @@ AF_UNIRANGE_REC( 0xFE30, 0xFE4F ), /* CJK Compatibility Forms */ AF_UNIRANGE_REC( 0xFF00, 0xFFEF ), /* Halfwidth and Fullwidth Forms */ AF_UNIRANGE_REC( 0x1B000, 0x1B0FF ), /* Kana Supplement */ + AF_UNIRANGE_REC( 0x1B100, 0x1B12F ), /* Kana Extended-A */ AF_UNIRANGE_REC( 0x1D300, 0x1D35F ), /* Tai Xuan Hing Symbols */ AF_UNIRANGE_REC( 0x20000, 0x2A6DF ), /* CJK Unified Ideographs Extension B */ AF_UNIRANGE_REC( 0x2A700, 0x2B73F ), /* CJK Unified Ideographs Extension C */ AF_UNIRANGE_REC( 0x2B740, 0x2B81F ), /* CJK Unified Ideographs Extension D */ + AF_UNIRANGE_REC( 0x2B820, 0x2CEAF ), /* CJK Unified Ideographs Extension E */ + AF_UNIRANGE_REC( 0x2CEB0, 0x2EBEF ), /* CJK Unified Ideographs Extension F */ AF_UNIRANGE_REC( 0x2F800, 0x2FA1F ), /* CJK Compatibility Ideographs Supplement */ AF_UNIRANGE_REC( 0, 0 ) }; diff --git a/sdk/lib/3rdparty/freetype/src/autofit/afranges.h b/sdk/lib/3rdparty/freetype/src/autofit/afranges.h index ba3b5e7ccbc5c..d5917aefed0ff 100644 --- a/sdk/lib/3rdparty/freetype/src/autofit/afranges.h +++ b/sdk/lib/3rdparty/freetype/src/autofit/afranges.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* afranges.h */ -/* */ -/* Auto-fitter Unicode script ranges (specification). */ -/* */ -/* Copyright 2013-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * afranges.h + * + * Auto-fitter Unicode script ranges (specification). + * + * Copyright (C) 2013-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef AFRANGES_H_ diff --git a/sdk/lib/3rdparty/freetype/src/autofit/afscript.h b/sdk/lib/3rdparty/freetype/src/autofit/afscript.h index 6ac193f6a71ca..c2f0c7ac60a31 100644 --- a/sdk/lib/3rdparty/freetype/src/autofit/afscript.h +++ b/sdk/lib/3rdparty/freetype/src/autofit/afscript.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* afscript.h */ -/* */ -/* Auto-fitter scripts (specification only). */ -/* */ -/* Copyright 2013-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * afscript.h + * + * Auto-fitter scripts (specification only). + * + * Copyright (C) 2013-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ /* The following part can be included multiple times. */ @@ -137,7 +137,7 @@ "Georgian (Mkhedruli)", HB_SCRIPT_GEORGIAN, HINTING_BOTTOM_TO_TOP, - "\xE1\x83\x98 \xE1\x83\x94 \xE1\x83\x90" ) /* ი ე ა */ + "\xE1\x83\x98 \xE1\x83\x94 \xE1\x83\x90 \xE1\xB2\xBF" ) /* ი ე ა Ი */ SCRIPT( geok, GEOK, "Georgian (Khutsuri)", diff --git a/sdk/lib/3rdparty/freetype/src/autofit/afshaper.c b/sdk/lib/3rdparty/freetype/src/autofit/afshaper.c index f30828173cf62..a5191c69158f8 100644 --- a/sdk/lib/3rdparty/freetype/src/autofit/afshaper.c +++ b/sdk/lib/3rdparty/freetype/src/autofit/afshaper.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* afshaper.c */ -/* */ -/* HarfBuzz interface for accessing OpenType features (body). */ -/* */ -/* Copyright 2013-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * afshaper.c + * + * HarfBuzz interface for accessing OpenType features (body). + * + * Copyright (C) 2013-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -26,14 +26,14 @@ #ifdef FT_CONFIG_OPTION_USE_HARFBUZZ - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_afshaper +#define FT_COMPONENT afshaper /* @@ -591,14 +591,9 @@ void* af_shaper_buf_create( FT_Face face ) { - FT_Error error; - FT_Memory memory = face->memory; - FT_ULong* buf; - - - FT_MEM_ALLOC( buf, sizeof ( FT_ULong ) ); + FT_UNUSED( face ); - return (void*)buf; + return NULL; } @@ -606,10 +601,8 @@ af_shaper_buf_destroy( FT_Face face, void* buf ) { - FT_Memory memory = face->memory; - - - FT_FREE( buf ); + FT_UNUSED( face ); + FT_UNUSED( buf ); } diff --git a/sdk/lib/3rdparty/freetype/src/autofit/afshaper.h b/sdk/lib/3rdparty/freetype/src/autofit/afshaper.h index 7efd9f6a4e6ee..06a1e06616201 100644 --- a/sdk/lib/3rdparty/freetype/src/autofit/afshaper.h +++ b/sdk/lib/3rdparty/freetype/src/autofit/afshaper.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* afshaper.h */ -/* */ -/* HarfBuzz interface for accessing OpenType features (specification). */ -/* */ -/* Copyright 2013-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * afshaper.h + * + * HarfBuzz interface for accessing OpenType features (specification). + * + * Copyright (C) 2013-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef AFSHAPER_H_ diff --git a/sdk/lib/3rdparty/freetype/src/autofit/afstyles.h b/sdk/lib/3rdparty/freetype/src/autofit/afstyles.h index e2688b3fc254f..edf4f54edd72e 100644 --- a/sdk/lib/3rdparty/freetype/src/autofit/afstyles.h +++ b/sdk/lib/3rdparty/freetype/src/autofit/afstyles.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* afstyles.h */ -/* */ -/* Auto-fitter styles (specification only). */ -/* */ -/* Copyright 2013-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * afstyles.h + * + * Auto-fitter styles (specification only). + * + * Copyright (C) 2013-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ /* The following part can be included multiple times. */ diff --git a/sdk/lib/3rdparty/freetype/src/autofit/aftypes.h b/sdk/lib/3rdparty/freetype/src/autofit/aftypes.h index a50013439bf89..579003d27d9b6 100644 --- a/sdk/lib/3rdparty/freetype/src/autofit/aftypes.h +++ b/sdk/lib/3rdparty/freetype/src/autofit/aftypes.h @@ -1,30 +1,30 @@ -/***************************************************************************/ -/* */ -/* aftypes.h */ -/* */ -/* Auto-fitter types (specification only). */ -/* */ -/* Copyright 2003-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * aftypes.h + * + * Auto-fitter types (specification only). + * + * Copyright (C) 2003-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ /************************************************************************* * - * The auto-fitter is a complete rewrite of the old auto-hinter. - * Its main feature is the ability to differentiate between different - * writing systems and scripts in order to apply specific rules. + * The auto-fitter is a complete rewrite of the old auto-hinter. + * Its main feature is the ability to differentiate between different + * writing systems and scripts in order to apply specific rules. * - * The code has also been compartmentalized into several entities that - * should make algorithmic experimentation easier than with the old - * code. + * The code has also been compartmentalized into several entities that + * should make algorithmic experimentation easier than with the old + * code. * *************************************************************************/ @@ -76,9 +76,9 @@ extern void* _af_debug_hints; typedef struct AF_WidthRec_ { - FT_Pos org; /* original position/width in font units */ - FT_Pos cur; /* current/scaled position/width in device sub-pixels */ - FT_Pos fit; /* current/fitted position/width in device sub-pixels */ + FT_Pos org; /* original position/width in font units */ + FT_Pos cur; /* current/scaled position/width in device subpixels */ + FT_Pos fit; /* current/fitted position/width in device subpixels */ } AF_WidthRec, *AF_Width; @@ -102,9 +102,9 @@ extern void* _af_debug_hints; /*************************************************************************/ /* - * The auto-fitter doesn't need a very high angular accuracy; - * this allows us to speed up some computations considerably with a - * light Cordic algorithm (see afangles.c). + * The auto-fitter doesn't need a very high angular accuracy; + * this allows us to speed up some computations considerably with a + * light Cordic algorithm (see afangles.c). */ typedef FT_Int AF_Angle; @@ -118,7 +118,7 @@ extern void* _af_debug_hints; #if 0 /* - * compute the angle of a given 2-D vector + * compute the angle of a given 2-D vector */ FT_LOCAL( AF_Angle ) af_angle_atan( FT_Pos dx, @@ -126,8 +126,8 @@ extern void* _af_debug_hints; /* - * compute `angle2 - angle1'; the result is always within - * the range [-AF_ANGLE_PI .. AF_ANGLE_PI - 1] + * compute `angle2 - angle1'; the result is always within + * the range [-AF_ANGLE_PI .. AF_ANGLE_PI - 1] */ FT_LOCAL( AF_Angle ) af_angle_diff( AF_Angle angle1, @@ -150,8 +150,9 @@ extern void* _af_debug_hints; FT_END_STMNT - /* opaque handle to glyph-specific hints -- see `afhints.h' for more - * details + /* + * opaque handle to glyph-specific hints -- see `afhints.h' for more + * details */ typedef struct AF_GlyphHintsRec_* AF_GlyphHints; @@ -165,8 +166,8 @@ extern void* _af_debug_hints; /*************************************************************************/ /* - * A scaler models the target pixel device that will receive the - * auto-hinted glyph image. + * A scaler models the target pixel device that will receive the + * auto-hinted glyph image. */ #define AF_SCALER_FLAG_NO_HORIZONTAL 1U /* disable horizontal hinting */ @@ -197,8 +198,9 @@ extern void* _af_debug_hints; typedef struct AF_StyleMetricsRec_* AF_StyleMetrics; - /* This function parses an FT_Face to compute global metrics for - * a specific style. + /* + * This function parses an FT_Face to compute global metrics for + * a specific style. */ typedef FT_Error (*AF_WritingSystem_InitMetricsFunc)( AF_StyleMetrics metrics, @@ -237,22 +239,22 @@ extern void* _af_debug_hints; /*************************************************************************/ /* - * For the auto-hinter, a writing system consists of multiple scripts that - * can be handled similarly *in a typographical way*; the relationship is - * not based on history. For example, both the Greek and the unrelated - * Armenian scripts share the same features like ascender, descender, - * x-height, etc. Essentially, a writing system is covered by a - * submodule of the auto-fitter; it contains + * For the auto-hinter, a writing system consists of multiple scripts that + * can be handled similarly *in a typographical way*; the relationship is + * not based on history. For example, both the Greek and the unrelated + * Armenian scripts share the same features like ascender, descender, + * x-height, etc. Essentially, a writing system is covered by a + * submodule of the auto-fitter; it contains * - * - a specific global analyzer that computes global metrics specific to - * the script (based on script-specific characters to identify ascender - * height, x-height, etc.), + * - a specific global analyzer that computes global metrics specific to + * the script (based on script-specific characters to identify ascender + * height, x-height, etc.), * - * - a specific glyph analyzer that computes segments and edges for each - * glyph covered by the script, + * - a specific glyph analyzer that computes segments and edges for each + * glyph covered by the script, * - * - a specific grid-fitting algorithm that distorts the scaled glyph - * outline according to the results of the glyph analyzer. + * - a specific grid-fitting algorithm that distorts the scaled glyph + * outline according to the results of the glyph analyzer. */ #define AFWRTSYS_H_ /* don't load header files */ @@ -300,12 +302,12 @@ extern void* _af_debug_hints; /*************************************************************************/ /* - * Each script is associated with two sets of Unicode ranges to test - * whether the font face supports the script, and which non-base - * characters the script contains. + * Each script is associated with two sets of Unicode ranges to test + * whether the font face supports the script, and which non-base + * characters the script contains. * - * We use four-letter script tags from the OpenType specification, - * extended by `NONE', which indicates `no script'. + * We use four-letter script tags from the OpenType specification, + * extended by `NONE', which indicates `no script'. */ #undef SCRIPT @@ -361,41 +363,41 @@ extern void* _af_debug_hints; /*************************************************************************/ /* - * Usually, a font contains more glyphs than can be addressed by its - * character map. + * Usually, a font contains more glyphs than can be addressed by its + * character map. * - * In the PostScript font world, encoding vectors specific to a given - * task are used to select such glyphs, and these glyphs can be often - * recognized by having a suffix in its glyph names. For example, a - * superscript glyph `A' might be called `A.sup'. Unfortunately, this - * naming scheme is not standardized and thus unusable for us. + * In the PostScript font world, encoding vectors specific to a given + * task are used to select such glyphs, and these glyphs can be often + * recognized by having a suffix in its glyph names. For example, a + * superscript glyph `A' might be called `A.sup'. Unfortunately, this + * naming scheme is not standardized and thus unusable for us. * - * In the OpenType world, a better solution was invented, namely - * `features', which cleanly separate a character's input encoding from - * the corresponding glyph's appearance, and which don't use glyph names - * at all. For our purposes, and slightly generalized, an OpenType - * feature is a name of a mapping that maps character codes to - * non-standard glyph indices (features get used for other things also). - * For example, the `sups' feature provides superscript glyphs, thus - * mapping character codes like `A' or `B' to superscript glyph - * representation forms. How this mapping happens is completely - * uninteresting to us. + * In the OpenType world, a better solution was invented, namely + * `features', which cleanly separate a character's input encoding from + * the corresponding glyph's appearance, and which don't use glyph names + * at all. For our purposes, and slightly generalized, an OpenType + * feature is a name of a mapping that maps character codes to + * non-standard glyph indices (features get used for other things also). + * For example, the `sups' feature provides superscript glyphs, thus + * mapping character codes like `A' or `B' to superscript glyph + * representation forms. How this mapping happens is completely + * uninteresting to us. * - * For the auto-hinter, a `coverage' represents all glyphs of an OpenType - * feature collected in a set (as listed below) that can be hinted - * together. To continue the above example, superscript glyphs must not - * be hinted together with normal glyphs because the blue zones - * completely differ. + * For the auto-hinter, a `coverage' represents all glyphs of an OpenType + * feature collected in a set (as listed below) that can be hinted + * together. To continue the above example, superscript glyphs must not + * be hinted together with normal glyphs because the blue zones + * completely differ. * - * Note that FreeType itself doesn't compute coverages; it only provides - * the glyphs addressable by the default Unicode character map. Instead, - * we use the HarfBuzz library (if available), which has many functions - * exactly for this purpose. + * Note that FreeType itself doesn't compute coverages; it only provides + * the glyphs addressable by the default Unicode character map. Instead, + * we use the HarfBuzz library (if available), which has many functions + * exactly for this purpose. * - * AF_COVERAGE_DEFAULT is special: It should cover everything that isn't - * listed separately (including the glyphs addressable by the character - * map). In case HarfBuzz isn't available, it exactly covers the glyphs - * addressable by the character map. + * AF_COVERAGE_DEFAULT is special: It should cover everything that isn't + * listed separately (including the glyphs addressable by the character + * map). In case HarfBuzz isn't available, it exactly covers the glyphs + * addressable by the character map. * */ @@ -423,8 +425,8 @@ extern void* _af_debug_hints; /*************************************************************************/ /* - * The topmost structure for modelling the auto-hinter glyph input data - * is a `style class', grouping everything together. + * The topmost structure for modelling the auto-hinter glyph input data + * is a `style class', grouping everything together. */ #undef STYLE @@ -486,8 +488,6 @@ extern void* _af_debug_hints; /* Declare and define vtables for classes */ -#ifndef FT_CONFIG_OPTION_PIC - #define AF_DECLARE_WRITING_SYSTEM_CLASS( writing_system_class ) \ FT_CALLBACK_TABLE const AF_WritingSystemClassRec \ writing_system_class; @@ -562,87 +562,9 @@ extern void* _af_debug_hints; coverage \ }; -#else /* FT_CONFIG_OPTION_PIC */ - -#define AF_DECLARE_WRITING_SYSTEM_CLASS( writing_system_class ) \ - FT_LOCAL( void ) \ - FT_Init_Class_ ## writing_system_class( AF_WritingSystemClassRec* ac ); - -#define AF_DEFINE_WRITING_SYSTEM_CLASS( \ - writing_system_class, \ - system, \ - m_size, \ - m_init, \ - m_scale, \ - m_done, \ - m_stdw, \ - h_init, \ - h_apply ) \ - FT_LOCAL_DEF( void ) \ - FT_Init_Class_ ## writing_system_class( AF_WritingSystemClassRec* ac ) \ - { \ - ac->writing_system = system; \ - \ - ac->style_metrics_size = m_size; \ - \ - ac->style_metrics_init = m_init; \ - ac->style_metrics_scale = m_scale; \ - ac->style_metrics_done = m_done; \ - ac->style_metrics_getstdw = m_stdw; \ - \ - ac->style_hints_init = h_init; \ - ac->style_hints_apply = h_apply; \ - } - - -#define AF_DECLARE_SCRIPT_CLASS( script_class ) \ - FT_LOCAL( void ) \ - FT_Init_Class_ ## script_class( AF_ScriptClassRec* ac ); - -#define AF_DEFINE_SCRIPT_CLASS( \ - script_class, \ - script_, \ - ranges, \ - nonbase_ranges, \ - top_to_bottom, \ - std_charstring ) \ - FT_LOCAL_DEF( void ) \ - FT_Init_Class_ ## script_class( AF_ScriptClassRec* ac ) \ - { \ - ac->script = script_; \ - ac->script_uni_ranges = ranges; \ - ac->script_uni_nonbase_ranges = nonbase_ranges; \ - ac->top_to_bottom_hinting = top_to_bottom; \ - ac->standard_charstring = std_charstring; \ - } - - -#define AF_DECLARE_STYLE_CLASS( style_class ) \ - FT_LOCAL( void ) \ - FT_Init_Class_ ## style_class( AF_StyleClassRec* ac ); - -#define AF_DEFINE_STYLE_CLASS( \ - style_class, \ - style_, \ - writing_system_, \ - script_, \ - blue_stringset_, \ - coverage_ ) \ - FT_LOCAL_DEF( void ) \ - FT_Init_Class_ ## style_class( AF_StyleClassRec* ac ) \ - { \ - ac->style = style_; \ - ac->writing_system = writing_system_; \ - ac->script = script_; \ - ac->blue_stringset = blue_stringset_; \ - ac->coverage = coverage_; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - /* */ + FT_END_HEADER #endif /* AFTYPES_H_ */ diff --git a/sdk/lib/3rdparty/freetype/src/autofit/afwarp.c b/sdk/lib/3rdparty/freetype/src/autofit/afwarp.c index 2a75ea7b35fd5..84e9753ad9931 100644 --- a/sdk/lib/3rdparty/freetype/src/autofit/afwarp.c +++ b/sdk/lib/3rdparty/freetype/src/autofit/afwarp.c @@ -1,40 +1,40 @@ -/***************************************************************************/ -/* */ -/* afwarp.c */ -/* */ -/* Auto-fitter warping algorithm (body). */ -/* */ -/* Copyright 2006-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * afwarp.c + * + * Auto-fitter warping algorithm (body). + * + * Copyright (C) 2006-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ /* - * The idea of the warping code is to slightly scale and shift a glyph - * within a single dimension so that as much of its segments are aligned - * (more or less) on the grid. To find out the optimal scaling and - * shifting value, various parameter combinations are tried and scored. + * The idea of the warping code is to slightly scale and shift a glyph + * within a single dimension so that as much of its segments are aligned + * (more or less) on the grid. To find out the optimal scaling and + * shifting value, various parameter combinations are tried and scored. */ #include "afwarp.h" #ifdef AF_CONFIG_OPTION_USE_WARPER - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_afwarp +#define FT_COMPONENT afwarp /* The weights cover the range 0/64 - 63/64 of a pixel. Obviously, */ diff --git a/sdk/lib/3rdparty/freetype/src/autofit/afwarp.h b/sdk/lib/3rdparty/freetype/src/autofit/afwarp.h index 520b1be907c6b..9a2c9a42c1b28 100644 --- a/sdk/lib/3rdparty/freetype/src/autofit/afwarp.h +++ b/sdk/lib/3rdparty/freetype/src/autofit/afwarp.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* afwarp.h */ -/* */ -/* Auto-fitter warping algorithm (specification). */ -/* */ -/* Copyright 2006-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * afwarp.h + * + * Auto-fitter warping algorithm (specification). + * + * Copyright (C) 2006-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef AFWARP_H_ @@ -47,12 +47,14 @@ FT_BEGIN_HEADER } AF_WarperRec, *AF_Warper; +#ifdef AF_CONFIG_OPTION_USE_WARPER FT_LOCAL( void ) af_warper_compute( AF_Warper warper, AF_GlyphHints hints, AF_Dimension dim, FT_Fixed *a_scale, - FT_Fixed *a_delta ); + FT_Pos *a_delta ); +#endif FT_END_HEADER diff --git a/sdk/lib/3rdparty/freetype/src/autofit/afwrtsys.h b/sdk/lib/3rdparty/freetype/src/autofit/afwrtsys.h index 4675f3242d197..5611cf441a4fa 100644 --- a/sdk/lib/3rdparty/freetype/src/autofit/afwrtsys.h +++ b/sdk/lib/3rdparty/freetype/src/autofit/afwrtsys.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* afwrtsys.h */ -/* */ -/* Auto-fitter writing systems (specification only). */ -/* */ -/* Copyright 2013-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * afwrtsys.h + * + * Auto-fitter writing systems (specification only). + * + * Copyright (C) 2013-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef AFWRTSYS_H_ diff --git a/sdk/lib/3rdparty/freetype/src/autofit/autofit.c b/sdk/lib/3rdparty/freetype/src/autofit/autofit.c index c1605160a1c40..facfec17444c1 100644 --- a/sdk/lib/3rdparty/freetype/src/autofit/autofit.c +++ b/sdk/lib/3rdparty/freetype/src/autofit/autofit.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* autofit.c */ -/* */ -/* Auto-fitter module (body). */ -/* */ -/* Copyright 2003-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * autofit.c + * + * Auto-fitter module (body). + * + * Copyright (C) 2003-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #define FT_MAKE_OPTION_SINGLE_OBJECT @@ -30,7 +30,6 @@ #include "aflatin2.c" #include "afloader.c" #include "afmodule.c" -#include "afpic.c" #include "afranges.c" #include "afshaper.c" #include "afwarp.c" diff --git a/sdk/lib/3rdparty/freetype/src/base/basepic.c b/sdk/lib/3rdparty/freetype/src/base/basepic.c deleted file mode 100644 index bc804064416c7..0000000000000 --- a/sdk/lib/3rdparty/freetype/src/base/basepic.c +++ /dev/null @@ -1,108 +0,0 @@ -/***************************************************************************/ -/* */ -/* basepic.c */ -/* */ -/* The FreeType position independent code services for base. */ -/* */ -/* Copyright 2009-2018 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_FREETYPE_H -#include FT_INTERNAL_OBJECTS_H -#include "basepic.h" - - -#ifdef FT_CONFIG_OPTION_PIC - - /* forward declaration of PIC init functions from ftglyph.c */ - void - FT_Init_Class_ft_outline_glyph_class( FT_Glyph_Class* clazz ); - - void - FT_Init_Class_ft_bitmap_glyph_class( FT_Glyph_Class* clazz ); - -#ifdef FT_CONFIG_OPTION_MAC_FONTS - /* forward declaration of PIC init function from ftrfork.c */ - /* (not modularized) */ - void - FT_Init_Table_ft_raccess_guess_table( ft_raccess_guess_rec* record ); -#endif - - /* forward declaration of PIC init functions from ftinit.c */ - FT_Error - ft_create_default_module_classes( FT_Library library ); - - void - ft_destroy_default_module_classes( FT_Library library ); - - - void - ft_base_pic_free( FT_Library library ) - { - FT_PIC_Container* pic_container = &library->pic_container; - FT_Memory memory = library->memory; - - - if ( pic_container->base ) - { - /* destroy default module classes */ - /* (in case FT_Add_Default_Modules was used) */ - ft_destroy_default_module_classes( library ); - - FT_FREE( pic_container->base ); - pic_container->base = NULL; - } - } - - - FT_Error - ft_base_pic_init( FT_Library library ) - { - FT_PIC_Container* pic_container = &library->pic_container; - FT_Error error = FT_Err_Ok; - BasePIC* container = NULL; - FT_Memory memory = library->memory; - - - /* allocate pointer, clear and set global container pointer */ - if ( FT_ALLOC( container, sizeof ( *container ) ) ) - return error; - FT_MEM_SET( container, 0, sizeof ( *container ) ); - pic_container->base = container; - - /* initialize default modules list and pointers */ - error = ft_create_default_module_classes( library ); - if ( error ) - goto Exit; - - /* initialize pointer table - */ - /* this is how the module usually expects this data */ - FT_Init_Class_ft_outline_glyph_class( - &container->ft_outline_glyph_class ); - FT_Init_Class_ft_bitmap_glyph_class( - &container->ft_bitmap_glyph_class ); -#ifdef FT_CONFIG_OPTION_MAC_FONTS - FT_Init_Table_ft_raccess_guess_table( - (ft_raccess_guess_rec*)&container->ft_raccess_guess_table ); -#endif - - Exit: - if ( error ) - ft_base_pic_free( library ); - return error; - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - -/* END */ diff --git a/sdk/lib/3rdparty/freetype/src/base/basepic.h b/sdk/lib/3rdparty/freetype/src/base/basepic.h deleted file mode 100644 index 492d1ede5647f..0000000000000 --- a/sdk/lib/3rdparty/freetype/src/base/basepic.h +++ /dev/null @@ -1,91 +0,0 @@ -/***************************************************************************/ -/* */ -/* basepic.h */ -/* */ -/* The FreeType position independent code services for base. */ -/* */ -/* Copyright 2009-2018 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#ifndef BASEPIC_H_ -#define BASEPIC_H_ - - -#include FT_INTERNAL_PIC_H - - -#ifndef FT_CONFIG_OPTION_PIC - -#define FT_OUTLINE_GLYPH_CLASS_GET &ft_outline_glyph_class -#define FT_BITMAP_GLYPH_CLASS_GET &ft_bitmap_glyph_class -#define FT_DEFAULT_MODULES_GET ft_default_modules - -#ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK -#define FT_RACCESS_GUESS_TABLE_GET ft_raccess_guess_table -#endif - -#else /* FT_CONFIG_OPTION_PIC */ - -#include FT_GLYPH_H - -#ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK -#include FT_INTERNAL_RFORK_H -#endif - - -FT_BEGIN_HEADER - - typedef struct BasePIC_ - { - FT_Module_Class** default_module_classes; - FT_Glyph_Class ft_outline_glyph_class; - FT_Glyph_Class ft_bitmap_glyph_class; - -#ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK - ft_raccess_guess_rec ft_raccess_guess_table[FT_RACCESS_N_RULES]; -#endif - - } BasePIC; - - -#define GET_PIC( lib ) ( (BasePIC*)( (lib)->pic_container.base ) ) - -#define FT_OUTLINE_GLYPH_CLASS_GET \ - ( &GET_PIC( library )->ft_outline_glyph_class ) -#define FT_BITMAP_GLYPH_CLASS_GET \ - ( &GET_PIC( library )->ft_bitmap_glyph_class ) -#define FT_DEFAULT_MODULES_GET \ - ( GET_PIC( library )->default_module_classes ) - -#ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK -#define FT_RACCESS_GUESS_TABLE_GET \ - ( GET_PIC( library )->ft_raccess_guess_table ) -#endif - - - /* see basepic.c for the implementation */ - void - ft_base_pic_free( FT_Library library ); - - FT_Error - ft_base_pic_init( FT_Library library ); - -FT_END_HEADER - -#endif /* FT_CONFIG_OPTION_PIC */ - - /* */ - -#endif /* BASEPIC_H_ */ - - -/* END */ diff --git a/sdk/lib/3rdparty/freetype/src/base/ftadvanc.c b/sdk/lib/3rdparty/freetype/src/base/ftadvanc.c index 230c84d6ad42c..0dfba57036ec2 100644 --- a/sdk/lib/3rdparty/freetype/src/base/ftadvanc.c +++ b/sdk/lib/3rdparty/freetype/src/base/ftadvanc.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftadvanc.c */ -/* */ -/* Quick computation of advance widths (body). */ -/* */ -/* Copyright 2008-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftadvanc.c + * + * Quick computation of advance widths (body). + * + * Copyright (C) 2008-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> diff --git a/sdk/lib/3rdparty/freetype/src/base/ftapi.c b/sdk/lib/3rdparty/freetype/src/base/ftapi.c deleted file mode 100644 index 32d6e95d199ff..0000000000000 --- a/sdk/lib/3rdparty/freetype/src/base/ftapi.c +++ /dev/null @@ -1,121 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftapi.c */ -/* */ -/* The FreeType compatibility functions (body). */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_LIST_H -#include FT_OUTLINE_H -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H -#include FT_TRUETYPE_TABLES_H -#include FT_OUTLINE_H - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** C O M P A T I B I L I T Y ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - /* backward compatibility API */ - - FT_BASE_DEF( void ) - FT_New_Memory_Stream( FT_Library library, - FT_Byte* base, - FT_ULong size, - FT_Stream stream ) - { - FT_UNUSED( library ); - - FT_Stream_OpenMemory( stream, base, size ); - } - - - FT_BASE_DEF( FT_Error ) - FT_Seek_Stream( FT_Stream stream, - FT_ULong pos ) - { - return FT_Stream_Seek( stream, pos ); - } - - - FT_BASE_DEF( FT_Error ) - FT_Skip_Stream( FT_Stream stream, - FT_Long distance ) - { - return FT_Stream_Skip( stream, distance ); - } - - - FT_BASE_DEF( FT_Error ) - FT_Read_Stream( FT_Stream stream, - FT_Byte* buffer, - FT_ULong count ) - { - return FT_Stream_Read( stream, buffer, count ); - } - - - FT_BASE_DEF( FT_Error ) - FT_Read_Stream_At( FT_Stream stream, - FT_ULong pos, - FT_Byte* buffer, - FT_ULong count ) - { - return FT_Stream_ReadAt( stream, pos, buffer, count ); - } - - - FT_BASE_DEF( FT_Error ) - FT_Extract_Frame( FT_Stream stream, - FT_ULong count, - FT_Byte** pbytes ) - { - return FT_Stream_ExtractFrame( stream, count, pbytes ); - } - - - FT_BASE_DEF( void ) - FT_Release_Frame( FT_Stream stream, - FT_Byte** pbytes ) - { - FT_Stream_ReleaseFrame( stream, pbytes ); - } - - FT_BASE_DEF( FT_Error ) - FT_Access_Frame( FT_Stream stream, - FT_ULong count ) - { - return FT_Stream_EnterFrame( stream, count ); - } - - - FT_BASE_DEF( void ) - FT_Forget_Frame( FT_Stream stream ) - { - FT_Stream_ExitFrame( stream ); - } - - -/* END */ diff --git a/sdk/lib/3rdparty/freetype/src/base/ftbase.c b/sdk/lib/3rdparty/freetype/src/base/ftbase.c index a1bdbaf6eac53..fb8cbfcc271fa 100644 --- a/sdk/lib/3rdparty/freetype/src/base/ftbase.c +++ b/sdk/lib/3rdparty/freetype/src/base/ftbase.c @@ -1,34 +1,36 @@ -/***************************************************************************/ -/* */ -/* ftbase.c */ -/* */ -/* Single object library component (body only). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftbase.c + * + * Single object library component (body only). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> #define FT_MAKE_OPTION_SINGLE_OBJECT -#include "basepic.c" #include "ftadvanc.c" #include "ftcalc.c" +#include "ftcolor.c" #include "ftdbgmem.c" +#include "fterrors.c" +#include "ftfntfmt.c" #include "ftgloadr.c" #include "fthash.c" +#include "ftlcdfil.c" #include "ftmac.c" #include "ftobjs.c" #include "ftoutln.c" -#include "ftpic.c" #include "ftpsprop.c" #include "ftrfork.c" #include "ftsnames.c" diff --git a/sdk/lib/3rdparty/freetype/src/base/ftbase.h b/sdk/lib/3rdparty/freetype/src/base/ftbase.h index 7e8cfad95902f..35b1c47fd9cae 100644 --- a/sdk/lib/3rdparty/freetype/src/base/ftbase.h +++ b/sdk/lib/3rdparty/freetype/src/base/ftbase.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftbase.h */ -/* */ -/* Private functions used in the `base' module (specification). */ -/* */ -/* Copyright 2008-2018 by */ -/* David Turner, Robert Wilhelm, Werner Lemberg, and suzuki toshiya. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftbase.h + * + * Private functions used in the `base' module (specification). + * + * Copyright (C) 2008-2019 by + * David Turner, Robert Wilhelm, Werner Lemberg, and suzuki toshiya. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTBASE_H_ diff --git a/sdk/lib/3rdparty/freetype/src/base/ftbbox.c b/sdk/lib/3rdparty/freetype/src/base/ftbbox.c index 151e85c97a58b..0b04fde635957 100644 --- a/sdk/lib/3rdparty/freetype/src/base/ftbbox.c +++ b/sdk/lib/3rdparty/freetype/src/base/ftbbox.c @@ -1,27 +1,27 @@ -/***************************************************************************/ -/* */ -/* ftbbox.c */ -/* */ -/* FreeType bbox computation (body). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used */ -/* modified and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This component has a _single_ role: to compute exact outline bounding */ - /* boxes. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * ftbbox.c + * + * FreeType bbox computation (body). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /************************************************************************** + * + * This component has a _single_ role: to compute exact outline bounding + * boxes. + * + */ #include <ft2build.h> @@ -61,26 +61,28 @@ ( p->y < bbox.yMin || p->y > bbox.yMax ) - /*************************************************************************/ - /* */ - /* <Function> */ - /* BBox_Move_To */ - /* */ - /* <Description> */ - /* This function is used as a `move_to' emitter during */ - /* FT_Outline_Decompose(). It simply records the destination point */ - /* in `user->last'. We also update bbox in case contour starts with */ - /* an implicit `on' point. */ - /* */ - /* <Input> */ - /* to :: A pointer to the destination vector. */ - /* */ - /* <InOut> */ - /* user :: A pointer to the current walk context. */ - /* */ - /* <Return> */ - /* Always 0. Needed for the interface only. */ - /* */ + /************************************************************************** + * + * @Function: + * BBox_Move_To + * + * @Description: + * This function is used as a `move_to' emitter during + * FT_Outline_Decompose(). It simply records the destination point + * in `user->last'. We also update bbox in case contour starts with + * an implicit `on' point. + * + * @Input: + * to :: + * A pointer to the destination vector. + * + * @InOut: + * user :: + * A pointer to the current walk context. + * + * @Return: + * Always 0. Needed for the interface only. + */ static int BBox_Move_To( FT_Vector* to, TBBox_Rec* user ) @@ -93,26 +95,28 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* BBox_Line_To */ - /* */ - /* <Description> */ - /* This function is used as a `line_to' emitter during */ - /* FT_Outline_Decompose(). It simply records the destination point */ - /* in `user->last'; no further computations are necessary because */ - /* bbox already contains both explicit ends of the line segment. */ - /* */ - /* <Input> */ - /* to :: A pointer to the destination vector. */ - /* */ - /* <InOut> */ - /* user :: A pointer to the current walk context. */ - /* */ - /* <Return> */ - /* Always 0. Needed for the interface only. */ - /* */ + /************************************************************************** + * + * @Function: + * BBox_Line_To + * + * @Description: + * This function is used as a `line_to' emitter during + * FT_Outline_Decompose(). It simply records the destination point + * in `user->last'; no further computations are necessary because + * bbox already contains both explicit ends of the line segment. + * + * @Input: + * to :: + * A pointer to the destination vector. + * + * @InOut: + * user :: + * A pointer to the current walk context. + * + * @Return: + * Always 0. Needed for the interface only. + */ static int BBox_Line_To( FT_Vector* to, TBBox_Rec* user ) @@ -123,28 +127,33 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* BBox_Conic_Check */ - /* */ - /* <Description> */ - /* Find the extrema of a 1-dimensional conic Bezier curve and update */ - /* a bounding range. This version uses direct computation, as it */ - /* doesn't need square roots. */ - /* */ - /* <Input> */ - /* y1 :: The start coordinate. */ - /* */ - /* y2 :: The coordinate of the control point. */ - /* */ - /* y3 :: The end coordinate. */ - /* */ - /* <InOut> */ - /* min :: The address of the current minimum. */ - /* */ - /* max :: The address of the current maximum. */ - /* */ + /************************************************************************** + * + * @Function: + * BBox_Conic_Check + * + * @Description: + * Find the extrema of a 1-dimensional conic Bezier curve and update + * a bounding range. This version uses direct computation, as it + * doesn't need square roots. + * + * @Input: + * y1 :: + * The start coordinate. + * + * y2 :: + * The coordinate of the control point. + * + * y3 :: + * The end coordinate. + * + * @InOut: + * min :: + * The address of the current minimum. + * + * max :: + * The address of the current maximum. + */ static void BBox_Conic_Check( FT_Pos y1, FT_Pos y2, @@ -168,32 +177,35 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* BBox_Conic_To */ - /* */ - /* <Description> */ - /* This function is used as a `conic_to' emitter during */ - /* FT_Outline_Decompose(). It checks a conic Bezier curve with the */ - /* current bounding box, and computes its extrema if necessary to */ - /* update it. */ - /* */ - /* <Input> */ - /* control :: A pointer to a control point. */ - /* */ - /* to :: A pointer to the destination vector. */ - /* */ - /* <InOut> */ - /* user :: The address of the current walk context. */ - /* */ - /* <Return> */ - /* Always 0. Needed for the interface only. */ - /* */ - /* <Note> */ - /* In the case of a non-monotonous arc, we compute directly the */ - /* extremum coordinates, as it is sufficiently fast. */ - /* */ + /************************************************************************** + * + * @Function: + * BBox_Conic_To + * + * @Description: + * This function is used as a `conic_to' emitter during + * FT_Outline_Decompose(). It checks a conic Bezier curve with the + * current bounding box, and computes its extrema if necessary to + * update it. + * + * @Input: + * control :: + * A pointer to a control point. + * + * to :: + * A pointer to the destination vector. + * + * @InOut: + * user :: + * The address of the current walk context. + * + * @Return: + * Always 0. Needed for the interface only. + * + * @Note: + * In the case of a non-monotonous arc, we compute directly the + * extremum coordinates, as it is sufficiently fast. + */ static int BBox_Conic_To( FT_Vector* control, FT_Vector* to, @@ -222,30 +234,36 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* BBox_Cubic_Check */ - /* */ - /* <Description> */ - /* Find the extrema of a 1-dimensional cubic Bezier curve and */ - /* update a bounding range. This version uses iterative splitting */ - /* because it is faster than the exact solution with square roots. */ - /* */ - /* <Input> */ - /* p1 :: The start coordinate. */ - /* */ - /* p2 :: The coordinate of the first control point. */ - /* */ - /* p3 :: The coordinate of the second control point. */ - /* */ - /* p4 :: The end coordinate. */ - /* */ - /* <InOut> */ - /* min :: The address of the current minimum. */ - /* */ - /* max :: The address of the current maximum. */ - /* */ + /************************************************************************** + * + * @Function: + * BBox_Cubic_Check + * + * @Description: + * Find the extrema of a 1-dimensional cubic Bezier curve and + * update a bounding range. This version uses iterative splitting + * because it is faster than the exact solution with square roots. + * + * @Input: + * p1 :: + * The start coordinate. + * + * p2 :: + * The coordinate of the first control point. + * + * p3 :: + * The coordinate of the second control point. + * + * p4 :: + * The end coordinate. + * + * @InOut: + * min :: + * The address of the current minimum. + * + * max :: + * The address of the current maximum. + */ static FT_Pos cubic_peak( FT_Pos q1, FT_Pos q2, @@ -361,34 +379,38 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* BBox_Cubic_To */ - /* */ - /* <Description> */ - /* This function is used as a `cubic_to' emitter during */ - /* FT_Outline_Decompose(). It checks a cubic Bezier curve with the */ - /* current bounding box, and computes its extrema if necessary to */ - /* update it. */ - /* */ - /* <Input> */ - /* control1 :: A pointer to the first control point. */ - /* */ - /* control2 :: A pointer to the second control point. */ - /* */ - /* to :: A pointer to the destination vector. */ - /* */ - /* <InOut> */ - /* user :: The address of the current walk context. */ - /* */ - /* <Return> */ - /* Always 0. Needed for the interface only. */ - /* */ - /* <Note> */ - /* In the case of a non-monotonous arc, we don't compute directly */ - /* extremum coordinates, we subdivide instead. */ - /* */ + /************************************************************************** + * + * @Function: + * BBox_Cubic_To + * + * @Description: + * This function is used as a `cubic_to' emitter during + * FT_Outline_Decompose(). It checks a cubic Bezier curve with the + * current bounding box, and computes its extrema if necessary to + * update it. + * + * @Input: + * control1 :: + * A pointer to the first control point. + * + * control2 :: + * A pointer to the second control point. + * + * to :: + * A pointer to the destination vector. + * + * @InOut: + * user :: + * The address of the current walk context. + * + * @Return: + * Always 0. Needed for the interface only. + * + * @Note: + * In the case of a non-monotonous arc, we don't compute directly + * extremum coordinates, we subdivide instead. + */ static int BBox_Cubic_To( FT_Vector* control1, FT_Vector* control2, @@ -490,12 +512,6 @@ FT_Error error; TBBox_Rec user; -#ifdef FT_CONFIG_OPTION_PIC - FT_Outline_Funcs bbox_interface; - - - Init_Class_bbox_interface( &bbox_interface ); -#endif user.bbox = bbox; diff --git a/sdk/lib/3rdparty/freetype/src/base/ftbdf.c b/sdk/lib/3rdparty/freetype/src/base/ftbdf.c index c4ea502fbc28b..c0fccd7b7c691 100644 --- a/sdk/lib/3rdparty/freetype/src/base/ftbdf.c +++ b/sdk/lib/3rdparty/freetype/src/base/ftbdf.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftbdf.c */ -/* */ -/* FreeType API for accessing BDF-specific strings (body). */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftbdf.c + * + * FreeType API for accessing BDF-specific strings (body). + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> diff --git a/sdk/lib/3rdparty/freetype/src/base/ftbitmap.c b/sdk/lib/3rdparty/freetype/src/base/ftbitmap.c index 5bfc13e2445e1..557a6ea85ae07 100644 --- a/sdk/lib/3rdparty/freetype/src/base/ftbitmap.c +++ b/sdk/lib/3rdparty/freetype/src/base/ftbitmap.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftbitmap.c */ -/* */ -/* FreeType utility functions for bitmaps (body). */ -/* */ -/* Copyright 2004-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftbitmap.c + * + * FreeType utility functions for bitmaps (body). + * + * Copyright (C) 2004-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -24,8 +24,18 @@ #include FT_INTERNAL_OBJECTS_H + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ +#undef FT_COMPONENT +#define FT_COMPONENT bitmap + + static - const FT_Bitmap null_bitmap = { 0, 0, 0, 0, 0, 0, 0, 0 }; + const FT_Bitmap null_bitmap = { 0, 0, 0, NULL, 0, 0, 0, NULL }; /* documentation is in ftbitmap.h */ @@ -237,7 +247,7 @@ unsigned char* out = buffer; unsigned char* limit = bitmap->buffer + pitch * bitmap->rows; - unsigned int delta = new_pitch - pitch; + unsigned int delta = new_pitch - len; FT_MEM_ZERO( out, new_pitch * ypixels ); @@ -247,8 +257,10 @@ { FT_MEM_COPY( out, in, len ); in += pitch; - out += pitch; + out += len; + /* we use FT_QALLOC_MULT, which doesn't zero out the buffer; */ + /* consequently, we have to manually zero out the remaining bytes */ FT_MEM_ZERO( out, delta ); out += delta; } @@ -261,14 +273,14 @@ unsigned char* out = buffer; unsigned char* limit = bitmap->buffer + pitch * bitmap->rows; - unsigned int delta = new_pitch - pitch; + unsigned int delta = new_pitch - len; while ( in < limit ) { FT_MEM_COPY( out, in, len ); in += pitch; - out += pitch; + out += len; FT_MEM_ZERO( out, delta ); out += delta; @@ -500,11 +512,20 @@ /* documentation is in ftbitmap.h */ +#ifdef __REACTOS__ + FT_EXPORT_DEF( FT_Error ) + FT_Bitmap_Convert_ReactOS_Hack( FT_Library library, + const FT_Bitmap *source, + FT_Bitmap *target, + FT_Int alignment, + FT_Bool hack ) +#else FT_EXPORT_DEF( FT_Error ) FT_Bitmap_Convert( FT_Library library, const FT_Bitmap *source, FT_Bitmap *target, FT_Int alignment ) +#endif { FT_Error error = FT_Err_Ok; FT_Memory memory; @@ -602,15 +623,20 @@ FT_Int val = ss[0]; /* avoid a byte->int cast on each line */ #ifdef __REACTOS__ - tt[0] = (FT_Byte)( ( val & 0x80 ) ? 0xff : 0); - tt[1] = (FT_Byte)( ( val & 0x40 ) ? 0xff : 0); - tt[2] = (FT_Byte)( ( val & 0x20 ) ? 0xff : 0); - tt[3] = (FT_Byte)( ( val & 0x10 ) ? 0xff : 0); - tt[4] = (FT_Byte)( ( val & 0x08 ) ? 0xff : 0); - tt[5] = (FT_Byte)( ( val & 0x04 ) ? 0xff : 0); - tt[6] = (FT_Byte)( ( val & 0x02 ) ? 0xff : 0); - tt[7] = (FT_Byte)( ( val & 0x01 ) ? 0xff : 0); -#else + if (hack) + { + tt[0] = (FT_Byte)( ( val & 0x80 ) ? 0xff : 0); + tt[1] = (FT_Byte)( ( val & 0x40 ) ? 0xff : 0); + tt[2] = (FT_Byte)( ( val & 0x20 ) ? 0xff : 0); + tt[3] = (FT_Byte)( ( val & 0x10 ) ? 0xff : 0); + tt[4] = (FT_Byte)( ( val & 0x08 ) ? 0xff : 0); + tt[5] = (FT_Byte)( ( val & 0x04 ) ? 0xff : 0); + tt[6] = (FT_Byte)( ( val & 0x02 ) ? 0xff : 0); + tt[7] = (FT_Byte)( ( val & 0x01 ) ? 0xff : 0); + } + else + { +#endif tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7 ); tt[1] = (FT_Byte)( ( val & 0x40 ) >> 6 ); tt[2] = (FT_Byte)( ( val & 0x20 ) >> 5 ); @@ -619,6 +645,8 @@ tt[5] = (FT_Byte)( ( val & 0x04 ) >> 2 ); tt[6] = (FT_Byte)( ( val & 0x02 ) >> 1 ); tt[7] = (FT_Byte)( val & 0x01 ); +#ifdef __REACTOS__ + } #endif tt += 8; @@ -635,10 +663,11 @@ for ( ; j > 0; j-- ) { #ifdef __REACTOS__ - tt[0] = (FT_Byte)( ( val & 0x80 ) ? 0xff : 0); -#else - tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7); + if (hack) + tt[0] = (FT_Byte)( ( val & 0x80 ) ? 0xff : 0); + else #endif + tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7); val <<= 1; tt += 1; } @@ -794,6 +823,341 @@ return error; } +#ifdef __REACTOS__ + FT_EXPORT_DEF( FT_Error ) + FT_Bitmap_Convert( FT_Library library, + const FT_Bitmap *source, + FT_Bitmap *target, + FT_Int alignment ) + { + return FT_Bitmap_Convert_ReactOS_Hack(library, source, target, alignment, FALSE); + } +#endif + + /* documentation is in ftbitmap.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Bitmap_Blend( FT_Library library, + const FT_Bitmap* source_, + const FT_Vector source_offset_, + FT_Bitmap* target, + FT_Vector *atarget_offset, + FT_Color color ) + { + FT_Error error = FT_Err_Ok; + FT_Memory memory; + + FT_Bitmap source_bitmap; + const FT_Bitmap* source; + + FT_Vector source_offset; + FT_Vector target_offset; + + FT_Bool free_source_bitmap = 0; + FT_Bool free_target_bitmap_on_error = 0; + + FT_Pos source_llx, source_lly, source_urx, source_ury; + FT_Pos target_llx, target_lly, target_urx, target_ury; + FT_Pos final_llx, final_lly, final_urx, final_ury; + + unsigned int final_rows, final_width; + long x, y; + + + if ( !library || !target || !source_ || !atarget_offset ) + return FT_THROW( Invalid_Argument ); + + memory = library->memory; + + if ( !( target->pixel_mode == FT_PIXEL_MODE_NONE || + ( target->pixel_mode == FT_PIXEL_MODE_BGRA && + target->buffer ) ) ) + return FT_THROW( Invalid_Argument ); + + if ( source_->pixel_mode == FT_PIXEL_MODE_NONE ) + return FT_Err_Ok; /* nothing to do */ + + /* pitches must have the same sign */ + if ( target->pixel_mode == FT_PIXEL_MODE_BGRA && + ( source_->pitch ^ target->pitch ) < 0 ) + return FT_THROW( Invalid_Argument ); + + if ( !( source_->width && source_->rows ) ) + return FT_Err_Ok; /* nothing to do */ + + /* assure integer pixel offsets */ + source_offset.x = FT_PIX_FLOOR( source_offset_.x ); + source_offset.y = FT_PIX_FLOOR( source_offset_.y ); + target_offset.x = FT_PIX_FLOOR( atarget_offset->x ); + target_offset.y = FT_PIX_FLOOR( atarget_offset->y ); + + /* get source bitmap dimensions */ + source_llx = source_offset.x; + if ( FT_LONG_MIN + (FT_Pos)( source_->rows << 6 ) + 64 > source_offset.y ) + { + FT_TRACE5(( + "FT_Bitmap_Blend: y coordinate overflow in source bitmap\n" )); + return FT_THROW( Invalid_Argument ); + } + source_lly = source_offset.y - ( source_->rows << 6 ); + + if ( FT_LONG_MAX - (FT_Pos)( source_->width << 6 ) - 64 < source_llx ) + { + FT_TRACE5(( + "FT_Bitmap_Blend: x coordinate overflow in source bitmap\n" )); + return FT_THROW( Invalid_Argument ); + } + source_urx = source_llx + ( source_->width << 6 ); + source_ury = source_offset.y; + + /* get target bitmap dimensions */ + if ( target->width && target->rows ) + { + target_llx = target_offset.x; + if ( FT_LONG_MIN + (FT_Pos)( target->rows << 6 ) > target_offset.y ) + { + FT_TRACE5(( + "FT_Bitmap_Blend: y coordinate overflow in target bitmap\n" )); + return FT_THROW( Invalid_Argument ); + } + target_lly = target_offset.y - ( target->rows << 6 ); + + if ( FT_LONG_MAX - (FT_Pos)( target->width << 6 ) < target_llx ) + { + FT_TRACE5(( + "FT_Bitmap_Blend: x coordinate overflow in target bitmap\n" )); + return FT_THROW( Invalid_Argument ); + } + target_urx = target_llx + ( target->width << 6 ); + target_ury = target_offset.y; + } + else + { + target_llx = FT_LONG_MAX; + target_lly = FT_LONG_MAX; + target_urx = FT_LONG_MIN; + target_ury = FT_LONG_MIN; + } + + /* compute final bitmap dimensions */ + final_llx = FT_MIN( source_llx, target_llx ); + final_lly = FT_MIN( source_lly, target_lly ); + final_urx = FT_MAX( source_urx, target_urx ); + final_ury = FT_MAX( source_ury, target_ury ); + + final_width = ( final_urx - final_llx ) >> 6; + final_rows = ( final_ury - final_lly ) >> 6; + +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE5(( "FT_Bitmap_Blend:\n" + " source bitmap: (%d, %d) -- (%d, %d); %d x %d\n", + source_llx / 64, source_lly / 64, + source_urx / 64, source_ury / 64, + source_->width, source_->rows )); + + if ( target->width && target->rows ) + FT_TRACE5(( " target bitmap: (%d, %d) -- (%d, %d); %d x %d\n", + target_llx / 64, target_lly / 64, + target_urx / 64, target_ury / 64, + target->width, target->rows )); + else + FT_TRACE5(( " target bitmap: empty\n" )); + + FT_TRACE5(( " final bitmap: (%d, %d) -- (%d, %d); %d x %d\n", + final_llx / 64, final_lly / 64, + final_urx / 64, final_ury / 64, + final_width, final_rows )); +#endif /* FT_DEBUG_LEVEL_TRACE */ + + /* for blending, set offset vector of final bitmap */ + /* temporarily to (0,0) */ + source_llx -= final_llx; + source_lly -= final_lly; + + if ( target->width && target->rows ) + { + target_llx -= final_llx; + target_lly -= final_lly; + } + + /* set up target bitmap */ + if ( target->pixel_mode == FT_PIXEL_MODE_NONE ) + { + /* create new empty bitmap */ + target->width = final_width; + target->rows = final_rows; + target->pixel_mode = FT_PIXEL_MODE_BGRA; + target->pitch = (int)final_width * 4; + target->num_grays = 256; + + if ( FT_LONG_MAX / target->pitch < (int)target->rows ) + { + FT_TRACE5(( "FT_Blend_Bitmap: target bitmap too large (%d x %d)\n", + final_width, final_rows )); + return FT_THROW( Invalid_Argument ); + } + + if ( FT_ALLOC( target->buffer, target->pitch * (int)target->rows ) ) + return error; + + free_target_bitmap_on_error = 1; + } + else if ( target->width != final_width || + target->rows != final_rows ) + { + /* adjust old bitmap to enlarged size */ + int pitch, new_pitch; + + unsigned char* buffer = NULL; + + + pitch = target->pitch; + if ( pitch < 0 ) + pitch = -pitch; + + new_pitch = (int)final_width * 4; + + if ( FT_LONG_MAX / new_pitch < (int)final_rows ) + { + FT_TRACE5(( "FT_Blend_Bitmap: target bitmap too large (%d x %d)\n", + final_width, final_rows )); + return FT_THROW( Invalid_Argument ); + } + + /* TODO: provide an in-buffer solution for large bitmaps */ + /* to avoid allocation of a new buffer */ + if ( FT_ALLOC( buffer, new_pitch * (int)final_rows ) ) + goto Error; + + /* copy data to new buffer */ + x = target_llx >> 6; + y = target_lly >> 6; + + /* the bitmap flow is from top to bottom, */ + /* but y is measured from bottom to top */ + if ( target->pitch < 0 ) + { + /* XXX */ + } + else + { + unsigned char* p = + target->buffer; + unsigned char* q = + buffer + + ( final_rows - y - target->rows ) * new_pitch + + x * 4; + unsigned char* limit_p = + p + pitch * (int)target->rows; + + + while ( p < limit_p ) + { + FT_MEM_COPY( q, p, pitch ); + + p += pitch; + q += new_pitch; + } + } + + FT_FREE( target->buffer ); + + target->width = final_width; + target->rows = final_rows; + + if ( target->pitch < 0 ) + target->pitch = -new_pitch; + else + target->pitch = new_pitch; + + target->buffer = buffer; + } + + /* adjust source bitmap if necessary */ + if ( source_->pixel_mode != FT_PIXEL_MODE_GRAY ) + { + FT_Bitmap_Init( &source_bitmap ); + error = FT_Bitmap_Convert( library, source_, &source_bitmap, 1 ); + if ( error ) + goto Error; + + source = &source_bitmap; + free_source_bitmap = 1; + } + else + source = source_; + + /* do blending; the code below returns pre-multiplied channels, */ + /* similar to what FreeType gets from `CBDT' tables */ + x = source_llx >> 6; + y = source_lly >> 6; + + /* the bitmap flow is from top to bottom, */ + /* but y is measured from bottom to top */ + if ( target->pitch < 0 ) + { + /* XXX */ + } + else + { + unsigned char* p = + source->buffer; + unsigned char* q = + target->buffer + + ( target->rows - y - source->rows ) * target->pitch + + x * 4; + unsigned char* limit_p = + p + source->pitch * (int)source->rows; + + + while ( p < limit_p ) + { + unsigned char* r = p; + unsigned char* s = q; + unsigned char* limit_r = r + source->width; + + + while ( r < limit_r ) + { + int aa = *r++; + int fa = color.alpha * aa / 255; + + int fb = color.blue * fa / 255; + int fg = color.green * fa / 255; + int fr = color.red * fa / 255; + + int ba2 = 255 - fa; + + int bb = s[0]; + int bg = s[1]; + int br = s[2]; + int ba = s[3]; + + + *s++ = (unsigned char)( bb * ba2 / 255 + fb ); + *s++ = (unsigned char)( bg * ba2 / 255 + fg ); + *s++ = (unsigned char)( br * ba2 / 255 + fr ); + *s++ = (unsigned char)( ba * ba2 / 255 + fa ); + } + + p += source->pitch; + q += target->pitch; + } + } + + atarget_offset->x = final_llx; + atarget_offset->y = final_lly + ( final_rows << 6 ); + + Error: + if ( error && free_target_bitmap_on_error ) + FT_Bitmap_Done( library, target ); + + if ( free_source_bitmap ) + FT_Bitmap_Done( library, &source_bitmap ); + + return error; + } + /* documentation is in ftbitmap.h */ diff --git a/sdk/lib/3rdparty/freetype/src/base/ftcalc.c b/sdk/lib/3rdparty/freetype/src/base/ftcalc.c index f4ff45f8ef17b..315dc441856ce 100644 --- a/sdk/lib/3rdparty/freetype/src/base/ftcalc.c +++ b/sdk/lib/3rdparty/freetype/src/base/ftcalc.c @@ -1,35 +1,35 @@ -/***************************************************************************/ -/* */ -/* ftcalc.c */ -/* */ -/* Arithmetic computations (body). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - /*************************************************************************/ - /* */ - /* Support for 1-complement arithmetic has been totally dropped in this */ - /* release. You can still write your own code if you need it. */ - /* */ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* Implementing basic computation routines. */ - /* */ - /* FT_MulDiv(), FT_MulFix(), FT_DivFix(), FT_RoundFix(), FT_CeilFix(), */ - /* and FT_FloorFix() are declared in freetype.h. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * ftcalc.c + * + * Arithmetic computations (body). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + /************************************************************************** + * + * Support for 1-complement arithmetic has been totally dropped in this + * release. You can still write your own code if you need it. + * + */ + + /************************************************************************** + * + * Implementing basic computation routines. + * + * FT_MulDiv(), FT_MulFix(), FT_DivFix(), FT_RoundFix(), FT_CeilFix(), + * and FT_FloorFix() are declared in freetype.h. + * + */ #include <ft2build.h> @@ -58,14 +58,14 @@ #endif /* !FT_LONG64 */ - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_calc +#define FT_COMPONENT calc /* transfer sign, leaving a positive number; */ @@ -516,10 +516,10 @@ #elif 0 /* - * This code is nonportable. See comment below. + * This code is nonportable. See comment below. * - * However, on a platform where right-shift of a signed quantity fills - * the leftmost bits by copying the sign bit, it might be faster. + * However, on a platform where right-shift of a signed quantity fills + * the leftmost bits by copying the sign bit, it might be faster. */ FT_Long sa, sb; @@ -527,22 +527,22 @@ /* - * This is a clever way of converting a signed number `a' into its - * absolute value (stored back into `a') and its sign. The sign is - * stored in `sa'; 0 means `a' was positive or zero, and -1 means `a' - * was negative. (Similarly for `b' and `sb'). + * This is a clever way of converting a signed number `a' into its + * absolute value (stored back into `a') and its sign. The sign is + * stored in `sa'; 0 means `a' was positive or zero, and -1 means `a' + * was negative. (Similarly for `b' and `sb'). * - * Unfortunately, it doesn't work (at least not portably). + * Unfortunately, it doesn't work (at least not portably). * - * It makes the assumption that right-shift on a negative signed value - * fills the leftmost bits by copying the sign bit. This is wrong. - * According to K&R 2nd ed, section `A7.8 Shift Operators' on page 206, - * the result of right-shift of a negative signed value is - * implementation-defined. At least one implementation fills the - * leftmost bits with 0s (i.e., it is exactly the same as an unsigned - * right shift). This means that when `a' is negative, `sa' ends up - * with the value 1 rather than -1. After that, everything else goes - * wrong. + * It makes the assumption that right-shift on a negative signed value + * fills the leftmost bits by copying the sign bit. This is wrong. + * According to K&R 2nd ed, section `A7.8 Shift Operators' on page 206, + * the result of right-shift of a negative signed value is + * implementation-defined. At least one implementation fills the + * leftmost bits with 0s (i.e., it is exactly the same as an unsigned + * right shift). This means that when `a' is negative, `sa' ends up + * with the value 1 rather than -1. After that, everything else goes + * wrong. */ sa = ( a_ >> ( sizeof ( a_ ) * 8 - 1 ) ); a = ( a_ ^ sa ) - sa; @@ -701,8 +701,8 @@ if ( !delta ) return FT_THROW( Invalid_Argument ); /* matrix can't be inverted */ - matrix->xy = - FT_DivFix( matrix->xy, delta ); - matrix->yx = - FT_DivFix( matrix->yx, delta ); + matrix->xy = -FT_DivFix( matrix->xy, delta ); + matrix->yx = -FT_DivFix( matrix->yx, delta ); xx = matrix->xx; yy = matrix->yy; @@ -745,6 +745,76 @@ } + /* documentation is in ftcalc.h */ + + FT_BASE_DEF( FT_Bool ) + FT_Matrix_Check( const FT_Matrix* matrix ) + { + FT_Matrix m; + FT_Fixed val[4]; + FT_Fixed nonzero_minval, maxval; + FT_Fixed temp1, temp2; + FT_UInt i; + + + if ( !matrix ) + return 0; + + val[0] = FT_ABS( matrix->xx ); + val[1] = FT_ABS( matrix->xy ); + val[2] = FT_ABS( matrix->yx ); + val[3] = FT_ABS( matrix->yy ); + + /* + * To avoid overflow, we ensure that each value is not larger than + * + * int(sqrt(2^31 / 4)) = 23170 ; + * + * we also check that no value becomes zero if we have to scale. + */ + + maxval = 0; + nonzero_minval = FT_LONG_MAX; + + for ( i = 0; i < 4; i++ ) + { + if ( val[i] > maxval ) + maxval = val[i]; + if ( val[i] && val[i] < nonzero_minval ) + nonzero_minval = val[i]; + } + + /* we only handle 32bit values */ + if ( maxval > 0x7FFFFFFFL ) + return 0; + + if ( maxval > 23170 ) + { + FT_Fixed scale = FT_DivFix( maxval, 23170 ); + + + if ( !FT_DivFix( nonzero_minval, scale ) ) + return 0; /* value range too large */ + + m.xx = FT_DivFix( matrix->xx, scale ); + m.xy = FT_DivFix( matrix->xy, scale ); + m.yx = FT_DivFix( matrix->yx, scale ); + m.yy = FT_DivFix( matrix->yy, scale ); + } + else + m = *matrix; + + temp1 = FT_ABS( m.xx * m.yy - m.xy * m.yx ); + temp2 = m.xx * m.xx + m.xy * m.xy + m.yx * m.yx + m.yy * m.yy; + + if ( temp1 == 0 || + temp2 / temp1 > 50 ) + return 0; + + return 1; + } + + /* documentation is in ftcalc.h */ FT_BASE_DEF( void ) @@ -913,9 +983,13 @@ FT_Pos out_x, FT_Pos out_y ) { + /* we silently ignore overflow errors since such large values */ + /* lead to even more (harmless) rendering errors later on */ + #ifdef FT_LONG64 - FT_Int64 delta = (FT_Int64)in_x * out_y - (FT_Int64)in_y * out_x; + FT_Int64 delta = SUB_INT64( MUL_INT64( in_x, out_y ), + MUL_INT64( in_y, out_x ) ); return ( delta > 0 ) - ( delta < 0 ); @@ -925,8 +999,6 @@ FT_Int result; - /* we silently ignore overflow errors, since such large values */ - /* lead to even more (harmless) rendering errors later on */ if ( ADD_LONG( FT_ABS( in_x ), FT_ABS( out_y ) ) <= 131071L && ADD_LONG( FT_ABS( in_y ), FT_ABS( out_x ) ) <= 131071L ) { diff --git a/sdk/lib/3rdparty/freetype/src/base/ftcid.c b/sdk/lib/3rdparty/freetype/src/base/ftcid.c index f5184649bfb37..190b23f3571fe 100644 --- a/sdk/lib/3rdparty/freetype/src/base/ftcid.c +++ b/sdk/lib/3rdparty/freetype/src/base/ftcid.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftcid.c */ -/* */ -/* FreeType API for accessing CID font information. */ -/* */ -/* Copyright 2007-2018 by */ -/* Derek Clegg and Michael Toftdal. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftcid.c + * + * FreeType API for accessing CID font information. + * + * Copyright (C) 2007-2019 by + * Derek Clegg and Michael Toftdal. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> diff --git a/sdk/lib/3rdparty/freetype/src/base/ftcolor.c b/sdk/lib/3rdparty/freetype/src/base/ftcolor.c new file mode 100644 index 0000000000000..8cb057a36550e --- /dev/null +++ b/sdk/lib/3rdparty/freetype/src/base/ftcolor.c @@ -0,0 +1,157 @@ +/**************************************************************************** + * + * ftcolor.c + * + * FreeType's glyph color management (body). + * + * Copyright (C) 2018-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_SFNT_H +#include FT_INTERNAL_TRUETYPE_TYPES_H +#include FT_COLOR_H + + +#ifdef TT_CONFIG_OPTION_COLOR_LAYERS + + static + const FT_Palette_Data null_palette_data = { 0, NULL, NULL, 0, NULL }; + + + /* documentation is in ftcolor.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Palette_Data_Get( FT_Face face, + FT_Palette_Data *apalette_data ) + { + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); + if ( !apalette_data) + return FT_THROW( Invalid_Argument ); + + if ( FT_IS_SFNT( face ) ) + *apalette_data = ( (TT_Face)face )->palette_data; + else + *apalette_data = null_palette_data; + + return FT_Err_Ok; + } + + + /* documentation is in ftcolor.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Palette_Select( FT_Face face, + FT_UShort palette_index, + FT_Color* *apalette ) + { + FT_Error error; + + TT_Face ttface; + SFNT_Service sfnt; + + + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); + + if ( !FT_IS_SFNT( face ) ) + { + if ( apalette ) + *apalette = NULL; + + return FT_Err_Ok; + } + + ttface = (TT_Face)face; + sfnt = (SFNT_Service)ttface->sfnt; + + error = sfnt->set_palette( ttface, palette_index ); + if ( error ) + return error; + + ttface->palette_index = palette_index; + + if ( apalette ) + *apalette = ttface->palette; + + return FT_Err_Ok; + } + + + /* documentation is in ftcolor.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Palette_Set_Foreground_Color( FT_Face face, + FT_Color foreground_color ) + { + TT_Face ttface; + + + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); + + if ( !FT_IS_SFNT( face ) ) + return FT_Err_Ok; + + ttface = (TT_Face)face; + + ttface->foreground_color = foreground_color; + ttface->have_foreground_color = 1; + + return FT_Err_Ok; + } + +#else /* !TT_CONFIG_OPTION_COLOR_LAYERS */ + + FT_EXPORT_DEF( FT_Error ) + FT_Palette_Data_Get( FT_Face face, + FT_Palette_Data *apalette_data ) + { + FT_UNUSED( face ); + FT_UNUSED( apalette_data ); + + + return FT_THROW( Unimplemented_Feature ); + } + + + FT_EXPORT_DEF( FT_Error ) + FT_Palette_Select( FT_Face face, + FT_UShort palette_index, + FT_Color* *apalette ) + { + FT_UNUSED( face ); + FT_UNUSED( palette_index ); + FT_UNUSED( apalette ); + + + return FT_THROW( Unimplemented_Feature ); + } + + + FT_EXPORT_DEF( FT_Error ) + FT_Palette_Set_Foreground_Color( FT_Face face, + FT_Color foreground_color ) + { + FT_UNUSED( face ); + FT_UNUSED( foreground_color ); + + + return FT_THROW( Unimplemented_Feature ); + } + +#endif /* !TT_CONFIG_OPTION_COLOR_LAYERS */ + + +/* END */ diff --git a/sdk/lib/3rdparty/freetype/src/base/ftdbgmem.c b/sdk/lib/3rdparty/freetype/src/base/ftdbgmem.c index c33d8acb4e1fc..55cd269e1fe0a 100644 --- a/sdk/lib/3rdparty/freetype/src/base/ftdbgmem.c +++ b/sdk/lib/3rdparty/freetype/src/base/ftdbgmem.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftdbgmem.c */ -/* */ -/* Memory debugger (body). */ -/* */ -/* Copyright 2001-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftdbgmem.c + * + * Memory debugger (body). + * + * Copyright (C) 2001-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -50,9 +50,9 @@ #define FT_MEM_VAL( addr ) ( (FT_PtrDist)(FT_Pointer)( addr ) ) /* - * This structure holds statistics for a single allocation/release - * site. This is useful to know where memory operations happen the - * most. + * This structure holds statistics for a single allocation/release + * site. This is useful to know where memory operations happen the + * most. */ typedef struct FT_MemSourceRec_ { @@ -76,17 +76,17 @@ /* - * We don't need a resizable array for the memory sources because - * their number is pretty limited within FreeType. + * We don't need a resizable array for the memory sources because + * their number is pretty limited within FreeType. */ #define FT_MEM_SOURCE_BUCKETS 128 /* - * This structure holds information related to a single allocated - * memory block. If KEEPALIVE is defined, blocks that are freed by - * FreeType are never released to the system. Instead, their `size' - * field is set to `-size'. This is mainly useful to detect double - * frees, at the price of a large memory footprint during execution. + * This structure holds information related to a single allocated + * memory block. If KEEPALIVE is defined, blocks that are freed by + * FreeType are never released to the system. Instead, their `size' + * field is set to `-size'. This is mainly useful to detect double + * frees, at the price of a large memory footprint during execution. */ typedef struct FT_MemNodeRec_ { @@ -106,8 +106,8 @@ /* - * The global structure, containing compound statistics and all hash - * tables. + * The global structure, containing compound statistics and all hash + * tables. */ typedef struct FT_MemTableRec_ { @@ -146,8 +146,8 @@ /* - * Prime numbers are ugly to handle. It would be better to implement - * L-Hashing, which is 10% faster and doesn't require divisions. + * Prime numbers are ugly to handle. It would be better to implement + * L-Hashing, which is 10% faster and doesn't require divisions. */ static const FT_Int ft_mem_primes[] = { diff --git a/sdk/lib/3rdparty/freetype/src/base/ftdebug.c b/sdk/lib/3rdparty/freetype/src/base/ftdebug.c index fe26309101459..15dd7c72cd3e5 100644 --- a/sdk/lib/3rdparty/freetype/src/base/ftdebug.c +++ b/sdk/lib/3rdparty/freetype/src/base/ftdebug.c @@ -1,44 +1,44 @@ -/***************************************************************************/ -/* */ -/* ftdebug.c */ -/* */ -/* Debugging and logging component (body). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This component contains various macros and functions used to ease the */ - /* debugging of the FreeType engine. Its main purpose is in assertion */ - /* checking, tracing, and error detection. */ - /* */ - /* There are now three debugging modes: */ - /* */ - /* - trace mode */ - /* */ - /* Error and trace messages are sent to the log file (which can be the */ - /* standard error output). */ - /* */ - /* - error mode */ - /* */ - /* Only error messages are generated. */ - /* */ - /* - release mode: */ - /* */ - /* No error message is sent or generated. The code is free from any */ - /* debugging parts. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * ftdebug.c + * + * Debugging and logging component (body). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /************************************************************************** + * + * This component contains various macros and functions used to ease the + * debugging of the FreeType engine. Its main purpose is in assertion + * checking, tracing, and error detection. + * + * There are now three debugging modes: + * + * - trace mode + * + * Error and trace messages are sent to the log file (which can be the + * standard error output). + * + * - error mode + * + * Only error messages are generated. + * + * - release mode: + * + * No error message is sent or generated. The code is free from any + * debugging parts. + * + */ #include <ft2build.h> @@ -50,6 +50,7 @@ /* documentation is in ftdebug.h */ +#ifndef __REACTOS__ /* win32ss/drivers/font/ftfd/rosglue.c defines this */ FT_BASE_DEF( void ) FT_Message( const char* fmt, ... ) @@ -61,10 +62,12 @@ vfprintf( stderr, fmt, ap ); va_end( ap ); } +#endif /* documentation is in ftdebug.h */ +#ifndef __REACTOS__ /* win32ss/drivers/font/ftfd/rosglue.c defines this */ FT_BASE_DEF( void ) FT_Panic( const char* fmt, ... ) @@ -78,6 +81,7 @@ exit( EXIT_FAILURE ); } +#endif /* documentation is in ftdebug.h */ @@ -87,9 +91,19 @@ int line, const char* file ) { +#if 0 + /* activating the code in this block makes FreeType very chatty */ + fprintf( stderr, + "%s:%d: error 0x%02x: %s\n", + file, + line, + error, + FT_Error_String( error ) ); +#else FT_UNUSED( error ); FT_UNUSED( line ); FT_UNUSED( file ); +#endif return 0; } @@ -100,9 +114,16 @@ #ifdef FT_DEBUG_LEVEL_TRACE - /* array of trace levels, initialized to 0 */ - int ft_trace_levels[trace_count]; + /* array of trace levels, initialized to 0; */ + /* this gets adjusted at run-time */ + static int ft_trace_levels_enabled[trace_count]; + /* array of trace levels, always initialized to 0 */ + static int ft_trace_levels_disabled[trace_count]; + + /* a pointer to either `ft_trace_levels_enabled' */ + /* or `ft_trace_levels_disabled' */ + int* ft_trace_levels; /* define array of trace toggle names */ #define FT_TRACE_DEF( x ) #x , @@ -140,24 +161,42 @@ } - /*************************************************************************/ - /* */ - /* Initialize the tracing sub-system. This is done by retrieving the */ - /* value of the `FT2_DEBUG' environment variable. It must be a list of */ - /* toggles, separated by spaces, `;', or `,'. Example: */ - /* */ - /* export FT2_DEBUG="any:3 memory:7 stream:5" */ - /* */ - /* This requests that all levels be set to 3, except the trace level for */ - /* the memory and stream components which are set to 7 and 5, */ - /* respectively. */ - /* */ - /* See the file `include/freetype/internal/fttrace.h' for details of */ - /* the available toggle names. */ - /* */ - /* The level must be between 0 and 7; 0 means quiet (except for serious */ - /* runtime errors), and 7 means _very_ verbose. */ - /* */ + /* documentation is in ftdebug.h */ + + FT_BASE_DEF( void ) + FT_Trace_Disable( void ) + { + ft_trace_levels = ft_trace_levels_disabled; + } + + + /* documentation is in ftdebug.h */ + + FT_BASE_DEF( void ) + FT_Trace_Enable( void ) + { + ft_trace_levels = ft_trace_levels_enabled; + } + + + /************************************************************************** + * + * Initialize the tracing sub-system. This is done by retrieving the + * value of the `FT2_DEBUG' environment variable. It must be a list of + * toggles, separated by spaces, `;', or `,'. Example: + * + * export FT2_DEBUG="any:3 memory:7 stream:5" + * + * This requests that all levels be set to 3, except the trace level for + * the memory and stream components which are set to 7 and 5, + * respectively. + * + * See the file `include/freetype/internal/fttrace.h' for details of + * the available toggle names. + * + * The level must be between 0 and 7; 0 means quiet (except for serious + * runtime errors), and 7 means _very_ verbose. + */ FT_BASE_DEF( void ) ft_debug_init( void ) { @@ -223,14 +262,16 @@ { /* special case for `any' */ for ( n = 0; n < trace_count; n++ ) - ft_trace_levels[n] = level; + ft_trace_levels_enabled[n] = level; } else - ft_trace_levels[found] = level; + ft_trace_levels_enabled[found] = level; } } } } + + ft_trace_levels = ft_trace_levels_enabled; } @@ -260,6 +301,22 @@ } + FT_BASE_DEF( void ) + FT_Trace_Disable( void ) + { + /* nothing */ + } + + + /* documentation is in ftdebug.h */ + + FT_BASE_DEF( void ) + FT_Trace_Enable( void ) + { + /* nothing */ + } + + #endif /* !FT_DEBUG_LEVEL_TRACE */ diff --git a/sdk/lib/3rdparty/freetype/src/base/fterrors.c b/sdk/lib/3rdparty/freetype/src/base/fterrors.c new file mode 100644 index 0000000000000..4ef326d8e28ad --- /dev/null +++ b/sdk/lib/3rdparty/freetype/src/base/fterrors.c @@ -0,0 +1,45 @@ +/**************************************************************************** + * + * fterrors.c + * + * FreeType API for error code handling. + * + * Copyright (C) 2018-2019 by + * Armin Hasitzka, David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + +#include <ft2build.h> +#include FT_ERRORS_H + + + /* documentation is in fterrors.h */ + + FT_EXPORT_DEF( const char* ) + FT_Error_String( FT_Error error_code ) + { + if ( error_code < 0 || + error_code >= FT_ERR_CAT( FT_ERR_PREFIX, Max ) ) + return NULL; + +#if defined( FT_CONFIG_OPTION_ERROR_STRINGS ) || \ + defined( FT_DEBUG_LEVEL_ERROR ) + +#undef FTERRORS_H_ +#define FT_ERROR_START_LIST switch ( FT_ERROR_BASE( error_code ) ) { +#define FT_ERRORDEF( e, v, s ) case v: return s; +#define FT_ERROR_END_LIST } + +#include FT_ERRORS_H + +#endif /* defined( FT_CONFIG_OPTION_ERROR_STRINGS ) || ... */ + + return NULL; + } diff --git a/sdk/lib/3rdparty/freetype/src/base/ftfntfmt.c b/sdk/lib/3rdparty/freetype/src/base/ftfntfmt.c index a2900ceb098f1..54ba537416488 100644 --- a/sdk/lib/3rdparty/freetype/src/base/ftfntfmt.c +++ b/sdk/lib/3rdparty/freetype/src/base/ftfntfmt.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftfntfmt.c */ -/* */ -/* FreeType utility file for font formats (body). */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftfntfmt.c + * + * FreeType utility file for font formats (body). + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> diff --git a/sdk/lib/3rdparty/freetype/src/base/ftfstype.c b/sdk/lib/3rdparty/freetype/src/base/ftfstype.c index e6cdf6e2ec681..45e2d8089bfe7 100644 --- a/sdk/lib/3rdparty/freetype/src/base/ftfstype.c +++ b/sdk/lib/3rdparty/freetype/src/base/ftfstype.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftfstype.c */ -/* */ -/* FreeType utility file to access FSType data (body). */ -/* */ -/* Copyright 2008-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftfstype.c + * + * FreeType utility file to access FSType data (body). + * + * Copyright (C) 2008-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> #include FT_TYPE1_TABLES_H diff --git a/sdk/lib/3rdparty/freetype/src/base/ftgasp.c b/sdk/lib/3rdparty/freetype/src/base/ftgasp.c index 4f80bba630cc4..720fb113ca32b 100644 --- a/sdk/lib/3rdparty/freetype/src/base/ftgasp.c +++ b/sdk/lib/3rdparty/freetype/src/base/ftgasp.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftgasp.c */ -/* */ -/* Access of TrueType's `gasp' table (body). */ -/* */ -/* Copyright 2007-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftgasp.c + * + * Access of TrueType's `gasp' table (body). + * + * Copyright (C) 2007-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> diff --git a/sdk/lib/3rdparty/freetype/src/base/ftgloadr.c b/sdk/lib/3rdparty/freetype/src/base/ftgloadr.c index 47202496b9c2d..bfeed461a8373 100644 --- a/sdk/lib/3rdparty/freetype/src/base/ftgloadr.c +++ b/sdk/lib/3rdparty/freetype/src/base/ftgloadr.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftgloadr.c */ -/* */ -/* The FreeType glyph loader (body). */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftgloadr.c + * + * The FreeType glyph loader (body). + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -23,7 +23,7 @@ #include FT_INTERNAL_OBJECTS_H #undef FT_COMPONENT -#define FT_COMPONENT trace_gloader +#define FT_COMPONENT gloader /*************************************************************************/ @@ -38,31 +38,31 @@ /*************************************************************************/ /*************************************************************************/ - /*************************************************************************/ - /* */ - /* The glyph loader is a simple object which is used to load a set of */ - /* glyphs easily. It is critical for the correct loading of composites. */ - /* */ - /* Ideally, one can see it as a stack of abstract `glyph' objects. */ - /* */ - /* loader.base Is really the bottom of the stack. It describes a */ - /* single glyph image made of the juxtaposition of */ - /* several glyphs (those `in the stack'). */ - /* */ - /* loader.current Describes the top of the stack, on which a new */ - /* glyph can be loaded. */ - /* */ - /* Rewind Clears the stack. */ - /* Prepare Set up `loader.current' for addition of a new glyph */ - /* image. */ - /* Add Add the `current' glyph image to the `base' one, */ - /* and prepare for another one. */ - /* */ - /* The glyph loader is now a base object. Each driver used to */ - /* re-implement it in one way or the other, which wasted code and */ - /* energy. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * The glyph loader is a simple object which is used to load a set of + * glyphs easily. It is critical for the correct loading of composites. + * + * Ideally, one can see it as a stack of abstract `glyph' objects. + * + * loader.base Is really the bottom of the stack. It describes a + * single glyph image made of the juxtaposition of + * several glyphs (those `in the stack'). + * + * loader.current Describes the top of the stack, on which a new + * glyph can be loaded. + * + * Rewind Clears the stack. + * Prepare Set up `loader.current' for addition of a new glyph + * image. + * Add Add the `current' glyph image to the `base' one, + * and prepare for another one. + * + * The glyph loader is now a base object. Each driver used to + * re-implement it in one way or the other, which wasted code and + * energy. + * + */ /* create a new glyph loader */ @@ -99,12 +99,12 @@ } - /* reset the glyph loader, frees all allocated tables */ - /* and starts from zero */ + /* reset glyph loader, free all allocated tables, */ + /* and start from zero */ FT_BASE_DEF( void ) FT_GlyphLoader_Reset( FT_GlyphLoader loader ) { - FT_Memory memory = loader->memory; + FT_Memory memory = loader->memory; FT_FREE( loader->base.outline.points ); @@ -129,7 +129,7 @@ { if ( loader ) { - FT_Memory memory = loader->memory; + FT_Memory memory = loader->memory; FT_GlyphLoader_Reset( loader ); @@ -361,46 +361,4 @@ } - FT_BASE_DEF( FT_Error ) - FT_GlyphLoader_CopyPoints( FT_GlyphLoader target, - FT_GlyphLoader source ) - { - FT_Error error; - FT_UInt num_points = (FT_UInt)source->base.outline.n_points; - FT_UInt num_contours = (FT_UInt)source->base.outline.n_contours; - - - error = FT_GlyphLoader_CheckPoints( target, num_points, num_contours ); - if ( !error ) - { - FT_Outline* out = &target->base.outline; - FT_Outline* in = &source->base.outline; - - - FT_ARRAY_COPY( out->points, in->points, - num_points ); - FT_ARRAY_COPY( out->tags, in->tags, - num_points ); - FT_ARRAY_COPY( out->contours, in->contours, - num_contours ); - - /* do we need to copy the extra points? */ - if ( target->use_extra && source->use_extra ) - { - FT_ARRAY_COPY( target->base.extra_points, source->base.extra_points, - num_points ); - FT_ARRAY_COPY( target->base.extra_points2, source->base.extra_points2, - num_points ); - } - - out->n_points = (short)num_points; - out->n_contours = (short)num_contours; - - FT_GlyphLoader_Adjust_Points( target ); - } - - return error; - } - - /* END */ diff --git a/sdk/lib/3rdparty/freetype/src/base/ftglyph.c b/sdk/lib/3rdparty/freetype/src/base/ftglyph.c index 6759aa25d0e3e..e6b13279015db 100644 --- a/sdk/lib/3rdparty/freetype/src/base/ftglyph.c +++ b/sdk/lib/3rdparty/freetype/src/base/ftglyph.c @@ -1,31 +1,31 @@ -/***************************************************************************/ -/* */ -/* ftglyph.c */ -/* */ -/* FreeType convenience functions to handle glyphs (body). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - /*************************************************************************/ - /* */ - /* This file contains the definition of several convenience functions */ - /* that can be used by client applications to easily retrieve glyph */ - /* bitmaps and outlines from a given face. */ - /* */ - /* These functions should be optional if you are writing a font server */ - /* or text layout engine on top of FreeType. However, they are pretty */ - /* handy for many other simple uses of the library. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * ftglyph.c + * + * FreeType convenience functions to handle glyphs (body). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + /************************************************************************** + * + * This file contains the definition of several convenience functions + * that can be used by client applications to easily retrieve glyph + * bitmaps and outlines from a given face. + * + * These functions should be optional if you are writing a font server + * or text layout engine on top of FreeType. However, they are pretty + * handy for many other simple uses of the library. + * + */ #include <ft2build.h> @@ -36,16 +36,15 @@ #include FT_BITMAP_H #include FT_INTERNAL_OBJECTS_H -#include "basepic.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_glyph +#define FT_COMPONENT glyph /*************************************************************************/ @@ -77,7 +76,7 @@ /* do lazy copying whenever possible */ if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) { - glyph->bitmap = slot->bitmap; + glyph->bitmap = slot->bitmap; slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; } else @@ -359,37 +358,28 @@ /* documentation is in ftglyph.h */ - FT_EXPORT_DEF( FT_Error ) - FT_Get_Glyph( FT_GlyphSlot slot, - FT_Glyph *aglyph ) + FT_EXPORT( FT_Error ) + FT_New_Glyph( FT_Library library, + FT_Glyph_Format format, + FT_Glyph *aglyph ) { - FT_Library library; - FT_Error error; - FT_Glyph glyph; - const FT_Glyph_Class* clazz = NULL; - - if ( !slot ) - return FT_THROW( Invalid_Slot_Handle ); - - library = slot->library; - - if ( !aglyph ) + if ( !library || !aglyph ) return FT_THROW( Invalid_Argument ); /* if it is a bitmap, that's easy :-) */ - if ( slot->format == FT_GLYPH_FORMAT_BITMAP ) - clazz = FT_BITMAP_GLYPH_CLASS_GET; + if ( format == FT_GLYPH_FORMAT_BITMAP ) + clazz = &ft_bitmap_glyph_class; /* if it is an outline */ - else if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) - clazz = FT_OUTLINE_GLYPH_CLASS_GET; + else if ( format == FT_GLYPH_FORMAT_OUTLINE ) + clazz = &ft_outline_glyph_class; else { /* try to find a renderer that supports the glyph image format */ - FT_Renderer render = FT_Lookup_Renderer( library, slot->format, 0 ); + FT_Renderer render = FT_Lookup_Renderer( library, format, 0 ); if ( render ) @@ -397,13 +387,31 @@ } if ( !clazz ) - { - error = FT_THROW( Invalid_Glyph_Format ); - goto Exit; - } + return FT_THROW( Invalid_Glyph_Format ); + + /* create FT_Glyph object */ + return ft_new_glyph( library, clazz, aglyph ); + } + + + /* documentation is in ftglyph.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Glyph( FT_GlyphSlot slot, + FT_Glyph *aglyph ) + { + FT_Error error; + FT_Glyph glyph; + + + if ( !slot ) + return FT_THROW( Invalid_Slot_Handle ); + + if ( !aglyph ) + return FT_THROW( Invalid_Argument ); /* create FT_Glyph object */ - error = ft_new_glyph( library, clazz, &glyph ); + error = FT_New_Glyph( slot->library, slot->format, &glyph ); if ( error ) goto Exit; @@ -427,7 +435,7 @@ glyph->advance.y = slot->advance.y * 1024; /* now import the image from the glyph slot */ - error = clazz->glyph_init( glyph, slot ); + error = glyph->clazz->glyph_init( glyph, slot ); Exit2: /* if an error occurred, destroy the glyph */ @@ -505,8 +513,8 @@ { acbox->xMin = FT_PIX_FLOOR( acbox->xMin ); acbox->yMin = FT_PIX_FLOOR( acbox->yMin ); - acbox->xMax = FT_PIX_CEIL( acbox->xMax ); - acbox->yMax = FT_PIX_CEIL( acbox->yMax ); + acbox->xMax = FT_PIX_CEIL_LONG( acbox->xMax ); + acbox->yMax = FT_PIX_CEIL_LONG( acbox->yMax ); } /* convert to integer pixels if needed */ @@ -536,7 +544,6 @@ FT_BitmapGlyph bitmap = NULL; const FT_Glyph_Class* clazz; - /* FT_BITMAP_GLYPH_CLASS_GET dereferences `library' in PIC mode */ FT_Library library; @@ -553,7 +560,7 @@ goto Bad; /* when called with a bitmap glyph, do nothing and return successfully */ - if ( clazz == FT_BITMAP_GLYPH_CLASS_GET ) + if ( clazz == &ft_bitmap_glyph_class ) goto Exit; if ( !clazz->glyph_prepare ) @@ -569,7 +576,7 @@ dummy.format = clazz->glyph_format; /* create result bitmap glyph */ - error = ft_new_glyph( library, FT_BITMAP_GLYPH_CLASS_GET, &b ); + error = ft_new_glyph( library, &ft_bitmap_glyph_class, &b ); if ( error ) goto Exit; bitmap = (FT_BitmapGlyph)b; diff --git a/sdk/lib/3rdparty/freetype/src/base/ftgxval.c b/sdk/lib/3rdparty/freetype/src/base/ftgxval.c index 19e2d6acb5a66..0677d26faaaf0 100644 --- a/sdk/lib/3rdparty/freetype/src/base/ftgxval.c +++ b/sdk/lib/3rdparty/freetype/src/base/ftgxval.c @@ -1,28 +1,28 @@ -/***************************************************************************/ -/* */ -/* ftgxval.c */ -/* */ -/* FreeType API for validating TrueTypeGX/AAT tables (body). */ -/* */ -/* Copyright 2004-2018 by */ -/* Masatake YAMATO, Redhat K.K, */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftgxval.c + * + * FreeType API for validating TrueTypeGX/AAT tables (body). + * + * Copyright (C) 2004-2019 by + * Masatake YAMATO, Redhat K.K, + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + +/**************************************************************************** + * + * gxvalid is derived from both gxlayout module and otvalid module. + * Development of gxlayout is supported by the Information-technology + * Promotion Agency(IPA), Japan. + * + */ #include <ft2build.h> diff --git a/sdk/lib/3rdparty/freetype/src/base/fthash.c b/sdk/lib/3rdparty/freetype/src/base/fthash.c index 21bc8dd5b42e3..387e6d26db954 100644 --- a/sdk/lib/3rdparty/freetype/src/base/fthash.c +++ b/sdk/lib/3rdparty/freetype/src/base/fthash.c @@ -1,10 +1,10 @@ -/***************************************************************************/ -/* */ -/* fthash.c */ -/* */ -/* Hashing functions (body). */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * fthash.c + * + * Hashing functions (body). + * + */ /* * Copyright 2000 Computing Research Labs, New Mexico State University @@ -30,13 +30,13 @@ * THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - /*************************************************************************/ - /* */ - /* This file is based on code from bdf.c,v 1.22 2000/03/16 20:08:50 */ - /* */ - /* taken from Mark Leisher's xmbdfed package */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * This file is based on code from bdf.c,v 1.22 2000/03/16 20:08:50 + * + * taken from Mark Leisher's xmbdfed package + * + */ #include <ft2build.h> diff --git a/sdk/lib/3rdparty/freetype/src/base/ftinit.c b/sdk/lib/3rdparty/freetype/src/base/ftinit.c index 1fa4721094a10..9d524effa925a 100644 --- a/sdk/lib/3rdparty/freetype/src/base/ftinit.c +++ b/sdk/lib/3rdparty/freetype/src/base/ftinit.c @@ -1,40 +1,40 @@ -/***************************************************************************/ -/* */ -/* ftinit.c */ -/* */ -/* FreeType initialization layer (body). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - /*************************************************************************/ - /* */ - /* The purpose of this file is to implement the following two */ - /* functions: */ - /* */ - /* FT_Add_Default_Modules(): */ - /* This function is used to add the set of default modules to a */ - /* fresh new library object. The set is taken from the header file */ - /* `freetype/config/ftmodule.h'. See the document `FreeType 2.0 */ - /* Build System' for more information. */ - /* */ - /* FT_Init_FreeType(): */ - /* This function creates a system object for the current platform, */ - /* builds a library out of it, then calls FT_Default_Drivers(). */ - /* */ - /* Note that even if FT_Init_FreeType() uses the implementation of the */ - /* system object defined at build time, client applications are still */ - /* able to provide their own `ftsystem.c'. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * ftinit.c + * + * FreeType initialization layer (body). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + /************************************************************************** + * + * The purpose of this file is to implement the following two + * functions: + * + * FT_Add_Default_Modules(): + * This function is used to add the set of default modules to a + * fresh new library object. The set is taken from the header file + * `freetype/config/ftmodule.h'. See the document `FreeType 2.0 + * Build System' for more information. + * + * FT_Init_FreeType(): + * This function creates a system object for the current platform, + * builds a library out of it, then calls FT_Default_Drivers(). + * + * Note that even if FT_Init_FreeType() uses the implementation of the + * system object defined at build time, client applications are still + * able to provide their own `ftsystem.c'. + * + */ #include <ft2build.h> @@ -42,20 +42,16 @@ #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_DEBUG_H #include FT_MODULE_H -#include "basepic.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_init - - -#ifndef FT_CONFIG_OPTION_PIC +#define FT_COMPONENT init #undef FT_USE_MODULE @@ -78,120 +74,6 @@ }; -#else /* FT_CONFIG_OPTION_PIC */ - - -#ifdef __cplusplus -#define FT_EXTERNC extern "C" -#else -#define FT_EXTERNC extern -#endif - - /* declare the module's class creation/destruction functions */ -#undef FT_USE_MODULE -#define FT_USE_MODULE( type, x ) \ - FT_EXTERNC FT_Error \ - FT_Create_Class_ ## x( FT_Library library, \ - FT_Module_Class* *output_class ); \ - FT_EXTERNC void \ - FT_Destroy_Class_ ## x( FT_Library library, \ - FT_Module_Class* clazz ); - -#include FT_CONFIG_MODULES_H - - /* count all module classes */ -#undef FT_USE_MODULE -#define FT_USE_MODULE( type, x ) MODULE_CLASS_ ## x, - - enum - { -#include FT_CONFIG_MODULES_H - FT_NUM_MODULE_CLASSES - }; - - /* destroy all module classes */ -#undef FT_USE_MODULE -#define FT_USE_MODULE( type, x ) \ - if ( classes[i] ) \ - { \ - FT_Destroy_Class_ ## x( library, classes[i] ); \ - } \ - i++; - - - FT_BASE_DEF( void ) - ft_destroy_default_module_classes( FT_Library library ) - { - FT_Module_Class* *classes; - FT_Memory memory; - FT_UInt i; - BasePIC* pic_container = (BasePIC*)library->pic_container.base; - - - if ( !pic_container->default_module_classes ) - return; - - memory = library->memory; - classes = pic_container->default_module_classes; - i = 0; - -#include FT_CONFIG_MODULES_H - - FT_FREE( classes ); - pic_container->default_module_classes = NULL; - } - - - /* initialize all module classes and the pointer table */ -#undef FT_USE_MODULE -#define FT_USE_MODULE( type, x ) \ - error = FT_Create_Class_ ## x( library, &clazz ); \ - if ( error ) \ - goto Exit; \ - classes[i++] = clazz; - - - FT_BASE_DEF( FT_Error ) - ft_create_default_module_classes( FT_Library library ) - { - FT_Error error; - FT_Memory memory; - FT_Module_Class* *classes = NULL; - FT_Module_Class* clazz; - FT_UInt i; - BasePIC* pic_container = (BasePIC*)library->pic_container.base; - - - memory = library->memory; - - pic_container->default_module_classes = NULL; - - if ( FT_ALLOC( classes, sizeof ( FT_Module_Class* ) * - ( FT_NUM_MODULE_CLASSES + 1 ) ) ) - return error; - - /* initialize all pointers to 0, especially the last one */ - for ( i = 0; i < FT_NUM_MODULE_CLASSES; i++ ) - classes[i] = NULL; - classes[FT_NUM_MODULE_CLASSES] = NULL; - - i = 0; - -#include FT_CONFIG_MODULES_H - - Exit: - if ( error ) - ft_destroy_default_module_classes( library ); - else - pic_container->default_module_classes = classes; - - return error; - } - - -#endif /* FT_CONFIG_OPTION_PIC */ - - /* documentation is in ftmodapi.h */ FT_EXPORT_DEF( void ) @@ -201,16 +83,10 @@ const FT_Module_Class* const* cur; - /* FT_DEFAULT_MODULES_GET dereferences `library' in PIC mode */ -#ifdef FT_CONFIG_OPTION_PIC - if ( !library ) - return; -#endif - /* GCC 4.6 warns the type difference: * FT_Module_Class** != const FT_Module_Class* const* */ - cur = (const FT_Module_Class* const*)FT_DEFAULT_MODULES_GET; + cur = (const FT_Module_Class* const*)ft_default_modules; /* test for valid `library' delayed to FT_Add_Module() */ while ( *cur ) diff --git a/sdk/lib/3rdparty/freetype/src/base/ftlcdfil.c b/sdk/lib/3rdparty/freetype/src/base/ftlcdfil.c index 5c38911a907d0..9fb49ba116edf 100644 --- a/sdk/lib/3rdparty/freetype/src/base/ftlcdfil.c +++ b/sdk/lib/3rdparty/freetype/src/base/ftlcdfil.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftlcdfil.c */ -/* */ -/* FreeType API for color filtering of subpixel bitmap glyphs (body). */ -/* */ -/* Copyright 2006-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftlcdfil.c + * + * FreeType API for color filtering of subpixel bitmap glyphs (body). + * + * Copyright (C) 2006-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -34,9 +34,9 @@ /* add padding according to filter weights */ FT_BASE_DEF (void) - ft_lcd_padding( FT_Pos* Min, - FT_Pos* Max, - FT_GlyphSlot slot ) + ft_lcd_padding( FT_BBox* cbox, + FT_GlyphSlot slot, + FT_Render_Mode mode ) { FT_Byte* lcd_weights; FT_Bitmap_LcdFilterFunc lcd_filter_func; @@ -56,10 +56,20 @@ if ( lcd_filter_func == ft_lcd_filter_fir ) { - *Min -= lcd_weights[0] ? 43 : - lcd_weights[1] ? 22 : 0; - *Max += lcd_weights[4] ? 43 : - lcd_weights[3] ? 22 : 0; + if ( mode == FT_RENDER_MODE_LCD ) + { + cbox->xMin -= lcd_weights[0] ? 43 : + lcd_weights[1] ? 22 : 0; + cbox->xMax += lcd_weights[4] ? 43 : + lcd_weights[3] ? 22 : 0; + } + else if ( mode == FT_RENDER_MODE_LCD_V ) + { + cbox->yMin -= lcd_weights[0] ? 43 : + lcd_weights[1] ? 22 : 0; + cbox->yMax += lcd_weights[4] ? 43 : + lcd_weights[3] ? 22 : 0; + } } } @@ -77,7 +87,7 @@ /* take care of bitmap flow */ - if ( pitch > 0 ) + if ( pitch > 0 && height > 0 ) origin += pitch * (FT_Int)( height - 1 ); /* horizontal in-place FIR filter */ @@ -192,7 +202,7 @@ /* take care of bitmap flow */ - if ( pitch > 0 ) + if ( pitch > 0 && height > 0 ) origin += pitch * (FT_Int)( height - 1 ); /* horizontal in-place intra-pixel filter */ @@ -275,6 +285,8 @@ #endif /* USE_LEGACY */ + /* documentation in ftlcdfil.h */ + FT_EXPORT_DEF( FT_Error ) FT_Library_SetLcdFilterWeights( FT_Library library, unsigned char *weights ) @@ -292,6 +304,8 @@ } + /* documentation in ftlcdfil.h */ + FT_EXPORT_DEF( FT_Error ) FT_Library_SetLcdFilter( FT_Library library, FT_LcdFilter filter ) @@ -341,18 +355,41 @@ return FT_Err_Ok; } + + FT_EXPORT_DEF( FT_Error ) + FT_Library_SetLcdGeometry( FT_Library library, + FT_Vector* sub ) + { + FT_UNUSED( library ); + FT_UNUSED( sub ); + + return FT_THROW( Unimplemented_Feature ); + } + #else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ - /* add padding according to accommodate outline shifts */ + /* add padding to accommodate outline shifts */ FT_BASE_DEF (void) - ft_lcd_padding( FT_Pos* Min, - FT_Pos* Max, - FT_GlyphSlot slot ) + ft_lcd_padding( FT_BBox* cbox, + FT_GlyphSlot slot, + FT_Render_Mode mode ) { - FT_UNUSED( slot ); + FT_Vector* sub = slot->library->lcd_geometry; - *Min -= 21; - *Max += 21; + if ( mode == FT_RENDER_MODE_LCD ) + { + cbox->xMin -= FT_MAX( FT_MAX( sub[0].x, sub[1].x ), sub[2].x ); + cbox->xMax -= FT_MIN( FT_MIN( sub[0].x, sub[1].x ), sub[2].x ); + cbox->yMin -= FT_MAX( FT_MAX( sub[0].y, sub[1].y ), sub[2].y ); + cbox->yMax -= FT_MIN( FT_MIN( sub[0].y, sub[1].y ), sub[2].y ); + } + else if ( mode == FT_RENDER_MODE_LCD_V ) + { + cbox->xMin -= FT_MAX( FT_MAX( sub[0].y, sub[1].y ), sub[2].y ); + cbox->xMax -= FT_MIN( FT_MIN( sub[0].y, sub[1].y ), sub[2].y ); + cbox->yMin += FT_MIN( FT_MIN( sub[0].x, sub[1].x ), sub[2].x ); + cbox->yMax += FT_MAX( FT_MAX( sub[0].x, sub[1].x ), sub[2].x ); + } } @@ -377,6 +414,24 @@ return FT_THROW( Unimplemented_Feature ); } + + /* documentation in ftlcdfil.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Library_SetLcdGeometry( FT_Library library, + FT_Vector sub[3] ) + { + if ( !library ) + return FT_THROW( Invalid_Library_Handle ); + + if ( !sub ) + return FT_THROW( Invalid_Argument ); + + ft_memcpy( library->lcd_geometry, sub, 3 * sizeof( FT_Vector ) ); + + return FT_THROW( Unimplemented_Feature ); + } + #endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ diff --git a/sdk/lib/3rdparty/freetype/src/base/ftmac.c b/sdk/lib/3rdparty/freetype/src/base/ftmac.c index fd4c0cc274f1b..5f23ceea9f35e 100644 --- a/sdk/lib/3rdparty/freetype/src/base/ftmac.c +++ b/sdk/lib/3rdparty/freetype/src/base/ftmac.c @@ -1,23 +1,23 @@ -/***************************************************************************/ -/* */ -/* ftmac.c */ -/* */ -/* Mac FOND support. Written by just@letterror.com. */ -/* Heavily modified by mpsuzuki, George Williams, and Sean McBride. */ -/* */ -/* This file is for Mac OS X only; see builds/mac/ftoldmac.c for */ -/* classic platforms built by MPW. */ -/* */ -/* Copyright 1996-2018 by */ -/* Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftmac.c + * + * Mac FOND support. Written by just@letterror.com. + * Heavily modified by mpsuzuki, George Williams, and Sean McBride. + * + * This file is for Mac OS X only; see builds/mac/ftoldmac.c for + * classic platforms built by MPW. + * + * Copyright (C) 1996-2019 by + * Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ /* @@ -954,17 +954,17 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_New_Face */ - /* */ - /* <Description> */ - /* This is the Mac-specific implementation of FT_New_Face. In */ - /* addition to the standard FT_New_Face() functionality, it also */ - /* accepts pathnames to Mac suitcase files. For further */ - /* documentation see the original FT_New_Face() in freetype.h. */ - /* */ + /************************************************************************** + * + * @Function: + * FT_New_Face + * + * @Description: + * This is the Mac-specific implementation of FT_New_Face. In + * addition to the standard FT_New_Face() functionality, it also + * accepts pathnames to Mac suitcase files. For further + * documentation see the original FT_New_Face() in freetype.h. + */ FT_EXPORT_DEF( FT_Error ) FT_New_Face( FT_Library library, const char* pathname, @@ -995,17 +995,18 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_New_Face_From_FSRef */ - /* */ - /* <Description> */ - /* FT_New_Face_From_FSRef is identical to FT_New_Face except it */ - /* accepts an FSRef instead of a path. */ - /* */ - /* This function is deprecated because Carbon data types (FSRef) */ - /* are not cross-platform, and thus not suitable for the FreeType API. */ + /************************************************************************** + * + * @Function: + * FT_New_Face_From_FSRef + * + * @Description: + * FT_New_Face_From_FSRef is identical to FT_New_Face except it + * accepts an FSRef instead of a path. + * + * This function is deprecated because Carbon data types (FSRef) + * are not cross-platform, and thus not suitable for the FreeType API. + */ FT_EXPORT_DEF( FT_Error ) FT_New_Face_From_FSRef( FT_Library library, const FSRef* ref, @@ -1040,16 +1041,17 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_New_Face_From_FSSpec */ - /* */ - /* <Description> */ - /* FT_New_Face_From_FSSpec is identical to FT_New_Face except it */ - /* accepts an FSSpec instead of a path. */ - /* */ - /* This function is deprecated because FSSpec is deprecated in Mac OS X */ + /************************************************************************** + * + * @Function: + * FT_New_Face_From_FSSpec + * + * @Description: + * FT_New_Face_From_FSSpec is identical to FT_New_Face except it + * accepts an FSSpec instead of a path. + * + * This function is deprecated because FSSpec is deprecated in Mac OS X + */ FT_EXPORT_DEF( FT_Error ) FT_New_Face_From_FSSpec( FT_Library library, const FSSpec* spec, diff --git a/sdk/lib/3rdparty/freetype/src/base/ftmm.c b/sdk/lib/3rdparty/freetype/src/base/ftmm.c index 800441bcac862..ba9e67f008a5c 100644 --- a/sdk/lib/3rdparty/freetype/src/base/ftmm.c +++ b/sdk/lib/3rdparty/freetype/src/base/ftmm.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftmm.c */ -/* */ -/* Multiple Master font support (body). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftmm.c + * + * Multiple Master font support (body). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -25,14 +25,14 @@ #include FT_SERVICE_METRICS_VARIATIONS_H - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_mm +#define FT_COMPONENT mm static FT_Error @@ -199,6 +199,67 @@ } + /* documentation is in ftmm.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Set_MM_WeightVector( FT_Face face, + FT_UInt len, + FT_Fixed* weightvector ) + { + FT_Error error; + FT_Service_MultiMasters service; + + + /* check of `face' delayed to `ft_face_get_mm_service' */ + + if ( len && !weightvector ) + return FT_THROW( Invalid_Argument ); + + error = ft_face_get_mm_service( face, &service ); + if ( !error ) + { + error = FT_ERR( Invalid_Argument ); + if ( service->set_mm_weightvector ) + error = service->set_mm_weightvector( face, len, weightvector ); + } + + /* enforce recomputation of auto-hinting data */ + if ( !error && face->autohint.finalizer ) + { + face->autohint.finalizer( face->autohint.data ); + face->autohint.data = NULL; + } + + return error; + } + + + FT_EXPORT_DEF( FT_Error ) + FT_Get_MM_WeightVector( FT_Face face, + FT_UInt* len, + FT_Fixed* weightvector ) + { + FT_Error error; + FT_Service_MultiMasters service; + + + /* check of `face' delayed to `ft_face_get_mm_service' */ + + if ( len && !weightvector ) + return FT_THROW( Invalid_Argument ); + + error = ft_face_get_mm_service( face, &service ); + if ( !error ) + { + error = FT_ERR( Invalid_Argument ); + if ( service->get_mm_weightvector ) + error = service->get_mm_weightvector( face, len, weightvector ); + } + + return error; + } + + /* documentation is in ftmm.h */ FT_EXPORT_DEF( FT_Error ) diff --git a/sdk/lib/3rdparty/freetype/src/base/ftobjs.c b/sdk/lib/3rdparty/freetype/src/base/ftobjs.c index 8d07e35ae371b..3f8619d3b3cdc 100644 --- a/sdk/lib/3rdparty/freetype/src/base/ftobjs.c +++ b/sdk/lib/3rdparty/freetype/src/base/ftobjs.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftobjs.c */ -/* */ -/* The FreeType private base classes (body). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftobjs.c + * + * The FreeType private base classes (body). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -79,6 +79,18 @@ #pragma warning( pop ) #endif + static const char* const pixel_modes[] = + { + "none", + "monochrome bitmap", + "gray 8-bit bitmap", + "gray 2-bit bitmap", + "gray 4-bit bitmap", + "LCD 8-bit bitmap", + "vertical LCD 8-bit bitmap", + "BGRA 32-bit color image bitmap" + }; + #endif /* FT_DEBUG_LEVEL_TRACE */ @@ -259,14 +271,14 @@ } - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_objs +#define FT_COMPONENT objs /*************************************************************************/ @@ -330,7 +342,9 @@ } - FT_BASE_DEF( void ) + /* overflow-resistant presetting of bitmap position and dimensions; */ + /* also check whether the size is too large for rendering */ + FT_BASE_DEF( FT_Bool ) ft_glyphslot_preset_bitmap( FT_GlyphSlot slot, FT_Render_Mode mode, const FT_Vector* origin ) @@ -340,15 +354,15 @@ FT_Pixel_Mode pixel_mode; - FT_BBox cbox; + FT_BBox cbox, pbox; FT_Pos x_shift = 0; FT_Pos y_shift = 0; FT_Pos x_left, y_top; FT_Pos width, height, pitch; - if ( slot->internal && ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) ) - return; + if ( slot->format != FT_GLYPH_FORMAT_OUTLINE ) + return 1; if ( origin ) { @@ -360,76 +374,89 @@ /* taking into account the origin shift */ FT_Outline_Get_CBox( outline, &cbox ); - cbox.xMin += x_shift; - cbox.yMin += y_shift; - cbox.xMax += x_shift; - cbox.yMax += y_shift; + /* rough estimate of pixel box */ + pbox.xMin = ( cbox.xMin >> 6 ) + ( x_shift >> 6 ); + pbox.yMin = ( cbox.yMin >> 6 ) + ( y_shift >> 6 ); + pbox.xMax = ( cbox.xMax >> 6 ) + ( x_shift >> 6 ); + pbox.yMax = ( cbox.yMax >> 6 ) + ( y_shift >> 6 ); + + /* tiny remainder box */ + cbox.xMin = ( cbox.xMin & 63 ) + ( x_shift & 63 ); + cbox.yMin = ( cbox.yMin & 63 ) + ( y_shift & 63 ); + cbox.xMax = ( cbox.xMax & 63 ) + ( x_shift & 63 ); + cbox.yMax = ( cbox.yMax & 63 ) + ( y_shift & 63 ); switch ( mode ) { case FT_RENDER_MODE_MONO: pixel_mode = FT_PIXEL_MODE_MONO; #if 1 - /* undocumented but confirmed: bbox values get rounded */ - /* unless the rounded box can collapse for a narrow glyph */ - if ( cbox.xMax - cbox.xMin < 64 ) - { - cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); - cbox.xMax = FT_PIX_CEIL_LONG( cbox.xMax ); - } - else - { - cbox.xMin = FT_PIX_ROUND_LONG( cbox.xMin ); - cbox.xMax = FT_PIX_ROUND_LONG( cbox.xMax ); - } + /* x */ + + /* undocumented but confirmed: bbox values get rounded; */ + /* we do asymmetric rounding so that the center of a pixel */ + /* gets always included */ + + pbox.xMin += ( cbox.xMin + 31 ) >> 6; + pbox.xMax += ( cbox.xMax + 32 ) >> 6; - if ( cbox.yMax - cbox.yMin < 64 ) + /* if the bbox collapsed, we add a pixel based on the total */ + /* rounding remainder to cover most of the original cbox */ + + if ( pbox.xMin == pbox.xMax ) { - cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); - cbox.yMax = FT_PIX_CEIL_LONG( cbox.yMax ); + if ( ( ( cbox.xMin + 31 ) & 63 ) - 31 + + ( ( cbox.xMax + 32 ) & 63 ) - 32 < 0 ) + pbox.xMin -= 1; + else + pbox.xMax += 1; } - else + + /* y */ + + pbox.yMin += ( cbox.yMin + 31 ) >> 6; + pbox.yMax += ( cbox.yMax + 32 ) >> 6; + + if ( pbox.yMin == pbox.yMax ) { - cbox.yMin = FT_PIX_ROUND_LONG( cbox.yMin ); - cbox.yMax = FT_PIX_ROUND_LONG( cbox.yMax ); + if ( ( ( cbox.yMin + 31 ) & 63 ) - 31 + + ( ( cbox.yMax + 32 ) & 63 ) - 32 < 0 ) + pbox.yMin -= 1; + else + pbox.yMax += 1; } + + break; #else - cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); - cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); - cbox.xMax = FT_PIX_CEIL_LONG( cbox.xMax ); - cbox.yMax = FT_PIX_CEIL_LONG( cbox.yMax ); + goto Adjust; #endif - break; case FT_RENDER_MODE_LCD: pixel_mode = FT_PIXEL_MODE_LCD; - ft_lcd_padding( &cbox.xMin, &cbox.xMax, slot ); - goto Round; + ft_lcd_padding( &cbox, slot, mode ); + goto Adjust; case FT_RENDER_MODE_LCD_V: pixel_mode = FT_PIXEL_MODE_LCD_V; - ft_lcd_padding( &cbox.yMin, &cbox.yMax, slot ); - goto Round; + ft_lcd_padding( &cbox, slot, mode ); + goto Adjust; case FT_RENDER_MODE_NORMAL: case FT_RENDER_MODE_LIGHT: default: pixel_mode = FT_PIXEL_MODE_GRAY; - Round: - cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); - cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); - cbox.xMax = FT_PIX_CEIL_LONG( cbox.xMax ); - cbox.yMax = FT_PIX_CEIL_LONG( cbox.yMax ); + Adjust: + pbox.xMin += cbox.xMin >> 6; + pbox.yMin += cbox.yMin >> 6; + pbox.xMax += ( cbox.xMax + 63 ) >> 6; + pbox.yMax += ( cbox.yMax + 63 ) >> 6; } - x_shift = SUB_LONG( x_shift, cbox.xMin ); - y_shift = SUB_LONG( y_shift, cbox.yMin ); + x_left = pbox.xMin; + y_top = pbox.yMax; - x_left = cbox.xMin >> 6; - y_top = cbox.yMax >> 6; - - width = ( (FT_ULong)cbox.xMax - (FT_ULong)cbox.xMin ) >> 6; - height = ( (FT_ULong)cbox.yMax - (FT_ULong)cbox.yMin ) >> 6; + width = pbox.xMax - pbox.xMin; + height = pbox.yMax - pbox.yMin; switch ( pixel_mode ) { @@ -459,6 +486,16 @@ bitmap->width = (unsigned int)width; bitmap->rows = (unsigned int)height; bitmap->pitch = pitch; + + if ( pbox.xMin < -0x8000 || pbox.xMax > 0x7FFF || + pbox.yMin < -0x8000 || pbox.yMax > 0x7FFF ) + { + FT_TRACE3(( "ft_glyphslot_preset_bitmap: [%ld %ld %ld %ld]\n", + pbox.xMin, pbox.yMin, pbox.xMax, pbox.yMax )); + return 1; + } + + return 0; } @@ -807,7 +844,7 @@ * - Do only auto-hinting if we have * * - a hinter module, - * - a scalable font format dealing with outlines, + * - a scalable font, * - not a tricky font, and * - no transforms except simple slants and/or rotations by * integer multiples of 90 degrees. @@ -825,8 +862,7 @@ if ( hinter && !( load_flags & FT_LOAD_NO_HINTING ) && !( load_flags & FT_LOAD_NO_AUTOHINT ) && - FT_DRIVER_IS_SCALABLE( driver ) && - FT_DRIVER_USES_OUTLINES( driver ) && + FT_IS_SCALABLE( face ) && !FT_IS_TRICKY( face ) && ( ( load_flags & FT_LOAD_IGNORE_TRANSFORM ) || ( face->internal->transform_matrix.yx == 0 && @@ -846,7 +882,7 @@ /* only the new Adobe engine (for both CFF and Type 1) is `light'; */ /* we use `strstr' to catch both `Type 1' and `CID Type 1' */ is_light_type1 = - ft_strstr( FT_Get_Font_Format( face ), "Type 1" ) != NULL && + ft_strstr( FT_Get_Font_Format( face ), "Type 1" ) != NULL && ((PS_Driver)driver)->hinting_engine == FT_HINTING_ADOBE; /* the check for `num_locations' assures that we actually */ @@ -926,8 +962,9 @@ #ifdef GRID_FIT_METRICS if ( !( load_flags & FT_LOAD_NO_HINTING ) ) - ft_glyphslot_grid_fit_metrics( slot, - FT_BOOL( load_flags & FT_LOAD_VERTICAL_LAYOUT ) ); + ft_glyphslot_grid_fit_metrics( + slot, + FT_BOOL( load_flags & FT_LOAD_VERTICAL_LAYOUT ) ); #endif } } @@ -995,6 +1032,9 @@ } } + slot->glyph_index = glyph_index; + slot->internal->load_flags = load_flags; + /* do we need to render the image or preset the bitmap now? */ if ( !error && ( load_flags & FT_LOAD_NO_SCALE ) == 0 && @@ -1014,17 +1054,21 @@ ft_glyphslot_preset_bitmap( slot, mode, NULL ); } - FT_TRACE5(( "FT_Load_Glyph: index %d, flags %x\n", - glyph_index, load_flags )); +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE5(( "FT_Load_Glyph: index %d, flags 0x%x\n", + glyph_index, load_flags )); FT_TRACE5(( " x advance: %f\n", slot->advance.x / 64.0 )); FT_TRACE5(( " y advance: %f\n", slot->advance.y / 64.0 )); FT_TRACE5(( " linear x advance: %f\n", slot->linearHoriAdvance / 65536.0 )); FT_TRACE5(( " linear y advance: %f\n", slot->linearVertAdvance / 65536.0 )); - FT_TRACE5(( " bitmap %dx%d, mode %d\n", - slot->bitmap.width, slot->bitmap.rows, - slot->bitmap.pixel_mode )); + FT_TRACE5(( " bitmap %dx%d, %s (mode %d)\n", + slot->bitmap.width, + slot->bitmap.rows, + pixel_modes[slot->bitmap.pixel_mode], + slot->bitmap.pixel_mode )); +#endif Exit: return error; @@ -1162,20 +1206,20 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* find_unicode_charmap */ - /* */ - /* <Description> */ - /* This function finds a Unicode charmap, if there is one. */ - /* And if there is more than one, it tries to favour the more */ - /* extensive one, i.e., one that supports UCS-4 against those which */ - /* are limited to the BMP (said UCS-2 encoding.) */ - /* */ - /* This function is called from open_face() (just below), and also */ - /* from FT_Select_Charmap( ..., FT_ENCODING_UNICODE ). */ - /* */ + /************************************************************************** + * + * @Function: + * find_unicode_charmap + * + * @Description: + * This function finds a Unicode charmap, if there is one. + * And if there is more than one, it tries to favour the more + * extensive one, i.e., one that supports UCS-4 against those which + * are limited to the BMP (said UCS-2 encoding.) + * + * This function is called from open_face() (just below), and also + * from FT_Select_Charmap( ..., FT_ENCODING_UNICODE ). + */ static FT_Error find_unicode_charmap( FT_Face face ) { @@ -1192,26 +1236,26 @@ return FT_THROW( Invalid_CharMap_Handle ); /* - * The original TrueType specification(s) only specified charmap - * formats that are capable of mapping 8 or 16 bit character codes to - * glyph indices. + * The original TrueType specification(s) only specified charmap + * formats that are capable of mapping 8 or 16 bit character codes to + * glyph indices. * - * However, recent updates to the Apple and OpenType specifications - * introduced new formats that are capable of mapping 32-bit character - * codes as well. And these are already used on some fonts, mainly to - * map non-BMP Asian ideographs as defined in Unicode. + * However, recent updates to the Apple and OpenType specifications + * introduced new formats that are capable of mapping 32-bit character + * codes as well. And these are already used on some fonts, mainly to + * map non-BMP Asian ideographs as defined in Unicode. * - * For compatibility purposes, these fonts generally come with - * *several* Unicode charmaps: + * For compatibility purposes, these fonts generally come with + * *several* Unicode charmaps: * - * - One of them in the "old" 16-bit format, that cannot access - * all glyphs in the font. + * - One of them in the "old" 16-bit format, that cannot access + * all glyphs in the font. * - * - Another one in the "new" 32-bit format, that can access all - * the glyphs. + * - Another one in the "new" 32-bit format, that can access all + * the glyphs. * - * This function has been written to always favor a 32-bit charmap - * when found. Otherwise, a 16-bit one is returned when found. + * This function has been written to always favor a 32-bit charmap + * when found. Otherwise, a 16-bit one is returned when found. */ /* Since the `interesting' table, with IDs (3,10), is normally the */ @@ -1255,15 +1299,15 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* find_variant_selector_charmap */ - /* */ - /* <Description> */ - /* This function finds the variant selector charmap, if there is one. */ - /* There can only be one (platform=0, specific=5, format=14). */ - /* */ + /************************************************************************** + * + * @Function: + * find_variant_selector_charmap + * + * @Description: + * This function finds the variant selector charmap, if there is one. + * There can only be one (platform=0, specific=5, format=14). + */ static FT_CharMap find_variant_selector_charmap( FT_Face face ) { @@ -1294,14 +1338,14 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* open_face */ - /* */ - /* <Description> */ - /* This function does some work for FT_Open_Face(). */ - /* */ + /************************************************************************** + * + * @Function: + * open_face + * + * @Description: + * This function does some work for FT_Open_Face(). + */ static FT_Error open_face( FT_Driver driver, FT_Stream *astream, @@ -2176,13 +2220,13 @@ { #undef FT_COMPONENT -#define FT_COMPONENT trace_raccess +#define FT_COMPONENT raccess FT_Memory memory = library->memory; FT_Error error = FT_ERR( Unknown_File_Format ); FT_UInt i; - char * file_names[FT_RACCESS_N_RULES]; + char* file_names[FT_RACCESS_N_RULES]; FT_Long offsets[FT_RACCESS_N_RULES]; FT_Error errors[FT_RACCESS_N_RULES]; FT_Bool is_darwin_vfs, vfs_rfork_has_no_font = FALSE; /* not tested */ @@ -2254,7 +2298,7 @@ return error; #undef FT_COMPONENT -#define FT_COMPONENT trace_objs +#define FT_COMPONENT objs } @@ -2282,7 +2326,7 @@ { #undef FT_COMPONENT -#define FT_COMPONENT trace_raccess +#define FT_COMPONENT raccess #ifdef FT_DEBUG_LEVEL_TRACE FT_TRACE3(( "Try as dfont: " )); @@ -2295,7 +2339,7 @@ FT_TRACE3(( "%s\n", error ? "failed" : "successful" )); #undef FT_COMPONENT -#define FT_COMPONENT trace_objs +#define FT_COMPONENT objs } @@ -2693,8 +2737,8 @@ /* close the attached stream */ FT_Stream_Free( stream, - (FT_Bool)( parameters->stream && - ( parameters->flags & FT_OPEN_STREAM ) ) ); + FT_BOOL( parameters->stream && + ( parameters->flags & FT_OPEN_STREAM ) ) ); Exit: return error; @@ -3464,7 +3508,8 @@ if ( !face ) return FT_THROW( Invalid_Face_Handle ); - if ( encoding == FT_ENCODING_NONE ) + /* FT_ENCODING_NONE is a valid encoding for BDF, PCF, and Windows FNT */ + if ( encoding == FT_ENCODING_NONE && !face->num_charmaps ) return FT_THROW( Invalid_Argument ); /* FT_ENCODING_UNICODE is special. We try to find the `best' Unicode */ @@ -3485,7 +3530,7 @@ if ( cur[0]->encoding == encoding ) { face->charmap = cur[0]; - return 0; + return FT_Err_Ok; } } @@ -3510,14 +3555,12 @@ if ( !cur || !charmap ) return FT_THROW( Invalid_CharMap_Handle ); - if ( FT_Get_CMap_Format( charmap ) == 14 ) - return FT_THROW( Invalid_Argument ); - limit = cur + face->num_charmaps; for ( ; cur < limit; cur++ ) { - if ( cur[0] == charmap ) + if ( cur[0] == charmap && + FT_Get_CMap_Format ( charmap ) != 14 ) { face->charmap = cur[0]; return FT_Err_Ok; @@ -4487,16 +4530,89 @@ FT_Render_Mode render_mode ) { FT_Error error = FT_Err_Ok; + FT_Face face = slot->face; FT_Renderer renderer; - /* if it is already a bitmap, no need to do anything */ switch ( slot->format ) { case FT_GLYPH_FORMAT_BITMAP: /* already a bitmap, don't do anything */ break; default: + if ( slot->internal->load_flags & FT_LOAD_COLOR ) + { + FT_LayerIterator iterator; + + FT_UInt base_glyph = slot->glyph_index; + + FT_Bool have_layers; + FT_UInt glyph_index; + FT_UInt color_index; + + + /* check whether we have colored glyph layers */ + iterator.p = NULL; + have_layers = FT_Get_Color_Glyph_Layer( face, + base_glyph, + &glyph_index, + &color_index, + &iterator ); + if ( have_layers ) + { + error = FT_New_GlyphSlot( face, NULL ); + if ( !error ) + { + TT_Face ttface = (TT_Face)face; + SFNT_Service sfnt = (SFNT_Service)ttface->sfnt; + + + do + { + FT_Int32 load_flags = slot->internal->load_flags; + + + /* disable the `FT_LOAD_COLOR' flag to avoid recursion */ + /* right here in this function */ + load_flags &= ~FT_LOAD_COLOR; + + /* render into the new `face->glyph' glyph slot */ + load_flags |= FT_LOAD_RENDER; + + error = FT_Load_Glyph( face, glyph_index, load_flags ); + if ( error ) + break; + + /* blend new `face->glyph' into old `slot'; */ + /* at the first call, `slot' is still empty */ + error = sfnt->colr_blend( ttface, + color_index, + slot, + face->glyph ); + if ( error ) + break; + + } while ( FT_Get_Color_Glyph_Layer( face, + base_glyph, + &glyph_index, + &color_index, + &iterator ) ); + + if ( !error ) + slot->format = FT_GLYPH_FORMAT_BITMAP; + + /* this call also restores `slot' as the glyph slot */ + FT_Done_GlyphSlot( face->glyph ); + } + + if ( !error ) + return error; + + /* Failed to do the colored layer. Draw outline instead. */ + slot->format = FT_GLYPH_FORMAT_OUTLINE; + } + } + { FT_ListNode node = NULL; @@ -4532,7 +4648,7 @@ #ifdef FT_DEBUG_LEVEL_TRACE #undef FT_COMPONENT -#define FT_COMPONENT trace_bitmap +#define FT_COMPONENT checksum /* * Computing the MD5 checksum is expensive, unnecessarily distorting a @@ -4542,9 +4658,9 @@ */ /* we use FT_TRACE3 in this block */ - if ( !error && - ft_trace_levels[trace_bitmap] >= 3 && - slot->bitmap.buffer ) + if ( !error && + ft_trace_levels[trace_checksum] >= 3 && + slot->bitmap.buffer ) { FT_Bitmap bitmap; FT_Error err; @@ -4565,8 +4681,11 @@ int pitch = bitmap.pitch; - FT_TRACE3(( "FT_Render_Glyph: bitmap %dx%d, mode %d\n", - rows, pitch, slot->bitmap.pixel_mode )); + FT_TRACE3(( "FT_Render_Glyph: bitmap %dx%d, %s (mode %d)\n", + pitch, + rows, + pixel_modes[slot->bitmap.pixel_mode], + slot->bitmap.pixel_mode )); for ( i = 0; i < rows; i++ ) for ( j = 0; j < pitch; j++ ) @@ -4594,49 +4713,56 @@ */ /* we use FT_TRACE7 in this block */ - if ( !error && - ft_trace_levels[trace_bitmap] >= 7 && - slot->bitmap.rows < 128U && - slot->bitmap.width < 128U && - slot->bitmap.buffer ) + if ( !error && + ft_trace_levels[trace_checksum] >= 7 ) { - int rows = (int)slot->bitmap.rows; - int width = (int)slot->bitmap.width; - int pitch = slot->bitmap.pitch; - int i, j, m; - unsigned char* topleft = slot->bitmap.buffer; + if ( slot->bitmap.rows < 128U && + slot->bitmap.width < 128U && + slot->bitmap.buffer ) + { + int rows = (int)slot->bitmap.rows; + int width = (int)slot->bitmap.width; + int pitch = slot->bitmap.pitch; + int i, j, m; - if ( pitch < 0 ) - topleft -= pitch * ( rows - 1 ); + unsigned char* topleft = slot->bitmap.buffer; - FT_TRACE7(( "Netpbm image: start\n" )); - switch ( slot->bitmap.pixel_mode ) - { - case FT_PIXEL_MODE_MONO: - FT_TRACE7(( "P1 %d %d\n", width, rows )); - for ( i = 0; i < rows; i++ ) - { - for ( j = 0; j < width; ) - for ( m = 128; m > 0 && j < width; m >>= 1, j++ ) - FT_TRACE7(( " %d", ( topleft[i * pitch + j / 8] & m ) != 0 )); - FT_TRACE7(( "\n" )); - } - break; - default: - FT_TRACE7(( "P2 %d %d 255\n", width, rows )); - for ( i = 0; i < rows; i++ ) + if ( pitch < 0 ) + topleft -= pitch * ( rows - 1 ); + + FT_TRACE7(( "Netpbm image: start\n" )); + switch ( slot->bitmap.pixel_mode ) { - for ( j = 0; j < width; j += 1 ) - FT_TRACE7(( " %3u", topleft[i * pitch + j] )); - FT_TRACE7(( "\n" )); + case FT_PIXEL_MODE_MONO: + FT_TRACE7(( "P1 %d %d\n", width, rows )); + for ( i = 0; i < rows; i++ ) + { + for ( j = 0; j < width; ) + for ( m = 128; m > 0 && j < width; m >>= 1, j++ ) + FT_TRACE7(( " %d", + ( topleft[i * pitch + j / 8] & m ) != 0 )); + FT_TRACE7(( "\n" )); + } + break; + + default: + FT_TRACE7(( "P2 %d %d 255\n", width, rows )); + for ( i = 0; i < rows; i++ ) + { + for ( j = 0; j < width; j += 1 ) + FT_TRACE7(( " %3u", topleft[i * pitch + j] )); + FT_TRACE7(( "\n" )); + } } + FT_TRACE7(( "Netpbm image: end\n" )); } - FT_TRACE7(( "Netpbm image: end\n" )); + else + FT_TRACE7(( "Netpbm image: too large, omitted\n" )); } #undef FT_COMPONENT -#define FT_COMPONENT trace_objs +#define FT_COMPONENT objs #endif /* FT_DEBUG_LEVEL_TRACE */ @@ -4675,21 +4801,22 @@ /*************************************************************************/ - /*************************************************************************/ - /* */ - /* <Function> */ - /* Destroy_Module */ - /* */ - /* <Description> */ - /* Destroys a given module object. For drivers, this also destroys */ - /* all child faces. */ - /* */ - /* <InOut> */ - /* module :: A handle to the target driver object. */ - /* */ - /* <Note> */ - /* The driver _must_ be LOCKED! */ - /* */ + /************************************************************************** + * + * @Function: + * Destroy_Module + * + * @Description: + * Destroys a given module object. For drivers, this also destroys + * all child faces. + * + * @InOut: + * module :: + * A handle to the target driver object. + * + * @Note: + * The driver _must_ be LOCKED! + */ static void Destroy_Module( FT_Module module ) { @@ -5028,9 +5155,9 @@ service = (FT_Service_Properties)interface; if ( set ) - missing_func = (FT_Bool)( !service->set_property ); + missing_func = FT_BOOL( !service->set_property ); else - missing_func = (FT_Bool)( !service->get_property ); + missing_func = FT_BOOL( !service->get_property ); if ( missing_func ) { @@ -5156,13 +5283,6 @@ library->memory = memory; -#ifdef FT_CONFIG_OPTION_PIC - /* initialize position independent code containers */ - error = ft_pic_container_init( library ); - if ( error ) - goto Fail; -#endif - library->version_major = FREETYPE_MAJOR; library->version_minor = FREETYPE_MINOR; library->version_patch = FREETYPE_PATCH; @@ -5173,13 +5293,6 @@ *alibrary = library; return FT_Err_Ok; - -#ifdef FT_CONFIG_OPTION_PIC - Fail: - ft_pic_container_destroy( library ); - FT_FREE( library ); - return error; -#endif } @@ -5237,10 +5350,10 @@ * * Example: * - * - the cff font driver uses the pshinter module in cff_size_done - * - if the pshinter module is destroyed before the cff font driver, - * opened FT_Face objects managed by the driver are not properly - * destroyed, resulting in a memory leak + * - the cff font driver uses the pshinter module in cff_size_done + * - if the pshinter module is destroyed before the cff font driver, + * opened FT_Face objects managed by the driver are not properly + * destroyed, resulting in a memory leak * * Some faces are dependent on other faces, like Type42 faces that * depend on TrueType faces synthesized internally. @@ -5310,11 +5423,6 @@ } #endif -#ifdef FT_CONFIG_OPTION_PIC - /* Destroy pic container contents */ - ft_pic_container_destroy( library ); -#endif - FT_FREE( library ); Exit: @@ -5402,4 +5510,41 @@ } + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Bool ) + FT_Get_Color_Glyph_Layer( FT_Face face, + FT_UInt base_glyph, + FT_UInt *aglyph_index, + FT_UInt *acolor_index, + FT_LayerIterator* iterator ) + { + TT_Face ttface; + SFNT_Service sfnt; + + + if ( !face || + !aglyph_index || + !acolor_index || + !iterator || + base_glyph >= (FT_UInt)face->num_glyphs ) + return 0; + + if ( !FT_IS_SFNT( face ) ) + return 0; + + ttface = (TT_Face)face; + sfnt = (SFNT_Service)ttface->sfnt; + + if ( sfnt->get_colr_layer ) + return sfnt->get_colr_layer( ttface, + base_glyph, + aglyph_index, + acolor_index, + iterator ); + else + return 0; + } + + /* END */ diff --git a/sdk/lib/3rdparty/freetype/src/base/ftotval.c b/sdk/lib/3rdparty/freetype/src/base/ftotval.c index a2944a7950c2e..007576ce6e2a6 100644 --- a/sdk/lib/3rdparty/freetype/src/base/ftotval.c +++ b/sdk/lib/3rdparty/freetype/src/base/ftotval.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftotval.c */ -/* */ -/* FreeType API for validating OpenType tables (body). */ -/* */ -/* Copyright 2004-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftotval.c + * + * FreeType API for validating OpenType tables (body). + * + * Copyright (C) 2004-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> #include FT_INTERNAL_DEBUG_H diff --git a/sdk/lib/3rdparty/freetype/src/base/ftoutln.c b/sdk/lib/3rdparty/freetype/src/base/ftoutln.c index 9c29ade92fbbd..00329b46c64dd 100644 --- a/sdk/lib/3rdparty/freetype/src/base/ftoutln.c +++ b/sdk/lib/3rdparty/freetype/src/base/ftoutln.c @@ -1,26 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftoutln.c */ -/* */ -/* FreeType outline management (body). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* All functions are declared in freetype.h. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * ftoutln.c + * + * FreeType outline management (body). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -31,14 +24,14 @@ #include FT_TRIGONOMETRY_H - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_outline +#define FT_COMPONENT outline static @@ -286,23 +279,32 @@ FT_TRACE5(( "FT_Outline_Decompose: Done\n", n )); return FT_Err_Ok; + Invalid_Outline: + error = FT_THROW( Invalid_Outline ); + /* fall through */ + Exit: FT_TRACE5(( "FT_Outline_Decompose: Error 0x%x\n", error )); return error; - - Invalid_Outline: - return FT_THROW( Invalid_Outline ); } + /* documentation is in ftoutln.h */ + FT_EXPORT_DEF( FT_Error ) - FT_Outline_New_Internal( FT_Memory memory, - FT_UInt numPoints, - FT_Int numContours, - FT_Outline *anoutline ) + FT_Outline_New( FT_Library library, + FT_UInt numPoints, + FT_Int numContours, + FT_Outline *anoutline ) { - FT_Error error; + FT_Error error; + FT_Memory memory; + + + if ( !library ) + return FT_THROW( Invalid_Library_Handle ); + memory = library->memory; if ( !anoutline || !memory ) return FT_THROW( Invalid_Argument ); @@ -329,28 +331,12 @@ Fail: anoutline->flags |= FT_OUTLINE_OWNER; - FT_Outline_Done_Internal( memory, anoutline ); + FT_Outline_Done( library, anoutline ); return error; } - /* documentation is in ftoutln.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Outline_New( FT_Library library, - FT_UInt numPoints, - FT_Int numContours, - FT_Outline *anoutline ) - { - if ( !library ) - return FT_THROW( Invalid_Library_Handle ); - - return FT_Outline_New_Internal( library->memory, numPoints, - numContours, anoutline ); - } - - /* documentation is in ftoutln.h */ FT_EXPORT_DEF( FT_Error ) @@ -435,13 +421,23 @@ } + /* documentation is in ftoutln.h */ + FT_EXPORT_DEF( FT_Error ) - FT_Outline_Done_Internal( FT_Memory memory, - FT_Outline* outline ) + FT_Outline_Done( FT_Library library, + FT_Outline* outline ) { + FT_Memory memory; + + + if ( !library ) + return FT_THROW( Invalid_Library_Handle ); + if ( !outline ) return FT_THROW( Invalid_Outline ); + memory = library->memory; + if ( !memory ) return FT_THROW( Invalid_Argument ); @@ -457,21 +453,6 @@ } - /* documentation is in ftoutln.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Outline_Done( FT_Library library, - FT_Outline* outline ) - { - /* check for valid `outline' in FT_Outline_Done_Internal() */ - - if ( !library ) - return FT_THROW( Invalid_Library_Handle ); - - return FT_Outline_Done_Internal( library->memory, outline ); - } - - /* documentation is in ftoutln.h */ FT_EXPORT_DEF( void ) @@ -618,6 +599,7 @@ FT_Error error; FT_Renderer renderer; FT_ListNode node; + FT_BBox cbox; if ( !library ) @@ -629,6 +611,11 @@ if ( !params ) return FT_THROW( Invalid_Argument ); + FT_Outline_Get_CBox( outline, &cbox ); + if ( cbox.xMin < -0x1000000L || cbox.yMin < -0x1000000L || + cbox.xMax > 0x1000000L || cbox.yMax > 0x1000000L ) + return FT_THROW( Invalid_Outline ); + renderer = library->cur_renderer; node = library->renderers.head; @@ -910,9 +897,9 @@ FT_Pos xstrength, FT_Pos ystrength ) { - FT_Vector* points; - FT_Int c, first, last; - FT_Int orientation; + FT_Vector* points; + FT_Int c, first, last; + FT_Orientation orientation; if ( !outline ) @@ -1043,7 +1030,7 @@ FT_EXPORT_DEF( FT_Orientation ) FT_Outline_Get_Orientation( FT_Outline* outline ) { - FT_BBox cbox; + FT_BBox cbox = { 0, 0, 0, 0 }; FT_Int xshift, yshift; FT_Vector* points; FT_Vector v_prev, v_cur; @@ -1089,7 +1076,8 @@ v_cur.y = points[n].y >> yshift; area = ADD_LONG( area, - ( v_cur.y - v_prev.y ) * ( v_cur.x + v_prev.x ) ); + MUL_LONG( v_cur.y - v_prev.y, + v_cur.x + v_prev.x ) ); v_prev = v_cur; } diff --git a/sdk/lib/3rdparty/freetype/src/base/ftpatent.c b/sdk/lib/3rdparty/freetype/src/base/ftpatent.c index e23ee2e3f486b..020f4646ebec5 100644 --- a/sdk/lib/3rdparty/freetype/src/base/ftpatent.c +++ b/sdk/lib/3rdparty/freetype/src/base/ftpatent.c @@ -1,20 +1,20 @@ -/***************************************************************************/ -/* */ -/* ftpatent.c */ -/* */ -/* FreeType API for checking patented TrueType bytecode instructions */ -/* (body). Obsolete, retained for backward compatibility. */ -/* */ -/* Copyright 2007-2018 by */ -/* David Turner. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftpatent.c + * + * FreeType API for checking patented TrueType bytecode instructions + * (body). Obsolete, retained for backward compatibility. + * + * Copyright (C) 2007-2019 by + * David Turner. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> #include FT_FREETYPE_H diff --git a/sdk/lib/3rdparty/freetype/src/base/ftpfr.c b/sdk/lib/3rdparty/freetype/src/base/ftpfr.c index bfe13520eb9d1..aeff1db8bd09a 100644 --- a/sdk/lib/3rdparty/freetype/src/base/ftpfr.c +++ b/sdk/lib/3rdparty/freetype/src/base/ftpfr.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftpfr.c */ -/* */ -/* FreeType API for accessing PFR-specific data (body). */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftpfr.c + * + * FreeType API for accessing PFR-specific data (body). + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> #include FT_INTERNAL_DEBUG_H diff --git a/sdk/lib/3rdparty/freetype/src/base/ftpic.c b/sdk/lib/3rdparty/freetype/src/base/ftpic.c deleted file mode 100644 index 1492e1809a514..0000000000000 --- a/sdk/lib/3rdparty/freetype/src/base/ftpic.c +++ /dev/null @@ -1,55 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftpic.c */ -/* */ -/* The FreeType position independent code services (body). */ -/* */ -/* Copyright 2009-2018 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_FREETYPE_H -#include FT_INTERNAL_OBJECTS_H -#include "basepic.h" - -#ifdef FT_CONFIG_OPTION_PIC - - /* documentation is in ftpic.h */ - - FT_BASE_DEF( FT_Error ) - ft_pic_container_init( FT_Library library ) - { - FT_PIC_Container* pic_container = &library->pic_container; - FT_Error error; - - - FT_MEM_SET( pic_container, 0, sizeof ( *pic_container ) ); - - error = ft_base_pic_init( library ); - if ( error ) - return error; - - return FT_Err_Ok; - } - - - /* Destroy the contents of the container. */ - FT_BASE_DEF( void ) - ft_pic_container_destroy( FT_Library library ) - { - ft_base_pic_free( library ); - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - -/* END */ diff --git a/sdk/lib/3rdparty/freetype/src/base/ftpsprop.c b/sdk/lib/3rdparty/freetype/src/base/ftpsprop.c index 459b5e6054c9d..52b9d453ad21e 100644 --- a/sdk/lib/3rdparty/freetype/src/base/ftpsprop.c +++ b/sdk/lib/3rdparty/freetype/src/base/ftpsprop.c @@ -1,20 +1,20 @@ -/***************************************************************************/ -/* */ -/* ftpsprop.c */ -/* */ -/* Get and set properties of PostScript drivers (body). */ -/* See `ftdriver.h' for available properties. */ -/* */ -/* Copyright 2017-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftpsprop.c + * + * Get and set properties of PostScript drivers (body). + * See `ftdriver.h' for available properties. + * + * Copyright (C) 2017-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -25,14 +25,14 @@ #include FT_INTERNAL_POSTSCRIPT_PROPS_H - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_psprops +#define FT_COMPONENT psprops FT_BASE_CALLBACK_DEF( FT_Error ) diff --git a/sdk/lib/3rdparty/freetype/src/base/ftrfork.c b/sdk/lib/3rdparty/freetype/src/base/ftrfork.c index c3a2b9151ac2e..73b7eb0ded495 100644 --- a/sdk/lib/3rdparty/freetype/src/base/ftrfork.c +++ b/sdk/lib/3rdparty/freetype/src/base/ftrfork.c @@ -1,38 +1,38 @@ -/***************************************************************************/ -/* */ -/* ftrfork.c */ -/* */ -/* Embedded resource forks accessor (body). */ -/* */ -/* Copyright 2004-2018 by */ -/* Masatake YAMATO and Redhat K.K. */ -/* */ -/* FT_Raccess_Get_HeaderInfo() and raccess_guess_darwin_hfsplus() are */ -/* derived from ftobjs.c. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* Development of the code in this file is support of */ -/* Information-technology Promotion Agency, Japan. */ -/***************************************************************************/ +/**************************************************************************** + * + * ftrfork.c + * + * Embedded resource forks accessor (body). + * + * Copyright (C) 2004-2019 by + * Masatake YAMATO and Redhat K.K. + * + * FT_Raccess_Get_HeaderInfo() and raccess_guess_darwin_hfsplus() are + * derived from ftobjs.c. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + +/**************************************************************************** + * Development of the code in this file is support of + * Information-technology Promotion Agency, Japan. + */ #include <ft2build.h> #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_RFORK_H -#include "basepic.h" + #include "ftbase.h" #undef FT_COMPONENT -#define FT_COMPONENT trace_raccess +#define FT_COMPONENT raccess /*************************************************************************/ @@ -438,7 +438,7 @@ static FT_Error raccess_guess_linux_double_from_file_name( FT_Library library, - char * file_name, + char* file_name, FT_Long *result_offset ); static char * @@ -468,10 +468,10 @@ if ( errors[i] ) continue; - errors[i] = (FT_RACCESS_GUESS_TABLE_GET[i].func)( library, - stream, base_name, - &(new_names[i]), - &(offsets[i]) ); + errors[i] = ft_raccess_guess_table[i].func( library, + stream, base_name, + &(new_names[i]), + &(offsets[i]) ); } return; @@ -488,7 +488,7 @@ if ( rule_index >= FT_RACCESS_N_RULES ) return FT_RFork_Rule_invalid; - return FT_RACCESS_GUESS_TABLE_GET[rule_index].type; + return ft_raccess_guess_table[rule_index].type; } @@ -847,7 +847,7 @@ { FT_Open_Args args2; FT_Stream stream2; - char * nouse = NULL; + char* nouse = NULL; FT_Error error; @@ -909,9 +909,9 @@ #else /* !FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */ - /*************************************************************************/ - /* Dummy function; just sets errors */ - /*************************************************************************/ + /************************************************************************** + * Dummy function; just sets errors + */ FT_BASE_DEF( void ) FT_Raccess_Guess( FT_Library library, diff --git a/sdk/lib/3rdparty/freetype/src/base/ftsnames.c b/sdk/lib/3rdparty/freetype/src/base/ftsnames.c index 90ea1e2be7b0a..7ab3fe3cfacd4 100644 --- a/sdk/lib/3rdparty/freetype/src/base/ftsnames.c +++ b/sdk/lib/3rdparty/freetype/src/base/ftsnames.c @@ -1,22 +1,22 @@ -/***************************************************************************/ -/* */ -/* ftsnames.c */ -/* */ -/* Simple interface to access SFNT name tables (which are used */ -/* to hold font names, copyright info, notices, etc.) (body). */ -/* */ -/* This is _not_ used to retrieve glyph names! */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftsnames.c + * + * Simple interface to access SFNT name tables (which are used + * to hold font names, copyright info, notices, etc.) (body). + * + * This is _not_ used to retrieve glyph names! + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -142,7 +142,45 @@ } -#endif /* TT_CONFIG_OPTION_SFNT_NAMES */ +#else /* !TT_CONFIG_OPTION_SFNT_NAMES */ + + + FT_EXPORT_DEF( FT_UInt ) + FT_Get_Sfnt_Name_Count( FT_Face face ) + { + FT_UNUSED( face ); + + return 0; + } + + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Sfnt_Name( FT_Face face, + FT_UInt idx, + FT_SfntName *aname ) + { + FT_UNUSED( face ); + FT_UNUSED( idx ); + FT_UNUSED( aname ); + + return FT_THROW( Unimplemented_Feature ); + } + + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Sfnt_LangTag( FT_Face face, + FT_UInt langID, + FT_SfntLangTag *alangTag ) + { + FT_UNUSED( face ); + FT_UNUSED( langID ); + FT_UNUSED( alangTag ); + + return FT_THROW( Unimplemented_Feature ); + } + + +#endif /* !TT_CONFIG_OPTION_SFNT_NAMES */ /* END */ diff --git a/sdk/lib/3rdparty/freetype/src/base/ftstream.c b/sdk/lib/3rdparty/freetype/src/base/ftstream.c index 18df7dcfef696..4b0890d7fd5cc 100644 --- a/sdk/lib/3rdparty/freetype/src/base/ftstream.c +++ b/sdk/lib/3rdparty/freetype/src/base/ftstream.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftstream.c */ -/* */ -/* I/O stream support (body). */ -/* */ -/* Copyright 2000-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftstream.c + * + * I/O stream support (body). + * + * Copyright (C) 2000-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -21,14 +21,14 @@ #include FT_INTERNAL_DEBUG_H - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_stream +#define FT_COMPONENT stream FT_BASE_DEF( void ) @@ -219,13 +219,14 @@ { FT_Memory memory = stream->memory; + #ifdef FT_DEBUG_MEMORY ft_mem_free( memory, *pbytes ); - *pbytes = NULL; #else FT_FREE( *pbytes ); #endif } + *pbytes = NULL; } @@ -238,6 +239,8 @@ FT_ULong read_bytes; + FT_TRACE7(( "FT_Stream_EnterFrame: %ld bytes\n", count )); + /* check for nested frame access */ FT_ASSERT( stream && stream->cursor == 0 ); @@ -281,6 +284,7 @@ FT_FREE( stream->base ); error = FT_THROW( Invalid_Stream_Operation ); } + stream->cursor = stream->base; stream->limit = stream->cursor + count; stream->pos += read_bytes; @@ -321,13 +325,16 @@ /* In this case, the loader code handles the 0-length table */ /* gracefully; however, stream.cursor is really set to 0 by the */ /* FT_Stream_EnterFrame() call, and this is not an error. */ - /* */ + + FT_TRACE7(( "FT_Stream_ExitFrame\n" )); + FT_ASSERT( stream ); if ( stream->read ) { FT_Memory memory = stream->memory; + #ifdef FT_DEBUG_MEMORY ft_mem_free( memory, stream->base ); stream->base = NULL; @@ -335,6 +342,7 @@ FT_FREE( stream->base ); #endif } + stream->cursor = NULL; stream->limit = NULL; } diff --git a/sdk/lib/3rdparty/freetype/src/base/ftstroke.c b/sdk/lib/3rdparty/freetype/src/base/ftstroke.c index 6ae1819067936..826062c94ec11 100644 --- a/sdk/lib/3rdparty/freetype/src/base/ftstroke.c +++ b/sdk/lib/3rdparty/freetype/src/base/ftstroke.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftstroke.c */ -/* */ -/* FreeType path stroker (body). */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftstroke.c + * + * FreeType path stroker (body). + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -24,15 +24,10 @@ #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_OBJECTS_H -#include "basepic.h" - - /* declare an extern to access `ft_outline_glyph_class' globally */ - /* allocated in `ftglyph.c', and use the FT_OUTLINE_GLYPH_CLASS_GET */ - /* macro to access it when FT_CONFIG_OPTION_PIC is defined */ -#ifndef FT_CONFIG_OPTION_PIC + /* declare an extern to access `ft_outline_glyph_class' globally */ + /* allocated in `ftglyph.c' */ FT_CALLBACK_TABLE const FT_Glyph_Class ft_outline_glyph_class; -#endif /* documentation is in ftstroke.h */ @@ -372,6 +367,7 @@ /* it contains the `adjusted' starting coordinates */ border->num_points = --count; border->points[start] = border->points[count]; + border->tags[start] = border->tags[count]; if ( reverse ) { @@ -436,8 +432,8 @@ } else { - /* don't add zero-length lineto */ - if ( border->num_points > 0 && + /* don't add zero-length lineto, but always add moveto */ + if ( border->num_points > (FT_UInt)border->start && FT_IS_SMALL( border->points[border->num_points - 1].x - to->x ) && FT_IS_SMALL( border->points[border->num_points - 1].y - to->y ) ) return error; @@ -2087,8 +2083,8 @@ /* documentation is in ftstroke.h */ /* - * The following is very similar to FT_Outline_Decompose, except - * that we do support opened paths, and do not scale the outline. + * The following is very similar to FT_Outline_Decompose, except + * that we do support opened paths, and do not scale the outline. */ FT_EXPORT_DEF( FT_Error ) FT_Stroker_ParseOutline( FT_Stroker stroker, @@ -2306,17 +2302,12 @@ FT_Error error = FT_ERR( Invalid_Argument ); FT_Glyph glyph = NULL; - /* for FT_OUTLINE_GLYPH_CLASS_GET (in PIC mode) */ - FT_Library library = stroker->library; - - FT_UNUSED( library ); - if ( !pglyph ) goto Exit; glyph = *pglyph; - if ( !glyph || glyph->clazz != FT_OUTLINE_GLYPH_CLASS_GET ) + if ( !glyph || glyph->clazz != &ft_outline_glyph_class ) goto Exit; { @@ -2386,17 +2377,12 @@ FT_Error error = FT_ERR( Invalid_Argument ); FT_Glyph glyph = NULL; - /* for FT_OUTLINE_GLYPH_CLASS_GET (in PIC mode) */ - FT_Library library = stroker->library; - - FT_UNUSED( library ); - if ( !pglyph ) goto Exit; glyph = *pglyph; - if ( !glyph || glyph->clazz != FT_OUTLINE_GLYPH_CLASS_GET ) + if ( !glyph || glyph->clazz != &ft_outline_glyph_class ) goto Exit; { diff --git a/sdk/lib/3rdparty/freetype/src/base/ftsynth.c b/sdk/lib/3rdparty/freetype/src/base/ftsynth.c index c28346707bd35..f87ed65e751b2 100644 --- a/sdk/lib/3rdparty/freetype/src/base/ftsynth.c +++ b/sdk/lib/3rdparty/freetype/src/base/ftsynth.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftsynth.c */ -/* */ -/* FreeType synthesizing code for emboldening and slanting (body). */ -/* */ -/* Copyright 2000-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftsynth.c + * + * FreeType synthesizing code for emboldening and slanting (body). + * + * Copyright (C) 2000-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -24,14 +24,14 @@ #include FT_BITMAP_H - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_synth +#define FT_COMPONENT synth /*************************************************************************/ diff --git a/sdk/lib/3rdparty/freetype/src/base/ftsystem.c b/sdk/lib/3rdparty/freetype/src/base/ftsystem.c index 6adebdb938366..f92b3a03d5826 100644 --- a/sdk/lib/3rdparty/freetype/src/base/ftsystem.c +++ b/sdk/lib/3rdparty/freetype/src/base/ftsystem.c @@ -1,28 +1,28 @@ -/***************************************************************************/ -/* */ -/* ftsystem.c */ -/* */ -/* ANSI-specific FreeType low-level system interface (body). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - /*************************************************************************/ - /* */ - /* This file contains the default interface used by FreeType to access */ - /* low-level, i.e. memory management, i/o access as well as thread */ - /* synchronisation. It can be replaced by user-specific routines if */ - /* necessary. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * ftsystem.c + * + * ANSI-specific FreeType low-level system interface (body). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + /************************************************************************** + * + * This file contains the default interface used by FreeType to access + * low-level, i.e. memory management, i/o access as well as thread + * synchronisation. It can be replaced by user-specific routines if + * necessary. + * + */ #include <ft2build.h> @@ -34,37 +34,39 @@ #include FT_TYPES_H - /*************************************************************************/ - /* */ - /* MEMORY MANAGEMENT INTERFACE */ - /* */ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* It is not necessary to do any error checking for the */ - /* allocation-related functions. This will be done by the higher level */ - /* routines like ft_mem_alloc() or ft_mem_realloc(). */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* ft_alloc */ - /* */ - /* <Description> */ - /* The memory allocation function. */ - /* */ - /* <Input> */ - /* memory :: A pointer to the memory object. */ - /* */ - /* size :: The requested size in bytes. */ - /* */ - /* <Return> */ - /* The address of newly allocated block. */ - /* */ + /************************************************************************** + * + * MEMORY MANAGEMENT INTERFACE + * + */ + + /************************************************************************** + * + * It is not necessary to do any error checking for the + * allocation-related functions. This will be done by the higher level + * routines like ft_mem_alloc() or ft_mem_realloc(). + * + */ + + + /************************************************************************** + * + * @Function: + * ft_alloc + * + * @Description: + * The memory allocation function. + * + * @Input: + * memory :: + * A pointer to the memory object. + * + * size :: + * The requested size in bytes. + * + * @Return: + * The address of newly allocated block. + */ FT_CALLBACK_DEF( void* ) ft_alloc( FT_Memory memory, long size ) @@ -75,26 +77,30 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* ft_realloc */ - /* */ - /* <Description> */ - /* The memory reallocation function. */ - /* */ - /* <Input> */ - /* memory :: A pointer to the memory object. */ - /* */ - /* cur_size :: The current size of the allocated memory block. */ - /* */ - /* new_size :: The newly requested size in bytes. */ - /* */ - /* block :: The current address of the block in memory. */ - /* */ - /* <Return> */ - /* The address of the reallocated memory block. */ - /* */ + /************************************************************************** + * + * @Function: + * ft_realloc + * + * @Description: + * The memory reallocation function. + * + * @Input: + * memory :: + * A pointer to the memory object. + * + * cur_size :: + * The current size of the allocated memory block. + * + * new_size :: + * The newly requested size in bytes. + * + * block :: + * The current address of the block in memory. + * + * @Return: + * The address of the reallocated memory block. + */ FT_CALLBACK_DEF( void* ) ft_realloc( FT_Memory memory, long cur_size, @@ -108,19 +114,21 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* ft_free */ - /* */ - /* <Description> */ - /* The memory release function. */ - /* */ - /* <Input> */ - /* memory :: A pointer to the memory object. */ - /* */ - /* block :: The address of block in memory to be freed. */ - /* */ + /************************************************************************** + * + * @Function: + * ft_free + * + * @Description: + * The memory release function. + * + * @Input: + * memory :: + * A pointer to the memory object. + * + * block :: + * The address of block in memory to be freed. + */ FT_CALLBACK_DEF( void ) ft_free( FT_Memory memory, void* block ) @@ -131,39 +139,40 @@ } - /*************************************************************************/ - /* */ - /* RESOURCE MANAGEMENT INTERFACE */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * RESOURCE MANAGEMENT INTERFACE + * + */ #ifndef FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_io +#define FT_COMPONENT io /* We use the macro STREAM_FILE for convenience to extract the */ /* system-specific stream handle from a given FreeType stream object */ #define STREAM_FILE( stream ) ( (FT_FILE*)stream->descriptor.pointer ) - /*************************************************************************/ - /* */ - /* <Function> */ - /* ft_ansi_stream_close */ - /* */ - /* <Description> */ - /* The function to close a stream. */ - /* */ - /* <Input> */ - /* stream :: A pointer to the stream object. */ - /* */ + /************************************************************************** + * + * @Function: + * ft_ansi_stream_close + * + * @Description: + * The function to close a stream. + * + * @Input: + * stream :: + * A pointer to the stream object. + */ FT_CALLBACK_DEF( void ) ft_ansi_stream_close( FT_Stream stream ) { @@ -175,28 +184,32 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* ft_ansi_stream_io */ - /* */ - /* <Description> */ - /* The function to open a stream. */ - /* */ - /* <Input> */ - /* stream :: A pointer to the stream object. */ - /* */ - /* offset :: The position in the data stream to start reading. */ - /* */ - /* buffer :: The address of buffer to store the read data. */ - /* */ - /* count :: The number of bytes to read from the stream. */ - /* */ - /* <Return> */ - /* The number of bytes actually read. If `count' is zero (this is, */ - /* the function is used for seeking), a non-zero return value */ - /* indicates an error. */ - /* */ + /************************************************************************** + * + * @Function: + * ft_ansi_stream_io + * + * @Description: + * The function to open a stream. + * + * @Input: + * stream :: + * A pointer to the stream object. + * + * offset :: + * The position in the data stream to start reading. + * + * buffer :: + * The address of buffer to store the read data. + * + * count :: + * The number of bytes to read from the stream. + * + * @Return: + * The number of bytes actually read. If `count' is zero (this is, + * the function is used for seeking), a non-zero return value + * indicates an error. + */ FT_CALLBACK_DEF( unsigned long ) ft_ansi_stream_io( FT_Stream stream, unsigned long offset, diff --git a/sdk/lib/3rdparty/freetype/src/base/fttrigon.c b/sdk/lib/3rdparty/freetype/src/base/fttrigon.c index d6dd098c426a6..38721977c783c 100644 --- a/sdk/lib/3rdparty/freetype/src/base/fttrigon.c +++ b/sdk/lib/3rdparty/freetype/src/base/fttrigon.c @@ -1,33 +1,33 @@ -/***************************************************************************/ -/* */ -/* fttrigon.c */ -/* */ -/* FreeType trigonometric functions (body). */ -/* */ -/* Copyright 2001-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - /*************************************************************************/ - /* */ - /* This is a fixed-point CORDIC implementation of trigonometric */ - /* functions as well as transformations between Cartesian and polar */ - /* coordinates. The angles are represented as 16.16 fixed-point values */ - /* in degrees, i.e., the angular resolution is 2^-16 degrees. Note that */ - /* only vectors longer than 2^16*180/pi (or at least 22 bits) on a */ - /* discrete Cartesian grid can have the same or better angular */ - /* resolution. Therefore, to maintain this precision, some functions */ - /* require an interim upscaling of the vectors, whereas others operate */ - /* with 24-bit long vectors directly. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * fttrigon.c + * + * FreeType trigonometric functions (body). + * + * Copyright (C) 2001-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + /************************************************************************** + * + * This is a fixed-point CORDIC implementation of trigonometric + * functions as well as transformations between Cartesian and polar + * coordinates. The angles are represented as 16.16 fixed-point values + * in degrees, i.e., the angular resolution is 2^-16 degrees. Note that + * only vectors longer than 2^16*180/pi (or at least 22 bits) on a + * discrete Cartesian grid can have the same or better angular + * resolution. Therefore, to maintain this precision, some functions + * require an interim upscaling of the vectors, whereas others operate + * with 24-bit long vectors directly. + * + */ #include <ft2build.h> #include FT_INTERNAL_OBJECTS_H @@ -325,10 +325,10 @@ FT_EXPORT_DEF( FT_Fixed ) FT_Tan( FT_Angle angle ) { - FT_Vector v; + FT_Vector v = { 1 << 24, 0 }; - FT_Vector_Unit( &v, angle ); + ft_trig_pseudo_rotate( &v, angle ); return FT_DivFix( v.y, v.x ); } @@ -372,14 +372,6 @@ } - /* these macros return 0 for positive numbers, - and -1 for negative ones */ -#define FT_SIGN_LONG( x ) ( (x) >> ( FT_SIZEOF_LONG * 8 - 1 ) ) -#define FT_SIGN_INT( x ) ( (x) >> ( FT_SIZEOF_INT * 8 - 1 ) ) -#define FT_SIGN_INT32( x ) ( (x) >> 31 ) -#define FT_SIGN_INT16( x ) ( (x) >> 15 ) - - /* documentation is in fttrigon.h */ FT_EXPORT_DEF( void ) @@ -408,8 +400,8 @@ FT_Int32 half = (FT_Int32)1L << ( shift - 1 ); - vec->x = ( v.x + half + FT_SIGN_LONG( v.x ) ) >> shift; - vec->y = ( v.y + half + FT_SIGN_LONG( v.y ) ) >> shift; + vec->x = ( v.x + half - ( v.x < 0 ) ) >> shift; + vec->y = ( v.y + half - ( v.y < 0 ) ) >> shift; } else { diff --git a/sdk/lib/3rdparty/freetype/src/base/fttype1.c b/sdk/lib/3rdparty/freetype/src/base/fttype1.c index aa8f8ccbbb4d7..26d4f1c3a8aaa 100644 --- a/sdk/lib/3rdparty/freetype/src/base/fttype1.c +++ b/sdk/lib/3rdparty/freetype/src/base/fttype1.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* fttype1.c */ -/* */ -/* FreeType utility file for PS names support (body). */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * fttype1.c + * + * FreeType utility file for PS names support (body). + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> diff --git a/sdk/lib/3rdparty/freetype/src/base/ftutil.c b/sdk/lib/3rdparty/freetype/src/base/ftutil.c index 4de5f2c145d93..92bd857e92238 100644 --- a/sdk/lib/3rdparty/freetype/src/base/ftutil.c +++ b/sdk/lib/3rdparty/freetype/src/base/ftutil.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftutil.c */ -/* */ -/* FreeType utility file for memory and list management (body). */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftutil.c + * + * FreeType utility file for memory and list management (body). + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -23,14 +23,14 @@ #include FT_LIST_H - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_memory +#define FT_COMPONENT memory /*************************************************************************/ @@ -54,7 +54,7 @@ FT_Error error; FT_Pointer block = ft_mem_qalloc( memory, size, &error ); - if ( !error && size > 0 ) + if ( !error && block && size > 0 ) FT_MEM_ZERO( block, size ); *p_error = error; @@ -101,7 +101,7 @@ block = ft_mem_qrealloc( memory, item_size, cur_count, new_count, block, &error ); - if ( !error && new_count > cur_count ) + if ( !error && block && new_count > cur_count ) FT_MEM_ZERO( (char*)block + cur_count * item_size, ( new_count - cur_count ) * item_size ); @@ -185,7 +185,7 @@ FT_Pointer p = ft_mem_qalloc( memory, (FT_Long)size, &error ); - if ( !error && address ) + if ( !error && address && size > 0 ) ft_memcpy( p, address, size ); *p_error = error; @@ -236,7 +236,7 @@ /*************************************************************************/ #undef FT_COMPONENT -#define FT_COMPONENT trace_list +#define FT_COMPONENT list /* documentation is in ftlist.h */ diff --git a/sdk/lib/3rdparty/freetype/src/base/ftwinfnt.c b/sdk/lib/3rdparty/freetype/src/base/ftwinfnt.c index 11bd28afb7a3d..59daa77031c16 100644 --- a/sdk/lib/3rdparty/freetype/src/base/ftwinfnt.c +++ b/sdk/lib/3rdparty/freetype/src/base/ftwinfnt.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftwinfnt.c */ -/* */ -/* FreeType API for accessing Windows FNT specific info (body). */ -/* */ -/* Copyright 2003-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftwinfnt.c + * + * FreeType API for accessing Windows FNT specific info (body). + * + * Copyright (C) 2003-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> diff --git a/sdk/lib/3rdparty/freetype/src/bdf/bdf.h b/sdk/lib/3rdparty/freetype/src/bdf/bdf.h index 9012727c7ecf6..4018756f72304 100644 --- a/sdk/lib/3rdparty/freetype/src/bdf/bdf.h +++ b/sdk/lib/3rdparty/freetype/src/bdf/bdf.h @@ -51,11 +51,11 @@ FT_BEGIN_HEADER /* end of bdfP.h */ - /*************************************************************************/ - /* */ - /* BDF font options macros and types. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * BDF font options macros and types. + * + */ #define BDF_CORRECT_METRICS 0x01 /* Correct invalid metrics when loading. */ @@ -93,11 +93,11 @@ FT_BEGIN_HEADER void* client_data ); - /*************************************************************************/ - /* */ - /* BDF font property macros and types. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * BDF font property macros and types. + * + */ #define BDF_ATOM 1 @@ -123,11 +123,11 @@ FT_BEGIN_HEADER } bdf_property_t; - /*************************************************************************/ - /* */ - /* BDF font metric and glyph types. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * BDF font metric and glyph types. + * + */ typedef struct bdf_bbx_t_ @@ -147,7 +147,7 @@ FT_BEGIN_HEADER typedef struct bdf_glyph_t_ { char* name; /* Glyph name. */ - long encoding; /* Glyph encoding. */ + unsigned long encoding; /* Glyph encoding. */ unsigned short swidth; /* Scalable width. */ unsigned short dwidth; /* Device width. */ bdf_bbx_t bbx; /* Glyph bounding box. */ @@ -158,20 +158,6 @@ FT_BEGIN_HEADER } bdf_glyph_t; - typedef struct bdf_glyphlist_t_ - { - unsigned short pad; /* Pad to 4-byte boundary. */ - unsigned short bpp; /* Bits per pixel. */ - long start; /* Beginning encoding value of glyphs. */ - long end; /* Ending encoding value of glyphs. */ - bdf_glyph_t* glyphs; /* Glyphs themselves. */ - unsigned long glyphs_size; /* Glyph structures allocated. */ - unsigned long glyphs_used; /* Glyph structures used. */ - bdf_bbx_t bbx; /* Overall bounding box of glyphs. */ - - } bdf_glyphlist_t; - - typedef struct bdf_font_t_ { char* name; /* Name of the font. */ @@ -185,7 +171,7 @@ FT_BEGIN_HEADER unsigned short monowidth; /* Logical width for monowidth font. */ - long default_char; /* Encoding of the default glyph. */ + unsigned long default_char; /* Encoding of the default glyph. */ long font_ascent; /* Font ascent. */ long font_descent; /* Font descent. */ @@ -205,16 +191,8 @@ FT_BEGIN_HEADER char* comments; /* Font comments. */ unsigned long comments_len; /* Length of comment string. */ - bdf_glyphlist_t overflow; /* Storage used for glyph insertion. */ - void* internal; /* Internal data for the font. */ - /* The size of the next two arrays must be in sync with the */ - /* size of the `have' array in the `bdf_parse_t' structure. */ - unsigned long nmod[34816]; /* Bitmap indicating modified glyphs. */ - unsigned long umod[34816]; /* Bitmap indicating modified */ - /* unencoded glyphs. */ - unsigned short modified; /* Boolean indicating font modified. */ unsigned short bpp; /* Bits per pixel. */ FT_Memory memory; @@ -226,11 +204,11 @@ FT_BEGIN_HEADER } bdf_font_t; - /*************************************************************************/ - /* */ - /* Types for load/save callbacks. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * Types for load/save callbacks. + * + */ /* Error codes. */ @@ -247,11 +225,11 @@ FT_BEGIN_HEADER #define BDF_INVALID_LINE -100 - /*************************************************************************/ - /* */ - /* BDF font API. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * BDF font API. + * + */ FT_LOCAL( FT_Error ) bdf_load_font( FT_Stream stream, diff --git a/sdk/lib/3rdparty/freetype/src/bdf/bdfdrivr.c b/sdk/lib/3rdparty/freetype/src/bdf/bdfdrivr.c index ca937f89ce33b..4a11843a1cbff 100644 --- a/sdk/lib/3rdparty/freetype/src/bdf/bdfdrivr.c +++ b/sdk/lib/3rdparty/freetype/src/bdf/bdfdrivr.c @@ -41,14 +41,14 @@ THE SOFTWARE. #include "bdferror.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_bdfdriver +#define FT_COMPONENT bdfdriver typedef struct BDF_CMapRec_ @@ -99,14 +99,17 @@ THE SOFTWARE. min = 0; max = cmap->num_encodings; + mid = ( min + max ) >> 1; while ( min < max ) { FT_ULong code; - mid = ( min + max ) >> 1; - code = (FT_ULong)encodings[mid].enc; + if ( mid > max || mid < min ) + mid = ( min + max ) >> 1; + + code = encodings[mid].enc; if ( charcode == code ) { @@ -120,6 +123,9 @@ THE SOFTWARE. max = mid; else min = mid + 1; + + /* prediction in a continuous block */ + mid += charcode - code; } return result; @@ -139,14 +145,17 @@ THE SOFTWARE. min = 0; max = cmap->num_encodings; + mid = ( min + max ) >> 1; while ( min < max ) { FT_ULong code; /* same as BDF_encoding_el.enc */ - mid = ( min + max ) >> 1; - code = (FT_ULong)encodings[mid].enc; + if ( mid > max || mid < min ) + mid = ( min + max ) >> 1; + + code = encodings[mid].enc; if ( charcode == code ) { @@ -160,12 +169,15 @@ THE SOFTWARE. max = mid; else min = mid + 1; + + /* prediction in a continuous block */ + mid += charcode - code; } charcode = 0; if ( min < cmap->num_encodings ) { - charcode = (FT_ULong)encodings[min].enc; + charcode = encodings[min].enc; result = encodings[min].glyph + 1; } @@ -401,8 +413,7 @@ THE SOFTWARE. bdfface->face_index = 0; bdfface->face_flags |= FT_FACE_FLAG_FIXED_SIZES | - FT_FACE_FLAG_HORIZONTAL | - FT_FACE_FLAG_FAST_GLYPHS; + FT_FACE_FLAG_HORIZONTAL; prop = bdf_get_font_property( font, "SPACING" ); if ( prop && prop->format == BDF_ATOM && @@ -863,7 +874,7 @@ THE SOFTWARE. /* * - * BDF SERVICE + * BDF SERVICE * */ @@ -939,7 +950,7 @@ THE SOFTWARE. /* * - * SERVICES LIST + * SERVICES LIST * */ diff --git a/sdk/lib/3rdparty/freetype/src/bdf/bdfdrivr.h b/sdk/lib/3rdparty/freetype/src/bdf/bdfdrivr.h index 94550818c1195..b37b84ea31f69 100644 --- a/sdk/lib/3rdparty/freetype/src/bdf/bdfdrivr.h +++ b/sdk/lib/3rdparty/freetype/src/bdf/bdfdrivr.h @@ -36,14 +36,10 @@ THE SOFTWARE. FT_BEGIN_HEADER -#ifdef FT_CONFIG_OPTION_PIC -#error "this module does not support PIC yet" -#endif - typedef struct BDF_encoding_el_ { - FT_Long enc; + FT_ULong enc; FT_UShort glyph; } BDF_encoding_el; @@ -60,9 +56,6 @@ FT_BEGIN_HEADER BDF_encoding_el* en_table; - FT_CharMap charmap_handle; - FT_CharMapRec charmap; /* a single charmap per face */ - FT_UInt default_glyph; } BDF_FaceRec, *BDF_Face; diff --git a/sdk/lib/3rdparty/freetype/src/bdf/bdferror.h b/sdk/lib/3rdparty/freetype/src/bdf/bdferror.h index b462c7d3b5c35..dbe41c02ab181 100644 --- a/sdk/lib/3rdparty/freetype/src/bdf/bdferror.h +++ b/sdk/lib/3rdparty/freetype/src/bdf/bdferror.h @@ -20,11 +20,11 @@ * THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - /*************************************************************************/ - /* */ - /* This file is used to define the BDF error enumeration constants. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * This file is used to define the BDF error enumeration constants. + * + */ #ifndef BDFERROR_H_ #define BDFERROR_H_ diff --git a/sdk/lib/3rdparty/freetype/src/bdf/bdflib.c b/sdk/lib/3rdparty/freetype/src/bdf/bdflib.c index 2f5c99d5448a4..0898b0d470d9a 100644 --- a/sdk/lib/3rdparty/freetype/src/bdf/bdflib.c +++ b/sdk/lib/3rdparty/freetype/src/bdf/bdflib.c @@ -22,13 +22,13 @@ * THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - /*************************************************************************/ - /* */ - /* This file is based on bdf.c,v 1.22 2000/03/16 20:08:50 */ - /* */ - /* taken from Mark Leisher's xmbdfed package */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * This file is based on bdf.c,v 1.22 2000/03/16 20:08:50 + * + * taken from Mark Leisher's xmbdfed package + * + */ #include <ft2build.h> @@ -42,21 +42,21 @@ #include "bdferror.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_bdflib +#define FT_COMPONENT bdflib - /*************************************************************************/ - /* */ - /* Default BDF font options. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * Default BDF font options. + * + */ static const bdf_options_t _bdf_opts = @@ -68,11 +68,11 @@ }; - /*************************************************************************/ - /* */ - /* Builtin BDF font properties. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * Builtin BDF font properties. + * + */ /* List of most properties that might appear in a font. Doesn't include */ /* the RAW_* and AXIS_* properties in X11R6 polymorphic fonts. */ @@ -196,11 +196,10 @@ #define ACMSG9 "SWIDTH field missing at line %ld. Set automatically.\n" #define ACMSG10 "DWIDTH field missing at line %ld. Set to glyph width.\n" #define ACMSG11 "SIZE bits per pixel field adjusted to %hd.\n" -#define ACMSG12 "Duplicate encoding %ld (%s) changed to unencoded.\n" -#define ACMSG13 "Glyph %ld extra rows removed.\n" -#define ACMSG14 "Glyph %ld extra columns removed.\n" +#define ACMSG13 "Glyph %lu extra rows removed.\n" +#define ACMSG14 "Glyph %lu extra columns removed.\n" #define ACMSG15 "Incorrect glyph count: %ld indicated but %ld found.\n" -#define ACMSG16 "Glyph %ld missing columns padded with zero bits.\n" +#define ACMSG16 "Glyph %lu missing columns padded with zero bits.\n" #define ACMSG17 "Adjusting number of glyphs to %ld.\n" /* Error messages. */ @@ -219,11 +218,11 @@ #define DBGMSG2 " (0x%lX)\n" - /*************************************************************************/ - /* */ - /* Utility types and functions. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * Utility types and functions. + * + */ /* Function type for parsing lines of a BDF font. */ @@ -270,8 +269,6 @@ bdf_font_t* font; bdf_options_t* opts; - unsigned long have[34816]; /* must be in sync with `nmod' and `umod' */ - /* arrays from `bdf_font_t' structure */ _bdf_list_t list; FT_Memory memory; @@ -900,11 +897,11 @@ } - /*************************************************************************/ - /* */ - /* BDF font file parsing flags and functions. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * BDF font file parsing flags and functions. + * + */ /* Parse flags. */ @@ -1232,7 +1229,7 @@ /* present, and the SPACING property should override the default */ /* spacing. */ if ( _bdf_strncmp( name, "DEFAULT_CHAR", 12 ) == 0 ) - font->default_char = fp->value.l; + font->default_char = fp->value.ul; else if ( _bdf_strncmp( name, "FONT_ASCENT", 11 ) == 0 ) font->font_ascent = fp->value.l; else if ( _bdf_strncmp( name, "FONT_DESCENT", 12 ) == 0 ) @@ -1265,6 +1262,25 @@ }; + static FT_Error + _bdf_parse_end( char* line, + unsigned long linelen, + unsigned long lineno, + void* call_data, + void* client_data ) + { + /* a no-op; we ignore everything after `ENDFONT' */ + + FT_UNUSED( line ); + FT_UNUSED( linelen ); + FT_UNUSED( lineno ); + FT_UNUSED( call_data ); + FT_UNUSED( client_data ); + + return FT_Err_Ok; + } + + /* Actually parse the glyph info and bitmaps. */ static FT_Error _bdf_parse_glyphs( char* line, @@ -1278,6 +1294,7 @@ unsigned char* bp; unsigned long i, slen, nibbles; + _bdf_line_func_t* next; _bdf_parse_t* p; bdf_glyph_t* glyph; bdf_font_t* font; @@ -1285,11 +1302,11 @@ FT_Memory memory; FT_Error error = FT_Err_Ok; - FT_UNUSED( call_data ); FT_UNUSED( lineno ); /* only used in debug mode */ - p = (_bdf_parse_t *)client_data; + next = (_bdf_line_func_t *)call_data; + p = (_bdf_parse_t *) client_data; font = p->font; memory = font->memory; @@ -1370,6 +1387,7 @@ by_encoding ); p->flags &= ~BDF_START_; + *next = _bdf_parse_end; goto Exit; } @@ -1458,40 +1476,11 @@ if ( p->glyph_enc == -1 && p->list.used > 2 ) p->glyph_enc = _bdf_atol( p->list.field[2] ); - if ( p->glyph_enc < -1 ) + if ( p->glyph_enc < -1 || p->glyph_enc >= 0x110000L ) p->glyph_enc = -1; FT_TRACE4(( DBGMSG2, p->glyph_enc )); - /* Check that the encoding is in the Unicode range because */ - /* otherwise p->have (a bitmap with static size) overflows. */ - if ( p->glyph_enc > 0 && - (size_t)p->glyph_enc >= sizeof ( p->have ) / - sizeof ( unsigned long ) * 32 ) - { - FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG5, lineno, "ENCODING" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - /* Check whether this encoding has already been encountered. */ - /* If it has then change it to unencoded so it gets added if */ - /* indicated. */ - if ( p->glyph_enc >= 0 ) - { - if ( _bdf_glyph_modified( p->have, p->glyph_enc ) ) - { - /* Emit a message saying a glyph has been moved to the */ - /* unencoded area. */ - FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG12, - p->glyph_enc, p->glyph_name )); - p->glyph_enc = -1; - font->modified = 1; - } - else - _bdf_set_glyph_modified( p->have, p->glyph_enc ); - } - if ( p->glyph_enc >= 0 ) { /* Make sure there are enough glyphs allocated in case the */ @@ -1508,7 +1497,7 @@ glyph = font->glyphs + font->glyphs_used++; glyph->name = p->glyph_name; - glyph->encoding = p->glyph_enc; + glyph->encoding = (unsigned long)p->glyph_enc; /* Reset the initial glyph info. */ p->glyph_name = NULL; @@ -1532,7 +1521,7 @@ glyph = font->unencoded + font->unencoded_used; glyph->name = p->glyph_name; - glyph->encoding = (long)font->unencoded_used++; + glyph->encoding = font->unencoded_used++; /* Reset the initial glyph info. */ p->glyph_name = NULL; @@ -1556,6 +1545,9 @@ goto Exit; } + if ( !( p->flags & BDF_ENCODING_ ) ) + goto Missing_Encoding; + /* Point at the glyph being constructed. */ if ( p->glyph_enc == -1 ) glyph = font->unencoded + ( font->unencoded_used - 1 ); @@ -1573,7 +1565,6 @@ { FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG13, glyph->encoding )); p->flags |= BDF_GLYPH_HEIGHT_CHECK_; - font->modified = 1; } goto Exit; @@ -1601,7 +1592,6 @@ { FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG16, glyph->encoding )); p->flags |= BDF_GLYPH_WIDTH_CHECK_; - font->modified = 1; } /* Remove possible garbage at the right. */ @@ -1616,7 +1606,6 @@ { FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG14, glyph->encoding )); p->flags |= BDF_GLYPH_WIDTH_CHECK_; - font->modified = 1; } p->row++; @@ -1626,9 +1615,6 @@ /* Expect the SWIDTH (scalable width) field next. */ if ( _bdf_strncmp( line, "SWIDTH", 6 ) == 0 ) { - if ( !( p->flags & BDF_ENCODING_ ) ) - goto Missing_Encoding; - error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); if ( error ) goto Exit; @@ -1642,9 +1628,6 @@ /* Expect the DWIDTH (scalable width) field next. */ if ( _bdf_strncmp( line, "DWIDTH", 6 ) == 0 ) { - if ( !( p->flags & BDF_ENCODING_ ) ) - goto Missing_Encoding; - error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); if ( error ) goto Exit; @@ -1670,9 +1653,6 @@ /* Expect the BBX field next. */ if ( _bdf_strncmp( line, "BBX", 3 ) == 0 ) { - if ( !( p->flags & BDF_ENCODING_ ) ) - goto Missing_Encoding; - error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); if ( error ) goto Exit; @@ -1720,14 +1700,7 @@ { glyph->swidth = sw; - if ( p->glyph_enc == -1 ) - _bdf_set_glyph_modified( font->umod, - font->unencoded_used - 1 ); - else - _bdf_set_glyph_modified( font->nmod, glyph->encoding ); - p->flags |= BDF_SWIDTH_ADJ_; - font->modified = 1; } } @@ -1829,7 +1802,6 @@ goto Exit; FT_TRACE2(( "_bdf_parse_properties: " ACMSG1, p->font->bbx.ascent )); - p->font->modified = 1; } if ( bdf_get_font_property( p->font, "FONT_DESCENT" ) == 0 ) @@ -1842,7 +1814,6 @@ goto Exit; FT_TRACE2(( "_bdf_parse_properties: " ACMSG2, p->font->bbx.descent )); - p->font->modified = 1; } p->flags &= ~BDF_PROPS_; @@ -1989,7 +1960,7 @@ if ( error ) goto Exit; p->font->spacing = p->opts->font_spacing; - p->font->default_char = -1; + p->font->default_char = ~0UL; goto Exit; } @@ -2179,8 +2150,6 @@ goto Exit; FT_TRACE2(( "_bdf_parse_properties: " ACMSG2, p->font->bbx.descent )); - p->font->modified = 1; - *next = _bdf_parse_glyphs; /* A special return value. */ @@ -2196,11 +2165,11 @@ } - /*************************************************************************/ - /* */ - /* API. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * API. + * + */ FT_LOCAL_DEF( FT_Error ) @@ -2246,7 +2215,6 @@ { FT_TRACE2(( "bdf_load_font: " ACMSG15, p->cnt, p->font->glyphs_used + p->font->unencoded_used )); - p->font->modified = 1; } /* Once the font has been loaded, adjust the overall font metrics if */ @@ -2259,7 +2227,6 @@ FT_TRACE2(( "bdf_load_font: " ACMSG3, p->font->bbx.width, p->maxrb - p->minlb )); p->font->bbx.width = (unsigned short)( p->maxrb - p->minlb ); - p->font->modified = 1; } if ( p->font->bbx.x_offset != p->minlb ) @@ -2267,7 +2234,6 @@ FT_TRACE2(( "bdf_load_font: " ACMSG4, p->font->bbx.x_offset, p->minlb )); p->font->bbx.x_offset = p->minlb; - p->font->modified = 1; } if ( p->font->bbx.ascent != p->maxas ) @@ -2275,7 +2241,6 @@ FT_TRACE2(( "bdf_load_font: " ACMSG5, p->font->bbx.ascent, p->maxas )); p->font->bbx.ascent = p->maxas; - p->font->modified = 1; } if ( p->font->bbx.descent != p->maxds ) @@ -2284,7 +2249,6 @@ p->font->bbx.descent, p->maxds )); p->font->bbx.descent = p->maxds; p->font->bbx.y_offset = (short)( -p->maxds ); - p->font->modified = 1; } if ( p->maxas + p->maxds != p->font->bbx.height ) @@ -2415,16 +2379,6 @@ FT_FREE( font->glyphs ); FT_FREE( font->unencoded ); - /* Free up the overflow storage if it was used. */ - for ( i = 0, glyphs = font->overflow.glyphs; - i < font->overflow.glyphs_used; i++, glyphs++ ) - { - FT_FREE( glyphs->name ); - FT_FREE( glyphs->bitmap ); - } - - FT_FREE( font->overflow.glyphs ); - /* bdf_cleanup */ ft_hash_str_free( &(font->proptbl), memory ); diff --git a/sdk/lib/3rdparty/freetype/src/bzip2/ftbzip2.c b/sdk/lib/3rdparty/freetype/src/bzip2/ftbzip2.c index 16019485a9bfc..1fda59b60cea5 100644 --- a/sdk/lib/3rdparty/freetype/src/bzip2/ftbzip2.c +++ b/sdk/lib/3rdparty/freetype/src/bzip2/ftbzip2.c @@ -1,25 +1,25 @@ -/***************************************************************************/ -/* */ -/* ftbzip2.c */ -/* */ -/* FreeType support for .bz2 compressed files. */ -/* */ -/* This optional component relies on libbz2. It should mainly be used to */ -/* parse compressed PCF fonts, as found with many X11 server */ -/* distributions. */ -/* */ -/* Copyright 2010-2018 by */ -/* Joel Klinghed. */ -/* */ -/* based on `src/gzip/ftgzip.c' */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftbzip2.c + * + * FreeType support for .bz2 compressed files. + * + * This optional component relies on libbz2. It should mainly be used to + * parse compressed PCF fonts, as found with many X11 server + * distributions. + * + * Copyright (C) 2010-2019 by + * Joel Klinghed. + * + * based on `src/gzip/ftgzip.c' + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -43,10 +43,6 @@ #ifdef FT_CONFIG_OPTION_USE_BZIP2 -#ifdef FT_CONFIG_OPTION_PIC -#error "bzip2 code does not support PIC yet" -#endif - #define BZ_NO_STDIO /* Do not need FILE */ #include <bzlib.h> @@ -475,8 +471,8 @@ memory = source->memory; /* - * check the header right now; this prevents allocating unnecessary - * objects when we don't need them + * check the header right now; this prevents allocating unnecessary + * objects when we don't need them */ error = ft_bzip2_check_header( source ); if ( error ) diff --git a/sdk/lib/3rdparty/freetype/src/cache/ftcache.c b/sdk/lib/3rdparty/freetype/src/cache/ftcache.c index 1b425af911f81..a6a3e63ef0b2d 100644 --- a/sdk/lib/3rdparty/freetype/src/cache/ftcache.c +++ b/sdk/lib/3rdparty/freetype/src/cache/ftcache.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftcache.c */ -/* */ -/* The FreeType Caching sub-system (body only). */ -/* */ -/* Copyright 2000-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftcache.c + * + * The FreeType Caching sub-system (body only). + * + * Copyright (C) 2000-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #define FT_MAKE_OPTION_SINGLE_OBJECT diff --git a/sdk/lib/3rdparty/freetype/src/cache/ftcbasic.c b/sdk/lib/3rdparty/freetype/src/cache/ftcbasic.c index 994aa12286fb5..a473585ebcf21 100644 --- a/sdk/lib/3rdparty/freetype/src/cache/ftcbasic.c +++ b/sdk/lib/3rdparty/freetype/src/cache/ftcbasic.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftcbasic.c */ -/* */ -/* The FreeType basic cache interface (body). */ -/* */ -/* Copyright 2003-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftcbasic.c + * + * The FreeType basic cache interface (body). + * + * Copyright (C) 2003-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -27,11 +27,11 @@ #include "ftccback.h" #include "ftcerror.h" -#define FT_COMPONENT trace_cache +#define FT_COMPONENT cache /* - * Basic Families + * Basic Families * */ typedef struct FTC_BasicAttrRec_ diff --git a/sdk/lib/3rdparty/freetype/src/cache/ftccache.c b/sdk/lib/3rdparty/freetype/src/cache/ftccache.c index 12ec585a25383..f38ca44ddd3d1 100644 --- a/sdk/lib/3rdparty/freetype/src/cache/ftccache.c +++ b/sdk/lib/3rdparty/freetype/src/cache/ftccache.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftccache.c */ -/* */ -/* The FreeType internal cache interface (body). */ -/* */ -/* Copyright 2000-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftccache.c + * + * The FreeType internal cache interface (body). + * + * Copyright (C) 2000-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -25,7 +25,7 @@ #include "ftcerror.h" #undef FT_COMPONENT -#define FT_COMPONENT trace_cache +#define FT_COMPONENT cache #define FTC_HASH_MAX_LOAD 2 diff --git a/sdk/lib/3rdparty/freetype/src/cache/ftccache.h b/sdk/lib/3rdparty/freetype/src/cache/ftccache.h index 859c547e46625..140ceadb11778 100644 --- a/sdk/lib/3rdparty/freetype/src/cache/ftccache.h +++ b/sdk/lib/3rdparty/freetype/src/cache/ftccache.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftccache.h */ -/* */ -/* FreeType internal cache interface (specification). */ -/* */ -/* Copyright 2000-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftccache.h + * + * FreeType internal cache interface (specification). + * + * Copyright (C) 2000-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTCCACHE_H_ @@ -42,17 +42,17 @@ FT_BEGIN_HEADER /*************************************************************************/ /*************************************************************************/ - /*************************************************************************/ - /* */ - /* Each cache controls one or more cache nodes. Each node is part of */ - /* the global_lru list of the manager. Its `data' field however is used */ - /* as a reference count for now. */ - /* */ - /* A node can be anything, depending on the type of information held by */ - /* the cache. It can be an individual glyph image, a set of bitmaps */ - /* glyphs for a given size, some metrics, etc. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * Each cache controls one or more cache nodes. Each node is part of + * the global_lru list of the manager. Its `data' field however is used + * as a reference count for now. + * + * A node can be anything, depending on the type of information held by + * the cache. It can be an individual glyph image, a set of bitmaps + * glyphs for a given size, some metrics, etc. + * + */ /* structure size should be 20 bytes on 32-bits machines */ typedef struct FTC_NodeRec_ @@ -302,11 +302,11 @@ FT_BEGIN_HEADER * * Example: * - * { - * FTC_CACHE_TRYLOOP( cache ) - * error = load_data( ... ); - * FTC_CACHE_TRYLOOP_END() - * } + * { + * FTC_CACHE_TRYLOOP( cache ) + * error = load_data( ... ); + * FTC_CACHE_TRYLOOP_END() + * } * */ #define FTC_CACHE_TRYLOOP( cache ) \ diff --git a/sdk/lib/3rdparty/freetype/src/cache/ftccback.h b/sdk/lib/3rdparty/freetype/src/cache/ftccback.h index e51d8d6e559c0..9321bc3d4ee11 100644 --- a/sdk/lib/3rdparty/freetype/src/cache/ftccback.h +++ b/sdk/lib/3rdparty/freetype/src/cache/ftccback.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftccback.h */ -/* */ -/* Callback functions of the caching sub-system (specification only). */ -/* */ -/* Copyright 2004-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftccback.h + * + * Callback functions of the caching sub-system (specification only). + * + * Copyright (C) 2004-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTCCBACK_H_ #define FTCCBACK_H_ diff --git a/sdk/lib/3rdparty/freetype/src/cache/ftccmap.c b/sdk/lib/3rdparty/freetype/src/cache/ftccmap.c index d20b0f48fe793..76ba10e3e90ef 100644 --- a/sdk/lib/3rdparty/freetype/src/cache/ftccmap.c +++ b/sdk/lib/3rdparty/freetype/src/cache/ftccmap.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftccmap.c */ -/* */ -/* FreeType CharMap cache (body) */ -/* */ -/* Copyright 2000-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftccmap.c + * + * FreeType CharMap cache (body) + * + * Copyright (C) 2000-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -28,21 +28,21 @@ #include "ftcerror.h" #undef FT_COMPONENT -#define FT_COMPONENT trace_cache - - - /*************************************************************************/ - /* */ - /* Each FTC_CMapNode contains a simple array to map a range of character */ - /* codes to equivalent glyph indices. */ - /* */ - /* For now, the implementation is very basic: Each node maps a range of */ - /* 128 consecutive character codes to their corresponding glyph indices. */ - /* */ - /* We could do more complex things, but I don't think it is really very */ - /* useful. */ - /* */ - /*************************************************************************/ +#define FT_COMPONENT cache + + + /************************************************************************** + * + * Each FTC_CMapNode contains a simple array to map a range of character + * codes to equivalent glyph indices. + * + * For now, the implementation is very basic: Each node maps a range of + * 128 consecutive character codes to their corresponding glyph indices. + * + * We could do more complex things, but I don't think it is really very + * useful. + * + */ /* number of glyph indices / character code per node */ diff --git a/sdk/lib/3rdparty/freetype/src/cache/ftcerror.h b/sdk/lib/3rdparty/freetype/src/cache/ftcerror.h index a26cd5935bceb..e2d6417180471 100644 --- a/sdk/lib/3rdparty/freetype/src/cache/ftcerror.h +++ b/sdk/lib/3rdparty/freetype/src/cache/ftcerror.h @@ -1,27 +1,27 @@ -/***************************************************************************/ -/* */ -/* ftcerror.h */ -/* */ -/* Caching sub-system error codes (specification only). */ -/* */ -/* Copyright 2001-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to define the caching sub-system error enumeration */ - /* constants. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * ftcerror.h + * + * Caching sub-system error codes (specification only). + * + * Copyright (C) 2001-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /************************************************************************** + * + * This file is used to define the caching sub-system error enumeration + * constants. + * + */ #ifndef FTCERROR_H_ #define FTCERROR_H_ diff --git a/sdk/lib/3rdparty/freetype/src/cache/ftcglyph.c b/sdk/lib/3rdparty/freetype/src/cache/ftcglyph.c index 782cc0ed09e6e..2a0e97d4afac7 100644 --- a/sdk/lib/3rdparty/freetype/src/cache/ftcglyph.c +++ b/sdk/lib/3rdparty/freetype/src/cache/ftcglyph.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftcglyph.c */ -/* */ -/* FreeType Glyph Image (FT_Glyph) cache (body). */ -/* */ -/* Copyright 2000-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftcglyph.c + * + * FreeType Glyph Image (FT_Glyph) cache (body). + * + * Copyright (C) 2000-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> diff --git a/sdk/lib/3rdparty/freetype/src/cache/ftcglyph.h b/sdk/lib/3rdparty/freetype/src/cache/ftcglyph.h index 23c24d223f46f..5a1f0e2a74852 100644 --- a/sdk/lib/3rdparty/freetype/src/cache/ftcglyph.h +++ b/sdk/lib/3rdparty/freetype/src/cache/ftcglyph.h @@ -1,101 +1,101 @@ -/***************************************************************************/ -/* */ -/* ftcglyph.h */ -/* */ -/* FreeType abstract glyph cache (specification). */ -/* */ -/* Copyright 2000-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftcglyph.h + * + * FreeType abstract glyph cache (specification). + * + * Copyright (C) 2000-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ /* * - * FTC_GCache is an _abstract_ cache object optimized to store glyph - * data. It works as follows: + * FTC_GCache is an _abstract_ cache object optimized to store glyph + * data. It works as follows: * - * - It manages FTC_GNode objects. Each one of them can hold one or more - * glyph `items'. Item types are not specified in the FTC_GCache but - * in classes that extend it. + * - It manages FTC_GNode objects. Each one of them can hold one or more + * glyph `items'. Item types are not specified in the FTC_GCache but + * in classes that extend it. * - * - Glyph attributes, like face ID, character size, render mode, etc., - * can be grouped into abstract `glyph families'. This avoids storing - * the attributes within the FTC_GCache, since it is likely that many - * FTC_GNodes will belong to the same family in typical uses. + * - Glyph attributes, like face ID, character size, render mode, etc., + * can be grouped into abstract `glyph families'. This avoids storing + * the attributes within the FTC_GCache, since it is likely that many + * FTC_GNodes will belong to the same family in typical uses. * - * - Each FTC_GNode is thus an FTC_Node with two additional fields: + * - Each FTC_GNode is thus an FTC_Node with two additional fields: * - * * gindex: A glyph index, or the first index in a glyph range. - * * family: A pointer to a glyph `family'. + * * gindex: A glyph index, or the first index in a glyph range. + * * family: A pointer to a glyph `family'. * - * - Family types are not fully specific in the FTC_Family type, but - * by classes that extend it. + * - Family types are not fully specific in the FTC_Family type, but + * by classes that extend it. * - * Note that both FTC_ImageCache and FTC_SBitCache extend FTC_GCache. - * They share an FTC_Family sub-class called FTC_BasicFamily which is - * used to store the following data: face ID, pixel/point sizes, load - * flags. For more details see the file `src/cache/ftcbasic.c'. + * Note that both FTC_ImageCache and FTC_SBitCache extend FTC_GCache. + * They share an FTC_Family sub-class called FTC_BasicFamily which is + * used to store the following data: face ID, pixel/point sizes, load + * flags. For more details see the file `src/cache/ftcbasic.c'. * - * Client applications can extend FTC_GNode with their own FTC_GNode - * and FTC_Family sub-classes to implement more complex caches (e.g., - * handling automatic synthesis, like obliquing & emboldening, colored - * glyphs, etc.). + * Client applications can extend FTC_GNode with their own FTC_GNode + * and FTC_Family sub-classes to implement more complex caches (e.g., + * handling automatic synthesis, like obliquing & emboldening, colored + * glyphs, etc.). * - * See also the FTC_ICache & FTC_SCache classes in `ftcimage.h' and - * `ftcsbits.h', which both extend FTC_GCache with additional - * optimizations. + * See also the FTC_ICache & FTC_SCache classes in `ftcimage.h' and + * `ftcsbits.h', which both extend FTC_GCache with additional + * optimizations. * - * A typical FTC_GCache implementation must provide at least the - * following: + * A typical FTC_GCache implementation must provide at least the + * following: * - * - FTC_GNode sub-class, e.g. MyNode, with relevant methods: - * my_node_new (must call FTC_GNode_Init) - * my_node_free (must call FTC_GNode_Done) - * my_node_compare (must call FTC_GNode_Compare) - * my_node_remove_faceid (must call ftc_gnode_unselect in case - * of match) + * - FTC_GNode sub-class, e.g. MyNode, with relevant methods: + * my_node_new (must call FTC_GNode_Init) + * my_node_free (must call FTC_GNode_Done) + * my_node_compare (must call FTC_GNode_Compare) + * my_node_remove_faceid (must call ftc_gnode_unselect in case + * of match) * - * - FTC_Family sub-class, e.g. MyFamily, with relevant methods: - * my_family_compare - * my_family_init - * my_family_reset (optional) - * my_family_done + * - FTC_Family sub-class, e.g. MyFamily, with relevant methods: + * my_family_compare + * my_family_init + * my_family_reset (optional) + * my_family_done * - * - FTC_GQuery sub-class, e.g. MyQuery, to hold cache-specific query - * data. + * - FTC_GQuery sub-class, e.g. MyQuery, to hold cache-specific query + * data. * - * - Constant structures for a FTC_GNodeClass. + * - Constant structures for a FTC_GNodeClass. * - * - MyCacheNew() can be implemented easily as a call to the convenience - * function FTC_GCache_New. + * - MyCacheNew() can be implemented easily as a call to the convenience + * function FTC_GCache_New. * - * - MyCacheLookup with a call to FTC_GCache_Lookup. This function will - * automatically: + * - MyCacheLookup with a call to FTC_GCache_Lookup. This function will + * automatically: * - * - Search for the corresponding family in the cache, or create - * a new one if necessary. Put it in FTC_GQUERY(myquery).family + * - Search for the corresponding family in the cache, or create + * a new one if necessary. Put it in FTC_GQUERY(myquery).family * - * - Call FTC_Cache_Lookup. + * - Call FTC_Cache_Lookup. * - * If it returns NULL, you should create a new node, then call - * ftc_cache_add as usual. + * If it returns NULL, you should create a new node, then call + * ftc_cache_add as usual. */ - /*************************************************************************/ - /* */ - /* Important: The functions defined in this file are only used to */ - /* implement an abstract glyph cache class. You need to */ - /* provide additional logic to implement a complete cache. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * Important: The functions defined in this file are only used to + * implement an abstract glyph cache class. You need to + * provide additional logic to implement a complete cache. + * + */ /*************************************************************************/ @@ -125,11 +125,11 @@ FT_BEGIN_HEADER /* - * We can group glyphs into `families'. Each family correspond to a - * given face ID, character size, transform, etc. + * We can group glyphs into `families'. Each family correspond to a + * given face ID, character size, transform, etc. * - * Families are implemented as MRU list nodes. They are - * reference-counted. + * Families are implemented as MRU list nodes. They are + * reference-counted. */ typedef struct FTC_FamilyRec_ @@ -167,12 +167,12 @@ FT_BEGIN_HEADER #define FTC_GQUERY( x ) ( (FTC_GQuery)(x) ) - /*************************************************************************/ - /* */ - /* These functions are exported so that they can be called from */ - /* user-provided cache classes; otherwise, they are really part of the */ - /* cache sub-system internals. */ - /* */ + /************************************************************************** + * + * These functions are exported so that they can be called from + * user-provided cache classes; otherwise, they are really part of the + * cache sub-system internals. + */ /* must be called by derived FTC_Node_InitFunc routines */ FT_LOCAL( void ) diff --git a/sdk/lib/3rdparty/freetype/src/cache/ftcimage.c b/sdk/lib/3rdparty/freetype/src/cache/ftcimage.c index 77a100153e083..9e64d51a22be7 100644 --- a/sdk/lib/3rdparty/freetype/src/cache/ftcimage.c +++ b/sdk/lib/3rdparty/freetype/src/cache/ftcimage.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftcimage.c */ -/* */ -/* FreeType Image cache (body). */ -/* */ -/* Copyright 2000-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftcimage.c + * + * FreeType Image cache (body). + * + * Copyright (C) 2000-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> diff --git a/sdk/lib/3rdparty/freetype/src/cache/ftcimage.h b/sdk/lib/3rdparty/freetype/src/cache/ftcimage.h index 24a221053b01d..dcb101fabce36 100644 --- a/sdk/lib/3rdparty/freetype/src/cache/ftcimage.h +++ b/sdk/lib/3rdparty/freetype/src/cache/ftcimage.h @@ -1,35 +1,35 @@ -/***************************************************************************/ -/* */ -/* ftcimage.h */ -/* */ -/* FreeType Generic Image cache (specification) */ -/* */ -/* Copyright 2000-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftcimage.h + * + * FreeType Generic Image cache (specification) + * + * Copyright (C) 2000-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ /* - * FTC_ICache is an _abstract_ cache used to store a single FT_Glyph - * image per cache node. + * FTC_ICache is an _abstract_ cache used to store a single FT_Glyph + * image per cache node. * - * FTC_ICache extends FTC_GCache. For an implementation example, - * see FTC_ImageCache in `src/cache/ftbasic.c'. + * FTC_ICache extends FTC_GCache. For an implementation example, + * see FTC_ImageCache in `src/cache/ftbasic.c'. */ - /*************************************************************************/ - /* */ - /* Each image cache really manages FT_Glyph objects. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * Each image cache really manages FT_Glyph objects. + * + */ #ifndef FTCIMAGE_H_ diff --git a/sdk/lib/3rdparty/freetype/src/cache/ftcmanag.c b/sdk/lib/3rdparty/freetype/src/cache/ftcmanag.c index 2bcd9df50260d..bd585968e3bfd 100644 --- a/sdk/lib/3rdparty/freetype/src/cache/ftcmanag.c +++ b/sdk/lib/3rdparty/freetype/src/cache/ftcmanag.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftcmanag.c */ -/* */ -/* FreeType Cache Manager (body). */ -/* */ -/* Copyright 2000-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftcmanag.c + * + * FreeType Cache Manager (body). + * + * Copyright (C) 2000-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -26,13 +26,9 @@ #include "ftccback.h" #include "ftcerror.h" -#ifdef FT_CONFIG_OPTION_PIC -#error "cache system does not support PIC yet" -#endif - #undef FT_COMPONENT -#define FT_COMPONENT trace_cache +#define FT_COMPONENT cache static FT_Error diff --git a/sdk/lib/3rdparty/freetype/src/cache/ftcmanag.h b/sdk/lib/3rdparty/freetype/src/cache/ftcmanag.h index b4b4755356808..60c66c8fc8f4a 100644 --- a/sdk/lib/3rdparty/freetype/src/cache/ftcmanag.h +++ b/sdk/lib/3rdparty/freetype/src/cache/ftcmanag.h @@ -1,47 +1,47 @@ -/***************************************************************************/ -/* */ -/* ftcmanag.h */ -/* */ -/* FreeType Cache Manager (specification). */ -/* */ -/* Copyright 2000-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* A cache manager is in charge of the following: */ - /* */ - /* - Maintain a mapping between generic FTC_FaceIDs and live FT_Face */ - /* objects. The mapping itself is performed through a user-provided */ - /* callback. However, the manager maintains a small cache of FT_Face */ - /* and FT_Size objects in order to speed up things considerably. */ - /* */ - /* - Manage one or more cache objects. Each cache is in charge of */ - /* holding a varying number of `cache nodes'. Each cache node */ - /* represents a minimal amount of individually accessible cached */ - /* data. For example, a cache node can be an FT_Glyph image */ - /* containing a vector outline, or some glyph metrics, or anything */ - /* else. */ - /* */ - /* Each cache node has a certain size in bytes that is added to the */ - /* total amount of `cache memory' within the manager. */ - /* */ - /* All cache nodes are located in a global LRU list, where the oldest */ - /* node is at the tail of the list. */ - /* */ - /* Each node belongs to a single cache, and includes a reference */ - /* count to avoid destroying it (due to caching). */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * ftcmanag.h + * + * FreeType Cache Manager (specification). + * + * Copyright (C) 2000-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /************************************************************************** + * + * A cache manager is in charge of the following: + * + * - Maintain a mapping between generic FTC_FaceIDs and live FT_Face + * objects. The mapping itself is performed through a user-provided + * callback. However, the manager maintains a small cache of FT_Face + * and FT_Size objects in order to speed up things considerably. + * + * - Manage one or more cache objects. Each cache is in charge of + * holding a varying number of `cache nodes'. Each cache node + * represents a minimal amount of individually accessible cached + * data. For example, a cache node can be an FT_Glyph image + * containing a vector outline, or some glyph metrics, or anything + * else. + * + * Each cache node has a certain size in bytes that is added to the + * total amount of `cache memory' within the manager. + * + * All cache nodes are located in a global LRU list, where the oldest + * node is at the tail of the list. + * + * Each node belongs to a single cache, and includes a reference + * count to avoid destroying it (due to caching). + * + */ /*************************************************************************/ @@ -72,12 +72,12 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* <Section> */ - /* cache_subsystem */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * @Section: + * cache_subsystem + * + */ #define FTC_MAX_FACES_DEFAULT 2 @@ -110,27 +110,28 @@ FT_BEGIN_HEADER } FTC_ManagerRec; - /*************************************************************************/ - /* */ - /* <Function> */ - /* FTC_Manager_Compress */ - /* */ - /* <Description> */ - /* This function is used to check the state of the cache manager if */ - /* its `num_bytes' field is greater than its `max_bytes' field. It */ - /* will flush as many old cache nodes as possible (ignoring cache */ - /* nodes with a non-zero reference count). */ - /* */ - /* <InOut> */ - /* manager :: A handle to the cache manager. */ - /* */ - /* <Note> */ - /* Client applications should not call this function directly. It is */ - /* normally invoked by specific cache implementations. */ - /* */ - /* The reason this function is exported is to allow client-specific */ - /* cache classes. */ - /* */ + /************************************************************************** + * + * @Function: + * FTC_Manager_Compress + * + * @Description: + * This function is used to check the state of the cache manager if + * its `num_bytes' field is greater than its `max_bytes' field. It + * will flush as many old cache nodes as possible (ignoring cache + * nodes with a non-zero reference count). + * + * @InOut: + * manager :: + * A handle to the cache manager. + * + * @Note: + * Client applications should not call this function directly. It is + * normally invoked by specific cache implementations. + * + * The reason this function is exported is to allow client-specific + * cache classes. + */ FT_LOCAL( void ) FTC_Manager_Compress( FTC_Manager manager ); diff --git a/sdk/lib/3rdparty/freetype/src/cache/ftcmru.c b/sdk/lib/3rdparty/freetype/src/cache/ftcmru.c index 1087be4d8900c..18a7b80054547 100644 --- a/sdk/lib/3rdparty/freetype/src/cache/ftcmru.c +++ b/sdk/lib/3rdparty/freetype/src/cache/ftcmru.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftcmru.c */ -/* */ -/* FreeType MRU support (body). */ -/* */ -/* Copyright 2003-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftcmru.c + * + * FreeType MRU support (body). + * + * Copyright (C) 2003-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> diff --git a/sdk/lib/3rdparty/freetype/src/cache/ftcmru.h b/sdk/lib/3rdparty/freetype/src/cache/ftcmru.h index 82396b917d099..58721ed3409b0 100644 --- a/sdk/lib/3rdparty/freetype/src/cache/ftcmru.h +++ b/sdk/lib/3rdparty/freetype/src/cache/ftcmru.h @@ -1,43 +1,43 @@ -/***************************************************************************/ -/* */ -/* ftcmru.h */ -/* */ -/* Simple MRU list-cache (specification). */ -/* */ -/* Copyright 2000-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* An MRU is a list that cannot hold more than a certain number of */ - /* elements (`max_elements'). All elements in the list are sorted in */ - /* least-recently-used order, i.e., the `oldest' element is at the tail */ - /* of the list. */ - /* */ - /* When doing a lookup (either through `Lookup()' or `Lookup_Node()'), */ - /* the list is searched for an element with the corresponding key. If */ - /* it is found, the element is moved to the head of the list and is */ - /* returned. */ - /* */ - /* If no corresponding element is found, the lookup routine will try to */ - /* obtain a new element with the relevant key. If the list is already */ - /* full, the oldest element from the list is discarded and replaced by a */ - /* new one; a new element is added to the list otherwise. */ - /* */ - /* Note that it is possible to pre-allocate the element list nodes. */ - /* This is handy if `max_elements' is sufficiently small, as it saves */ - /* allocations/releases during the lookup process. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * ftcmru.h + * + * Simple MRU list-cache (specification). + * + * Copyright (C) 2000-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /************************************************************************** + * + * An MRU is a list that cannot hold more than a certain number of + * elements (`max_elements'). All elements in the list are sorted in + * least-recently-used order, i.e., the `oldest' element is at the tail + * of the list. + * + * When doing a lookup (either through `Lookup()' or `Lookup_Node()'), + * the list is searched for an element with the corresponding key. If + * it is found, the element is moved to the head of the list and is + * returned. + * + * If no corresponding element is found, the lookup routine will try to + * obtain a new element with the relevant key. If the list is already + * full, the oldest element from the list is discarded and replaced by a + * new one; a new element is added to the list otherwise. + * + * Note that it is possible to pre-allocate the element list nodes. + * This is handy if `max_elements' is sufficiently small, as it saves + * allocations/releases during the lookup process. + * + */ #ifndef FTCMRU_H_ diff --git a/sdk/lib/3rdparty/freetype/src/cache/ftcsbits.c b/sdk/lib/3rdparty/freetype/src/cache/ftcsbits.c index 018f1ecdb710a..06b46c896ee5a 100644 --- a/sdk/lib/3rdparty/freetype/src/cache/ftcsbits.c +++ b/sdk/lib/3rdparty/freetype/src/cache/ftcsbits.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftcsbits.c */ -/* */ -/* FreeType sbits manager (body). */ -/* */ -/* Copyright 2000-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftcsbits.c + * + * FreeType sbits manager (body). + * + * Copyright (C) 2000-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -27,7 +27,7 @@ #include "ftcerror.h" #undef FT_COMPONENT -#define FT_COMPONENT trace_cache +#define FT_COMPONENT cache /*************************************************************************/ @@ -91,14 +91,14 @@ /* - * This function tries to load a small bitmap within a given FTC_SNode. - * Note that it returns a non-zero error code _only_ in the case of - * out-of-memory condition. For all other errors (e.g., corresponding - * to a bad font file), this function will mark the sbit as `unavailable' - * and return a value of 0. + * This function tries to load a small bitmap within a given FTC_SNode. + * Note that it returns a non-zero error code _only_ in the case of + * out-of-memory condition. For all other errors (e.g., corresponding + * to a bad font file), this function will mark the sbit as `unavailable' + * and return a value of 0. * - * You should also read the comment within the @ftc_snode_compare - * function below to see how out-of-memory is handled during a lookup. + * You should also read the comment within the @ftc_snode_compare + * function below to see how out-of-memory is handled during a lookup. */ static FT_Error ftc_snode_load( FTC_SNode snode, @@ -347,34 +347,34 @@ /* - * The following code illustrates what to do when you want to - * perform operations that may fail within a lookup function. + * The following code illustrates what to do when you want to + * perform operations that may fail within a lookup function. * - * Here, we want to load a small bitmap on-demand; we thus - * need to call the `ftc_snode_load' function which may return - * a non-zero error code only when we are out of memory (OOM). + * Here, we want to load a small bitmap on-demand; we thus + * need to call the `ftc_snode_load' function which may return + * a non-zero error code only when we are out of memory (OOM). * - * The correct thing to do is to use @FTC_CACHE_TRYLOOP and - * @FTC_CACHE_TRYLOOP_END in order to implement a retry loop - * that is capable of flushing the cache incrementally when - * an OOM errors occur. + * The correct thing to do is to use @FTC_CACHE_TRYLOOP and + * @FTC_CACHE_TRYLOOP_END in order to implement a retry loop + * that is capable of flushing the cache incrementally when + * an OOM errors occur. * - * However, we need to `lock' the node before this operation to - * prevent it from being flushed within the loop. + * However, we need to `lock' the node before this operation to + * prevent it from being flushed within the loop. * - * When we exit the loop, we unlock the node, then check the `error' - * variable. If it is non-zero, this means that the cache was - * completely flushed and that no usable memory was found to load - * the bitmap. + * When we exit the loop, we unlock the node, then check the `error' + * variable. If it is non-zero, this means that the cache was + * completely flushed and that no usable memory was found to load + * the bitmap. * - * We then prefer to return a value of 0 (i.e., NO MATCH). This - * ensures that the caller will try to allocate a new node. - * This operation consequently _fail_ and the lookup function - * returns the appropriate OOM error code. + * We then prefer to return a value of 0 (i.e., NO MATCH). This + * ensures that the caller will try to allocate a new node. + * This operation consequently _fail_ and the lookup function + * returns the appropriate OOM error code. * - * Note that `buffer == NULL && width == 255' is a hack used to - * tag `unavailable' bitmaps in the array. We should never try - * to load these. + * Note that `buffer == NULL && width == 255' is a hack used to + * tag `unavailable' bitmaps in the array. We should never try + * to load these. * */ diff --git a/sdk/lib/3rdparty/freetype/src/cache/ftcsbits.h b/sdk/lib/3rdparty/freetype/src/cache/ftcsbits.h index 206a1bb3fc3ae..f1b71c2835319 100644 --- a/sdk/lib/3rdparty/freetype/src/cache/ftcsbits.h +++ b/sdk/lib/3rdparty/freetype/src/cache/ftcsbits.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftcsbits.h */ -/* */ -/* A small-bitmap cache (specification). */ -/* */ -/* Copyright 2000-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftcsbits.h + * + * A small-bitmap cache (specification). + * + * Copyright (C) 2000-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTCSBITS_H_ diff --git a/sdk/lib/3rdparty/freetype/src/cff/cff.c b/sdk/lib/3rdparty/freetype/src/cff/cff.c index 1a755d5dadd99..a34ba9b710eb0 100644 --- a/sdk/lib/3rdparty/freetype/src/cff/cff.c +++ b/sdk/lib/3rdparty/freetype/src/cff/cff.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* cff.c */ -/* */ -/* FreeType OpenType driver component (body only). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * cff.c + * + * FreeType OpenType driver component (body only). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #define FT_MAKE_OPTION_SINGLE_OBJECT @@ -23,7 +23,6 @@ #include "cffdrivr.c" #include "cffgload.c" #include "cffparse.c" -#include "cffpic.c" #include "cffload.c" #include "cffobjs.c" diff --git a/sdk/lib/3rdparty/freetype/src/cff/cffcmap.c b/sdk/lib/3rdparty/freetype/src/cff/cffcmap.c index e45ae1127bf9f..15cc94cafb0ca 100644 --- a/sdk/lib/3rdparty/freetype/src/cff/cffcmap.c +++ b/sdk/lib/3rdparty/freetype/src/cff/cffcmap.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* cffcmap.c */ -/* */ -/* CFF character mapping table (cmap) support (body). */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * cffcmap.c + * + * CFF character mapping table (cmap) support (body). + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -161,6 +161,9 @@ if ( !charset->sids ) return FT_THROW( No_Unicode_Glyph_Name ); + if ( !psnames->unicodes_init ) + return FT_THROW( Unimplemented_Feature ); + return psnames->unicodes_init( memory, unicodes, cff->num_glyphs, diff --git a/sdk/lib/3rdparty/freetype/src/cff/cffcmap.h b/sdk/lib/3rdparty/freetype/src/cff/cffcmap.h index 856a43dd1b9e9..07366bc7486d7 100644 --- a/sdk/lib/3rdparty/freetype/src/cff/cffcmap.h +++ b/sdk/lib/3rdparty/freetype/src/cff/cffcmap.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* cffcmap.h */ -/* */ -/* CFF character mapping table (cmap) support (specification). */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * cffcmap.h + * + * CFF character mapping table (cmap) support (specification). + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef CFFCMAP_H_ diff --git a/sdk/lib/3rdparty/freetype/src/cff/cffdrivr.c b/sdk/lib/3rdparty/freetype/src/cff/cffdrivr.c index df896848da450..bbd5c40329715 100644 --- a/sdk/lib/3rdparty/freetype/src/cff/cffdrivr.c +++ b/sdk/lib/3rdparty/freetype/src/cff/cffdrivr.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* cffdrivr.c */ -/* */ -/* OpenType font driver implementation (body). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * cffdrivr.c + * + * OpenType font driver implementation (body). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -42,7 +42,6 @@ #endif #include "cfferrs.h" -#include "cffpic.h" #include FT_SERVICE_FONT_FORMAT_H #include FT_SERVICE_GLYPH_DICT_H @@ -50,14 +49,14 @@ #include FT_DRIVER_H - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_cffdriver +#define FT_COMPONENT cffdriver /*************************************************************************/ @@ -73,38 +72,42 @@ /*************************************************************************/ - /*************************************************************************/ - /* */ - /* <Function> */ - /* cff_get_kerning */ - /* */ - /* <Description> */ - /* A driver method used to return the kerning vector between two */ - /* glyphs of the same face. */ - /* */ - /* <Input> */ - /* face :: A handle to the source face object. */ - /* */ - /* left_glyph :: The index of the left glyph in the kern pair. */ - /* */ - /* right_glyph :: The index of the right glyph in the kern pair. */ - /* */ - /* <Output> */ - /* kerning :: The kerning vector. This is in font units for */ - /* scalable formats, and in pixels for fixed-sizes */ - /* formats. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - /* <Note> */ - /* Only horizontal layouts (left-to-right & right-to-left) are */ - /* supported by this function. Other layouts, or more sophisticated */ - /* kernings, are out of scope of this method (the basic driver */ - /* interface is meant to be simple). */ - /* */ - /* They can be implemented by format-specific interfaces. */ - /* */ + /************************************************************************** + * + * @Function: + * cff_get_kerning + * + * @Description: + * A driver method used to return the kerning vector between two + * glyphs of the same face. + * + * @Input: + * face :: + * A handle to the source face object. + * + * left_glyph :: + * The index of the left glyph in the kern pair. + * + * right_glyph :: + * The index of the right glyph in the kern pair. + * + * @Output: + * kerning :: + * The kerning vector. This is in font units for + * scalable formats, and in pixels for fixed-sizes + * formats. + * + * @Return: + * FreeType error code. 0 means success. + * + * @Note: + * Only horizontal layouts (left-to-right & right-to-left) are + * supported by this function. Other layouts, or more sophisticated + * kernings, are out of scope of this method (the basic driver + * interface is meant to be simple). + * + * They can be implemented by format-specific interfaces. + */ FT_CALLBACK_DEF( FT_Error ) cff_get_kerning( FT_Face ttface, /* TT_Face */ FT_UInt left_glyph, @@ -125,32 +128,36 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* cff_glyph_load */ - /* */ - /* <Description> */ - /* A driver method used to load a glyph within a given glyph slot. */ - /* */ - /* <Input> */ - /* slot :: A handle to the target slot object where the glyph */ - /* will be loaded. */ - /* */ - /* size :: A handle to the source face size at which the glyph */ - /* must be scaled, loaded, etc. */ - /* */ - /* glyph_index :: The index of the glyph in the font file. */ - /* */ - /* load_flags :: A flag indicating what to load for this glyph. The */ - /* FT_LOAD_??? constants can be used to control the */ - /* glyph loading process (e.g., whether the outline */ - /* should be scaled, whether to load bitmaps or not, */ - /* whether to hint the outline, etc). */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * cff_glyph_load + * + * @Description: + * A driver method used to load a glyph within a given glyph slot. + * + * @Input: + * slot :: + * A handle to the target slot object where the glyph + * will be loaded. + * + * size :: + * A handle to the source face size at which the glyph + * must be scaled, loaded, etc. + * + * glyph_index :: + * The index of the glyph in the font file. + * + * load_flags :: + * A flag indicating what to load for this glyph. The + * FT_LOAD_??? constants can be used to control the + * glyph loading process (e.g., whether the outline + * should be scaled, whether to load bitmaps or not, + * whether to hint the outline, etc). + * + * @Return: + * FreeType error code. 0 means success. + */ FT_CALLBACK_DEF( FT_Error ) cff_glyph_load( FT_GlyphSlot cffslot, /* CFF_GlyphSlot */ FT_Size cffsize, /* CFF_Size */ @@ -302,7 +309,7 @@ /* - * GLYPH DICT SERVICE + * GLYPH DICT SERVICE * */ @@ -341,7 +348,7 @@ FT_ERROR(( "cff_get_glyph_name:" " cannot get glyph name from a CFF2 font\n" " " - " without the `PSNames' module\n" )); + " without the `psnames' module\n" )); error = FT_THROW( Missing_Module ); goto Exit; } @@ -352,7 +359,7 @@ FT_ERROR(( "cff_get_glyph_name:" " cannot get glyph name from CFF & CEF fonts\n" " " - " without the `PSNames' module\n" )); + " without the `psnames' module\n" )); error = FT_THROW( Missing_Module ); goto Exit; } @@ -408,7 +415,7 @@ FT_ERROR(( "cff_get_name_index:" " cannot get glyph index from a CFF2 font\n" " " - " without the `PSNames' module\n" )); + " without the `psnames' module\n" )); return 0; } } @@ -446,7 +453,7 @@ /* - * POSTSCRIPT INFO SERVICE + * POSTSCRIPT INFO SERVICE * */ @@ -593,7 +600,7 @@ /* - * POSTSCRIPT NAME SERVICE + * POSTSCRIPT NAME SERVICE * */ @@ -654,8 +661,8 @@ FT_Library library = FT_FACE_LIBRARY( face ); - if ( cmap->clazz != &CFF_CMAP_ENCODING_CLASS_REC_GET && - cmap->clazz != &CFF_CMAP_UNICODE_CLASS_REC_GET ) + if ( cmap->clazz != &cff_cmap_encoding_class_rec && + cmap->clazz != &cff_cmap_unicode_class_rec ) { FT_Module sfnt = FT_Get_Module( library, "sfnt" ); FT_Service_TTCMaps service = @@ -682,7 +689,7 @@ /* - * CID INFO SERVICE + * CID INFO SERVICE * */ static FT_Error @@ -788,7 +795,7 @@ goto Fail; } - if ( glyph_index > cff->num_glyphs ) + if ( glyph_index >= cff->num_glyphs ) { error = FT_THROW( Invalid_Argument ); goto Fail; @@ -818,7 +825,7 @@ /* - * PROPERTY SERVICE + * PROPERTY SERVICE * */ @@ -832,7 +839,7 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT /* - * MULTIPLE MASTER SERVICE + * MULTIPLE MASTER SERVICE * */ @@ -860,6 +867,30 @@ } + static FT_Error + cff_set_mm_weightvector( CFF_Face face, + FT_UInt len, + FT_Fixed* weightvector ) + { + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + + + return mm->set_mm_weightvector( FT_FACE( face ), len, weightvector ); + } + + + static FT_Error + cff_get_mm_weightvector( CFF_Face face, + FT_UInt* len, + FT_Fixed* weightvector ) + { + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + + + return mm->get_mm_weightvector( FT_FACE( face ), len, weightvector ); + } + + static FT_Error cff_get_mm_var( CFF_Face face, FT_MM_Var* *master ) @@ -909,22 +940,24 @@ FT_DEFINE_SERVICE_MULTIMASTERSREC( cff_service_multi_masters, - (FT_Get_MM_Func) NULL, /* get_mm */ - (FT_Set_MM_Design_Func) NULL, /* set_mm_design */ - (FT_Set_MM_Blend_Func) cff_set_mm_blend, /* set_mm_blend */ - (FT_Get_MM_Blend_Func) cff_get_mm_blend, /* get_mm_blend */ - (FT_Get_MM_Var_Func) cff_get_mm_var, /* get_mm_var */ - (FT_Set_Var_Design_Func)cff_set_var_design, /* set_var_design */ - (FT_Get_Var_Design_Func)cff_get_var_design, /* get_var_design */ - (FT_Set_Instance_Func) cff_set_instance, /* set_instance */ - - (FT_Get_Var_Blend_Func) cff_get_var_blend, /* get_var_blend */ - (FT_Done_Blend_Func) cff_done_blend /* done_blend */ + (FT_Get_MM_Func) NULL, /* get_mm */ + (FT_Set_MM_Design_Func) NULL, /* set_mm_design */ + (FT_Set_MM_Blend_Func) cff_set_mm_blend, /* set_mm_blend */ + (FT_Get_MM_Blend_Func) cff_get_mm_blend, /* get_mm_blend */ + (FT_Get_MM_Var_Func) cff_get_mm_var, /* get_mm_var */ + (FT_Set_Var_Design_Func) cff_set_var_design, /* set_var_design */ + (FT_Get_Var_Design_Func) cff_get_var_design, /* get_var_design */ + (FT_Set_Instance_Func) cff_set_instance, /* set_instance */ + (FT_Set_MM_WeightVector_Func)cff_set_mm_weightvector, /* set_mm_weightvector */ + (FT_Get_MM_WeightVector_Func)cff_get_mm_weightvector, /* get_mm_weightvector */ + + (FT_Get_Var_Blend_Func) cff_get_var_blend, /* get_var_blend */ + (FT_Done_Blend_Func) cff_done_blend /* done_blend */ ) /* - * METRICS VARIATIONS SERVICE + * METRICS VARIATIONS SERVICE * */ @@ -968,7 +1001,7 @@ /* - * CFFLOAD SERVICE + * CFFLOAD SERVICE * */ @@ -1001,54 +1034,54 @@ cff_services, FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_CFF, - FT_SERVICE_ID_MULTI_MASTERS, &CFF_SERVICE_MULTI_MASTERS_GET, - FT_SERVICE_ID_METRICS_VARIATIONS, &CFF_SERVICE_METRICS_VAR_GET, - FT_SERVICE_ID_POSTSCRIPT_INFO, &CFF_SERVICE_PS_INFO_GET, - FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET, - FT_SERVICE_ID_GLYPH_DICT, &CFF_SERVICE_GLYPH_DICT_GET, - FT_SERVICE_ID_TT_CMAP, &CFF_SERVICE_GET_CMAP_INFO_GET, - FT_SERVICE_ID_CID, &CFF_SERVICE_CID_INFO_GET, - FT_SERVICE_ID_PROPERTIES, &CFF_SERVICE_PROPERTIES_GET, - FT_SERVICE_ID_CFF_LOAD, &CFF_SERVICE_CFF_LOAD_GET + FT_SERVICE_ID_MULTI_MASTERS, &cff_service_multi_masters, + FT_SERVICE_ID_METRICS_VARIATIONS, &cff_service_metrics_variations, + FT_SERVICE_ID_POSTSCRIPT_INFO, &cff_service_ps_info, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &cff_service_ps_name, + FT_SERVICE_ID_GLYPH_DICT, &cff_service_glyph_dict, + FT_SERVICE_ID_TT_CMAP, &cff_service_get_cmap_info, + FT_SERVICE_ID_CID, &cff_service_cid_info, + FT_SERVICE_ID_PROPERTIES, &cff_service_properties, + FT_SERVICE_ID_CFF_LOAD, &cff_service_cff_load ) #elif !defined FT_CONFIG_OPTION_NO_GLYPH_NAMES FT_DEFINE_SERVICEDESCREC8( cff_services, FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_CFF, - FT_SERVICE_ID_POSTSCRIPT_INFO, &CFF_SERVICE_PS_INFO_GET, - FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET, - FT_SERVICE_ID_GLYPH_DICT, &CFF_SERVICE_GLYPH_DICT_GET, - FT_SERVICE_ID_TT_CMAP, &CFF_SERVICE_GET_CMAP_INFO_GET, - FT_SERVICE_ID_CID, &CFF_SERVICE_CID_INFO_GET, - FT_SERVICE_ID_PROPERTIES, &CFF_SERVICE_PROPERTIES_GET, - FT_SERVICE_ID_CFF_LOAD, &CFF_SERVICE_CFF_LOAD_GET + FT_SERVICE_ID_POSTSCRIPT_INFO, &cff_service_ps_info, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &cff_service_ps_name, + FT_SERVICE_ID_GLYPH_DICT, &cff_service_glyph_dict, + FT_SERVICE_ID_TT_CMAP, &cff_service_get_cmap_info, + FT_SERVICE_ID_CID, &cff_service_cid_info, + FT_SERVICE_ID_PROPERTIES, &cff_service_properties, + FT_SERVICE_ID_CFF_LOAD, &cff_service_cff_load ) #elif defined TT_CONFIG_OPTION_GX_VAR_SUPPORT FT_DEFINE_SERVICEDESCREC9( cff_services, FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_CFF, - FT_SERVICE_ID_MULTI_MASTERS, &CFF_SERVICE_MULTI_MASTERS_GET, - FT_SERVICE_ID_METRICS_VARIATIONS, &CFF_SERVICE_METRICS_VAR_GET, - FT_SERVICE_ID_POSTSCRIPT_INFO, &CFF_SERVICE_PS_INFO_GET, - FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET, - FT_SERVICE_ID_TT_CMAP, &CFF_SERVICE_GET_CMAP_INFO_GET, - FT_SERVICE_ID_CID, &CFF_SERVICE_CID_INFO_GET, - FT_SERVICE_ID_PROPERTIES, &CFF_SERVICE_PROPERTIES_GET, - FT_SERVICE_ID_CFF_LOAD, &CFF_SERVICE_CFF_LOAD_GET + FT_SERVICE_ID_MULTI_MASTERS, &cff_service_multi_masters, + FT_SERVICE_ID_METRICS_VARIATIONS, &cff_service_metrics_var, + FT_SERVICE_ID_POSTSCRIPT_INFO, &cff_service_ps_info, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &cff_service_ps_name, + FT_SERVICE_ID_TT_CMAP, &cff_service_get_cmap_info, + FT_SERVICE_ID_CID, &cff_service_cid_info, + FT_SERVICE_ID_PROPERTIES, &cff_service_properties, + FT_SERVICE_ID_CFF_LOAD, &cff_service_cff_load ) #else FT_DEFINE_SERVICEDESCREC7( cff_services, FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_CFF, - FT_SERVICE_ID_POSTSCRIPT_INFO, &CFF_SERVICE_PS_INFO_GET, - FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET, - FT_SERVICE_ID_TT_CMAP, &CFF_SERVICE_GET_CMAP_INFO_GET, - FT_SERVICE_ID_CID, &CFF_SERVICE_CID_INFO_GET, - FT_SERVICE_ID_PROPERTIES, &CFF_SERVICE_PROPERTIES_GET, - FT_SERVICE_ID_CFF_LOAD, &CFF_SERVICE_CFF_LOAD_GET + FT_SERVICE_ID_POSTSCRIPT_INFO, &cff_service_ps_info, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &cff_service_ps_name, + FT_SERVICE_ID_TT_CMAP, &cff_service_get_cmap_info, + FT_SERVICE_ID_CID, &cff_service_cid_info, + FT_SERVICE_ID_PROPERTIES, &cff_service_properties, + FT_SERVICE_ID_CFF_LOAD, &cff_service_cff_load ) #endif @@ -1062,27 +1095,16 @@ FT_Module_Interface result; - /* CFF_SERVICES_GET dereferences `library' in PIC mode */ -#ifdef FT_CONFIG_OPTION_PIC - if ( !driver ) - return NULL; - library = driver->library; - if ( !library ) - return NULL; -#endif - - result = ft_service_list_lookup( CFF_SERVICES_GET, module_interface ); + result = ft_service_list_lookup( cff_services, module_interface ); if ( result ) return result; - /* `driver' is not yet evaluated in non-PIC mode */ -#ifndef FT_CONFIG_OPTION_PIC + /* `driver' is not yet evaluated */ if ( !driver ) return NULL; library = driver->library; if ( !library ) return NULL; -#endif /* we pass our request to the `sfnt' module */ sfnt = FT_Get_Module( library, "sfnt" ); diff --git a/sdk/lib/3rdparty/freetype/src/cff/cffdrivr.h b/sdk/lib/3rdparty/freetype/src/cff/cffdrivr.h index ad7c3ad70a8f6..f2bbcfe4f11b5 100644 --- a/sdk/lib/3rdparty/freetype/src/cff/cffdrivr.h +++ b/sdk/lib/3rdparty/freetype/src/cff/cffdrivr.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* cffdrivr.h */ -/* */ -/* High-level OpenType driver interface (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * cffdrivr.h + * + * High-level OpenType driver interface (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef CFFDRIVER_H_ @@ -26,10 +26,8 @@ FT_BEGIN_HEADER - FT_DECLARE_DRIVER( cff_driver_class ) - FT_END_HEADER #endif /* CFFDRIVER_H_ */ diff --git a/sdk/lib/3rdparty/freetype/src/cff/cfferrs.h b/sdk/lib/3rdparty/freetype/src/cff/cfferrs.h index b2e1bfaf9db09..78d47a156db44 100644 --- a/sdk/lib/3rdparty/freetype/src/cff/cfferrs.h +++ b/sdk/lib/3rdparty/freetype/src/cff/cfferrs.h @@ -1,26 +1,26 @@ -/***************************************************************************/ -/* */ -/* cfferrs.h */ -/* */ -/* CFF error codes (specification only). */ -/* */ -/* Copyright 2001-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to define the CFF error enumeration constants. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * cfferrs.h + * + * CFF error codes (specification only). + * + * Copyright (C) 2001-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /************************************************************************** + * + * This file is used to define the CFF error enumeration constants. + * + */ #ifndef CFFERRS_H_ #define CFFERRS_H_ diff --git a/sdk/lib/3rdparty/freetype/src/cff/cffgload.c b/sdk/lib/3rdparty/freetype/src/cff/cffgload.c index c58471ce86113..36aa7d1b9cac0 100644 --- a/sdk/lib/3rdparty/freetype/src/cff/cffgload.c +++ b/sdk/lib/3rdparty/freetype/src/cff/cffgload.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* cffgload.c */ -/* */ -/* OpenType Glyph Loader (body). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * cffgload.c + * + * OpenType Glyph Loader (body). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -31,14 +31,14 @@ #include "cfferrs.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_cffgload +#define FT_COMPONENT cffgload FT_LOCAL_DEF( FT_Error ) @@ -280,16 +280,16 @@ glyph->root.outline.n_points = 0; glyph->root.outline.n_contours = 0; - glyph->root.metrics.width = (FT_Pos)metrics.width << 6; - glyph->root.metrics.height = (FT_Pos)metrics.height << 6; + glyph->root.metrics.width = (FT_Pos)metrics.width * 64; + glyph->root.metrics.height = (FT_Pos)metrics.height * 64; - glyph->root.metrics.horiBearingX = (FT_Pos)metrics.horiBearingX << 6; - glyph->root.metrics.horiBearingY = (FT_Pos)metrics.horiBearingY << 6; - glyph->root.metrics.horiAdvance = (FT_Pos)metrics.horiAdvance << 6; + glyph->root.metrics.horiBearingX = (FT_Pos)metrics.horiBearingX * 64; + glyph->root.metrics.horiBearingY = (FT_Pos)metrics.horiBearingY * 64; + glyph->root.metrics.horiAdvance = (FT_Pos)metrics.horiAdvance * 64; - glyph->root.metrics.vertBearingX = (FT_Pos)metrics.vertBearingX << 6; - glyph->root.metrics.vertBearingY = (FT_Pos)metrics.vertBearingY << 6; - glyph->root.metrics.vertAdvance = (FT_Pos)metrics.vertAdvance << 6; + glyph->root.metrics.vertBearingX = (FT_Pos)metrics.vertBearingX * 64; + glyph->root.metrics.vertBearingY = (FT_Pos)metrics.vertBearingY * 64; + glyph->root.metrics.vertAdvance = (FT_Pos)metrics.vertAdvance * 64; glyph->root.format = FT_GLYPH_FORMAT_BITMAP; @@ -414,7 +414,7 @@ decoder.width_only = TRUE; decoder.builder.no_recurse = - (FT_Bool)( load_flags & FT_LOAD_NO_RECURSE ); + FT_BOOL( load_flags & FT_LOAD_NO_RECURSE ); /* now load the unscaled outline */ error = cff_get_glyph_data( face, glyph_index, diff --git a/sdk/lib/3rdparty/freetype/src/cff/cffgload.h b/sdk/lib/3rdparty/freetype/src/cff/cffgload.h index 803f3974fc71e..754c55acf9e9d 100644 --- a/sdk/lib/3rdparty/freetype/src/cff/cffgload.h +++ b/sdk/lib/3rdparty/freetype/src/cff/cffgload.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* cffgload.h */ -/* */ -/* OpenType Glyph Loader (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * cffgload.h + * + * OpenType Glyph Loader (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef CFFGLOAD_H_ diff --git a/sdk/lib/3rdparty/freetype/src/cff/cffload.c b/sdk/lib/3rdparty/freetype/src/cff/cffload.c index ba49793dc8a35..12efd18dc4ba8 100644 --- a/sdk/lib/3rdparty/freetype/src/cff/cffload.c +++ b/sdk/lib/3rdparty/freetype/src/cff/cffload.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* cffload.c */ -/* */ -/* OpenType and CFF data/program tables loader (body). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * cffload.c + * + * OpenType and CFF data/program tables loader (body). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -196,14 +196,14 @@ } - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_cffload +#define FT_COMPONENT cffload /* read an offset from the index's stream current position */ @@ -1398,7 +1398,14 @@ FT_UInt master; - FT_ASSERT( lenNDV == 0 || NDV ); + /* protect against malformed fonts */ + if ( !( lenNDV == 0 || NDV ) ) + { + FT_TRACE4(( " cff_blend_build_vector:" + " Malformed Normalize Design Vector data\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } blend->builtBV = FALSE; @@ -1933,6 +1940,24 @@ else if ( priv->initial_random_seed == 0 ) priv->initial_random_seed = 987654321; + /* some sanitizing to avoid overflows later on; */ + /* the upper limits are ad-hoc values */ + if ( priv->blue_shift > 1000 || priv->blue_shift < 0 ) + { + FT_TRACE2(( "cff_load_private_dict:" + " setting unlikely BlueShift value %d to default (7)\n", + priv->blue_shift )); + priv->blue_shift = 7; + } + + if ( priv->blue_fuzz > 1000 || priv->blue_fuzz < 0 ) + { + FT_TRACE2(( "cff_load_private_dict:" + " setting unlikely BlueFuzz value %d to default (1)\n", + priv->blue_fuzz )); + priv->blue_fuzz = 1; + } + Exit: /* clean up */ cff_blend_clear( subfont ); /* clear blend stack */ @@ -2062,13 +2087,13 @@ /* * Initialize the random number generator. * - * . If we have a face-specific seed, use it. + * - If we have a face-specific seed, use it. * If non-zero, update it to a positive value. * - * . Otherwise, use the seed from the CFF driver. + * - Otherwise, use the seed from the CFF driver. * If non-zero, update it to a positive value. * - * . If the random value is zero, use the seed given by the subfont's + * - If the random value is zero, use the seed given by the subfont's * `initialRandomSeed' value. * */ diff --git a/sdk/lib/3rdparty/freetype/src/cff/cffload.h b/sdk/lib/3rdparty/freetype/src/cff/cffload.h index 14d14e21122b4..42d2696f33cf4 100644 --- a/sdk/lib/3rdparty/freetype/src/cff/cffload.h +++ b/sdk/lib/3rdparty/freetype/src/cff/cffload.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* cffload.h */ -/* */ -/* OpenType & CFF data/program tables loader (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * cffload.h + * + * OpenType & CFF data/program tables loader (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef CFFLOAD_H_ diff --git a/sdk/lib/3rdparty/freetype/src/cff/cffobjs.c b/sdk/lib/3rdparty/freetype/src/cff/cffobjs.c index a2d7aec65ef9a..1a1030c06509f 100644 --- a/sdk/lib/3rdparty/freetype/src/cff/cffobjs.c +++ b/sdk/lib/3rdparty/freetype/src/cff/cffobjs.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* cffobjs.c */ -/* */ -/* OpenType objects manager (body). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * cffobjs.c + * + * OpenType objects manager (body). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -37,7 +37,6 @@ #include "cffobjs.h" #include "cffload.h" #include "cffcmap.h" -#include "cffpic.h" #include "cfferrs.h" @@ -45,21 +44,21 @@ #include FT_SERVICE_CFF_TABLE_LOAD_H - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_cffobjs +#define FT_COMPONENT cffobjs - /*************************************************************************/ - /* */ - /* SIZE FUNCTIONS */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * SIZE FUNCTIONS + * + */ static PSH_Globals_Funcs @@ -341,11 +340,11 @@ } - /*************************************************************************/ - /* */ - /* SLOT FUNCTIONS */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * SLOT FUNCTIONS + * + */ FT_LOCAL_DEF( void ) cff_slot_done( FT_GlyphSlot slot ) @@ -383,11 +382,11 @@ } - /*************************************************************************/ - /* */ - /* FACE FUNCTIONS */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * FACE FUNCTIONS + * + */ static FT_String* cff_strcpy( FT_Memory memory, @@ -645,14 +644,14 @@ dict = &cff->top_font.font_dict; - /* we need the `PSNames' module for CFF and CEF formats */ + /* we need the `psnames' module for CFF and CEF formats */ /* which aren't CID-keyed */ if ( dict->cid_registry == 0xFFFFU && !psnames ) { FT_ERROR(( "cff_face_init:" " cannot open CFF & CEF fonts\n" " " - " without the `PSNames' module\n" )); + " without the `psnames' module\n" )); error = FT_THROW( Missing_Module ); goto Exit; } @@ -965,10 +964,10 @@ /* assume "Regular" style if we don't know better */ cffface->style_name = cff_strcpy( memory, (char *)"Regular" ); - /*******************************************************************/ - /* */ - /* Compute face flags. */ - /* */ + /******************************************************************** + * + * Compute face flags. + */ flags = FT_FACE_FLAG_SCALABLE | /* scalable outlines */ FT_FACE_FLAG_HORIZONTAL | /* horizontal data */ FT_FACE_FLAG_HINTER; /* has native hinter */ @@ -989,10 +988,10 @@ cffface->face_flags |= flags; - /*******************************************************************/ - /* */ - /* Compute style flags. */ - /* */ + /******************************************************************** + * + * Compute style flags. + */ flags = 0; if ( dict->italic_angle ) @@ -1028,10 +1027,10 @@ if ( dict->cid_registry != 0xFFFFU && pure_cff ) cffface->face_flags |= FT_FACE_FLAG_CID_KEYED; - /*******************************************************************/ - /* */ - /* Compute char maps. */ - /* */ + /******************************************************************** + * + * Compute char maps. + */ /* Try to synthesize a Unicode charmap if there is none available */ /* already. If an OpenType font contains a Unicode "cmap", we */ @@ -1070,10 +1069,11 @@ nn = (FT_UInt)cffface->num_charmaps; - error = FT_CMap_New( &CFF_CMAP_UNICODE_CLASS_REC_GET, NULL, + error = FT_CMap_New( &cff_cmap_unicode_class_rec, NULL, &cmaprec, NULL ); if ( error && - FT_ERR_NEQ( error, No_Unicode_Glyph_Name ) ) + FT_ERR_NEQ( error, No_Unicode_Glyph_Name ) && + FT_ERR_NEQ( error, Unimplemented_Feature ) ) goto Exit; error = FT_Err_Ok; @@ -1094,19 +1094,19 @@ { cmaprec.encoding_id = TT_ADOBE_ID_STANDARD; cmaprec.encoding = FT_ENCODING_ADOBE_STANDARD; - clazz = &CFF_CMAP_ENCODING_CLASS_REC_GET; + clazz = &cff_cmap_encoding_class_rec; } else if ( encoding->offset == 1 ) { cmaprec.encoding_id = TT_ADOBE_ID_EXPERT; cmaprec.encoding = FT_ENCODING_ADOBE_EXPERT; - clazz = &CFF_CMAP_ENCODING_CLASS_REC_GET; + clazz = &cff_cmap_encoding_class_rec; } else { cmaprec.encoding_id = TT_ADOBE_ID_CUSTOM; cmaprec.encoding = FT_ENCODING_ADOBE_CUSTOM; - clazz = &CFF_CMAP_ENCODING_CLASS_REC_GET; + clazz = &cff_cmap_encoding_class_rec; } error = FT_CMap_New( clazz, NULL, &cmaprec, NULL ); diff --git a/sdk/lib/3rdparty/freetype/src/cff/cffobjs.h b/sdk/lib/3rdparty/freetype/src/cff/cffobjs.h index 616a25b3b5934..03bc78a67f459 100644 --- a/sdk/lib/3rdparty/freetype/src/cff/cffobjs.h +++ b/sdk/lib/3rdparty/freetype/src/cff/cffobjs.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* cffobjs.h */ -/* */ -/* OpenType objects manager (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * cffobjs.h + * + * OpenType objects manager (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef CFFOBJS_H_ @@ -51,10 +51,10 @@ FT_BEGIN_HEADER cff_slot_init( FT_GlyphSlot slot ); - /*************************************************************************/ - /* */ - /* Face functions */ - /* */ + /************************************************************************** + * + * Face functions + */ FT_LOCAL( FT_Error ) cff_face_init( FT_Stream stream, FT_Face face, /* CFF_Face */ @@ -66,10 +66,10 @@ FT_BEGIN_HEADER cff_face_done( FT_Face face ); /* CFF_Face */ - /*************************************************************************/ - /* */ - /* Driver functions */ - /* */ + /************************************************************************** + * + * Driver functions + */ FT_LOCAL( FT_Error ) cff_driver_init( FT_Module module ); /* PS_Driver */ diff --git a/sdk/lib/3rdparty/freetype/src/cff/cffparse.c b/sdk/lib/3rdparty/freetype/src/cff/cffparse.c index b9611cf548a92..fa806f1a9059a 100644 --- a/sdk/lib/3rdparty/freetype/src/cff/cffparse.c +++ b/sdk/lib/3rdparty/freetype/src/cff/cffparse.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* cffparse.c */ -/* */ -/* CFF token stream parser (body) */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * cffparse.c + * + * CFF token stream parser (body) + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -22,20 +22,20 @@ #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_CALC_H #include FT_INTERNAL_POSTSCRIPT_AUX_H +#include FT_LIST_H #include "cfferrs.h" -#include "cffpic.h" #include "cffload.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_cffparse +#define FT_COMPONENT cffparse FT_LOCAL_DEF( FT_Error ) @@ -605,7 +605,6 @@ FT_Vector* offset = &dict->font_offset; FT_ULong* upm = &dict->units_per_em; FT_Byte** data = parser->stack; - FT_Error error = FT_ERR( Stack_Underflow ); if ( parser->top >= parser->stack + 6 ) @@ -617,8 +616,6 @@ int i; - error = FT_Err_Ok; - dict->has_font_matrix = TRUE; /* We expect a well-formed font matrix, this is, the matrix elements */ @@ -647,22 +644,11 @@ ( max_scaling - min_scaling ) < 0 || ( max_scaling - min_scaling ) > 9 ) { - /* Return default matrix in case of unlikely values. */ - FT_TRACE1(( "cff_parse_font_matrix:" " strange scaling values (minimum %d, maximum %d),\n" " " " using default matrix\n", min_scaling, max_scaling )); - - matrix->xx = 0x10000L; - matrix->yx = 0; - matrix->xy = 0; - matrix->yy = 0x10000L; - offset->x = 0; - offset->y = 0; - *upm = 1; - - goto Exit; + goto Unlikely; } for ( i = 0; i < 6; i++ ) @@ -709,10 +695,31 @@ (double)matrix->yy / *upm / 65536, (double)offset->x / *upm / 65536, (double)offset->y / *upm / 65536 )); + + if ( !FT_Matrix_Check( matrix ) ) + { + FT_TRACE1(( "cff_parse_font_matrix:" + " degenerate values, using default matrix\n" )); + goto Unlikely; + } + + return FT_Err_Ok; } + else + return FT_THROW( Stack_Underflow ); - Exit: - return error; + Unlikely: + /* Return default matrix in case of unlikely values. */ + + matrix->xx = 0x10000L; + matrix->yx = 0; + matrix->xy = 0; + matrix->yy = 0x10000L; + offset->x = 0; + offset->y = 0; + *upm = 1; + + return FT_Err_Ok; } @@ -802,7 +809,7 @@ #ifdef FT_DEBUG_LEVEL_TRACE /* beautify tracing message */ - if ( ft_trace_levels[FT_COMPONENT] < 4 ) + if ( ft_trace_levels[FT_TRACE_COMP( FT_COMPONENT )] < 4 ) FT_TRACE1(( "Multiple Master CFFs not supported yet," " handling first master design only\n" )); else @@ -1003,9 +1010,6 @@ CFF_FIELD( code, name, id, cff_kind_bool ) -#ifndef FT_CONFIG_OPTION_PIC - - #undef CFF_FIELD #undef CFF_FIELD_DELTA @@ -1118,182 +1122,16 @@ #endif /* FT_DEBUG_LEVEL_TRACE */ -#else /* FT_CONFIG_OPTION_PIC */ - - - void - FT_Destroy_Class_cff_field_handlers( FT_Library library, - CFF_Field_Handler* clazz ) +#ifdef CFF_CONFIG_OPTION_OLD_ENGINE + static void + destruct_t2s_item( FT_Memory memory, + void* data, + void* user ) { - FT_Memory memory = library->memory; - - - if ( clazz ) - FT_FREE( clazz ); + FT_UNUSED( user ); + memory->free( memory, data ); } - - - FT_Error - FT_Create_Class_cff_field_handlers( FT_Library library, - CFF_Field_Handler** output_class ) - { - CFF_Field_Handler* clazz = NULL; - FT_Error error; - FT_Memory memory = library->memory; - - int i = 0; - - -#undef CFF_FIELD -#define CFF_FIELD( code, name, id, kind ) i++; -#undef CFF_FIELD_DELTA -#define CFF_FIELD_DELTA( code, name, max, id ) i++; -#undef CFF_FIELD_CALLBACK -#define CFF_FIELD_CALLBACK( code, name, id ) i++; -#undef CFF_FIELD_BLEND -#define CFF_FIELD_BLEND( code, id ) i++; - -#include "cfftoken.h" - - i++; /* { 0, 0, 0, 0, 0, 0, 0 } */ - - if ( FT_ALLOC( clazz, sizeof ( CFF_Field_Handler ) * i ) ) - return error; - - i = 0; - - -#ifndef FT_DEBUG_LEVEL_TRACE - - -#undef CFF_FIELD_CALLBACK -#define CFF_FIELD_CALLBACK( code_, name_, id_ ) \ - clazz[i].kind = cff_kind_callback; \ - clazz[i].code = code_ | CFFCODE; \ - clazz[i].offset = 0; \ - clazz[i].size = 0; \ - clazz[i].reader = cff_parse_ ## name_; \ - clazz[i].array_max = 0; \ - clazz[i].count_offset = 0; \ - i++; - -#undef CFF_FIELD -#define CFF_FIELD( code_, name_, id_, kind_ ) \ - clazz[i].kind = kind_; \ - clazz[i].code = code_ | CFFCODE; \ - clazz[i].offset = FT_FIELD_OFFSET( name_ ); \ - clazz[i].size = FT_FIELD_SIZE( name_ ); \ - clazz[i].reader = 0; \ - clazz[i].array_max = 0; \ - clazz[i].count_offset = 0; \ - i++; \ - -#undef CFF_FIELD_DELTA -#define CFF_FIELD_DELTA( code_, name_, max_, id_ ) \ - clazz[i].kind = cff_kind_delta; \ - clazz[i].code = code_ | CFFCODE; \ - clazz[i].offset = FT_FIELD_OFFSET( name_ ); \ - clazz[i].size = FT_FIELD_SIZE_DELTA( name_ ); \ - clazz[i].reader = 0; \ - clazz[i].array_max = max_; \ - clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ ); \ - i++; - -#undef CFF_FIELD_BLEND -#define CFF_FIELD_BLEND( code_, id_ ) \ - clazz[i].kind = cff_kind_blend; \ - clazz[i].code = code_ | CFFCODE; \ - clazz[i].offset = 0; \ - clazz[i].size = 0; \ - clazz[i].reader = cff_parse_blend; \ - clazz[i].array_max = 0; \ - clazz[i].count_offset = 0; \ - i++; - -#include "cfftoken.h" - - clazz[i].kind = 0; - clazz[i].code = 0; - clazz[i].offset = 0; - clazz[i].size = 0; - clazz[i].reader = 0; - clazz[i].array_max = 0; - clazz[i].count_offset = 0; - - -#else /* FT_DEBUG_LEVEL_TRACE */ - - -#undef CFF_FIELD_CALLBACK -#define CFF_FIELD_CALLBACK( code_, name_, id_ ) \ - clazz[i].kind = cff_kind_callback; \ - clazz[i].code = code_ | CFFCODE; \ - clazz[i].offset = 0; \ - clazz[i].size = 0; \ - clazz[i].reader = cff_parse_ ## name_; \ - clazz[i].array_max = 0; \ - clazz[i].count_offset = 0; \ - clazz[i].id = id_; \ - i++; - -#undef CFF_FIELD -#define CFF_FIELD( code_, name_, id_, kind_ ) \ - clazz[i].kind = kind_; \ - clazz[i].code = code_ | CFFCODE; \ - clazz[i].offset = FT_FIELD_OFFSET( name_ ); \ - clazz[i].size = FT_FIELD_SIZE( name_ ); \ - clazz[i].reader = 0; \ - clazz[i].array_max = 0; \ - clazz[i].count_offset = 0; \ - clazz[i].id = id_; \ - i++; \ - -#undef CFF_FIELD_DELTA -#define CFF_FIELD_DELTA( code_, name_, max_, id_ ) \ - clazz[i].kind = cff_kind_delta; \ - clazz[i].code = code_ | CFFCODE; \ - clazz[i].offset = FT_FIELD_OFFSET( name_ ); \ - clazz[i].size = FT_FIELD_SIZE_DELTA( name_ ); \ - clazz[i].reader = 0; \ - clazz[i].array_max = max_; \ - clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ ); \ - clazz[i].id = id_; \ - i++; - -#undef CFF_FIELD_BLEND -#define CFF_FIELD_BLEND( code_, id_ ) \ - clazz[i].kind = cff_kind_blend; \ - clazz[i].code = code_ | CFFCODE; \ - clazz[i].offset = 0; \ - clazz[i].size = 0; \ - clazz[i].reader = cff_parse_blend; \ - clazz[i].array_max = 0; \ - clazz[i].count_offset = 0; \ - clazz[i].id = id_; \ - i++; - -#include "cfftoken.h" - - clazz[i].kind = 0; - clazz[i].code = 0; - clazz[i].offset = 0; - clazz[i].size = 0; - clazz[i].reader = 0; - clazz[i].array_max = 0; - clazz[i].count_offset = 0; - clazz[i].id = 0; - - -#endif /* FT_DEBUG_LEVEL_TRACE */ - - - *output_class = clazz; - - return FT_Err_Ok; - } - - -#endif /* FT_CONFIG_OPTION_PIC */ +#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */ FT_LOCAL_DEF( FT_Error ) @@ -1301,17 +1139,21 @@ FT_Byte* start, FT_Byte* limit ) { + FT_Byte* p = start; + FT_Error error = FT_Err_Ok; + #ifdef CFF_CONFIG_OPTION_OLD_ENGINE PSAux_Service psaux; -#endif - FT_Byte* p = start; - FT_Error error = FT_Err_Ok; FT_Library library = parser->library; + FT_Memory memory = library->memory; - FT_UNUSED( library ); + FT_ListRec t2s; + FT_ZERO( &t2s ); +#endif + parser->top = parser->stack; parser->start = start; parser->limit = limit; @@ -1321,6 +1163,7 @@ { FT_UInt v = *p; + /* Opcode 31 is legacy MM T2 operator, not a number. */ /* Opcode 255 is reserved and should not appear in fonts; */ /* it is used internally for CFF2 blends. */ @@ -1369,8 +1212,9 @@ FT_Byte* charstring_base; FT_ULong charstring_len; - FT_Fixed* stack; - FT_Byte* q; + FT_Fixed* stack; + FT_ListNode node; + FT_Byte* q; charstring_base = ++p; @@ -1405,17 +1249,29 @@ error = psaux->cff_decoder_funcs->parse_charstrings_old( &decoder, charstring_base, charstring_len, 1 ); + if ( error ) + goto Exit; /* Now copy the stack data in the temporary decoder object, */ /* converting it back to charstring number representations */ /* (this is ugly, I know). */ - /* */ - /* We overwrite the original top DICT charstring under the */ - /* assumption that the charstring representation of the result */ - /* of `cff_decoder_parse_charstrings' is shorter, which should */ - /* be always true. */ - q = charstring_base - 1; + node = (FT_ListNode)memory->alloc( memory, + sizeof ( FT_ListNodeRec ) ); + if ( !node ) + goto Out_Of_Memory_Error; + + /* `5' is the conservative upper bound of required bytes per stack */ + /* element. */ + q = (FT_Byte*)memory->alloc( memory, + 5 * ( decoder.top - decoder.stack ) ); + if ( !q ) + goto Out_Of_Memory_Error; + + node->data = q; + + FT_List_Add( &t2s, node ); + stack = decoder.stack; while ( stack < decoder.top ) @@ -1431,7 +1287,7 @@ if ( *stack < 0 ) { - num = (FT_ULong)-*stack; + num = (FT_ULong)NEG_LONG( *stack ); neg = 1; } else @@ -1523,7 +1379,7 @@ } code = code | parser->object_code; - for ( field = CFF_FIELD_HANDLERS_GET; field->kind; field++ ) + for ( field = cff_field_handlers; field->kind; field++ ) { if ( field->code == (FT_Int)code ) { @@ -1672,11 +1528,20 @@ parser->top = parser->stack; } p++; - } + } /* while ( p < limit ) */ Exit: +#ifdef CFF_CONFIG_OPTION_OLD_ENGINE + FT_List_Finalize( &t2s, destruct_t2s_item, memory, NULL ); +#endif return error; +#ifdef CFF_CONFIG_OPTION_OLD_ENGINE + Out_Of_Memory_Error: + error = FT_THROW( Out_Of_Memory ); + goto Exit; +#endif + Stack_Overflow: error = FT_THROW( Invalid_Argument ); goto Exit; diff --git a/sdk/lib/3rdparty/freetype/src/cff/cffparse.h b/sdk/lib/3rdparty/freetype/src/cff/cffparse.h index 8a8caeca4466c..bac32f9449113 100644 --- a/sdk/lib/3rdparty/freetype/src/cff/cffparse.h +++ b/sdk/lib/3rdparty/freetype/src/cff/cffparse.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* cffparse.h */ -/* */ -/* CFF token stream parser (specification) */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * cffparse.h + * + * CFF token stream parser (specification) + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef CFFPARSE_H_ @@ -33,11 +33,11 @@ FT_BEGIN_HEADER #define CFF_MAX_STACK_DEPTH 96 /* - * There are plans to remove the `maxstack' operator in a forthcoming - * revision of the CFF2 specification, increasing the (then static) stack - * size to 513. By making the default stack size equal to the maximum - * stack size, the operator is essentially disabled, which has the - * desired effect in FreeType. + * There are plans to remove the `maxstack' operator in a forthcoming + * revision of the CFF2 specification, increasing the (then static) stack + * size to 513. By making the default stack size equal to the maximum + * stack size, the operator is essentially disabled, which has the + * desired effect in FreeType. */ #define CFF2_MAX_STACK 513 #define CFF2_DEFAULT_STACK 513 diff --git a/sdk/lib/3rdparty/freetype/src/cff/cffpic.c b/sdk/lib/3rdparty/freetype/src/cff/cffpic.c deleted file mode 100644 index 08b74c7cf20fe..0000000000000 --- a/sdk/lib/3rdparty/freetype/src/cff/cffpic.c +++ /dev/null @@ -1,138 +0,0 @@ -/***************************************************************************/ -/* */ -/* cffpic.c */ -/* */ -/* The FreeType position independent code services for cff module. */ -/* */ -/* Copyright 2009-2018 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_FREETYPE_H -#include FT_INTERNAL_OBJECTS_H -#include "cffcmap.h" -#include "cffpic.h" -#include "cfferrs.h" - - -#ifdef FT_CONFIG_OPTION_PIC - - /* forward declaration of PIC init functions from cffdrivr.c */ - FT_Error - FT_Create_Class_cff_services( FT_Library library, - FT_ServiceDescRec** output_class ); - void - FT_Destroy_Class_cff_services( FT_Library library, - FT_ServiceDescRec* clazz ); - void - FT_Init_Class_cff_service_ps_info( FT_Library library, - FT_Service_PsInfoRec* clazz ); - void - FT_Init_Class_cff_service_glyph_dict( FT_Library library, - FT_Service_GlyphDictRec* clazz ); - void - FT_Init_Class_cff_service_ps_name( FT_Library library, - FT_Service_PsFontNameRec* clazz ); - void - FT_Init_Class_cff_service_get_cmap_info( FT_Library library, - FT_Service_TTCMapsRec* clazz ); - void - FT_Init_Class_cff_service_cid_info( FT_Library library, - FT_Service_CIDRec* clazz ); - - /* forward declaration of PIC init functions from cffparse.c */ - FT_Error - FT_Create_Class_cff_field_handlers( FT_Library library, - CFF_Field_Handler** output_class ); - void - FT_Destroy_Class_cff_field_handlers( FT_Library library, - CFF_Field_Handler* clazz ); - - - void - cff_driver_class_pic_free( FT_Library library ) - { - FT_PIC_Container* pic_container = &library->pic_container; - FT_Memory memory = library->memory; - - - if ( pic_container->cff ) - { - CffModulePIC* container = (CffModulePIC*)pic_container->cff; - - - if ( container->cff_services ) - FT_Destroy_Class_cff_services( library, - container->cff_services ); - container->cff_services = NULL; - if ( container->cff_field_handlers ) - FT_Destroy_Class_cff_field_handlers( - library, container->cff_field_handlers ); - container->cff_field_handlers = NULL; - FT_FREE( container ); - pic_container->cff = NULL; - } - } - - - FT_Error - cff_driver_class_pic_init( FT_Library library ) - { - FT_PIC_Container* pic_container = &library->pic_container; - FT_Error error = FT_Err_Ok; - CffModulePIC* container = NULL; - FT_Memory memory = library->memory; - - - /* allocate pointer, clear and set global container pointer */ - if ( FT_ALLOC ( container, sizeof ( *container ) ) ) - return error; - FT_MEM_SET( container, 0, sizeof ( *container ) ); - pic_container->cff = container; - - /* initialize pointer table - */ - /* this is how the module usually expects this data */ - error = FT_Create_Class_cff_services( library, - &container->cff_services ); - if ( error ) - goto Exit; - - error = FT_Create_Class_cff_field_handlers( - library, &container->cff_field_handlers ); - if ( error ) - goto Exit; - - FT_Init_Class_cff_service_ps_info( - library, &container->cff_service_ps_info ); - FT_Init_Class_cff_service_glyph_dict( - library, &container->cff_service_glyph_dict ); - FT_Init_Class_cff_service_ps_name( - library, &container->cff_service_ps_name ); - FT_Init_Class_cff_service_get_cmap_info( - library, &container->cff_service_get_cmap_info ); - FT_Init_Class_cff_service_cid_info( - library, &container->cff_service_cid_info ); - FT_Init_Class_cff_cmap_encoding_class_rec( - library, &container->cff_cmap_encoding_class_rec ); - FT_Init_Class_cff_cmap_unicode_class_rec( - library, &container->cff_cmap_unicode_class_rec ); - - Exit: - if ( error ) - cff_driver_class_pic_free( library ); - return error; - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - -/* END */ diff --git a/sdk/lib/3rdparty/freetype/src/cff/cffpic.h b/sdk/lib/3rdparty/freetype/src/cff/cffpic.h deleted file mode 100644 index 8ba4203a8de23..0000000000000 --- a/sdk/lib/3rdparty/freetype/src/cff/cffpic.h +++ /dev/null @@ -1,121 +0,0 @@ -/***************************************************************************/ -/* */ -/* cffpic.h */ -/* */ -/* The FreeType position independent code services for cff module. */ -/* */ -/* Copyright 2009-2018 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#ifndef CFFPIC_H_ -#define CFFPIC_H_ - - -#include FT_INTERNAL_PIC_H - -#ifndef FT_CONFIG_OPTION_PIC - -#define CFF_SERVICE_PS_INFO_GET cff_service_ps_info -#define CFF_SERVICE_GLYPH_DICT_GET cff_service_glyph_dict -#define CFF_SERVICE_PS_NAME_GET cff_service_ps_name -#define CFF_SERVICE_GET_CMAP_INFO_GET cff_service_get_cmap_info -#define CFF_SERVICE_CID_INFO_GET cff_service_cid_info -#define CFF_SERVICE_PROPERTIES_GET cff_service_properties -#define CFF_SERVICES_GET cff_services -#define CFF_SERVICE_MULTI_MASTERS_GET cff_service_multi_masters -#define CFF_SERVICE_METRICS_VAR_GET cff_service_metrics_variations -#define CFF_SERVICE_CFF_LOAD_GET cff_service_cff_load -#define CFF_CMAP_ENCODING_CLASS_REC_GET cff_cmap_encoding_class_rec -#define CFF_CMAP_UNICODE_CLASS_REC_GET cff_cmap_unicode_class_rec -#define CFF_FIELD_HANDLERS_GET cff_field_handlers - -#else /* FT_CONFIG_OPTION_PIC */ - -#include FT_SERVICE_GLYPH_DICT_H -#include "cffparse.h" -#include FT_SERVICE_POSTSCRIPT_INFO_H -#include FT_SERVICE_POSTSCRIPT_NAME_H -#include FT_SERVICE_TT_CMAP_H -#include FT_SERVICE_CID_H -#include FT_SERVICE_PROPERTIES_H -#include FT_SERVICE_MULTIPLE_MASTERS_H -#include FT_SERVICE_METRICS_VARIATIONS_H - - -FT_BEGIN_HEADER - - typedef struct CffModulePIC_ - { - FT_ServiceDescRec* cff_services; - CFF_Field_Handler* cff_field_handlers; - FT_Service_PsInfoRec cff_service_ps_info; - FT_Service_GlyphDictRec cff_service_glyph_dict; - FT_Service_PsFontNameRec cff_service_ps_name; - FT_Service_TTCMapsRec cff_service_get_cmap_info; - FT_Service_CIDRec cff_service_cid_info; - FT_Service_PropertiesRec cff_service_properties; - FT_Service_MultiMastersRec cff_service_multi_masters; - FT_Service_MetricsVariationsRec cff_service_metrics_variations; - FT_Service_CFFLoadRec cff_service_cff_load; - FT_CMap_ClassRec cff_cmap_encoding_class_rec; - FT_CMap_ClassRec cff_cmap_unicode_class_rec; - - } CffModulePIC; - - -#define GET_PIC( lib ) \ - ( (CffModulePIC*)( (lib)->pic_container.cff ) ) - -#define CFF_SERVICE_PS_INFO_GET \ - ( GET_PIC( library )->cff_service_ps_info ) -#define CFF_SERVICE_GLYPH_DICT_GET \ - ( GET_PIC( library )->cff_service_glyph_dict ) -#define CFF_SERVICE_PS_NAME_GET \ - ( GET_PIC( library )->cff_service_ps_name ) -#define CFF_SERVICE_GET_CMAP_INFO_GET \ - ( GET_PIC( library )->cff_service_get_cmap_info ) -#define CFF_SERVICE_CID_INFO_GET \ - ( GET_PIC( library )->cff_service_cid_info ) -#define CFF_SERVICE_PROPERTIES_GET \ - ( GET_PIC( library )->cff_service_properties ) -#define CFF_SERVICES_GET \ - ( GET_PIC( library )->cff_services ) -#define CFF_SERVICE_MULTI_MASTERS_GET \ - ( GET_PIC( library )->cff_service_multi_masters ) -#define CFF_SERVICE_METRICS_VAR_GET \ - ( GET_PIC( library )->cff_service_metrics_variations ) -#define CFF_SERVICE_CFF_LOAD_GET \ - ( GET_PIC( library )->cff_service_cff_load ) -#define CFF_CMAP_ENCODING_CLASS_REC_GET \ - ( GET_PIC( library )->cff_cmap_encoding_class_rec ) -#define CFF_CMAP_UNICODE_CLASS_REC_GET \ - ( GET_PIC( library )->cff_cmap_unicode_class_rec ) -#define CFF_FIELD_HANDLERS_GET \ - ( GET_PIC( library )->cff_field_handlers ) - - /* see cffpic.c for the implementation */ - void - cff_driver_class_pic_free( FT_Library library ); - - FT_Error - cff_driver_class_pic_init( FT_Library library ); - -FT_END_HEADER - -#endif /* FT_CONFIG_OPTION_PIC */ - - /* */ - -#endif /* CFFPIC_H_ */ - - -/* END */ diff --git a/sdk/lib/3rdparty/freetype/src/cff/cfftoken.h b/sdk/lib/3rdparty/freetype/src/cff/cfftoken.h index fec1ca20bde0e..063a7b3be072d 100644 --- a/sdk/lib/3rdparty/freetype/src/cff/cfftoken.h +++ b/sdk/lib/3rdparty/freetype/src/cff/cfftoken.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* cfftoken.h */ -/* */ -/* CFF token definitions (specification only). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * cfftoken.h + * + * CFF token definitions (specification only). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #undef FT_STRUCTURE diff --git a/sdk/lib/3rdparty/freetype/src/cid/ciderrs.h b/sdk/lib/3rdparty/freetype/src/cid/ciderrs.h index a5a86e3fc68a7..be80bed3bea44 100644 --- a/sdk/lib/3rdparty/freetype/src/cid/ciderrs.h +++ b/sdk/lib/3rdparty/freetype/src/cid/ciderrs.h @@ -1,26 +1,26 @@ -/***************************************************************************/ -/* */ -/* ciderrs.h */ -/* */ -/* CID error codes (specification only). */ -/* */ -/* Copyright 2001-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to define the CID error enumeration constants. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * ciderrs.h + * + * CID error codes (specification only). + * + * Copyright (C) 2001-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /************************************************************************** + * + * This file is used to define the CID error enumeration constants. + * + */ #ifndef CIDERRS_H_ #define CIDERRS_H_ diff --git a/sdk/lib/3rdparty/freetype/src/cid/cidgload.c b/sdk/lib/3rdparty/freetype/src/cid/cidgload.c index 4ae2e051e3b12..1804c28eee44d 100644 --- a/sdk/lib/3rdparty/freetype/src/cid/cidgload.c +++ b/sdk/lib/3rdparty/freetype/src/cid/cidgload.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* cidgload.c */ -/* */ -/* CID-keyed Type1 Glyph Loader (body). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * cidgload.c + * + * CID-keyed Type1 Glyph Loader (body). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -31,14 +31,14 @@ #include "ciderrs.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_cidgload +#define FT_COMPONENT cidgload FT_CALLBACK_DEF( FT_Error ) @@ -286,7 +286,16 @@ FT_Int* max_advance ) { FT_Error error; +#ifdef __REACTOS__ + T1_DecoderRec *decoder_allocated = malloc(sizeof(*decoder_allocated)); + if (!decoder_allocated) + return FT_THROW( Out_Of_Memory ); +/* Ugly but it allows us to reduce the diff */ +#define decoder (*decoder_allocated) + { +#else T1_DecoderRec decoder; +#endif FT_Int glyph_index; PSAux_Service psaux = (PSAux_Service)face->psaux; @@ -304,7 +313,14 @@ 0, /* hinting == 0 */ cid_load_glyph ); if ( error ) +#ifdef __REACTOS__ + { + free(decoder_allocated); + return error; + } +#else return error; +#endif /* TODO: initialize decoder.len_buildchar and decoder.buildchar */ /* if we ever support CID-keyed multiple master fonts */ @@ -326,6 +342,11 @@ psaux->t1_decoder_funcs->done( &decoder ); +#ifdef __REACTOS__ + free(decoder_allocated); +#undef decoder + } +#endif return FT_Err_Ok; } @@ -342,10 +363,10 @@ CID_GlyphSlot glyph = (CID_GlyphSlot)cidglyph; FT_Error error; #ifdef __REACTOS__ - T1_DecoderRec *decoder = malloc(sizeof(T1_DecoderRec)); - if (!decoder) return FT_Err_Out_Of_Memory; + T1_DecoderRec *decoder_allocated = malloc(sizeof(*decoder_allocated)); + if (!decoder_allocated) return FT_Err_Out_Of_Memory; /* Ugly but it allows us to reduce the diff */ -#define decoder (*decoder) +#define decoder (*decoder_allocated) { #else T1_DecoderRec decoder; @@ -401,8 +422,7 @@ must_finish_decoder = TRUE; /* set up the decoder */ - decoder.builder.no_recurse = FT_BOOL( - ( ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ) ); + decoder.builder.no_recurse = FT_BOOL( load_flags & FT_LOAD_NO_RECURSE ); error = cid_load_glyph( &decoder, glyph_index ); if ( error ) @@ -533,7 +553,7 @@ psaux->t1_decoder_funcs->done( &decoder ); #ifdef __REACTOS__ - free(&decoder); + free(decoder_allocated); #undef decoder } #endif diff --git a/sdk/lib/3rdparty/freetype/src/cid/cidgload.h b/sdk/lib/3rdparty/freetype/src/cid/cidgload.h index 4811852ae43ee..37eba7ca7bee2 100644 --- a/sdk/lib/3rdparty/freetype/src/cid/cidgload.h +++ b/sdk/lib/3rdparty/freetype/src/cid/cidgload.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* cidgload.h */ -/* */ -/* OpenType Glyph Loader (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * cidgload.h + * + * OpenType Glyph Loader (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef CIDGLOAD_H_ diff --git a/sdk/lib/3rdparty/freetype/src/cid/cidload.c b/sdk/lib/3rdparty/freetype/src/cid/cidload.c index 27cd09b3c3569..fce3e37da7486 100644 --- a/sdk/lib/3rdparty/freetype/src/cid/cidload.c +++ b/sdk/lib/3rdparty/freetype/src/cid/cidload.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* cidload.c */ -/* */ -/* CID-keyed Type1 font loader (body). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * cidload.c + * + * CID-keyed Type1 font loader (body). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -21,20 +21,21 @@ #include FT_CONFIG_CONFIG_H #include FT_MULTIPLE_MASTERS_H #include FT_INTERNAL_TYPE1_TYPES_H +#include FT_INTERNAL_POSTSCRIPT_AUX_H #include "cidload.h" #include "ciderrs.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_cidload +#define FT_COMPONENT cidload /* read a single offset */ @@ -81,6 +82,8 @@ /* if the keyword has a dedicated callback, call it */ if ( keyword->type == T1_FIELD_TYPE_CALLBACK ) { + FT_TRACE4(( " %s", keyword->ident )); + keyword->reader( (FT_Face)face, parser ); error = parser->root.error; goto Exit; @@ -131,6 +134,8 @@ } } + FT_TRACE4(( " %s", keyword->ident )); + dummy_object = object; /* now, load the keyword data in the object's field(s) */ @@ -141,12 +146,15 @@ else error = cid_parser_load_field( &loader->parser, keyword, &dummy_object ); + + FT_TRACE4(( "\n" )); + Exit: return error; } - FT_CALLBACK_DEF( FT_Error ) + FT_CALLBACK_DEF( void ) cid_parse_font_matrix( CID_Face face, CID_Parser* parser ) { @@ -171,14 +179,25 @@ result = cid_parser_to_fixed_array( parser, 6, temp, 3 ); if ( result < 6 ) - return FT_THROW( Invalid_File_Format ); + { + FT_ERROR(( "cid_parse_font_matrix: not enough matrix elements\n" )); + goto Exit; + } + + FT_TRACE4(( " [%f %f %f %f %f %f]\n", + (double)temp[0] / 65536 / 1000, + (double)temp[1] / 65536 / 1000, + (double)temp[2] / 65536 / 1000, + (double)temp[3] / 65536 / 1000, + (double)temp[4] / 65536 / 1000, + (double)temp[5] / 65536 / 1000 )); temp_scale = FT_ABS( temp[3] ); if ( temp_scale == 0 ) { FT_ERROR(( "cid_parse_font_matrix: invalid font matrix\n" )); - return FT_THROW( Invalid_File_Format ); + goto Exit; } /* atypical case */ @@ -200,16 +219,24 @@ matrix->xy = temp[2]; matrix->yy = temp[3]; + if ( !FT_Matrix_Check( matrix ) ) + { + FT_ERROR(( "t1_parse_font_matrix: invalid font matrix\n" )); + parser->root.error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + /* note that the font offsets are expressed in integer font units */ offset->x = temp[4] >> 16; offset->y = temp[5] >> 16; } - return FT_Err_Ok; + Exit: + return; } - FT_CALLBACK_DEF( FT_Error ) + FT_CALLBACK_DEF( void ) parse_fd_array( CID_Face face, CID_Parser* parser ) { @@ -224,10 +251,11 @@ if ( num_dicts < 0 ) { FT_ERROR(( "parse_fd_array: invalid number of dictionaries\n" )); - error = FT_THROW( Invalid_File_Format ); goto Exit; } + FT_TRACE4(( " %d\n", num_dicts )); + /* * A single entry in the FDArray must (at least) contain the following * structure elements. @@ -263,27 +291,31 @@ cid->num_dicts = num_dicts; - /* don't forget to set a few defaults */ + /* set some default values (the same as for Type 1 fonts) */ for ( n = 0; n < cid->num_dicts; n++ ) { CID_FaceDict dict = cid->font_dicts + n; - /* default value for lenIV */ - dict->private_dict.lenIV = 4; + dict->private_dict.blue_shift = 7; + dict->private_dict.blue_fuzz = 1; + dict->private_dict.lenIV = 4; + dict->private_dict.expansion_factor = (FT_Fixed)( 0.06 * 0x10000L ); + dict->private_dict.blue_scale = (FT_Fixed)( + 0.039625 * 0x10000L * 1000 ); } } Exit: - return error; + return; } - /* by mistake, `expansion_factor' appears both in PS_PrivateRec */ + /* By mistake, `expansion_factor' appears both in PS_PrivateRec */ /* and CID_FaceDictRec (both are public header files and can't */ - /* changed); we simply copy the value */ + /* changed). We simply copy the value. */ - FT_CALLBACK_DEF( FT_Error ) + FT_CALLBACK_DEF( void ) parse_expansion_factor( CID_Face face, CID_Parser* parser ) { @@ -296,9 +328,43 @@ dict->expansion_factor = cid_parser_to_fixed( parser, 0 ); dict->private_dict.expansion_factor = dict->expansion_factor; + + FT_TRACE4(( "%d\n", dict->expansion_factor )); + } + + return; + } + + + /* By mistake, `CID_FaceDictRec' doesn't contain a field for the */ + /* `FontName' keyword. FreeType doesn't need it, but it is nice */ + /* to catch it for producing better trace output. */ + + FT_CALLBACK_DEF( void ) + parse_font_name( CID_Face face, + CID_Parser* parser ) + { +#ifdef FT_DEBUG_LEVEL_TRACE + if ( parser->num_dict >= 0 && parser->num_dict < face->cid.num_dicts ) + { + T1_TokenRec token; + FT_UInt len; + + + cid_parser_to_token( parser, &token ); + + len = (FT_UInt)( token.limit - token.start ); + if ( len ) + FT_TRACE4(( " %.*s\n", len, token.start )); + else + FT_TRACE4(( " <no value>\n" )); } +#else + FT_UNUSED( face ); + FT_UNUSED( parser ); +#endif - return FT_Err_Ok; + return; } @@ -311,6 +377,7 @@ T1_FIELD_CALLBACK( "FDArray", parse_fd_array, 0 ) T1_FIELD_CALLBACK( "FontMatrix", cid_parse_font_matrix, 0 ) T1_FIELD_CALLBACK( "ExpansionFactor", parse_expansion_factor, 0 ) + T1_FIELD_CALLBACK( "FontName", parse_font_name, 0 ) { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0, 0 } }; @@ -356,7 +423,16 @@ /* if /FDArray was found, then cid->num_dicts is > 0, and */ /* we can start increasing parser->num_dict */ if ( face->cid.num_dicts > 0 ) + { parser->num_dict++; + +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE4(( " FontDict %d", parser->num_dict )); + if ( parser->num_dict > face->cid.num_dicts ) + FT_TRACE4(( " (ignored)" )); + FT_TRACE4(( "\n" )); +#endif + } } } @@ -757,7 +833,7 @@ if ( cid->fd_bytes < 0 || cid->gd_bytes < 1 ) { - FT_ERROR(( "cid_parse_dict:" + FT_ERROR(( "cid_face_open:" " Invalid `FDBytes' or `GDBytes' value\n" )); error = FT_THROW( Invalid_File_Format ); goto Exit; @@ -766,7 +842,7 @@ /* allow at most 32bit offsets */ if ( cid->fd_bytes > 4 || cid->gd_bytes > 4 ) { - FT_ERROR(( "cid_parse_dict:" + FT_ERROR(( "cid_face_open:" " Values of `FDBytes' or `GDBytes' larger than 4\n" " " " are not supported\n" )); @@ -782,17 +858,36 @@ CID_FaceDict dict = cid->font_dicts + n; + /* the upper limits are ad-hoc values */ + if ( dict->private_dict.blue_shift > 1000 || + dict->private_dict.blue_shift < 0 ) + { + FT_TRACE2(( "cid_face_open:" + " setting unlikely BlueShift value %d to default (7)\n", + dict->private_dict.blue_shift )); + dict->private_dict.blue_shift = 7; + } + + if ( dict->private_dict.blue_fuzz > 1000 || + dict->private_dict.blue_fuzz < 0 ) + { + FT_TRACE2(( "cid_face_open:" + " setting unlikely BlueFuzz value %d to default (1)\n", + dict->private_dict.blue_fuzz )); + dict->private_dict.blue_fuzz = 1; + } + if ( dict->sd_bytes < 0 || ( dict->num_subrs && dict->sd_bytes < 1 ) ) { - FT_ERROR(( "cid_parse_dict: Invalid `SDBytes' value\n" )); + FT_ERROR(( "cid_face_open: Invalid `SDBytes' value\n" )); error = FT_THROW( Invalid_File_Format ); goto Exit; } if ( dict->sd_bytes > 4 ) { - FT_ERROR(( "cid_parse_dict:" + FT_ERROR(( "cid_face_open:" " Values of `SDBytes' larger than 4" " are not supported\n" )); error = FT_THROW( Invalid_File_Format ); @@ -801,7 +896,7 @@ if ( dict->subrmap_offset > binary_length ) { - FT_ERROR(( "cid_parse_dict: Invalid `SubrMapOffset' value\n" )); + FT_ERROR(( "cid_face_open: Invalid `SubrMapOffset' value\n" )); error = FT_THROW( Invalid_File_Format ); goto Exit; } @@ -812,7 +907,7 @@ dict->num_subrs > ( binary_length - dict->subrmap_offset ) / (FT_UInt)dict->sd_bytes ) ) { - FT_ERROR(( "cid_parse_dict: Invalid `SubrCount' value\n" )); + FT_ERROR(( "cid_face_open: Invalid `SubrCount' value\n" )); error = FT_THROW( Invalid_File_Format ); goto Exit; } @@ -820,7 +915,7 @@ if ( cid->cidmap_offset > binary_length ) { - FT_ERROR(( "cid_parse_dict: Invalid `CIDMapOffset' value\n" )); + FT_ERROR(( "cid_face_open: Invalid `CIDMapOffset' value\n" )); error = FT_THROW( Invalid_File_Format ); goto Exit; } @@ -829,7 +924,7 @@ cid->cid_count > ( binary_length - cid->cidmap_offset ) / entry_len ) { - FT_ERROR(( "cid_parse_dict: Invalid `CIDCount' value\n" )); + FT_ERROR(( "cid_face_open: Invalid `CIDCount' value\n" )); error = FT_THROW( Invalid_File_Format ); goto Exit; } diff --git a/sdk/lib/3rdparty/freetype/src/cid/cidload.h b/sdk/lib/3rdparty/freetype/src/cid/cidload.h index 3f8bd08620ab1..fb9d46216d099 100644 --- a/sdk/lib/3rdparty/freetype/src/cid/cidload.h +++ b/sdk/lib/3rdparty/freetype/src/cid/cidload.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* cidload.h */ -/* */ -/* CID-keyed Type1 font loader (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * cidload.h + * + * CID-keyed Type1 font loader (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef CIDLOAD_H_ diff --git a/sdk/lib/3rdparty/freetype/src/cid/cidobjs.c b/sdk/lib/3rdparty/freetype/src/cid/cidobjs.c index 77afe1c8751f2..4e9728719b73a 100644 --- a/sdk/lib/3rdparty/freetype/src/cid/cidobjs.c +++ b/sdk/lib/3rdparty/freetype/src/cid/cidobjs.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* cidobjs.c */ -/* */ -/* CID objects manager (body). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * cidobjs.c + * + * CID objects manager (body). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -31,21 +31,21 @@ #include "ciderrs.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_cidobjs +#define FT_COMPONENT cidobjs - /*************************************************************************/ - /* */ - /* SLOT FUNCTIONS */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * SLOT FUNCTIONS + * + */ FT_LOCAL_DEF( void ) cid_slot_done( FT_GlyphSlot slot ) @@ -85,11 +85,11 @@ } - /*************************************************************************/ - /* */ - /* SIZE FUNCTIONS */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * SIZE FUNCTIONS + * + */ static PSH_Globals_Funcs @@ -174,23 +174,24 @@ } - /*************************************************************************/ - /* */ - /* FACE FUNCTIONS */ - /* */ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* <Function> */ - /* cid_face_done */ - /* */ - /* <Description> */ - /* Finalizes a given face object. */ - /* */ - /* <Input> */ - /* face :: A pointer to the face object to destroy. */ - /* */ + /************************************************************************** + * + * FACE FUNCTIONS + * + */ + + /************************************************************************** + * + * @Function: + * cid_face_done + * + * @Description: + * Finalizes a given face object. + * + * @Input: + * face :: + * A pointer to the face object to destroy. + */ FT_LOCAL_DEF( void ) cid_face_done( FT_Face cidface ) /* CID_Face */ { @@ -252,29 +253,34 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* cid_face_init */ - /* */ - /* <Description> */ - /* Initializes a given CID face object. */ - /* */ - /* <Input> */ - /* stream :: The source font stream. */ - /* */ - /* face_index :: The index of the font face in the resource. */ - /* */ - /* num_params :: Number of additional generic parameters. Ignored. */ - /* */ - /* params :: Additional generic parameters. Ignored. */ - /* */ - /* <InOut> */ - /* face :: The newly built face object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * cid_face_init + * + * @Description: + * Initializes a given CID face object. + * + * @Input: + * stream :: + * The source font stream. + * + * face_index :: + * The index of the font face in the resource. + * + * num_params :: + * Number of additional generic parameters. Ignored. + * + * params :: + * Additional generic parameters. Ignored. + * + * @InOut: + * face :: + * The newly built face object. + * + * @Return: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) cid_face_init( FT_Stream stream, FT_Face cidface, /* CID_Face */ @@ -449,20 +455,21 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* cid_driver_init */ - /* */ - /* <Description> */ - /* Initializes a given CID driver object. */ - /* */ - /* <Input> */ - /* driver :: A handle to the target driver object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * cid_driver_init + * + * @Description: + * Initializes a given CID driver object. + * + * @Input: + * driver :: + * A handle to the target driver object. + * + * @Return: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) cid_driver_init( FT_Module module ) { @@ -505,17 +512,18 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* cid_driver_done */ - /* */ - /* <Description> */ - /* Finalizes a given CID driver. */ - /* */ - /* <Input> */ - /* driver :: A handle to the target CID driver. */ - /* */ + /************************************************************************** + * + * @Function: + * cid_driver_done + * + * @Description: + * Finalizes a given CID driver. + * + * @Input: + * driver :: + * A handle to the target CID driver. + */ FT_LOCAL_DEF( void ) cid_driver_done( FT_Module driver ) { diff --git a/sdk/lib/3rdparty/freetype/src/cid/cidobjs.h b/sdk/lib/3rdparty/freetype/src/cid/cidobjs.h index 0221f017dd28f..89c9aa74ab890 100644 --- a/sdk/lib/3rdparty/freetype/src/cid/cidobjs.h +++ b/sdk/lib/3rdparty/freetype/src/cid/cidobjs.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* cidobjs.h */ -/* */ -/* CID objects manager (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * cidobjs.h + * + * CID objects manager (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef CIDOBJS_H_ @@ -34,60 +34,60 @@ FT_BEGIN_HEADER typedef struct CID_Glyph_Hints_ CID_Glyph_Hints; - /*************************************************************************/ - /* */ - /* <Type> */ - /* CID_Driver */ - /* */ - /* <Description> */ - /* A handle to a Type 1 driver object. */ - /* */ + /************************************************************************** + * + * @Type: + * CID_Driver + * + * @Description: + * A handle to a Type 1 driver object. + */ typedef struct CID_DriverRec_* CID_Driver; - /*************************************************************************/ - /* */ - /* <Type> */ - /* CID_Size */ - /* */ - /* <Description> */ - /* A handle to a Type 1 size object. */ - /* */ + /************************************************************************** + * + * @Type: + * CID_Size + * + * @Description: + * A handle to a Type 1 size object. + */ typedef struct CID_SizeRec_* CID_Size; - /*************************************************************************/ - /* */ - /* <Type> */ - /* CID_GlyphSlot */ - /* */ - /* <Description> */ - /* A handle to a Type 1 glyph slot object. */ - /* */ + /************************************************************************** + * + * @Type: + * CID_GlyphSlot + * + * @Description: + * A handle to a Type 1 glyph slot object. + */ typedef struct CID_GlyphSlotRec_* CID_GlyphSlot; - /*************************************************************************/ - /* */ - /* <Type> */ - /* CID_CharMap */ - /* */ - /* <Description> */ - /* A handle to a Type 1 character mapping object. */ - /* */ - /* <Note> */ - /* The Type 1 format doesn't use a charmap but an encoding table. */ - /* The driver is responsible for making up charmap objects */ - /* corresponding to these tables. */ - /* */ + /************************************************************************** + * + * @Type: + * CID_CharMap + * + * @Description: + * A handle to a Type 1 character mapping object. + * + * @Note: + * The Type 1 format doesn't use a charmap but an encoding table. + * The driver is responsible for making up charmap objects + * corresponding to these tables. + */ typedef struct CID_CharMapRec_* CID_CharMap; - /*************************************************************************/ - /* */ - /* HERE BEGINS THE TYPE 1 SPECIFIC STUFF */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * HERE BEGINS THE TYPE 1 SPECIFIC STUFF + * + */ typedef struct CID_SizeRec_ diff --git a/sdk/lib/3rdparty/freetype/src/cid/cidparse.c b/sdk/lib/3rdparty/freetype/src/cid/cidparse.c index b1c7f3cb2c98c..1be46ec328734 100644 --- a/sdk/lib/3rdparty/freetype/src/cid/cidparse.c +++ b/sdk/lib/3rdparty/freetype/src/cid/cidparse.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* cidparse.c */ -/* */ -/* CID-keyed Type1 parser (body). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * cidparse.c + * + * CID-keyed Type1 parser (body). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -26,14 +26,14 @@ #include "ciderrs.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_cidparse +#define FT_COMPONENT cidparse /*************************************************************************/ diff --git a/sdk/lib/3rdparty/freetype/src/cid/cidparse.h b/sdk/lib/3rdparty/freetype/src/cid/cidparse.h index 61602f76741c4..ec1f6a346db88 100644 --- a/sdk/lib/3rdparty/freetype/src/cid/cidparse.h +++ b/sdk/lib/3rdparty/freetype/src/cid/cidparse.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* cidparse.h */ -/* */ -/* CID-keyed Type1 parser (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * cidparse.h + * + * CID-keyed Type1 parser (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef CIDPARSE_H_ @@ -29,35 +29,43 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* <Struct> */ - /* CID_Parser */ - /* */ - /* <Description> */ - /* A CID_Parser is an object used to parse a Type 1 fonts very */ - /* quickly. */ - /* */ - /* <Fields> */ - /* root :: The root PS_ParserRec fields. */ - /* */ - /* stream :: The current input stream. */ - /* */ - /* postscript :: A pointer to the data to be parsed. */ - /* */ - /* postscript_len :: The length of the data to be parsed. */ - /* */ - /* data_offset :: The start position of the binary data (i.e., the */ - /* end of the data to be parsed. */ - /* */ - /* binary_length :: The length of the data after the `StartData' */ - /* command if the data format is hexadecimal. */ - /* */ - /* cid :: A structure which holds the information about */ - /* the current font. */ - /* */ - /* num_dict :: The number of font dictionaries. */ - /* */ + /************************************************************************** + * + * @Struct: + * CID_Parser + * + * @Description: + * A CID_Parser is an object used to parse a Type 1 fonts very + * quickly. + * + * @Fields: + * root :: + * The root PS_ParserRec fields. + * + * stream :: + * The current input stream. + * + * postscript :: + * A pointer to the data to be parsed. + * + * postscript_len :: + * The length of the data to be parsed. + * + * data_offset :: + * The start position of the binary data (i.e., the + * end of the data to be parsed. + * + * binary_length :: + * The length of the data after the `StartData' + * command if the data format is hexadecimal. + * + * cid :: + * A structure which holds the information about + * the current font. + * + * num_dict :: + * The number of font dictionaries. + */ typedef struct CID_Parser_ { PS_ParserRec root; @@ -86,11 +94,11 @@ FT_BEGIN_HEADER cid_parser_done( CID_Parser* parser ); - /*************************************************************************/ - /* */ - /* PARSING ROUTINES */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * PARSING ROUTINES + * + */ #define cid_parser_skip_spaces( p ) \ (p)->root.funcs.skip_spaces( &(p)->root ) diff --git a/sdk/lib/3rdparty/freetype/src/cid/cidriver.c b/sdk/lib/3rdparty/freetype/src/cid/cidriver.c index d9faf353ea41f..4d91e875291f9 100644 --- a/sdk/lib/3rdparty/freetype/src/cid/cidriver.c +++ b/sdk/lib/3rdparty/freetype/src/cid/cidriver.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* cidriver.c */ -/* */ -/* CID driver interface (body). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * cidriver.c + * + * CID driver interface (body). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -34,18 +34,18 @@ #include FT_INTERNAL_POSTSCRIPT_AUX_H - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_ciddriver +#define FT_COMPONENT ciddriver /* - * POSTSCRIPT NAME SERVICE + * POSTSCRIPT NAME SERVICE * */ @@ -69,7 +69,7 @@ /* - * POSTSCRIPT INFO SERVICE + * POSTSCRIPT INFO SERVICE * */ @@ -105,7 +105,7 @@ /* - * CID INFO SERVICE + * CID INFO SERVICE * */ static FT_Error @@ -173,7 +173,7 @@ /* - * PROPERTY SERVICE + * PROPERTY SERVICE * */ @@ -185,7 +185,7 @@ /* - * SERVICE LIST + * SERVICE LIST * */ diff --git a/sdk/lib/3rdparty/freetype/src/cid/cidriver.h b/sdk/lib/3rdparty/freetype/src/cid/cidriver.h index 59d9ded901561..3402fd7e99432 100644 --- a/sdk/lib/3rdparty/freetype/src/cid/cidriver.h +++ b/sdk/lib/3rdparty/freetype/src/cid/cidriver.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* cidriver.h */ -/* */ -/* High-level CID driver interface (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * cidriver.h + * + * High-level CID driver interface (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef CIDRIVER_H_ @@ -26,15 +26,9 @@ FT_BEGIN_HEADER -#ifdef FT_CONFIG_OPTION_PIC -#error "this module does not support PIC yet" -#endif - - FT_CALLBACK_TABLE const FT_Driver_ClassRec t1cid_driver_class; - FT_END_HEADER #endif /* CIDRIVER_H_ */ diff --git a/sdk/lib/3rdparty/freetype/src/cid/cidtoken.h b/sdk/lib/3rdparty/freetype/src/cid/cidtoken.h index b0e2dac6aaf69..f505c9e1664e8 100644 --- a/sdk/lib/3rdparty/freetype/src/cid/cidtoken.h +++ b/sdk/lib/3rdparty/freetype/src/cid/cidtoken.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* cidtoken.h */ -/* */ -/* CID token definitions (specification only). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * cidtoken.h + * + * CID token definitions (specification only). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #undef FT_STRUCTURE @@ -21,17 +21,20 @@ #undef T1CODE #define T1CODE T1_FIELD_LOCATION_CID_INFO - T1_FIELD_KEY ( "CIDFontName", cid_font_name, 0 ) - T1_FIELD_FIXED ( "CIDFontVersion", cid_version, 0 ) - T1_FIELD_NUM ( "CIDFontType", cid_font_type, 0 ) - T1_FIELD_STRING( "Registry", registry, 0 ) - T1_FIELD_STRING( "Ordering", ordering, 0 ) - T1_FIELD_NUM ( "Supplement", supplement, 0 ) - T1_FIELD_NUM ( "UIDBase", uid_base, 0 ) - T1_FIELD_NUM ( "CIDMapOffset", cidmap_offset, 0 ) - T1_FIELD_NUM ( "FDBytes", fd_bytes, 0 ) - T1_FIELD_NUM ( "GDBytes", gd_bytes, 0 ) - T1_FIELD_NUM ( "CIDCount", cid_count, 0 ) + T1_FIELD_KEY ( "CIDFontName", cid_font_name, 0 ) + T1_FIELD_FIXED ( "CIDFontVersion", cid_version, 0 ) + T1_FIELD_NUM ( "CIDFontType", cid_font_type, 0 ) + T1_FIELD_STRING ( "Registry", registry, 0 ) + T1_FIELD_STRING ( "Ordering", ordering, 0 ) + T1_FIELD_NUM ( "Supplement", supplement, 0 ) + T1_FIELD_NUM ( "UIDBase", uid_base, 0 ) + + T1_FIELD_NUM_TABLE( "XUID", xuid, 16, 0 ) + + T1_FIELD_NUM ( "CIDMapOffset", cidmap_offset, 0 ) + T1_FIELD_NUM ( "FDBytes", fd_bytes, 0 ) + T1_FIELD_NUM ( "GDBytes", gd_bytes, 0 ) + T1_FIELD_NUM ( "CIDCount", cid_count, 0 ) #undef FT_STRUCTURE diff --git a/sdk/lib/3rdparty/freetype/src/cid/type1cid.c b/sdk/lib/3rdparty/freetype/src/cid/type1cid.c index 61770e3f1e212..d21801cec194e 100644 --- a/sdk/lib/3rdparty/freetype/src/cid/type1cid.c +++ b/sdk/lib/3rdparty/freetype/src/cid/type1cid.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* type1cid.c */ -/* */ -/* FreeType OpenType driver component (body only). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * type1cid.c + * + * FreeType OpenType driver component (body only). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #define FT_MAKE_OPTION_SINGLE_OBJECT diff --git a/sdk/lib/3rdparty/freetype/src/gxvalid/README b/sdk/lib/3rdparty/freetype/src/gxvalid/README index af8128e0e7942..d493587842dc5 100644 --- a/sdk/lib/3rdparty/freetype/src/gxvalid/README +++ b/sdk/lib/3rdparty/freetype/src/gxvalid/README @@ -518,7 +518,7 @@ gxvalid: TrueType GX validator ------------------------------------------------------------------------ -Copyright 2004-2018 by +Copyright (C) 2004-2019 by suzuki toshiya, Masatake YAMATO, Red hat K.K., David Turner, Robert Wilhelm, and Werner Lemberg. diff --git a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvalid.c b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvalid.c index d0577a247eb73..462e461bf2aa0 100644 --- a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvalid.c +++ b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvalid.c @@ -1,20 +1,20 @@ -/***************************************************************************/ -/* */ -/* gxvalid.c */ -/* */ -/* FreeType validator for TrueTypeGX/AAT tables (body only). */ -/* */ -/* Copyright 2005-2018 by */ -/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * gxvalid.c + * + * FreeType validator for TrueTypeGX/AAT tables (body only). + * + * Copyright (C) 2005-2019 by + * suzuki toshiya, Masatake YAMATO, Red Hat K.K., + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #define FT_MAKE_OPTION_SINGLE_OBJECT diff --git a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvalid.h b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvalid.h index 19f0379982213..969cd0927ab1b 100644 --- a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvalid.h +++ b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvalid.h @@ -1,28 +1,28 @@ -/***************************************************************************/ -/* */ -/* gxvalid.h */ -/* */ -/* TrueTypeGX/AAT table validation (specification only). */ -/* */ -/* Copyright 2005-2018 by */ -/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * gxvalid.h + * + * TrueTypeGX/AAT table validation (specification only). + * + * Copyright (C) 2005-2019 by + * suzuki toshiya, Masatake YAMATO, Red Hat K.K., + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + +/**************************************************************************** + * + * gxvalid is derived from both gxlayout module and otvalid module. + * Development of gxlayout is supported by the Information-technology + * Promotion Agency(IPA), Japan. + * + */ #ifndef GXVALID_H_ diff --git a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvbsln.c b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvbsln.c index c367d384834e5..f22f2545fa2ec 100644 --- a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvbsln.c +++ b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvbsln.c @@ -1,42 +1,42 @@ -/***************************************************************************/ -/* */ -/* gxvbsln.c */ -/* */ -/* TrueTypeGX/AAT bsln table validation (body). */ -/* */ -/* Copyright 2004-2018 by */ -/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * gxvbsln.c + * + * TrueTypeGX/AAT bsln table validation (body). + * + * Copyright (C) 2004-2019 by + * suzuki toshiya, Masatake YAMATO, Red Hat K.K., + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + +/**************************************************************************** + * + * gxvalid is derived from both gxlayout module and otvalid module. + * Development of gxlayout is supported by the Information-technology + * Promotion Agency(IPA), Japan. + * + */ #include "gxvalid.h" #include "gxvcommn.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_gxvbsln +#define FT_COMPONENT gxvbsln /*************************************************************************/ diff --git a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvcommn.c b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvcommn.c index b96601108b6c3..c5cb8ebe8b387 100644 --- a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvcommn.c +++ b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvcommn.c @@ -1,41 +1,41 @@ -/***************************************************************************/ -/* */ -/* gxvcommn.c */ -/* */ -/* TrueTypeGX/AAT common tables validation (body). */ -/* */ -/* Copyright 2004-2018 by */ -/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * gxvcommn.c + * + * TrueTypeGX/AAT common tables validation (body). + * + * Copyright (C) 2004-2019 by + * suzuki toshiya, Masatake YAMATO, Red Hat K.K., + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + +/**************************************************************************** + * + * gxvalid is derived from both gxlayout module and otvalid module. + * Development of gxlayout is supported by the Information-technology + * Promotion Agency(IPA), Japan. + * + */ #include "gxvcommn.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_gxvcommon +#define FT_COMPONENT gxvcommon /*************************************************************************/ @@ -384,8 +384,8 @@ ( P += 2, gxv_lookup_value_load( P - 2, SIGNSPEC ) ) static GXV_LookupValueDesc - gxv_lookup_value_load( FT_Bytes p, - int signspec ) + gxv_lookup_value_load( FT_Bytes p, + GXV_LookupValue_SignSpec signspec ) { GXV_LookupValueDesc v; diff --git a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvcommn.h b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvcommn.h index 8e4ff9cafc001..334dc9dfb3520 100644 --- a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvcommn.h +++ b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvcommn.h @@ -1,39 +1,39 @@ -/***************************************************************************/ -/* */ -/* gxvcommn.h */ -/* */ -/* TrueTypeGX/AAT common tables validation (specification). */ -/* */ -/* Copyright 2004-2018 by */ -/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * gxvcommn.h + * + * TrueTypeGX/AAT common tables validation (specification). + * + * Copyright (C) 2004-2019 by + * suzuki toshiya, Masatake YAMATO, Red Hat K.K., + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + +/**************************************************************************** + * + * gxvalid is derived from both gxlayout module and otvalid module. + * Development of gxlayout is supported by the Information-technology + * Promotion Agency(IPA), Japan. + * + */ /* * keywords in variable naming * --------------------------- - * table: Of type FT_Bytes, pointing to the start of this table/subtable. - * limit: Of type FT_Bytes, pointing to the end of this table/subtable, + * table: Of type FT_Bytes, pointing to the start of this table/subtable. + * limit: Of type FT_Bytes, pointing to the end of this table/subtable, * including padding for alignment. - * offset: Of type FT_UInt, the number of octets from the start to target. - * length: Of type FT_UInt, the number of octets from the start to the - * end in this table/subtable, including padding for alignment. + * offset: Of type FT_UInt, the number of octets from the start to target. + * length: Of type FT_UInt, the number of octets from the start to the + * end in this table/subtable, including padding for alignment. * * _MIN, _MAX: Should be added to the tail of macros, as INT_MIN, etc. */ diff --git a/sdk/lib/3rdparty/freetype/src/gxvalid/gxverror.h b/sdk/lib/3rdparty/freetype/src/gxvalid/gxverror.h index d1151258a976f..da0edb35f940e 100644 --- a/sdk/lib/3rdparty/freetype/src/gxvalid/gxverror.h +++ b/sdk/lib/3rdparty/freetype/src/gxvalid/gxverror.h @@ -1,36 +1,36 @@ -/***************************************************************************/ -/* */ -/* gxverror.h */ -/* */ -/* TrueTypeGX/AAT validation module error codes (specification only). */ -/* */ -/* Copyright 2004-2018 by */ -/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to define the OpenType validation module error */ - /* enumeration constants. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * gxverror.h + * + * TrueTypeGX/AAT validation module error codes (specification only). + * + * Copyright (C) 2004-2019 by + * suzuki toshiya, Masatake YAMATO, Red Hat K.K., + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + +/**************************************************************************** + * + * gxvalid is derived from both gxlayout module and otvalid module. + * Development of gxlayout is supported by the Information-technology + * Promotion Agency(IPA), Japan. + * + */ + + + /************************************************************************** + * + * This file is used to define the OpenType validation module error + * enumeration constants. + * + */ #ifndef GXVERROR_H_ #define GXVERROR_H_ diff --git a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvfeat.c b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvfeat.c index 2c805d1d119a1..e1a12a18eddbb 100644 --- a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvfeat.c +++ b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvfeat.c @@ -1,28 +1,28 @@ -/***************************************************************************/ -/* */ -/* gxvfeat.c */ -/* */ -/* TrueTypeGX/AAT feat table validation (body). */ -/* */ -/* Copyright 2004-2018 by */ -/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * gxvfeat.c + * + * TrueTypeGX/AAT feat table validation (body). + * + * Copyright (C) 2004-2019 by + * suzuki toshiya, Masatake YAMATO, Red Hat K.K., + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + +/**************************************************************************** + * + * gxvalid is derived from both gxlayout module and otvalid module. + * Development of gxlayout is supported by the Information-technology + * Promotion Agency(IPA), Japan. + * + */ #include "gxvalid.h" @@ -30,14 +30,14 @@ #include "gxvfeat.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_gxvfeat +#define FT_COMPONENT gxvfeat /*************************************************************************/ diff --git a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvfeat.h b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvfeat.h index 2d943806c11c8..6c9892910cef0 100644 --- a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvfeat.h +++ b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvfeat.h @@ -1,28 +1,28 @@ -/***************************************************************************/ -/* */ -/* gxvfeat.h */ -/* */ -/* TrueTypeGX/AAT feat table validation (specification). */ -/* */ -/* Copyright 2004-2018 by */ -/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * gxvfeat.h + * + * TrueTypeGX/AAT feat table validation (specification). + * + * Copyright (C) 2004-2019 by + * suzuki toshiya, Masatake YAMATO, Red Hat K.K., + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + +/**************************************************************************** + * + * gxvalid is derived from both gxlayout module and otvalid module. + * Development of gxlayout is supported by the Information-technology + * Promotion Agency(IPA), Japan. + * + */ #ifndef GXVFEAT_H_ diff --git a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvfgen.c b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvfgen.c index 840c0f3524a88..5ecb9443c3bf2 100644 --- a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvfgen.c +++ b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvfgen.c @@ -1,62 +1,62 @@ -/***************************************************************************/ -/* */ -/* gxfgen.c */ -/* */ -/* Generate feature registry data for gxv `feat' validator. */ -/* This program is derived from gxfeatreg.c in gxlayout. */ -/* */ -/* Copyright 2004-2018 by */ -/* Masatake YAMATO and Redhat K.K. */ -/* */ -/* This file may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * gxfgen.c + * + * Generate feature registry data for gxv `feat' validator. + * This program is derived from gxfeatreg.c in gxlayout. + * + * Copyright (C) 2004-2019 by + * Masatake YAMATO and Redhat K.K. + * + * This file may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ -/***************************************************************************/ -/* */ -/* gxfeatreg.c */ -/* */ -/* Database of font features pre-defined by Apple Computer, Inc. */ -/* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html */ -/* (body). */ -/* */ -/* Copyright 2003 by */ -/* Masatake YAMATO and Redhat K.K. */ -/* */ -/* This file may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * gxfeatreg.c + * + * Database of font features pre-defined by Apple Computer, Inc. + * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html + * (body). + * + * Copyright 2003 by + * Masatake YAMATO and Redhat K.K. + * + * This file may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ -/***************************************************************************/ -/* */ -/* Development of gxfeatreg.c is supported by */ -/* Information-technology Promotion Agency, Japan. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * Development of gxfeatreg.c is supported by + * Information-technology Promotion Agency, Japan. + * + */ -/***************************************************************************/ -/* */ -/* This file is compiled as a stand-alone executable. */ -/* This file is never compiled into `libfreetype2'. */ -/* The output of this file is used in `gxvfeat.c'. */ -/* ----------------------------------------------------------------------- */ -/* Compile: gcc `pkg-config --cflags freetype2` gxvfgen.c -o gxvfgen */ -/* Run: ./gxvfgen > tmp.c */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * This file is compiled as a stand-alone executable. + * This file is never compiled into `libfreetype2'. + * The output of this file is used in `gxvfeat.c'. + * ----------------------------------------------------------------------- + * Compile: gcc `pkg-config --cflags freetype2` gxvfgen.c -o gxvfgen + * Run: ./gxvfgen > tmp.c + * + */ - /*******************************************************************/ - /* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING */ - /*******************************************************************/ + /******************************************************************** + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + */ /* * If you add a new setting to a feature, check the number of settings @@ -65,9 +65,9 @@ */ #define FEATREG_MAX_SETTING 12 - /*******************************************************************/ - /* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING */ - /*******************************************************************/ + /******************************************************************** + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + */ #include <stdio.h> diff --git a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvjust.c b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvjust.c index 00c4293195b08..a582377859fff 100644 --- a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvjust.c +++ b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvjust.c @@ -1,28 +1,28 @@ -/***************************************************************************/ -/* */ -/* gxvjust.c */ -/* */ -/* TrueTypeGX/AAT just table validation (body). */ -/* */ -/* Copyright 2005-2018 by */ -/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * gxvjust.c + * + * TrueTypeGX/AAT just table validation (body). + * + * Copyright (C) 2005-2019 by + * suzuki toshiya, Masatake YAMATO, Red Hat K.K., + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + +/**************************************************************************** + * + * gxvalid is derived from both gxlayout module and otvalid module. + * Development of gxlayout is supported by the Information-technology + * Promotion Agency(IPA), Japan. + * + */ #include "gxvalid.h" @@ -31,14 +31,14 @@ #include FT_SFNT_NAMES_H - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_gxvjust +#define FT_COMPONENT gxvjust /* * referred `just' table format specification: @@ -72,6 +72,8 @@ const FT_String* msg_tag, GXV_Validator gxvalid ) { + FT_UNUSED( msg_tag ); + if ( gid < gxvalid->face->num_glyphs ) return; diff --git a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvkern.c b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvkern.c index 9c0efd7a4f667..a7532335a573f 100644 --- a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvkern.c +++ b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvkern.c @@ -1,28 +1,28 @@ -/***************************************************************************/ -/* */ -/* gxvkern.c */ -/* */ -/* TrueTypeGX/AAT kern table validation (body). */ -/* */ -/* Copyright 2004-2018 by */ -/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * gxvkern.c + * + * TrueTypeGX/AAT kern table validation (body). + * + * Copyright (C) 2004-2019 by + * suzuki toshiya, Masatake YAMATO, Red Hat K.K., + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + +/**************************************************************************** + * + * gxvalid is derived from both gxlayout module and otvalid module. + * Development of gxlayout is supported by the Information-technology + * Promotion Agency(IPA), Japan. + * + */ #include "gxvalid.h" @@ -32,14 +32,14 @@ #include FT_SERVICE_GX_VALIDATE_H - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_gxvkern +#define FT_COMPONENT gxvkern /*************************************************************************/ diff --git a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvlcar.c b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvlcar.c index 0f261a9ace35a..13b3de3eaa8be 100644 --- a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvlcar.c +++ b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvlcar.c @@ -1,42 +1,42 @@ -/***************************************************************************/ -/* */ -/* gxvlcar.c */ -/* */ -/* TrueTypeGX/AAT lcar table validation (body). */ -/* */ -/* Copyright 2004-2018 by */ -/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * gxvlcar.c + * + * TrueTypeGX/AAT lcar table validation (body). + * + * Copyright (C) 2004-2019 by + * suzuki toshiya, Masatake YAMATO, Red Hat K.K., + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + +/**************************************************************************** + * + * gxvalid is derived from both gxlayout module and otvalid module. + * Development of gxlayout is supported by the Information-technology + * Promotion Agency(IPA), Japan. + * + */ #include "gxvalid.h" #include "gxvcommn.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_gxvlcar +#define FT_COMPONENT gxvlcar /*************************************************************************/ diff --git a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmod.c b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmod.c index 1a3c862927d8d..eeadeb3e1d63e 100644 --- a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmod.c +++ b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmod.c @@ -1,28 +1,28 @@ -/***************************************************************************/ -/* */ -/* gxvmod.c */ -/* */ -/* FreeType's TrueTypeGX/AAT validation module implementation (body). */ -/* */ -/* Copyright 2004-2018 by */ -/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * gxvmod.c + * + * FreeType's TrueTypeGX/AAT validation module implementation (body). + * + * Copyright (C) 2004-2019 by + * suzuki toshiya, Masatake YAMATO, Red Hat K.K., + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + +/**************************************************************************** + * + * gxvalid is derived from both gxlayout module and otvalid module. + * Development of gxlayout is supported by the Information-technology + * Promotion Agency(IPA), Japan. + * + */ #include <ft2build.h> @@ -37,14 +37,14 @@ #include "gxvcommn.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_gxvmodule +#define FT_COMPONENT gxvmodule static FT_Error diff --git a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmod.h b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmod.h index 745c62e105415..6ecd7312c9fbe 100644 --- a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmod.h +++ b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmod.h @@ -1,29 +1,29 @@ -/***************************************************************************/ -/* */ -/* gxvmod.h */ -/* */ -/* FreeType's TrueTypeGX/AAT validation module implementation */ -/* (specification). */ -/* */ -/* Copyright 2004-2018 by */ -/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * gxvmod.h + * + * FreeType's TrueTypeGX/AAT validation module implementation + * (specification). + * + * Copyright (C) 2004-2019 by + * suzuki toshiya, Masatake YAMATO, Red Hat K.K., + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + +/**************************************************************************** + * + * gxvalid is derived from both gxlayout module and otvalid module. + * Development of gxlayout is supported by the Information-technology + * Promotion Agency(IPA), Japan. + * + */ #ifndef GXVMOD_H_ @@ -35,10 +35,6 @@ FT_BEGIN_HEADER -#ifdef FT_CONFIG_OPTION_PIC -#error "this module does not support PIC yet" -#endif - FT_EXPORT_VAR( const FT_Module_Class ) gxv_module_class; diff --git a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmort.c b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmort.c index b361cb2b9d77b..288ef6988b786 100644 --- a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmort.c +++ b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmort.c @@ -1,42 +1,42 @@ -/***************************************************************************/ -/* */ -/* gxvmort.c */ -/* */ -/* TrueTypeGX/AAT mort table validation (body). */ -/* */ -/* Copyright 2005-2018 by */ -/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * gxvmort.c + * + * TrueTypeGX/AAT mort table validation (body). + * + * Copyright (C) 2005-2019 by + * suzuki toshiya, Masatake YAMATO, Red Hat K.K., + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + +/**************************************************************************** + * + * gxvalid is derived from both gxlayout module and otvalid module. + * Development of gxlayout is supported by the Information-technology + * Promotion Agency(IPA), Japan. + * + */ #include "gxvmort.h" #include "gxvfeat.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_gxvmort +#define FT_COMPONENT gxvmort static void @@ -123,6 +123,7 @@ GXV_Validator gxvalid ) { FT_UNUSED( gxvalid ); + FT_UNUSED( coverage ); #ifdef FT_DEBUG_LEVEL_TRACE if ( coverage & 0x8000U ) diff --git a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmort.h b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmort.h index d8030645e99ec..0619e24fb9df6 100644 --- a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmort.h +++ b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmort.h @@ -1,28 +1,28 @@ -/***************************************************************************/ -/* */ -/* gxvmort.h */ -/* */ -/* TrueTypeGX/AAT common definition for mort table (specification). */ -/* */ -/* Copyright 2004-2018 by */ -/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * gxvmort.h + * + * TrueTypeGX/AAT common definition for mort table (specification). + * + * Copyright (C) 2004-2019 by + * suzuki toshiya, Masatake YAMATO, Red Hat K.K., + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + +/**************************************************************************** + * + * gxvalid is derived from both gxlayout module and otvalid module. + * Development of gxlayout is supported by the Information-technology + * Promotion Agency(IPA), Japan. + * + */ #ifndef GXVMORT_H_ diff --git a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmort0.c b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmort0.c index 95cf53d5ebfce..2c01bf95ec7d3 100644 --- a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmort0.c +++ b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmort0.c @@ -1,42 +1,42 @@ -/***************************************************************************/ -/* */ -/* gxvmort0.c */ -/* */ -/* TrueTypeGX/AAT mort table validation */ -/* body for type0 (Indic Script Rearrangement) subtable. */ -/* */ -/* Copyright 2005-2018 by */ -/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * gxvmort0.c + * + * TrueTypeGX/AAT mort table validation + * body for type0 (Indic Script Rearrangement) subtable. + * + * Copyright (C) 2005-2019 by + * suzuki toshiya, Masatake YAMATO, Red Hat K.K., + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + +/**************************************************************************** + * + * gxvalid is derived from both gxlayout module and otvalid module. + * Development of gxlayout is supported by the Information-technology + * Promotion Agency(IPA), Japan. + * + */ #include "gxvmort.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_gxvmort +#define FT_COMPONENT gxvmort static const char* GXV_Mort_IndicScript_Msg[] = diff --git a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmort1.c b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmort1.c index a7683a17b0b7c..c71ba13351cdf 100644 --- a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmort1.c +++ b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmort1.c @@ -1,42 +1,42 @@ -/***************************************************************************/ -/* */ -/* gxvmort1.c */ -/* */ -/* TrueTypeGX/AAT mort table validation */ -/* body for type1 (Contextual Substitution) subtable. */ -/* */ -/* Copyright 2005-2018 by */ -/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * gxvmort1.c + * + * TrueTypeGX/AAT mort table validation + * body for type1 (Contextual Substitution) subtable. + * + * Copyright (C) 2005-2019 by + * suzuki toshiya, Masatake YAMATO, Red Hat K.K., + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + +/**************************************************************************** + * + * gxvalid is derived from both gxlayout module and otvalid module. + * Development of gxlayout is supported by the Information-technology + * Promotion Agency(IPA), Japan. + * + */ #include "gxvmort.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_gxvmort +#define FT_COMPONENT gxvmort typedef struct GXV_mort_subtable_type1_StateOptRec_ diff --git a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmort2.c b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmort2.c index c23c2775a15e9..889d3bd582c62 100644 --- a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmort2.c +++ b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmort2.c @@ -1,42 +1,42 @@ -/***************************************************************************/ -/* */ -/* gxvmort2.c */ -/* */ -/* TrueTypeGX/AAT mort table validation */ -/* body for type2 (Ligature Substitution) subtable. */ -/* */ -/* Copyright 2005-2018 by */ -/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * gxvmort2.c + * + * TrueTypeGX/AAT mort table validation + * body for type2 (Ligature Substitution) subtable. + * + * Copyright (C) 2005-2019 by + * suzuki toshiya, Masatake YAMATO, Red Hat K.K., + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + +/**************************************************************************** + * + * gxvalid is derived from both gxlayout module and otvalid module. + * Development of gxlayout is supported by the Information-technology + * Promotion Agency(IPA), Japan. + * + */ #include "gxvmort.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_gxvmort +#define FT_COMPONENT gxvmort typedef struct GXV_mort_subtable_type2_StateOptRec_ diff --git a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmort4.c b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmort4.c index 9d21a5fc29df3..f8ce6cf789eb6 100644 --- a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmort4.c +++ b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmort4.c @@ -1,42 +1,42 @@ -/***************************************************************************/ -/* */ -/* gxvmort4.c */ -/* */ -/* TrueTypeGX/AAT mort table validation */ -/* body for type4 (Non-Contextual Glyph Substitution) subtable. */ -/* */ -/* Copyright 2005-2018 by */ -/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * gxvmort4.c + * + * TrueTypeGX/AAT mort table validation + * body for type4 (Non-Contextual Glyph Substitution) subtable. + * + * Copyright (C) 2005-2019 by + * suzuki toshiya, Masatake YAMATO, Red Hat K.K., + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + +/**************************************************************************** + * + * gxvalid is derived from both gxlayout module and otvalid module. + * Development of gxlayout is supported by the Information-technology + * Promotion Agency(IPA), Japan. + * + */ #include "gxvmort.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_gxvmort +#define FT_COMPONENT gxvmort static void diff --git a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmort5.c b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmort5.c index 42cb428aa8801..1ba1e5ded0587 100644 --- a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmort5.c +++ b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmort5.c @@ -1,42 +1,42 @@ -/***************************************************************************/ -/* */ -/* gxvmort5.c */ -/* */ -/* TrueTypeGX/AAT mort table validation */ -/* body for type5 (Contextual Glyph Insertion) subtable. */ -/* */ -/* Copyright 2005-2018 by */ -/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * gxvmort5.c + * + * TrueTypeGX/AAT mort table validation + * body for type5 (Contextual Glyph Insertion) subtable. + * + * Copyright (C) 2005-2019 by + * suzuki toshiya, Masatake YAMATO, Red Hat K.K., + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + +/**************************************************************************** + * + * gxvalid is derived from both gxlayout module and otvalid module. + * Development of gxlayout is supported by the Information-technology + * Promotion Agency(IPA), Japan. + * + */ #include "gxvmort.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_gxvmort +#define FT_COMPONENT gxvmort /* diff --git a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmorx.c b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmorx.c index 9fd6e6b971ed5..8bd45c27e6b8f 100644 --- a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmorx.c +++ b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmorx.c @@ -1,41 +1,41 @@ -/***************************************************************************/ -/* */ -/* gxvmorx.c */ -/* */ -/* TrueTypeGX/AAT morx table validation (body). */ -/* */ -/* Copyright 2005-2018 by */ -/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * gxvmorx.c + * + * TrueTypeGX/AAT morx table validation (body). + * + * Copyright (C) 2005-2019 by + * suzuki toshiya, Masatake YAMATO, Red Hat K.K., + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + +/**************************************************************************** + * + * gxvalid is derived from both gxlayout module and otvalid module. + * Development of gxlayout is supported by the Information-technology + * Promotion Agency(IPA), Japan. + * + */ #include "gxvmorx.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_gxvmorx +#define FT_COMPONENT gxvmorx static void diff --git a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmorx.h b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmorx.h index 6d9925e92b2a1..e25727034247a 100644 --- a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmorx.h +++ b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmorx.h @@ -1,28 +1,28 @@ -/***************************************************************************/ -/* */ -/* gxvmorx.h */ -/* */ -/* TrueTypeGX/AAT common definition for morx table (specification). */ -/* */ -/* Copyright 2005-2018 by */ -/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * gxvmorx.h + * + * TrueTypeGX/AAT common definition for morx table (specification). + * + * Copyright (C) 2005-2019 by + * suzuki toshiya, Masatake YAMATO, Red Hat K.K., + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + +/**************************************************************************** + * + * gxvalid is derived from both gxlayout module and otvalid module. + * Development of gxlayout is supported by the Information-technology + * Promotion Agency(IPA), Japan. + * + */ #ifndef GXVMORX_H_ diff --git a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmorx0.c b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmorx0.c index 302261b7fa268..d7764a0ae8b46 100644 --- a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmorx0.c +++ b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmorx0.c @@ -1,42 +1,42 @@ -/***************************************************************************/ -/* */ -/* gxvmorx0.c */ -/* */ -/* TrueTypeGX/AAT morx table validation */ -/* body for type0 (Indic Script Rearrangement) subtable. */ -/* */ -/* Copyright 2005-2018 by */ -/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * gxvmorx0.c + * + * TrueTypeGX/AAT morx table validation + * body for type0 (Indic Script Rearrangement) subtable. + * + * Copyright (C) 2005-2019 by + * suzuki toshiya, Masatake YAMATO, Red Hat K.K., + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + +/**************************************************************************** + * + * gxvalid is derived from both gxlayout module and otvalid module. + * Development of gxlayout is supported by the Information-technology + * Promotion Agency(IPA), Japan. + * + */ #include "gxvmorx.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_gxvmorx +#define FT_COMPONENT gxvmorx static void diff --git a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmorx1.c b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmorx1.c index 890ca74b1d124..5b41b3605f87c 100644 --- a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmorx1.c +++ b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmorx1.c @@ -1,42 +1,42 @@ -/***************************************************************************/ -/* */ -/* gxvmorx1.c */ -/* */ -/* TrueTypeGX/AAT morx table validation */ -/* body for type1 (Contextual Substitution) subtable. */ -/* */ -/* Copyright 2005-2018 by */ -/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * gxvmorx1.c + * + * TrueTypeGX/AAT morx table validation + * body for type1 (Contextual Substitution) subtable. + * + * Copyright (C) 2005-2019 by + * suzuki toshiya, Masatake YAMATO, Red Hat K.K., + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + +/**************************************************************************** + * + * gxvalid is derived from both gxlayout module and otvalid module. + * Development of gxlayout is supported by the Information-technology + * Promotion Agency(IPA), Japan. + * + */ #include "gxvmorx.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_gxvmorx +#define FT_COMPONENT gxvmorx typedef struct GXV_morx_subtable_type1_StateOptRec_ diff --git a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmorx2.c b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmorx2.c index 3135031d4576f..ec4c81299d640 100644 --- a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmorx2.c +++ b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmorx2.c @@ -1,42 +1,42 @@ -/***************************************************************************/ -/* */ -/* gxvmorx2.c */ -/* */ -/* TrueTypeGX/AAT morx table validation */ -/* body for type2 (Ligature Substitution) subtable. */ -/* */ -/* Copyright 2005-2018 by */ -/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * gxvmorx2.c + * + * TrueTypeGX/AAT morx table validation + * body for type2 (Ligature Substitution) subtable. + * + * Copyright (C) 2005-2019 by + * suzuki toshiya, Masatake YAMATO, Red Hat K.K., + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + +/**************************************************************************** + * + * gxvalid is derived from both gxlayout module and otvalid module. + * Development of gxlayout is supported by the Information-technology + * Promotion Agency(IPA), Japan. + * + */ #include "gxvmorx.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_gxvmorx +#define FT_COMPONENT gxvmorx typedef struct GXV_morx_subtable_type2_StateOptRec_ diff --git a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmorx4.c b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmorx4.c index 1e2397b0c57f1..7b041534c0b96 100644 --- a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmorx4.c +++ b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmorx4.c @@ -1,42 +1,42 @@ -/***************************************************************************/ -/* */ -/* gxvmorx4.c */ -/* */ -/* TrueTypeGX/AAT morx table validation */ -/* body for "morx" type4 (Non-Contextual Glyph Substitution) subtable. */ -/* */ -/* Copyright 2005-2018 by */ -/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * gxvmorx4.c + * + * TrueTypeGX/AAT morx table validation + * body for "morx" type4 (Non-Contextual Glyph Substitution) subtable. + * + * Copyright (C) 2005-2019 by + * suzuki toshiya, Masatake YAMATO, Red Hat K.K., + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + +/**************************************************************************** + * + * gxvalid is derived from both gxlayout module and otvalid module. + * Development of gxlayout is supported by the Information-technology + * Promotion Agency(IPA), Japan. + * + */ #include "gxvmorx.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_gxvmorx +#define FT_COMPONENT gxvmorx FT_LOCAL_DEF( void ) diff --git a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmorx5.c b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmorx5.c index db4f9290c8ed1..70a462365650f 100644 --- a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmorx5.c +++ b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmorx5.c @@ -1,42 +1,42 @@ -/***************************************************************************/ -/* */ -/* gxvmorx5.c */ -/* */ -/* TrueTypeGX/AAT morx table validation */ -/* body for type5 (Contextual Glyph Insertion) subtable. */ -/* */ -/* Copyright 2005-2018 by */ -/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * gxvmorx5.c + * + * TrueTypeGX/AAT morx table validation + * body for type5 (Contextual Glyph Insertion) subtable. + * + * Copyright (C) 2005-2019 by + * suzuki toshiya, Masatake YAMATO, Red Hat K.K., + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + +/**************************************************************************** + * + * gxvalid is derived from both gxlayout module and otvalid module. + * Development of gxlayout is supported by the Information-technology + * Promotion Agency(IPA), Japan. + * + */ #include "gxvmorx.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_gxvmorx +#define FT_COMPONENT gxvmorx /* diff --git a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvopbd.c b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvopbd.c index e2c167ea599f7..f055a22054415 100644 --- a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvopbd.c +++ b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvopbd.c @@ -1,42 +1,42 @@ -/***************************************************************************/ -/* */ -/* gxvopbd.c */ -/* */ -/* TrueTypeGX/AAT opbd table validation (body). */ -/* */ -/* Copyright 2004-2018 by */ -/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * gxvopbd.c + * + * TrueTypeGX/AAT opbd table validation (body). + * + * Copyright (C) 2004-2019 by + * suzuki toshiya, Masatake YAMATO, Red Hat K.K., + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + +/**************************************************************************** + * + * gxvalid is derived from both gxlayout module and otvalid module. + * Development of gxlayout is supported by the Information-technology + * Promotion Agency(IPA), Japan. + * + */ #include "gxvalid.h" #include "gxvcommn.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_gxvopbd +#define FT_COMPONENT gxvopbd /*************************************************************************/ diff --git a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvprop.c b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvprop.c index a67b6bdd009dc..e1911edd48d02 100644 --- a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvprop.c +++ b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvprop.c @@ -1,42 +1,42 @@ -/***************************************************************************/ -/* */ -/* gxvprop.c */ -/* */ -/* TrueTypeGX/AAT prop table validation (body). */ -/* */ -/* Copyright 2004-2018 by */ -/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * gxvprop.c + * + * TrueTypeGX/AAT prop table validation (body). + * + * Copyright (C) 2004-2019 by + * suzuki toshiya, Masatake YAMATO, Red Hat K.K., + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + +/**************************************************************************** + * + * gxvalid is derived from both gxlayout module and otvalid module. + * Development of gxlayout is supported by the Information-technology + * Promotion Agency(IPA), Japan. + * + */ #include "gxvalid.h" #include "gxvcommn.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_gxvprop +#define FT_COMPONENT gxvprop /*************************************************************************/ diff --git a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvtrak.c b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvtrak.c index d501b5014b57a..b7794b7af4640 100644 --- a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvtrak.c +++ b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvtrak.c @@ -1,42 +1,42 @@ -/***************************************************************************/ -/* */ -/* gxvtrak.c */ -/* */ -/* TrueTypeGX/AAT trak table validation (body). */ -/* */ -/* Copyright 2004-2018 by */ -/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* */ -/* gxvalid is derived from both gxlayout module and otvalid module. */ -/* Development of gxlayout is supported by the Information-technology */ -/* Promotion Agency(IPA), Japan. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * gxvtrak.c + * + * TrueTypeGX/AAT trak table validation (body). + * + * Copyright (C) 2004-2019 by + * suzuki toshiya, Masatake YAMATO, Red Hat K.K., + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + +/**************************************************************************** + * + * gxvalid is derived from both gxlayout module and otvalid module. + * Development of gxlayout is supported by the Information-technology + * Promotion Agency(IPA), Japan. + * + */ #include "gxvalid.h" #include "gxvcommn.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_gxvtrak +#define FT_COMPONENT gxvtrak /*************************************************************************/ diff --git a/sdk/lib/3rdparty/freetype/src/gzip/ftgzip.c b/sdk/lib/3rdparty/freetype/src/gzip/ftgzip.c index f8011c2dd829e..a5206307f4e2c 100644 --- a/sdk/lib/3rdparty/freetype/src/gzip/ftgzip.c +++ b/sdk/lib/3rdparty/freetype/src/gzip/ftgzip.c @@ -1,23 +1,23 @@ -/***************************************************************************/ -/* */ -/* ftgzip.c */ -/* */ -/* FreeType support for .gz compressed files. */ -/* */ -/* This optional component relies on zlib. It should mainly be used to */ -/* parse compressed PCF fonts, as found with many X11 server */ -/* distributions. */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftgzip.c + * + * FreeType support for .gz compressed files. + * + * This optional component relies on zlib. It should mainly be used to + * parse compressed PCF fonts, as found with many X11 server + * distributions. + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -41,10 +41,6 @@ #ifdef FT_CONFIG_OPTION_USE_ZLIB -#ifdef FT_CONFIG_OPTION_PIC -#error "gzip code does not support PIC yet" -#endif - #ifdef FT_CONFIG_OPTION_SYSTEM_ZLIB #include <zlib.h> @@ -637,8 +633,8 @@ memory = source->memory; /* - * check the header right now; this prevents allocating un-necessary - * objects when we don't need them + * check the header right now; this prevents allocating un-necessary + * objects when we don't need them */ error = ft_gzip_check_header( source ); if ( error ) @@ -660,12 +656,12 @@ } /* - * We use the following trick to try to dramatically improve the - * performance while dealing with small files. If the original stream - * size is less than a certain threshold, we try to load the whole font - * file into memory. This saves us from using the 32KB buffer needed - * to inflate the file, plus the two 4KB intermediate input/output - * buffers used in the `FT_GZipFile' structure. + * We use the following trick to try to dramatically improve the + * performance while dealing with small files. If the original stream + * size is less than a certain threshold, we try to load the whole font + * file into memory. This saves us from using the 32KB buffer needed + * to inflate the file, plus the two 4KB intermediate input/output + * buffers used in the `FT_GZipFile' structure. */ { FT_ULong zip_size = ft_gzip_get_uncompressed_size( source ); @@ -735,7 +731,7 @@ /* check for `input' delayed to `inflate' */ - if ( !memory || ! output_len || !output ) + if ( !memory || !output_len || !output ) return FT_THROW( Invalid_Argument ); /* this function is modeled after zlib's `uncompress' function */ diff --git a/sdk/lib/3rdparty/freetype/src/lzw/ftlzw.c b/sdk/lib/3rdparty/freetype/src/lzw/ftlzw.c index cb46f93c68e0d..9805a1e3bd0ea 100644 --- a/sdk/lib/3rdparty/freetype/src/lzw/ftlzw.c +++ b/sdk/lib/3rdparty/freetype/src/lzw/ftlzw.c @@ -1,25 +1,25 @@ -/***************************************************************************/ -/* */ -/* ftlzw.c */ -/* */ -/* FreeType support for .Z compressed files. */ -/* */ -/* This optional component relies on NetBSD's zopen(). It should mainly */ -/* be used to parse compressed PCF fonts, as found with many X11 server */ -/* distributions. */ -/* */ -/* Copyright 2004-2018 by */ -/* Albert Chin-A-Young. */ -/* */ -/* based on code in `src/gzip/ftgzip.c' */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftlzw.c + * + * FreeType support for .Z compressed files. + * + * This optional component relies on NetBSD's zopen(). It should mainly + * be used to parse compressed PCF fonts, as found with many X11 server + * distributions. + * + * Copyright (C) 2004-2019 by + * Albert Chin-A-Young. + * + * based on code in `src/gzip/ftgzip.c' + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> #include FT_INTERNAL_MEMORY_H @@ -42,10 +42,6 @@ #ifdef FT_CONFIG_OPTION_USE_LZW -#ifdef FT_CONFIG_OPTION_PIC -#error "lzw code does not support PIC yet" -#endif - #include "ftzopen.h" @@ -361,11 +357,11 @@ memory = source->memory; /* - * Check the header right now; this prevents allocation of a huge - * LZWFile object (400 KByte of heap memory) if not necessary. + * Check the header right now; this prevents allocation of a huge + * LZWFile object (400 KByte of heap memory) if not necessary. * - * Did I mention that you should never use .Z compressed font - * files? + * Did I mention that you should never use .Z compressed font + * files? */ error = ft_lzw_check_header( source ); if ( error ) diff --git a/sdk/lib/3rdparty/freetype/src/lzw/ftzopen.c b/sdk/lib/3rdparty/freetype/src/lzw/ftzopen.c index 2b868ba9f2d23..67e6760f95f90 100644 --- a/sdk/lib/3rdparty/freetype/src/lzw/ftzopen.c +++ b/sdk/lib/3rdparty/freetype/src/lzw/ftzopen.c @@ -1,23 +1,23 @@ -/***************************************************************************/ -/* */ -/* ftzopen.c */ -/* */ -/* FreeType support for .Z compressed files. */ -/* */ -/* This optional component relies on NetBSD's zopen(). It should mainly */ -/* be used to parse compressed PCF fonts, as found with many X11 server */ -/* distributions. */ -/* */ -/* Copyright 2005-2018 by */ -/* David Turner. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftzopen.c + * + * FreeType support for .Z compressed files. + * + * This optional component relies on NetBSD's zopen(). It should mainly + * be used to parse compressed PCF fonts, as found with many X11 server + * distributions. + * + * Copyright (C) 2005-2019 by + * David Turner. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include "ftzopen.h" #include FT_INTERNAL_MEMORY_H @@ -167,11 +167,11 @@ new_size += new_size >> 2; /* don't grow too fast */ /* - * Note that the `suffix' array is located in the same memory block - * pointed to by `prefix'. + * Note that the `suffix' array is located in the same memory block + * pointed to by `prefix'. * - * I know that sizeof(FT_Byte) == 1 by definition, but it is clearer - * to write it literally. + * I know that sizeof(FT_Byte) == 1 by definition, but it is clearer + * to write it literally. * */ if ( FT_REALLOC_MULT( state->prefix, old_size, new_size, diff --git a/sdk/lib/3rdparty/freetype/src/lzw/ftzopen.h b/sdk/lib/3rdparty/freetype/src/lzw/ftzopen.h index 4fd267eb90fb8..44fe36d6c5b76 100644 --- a/sdk/lib/3rdparty/freetype/src/lzw/ftzopen.h +++ b/sdk/lib/3rdparty/freetype/src/lzw/ftzopen.h @@ -1,23 +1,23 @@ -/***************************************************************************/ -/* */ -/* ftzopen.h */ -/* */ -/* FreeType support for .Z compressed files. */ -/* */ -/* This optional component relies on NetBSD's zopen(). It should mainly */ -/* be used to parse compressed PCF fonts, as found with many X11 server */ -/* distributions. */ -/* */ -/* Copyright 2005-2018 by */ -/* David Turner. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftzopen.h + * + * FreeType support for .Z compressed files. + * + * This optional component relies on NetBSD's zopen(). It should mainly + * be used to parse compressed PCF fonts, as found with many X11 server + * distributions. + * + * Copyright (C) 2005-2019 by + * David Turner. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTZOPEN_H_ #define FTZOPEN_H_ @@ -27,9 +27,9 @@ /* - * This is a complete re-implementation of the LZW file reader, - * since the old one was incredibly badly written, using - * 400 KByte of heap memory before decompressing anything. + * This is a complete re-implementation of the LZW file reader, + * since the old one was incredibly badly written, using + * 400 KByte of heap memory before decompressing anything. * */ @@ -58,56 +58,56 @@ /* - * state of LZW decompressor + * state of LZW decompressor * - * small technical note - * -------------------- + * small technical note + * -------------------- * - * We use a few tricks in this implementation that are explained here to - * ease debugging and maintenance. + * We use a few tricks in this implementation that are explained here to + * ease debugging and maintenance. * - * - First of all, the `prefix' and `suffix' arrays contain the suffix - * and prefix for codes over 256; this means that + * - First of all, the `prefix' and `suffix' arrays contain the suffix + * and prefix for codes over 256; this means that * - * prefix_of(code) == state->prefix[code-256] - * suffix_of(code) == state->suffix[code-256] + * prefix_of(code) == state->prefix[code-256] + * suffix_of(code) == state->suffix[code-256] * - * Each prefix is a 16-bit code, and each suffix an 8-bit byte. + * Each prefix is a 16-bit code, and each suffix an 8-bit byte. * - * Both arrays are stored in a single memory block, pointed to by - * `state->prefix'. This means that the following equality is always - * true: + * Both arrays are stored in a single memory block, pointed to by + * `state->prefix'. This means that the following equality is always + * true: * - * state->suffix == (FT_Byte*)(state->prefix + state->prefix_size) + * state->suffix == (FT_Byte*)(state->prefix + state->prefix_size) * - * Of course, state->prefix_size is the number of prefix/suffix slots - * in the arrays, corresponding to codes 256..255+prefix_size. + * Of course, state->prefix_size is the number of prefix/suffix slots + * in the arrays, corresponding to codes 256..255+prefix_size. * - * - `free_ent' is the index of the next free entry in the `prefix' - * and `suffix' arrays. This means that the corresponding `next free - * code' is really `256+free_ent'. + * - `free_ent' is the index of the next free entry in the `prefix' + * and `suffix' arrays. This means that the corresponding `next free + * code' is really `256+free_ent'. * - * Moreover, `max_free' is the maximum value that `free_ent' can reach. + * Moreover, `max_free' is the maximum value that `free_ent' can reach. * - * `max_free' corresponds to `(1 << max_bits) - 256'. Note that this - * value is always <= 0xFF00, which means that both `free_ent' and - * `max_free' can be stored in an FT_UInt variable, even on 16-bit - * machines. + * `max_free' corresponds to `(1 << max_bits) - 256'. Note that this + * value is always <= 0xFF00, which means that both `free_ent' and + * `max_free' can be stored in an FT_UInt variable, even on 16-bit + * machines. * - * If `free_ent == max_free', you cannot add new codes to the - * prefix/suffix table. + * If `free_ent == max_free', you cannot add new codes to the + * prefix/suffix table. * - * - `num_bits' is the current number of code bits, starting at 9 and - * growing each time `free_ent' reaches the value of `free_bits'. The - * latter is computed as follows + * - `num_bits' is the current number of code bits, starting at 9 and + * growing each time `free_ent' reaches the value of `free_bits'. The + * latter is computed as follows * - * if num_bits < max_bits: - * free_bits = (1 << num_bits)-256 - * else: - * free_bits = max_free + 1 + * if num_bits < max_bits: + * free_bits = (1 << num_bits)-256 + * else: + * free_bits = max_free + 1 * - * Since the value of `max_free + 1' can never be reached by - * `free_ent', `num_bits' cannot grow larger than `max_bits'. + * Since the value of `max_free + 1' can never be reached by + * `free_ent', `num_bits' cannot grow larger than `max_bits'. */ typedef struct FT_LzwStateRec_ diff --git a/sdk/lib/3rdparty/freetype/src/otvalid/otvalid.c b/sdk/lib/3rdparty/freetype/src/otvalid/otvalid.c index 4423ca1012823..e3964b99aee7c 100644 --- a/sdk/lib/3rdparty/freetype/src/otvalid/otvalid.c +++ b/sdk/lib/3rdparty/freetype/src/otvalid/otvalid.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* otvalid.c */ -/* */ -/* FreeType validator for OpenType tables (body only). */ -/* */ -/* Copyright 2004-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * otvalid.c + * + * FreeType validator for OpenType tables (body only). + * + * Copyright (C) 2004-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #define FT_MAKE_OPTION_SINGLE_OBJECT diff --git a/sdk/lib/3rdparty/freetype/src/otvalid/otvalid.h b/sdk/lib/3rdparty/freetype/src/otvalid/otvalid.h index d7801abae501b..5ca819f26194f 100644 --- a/sdk/lib/3rdparty/freetype/src/otvalid/otvalid.h +++ b/sdk/lib/3rdparty/freetype/src/otvalid/otvalid.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* otvalid.h */ -/* */ -/* OpenType table validation (specification only). */ -/* */ -/* Copyright 2004-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * otvalid.h + * + * OpenType table validation (specification only). + * + * Copyright (C) 2004-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef OTVALID_H_ diff --git a/sdk/lib/3rdparty/freetype/src/otvalid/otvbase.c b/sdk/lib/3rdparty/freetype/src/otvalid/otvbase.c index a01d45c707a40..be69d7ca31d78 100644 --- a/sdk/lib/3rdparty/freetype/src/otvalid/otvbase.c +++ b/sdk/lib/3rdparty/freetype/src/otvalid/otvbase.c @@ -1,33 +1,33 @@ -/***************************************************************************/ -/* */ -/* otvbase.c */ -/* */ -/* OpenType BASE table validation (body). */ -/* */ -/* Copyright 2004-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * otvbase.c + * + * OpenType BASE table validation (body). + * + * Copyright (C) 2004-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include "otvalid.h" #include "otvcommn.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_otvbase +#define FT_COMPONENT otvbase static void diff --git a/sdk/lib/3rdparty/freetype/src/otvalid/otvcommn.c b/sdk/lib/3rdparty/freetype/src/otvalid/otvcommn.c index 0ccfb03c08a7d..5ed1723506fff 100644 --- a/sdk/lib/3rdparty/freetype/src/otvalid/otvcommn.c +++ b/sdk/lib/3rdparty/freetype/src/otvalid/otvcommn.c @@ -1,32 +1,32 @@ -/***************************************************************************/ -/* */ -/* otvcommn.c */ -/* */ -/* OpenType common tables validation (body). */ -/* */ -/* Copyright 2004-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * otvcommn.c + * + * OpenType common tables validation (body). + * + * Copyright (C) 2004-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include "otvcommn.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_otvcommon +#define FT_COMPONENT otvcommon /*************************************************************************/ diff --git a/sdk/lib/3rdparty/freetype/src/otvalid/otvcommn.h b/sdk/lib/3rdparty/freetype/src/otvalid/otvcommn.h index a392784cf1902..bfcc5b974a399 100644 --- a/sdk/lib/3rdparty/freetype/src/otvalid/otvcommn.h +++ b/sdk/lib/3rdparty/freetype/src/otvalid/otvcommn.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* otvcommn.h */ -/* */ -/* OpenType common tables validation (specification). */ -/* */ -/* Copyright 2004-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * otvcommn.h + * + * OpenType common tables validation (specification). + * + * Copyright (C) 2004-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef OTVCOMMN_H_ diff --git a/sdk/lib/3rdparty/freetype/src/otvalid/otverror.h b/sdk/lib/3rdparty/freetype/src/otvalid/otverror.h index 2fcf42e387565..a7d35acf1abca 100644 --- a/sdk/lib/3rdparty/freetype/src/otvalid/otverror.h +++ b/sdk/lib/3rdparty/freetype/src/otvalid/otverror.h @@ -1,27 +1,27 @@ -/***************************************************************************/ -/* */ -/* otverror.h */ -/* */ -/* OpenType validation module error codes (specification only). */ -/* */ -/* Copyright 2004-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to define the OpenType validation module error */ - /* enumeration constants. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * otverror.h + * + * OpenType validation module error codes (specification only). + * + * Copyright (C) 2004-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /************************************************************************** + * + * This file is used to define the OpenType validation module error + * enumeration constants. + * + */ #ifndef OTVERROR_H_ #define OTVERROR_H_ diff --git a/sdk/lib/3rdparty/freetype/src/otvalid/otvgdef.c b/sdk/lib/3rdparty/freetype/src/otvalid/otvgdef.c index 08f3171541f4e..2529b544d2ade 100644 --- a/sdk/lib/3rdparty/freetype/src/otvalid/otvgdef.c +++ b/sdk/lib/3rdparty/freetype/src/otvalid/otvgdef.c @@ -1,33 +1,33 @@ -/***************************************************************************/ -/* */ -/* otvgdef.c */ -/* */ -/* OpenType GDEF table validation (body). */ -/* */ -/* Copyright 2004-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * otvgdef.c + * + * OpenType GDEF table validation (body). + * + * Copyright (C) 2004-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include "otvalid.h" #include "otvcommn.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_otvgdef +#define FT_COMPONENT otvgdef /*************************************************************************/ diff --git a/sdk/lib/3rdparty/freetype/src/otvalid/otvgpos.c b/sdk/lib/3rdparty/freetype/src/otvalid/otvgpos.c index 696b35cae6230..f3bddeac6ccc3 100644 --- a/sdk/lib/3rdparty/freetype/src/otvalid/otvgpos.c +++ b/sdk/lib/3rdparty/freetype/src/otvalid/otvgpos.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* otvgpos.c */ -/* */ -/* OpenType GPOS table validation (body). */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * otvgpos.c + * + * OpenType GPOS table validation (body). + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include "otvalid.h" @@ -21,14 +21,14 @@ #include "otvgpos.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_otvgpos +#define FT_COMPONENT otvgpos static void diff --git a/sdk/lib/3rdparty/freetype/src/otvalid/otvgpos.h b/sdk/lib/3rdparty/freetype/src/otvalid/otvgpos.h index 95f9ac3ee85e2..b3154312eb1e0 100644 --- a/sdk/lib/3rdparty/freetype/src/otvalid/otvgpos.h +++ b/sdk/lib/3rdparty/freetype/src/otvalid/otvgpos.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* otvgpos.h */ -/* */ -/* OpenType GPOS table validator (specification). */ -/* */ -/* Copyright 2004-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * otvgpos.h + * + * OpenType GPOS table validator (specification). + * + * Copyright (C) 2004-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef OTVGPOS_H_ diff --git a/sdk/lib/3rdparty/freetype/src/otvalid/otvgsub.c b/sdk/lib/3rdparty/freetype/src/otvalid/otvgsub.c index d35ea67f30988..97da997d3da6d 100644 --- a/sdk/lib/3rdparty/freetype/src/otvalid/otvgsub.c +++ b/sdk/lib/3rdparty/freetype/src/otvalid/otvgsub.c @@ -1,33 +1,33 @@ -/***************************************************************************/ -/* */ -/* otvgsub.c */ -/* */ -/* OpenType GSUB table validation (body). */ -/* */ -/* Copyright 2004-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * otvgsub.c + * + * OpenType GSUB table validation (body). + * + * Copyright (C) 2004-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include "otvalid.h" #include "otvcommn.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_otvgsub +#define FT_COMPONENT otvgsub /*************************************************************************/ diff --git a/sdk/lib/3rdparty/freetype/src/otvalid/otvjstf.c b/sdk/lib/3rdparty/freetype/src/otvalid/otvjstf.c index 94d4af90f6f75..d4e6d871787fc 100644 --- a/sdk/lib/3rdparty/freetype/src/otvalid/otvjstf.c +++ b/sdk/lib/3rdparty/freetype/src/otvalid/otvjstf.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* otvjstf.c */ -/* */ -/* OpenType JSTF table validation (body). */ -/* */ -/* Copyright 2004-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * otvjstf.c + * + * OpenType JSTF table validation (body). + * + * Copyright (C) 2004-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include "otvalid.h" @@ -21,14 +21,14 @@ #include "otvgpos.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_otvjstf +#define FT_COMPONENT otvjstf #define JstfPriorityFunc otv_JstfPriority_validate diff --git a/sdk/lib/3rdparty/freetype/src/otvalid/otvmath.c b/sdk/lib/3rdparty/freetype/src/otvalid/otvmath.c index b9800f60a2660..3aaf0ec0ec5fc 100644 --- a/sdk/lib/3rdparty/freetype/src/otvalid/otvmath.c +++ b/sdk/lib/3rdparty/freetype/src/otvalid/otvmath.c @@ -1,21 +1,21 @@ -/***************************************************************************/ -/* */ -/* otvmath.c */ -/* */ -/* OpenType MATH table validation (body). */ -/* */ -/* Copyright 2007-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* Written by George Williams. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * otvmath.c + * + * OpenType MATH table validation (body). + * + * Copyright (C) 2007-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * Written by George Williams. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include "otvalid.h" @@ -23,14 +23,14 @@ #include "otvgpos.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_otvmath +#define FT_COMPONENT otvmath diff --git a/sdk/lib/3rdparty/freetype/src/otvalid/otvmod.c b/sdk/lib/3rdparty/freetype/src/otvalid/otvmod.c index 89ee449d16de6..f417bd220f5c2 100644 --- a/sdk/lib/3rdparty/freetype/src/otvalid/otvmod.c +++ b/sdk/lib/3rdparty/freetype/src/otvalid/otvmod.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* otvmod.c */ -/* */ -/* FreeType's OpenType validation module implementation (body). */ -/* */ -/* Copyright 2004-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * otvmod.c + * + * FreeType's OpenType validation module implementation (body). + * + * Copyright (C) 2004-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -28,14 +28,14 @@ #include "otvcommn.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_otvmodule +#define FT_COMPONENT otvmodule static FT_Error diff --git a/sdk/lib/3rdparty/freetype/src/otvalid/otvmod.h b/sdk/lib/3rdparty/freetype/src/otvalid/otvmod.h index 6917bccee5d14..5539de7ec6e0c 100644 --- a/sdk/lib/3rdparty/freetype/src/otvalid/otvmod.h +++ b/sdk/lib/3rdparty/freetype/src/otvalid/otvmod.h @@ -1,20 +1,20 @@ -/***************************************************************************/ -/* */ -/* otvmod.h */ -/* */ -/* FreeType's OpenType validation module implementation */ -/* (specification). */ -/* */ -/* Copyright 2004-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * otvmod.h + * + * FreeType's OpenType validation module implementation + * (specification). + * + * Copyright (C) 2004-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef OTVMOD_H_ @@ -27,10 +27,6 @@ FT_BEGIN_HEADER -#ifdef FT_CONFIG_OPTION_PIC -#error "this module does not support PIC yet" -#endif - FT_EXPORT_VAR( const FT_Module_Class ) otv_module_class; diff --git a/sdk/lib/3rdparty/freetype/src/pcf/pcf.h b/sdk/lib/3rdparty/freetype/src/pcf/pcf.h index f0390cb1eb3da..529dd3adf867e 100644 --- a/sdk/lib/3rdparty/freetype/src/pcf/pcf.h +++ b/sdk/lib/3rdparty/freetype/src/pcf/pcf.h @@ -104,6 +104,19 @@ FT_BEGIN_HEADER } PCF_MetricRec, *PCF_Metric; + typedef struct PCF_EncRec_ + { + FT_UShort firstCol; + FT_UShort lastCol; + FT_UShort firstRow; + FT_UShort lastRow; + FT_UShort defaultChar; + + FT_UShort* offset; + + } PCF_EncRec, *PCF_Enc; + + typedef struct PCF_AccelRec_ { FT_Byte noOverlap; @@ -124,41 +137,32 @@ FT_BEGIN_HEADER } PCF_AccelRec, *PCF_Accel; - typedef struct PCF_EncodingRec_ - { - FT_Long enc; - FT_UShort glyph; - - } PCF_EncodingRec, *PCF_Encoding; - - + /* + * This file uses X11 terminology for PCF data; an `encoding' in X11 speak + * is the same as a `character code' in FreeType speak. + */ typedef struct PCF_FaceRec_ { - FT_FaceRec root; - - FT_StreamRec comp_stream; - FT_Stream comp_source; + FT_FaceRec root; - char* charset_encoding; - char* charset_registry; + FT_StreamRec comp_stream; + FT_Stream comp_source; - PCF_TocRec toc; - PCF_AccelRec accel; + char* charset_encoding; + char* charset_registry; - int nprops; - PCF_Property properties; + PCF_TocRec toc; + PCF_AccelRec accel; - FT_ULong nmetrics; - PCF_Metric metrics; - FT_ULong nencodings; - PCF_Encoding encodings; + int nprops; + PCF_Property properties; - FT_Short defaultChar; + FT_ULong nmetrics; + PCF_Metric metrics; - FT_ULong bitmapsFormat; + PCF_EncRec enc; - FT_CharMap charmap_handle; - FT_CharMapRec charmap; /* a single charmap per face */ + FT_ULong bitmapsFormat; } PCF_FaceRec, *PCF_Face; diff --git a/sdk/lib/3rdparty/freetype/src/pcf/pcfdrivr.c b/sdk/lib/3rdparty/freetype/src/pcf/pcfdrivr.c index 0119d94853ab8..54bbb9d119c17 100644 --- a/sdk/lib/3rdparty/freetype/src/pcf/pcfdrivr.c +++ b/sdk/lib/3rdparty/freetype/src/pcf/pcfdrivr.c @@ -45,7 +45,7 @@ THE SOFTWARE. #include "pcfutil.h" #undef FT_COMPONENT -#define FT_COMPONENT trace_pcfread +#define FT_COMPONENT pcfread #include FT_SERVICE_BDF_H #include FT_SERVICE_FONT_FORMAT_H @@ -53,21 +53,24 @@ THE SOFTWARE. #include FT_DRIVER_H - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_pcfdriver +#define FT_COMPONENT pcfdriver + /* + * This file uses X11 terminology for PCF data; an `encoding' in X11 speak + * is the same as a `character code' in FreeType speak. + */ typedef struct PCF_CMapRec_ { - FT_CMapRec root; - FT_ULong num_encodings; - PCF_Encoding encodings; + FT_CMapRec root; + PCF_Enc enc; } PCF_CMapRec, *PCF_CMap; @@ -82,8 +85,7 @@ THE SOFTWARE. FT_UNUSED( init_data ); - cmap->num_encodings = face->nencodings; - cmap->encodings = face->encodings; + cmap->enc = &face->enc; return FT_Err_Ok; } @@ -95,8 +97,7 @@ THE SOFTWARE. PCF_CMap cmap = (PCF_CMap)pcfcmap; - cmap->encodings = NULL; - cmap->num_encodings = 0; + cmap->enc = NULL; } @@ -104,36 +105,26 @@ THE SOFTWARE. pcf_cmap_char_index( FT_CMap pcfcmap, /* PCF_CMap */ FT_UInt32 charcode ) { - PCF_CMap cmap = (PCF_CMap)pcfcmap; - PCF_Encoding encodings = cmap->encodings; - FT_ULong min, max, mid; - FT_UInt result = 0; + PCF_CMap cmap = (PCF_CMap)pcfcmap; + PCF_Enc enc = cmap->enc; + FT_UShort charcodeRow; + FT_UShort charcodeCol; - min = 0; - max = cmap->num_encodings; + if ( charcode > (FT_UInt32)( enc->lastRow * 256 + enc->lastCol ) || + charcode < (FT_UInt32)( enc->firstRow * 256 + enc->firstCol ) ) + return 0; - while ( min < max ) - { - FT_ULong code; + charcodeRow = (FT_UShort)( charcode >> 8 ); + charcodeCol = (FT_UShort)( charcode & 0xFF ); + if ( charcodeCol < enc->firstCol || + charcodeCol > enc->lastCol ) + return 0; - mid = ( min + max ) >> 1; - code = (FT_ULong)encodings[mid].enc; - - if ( charcode == code ) - { - result = encodings[mid].glyph + 1; - break; - } - - if ( charcode < code ) - max = mid; - else - min = mid + 1; - } - - return result; + return (FT_UInt)enc->offset[ ( charcodeRow - enc->firstRow ) * + ( enc->lastCol - enc->firstCol + 1 ) + + charcodeCol - enc->firstCol ]; } @@ -141,52 +132,43 @@ THE SOFTWARE. pcf_cmap_char_next( FT_CMap pcfcmap, /* PCF_CMap */ FT_UInt32 *acharcode ) { - PCF_CMap cmap = (PCF_CMap)pcfcmap; - PCF_Encoding encodings = cmap->encodings; - FT_ULong min, max, mid; - FT_ULong charcode = *acharcode + 1; - FT_UInt result = 0; - + PCF_CMap cmap = (PCF_CMap)pcfcmap; + PCF_Enc enc = cmap->enc; + FT_UInt32 charcode = *acharcode; + FT_UShort charcodeRow; + FT_UShort charcodeCol; + FT_Int result = 0; - min = 0; - max = cmap->num_encodings; - while ( min < max ) + while ( charcode < (FT_UInt32)( enc->lastRow * 256 + enc->lastCol ) ) { - FT_ULong code; + charcode++; + if ( charcode < (FT_UInt32)( enc->firstRow * 256 + enc->firstCol ) ) + charcode = (FT_UInt32)( enc->firstRow * 256 + enc->firstCol ); - mid = ( min + max ) >> 1; - code = (FT_ULong)encodings[mid].enc; + charcodeRow = (FT_UShort)( charcode >> 8 ); + charcodeCol = (FT_UShort)( charcode & 0xFF ); - if ( charcode == code ) + if ( charcodeCol < enc->firstCol ) + charcodeCol = enc->firstCol; + else if ( charcodeCol > enc->lastCol ) { - result = encodings[mid].glyph + 1; - goto Exit; + charcodeRow++; + charcodeCol = enc->firstCol; } - if ( charcode < code ) - max = mid; - else - min = mid + 1; - } + charcode = (FT_UInt32)( charcodeRow * 256 + charcodeCol ); - charcode = 0; - if ( min < cmap->num_encodings ) - { - charcode = (FT_ULong)encodings[min].enc; - result = encodings[min].glyph + 1; + result = (FT_UInt)enc->offset[ ( charcodeRow - enc->firstRow ) * + ( enc->lastCol - enc->firstCol + 1 ) + + charcodeCol - enc->firstCol ]; + if ( result != 0xFFFFU ) + break; } - Exit: - if ( charcode > 0xFFFFFFFFUL ) - { - FT_TRACE1(( "pcf_cmap_char_next: charcode 0x%x > 32bit API" )); - *acharcode = 0; - /* XXX: result should be changed to indicate an overflow error */ - } - else - *acharcode = (FT_UInt32)charcode; + *acharcode = charcode; + return result; } @@ -216,8 +198,8 @@ THE SOFTWARE. memory = FT_FACE_MEMORY( face ); - FT_FREE( face->encodings ); FT_FREE( face->metrics ); + FT_FREE( face->enc.offset ); /* free properties */ if ( face->properties ) @@ -512,9 +494,6 @@ THE SOFTWARE. stream = face->root.stream; - if ( glyph_index > 0 ) - glyph_index--; - metric = face->metrics + glyph_index; bitmap->rows = (unsigned int)( metric->ascent + @@ -601,11 +580,11 @@ THE SOFTWARE. } - /* - * - * BDF SERVICE - * - */ + /* + * + * BDF SERVICE + * + */ static FT_Error pcf_get_bdf_property( PCF_Face face, @@ -633,9 +612,9 @@ THE SOFTWARE. } /* - * The PCF driver loads all properties as signed integers. - * This really doesn't seem to be a problem, because this is - * sufficient for any meaningful values. + * The PCF driver loads all properties as signed integers. + * This really doesn't seem to be a problem, because this is + * sufficient for any meaningful values. */ aproperty->type = BDF_PROPERTY_TYPE_INTEGER; aproperty->u.integer = (FT_Int32)prop->value.l; @@ -668,7 +647,7 @@ THE SOFTWARE. /* - * PROPERTY SERVICE + * PROPERTY SERVICE * */ static FT_Error @@ -777,11 +756,11 @@ THE SOFTWARE. (FT_Properties_GetFunc)pcf_property_get ) /* get_property */ - /* - * - * SERVICE LIST - * - */ + /* + * + * SERVICE LIST + * + */ static const FT_ServiceDescRec pcf_services[] = { diff --git a/sdk/lib/3rdparty/freetype/src/pcf/pcfdrivr.h b/sdk/lib/3rdparty/freetype/src/pcf/pcfdrivr.h index 29d30497cd683..73db0823d25f3 100644 --- a/sdk/lib/3rdparty/freetype/src/pcf/pcfdrivr.h +++ b/sdk/lib/3rdparty/freetype/src/pcf/pcfdrivr.h @@ -31,11 +31,8 @@ THE SOFTWARE. #include <ft2build.h> #include FT_INTERNAL_DRIVER_H -FT_BEGIN_HEADER -#ifdef FT_CONFIG_OPTION_PIC -#error "this module does not support PIC yet" -#endif +FT_BEGIN_HEADER FT_EXPORT_VAR( const FT_Driver_ClassRec ) pcf_driver_class; diff --git a/sdk/lib/3rdparty/freetype/src/pcf/pcferror.h b/sdk/lib/3rdparty/freetype/src/pcf/pcferror.h index add8ef2230e31..2e69d1d21985f 100644 --- a/sdk/lib/3rdparty/freetype/src/pcf/pcferror.h +++ b/sdk/lib/3rdparty/freetype/src/pcf/pcferror.h @@ -1,26 +1,26 @@ -/***************************************************************************/ -/* */ -/* pcferror.h */ -/* */ -/* PCF error codes (specification only). */ -/* */ -/* Copyright 2001, 2012 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to define the PCF error enumeration constants. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * pcferror.h + * + * PCF error codes (specification only). + * + * Copyright 2001, 2012 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /************************************************************************** + * + * This file is used to define the PCF error enumeration constants. + * + */ #ifndef PCFERROR_H_ #define PCFERROR_H_ diff --git a/sdk/lib/3rdparty/freetype/src/pcf/pcfread.c b/sdk/lib/3rdparty/freetype/src/pcf/pcfread.c index 537da0dc79b59..71143ecfb54f3 100644 --- a/sdk/lib/3rdparty/freetype/src/pcf/pcfread.c +++ b/sdk/lib/3rdparty/freetype/src/pcf/pcfread.c @@ -37,14 +37,14 @@ THE SOFTWARE. #include "pcferror.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_pcfread +#define FT_COMPONENT pcfread #ifdef FT_DEBUG_LEVEL_TRACE @@ -178,23 +178,23 @@ THE SOFTWARE. } /* - * We now check whether the `size' and `offset' values are reasonable: - * `offset' + `size' must not exceed the stream size. + * We now check whether the `size' and `offset' values are reasonable: + * `offset' + `size' must not exceed the stream size. * - * Note, however, that X11's `pcfWriteFont' routine (used by the - * `bdftopcf' program to create PDF font files) has two special - * features. + * Note, however, that X11's `pcfWriteFont' routine (used by the + * `bdftopcf' program to create PCF font files) has two special + * features. * - * - It always assigns the accelerator table a size of 100 bytes in the - * TOC, regardless of its real size, which can vary between 34 and 72 - * bytes. + * - It always assigns the accelerator table a size of 100 bytes in the + * TOC, regardless of its real size, which can vary between 34 and 72 + * bytes. * - * - Due to the way the routine is designed, it ships out the last font - * table with its real size, ignoring the TOC's size value. Since - * the TOC size values are always rounded up to a multiple of 4, the - * difference can be up to three bytes for all tables except the - * accelerator table, for which the difference can be as large as 66 - * bytes. + * - Due to the way the routine is designed, it ships out the last font + * table with its real size, ignoring the TOC's size value. Since + * the TOC size values are always rounded up to a multiple of 4, the + * difference can be up to three bytes for all tables except the + * accelerator table, for which the difference can be as large as 66 + * bytes. * */ @@ -810,8 +810,8 @@ THE SOFTWARE. { FT_Error error; FT_Memory memory = FT_FACE( face )->memory; - FT_Long* offsets = NULL; - FT_Long bitmapSizes[GLYPHPADOPTIONS]; + FT_ULong* offsets = NULL; + FT_ULong bitmapSizes[GLYPHPADOPTIONS]; FT_ULong format, size; FT_ULong nbitmaps, orig_nbitmaps, i, sizebitmaps = 0; @@ -878,11 +878,11 @@ THE SOFTWARE. for ( i = 0; i < nbitmaps; i++ ) { if ( PCF_BYTE_ORDER( format ) == MSBFirst ) - (void)FT_READ_LONG( offsets[i] ); + (void)FT_READ_ULONG( offsets[i] ); else - (void)FT_READ_LONG_LE( offsets[i] ); + (void)FT_READ_ULONG_LE( offsets[i] ); - FT_TRACE5(( " bitmap %ld: offset %ld (0x%lX)\n", + FT_TRACE5(( " bitmap %lu: offset %lu (0x%lX)\n", i, offsets[i], offsets[i] )); } if ( error ) @@ -891,22 +891,22 @@ THE SOFTWARE. for ( i = 0; i < GLYPHPADOPTIONS; i++ ) { if ( PCF_BYTE_ORDER( format ) == MSBFirst ) - (void)FT_READ_LONG( bitmapSizes[i] ); + (void)FT_READ_ULONG( bitmapSizes[i] ); else - (void)FT_READ_LONG_LE( bitmapSizes[i] ); + (void)FT_READ_ULONG_LE( bitmapSizes[i] ); if ( error ) goto Bail; - sizebitmaps = (FT_ULong)bitmapSizes[PCF_GLYPH_PAD_INDEX( format )]; + sizebitmaps = bitmapSizes[PCF_GLYPH_PAD_INDEX( format )]; - FT_TRACE4(( " %ld-bit padding implies a size of %ld\n", + FT_TRACE4(( " %ld-bit padding implies a size of %lu\n", 8 << i, bitmapSizes[i] )); } - FT_TRACE4(( " %ld bitmaps, using %ld-bit padding\n", + FT_TRACE4(( " %lu bitmaps, using %ld-bit padding\n", nbitmaps, 8 << PCF_GLYPH_PAD_INDEX( format ) )); - FT_TRACE4(( " bitmap size: %ld\n", sizebitmaps )); + FT_TRACE4(( " bitmap size: %lu\n", sizebitmaps )); FT_UNUSED( sizebitmaps ); /* only used for debugging */ @@ -915,14 +915,13 @@ THE SOFTWARE. for ( i = 0; i < nbitmaps; i++ ) { /* rough estimate */ - if ( ( offsets[i] < 0 ) || - ( (FT_ULong)offsets[i] > size ) ) + if ( offsets[i] > size ) { FT_TRACE0(( "pcf_get_bitmaps:" - " invalid offset to bitmap data of glyph %ld\n", i )); + " invalid offset to bitmap data of glyph %lu\n", i )); } else - face->metrics[i].bits = stream->pos + (FT_ULong)offsets[i]; + face->metrics[i].bits = stream->pos + offsets[i]; } face->bitmapsFormat = format; @@ -933,20 +932,58 @@ THE SOFTWARE. } + /* + * This file uses X11 terminology for PCF data; an `encoding' in X11 speak + * is the same as a character code in FreeType speak. + */ +#define PCF_ENC_SIZE 10 + + static + const FT_Frame_Field pcf_enc_header[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE PCF_EncRec + + FT_FRAME_START( PCF_ENC_SIZE ), + FT_FRAME_USHORT_LE( firstCol ), + FT_FRAME_USHORT_LE( lastCol ), + FT_FRAME_USHORT_LE( firstRow ), + FT_FRAME_USHORT_LE( lastRow ), + FT_FRAME_USHORT_LE( defaultChar ), + FT_FRAME_END + }; + + + static + const FT_Frame_Field pcf_enc_msb_header[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE PCF_EncRec + + FT_FRAME_START( PCF_ENC_SIZE ), + FT_FRAME_USHORT( firstCol ), + FT_FRAME_USHORT( lastCol ), + FT_FRAME_USHORT( firstRow ), + FT_FRAME_USHORT( lastRow ), + FT_FRAME_USHORT( defaultChar ), + FT_FRAME_END + }; + + static FT_Error pcf_get_encodings( FT_Stream stream, PCF_Face face ) { - FT_Error error; - FT_Memory memory = FT_FACE( face )->memory; - FT_ULong format, size; - int firstCol, lastCol; - int firstRow, lastRow; - FT_ULong nencoding; - FT_UShort encodingOffset; - int i, j; - FT_ULong k; - PCF_Encoding encoding = NULL; + FT_Error error; + FT_Memory memory = FT_FACE( face )->memory; + FT_ULong format, size; + PCF_Enc enc = &face->enc; + FT_ULong nencoding; + FT_UShort* offset; + FT_UShort defaultCharRow, defaultCharCol; + FT_UShort encodingOffset, defaultCharEncodingOffset; + FT_UShort i, j; + FT_Byte* pos; error = pcf_seek_to_table_type( stream, @@ -956,75 +993,118 @@ THE SOFTWARE. &format, &size ); if ( error ) - return error; + goto Bail; - error = FT_Stream_EnterFrame( stream, 14 ); - if ( error ) - return error; + if ( FT_READ_ULONG_LE( format ) ) + goto Bail; - format = FT_GET_ULONG_LE(); + FT_TRACE4(( "pcf_get_encodings:\n" + " format: 0x%lX (%s)\n", + format, + PCF_BYTE_ORDER( format ) == MSBFirst ? "MSB" : "LSB" )); + + if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) && + !PCF_FORMAT_MATCH( format, PCF_BDF_ENCODINGS ) ) + return FT_THROW( Invalid_File_Format ); if ( PCF_BYTE_ORDER( format ) == MSBFirst ) { - firstCol = FT_GET_SHORT(); - lastCol = FT_GET_SHORT(); - firstRow = FT_GET_SHORT(); - lastRow = FT_GET_SHORT(); - face->defaultChar = FT_GET_SHORT(); + if ( FT_STREAM_READ_FIELDS( pcf_enc_msb_header, enc ) ) + goto Bail; } else { - firstCol = FT_GET_SHORT_LE(); - lastCol = FT_GET_SHORT_LE(); - firstRow = FT_GET_SHORT_LE(); - lastRow = FT_GET_SHORT_LE(); - face->defaultChar = FT_GET_SHORT_LE(); + if ( FT_STREAM_READ_FIELDS( pcf_enc_header, enc ) ) + goto Bail; } - FT_Stream_ExitFrame( stream ); - - FT_TRACE4(( "pcf_get_encodings:\n" - " format: 0x%lX (%s)\n", - format, - PCF_BYTE_ORDER( format ) == MSBFirst ? "MSB" : "LSB" )); - - if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) - return FT_THROW( Invalid_File_Format ); - FT_TRACE4(( " firstCol 0x%X, lastCol 0x%X\n" - " firstRow 0x%X, lastRow 0x%X\n", - firstCol, lastCol, - firstRow, lastRow )); + " firstRow 0x%X, lastRow 0x%X\n" + " defaultChar 0x%X\n", + enc->firstCol, enc->lastCol, + enc->firstRow, enc->lastRow, + enc->defaultChar )); /* sanity checks; we limit numbers of rows and columns to 256 */ - if ( firstCol < 0 || - firstCol > lastCol || - lastCol > 0xFF || - firstRow < 0 || - firstRow > lastRow || - lastRow > 0xFF ) + if ( enc->firstCol > enc->lastCol || + enc->lastCol > 0xFF || + enc->firstRow > enc->lastRow || + enc->lastRow > 0xFF ) return FT_THROW( Invalid_Table ); - nencoding = (FT_ULong)( lastCol - firstCol + 1 ) * - (FT_ULong)( lastRow - firstRow + 1 ); + nencoding = (FT_ULong)( enc->lastCol - enc->firstCol + 1 ) * + (FT_ULong)( enc->lastRow - enc->firstRow + 1 ); - if ( FT_NEW_ARRAY( encoding, nencoding ) ) - return error; + if ( FT_NEW_ARRAY( enc->offset, nencoding ) ) + goto Bail; error = FT_Stream_EnterFrame( stream, 2 * nencoding ); if ( error ) - goto Bail; + goto Exit; FT_TRACE5(( "\n" )); - k = 0; - for ( i = firstRow; i <= lastRow; i++ ) + defaultCharRow = enc->defaultChar >> 8; + defaultCharCol = enc->defaultChar & 0xFF; + + /* validate default character */ + if ( defaultCharRow < enc->firstRow || + defaultCharRow > enc->lastRow || + defaultCharCol < enc->firstCol || + defaultCharCol > enc->lastCol ) + { + enc->defaultChar = enc->firstRow * 256U + enc->firstCol; + FT_TRACE0(( "pcf_get_encodings:" + " Invalid default character set to %u\n", + enc->defaultChar )); + + defaultCharRow = enc->firstRow; + defaultCharCol = enc->firstCol; + } + + /* FreeType mandates that glyph index 0 is the `undefined glyph', */ + /* which PCF calls the `default character'. For this reason, we */ + /* swap the positions of glyph index 0 and the index corresponding */ + /* to `defaultChar' in case they are different. */ + + /* `stream->cursor' still points at the beginning of the frame; */ + /* we can thus easily get the offset to the default character */ + pos = stream->cursor + + 2 * ( ( defaultCharRow - enc->firstRow ) * + ( enc->lastCol - enc->firstCol + 1 ) + + defaultCharCol - enc->firstCol ); + + if ( PCF_BYTE_ORDER( format ) == MSBFirst ) + defaultCharEncodingOffset = FT_PEEK_USHORT( pos ); + else + defaultCharEncodingOffset = FT_PEEK_USHORT_LE( pos ); + + if ( defaultCharEncodingOffset >= face->nmetrics ) + { + FT_TRACE0(( "pcf_get_encodings:" + " Invalid glyph index for default character," + " setting to zero\n" )); + defaultCharEncodingOffset = 0; + } + + if ( defaultCharEncodingOffset ) + { + /* do the swapping */ + PCF_MetricRec tmp = face->metrics[defaultCharEncodingOffset]; + + + face->metrics[defaultCharEncodingOffset] = face->metrics[0]; + face->metrics[0] = tmp; + } + + offset = enc->offset; + for ( i = enc->firstRow; i <= enc->lastRow; i++ ) { - for ( j = firstCol; j <= lastCol; j++ ) + for ( j = enc->firstCol; j <= enc->lastCol; j++ ) { /* X11's reference implementation uses the equivalent to */ /* `FT_GET_SHORT', however PCF fonts with more than 32768 */ - /* characters (e.g. `unifont.pcf') clearly show that an */ + /* characters (e.g., `unifont.pcf') clearly show that an */ /* unsigned value is needed. */ if ( PCF_BYTE_ORDER( format ) == MSBFirst ) encodingOffset = FT_GET_USHORT(); @@ -1033,28 +1113,23 @@ THE SOFTWARE. if ( encodingOffset != 0xFFFFU ) { - encoding[k].enc = i * 256 + j; - encoding[k].glyph = encodingOffset; - - FT_TRACE5(( " code %d (0x%04X): idx %d\n", - encoding[k].enc, encoding[k].enc, encoding[k].glyph )); - - k++; + if ( encodingOffset == defaultCharEncodingOffset ) + encodingOffset = 0; + else if ( encodingOffset == 0 ) + encodingOffset = defaultCharEncodingOffset; } + + *offset++ = encodingOffset; } } FT_Stream_ExitFrame( stream ); - if ( FT_RENEW_ARRAY( encoding, nencoding, k ) ) - goto Bail; - - face->nencodings = k; - face->encodings = encoding; - return error; + Exit: + FT_FREE( enc->offset ); + Bail: - FT_FREE( encoding ); return error; } @@ -1397,8 +1472,7 @@ THE SOFTWARE. root->face_flags |= FT_FACE_FLAG_FIXED_SIZES | - FT_FACE_FLAG_HORIZONTAL | - FT_FACE_FLAG_FAST_GLYPHS; + FT_FACE_FLAG_HORIZONTAL; if ( face->accel.constantWidth ) root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; @@ -1482,14 +1556,7 @@ THE SOFTWARE. else root->family_name = NULL; - /* - * Note: We shift all glyph indices by +1 since we must - * respect the convention that glyph 0 always corresponds - * to the `missing glyph'. - * - * This implies bumping the number of `available' glyphs by 1. - */ - root->num_glyphs = (FT_Long)( face->nmetrics + 1 ); + root->num_glyphs = (FT_Long)face->nmetrics; root->num_fixed_sizes = 1; if ( FT_NEW_ARRAY( root->available_sizes, 1 ) ) diff --git a/sdk/lib/3rdparty/freetype/src/pcf/pcfutil.c b/sdk/lib/3rdparty/freetype/src/pcf/pcfutil.c index 0451ee8deff65..045c42d60f3b3 100644 --- a/sdk/lib/3rdparty/freetype/src/pcf/pcfutil.c +++ b/sdk/lib/3rdparty/freetype/src/pcf/pcfutil.c @@ -37,7 +37,7 @@ in this Software without prior written authorization from The Open Group. /* - * Invert bit order within each BYTE of an array. + * Invert bit order within each BYTE of an array. */ FT_LOCAL_DEF( void ) @@ -59,7 +59,7 @@ in this Software without prior written authorization from The Open Group. /* - * Invert byte order within each 16-bits of an array. + * Invert byte order within each 16-bits of an array. */ FT_LOCAL_DEF( void ) @@ -78,7 +78,7 @@ in this Software without prior written authorization from The Open Group. } /* - * Invert byte order within each 32-bits of an array. + * Invert byte order within each 32-bits of an array. */ FT_LOCAL_DEF( void ) diff --git a/sdk/lib/3rdparty/freetype/src/pfr/pfr.c b/sdk/lib/3rdparty/freetype/src/pfr/pfr.c index 1760882fcdb5f..6d885ea47f624 100644 --- a/sdk/lib/3rdparty/freetype/src/pfr/pfr.c +++ b/sdk/lib/3rdparty/freetype/src/pfr/pfr.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* pfr.c */ -/* */ -/* FreeType PFR driver component. */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * pfr.c + * + * FreeType PFR driver component. + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #define FT_MAKE_OPTION_SINGLE_OBJECT diff --git a/sdk/lib/3rdparty/freetype/src/pfr/pfrcmap.c b/sdk/lib/3rdparty/freetype/src/pfr/pfrcmap.c index 60643780a165e..bfa1b9ea05a03 100644 --- a/sdk/lib/3rdparty/freetype/src/pfr/pfrcmap.c +++ b/sdk/lib/3rdparty/freetype/src/pfr/pfrcmap.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* pfrcmap.c */ -/* */ -/* FreeType PFR cmap handling (body). */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * pfrcmap.c + * + * FreeType PFR cmap handling (body). + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> diff --git a/sdk/lib/3rdparty/freetype/src/pfr/pfrcmap.h b/sdk/lib/3rdparty/freetype/src/pfr/pfrcmap.h index c70a0c83c5001..1e203a0514d45 100644 --- a/sdk/lib/3rdparty/freetype/src/pfr/pfrcmap.h +++ b/sdk/lib/3rdparty/freetype/src/pfr/pfrcmap.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* pfrcmap.h */ -/* */ -/* FreeType PFR cmap handling (specification). */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * pfrcmap.h + * + * FreeType PFR cmap handling (specification). + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef PFRCMAP_H_ diff --git a/sdk/lib/3rdparty/freetype/src/pfr/pfrdrivr.c b/sdk/lib/3rdparty/freetype/src/pfr/pfrdrivr.c index 6c7e50128a207..f67eebf11892c 100644 --- a/sdk/lib/3rdparty/freetype/src/pfr/pfrdrivr.c +++ b/sdk/lib/3rdparty/freetype/src/pfr/pfrdrivr.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* pfrdrivr.c */ -/* */ -/* FreeType PFR driver interface (body). */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * pfrdrivr.c + * + * FreeType PFR driver interface (body). + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -57,10 +57,10 @@ } - /* - * PFR METRICS SERVICE - * - */ + /* + * PFR METRICS SERVICE + * + */ FT_CALLBACK_DEF( FT_Error ) pfr_get_advance( FT_Face pfrface, /* PFR_Face */ @@ -145,10 +145,10 @@ }; - /* - * SERVICE LIST - * - */ + /* + * SERVICE LIST + * + */ static const FT_ServiceDescRec pfr_services[] = { diff --git a/sdk/lib/3rdparty/freetype/src/pfr/pfrdrivr.h b/sdk/lib/3rdparty/freetype/src/pfr/pfrdrivr.h index cab852789b9b9..33b7b9413f2b5 100644 --- a/sdk/lib/3rdparty/freetype/src/pfr/pfrdrivr.h +++ b/sdk/lib/3rdparty/freetype/src/pfr/pfrdrivr.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* pfrdrivr.h */ -/* */ -/* High-level Type PFR driver interface (specification). */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * pfrdrivr.h + * + * High-level Type PFR driver interface (specification). + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef PFRDRIVR_H_ @@ -26,14 +26,8 @@ FT_BEGIN_HEADER -#ifdef FT_CONFIG_OPTION_PIC -#error "this module does not support PIC yet" -#endif - - FT_EXPORT_VAR( const FT_Driver_ClassRec ) pfr_driver_class; - FT_END_HEADER diff --git a/sdk/lib/3rdparty/freetype/src/pfr/pfrerror.h b/sdk/lib/3rdparty/freetype/src/pfr/pfrerror.h index 7027c818e89c2..4829cfc000090 100644 --- a/sdk/lib/3rdparty/freetype/src/pfr/pfrerror.h +++ b/sdk/lib/3rdparty/freetype/src/pfr/pfrerror.h @@ -1,26 +1,26 @@ -/***************************************************************************/ -/* */ -/* pfrerror.h */ -/* */ -/* PFR error codes (specification only). */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to define the PFR error enumeration constants. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * pfrerror.h + * + * PFR error codes (specification only). + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /************************************************************************** + * + * This file is used to define the PFR error enumeration constants. + * + */ #ifndef PFRERROR_H_ #define PFRERROR_H_ diff --git a/sdk/lib/3rdparty/freetype/src/pfr/pfrgload.c b/sdk/lib/3rdparty/freetype/src/pfr/pfrgload.c index b7990196b6e89..6ef5856a8dc15 100644 --- a/sdk/lib/3rdparty/freetype/src/pfr/pfrgload.c +++ b/sdk/lib/3rdparty/freetype/src/pfr/pfrgload.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* pfrgload.c */ -/* */ -/* FreeType PFR glyph loader (body). */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * pfrgload.c + * + * FreeType PFR glyph loader (body). + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include "pfrgload.h" @@ -24,7 +24,7 @@ #include "pfrerror.h" #undef FT_COMPONENT -#define FT_COMPONENT trace_pfr +#define FT_COMPONENT pfr /*************************************************************************/ @@ -359,9 +359,9 @@ FT_UInt format, format_low, args_format = 0, args_count, n; - /***************************************************************/ - /* read instruction */ - /* */ + /**************************************************************** + * read instruction + */ PFR_CHECK( 1 ); format = PFR_NEXT_BYTE( p ); format_low = format & 15; @@ -426,9 +426,9 @@ args_format = format_low; } - /***********************************************************/ - /* now read arguments */ - /* */ + /************************************************************ + * now read arguments + */ cur = pos; for ( n = 0; n < args_count; n++ ) { @@ -513,9 +513,9 @@ FT_TRACE7(( "\n" )); - /***********************************************************/ - /* finally, execute instruction */ - /* */ + /************************************************************ + * finally, execute instruction + */ switch ( format >> 4 ) { case 0: /* end glyph => EXIT */ diff --git a/sdk/lib/3rdparty/freetype/src/pfr/pfrgload.h b/sdk/lib/3rdparty/freetype/src/pfr/pfrgload.h index 01f48d7706aee..d0e1420b671b4 100644 --- a/sdk/lib/3rdparty/freetype/src/pfr/pfrgload.h +++ b/sdk/lib/3rdparty/freetype/src/pfr/pfrgload.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* pfrgload.h */ -/* */ -/* FreeType PFR glyph loader (specification). */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * pfrgload.h + * + * FreeType PFR glyph loader (specification). + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef PFRGLOAD_H_ diff --git a/sdk/lib/3rdparty/freetype/src/pfr/pfrload.c b/sdk/lib/3rdparty/freetype/src/pfr/pfrload.c index 2776da462a862..ccf0b7e1f89aa 100644 --- a/sdk/lib/3rdparty/freetype/src/pfr/pfrload.c +++ b/sdk/lib/3rdparty/freetype/src/pfr/pfrload.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* pfrload.c */ -/* */ -/* FreeType PFR loader (body). */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * pfrload.c + * + * FreeType PFR loader (body). + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include "pfrload.h" @@ -23,92 +23,92 @@ #include "pfrerror.h" #undef FT_COMPONENT -#define FT_COMPONENT trace_pfr +#define FT_COMPONENT pfr /* - * The overall structure of a PFR file is as follows. + * The overall structure of a PFR file is as follows. * - * PFR header - * 58 bytes (contains nPhysFonts) + * PFR header + * 58 bytes (contains nPhysFonts) * - * Logical font directory (size at most 2^16 bytes) - * 2 bytes (nLogFonts) - * + nLogFonts * 5 bytes + * Logical font directory (size at most 2^16 bytes) + * 2 bytes (nLogFonts) + * + nLogFonts * 5 bytes * - * ==> nLogFonts <= 13106 + * ==> nLogFonts <= 13106 * - * Logical font section (size at most 2^24 bytes) - * nLogFonts * logFontRecord + * Logical font section (size at most 2^24 bytes) + * nLogFonts * logFontRecord * - * logFontRecord (size at most 2^16 bytes) - * 12 bytes (fontMatrix) - * + 1 byte (flags) - * + 0-5 bytes (depending on `flags') - * + 0-(1+255*(2+255)) = 0-65536 (depending on `flags') - * + 5 bytes (physical font info) - * + 0-1 bytes (depending on PFR header) + * logFontRecord (size at most 2^16 bytes) + * 12 bytes (fontMatrix) + * + 1 byte (flags) + * + 0-5 bytes (depending on `flags') + * + 0-(1+255*(2+255)) = 0-65536 (depending on `flags') + * + 5 bytes (physical font info) + * + 0-1 bytes (depending on PFR header) * - * ==> minimum size 18 bytes + * ==> minimum size 18 bytes * - * Physical font section (size at most 2^24 bytes) - * nPhysFonts * (physFontRecord - * + nBitmapSizes * nBmapChars * bmapCharRecord) + * Physical font section (size at most 2^24 bytes) + * nPhysFonts * (physFontRecord + * + nBitmapSizes * nBmapChars * bmapCharRecord) * - * physFontRecord (size at most 2^24 bytes) - * 14 bytes (font info) - * + 1 byte (flags) - * + 0-2 (depending on `flags') - * + 0-? (structure too complicated to be shown here; depending on - * `flags'; contains `nBitmapSizes' and `nBmapChars') - * + 3 bytes (nAuxBytes) - * + nAuxBytes - * + 1 byte (nBlueValues) - * + 2 * nBlueValues - * + 6 bytes (hinting data) - * + 2 bytes (nCharacters) - * + nCharacters * (4-10 bytes) (depending on `flags') + * physFontRecord (size at most 2^24 bytes) + * 14 bytes (font info) + * + 1 byte (flags) + * + 0-2 (depending on `flags') + * + 0-? (structure too complicated to be shown here; depending on + * `flags'; contains `nBitmapSizes' and `nBmapChars') + * + 3 bytes (nAuxBytes) + * + nAuxBytes + * + 1 byte (nBlueValues) + * + 2 * nBlueValues + * + 6 bytes (hinting data) + * + 2 bytes (nCharacters) + * + nCharacters * (4-10 bytes) (depending on `flags') * - * ==> minimum size 27 bytes + * ==> minimum size 27 bytes * - * bmapCharRecord - * 4-7 bytes + * bmapCharRecord + * 4-7 bytes * - * Glyph program strings (three possible types: simpleGps, compoundGps, - * and bitmapGps; size at most 2^24 bytes) - * simpleGps (size at most 2^16 bytes) - * 1 byte (flags) - * 1-2 bytes (n[XY]orus, depending on `flags') - * 0-(64+512*2) = 0-1088 bytes (depending on `n[XY]orus') - * 0-? (structure too complicated to be shown here; depending on - * `flags') - * 1-? glyph data (faintly resembling PS Type 1 charstrings) + * Glyph program strings (three possible types: simpleGps, compoundGps, + * and bitmapGps; size at most 2^24 bytes) + * simpleGps (size at most 2^16 bytes) + * 1 byte (flags) + * 1-2 bytes (n[XY]orus, depending on `flags') + * 0-(64+512*2) = 0-1088 bytes (depending on `n[XY]orus') + * 0-? (structure too complicated to be shown here; depending on + * `flags') + * 1-? glyph data (faintly resembling PS Type 1 charstrings) * - * ==> minimum size 3 bytes + * ==> minimum size 3 bytes * - * compoundGps (size at most 2^16 bytes) - * 1 byte (nElements <= 63, flags) - * + 0-(1+255*(2+255)) = 0-65536 (depending on `flags') - * + nElements * (6-14 bytes) + * compoundGps (size at most 2^16 bytes) + * 1 byte (nElements <= 63, flags) + * + 0-(1+255*(2+255)) = 0-65536 (depending on `flags') + * + nElements * (6-14 bytes) * - * bitmapGps (size at most 2^16 bytes) - * 1 byte (flags) - * 3-13 bytes (position info, depending on `flags') - * 0-? bitmap data + * bitmapGps (size at most 2^16 bytes) + * 1 byte (flags) + * 3-13 bytes (position info, depending on `flags') + * 0-? bitmap data * - * ==> minimum size 4 bytes + * ==> minimum size 4 bytes * - * PFR trailer - * 8 bytes + * PFR trailer + * 8 bytes * * - * ==> minimum size of a valid PFR: - * 58 (header) - * + 2 (nLogFonts) - * + 27 (1 physFontRecord) - * + 8 (trailer) - * ----- - * 95 bytes + * ==> minimum size of a valid PFR: + * 58 (header) + * + 2 (nLogFonts) + * + 27 (1 physFontRecord) + * + 8 (trailer) + * ----- + * 95 bytes * */ diff --git a/sdk/lib/3rdparty/freetype/src/pfr/pfrload.h b/sdk/lib/3rdparty/freetype/src/pfr/pfrload.h index 36e809a762c33..2e7ffd0127060 100644 --- a/sdk/lib/3rdparty/freetype/src/pfr/pfrload.h +++ b/sdk/lib/3rdparty/freetype/src/pfr/pfrload.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* pfrload.h */ -/* */ -/* FreeType PFR loader (specification). */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * pfrload.h + * + * FreeType PFR loader (specification). + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef PFRLOAD_H_ diff --git a/sdk/lib/3rdparty/freetype/src/pfr/pfrobjs.c b/sdk/lib/3rdparty/freetype/src/pfr/pfrobjs.c index 737b97b5ff291..e103a3f6f28a5 100644 --- a/sdk/lib/3rdparty/freetype/src/pfr/pfrobjs.c +++ b/sdk/lib/3rdparty/freetype/src/pfr/pfrobjs.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* pfrobjs.c */ -/* */ -/* FreeType PFR object methods (body). */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * pfrobjs.c + * + * FreeType PFR object methods (body). + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include "pfrobjs.h" @@ -29,7 +29,7 @@ #include "pfrerror.h" #undef FT_COMPONENT -#define FT_COMPONENT trace_pfr +#define FT_COMPONENT pfr /*************************************************************************/ @@ -122,7 +122,7 @@ stream, (FT_UInt)( face_index & 0xFFFF ), face->header.log_dir_offset, - FT_BOOL( face->header.phy_font_max_size_high != 0 ) ); + FT_BOOL( face->header.phy_font_max_size_high ) ); if ( error ) goto Exit; @@ -370,7 +370,7 @@ FT_Bool scaling; - scaling = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ); + scaling = FT_BOOL( !( load_flags & FT_LOAD_NO_SCALE ) ); /* copy outline data */ *outline = slot->glyph.loader->base.outline; diff --git a/sdk/lib/3rdparty/freetype/src/pfr/pfrobjs.h b/sdk/lib/3rdparty/freetype/src/pfr/pfrobjs.h index 59c709f58d00e..39cffd07c5ce6 100644 --- a/sdk/lib/3rdparty/freetype/src/pfr/pfrobjs.h +++ b/sdk/lib/3rdparty/freetype/src/pfr/pfrobjs.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* pfrobjs.h */ -/* */ -/* FreeType PFR object methods (specification). */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * pfrobjs.h + * + * FreeType PFR object methods (specification). + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef PFROBJS_H_ diff --git a/sdk/lib/3rdparty/freetype/src/pfr/pfrsbit.c b/sdk/lib/3rdparty/freetype/src/pfr/pfrsbit.c index ba909ddca7555..00a9616455dbc 100644 --- a/sdk/lib/3rdparty/freetype/src/pfr/pfrsbit.c +++ b/sdk/lib/3rdparty/freetype/src/pfr/pfrsbit.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* pfrsbit.c */ -/* */ -/* FreeType PFR bitmap loader (body). */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * pfrsbit.c + * + * FreeType PFR bitmap loader (body). + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include "pfrsbit.h" @@ -24,7 +24,7 @@ #include "pfrerror.h" #undef FT_COMPONENT -#define FT_COMPONENT trace_pfr +#define FT_COMPONENT pfr /*************************************************************************/ diff --git a/sdk/lib/3rdparty/freetype/src/pfr/pfrsbit.h b/sdk/lib/3rdparty/freetype/src/pfr/pfrsbit.h index 07b27bc06cc9d..6568b90943fbc 100644 --- a/sdk/lib/3rdparty/freetype/src/pfr/pfrsbit.h +++ b/sdk/lib/3rdparty/freetype/src/pfr/pfrsbit.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* pfrsbit.h */ -/* */ -/* FreeType PFR bitmap loader (specification). */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * pfrsbit.h + * + * FreeType PFR bitmap loader (specification). + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef PFRSBIT_H_ diff --git a/sdk/lib/3rdparty/freetype/src/pfr/pfrtypes.h b/sdk/lib/3rdparty/freetype/src/pfr/pfrtypes.h index 058d6aadc9a5c..6a5f9d571b47e 100644 --- a/sdk/lib/3rdparty/freetype/src/pfr/pfrtypes.h +++ b/sdk/lib/3rdparty/freetype/src/pfr/pfrtypes.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* pfrtypes.h */ -/* */ -/* FreeType PFR data structures (specification only). */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * pfrtypes.h + * + * FreeType PFR data structures (specification only). + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef PFRTYPES_H_ diff --git a/sdk/lib/3rdparty/freetype/src/psaux/afmparse.c b/sdk/lib/3rdparty/freetype/src/psaux/afmparse.c index 0c33d5949bc77..49225a9f78e1d 100644 --- a/sdk/lib/3rdparty/freetype/src/psaux/afmparse.c +++ b/sdk/lib/3rdparty/freetype/src/psaux/afmparse.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* afmparse.c */ -/* */ -/* AFM parser (body). */ -/* */ -/* Copyright 2006-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * afmparse.c + * + * AFM parser (body). + * + * Copyright (C) 2006-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> #include FT_FREETYPE_H @@ -28,13 +28,13 @@ #include "psauxerr.h" -/***************************************************************************/ -/* */ -/* AFM_Stream */ -/* */ -/* The use of AFM_Stream is largely inspired by parseAFM.[ch] from t1lib. */ -/* */ -/* */ + /************************************************************************** + * + * AFM_Stream + * + * The use of AFM_Stream is largely inspired by parseAFM.[ch] from t1lib. + * + */ enum { @@ -193,11 +193,11 @@ } - /*************************************************************************/ - /* */ - /* AFM_Parser */ - /* */ - /* */ + /************************************************************************** + * + * AFM_Parser + * + */ /* all keys defined in Ch. 7-10 of 5004.AFM_Spec.pdf */ typedef enum AFM_Token_ diff --git a/sdk/lib/3rdparty/freetype/src/psaux/afmparse.h b/sdk/lib/3rdparty/freetype/src/psaux/afmparse.h index 86f852a2477de..2ceb77553b27e 100644 --- a/sdk/lib/3rdparty/freetype/src/psaux/afmparse.h +++ b/sdk/lib/3rdparty/freetype/src/psaux/afmparse.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* afmparse.h */ -/* */ -/* AFM parser (specification). */ -/* */ -/* Copyright 2006-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * afmparse.h + * + * AFM parser (specification). + * + * Copyright (C) 2006-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef AFMPARSE_H_ diff --git a/sdk/lib/3rdparty/freetype/src/psaux/cffdecode.c b/sdk/lib/3rdparty/freetype/src/psaux/cffdecode.c index 80d622c0e1bbb..17cccf818b498 100644 --- a/sdk/lib/3rdparty/freetype/src/psaux/cffdecode.c +++ b/sdk/lib/3rdparty/freetype/src/psaux/cffdecode.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* cffdecode.c */ -/* */ -/* PostScript CFF (Type 2) decoding routines (body). */ -/* */ -/* Copyright 2017-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * cffdecode.c + * + * PostScript CFF (Type 2) decoding routines (body). + * + * Copyright (C) 2017-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -28,14 +28,14 @@ #include "psauxerr.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_cffdecode +#define FT_COMPONENT cffdecode #ifdef CFF_CONFIG_OPTION_OLD_ENGINE @@ -235,8 +235,8 @@ return FT_THROW( Syntax_Error ); } - adx += decoder->builder.left_bearing.x; - ady += decoder->builder.left_bearing.y; + adx = ADD_LONG( adx, decoder->builder.left_bearing.x ); + ady = ADD_LONG( ady, decoder->builder.left_bearing.y ); #ifdef FT_CONFIG_OPTION_INCREMENTAL /* Incremental fonts don't necessarily have valid charsets. */ @@ -378,23 +378,26 @@ /*************************************************************************/ /*************************************************************************/ - /*************************************************************************/ - /* */ - /* <Function> */ - /* cff_compute_bias */ - /* */ - /* <Description> */ - /* Computes the bias value in dependence of the number of glyph */ - /* subroutines. */ - /* */ - /* <Input> */ - /* in_charstring_type :: The `CharstringType' value of the top DICT */ - /* dictionary. */ - /* */ - /* num_subrs :: The number of glyph subroutines. */ - /* */ - /* <Return> */ - /* The bias value. */ + /************************************************************************** + * + * @Function: + * cff_compute_bias + * + * @Description: + * Computes the bias value in dependence of the number of glyph + * subroutines. + * + * @Input: + * in_charstring_type :: + * The `CharstringType' value of the top DICT + * dictionary. + * + * num_subrs :: + * The number of glyph subroutines. + * + * @Return: + * The bias value. + */ static FT_Int cff_compute_bias( FT_Int in_charstring_type, FT_UInt num_subrs ) @@ -464,28 +467,32 @@ #ifdef CFF_CONFIG_OPTION_OLD_ENGINE - /*************************************************************************/ - /* */ - /* <Function> */ - /* cff_decoder_parse_charstrings */ - /* */ - /* <Description> */ - /* Parses a given Type 2 charstrings program. */ - /* */ - /* <InOut> */ - /* decoder :: The current Type 1 decoder. */ - /* */ - /* <Input> */ - /* charstring_base :: The base of the charstring stream. */ - /* */ - /* charstring_len :: The length in bytes of the charstring stream. */ - /* */ - /* in_dict :: Set to 1 if function is called from top or */ - /* private DICT (needed for Multiple Master CFFs). */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * cff_decoder_parse_charstrings + * + * @Description: + * Parses a given Type 2 charstrings program. + * + * @InOut: + * decoder :: + * The current Type 1 decoder. + * + * @Input: + * charstring_base :: + * The base of the charstring stream. + * + * charstring_len :: + * The length in bytes of the charstring stream. + * + * in_dict :: + * Set to 1 if function is called from top or + * private DICT (needed for Multiple Master CFFs). + * + * @Return: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) cff_decoder_parse_charstrings( CFF_Decoder* decoder, FT_Byte* charstring_base, @@ -543,10 +550,10 @@ FT_Byte v; - /********************************************************************/ - /* */ - /* Decode operator or operand */ - /* */ + /********************************************************************* + * + * Decode operator or operand + */ v = *ip++; if ( v >= 32 || v == 28 ) { @@ -853,6 +860,15 @@ case cff_op_flex1: case cff_op_callsubr: case cff_op_callgsubr: + /* deprecated opcodes */ + case cff_op_dotsection: + /* invalid Type 1 opcodes */ + case cff_op_hsbw: + case cff_op_closepath: + case cff_op_callothersubr: + case cff_op_seac: + case cff_op_sbw: + case cff_op_setcurrentpoint: goto MM_Error; default: @@ -948,10 +964,10 @@ case cff_op_hstemhm: case cff_op_vstemhm: /* the number of arguments is always even here */ - FT_TRACE4(( - op == cff_op_hstem ? " hstem\n" : - ( op == cff_op_vstem ? " vstem\n" : - ( op == cff_op_hstemhm ? " hstemhm\n" : " vstemhm\n" ) ) )); + FT_TRACE4(( "%s\n", + op == cff_op_hstem ? " hstem" : + ( op == cff_op_vstem ? " vstem" : + ( op == cff_op_hstemhm ? " hstemhm" : " vstemhm" ) ) )); if ( hinter ) hinter->stems( hinter->hints, @@ -965,7 +981,8 @@ case cff_op_hintmask: case cff_op_cntrmask: - FT_TRACE4(( op == cff_op_hintmask ? " hintmask" : " cntrmask" )); + FT_TRACE4(( "%s", op == cff_op_hintmask ? " hintmask" + : " cntrmask" )); /* implement vstem when needed -- */ /* the specification doesn't say it, but this also works */ @@ -1078,8 +1095,8 @@ FT_Int phase = ( op == cff_op_hlineto ); - FT_TRACE4(( op == cff_op_hlineto ? " hlineto\n" - : " vlineto\n" )); + FT_TRACE4(( "%s\n", op == cff_op_hlineto ? " hlineto" + : " vlineto" )); if ( num_args < 0 ) goto Stack_Underflow; @@ -1250,8 +1267,8 @@ FT_Int nargs; - FT_TRACE4(( op == cff_op_vhcurveto ? " vhcurveto\n" - : " hvcurveto\n" )); + FT_TRACE4(( "%s\n", op == cff_op_vhcurveto ? " vhcurveto" + : " hvcurveto" )); if ( cff_builder_start_point( builder, x, y ) ) goto Fail; @@ -1539,9 +1556,9 @@ } if ( dx < 0 ) - dx = -dx; + dx = NEG_LONG( dx ); if ( dy < 0 ) - dy = -dy; + dy = NEG_LONG( dy ); /* strange test, but here it is... */ horizontal = ( dx > dy ); @@ -1551,7 +1568,7 @@ x = ADD_LONG( x, args[0] ); y = ADD_LONG( y, args[1] ); cff_builder_add_point( builder, x, y, - (FT_Bool)( count == 3 ) ); + FT_BOOL( count == 3 ) ); args += 2; } @@ -1589,7 +1606,7 @@ x = ADD_LONG( x, args[0] ); y = ADD_LONG( y, args[1] ); cff_builder_add_point( builder, x, y, - (FT_Bool)( count == 4 || count == 1 ) ); + FT_BOOL( count == 4 || count == 1 ) ); args += 2; } @@ -1705,16 +1722,20 @@ break; case cff_op_random: - FT_TRACE4(( " random\n" )); + { + FT_UInt32* randval = in_dict ? &decoder->cff->top_font.random + : &decoder->current_subfont->random; - /* only use the lower 16 bits of `random' */ - /* to generate a number in the range (0;1] */ - args[0] = (FT_Fixed) - ( ( decoder->current_subfont->random & 0xFFFF ) + 1 ); - args++; - decoder->current_subfont->random = - cff_random( decoder->current_subfont->random ); + FT_TRACE4(( " random\n" )); + + /* only use the lower 16 bits of `random' */ + /* to generate a number in the range (0;1] */ + args[0] = (FT_Fixed)( ( *randval & 0xFFFF ) + 1 ); + args++; + + *randval = cff_random( *randval ); + } break; case cff_op_mul: @@ -1727,7 +1748,10 @@ case cff_op_sqrt: FT_TRACE4(( " sqrt\n" )); - if ( args[0] > 0 ) + /* without upper limit the loop below might not finish */ + if ( args[0] > 0x7FFFFFFFL ) + args[0] = 46341; + else if ( args[0] > 0 ) { FT_Fixed root = args[0]; FT_Fixed new_root; @@ -1800,6 +1824,7 @@ if ( idx >= 0 ) { + idx = idx % count; while ( idx > 0 ) { FT_Fixed tmp = args[count - 1]; @@ -1814,6 +1839,10 @@ } else { + /* before C99 it is implementation-defined whether */ + /* the result of `%' is negative if the first operand */ + /* is negative */ + idx = -( NEG_INT( idx ) % count ); while ( idx < 0 ) { FT_Fixed tmp = args[0]; @@ -1914,6 +1943,7 @@ case cff_op_blend: /* this operator was removed from the Type2 specification */ /* in version 16-March-2000 */ + if ( num_designs ) { FT_Int num_results = (FT_Int)( args[0] >> 16 ); @@ -1923,7 +1953,8 @@ if ( num_results < 0 ) goto Syntax_Error; - if ( num_results * (FT_Int)num_designs > num_args ) + if ( num_results > num_args || + num_results * (FT_Int)num_designs > num_args ) goto Stack_Underflow; /* since we currently don't handle interpolation of multiple */ @@ -1932,6 +1963,8 @@ args -= num_results * ( num_designs - 1 ); num_args -= num_results * ( num_designs - 1 ); } + else + goto Syntax_Error; break; case cff_op_dotsection: @@ -1998,20 +2031,31 @@ break; case cff_op_callothersubr: - /* this is an invalid Type 2 operator; however, there */ - /* exist fonts which are incorrectly converted from probably */ - /* Type 1 to CFF, and some parsers seem to accept it */ + { + FT_Fixed arg; - FT_TRACE4(( " callothersubr (invalid op)\n" )); - /* subsequent `pop' operands should add the arguments, */ - /* this is the implementation described for `unknown' other */ - /* subroutines in the Type1 spec. */ - /* */ - /* XXX Fix return arguments (see discussion below). */ - args -= 2 + ( args[-2] >> 16 ); - if ( args < stack ) - goto Stack_Underflow; + /* this is an invalid Type 2 operator; however, there */ + /* exist fonts which are incorrectly converted from */ + /* probably Type 1 to CFF, and some parsers seem to accept */ + /* it */ + + FT_TRACE4(( " callothersubr (invalid op)\n" )); + + /* subsequent `pop' operands should add the arguments, */ + /* this is the implementation described for `unknown' */ + /* other subroutines in the Type1 spec. */ + /* */ + /* XXX Fix return arguments (see discussion below). */ + + arg = 2 + ( args[-2] >> 16 ); + if ( arg >= CFF_MAX_OPERANDS ) + goto Stack_Underflow; + + args -= arg; + if ( args < stack ) + goto Stack_Underflow; + } break; case cff_op_pop: @@ -2251,28 +2295,34 @@ #endif /* CFF_CONFIG_OPTION_OLD_ENGINE */ - /*************************************************************************/ - /* */ - /* <Function> */ - /* cff_decoder_init */ - /* */ - /* <Description> */ - /* Initializes a given glyph decoder. */ - /* */ - /* <InOut> */ - /* decoder :: A pointer to the glyph builder to initialize. */ - /* */ - /* <Input> */ - /* face :: The current face object. */ - /* */ - /* size :: The current size object. */ - /* */ - /* slot :: The current glyph object. */ - /* */ - /* hinting :: Whether hinting is active. */ - /* */ - /* hint_mode :: The hinting mode. */ - /* */ + /************************************************************************** + * + * @Function: + * cff_decoder_init + * + * @Description: + * Initializes a given glyph decoder. + * + * @InOut: + * decoder :: + * A pointer to the glyph builder to initialize. + * + * @Input: + * face :: + * The current face object. + * + * size :: + * The current size object. + * + * slot :: + * The current glyph object. + * + * hinting :: + * Whether hinting is active. + * + * hint_mode :: + * The hinting mode. + */ FT_LOCAL_DEF( void ) cff_decoder_init( CFF_Decoder* decoder, TT_Face face, diff --git a/sdk/lib/3rdparty/freetype/src/psaux/cffdecode.h b/sdk/lib/3rdparty/freetype/src/psaux/cffdecode.h index 0d4f5fef631d8..a6691979f0c4d 100644 --- a/sdk/lib/3rdparty/freetype/src/psaux/cffdecode.h +++ b/sdk/lib/3rdparty/freetype/src/psaux/cffdecode.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* cffdecode.h */ -/* */ -/* PostScript CFF (Type 2) decoding routines (specification). */ -/* */ -/* Copyright 2017-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * cffdecode.h + * + * PostScript CFF (Type 2) decoding routines (specification). + * + * Copyright (C) 2017-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef CFFDECODE_H_ diff --git a/sdk/lib/3rdparty/freetype/src/psaux/psarrst.c b/sdk/lib/3rdparty/freetype/src/psaux/psarrst.c index a8780947f9d55..011803b41616b 100644 --- a/sdk/lib/3rdparty/freetype/src/psaux/psarrst.c +++ b/sdk/lib/3rdparty/freetype/src/psaux/psarrst.c @@ -1,39 +1,39 @@ -/***************************************************************************/ -/* */ -/* psarrst.c */ -/* */ -/* Adobe's code for Array Stacks (body). */ -/* */ -/* Copyright 2007-2013 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * psarrst.c + * + * Adobe's code for Array Stacks (body). + * + * Copyright 2007-2013 Adobe Systems Incorporated. + * + * This software, and all works of authorship, whether in source or + * object code form as indicated by the copyright notice(s) included + * herein (collectively, the "Work") is made available, and may only be + * used, modified, and distributed under the FreeType Project License, + * LICENSE.TXT. Additionally, subject to the terms and conditions of the + * FreeType Project License, each contributor to the Work hereby grants + * to any individual or legal entity exercising permissions granted by + * the FreeType Project License and this section (hereafter, "You" or + * "Your") a perpetual, worldwide, non-exclusive, no-charge, + * royalty-free, irrevocable (except as stated in this section) patent + * license to make, have made, use, offer to sell, sell, import, and + * otherwise transfer the Work, where such license applies only to those + * patent claims licensable by such contributor that are necessarily + * infringed by their contribution(s) alone or by combination of their + * contribution(s) with the Work to which such contribution(s) was + * submitted. If You institute patent litigation against any entity + * (including a cross-claim or counterclaim in a lawsuit) alleging that + * the Work or a contribution incorporated within the Work constitutes + * direct or contributory patent infringement, then any patent licenses + * granted to You under this License for that Work shall terminate as of + * the date such litigation is filed. + * + * By using, modifying, or distributing the Work you indicate that you + * have read and understood the terms and conditions of the + * FreeType Project License as well as those provided in this section, + * and you accept them fully. + * + */ #include "psft.h" diff --git a/sdk/lib/3rdparty/freetype/src/psaux/psarrst.h b/sdk/lib/3rdparty/freetype/src/psaux/psarrst.h index b3568eb61fc4c..098617b25754e 100644 --- a/sdk/lib/3rdparty/freetype/src/psaux/psarrst.h +++ b/sdk/lib/3rdparty/freetype/src/psaux/psarrst.h @@ -1,39 +1,39 @@ -/***************************************************************************/ -/* */ -/* psarrst.h */ -/* */ -/* Adobe's code for Array Stacks (specification). */ -/* */ -/* Copyright 2007-2013 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * psarrst.h + * + * Adobe's code for Array Stacks (specification). + * + * Copyright 2007-2013 Adobe Systems Incorporated. + * + * This software, and all works of authorship, whether in source or + * object code form as indicated by the copyright notice(s) included + * herein (collectively, the "Work") is made available, and may only be + * used, modified, and distributed under the FreeType Project License, + * LICENSE.TXT. Additionally, subject to the terms and conditions of the + * FreeType Project License, each contributor to the Work hereby grants + * to any individual or legal entity exercising permissions granted by + * the FreeType Project License and this section (hereafter, "You" or + * "Your") a perpetual, worldwide, non-exclusive, no-charge, + * royalty-free, irrevocable (except as stated in this section) patent + * license to make, have made, use, offer to sell, sell, import, and + * otherwise transfer the Work, where such license applies only to those + * patent claims licensable by such contributor that are necessarily + * infringed by their contribution(s) alone or by combination of their + * contribution(s) with the Work to which such contribution(s) was + * submitted. If You institute patent litigation against any entity + * (including a cross-claim or counterclaim in a lawsuit) alleging that + * the Work or a contribution incorporated within the Work constitutes + * direct or contributory patent infringement, then any patent licenses + * granted to You under this License for that Work shall terminate as of + * the date such litigation is filed. + * + * By using, modifying, or distributing the Work you indicate that you + * have read and understood the terms and conditions of the + * FreeType Project License as well as those provided in this section, + * and you accept them fully. + * + */ #ifndef PSARRST_H_ diff --git a/sdk/lib/3rdparty/freetype/src/psaux/psaux.c b/sdk/lib/3rdparty/freetype/src/psaux/psaux.c index fb447fcdbbc09..1db04625514b5 100644 --- a/sdk/lib/3rdparty/freetype/src/psaux/psaux.c +++ b/sdk/lib/3rdparty/freetype/src/psaux/psaux.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* psaux.c */ -/* */ -/* FreeType auxiliary PostScript driver component (body only). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * psaux.c + * + * FreeType auxiliary PostScript driver component (body only). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #define FT_MAKE_OPTION_SINGLE_OBJECT diff --git a/sdk/lib/3rdparty/freetype/src/psaux/psauxerr.h b/sdk/lib/3rdparty/freetype/src/psaux/psauxerr.h index cc33fd2eeac1c..523e1886c22c5 100644 --- a/sdk/lib/3rdparty/freetype/src/psaux/psauxerr.h +++ b/sdk/lib/3rdparty/freetype/src/psaux/psauxerr.h @@ -1,27 +1,27 @@ -/***************************************************************************/ -/* */ -/* psauxerr.h */ -/* */ -/* PS auxiliary module error codes (specification only). */ -/* */ -/* Copyright 2001-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to define the PS auxiliary module error enumeration */ - /* constants. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * psauxerr.h + * + * PS auxiliary module error codes (specification only). + * + * Copyright (C) 2001-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /************************************************************************** + * + * This file is used to define the PS auxiliary module error enumeration + * constants. + * + */ #ifndef PSAUXERR_H_ #define PSAUXERR_H_ diff --git a/sdk/lib/3rdparty/freetype/src/psaux/psauxmod.c b/sdk/lib/3rdparty/freetype/src/psaux/psauxmod.c index ee497085cc299..5df8e690561f1 100644 --- a/sdk/lib/3rdparty/freetype/src/psaux/psauxmod.c +++ b/sdk/lib/3rdparty/freetype/src/psaux/psauxmod.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* psauxmod.c */ -/* */ -/* FreeType auxiliary PostScript module implementation (body). */ -/* */ -/* Copyright 2000-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * psauxmod.c + * + * FreeType auxiliary PostScript module implementation (body). + * + * Copyright (C) 2000-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> diff --git a/sdk/lib/3rdparty/freetype/src/psaux/psauxmod.h b/sdk/lib/3rdparty/freetype/src/psaux/psauxmod.h index f30978f02202e..a0eda0bfc03d4 100644 --- a/sdk/lib/3rdparty/freetype/src/psaux/psauxmod.h +++ b/sdk/lib/3rdparty/freetype/src/psaux/psauxmod.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* psauxmod.h */ -/* */ -/* FreeType auxiliary PostScript module implementation (specification). */ -/* */ -/* Copyright 2000-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * psauxmod.h + * + * FreeType auxiliary PostScript module implementation (specification). + * + * Copyright (C) 2000-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef PSAUXMOD_H_ @@ -28,10 +28,6 @@ FT_BEGIN_HEADER -#ifdef FT_CONFIG_OPTION_PIC -#error "this module does not support PIC yet" -#endif - FT_CALLBACK_TABLE const CFF_Builder_FuncsRec cff_builder_funcs; diff --git a/sdk/lib/3rdparty/freetype/src/psaux/psblues.c b/sdk/lib/3rdparty/freetype/src/psaux/psblues.c index ae39d03c77768..89738ce474965 100644 --- a/sdk/lib/3rdparty/freetype/src/psaux/psblues.c +++ b/sdk/lib/3rdparty/freetype/src/psaux/psblues.c @@ -1,39 +1,39 @@ -/***************************************************************************/ -/* */ -/* psblues.c */ -/* */ -/* Adobe's code for handling Blue Zones (body). */ -/* */ -/* Copyright 2009-2014 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * psblues.c + * + * Adobe's code for handling Blue Zones (body). + * + * Copyright 2009-2014 Adobe Systems Incorporated. + * + * This software, and all works of authorship, whether in source or + * object code form as indicated by the copyright notice(s) included + * herein (collectively, the "Work") is made available, and may only be + * used, modified, and distributed under the FreeType Project License, + * LICENSE.TXT. Additionally, subject to the terms and conditions of the + * FreeType Project License, each contributor to the Work hereby grants + * to any individual or legal entity exercising permissions granted by + * the FreeType Project License and this section (hereafter, "You" or + * "Your") a perpetual, worldwide, non-exclusive, no-charge, + * royalty-free, irrevocable (except as stated in this section) patent + * license to make, have made, use, offer to sell, sell, import, and + * otherwise transfer the Work, where such license applies only to those + * patent claims licensable by such contributor that are necessarily + * infringed by their contribution(s) alone or by combination of their + * contribution(s) with the Work to which such contribution(s) was + * submitted. If You institute patent litigation against any entity + * (including a cross-claim or counterclaim in a lawsuit) alleging that + * the Work or a contribution incorporated within the Work constitutes + * direct or contributory patent infringement, then any patent licenses + * granted to You under this License for that Work shall terminate as of + * the date such litigation is filed. + * + * By using, modifying, or distributing the Work you indicate that you + * have read and understood the terms and conditions of the + * FreeType Project License as well as those provided in this section, + * and you accept them fully. + * + */ #include "psft.h" @@ -44,14 +44,14 @@ #include "psfont.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_cf2blues +#define FT_COMPONENT cf2blues /* @@ -452,13 +452,13 @@ * zones in the same pass (see `BlueLock'). If a hint is captured, * return true and position the edge(s) in one of 3 ways: * - * 1) If `BlueScale' suppresses overshoot, position the captured edge - * at the flat edge of the zone. - * 2) If overshoot is not suppressed and `BlueShift' requires - * overshoot, position the captured edge a minimum of 1 device pixel - * from the flat edge. - * 3) If overshoot is not suppressed or required, position the captured - * edge at the nearest device pixel. + * 1) If `BlueScale' suppresses overshoot, position the captured edge + * at the flat edge of the zone. + * 2) If overshoot is not suppressed and `BlueShift' requires + * overshoot, position the captured edge a minimum of 1 device pixel + * from the flat edge. + * 3) If overshoot is not suppressed or required, position the captured + * edge at the nearest device pixel. * */ FT_LOCAL_DEF( FT_Bool ) diff --git a/sdk/lib/3rdparty/freetype/src/psaux/psblues.h b/sdk/lib/3rdparty/freetype/src/psaux/psblues.h index 25ef6849c77ce..55fb88ecddfa1 100644 --- a/sdk/lib/3rdparty/freetype/src/psaux/psblues.h +++ b/sdk/lib/3rdparty/freetype/src/psaux/psblues.h @@ -1,39 +1,39 @@ -/***************************************************************************/ -/* */ -/* psblues.h */ -/* */ -/* Adobe's code for handling Blue Zones (specification). */ -/* */ -/* Copyright 2009-2013 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * psblues.h + * + * Adobe's code for handling Blue Zones (specification). + * + * Copyright 2009-2013 Adobe Systems Incorporated. + * + * This software, and all works of authorship, whether in source or + * object code form as indicated by the copyright notice(s) included + * herein (collectively, the "Work") is made available, and may only be + * used, modified, and distributed under the FreeType Project License, + * LICENSE.TXT. Additionally, subject to the terms and conditions of the + * FreeType Project License, each contributor to the Work hereby grants + * to any individual or legal entity exercising permissions granted by + * the FreeType Project License and this section (hereafter, "You" or + * "Your") a perpetual, worldwide, non-exclusive, no-charge, + * royalty-free, irrevocable (except as stated in this section) patent + * license to make, have made, use, offer to sell, sell, import, and + * otherwise transfer the Work, where such license applies only to those + * patent claims licensable by such contributor that are necessarily + * infringed by their contribution(s) alone or by combination of their + * contribution(s) with the Work to which such contribution(s) was + * submitted. If You institute patent litigation against any entity + * (including a cross-claim or counterclaim in a lawsuit) alleging that + * the Work or a contribution incorporated within the Work constitutes + * direct or contributory patent infringement, then any patent licenses + * granted to You under this License for that Work shall terminate as of + * the date such litigation is filed. + * + * By using, modifying, or distributing the Work you indicate that you + * have read and understood the terms and conditions of the + * FreeType Project License as well as those provided in this section, + * and you accept them fully. + * + */ /* diff --git a/sdk/lib/3rdparty/freetype/src/psaux/psconv.c b/sdk/lib/3rdparty/freetype/src/psaux/psconv.c index a03385000df76..c88761681cc59 100644 --- a/sdk/lib/3rdparty/freetype/src/psaux/psconv.c +++ b/sdk/lib/3rdparty/freetype/src/psaux/psconv.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* psconv.c */ -/* */ -/* Some convenience conversions (body). */ -/* */ -/* Copyright 2006-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * psconv.c + * + * Some convenience conversions (body). + * + * Copyright (C) 2006-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -24,14 +24,14 @@ #include "psauxerr.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_psconv +#define FT_COMPONENT psconv /* The following array is used by various functions to quickly convert */ diff --git a/sdk/lib/3rdparty/freetype/src/psaux/psconv.h b/sdk/lib/3rdparty/freetype/src/psaux/psconv.h index d643ffcfc2cae..6b24bf6fc95e0 100644 --- a/sdk/lib/3rdparty/freetype/src/psaux/psconv.h +++ b/sdk/lib/3rdparty/freetype/src/psaux/psconv.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* psconv.h */ -/* */ -/* Some convenience conversions (specification). */ -/* */ -/* Copyright 2006-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * psconv.h + * + * Some convenience conversions (specification). + * + * Copyright (C) 2006-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef PSCONV_H_ diff --git a/sdk/lib/3rdparty/freetype/src/psaux/pserror.c b/sdk/lib/3rdparty/freetype/src/psaux/pserror.c index 9169e5222d0ab..98cebcf74d99e 100644 --- a/sdk/lib/3rdparty/freetype/src/psaux/pserror.c +++ b/sdk/lib/3rdparty/freetype/src/psaux/pserror.c @@ -1,39 +1,39 @@ -/***************************************************************************/ -/* */ -/* pserror.c */ -/* */ -/* Adobe's code for error handling (body). */ -/* */ -/* Copyright 2006-2013 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * pserror.c + * + * Adobe's code for error handling (body). + * + * Copyright 2006-2013 Adobe Systems Incorporated. + * + * This software, and all works of authorship, whether in source or + * object code form as indicated by the copyright notice(s) included + * herein (collectively, the "Work") is made available, and may only be + * used, modified, and distributed under the FreeType Project License, + * LICENSE.TXT. Additionally, subject to the terms and conditions of the + * FreeType Project License, each contributor to the Work hereby grants + * to any individual or legal entity exercising permissions granted by + * the FreeType Project License and this section (hereafter, "You" or + * "Your") a perpetual, worldwide, non-exclusive, no-charge, + * royalty-free, irrevocable (except as stated in this section) patent + * license to make, have made, use, offer to sell, sell, import, and + * otherwise transfer the Work, where such license applies only to those + * patent claims licensable by such contributor that are necessarily + * infringed by their contribution(s) alone or by combination of their + * contribution(s) with the Work to which such contribution(s) was + * submitted. If You institute patent litigation against any entity + * (including a cross-claim or counterclaim in a lawsuit) alleging that + * the Work or a contribution incorporated within the Work constitutes + * direct or contributory patent infringement, then any patent licenses + * granted to You under this License for that Work shall terminate as of + * the date such litigation is filed. + * + * By using, modifying, or distributing the Work you indicate that you + * have read and understood the terms and conditions of the + * FreeType Project License as well as those provided in this section, + * and you accept them fully. + * + */ #include "psft.h" diff --git a/sdk/lib/3rdparty/freetype/src/psaux/pserror.h b/sdk/lib/3rdparty/freetype/src/psaux/pserror.h index 13d52062bf31d..b2156b3318b75 100644 --- a/sdk/lib/3rdparty/freetype/src/psaux/pserror.h +++ b/sdk/lib/3rdparty/freetype/src/psaux/pserror.h @@ -1,39 +1,39 @@ -/***************************************************************************/ -/* */ -/* pserror.h */ -/* */ -/* Adobe's code for error handling (specification). */ -/* */ -/* Copyright 2006-2013 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * pserror.h + * + * Adobe's code for error handling (specification). + * + * Copyright 2006-2013 Adobe Systems Incorporated. + * + * This software, and all works of authorship, whether in source or + * object code form as indicated by the copyright notice(s) included + * herein (collectively, the "Work") is made available, and may only be + * used, modified, and distributed under the FreeType Project License, + * LICENSE.TXT. Additionally, subject to the terms and conditions of the + * FreeType Project License, each contributor to the Work hereby grants + * to any individual or legal entity exercising permissions granted by + * the FreeType Project License and this section (hereafter, "You" or + * "Your") a perpetual, worldwide, non-exclusive, no-charge, + * royalty-free, irrevocable (except as stated in this section) patent + * license to make, have made, use, offer to sell, sell, import, and + * otherwise transfer the Work, where such license applies only to those + * patent claims licensable by such contributor that are necessarily + * infringed by their contribution(s) alone or by combination of their + * contribution(s) with the Work to which such contribution(s) was + * submitted. If You institute patent litigation against any entity + * (including a cross-claim or counterclaim in a lawsuit) alleging that + * the Work or a contribution incorporated within the Work constitutes + * direct or contributory patent infringement, then any patent licenses + * granted to You under this License for that Work shall terminate as of + * the date such litigation is filed. + * + * By using, modifying, or distributing the Work you indicate that you + * have read and understood the terms and conditions of the + * FreeType Project License as well as those provided in this section, + * and you accept them fully. + * + */ #ifndef PSERROR_H_ diff --git a/sdk/lib/3rdparty/freetype/src/psaux/psfixed.h b/sdk/lib/3rdparty/freetype/src/psaux/psfixed.h index 219589e7fc777..fd3460f34afb9 100644 --- a/sdk/lib/3rdparty/freetype/src/psaux/psfixed.h +++ b/sdk/lib/3rdparty/freetype/src/psaux/psfixed.h @@ -1,39 +1,39 @@ -/***************************************************************************/ -/* */ -/* psfixed.h */ -/* */ -/* Adobe's code for Fixed Point Mathematics (specification only). */ -/* */ -/* Copyright 2007-2013 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * psfixed.h + * + * Adobe's code for Fixed Point Mathematics (specification only). + * + * Copyright 2007-2013 Adobe Systems Incorporated. + * + * This software, and all works of authorship, whether in source or + * object code form as indicated by the copyright notice(s) included + * herein (collectively, the "Work") is made available, and may only be + * used, modified, and distributed under the FreeType Project License, + * LICENSE.TXT. Additionally, subject to the terms and conditions of the + * FreeType Project License, each contributor to the Work hereby grants + * to any individual or legal entity exercising permissions granted by + * the FreeType Project License and this section (hereafter, "You" or + * "Your") a perpetual, worldwide, non-exclusive, no-charge, + * royalty-free, irrevocable (except as stated in this section) patent + * license to make, have made, use, offer to sell, sell, import, and + * otherwise transfer the Work, where such license applies only to those + * patent claims licensable by such contributor that are necessarily + * infringed by their contribution(s) alone or by combination of their + * contribution(s) with the Work to which such contribution(s) was + * submitted. If You institute patent litigation against any entity + * (including a cross-claim or counterclaim in a lawsuit) alleging that + * the Work or a contribution incorporated within the Work constitutes + * direct or contributory patent infringement, then any patent licenses + * granted to You under this License for that Work shall terminate as of + * the date such litigation is filed. + * + * By using, modifying, or distributing the Work you indicate that you + * have read and understood the terms and conditions of the + * FreeType Project License as well as those provided in this section, + * and you accept them fully. + * + */ #ifndef PSFIXED_H_ diff --git a/sdk/lib/3rdparty/freetype/src/psaux/psfont.c b/sdk/lib/3rdparty/freetype/src/psaux/psfont.c index dde67a739d661..bb5faa38f5c0d 100644 --- a/sdk/lib/3rdparty/freetype/src/psaux/psfont.c +++ b/sdk/lib/3rdparty/freetype/src/psaux/psfont.c @@ -1,39 +1,39 @@ -/***************************************************************************/ -/* */ -/* psfont.c */ -/* */ -/* Adobe's code for font instances (body). */ -/* */ -/* Copyright 2007-2014 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * psfont.c + * + * Adobe's code for font instances (body). + * + * Copyright 2007-2014 Adobe Systems Incorporated. + * + * This software, and all works of authorship, whether in source or + * object code form as indicated by the copyright notice(s) included + * herein (collectively, the "Work") is made available, and may only be + * used, modified, and distributed under the FreeType Project License, + * LICENSE.TXT. Additionally, subject to the terms and conditions of the + * FreeType Project License, each contributor to the Work hereby grants + * to any individual or legal entity exercising permissions granted by + * the FreeType Project License and this section (hereafter, "You" or + * "Your") a perpetual, worldwide, non-exclusive, no-charge, + * royalty-free, irrevocable (except as stated in this section) patent + * license to make, have made, use, offer to sell, sell, import, and + * otherwise transfer the Work, where such license applies only to those + * patent claims licensable by such contributor that are necessarily + * infringed by their contribution(s) alone or by combination of their + * contribution(s) with the Work to which such contribution(s) was + * submitted. If You institute patent litigation against any entity + * (including a cross-claim or counterclaim in a lawsuit) alleging that + * the Work or a contribution incorporated within the Work constitutes + * direct or contributory patent infringement, then any patent licenses + * granted to You under this License for that Work shall terminate as of + * the date such litigation is filed. + * + * By using, modifying, or distributing the Work you indicate that you + * have read and understood the terms and conditions of the + * FreeType Project License as well as those provided in this section, + * and you accept them fully. + * + */ #include <ft2build.h> @@ -331,7 +331,7 @@ } /* copy hinted flag on each call */ - font->hinted = (FT_Bool)( font->renderingFlags & CF2_FlagsHinted ); + font->hinted = FT_BOOL( font->renderingFlags & CF2_FlagsHinted ); /* determine if transform has changed; */ /* include Fontmatrix but ignore translation */ @@ -366,7 +366,7 @@ if ( font->stemDarkened != ( font->renderingFlags & CF2_FlagsDarkened ) ) { font->stemDarkened = - (FT_Bool)( font->renderingFlags & CF2_FlagsDarkened ); + FT_BOOL( font->renderingFlags & CF2_FlagsDarkened ); /* blue zones depend on darkened flag */ needExtraSetup = TRUE; diff --git a/sdk/lib/3rdparty/freetype/src/psaux/psfont.h b/sdk/lib/3rdparty/freetype/src/psaux/psfont.h index e611ac4bdc8b4..8fbacbb6e3465 100644 --- a/sdk/lib/3rdparty/freetype/src/psaux/psfont.h +++ b/sdk/lib/3rdparty/freetype/src/psaux/psfont.h @@ -1,39 +1,39 @@ -/***************************************************************************/ -/* */ -/* psfont.h */ -/* */ -/* Adobe's code for font instances (specification). */ -/* */ -/* Copyright 2007-2013 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * psfont.h + * + * Adobe's code for font instances (specification). + * + * Copyright 2007-2013 Adobe Systems Incorporated. + * + * This software, and all works of authorship, whether in source or + * object code form as indicated by the copyright notice(s) included + * herein (collectively, the "Work") is made available, and may only be + * used, modified, and distributed under the FreeType Project License, + * LICENSE.TXT. Additionally, subject to the terms and conditions of the + * FreeType Project License, each contributor to the Work hereby grants + * to any individual or legal entity exercising permissions granted by + * the FreeType Project License and this section (hereafter, "You" or + * "Your") a perpetual, worldwide, non-exclusive, no-charge, + * royalty-free, irrevocable (except as stated in this section) patent + * license to make, have made, use, offer to sell, sell, import, and + * otherwise transfer the Work, where such license applies only to those + * patent claims licensable by such contributor that are necessarily + * infringed by their contribution(s) alone or by combination of their + * contribution(s) with the Work to which such contribution(s) was + * submitted. If You institute patent litigation against any entity + * (including a cross-claim or counterclaim in a lawsuit) alleging that + * the Work or a contribution incorporated within the Work constitutes + * direct or contributory patent infringement, then any patent licenses + * granted to You under this License for that Work shall terminate as of + * the date such litigation is filed. + * + * By using, modifying, or distributing the Work you indicate that you + * have read and understood the terms and conditions of the + * FreeType Project License as well as those provided in this section, + * and you accept them fully. + * + */ #ifndef PSFONT_H_ diff --git a/sdk/lib/3rdparty/freetype/src/psaux/psft.c b/sdk/lib/3rdparty/freetype/src/psaux/psft.c index 1f750174a1c93..54be46834303f 100644 --- a/sdk/lib/3rdparty/freetype/src/psaux/psft.c +++ b/sdk/lib/3rdparty/freetype/src/psaux/psft.c @@ -1,39 +1,39 @@ -/***************************************************************************/ -/* */ -/* psft.c */ -/* */ -/* FreeType Glue Component to Adobe's Interpreter (body). */ -/* */ -/* Copyright 2013-2014 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * psft.c + * + * FreeType Glue Component to Adobe's Interpreter (body). + * + * Copyright 2013-2014 Adobe Systems Incorporated. + * + * This software, and all works of authorship, whether in source or + * object code form as indicated by the copyright notice(s) included + * herein (collectively, the "Work") is made available, and may only be + * used, modified, and distributed under the FreeType Project License, + * LICENSE.TXT. Additionally, subject to the terms and conditions of the + * FreeType Project License, each contributor to the Work hereby grants + * to any individual or legal entity exercising permissions granted by + * the FreeType Project License and this section (hereafter, "You" or + * "Your") a perpetual, worldwide, non-exclusive, no-charge, + * royalty-free, irrevocable (except as stated in this section) patent + * license to make, have made, use, offer to sell, sell, import, and + * otherwise transfer the Work, where such license applies only to those + * patent claims licensable by such contributor that are necessarily + * infringed by their contribution(s) alone or by combination of their + * contribution(s) with the Work to which such contribution(s) was + * submitted. If You institute patent litigation against any entity + * (including a cross-claim or counterclaim in a lawsuit) alleging that + * the Work or a contribution incorporated within the Work constitutes + * direct or contributory patent infringement, then any patent licenses + * granted to You under this License for that Work shall terminate as of + * the date such litigation is filed. + * + * By using, modifying, or distributing the Work you indicate that you + * have read and understood the terms and conditions of the + * FreeType Project License as well as those provided in this section, + * and you accept them fully. + * + */ #include "psft.h" @@ -120,12 +120,12 @@ } - /********************************************/ - /* */ - /* functions for handling client outline; */ - /* FreeType uses coordinates in 26.6 format */ - /* */ - /********************************************/ + /********************************************* + * + * functions for handling client outline; + * FreeType uses coordinates in 26.6 format + * + */ static void cf2_builder_moveTo( CF2_OutlineCallbacks callbacks, @@ -767,13 +767,14 @@ cf2_freeT1SeacComponent( PS_Decoder* decoder, CF2_Buffer buf ) { +#ifdef FT_CONFIG_OPTION_INCREMENTAL + T1_Face face; FT_Data data; FT_ASSERT( decoder ); -#ifdef FT_CONFIG_OPTION_INCREMENTAL face = (T1_Face)decoder->builder.face; data.pointer = buf->start; @@ -783,7 +784,13 @@ face->root.internal->incremental_interface->funcs->free_glyph_data( face->root.internal->incremental_interface->object, &data ); -#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + +#else /* !FT_CONFIG_OPTION_INCREMENTAL */ + + FT_UNUSED( decoder ); + FT_UNUSED( buf ); + +#endif /* !FT_CONFIG_OPTION_INCREMENTAL */ } diff --git a/sdk/lib/3rdparty/freetype/src/psaux/psft.h b/sdk/lib/3rdparty/freetype/src/psaux/psft.h index ab172110bb69b..4c930f0d73fbd 100644 --- a/sdk/lib/3rdparty/freetype/src/psaux/psft.h +++ b/sdk/lib/3rdparty/freetype/src/psaux/psft.h @@ -1,39 +1,39 @@ -/***************************************************************************/ -/* */ -/* psft.h */ -/* */ -/* FreeType Glue Component to Adobe's Interpreter (specification). */ -/* */ -/* Copyright 2013 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * psft.h + * + * FreeType Glue Component to Adobe's Interpreter (specification). + * + * Copyright 2013 Adobe Systems Incorporated. + * + * This software, and all works of authorship, whether in source or + * object code form as indicated by the copyright notice(s) included + * herein (collectively, the "Work") is made available, and may only be + * used, modified, and distributed under the FreeType Project License, + * LICENSE.TXT. Additionally, subject to the terms and conditions of the + * FreeType Project License, each contributor to the Work hereby grants + * to any individual or legal entity exercising permissions granted by + * the FreeType Project License and this section (hereafter, "You" or + * "Your") a perpetual, worldwide, non-exclusive, no-charge, + * royalty-free, irrevocable (except as stated in this section) patent + * license to make, have made, use, offer to sell, sell, import, and + * otherwise transfer the Work, where such license applies only to those + * patent claims licensable by such contributor that are necessarily + * infringed by their contribution(s) alone or by combination of their + * contribution(s) with the Work to which such contribution(s) was + * submitted. If You institute patent litigation against any entity + * (including a cross-claim or counterclaim in a lawsuit) alleging that + * the Work or a contribution incorporated within the Work constitutes + * direct or contributory patent infringement, then any patent licenses + * granted to You under this License for that Work shall terminate as of + * the date such litigation is filed. + * + * By using, modifying, or distributing the Work you indicate that you + * have read and understood the terms and conditions of the + * FreeType Project License as well as those provided in this section, + * and you accept them fully. + * + */ #ifndef PSFT_H_ diff --git a/sdk/lib/3rdparty/freetype/src/psaux/psglue.h b/sdk/lib/3rdparty/freetype/src/psaux/psglue.h index 5545e12a5bf2e..022aafbfcacc2 100644 --- a/sdk/lib/3rdparty/freetype/src/psaux/psglue.h +++ b/sdk/lib/3rdparty/freetype/src/psaux/psglue.h @@ -1,39 +1,39 @@ -/***************************************************************************/ -/* */ -/* psglue.h */ -/* */ -/* Adobe's code for shared stuff (specification only). */ -/* */ -/* Copyright 2007-2013 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * psglue.h + * + * Adobe's code for shared stuff (specification only). + * + * Copyright 2007-2013 Adobe Systems Incorporated. + * + * This software, and all works of authorship, whether in source or + * object code form as indicated by the copyright notice(s) included + * herein (collectively, the "Work") is made available, and may only be + * used, modified, and distributed under the FreeType Project License, + * LICENSE.TXT. Additionally, subject to the terms and conditions of the + * FreeType Project License, each contributor to the Work hereby grants + * to any individual or legal entity exercising permissions granted by + * the FreeType Project License and this section (hereafter, "You" or + * "Your") a perpetual, worldwide, non-exclusive, no-charge, + * royalty-free, irrevocable (except as stated in this section) patent + * license to make, have made, use, offer to sell, sell, import, and + * otherwise transfer the Work, where such license applies only to those + * patent claims licensable by such contributor that are necessarily + * infringed by their contribution(s) alone or by combination of their + * contribution(s) with the Work to which such contribution(s) was + * submitted. If You institute patent litigation against any entity + * (including a cross-claim or counterclaim in a lawsuit) alleging that + * the Work or a contribution incorporated within the Work constitutes + * direct or contributory patent infringement, then any patent licenses + * granted to You under this License for that Work shall terminate as of + * the date such litigation is filed. + * + * By using, modifying, or distributing the Work you indicate that you + * have read and understood the terms and conditions of the + * FreeType Project License as well as those provided in this section, + * and you accept them fully. + * + */ #ifndef PSGLUE_H_ diff --git a/sdk/lib/3rdparty/freetype/src/psaux/pshints.c b/sdk/lib/3rdparty/freetype/src/psaux/pshints.c index 3615196425395..1cbecd2b193b8 100644 --- a/sdk/lib/3rdparty/freetype/src/psaux/pshints.c +++ b/sdk/lib/3rdparty/freetype/src/psaux/pshints.c @@ -1,39 +1,39 @@ -/***************************************************************************/ -/* */ -/* pshints.c */ -/* */ -/* Adobe's code for handling CFF hints (body). */ -/* */ -/* Copyright 2007-2014 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * pshints.c + * + * Adobe's code for handling CFF hints (body). + * + * Copyright 2007-2014 Adobe Systems Incorporated. + * + * This software, and all works of authorship, whether in source or + * object code form as indicated by the copyright notice(s) included + * herein (collectively, the "Work") is made available, and may only be + * used, modified, and distributed under the FreeType Project License, + * LICENSE.TXT. Additionally, subject to the terms and conditions of the + * FreeType Project License, each contributor to the Work hereby grants + * to any individual or legal entity exercising permissions granted by + * the FreeType Project License and this section (hereafter, "You" or + * "Your") a perpetual, worldwide, non-exclusive, no-charge, + * royalty-free, irrevocable (except as stated in this section) patent + * license to make, have made, use, offer to sell, sell, import, and + * otherwise transfer the Work, where such license applies only to those + * patent claims licensable by such contributor that are necessarily + * infringed by their contribution(s) alone or by combination of their + * contribution(s) with the Work to which such contribution(s) was + * submitted. If You institute patent litigation against any entity + * (including a cross-claim or counterclaim in a lawsuit) alleging that + * the Work or a contribution incorporated within the Work constitutes + * direct or contributory patent infringement, then any patent licenses + * granted to You under this License for that Work shall terminate as of + * the date such litigation is filed. + * + * By using, modifying, or distributing the Work you indicate that you + * have read and understood the terms and conditions of the + * FreeType Project License as well as those provided in this section, + * and you accept them fully. + * + */ #include "psft.h" @@ -45,14 +45,14 @@ #include "psintrp.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_cf2hints +#define FT_COMPONENT cf2hints typedef struct CF2_HintMoveRec_ @@ -217,52 +217,49 @@ FT_LOCAL_DEF( FT_Bool ) cf2_hint_isValid( const CF2_Hint hint ) { - return (FT_Bool)( hint->flags != 0 ); + return FT_BOOL( hint->flags ); } static FT_Bool cf2_hint_isPair( const CF2_Hint hint ) { - return (FT_Bool)( ( hint->flags & - ( CF2_PairBottom | CF2_PairTop ) ) != 0 ); + return FT_BOOL( hint->flags & ( CF2_PairBottom | CF2_PairTop ) ); } static FT_Bool cf2_hint_isPairTop( const CF2_Hint hint ) { - return (FT_Bool)( ( hint->flags & CF2_PairTop ) != 0 ); + return FT_BOOL( hint->flags & CF2_PairTop ); } FT_LOCAL_DEF( FT_Bool ) cf2_hint_isTop( const CF2_Hint hint ) { - return (FT_Bool)( ( hint->flags & - ( CF2_PairTop | CF2_GhostTop ) ) != 0 ); + return FT_BOOL( hint->flags & ( CF2_PairTop | CF2_GhostTop ) ); } FT_LOCAL_DEF( FT_Bool ) cf2_hint_isBottom( const CF2_Hint hint ) { - return (FT_Bool)( ( hint->flags & - ( CF2_PairBottom | CF2_GhostBottom ) ) != 0 ); + return FT_BOOL( hint->flags & ( CF2_PairBottom | CF2_GhostBottom ) ); } static FT_Bool cf2_hint_isLocked( const CF2_Hint hint ) { - return (FT_Bool)( ( hint->flags & CF2_Locked ) != 0 ); + return FT_BOOL( hint->flags & CF2_Locked ); } static FT_Bool cf2_hint_isSynthetic( const CF2_Hint hint ) { - return (FT_Bool)( ( hint->flags & CF2_Synthetic ) != 0 ); + return FT_BOOL( hint->flags & CF2_Synthetic ); } @@ -334,7 +331,7 @@ cf2_hintmap_map( CF2_HintMap hintmap, CF2_Fixed csCoord ) { - if ( hintmap->count == 0 || ! hintmap->hinted ) + if ( hintmap->count == 0 || !hintmap->hinted ) { /* there are no hints; use uniform scale and zero offset */ return FT_MulFix( csCoord, hintmap->scale ); @@ -497,7 +494,7 @@ { move = moveDown; /* true if non-optimum move */ - saveEdge = (FT_Bool)( moveUp < -moveDown ); + saveEdge = FT_BOOL( moveUp < -moveDown ); } else { @@ -1025,10 +1022,10 @@ } } - FT_TRACE6(( initialMap ? "flags: [p]air [g]host [t]op " - "[b]ottom [L]ocked [S]ynthetic\n" - "Initial hintmap\n" - : "Hints:\n" )); + FT_TRACE6(( "%s\n", initialMap ? "flags: [p]air [g]host [t]op" + " [b]ottom [L]ocked [S]ynthetic\n" + "Initial hintmap" + : "Hints:" )); cf2_hintmap_dump( hintmap ); /* @@ -1215,7 +1212,7 @@ * (`u'). * * See notation in - * http://softsurfer.com/Archive/algorithm_0104/algorithm_0104B.htm. + * http://geomalgorithms.com/a05-_intersect-1.html. * Calculations are done in 16.16, but must handle the squaring of * line lengths in character space. We scale all vectors by 1/32 to * avoid overflow. This allows values up to 4095 to be squared. The diff --git a/sdk/lib/3rdparty/freetype/src/psaux/pshints.h b/sdk/lib/3rdparty/freetype/src/psaux/pshints.h index 92e37e98aef0c..31a8230364c34 100644 --- a/sdk/lib/3rdparty/freetype/src/psaux/pshints.h +++ b/sdk/lib/3rdparty/freetype/src/psaux/pshints.h @@ -1,39 +1,39 @@ -/***************************************************************************/ -/* */ -/* pshints.h */ -/* */ -/* Adobe's code for handling CFF hints (body). */ -/* */ -/* Copyright 2007-2013 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * pshints.h + * + * Adobe's code for handling CFF hints (body). + * + * Copyright 2007-2013 Adobe Systems Incorporated. + * + * This software, and all works of authorship, whether in source or + * object code form as indicated by the copyright notice(s) included + * herein (collectively, the "Work") is made available, and may only be + * used, modified, and distributed under the FreeType Project License, + * LICENSE.TXT. Additionally, subject to the terms and conditions of the + * FreeType Project License, each contributor to the Work hereby grants + * to any individual or legal entity exercising permissions granted by + * the FreeType Project License and this section (hereafter, "You" or + * "Your") a perpetual, worldwide, non-exclusive, no-charge, + * royalty-free, irrevocable (except as stated in this section) patent + * license to make, have made, use, offer to sell, sell, import, and + * otherwise transfer the Work, where such license applies only to those + * patent claims licensable by such contributor that are necessarily + * infringed by their contribution(s) alone or by combination of their + * contribution(s) with the Work to which such contribution(s) was + * submitted. If You institute patent litigation against any entity + * (including a cross-claim or counterclaim in a lawsuit) alleging that + * the Work or a contribution incorporated within the Work constitutes + * direct or contributory patent infringement, then any patent licenses + * granted to You under this License for that Work shall terminate as of + * the date such litigation is filed. + * + * By using, modifying, or distributing the Work you indicate that you + * have read and understood the terms and conditions of the + * FreeType Project License as well as those provided in this section, + * and you accept them fully. + * + */ #ifndef PSHINT_H_ diff --git a/sdk/lib/3rdparty/freetype/src/psaux/psintrp.c b/sdk/lib/3rdparty/freetype/src/psaux/psintrp.c index bc86d00b27591..cf3f0d76ada41 100644 --- a/sdk/lib/3rdparty/freetype/src/psaux/psintrp.c +++ b/sdk/lib/3rdparty/freetype/src/psaux/psintrp.c @@ -1,39 +1,39 @@ -/***************************************************************************/ -/* */ -/* psintrp.c */ -/* */ -/* Adobe's CFF Interpreter (body). */ -/* */ -/* Copyright 2007-2014 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * psintrp.c + * + * Adobe's CFF Interpreter (body). + * + * Copyright 2007-2014 Adobe Systems Incorporated. + * + * This software, and all works of authorship, whether in source or + * object code form as indicated by the copyright notice(s) included + * herein (collectively, the "Work") is made available, and may only be + * used, modified, and distributed under the FreeType Project License, + * LICENSE.TXT. Additionally, subject to the terms and conditions of the + * FreeType Project License, each contributor to the Work hereby grants + * to any individual or legal entity exercising permissions granted by + * the FreeType Project License and this section (hereafter, "You" or + * "Your") a perpetual, worldwide, non-exclusive, no-charge, + * royalty-free, irrevocable (except as stated in this section) patent + * license to make, have made, use, offer to sell, sell, import, and + * otherwise transfer the Work, where such license applies only to those + * patent claims licensable by such contributor that are necessarily + * infringed by their contribution(s) alone or by combination of their + * contribution(s) with the Work to which such contribution(s) was + * submitted. If You institute patent litigation against any entity + * (including a cross-claim or counterclaim in a lawsuit) alleging that + * the Work or a contribution incorporated within the Work constitutes + * direct or contributory patent infringement, then any patent licenses + * granted to You under this License for that Work shall terminate as of + * the date such litigation is filed. + * + * By using, modifying, or distributing the Work you indicate that you + * have read and understood the terms and conditions of the + * FreeType Project License as well as those provided in this section, + * and you accept them fully. + * + */ #include "psft.h" @@ -52,14 +52,14 @@ #include "t1decode.h" /* for t1 seac */ - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_cf2interp +#define FT_COMPONENT cf2interp FT_LOCAL_DEF( void ) @@ -287,7 +287,7 @@ { CF2_UInt i; CF2_UInt count = cf2_stack_count( opStack ); - FT_Bool hasWidthArg = (FT_Bool)( count & 1 ); + FT_Bool hasWidthArg = FT_BOOL( count & 1 ); /* variable accumulates delta values from operand stack */ CF2_Fixed position = hintOffset; @@ -364,7 +364,7 @@ if ( doConditionalLastRead ) { - FT_Bool lastIsX = (FT_Bool)( + FT_Bool lastIsX = FT_BOOL( cf2_fixedAbs( SUB_INT32( vals[10], *curX ) ) > cf2_fixedAbs( SUB_INT32( vals[11], *curY ) ) ); CF2_Fixed lastVal = cf2_stack_getReal( opStack, idx ); @@ -526,10 +526,10 @@ CF2_HintMaskRec hintMask; #ifdef __REACTOS__ - CF2_GlyphPathRec *glyphPath = malloc(sizeof(CF2_GlyphPathRec)); - if (!glyphPath) return; + CF2_GlyphPathRec *glyphPath_allocated = malloc(sizeof(*glyphPath_allocated)); + if (!glyphPath_allocated) return; /* Ugly but it allows us to reduce the diff */ -#define glyphPath (*glyphPath) +#define glyphPath (*glyphPath_allocated) #else CF2_GlyphPathRec glyphPath; #endif @@ -618,14 +618,14 @@ cf2_arrstack_setCount( &subrStack, CF2_MAX_SUBR + 1 ); charstring = (CF2_Buffer)cf2_arrstack_getBuffer( &subrStack ); - *charstring = *buf; /* structure copy */ - - charstringIndex = 0; /* entry is valid now */ /* catch errors so far */ if ( *error ) goto exit; + *charstring = *buf; /* structure copy */ + charstringIndex = 0; /* entry is valid now */ + /* main interpreter loop */ while ( 1 ) { @@ -669,6 +669,7 @@ /* Skip outline commands first time round. */ /* `endchar' will trigger initial hintmap build */ /* and rewind the charstring. */ + FT_TRACE4(( " <outline command skipped>\n" )); cf2_stack_clear( opStack ); continue; } @@ -781,7 +782,8 @@ case cf2_cmdHSTEMHM: case cf2_cmdHSTEM: - FT_TRACE4(( op1 == cf2_cmdHSTEMHM ? " hstemhm\n" : " hstem\n" )); + FT_TRACE4(( "%s\n", op1 == cf2_cmdHSTEMHM ? " hstemhm" + : " hstem" )); if ( !font->isT1 ) { @@ -811,7 +813,8 @@ case cf2_cmdVSTEMHM: case cf2_cmdVSTEM: - FT_TRACE4(( op1 == cf2_cmdVSTEMHM ? " vstemhm\n" : " vstem\n" )); + FT_TRACE4(( "%s\n", op1 == cf2_cmdVSTEMHM ? " vstemhm" + : " vstem" )); if ( !font->isT1 ) { @@ -858,7 +861,8 @@ curY = ADD_INT32( curY, cf2_stack_popFixed( opStack ) ); - cf2_glyphpath_moveTo( &glyphPath, curX, curY ); + if ( !decoder->flex_state ) + cf2_glyphpath_moveTo( &glyphPath, curX, curY ); break; @@ -893,7 +897,7 @@ FT_Bool isX = FT_BOOL( op1 == cf2_cmdHLINETO ); - FT_TRACE4(( isX ? " hlineto\n" : " vlineto\n" )); + FT_TRACE4(( "%s\n", isX ? " hlineto" : " vlineto" )); for ( idx = 0; idx < count; idx++ ) { @@ -921,8 +925,8 @@ CF2_UInt idx = 0; - FT_TRACE4(( op1 == cf2_cmdRCURVELINE ? " rcurveline\n" - : " rrcurveto\n" )); + FT_TRACE4(( "%s\n", op1 == cf2_cmdRCURVELINE ? " rcurveline" + : " rrcurveto" )); while ( idx + 6 <= count ) { @@ -962,10 +966,10 @@ FT_TRACE4(( " unknown op (%d)\n", op1 )); else { - FT_TRACE4(( " closepath" )); + FT_TRACE4(( " closepath\n" )); /* if there is no path, `closepath' is a no-op */ - ps_builder_close_contour( &decoder->builder ); + cf2_glyphpath_closeOpenPath( &glyphPath ); haveWidth = TRUE; } @@ -977,8 +981,8 @@ CF2_Int subrNum; - FT_TRACE4(( op1 == cf2_cmdCALLGSUBR ? " callgsubr" - : " callsubr" )); + FT_TRACE4(( "%s", op1 == cf2_cmdCALLGSUBR ? " callgsubr" + : " callsubr" )); if ( ( !font->isT1 && charstringIndex > CF2_MAX_SUBR ) || ( font->isT1 && charstringIndex > T1_MAX_SUBRS_CALLS ) ) @@ -1217,8 +1221,8 @@ FT_Bool isV = FT_BOOL( op2 == cf2_escVSTEM3 ); - FT_TRACE4(( isV ? " vstem3\n" - : " hstem3\n" )); + FT_TRACE4(( "%s\n", isV ? " vstem3" + : " hstem3" )); FT_ASSERT( cf2_stack_count( opStack ) == 6 ); @@ -1649,16 +1653,17 @@ subr_no = cf2_stack_popInt( opStack ); arg_cnt = cf2_stack_popInt( opStack ); - /*******************************************************/ - /* */ - /* remove all operands to callothersubr from the stack */ - /* */ - /* for handled othersubrs, where we know the number of */ - /* arguments, we increase the stack by the value of */ - /* known_othersubr_result_cnt */ - /* */ - /* for unhandled othersubrs the following pops adjust */ - /* the stack pointer as necessary */ + /******************************************************** + * + * remove all operands to callothersubr from the stack + * + * for handled othersubrs, where we know the number of + * arguments, we increase the stack by the value of + * known_othersubr_result_cnt + * + * for unhandled othersubrs the following pops adjust + * the stack pointer as necessary + */ count = cf2_stack_count( opStack ); FT_ASSERT( (CF2_UInt)arg_cnt <= count ); @@ -2421,7 +2426,7 @@ PS_Builder* builder; - FT_TRACE4(( " hsbw" )); + FT_TRACE4(( " hsbw\n" )); builder = &decoder->builder; @@ -2567,7 +2572,7 @@ case cf2_cmdHINTMASK: /* the final \n in the tracing message gets added in */ /* `cf2_hintmask_read' (which also traces the mask bytes) */ - FT_TRACE4(( op1 == cf2_cmdCNTRMASK ? " cntrmask" : " hintmask" )); + FT_TRACE4(( "%s", op1 == cf2_cmdCNTRMASK ? " cntrmask" : " hintmask" )); /* never add hints after the mask is computed */ if ( cf2_stack_count( opStack ) > 1 && @@ -2613,15 +2618,15 @@ * */ #ifdef __REACTOS__ - CF2_HintMapRec *counterHintMap = malloc(sizeof(CF2_HintMapRec)); + CF2_HintMapRec *counterHintMap_allocated = malloc(sizeof(*counterHintMap_allocated)); CF2_HintMaskRec counterMask; - if (!counterHintMap) + if (!counterHintMap_allocated) { lastError = FT_Err_Out_Of_Memory; goto exit; } /* Ugly but it allows us to reduce the diff */ -#define counterHintMap (*counterHintMap) +#define counterHintMap (*counterHintMap_allocated) #else CF2_HintMapRec counterHintMap; CF2_HintMaskRec counterMask; @@ -2646,7 +2651,8 @@ 0, FALSE ); #ifdef __REACTOS__ - free(&counterHintMap); + free(counterHintMap_allocated); +#undef counterHintMap #endif } break; @@ -2695,7 +2701,8 @@ curX = ADD_INT32( curX, cf2_stack_popFixed( opStack ) ); - cf2_glyphpath_moveTo( &glyphPath, curX, curY ); + if ( !decoder->flex_state ) + cf2_glyphpath_moveTo( &glyphPath, curX, curY ); break; @@ -2847,7 +2854,7 @@ count = count1 & ~2U; idx += count1 - count; - FT_TRACE4(( alternate ? " hvcurveto\n" : " vhcurveto\n" )); + FT_TRACE4(( "%s\n", alternate ? " hvcurveto" : " vhcurveto" )); while ( idx < count ) { @@ -3053,8 +3060,7 @@ FT_TRACE4(( "\n" )); #ifdef __REACTOS__ - free(&glyphPath); -#undef counterHintMap + free(glyphPath_allocated); #undef glyphPath #endif diff --git a/sdk/lib/3rdparty/freetype/src/psaux/psintrp.h b/sdk/lib/3rdparty/freetype/src/psaux/psintrp.h index 4790aaa302ae0..669c09c0ae5f8 100644 --- a/sdk/lib/3rdparty/freetype/src/psaux/psintrp.h +++ b/sdk/lib/3rdparty/freetype/src/psaux/psintrp.h @@ -1,39 +1,39 @@ -/***************************************************************************/ -/* */ -/* psintrp.h */ -/* */ -/* Adobe's CFF Interpreter (specification). */ -/* */ -/* Copyright 2007-2013 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * psintrp.h + * + * Adobe's CFF Interpreter (specification). + * + * Copyright 2007-2013 Adobe Systems Incorporated. + * + * This software, and all works of authorship, whether in source or + * object code form as indicated by the copyright notice(s) included + * herein (collectively, the "Work") is made available, and may only be + * used, modified, and distributed under the FreeType Project License, + * LICENSE.TXT. Additionally, subject to the terms and conditions of the + * FreeType Project License, each contributor to the Work hereby grants + * to any individual or legal entity exercising permissions granted by + * the FreeType Project License and this section (hereafter, "You" or + * "Your") a perpetual, worldwide, non-exclusive, no-charge, + * royalty-free, irrevocable (except as stated in this section) patent + * license to make, have made, use, offer to sell, sell, import, and + * otherwise transfer the Work, where such license applies only to those + * patent claims licensable by such contributor that are necessarily + * infringed by their contribution(s) alone or by combination of their + * contribution(s) with the Work to which such contribution(s) was + * submitted. If You institute patent litigation against any entity + * (including a cross-claim or counterclaim in a lawsuit) alleging that + * the Work or a contribution incorporated within the Work constitutes + * direct or contributory patent infringement, then any patent licenses + * granted to You under this License for that Work shall terminate as of + * the date such litigation is filed. + * + * By using, modifying, or distributing the Work you indicate that you + * have read and understood the terms and conditions of the + * FreeType Project License as well as those provided in this section, + * and you accept them fully. + * + */ #ifndef PSINTRP_H_ diff --git a/sdk/lib/3rdparty/freetype/src/psaux/psobjs.c b/sdk/lib/3rdparty/freetype/src/psaux/psobjs.c index f54bc7e416443..e2168a3324082 100644 --- a/sdk/lib/3rdparty/freetype/src/psaux/psobjs.c +++ b/sdk/lib/3rdparty/freetype/src/psaux/psobjs.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* psobjs.c */ -/* */ -/* Auxiliary functions for PostScript fonts (body). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * psobjs.c + * + * Auxiliary functions for PostScript fonts (body). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -29,14 +29,14 @@ #include "psauxmod.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_psobjs +#define FT_COMPONENT psobjs /*************************************************************************/ @@ -47,26 +47,29 @@ /*************************************************************************/ /*************************************************************************/ - /*************************************************************************/ - /* */ - /* <Function> */ - /* ps_table_new */ - /* */ - /* <Description> */ - /* Initializes a PS_Table. */ - /* */ - /* <InOut> */ - /* table :: The address of the target table. */ - /* */ - /* <Input> */ - /* count :: The table size = the maximum number of elements. */ - /* */ - /* memory :: The memory object to use for all subsequent */ - /* reallocations. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * ps_table_new + * + * @Description: + * Initializes a PS_Table. + * + * @InOut: + * table :: + * The address of the target table. + * + * @Input: + * count :: + * The table size = the maximum number of elements. + * + * memory :: + * The memory object to use for all subsequent + * reallocations. + * + * @Return: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) ps_table_new( PS_Table table, FT_Int count, @@ -144,28 +147,32 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* ps_table_add */ - /* */ - /* <Description> */ - /* Adds an object to a PS_Table, possibly growing its memory block. */ - /* */ - /* <InOut> */ - /* table :: The target table. */ - /* */ - /* <Input> */ - /* idx :: The index of the object in the table. */ - /* */ - /* object :: The address of the object to copy in memory. */ - /* */ - /* length :: The length in bytes of the source object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. An error is returned if a */ - /* reallocation fails. */ - /* */ + /************************************************************************** + * + * @Function: + * ps_table_add + * + * @Description: + * Adds an object to a PS_Table, possibly growing its memory block. + * + * @InOut: + * table :: + * The target table. + * + * @Input: + * idx :: + * The index of the object in the table. + * + * object :: + * The address of the object to copy in memory. + * + * length :: + * The length in bytes of the source object. + * + * @Return: + * FreeType error code. 0 means success. An error is returned if a + * reallocation fails. + */ FT_LOCAL_DEF( FT_Error ) ps_table_add( PS_Table table, FT_Int idx, @@ -216,22 +223,23 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* ps_table_done */ - /* */ - /* <Description> */ - /* Finalizes a PS_TableRec (i.e., reallocate it to its current */ - /* cursor). */ - /* */ - /* <InOut> */ - /* table :: The target table. */ - /* */ - /* <Note> */ - /* This function does NOT release the heap's memory block. It is up */ - /* to the caller to clean it, or reference it in its own structures. */ - /* */ + /************************************************************************** + * + * @Function: + * ps_table_done + * + * @Description: + * Finalizes a PS_TableRec (i.e., reallocate it to its current + * cursor). + * + * @InOut: + * table :: + * The target table. + * + * @Note: + * This function does NOT release the heap's memory block. It is up + * to the caller to clean it, or reference it in its own structures. + */ FT_LOCAL_DEF( void ) ps_table_done( PS_Table table ) { @@ -498,12 +506,12 @@ } - /***********************************************************************/ - /* */ - /* All exported parsing routines handle leading whitespace and stop at */ - /* the first character which isn't part of the just handled token. */ - /* */ - /***********************************************************************/ + /************************************************************************ + * + * All exported parsing routines handle leading whitespace and stop at + * the first character which isn't part of the just handled token. + * + */ FT_LOCAL_DEF( void ) @@ -1100,18 +1108,22 @@ { case T1_FIELD_TYPE_BOOL: val = ps_tobool( &cur, limit ); + FT_TRACE4(( " %s", val ? "true" : "false" )); goto Store_Integer; case T1_FIELD_TYPE_FIXED: val = PS_Conv_ToFixed( &cur, limit, 0 ); + FT_TRACE4(( " %f", (double)val / 65536 )); goto Store_Integer; case T1_FIELD_TYPE_FIXED_1000: val = PS_Conv_ToFixed( &cur, limit, 3 ); + FT_TRACE4(( " %f", (double)val / 65536 / 1000 )); goto Store_Integer; case T1_FIELD_TYPE_INTEGER: val = PS_Conv_ToInt( &cur, limit ); + FT_TRACE4(( " %ld", val )); /* fall through */ Store_Integer: @@ -1188,6 +1200,13 @@ FT_MEM_COPY( string, cur, len ); string[len] = 0; +#ifdef FT_DEBUG_LEVEL_TRACE + if ( token.type == T1_TOKEN_TYPE_STRING ) + FT_TRACE4(( " (%s)", string )); + else + FT_TRACE4(( " /%s", string )); +#endif + *(FT_String**)q = string; } break; @@ -1213,6 +1232,12 @@ bbox->yMin = FT_RoundFix( temp[1] ); bbox->xMax = FT_RoundFix( temp[2] ); bbox->yMax = FT_RoundFix( temp[3] ); + + FT_TRACE4(( " [%d %d %d %d]", + bbox->xMin / 65536, + bbox->yMin / 65536, + bbox->xMax / 65536, + bbox->yMax / 65536 )); } break; @@ -1251,6 +1276,7 @@ skip_spaces( &cur, limit ); } + FT_TRACE4(( " [" )); for ( i = 0; i < max_objects; i++ ) { FT_BBox* bbox = (FT_BBox*)objects[i]; @@ -1260,7 +1286,14 @@ bbox->yMin = FT_RoundFix( temp[i + max_objects] ); bbox->xMax = FT_RoundFix( temp[i + 2 * max_objects] ); bbox->yMax = FT_RoundFix( temp[i + 3 * max_objects] ); + + FT_TRACE4(( " [%d %d %d %d]", + bbox->xMin / 65536, + bbox->yMin / 65536, + bbox->xMax / 65536, + bbox->yMax / 65536 )); } + FT_TRACE4(( "]" )); FT_FREE( temp ); } @@ -1333,6 +1366,8 @@ *(FT_Byte*)( (FT_Byte*)objects[0] + field->count_offset ) = (FT_Byte)num_elements; + FT_TRACE4(( " [" )); + /* we now load each element, adjusting the field.offset on each one */ token = elements; for ( ; num_elements > 0; num_elements--, token++ ) @@ -1351,6 +1386,8 @@ fieldrec.offset += fieldrec.size; } + FT_TRACE4(( "]" )); + #if 0 /* obsolete -- keep for reference */ if ( pflags ) *pflags |= 1L << field->flag_bit; @@ -1410,6 +1447,8 @@ bytes, max_bytes ); + parser->cursor = cur; + if ( delimiters ) { if ( cur < parser->limit && *cur != '>' ) @@ -1419,11 +1458,9 @@ goto Exit; } - cur++; + parser->cursor++; } - parser->cursor = cur; - Exit: return error; } @@ -1509,26 +1546,31 @@ /*************************************************************************/ /*************************************************************************/ - /*************************************************************************/ - /* */ - /* <Function> */ - /* t1_builder_init */ - /* */ - /* <Description> */ - /* Initializes a given glyph builder. */ - /* */ - /* <InOut> */ - /* builder :: A pointer to the glyph builder to initialize. */ - /* */ - /* <Input> */ - /* face :: The current face object. */ - /* */ - /* size :: The current size object. */ - /* */ - /* glyph :: The current glyph object. */ - /* */ - /* hinting :: Whether hinting should be applied. */ - /* */ + /************************************************************************** + * + * @Function: + * t1_builder_init + * + * @Description: + * Initializes a given glyph builder. + * + * @InOut: + * builder :: + * A pointer to the glyph builder to initialize. + * + * @Input: + * face :: + * The current face object. + * + * size :: + * The current size object. + * + * glyph :: + * The current glyph object. + * + * hinting :: + * Whether hinting should be applied. + */ FT_LOCAL_DEF( void ) t1_builder_init( T1_Builder builder, FT_Face face, @@ -1572,19 +1614,20 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* t1_builder_done */ - /* */ - /* <Description> */ - /* Finalizes a given glyph builder. Its contents can still be used */ - /* after the call, but the function saves important information */ - /* within the corresponding glyph slot. */ - /* */ - /* <Input> */ - /* builder :: A pointer to the glyph builder to finalize. */ - /* */ + /************************************************************************** + * + * @Function: + * t1_builder_done + * + * @Description: + * Finalizes a given glyph builder. Its contents can still be used + * after the call, but the function saves important information + * within the corresponding glyph slot. + * + * @Input: + * builder :: + * A pointer to the glyph builder to finalize. + */ FT_LOCAL_DEF( void ) t1_builder_done( T1_Builder builder ) { @@ -1769,26 +1812,31 @@ /*************************************************************************/ - /*************************************************************************/ - /* */ - /* <Function> */ - /* cff_builder_init */ - /* */ - /* <Description> */ - /* Initializes a given glyph builder. */ - /* */ - /* <InOut> */ - /* builder :: A pointer to the glyph builder to initialize. */ - /* */ - /* <Input> */ - /* face :: The current face object. */ - /* */ - /* size :: The current size object. */ - /* */ - /* glyph :: The current glyph object. */ - /* */ - /* hinting :: Whether hinting is active. */ - /* */ + /************************************************************************** + * + * @Function: + * cff_builder_init + * + * @Description: + * Initializes a given glyph builder. + * + * @InOut: + * builder :: + * A pointer to the glyph builder to initialize. + * + * @Input: + * face :: + * The current face object. + * + * size :: + * The current size object. + * + * glyph :: + * The current glyph object. + * + * hinting :: + * Whether hinting is active. + */ FT_LOCAL_DEF( void ) cff_builder_init( CFF_Builder* builder, TT_Face face, @@ -1841,19 +1889,20 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* cff_builder_done */ - /* */ - /* <Description> */ - /* Finalizes a given glyph builder. Its contents can still be used */ - /* after the call, but the function saves important information */ - /* within the corresponding glyph slot. */ - /* */ - /* <Input> */ - /* builder :: A pointer to the glyph builder to finalize. */ - /* */ + /************************************************************************** + * + * @Function: + * cff_builder_done + * + * @Description: + * Finalizes a given glyph builder. Its contents can still be used + * after the call, but the function saves important information + * within the corresponding glyph slot. + * + * @Input: + * builder :: + * A pointer to the glyph builder to finalize. + */ FT_LOCAL_DEF( void ) cff_builder_done( CFF_Builder* builder ) { @@ -1993,6 +2042,14 @@ first = outline->n_contours <= 1 ? 0 : outline->contours[outline->n_contours - 2] + 1; + /* in malformed fonts it can happen that a contour was started */ + /* but no points were added */ + if ( outline->n_contours && first == outline->n_points ) + { + outline->n_contours--; + return; + } + /* We must not include the last point in the path if it */ /* is located on the first point. */ if ( outline->n_points > 1 ) @@ -2033,26 +2090,31 @@ /*************************************************************************/ /*************************************************************************/ - /*************************************************************************/ - /* */ - /* <Function> */ - /* ps_builder_init */ - /* */ - /* <Description> */ - /* Initializes a given glyph builder. */ - /* */ - /* <InOut> */ - /* builder :: A pointer to the glyph builder to initialize. */ - /* */ - /* <Input> */ - /* face :: The current face object. */ - /* */ - /* size :: The current size object. */ - /* */ - /* glyph :: The current glyph object. */ - /* */ - /* hinting :: Whether hinting should be applied. */ - /* */ + /************************************************************************** + * + * @Function: + * ps_builder_init + * + * @Description: + * Initializes a given glyph builder. + * + * @InOut: + * builder :: + * A pointer to the glyph builder to initialize. + * + * @Input: + * face :: + * The current face object. + * + * size :: + * The current size object. + * + * glyph :: + * The current glyph object. + * + * hinting :: + * Whether hinting should be applied. + */ FT_LOCAL_DEF( void ) ps_builder_init( PS_Builder* ps_builder, void* builder, @@ -2116,19 +2178,20 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* ps_builder_done */ - /* */ - /* <Description> */ - /* Finalizes a given glyph builder. Its contents can still be used */ - /* after the call, but the function saves important information */ - /* within the corresponding glyph slot. */ - /* */ - /* <Input> */ - /* builder :: A pointer to the glyph builder to finalize. */ - /* */ + /************************************************************************** + * + * @Function: + * ps_builder_done + * + * @Description: + * Finalizes a given glyph builder. Its contents can still be used + * after the call, but the function saves important information + * within the corresponding glyph slot. + * + * @Input: + * builder :: + * A pointer to the glyph builder to finalize. + */ FT_LOCAL_DEF( void ) ps_builder_done( PS_Builder* builder ) { @@ -2336,23 +2399,26 @@ /*************************************************************************/ - /*************************************************************************/ - /* */ - /* <Function> */ - /* ps_decoder_init */ - /* */ - /* <Description> */ - /* Creates a wrapper decoder for use in the combined */ - /* Type 1 / CFF interpreter. */ - /* */ - /* <InOut> */ - /* ps_decoder :: A pointer to the decoder to initialize. */ - /* */ - /* <Input> */ - /* decoder :: A pointer to the original decoder. */ - /* */ - /* is_t1 :: Flag indicating Type 1 or CFF */ - /* */ + /************************************************************************** + * + * @Function: + * ps_decoder_init + * + * @Description: + * Creates a wrapper decoder for use in the combined + * Type 1 / CFF interpreter. + * + * @InOut: + * ps_decoder :: + * A pointer to the decoder to initialize. + * + * @Input: + * decoder :: + * A pointer to the original decoder. + * + * is_t1 :: + * Flag indicating Type 1 or CFF + */ FT_LOCAL_DEF( void ) ps_decoder_init( PS_Decoder* ps_decoder, void* decoder, diff --git a/sdk/lib/3rdparty/freetype/src/psaux/psobjs.h b/sdk/lib/3rdparty/freetype/src/psaux/psobjs.h index 8e0fe5fa4c05b..9466a1d0754f3 100644 --- a/sdk/lib/3rdparty/freetype/src/psaux/psobjs.h +++ b/sdk/lib/3rdparty/freetype/src/psaux/psobjs.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* psobjs.h */ -/* */ -/* Auxiliary functions for PostScript fonts (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * psobjs.h + * + * Auxiliary functions for PostScript fonts (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef PSOBJS_H_ diff --git a/sdk/lib/3rdparty/freetype/src/psaux/psread.c b/sdk/lib/3rdparty/freetype/src/psaux/psread.c index 719863ce1786d..86bfc03c6e5f8 100644 --- a/sdk/lib/3rdparty/freetype/src/psaux/psread.c +++ b/sdk/lib/3rdparty/freetype/src/psaux/psread.c @@ -1,39 +1,39 @@ -/***************************************************************************/ -/* */ -/* psread.c */ -/* */ -/* Adobe's code for stream handling (body). */ -/* */ -/* Copyright 2007-2013 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * psread.c + * + * Adobe's code for stream handling (body). + * + * Copyright 2007-2013 Adobe Systems Incorporated. + * + * This software, and all works of authorship, whether in source or + * object code form as indicated by the copyright notice(s) included + * herein (collectively, the "Work") is made available, and may only be + * used, modified, and distributed under the FreeType Project License, + * LICENSE.TXT. Additionally, subject to the terms and conditions of the + * FreeType Project License, each contributor to the Work hereby grants + * to any individual or legal entity exercising permissions granted by + * the FreeType Project License and this section (hereafter, "You" or + * "Your") a perpetual, worldwide, non-exclusive, no-charge, + * royalty-free, irrevocable (except as stated in this section) patent + * license to make, have made, use, offer to sell, sell, import, and + * otherwise transfer the Work, where such license applies only to those + * patent claims licensable by such contributor that are necessarily + * infringed by their contribution(s) alone or by combination of their + * contribution(s) with the Work to which such contribution(s) was + * submitted. If You institute patent litigation against any entity + * (including a cross-claim or counterclaim in a lawsuit) alleging that + * the Work or a contribution incorporated within the Work constitutes + * direct or contributory patent infringement, then any patent licenses + * granted to You under this License for that Work shall terminate as of + * the date such litigation is filed. + * + * By using, modifying, or distributing the Work you indicate that you + * have read and understood the terms and conditions of the + * FreeType Project License as well as those provided in this section, + * and you accept them fully. + * + */ #include "psft.h" @@ -105,7 +105,7 @@ FT_LOCAL_DEF( FT_Bool ) cf2_buf_isEnd( CF2_Buffer buf ) { - return (FT_Bool)( buf->ptr >= buf->end ); + return FT_BOOL( buf->ptr >= buf->end ); } diff --git a/sdk/lib/3rdparty/freetype/src/psaux/psread.h b/sdk/lib/3rdparty/freetype/src/psaux/psread.h index 464b29ba743f2..9e55fe0447030 100644 --- a/sdk/lib/3rdparty/freetype/src/psaux/psread.h +++ b/sdk/lib/3rdparty/freetype/src/psaux/psread.h @@ -1,39 +1,39 @@ -/***************************************************************************/ -/* */ -/* psread.h */ -/* */ -/* Adobe's code for stream handling (specification). */ -/* */ -/* Copyright 2007-2013 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * psread.h + * + * Adobe's code for stream handling (specification). + * + * Copyright 2007-2013 Adobe Systems Incorporated. + * + * This software, and all works of authorship, whether in source or + * object code form as indicated by the copyright notice(s) included + * herein (collectively, the "Work") is made available, and may only be + * used, modified, and distributed under the FreeType Project License, + * LICENSE.TXT. Additionally, subject to the terms and conditions of the + * FreeType Project License, each contributor to the Work hereby grants + * to any individual or legal entity exercising permissions granted by + * the FreeType Project License and this section (hereafter, "You" or + * "Your") a perpetual, worldwide, non-exclusive, no-charge, + * royalty-free, irrevocable (except as stated in this section) patent + * license to make, have made, use, offer to sell, sell, import, and + * otherwise transfer the Work, where such license applies only to those + * patent claims licensable by such contributor that are necessarily + * infringed by their contribution(s) alone or by combination of their + * contribution(s) with the Work to which such contribution(s) was + * submitted. If You institute patent litigation against any entity + * (including a cross-claim or counterclaim in a lawsuit) alleging that + * the Work or a contribution incorporated within the Work constitutes + * direct or contributory patent infringement, then any patent licenses + * granted to You under this License for that Work shall terminate as of + * the date such litigation is filed. + * + * By using, modifying, or distributing the Work you indicate that you + * have read and understood the terms and conditions of the + * FreeType Project License as well as those provided in this section, + * and you accept them fully. + * + */ #ifndef PSREAD_H_ diff --git a/sdk/lib/3rdparty/freetype/src/psaux/psstack.c b/sdk/lib/3rdparty/freetype/src/psaux/psstack.c index 69d063349a1b2..6659068001ce6 100644 --- a/sdk/lib/3rdparty/freetype/src/psaux/psstack.c +++ b/sdk/lib/3rdparty/freetype/src/psaux/psstack.c @@ -1,39 +1,39 @@ -/***************************************************************************/ -/* */ -/* psstack.c */ -/* */ -/* Adobe's code for emulating a CFF stack (body). */ -/* */ -/* Copyright 2007-2013 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * psstack.c + * + * Adobe's code for emulating a CFF stack (body). + * + * Copyright 2007-2013 Adobe Systems Incorporated. + * + * This software, and all works of authorship, whether in source or + * object code form as indicated by the copyright notice(s) included + * herein (collectively, the "Work") is made available, and may only be + * used, modified, and distributed under the FreeType Project License, + * LICENSE.TXT. Additionally, subject to the terms and conditions of the + * FreeType Project License, each contributor to the Work hereby grants + * to any individual or legal entity exercising permissions granted by + * the FreeType Project License and this section (hereafter, "You" or + * "Your") a perpetual, worldwide, non-exclusive, no-charge, + * royalty-free, irrevocable (except as stated in this section) patent + * license to make, have made, use, offer to sell, sell, import, and + * otherwise transfer the Work, where such license applies only to those + * patent claims licensable by such contributor that are necessarily + * infringed by their contribution(s) alone or by combination of their + * contribution(s) with the Work to which such contribution(s) was + * submitted. If You institute patent litigation against any entity + * (including a cross-claim or counterclaim in a lawsuit) alleging that + * the Work or a contribution incorporated within the Work constitutes + * direct or contributory patent infringement, then any patent licenses + * granted to You under this License for that Work shall terminate as of + * the date such litigation is filed. + * + * By using, modifying, or distributing the Work you indicate that you + * have read and understood the terms and conditions of the + * FreeType Project License as well as those provided in this section, + * and you accept them fully. + * + */ #include "psft.h" @@ -258,6 +258,9 @@ return; } + /* before C99 it is implementation-defined whether */ + /* the result of `%' is negative if the first operand */ + /* is negative */ if ( shift < 0 ) shift = -( ( -shift ) % count ); else diff --git a/sdk/lib/3rdparty/freetype/src/psaux/psstack.h b/sdk/lib/3rdparty/freetype/src/psaux/psstack.h index 38f7b41c689e3..18cd39bc6a06a 100644 --- a/sdk/lib/3rdparty/freetype/src/psaux/psstack.h +++ b/sdk/lib/3rdparty/freetype/src/psaux/psstack.h @@ -1,39 +1,39 @@ -/***************************************************************************/ -/* */ -/* psstack.h */ -/* */ -/* Adobe's code for emulating a CFF stack (specification). */ -/* */ -/* Copyright 2007-2013 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * psstack.h + * + * Adobe's code for emulating a CFF stack (specification). + * + * Copyright 2007-2013 Adobe Systems Incorporated. + * + * This software, and all works of authorship, whether in source or + * object code form as indicated by the copyright notice(s) included + * herein (collectively, the "Work") is made available, and may only be + * used, modified, and distributed under the FreeType Project License, + * LICENSE.TXT. Additionally, subject to the terms and conditions of the + * FreeType Project License, each contributor to the Work hereby grants + * to any individual or legal entity exercising permissions granted by + * the FreeType Project License and this section (hereafter, "You" or + * "Your") a perpetual, worldwide, non-exclusive, no-charge, + * royalty-free, irrevocable (except as stated in this section) patent + * license to make, have made, use, offer to sell, sell, import, and + * otherwise transfer the Work, where such license applies only to those + * patent claims licensable by such contributor that are necessarily + * infringed by their contribution(s) alone or by combination of their + * contribution(s) with the Work to which such contribution(s) was + * submitted. If You institute patent litigation against any entity + * (including a cross-claim or counterclaim in a lawsuit) alleging that + * the Work or a contribution incorporated within the Work constitutes + * direct or contributory patent infringement, then any patent licenses + * granted to You under this License for that Work shall terminate as of + * the date such litigation is filed. + * + * By using, modifying, or distributing the Work you indicate that you + * have read and understood the terms and conditions of the + * FreeType Project License as well as those provided in this section, + * and you accept them fully. + * + */ #ifndef PSSTACK_H_ diff --git a/sdk/lib/3rdparty/freetype/src/psaux/pstypes.h b/sdk/lib/3rdparty/freetype/src/psaux/pstypes.h index dfbaa3d475b24..041287e8d5e34 100644 --- a/sdk/lib/3rdparty/freetype/src/psaux/pstypes.h +++ b/sdk/lib/3rdparty/freetype/src/psaux/pstypes.h @@ -1,39 +1,39 @@ -/***************************************************************************/ -/* */ -/* pstypes.h */ -/* */ -/* Adobe's code for defining data types (specification only). */ -/* */ -/* Copyright 2011-2013 Adobe Systems Incorporated. */ -/* */ -/* This software, and all works of authorship, whether in source or */ -/* object code form as indicated by the copyright notice(s) included */ -/* herein (collectively, the "Work") is made available, and may only be */ -/* used, modified, and distributed under the FreeType Project License, */ -/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ -/* FreeType Project License, each contributor to the Work hereby grants */ -/* to any individual or legal entity exercising permissions granted by */ -/* the FreeType Project License and this section (hereafter, "You" or */ -/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ -/* royalty-free, irrevocable (except as stated in this section) patent */ -/* license to make, have made, use, offer to sell, sell, import, and */ -/* otherwise transfer the Work, where such license applies only to those */ -/* patent claims licensable by such contributor that are necessarily */ -/* infringed by their contribution(s) alone or by combination of their */ -/* contribution(s) with the Work to which such contribution(s) was */ -/* submitted. If You institute patent litigation against any entity */ -/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ -/* the Work or a contribution incorporated within the Work constitutes */ -/* direct or contributory patent infringement, then any patent licenses */ -/* granted to You under this License for that Work shall terminate as of */ -/* the date such litigation is filed. */ -/* */ -/* By using, modifying, or distributing the Work you indicate that you */ -/* have read and understood the terms and conditions of the */ -/* FreeType Project License as well as those provided in this section, */ -/* and you accept them fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * pstypes.h + * + * Adobe's code for defining data types (specification only). + * + * Copyright 2011-2013 Adobe Systems Incorporated. + * + * This software, and all works of authorship, whether in source or + * object code form as indicated by the copyright notice(s) included + * herein (collectively, the "Work") is made available, and may only be + * used, modified, and distributed under the FreeType Project License, + * LICENSE.TXT. Additionally, subject to the terms and conditions of the + * FreeType Project License, each contributor to the Work hereby grants + * to any individual or legal entity exercising permissions granted by + * the FreeType Project License and this section (hereafter, "You" or + * "Your") a perpetual, worldwide, non-exclusive, no-charge, + * royalty-free, irrevocable (except as stated in this section) patent + * license to make, have made, use, offer to sell, sell, import, and + * otherwise transfer the Work, where such license applies only to those + * patent claims licensable by such contributor that are necessarily + * infringed by their contribution(s) alone or by combination of their + * contribution(s) with the Work to which such contribution(s) was + * submitted. If You institute patent litigation against any entity + * (including a cross-claim or counterclaim in a lawsuit) alleging that + * the Work or a contribution incorporated within the Work constitutes + * direct or contributory patent infringement, then any patent licenses + * granted to You under this License for that Work shall terminate as of + * the date such litigation is filed. + * + * By using, modifying, or distributing the Work you indicate that you + * have read and understood the terms and conditions of the + * FreeType Project License as well as those provided in this section, + * and you accept them fully. + * + */ #ifndef PSTYPES_H_ diff --git a/sdk/lib/3rdparty/freetype/src/psaux/t1cmap.c b/sdk/lib/3rdparty/freetype/src/psaux/t1cmap.c index 112a7892bac4b..d62d2d5c816d2 100644 --- a/sdk/lib/3rdparty/freetype/src/psaux/t1cmap.c +++ b/sdk/lib/3rdparty/freetype/src/psaux/t1cmap.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* t1cmap.c */ -/* */ -/* Type 1 character map support (body). */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * t1cmap.c + * + * Type 1 character map support (body). + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include "t1cmap.h" @@ -305,6 +305,9 @@ FT_UNUSED( pointer ); + if ( !psnames->unicodes_init ) + return FT_THROW( Unimplemented_Feature ); + return psnames->unicodes_init( memory, unicodes, (FT_UInt)face->type1.num_glyphs, diff --git a/sdk/lib/3rdparty/freetype/src/psaux/t1cmap.h b/sdk/lib/3rdparty/freetype/src/psaux/t1cmap.h index 4308e31d2d7fb..d325e7b5a65b8 100644 --- a/sdk/lib/3rdparty/freetype/src/psaux/t1cmap.h +++ b/sdk/lib/3rdparty/freetype/src/psaux/t1cmap.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* t1cmap.h */ -/* */ -/* Type 1 character map support (specification). */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * t1cmap.h + * + * Type 1 character map support (specification). + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef T1CMAP_H_ diff --git a/sdk/lib/3rdparty/freetype/src/psaux/t1decode.c b/sdk/lib/3rdparty/freetype/src/psaux/t1decode.c index 6ad145661f201..c2b3729b5393d 100644 --- a/sdk/lib/3rdparty/freetype/src/psaux/t1decode.c +++ b/sdk/lib/3rdparty/freetype/src/psaux/t1decode.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* t1decode.c */ -/* */ -/* PostScript Type 1 decoding routines (body). */ -/* */ -/* Copyright 2000-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * t1decode.c + * + * PostScript Type 1 decoding routines (body). + * + * Copyright (C) 2000-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -31,14 +31,14 @@ /* ensure proper sign extension */ #define Fix2Int( f ) ( (FT_Int)(FT_Short)( (f) >> 16 ) ) - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_t1decode +#define FT_COMPONENT t1decode typedef enum T1_Operator_ @@ -109,24 +109,26 @@ }; - /*************************************************************************/ - /* */ - /* <Function> */ - /* t1_lookup_glyph_by_stdcharcode_ps */ - /* */ - /* <Description> */ - /* Looks up a given glyph by its StandardEncoding charcode. Used to */ - /* implement the SEAC Type 1 operator in the Adobe engine */ - /* */ - /* <Input> */ - /* face :: The current face object. */ - /* */ - /* charcode :: The character code to look for. */ - /* */ - /* <Return> */ - /* A glyph index in the font face. Returns -1 if the corresponding */ - /* glyph wasn't found. */ - /* */ + /************************************************************************** + * + * @Function: + * t1_lookup_glyph_by_stdcharcode_ps + * + * @Description: + * Looks up a given glyph by its StandardEncoding charcode. Used to + * implement the SEAC Type 1 operator in the Adobe engine + * + * @Input: + * face :: + * The current face object. + * + * charcode :: + * The character code to look for. + * + * @Return: + * A glyph index in the font face. Returns -1 if the corresponding + * glyph wasn't found. + */ FT_LOCAL_DEF( FT_Int ) t1_lookup_glyph_by_stdcharcode_ps( PS_Decoder* decoder, FT_Int charcode ) @@ -159,24 +161,27 @@ #ifdef T1_CONFIG_OPTION_OLD_ENGINE - /*************************************************************************/ - /* */ - /* <Function> */ - /* t1_lookup_glyph_by_stdcharcode */ - /* */ - /* <Description> */ - /* Looks up a given glyph by its StandardEncoding charcode. Used to */ - /* implement the SEAC Type 1 operator. */ - /* */ - /* <Input> */ - /* face :: The current face object. */ - /* */ - /* charcode :: The character code to look for. */ - /* */ - /* <Return> */ - /* A glyph index in the font face. Returns -1 if the corresponding */ - /* glyph wasn't found. */ - /* */ + + /************************************************************************** + * + * @Function: + * t1_lookup_glyph_by_stdcharcode + * + * @Description: + * Looks up a given glyph by its StandardEncoding charcode. Used to + * implement the SEAC Type 1 operator. + * + * @Input: + * face :: + * The current face object. + * + * charcode :: + * The character code to look for. + * + * @Return: + * A glyph index in the font face. Returns -1 if the corresponding + * glyph wasn't found. + */ static FT_Int t1_lookup_glyph_by_stdcharcode( T1_Decoder decoder, FT_Int charcode ) @@ -217,30 +222,36 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* t1operator_seac */ - /* */ - /* <Description> */ - /* Implements the `seac' Type 1 operator for a Type 1 decoder. */ - /* */ - /* <Input> */ - /* decoder :: The current CID decoder. */ - /* */ - /* asb :: The accent's side bearing. */ - /* */ - /* adx :: The horizontal offset of the accent. */ - /* */ - /* ady :: The vertical offset of the accent. */ - /* */ - /* bchar :: The base character's StandardEncoding charcode. */ - /* */ - /* achar :: The accent character's StandardEncoding charcode. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * t1operator_seac + * + * @Description: + * Implements the `seac' Type 1 operator for a Type 1 decoder. + * + * @Input: + * decoder :: + * The current CID decoder. + * + * asb :: + * The accent's side bearing. + * + * adx :: + * The horizontal offset of the accent. + * + * ady :: + * The vertical offset of the accent. + * + * bchar :: + * The base character's StandardEncoding charcode. + * + * achar :: + * The accent character's StandardEncoding charcode. + * + * @Return: + * FreeType error code. 0 means success. + */ static FT_Error t1operator_seac( T1_Decoder decoder, FT_Pos asb, @@ -399,24 +410,27 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* t1_decoder_parse_charstrings */ - /* */ - /* <Description> */ - /* Parses a given Type 1 charstrings program. */ - /* */ - /* <Input> */ - /* decoder :: The current Type 1 decoder. */ - /* */ - /* charstring_base :: The base address of the charstring stream. */ - /* */ - /* charstring_len :: The length in bytes of the charstring stream. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * t1_decoder_parse_charstrings + * + * @Description: + * Parses a given Type 1 charstrings program. + * + * @Input: + * decoder :: + * The current Type 1 decoder. + * + * charstring_base :: + * The base address of the charstring stream. + * + * charstring_len :: + * The length in bytes of the charstring stream. + * + * @Return: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) t1_decoder_parse_charstrings( T1_Decoder decoder, FT_Byte* charstring_base, @@ -466,9 +480,6 @@ if ( decoder->buildchar && decoder->len_buildchar > 0 ) FT_ARRAY_ZERO( decoder->buildchar, decoder->len_buildchar ); - FT_TRACE4(( "\n" - "Start charstring\n" )); - zone->base = charstring_base; limit = zone->limit = charstring_base + charstring_len; ip = zone->cursor = zone->base; @@ -503,11 +514,11 @@ } #endif - /*********************************************************************/ - /* */ - /* Decode operator or operand */ - /* */ - /* */ + /********************************************************************** + * + * Decode operator or operand + * + */ /* first of all, decompress operator or value */ switch ( *ip++ ) @@ -710,11 +721,11 @@ large_int = FALSE; } - /*********************************************************************/ - /* */ - /* Push value on stack, or process operator */ - /* */ - /* */ + /********************************************************************** + * + * Push value on stack, or process operator + * + */ if ( op == op_none ) { if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS ) @@ -752,16 +763,17 @@ subr_no = Fix2Int( top[1] ); arg_cnt = Fix2Int( top[0] ); - /***********************************************************/ - /* */ - /* remove all operands to callothersubr from the stack */ - /* */ - /* for handled othersubrs, where we know the number of */ - /* arguments, we increase the stack by the value of */ - /* known_othersubr_result_cnt */ - /* */ - /* for unhandled othersubrs the following pops adjust the */ - /* stack pointer as necessary */ + /************************************************************ + * + * remove all operands to callothersubr from the stack + * + * for handled othersubrs, where we know the number of + * arguments, we increase the stack by the value of + * known_othersubr_result_cnt + * + * for unhandled othersubrs the following pops adjust the + * stack pointer as necessary + */ if ( arg_cnt > top - decoder->stack ) goto Stack_Underflow; @@ -1223,7 +1235,10 @@ /* the glyph's metrics (lsb + advance width), not load the */ /* rest of it; so exit immediately */ if ( builder->metrics_only ) + { + FT_TRACE4(( "\n" )); return FT_Err_Ok; + } break; @@ -1255,7 +1270,10 @@ /* the glyph's metrics (lsb + advance width), not load the */ /* rest of it; so exit immediately */ if ( builder->metrics_only ) + { + FT_TRACE4(( "\n" )); return FT_Err_Ok; + } break; @@ -1638,26 +1656,31 @@ return FT_THROW( Stack_Underflow ); } -#else /* T1_CONFIG_OPTION_OLD_ENGINE */ - - /*************************************************************************/ - /* */ - /* <Function> */ - /* t1_decoder_parse_metrics */ - /* */ - /* <Description> */ - /* Parses a given Type 1 charstrings program to extract width */ - /* */ - /* <Input> */ - /* decoder :: The current Type 1 decoder. */ - /* */ - /* charstring_base :: The base address of the charstring stream. */ - /* */ - /* charstring_len :: The length in bytes of the charstring stream. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ + +#else /* !T1_CONFIG_OPTION_OLD_ENGINE */ + + + /************************************************************************** + * + * @Function: + * t1_decoder_parse_metrics + * + * @Description: + * Parses a given Type 1 charstrings program to extract width + * + * @Input: + * decoder :: + * The current Type 1 decoder. + * + * charstring_base :: + * The base address of the charstring stream. + * + * charstring_len :: + * The length in bytes of the charstring stream. + * + * @Return: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) t1_decoder_parse_metrics( T1_Decoder decoder, FT_Byte* charstring_base, @@ -1680,9 +1703,6 @@ builder->parse_state = T1_Parse_Start; - FT_TRACE4(( "\n" - "Start charstring: get width\n" )); - zone->base = charstring_base; limit = zone->limit = charstring_base + charstring_len; ip = zone->cursor = zone->base; @@ -1703,11 +1723,11 @@ } #endif - /*********************************************************************/ - /* */ - /* Decode operator or operand */ - /* */ - /* */ + /********************************************************************** + * + * Decode operator or operand + * + */ /* first of all, decompress operator or value */ switch ( *ip++ ) @@ -1817,11 +1837,11 @@ } } - /*********************************************************************/ - /* */ - /* Push value on stack, or process operator */ - /* */ - /* */ + /********************************************************************** + * + * Push value on stack, or process operator + * + */ if ( op == op_none ) { if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS ) @@ -1875,6 +1895,7 @@ /* we only want to compute the glyph's metrics */ /* (lsb + advance width), not load the rest of */ /* it; so exit immediately */ + FT_TRACE4(( "\n" )); return FT_Err_Ok; case op_sbw: @@ -1893,6 +1914,7 @@ /* we only want to compute the glyph's metrics */ /* (lsb + advance width), not load the rest of */ /* it; so exit immediately */ + FT_TRACE4(( "\n" )); return FT_Err_Ok; default: @@ -1917,7 +1939,8 @@ Stack_Underflow: return FT_THROW( Stack_Underflow ); } -#endif /* T1_CONFIG_OPTION_OLD_ENGINE */ + +#endif /* !T1_CONFIG_OPTION_OLD_ENGINE */ /* initialize T1 decoder */ @@ -1934,7 +1957,7 @@ { FT_ZERO( decoder ); - /* retrieve PSNames interface from list of current modules */ + /* retrieve `psnames' interface from list of current modules */ { FT_Service_PsCMaps psnames; diff --git a/sdk/lib/3rdparty/freetype/src/psaux/t1decode.h b/sdk/lib/3rdparty/freetype/src/psaux/t1decode.h index 1d9718d678eb9..1b5d6263d3706 100644 --- a/sdk/lib/3rdparty/freetype/src/psaux/t1decode.h +++ b/sdk/lib/3rdparty/freetype/src/psaux/t1decode.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* t1decode.h */ -/* */ -/* PostScript Type 1 decoding routines (specification). */ -/* */ -/* Copyright 2000-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * t1decode.h + * + * PostScript Type 1 decoding routines (specification). + * + * Copyright (C) 2000-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef T1DECODE_H_ diff --git a/sdk/lib/3rdparty/freetype/src/pshinter/pshalgo.c b/sdk/lib/3rdparty/freetype/src/pshinter/pshalgo.c index b98077c62efa4..0c5ae6269993e 100644 --- a/sdk/lib/3rdparty/freetype/src/pshinter/pshalgo.c +++ b/sdk/lib/3rdparty/freetype/src/pshinter/pshalgo.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* pshalgo.c */ -/* */ -/* PostScript hinting algorithm (body). */ -/* */ -/* Copyright 2001-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used */ -/* modified and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * pshalgo.c + * + * PostScript hinting algorithm (body). + * + * Copyright (C) 2001-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -26,7 +26,7 @@ #undef FT_COMPONENT -#define FT_COMPONENT trace_pshalgo +#define FT_COMPONENT pshalgo #ifdef DEBUG_HINTER @@ -53,8 +53,8 @@ psh_hint_overlap( PSH_Hint hint1, PSH_Hint hint2 ) { - return hint1->org_pos + hint1->org_len >= hint2->org_pos && - hint2->org_pos + hint2->org_len >= hint1->org_pos; + return ADD_INT( hint1->org_pos, hint1->org_len ) >= hint2->org_pos && + ADD_INT( hint2->org_pos, hint2->org_len ) >= hint1->org_pos; } @@ -479,7 +479,7 @@ if ( dimension == 1 ) psh_blues_snap_stem( &globals->blues, - hint->org_pos + hint->org_len, + ADD_INT( hint->org_pos, hint->org_len ), hint->org_pos, &align ); @@ -658,8 +658,8 @@ #if 0 /* not used for now, experimental */ /* - * A variant to perform "light" hinting (i.e. FT_RENDER_MODE_LIGHT) - * of stems + * A variant to perform "light" hinting (i.e. FT_RENDER_MODE_LIGHT) + * of stems */ static void psh_hint_align_light( PSH_Hint hint, @@ -703,7 +703,7 @@ if ( dimension == 1 ) psh_blues_snap_stem( &globals->blues, - hint->org_pos + hint->org_len, + ADD_INT( hint->org_pos, hint->org_len ), hint->org_pos, &align ); @@ -1538,8 +1538,8 @@ PSH_Hint hint = sort[nn]; - if ( org_u >= hint->org_pos && - org_u <= hint->org_pos + hint->org_len ) + if ( org_u >= hint->org_pos && + org_u <= ADD_INT( hint->org_pos, hint->org_len ) ) { point->hint = hint; break; diff --git a/sdk/lib/3rdparty/freetype/src/pshinter/pshalgo.h b/sdk/lib/3rdparty/freetype/src/pshinter/pshalgo.h index c50683fbec6a6..6859e95cd2de5 100644 --- a/sdk/lib/3rdparty/freetype/src/pshinter/pshalgo.h +++ b/sdk/lib/3rdparty/freetype/src/pshinter/pshalgo.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* pshalgo.h */ -/* */ -/* PostScript hinting algorithm (specification). */ -/* */ -/* Copyright 2001-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * pshalgo.h + * + * PostScript hinting algorithm (specification). + * + * Copyright (C) 2001-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef PSHALGO_H_ diff --git a/sdk/lib/3rdparty/freetype/src/pshinter/pshglob.c b/sdk/lib/3rdparty/freetype/src/pshinter/pshglob.c index 29f328d0e6d69..b021e6e42a326 100644 --- a/sdk/lib/3rdparty/freetype/src/pshinter/pshglob.c +++ b/sdk/lib/3rdparty/freetype/src/pshinter/pshglob.c @@ -1,25 +1,26 @@ -/***************************************************************************/ -/* */ -/* pshglob.c */ -/* */ -/* PostScript hinter global hinting management (body). */ -/* Inspired by the new auto-hinter module. */ -/* */ -/* Copyright 2001-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used */ -/* modified and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * pshglob.c + * + * PostScript hinter global hinting management (body). + * Inspired by the new auto-hinter module. + * + * Copyright (C) 2001-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> #include FT_FREETYPE_H #include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_CALC_H #include "pshglob.h" #ifdef DEBUG_HINTER @@ -227,8 +228,8 @@ } - /* Re-read blue zones from the original fonts and store them into out */ - /* private structure. This function re-orders, sanitizes and */ + /* Re-read blue zones from the original fonts and store them into our */ + /* private structure. This function re-orders, sanitizes, and */ /* fuzz-expands the zones as well. */ static void psh_blues_set_zones( PSH_Blues target, @@ -568,7 +569,7 @@ for ( ; count > 0; count--, zone++ ) { - delta = stem_top - zone->org_bottom; + delta = SUB_LONG( stem_top, zone->org_bottom ); if ( delta < -blues->blue_fuzz ) break; @@ -590,7 +591,7 @@ for ( ; count > 0; count--, zone-- ) { - delta = zone->org_top - stem_bot; + delta = SUB_LONG( zone->org_top, stem_bot ); if ( delta < -blues->blue_fuzz ) break; diff --git a/sdk/lib/3rdparty/freetype/src/pshinter/pshglob.h b/sdk/lib/3rdparty/freetype/src/pshinter/pshglob.h index cf80bf40e64b5..0049d4c0bc888 100644 --- a/sdk/lib/3rdparty/freetype/src/pshinter/pshglob.h +++ b/sdk/lib/3rdparty/freetype/src/pshinter/pshglob.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* pshglob.h */ -/* */ -/* PostScript hinter global hinting management. */ -/* */ -/* Copyright 2001-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * pshglob.h + * + * PostScript hinter global hinting management. + * + * Copyright (C) 2001-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef PSHGLOB_H_ @@ -36,27 +36,27 @@ FT_BEGIN_HEADER /*************************************************************************/ - /*************************************************************************/ - /* */ - /* @constant: */ - /* PS_GLOBALS_MAX_BLUE_ZONES */ - /* */ - /* @description: */ - /* The maximum number of blue zones in a font global hints structure. */ - /* See @PS_Globals_BluesRec. */ - /* */ + /************************************************************************** + * + * @constant: + * PS_GLOBALS_MAX_BLUE_ZONES + * + * @description: + * The maximum number of blue zones in a font global hints structure. + * See @PS_Globals_BluesRec. + */ #define PS_GLOBALS_MAX_BLUE_ZONES 16 - /*************************************************************************/ - /* */ - /* @constant: */ - /* PS_GLOBALS_MAX_STD_WIDTHS */ - /* */ - /* @description: */ - /* The maximum number of standard and snap widths in either the */ - /* horizontal or vertical direction. See @PS_Globals_WidthsRec. */ - /* */ + /************************************************************************** + * + * @constant: + * PS_GLOBALS_MAX_STD_WIDTHS + * + * @description: + * The maximum number of standard and snap widths in either the + * horizontal or vertical direction. See @PS_Globals_WidthsRec. + */ #define PS_GLOBALS_MAX_STD_WIDTHS 16 diff --git a/sdk/lib/3rdparty/freetype/src/pshinter/pshinter.c b/sdk/lib/3rdparty/freetype/src/pshinter/pshinter.c index 0eedac452d270..16c3a0a117740 100644 --- a/sdk/lib/3rdparty/freetype/src/pshinter/pshinter.c +++ b/sdk/lib/3rdparty/freetype/src/pshinter/pshinter.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* pshinter.c */ -/* */ -/* FreeType PostScript Hinting module */ -/* */ -/* Copyright 2001-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * pshinter.c + * + * FreeType PostScript Hinting module + * + * Copyright (C) 2001-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #define FT_MAKE_OPTION_SINGLE_OBJECT @@ -22,7 +22,6 @@ #include "pshalgo.c" #include "pshglob.c" #include "pshmod.c" -#include "pshpic.c" #include "pshrec.c" diff --git a/sdk/lib/3rdparty/freetype/src/pshinter/pshmod.c b/sdk/lib/3rdparty/freetype/src/pshinter/pshmod.c index 0b8f6f99b83d7..2d36ea2a6a696 100644 --- a/sdk/lib/3rdparty/freetype/src/pshinter/pshmod.c +++ b/sdk/lib/3rdparty/freetype/src/pshinter/pshmod.c @@ -1,26 +1,25 @@ -/***************************************************************************/ -/* */ -/* pshmod.c */ -/* */ -/* FreeType PostScript hinter module implementation (body). */ -/* */ -/* Copyright 2001-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * pshmod.c + * + * FreeType PostScript hinter module implementation (body). + * + * Copyright (C) 2001-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> #include FT_INTERNAL_OBJECTS_H #include "pshrec.h" #include "pshalgo.h" -#include "pshpic.h" /* the Postscript Hinter module structure */ @@ -111,7 +110,7 @@ 0x10000L, 0x20000L, - &PSHINTER_INTERFACE_GET, /* module-specific interface */ + &pshinter_interface, /* module-specific interface */ (FT_Module_Constructor)ps_hinter_init, /* module_init */ (FT_Module_Destructor) ps_hinter_done, /* module_done */ diff --git a/sdk/lib/3rdparty/freetype/src/pshinter/pshmod.h b/sdk/lib/3rdparty/freetype/src/pshinter/pshmod.h index 556de2fbc0e76..ea8771308af87 100644 --- a/sdk/lib/3rdparty/freetype/src/pshinter/pshmod.h +++ b/sdk/lib/3rdparty/freetype/src/pshinter/pshmod.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* pshmod.h */ -/* */ -/* PostScript hinter module interface (specification). */ -/* */ -/* Copyright 2001-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * pshmod.h + * + * PostScript hinter module interface (specification). + * + * Copyright (C) 2001-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef PSHMOD_H_ diff --git a/sdk/lib/3rdparty/freetype/src/pshinter/pshnterr.h b/sdk/lib/3rdparty/freetype/src/pshinter/pshnterr.h index b9d02d2956a7b..fb9dbca2b1f3a 100644 --- a/sdk/lib/3rdparty/freetype/src/pshinter/pshnterr.h +++ b/sdk/lib/3rdparty/freetype/src/pshinter/pshnterr.h @@ -1,26 +1,26 @@ -/***************************************************************************/ -/* */ -/* pshnterr.h */ -/* */ -/* PS Hinter error codes (specification only). */ -/* */ -/* Copyright 2003-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to define the PSHinter error enumeration constants. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * pshnterr.h + * + * PS Hinter error codes (specification only). + * + * Copyright (C) 2003-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /************************************************************************** + * + * This file is used to define the PSHinter error enumeration constants. + * + */ #ifndef PSHNTERR_H_ #define PSHNTERR_H_ diff --git a/sdk/lib/3rdparty/freetype/src/pshinter/pshpic.c b/sdk/lib/3rdparty/freetype/src/pshinter/pshpic.c deleted file mode 100644 index 465ad31885b95..0000000000000 --- a/sdk/lib/3rdparty/freetype/src/pshinter/pshpic.c +++ /dev/null @@ -1,76 +0,0 @@ -/***************************************************************************/ -/* */ -/* pshpic.c */ -/* */ -/* The FreeType position independent code services for pshinter module. */ -/* */ -/* Copyright 2009-2018 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_FREETYPE_H -#include FT_INTERNAL_OBJECTS_H -#include "pshpic.h" -#include "pshnterr.h" - - -#ifdef FT_CONFIG_OPTION_PIC - - /* forward declaration of PIC init functions from pshmod.c */ - void - FT_Init_Class_pshinter_interface( FT_Library library, - PSHinter_Interface* clazz ); - - void - pshinter_module_class_pic_free( FT_Library library ) - { - FT_PIC_Container* pic_container = &library->pic_container; - FT_Memory memory = library->memory; - - - if ( pic_container->pshinter ) - { - FT_FREE( pic_container->pshinter ); - pic_container->pshinter = NULL; - } - } - - - FT_Error - pshinter_module_class_pic_init( FT_Library library ) - { - FT_PIC_Container* pic_container = &library->pic_container; - FT_Error error = FT_Err_Ok; - PSHinterPIC* container = NULL; - FT_Memory memory = library->memory; - - - /* allocate pointer, clear and set global container pointer */ - if ( FT_ALLOC( container, sizeof ( *container ) ) ) - return error; - FT_MEM_SET( container, 0, sizeof ( *container ) ); - pic_container->pshinter = container; - - /* add call to initialization function when you add new scripts */ - FT_Init_Class_pshinter_interface( - library, &container->pshinter_interface ); - - if ( error ) - pshinter_module_class_pic_free( library ); - - return error; - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - -/* END */ diff --git a/sdk/lib/3rdparty/freetype/src/pshinter/pshpic.h b/sdk/lib/3rdparty/freetype/src/pshinter/pshpic.h deleted file mode 100644 index 4469ba87c8083..0000000000000 --- a/sdk/lib/3rdparty/freetype/src/pshinter/pshpic.h +++ /dev/null @@ -1,63 +0,0 @@ -/***************************************************************************/ -/* */ -/* pshpic.h */ -/* */ -/* The FreeType position independent code services for pshinter module. */ -/* */ -/* Copyright 2009-2018 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#ifndef PSHPIC_H_ -#define PSHPIC_H_ - - -#include FT_INTERNAL_PIC_H - - -#ifndef FT_CONFIG_OPTION_PIC - -#define PSHINTER_INTERFACE_GET pshinter_interface - -#else /* FT_CONFIG_OPTION_PIC */ - -#include FT_INTERNAL_POSTSCRIPT_HINTS_H - -FT_BEGIN_HEADER - - typedef struct PSHinterPIC_ - { - PSHinter_Interface pshinter_interface; - - } PSHinterPIC; - - -#define GET_PIC( lib ) ( (PSHinterPIC*)( (lib)->pic_container.pshinter ) ) - -#define PSHINTER_INTERFACE_GET ( GET_PIC( library )->pshinter_interface ) - - /* see pshpic.c for the implementation */ - void - pshinter_module_class_pic_free( FT_Library library ); - - FT_Error - pshinter_module_class_pic_init( FT_Library library ); - -FT_END_HEADER - -#endif /* FT_CONFIG_OPTION_PIC */ - - /* */ - -#endif /* PSHPIC_H_ */ - - -/* END */ diff --git a/sdk/lib/3rdparty/freetype/src/pshinter/pshrec.c b/sdk/lib/3rdparty/freetype/src/pshinter/pshrec.c index 6648d13d60fd1..9dd09efe4ca5b 100644 --- a/sdk/lib/3rdparty/freetype/src/pshinter/pshrec.c +++ b/sdk/lib/3rdparty/freetype/src/pshinter/pshrec.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* pshrec.c */ -/* */ -/* FreeType PostScript hints recorder (body). */ -/* */ -/* Copyright 2001-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * pshrec.c + * + * FreeType PostScript hints recorder (body). + * + * Copyright (C) 2001-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -28,7 +28,7 @@ #include "pshnterr.h" #undef FT_COMPONENT -#define FT_COMPONENT trace_pshrec +#define FT_COMPONENT pshrec #ifdef DEBUG_HINTER PS_Hints ps_debug_hints = NULL; @@ -666,7 +666,7 @@ if ( len == -21 ) { flags |= PS_HINT_FLAG_BOTTOM; - pos += len; + pos = ADD_INT( pos, len ); } len = 0; } @@ -1187,7 +1187,7 @@ /* compute integer stem positions in font units */ for ( n = 0; n < count * 2; n++ ) { - y += coords[n]; + y = ADD_LONG( y, coords[n] ); stems[n] = FIXED_TO_INT( y ); } diff --git a/sdk/lib/3rdparty/freetype/src/pshinter/pshrec.h b/sdk/lib/3rdparty/freetype/src/pshinter/pshrec.h index 7e3dfe0d5380e..02cc2102ec32f 100644 --- a/sdk/lib/3rdparty/freetype/src/pshinter/pshrec.h +++ b/sdk/lib/3rdparty/freetype/src/pshinter/pshrec.h @@ -1,31 +1,31 @@ -/***************************************************************************/ -/* */ -/* pshrec.h */ -/* */ -/* Postscript (Type1/Type2) hints recorder (specification). */ -/* */ -/* Copyright 2001-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /**************************************************************************/ - /* */ - /* The functions defined here are called from the Type 1, CID and CFF */ - /* font drivers to record the hints of a given character/glyph. */ - /* */ - /* The hints are recorded in a unified format, and are later processed */ - /* by the `optimizer' and `fitter' to adjust the outlines to the pixel */ - /* grid. */ - /* */ - /**************************************************************************/ +/**************************************************************************** + * + * pshrec.h + * + * Postscript (Type1/Type2) hints recorder (specification). + * + * Copyright (C) 2001-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /*************************************************************************** + * + * The functions defined here are called from the Type 1, CID and CFF + * font drivers to record the hints of a given character/glyph. + * + * The hints are recorded in a unified format, and are later processed + * by the `optimizer' and `fitter' to adjust the outlines to the pixel + * grid. + * + */ #ifndef PSHREC_H_ diff --git a/sdk/lib/3rdparty/freetype/src/psnames/psmodule.c b/sdk/lib/3rdparty/freetype/src/psnames/psmodule.c index 8929ebe751dce..0ec440e67b4c6 100644 --- a/sdk/lib/3rdparty/freetype/src/psnames/psmodule.c +++ b/sdk/lib/3rdparty/freetype/src/psnames/psmodule.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* psmodule.c */ -/* */ -/* PSNames module implementation (body). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * psmodule.c + * + * psnames module implementation (body). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -24,16 +24,16 @@ #include "psmodule.h" /* - * The file `pstables.h' with its arrays and its function - * `ft_get_adobe_glyph_index' is useful for other projects also (for - * example, `pdfium' is using it). However, if used as a C++ header, - * including it in two different source files makes it necessary to use - * `extern const' for the declaration of its arrays, otherwise the data - * would be duplicated as mandated by the C++ standard. + * The file `pstables.h' with its arrays and its function + * `ft_get_adobe_glyph_index' is useful for other projects also (for + * example, `pdfium' is using it). However, if used as a C++ header, + * including it in two different source files makes it necessary to use + * `extern const' for the declaration of its arrays, otherwise the data + * would be duplicated as mandated by the C++ standard. * - * For this reason, we use `DEFINE_PS_TABLES' to guard the function - * definitions, and `DEFINE_PS_TABLES_DATA' to provide both proper array - * declarations and definitions. + * For this reason, we use `DEFINE_PS_TABLES' to guard the function + * definitions, and `DEFINE_PS_TABLES_DATA' to provide both proper array + * declarations and definitions. */ #include "pstables.h" #define DEFINE_PS_TABLES @@ -41,7 +41,6 @@ #include "pstables.h" #include "psnamerr.h" -#include "pspic.h" #ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES @@ -393,7 +392,9 @@ /* Reallocate if the number of used entries is much smaller. */ if ( count < num_glyphs / 2 ) { - (void)FT_RENEW_ARRAY( table->maps, num_glyphs, count ); + (void)FT_RENEW_ARRAY( table->maps, + num_glyphs + EXTRA_GLYPH_LIST_SIZE, + count ); error = FT_Err_Ok; } @@ -577,28 +578,16 @@ FT_DEFINE_SERVICEDESCREC1( pscmaps_services, - FT_SERVICE_ID_POSTSCRIPT_CMAPS, &PSCMAPS_INTERFACE_GET ) + FT_SERVICE_ID_POSTSCRIPT_CMAPS, &pscmaps_interface ) static FT_Pointer psnames_get_service( FT_Module module, const char* service_id ) { - /* PSCMAPS_SERVICES_GET dereferences `library' in PIC mode */ -#ifdef FT_CONFIG_OPTION_PIC - FT_Library library; - - - if ( !module ) - return NULL; - library = module->library; - if ( !library ) - return NULL; -#else FT_UNUSED( module ); -#endif - return ft_service_list_lookup( PSCMAPS_SERVICES_GET, service_id ); + return ft_service_list_lookup( pscmaps_services, service_id ); } #endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */ @@ -621,7 +610,7 @@ 0x20000L, /* driver requires FreeType 2 or above */ PUT_PS_NAMES_SERVICE( - (void*)&PSCMAPS_INTERFACE_GET ), /* module specific interface */ + (void*)&pscmaps_interface ), /* module specific interface */ (FT_Module_Constructor)NULL, /* module_init */ (FT_Module_Destructor) NULL, /* module_done */ diff --git a/sdk/lib/3rdparty/freetype/src/psnames/psmodule.h b/sdk/lib/3rdparty/freetype/src/psnames/psmodule.h index 3e94f8b437e43..0df9a7d889c75 100644 --- a/sdk/lib/3rdparty/freetype/src/psnames/psmodule.h +++ b/sdk/lib/3rdparty/freetype/src/psnames/psmodule.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* psmodule.h */ -/* */ -/* High-level PSNames module interface (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * psmodule.h + * + * High-level psnames module interface (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef PSMODULE_H_ diff --git a/sdk/lib/3rdparty/freetype/src/psnames/psnamerr.h b/sdk/lib/3rdparty/freetype/src/psnames/psnamerr.h index 14eb76c99cfd7..67ab1765d386f 100644 --- a/sdk/lib/3rdparty/freetype/src/psnames/psnamerr.h +++ b/sdk/lib/3rdparty/freetype/src/psnames/psnamerr.h @@ -1,27 +1,27 @@ -/***************************************************************************/ -/* */ -/* psnamerr.h */ -/* */ -/* PS names module error codes (specification only). */ -/* */ -/* Copyright 2001-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to define the PS names module error enumeration */ - /* constants. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * psnamerr.h + * + * PS names module error codes (specification only). + * + * Copyright (C) 2001-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /************************************************************************** + * + * This file is used to define the PS names module error enumeration + * constants. + * + */ #ifndef PSNAMERR_H_ #define PSNAMERR_H_ diff --git a/sdk/lib/3rdparty/freetype/src/psnames/psnames.c b/sdk/lib/3rdparty/freetype/src/psnames/psnames.c index febb80d594ee5..4722f9883172f 100644 --- a/sdk/lib/3rdparty/freetype/src/psnames/psnames.c +++ b/sdk/lib/3rdparty/freetype/src/psnames/psnames.c @@ -1,26 +1,25 @@ -/***************************************************************************/ -/* */ -/* psnames.c */ -/* */ -/* FreeType PSNames module component (body only). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * psnames.c + * + * FreeType psnames module component (body only). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #define FT_MAKE_OPTION_SINGLE_OBJECT #include <ft2build.h> #include "psmodule.c" -#include "pspic.c" /* END */ diff --git a/sdk/lib/3rdparty/freetype/src/psnames/pspic.c b/sdk/lib/3rdparty/freetype/src/psnames/pspic.c deleted file mode 100644 index 85a06f36037e3..0000000000000 --- a/sdk/lib/3rdparty/freetype/src/psnames/pspic.c +++ /dev/null @@ -1,97 +0,0 @@ -/***************************************************************************/ -/* */ -/* pspic.c */ -/* */ -/* The FreeType position independent code services for psnames module. */ -/* */ -/* Copyright 2009-2018 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_FREETYPE_H -#include FT_INTERNAL_OBJECTS_H -#include "pspic.h" -#include "psnamerr.h" - - -#ifdef FT_CONFIG_OPTION_PIC - - /* forward declaration of PIC init functions from psmodule.c */ - FT_Error - FT_Create_Class_pscmaps_services( FT_Library library, - FT_ServiceDescRec** output_class ); - void - FT_Destroy_Class_pscmaps_services( FT_Library library, - FT_ServiceDescRec* clazz ); - - void - FT_Init_Class_pscmaps_interface( FT_Library library, - FT_Service_PsCMapsRec* clazz ); - - - void - psnames_module_class_pic_free( FT_Library library ) - { - FT_PIC_Container* pic_container = &library->pic_container; - FT_Memory memory = library->memory; - - - if ( pic_container->psnames ) - { - PSModulePIC* container = (PSModulePIC*)pic_container->psnames; - - - if ( container->pscmaps_services ) - FT_Destroy_Class_pscmaps_services( library, - container->pscmaps_services ); - container->pscmaps_services = NULL; - FT_FREE( container ); - pic_container->psnames = NULL; - } - } - - - FT_Error - psnames_module_class_pic_init( FT_Library library ) - { - FT_PIC_Container* pic_container = &library->pic_container; - FT_Error error = FT_Err_Ok; - PSModulePIC* container = NULL; - FT_Memory memory = library->memory; - - - /* allocate pointer, clear and set global container pointer */ - if ( FT_ALLOC( container, sizeof ( *container ) ) ) - return error; - FT_MEM_SET( container, 0, sizeof ( *container ) ); - pic_container->psnames = container; - - /* initialize pointer table - */ - /* this is how the module usually expects this data */ - error = FT_Create_Class_pscmaps_services( - library, &container->pscmaps_services ); - if ( error ) - goto Exit; - FT_Init_Class_pscmaps_interface( library, - &container->pscmaps_interface ); - - Exit: - if ( error ) - psnames_module_class_pic_free( library ); - return error; - } - - -#endif /* FT_CONFIG_OPTION_PIC */ - - -/* END */ diff --git a/sdk/lib/3rdparty/freetype/src/psnames/pspic.h b/sdk/lib/3rdparty/freetype/src/psnames/pspic.h deleted file mode 100644 index 889780cc03283..0000000000000 --- a/sdk/lib/3rdparty/freetype/src/psnames/pspic.h +++ /dev/null @@ -1,68 +0,0 @@ -/***************************************************************************/ -/* */ -/* pspic.h */ -/* */ -/* The FreeType position independent code services for psnames module. */ -/* */ -/* Copyright 2009-2018 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#ifndef PSPIC_H_ -#define PSPIC_H_ - - -#include FT_INTERNAL_PIC_H - - -#ifndef FT_CONFIG_OPTION_PIC - -#define PSCMAPS_SERVICES_GET pscmaps_services -#define PSCMAPS_INTERFACE_GET pscmaps_interface - -#else /* FT_CONFIG_OPTION_PIC */ - -#include FT_SERVICE_POSTSCRIPT_CMAPS_H - - -FT_BEGIN_HEADER - - typedef struct PSModulePIC_ - { - FT_ServiceDescRec* pscmaps_services; - FT_Service_PsCMapsRec pscmaps_interface; - - } PSModulePIC; - - -#define GET_PIC( lib ) \ - ( (PSModulePIC*)((lib)->pic_container.psnames) ) -#define PSCMAPS_SERVICES_GET ( GET_PIC( library )->pscmaps_services ) -#define PSCMAPS_INTERFACE_GET ( GET_PIC( library )->pscmaps_interface ) - - - /* see pspic.c for the implementation */ - void - psnames_module_class_pic_free( FT_Library library ); - - FT_Error - psnames_module_class_pic_init( FT_Library library ); - -FT_END_HEADER - -#endif /* FT_CONFIG_OPTION_PIC */ - - /* */ - -#endif /* PSPIC_H_ */ - - -/* END */ diff --git a/sdk/lib/3rdparty/freetype/src/psnames/pstables.h b/sdk/lib/3rdparty/freetype/src/psnames/pstables.h index 79545ee039657..c0139bbc601d9 100644 --- a/sdk/lib/3rdparty/freetype/src/psnames/pstables.h +++ b/sdk/lib/3rdparty/freetype/src/psnames/pstables.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* pstables.h */ -/* */ -/* PostScript glyph names. */ -/* */ -/* Copyright 2005-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * pstables.h + * + * PostScript glyph names. + * + * Copyright (C) 2005-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ /* This file has been generated automatically -- do not edit! */ @@ -609,12 +609,12 @@ /* - * This table is a compressed version of the Adobe Glyph List (AGL), - * optimized for efficient searching. It has been generated by the - * `glnames.py' python script located in the `src/tools' directory. + * This table is a compressed version of the Adobe Glyph List (AGL), + * optimized for efficient searching. It has been generated by the + * `glnames.py' python script located in the `src/tools' directory. * - * The lookup function to get the Unicode value for a given string - * is defined below the table. + * The lookup function to get the Unicode value for a given string + * is defined below the table. */ #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST @@ -4137,7 +4137,7 @@ #ifdef DEFINE_PS_TABLES /* - * This function searches the compressed table efficiently. + * This function searches the compressed table efficiently. */ static unsigned long ft_get_adobe_glyph_index( const char* name, diff --git a/sdk/lib/3rdparty/freetype/src/raster/ftmisc.h b/sdk/lib/3rdparty/freetype/src/raster/ftmisc.h index 7e401190711cd..a246569e3befe 100644 --- a/sdk/lib/3rdparty/freetype/src/raster/ftmisc.h +++ b/sdk/lib/3rdparty/freetype/src/raster/ftmisc.h @@ -1,28 +1,28 @@ -/***************************************************************************/ -/* */ -/* ftmisc.h */ -/* */ -/* Miscellaneous macros for stand-alone rasterizer (specification */ -/* only). */ -/* */ -/* Copyright 2005-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used */ -/* modified and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /***************************************************/ - /* */ - /* This file is *not* portable! You have to adapt */ - /* its definitions to your platform. */ - /* */ - /***************************************************/ +/**************************************************************************** + * + * ftmisc.h + * + * Miscellaneous macros for stand-alone rasterizer (specification + * only). + * + * Copyright (C) 2005-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /**************************************************** + * + * This file is *not* portable! You have to adapt + * its definitions to your platform. + * + */ #ifndef FTMISC_H_ #define FTMISC_H_ diff --git a/sdk/lib/3rdparty/freetype/src/raster/ftraster.c b/sdk/lib/3rdparty/freetype/src/raster/ftraster.c index 40d5d9d5a725d..6287ddccf16e1 100644 --- a/sdk/lib/3rdparty/freetype/src/raster/ftraster.c +++ b/sdk/lib/3rdparty/freetype/src/raster/ftraster.c @@ -1,51 +1,51 @@ -/***************************************************************************/ -/* */ -/* ftraster.c */ -/* */ -/* The FreeType glyph rasterizer (body). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - /*************************************************************************/ - /* */ - /* This file can be compiled without the rest of the FreeType engine, by */ - /* defining the STANDALONE_ macro when compiling it. You also need to */ - /* put the files `ftimage.h' and `ftmisc.h' into the $(incdir) */ - /* directory. Typically, you should do something like */ - /* */ - /* - copy `src/raster/ftraster.c' (this file) to your current directory */ - /* */ - /* - copy `include/freetype/ftimage.h' and `src/raster/ftmisc.h' to your */ - /* current directory */ - /* */ - /* - compile `ftraster' with the STANDALONE_ macro defined, as in */ - /* */ - /* cc -c -DSTANDALONE_ ftraster.c */ - /* */ - /* The renderer can be initialized with a call to */ - /* `ft_standard_raster.raster_new'; a bitmap can be generated */ - /* with a call to `ft_standard_raster.raster_render'. */ - /* */ - /* See the comments and documentation in the file `ftimage.h' for more */ - /* details on how the raster works. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This is a rewrite of the FreeType 1.x scan-line converter */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * ftraster.c + * + * The FreeType glyph rasterizer (body). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + /************************************************************************** + * + * This file can be compiled without the rest of the FreeType engine, by + * defining the STANDALONE_ macro when compiling it. You also need to + * put the files `ftimage.h' and `ftmisc.h' into the $(incdir) + * directory. Typically, you should do something like + * + * - copy `src/raster/ftraster.c' (this file) to your current directory + * + * - copy `include/freetype/ftimage.h' and `src/raster/ftmisc.h' to your + * current directory + * + * - compile `ftraster' with the STANDALONE_ macro defined, as in + * + * cc -c -DSTANDALONE_ ftraster.c + * + * The renderer can be initialized with a call to + * `ft_standard_raster.raster_new'; a bitmap can be generated + * with a call to `ft_standard_raster.raster_render'. + * + * See the comments and documentation in the file `ftimage.h' for more + * details on how the raster works. + * + */ + + + /************************************************************************** + * + * This is a rewrite of the FreeType 1.x scan-line converter + * + */ #ifdef STANDALONE_ @@ -65,82 +65,81 @@ #include <ft2build.h> #include "ftraster.h" #include FT_INTERNAL_CALC_H /* for FT_MulDiv and FT_MulDiv_No_Round */ - -#include "rastpic.h" +#include FT_OUTLINE_H /* for FT_Outline_Get_CBox */ #endif /* !STANDALONE_ */ - /*************************************************************************/ - /* */ - /* A simple technical note on how the raster works */ - /* ----------------------------------------------- */ - /* */ - /* Converting an outline into a bitmap is achieved in several steps: */ - /* */ - /* 1 - Decomposing the outline into successive `profiles'. Each */ - /* profile is simply an array of scanline intersections on a given */ - /* dimension. A profile's main attributes are */ - /* */ - /* o its scanline position boundaries, i.e. `Ymin' and `Ymax' */ - /* */ - /* o an array of intersection coordinates for each scanline */ - /* between `Ymin' and `Ymax' */ - /* */ - /* o a direction, indicating whether it was built going `up' or */ - /* `down', as this is very important for filling rules */ - /* */ - /* o its drop-out mode */ - /* */ - /* 2 - Sweeping the target map's scanlines in order to compute segment */ - /* `spans' which are then filled. Additionally, this pass */ - /* performs drop-out control. */ - /* */ - /* The outline data is parsed during step 1 only. The profiles are */ - /* built from the bottom of the render pool, used as a stack. The */ - /* following graphics shows the profile list under construction: */ - /* */ - /* __________________________________________________________ _ _ */ - /* | | | | | */ - /* | profile | coordinates for | profile | coordinates for |--> */ - /* | 1 | profile 1 | 2 | profile 2 |--> */ - /* |_________|_________________|_________|_________________|__ _ _ */ - /* */ - /* ^ ^ */ - /* | | */ - /* start of render pool top */ - /* */ - /* The top of the profile stack is kept in the `top' variable. */ - /* */ - /* As you can see, a profile record is pushed on top of the render */ - /* pool, which is then followed by its coordinates/intersections. If */ - /* a change of direction is detected in the outline, a new profile is */ - /* generated until the end of the outline. */ - /* */ - /* Note that when all profiles have been generated, the function */ - /* Finalize_Profile_Table() is used to record, for each profile, its */ - /* bottom-most scanline as well as the scanline above its upmost */ - /* boundary. These positions are called `y-turns' because they (sort */ - /* of) correspond to local extrema. They are stored in a sorted list */ - /* built from the top of the render pool as a downwards stack: */ - /* */ - /* _ _ _______________________________________ */ - /* | | */ - /* <--| sorted list of | */ - /* <--| extrema scanlines | */ - /* _ _ __________________|____________________| */ - /* */ - /* ^ ^ */ - /* | | */ - /* maxBuff sizeBuff = end of pool */ - /* */ - /* This list is later used during the sweep phase in order to */ - /* optimize performance (see technical note on the sweep below). */ - /* */ - /* Of course, the raster detects whether the two stacks collide and */ - /* handles the situation properly. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * A simple technical note on how the raster works + * ----------------------------------------------- + * + * Converting an outline into a bitmap is achieved in several steps: + * + * 1 - Decomposing the outline into successive `profiles'. Each + * profile is simply an array of scanline intersections on a given + * dimension. A profile's main attributes are + * + * o its scanline position boundaries, i.e. `Ymin' and `Ymax' + * + * o an array of intersection coordinates for each scanline + * between `Ymin' and `Ymax' + * + * o a direction, indicating whether it was built going `up' or + * `down', as this is very important for filling rules + * + * o its drop-out mode + * + * 2 - Sweeping the target map's scanlines in order to compute segment + * `spans' which are then filled. Additionally, this pass + * performs drop-out control. + * + * The outline data is parsed during step 1 only. The profiles are + * built from the bottom of the render pool, used as a stack. The + * following graphics shows the profile list under construction: + * + * __________________________________________________________ _ _ + * | | | | | + * | profile | coordinates for | profile | coordinates for |--> + * | 1 | profile 1 | 2 | profile 2 |--> + * |_________|_________________|_________|_________________|__ _ _ + * + * ^ ^ + * | | + * start of render pool top + * + * The top of the profile stack is kept in the `top' variable. + * + * As you can see, a profile record is pushed on top of the render + * pool, which is then followed by its coordinates/intersections. If + * a change of direction is detected in the outline, a new profile is + * generated until the end of the outline. + * + * Note that when all profiles have been generated, the function + * Finalize_Profile_Table() is used to record, for each profile, its + * bottom-most scanline as well as the scanline above its upmost + * boundary. These positions are called `y-turns' because they (sort + * of) correspond to local extrema. They are stored in a sorted list + * built from the top of the render pool as a downwards stack: + * + * _ _ _______________________________________ + * | | + * <--| sorted list of | + * <--| extrema scanlines | + * _ _ __________________|____________________| + * + * ^ ^ + * | | + * maxBuff sizeBuff = end of pool + * + * This list is later used during the sweep phase in order to + * optimize performance (see technical note on the sweep below). + * + * Of course, the raster detects whether the two stacks collide and + * handles the situation properly. + * + */ /*************************************************************************/ @@ -163,14 +162,14 @@ /*************************************************************************/ /*************************************************************************/ - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_raster +#define FT_COMPONENT raster #ifdef STANDALONE_ @@ -452,9 +451,9 @@ #define CEILING( x ) ( ( (x) + ras.precision - 1 ) & -ras.precision ) #define TRUNC( x ) ( (Long)(x) >> ras.precision_bits ) #define FRAC( x ) ( (x) & ( ras.precision - 1 ) ) -#define SCALED( x ) ( ( (x) < 0 ? -( -(x) << ras.scale_shift ) \ - : ( (x) << ras.scale_shift ) ) \ - - ras.precision_half ) + + /* scale and shift grid to pixel centers */ +#define SCALED( x ) ( (x) * ras.precision_scale - ras.precision_half ) #define IS_BOTTOM_OVERSHOOT( x ) \ (Bool)( CEILING( x ) - x >= ras.precision_half ) @@ -476,13 +475,10 @@ Int precision_bits; /* precision related variables */ Int precision; Int precision_half; - Int precision_shift; + Int precision_scale; Int precision_step; Int precision_jitter; - Int scale_shift; /* == precision_shift for bitmaps */ - /* == precision_shift+1 for pixmaps */ - PLong buff; /* The profiles buffer */ PLong sizeBuff; /* Render pool size */ PLong maxBuff; /* Profiles buffer size */ @@ -495,8 +491,7 @@ TPoint* arc; /* current Bezier arc pointer */ UShort bWidth; /* target bitmap width */ - PByte bTarget; /* target bitmap buffer */ - PByte gTarget; /* target pixmap buffer */ + PByte bOrigin; /* target bitmap bottom-left origin */ Long lastX, lastY; Long minY, maxY; @@ -519,8 +514,6 @@ FT_Outline outline; Long traceOfs; /* current offset in target bitmap */ - Long traceG; /* current offset in target pixmap */ - Short traceIncr; /* sweep's increment in target bitmap */ /* dispatch variables */ @@ -572,18 +565,19 @@ /*************************************************************************/ - /*************************************************************************/ - /* */ - /* <Function> */ - /* Set_High_Precision */ - /* */ - /* <Description> */ - /* Set precision variables according to param flag. */ - /* */ - /* <Input> */ - /* High :: Set to True for high precision (typically for ppem < 24), */ - /* false otherwise. */ - /* */ + /************************************************************************** + * + * @Function: + * Set_High_Precision + * + * @Description: + * Set precision variables according to param flag. + * + * @Input: + * High :: + * Set to True for high precision (typically for ppem < 24), + * false otherwise. + */ static void Set_High_Precision( RAS_ARGS Int High ) { @@ -625,29 +619,31 @@ FT_TRACE6(( "Set_High_Precision(%s)\n", High ? "true" : "false" )); ras.precision = 1 << ras.precision_bits; - ras.precision_half = ras.precision / 2; - ras.precision_shift = ras.precision_bits - Pixel_Bits; + ras.precision_half = ras.precision >> 1; + ras.precision_scale = ras.precision >> Pixel_Bits; } - /*************************************************************************/ - /* */ - /* <Function> */ - /* New_Profile */ - /* */ - /* <Description> */ - /* Create a new profile in the render pool. */ - /* */ - /* <Input> */ - /* aState :: The state/orientation of the new profile. */ - /* */ - /* overshoot :: Whether the profile's unrounded start position */ - /* differs by at least a half pixel. */ - /* */ - /* <Return> */ - /* SUCCESS on success. FAILURE in case of overflow or of incoherent */ - /* profile. */ - /* */ + /************************************************************************** + * + * @Function: + * New_Profile + * + * @Description: + * Create a new profile in the render pool. + * + * @Input: + * aState :: + * The state/orientation of the new profile. + * + * overshoot :: + * Whether the profile's unrounded start position + * differs by at least a half pixel. + * + * @Return: + * SUCCESS on success. FAILURE in case of overflow or of incoherent + * profile. + */ static Bool New_Profile( RAS_ARGS TStates aState, Bool overshoot ) @@ -706,21 +702,22 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* End_Profile */ - /* */ - /* <Description> */ - /* Finalize the current profile. */ - /* */ - /* <Input> */ - /* overshoot :: Whether the profile's unrounded end position differs */ - /* by at least a half pixel. */ - /* */ - /* <Return> */ - /* SUCCESS on success. FAILURE in case of overflow or incoherency. */ - /* */ + /************************************************************************** + * + * @Function: + * End_Profile + * + * @Description: + * Finalize the current profile. + * + * @Input: + * overshoot :: + * Whether the profile's unrounded end position differs + * by at least a half pixel. + * + * @Return: + * SUCCESS on success. FAILURE in case of overflow or incoherency. + */ static Bool End_Profile( RAS_ARGS Bool overshoot ) { @@ -778,21 +775,21 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* Insert_Y_Turn */ - /* */ - /* <Description> */ - /* Insert a salient into the sorted list placed on top of the render */ - /* pool. */ - /* */ - /* <Input> */ - /* New y scanline position. */ - /* */ - /* <Return> */ - /* SUCCESS on success. FAILURE in case of overflow. */ - /* */ + /************************************************************************** + * + * @Function: + * Insert_Y_Turn + * + * @Description: + * Insert a salient into the sorted list placed on top of the render + * pool. + * + * @Input: + * New y scanline position. + * + * @Return: + * SUCCESS on success. FAILURE in case of overflow. + */ static Bool Insert_Y_Turn( RAS_ARGS Int y ) { @@ -834,17 +831,17 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* Finalize_Profile_Table */ - /* */ - /* <Description> */ - /* Adjust all links in the profiles list. */ - /* */ - /* <Return> */ - /* SUCCESS on success. FAILURE in case of overflow. */ - /* */ + /************************************************************************** + * + * @Function: + * Finalize_Profile_Table + * + * @Description: + * Adjust all links in the profiles list. + * + * @Return: + * SUCCESS on success. FAILURE in case of overflow. + */ static Bool Finalize_Profile_Table( RAS_ARG ) { @@ -894,22 +891,22 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* Split_Conic */ - /* */ - /* <Description> */ - /* Subdivide one conic Bezier into two joint sub-arcs in the Bezier */ - /* stack. */ - /* */ - /* <Input> */ - /* None (subdivided Bezier is taken from the top of the stack). */ - /* */ - /* <Note> */ - /* This routine is the `beef' of this component. It is _the_ inner */ - /* loop that should be optimized to hell to get the best performance. */ - /* */ + /************************************************************************** + * + * @Function: + * Split_Conic + * + * @Description: + * Subdivide one conic Bezier into two joint sub-arcs in the Bezier + * stack. + * + * @Input: + * None (subdivided Bezier is taken from the top of the stack). + * + * @Note: + * This routine is the `beef' of this component. It is _the_ inner + * loop that should be optimized to hell to get the best performance. + */ static void Split_Conic( TPoint* base ) { @@ -933,20 +930,20 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* Split_Cubic */ - /* */ - /* <Description> */ - /* Subdivide a third-order Bezier arc into two joint sub-arcs in the */ - /* Bezier stack. */ - /* */ - /* <Note> */ - /* This routine is the `beef' of the component. It is one of _the_ */ - /* inner loops that should be optimized like hell to get the best */ - /* performance. */ - /* */ + /************************************************************************** + * + * @Function: + * Split_Cubic + * + * @Description: + * Subdivide a third-order Bezier arc into two joint sub-arcs in the + * Bezier stack. + * + * @Note: + * This routine is the `beef' of the component. It is one of _the_ + * inner loops that should be optimized like hell to get the best + * performance. + */ static void Split_Cubic( TPoint* base ) { @@ -975,31 +972,37 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* Line_Up */ - /* */ - /* <Description> */ - /* Compute the x-coordinates of an ascending line segment and store */ - /* them in the render pool. */ - /* */ - /* <Input> */ - /* x1 :: The x-coordinate of the segment's start point. */ - /* */ - /* y1 :: The y-coordinate of the segment's start point. */ - /* */ - /* x2 :: The x-coordinate of the segment's end point. */ - /* */ - /* y2 :: The y-coordinate of the segment's end point. */ - /* */ - /* miny :: A lower vertical clipping bound value. */ - /* */ - /* maxy :: An upper vertical clipping bound value. */ - /* */ - /* <Return> */ - /* SUCCESS on success, FAILURE on render pool overflow. */ - /* */ + /************************************************************************** + * + * @Function: + * Line_Up + * + * @Description: + * Compute the x-coordinates of an ascending line segment and store + * them in the render pool. + * + * @Input: + * x1 :: + * The x-coordinate of the segment's start point. + * + * y1 :: + * The y-coordinate of the segment's start point. + * + * x2 :: + * The x-coordinate of the segment's end point. + * + * y2 :: + * The y-coordinate of the segment's end point. + * + * miny :: + * A lower vertical clipping bound value. + * + * maxy :: + * An upper vertical clipping bound value. + * + * @Return: + * SUCCESS on success, FAILURE on render pool overflow. + */ static Bool Line_Up( RAS_ARGS Long x1, Long y1, @@ -1114,31 +1117,37 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* Line_Down */ - /* */ - /* <Description> */ - /* Compute the x-coordinates of an descending line segment and store */ - /* them in the render pool. */ - /* */ - /* <Input> */ - /* x1 :: The x-coordinate of the segment's start point. */ - /* */ - /* y1 :: The y-coordinate of the segment's start point. */ - /* */ - /* x2 :: The x-coordinate of the segment's end point. */ - /* */ - /* y2 :: The y-coordinate of the segment's end point. */ - /* */ - /* miny :: A lower vertical clipping bound value. */ - /* */ - /* maxy :: An upper vertical clipping bound value. */ - /* */ - /* <Return> */ - /* SUCCESS on success, FAILURE on render pool overflow. */ - /* */ + /************************************************************************** + * + * @Function: + * Line_Down + * + * @Description: + * Compute the x-coordinates of an descending line segment and store + * them in the render pool. + * + * @Input: + * x1 :: + * The x-coordinate of the segment's start point. + * + * y1 :: + * The y-coordinate of the segment's start point. + * + * x2 :: + * The x-coordinate of the segment's end point. + * + * y2 :: + * The y-coordinate of the segment's end point. + * + * miny :: + * A lower vertical clipping bound value. + * + * maxy :: + * An upper vertical clipping bound value. + * + * @Return: + * SUCCESS on success, FAILURE on render pool overflow. + */ static Bool Line_Down( RAS_ARGS Long x1, Long y1, @@ -1165,27 +1174,31 @@ typedef void (*TSplitter)( TPoint* base ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* Bezier_Up */ - /* */ - /* <Description> */ - /* Compute the x-coordinates of an ascending Bezier arc and store */ - /* them in the render pool. */ - /* */ - /* <Input> */ - /* degree :: The degree of the Bezier arc (either 2 or 3). */ - /* */ - /* splitter :: The function to split Bezier arcs. */ - /* */ - /* miny :: A lower vertical clipping bound value. */ - /* */ - /* maxy :: An upper vertical clipping bound value. */ - /* */ - /* <Return> */ - /* SUCCESS on success, FAILURE on render pool overflow. */ - /* */ + /************************************************************************** + * + * @Function: + * Bezier_Up + * + * @Description: + * Compute the x-coordinates of an ascending Bezier arc and store + * them in the render pool. + * + * @Input: + * degree :: + * The degree of the Bezier arc (either 2 or 3). + * + * splitter :: + * The function to split Bezier arcs. + * + * miny :: + * A lower vertical clipping bound value. + * + * maxy :: + * An upper vertical clipping bound value. + * + * @Return: + * SUCCESS on success, FAILURE on render pool overflow. + */ static Bool Bezier_Up( RAS_ARGS Int degree, TSplitter splitter, @@ -1298,27 +1311,31 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* Bezier_Down */ - /* */ - /* <Description> */ - /* Compute the x-coordinates of an descending Bezier arc and store */ - /* them in the render pool. */ - /* */ - /* <Input> */ - /* degree :: The degree of the Bezier arc (either 2 or 3). */ - /* */ - /* splitter :: The function to split Bezier arcs. */ - /* */ - /* miny :: A lower vertical clipping bound value. */ - /* */ - /* maxy :: An upper vertical clipping bound value. */ - /* */ - /* <Return> */ - /* SUCCESS on success, FAILURE on render pool overflow. */ - /* */ + /************************************************************************** + * + * @Function: + * Bezier_Down + * + * @Description: + * Compute the x-coordinates of an descending Bezier arc and store + * them in the render pool. + * + * @Input: + * degree :: + * The degree of the Bezier arc (either 2 or 3). + * + * splitter :: + * The function to split Bezier arcs. + * + * miny :: + * A lower vertical clipping bound value. + * + * maxy :: + * An upper vertical clipping bound value. + * + * @Return: + * SUCCESS on success, FAILURE on render pool overflow. + */ static Bool Bezier_Down( RAS_ARGS Int degree, TSplitter splitter, @@ -1347,25 +1364,27 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* Line_To */ - /* */ - /* <Description> */ - /* Inject a new line segment and adjust the Profiles list. */ - /* */ - /* <Input> */ - /* x :: The x-coordinate of the segment's end point (its start point */ - /* is stored in `lastX'). */ - /* */ - /* y :: The y-coordinate of the segment's end point (its start point */ - /* is stored in `lastY'). */ - /* */ - /* <Return> */ - /* SUCCESS on success, FAILURE on render pool overflow or incorrect */ - /* profile. */ - /* */ + /************************************************************************** + * + * @Function: + * Line_To + * + * @Description: + * Inject a new line segment and adjust the Profiles list. + * + * @Input: + * x :: + * The x-coordinate of the segment's end point (its start point + * is stored in `lastX'). + * + * y :: + * The y-coordinate of the segment's end point (its start point + * is stored in `lastY'). + * + * @Return: + * SUCCESS on success, FAILURE on render pool overflow or incorrect + * profile. + */ static Bool Line_To( RAS_ARGS Long x, Long y ) @@ -1441,29 +1460,33 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* Conic_To */ - /* */ - /* <Description> */ - /* Inject a new conic arc and adjust the profile list. */ - /* */ - /* <Input> */ - /* cx :: The x-coordinate of the arc's new control point. */ - /* */ - /* cy :: The y-coordinate of the arc's new control point. */ - /* */ - /* x :: The x-coordinate of the arc's end point (its start point is */ - /* stored in `lastX'). */ - /* */ - /* y :: The y-coordinate of the arc's end point (its start point is */ - /* stored in `lastY'). */ - /* */ - /* <Return> */ - /* SUCCESS on success, FAILURE on render pool overflow or incorrect */ - /* profile. */ - /* */ + /************************************************************************** + * + * @Function: + * Conic_To + * + * @Description: + * Inject a new conic arc and adjust the profile list. + * + * @Input: + * cx :: + * The x-coordinate of the arc's new control point. + * + * cy :: + * The y-coordinate of the arc's new control point. + * + * x :: + * The x-coordinate of the arc's end point (its start point is + * stored in `lastX'). + * + * y :: + * The y-coordinate of the arc's end point (its start point is + * stored in `lastY'). + * + * @Return: + * SUCCESS on success, FAILURE on render pool overflow or incorrect + * profile. + */ static Bool Conic_To( RAS_ARGS Long cx, Long cy, @@ -1558,33 +1581,39 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* Cubic_To */ - /* */ - /* <Description> */ - /* Inject a new cubic arc and adjust the profile list. */ - /* */ - /* <Input> */ - /* cx1 :: The x-coordinate of the arc's first new control point. */ - /* */ - /* cy1 :: The y-coordinate of the arc's first new control point. */ - /* */ - /* cx2 :: The x-coordinate of the arc's second new control point. */ - /* */ - /* cy2 :: The y-coordinate of the arc's second new control point. */ - /* */ - /* x :: The x-coordinate of the arc's end point (its start point is */ - /* stored in `lastX'). */ - /* */ - /* y :: The y-coordinate of the arc's end point (its start point is */ - /* stored in `lastY'). */ - /* */ - /* <Return> */ - /* SUCCESS on success, FAILURE on render pool overflow or incorrect */ - /* profile. */ - /* */ + /************************************************************************** + * + * @Function: + * Cubic_To + * + * @Description: + * Inject a new cubic arc and adjust the profile list. + * + * @Input: + * cx1 :: + * The x-coordinate of the arc's first new control point. + * + * cy1 :: + * The y-coordinate of the arc's first new control point. + * + * cx2 :: + * The x-coordinate of the arc's second new control point. + * + * cy2 :: + * The y-coordinate of the arc's second new control point. + * + * x :: + * The x-coordinate of the arc's end point (its start point is + * stored in `lastX'). + * + * y :: + * The y-coordinate of the arc's end point (its start point is + * stored in `lastY'). + * + * @Return: + * SUCCESS on success, FAILURE on render pool overflow or incorrect + * profile. + */ static Bool Cubic_To( RAS_ARGS Long cx1, Long cy1, @@ -1705,27 +1734,30 @@ } while ( 0 ) - /*************************************************************************/ - /* */ - /* <Function> */ - /* Decompose_Curve */ - /* */ - /* <Description> */ - /* Scan the outline arrays in order to emit individual segments and */ - /* Beziers by calling Line_To() and Bezier_To(). It handles all */ - /* weird cases, like when the first point is off the curve, or when */ - /* there are simply no `on' points in the contour! */ - /* */ - /* <Input> */ - /* first :: The index of the first point in the contour. */ - /* */ - /* last :: The index of the last point in the contour. */ - /* */ - /* flipped :: If set, flip the direction of the curve. */ - /* */ - /* <Return> */ - /* SUCCESS on success, FAILURE on error. */ - /* */ + /************************************************************************** + * + * @Function: + * Decompose_Curve + * + * @Description: + * Scan the outline arrays in order to emit individual segments and + * Beziers by calling Line_To() and Bezier_To(). It handles all + * weird cases, like when the first point is off the curve, or when + * there are simply no `on' points in the contour! + * + * @Input: + * first :: + * The index of the first point in the contour. + * + * last :: + * The index of the last point in the contour. + * + * flipped :: + * If set, flip the direction of the curve. + * + * @Return: + * SUCCESS on success, FAILURE on error. + */ static Bool Decompose_Curve( RAS_ARGS UShort first, UShort last, @@ -1934,22 +1966,23 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* Convert_Glyph */ - /* */ - /* <Description> */ - /* Convert a glyph into a series of segments and arcs and make a */ - /* profiles list with them. */ - /* */ - /* <Input> */ - /* flipped :: If set, flip the direction of curve. */ - /* */ - /* <Return> */ - /* SUCCESS on success, FAILURE if any error was encountered during */ - /* rendering. */ - /* */ + /************************************************************************** + * + * @Function: + * Convert_Glyph + * + * @Description: + * Convert a glyph into a series of segments and arcs and make a + * profiles list with them. + * + * @Input: + * flipped :: + * If set, flip the direction of curve. + * + * @Return: + * SUCCESS on success, FAILURE if any error was encountered during + * rendering. + */ static Bool Convert_Glyph( RAS_ARGS Int flipped ) { @@ -2028,12 +2061,12 @@ /*************************************************************************/ - /*************************************************************************/ - /* */ - /* Init_Linked */ - /* */ - /* Initializes an empty linked list. */ - /* */ + /************************************************************************** + * + * Init_Linked + * + * Initializes an empty linked list. + */ static void Init_Linked( TProfileList* l ) { @@ -2041,12 +2074,12 @@ } - /*************************************************************************/ - /* */ - /* InsNew */ - /* */ - /* Inserts a new profile in a linked list. */ - /* */ + /************************************************************************** + * + * InsNew + * + * Inserts a new profile in a linked list. + */ static void InsNew( PProfileList list, PProfile profile ) @@ -2072,12 +2105,12 @@ } - /*************************************************************************/ - /* */ - /* DelOld */ - /* */ - /* Removes an old profile from a linked list. */ - /* */ + /************************************************************************** + * + * DelOld + * + * Removes an old profile from a linked list. + */ static void DelOld( PProfileList list, PProfile profile ) @@ -2105,14 +2138,14 @@ } - /*************************************************************************/ - /* */ - /* Sort */ - /* */ - /* Sorts a trace list. In 95%, the list is already sorted. We need */ - /* an algorithm which is fast in this case. Bubble sort is enough */ - /* and simple. */ - /* */ + /************************************************************************** + * + * Sort + * + * Sorts a trace list. In 95%, the list is already sorted. We need + * an algorithm which is fast in this case. Bubble sort is enough + * and simple. + */ static void Sort( PProfileList list ) { @@ -2163,14 +2196,14 @@ } - /*************************************************************************/ - /* */ - /* Vertical Sweep Procedure Set */ - /* */ - /* These four routines are used during the vertical black/white sweep */ - /* phase by the generic Draw_Sweep() function. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * Vertical Sweep Procedure Set + * + * These four routines are used during the vertical black/white sweep + * phase by the generic Draw_Sweep() function. + * + */ static void Vertical_Sweep_Init( RAS_ARGS Short* min, @@ -2183,8 +2216,6 @@ ras.traceIncr = (Short)-pitch; ras.traceOfs = -*min * pitch; - if ( pitch > 0 ) - ras.traceOfs += (Long)( ras.target.rows - 1 ) * pitch; } @@ -2215,13 +2246,18 @@ /* Drop-out control */ - e1 = TRUNC( CEILING( x1 ) ); + e1 = CEILING( x1 ); + e2 = FLOOR( x2 ); + /* take care of the special case where both the left */ + /* and right contour lie exactly on pixel centers */ if ( dropOutControl != 2 && - x2 - x1 - ras.precision <= ras.precision_jitter ) + x2 - x1 - ras.precision <= ras.precision_jitter && + e1 != x1 && e2 != x2 ) e2 = e1; - else - e2 = TRUNC( FLOOR( x2 ) ); + + e1 = TRUNC( e1 ); + e2 = TRUNC( e2 ); if ( e2 >= 0 && e1 < ras.bWidth ) { @@ -2242,7 +2278,7 @@ f1 = (Byte) ( 0xFF >> ( e1 & 7 ) ); f2 = (Byte) ~( 0x7F >> ( e2 & 7 ) ); - target = ras.bTarget + ras.traceOfs + c1; + target = ras.bOrigin + ras.traceOfs + c1; c2 -= c1; if ( c2 > 0 ) @@ -2252,12 +2288,9 @@ /* memset() is slower than the following code on many platforms. */ /* This is due to the fact that, in the vast majority of cases, */ /* the span length in bytes is relatively small. */ - c2--; - while ( c2 > 0 ) - { + while ( --c2 > 0 ) *(++target) = 0xFF; - c2--; - } + target[1] |= f2; } else @@ -2400,7 +2433,7 @@ f1 = (Short)( e1 & 7 ); if ( e1 >= 0 && e1 < ras.bWidth && - ras.bTarget[ras.traceOfs + c1] & ( 0x80 >> f1 ) ) + ras.bOrigin[ras.traceOfs + c1] & ( 0x80 >> f1 ) ) goto Exit; } else @@ -2416,7 +2449,7 @@ c1 = (Short)( e1 >> 3 ); f1 = (Short)( e1 & 7 ); - ras.bTarget[ras.traceOfs + c1] |= (char)( 0x80 >> f1 ); + ras.bOrigin[ras.traceOfs + c1] |= (char)( 0x80 >> f1 ); } Exit: @@ -2431,14 +2464,14 @@ } - /***********************************************************************/ - /* */ - /* Horizontal Sweep Procedure Set */ - /* */ - /* These four routines are used during the horizontal black/white */ - /* sweep phase by the generic Draw_Sweep() function. */ - /* */ - /***********************************************************************/ + /************************************************************************ + * + * Horizontal Sweep Procedure Set + * + * These four routines are used during the horizontal black/white + * sweep phase by the generic Draw_Sweep() function. + * + */ static void Horizontal_Sweep_Init( RAS_ARGS Short* min, @@ -2483,19 +2516,14 @@ { Byte f1; PByte bits; - PByte p; FT_TRACE7(( " -> y=%d (drop-out)", e1 )); - bits = ras.bTarget + ( y >> 3 ); + bits = ras.bOrigin + ( y >> 3 ) - e1 * ras.target.pitch; f1 = (Byte)( 0x80 >> ( y & 7 ) ); - p = bits - e1 * ras.target.pitch; - - if ( ras.target.pitch > 0 ) - p += (Long)( ras.target.rows - 1 ) * ras.target.pitch; - p[0] |= f1; + bits[0] |= f1; } } @@ -2597,13 +2625,9 @@ e1 = TRUNC( e1 ); - bits = ras.bTarget + ( y >> 3 ); + bits = ras.bOrigin + ( y >> 3 ) - e1 * ras.target.pitch; f1 = (Byte)( 0x80 >> ( y & 7 ) ); - bits -= e1 * ras.target.pitch; - if ( ras.target.pitch > 0 ) - bits += (Long)( ras.target.rows - 1 ) * ras.target.pitch; - if ( e1 >= 0 && (ULong)e1 < ras.target.rows && *bits & f1 ) @@ -2619,12 +2643,8 @@ { FT_TRACE7(( " -> y=%d (drop-out)", e1 )); - bits = ras.bTarget + ( y >> 3 ); + bits = ras.bOrigin + ( y >> 3 ) - e1 * ras.target.pitch; f1 = (Byte)( 0x80 >> ( y & 7 ) ); - bits -= e1 * ras.target.pitch; - - if ( ras.target.pitch > 0 ) - bits += (Long)( ras.target.rows - 1 ) * ras.target.pitch; bits[0] |= f1; } @@ -2642,11 +2662,11 @@ } - /*************************************************************************/ - /* */ - /* Generic Sweep Drawing routine */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * Generic Sweep Drawing routine + * + */ static Bool Draw_Sweep( RAS_ARG ) @@ -2888,20 +2908,109 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* Render_Single_Pass */ - /* */ - /* <Description> */ - /* Perform one sweep with sub-banding. */ - /* */ - /* <Input> */ - /* flipped :: If set, flip the direction of the outline. */ - /* */ - /* <Return> */ - /* Renderer error code. */ - /* */ +#ifdef STANDALONE_ + + /************************************************************************** + * + * The following functions should only compile in stand-alone mode, + * i.e., when building this component without the rest of FreeType. + * + */ + + /************************************************************************** + * + * @Function: + * FT_Outline_Get_CBox + * + * @Description: + * Return an outline's `control box'. The control box encloses all + * the outline's points, including Bézier control points. Though it + * coincides with the exact bounding box for most glyphs, it can be + * slightly larger in some situations (like when rotating an outline + * that contains Bézier outside arcs). + * + * Computing the control box is very fast, while getting the bounding + * box can take much more time as it needs to walk over all segments + * and arcs in the outline. To get the latter, you can use the + * `ftbbox' component, which is dedicated to this single task. + * + * @Input: + * outline :: + * A pointer to the source outline descriptor. + * + * @Output: + * acbox :: + * The outline's control box. + * + * @Note: + * See @FT_Glyph_Get_CBox for a discussion of tricky fonts. + */ + + static void + FT_Outline_Get_CBox( const FT_Outline* outline, + FT_BBox *acbox ) + { + Long xMin, yMin, xMax, yMax; + + + if ( outline && acbox ) + { + if ( outline->n_points == 0 ) + { + xMin = 0; + yMin = 0; + xMax = 0; + yMax = 0; + } + else + { + FT_Vector* vec = outline->points; + FT_Vector* limit = vec + outline->n_points; + + + xMin = xMax = vec->x; + yMin = yMax = vec->y; + vec++; + + for ( ; vec < limit; vec++ ) + { + Long x, y; + + + x = vec->x; + if ( x < xMin ) xMin = x; + if ( x > xMax ) xMax = x; + + y = vec->y; + if ( y < yMin ) yMin = y; + if ( y > yMax ) yMax = y; + } + } + acbox->xMin = xMin; + acbox->xMax = xMax; + acbox->yMin = yMin; + acbox->yMax = yMax; + } + } + +#endif /* STANDALONE_ */ + + + /************************************************************************** + * + * @Function: + * Render_Single_Pass + * + * @Description: + * Perform one sweep with sub-banding. + * + * @Input: + * flipped :: + * If set, flip the direction of the outline. + * + * @Return: + * Renderer error code. + */ static int Render_Single_Pass( RAS_ARGS Bool flipped ) { @@ -2963,17 +3072,17 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* Render_Glyph */ - /* */ - /* <Description> */ - /* Render a glyph in a bitmap. Sub-banding if needed. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * Render_Glyph + * + * @Description: + * Render a glyph in a bitmap. Sub-banding if needed. + * + * @Return: + * FreeType error code. 0 means success. + */ static FT_Error Render_Glyph( RAS_ARG ) { @@ -2982,7 +3091,6 @@ Set_High_Precision( RAS_VARS ras.outline.flags & FT_OUTLINE_HIGH_PRECISION ); - ras.scale_shift = ras.precision_shift; if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS ) ras.dropOutControl = 2; @@ -3013,7 +3121,10 @@ ras.band_stack[0].y_max = (Short)( ras.target.rows - 1 ); ras.bWidth = (UShort)ras.target.width; - ras.bTarget = (Byte*)ras.target.buffer; + ras.bOrigin = (Byte*)ras.target.buffer; + + if ( ras.target.pitch > 0 ) + ras.bOrigin += (Long)( ras.target.rows - 1 ) * ras.target.pitch; if ( ( error = Render_Single_Pass( RAS_VARS 0 ) ) != 0 ) return error; @@ -3147,16 +3258,20 @@ const FT_Bitmap* target_map = params->target; #ifdef __REACTOS__ - FT_Error ret; - black_TWorker *worker; - Long *buffer; + black_TWorker *worker = malloc(sizeof(*worker)); + Long *buffer = malloc(FT_MAX_BLACK_POOL * sizeof(Long)); + if (!worker || !buffer) + { + free(worker); + free(buffer); + return FT_THROW( Out_Of_Memory ); + } #else black_TWorker worker[1]; Long buffer[FT_MAX_BLACK_POOL]; #endif - if ( !raster ) return FT_THROW( Not_Ini ); @@ -3191,46 +3306,23 @@ if ( !target_map->buffer ) return FT_THROW( Invalid ); - /* reject too large outline coordinates */ - { - FT_Vector* vec = outline->points; - FT_Vector* limit = vec + outline->n_points; - - - for ( ; vec < limit; vec++ ) - { - if ( vec->x < -0x1000000L || vec->x > 0x1000000L || - vec->y < -0x1000000L || vec->y > 0x1000000L ) - return FT_THROW( Invalid ); - } - } - -#ifdef __REACTOS__ - worker = malloc(sizeof(black_TWorker)); - buffer = malloc(FT_MAX(FT_RENDER_POOL_SIZE, 2048)); - if (!worker || !buffer) - { - free(worker); - free(buffer); - return FT_THROW( Out_Of_Memory ); - } -#endif - ras.outline = *outline; ras.target = *target_map; worker->buff = buffer; #ifdef __REACTOS__ - worker->sizeBuff = buffer + FT_MAX_BLACK_POOL; + worker->sizeBuff = &buffer[FT_MAX_BLACK_POOL]; #else worker->sizeBuff = (&buffer)[1]; /* Points to right after buffer. */ #endif #ifdef __REACTOS__ - ret = Render_Glyph(RAS_VAR); - free(worker); - free(buffer); - return ret; + { + FT_Error error = Render_Glyph( RAS_VAR ); + free(buffer); + free(worker); + return error; + } #else return Render_Glyph( RAS_VAR ); #endif diff --git a/sdk/lib/3rdparty/freetype/src/raster/ftraster.h b/sdk/lib/3rdparty/freetype/src/raster/ftraster.h index 40b5d6d321c81..50d34201a1c05 100644 --- a/sdk/lib/3rdparty/freetype/src/raster/ftraster.h +++ b/sdk/lib/3rdparty/freetype/src/raster/ftraster.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftraster.h */ -/* */ -/* The FreeType glyph rasterizer (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used */ -/* modified and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftraster.h + * + * The FreeType glyph rasterizer (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTRASTER_H_ @@ -28,11 +28,11 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* Uncomment the following line if you are using ftraster.c as a */ - /* standalone module, fully independent of FreeType. */ - /* */ + /************************************************************************** + * + * Uncomment the following line if you are using ftraster.c as a + * standalone module, fully independent of FreeType. + */ /* #define STANDALONE_ */ FT_EXPORT_VAR( const FT_Raster_Funcs ) ft_standard_raster; diff --git a/sdk/lib/3rdparty/freetype/src/raster/ftrend1.c b/sdk/lib/3rdparty/freetype/src/raster/ftrend1.c index a7ce9731d7754..62c727182a408 100644 --- a/sdk/lib/3rdparty/freetype/src/raster/ftrend1.c +++ b/sdk/lib/3rdparty/freetype/src/raster/ftrend1.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftrend1.c */ -/* */ -/* The FreeType glyph rasterizer interface (body). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftrend1.c + * + * The FreeType glyph rasterizer interface (body). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -22,7 +22,6 @@ #include FT_OUTLINE_H #include "ftrend1.h" #include "ftraster.h" -#include "rastpic.h" #include "rasterrs.h" @@ -128,7 +127,11 @@ slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; } - ft_glyphslot_preset_bitmap( slot, mode, origin ); + if ( ft_glyphslot_preset_bitmap( slot, mode, origin ) ) + { + error = FT_THROW( Raster_Overflow ); + goto Exit; + } /* allocate new one */ if ( FT_ALLOC_MULT( bitmap->buffer, bitmap->rows, bitmap->pitch ) ) @@ -197,7 +200,7 @@ (FT_Renderer_GetCBoxFunc) ft_raster1_get_cbox, /* get_glyph_cbox */ (FT_Renderer_SetModeFunc) ft_raster1_set_mode, /* set_mode */ - (FT_Raster_Funcs*)&FT_STANDARD_RASTER_GET /* raster_class */ + (FT_Raster_Funcs*)&ft_standard_raster /* raster_class */ ) diff --git a/sdk/lib/3rdparty/freetype/src/raster/ftrend1.h b/sdk/lib/3rdparty/freetype/src/raster/ftrend1.h index 2abdf2d703b2e..82ecac686c164 100644 --- a/sdk/lib/3rdparty/freetype/src/raster/ftrend1.h +++ b/sdk/lib/3rdparty/freetype/src/raster/ftrend1.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftrend1.h */ -/* */ -/* The FreeType glyph rasterizer interface (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftrend1.h + * + * The FreeType glyph rasterizer interface (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTREND1_H_ diff --git a/sdk/lib/3rdparty/freetype/src/raster/raster.c b/sdk/lib/3rdparty/freetype/src/raster/raster.c index 76edd21e1e01a..e3ac9e566a3d7 100644 --- a/sdk/lib/3rdparty/freetype/src/raster/raster.c +++ b/sdk/lib/3rdparty/freetype/src/raster/raster.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* raster.c */ -/* */ -/* FreeType monochrome rasterer module component (body only). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * raster.c + * + * FreeType monochrome rasterer module component (body only). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #define FT_MAKE_OPTION_SINGLE_OBJECT @@ -21,7 +21,6 @@ #include "ftraster.c" #include "ftrend1.c" -#include "rastpic.c" /* END */ diff --git a/sdk/lib/3rdparty/freetype/src/raster/rasterrs.h b/sdk/lib/3rdparty/freetype/src/raster/rasterrs.h index 22a3e15340611..72664073657d0 100644 --- a/sdk/lib/3rdparty/freetype/src/raster/rasterrs.h +++ b/sdk/lib/3rdparty/freetype/src/raster/rasterrs.h @@ -1,27 +1,27 @@ -/***************************************************************************/ -/* */ -/* rasterrs.h */ -/* */ -/* monochrome renderer error codes (specification only). */ -/* */ -/* Copyright 2001-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to define the monochrome renderer error enumeration */ - /* constants. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * rasterrs.h + * + * monochrome renderer error codes (specification only). + * + * Copyright (C) 2001-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /************************************************************************** + * + * This file is used to define the monochrome renderer error enumeration + * constants. + * + */ #ifndef RASTERRS_H_ #define RASTERRS_H_ diff --git a/sdk/lib/3rdparty/freetype/src/raster/rastpic.c b/sdk/lib/3rdparty/freetype/src/raster/rastpic.c deleted file mode 100644 index 1dc8981b8a671..0000000000000 --- a/sdk/lib/3rdparty/freetype/src/raster/rastpic.c +++ /dev/null @@ -1,89 +0,0 @@ -/***************************************************************************/ -/* */ -/* rastpic.c */ -/* */ -/* The FreeType position independent code services for raster module. */ -/* */ -/* Copyright 2009-2018 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_FREETYPE_H -#include FT_INTERNAL_OBJECTS_H -#include "rastpic.h" -#include "rasterrs.h" - - -#ifdef FT_CONFIG_OPTION_PIC - - /* forward declaration of PIC init functions from ftraster.c */ - void - FT_Init_Class_ft_standard_raster( FT_Raster_Funcs* funcs ); - - - void - ft_raster1_renderer_class_pic_free( FT_Library library ) - { - FT_PIC_Container* pic_container = &library->pic_container; - FT_Memory memory = library->memory; - - - if ( pic_container->raster ) - { - RasterPIC* container = (RasterPIC*)pic_container->raster; - - - if ( --container->ref_count ) - return; - FT_FREE( container ); - pic_container->raster = NULL; - } - } - - - FT_Error - ft_raster1_renderer_class_pic_init( FT_Library library ) - { - FT_PIC_Container* pic_container = &library->pic_container; - FT_Error error = FT_Err_Ok; - RasterPIC* container = NULL; - FT_Memory memory = library->memory; - - - /* XXX: since this function also served the no longer available */ - /* raster5 renderer it uses reference counting, which could */ - /* be removed now */ - if ( pic_container->raster ) - { - ((RasterPIC*)pic_container->raster)->ref_count++; - return error; - } - - /* allocate pointer, clear and set global container pointer */ - if ( FT_ALLOC( container, sizeof ( *container ) ) ) - return error; - FT_MEM_SET( container, 0, sizeof ( *container ) ); - pic_container->raster = container; - - container->ref_count = 1; - - /* initialize pointer table - */ - /* this is how the module usually expects this data */ - FT_Init_Class_ft_standard_raster( &container->ft_standard_raster ); - - return error; - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - -/* END */ diff --git a/sdk/lib/3rdparty/freetype/src/raster/rastpic.h b/sdk/lib/3rdparty/freetype/src/raster/rastpic.h deleted file mode 100644 index 6d0877c42397c..0000000000000 --- a/sdk/lib/3rdparty/freetype/src/raster/rastpic.h +++ /dev/null @@ -1,63 +0,0 @@ -/***************************************************************************/ -/* */ -/* rastpic.h */ -/* */ -/* The FreeType position independent code services for raster module. */ -/* */ -/* Copyright 2009-2018 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#ifndef RASTPIC_H_ -#define RASTPIC_H_ - - -#include FT_INTERNAL_PIC_H - - -FT_BEGIN_HEADER - -#ifndef FT_CONFIG_OPTION_PIC - -#define FT_STANDARD_RASTER_GET ft_standard_raster - -#else /* FT_CONFIG_OPTION_PIC */ - - typedef struct RasterPIC_ - { - int ref_count; - FT_Raster_Funcs ft_standard_raster; - - } RasterPIC; - - -#define GET_PIC( lib ) \ - ( (RasterPIC*)( (lib)->pic_container.raster ) ) -#define FT_STANDARD_RASTER_GET ( GET_PIC( library )->ft_standard_raster ) - - - /* see rastpic.c for the implementation */ - void - ft_raster1_renderer_class_pic_free( FT_Library library ); - - FT_Error - ft_raster1_renderer_class_pic_init( FT_Library library ); - -#endif /* FT_CONFIG_OPTION_PIC */ - - /* */ - -FT_END_HEADER - -#endif /* RASTPIC_H_ */ - - -/* END */ diff --git a/sdk/lib/3rdparty/freetype/src/sfnt/pngshim.c b/sdk/lib/3rdparty/freetype/src/sfnt/pngshim.c index 16020266afd5e..ca85d9751f02c 100644 --- a/sdk/lib/3rdparty/freetype/src/sfnt/pngshim.c +++ b/sdk/lib/3rdparty/freetype/src/sfnt/pngshim.c @@ -1,20 +1,20 @@ -/***************************************************************************/ -/* */ -/* pngshim.c */ -/* */ -/* PNG Bitmap glyph support. */ -/* */ -/* Copyright 2013-2018 by */ -/* Google, Inc. */ -/* Written by Stuart Gill and Behdad Esfahbod. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * pngshim.c + * + * PNG Bitmap glyph support. + * + * Copyright (C) 2013-2019 by + * Google, Inc. + * Written by Stuart Gill and Behdad Esfahbod. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> diff --git a/sdk/lib/3rdparty/freetype/src/sfnt/pngshim.h b/sdk/lib/3rdparty/freetype/src/sfnt/pngshim.h index 194238c3a2024..06c6f6b20e7a4 100644 --- a/sdk/lib/3rdparty/freetype/src/sfnt/pngshim.h +++ b/sdk/lib/3rdparty/freetype/src/sfnt/pngshim.h @@ -1,20 +1,20 @@ -/***************************************************************************/ -/* */ -/* pngshim.h */ -/* */ -/* PNG Bitmap glyph support. */ -/* */ -/* Copyright 2013-2018 by */ -/* Google, Inc. */ -/* Written by Stuart Gill and Behdad Esfahbod. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * pngshim.h + * + * PNG Bitmap glyph support. + * + * Copyright (C) 2013-2019 by + * Google, Inc. + * Written by Stuart Gill and Behdad Esfahbod. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef PNGSHIM_H_ diff --git a/sdk/lib/3rdparty/freetype/src/sfnt/sfdriver.c b/sdk/lib/3rdparty/freetype/src/sfnt/sfdriver.c index 303e1ca9f1a42..c467ff4d370aa 100644 --- a/sdk/lib/3rdparty/freetype/src/sfnt/sfdriver.c +++ b/sdk/lib/3rdparty/freetype/src/sfnt/sfdriver.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* sfdriver.c */ -/* */ -/* High-level SFNT driver interface (body). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * sfdriver.c + * + * High-level SFNT driver interface (body). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -25,7 +25,6 @@ #include "sfdriver.h" #include "ttload.h" #include "sfobjs.h" -#include "sfntpic.h" #include "sferrors.h" @@ -33,6 +32,11 @@ #include "ttsbit.h" #endif +#ifdef TT_CONFIG_OPTION_COLOR_LAYERS +#include "ttcolr.h" +#include "ttcpal.h" +#endif + #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES #include "ttpost.h" #endif @@ -57,18 +61,18 @@ #endif - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_sfdriver +#define FT_COMPONENT sfdriver /* - * SFNT TABLE SERVICE + * SFNT TABLE SERVICE * */ @@ -155,7 +159,7 @@ #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES /* - * GLYPH DICT SERVICE + * GLYPH DICT SERVICE * */ @@ -222,7 +226,7 @@ /* - * POSTSCRIPT NAME SERVICE + * POSTSCRIPT NAME SERVICE * */ @@ -460,14 +464,12 @@ typedef int (*char_type_func)( int c ); - /* handling of PID/EID 3/0 and 3/1 is the same */ + /* Handling of PID/EID 3/0 and 3/1 is the same. */ #define IS_WIN( n ) ( (n)->platformID == 3 && \ - ( (n)->encodingID == 1 || (n)->encodingID == 0 ) && \ - (n)->languageID == 0x409 ) + ( (n)->encodingID == 1 || (n)->encodingID == 0 ) ) #define IS_APPLE( n ) ( (n)->platformID == 1 && \ - (n)->encodingID == 0 && \ - (n)->languageID == 0 ) + (n)->encodingID == 0 ) static char* get_win_string( FT_Memory memory, @@ -491,42 +493,40 @@ if ( FT_STREAM_SEEK( entry->stringOffset ) || FT_FRAME_ENTER( entry->stringLength ) ) - { - FT_FREE( result ); - entry->stringLength = 0; - entry->stringOffset = 0; - FT_FREE( entry->string ); - - return NULL; - } + goto get_win_string_error; r = (FT_String*)result; p = (FT_Char*)stream->cursor; for ( len = entry->stringLength / 2; len > 0; len--, p += 2 ) { - if ( p[0] == 0 ) + if ( p[0] == 0 && char_type( p[1] ) ) + *r++ = p[1]; + else { - if ( char_type( p[1] ) ) - *r++ = p[1]; - else - { - if ( report_invalid_characters ) - { - FT_TRACE0(( "get_win_string:" - " Character `%c' (0x%X) invalid in PS name string\n", - p[1], p[1] )); - /* it's not the job of FreeType to correct PS names... */ - *r++ = p[1]; - } - } + if ( report_invalid_characters ) + FT_TRACE0(( "get_win_string:" + " Character 0x%X invalid in PS name string\n", + ((unsigned)p[0])*256 + (unsigned)p[1] )); + break; } } - *r = '\0'; + if ( !len ) + *r = '\0'; FT_FRAME_EXIT(); - return result; + if ( !len ) + return result; + + get_win_string_error: + FT_FREE( result ); + + entry->stringLength = 0; + entry->stringOffset = 0; + FT_FREE( entry->string ); + + return NULL; } @@ -552,14 +552,7 @@ if ( FT_STREAM_SEEK( entry->stringOffset ) || FT_FRAME_ENTER( entry->stringLength ) ) - { - FT_FREE( result ); - entry->stringOffset = 0; - entry->stringLength = 0; - FT_FREE( entry->string ); - - return NULL; - } + goto get_apple_string_error; r = (FT_String*)result; p = (FT_Char*)stream->cursor; @@ -571,20 +564,28 @@ else { if ( report_invalid_characters ) - { FT_TRACE0(( "get_apple_string:" " Character `%c' (0x%X) invalid in PS name string\n", *p, *p )); - /* it's not the job of FreeType to correct PS names... */ - *r++ = *p; - } + break; } } - *r = '\0'; + if ( !len ) + *r = '\0'; FT_FRAME_EXIT(); - return result; + if ( !len ) + return result; + + get_apple_string_error: + FT_FREE( result ); + + entry->stringOffset = 0; + entry->stringLength = 0; + FT_FREE( entry->string ); + + return NULL; } @@ -607,10 +608,10 @@ if ( name->nameID == id && name->stringLength > 0 ) { - if ( IS_WIN( name ) ) + if ( IS_WIN( name ) && ( name->languageID == 0x409 || *win == -1 ) ) *win = n; - if ( IS_APPLE( name ) ) + if ( IS_APPLE( name ) && ( name->languageID == 0 || *apple == -1 ) ) *apple = n; } } @@ -643,9 +644,9 @@ /* - * Find the shortest decimal representation of a 16.16 fixed point - * number. The function fills `buf' with the result, returning a pointer - * to the position after the representation's last byte. + * Find the shortest decimal representation of a 16.16 fixed point + * number. The function fills `buf' with the result, returning a pointer + * to the position after the representation's last byte. */ static char* @@ -673,7 +674,7 @@ if ( fixed < 0 ) { *p++ = '-'; - fixed = -fixed; + fixed = NEG_INT( fixed ); } int_part = ( fixed >> 16 ) & 0xFFFF; @@ -828,13 +829,20 @@ face->name_table.names + win, sfnt_is_alphanumeric, 0 ); - else + if ( !result && apple != -1 ) result = get_apple_string( face->root.memory, face->name_table.stream, face->name_table.names + apple, sfnt_is_alphanumeric, 0 ); + if ( !result ) + { + FT_TRACE0(( "sfnt_get_var_ps_name:" + " No valid PS name prefix for font instances found\n" )); + return NULL; + } + len = ft_strlen( result ); /* sanitize if necessary; we reserve space for 36 bytes (a 128bit */ @@ -1052,7 +1060,7 @@ face->name_table.names + win, sfnt_is_postscript, 1 ); - else + if ( !result && apple != -1 ) result = get_apple_string( face->root.memory, face->name_table.stream, face->name_table.names + apple, @@ -1073,7 +1081,7 @@ /* - * TT CMAP INFO + * TT CMAP INFO */ FT_DEFINE_SERVICE_TTCMAPSREC( tt_service_get_cmap_info, @@ -1132,41 +1140,41 @@ /* - * SERVICE LIST + * SERVICE LIST */ #if defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES && defined TT_CONFIG_OPTION_BDF FT_DEFINE_SERVICEDESCREC5( sfnt_services, - FT_SERVICE_ID_SFNT_TABLE, &SFNT_SERVICE_SFNT_TABLE_GET, - FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET, - FT_SERVICE_ID_GLYPH_DICT, &SFNT_SERVICE_GLYPH_DICT_GET, - FT_SERVICE_ID_BDF, &SFNT_SERVICE_BDF_GET, - FT_SERVICE_ID_TT_CMAP, &TT_SERVICE_CMAP_INFO_GET ) + FT_SERVICE_ID_SFNT_TABLE, &sfnt_service_sfnt_table, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &sfnt_service_ps_name, + FT_SERVICE_ID_GLYPH_DICT, &sfnt_service_glyph_dict, + FT_SERVICE_ID_BDF, &sfnt_service_bdf, + FT_SERVICE_ID_TT_CMAP, &tt_service_get_cmap_info ) #elif defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES FT_DEFINE_SERVICEDESCREC4( sfnt_services, - FT_SERVICE_ID_SFNT_TABLE, &SFNT_SERVICE_SFNT_TABLE_GET, - FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET, - FT_SERVICE_ID_GLYPH_DICT, &SFNT_SERVICE_GLYPH_DICT_GET, - FT_SERVICE_ID_TT_CMAP, &TT_SERVICE_CMAP_INFO_GET ) + FT_SERVICE_ID_SFNT_TABLE, &sfnt_service_sfnt_table, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &sfnt_service_ps_name, + FT_SERVICE_ID_GLYPH_DICT, &sfnt_service_glyph_dict, + FT_SERVICE_ID_TT_CMAP, &tt_service_get_cmap_info ) #elif defined TT_CONFIG_OPTION_BDF FT_DEFINE_SERVICEDESCREC4( sfnt_services, - FT_SERVICE_ID_SFNT_TABLE, &SFNT_SERVICE_SFNT_TABLE_GET, - FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET, - FT_SERVICE_ID_BDF, &SFNT_SERVICE_BDF_GET, - FT_SERVICE_ID_TT_CMAP, &TT_SERVICE_CMAP_INFO_GET ) + FT_SERVICE_ID_SFNT_TABLE, &sfnt_service_sfnt_table, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &sfnt_service_ps_name, + FT_SERVICE_ID_BDF, &sfnt_service_bdf, + FT_SERVICE_ID_TT_CMAP, &tt_service_get_cmap_info ) #else FT_DEFINE_SERVICEDESCREC3( sfnt_services, - FT_SERVICE_ID_SFNT_TABLE, &SFNT_SERVICE_SFNT_TABLE_GET, - FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET, - FT_SERVICE_ID_TT_CMAP, &TT_SERVICE_CMAP_INFO_GET ) + FT_SERVICE_ID_SFNT_TABLE, &sfnt_service_sfnt_table, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &sfnt_service_ps_name, + FT_SERVICE_ID_TT_CMAP, &tt_service_get_cmap_info ) #endif @@ -1174,21 +1182,9 @@ sfnt_get_interface( FT_Module module, const char* module_interface ) { - /* SFNT_SERVICES_GET dereferences `library' in PIC mode */ -#ifdef FT_CONFIG_OPTION_PIC - FT_Library library; - - - if ( !module ) - return NULL; - library = module->library; - if ( !library ) - return NULL; -#else FT_UNUSED( module ); -#endif - return ft_service_list_lookup( SFNT_SERVICES_GET, module_interface ); + return ft_service_list_lookup( sfnt_services, module_interface ); } @@ -1198,6 +1194,12 @@ #define PUT_EMBEDDED_BITMAPS( a ) NULL #endif +#ifdef TT_CONFIG_OPTION_COLOR_LAYERS +#define PUT_COLOR_LAYERS( a ) a +#else +#define PUT_COLOR_LAYERS( a ) NULL +#endif + #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES #define PUT_PS_NAMES( a ) a #else @@ -1256,9 +1258,24 @@ /* TT_Free_Table_Func free_eblc */ PUT_EMBEDDED_BITMAPS( tt_face_set_sbit_strike ), - /* TT_Set_SBit_Strike_Func set_sbit_strike */ + /* TT_Set_SBit_Strike_Func set_sbit_strike */ PUT_EMBEDDED_BITMAPS( tt_face_load_strike_metrics ), - /* TT_Load_Strike_Metrics_Func load_strike_metrics */ + /* TT_Load_Strike_Metrics_Func load_strike_metrics */ + + PUT_COLOR_LAYERS( tt_face_load_cpal ), + /* TT_Load_Table_Func load_cpal */ + PUT_COLOR_LAYERS( tt_face_load_colr ), + /* TT_Load_Table_Func load_colr */ + PUT_COLOR_LAYERS( tt_face_free_cpal ), + /* TT_Free_Table_Func free_cpal */ + PUT_COLOR_LAYERS( tt_face_free_colr ), + /* TT_Free_Table_Func free_colr */ + PUT_COLOR_LAYERS( tt_face_palette_set ), + /* TT_Set_Palette_Func set_palette */ + PUT_COLOR_LAYERS( tt_face_get_colr_layer ), + /* TT_Get_Colr_Layer_Func get_colr_layer */ + PUT_COLOR_LAYERS( tt_face_colr_blend_layer ), + /* TT_Blend_Colr_Func colr_blend */ tt_face_get_metrics, /* TT_Get_Metrics_Func get_metrics */ @@ -1277,7 +1294,7 @@ 0x10000L, /* driver version 1.0 */ 0x20000L, /* driver requires FreeType 2.0 or higher */ - (const void*)&SFNT_INTERFACE_GET, /* module specific interface */ + (const void*)&sfnt_interface, /* module specific interface */ (FT_Module_Constructor)NULL, /* module_init */ (FT_Module_Destructor) NULL, /* module_done */ diff --git a/sdk/lib/3rdparty/freetype/src/sfnt/sfdriver.h b/sdk/lib/3rdparty/freetype/src/sfnt/sfdriver.h index 81c22d28870f1..8c174634b3786 100644 --- a/sdk/lib/3rdparty/freetype/src/sfnt/sfdriver.h +++ b/sdk/lib/3rdparty/freetype/src/sfnt/sfdriver.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* sfdriver.h */ -/* */ -/* High-level SFNT driver interface (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * sfdriver.h + * + * High-level SFNT driver interface (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef SFDRIVER_H_ @@ -26,10 +26,8 @@ FT_BEGIN_HEADER - FT_DECLARE_MODULE( sfnt_module_class ) - FT_END_HEADER #endif /* SFDRIVER_H_ */ diff --git a/sdk/lib/3rdparty/freetype/src/sfnt/sferrors.h b/sdk/lib/3rdparty/freetype/src/sfnt/sferrors.h index 74003d4b38c6c..43e148d2954ec 100644 --- a/sdk/lib/3rdparty/freetype/src/sfnt/sferrors.h +++ b/sdk/lib/3rdparty/freetype/src/sfnt/sferrors.h @@ -1,26 +1,26 @@ -/***************************************************************************/ -/* */ -/* sferrors.h */ -/* */ -/* SFNT error codes (specification only). */ -/* */ -/* Copyright 2001-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to define the SFNT error enumeration constants. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * sferrors.h + * + * SFNT error codes (specification only). + * + * Copyright (C) 2001-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /************************************************************************** + * + * This file is used to define the SFNT error enumeration constants. + * + */ #ifndef SFERRORS_H_ #define SFERRORS_H_ diff --git a/sdk/lib/3rdparty/freetype/src/sfnt/sfnt.c b/sdk/lib/3rdparty/freetype/src/sfnt/sfnt.c index 8b9a6b345df1b..5a503f30c54b6 100644 --- a/sdk/lib/3rdparty/freetype/src/sfnt/sfnt.c +++ b/sdk/lib/3rdparty/freetype/src/sfnt/sfnt.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* sfnt.c */ -/* */ -/* Single object library component. */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * sfnt.c + * + * Single object library component. + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #define FT_MAKE_OPTION_SINGLE_OBJECT @@ -21,10 +21,12 @@ #include "pngshim.c" #include "sfdriver.c" -#include "sfntpic.c" #include "sfobjs.c" #include "ttbdf.c" #include "ttcmap.c" +#include "ttcolr.c" +#include "ttcpal.c" + #include "ttkern.c" #include "ttload.c" #include "ttmtx.c" diff --git a/sdk/lib/3rdparty/freetype/src/sfnt/sfntpic.c b/sdk/lib/3rdparty/freetype/src/sfnt/sfntpic.c deleted file mode 100644 index db2d816ce68c1..0000000000000 --- a/sdk/lib/3rdparty/freetype/src/sfnt/sfntpic.c +++ /dev/null @@ -1,143 +0,0 @@ -/***************************************************************************/ -/* */ -/* sfntpic.c */ -/* */ -/* The FreeType position independent code services for sfnt module. */ -/* */ -/* Copyright 2009-2018 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_FREETYPE_H -#include FT_INTERNAL_OBJECTS_H -#include "sfntpic.h" -#include "sferrors.h" - - -#ifdef FT_CONFIG_OPTION_PIC - - /* forward declaration of PIC init functions from sfdriver.c */ - FT_Error - FT_Create_Class_sfnt_services( FT_Library library, - FT_ServiceDescRec** output_class ); - void - FT_Destroy_Class_sfnt_services( FT_Library library, - FT_ServiceDescRec* clazz ); - void - FT_Init_Class_sfnt_service_bdf( FT_Service_BDFRec* clazz ); - void - FT_Init_Class_sfnt_interface( FT_Library library, - SFNT_Interface* clazz ); - void - FT_Init_Class_sfnt_service_glyph_dict( - FT_Library library, - FT_Service_GlyphDictRec* clazz ); - void - FT_Init_Class_sfnt_service_ps_name( - FT_Library library, - FT_Service_PsFontNameRec* clazz ); - void - FT_Init_Class_tt_service_get_cmap_info( - FT_Library library, - FT_Service_TTCMapsRec* clazz ); - void - FT_Init_Class_sfnt_service_sfnt_table( - FT_Service_SFNT_TableRec* clazz ); - - - /* forward declaration of PIC init functions from ttcmap.c */ - FT_Error - FT_Create_Class_tt_cmap_classes( FT_Library library, - TT_CMap_Class** output_class ); - void - FT_Destroy_Class_tt_cmap_classes( FT_Library library, - TT_CMap_Class* clazz ); - - - void - sfnt_module_class_pic_free( FT_Library library ) - { - FT_PIC_Container* pic_container = &library->pic_container; - FT_Memory memory = library->memory; - - - if ( pic_container->sfnt ) - { - sfntModulePIC* container = (sfntModulePIC*)pic_container->sfnt; - - - if ( container->sfnt_services ) - FT_Destroy_Class_sfnt_services( library, - container->sfnt_services ); - container->sfnt_services = NULL; - - if ( container->tt_cmap_classes ) - FT_Destroy_Class_tt_cmap_classes( library, - container->tt_cmap_classes ); - container->tt_cmap_classes = NULL; - - FT_FREE( container ); - pic_container->sfnt = NULL; - } - } - - - FT_Error - sfnt_module_class_pic_init( FT_Library library ) - { - FT_PIC_Container* pic_container = &library->pic_container; - FT_Error error = FT_Err_Ok; - sfntModulePIC* container = NULL; - FT_Memory memory = library->memory; - - - /* allocate pointer, clear and set global container pointer */ - if ( FT_ALLOC( container, sizeof ( *container ) ) ) - return error; - FT_MEM_SET( container, 0, sizeof ( *container ) ); - pic_container->sfnt = container; - - /* initialize pointer table - */ - /* this is how the module usually expects this data */ - error = FT_Create_Class_sfnt_services( library, - &container->sfnt_services ); - if ( error ) - goto Exit; - - error = FT_Create_Class_tt_cmap_classes( library, - &container->tt_cmap_classes ); - if ( error ) - goto Exit; - - FT_Init_Class_sfnt_service_glyph_dict( - library, &container->sfnt_service_glyph_dict ); - FT_Init_Class_sfnt_service_ps_name( - library, &container->sfnt_service_ps_name ); - FT_Init_Class_tt_service_get_cmap_info( - library, &container->tt_service_get_cmap_info ); - FT_Init_Class_sfnt_service_sfnt_table( - &container->sfnt_service_sfnt_table ); -#ifdef TT_CONFIG_OPTION_BDF - FT_Init_Class_sfnt_service_bdf( &container->sfnt_service_bdf ); -#endif - FT_Init_Class_sfnt_interface( library, &container->sfnt_interface ); - - Exit: - if ( error ) - sfnt_module_class_pic_free( library ); - return error; - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - -/* END */ diff --git a/sdk/lib/3rdparty/freetype/src/sfnt/sfntpic.h b/sdk/lib/3rdparty/freetype/src/sfnt/sfntpic.h deleted file mode 100644 index 8f43122d81bf3..0000000000000 --- a/sdk/lib/3rdparty/freetype/src/sfnt/sfntpic.h +++ /dev/null @@ -1,112 +0,0 @@ -/***************************************************************************/ -/* */ -/* sfntpic.h */ -/* */ -/* The FreeType position independent code services for sfnt module. */ -/* */ -/* Copyright 2009-2018 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#ifndef SFNTPIC_H_ -#define SFNTPIC_H_ - - -#include FT_INTERNAL_PIC_H - - -#ifndef FT_CONFIG_OPTION_PIC - -#define SFNT_SERVICES_GET sfnt_services -#define SFNT_SERVICE_GLYPH_DICT_GET sfnt_service_glyph_dict -#define SFNT_SERVICE_PS_NAME_GET sfnt_service_ps_name -#define TT_SERVICE_CMAP_INFO_GET tt_service_get_cmap_info -#define TT_CMAP_CLASSES_GET tt_cmap_classes -#define SFNT_SERVICE_SFNT_TABLE_GET sfnt_service_sfnt_table -#define SFNT_SERVICE_BDF_GET sfnt_service_bdf -#define SFNT_INTERFACE_GET sfnt_interface - -#else /* FT_CONFIG_OPTION_PIC */ - - /* some include files required for members of sfntModulePIC */ -#include FT_SERVICE_GLYPH_DICT_H -#include FT_SERVICE_POSTSCRIPT_NAME_H -#include FT_SERVICE_SFNT_H -#include FT_SERVICE_TT_CMAP_H - -#ifdef TT_CONFIG_OPTION_BDF -#include "ttbdf.h" -#include FT_SERVICE_BDF_H -#endif - -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H -#include FT_INTERNAL_SFNT_H -#include "ttcmap.h" - - -FT_BEGIN_HEADER - - typedef struct sfntModulePIC_ - { - FT_ServiceDescRec* sfnt_services; - FT_Service_GlyphDictRec sfnt_service_glyph_dict; - FT_Service_PsFontNameRec sfnt_service_ps_name; - FT_Service_TTCMapsRec tt_service_get_cmap_info; - TT_CMap_Class* tt_cmap_classes; - FT_Service_SFNT_TableRec sfnt_service_sfnt_table; -#ifdef TT_CONFIG_OPTION_BDF - FT_Service_BDFRec sfnt_service_bdf; -#endif - SFNT_Interface sfnt_interface; - - } sfntModulePIC; - - -#define GET_PIC( lib ) \ - ( (sfntModulePIC*)( (lib)->pic_container.sfnt ) ) - -#define SFNT_SERVICES_GET \ - ( GET_PIC( library )->sfnt_services ) -#define SFNT_SERVICE_GLYPH_DICT_GET \ - ( GET_PIC( library )->sfnt_service_glyph_dict ) -#define SFNT_SERVICE_PS_NAME_GET \ - ( GET_PIC( library )->sfnt_service_ps_name ) -#define TT_SERVICE_CMAP_INFO_GET \ - ( GET_PIC( library )->tt_service_get_cmap_info ) -#define TT_CMAP_CLASSES_GET \ - ( GET_PIC( library )->tt_cmap_classes ) -#define SFNT_SERVICE_SFNT_TABLE_GET \ - ( GET_PIC( library )->sfnt_service_sfnt_table ) -#define SFNT_SERVICE_BDF_GET \ - ( GET_PIC( library )->sfnt_service_bdf ) -#define SFNT_INTERFACE_GET \ - ( GET_PIC( library )->sfnt_interface ) - - - /* see sfntpic.c for the implementation */ - void - sfnt_module_class_pic_free( FT_Library library ); - - FT_Error - sfnt_module_class_pic_init( FT_Library library ); - - -FT_END_HEADER - -#endif /* FT_CONFIG_OPTION_PIC */ - - /* */ - -#endif /* SFNTPIC_H_ */ - - -/* END */ diff --git a/sdk/lib/3rdparty/freetype/src/sfnt/sfobjs.c b/sdk/lib/3rdparty/freetype/src/sfnt/sfobjs.c index 0c917030f37f9..0b43d251b87cf 100644 --- a/sdk/lib/3rdparty/freetype/src/sfnt/sfobjs.c +++ b/sdk/lib/3rdparty/freetype/src/sfnt/sfobjs.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* sfobjs.c */ -/* */ -/* SFNT object management (base). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * sfobjs.c + * + * SFNT object management (base). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -41,14 +41,14 @@ #endif - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_sfobjs +#define FT_COMPONENT sfobjs @@ -918,7 +918,9 @@ /* Stream may have changed in sfnt_open_font. */ stream = face->root.stream; - FT_TRACE2(( "sfnt_init_face: %08p, %d\n", face, face_instance_index )); + FT_TRACE2(( "sfnt_init_face: %08p (index %d)\n", + face, + face_instance_index )); face_index = FT_ABS( face_instance_index ) & 0xFFFF; @@ -1001,15 +1003,15 @@ face->variation_support |= TT_FACE_FLAG_VAR_FVAR; /* - * As documented in the OpenType specification, an entry for the - * default instance may be omitted in the named instance table. In - * particular this means that even if there is no named instance - * table in the font we actually do have a named instance, namely the - * default instance. + * As documented in the OpenType specification, an entry for the + * default instance may be omitted in the named instance table. In + * particular this means that even if there is no named instance + * table in the font we actually do have a named instance, namely the + * default instance. * - * For consistency, we always want the default instance in our list - * of named instances. If it is missing, we try to synthesize it - * later on. Here, we have to adjust `num_instances' accordingly. + * For consistency, we always want the default instance in our list + * of named instances. If it is missing, we try to synthesize it + * later on. Here, we have to adjust `num_instances' accordingly. */ if ( ( face->variation_support & TT_FACE_FLAG_VAR_FVAR ) && @@ -1144,6 +1146,8 @@ FT_Bool has_outline; FT_Bool is_apple_sbit; FT_Bool is_apple_sbix; + FT_Bool has_CBLC; + FT_Bool has_CBDT; FT_Bool ignore_typographic_family = FALSE; FT_Bool ignore_typographic_subfamily = FALSE; @@ -1224,6 +1228,13 @@ goto Exit; } + has_CBLC = !face->goto_table( face, TTAG_CBLC, stream, 0 ); + has_CBDT = !face->goto_table( face, TTAG_CBDT, stream, 0 ); + + /* Ignore outlines for CBLC/CBDT fonts. */ + if ( has_CBLC || has_CBDT ) + has_outline = FALSE; + /* OpenType 1.8.2 introduced limits to this value; */ /* however, they make sense for older SFNT fonts also */ if ( face->header.Units_Per_EM < 16 || @@ -1332,6 +1343,13 @@ if ( sfnt->load_eblc ) LOAD_( eblc ); + /* colored glyph support */ + if ( sfnt->load_cpal ) + { + LOAD_( cpal ); + LOAD_( colr ); + } + /* consider the pclt, kerning, and gasp tables as optional */ LOAD_( pclt ); LOAD_( gasp ); @@ -1380,12 +1398,13 @@ FT_Long flags = root->face_flags; - /*********************************************************************/ - /* */ - /* Compute face flags. */ - /* */ + /********************************************************************** + * + * Compute face flags. + */ if ( face->sbit_table_type == TT_SBIT_TABLE_TYPE_CBLC || - face->sbit_table_type == TT_SBIT_TABLE_TYPE_SBIX ) + face->sbit_table_type == TT_SBIT_TABLE_TYPE_SBIX || + face->colr ) flags |= FT_FACE_FLAG_COLOR; /* color glyphs */ if ( has_outline == TRUE ) @@ -1429,10 +1448,10 @@ root->face_flags = flags; - /*********************************************************************/ - /* */ - /* Compute style flags. */ - /* */ + /********************************************************************** + * + * Compute style flags. + */ flags = 0; if ( has_outline == TRUE && face->os2.version != 0xFFFFU ) @@ -1462,14 +1481,14 @@ root->style_flags |= flags; - /*********************************************************************/ - /* */ - /* Polish the charmaps. */ - /* */ - /* Try to set the charmap encoding according to the platform & */ - /* encoding ID of each charmap. Emulate Unicode charmap if one */ - /* is missing. */ - /* */ + /********************************************************************** + * + * Polish the charmaps. + * + * Try to set the charmap encoding according to the platform & + * encoding ID of each charmap. Emulate Unicode charmap if one + * is missing. + */ tt_face_build_cmaps( face ); /* ignore errors */ @@ -1512,7 +1531,8 @@ error = FT_CMap_New( (FT_CMap_Class)&tt_cmap_unicode_class_rec, NULL, &cmaprec, NULL ); if ( error && - FT_ERR_NEQ( error, No_Unicode_Glyph_Name ) ) + FT_ERR_NEQ( error, No_Unicode_Glyph_Name ) && + FT_ERR_NEQ( error, Unimplemented_Feature ) ) goto Exit; error = FT_Err_Ok; @@ -1524,9 +1544,9 @@ #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS /* - * Now allocate the root array of FT_Bitmap_Size records and - * populate them. Unfortunately, it isn't possible to indicate bit - * depths in the FT_Bitmap_Size record. This is a design error. + * Now allocate the root array of FT_Bitmap_Size records and + * populate them. Unfortunately, it isn't possible to indicate bit + * depths in the FT_Bitmap_Size record. This is a design error. */ { FT_UInt count; @@ -1606,10 +1626,10 @@ root->face_flags |= FT_FACE_FLAG_SCALABLE; - /*********************************************************************/ - /* */ - /* Set up metrics. */ - /* */ + /********************************************************************** + * + * Set up metrics. + */ if ( FT_IS_SCALABLE( root ) ) { /* XXX What about if outline header is missing */ @@ -1621,59 +1641,73 @@ root->units_per_EM = face->header.Units_Per_EM; - /* XXX: Computing the ascender/descender/height is very different */ - /* from what the specification tells you. Apparently, we */ - /* must be careful because */ - /* */ - /* - not all fonts have an OS/2 table; in this case, we take */ - /* the values in the horizontal header. However, these */ - /* values very often are not reliable. */ - /* */ - /* - otherwise, the correct typographic values are in the */ - /* sTypoAscender, sTypoDescender & sTypoLineGap fields. */ - /* */ - /* However, certain fonts have these fields set to 0. */ - /* Rather, they have usWinAscent & usWinDescent correctly */ - /* set (but with different values). */ - /* */ - /* As an example, Arial Narrow is implemented through four */ - /* files ARIALN.TTF, ARIALNI.TTF, ARIALNB.TTF & ARIALNBI.TTF */ - /* */ - /* Strangely, all fonts have the same values in their */ - /* sTypoXXX fields, except ARIALNB which sets them to 0. */ - /* */ - /* On the other hand, they all have different */ - /* usWinAscent/Descent values -- as a conclusion, the OS/2 */ - /* table cannot be used to compute the text height reliably! */ - /* */ - - /* The ascender and descender are taken from the `hhea' table. */ - /* If zero, they are taken from the `OS/2' table. */ - - root->ascender = face->horizontal.Ascender; - root->descender = face->horizontal.Descender; - - root->height = root->ascender - root->descender + - face->horizontal.Line_Gap; - - if ( !( root->ascender || root->descender ) ) + /* + * Computing the ascender/descender/height is tricky. + * + * The OpenType specification v1.8.3 says: + * + * [OS/2's] sTypoAscender, sTypoDescender and sTypoLineGap fields + * are intended to allow applications to lay out documents in a + * typographically-correct and portable fashion. + * + * This is somewhat at odds with the decades of backwards + * compatibility, operating systems and applications doing whatever + * they want, not to mention broken fonts. + * + * Not all fonts have an OS/2 table; in this case, we take the values + * in the horizontal header, although there is nothing stopping the + * values from being unreliable. Even with a OS/2 table, certain fonts + * set the sTypoAscender, sTypoDescender and sTypoLineGap fields to 0 + * and instead correctly set usWinAscent and usWinDescent. + * + * As an example, Arial Narrow is shipped as four files ARIALN.TTF, + * ARIALNI.TTF, ARIALNB.TTF and ARIALNBI.TTF. Strangely, all fonts have + * the same values in their sTypo* fields, except ARIALNB.ttf which + * sets them to 0. All of them have different usWinAscent/Descent + * values. The OS/2 table therefore cannot be trusted for computing the + * text height reliably. + * + * As a compromise, do the following: + * + * 1. If the OS/2 table exists and the fsSelection bit 7 is set + * (USE_TYPO_METRICS), trust the font and use the sTypo* metrics. + * 2. Otherwise, use the `hhea' table's metrics. + * 3. If they are zero and the OS/2 table exists, + * 1. use the OS/2 table's sTypo* metrics if they are non-zero. + * 2. Otherwise, use the OS/2 table's usWin* metrics. + */ + + if ( face->os2.version != 0xFFFFU && face->os2.fsSelection & 128 ) { - if ( face->os2.version != 0xFFFFU ) - { - if ( face->os2.sTypoAscender || face->os2.sTypoDescender ) - { - root->ascender = face->os2.sTypoAscender; - root->descender = face->os2.sTypoDescender; + root->ascender = face->os2.sTypoAscender; + root->descender = face->os2.sTypoDescender; + root->height = root->ascender - root->descender + + face->os2.sTypoLineGap; + } + else + { + root->ascender = face->horizontal.Ascender; + root->descender = face->horizontal.Descender; + root->height = root->ascender - root->descender + + face->horizontal.Line_Gap; - root->height = root->ascender - root->descender + - face->os2.sTypoLineGap; - } - else + if ( !( root->ascender || root->descender ) ) + { + if ( face->os2.version != 0xFFFFU ) { - root->ascender = (FT_Short)face->os2.usWinAscent; - root->descender = -(FT_Short)face->os2.usWinDescent; - - root->height = root->ascender - root->descender; + if ( face->os2.sTypoAscender || face->os2.sTypoDescender ) + { + root->ascender = face->os2.sTypoAscender; + root->descender = face->os2.sTypoDescender; + root->height = root->ascender - root->descender + + face->os2.sTypoLineGap; + } + else + { + root->ascender = (FT_Short)face->os2.usWinAscent; + root->descender = -(FT_Short)face->os2.usWinDescent; + root->height = root->ascender - root->descender; + } } } } @@ -1728,6 +1762,13 @@ /* destroy the embedded bitmaps table if it is loaded */ if ( sfnt->free_eblc ) sfnt->free_eblc( face ); + + /* destroy color table data if it is loaded */ + if ( sfnt->free_cpal ) + { + sfnt->free_cpal( face ); + sfnt->free_colr( face ); + } } #ifdef TT_CONFIG_OPTION_BDF @@ -1783,11 +1824,18 @@ FT_FREE( face->sbit_strike_map ); face->root.num_fixed_sizes = 0; -#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT FT_FREE( face->postscript_name ); + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT FT_FREE( face->var_postscript_prefix ); #endif + /* freeing glyph color palette data */ + FT_FREE( face->palette_data.palette_name_ids ); + FT_FREE( face->palette_data.palette_flags ); + FT_FREE( face->palette_data.palette_entry_name_ids ); + FT_FREE( face->palette ); + face->sfnt = NULL; } diff --git a/sdk/lib/3rdparty/freetype/src/sfnt/sfobjs.h b/sdk/lib/3rdparty/freetype/src/sfnt/sfobjs.h index 1b8d1be5b1a8b..17b0d50105e42 100644 --- a/sdk/lib/3rdparty/freetype/src/sfnt/sfobjs.h +++ b/sdk/lib/3rdparty/freetype/src/sfnt/sfobjs.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* sfobjs.h */ -/* */ -/* SFNT object management (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * sfobjs.h + * + * SFNT object management (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef SFOBJS_H_ diff --git a/sdk/lib/3rdparty/freetype/src/sfnt/ttbdf.c b/sdk/lib/3rdparty/freetype/src/sfnt/ttbdf.c index 534201f229f9b..853599fc43c7d 100644 --- a/sdk/lib/3rdparty/freetype/src/sfnt/ttbdf.c +++ b/sdk/lib/3rdparty/freetype/src/sfnt/ttbdf.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ttbdf.c */ -/* */ -/* TrueType and OpenType embedded BDF properties (body). */ -/* */ -/* Copyright 2005-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ttbdf.c + * + * TrueType and OpenType embedded BDF properties (body). + * + * Copyright (C) 2005-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -27,14 +27,14 @@ #ifdef TT_CONFIG_OPTION_BDF - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_ttbdf +#define FT_COMPONENT ttbdf FT_LOCAL_DEF( void ) @@ -45,7 +45,7 @@ if ( bdf->loaded ) { - FT_Stream stream = FT_FACE(face)->stream; + FT_Stream stream = FT_FACE( face )->stream; if ( bdf->table ) @@ -111,8 +111,8 @@ FT_UInt num_items = FT_PEEK_USHORT( p + 2 ); /* - * We don't need to check the value sets themselves, since this - * is done later. + * We don't need to check the value sets themselves, since this + * is done later. */ strike += 10 * num_items; @@ -142,7 +142,7 @@ BDF_PropertyRec *aprop ) { TT_BDF bdf = &face->bdf; - FT_Size size = FT_FACE(face)->size; + FT_Size size = FT_FACE( face )->size; FT_Error error = FT_Err_Ok; FT_Byte* p; FT_UInt count; diff --git a/sdk/lib/3rdparty/freetype/src/sfnt/ttbdf.h b/sdk/lib/3rdparty/freetype/src/sfnt/ttbdf.h index 809a663001174..e4164e61fc7eb 100644 --- a/sdk/lib/3rdparty/freetype/src/sfnt/ttbdf.h +++ b/sdk/lib/3rdparty/freetype/src/sfnt/ttbdf.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ttbdf.h */ -/* */ -/* TrueType and OpenType embedded BDF properties (specification). */ -/* */ -/* Copyright 2005-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ttbdf.h + * + * TrueType and OpenType embedded BDF properties (specification). + * + * Copyright (C) 2005-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef TTBDF_H_ diff --git a/sdk/lib/3rdparty/freetype/src/sfnt/ttcmap.c b/sdk/lib/3rdparty/freetype/src/sfnt/ttcmap.c index 8cc70f759af63..8d9737310c729 100644 --- a/sdk/lib/3rdparty/freetype/src/sfnt/ttcmap.c +++ b/sdk/lib/3rdparty/freetype/src/sfnt/ttcmap.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ttcmap.c */ -/* */ -/* TrueType character mapping table (cmap) support (body). */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ttcmap.c + * + * TrueType character mapping table (cmap) support (body). + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -27,17 +27,16 @@ #include "ttload.h" #include "ttcmap.h" #include "ttpost.h" -#include "sfntpic.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_ttcmap +#define FT_COMPONENT ttcmap #define TT_PEEK_SHORT FT_PEEK_SHORT @@ -77,19 +76,19 @@ /*************************************************************************/ /*************************************************************************/ - /*************************************************************************/ - /* */ - /* TABLE OVERVIEW */ - /* -------------- */ - /* */ - /* NAME OFFSET TYPE DESCRIPTION */ - /* */ - /* format 0 USHORT must be 0 */ - /* length 2 USHORT table length in bytes */ - /* language 4 USHORT Mac language code */ - /* glyph_ids 6 BYTE[256] array of glyph indices */ - /* 262 */ - /* */ + /************************************************************************** + * + * TABLE OVERVIEW + * -------------- + * + * NAME OFFSET TYPE DESCRIPTION + * + * format 0 USHORT must be 0 + * length 2 USHORT table length in bytes + * language 4 USHORT Mac language code + * glyph_ids 6 BYTE[256] array of glyph indices + * 262 + */ #ifdef TT_CONFIG_CMAP_FORMAT_0 @@ -222,10 +221,10 @@ /***** The following charmap lookup and iteration functions all *****/ /***** assume that the value `charcode' fulfills the following. *****/ /***** *****/ - /***** - For one byte characters, `charcode' is simply the *****/ + /***** - For one-byte characters, `charcode' is simply the *****/ /***** character code. *****/ /***** *****/ - /***** - For two byte characters, `charcode' is the 2-byte *****/ + /***** - For two-byte characters, `charcode' is the 2-byte *****/ /***** character code in big endian format. More precisely: *****/ /***** *****/ /***** (charcode >> 8) is the first byte value *****/ @@ -238,57 +237,57 @@ /*************************************************************************/ /*************************************************************************/ - /*************************************************************************/ - /* */ - /* TABLE OVERVIEW */ - /* -------------- */ - /* */ - /* NAME OFFSET TYPE DESCRIPTION */ - /* */ - /* format 0 USHORT must be 2 */ - /* length 2 USHORT table length in bytes */ - /* language 4 USHORT Mac language code */ - /* keys 6 USHORT[256] sub-header keys */ - /* subs 518 SUBHEAD[NSUBS] sub-headers array */ - /* glyph_ids 518+NSUB*8 USHORT[] glyph ID array */ - /* */ - /* The `keys' table is used to map charcode high-bytes to sub-headers. */ - /* The value of `NSUBS' is the number of sub-headers defined in the */ - /* table and is computed by finding the maximum of the `keys' table. */ - /* */ - /* Note that for any n, `keys[n]' is a byte offset within the `subs' */ - /* table, i.e., it is the corresponding sub-header index multiplied */ - /* by 8. */ - /* */ - /* Each sub-header has the following format. */ - /* */ - /* NAME OFFSET TYPE DESCRIPTION */ - /* */ - /* first 0 USHORT first valid low-byte */ - /* count 2 USHORT number of valid low-bytes */ - /* delta 4 SHORT see below */ - /* offset 6 USHORT see below */ - /* */ - /* A sub-header defines, for each high-byte, the range of valid */ - /* low-bytes within the charmap. Note that the range defined by `first' */ - /* and `count' must be completely included in the interval [0..255] */ - /* according to the specification. */ - /* */ - /* If a character code is contained within a given sub-header, then */ - /* mapping it to a glyph index is done as follows. */ - /* */ - /* * The value of `offset' is read. This is a _byte_ distance from the */ - /* location of the `offset' field itself into a slice of the */ - /* `glyph_ids' table. Let's call it `slice' (it is a USHORT[], too). */ - /* */ - /* * The value `slice[char.lo - first]' is read. If it is 0, there is */ - /* no glyph for the charcode. Otherwise, the value of `delta' is */ - /* added to it (modulo 65536) to form a new glyph index. */ - /* */ - /* It is up to the validation routine to check that all offsets fall */ - /* within the glyph IDs table (and not within the `subs' table itself or */ - /* outside of the CMap). */ - /* */ + /************************************************************************** + * + * TABLE OVERVIEW + * -------------- + * + * NAME OFFSET TYPE DESCRIPTION + * + * format 0 USHORT must be 2 + * length 2 USHORT table length in bytes + * language 4 USHORT Mac language code + * keys 6 USHORT[256] sub-header keys + * subs 518 SUBHEAD[NSUBS] sub-headers array + * glyph_ids 518+NSUB*8 USHORT[] glyph ID array + * + * The `keys' table is used to map charcode high bytes to sub-headers. + * The value of `NSUBS' is the number of sub-headers defined in the + * table and is computed by finding the maximum of the `keys' table. + * + * Note that for any `n', `keys[n]' is a byte offset within the `subs' + * table, i.e., it is the corresponding sub-header index multiplied + * by 8. + * + * Each sub-header has the following format. + * + * NAME OFFSET TYPE DESCRIPTION + * + * first 0 USHORT first valid low-byte + * count 2 USHORT number of valid low-bytes + * delta 4 SHORT see below + * offset 6 USHORT see below + * + * A sub-header defines, for each high byte, the range of valid + * low bytes within the charmap. Note that the range defined by `first' + * and `count' must be completely included in the interval [0..255] + * according to the specification. + * + * If a character code is contained within a given sub-header, then + * mapping it to a glyph index is done as follows. + * + * - The value of `offset' is read. This is a _byte_ distance from the + * location of the `offset' field itself into a slice of the + * `glyph_ids' table. Let's call it `slice' (it is a USHORT[], too). + * + * - The value `slice[char.lo - first]' is read. If it is 0, there is + * no glyph for the charcode. Otherwise, the value of `delta' is + * added to it (modulo 65536) to form a new glyph index. + * + * It is up to the validation routine to check that all offsets fall + * within the glyph IDs table (and not within the `subs' table itself or + * outside of the CMap). + */ #ifdef TT_CONFIG_CMAP_FORMAT_2 @@ -360,7 +359,7 @@ /* check range within 0..255 */ if ( valid->level >= FT_VALIDATE_PARANOID ) { - if ( first_code >= 256 || first_code + code_count > 256 ) + if ( first_code >= 256 || code_count > 256 - first_code ) FT_INVALID_DATA; } @@ -412,7 +411,7 @@ { FT_UInt char_lo = (FT_UInt)( char_code & 0xFF ); FT_UInt char_hi = (FT_UInt)( char_code >> 8 ); - FT_Byte* p = table + 6; /* keys table */ + FT_Byte* p = table + 6; /* keys table */ FT_Byte* subs = table + 518; /* subheaders table */ FT_Byte* sub; @@ -425,8 +424,8 @@ sub = subs; /* jump to first sub-header */ /* check that the sub-header for this byte is 0, which */ - /* indicates that it is really a valid one-byte value */ - /* Otherwise, return 0 */ + /* indicates that it is really a valid one-byte value; */ + /* otherwise, return 0 */ /* */ p += char_lo * 2; if ( TT_PEEK_USHORT( p ) != 0 ) @@ -445,6 +444,7 @@ if ( sub == subs ) goto Exit; } + result = sub; } @@ -517,6 +517,13 @@ FT_UInt pos, idx; + if ( char_lo >= start + count && charcode <= 0xFF ) + { + /* this happens only for a malformed cmap */ + charcode = 0x100; + continue; + } + if ( offset == 0 ) { if ( charcode == 0x100 ) @@ -549,19 +556,18 @@ } } } + + /* if unsuccessful, avoid `charcode' leaving */ + /* the current 256-character block */ + if ( count ) + charcode--; } - /* If `charcode' is <= 0xFF, retry with `charcode + 1'. If */ - /* `charcode' is 0x100 after the loop, do nothing since we have */ - /* just reached the first sub-header for two-byte character codes. */ - /* */ - /* For all other cases, we jump to the next sub-header and adjust */ - /* `charcode' accordingly. */ + /* If `charcode' is <= 0xFF, retry with `charcode + 1'. */ + /* Otherwise jump to the next 256-character block and retry. */ Next_SubHeader: if ( charcode <= 0xFF ) charcode++; - else if ( charcode == 0x100 ) - ; else charcode = FT_PAD_FLOOR( charcode, 0x100 ) + 0x100; } @@ -619,68 +625,68 @@ /*************************************************************************/ /*************************************************************************/ - /*************************************************************************/ - /* */ - /* TABLE OVERVIEW */ - /* -------------- */ - /* */ - /* NAME OFFSET TYPE DESCRIPTION */ - /* */ - /* format 0 USHORT must be 4 */ - /* length 2 USHORT table length */ - /* in bytes */ - /* language 4 USHORT Mac language code */ - /* */ - /* segCountX2 6 USHORT 2*NUM_SEGS */ - /* searchRange 8 USHORT 2*(1 << LOG_SEGS) */ - /* entrySelector 10 USHORT LOG_SEGS */ - /* rangeShift 12 USHORT segCountX2 - */ - /* searchRange */ - /* */ - /* endCount 14 USHORT[NUM_SEGS] end charcode for */ - /* each segment; last */ - /* is 0xFFFF */ - /* */ - /* pad 14+NUM_SEGS*2 USHORT padding */ - /* */ - /* startCount 16+NUM_SEGS*2 USHORT[NUM_SEGS] first charcode for */ - /* each segment */ - /* */ - /* idDelta 16+NUM_SEGS*4 SHORT[NUM_SEGS] delta for each */ - /* segment */ - /* idOffset 16+NUM_SEGS*6 SHORT[NUM_SEGS] range offset for */ - /* each segment; can be */ - /* zero */ - /* */ - /* glyphIds 16+NUM_SEGS*8 USHORT[] array of glyph ID */ - /* ranges */ - /* */ - /* Character codes are modelled by a series of ordered (increasing) */ - /* intervals called segments. Each segment has start and end codes, */ - /* provided by the `startCount' and `endCount' arrays. Segments must */ - /* not overlap, and the last segment should always contain the value */ - /* 0xFFFF for `endCount'. */ - /* */ - /* The fields `searchRange', `entrySelector' and `rangeShift' are better */ - /* ignored (they are traces of over-engineering in the TrueType */ - /* specification). */ - /* */ - /* Each segment also has a signed `delta', as well as an optional offset */ - /* within the `glyphIds' table. */ - /* */ - /* If a segment's idOffset is 0, the glyph index corresponding to any */ - /* charcode within the segment is obtained by adding the value of */ - /* `idDelta' directly to the charcode, modulo 65536. */ - /* */ - /* Otherwise, a glyph index is taken from the glyph IDs sub-array for */ - /* the segment, and the value of `idDelta' is added to it. */ - /* */ - /* */ - /* Finally, note that a lot of fonts contain an invalid last segment, */ - /* where `start' and `end' are correctly set to 0xFFFF but both `delta' */ - /* and `offset' are incorrect (e.g., `opens___.ttf' which comes with */ - /* OpenOffice.org). We need special code to deal with them correctly. */ - /* */ + /************************************************************************** + * + * TABLE OVERVIEW + * -------------- + * + * NAME OFFSET TYPE DESCRIPTION + * + * format 0 USHORT must be 4 + * length 2 USHORT table length + * in bytes + * language 4 USHORT Mac language code + * + * segCountX2 6 USHORT 2*NUM_SEGS + * searchRange 8 USHORT 2*(1 << LOG_SEGS) + * entrySelector 10 USHORT LOG_SEGS + * rangeShift 12 USHORT segCountX2 - + * searchRange + * + * endCount 14 USHORT[NUM_SEGS] end charcode for + * each segment; last + * is 0xFFFF + * + * pad 14+NUM_SEGS*2 USHORT padding + * + * startCount 16+NUM_SEGS*2 USHORT[NUM_SEGS] first charcode for + * each segment + * + * idDelta 16+NUM_SEGS*4 SHORT[NUM_SEGS] delta for each + * segment + * idOffset 16+NUM_SEGS*6 SHORT[NUM_SEGS] range offset for + * each segment; can be + * zero + * + * glyphIds 16+NUM_SEGS*8 USHORT[] array of glyph ID + * ranges + * + * Character codes are modelled by a series of ordered (increasing) + * intervals called segments. Each segment has start and end codes, + * provided by the `startCount' and `endCount' arrays. Segments must + * not overlap, and the last segment should always contain the value + * 0xFFFF for `endCount'. + * + * The fields `searchRange', `entrySelector' and `rangeShift' are better + * ignored (they are traces of over-engineering in the TrueType + * specification). + * + * Each segment also has a signed `delta', as well as an optional offset + * within the `glyphIds' table. + * + * If a segment's idOffset is 0, the glyph index corresponding to any + * charcode within the segment is obtained by adding the value of + * `idDelta' directly to the charcode, modulo 65536. + * + * Otherwise, a glyph index is taken from the glyph IDs sub-array for + * the segment, and the value of `idDelta' is added to it. + * + * + * Finally, note that a lot of fonts contain an invalid last segment, + * where `start' and `end' are correctly set to 0xFFFF but both `delta' + * and `offset' are incorrect (e.g., `opens___.ttf' which comes with + * OpenOffice.org). We need special code to deal with them correctly. + */ #ifdef TT_CONFIG_CMAP_FORMAT_4 @@ -1566,23 +1572,23 @@ /*************************************************************************/ /*************************************************************************/ - /*************************************************************************/ - /* */ - /* TABLE OVERVIEW */ - /* -------------- */ - /* */ - /* NAME OFFSET TYPE DESCRIPTION */ - /* */ - /* format 0 USHORT must be 6 */ - /* length 2 USHORT table length in bytes */ - /* language 4 USHORT Mac language code */ - /* */ - /* first 6 USHORT first segment code */ - /* count 8 USHORT segment size in chars */ - /* glyphIds 10 USHORT[count] glyph IDs */ - /* */ - /* A very simplified segment mapping. */ - /* */ + /************************************************************************** + * + * TABLE OVERVIEW + * -------------- + * + * NAME OFFSET TYPE DESCRIPTION + * + * format 0 USHORT must be 6 + * length 2 USHORT table length in bytes + * language 4 USHORT Mac language code + * + * first 6 USHORT first segment code + * count 8 USHORT segment size in chars + * glyphIds 10 USHORT[count] glyph IDs + * + * A very simplified segment mapping. + */ #ifdef TT_CONFIG_CMAP_FORMAT_6 @@ -1761,26 +1767,26 @@ /*************************************************************************/ /*************************************************************************/ - /*************************************************************************/ - /* */ - /* TABLE OVERVIEW */ - /* -------------- */ - /* */ - /* NAME OFFSET TYPE DESCRIPTION */ - /* */ - /* format 0 USHORT must be 8 */ - /* reserved 2 USHORT reserved */ - /* length 4 ULONG length in bytes */ - /* language 8 ULONG Mac language code */ - /* is32 12 BYTE[8192] 32-bitness bitmap */ - /* count 8204 ULONG number of groups */ - /* */ - /* This header is followed by `count' groups of the following format: */ - /* */ - /* start 0 ULONG first charcode */ - /* end 4 ULONG last charcode */ - /* startId 8 ULONG start glyph ID for the group */ - /* */ + /************************************************************************** + * + * TABLE OVERVIEW + * -------------- + * + * NAME OFFSET TYPE DESCRIPTION + * + * format 0 USHORT must be 8 + * reserved 2 USHORT reserved + * length 4 ULONG length in bytes + * language 8 ULONG Mac language code + * is32 12 BYTE[8192] 32-bitness bitmap + * count 8204 ULONG number of groups + * + * This header is followed by `count' groups of the following format: + * + * start 0 ULONG first charcode + * end 4 ULONG last charcode + * startId 8 ULONG start glyph ID for the group + */ #ifdef TT_CONFIG_CMAP_FORMAT_8 @@ -2030,22 +2036,22 @@ /*************************************************************************/ /*************************************************************************/ - /*************************************************************************/ - /* */ - /* TABLE OVERVIEW */ - /* -------------- */ - /* */ - /* NAME OFFSET TYPE DESCRIPTION */ - /* */ - /* format 0 USHORT must be 10 */ - /* reserved 2 USHORT reserved */ - /* length 4 ULONG length in bytes */ - /* language 8 ULONG Mac language code */ - /* */ - /* start 12 ULONG first char in range */ - /* count 16 ULONG number of chars in range */ - /* glyphIds 20 USHORT[count] glyph indices covered */ - /* */ + /************************************************************************** + * + * TABLE OVERVIEW + * -------------- + * + * NAME OFFSET TYPE DESCRIPTION + * + * format 0 USHORT must be 10 + * reserved 2 USHORT reserved + * length 4 ULONG length in bytes + * language 8 ULONG Mac language code + * + * start 12 ULONG first char in range + * count 16 ULONG number of chars in range + * glyphIds 20 USHORT[count] glyph indices covered + */ #ifdef TT_CONFIG_CMAP_FORMAT_10 @@ -2202,26 +2208,26 @@ /*************************************************************************/ /*************************************************************************/ - /*************************************************************************/ - /* */ - /* TABLE OVERVIEW */ - /* -------------- */ - /* */ - /* NAME OFFSET TYPE DESCRIPTION */ - /* */ - /* format 0 USHORT must be 12 */ - /* reserved 2 USHORT reserved */ - /* length 4 ULONG length in bytes */ - /* language 8 ULONG Mac language code */ - /* count 12 ULONG number of groups */ - /* 16 */ - /* */ - /* This header is followed by `count' groups of the following format: */ - /* */ - /* start 0 ULONG first charcode */ - /* end 4 ULONG last charcode */ - /* startId 8 ULONG start glyph ID for the group */ - /* */ + /************************************************************************** + * + * TABLE OVERVIEW + * -------------- + * + * NAME OFFSET TYPE DESCRIPTION + * + * format 0 USHORT must be 12 + * reserved 2 USHORT reserved + * length 4 ULONG length in bytes + * language 8 ULONG Mac language code + * count 12 ULONG number of groups + * 16 + * + * This header is followed by `count' groups of the following format: + * + * start 0 ULONG first charcode + * end 4 ULONG last charcode + * startId 8 ULONG start glyph ID for the group + */ #ifdef TT_CONFIG_CMAP_FORMAT_12 @@ -2558,26 +2564,26 @@ /*************************************************************************/ /*************************************************************************/ - /*************************************************************************/ - /* */ - /* TABLE OVERVIEW */ - /* -------------- */ - /* */ - /* NAME OFFSET TYPE DESCRIPTION */ - /* */ - /* format 0 USHORT must be 13 */ - /* reserved 2 USHORT reserved */ - /* length 4 ULONG length in bytes */ - /* language 8 ULONG Mac language code */ - /* count 12 ULONG number of groups */ - /* 16 */ - /* */ - /* This header is followed by `count' groups of the following format: */ - /* */ - /* start 0 ULONG first charcode */ - /* end 4 ULONG last charcode */ - /* glyphId 8 ULONG glyph ID for the whole group */ - /* */ + /************************************************************************** + * + * TABLE OVERVIEW + * -------------- + * + * NAME OFFSET TYPE DESCRIPTION + * + * format 0 USHORT must be 13 + * reserved 2 USHORT reserved + * length 4 ULONG length in bytes + * language 8 ULONG Mac language code + * count 12 ULONG number of groups + * 16 + * + * This header is followed by `count' groups of the following format: + * + * start 0 ULONG first charcode + * end 4 ULONG last charcode + * glyphId 8 ULONG glyph ID for the whole group + */ #ifdef TT_CONFIG_CMAP_FORMAT_13 @@ -2884,58 +2890,59 @@ /*************************************************************************/ /*************************************************************************/ - /*************************************************************************/ - /* */ - /* TABLE OVERVIEW */ - /* -------------- */ - /* */ - /* NAME OFFSET TYPE DESCRIPTION */ - /* */ - /* format 0 USHORT must be 14 */ - /* length 2 ULONG table length in bytes */ - /* numSelector 6 ULONG number of variation sel. records */ - /* */ - /* Followed by numSelector records, each of which looks like */ - /* */ - /* varSelector 0 UINT24 Unicode codepoint of sel. */ - /* defaultOff 3 ULONG offset to a default UVS table */ - /* describing any variants to be found in */ - /* the normal Unicode subtable. */ - /* nonDefOff 7 ULONG offset to a non-default UVS table */ - /* describing any variants not in the */ - /* standard cmap, with GIDs here */ - /* (either offset may be 0 NULL) */ - /* */ - /* Selectors are sorted by code point. */ - /* */ - /* A default Unicode Variation Selector (UVS) subtable is just a list of */ - /* ranges of code points which are to be found in the standard cmap. No */ - /* glyph IDs (GIDs) here. */ - /* */ - /* numRanges 0 ULONG number of ranges following */ - /* */ - /* A range looks like */ - /* */ - /* uniStart 0 UINT24 code point of the first character in */ - /* this range */ - /* additionalCnt 3 UBYTE count of additional characters in this */ - /* range (zero means a range of a single */ - /* character) */ - /* */ - /* Ranges are sorted by `uniStart'. */ - /* */ - /* A non-default Unicode Variation Selector (UVS) subtable is a list of */ - /* mappings from codepoint to GID. */ - /* */ - /* numMappings 0 ULONG number of mappings */ - /* */ - /* A range looks like */ - /* */ - /* uniStart 0 UINT24 code point of the first character in */ - /* this range */ - /* GID 3 USHORT and its GID */ - /* */ - /* Ranges are sorted by `uniStart'. */ + /************************************************************************** + * + * TABLE OVERVIEW + * -------------- + * + * NAME OFFSET TYPE DESCRIPTION + * + * format 0 USHORT must be 14 + * length 2 ULONG table length in bytes + * numSelector 6 ULONG number of variation sel. records + * + * Followed by numSelector records, each of which looks like + * + * varSelector 0 UINT24 Unicode codepoint of sel. + * defaultOff 3 ULONG offset to a default UVS table + * describing any variants to be found in + * the normal Unicode subtable. + * nonDefOff 7 ULONG offset to a non-default UVS table + * describing any variants not in the + * standard cmap, with GIDs here + * (either offset may be 0 NULL) + * + * Selectors are sorted by code point. + * + * A default Unicode Variation Selector (UVS) subtable is just a list of + * ranges of code points which are to be found in the standard cmap. No + * glyph IDs (GIDs) here. + * + * numRanges 0 ULONG number of ranges following + * + * A range looks like + * + * uniStart 0 UINT24 code point of the first character in + * this range + * additionalCnt 3 UBYTE count of additional characters in this + * range (zero means a range of a single + * character) + * + * Ranges are sorted by `uniStart'. + * + * A non-default Unicode Variation Selector (UVS) subtable is a list of + * mappings from codepoint to GID. + * + * numMappings 0 ULONG number of mappings + * + * A range looks like + * + * uniStart 0 UINT24 code point of the first character in + * this range + * GID 3 USHORT and its GID + * + * Ranges are sorted by `uniStart'. + */ #ifdef TT_CONFIG_CMAP_FORMAT_14 @@ -3674,6 +3681,9 @@ FT_UNUSED( pointer ); + if ( !psnames->unicodes_init ) + return FT_THROW( Unimplemented_Feature ); + return psnames->unicodes_init( memory, unicodes, face->root.num_glyphs, @@ -3742,7 +3752,6 @@ #endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */ -#ifndef FT_CONFIG_OPTION_PIC static const TT_CMap_Class tt_cmap_classes[] = { @@ -3751,61 +3760,6 @@ NULL, }; -#else /*FT_CONFIG_OPTION_PIC*/ - - void - FT_Destroy_Class_tt_cmap_classes( FT_Library library, - TT_CMap_Class* clazz ) - { - FT_Memory memory = library->memory; - - - if ( clazz ) - FT_FREE( clazz ); - } - - - FT_Error - FT_Create_Class_tt_cmap_classes( FT_Library library, - TT_CMap_Class** output_class ) - { - TT_CMap_Class* clazz = NULL; - TT_CMap_ClassRec* recs; - FT_Error error; - FT_Memory memory = library->memory; - - int i = 0; - - -#define TTCMAPCITEM( a ) i++; -#include "ttcmapc.h" - - /* allocate enough space for both the pointers */ - /* plus terminator and the class instances */ - if ( FT_ALLOC( clazz, sizeof ( *clazz ) * ( i + 1 ) + - sizeof ( TT_CMap_ClassRec ) * i ) ) - return error; - - /* the location of the class instances follows the array of pointers */ - recs = (TT_CMap_ClassRec*)( (char*)clazz + - sizeof ( *clazz ) * ( i + 1 ) ); - i = 0; - -#undef TTCMAPCITEM -#define TTCMAPCITEM( a ) \ - FT_Init_Class_ ## a( &recs[i] ); \ - clazz[i] = &recs[i]; \ - i++; -#include "ttcmapc.h" - - clazz[i] = NULL; - - *output_class = clazz; - return FT_Err_Ok; - } - -#endif /*FT_CONFIG_OPTION_PIC*/ - /* parse the `cmap' table and build the corresponding TT_CMap objects */ /* in the current face */ @@ -3852,7 +3806,7 @@ { FT_Byte* volatile cmap = table + offset; volatile FT_UInt format = TT_PEEK_USHORT( cmap ); - const TT_CMap_Class* volatile pclazz = TT_CMAP_CLASSES_GET; + const TT_CMap_Class* volatile pclazz = tt_cmap_classes; TT_CMap_Class volatile clazz; diff --git a/sdk/lib/3rdparty/freetype/src/sfnt/ttcmap.h b/sdk/lib/3rdparty/freetype/src/sfnt/ttcmap.h index d264d99d2c993..36801c939eeed 100644 --- a/sdk/lib/3rdparty/freetype/src/sfnt/ttcmap.h +++ b/sdk/lib/3rdparty/freetype/src/sfnt/ttcmap.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ttcmap.h */ -/* */ -/* TrueType character mapping table (cmap) support (specification). */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ttcmap.h + * + * TrueType character mapping table (cmap) support (specification). + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef TTCMAP_H_ @@ -56,8 +56,6 @@ FT_BEGIN_HEADER } TT_CMap_ClassRec; -#ifndef FT_CONFIG_OPTION_PIC - #define FT_DEFINE_TT_CMAP( class_, \ size_, \ init_, \ @@ -92,42 +90,6 @@ FT_BEGIN_HEADER get_cmap_info_ \ }; -#else /* FT_CONFIG_OPTION_PIC */ - -#define FT_DEFINE_TT_CMAP( class_, \ - size_, \ - init_, \ - done_, \ - char_index_, \ - char_next_, \ - char_var_index_, \ - char_var_default_, \ - variant_list_, \ - charvariant_list_, \ - variantchar_list_, \ - format_, \ - validate_, \ - get_cmap_info_ ) \ - void \ - FT_Init_Class_ ## class_( TT_CMap_ClassRec* clazz ) \ - { \ - clazz->clazz.size = size_; \ - clazz->clazz.init = init_; \ - clazz->clazz.done = done_; \ - clazz->clazz.char_index = char_index_; \ - clazz->clazz.char_next = char_next_; \ - clazz->clazz.char_var_index = char_var_index_; \ - clazz->clazz.char_var_default = char_var_default_; \ - clazz->clazz.variant_list = variant_list_; \ - clazz->clazz.charvariant_list = charvariant_list_; \ - clazz->clazz.variantchar_list = variantchar_list_; \ - clazz->format = format_; \ - clazz->validate = validate_; \ - clazz->get_cmap_info = get_cmap_info_; \ - } - -#endif /* FT_CONFIG_OPTION_PIC */ - typedef struct TT_ValidatorRec_ { diff --git a/sdk/lib/3rdparty/freetype/src/sfnt/ttcmapc.h b/sdk/lib/3rdparty/freetype/src/sfnt/ttcmapc.h index 4980e9dd3dce7..ace9e69ca8da8 100644 --- a/sdk/lib/3rdparty/freetype/src/sfnt/ttcmapc.h +++ b/sdk/lib/3rdparty/freetype/src/sfnt/ttcmapc.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ttcmapc.h */ -/* */ -/* TT CMAP classes definitions (specification only). */ -/* */ -/* Copyright 2009-2018 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ttcmapc.h + * + * TT CMAP classes definitions (specification only). + * + * Copyright (C) 2009-2019 by + * Oran Agra and Mickey Gabel. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifdef TT_CONFIG_CMAP_FORMAT_0 diff --git a/sdk/lib/3rdparty/freetype/src/sfnt/ttcolr.c b/sdk/lib/3rdparty/freetype/src/sfnt/ttcolr.c new file mode 100644 index 0000000000000..6b537d95b8541 --- /dev/null +++ b/sdk/lib/3rdparty/freetype/src/sfnt/ttcolr.c @@ -0,0 +1,451 @@ +/**************************************************************************** + * + * ttcolr.c + * + * TrueType and OpenType colored glyph layer support (body). + * + * Copyright (C) 2018-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * Originally written by Shao Yu Zhang <shaozhang@fb.com>. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /************************************************************************** + * + * `COLR' table specification: + * + * https://www.microsoft.com/typography/otspec/colr.htm + * + */ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_TRUETYPE_TAGS_H +#include FT_COLOR_H + + +#ifdef TT_CONFIG_OPTION_COLOR_LAYERS + +#include "ttcolr.h" + + + /* NOTE: These are the table sizes calculated through the specs. */ +#define BASE_GLYPH_SIZE 6 +#define LAYER_SIZE 4 +#define COLR_HEADER_SIZE 14 + + + typedef struct BaseGlyphRecord_ + { + FT_UShort gid; + FT_UShort first_layer_index; + FT_UShort num_layers; + + } BaseGlyphRecord; + + + typedef struct Colr_ + { + FT_UShort version; + FT_UShort num_base_glyphs; + FT_UShort num_layers; + + FT_Byte* base_glyphs; + FT_Byte* layers; + + /* The memory which backs up the `COLR' table. */ + void* table; + FT_ULong table_size; + + } Colr; + + + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ +#undef FT_COMPONENT +#define FT_COMPONENT ttcolr + + + FT_LOCAL_DEF( FT_Error ) + tt_face_load_colr( TT_Face face, + FT_Stream stream ) + { + FT_Error error; + FT_Memory memory = face->root.memory; + + FT_Byte* table = NULL; + FT_Byte* p = NULL; + + Colr* colr = NULL; + + FT_ULong base_glyph_offset, layer_offset; + FT_ULong table_size; + + + /* `COLR' always needs `CPAL' */ + if ( !face->cpal ) + return FT_THROW( Invalid_File_Format ); + + error = face->goto_table( face, TTAG_COLR, stream, &table_size ); + if ( error ) + goto NoColr; + + if ( table_size < COLR_HEADER_SIZE ) + goto InvalidTable; + + if ( FT_FRAME_EXTRACT( table_size, table ) ) + goto NoColr; + + p = table; + + if ( FT_NEW( colr ) ) + goto NoColr; + + colr->version = FT_NEXT_USHORT( p ); + if ( colr->version != 0 ) + goto InvalidTable; + + colr->num_base_glyphs = FT_NEXT_USHORT( p ); + base_glyph_offset = FT_NEXT_ULONG( p ); + + if ( base_glyph_offset >= table_size ) + goto InvalidTable; + if ( colr->num_base_glyphs * BASE_GLYPH_SIZE > + table_size - base_glyph_offset ) + goto InvalidTable; + + layer_offset = FT_NEXT_ULONG( p ); + colr->num_layers = FT_NEXT_USHORT( p ); + + if ( layer_offset >= table_size ) + goto InvalidTable; + if ( colr->num_layers * LAYER_SIZE > table_size - layer_offset ) + goto InvalidTable; + + colr->base_glyphs = (FT_Byte*)( table + base_glyph_offset ); + colr->layers = (FT_Byte*)( table + layer_offset ); + colr->table = table; + colr->table_size = table_size; + + face->colr = colr; + + return FT_Err_Ok; + + InvalidTable: + error = FT_THROW( Invalid_Table ); + + NoColr: + FT_FRAME_RELEASE( table ); + FT_FREE( colr ); + + return error; + } + + + FT_LOCAL_DEF( void ) + tt_face_free_colr( TT_Face face ) + { + FT_Stream stream = face->root.stream; + FT_Memory memory = face->root.memory; + + Colr* colr = (Colr*)face->colr; + + + if ( colr ) + { + FT_FRAME_RELEASE( colr->table ); + FT_FREE( colr ); + } + } + + + static FT_Bool + find_base_glyph_record( FT_Byte* base_glyph_begin, + FT_Int num_base_glyph, + FT_UInt glyph_id, + BaseGlyphRecord* record ) + { + FT_Int min = 0; + FT_Int max = num_base_glyph - 1; + + + while ( min <= max ) + { + FT_Int mid = min + ( max - min ) / 2; + FT_Byte* p = base_glyph_begin + mid * BASE_GLYPH_SIZE; + + FT_UShort gid = FT_NEXT_USHORT( p ); + + + if ( gid < glyph_id ) + min = mid + 1; + else if (gid > glyph_id ) + max = mid - 1; + else + { + record->gid = gid; + record->first_layer_index = FT_NEXT_USHORT( p ); + record->num_layers = FT_NEXT_USHORT( p ); + + return 1; + } + } + + return 0; + } + + + FT_LOCAL_DEF( FT_Bool ) + tt_face_get_colr_layer( TT_Face face, + FT_UInt base_glyph, + FT_UInt *aglyph_index, + FT_UInt *acolor_index, + FT_LayerIterator* iterator ) + { + Colr* colr = (Colr*)face->colr; + BaseGlyphRecord glyph_record; + + + if ( !colr ) + return 0; + + if ( !iterator->p ) + { + FT_ULong offset; + + + /* first call to function */ + iterator->layer = 0; + + if ( !find_base_glyph_record( colr->base_glyphs, + colr->num_base_glyphs, + base_glyph, + &glyph_record ) ) + return 0; + + if ( glyph_record.num_layers ) + iterator->num_layers = glyph_record.num_layers; + else + return 0; + + offset = LAYER_SIZE * glyph_record.first_layer_index; + if ( offset + LAYER_SIZE * glyph_record.num_layers > colr->table_size ) + return 0; + + iterator->p = colr->layers + offset; + } + + if ( iterator->layer >= iterator->num_layers ) + return 0; + + *aglyph_index = FT_NEXT_USHORT( iterator->p ); + *acolor_index = FT_NEXT_USHORT( iterator->p ); + + if ( *aglyph_index >= (FT_UInt)( FT_FACE( face )->num_glyphs ) || + ( *acolor_index != 0xFFFF && + *acolor_index >= face->palette_data.num_palette_entries ) ) + return 0; + + iterator->layer++; + + return 1; + } + + + FT_LOCAL_DEF( FT_Error ) + tt_face_colr_blend_layer( TT_Face face, + FT_UInt color_index, + FT_GlyphSlot dstSlot, + FT_GlyphSlot srcSlot ) + { + FT_Error error; + + FT_UInt x, y; + FT_Byte b, g, r, alpha; + + FT_ULong size; + FT_Byte* src; + FT_Byte* dst; + + + if ( !dstSlot->bitmap.buffer ) + { + /* Initialize destination of color bitmap */ + /* with the size of first component. */ + dstSlot->bitmap_left = srcSlot->bitmap_left; + dstSlot->bitmap_top = srcSlot->bitmap_top; + + dstSlot->bitmap.width = srcSlot->bitmap.width; + dstSlot->bitmap.rows = srcSlot->bitmap.rows; + dstSlot->bitmap.pixel_mode = FT_PIXEL_MODE_BGRA; + dstSlot->bitmap.pitch = (int)dstSlot->bitmap.width * 4; + dstSlot->bitmap.num_grays = 256; + + size = dstSlot->bitmap.rows * (unsigned int)dstSlot->bitmap.pitch; + + error = ft_glyphslot_alloc_bitmap( dstSlot, size ); + if ( error ) + return error; + + FT_MEM_ZERO( dstSlot->bitmap.buffer, size ); + } + else + { + /* Resize destination if needed such that new component fits. */ + FT_Int x_min, x_max, y_min, y_max; + + + x_min = FT_MIN( dstSlot->bitmap_left, srcSlot->bitmap_left ); + x_max = FT_MAX( dstSlot->bitmap_left + (FT_Int)dstSlot->bitmap.width, + srcSlot->bitmap_left + (FT_Int)srcSlot->bitmap.width ); + + y_min = FT_MIN( dstSlot->bitmap_top - (FT_Int)dstSlot->bitmap.rows, + srcSlot->bitmap_top - (FT_Int)srcSlot->bitmap.rows ); + y_max = FT_MAX( dstSlot->bitmap_top, srcSlot->bitmap_top ); + + if ( x_min != dstSlot->bitmap_left || + x_max != dstSlot->bitmap_left + (FT_Int)dstSlot->bitmap.width || + y_min != dstSlot->bitmap_top - (FT_Int)dstSlot->bitmap.rows || + y_max != dstSlot->bitmap_top ) + { + FT_Memory memory = face->root.memory; + + FT_UInt width = (FT_UInt)( x_max - x_min ); + FT_UInt rows = (FT_UInt)( y_max - y_min ); + FT_UInt pitch = width * 4; + + FT_Byte* buf = NULL; + FT_Byte* p; + FT_Byte* q; + + + size = rows * pitch; + if ( FT_ALLOC( buf, size ) ) + return error; + + p = dstSlot->bitmap.buffer; + q = buf + + (int)pitch * ( y_max - dstSlot->bitmap_top ) + + 4 * ( dstSlot->bitmap_left - x_min ); + + for ( y = 0; y < dstSlot->bitmap.rows; y++ ) + { + FT_MEM_COPY( q, p, dstSlot->bitmap.width * 4 ); + + p += dstSlot->bitmap.pitch; + q += pitch; + } + + ft_glyphslot_set_bitmap( dstSlot, buf ); + + dstSlot->bitmap_top = y_max; + dstSlot->bitmap_left = x_min; + + dstSlot->bitmap.width = width; + dstSlot->bitmap.rows = rows; + dstSlot->bitmap.pitch = (int)pitch; + + dstSlot->internal->flags |= FT_GLYPH_OWN_BITMAP; + dstSlot->format = FT_GLYPH_FORMAT_BITMAP; + } + } + + if ( color_index == 0xFFFF ) + { + if ( face->have_foreground_color ) + { + b = face->foreground_color.blue; + g = face->foreground_color.green; + r = face->foreground_color.red; + alpha = face->foreground_color.alpha; + } + else + { + if ( face->palette_data.palette_flags && + ( face->palette_data.palette_flags[face->palette_index] & + FT_PALETTE_FOR_DARK_BACKGROUND ) ) + { + /* white opaque */ + b = 0xFF; + g = 0xFF; + r = 0xFF; + alpha = 0xFF; + } + else + { + /* black opaque */ + b = 0x00; + g = 0x00; + r = 0x00; + alpha = 0xFF; + } + } + } + else + { + b = face->palette[color_index].blue; + g = face->palette[color_index].green; + r = face->palette[color_index].red; + alpha = face->palette[color_index].alpha; + } + + /* XXX Convert if srcSlot.bitmap is not grey? */ + src = srcSlot->bitmap.buffer; + dst = dstSlot->bitmap.buffer + + dstSlot->bitmap.pitch * ( dstSlot->bitmap_top - srcSlot->bitmap_top ) + + 4 * ( srcSlot->bitmap_left - dstSlot->bitmap_left ); + + for ( y = 0; y < srcSlot->bitmap.rows; y++ ) + { + for ( x = 0; x < srcSlot->bitmap.width; x++ ) + { + int aa = src[x]; + int fa = alpha * aa / 255; + + int fb = b * fa / 255; + int fg = g * fa / 255; + int fr = r * fa / 255; + + int ba2 = 255 - fa; + + int bb = dst[4 * x + 0]; + int bg = dst[4 * x + 1]; + int br = dst[4 * x + 2]; + int ba = dst[4 * x + 3]; + + + dst[4 * x + 0] = (FT_Byte)( bb * ba2 / 255 + fb ); + dst[4 * x + 1] = (FT_Byte)( bg * ba2 / 255 + fg ); + dst[4 * x + 2] = (FT_Byte)( br * ba2 / 255 + fr ); + dst[4 * x + 3] = (FT_Byte)( ba * ba2 / 255 + fa ); + } + + src += srcSlot->bitmap.pitch; + dst += dstSlot->bitmap.pitch; + } + + return FT_Err_Ok; + } + +#else /* !TT_CONFIG_OPTION_COLOR_LAYERS */ + + /* ANSI C doesn't like empty source files */ + typedef int _tt_colr_dummy; + +#endif /* !TT_CONFIG_OPTION_COLOR_LAYERS */ + +/* EOF */ diff --git a/sdk/lib/3rdparty/freetype/src/sfnt/ttcolr.h b/sdk/lib/3rdparty/freetype/src/sfnt/ttcolr.h new file mode 100644 index 0000000000000..817489a855a50 --- /dev/null +++ b/sdk/lib/3rdparty/freetype/src/sfnt/ttcolr.h @@ -0,0 +1,58 @@ +/**************************************************************************** + * + * ttcolr.h + * + * TrueType and OpenType colored glyph layer support (specification). + * + * Copyright (C) 2018-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * Originally written by Shao Yu Zhang <shaozhang@fb.com>. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + +#ifndef __TTCOLR_H__ +#define __TTCOLR_H__ + + +#include <ft2build.h> +#include "ttload.h" + + +FT_BEGIN_HEADER + + + FT_LOCAL( FT_Error ) + tt_face_load_colr( TT_Face face, + FT_Stream stream ); + + FT_LOCAL( void ) + tt_face_free_colr( TT_Face face ); + + FT_LOCAL( FT_Bool ) + tt_face_get_colr_layer( TT_Face face, + FT_UInt base_glyph, + FT_UInt *aglyph_index, + FT_UInt *acolor_index, + FT_LayerIterator* iterator ); + + FT_LOCAL( FT_Error ) + tt_face_colr_blend_layer( TT_Face face, + FT_UInt color_index, + FT_GlyphSlot dstSlot, + FT_GlyphSlot srcSlot ); + + +FT_END_HEADER + + +#endif /* __TTCOLR_H__ */ + +/* END */ diff --git a/sdk/lib/3rdparty/freetype/src/sfnt/ttcpal.c b/sdk/lib/3rdparty/freetype/src/sfnt/ttcpal.c new file mode 100644 index 0000000000000..3482169a891be --- /dev/null +++ b/sdk/lib/3rdparty/freetype/src/sfnt/ttcpal.c @@ -0,0 +1,311 @@ +/**************************************************************************** + * + * ttcpal.c + * + * TrueType and OpenType color palette support (body). + * + * Copyright (C) 2018-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * Originally written by Shao Yu Zhang <shaozhang@fb.com>. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /************************************************************************** + * + * `CPAL' table specification: + * + * https://www.microsoft.com/typography/otspec/cpal.htm + * + */ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_TRUETYPE_TAGS_H +#include FT_COLOR_H + + +#ifdef TT_CONFIG_OPTION_COLOR_LAYERS + +#include "ttcpal.h" + + + /* NOTE: These are the table sizes calculated through the specs. */ +#define CPAL_V0_HEADER_BASE_SIZE 12 +#define COLOR_SIZE 4 + + + /* all data from `CPAL' not covered in FT_Palette_Data */ + typedef struct Cpal_ + { + FT_UShort version; /* Table version number (0 or 1 supported). */ + FT_UShort num_colors; /* Total number of color records, */ + /* combined for all palettes. */ + FT_Byte* colors; /* RGBA array of colors */ + FT_Byte* color_indices; /* Index of each palette's first color record */ + /* in the combined color record array. */ + + /* The memory which backs up the `CPAL' table. */ + void* table; + FT_ULong table_size; + + } Cpal; + + + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ +#undef FT_COMPONENT +#define FT_COMPONENT ttcpal + + + FT_LOCAL_DEF( FT_Error ) + tt_face_load_cpal( TT_Face face, + FT_Stream stream ) + { + FT_Error error; + FT_Memory memory = face->root.memory; + + FT_Byte* table = NULL; + FT_Byte* p = NULL; + + Cpal* cpal = NULL; + + FT_ULong colors_offset; + FT_ULong table_size; + + + error = face->goto_table( face, TTAG_CPAL, stream, &table_size ); + if ( error ) + goto NoCpal; + + if ( table_size < CPAL_V0_HEADER_BASE_SIZE ) + goto InvalidTable; + + if ( FT_FRAME_EXTRACT( table_size, table ) ) + goto NoCpal; + + p = table; + + if ( FT_NEW( cpal ) ) + goto NoCpal; + + cpal->version = FT_NEXT_USHORT( p ); + if ( cpal->version > 1 ) + goto InvalidTable; + + face->palette_data.num_palette_entries = FT_NEXT_USHORT( p ); + face->palette_data.num_palettes = FT_NEXT_USHORT( p ); + + cpal->num_colors = FT_NEXT_USHORT( p ); + colors_offset = FT_NEXT_ULONG( p ); + + if ( CPAL_V0_HEADER_BASE_SIZE + + face->palette_data.num_palettes * 2U > table_size ) + goto InvalidTable; + + if ( colors_offset >= table_size ) + goto InvalidTable; + if ( cpal->num_colors * COLOR_SIZE > table_size - colors_offset ) + goto InvalidTable; + + if ( face->palette_data.num_palette_entries > cpal->num_colors ) + goto InvalidTable; + + cpal->color_indices = p; + cpal->colors = (FT_Byte*)( table + colors_offset ); + + if ( cpal->version == 1 ) + { + FT_ULong type_offset, label_offset, entry_label_offset; + FT_UShort* array = NULL; + FT_UShort* limit; + FT_UShort* q; + + + if ( CPAL_V0_HEADER_BASE_SIZE + + face->palette_data.num_palettes * 2U + + 3U * 4 > table_size ) + goto InvalidTable; + + p += face->palette_data.num_palettes * 2; + + type_offset = FT_NEXT_ULONG( p ); + label_offset = FT_NEXT_ULONG( p ); + entry_label_offset = FT_NEXT_ULONG( p ); + + if ( type_offset ) + { + if ( type_offset >= table_size ) + goto InvalidTable; + if ( face->palette_data.num_palettes * 2 > + table_size - type_offset ) + goto InvalidTable; + + if ( FT_QNEW_ARRAY( array, face->palette_data.num_palettes ) ) + goto NoCpal; + + p = table + type_offset; + q = array; + limit = q + face->palette_data.num_palettes; + + while ( q < limit ) + *q++ = FT_NEXT_USHORT( p ); + + face->palette_data.palette_flags = array; + } + + if ( label_offset ) + { + if ( label_offset >= table_size ) + goto InvalidTable; + if ( face->palette_data.num_palettes * 2 > + table_size - label_offset ) + goto InvalidTable; + + if ( FT_QNEW_ARRAY( array, face->palette_data.num_palettes ) ) + goto NoCpal; + + p = table + label_offset; + q = array; + limit = q + face->palette_data.num_palettes; + + while ( q < limit ) + *q++ = FT_NEXT_USHORT( p ); + + face->palette_data.palette_name_ids = array; + } + + if ( entry_label_offset ) + { + if ( entry_label_offset >= table_size ) + goto InvalidTable; + if ( face->palette_data.num_palette_entries * 2 > + table_size - entry_label_offset ) + goto InvalidTable; + + if ( FT_QNEW_ARRAY( array, face->palette_data.num_palette_entries ) ) + goto NoCpal; + + p = table + entry_label_offset; + q = array; + limit = q + face->palette_data.num_palette_entries; + + while ( q < limit ) + *q++ = FT_NEXT_USHORT( p ); + + face->palette_data.palette_entry_name_ids = array; + } + } + + cpal->table = table; + cpal->table_size = table_size; + + face->cpal = cpal; + + /* set up default palette */ + if ( FT_NEW_ARRAY( face->palette, + face->palette_data.num_palette_entries ) ) + goto NoCpal; + + if ( tt_face_palette_set( face, 0 ) ) + goto InvalidTable; + + return FT_Err_Ok; + + InvalidTable: + error = FT_THROW( Invalid_Table ); + + NoCpal: + FT_FRAME_RELEASE( table ); + FT_FREE( cpal ); + + face->cpal = NULL; + + /* arrays in `face->palette_data' and `face->palette' */ + /* are freed in `sfnt_done_face' */ + + return error; + } + + + FT_LOCAL_DEF( void ) + tt_face_free_cpal( TT_Face face ) + { + FT_Stream stream = face->root.stream; + FT_Memory memory = face->root.memory; + + Cpal* cpal = (Cpal*)face->cpal; + + + if ( cpal ) + { + FT_FRAME_RELEASE( cpal->table ); + FT_FREE( cpal ); + } + } + + + FT_LOCAL_DEF( FT_Error ) + tt_face_palette_set( TT_Face face, + FT_UInt palette_index ) + { + Cpal* cpal = (Cpal*)face->cpal; + + FT_Byte* offset; + FT_Byte* p; + + FT_Color* q; + FT_Color* limit; + + FT_UShort color_index; + + + if ( !cpal || palette_index >= face->palette_data.num_palettes ) + return FT_THROW( Invalid_Argument ); + + offset = cpal->color_indices + 2 * palette_index; + color_index = FT_PEEK_USHORT( offset ); + + if ( color_index + face->palette_data.num_palette_entries > + cpal->num_colors ) + return FT_THROW( Invalid_Table ); + + p = cpal->colors + COLOR_SIZE * color_index; + q = face->palette; + limit = q + face->palette_data.num_palette_entries; + + while ( q < limit ) + { + q->blue = FT_NEXT_BYTE( p ); + q->green = FT_NEXT_BYTE( p ); + q->red = FT_NEXT_BYTE( p ); + q->alpha = FT_NEXT_BYTE( p ); + + q++; + } + + return FT_Err_Ok; + } + + +#else /* !TT_CONFIG_OPTION_COLOR_LAYERS */ + + /* ANSI C doesn't like empty source files */ + typedef int _tt_cpal_dummy; + +#endif /* !TT_CONFIG_OPTION_COLOR_LAYERS */ + +/* EOF */ diff --git a/sdk/lib/3rdparty/freetype/src/sfnt/ttcpal.h b/sdk/lib/3rdparty/freetype/src/sfnt/ttcpal.h new file mode 100644 index 0000000000000..d1b244f3e34cd --- /dev/null +++ b/sdk/lib/3rdparty/freetype/src/sfnt/ttcpal.h @@ -0,0 +1,49 @@ +/**************************************************************************** + * + * ttcpal.h + * + * TrueType and OpenType color palette support (specification). + * + * Copyright (C) 2018-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * Originally written by Shao Yu Zhang <shaozhang@fb.com>. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + +#ifndef __TTCPAL_H__ +#define __TTCPAL_H__ + + +#include <ft2build.h> +#include "ttload.h" + + +FT_BEGIN_HEADER + + + FT_LOCAL( FT_Error ) + tt_face_load_cpal( TT_Face face, + FT_Stream stream ); + + FT_LOCAL( void ) + tt_face_free_cpal( TT_Face face ); + + FT_LOCAL( FT_Error ) + tt_face_palette_set( TT_Face face, + FT_UInt palette_index ); + + +FT_END_HEADER + + +#endif /* __TTCPAL_H__ */ + +/* END */ diff --git a/sdk/lib/3rdparty/freetype/src/sfnt/ttkern.c b/sdk/lib/3rdparty/freetype/src/sfnt/ttkern.c index 68f15a201025a..8d1b7810904e7 100644 --- a/sdk/lib/3rdparty/freetype/src/sfnt/ttkern.c +++ b/sdk/lib/3rdparty/freetype/src/sfnt/ttkern.c @@ -1,20 +1,20 @@ -/***************************************************************************/ -/* */ -/* ttkern.c */ -/* */ -/* Load the basic TrueType kerning table. This doesn't handle */ -/* kerning data within the GPOS table at the moment. */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ttkern.c + * + * Load the basic TrueType kerning table. This doesn't handle + * kerning data within the GPOS table at the moment. + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -26,14 +26,14 @@ #include "sferrors.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_ttkern +#define FT_COMPONENT ttkern #undef TT_KERN_INDEX @@ -127,8 +127,8 @@ avail |= mask; /* - * Now check whether the pairs in this table are ordered. - * We then can use binary search. + * Now check whether the pairs in this table are ordered. + * We then can use binary search. */ if ( num_pairs > 0 ) { @@ -283,8 +283,8 @@ break; /* - * We don't support format 2 because we haven't seen a single font - * using it in real life... + * We don't support format 2 because we haven't seen a single font + * using it in real life... */ default: diff --git a/sdk/lib/3rdparty/freetype/src/sfnt/ttkern.h b/sdk/lib/3rdparty/freetype/src/sfnt/ttkern.h index 4e45d0964b4b6..5f283e5e622a6 100644 --- a/sdk/lib/3rdparty/freetype/src/sfnt/ttkern.h +++ b/sdk/lib/3rdparty/freetype/src/sfnt/ttkern.h @@ -1,20 +1,20 @@ -/***************************************************************************/ -/* */ -/* ttkern.h */ -/* */ -/* Load the basic TrueType kerning table. This doesn't handle */ -/* kerning data within the GPOS table at the moment. */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ttkern.h + * + * Load the basic TrueType kerning table. This doesn't handle + * kerning data within the GPOS table at the moment. + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef TTKERN_H_ diff --git a/sdk/lib/3rdparty/freetype/src/sfnt/ttload.c b/sdk/lib/3rdparty/freetype/src/sfnt/ttload.c index a86a546c3dd71..5443bf4b69604 100644 --- a/sdk/lib/3rdparty/freetype/src/sfnt/ttload.c +++ b/sdk/lib/3rdparty/freetype/src/sfnt/ttload.c @@ -1,20 +1,20 @@ -/***************************************************************************/ -/* */ -/* ttload.c */ -/* */ -/* Load the basic TrueType tables, i.e., tables that can be either in */ -/* TTF or OTF fonts (body). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ttload.c + * + * Load the basic TrueType tables, i.e., tables that can be either in + * TTF or OTF fonts (body). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -26,32 +26,34 @@ #include "sferrors.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_ttload - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_lookup_table */ - /* */ - /* <Description> */ - /* Looks for a TrueType table by name. */ - /* */ - /* <Input> */ - /* face :: A face object handle. */ - /* */ - /* tag :: The searched tag. */ - /* */ - /* <Return> */ - /* A pointer to the table directory entry. 0 if not found. */ - /* */ +#define FT_COMPONENT ttload + + + /************************************************************************** + * + * @Function: + * tt_face_lookup_table + * + * @Description: + * Looks for a TrueType table by name. + * + * @Input: + * face :: + * A face object handle. + * + * tag :: + * The searched tag. + * + * @Return: + * A pointer to the table directory entry. 0 if not found. + */ FT_LOCAL_DEF( TT_Table ) tt_face_lookup_table( TT_Face face, FT_ULong tag ) @@ -101,27 +103,31 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_goto_table */ - /* */ - /* <Description> */ - /* Looks for a TrueType table by name, then seek a stream to it. */ - /* */ - /* <Input> */ - /* face :: A face object handle. */ - /* */ - /* tag :: The searched tag. */ - /* */ - /* stream :: The stream to seek when the table is found. */ - /* */ - /* <Output> */ - /* length :: The length of the table if found, undefined otherwise. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * tt_face_goto_table + * + * @Description: + * Looks for a TrueType table by name, then seek a stream to it. + * + * @Input: + * face :: + * A face object handle. + * + * tag :: + * The searched tag. + * + * stream :: + * The stream to seek when the table is found. + * + * @Output: + * length :: + * The length of the table if found, undefined otherwise. + * + * @Return: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) tt_face_goto_table( TT_Face face, FT_ULong tag, @@ -309,28 +315,31 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_load_font_dir */ - /* */ - /* <Description> */ - /* Loads the header of a SFNT font file. */ - /* */ - /* <Input> */ - /* face :: A handle to the target face object. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* <Output> */ - /* sfnt :: The SFNT header. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - /* <Note> */ - /* The stream cursor must be at the beginning of the font directory. */ - /* */ + /************************************************************************** + * + * @Function: + * tt_face_load_font_dir + * + * @Description: + * Loads the header of a SFNT font file. + * + * @Input: + * face :: + * A handle to the target face object. + * + * stream :: + * The input stream. + * + * @Output: + * sfnt :: + * The SFNT header. + * + * @Return: + * FreeType error code. 0 means success. + * + * @Note: + * The stream cursor must be at the beginning of the font directory. + */ FT_LOCAL_DEF( FT_Error ) tt_face_load_font_dir( TT_Face face, FT_Stream stream ) @@ -496,46 +505,51 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_load_any */ - /* */ - /* <Description> */ - /* Loads any font table into client memory. */ - /* */ - /* <Input> */ - /* face :: The face object to look for. */ - /* */ - /* tag :: The tag of table to load. Use the value 0 if you want */ - /* to access the whole font file, else set this parameter */ - /* to a valid TrueType table tag that you can forge with */ - /* the MAKE_TT_TAG macro. */ - /* */ - /* offset :: The starting offset in the table (or the file if */ - /* tag == 0). */ - /* */ - /* length :: The address of the decision variable: */ - /* */ - /* If length == NULL: */ - /* Loads the whole table. Returns an error if */ - /* `offset' == 0! */ - /* */ - /* If *length == 0: */ - /* Exits immediately; returning the length of the given */ - /* table or of the font file, depending on the value of */ - /* `tag'. */ - /* */ - /* If *length != 0: */ - /* Loads the next `length' bytes of table or font, */ - /* starting at offset `offset' (in table or font too). */ - /* */ - /* <Output> */ - /* buffer :: The address of target buffer. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * tt_face_load_any + * + * @Description: + * Loads any font table into client memory. + * + * @Input: + * face :: + * The face object to look for. + * + * tag :: + * The tag of table to load. Use the value 0 if you want + * to access the whole font file, else set this parameter + * to a valid TrueType table tag that you can forge with + * the MAKE_TT_TAG macro. + * + * offset :: + * The starting offset in the table (or the file if + * tag == 0). + * + * length :: + * The address of the decision variable: + * + * If length == NULL: + * Loads the whole table. Returns an error if + * `offset' == 0! + * + * If *length == 0: + * Exits immediately; returning the length of the given + * table or of the font file, depending on the value of + * `tag'. + * + * If *length != 0: + * Loads the next `length' bytes of table or font, + * starting at offset `offset' (in table or font too). + * + * @Output: + * buffer :: + * The address of target buffer. + * + * @Return: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) tt_face_load_any( TT_Face face, FT_ULong tag, @@ -586,22 +600,24 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_load_generic_header */ - /* */ - /* <Description> */ - /* Loads the TrueType table `head' or `bhed'. */ - /* */ - /* <Input> */ - /* face :: A handle to the target face object. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * tt_face_load_generic_header + * + * @Description: + * Loads the TrueType table `head' or `bhed'. + * + * @Input: + * face :: + * A handle to the target face object. + * + * stream :: + * The input stream. + * + * @Return: + * FreeType error code. 0 means success. + */ static FT_Error tt_face_load_generic_header( TT_Face face, FT_Stream stream, @@ -622,10 +638,10 @@ FT_FRAME_LONG ( Magic_Number ), FT_FRAME_USHORT( Flags ), FT_FRAME_USHORT( Units_Per_EM ), - FT_FRAME_LONG ( Created[0] ), - FT_FRAME_LONG ( Created[1] ), - FT_FRAME_LONG ( Modified[0] ), - FT_FRAME_LONG ( Modified[1] ), + FT_FRAME_ULONG ( Created[0] ), + FT_FRAME_ULONG ( Created[1] ), + FT_FRAME_ULONG ( Modified[0] ), + FT_FRAME_ULONG ( Modified[1] ), FT_FRAME_SHORT ( xMin ), FT_FRAME_SHORT ( yMin ), FT_FRAME_SHORT ( xMax ), @@ -676,22 +692,24 @@ #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_load_maxp */ - /* */ - /* <Description> */ - /* Loads the maximum profile into a face object. */ - /* */ - /* <Input> */ - /* face :: A handle to the target face object. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * tt_face_load_maxp + * + * @Description: + * Loads the maximum profile into a face object. + * + * @Input: + * face :: + * A handle to the target face object. + * + * stream :: + * The input stream. + * + * @Return: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) tt_face_load_maxp( TT_Face face, FT_Stream stream ) @@ -784,22 +802,24 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_load_name */ - /* */ - /* <Description> */ - /* Loads the name records. */ - /* */ - /* <Input> */ - /* face :: A handle to the target face object. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * tt_face_load_name + * + * @Description: + * Loads the name records. + * + * @Input: + * face :: + * A handle to the target face object. + * + * stream :: + * The input stream. + * + * @Return: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) tt_face_load_name( TT_Face face, FT_Stream stream ) @@ -981,17 +1001,18 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_free_name */ - /* */ - /* <Description> */ - /* Frees the name records. */ - /* */ - /* <Input> */ - /* face :: A handle to the target face object. */ - /* */ + /************************************************************************** + * + * @Function: + * tt_face_free_name + * + * @Description: + * Frees the name records. + * + * @Input: + * face :: + * A handle to the target face object. + */ FT_LOCAL_DEF( void ) tt_face_free_name( TT_Face face ) { @@ -1030,23 +1051,25 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_load_cmap */ - /* */ - /* <Description> */ - /* Loads the cmap directory in a face object. The cmaps themselves */ - /* are loaded on demand in the `ttcmap.c' module. */ - /* */ - /* <Input> */ - /* face :: A handle to the target face object. */ - /* */ - /* stream :: A handle to the input stream. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * tt_face_load_cmap + * + * @Description: + * Loads the cmap directory in a face object. The cmaps themselves + * are loaded on demand in the `ttcmap.c' module. + * + * @Input: + * face :: + * A handle to the target face object. + * + * stream :: + * A handle to the input stream. + * + * @Return: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) tt_face_load_cmap( TT_Face face, @@ -1068,22 +1091,24 @@ - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_load_os2 */ - /* */ - /* <Description> */ - /* Loads the OS2 table. */ - /* */ - /* <Input> */ - /* face :: A handle to the target face object. */ - /* */ - /* stream :: A handle to the input stream. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * tt_face_load_os2 + * + * @Description: + * Loads the OS2 table. + * + * @Input: + * face :: + * A handle to the target face object. + * + * stream :: + * A handle to the input stream. + * + * @Return: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) tt_face_load_os2( TT_Face face, FT_Stream stream ) @@ -1228,22 +1253,24 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_load_postscript */ - /* */ - /* <Description> */ - /* Loads the Postscript table. */ - /* */ - /* <Input> */ - /* face :: A handle to the target face object. */ - /* */ - /* stream :: A handle to the input stream. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * tt_face_load_postscript + * + * @Description: + * Loads the Postscript table. + * + * @Input: + * face :: + * A handle to the target face object. + * + * stream :: + * A handle to the input stream. + * + * @Return: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) tt_face_load_post( TT_Face face, FT_Stream stream ) @@ -1288,22 +1315,24 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_load_pclt */ - /* */ - /* <Description> */ - /* Loads the PCL 5 Table. */ - /* */ - /* <Input> */ - /* face :: A handle to the target face object. */ - /* */ - /* stream :: A handle to the input stream. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * tt_face_load_pclt + * + * @Description: + * Loads the PCL 5 Table. + * + * @Input: + * face :: + * A handle to the target face object. + * + * stream :: + * A handle to the input stream. + * + * @Return: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) tt_face_load_pclt( TT_Face face, FT_Stream stream ) @@ -1349,22 +1378,24 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_load_gasp */ - /* */ - /* <Description> */ - /* Loads the `gasp' table into a face object. */ - /* */ - /* <Input> */ - /* face :: A handle to the target face object. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * tt_face_load_gasp + * + * @Description: + * Loads the `gasp' table into a face object. + * + * @Input: + * face :: + * A handle to the target face object. + * + * stream :: + * The input stream. + * + * @Return: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) tt_face_load_gasp( TT_Face face, FT_Stream stream ) diff --git a/sdk/lib/3rdparty/freetype/src/sfnt/ttload.h b/sdk/lib/3rdparty/freetype/src/sfnt/ttload.h index f94be8b7bd010..cc18c18694cf0 100644 --- a/sdk/lib/3rdparty/freetype/src/sfnt/ttload.h +++ b/sdk/lib/3rdparty/freetype/src/sfnt/ttload.h @@ -1,20 +1,20 @@ -/***************************************************************************/ -/* */ -/* ttload.h */ -/* */ -/* Load the basic TrueType tables, i.e., tables that can be either in */ -/* TTF or OTF fonts (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ttload.h + * + * Load the basic TrueType tables, i.e., tables that can be either in + * TTF or OTF fonts (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef TTLOAD_H_ diff --git a/sdk/lib/3rdparty/freetype/src/sfnt/ttmtx.c b/sdk/lib/3rdparty/freetype/src/sfnt/ttmtx.c index 6ddda95b567e0..7a4d2be2cb811 100644 --- a/sdk/lib/3rdparty/freetype/src/sfnt/ttmtx.c +++ b/sdk/lib/3rdparty/freetype/src/sfnt/ttmtx.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ttmtx.c */ -/* */ -/* Load the metrics tables common to TTF and OTF fonts (body). */ -/* */ -/* Copyright 2006-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ttmtx.c + * + * Load the metrics tables common to TTF and OTF fonts (body). + * + * Copyright (C) 2006-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -38,34 +38,37 @@ /* both the horizontal and vertical headers. */ - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_ttmtx - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_load_hmtx */ - /* */ - /* <Description> */ - /* Load the `hmtx' or `vmtx' table into a face object. */ - /* */ - /* <Input> */ - /* face :: A handle to the target face object. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* vertical :: A boolean flag. If set, load `vmtx'. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ +#define FT_COMPONENT ttmtx + + + /************************************************************************** + * + * @Function: + * tt_face_load_hmtx + * + * @Description: + * Load the `hmtx' or `vmtx' table into a face object. + * + * @Input: + * face :: + * A handle to the target face object. + * + * stream :: + * The input stream. + * + * vertical :: + * A boolean flag. If set, load `vmtx'. + * + * @Return: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) tt_face_load_hmtx( TT_Face face, FT_Stream stream, @@ -102,24 +105,27 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_load_hhea */ - /* */ - /* <Description> */ - /* Load the `hhea' or 'vhea' table into a face object. */ - /* */ - /* <Input> */ - /* face :: A handle to the target face object. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* vertical :: A boolean flag. If set, load `vhea'. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * tt_face_load_hhea + * + * @Description: + * Load the `hhea' or 'vhea' table into a face object. + * + * @Input: + * face :: + * A handle to the target face object. + * + * stream :: + * The input stream. + * + * vertical :: + * A boolean flag. If set, load `vhea'. + * + * @Return: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) tt_face_load_hhea( TT_Face face, FT_Stream stream, @@ -190,30 +196,35 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_get_metrics */ - /* */ - /* <Description> */ - /* Return the horizontal or vertical metrics in font units for a */ - /* given glyph. The values are the left side bearing (top side */ - /* bearing for vertical metrics) and advance width (advance height */ - /* for vertical metrics). */ - /* */ - /* <Input> */ - /* face :: A pointer to the TrueType face structure. */ - /* */ - /* vertical :: If set to TRUE, get vertical metrics. */ - /* */ - /* gindex :: The glyph index. */ - /* */ - /* <Output> */ - /* abearing :: The bearing, either left side or top side. */ - /* */ - /* aadvance :: The advance width or advance height, depending on */ - /* the `vertical' flag. */ - /* */ + /************************************************************************** + * + * @Function: + * tt_face_get_metrics + * + * @Description: + * Return the horizontal or vertical metrics in font units for a + * given glyph. The values are the left side bearing (top side + * bearing for vertical metrics) and advance width (advance height + * for vertical metrics). + * + * @Input: + * face :: + * A pointer to the TrueType face structure. + * + * vertical :: + * If set to TRUE, get vertical metrics. + * + * gindex :: + * The glyph index. + * + * @Output: + * abearing :: + * The bearing, either left side or top side. + * + * aadvance :: + * The advance width or advance height, depending on + * the `vertical' flag. + */ FT_LOCAL_DEF( void ) tt_face_get_metrics( TT_Face face, FT_Bool vertical, diff --git a/sdk/lib/3rdparty/freetype/src/sfnt/ttmtx.h b/sdk/lib/3rdparty/freetype/src/sfnt/ttmtx.h index ab00acd79526c..5b0b60b641c2d 100644 --- a/sdk/lib/3rdparty/freetype/src/sfnt/ttmtx.h +++ b/sdk/lib/3rdparty/freetype/src/sfnt/ttmtx.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ttmtx.h */ -/* */ -/* Load the metrics tables common to TTF and OTF fonts (specification). */ -/* */ -/* Copyright 2006-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ttmtx.h + * + * Load the metrics tables common to TTF and OTF fonts (specification). + * + * Copyright (C) 2006-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef TTMTX_H_ diff --git a/sdk/lib/3rdparty/freetype/src/sfnt/ttpost.c b/sdk/lib/3rdparty/freetype/src/sfnt/ttpost.c index f140649993a37..636a0a004ac50 100644 --- a/sdk/lib/3rdparty/freetype/src/sfnt/ttpost.c +++ b/sdk/lib/3rdparty/freetype/src/sfnt/ttpost.c @@ -1,28 +1,28 @@ -/***************************************************************************/ -/* */ -/* ttpost.c */ -/* */ -/* PostScript name table processing for TrueType and OpenType fonts */ -/* (body). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - /*************************************************************************/ - /* */ - /* The post table is not completely loaded by the core engine. This */ - /* file loads the missing PS glyph names and implements an API to access */ - /* them. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * ttpost.c + * + * PostScript name table processing for TrueType and OpenType fonts + * (body). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + /************************************************************************** + * + * The post table is not completely loaded by the core engine. This + * file loads the missing PS glyph names and implements an API to access + * them. + * + */ #include <ft2build.h> @@ -38,17 +38,17 @@ #include "sferrors.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_ttpost +#define FT_COMPONENT ttpost - /* If this configuration macro is defined, we rely on the `PSNames' */ + /* If this configuration macro is defined, we rely on the `psnames' */ /* module to grab the glyph names. */ #ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES @@ -62,9 +62,9 @@ #else /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */ - /* Otherwise, we ignore the `PSNames' module, and provide our own */ + /* Otherwise, we ignore the `psnames' module, and provide our own */ /* table of Mac names. Thus, it is possible to build a version of */ - /* FreeType without the Type 1 driver & PSNames module. */ + /* FreeType without the Type 1 driver & psnames module. */ #define MAC_NAME( x ) (FT_String*)tt_post_default_names[x] @@ -459,28 +459,31 @@ } - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_get_ps_name */ - /* */ - /* <Description> */ - /* Get the PostScript glyph name of a glyph. */ - /* */ - /* <Input> */ - /* face :: A handle to the parent face. */ - /* */ - /* idx :: The glyph index. */ - /* */ - /* <InOut> */ - /* PSname :: The address of a string pointer. Will be NULL in case */ - /* of error, otherwise it is a pointer to the glyph name. */ - /* */ - /* You must not modify the returned string! */ - /* */ - /* <Output> */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * tt_face_get_ps_name + * + * @Description: + * Get the PostScript glyph name of a glyph. + * + * @Input: + * face :: + * A handle to the parent face. + * + * idx :: + * The glyph index. + * + * @InOut: + * PSname :: + * The address of a string pointer. Undefined in case of + * error, otherwise it is a pointer to the glyph name. + * + * You must not modify the returned string! + * + * @Output: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) tt_face_get_ps_name( TT_Face face, FT_UInt idx, diff --git a/sdk/lib/3rdparty/freetype/src/sfnt/ttpost.h b/sdk/lib/3rdparty/freetype/src/sfnt/ttpost.h index 3bec07e445489..812a0fc92db13 100644 --- a/sdk/lib/3rdparty/freetype/src/sfnt/ttpost.h +++ b/sdk/lib/3rdparty/freetype/src/sfnt/ttpost.h @@ -1,20 +1,20 @@ -/***************************************************************************/ -/* */ -/* ttpost.h */ -/* */ -/* PostScript name table processing for TrueType and OpenType fonts */ -/* (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ttpost.h + * + * PostScript name table processing for TrueType and OpenType fonts + * (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef TTPOST_H_ diff --git a/sdk/lib/3rdparty/freetype/src/sfnt/ttsbit.c b/sdk/lib/3rdparty/freetype/src/sfnt/ttsbit.c index 53e61756d1842..0c5a2ea87c0fc 100644 --- a/sdk/lib/3rdparty/freetype/src/sfnt/ttsbit.c +++ b/sdk/lib/3rdparty/freetype/src/sfnt/ttsbit.c @@ -1,22 +1,22 @@ -/***************************************************************************/ -/* */ -/* ttsbit.c */ -/* */ -/* TrueType and OpenType embedded bitmap support (body). */ -/* */ -/* Copyright 2005-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* Copyright 2013 by Google, Inc. */ -/* Google Author(s): Behdad Esfahbod. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ttsbit.c + * + * TrueType and OpenType embedded bitmap support (body). + * + * Copyright (C) 2005-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * Copyright 2013 by Google, Inc. + * Google Author(s): Behdad Esfahbod. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -36,14 +36,14 @@ #include "pngshim.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_ttsbit +#define FT_COMPONENT ttsbit FT_LOCAL_DEF( FT_Error ) @@ -129,8 +129,8 @@ } /* - * Count the number of strikes available in the table. We are a bit - * paranoid there and don't trust the data. + * Count the number of strikes available in the table. We are a bit + * paranoid there and don't trust the data. */ count = (FT_UInt)num_strikes; if ( 8 + 48UL * count > table_size ) @@ -182,8 +182,8 @@ " expect bad rendering results\n" )); /* - * Count the number of strikes available in the table. We are a bit - * paranoid there and don't trust the data. + * Count the number of strikes available in the table. We are a bit + * paranoid there and don't trust the data. */ count = (FT_UInt)num_strikes; if ( 8 + 4UL * count > table_size ) @@ -1014,8 +1014,8 @@ for ( nn = 0; nn < num_components; nn++ ) { FT_UInt gindex = FT_NEXT_USHORT( p ); - FT_Byte dx = FT_NEXT_BYTE( p ); - FT_Byte dy = FT_NEXT_BYTE( p ); + FT_Char dx = FT_NEXT_CHAR( p ); + FT_Char dy = FT_NEXT_CHAR( p ); /* NB: a recursive call */ @@ -1514,7 +1514,7 @@ FT_FRAME_EXIT(); if ( glyph_start == glyph_end ) - return FT_THROW( Invalid_Argument ); + return FT_THROW( Missing_Bitmap ); if ( glyph_start > glyph_end || glyph_end - glyph_start < 8 || face->ebdt_size - strike_offset < glyph_end ) @@ -1607,7 +1607,16 @@ case TT_SBIT_TABLE_TYPE_EBLC: case TT_SBIT_TABLE_TYPE_CBLC: { +#ifdef __REACTOS__ + TT_SBitDecoderRec *decoder = malloc(sizeof(*decoder)); + if (!decoder) + { + error = FT_THROW( Out_Of_Memory ); + break; + } +#else TT_SBitDecoderRec decoder[1]; +#endif error = tt_sbit_decoder_init( decoder, face, strike_index, metrics ); @@ -1622,6 +1631,9 @@ ( load_flags & FT_LOAD_BITMAP_METRICS_ONLY ) != 0 ); tt_sbit_decoder_done( decoder ); } +#ifdef __REACTOS__ + free(decoder); +#endif } break; diff --git a/sdk/lib/3rdparty/freetype/src/sfnt/ttsbit.h b/sdk/lib/3rdparty/freetype/src/sfnt/ttsbit.h index ce2af3c1628fe..5ab8ff55689d0 100644 --- a/sdk/lib/3rdparty/freetype/src/sfnt/ttsbit.h +++ b/sdk/lib/3rdparty/freetype/src/sfnt/ttsbit.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ttsbit.h */ -/* */ -/* TrueType and OpenType embedded bitmap support (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ttsbit.h + * + * TrueType and OpenType embedded bitmap support (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef TTSBIT_H_ diff --git a/sdk/lib/3rdparty/freetype/src/smooth/ftgrays.c b/sdk/lib/3rdparty/freetype/src/smooth/ftgrays.c index a5ec55bf5a3c8..20cb3f38691a1 100644 --- a/sdk/lib/3rdparty/freetype/src/smooth/ftgrays.c +++ b/sdk/lib/3rdparty/freetype/src/smooth/ftgrays.c @@ -1,94 +1,94 @@ -/***************************************************************************/ -/* */ -/* ftgrays.c */ -/* */ -/* A new `perfect' anti-aliasing renderer (body). */ -/* */ -/* Copyright 2000-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - /*************************************************************************/ - /* */ - /* This file can be compiled without the rest of the FreeType engine, by */ - /* defining the STANDALONE_ macro when compiling it. You also need to */ - /* put the files `ftgrays.h' and `ftimage.h' into the current */ - /* compilation directory. Typically, you could do something like */ - /* */ - /* - copy `src/smooth/ftgrays.c' (this file) to your current directory */ - /* */ - /* - copy `include/freetype/ftimage.h' and `src/smooth/ftgrays.h' to the */ - /* same directory */ - /* */ - /* - compile `ftgrays' with the STANDALONE_ macro defined, as in */ - /* */ - /* cc -c -DSTANDALONE_ ftgrays.c */ - /* */ - /* The renderer can be initialized with a call to */ - /* `ft_gray_raster.raster_new'; an anti-aliased bitmap can be generated */ - /* with a call to `ft_gray_raster.raster_render'. */ - /* */ - /* See the comments and documentation in the file `ftimage.h' for more */ - /* details on how the raster works. */ - /* */ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* This is a new anti-aliasing scan-converter for FreeType 2. The */ - /* algorithm used here is _very_ different from the one in the standard */ - /* `ftraster' module. Actually, `ftgrays' computes the _exact_ */ - /* coverage of the outline on each pixel cell. */ - /* */ - /* It is based on ideas that I initially found in Raph Levien's */ - /* excellent LibArt graphics library (see http://www.levien.com/libart */ - /* for more information, though the web pages do not tell anything */ - /* about the renderer; you'll have to dive into the source code to */ - /* understand how it works). */ - /* */ - /* Note, however, that this is a _very_ different implementation */ - /* compared to Raph's. Coverage information is stored in a very */ - /* different way, and I don't use sorted vector paths. Also, it doesn't */ - /* use floating point values. */ - /* */ - /* This renderer has the following advantages: */ - /* */ - /* - It doesn't need an intermediate bitmap. Instead, one can supply a */ - /* callback function that will be called by the renderer to draw gray */ - /* spans on any target surface. You can thus do direct composition on */ - /* any kind of bitmap, provided that you give the renderer the right */ - /* callback. */ - /* */ - /* - A perfect anti-aliaser, i.e., it computes the _exact_ coverage on */ - /* each pixel cell. */ - /* */ - /* - It performs a single pass on the outline (the `standard' FT2 */ - /* renderer makes two passes). */ - /* */ - /* - It can easily be modified to render to _any_ number of gray levels */ - /* cheaply. */ - /* */ - /* - For small (< 20) pixel sizes, it is faster than the standard */ - /* renderer. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ +/**************************************************************************** + * + * ftgrays.c + * + * A new `perfect' anti-aliasing renderer (body). + * + * Copyright (C) 2000-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + /************************************************************************** + * + * This file can be compiled without the rest of the FreeType engine, by + * defining the STANDALONE_ macro when compiling it. You also need to + * put the files `ftgrays.h' and `ftimage.h' into the current + * compilation directory. Typically, you could do something like + * + * - copy `src/smooth/ftgrays.c' (this file) to your current directory + * + * - copy `include/freetype/ftimage.h' and `src/smooth/ftgrays.h' to the + * same directory + * + * - compile `ftgrays' with the STANDALONE_ macro defined, as in + * + * cc -c -DSTANDALONE_ ftgrays.c + * + * The renderer can be initialized with a call to + * `ft_gray_raster.raster_new'; an anti-aliased bitmap can be generated + * with a call to `ft_gray_raster.raster_render'. + * + * See the comments and documentation in the file `ftimage.h' for more + * details on how the raster works. + * + */ + + /************************************************************************** + * + * This is a new anti-aliasing scan-converter for FreeType 2. The + * algorithm used here is _very_ different from the one in the standard + * `ftraster' module. Actually, `ftgrays' computes the _exact_ + * coverage of the outline on each pixel cell. + * + * It is based on ideas that I initially found in Raph Levien's + * excellent LibArt graphics library (see https://www.levien.com/libart + * for more information, though the web pages do not tell anything + * about the renderer; you'll have to dive into the source code to + * understand how it works). + * + * Note, however, that this is a _very_ different implementation + * compared to Raph's. Coverage information is stored in a very + * different way, and I don't use sorted vector paths. Also, it doesn't + * use floating point values. + * + * This renderer has the following advantages: + * + * - It doesn't need an intermediate bitmap. Instead, one can supply a + * callback function that will be called by the renderer to draw gray + * spans on any target surface. You can thus do direct composition on + * any kind of bitmap, provided that you give the renderer the right + * callback. + * + * - A perfect anti-aliaser, i.e., it computes the _exact_ coverage on + * each pixel cell. + * + * - It performs a single pass on the outline (the `standard' FT2 + * renderer makes two passes). + * + * - It can easily be modified to render to _any_ number of gray levels + * cheaply. + * + * - For small (< 20) pixel sizes, it is faster than the standard + * renderer. + * + */ + + + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_smooth +#define FT_COMPONENT smooth #ifdef STANDALONE_ @@ -112,9 +112,9 @@ /* - * Approximate sqrt(x*x+y*y) using the `alpha max plus beta min' - * algorithm. We use alpha = 1, beta = 3/8, giving us results with a - * largest error less than 7% compared to the exact value. + * Approximate sqrt(x*x+y*y) using the `alpha max plus beta min' + * algorithm. We use alpha = 1, beta = 3/8, giving us results with a + * largest error less than 7% compared to the exact value. */ #define FT_HYPOT( x, y ) \ ( x = FT_ABS( x ), \ @@ -222,10 +222,10 @@ typedef ptrdiff_t FT_PtrDist; #endif #define FT_THROW( e ) \ - ( FT_Throw( FT_ERR_CAT( ErrRaster, e ), \ + ( FT_Throw( FT_ERR_CAT( ErrRaster_, e ), \ __LINE__, \ __FILE__ ) | \ - FT_ERR_CAT( ErrRaster, e ) ) + FT_ERR_CAT( ErrRaster_, e ) ) #else /* !FT_DEBUG_LEVEL_TRACE */ @@ -279,8 +279,6 @@ typedef ptrdiff_t FT_PtrDist; #include "ftsmerrs.h" -#include "ftspic.h" - #define Smooth_Err_Invalid_Mode Smooth_Err_Cannot_Render_Glyph #define Smooth_Err_Memory_Overflow Smooth_Err_Out_Of_Memory #define ErrRaster_Memory_Overflow Smooth_Err_Out_Of_Memory @@ -395,16 +393,16 @@ typedef ptrdiff_t FT_PtrDist; ( sizeof( long ) * FT_CHAR_BIT - PIXEL_BITS ) ) - /*************************************************************************/ - /* */ - /* TYPE DEFINITIONS */ - /* */ + /************************************************************************** + * + * TYPE DEFINITIONS + */ /* don't change the following types to FT_Int or FT_Pos, since we might */ /* need to define them to "float" or "double" when experimenting with */ /* new algorithms */ - typedef long TPos; /* sub-pixel coordinate */ + typedef long TPos; /* subpixel coordinate */ typedef int TCoord; /* integer scanline/pixel coordinate */ typedef int TArea; /* cell areas, coordinate products */ @@ -516,10 +514,10 @@ typedef ptrdiff_t FT_PtrDist; #endif /* FT_DEBUG_LEVEL_TRACE */ - /*************************************************************************/ - /* */ - /* Record the current cell in the table. */ - /* */ + /************************************************************************** + * + * Record the current cell in the table. + */ static void gray_record_cell( RAS_ARG ) { @@ -561,10 +559,10 @@ typedef ptrdiff_t FT_PtrDist; } - /*************************************************************************/ - /* */ - /* Set the current cell to a new position. */ - /* */ + /************************************************************************** + * + * Set the current cell to a new position. + */ static void gray_set_cell( RAS_ARG_ TCoord ex, TCoord ey ) @@ -598,10 +596,10 @@ typedef ptrdiff_t FT_PtrDist; #ifndef FT_LONG64 - /*************************************************************************/ - /* */ - /* Render a scanline as one or more cells. */ - /* */ + /************************************************************************** + * + * Render a scanline as one or more cells. + */ static void gray_render_scanline( RAS_ARG_ TCoord ey, TPos x1, @@ -696,10 +694,10 @@ typedef ptrdiff_t FT_PtrDist; } - /*************************************************************************/ - /* */ - /* Render a given line as a series of scanlines. */ - /* */ + /************************************************************************** + * + * Render a given line as a series of scanlines. + */ static void gray_render_line( RAS_ARG_ TPos to_x, TPos to_y ) @@ -837,10 +835,10 @@ typedef ptrdiff_t FT_PtrDist; #else - /*************************************************************************/ - /* */ - /* Render a straight line across multiple cells in any direction. */ - /* */ + /************************************************************************** + * + * Render a straight line across multiple cells in any direction. + */ static void gray_render_line( RAS_ARG_ TPos to_x, TPos to_y ) @@ -1330,40 +1328,43 @@ typedef ptrdiff_t FT_PtrDist; #ifdef STANDALONE_ - /*************************************************************************/ - /* */ - /* The following functions should only compile in stand-alone mode, */ - /* i.e., when building this component without the rest of FreeType. */ - /* */ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Outline_Decompose */ - /* */ - /* <Description> */ - /* Walk over an outline's structure to decompose it into individual */ - /* segments and Bézier arcs. This function is also able to emit */ - /* `move to' and `close to' operations to indicate the start and end */ - /* of new contours in the outline. */ - /* */ - /* <Input> */ - /* outline :: A pointer to the source target. */ - /* */ - /* func_interface :: A table of `emitters', i.e., function pointers */ - /* called during decomposition to indicate path */ - /* operations. */ - /* */ - /* <InOut> */ - /* user :: A typeless pointer which is passed to each */ - /* emitter during the decomposition. It can be */ - /* used to store the state during the */ - /* decomposition. */ - /* */ - /* <Return> */ - /* Error code. 0 means success. */ - /* */ + /************************************************************************** + * + * The following functions should only compile in stand-alone mode, + * i.e., when building this component without the rest of FreeType. + * + */ + + /************************************************************************** + * + * @Function: + * FT_Outline_Decompose + * + * @Description: + * Walk over an outline's structure to decompose it into individual + * segments and Bézier arcs. This function is also able to emit + * `move to' and `close to' operations to indicate the start and end + * of new contours in the outline. + * + * @Input: + * outline :: + * A pointer to the source target. + * + * func_interface :: + * A table of `emitters', i.e., function pointers + * called during decomposition to indicate path + * operations. + * + * @InOut: + * user :: + * A typeless pointer which is passed to each + * emitter during the decomposition. It can be + * used to store the state during the + * decomposition. + * + * @Return: + * Error code. 0 means success. + */ static int FT_Outline_Decompose( const FT_Outline* outline, const FT_Outline_Funcs* func_interface, @@ -1610,81 +1611,6 @@ typedef ptrdiff_t FT_PtrDist; return FT_THROW( Invalid_Outline ); } - - /*************************************************************************/ - /* */ - /* <Function> */ - /* FT_Outline_Get_CBox */ - /* */ - /* <Description> */ - /* Return an outline's `control box'. The control box encloses all */ - /* the outline's points, including Bézier control points. Though it */ - /* coincides with the exact bounding box for most glyphs, it can be */ - /* slightly larger in some situations (like when rotating an outline */ - /* that contains Bézier outside arcs). */ - /* */ - /* Computing the control box is very fast, while getting the bounding */ - /* box can take much more time as it needs to walk over all segments */ - /* and arcs in the outline. To get the latter, you can use the */ - /* `ftbbox' component, which is dedicated to this single task. */ - /* */ - /* <Input> */ - /* outline :: A pointer to the source outline descriptor. */ - /* */ - /* <Output> */ - /* acbox :: The outline's control box. */ - /* */ - /* <Note> */ - /* See @FT_Glyph_Get_CBox for a discussion of tricky fonts. */ - /* */ - - static void - FT_Outline_Get_CBox( const FT_Outline* outline, - FT_BBox *acbox ) - { - TPos xMin, yMin, xMax, yMax; - - - if ( outline && acbox ) - { - if ( outline->n_points == 0 ) - { - xMin = 0; - yMin = 0; - xMax = 0; - yMax = 0; - } - else - { - FT_Vector* vec = outline->points; - FT_Vector* limit = vec + outline->n_points; - - - xMin = xMax = vec->x; - yMin = yMax = vec->y; - vec++; - - for ( ; vec < limit; vec++ ) - { - TPos x, y; - - - x = vec->x; - if ( x < xMin ) xMin = x; - if ( x > xMax ) xMax = x; - - y = vec->y; - if ( y < yMin ) yMin = y; - if ( y > yMax ) yMax = y; - } - } - acbox->xMin = xMin; - acbox->xMax = xMax; - acbox->yMin = yMin; - acbox->yMax = yMax; - } - } - #endif /* STANDALONE_ */ @@ -1702,19 +1628,20 @@ typedef ptrdiff_t FT_PtrDist; static int - gray_convert_glyph_inner( RAS_ARG ) + gray_convert_glyph_inner( RAS_ARG, + int continued ) { - volatile int error = 0; -#ifdef FT_CONFIG_OPTION_PIC - FT_Outline_Funcs func_interface; - Init_Class_func_interface(&func_interface); -#endif if ( ft_setjmp( ras.jump_buffer ) == 0 ) { + if ( continued ) + FT_Trace_Disable(); error = FT_Outline_Decompose( &ras.outline, &func_interface, &ras ); + if ( continued ) + FT_Trace_Enable(); + if ( !ras.invalid ) gray_record_cell( RAS_VAR ); @@ -1741,11 +1668,12 @@ typedef ptrdiff_t FT_PtrDist; { const TCoord yMin = ras.min_ey; const TCoord yMax = ras.max_ey; - const TCoord xMin = ras.min_ex; - const TCoord xMax = ras.max_ex; #ifdef __REACTOS__ - TCell *buffer; + TCell *buffer = malloc(FT_MAX_GRAY_POOL * sizeof(TCell)); + if (!buffer) + return 1; + { #else TCell buffer[FT_MAX_GRAY_POOL]; #endif @@ -1755,13 +1683,8 @@ typedef ptrdiff_t FT_PtrDist; TCoord bands[32]; /* enough to accommodate bisections */ TCoord* band; -#ifdef __REACTOS__ - buffer = malloc(FT_MAX(FT_RENDER_POOL_SIZE, 2048)); - if (!buffer) - { - return 1; - } -#endif + int continued = 0; + /* set up vertical bands */ if ( height > n ) @@ -1785,8 +1708,8 @@ typedef ptrdiff_t FT_PtrDist; ras.max_ey = FT_MIN( y, yMax ); band = bands; - band[1] = xMin; - band[0] = xMax; + band[1] = ras.min_ey; + band[0] = ras.max_ey; do { @@ -1798,10 +1721,11 @@ typedef ptrdiff_t FT_PtrDist; ras.num_cells = 0; ras.invalid = 1; - ras.min_ex = band[1]; - ras.max_ex = band[0]; + ras.min_ey = band[1]; + ras.max_ey = band[0]; - error = gray_convert_glyph_inner( RAS_VAR ); + error = gray_convert_glyph_inner( RAS_VAR, continued ); + continued = 1; if ( !error ) { @@ -1810,12 +1734,14 @@ typedef ptrdiff_t FT_PtrDist; continue; } else if ( error != ErrRaster_Memory_Overflow ) - { #ifdef __REACTOS__ + { free(buffer); -#endif return 1; } +#else + return 1; +#endif /* render pool overflow; we will reduce the render band by half */ width >>= 1; @@ -1838,8 +1764,8 @@ typedef ptrdiff_t FT_PtrDist; #ifdef __REACTOS__ free(buffer); + } #endif - return 0; } @@ -1850,11 +1776,15 @@ typedef ptrdiff_t FT_PtrDist; { const FT_Outline* outline = (const FT_Outline*)params->source; const FT_Bitmap* target_map = params->target; - FT_BBox cbox, clip; + FT_BBox clip; #ifndef FT_STATIC_RASTER +#ifdef __REACTOS__ + gray_TWorker *worker; +#else gray_TWorker worker[1]; #endif +#endif if ( !raster ) @@ -1878,12 +1808,25 @@ typedef ptrdiff_t FT_PtrDist; outline->contours[outline->n_contours - 1] + 1 ) return FT_THROW( Invalid_Outline ); +#if !defined(FT_STATIC_RASTER) && defined(__REACTOS__) + worker = malloc(sizeof(*worker)); + if (!worker) + return FT_THROW(Out_Of_Memory); +#endif /* !defined(FT_STATIC_RASTER) && defined(__REACTOS__) */ + ras.outline = *outline; if ( params->flags & FT_RASTER_FLAG_DIRECT ) { if ( !params->gray_spans ) +#if !defined(FT_STATIC_RASTER) && defined(__REACTOS__) + { + free(worker); return 0; + } +#else + return 0; +#endif ras.render_span = (FT_Raster_Span_Func)params->gray_spans; ras.render_span_data = params->user; @@ -1892,14 +1835,35 @@ typedef ptrdiff_t FT_PtrDist; { /* if direct mode is not set, we must have a target bitmap */ if ( !target_map ) +#if !defined(FT_STATIC_RASTER) && defined(__REACTOS__) + { + free(worker); return FT_THROW( Invalid_Argument ); + } +#else + return FT_THROW( Invalid_Argument ); +#endif /* nothing to do */ if ( !target_map->width || !target_map->rows ) +#if !defined(FT_STATIC_RASTER) && defined(__REACTOS__) + { + free(worker); + return 0; + } +#else return 0; +#endif if ( !target_map->buffer ) +#if !defined(FT_STATIC_RASTER) && defined(__REACTOS__) + { + free(worker); return FT_THROW( Invalid_Argument ); + } +#else + return FT_THROW( Invalid_Argument ); +#endif if ( target_map->pitch < 0 ) ras.target.origin = target_map->buffer; @@ -1913,21 +1877,11 @@ typedef ptrdiff_t FT_PtrDist; ras.render_span_data = NULL; } - FT_Outline_Get_CBox( outline, &cbox ); - - /* reject too large outline coordinates */ - if ( cbox.xMin < -0x1000000L || cbox.xMax > 0x1000000L || - cbox.yMin < -0x1000000L || cbox.yMax > 0x1000000L ) - return FT_THROW( Invalid_Outline ); - - /* truncate the bounding box to integer pixels */ - cbox.xMin = cbox.xMin >> 6; - cbox.yMin = cbox.yMin >> 6; - cbox.xMax = ( cbox.xMax + 63 ) >> 6; - cbox.yMax = ( cbox.yMax + 63 ) >> 6; - /* compute clipping box */ - if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) ) + if ( params->flags & FT_RASTER_FLAG_DIRECT && + params->flags & FT_RASTER_FLAG_CLIP ) + clip = params->clip_box; + else { /* compute clip box from target pixmap */ clip.xMin = 0; @@ -1935,26 +1889,32 @@ typedef ptrdiff_t FT_PtrDist; clip.xMax = (FT_Pos)target_map->width; clip.yMax = (FT_Pos)target_map->rows; } - else if ( params->flags & FT_RASTER_FLAG_CLIP ) - clip = params->clip_box; - else - { - clip.xMin = -32768L; - clip.yMin = -32768L; - clip.xMax = 32767L; - clip.yMax = 32767L; - } /* clip to target bitmap, exit if nothing to do */ - ras.min_ex = FT_MAX( cbox.xMin, clip.xMin ); - ras.min_ey = FT_MAX( cbox.yMin, clip.yMin ); - ras.max_ex = FT_MIN( cbox.xMax, clip.xMax ); - ras.max_ey = FT_MIN( cbox.yMax, clip.yMax ); + ras.min_ex = clip.xMin; + ras.min_ey = clip.yMin; + ras.max_ex = clip.xMax; + ras.max_ey = clip.yMax; if ( ras.max_ex <= ras.min_ex || ras.max_ey <= ras.min_ey ) +#if !defined(FT_STATIC_RASTER) && defined(__REACTOS__) + { + free(worker); + return 0; + } +#else return 0; +#endif +#if !defined(FT_STATIC_RASTER) && defined(__REACTOS__) + { + FT_Error error = gray_convert_glyph( RAS_VAR ); + free(worker); + return error; + } +#else return gray_convert_glyph( RAS_VAR ); +#endif } diff --git a/sdk/lib/3rdparty/freetype/src/smooth/ftgrays.h b/sdk/lib/3rdparty/freetype/src/smooth/ftgrays.h index 9e11ca675ef13..e9f9c7a4add08 100644 --- a/sdk/lib/3rdparty/freetype/src/smooth/ftgrays.h +++ b/sdk/lib/3rdparty/freetype/src/smooth/ftgrays.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftgrays.h */ -/* */ -/* FreeType smooth renderer declaration */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftgrays.h + * + * FreeType smooth renderer declaration + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTGRAYS_H_ @@ -28,19 +28,18 @@ #include "ftimage.h" #else #include <ft2build.h> -#include FT_CONFIG_CONFIG_H /* for FT_CONFIG_OPTION_PIC */ #include FT_IMAGE_H #endif - /*************************************************************************/ - /* */ - /* To make ftgrays.h independent from configuration files we check */ - /* whether FT_EXPORT_VAR has been defined already. */ - /* */ - /* On some systems and compilers (Win32 mostly), an extra keyword is */ - /* necessary to compile the library as a DLL. */ - /* */ + /************************************************************************** + * + * To make ftgrays.h independent from configuration files we check + * whether FT_EXPORT_VAR has been defined already. + * + * On some systems and compilers (Win32 mostly), an extra keyword is + * necessary to compile the library as a DLL. + */ #ifndef FT_EXPORT_VAR #define FT_EXPORT_VAR( x ) extern x #endif diff --git a/sdk/lib/3rdparty/freetype/src/smooth/ftsmerrs.h b/sdk/lib/3rdparty/freetype/src/smooth/ftsmerrs.h index 226dc1b00175d..d52c0dd9e2053 100644 --- a/sdk/lib/3rdparty/freetype/src/smooth/ftsmerrs.h +++ b/sdk/lib/3rdparty/freetype/src/smooth/ftsmerrs.h @@ -1,27 +1,27 @@ -/***************************************************************************/ -/* */ -/* ftsmerrs.h */ -/* */ -/* smooth renderer error codes (specification only). */ -/* */ -/* Copyright 2001-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to define the smooth renderer error enumeration */ - /* constants. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * ftsmerrs.h + * + * smooth renderer error codes (specification only). + * + * Copyright (C) 2001-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /************************************************************************** + * + * This file is used to define the smooth renderer error enumeration + * constants. + * + */ #ifndef FTSMERRS_H_ #define FTSMERRS_H_ diff --git a/sdk/lib/3rdparty/freetype/src/smooth/ftsmooth.c b/sdk/lib/3rdparty/freetype/src/smooth/ftsmooth.c index ef176bdf1ec6a..c8b6bb75186b1 100644 --- a/sdk/lib/3rdparty/freetype/src/smooth/ftsmooth.c +++ b/sdk/lib/3rdparty/freetype/src/smooth/ftsmooth.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftsmooth.c */ -/* */ -/* Anti-aliasing renderer interface (body). */ -/* */ -/* Copyright 2000-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftsmooth.c + * + * Anti-aliasing renderer interface (body). + * + * Copyright (C) 2000-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include <ft2build.h> @@ -22,7 +22,6 @@ #include FT_OUTLINE_H #include "ftsmooth.h" #include "ftgrays.h" -#include "ftspic.h" #include "ftsmerrs.h" @@ -31,6 +30,26 @@ static FT_Error ft_smooth_init( FT_Renderer render ) { + +#ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING + + FT_Vector* sub = render->root.library->lcd_geometry; + + + /* set up default subpixel geometry for striped RGB panels. */ + sub[0].x = -21; + sub[0].y = 0; + sub[1].x = 0; + sub[1].y = 0; + sub[2].x = 21; + sub[2].y = 0; + +#elif 0 /* or else, once ClearType patents expire */ + + FT_Library_SetLcdFilter( render->root.library, FT_LCD_FILTER_DEFAULT ); + +#endif + render->clazz->raster_class->raster_reset( render->raster, NULL, 0 ); return 0; @@ -130,7 +149,11 @@ slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; } - ft_glyphslot_preset_bitmap( slot, mode, origin ); + if ( ft_glyphslot_preset_bitmap( slot, mode, origin ) ) + { + error = FT_THROW( Raster_Overflow ); + goto Exit; + } /* allocate new one */ if ( FT_ALLOC_MULT( bitmap->buffer, bitmap->rows, bitmap->pitch ) ) @@ -235,33 +258,40 @@ unsigned int width = bitmap->width; int pitch = bitmap->pitch; + FT_Vector* sub = slot->library->lcd_geometry; - /* Render 3 separate monochrome bitmaps, shifting the outline */ - /* by 1/3 pixel. */ - width /= 3; - bitmap->buffer += width; + /* Render 3 separate monochrome bitmaps, shifting the outline. */ + width /= 3; + FT_Outline_Translate( outline, + -sub[0].x, + -sub[0].y ); error = render->raster_render( render->raster, ¶ms ); if ( error ) goto Exit; - FT_Outline_Translate( outline, -21, 0 ); - x_shift -= 21; bitmap->buffer += width; - + FT_Outline_Translate( outline, + sub[0].x - sub[1].x, + sub[0].y - sub[1].y ); error = render->raster_render( render->raster, ¶ms ); + bitmap->buffer -= width; if ( error ) goto Exit; - FT_Outline_Translate( outline, 42, 0 ); - x_shift += 42; - bitmap->buffer -= 2 * width; - + bitmap->buffer += 2 * width; + FT_Outline_Translate( outline, + sub[1].x - sub[2].x, + sub[1].y - sub[2].y ); error = render->raster_render( render->raster, ¶ms ); + bitmap->buffer -= 2 * width; if ( error ) goto Exit; + x_shift -= sub[2].x; + y_shift -= sub[2].y; + /* XXX: Rearrange the bytes according to FT_PIXEL_MODE_LCD. */ /* XXX: It is more efficient to render every third byte above. */ @@ -286,34 +316,43 @@ { int pitch = bitmap->pitch; + FT_Vector* sub = slot->library->lcd_geometry; + - /* Render 3 separate monochrome bitmaps, shifting the outline */ - /* by 1/3 pixel. Triple the pitch to render on each third row. */ + /* Render 3 separate monochrome bitmaps, shifting the outline. */ + /* Notice that the subpixel geometry vectors are rotated. */ + /* Triple the pitch to render on each third row. */ bitmap->pitch *= 3; bitmap->rows /= 3; - bitmap->buffer += pitch; - + FT_Outline_Translate( outline, + -sub[0].y, + sub[0].x ); error = render->raster_render( render->raster, ¶ms ); if ( error ) goto Exit; - FT_Outline_Translate( outline, 0, 21 ); - y_shift += 21; bitmap->buffer += pitch; - + FT_Outline_Translate( outline, + sub[0].y - sub[1].y, + sub[1].x - sub[0].x ); error = render->raster_render( render->raster, ¶ms ); + bitmap->buffer -= pitch; if ( error ) goto Exit; - FT_Outline_Translate( outline, 0, -42 ); - y_shift -= 42; - bitmap->buffer -= 2 * pitch; - + bitmap->buffer += 2 * pitch; + FT_Outline_Translate( outline, + sub[1].y - sub[2].y, + sub[2].x - sub[1].x ); error = render->raster_render( render->raster, ¶ms ); + bitmap->buffer -= 2 * pitch; if ( error ) goto Exit; + x_shift -= sub[2].y; + y_shift += sub[2].x; + bitmap->pitch /= 3; bitmap->rows *= 3; } @@ -403,7 +442,7 @@ (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, /* get_glyph_cbox */ (FT_Renderer_SetModeFunc) ft_smooth_set_mode, /* set_mode */ - (FT_Raster_Funcs*)&FT_GRAYS_RASTER_GET /* raster_class */ + (FT_Raster_Funcs*)&ft_grays_raster /* raster_class */ ) @@ -430,7 +469,7 @@ (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, /* get_glyph_cbox */ (FT_Renderer_SetModeFunc) ft_smooth_set_mode, /* set_mode */ - (FT_Raster_Funcs*)&FT_GRAYS_RASTER_GET /* raster_class */ + (FT_Raster_Funcs*)&ft_grays_raster /* raster_class */ ) @@ -457,7 +496,7 @@ (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, /* get_glyph_cbox */ (FT_Renderer_SetModeFunc) ft_smooth_set_mode, /* set_mode */ - (FT_Raster_Funcs*)&FT_GRAYS_RASTER_GET /* raster_class */ + (FT_Raster_Funcs*)&ft_grays_raster /* raster_class */ ) diff --git a/sdk/lib/3rdparty/freetype/src/smooth/ftsmooth.h b/sdk/lib/3rdparty/freetype/src/smooth/ftsmooth.h index c76ffc5034e6d..fbb21a31d0598 100644 --- a/sdk/lib/3rdparty/freetype/src/smooth/ftsmooth.h +++ b/sdk/lib/3rdparty/freetype/src/smooth/ftsmooth.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftsmooth.h */ -/* */ -/* Anti-aliasing renderer interface (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftsmooth.h + * + * Anti-aliasing renderer interface (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTSMOOTH_H_ diff --git a/sdk/lib/3rdparty/freetype/src/smooth/ftspic.c b/sdk/lib/3rdparty/freetype/src/smooth/ftspic.c deleted file mode 100644 index 10f04cf4ccf88..0000000000000 --- a/sdk/lib/3rdparty/freetype/src/smooth/ftspic.c +++ /dev/null @@ -1,118 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftspic.c */ -/* */ -/* The FreeType position independent code services for smooth module. */ -/* */ -/* Copyright 2009-2018 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_FREETYPE_H -#include FT_INTERNAL_OBJECTS_H -#include "ftspic.h" -#include "ftsmerrs.h" - - -#ifdef FT_CONFIG_OPTION_PIC - - /* forward declaration of PIC init functions from ftgrays.c */ - void - FT_Init_Class_ft_grays_raster( FT_Raster_Funcs* funcs ); - - - void - ft_smooth_renderer_class_pic_free( FT_Library library ) - { - FT_PIC_Container* pic_container = &library->pic_container; - FT_Memory memory = library->memory; - - - if ( pic_container->smooth ) - { - SmoothPIC* container = (SmoothPIC*)pic_container->smooth; - - - if ( --container->ref_count ) - return; - - FT_FREE( container ); - pic_container->smooth = NULL; - } - } - - - FT_Error - ft_smooth_renderer_class_pic_init( FT_Library library ) - { - FT_PIC_Container* pic_container = &library->pic_container; - FT_Error error = FT_Err_Ok; - SmoothPIC* container = NULL; - FT_Memory memory = library->memory; - - - /* since this function also serve smooth_lcd and smooth_lcdv renderers, - it implements reference counting */ - if ( pic_container->smooth ) - { - ((SmoothPIC*)pic_container->smooth)->ref_count++; - return error; - } - - /* allocate pointer, clear and set global container pointer */ - if ( FT_ALLOC( container, sizeof ( *container ) ) ) - return error; - FT_MEM_SET( container, 0, sizeof ( *container ) ); - pic_container->smooth = container; - - container->ref_count = 1; - - /* initialize pointer table - */ - /* this is how the module usually expects this data */ - FT_Init_Class_ft_grays_raster( &container->ft_grays_raster ); - - return error; - } - - - /* re-route these init and free functions to the above functions */ - FT_Error - ft_smooth_lcd_renderer_class_pic_init( FT_Library library ) - { - return ft_smooth_renderer_class_pic_init( library ); - } - - - void - ft_smooth_lcd_renderer_class_pic_free( FT_Library library ) - { - ft_smooth_renderer_class_pic_free( library ); - } - - - FT_Error - ft_smooth_lcdv_renderer_class_pic_init( FT_Library library ) - { - return ft_smooth_renderer_class_pic_init( library ); - } - - - void - ft_smooth_lcdv_renderer_class_pic_free( FT_Library library ) - { - ft_smooth_renderer_class_pic_free( library ); - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - -/* END */ diff --git a/sdk/lib/3rdparty/freetype/src/smooth/ftspic.h b/sdk/lib/3rdparty/freetype/src/smooth/ftspic.h deleted file mode 100644 index 80fb64cff43ce..0000000000000 --- a/sdk/lib/3rdparty/freetype/src/smooth/ftspic.h +++ /dev/null @@ -1,75 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftspic.h */ -/* */ -/* The FreeType position independent code services for smooth module. */ -/* */ -/* Copyright 2009-2018 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#ifndef FTSPIC_H_ -#define FTSPIC_H_ - - -#include FT_INTERNAL_PIC_H - - -FT_BEGIN_HEADER - -#ifndef FT_CONFIG_OPTION_PIC - -#define FT_GRAYS_RASTER_GET ft_grays_raster - -#else /* FT_CONFIG_OPTION_PIC */ - - typedef struct SmoothPIC_ - { - int ref_count; - FT_Raster_Funcs ft_grays_raster; - - } SmoothPIC; - - -#define GET_PIC( lib ) \ - ( (SmoothPIC*)( (lib)->pic_container.smooth ) ) -#define FT_GRAYS_RASTER_GET ( GET_PIC( library )->ft_grays_raster ) - - - /* see ftspic.c for the implementation */ - void - ft_smooth_renderer_class_pic_free( FT_Library library ); - - void - ft_smooth_lcd_renderer_class_pic_free( FT_Library library ); - - void - ft_smooth_lcdv_renderer_class_pic_free( FT_Library library ); - - FT_Error - ft_smooth_renderer_class_pic_init( FT_Library library ); - - FT_Error - ft_smooth_lcd_renderer_class_pic_init( FT_Library library ); - - FT_Error - ft_smooth_lcdv_renderer_class_pic_init( FT_Library library ); - -#endif /* FT_CONFIG_OPTION_PIC */ - - /* */ - -FT_END_HEADER - -#endif /* FTSPIC_H_ */ - - -/* END */ diff --git a/sdk/lib/3rdparty/freetype/src/smooth/smooth.c b/sdk/lib/3rdparty/freetype/src/smooth/smooth.c index 5249a8931e39c..9c543d3360335 100644 --- a/sdk/lib/3rdparty/freetype/src/smooth/smooth.c +++ b/sdk/lib/3rdparty/freetype/src/smooth/smooth.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* smooth.c */ -/* */ -/* FreeType anti-aliasing rasterer module component (body only). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * smooth.c + * + * FreeType anti-aliasing rasterer module component (body only). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #define FT_MAKE_OPTION_SINGLE_OBJECT @@ -21,7 +21,6 @@ #include "ftgrays.c" #include "ftsmooth.c" -#include "ftspic.c" /* END */ diff --git a/sdk/lib/3rdparty/freetype/src/tools/afblue.pl b/sdk/lib/3rdparty/freetype/src/tools/afblue.pl deleted file mode 100644 index 7c6f1a7df131a..0000000000000 --- a/sdk/lib/3rdparty/freetype/src/tools/afblue.pl +++ /dev/null @@ -1,551 +0,0 @@ -#! /usr/bin/perl -w -# -*- Perl -*- -# -# afblue.pl -# -# Process a blue zone character data file. -# -# Copyright 2013-2018 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, -# modified, and distributed under the terms of the FreeType project -# license, LICENSE.TXT. By continuing to use, modify, or distribute -# this file you indicate that you have read the license and -# understand and accept it fully. - -use strict; -use warnings; -use English '-no_match_vars'; -use open ':std', ':encoding(UTF-8)'; - - -my $prog = $PROGRAM_NAME; -$prog =~ s| .* / ||x; # Remove path. - -die "usage: $prog datafile < infile > outfile\n" if $#ARGV != 0; - - -my $datafile = $ARGV[0]; - -my %diversions; # The extracted and massaged data from `datafile'. -my @else_stack; # Booleans to track else-clauses. -my @name_stack; # Stack of integers used for names of aux. variables. - -my $curr_enum; # Name of the current enumeration. -my $curr_array; # Name of the current array. -my $curr_max; # Name of the current maximum value. - -my $curr_enum_element; # Name of the current enumeration element. -my $curr_offset; # The offset relative to current aux. variable. -my $curr_elem_size; # The number of non-space characters in the current string or - # the number of elements in the current block. - -my $have_sections = 0; # Boolean; set if start of a section has been seen. -my $have_strings; # Boolean; set if current section contains strings. -my $have_blocks; # Boolean; set if current section contains blocks. - -my $have_enum_element; # Boolean; set if we have an enumeration element. -my $in_string; # Boolean; set if a string has been parsed. - -my $num_sections = 0; # Number of sections seen so far. - -my $last_aux; # Name of last auxiliary variable. - - -# Regular expressions. - -# [<ws>] <enum_name> <ws> <array_name> <ws> <max_name> [<ws>] ':' [<ws>] '\n' -my $section_re = qr/ ^ \s* (\S+) \s+ (\S+) \s+ (\S+) \s* : \s* $ /x; - -# [<ws>] <enum_element_name> [<ws>] '\n' -my $enum_element_re = qr/ ^ \s* ( [A-Za-z0-9_]+ ) \s* $ /x; - -# '#' <preprocessor directive> '\n' -my $preprocessor_re = qr/ ^ \# /x; - -# [<ws>] '/' '/' <comment> '\n' -my $comment_re = qr| ^ \s* // |x; - -# empty line -my $whitespace_only_re = qr/ ^ \s* $ /x; - -# [<ws>] '"' <string> '"' [<ws>] '\n' (<string> doesn't contain newlines) -my $string_re = qr/ ^ \s* - " ( (?> (?: (?> [^"\\]+ ) | \\. )* ) ) " - \s* $ /x; - -# [<ws>] '{' <block> '}' [<ws>] '\n' (<block> can contain newlines) -my $block_start_re = qr/ ^ \s* \{ /x; - -# We need the capturing group for `split' to make it return the separator -# tokens (i.e., the opening and closing brace) also. -my $brace_re = qr/ ( [{}] ) /x; - - -sub Warn -{ - my $message = shift; - warn "$datafile:$INPUT_LINE_NUMBER: warning: $message\n"; -} - - -sub Die -{ - my $message = shift; - die "$datafile:$INPUT_LINE_NUMBER: error: $message\n"; -} - - -my $warned_before = 0; - -sub warn_before -{ - Warn("data before first section gets ignored") unless $warned_before; - $warned_before = 1; -} - - -sub strip_newline -{ - chomp; - s/ \x0D $ //x; -} - - -sub end_curr_string -{ - # Append final null byte to string. - if ($have_strings) - { - push @{$diversions{$curr_array}}, " '\\0',\n" if $in_string; - - $curr_offset++; - $in_string = 0; - } -} - - -sub update_max_elem_size -{ - if ($curr_elem_size) - { - my $max = pop @{$diversions{$curr_max}}; - $max = $curr_elem_size if $curr_elem_size > $max; - push @{$diversions{$curr_max}}, $max; - } -} - - -sub convert_non_ascii_char -{ - # A UTF-8 character outside of the printable ASCII range, with possibly a - # leading backslash character. - my $s = shift; - - # Here we count characters, not bytes. - $curr_elem_size += length $s; - - utf8::encode($s); - $s = uc unpack 'H*', $s; - - $curr_offset += $s =~ s/\G(..)/'\\x$1', /sg; - - return $s; -} - - -sub convert_ascii_chars -{ - # A series of ASCII characters in the printable range. - my $s = shift; - - # We reduce multiple space characters to a single one. - $s =~ s/ +/ /g; - - # Count all non-space characters. Note that `()' applies a list context - # to the capture that is used to count the elements. - $curr_elem_size += () = $s =~ /[^ ]/g; - - $curr_offset += $s =~ s/\G(.)/'$1', /g; - - return $s; -} - - -sub convert_literal -{ - my $s = shift; - my $orig = $s; - - # ASCII printables and space - my $safe_re = '\x20-\x7E'; - # ASCII printables and space, no backslash - my $safe_no_backslash_re = '\x20-\x5B\x5D-\x7E'; - - $s =~ s{ - (?: \\? ( [^$safe_re] ) - | ( (?: [$safe_no_backslash_re] - | \\ [$safe_re] )+ ) ) - } - { - defined($1) ? convert_non_ascii_char($1) - : convert_ascii_chars($2) - }egx; - - # We assume that `$orig' doesn't contain `*/' - return $s . " /* $orig */"; -} - - -sub aux_name -{ - return "af_blue_" . $num_sections. "_" . join('_', @name_stack); -} - - -sub aux_name_next -{ - $name_stack[$#name_stack]++; - my $name = aux_name(); - $name_stack[$#name_stack]--; - - return $name; -} - - -sub enum_val_string -{ - # Build string that holds code to save the current offset in an - # enumeration element. - my $aux = shift; - - my $add = ($last_aux eq "af_blue_" . $num_sections . "_0" ) - ? "" - : "$last_aux + "; - - return " $aux = $add$curr_offset,\n"; -} - - - -# Process data file. - -open(DATA, $datafile) || die "$prog: can't open \`$datafile': $OS_ERROR\n"; - -while (<DATA>) -{ - strip_newline(); - - next if /$comment_re/; - next if /$whitespace_only_re/; - - if (/$section_re/) - { - Warn("previous section is empty") if ($have_sections - && !$have_strings - && !$have_blocks); - - end_curr_string(); - update_max_elem_size(); - - # Save captured groups from `section_re'. - $curr_enum = $1; - $curr_array = $2; - $curr_max = $3; - - $curr_enum_element = ""; - $curr_offset = 0; - - Warn("overwriting already defined enumeration \`$curr_enum'") - if exists($diversions{$curr_enum}); - Warn("overwriting already defined array \`$curr_array'") - if exists($diversions{$curr_array}); - Warn("overwriting already defined maximum value \`$curr_max'") - if exists($diversions{$curr_max}); - - $diversions{$curr_enum} = []; - $diversions{$curr_array} = []; - $diversions{$curr_max} = []; - - push @{$diversions{$curr_max}}, 0; - - @name_stack = (); - push @name_stack, 0; - - $have_sections = 1; - $have_strings = 0; - $have_blocks = 0; - - $have_enum_element = 0; - $in_string = 0; - - $num_sections++; - $curr_elem_size = 0; - - $last_aux = aux_name(); - - next; - } - - if (/$preprocessor_re/) - { - if ($have_sections) - { - # Having preprocessor conditionals complicates the computation of - # correct offset values. We have to introduce auxiliary enumeration - # elements with the name `af_blue_<s>_<n1>_<n2>_...' that store - # offsets to be used in conditional clauses. `<s>' is the number of - # sections seen so far, `<n1>' is the number of `#if' and `#endif' - # conditionals seen so far in the topmost level, `<n2>' the number of - # `#if' and `#endif' conditionals seen so far one level deeper, etc. - # As a consequence, uneven values are used within a clause, and even - # values after a clause, since the C standard doesn't allow the - # redefinition of an enumeration value. For example, the name - # `af_blue_5_1_6' is used to construct enumeration values in the fifth - # section after the third (second-level) if-clause within the first - # (top-level) if-clause. After the first top-level clause has - # finished, `af_blue_5_2' is used. The current offset is then - # relative to the value stored in the current auxiliary element. - - if (/ ^ \# \s* if /x) - { - push @else_stack, 0; - - $name_stack[$#name_stack]++; - - push @{$diversions{$curr_enum}}, enum_val_string(aux_name()); - $last_aux = aux_name(); - - push @name_stack, 0; - - $curr_offset = 0; - } - elsif (/ ^ \# \s* elif /x) - { - Die("unbalanced #elif") unless @else_stack; - - pop @name_stack; - - push @{$diversions{$curr_enum}}, enum_val_string(aux_name_next()); - $last_aux = aux_name(); - - push @name_stack, 0; - - $curr_offset = 0; - } - elsif (/ ^ \# \s* else /x) - { - my $prev_else = pop @else_stack; - Die("unbalanced #else") unless defined($prev_else); - Die("#else already seen") if $prev_else; - push @else_stack, 1; - - pop @name_stack; - - push @{$diversions{$curr_enum}}, enum_val_string(aux_name_next()); - $last_aux = aux_name(); - - push @name_stack, 0; - - $curr_offset = 0; - } - elsif (/ ^ (\# \s*) endif /x) - { - my $prev_else = pop @else_stack; - Die("unbalanced #endif") unless defined($prev_else); - - pop @name_stack; - - # If there is no else-clause for an if-clause, we add one. This is - # necessary to have correct offsets. - if (!$prev_else) - { - # Use amount of whitespace from `endif'. - push @{$diversions{$curr_enum}}, enum_val_string(aux_name_next()) - . $1 . "else\n"; - $last_aux = aux_name(); - - $curr_offset = 0; - } - - $name_stack[$#name_stack]++; - - push @{$diversions{$curr_enum}}, enum_val_string(aux_name()); - $last_aux = aux_name(); - - $curr_offset = 0; - } - - # Handle (probably continued) preprocessor lines. - CONTINUED_LOOP: - { - do - { - strip_newline(); - - push @{$diversions{$curr_enum}}, $ARG . "\n"; - push @{$diversions{$curr_array}}, $ARG . "\n"; - - last CONTINUED_LOOP unless / \\ $ /x; - - } while (<DATA>); - } - } - else - { - warn_before(); - } - - next; - } - - if (/$enum_element_re/) - { - end_curr_string(); - update_max_elem_size(); - - $curr_enum_element = $1; - $have_enum_element = 1; - $curr_elem_size = 0; - - next; - } - - if (/$string_re/) - { - if ($have_sections) - { - Die("strings and blocks can't be mixed in a section") if $have_blocks; - - # Save captured group from `string_re'. - my $string = $1; - - if ($have_enum_element) - { - push @{$diversions{$curr_enum}}, enum_val_string($curr_enum_element); - $have_enum_element = 0; - } - - $string = convert_literal($string); - - push @{$diversions{$curr_array}}, " $string\n"; - - $have_strings = 1; - $in_string = 1; - } - else - { - warn_before(); - } - - next; - } - - if (/$block_start_re/) - { - if ($have_sections) - { - Die("strings and blocks can't be mixed in a section") if $have_strings; - - my $depth = 0; - my $block = ""; - my $block_end = 0; - - # Count braces while getting the block. - BRACE_LOOP: - { - do - { - strip_newline(); - - foreach my $substring (split(/$brace_re/)) - { - if ($block_end) - { - Die("invalid data after last matching closing brace") - if $substring !~ /$whitespace_only_re/; - } - - $block .= $substring; - - if ($substring eq '{') - { - $depth++; - } - elsif ($substring eq '}') - { - $depth--; - - $block_end = 1 if $depth == 0; - } - } - - # If we are here, we have run out of substrings, so get next line - # or exit. - last BRACE_LOOP if $block_end; - - $block .= "\n"; - - } while (<DATA>); - } - - if ($have_enum_element) - { - push @{$diversions{$curr_enum}}, enum_val_string($curr_enum_element); - $have_enum_element = 0; - } - - push @{$diversions{$curr_array}}, $block . ",\n"; - - $curr_offset++; - $curr_elem_size++; - - $have_blocks = 1; - } - else - { - warn_before(); - } - - next; - } - - # Garbage. We weren't able to parse the data. - Die("syntax error"); -} - -# Finalize data. -end_curr_string(); -update_max_elem_size(); - - -# Filter stdin to stdout, replacing `@...@' templates. - -sub emit_diversion -{ - my $diversion_name = shift; - return (exists($diversions{$1})) ? "@{$diversions{$1}}" - : "@" . $diversion_name . "@"; -} - - -$LIST_SEPARATOR = ''; - -my $s1 = "This file has been generated by the Perl script \`$prog',"; -my $s1len = length $s1; -my $s2 = "using data from file \`$datafile'."; -my $s2len = length $s2; -my $slen = ($s1len > $s2len) ? $s1len : $s2len; - -print "/* " . $s1 . " " x ($slen - $s1len) . " */\n" - . "/* " . $s2 . " " x ($slen - $s2len) . " */\n" - . "\n"; - -while (<STDIN>) -{ - s/ @ ( [A-Za-z0-9_]+? ) @ / emit_diversion($1) /egx; - print; -} - -# EOF diff --git a/sdk/lib/3rdparty/freetype/src/tools/apinames.c b/sdk/lib/3rdparty/freetype/src/tools/apinames.c deleted file mode 100644 index 73bc99de5d9d4..0000000000000 --- a/sdk/lib/3rdparty/freetype/src/tools/apinames.c +++ /dev/null @@ -1,466 +0,0 @@ -/* - * This little program is used to parse the FreeType headers and - * find the declaration of all public APIs. This is easy, because - * they all look like the following: - * - * FT_EXPORT( return_type ) - * function_name( function arguments ); - * - * You must pass the list of header files as arguments. Wildcards are - * accepted if you are using GCC for compilation (and probably by - * other compilers too). - * - * Author: David Turner, 2005, 2006, 2008-2013, 2015 - * - * This code is explicitly placed into the public domain. - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> - -#define PROGRAM_NAME "apinames" -#define PROGRAM_VERSION "0.2" - -#define LINEBUFF_SIZE 1024 - -typedef enum OutputFormat_ -{ - OUTPUT_LIST = 0, /* output the list of names, one per line */ - OUTPUT_WINDOWS_DEF, /* output a Windows .DEF file for Visual C++ or Mingw */ - OUTPUT_BORLAND_DEF, /* output a Windows .DEF file for Borland C++ */ - OUTPUT_WATCOM_LBC, /* output a Watcom Linker Command File */ - OUTPUT_NETWARE_IMP /* output a NetWare ImportFile */ - -} OutputFormat; - - -static void -panic( const char* message ) -{ - fprintf( stderr, "PANIC: %s\n", message ); - exit(2); -} - - -typedef struct NameRec_ -{ - char* name; - unsigned int hash; - -} NameRec, *Name; - -static Name the_names; -static int num_names; -static int max_names; - -static void -names_add( const char* name, - const char* end ) -{ - unsigned int h; - int nn, len; - Name nm; - - if ( end <= name ) - return; - - /* compute hash value */ - len = (int)(end - name); - h = 0; - for ( nn = 0; nn < len; nn++ ) - h = h*33 + name[nn]; - - /* check for an pre-existing name */ - for ( nn = 0; nn < num_names; nn++ ) - { - nm = the_names + nn; - - if ( (int)nm->hash == h && - memcmp( name, nm->name, len ) == 0 && - nm->name[len] == 0 ) - return; - } - - /* add new name */ - if ( num_names >= max_names ) - { - max_names += (max_names >> 1) + 4; - the_names = (NameRec*)realloc( the_names, - sizeof ( the_names[0] ) * max_names ); - if ( !the_names ) - panic( "not enough memory" ); - } - nm = &the_names[num_names++]; - - nm->hash = h; - nm->name = (char*)malloc( len+1 ); - if ( !nm->name ) - panic( "not enough memory" ); - - memcpy( nm->name, name, len ); - nm->name[len] = 0; -} - - -static int -name_compare( const void* name1, - const void* name2 ) -{ - Name n1 = (Name)name1; - Name n2 = (Name)name2; - - return strcmp( n1->name, n2->name ); -} - -static void -names_sort( void ) -{ - qsort( the_names, (size_t)num_names, - sizeof ( the_names[0] ), name_compare ); -} - - -static void -names_dump( FILE* out, - OutputFormat format, - const char* dll_name ) -{ - int nn; - - - switch ( format ) - { - case OUTPUT_WINDOWS_DEF: - if ( dll_name ) - fprintf( out, "LIBRARY %s\n", dll_name ); - - fprintf( out, "DESCRIPTION FreeType 2 DLL\n" ); - fprintf( out, "EXPORTS\n" ); - for ( nn = 0; nn < num_names; nn++ ) - fprintf( out, " %s\n", the_names[nn].name ); - break; - - case OUTPUT_BORLAND_DEF: - if ( dll_name ) - fprintf( out, "LIBRARY %s\n", dll_name ); - - fprintf( out, "DESCRIPTION FreeType 2 DLL\n" ); - fprintf( out, "EXPORTS\n" ); - for ( nn = 0; nn < num_names; nn++ ) - fprintf( out, " _%s\n", the_names[nn].name ); - break; - - case OUTPUT_WATCOM_LBC: - { - const char* dot; - char temp[512]; - - - if ( !dll_name ) - { - fprintf( stderr, - "you must provide a DLL name with the -d option!\n" ); - exit( 4 ); - } - - /* we must omit the .dll suffix from the library name */ - dot = strchr( dll_name, '.' ); - if ( dot ) - { - int len = dot - dll_name; - - - if ( len > (int)( sizeof ( temp ) - 1 ) ) - len = sizeof ( temp ) - 1; - - memcpy( temp, dll_name, len ); - temp[len] = 0; - - dll_name = (const char*)temp; - } - - for ( nn = 0; nn < num_names; nn++ ) - fprintf( out, "++_%s.%s.%s\n", the_names[nn].name, dll_name, - the_names[nn].name ); - } - break; - - case OUTPUT_NETWARE_IMP: - { - if ( dll_name ) - fprintf( out, " (%s)\n", dll_name ); - for ( nn = 0; nn < num_names - 1; nn++ ) - fprintf( out, " %s,\n", the_names[nn].name ); - fprintf( out, " %s\n", the_names[num_names - 1].name ); - } - break; - - default: /* LIST */ - for ( nn = 0; nn < num_names; nn++ ) - fprintf( out, "%s\n", the_names[nn].name ); - } -} - - - - -/* states of the line parser */ - -typedef enum State_ -{ - STATE_START = 0, /* waiting for FT_EXPORT keyword and return type */ - STATE_TYPE /* type was read, waiting for function name */ - -} State; - -static int -read_header_file( FILE* file, int verbose ) -{ - static char buff[LINEBUFF_SIZE + 1]; - State state = STATE_START; - - while ( !feof( file ) ) - { - char* p; - - if ( !fgets( buff, LINEBUFF_SIZE, file ) ) - break; - - p = buff; - - while ( *p && (*p == ' ' || *p == '\\') ) /* skip leading whitespace */ - p++; - - if ( *p == '\n' || *p == '\r' ) /* skip empty lines */ - continue; - - switch ( state ) - { - case STATE_START: - { - if ( memcmp( p, "FT_EXPORT(", 10 ) != 0 ) - break; - - p += 10; - for (;;) - { - if ( *p == 0 || *p == '\n' || *p == '\r' ) - goto NextLine; - - if ( *p == ')' ) - { - p++; - break; - } - - p++; - } - - state = STATE_TYPE; - - /* sometimes, the name is just after the FT_EXPORT(...), so - * skip whitespace, and fall-through if we find an alphanumeric - * character - */ - while ( *p == ' ' || *p == '\t' ) - p++; - - if ( !isalpha(*p) ) - break; - } - /* fall-through */ - - case STATE_TYPE: - { - char* name = p; - - while ( isalnum(*p) || *p == '_' ) - p++; - - if ( p > name ) - { - if ( verbose ) - fprintf( stderr, ">>> %.*s\n", (int)(p - name), name ); - - names_add( name, p ); - } - - state = STATE_START; - } - break; - - default: - ; - } - - NextLine: - ; - } - - return 0; -} - - -static void -usage( void ) -{ - static const char* const format = - "%s %s: extract FreeType API names from header files\n\n" - "this program is used to extract the list of public FreeType API\n" - "functions. It receives the list of header files as argument and\n" - "generates a sorted list of unique identifiers\n\n" - - "usage: %s header1 [options] [header2 ...]\n\n" - - "options: - : parse the content of stdin, ignore arguments\n" - " -v : verbose mode, output sent to standard error\n" - " -oFILE : write output to FILE instead of standard output\n" - " -dNAME : indicate DLL file name, 'freetype.dll' by default\n" - " -w : output .DEF file for Visual C++ and Mingw\n" - " -wB : output .DEF file for Borland C++\n" - " -wW : output Watcom Linker Response File\n" - " -wN : output NetWare Import File\n" - "\n"; - - fprintf( stderr, - format, - PROGRAM_NAME, - PROGRAM_VERSION, - PROGRAM_NAME - ); - exit(1); -} - - -int main( int argc, const char* const* argv ) -{ - int from_stdin = 0; - int verbose = 0; - OutputFormat format = OUTPUT_LIST; /* the default */ - FILE* out = stdout; - const char* library_name = NULL; - - if ( argc < 2 ) - usage(); - - /* '-' used as a single argument means read source file from stdin */ - while ( argc > 1 && argv[1][0] == '-' ) - { - const char* arg = argv[1]; - - switch ( arg[1] ) - { - case 'v': - verbose = 1; - break; - - case 'o': - if ( arg[2] == 0 ) - { - if ( argc < 2 ) - usage(); - - arg = argv[2]; - argv++; - argc--; - } - else - arg += 2; - - out = fopen( arg, "wt" ); - if ( !out ) - { - fprintf( stderr, "could not open '%s' for writing\n", argv[2] ); - exit(3); - } - break; - - case 'd': - if ( arg[2] == 0 ) - { - if ( argc < 2 ) - usage(); - - arg = argv[2]; - argv++; - argc--; - } - else - arg += 2; - - library_name = arg; - break; - - case 'w': - format = OUTPUT_WINDOWS_DEF; - switch ( arg[2] ) - { - case 'B': - format = OUTPUT_BORLAND_DEF; - break; - - case 'W': - format = OUTPUT_WATCOM_LBC; - break; - - case 'N': - format = OUTPUT_NETWARE_IMP; - break; - - case 0: - break; - - default: - usage(); - } - break; - - case 0: - from_stdin = 1; - break; - - default: - usage(); - } - - argc--; - argv++; - } - - if ( from_stdin ) - { - read_header_file( stdin, verbose ); - } - else - { - for ( --argc, argv++; argc > 0; argc--, argv++ ) - { - FILE* file = fopen( argv[0], "rb" ); - - if ( !file ) - fprintf( stderr, "unable to open '%s'\n", argv[0] ); - else - { - if ( verbose ) - fprintf( stderr, "opening '%s'\n", argv[0] ); - - read_header_file( file, verbose ); - fclose( file ); - } - } - } - - if ( num_names == 0 ) - panic( "could not find exported functions !!\n" ); - - names_sort(); - names_dump( out, format, library_name ); - - if ( out != stdout ) - fclose( out ); - - return 0; -} diff --git a/sdk/lib/3rdparty/freetype/src/tools/chktrcmp.py b/sdk/lib/3rdparty/freetype/src/tools/chktrcmp.py deleted file mode 100644 index 4c40bdafdb574..0000000000000 --- a/sdk/lib/3rdparty/freetype/src/tools/chktrcmp.py +++ /dev/null @@ -1,114 +0,0 @@ -#!/usr/bin/env python -# -# Check trace components in FreeType 2 source. -# Author: suzuki toshiya, 2009, 2013 -# -# This code is explicitly into the public domain. - - -import sys -import os -import re - -SRC_FILE_LIST = [] -USED_COMPONENT = {} -KNOWN_COMPONENT = {} - -SRC_FILE_DIRS = [ "src" ] -TRACE_DEF_FILES = [ "include/freetype/internal/fttrace.h" ] - - -# -------------------------------------------------------------- -# Parse command line options -# - -for i in range( 1, len( sys.argv ) ): - if sys.argv[i].startswith( "--help" ): - print "Usage: %s [option]" % sys.argv[0] - print "Search used-but-defined and defined-but-not-used trace_XXX macros" - print "" - print " --help:" - print " Show this help" - print "" - print " --src-dirs=dir1:dir2:..." - print " Specify the directories of C source files to be checked" - print " Default is %s" % ":".join( SRC_FILE_DIRS ) - print "" - print " --def-files=file1:file2:..." - print " Specify the header files including FT_TRACE_DEF()" - print " Default is %s" % ":".join( TRACE_DEF_FILES ) - print "" - exit(0) - if sys.argv[i].startswith( "--src-dirs=" ): - SRC_FILE_DIRS = sys.argv[i].replace( "--src-dirs=", "", 1 ).split( ":" ) - elif sys.argv[i].startswith( "--def-files=" ): - TRACE_DEF_FILES = sys.argv[i].replace( "--def-files=", "", 1 ).split( ":" ) - - -# -------------------------------------------------------------- -# Scan C source and header files using trace macros. -# - -c_pathname_pat = re.compile( '^.*\.[ch]$', re.IGNORECASE ) -trace_use_pat = re.compile( '^[ \t]*#define[ \t]+FT_COMPONENT[ \t]+trace_' ) - -for d in SRC_FILE_DIRS: - for ( p, dlst, flst ) in os.walk( d ): - for f in flst: - if c_pathname_pat.match( f ) != None: - src_pathname = os.path.join( p, f ) - - line_num = 0 - for src_line in open( src_pathname, 'r' ): - line_num = line_num + 1 - src_line = src_line.strip() - if trace_use_pat.match( src_line ) != None: - component_name = trace_use_pat.sub( '', src_line ) - if component_name in USED_COMPONENT: - USED_COMPONENT[component_name].append( "%s:%d" % ( src_pathname, line_num ) ) - else: - USED_COMPONENT[component_name] = [ "%s:%d" % ( src_pathname, line_num ) ] - - -# -------------------------------------------------------------- -# Scan header file(s) defining trace macros. -# - -trace_def_pat_opn = re.compile( '^.*FT_TRACE_DEF[ \t]*\([ \t]*' ) -trace_def_pat_cls = re.compile( '[ \t\)].*$' ) - -for f in TRACE_DEF_FILES: - line_num = 0 - for hdr_line in open( f, 'r' ): - line_num = line_num + 1 - hdr_line = hdr_line.strip() - if trace_def_pat_opn.match( hdr_line ) != None: - component_name = trace_def_pat_opn.sub( '', hdr_line ) - component_name = trace_def_pat_cls.sub( '', component_name ) - if component_name in KNOWN_COMPONENT: - print "trace component %s is defined twice, see %s and fttrace.h:%d" % \ - ( component_name, KNOWN_COMPONENT[component_name], line_num ) - else: - KNOWN_COMPONENT[component_name] = "%s:%d" % \ - ( os.path.basename( f ), line_num ) - - -# -------------------------------------------------------------- -# Compare the used and defined trace macros. -# - -print "# Trace component used in the implementations but not defined in fttrace.h." -cmpnt = USED_COMPONENT.keys() -cmpnt.sort() -for c in cmpnt: - if c not in KNOWN_COMPONENT: - print "Trace component %s (used in %s) is not defined." % ( c, ", ".join( USED_COMPONENT[c] ) ) - -print "# Trace component is defined but not used in the implementations." -cmpnt = KNOWN_COMPONENT.keys() -cmpnt.sort() -for c in cmpnt: - if c not in USED_COMPONENT: - if c != "any": - print "Trace component %s (defined in %s) is not used." % ( c, KNOWN_COMPONENT[c] ) - diff --git a/sdk/lib/3rdparty/freetype/src/tools/cordic.py b/sdk/lib/3rdparty/freetype/src/tools/cordic.py deleted file mode 100644 index 6742c90dfefb8..0000000000000 --- a/sdk/lib/3rdparty/freetype/src/tools/cordic.py +++ /dev/null @@ -1,33 +0,0 @@ -# compute arctangent table for CORDIC computations in fttrigon.c -import sys, math - -#units = 64*65536.0 # don't change !! -units = 180 * 2**16 -scale = units/math.pi -shrink = 1.0 -comma = "" - -print "" -print "table of arctan( 1/2^n ) for PI = " + repr(units/65536.0) + " units" - -for n in range(1,32): - - x = 0.5**n # tangent value - - angle = math.atan(x) # arctangent - angle2 = round(angle*scale) # arctangent in FT_Angle units - - if angle2 <= 0: - break - - sys.stdout.write( comma + repr( int(angle2) ) ) - comma = ", " - - shrink /= math.sqrt( 1 + x*x ) - -print -print "shrink factor = " + repr( shrink ) -print "shrink factor 2 = " + repr( int( shrink * (2**32) ) ) -print "expansion factor = " + repr( 1/shrink ) -print "" - diff --git a/sdk/lib/3rdparty/freetype/src/tools/docmaker/content.py b/sdk/lib/3rdparty/freetype/src/tools/docmaker/content.py deleted file mode 100644 index c9969dbe5bbf4..0000000000000 --- a/sdk/lib/3rdparty/freetype/src/tools/docmaker/content.py +++ /dev/null @@ -1,672 +0,0 @@ -# -# content.py -# -# Parse comment blocks to build content blocks (library file). -# -# Copyright 2002-2018 by -# David Turner. -# -# This file is part of the FreeType project, and may only be used, -# modified, and distributed under the terms of the FreeType project -# license, LICENSE.TXT. By continuing to use, modify, or distribute -# this file you indicate that you have read the license and -# understand and accept it fully. - -# -# This file contains routines to parse documentation comment blocks, -# building more structured objects out of them. -# - - -from sources import * -from utils import * - -import string, re - - -# -# Regular expressions to detect code sequences. `Code sequences' are simply -# code fragments embedded in '{' and '}', as demonstrated in the following -# example. -# -# { -# x = y + z; -# if ( zookoo == 2 ) -# { -# foobar(); -# } -# } -# -# Note that the indentation of the first opening brace and the last closing -# brace must be exactly the same. The code sequence itself should have a -# larger indentation than the surrounding braces. -# -re_code_start = re.compile( r"(\s*){\s*$" ) -re_code_end = re.compile( r"(\s*)}\s*$" ) - - -# -# A regular expression to isolate identifiers from other text. Two syntax -# forms are supported: -# -# <name> -# <name>[<id>] -# -# where both `<name>' and `<id>' consist of alphanumeric characters, `_', -# and `-'. Use `<id>' if there are multiple, valid `<name>' entries; in the -# index, `<id>' will be appended in parentheses. -# -# For example, -# -# stem_darkening[autofit] -# -# becomes `stem_darkening (autofit)' in the index. -# -re_identifier = re.compile( r""" - ((?:\w|-)+ - (?:\[(?:\w|-)+\])?) - """, re.VERBOSE ) - - -# -# We collect macro names ending in `_H' (group 1), as defined in -# `freetype/config/ftheader.h'. While outputting the object data, we use -# this info together with the object's file location (group 2) to emit the -# appropriate header file macro and its associated file name before the -# object itself. -# -# Example: -# -# #define FT_FREETYPE_H <freetype.h> -# -re_header_macro = re.compile( r'^#define\s{1,}(\w{1,}_H)\s{1,}<(.*)>' ) - - -################################################################ -## -## DOC CODE CLASS -## -## The `DocCode' class is used to store source code lines. -## -## `self.lines' contains a set of source code lines that will be dumped as -## HTML in a <PRE> tag. -## -## The object is filled line by line by the parser; it strips the leading -## `margin' space from each input line before storing it in `self.lines'. -## -class DocCode: - - def __init__( self, margin, lines ): - self.lines = [] - self.words = None - - # remove margin spaces - for l in lines: - if string.strip( l[:margin] ) == "": - l = l[margin:] - self.lines.append( l ) - - def dump( self, prefix = "", width = 60 ): - lines = self.dump_lines( 0, width ) - for l in lines: - print prefix + l - - def dump_lines( self, margin = 0, width = 60 ): - result = [] - for l in self.lines: - result.append( " " * margin + l ) - return result - - - -################################################################ -## -## DOC PARA CLASS -## -## `Normal' text paragraphs are stored in the `DocPara' class. -## -## `self.words' contains the list of words that make up the paragraph. -## -class DocPara: - - def __init__( self, lines ): - self.lines = None - self.words = [] - for l in lines: - l = string.strip( l ) - self.words.extend( string.split( l ) ) - - def dump( self, prefix = "", width = 60 ): - lines = self.dump_lines( 0, width ) - for l in lines: - print prefix + l - - def dump_lines( self, margin = 0, width = 60 ): - cur = "" # current line - col = 0 # current width - result = [] - - for word in self.words: - ln = len( word ) - if col > 0: - ln = ln + 1 - - if col + ln > width: - result.append( " " * margin + cur ) - cur = word - col = len( word ) - else: - if col > 0: - cur = cur + " " - cur = cur + word - col = col + ln - - if col > 0: - result.append( " " * margin + cur ) - - return result - - -################################################################ -## -## DOC FIELD CLASS -## -## The `DocField' class stores a list containing either `DocPara' or -## `DocCode' objects. Each DocField object also has an optional `name' -## that is used when the object corresponds to a field or value definition. -## -class DocField: - - def __init__( self, name, lines ): - self.name = name # can be `None' for normal paragraphs/sources - self.items = [] # list of items - - mode_none = 0 # start parsing mode - mode_code = 1 # parsing code sequences - mode_para = 3 # parsing normal paragraph - - margin = -1 # current code sequence indentation - cur_lines = [] - - # analyze the markup lines to check whether they contain paragraphs, - # code sequences, or fields definitions - # - start = 0 - mode = mode_none - - for l in lines: - # are we parsing a code sequence? - if mode == mode_code: - m = re_code_end.match( l ) - if m and len( m.group( 1 ) ) <= margin: - # that's it, we finished the code sequence - code = DocCode( 0, cur_lines ) - self.items.append( code ) - margin = -1 - cur_lines = [] - mode = mode_none - else: - # otherwise continue the code sequence - cur_lines.append( l[margin:] ) - else: - # start of code sequence? - m = re_code_start.match( l ) - if m: - # save current lines - if cur_lines: - para = DocPara( cur_lines ) - self.items.append( para ) - cur_lines = [] - - # switch to code extraction mode - margin = len( m.group( 1 ) ) - mode = mode_code - else: - if not string.split( l ) and cur_lines: - # if the line is empty, we end the current paragraph, - # if any - para = DocPara( cur_lines ) - self.items.append( para ) - cur_lines = [] - else: - # otherwise, simply add the line to the current - # paragraph - cur_lines.append( l ) - - if mode == mode_code: - # unexpected end of code sequence - code = DocCode( margin, cur_lines ) - self.items.append( code ) - elif cur_lines: - para = DocPara( cur_lines ) - self.items.append( para ) - - def dump( self, prefix = "" ): - if self.field: - print prefix + self.field + " ::" - prefix = prefix + "----" - - first = 1 - for p in self.items: - if not first: - print "" - p.dump( prefix ) - first = 0 - - def dump_lines( self, margin = 0, width = 60 ): - result = [] - nl = None - - for p in self.items: - if nl: - result.append( "" ) - - result.extend( p.dump_lines( margin, width ) ) - nl = 1 - - return result - - -# -# A regular expression to detect field definitions. -# -# Examples: -# -# foo :: -# foo.bar :: -# -re_field = re.compile( r""" - \s* - ( - \w* - | - \w (\w | \.)* \w - ) - \s* :: - """, re.VERBOSE ) - - -################################################################ -## -## DOC MARKUP CLASS -## -class DocMarkup: - - def __init__( self, tag, lines ): - self.tag = string.lower( tag ) - self.fields = [] - - cur_lines = [] - field = None - mode = 0 - - for l in lines: - m = re_field.match( l ) - if m: - # We detected the start of a new field definition. - - # first, save the current one - if cur_lines: - f = DocField( field, cur_lines ) - self.fields.append( f ) - cur_lines = [] - field = None - - field = m.group( 1 ) # record field name - ln = len( m.group( 0 ) ) - l = " " * ln + l[ln:] - cur_lines = [l] - else: - cur_lines.append( l ) - - if field or cur_lines: - f = DocField( field, cur_lines ) - self.fields.append( f ) - - def get_name( self ): - try: - return self.fields[0].items[0].words[0] - except: - return None - - def dump( self, margin ): - print " " * margin + "<" + self.tag + ">" - for f in self.fields: - f.dump( " " ) - print " " * margin + "</" + self.tag + ">" - - -################################################################ -## -## DOC CHAPTER CLASS -## -class DocChapter: - - def __init__( self, block ): - self.block = block - self.sections = [] - if block: - self.name = block.name - self.title = block.get_markup_words( "title" ) - self.order = block.get_markup_words( "sections" ) - else: - self.name = "Other" - self.title = string.split( "Miscellaneous" ) - self.order = [] - - -################################################################ -## -## DOC SECTION CLASS -## -class DocSection: - - def __init__( self, name = "Other" ): - self.name = name - self.blocks = {} - self.block_names = [] # ordered block names in section - self.defs = [] - self.abstract = "" - self.description = "" - self.order = [] - self.title = "ERROR" - self.chapter = None - - def add_def( self, block ): - self.defs.append( block ) - - def add_block( self, block ): - self.block_names.append( block.name ) - self.blocks[block.name] = block - - def process( self ): - # look up one block that contains a valid section description - for block in self.defs: - title = block.get_markup_text( "title" ) - if title: - self.title = title - self.abstract = block.get_markup_words( "abstract" ) - self.description = block.get_markup_items( "description" ) - self.order = block.get_markup_words_all( "order" ) - return - - def reorder( self ): - self.block_names = sort_order_list( self.block_names, self.order ) - - -################################################################ -## -## CONTENT PROCESSOR CLASS -## -class ContentProcessor: - - def __init__( self ): - """Initialize a block content processor.""" - self.reset() - - self.sections = {} # dictionary of documentation sections - self.section = None # current documentation section - - self.chapters = [] # list of chapters - - self.headers = {} # dictionary of header macros - - def set_section( self, section_name ): - """Set current section during parsing.""" - if not section_name in self.sections: - section = DocSection( section_name ) - self.sections[section_name] = section - self.section = section - else: - self.section = self.sections[section_name] - - def add_chapter( self, block ): - chapter = DocChapter( block ) - self.chapters.append( chapter ) - - def reset( self ): - """Reset the content processor for a new block.""" - self.markups = [] - self.markup = None - self.markup_lines = [] - - def add_markup( self ): - """Add a new markup section.""" - if self.markup and self.markup_lines: - - # get rid of last line of markup if it's empty - marks = self.markup_lines - if len( marks ) > 0 and not string.strip( marks[-1] ): - self.markup_lines = marks[:-1] - - m = DocMarkup( self.markup, self.markup_lines ) - - self.markups.append( m ) - - self.markup = None - self.markup_lines = [] - - def process_content( self, content ): - """Process a block content and return a list of DocMarkup objects - corresponding to it.""" - markup = None - markup_lines = [] - first = 1 - - margin = -1 - in_code = 0 - - for line in content: - if in_code: - m = re_code_end.match( line ) - if m and len( m.group( 1 ) ) <= margin: - in_code = 0 - margin = -1 - else: - m = re_code_start.match( line ) - if m: - in_code = 1 - margin = len( m.group( 1 ) ) - - found = None - - if not in_code: - for t in re_markup_tags: - m = t.match( line ) - if m: - found = string.lower( m.group( 1 ) ) - prefix = len( m.group( 0 ) ) - # remove markup from line - line = " " * prefix + line[prefix:] - break - - # is it the start of a new markup section ? - if found: - first = 0 - self.add_markup() # add current markup content - self.markup = found - if len( string.strip( line ) ) > 0: - self.markup_lines.append( line ) - elif first == 0: - self.markup_lines.append( line ) - - self.add_markup() - - return self.markups - - def parse_sources( self, source_processor ): - blocks = source_processor.blocks - count = len( blocks ) - - for n in range( count ): - source = blocks[n] - if source.content: - # this is a documentation comment, we need to catch - # all following normal blocks in the "follow" list - # - follow = [] - m = n + 1 - while m < count and not blocks[m].content: - follow.append( blocks[m] ) - m = m + 1 - - doc_block = DocBlock( source, follow, self ) - - def finish( self ): - # process all sections to extract their abstract, description - # and ordered list of items - # - for sec in self.sections.values(): - sec.process() - - # process chapters to check that all sections are correctly - # listed there - for chap in self.chapters: - for sec in chap.order: - if sec in self.sections: - section = self.sections[sec] - section.chapter = chap - section.reorder() - chap.sections.append( section ) - else: - sys.stderr.write( "WARNING: chapter '" + \ - chap.name + "' in " + chap.block.location() + \ - " lists unknown section '" + sec + "'\n" ) - - # check that all sections are in a chapter - # - others = [] - for sec in self.sections.values(): - if not sec.chapter: - sec.reorder() - others.append( sec ) - - # create a new special chapter for all remaining sections - # when necessary - # - if others: - chap = DocChapter( None ) - chap.sections = others - self.chapters.append( chap ) - - -################################################################ -## -## DOC BLOCK CLASS -## -class DocBlock: - - def __init__( self, source, follow, processor ): - processor.reset() - - self.source = source - self.code = [] - self.type = "ERRTYPE" - self.name = "ERRNAME" - self.section = processor.section - self.markups = processor.process_content( source.content ) - - # compute block type from first markup tag - try: - self.type = self.markups[0].tag - except: - pass - - # compute block name from first markup paragraph - try: - markup = self.markups[0] - para = markup.fields[0].items[0] - name = para.words[0] - m = re_identifier.match( name ) - if m: - name = m.group( 1 ) - self.name = name - except: - pass - - if self.type == "section": - # detect new section starts - processor.set_section( self.name ) - processor.section.add_def( self ) - elif self.type == "chapter": - # detect new chapter - processor.add_chapter( self ) - else: - processor.section.add_block( self ) - - # now, compute the source lines relevant to this documentation - # block. We keep normal comments in for obvious reasons (??) - source = [] - for b in follow: - if b.format: - break - for l in b.lines: - # collect header macro definitions - m = re_header_macro.match( l ) - if m: - processor.headers[m.group( 2 )] = m.group( 1 ); - - # we use "/* */" as a separator - if re_source_sep.match( l ): - break - source.append( l ) - - # now strip the leading and trailing empty lines from the sources - start = 0 - end = len( source ) - 1 - - while start < end and not string.strip( source[start] ): - start = start + 1 - - while start < end and not string.strip( source[end] ): - end = end - 1 - - if start == end and not string.strip( source[start] ): - self.code = [] - else: - self.code = source[start:end + 1] - - def location( self ): - return self.source.location() - - def get_markup( self, tag_name ): - """Return the DocMarkup corresponding to a given tag in a block.""" - for m in self.markups: - if m.tag == string.lower( tag_name ): - return m - return None - - def get_markup_words( self, tag_name ): - try: - m = self.get_markup( tag_name ) - return m.fields[0].items[0].words - except: - return [] - - def get_markup_words_all( self, tag_name ): - try: - m = self.get_markup( tag_name ) - words = [] - for item in m.fields[0].items: - # We honour empty lines in an `<Order>' section element by - # adding the sentinel `/empty/'. The formatter should then - # convert it to an appropriate representation in the - # `section_enter' function. - words += item.words - words.append( "/empty/" ) - return words - except: - return [] - - def get_markup_text( self, tag_name ): - result = self.get_markup_words( tag_name ) - return string.join( result ) - - def get_markup_items( self, tag_name ): - try: - m = self.get_markup( tag_name ) - return m.fields[0].items - except: - return None - -# eof diff --git a/sdk/lib/3rdparty/freetype/src/tools/docmaker/docbeauty.py b/sdk/lib/3rdparty/freetype/src/tools/docmaker/docbeauty.py deleted file mode 100644 index 3ddf4a94a1551..0000000000000 --- a/sdk/lib/3rdparty/freetype/src/tools/docmaker/docbeauty.py +++ /dev/null @@ -1,113 +0,0 @@ -#!/usr/bin/env python -# -# DocBeauty (c) 2003, 2004, 2008 David Turner <david@freetype.org> -# -# This program is used to beautify the documentation comments used -# in the FreeType 2 public headers. -# - -from sources import * -from content import * -from utils import * - -import utils - -import sys, os, time, string, getopt - - -content_processor = ContentProcessor() - - -def beautify_block( block ): - if block.content: - content_processor.reset() - - markups = content_processor.process_content( block.content ) - text = [] - first = 1 - - for markup in markups: - text.extend( markup.beautify( first ) ) - first = 0 - - # now beautify the documentation "borders" themselves - lines = [" /*************************************************************************"] - for l in text: - lines.append( " *" + l ) - lines.append( " */" ) - - block.lines = lines - - -def usage(): - print "\nDocBeauty 0.1 Usage information\n" - print " docbeauty [options] file1 [file2 ...]\n" - print "using the following options:\n" - print " -h : print this page" - print " -b : backup original files with the 'orig' extension" - print "" - print " --backup : same as -b" - - -def main( argv ): - """main program loop""" - - global output_dir - - try: - opts, args = getopt.getopt( sys.argv[1:], \ - "hb", \ - ["help", "backup"] ) - except getopt.GetoptError: - usage() - sys.exit( 2 ) - - if args == []: - usage() - sys.exit( 1 ) - - # process options - # - output_dir = None - do_backup = None - - for opt in opts: - if opt[0] in ( "-h", "--help" ): - usage() - sys.exit( 0 ) - - if opt[0] in ( "-b", "--backup" ): - do_backup = 1 - - # create context and processor - source_processor = SourceProcessor() - - # retrieve the list of files to process - file_list = make_file_list( args ) - for filename in file_list: - source_processor.parse_file( filename ) - - for block in source_processor.blocks: - beautify_block( block ) - - new_name = filename + ".new" - ok = None - - try: - file = open( new_name, "wt" ) - for block in source_processor.blocks: - for line in block.lines: - file.write( line ) - file.write( "\n" ) - file.close() - except: - ok = 0 - - -# if called from the command line -# -if __name__ == '__main__': - main( sys.argv ) - - -# eof diff --git a/sdk/lib/3rdparty/freetype/src/tools/docmaker/docmaker.py b/sdk/lib/3rdparty/freetype/src/tools/docmaker/docmaker.py deleted file mode 100644 index 253a4d35af7af..0000000000000 --- a/sdk/lib/3rdparty/freetype/src/tools/docmaker/docmaker.py +++ /dev/null @@ -1,115 +0,0 @@ -#!/usr/bin/env python -# -# docmaker.py -# -# Convert source code markup to HTML documentation. -# -# Copyright 2002-2018 by -# David Turner. -# -# This file is part of the FreeType project, and may only be used, -# modified, and distributed under the terms of the FreeType project -# license, LICENSE.TXT. By continuing to use, modify, or distribute -# this file you indicate that you have read the license and -# understand and accept it fully. - -# -# This program is a re-write of the original DocMaker tool used to generate -# the API Reference of the FreeType font rendering engine by converting -# in-source comments into structured HTML. -# -# This new version is capable of outputting XML data as well as accepting -# more liberal formatting options. It also uses regular expression matching -# and substitution to speed up operation significantly. -# - -from sources import * -from content import * -from utils import * -from formatter import * -from tohtml import * - -import utils - -import sys, os, time, string, glob, getopt - - -def usage(): - print "\nDocMaker Usage information\n" - print " docmaker [options] file1 [file2 ...]\n" - print "using the following options:\n" - print " -h : print this page" - print " -t : set project title, as in '-t \"My Project\"'" - print " -o : set output directory, as in '-o mydir'" - print " -p : set documentation prefix, as in '-p ft2'" - print "" - print " --title : same as -t, as in '--title=\"My Project\"'" - print " --output : same as -o, as in '--output=mydir'" - print " --prefix : same as -p, as in '--prefix=ft2'" - - -def main( argv ): - """Main program loop.""" - - global output_dir - - try: - opts, args = getopt.getopt( sys.argv[1:], - "ht:o:p:", - ["help", "title=", "output=", "prefix="] ) - except getopt.GetoptError: - usage() - sys.exit( 2 ) - - if args == []: - usage() - sys.exit( 1 ) - - # process options - project_title = "Project" - project_prefix = None - output_dir = None - - for opt in opts: - if opt[0] in ( "-h", "--help" ): - usage() - sys.exit( 0 ) - - if opt[0] in ( "-t", "--title" ): - project_title = opt[1] - - if opt[0] in ( "-o", "--output" ): - utils.output_dir = opt[1] - - if opt[0] in ( "-p", "--prefix" ): - project_prefix = opt[1] - - check_output() - - # create context and processor - source_processor = SourceProcessor() - content_processor = ContentProcessor() - - # retrieve the list of files to process - file_list = make_file_list( args ) - for filename in file_list: - source_processor.parse_file( filename ) - content_processor.parse_sources( source_processor ) - - # process sections - content_processor.finish() - - formatter = HtmlFormatter( content_processor, - project_title, - project_prefix ) - - formatter.toc_dump() - formatter.index_dump() - formatter.section_dump_all() - - -# if called from the command line -if __name__ == '__main__': - main( sys.argv ) - -# eof diff --git a/sdk/lib/3rdparty/freetype/src/tools/docmaker/formatter.py b/sdk/lib/3rdparty/freetype/src/tools/docmaker/formatter.py deleted file mode 100644 index 2708fd40d60cc..0000000000000 --- a/sdk/lib/3rdparty/freetype/src/tools/docmaker/formatter.py +++ /dev/null @@ -1,228 +0,0 @@ -# -# formatter.py -# -# Convert parsed content blocks to a structured document (library file). -# -# Copyright 2002-2018 by -# David Turner. -# -# This file is part of the FreeType project, and may only be used, -# modified, and distributed under the terms of the FreeType project -# license, LICENSE.TXT. By continuing to use, modify, or distribute -# this file you indicate that you have read the license and -# understand and accept it fully. - -# -# This is the base Formatter class. Its purpose is to convert a content -# processor's data into specific documents (i.e., table of contents, global -# index, and individual API reference indices). -# -# You need to sub-class it to output anything sensible. For example, the -# file `tohtml.py' contains the definition of the `HtmlFormatter' sub-class -# to output HTML. -# - - -from sources import * -from content import * -from utils import * - - -################################################################ -## -## FORMATTER CLASS -## -class Formatter: - - def __init__( self, processor ): - self.processor = processor - self.identifiers = {} - self.chapters = processor.chapters - self.sections = processor.sections.values() - self.block_index = [] - - # store all blocks in a dictionary - self.blocks = [] - for section in self.sections: - for block in section.blocks.values(): - self.add_identifier( block.name, block ) - - # add enumeration values to the index, since this is useful - for markup in block.markups: - if markup.tag == 'values': - for field in markup.fields: - self.add_identifier( field.name, block ) - - self.block_index = self.identifiers.keys() - self.block_index.sort( key = index_key ) - - # also add section names to dictionary (without making them appear - # in the index) - for section in self.sections: - self.add_identifier( section.name, section ) - - def add_identifier( self, name, block ): - if name in self.identifiers: - # duplicate name! - sys.stderr.write( "WARNING: duplicate definition for" - + " '" + name + "' " - + "in " + block.location() + ", " - + "previous definition in " - + self.identifiers[name].location() - + "\n" ) - else: - self.identifiers[name] = block - - # - # formatting the table of contents - # - def toc_enter( self ): - pass - - def toc_chapter_enter( self, chapter ): - pass - - def toc_section_enter( self, section ): - pass - - def toc_section_exit( self, section ): - pass - - def toc_chapter_exit( self, chapter ): - pass - - def toc_index( self, index_filename ): - pass - - def toc_exit( self ): - pass - - def toc_dump( self, toc_filename = None, index_filename = None ): - output = None - if toc_filename: - output = open_output( toc_filename ) - - self.toc_enter() - - for chap in self.processor.chapters: - - self.toc_chapter_enter( chap ) - - for section in chap.sections: - self.toc_section_enter( section ) - self.toc_section_exit( section ) - - self.toc_chapter_exit( chap ) - - self.toc_index( index_filename ) - - self.toc_exit() - - if output: - close_output( output ) - - # - # formatting the index - # - def index_enter( self ): - pass - - def index_name_enter( self, name ): - pass - - def index_name_exit( self, name ): - pass - - def index_exit( self ): - pass - - def index_dump( self, index_filename = None ): - output = None - if index_filename: - output = open_output( index_filename ) - - self.index_enter() - - for name in self.block_index: - self.index_name_enter( name ) - self.index_name_exit( name ) - - self.index_exit() - - if output: - close_output( output ) - - # - # formatting a section - # - def section_enter( self, section ): - pass - - def block_enter( self, block ): - pass - - def markup_enter( self, markup, block = None ): - pass - - def field_enter( self, field, markup = None, block = None ): - pass - - def field_exit( self, field, markup = None, block = None ): - pass - - def markup_exit( self, markup, block = None ): - pass - - def block_exit( self, block ): - pass - - def section_exit( self, section ): - pass - - def section_dump( self, section, section_filename = None ): - output = None - if section_filename: - output = open_output( section_filename ) - - self.section_enter( section ) - - for name in section.block_names: - skip_entry = 0 - try: - block = self.identifiers[name] - # `block_names' can contain field names also, - # which we filter out - for markup in block.markups: - if markup.tag == 'values': - for field in markup.fields: - if field.name == name: - skip_entry = 1 - except: - skip_entry = 1 # this happens e.g. for `/empty/' entries - - if skip_entry: - continue - - self.block_enter( block ) - - for markup in block.markups[1:]: # always ignore first markup! - self.markup_enter( markup, block ) - - for field in markup.fields: - self.field_enter( field, markup, block ) - self.field_exit( field, markup, block ) - - self.markup_exit( markup, block ) - - self.block_exit( block ) - - self.section_exit( section ) - - if output: - close_output( output ) - - def section_dump_all( self ): - for section in self.sections: - self.section_dump( section ) - -# eof diff --git a/sdk/lib/3rdparty/freetype/src/tools/docmaker/sources.py b/sdk/lib/3rdparty/freetype/src/tools/docmaker/sources.py deleted file mode 100644 index 2cd5a3379c253..0000000000000 --- a/sdk/lib/3rdparty/freetype/src/tools/docmaker/sources.py +++ /dev/null @@ -1,410 +0,0 @@ -# -# sources.py -# -# Convert source code comments to multi-line blocks (library file). -# -# Copyright 2002-2018 by -# David Turner. -# -# This file is part of the FreeType project, and may only be used, -# modified, and distributed under the terms of the FreeType project -# license, LICENSE.TXT. By continuing to use, modify, or distribute -# this file you indicate that you have read the license and -# understand and accept it fully. - -# -# This library file contains definitions of classes needed to decompose C -# source code files into a series of multi-line `blocks'. There are two -# kinds of blocks. -# -# - Normal blocks, which contain source code or ordinary comments. -# -# - Documentation blocks, which have restricted formatting, and whose text -# always start with a documentation markup tag like `<Function>', -# `<Type>', etc. -# -# The routines to process the content of documentation blocks are contained -# in file `content.py'; the classes and methods found here only deal with -# text parsing and basic documentation block extraction. -# - - -import fileinput, re, sys, os, string - - -################################################################ -## -## SOURCE BLOCK FORMAT CLASS -## -## A simple class containing compiled regular expressions to detect -## potential documentation format block comments within C source code. -## -## The `column' pattern must contain a group to `unbox' the content of -## documentation comment blocks. -## -## Later on, paragraphs are converted to long lines, which simplifies the -## regular expressions that act upon the text. -## -class SourceBlockFormat: - - def __init__( self, id, start, column, end ): - """Create a block pattern, used to recognize special documentation - blocks.""" - self.id = id - self.start = re.compile( start, re.VERBOSE ) - self.column = re.compile( column, re.VERBOSE ) - self.end = re.compile( end, re.VERBOSE ) - - -# -# Format 1 documentation comment blocks. -# -# /************************************/ (at least 2 asterisks) -# /* */ -# /* */ -# /* */ -# /************************************/ (at least 2 asterisks) -# -start = r''' - \s* # any number of whitespace - /\*{2,}/ # followed by '/' and at least two asterisks then '/' - \s*$ # probably followed by whitespace -''' - -column = r''' - \s* # any number of whitespace - /\*{1} # followed by '/' and precisely one asterisk - ([^*].*) # followed by anything (group 1) - \*{1}/ # followed by one asterisk and a '/' - \s*$ # probably followed by whitespace -''' - -re_source_block_format1 = SourceBlockFormat( 1, start, column, start ) - - -# -# Format 2 documentation comment blocks. -# -# /************************************ (at least 2 asterisks) -# * -# * (1 asterisk) -# * -# */ (1 or more asterisks) -# -start = r''' - \s* # any number of whitespace - /\*{2,} # followed by '/' and at least two asterisks - \s*$ # probably followed by whitespace -''' - -column = r''' - \s* # any number of whitespace - \*{1}(?![*/]) # followed by precisely one asterisk not followed by `/' - (.*) # then anything (group1) -''' - -end = r''' - \s* # any number of whitespace - \*+/ # followed by at least one asterisk, then '/' -''' - -re_source_block_format2 = SourceBlockFormat( 2, start, column, end ) - - -# -# The list of supported documentation block formats. We could add new ones -# quite easily. -# -re_source_block_formats = [re_source_block_format1, re_source_block_format2] - - -# -# The following regular expressions correspond to markup tags within the -# documentation comment blocks. They are equivalent despite their different -# syntax. -# -# A markup tag consists of letters or character `-', to be found in group 1. -# -# Notice that a markup tag _must_ begin a new paragraph. -# -re_markup_tag1 = re.compile( r'''\s*<((?:\w|-)*)>''' ) # <xxxx> format -re_markup_tag2 = re.compile( r'''\s*@((?:\w|-)*):''' ) # @xxxx: format - -# -# The list of supported markup tags. We could add new ones quite easily. -# -re_markup_tags = [re_markup_tag1, re_markup_tag2] - - -# -# A regular expression to detect a cross reference, after markup tags have -# been stripped off. -# -# Two syntax forms are supported: -# -# @<name> -# @<name>[<id>] -# -# where both `<name>' and `<id>' consist of alphanumeric characters, `_', -# and `-'. Use `<id>' if there are multiple, valid `<name>' entries. -# -# Example: @foo[bar] -# -re_crossref = re.compile( r""" - @ - (?P<name>(?:\w|-)+ - (?:\[(?:\w|-)+\])?) - (?P<rest>.*) - """, re.VERBOSE ) - -# -# Two regular expressions to detect italic and bold markup, respectively. -# Group 1 is the markup, group 2 the rest of the line. -# -# Note that the markup is limited to words consisting of letters, digits, -# the characters `_' and `-', or an apostrophe (but not as the first -# character). -# -re_italic = re.compile( r"_((?:\w|-)(?:\w|'|-)*)_(.*)" ) # _italic_ -re_bold = re.compile( r"\*((?:\w|-)(?:\w|'|-)*)\*(.*)" ) # *bold* - -# -# This regular expression code to identify an URL has been taken from -# -# https://mail.python.org/pipermail/tutor/2002-September/017228.html -# -# (with slight modifications). -# -urls = r'(?:https?|telnet|gopher|file|wais|ftp)' -ltrs = r'\w' -gunk = r'/#~:.?+=&%@!\-' -punc = r'.:?\-' -any = "%(ltrs)s%(gunk)s%(punc)s" % { 'ltrs' : ltrs, - 'gunk' : gunk, - 'punc' : punc } -url = r""" - ( - \b # start at word boundary - %(urls)s : # need resource and a colon - [%(any)s] +? # followed by one or more of any valid - # character, but be conservative and - # take only what you need to... - (?= # [look-ahead non-consumptive assertion] - [%(punc)s]* # either 0 or more punctuation - (?: # [non-grouping parentheses] - [^%(any)s] | $ # followed by a non-url char - # or end of the string - ) - ) - ) - """ % {'urls' : urls, - 'any' : any, - 'punc' : punc } - -re_url = re.compile( url, re.VERBOSE | re.MULTILINE ) - -# -# A regular expression that stops collection of comments for the current -# block. -# -re_source_sep = re.compile( r'\s*/\*\s*\*/' ) # /* */ - -# -# A regular expression to find possible C identifiers while outputting -# source code verbatim, covering things like `*foo' or `(bar'. Group 1 is -# the prefix, group 2 the identifier -- since we scan lines from left to -# right, sequentially splitting the source code into prefix and identifier -# is fully sufficient for our purposes. -# -re_source_crossref = re.compile( r'(\W*)(\w*)' ) - -# -# A regular expression that matches a list of reserved C source keywords. -# -re_source_keywords = re.compile( '''\\b ( typedef | - struct | - enum | - union | - const | - char | - int | - short | - long | - void | - signed | - unsigned | - \#include | - \#define | - \#undef | - \#if | - \#ifdef | - \#ifndef | - \#else | - \#endif ) \\b''', re.VERBOSE ) - - -################################################################ -## -## SOURCE BLOCK CLASS -## -## There are two important fields in a `SourceBlock' object. -## -## self.lines -## A list of text lines for the corresponding block. -## -## self.content -## For documentation comment blocks only, this is the block content -## that has been `unboxed' from its decoration. This is `None' for all -## other blocks (i.e., sources or ordinary comments with no starting -## markup tag) -## -class SourceBlock: - - def __init__( self, processor, filename, lineno, lines ): - self.processor = processor - self.filename = filename - self.lineno = lineno - self.lines = lines[:] - self.format = processor.format - self.content = [] - - if self.format == None: - return - - words = [] - - # extract comment lines - lines = [] - - for line0 in self.lines: - m = self.format.column.match( line0 ) - if m: - lines.append( m.group( 1 ) ) - - # now, look for a markup tag - for l in lines: - l = string.strip( l ) - if len( l ) > 0: - for tag in re_markup_tags: - if tag.match( l ): - self.content = lines - return - - def location( self ): - return "(" + self.filename + ":" + repr( self.lineno ) + ")" - - # debugging only -- not used in normal operations - def dump( self ): - if self.content: - print "{{{content start---" - for l in self.content: - print l - print "---content end}}}" - return - - fmt = "" - if self.format: - fmt = repr( self.format.id ) + " " - - for line in self.lines: - print line - - -################################################################ -## -## SOURCE PROCESSOR CLASS -## -## The `SourceProcessor' is in charge of reading a C source file and -## decomposing it into a series of different `SourceBlock' objects. -## -## A SourceBlock object consists of the following data. -## -## - A documentation comment block using one of the layouts above. Its -## exact format will be discussed later. -## -## - Normal sources lines, including comments. -## -## -class SourceProcessor: - - def __init__( self ): - """Initialize a source processor.""" - self.blocks = [] - self.filename = None - self.format = None - self.lines = [] - - def reset( self ): - """Reset a block processor and clean up all its blocks.""" - self.blocks = [] - self.format = None - - def parse_file( self, filename ): - """Parse a C source file and add its blocks to the processor's - list.""" - self.reset() - - self.filename = filename - - fileinput.close() - self.format = None - self.lineno = 0 - self.lines = [] - - for line in fileinput.input( filename ): - # strip trailing newlines, important on Windows machines! - if line[-1] == '\012': - line = line[0:-1] - - if self.format == None: - self.process_normal_line( line ) - else: - if self.format.end.match( line ): - # A normal block end. Add it to `lines' and create a - # new block - self.lines.append( line ) - self.add_block_lines() - elif self.format.column.match( line ): - # A normal column line. Add it to `lines'. - self.lines.append( line ) - else: - # An unexpected block end. Create a new block, but - # don't process the line. - self.add_block_lines() - - # we need to process the line again - self.process_normal_line( line ) - - # record the last lines - self.add_block_lines() - - def process_normal_line( self, line ): - """Process a normal line and check whether it is the start of a new - block.""" - for f in re_source_block_formats: - if f.start.match( line ): - self.add_block_lines() - self.format = f - self.lineno = fileinput.filelineno() - - self.lines.append( line ) - - def add_block_lines( self ): - """Add the current accumulated lines and create a new block.""" - if self.lines != []: - block = SourceBlock( self, - self.filename, - self.lineno, - self.lines ) - - self.blocks.append( block ) - self.format = None - self.lines = [] - - # debugging only, not used in normal operations - def dump( self ): - """Print all blocks in a processor.""" - for b in self.blocks: - b.dump() - -# eof diff --git a/sdk/lib/3rdparty/freetype/src/tools/docmaker/tohtml.py b/sdk/lib/3rdparty/freetype/src/tools/docmaker/tohtml.py deleted file mode 100644 index 7f5ecda41ce73..0000000000000 --- a/sdk/lib/3rdparty/freetype/src/tools/docmaker/tohtml.py +++ /dev/null @@ -1,725 +0,0 @@ -# -# tohtml.py -# -# A sub-class container of the `Formatter' class to produce HTML. -# -# Copyright 2002-2018 by -# David Turner. -# -# This file is part of the FreeType project, and may only be used, -# modified, and distributed under the terms of the FreeType project -# license, LICENSE.TXT. By continuing to use, modify, or distribute -# this file you indicate that you have read the license and -# understand and accept it fully. - -# The parent class is contained in file `formatter.py'. - - -from sources import * -from content import * -from formatter import * - -import time - - -# The following strings define the HTML header used by all generated pages. -html_header_1 = """\ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" -"https://www.w3.org/TR/html4/loose.dtd"> -<html> -<head> -<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> -<title>\ -""" - -html_header_2 = """\ - API Reference - - - -""" - -html_header_3l = """ - -

\ -""" - -html_header_5i = """\ -">Index] -

\ -""" - -html_header_6 = """\ - API Reference

-""" - - -# The HTML footer used by all generated pages. -html_footer = """\ - -\ -""" - -# The header and footer used for each section. -section_title_header1 = '

' -section_title_footer = "

" - -# The header and footer used for code segments. -code_header = '
'
-code_footer = '
' - -# Paragraph header and footer. -para_header = "

" -para_footer = "

" - -# Block header and footer. -block_header = '
' -block_footer_start = """\ -
-\ -\ -
-""" - -# Description header/footer. -description_header = "" -description_footer = "" - -# Marker header/inter/footer combination. -marker_header = "

" -marker_inter = "

" -marker_footer = "" - -# Header location header/footer. -header_location_header = "

" -header_location_footer = "

" - -# Source code extracts header/footer. -source_header = "
"
-source_footer = "
" - -# Chapter header/inter/footer. -chapter_header = """\ -
-

\ -""" -chapter_inter = '

' -chapter_footer = '
' - -# Index footer. -index_footer_start = """\ -
- -""" - -# TOC footer. -toc_footer_start = """\ -
- -""" - - -# Source language keyword coloration and styling. -keyword_prefix = '' -keyword_suffix = '' - -section_synopsis_header = '

Synopsis

' -section_synopsis_footer = '' - - -# Translate a single line of source to HTML. This converts `<', `>', and -# `&' into `<',`>', and `&'. -# -def html_quote( line ): - result = string.replace( line, "&", "&" ) - result = string.replace( result, "<", "<" ) - result = string.replace( result, ">", ">" ) - return result - - -################################################################ -## -## HTML FORMATTER CLASS -## -class HtmlFormatter( Formatter ): - - def __init__( self, processor, project_title, file_prefix ): - Formatter.__init__( self, processor ) - - global html_header_1 - global html_header_2 - global html_header_3l, html_header_3r - global html_header_4 - global html_header_5t, html_header_5i - global html_header_6 - global html_footer - - if file_prefix: - file_prefix = file_prefix + "-" - else: - file_prefix = "" - - self.headers = processor.headers - self.project_title = project_title - self.file_prefix = file_prefix - self.html_header = ( - html_header_1 + project_title - + html_header_2 - + html_header_3l + file_prefix + "index.html" - + html_header_4 + file_prefix + "toc.html" - + html_header_5t + project_title - + html_header_6 ) - self.html_index_header = ( - html_header_1 + project_title - + html_header_2 - + html_header_3r + file_prefix + "toc.html" - + html_header_5t + project_title - + html_header_6 ) - self.html_toc_header = ( - html_header_1 + project_title - + html_header_2 - + html_header_3l + file_prefix + "index.html" - + html_header_5i + project_title - + html_header_6 ) - self.html_footer = ( - '
generated on ' - + time.asctime( time.localtime( time.time() ) ) - + "
" + html_footer ) - - self.columns = 3 - - def make_section_url( self, section ): - return self.file_prefix + section.name + ".html" - - def make_block_url( self, block, name = None ): - if name == None: - name = block.name - - try: - section_url = self.make_section_url( block.section ) - except: - # we already have a section - section_url = self.make_section_url( block ) - - return section_url + "#" + name - - def make_html_word( self, word ): - """Analyze a simple word to detect cross-references and markup.""" - # handle cross-references - m = re_crossref.match( word ) - if m: - try: - name = m.group( 'name' ) - rest = m.group( 'rest' ) - block = self.identifiers[name] - url = self.make_block_url( block ) - # display `foo[bar]' as `foo' - name = re.sub( r'\[.*\]', '', name ) - # normalize url, following RFC 3986 - url = string.replace( url, "[", "(" ) - url = string.replace( url, "]", ")" ) - - try: - # for sections, display title - url = ( '‘' - + block.title + '’' - + rest ) - except: - url = ( '' - + name + '' - + rest ) - - return url - except: - # we detected a cross-reference to an unknown item - sys.stderr.write( "WARNING: undefined cross reference" - + " '" + name + "'.\n" ) - return '?' + name + '?' + rest - - # handle markup for italic and bold - m = re_italic.match( word ) - if m: - name = m.group( 1 ) - rest = m.group( 2 ) - return '' + name + '' + rest - - m = re_bold.match( word ) - if m: - name = m.group( 1 ) - rest = m.group( 2 ) - return '' + name + '' + rest - - return html_quote( word ) - - def make_html_para( self, words ): - """Convert words of a paragraph into tagged HTML text. Also handle - cross references.""" - line = "" - if words: - line = self.make_html_word( words[0] ) - for word in words[1:]: - line = line + " " + self.make_html_word( word ) - # handle hyperlinks - line = re_url.sub( r'\1', line ) - # convert `...' quotations into real left and right single quotes - line = re.sub( r"(^|\W)`(.*?)'(\W|$)", - r'\1‘\2’\3', - line ) - # convert tilde into non-breakable space - line = string.replace( line, "~", " " ) - - return para_header + line + para_footer - - def make_html_code( self, lines ): - """Convert a code sequence to HTML.""" - line = code_header + '\n' - for l in lines: - line = line + html_quote( l ).rstrip() + '\n' - - return line + code_footer - - def make_html_items( self, items ): - """Convert a field's content into HTML.""" - lines = [] - for item in items: - if item.lines: - lines.append( self.make_html_code( item.lines ) ) - else: - lines.append( self.make_html_para( item.words ) ) - - return string.join( lines, '\n' ) - - def print_html_items( self, items ): - print self.make_html_items( items ) - - def print_html_field( self, field ): - if field.name: - print( '
' - + field.name - + "" ) - - print self.make_html_items( field.items ) - - if field.name: - print "
" - - def html_source_quote( self, line, block_name = None ): - result = "" - while line: - m = re_source_crossref.match( line ) - if m: - name = m.group( 2 ) - prefix = html_quote( m.group( 1 ) ) - length = len( m.group( 0 ) ) - - if name == block_name: - # this is the current block name, if any - result = result + prefix + '' + name + '' - elif re_source_keywords.match( name ): - # this is a C keyword - result = ( result + prefix - + keyword_prefix + name + keyword_suffix ) - elif name in self.identifiers: - # this is a known identifier - block = self.identifiers[name] - id = block.name - - # link to a field ID if possible - try: - for markup in block.markups: - if markup.tag == 'values': - for field in markup.fields: - if field.name: - id = name - - result = ( result + prefix - + '' + name + '' ) - except: - # sections don't have `markups'; however, we don't - # want references to sections here anyway - result = result + html_quote( line[:length] ) - - else: - result = result + html_quote( line[:length] ) - - line = line[length:] - else: - result = result + html_quote( line ) - line = [] - - return result - - def print_html_field_list( self, fields ): - print '' - for field in fields: - print ( '" - print "
' - + field.name - + '' ) - self.print_html_items( field.items ) - print "
" - - def print_html_markup( self, markup ): - table_fields = [] - for field in markup.fields: - if field.name: - # We begin a new series of field or value definitions. We - # record them in the `table_fields' list before outputting - # all of them as a single table. - table_fields.append( field ) - else: - if table_fields: - self.print_html_field_list( table_fields ) - table_fields = [] - - self.print_html_items( field.items ) - - if table_fields: - self.print_html_field_list( table_fields ) - - # - # formatting the index - # - def index_enter( self ): - print self.html_index_header - self.index_items = {} - - def index_name_enter( self, name ): - block = self.identifiers[name] - url = self.make_block_url( block ) - self.index_items[name] = url - - def index_exit( self ): - # `block_index' already contains the sorted list of index names - count = len( self.block_index ) - rows = ( count + self.columns - 1 ) // self.columns - - print '' - for r in range( rows ): - line = "" - for c in range( self.columns ): - i = r + c * rows - if i < count: - bname = self.block_index[r + c * rows] - url = self.index_items[bname] - # display `foo[bar]' as `foo (bar)' - bname = string.replace( bname, "[", " (" ) - bname = string.replace( bname, "]", ")" ) - # normalize url, following RFC 3986 - url = string.replace( url, "[", "(" ) - url = string.replace( url, "]", ")" ) - line = ( line + '' ) - else: - line = line + '' - line = line + "" - print line - - print "
' - + bname + '
" - - print( index_footer_start - + self.file_prefix + "toc.html" - + index_footer_end ) - - print self.html_footer - - self.index_items = {} - - def index_dump( self, index_filename = None ): - if index_filename == None: - index_filename = self.file_prefix + "index.html" - - Formatter.index_dump( self, index_filename ) - - # - # formatting the table of contents - # - def toc_enter( self ): - print self.html_toc_header - print "

Table of Contents

" - - def toc_chapter_enter( self, chapter ): - print chapter_header + string.join( chapter.title ) + chapter_inter - print '' - - def toc_section_enter( self, section ): - print ( '" - - def toc_chapter_exit( self, chapter ): - print "
' ) - print self.make_html_para( section.abstract ) - - def toc_section_exit( self, section ): - print "
" - print chapter_footer - - def toc_index( self, index_filename ): - print( chapter_header - + 'Global Index' - + chapter_inter + chapter_footer ) - - def toc_exit( self ): - print( toc_footer_start - + self.file_prefix + "index.html" - + toc_footer_end ) - - print self.html_footer - - def toc_dump( self, toc_filename = None, index_filename = None ): - if toc_filename == None: - toc_filename = self.file_prefix + "toc.html" - - if index_filename == None: - index_filename = self.file_prefix + "index.html" - - Formatter.toc_dump( self, toc_filename, index_filename ) - - # - # formatting sections - # - def section_enter( self, section ): - print self.html_header - - print ( section_title_header1 + section.name + section_title_header2 - + section.title - + section_title_footer ) - - maxwidth = 0 - for b in section.blocks.values(): - if len( b.name ) > maxwidth: - maxwidth = len( b.name ) - - width = 70 # XXX magic number - if maxwidth > 0: - # print section synopsis - print section_synopsis_header - print '' - - columns = width // maxwidth - if columns < 1: - columns = 1 - - count = len( section.block_names ) - # don't handle last entry if it is empty - if section.block_names[-1] == "/empty/": - count -= 1 - rows = ( count + columns - 1 ) // columns - - for r in range( rows ): - line = "" - for c in range( columns ): - i = r + c * rows - line = line + '' - line = line + "" - print line - - print "
' - if i < count: - name = section.block_names[i] - if name == "/empty/": - # it can happen that a complete row is empty, and - # without a proper `filler' the browser might - # collapse the row to a much smaller height (or - # even omit it completely) - line = line + " " - else: - url = name - # display `foo[bar]' as `foo' - name = re.sub( r'\[.*\]', '', name ) - # normalize url, following RFC 3986 - url = string.replace( url, "[", "(" ) - url = string.replace( url, "]", ")" ) - line = ( line + '' - + name + '' ) - - line = line + '
" - print section_synopsis_footer - - print description_header - print self.make_html_items( section.description ) - print description_footer - - def block_enter( self, block ): - print block_header - - # place html anchor if needed - if block.name: - url = block.name - # display `foo[bar]' as `foo' - name = re.sub( r'\[.*\]', '', block.name ) - # normalize url, following RFC 3986 - url = string.replace( url, "[", "(" ) - url = string.replace( url, "]", ")" ) - print( '

' + name + '

' ) - - # dump the block C source lines now - if block.code: - header = '' - for f in self.headers.keys(): - if block.source.filename.find( f ) >= 0: - header = self.headers[f] + ' (' + f + ')' - break - -# if not header: -# sys.stderr.write( -# "WARNING: No header macro for" -# + " '" + block.source.filename + "'.\n" ) - - if header: - print ( header_location_header - + 'Defined in ' + header + '.' - + header_location_footer ) - - print source_header - for l in block.code: - print self.html_source_quote( l, block.name ) - print source_footer - - def markup_enter( self, markup, block ): - if markup.tag == "description": - print description_header - else: - print marker_header + markup.tag + marker_inter - - self.print_html_markup( markup ) - - def markup_exit( self, markup, block ): - if markup.tag == "description": - print description_footer - else: - print marker_footer - - def block_exit( self, block ): - print( block_footer_start + self.file_prefix + "index.html" - + block_footer_middle + self.file_prefix + "toc.html" - + block_footer_end ) - - def section_exit( self, section ): - print html_footer - - def section_dump_all( self ): - for section in self.sections: - self.section_dump( section, - self.file_prefix + section.name + '.html' ) - -# eof diff --git a/sdk/lib/3rdparty/freetype/src/tools/docmaker/utils.py b/sdk/lib/3rdparty/freetype/src/tools/docmaker/utils.py deleted file mode 100644 index f40f1674a04eb..0000000000000 --- a/sdk/lib/3rdparty/freetype/src/tools/docmaker/utils.py +++ /dev/null @@ -1,127 +0,0 @@ -# -# utils.py -# -# Auxiliary functions for the `docmaker' tool (library file). -# -# Copyright 2002-2018 by -# David Turner. -# -# This file is part of the FreeType project, and may only be used, -# modified, and distributed under the terms of the FreeType project -# license, LICENSE.TXT. By continuing to use, modify, or distribute -# this file you indicate that you have read the license and -# understand and accept it fully. - - -import string, sys, os, glob, itertools - - -# current output directory -# -output_dir = None - - -# A function that generates a sorting key. We want lexicographical order -# (primary key) except that capital letters are sorted before lowercase -# ones (secondary key). -# -# The primary key is implemented by lowercasing the input. The secondary -# key is simply the original data appended, character by character. For -# example, the sort key for `FT_x' is `fFtT__xx', while the sort key for -# `ft_X' is `fftt__xX'. Since ASCII codes of uppercase letters are -# numerically smaller than the codes of lowercase letters, `fFtT__xx' gets -# sorted before `fftt__xX'. -# -def index_key( s ): - return string.join( itertools.chain( *zip( s.lower(), s ) ) ) - - -# Sort `input_list', placing the elements of `order_list' in front. -# -def sort_order_list( input_list, order_list ): - new_list = order_list[:] - for id in input_list: - if not id in order_list: - new_list.append( id ) - return new_list - - -# Divert standard output to a given project documentation file. Use -# `output_dir' to determine the filename location if necessary and save the -# old stdout handle in a tuple that is returned by this function. -# -def open_output( filename ): - global output_dir - - if output_dir and output_dir != "": - filename = output_dir + os.sep + filename - - old_stdout = sys.stdout - new_file = open( filename, "w" ) - sys.stdout = new_file - - return ( new_file, old_stdout ) - - -# Close the output that was returned by `open_output'. -# -def close_output( output ): - output[0].close() - sys.stdout = output[1] - - -# Check output directory. -# -def check_output(): - global output_dir - if output_dir: - if output_dir != "": - if not os.path.isdir( output_dir ): - sys.stderr.write( "argument" - + " '" + output_dir + "' " - + "is not a valid directory\n" ) - sys.exit( 2 ) - else: - output_dir = None - - -def file_exists( pathname ): - """Check that a given file exists.""" - result = 1 - try: - file = open( pathname, "r" ) - file.close() - except: - result = None - sys.stderr.write( pathname + " couldn't be accessed\n" ) - - return result - - -def make_file_list( args = None ): - """Build a list of input files from command-line arguments.""" - file_list = [] - # sys.stderr.write( repr( sys.argv[1 :] ) + '\n' ) - - if not args: - args = sys.argv[1:] - - for pathname in args: - if string.find( pathname, '*' ) >= 0: - newpath = glob.glob( pathname ) - newpath.sort() # sort files -- this is important because - # of the order of files - else: - newpath = [pathname] - - file_list.extend( newpath ) - - if len( file_list ) == 0: - file_list = None - else: - # now filter the file list to remove non-existing ones - file_list = filter( file_exists, file_list ) - - return file_list - -# eof diff --git a/sdk/lib/3rdparty/freetype/src/tools/ftrandom/Makefile b/sdk/lib/3rdparty/freetype/src/tools/ftrandom/Makefile deleted file mode 100644 index 24dc49c563961..0000000000000 --- a/sdk/lib/3rdparty/freetype/src/tools/ftrandom/Makefile +++ /dev/null @@ -1,45 +0,0 @@ -# TOP_DIR and OBJ_DIR should be set by the user to the right directories, -# if necessary. - -TOP_DIR ?= ../../.. -OBJ_DIR ?= $(TOP_DIR)/objs - - -# The setup below is for gcc on a Unix-like platform, -# where FreeType has been set up to create a static library -# (which is the default). - -VPATH = $(OBJ_DIR) \ - $(OBJ_DIR)/.libs - -SRC_DIR = $(TOP_DIR)/src/tools/ftrandom - -CC = gcc -WFLAGS = -Wmissing-prototypes \ - -Wunused \ - -Wimplicit \ - -Wreturn-type \ - -Wparentheses \ - -pedantic \ - -Wformat \ - -Wchar-subscripts \ - -Wsequence-point -CFLAGS = $(WFLAGS) \ - -g -INCLUDES = -I $(TOP_DIR)/include -LDFLAGS = -LIBS = -lm \ - -lz \ - -lpng \ - -lbz2 \ - -lharfbuzz - -all: $(OBJ_DIR)/ftrandom - -$(OBJ_DIR)/ftrandom.o: $(SRC_DIR)/ftrandom.c - $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $< - -$(OBJ_DIR)/ftrandom: $(OBJ_DIR)/ftrandom.o libfreetype.a - $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) - -# EOF diff --git a/sdk/lib/3rdparty/freetype/src/tools/ftrandom/README b/sdk/lib/3rdparty/freetype/src/tools/ftrandom/README deleted file mode 100644 index 7c610864b6adb..0000000000000 --- a/sdk/lib/3rdparty/freetype/src/tools/ftrandom/README +++ /dev/null @@ -1,69 +0,0 @@ -ftrandom -======== - -This program expects a set of directories containing good fonts, and a set -of extensions of fonts to be tested. It will randomly pick a font, copy it, -introduce an error and then test it. - -The FreeType tests are quite basic; for each erroneous font ftrandom - - . forks off a new tester, - . initializes the library, - . opens each font in the file, - . loads each glyph, - . optionally reviews the contours of the glyph, - . optionally rasterizes the glyph, and - . closes the face. - -If a tester takes longer than 20 seconds, ftrandom saves the erroneous font -and continues. If the tester exits normally or with an error, then the -superstructure removes the test font and continues. - - -Command line options --------------------- - - --all Test every font in the directory(ies) no matter - what its extension. - --check-outlines Call `FT_Outline_Decompose' on each glyph. - --dir Append to the list of directories to search - for good fonts. No recursive search. - --error-count Introduce single-byte errors into the - erroneous fonts (default: 1). - --error-fraction Multiply the file size of the font by and - introduce that many errors into the erroneous - font file. should be in the range [0;1] - (default: 0.0). - --ext Add to the set of font types tested. - --help Print out this list of options. - --nohints Specify FT_LOAD_NO_HINTING when loading glyphs. - --rasterize Call `FT_Render_Glyph' as well as loading it. - --result This is the directory in which test files are - placed. - --test Run a single test on a pre-generated testcase. - This is done in the current process so it can be - debugged more easily. - -The default font extensions tested by ftrandom are - - .ttf .otf .ttc .cid .pfb .pfa .bdf .pcf .pfr .fon .otb .cff - -The default font directory is controlled by the macro `GOOD_FONTS_DIR' in -the source code (and can be thus specified during compilation); its default -value is - - /usr/local/share/fonts - -The default result directory is `results' (in the current directory). - - -Compilation ------------ - -Two possible solutions. - -. Run ftrandom within a debugging tool like `valgrind' to catch various - memory issues. - -. Compile FreeType with sanitizer flags as provided by gcc or clang, for - example, then link it with ftrandom. diff --git a/sdk/lib/3rdparty/freetype/src/tools/ftrandom/ftrandom.c b/sdk/lib/3rdparty/freetype/src/tools/ftrandom/ftrandom.c deleted file mode 100644 index ab5cfc98b6cd7..0000000000000 --- a/sdk/lib/3rdparty/freetype/src/tools/ftrandom/ftrandom.c +++ /dev/null @@ -1,720 +0,0 @@ -/* Copyright (C) 2005, 2007, 2008, 2013 by George Williams */ -/* - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - - * The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* modified by Werner Lemberg */ -/* This file is now part of the FreeType library */ - - -#define _XOPEN_SOURCE 500 /* for `kill', `strdup', `random', and `srandom' */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include FT_FREETYPE_H -#include FT_OUTLINE_H - -#define true 1 -#define false 0 -#define forever for (;;) - - - static int check_outlines = false; - static int nohints = false; - static int rasterize = false; - static char* results_dir = "results"; - -#define GOOD_FONTS_DIR "/usr/local/share/fonts" - - static char* default_dir_list[] = - { - GOOD_FONTS_DIR, - NULL - }; - - static char* default_ext_list[] = - { - "ttf", - "otf", - "ttc", - "cid", - "pfb", - "pfa", - "bdf", - "pcf", - "pfr", - "fon", - "otb", - "cff", - NULL - }; - - static unsigned int error_count = 1; - static double error_fraction = 0.0; - - static FT_F26Dot6 font_size = 12 * 64; - - static struct fontlist - { - char* name; - long len; - unsigned int isbinary: 1; - unsigned int isascii: 1; - unsigned int ishex: 1; - - } *fontlist; - - static unsigned int fcnt; - - - static int - FT_MoveTo( const FT_Vector *to, - void *user ) - { - FT_UNUSED( to ); - FT_UNUSED( user ); - - return 0; - } - - - static int - FT_LineTo( const FT_Vector *to, - void *user ) - { - FT_UNUSED( to ); - FT_UNUSED( user ); - - return 0; - } - - - static int - FT_ConicTo( const FT_Vector *_cp, - const FT_Vector *to, - void *user ) - { - FT_UNUSED( _cp ); - FT_UNUSED( to ); - FT_UNUSED( user ); - - return 0; - } - - - static int - FT_CubicTo( const FT_Vector *cp1, - const FT_Vector *cp2, - const FT_Vector *to, - void *user ) - { - FT_UNUSED( cp1 ); - FT_UNUSED( cp2 ); - FT_UNUSED( to ); - FT_UNUSED( user ); - - return 0; - } - - - static FT_Outline_Funcs outlinefuncs = - { - FT_MoveTo, - FT_LineTo, - FT_ConicTo, - FT_CubicTo, - 0, 0 /* No shift, no delta */ - }; - - - static void - TestFace( FT_Face face ) - { - unsigned int gid; - int load_flags = FT_LOAD_DEFAULT; - - - if ( check_outlines && - FT_IS_SCALABLE( face ) ) - load_flags = FT_LOAD_NO_BITMAP; - - if ( nohints ) - load_flags |= FT_LOAD_NO_HINTING; - - FT_Set_Char_Size( face, 0, font_size, 72, 72 ); - - for ( gid = 0; gid < face->num_glyphs; gid++ ) - { - if ( check_outlines && - FT_IS_SCALABLE( face ) ) - { - if ( !FT_Load_Glyph( face, gid, load_flags ) ) - FT_Outline_Decompose( &face->glyph->outline, &outlinefuncs, NULL ); - } - else - FT_Load_Glyph( face, gid, load_flags ); - - if ( rasterize ) - FT_Render_Glyph( face->glyph, ft_render_mode_normal ); - } - - FT_Done_Face( face ); - } - - - static void - ExecuteTest( char* testfont ) - { - FT_Library context; - FT_Face face; - - - if ( FT_Init_FreeType( &context ) ) - { - fprintf( stderr, "Can't initialize FreeType.\n" ); - exit( 1 ); - } - - if ( FT_New_Face( context, testfont, 0, &face ) ) - { - /* The font is erroneous, so if this fails that's ok. */ - exit( 0 ); - } - - if ( face->num_faces == 1 ) - TestFace( face ); - else - { - long i, num; - - - num = face->num_faces; - FT_Done_Face( face ); - - for ( i = 0; i < num; i++ ) - { - if ( !FT_New_Face( context, testfont, i, &face ) ) - TestFace( face ); - } - } - - FT_Done_FreeType( context ); - - exit( 0 ); - } - - - static int - extmatch( char* filename, - char** extensions ) - { - int i; - char* pt; - - - if ( !extensions ) - return true; - - pt = strrchr( filename, '.' ); - if ( !pt ) - return false; - if ( pt < strrchr( filename, '/' ) ) - return false; - - for ( i = 0; extensions[i] != NULL; i++ ) - if ( strcasecmp( pt + 1, extensions[i] ) == 0 || - strcasecmp( pt, extensions[i] ) == 0 ) - return true; - - return false; - } - - - static void - figurefiletype( struct fontlist* item ) - { - FILE* foo; - - - item->isbinary = item->isascii = item->ishex = false; - - foo = fopen( item->name, "rb" ); - if ( foo ) - { - /* Try to guess the file type from the first few characters... */ - int ch1 = getc( foo ); - int ch2 = getc( foo ); - int ch3 = getc( foo ); - int ch4 = getc( foo ); - - - fclose( foo ); - - if ( ( ch1 == 0 && ch2 == 1 && ch3 == 0 && ch4 == 0 ) || - ( ch1 == 'O' && ch2 == 'T' && ch3 == 'T' && ch4 == 'O' ) || - ( ch1 == 't' && ch2 == 'r' && ch3 == 'u' && ch4 == 'e' ) || - ( ch1 == 't' && ch2 == 't' && ch3 == 'c' && ch4 == 'f' ) ) - { - /* ttf, otf, ttc files */ - item->isbinary = true; - } - else if ( ch1 == 0x80 && ch2 == '\01' ) - { - /* PFB header */ - item->isbinary = true; - } - else if ( ch1 == '%' && ch2 == '!' ) - { - /* Random PostScript */ - if ( strstr( item->name, ".pfa" ) || - strstr( item->name, ".PFA" ) ) - item->ishex = true; - else - item->isascii = true; - } - else if ( ch1 == 1 && ch2 == 0 && ch3 == 4 ) - { - /* Bare CFF */ - item->isbinary = true; - } - else if ( ch1 == 'S' && ch2 == 'T' && ch3 == 'A' && ch4 == 'R' ) - { - /* BDF */ - item->ishex = true; - } - else if ( ch1 == 'P' && ch2 == 'F' && ch3 == 'R' && ch4 == '0' ) - { - /* PFR */ - item->isbinary = true; - } - else if ( ( ch1 == '\1' && ch2 == 'f' && ch3 == 'c' && ch4 == 'p' ) || - ( ch1 == 'M' && ch2 == 'Z' ) ) - { - /* Windows FON */ - item->isbinary = true; - } - else - { - fprintf( stderr, - "Can't recognize file type of `%s', assuming binary\n", - item->name ); - item->isbinary = true; - } - } - else - { - fprintf( stderr, "Can't open `%s' for typing the file.\n", - item->name ); - item->isbinary = true; - } - } - - - static void - FindFonts( char** fontdirs, - char** extensions ) - { - int i; - unsigned int max; - char buffer[1025]; - struct stat statb; - - - max = 0; - fcnt = 0; - - for ( i = 0; fontdirs[i] != NULL; i++ ) - { - DIR* examples; - struct dirent* ent; - - - examples = opendir( fontdirs[i] ); - if ( !examples ) - { - fprintf( stderr, - "Can't open example font directory `%s'\n", - fontdirs[i] ); - exit( 1 ); - } - - while ( ( ent = readdir( examples ) ) != NULL ) - { - snprintf( buffer, sizeof ( buffer ), - "%s/%s", fontdirs[i], ent->d_name ); - if ( stat( buffer, &statb ) == -1 || S_ISDIR( statb.st_mode ) ) - continue; - if ( !extensions || extmatch( buffer, extensions ) ) - { - if ( fcnt >= max ) - { - max += 100; - fontlist = realloc( fontlist, max * sizeof ( struct fontlist ) ); - if ( !fontlist ) - { - fprintf( stderr, "Can't allocate memory\n" ); - exit( 1 ); - } - } - - fontlist[fcnt].name = strdup( buffer ); - fontlist[fcnt].len = statb.st_size; - - figurefiletype( &fontlist[fcnt] ); - fcnt++; - } - } - - closedir( examples ); - } - - if ( fcnt == 0 ) - { - fprintf( stderr, "Can't find matching font files.\n" ); - exit( 1 ); - } - - fontlist[fcnt].name = NULL; - } - - - static unsigned int - getErrorCnt( struct fontlist* item ) - { - if ( error_count == 0 && error_fraction == 0.0 ) - return 0; - - return error_count + (unsigned int)( error_fraction * item->len ); - } - - - static int - getRandom( int low, - int high ) - { - if ( low - high < 0x10000L ) - return low + ( ( random() >> 8 ) % ( high + 1 - low ) ); - - return low + ( random() % ( high + 1 - low ) ); - } - - - static int - copyfont( struct fontlist* item, - char* newfont ) - { - static char buffer[8096]; - FILE *good, *newf; - size_t len; - unsigned int i, err_cnt; - - - good = fopen( item->name, "r" ); - if ( !good ) - { - fprintf( stderr, "Can't open `%s'\n", item->name ); - return false; - } - - newf = fopen( newfont, "w+" ); - if ( !newf ) - { - fprintf( stderr, "Can't create temporary output file `%s'\n", - newfont ); - exit( 1 ); - } - - while ( ( len = fread( buffer, 1, sizeof ( buffer ), good ) ) > 0 ) - fwrite( buffer, 1, len, newf ); - - fclose( good ); - - err_cnt = getErrorCnt( item ); - for ( i = 0; i < err_cnt; i++ ) - { - fseek( newf, getRandom( 0, (int)( item->len - 1 ) ), SEEK_SET ); - - if ( item->isbinary ) - putc( getRandom( 0, 0xFF ), newf ); - else if ( item->isascii ) - putc( getRandom( 0x20, 0x7E ), newf ); - else - { - int hex = getRandom( 0, 15 ); - - - if ( hex < 10 ) - hex += '0'; - else - hex += 'A' - 10; - - putc( hex, newf ); - } - } - - if ( ferror( newf ) ) - { - fclose( newf ); - unlink( newfont ); - return false; - } - - fclose( newf ); - - return true; - } - - - static int child_pid; - - static void - abort_test( int sig ) - { - FT_UNUSED( sig ); - - /* If a time-out happens, then kill the child */ - kill( child_pid, SIGFPE ); - write( 2, "Timeout... ", 11 ); - } - - - static void - do_test( void ) - { - int i = getRandom( 0, (int)( fcnt - 1 ) ); - static int test_num = 0; - char buffer[1024]; - - - sprintf( buffer, "%s/test%d", results_dir, test_num++ ); - - if ( copyfont ( &fontlist[i], buffer ) ) - { - signal( SIGALRM, abort_test ); - /* Anything that takes more than 20 seconds */ - /* to parse and/or rasterize is an error. */ - alarm( 20 ); - if ( ( child_pid = fork() ) == 0 ) - ExecuteTest( buffer ); - else if ( child_pid != -1 ) - { - int status; - - - waitpid( child_pid, &status, 0 ); - alarm( 0 ); - if ( WIFSIGNALED ( status ) ) - printf( "Error found in file `%s'\n", buffer ); - else - unlink( buffer ); - } - else - { - fprintf( stderr, "Can't fork test case.\n" ); - exit( 1 ); - } - alarm( 0 ); - } - } - - - static void - usage( FILE* out, - char* name ) - { - char** d = default_dir_list; - char** e = default_ext_list; - - - fprintf( out, "%s [options] -- Generate random erroneous fonts\n" - " and attempt to parse them with FreeType.\n\n", name ); - - fprintf( out, " --all All non-directory files are assumed to be fonts.\n" ); - fprintf( out, " --check-outlines Make sure we can parse the outlines of each glyph.\n" ); - fprintf( out, " --dir Append to list of font search directories\n" - " (no recursive search).\n" ); - fprintf( out, " --error-count Introduce single byte errors into each font\n" - " (default: 1)\n" ); - fprintf( out, " --error-fraction Introduce *filesize single byte errors\n" - " into each font (default: 0.0).\n" ); - fprintf( out, " --ext Add to list of extensions indicating fonts.\n" ); - fprintf( out, " --help Print this.\n" ); - fprintf( out, " --nohints Turn off hinting.\n" ); - fprintf( out, " --rasterize Attempt to rasterize each glyph.\n" ); - fprintf( out, " --results Place the created test fonts into \n" - " (default: `results')\n" ); - fprintf( out, " --size Use the given font size for the tests.\n" ); - fprintf( out, " --test Run a single test on an already existing file.\n" ); - fprintf( out, "\n" ); - - fprintf( out, "Default font extensions:\n" ); - fprintf( out, " " ); - while ( *e ) - fprintf( out, " .%s", *e++ ); - fprintf( out, "\n" ); - - fprintf( out, "Default font directories:\n" ); - fprintf( out, " " ); - while ( *d ) - fprintf( out, " %s", *d++ ); - fprintf( out, "\n" ); - } - - - int - main( int argc, - char** argv ) - { - char **dirs, **exts; - int dcnt = 0, ecnt = 0, rset = false, allexts = false; - int i; - time_t now; - char* testfile = NULL; - - - dirs = calloc( (size_t)( argc + 1 ), sizeof ( char ** ) ); - exts = calloc( (size_t)( argc + 1 ), sizeof ( char ** ) ); - - for ( i = 1; i < argc; i++ ) - { - char* pt = argv[i]; - char* end; - - - if ( pt[0] == '-' && pt[1] == '-' ) - pt++; - - if ( strcmp( pt, "-all" ) == 0 ) - allexts = true; - else if ( strcmp( pt, "-check-outlines" ) == 0 ) - check_outlines = true; - else if ( strcmp( pt, "-dir" ) == 0 ) - dirs[dcnt++] = argv[++i]; - else if ( strcmp( pt, "-error-count" ) == 0 ) - { - if ( !rset ) - error_fraction = 0.0; - rset = true; - error_count = (unsigned int)strtoul( argv[++i], &end, 10 ); - if ( *end != '\0' ) - { - fprintf( stderr, "Bad value for error-count: %s\n", argv[i] ); - exit( 1 ); - } - } - else if ( strcmp( pt, "-error-fraction" ) == 0 ) - { - if ( !rset ) - error_count = 0; - rset = true; - error_fraction = strtod( argv[++i], &end ); - if ( *end != '\0' ) - { - fprintf( stderr, "Bad value for error-fraction: %s\n", argv[i] ); - exit( 1 ); - } - if ( error_fraction < 0.0 || error_fraction > 1.0 ) - { - fprintf( stderr, "error-fraction must be in the range [0;1]\n" ); - exit( 1 ); - } - } - else if ( strcmp( pt, "-ext" ) == 0 ) - exts[ecnt++] = argv[++i]; - else if ( strcmp( pt, "-help" ) == 0 ) - { - usage( stdout, argv[0] ); - exit( 0 ); - } - else if ( strcmp( pt, "-nohints" ) == 0 ) - nohints = true; - else if ( strcmp( pt, "-rasterize" ) == 0 ) - rasterize = true; - else if ( strcmp( pt, "-results" ) == 0 ) - results_dir = argv[++i]; - else if ( strcmp( pt, "-size" ) == 0 ) - { - font_size = (FT_F26Dot6)( strtod( argv[++i], &end ) * 64 ); - if ( *end != '\0' || font_size < 64 ) - { - fprintf( stderr, "Bad value for size: %s\n", argv[i] ); - exit( 1 ); - } - } - else if ( strcmp( pt, "-test" ) == 0 ) - testfile = argv[++i]; - else - { - usage( stderr, argv[0] ); - exit( 1 ); - } - } - - if ( allexts ) - { - free( exts ); - exts = NULL; - } - else if ( ecnt == 0 ) - { - free( exts ); - exts = default_ext_list; - } - - if ( dcnt == 0 ) - { - free( dirs ); - dirs = default_dir_list; - } - - if ( testfile ) - ExecuteTest( testfile ); /* This should never return */ - - time( &now ); - srandom( (unsigned int)now ); - - FindFonts( dirs, exts ); - mkdir( results_dir, 0755 ); - - forever - do_test(); - - return 0; - } - - -/* EOF */ diff --git a/sdk/lib/3rdparty/freetype/src/tools/glnames.py b/sdk/lib/3rdparty/freetype/src/tools/glnames.py deleted file mode 100644 index b048d2936418b..0000000000000 --- a/sdk/lib/3rdparty/freetype/src/tools/glnames.py +++ /dev/null @@ -1,5540 +0,0 @@ -#!/usr/bin/env python -# - -# -# FreeType 2 glyph name builder -# - - -# Copyright 1996-2018 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -"""\ - -usage: %s - - This python script generates the glyph names tables defined in the - `psnames' module. - - Its single argument is the name of the header file to be created. -""" - - -import sys, string, struct, re, os.path - - -# This table lists the glyphs according to the Macintosh specification. -# It is used by the TrueType Postscript names table. -# -# See -# -# https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6post.html -# -# for the official list. -# -mac_standard_names = \ -[ - # 0 - ".notdef", ".null", "nonmarkingreturn", "space", "exclam", - "quotedbl", "numbersign", "dollar", "percent", "ampersand", - - # 10 - "quotesingle", "parenleft", "parenright", "asterisk", "plus", - "comma", "hyphen", "period", "slash", "zero", - - # 20 - "one", "two", "three", "four", "five", - "six", "seven", "eight", "nine", "colon", - - # 30 - "semicolon", "less", "equal", "greater", "question", - "at", "A", "B", "C", "D", - - # 40 - "E", "F", "G", "H", "I", - "J", "K", "L", "M", "N", - - # 50 - "O", "P", "Q", "R", "S", - "T", "U", "V", "W", "X", - - # 60 - "Y", "Z", "bracketleft", "backslash", "bracketright", - "asciicircum", "underscore", "grave", "a", "b", - - # 70 - "c", "d", "e", "f", "g", - "h", "i", "j", "k", "l", - - # 80 - "m", "n", "o", "p", "q", - "r", "s", "t", "u", "v", - - # 90 - "w", "x", "y", "z", "braceleft", - "bar", "braceright", "asciitilde", "Adieresis", "Aring", - - # 100 - "Ccedilla", "Eacute", "Ntilde", "Odieresis", "Udieresis", - "aacute", "agrave", "acircumflex", "adieresis", "atilde", - - # 110 - "aring", "ccedilla", "eacute", "egrave", "ecircumflex", - "edieresis", "iacute", "igrave", "icircumflex", "idieresis", - - # 120 - "ntilde", "oacute", "ograve", "ocircumflex", "odieresis", - "otilde", "uacute", "ugrave", "ucircumflex", "udieresis", - - # 130 - "dagger", "degree", "cent", "sterling", "section", - "bullet", "paragraph", "germandbls", "registered", "copyright", - - # 140 - "trademark", "acute", "dieresis", "notequal", "AE", - "Oslash", "infinity", "plusminus", "lessequal", "greaterequal", - - # 150 - "yen", "mu", "partialdiff", "summation", "product", - "pi", "integral", "ordfeminine", "ordmasculine", "Omega", - - # 160 - "ae", "oslash", "questiondown", "exclamdown", "logicalnot", - "radical", "florin", "approxequal", "Delta", "guillemotleft", - - # 170 - "guillemotright", "ellipsis", "nonbreakingspace", "Agrave", "Atilde", - "Otilde", "OE", "oe", "endash", "emdash", - - # 180 - "quotedblleft", "quotedblright", "quoteleft", "quoteright", "divide", - "lozenge", "ydieresis", "Ydieresis", "fraction", "currency", - - # 190 - "guilsinglleft", "guilsinglright", "fi", "fl", "daggerdbl", - "periodcentered", "quotesinglbase", "quotedblbase", "perthousand", - "Acircumflex", - - # 200 - "Ecircumflex", "Aacute", "Edieresis", "Egrave", "Iacute", - "Icircumflex", "Idieresis", "Igrave", "Oacute", "Ocircumflex", - - # 210 - "apple", "Ograve", "Uacute", "Ucircumflex", "Ugrave", - "dotlessi", "circumflex", "tilde", "macron", "breve", - - # 220 - "dotaccent", "ring", "cedilla", "hungarumlaut", "ogonek", - "caron", "Lslash", "lslash", "Scaron", "scaron", - - # 230 - "Zcaron", "zcaron", "brokenbar", "Eth", "eth", - "Yacute", "yacute", "Thorn", "thorn", "minus", - - # 240 - "multiply", "onesuperior", "twosuperior", "threesuperior", "onehalf", - "onequarter", "threequarters", "franc", "Gbreve", "gbreve", - - # 250 - "Idotaccent", "Scedilla", "scedilla", "Cacute", "cacute", - "Ccaron", "ccaron", "dcroat" -] - - -# The list of standard `SID' glyph names. For the official list, -# see Annex A of document at -# -# https://www.adobe.com/content/dam/acom/en/devnet/font/pdfs/5176.CFF.pdf . -# -sid_standard_names = \ -[ - # 0 - ".notdef", "space", "exclam", "quotedbl", "numbersign", - "dollar", "percent", "ampersand", "quoteright", "parenleft", - - # 10 - "parenright", "asterisk", "plus", "comma", "hyphen", - "period", "slash", "zero", "one", "two", - - # 20 - "three", "four", "five", "six", "seven", - "eight", "nine", "colon", "semicolon", "less", - - # 30 - "equal", "greater", "question", "at", "A", - "B", "C", "D", "E", "F", - - # 40 - "G", "H", "I", "J", "K", - "L", "M", "N", "O", "P", - - # 50 - "Q", "R", "S", "T", "U", - "V", "W", "X", "Y", "Z", - - # 60 - "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", - "quoteleft", "a", "b", "c", "d", - - # 70 - "e", "f", "g", "h", "i", - "j", "k", "l", "m", "n", - - # 80 - "o", "p", "q", "r", "s", - "t", "u", "v", "w", "x", - - # 90 - "y", "z", "braceleft", "bar", "braceright", - "asciitilde", "exclamdown", "cent", "sterling", "fraction", - - # 100 - "yen", "florin", "section", "currency", "quotesingle", - "quotedblleft", "guillemotleft", "guilsinglleft", "guilsinglright", "fi", - - # 110 - "fl", "endash", "dagger", "daggerdbl", "periodcentered", - "paragraph", "bullet", "quotesinglbase", "quotedblbase", "quotedblright", - - # 120 - "guillemotright", "ellipsis", "perthousand", "questiondown", "grave", - "acute", "circumflex", "tilde", "macron", "breve", - - # 130 - "dotaccent", "dieresis", "ring", "cedilla", "hungarumlaut", - "ogonek", "caron", "emdash", "AE", "ordfeminine", - - # 140 - "Lslash", "Oslash", "OE", "ordmasculine", "ae", - "dotlessi", "lslash", "oslash", "oe", "germandbls", - - # 150 - "onesuperior", "logicalnot", "mu", "trademark", "Eth", - "onehalf", "plusminus", "Thorn", "onequarter", "divide", - - # 160 - "brokenbar", "degree", "thorn", "threequarters", "twosuperior", - "registered", "minus", "eth", "multiply", "threesuperior", - - # 170 - "copyright", "Aacute", "Acircumflex", "Adieresis", "Agrave", - "Aring", "Atilde", "Ccedilla", "Eacute", "Ecircumflex", - - # 180 - "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis", - "Igrave", "Ntilde", "Oacute", "Ocircumflex", "Odieresis", - - # 190 - "Ograve", "Otilde", "Scaron", "Uacute", "Ucircumflex", - "Udieresis", "Ugrave", "Yacute", "Ydieresis", "Zcaron", - - # 200 - "aacute", "acircumflex", "adieresis", "agrave", "aring", - "atilde", "ccedilla", "eacute", "ecircumflex", "edieresis", - - # 210 - "egrave", "iacute", "icircumflex", "idieresis", "igrave", - "ntilde", "oacute", "ocircumflex", "odieresis", "ograve", - - # 220 - "otilde", "scaron", "uacute", "ucircumflex", "udieresis", - "ugrave", "yacute", "ydieresis", "zcaron", "exclamsmall", - - # 230 - "Hungarumlautsmall", "dollaroldstyle", "dollarsuperior", "ampersandsmall", - "Acutesmall", - "parenleftsuperior", "parenrightsuperior", "twodotenleader", - "onedotenleader", "zerooldstyle", - - # 240 - "oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle", - "fiveoldstyle", - "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle", - "commasuperior", - - # 250 - "threequartersemdash", "periodsuperior", "questionsmall", "asuperior", - "bsuperior", - "centsuperior", "dsuperior", "esuperior", "isuperior", "lsuperior", - - # 260 - "msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior", - "tsuperior", "ff", "ffi", "ffl", "parenleftinferior", - - # 270 - "parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall", - "Asmall", - "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall", - - # 280 - "Gsmall", "Hsmall", "Ismall", "Jsmall", "Ksmall", - "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall", - - # 290 - "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall", - "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall", - - # 300 - "colonmonetary", "onefitted", "rupiah", "Tildesmall", "exclamdownsmall", - "centoldstyle", "Lslashsmall", "Scaronsmall", "Zcaronsmall", - "Dieresissmall", - - # 310 - "Brevesmall", "Caronsmall", "Dotaccentsmall", "Macronsmall", "figuredash", - "hypheninferior", "Ogoneksmall", "Ringsmall", "Cedillasmall", - "questiondownsmall", - - # 320 - "oneeighth", "threeeighths", "fiveeighths", "seveneighths", "onethird", - "twothirds", "zerosuperior", "foursuperior", "fivesuperior", - "sixsuperior", - - # 330 - "sevensuperior", "eightsuperior", "ninesuperior", "zeroinferior", - "oneinferior", - "twoinferior", "threeinferior", "fourinferior", "fiveinferior", - "sixinferior", - - # 340 - "seveninferior", "eightinferior", "nineinferior", "centinferior", - "dollarinferior", - "periodinferior", "commainferior", "Agravesmall", "Aacutesmall", - "Acircumflexsmall", - - # 350 - "Atildesmall", "Adieresissmall", "Aringsmall", "AEsmall", "Ccedillasmall", - "Egravesmall", "Eacutesmall", "Ecircumflexsmall", "Edieresissmall", - "Igravesmall", - - # 360 - "Iacutesmall", "Icircumflexsmall", "Idieresissmall", "Ethsmall", - "Ntildesmall", - "Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall", - "Odieresissmall", - - # 370 - "OEsmall", "Oslashsmall", "Ugravesmall", "Uacutesmall", - "Ucircumflexsmall", - "Udieresissmall", "Yacutesmall", "Thornsmall", "Ydieresissmall", - "001.000", - - # 380 - "001.001", "001.002", "001.003", "Black", "Bold", - "Book", "Light", "Medium", "Regular", "Roman", - - # 390 - "Semibold" -] - - -# This table maps character codes of the Adobe Standard Type 1 -# encoding to glyph indices in the sid_standard_names table. -# -t1_standard_encoding = \ -[ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, - 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, - - 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 93, 94, 95, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 0, 111, 112, 113, - 114, 0, 115, 116, 117, 118, 119, 120, 121, 122, - 0, 123, 0, 124, 125, 126, 127, 128, 129, 130, - - 131, 0, 132, 133, 0, 134, 135, 136, 137, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 138, 0, 139, 0, 0, - 0, 0, 140, 141, 142, 143, 0, 0, 0, 0, - 0, 144, 0, 0, 0, 145, 0, 0, 146, 147, - - 148, 149, 0, 0, 0, 0 -] - - -# This table maps character codes of the Adobe Expert Type 1 -# encoding to glyph indices in the sid_standard_names table. -# -t1_expert_encoding = \ -[ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 229, 230, 0, 231, 232, 233, 234, - 235, 236, 237, 238, 13, 14, 15, 99, 239, 240, - - 241, 242, 243, 244, 245, 246, 247, 248, 27, 28, - 249, 250, 251, 252, 0, 253, 254, 255, 256, 257, - 0, 0, 0, 258, 0, 0, 259, 260, 261, 262, - 0, 0, 263, 264, 265, 0, 266, 109, 110, 267, - 268, 269, 0, 270, 271, 272, 273, 274, 275, 276, - - 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 300, 301, 302, 303, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 304, 305, 306, 0, 0, 307, 308, 309, 310, - 311, 0, 312, 0, 0, 313, 0, 0, 314, 315, - 0, 0, 316, 317, 318, 0, 0, 0, 158, 155, - 163, 319, 320, 321, 322, 323, 324, 325, 0, 0, - - 326, 150, 164, 169, 327, 328, 329, 330, 331, 332, - 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, - 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, - 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, - 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, - - 373, 374, 375, 376, 377, 378 -] - - -# This data has been taken literally from the files `glyphlist.txt' -# and `zapfdingbats.txt' version 2.0, Sept 2002. It is available from -# -# https://github.com/adobe-type-tools/agl-aglfn -# -adobe_glyph_list = """\ -A;0041 -AE;00C6 -AEacute;01FC -AEmacron;01E2 -AEsmall;F7E6 -Aacute;00C1 -Aacutesmall;F7E1 -Abreve;0102 -Abreveacute;1EAE -Abrevecyrillic;04D0 -Abrevedotbelow;1EB6 -Abrevegrave;1EB0 -Abrevehookabove;1EB2 -Abrevetilde;1EB4 -Acaron;01CD -Acircle;24B6 -Acircumflex;00C2 -Acircumflexacute;1EA4 -Acircumflexdotbelow;1EAC -Acircumflexgrave;1EA6 -Acircumflexhookabove;1EA8 -Acircumflexsmall;F7E2 -Acircumflextilde;1EAA -Acute;F6C9 -Acutesmall;F7B4 -Acyrillic;0410 -Adblgrave;0200 -Adieresis;00C4 -Adieresiscyrillic;04D2 -Adieresismacron;01DE -Adieresissmall;F7E4 -Adotbelow;1EA0 -Adotmacron;01E0 -Agrave;00C0 -Agravesmall;F7E0 -Ahookabove;1EA2 -Aiecyrillic;04D4 -Ainvertedbreve;0202 -Alpha;0391 -Alphatonos;0386 -Amacron;0100 -Amonospace;FF21 -Aogonek;0104 -Aring;00C5 -Aringacute;01FA -Aringbelow;1E00 -Aringsmall;F7E5 -Asmall;F761 -Atilde;00C3 -Atildesmall;F7E3 -Aybarmenian;0531 -B;0042 -Bcircle;24B7 -Bdotaccent;1E02 -Bdotbelow;1E04 -Becyrillic;0411 -Benarmenian;0532 -Beta;0392 -Bhook;0181 -Blinebelow;1E06 -Bmonospace;FF22 -Brevesmall;F6F4 -Bsmall;F762 -Btopbar;0182 -C;0043 -Caarmenian;053E -Cacute;0106 -Caron;F6CA -Caronsmall;F6F5 -Ccaron;010C -Ccedilla;00C7 -Ccedillaacute;1E08 -Ccedillasmall;F7E7 -Ccircle;24B8 -Ccircumflex;0108 -Cdot;010A -Cdotaccent;010A -Cedillasmall;F7B8 -Chaarmenian;0549 -Cheabkhasiancyrillic;04BC -Checyrillic;0427 -Chedescenderabkhasiancyrillic;04BE -Chedescendercyrillic;04B6 -Chedieresiscyrillic;04F4 -Cheharmenian;0543 -Chekhakassiancyrillic;04CB -Cheverticalstrokecyrillic;04B8 -Chi;03A7 -Chook;0187 -Circumflexsmall;F6F6 -Cmonospace;FF23 -Coarmenian;0551 -Csmall;F763 -D;0044 -DZ;01F1 -DZcaron;01C4 -Daarmenian;0534 -Dafrican;0189 -Dcaron;010E -Dcedilla;1E10 -Dcircle;24B9 -Dcircumflexbelow;1E12 -Dcroat;0110 -Ddotaccent;1E0A -Ddotbelow;1E0C -Decyrillic;0414 -Deicoptic;03EE -Delta;2206 -Deltagreek;0394 -Dhook;018A -Dieresis;F6CB -DieresisAcute;F6CC -DieresisGrave;F6CD -Dieresissmall;F7A8 -Digammagreek;03DC -Djecyrillic;0402 -Dlinebelow;1E0E -Dmonospace;FF24 -Dotaccentsmall;F6F7 -Dslash;0110 -Dsmall;F764 -Dtopbar;018B -Dz;01F2 -Dzcaron;01C5 -Dzeabkhasiancyrillic;04E0 -Dzecyrillic;0405 -Dzhecyrillic;040F -E;0045 -Eacute;00C9 -Eacutesmall;F7E9 -Ebreve;0114 -Ecaron;011A -Ecedillabreve;1E1C -Echarmenian;0535 -Ecircle;24BA -Ecircumflex;00CA -Ecircumflexacute;1EBE -Ecircumflexbelow;1E18 -Ecircumflexdotbelow;1EC6 -Ecircumflexgrave;1EC0 -Ecircumflexhookabove;1EC2 -Ecircumflexsmall;F7EA -Ecircumflextilde;1EC4 -Ecyrillic;0404 -Edblgrave;0204 -Edieresis;00CB -Edieresissmall;F7EB -Edot;0116 -Edotaccent;0116 -Edotbelow;1EB8 -Efcyrillic;0424 -Egrave;00C8 -Egravesmall;F7E8 -Eharmenian;0537 -Ehookabove;1EBA -Eightroman;2167 -Einvertedbreve;0206 -Eiotifiedcyrillic;0464 -Elcyrillic;041B -Elevenroman;216A -Emacron;0112 -Emacronacute;1E16 -Emacrongrave;1E14 -Emcyrillic;041C -Emonospace;FF25 -Encyrillic;041D -Endescendercyrillic;04A2 -Eng;014A -Enghecyrillic;04A4 -Enhookcyrillic;04C7 -Eogonek;0118 -Eopen;0190 -Epsilon;0395 -Epsilontonos;0388 -Ercyrillic;0420 -Ereversed;018E -Ereversedcyrillic;042D -Escyrillic;0421 -Esdescendercyrillic;04AA -Esh;01A9 -Esmall;F765 -Eta;0397 -Etarmenian;0538 -Etatonos;0389 -Eth;00D0 -Ethsmall;F7F0 -Etilde;1EBC -Etildebelow;1E1A -Euro;20AC -Ezh;01B7 -Ezhcaron;01EE -Ezhreversed;01B8 -F;0046 -Fcircle;24BB -Fdotaccent;1E1E -Feharmenian;0556 -Feicoptic;03E4 -Fhook;0191 -Fitacyrillic;0472 -Fiveroman;2164 -Fmonospace;FF26 -Fourroman;2163 -Fsmall;F766 -G;0047 -GBsquare;3387 -Gacute;01F4 -Gamma;0393 -Gammaafrican;0194 -Gangiacoptic;03EA -Gbreve;011E -Gcaron;01E6 -Gcedilla;0122 -Gcircle;24BC -Gcircumflex;011C -Gcommaaccent;0122 -Gdot;0120 -Gdotaccent;0120 -Gecyrillic;0413 -Ghadarmenian;0542 -Ghemiddlehookcyrillic;0494 -Ghestrokecyrillic;0492 -Gheupturncyrillic;0490 -Ghook;0193 -Gimarmenian;0533 -Gjecyrillic;0403 -Gmacron;1E20 -Gmonospace;FF27 -Grave;F6CE -Gravesmall;F760 -Gsmall;F767 -Gsmallhook;029B -Gstroke;01E4 -H;0048 -H18533;25CF -H18543;25AA -H18551;25AB -H22073;25A1 -HPsquare;33CB -Haabkhasiancyrillic;04A8 -Hadescendercyrillic;04B2 -Hardsigncyrillic;042A -Hbar;0126 -Hbrevebelow;1E2A -Hcedilla;1E28 -Hcircle;24BD -Hcircumflex;0124 -Hdieresis;1E26 -Hdotaccent;1E22 -Hdotbelow;1E24 -Hmonospace;FF28 -Hoarmenian;0540 -Horicoptic;03E8 -Hsmall;F768 -Hungarumlaut;F6CF -Hungarumlautsmall;F6F8 -Hzsquare;3390 -I;0049 -IAcyrillic;042F -IJ;0132 -IUcyrillic;042E -Iacute;00CD -Iacutesmall;F7ED -Ibreve;012C -Icaron;01CF -Icircle;24BE -Icircumflex;00CE -Icircumflexsmall;F7EE -Icyrillic;0406 -Idblgrave;0208 -Idieresis;00CF -Idieresisacute;1E2E -Idieresiscyrillic;04E4 -Idieresissmall;F7EF -Idot;0130 -Idotaccent;0130 -Idotbelow;1ECA -Iebrevecyrillic;04D6 -Iecyrillic;0415 -Ifraktur;2111 -Igrave;00CC -Igravesmall;F7EC -Ihookabove;1EC8 -Iicyrillic;0418 -Iinvertedbreve;020A -Iishortcyrillic;0419 -Imacron;012A -Imacroncyrillic;04E2 -Imonospace;FF29 -Iniarmenian;053B -Iocyrillic;0401 -Iogonek;012E -Iota;0399 -Iotaafrican;0196 -Iotadieresis;03AA -Iotatonos;038A -Ismall;F769 -Istroke;0197 -Itilde;0128 -Itildebelow;1E2C -Izhitsacyrillic;0474 -Izhitsadblgravecyrillic;0476 -J;004A -Jaarmenian;0541 -Jcircle;24BF -Jcircumflex;0134 -Jecyrillic;0408 -Jheharmenian;054B -Jmonospace;FF2A -Jsmall;F76A -K;004B -KBsquare;3385 -KKsquare;33CD -Kabashkircyrillic;04A0 -Kacute;1E30 -Kacyrillic;041A -Kadescendercyrillic;049A -Kahookcyrillic;04C3 -Kappa;039A -Kastrokecyrillic;049E -Kaverticalstrokecyrillic;049C -Kcaron;01E8 -Kcedilla;0136 -Kcircle;24C0 -Kcommaaccent;0136 -Kdotbelow;1E32 -Keharmenian;0554 -Kenarmenian;053F -Khacyrillic;0425 -Kheicoptic;03E6 -Khook;0198 -Kjecyrillic;040C -Klinebelow;1E34 -Kmonospace;FF2B -Koppacyrillic;0480 -Koppagreek;03DE -Ksicyrillic;046E -Ksmall;F76B -L;004C -LJ;01C7 -LL;F6BF -Lacute;0139 -Lambda;039B -Lcaron;013D -Lcedilla;013B -Lcircle;24C1 -Lcircumflexbelow;1E3C -Lcommaaccent;013B -Ldot;013F -Ldotaccent;013F -Ldotbelow;1E36 -Ldotbelowmacron;1E38 -Liwnarmenian;053C -Lj;01C8 -Ljecyrillic;0409 -Llinebelow;1E3A -Lmonospace;FF2C -Lslash;0141 -Lslashsmall;F6F9 -Lsmall;F76C -M;004D -MBsquare;3386 -Macron;F6D0 -Macronsmall;F7AF -Macute;1E3E -Mcircle;24C2 -Mdotaccent;1E40 -Mdotbelow;1E42 -Menarmenian;0544 -Mmonospace;FF2D -Msmall;F76D -Mturned;019C -Mu;039C -N;004E -NJ;01CA -Nacute;0143 -Ncaron;0147 -Ncedilla;0145 -Ncircle;24C3 -Ncircumflexbelow;1E4A -Ncommaaccent;0145 -Ndotaccent;1E44 -Ndotbelow;1E46 -Nhookleft;019D -Nineroman;2168 -Nj;01CB -Njecyrillic;040A -Nlinebelow;1E48 -Nmonospace;FF2E -Nowarmenian;0546 -Nsmall;F76E -Ntilde;00D1 -Ntildesmall;F7F1 -Nu;039D -O;004F -OE;0152 -OEsmall;F6FA -Oacute;00D3 -Oacutesmall;F7F3 -Obarredcyrillic;04E8 -Obarreddieresiscyrillic;04EA -Obreve;014E -Ocaron;01D1 -Ocenteredtilde;019F -Ocircle;24C4 -Ocircumflex;00D4 -Ocircumflexacute;1ED0 -Ocircumflexdotbelow;1ED8 -Ocircumflexgrave;1ED2 -Ocircumflexhookabove;1ED4 -Ocircumflexsmall;F7F4 -Ocircumflextilde;1ED6 -Ocyrillic;041E -Odblacute;0150 -Odblgrave;020C -Odieresis;00D6 -Odieresiscyrillic;04E6 -Odieresissmall;F7F6 -Odotbelow;1ECC -Ogoneksmall;F6FB -Ograve;00D2 -Ogravesmall;F7F2 -Oharmenian;0555 -Ohm;2126 -Ohookabove;1ECE -Ohorn;01A0 -Ohornacute;1EDA -Ohorndotbelow;1EE2 -Ohorngrave;1EDC -Ohornhookabove;1EDE -Ohorntilde;1EE0 -Ohungarumlaut;0150 -Oi;01A2 -Oinvertedbreve;020E -Omacron;014C -Omacronacute;1E52 -Omacrongrave;1E50 -Omega;2126 -Omegacyrillic;0460 -Omegagreek;03A9 -Omegaroundcyrillic;047A -Omegatitlocyrillic;047C -Omegatonos;038F -Omicron;039F -Omicrontonos;038C -Omonospace;FF2F -Oneroman;2160 -Oogonek;01EA -Oogonekmacron;01EC -Oopen;0186 -Oslash;00D8 -Oslashacute;01FE -Oslashsmall;F7F8 -Osmall;F76F -Ostrokeacute;01FE -Otcyrillic;047E -Otilde;00D5 -Otildeacute;1E4C -Otildedieresis;1E4E -Otildesmall;F7F5 -P;0050 -Pacute;1E54 -Pcircle;24C5 -Pdotaccent;1E56 -Pecyrillic;041F -Peharmenian;054A -Pemiddlehookcyrillic;04A6 -Phi;03A6 -Phook;01A4 -Pi;03A0 -Piwrarmenian;0553 -Pmonospace;FF30 -Psi;03A8 -Psicyrillic;0470 -Psmall;F770 -Q;0051 -Qcircle;24C6 -Qmonospace;FF31 -Qsmall;F771 -R;0052 -Raarmenian;054C -Racute;0154 -Rcaron;0158 -Rcedilla;0156 -Rcircle;24C7 -Rcommaaccent;0156 -Rdblgrave;0210 -Rdotaccent;1E58 -Rdotbelow;1E5A -Rdotbelowmacron;1E5C -Reharmenian;0550 -Rfraktur;211C -Rho;03A1 -Ringsmall;F6FC -Rinvertedbreve;0212 -Rlinebelow;1E5E -Rmonospace;FF32 -Rsmall;F772 -Rsmallinverted;0281 -Rsmallinvertedsuperior;02B6 -S;0053 -SF010000;250C -SF020000;2514 -SF030000;2510 -SF040000;2518 -SF050000;253C -SF060000;252C -SF070000;2534 -SF080000;251C -SF090000;2524 -SF100000;2500 -SF110000;2502 -SF190000;2561 -SF200000;2562 -SF210000;2556 -SF220000;2555 -SF230000;2563 -SF240000;2551 -SF250000;2557 -SF260000;255D -SF270000;255C -SF280000;255B -SF360000;255E -SF370000;255F -SF380000;255A -SF390000;2554 -SF400000;2569 -SF410000;2566 -SF420000;2560 -SF430000;2550 -SF440000;256C -SF450000;2567 -SF460000;2568 -SF470000;2564 -SF480000;2565 -SF490000;2559 -SF500000;2558 -SF510000;2552 -SF520000;2553 -SF530000;256B -SF540000;256A -Sacute;015A -Sacutedotaccent;1E64 -Sampigreek;03E0 -Scaron;0160 -Scarondotaccent;1E66 -Scaronsmall;F6FD -Scedilla;015E -Schwa;018F -Schwacyrillic;04D8 -Schwadieresiscyrillic;04DA -Scircle;24C8 -Scircumflex;015C -Scommaaccent;0218 -Sdotaccent;1E60 -Sdotbelow;1E62 -Sdotbelowdotaccent;1E68 -Seharmenian;054D -Sevenroman;2166 -Shaarmenian;0547 -Shacyrillic;0428 -Shchacyrillic;0429 -Sheicoptic;03E2 -Shhacyrillic;04BA -Shimacoptic;03EC -Sigma;03A3 -Sixroman;2165 -Smonospace;FF33 -Softsigncyrillic;042C -Ssmall;F773 -Stigmagreek;03DA -T;0054 -Tau;03A4 -Tbar;0166 -Tcaron;0164 -Tcedilla;0162 -Tcircle;24C9 -Tcircumflexbelow;1E70 -Tcommaaccent;0162 -Tdotaccent;1E6A -Tdotbelow;1E6C -Tecyrillic;0422 -Tedescendercyrillic;04AC -Tenroman;2169 -Tetsecyrillic;04B4 -Theta;0398 -Thook;01AC -Thorn;00DE -Thornsmall;F7FE -Threeroman;2162 -Tildesmall;F6FE -Tiwnarmenian;054F -Tlinebelow;1E6E -Tmonospace;FF34 -Toarmenian;0539 -Tonefive;01BC -Tonesix;0184 -Tonetwo;01A7 -Tretroflexhook;01AE -Tsecyrillic;0426 -Tshecyrillic;040B -Tsmall;F774 -Twelveroman;216B -Tworoman;2161 -U;0055 -Uacute;00DA -Uacutesmall;F7FA -Ubreve;016C -Ucaron;01D3 -Ucircle;24CA -Ucircumflex;00DB -Ucircumflexbelow;1E76 -Ucircumflexsmall;F7FB -Ucyrillic;0423 -Udblacute;0170 -Udblgrave;0214 -Udieresis;00DC -Udieresisacute;01D7 -Udieresisbelow;1E72 -Udieresiscaron;01D9 -Udieresiscyrillic;04F0 -Udieresisgrave;01DB -Udieresismacron;01D5 -Udieresissmall;F7FC -Udotbelow;1EE4 -Ugrave;00D9 -Ugravesmall;F7F9 -Uhookabove;1EE6 -Uhorn;01AF -Uhornacute;1EE8 -Uhorndotbelow;1EF0 -Uhorngrave;1EEA -Uhornhookabove;1EEC -Uhorntilde;1EEE -Uhungarumlaut;0170 -Uhungarumlautcyrillic;04F2 -Uinvertedbreve;0216 -Ukcyrillic;0478 -Umacron;016A -Umacroncyrillic;04EE -Umacrondieresis;1E7A -Umonospace;FF35 -Uogonek;0172 -Upsilon;03A5 -Upsilon1;03D2 -Upsilonacutehooksymbolgreek;03D3 -Upsilonafrican;01B1 -Upsilondieresis;03AB -Upsilondieresishooksymbolgreek;03D4 -Upsilonhooksymbol;03D2 -Upsilontonos;038E -Uring;016E -Ushortcyrillic;040E -Usmall;F775 -Ustraightcyrillic;04AE -Ustraightstrokecyrillic;04B0 -Utilde;0168 -Utildeacute;1E78 -Utildebelow;1E74 -V;0056 -Vcircle;24CB -Vdotbelow;1E7E -Vecyrillic;0412 -Vewarmenian;054E -Vhook;01B2 -Vmonospace;FF36 -Voarmenian;0548 -Vsmall;F776 -Vtilde;1E7C -W;0057 -Wacute;1E82 -Wcircle;24CC -Wcircumflex;0174 -Wdieresis;1E84 -Wdotaccent;1E86 -Wdotbelow;1E88 -Wgrave;1E80 -Wmonospace;FF37 -Wsmall;F777 -X;0058 -Xcircle;24CD -Xdieresis;1E8C -Xdotaccent;1E8A -Xeharmenian;053D -Xi;039E -Xmonospace;FF38 -Xsmall;F778 -Y;0059 -Yacute;00DD -Yacutesmall;F7FD -Yatcyrillic;0462 -Ycircle;24CE -Ycircumflex;0176 -Ydieresis;0178 -Ydieresissmall;F7FF -Ydotaccent;1E8E -Ydotbelow;1EF4 -Yericyrillic;042B -Yerudieresiscyrillic;04F8 -Ygrave;1EF2 -Yhook;01B3 -Yhookabove;1EF6 -Yiarmenian;0545 -Yicyrillic;0407 -Yiwnarmenian;0552 -Ymonospace;FF39 -Ysmall;F779 -Ytilde;1EF8 -Yusbigcyrillic;046A -Yusbigiotifiedcyrillic;046C -Yuslittlecyrillic;0466 -Yuslittleiotifiedcyrillic;0468 -Z;005A -Zaarmenian;0536 -Zacute;0179 -Zcaron;017D -Zcaronsmall;F6FF -Zcircle;24CF -Zcircumflex;1E90 -Zdot;017B -Zdotaccent;017B -Zdotbelow;1E92 -Zecyrillic;0417 -Zedescendercyrillic;0498 -Zedieresiscyrillic;04DE -Zeta;0396 -Zhearmenian;053A -Zhebrevecyrillic;04C1 -Zhecyrillic;0416 -Zhedescendercyrillic;0496 -Zhedieresiscyrillic;04DC -Zlinebelow;1E94 -Zmonospace;FF3A -Zsmall;F77A -Zstroke;01B5 -a;0061 -aabengali;0986 -aacute;00E1 -aadeva;0906 -aagujarati;0A86 -aagurmukhi;0A06 -aamatragurmukhi;0A3E -aarusquare;3303 -aavowelsignbengali;09BE -aavowelsigndeva;093E -aavowelsigngujarati;0ABE -abbreviationmarkarmenian;055F -abbreviationsigndeva;0970 -abengali;0985 -abopomofo;311A -abreve;0103 -abreveacute;1EAF -abrevecyrillic;04D1 -abrevedotbelow;1EB7 -abrevegrave;1EB1 -abrevehookabove;1EB3 -abrevetilde;1EB5 -acaron;01CE -acircle;24D0 -acircumflex;00E2 -acircumflexacute;1EA5 -acircumflexdotbelow;1EAD -acircumflexgrave;1EA7 -acircumflexhookabove;1EA9 -acircumflextilde;1EAB -acute;00B4 -acutebelowcmb;0317 -acutecmb;0301 -acutecomb;0301 -acutedeva;0954 -acutelowmod;02CF -acutetonecmb;0341 -acyrillic;0430 -adblgrave;0201 -addakgurmukhi;0A71 -adeva;0905 -adieresis;00E4 -adieresiscyrillic;04D3 -adieresismacron;01DF -adotbelow;1EA1 -adotmacron;01E1 -ae;00E6 -aeacute;01FD -aekorean;3150 -aemacron;01E3 -afii00208;2015 -afii08941;20A4 -afii10017;0410 -afii10018;0411 -afii10019;0412 -afii10020;0413 -afii10021;0414 -afii10022;0415 -afii10023;0401 -afii10024;0416 -afii10025;0417 -afii10026;0418 -afii10027;0419 -afii10028;041A -afii10029;041B -afii10030;041C -afii10031;041D -afii10032;041E -afii10033;041F -afii10034;0420 -afii10035;0421 -afii10036;0422 -afii10037;0423 -afii10038;0424 -afii10039;0425 -afii10040;0426 -afii10041;0427 -afii10042;0428 -afii10043;0429 -afii10044;042A -afii10045;042B -afii10046;042C -afii10047;042D -afii10048;042E -afii10049;042F -afii10050;0490 -afii10051;0402 -afii10052;0403 -afii10053;0404 -afii10054;0405 -afii10055;0406 -afii10056;0407 -afii10057;0408 -afii10058;0409 -afii10059;040A -afii10060;040B -afii10061;040C -afii10062;040E -afii10063;F6C4 -afii10064;F6C5 -afii10065;0430 -afii10066;0431 -afii10067;0432 -afii10068;0433 -afii10069;0434 -afii10070;0435 -afii10071;0451 -afii10072;0436 -afii10073;0437 -afii10074;0438 -afii10075;0439 -afii10076;043A -afii10077;043B -afii10078;043C -afii10079;043D -afii10080;043E -afii10081;043F -afii10082;0440 -afii10083;0441 -afii10084;0442 -afii10085;0443 -afii10086;0444 -afii10087;0445 -afii10088;0446 -afii10089;0447 -afii10090;0448 -afii10091;0449 -afii10092;044A -afii10093;044B -afii10094;044C -afii10095;044D -afii10096;044E -afii10097;044F -afii10098;0491 -afii10099;0452 -afii10100;0453 -afii10101;0454 -afii10102;0455 -afii10103;0456 -afii10104;0457 -afii10105;0458 -afii10106;0459 -afii10107;045A -afii10108;045B -afii10109;045C -afii10110;045E -afii10145;040F -afii10146;0462 -afii10147;0472 -afii10148;0474 -afii10192;F6C6 -afii10193;045F -afii10194;0463 -afii10195;0473 -afii10196;0475 -afii10831;F6C7 -afii10832;F6C8 -afii10846;04D9 -afii299;200E -afii300;200F -afii301;200D -afii57381;066A -afii57388;060C -afii57392;0660 -afii57393;0661 -afii57394;0662 -afii57395;0663 -afii57396;0664 -afii57397;0665 -afii57398;0666 -afii57399;0667 -afii57400;0668 -afii57401;0669 -afii57403;061B -afii57407;061F -afii57409;0621 -afii57410;0622 -afii57411;0623 -afii57412;0624 -afii57413;0625 -afii57414;0626 -afii57415;0627 -afii57416;0628 -afii57417;0629 -afii57418;062A -afii57419;062B -afii57420;062C -afii57421;062D -afii57422;062E -afii57423;062F -afii57424;0630 -afii57425;0631 -afii57426;0632 -afii57427;0633 -afii57428;0634 -afii57429;0635 -afii57430;0636 -afii57431;0637 -afii57432;0638 -afii57433;0639 -afii57434;063A -afii57440;0640 -afii57441;0641 -afii57442;0642 -afii57443;0643 -afii57444;0644 -afii57445;0645 -afii57446;0646 -afii57448;0648 -afii57449;0649 -afii57450;064A -afii57451;064B -afii57452;064C -afii57453;064D -afii57454;064E -afii57455;064F -afii57456;0650 -afii57457;0651 -afii57458;0652 -afii57470;0647 -afii57505;06A4 -afii57506;067E -afii57507;0686 -afii57508;0698 -afii57509;06AF -afii57511;0679 -afii57512;0688 -afii57513;0691 -afii57514;06BA -afii57519;06D2 -afii57534;06D5 -afii57636;20AA -afii57645;05BE -afii57658;05C3 -afii57664;05D0 -afii57665;05D1 -afii57666;05D2 -afii57667;05D3 -afii57668;05D4 -afii57669;05D5 -afii57670;05D6 -afii57671;05D7 -afii57672;05D8 -afii57673;05D9 -afii57674;05DA -afii57675;05DB -afii57676;05DC -afii57677;05DD -afii57678;05DE -afii57679;05DF -afii57680;05E0 -afii57681;05E1 -afii57682;05E2 -afii57683;05E3 -afii57684;05E4 -afii57685;05E5 -afii57686;05E6 -afii57687;05E7 -afii57688;05E8 -afii57689;05E9 -afii57690;05EA -afii57694;FB2A -afii57695;FB2B -afii57700;FB4B -afii57705;FB1F -afii57716;05F0 -afii57717;05F1 -afii57718;05F2 -afii57723;FB35 -afii57793;05B4 -afii57794;05B5 -afii57795;05B6 -afii57796;05BB -afii57797;05B8 -afii57798;05B7 -afii57799;05B0 -afii57800;05B2 -afii57801;05B1 -afii57802;05B3 -afii57803;05C2 -afii57804;05C1 -afii57806;05B9 -afii57807;05BC -afii57839;05BD -afii57841;05BF -afii57842;05C0 -afii57929;02BC -afii61248;2105 -afii61289;2113 -afii61352;2116 -afii61573;202C -afii61574;202D -afii61575;202E -afii61664;200C -afii63167;066D -afii64937;02BD -agrave;00E0 -agujarati;0A85 -agurmukhi;0A05 -ahiragana;3042 -ahookabove;1EA3 -aibengali;0990 -aibopomofo;311E -aideva;0910 -aiecyrillic;04D5 -aigujarati;0A90 -aigurmukhi;0A10 -aimatragurmukhi;0A48 -ainarabic;0639 -ainfinalarabic;FECA -aininitialarabic;FECB -ainmedialarabic;FECC -ainvertedbreve;0203 -aivowelsignbengali;09C8 -aivowelsigndeva;0948 -aivowelsigngujarati;0AC8 -akatakana;30A2 -akatakanahalfwidth;FF71 -akorean;314F -alef;05D0 -alefarabic;0627 -alefdageshhebrew;FB30 -aleffinalarabic;FE8E -alefhamzaabovearabic;0623 -alefhamzaabovefinalarabic;FE84 -alefhamzabelowarabic;0625 -alefhamzabelowfinalarabic;FE88 -alefhebrew;05D0 -aleflamedhebrew;FB4F -alefmaddaabovearabic;0622 -alefmaddaabovefinalarabic;FE82 -alefmaksuraarabic;0649 -alefmaksurafinalarabic;FEF0 -alefmaksurainitialarabic;FEF3 -alefmaksuramedialarabic;FEF4 -alefpatahhebrew;FB2E -alefqamatshebrew;FB2F -aleph;2135 -allequal;224C -alpha;03B1 -alphatonos;03AC -amacron;0101 -amonospace;FF41 -ampersand;0026 -ampersandmonospace;FF06 -ampersandsmall;F726 -amsquare;33C2 -anbopomofo;3122 -angbopomofo;3124 -angkhankhuthai;0E5A -angle;2220 -anglebracketleft;3008 -anglebracketleftvertical;FE3F -anglebracketright;3009 -anglebracketrightvertical;FE40 -angleleft;2329 -angleright;232A -angstrom;212B -anoteleia;0387 -anudattadeva;0952 -anusvarabengali;0982 -anusvaradeva;0902 -anusvaragujarati;0A82 -aogonek;0105 -apaatosquare;3300 -aparen;249C -apostrophearmenian;055A -apostrophemod;02BC -apple;F8FF -approaches;2250 -approxequal;2248 -approxequalorimage;2252 -approximatelyequal;2245 -araeaekorean;318E -araeakorean;318D -arc;2312 -arighthalfring;1E9A -aring;00E5 -aringacute;01FB -aringbelow;1E01 -arrowboth;2194 -arrowdashdown;21E3 -arrowdashleft;21E0 -arrowdashright;21E2 -arrowdashup;21E1 -arrowdblboth;21D4 -arrowdbldown;21D3 -arrowdblleft;21D0 -arrowdblright;21D2 -arrowdblup;21D1 -arrowdown;2193 -arrowdownleft;2199 -arrowdownright;2198 -arrowdownwhite;21E9 -arrowheaddownmod;02C5 -arrowheadleftmod;02C2 -arrowheadrightmod;02C3 -arrowheadupmod;02C4 -arrowhorizex;F8E7 -arrowleft;2190 -arrowleftdbl;21D0 -arrowleftdblstroke;21CD -arrowleftoverright;21C6 -arrowleftwhite;21E6 -arrowright;2192 -arrowrightdblstroke;21CF -arrowrightheavy;279E -arrowrightoverleft;21C4 -arrowrightwhite;21E8 -arrowtableft;21E4 -arrowtabright;21E5 -arrowup;2191 -arrowupdn;2195 -arrowupdnbse;21A8 -arrowupdownbase;21A8 -arrowupleft;2196 -arrowupleftofdown;21C5 -arrowupright;2197 -arrowupwhite;21E7 -arrowvertex;F8E6 -asciicircum;005E -asciicircummonospace;FF3E -asciitilde;007E -asciitildemonospace;FF5E -ascript;0251 -ascriptturned;0252 -asmallhiragana;3041 -asmallkatakana;30A1 -asmallkatakanahalfwidth;FF67 -asterisk;002A -asteriskaltonearabic;066D -asteriskarabic;066D -asteriskmath;2217 -asteriskmonospace;FF0A -asterisksmall;FE61 -asterism;2042 -asuperior;F6E9 -asymptoticallyequal;2243 -at;0040 -atilde;00E3 -atmonospace;FF20 -atsmall;FE6B -aturned;0250 -aubengali;0994 -aubopomofo;3120 -audeva;0914 -augujarati;0A94 -augurmukhi;0A14 -aulengthmarkbengali;09D7 -aumatragurmukhi;0A4C -auvowelsignbengali;09CC -auvowelsigndeva;094C -auvowelsigngujarati;0ACC -avagrahadeva;093D -aybarmenian;0561 -ayin;05E2 -ayinaltonehebrew;FB20 -ayinhebrew;05E2 -b;0062 -babengali;09AC -backslash;005C -backslashmonospace;FF3C -badeva;092C -bagujarati;0AAC -bagurmukhi;0A2C -bahiragana;3070 -bahtthai;0E3F -bakatakana;30D0 -bar;007C -barmonospace;FF5C -bbopomofo;3105 -bcircle;24D1 -bdotaccent;1E03 -bdotbelow;1E05 -beamedsixteenthnotes;266C -because;2235 -becyrillic;0431 -beharabic;0628 -behfinalarabic;FE90 -behinitialarabic;FE91 -behiragana;3079 -behmedialarabic;FE92 -behmeeminitialarabic;FC9F -behmeemisolatedarabic;FC08 -behnoonfinalarabic;FC6D -bekatakana;30D9 -benarmenian;0562 -bet;05D1 -beta;03B2 -betasymbolgreek;03D0 -betdagesh;FB31 -betdageshhebrew;FB31 -bethebrew;05D1 -betrafehebrew;FB4C -bhabengali;09AD -bhadeva;092D -bhagujarati;0AAD -bhagurmukhi;0A2D -bhook;0253 -bihiragana;3073 -bikatakana;30D3 -bilabialclick;0298 -bindigurmukhi;0A02 -birusquare;3331 -blackcircle;25CF -blackdiamond;25C6 -blackdownpointingtriangle;25BC -blackleftpointingpointer;25C4 -blackleftpointingtriangle;25C0 -blacklenticularbracketleft;3010 -blacklenticularbracketleftvertical;FE3B -blacklenticularbracketright;3011 -blacklenticularbracketrightvertical;FE3C -blacklowerlefttriangle;25E3 -blacklowerrighttriangle;25E2 -blackrectangle;25AC -blackrightpointingpointer;25BA -blackrightpointingtriangle;25B6 -blacksmallsquare;25AA -blacksmilingface;263B -blacksquare;25A0 -blackstar;2605 -blackupperlefttriangle;25E4 -blackupperrighttriangle;25E5 -blackuppointingsmalltriangle;25B4 -blackuppointingtriangle;25B2 -blank;2423 -blinebelow;1E07 -block;2588 -bmonospace;FF42 -bobaimaithai;0E1A -bohiragana;307C -bokatakana;30DC -bparen;249D -bqsquare;33C3 -braceex;F8F4 -braceleft;007B -braceleftbt;F8F3 -braceleftmid;F8F2 -braceleftmonospace;FF5B -braceleftsmall;FE5B -bracelefttp;F8F1 -braceleftvertical;FE37 -braceright;007D -bracerightbt;F8FE -bracerightmid;F8FD -bracerightmonospace;FF5D -bracerightsmall;FE5C -bracerighttp;F8FC -bracerightvertical;FE38 -bracketleft;005B -bracketleftbt;F8F0 -bracketleftex;F8EF -bracketleftmonospace;FF3B -bracketlefttp;F8EE -bracketright;005D -bracketrightbt;F8FB -bracketrightex;F8FA -bracketrightmonospace;FF3D -bracketrighttp;F8F9 -breve;02D8 -brevebelowcmb;032E -brevecmb;0306 -breveinvertedbelowcmb;032F -breveinvertedcmb;0311 -breveinverteddoublecmb;0361 -bridgebelowcmb;032A -bridgeinvertedbelowcmb;033A -brokenbar;00A6 -bstroke;0180 -bsuperior;F6EA -btopbar;0183 -buhiragana;3076 -bukatakana;30D6 -bullet;2022 -bulletinverse;25D8 -bulletoperator;2219 -bullseye;25CE -c;0063 -caarmenian;056E -cabengali;099A -cacute;0107 -cadeva;091A -cagujarati;0A9A -cagurmukhi;0A1A -calsquare;3388 -candrabindubengali;0981 -candrabinducmb;0310 -candrabindudeva;0901 -candrabindugujarati;0A81 -capslock;21EA -careof;2105 -caron;02C7 -caronbelowcmb;032C -caroncmb;030C -carriagereturn;21B5 -cbopomofo;3118 -ccaron;010D -ccedilla;00E7 -ccedillaacute;1E09 -ccircle;24D2 -ccircumflex;0109 -ccurl;0255 -cdot;010B -cdotaccent;010B -cdsquare;33C5 -cedilla;00B8 -cedillacmb;0327 -cent;00A2 -centigrade;2103 -centinferior;F6DF -centmonospace;FFE0 -centoldstyle;F7A2 -centsuperior;F6E0 -chaarmenian;0579 -chabengali;099B -chadeva;091B -chagujarati;0A9B -chagurmukhi;0A1B -chbopomofo;3114 -cheabkhasiancyrillic;04BD -checkmark;2713 -checyrillic;0447 -chedescenderabkhasiancyrillic;04BF -chedescendercyrillic;04B7 -chedieresiscyrillic;04F5 -cheharmenian;0573 -chekhakassiancyrillic;04CC -cheverticalstrokecyrillic;04B9 -chi;03C7 -chieuchacirclekorean;3277 -chieuchaparenkorean;3217 -chieuchcirclekorean;3269 -chieuchkorean;314A -chieuchparenkorean;3209 -chochangthai;0E0A -chochanthai;0E08 -chochingthai;0E09 -chochoethai;0E0C -chook;0188 -cieucacirclekorean;3276 -cieucaparenkorean;3216 -cieuccirclekorean;3268 -cieuckorean;3148 -cieucparenkorean;3208 -cieucuparenkorean;321C -circle;25CB -circlemultiply;2297 -circleot;2299 -circleplus;2295 -circlepostalmark;3036 -circlewithlefthalfblack;25D0 -circlewithrighthalfblack;25D1 -circumflex;02C6 -circumflexbelowcmb;032D -circumflexcmb;0302 -clear;2327 -clickalveolar;01C2 -clickdental;01C0 -clicklateral;01C1 -clickretroflex;01C3 -club;2663 -clubsuitblack;2663 -clubsuitwhite;2667 -cmcubedsquare;33A4 -cmonospace;FF43 -cmsquaredsquare;33A0 -coarmenian;0581 -colon;003A -colonmonetary;20A1 -colonmonospace;FF1A -colonsign;20A1 -colonsmall;FE55 -colontriangularhalfmod;02D1 -colontriangularmod;02D0 -comma;002C -commaabovecmb;0313 -commaaboverightcmb;0315 -commaaccent;F6C3 -commaarabic;060C -commaarmenian;055D -commainferior;F6E1 -commamonospace;FF0C -commareversedabovecmb;0314 -commareversedmod;02BD -commasmall;FE50 -commasuperior;F6E2 -commaturnedabovecmb;0312 -commaturnedmod;02BB -compass;263C -congruent;2245 -contourintegral;222E -control;2303 -controlACK;0006 -controlBEL;0007 -controlBS;0008 -controlCAN;0018 -controlCR;000D -controlDC1;0011 -controlDC2;0012 -controlDC3;0013 -controlDC4;0014 -controlDEL;007F -controlDLE;0010 -controlEM;0019 -controlENQ;0005 -controlEOT;0004 -controlESC;001B -controlETB;0017 -controlETX;0003 -controlFF;000C -controlFS;001C -controlGS;001D -controlHT;0009 -controlLF;000A -controlNAK;0015 -controlRS;001E -controlSI;000F -controlSO;000E -controlSOT;0002 -controlSTX;0001 -controlSUB;001A -controlSYN;0016 -controlUS;001F -controlVT;000B -copyright;00A9 -copyrightsans;F8E9 -copyrightserif;F6D9 -cornerbracketleft;300C -cornerbracketlefthalfwidth;FF62 -cornerbracketleftvertical;FE41 -cornerbracketright;300D -cornerbracketrighthalfwidth;FF63 -cornerbracketrightvertical;FE42 -corporationsquare;337F -cosquare;33C7 -coverkgsquare;33C6 -cparen;249E -cruzeiro;20A2 -cstretched;0297 -curlyand;22CF -curlyor;22CE -currency;00A4 -cyrBreve;F6D1 -cyrFlex;F6D2 -cyrbreve;F6D4 -cyrflex;F6D5 -d;0064 -daarmenian;0564 -dabengali;09A6 -dadarabic;0636 -dadeva;0926 -dadfinalarabic;FEBE -dadinitialarabic;FEBF -dadmedialarabic;FEC0 -dagesh;05BC -dageshhebrew;05BC -dagger;2020 -daggerdbl;2021 -dagujarati;0AA6 -dagurmukhi;0A26 -dahiragana;3060 -dakatakana;30C0 -dalarabic;062F -dalet;05D3 -daletdagesh;FB33 -daletdageshhebrew;FB33 -dalethatafpatah;05D3 05B2 -dalethatafpatahhebrew;05D3 05B2 -dalethatafsegol;05D3 05B1 -dalethatafsegolhebrew;05D3 05B1 -dalethebrew;05D3 -dalethiriq;05D3 05B4 -dalethiriqhebrew;05D3 05B4 -daletholam;05D3 05B9 -daletholamhebrew;05D3 05B9 -daletpatah;05D3 05B7 -daletpatahhebrew;05D3 05B7 -daletqamats;05D3 05B8 -daletqamatshebrew;05D3 05B8 -daletqubuts;05D3 05BB -daletqubutshebrew;05D3 05BB -daletsegol;05D3 05B6 -daletsegolhebrew;05D3 05B6 -daletsheva;05D3 05B0 -daletshevahebrew;05D3 05B0 -dalettsere;05D3 05B5 -dalettserehebrew;05D3 05B5 -dalfinalarabic;FEAA -dammaarabic;064F -dammalowarabic;064F -dammatanaltonearabic;064C -dammatanarabic;064C -danda;0964 -dargahebrew;05A7 -dargalefthebrew;05A7 -dasiapneumatacyrilliccmb;0485 -dblGrave;F6D3 -dblanglebracketleft;300A -dblanglebracketleftvertical;FE3D -dblanglebracketright;300B -dblanglebracketrightvertical;FE3E -dblarchinvertedbelowcmb;032B -dblarrowleft;21D4 -dblarrowright;21D2 -dbldanda;0965 -dblgrave;F6D6 -dblgravecmb;030F -dblintegral;222C -dbllowline;2017 -dbllowlinecmb;0333 -dbloverlinecmb;033F -dblprimemod;02BA -dblverticalbar;2016 -dblverticallineabovecmb;030E -dbopomofo;3109 -dbsquare;33C8 -dcaron;010F -dcedilla;1E11 -dcircle;24D3 -dcircumflexbelow;1E13 -dcroat;0111 -ddabengali;09A1 -ddadeva;0921 -ddagujarati;0AA1 -ddagurmukhi;0A21 -ddalarabic;0688 -ddalfinalarabic;FB89 -dddhadeva;095C -ddhabengali;09A2 -ddhadeva;0922 -ddhagujarati;0AA2 -ddhagurmukhi;0A22 -ddotaccent;1E0B -ddotbelow;1E0D -decimalseparatorarabic;066B -decimalseparatorpersian;066B -decyrillic;0434 -degree;00B0 -dehihebrew;05AD -dehiragana;3067 -deicoptic;03EF -dekatakana;30C7 -deleteleft;232B -deleteright;2326 -delta;03B4 -deltaturned;018D -denominatorminusonenumeratorbengali;09F8 -dezh;02A4 -dhabengali;09A7 -dhadeva;0927 -dhagujarati;0AA7 -dhagurmukhi;0A27 -dhook;0257 -dialytikatonos;0385 -dialytikatonoscmb;0344 -diamond;2666 -diamondsuitwhite;2662 -dieresis;00A8 -dieresisacute;F6D7 -dieresisbelowcmb;0324 -dieresiscmb;0308 -dieresisgrave;F6D8 -dieresistonos;0385 -dihiragana;3062 -dikatakana;30C2 -dittomark;3003 -divide;00F7 -divides;2223 -divisionslash;2215 -djecyrillic;0452 -dkshade;2593 -dlinebelow;1E0F -dlsquare;3397 -dmacron;0111 -dmonospace;FF44 -dnblock;2584 -dochadathai;0E0E -dodekthai;0E14 -dohiragana;3069 -dokatakana;30C9 -dollar;0024 -dollarinferior;F6E3 -dollarmonospace;FF04 -dollaroldstyle;F724 -dollarsmall;FE69 -dollarsuperior;F6E4 -dong;20AB -dorusquare;3326 -dotaccent;02D9 -dotaccentcmb;0307 -dotbelowcmb;0323 -dotbelowcomb;0323 -dotkatakana;30FB -dotlessi;0131 -dotlessj;F6BE -dotlessjstrokehook;0284 -dotmath;22C5 -dottedcircle;25CC -doubleyodpatah;FB1F -doubleyodpatahhebrew;FB1F -downtackbelowcmb;031E -downtackmod;02D5 -dparen;249F -dsuperior;F6EB -dtail;0256 -dtopbar;018C -duhiragana;3065 -dukatakana;30C5 -dz;01F3 -dzaltone;02A3 -dzcaron;01C6 -dzcurl;02A5 -dzeabkhasiancyrillic;04E1 -dzecyrillic;0455 -dzhecyrillic;045F -e;0065 -eacute;00E9 -earth;2641 -ebengali;098F -ebopomofo;311C -ebreve;0115 -ecandradeva;090D -ecandragujarati;0A8D -ecandravowelsigndeva;0945 -ecandravowelsigngujarati;0AC5 -ecaron;011B -ecedillabreve;1E1D -echarmenian;0565 -echyiwnarmenian;0587 -ecircle;24D4 -ecircumflex;00EA -ecircumflexacute;1EBF -ecircumflexbelow;1E19 -ecircumflexdotbelow;1EC7 -ecircumflexgrave;1EC1 -ecircumflexhookabove;1EC3 -ecircumflextilde;1EC5 -ecyrillic;0454 -edblgrave;0205 -edeva;090F -edieresis;00EB -edot;0117 -edotaccent;0117 -edotbelow;1EB9 -eegurmukhi;0A0F -eematragurmukhi;0A47 -efcyrillic;0444 -egrave;00E8 -egujarati;0A8F -eharmenian;0567 -ehbopomofo;311D -ehiragana;3048 -ehookabove;1EBB -eibopomofo;311F -eight;0038 -eightarabic;0668 -eightbengali;09EE -eightcircle;2467 -eightcircleinversesansserif;2791 -eightdeva;096E -eighteencircle;2471 -eighteenparen;2485 -eighteenperiod;2499 -eightgujarati;0AEE -eightgurmukhi;0A6E -eighthackarabic;0668 -eighthangzhou;3028 -eighthnotebeamed;266B -eightideographicparen;3227 -eightinferior;2088 -eightmonospace;FF18 -eightoldstyle;F738 -eightparen;247B -eightperiod;248F -eightpersian;06F8 -eightroman;2177 -eightsuperior;2078 -eightthai;0E58 -einvertedbreve;0207 -eiotifiedcyrillic;0465 -ekatakana;30A8 -ekatakanahalfwidth;FF74 -ekonkargurmukhi;0A74 -ekorean;3154 -elcyrillic;043B -element;2208 -elevencircle;246A -elevenparen;247E -elevenperiod;2492 -elevenroman;217A -ellipsis;2026 -ellipsisvertical;22EE -emacron;0113 -emacronacute;1E17 -emacrongrave;1E15 -emcyrillic;043C -emdash;2014 -emdashvertical;FE31 -emonospace;FF45 -emphasismarkarmenian;055B -emptyset;2205 -enbopomofo;3123 -encyrillic;043D -endash;2013 -endashvertical;FE32 -endescendercyrillic;04A3 -eng;014B -engbopomofo;3125 -enghecyrillic;04A5 -enhookcyrillic;04C8 -enspace;2002 -eogonek;0119 -eokorean;3153 -eopen;025B -eopenclosed;029A -eopenreversed;025C -eopenreversedclosed;025E -eopenreversedhook;025D -eparen;24A0 -epsilon;03B5 -epsilontonos;03AD -equal;003D -equalmonospace;FF1D -equalsmall;FE66 -equalsuperior;207C -equivalence;2261 -erbopomofo;3126 -ercyrillic;0440 -ereversed;0258 -ereversedcyrillic;044D -escyrillic;0441 -esdescendercyrillic;04AB -esh;0283 -eshcurl;0286 -eshortdeva;090E -eshortvowelsigndeva;0946 -eshreversedloop;01AA -eshsquatreversed;0285 -esmallhiragana;3047 -esmallkatakana;30A7 -esmallkatakanahalfwidth;FF6A -estimated;212E -esuperior;F6EC -eta;03B7 -etarmenian;0568 -etatonos;03AE -eth;00F0 -etilde;1EBD -etildebelow;1E1B -etnahtafoukhhebrew;0591 -etnahtafoukhlefthebrew;0591 -etnahtahebrew;0591 -etnahtalefthebrew;0591 -eturned;01DD -eukorean;3161 -euro;20AC -evowelsignbengali;09C7 -evowelsigndeva;0947 -evowelsigngujarati;0AC7 -exclam;0021 -exclamarmenian;055C -exclamdbl;203C -exclamdown;00A1 -exclamdownsmall;F7A1 -exclammonospace;FF01 -exclamsmall;F721 -existential;2203 -ezh;0292 -ezhcaron;01EF -ezhcurl;0293 -ezhreversed;01B9 -ezhtail;01BA -f;0066 -fadeva;095E -fagurmukhi;0A5E -fahrenheit;2109 -fathaarabic;064E -fathalowarabic;064E -fathatanarabic;064B -fbopomofo;3108 -fcircle;24D5 -fdotaccent;1E1F -feharabic;0641 -feharmenian;0586 -fehfinalarabic;FED2 -fehinitialarabic;FED3 -fehmedialarabic;FED4 -feicoptic;03E5 -female;2640 -ff;FB00 -ffi;FB03 -ffl;FB04 -fi;FB01 -fifteencircle;246E -fifteenparen;2482 -fifteenperiod;2496 -figuredash;2012 -filledbox;25A0 -filledrect;25AC -finalkaf;05DA -finalkafdagesh;FB3A -finalkafdageshhebrew;FB3A -finalkafhebrew;05DA -finalkafqamats;05DA 05B8 -finalkafqamatshebrew;05DA 05B8 -finalkafsheva;05DA 05B0 -finalkafshevahebrew;05DA 05B0 -finalmem;05DD -finalmemhebrew;05DD -finalnun;05DF -finalnunhebrew;05DF -finalpe;05E3 -finalpehebrew;05E3 -finaltsadi;05E5 -finaltsadihebrew;05E5 -firsttonechinese;02C9 -fisheye;25C9 -fitacyrillic;0473 -five;0035 -fivearabic;0665 -fivebengali;09EB -fivecircle;2464 -fivecircleinversesansserif;278E -fivedeva;096B -fiveeighths;215D -fivegujarati;0AEB -fivegurmukhi;0A6B -fivehackarabic;0665 -fivehangzhou;3025 -fiveideographicparen;3224 -fiveinferior;2085 -fivemonospace;FF15 -fiveoldstyle;F735 -fiveparen;2478 -fiveperiod;248C -fivepersian;06F5 -fiveroman;2174 -fivesuperior;2075 -fivethai;0E55 -fl;FB02 -florin;0192 -fmonospace;FF46 -fmsquare;3399 -fofanthai;0E1F -fofathai;0E1D -fongmanthai;0E4F -forall;2200 -four;0034 -fourarabic;0664 -fourbengali;09EA -fourcircle;2463 -fourcircleinversesansserif;278D -fourdeva;096A -fourgujarati;0AEA -fourgurmukhi;0A6A -fourhackarabic;0664 -fourhangzhou;3024 -fourideographicparen;3223 -fourinferior;2084 -fourmonospace;FF14 -fournumeratorbengali;09F7 -fouroldstyle;F734 -fourparen;2477 -fourperiod;248B -fourpersian;06F4 -fourroman;2173 -foursuperior;2074 -fourteencircle;246D -fourteenparen;2481 -fourteenperiod;2495 -fourthai;0E54 -fourthtonechinese;02CB -fparen;24A1 -fraction;2044 -franc;20A3 -g;0067 -gabengali;0997 -gacute;01F5 -gadeva;0917 -gafarabic;06AF -gaffinalarabic;FB93 -gafinitialarabic;FB94 -gafmedialarabic;FB95 -gagujarati;0A97 -gagurmukhi;0A17 -gahiragana;304C -gakatakana;30AC -gamma;03B3 -gammalatinsmall;0263 -gammasuperior;02E0 -gangiacoptic;03EB -gbopomofo;310D -gbreve;011F -gcaron;01E7 -gcedilla;0123 -gcircle;24D6 -gcircumflex;011D -gcommaaccent;0123 -gdot;0121 -gdotaccent;0121 -gecyrillic;0433 -gehiragana;3052 -gekatakana;30B2 -geometricallyequal;2251 -gereshaccenthebrew;059C -gereshhebrew;05F3 -gereshmuqdamhebrew;059D -germandbls;00DF -gershayimaccenthebrew;059E -gershayimhebrew;05F4 -getamark;3013 -ghabengali;0998 -ghadarmenian;0572 -ghadeva;0918 -ghagujarati;0A98 -ghagurmukhi;0A18 -ghainarabic;063A -ghainfinalarabic;FECE -ghaininitialarabic;FECF -ghainmedialarabic;FED0 -ghemiddlehookcyrillic;0495 -ghestrokecyrillic;0493 -gheupturncyrillic;0491 -ghhadeva;095A -ghhagurmukhi;0A5A -ghook;0260 -ghzsquare;3393 -gihiragana;304E -gikatakana;30AE -gimarmenian;0563 -gimel;05D2 -gimeldagesh;FB32 -gimeldageshhebrew;FB32 -gimelhebrew;05D2 -gjecyrillic;0453 -glottalinvertedstroke;01BE -glottalstop;0294 -glottalstopinverted;0296 -glottalstopmod;02C0 -glottalstopreversed;0295 -glottalstopreversedmod;02C1 -glottalstopreversedsuperior;02E4 -glottalstopstroke;02A1 -glottalstopstrokereversed;02A2 -gmacron;1E21 -gmonospace;FF47 -gohiragana;3054 -gokatakana;30B4 -gparen;24A2 -gpasquare;33AC -gradient;2207 -grave;0060 -gravebelowcmb;0316 -gravecmb;0300 -gravecomb;0300 -gravedeva;0953 -gravelowmod;02CE -gravemonospace;FF40 -gravetonecmb;0340 -greater;003E -greaterequal;2265 -greaterequalorless;22DB -greatermonospace;FF1E -greaterorequivalent;2273 -greaterorless;2277 -greateroverequal;2267 -greatersmall;FE65 -gscript;0261 -gstroke;01E5 -guhiragana;3050 -guillemotleft;00AB -guillemotright;00BB -guilsinglleft;2039 -guilsinglright;203A -gukatakana;30B0 -guramusquare;3318 -gysquare;33C9 -h;0068 -haabkhasiancyrillic;04A9 -haaltonearabic;06C1 -habengali;09B9 -hadescendercyrillic;04B3 -hadeva;0939 -hagujarati;0AB9 -hagurmukhi;0A39 -haharabic;062D -hahfinalarabic;FEA2 -hahinitialarabic;FEA3 -hahiragana;306F -hahmedialarabic;FEA4 -haitusquare;332A -hakatakana;30CF -hakatakanahalfwidth;FF8A -halantgurmukhi;0A4D -hamzaarabic;0621 -hamzadammaarabic;0621 064F -hamzadammatanarabic;0621 064C -hamzafathaarabic;0621 064E -hamzafathatanarabic;0621 064B -hamzalowarabic;0621 -hamzalowkasraarabic;0621 0650 -hamzalowkasratanarabic;0621 064D -hamzasukunarabic;0621 0652 -hangulfiller;3164 -hardsigncyrillic;044A -harpoonleftbarbup;21BC -harpoonrightbarbup;21C0 -hasquare;33CA -hatafpatah;05B2 -hatafpatah16;05B2 -hatafpatah23;05B2 -hatafpatah2f;05B2 -hatafpatahhebrew;05B2 -hatafpatahnarrowhebrew;05B2 -hatafpatahquarterhebrew;05B2 -hatafpatahwidehebrew;05B2 -hatafqamats;05B3 -hatafqamats1b;05B3 -hatafqamats28;05B3 -hatafqamats34;05B3 -hatafqamatshebrew;05B3 -hatafqamatsnarrowhebrew;05B3 -hatafqamatsquarterhebrew;05B3 -hatafqamatswidehebrew;05B3 -hatafsegol;05B1 -hatafsegol17;05B1 -hatafsegol24;05B1 -hatafsegol30;05B1 -hatafsegolhebrew;05B1 -hatafsegolnarrowhebrew;05B1 -hatafsegolquarterhebrew;05B1 -hatafsegolwidehebrew;05B1 -hbar;0127 -hbopomofo;310F -hbrevebelow;1E2B -hcedilla;1E29 -hcircle;24D7 -hcircumflex;0125 -hdieresis;1E27 -hdotaccent;1E23 -hdotbelow;1E25 -he;05D4 -heart;2665 -heartsuitblack;2665 -heartsuitwhite;2661 -hedagesh;FB34 -hedageshhebrew;FB34 -hehaltonearabic;06C1 -heharabic;0647 -hehebrew;05D4 -hehfinalaltonearabic;FBA7 -hehfinalalttwoarabic;FEEA -hehfinalarabic;FEEA -hehhamzaabovefinalarabic;FBA5 -hehhamzaaboveisolatedarabic;FBA4 -hehinitialaltonearabic;FBA8 -hehinitialarabic;FEEB -hehiragana;3078 -hehmedialaltonearabic;FBA9 -hehmedialarabic;FEEC -heiseierasquare;337B -hekatakana;30D8 -hekatakanahalfwidth;FF8D -hekutaarusquare;3336 -henghook;0267 -herutusquare;3339 -het;05D7 -hethebrew;05D7 -hhook;0266 -hhooksuperior;02B1 -hieuhacirclekorean;327B -hieuhaparenkorean;321B -hieuhcirclekorean;326D -hieuhkorean;314E -hieuhparenkorean;320D -hihiragana;3072 -hikatakana;30D2 -hikatakanahalfwidth;FF8B -hiriq;05B4 -hiriq14;05B4 -hiriq21;05B4 -hiriq2d;05B4 -hiriqhebrew;05B4 -hiriqnarrowhebrew;05B4 -hiriqquarterhebrew;05B4 -hiriqwidehebrew;05B4 -hlinebelow;1E96 -hmonospace;FF48 -hoarmenian;0570 -hohipthai;0E2B -hohiragana;307B -hokatakana;30DB -hokatakanahalfwidth;FF8E -holam;05B9 -holam19;05B9 -holam26;05B9 -holam32;05B9 -holamhebrew;05B9 -holamnarrowhebrew;05B9 -holamquarterhebrew;05B9 -holamwidehebrew;05B9 -honokhukthai;0E2E -hookabovecomb;0309 -hookcmb;0309 -hookpalatalizedbelowcmb;0321 -hookretroflexbelowcmb;0322 -hoonsquare;3342 -horicoptic;03E9 -horizontalbar;2015 -horncmb;031B -hotsprings;2668 -house;2302 -hparen;24A3 -hsuperior;02B0 -hturned;0265 -huhiragana;3075 -huiitosquare;3333 -hukatakana;30D5 -hukatakanahalfwidth;FF8C -hungarumlaut;02DD -hungarumlautcmb;030B -hv;0195 -hyphen;002D -hypheninferior;F6E5 -hyphenmonospace;FF0D -hyphensmall;FE63 -hyphensuperior;F6E6 -hyphentwo;2010 -i;0069 -iacute;00ED -iacyrillic;044F -ibengali;0987 -ibopomofo;3127 -ibreve;012D -icaron;01D0 -icircle;24D8 -icircumflex;00EE -icyrillic;0456 -idblgrave;0209 -ideographearthcircle;328F -ideographfirecircle;328B -ideographicallianceparen;323F -ideographiccallparen;323A -ideographiccentrecircle;32A5 -ideographicclose;3006 -ideographiccomma;3001 -ideographiccommaleft;FF64 -ideographiccongratulationparen;3237 -ideographiccorrectcircle;32A3 -ideographicearthparen;322F -ideographicenterpriseparen;323D -ideographicexcellentcircle;329D -ideographicfestivalparen;3240 -ideographicfinancialcircle;3296 -ideographicfinancialparen;3236 -ideographicfireparen;322B -ideographichaveparen;3232 -ideographichighcircle;32A4 -ideographiciterationmark;3005 -ideographiclaborcircle;3298 -ideographiclaborparen;3238 -ideographicleftcircle;32A7 -ideographiclowcircle;32A6 -ideographicmedicinecircle;32A9 -ideographicmetalparen;322E -ideographicmoonparen;322A -ideographicnameparen;3234 -ideographicperiod;3002 -ideographicprintcircle;329E -ideographicreachparen;3243 -ideographicrepresentparen;3239 -ideographicresourceparen;323E -ideographicrightcircle;32A8 -ideographicsecretcircle;3299 -ideographicselfparen;3242 -ideographicsocietyparen;3233 -ideographicspace;3000 -ideographicspecialparen;3235 -ideographicstockparen;3231 -ideographicstudyparen;323B -ideographicsunparen;3230 -ideographicsuperviseparen;323C -ideographicwaterparen;322C -ideographicwoodparen;322D -ideographiczero;3007 -ideographmetalcircle;328E -ideographmooncircle;328A -ideographnamecircle;3294 -ideographsuncircle;3290 -ideographwatercircle;328C -ideographwoodcircle;328D -ideva;0907 -idieresis;00EF -idieresisacute;1E2F -idieresiscyrillic;04E5 -idotbelow;1ECB -iebrevecyrillic;04D7 -iecyrillic;0435 -ieungacirclekorean;3275 -ieungaparenkorean;3215 -ieungcirclekorean;3267 -ieungkorean;3147 -ieungparenkorean;3207 -igrave;00EC -igujarati;0A87 -igurmukhi;0A07 -ihiragana;3044 -ihookabove;1EC9 -iibengali;0988 -iicyrillic;0438 -iideva;0908 -iigujarati;0A88 -iigurmukhi;0A08 -iimatragurmukhi;0A40 -iinvertedbreve;020B -iishortcyrillic;0439 -iivowelsignbengali;09C0 -iivowelsigndeva;0940 -iivowelsigngujarati;0AC0 -ij;0133 -ikatakana;30A4 -ikatakanahalfwidth;FF72 -ikorean;3163 -ilde;02DC -iluyhebrew;05AC -imacron;012B -imacroncyrillic;04E3 -imageorapproximatelyequal;2253 -imatragurmukhi;0A3F -imonospace;FF49 -increment;2206 -infinity;221E -iniarmenian;056B -integral;222B -integralbottom;2321 -integralbt;2321 -integralex;F8F5 -integraltop;2320 -integraltp;2320 -intersection;2229 -intisquare;3305 -invbullet;25D8 -invcircle;25D9 -invsmileface;263B -iocyrillic;0451 -iogonek;012F -iota;03B9 -iotadieresis;03CA -iotadieresistonos;0390 -iotalatin;0269 -iotatonos;03AF -iparen;24A4 -irigurmukhi;0A72 -ismallhiragana;3043 -ismallkatakana;30A3 -ismallkatakanahalfwidth;FF68 -issharbengali;09FA -istroke;0268 -isuperior;F6ED -iterationhiragana;309D -iterationkatakana;30FD -itilde;0129 -itildebelow;1E2D -iubopomofo;3129 -iucyrillic;044E -ivowelsignbengali;09BF -ivowelsigndeva;093F -ivowelsigngujarati;0ABF -izhitsacyrillic;0475 -izhitsadblgravecyrillic;0477 -j;006A -jaarmenian;0571 -jabengali;099C -jadeva;091C -jagujarati;0A9C -jagurmukhi;0A1C -jbopomofo;3110 -jcaron;01F0 -jcircle;24D9 -jcircumflex;0135 -jcrossedtail;029D -jdotlessstroke;025F -jecyrillic;0458 -jeemarabic;062C -jeemfinalarabic;FE9E -jeeminitialarabic;FE9F -jeemmedialarabic;FEA0 -jeharabic;0698 -jehfinalarabic;FB8B -jhabengali;099D -jhadeva;091D -jhagujarati;0A9D -jhagurmukhi;0A1D -jheharmenian;057B -jis;3004 -jmonospace;FF4A -jparen;24A5 -jsuperior;02B2 -k;006B -kabashkircyrillic;04A1 -kabengali;0995 -kacute;1E31 -kacyrillic;043A -kadescendercyrillic;049B -kadeva;0915 -kaf;05DB -kafarabic;0643 -kafdagesh;FB3B -kafdageshhebrew;FB3B -kaffinalarabic;FEDA -kafhebrew;05DB -kafinitialarabic;FEDB -kafmedialarabic;FEDC -kafrafehebrew;FB4D -kagujarati;0A95 -kagurmukhi;0A15 -kahiragana;304B -kahookcyrillic;04C4 -kakatakana;30AB -kakatakanahalfwidth;FF76 -kappa;03BA -kappasymbolgreek;03F0 -kapyeounmieumkorean;3171 -kapyeounphieuphkorean;3184 -kapyeounpieupkorean;3178 -kapyeounssangpieupkorean;3179 -karoriisquare;330D -kashidaautoarabic;0640 -kashidaautonosidebearingarabic;0640 -kasmallkatakana;30F5 -kasquare;3384 -kasraarabic;0650 -kasratanarabic;064D -kastrokecyrillic;049F -katahiraprolongmarkhalfwidth;FF70 -kaverticalstrokecyrillic;049D -kbopomofo;310E -kcalsquare;3389 -kcaron;01E9 -kcedilla;0137 -kcircle;24DA -kcommaaccent;0137 -kdotbelow;1E33 -keharmenian;0584 -kehiragana;3051 -kekatakana;30B1 -kekatakanahalfwidth;FF79 -kenarmenian;056F -kesmallkatakana;30F6 -kgreenlandic;0138 -khabengali;0996 -khacyrillic;0445 -khadeva;0916 -khagujarati;0A96 -khagurmukhi;0A16 -khaharabic;062E -khahfinalarabic;FEA6 -khahinitialarabic;FEA7 -khahmedialarabic;FEA8 -kheicoptic;03E7 -khhadeva;0959 -khhagurmukhi;0A59 -khieukhacirclekorean;3278 -khieukhaparenkorean;3218 -khieukhcirclekorean;326A -khieukhkorean;314B -khieukhparenkorean;320A -khokhaithai;0E02 -khokhonthai;0E05 -khokhuatthai;0E03 -khokhwaithai;0E04 -khomutthai;0E5B -khook;0199 -khorakhangthai;0E06 -khzsquare;3391 -kihiragana;304D -kikatakana;30AD -kikatakanahalfwidth;FF77 -kiroguramusquare;3315 -kiromeetorusquare;3316 -kirosquare;3314 -kiyeokacirclekorean;326E -kiyeokaparenkorean;320E -kiyeokcirclekorean;3260 -kiyeokkorean;3131 -kiyeokparenkorean;3200 -kiyeoksioskorean;3133 -kjecyrillic;045C -klinebelow;1E35 -klsquare;3398 -kmcubedsquare;33A6 -kmonospace;FF4B -kmsquaredsquare;33A2 -kohiragana;3053 -kohmsquare;33C0 -kokaithai;0E01 -kokatakana;30B3 -kokatakanahalfwidth;FF7A -kooposquare;331E -koppacyrillic;0481 -koreanstandardsymbol;327F -koroniscmb;0343 -kparen;24A6 -kpasquare;33AA -ksicyrillic;046F -ktsquare;33CF -kturned;029E -kuhiragana;304F -kukatakana;30AF -kukatakanahalfwidth;FF78 -kvsquare;33B8 -kwsquare;33BE -l;006C -labengali;09B2 -lacute;013A -ladeva;0932 -lagujarati;0AB2 -lagurmukhi;0A32 -lakkhangyaothai;0E45 -lamaleffinalarabic;FEFC -lamalefhamzaabovefinalarabic;FEF8 -lamalefhamzaaboveisolatedarabic;FEF7 -lamalefhamzabelowfinalarabic;FEFA -lamalefhamzabelowisolatedarabic;FEF9 -lamalefisolatedarabic;FEFB -lamalefmaddaabovefinalarabic;FEF6 -lamalefmaddaaboveisolatedarabic;FEF5 -lamarabic;0644 -lambda;03BB -lambdastroke;019B -lamed;05DC -lameddagesh;FB3C -lameddageshhebrew;FB3C -lamedhebrew;05DC -lamedholam;05DC 05B9 -lamedholamdagesh;05DC 05B9 05BC -lamedholamdageshhebrew;05DC 05B9 05BC -lamedholamhebrew;05DC 05B9 -lamfinalarabic;FEDE -lamhahinitialarabic;FCCA -laminitialarabic;FEDF -lamjeeminitialarabic;FCC9 -lamkhahinitialarabic;FCCB -lamlamhehisolatedarabic;FDF2 -lammedialarabic;FEE0 -lammeemhahinitialarabic;FD88 -lammeeminitialarabic;FCCC -lammeemjeeminitialarabic;FEDF FEE4 FEA0 -lammeemkhahinitialarabic;FEDF FEE4 FEA8 -largecircle;25EF -lbar;019A -lbelt;026C -lbopomofo;310C -lcaron;013E -lcedilla;013C -lcircle;24DB -lcircumflexbelow;1E3D -lcommaaccent;013C -ldot;0140 -ldotaccent;0140 -ldotbelow;1E37 -ldotbelowmacron;1E39 -leftangleabovecmb;031A -lefttackbelowcmb;0318 -less;003C -lessequal;2264 -lessequalorgreater;22DA -lessmonospace;FF1C -lessorequivalent;2272 -lessorgreater;2276 -lessoverequal;2266 -lesssmall;FE64 -lezh;026E -lfblock;258C -lhookretroflex;026D -lira;20A4 -liwnarmenian;056C -lj;01C9 -ljecyrillic;0459 -ll;F6C0 -lladeva;0933 -llagujarati;0AB3 -llinebelow;1E3B -llladeva;0934 -llvocalicbengali;09E1 -llvocalicdeva;0961 -llvocalicvowelsignbengali;09E3 -llvocalicvowelsigndeva;0963 -lmiddletilde;026B -lmonospace;FF4C -lmsquare;33D0 -lochulathai;0E2C -logicaland;2227 -logicalnot;00AC -logicalnotreversed;2310 -logicalor;2228 -lolingthai;0E25 -longs;017F -lowlinecenterline;FE4E -lowlinecmb;0332 -lowlinedashed;FE4D -lozenge;25CA -lparen;24A7 -lslash;0142 -lsquare;2113 -lsuperior;F6EE -ltshade;2591 -luthai;0E26 -lvocalicbengali;098C -lvocalicdeva;090C -lvocalicvowelsignbengali;09E2 -lvocalicvowelsigndeva;0962 -lxsquare;33D3 -m;006D -mabengali;09AE -macron;00AF -macronbelowcmb;0331 -macroncmb;0304 -macronlowmod;02CD -macronmonospace;FFE3 -macute;1E3F -madeva;092E -magujarati;0AAE -magurmukhi;0A2E -mahapakhhebrew;05A4 -mahapakhlefthebrew;05A4 -mahiragana;307E -maichattawalowleftthai;F895 -maichattawalowrightthai;F894 -maichattawathai;0E4B -maichattawaupperleftthai;F893 -maieklowleftthai;F88C -maieklowrightthai;F88B -maiekthai;0E48 -maiekupperleftthai;F88A -maihanakatleftthai;F884 -maihanakatthai;0E31 -maitaikhuleftthai;F889 -maitaikhuthai;0E47 -maitholowleftthai;F88F -maitholowrightthai;F88E -maithothai;0E49 -maithoupperleftthai;F88D -maitrilowleftthai;F892 -maitrilowrightthai;F891 -maitrithai;0E4A -maitriupperleftthai;F890 -maiyamokthai;0E46 -makatakana;30DE -makatakanahalfwidth;FF8F -male;2642 -mansyonsquare;3347 -maqafhebrew;05BE -mars;2642 -masoracirclehebrew;05AF -masquare;3383 -mbopomofo;3107 -mbsquare;33D4 -mcircle;24DC -mcubedsquare;33A5 -mdotaccent;1E41 -mdotbelow;1E43 -meemarabic;0645 -meemfinalarabic;FEE2 -meeminitialarabic;FEE3 -meemmedialarabic;FEE4 -meemmeeminitialarabic;FCD1 -meemmeemisolatedarabic;FC48 -meetorusquare;334D -mehiragana;3081 -meizierasquare;337E -mekatakana;30E1 -mekatakanahalfwidth;FF92 -mem;05DE -memdagesh;FB3E -memdageshhebrew;FB3E -memhebrew;05DE -menarmenian;0574 -merkhahebrew;05A5 -merkhakefulahebrew;05A6 -merkhakefulalefthebrew;05A6 -merkhalefthebrew;05A5 -mhook;0271 -mhzsquare;3392 -middledotkatakanahalfwidth;FF65 -middot;00B7 -mieumacirclekorean;3272 -mieumaparenkorean;3212 -mieumcirclekorean;3264 -mieumkorean;3141 -mieumpansioskorean;3170 -mieumparenkorean;3204 -mieumpieupkorean;316E -mieumsioskorean;316F -mihiragana;307F -mikatakana;30DF -mikatakanahalfwidth;FF90 -minus;2212 -minusbelowcmb;0320 -minuscircle;2296 -minusmod;02D7 -minusplus;2213 -minute;2032 -miribaarusquare;334A -mirisquare;3349 -mlonglegturned;0270 -mlsquare;3396 -mmcubedsquare;33A3 -mmonospace;FF4D -mmsquaredsquare;339F -mohiragana;3082 -mohmsquare;33C1 -mokatakana;30E2 -mokatakanahalfwidth;FF93 -molsquare;33D6 -momathai;0E21 -moverssquare;33A7 -moverssquaredsquare;33A8 -mparen;24A8 -mpasquare;33AB -mssquare;33B3 -msuperior;F6EF -mturned;026F -mu;00B5 -mu1;00B5 -muasquare;3382 -muchgreater;226B -muchless;226A -mufsquare;338C -mugreek;03BC -mugsquare;338D -muhiragana;3080 -mukatakana;30E0 -mukatakanahalfwidth;FF91 -mulsquare;3395 -multiply;00D7 -mumsquare;339B -munahhebrew;05A3 -munahlefthebrew;05A3 -musicalnote;266A -musicalnotedbl;266B -musicflatsign;266D -musicsharpsign;266F -mussquare;33B2 -muvsquare;33B6 -muwsquare;33BC -mvmegasquare;33B9 -mvsquare;33B7 -mwmegasquare;33BF -mwsquare;33BD -n;006E -nabengali;09A8 -nabla;2207 -nacute;0144 -nadeva;0928 -nagujarati;0AA8 -nagurmukhi;0A28 -nahiragana;306A -nakatakana;30CA -nakatakanahalfwidth;FF85 -napostrophe;0149 -nasquare;3381 -nbopomofo;310B -nbspace;00A0 -ncaron;0148 -ncedilla;0146 -ncircle;24DD -ncircumflexbelow;1E4B -ncommaaccent;0146 -ndotaccent;1E45 -ndotbelow;1E47 -nehiragana;306D -nekatakana;30CD -nekatakanahalfwidth;FF88 -newsheqelsign;20AA -nfsquare;338B -ngabengali;0999 -ngadeva;0919 -ngagujarati;0A99 -ngagurmukhi;0A19 -ngonguthai;0E07 -nhiragana;3093 -nhookleft;0272 -nhookretroflex;0273 -nieunacirclekorean;326F -nieunaparenkorean;320F -nieuncieuckorean;3135 -nieuncirclekorean;3261 -nieunhieuhkorean;3136 -nieunkorean;3134 -nieunpansioskorean;3168 -nieunparenkorean;3201 -nieunsioskorean;3167 -nieuntikeutkorean;3166 -nihiragana;306B -nikatakana;30CB -nikatakanahalfwidth;FF86 -nikhahitleftthai;F899 -nikhahitthai;0E4D -nine;0039 -ninearabic;0669 -ninebengali;09EF -ninecircle;2468 -ninecircleinversesansserif;2792 -ninedeva;096F -ninegujarati;0AEF -ninegurmukhi;0A6F -ninehackarabic;0669 -ninehangzhou;3029 -nineideographicparen;3228 -nineinferior;2089 -ninemonospace;FF19 -nineoldstyle;F739 -nineparen;247C -nineperiod;2490 -ninepersian;06F9 -nineroman;2178 -ninesuperior;2079 -nineteencircle;2472 -nineteenparen;2486 -nineteenperiod;249A -ninethai;0E59 -nj;01CC -njecyrillic;045A -nkatakana;30F3 -nkatakanahalfwidth;FF9D -nlegrightlong;019E -nlinebelow;1E49 -nmonospace;FF4E -nmsquare;339A -nnabengali;09A3 -nnadeva;0923 -nnagujarati;0AA3 -nnagurmukhi;0A23 -nnnadeva;0929 -nohiragana;306E -nokatakana;30CE -nokatakanahalfwidth;FF89 -nonbreakingspace;00A0 -nonenthai;0E13 -nonuthai;0E19 -noonarabic;0646 -noonfinalarabic;FEE6 -noonghunnaarabic;06BA -noonghunnafinalarabic;FB9F -noonhehinitialarabic;FEE7 FEEC -nooninitialarabic;FEE7 -noonjeeminitialarabic;FCD2 -noonjeemisolatedarabic;FC4B -noonmedialarabic;FEE8 -noonmeeminitialarabic;FCD5 -noonmeemisolatedarabic;FC4E -noonnoonfinalarabic;FC8D -notcontains;220C -notelement;2209 -notelementof;2209 -notequal;2260 -notgreater;226F -notgreaternorequal;2271 -notgreaternorless;2279 -notidentical;2262 -notless;226E -notlessnorequal;2270 -notparallel;2226 -notprecedes;2280 -notsubset;2284 -notsucceeds;2281 -notsuperset;2285 -nowarmenian;0576 -nparen;24A9 -nssquare;33B1 -nsuperior;207F -ntilde;00F1 -nu;03BD -nuhiragana;306C -nukatakana;30CC -nukatakanahalfwidth;FF87 -nuktabengali;09BC -nuktadeva;093C -nuktagujarati;0ABC -nuktagurmukhi;0A3C -numbersign;0023 -numbersignmonospace;FF03 -numbersignsmall;FE5F -numeralsigngreek;0374 -numeralsignlowergreek;0375 -numero;2116 -nun;05E0 -nundagesh;FB40 -nundageshhebrew;FB40 -nunhebrew;05E0 -nvsquare;33B5 -nwsquare;33BB -nyabengali;099E -nyadeva;091E -nyagujarati;0A9E -nyagurmukhi;0A1E -o;006F -oacute;00F3 -oangthai;0E2D -obarred;0275 -obarredcyrillic;04E9 -obarreddieresiscyrillic;04EB -obengali;0993 -obopomofo;311B -obreve;014F -ocandradeva;0911 -ocandragujarati;0A91 -ocandravowelsigndeva;0949 -ocandravowelsigngujarati;0AC9 -ocaron;01D2 -ocircle;24DE -ocircumflex;00F4 -ocircumflexacute;1ED1 -ocircumflexdotbelow;1ED9 -ocircumflexgrave;1ED3 -ocircumflexhookabove;1ED5 -ocircumflextilde;1ED7 -ocyrillic;043E -odblacute;0151 -odblgrave;020D -odeva;0913 -odieresis;00F6 -odieresiscyrillic;04E7 -odotbelow;1ECD -oe;0153 -oekorean;315A -ogonek;02DB -ogonekcmb;0328 -ograve;00F2 -ogujarati;0A93 -oharmenian;0585 -ohiragana;304A -ohookabove;1ECF -ohorn;01A1 -ohornacute;1EDB -ohorndotbelow;1EE3 -ohorngrave;1EDD -ohornhookabove;1EDF -ohorntilde;1EE1 -ohungarumlaut;0151 -oi;01A3 -oinvertedbreve;020F -okatakana;30AA -okatakanahalfwidth;FF75 -okorean;3157 -olehebrew;05AB -omacron;014D -omacronacute;1E53 -omacrongrave;1E51 -omdeva;0950 -omega;03C9 -omega1;03D6 -omegacyrillic;0461 -omegalatinclosed;0277 -omegaroundcyrillic;047B -omegatitlocyrillic;047D -omegatonos;03CE -omgujarati;0AD0 -omicron;03BF -omicrontonos;03CC -omonospace;FF4F -one;0031 -onearabic;0661 -onebengali;09E7 -onecircle;2460 -onecircleinversesansserif;278A -onedeva;0967 -onedotenleader;2024 -oneeighth;215B -onefitted;F6DC -onegujarati;0AE7 -onegurmukhi;0A67 -onehackarabic;0661 -onehalf;00BD -onehangzhou;3021 -oneideographicparen;3220 -oneinferior;2081 -onemonospace;FF11 -onenumeratorbengali;09F4 -oneoldstyle;F731 -oneparen;2474 -oneperiod;2488 -onepersian;06F1 -onequarter;00BC -oneroman;2170 -onesuperior;00B9 -onethai;0E51 -onethird;2153 -oogonek;01EB -oogonekmacron;01ED -oogurmukhi;0A13 -oomatragurmukhi;0A4B -oopen;0254 -oparen;24AA -openbullet;25E6 -option;2325 -ordfeminine;00AA -ordmasculine;00BA -orthogonal;221F -oshortdeva;0912 -oshortvowelsigndeva;094A -oslash;00F8 -oslashacute;01FF -osmallhiragana;3049 -osmallkatakana;30A9 -osmallkatakanahalfwidth;FF6B -ostrokeacute;01FF -osuperior;F6F0 -otcyrillic;047F -otilde;00F5 -otildeacute;1E4D -otildedieresis;1E4F -oubopomofo;3121 -overline;203E -overlinecenterline;FE4A -overlinecmb;0305 -overlinedashed;FE49 -overlinedblwavy;FE4C -overlinewavy;FE4B -overscore;00AF -ovowelsignbengali;09CB -ovowelsigndeva;094B -ovowelsigngujarati;0ACB -p;0070 -paampssquare;3380 -paasentosquare;332B -pabengali;09AA -pacute;1E55 -padeva;092A -pagedown;21DF -pageup;21DE -pagujarati;0AAA -pagurmukhi;0A2A -pahiragana;3071 -paiyannoithai;0E2F -pakatakana;30D1 -palatalizationcyrilliccmb;0484 -palochkacyrillic;04C0 -pansioskorean;317F -paragraph;00B6 -parallel;2225 -parenleft;0028 -parenleftaltonearabic;FD3E -parenleftbt;F8ED -parenleftex;F8EC -parenleftinferior;208D -parenleftmonospace;FF08 -parenleftsmall;FE59 -parenleftsuperior;207D -parenlefttp;F8EB -parenleftvertical;FE35 -parenright;0029 -parenrightaltonearabic;FD3F -parenrightbt;F8F8 -parenrightex;F8F7 -parenrightinferior;208E -parenrightmonospace;FF09 -parenrightsmall;FE5A -parenrightsuperior;207E -parenrighttp;F8F6 -parenrightvertical;FE36 -partialdiff;2202 -paseqhebrew;05C0 -pashtahebrew;0599 -pasquare;33A9 -patah;05B7 -patah11;05B7 -patah1d;05B7 -patah2a;05B7 -patahhebrew;05B7 -patahnarrowhebrew;05B7 -patahquarterhebrew;05B7 -patahwidehebrew;05B7 -pazerhebrew;05A1 -pbopomofo;3106 -pcircle;24DF -pdotaccent;1E57 -pe;05E4 -pecyrillic;043F -pedagesh;FB44 -pedageshhebrew;FB44 -peezisquare;333B -pefinaldageshhebrew;FB43 -peharabic;067E -peharmenian;057A -pehebrew;05E4 -pehfinalarabic;FB57 -pehinitialarabic;FB58 -pehiragana;307A -pehmedialarabic;FB59 -pekatakana;30DA -pemiddlehookcyrillic;04A7 -perafehebrew;FB4E -percent;0025 -percentarabic;066A -percentmonospace;FF05 -percentsmall;FE6A -period;002E -periodarmenian;0589 -periodcentered;00B7 -periodhalfwidth;FF61 -periodinferior;F6E7 -periodmonospace;FF0E -periodsmall;FE52 -periodsuperior;F6E8 -perispomenigreekcmb;0342 -perpendicular;22A5 -perthousand;2030 -peseta;20A7 -pfsquare;338A -phabengali;09AB -phadeva;092B -phagujarati;0AAB -phagurmukhi;0A2B -phi;03C6 -phi1;03D5 -phieuphacirclekorean;327A -phieuphaparenkorean;321A -phieuphcirclekorean;326C -phieuphkorean;314D -phieuphparenkorean;320C -philatin;0278 -phinthuthai;0E3A -phisymbolgreek;03D5 -phook;01A5 -phophanthai;0E1E -phophungthai;0E1C -phosamphaothai;0E20 -pi;03C0 -pieupacirclekorean;3273 -pieupaparenkorean;3213 -pieupcieuckorean;3176 -pieupcirclekorean;3265 -pieupkiyeokkorean;3172 -pieupkorean;3142 -pieupparenkorean;3205 -pieupsioskiyeokkorean;3174 -pieupsioskorean;3144 -pieupsiostikeutkorean;3175 -pieupthieuthkorean;3177 -pieuptikeutkorean;3173 -pihiragana;3074 -pikatakana;30D4 -pisymbolgreek;03D6 -piwrarmenian;0583 -plus;002B -plusbelowcmb;031F -pluscircle;2295 -plusminus;00B1 -plusmod;02D6 -plusmonospace;FF0B -plussmall;FE62 -plussuperior;207A -pmonospace;FF50 -pmsquare;33D8 -pohiragana;307D -pointingindexdownwhite;261F -pointingindexleftwhite;261C -pointingindexrightwhite;261E -pointingindexupwhite;261D -pokatakana;30DD -poplathai;0E1B -postalmark;3012 -postalmarkface;3020 -pparen;24AB -precedes;227A -prescription;211E -primemod;02B9 -primereversed;2035 -product;220F -projective;2305 -prolongedkana;30FC -propellor;2318 -propersubset;2282 -propersuperset;2283 -proportion;2237 -proportional;221D -psi;03C8 -psicyrillic;0471 -psilipneumatacyrilliccmb;0486 -pssquare;33B0 -puhiragana;3077 -pukatakana;30D7 -pvsquare;33B4 -pwsquare;33BA -q;0071 -qadeva;0958 -qadmahebrew;05A8 -qafarabic;0642 -qaffinalarabic;FED6 -qafinitialarabic;FED7 -qafmedialarabic;FED8 -qamats;05B8 -qamats10;05B8 -qamats1a;05B8 -qamats1c;05B8 -qamats27;05B8 -qamats29;05B8 -qamats33;05B8 -qamatsde;05B8 -qamatshebrew;05B8 -qamatsnarrowhebrew;05B8 -qamatsqatanhebrew;05B8 -qamatsqatannarrowhebrew;05B8 -qamatsqatanquarterhebrew;05B8 -qamatsqatanwidehebrew;05B8 -qamatsquarterhebrew;05B8 -qamatswidehebrew;05B8 -qarneyparahebrew;059F -qbopomofo;3111 -qcircle;24E0 -qhook;02A0 -qmonospace;FF51 -qof;05E7 -qofdagesh;FB47 -qofdageshhebrew;FB47 -qofhatafpatah;05E7 05B2 -qofhatafpatahhebrew;05E7 05B2 -qofhatafsegol;05E7 05B1 -qofhatafsegolhebrew;05E7 05B1 -qofhebrew;05E7 -qofhiriq;05E7 05B4 -qofhiriqhebrew;05E7 05B4 -qofholam;05E7 05B9 -qofholamhebrew;05E7 05B9 -qofpatah;05E7 05B7 -qofpatahhebrew;05E7 05B7 -qofqamats;05E7 05B8 -qofqamatshebrew;05E7 05B8 -qofqubuts;05E7 05BB -qofqubutshebrew;05E7 05BB -qofsegol;05E7 05B6 -qofsegolhebrew;05E7 05B6 -qofsheva;05E7 05B0 -qofshevahebrew;05E7 05B0 -qoftsere;05E7 05B5 -qoftserehebrew;05E7 05B5 -qparen;24AC -quarternote;2669 -qubuts;05BB -qubuts18;05BB -qubuts25;05BB -qubuts31;05BB -qubutshebrew;05BB -qubutsnarrowhebrew;05BB -qubutsquarterhebrew;05BB -qubutswidehebrew;05BB -question;003F -questionarabic;061F -questionarmenian;055E -questiondown;00BF -questiondownsmall;F7BF -questiongreek;037E -questionmonospace;FF1F -questionsmall;F73F -quotedbl;0022 -quotedblbase;201E -quotedblleft;201C -quotedblmonospace;FF02 -quotedblprime;301E -quotedblprimereversed;301D -quotedblright;201D -quoteleft;2018 -quoteleftreversed;201B -quotereversed;201B -quoteright;2019 -quoterightn;0149 -quotesinglbase;201A -quotesingle;0027 -quotesinglemonospace;FF07 -r;0072 -raarmenian;057C -rabengali;09B0 -racute;0155 -radeva;0930 -radical;221A -radicalex;F8E5 -radoverssquare;33AE -radoverssquaredsquare;33AF -radsquare;33AD -rafe;05BF -rafehebrew;05BF -ragujarati;0AB0 -ragurmukhi;0A30 -rahiragana;3089 -rakatakana;30E9 -rakatakanahalfwidth;FF97 -ralowerdiagonalbengali;09F1 -ramiddlediagonalbengali;09F0 -ramshorn;0264 -ratio;2236 -rbopomofo;3116 -rcaron;0159 -rcedilla;0157 -rcircle;24E1 -rcommaaccent;0157 -rdblgrave;0211 -rdotaccent;1E59 -rdotbelow;1E5B -rdotbelowmacron;1E5D -referencemark;203B -reflexsubset;2286 -reflexsuperset;2287 -registered;00AE -registersans;F8E8 -registerserif;F6DA -reharabic;0631 -reharmenian;0580 -rehfinalarabic;FEAE -rehiragana;308C -rehyehaleflamarabic;0631 FEF3 FE8E 0644 -rekatakana;30EC -rekatakanahalfwidth;FF9A -resh;05E8 -reshdageshhebrew;FB48 -reshhatafpatah;05E8 05B2 -reshhatafpatahhebrew;05E8 05B2 -reshhatafsegol;05E8 05B1 -reshhatafsegolhebrew;05E8 05B1 -reshhebrew;05E8 -reshhiriq;05E8 05B4 -reshhiriqhebrew;05E8 05B4 -reshholam;05E8 05B9 -reshholamhebrew;05E8 05B9 -reshpatah;05E8 05B7 -reshpatahhebrew;05E8 05B7 -reshqamats;05E8 05B8 -reshqamatshebrew;05E8 05B8 -reshqubuts;05E8 05BB -reshqubutshebrew;05E8 05BB -reshsegol;05E8 05B6 -reshsegolhebrew;05E8 05B6 -reshsheva;05E8 05B0 -reshshevahebrew;05E8 05B0 -reshtsere;05E8 05B5 -reshtserehebrew;05E8 05B5 -reversedtilde;223D -reviahebrew;0597 -reviamugrashhebrew;0597 -revlogicalnot;2310 -rfishhook;027E -rfishhookreversed;027F -rhabengali;09DD -rhadeva;095D -rho;03C1 -rhook;027D -rhookturned;027B -rhookturnedsuperior;02B5 -rhosymbolgreek;03F1 -rhotichookmod;02DE -rieulacirclekorean;3271 -rieulaparenkorean;3211 -rieulcirclekorean;3263 -rieulhieuhkorean;3140 -rieulkiyeokkorean;313A -rieulkiyeoksioskorean;3169 -rieulkorean;3139 -rieulmieumkorean;313B -rieulpansioskorean;316C -rieulparenkorean;3203 -rieulphieuphkorean;313F -rieulpieupkorean;313C -rieulpieupsioskorean;316B -rieulsioskorean;313D -rieulthieuthkorean;313E -rieultikeutkorean;316A -rieulyeorinhieuhkorean;316D -rightangle;221F -righttackbelowcmb;0319 -righttriangle;22BF -rihiragana;308A -rikatakana;30EA -rikatakanahalfwidth;FF98 -ring;02DA -ringbelowcmb;0325 -ringcmb;030A -ringhalfleft;02BF -ringhalfleftarmenian;0559 -ringhalfleftbelowcmb;031C -ringhalfleftcentered;02D3 -ringhalfright;02BE -ringhalfrightbelowcmb;0339 -ringhalfrightcentered;02D2 -rinvertedbreve;0213 -rittorusquare;3351 -rlinebelow;1E5F -rlongleg;027C -rlonglegturned;027A -rmonospace;FF52 -rohiragana;308D -rokatakana;30ED -rokatakanahalfwidth;FF9B -roruathai;0E23 -rparen;24AD -rrabengali;09DC -rradeva;0931 -rragurmukhi;0A5C -rreharabic;0691 -rrehfinalarabic;FB8D -rrvocalicbengali;09E0 -rrvocalicdeva;0960 -rrvocalicgujarati;0AE0 -rrvocalicvowelsignbengali;09C4 -rrvocalicvowelsigndeva;0944 -rrvocalicvowelsigngujarati;0AC4 -rsuperior;F6F1 -rtblock;2590 -rturned;0279 -rturnedsuperior;02B4 -ruhiragana;308B -rukatakana;30EB -rukatakanahalfwidth;FF99 -rupeemarkbengali;09F2 -rupeesignbengali;09F3 -rupiah;F6DD -ruthai;0E24 -rvocalicbengali;098B -rvocalicdeva;090B -rvocalicgujarati;0A8B -rvocalicvowelsignbengali;09C3 -rvocalicvowelsigndeva;0943 -rvocalicvowelsigngujarati;0AC3 -s;0073 -sabengali;09B8 -sacute;015B -sacutedotaccent;1E65 -sadarabic;0635 -sadeva;0938 -sadfinalarabic;FEBA -sadinitialarabic;FEBB -sadmedialarabic;FEBC -sagujarati;0AB8 -sagurmukhi;0A38 -sahiragana;3055 -sakatakana;30B5 -sakatakanahalfwidth;FF7B -sallallahoualayhewasallamarabic;FDFA -samekh;05E1 -samekhdagesh;FB41 -samekhdageshhebrew;FB41 -samekhhebrew;05E1 -saraaathai;0E32 -saraaethai;0E41 -saraaimaimalaithai;0E44 -saraaimaimuanthai;0E43 -saraamthai;0E33 -saraathai;0E30 -saraethai;0E40 -saraiileftthai;F886 -saraiithai;0E35 -saraileftthai;F885 -saraithai;0E34 -saraothai;0E42 -saraueeleftthai;F888 -saraueethai;0E37 -saraueleftthai;F887 -sarauethai;0E36 -sarauthai;0E38 -sarauuthai;0E39 -sbopomofo;3119 -scaron;0161 -scarondotaccent;1E67 -scedilla;015F -schwa;0259 -schwacyrillic;04D9 -schwadieresiscyrillic;04DB -schwahook;025A -scircle;24E2 -scircumflex;015D -scommaaccent;0219 -sdotaccent;1E61 -sdotbelow;1E63 -sdotbelowdotaccent;1E69 -seagullbelowcmb;033C -second;2033 -secondtonechinese;02CA -section;00A7 -seenarabic;0633 -seenfinalarabic;FEB2 -seeninitialarabic;FEB3 -seenmedialarabic;FEB4 -segol;05B6 -segol13;05B6 -segol1f;05B6 -segol2c;05B6 -segolhebrew;05B6 -segolnarrowhebrew;05B6 -segolquarterhebrew;05B6 -segoltahebrew;0592 -segolwidehebrew;05B6 -seharmenian;057D -sehiragana;305B -sekatakana;30BB -sekatakanahalfwidth;FF7E -semicolon;003B -semicolonarabic;061B -semicolonmonospace;FF1B -semicolonsmall;FE54 -semivoicedmarkkana;309C -semivoicedmarkkanahalfwidth;FF9F -sentisquare;3322 -sentosquare;3323 -seven;0037 -sevenarabic;0667 -sevenbengali;09ED -sevencircle;2466 -sevencircleinversesansserif;2790 -sevendeva;096D -seveneighths;215E -sevengujarati;0AED -sevengurmukhi;0A6D -sevenhackarabic;0667 -sevenhangzhou;3027 -sevenideographicparen;3226 -seveninferior;2087 -sevenmonospace;FF17 -sevenoldstyle;F737 -sevenparen;247A -sevenperiod;248E -sevenpersian;06F7 -sevenroman;2176 -sevensuperior;2077 -seventeencircle;2470 -seventeenparen;2484 -seventeenperiod;2498 -seventhai;0E57 -sfthyphen;00AD -shaarmenian;0577 -shabengali;09B6 -shacyrillic;0448 -shaddaarabic;0651 -shaddadammaarabic;FC61 -shaddadammatanarabic;FC5E -shaddafathaarabic;FC60 -shaddafathatanarabic;0651 064B -shaddakasraarabic;FC62 -shaddakasratanarabic;FC5F -shade;2592 -shadedark;2593 -shadelight;2591 -shademedium;2592 -shadeva;0936 -shagujarati;0AB6 -shagurmukhi;0A36 -shalshelethebrew;0593 -shbopomofo;3115 -shchacyrillic;0449 -sheenarabic;0634 -sheenfinalarabic;FEB6 -sheeninitialarabic;FEB7 -sheenmedialarabic;FEB8 -sheicoptic;03E3 -sheqel;20AA -sheqelhebrew;20AA -sheva;05B0 -sheva115;05B0 -sheva15;05B0 -sheva22;05B0 -sheva2e;05B0 -shevahebrew;05B0 -shevanarrowhebrew;05B0 -shevaquarterhebrew;05B0 -shevawidehebrew;05B0 -shhacyrillic;04BB -shimacoptic;03ED -shin;05E9 -shindagesh;FB49 -shindageshhebrew;FB49 -shindageshshindot;FB2C -shindageshshindothebrew;FB2C -shindageshsindot;FB2D -shindageshsindothebrew;FB2D -shindothebrew;05C1 -shinhebrew;05E9 -shinshindot;FB2A -shinshindothebrew;FB2A -shinsindot;FB2B -shinsindothebrew;FB2B -shook;0282 -sigma;03C3 -sigma1;03C2 -sigmafinal;03C2 -sigmalunatesymbolgreek;03F2 -sihiragana;3057 -sikatakana;30B7 -sikatakanahalfwidth;FF7C -siluqhebrew;05BD -siluqlefthebrew;05BD -similar;223C -sindothebrew;05C2 -siosacirclekorean;3274 -siosaparenkorean;3214 -sioscieuckorean;317E -sioscirclekorean;3266 -sioskiyeokkorean;317A -sioskorean;3145 -siosnieunkorean;317B -siosparenkorean;3206 -siospieupkorean;317D -siostikeutkorean;317C -six;0036 -sixarabic;0666 -sixbengali;09EC -sixcircle;2465 -sixcircleinversesansserif;278F -sixdeva;096C -sixgujarati;0AEC -sixgurmukhi;0A6C -sixhackarabic;0666 -sixhangzhou;3026 -sixideographicparen;3225 -sixinferior;2086 -sixmonospace;FF16 -sixoldstyle;F736 -sixparen;2479 -sixperiod;248D -sixpersian;06F6 -sixroman;2175 -sixsuperior;2076 -sixteencircle;246F -sixteencurrencydenominatorbengali;09F9 -sixteenparen;2483 -sixteenperiod;2497 -sixthai;0E56 -slash;002F -slashmonospace;FF0F -slong;017F -slongdotaccent;1E9B -smileface;263A -smonospace;FF53 -sofpasuqhebrew;05C3 -softhyphen;00AD -softsigncyrillic;044C -sohiragana;305D -sokatakana;30BD -sokatakanahalfwidth;FF7F -soliduslongoverlaycmb;0338 -solidusshortoverlaycmb;0337 -sorusithai;0E29 -sosalathai;0E28 -sosothai;0E0B -sosuathai;0E2A -space;0020 -spacehackarabic;0020 -spade;2660 -spadesuitblack;2660 -spadesuitwhite;2664 -sparen;24AE -squarebelowcmb;033B -squarecc;33C4 -squarecm;339D -squarediagonalcrosshatchfill;25A9 -squarehorizontalfill;25A4 -squarekg;338F -squarekm;339E -squarekmcapital;33CE -squareln;33D1 -squarelog;33D2 -squaremg;338E -squaremil;33D5 -squaremm;339C -squaremsquared;33A1 -squareorthogonalcrosshatchfill;25A6 -squareupperlefttolowerrightfill;25A7 -squareupperrighttolowerleftfill;25A8 -squareverticalfill;25A5 -squarewhitewithsmallblack;25A3 -srsquare;33DB -ssabengali;09B7 -ssadeva;0937 -ssagujarati;0AB7 -ssangcieuckorean;3149 -ssanghieuhkorean;3185 -ssangieungkorean;3180 -ssangkiyeokkorean;3132 -ssangnieunkorean;3165 -ssangpieupkorean;3143 -ssangsioskorean;3146 -ssangtikeutkorean;3138 -ssuperior;F6F2 -sterling;00A3 -sterlingmonospace;FFE1 -strokelongoverlaycmb;0336 -strokeshortoverlaycmb;0335 -subset;2282 -subsetnotequal;228A -subsetorequal;2286 -succeeds;227B -suchthat;220B -suhiragana;3059 -sukatakana;30B9 -sukatakanahalfwidth;FF7D -sukunarabic;0652 -summation;2211 -sun;263C -superset;2283 -supersetnotequal;228B -supersetorequal;2287 -svsquare;33DC -syouwaerasquare;337C -t;0074 -tabengali;09A4 -tackdown;22A4 -tackleft;22A3 -tadeva;0924 -tagujarati;0AA4 -tagurmukhi;0A24 -taharabic;0637 -tahfinalarabic;FEC2 -tahinitialarabic;FEC3 -tahiragana;305F -tahmedialarabic;FEC4 -taisyouerasquare;337D -takatakana;30BF -takatakanahalfwidth;FF80 -tatweelarabic;0640 -tau;03C4 -tav;05EA -tavdages;FB4A -tavdagesh;FB4A -tavdageshhebrew;FB4A -tavhebrew;05EA -tbar;0167 -tbopomofo;310A -tcaron;0165 -tccurl;02A8 -tcedilla;0163 -tcheharabic;0686 -tchehfinalarabic;FB7B -tchehinitialarabic;FB7C -tchehmedialarabic;FB7D -tchehmeeminitialarabic;FB7C FEE4 -tcircle;24E3 -tcircumflexbelow;1E71 -tcommaaccent;0163 -tdieresis;1E97 -tdotaccent;1E6B -tdotbelow;1E6D -tecyrillic;0442 -tedescendercyrillic;04AD -teharabic;062A -tehfinalarabic;FE96 -tehhahinitialarabic;FCA2 -tehhahisolatedarabic;FC0C -tehinitialarabic;FE97 -tehiragana;3066 -tehjeeminitialarabic;FCA1 -tehjeemisolatedarabic;FC0B -tehmarbutaarabic;0629 -tehmarbutafinalarabic;FE94 -tehmedialarabic;FE98 -tehmeeminitialarabic;FCA4 -tehmeemisolatedarabic;FC0E -tehnoonfinalarabic;FC73 -tekatakana;30C6 -tekatakanahalfwidth;FF83 -telephone;2121 -telephoneblack;260E -telishagedolahebrew;05A0 -telishaqetanahebrew;05A9 -tencircle;2469 -tenideographicparen;3229 -tenparen;247D -tenperiod;2491 -tenroman;2179 -tesh;02A7 -tet;05D8 -tetdagesh;FB38 -tetdageshhebrew;FB38 -tethebrew;05D8 -tetsecyrillic;04B5 -tevirhebrew;059B -tevirlefthebrew;059B -thabengali;09A5 -thadeva;0925 -thagujarati;0AA5 -thagurmukhi;0A25 -thalarabic;0630 -thalfinalarabic;FEAC -thanthakhatlowleftthai;F898 -thanthakhatlowrightthai;F897 -thanthakhatthai;0E4C -thanthakhatupperleftthai;F896 -theharabic;062B -thehfinalarabic;FE9A -thehinitialarabic;FE9B -thehmedialarabic;FE9C -thereexists;2203 -therefore;2234 -theta;03B8 -theta1;03D1 -thetasymbolgreek;03D1 -thieuthacirclekorean;3279 -thieuthaparenkorean;3219 -thieuthcirclekorean;326B -thieuthkorean;314C -thieuthparenkorean;320B -thirteencircle;246C -thirteenparen;2480 -thirteenperiod;2494 -thonangmonthothai;0E11 -thook;01AD -thophuthaothai;0E12 -thorn;00FE -thothahanthai;0E17 -thothanthai;0E10 -thothongthai;0E18 -thothungthai;0E16 -thousandcyrillic;0482 -thousandsseparatorarabic;066C -thousandsseparatorpersian;066C -three;0033 -threearabic;0663 -threebengali;09E9 -threecircle;2462 -threecircleinversesansserif;278C -threedeva;0969 -threeeighths;215C -threegujarati;0AE9 -threegurmukhi;0A69 -threehackarabic;0663 -threehangzhou;3023 -threeideographicparen;3222 -threeinferior;2083 -threemonospace;FF13 -threenumeratorbengali;09F6 -threeoldstyle;F733 -threeparen;2476 -threeperiod;248A -threepersian;06F3 -threequarters;00BE -threequartersemdash;F6DE -threeroman;2172 -threesuperior;00B3 -threethai;0E53 -thzsquare;3394 -tihiragana;3061 -tikatakana;30C1 -tikatakanahalfwidth;FF81 -tikeutacirclekorean;3270 -tikeutaparenkorean;3210 -tikeutcirclekorean;3262 -tikeutkorean;3137 -tikeutparenkorean;3202 -tilde;02DC -tildebelowcmb;0330 -tildecmb;0303 -tildecomb;0303 -tildedoublecmb;0360 -tildeoperator;223C -tildeoverlaycmb;0334 -tildeverticalcmb;033E -timescircle;2297 -tipehahebrew;0596 -tipehalefthebrew;0596 -tippigurmukhi;0A70 -titlocyrilliccmb;0483 -tiwnarmenian;057F -tlinebelow;1E6F -tmonospace;FF54 -toarmenian;0569 -tohiragana;3068 -tokatakana;30C8 -tokatakanahalfwidth;FF84 -tonebarextrahighmod;02E5 -tonebarextralowmod;02E9 -tonebarhighmod;02E6 -tonebarlowmod;02E8 -tonebarmidmod;02E7 -tonefive;01BD -tonesix;0185 -tonetwo;01A8 -tonos;0384 -tonsquare;3327 -topatakthai;0E0F -tortoiseshellbracketleft;3014 -tortoiseshellbracketleftsmall;FE5D -tortoiseshellbracketleftvertical;FE39 -tortoiseshellbracketright;3015 -tortoiseshellbracketrightsmall;FE5E -tortoiseshellbracketrightvertical;FE3A -totaothai;0E15 -tpalatalhook;01AB -tparen;24AF -trademark;2122 -trademarksans;F8EA -trademarkserif;F6DB -tretroflexhook;0288 -triagdn;25BC -triaglf;25C4 -triagrt;25BA -triagup;25B2 -ts;02A6 -tsadi;05E6 -tsadidagesh;FB46 -tsadidageshhebrew;FB46 -tsadihebrew;05E6 -tsecyrillic;0446 -tsere;05B5 -tsere12;05B5 -tsere1e;05B5 -tsere2b;05B5 -tserehebrew;05B5 -tserenarrowhebrew;05B5 -tserequarterhebrew;05B5 -tserewidehebrew;05B5 -tshecyrillic;045B -tsuperior;F6F3 -ttabengali;099F -ttadeva;091F -ttagujarati;0A9F -ttagurmukhi;0A1F -tteharabic;0679 -ttehfinalarabic;FB67 -ttehinitialarabic;FB68 -ttehmedialarabic;FB69 -tthabengali;09A0 -tthadeva;0920 -tthagujarati;0AA0 -tthagurmukhi;0A20 -tturned;0287 -tuhiragana;3064 -tukatakana;30C4 -tukatakanahalfwidth;FF82 -tusmallhiragana;3063 -tusmallkatakana;30C3 -tusmallkatakanahalfwidth;FF6F -twelvecircle;246B -twelveparen;247F -twelveperiod;2493 -twelveroman;217B -twentycircle;2473 -twentyhangzhou;5344 -twentyparen;2487 -twentyperiod;249B -two;0032 -twoarabic;0662 -twobengali;09E8 -twocircle;2461 -twocircleinversesansserif;278B -twodeva;0968 -twodotenleader;2025 -twodotleader;2025 -twodotleadervertical;FE30 -twogujarati;0AE8 -twogurmukhi;0A68 -twohackarabic;0662 -twohangzhou;3022 -twoideographicparen;3221 -twoinferior;2082 -twomonospace;FF12 -twonumeratorbengali;09F5 -twooldstyle;F732 -twoparen;2475 -twoperiod;2489 -twopersian;06F2 -tworoman;2171 -twostroke;01BB -twosuperior;00B2 -twothai;0E52 -twothirds;2154 -u;0075 -uacute;00FA -ubar;0289 -ubengali;0989 -ubopomofo;3128 -ubreve;016D -ucaron;01D4 -ucircle;24E4 -ucircumflex;00FB -ucircumflexbelow;1E77 -ucyrillic;0443 -udattadeva;0951 -udblacute;0171 -udblgrave;0215 -udeva;0909 -udieresis;00FC -udieresisacute;01D8 -udieresisbelow;1E73 -udieresiscaron;01DA -udieresiscyrillic;04F1 -udieresisgrave;01DC -udieresismacron;01D6 -udotbelow;1EE5 -ugrave;00F9 -ugujarati;0A89 -ugurmukhi;0A09 -uhiragana;3046 -uhookabove;1EE7 -uhorn;01B0 -uhornacute;1EE9 -uhorndotbelow;1EF1 -uhorngrave;1EEB -uhornhookabove;1EED -uhorntilde;1EEF -uhungarumlaut;0171 -uhungarumlautcyrillic;04F3 -uinvertedbreve;0217 -ukatakana;30A6 -ukatakanahalfwidth;FF73 -ukcyrillic;0479 -ukorean;315C -umacron;016B -umacroncyrillic;04EF -umacrondieresis;1E7B -umatragurmukhi;0A41 -umonospace;FF55 -underscore;005F -underscoredbl;2017 -underscoremonospace;FF3F -underscorevertical;FE33 -underscorewavy;FE4F -union;222A -universal;2200 -uogonek;0173 -uparen;24B0 -upblock;2580 -upperdothebrew;05C4 -upsilon;03C5 -upsilondieresis;03CB -upsilondieresistonos;03B0 -upsilonlatin;028A -upsilontonos;03CD -uptackbelowcmb;031D -uptackmod;02D4 -uragurmukhi;0A73 -uring;016F -ushortcyrillic;045E -usmallhiragana;3045 -usmallkatakana;30A5 -usmallkatakanahalfwidth;FF69 -ustraightcyrillic;04AF -ustraightstrokecyrillic;04B1 -utilde;0169 -utildeacute;1E79 -utildebelow;1E75 -uubengali;098A -uudeva;090A -uugujarati;0A8A -uugurmukhi;0A0A -uumatragurmukhi;0A42 -uuvowelsignbengali;09C2 -uuvowelsigndeva;0942 -uuvowelsigngujarati;0AC2 -uvowelsignbengali;09C1 -uvowelsigndeva;0941 -uvowelsigngujarati;0AC1 -v;0076 -vadeva;0935 -vagujarati;0AB5 -vagurmukhi;0A35 -vakatakana;30F7 -vav;05D5 -vavdagesh;FB35 -vavdagesh65;FB35 -vavdageshhebrew;FB35 -vavhebrew;05D5 -vavholam;FB4B -vavholamhebrew;FB4B -vavvavhebrew;05F0 -vavyodhebrew;05F1 -vcircle;24E5 -vdotbelow;1E7F -vecyrillic;0432 -veharabic;06A4 -vehfinalarabic;FB6B -vehinitialarabic;FB6C -vehmedialarabic;FB6D -vekatakana;30F9 -venus;2640 -verticalbar;007C -verticallineabovecmb;030D -verticallinebelowcmb;0329 -verticallinelowmod;02CC -verticallinemod;02C8 -vewarmenian;057E -vhook;028B -vikatakana;30F8 -viramabengali;09CD -viramadeva;094D -viramagujarati;0ACD -visargabengali;0983 -visargadeva;0903 -visargagujarati;0A83 -vmonospace;FF56 -voarmenian;0578 -voicediterationhiragana;309E -voicediterationkatakana;30FE -voicedmarkkana;309B -voicedmarkkanahalfwidth;FF9E -vokatakana;30FA -vparen;24B1 -vtilde;1E7D -vturned;028C -vuhiragana;3094 -vukatakana;30F4 -w;0077 -wacute;1E83 -waekorean;3159 -wahiragana;308F -wakatakana;30EF -wakatakanahalfwidth;FF9C -wakorean;3158 -wasmallhiragana;308E -wasmallkatakana;30EE -wattosquare;3357 -wavedash;301C -wavyunderscorevertical;FE34 -wawarabic;0648 -wawfinalarabic;FEEE -wawhamzaabovearabic;0624 -wawhamzaabovefinalarabic;FE86 -wbsquare;33DD -wcircle;24E6 -wcircumflex;0175 -wdieresis;1E85 -wdotaccent;1E87 -wdotbelow;1E89 -wehiragana;3091 -weierstrass;2118 -wekatakana;30F1 -wekorean;315E -weokorean;315D -wgrave;1E81 -whitebullet;25E6 -whitecircle;25CB -whitecircleinverse;25D9 -whitecornerbracketleft;300E -whitecornerbracketleftvertical;FE43 -whitecornerbracketright;300F -whitecornerbracketrightvertical;FE44 -whitediamond;25C7 -whitediamondcontainingblacksmalldiamond;25C8 -whitedownpointingsmalltriangle;25BF -whitedownpointingtriangle;25BD -whiteleftpointingsmalltriangle;25C3 -whiteleftpointingtriangle;25C1 -whitelenticularbracketleft;3016 -whitelenticularbracketright;3017 -whiterightpointingsmalltriangle;25B9 -whiterightpointingtriangle;25B7 -whitesmallsquare;25AB -whitesmilingface;263A -whitesquare;25A1 -whitestar;2606 -whitetelephone;260F -whitetortoiseshellbracketleft;3018 -whitetortoiseshellbracketright;3019 -whiteuppointingsmalltriangle;25B5 -whiteuppointingtriangle;25B3 -wihiragana;3090 -wikatakana;30F0 -wikorean;315F -wmonospace;FF57 -wohiragana;3092 -wokatakana;30F2 -wokatakanahalfwidth;FF66 -won;20A9 -wonmonospace;FFE6 -wowaenthai;0E27 -wparen;24B2 -wring;1E98 -wsuperior;02B7 -wturned;028D -wynn;01BF -x;0078 -xabovecmb;033D -xbopomofo;3112 -xcircle;24E7 -xdieresis;1E8D -xdotaccent;1E8B -xeharmenian;056D -xi;03BE -xmonospace;FF58 -xparen;24B3 -xsuperior;02E3 -y;0079 -yaadosquare;334E -yabengali;09AF -yacute;00FD -yadeva;092F -yaekorean;3152 -yagujarati;0AAF -yagurmukhi;0A2F -yahiragana;3084 -yakatakana;30E4 -yakatakanahalfwidth;FF94 -yakorean;3151 -yamakkanthai;0E4E -yasmallhiragana;3083 -yasmallkatakana;30E3 -yasmallkatakanahalfwidth;FF6C -yatcyrillic;0463 -ycircle;24E8 -ycircumflex;0177 -ydieresis;00FF -ydotaccent;1E8F -ydotbelow;1EF5 -yeharabic;064A -yehbarreearabic;06D2 -yehbarreefinalarabic;FBAF -yehfinalarabic;FEF2 -yehhamzaabovearabic;0626 -yehhamzaabovefinalarabic;FE8A -yehhamzaaboveinitialarabic;FE8B -yehhamzaabovemedialarabic;FE8C -yehinitialarabic;FEF3 -yehmedialarabic;FEF4 -yehmeeminitialarabic;FCDD -yehmeemisolatedarabic;FC58 -yehnoonfinalarabic;FC94 -yehthreedotsbelowarabic;06D1 -yekorean;3156 -yen;00A5 -yenmonospace;FFE5 -yeokorean;3155 -yeorinhieuhkorean;3186 -yerahbenyomohebrew;05AA -yerahbenyomolefthebrew;05AA -yericyrillic;044B -yerudieresiscyrillic;04F9 -yesieungkorean;3181 -yesieungpansioskorean;3183 -yesieungsioskorean;3182 -yetivhebrew;059A -ygrave;1EF3 -yhook;01B4 -yhookabove;1EF7 -yiarmenian;0575 -yicyrillic;0457 -yikorean;3162 -yinyang;262F -yiwnarmenian;0582 -ymonospace;FF59 -yod;05D9 -yoddagesh;FB39 -yoddageshhebrew;FB39 -yodhebrew;05D9 -yodyodhebrew;05F2 -yodyodpatahhebrew;FB1F -yohiragana;3088 -yoikorean;3189 -yokatakana;30E8 -yokatakanahalfwidth;FF96 -yokorean;315B -yosmallhiragana;3087 -yosmallkatakana;30E7 -yosmallkatakanahalfwidth;FF6E -yotgreek;03F3 -yoyaekorean;3188 -yoyakorean;3187 -yoyakthai;0E22 -yoyingthai;0E0D -yparen;24B4 -ypogegrammeni;037A -ypogegrammenigreekcmb;0345 -yr;01A6 -yring;1E99 -ysuperior;02B8 -ytilde;1EF9 -yturned;028E -yuhiragana;3086 -yuikorean;318C -yukatakana;30E6 -yukatakanahalfwidth;FF95 -yukorean;3160 -yusbigcyrillic;046B -yusbigiotifiedcyrillic;046D -yuslittlecyrillic;0467 -yuslittleiotifiedcyrillic;0469 -yusmallhiragana;3085 -yusmallkatakana;30E5 -yusmallkatakanahalfwidth;FF6D -yuyekorean;318B -yuyeokorean;318A -yyabengali;09DF -yyadeva;095F -z;007A -zaarmenian;0566 -zacute;017A -zadeva;095B -zagurmukhi;0A5B -zaharabic;0638 -zahfinalarabic;FEC6 -zahinitialarabic;FEC7 -zahiragana;3056 -zahmedialarabic;FEC8 -zainarabic;0632 -zainfinalarabic;FEB0 -zakatakana;30B6 -zaqefgadolhebrew;0595 -zaqefqatanhebrew;0594 -zarqahebrew;0598 -zayin;05D6 -zayindagesh;FB36 -zayindageshhebrew;FB36 -zayinhebrew;05D6 -zbopomofo;3117 -zcaron;017E -zcircle;24E9 -zcircumflex;1E91 -zcurl;0291 -zdot;017C -zdotaccent;017C -zdotbelow;1E93 -zecyrillic;0437 -zedescendercyrillic;0499 -zedieresiscyrillic;04DF -zehiragana;305C -zekatakana;30BC -zero;0030 -zeroarabic;0660 -zerobengali;09E6 -zerodeva;0966 -zerogujarati;0AE6 -zerogurmukhi;0A66 -zerohackarabic;0660 -zeroinferior;2080 -zeromonospace;FF10 -zerooldstyle;F730 -zeropersian;06F0 -zerosuperior;2070 -zerothai;0E50 -zerowidthjoiner;FEFF -zerowidthnonjoiner;200C -zerowidthspace;200B -zeta;03B6 -zhbopomofo;3113 -zhearmenian;056A -zhebrevecyrillic;04C2 -zhecyrillic;0436 -zhedescendercyrillic;0497 -zhedieresiscyrillic;04DD -zihiragana;3058 -zikatakana;30B8 -zinorhebrew;05AE -zlinebelow;1E95 -zmonospace;FF5A -zohiragana;305E -zokatakana;30BE -zparen;24B5 -zretroflexhook;0290 -zstroke;01B6 -zuhiragana;305A -zukatakana;30BA -a100;275E -a101;2761 -a102;2762 -a103;2763 -a104;2764 -a105;2710 -a106;2765 -a107;2766 -a108;2767 -a109;2660 -a10;2721 -a110;2665 -a111;2666 -a112;2663 -a117;2709 -a118;2708 -a119;2707 -a11;261B -a120;2460 -a121;2461 -a122;2462 -a123;2463 -a124;2464 -a125;2465 -a126;2466 -a127;2467 -a128;2468 -a129;2469 -a12;261E -a130;2776 -a131;2777 -a132;2778 -a133;2779 -a134;277A -a135;277B -a136;277C -a137;277D -a138;277E -a139;277F -a13;270C -a140;2780 -a141;2781 -a142;2782 -a143;2783 -a144;2784 -a145;2785 -a146;2786 -a147;2787 -a148;2788 -a149;2789 -a14;270D -a150;278A -a151;278B -a152;278C -a153;278D -a154;278E -a155;278F -a156;2790 -a157;2791 -a158;2792 -a159;2793 -a15;270E -a160;2794 -a161;2192 -a162;27A3 -a163;2194 -a164;2195 -a165;2799 -a166;279B -a167;279C -a168;279D -a169;279E -a16;270F -a170;279F -a171;27A0 -a172;27A1 -a173;27A2 -a174;27A4 -a175;27A5 -a176;27A6 -a177;27A7 -a178;27A8 -a179;27A9 -a17;2711 -a180;27AB -a181;27AD -a182;27AF -a183;27B2 -a184;27B3 -a185;27B5 -a186;27B8 -a187;27BA -a188;27BB -a189;27BC -a18;2712 -a190;27BD -a191;27BE -a192;279A -a193;27AA -a194;27B6 -a195;27B9 -a196;2798 -a197;27B4 -a198;27B7 -a199;27AC -a19;2713 -a1;2701 -a200;27AE -a201;27B1 -a202;2703 -a203;2750 -a204;2752 -a205;276E -a206;2770 -a20;2714 -a21;2715 -a22;2716 -a23;2717 -a24;2718 -a25;2719 -a26;271A -a27;271B -a28;271C -a29;2722 -a2;2702 -a30;2723 -a31;2724 -a32;2725 -a33;2726 -a34;2727 -a35;2605 -a36;2729 -a37;272A -a38;272B -a39;272C -a3;2704 -a40;272D -a41;272E -a42;272F -a43;2730 -a44;2731 -a45;2732 -a46;2733 -a47;2734 -a48;2735 -a49;2736 -a4;260E -a50;2737 -a51;2738 -a52;2739 -a53;273A -a54;273B -a55;273C -a56;273D -a57;273E -a58;273F -a59;2740 -a5;2706 -a60;2741 -a61;2742 -a62;2743 -a63;2744 -a64;2745 -a65;2746 -a66;2747 -a67;2748 -a68;2749 -a69;274A -a6;271D -a70;274B -a71;25CF -a72;274D -a73;25A0 -a74;274F -a75;2751 -a76;25B2 -a77;25BC -a78;25C6 -a79;2756 -a7;271E -a81;25D7 -a82;2758 -a83;2759 -a84;275A -a85;276F -a86;2771 -a87;2772 -a88;2773 -a89;2768 -a8;271F -a90;2769 -a91;276C -a92;276D -a93;276A -a94;276B -a95;2774 -a96;2775 -a97;275B -a98;275C -a99;275D -a9;2720 -""" - - -# string table management -# -class StringTable: - def __init__( self, name_list, master_table_name ): - self.names = name_list - self.master_table = master_table_name - self.indices = {} - index = 0 - - for name in name_list: - self.indices[name] = index - index += len( name ) + 1 - - self.total = index - - def dump( self, file ): - write = file.write - write( "#ifndef DEFINE_PS_TABLES_DATA\n" ) - write( "#ifdef __cplusplus\n" ) - write( ' extern "C"\n' ) - write( "#else\n" ) - write( " extern\n" ) - write( "#endif\n" ) - write( "#endif\n" ) - write( " const char " + self.master_table + - "[" + repr( self.total ) + "]\n" ) - write( "#ifdef DEFINE_PS_TABLES_DATA\n" ) - write( " =\n" ) - write( " {\n" ) - - line = "" - for name in self.names: - line += " '" - line += string.join( ( re.findall( ".", name ) ), "','" ) - line += "', 0,\n" - - write( line ) - write( " }\n" ) - write( "#endif /* DEFINE_PS_TABLES_DATA */\n" ) - write( " ;\n\n\n" ) - - def dump_sublist( self, file, table_name, macro_name, sublist ): - write = file.write - write( "#define " + macro_name + " " + repr( len( sublist ) ) + "\n\n" ) - - write( " /* Values are offsets into the `" + - self.master_table + "' table */\n\n" ) - write( "#ifndef DEFINE_PS_TABLES_DATA\n" ) - write( "#ifdef __cplusplus\n" ) - write( ' extern "C"\n' ) - write( "#else\n" ) - write( " extern\n" ) - write( "#endif\n" ) - write( "#endif\n" ) - write( " const short " + table_name + - "[" + macro_name + "]\n" ) - write( "#ifdef DEFINE_PS_TABLES_DATA\n" ) - write( " =\n" ) - write( " {\n" ) - - line = " " - comma = "" - col = 0 - - for name in sublist: - line += comma - line += "%4d" % self.indices[name] - col += 1 - comma = "," - if col == 14: - col = 0 - comma = ",\n " - - write( line ) - write( "\n" ) - write( " }\n" ) - write( "#endif /* DEFINE_PS_TABLES_DATA */\n" ) - write( " ;\n\n\n" ) - - -# We now store the Adobe Glyph List in compressed form. The list is put -# into a data structure called `trie' (because it has a tree-like -# appearance). Consider, for example, that you want to store the -# following name mapping: -# -# A => 1 -# Aacute => 6 -# Abalon => 2 -# Abstract => 4 -# -# It is possible to store the entries as follows. -# -# A => 1 -# | -# +-acute => 6 -# | -# +-b -# | -# +-alon => 2 -# | -# +-stract => 4 -# -# We see that each node in the trie has: -# -# - one or more `letters' -# - an optional value -# - zero or more child nodes -# -# The first step is to call -# -# root = StringNode( "", 0 ) -# for word in map.values(): -# root.add( word, map[word] ) -# -# which creates a large trie where each node has only one children. -# -# Executing -# -# root = root.optimize() -# -# optimizes the trie by merging the letters of successive nodes whenever -# possible. -# -# Each node of the trie is stored as follows. -# -# - First the node's letter, according to the following scheme. We -# use the fact that in the AGL no name contains character codes > 127. -# -# name bitsize description -# ---------------------------------------------------------------- -# notlast 1 Set to 1 if this is not the last letter -# in the word. -# ascii 7 The letter's ASCII value. -# -# - The letter is followed by a children count and the value of the -# current key (if any). Again we can do some optimization because all -# AGL entries are from the BMP; this means that 16 bits are sufficient -# to store its Unicode values. Additionally, no node has more than -# 127 children. -# -# name bitsize description -# ----------------------------------------- -# hasvalue 1 Set to 1 if a 16-bit Unicode value follows. -# num_children 7 Number of children. Can be 0 only if -# `hasvalue' is set to 1. -# value 16 Optional Unicode value. -# -# - A node is finished by a list of 16bit absolute offsets to the -# children, which must be sorted in increasing order of their first -# letter. -# -# For simplicity, all 16bit quantities are stored in big-endian order. -# -# The root node has first letter = 0, and no value. -# -class StringNode: - def __init__( self, letter, value ): - self.letter = letter - self.value = value - self.children = {} - - def __cmp__( self, other ): - return ord( self.letter[0] ) - ord( other.letter[0] ) - - def add( self, word, value ): - if len( word ) == 0: - self.value = value - return - - letter = word[0] - word = word[1:] - - if self.children.has_key( letter ): - child = self.children[letter] - else: - child = StringNode( letter, 0 ) - self.children[letter] = child - - child.add( word, value ) - - def optimize( self ): - # optimize all children first - children = self.children.values() - self.children = {} - - for child in children: - self.children[child.letter[0]] = child.optimize() - - # don't optimize if there's a value, - # if we don't have any child or if we - # have more than one child - if ( self.value != 0 ) or ( not children ) or len( children ) > 1: - return self - - child = children[0] - - self.letter += child.letter - self.value = child.value - self.children = child.children - - return self - - def dump_debug( self, write, margin ): - # this is used during debugging - line = margin + "+-" - if len( self.letter ) == 0: - line += "" - else: - line += self.letter - - if self.value: - line += " => " + repr( self.value ) - - write( line + "\n" ) - - if self.children: - margin += "| " - for child in self.children.values(): - child.dump_debug( write, margin ) - - def locate( self, index ): - self.index = index - if len( self.letter ) > 0: - index += len( self.letter ) + 1 - else: - index += 2 - - if self.value != 0: - index += 2 - - children = self.children.values() - children.sort() - - index += 2 * len( children ) - for child in children: - index = child.locate( index ) - - return index - - def store( self, storage ): - # write the letters - l = len( self.letter ) - if l == 0: - storage += struct.pack( "B", 0 ) - else: - for n in range( l ): - val = ord( self.letter[n] ) - if n < l - 1: - val += 128 - storage += struct.pack( "B", val ) - - # write the count - children = self.children.values() - children.sort() - - count = len( children ) - - if self.value != 0: - storage += struct.pack( "!BH", count + 128, self.value ) - else: - storage += struct.pack( "B", count ) - - for child in children: - storage += struct.pack( "!H", child.index ) - - for child in children: - storage = child.store( storage ) - - return storage - - -def adobe_glyph_values(): - """return the list of glyph names and their unicode values""" - - lines = string.split( adobe_glyph_list, '\n' ) - glyphs = [] - values = [] - - for line in lines: - if line: - fields = string.split( line, ';' ) -# print fields[1] + ' - ' + fields[0] - subfields = string.split( fields[1], ' ' ) - if len( subfields ) == 1: - glyphs.append( fields[0] ) - values.append( fields[1] ) - - return glyphs, values - - -def filter_glyph_names( alist, filter ): - """filter `alist' by taking _out_ all glyph names that are in `filter'""" - - count = 0 - extras = [] - - for name in alist: - try: - filtered_index = filter.index( name ) - except: - extras.append( name ) - - return extras - - -def dump_encoding( file, encoding_name, encoding_list ): - """dump a given encoding""" - - write = file.write - write( " /* the following are indices into the SID name table */\n" ) - write( "#ifndef DEFINE_PS_TABLES_DATA\n" ) - write( "#ifdef __cplusplus\n" ) - write( ' extern "C"\n' ) - write( "#else\n" ) - write( " extern\n" ) - write( "#endif\n" ) - write( "#endif\n" ) - write( " const unsigned short " + encoding_name + - "[" + repr( len( encoding_list ) ) + "]\n" ) - write( "#ifdef DEFINE_PS_TABLES_DATA\n" ) - write( " =\n" ) - write( " {\n" ) - - line = " " - comma = "" - col = 0 - for value in encoding_list: - line += comma - line += "%3d" % value - comma = "," - col += 1 - if col == 16: - col = 0 - comma = ",\n " - - write( line ) - write( "\n" ) - write( " }\n" ) - write( "#endif /* DEFINE_PS_TABLES_DATA */\n" ) - write( " ;\n\n\n" ) - - -def dump_array( the_array, write, array_name ): - """dumps a given encoding""" - - write( "#ifndef DEFINE_PS_TABLES_DATA\n" ) - write( "#ifdef __cplusplus\n" ) - write( ' extern "C"\n' ) - write( "#else\n" ) - write( " extern\n" ) - write( "#endif\n" ) - write( "#endif\n" ) - write( " const unsigned char " + array_name + - "[" + repr( len( the_array ) ) + "L]\n" ) - write( "#ifdef DEFINE_PS_TABLES_DATA\n" ) - write( " =\n" ) - write( " {\n" ) - - line = "" - comma = " " - col = 0 - - for value in the_array: - line += comma - line += "%3d" % ord( value ) - comma = "," - col += 1 - - if col == 16: - col = 0 - comma = ",\n " - - if len( line ) > 1024: - write( line ) - line = "" - - write( line ) - write( "\n" ) - write( " }\n" ) - write( "#endif /* DEFINE_PS_TABLES_DATA */\n" ) - write( " ;\n\n\n" ) - - -def main(): - """main program body""" - - if len( sys.argv ) != 2: - print __doc__ % sys.argv[0] - sys.exit( 1 ) - - file = open( sys.argv[1], "wb" ) - write = file.write - - count_sid = len( sid_standard_names ) - - # `mac_extras' contains the list of glyph names in the Macintosh standard - # encoding which are not in the SID Standard Names. - # - mac_extras = filter_glyph_names( mac_standard_names, sid_standard_names ) - - # `base_list' contains the names of our final glyph names table. - # It consists of the `mac_extras' glyph names, followed by the SID - # standard names. - # - mac_extras_count = len( mac_extras ) - base_list = mac_extras + sid_standard_names - - write( "/***************************************************************************/\n" ) - write( "/* */\n" ) - - write( "/* %-71s*/\n" % os.path.basename( sys.argv[1] ) ) - - write( "/* */\n" ) - write( "/* PostScript glyph names. */\n" ) - write( "/* */\n" ) - write( "/* Copyright 2005-2018 by */\n" ) - write( "/* David Turner, Robert Wilhelm, and Werner Lemberg. */\n" ) - write( "/* */\n" ) - write( "/* This file is part of the FreeType project, and may only be used, */\n" ) - write( "/* modified, and distributed under the terms of the FreeType project */\n" ) - write( "/* license, LICENSE.TXT. By continuing to use, modify, or distribute */\n" ) - write( "/* this file you indicate that you have read the license and */\n" ) - write( "/* understand and accept it fully. */\n" ) - write( "/* */\n" ) - write( "/***************************************************************************/\n" ) - write( "\n" ) - write( "\n" ) - write( " /* This file has been generated automatically -- do not edit! */\n" ) - write( "\n" ) - write( "\n" ) - - # dump final glyph list (mac extras + sid standard names) - # - st = StringTable( base_list, "ft_standard_glyph_names" ) - - st.dump( file ) - st.dump_sublist( file, "ft_mac_names", - "FT_NUM_MAC_NAMES", mac_standard_names ) - st.dump_sublist( file, "ft_sid_names", - "FT_NUM_SID_NAMES", sid_standard_names ) - - dump_encoding( file, "t1_standard_encoding", t1_standard_encoding ) - dump_encoding( file, "t1_expert_encoding", t1_expert_encoding ) - - # dump the AGL in its compressed form - # - agl_glyphs, agl_values = adobe_glyph_values() - dict = StringNode( "", 0 ) - - for g in range( len( agl_glyphs ) ): - dict.add( agl_glyphs[g], eval( "0x" + agl_values[g] ) ) - - dict = dict.optimize() - dict_len = dict.locate( 0 ) - dict_array = dict.store( "" ) - - write( """\ - /* - * This table is a compressed version of the Adobe Glyph List (AGL), - * optimized for efficient searching. It has been generated by the - * `glnames.py' python script located in the `src/tools' directory. - * - * The lookup function to get the Unicode value for a given string - * is defined below the table. - */ - -#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST - -""" ) - - dump_array( dict_array, write, "ft_adobe_glyph_list" ) - - # write the lookup routine now - # - write( """\ -#ifdef DEFINE_PS_TABLES - /* - * This function searches the compressed table efficiently. - */ - static unsigned long - ft_get_adobe_glyph_index( const char* name, - const char* limit ) - { - int c = 0; - int count, min, max; - const unsigned char* p = ft_adobe_glyph_list; - - - if ( name == 0 || name >= limit ) - goto NotFound; - - c = *name++; - count = p[1]; - p += 2; - - min = 0; - max = count; - - while ( min < max ) - { - int mid = ( min + max ) >> 1; - const unsigned char* q = p + mid * 2; - int c2; - - - q = ft_adobe_glyph_list + ( ( (int)q[0] << 8 ) | q[1] ); - - c2 = q[0] & 127; - if ( c2 == c ) - { - p = q; - goto Found; - } - if ( c2 < c ) - min = mid + 1; - else - max = mid; - } - goto NotFound; - - Found: - for (;;) - { - /* assert (*p & 127) == c */ - - if ( name >= limit ) - { - if ( (p[0] & 128) == 0 && - (p[1] & 128) != 0 ) - return (unsigned long)( ( (int)p[2] << 8 ) | p[3] ); - - goto NotFound; - } - c = *name++; - if ( p[0] & 128 ) - { - p++; - if ( c != (p[0] & 127) ) - goto NotFound; - - continue; - } - - p++; - count = p[0] & 127; - if ( p[0] & 128 ) - p += 2; - - p++; - - for ( ; count > 0; count--, p += 2 ) - { - int offset = ( (int)p[0] << 8 ) | p[1]; - const unsigned char* q = ft_adobe_glyph_list + offset; - - if ( c == ( q[0] & 127 ) ) - { - p = q; - goto NextIter; - } - } - goto NotFound; - - NextIter: - ; - } - - NotFound: - return 0; - } -#endif /* DEFINE_PS_TABLES */ - -#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ - -""" ) - - if 0: # generate unit test, or don't - # - # now write the unit test to check that everything works OK - # - write( "#ifdef TEST\n\n" ) - - write( "static const char* const the_names[] = {\n" ) - for name in agl_glyphs: - write( ' "' + name + '",\n' ) - write( " 0\n};\n" ) - - write( "static const unsigned long the_values[] = {\n" ) - for val in agl_values: - write( ' 0x' + val + ',\n' ) - write( " 0\n};\n" ) - - write( """ -#include -#include - - int - main( void ) - { - int result = 0; - const char* const* names = the_names; - const unsigned long* values = the_values; - - - for ( ; *names; names++, values++ ) - { - const char* name = *names; - unsigned long reference = *values; - unsigned long value; - - - value = ft_get_adobe_glyph_index( name, name + strlen( name ) ); - if ( value != reference ) - { - result = 1; - fprintf( stderr, "name '%s' => %04x instead of %04x\\n", - name, value, reference ); - } - } - - return result; - } -""" ) - - write( "#endif /* TEST */\n" ) - - write("\n/* END */\n") - - -# Now run the main routine -# -main() - - -# END diff --git a/sdk/lib/3rdparty/freetype/src/tools/test_afm.c b/sdk/lib/3rdparty/freetype/src/tools/test_afm.c deleted file mode 100644 index 8de619bb035cb..0000000000000 --- a/sdk/lib/3rdparty/freetype/src/tools/test_afm.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * gcc -DFT2_BUILD_LIBRARY -I../../include -o test_afm test_afm.c \ - * -L../../objs/.libs -lfreetype -lz -static - */ -#include -#include FT_FREETYPE_H -#include FT_INTERNAL_STREAM_H -#include FT_INTERNAL_POSTSCRIPT_AUX_H - - void dump_fontinfo( AFM_FontInfo fi ) - { - FT_UInt i; - - - printf( "This AFM is for %sCID font.\n\n", - ( fi->IsCIDFont ) ? "" : "non-" ); - - printf( "FontBBox: %.2f %.2f %.2f %.2f\n", fi->FontBBox.xMin / 65536., - fi->FontBBox.yMin / 65536., - fi->FontBBox.xMax / 65536., - fi->FontBBox.yMax / 65536. ); - printf( "Ascender: %.2f\n", fi->Ascender / 65536. ); - printf( "Descender: %.2f\n\n", fi->Descender / 65536. ); - - if ( fi->NumTrackKern ) - printf( "There are %d sets of track kernings:\n", - fi->NumTrackKern ); - else - printf( "There is no track kerning.\n" ); - - for ( i = 0; i < fi->NumTrackKern; i++ ) - { - AFM_TrackKern tk = fi->TrackKerns + i; - - - printf( "\t%2d: %5.2f %5.2f %5.2f %5.2f\n", tk->degree, - tk->min_ptsize / 65536., - tk->min_kern / 65536., - tk->max_ptsize / 65536., - tk->max_kern / 65536. ); - } - - printf( "\n" ); - - if ( fi->NumKernPair ) - printf( "There are %d kerning pairs:\n", - fi->NumKernPair ); - else - printf( "There is no kerning pair.\n" ); - - for ( i = 0; i < fi->NumKernPair; i++ ) - { - AFM_KernPair kp = fi->KernPairs + i; - - - printf( "\t%3d + %3d => (%4d, %4d)\n", kp->index1, - kp->index2, - kp->x, - kp->y ); - } - - } - - int - dummy_get_index( const char* name, - FT_Offset len, - void* user_data ) - { - if ( len ) - return name[0]; - else - return 0; - } - - FT_Error - parse_afm( FT_Library library, - FT_Stream stream, - AFM_FontInfo fi ) - { - PSAux_Service psaux; - AFM_ParserRec parser; - FT_Error error = FT_Err_Ok; - - - psaux = (PSAux_Service)FT_Get_Module_Interface( library, "psaux" ); - if ( !psaux || !psaux->afm_parser_funcs ) - return -1; - - error = FT_Stream_EnterFrame( stream, stream->size ); - if ( error ) - return error; - - error = psaux->afm_parser_funcs->init( &parser, - library->memory, - stream->cursor, - stream->limit ); - if ( error ) - return error; - - parser.FontInfo = fi; - parser.get_index = dummy_get_index; - - error = psaux->afm_parser_funcs->parse( &parser ); - - psaux->afm_parser_funcs->done( &parser ); - - return error; - } - - - int main( int argc, - char** argv ) - { - FT_Library library; - FT_StreamRec stream; - FT_Error error = FT_Err_Ok; - AFM_FontInfoRec fi; - - - if ( argc < 2 ) - return FT_ERR( Invalid_Argument ); - - error = FT_Init_FreeType( &library ); - if ( error ) - return error; - - FT_ZERO( &stream ); - error = FT_Stream_Open( &stream, argv[1] ); - if ( error ) - goto Exit; - stream.memory = library->memory; - - FT_ZERO( &fi ); - error = parse_afm( library, &stream, &fi ); - - if ( !error ) - { - FT_Memory memory = library->memory; - - - dump_fontinfo( &fi ); - - if ( fi.KernPairs ) - FT_FREE( fi.KernPairs ); - if ( fi.TrackKerns ) - FT_FREE( fi.TrackKerns ); - } - else - printf( "parse error\n" ); - - FT_Stream_Close( &stream ); - - Exit: - FT_Done_FreeType( library ); - - return error; - } diff --git a/sdk/lib/3rdparty/freetype/src/tools/test_bbox.c b/sdk/lib/3rdparty/freetype/src/tools/test_bbox.c deleted file mode 100644 index 64b82c384b6a1..0000000000000 --- a/sdk/lib/3rdparty/freetype/src/tools/test_bbox.c +++ /dev/null @@ -1,188 +0,0 @@ -#include -#include FT_FREETYPE_H -#include FT_BBOX_H - - -#include /* for clock() */ - -/* SunOS 4.1.* does not define CLOCKS_PER_SEC, so include */ -/* to get the HZ macro which is the equivalent. */ -#if defined(__sun__) && !defined(SVR4) && !defined(__SVR4) -#include -#define CLOCKS_PER_SEC HZ -#endif - - static long - get_time( void ) - { - return clock() * 10000L / CLOCKS_PER_SEC; - } - - - - - /* test bbox computations */ - -#define XSCALE 65536 -#define XX(x) ((FT_Pos)(x*XSCALE)) -#define XVEC(x,y) { XX(x), XX(y) } -#define XVAL(x) ((x)/(1.0*XSCALE)) - - /* dummy outline #1 */ - static FT_Vector dummy_vec_1[4] = - { -#if 1 - XVEC( 408.9111, 535.3164 ), - XVEC( 455.8887, 634.396 ), - XVEC( -37.8765, 786.2207 ), - XVEC( 164.6074, 535.3164 ) -#else - { (FT_Int32)0x0198E93DL , (FT_Int32)0x021750FFL }, /* 408.9111, 535.3164 */ - { (FT_Int32)0x01C7E312L , (FT_Int32)0x027A6560L }, /* 455.8887, 634.3960 */ - { (FT_Int32)0xFFDA1F9EL , (FT_Int32)0x0312387FL }, /* -37.8765, 786.2207 */ - { (FT_Int32)0x00A49B7EL , (FT_Int32)0x021750FFL } /* 164.6074, 535.3164 */ -#endif - }; - - static char dummy_tag_1[4] = - { - FT_CURVE_TAG_ON, - FT_CURVE_TAG_CUBIC, - FT_CURVE_TAG_CUBIC, - FT_CURVE_TAG_ON - }; - - static short dummy_contour_1[1] = - { - 3 - }; - - static FT_Outline dummy_outline_1 = - { - 1, - 4, - dummy_vec_1, - dummy_tag_1, - dummy_contour_1, - 0 - }; - - - /* dummy outline #2 */ - static FT_Vector dummy_vec_2[4] = - { - XVEC( 100.0, 100.0 ), - XVEC( 100.0, 200.0 ), - XVEC( 200.0, 200.0 ), - XVEC( 200.0, 133.0 ) - }; - - static FT_Outline dummy_outline_2 = - { - 1, - 4, - dummy_vec_2, - dummy_tag_1, - dummy_contour_1, - 0 - }; - - - /* dummy outline #3 with bbox of [0 100 128 128] precisely */ - static FT_Vector dummy_vec_3[4] = - { - XVEC( 100.0, 127.0 ), - XVEC( 200.0, 127.0 ), - XVEC( 0.0, 136.0 ), - XVEC( 0.0, 100.0 ) - }; - - static FT_Outline dummy_outline_3 = - { - 1, - 4, - dummy_vec_3, - dummy_tag_1, - dummy_contour_1, - 0 - }; - - - static void - dump_outline( FT_Outline* outline ) - { - FT_BBox bbox; - - /* compute and display cbox */ - FT_Outline_Get_CBox( outline, &bbox ); - printf( "cbox = [%.2f %.2f %.2f %.2f]\n", - XVAL( bbox.xMin ), - XVAL( bbox.yMin ), - XVAL( bbox.xMax ), - XVAL( bbox.yMax ) ); - - /* compute and display bbox */ - FT_Outline_Get_BBox( outline, &bbox ); - printf( "bbox = [%.2f %.2f %.2f %.2f]\n", - XVAL( bbox.xMin ), - XVAL( bbox.yMin ), - XVAL( bbox.xMax ), - XVAL( bbox.yMax ) ); - } - - - - static void - profile_outline( FT_Outline* outline, - long repeat ) - { - FT_BBox bbox; - long count; - long time0; - - time0 = get_time(); - for ( count = repeat; count > 0; count-- ) - FT_Outline_Get_CBox( outline, &bbox ); - - time0 = get_time() - time0; - printf( "time = %6.3f cbox = [%8.4f %8.4f %8.4f %8.4f]\n", - ((double)time0/10000.0), - XVAL( bbox.xMin ), - XVAL( bbox.yMin ), - XVAL( bbox.xMax ), - XVAL( bbox.yMax ) ); - printf( "cbox_hex = [%08X %08X %08X %08X]\n", - bbox.xMin, bbox.yMin, bbox.xMax, bbox.yMax ); - - - time0 = get_time(); - for ( count = repeat; count > 0; count-- ) - FT_Outline_Get_BBox( outline, &bbox ); - - time0 = get_time() - time0; - printf( "time = %6.3f bbox = [%8.4f %8.4f %8.4f %8.4f]\n", - ((double)time0/10000.0), - XVAL( bbox.xMin ), - XVAL( bbox.yMin ), - XVAL( bbox.xMax ), - XVAL( bbox.yMax ) ); - printf( "bbox_hex = [%08X %08X %08X %08X]\n", - bbox.xMin, bbox.yMin, bbox.xMax, bbox.yMax ); - } - -#define REPEAT 1000000L - - int main( int argc, char** argv ) - { - printf( "outline #1\n" ); - profile_outline( &dummy_outline_1, REPEAT ); - - printf( "outline #2\n" ); - profile_outline( &dummy_outline_2, REPEAT ); - - printf( "outline #3\n" ); - profile_outline( &dummy_outline_3, REPEAT ); - - return 0; - } - diff --git a/sdk/lib/3rdparty/freetype/src/tools/test_trig.c b/sdk/lib/3rdparty/freetype/src/tools/test_trig.c deleted file mode 100644 index 99ac1cf174d98..0000000000000 --- a/sdk/lib/3rdparty/freetype/src/tools/test_trig.c +++ /dev/null @@ -1,258 +0,0 @@ -#include -#include FT_FREETYPE_H -#include FT_TRIGONOMETRY_H - -#include -#include - -#define PI 3.14159265358979323846 -#define SPI (PI/FT_ANGLE_PI) - -/* the precision in 16.16 fixed-point checks. Expect between 2 and 5 */ -/* noise LSB bits during operations, due to rounding errors.. */ -#define THRESHOLD 64 - - static error = 0; - - static void - test_cos( void ) - { - int i; - - - for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000L ) - { - FT_Fixed f1, f2; - double d2; - - - f1 = FT_Cos(i); - d2 = cos( i*SPI ); - f2 = (FT_Fixed)(d2*65536.0); - - if ( abs( f2-f1 ) > THRESHOLD ) - { - error = 1; - printf( "FT_Cos[%3d] = %.7f cos[%3d] = %.7f\n", - (i >> 16), f1/65536.0, (i >> 16), d2 ); - } - } - } - - - static void - test_sin( void ) - { - int i; - - - for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000L ) - { - FT_Fixed f1, f2; - double d2; - - - f1 = FT_Sin(i); - d2 = sin( i*SPI ); - f2 = (FT_Fixed)(d2*65536.0); - - if ( abs( f2-f1 ) > THRESHOLD ) - { - error = 1; - printf( "FT_Sin[%3d] = %.7f sin[%3d] = %.7f\n", - (i >> 16), f1/65536.0, (i >> 16), d2 ); - } - } - } - - - static void - test_tan( void ) - { - int i; - - - for ( i = 0; i < FT_ANGLE_PI2 - 0x2000000L; i += 0x10000L ) - { - FT_Fixed f1, f2; - double d2; - - - f1 = FT_Tan(i); - d2 = tan( i*SPI ); - f2 = (FT_Fixed)(d2*65536.0); - - if ( abs( f2-f1 ) > THRESHOLD ) - { - error = 1; - printf( "FT_Tan[%3d] = %.7f tan[%3d] = %.7f\n", - (i >> 16), f1/65536.0, (i >> 16), d2 ); - } - } - } - - - static void - test_atan2( void ) - { - int i; - - - for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000L ) - { - FT_Fixed c2, s2; - double l, a, c1, s1; - int j; - - - l = 5.0; - a = i*SPI; - - c1 = l * cos(a); - s1 = l * sin(a); - - c2 = (FT_Fixed)(c1*65536.0); - s2 = (FT_Fixed)(s1*65536.0); - - j = FT_Atan2( c2, s2 ); - if ( j < 0 ) - j += FT_ANGLE_2PI; - - if ( abs( i - j ) > 1 ) - { - printf( "FT_Atan2( %.7f, %.7f ) = %.5f, atan = %.5f\n", - c2/65536.0, s2/65536.0, j/65536.0, i/65536.0 ); - } - } - } - - - static void - test_unit( void ) - { - int i; - - - for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000L ) - { - FT_Vector v; - double a, c1, s1; - FT_Fixed c2, s2; - - - FT_Vector_Unit( &v, i ); - a = ( i*SPI ); - c1 = cos(a); - s1 = sin(a); - c2 = (FT_Fixed)(c1*65536.0); - s2 = (FT_Fixed)(s1*65536.0); - - if ( abs( v.x-c2 ) > THRESHOLD || - abs( v.y-s2 ) > THRESHOLD ) - { - error = 1; - printf( "FT_Vector_Unit[%3d] = ( %.7f, %.7f ) vec = ( %.7f, %.7f )\n", - (i >> 16), - v.x/65536.0, v.y/65536.0, - c1, s1 ); - } - } - } - - - static void - test_length( void ) - { - int i; - - - for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000L ) - { - FT_Vector v; - FT_Fixed l, l2; - - - l = (FT_Fixed)(500.0*65536.0); - v.x = (FT_Fixed)( l * cos( i*SPI ) ); - v.y = (FT_Fixed)( l * sin( i*SPI ) ); - l2 = FT_Vector_Length( &v ); - - if ( abs( l2-l ) > THRESHOLD ) - { - error = 1; - printf( "FT_Length( %.7f, %.7f ) = %.5f, length = %.5f\n", - v.x/65536.0, v.y/65536.0, l2/65536.0, l/65536.0 ); - } - } - } - - - static void - test_rotate( void ) - { - int rotate; - - - for ( rotate = 0; rotate < FT_ANGLE_2PI; rotate += 0x10000L ) - { - double ra, cra, sra; - int i; - - - ra = rotate*SPI; - cra = cos( ra ); - sra = sin( ra ); - - for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000L ) - { - FT_Fixed c2, s2, c4, s4; - FT_Vector v; - double l, a, c1, s1, c3, s3; - - - l = 500.0; - a = i*SPI; - - c1 = l * cos(a); - s1 = l * sin(a); - - v.x = c2 = (FT_Fixed)(c1*65536.0); - v.y = s2 = (FT_Fixed)(s1*65536.0); - - FT_Vector_Rotate( &v, rotate ); - - c3 = c1 * cra - s1 * sra; - s3 = c1 * sra + s1 * cra; - - c4 = (FT_Fixed)(c3*65536.0); - s4 = (FT_Fixed)(s3*65536.0); - - if ( abs( c4 - v.x ) > THRESHOLD || - abs( s4 - v.y ) > THRESHOLD ) - { - error = 1; - printf( "FT_Rotate( (%.7f,%.7f), %.5f ) = ( %.7f, %.7f ), rot = ( %.7f, %.7f )\n", - c1, s1, ra, - c2/65536.0, s2/65536.0, - c4/65536.0, s4/65536.0 ); - } - } - } - } - - - int main( void ) - { - test_cos(); - test_sin(); - test_tan(); - test_atan2(); - test_unit(); - test_length(); - test_rotate(); - - if (!error) - printf( "trigonometry test ok !\n" ); - - return !error; - } diff --git a/sdk/lib/3rdparty/freetype/src/truetype/truetype.c b/sdk/lib/3rdparty/freetype/src/truetype/truetype.c index 484370975c642..84928e7321b75 100644 --- a/sdk/lib/3rdparty/freetype/src/truetype/truetype.c +++ b/sdk/lib/3rdparty/freetype/src/truetype/truetype.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* truetype.c */ -/* */ -/* FreeType TrueType driver component (body only). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * truetype.c + * + * FreeType TrueType driver component (body only). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #define FT_MAKE_OPTION_SINGLE_OBJECT @@ -24,7 +24,6 @@ #include "ttgxvar.c" /* gx distortable font */ #include "ttinterp.c" #include "ttobjs.c" /* object manager */ -#include "ttpic.c" #include "ttpload.c" /* tables loader */ #include "ttsubpix.c" diff --git a/sdk/lib/3rdparty/freetype/src/truetype/ttdriver.c b/sdk/lib/3rdparty/freetype/src/truetype/ttdriver.c index 820cafbb8d851..ff626d53ab912 100644 --- a/sdk/lib/3rdparty/freetype/src/truetype/ttdriver.c +++ b/sdk/lib/3rdparty/freetype/src/truetype/ttdriver.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ttdriver.c */ -/* */ -/* TrueType font driver implementation (body). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ttdriver.c + * + * TrueType font driver implementation (body). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include @@ -43,20 +43,19 @@ #include "tterrors.h" -#include "ttpic.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_ttdriver +#define FT_COMPONENT ttdriver /* - * PROPERTY SERVICE + * PROPERTY SERVICE * */ static FT_Error @@ -164,38 +163,42 @@ /*************************************************************************/ - /*************************************************************************/ - /* */ - /* */ - /* tt_get_kerning */ - /* */ - /* */ - /* A driver method used to return the kerning vector between two */ - /* glyphs of the same face. */ - /* */ - /* */ - /* face :: A handle to the source face object. */ - /* */ - /* left_glyph :: The index of the left glyph in the kern pair. */ - /* */ - /* right_glyph :: The index of the right glyph in the kern pair. */ - /* */ - /* */ - /* kerning :: The kerning vector. This is in font units for */ - /* scalable formats, and in pixels for fixed-sizes */ - /* formats. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Only horizontal layouts (left-to-right & right-to-left) are */ - /* supported by this function. Other layouts, or more sophisticated */ - /* kernings, are out of scope of this method (the basic driver */ - /* interface is meant to be simple). */ - /* */ - /* They can be implemented by format-specific interfaces. */ - /* */ + /************************************************************************** + * + * @Function: + * tt_get_kerning + * + * @Description: + * A driver method used to return the kerning vector between two + * glyphs of the same face. + * + * @Input: + * face :: + * A handle to the source face object. + * + * left_glyph :: + * The index of the left glyph in the kern pair. + * + * right_glyph :: + * The index of the right glyph in the kern pair. + * + * @Output: + * kerning :: + * The kerning vector. This is in font units for + * scalable formats, and in pixels for fixed-sizes + * formats. + * + * @Return: + * FreeType error code. 0 means success. + * + * @Note: + * Only horizontal layouts (left-to-right & right-to-left) are + * supported by this function. Other layouts, or more sophisticated + * kernings, are out of scope of this method (the basic driver + * interface is meant to be simple). + * + * They can be implemented by format-specific interfaces. + */ static FT_Error tt_get_kerning( FT_Face ttface, /* TT_Face */ FT_UInt left_glyph, @@ -384,32 +387,36 @@ } - /*************************************************************************/ - /* */ - /* */ - /* tt_glyph_load */ - /* */ - /* */ - /* A driver method used to load a glyph within a given glyph slot. */ - /* */ - /* */ - /* slot :: A handle to the target slot object where the glyph */ - /* will be loaded. */ - /* */ - /* size :: A handle to the source face size at which the glyph */ - /* must be scaled, loaded, etc. */ - /* */ - /* glyph_index :: The index of the glyph in the font file. */ - /* */ - /* load_flags :: A flag indicating what to load for this glyph. The */ - /* FT_LOAD_XXX constants can be used to control the */ - /* glyph loading process (e.g., whether the outline */ - /* should be scaled, whether to load bitmaps or not, */ - /* whether to hint the outline, etc). */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * tt_glyph_load + * + * @Description: + * A driver method used to load a glyph within a given glyph slot. + * + * @Input: + * slot :: + * A handle to the target slot object where the glyph + * will be loaded. + * + * size :: + * A handle to the source face size at which the glyph + * must be scaled, loaded, etc. + * + * glyph_index :: + * The index of the glyph in the font file. + * + * load_flags :: + * A flag indicating what to load for this glyph. The + * FT_LOAD_XXX constants can be used to control the + * glyph loading process (e.g., whether the outline + * should be scaled, whether to load bitmaps or not, + * whether to hint the outline, etc). + * + * @Return: + * FreeType error code. 0 means success. + */ static FT_Error tt_glyph_load( FT_GlyphSlot ttslot, /* TT_GlyphSlot */ FT_Size ttsize, /* TT_Size */ @@ -464,7 +471,7 @@ ? &ttsize->metrics : &size->hinted_metrics; - /* now load the glyph outline if necessary */ + /* now fill in the glyph slot with outline/bitmap/layered */ error = TT_Load_Glyph( size, slot, glyph_index, load_flags ); /* force drop-out mode to 2 - irrelevant now */ @@ -491,17 +498,19 @@ FT_DEFINE_SERVICE_MULTIMASTERSREC( tt_service_gx_multi_masters, - (FT_Get_MM_Func) NULL, /* get_mm */ - (FT_Set_MM_Design_Func) NULL, /* set_mm_design */ - (FT_Set_MM_Blend_Func) TT_Set_MM_Blend, /* set_mm_blend */ - (FT_Get_MM_Blend_Func) TT_Get_MM_Blend, /* get_mm_blend */ - (FT_Get_MM_Var_Func) TT_Get_MM_Var, /* get_mm_var */ - (FT_Set_Var_Design_Func)TT_Set_Var_Design, /* set_var_design */ - (FT_Get_Var_Design_Func)TT_Get_Var_Design, /* get_var_design */ - (FT_Set_Instance_Func) TT_Set_Named_Instance, /* set_instance */ - - (FT_Get_Var_Blend_Func) tt_get_var_blend, /* get_var_blend */ - (FT_Done_Blend_Func) tt_done_blend /* done_blend */ + (FT_Get_MM_Func) NULL, /* get_mm */ + (FT_Set_MM_Design_Func) NULL, /* set_mm_design */ + (FT_Set_MM_Blend_Func) TT_Set_MM_Blend, /* set_mm_blend */ + (FT_Get_MM_Blend_Func) TT_Get_MM_Blend, /* get_mm_blend */ + (FT_Get_MM_Var_Func) TT_Get_MM_Var, /* get_mm_var */ + (FT_Set_Var_Design_Func) TT_Set_Var_Design, /* set_var_design */ + (FT_Get_Var_Design_Func) TT_Get_Var_Design, /* get_var_design */ + (FT_Set_Instance_Func) TT_Set_Named_Instance, /* set_instance */ + (FT_Set_MM_WeightVector_Func)NULL, /* set_mm_weightvector */ + (FT_Get_MM_WeightVector_Func)NULL, /* get_mm_weightvector */ + + (FT_Get_Var_Blend_Func) tt_get_var_blend, /* get_var_blend */ + (FT_Done_Blend_Func) tt_done_blend /* done_blend */ ) FT_DEFINE_SERVICE_METRICSVARIATIONSREC( @@ -548,19 +557,19 @@ tt_services, FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_TRUETYPE, - FT_SERVICE_ID_MULTI_MASTERS, &TT_SERVICE_GX_MULTI_MASTERS_GET, - FT_SERVICE_ID_METRICS_VARIATIONS, &TT_SERVICE_METRICS_VARIATIONS_GET, + FT_SERVICE_ID_MULTI_MASTERS, &tt_service_gx_multi_masters, + FT_SERVICE_ID_METRICS_VARIATIONS, &tt_service_metrics_variations, FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine, - FT_SERVICE_ID_TT_GLYF, &TT_SERVICE_TRUETYPE_GLYF_GET, - FT_SERVICE_ID_PROPERTIES, &TT_SERVICE_PROPERTIES_GET ) + FT_SERVICE_ID_TT_GLYF, &tt_service_truetype_glyf, + FT_SERVICE_ID_PROPERTIES, &tt_service_properties ) #else FT_DEFINE_SERVICEDESCREC4( tt_services, FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_TRUETYPE, FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine, - FT_SERVICE_ID_TT_GLYF, &TT_SERVICE_TRUETYPE_GLYF_GET, - FT_SERVICE_ID_PROPERTIES, &TT_SERVICE_PROPERTIES_GET ) + FT_SERVICE_ID_TT_GLYF, &tt_service_truetype_glyf, + FT_SERVICE_ID_PROPERTIES, &tt_service_properties ) #endif @@ -574,26 +583,15 @@ SFNT_Service sfnt; - /* TT_SERVICES_GET dereferences `library' in PIC mode */ -#ifdef FT_CONFIG_OPTION_PIC - if ( !driver ) - return NULL; - library = driver->library; - if ( !library ) - return NULL; -#endif - - result = ft_service_list_lookup( TT_SERVICES_GET, tt_interface ); + result = ft_service_list_lookup( tt_services, tt_interface ); if ( result ) return result; -#ifndef FT_CONFIG_OPTION_PIC if ( !driver ) return NULL; library = driver->library; if ( !library ) return NULL; -#endif /* only return the default interface from the SFNT module */ sfntd = FT_Get_Module( library, "sfnt" ); diff --git a/sdk/lib/3rdparty/freetype/src/truetype/ttdriver.h b/sdk/lib/3rdparty/freetype/src/truetype/ttdriver.h index 707aa68edf3e7..3936c6a4defba 100644 --- a/sdk/lib/3rdparty/freetype/src/truetype/ttdriver.h +++ b/sdk/lib/3rdparty/freetype/src/truetype/ttdriver.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ttdriver.h */ -/* */ -/* High-level TrueType driver interface (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ttdriver.h + * + * High-level TrueType driver interface (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef TTDRIVER_H_ @@ -26,10 +26,8 @@ FT_BEGIN_HEADER - FT_DECLARE_DRIVER( tt_driver_class ) - FT_END_HEADER #endif /* TTDRIVER_H_ */ diff --git a/sdk/lib/3rdparty/freetype/src/truetype/tterrors.h b/sdk/lib/3rdparty/freetype/src/truetype/tterrors.h index 88bca3a04aff0..5609d28d689a7 100644 --- a/sdk/lib/3rdparty/freetype/src/truetype/tterrors.h +++ b/sdk/lib/3rdparty/freetype/src/truetype/tterrors.h @@ -1,27 +1,27 @@ -/***************************************************************************/ -/* */ -/* tterrors.h */ -/* */ -/* TrueType error codes (specification only). */ -/* */ -/* Copyright 2001-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to define the TrueType error enumeration */ - /* constants. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * tterrors.h + * + * TrueType error codes (specification only). + * + * Copyright (C) 2001-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /************************************************************************** + * + * This file is used to define the TrueType error enumeration + * constants. + * + */ #ifndef TTERRORS_H_ #define TTERRORS_H_ diff --git a/sdk/lib/3rdparty/freetype/src/truetype/ttgload.c b/sdk/lib/3rdparty/freetype/src/truetype/ttgload.c index 32ed34aba5ef6..cbee27aa69210 100644 --- a/sdk/lib/3rdparty/freetype/src/truetype/ttgload.c +++ b/sdk/lib/3rdparty/freetype/src/truetype/ttgload.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ttgload.c */ -/* */ -/* TrueType Glyph Loader (body). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ttgload.c + * + * TrueType Glyph Loader (body). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include @@ -38,20 +38,35 @@ #include "ttsubpix.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_ttgload +#define FT_COMPONENT ttgload - /*************************************************************************/ - /* */ - /* Composite glyph flags. */ - /* */ + /************************************************************************** + * + * Simple glyph flags. + */ +#define ON_CURVE_POINT 0x01 /* same value as FT_CURVE_TAG_ON */ +#define X_SHORT_VECTOR 0x02 +#define Y_SHORT_VECTOR 0x04 +#define REPEAT_FLAG 0x08 +#define X_POSITIVE 0x10 /* two meanings depending on X_SHORT_VECTOR */ +#define SAME_X 0x10 +#define Y_POSITIVE 0x20 /* two meanings depending on Y_SHORT_VECTOR */ +#define SAME_Y 0x20 +#define OVERLAP_SIMPLE 0x40 /* we ignore this value */ + + + /************************************************************************** + * + * Composite glyph flags. + */ #define ARGS_ARE_WORDS 0x0001 #define ARGS_ARE_XY_VALUES 0x0002 #define ROUND_XY_TO_GRID 0x0004 @@ -62,15 +77,15 @@ #define WE_HAVE_A_2X2 0x0080 #define WE_HAVE_INSTR 0x0100 #define USE_MY_METRICS 0x0200 -#define OVERLAP_COMPOUND 0x0400 +#define OVERLAP_COMPOUND 0x0400 /* we ignore this value */ #define SCALED_COMPONENT_OFFSET 0x0800 #define UNSCALED_COMPONENT_OFFSET 0x1000 - /*************************************************************************/ - /* */ - /* Return the horizontal metrics in font units for a given glyph. */ - /* */ + /************************************************************************** + * + * Return the horizontal metrics in font units for a given glyph. + */ FT_LOCAL_DEF( void ) TT_Get_HMetrics( TT_Face face, FT_UInt idx, @@ -84,11 +99,11 @@ } - /*************************************************************************/ - /* */ - /* Return the vertical metrics in font units for a given glyph. */ - /* See function `tt_loader_set_pp' below for explanations. */ - /* */ + /************************************************************************** + * + * Return the vertical metrics in font units for a given glyph. + * See function `tt_loader_set_pp' below for explanations. + */ FT_LOCAL_DEF( void ) TT_Get_VMetrics( TT_Face face, FT_UInt idx, @@ -250,13 +265,13 @@ #endif /* FT_CONFIG_OPTION_INCREMENTAL */ - /*************************************************************************/ - /* */ - /* The following functions are used by default with TrueType fonts. */ - /* However, they can be replaced by alternatives if we need to support */ - /* TrueType-compressed formats (like MicroType) in the future. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * The following functions are used by default with TrueType fonts. + * However, they can be replaced by alternatives if we need to support + * TrueType-compressed formats (like MicroType) in the future. + * + */ FT_CALLBACK_DEF( FT_Error ) TT_Access_Glyph_Frame( TT_Loader loader, @@ -267,12 +282,9 @@ FT_Error error; FT_Stream stream = loader->stream; - /* for non-debug mode */ FT_UNUSED( glyph_index ); - FT_TRACE4(( "Glyph %ld\n", glyph_index )); - /* the following line sets the `error' variable through macros! */ if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( byte_count ) ) return error; @@ -337,7 +349,7 @@ FT_Byte *flag, *flag_limit; FT_Byte c, count; FT_Vector *vec, *vec_limit; - FT_Pos x; + FT_Pos x, y; FT_Short *cont, *cont_limit, prev_cont; FT_Int xy_size = 0; @@ -382,6 +394,8 @@ goto Invalid_Outline; } + FT_TRACE5(( " # of points: %d\n", n_points )); + /* note that we will add four phantom points later */ error = FT_GLYPHLOADER_CHECK_POINTS( gloader, n_points + 4, 0 ); if ( error ) @@ -452,7 +466,7 @@ goto Invalid_Outline; *flag++ = c = FT_NEXT_BYTE( p ); - if ( c & 8 ) + if ( c & REPEAT_FLAG ) { if ( p + 1 > limit ) goto Invalid_Outline; @@ -478,31 +492,29 @@ for ( ; vec < vec_limit; vec++, flag++ ) { - FT_Pos y = 0; - FT_Byte f = *flag; + FT_Pos delta = 0; + FT_Byte f = *flag; - if ( f & 2 ) + if ( f & X_SHORT_VECTOR ) { if ( p + 1 > limit ) goto Invalid_Outline; - y = (FT_Pos)FT_NEXT_BYTE( p ); - if ( ( f & 16 ) == 0 ) - y = -y; + delta = (FT_Pos)FT_NEXT_BYTE( p ); + if ( !( f & X_POSITIVE ) ) + delta = -delta; } - else if ( ( f & 16 ) == 0 ) + else if ( !( f & SAME_X ) ) { if ( p + 2 > limit ) goto Invalid_Outline; - y = (FT_Pos)FT_NEXT_SHORT( p ); + delta = (FT_Pos)FT_NEXT_SHORT( p ); } - x += y; + x += delta; vec->x = x; - /* the cast is for stupid compilers */ - *flag = (FT_Byte)( f & ~( 2 | 16 ) ); } /* reading the Y coordinates */ @@ -510,35 +522,36 @@ vec = gloader->current.outline.points; vec_limit = vec + n_points; flag = (FT_Byte*)outline->tags; - x = 0; + y = 0; for ( ; vec < vec_limit; vec++, flag++ ) { - FT_Pos y = 0; - FT_Byte f = *flag; + FT_Pos delta = 0; + FT_Byte f = *flag; - if ( f & 4 ) + if ( f & Y_SHORT_VECTOR ) { if ( p + 1 > limit ) goto Invalid_Outline; - y = (FT_Pos)FT_NEXT_BYTE( p ); - if ( ( f & 32 ) == 0 ) - y = -y; + delta = (FT_Pos)FT_NEXT_BYTE( p ); + if ( !( f & Y_POSITIVE ) ) + delta = -delta; } - else if ( ( f & 32 ) == 0 ) + else if ( !( f & SAME_Y ) ) { if ( p + 2 > limit ) goto Invalid_Outline; - y = (FT_Pos)FT_NEXT_SHORT( p ); + delta = (FT_Pos)FT_NEXT_SHORT( p ); } - x += y; - vec->y = x; + y += delta; + vec->y = y; + /* the cast is for stupid compilers */ - *flag = (FT_Byte)( f & FT_CURVE_TAG_ON ); + *flag = (FT_Byte)( f & ON_CURVE_POINT ); } outline->n_points = (FT_Short)n_points; @@ -559,9 +572,10 @@ TT_Load_Composite_Glyph( TT_Loader loader ) { FT_Error error; - FT_Byte* p = loader->cursor; - FT_Byte* limit = loader->limit; - FT_GlyphLoader gloader = loader->gloader; + FT_Byte* p = loader->cursor; + FT_Byte* limit = loader->limit; + FT_GlyphLoader gloader = loader->gloader; + FT_Long num_glyphs = loader->face->root.num_glyphs; FT_SubGlyph subglyph; FT_UInt num_subglyphs; @@ -590,6 +604,11 @@ subglyph->flags = FT_NEXT_USHORT( p ); subglyph->index = FT_NEXT_USHORT( p ); + /* we reject composites that have components */ + /* with invalid glyph indices */ + if ( subglyph->index >= num_glyphs ) + goto Invalid_Composite; + /* check space */ count = 2; if ( subglyph->flags & ARGS_ARE_WORDS ) @@ -768,15 +787,15 @@ } - /*************************************************************************/ - /* */ - /* */ - /* TT_Hint_Glyph */ - /* */ - /* */ - /* Hint the glyph using the zone prepared by the caller. Note that */ - /* the zone is supposed to include four phantom points. */ - /* */ + /************************************************************************** + * + * @Function: + * TT_Hint_Glyph + * + * @Description: + * Hint the glyph using the zone prepared by the caller. Note that + * the zone is supposed to include four phantom points. + */ static FT_Error TT_Hint_Glyph( TT_Loader loader, FT_Bool is_composite ) @@ -797,15 +816,9 @@ #ifdef TT_USE_BYTECODE_INTERPRETER - if ( loader->glyph->control_len > 0xFFFFL ) - { - FT_TRACE1(( "TT_Hint_Glyph: too long instructions" )); - FT_TRACE1(( " (0x%lx byte) is truncated\n", - loader->glyph->control_len )); - } n_ins = loader->glyph->control_len; - /* save original point position in org */ + /* save original point positions in `org' array */ if ( n_ins > 0 ) FT_ARRAY_COPY( zone->org, zone->cur, zone->n_points ); @@ -896,16 +909,16 @@ } - /*************************************************************************/ - /* */ - /* */ - /* TT_Process_Simple_Glyph */ - /* */ - /* */ - /* Once a simple glyph has been loaded, it needs to be processed. */ - /* Usually, this means scaling and hinting through bytecode */ - /* interpretation. */ - /* */ + /************************************************************************** + * + * @Function: + * TT_Process_Simple_Glyph + * + * @Description: + * Once a simple glyph has been loaded, it needs to be processed. + * Usually, this means scaling and hinting through bytecode + * interpretation. + */ static FT_Error TT_Process_Simple_Glyph( TT_Loader loader ) { @@ -1071,15 +1084,15 @@ } - /*************************************************************************/ - /* */ - /* */ - /* TT_Process_Composite_Component */ - /* */ - /* */ - /* Once a composite component has been loaded, it needs to be */ - /* processed. Usually, this means transforming and translating. */ - /* */ + /************************************************************************** + * + * @Function: + * TT_Process_Composite_Component + * + * @Description: + * Once a composite component has been loaded, it needs to be + * processed. Usually, this means transforming and translating. + */ static FT_Error TT_Process_Composite_Component( TT_Loader loader, FT_SubGlyph subglyph, @@ -1153,10 +1166,10 @@ #if 0 - /*******************************************************************/ - /* */ - /* This algorithm is what Apple documents. But it doesn't work. */ - /* */ + /******************************************************************** + * + * This algorithm is what Apple documents. But it doesn't work. + */ int a = subglyph->transform.xx > 0 ? subglyph->transform.xx : -subglyph->transform.xx; int b = subglyph->transform.yx > 0 ? subglyph->transform.yx @@ -1178,10 +1191,10 @@ #else /* 1 */ - /*******************************************************************/ - /* */ - /* This algorithm is a guess and works much better than the above. */ - /* */ + /******************************************************************** + * + * This algorithm is a guess and works much better than the above. + */ FT_Fixed mac_xscale = FT_Hypot( subglyph->transform.xx, subglyph->transform.xy ); FT_Fixed mac_yscale = FT_Hypot( subglyph->transform.yy, @@ -1219,7 +1232,7 @@ * Theoretically, a glyph's bytecode can toggle ClearType's * `backward compatibility' mode, which would allow modification * of the advance width. In reality, however, applications - * neither allow nor expect modified advance widths if sub-pixel + * neither allow nor expect modified advance widths if subpixel * rendering is active. * */ @@ -1239,16 +1252,16 @@ } - /*************************************************************************/ - /* */ - /* */ - /* TT_Process_Composite_Glyph */ - /* */ - /* */ - /* This is slightly different from TT_Process_Simple_Glyph, in that */ - /* its sole purpose is to hint the glyph. Thus this function is */ - /* only available when bytecode interpreter is enabled. */ - /* */ + /************************************************************************** + * + * @Function: + * TT_Process_Composite_Glyph + * + * @Description: + * This is slightly different from TT_Process_Simple_Glyph, in that + * its sole purpose is to hint the glyph. Thus this function is + * only available when bytecode interpreter is enabled. + */ static FT_Error TT_Process_Composite_Glyph( TT_Loader loader, FT_UInt start_point, @@ -1460,7 +1473,7 @@ } #endif - use_aw_2 = (FT_Bool)( subpixel_hinting && grayscale ); + use_aw_2 = FT_BOOL( subpixel_hinting && grayscale ); loader->pp1.x = loader->bbox.xMin - loader->left_bearing; loader->pp1.y = 0; @@ -1497,27 +1510,28 @@ } - /*************************************************************************/ - /* */ - /* */ - /* load_truetype_glyph */ - /* */ - /* */ - /* Loads a given truetype glyph. Handles composites and uses a */ - /* TT_Loader object. */ - /* */ + /************************************************************************** + * + * @Function: + * load_truetype_glyph + * + * @Description: + * Loads a given truetype glyph. Handles composites and uses a + * TT_Loader object. + */ static FT_Error load_truetype_glyph( TT_Loader loader, FT_UInt glyph_index, FT_UInt recurse_count, FT_Bool header_only ) { - FT_Error error = FT_Err_Ok; + FT_Error error = FT_Err_Ok; FT_Fixed x_scale, y_scale; FT_ULong offset; - TT_Face face = loader->face; - FT_GlyphLoader gloader = loader->gloader; - FT_Bool opened_frame = 0; + TT_Face face = loader->face; + FT_GlyphLoader gloader = loader->gloader; + + FT_Bool opened_frame = 0; #ifdef FT_CONFIG_OPTION_INCREMENTAL FT_StreamRec inc_stream; @@ -1550,15 +1564,15 @@ loader->glyph_index = glyph_index; - if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) + if ( loader->load_flags & FT_LOAD_NO_SCALE ) { - x_scale = loader->size->metrics->x_scale; - y_scale = loader->size->metrics->y_scale; + x_scale = 0x10000L; + y_scale = 0x10000L; } else { - x_scale = 0x10000L; - y_scale = 0x10000L; + x_scale = loader->size->metrics->x_scale; + y_scale = loader->size->metrics->y_scale; } /* Set `offset' to the start of the glyph relative to the start of */ @@ -1617,38 +1631,36 @@ if ( error ) goto Exit; - opened_frame = 1; - /* read glyph header first */ error = face->read_glyph_header( loader ); - if ( error ) - goto Exit; - /* the metrics must be computed after loading the glyph header */ - /* since we need the glyph's `yMax' value in case the vertical */ - /* metrics must be emulated */ - error = tt_get_metrics( loader, glyph_index ); - if ( error ) - goto Exit; + face->forget_glyph_frame( loader ); - if ( header_only ) + if ( error ) goto Exit; } + /* a space glyph */ if ( loader->byte_len == 0 || loader->n_contours == 0 ) { loader->bbox.xMin = 0; loader->bbox.xMax = 0; loader->bbox.yMin = 0; loader->bbox.yMax = 0; + } - error = tt_get_metrics( loader, glyph_index ); - if ( error ) - goto Exit; + /* the metrics must be computed after loading the glyph header */ + /* since we need the glyph's `yMax' value in case the vertical */ + /* metrics must be emulated */ + error = tt_get_metrics( loader, glyph_index ); + if ( error ) + goto Exit; - if ( header_only ) - goto Exit; + if ( header_only ) + goto Exit; + if ( loader->byte_len == 0 || loader->n_contours == 0 ) + { /* must initialize points before (possibly) overriding */ /* glyph metrics from the incremental interface */ tt_loader_set_pp( loader ); @@ -1704,7 +1716,6 @@ loader->pp4.x = points[3].x; loader->pp4.y = points[3].y; - /* recalculate linear horizontal and vertical advances */ /* if we don't have HVAR and VVAR, respectively */ if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ) @@ -1745,6 +1756,16 @@ /***********************************************************************/ /***********************************************************************/ + /* we now open a frame again, right after the glyph header */ + /* (which consists of 10 bytes) */ + error = face->access_glyph_frame( loader, glyph_index, + face->glyf_offset + offset + 10, + (FT_UInt)loader->byte_len - 10 ); + if ( error ) + goto Exit; + + opened_frame = 1; + /* if it is a simple glyph, load it */ if ( loader->n_contours > 0 ) @@ -1790,7 +1811,6 @@ * pointers with a width of at least 32 bits. */ - /* clear the nodes filled by sibling chains */ node = ft_list_get_node_at( &loader->composites, recurse_count ); for ( node2 = node; node2; node2 = node2->next ) @@ -2002,7 +2022,7 @@ FT_Int linear_vadvance; - /* Each time we call load_truetype_glyph in this loop, the */ + /* Each time we call `load_truetype_glyph' in this loop, the */ /* value of `gloader.base.subglyphs' can change due to table */ /* reallocations. We thus need to recompute the subglyph */ /* pointer on each iteration. */ @@ -2045,12 +2065,14 @@ if ( num_points == num_base_points ) continue; - /* gloader->base.outline consists of three parts: */ - /* 0 -(1)-> start_point -(2)-> num_base_points -(3)-> n_points. */ - /* */ - /* (1): exists from the beginning */ - /* (2): components that have been loaded so far */ - /* (3): the newly loaded component */ + /* gloader->base.outline consists of three parts: */ + /* */ + /* 0 ----> start_point ----> num_base_points ----> n_points */ + /* (1) (2) (3) */ + /* */ + /* (1) points that exist from the beginning */ + /* (2) component points that have been loaded so far */ + /* (3) points of the newly loaded component */ error = TT_Process_Composite_Component( loader, subglyph, start_point, @@ -2132,7 +2154,7 @@ glyph->metrics.horiBearingX = bbox.xMin; glyph->metrics.horiBearingY = bbox.yMax; - glyph->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; + glyph->metrics.horiAdvance = SUB_LONG(loader->pp2.x, loader->pp1.x); /* Adjust advance width to the value contained in the hdmx table */ /* unless FT_LOAD_COMPUTE_METRICS is set or backward compatibility */ @@ -2276,13 +2298,13 @@ /* XXX: for now, we have no better algorithm for the lsb, but it */ /* should work fine. */ /* */ - glyph->metrics.vertBearingX = glyph->metrics.horiBearingX - - glyph->metrics.horiAdvance / 2; + glyph->metrics.vertBearingX = SUB_LONG( glyph->metrics.horiBearingX, + glyph->metrics.horiAdvance / 2 ); glyph->metrics.vertBearingY = top; glyph->metrics.vertAdvance = advance; } - return 0; + return FT_Err_Ok; } @@ -2656,33 +2678,37 @@ } - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Glyph */ - /* */ - /* */ - /* A function used to load a single glyph within a given glyph slot, */ - /* for a given size. */ - /* */ - /* */ - /* glyph :: A handle to a target slot object where the glyph */ - /* will be loaded. */ - /* */ - /* size :: A handle to the source face size at which the glyph */ - /* must be scaled/loaded. */ - /* */ - /* glyph_index :: The index of the glyph in the font file. */ - /* */ - /* load_flags :: A flag indicating what to load for this glyph. The */ - /* FT_LOAD_XXX constants can be used to control the */ - /* glyph loading process (e.g., whether the outline */ - /* should be scaled, whether to load bitmaps or not, */ - /* whether to hint the outline, etc). */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * TT_Load_Glyph + * + * @Description: + * A function used to load a single glyph within a given glyph slot, + * for a given size. + * + * @Input: + * glyph :: + * A handle to a target slot object where the glyph + * will be loaded. + * + * size :: + * A handle to the source face size at which the glyph + * must be scaled/loaded. + * + * glyph_index :: + * The index of the glyph in the font file. + * + * load_flags :: + * A flag indicating what to load for this glyph. The + * FT_LOAD_XXX constants can be used to control the + * glyph loading process (e.g., whether the outline + * should be scaled, whether to load bitmaps or not, + * whether to hint the outline, etc). + * + * @Return: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) TT_Load_Glyph( TT_Size size, TT_GlyphSlot glyph, @@ -2709,6 +2735,10 @@ ( load_flags & FT_LOAD_NO_BITMAP ) == 0 && IS_DEFAULT_INSTANCE ) { + FT_Fixed x_scale = size->root.metrics.x_scale; + FT_Fixed y_scale = size->root.metrics.y_scale; + + error = load_sbit_image( size, glyph, glyph_index, load_flags ); if ( FT_ERR_EQ( error, Missing_Bitmap ) ) { @@ -2716,9 +2746,13 @@ /* if we have a bitmap-only font, return an empty glyph */ if ( !FT_IS_SCALABLE( glyph->face ) ) { - TT_Face face = (TT_Face)glyph->face; - FT_Short left_bearing = 0, top_bearing = 0; - FT_UShort advance_width = 0, advance_height = 0; + TT_Face face = (TT_Face)glyph->face; + + FT_Short left_bearing = 0; + FT_Short top_bearing = 0; + + FT_UShort advance_width = 0; + FT_UShort advance_height = 0; /* to return an empty glyph, however, we need metrics data */ @@ -2744,13 +2778,13 @@ glyph->metrics.width = 0; glyph->metrics.height = 0; - glyph->metrics.horiBearingX = left_bearing; + glyph->metrics.horiBearingX = FT_MulFix( left_bearing, x_scale ); glyph->metrics.horiBearingY = 0; - glyph->metrics.horiAdvance = advance_width; + glyph->metrics.horiAdvance = FT_MulFix( advance_width, x_scale ); glyph->metrics.vertBearingX = 0; - glyph->metrics.vertBearingY = top_bearing; - glyph->metrics.vertAdvance = advance_height; + glyph->metrics.vertBearingY = FT_MulFix( top_bearing, y_scale ); + glyph->metrics.vertAdvance = FT_MulFix( advance_height, y_scale ); glyph->format = FT_GLYPH_FORMAT_BITMAP; glyph->bitmap.pixel_mode = FT_PIXEL_MODE_MONO; @@ -2781,13 +2815,11 @@ /* sanity checks: if `xxxAdvance' in the sbit metric */ /* structure isn't set, use `linearXXXAdvance' */ if ( !glyph->metrics.horiAdvance && glyph->linearHoriAdvance ) - glyph->metrics.horiAdvance = - FT_MulFix( glyph->linearHoriAdvance, - size->metrics->x_scale ); + glyph->metrics.horiAdvance = FT_MulFix( glyph->linearHoriAdvance, + x_scale ); if ( !glyph->metrics.vertAdvance && glyph->linearVertAdvance ) - glyph->metrics.vertAdvance = - FT_MulFix( glyph->linearVertAdvance, - size->metrics->y_scale ); + glyph->metrics.vertAdvance = FT_MulFix( glyph->linearVertAdvance, + y_scale ); } return FT_Err_Ok; diff --git a/sdk/lib/3rdparty/freetype/src/truetype/ttgload.h b/sdk/lib/3rdparty/freetype/src/truetype/ttgload.h index d237cfd284175..f1324bc8621a4 100644 --- a/sdk/lib/3rdparty/freetype/src/truetype/ttgload.h +++ b/sdk/lib/3rdparty/freetype/src/truetype/ttgload.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ttgload.h */ -/* */ -/* TrueType Glyph Loader (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ttgload.h + * + * TrueType Glyph Loader (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef TTGLOAD_H_ diff --git a/sdk/lib/3rdparty/freetype/src/truetype/ttgxvar.c b/sdk/lib/3rdparty/freetype/src/truetype/ttgxvar.c index 6f456cf8c410e..020918f53368e 100644 --- a/sdk/lib/3rdparty/freetype/src/truetype/ttgxvar.c +++ b/sdk/lib/3rdparty/freetype/src/truetype/ttgxvar.c @@ -1,42 +1,42 @@ -/***************************************************************************/ -/* */ -/* ttgxvar.c */ -/* */ -/* TrueType GX Font Variation loader */ -/* */ -/* Copyright 2004-2018 by */ -/* David Turner, Robert Wilhelm, Werner Lemberg, and George Williams. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* Apple documents the `fvar', `gvar', `cvar', and `avar' tables at */ - /* */ - /* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6[fgca]var.html */ - /* */ - /* The documentation for `gvar' is not intelligible; `cvar' refers you */ - /* to `gvar' and is thus also incomprehensible. */ - /* */ - /* The documentation for `avar' appears correct, but Apple has no fonts */ - /* with an `avar' table, so it is hard to test. */ - /* */ - /* Many thanks to John Jenkins (at Apple) in figuring this out. */ - /* */ - /* */ - /* Apple's `kern' table has some references to tuple indices, but as */ - /* there is no indication where these indices are defined, nor how to */ - /* interpolate the kerning values (different tuples have different */ - /* classes) this issue is ignored. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * ttgxvar.c + * + * TrueType GX Font Variation loader + * + * Copyright (C) 2004-2019 by + * David Turner, Robert Wilhelm, Werner Lemberg, and George Williams. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /************************************************************************** + * + * Apple documents the `fvar', `gvar', `cvar', and `avar' tables at + * + * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6[fgca]var.html + * + * The documentation for `gvar' is not intelligible; `cvar' refers you + * to `gvar' and is thus also incomprehensible. + * + * The documentation for `avar' appears correct, but Apple has no fonts + * with an `avar' table, so it is hard to test. + * + * Many thanks to John Jenkins (at Apple) in figuring this out. + * + * + * Apple's `kern' table has some references to tuple indices, but as + * there is no indication where these indices are defined, nor how to + * interpolate the kerning values (different tuples have different + * classes) this issue is ignored. + * + */ #include @@ -67,14 +67,23 @@ : (stream)->limit - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /* some macros we need */ +#define FT_fdot14ToFixed( x ) \ + ( (FT_Fixed)( (FT_ULong)(x) << 2 ) ) +#define FT_intToFixed( i ) \ + ( (FT_Fixed)( (FT_ULong)(i) << 16 ) ) +#define FT_fixedToInt( x ) \ + ( (FT_Short)( ( (FT_UInt32)(x) + 0x8000U ) >> 16 ) ) + + + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_ttgxvar +#define FT_COMPONENT ttgxvar /*************************************************************************/ @@ -86,12 +95,12 @@ /*************************************************************************/ - /*************************************************************************/ - /* */ - /* The macro ALL_POINTS is used in `ft_var_readpackedpoints'. It */ - /* indicates that there is a delta for every point without needing to */ - /* enumerate all of them. */ - /* */ + /************************************************************************** + * + * The macro ALL_POINTS is used in `ft_var_readpackedpoints'. It + * indicates that there is a delta for every point without needing to + * enumerate all of them. + */ /* ensure that value `0' has the same width as a pointer */ #define ALL_POINTS (FT_UShort*)~(FT_PtrDist)0 @@ -101,29 +110,32 @@ #define GX_PT_POINT_RUN_COUNT_MASK 0x7FU - /*************************************************************************/ - /* */ - /* */ - /* ft_var_readpackedpoints */ - /* */ - /* */ - /* Read a set of points to which the following deltas will apply. */ - /* Points are packed with a run length encoding. */ - /* */ - /* */ - /* stream :: The data stream. */ - /* */ - /* size :: The size of the table holding the data. */ - /* */ - /* */ - /* point_cnt :: The number of points read. A zero value means that */ - /* all points in the glyph will be affected, without */ - /* enumerating them individually. */ - /* */ - /* */ - /* An array of FT_UShort containing the affected points or the */ - /* special value ALL_POINTS. */ - /* */ + /************************************************************************** + * + * @Function: + * ft_var_readpackedpoints + * + * @Description: + * Read a set of points to which the following deltas will apply. + * Points are packed with a run length encoding. + * + * @Input: + * stream :: + * The data stream. + * + * size :: + * The size of the table holding the data. + * + * @Output: + * point_cnt :: + * The number of points read. A zero value means that + * all points in the glyph will be affected, without + * enumerating them individually. + * + * @Return: + * An array of FT_UShort containing the affected points or the + * special value ALL_POINTS. + */ static FT_UShort* ft_var_readpackedpoints( FT_Stream stream, FT_ULong size, @@ -211,34 +223,41 @@ #define GX_DT_DELTA_RUN_COUNT_MASK 0x3FU - /*************************************************************************/ - /* */ - /* */ - /* ft_var_readpackeddeltas */ - /* */ - /* */ - /* Read a set of deltas. These are packed slightly differently than */ - /* points. In particular there is no overall count. */ - /* */ - /* */ - /* stream :: The data stream. */ - /* */ - /* size :: The size of the table holding the data. */ - /* */ - /* delta_cnt :: The number of deltas to be read. */ - /* */ - /* */ - /* An array of FT_Short containing the deltas for the affected */ - /* points. (This only gets the deltas for one dimension. It will */ - /* generally be called twice, once for x, once for y. When used in */ - /* cvt table, it will only be called once.) */ - /* */ - static FT_Short* + /************************************************************************** + * + * @Function: + * ft_var_readpackeddeltas + * + * @Description: + * Read a set of deltas. These are packed slightly differently than + * points. In particular there is no overall count. + * + * @Input: + * stream :: + * The data stream. + * + * size :: + * The size of the table holding the data. + * + * delta_cnt :: + * The number of deltas to be read. + * + * @Return: + * An array of FT_Fixed containing the deltas for the affected + * points. (This only gets the deltas for one dimension. It will + * generally be called twice, once for x, once for y. When used in + * cvt table, it will only be called once.) + * + * We use FT_Fixed to avoid accumulation errors while summing up all + * deltas (the rounding to integer values happens as the very last + * step). + */ + static FT_Fixed* ft_var_readpackeddeltas( FT_Stream stream, FT_ULong size, FT_UInt delta_cnt ) { - FT_Short *deltas = NULL; + FT_Fixed *deltas = NULL; FT_UInt runcnt, cnt; FT_UInt i, j; FT_Memory memory = stream->memory; @@ -272,13 +291,13 @@ { /* `runcnt' shorts from the stack */ for ( j = 0; j <= cnt && i < delta_cnt; j++ ) - deltas[i++] = FT_GET_SHORT(); + deltas[i++] = FT_intToFixed( FT_GET_SHORT() ); } else { /* `runcnt' signed bytes from the stack */ for ( j = 0; j <= cnt && i < delta_cnt; j++ ) - deltas[i++] = FT_GET_CHAR(); + deltas[i++] = FT_intToFixed( FT_GET_CHAR() ); } if ( j <= cnt ) @@ -293,18 +312,19 @@ } - /*************************************************************************/ - /* */ - /* */ - /* ft_var_load_avar */ - /* */ - /* */ - /* Parse the `avar' table if present. It need not be, so we return */ - /* nothing. */ - /* */ - /* */ - /* face :: The font face. */ - /* */ + /************************************************************************** + * + * @Function: + * ft_var_load_avar + * + * @Description: + * Parse the `avar' table if present. It need not be, so we return + * nothing. + * + * @InOut: + * face :: + * The font face. + */ static void ft_var_load_avar( TT_Face face ) { @@ -394,17 +414,6 @@ } - /* some macros we need */ -#define FT_FIXED_ONE ( (FT_Fixed)0x10000 ) - -#define FT_fdot14ToFixed( x ) \ - ( (FT_Fixed)( (FT_ULong)(x) << 2 ) ) -#define FT_intToFixed( i ) \ - ( (FT_Fixed)( (FT_ULong)(i) << 16 ) ) -#define FT_fixedToInt( x ) \ - ( (FT_Short)( ( (FT_UInt32)(x) + 0x8000U ) >> 16 ) ) - - static FT_Error ft_var_load_item_variation_store( TT_Face face, FT_ULong offset, @@ -702,29 +711,30 @@ } - /*************************************************************************/ - /* */ - /* */ - /* ft_var_load_hvvar */ - /* */ - /* */ - /* If `vertical' is zero, parse the `HVAR' table and set */ - /* `blend->hvar_loaded' to TRUE. On success, `blend->hvar_checked' */ - /* is set to TRUE. */ - /* */ - /* If `vertical' is not zero, parse the `VVAR' table and set */ - /* `blend->vvar_loaded' to TRUE. On success, `blend->vvar_checked' */ - /* is set to TRUE. */ - /* */ - /* Some memory may remain allocated on error; it is always freed in */ - /* `tt_done_blend', however. */ - /* */ - /* */ - /* face :: The font face. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * ft_var_load_hvvar + * + * @Description: + * If `vertical' is zero, parse the `HVAR' table and set + * `blend->hvar_loaded' to TRUE. On success, `blend->hvar_checked' + * is set to TRUE. + * + * If `vertical' is not zero, parse the `VVAR' table and set + * `blend->vvar_loaded' to TRUE. On success, `blend->vvar_checked' + * is set to TRUE. + * + * Some memory may remain allocated on error; it is always freed in + * `tt_done_blend', however. + * + * @InOut: + * face :: + * The font face. + * + * @Return: + * FreeType error code. 0 means success. + */ static FT_Error ft_var_load_hvvar( TT_Face face, FT_Bool vertical ) @@ -872,7 +882,7 @@ /* outer loop steps through master designs to be blended */ for ( master = 0; master < varData->regionIdxCount; master++ ) { - FT_Fixed scalar = FT_FIXED_ONE; + FT_Fixed scalar = 0x10000L; FT_UInt regionIndex = varData->regionIndices[master]; GX_AxisCoords axis = itemStore->varRegionList[regionIndex].axisList; @@ -881,47 +891,43 @@ /* inner loop steps through axes in this region */ for ( j = 0; j < itemStore->axisCount; j++, axis++ ) { - FT_Fixed axisScalar; - - /* compute the scalar contribution of this axis; */ /* ignore invalid ranges */ if ( axis->startCoord > axis->peakCoord || axis->peakCoord > axis->endCoord ) - axisScalar = FT_FIXED_ONE; + continue; else if ( axis->startCoord < 0 && axis->endCoord > 0 && axis->peakCoord != 0 ) - axisScalar = FT_FIXED_ONE; + continue; /* peak of 0 means ignore this axis */ else if ( axis->peakCoord == 0 ) - axisScalar = FT_FIXED_ONE; + continue; - /* ignore this region if coords are out of range */ - else if ( face->blend->normalizedcoords[j] < axis->startCoord || - face->blend->normalizedcoords[j] > axis->endCoord ) - axisScalar = 0; + else if ( face->blend->normalizedcoords[j] == axis->peakCoord ) + continue; - /* calculate a proportional factor */ - else + /* ignore this region if coords are out of range */ + else if ( face->blend->normalizedcoords[j] <= axis->startCoord || + face->blend->normalizedcoords[j] >= axis->endCoord ) { - if ( face->blend->normalizedcoords[j] == axis->peakCoord ) - axisScalar = FT_FIXED_ONE; - else if ( face->blend->normalizedcoords[j] < axis->peakCoord ) - axisScalar = - FT_DivFix( face->blend->normalizedcoords[j] - axis->startCoord, - axis->peakCoord - axis->startCoord ); - else - axisScalar = - FT_DivFix( axis->endCoord - face->blend->normalizedcoords[j], - axis->endCoord - axis->peakCoord ); + scalar = 0; + break; } - /* take product of all the axis scalars */ - scalar = FT_MulFix( scalar, axisScalar ); - + /* cumulative product of all the axis scalars */ + else if ( face->blend->normalizedcoords[j] < axis->peakCoord ) + scalar = + FT_MulDiv( scalar, + face->blend->normalizedcoords[j] - axis->startCoord, + axis->peakCoord - axis->startCoord ); + else + scalar = + FT_MulDiv( scalar, + axis->endCoord - face->blend->normalizedcoords[j], + axis->endCoord - axis->peakCoord ); } /* per-axis loop */ /* get the scaled delta for this region */ @@ -937,25 +943,29 @@ } - /*************************************************************************/ - /* */ - /* */ - /* tt_hvadvance_adjust */ - /* */ - /* */ - /* Apply `HVAR' advance width or `VVAR' advance height adjustment of */ - /* a given glyph. */ - /* */ - /* */ - /* gindex :: The glyph index. */ - /* */ - /* vertical :: If set, handle `VVAR' table. */ - /* */ - /* */ - /* face :: The font face. */ - /* */ - /* adelta :: Points to width or height value that gets modified. */ - /* */ + /************************************************************************** + * + * @Function: + * tt_hvadvance_adjust + * + * @Description: + * Apply `HVAR' advance width or `VVAR' advance height adjustment of + * a given glyph. + * + * @Input: + * gindex :: + * The glyph index. + * + * vertical :: + * If set, handle `VVAR' table. + * + * @InOut: + * face :: + * The font face. + * + * adelta :: + * Points to width or height value that gets modified. + */ static FT_Error tt_hvadvance_adjust( TT_Face face, FT_UInt gindex, @@ -1151,20 +1161,21 @@ } - /*************************************************************************/ - /* */ - /* */ - /* ft_var_load_mvar */ - /* */ - /* */ - /* Parse the `MVAR' table. */ - /* */ - /* Some memory may remain allocated on error; it is always freed in */ - /* `tt_done_blend', however. */ - /* */ - /* */ - /* face :: The font face. */ - /* */ + /************************************************************************** + * + * @Function: + * ft_var_load_mvar + * + * @Description: + * Parse the `MVAR' table. + * + * Some memory may remain allocated on error; it is always freed in + * `tt_done_blend', however. + * + * @InOut: + * face :: + * The font face. + */ static void ft_var_load_mvar( TT_Face face ) { @@ -1297,22 +1308,26 @@ } - /*************************************************************************/ - /* */ - /* */ - /* tt_apply_mvar */ - /* */ - /* */ - /* Apply `MVAR' table adjustments. */ - /* */ - /* */ - /* face :: The font face. */ - /* */ + /************************************************************************** + * + * @Function: + * tt_apply_mvar + * + * @Description: + * Apply `MVAR' table adjustments. + * + * @InOut: + * face :: + * The font face. + */ FT_LOCAL_DEF( void ) tt_apply_mvar( TT_Face face ) { GX_Blend blend = face->blend; GX_Value value, limit; + FT_Short mvar_hasc_delta = 0; + FT_Short mvar_hdsc_delta = 0; + FT_Short mvar_hlgp_delta = 0; if ( !( face->variation_support & TT_FACE_FLAG_VAR_MVAR ) ) @@ -1347,6 +1362,14 @@ /* since we handle both signed and unsigned values as FT_Short, */ /* ensure proper overflow arithmetic */ *p = (FT_Short)( value->unmodified + (FT_Short)delta ); + + /* Treat hasc, hdsc and hlgp specially, see below. */ + if ( value->tag == MVAR_TAG_HASC ) + mvar_hasc_delta = (FT_Short)delta; + else if ( value->tag == MVAR_TAG_HDSC ) + mvar_hdsc_delta = (FT_Short)delta; + else if ( value->tag == MVAR_TAG_HLGP ) + mvar_hlgp_delta = (FT_Short)delta; } } @@ -1354,25 +1377,40 @@ { FT_Face root = &face->root; - - if ( face->os2.version != 0xFFFFU ) - { - if ( face->os2.sTypoAscender || face->os2.sTypoDescender ) - { - root->ascender = face->os2.sTypoAscender; - root->descender = face->os2.sTypoDescender; - - root->height = root->ascender - root->descender + - face->os2.sTypoLineGap; - } - else - { - root->ascender = (FT_Short)face->os2.usWinAscent; - root->descender = -(FT_Short)face->os2.usWinDescent; - - root->height = root->ascender - root->descender; - } - } + /* + * Apply the deltas of hasc, hdsc and hlgp to the FT_Face's ascender, + * descender and height attributes, no matter how they were originally + * computed. + * + * (Code that ignores those and accesses the font's metrics values + * directly is already served by the delta application code above.) + * + * The MVAR table supports variations for both typo and win metrics. + * According to Behdad Esfahbod, the thinking of the working group was + * that no one uses win metrics anymore for setting line metrics (the + * specification even calls these metrics "horizontal clipping + * ascent/descent", probably for their role on the Windows platform in + * computing clipping boxes), and new fonts should use typo metrics, so + * typo deltas should be applied to whatever sfnt_load_face decided the + * line metrics should be. + * + * Before, the following led to different line metrics between default + * outline and instances, visible when e.g. the default outlines were + * used as the regular face and instances for everything else: + * + * 1. sfnt_load_face applied the hhea metrics by default. + * 2. This code later applied the typo metrics by default, regardless of + * whether they were actually changed or the font had the OS/2 table's + * fsSelection's bit 7 (USE_TYPO_METRICS) set. + */ + FT_Short current_line_gap = root->height - root->ascender + + root->descender; + + + root->ascender = root->ascender + mvar_hasc_delta; + root->descender = root->descender + mvar_hdsc_delta; + root->height = root->ascender - root->descender + + current_line_gap + mvar_hlgp_delta; root->underline_position = face->postscript.underlinePosition - face->postscript.underlineThickness / 2; @@ -1400,21 +1438,22 @@ } GX_GVar_Head; - /*************************************************************************/ - /* */ - /* */ - /* ft_var_load_gvar */ - /* */ - /* */ - /* Parse the `gvar' table if present. If `fvar' is there, `gvar' had */ - /* better be there too. */ - /* */ - /* */ - /* face :: The font face. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * ft_var_load_gvar + * + * @Description: + * Parse the `gvar' table if present. If `fvar' is there, `gvar' had + * better be there too. + * + * @InOut: + * face :: + * The font face. + * + * @Return: + * FreeType error code. 0 means success. + */ static FT_Error ft_var_load_gvar( TT_Face face ) { @@ -1512,28 +1551,55 @@ if ( gvar_head.flags & 1 ) { + FT_ULong limit = gvar_start + table_len; + + /* long offsets (one more offset than glyphs, to mark size of last) */ if ( FT_FRAME_ENTER( ( blend->gv_glyphcnt + 1 ) * 4L ) ) goto Exit; for ( i = 0; i <= blend->gv_glyphcnt; i++ ) + { blend->glyphoffsets[i] = offsetToData + FT_GET_ULONG(); - - FT_FRAME_EXIT(); + /* use `>', not `>=' */ + if ( blend->glyphoffsets[i] > limit ) + { + FT_TRACE2(( "ft_var_load_gvar:" + " invalid glyph variation data offset for index %d\n", + i )); + error = FT_THROW( Invalid_Table ); + break; + } + } } else { + FT_ULong limit = gvar_start + table_len; + + /* short offsets (one more offset than glyphs, to mark size of last) */ if ( FT_FRAME_ENTER( ( blend->gv_glyphcnt + 1 ) * 2L ) ) goto Exit; for ( i = 0; i <= blend->gv_glyphcnt; i++ ) + { blend->glyphoffsets[i] = offsetToData + FT_GET_USHORT() * 2; - /* XXX: Undocumented: `*2'! */ - - FT_FRAME_EXIT(); + /* use `>', not `>=' */ + if ( blend->glyphoffsets[i] > limit ) + { + FT_TRACE2(( "ft_var_load_gvar:" + " invalid glyph variation data offset for index %d\n", + i )); + error = FT_THROW( Invalid_Table ); + break; + } + } } + FT_FRAME_EXIT(); + if ( error ) + goto Exit; + if ( blend->tuplecount != 0 ) { if ( FT_NEW_ARRAY( blend->tuplecoords, @@ -1567,33 +1633,38 @@ } - /*************************************************************************/ - /* */ - /* */ - /* ft_var_apply_tuple */ - /* */ - /* */ - /* Figure out whether a given tuple (design) applies to the current */ - /* blend, and if so, what is the scaling factor. */ - /* */ - /* */ - /* blend :: The current blend of the font. */ - /* */ - /* tupleIndex :: A flag saying whether this is an intermediate */ - /* tuple or not. */ - /* */ - /* tuple_coords :: The coordinates of the tuple in normalized axis */ - /* units. */ - /* */ - /* im_start_coords :: The initial coordinates where this tuple starts */ - /* to apply (for intermediate coordinates). */ - /* */ - /* im_end_coords :: The final coordinates after which this tuple no */ - /* longer applies (for intermediate coordinates). */ - /* */ - /* */ - /* An FT_Fixed value containing the scaling factor. */ - /* */ + /************************************************************************** + * + * @Function: + * ft_var_apply_tuple + * + * @Description: + * Figure out whether a given tuple (design) applies to the current + * blend, and if so, what is the scaling factor. + * + * @Input: + * blend :: + * The current blend of the font. + * + * tupleIndex :: + * A flag saying whether this is an intermediate + * tuple or not. + * + * tuple_coords :: + * The coordinates of the tuple in normalized axis + * units. + * + * im_start_coords :: + * The initial coordinates where this tuple starts + * to apply (for intermediate coordinates). + * + * im_end_coords :: + * The final coordinates after which this tuple no + * longer applies (for intermediate coordinates). + * + * @Return: + * An FT_Fixed value containing the scaling factor. + */ static FT_Fixed ft_var_apply_tuple( GX_Blend blend, FT_UShort tupleIndex, @@ -1607,13 +1678,8 @@ for ( i = 0; i < blend->num_axis; i++ ) { - FT_TRACE6(( " axis coordinate %d (%.5f):\n", + FT_TRACE6(( " axis %d coordinate %.5f:\n", i, blend->normalizedcoords[i] / 65536.0 )); - if ( !( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) ) - FT_TRACE6(( " intermediate coordinates %d (%.5f, %.5f):\n", - i, - im_start_coords[i] / 65536.0, - im_end_coords[i] / 65536.0 )); /* It's not clear why (for intermediate tuples) we don't need */ /* to check against start/end -- the documentation says we don't. */ @@ -1622,7 +1688,7 @@ if ( tuple_coords[i] == 0 ) { - FT_TRACE6(( " tuple coordinate is zero, ignored\n", i )); + FT_TRACE6(( " tuple coordinate is zero, ignore\n", i )); continue; } @@ -1635,7 +1701,7 @@ if ( blend->normalizedcoords[i] == tuple_coords[i] ) { - FT_TRACE6(( " tuple coordinate value %.5f fits perfectly\n", + FT_TRACE6(( " tuple coordinate %.5f fits perfectly\n", tuple_coords[i] / 65536.0 )); /* `apply' does not change */ continue; @@ -1648,13 +1714,13 @@ if ( blend->normalizedcoords[i] < FT_MIN( 0, tuple_coords[i] ) || blend->normalizedcoords[i] > FT_MAX( 0, tuple_coords[i] ) ) { - FT_TRACE6(( " tuple coordinate value %.5f is exceeded, stop\n", + FT_TRACE6(( " tuple coordinate %.5f is exceeded, stop\n", tuple_coords[i] / 65536.0 )); apply = 0; break; } - FT_TRACE6(( " tuple coordinate value %.5f fits\n", + FT_TRACE6(( " tuple coordinate %.5f fits\n", tuple_coords[i] / 65536.0 )); apply = FT_MulDiv( apply, blend->normalizedcoords[i], @@ -1664,10 +1730,10 @@ { /* intermediate tuple */ - if ( blend->normalizedcoords[i] < im_start_coords[i] || - blend->normalizedcoords[i] > im_end_coords[i] ) + if ( blend->normalizedcoords[i] <= im_start_coords[i] || + blend->normalizedcoords[i] >= im_end_coords[i] ) { - FT_TRACE6(( " intermediate tuple range [%.5f;%.5f] is exceeded," + FT_TRACE6(( " intermediate tuple range ]%.5f;%.5f[ is exceeded," " stop\n", im_start_coords[i] / 65536.0, im_end_coords[i] / 65536.0 )); @@ -1675,25 +1741,17 @@ break; } - else if ( blend->normalizedcoords[i] < tuple_coords[i] ) - { - FT_TRACE6(( " intermediate tuple range [%.5f;%.5f] fits\n", - im_start_coords[i] / 65536.0, - im_end_coords[i] / 65536.0 )); + FT_TRACE6(( " intermediate tuple range ]%.5f;%.5f[ fits\n", + im_start_coords[i] / 65536.0, + im_end_coords[i] / 65536.0 )); + if ( blend->normalizedcoords[i] < tuple_coords[i] ) apply = FT_MulDiv( apply, blend->normalizedcoords[i] - im_start_coords[i], tuple_coords[i] - im_start_coords[i] ); - } - else - { - FT_TRACE6(( " intermediate tuple range [%.5f;%.5f] fits\n", - im_start_coords[i] / 65536.0, - im_end_coords[i] / 65536.0 )); apply = FT_MulDiv( apply, im_end_coords[i] - blend->normalizedcoords[i], im_end_coords[i] - tuple_coords[i] ); - } } } @@ -1733,17 +1791,13 @@ /* based on the [min,def,max] values for the axis to be [-1,0,1]. */ /* Then, if there's an `avar' table, we renormalize this range. */ - FT_TRACE5(( "%d design coordinate%s:\n", - num_coords, - num_coords == 1 ? "" : "s" )); - a = mmvar->axis; for ( i = 0; i < num_coords; i++, a++ ) { FT_Fixed coord = coords[i]; - FT_TRACE5(( " %.5f\n", coord / 65536.0 )); + FT_TRACE5(( " %d: %.5f\n", i, coord / 65536.0 )); if ( coord > a->maximum || coord < a->minimum ) { FT_TRACE1(( @@ -1760,11 +1814,11 @@ } if ( coord < a->def ) - normalized[i] = -FT_DivFix( coord - a->def, - a->minimum - a->def ); + normalized[i] = -FT_DivFix( SUB_LONG( coord, a->def ), + SUB_LONG( a->minimum, a->def ) ); else if ( coord > a->def ) - normalized[i] = FT_DivFix( coord - a->def, - a->maximum - a->def ); + normalized[i] = FT_DivFix( SUB_LONG( coord, a->def ), + SUB_LONG( a->maximum, a->def ) ); else normalized[i] = 0; } @@ -1914,27 +1968,29 @@ } GX_FVar_Axis; - /*************************************************************************/ - /* */ - /* */ - /* TT_Get_MM_Var */ - /* */ - /* */ - /* Check that the font's `fvar' table is valid, parse it, and return */ - /* those data. It also loads (and parses) the `MVAR' table, if */ - /* possible. */ - /* */ - /* */ - /* face :: The font face. */ - /* TT_Get_MM_Var initializes the blend structure. */ - /* */ - /* */ - /* master :: The `fvar' data (must be freed by caller). Can be NULL, */ - /* which makes this function simply load MM support. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * TT_Get_MM_Var + * + * @Description: + * Check that the font's `fvar' table is valid, parse it, and return + * those data. It also loads (and parses) the `MVAR' table, if + * possible. + * + * @InOut: + * face :: + * The font face. + * TT_Get_MM_Var initializes the blend structure. + * + * @Output: + * master :: + * The `fvar' data (must be freed by caller). Can be NULL, + * which makes this function simply load MM support. + * + * @Return: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) TT_Get_MM_Var( TT_Face face, FT_MM_Var* *master ) @@ -2043,12 +2099,15 @@ FT_TRACE2(( "loaded\n" )); - FT_TRACE5(( "number of GX style axes: %d\n", fvar_head.axisCount )); + FT_TRACE5(( "%d variation ax%s\n", + fvar_head.axisCount, + fvar_head.axisCount == 1 ? "is" : "es" )); if ( FT_NEW( face->blend ) ) goto Exit; - num_axes = fvar_head.axisCount; + num_axes = fvar_head.axisCount; + face->blend->num_axis = num_axes; } else num_axes = face->blend->num_axis; @@ -2142,6 +2201,10 @@ { GX_FVar_Axis axis_rec; +#ifdef FT_DEBUG_LEVEL_TRACE + int invalid = 0; +#endif + if ( FT_STREAM_READ_FIELDS( fvaraxis_fields, &axis_rec ) ) goto Exit; @@ -2162,22 +2225,31 @@ if ( a->minimum > a->def || a->def > a->maximum ) { - FT_TRACE2(( "TT_Get_MM_Var:" - " invalid \"%s\" axis record; disabling\n", - a->name )); - a->minimum = a->def; a->maximum = a->def; + +#ifdef FT_DEBUG_LEVEL_TRACE + invalid = 1; +#endif } - FT_TRACE5(( " \"%s\":" - " minimum=%.5f, default=%.5f, maximum=%.5f," - " flags=0x%04X\n", +#ifdef FT_DEBUG_LEVEL_TRACE + if ( i == 0 ) + FT_TRACE5(( " idx tag " + /* " XXX `XXXX'" */ + " minimum default maximum flags\n" )); + /* " XXXX.XXXXX XXXX.XXXXX XXXX.XXXXX 0xXXXX" */ + + FT_TRACE5(( " %3d `%s'" + " %10.5f %10.5f %10.5f 0x%04X%s\n", + i, a->name, a->minimum / 65536.0, a->def / 65536.0, a->maximum / 65536.0, - *axis_flags )); + *axis_flags, + invalid ? " (invalid, disabled)" : "" )); +#endif a++; axis_flags++; @@ -2202,6 +2274,10 @@ goto Exit; } + FT_TRACE5(( "%d instance%s\n", + fvar_head.instanceCount, + fvar_head.instanceCount == 1 ? "" : "s" )); + ns = mmvar->namedstyle; nsc = face->blend->normalized_stylecoords; for ( i = 0; i < fvar_head.instanceCount; i++, ns++ ) @@ -2224,6 +2300,52 @@ else ns->psid = 0xFFFF; +#ifdef FT_DEBUG_LEVEL_TRACE + { + SFNT_Service sfnt = (SFNT_Service)face->sfnt; + + FT_String* strname = NULL; + FT_String* psname = NULL; + + FT_ULong pos; + + + pos = FT_STREAM_POS(); + + if ( ns->strid != 0xFFFF ) + { + (void)sfnt->get_name( face, + (FT_UShort)ns->strid, + &strname ); + if ( strname && !ft_strcmp( strname, ".notdef" ) ) + strname = NULL; + } + + if ( ns->psid != 0xFFFF ) + { + (void)sfnt->get_name( face, + (FT_UShort)ns->psid, + &psname ); + if ( psname && !ft_strcmp( psname, ".notdef" ) ) + psname = NULL; + } + + (void)FT_STREAM_SEEK( pos ); + + FT_TRACE5(( " instance %d (%s%s%s, %s%s%s)\n", + i, + strname ? "name: `" : "", + strname ? strname : "unnamed", + strname ? "'" : "", + psname ? "PS name: `" : "", + psname ? psname : "no PS name", + psname ? "'" : "" )); + + FT_FREE( strname ); + FT_FREE( psname ); + } +#endif /* FT_DEBUG_LEVEL_TRACE */ + ft_var_to_normalized( face, num_axes, ns->coords, nsc ); nsc += num_axes; @@ -2381,11 +2503,12 @@ num_coords = mmvar->num_axis; } - FT_TRACE5(( "normalized design coordinates:\n" )); + FT_TRACE5(( "TT_Set_MM_Blend:\n" + " normalized design coordinates:\n" )); for ( i = 0; i < num_coords; i++ ) { - FT_TRACE5(( " %.5f\n", coords[i] / 65536.0 )); + FT_TRACE5(( " %.5f\n", coords[i] / 65536.0 )); if ( coords[i] < -0x00010000L || coords[i] > 0x00010000L ) { FT_TRACE1(( "TT_Set_MM_Blend: normalized design coordinate %.5f\n" @@ -2444,11 +2567,14 @@ if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) ) { - FT_UInt idx = (FT_UInt)face->root.face_index >> 16; + FT_UInt instance_index = (FT_UInt)face->root.face_index >> 16; c = blend->normalizedcoords + i; - n = blend->normalized_stylecoords + idx * mmvar->num_axis + i; + n = blend->normalized_stylecoords + + ( instance_index - 1 ) * mmvar->num_axis + + i; + for ( j = i; j < mmvar->num_axis; j++, n++, c++ ) if ( *c != *n ) have_diff = 1; @@ -2463,7 +2589,11 @@ /* return value -1 indicates `no change' */ if ( !have_diff ) + { + face->doblend = TRUE; + return -1; + } for ( ; i < mmvar->num_axis; i++ ) { @@ -2527,31 +2657,34 @@ } - /*************************************************************************/ - /* */ - /* */ - /* TT_Set_MM_Blend */ - /* */ - /* */ - /* Set the blend (normalized) coordinates for this instance of the */ - /* font. Check that the `gvar' table is reasonable and does some */ - /* initial preparation. */ - /* */ - /* */ - /* face :: The font. */ - /* Initialize the blend structure with `gvar' data. */ - /* */ - /* */ - /* num_coords :: The number of available coordinates. If it is */ - /* larger than the number of axes, ignore the excess */ - /* values. If it is smaller than the number of axes, */ - /* use the default value (0) for the remaining axes. */ - /* */ - /* coords :: An array of `num_coords', each between [-1,1]. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * TT_Set_MM_Blend + * + * @Description: + * Set the blend (normalized) coordinates for this instance of the + * font. Check that the `gvar' table is reasonable and does some + * initial preparation. + * + * @InOut: + * face :: + * The font. + * Initialize the blend structure with `gvar' data. + * + * @Input: + * num_coords :: + * The number of available coordinates. If it is + * larger than the number of axes, ignore the excess + * values. If it is smaller than the number of axes, + * use the default value (0) for the remaining axes. + * + * coords :: + * An array of `num_coords', each between [-1,1]. + * + * @Return: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) TT_Set_MM_Blend( TT_Face face, FT_UInt num_coords, @@ -2573,29 +2706,32 @@ } - /*************************************************************************/ - /* */ - /* */ - /* TT_Get_MM_Blend */ - /* */ - /* */ - /* Get the blend (normalized) coordinates for this instance of the */ - /* font. */ - /* */ - /* */ - /* face :: The font. */ - /* Initialize the blend structure with `gvar' data. */ - /* */ - /* */ - /* num_coords :: The number of available coordinates. If it is */ - /* larger than the number of axes, set the excess */ - /* values to 0. */ - /* */ - /* coords :: An array of `num_coords', each between [-1,1]. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * TT_Get_MM_Blend + * + * @Description: + * Get the blend (normalized) coordinates for this instance of the + * font. + * + * @InOut: + * face :: + * The font. + * Initialize the blend structure with `gvar' data. + * + * @Input: + * num_coords :: + * The number of available coordinates. If it is + * larger than the number of axes, set the excess + * values to 0. + * + * coords :: + * An array of `num_coords', each between [-1,1]. + * + * @Return: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) TT_Get_MM_Blend( TT_Face face, FT_UInt num_coords, @@ -2649,31 +2785,34 @@ } - /*************************************************************************/ - /* */ - /* */ - /* TT_Set_Var_Design */ - /* */ - /* */ - /* Set the coordinates for the instance, measured in the user */ - /* coordinate system. Parse the `avar' table (if present) to convert */ - /* from user to normalized coordinates. */ - /* */ - /* */ - /* face :: The font face. */ - /* Initialize the blend struct with `gvar' data. */ - /* */ - /* */ - /* num_coords :: The number of available coordinates. If it is */ - /* larger than the number of axes, ignore the excess */ - /* values. If it is smaller than the number of axes, */ - /* use the default values for the remaining axes. */ - /* */ - /* coords :: A coordinate array with `num_coords' elements. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * TT_Set_Var_Design + * + * @Description: + * Set the coordinates for the instance, measured in the user + * coordinate system. Parse the `avar' table (if present) to convert + * from user to normalized coordinates. + * + * @InOut: + * face :: + * The font face. + * Initialize the blend struct with `gvar' data. + * + * @Input: + * num_coords :: + * The number of available coordinates. If it is + * larger than the number of axes, ignore the excess + * values. If it is smaller than the number of axes, + * use the default values for the remaining axes. + * + * coords :: + * A coordinate array with `num_coords' elements. + * + * @Return: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) TT_Set_Var_Design( TT_Face face, FT_UInt num_coords, @@ -2761,8 +2900,9 @@ } } - /* return value -1 indicates `no change' */ - if ( !have_diff ) + /* return value -1 indicates `no change'; */ + /* we can exit early if `normalizedcoords' is already computed */ + if ( blend->normalizedcoords && !have_diff ) return -1; if ( FT_NEW_ARRAY( normalized, mmvar->num_axis ) ) @@ -2771,6 +2911,8 @@ if ( !face->blend->avar_loaded ) ft_var_load_avar( face ); + FT_TRACE5(( "TT_Set_Var_Design:\n" + " normalized design coordinates:\n" )); ft_var_to_normalized( face, num_coords, blend->coords, normalized ); error = tt_set_mm_blend( face, mmvar->num_axis, normalized, 0 ); @@ -2788,28 +2930,31 @@ } - /*************************************************************************/ - /* */ - /* */ - /* TT_Get_Var_Design */ - /* */ - /* */ - /* Get the design coordinates of the currently selected interpolated */ - /* font. */ - /* */ - /* */ - /* face :: A handle to the source face. */ - /* */ - /* num_coords :: The number of design coordinates to retrieve. If it */ - /* is larger than the number of axes, set the excess */ - /* values to~0. */ - /* */ - /* */ - /* coords :: The design coordinates array. */ - /* */ - /* */ - /* FreeType error code. 0~means success. */ - /* */ + /************************************************************************** + * + * @Function: + * TT_Get_Var_Design + * + * @Description: + * Get the design coordinates of the currently selected interpolated + * font. + * + * @Input: + * face :: + * A handle to the source face. + * + * num_coords :: + * The number of design coordinates to retrieve. If it + * is larger than the number of axes, set the excess + * values to~0. + * + * @Output: + * coords :: + * The design coordinates array. + * + * @Return: + * FreeType error code. 0~means success. + */ FT_LOCAL_DEF( FT_Error ) TT_Get_Var_Design( TT_Face face, FT_UInt num_coords, @@ -2863,24 +3008,26 @@ } - /*************************************************************************/ - /* */ - /* */ - /* TT_Set_Named_Instance */ - /* */ - /* */ - /* Set the given named instance, also resetting any further */ - /* variation. */ - /* */ - /* */ - /* face :: A handle to the source face. */ - /* */ - /* instance_index :: The instance index, starting with value 1. */ - /* Value 0 indicates to not use an instance. */ - /* */ - /* */ - /* FreeType error code. 0~means success. */ - /* */ + /************************************************************************** + * + * @Function: + * TT_Set_Named_Instance + * + * @Description: + * Set the given named instance, also resetting any further + * variation. + * + * @Input: + * face :: + * A handle to the source face. + * + * instance_index :: + * The instance index, starting with value 1. + * Value 0 indicates to not use an instance. + * + * @Return: + * FreeType error code. 0~means success. + */ FT_LOCAL_DEF( FT_Error ) TT_Set_Named_Instance( TT_Face face, FT_UInt instance_index ) @@ -2956,48 +3103,60 @@ /*************************************************************************/ - /*************************************************************************/ - /* */ - /* */ - /* tt_face_vary_cvt */ - /* */ - /* */ - /* Modify the loaded cvt table according to the `cvar' table and the */ - /* font's blend. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* */ - /* stream :: A handle to the input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* Most errors are ignored. It is perfectly valid not to have a */ - /* `cvar' table even if there is a `gvar' and `fvar' table. */ - /* */ + /************************************************************************** + * + * @Function: + * tt_face_vary_cvt + * + * @Description: + * Modify the loaded cvt table according to the `cvar' table and the + * font's blend. + * + * @InOut: + * face :: + * A handle to the target face object. + * + * @Input: + * stream :: + * A handle to the input stream. + * + * @Return: + * FreeType error code. 0 means success. + * + * Most errors are ignored. It is perfectly valid not to have a + * `cvar' table even if there is a `gvar' and `fvar' table. + */ FT_LOCAL_DEF( FT_Error ) tt_face_vary_cvt( TT_Face face, FT_Stream stream ) { - FT_Error error; - FT_Memory memory = stream->memory; - FT_ULong table_start; - FT_ULong table_len; - FT_UInt tupleCount; - FT_ULong offsetToData; - FT_ULong here; - FT_UInt i, j; - FT_Fixed* tuple_coords = NULL; - FT_Fixed* im_start_coords = NULL; - FT_Fixed* im_end_coords = NULL; - GX_Blend blend = face->blend; - FT_UInt point_count, spoint_count = 0; + FT_Error error; + FT_Memory memory = stream->memory; + + FT_ULong table_start; + FT_ULong table_len; + + FT_UInt tupleCount; + FT_ULong offsetToData; + + FT_ULong here; + FT_UInt i, j; + + FT_Fixed* tuple_coords = NULL; + FT_Fixed* im_start_coords = NULL; + FT_Fixed* im_end_coords = NULL; + + GX_Blend blend = face->blend; + + FT_UInt point_count; + FT_UInt spoint_count = 0; + FT_UShort* sharedpoints = NULL; FT_UShort* localpoints = NULL; FT_UShort* points; - FT_Short* deltas; + + FT_Fixed* deltas = NULL; + FT_Fixed* cvt_deltas = NULL; FT_TRACE2(( "CVAR " )); @@ -3080,11 +3239,14 @@ } FT_TRACE5(( "cvar: there %s %d tuple%s:\n", - ( tupleCount & 0xFFF ) == 1 ? "is" : "are", - tupleCount & 0xFFF, - ( tupleCount & 0xFFF ) == 1 ? "" : "s" )); + ( tupleCount & GX_TC_TUPLE_COUNT_MASK ) == 1 ? "is" : "are", + tupleCount & GX_TC_TUPLE_COUNT_MASK, + ( tupleCount & GX_TC_TUPLE_COUNT_MASK ) == 1 ? "" : "s" )); + + if ( FT_NEW_ARRAY( cvt_deltas, face->cvt_size ) ) + goto FExit; - for ( i = 0; i < ( tupleCount & 0xFFF ); i++ ) + for ( i = 0; i < ( tupleCount & GX_TC_TUPLE_COUNT_MASK ); i++ ) { FT_UInt tupleDataSize; FT_UInt tupleIndex; @@ -3108,13 +3270,25 @@ " invalid tuple index\n" )); error = FT_THROW( Invalid_Table ); - goto Exit; + goto FExit; } else + { + if ( !blend->tuplecoords ) + { + FT_TRACE2(( "tt_face_vary_cvt:" + " no valid tuple coordinates available\n" )); + + error = FT_THROW( Invalid_Table ); + goto FExit; + } + FT_MEM_COPY( tuple_coords, - &blend->tuplecoords[( tupleIndex & 0xFFF ) * blend->num_axis], + blend->tuplecoords + + ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) * blend->num_axis, blend->num_axis * sizeof ( FT_Fixed ) ); + } if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) { @@ -3175,17 +3349,21 @@ /* this means that there are deltas for every entry in cvt */ for ( j = 0; j < face->cvt_size; j++ ) { - FT_Long orig_cvt = face->cvt[j]; + FT_Fixed old_cvt_delta; - face->cvt[j] = (FT_Short)( orig_cvt + - FT_MulFix( deltas[j], apply ) ); + old_cvt_delta = cvt_deltas[j]; + cvt_deltas[j] = old_cvt_delta + FT_MulFix( deltas[j], apply ); #ifdef FT_DEBUG_LEVEL_TRACE - if ( orig_cvt != face->cvt[j] ) + if ( old_cvt_delta != cvt_deltas[j] ) { - FT_TRACE7(( " %d: %d -> %d\n", - j, orig_cvt, face->cvt[j] )); + FT_TRACE7(( " %d: %f -> %f\n", + j, + ( FT_intToFixed( face->cvt[j] ) + + old_cvt_delta ) / 65536.0, + ( FT_intToFixed( face->cvt[j] ) + + cvt_deltas[j] ) / 65536.0 )); count++; } #endif @@ -3208,23 +3386,26 @@ for ( j = 0; j < point_count; j++ ) { - int pindex; - FT_Long orig_cvt; + int pindex; + FT_Fixed old_cvt_delta; pindex = points[j]; if ( (FT_ULong)pindex >= face->cvt_size ) continue; - orig_cvt = face->cvt[pindex]; - face->cvt[pindex] = (FT_Short)( orig_cvt + - FT_MulFix( deltas[j], apply ) ); + old_cvt_delta = cvt_deltas[pindex]; + cvt_deltas[pindex] = old_cvt_delta + FT_MulFix( deltas[j], apply ); #ifdef FT_DEBUG_LEVEL_TRACE - if ( orig_cvt != face->cvt[pindex] ) + if ( old_cvt_delta != cvt_deltas[pindex] ) { - FT_TRACE7(( " %d: %d -> %d\n", - pindex, orig_cvt, face->cvt[pindex] )); + FT_TRACE7(( " %d: %f -> %f\n", + pindex, + ( FT_intToFixed( face->cvt[pindex] ) + + old_cvt_delta ) / 65536.0, + ( FT_intToFixed( face->cvt[pindex] ) + + cvt_deltas[pindex] ) / 65536.0 )); count++; } #endif @@ -3247,6 +3428,9 @@ FT_TRACE5(( "\n" )); + for ( i = 0; i < face->cvt_size; i++ ) + face->cvt[i] += FT_fixedToInt( cvt_deltas[i] ); + FExit: FT_FRAME_EXIT(); @@ -3256,6 +3440,7 @@ FT_FREE( tuple_coords ); FT_FREE( im_start_coords ); FT_FREE( im_end_coords ); + FT_FREE( cvt_deltas ); return error; } @@ -3301,9 +3486,8 @@ /* between `p1' and `p2', using `ref1' and `ref2' as the reference */ /* point indices. */ - /* modeled after `af_iup_interp', `_iup_worker_interpolate', and */ - /* `Ins_IUP' */ - + /* modeled after `af_iup_interp', `_iup_worker_interpolate', and */ + /* `Ins_IUP' with spec differences in handling ill-defined cases. */ static void tt_delta_interpolate( int p1, int p2, @@ -3462,56 +3646,72 @@ } - /*************************************************************************/ - /* */ - /* */ - /* TT_Vary_Apply_Glyph_Deltas */ - /* */ - /* */ - /* Apply the appropriate deltas to the current glyph. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* glyph_index :: The index of the glyph being modified. */ - /* */ - /* n_points :: The number of the points in the glyph, including */ - /* phantom points. */ - /* */ - /* */ - /* outline :: The outline to change. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * TT_Vary_Apply_Glyph_Deltas + * + * @Description: + * Apply the appropriate deltas to the current glyph. + * + * @Input: + * face :: + * A handle to the target face object. + * + * glyph_index :: + * The index of the glyph being modified. + * + * n_points :: + * The number of the points in the glyph, including + * phantom points. + * + * @InOut: + * outline :: + * The outline to change. + * + * @Return: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) TT_Vary_Apply_Glyph_Deltas( TT_Face face, FT_UInt glyph_index, FT_Outline* outline, FT_UInt n_points ) { - FT_Stream stream = face->root.stream; - FT_Memory memory = stream->memory; - GX_Blend blend = face->blend; + FT_Error error; + FT_Stream stream = face->root.stream; + FT_Memory memory = stream->memory; - FT_Vector* points_org = NULL; - FT_Vector* points_out = NULL; + FT_Vector* points_org = NULL; /* coordinates in 16.16 format */ + FT_Vector* points_out = NULL; /* coordinates in 16.16 format */ FT_Bool* has_delta = NULL; - FT_Error error; - FT_ULong glyph_start; - FT_UInt tupleCount; - FT_ULong offsetToData; - FT_ULong here; - FT_UInt i, j; - FT_Fixed* tuple_coords = NULL; - FT_Fixed* im_start_coords = NULL; - FT_Fixed* im_end_coords = NULL; - FT_UInt point_count, spoint_count = 0; + FT_ULong glyph_start; + + FT_UInt tupleCount; + FT_ULong offsetToData; + FT_ULong dataSize; + + FT_ULong here; + FT_UInt i, j; + + FT_Fixed* tuple_coords = NULL; + FT_Fixed* im_start_coords = NULL; + FT_Fixed* im_end_coords = NULL; + + GX_Blend blend = face->blend; + + FT_UInt point_count; + FT_UInt spoint_count = 0; + FT_UShort* sharedpoints = NULL; FT_UShort* localpoints = NULL; FT_UShort* points; - FT_Short *deltas_x, *deltas_y; + + FT_Fixed* deltas_x = NULL; + FT_Fixed* deltas_y = NULL; + FT_Fixed* point_deltas_x = NULL; + FT_Fixed* point_deltas_y = NULL; if ( !face->doblend || !blend ) @@ -3531,9 +3731,11 @@ FT_NEW_ARRAY( has_delta, n_points ) ) goto Fail1; - if ( FT_STREAM_SEEK( blend->glyphoffsets[glyph_index] ) || - FT_FRAME_ENTER( blend->glyphoffsets[glyph_index + 1] - - blend->glyphoffsets[glyph_index] ) ) + dataSize = blend->glyphoffsets[glyph_index + 1] - + blend->glyphoffsets[glyph_index]; + + if ( FT_STREAM_SEEK( blend->glyphoffsets[glyph_index] ) || + FT_FRAME_ENTER( dataSize ) ) goto Fail1; glyph_start = FT_Stream_FTell( stream ); @@ -3549,8 +3751,8 @@ offsetToData = FT_GET_USHORT(); /* rough sanity test */ - if ( offsetToData + ( tupleCount & GX_TC_TUPLE_COUNT_MASK ) * 4 > - blend->gvar_size ) + if ( offsetToData > dataSize || + ( tupleCount & GX_TC_TUPLE_COUNT_MASK ) * 4 > dataSize ) { FT_TRACE2(( "TT_Vary_Apply_Glyph_Deltas:" " invalid glyph variation array header\n" )); @@ -3580,8 +3782,15 @@ tupleCount & GX_TC_TUPLE_COUNT_MASK, ( tupleCount & GX_TC_TUPLE_COUNT_MASK ) == 1 ? "" : "s" )); + if ( FT_NEW_ARRAY( point_deltas_x, n_points ) || + FT_NEW_ARRAY( point_deltas_y, n_points ) ) + goto Fail3; + for ( j = 0; j < n_points; j++ ) - points_org[j] = outline->points[j]; + { + points_org[j].x = FT_intToFixed( outline->points[j].x ); + points_org[j].y = FT_intToFixed( outline->points[j].y ); + } for ( i = 0; i < ( tupleCount & GX_TC_TUPLE_COUNT_MASK ); i++ ) { @@ -3607,12 +3816,13 @@ " invalid tuple index\n" )); error = FT_THROW( Invalid_Table ); - goto Fail2; + goto Fail3; } else FT_MEM_COPY( tuple_coords, - &blend->tuplecoords[( tupleIndex & 0xFFF ) * blend->num_axis], + blend->tuplecoords + + ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) * blend->num_axis, blend->num_axis * sizeof ( FT_Fixed ) ); if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) @@ -3676,14 +3886,17 @@ /* this means that there are deltas for every point in the glyph */ for ( j = 0; j < n_points; j++ ) { - FT_Pos delta_x = FT_MulFix( deltas_x[j], apply ); - FT_Pos delta_y = FT_MulFix( deltas_y[j], apply ); + FT_Fixed old_point_delta_x = point_deltas_x[j]; + FT_Fixed old_point_delta_y = point_deltas_y[j]; + + FT_Fixed point_delta_x = FT_MulFix( deltas_x[j], apply ); + FT_Fixed point_delta_y = FT_MulFix( deltas_y[j], apply ); if ( j < n_points - 4 ) { - outline->points[j].x += delta_x; - outline->points[j].y += delta_y; + point_deltas_x[j] = old_point_delta_x + point_delta_x; + point_deltas_y[j] = old_point_delta_y + point_delta_y; } else { @@ -3693,33 +3906,37 @@ if ( j == ( n_points - 4 ) && !( face->variation_support & TT_FACE_FLAG_VAR_LSB ) ) - outline->points[j].x += delta_x; + point_deltas_x[j] = old_point_delta_x + point_delta_x; else if ( j == ( n_points - 3 ) && !( face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ) - outline->points[j].x += delta_x; + point_deltas_x[j] = old_point_delta_x + point_delta_x; else if ( j == ( n_points - 2 ) && !( face->variation_support & TT_FACE_FLAG_VAR_TSB ) ) - outline->points[j].y += delta_y; + point_deltas_y[j] = old_point_delta_y + point_delta_y; else if ( j == ( n_points - 1 ) && !( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ) - outline->points[j].y += delta_y; + point_deltas_y[j] = old_point_delta_y + point_delta_y; } #ifdef FT_DEBUG_LEVEL_TRACE - if ( delta_x || delta_y ) + if ( point_delta_x || point_delta_y ) { - FT_TRACE7(( " %d: (%d, %d) -> (%d, %d)\n", + FT_TRACE7(( " %d: (%f, %f) -> (%f, %f)\n", j, - outline->points[j].x - delta_x, - outline->points[j].y - delta_y, - outline->points[j].x, - outline->points[j].y )); + ( FT_intToFixed( outline->points[j].x ) + + old_point_delta_x ) / 65536.0, + ( FT_intToFixed( outline->points[j].y ) + + old_point_delta_y ) / 65536.0, + ( FT_intToFixed( outline->points[j].x ) + + point_deltas_x[j] ) / 65536.0, + ( FT_intToFixed( outline->points[j].y ) + + point_deltas_y[j] ) / 65536.0 )); count++; } #endif @@ -3771,14 +3988,17 @@ for ( j = 0; j < n_points; j++ ) { - FT_Pos delta_x = points_out[j].x - points_org[j].x; - FT_Pos delta_y = points_out[j].y - points_org[j].y; + FT_Fixed old_point_delta_x = point_deltas_x[j]; + FT_Fixed old_point_delta_y = point_deltas_y[j]; + + FT_Pos point_delta_x = points_out[j].x - points_org[j].x; + FT_Pos point_delta_y = points_out[j].y - points_org[j].y; if ( j < n_points - 4 ) { - outline->points[j].x += delta_x; - outline->points[j].y += delta_y; + point_deltas_x[j] = old_point_delta_x + point_delta_x; + point_deltas_y[j] = old_point_delta_y + point_delta_y; } else { @@ -3788,33 +4008,37 @@ if ( j == ( n_points - 4 ) && !( face->variation_support & TT_FACE_FLAG_VAR_LSB ) ) - outline->points[j].x += delta_x; + point_deltas_x[j] = old_point_delta_x + point_delta_x; else if ( j == ( n_points - 3 ) && !( face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ) - outline->points[j].x += delta_x; + point_deltas_x[j] = old_point_delta_x + point_delta_x; else if ( j == ( n_points - 2 ) && !( face->variation_support & TT_FACE_FLAG_VAR_TSB ) ) - outline->points[j].y += delta_y; + point_deltas_y[j] = old_point_delta_y + point_delta_y; else if ( j == ( n_points - 1 ) && !( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ) - outline->points[j].y += delta_y; + point_deltas_y[j] = old_point_delta_y + point_delta_y; } #ifdef FT_DEBUG_LEVEL_TRACE - if ( delta_x || delta_y ) + if ( point_delta_x || point_delta_y ) { - FT_TRACE7(( " %d: (%d, %d) -> (%d, %d)\n", + FT_TRACE7(( " %d: (%f, %f) -> (%f, %f)\n", j, - outline->points[j].x - delta_x, - outline->points[j].y - delta_y, - outline->points[j].x, - outline->points[j].y )); + ( FT_intToFixed( outline->points[j].x ) + + old_point_delta_x ) / 65536.0, + ( FT_intToFixed( outline->points[j].y ) + + old_point_delta_y ) / 65536.0, + ( FT_intToFixed( outline->points[j].x ) + + point_deltas_x[j] ) / 65536.0, + ( FT_intToFixed( outline->points[j].y ) + + point_deltas_y[j] ) / 65536.0 )); count++; } #endif @@ -3838,6 +4062,16 @@ FT_TRACE5(( "\n" )); + for ( i = 0; i < n_points; i++ ) + { + outline->points[i].x += FT_fixedToInt( point_deltas_x[i] ); + outline->points[i].y += FT_fixedToInt( point_deltas_y[i] ); + } + + Fail3: + FT_FREE( point_deltas_x ); + FT_FREE( point_deltas_y ); + Fail2: if ( sharedpoints != ALL_POINTS ) FT_FREE( sharedpoints ); @@ -3856,16 +4090,16 @@ } - /*************************************************************************/ - /* */ - /* */ - /* tt_get_var_blend */ - /* */ - /* */ - /* An extended internal version of `TT_Get_MM_Blend' that returns */ - /* pointers instead of copying data, without any initialization of */ - /* the MM machinery in case it isn't loaded yet. */ - /* */ + /************************************************************************** + * + * @Function: + * tt_get_var_blend + * + * @Description: + * An extended internal version of `TT_Get_MM_Blend' that returns + * pointers instead of copying data, without any initialization of + * the MM machinery in case it isn't loaded yet. + */ FT_LOCAL_DEF( FT_Error ) tt_get_var_blend( TT_Face face, FT_UInt *num_coords, @@ -3927,14 +4161,14 @@ } - /*************************************************************************/ - /* */ - /* */ - /* tt_done_blend */ - /* */ - /* */ - /* Free the blend internal data structure. */ - /* */ + /************************************************************************** + * + * @Function: + * tt_done_blend + * + * @Description: + * Free the blend internal data structure. + */ FT_LOCAL_DEF( void ) tt_done_blend( TT_Face face ) { diff --git a/sdk/lib/3rdparty/freetype/src/truetype/ttgxvar.h b/sdk/lib/3rdparty/freetype/src/truetype/ttgxvar.h index a37bb90266cfa..7e8d9768a76a2 100644 --- a/sdk/lib/3rdparty/freetype/src/truetype/ttgxvar.h +++ b/sdk/lib/3rdparty/freetype/src/truetype/ttgxvar.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ttgxvar.h */ -/* */ -/* TrueType GX Font Variation loader (specification) */ -/* */ -/* Copyright 2004-2018 by */ -/* David Turner, Robert Wilhelm, Werner Lemberg and George Williams. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ttgxvar.h + * + * TrueType GX Font Variation loader (specification) + * + * Copyright (C) 2004-2019 by + * David Turner, Robert Wilhelm, Werner Lemberg and George Williams. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef TTGXVAR_H_ @@ -29,15 +29,15 @@ FT_BEGIN_HEADER #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - /*************************************************************************/ - /* */ - /* */ - /* GX_AVarCorrespondenceRec */ - /* */ - /* */ - /* A data structure representing `shortFracCorrespondence' in `avar' */ - /* table according to the specifications from Apple. */ - /* */ + /************************************************************************** + * + * @Struct: + * GX_AVarCorrespondenceRec + * + * @Description: + * A data structure representing `shortFracCorrespondence' in `avar' + * table according to the specifications from Apple. + */ typedef struct GX_AVarCorrespondenceRec_ { FT_Fixed fromCoord; @@ -46,15 +46,15 @@ FT_BEGIN_HEADER } GX_AVarCorrespondenceRec_, *GX_AVarCorrespondence; - /*************************************************************************/ - /* */ - /* */ - /* GX_AVarRec */ - /* */ - /* */ - /* Data from the segment field of `avar' table. */ - /* There is one of these for each axis. */ - /* */ + /************************************************************************** + * + * @Struct: + * GX_AVarRec + * + * @Description: + * Data from the segment field of `avar' table. + * There is one of these for each axis. + */ typedef struct GX_AVarSegmentRec_ { FT_UShort pairCount; @@ -114,14 +114,14 @@ FT_BEGIN_HEADER } GX_DeltaSetIdxMapRec, *GX_DeltaSetIdxMap; - /*************************************************************************/ - /* */ - /* */ - /* GX_HVVarTableRec */ - /* */ - /* */ - /* Data from either the `HVAR' or `VVAR' table. */ - /* */ + /************************************************************************** + * + * @Struct: + * GX_HVVarTableRec + * + * @Description: + * Data from either the `HVAR' or `VVAR' table. + */ typedef struct GX_HVVarTableRec_ { GX_ItemVarStoreRec itemStore; /* Item Variation Store */ @@ -191,14 +191,14 @@ FT_BEGIN_HEADER } GX_ValueRec, *GX_Value; - /*************************************************************************/ - /* */ - /* */ - /* GX_MVarTableRec */ - /* */ - /* */ - /* Data from the `MVAR' table. */ - /* */ + /************************************************************************** + * + * @Struct: + * GX_MVarTableRec + * + * @Description: + * Data from the `MVAR' table. + */ typedef struct GX_MVarTableRec_ { FT_UShort valueCount; @@ -209,95 +209,95 @@ FT_BEGIN_HEADER } GX_MVarTableRec, *GX_MVarTable; - /*************************************************************************/ - /* */ - /* */ - /* GX_BlendRec */ - /* */ - /* */ - /* Data for interpolating a font from a distortable font specified */ - /* by the GX *var tables ([fgcahvm]var). */ - /* */ - /* */ - /* num_axis :: */ - /* The number of axes along which interpolation may happen. */ - /* */ - /* coords :: */ - /* An array of design coordinates (in user space) indicating the */ - /* contribution along each axis to the final interpolated font. */ - /* `normalizedcoords' holds the same values. */ - /* */ - /* normalizedcoords :: */ - /* An array of normalized values (between [-1,1]) indicating the */ - /* contribution along each axis to the final interpolated font. */ - /* `coords' holds the same values. */ - /* */ - /* mmvar :: */ - /* Data from the `fvar' table. */ - /* */ - /* mmvar_len :: */ - /* The length of the `mmvar' structure. */ - /* */ - /* normalized_stylecoords :: */ - /* A two-dimensional array that holds the named instance data from */ - /* `mmvar' as normalized values. */ - /* */ - /* avar_loaded :: */ - /* A Boolean; if set, FreeType tried to load (and parse) the `avar' */ - /* table. */ - /* */ - /* avar_segment :: */ - /* Data from the `avar' table. */ - /* */ - /* hvar_loaded :: */ - /* A Boolean; if set, FreeType tried to load (and parse) the `hvar' */ - /* table. */ - /* */ - /* hvar_checked :: */ - /* A Boolean; if set, FreeType successfully loaded and parsed the */ - /* `hvar' table. */ - /* */ - /* hvar_error :: */ - /* If loading and parsing of the `hvar' table failed, this field */ - /* holds the corresponding error code. */ - /* */ - /* hvar_table :: */ - /* Data from the `hvar' table. */ - /* */ - /* vvar_loaded :: */ - /* A Boolean; if set, FreeType tried to load (and parse) the `vvar' */ - /* table. */ - /* */ - /* vvar_checked :: */ - /* A Boolean; if set, FreeType successfully loaded and parsed the */ - /* `vvar' table. */ - /* */ - /* vvar_error :: */ - /* If loading and parsing of the `vvar' table failed, this field */ - /* holds the corresponding error code. */ - /* */ - /* vvar_table :: */ - /* Data from the `vvar' table. */ - /* */ - /* mvar_table :: */ - /* Data from the `mvar' table. */ - /* */ - /* tuplecount :: */ - /* The number of shared tuples in the `gvar' table. */ - /* */ - /* tuplecoords :: */ - /* A two-dimensional array that holds the shared tuple coordinates */ - /* in the `gvar' table. */ - /* */ - /* gv_glyphcnt :: */ - /* The number of glyphs handled in the `gvar' table. */ - /* */ - /* glyphoffsets :: */ - /* Offsets into the glyph variation data array. */ - /* */ - /* gvar_size :: */ - /* The size of the `gvar' table. */ - /* */ + /************************************************************************** + * + * @Struct: + * GX_BlendRec + * + * @Description: + * Data for interpolating a font from a distortable font specified + * by the GX *var tables ([fgcahvm]var). + * + * @Fields: + * num_axis :: + * The number of axes along which interpolation may happen. + * + * coords :: + * An array of design coordinates (in user space) indicating the + * contribution along each axis to the final interpolated font. + * `normalizedcoords' holds the same values. + * + * normalizedcoords :: + * An array of normalized values (between [-1,1]) indicating the + * contribution along each axis to the final interpolated font. + * `coords' holds the same values. + * + * mmvar :: + * Data from the `fvar' table. + * + * mmvar_len :: + * The length of the `mmvar' structure. + * + * normalized_stylecoords :: + * A two-dimensional array that holds the named instance data from + * `mmvar' as normalized values. + * + * avar_loaded :: + * A Boolean; if set, FreeType tried to load (and parse) the `avar' + * table. + * + * avar_segment :: + * Data from the `avar' table. + * + * hvar_loaded :: + * A Boolean; if set, FreeType tried to load (and parse) the `hvar' + * table. + * + * hvar_checked :: + * A Boolean; if set, FreeType successfully loaded and parsed the + * `hvar' table. + * + * hvar_error :: + * If loading and parsing of the `hvar' table failed, this field + * holds the corresponding error code. + * + * hvar_table :: + * Data from the `hvar' table. + * + * vvar_loaded :: + * A Boolean; if set, FreeType tried to load (and parse) the `vvar' + * table. + * + * vvar_checked :: + * A Boolean; if set, FreeType successfully loaded and parsed the + * `vvar' table. + * + * vvar_error :: + * If loading and parsing of the `vvar' table failed, this field + * holds the corresponding error code. + * + * vvar_table :: + * Data from the `vvar' table. + * + * mvar_table :: + * Data from the `mvar' table. + * + * tuplecount :: + * The number of shared tuples in the `gvar' table. + * + * tuplecoords :: + * A two-dimensional array that holds the shared tuple coordinates + * in the `gvar' table. + * + * gv_glyphcnt :: + * The number of glyphs handled in the `gvar' table. + * + * glyphoffsets :: + * Offsets into the glyph variation data array. + * + * gvar_size :: + * The size of the `gvar' table. + */ typedef struct GX_BlendRec_ { FT_UInt num_axis; @@ -336,14 +336,14 @@ FT_BEGIN_HEADER } GX_BlendRec; - /*************************************************************************/ - /* */ - /* */ - /* GX_TupleCountFlags */ - /* */ - /* */ - /* Flags used within the `TupleCount' field of the `gvar' table. */ - /* */ + /************************************************************************** + * + * @enum: + * GX_TupleCountFlags + * + * @Description: + * Flags used within the `TupleCount' field of the `gvar' table. + */ typedef enum GX_TupleCountFlags_ { GX_TC_TUPLES_SHARE_POINT_NUMBERS = 0x8000, @@ -353,15 +353,15 @@ FT_BEGIN_HEADER } GX_TupleCountFlags; - /*************************************************************************/ - /* */ - /* */ - /* GX_TupleIndexFlags */ - /* */ - /* */ - /* Flags used within the `TupleIndex' field of the `gvar' and `cvar' */ - /* tables. */ - /* */ + /************************************************************************** + * + * @enum: + * GX_TupleIndexFlags + * + * @Description: + * Flags used within the `TupleIndex' field of the `gvar' and `cvar' + * tables. + */ typedef enum GX_TupleIndexFlags_ { GX_TI_EMBEDDED_TUPLE_COORD = 0x8000, diff --git a/sdk/lib/3rdparty/freetype/src/truetype/ttinterp.c b/sdk/lib/3rdparty/freetype/src/truetype/ttinterp.c index d855aaaa9c649..403f3753c7b5b 100644 --- a/sdk/lib/3rdparty/freetype/src/truetype/ttinterp.c +++ b/sdk/lib/3rdparty/freetype/src/truetype/ttinterp.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ttinterp.c */ -/* */ -/* TrueType bytecode interpreter (body). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ttinterp.c + * + * TrueType bytecode interpreter (body). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ /* Greg Hitchcock from Microsoft has helped a lot in resolving unclear */ @@ -39,14 +39,14 @@ #ifdef TT_USE_BYTECODE_INTERPRETER - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_ttinterp +#define FT_COMPONENT ttinterp #define NO_SUBPIXEL_HINTING \ @@ -82,10 +82,10 @@ exc->func_dualproj( exc, (v)->x, (v)->y ) - /*************************************************************************/ - /* */ - /* Two simple bounds-checking macros. */ - /* */ + /************************************************************************** + * + * Two simple bounds-checking macros. + */ #define BOUNDS( x, n ) ( (FT_UInt)(x) >= (FT_UInt)(n) ) #define BOUNDSL( x, n ) ( (FT_ULong)(x) >= (FT_ULong)(n) ) @@ -97,30 +97,33 @@ #define FAILURE 1 - /*************************************************************************/ - /* */ - /* CODERANGE FUNCTIONS */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Goto_CodeRange */ - /* */ - /* */ - /* Switches to a new code range (updates the code related elements in */ - /* `exec', and `IP'). */ - /* */ - /* */ - /* range :: The new execution code range. */ - /* */ - /* IP :: The new IP in the new code range. */ - /* */ - /* */ - /* exec :: The target execution context. */ - /* */ + /************************************************************************** + * + * CODERANGE FUNCTIONS + * + */ + + + /************************************************************************** + * + * @Function: + * TT_Goto_CodeRange + * + * @Description: + * Switches to a new code range (updates the code related elements in + * `exec', and `IP'). + * + * @Input: + * range :: + * The new execution code range. + * + * IP :: + * The new IP in the new code range. + * + * @InOut: + * exec :: + * The target execution context. + */ FT_LOCAL_DEF( void ) TT_Goto_CodeRange( TT_ExecContext exec, FT_Int range, @@ -148,24 +151,28 @@ } - /*************************************************************************/ - /* */ - /* */ - /* TT_Set_CodeRange */ - /* */ - /* */ - /* Sets a code range. */ - /* */ - /* */ - /* range :: The code range index. */ - /* */ - /* base :: The new code base. */ - /* */ - /* length :: The range size in bytes. */ - /* */ - /* */ - /* exec :: The target execution context. */ - /* */ + /************************************************************************** + * + * @Function: + * TT_Set_CodeRange + * + * @Description: + * Sets a code range. + * + * @Input: + * range :: + * The code range index. + * + * base :: + * The new code base. + * + * length :: + * The range size in bytes. + * + * @InOut: + * exec :: + * The target execution context. + */ FT_LOCAL_DEF( void ) TT_Set_CodeRange( TT_ExecContext exec, FT_Int range, @@ -179,20 +186,22 @@ } - /*************************************************************************/ - /* */ - /* */ - /* TT_Clear_CodeRange */ - /* */ - /* */ - /* Clears a code range. */ - /* */ - /* */ - /* range :: The code range index. */ - /* */ - /* */ - /* exec :: The target execution context. */ - /* */ + /************************************************************************** + * + * @Function: + * TT_Clear_CodeRange + * + * @Description: + * Clears a code range. + * + * @Input: + * range :: + * The code range index. + * + * @InOut: + * exec :: + * The target execution context. + */ FT_LOCAL_DEF( void ) TT_Clear_CodeRange( TT_ExecContext exec, FT_Int range ) @@ -204,29 +213,31 @@ } - /*************************************************************************/ - /* */ - /* EXECUTION CONTEXT ROUTINES */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Done_Context */ - /* */ - /* */ - /* Destroys a given context. */ - /* */ - /* */ - /* exec :: A handle to the target execution context. */ - /* */ - /* memory :: A handle to the parent memory object. */ - /* */ - /* */ - /* Only the glyph loader and debugger should call this function. */ - /* */ + /************************************************************************** + * + * EXECUTION CONTEXT ROUTINES + * + */ + + + /************************************************************************** + * + * @Function: + * TT_Done_Context + * + * @Description: + * Destroys a given context. + * + * @Input: + * exec :: + * A handle to the target execution context. + * + * memory :: + * A handle to the parent memory object. + * + * @Note: + * Only the glyph loader and debugger should call this function. + */ FT_LOCAL_DEF( void ) TT_Done_Context( TT_ExecContext exec ) { @@ -257,23 +268,25 @@ } - /*************************************************************************/ - /* */ - /* */ - /* Init_Context */ - /* */ - /* */ - /* Initializes a context object. */ - /* */ - /* */ - /* memory :: A handle to the parent memory object. */ - /* */ - /* */ - /* exec :: A handle to the target execution context. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * Init_Context + * + * @Description: + * Initializes a context object. + * + * @Input: + * memory :: + * A handle to the parent memory object. + * + * @InOut: + * exec :: + * A handle to the target execution context. + * + * @Return: + * FreeType error code. 0 means success. + */ static FT_Error Init_Context( TT_ExecContext exec, FT_Memory memory ) @@ -313,30 +326,35 @@ } - /*************************************************************************/ - /* */ - /* */ - /* Update_Max */ - /* */ - /* */ - /* Checks the size of a buffer and reallocates it if necessary. */ - /* */ - /* */ - /* memory :: A handle to the parent memory object. */ - /* */ - /* multiplier :: The size in bytes of each element in the buffer. */ - /* */ - /* new_max :: The new capacity (size) of the buffer. */ - /* */ - /* */ - /* size :: The address of the buffer's current size expressed */ - /* in elements. */ - /* */ - /* buff :: The address of the buffer base pointer. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * Update_Max + * + * @Description: + * Checks the size of a buffer and reallocates it if necessary. + * + * @Input: + * memory :: + * A handle to the parent memory object. + * + * multiplier :: + * The size in bytes of each element in the buffer. + * + * new_max :: + * The new capacity (size) of the buffer. + * + * @InOut: + * size :: + * The address of the buffer's current size expressed + * in elements. + * + * buff :: + * The address of the buffer base pointer. + * + * @Return: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) Update_Max( FT_Memory memory, FT_ULong* size, @@ -359,28 +377,31 @@ } - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Context */ - /* */ - /* */ - /* Prepare an execution context for glyph hinting. */ - /* */ - /* */ - /* face :: A handle to the source face object. */ - /* */ - /* size :: A handle to the source size object. */ - /* */ - /* */ - /* exec :: A handle to the target execution context. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Only the glyph loader and debugger should call this function. */ - /* */ + /************************************************************************** + * + * @Function: + * TT_Load_Context + * + * @Description: + * Prepare an execution context for glyph hinting. + * + * @Input: + * face :: + * A handle to the source face object. + * + * size :: + * A handle to the source size object. + * + * @InOut: + * exec :: + * A handle to the target execution context. + * + * @Return: + * FreeType error code. 0 means success. + * + * @Note: + * Only the glyph loader and debugger should call this function. + */ FT_LOCAL_DEF( FT_Error ) TT_Load_Context( TT_ExecContext exec, TT_Face face, @@ -467,23 +488,25 @@ } - /*************************************************************************/ - /* */ - /* */ - /* TT_Save_Context */ - /* */ - /* */ - /* Saves the code ranges in a `size' object. */ - /* */ - /* */ - /* exec :: A handle to the source execution context. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - /* */ - /* Only the glyph loader and debugger should call this function. */ - /* */ + /************************************************************************** + * + * @Function: + * TT_Save_Context + * + * @Description: + * Saves the code ranges in a `size' object. + * + * @Input: + * exec :: + * A handle to the source execution context. + * + * @InOut: + * size :: + * A handle to the target size object. + * + * @Note: + * Only the glyph loader and debugger should call this function. + */ FT_LOCAL_DEF( void ) TT_Save_Context( TT_ExecContext exec, TT_Size size ) @@ -505,27 +528,21 @@ } - /*************************************************************************/ - /* */ - /* */ - /* TT_Run_Context */ - /* */ - /* */ - /* Executes one or more instructions in the execution context. */ - /* */ - /* */ - /* debug :: A Boolean flag. If set, the function sets some internal */ - /* variables and returns immediately, otherwise TT_RunIns() */ - /* is called. */ - /* */ - /* This is commented out currently. */ - /* */ - /* */ - /* exec :: A handle to the target execution context. */ - /* */ - /* */ - /* TrueType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * TT_Run_Context + * + * @Description: + * Executes one or more instructions in the execution context. + * + * @Input: + * exec :: + * A handle to the target execution context. + * + * @Return: + * TrueType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) TT_Run_Context( TT_ExecContext exec ) { @@ -609,22 +626,22 @@ } - /*************************************************************************/ - /* */ - /* Before an opcode is executed, the interpreter verifies that there are */ - /* enough arguments on the stack, with the help of the `Pop_Push_Count' */ - /* table. */ - /* */ - /* For each opcode, the first column gives the number of arguments that */ - /* are popped from the stack; the second one gives the number of those */ - /* that are pushed in result. */ - /* */ - /* Opcodes which have a varying number of parameters in the data stream */ - /* (NPUSHB, NPUSHW) are handled specially; they have a negative value in */ - /* the `opcode_length' table, and the value in `Pop_Push_Count' is set */ - /* to zero. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * Before an opcode is executed, the interpreter verifies that there are + * enough arguments on the stack, with the help of the `Pop_Push_Count' + * table. + * + * For each opcode, the first column gives the number of arguments that + * are popped from the stack; the second one gives the number of those + * that are pushed in result. + * + * Opcodes which have a varying number of parameters in the data stream + * (NPUSHB, NPUSHW) are handled specially; they have a negative value in + * the `opcode_length' table, and the value in `Pop_Push_Count' is set + * to zero. + * + */ #undef PACK @@ -1129,73 +1146,73 @@ "8 PushW[6]", "8 PushW[7]", - "8 MDRP[00]", - "8 MDRP[01]", - "8 MDRP[02]", - "8 MDRP[03]", - "8 MDRP[04]", - "8 MDRP[05]", - "8 MDRP[06]", - "8 MDRP[07]", - "8 MDRP[08]", - "8 MDRP[09]", - "8 MDRP[10]", - "8 MDRP[11]", - "8 MDRP[12]", - "8 MDRP[13]", - "8 MDRP[14]", - "8 MDRP[15]", - - "8 MDRP[16]", - "8 MDRP[17]", - "8 MDRP[18]", - "8 MDRP[19]", - "8 MDRP[20]", - "8 MDRP[21]", - "8 MDRP[22]", - "8 MDRP[23]", - "8 MDRP[24]", - "8 MDRP[25]", - "8 MDRP[26]", - "8 MDRP[27]", - "8 MDRP[28]", - "8 MDRP[29]", - "8 MDRP[30]", - "8 MDRP[31]", - - "8 MIRP[00]", - "8 MIRP[01]", - "8 MIRP[02]", - "8 MIRP[03]", - "8 MIRP[04]", - "8 MIRP[05]", - "8 MIRP[06]", - "8 MIRP[07]", - "8 MIRP[08]", - "8 MIRP[09]", - "8 MIRP[10]", - "8 MIRP[11]", - "8 MIRP[12]", - "8 MIRP[13]", - "8 MIRP[14]", - "8 MIRP[15]", - - "8 MIRP[16]", - "8 MIRP[17]", - "8 MIRP[18]", - "8 MIRP[19]", - "8 MIRP[20]", - "8 MIRP[21]", - "8 MIRP[22]", - "8 MIRP[23]", - "8 MIRP[24]", - "8 MIRP[25]", - "8 MIRP[26]", - "8 MIRP[27]", - "8 MIRP[28]", - "8 MIRP[29]", - "8 MIRP[30]", - "8 MIRP[31]" + "7 MDRP[G]", + "7 MDRP[B]", + "7 MDRP[W]", + "7 MDRP[?]", + "8 MDRP[rG]", + "8 MDRP[rB]", + "8 MDRP[rW]", + "8 MDRP[r?]", + "8 MDRP[mG]", + "8 MDRP[mB]", + "8 MDRP[mW]", + "8 MDRP[m?]", + "9 MDRP[mrG]", + "9 MDRP[mrB]", + "9 MDRP[mrW]", + "9 MDRP[mr?]", + + "8 MDRP[pG]", + "8 MDRP[pB]", + "8 MDRP[pW]", + "8 MDRP[p?]", + "9 MDRP[prG]", + "9 MDRP[prB]", + "9 MDRP[prW]", + "9 MDRP[pr?]", + "9 MDRP[pmG]", + "9 MDRP[pmB]", + "9 MDRP[pmW]", + "9 MDRP[pm?]", + "A MDRP[pmrG]", + "A MDRP[pmrB]", + "A MDRP[pmrW]", + "A MDRP[pmr?]", + + "7 MIRP[G]", + "7 MIRP[B]", + "7 MIRP[W]", + "7 MIRP[?]", + "8 MIRP[rG]", + "8 MIRP[rB]", + "8 MIRP[rW]", + "8 MIRP[r?]", + "8 MIRP[mG]", + "8 MIRP[mB]", + "8 MIRP[mW]", + "8 MIRP[m?]", + "9 MIRP[mrG]", + "9 MIRP[mrB]", + "9 MIRP[mrW]", + "9 MIRP[mr?]", + + "8 MIRP[pG]", + "8 MIRP[pB]", + "8 MIRP[pW]", + "8 MIRP[p?]", + "9 MIRP[prG]", + "9 MIRP[prB]", + "9 MIRP[prW]", + "9 MIRP[pr?]", + "9 MIRP[pmG]", + "9 MIRP[pmB]", + "9 MIRP[pmW]", + "9 MIRP[pm?]", + "A MIRP[pmrG]", + "A MIRP[pmrB]", + "A MIRP[pmrW]", + "A MIRP[pmr?]" }; #endif /* FT_DEBUG_LEVEL_TRACE */ @@ -1448,18 +1465,18 @@ #endif /* TT_DotFix14 */ - /*************************************************************************/ - /* */ - /* */ - /* Current_Ratio */ - /* */ - /* */ - /* Returns the current aspect ratio scaling factor depending on the */ - /* projection vector's state and device resolutions. */ - /* */ - /* */ - /* The aspect ratio in 16.16 format, always <= 1.0 . */ - /* */ + /************************************************************************** + * + * @Function: + * Current_Ratio + * + * @Description: + * Returns the current aspect ratio scaling factor depending on the + * projection vector's state and device resolutions. + * + * @Return: + * The aspect ratio in 16.16 format, always <= 1.0 . + */ static FT_Long Current_Ratio( TT_ExecContext exc ) { @@ -1501,11 +1518,11 @@ } - /*************************************************************************/ - /* */ - /* Functions related to the control value table (CVT). */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * Functions related to the control value table (CVT). + * + */ FT_CALLBACK_DEF( FT_F26Dot6 ) @@ -1547,7 +1564,7 @@ FT_ULong idx, FT_F26Dot6 value ) { - exc->cvt[idx] += value; + exc->cvt[idx] = ADD_LONG( exc->cvt[idx], value ); } @@ -1556,25 +1573,26 @@ FT_ULong idx, FT_F26Dot6 value ) { - exc->cvt[idx] += FT_DivFix( value, Current_Ratio( exc ) ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* GetShortIns */ - /* */ - /* */ - /* Returns a short integer taken from the instruction stream at */ - /* address IP. */ - /* */ - /* */ - /* Short read at code[IP]. */ - /* */ - /* */ - /* This one could become a macro. */ - /* */ + exc->cvt[idx] = ADD_LONG( exc->cvt[idx], + FT_DivFix( value, Current_Ratio( exc ) ) ); + } + + + /************************************************************************** + * + * @Function: + * GetShortIns + * + * @Description: + * Returns a short integer taken from the instruction stream at + * address IP. + * + * @Return: + * Short read at code[IP]. + * + * @Note: + * This one could become a macro. + */ static FT_Short GetShortIns( TT_ExecContext exc ) { @@ -1585,22 +1603,24 @@ } - /*************************************************************************/ - /* */ - /* */ - /* Ins_Goto_CodeRange */ - /* */ - /* */ - /* Goes to a certain code range in the instruction stream. */ - /* */ - /* */ - /* aRange :: The index of the code range. */ - /* */ - /* aIP :: The new IP address in the code range. */ - /* */ - /* */ - /* SUCCESS or FAILURE. */ - /* */ + /************************************************************************** + * + * @Function: + * Ins_Goto_CodeRange + * + * @Description: + * Goes to a certain code range in the instruction stream. + * + * @Input: + * aRange :: + * The index of the code range. + * + * aIP :: + * The new IP address in the code range. + * + * @Return: + * SUCCESS or FAILURE. + */ static FT_Bool Ins_Goto_CodeRange( TT_ExecContext exc, FT_Int aRange, @@ -1642,27 +1662,30 @@ } - /*************************************************************************/ - /* */ - /* */ - /* Direct_Move */ - /* */ - /* */ - /* Moves a point by a given distance along the freedom vector. The */ - /* point will be `touched'. */ - /* */ - /* */ - /* point :: The index of the point to move. */ - /* */ - /* distance :: The distance to apply. */ - /* */ - /* */ - /* zone :: The affected glyph zone. */ - /* */ - /* */ - /* See `ttinterp.h' for details on backward compatibility mode. */ - /* `Touches' the point. */ - /* */ + /************************************************************************** + * + * @Function: + * Direct_Move + * + * @Description: + * Moves a point by a given distance along the freedom vector. The + * point will be `touched'. + * + * @Input: + * point :: + * The index of the point to move. + * + * distance :: + * The distance to apply. + * + * @InOut: + * zone :: + * The affected glyph zone. + * + * @Note: + * See `ttinterp.h' for details on backward compatibility mode. + * `Touches' the point. + */ static void Direct_Move( TT_ExecContext exc, TT_GlyphZone zone, @@ -1728,23 +1751,26 @@ } - /*************************************************************************/ - /* */ - /* */ - /* Direct_Move_Orig */ - /* */ - /* */ - /* Moves the *original* position of a point by a given distance along */ - /* the freedom vector. Obviously, the point will not be `touched'. */ - /* */ - /* */ - /* point :: The index of the point to move. */ - /* */ - /* distance :: The distance to apply. */ - /* */ - /* */ - /* zone :: The affected glyph zone. */ - /* */ + /************************************************************************** + * + * @Function: + * Direct_Move_Orig + * + * @Description: + * Moves the *original* position of a point by a given distance along + * the freedom vector. Obviously, the point will not be `touched'. + * + * @Input: + * point :: + * The index of the point to move. + * + * distance :: + * The distance to apply. + * + * @InOut: + * zone :: + * The affected glyph zone. + */ static void Direct_Move_Orig( TT_ExecContext exc, TT_GlyphZone zone, @@ -1772,15 +1798,15 @@ } - /*************************************************************************/ - /* */ - /* Special versions of Direct_Move() */ - /* */ - /* The following versions are used whenever both vectors are both */ - /* along one of the coordinate unit vectors, i.e. in 90% of the cases. */ - /* See `ttinterp.h' for details on backward compatibility mode. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * Special versions of Direct_Move() + * + * The following versions are used whenever both vectors are both + * along one of the coordinate unit vectors, i.e. in 90% of the cases. + * See `ttinterp.h' for details on backward compatibility mode. + * + */ static void @@ -1827,14 +1853,14 @@ } - /*************************************************************************/ - /* */ - /* Special versions of Direct_Move_Orig() */ - /* */ - /* The following versions are used whenever both vectors are both */ - /* along one of the coordinate unit vectors, i.e. in 90% of the cases. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * Special versions of Direct_Move_Orig() + * + * The following versions are used whenever both vectors are both + * along one of the coordinate unit vectors, i.e. in 90% of the cases. + * + */ static void @@ -1861,28 +1887,30 @@ } - /*************************************************************************/ - /* */ - /* */ - /* Round_None */ - /* */ - /* */ - /* Does not round, but adds engine compensation. */ - /* */ - /* */ - /* distance :: The distance (not) to round. */ - /* */ - /* compensation :: The engine compensation. */ - /* */ - /* */ - /* The compensated distance. */ - /* */ - /* */ - /* The TrueType specification says very few about the relationship */ - /* between rounding and engine compensation. However, it seems from */ - /* the description of super round that we should add the compensation */ - /* before rounding. */ - /* */ + /************************************************************************** + * + * @Function: + * Round_None + * + * @Description: + * Does not round, but adds engine compensation. + * + * @Input: + * distance :: + * The distance (not) to round. + * + * compensation :: + * The engine compensation. + * + * @Return: + * The compensated distance. + * + * @Note: + * The TrueType specification says very few about the relationship + * between rounding and engine compensation. However, it seems from + * the description of super round that we should add the compensation + * before rounding. + */ static FT_F26Dot6 Round_None( TT_ExecContext exc, FT_F26Dot6 distance, @@ -1909,22 +1937,24 @@ } - /*************************************************************************/ - /* */ - /* */ - /* Round_To_Grid */ - /* */ - /* */ - /* Rounds value to grid after adding engine compensation. */ - /* */ - /* */ - /* distance :: The distance to round. */ - /* */ - /* compensation :: The engine compensation. */ - /* */ - /* */ - /* Rounded distance. */ - /* */ + /************************************************************************** + * + * @Function: + * Round_To_Grid + * + * @Description: + * Rounds value to grid after adding engine compensation. + * + * @Input: + * distance :: + * The distance to round. + * + * compensation :: + * The engine compensation. + * + * @Return: + * Rounded distance. + */ static FT_F26Dot6 Round_To_Grid( TT_ExecContext exc, FT_F26Dot6 distance, @@ -1953,22 +1983,24 @@ } - /*************************************************************************/ - /* */ - /* */ - /* Round_To_Half_Grid */ - /* */ - /* */ - /* Rounds value to half grid after adding engine compensation. */ - /* */ - /* */ - /* distance :: The distance to round. */ - /* */ - /* compensation :: The engine compensation. */ - /* */ - /* */ - /* Rounded distance. */ - /* */ + /************************************************************************** + * + * @Function: + * Round_To_Half_Grid + * + * @Description: + * Rounds value to half grid after adding engine compensation. + * + * @Input: + * distance :: + * The distance to round. + * + * compensation :: + * The engine compensation. + * + * @Return: + * Rounded distance. + */ static FT_F26Dot6 Round_To_Half_Grid( TT_ExecContext exc, FT_F26Dot6 distance, @@ -1999,22 +2031,24 @@ } - /*************************************************************************/ - /* */ - /* */ - /* Round_Down_To_Grid */ - /* */ - /* */ - /* Rounds value down to grid after adding engine compensation. */ - /* */ - /* */ - /* distance :: The distance to round. */ - /* */ - /* compensation :: The engine compensation. */ - /* */ - /* */ - /* Rounded distance. */ - /* */ + /************************************************************************** + * + * @Function: + * Round_Down_To_Grid + * + * @Description: + * Rounds value down to grid after adding engine compensation. + * + * @Input: + * distance :: + * The distance to round. + * + * compensation :: + * The engine compensation. + * + * @Return: + * Rounded distance. + */ static FT_F26Dot6 Round_Down_To_Grid( TT_ExecContext exc, FT_F26Dot6 distance, @@ -2042,22 +2076,24 @@ } - /*************************************************************************/ - /* */ - /* */ - /* Round_Up_To_Grid */ - /* */ - /* */ - /* Rounds value up to grid after adding engine compensation. */ - /* */ - /* */ - /* distance :: The distance to round. */ - /* */ - /* compensation :: The engine compensation. */ - /* */ - /* */ - /* Rounded distance. */ - /* */ + /************************************************************************** + * + * @Function: + * Round_Up_To_Grid + * + * @Description: + * Rounds value up to grid after adding engine compensation. + * + * @Input: + * distance :: + * The distance to round. + * + * compensation :: + * The engine compensation. + * + * @Return: + * Rounded distance. + */ static FT_F26Dot6 Round_Up_To_Grid( TT_ExecContext exc, FT_F26Dot6 distance, @@ -2086,22 +2122,24 @@ } - /*************************************************************************/ - /* */ - /* */ - /* Round_To_Double_Grid */ - /* */ - /* */ - /* Rounds value to double grid after adding engine compensation. */ - /* */ - /* */ - /* distance :: The distance to round. */ - /* */ - /* compensation :: The engine compensation. */ - /* */ - /* */ - /* Rounded distance. */ - /* */ + /************************************************************************** + * + * @Function: + * Round_To_Double_Grid + * + * @Description: + * Rounds value to double grid after adding engine compensation. + * + * @Input: + * distance :: + * The distance to round. + * + * compensation :: + * The engine compensation. + * + * @Return: + * Rounded distance. + */ static FT_F26Dot6 Round_To_Double_Grid( TT_ExecContext exc, FT_F26Dot6 distance, @@ -2130,28 +2168,30 @@ } - /*************************************************************************/ - /* */ - /* */ - /* Round_Super */ - /* */ - /* */ - /* Super-rounds value to grid after adding engine compensation. */ - /* */ - /* */ - /* distance :: The distance to round. */ - /* */ - /* compensation :: The engine compensation. */ - /* */ - /* */ - /* Rounded distance. */ - /* */ - /* */ - /* The TrueType specification says very little about the relationship */ - /* between rounding and engine compensation. However, it seems from */ - /* the description of super round that we should add the compensation */ - /* before rounding. */ - /* */ + /************************************************************************** + * + * @Function: + * Round_Super + * + * @Description: + * Super-rounds value to grid after adding engine compensation. + * + * @Input: + * distance :: + * The distance to round. + * + * compensation :: + * The engine compensation. + * + * @Return: + * Rounded distance. + * + * @Note: + * The TrueType specification says very little about the relationship + * between rounding and engine compensation. However, it seems from + * the description of super round that we should add the compensation + * before rounding. + */ static FT_F26Dot6 Round_Super( TT_ExecContext exc, FT_F26Dot6 distance, @@ -2165,7 +2205,7 @@ val = ADD_LONG( distance, exc->threshold - exc->phase + compensation ) & -exc->period; - val += exc->phase; + val = ADD_LONG( val, exc->phase ); if ( val < 0 ) val = exc->phase; } @@ -2174,7 +2214,7 @@ val = NEG_LONG( SUB_LONG( exc->threshold - exc->phase + compensation, distance ) & -exc->period ); - val -= exc->phase; + val = SUB_LONG( val, exc->phase ); if ( val > 0 ) val = -exc->phase; } @@ -2183,26 +2223,28 @@ } - /*************************************************************************/ - /* */ - /* */ - /* Round_Super_45 */ - /* */ - /* */ - /* Super-rounds value to grid after adding engine compensation. */ - /* */ - /* */ - /* distance :: The distance to round. */ - /* */ - /* compensation :: The engine compensation. */ - /* */ - /* */ - /* Rounded distance. */ - /* */ - /* */ - /* There is a separate function for Round_Super_45() as we may need */ - /* greater precision. */ - /* */ + /************************************************************************** + * + * @Function: + * Round_Super_45 + * + * @Description: + * Super-rounds value to grid after adding engine compensation. + * + * @Input: + * distance :: + * The distance to round. + * + * compensation :: + * The engine compensation. + * + * @Return: + * Rounded distance. + * + * @Note: + * There is a separate function for Round_Super_45() as we may need + * greater precision. + */ static FT_F26Dot6 Round_Super_45( TT_ExecContext exc, FT_F26Dot6 distance, @@ -2216,7 +2258,7 @@ val = ( ADD_LONG( distance, exc->threshold - exc->phase + compensation ) / exc->period ) * exc->period; - val += exc->phase; + val = ADD_LONG( val, exc->phase ); if ( val < 0 ) val = exc->phase; } @@ -2225,7 +2267,7 @@ val = NEG_LONG( ( SUB_LONG( exc->threshold - exc->phase + compensation, distance ) / exc->period ) * exc->period ); - val -= exc->phase; + val = SUB_LONG( val, exc->phase ); if ( val > 0 ) val = -exc->phase; } @@ -2234,17 +2276,18 @@ } - /*************************************************************************/ - /* */ - /* */ - /* Compute_Round */ - /* */ - /* */ - /* Sets the rounding mode. */ - /* */ - /* */ - /* round_mode :: The rounding mode to be used. */ - /* */ + /************************************************************************** + * + * @Function: + * Compute_Round + * + * @Description: + * Sets the rounding mode. + * + * @Input: + * round_mode :: + * The rounding mode to be used. + */ static void Compute_Round( TT_ExecContext exc, FT_Byte round_mode ) @@ -2286,19 +2329,21 @@ } - /*************************************************************************/ - /* */ - /* */ - /* SetSuperRound */ - /* */ - /* */ - /* Sets Super Round parameters. */ - /* */ - /* */ - /* GridPeriod :: The grid period. */ - /* */ - /* selector :: The SROUND opcode. */ - /* */ + /************************************************************************** + * + * @Function: + * SetSuperRound + * + * @Description: + * Sets Super Round parameters. + * + * @Input: + * GridPeriod :: + * The grid period. + * + * selector :: + * The SROUND opcode. + */ static void SetSuperRound( TT_ExecContext exc, FT_F2Dot14 GridPeriod, @@ -2355,22 +2400,24 @@ } - /*************************************************************************/ - /* */ - /* */ - /* Project */ - /* */ - /* */ - /* Computes the projection of vector given by (v2-v1) along the */ - /* current projection vector. */ - /* */ - /* */ - /* v1 :: First input vector. */ - /* v2 :: Second input vector. */ - /* */ - /* */ - /* The distance in F26dot6 format. */ - /* */ + /************************************************************************** + * + * @Function: + * Project + * + * @Description: + * Computes the projection of vector given by (v2-v1) along the + * current projection vector. + * + * @Input: + * v1 :: + * First input vector. + * v2 :: + * Second input vector. + * + * @Return: + * The distance in F26dot6 format. + */ static FT_F26Dot6 Project( TT_ExecContext exc, FT_Pos dx, @@ -2382,22 +2429,24 @@ } - /*************************************************************************/ - /* */ - /* */ - /* Dual_Project */ - /* */ - /* */ - /* Computes the projection of the vector given by (v2-v1) along the */ - /* current dual vector. */ - /* */ - /* */ - /* v1 :: First input vector. */ - /* v2 :: Second input vector. */ - /* */ - /* */ - /* The distance in F26dot6 format. */ - /* */ + /************************************************************************** + * + * @Function: + * Dual_Project + * + * @Description: + * Computes the projection of the vector given by (v2-v1) along the + * current dual vector. + * + * @Input: + * v1 :: + * First input vector. + * v2 :: + * Second input vector. + * + * @Return: + * The distance in F26dot6 format. + */ static FT_F26Dot6 Dual_Project( TT_ExecContext exc, FT_Pos dx, @@ -2409,22 +2458,24 @@ } - /*************************************************************************/ - /* */ - /* */ - /* Project_x */ - /* */ - /* */ - /* Computes the projection of the vector given by (v2-v1) along the */ - /* horizontal axis. */ - /* */ - /* */ - /* v1 :: First input vector. */ - /* v2 :: Second input vector. */ - /* */ - /* */ - /* The distance in F26dot6 format. */ - /* */ + /************************************************************************** + * + * @Function: + * Project_x + * + * @Description: + * Computes the projection of the vector given by (v2-v1) along the + * horizontal axis. + * + * @Input: + * v1 :: + * First input vector. + * v2 :: + * Second input vector. + * + * @Return: + * The distance in F26dot6 format. + */ static FT_F26Dot6 Project_x( TT_ExecContext exc, FT_Pos dx, @@ -2437,22 +2488,24 @@ } - /*************************************************************************/ - /* */ - /* */ - /* Project_y */ - /* */ - /* */ - /* Computes the projection of the vector given by (v2-v1) along the */ - /* vertical axis. */ - /* */ - /* */ - /* v1 :: First input vector. */ - /* v2 :: Second input vector. */ - /* */ - /* */ - /* The distance in F26dot6 format. */ - /* */ + /************************************************************************** + * + * @Function: + * Project_y + * + * @Description: + * Computes the projection of the vector given by (v2-v1) along the + * vertical axis. + * + * @Input: + * v1 :: + * First input vector. + * v2 :: + * Second input vector. + * + * @Return: + * The distance in F26dot6 format. + */ static FT_F26Dot6 Project_y( TT_ExecContext exc, FT_Pos dx, @@ -2465,15 +2518,15 @@ } - /*************************************************************************/ - /* */ - /* */ - /* Compute_Funcs */ - /* */ - /* */ - /* Computes the projection and movement function pointers according */ - /* to the current graphics state. */ - /* */ + /************************************************************************** + * + * @Function: + * Compute_Funcs + * + * @Description: + * Computes the projection and movement function pointers according + * to the current graphics state. + */ static void Compute_Funcs( TT_ExecContext exc ) { @@ -2528,28 +2581,31 @@ } - /*************************************************************************/ - /* */ - /* */ - /* Normalize */ - /* */ - /* */ - /* Norms a vector. */ - /* */ - /* */ - /* Vx :: The horizontal input vector coordinate. */ - /* Vy :: The vertical input vector coordinate. */ - /* */ - /* */ - /* R :: The normed unit vector. */ - /* */ - /* */ - /* Returns FAILURE if a vector parameter is zero. */ - /* */ - /* */ - /* In case Vx and Vy are both zero, `Normalize' returns SUCCESS, and */ - /* R is undefined. */ - /* */ + /************************************************************************** + * + * @Function: + * Normalize + * + * @Description: + * Norms a vector. + * + * @Input: + * Vx :: + * The horizontal input vector coordinate. + * Vy :: + * The vertical input vector coordinate. + * + * @Output: + * R :: + * The normed unit vector. + * + * @Return: + * Returns FAILURE if a vector parameter is zero. + * + * @Note: + * In case Vx and Vy are both zero, `Normalize' returns SUCCESS, and + * R is undefined. + */ static FT_Bool Normalize( FT_F26Dot6 Vx, FT_F26Dot6 Vy, @@ -2577,11 +2633,11 @@ } - /*************************************************************************/ - /* */ - /* Here we start with the implementation of the various opcodes. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * Here we start with the implementation of the various opcodes. + * + */ #define ARRAY_BOUND_ERROR \ @@ -2592,12 +2648,12 @@ } while (0) - /*************************************************************************/ - /* */ - /* MPPEM[]: Measure Pixel Per EM */ - /* Opcode range: 0x4B */ - /* Stack: --> Euint16 */ - /* */ + /************************************************************************** + * + * MPPEM[]: Measure Pixel Per EM + * Opcode range: 0x4B + * Stack: --> Euint16 + */ static void Ins_MPPEM( TT_ExecContext exc, FT_Long* args ) @@ -2606,12 +2662,12 @@ } - /*************************************************************************/ - /* */ - /* MPS[]: Measure Point Size */ - /* Opcode range: 0x4C */ - /* Stack: --> Euint16 */ - /* */ + /************************************************************************** + * + * MPS[]: Measure Point Size + * Opcode range: 0x4C + * Stack: --> Euint16 + */ static void Ins_MPS( TT_ExecContext exc, FT_Long* args ) @@ -2633,12 +2689,12 @@ } - /*************************************************************************/ - /* */ - /* DUP[]: DUPlicate the stack's top element */ - /* Opcode range: 0x20 */ - /* Stack: StkElt --> StkElt StkElt */ - /* */ + /************************************************************************** + * + * DUP[]: DUPlicate the stack's top element + * Opcode range: 0x20 + * Stack: StkElt --> StkElt StkElt + */ static void Ins_DUP( FT_Long* args ) { @@ -2646,12 +2702,12 @@ } - /*************************************************************************/ - /* */ - /* POP[]: POP the stack's top element */ - /* Opcode range: 0x21 */ - /* Stack: StkElt --> */ - /* */ + /************************************************************************** + * + * POP[]: POP the stack's top element + * Opcode range: 0x21 + * Stack: StkElt --> + */ static void Ins_POP( void ) { @@ -2659,12 +2715,12 @@ } - /*************************************************************************/ - /* */ - /* CLEAR[]: CLEAR the entire stack */ - /* Opcode range: 0x22 */ - /* Stack: StkElt... --> */ - /* */ + /************************************************************************** + * + * CLEAR[]: CLEAR the entire stack + * Opcode range: 0x22 + * Stack: StkElt... --> + */ static void Ins_CLEAR( TT_ExecContext exc ) { @@ -2672,12 +2728,12 @@ } - /*************************************************************************/ - /* */ - /* SWAP[]: SWAP the stack's top two elements */ - /* Opcode range: 0x23 */ - /* Stack: 2 * StkElt --> 2 * StkElt */ - /* */ + /************************************************************************** + * + * SWAP[]: SWAP the stack's top two elements + * Opcode range: 0x23 + * Stack: 2 * StkElt --> 2 * StkElt + */ static void Ins_SWAP( FT_Long* args ) { @@ -2690,12 +2746,12 @@ } - /*************************************************************************/ - /* */ - /* DEPTH[]: return the stack DEPTH */ - /* Opcode range: 0x24 */ - /* Stack: --> uint32 */ - /* */ + /************************************************************************** + * + * DEPTH[]: return the stack DEPTH + * Opcode range: 0x24 + * Stack: --> uint32 + */ static void Ins_DEPTH( TT_ExecContext exc, FT_Long* args ) @@ -2704,12 +2760,12 @@ } - /*************************************************************************/ - /* */ - /* LT[]: Less Than */ - /* Opcode range: 0x50 */ - /* Stack: int32? int32? --> bool */ - /* */ + /************************************************************************** + * + * LT[]: Less Than + * Opcode range: 0x50 + * Stack: int32? int32? --> bool + */ static void Ins_LT( FT_Long* args ) { @@ -2717,12 +2773,12 @@ } - /*************************************************************************/ - /* */ - /* LTEQ[]: Less Than or EQual */ - /* Opcode range: 0x51 */ - /* Stack: int32? int32? --> bool */ - /* */ + /************************************************************************** + * + * LTEQ[]: Less Than or EQual + * Opcode range: 0x51 + * Stack: int32? int32? --> bool + */ static void Ins_LTEQ( FT_Long* args ) { @@ -2730,12 +2786,12 @@ } - /*************************************************************************/ - /* */ - /* GT[]: Greater Than */ - /* Opcode range: 0x52 */ - /* Stack: int32? int32? --> bool */ - /* */ + /************************************************************************** + * + * GT[]: Greater Than + * Opcode range: 0x52 + * Stack: int32? int32? --> bool + */ static void Ins_GT( FT_Long* args ) { @@ -2743,12 +2799,12 @@ } - /*************************************************************************/ - /* */ - /* GTEQ[]: Greater Than or EQual */ - /* Opcode range: 0x53 */ - /* Stack: int32? int32? --> bool */ - /* */ + /************************************************************************** + * + * GTEQ[]: Greater Than or EQual + * Opcode range: 0x53 + * Stack: int32? int32? --> bool + */ static void Ins_GTEQ( FT_Long* args ) { @@ -2756,12 +2812,12 @@ } - /*************************************************************************/ - /* */ - /* EQ[]: EQual */ - /* Opcode range: 0x54 */ - /* Stack: StkElt StkElt --> bool */ - /* */ + /************************************************************************** + * + * EQ[]: EQual + * Opcode range: 0x54 + * Stack: StkElt StkElt --> bool + */ static void Ins_EQ( FT_Long* args ) { @@ -2769,12 +2825,12 @@ } - /*************************************************************************/ - /* */ - /* NEQ[]: Not EQual */ - /* Opcode range: 0x55 */ - /* Stack: StkElt StkElt --> bool */ - /* */ + /************************************************************************** + * + * NEQ[]: Not EQual + * Opcode range: 0x55 + * Stack: StkElt StkElt --> bool + */ static void Ins_NEQ( FT_Long* args ) { @@ -2782,12 +2838,12 @@ } - /*************************************************************************/ - /* */ - /* ODD[]: Is ODD */ - /* Opcode range: 0x56 */ - /* Stack: f26.6 --> bool */ - /* */ + /************************************************************************** + * + * ODD[]: Is ODD + * Opcode range: 0x56 + * Stack: f26.6 --> bool + */ static void Ins_ODD( TT_ExecContext exc, FT_Long* args ) @@ -2796,12 +2852,12 @@ } - /*************************************************************************/ - /* */ - /* EVEN[]: Is EVEN */ - /* Opcode range: 0x57 */ - /* Stack: f26.6 --> bool */ - /* */ + /************************************************************************** + * + * EVEN[]: Is EVEN + * Opcode range: 0x57 + * Stack: f26.6 --> bool + */ static void Ins_EVEN( TT_ExecContext exc, FT_Long* args ) @@ -2810,12 +2866,12 @@ } - /*************************************************************************/ - /* */ - /* AND[]: logical AND */ - /* Opcode range: 0x5A */ - /* Stack: uint32 uint32 --> uint32 */ - /* */ + /************************************************************************** + * + * AND[]: logical AND + * Opcode range: 0x5A + * Stack: uint32 uint32 --> uint32 + */ static void Ins_AND( FT_Long* args ) { @@ -2823,12 +2879,12 @@ } - /*************************************************************************/ - /* */ - /* OR[]: logical OR */ - /* Opcode range: 0x5B */ - /* Stack: uint32 uint32 --> uint32 */ - /* */ + /************************************************************************** + * + * OR[]: logical OR + * Opcode range: 0x5B + * Stack: uint32 uint32 --> uint32 + */ static void Ins_OR( FT_Long* args ) { @@ -2836,12 +2892,12 @@ } - /*************************************************************************/ - /* */ - /* NOT[]: logical NOT */ - /* Opcode range: 0x5C */ - /* Stack: StkElt --> uint32 */ - /* */ + /************************************************************************** + * + * NOT[]: logical NOT + * Opcode range: 0x5C + * Stack: StkElt --> uint32 + */ static void Ins_NOT( FT_Long* args ) { @@ -2849,12 +2905,12 @@ } - /*************************************************************************/ - /* */ - /* ADD[]: ADD */ - /* Opcode range: 0x60 */ - /* Stack: f26.6 f26.6 --> f26.6 */ - /* */ + /************************************************************************** + * + * ADD[]: ADD + * Opcode range: 0x60 + * Stack: f26.6 f26.6 --> f26.6 + */ static void Ins_ADD( FT_Long* args ) { @@ -2862,12 +2918,12 @@ } - /*************************************************************************/ - /* */ - /* SUB[]: SUBtract */ - /* Opcode range: 0x61 */ - /* Stack: f26.6 f26.6 --> f26.6 */ - /* */ + /************************************************************************** + * + * SUB[]: SUBtract + * Opcode range: 0x61 + * Stack: f26.6 f26.6 --> f26.6 + */ static void Ins_SUB( FT_Long* args ) { @@ -2875,12 +2931,12 @@ } - /*************************************************************************/ - /* */ - /* DIV[]: DIVide */ - /* Opcode range: 0x62 */ - /* Stack: f26.6 f26.6 --> f26.6 */ - /* */ + /************************************************************************** + * + * DIV[]: DIVide + * Opcode range: 0x62 + * Stack: f26.6 f26.6 --> f26.6 + */ static void Ins_DIV( TT_ExecContext exc, FT_Long* args ) @@ -2892,12 +2948,12 @@ } - /*************************************************************************/ - /* */ - /* MUL[]: MULtiply */ - /* Opcode range: 0x63 */ - /* Stack: f26.6 f26.6 --> f26.6 */ - /* */ + /************************************************************************** + * + * MUL[]: MULtiply + * Opcode range: 0x63 + * Stack: f26.6 f26.6 --> f26.6 + */ static void Ins_MUL( FT_Long* args ) { @@ -2905,12 +2961,12 @@ } - /*************************************************************************/ - /* */ - /* ABS[]: ABSolute value */ - /* Opcode range: 0x64 */ - /* Stack: f26.6 --> f26.6 */ - /* */ + /************************************************************************** + * + * ABS[]: ABSolute value + * Opcode range: 0x64 + * Stack: f26.6 --> f26.6 + */ static void Ins_ABS( FT_Long* args ) { @@ -2919,12 +2975,12 @@ } - /*************************************************************************/ - /* */ - /* NEG[]: NEGate */ - /* Opcode range: 0x65 */ - /* Stack: f26.6 --> f26.6 */ - /* */ + /************************************************************************** + * + * NEG[]: NEGate + * Opcode range: 0x65 + * Stack: f26.6 --> f26.6 + */ static void Ins_NEG( FT_Long* args ) { @@ -2932,12 +2988,12 @@ } - /*************************************************************************/ - /* */ - /* FLOOR[]: FLOOR */ - /* Opcode range: 0x66 */ - /* Stack: f26.6 --> f26.6 */ - /* */ + /************************************************************************** + * + * FLOOR[]: FLOOR + * Opcode range: 0x66 + * Stack: f26.6 --> f26.6 + */ static void Ins_FLOOR( FT_Long* args ) { @@ -2945,25 +3001,25 @@ } - /*************************************************************************/ - /* */ - /* CEILING[]: CEILING */ - /* Opcode range: 0x67 */ - /* Stack: f26.6 --> f26.6 */ - /* */ + /************************************************************************** + * + * CEILING[]: CEILING + * Opcode range: 0x67 + * Stack: f26.6 --> f26.6 + */ static void Ins_CEILING( FT_Long* args ) { - args[0] = FT_PIX_CEIL( args[0] ); + args[0] = FT_PIX_CEIL_LONG( args[0] ); } - /*************************************************************************/ - /* */ - /* RS[]: Read Store */ - /* Opcode range: 0x43 */ - /* Stack: uint32 --> uint32 */ - /* */ + /************************************************************************** + * + * RS[]: Read Store + * Opcode range: 0x43 + * Stack: uint32 --> uint32 + */ static void Ins_RS( TT_ExecContext exc, FT_Long* args ) @@ -3004,12 +3060,12 @@ } - /*************************************************************************/ - /* */ - /* WS[]: Write Store */ - /* Opcode range: 0x42 */ - /* Stack: uint32 uint32 --> */ - /* */ + /************************************************************************** + * + * WS[]: Write Store + * Opcode range: 0x42 + * Stack: uint32 uint32 --> + */ static void Ins_WS( TT_ExecContext exc, FT_Long* args ) @@ -3027,12 +3083,12 @@ } - /*************************************************************************/ - /* */ - /* WCVTP[]: Write CVT in Pixel units */ - /* Opcode range: 0x44 */ - /* Stack: f26.6 uint32 --> */ - /* */ + /************************************************************************** + * + * WCVTP[]: Write CVT in Pixel units + * Opcode range: 0x44 + * Stack: f26.6 uint32 --> + */ static void Ins_WCVTP( TT_ExecContext exc, FT_Long* args ) @@ -3050,12 +3106,12 @@ } - /*************************************************************************/ - /* */ - /* WCVTF[]: Write CVT in Funits */ - /* Opcode range: 0x70 */ - /* Stack: uint32 uint32 --> */ - /* */ + /************************************************************************** + * + * WCVTF[]: Write CVT in Funits + * Opcode range: 0x70 + * Stack: uint32 uint32 --> + */ static void Ins_WCVTF( TT_ExecContext exc, FT_Long* args ) @@ -3073,12 +3129,12 @@ } - /*************************************************************************/ - /* */ - /* RCVT[]: Read CVT */ - /* Opcode range: 0x45 */ - /* Stack: uint32 --> f26.6 */ - /* */ + /************************************************************************** + * + * RCVT[]: Read CVT + * Opcode range: 0x45 + * Stack: uint32 --> f26.6 + */ static void Ins_RCVT( TT_ExecContext exc, FT_Long* args ) @@ -3098,12 +3154,12 @@ } - /*************************************************************************/ - /* */ - /* AA[]: Adjust Angle */ - /* Opcode range: 0x7F */ - /* Stack: uint32 --> */ - /* */ + /************************************************************************** + * + * AA[]: Adjust Angle + * Opcode range: 0x7F + * Stack: uint32 --> + */ static void Ins_AA( void ) { @@ -3111,14 +3167,14 @@ } - /*************************************************************************/ - /* */ - /* DEBUG[]: DEBUG. Unsupported. */ - /* Opcode range: 0x4F */ - /* Stack: uint32 --> */ - /* */ - /* Note: The original instruction pops a value from the stack. */ - /* */ + /************************************************************************** + * + * DEBUG[]: DEBUG. Unsupported. + * Opcode range: 0x4F + * Stack: uint32 --> + * + * Note: The original instruction pops a value from the stack. + */ static void Ins_DEBUG( TT_ExecContext exc ) { @@ -3126,12 +3182,12 @@ } - /*************************************************************************/ - /* */ - /* ROUND[ab]: ROUND value */ - /* Opcode range: 0x68-0x6B */ - /* Stack: f26.6 --> f26.6 */ - /* */ + /************************************************************************** + * + * ROUND[ab]: ROUND value + * Opcode range: 0x68-0x6B + * Stack: f26.6 --> f26.6 + */ static void Ins_ROUND( TT_ExecContext exc, FT_Long* args ) @@ -3143,12 +3199,12 @@ } - /*************************************************************************/ - /* */ - /* NROUND[ab]: No ROUNDing of value */ - /* Opcode range: 0x6C-0x6F */ - /* Stack: f26.6 --> f26.6 */ - /* */ + /************************************************************************** + * + * NROUND[ab]: No ROUNDing of value + * Opcode range: 0x6C-0x6F + * Stack: f26.6 --> f26.6 + */ static void Ins_NROUND( TT_ExecContext exc, FT_Long* args ) @@ -3160,12 +3216,12 @@ } - /*************************************************************************/ - /* */ - /* MAX[]: MAXimum */ - /* Opcode range: 0x8B */ - /* Stack: int32? int32? --> int32 */ - /* */ + /************************************************************************** + * + * MAX[]: MAXimum + * Opcode range: 0x8B + * Stack: int32? int32? --> int32 + */ static void Ins_MAX( FT_Long* args ) { @@ -3174,12 +3230,12 @@ } - /*************************************************************************/ - /* */ - /* MIN[]: MINimum */ - /* Opcode range: 0x8C */ - /* Stack: int32? int32? --> int32 */ - /* */ + /************************************************************************** + * + * MIN[]: MINimum + * Opcode range: 0x8C + * Stack: int32? int32? --> int32 + */ static void Ins_MIN( FT_Long* args ) { @@ -3188,12 +3244,12 @@ } - /*************************************************************************/ - /* */ - /* MINDEX[]: Move INDEXed element */ - /* Opcode range: 0x26 */ - /* Stack: int32? --> StkElt */ - /* */ + /************************************************************************** + * + * MINDEX[]: Move INDEXed element + * Opcode range: 0x26 + * Stack: int32? --> StkElt + */ static void Ins_MINDEX( TT_ExecContext exc, FT_Long* args ) @@ -3221,12 +3277,12 @@ } - /*************************************************************************/ - /* */ - /* CINDEX[]: Copy INDEXed element */ - /* Opcode range: 0x25 */ - /* Stack: int32 --> StkElt */ - /* */ + /************************************************************************** + * + * CINDEX[]: Copy INDEXed element + * Opcode range: 0x25 + * Stack: int32 --> StkElt + */ static void Ins_CINDEX( TT_ExecContext exc, FT_Long* args ) @@ -3247,12 +3303,12 @@ } - /*************************************************************************/ - /* */ - /* ROLL[]: ROLL top three elements */ - /* Opcode range: 0x8A */ - /* Stack: 3 * StkElt --> 3 * StkElt */ - /* */ + /************************************************************************** + * + * ROLL[]: ROLL top three elements + * Opcode range: 0x8A + * Stack: 3 * StkElt --> 3 * StkElt + */ static void Ins_ROLL( FT_Long* args ) { @@ -3269,19 +3325,19 @@ } - /*************************************************************************/ - /* */ - /* MANAGING THE FLOW OF CONTROL */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * MANAGING THE FLOW OF CONTROL + * + */ - /*************************************************************************/ - /* */ - /* SLOOP[]: Set LOOP variable */ - /* Opcode range: 0x17 */ - /* Stack: int32? --> */ - /* */ + /************************************************************************** + * + * SLOOP[]: Set LOOP variable + * Opcode range: 0x17 + * Stack: int32? --> + */ static void Ins_SLOOP( TT_ExecContext exc, FT_Long* args ) @@ -3289,7 +3345,10 @@ if ( args[0] < 0 ) exc->error = FT_THROW( Bad_Argument ); else - exc->GS.loop = args[0]; + { + /* we heuristically limit the number of loops to 16 bits */ + exc->GS.loop = args[0] > 0xFFFFL ? 0xFFFFL : args[0]; + } } @@ -3320,12 +3379,12 @@ } - /*************************************************************************/ - /* */ - /* IF[]: IF test */ - /* Opcode range: 0x58 */ - /* Stack: StkElt --> */ - /* */ + /************************************************************************** + * + * IF[]: IF test + * Opcode range: 0x58 + * Stack: StkElt --> + */ static void Ins_IF( TT_ExecContext exc, FT_Long* args ) @@ -3364,12 +3423,12 @@ } - /*************************************************************************/ - /* */ - /* ELSE[]: ELSE */ - /* Opcode range: 0x1B */ - /* Stack: --> */ - /* */ + /************************************************************************** + * + * ELSE[]: ELSE + * Opcode range: 0x1B + * Stack: --> + */ static void Ins_ELSE( TT_ExecContext exc ) { @@ -3397,12 +3456,12 @@ } - /*************************************************************************/ - /* */ - /* EIF[]: End IF */ - /* Opcode range: 0x59 */ - /* Stack: --> */ - /* */ + /************************************************************************** + * + * EIF[]: End IF + * Opcode range: 0x59 + * Stack: --> + */ static void Ins_EIF( void ) { @@ -3410,12 +3469,12 @@ } - /*************************************************************************/ - /* */ - /* JMPR[]: JuMP Relative */ - /* Opcode range: 0x1C */ - /* Stack: int32 --> */ - /* */ + /************************************************************************** + * + * JMPR[]: JuMP Relative + * Opcode range: 0x1C + * Stack: int32 --> + */ static void Ins_JMPR( TT_ExecContext exc, FT_Long* args ) @@ -3445,12 +3504,12 @@ } - /*************************************************************************/ - /* */ - /* JROT[]: Jump Relative On True */ - /* Opcode range: 0x78 */ - /* Stack: StkElt int32 --> */ - /* */ + /************************************************************************** + * + * JROT[]: Jump Relative On True + * Opcode range: 0x78 + * Stack: StkElt int32 --> + */ static void Ins_JROT( TT_ExecContext exc, FT_Long* args ) @@ -3460,12 +3519,12 @@ } - /*************************************************************************/ - /* */ - /* JROF[]: Jump Relative On False */ - /* Opcode range: 0x79 */ - /* Stack: StkElt int32 --> */ - /* */ + /************************************************************************** + * + * JROF[]: Jump Relative On False + * Opcode range: 0x79 + * Stack: StkElt int32 --> + */ static void Ins_JROF( TT_ExecContext exc, FT_Long* args ) @@ -3475,19 +3534,19 @@ } - /*************************************************************************/ - /* */ - /* DEFINING AND USING FUNCTIONS AND INSTRUCTIONS */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * DEFINING AND USING FUNCTIONS AND INSTRUCTIONS + * + */ - /*************************************************************************/ - /* */ - /* FDEF[]: Function DEFinition */ - /* Opcode range: 0x2C */ - /* Stack: uint32 --> */ - /* */ + /************************************************************************** + * + * FDEF[]: Function DEFinition + * Opcode range: 0x2C + * Stack: uint32 --> + */ static void Ins_FDEF( TT_ExecContext exc, FT_Long* args ) @@ -3785,12 +3844,12 @@ } - /*************************************************************************/ - /* */ - /* ENDF[]: END Function definition */ - /* Opcode range: 0x2D */ - /* Stack: --> */ - /* */ + /************************************************************************** + * + * ENDF[]: END Function definition + * Opcode range: 0x2D + * Stack: --> + */ static void Ins_ENDF( TT_ExecContext exc ) { @@ -3834,12 +3893,12 @@ } - /*************************************************************************/ - /* */ - /* CALL[]: CALL function */ - /* Opcode range: 0x2B */ - /* Stack: uint32? --> */ - /* */ + /************************************************************************** + * + * CALL[]: CALL function + * Opcode range: 0x2B + * Stack: uint32? --> + */ static void Ins_CALL( TT_ExecContext exc, FT_Long* args ) @@ -3923,12 +3982,12 @@ } - /*************************************************************************/ - /* */ - /* LOOPCALL[]: LOOP and CALL function */ - /* Opcode range: 0x2A */ - /* Stack: uint32? Eint16? --> */ - /* */ + /************************************************************************** + * + * LOOPCALL[]: LOOP and CALL function + * Opcode range: 0x2A + * Stack: uint32? Eint16? --> + */ static void Ins_LOOPCALL( TT_ExecContext exc, FT_Long* args ) @@ -4016,12 +4075,12 @@ } - /*************************************************************************/ - /* */ - /* IDEF[]: Instruction DEFinition */ - /* Opcode range: 0x89 */ - /* Stack: Eint8 --> */ - /* */ + /************************************************************************** + * + * IDEF[]: Instruction DEFinition + * Opcode range: 0x89 + * Stack: Eint8 --> + */ static void Ins_IDEF( TT_ExecContext exc, FT_Long* args ) @@ -4091,19 +4150,19 @@ } - /*************************************************************************/ - /* */ - /* PUSHING DATA ONTO THE INTERPRETER STACK */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * PUSHING DATA ONTO THE INTERPRETER STACK + * + */ - /*************************************************************************/ - /* */ - /* NPUSHB[]: PUSH N Bytes */ - /* Opcode range: 0x40 */ - /* Stack: --> uint32... */ - /* */ + /************************************************************************** + * + * NPUSHB[]: PUSH N Bytes + * Opcode range: 0x40 + * Stack: --> uint32... + */ static void Ins_NPUSHB( TT_ExecContext exc, FT_Long* args ) @@ -4126,12 +4185,12 @@ } - /*************************************************************************/ - /* */ - /* NPUSHW[]: PUSH N Words */ - /* Opcode range: 0x41 */ - /* Stack: --> int32... */ - /* */ + /************************************************************************** + * + * NPUSHW[]: PUSH N Words + * Opcode range: 0x41 + * Stack: --> int32... + */ static void Ins_NPUSHW( TT_ExecContext exc, FT_Long* args ) @@ -4157,12 +4216,12 @@ } - /*************************************************************************/ - /* */ - /* PUSHB[abc]: PUSH Bytes */ - /* Opcode range: 0xB0-0xB7 */ - /* Stack: --> uint32... */ - /* */ + /************************************************************************** + * + * PUSHB[abc]: PUSH Bytes + * Opcode range: 0xB0-0xB7 + * Stack: --> uint32... + */ static void Ins_PUSHB( TT_ExecContext exc, FT_Long* args ) @@ -4183,12 +4242,12 @@ } - /*************************************************************************/ - /* */ - /* PUSHW[abc]: PUSH Words */ - /* Opcode range: 0xB8-0xBF */ - /* Stack: --> int32... */ - /* */ + /************************************************************************** + * + * PUSHW[abc]: PUSH Words + * Opcode range: 0xB8-0xBF + * Stack: --> int32... + */ static void Ins_PUSHW( TT_ExecContext exc, FT_Long* args ) @@ -4213,11 +4272,11 @@ } - /*************************************************************************/ - /* */ - /* MANAGING THE GRAPHICS STATE */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * MANAGING THE GRAPHICS STATE + * + */ static FT_Bool @@ -4271,20 +4330,20 @@ } - /*************************************************************************/ - /* */ - /* SVTCA[a]: Set (F and P) Vectors to Coordinate Axis */ - /* Opcode range: 0x00-0x01 */ - /* Stack: --> */ - /* */ - /* SPvTCA[a]: Set PVector to Coordinate Axis */ - /* Opcode range: 0x02-0x03 */ - /* Stack: --> */ - /* */ - /* SFvTCA[a]: Set FVector to Coordinate Axis */ - /* Opcode range: 0x04-0x05 */ - /* Stack: --> */ - /* */ + /************************************************************************** + * + * SVTCA[a]: Set (F and P) Vectors to Coordinate Axis + * Opcode range: 0x00-0x01 + * Stack: --> + * + * SPvTCA[a]: Set PVector to Coordinate Axis + * Opcode range: 0x02-0x03 + * Stack: --> + * + * SFvTCA[a]: Set FVector to Coordinate Axis + * Opcode range: 0x04-0x05 + * Stack: --> + */ static void Ins_SxyTCA( TT_ExecContext exc ) { @@ -4315,12 +4374,12 @@ } - /*************************************************************************/ - /* */ - /* SPvTL[a]: Set PVector To Line */ - /* Opcode range: 0x06-0x07 */ - /* Stack: uint32 uint32 --> */ - /* */ + /************************************************************************** + * + * SPvTL[a]: Set PVector To Line + * Opcode range: 0x06-0x07 + * Stack: uint32 uint32 --> + */ static void Ins_SPVTL( TT_ExecContext exc, FT_Long* args ) @@ -4336,12 +4395,12 @@ } - /*************************************************************************/ - /* */ - /* SFvTL[a]: Set FVector To Line */ - /* Opcode range: 0x08-0x09 */ - /* Stack: uint32 uint32 --> */ - /* */ + /************************************************************************** + * + * SFvTL[a]: Set FVector To Line + * Opcode range: 0x08-0x09 + * Stack: uint32 uint32 --> + */ static void Ins_SFVTL( TT_ExecContext exc, FT_Long* args ) @@ -4356,12 +4415,12 @@ } - /*************************************************************************/ - /* */ - /* SFvTPv[]: Set FVector To PVector */ - /* Opcode range: 0x0E */ - /* Stack: --> */ - /* */ + /************************************************************************** + * + * SFvTPv[]: Set FVector To PVector + * Opcode range: 0x0E + * Stack: --> + */ static void Ins_SFVTPV( TT_ExecContext exc ) { @@ -4370,12 +4429,12 @@ } - /*************************************************************************/ - /* */ - /* SPvFS[]: Set PVector From Stack */ - /* Opcode range: 0x0A */ - /* Stack: f2.14 f2.14 --> */ - /* */ + /************************************************************************** + * + * SPvFS[]: Set PVector From Stack + * Opcode range: 0x0A + * Stack: f2.14 f2.14 --> + */ static void Ins_SPVFS( TT_ExecContext exc, FT_Long* args ) @@ -4397,12 +4456,12 @@ } - /*************************************************************************/ - /* */ - /* SFvFS[]: Set FVector From Stack */ - /* Opcode range: 0x0B */ - /* Stack: f2.14 f2.14 --> */ - /* */ + /************************************************************************** + * + * SFvFS[]: Set FVector From Stack + * Opcode range: 0x0B + * Stack: f2.14 f2.14 --> + */ static void Ins_SFVFS( TT_ExecContext exc, FT_Long* args ) @@ -4422,12 +4481,12 @@ } - /*************************************************************************/ - /* */ - /* GPv[]: Get Projection Vector */ - /* Opcode range: 0x0C */ - /* Stack: ef2.14 --> ef2.14 */ - /* */ + /************************************************************************** + * + * GPv[]: Get Projection Vector + * Opcode range: 0x0C + * Stack: ef2.14 --> ef2.14 + */ static void Ins_GPV( TT_ExecContext exc, FT_Long* args ) @@ -4437,12 +4496,12 @@ } - /*************************************************************************/ - /* */ - /* GFv[]: Get Freedom Vector */ - /* Opcode range: 0x0D */ - /* Stack: ef2.14 --> ef2.14 */ - /* */ + /************************************************************************** + * + * GFv[]: Get Freedom Vector + * Opcode range: 0x0D + * Stack: ef2.14 --> ef2.14 + */ static void Ins_GFV( TT_ExecContext exc, FT_Long* args ) @@ -4452,12 +4511,12 @@ } - /*************************************************************************/ - /* */ - /* SRP0[]: Set Reference Point 0 */ - /* Opcode range: 0x10 */ - /* Stack: uint32 --> */ - /* */ + /************************************************************************** + * + * SRP0[]: Set Reference Point 0 + * Opcode range: 0x10 + * Stack: uint32 --> + */ static void Ins_SRP0( TT_ExecContext exc, FT_Long* args ) @@ -4466,12 +4525,12 @@ } - /*************************************************************************/ - /* */ - /* SRP1[]: Set Reference Point 1 */ - /* Opcode range: 0x11 */ - /* Stack: uint32 --> */ - /* */ + /************************************************************************** + * + * SRP1[]: Set Reference Point 1 + * Opcode range: 0x11 + * Stack: uint32 --> + */ static void Ins_SRP1( TT_ExecContext exc, FT_Long* args ) @@ -4480,12 +4539,12 @@ } - /*************************************************************************/ - /* */ - /* SRP2[]: Set Reference Point 2 */ - /* Opcode range: 0x12 */ - /* Stack: uint32 --> */ - /* */ + /************************************************************************** + * + * SRP2[]: Set Reference Point 2 + * Opcode range: 0x12 + * Stack: uint32 --> + */ static void Ins_SRP2( TT_ExecContext exc, FT_Long* args ) @@ -4494,12 +4553,12 @@ } - /*************************************************************************/ - /* */ - /* SMD[]: Set Minimum Distance */ - /* Opcode range: 0x1A */ - /* Stack: f26.6 --> */ - /* */ + /************************************************************************** + * + * SMD[]: Set Minimum Distance + * Opcode range: 0x1A + * Stack: f26.6 --> + */ static void Ins_SMD( TT_ExecContext exc, FT_Long* args ) @@ -4508,12 +4567,12 @@ } - /*************************************************************************/ - /* */ - /* SCVTCI[]: Set Control Value Table Cut In */ - /* Opcode range: 0x1D */ - /* Stack: f26.6 --> */ - /* */ + /************************************************************************** + * + * SCVTCI[]: Set Control Value Table Cut In + * Opcode range: 0x1D + * Stack: f26.6 --> + */ static void Ins_SCVTCI( TT_ExecContext exc, FT_Long* args ) @@ -4522,12 +4581,12 @@ } - /*************************************************************************/ - /* */ - /* SSWCI[]: Set Single Width Cut In */ - /* Opcode range: 0x1E */ - /* Stack: f26.6 --> */ - /* */ + /************************************************************************** + * + * SSWCI[]: Set Single Width Cut In + * Opcode range: 0x1E + * Stack: f26.6 --> + */ static void Ins_SSWCI( TT_ExecContext exc, FT_Long* args ) @@ -4536,12 +4595,12 @@ } - /*************************************************************************/ - /* */ - /* SSW[]: Set Single Width */ - /* Opcode range: 0x1F */ - /* Stack: int32? --> */ - /* */ + /************************************************************************** + * + * SSW[]: Set Single Width + * Opcode range: 0x1F + * Stack: int32? --> + */ static void Ins_SSW( TT_ExecContext exc, FT_Long* args ) @@ -4551,12 +4610,12 @@ } - /*************************************************************************/ - /* */ - /* FLIPON[]: Set auto-FLIP to ON */ - /* Opcode range: 0x4D */ - /* Stack: --> */ - /* */ + /************************************************************************** + * + * FLIPON[]: Set auto-FLIP to ON + * Opcode range: 0x4D + * Stack: --> + */ static void Ins_FLIPON( TT_ExecContext exc ) { @@ -4564,12 +4623,12 @@ } - /*************************************************************************/ - /* */ - /* FLIPOFF[]: Set auto-FLIP to OFF */ - /* Opcode range: 0x4E */ - /* Stack: --> */ - /* */ + /************************************************************************** + * + * FLIPOFF[]: Set auto-FLIP to OFF + * Opcode range: 0x4E + * Stack: --> + */ static void Ins_FLIPOFF( TT_ExecContext exc ) { @@ -4577,12 +4636,12 @@ } - /*************************************************************************/ - /* */ - /* SANGW[]: Set ANGle Weight */ - /* Opcode range: 0x7E */ - /* Stack: uint32 --> */ - /* */ + /************************************************************************** + * + * SANGW[]: Set ANGle Weight + * Opcode range: 0x7E + * Stack: uint32 --> + */ static void Ins_SANGW( void ) { @@ -4590,12 +4649,12 @@ } - /*************************************************************************/ - /* */ - /* SDB[]: Set Delta Base */ - /* Opcode range: 0x5E */ - /* Stack: uint32 --> */ - /* */ + /************************************************************************** + * + * SDB[]: Set Delta Base + * Opcode range: 0x5E + * Stack: uint32 --> + */ static void Ins_SDB( TT_ExecContext exc, FT_Long* args ) @@ -4604,12 +4663,12 @@ } - /*************************************************************************/ - /* */ - /* SDS[]: Set Delta Shift */ - /* Opcode range: 0x5F */ - /* Stack: uint32 --> */ - /* */ + /************************************************************************** + * + * SDS[]: Set Delta Shift + * Opcode range: 0x5F + * Stack: uint32 --> + */ static void Ins_SDS( TT_ExecContext exc, FT_Long* args ) @@ -4621,12 +4680,12 @@ } - /*************************************************************************/ - /* */ - /* RTHG[]: Round To Half Grid */ - /* Opcode range: 0x19 */ - /* Stack: --> */ - /* */ + /************************************************************************** + * + * RTHG[]: Round To Half Grid + * Opcode range: 0x19 + * Stack: --> + */ static void Ins_RTHG( TT_ExecContext exc ) { @@ -4635,12 +4694,12 @@ } - /*************************************************************************/ - /* */ - /* RTG[]: Round To Grid */ - /* Opcode range: 0x18 */ - /* Stack: --> */ - /* */ + /************************************************************************** + * + * RTG[]: Round To Grid + * Opcode range: 0x18 + * Stack: --> + */ static void Ins_RTG( TT_ExecContext exc ) { @@ -4649,11 +4708,11 @@ } - /*************************************************************************/ - /* RTDG[]: Round To Double Grid */ - /* Opcode range: 0x3D */ - /* Stack: --> */ - /* */ + /************************************************************************** + * RTDG[]: Round To Double Grid + * Opcode range: 0x3D + * Stack: --> + */ static void Ins_RTDG( TT_ExecContext exc ) { @@ -4662,11 +4721,11 @@ } - /*************************************************************************/ - /* RUTG[]: Round Up To Grid */ - /* Opcode range: 0x7C */ - /* Stack: --> */ - /* */ + /************************************************************************** + * RUTG[]: Round Up To Grid + * Opcode range: 0x7C + * Stack: --> + */ static void Ins_RUTG( TT_ExecContext exc ) { @@ -4675,12 +4734,12 @@ } - /*************************************************************************/ - /* */ - /* RDTG[]: Round Down To Grid */ - /* Opcode range: 0x7D */ - /* Stack: --> */ - /* */ + /************************************************************************** + * + * RDTG[]: Round Down To Grid + * Opcode range: 0x7D + * Stack: --> + */ static void Ins_RDTG( TT_ExecContext exc ) { @@ -4689,12 +4748,12 @@ } - /*************************************************************************/ - /* */ - /* ROFF[]: Round OFF */ - /* Opcode range: 0x7A */ - /* Stack: --> */ - /* */ + /************************************************************************** + * + * ROFF[]: Round OFF + * Opcode range: 0x7A + * Stack: --> + */ static void Ins_ROFF( TT_ExecContext exc ) { @@ -4703,12 +4762,12 @@ } - /*************************************************************************/ - /* */ - /* SROUND[]: Super ROUND */ - /* Opcode range: 0x76 */ - /* Stack: Eint8 --> */ - /* */ + /************************************************************************** + * + * SROUND[]: Super ROUND + * Opcode range: 0x76 + * Stack: Eint8 --> + */ static void Ins_SROUND( TT_ExecContext exc, FT_Long* args ) @@ -4720,12 +4779,12 @@ } - /*************************************************************************/ - /* */ - /* S45ROUND[]: Super ROUND 45 degrees */ - /* Opcode range: 0x77 */ - /* Stack: uint32 --> */ - /* */ + /************************************************************************** + * + * S45ROUND[]: Super ROUND 45 degrees + * Opcode range: 0x77 + * Stack: uint32 --> + */ static void Ins_S45ROUND( TT_ExecContext exc, FT_Long* args ) @@ -4737,15 +4796,15 @@ } - /*************************************************************************/ - /* */ - /* GC[a]: Get Coordinate projected onto */ - /* Opcode range: 0x46-0x47 */ - /* Stack: uint32 --> f26.6 */ - /* */ - /* XXX: UNDOCUMENTED: Measures from the original glyph must be taken */ - /* along the dual projection vector! */ - /* */ + /************************************************************************** + * + * GC[a]: Get Coordinate projected onto + * Opcode range: 0x46-0x47 + * Stack: uint32 --> f26.6 + * + * XXX: UNDOCUMENTED: Measures from the original glyph must be taken + * along the dual projection vector! + */ static void Ins_GC( TT_ExecContext exc, FT_Long* args ) @@ -4774,16 +4833,16 @@ } - /*************************************************************************/ - /* */ - /* SCFS[]: Set Coordinate From Stack */ - /* Opcode range: 0x48 */ - /* Stack: f26.6 uint32 --> */ - /* */ - /* Formula: */ - /* */ - /* OA := OA + ( value - OA.p )/( f.p ) * f */ - /* */ + /************************************************************************** + * + * SCFS[]: Set Coordinate From Stack + * Opcode range: 0x48 + * Stack: f26.6 uint32 --> + * + * Formula: + * + * OA := OA + ( value - OA.p )/( f.p ) * f + */ static void Ins_SCFS( TT_ExecContext exc, FT_Long* args ) @@ -4812,21 +4871,21 @@ } - /*************************************************************************/ - /* */ - /* MD[a]: Measure Distance */ - /* Opcode range: 0x49-0x4A */ - /* Stack: uint32 uint32 --> f26.6 */ - /* */ - /* XXX: UNDOCUMENTED: Measure taken in the original glyph must be along */ - /* the dual projection vector. */ - /* */ - /* XXX: UNDOCUMENTED: Flag attributes are inverted! */ - /* 0 => measure distance in original outline */ - /* 1 => measure distance in grid-fitted outline */ - /* */ - /* XXX: UNDOCUMENTED: `zp0 - zp1', and not `zp2 - zp1! */ - /* */ + /************************************************************************** + * + * MD[a]: Measure Distance + * Opcode range: 0x49-0x4A + * Stack: uint32 uint32 --> f26.6 + * + * XXX: UNDOCUMENTED: Measure taken in the original glyph must be along + * the dual projection vector. + * + * XXX: UNDOCUMENTED: Flag attributes are inverted! + * 0 => measure distance in original outline + * 1 => measure distance in grid-fitted outline + * + * XXX: UNDOCUMENTED: `zp0 - zp1', and not `zp2 - zp1! + */ static void Ins_MD( TT_ExecContext exc, FT_Long* args ) @@ -4899,12 +4958,12 @@ } - /*************************************************************************/ - /* */ - /* SDPvTL[a]: Set Dual PVector to Line */ - /* Opcode range: 0x86-0x87 */ - /* Stack: uint32 uint32 --> */ - /* */ + /************************************************************************** + * + * SDPvTL[a]: Set Dual PVector to Line + * Opcode range: 0x86-0x87 + * Stack: uint32 uint32 --> + */ static void Ins_SDPVTL( TT_ExecContext exc, FT_Long* args ) @@ -4982,12 +5041,12 @@ } - /*************************************************************************/ - /* */ - /* SZP0[]: Set Zone Pointer 0 */ - /* Opcode range: 0x13 */ - /* Stack: uint32 --> */ - /* */ + /************************************************************************** + * + * SZP0[]: Set Zone Pointer 0 + * Opcode range: 0x13 + * Stack: uint32 --> + */ static void Ins_SZP0( TT_ExecContext exc, FT_Long* args ) @@ -5012,12 +5071,12 @@ } - /*************************************************************************/ - /* */ - /* SZP1[]: Set Zone Pointer 1 */ - /* Opcode range: 0x14 */ - /* Stack: uint32 --> */ - /* */ + /************************************************************************** + * + * SZP1[]: Set Zone Pointer 1 + * Opcode range: 0x14 + * Stack: uint32 --> + */ static void Ins_SZP1( TT_ExecContext exc, FT_Long* args ) @@ -5042,12 +5101,12 @@ } - /*************************************************************************/ - /* */ - /* SZP2[]: Set Zone Pointer 2 */ - /* Opcode range: 0x15 */ - /* Stack: uint32 --> */ - /* */ + /************************************************************************** + * + * SZP2[]: Set Zone Pointer 2 + * Opcode range: 0x15 + * Stack: uint32 --> + */ static void Ins_SZP2( TT_ExecContext exc, FT_Long* args ) @@ -5072,12 +5131,12 @@ } - /*************************************************************************/ - /* */ - /* SZPS[]: Set Zone PointerS */ - /* Opcode range: 0x16 */ - /* Stack: uint32 --> */ - /* */ + /************************************************************************** + * + * SZPS[]: Set Zone PointerS + * Opcode range: 0x16 + * Stack: uint32 --> + */ static void Ins_SZPS( TT_ExecContext exc, FT_Long* args ) @@ -5107,12 +5166,12 @@ } - /*************************************************************************/ - /* */ - /* INSTCTRL[]: INSTruction ConTRoL */ - /* Opcode range: 0x8E */ - /* Stack: int32 int32 --> */ - /* */ + /************************************************************************** + * + * INSTCTRL[]: INSTruction ConTRoL + * Opcode range: 0x8E + * Stack: int32 int32 --> + */ static void Ins_INSTCTRL( TT_ExecContext exc, FT_Long* args ) @@ -5169,12 +5228,12 @@ } - /*************************************************************************/ - /* */ - /* SCANCTRL[]: SCAN ConTRoL */ - /* Opcode range: 0x85 */ - /* Stack: uint32? --> */ - /* */ + /************************************************************************** + * + * SCANCTRL[]: SCAN ConTRoL + * Opcode range: 0x85 + * Stack: uint32? --> + */ static void Ins_SCANCTRL( TT_ExecContext exc, FT_Long* args ) @@ -5216,12 +5275,12 @@ } - /*************************************************************************/ - /* */ - /* SCANTYPE[]: SCAN TYPE */ - /* Opcode range: 0x8D */ - /* Stack: uint16 --> */ - /* */ + /************************************************************************** + * + * SCANTYPE[]: SCAN TYPE + * Opcode range: 0x8D + * Stack: uint16 --> + */ static void Ins_SCANTYPE( TT_ExecContext exc, FT_Long* args ) @@ -5231,19 +5290,19 @@ } - /*************************************************************************/ - /* */ - /* MANAGING OUTLINES */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * MANAGING OUTLINES + * + */ - /*************************************************************************/ - /* */ - /* FLIPPT[]: FLIP PoinT */ - /* Opcode range: 0x80 */ - /* Stack: uint32... --> */ - /* */ + /************************************************************************** + * + * FLIPPT[]: FLIP PoinT + * Opcode range: 0x80 + * Stack: uint32... --> + */ static void Ins_FLIPPT( TT_ExecContext exc ) { @@ -5292,12 +5351,12 @@ } - /*************************************************************************/ - /* */ - /* FLIPRGON[]: FLIP RanGe ON */ - /* Opcode range: 0x81 */ - /* Stack: uint32 uint32 --> */ - /* */ + /************************************************************************** + * + * FLIPRGON[]: FLIP RanGe ON + * Opcode range: 0x81 + * Stack: uint32 uint32 --> + */ static void Ins_FLIPRGON( TT_ExecContext exc, FT_Long* args ) @@ -5330,12 +5389,12 @@ } - /*************************************************************************/ - /* */ - /* FLIPRGOFF: FLIP RanGe OFF */ - /* Opcode range: 0x82 */ - /* Stack: uint32 uint32 --> */ - /* */ + /************************************************************************** + * + * FLIPRGOFF: FLIP RanGe OFF + * Opcode range: 0x82 + * Stack: uint32 uint32 --> + */ static void Ins_FLIPRGOFF( TT_ExecContext exc, FT_Long* args ) @@ -5447,12 +5506,12 @@ } - /*************************************************************************/ - /* */ - /* SHP[a]: SHift Point by the last point */ - /* Opcode range: 0x32-0x33 */ - /* Stack: uint32... --> */ - /* */ + /************************************************************************** + * + * SHP[a]: SHift Point by the last point + * Opcode range: 0x32-0x33 + * Stack: uint32... --> + */ static void Ins_SHP( TT_ExecContext exc ) { @@ -5504,16 +5563,16 @@ } - /*************************************************************************/ - /* */ - /* SHC[a]: SHift Contour */ - /* Opcode range: 0x34-35 */ - /* Stack: uint32 --> */ - /* */ - /* UNDOCUMENTED: According to Greg Hitchcock, there is one (virtual) */ - /* contour in the twilight zone, namely contour number */ - /* zero which includes all points of it. */ - /* */ + /************************************************************************** + * + * SHC[a]: SHift Contour + * Opcode range: 0x34-35 + * Stack: uint32 --> + * + * UNDOCUMENTED: According to Greg Hitchcock, there is one (virtual) + * contour in the twilight zone, namely contour number + * zero which includes all points of it. + */ static void Ins_SHC( TT_ExecContext exc, FT_Long* args ) @@ -5560,12 +5619,12 @@ } - /*************************************************************************/ - /* */ - /* SHZ[a]: SHift Zone */ - /* Opcode range: 0x36-37 */ - /* Stack: uint32 --> */ - /* */ + /************************************************************************** + * + * SHZ[a]: SHift Zone + * Opcode range: 0x36-37 + * Stack: uint32 --> + */ static void Ins_SHZ( TT_ExecContext exc, FT_Long* args ) @@ -5608,12 +5667,12 @@ } - /*************************************************************************/ - /* */ - /* SHPIX[]: SHift points by a PIXel amount */ - /* Opcode range: 0x38 */ - /* Stack: f26.6 uint32... --> */ - /* */ + /************************************************************************** + * + * SHPIX[]: SHift points by a PIXel amount + * Opcode range: 0x38 + * Stack: f26.6 uint32... --> + */ static void Ins_SHPIX( TT_ExecContext exc, FT_Long* args ) @@ -5768,12 +5827,12 @@ } - /*************************************************************************/ - /* */ - /* MSIRP[a]: Move Stack Indirect Relative Position */ - /* Opcode range: 0x3A-0x3B */ - /* Stack: f26.6 uint32 --> */ - /* */ + /************************************************************************** + * + * MSIRP[a]: Move Stack Indirect Relative Position + * Opcode range: 0x3A-0x3B + * Stack: f26.6 uint32 --> + */ static void Ins_MSIRP( TT_ExecContext exc, FT_Long* args ) @@ -5782,6 +5841,7 @@ FT_F26Dot6 distance; #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY FT_F26Dot6 control_value_cutin = 0; + FT_F26Dot6 delta; if ( SUBPIXEL_HINTING_INFINALITY ) @@ -5817,11 +5877,15 @@ distance = PROJECT( exc->zp1.cur + point, exc->zp0.cur + exc->GS.rp0 ); #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + delta = SUB_LONG( distance, args[1] ); + if ( delta < 0 ) + delta = NEG_LONG( delta ); + /* subpixel hinting - make MSIRP respect CVT cut-in; */ - if ( SUBPIXEL_HINTING_INFINALITY && - exc->ignore_x_mode && - exc->GS.freeVector.x != 0 && - FT_ABS( SUB_LONG( distance, args[1] ) ) >= control_value_cutin ) + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + exc->GS.freeVector.x != 0 && + delta >= control_value_cutin ) distance = args[1]; #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ @@ -5838,12 +5902,12 @@ } - /*************************************************************************/ - /* */ - /* MDAP[a]: Move Direct Absolute Point */ - /* Opcode range: 0x2E-0x2F */ - /* Stack: uint32 --> */ - /* */ + /************************************************************************** + * + * MDAP[a]: Move Direct Absolute Point + * Opcode range: 0x2E-0x2F + * Stack: uint32 --> + */ static void Ins_MDAP( TT_ExecContext exc, FT_Long* args ) @@ -5869,16 +5933,18 @@ if ( SUBPIXEL_HINTING_INFINALITY && exc->ignore_x_mode && exc->GS.freeVector.x != 0 ) - distance = Round_None( - exc, - cur_dist, - exc->tt_metrics.compensations[0] ) - cur_dist; + distance = SUB_LONG( + Round_None( exc, + cur_dist, + exc->tt_metrics.compensations[0] ), + cur_dist ); else #endif - distance = exc->func_round( - exc, - cur_dist, - exc->tt_metrics.compensations[0] ) - cur_dist; + distance = SUB_LONG( + exc->func_round( exc, + cur_dist, + exc->tt_metrics.compensations[0] ), + cur_dist ); } else distance = 0; @@ -5890,12 +5956,12 @@ } - /*************************************************************************/ - /* */ - /* MIAP[a]: Move Indirect Absolute Point */ - /* Opcode range: 0x3E-0x3F */ - /* Stack: uint32 uint32 --> */ - /* */ + /************************************************************************** + * + * MIAP[a]: Move Indirect Absolute Point + * Opcode range: 0x3E-0x3F + * Stack: uint32 uint32 --> + */ static void Ins_MIAP( TT_ExecContext exc, FT_Long* args ) @@ -5978,7 +6044,14 @@ if ( ( exc->opcode & 1 ) != 0 ) /* rounding and control cut-in flag */ { - if ( FT_ABS( distance - org_dist ) > control_value_cutin ) + FT_F26Dot6 delta; + + + delta = SUB_LONG( distance, org_dist ); + if ( delta < 0 ) + delta = NEG_LONG( delta ); + + if ( delta > control_value_cutin ) distance = org_dist; #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY @@ -6003,12 +6076,12 @@ } - /*************************************************************************/ - /* */ - /* MDRP[abcde]: Move Direct Relative Point */ - /* Opcode range: 0xC0-0xDF */ - /* Stack: uint32 --> */ - /* */ + /************************************************************************** + * + * MDRP[abcde]: Move Direct Relative Point + * Opcode range: 0xC0-0xDF + * Stack: uint32 --> + */ static void Ins_MDRP( TT_ExecContext exc, FT_Long* args ) @@ -6147,12 +6220,12 @@ } - /*************************************************************************/ - /* */ - /* MIRP[abcde]: Move Indirect Relative Point */ - /* Opcode range: 0xE0-0xFF */ - /* Stack: int32? uint32 --> */ - /* */ + /************************************************************************** + * + * MIRP[abcde]: Move Indirect Relative Point + * Opcode range: 0xE0-0xFF + * Stack: int32? uint32 --> + */ static void Ins_MIRP( TT_ExecContext exc, FT_Long* args ) @@ -6172,11 +6245,13 @@ FT_Bool reverse_move = FALSE; #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ + FT_F26Dot6 delta; + minimum_distance = exc->GS.minimum_distance; control_value_cutin = exc->GS.control_value_cutin; point = (FT_UShort)args[0]; - cvtEntry = (FT_ULong)( args[1] + 1 ); + cvtEntry = (FT_ULong)( ADD_LONG( args[1], 1 ) ); #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY if ( SUBPIXEL_HINTING_INFINALITY && @@ -6204,8 +6279,11 @@ /* single width test */ - if ( FT_ABS( cvt_dist - exc->GS.single_width_value ) < - exc->GS.single_width_cutin ) + delta = SUB_LONG( cvt_dist, exc->GS.single_width_value ); + if ( delta < 0 ) + delta = NEG_LONG( delta ); + + if ( delta < exc->GS.single_width_cutin ) { if ( cvt_dist >= 0 ) cvt_dist = exc->GS.single_width_value; @@ -6234,7 +6312,7 @@ if ( exc->GS.auto_flip ) { if ( ( org_dist ^ cvt_dist ) < 0 ) - cvt_dist = -cvt_dist; + cvt_dist = NEG_LONG( cvt_dist ); } #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY @@ -6271,7 +6349,11 @@ /* `ttinst2.doc', version 1.66, is thus incorrect since */ /* it implies `>=' instead of `>'. */ - if ( FT_ABS( cvt_dist - org_dist ) > control_value_cutin ) + delta = SUB_LONG( cvt_dist, org_dist ); + if ( delta < 0 ) + delta = NEG_LONG( delta ); + + if ( delta > control_value_cutin ) cvt_dist = org_dist; } @@ -6289,7 +6371,11 @@ exc->ignore_x_mode && exc->GS.gep0 == exc->GS.gep1 ) { - if ( FT_ABS( cvt_dist - org_dist ) > control_value_cutin ) + delta = SUB_LONG( cvt_dist, org_dist ); + if ( delta < 0 ) + delta = NEG_LONG( delta ); + + if ( delta > control_value_cutin ) cvt_dist = org_dist; } #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ @@ -6381,12 +6467,12 @@ } - /*************************************************************************/ - /* */ - /* ALIGNRP[]: ALIGN Relative Point */ - /* Opcode range: 0x3C */ - /* Stack: uint32 uint32... --> */ - /* */ + /************************************************************************** + * + * ALIGNRP[]: ALIGN Relative Point + * Opcode range: 0x3C + * Stack: uint32 uint32... --> + */ static void Ins_ALIGNRP( TT_ExecContext exc ) { @@ -6444,12 +6530,12 @@ } - /*************************************************************************/ - /* */ - /* ISECT[]: moves point to InterSECTion */ - /* Opcode range: 0x0F */ - /* Stack: 5 * uint32 --> */ - /* */ + /************************************************************************** + * + * ISECT[]: moves point to InterSECTion + * Opcode range: 0x0F + * Stack: 5 * uint32 --> + */ static void Ins_ISECT( TT_ExecContext exc, FT_Long* args ) @@ -6540,12 +6626,12 @@ } - /*************************************************************************/ - /* */ - /* ALIGNPTS[]: ALIGN PoinTS */ - /* Opcode range: 0x27 */ - /* Stack: uint32 uint32 --> */ - /* */ + /************************************************************************** + * + * ALIGNPTS[]: ALIGN PoinTS + * Opcode range: 0x27 + * Stack: uint32 uint32 --> + */ static void Ins_ALIGNPTS( TT_ExecContext exc, FT_Long* args ) @@ -6572,12 +6658,12 @@ } - /*************************************************************************/ - /* */ - /* IP[]: Interpolate Point */ - /* Opcode range: 0x39 */ - /* Stack: uint32... --> */ - /* */ + /************************************************************************** + * + * IP[]: Interpolate Point + * Opcode range: 0x39 + * Stack: uint32... --> + */ /* SOMETIMES, DUMBER CODE IS BETTER CODE */ @@ -6732,12 +6818,12 @@ } - /*************************************************************************/ - /* */ - /* UTP[a]: UnTouch Point */ - /* Opcode range: 0x29 */ - /* Stack: uint32 --> */ - /* */ + /************************************************************************** + * + * UTP[a]: UnTouch Point + * Opcode range: 0x29 + * Stack: uint32 --> + */ static void Ins_UTP( TT_ExecContext exc, FT_Long* args ) @@ -6901,12 +6987,12 @@ } - /*************************************************************************/ - /* */ - /* IUP[a]: Interpolate Untouched Points */ - /* Opcode range: 0x30-0x31 */ - /* Stack: --> */ - /* */ + /************************************************************************** + * + * IUP[a]: Interpolate Untouched Points + * Opcode range: 0x30-0x31 + * Stack: --> + */ static void Ins_IUP( TT_ExecContext exc ) { @@ -7029,12 +7115,12 @@ } - /*************************************************************************/ - /* */ - /* DELTAPn[]: DELTA exceptions P1, P2, P3 */ - /* Opcode range: 0x5D,0x71,0x72 */ - /* Stack: uint32 (2 * uint32)... --> */ - /* */ + /************************************************************************** + * + * DELTAPn[]: DELTA exceptions P1, P2, P3 + * Opcode range: 0x5D,0x71,0x72 + * Stack: uint32 (2 * uint32)... --> + */ static void Ins_DELTAP( TT_ExecContext exc, FT_Long* args ) @@ -7111,12 +7197,12 @@ if ( SUBPIXEL_HINTING_INFINALITY ) { /* - * Allow delta move if + * Allow delta move if * - * - not using ignore_x_mode rendering, - * - glyph is specifically set to allow it, or - * - glyph is composite and freedom vector is not in subpixel - * direction. + * - not using ignore_x_mode rendering, + * - glyph is specifically set to allow it, or + * - glyph is composite and freedom vector is not in subpixel + * direction. */ if ( !exc->ignore_x_mode || ( exc->sph_tweak_flags & SPH_TWEAK_ALWAYS_DO_DELTAP ) || @@ -7196,12 +7282,12 @@ } - /*************************************************************************/ - /* */ - /* DELTACn[]: DELTA exceptions C1, C2, C3 */ - /* Opcode range: 0x73,0x74,0x75 */ - /* Stack: uint32 (2 * uint32)... --> */ - /* */ + /************************************************************************** + * + * DELTACn[]: DELTA exceptions C1, C2, C3 + * Opcode range: 0x73,0x74,0x75 + * Stack: uint32 (2 * uint32)... --> + */ static void Ins_DELTAC( TT_ExecContext exc, FT_Long* args ) @@ -7274,27 +7360,27 @@ } - /*************************************************************************/ - /* */ - /* MISC. INSTRUCTIONS */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * MISC. INSTRUCTIONS + * + */ - /*************************************************************************/ - /* */ - /* GETINFO[]: GET INFOrmation */ - /* Opcode range: 0x88 */ - /* Stack: uint32 --> uint32 */ - /* */ - /* XXX: UNDOCUMENTED: Selector bits higher than 9 are currently (May */ - /* 2015) not documented in the OpenType specification. */ - /* */ - /* Selector bit 11 is incorrectly described as bit 8, while the */ - /* real meaning of bit 8 (vertical LCD subpixels) stays */ - /* undocumented. The same mistake can be found in Greg Hitchcock's */ - /* whitepaper. */ - /* */ + /************************************************************************** + * + * GETINFO[]: GET INFOrmation + * Opcode range: 0x88 + * Stack: uint32 --> uint32 + * + * XXX: UNDOCUMENTED: Selector bits higher than 9 are currently (May + * 2015) not documented in the OpenType specification. + * + * Selector bit 11 is incorrectly described as bit 8, while the + * real meaning of bit 8 (vertical LCD subpixels) stays + * undocumented. The same mistake can be found in Greg Hitchcock's + * whitepaper. + */ static void Ins_GETINFO( TT_ExecContext exc, FT_Long* args ) @@ -7306,11 +7392,11 @@ K = 0; #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - /********************************/ - /* RASTERIZER VERSION */ - /* Selector Bit: 0 */ - /* Return Bit(s): 0-7 */ - /* */ + /********************************* + * RASTERIZER VERSION + * Selector Bit: 0 + * Return Bit(s): 0-7 + */ if ( SUBPIXEL_HINTING_INFINALITY && ( args[0] & 1 ) != 0 && exc->subpixel_hinting ) @@ -7331,39 +7417,40 @@ if ( ( args[0] & 1 ) != 0 ) K = driver->interpreter_version; - /********************************/ - /* GLYPH ROTATED */ - /* Selector Bit: 1 */ - /* Return Bit(s): 8 */ - /* */ + /********************************* + * GLYPH ROTATED + * Selector Bit: 1 + * Return Bit(s): 8 + */ if ( ( args[0] & 2 ) != 0 && exc->tt_metrics.rotated ) K |= 1 << 8; - /********************************/ - /* GLYPH STRETCHED */ - /* Selector Bit: 2 */ - /* Return Bit(s): 9 */ - /* */ + /********************************* + * GLYPH STRETCHED + * Selector Bit: 2 + * Return Bit(s): 9 + */ if ( ( args[0] & 4 ) != 0 && exc->tt_metrics.stretched ) K |= 1 << 9; #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - /********************************/ - /* VARIATION GLYPH */ - /* Selector Bit: 3 */ - /* Return Bit(s): 10 */ - /* */ - /* XXX: UNDOCUMENTED! */ + /********************************* + * VARIATION GLYPH + * Selector Bit: 3 + * Return Bit(s): 10 + * + * XXX: UNDOCUMENTED! + */ if ( (args[0] & 8 ) != 0 && exc->face->blend ) K |= 1 << 10; #endif - /********************************/ - /* BI-LEVEL HINTING AND */ - /* GRAYSCALE RENDERING */ - /* Selector Bit: 5 */ - /* Return Bit(s): 12 */ - /* */ + /********************************* + * BI-LEVEL HINTING AND + * GRAYSCALE RENDERING + * Selector Bit: 5 + * Return Bit(s): 12 + */ if ( ( args[0] & 32 ) != 0 && exc->grayscale ) K |= 1 << 12; @@ -7374,50 +7461,54 @@ /* Bold Italic'. */ if ( SUBPIXEL_HINTING_MINIMAL && exc->subpixel_hinting_lean ) { - /********************************/ - /* HINTING FOR SUBPIXEL */ - /* Selector Bit: 6 */ - /* Return Bit(s): 13 */ - /* */ - /* v40 does subpixel hinting by default. */ + /********************************* + * HINTING FOR SUBPIXEL + * Selector Bit: 6 + * Return Bit(s): 13 + * + * v40 does subpixel hinting by default. + */ if ( ( args[0] & 64 ) != 0 ) K |= 1 << 13; - /********************************/ - /* VERTICAL LCD SUBPIXELS? */ - /* Selector Bit: 8 */ - /* Return Bit(s): 15 */ - /* */ + /********************************* + * VERTICAL LCD SUBPIXELS? + * Selector Bit: 8 + * Return Bit(s): 15 + */ if ( ( args[0] & 256 ) != 0 && exc->vertical_lcd_lean ) K |= 1 << 15; - /********************************/ - /* SUBPIXEL POSITIONED? */ - /* Selector Bit: 10 */ - /* Return Bit(s): 17 */ - /* */ - /* XXX: FreeType supports it, dependent on what client does? */ + /********************************* + * SUBPIXEL POSITIONED? + * Selector Bit: 10 + * Return Bit(s): 17 + * + * XXX: FreeType supports it, dependent on what client does? + */ if ( ( args[0] & 1024 ) != 0 ) K |= 1 << 17; - /********************************/ - /* SYMMETRICAL SMOOTHING */ - /* Selector Bit: 11 */ - /* Return Bit(s): 18 */ - /* */ - /* The only smoothing method FreeType supports unless someone sets */ - /* FT_LOAD_TARGET_MONO. */ + /********************************* + * SYMMETRICAL SMOOTHING + * Selector Bit: 11 + * Return Bit(s): 18 + * + * The only smoothing method FreeType supports unless someone sets + * FT_LOAD_TARGET_MONO. + */ if ( ( args[0] & 2048 ) != 0 && exc->subpixel_hinting_lean ) K |= 1 << 18; - /********************************/ - /* CLEARTYPE HINTING AND */ - /* GRAYSCALE RENDERING */ - /* Selector Bit: 12 */ - /* Return Bit(s): 19 */ - /* */ - /* Grayscale rendering is what FreeType does anyway unless someone */ - /* sets FT_LOAD_TARGET_MONO or FT_LOAD_TARGET_LCD(_V) */ + /********************************* + * CLEARTYPE HINTING AND + * GRAYSCALE RENDERING + * Selector Bit: 12 + * Return Bit(s): 19 + * + * Grayscale rendering is what FreeType does anyway unless someone + * sets FT_LOAD_TARGET_MONO or FT_LOAD_TARGET_LCD(_V) + */ if ( ( args[0] & 4096 ) != 0 && exc->grayscale_cleartype ) K |= 1 << 19; } @@ -7431,67 +7522,73 @@ if ( exc->rasterizer_version >= 37 ) { - /********************************/ - /* HINTING FOR SUBPIXEL */ - /* Selector Bit: 6 */ - /* Return Bit(s): 13 */ - /* */ + /********************************* + * HINTING FOR SUBPIXEL + * Selector Bit: 6 + * Return Bit(s): 13 + */ if ( ( args[0] & 64 ) != 0 && exc->subpixel_hinting ) K |= 1 << 13; - /********************************/ - /* COMPATIBLE WIDTHS ENABLED */ - /* Selector Bit: 7 */ - /* Return Bit(s): 14 */ - /* */ - /* Functionality still needs to be added */ + /********************************* + * COMPATIBLE WIDTHS ENABLED + * Selector Bit: 7 + * Return Bit(s): 14 + * + * Functionality still needs to be added + */ if ( ( args[0] & 128 ) != 0 && exc->compatible_widths ) K |= 1 << 14; - /********************************/ - /* VERTICAL LCD SUBPIXELS? */ - /* Selector Bit: 8 */ - /* Return Bit(s): 15 */ - /* */ - /* Functionality still needs to be added */ + /********************************* + * VERTICAL LCD SUBPIXELS? + * Selector Bit: 8 + * Return Bit(s): 15 + * + * Functionality still needs to be added + */ if ( ( args[0] & 256 ) != 0 && exc->vertical_lcd ) K |= 1 << 15; - /********************************/ - /* HINTING FOR BGR? */ - /* Selector Bit: 9 */ - /* Return Bit(s): 16 */ - /* */ - /* Functionality still needs to be added */ + /********************************* + * HINTING FOR BGR? + * Selector Bit: 9 + * Return Bit(s): 16 + * + * Functionality still needs to be added + */ if ( ( args[0] & 512 ) != 0 && exc->bgr ) K |= 1 << 16; if ( exc->rasterizer_version >= 38 ) { - /********************************/ - /* SUBPIXEL POSITIONED? */ - /* Selector Bit: 10 */ - /* Return Bit(s): 17 */ - /* */ - /* Functionality still needs to be added */ + /********************************* + * SUBPIXEL POSITIONED? + * Selector Bit: 10 + * Return Bit(s): 17 + * + * Functionality still needs to be added + */ if ( ( args[0] & 1024 ) != 0 && exc->subpixel_positioned ) K |= 1 << 17; - /********************************/ - /* SYMMETRICAL SMOOTHING */ - /* Selector Bit: 11 */ - /* Return Bit(s): 18 */ - /* */ - /* Functionality still needs to be added */ + /********************************* + * SYMMETRICAL SMOOTHING + * Selector Bit: 11 + * Return Bit(s): 18 + * + * Functionality still needs to be added + */ if ( ( args[0] & 2048 ) != 0 && exc->symmetrical_smoothing ) K |= 1 << 18; - /********************************/ - /* GRAY CLEARTYPE */ - /* Selector Bit: 12 */ - /* Return Bit(s): 19 */ - /* */ - /* Functionality still needs to be added */ + /********************************* + * GRAY CLEARTYPE + * Selector Bit: 12 + * Return Bit(s): 19 + * + * Functionality still needs to be added + */ if ( ( args[0] & 4096 ) != 0 && exc->gray_cleartype ) K |= 1 << 19; } @@ -7506,16 +7603,16 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - /*************************************************************************/ - /* */ - /* GETVARIATION[]: get normalized variation (blend) coordinates */ - /* Opcode range: 0x91 */ - /* Stack: --> f2.14... */ - /* */ - /* XXX: UNDOCUMENTED! There is no official documentation from Apple for */ - /* this bytecode instruction. Active only if a font has GX */ - /* variation axes. */ - /* */ + /************************************************************************** + * + * GETVARIATION[]: get normalized variation (blend) coordinates + * Opcode range: 0x91 + * Stack: --> f2.14... + * + * XXX: UNDOCUMENTED! There is no official documentation from Apple for + * this bytecode instruction. Active only if a font has GX + * variation axes. + */ static void Ins_GETVARIATION( TT_ExecContext exc, FT_Long* args ) @@ -7532,20 +7629,28 @@ return; } - for ( i = 0; i < num_axes; i++ ) - args[i] = coords[i] >> 2; /* convert 16.16 to 2.14 format */ + if ( coords ) + { + for ( i = 0; i < num_axes; i++ ) + args[i] = coords[i] >> 2; /* convert 16.16 to 2.14 format */ + } + else + { + for ( i = 0; i < num_axes; i++ ) + args[i] = 0; + } } - /*************************************************************************/ - /* */ - /* GETDATA[]: no idea what this is good for */ - /* Opcode range: 0x92 */ - /* Stack: --> 17 */ - /* */ - /* XXX: UNDOCUMENTED! There is no documentation from Apple for this */ - /* very weird bytecode instruction. */ - /* */ + /************************************************************************** + * + * GETDATA[]: no idea what this is good for + * Opcode range: 0x92 + * Stack: --> 17 + * + * XXX: UNDOCUMENTED! There is no documentation from Apple for this + * very weird bytecode instruction. + */ static void Ins_GETDATA( FT_Long* args ) { @@ -7593,34 +7698,34 @@ } - /*************************************************************************/ - /* */ - /* RUN */ - /* */ - /* This function executes a run of opcodes. It will exit in the */ - /* following cases: */ - /* */ - /* - Errors (in which case it returns FALSE). */ - /* */ - /* - Reaching the end of the main code range (returns TRUE). */ - /* Reaching the end of a code range within a function call is an */ - /* error. */ - /* */ - /* - After executing one single opcode, if the flag `Instruction_Trap' */ - /* is set to TRUE (returns TRUE). */ - /* */ - /* On exit with TRUE, test IP < CodeSize to know whether it comes from */ - /* an instruction trap or a normal termination. */ - /* */ - /* */ - /* Note: The documented DEBUG opcode pops a value from the stack. This */ - /* behaviour is unsupported; here a DEBUG opcode is always an */ - /* error. */ - /* */ - /* */ - /* THIS IS THE INTERPRETER'S MAIN LOOP. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * RUN + * + * This function executes a run of opcodes. It will exit in the + * following cases: + * + * - Errors (in which case it returns FALSE). + * + * - Reaching the end of the main code range (returns TRUE). + * Reaching the end of a code range within a function call is an + * error. + * + * - After executing one single opcode, if the flag `Instruction_Trap' + * is set to TRUE (returns TRUE). + * + * On exit with TRUE, test IP < CodeSize to know whether it comes from + * an instruction trap or a normal termination. + * + * + * Note: The documented DEBUG opcode pops a value from the stack. This + * behaviour is unsupported; here a DEBUG opcode is always an + * error. + * + * + * THIS IS THE INTERPRETER'S MAIN LOOP. + * + */ /* documentation is in ttinterp.h */ @@ -7652,16 +7757,16 @@ #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL /* - * Toggle backward compatibility according to what font wants, except - * when + * Toggle backward compatibility according to what font wants, except + * when * - * 1) we have a `tricky' font that heavily relies on the interpreter to - * render glyphs correctly, for example DFKai-SB, or - * 2) FT_RENDER_MODE_MONO (i.e, monochome rendering) is requested. + * 1) we have a `tricky' font that heavily relies on the interpreter to + * render glyphs correctly, for example DFKai-SB, or + * 2) FT_RENDER_MODE_MONO (i.e, monochome rendering) is requested. * - * In those cases, backward compatibility needs to be turned off to get - * correct rendering. The rendering is then completely up to the - * font's programming. + * In those cases, backward compatibility needs to be turned off to get + * correct rendering. The rendering is then completely up to the + * font's programming. * */ if ( SUBPIXEL_HINTING_MINIMAL && @@ -7762,7 +7867,7 @@ /* and the first few stack elements also */ FT_TRACE6(( " " )); FT_TRACE7(( "%06d ", exc->IP )); - FT_TRACE6(( opcode_name[exc->opcode] + 2 )); + FT_TRACE6(( "%s", opcode_name[exc->opcode] + 2 )); FT_TRACE7(( "%*s", *opcode_name[exc->opcode] == 'A' ? 2 : 12 - ( *opcode_name[exc->opcode] - '0' ), @@ -8487,8 +8592,8 @@ LNo_Error_: FT_TRACE4(( " %d instruction%s executed\n", - ins_counter == 1 ? "" : "s", - ins_counter )); + ins_counter, + ins_counter == 1 ? "" : "s" )); return FT_Err_Ok; LErrorCodeOverflow_: diff --git a/sdk/lib/3rdparty/freetype/src/truetype/ttinterp.h b/sdk/lib/3rdparty/freetype/src/truetype/ttinterp.h index 2966439ea25f3..0cb1e892fb858 100644 --- a/sdk/lib/3rdparty/freetype/src/truetype/ttinterp.h +++ b/sdk/lib/3rdparty/freetype/src/truetype/ttinterp.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ttinterp.h */ -/* */ -/* TrueType bytecode interpreter (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ttinterp.h + * + * TrueType bytecode interpreter (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef TTINTERP_H_ @@ -26,10 +26,10 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* Rounding mode constants. */ - /* */ + /************************************************************************** + * + * Rounding mode constants. + */ #define TT_Round_Off 5 #define TT_Round_To_Half_Grid 0 #define TT_Round_To_Grid 1 @@ -40,13 +40,13 @@ FT_BEGIN_HEADER #define TT_Round_Super_45 7 - /*************************************************************************/ - /* */ - /* Function types used by the interpreter, depending on various modes */ - /* (e.g. the rounding mode, whether to render a vertical or horizontal */ - /* line etc). */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * Function types used by the interpreter, depending on various modes + * (e.g. the rounding mode, whether to render a vertical or horizontal + * line etc). + * + */ /* Rounding function */ typedef FT_F26Dot6 @@ -84,10 +84,10 @@ FT_BEGIN_HEADER FT_F26Dot6 value ); - /*************************************************************************/ - /* */ - /* This structure defines a call record, used to manage function calls. */ - /* */ + /************************************************************************** + * + * This structure defines a call record, used to manage function calls. + */ typedef struct TT_CallRec_ { FT_Int Caller_Range; @@ -101,11 +101,11 @@ FT_BEGIN_HEADER #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - /*************************************************************************/ - /* */ - /* These structures define rules used to tweak subpixel hinting for */ - /* various fonts. "", 0, "", NULL value indicates to match any value. */ - /* */ + /************************************************************************** + * + * These structures define rules used to tweak subpixel hinting for + * various fonts. "", 0, "", NULL value indicates to match any value. + */ #define SPH_MAX_NAME_SIZE 32 #define SPH_MAX_CLASS_MEMBERS 100 @@ -141,11 +141,11 @@ FT_BEGIN_HEADER #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - /*************************************************************************/ - /* */ - /* The main structure for the interpreter which collects all necessary */ - /* variables and states. */ - /* */ + /************************************************************************** + * + * The main structure for the interpreter which collects all necessary + * variables and states. + */ typedef struct TT_ExecContextRec_ { TT_Face face; @@ -352,7 +352,7 @@ FT_BEGIN_HEADER * https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx * * [3] Beat Stamm describes it in more detail: - * http://www.beatstamm.com/typography/RTRCh4.htm#Sec12 + * http://rastertragedy.com/RTRCh4.htm#Sec12. * * [4] The list of `native ClearType' fonts is small at the time of this * writing; I found the following on a Windows 10 Update 1511 @@ -464,26 +464,27 @@ FT_BEGIN_HEADER #endif /* TT_USE_BYTECODE_INTERPRETER */ - /*************************************************************************/ - /* */ - /* */ - /* TT_New_Context */ - /* */ - /* */ - /* Queries the face context for a given font. Note that there is */ - /* now a _single_ execution context in the TrueType driver which is */ - /* shared among faces. */ - /* */ - /* */ - /* face :: A handle to the source face object. */ - /* */ - /* */ - /* A handle to the execution context. Initialized for `face'. */ - /* */ - /* */ - /* Only the glyph loader and debugger should call this function. */ - /* (And right now only the glyph loader uses it.) */ - /* */ + /************************************************************************** + * + * @Function: + * TT_New_Context + * + * @Description: + * Queries the face context for a given font. Note that there is + * now a _single_ execution context in the TrueType driver which is + * shared among faces. + * + * @Input: + * face :: + * A handle to the source face object. + * + * @Return: + * A handle to the execution context. Initialized for `face'. + * + * @Note: + * Only the glyph loader and debugger should call this function. + * (And right now only the glyph loader uses it.) + */ FT_EXPORT( TT_ExecContext ) TT_New_Context( TT_Driver driver ); @@ -506,27 +507,28 @@ FT_BEGIN_HEADER #endif /* TT_USE_BYTECODE_INTERPRETER */ - /*************************************************************************/ - /* */ - /* */ - /* TT_RunIns */ - /* */ - /* */ - /* Executes one or more instruction in the execution context. This */ - /* is the main function of the TrueType opcode interpreter. */ - /* */ - /* */ - /* exec :: A handle to the target execution context. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Only the object manager and debugger should call this function. */ - /* */ - /* This function is publicly exported because it is directly */ - /* invoked by the TrueType debugger. */ - /* */ + /************************************************************************** + * + * @Function: + * TT_RunIns + * + * @Description: + * Executes one or more instruction in the execution context. This + * is the main function of the TrueType opcode interpreter. + * + * @Input: + * exec :: + * A handle to the target execution context. + * + * @Return: + * FreeType error code. 0 means success. + * + * @Note: + * Only the object manager and debugger should call this function. + * + * This function is publicly exported because it is directly + * invoked by the TrueType debugger. + */ FT_EXPORT( FT_Error ) TT_RunIns( TT_ExecContext exec ); diff --git a/sdk/lib/3rdparty/freetype/src/truetype/ttobjs.c b/sdk/lib/3rdparty/freetype/src/truetype/ttobjs.c index bc8086f256840..f3a432cedd6fa 100644 --- a/sdk/lib/3rdparty/freetype/src/truetype/ttobjs.c +++ b/sdk/lib/3rdparty/freetype/src/truetype/ttobjs.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ttobjs.c */ -/* */ -/* Objects manager (body). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ttobjs.c + * + * Objects manager (body). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include @@ -36,36 +36,37 @@ #include "ttgxvar.h" #endif - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_ttobjs +#define FT_COMPONENT ttobjs #ifdef TT_USE_BYTECODE_INTERPRETER - /*************************************************************************/ - /* */ - /* GLYPH ZONE FUNCTIONS */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* tt_glyphzone_done */ - /* */ - /* */ - /* Deallocate a glyph zone. */ - /* */ - /* */ - /* zone :: A pointer to the target glyph zone. */ - /* */ + /************************************************************************** + * + * GLYPH ZONE FUNCTIONS + * + */ + + + /************************************************************************** + * + * @Function: + * tt_glyphzone_done + * + * @Description: + * Deallocate a glyph zone. + * + * @Input: + * zone :: + * A pointer to the target glyph zone. + */ FT_LOCAL_DEF( void ) tt_glyphzone_done( TT_GlyphZone zone ) { @@ -87,27 +88,31 @@ } - /*************************************************************************/ - /* */ - /* */ - /* tt_glyphzone_new */ - /* */ - /* */ - /* Allocate a new glyph zone. */ - /* */ - /* */ - /* memory :: A handle to the current memory object. */ - /* */ - /* maxPoints :: The capacity of glyph zone in points. */ - /* */ - /* maxContours :: The capacity of glyph zone in contours. */ - /* */ - /* */ - /* zone :: A pointer to the target glyph zone record. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * tt_glyphzone_new + * + * @Description: + * Allocate a new glyph zone. + * + * @Input: + * memory :: + * A handle to the current memory object. + * + * maxPoints :: + * The capacity of glyph zone in points. + * + * maxContours :: + * The capacity of glyph zone in contours. + * + * @Output: + * zone :: + * A pointer to the target glyph zone record. + * + * @Return: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) tt_glyphzone_new( FT_Memory memory, FT_UShort maxPoints, @@ -147,7 +152,7 @@ { #define TRICK_NAMES_MAX_CHARACTERS 19 -#define TRICK_NAMES_COUNT 23 +#define TRICK_NAMES_COUNT 26 static const char trick_names[TRICK_NAMES_COUNT] [TRICK_NAMES_MAX_CHARACTERS + 1] = @@ -167,12 +172,15 @@ "DFGirl-W6-WIN-BF", /* dftt-h6.ttf; version 1.00, 1993 */ "DFGothic-EB", /* DynaLab Inc. 1992-1995 */ "DFGyoSho-Lt", /* DynaLab Inc. 1992-1995 */ + "DFHei-Md-HK-BF", /* maybe DynaLab Inc. */ "DFHSGothic-W5", /* DynaLab Inc. 1992-1995 */ "DFHSMincho-W3", /* DynaLab Inc. 1992-1995 */ "DFHSMincho-W7", /* DynaLab Inc. 1992-1995 */ "DFKaiSho-SB", /* dfkaisb.ttf */ "DFKaiShu", + "DFKaiShu-Md-HK-BF", /* maybe DynaLab Inc. */ "DFKai-SB", /* kaiu.ttf; version 3.00, 1998 [DFKaiShu-SB-Estd-BF] */ + "DFMing-Bd-HK-BF", /* maybe DynaLab Inc. */ "DLC", /* dftt-m7.ttf; version 1.00, 1993 [DLCMingBold] */ /* dftt-f5.ttf; version 1.00, 1993 [DLCFongSung] */ "DLCHayMedium", /* dftt-b5.ttf; version 1.00, 1993 */ @@ -270,7 +278,7 @@ tt_check_trickyness_sfnt_ids( TT_Face face ) { #define TRICK_SFNT_IDS_PER_FACE 3 -#define TRICK_SFNT_IDS_NUM_FACES 26 +#define TRICK_SFNT_IDS_NUM_FACES 29 static const tt_sfnt_id_rec sfnt_id[TRICK_SFNT_IDS_NUM_FACES] [TRICK_SFNT_IDS_PER_FACE] = { @@ -299,6 +307,11 @@ { 0xCE5956E9UL, 0x0000BC85UL }, /* fpgm */ { 0x8272F416UL, 0x00000045UL } /* prep */ }, + { /* DFHei-Md-HK-BF */ + { 0x1257EB46UL, 0x00000350UL }, /* cvt */ + { 0xF699D160UL, 0x0000715FUL }, /* fpgm */ + { 0xD222F568UL, 0x000003BCUL } /* prep */ + }, { /* DFHSGothic-W5 */ { 0x1262EB4EUL, 0x00000350UL }, /* cvt */ { 0xE86A5D64UL, 0x00007940UL }, /* fpgm */ @@ -324,6 +337,16 @@ { 0xA6E78C01UL, 0x00008998UL }, /* fpgm */ { 0x13A42602UL, 0x0000007EUL } /* prep */ }, + { /* DFKaiShu-Md-HK-BF */ + { 0x11E5EAD4UL, 0x00000360UL }, /* cvt */ + { 0x9DB282B2UL, 0x0000C06EUL }, /* fpgm */ + { 0x53E6D7CAUL, 0x00000082UL } /* prep */ + }, + { /* DFMing-Bd-HK-BF */ + { 0x1243EB18UL, 0x00000350UL }, /* cvt */ + { 0xBA0A8C30UL, 0x000074ADUL }, /* fpgm */ + { 0xF3D83409UL, 0x0000037BUL } /* prep */ + }, { /* DLCLiShu */ { 0x07DCF546UL, 0x00000308UL }, /* cvt */ { 0x40FE7C90UL, 0x00008E2AUL }, /* fpgm */ @@ -548,32 +571,37 @@ } - /*************************************************************************/ - /* */ - /* */ - /* tt_face_init */ - /* */ - /* */ - /* Initialize a given TrueType face object. */ - /* */ - /* */ - /* stream :: The source font stream. */ - /* */ - /* face_index :: The index of the TrueType font, if we are opening a */ - /* collection, in bits 0-15. The numbered instance */ - /* index~+~1 of a GX (sub)font, if applicable, in bits */ - /* 16-30. */ - /* */ - /* num_params :: Number of additional generic parameters. Ignored. */ - /* */ - /* params :: Additional generic parameters. Ignored. */ - /* */ - /* */ - /* face :: The newly built face object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * tt_face_init + * + * @Description: + * Initialize a given TrueType face object. + * + * @Input: + * stream :: + * The source font stream. + * + * face_index :: + * The index of the TrueType font, if we are opening a + * collection, in bits 0-15. The numbered instance + * index~+~1 of a GX (sub)font, if applicable, in bits + * 16-30. + * + * num_params :: + * Number of additional generic parameters. Ignored. + * + * params :: + * Additional generic parameters. Ignored. + * + * @InOut: + * face :: + * The newly built face object. + * + * @Return: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) tt_face_init( FT_Stream stream, FT_Face ttface, /* TT_Face */ @@ -725,17 +753,18 @@ } - /*************************************************************************/ - /* */ - /* */ - /* tt_face_done */ - /* */ - /* */ - /* Finalize a given face object. */ - /* */ - /* */ - /* face :: A pointer to the face object to destroy. */ - /* */ + /************************************************************************** + * + * @Function: + * tt_face_done + * + * @Description: + * Finalize a given face object. + * + * @Input: + * face :: + * A pointer to the face object to destroy. + */ FT_LOCAL_DEF( void ) tt_face_done( FT_Face ttface ) /* TT_Face */ { @@ -781,30 +810,32 @@ } - /*************************************************************************/ - /* */ - /* SIZE FUNCTIONS */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * SIZE FUNCTIONS + * + */ #ifdef TT_USE_BYTECODE_INTERPRETER - /*************************************************************************/ - /* */ - /* */ - /* tt_size_run_fpgm */ - /* */ - /* */ - /* Run the font program. */ - /* */ - /* */ - /* size :: A handle to the size object. */ - /* */ - /* pedantic :: Set if bytecode execution should be pedantic. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * tt_size_run_fpgm + * + * @Description: + * Run the font program. + * + * @Input: + * size :: + * A handle to the size object. + * + * pedantic :: + * Set if bytecode execution should be pedantic. + * + * @Return: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) tt_size_run_fpgm( TT_Size size, FT_Bool pedantic ) @@ -881,22 +912,24 @@ } - /*************************************************************************/ - /* */ - /* */ - /* tt_size_run_prep */ - /* */ - /* */ - /* Run the control value program. */ - /* */ - /* */ - /* size :: A handle to the size object. */ - /* */ - /* pedantic :: Set if bytecode execution should be pedantic. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * tt_size_run_prep + * + * @Description: + * Run the control value program. + * + * @Input: + * size :: + * A handle to the size object. + * + * pedantic :: + * Set if bytecode execution should be pedantic. + * + * @Return: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) tt_size_run_prep( TT_Size size, FT_Bool pedantic ) @@ -1141,10 +1174,16 @@ TT_Face face = (TT_Face)size->root.face; - /* Scale the cvt values to the new ppem. */ - /* We use by default the y ppem to scale the CVT. */ + /* Scale the cvt values to the new ppem. */ + /* By default, we use the y ppem value for scaling. */ + FT_TRACE6(( "CVT values:\n" )); for ( i = 0; i < size->cvt_size; i++ ) + { size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale ); + FT_TRACE6(( " %3d: %d (%f)\n", + i, face->cvt[i], size->cvt[i] / 64.0 )); + } + FT_TRACE6(( "\n" )); /* all twilight points are originally zero */ for ( i = 0; i < (FT_UInt)size->twilight.n_points; i++ ) @@ -1173,20 +1212,21 @@ #endif /* TT_USE_BYTECODE_INTERPRETER */ - /*************************************************************************/ - /* */ - /* */ - /* tt_size_init */ - /* */ - /* */ - /* Initialize a new TrueType size object. */ - /* */ - /* */ - /* size :: A handle to the size object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * tt_size_init + * + * @Description: + * Initialize a new TrueType size object. + * + * @InOut: + * size :: + * A handle to the size object. + * + * @Return: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) tt_size_init( FT_Size ttsize ) /* TT_Size */ { @@ -1206,17 +1246,18 @@ } - /*************************************************************************/ - /* */ - /* */ - /* tt_size_done */ - /* */ - /* */ - /* The TrueType size object finalizer. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ + /************************************************************************** + * + * @Function: + * tt_size_done + * + * @Description: + * The TrueType size object finalizer. + * + * @Input: + * size :: + * A handle to the target size object. + */ FT_LOCAL_DEF( void ) tt_size_done( FT_Size ttsize ) /* TT_Size */ { @@ -1231,22 +1272,24 @@ } - /*************************************************************************/ - /* */ - /* */ - /* tt_size_reset */ - /* */ - /* */ - /* Reset a TrueType size when resolutions and character dimensions */ - /* have been changed. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - /* only_height :: Only recompute ascender, descender, and height; */ - /* this flag is used for variation fonts where */ - /* `tt_size_reset' is used as an iterator function. */ - /* */ + /************************************************************************** + * + * @Function: + * tt_size_reset + * + * @Description: + * Reset a TrueType size when resolutions and character dimensions + * have been changed. + * + * @Input: + * size :: + * A handle to the target size object. + * + * only_height :: + * Only recompute ascender, descender, and height; + * this flag is used for variation fonts where + * `tt_size_reset' is used as an iterator function. + */ FT_LOCAL_DEF( FT_Error ) tt_size_reset( TT_Size size, FT_Bool only_height ) @@ -1340,20 +1383,21 @@ } - /*************************************************************************/ - /* */ - /* */ - /* tt_driver_init */ - /* */ - /* */ - /* Initialize a given TrueType driver object. */ - /* */ - /* */ - /* driver :: A handle to the target driver object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * tt_driver_init + * + * @Description: + * Initialize a given TrueType driver object. + * + * @Input: + * driver :: + * A handle to the target driver object. + * + * @Return: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) tt_driver_init( FT_Module ttdriver ) /* TT_Driver */ { @@ -1380,17 +1424,18 @@ } - /*************************************************************************/ - /* */ - /* */ - /* tt_driver_done */ - /* */ - /* */ - /* Finalize a given TrueType driver. */ - /* */ - /* */ - /* driver :: A handle to the target TrueType driver. */ - /* */ + /************************************************************************** + * + * @Function: + * tt_driver_done + * + * @Description: + * Finalize a given TrueType driver. + * + * @Input: + * driver :: + * A handle to the target TrueType driver. + */ FT_LOCAL_DEF( void ) tt_driver_done( FT_Module ttdriver ) /* TT_Driver */ { @@ -1398,20 +1443,21 @@ } - /*************************************************************************/ - /* */ - /* */ - /* tt_slot_init */ - /* */ - /* */ - /* Initialize a new slot object. */ - /* */ - /* */ - /* slot :: A handle to the slot object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * tt_slot_init + * + * @Description: + * Initialize a new slot object. + * + * @InOut: + * slot :: + * A handle to the slot object. + * + * @Return: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) tt_slot_init( FT_GlyphSlot slot ) { diff --git a/sdk/lib/3rdparty/freetype/src/truetype/ttobjs.h b/sdk/lib/3rdparty/freetype/src/truetype/ttobjs.h index 38fa30e4e9fd1..9fc654d5d1047 100644 --- a/sdk/lib/3rdparty/freetype/src/truetype/ttobjs.h +++ b/sdk/lib/3rdparty/freetype/src/truetype/ttobjs.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ttobjs.h */ -/* */ -/* Objects manager (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ttobjs.h + * + * Objects manager (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef TTOBJS_H_ @@ -28,40 +28,40 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* */ - /* TT_Driver */ - /* */ - /* */ - /* A handle to a TrueType driver object. */ - /* */ + /************************************************************************** + * + * @Type: + * TT_Driver + * + * @Description: + * A handle to a TrueType driver object. + */ typedef struct TT_DriverRec_* TT_Driver; - /*************************************************************************/ - /* */ - /* */ - /* TT_GlyphSlot */ - /* */ - /* */ - /* A handle to a TrueType glyph slot object. */ - /* */ - /* */ - /* This is a direct typedef of FT_GlyphSlot, as there is nothing */ - /* specific about the TrueType glyph slot. */ - /* */ + /************************************************************************** + * + * @Type: + * TT_GlyphSlot + * + * @Description: + * A handle to a TrueType glyph slot object. + * + * @Note: + * This is a direct typedef of FT_GlyphSlot, as there is nothing + * specific about the TrueType glyph slot. + */ typedef FT_GlyphSlot TT_GlyphSlot; - /*************************************************************************/ - /* */ - /* */ - /* TT_GraphicsState */ - /* */ - /* */ - /* The TrueType graphics state used during bytecode interpretation. */ - /* */ + /************************************************************************** + * + * @Struct: + * TT_GraphicsState + * + * @Description: + * The TrueType graphics state used during bytecode interpretation. + */ typedef struct TT_GraphicsState_ { FT_UShort rp0; @@ -113,25 +113,25 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* EXECUTION SUBTABLES */ - /* */ - /* These sub-tables relate to instruction execution. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * EXECUTION SUBTABLES + * + * These sub-tables relate to instruction execution. + * + */ #define TT_MAX_CODE_RANGES 3 - /*************************************************************************/ - /* */ - /* There can only be 3 active code ranges at once: */ - /* - the Font Program */ - /* - the CVT Program */ - /* - a glyph's instructions set */ - /* */ + /************************************************************************** + * + * There can only be 3 active code ranges at once: + * - the Font Program + * - the CVT Program + * - a glyph's instructions set + */ typedef enum TT_CodeRange_Tag_ { tt_coderange_none = 0, @@ -152,10 +152,10 @@ FT_BEGIN_HEADER typedef TT_CodeRange TT_CodeRangeTable[TT_MAX_CODE_RANGES]; - /*************************************************************************/ - /* */ - /* Defines a function/instruction definition record. */ - /* */ + /************************************************************************** + * + * Defines a function/instruction definition record. + */ typedef struct TT_DefRecord_ { FT_Int range; /* in which code range is it located? */ @@ -169,10 +169,10 @@ FT_BEGIN_HEADER } TT_DefRecord, *TT_DefArray; - /*************************************************************************/ - /* */ - /* Subglyph transformation record. */ - /* */ + /************************************************************************** + * + * Subglyph transformation record. + */ typedef struct TT_Transform_ { FT_Fixed xx, xy; /* transformation matrix coefficients */ @@ -182,72 +182,72 @@ FT_BEGIN_HEADER } TT_Transform; - /*************************************************************************/ - /* */ - /* A note regarding non-squared pixels: */ - /* */ - /* (This text will probably go into some docs at some time; for now, it */ - /* is kept here to explain some definitions in the TT_Size_Metrics */ - /* record). */ - /* */ - /* The CVT is a one-dimensional array containing values that control */ - /* certain important characteristics in a font, like the height of all */ - /* capitals, all lowercase letter, default spacing or stem width/height. */ - /* */ - /* These values are found in FUnits in the font file, and must be scaled */ - /* to pixel coordinates before being used by the CVT and glyph programs. */ - /* Unfortunately, when using distinct x and y resolutions (or distinct x */ - /* and y pointsizes), there are two possible scalings. */ - /* */ - /* A first try was to implement a `lazy' scheme where all values were */ - /* scaled when first used. However, while some values are always used */ - /* in the same direction, some others are used under many different */ - /* circumstances and orientations. */ - /* */ - /* I have found a simpler way to do the same, and it even seems to work */ - /* in most of the cases: */ - /* */ - /* - All CVT values are scaled to the maximum ppem size. */ - /* */ - /* - When performing a read or write in the CVT, a ratio factor is used */ - /* to perform adequate scaling. Example: */ - /* */ - /* x_ppem = 14 */ - /* y_ppem = 10 */ - /* */ - /* We choose ppem = x_ppem = 14 as the CVT scaling size. All cvt */ - /* entries are scaled to it. */ - /* */ - /* x_ratio = 1.0 */ - /* y_ratio = y_ppem/ppem (< 1.0) */ - /* */ - /* We compute the current ratio like: */ - /* */ - /* - If projVector is horizontal, */ - /* ratio = x_ratio = 1.0 */ - /* */ - /* - if projVector is vertical, */ - /* ratio = y_ratio */ - /* */ - /* - else, */ - /* ratio = sqrt( (proj.x * x_ratio) ^ 2 + (proj.y * y_ratio) ^ 2 ) */ - /* */ - /* Reading a cvt value returns */ - /* ratio * cvt[index] */ - /* */ - /* Writing a cvt value in pixels: */ - /* cvt[index] / ratio */ - /* */ - /* The current ppem is simply */ - /* ratio * ppem */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* Metrics used by the TrueType size and context objects. */ - /* */ + /************************************************************************** + * + * A note regarding non-squared pixels: + * + * (This text will probably go into some docs at some time; for now, it + * is kept here to explain some definitions in the TT_Size_Metrics + * record). + * + * The CVT is a one-dimensional array containing values that control + * certain important characteristics in a font, like the height of all + * capitals, all lowercase letter, default spacing or stem width/height. + * + * These values are found in FUnits in the font file, and must be scaled + * to pixel coordinates before being used by the CVT and glyph programs. + * Unfortunately, when using distinct x and y resolutions (or distinct x + * and y pointsizes), there are two possible scalings. + * + * A first try was to implement a `lazy' scheme where all values were + * scaled when first used. However, while some values are always used + * in the same direction, some others are used under many different + * circumstances and orientations. + * + * I have found a simpler way to do the same, and it even seems to work + * in most of the cases: + * + * - All CVT values are scaled to the maximum ppem size. + * + * - When performing a read or write in the CVT, a ratio factor is used + * to perform adequate scaling. Example: + * + * x_ppem = 14 + * y_ppem = 10 + * + * We choose ppem = x_ppem = 14 as the CVT scaling size. All cvt + * entries are scaled to it. + * + * x_ratio = 1.0 + * y_ratio = y_ppem/ppem (< 1.0) + * + * We compute the current ratio like: + * + * - If projVector is horizontal, + * ratio = x_ratio = 1.0 + * + * - if projVector is vertical, + * ratio = y_ratio + * + * - else, + * ratio = sqrt( (proj.x * x_ratio) ^ 2 + (proj.y * y_ratio) ^ 2 ) + * + * Reading a cvt value returns + * ratio * cvt[index] + * + * Writing a cvt value in pixels: + * cvt[index] / ratio + * + * The current ppem is simply + * ratio * ppem + * + */ + + + /************************************************************************** + * + * Metrics used by the TrueType size and context objects. + */ typedef struct TT_Size_Metrics_ { /* for non-square pixels */ @@ -268,10 +268,10 @@ FT_BEGIN_HEADER } TT_Size_Metrics; - /*************************************************************************/ - /* */ - /* TrueType size class. */ - /* */ + /************************************************************************** + * + * TrueType size class. + */ typedef struct TT_SizeRec_ { FT_SizeRec root; @@ -324,10 +324,10 @@ FT_BEGIN_HEADER } TT_SizeRec; - /*************************************************************************/ - /* */ - /* TrueType driver class. */ - /* */ + /************************************************************************** + * + * TrueType driver class. + */ typedef struct TT_DriverRec_ { FT_DriverRec root; @@ -348,10 +348,10 @@ FT_BEGIN_HEADER /* will always use the TT driver to create them. */ - /*************************************************************************/ - /* */ - /* Face functions */ - /* */ + /************************************************************************** + * + * Face functions + */ FT_LOCAL( FT_Error ) tt_face_init( FT_Stream stream, FT_Face ttface, /* TT_Face */ @@ -363,10 +363,10 @@ FT_BEGIN_HEADER tt_face_done( FT_Face ttface ); /* TT_Face */ - /*************************************************************************/ - /* */ - /* Size functions */ - /* */ + /************************************************************************** + * + * Size functions + */ FT_LOCAL( FT_Error ) tt_size_init( FT_Size ttsize ); /* TT_Size */ @@ -394,10 +394,10 @@ FT_BEGIN_HEADER FT_Bool only_height ); - /*************************************************************************/ - /* */ - /* Driver functions */ - /* */ + /************************************************************************** + * + * Driver functions + */ FT_LOCAL( FT_Error ) tt_driver_init( FT_Module ttdriver ); /* TT_Driver */ @@ -405,10 +405,10 @@ FT_BEGIN_HEADER tt_driver_done( FT_Module ttdriver ); /* TT_Driver */ - /*************************************************************************/ - /* */ - /* Slot functions */ - /* */ + /************************************************************************** + * + * Slot functions + */ FT_LOCAL( FT_Error ) tt_slot_init( FT_GlyphSlot slot ); diff --git a/sdk/lib/3rdparty/freetype/src/truetype/ttpic.c b/sdk/lib/3rdparty/freetype/src/truetype/ttpic.c deleted file mode 100644 index cdbb80639e112..0000000000000 --- a/sdk/lib/3rdparty/freetype/src/truetype/ttpic.c +++ /dev/null @@ -1,101 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttpic.c */ -/* */ -/* The FreeType position independent code services for truetype module. */ -/* */ -/* Copyright 2009-2018 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include -#include FT_FREETYPE_H -#include FT_INTERNAL_OBJECTS_H -#include "ttpic.h" -#include "tterrors.h" - - -#ifdef FT_CONFIG_OPTION_PIC - - /* forward declaration of PIC init functions from ttdriver.c */ - FT_Error - FT_Create_Class_tt_services( FT_Library library, - FT_ServiceDescRec** output_class ); - void - FT_Destroy_Class_tt_services( FT_Library library, - FT_ServiceDescRec* clazz ); - void - FT_Init_Class_tt_service_gx_multi_masters( - FT_Service_MultiMastersRec* sv_mm ); - void - FT_Init_Class_tt_service_truetype_glyf( - FT_Service_TTGlyfRec* sv_ttglyf ); - - - void - tt_driver_class_pic_free( FT_Library library ) - { - FT_PIC_Container* pic_container = &library->pic_container; - FT_Memory memory = library->memory; - - - if ( pic_container->truetype ) - { - TTModulePIC* container = (TTModulePIC*)pic_container->truetype; - - - if ( container->tt_services ) - FT_Destroy_Class_tt_services( library, container->tt_services ); - container->tt_services = NULL; - FT_FREE( container ); - pic_container->truetype = NULL; - } - } - - - FT_Error - tt_driver_class_pic_init( FT_Library library ) - { - FT_PIC_Container* pic_container = &library->pic_container; - FT_Error error = FT_Err_Ok; - TTModulePIC* container = NULL; - FT_Memory memory = library->memory; - - - /* allocate pointer, clear and set global container pointer */ - if ( FT_ALLOC( container, sizeof ( *container ) ) ) - return error; - FT_MEM_SET( container, 0, sizeof ( *container ) ); - pic_container->truetype = container; - - /* initialize pointer table - this is how the module usually */ - /* expects this data */ - error = FT_Create_Class_tt_services( library, - &container->tt_services ); - if ( error ) - goto Exit; -#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - FT_Init_Class_tt_service_gx_multi_masters( - &container->tt_service_gx_multi_masters ); -#endif - FT_Init_Class_tt_service_truetype_glyf( - &container->tt_service_truetype_glyf ); - - Exit: - if ( error ) - tt_driver_class_pic_free( library ); - return error; - } - -#endif /* FT_CONFIG_OPTION_PIC */ - - -/* END */ diff --git a/sdk/lib/3rdparty/freetype/src/truetype/ttpic.h b/sdk/lib/3rdparty/freetype/src/truetype/ttpic.h deleted file mode 100644 index df878ae6f1d3b..0000000000000 --- a/sdk/lib/3rdparty/freetype/src/truetype/ttpic.h +++ /dev/null @@ -1,88 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttpic.h */ -/* */ -/* The FreeType position independent code services for truetype module. */ -/* */ -/* Copyright 2009-2018 by */ -/* Oran Agra and Mickey Gabel. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#ifndef TTPIC_H_ -#define TTPIC_H_ - - -#include FT_INTERNAL_PIC_H - - -#ifndef FT_CONFIG_OPTION_PIC - -#define TT_SERVICES_GET tt_services -#define TT_SERVICE_GX_MULTI_MASTERS_GET tt_service_gx_multi_masters -#define TT_SERVICE_METRICS_VARIATIONS_GET tt_service_metrics_variations -#define TT_SERVICE_TRUETYPE_GLYF_GET tt_service_truetype_glyf -#define TT_SERVICE_PROPERTIES_GET tt_service_properties - -#else /* FT_CONFIG_OPTION_PIC */ - -#include FT_MULTIPLE_MASTERS_H -#include FT_SERVICE_MULTIPLE_MASTERS_H -#include FT_SERVICE_METRICS_VARIATIONS_H -#include FT_SERVICE_TRUETYPE_GLYF_H -#include FT_SERVICE_PROPERTIES_H - - -FT_BEGIN_HEADER - - typedef struct TTModulePIC_ - { - FT_ServiceDescRec* tt_services; -#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - FT_Service_MultiMastersRec tt_service_gx_multi_masters; - FT_Service_MetricsVariationsRec tt_service_metrics_variations; -#endif - FT_Service_TTGlyfRec tt_service_truetype_glyf; - FT_Service_PropertiesRec tt_service_properties; - - } TTModulePIC; - - -#define GET_PIC( lib ) \ - ( (TTModulePIC*)((lib)->pic_container.truetype) ) -#define TT_SERVICES_GET \ - ( GET_PIC( library )->tt_services ) -#define TT_SERVICE_METRICS_VARIATIONS_GET \ - ( GET_PIC( library )->tt_service_metrics_variations ) -#define TT_SERVICE_GX_MULTI_MASTERS_GET \ - ( GET_PIC( library )->tt_service_gx_multi_masters ) -#define TT_SERVICE_TRUETYPE_GLYF_GET \ - ( GET_PIC( library )->tt_service_truetype_glyf ) -#define TT_SERVICE_PROPERTIES_GET \ - ( GET_PIC( library )->tt_service_properties ) - - - /* see ttpic.c for the implementation */ - void - tt_driver_class_pic_free( FT_Library library ); - - FT_Error - tt_driver_class_pic_init( FT_Library library ); - -FT_END_HEADER - -#endif /* FT_CONFIG_OPTION_PIC */ - - /* */ - -#endif /* TTPIC_H_ */ - - -/* END */ diff --git a/sdk/lib/3rdparty/freetype/src/truetype/ttpload.c b/sdk/lib/3rdparty/freetype/src/truetype/ttpload.c index d9526ad082b77..e7718bf9b794c 100644 --- a/sdk/lib/3rdparty/freetype/src/truetype/ttpload.c +++ b/sdk/lib/3rdparty/freetype/src/truetype/ttpload.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ttpload.c */ -/* */ -/* TrueType-specific tables loader (body). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ttpload.c + * + * TrueType-specific tables loader (body). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include @@ -31,33 +31,35 @@ #include "tterrors.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_ttpload - - - /*************************************************************************/ - /* */ - /* */ - /* tt_face_load_loca */ - /* */ - /* */ - /* Load the locations table. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* */ - /* stream :: The input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ +#define FT_COMPONENT ttpload + + + /************************************************************************** + * + * @Function: + * tt_face_load_loca + * + * @Description: + * Load the locations table. + * + * @InOut: + * face :: + * A handle to the target face object. + * + * @Input: + * stream :: + * The input stream. + * + * @Return: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) tt_face_load_loca( TT_Face face, FT_Stream stream ) @@ -297,23 +299,25 @@ - /*************************************************************************/ - /* */ - /* */ - /* tt_face_load_cvt */ - /* */ - /* */ - /* Load the control value table into a face object. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* */ - /* stream :: A handle to the input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * tt_face_load_cvt + * + * @Description: + * Load the control value table into a face object. + * + * @InOut: + * face :: + * A handle to the target face object. + * + * @Input: + * stream :: + * A handle to the input stream. + * + * @Return: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) tt_face_load_cvt( TT_Face face, FT_Stream stream ) @@ -378,23 +382,25 @@ } - /*************************************************************************/ - /* */ - /* */ - /* tt_face_load_fpgm */ - /* */ - /* */ - /* Load the font program. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* */ - /* stream :: A handle to the input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * tt_face_load_fpgm + * + * @Description: + * Load the font program. + * + * @InOut: + * face :: + * A handle to the target face object. + * + * @Input: + * stream :: + * A handle to the input stream. + * + * @Return: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) tt_face_load_fpgm( TT_Face face, FT_Stream stream ) @@ -440,23 +446,25 @@ } - /*************************************************************************/ - /* */ - /* */ - /* tt_face_load_prep */ - /* */ - /* */ - /* Load the cvt program. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* */ - /* stream :: A handle to the input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * tt_face_load_prep + * + * @Description: + * Load the cvt program. + * + * @InOut: + * face :: + * A handle to the target face object. + * + * @Input: + * stream :: + * A handle to the input stream. + * + * @Return: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) tt_face_load_prep( TT_Face face, FT_Stream stream ) @@ -501,22 +509,24 @@ } - /*************************************************************************/ - /* */ - /* */ - /* tt_face_load_hdmx */ - /* */ - /* */ - /* Load the `hdmx' table into the face object. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* stream :: A handle to the input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * tt_face_load_hdmx + * + * @Description: + * Load the `hdmx' table into the face object. + * + * @Input: + * face :: + * A handle to the target face object. + * + * stream :: + * A handle to the input stream. + * + * @Return: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) tt_face_load_hdmx( TT_Face face, @@ -610,11 +620,11 @@ } - /*************************************************************************/ - /* */ - /* Return the advance width table for a given pixel size if it is found */ - /* in the font's `hdmx' table (if any). */ - /* */ + /************************************************************************** + * + * Return the advance width table for a given pixel size if it is found + * in the font's `hdmx' table (if any). + */ FT_LOCAL_DEF( FT_Byte* ) tt_face_get_device_metrics( TT_Face face, FT_UInt ppem, diff --git a/sdk/lib/3rdparty/freetype/src/truetype/ttpload.h b/sdk/lib/3rdparty/freetype/src/truetype/ttpload.h index fa125272472cd..022750e32462f 100644 --- a/sdk/lib/3rdparty/freetype/src/truetype/ttpload.h +++ b/sdk/lib/3rdparty/freetype/src/truetype/ttpload.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ttpload.h */ -/* */ -/* TrueType-specific tables loader (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ttpload.h + * + * TrueType-specific tables loader (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef TTPLOAD_H_ diff --git a/sdk/lib/3rdparty/freetype/src/truetype/ttsubpix.c b/sdk/lib/3rdparty/freetype/src/truetype/ttsubpix.c index d94bcc8b50d71..23a2e5b440131 100644 --- a/sdk/lib/3rdparty/freetype/src/truetype/ttsubpix.c +++ b/sdk/lib/3rdparty/freetype/src/truetype/ttsubpix.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ttsubpix.c */ -/* */ -/* TrueType Subpixel Hinting. */ -/* */ -/* Copyright 2010-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ttsubpix.c + * + * TrueType Subpixel Hinting. + * + * Copyright (C) 2010-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include #include FT_INTERNAL_DEBUG_H @@ -30,35 +30,35 @@ #if defined( TT_USE_BYTECODE_INTERPRETER ) && \ defined( TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY ) - /*************************************************************************/ - /* */ - /* These rules affect how the TT Interpreter does hinting, with the */ - /* goal of doing subpixel hinting by (in general) ignoring x moves. */ - /* Some of these rules are fixes that go above and beyond the */ - /* stated techniques in the MS whitepaper on Cleartype, due to */ - /* artifacts in many glyphs. So, these rules make some glyphs render */ - /* better than they do in the MS rasterizer. */ - /* */ - /* "" string or 0 int/char indicates to apply to all glyphs. */ - /* "-" used as dummy placeholders, but any non-matching string works. */ - /* */ - /* Some of this could arguably be implemented in fontconfig, however: */ - /* */ - /* - Fontconfig can't set things on a glyph-by-glyph basis. */ - /* - The tweaks that happen here are very low-level, from an average */ - /* user's point of view and are best implemented in the hinter. */ - /* */ - /* The goal is to make the subpixel hinting techniques as generalized */ - /* as possible across all fonts to prevent the need for extra rules such */ - /* as these. */ - /* */ - /* The rule structure is designed so that entirely new rules can easily */ - /* be added when a new compatibility feature is discovered. */ - /* */ - /* The rule structures could also use some enhancement to handle ranges. */ - /* */ - /* ****************** WORK IN PROGRESS ******************* */ - /* */ + /************************************************************************** + * + * These rules affect how the TT Interpreter does hinting, with the + * goal of doing subpixel hinting by (in general) ignoring x moves. + * Some of these rules are fixes that go above and beyond the + * stated techniques in the MS whitepaper on Cleartype, due to + * artifacts in many glyphs. So, these rules make some glyphs render + * better than they do in the MS rasterizer. + * + * "" string or 0 int/char indicates to apply to all glyphs. + * "-" used as dummy placeholders, but any non-matching string works. + * + * Some of this could arguably be implemented in fontconfig, however: + * + * - Fontconfig can't set things on a glyph-by-glyph basis. + * - The tweaks that happen here are very low-level, from an average + * user's point of view and are best implemented in the hinter. + * + * The goal is to make the subpixel hinting techniques as generalized + * as possible across all fonts to prevent the need for extra rules such + * as these. + * + * The rule structure is designed so that entirely new rules can easily + * be added when a new compatibility feature is discovered. + * + * The rule structures could also use some enhancement to handle ranges. + * + * ****************** WORK IN PROGRESS ******************* + */ /* These are `classes' of fonts that can be grouped together and used in */ /* rules below. A blank entry "" is required at the end of these! */ diff --git a/sdk/lib/3rdparty/freetype/src/truetype/ttsubpix.h b/sdk/lib/3rdparty/freetype/src/truetype/ttsubpix.h index 1070bb016fdfc..4966800c2d7e3 100644 --- a/sdk/lib/3rdparty/freetype/src/truetype/ttsubpix.h +++ b/sdk/lib/3rdparty/freetype/src/truetype/ttsubpix.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ttsubpix.h */ -/* */ -/* TrueType Subpixel Hinting. */ -/* */ -/* Copyright 2010-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ttsubpix.h + * + * TrueType Subpixel Hinting. + * + * Copyright (C) 2010-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef TTSUBPIX_H_ @@ -29,11 +29,11 @@ FT_BEGIN_HEADER #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - /*************************************************************************/ - /* */ - /* ID flags to identify special functions at FDEF and runtime. */ - /* */ - /* */ + /************************************************************************** + * + * ID flags to identify special functions at FDEF and runtime. + * + */ #define SPH_FDEF_INLINE_DELTA_1 0x0000001 #define SPH_FDEF_INLINE_DELTA_2 0x0000002 #define SPH_FDEF_DIAGONAL_STROKE 0x0000004 @@ -45,11 +45,11 @@ FT_BEGIN_HEADER #define SPH_FDEF_TYPEMAN_DIAGENDCTRL 0x0000100 - /*************************************************************************/ - /* */ - /* Tweak flags that are set for each glyph by the below rules. */ - /* */ - /* */ + /************************************************************************** + * + * Tweak flags that are set for each glyph by the below rules. + * + */ #define SPH_TWEAK_ALLOW_X_DMOVE 0x0000001UL #define SPH_TWEAK_ALWAYS_DO_DELTAP 0x0000002UL #define SPH_TWEAK_ALWAYS_SKIP_DELTAP 0x0000004UL diff --git a/sdk/lib/3rdparty/freetype/src/type1/t1afm.c b/sdk/lib/3rdparty/freetype/src/type1/t1afm.c index 61053d9a64069..6841184539f02 100644 --- a/sdk/lib/3rdparty/freetype/src/type1/t1afm.c +++ b/sdk/lib/3rdparty/freetype/src/type1/t1afm.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* t1afm.c */ -/* */ -/* AFM support for Type 1 fonts (body). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * t1afm.c + * + * AFM support for Type 1 fonts (body). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include @@ -26,14 +26,14 @@ #ifndef T1_CONFIG_OPTION_NO_AFM - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_t1afm +#define FT_COMPONENT t1afm FT_LOCAL_DEF( void ) diff --git a/sdk/lib/3rdparty/freetype/src/type1/t1afm.h b/sdk/lib/3rdparty/freetype/src/type1/t1afm.h index cb8d302b4d484..a8e6a5495a21d 100644 --- a/sdk/lib/3rdparty/freetype/src/type1/t1afm.h +++ b/sdk/lib/3rdparty/freetype/src/type1/t1afm.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* t1afm.h */ -/* */ -/* AFM support for Type 1 fonts (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * t1afm.h + * + * AFM support for Type 1 fonts (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef T1AFM_H_ diff --git a/sdk/lib/3rdparty/freetype/src/type1/t1driver.c b/sdk/lib/3rdparty/freetype/src/type1/t1driver.c index 029b410b47604..8625db5b0159f 100644 --- a/sdk/lib/3rdparty/freetype/src/type1/t1driver.c +++ b/sdk/lib/3rdparty/freetype/src/type1/t1driver.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* t1driver.c */ -/* */ -/* Type 1 driver interface (body). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * t1driver.c + * + * Type 1 driver interface (body). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include @@ -43,19 +43,19 @@ #include FT_SERVICE_KERNING_H - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_t1driver +#define FT_COMPONENT t1driver - /* - * GLYPH DICT SERVICE - * - */ + /* + * GLYPH DICT SERVICE + * + */ static FT_Error t1_get_glyph_name( T1_Face face, @@ -97,7 +97,7 @@ /* - * POSTSCRIPT NAME SERVICE + * POSTSCRIPT NAME SERVICE * */ @@ -115,30 +115,32 @@ /* - * MULTIPLE MASTERS SERVICE + * MULTIPLE MASTERS SERVICE * */ #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT static const FT_Service_MultiMastersRec t1_service_multi_masters = { - (FT_Get_MM_Func) T1_Get_Multi_Master, /* get_mm */ - (FT_Set_MM_Design_Func) T1_Set_MM_Design, /* set_mm_design */ - (FT_Set_MM_Blend_Func) T1_Set_MM_Blend, /* set_mm_blend */ - (FT_Get_MM_Blend_Func) T1_Get_MM_Blend, /* get_mm_blend */ - (FT_Get_MM_Var_Func) T1_Get_MM_Var, /* get_mm_var */ - (FT_Set_Var_Design_Func)T1_Set_Var_Design, /* set_var_design */ - (FT_Get_Var_Design_Func)T1_Get_Var_Design, /* get_var_design */ - (FT_Set_Instance_Func) T1_Reset_MM_Blend, /* set_instance */ - - (FT_Get_Var_Blend_Func) NULL, /* get_var_blend */ - (FT_Done_Blend_Func) T1_Done_Blend /* done_blend */ + (FT_Get_MM_Func) T1_Get_Multi_Master, /* get_mm */ + (FT_Set_MM_Design_Func) T1_Set_MM_Design, /* set_mm_design */ + (FT_Set_MM_Blend_Func) T1_Set_MM_Blend, /* set_mm_blend */ + (FT_Get_MM_Blend_Func) T1_Get_MM_Blend, /* get_mm_blend */ + (FT_Get_MM_Var_Func) T1_Get_MM_Var, /* get_mm_var */ + (FT_Set_Var_Design_Func) T1_Set_Var_Design, /* set_var_design */ + (FT_Get_Var_Design_Func) T1_Get_Var_Design, /* get_var_design */ + (FT_Set_Instance_Func) T1_Reset_MM_Blend, /* set_instance */ + (FT_Set_MM_WeightVector_Func)T1_Set_MM_WeightVector, /* set_mm_weightvector */ + (FT_Get_MM_WeightVector_Func)T1_Get_MM_WeightVector, /* get_mm_weightvector */ + + (FT_Get_Var_Blend_Func) NULL, /* get_var_blend */ + (FT_Done_Blend_Func) T1_Done_Blend /* done_blend */ }; #endif /* - * POSTSCRIPT INFO SERVICE + * POSTSCRIPT INFO SERVICE * */ @@ -270,9 +272,12 @@ break; case PS_DICT_FONT_NAME: - retval = ft_strlen( type1->font_name ) + 1; - if ( value && value_len >= retval ) - ft_memcpy( value, (void *)( type1->font_name ), retval ); + if ( type1->font_name ) + { + retval = ft_strlen( type1->font_name ) + 1; + if ( value && value_len >= retval ) + ft_memcpy( value, (void *)( type1->font_name ), retval ); + } break; case PS_DICT_UNIQUE_ID: @@ -362,7 +367,7 @@ ok = 1; } - if ( ok ) + if ( ok && type1->subrs ) { retval = type1->subrs_len[idx] + 1; if ( value && value_len >= retval ) @@ -559,33 +564,49 @@ break; case PS_DICT_VERSION: - retval = ft_strlen( type1->font_info.version ) + 1; - if ( value && value_len >= retval ) - ft_memcpy( value, (void *)( type1->font_info.version ), retval ); + if ( type1->font_info.version ) + { + retval = ft_strlen( type1->font_info.version ) + 1; + if ( value && value_len >= retval ) + ft_memcpy( value, (void *)( type1->font_info.version ), retval ); + } break; case PS_DICT_NOTICE: - retval = ft_strlen( type1->font_info.notice ) + 1; - if ( value && value_len >= retval ) - ft_memcpy( value, (void *)( type1->font_info.notice ), retval ); + if ( type1->font_info.notice ) + { + retval = ft_strlen( type1->font_info.notice ) + 1; + if ( value && value_len >= retval ) + ft_memcpy( value, (void *)( type1->font_info.notice ), retval ); + } break; case PS_DICT_FULL_NAME: - retval = ft_strlen( type1->font_info.full_name ) + 1; - if ( value && value_len >= retval ) - ft_memcpy( value, (void *)( type1->font_info.full_name ), retval ); + if ( type1->font_info.full_name ) + { + retval = ft_strlen( type1->font_info.full_name ) + 1; + if ( value && value_len >= retval ) + ft_memcpy( value, (void *)( type1->font_info.full_name ), retval ); + } break; case PS_DICT_FAMILY_NAME: - retval = ft_strlen( type1->font_info.family_name ) + 1; - if ( value && value_len >= retval ) - ft_memcpy( value, (void *)( type1->font_info.family_name ), retval ); + if ( type1->font_info.family_name ) + { + retval = ft_strlen( type1->font_info.family_name ) + 1; + if ( value && value_len >= retval ) + ft_memcpy( value, (void *)( type1->font_info.family_name ), + retval ); + } break; case PS_DICT_WEIGHT: - retval = ft_strlen( type1->font_info.weight ) + 1; - if ( value && value_len >= retval ) - ft_memcpy( value, (void *)( type1->font_info.weight ), retval ); + if ( type1->font_info.weight ) + { + retval = ft_strlen( type1->font_info.weight ) + 1; + if ( value && value_len >= retval ) + ft_memcpy( value, (void *)( type1->font_info.weight ), retval ); + } break; case PS_DICT_ITALIC_ANGLE: @@ -618,7 +639,7 @@ /* - * PROPERTY SERVICE + * PROPERTY SERVICE * */ @@ -630,7 +651,7 @@ /* - * SERVICE LIST + * SERVICE LIST * */ @@ -665,38 +686,42 @@ #ifndef T1_CONFIG_OPTION_NO_AFM - /*************************************************************************/ - /* */ - /* */ - /* Get_Kerning */ - /* */ - /* */ - /* A driver method used to return the kerning vector between two */ - /* glyphs of the same face. */ - /* */ - /* */ - /* face :: A handle to the source face object. */ - /* */ - /* left_glyph :: The index of the left glyph in the kern pair. */ - /* */ - /* right_glyph :: The index of the right glyph in the kern pair. */ - /* */ - /* */ - /* kerning :: The kerning vector. This is in font units for */ - /* scalable formats, and in pixels for fixed-sizes */ - /* formats. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Only horizontal layouts (left-to-right & right-to-left) are */ - /* supported by this function. Other layouts, or more sophisticated */ - /* kernings are out of scope of this method (the basic driver */ - /* interface is meant to be simple). */ - /* */ - /* They can be implemented by format-specific interfaces. */ - /* */ + /************************************************************************** + * + * @Function: + * Get_Kerning + * + * @Description: + * A driver method used to return the kerning vector between two + * glyphs of the same face. + * + * @Input: + * face :: + * A handle to the source face object. + * + * left_glyph :: + * The index of the left glyph in the kern pair. + * + * right_glyph :: + * The index of the right glyph in the kern pair. + * + * @Output: + * kerning :: + * The kerning vector. This is in font units for + * scalable formats, and in pixels for fixed-sizes + * formats. + * + * @Return: + * FreeType error code. 0 means success. + * + * @Note: + * Only horizontal layouts (left-to-right & right-to-left) are + * supported by this function. Other layouts, or more sophisticated + * kernings are out of scope of this method (the basic driver + * interface is meant to be simple). + * + * They can be implemented by format-specific interfaces. + */ static FT_Error Get_Kerning( FT_Face t1face, /* T1_Face */ FT_UInt left_glyph, diff --git a/sdk/lib/3rdparty/freetype/src/type1/t1driver.h b/sdk/lib/3rdparty/freetype/src/type1/t1driver.h index 2b1507233dda5..206f64a0bca9e 100644 --- a/sdk/lib/3rdparty/freetype/src/type1/t1driver.h +++ b/sdk/lib/3rdparty/freetype/src/type1/t1driver.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* t1driver.h */ -/* */ -/* High-level Type 1 driver interface (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * t1driver.h + * + * High-level Type 1 driver interface (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef T1DRIVER_H_ @@ -26,14 +26,8 @@ FT_BEGIN_HEADER -#ifdef FT_CONFIG_OPTION_PIC -#error "this module does not support PIC yet" -#endif - - FT_EXPORT_VAR( const FT_Driver_ClassRec ) t1_driver_class; - FT_END_HEADER #endif /* T1DRIVER_H_ */ diff --git a/sdk/lib/3rdparty/freetype/src/type1/t1errors.h b/sdk/lib/3rdparty/freetype/src/type1/t1errors.h index 9e0151b957190..b35f67a24c92a 100644 --- a/sdk/lib/3rdparty/freetype/src/type1/t1errors.h +++ b/sdk/lib/3rdparty/freetype/src/type1/t1errors.h @@ -1,26 +1,26 @@ -/***************************************************************************/ -/* */ -/* t1errors.h */ -/* */ -/* Type 1 error codes (specification only). */ -/* */ -/* Copyright 2001-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to define the Type 1 error enumeration constants. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * t1errors.h + * + * Type 1 error codes (specification only). + * + * Copyright (C) 2001-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /************************************************************************** + * + * This file is used to define the Type 1 error enumeration constants. + * + */ #ifndef T1ERRORS_H_ #define T1ERRORS_H_ diff --git a/sdk/lib/3rdparty/freetype/src/type1/t1gload.c b/sdk/lib/3rdparty/freetype/src/type1/t1gload.c index 3e78b9e43a2dc..fd2eb42afc629 100644 --- a/sdk/lib/3rdparty/freetype/src/type1/t1gload.c +++ b/sdk/lib/3rdparty/freetype/src/type1/t1gload.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* t1gload.c */ -/* */ -/* Type 1 Glyph Loader (body). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * t1gload.c + * + * Type 1 Glyph Loader (body). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include @@ -29,14 +29,14 @@ #include "t1errors.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_t1gload +#define FT_COMPONENT t1gload static FT_Error @@ -62,6 +62,7 @@ PS_Driver driver = (PS_Driver)FT_FACE_DRIVER( face ); #endif + decoder->font_matrix = type1->font_matrix; decoder->font_offset = type1->font_offset; @@ -214,12 +215,12 @@ { FT_Error error; #ifdef __REACTOS__ - T1_DecoderRec *decoder = malloc(sizeof(T1_DecoderRec)); - if (!decoder) + T1_DecoderRec *decoder_allocated = malloc(sizeof(*decoder_allocated)); + if (!decoder_allocated) return FT_THROW( Out_Of_Memory ); { /* Ugly but it allows us to reduce the diff */ -#define decoder (*decoder) +#define decoder (*decoder_allocated) #else T1_DecoderRec decoder; #endif @@ -245,7 +246,7 @@ if ( error ) #ifdef __REACTOS__ { - free(&decoder); + free(decoder_allocated); return error; } #else @@ -265,6 +266,8 @@ *max_advance = 0; + FT_TRACE6(( "T1_Compute_Max_Advance:\n" )); + /* for each glyph, parse the glyph charstring and extract */ /* the advance width */ for ( glyph_index = 0; glyph_index < type1->num_glyphs; glyph_index++ ) @@ -277,10 +280,13 @@ /* ignore the error if one occurred - skip to next glyph */ } + FT_TRACE6(( "T1_Compute_Max_Advance: max advance: %f\n", + *max_advance / 65536.0 )); + psaux->t1_decoder_funcs->done( &decoder ); #ifdef __REACTOS__ - free(&decoder); + free(decoder_allocated); #undef decoder } #endif @@ -297,11 +303,11 @@ { T1_Face face = (T1_Face)t1face; #ifdef __REACTOS__ - T1_DecoderRec *decoder = malloc(sizeof(T1_DecoderRec)); - if (!decoder) + T1_DecoderRec *decoder_allocated = malloc(sizeof(*decoder_allocated)); + if (!decoder_allocated) return FT_THROW( Out_Of_Memory ); /* Ugly but it allows us to reduce the diff */ -#define decoder (*decoder) +#define decoder (*decoder_allocated) { #else T1_DecoderRec decoder; @@ -312,13 +318,20 @@ FT_Error error; + FT_TRACE5(( "T1_Get_Advances:\n" )); + if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) { for ( nn = 0; nn < count; nn++ ) + { advances[nn] = 0; + FT_TRACE5(( " idx %d: advance height 0 font units\n", + first + nn )); + } + #ifdef __REACTOS__ - free(&decoder); + free(decoder_allocated); #endif return FT_Err_Ok; } @@ -335,7 +348,7 @@ if ( error ) #ifdef __REACTOS__ { - free(&decoder); + free(decoder_allocated); return error; } #else @@ -360,10 +373,15 @@ advances[nn] = FIXED_TO_INT( decoder.builder.advance.x ); else advances[nn] = 0; + + FT_TRACE5(( " idx %d: advance width %d font unit%s\n", + first + nn, + advances[nn], + advances[nn] == 1 ? "" : "s" )); } #ifdef __REACTOS__ - free(&decoder); + free(decoder_allocated); #undef decoder } #endif @@ -380,11 +398,11 @@ T1_GlyphSlot glyph = (T1_GlyphSlot)t1glyph; FT_Error error; #ifdef __REACTOS__ - T1_DecoderRec *decoder = malloc(sizeof(T1_DecoderRec)); - if (!decoder) + T1_DecoderRec *decoder_allocated = malloc(sizeof(*decoder_allocated)); + if (!decoder_allocated) return FT_THROW( Out_Of_Memory ); /* Ugly but it allows us to reduce the diff */ -#define decoder (*decoder) +#define decoder (*decoder_allocated) { #else T1_DecoderRec decoder; @@ -438,9 +456,9 @@ t1glyph->outline.n_points = 0; t1glyph->outline.n_contours = 0; - hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 && - ( load_flags & FT_LOAD_NO_HINTING ) == 0 ); - scaled = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ); + hinting = FT_BOOL( !( load_flags & FT_LOAD_NO_SCALE ) && + !( load_flags & FT_LOAD_NO_HINTING ) ); + scaled = FT_BOOL( !( load_flags & FT_LOAD_NO_SCALE ) ); glyph->hint = hinting; glyph->scaled = scaled; @@ -452,7 +470,7 @@ t1glyph, (FT_Byte**)type1->glyph_names, face->blend, - FT_BOOL( hinting ), + hinting, FT_LOAD_TARGET_MODE( load_flags ), T1_Parse_Glyph ); if ( error ) @@ -460,8 +478,7 @@ must_finish_decoder = TRUE; - decoder.builder.no_recurse = FT_BOOL( - ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ); + decoder.builder.no_recurse = FT_BOOL( load_flags & FT_LOAD_NO_RECURSE ); decoder.num_subrs = type1->num_subrs; decoder.subrs = type1->subrs; @@ -582,7 +599,7 @@ /* First of all, scale the points, if we are not hinting */ - if ( !hinting || ! decoder.builder.hints_funcs ) + if ( !hinting || !decoder.builder.hints_funcs ) for ( n = cur->n_points; n > 0; n--, vec++ ) { vec->x = FT_MulFix( vec->x, x_scale ); @@ -638,7 +655,7 @@ decoder_funcs->done( &decoder ); #ifdef __REACTOS__ - free(&decoder); + free(decoder_allocated); #undef decoder } #endif diff --git a/sdk/lib/3rdparty/freetype/src/type1/t1gload.h b/sdk/lib/3rdparty/freetype/src/type1/t1gload.h index 72ef76f6ae30a..80440369dc085 100644 --- a/sdk/lib/3rdparty/freetype/src/type1/t1gload.h +++ b/sdk/lib/3rdparty/freetype/src/type1/t1gload.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* t1gload.h */ -/* */ -/* Type 1 Glyph Loader (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * t1gload.h + * + * Type 1 Glyph Loader (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef T1GLOAD_H_ diff --git a/sdk/lib/3rdparty/freetype/src/type1/t1load.c b/sdk/lib/3rdparty/freetype/src/type1/t1load.c index 2b8d4893c692c..3896af70ba1e9 100644 --- a/sdk/lib/3rdparty/freetype/src/type1/t1load.c +++ b/sdk/lib/3rdparty/freetype/src/type1/t1load.c @@ -1,63 +1,63 @@ -/***************************************************************************/ -/* */ -/* t1load.c */ -/* */ -/* Type 1 font loader (body). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This is the new and improved Type 1 data loader for FreeType 2. The */ - /* old loader has several problems: it is slow, complex, difficult to */ - /* maintain, and contains incredible hacks to make it accept some */ - /* ill-formed Type 1 fonts without hiccup-ing. Moreover, about 5% of */ - /* the Type 1 fonts on my machine still aren't loaded correctly by it. */ - /* */ - /* This version is much simpler, much faster and also easier to read and */ - /* maintain by a great order of magnitude. The idea behind it is to */ - /* _not_ try to read the Type 1 token stream with a state machine (i.e. */ - /* a Postscript-like interpreter) but rather to perform simple pattern */ - /* matching. */ - /* */ - /* Indeed, nearly all data definitions follow a simple pattern like */ - /* */ - /* ... /Field ... */ - /* */ - /* where can be a number, a boolean, a string, or an array of */ - /* numbers. There are a few exceptions, namely the encoding, font name, */ - /* charstrings, and subrs; they are handled with a special pattern */ - /* matching routine. */ - /* */ - /* All other common cases are handled very simply. The matching rules */ - /* are defined in the file `t1tokens.h' through the use of several */ - /* macros calls PARSE_XXX. This file is included twice here; the first */ - /* time to generate parsing callback functions, the second time to */ - /* generate a table of keywords (with pointers to the associated */ - /* callback functions). */ - /* */ - /* The function `parse_dict' simply scans *linearly* a given dictionary */ - /* (either the top-level or private one) and calls the appropriate */ - /* callback when it encounters an immediate keyword. */ - /* */ - /* This is by far the fastest way one can find to parse and read all */ - /* data. */ - /* */ - /* This led to tremendous code size reduction. Note that later, the */ - /* glyph loader will also be _greatly_ simplified, and the automatic */ - /* hinter will replace the clumsy `t1hinter'. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * t1load.c + * + * Type 1 font loader (body). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /************************************************************************** + * + * This is the new and improved Type 1 data loader for FreeType 2. The + * old loader has several problems: it is slow, complex, difficult to + * maintain, and contains incredible hacks to make it accept some + * ill-formed Type 1 fonts without hiccup-ing. Moreover, about 5% of + * the Type 1 fonts on my machine still aren't loaded correctly by it. + * + * This version is much simpler, much faster and also easier to read and + * maintain by a great order of magnitude. The idea behind it is to + * _not_ try to read the Type 1 token stream with a state machine (i.e. + * a Postscript-like interpreter) but rather to perform simple pattern + * matching. + * + * Indeed, nearly all data definitions follow a simple pattern like + * + * ... /Field ... + * + * where can be a number, a boolean, a string, or an array of + * numbers. There are a few exceptions, namely the encoding, font name, + * charstrings, and subrs; they are handled with a special pattern + * matching routine. + * + * All other common cases are handled very simply. The matching rules + * are defined in the file `t1tokens.h' through the use of several + * macros calls PARSE_XXX. This file is included twice here; the first + * time to generate parsing callback functions, the second time to + * generate a table of keywords (with pointers to the associated + * callback functions). + * + * The function `parse_dict' simply scans *linearly* a given dictionary + * (either the top-level or private one) and calls the appropriate + * callback when it encounters an immediate keyword. + * + * This is by far the fastest way one can find to parse and read all + * data. + * + * This led to tremendous code size reduction. Note that later, the + * glyph loader will also be _greatly_ simplified, and the automatic + * hinter will replace the clumsy `t1hinter'. + * + */ #include @@ -73,20 +73,20 @@ #ifdef FT_CONFIG_OPTION_INCREMENTAL -#define IS_INCREMENTAL (FT_Bool)( face->root.internal->incremental_interface != 0 ) +#define IS_INCREMENTAL FT_BOOL( face->root.internal->incremental_interface ) #else #define IS_INCREMENTAL 0 #endif - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_t1load +#define FT_COMPONENT t1load #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT @@ -222,11 +222,11 @@ } - /*************************************************************************/ - /* */ - /* Given a normalized (blend) coordinate, figure out the design */ - /* coordinate appropriate for that value. */ - /* */ + /************************************************************************** + * + * Given a normalized (blend) coordinate, figure out the design + * coordinate appropriate for that value. + */ static FT_Fixed mm_axis_unmap( PS_DesignMap axismap, FT_Fixed ncv ) @@ -251,11 +251,11 @@ } - /*************************************************************************/ - /* */ - /* Given a vector of weights, one for each design, figure out the */ - /* normalized axis coordinates which gave rise to those weights. */ - /* */ + /************************************************************************** + * + * Given a vector of weights, one for each design, figure out the + * normalized axis coordinates which gave rise to those weights. + */ static void mm_weights_unmap( FT_Fixed* weights, FT_Fixed* axiscoords, @@ -293,11 +293,11 @@ } - /*************************************************************************/ - /* */ - /* Just a wrapper around T1_Get_Multi_Master to support the different */ - /* arguments needed by the GX var distortable fonts. */ - /* */ + /************************************************************************** + * + * Just a wrapper around T1_Get_Multi_Master to support the different + * arguments needed by the GX var distortable fonts. + */ FT_LOCAL_DEF( FT_Error ) T1_Get_MM_Var( T1_Face face, FT_MM_Var* *master ) @@ -348,16 +348,13 @@ mmvar->axis[i].tag = FT_MAKE_TAG( 'o', 'p', 's', 'z' ); } - if ( blend->num_designs == ( 1U << blend->num_axis ) ) - { - mm_weights_unmap( blend->default_weight_vector, - axiscoords, - blend->num_axis ); + mm_weights_unmap( blend->default_weight_vector, + axiscoords, + blend->num_axis ); - for ( i = 0; i < mmaster.num_axis; i++ ) - mmvar->axis[i].def = mm_axis_unmap( &blend->design_map[i], - axiscoords[i] ); - } + for ( i = 0; i < mmaster.num_axis; i++ ) + mmvar->axis[i].def = mm_axis_unmap( &blend->design_map[i], + axiscoords[i] ); *master = mmvar; @@ -387,24 +384,31 @@ for ( n = 0; n < blend->num_designs; n++ ) { FT_Fixed result = 0x10000L; /* 1.0 fixed */ + FT_Fixed factor; for ( m = 0; m < blend->num_axis; m++ ) { - FT_Fixed factor; - - - /* get current blend axis position; */ /* use a default value if we don't have a coordinate */ - factor = m < num_coords ? coords[m] : 0x8000; - if ( factor < 0 ) - factor = 0; - if ( factor > 0x10000L ) - factor = 0x10000L; + if ( m >= num_coords ) + { + result >>= 1; + continue; + } + /* get current blend axis position */ + factor = coords[m]; if ( ( n & ( 1 << m ) ) == 0 ) factor = 0x10000L - factor; + if ( factor <= 0 ) + { + result = 0; + break; + } + else if ( factor >= 0x10000L ) + continue; + result = FT_MulFix( result, factor ); } @@ -476,6 +480,75 @@ } + FT_LOCAL_DEF( FT_Error ) + T1_Set_MM_WeightVector( T1_Face face, + FT_UInt len, + FT_Fixed* weightvector ) + { + PS_Blend blend = face->blend; + FT_UInt i, n; + + + if ( !blend ) + return FT_THROW( Invalid_Argument ); + + if ( !len && !weightvector ) + { + for ( i = 0; i < blend->num_designs; i++ ) + blend->weight_vector[i] = blend->default_weight_vector[i]; + } + else + { + if ( !weightvector ) + return FT_THROW( Invalid_Argument ); + + n = len < blend->num_designs ? len : blend->num_designs; + + for ( i = 0; i < n; i++ ) + blend->weight_vector[i] = weightvector[i]; + + for ( ; i < blend->num_designs; i++ ) + blend->weight_vector[i] = (FT_Fixed)0; + + if ( len ) + face->root.face_flags |= FT_FACE_FLAG_VARIATION; + else + face->root.face_flags &= ~FT_FACE_FLAG_VARIATION; + } + + return FT_Err_Ok; + } + + + FT_LOCAL_DEF( FT_Error ) + T1_Get_MM_WeightVector( T1_Face face, + FT_UInt* len, + FT_Fixed* weightvector ) + { + PS_Blend blend = face->blend; + FT_UInt i; + + + if ( !blend ) + return FT_THROW( Invalid_Argument ); + + if ( *len < blend->num_designs ) + { + *len = blend->num_designs; + return FT_THROW( Invalid_Argument ); + } + + for ( i = 0; i < blend->num_designs; i++ ) + weightvector[i] = blend->weight_vector[i]; + for ( ; i < *len; i++ ) + weightvector[i] = (FT_Fixed)0; + + *len = blend->num_designs; + + return FT_Err_Ok; + } + + FT_LOCAL_DEF( FT_Error ) T1_Set_MM_Design( T1_Face face, FT_UInt num_coords, @@ -573,11 +646,11 @@ } - /*************************************************************************/ - /* */ - /* Just a wrapper around T1_Set_MM_Design to support the different */ - /* arguments needed by the GX var distortable fonts. */ - /* */ + /************************************************************************** + * + * Just a wrapper around T1_Set_MM_Design to support the different + * arguments needed by the GX var distortable fonts. + */ FT_LOCAL_DEF( FT_Error ) T1_Set_Var_Design( T1_Face face, FT_UInt num_coords, @@ -719,6 +792,8 @@ if ( error ) goto Exit; + FT_TRACE4(( " [" )); + blend = face->blend; memory = face->root.memory; @@ -741,11 +816,13 @@ goto Exit; } + FT_TRACE4(( " /%.*s", len, token->start )); + name = (FT_Byte*)blend->axis_names[n]; if ( name ) { FT_TRACE0(( "parse_blend_axis_types:" - " overwriting axis name `%s' with `%*.s'\n", + " overwriting axis name `%s' with `%.*s'\n", name, len, token->start )); FT_FREE( name ); } @@ -758,6 +835,8 @@ name[len] = '\0'; } + FT_TRACE4(( "]\n" )); + Exit: loader->parser.root.error = error; } @@ -802,6 +881,8 @@ blend = face->blend; num_axis = 0; /* make compiler happy */ + FT_TRACE4(( " [" )); + for ( n = 0; n < num_designs; n++ ) { T1_TokenRec axis_tokens[T1_MAX_MM_AXIS]; @@ -842,6 +923,7 @@ } /* now read each axis token into the design position */ + FT_TRACE4(( " [" )) ; for ( axis = 0; axis < n_axis; axis++ ) { T1_Token token2 = axis_tokens + axis; @@ -850,9 +932,13 @@ parser->root.cursor = token2->start; parser->root.limit = token2->limit; blend->design_pos[n][axis] = T1_ToFixed( parser, 0 ); + FT_TRACE4(( " %f", (double)blend->design_pos[n][axis] / 65536 )); } + FT_TRACE4(( "]" )) ; } + FT_TRACE4(( "]\n" )); + loader->parser.root.cursor = old_cursor; loader->parser.root.limit = old_limit; } @@ -899,6 +985,8 @@ goto Exit; blend = face->blend; + FT_TRACE4(( " [" )); + /* now read each axis design map */ for ( n = 0; n < num_axis; n++ ) { @@ -915,6 +1003,8 @@ T1_ToTokenArray( parser, point_tokens, T1_MAX_MM_MAP_POINTS, &num_points ); + FT_TRACE4(( " [" )); + if ( num_points <= 0 || num_points > T1_MAX_MM_MAP_POINTS ) { FT_ERROR(( "parse_blend_design_map: incorrect table\n" )); @@ -948,9 +1038,17 @@ map->design_points[p] = T1_ToInt( parser ); map->blend_points [p] = T1_ToFixed( parser, 0 ); + + FT_TRACE4(( " [%d %f]", + map->design_points[p], + (double)map->blend_points[p] / 65536 )); } + + FT_TRACE4(( "]" )); } + FT_TRACE4(( "]\n" )); + parser->root.cursor = old_cursor; parser->root.limit = old_limit; @@ -1010,6 +1108,8 @@ old_cursor = parser->root.cursor; old_limit = parser->root.limit; + FT_TRACE4(( "[" )); + for ( n = 0; n < num_designs; n++ ) { token = design_tokens + n; @@ -1018,8 +1118,12 @@ blend->default_weight_vector[n] = blend->weight_vector[n] = T1_ToFixed( parser, 0 ); + + FT_TRACE4(( " %f", (double)blend->weight_vector[n] / 65536 )); } + FT_TRACE4(( "]\n" )); + parser->root.cursor = old_cursor; parser->root.limit = old_limit; @@ -1036,6 +1140,20 @@ { face->len_buildchar = (FT_UInt)T1_ToFixedArray( &loader->parser, 0, NULL, 0 ); + +#ifdef FT_DEBUG_LEVEL_TRACE + { + FT_UInt i; + + + FT_TRACE4(( " [" )); + for ( i = 0; i < face->len_buildchar; i++ ) + FT_TRACE4(( " 0" )); + + FT_TRACE4(( "]\n" )); + } +#endif + return; } @@ -1071,6 +1189,8 @@ /* if the keyword has a dedicated callback, call it */ if ( field->type == T1_FIELD_TYPE_CALLBACK ) { + FT_TRACE4(( " %s", field->ident )); + field->reader( (FT_Face)face, loader ); error = loader->parser.root.error; goto Exit; @@ -1148,6 +1268,8 @@ max_objects = 0; } + FT_TRACE4(( " %s", field->ident )); + if ( *objects ) { if ( field->type == T1_FIELD_TYPE_INTEGER_ARRAY || @@ -1167,6 +1289,8 @@ error = FT_Err_Ok; } + FT_TRACE4(( "\n" )); + Exit: return error; } @@ -1179,6 +1303,8 @@ FT_UNUSED( face ); loader->keywords_encountered |= T1_PRIVATE; + + FT_TRACE4(( "\n" )); } @@ -1258,6 +1384,14 @@ return; } + FT_TRACE4(( " [%f %f %f %f %f %f]\n", + (double)temp[0] / 65536 / 1000, + (double)temp[1] / 65536 / 1000, + (double)temp[2] / 65536 / 1000, + (double)temp[3] / 65536 / 1000, + (double)temp[4] / 65536 / 1000, + (double)temp[5] / 65536 / 1000 )); + temp_scale = FT_ABS( temp[3] ); if ( temp_scale == 0 ) @@ -1280,12 +1414,18 @@ temp[5] = FT_DivFix( temp[5], temp_scale ); temp[3] = temp[3] < 0 ? -0x10000L : 0x10000L; } - matrix->xx = temp[0]; matrix->yx = temp[1]; matrix->xy = temp[2]; matrix->yy = temp[3]; + if ( !FT_Matrix_Check( matrix ) ) + { + FT_ERROR(( "t1_parse_font_matrix: invalid font matrix\n" )); + parser->root.error = FT_THROW( Invalid_File_Format ); + return; + } + /* note that the offsets must be expressed in integer font units */ offset->x = temp[4] >> 16; offset->y = temp[5] >> 16; @@ -1494,6 +1634,15 @@ T1_Skip_Spaces( parser ); } +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE4(( " [" )); + + /* XXX show encoding vector */ + FT_TRACE4(( "..." )); + + FT_TRACE4(( "]\n" )); +#endif + face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY; parser->root.cursor = cur; } @@ -1504,18 +1653,30 @@ { if ( cur + 17 < limit && ft_strncmp( (const char*)cur, "StandardEncoding", 16 ) == 0 ) + { face->type1.encoding_type = T1_ENCODING_TYPE_STANDARD; + FT_TRACE4(( " StandardEncoding\n" )); + } else if ( cur + 15 < limit && ft_strncmp( (const char*)cur, "ExpertEncoding", 14 ) == 0 ) + { face->type1.encoding_type = T1_ENCODING_TYPE_EXPERT; + FT_TRACE4(( " ExpertEncoding\n" )); + } else if ( cur + 18 < limit && ft_strncmp( (const char*)cur, "ISOLatin1Encoding", 17 ) == 0 ) + { face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1; + FT_TRACE4(( " ISOLatin1Encoding\n" )); + } else + { parser->root.error = FT_ERR( Ignore ); + FT_TRACE4(( "\n" )); + } } } @@ -1696,6 +1857,15 @@ if ( !loader->num_subrs ) loader->num_subrs = num_subrs; +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE4(( " <" )); + + /* XXX show subrs? */ + FT_TRACE4(( "%d elements", num_subrs )); + + FT_TRACE4(( ">\n" )); +#endif + return; Fail: @@ -2017,6 +2187,15 @@ loader->num_glyphs += 1; } +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE4(( " <" )); + + /* XXX show charstrings? */ + FT_TRACE4(( "%d elements", loader->num_glyphs )); + + FT_TRACE4(( ">\n" )); +#endif + return; Fail: @@ -2024,12 +2203,12 @@ } - /*************************************************************************/ - /* */ - /* Define the token field static variables. This is a set of */ - /* T1_FieldRec variables. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * Define the token field static variables. This is a set of + * T1_FieldRec variables. + * + */ static @@ -2216,6 +2395,7 @@ ? T1_FIELD_DICT_PRIVATE : T1_FIELD_DICT_FONTDICT; + if ( !( dict & keyword->dict ) ) { FT_TRACE1(( "parse_dict: found `%s' but ignoring it" @@ -2330,6 +2510,7 @@ if ( error ) goto Exit; + FT_TRACE4(( " top dictionary:\n" )); error = parse_dict( face, &loader, parser->base_dict, parser->base_len ); if ( error ) @@ -2339,6 +2520,7 @@ if ( error ) goto Exit; + FT_TRACE4(( " private dictionary:\n" )); error = parse_dict( face, &loader, parser->private_dict, parser->private_len ); if ( error ) @@ -2349,6 +2531,16 @@ #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT + /* we don't support Multiple Master fonts with intermediate designs; */ + /* this implies that `num_designs' must be equal to `2^^num_axis' */ + if ( face->blend && + face->blend->num_designs != ( 1U << face->blend->num_axis ) ) + { + FT_ERROR(( "T1_Open_Face:" + " number-of-designs != 2 ^^ number-of-axes\n" )); + T1_Done_Blend( face ); + } + if ( face->blend && face->blend->num_default_design_vector != 0 && face->blend->num_default_design_vector != face->blend->num_axis ) @@ -2493,6 +2685,24 @@ type1->encoding.num_chars = loader.num_chars; } + /* some sanitizing to avoid overflows later on; */ + /* the upper limits are ad-hoc values */ + if ( priv->blue_shift > 1000 || priv->blue_shift < 0 ) + { + FT_TRACE2(( "T1_Open_Face:" + " setting unlikely BlueShift value %d to default (7)\n", + priv->blue_shift )); + priv->blue_shift = 7; + } + + if ( priv->blue_fuzz > 1000 || priv->blue_fuzz < 0 ) + { + FT_TRACE2(( "T1_Open_Face:" + " setting unlikely BlueFuzz value %d to default (1)\n", + priv->blue_fuzz )); + priv->blue_fuzz = 1; + } + Exit: t1_done_loader( &loader ); return error; diff --git a/sdk/lib/3rdparty/freetype/src/type1/t1load.h b/sdk/lib/3rdparty/freetype/src/type1/t1load.h index 03be3f7f9377c..44f835bde2396 100644 --- a/sdk/lib/3rdparty/freetype/src/type1/t1load.h +++ b/sdk/lib/3rdparty/freetype/src/type1/t1load.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* t1load.h */ -/* */ -/* Type 1 font loader (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * t1load.h + * + * Type 1 font loader (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef T1LOAD_H_ @@ -106,6 +106,16 @@ FT_BEGIN_HEADER FT_LOCAL( void ) T1_Done_Blend( T1_Face face ); + FT_LOCAL( FT_Error ) + T1_Set_MM_WeightVector( T1_Face face, + FT_UInt len, + FT_Fixed* weightvector ); + + FT_LOCAL( FT_Error ) + T1_Get_MM_WeightVector( T1_Face face, + FT_UInt* len, + FT_Fixed* weightvector ); + #endif /* !T1_CONFIG_OPTION_NO_MM_SUPPORT */ diff --git a/sdk/lib/3rdparty/freetype/src/type1/t1objs.c b/sdk/lib/3rdparty/freetype/src/type1/t1objs.c index 7333c4c9587e1..741388a645a5e 100644 --- a/sdk/lib/3rdparty/freetype/src/type1/t1objs.c +++ b/sdk/lib/3rdparty/freetype/src/type1/t1objs.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* t1objs.c */ -/* */ -/* Type 1 objects manager (body). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * t1objs.c + * + * Type 1 objects manager (body). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include @@ -36,21 +36,21 @@ #include FT_INTERNAL_POSTSCRIPT_AUX_H - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_t1objs +#define FT_COMPONENT t1objs - /*************************************************************************/ - /* */ - /* SIZE FUNCTIONS */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * SIZE FUNCTIONS + * + */ static PSH_Globals_Funcs @@ -133,11 +133,11 @@ } - /*************************************************************************/ - /* */ - /* SLOT FUNCTIONS */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * SLOT FUNCTIONS + * + */ FT_LOCAL_DEF( void ) T1_GlyphSlot_Done( FT_GlyphSlot slot ) @@ -177,24 +177,25 @@ } - /*************************************************************************/ - /* */ - /* FACE FUNCTIONS */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Face_Done */ - /* */ - /* */ - /* The face object destructor. */ - /* */ - /* */ - /* face :: A typeless pointer to the face object to destroy. */ - /* */ + /************************************************************************** + * + * FACE FUNCTIONS + * + */ + + + /************************************************************************** + * + * @Function: + * T1_Face_Done + * + * @Description: + * The face object destructor. + * + * @Input: + * face :: + * A typeless pointer to the face object to destroy. + */ FT_LOCAL_DEF( void ) T1_Face_Done( FT_Face t1face ) /* T1_Face */ { @@ -274,29 +275,34 @@ } - /*************************************************************************/ - /* */ - /* */ - /* T1_Face_Init */ - /* */ - /* */ - /* The face object constructor. */ - /* */ - /* */ - /* stream :: input stream where to load font data. */ - /* */ - /* face_index :: The index of the font face in the resource. */ - /* */ - /* num_params :: Number of additional generic parameters. Ignored. */ - /* */ - /* params :: Additional generic parameters. Ignored. */ - /* */ - /* */ - /* face :: The face record to build. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * T1_Face_Init + * + * @Description: + * The face object constructor. + * + * @Input: + * stream :: + * input stream where to load font data. + * + * face_index :: + * The index of the font face in the resource. + * + * num_params :: + * Number of additional generic parameters. Ignored. + * + * params :: + * Additional generic parameters. Ignored. + * + * @InOut: + * face :: + * The face record to build. + * + * @Return: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) T1_Face_Init( FT_Stream stream, FT_Face t1face, /* T1_Face */ @@ -341,6 +347,10 @@ if ( error ) goto Exit; + FT_TRACE2(( "T1_Face_Init: %08p (index %d)\n", + face, + face_index )); + /* if we just wanted to check the format, leave successfully now */ if ( face_index < 0 ) goto Exit; @@ -516,7 +526,8 @@ error = FT_CMap_New( cmap_classes->unicode, NULL, &charmap, NULL ); if ( error && - FT_ERR_NEQ( error, No_Unicode_Glyph_Name ) ) + FT_ERR_NEQ( error, No_Unicode_Glyph_Name ) && + FT_ERR_NEQ( error, Unimplemented_Feature ) ) goto Exit; error = FT_Err_Ok; @@ -564,20 +575,21 @@ } - /*************************************************************************/ - /* */ - /* */ - /* T1_Driver_Init */ - /* */ - /* */ - /* Initializes a given Type 1 driver object. */ - /* */ - /* */ - /* driver :: A handle to the target driver object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * T1_Driver_Init + * + * @Description: + * Initializes a given Type 1 driver object. + * + * @Input: + * driver :: + * A handle to the target driver object. + * + * @Return: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) T1_Driver_Init( FT_Module module ) { @@ -620,17 +632,18 @@ } - /*************************************************************************/ - /* */ - /* */ - /* T1_Driver_Done */ - /* */ - /* */ - /* Finalizes a given Type 1 driver. */ - /* */ - /* */ - /* driver :: A handle to the target Type 1 driver. */ - /* */ + /************************************************************************** + * + * @Function: + * T1_Driver_Done + * + * @Description: + * Finalizes a given Type 1 driver. + * + * @Input: + * driver :: + * A handle to the target Type 1 driver. + */ FT_LOCAL_DEF( void ) T1_Driver_Done( FT_Module driver ) { diff --git a/sdk/lib/3rdparty/freetype/src/type1/t1objs.h b/sdk/lib/3rdparty/freetype/src/type1/t1objs.h index 8298e036f4bd4..2161091f7795c 100644 --- a/sdk/lib/3rdparty/freetype/src/type1/t1objs.h +++ b/sdk/lib/3rdparty/freetype/src/type1/t1objs.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* t1objs.h */ -/* */ -/* Type 1 objects manager (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * t1objs.h + * + * Type 1 objects manager (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef T1OBJS_H_ @@ -34,59 +34,59 @@ FT_BEGIN_HEADER typedef struct T1_Glyph_Hints_ T1_Glyph_Hints; - /*************************************************************************/ - /* */ - /* */ - /* T1_Size */ - /* */ - /* */ - /* A handle to a Type 1 size object. */ - /* */ + /************************************************************************** + * + * @Type: + * T1_Size + * + * @Description: + * A handle to a Type 1 size object. + */ typedef struct T1_SizeRec_* T1_Size; - /*************************************************************************/ - /* */ - /* */ - /* T1_GlyphSlot */ - /* */ - /* */ - /* A handle to a Type 1 glyph slot object. */ - /* */ + /************************************************************************** + * + * @Type: + * T1_GlyphSlot + * + * @Description: + * A handle to a Type 1 glyph slot object. + */ typedef struct T1_GlyphSlotRec_* T1_GlyphSlot; - /*************************************************************************/ - /* */ - /* */ - /* T1_CharMap */ - /* */ - /* */ - /* A handle to a Type 1 character mapping object. */ - /* */ - /* */ - /* The Type 1 format doesn't use a charmap but an encoding table. */ - /* The driver is responsible for making up charmap objects */ - /* corresponding to these tables. */ - /* */ + /************************************************************************** + * + * @Type: + * T1_CharMap + * + * @Description: + * A handle to a Type 1 character mapping object. + * + * @Note: + * The Type 1 format doesn't use a charmap but an encoding table. + * The driver is responsible for making up charmap objects + * corresponding to these tables. + */ typedef struct T1_CharMapRec_* T1_CharMap; - /*************************************************************************/ - /* */ - /* HERE BEGINS THE TYPE1 SPECIFIC STUFF */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * HERE BEGINS THE TYPE1 SPECIFIC STUFF + * + */ - /*************************************************************************/ - /* */ - /* */ - /* T1_SizeRec */ - /* */ - /* */ - /* Type 1 size record. */ - /* */ + /************************************************************************** + * + * @Type: + * T1_SizeRec + * + * @Description: + * Type 1 size record. + */ typedef struct T1_SizeRec_ { FT_SizeRec root; @@ -105,14 +105,14 @@ FT_BEGIN_HEADER T1_Size_Init( FT_Size size ); - /*************************************************************************/ - /* */ - /* */ - /* T1_GlyphSlotRec */ - /* */ - /* */ - /* Type 1 glyph slot record. */ - /* */ + /************************************************************************** + * + * @Type: + * T1_GlyphSlotRec + * + * @Description: + * Type 1 glyph slot record. + */ typedef struct T1_GlyphSlotRec_ { FT_GlyphSlotRec root; diff --git a/sdk/lib/3rdparty/freetype/src/type1/t1parse.c b/sdk/lib/3rdparty/freetype/src/type1/t1parse.c index 8e201e5ef5ab6..56caeb9e40733 100644 --- a/sdk/lib/3rdparty/freetype/src/type1/t1parse.c +++ b/sdk/lib/3rdparty/freetype/src/type1/t1parse.c @@ -1,36 +1,36 @@ -/***************************************************************************/ -/* */ -/* t1parse.c */ -/* */ -/* Type 1 parser (body). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* The Type 1 parser is in charge of the following: */ - /* */ - /* - provide an implementation of a growing sequence of objects called */ - /* a `T1_Table' (used to build various tables needed by the loader). */ - /* */ - /* - opening .pfb and .pfa files to extract their top-level and private */ - /* dictionaries. */ - /* */ - /* - read numbers, arrays & strings from any dictionary. */ - /* */ - /* See `t1load.c' to see how data is loaded from the font file. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * t1parse.c + * + * Type 1 parser (body). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /************************************************************************** + * + * The Type 1 parser is in charge of the following: + * + * - provide an implementation of a growing sequence of objects called + * a `T1_Table' (used to build various tables needed by the loader). + * + * - opening .pfb and .pfa files to extract their top-level and private + * dictionaries. + * + * - read numbers, arrays & strings from any dictionary. + * + * See `t1load.c' to see how data is loaded from the font file. + * + */ #include @@ -43,14 +43,14 @@ #include "t1errors.h" - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_t1parse +#define FT_COMPONENT t1parse /*************************************************************************/ @@ -169,21 +169,21 @@ } } - /******************************************************************/ - /* */ - /* Here a short summary of what is going on: */ - /* */ - /* When creating a new Type 1 parser, we try to locate and load */ - /* the base dictionary if this is possible (i.e., for PFB */ - /* files). Otherwise, we load the whole font into memory. */ - /* */ - /* When `loading' the base dictionary, we only setup pointers */ - /* in the case of a memory-based stream. Otherwise, we */ - /* allocate and load the base dictionary in it. */ - /* */ - /* parser->in_pfb is set if we are in a binary (`.pfb') font. */ - /* parser->in_memory is set if we have a memory stream. */ - /* */ + /******************************************************************* + * + * Here a short summary of what is going on: + * + * When creating a new Type 1 parser, we try to locate and load + * the base dictionary if this is possible (i.e., for PFB + * files). Otherwise, we load the whole font into memory. + * + * When `loading' the base dictionary, we only setup pointers + * in the case of a memory-based stream. Otherwise, we + * allocate and load the base dictionary in it. + * + * parser->in_pfb is set if we are in a binary (`.pfb') font. + * parser->in_memory is set if we have a memory stream. + */ /* try to compute the size of the base dictionary; */ /* look for a Postscript binary file tag, i.e., 0x8001 */ diff --git a/sdk/lib/3rdparty/freetype/src/type1/t1parse.h b/sdk/lib/3rdparty/freetype/src/type1/t1parse.h index 4ac82ae913ef4..dab8fddc8b613 100644 --- a/sdk/lib/3rdparty/freetype/src/type1/t1parse.h +++ b/sdk/lib/3rdparty/freetype/src/type1/t1parse.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* t1parse.h */ -/* */ -/* Type 1 parser (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * t1parse.h + * + * Type 1 parser (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef T1PARSE_H_ @@ -28,36 +28,45 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* */ - /* T1_ParserRec */ - /* */ - /* */ - /* A PS_ParserRec is an object used to parse a Type 1 fonts very */ - /* quickly. */ - /* */ - /* */ - /* root :: The root parser. */ - /* */ - /* stream :: The current input stream. */ - /* */ - /* base_dict :: A pointer to the top-level dictionary. */ - /* */ - /* base_len :: The length in bytes of the top dictionary. */ - /* */ - /* private_dict :: A pointer to the private dictionary. */ - /* */ - /* private_len :: The length in bytes of the private dictionary. */ - /* */ - /* in_pfb :: A boolean. Indicates that we are handling a PFB */ - /* file. */ - /* */ - /* in_memory :: A boolean. Indicates a memory-based stream. */ - /* */ - /* single_block :: A boolean. Indicates that the private dictionary */ - /* is stored in lieu of the base dictionary. */ - /* */ + /************************************************************************** + * + * @Struct: + * T1_ParserRec + * + * @Description: + * A PS_ParserRec is an object used to parse a Type 1 fonts very + * quickly. + * + * @Fields: + * root :: + * The root parser. + * + * stream :: + * The current input stream. + * + * base_dict :: + * A pointer to the top-level dictionary. + * + * base_len :: + * The length in bytes of the top dictionary. + * + * private_dict :: + * A pointer to the private dictionary. + * + * private_len :: + * The length in bytes of the private dictionary. + * + * in_pfb :: + * A boolean. Indicates that we are handling a PFB + * file. + * + * in_memory :: + * A boolean. Indicates a memory-based stream. + * + * single_block :: + * A boolean. Indicates that the private dictionary + * is stored in lieu of the base dictionary. + */ typedef struct T1_ParserRec_ { PS_ParserRec root; diff --git a/sdk/lib/3rdparty/freetype/src/type1/t1tokens.h b/sdk/lib/3rdparty/freetype/src/type1/t1tokens.h index 43a65d88ea458..97f2dbe0cfa1b 100644 --- a/sdk/lib/3rdparty/freetype/src/type1/t1tokens.h +++ b/sdk/lib/3rdparty/freetype/src/type1/t1tokens.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* t1tokens.h */ -/* */ -/* Type 1 tokenizer (specification). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * t1tokens.h + * + * Type 1 tokenizer (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #undef FT_STRUCTURE diff --git a/sdk/lib/3rdparty/freetype/src/type1/type1.c b/sdk/lib/3rdparty/freetype/src/type1/type1.c index 72eff59bfede6..ce8557a5fbf7e 100644 --- a/sdk/lib/3rdparty/freetype/src/type1/type1.c +++ b/sdk/lib/3rdparty/freetype/src/type1/type1.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* type1.c */ -/* */ -/* FreeType Type 1 driver component (body only). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * type1.c + * + * FreeType Type 1 driver component (body only). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #define FT_MAKE_OPTION_SINGLE_OBJECT diff --git a/sdk/lib/3rdparty/freetype/src/type42/t42drivr.c b/sdk/lib/3rdparty/freetype/src/type42/t42drivr.c index f579b2708c893..6d4e7a09554ce 100644 --- a/sdk/lib/3rdparty/freetype/src/type42/t42drivr.c +++ b/sdk/lib/3rdparty/freetype/src/type42/t42drivr.c @@ -1,39 +1,39 @@ -/***************************************************************************/ -/* */ -/* t42drivr.c */ -/* */ -/* High-level Type 42 driver interface (body). */ -/* */ -/* Copyright 2002-2018 by */ -/* Roberto Alameda. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This driver implements Type42 fonts as described in the */ - /* Technical Note #5012 from Adobe, with these limitations: */ - /* */ - /* 1) CID Fonts are not currently supported. */ - /* 2) Incremental fonts making use of the GlyphDirectory keyword */ - /* will be loaded, but the rendering will be using the TrueType */ - /* tables. */ - /* 3) As for Type1 fonts, CDevProc is not supported. */ - /* 4) The Metrics dictionary is not supported. */ - /* 5) AFM metrics are not supported. */ - /* */ - /* In other words, this driver supports Type42 fonts derived from */ - /* TrueType fonts in a non-CID manner, as done by usual conversion */ - /* programs. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * t42drivr.c + * + * High-level Type 42 driver interface (body). + * + * Copyright (C) 2002-2019 by + * Roberto Alameda. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /************************************************************************** + * + * This driver implements Type42 fonts as described in the + * Technical Note #5012 from Adobe, with these limitations: + * + * 1) CID Fonts are not currently supported. + * 2) Incremental fonts making use of the GlyphDirectory keyword + * will be loaded, but the rendering will be using the TrueType + * tables. + * 3) As for Type1 fonts, CDevProc is not supported. + * 4) The Metrics dictionary is not supported. + * 5) AFM metrics are not supported. + * + * In other words, this driver supports Type42 fonts derived from + * TrueType fonts in a non-CID manner, as done by usual conversion + * programs. + * + */ #include "t42drivr.h" @@ -47,12 +47,12 @@ #include FT_SERVICE_POSTSCRIPT_INFO_H #undef FT_COMPONENT -#define FT_COMPONENT trace_t42 +#define FT_COMPONENT t42 /* * - * GLYPH DICT SERVICE + * GLYPH DICT SERVICE * */ @@ -98,7 +98,7 @@ /* * - * POSTSCRIPT NAME SERVICE + * POSTSCRIPT NAME SERVICE * */ @@ -117,7 +117,7 @@ /* * - * POSTSCRIPT INFO SERVICE + * POSTSCRIPT INFO SERVICE * */ @@ -173,7 +173,7 @@ /* * - * SERVICE LIST + * SERVICE LIST * */ diff --git a/sdk/lib/3rdparty/freetype/src/type42/t42drivr.h b/sdk/lib/3rdparty/freetype/src/type42/t42drivr.h index 3667f3e066791..a35ca28f847ca 100644 --- a/sdk/lib/3rdparty/freetype/src/type42/t42drivr.h +++ b/sdk/lib/3rdparty/freetype/src/type42/t42drivr.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* t42drivr.h */ -/* */ -/* High-level Type 42 driver interface (specification). */ -/* */ -/* Copyright 2002-2018 by */ -/* Roberto Alameda. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * t42drivr.h + * + * High-level Type 42 driver interface (specification). + * + * Copyright (C) 2002-2019 by + * Roberto Alameda. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef T42DRIVR_H_ @@ -26,14 +26,8 @@ FT_BEGIN_HEADER -#ifdef FT_CONFIG_OPTION_PIC -#error "this module does not support PIC yet" -#endif - - FT_EXPORT_VAR( const FT_Driver_ClassRec ) t42_driver_class; - FT_END_HEADER diff --git a/sdk/lib/3rdparty/freetype/src/type42/t42error.h b/sdk/lib/3rdparty/freetype/src/type42/t42error.h index e3978a760778c..5fb21439497b1 100644 --- a/sdk/lib/3rdparty/freetype/src/type42/t42error.h +++ b/sdk/lib/3rdparty/freetype/src/type42/t42error.h @@ -1,26 +1,26 @@ -/***************************************************************************/ -/* */ -/* t42error.h */ -/* */ -/* Type 42 error codes (specification only). */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to define the Type 42 error enumeration constants. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * t42error.h + * + * Type 42 error codes (specification only). + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /************************************************************************** + * + * This file is used to define the Type 42 error enumeration constants. + * + */ #ifndef T42ERROR_H_ #define T42ERROR_H_ diff --git a/sdk/lib/3rdparty/freetype/src/type42/t42objs.c b/sdk/lib/3rdparty/freetype/src/type42/t42objs.c index 66e5c40382532..234c0a3e9756b 100644 --- a/sdk/lib/3rdparty/freetype/src/type42/t42objs.c +++ b/sdk/lib/3rdparty/freetype/src/type42/t42objs.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* t42objs.c */ -/* */ -/* Type 42 objects manager (body). */ -/* */ -/* Copyright 2002-2018 by */ -/* Roberto Alameda. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * t42objs.c + * + * Type 42 objects manager (body). + * + * Copyright (C) 2002-2019 by + * Roberto Alameda. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include "t42objs.h" @@ -25,7 +25,7 @@ #undef FT_COMPONENT -#define FT_COMPONENT trace_t42 +#define FT_COMPONENT t42 static FT_Error @@ -354,7 +354,8 @@ error = FT_CMap_New( cmap_classes->unicode, NULL, &charmap, NULL ); if ( error && - FT_ERR_NEQ( error, No_Unicode_Glyph_Name ) ) + FT_ERR_NEQ( error, No_Unicode_Glyph_Name ) && + FT_ERR_NEQ( error, Unimplemented_Feature ) ) goto Exit; error = FT_Err_Ok; @@ -457,20 +458,21 @@ } - /*************************************************************************/ - /* */ - /* */ - /* T42_Driver_Init */ - /* */ - /* */ - /* Initializes a given Type 42 driver object. */ - /* */ - /* */ - /* driver :: A handle to the target driver object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ + /************************************************************************** + * + * @Function: + * T42_Driver_Init + * + * @Description: + * Initializes a given Type 42 driver object. + * + * @Input: + * driver :: + * A handle to the target driver object. + * + * @Return: + * FreeType error code. 0 means success. + */ FT_LOCAL_DEF( FT_Error ) T42_Driver_Init( FT_Module module ) /* T42_Driver */ { diff --git a/sdk/lib/3rdparty/freetype/src/type42/t42objs.h b/sdk/lib/3rdparty/freetype/src/type42/t42objs.h index 3bad5135e09b5..98300cf348541 100644 --- a/sdk/lib/3rdparty/freetype/src/type42/t42objs.h +++ b/sdk/lib/3rdparty/freetype/src/type42/t42objs.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* t42objs.h */ -/* */ -/* Type 42 objects manager (specification). */ -/* */ -/* Copyright 2002-2018 by */ -/* Roberto Alameda. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * t42objs.h + * + * Type 42 objects manager (specification). + * + * Copyright (C) 2002-2019 by + * Roberto Alameda. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef T42OBJS_H_ diff --git a/sdk/lib/3rdparty/freetype/src/type42/t42parse.c b/sdk/lib/3rdparty/freetype/src/type42/t42parse.c index 4813d1f3f9896..b653a133a550f 100644 --- a/sdk/lib/3rdparty/freetype/src/type42/t42parse.c +++ b/sdk/lib/3rdparty/freetype/src/type42/t42parse.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* t42parse.c */ -/* */ -/* Type 42 font parser (body). */ -/* */ -/* Copyright 2002-2018 by */ -/* Roberto Alameda. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * t42parse.c + * + * Type 42 font parser (body). + * + * Copyright (C) 2002-2019 by + * Roberto Alameda. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include "t42parse.h" @@ -23,14 +23,14 @@ #include FT_INTERNAL_POSTSCRIPT_AUX_H - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_t42 +#define FT_COMPONENT t42 static void @@ -149,19 +149,19 @@ parser->base_dict = NULL; parser->in_memory = 0; - /*******************************************************************/ - /* */ - /* Here a short summary of what is going on: */ - /* */ - /* When creating a new Type 42 parser, we try to locate and load */ - /* the base dictionary, loading the whole font into memory. */ - /* */ - /* When `loading' the base dictionary, we only set up pointers */ - /* in the case of a memory-based stream. Otherwise, we allocate */ - /* and load the base dictionary in it. */ - /* */ - /* parser->in_memory is set if we have a memory stream. */ - /* */ + /******************************************************************** + * + * Here a short summary of what is going on: + * + * When creating a new Type 42 parser, we try to locate and load + * the base dictionary, loading the whole font into memory. + * + * When `loading' the base dictionary, we only set up pointers + * in the case of a memory-based stream. Otherwise, we allocate + * and load the base dictionary in it. + * + * parser->in_memory is set if we have a memory stream. + */ if ( FT_STREAM_SEEK( 0L ) || FT_FRAME_ENTER( 17 ) ) @@ -284,6 +284,13 @@ matrix->xy = temp[2]; matrix->yy = temp[3]; + if ( !FT_Matrix_Check( matrix ) ) + { + FT_ERROR(( "t42_parse_font_matrix: invalid font matrix\n" )); + parser->root.error = FT_THROW( Invalid_File_Format ); + return; + } + /* note that the offsets must be expressed in integer font units */ offset->x = temp[4] >> 16; offset->y = temp[5] >> 16; @@ -588,6 +595,14 @@ else if ( *cur == '<' ) { + if ( string_buf && !allocated ) + { + FT_ERROR(( "t42_parse_sfnts: " + "can't handle mixed binary and hex strings\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + T1_Skip_PS_Token( parser ); if ( parser->root.error ) goto Exit; diff --git a/sdk/lib/3rdparty/freetype/src/type42/t42parse.h b/sdk/lib/3rdparty/freetype/src/type42/t42parse.h index f35d23de63527..0c7bb48496dde 100644 --- a/sdk/lib/3rdparty/freetype/src/type42/t42parse.h +++ b/sdk/lib/3rdparty/freetype/src/type42/t42parse.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* t42parse.h */ -/* */ -/* Type 42 font parser (specification). */ -/* */ -/* Copyright 2002-2018 by */ -/* Roberto Alameda. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * t42parse.h + * + * Type 42 font parser (specification). + * + * Copyright (C) 2002-2019 by + * Roberto Alameda. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef T42PARSE_H_ diff --git a/sdk/lib/3rdparty/freetype/src/type42/t42types.h b/sdk/lib/3rdparty/freetype/src/type42/t42types.h index d0aa2de570533..a258144ec3d14 100644 --- a/sdk/lib/3rdparty/freetype/src/type42/t42types.h +++ b/sdk/lib/3rdparty/freetype/src/type42/t42types.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* t42types.h */ -/* */ -/* Type 42 font data types (specification only). */ -/* */ -/* Copyright 2002-2018 by */ -/* Roberto Alameda. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * t42types.h + * + * Type 42 font data types (specification only). + * + * Copyright (C) 2002-2019 by + * Roberto Alameda. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef T42TYPES_H_ diff --git a/sdk/lib/3rdparty/freetype/src/type42/type42.c b/sdk/lib/3rdparty/freetype/src/type42/type42.c index 6a89cfbed1b5d..0cb7b77eec1a1 100644 --- a/sdk/lib/3rdparty/freetype/src/type42/type42.c +++ b/sdk/lib/3rdparty/freetype/src/type42/type42.c @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* type42.c */ -/* */ -/* FreeType Type 42 driver component. */ -/* */ -/* Copyright 2002-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * type42.c + * + * FreeType Type 42 driver component. + * + * Copyright (C) 2002-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #define FT_MAKE_OPTION_SINGLE_OBJECT diff --git a/sdk/lib/3rdparty/freetype/src/winfonts/fnterrs.h b/sdk/lib/3rdparty/freetype/src/winfonts/fnterrs.h index 3a86af5aacef2..af29307c75c7f 100644 --- a/sdk/lib/3rdparty/freetype/src/winfonts/fnterrs.h +++ b/sdk/lib/3rdparty/freetype/src/winfonts/fnterrs.h @@ -1,27 +1,27 @@ -/***************************************************************************/ -/* */ -/* fnterrs.h */ -/* */ -/* Win FNT/FON error codes (specification only). */ -/* */ -/* Copyright 2001-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file is used to define the Windows FNT/FON error enumeration */ - /* constants. */ - /* */ - /*************************************************************************/ +/**************************************************************************** + * + * fnterrs.h + * + * Win FNT/FON error codes (specification only). + * + * Copyright (C) 2001-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + + /************************************************************************** + * + * This file is used to define the Windows FNT/FON error enumeration + * constants. + * + */ #ifndef FNTERRS_H_ #define FNTERRS_H_ diff --git a/sdk/lib/3rdparty/freetype/src/winfonts/winfnt.c b/sdk/lib/3rdparty/freetype/src/winfonts/winfnt.c index 36bd3148d51da..2d771be2ccb01 100644 --- a/sdk/lib/3rdparty/freetype/src/winfonts/winfnt.c +++ b/sdk/lib/3rdparty/freetype/src/winfonts/winfnt.c @@ -1,21 +1,21 @@ -/***************************************************************************/ -/* */ -/* winfnt.c */ -/* */ -/* FreeType font driver for Windows FNT/FON files */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* Copyright 2003 Huw D M Davies for Codeweavers */ -/* Copyright 2007 Dmitry Timoshkov for Codeweavers */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * winfnt.c + * + * FreeType font driver for Windows FNT/FON files + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * Copyright 2003 Huw D M Davies for Codeweavers + * Copyright 2007 Dmitry Timoshkov for Codeweavers + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #include @@ -30,14 +30,14 @@ #include FT_SERVICE_WINFNT_H #include FT_SERVICE_FONT_FORMAT_H - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ #undef FT_COMPONENT -#define FT_COMPONENT trace_winfnt +#define FT_COMPONENT winfnt static const FT_Frame_Field winmz_header_fields[] = @@ -1131,10 +1131,10 @@ winfnt_get_header /* get_header */ }; - /* - * SERVICE LIST - * - */ + /* + * SERVICE LIST + * + */ static const FT_ServiceDescRec winfnt_services[] = { diff --git a/sdk/lib/3rdparty/freetype/src/winfonts/winfnt.h b/sdk/lib/3rdparty/freetype/src/winfonts/winfnt.h index 4885c9d74523a..b628ad4c425a5 100644 --- a/sdk/lib/3rdparty/freetype/src/winfonts/winfnt.h +++ b/sdk/lib/3rdparty/freetype/src/winfonts/winfnt.h @@ -1,20 +1,20 @@ -/***************************************************************************/ -/* */ -/* winfnt.h */ -/* */ -/* FreeType font driver for Windows FNT/FON files */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* Copyright 2007 Dmitry Timoshkov for Codeweavers */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * winfnt.h + * + * FreeType font driver for Windows FNT/FON files + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * Copyright 2007 Dmitry Timoshkov for Codeweavers + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef WINFNT_H_ @@ -28,9 +28,6 @@ FT_BEGIN_HEADER -#ifdef FT_CONFIG_OPTION_PIC -#error "this module does not support PIC yet" -#endif typedef struct WinMZ_HeaderRec_ { @@ -153,9 +150,6 @@ FT_BEGIN_HEADER FT_FaceRec root; FNT_Font font; - FT_CharMap charmap_handle; - FT_CharMapRec charmap; /* a single charmap per face */ - } FNT_FaceRec, *FNT_Face; diff --git a/sdk/lib/3rdparty/zlib/CMakeLists.txt b/sdk/lib/3rdparty/zlib/CMakeLists.txt index af42ff93b48db..2630baf087056 100644 --- a/sdk/lib/3rdparty/zlib/CMakeLists.txt +++ b/sdk/lib/3rdparty/zlib/CMakeLists.txt @@ -31,6 +31,9 @@ list(APPEND MINIZIP_SOURCE contrib/minizip/zip.c contrib/minizip/zip.h) +if(CMAKE_C_COMPILER_ID STREQUAL "Clang") + add_compile_options(-Wno-deprecated-non-prototype) +endif() if(CMAKE_CROSSCOMPILING) add_library(zlib ${SOURCE} ${SOLO_SOURCE}) diff --git a/sdk/lib/CMakeLists.txt b/sdk/lib/CMakeLists.txt index 34dc04870fd8a..e3344d8c62192 100644 --- a/sdk/lib/CMakeLists.txt +++ b/sdk/lib/CMakeLists.txt @@ -52,8 +52,10 @@ add_subdirectory(strmiids) add_subdirectory(smlib) add_subdirectory(tdilib) add_subdirectory(tzlib) +add_subdirectory(ucrt) add_subdirectory(udmihelp) add_subdirectory(uuid) +add_subdirectory(vcruntime) add_subdirectory(wdmguid) else() diff --git a/sdk/lib/apisets/apisets.table.c b/sdk/lib/apisets/apisets.table.c index bc352128b70dd..fdbdad720963d 100644 --- a/sdk/lib/apisets/apisets.table.c +++ b/sdk/lib/apisets/apisets.table.c @@ -318,21 +318,21 @@ const ROS_APISET g_Apisets[] = { // { RTL_CONSTANT_STRING(L"api-ms-win-coremessaging-host-l1-1-0"), RTL_CONSTANT_STRING(L""), APISET_WIN10 }, // { RTL_CONSTANT_STRING(L"api-ms-win-coreui-l1-1-0"), RTL_CONSTANT_STRING(L""), APISET_WIN8 | APISET_WIN81 }, // { RTL_CONSTANT_STRING(L"api-ms-win-coreui-secruntime-l1-1-0"), RTL_CONSTANT_STRING(L""), APISET_WIN10 }, - { RTL_CONSTANT_STRING(L"api-ms-win-crt-conio-l1-1-0"), RTL_CONSTANT_STRING(L"msvcrt.dll"), APISET_WIN10 }, // ucrtbase.dll - { RTL_CONSTANT_STRING(L"api-ms-win-crt-convert-l1-1-0"), RTL_CONSTANT_STRING(L"msvcrt.dll"), APISET_WIN10 }, // ucrtbase.dll - { RTL_CONSTANT_STRING(L"api-ms-win-crt-environment-l1-1-0"), RTL_CONSTANT_STRING(L"msvcrt.dll"), APISET_WIN10 }, // ucrtbase.dll - { RTL_CONSTANT_STRING(L"api-ms-win-crt-filesystem-l1-1-0"), RTL_CONSTANT_STRING(L"msvcrt.dll"), APISET_WIN10 }, // ucrtbase.dll - { RTL_CONSTANT_STRING(L"api-ms-win-crt-heap-l1-1-0"), RTL_CONSTANT_STRING(L"msvcrt.dll"), APISET_WIN10 }, // ucrtbase.dll - { RTL_CONSTANT_STRING(L"api-ms-win-crt-locale-l1-1-0"), RTL_CONSTANT_STRING(L"msvcrt.dll"), APISET_WIN10 }, // ucrtbase.dll - { RTL_CONSTANT_STRING(L"api-ms-win-crt-math-l1-1-0"), RTL_CONSTANT_STRING(L"msvcrt.dll"), APISET_WIN10 }, // ucrtbase.dll - { RTL_CONSTANT_STRING(L"api-ms-win-crt-multibyte-l1-1-0"), RTL_CONSTANT_STRING(L"msvcrt.dll"), APISET_WIN10 }, // ucrtbase.dll - { RTL_CONSTANT_STRING(L"api-ms-win-crt-private-l1-1-0"), RTL_CONSTANT_STRING(L"msvcrt.dll"), APISET_WIN10 }, // ucrtbase.dll - { RTL_CONSTANT_STRING(L"api-ms-win-crt-process-l1-1-0"), RTL_CONSTANT_STRING(L"msvcrt.dll"), APISET_WIN10 }, // ucrtbase.dll - { RTL_CONSTANT_STRING(L"api-ms-win-crt-runtime-l1-1-0"), RTL_CONSTANT_STRING(L"msvcrt.dll"), APISET_WIN10 }, // ucrtbase.dll - { RTL_CONSTANT_STRING(L"api-ms-win-crt-stdio-l1-1-0"), RTL_CONSTANT_STRING(L"msvcrt.dll"), APISET_WIN10 }, // ucrtbase.dll - { RTL_CONSTANT_STRING(L"api-ms-win-crt-string-l1-1-0"), RTL_CONSTANT_STRING(L"msvcrt.dll"), APISET_WIN10 }, // ucrtbase.dll - { RTL_CONSTANT_STRING(L"api-ms-win-crt-time-l1-1-0"), RTL_CONSTANT_STRING(L"msvcrt.dll"), APISET_WIN10 }, // ucrtbase.dll - { RTL_CONSTANT_STRING(L"api-ms-win-crt-utility-l1-1-0"), RTL_CONSTANT_STRING(L"msvcrt.dll"), APISET_WIN10 }, // ucrtbase.dll + { RTL_CONSTANT_STRING(L"api-ms-win-crt-conio-l1-1-0"), RTL_CONSTANT_STRING(L"ucrtbase.dll"), APISET_WIN10 }, + { RTL_CONSTANT_STRING(L"api-ms-win-crt-convert-l1-1-0"), RTL_CONSTANT_STRING(L"ucrtbase.dll"), APISET_WIN10 }, + { RTL_CONSTANT_STRING(L"api-ms-win-crt-environment-l1-1-0"), RTL_CONSTANT_STRING(L"ucrtbase.dll"), APISET_WIN10 }, + { RTL_CONSTANT_STRING(L"api-ms-win-crt-filesystem-l1-1-0"), RTL_CONSTANT_STRING(L"ucrtbase.dll"), APISET_WIN10 }, + { RTL_CONSTANT_STRING(L"api-ms-win-crt-heap-l1-1-0"), RTL_CONSTANT_STRING(L"ucrtbase.dll"), APISET_WIN10 }, + { RTL_CONSTANT_STRING(L"api-ms-win-crt-locale-l1-1-0"), RTL_CONSTANT_STRING(L"ucrtbase.dll"), APISET_WIN10 }, + { RTL_CONSTANT_STRING(L"api-ms-win-crt-math-l1-1-0"), RTL_CONSTANT_STRING(L"ucrtbase.dll"), APISET_WIN10 }, + { RTL_CONSTANT_STRING(L"api-ms-win-crt-multibyte-l1-1-0"), RTL_CONSTANT_STRING(L"ucrtbase.dll"), APISET_WIN10 }, + { RTL_CONSTANT_STRING(L"api-ms-win-crt-private-l1-1-0"), RTL_CONSTANT_STRING(L"ucrtbase.dll"), APISET_WIN10 }, + { RTL_CONSTANT_STRING(L"api-ms-win-crt-process-l1-1-0"), RTL_CONSTANT_STRING(L"ucrtbase.dll"), APISET_WIN10 }, + { RTL_CONSTANT_STRING(L"api-ms-win-crt-runtime-l1-1-0"), RTL_CONSTANT_STRING(L"ucrtbase.dll"), APISET_WIN10 }, + { RTL_CONSTANT_STRING(L"api-ms-win-crt-stdio-l1-1-0"), RTL_CONSTANT_STRING(L"ucrtbase.dll"), APISET_WIN10 }, + { RTL_CONSTANT_STRING(L"api-ms-win-crt-string-l1-1-0"), RTL_CONSTANT_STRING(L"ucrtbase.dll"), APISET_WIN10 }, + { RTL_CONSTANT_STRING(L"api-ms-win-crt-time-l1-1-0"), RTL_CONSTANT_STRING(L"ucrtbase.dll"), APISET_WIN10 }, + { RTL_CONSTANT_STRING(L"api-ms-win-crt-utility-l1-1-0"), RTL_CONSTANT_STRING(L"ucrtbase.dll"), APISET_WIN10 }, // { RTL_CONSTANT_STRING(L"api-ms-win-deprecated-apis-advapi-l1-1-0"), RTL_CONSTANT_STRING(L""), APISET_WIN10 }, // { RTL_CONSTANT_STRING(L"api-ms-win-deprecated-apis-legacy-l1-1-0"), RTL_CONSTANT_STRING(L""), APISET_WIN10 }, // { RTL_CONSTANT_STRING(L"api-ms-win-deprecated-apis-legacy-l1-2-0"), RTL_CONSTANT_STRING(L""), APISET_WIN10 }, diff --git a/sdk/lib/conutils/outstream.c b/sdk/lib/conutils/outstream.c index 9dd0dfa12073b..428a0b00c4047 100644 --- a/sdk/lib/conutils/outstream.c +++ b/sdk/lib/conutils/outstream.c @@ -103,7 +103,7 @@ ConWrite( /* * This code is inspired from _cputws, in particular from the fact that, - * according to MSDN: https://msdn.microsoft.com/en-us/library/ms687401(v=vs.85).aspx + * according to MSDN: https://learn.microsoft.com/en-us/windows/console/writeconsole * the buffer size must be less than 64 KB. * * A similar code can be used for implementing _cputs too. diff --git a/sdk/lib/crt/CMakeLists.txt b/sdk/lib/crt/CMakeLists.txt index 740b9aec15457..634be636c18f1 100644 --- a/sdk/lib/crt/CMakeLists.txt +++ b/sdk/lib/crt/CMakeLists.txt @@ -28,6 +28,7 @@ include(crt.cmake) include(libcntpr.cmake) include(msvcrtex.cmake) include(oldnames.cmake) +include(ucrtsupport.cmake) add_library(user32_wsprintf printf/streamout.c diff --git a/sdk/lib/crt/except/amd64/cpp.s b/sdk/lib/crt/except/amd64/cpp.s index ad869b8d6095b..c4f472d65a1f8 100644 --- a/sdk/lib/crt/except/amd64/cpp.s +++ b/sdk/lib/crt/except/amd64/cpp.s @@ -28,62 +28,4 @@ DEFINE_EXCEPTION_VTABLE bad_typeid, ??_7bad_typeid@@6B@ DEFINE_EXCEPTION_VTABLE bad_cast, ??_7bad_cast@@6B@ DEFINE_EXCEPTION_VTABLE __non_rtti_object, ??_7__non_rtti_object@@6B@ - -MACRO(DEFINE_ALIAS, alias, orig) -EXTERN &orig:ABS -ALIAS <&alias> = <&orig> -ENDM - -DEFINE_ALIAS ??3@YAXPEAX@Z, operator_delete -DEFINE_ALIAS ??_U@YAPEAX_K@Z, operator_new -DEFINE_ALIAS ??_U@YAPEAX_KHPEBDH@Z, operator_new_dbg -DEFINE_ALIAS ??_V@YAXPEAX@Z, operator_delete -DEFINE_ALIAS ??2@YAPEAX_K@Z, operator_new -DEFINE_ALIAS ??2@YAPEAX_KHPEBDH@Z, operator_new_dbg -DEFINE_ALIAS ?_query_new_handler@@YAP6AHI@ZXZ, _query_new_handler -DEFINE_ALIAS ?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z, _set_new_handler -DEFINE_ALIAS ?set_new_handler@@YAP6AXXZP6AXXZ@Z, set_new_handler -DEFINE_ALIAS ?_query_new_mode@@YAHXZ, _query_new_mode -DEFINE_ALIAS ?_set_new_mode@@YAHH@Z, _set_new_mode -DEFINE_ALIAS ?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z, _set_se_translator -DEFINE_ALIAS ?set_terminate@@YAP6AXXZP6AXXZ@Z, set_terminate -DEFINE_ALIAS ?set_unexpected@@YAP6AXXZP6AXXZ@Z, set_unexpected -DEFINE_ALIAS ?terminate@@YAXXZ, terminate -DEFINE_ALIAS ?unexpected@@YAXXZ, unexpected -DEFINE_ALIAS ?what@exception@@UEBAPEBDXZ, exception_what -DEFINE_ALIAS ??0exception@@QEAA@AEBQEBDH@Z, exception_ctor_noalloc -DEFINE_ALIAS ??0exception@@QEAA@AEBV0@@Z, exception_copy_ctor -DEFINE_ALIAS ??0exception@@QEAA@XZ, exception_default_ctor -DEFINE_ALIAS ??1exception@@UEAA@XZ, exception_dtor -DEFINE_ALIAS ??4exception@@QEAAAEAV0@AEBV0@@Z, exception_opequals -DEFINE_ALIAS ??1type_info@@UEAA@XZ, type_info_dtor -DEFINE_ALIAS ??0__non_rtti_object@@QEAA@AEBV0@@Z, __non_rtti_object_copy_ctor -DEFINE_ALIAS ??0__non_rtti_object@@QEAA@PEBD@Z, __non_rtti_object_ctor -DEFINE_ALIAS ??0bad_cast@@AAE@PBQBD@Z, bad_cast_ctor -DEFINE_ALIAS ??0bad_cast@@AEAA@PEBQEBD@Z, bad_cast_ctor -DEFINE_ALIAS ??0bad_cast@@QAE@ABQBD@Z, bad_cast_ctor -DEFINE_ALIAS ??0bad_cast@@QEAA@AEBQEBD@Z, bad_cast_ctor -DEFINE_ALIAS ??0bad_cast@@QEAA@AEBV0@@Z, bad_cast_copy_ctor -DEFINE_ALIAS ??0bad_cast@@QEAA@PEBD@Z, bad_cast_ctor_charptr -DEFINE_ALIAS ??0bad_typeid@@QEAA@AEBV0@@Z, bad_typeid_copy_ctor -DEFINE_ALIAS ??0bad_typeid@@QEAA@PEBD@Z, bad_typeid_ctor -DEFINE_ALIAS ??0exception@@QEAA@AEBQEBD@Z, exception_ctor -DEFINE_ALIAS ??1__non_rtti_object@@UEAA@XZ, __non_rtti_object_dtor -DEFINE_ALIAS ??1bad_cast@@UEAA@XZ, bad_cast_dtor -DEFINE_ALIAS ??1bad_typeid@@UEAA@XZ, bad_typeid_dtor -DEFINE_ALIAS ??4bad_cast@@QEAAAEAV0@AEBV0@@Z, bad_cast_opequals -DEFINE_ALIAS ??4bad_typeid@@QEAAAEAV0@AEBV0@@Z, bad_typeid_opequals -DEFINE_ALIAS ??8type_info@@QEBAHAEBV0@@Z, type_info_opequals_equals -DEFINE_ALIAS ??9type_info@@QEBAHAEBV0@@Z, type_info_opnot_equals -DEFINE_ALIAS ??_Fbad_cast@@QEAAXXZ, bad_cast_default_ctor -DEFINE_ALIAS ??_Fbad_typeid@@QEAAXXZ, bad_typeid_default_ctor -DEFINE_ALIAS ?_query_new_handler@@YAP6AH_K@ZXZ, _query_new_handler -DEFINE_ALIAS ?_set_new_handler@@YAP6AH_K@ZP6AH0@Z@Z, _set_new_handler -DEFINE_ALIAS ?_set_se_translator@@YAP6AXIPEAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z, _set_se_translator -DEFINE_ALIAS ?before@type_info@@QEBAHAEBV1@@Z, type_info_before -DEFINE_ALIAS ?name@type_info@@QEBAPEBDXZ, type_info_name -DEFINE_ALIAS ?raw_name@type_info@@QEBAPEBDXZ, type_info_raw_name -DEFINE_ALIAS ??4__non_rtti_object@@QEAAAEAV0@AEBV0@@Z, __non_rtti_object_opequals - END - diff --git a/sdk/lib/crt/except/amd64/cpp_alias.s b/sdk/lib/crt/except/amd64/cpp_alias.s new file mode 100644 index 0000000000000..a7da20ad93cca --- /dev/null +++ b/sdk/lib/crt/except/amd64/cpp_alias.s @@ -0,0 +1,64 @@ + + +#include + +.code64 +.align 4 + +MACRO(DEFINE_ALIAS, alias, orig) +EXTERN &orig:ABS +ALIAS <&alias> = <&orig> +ENDM + +DEFINE_ALIAS ??3@YAXPEAX@Z, operator_delete +DEFINE_ALIAS ??_U@YAPEAX_K@Z, operator_new +DEFINE_ALIAS ??_U@YAPEAX_KHPEBDH@Z, operator_new_dbg +DEFINE_ALIAS ??_V@YAXPEAX@Z, operator_delete +DEFINE_ALIAS ??2@YAPEAX_K@Z, operator_new +DEFINE_ALIAS ??2@YAPEAX_KHPEBDH@Z, operator_new_dbg +DEFINE_ALIAS ?_query_new_handler@@YAP6AHI@ZXZ, _query_new_handler +DEFINE_ALIAS ?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z, _set_new_handler +DEFINE_ALIAS ?set_new_handler@@YAP6AXXZP6AXXZ@Z, set_new_handler +DEFINE_ALIAS ?_query_new_mode@@YAHXZ, _query_new_mode +DEFINE_ALIAS ?_set_new_mode@@YAHH@Z, _set_new_mode +DEFINE_ALIAS ?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z, _set_se_translator +DEFINE_ALIAS ?set_terminate@@YAP6AXXZP6AXXZ@Z, set_terminate +DEFINE_ALIAS ?set_unexpected@@YAP6AXXZP6AXXZ@Z, set_unexpected +DEFINE_ALIAS ?terminate@@YAXXZ, terminate +DEFINE_ALIAS ?unexpected@@YAXXZ, unexpected +DEFINE_ALIAS ?what@exception@@UEBAPEBDXZ, exception_what +DEFINE_ALIAS ??0exception@@QEAA@AEBQEBDH@Z, exception_ctor_noalloc +DEFINE_ALIAS ??0exception@@QEAA@AEBV0@@Z, exception_copy_ctor +DEFINE_ALIAS ??0exception@@QEAA@XZ, exception_default_ctor +DEFINE_ALIAS ??1exception@@UEAA@XZ, exception_dtor +DEFINE_ALIAS ??4exception@@QEAAAEAV0@AEBV0@@Z, exception_opequals +DEFINE_ALIAS ??1type_info@@UEAA@XZ, type_info_dtor +DEFINE_ALIAS ??0__non_rtti_object@@QEAA@AEBV0@@Z, __non_rtti_object_copy_ctor +DEFINE_ALIAS ??0__non_rtti_object@@QEAA@PEBD@Z, __non_rtti_object_ctor +DEFINE_ALIAS ??0bad_cast@@AAE@PBQBD@Z, bad_cast_ctor +DEFINE_ALIAS ??0bad_cast@@AEAA@PEBQEBD@Z, bad_cast_ctor +DEFINE_ALIAS ??0bad_cast@@QAE@ABQBD@Z, bad_cast_ctor +DEFINE_ALIAS ??0bad_cast@@QEAA@AEBQEBD@Z, bad_cast_ctor +DEFINE_ALIAS ??0bad_cast@@QEAA@AEBV0@@Z, bad_cast_copy_ctor +DEFINE_ALIAS ??0bad_cast@@QEAA@PEBD@Z, bad_cast_ctor_charptr +DEFINE_ALIAS ??0bad_typeid@@QEAA@AEBV0@@Z, bad_typeid_copy_ctor +DEFINE_ALIAS ??0bad_typeid@@QEAA@PEBD@Z, bad_typeid_ctor +DEFINE_ALIAS ??0exception@@QEAA@AEBQEBD@Z, exception_ctor +DEFINE_ALIAS ??1__non_rtti_object@@UEAA@XZ, __non_rtti_object_dtor +DEFINE_ALIAS ??1bad_cast@@UEAA@XZ, bad_cast_dtor +DEFINE_ALIAS ??1bad_typeid@@UEAA@XZ, bad_typeid_dtor +DEFINE_ALIAS ??4bad_cast@@QEAAAEAV0@AEBV0@@Z, bad_cast_opequals +DEFINE_ALIAS ??4bad_typeid@@QEAAAEAV0@AEBV0@@Z, bad_typeid_opequals +DEFINE_ALIAS ??8type_info@@QEBAHAEBV0@@Z, type_info_opequals_equals +DEFINE_ALIAS ??9type_info@@QEBAHAEBV0@@Z, type_info_opnot_equals +DEFINE_ALIAS ??_Fbad_cast@@QEAAXXZ, bad_cast_default_ctor +DEFINE_ALIAS ??_Fbad_typeid@@QEAAXXZ, bad_typeid_default_ctor +DEFINE_ALIAS ?_query_new_handler@@YAP6AH_K@ZXZ, _query_new_handler +DEFINE_ALIAS ?_set_new_handler@@YAP6AH_K@ZP6AH0@Z@Z, _set_new_handler +DEFINE_ALIAS ?_set_se_translator@@YAP6AXIPEAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z, _set_se_translator +DEFINE_ALIAS ?before@type_info@@QEBAHAEBV1@@Z, type_info_before +DEFINE_ALIAS ?name@type_info@@QEBAPEBDXZ, type_info_name +DEFINE_ALIAS ?raw_name@type_info@@QEBAPEBDXZ, type_info_raw_name +DEFINE_ALIAS ??4__non_rtti_object@@QEAAAEAV0@AEBV0@@Z, __non_rtti_object_opequals + +END diff --git a/sdk/lib/crt/except/arm/cpp.s b/sdk/lib/crt/except/arm/cpp.s index 5a45e587189fc..ddc1498896b0f 100644 --- a/sdk/lib/crt/except/arm/cpp.s +++ b/sdk/lib/crt/except/arm/cpp.s @@ -13,58 +13,6 @@ TEXTAREA - MACRO - DEFINE_ALIAS $FuncName, $Target - LCLS _FuncName - LCLS _Target -_FuncName SETS "|$FuncName|" -_Target SETS "|$Target|" - IMPORT $_FuncName, WEAK $_Target - MEND - - DEFINE_ALIAS ??0__non_rtti_object@@QAA@ABV0@@Z, __non_rtti_object_copy_ctor - DEFINE_ALIAS ??0__non_rtti_object@@QAA@PBD@Z, __non_rtti_object_ctor - DEFINE_ALIAS ??0bad_cast@@AAA@PBQBD@Z, bad_cast_ctor // private: __cdecl bad_cast::bad_cast(char const * const *) - DEFINE_ALIAS ??0bad_cast@@QAA@ABV0@@Z, bad_cast_copy_ctor // public: __cdecl bad_cast::bad_cast(class bad_cast const &) - DEFINE_ALIAS ??0bad_cast@@QAA@PBD@Z, bad_cast_ctor // public: __cdecl bad_cast::bad_cast(char const *) - DEFINE_ALIAS ??0bad_typeid@@QAA@ABV0@@Z, bad_typeid_copy_ctor // public: __cdecl bad_typeid::bad_typeid(class bad_typeid const &) - DEFINE_ALIAS ??0bad_typeid@@QAA@PBD@Z, bad_typeid_ctor // public: __cdecl bad_typeid::bad_typeid(char const *) - DEFINE_ALIAS ??0exception@@QAA@ABQBD@Z, exception_ctor // public: __cdecl exception::exception(char const * const &) - DEFINE_ALIAS ??0exception@@QAA@ABQBDH@Z, exception_ctor_noalloc // public: __cdecl exception::exception(char const * const &,int) - DEFINE_ALIAS ??0exception@@QAA@ABV0@@Z, exception_copy_ctor // public: __cdecl exception::exception(class exception const &) - DEFINE_ALIAS ??0exception@@QAA@XZ, exception_default_ctor // public: __cdecl exception::exception(void) - DEFINE_ALIAS ??1__non_rtti_object@@UAA@XZ, __non_rtti_object_dtor // public: virtual __cdecl __non_rtti_object::~__non_rtti_object(void) - DEFINE_ALIAS ??1bad_cast@@UAA@XZ, bad_cast_dtor // public: virtual __cdecl bad_cast::~bad_cast(void) - DEFINE_ALIAS ??1bad_typeid@@UAA@XZ, bad_typeid_dtor // public: virtual __cdecl bad_typeid::~bad_typeid(void) - DEFINE_ALIAS ??1exception@@UAA@XZ, exception_dtor // public: virtual __cdecl exception::~exception(void) - DEFINE_ALIAS ??1type_info@@UAA@XZ, type_info_dtor // public: virtual __cdecl type_info::~type_info(void) - DEFINE_ALIAS ??2@YAPAXI@Z, operator_new // void * __cdecl operator new(unsigned int) - DEFINE_ALIAS ??2@YAPAXIHPBDH@Z, operator_new_dbg // void * __cdecl operator new(unsigned int,int,char const *,int) - DEFINE_ALIAS ??3@YAXPAX@Z, operator_delete // void __cdecl operator delete(void *) - DEFINE_ALIAS ??4__non_rtti_object@@QAAAAV0@ABV0@@Z, __non_rtti_object_opequals // public: class __non_rtti_object & __cdecl __non_rtti_object::operator=(class __non_rtti_object const &) - DEFINE_ALIAS ??4bad_cast@@QAAAAV0@ABV0@@Z, bad_cast_opequals // public: class bad_cast & __cdecl bad_cast::operator=(class bad_cast const &) - DEFINE_ALIAS ??4bad_typeid@@QAAAAV0@ABV0@@Z, bad_typeid_opequals // public: class bad_typeid & __cdecl bad_typeid::operator=(class bad_typeid const &) - DEFINE_ALIAS ??4exception@@QAAAAV0@ABV0@@Z, exception_opequals // public: class exception & __cdecl exception::operator=(class exception const &) - DEFINE_ALIAS ??8type_info@@QBAHABV0@@Z, type_info_opequals_equals // public: int __cdecl type_info::operator==(class type_info const &)const - DEFINE_ALIAS ??9type_info@@QBAHABV0@@Z, type_info_opnot_equals // public: int __cdecl type_info::operator!=(class type_info const &)const - DEFINE_ALIAS ??_Fbad_cast@@QAAXXZ, bad_cast_default_ctor // public: void __cdecl bad_cast::`default constructor closure'(void) - DEFINE_ALIAS ??_Fbad_typeid@@QAAXXZ, bad_typeid_default_ctor // public: void __cdecl bad_typeid::`default constructor closure'(void) - DEFINE_ALIAS ??_U@YAPAXI@Z, operator_new // void * __cdecl operator new[](unsigned int) - DEFINE_ALIAS ??_U@YAPAXIHPBDH@Z, operator_new_dbg // void * __cdecl operator new[](unsigned int,int,char const *,int) - DEFINE_ALIAS ??_V@YAXPAX@Z, operator_delete // void __cdecl operator delete[](void *) - DEFINE_ALIAS ?_query_new_handler@@YAP6AHI@ZXZ, _query_new_handler // int (__cdecl*__cdecl _query_new_handler(void))(unsigned int) - DEFINE_ALIAS ?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z, _set_new_handler // int (__cdecl*__cdecl _set_new_handler(int (__cdecl*)(unsigned int)))(unsigned int) - DEFINE_ALIAS ?_set_new_mode@@YAHH@Z, _set_new_mode // int __cdecl _set_new_mode(int) - DEFINE_ALIAS ?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z, _set_se_translator // void (__cdecl*__cdecl _set_se_translator(void (__cdecl*)(unsigned int,struct _EXCEPTION_POINTERS *)))(unsigned int,struct _EXCEPTION_POINTERS *) - DEFINE_ALIAS ?before@type_info@@QBAHABV1@@Z, type_info_before // public: int __cdecl type_info::before(class type_info const &)const - DEFINE_ALIAS ?name@type_info@@QBAPBDXZ, type_info_name // public: char const * __cdecl type_info::name(void)const - DEFINE_ALIAS ?raw_name@type_info@@QBAPBDXZ, type_info_raw_name // public: char const * __cdecl type_info::raw_name(void)const - DEFINE_ALIAS ?set_terminate@@YAP6AXXZP6AXXZ@Z, set_terminate // void (__cdecl*__cdecl set_terminate(void (__cdecl*)(void)))(void) - DEFINE_ALIAS ?set_unexpected@@YAP6AXXZP6AXXZ@Z, set_unexpected // void (__cdecl*__cdecl set_unexpected(void (__cdecl*)(void)))(void) - DEFINE_ALIAS ?terminate@@YAXXZ, terminate // void __cdecl terminate(void) - DEFINE_ALIAS ?unexpected@@YAXXZ, unexpected // void __cdecl unexpected(void) - DEFINE_ALIAS ?what@exception@@UBAPBDXZ, exception_what // public: virtual char const * __cdecl exception::what(void)const - #undef _MSVCRT_ MACRO START_VTABLE $ShortName, $CxxName diff --git a/sdk/lib/crt/except/arm/cpp_alias.s b/sdk/lib/crt/except/arm/cpp_alias.s new file mode 100644 index 0000000000000..7b6ae45683eee --- /dev/null +++ b/sdk/lib/crt/except/arm/cpp_alias.s @@ -0,0 +1,69 @@ +/* + * COPYRIGHT: BSD - See COPYING.ARM in the top level directory + * PROJECT: ReactOS CRT library + * PURPOSE: MSVC wrappers for C++ functions + * PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include + +/* CODE **********************************************************************/ + + TEXTAREA + + MACRO + DEFINE_ALIAS $FuncName, $Target + LCLS _FuncName + LCLS _Target +_FuncName SETS "|$FuncName|" +_Target SETS "|$Target|" + IMPORT $_FuncName, WEAK $_Target + MEND + + DEFINE_ALIAS ??0__non_rtti_object@@QAA@ABV0@@Z, __non_rtti_object_copy_ctor + DEFINE_ALIAS ??0__non_rtti_object@@QAA@PBD@Z, __non_rtti_object_ctor + DEFINE_ALIAS ??0bad_cast@@AAA@PBQBD@Z, bad_cast_ctor // private: __cdecl bad_cast::bad_cast(char const * const *) + DEFINE_ALIAS ??0bad_cast@@QAA@ABV0@@Z, bad_cast_copy_ctor // public: __cdecl bad_cast::bad_cast(class bad_cast const &) + DEFINE_ALIAS ??0bad_cast@@QAA@PBD@Z, bad_cast_ctor // public: __cdecl bad_cast::bad_cast(char const *) + DEFINE_ALIAS ??0bad_typeid@@QAA@ABV0@@Z, bad_typeid_copy_ctor // public: __cdecl bad_typeid::bad_typeid(class bad_typeid const &) + DEFINE_ALIAS ??0bad_typeid@@QAA@PBD@Z, bad_typeid_ctor // public: __cdecl bad_typeid::bad_typeid(char const *) + DEFINE_ALIAS ??0exception@@QAA@ABQBD@Z, exception_ctor // public: __cdecl exception::exception(char const * const &) + DEFINE_ALIAS ??0exception@@QAA@ABQBDH@Z, exception_ctor_noalloc // public: __cdecl exception::exception(char const * const &,int) + DEFINE_ALIAS ??0exception@@QAA@ABV0@@Z, exception_copy_ctor // public: __cdecl exception::exception(class exception const &) + DEFINE_ALIAS ??0exception@@QAA@XZ, exception_default_ctor // public: __cdecl exception::exception(void) + DEFINE_ALIAS ??1__non_rtti_object@@UAA@XZ, __non_rtti_object_dtor // public: virtual __cdecl __non_rtti_object::~__non_rtti_object(void) + DEFINE_ALIAS ??1bad_cast@@UAA@XZ, bad_cast_dtor // public: virtual __cdecl bad_cast::~bad_cast(void) + DEFINE_ALIAS ??1bad_typeid@@UAA@XZ, bad_typeid_dtor // public: virtual __cdecl bad_typeid::~bad_typeid(void) + DEFINE_ALIAS ??1exception@@UAA@XZ, exception_dtor // public: virtual __cdecl exception::~exception(void) + DEFINE_ALIAS ??1type_info@@UAA@XZ, type_info_dtor // public: virtual __cdecl type_info::~type_info(void) + DEFINE_ALIAS ??2@YAPAXI@Z, operator_new // void * __cdecl operator new(unsigned int) + DEFINE_ALIAS ??2@YAPAXIHPBDH@Z, operator_new_dbg // void * __cdecl operator new(unsigned int,int,char const *,int) + DEFINE_ALIAS ??3@YAXPAX@Z, operator_delete // void __cdecl operator delete(void *) + DEFINE_ALIAS ??4__non_rtti_object@@QAAAAV0@ABV0@@Z, __non_rtti_object_opequals // public: class __non_rtti_object & __cdecl __non_rtti_object::operator=(class __non_rtti_object const &) + DEFINE_ALIAS ??4bad_cast@@QAAAAV0@ABV0@@Z, bad_cast_opequals // public: class bad_cast & __cdecl bad_cast::operator=(class bad_cast const &) + DEFINE_ALIAS ??4bad_typeid@@QAAAAV0@ABV0@@Z, bad_typeid_opequals // public: class bad_typeid & __cdecl bad_typeid::operator=(class bad_typeid const &) + DEFINE_ALIAS ??4exception@@QAAAAV0@ABV0@@Z, exception_opequals // public: class exception & __cdecl exception::operator=(class exception const &) + DEFINE_ALIAS ??8type_info@@QBAHABV0@@Z, type_info_opequals_equals // public: int __cdecl type_info::operator==(class type_info const &)const + DEFINE_ALIAS ??9type_info@@QBAHABV0@@Z, type_info_opnot_equals // public: int __cdecl type_info::operator!=(class type_info const &)const + DEFINE_ALIAS ??_Fbad_cast@@QAAXXZ, bad_cast_default_ctor // public: void __cdecl bad_cast::`default constructor closure'(void) + DEFINE_ALIAS ??_Fbad_typeid@@QAAXXZ, bad_typeid_default_ctor // public: void __cdecl bad_typeid::`default constructor closure'(void) + DEFINE_ALIAS ??_U@YAPAXI@Z, operator_new // void * __cdecl operator new[](unsigned int) + DEFINE_ALIAS ??_U@YAPAXIHPBDH@Z, operator_new_dbg // void * __cdecl operator new[](unsigned int,int,char const *,int) + DEFINE_ALIAS ??_V@YAXPAX@Z, operator_delete // void __cdecl operator delete[](void *) + DEFINE_ALIAS ?_query_new_handler@@YAP6AHI@ZXZ, _query_new_handler // int (__cdecl*__cdecl _query_new_handler(void))(unsigned int) + DEFINE_ALIAS ?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z, _set_new_handler // int (__cdecl*__cdecl _set_new_handler(int (__cdecl*)(unsigned int)))(unsigned int) + DEFINE_ALIAS ?_set_new_mode@@YAHH@Z, _set_new_mode // int __cdecl _set_new_mode(int) + DEFINE_ALIAS ?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z, _set_se_translator // void (__cdecl*__cdecl _set_se_translator(void (__cdecl*)(unsigned int,struct _EXCEPTION_POINTERS *)))(unsigned int,struct _EXCEPTION_POINTERS *) + DEFINE_ALIAS ?before@type_info@@QBAHABV1@@Z, type_info_before // public: int __cdecl type_info::before(class type_info const &)const + DEFINE_ALIAS ?name@type_info@@QBAPBDXZ, type_info_name // public: char const * __cdecl type_info::name(void)const + DEFINE_ALIAS ?raw_name@type_info@@QBAPBDXZ, type_info_raw_name // public: char const * __cdecl type_info::raw_name(void)const + DEFINE_ALIAS ?set_terminate@@YAP6AXXZP6AXXZ@Z, set_terminate // void (__cdecl*__cdecl set_terminate(void (__cdecl*)(void)))(void) + DEFINE_ALIAS ?set_unexpected@@YAP6AXXZP6AXXZ@Z, set_unexpected // void (__cdecl*__cdecl set_unexpected(void (__cdecl*)(void)))(void) + DEFINE_ALIAS ?terminate@@YAXXZ, terminate // void __cdecl terminate(void) + DEFINE_ALIAS ?unexpected@@YAXXZ, unexpected // void __cdecl unexpected(void) + DEFINE_ALIAS ?what@exception@@UBAPBDXZ, exception_what // public: virtual char const * __cdecl exception::what(void)const + + END +/* EOF */ diff --git a/sdk/lib/crt/except/except.cmake b/sdk/lib/crt/except/except.cmake index 656853c097cb9..add149de4ec40 100644 --- a/sdk/lib/crt/except/except.cmake +++ b/sdk/lib/crt/except/except.cmake @@ -13,7 +13,8 @@ if(ARCH STREQUAL "i386") ) if(MSVC) list(APPEND CRT_EXCEPT_ASM_SOURCE - except/i386/cpp.s) + except/i386/cpp.s + except/i386/cpp_alias.s) endif() elseif(ARCH STREQUAL "amd64") list(APPEND LIBCNTPR_EXCEPT_SOURCE @@ -28,7 +29,8 @@ elseif(ARCH STREQUAL "amd64") ) if(MSVC) list(APPEND CRT_EXCEPT_ASM_SOURCE - except/amd64/cpp.s) + except/amd64/cpp.s + except/amd64/cpp_alias.s) endif() elseif(ARCH STREQUAL "arm") list(APPEND LIBCNTPR_EXCEPT_SOURCE @@ -53,7 +55,8 @@ elseif(ARCH STREQUAL "arm") ) if(MSVC) list(APPEND CRT_EXCEPT_ASM_SOURCE - except/arm/cpp.s) + except/arm/cpp.s + except/arm/cpp_alias.s) endif() endif() diff --git a/sdk/lib/crt/except/i386/cpp.s b/sdk/lib/crt/except/i386/cpp.s index 99e2748edd6ef..7c524938dd4c1 100644 --- a/sdk/lib/crt/except/i386/cpp.s +++ b/sdk/lib/crt/except/i386/cpp.s @@ -7,55 +7,6 @@ EXTERN _cxx_frame_handler:PROC -MACRO(DEFINE_THISCALL_ALIAS, cxxname, target) -#ifdef _USE_ML - EXTERN ___thiscall&target:PROC - ALIAS <&cxxname> = <___thiscall&target> -#else - PUBLIC cxxname - .weakref &cxxname, &target -#endif -ENDM - -DEFINE_THISCALL_ALIAS ??0exception@@QAE@ABQBD@Z, _exception_ctor -DEFINE_THISCALL_ALIAS ??0exception@@QAE@ABQBDH@Z, _exception_ctor_noalloc -DEFINE_THISCALL_ALIAS ??0exception@@QAE@ABV0@@Z, _exception_copy_ctor -DEFINE_THISCALL_ALIAS ??0exception@@QAE@XZ, _exception_default_ctor -DEFINE_THISCALL_ALIAS ??1exception@@UAE@XZ, _exception_dtor -DEFINE_THISCALL_ALIAS ??4exception@@QAEAAV0@ABV0@@Z, _exception_opequals -DEFINE_THISCALL_ALIAS ??_Eexception@@UAEPAXI@Z, _exception_vector_dtor -DEFINE_THISCALL_ALIAS ??_Gexception@@UAEPAXI@Z, _exception_scalar_dtor -DEFINE_THISCALL_ALIAS ?what@exception@@UBEPBDXZ, _exception_what -DEFINE_THISCALL_ALIAS ??0bad_typeid@@QAE@ABV0@@Z, _bad_typeid_copy_ctor -DEFINE_THISCALL_ALIAS ??0bad_typeid@@QAE@PBD@Z, _bad_typeid_ctor -DEFINE_THISCALL_ALIAS ??_Fbad_typeid@@QAEXXZ, _bad_typeid_default_ctor -DEFINE_THISCALL_ALIAS ??1bad_typeid@@UAE@XZ, _bad_typeid_dtor -DEFINE_THISCALL_ALIAS ??4bad_typeid@@QAEAAV0@ABV0@@Z, _bad_typeid_opequals -DEFINE_THISCALL_ALIAS ??_Ebad_typeid@@UAEPAXI@Z, _bad_typeid_vector_dtor -DEFINE_THISCALL_ALIAS ??_Gbad_typeid@@UAEPAXI@Z, _bad_typeid_scalar_dtor -DEFINE_THISCALL_ALIAS ??0__non_rtti_object@@QAE@ABV0@@Z, ___non_rtti_object_copy_ctor -DEFINE_THISCALL_ALIAS ??0__non_rtti_object@@QAE@PBD@Z, ___non_rtti_object_ctor -DEFINE_THISCALL_ALIAS ??1__non_rtti_object@@UAE@XZ, ___non_rtti_object_dtor -DEFINE_THISCALL_ALIAS ??4__non_rtti_object@@QAEAAV0@ABV0@@Z, ___non_rtti_object_opequals -DEFINE_THISCALL_ALIAS ??_E__non_rtti_object@@UAEPAXI@Z, ___non_rtti_object_vector_dtor -DEFINE_THISCALL_ALIAS ??_G__non_rtti_object@@UAEPAXI@Z, ___non_rtti_object_scalar_dtor -DEFINE_THISCALL_ALIAS ??0bad_cast@@AAE@PBQBD@Z, _bad_cast_ctor -DEFINE_THISCALL_ALIAS ??0bad_cast@@QAE@ABQBD@Z, _bad_cast_ctor -DEFINE_THISCALL_ALIAS ??0bad_cast@@QAE@ABV0@@Z, _bad_cast_copy_ctor -DEFINE_THISCALL_ALIAS ??0bad_cast@@QAE@PBD@Z, _bad_cast_ctor_charptr -DEFINE_THISCALL_ALIAS ??_Fbad_cast@@QAEXXZ, _bad_cast_default_ctor -DEFINE_THISCALL_ALIAS ??1bad_cast@@UAE@XZ, _bad_cast_dtor -DEFINE_THISCALL_ALIAS ??4bad_cast@@QAEAAV0@ABV0@@Z, _bad_cast_opequals -DEFINE_THISCALL_ALIAS ??_Ebad_cast@@UAEPAXI@Z, _bad_cast_vector_dtor -DEFINE_THISCALL_ALIAS ??_Gbad_cast@@UAEPAXI@Z, _bad_cast_scalar_dtor -DEFINE_THISCALL_ALIAS ??8type_info@@QBEHABV0@@Z, _type_info_opequals_equals -DEFINE_THISCALL_ALIAS ??9type_info@@QBEHABV0@@Z, _type_info_opnot_equals -DEFINE_THISCALL_ALIAS ?before@type_info@@QBEHABV1@@Z, _type_info_before -DEFINE_THISCALL_ALIAS ??1type_info@@UAE@XZ, _type_info_dtor -DEFINE_THISCALL_ALIAS ?name@type_info@@QBEPBDXZ, _type_info_name -DEFINE_THISCALL_ALIAS ?raw_name@type_info@@QBEPBDXZ, _type_info_raw_name - - #undef _MSVCRT_ MACRO(START_VTABLE, shortname, cxxname) EXTERN _&shortname&_rtti:PROC @@ -80,36 +31,6 @@ DEFINE_EXCEPTION_VTABLE bad_typeid, ??_7bad_typeid@@6B@ DEFINE_EXCEPTION_VTABLE bad_cast, ??_7bad_cast@@6B@ DEFINE_EXCEPTION_VTABLE __non_rtti_object, ??_7__non_rtti_object@@6B@ -EXTERN _operator_delete:PROC -PUBLIC ??3@YAXPAX@Z -??3@YAXPAX@Z: - jmp _operator_delete - -EXTERN _operator_new:PROC -PUBLIC ??_U@YAPAXI@Z -??_U@YAPAXI@Z: - jmp _operator_new - - -MACRO(DEFINE_ALIAS, alias, orig, type) -EXTERN &orig:&type -ALIAS <&alias> = <&orig> -ENDM - -DEFINE_ALIAS ??_V@YAXPAX@Z, _operator_delete, PROC -DEFINE_ALIAS ??2@YAPAXI@Z, _operator_new, PROC -DEFINE_ALIAS ?_query_new_handler@@YAP6AHI@ZXZ, __query_new_handler, PROC -DEFINE_ALIAS ?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z, __set_new_handler, PROC -DEFINE_ALIAS ?set_new_handler@@YAP6AXXZP6AXXZ@Z, _set_new_handler, PROC -DEFINE_ALIAS ?_query_new_mode@@YAHXZ, __query_new_mode, PROC -DEFINE_ALIAS ?_set_new_mode@@YAHH@Z, __set_new_mode, PROC -DEFINE_ALIAS ?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z, __set_se_translator, PROC -DEFINE_ALIAS ?set_terminate@@YAP6AXXZP6AXXZ@Z, _set_terminate, PROC -DEFINE_ALIAS ?set_unexpected@@YAP6AXXZP6AXXZ@Z, _set_unexpected, PROC -DEFINE_ALIAS ?terminate@@YAXXZ, _terminate, PROC -DEFINE_ALIAS ?unexpected@@YAXXZ, _unexpected, PROC - - // void call_copy_ctor( void *func, void *this, void *src, int has_vbase ); PUBLIC _call_copy_ctor _call_copy_ctor: diff --git a/sdk/lib/crt/except/i386/cpp_alias.s b/sdk/lib/crt/except/i386/cpp_alias.s new file mode 100644 index 0000000000000..384a3ed0f5291 --- /dev/null +++ b/sdk/lib/crt/except/i386/cpp_alias.s @@ -0,0 +1,85 @@ + + +#include + +.code +.align 4 + +MACRO(DEFINE_THISCALL_ALIAS, cxxname, target) +#ifdef _USE_ML + EXTERN ___thiscall&target:PROC + ALIAS <&cxxname> = <___thiscall&target> +#else + PUBLIC cxxname + .weakref &cxxname, &target +#endif +ENDM + +DEFINE_THISCALL_ALIAS ??0exception@@QAE@ABQBD@Z, _exception_ctor +DEFINE_THISCALL_ALIAS ??0exception@@QAE@ABQBDH@Z, _exception_ctor_noalloc +DEFINE_THISCALL_ALIAS ??0exception@@QAE@ABV0@@Z, _exception_copy_ctor +DEFINE_THISCALL_ALIAS ??0exception@@QAE@XZ, _exception_default_ctor +DEFINE_THISCALL_ALIAS ??1exception@@UAE@XZ, _exception_dtor +DEFINE_THISCALL_ALIAS ??4exception@@QAEAAV0@ABV0@@Z, _exception_opequals +DEFINE_THISCALL_ALIAS ??_Eexception@@UAEPAXI@Z, _exception_vector_dtor +DEFINE_THISCALL_ALIAS ??_Gexception@@UAEPAXI@Z, _exception_scalar_dtor +DEFINE_THISCALL_ALIAS ?what@exception@@UBEPBDXZ, _exception_what +DEFINE_THISCALL_ALIAS ??0bad_typeid@@QAE@ABV0@@Z, _bad_typeid_copy_ctor +DEFINE_THISCALL_ALIAS ??0bad_typeid@@QAE@PBD@Z, _bad_typeid_ctor +DEFINE_THISCALL_ALIAS ??_Fbad_typeid@@QAEXXZ, _bad_typeid_default_ctor +DEFINE_THISCALL_ALIAS ??1bad_typeid@@UAE@XZ, _bad_typeid_dtor +DEFINE_THISCALL_ALIAS ??4bad_typeid@@QAEAAV0@ABV0@@Z, _bad_typeid_opequals +DEFINE_THISCALL_ALIAS ??_Ebad_typeid@@UAEPAXI@Z, _bad_typeid_vector_dtor +DEFINE_THISCALL_ALIAS ??_Gbad_typeid@@UAEPAXI@Z, _bad_typeid_scalar_dtor +DEFINE_THISCALL_ALIAS ??0__non_rtti_object@@QAE@ABV0@@Z, ___non_rtti_object_copy_ctor +DEFINE_THISCALL_ALIAS ??0__non_rtti_object@@QAE@PBD@Z, ___non_rtti_object_ctor +DEFINE_THISCALL_ALIAS ??1__non_rtti_object@@UAE@XZ, ___non_rtti_object_dtor +DEFINE_THISCALL_ALIAS ??4__non_rtti_object@@QAEAAV0@ABV0@@Z, ___non_rtti_object_opequals +DEFINE_THISCALL_ALIAS ??_E__non_rtti_object@@UAEPAXI@Z, ___non_rtti_object_vector_dtor +DEFINE_THISCALL_ALIAS ??_G__non_rtti_object@@UAEPAXI@Z, ___non_rtti_object_scalar_dtor +DEFINE_THISCALL_ALIAS ??0bad_cast@@AAE@PBQBD@Z, _bad_cast_ctor +DEFINE_THISCALL_ALIAS ??0bad_cast@@QAE@ABQBD@Z, _bad_cast_ctor +DEFINE_THISCALL_ALIAS ??0bad_cast@@QAE@ABV0@@Z, _bad_cast_copy_ctor +DEFINE_THISCALL_ALIAS ??0bad_cast@@QAE@PBD@Z, _bad_cast_ctor_charptr +DEFINE_THISCALL_ALIAS ??_Fbad_cast@@QAEXXZ, _bad_cast_default_ctor +DEFINE_THISCALL_ALIAS ??1bad_cast@@UAE@XZ, _bad_cast_dtor +DEFINE_THISCALL_ALIAS ??4bad_cast@@QAEAAV0@ABV0@@Z, _bad_cast_opequals +DEFINE_THISCALL_ALIAS ??_Ebad_cast@@UAEPAXI@Z, _bad_cast_vector_dtor +DEFINE_THISCALL_ALIAS ??_Gbad_cast@@UAEPAXI@Z, _bad_cast_scalar_dtor +DEFINE_THISCALL_ALIAS ??8type_info@@QBEHABV0@@Z, _type_info_opequals_equals +DEFINE_THISCALL_ALIAS ??9type_info@@QBEHABV0@@Z, _type_info_opnot_equals +DEFINE_THISCALL_ALIAS ?before@type_info@@QBEHABV1@@Z, _type_info_before +DEFINE_THISCALL_ALIAS ??1type_info@@UAE@XZ, _type_info_dtor +DEFINE_THISCALL_ALIAS ?name@type_info@@QBEPBDXZ, _type_info_name +DEFINE_THISCALL_ALIAS ?raw_name@type_info@@QBEPBDXZ, _type_info_raw_name + +EXTERN _operator_delete:PROC +PUBLIC ??3@YAXPAX@Z +??3@YAXPAX@Z: + jmp _operator_delete + +EXTERN _operator_new:PROC +PUBLIC ??_U@YAPAXI@Z +??_U@YAPAXI@Z: + jmp _operator_new + +MACRO(DEFINE_ALIAS, alias, orig, type) +EXTERN &orig:&type +ALIAS <&alias> = <&orig> +ENDM + +DEFINE_ALIAS ??_V@YAXPAX@Z, _operator_delete, PROC +DEFINE_ALIAS ??2@YAPAXI@Z, _operator_new, PROC +DEFINE_ALIAS ?_query_new_handler@@YAP6AHI@ZXZ, __query_new_handler, PROC +DEFINE_ALIAS ?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z, __set_new_handler, PROC +DEFINE_ALIAS ?set_new_handler@@YAP6AXXZP6AXXZ@Z, _set_new_handler, PROC +DEFINE_ALIAS ?_query_new_mode@@YAHXZ, __query_new_mode, PROC +DEFINE_ALIAS ?_set_new_mode@@YAHH@Z, __set_new_mode, PROC +DEFINE_ALIAS ?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z, __set_se_translator, PROC +DEFINE_ALIAS ?set_terminate@@YAP6AXXZP6AXXZ@Z, _set_terminate, PROC +DEFINE_ALIAS ?set_unexpected@@YAP6AXXZP6AXXZ@Z, _set_unexpected, PROC +DEFINE_ALIAS ?terminate@@YAXXZ, _terminate, PROC +DEFINE_ALIAS ?unexpected@@YAXXZ, _unexpected, PROC + +END + diff --git a/sdk/lib/crt/math/libm_sse2/exp2.c b/sdk/lib/crt/math/libm_sse2/exp2.c index 470be6f4bf874..a5998791c9cea 100644 --- a/sdk/lib/crt/math/libm_sse2/exp2.c +++ b/sdk/lib/crt/math/libm_sse2/exp2.c @@ -44,9 +44,7 @@ THE SOFTWARE. #include "libm_errno.h" -/* exp2 is only provided for use by powf under Windows, so give - it a leading underscore. */ -double FN_PROTOTYPE(_exp2)(double x) +double FN_PROTOTYPE(exp2)(double x) { static const double max_exp2_arg = 1024.0, /* 0x4090000000000000 */ diff --git a/sdk/lib/crt/math/math.cmake b/sdk/lib/crt/math/math.cmake index 3a6c69995b558..e46243f184112 100644 --- a/sdk/lib/crt/math/math.cmake +++ b/sdk/lib/crt/math/math.cmake @@ -2,9 +2,11 @@ include_directories(libm_sse2) list(APPEND LIBCNTPR_MATH_SOURCE + math/_chgsignf.c math/_invoke_matherr.c math/abs.c math/div.c + math/exp2f.c math/labs.c math/sincos.c ) @@ -55,6 +57,9 @@ if(ARCH STREQUAL "i386") math/i386/fmod_asm.s math/i386/fmodf_asm.s ) + list(APPEND CRT_MATH_SOURCE + math/_hypotf.c + ) elseif(ARCH STREQUAL "amd64") list(APPEND LIBCNTPR_MATH_SOURCE math/amd64/_set_statfp.c @@ -204,7 +209,6 @@ endif() if(NOT ARCH STREQUAL "i386") list(APPEND CRT_MATH_SOURCE - math/_chgsignf.c math/_copysignf.c math/log10f.c math/stubs.c @@ -217,6 +221,7 @@ if(NOT ARCH STREQUAL "amd64") math/asin.c math/cosh.c math/cosf.c + math/exp2.c math/hypot.c math/modf.c math/s_modf.c diff --git a/sdk/lib/crt/misc/getargs.c b/sdk/lib/crt/misc/getargs.c index da2a2b16907fe..e016f77369312 100644 --- a/sdk/lib/crt/misc/getargs.c +++ b/sdk/lib/crt/misc/getargs.c @@ -208,7 +208,7 @@ void __getmainargs(int* argc, char*** argv, char*** env, int expand_wildcards, i len = strlen(_acmdln); buffer = malloc(sizeof(char) * len); - // Reference: https://msdn.microsoft.com/en-us/library/a1y7w461.aspx + // Reference: https://learn.microsoft.com/en-us/cpp/c-language/parsing-c-command-line-arguments?view=msvc-170 while (TRUE) { // Arguments are delimited by white space, which is either a space or a tab. @@ -355,7 +355,7 @@ void __wgetmainargs(int* argc, wchar_t*** wargv, wchar_t*** wenv, len = wcslen(_wcmdln); buffer = malloc(sizeof(wchar_t) * len); - // Reference: https://msdn.microsoft.com/en-us/library/a1y7w461.aspx + // Reference: https://learn.microsoft.com/en-us/cpp/c-language/parsing-c-command-line-arguments?view=msvc-170 while (TRUE) { // Arguments are delimited by white space, which is either a space or a tab. diff --git a/sdk/lib/crt/misc/tls.c b/sdk/lib/crt/misc/tls.c index da5f918d22afa..568bd17be65a9 100644 --- a/sdk/lib/crt/misc/tls.c +++ b/sdk/lib/crt/misc/tls.c @@ -41,8 +41,10 @@ thread_data_t *msvcrt_get_thread_data(void) ptr->tid = GetCurrentThreadId(); ptr->handle = INVALID_HANDLE_VALUE; ptr->random_seed = 1; +#ifndef __UCRTSUPPORT__ ptr->locinfo = MSVCRT_locale->locinfo; ptr->mbcinfo = MSVCRT_locale->mbcinfo; +#endif /* !__UCRTSUPPORT__ */ } SetLastError( err ); return ptr; diff --git a/sdk/lib/crt/oldnames-common.S b/sdk/lib/crt/oldnames-common.S new file mode 100644 index 0000000000000..b4da5d01b5ca5 --- /dev/null +++ b/sdk/lib/crt/oldnames-common.S @@ -0,0 +1,118 @@ + +#include + + /* Do not remove indentation, this would break ARM build! */ + CREATE_ALIAS access, _access + CREATE_ALIAS chdir, _chdir + CREATE_ALIAS chmod, _chmod + CREATE_ALIAS chsize, _chsize + CREATE_ALIAS close, _close + CREATE_ALIAS creat, _creat + CREATE_ALIAS cwait, _cwait + CREATE_ALIAS dup, _dup + CREATE_ALIAS dup2, _dup2 + CREATE_ALIAS ecvt, _ecvt + CREATE_ALIAS eof, _eof + CREATE_ALIAS execl, _execl + CREATE_ALIAS execle, _execle + CREATE_ALIAS execlp, _execlp + CREATE_ALIAS execlpe, _execlpe + CREATE_ALIAS execv, _execv + CREATE_ALIAS execve, _execve + CREATE_ALIAS execvp, _execvp + CREATE_ALIAS execvpe, _execvpe + CREATE_ALIAS fcvt, _fcvt + CREATE_ALIAS fdopen, _fdopen + CREATE_ALIAS fgetchar, _fgetchar + CREATE_ALIAS fgetwchar, _fgetwchar + CREATE_ALIAS filelength, _filelength + CREATE_ALIAS fileno, _fileno + CREATE_ALIAS fpreset, _fpreset + CREATE_ALIAS fputchar, _fputchar + CREATE_ALIAS fputwchar, _fputwchar + CREATE_ALIAS gcvt, _gcvt + CREATE_ALIAS getch, _getch + CREATE_ALIAS getche, _getche + CREATE_ALIAS getcwd, _getcwd + CREATE_ALIAS getpid, _getpid + CREATE_ALIAS getw, _getw + CREATE_ALIAS heapwalk, _heapwalk + CREATE_ALIAS isatty, _isatty + CREATE_ALIAS isascii, __isascii + CREATE_ALIAS itoa, _itoa + CREATE_ALIAS kbhit, _kbhit + CREATE_ALIAS lfind, _lfind + CREATE_ALIAS lsearch, _lsearch + CREATE_ALIAS lseek, _lseek + CREATE_ALIAS ltoa, _ltoa + CREATE_ALIAS memccpy, _memccpy + CREATE_ALIAS memicmp, _memicmp + CREATE_ALIAS mkdir, _mkdir + CREATE_ALIAS mktemp, _mktemp + CREATE_ALIAS open, _open + CREATE_ALIAS pclose, _pclose + CREATE_ALIAS popen, _popen + CREATE_ALIAS putch, _putch + CREATE_ALIAS putenv, _putenv + CREATE_ALIAS putw, _putw + CREATE_ALIAS read, _read + CREATE_ALIAS rmdir, _rmdir + CREATE_ALIAS rmtmp, _rmtmp + CREATE_ALIAS searchenv, _searchenv + CREATE_ALIAS setmode, _setmode + CREATE_ALIAS sopen, _sopen + CREATE_ALIAS spawnl, _spawnl + CREATE_ALIAS spawnle, _spawnle + CREATE_ALIAS spawnlp, _spawnlp + CREATE_ALIAS spawnlpe, _spawnlpe + CREATE_ALIAS spawnv, _spawnv + CREATE_ALIAS spawnve, _spawnve + CREATE_ALIAS spawnvp, _spawnvp + CREATE_ALIAS spawnvpe, _spawnvpe + CREATE_ALIAS strdup, _strdup + CREATE_ALIAS stricmp, _stricmp + CREATE_ALIAS stricoll, _stricoll + CREATE_ALIAS strlwr, _strlwr + CREATE_ALIAS strnicmp, _strnicmp + CREATE_ALIAS strnset, _strnset + CREATE_ALIAS strrev, _strrev + CREATE_ALIAS strset, _strset + CREATE_ALIAS strupr, _strupr + CREATE_ALIAS swab, _swab + CREATE_ALIAS tell, _tell + CREATE_ALIAS tempnam, _tempnam + CREATE_ALIAS tzset, _tzset + CREATE_ALIAS umask, _umask + CREATE_ALIAS ungetch, _ungetch + CREATE_ALIAS unlink, _unlink + CREATE_ALIAS wcsdup, _wcsdup + CREATE_ALIAS wcsicmp, _wcsicmp + CREATE_ALIAS wcsicoll, _wcsicoll + CREATE_ALIAS wcslwr, _wcslwr + CREATE_ALIAS wcsnicmp, _wcsnicmp + CREATE_ALIAS wcsnset, _wcsnset + CREATE_ALIAS wcsrev, _wcsrev + CREATE_ALIAS wcsset, _wcsset + CREATE_ALIAS wcsupr, _wcsupr + CREATE_ALIAS wpopen, _wpopen + CREATE_ALIAS write, _write + // non-ANSI functions declared in math.h + CREATE_ALIAS j0, _j0 + CREATE_ALIAS j1, _j1 + CREATE_ALIAS jn, _jn + CREATE_ALIAS y0, _y0 + CREATE_ALIAS y1, _y1 + CREATE_ALIAS yn, _yn + CREATE_ALIAS chgsign, _chgsign + CREATE_ALIAS scalb, _scalb + CREATE_ALIAS finite, _finite + CREATE_ALIAS fpclass, _fpclass + + // These do not exist as exports in ucrtbase, but as import symbols + CREATE_ALIAS fstat, _fstat + CREATE_ALIAS ftime, _ftime + CREATE_ALIAS stat, _stat + CREATE_ALIAS utime, _utime + + END + diff --git a/sdk/lib/crt/oldnames-msvcrt.S b/sdk/lib/crt/oldnames-msvcrt.S index 58d2f6e949165..dcab39e8493c0 100644 --- a/sdk/lib/crt/oldnames-msvcrt.S +++ b/sdk/lib/crt/oldnames-msvcrt.S @@ -1,182 +1,18 @@ -#ifdef _M_IX86 -#define SYM(name) _##name -#define IMPSYM(name) __imp__##name -#else -#define SYM(name) name -#define IMPSYM(name) __imp_##name -#endif +#include -#if (defined(_M_IX86) || defined(_M_AMD64)) - -#include - -MACRO(CREATE_ALIAS1, alias, target) -#ifdef _USE_ML - EXTERN SYM(&target):PROC - ALIAS = -#else - .weakref SYM(&alias), SYM(&target) -#endif -ENDM - -MACRO(CREATE_ALIAS2, alias, target) -#ifdef _USE_ML - EXTERN IMPSYM(&target):PROC - ALIAS = -#else - .weakref IMPSYM(&alias), IMPSYM(&target) -#endif -ENDM - -MACRO(CREATE_ALIAS, alias, target) - CREATE_ALIAS1 &alias, &target - CREATE_ALIAS2 &alias, &target -ENDM - -#elif defined(_M_ARM) - -#include - - MACRO - CREATE_ALIAS1 $alias, $target - IMPORT SYM($alias), WEAK SYM($target) - MEND - - MACRO - CREATE_ALIAS2 $alias, $target - IMPORT IMPSYM($alias), WEAK IMPSYM($target) - MEND - - MACRO - CREATE_ALIAS $alias, $target - CREATE_ALIAS1 $alias, $target - CREATE_ALIAS2 $alias, $target - MEND -#else -#error "Unsupported platform." -#endif - - /* Do not remove indentation, this would break ARM build! */ - CREATE_ALIAS access, _access - CREATE_ALIAS chdir, _chdir - CREATE_ALIAS chmod, _chmod - CREATE_ALIAS chsize, _chsize - CREATE_ALIAS close, _close - CREATE_ALIAS creat, _creat - CREATE_ALIAS cwait, _cwait + // These exports only exist in msvcrt.dll, not in ucrtbase.dll + // Do not remove indentation, this would break ARM build! CREATE_ALIAS2 daylight, _daylight - CREATE_ALIAS dup, _dup - CREATE_ALIAS dup2, _dup2 - CREATE_ALIAS ecvt, _ecvt - CREATE_ALIAS eof, _eof - CREATE_ALIAS execl, _execl - CREATE_ALIAS execle, _execle - CREATE_ALIAS execlp, _execlp - CREATE_ALIAS execlpe, _execlpe - CREATE_ALIAS execv, _execv - CREATE_ALIAS execve, _execve - CREATE_ALIAS execvp, _execvp - CREATE_ALIAS execvpe, _execvpe - CREATE_ALIAS fcvt, _fcvt - CREATE_ALIAS fdopen, _fdopen - CREATE_ALIAS fgetchar, _fgetchar - CREATE_ALIAS fgetwchar, _fgetwchar - CREATE_ALIAS filelength, _filelength - CREATE_ALIAS fileno, _fileno - CREATE_ALIAS fpreset, _fpreset - CREATE_ALIAS fputchar, _fputchar - CREATE_ALIAS fputwchar, _fputwchar - CREATE_ALIAS fstat, _fstat - CREATE_ALIAS ftime, _ftime - CREATE_ALIAS gcvt, _gcvt - CREATE_ALIAS getch, _getch - CREATE_ALIAS getche, _getche - CREATE_ALIAS getcwd, _getcwd - CREATE_ALIAS getpid, _getpid - CREATE_ALIAS getw, _getw - CREATE_ALIAS heapwalk, _heapwalk - CREATE_ALIAS isatty, _isatty - CREATE_ALIAS isascii, __isascii - CREATE_ALIAS itoa, _itoa - CREATE_ALIAS kbhit, _kbhit - CREATE_ALIAS lfind, _lfind - CREATE_ALIAS lsearch, _lsearch - CREATE_ALIAS lseek, _lseek - CREATE_ALIAS ltoa, _ltoa - CREATE_ALIAS memccpy, _memccpy - CREATE_ALIAS memicmp, _memicmp - CREATE_ALIAS mkdir, _mkdir - CREATE_ALIAS mktemp, _mktemp - CREATE_ALIAS open, _open - CREATE_ALIAS pclose, _pclose - CREATE_ALIAS popen, _popen - CREATE_ALIAS putch, _putch - CREATE_ALIAS putenv, _putenv - CREATE_ALIAS putw, _putw - CREATE_ALIAS read, _read - CREATE_ALIAS rmdir, _rmdir - CREATE_ALIAS rmtmp, _rmtmp - CREATE_ALIAS searchenv, _searchenv - CREATE_ALIAS setmode, _setmode CREATE_ALIAS snprintf, _snprintf - CREATE_ALIAS sopen, _sopen - CREATE_ALIAS spawnl, _spawnl - CREATE_ALIAS spawnle, _spawnle - CREATE_ALIAS spawnlp, _spawnlp - CREATE_ALIAS spawnlpe, _spawnlpe - CREATE_ALIAS spawnv, _spawnv - CREATE_ALIAS spawnve, _spawnve - CREATE_ALIAS spawnvp, _spawnvp - CREATE_ALIAS spawnvpe, _spawnvpe - CREATE_ALIAS stat, _stat CREATE_ALIAS strcmpi, _strcmpi - CREATE_ALIAS strdup, _strdup - CREATE_ALIAS stricmp, _stricmp - CREATE_ALIAS stricoll, _stricoll - CREATE_ALIAS strlwr, _strlwr - CREATE_ALIAS strnicmp, _strnicmp - CREATE_ALIAS strnset, _strnset - CREATE_ALIAS strrev, _strrev - CREATE_ALIAS strset, _strset - CREATE_ALIAS strupr, _strupr - CREATE_ALIAS swab, _swab - CREATE_ALIAS tell, _tell - CREATE_ALIAS tempnam, _tempnam CREATE_ALIAS2 timezone, _timezone CREATE_ALIAS2 tzname, _tzname - CREATE_ALIAS tzset, _tzset - CREATE_ALIAS umask, _umask - CREATE_ALIAS ungetch, _ungetch - CREATE_ALIAS unlink, _unlink - CREATE_ALIAS utime, _utime - CREATE_ALIAS wcsdup, _wcsdup - CREATE_ALIAS wcsicmp, _wcsicmp - CREATE_ALIAS wcsicoll, _wcsicoll - CREATE_ALIAS wcslwr, _wcslwr - CREATE_ALIAS wcsnicmp, _wcsnicmp - CREATE_ALIAS wcsnset, _wcsnset - CREATE_ALIAS wcsrev, _wcsrev - CREATE_ALIAS wcsset, _wcsset - CREATE_ALIAS wcsupr, _wcsupr - CREATE_ALIAS wpopen, _wpopen - CREATE_ALIAS write, _write - // non-ANSI functions declared in math.h - CREATE_ALIAS j0, _j0 - CREATE_ALIAS j1, _j1 - CREATE_ALIAS jn, _jn - CREATE_ALIAS y0, _y0 - CREATE_ALIAS y1, _y1 - CREATE_ALIAS yn, _yn - CREATE_ALIAS chgsign, _chgsign - CREATE_ALIAS scalb, _scalb - CREATE_ALIAS finite, _finite - CREATE_ALIAS fpclass, _fpclass - // C99 functions + + // C99 functions (already properly exported in ucrtbase.dll)) CREATE_ALIAS cabs, _cabs CREATE_ALIAS hypot, _hypot CREATE_ALIAS logb, _logb CREATE_ALIAS nextafter, _nextafter END - diff --git a/sdk/lib/crt/oldnames.cmake b/sdk/lib/crt/oldnames.cmake index 0af57b8cfefb3..93b2a55721a30 100644 --- a/sdk/lib/crt/oldnames.cmake +++ b/sdk/lib/crt/oldnames.cmake @@ -17,7 +17,7 @@ if(NOT MSVC) _add_library(oldnames STATIC EXCLUDE_FROM_ALL ${LIBRARY_PRIVATE_DIR}/oldnames.a) set_target_properties(oldnames PROPERTIES LINKER_LANGUAGE "C") else() - add_asm_files(oldnames_asm oldnames-msvcrt.S) + add_asm_files(oldnames_asm oldnames-common.S oldnames-msvcrt.S) add_library(oldnames ${oldnames_asm}) set_target_properties(oldnames PROPERTIES LINKER_LANGUAGE "C") endif() diff --git a/sdk/lib/crt/printf/streamout.c b/sdk/lib/crt/printf/streamout.c index d3b7a3d8b6332..6c588f310cb8f 100644 --- a/sdk/lib/crt/printf/streamout.c +++ b/sdk/lib/crt/printf/streamout.c @@ -145,7 +145,7 @@ format_float( val32 = exponent >= 0 ? exponent : -exponent; // FIXME: handle length of exponent field: - // http://msdn.microsoft.com/de-de/library/0fatw238%28VS.80%29.aspx + // http://msdn.microsoft.com/de-de/library/0fatw238%28VS.80%29.aspx (DEAD_LINK) num_digits = 3; while (num_digits--) { diff --git a/sdk/lib/crt/stdlib/fcvtbuf.c b/sdk/lib/crt/stdlib/fcvtbuf.c index a76b27bc51548..18966efcb0b88 100644 --- a/sdk/lib/crt/stdlib/fcvtbuf.c +++ b/sdk/lib/crt/stdlib/fcvtbuf.c @@ -48,6 +48,21 @@ static char *cvt(double arg, int ndigits, int *decpt, int *sign, char *buf, int double fi, fj; char *p, *p1; + if (_isnan(arg)) + { + snprintf(buf, ndigits, "1.#QNAN"); + *decpt = 0; + *sign = 0; + return buf; + } + if (!_finite(arg)) + { + snprintf(buf, ndigits, "1.#INF"); + *decpt = 0; + *sign = 0; + return buf; + } + if (ndigits >= CVTBUFSIZE - 1) ndigits = CVTBUFSIZE - 2; r2 = 0; *sign = 0; diff --git a/sdk/lib/crt/time/ftime.c b/sdk/lib/crt/time/ftime.c index 84d48104eaea6..2cde56714fd67 100644 --- a/sdk/lib/crt/time/ftime.c +++ b/sdk/lib/crt/time/ftime.c @@ -14,7 +14,7 @@ * \brief Get the current time. * \param [out] ptimeb Pointer to a structure of type struct _timeb that * receives the current time. - * \sa http://msdn.microsoft.com/en-us/library/95e68951.aspx + * \sa https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/ftime-s-ftime32-s-ftime64-s?view=msvc-170 */ errno_t CDECL @@ -48,7 +48,7 @@ _ftime_s(struct _timeb *ptimeb) * receives the current time. * \note This function is for compatability and simply calls the secure * version _ftime_s(). - * \sa http://msdn.microsoft.com/en-us/library/z54t9z5f.aspx + * \sa https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/ftime-ftime32-ftime64?view=msvc-170 */ void CDECL diff --git a/sdk/lib/crt/time/futime.c b/sdk/lib/crt/time/futime.c index 3c6a20409aec4..d67df35ec1811 100644 --- a/sdk/lib/crt/time/futime.c +++ b/sdk/lib/crt/time/futime.c @@ -49,7 +49,7 @@ void release_ioinfo(ioinfo *info); * \brief Set a file's modification time. * \param [out] ptimeb Pointer to a structure of type struct _timeb that * receives the current time. - * \sa http://msdn.microsoft.com/en-us/library/95e68951.aspx + * \sa https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/futime-futime32-futime64?view=msvc-170 */ int _futime(int fd, struct _utimbuf *filetime) diff --git a/sdk/lib/crt/time/timezone.c b/sdk/lib/crt/time/timezone.c index 27b1b652623be..dd38a443a0b61 100644 --- a/sdk/lib/crt/time/timezone.c +++ b/sdk/lib/crt/time/timezone.c @@ -86,7 +86,7 @@ __p__tzname(void) * \brief Initializes the variables _daylight, _timezone, and _tzname from the * "TZ" environment variable if available or else by calling * GetTimeZoneInformation. - * \sa http://msdn.microsoft.com/en-us/library/90s5c885.aspx + * \sa https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/tzset?view=msvc-170 */ void _tzset(void) diff --git a/sdk/lib/crt/ucrtsupport.cmake b/sdk/lib/crt/ucrtsupport.cmake new file mode 100644 index 0000000000000..2f558d96db5e1 --- /dev/null +++ b/sdk/lib/crt/ucrtsupport.cmake @@ -0,0 +1,80 @@ + +list(APPEND UCRTSUPP_SOURCE + ${CRT_FLOAT_SOURCE} + ${CRT_MATH_SOURCE} + misc/amsg.c + misc/purecall.c + misc/tls.c + wine/cpp.c + wine/except.c + wine/undname.c +) + +list(APPEND UCRTSUPP_ASM_SOURCE + ${CRT_FLOAT_ASM_SOURCE} + ${CRT_MATH_ASM_SOURCE} + ${CRT_SETJMP_ASM_SOURCE} + ${CRT_WINE_ASM_SOURCE} +) + +if(ARCH STREQUAL "i386") + list(APPEND UCRTSUPP_SOURCE + except/i386/CxxHandleV8Frame.c + wine/except_i386.c + ) + list(APPEND UCRTSUPP_ASM_SOURCE + except/i386/__CxxFrameHandler3.s + except/i386/chkesp.s + wine/rosglue_i386.s + ) + if(MSVC) + list(APPEND UCRTSUPP_ASM_SOURCE + except/i386/cpp.s + except/i386/prolog.s + ) + endif() +elseif(ARCH STREQUAL "amd64") + list(APPEND UCRTSUPP_SOURCE + wine/except_x86_64.c + ) + if(MSVC) + list(APPEND UCRTSUPP_ASM_SOURCE + except/amd64/cpp.s + ) + endif() +elseif(ARCH STREQUAL "arm") + list(APPEND UCRTSUPP_SOURCE + wine/except_arm.c + ) + if(MSVC) + list(APPEND UCRTSUPP_ASM_SOURCE + except/arm/cpp.s + ) + endif() +elseif(ARCH STREQUAL "arm64") + list(APPEND UCRTSUPP_SOURCE + wine/except_arm64.c + ) +endif() + +add_asm_files(ucrtsupp_asm ${UCRTSUPP_ASM_SOURCE}) + +add_library(ucrtsupport ${UCRTSUPP_SOURCE} ${ucrtsupp_asm}) +target_link_libraries(ucrtsupport chkstk ${PSEH_LIB}) +target_compile_definitions(ucrtsupport PRIVATE + __UCRTSUPPORT__ + CRTDLL + _MSVCRT_LIB_ + _MSVCRT_ + _MT + USE_MSVCRT_PREFIX + __MINGW_IMPORT=extern + __fma3_lib_init=__acrt_initialize_fma3 + set_terminate=_wine_set_terminate + terminate=_wine_terminate + _get_terminate=_wine_get_terminate + unexpected=_wine_unexpected + __pxcptinfoptrs=_wine__pxcptinfoptrs +) +#add_pch(crt precomp.h) +add_dependencies(ucrtsupport psdk asm) diff --git a/sdk/lib/crt/wine/cpp.c b/sdk/lib/crt/wine/cpp.c index a256569584bb2..d7cc32aefc72e 100644 --- a/sdk/lib/crt/wine/cpp.c +++ b/sdk/lib/crt/wine/cpp.c @@ -1025,7 +1025,7 @@ void WINAPI _CxxThrowException( void *object, const cxx_exception_type *type ) } #endif -#if _MSVCR_VER >= 80 +#if _MSVCR_VER >= 80 || defined(__UCRTSUPPORT__) /********************************************************************* * ?_is_exception_typeof@@YAHABVtype_info@@PAU_EXCEPTION_POINTERS@@@Z @@ -1063,6 +1063,8 @@ int __cdecl _is_exception_typeof(const type_info *ti, EXCEPTION_POINTERS *ep) } } __EXCEPT_PAGE_FAULT + { + } __ENDTRY if(ret == -1) @@ -1104,6 +1106,8 @@ int __cdecl _is_exception_typeof(const type_info *ti, EXCEPTION_POINTERS *ep) } } __EXCEPT_PAGE_FAULT + { + } __ENDTRY if(ret == -1) @@ -1123,6 +1127,7 @@ void CDECL __clean_type_info_names_internal(void *p) /********************************************************************* * ?_name_internal_method@type_info@@QBEPBDPAU__type_info_node@@@Z (MSVCR100.@) */ +const char * __thiscall type_info_name_internal_method(type_info * _this, struct __type_info_node *node); DEFINE_THISCALL_WRAPPER(type_info_name_internal_method,8) const char * __thiscall type_info_name_internal_method(type_info * _this, struct __type_info_node *node) { @@ -1472,14 +1477,14 @@ bool __cdecl __ExceptionPtrCompare(const exception_ptr *ep1, const exception_ptr #endif /* _MSVCR_VER >= 100 */ -#if _MSVCR_VER >= 80 +#if _MSVCR_VER >= 80 || defined(__UCRTSUPPORT__) void* __cdecl __AdjustPointer(void *obj, const this_ptr_offsets *off) { return get_this_pointer(off, obj); } #endif -#if _MSVCR_VER >= 140 +#if _MSVCR_VER >= 140 || defined(__UCRTSUPPORT__) typedef struct { diff --git a/sdk/lib/crt/wine/except.c b/sdk/lib/crt/wine/except.c index 4679560dae5db..8750379225bd8 100644 --- a/sdk/lib/crt/wine/except.c +++ b/sdk/lib/crt/wine/except.c @@ -487,7 +487,7 @@ struct __std_exception_data { char dofree; }; -#if _MSVCR_VER>=140 +#if _MSVCR_VER>=140 || defined(__UCRTSUPPORT__) /********************************************************************* * __std_exception_copy (UCRTBASE.@) diff --git a/sdk/lib/drivers/rdbsslib/rdbss.c b/sdk/lib/drivers/rdbsslib/rdbss.c index ba6839b298b4c..275a2a8e8a97c 100644 --- a/sdk/lib/drivers/rdbsslib/rdbss.c +++ b/sdk/lib/drivers/rdbsslib/rdbss.c @@ -7846,7 +7846,7 @@ RxPrepareToReparseSymbolicLink( if (!SymbolicLinkEmbeddedInOldPath) { /* Excepted if DELETE is the only flag specified, then, open has to succeed - * See: https://msdn.microsoft.com/en-us/library/windows/hardware/ff554649(v=vs.85).aspx (remarks) + * See: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/rxprocs/nf-rxprocs-rxpreparetoreparsesymboliclink (remarks) */ if (BooleanFlagOn(RxContext->Create.NtCreateParameters.DesiredAccess, DELETE) && BooleanFlagOn(RxContext->Create.NtCreateParameters.DesiredAccess, ~DELETE)) diff --git a/sdk/lib/drivers/sound/mmixer/mixer.c b/sdk/lib/drivers/sound/mmixer/mixer.c index 4b98ed53ae3ea..214e1234071d8 100644 --- a/sdk/lib/drivers/sound/mmixer/mixer.c +++ b/sdk/lib/drivers/sound/mmixer/mixer.c @@ -817,11 +817,8 @@ MMixerInitialize( /* store mixer list */ MixerContext->MixerContext = (PVOID)MixerList; - /* start enumerating all available devices */ - Count = 0; - DeviceIndex = 0; - - do + /* enumerate all available devices */ + for (DeviceIndex = 0; ; DeviceIndex++) { /* enumerate a device */ Status = EnumFunction(EnumContext, DeviceIndex, &DeviceName, &hMixer, &hKey); @@ -834,29 +831,27 @@ MMixerInitialize( /* enumeration has finished */ break; } - else - { - DPRINT1("Failed to enumerate device %lu\n", DeviceIndex); - /* TODO cleanup */ - return Status; - } + DPRINT1("EnumFunction() failed for device %lu, Status %x\n", DeviceIndex, Status); + + /* ignore error and continue */ } else { /* create a mixer data entry */ Status = MMixerCreateMixerData(MixerContext, MixerList, DeviceIndex, DeviceName, hMixer, hKey); if (Status != MM_STATUS_SUCCESS) - break; - } + DPRINT1("MMixerCreateMixerData() failed for device %lu, Status %x\n", + DeviceIndex, Status); - /* increment device index */ - DeviceIndex++; - }while(TRUE); + /* ignore error and continue */ + } + } /* now all filters have been pre-opened * lets enumerate the filters */ + Count = 0; Entry = MixerList->MixerData.Flink; while(Entry != &MixerList->MixerData) { diff --git a/sdk/lib/lsalib/lsa.c b/sdk/lib/lsalib/lsa.c index 95a02f41cd7c0..321797e066b7d 100644 --- a/sdk/lib/lsalib/lsa.c +++ b/sdk/lib/lsalib/lsa.c @@ -317,6 +317,7 @@ LsaRegisterLogonProcess(IN PLSA_STRING LogonProcessName, ConnectInfo.Length = LogonProcessName->Length; ConnectInfo.LogonProcessNameBuffer[ConnectInfo.Length] = ANSI_NULL; ConnectInfo.CreateContext = TRUE; + ConnectInfo.TrustedCaller = CHECK; Status = ZwConnectPort(LsaHandle, &PortName, diff --git a/sdk/lib/pseh/CMakeLists.txt b/sdk/lib/pseh/CMakeLists.txt index b2d23bb358836..e36a3f5fd8705 100644 --- a/sdk/lib/pseh/CMakeLists.txt +++ b/sdk/lib/pseh/CMakeLists.txt @@ -57,5 +57,4 @@ target_include_directories(pseh INTERFACE include) # Make it clear that we are using PSEH2 if ((CMAKE_C_COMPILER_ID STREQUAL "GNU") OR ((CMAKE_C_COMPILER_ID STREQUAL "Clang") AND (NOT (ARCH STREQUAL "amd64")))) - target_compile_definitions(pseh INTERFACE __USE_PSEH2__) endif() diff --git a/sdk/lib/pseh/include/pseh/pseh2.h b/sdk/lib/pseh/include/pseh/pseh2.h index 523d9ddd161c6..a3aed7aed2b44 100644 --- a/sdk/lib/pseh/include/pseh/pseh2.h +++ b/sdk/lib/pseh/include/pseh/pseh2.h @@ -23,7 +23,9 @@ #ifndef KJK_PSEH2_H_ #define KJK_PSEH2_H_ -#if defined(_USE_NATIVE_SEH) || (defined(_MSC_VER) && !(defined(__clang__) && defined(_M_AMD64))) +#define __USE_PSEH2__ + +#if defined(_USE_NATIVE_SEH) || defined(_MSC_VER) #define _SEH2_TRY __try #define _SEH2_FINALLY __finally @@ -86,6 +88,14 @@ _Pragma("GCC diagnostic pop") #define _SEH2_LEAVE goto __seh2_scope_end__; #define _SEH2_VOLATILE volatile +#define __try _SEH2_TRY +#define __except _SEH2_EXCEPT +#define __finally _SEH2_FINALLY +#define __endtry _SEH2_END +#define __leave _SEH2_LEAVE +#define _exception_code() 0 +#define _exception_info() ((void*)0) + #elif defined(_USE_PSEH3) #include "pseh3.h" diff --git a/sdk/lib/pseh/include/pseh/pseh2_64.h b/sdk/lib/pseh/include/pseh/pseh2_64.h index 7d9414ddd2bb5..d33ea377c10bf 100644 --- a/sdk/lib/pseh/include/pseh/pseh2_64.h +++ b/sdk/lib/pseh/include/pseh/pseh2_64.h @@ -1,6 +1,22 @@ #pragma once +struct _SEH$$_EXCEPTION_RECORD +{ + unsigned long ExceptionCode; + unsigned long ExceptionFlags; + struct _EXCEPTION_RECORD *ExceptionRecord; + void* ExceptionAddress; + unsigned long NumberParameters; + unsigned long long ExceptionInformation[15]; +}; + +struct _SEH$$_EXCEPTION_POINTERS +{ + struct _SEH$$_EXCEPTION_RECORD *ExceptionRecord; + struct _CONTEXT *ContextRecord; +}; + /* Declare our global trampoline function for filter and unwinder */ __asm__( ".p2align 4, 0x90\n" @@ -78,7 +94,7 @@ __seh2$$end_try__:(void)0; if (0) \ { \ __label__ __seh2$$leave_scope__; \ - LONG __MINGW_ATTRIB_UNUSED __seh2$$exception_code__; \ + long __MINGW_ATTRIB_UNUSED __seh2$$exception_code__; \ /* Add our handlers to the list */ \ if (0) \ { \ @@ -93,7 +109,7 @@ __seh2$$end_try__:(void)0; : "%r8" \ : __seh2$$filter_funclet__); \ /* Actually declare our filter funclet */ \ - struct _EXCEPTION_POINTERS* __seh2$$exception_ptr__; \ + struct _SEH$$_EXCEPTION_POINTERS* __seh2$$exception_ptr__; \ __seh2$$filter_funclet__: \ /* At this point, the compiler can't count on any register being valid */ \ __asm__ __volatile__("" \ @@ -167,20 +183,19 @@ __seh2$$begin_except__: __MINGW_ATTRIB_UNUSED; } \ } -#define _SEH2_GetExceptionInformation() __seh2$$exception_ptr__ +#define _SEH2_GetExceptionInformation() ((struct _EXCEPTION_POINTERS*)__seh2$$exception_ptr__) #define _SEH2_GetExceptionCode() __seh2$$exception_code__ #define _SEH2_AbnormalTermination() __seh2$$abnormal_termination__ #define _SEH2_LEAVE goto __seh2$$leave_scope__ #define _SEH2_YIELD(__stmt) __stmt #define _SEH2_VOLATILE volatile -#ifndef __try // Conflict with GCC's STL +#undef __try // undef from GCC's stl #define __try _SEH2_TRY #define __except _SEH2_EXCEPT #define __finally _SEH2_FINALLY #define __endtry _SEH2_END #define __leave goto __seh2$$leave_scope__ -#define _exception_info() __seh2$$exception_ptr__ +#define _exception_info() ((struct _EXCEPTION_POINTERS*)__seh2$$exception_ptr__) #define _exception_code() __seh2$$exception_code__ #define _abnormal_termination() __seh2$$abnormal_termination__ -#endif diff --git a/sdk/lib/rtl/CMakeLists.txt b/sdk/lib/rtl/CMakeLists.txt index efe2c90a40bb8..688d925858791 100644 --- a/sdk/lib/rtl/CMakeLists.txt +++ b/sdk/lib/rtl/CMakeLists.txt @@ -8,13 +8,19 @@ add_definitions( if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") # Enable this again. CORE-17637 add_compile_options(-Wunused-result) + + add_compile_options(-Wno-incompatible-pointer-types) + add_compile_options(-Wno-missing-braces) endif() +include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) + list(APPEND RTL_WINE_SOURCE actctx.c timerqueue.c - wait.c + threadpool.c ) +set_source_files_properties(threadpool.c PROPERTIES COMPILE_DEFINITIONS __WINESRC__) if(MSVC) # Silence warning C4267: 'initializing': conversion from 'size_t' to 'const int', possible loss of data @@ -51,6 +57,7 @@ list(APPEND SOURCE image.c interlck.c largeint.c + locale.c luid.c memstream.c message.c diff --git a/sdk/lib/rtl/amd64/unwind.c b/sdk/lib/rtl/amd64/unwind.c index ee7313bc62f0f..3a438390cb6b1 100644 --- a/sdk/lib/rtl/amd64/unwind.c +++ b/sdk/lib/rtl/amd64/unwind.c @@ -116,7 +116,7 @@ RtlpLookupDynamicFunctionEntry( /*! RtlLookupFunctionEntry * \brief Locates the RUNTIME_FUNCTION entry corresponding to a code address. - * \ref http://msdn.microsoft.com/en-us/library/ms680597(VS.85).aspx + * \ref https://learn.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-rtllookupfunctionentry * \todo Implement HistoryTable */ PRUNTIME_FUNCTION @@ -649,6 +649,18 @@ RtlVirtualUnwind( return NULL; } +static __inline +BOOL +RtlpIsStackPointerValid( + _In_ ULONG64 StackPointer, + _In_ ULONG64 LowLimit, + _In_ ULONG64 HighLimit) +{ + return (StackPointer >= LowLimit) && + (StackPointer < HighLimit) && + ((StackPointer & 7) == 0); +} + /*! \remark The implementation is based on the description in this blog: http://www.nynaeve.net/?p=106 @@ -699,6 +711,11 @@ RtlpUnwindInternal( /* Start looping */ while (TRUE) { + if (!RtlpIsStackPointerValid(UnwindContext.Rsp, StackLow, StackHigh)) + { + return FALSE; + } + /* Lookup the FunctionEntry for the current RIP */ FunctionEntry = RtlLookupFunctionEntry(UnwindContext.Rip, &ImageBase, NULL); if (FunctionEntry == NULL) @@ -943,6 +960,7 @@ RtlWalkFrameChain(OUT PVOID *Callers, PVOID HandlerData; ULONG i, FramesToSkip; PRUNTIME_FUNCTION FunctionEntry; + MODE CurrentMode = RtlpGetMode(); DPRINT("Enter RtlWalkFrameChain\n"); @@ -956,11 +974,6 @@ RtlWalkFrameChain(OUT PVOID *Callers, /* Get the stack limits */ RtlpGetStackLimits(&StackLow, &StackHigh); - /* Check if we want the user-mode stack frame */ - if (Flags & 1) - { - } - _SEH2_TRY { /* Loop the frames */ @@ -990,15 +1003,26 @@ RtlWalkFrameChain(OUT PVOID *Callers, } /* Check if we are in kernel mode */ - if (RtlpGetMode() == KernelMode) + if (CurrentMode == KernelMode) { /* Check if we left the kernel range */ - if (!(Flags & 1) && (Context.Rip < 0xFFFF800000000000ULL)) + if (Context.Rip < 0xFFFF800000000000ULL) { - break; + /* Bail out, unless user mode was requested */ + if ((Flags & 1) == 0) + { + break; + } + + /* We are in user mode now, get UM stack bounds */ + CurrentMode = UserMode; + StackLow = (ULONG64)NtCurrentTeb()->NtTib.StackLimit; + StackHigh = (ULONG64)NtCurrentTeb()->NtTib.StackBase; } } - else + + /* Check (again) if we are in user mode now */ + if (CurrentMode == UserMode) { /* Check if we left the user range */ if ((Context.Rip < 0x10000) || diff --git a/sdk/lib/rtl/critical.c b/sdk/lib/rtl/critical.c index c70ff191bbcec..2e35b7029daf5 100644 --- a/sdk/lib/rtl/critical.c +++ b/sdk/lib/rtl/critical.c @@ -369,7 +369,7 @@ RtlpFreeDebugInfo(PRTL_CRITICAL_SECTION_DEBUG DebugInfo) } else { - /* Wine stores a section name pointer in the Flags member */ + /* HACK for Wine: stores a section name pointer in the Flags member */ DPRINT("Assuming static: %p inside Process: %p\n", DebugInfo, NtCurrentTeb()->ClientId.UniqueProcess); @@ -415,7 +415,7 @@ RtlDeleteCriticalSection(PRTL_CRITICAL_SECTION CriticalSection) /* Remove it from the list */ RemoveEntryList(&CriticalSection->DebugInfo->ProcessLocksList); #if 0 - /* We need to preserve Flags for RtlpFreeDebugInfo */ + /* HACK for Wine: We need to preserve Flags for RtlpFreeDebugInfo */ RtlZeroMemory(CriticalSection->DebugInfo, sizeof(RTL_CRITICAL_SECTION_DEBUG)); #endif } @@ -521,6 +521,7 @@ RtlEnterCriticalSection(PRTL_CRITICAL_SECTION CriticalSection) */ CriticalSection->OwningThread = Thread; CriticalSection->RecursionCount = 1; + NtCurrentTeb()->CountOfOwnedCriticalSections++; return STATUS_SUCCESS; } @@ -800,6 +801,7 @@ RtlLeaveCriticalSection(PRTL_CRITICAL_SECTION CriticalSection) * See comment above. */ CriticalSection->OwningThread = 0; + NtCurrentTeb()->CountOfOwnedCriticalSections--; /* Was someone wanting us? This needs to be done atomically. */ if (-1 != InterlockedDecrement(&CriticalSection->LockCount)) @@ -837,8 +839,9 @@ RtlTryEnterCriticalSection(PRTL_CRITICAL_SECTION CriticalSection) if (InterlockedCompareExchange(&CriticalSection->LockCount, 0, -1) == -1) { /* It's ours */ - CriticalSection->OwningThread = NtCurrentTeb()->ClientId.UniqueThread; + CriticalSection->OwningThread = NtCurrentTeb()->ClientId.UniqueThread; CriticalSection->RecursionCount = 1; + NtCurrentTeb()->CountOfOwnedCriticalSections++; return TRUE; } else if (CriticalSection->OwningThread == NtCurrentTeb()->ClientId.UniqueThread) diff --git a/sdk/lib/rtl/heap.c b/sdk/lib/rtl/heap.c index 256736fda1a89..b38f4c93e3b51 100644 --- a/sdk/lib/rtl/heap.c +++ b/sdk/lib/rtl/heap.c @@ -8,8 +8,8 @@ */ /* Useful references: - http://msdn.microsoft.com/en-us/library/ms810466.aspx - http://msdn.microsoft.com/en-us/library/ms810603.aspx + https://learn.microsoft.com/en-us/previous-versions/ms810466(v=msdn.10) + https://learn.microsoft.com/en-us/previous-versions/ms810603(v=msdn.10) http://www.securitylab.ru/analytics/216376.php http://binglongx.spaces.live.com/blog/cns!142CBF6D49079DE8!596.entry http://www.phreedom.org/research/exploits/asn1-bitstring/ diff --git a/sdk/lib/rtl/heappage.c b/sdk/lib/rtl/heappage.c index e15d981e4eff3..34a2feab298b0 100644 --- a/sdk/lib/rtl/heappage.c +++ b/sdk/lib/rtl/heappage.c @@ -7,7 +7,7 @@ */ /* Useful references: - http://msdn.microsoft.com/en-us/library/ms220938(VS.80).aspx + https://learn.microsoft.com/en-us/previous-versions/ms220938(v=vs.80) http://blogs.msdn.com/b/jiangyue/archive/2010/03/16/windows-heap-overrun-monitoring.aspx */ @@ -202,6 +202,10 @@ RtlpDphReportCorruptedBlock( BOOLEAN NTAPI RtlpDphNormalHeapValidate(PDPH_HEAP_ROOT DphRoot, ULONG Flags, PVOID BaseAddress); +/* verifier.c */ +VOID NTAPI +AVrfInternalHeapFreeNotification(PVOID AllocationBase, SIZE_T AllocationSize); + VOID NTAPI RtlpDphRaiseException(NTSTATUS Status) @@ -1348,67 +1352,67 @@ RtlpDphReportCorruptedBlock( if (ValidationInfo & DPH_VALINFO_CORRUPTED_AFTER_FREE) { - RtlApplicationVerifierStop( - APPLICATION_VERIFIER_CORRUPTED_HEAP_BLOCK_AFTER_FREE, "block corrupted after having been freed", + VERIFIER_STOP( + APPLICATION_VERIFIER_CORRUPTED_HEAP_BLOCK_HEADER, "block corrupted after having been freed", RtlpDphHeapFromPointer(DphRoot), "Heap handle", Block, "Heap block", (PVOID)Size, "Block size", 0, ""); } if (ValidationInfo & DPH_VALINFO_ALREADY_FREED) { - RtlApplicationVerifierStop( + VERIFIER_STOP( APPLICATION_VERIFIER_DOUBLE_FREE, "block already freed", RtlpDphHeapFromPointer(DphRoot), "Heap handle", Block, "Heap block", Size, "Block size", 0, ""); } if (ValidationInfo & DPH_VALINFO_BAD_INFIX_PATTERN) { - RtlApplicationVerifierStop( - APPLICATION_VERIFIER_CORRUPTED_INFIX_PATTERN, "corrupted infix pattern for freed block", + VERIFIER_STOP( + APPLICATION_VERIFIER_CORRUPTED_FREED_HEAP_BLOCK, "corrupted infix pattern for freed block", RtlpDphHeapFromPointer(DphRoot), "Heap handle", Block, "Heap block", Size, "Block size", 0, ""); } if (ValidationInfo & DPH_VALINFO_BAD_POINTER) { - RtlApplicationVerifierStop( - APPLICATION_VERIFIER_CORRUPT_HEAP_POINTER, "corrupted heap pointer or using wrong heap", + VERIFIER_STOP( + APPLICATION_VERIFIER_SWITCHED_HEAP_HANDLE, "corrupted heap pointer or using wrong heap", RtlpDphHeapFromPointer(DphRoot), "Heap handle used", Block, "Heap block", Size, "Block size", SafeInfo.Heap, "Actual heap handle"); } if (ValidationInfo & DPH_VALINFO_BAD_SUFFIX_PATTERN) { - RtlApplicationVerifierStop( - APPLICATION_VERIFIER_CORRUPTED_SUFFIX_PATTERN, "corrupted suffix pattern", RtlpDphHeapFromPointer(DphRoot), + VERIFIER_STOP( + APPLICATION_VERIFIER_CORRUPTED_HEAP_BLOCK_SUFFIX, "corrupted suffix pattern", RtlpDphHeapFromPointer(DphRoot), "Heap handle used", Block, "Heap block", Size, "Block size", 0, ""); } if (ValidationInfo & DPH_VALINFO_BAD_PREFIX_PATTERN) { - RtlApplicationVerifierStop( - APPLICATION_VERIFIER_CORRUPTED_PREFIX_PATTERN, "corrupted prefix pattern", RtlpDphHeapFromPointer(DphRoot), + VERIFIER_STOP( + APPLICATION_VERIFIER_CORRUPTED_HEAP_BLOCK_PREFIX, "corrupted prefix pattern", RtlpDphHeapFromPointer(DphRoot), "Heap handle used", Block, "Heap block", Size, "Block size", 0, ""); } if (ValidationInfo & DPH_VALINFO_BAD_START_STAMP) { - RtlApplicationVerifierStop( - APPLICATION_VERIFIER_CORRUPTED_START_STAMP, "corrupted start stamp", RtlpDphHeapFromPointer(DphRoot), + VERIFIER_STOP( + APPLICATION_VERIFIER_CORRUPTED_HEAP_BLOCK_START_STAMP, "corrupted start stamp", RtlpDphHeapFromPointer(DphRoot), "Heap handle used", Block, "Heap block", Size, "Block size", (PVOID)(ULONG_PTR)SafeInfo.StartStamp, "Corrupted start stamp"); } if (ValidationInfo & DPH_VALINFO_BAD_END_STAMP) { - RtlApplicationVerifierStop( - APPLICATION_VERIFIER_CORRUPTED_END_STAMP, "corrupted end stamp", RtlpDphHeapFromPointer(DphRoot), + VERIFIER_STOP( + APPLICATION_VERIFIER_CORRUPTED_HEAP_BLOCK_END_STAMP, "corrupted end stamp", RtlpDphHeapFromPointer(DphRoot), "Heap handle used", Block, "Heap block", Size, "Block size", (PVOID)(ULONG_PTR)SafeInfo.EndStamp, "Corrupted end stamp"); } if (ValidationInfo & DPH_VALINFO_EXCEPTION) { - RtlApplicationVerifierStop( - APPLICATION_VERIFIER_EXCEPTION_WHILE_VERIFYING_BLOCK_HEADER, "exception raised while verifying block", + VERIFIER_STOP( + APPLICATION_VERIFIER_CORRUPTED_HEAP_BLOCK_EXCEPTION_RAISED_FOR_HEADER, "exception raised while verifying block", RtlpDphHeapFromPointer(DphRoot), "Heap handle used", Block, "Heap block", Size, "Block size", 0, ""); } } @@ -1682,7 +1686,12 @@ RtlpPageHeapDestroy(HANDLE HeapPtr) /* Check if it's not a process heap */ if (HeapPtr == RtlGetProcessHeap()) { - DbgBreakPoint(); + VERIFIER_STOP(APPLICATION_VERIFIER_DESTROY_PROCESS_HEAP, + "attempt to destroy process heap", + HeapPtr, "Heap handle", + 0, "", + 0, "", + 0, ""); return NULL; } @@ -1712,8 +1721,7 @@ RtlpPageHeapDestroy(HANDLE HeapPtr) } } - /* FIXME: Call AV notification */ - //AVrfInternalHeapFreeNotification(); + AVrfInternalHeapFreeNotification(Node->pUserAllocation, Node->nUserRequestedSize); /* Go to the next node */ Ptr = RtlEnumerateGenericTableAvl(&DphRoot->BusyNodesTable, FALSE); diff --git a/sdk/lib/rtl/locale.c b/sdk/lib/rtl/locale.c new file mode 100644 index 0000000000000..980a715590ec5 --- /dev/null +++ b/sdk/lib/rtl/locale.c @@ -0,0 +1,954 @@ +/* + * PROJECT: ReactOS runtime library + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: Rtl locale functions + * COPYRIGHT: Copyright 2025 Timo Kreuzer + */ + +#include + +#define NDEBUG +#include + +// See https://winprotocoldoc.z19.web.core.windows.net/MS-LCID/%5bMS-LCID%5d.pdf +// For special LCIDs see https://learn.microsoft.com/en-us/windows/win32/intl/locale-custom-constants +// and https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-lcid/926e694f-1797-4418-a922-343d1c5e91a6 +// and https://learn.microsoft.com/en-us/windows/win32/intl/locale-identifiers + +#define MAX_PRIMARY_LANGUAGE 0x3FF +#define MAX_BASIC_LCID 0x5FFF + +#define LCID_ALT_NAME 0x00100000 // Alternative name, OR'ed with LCID + +LCID RtlpUserDefaultLcid; +LCID RtlpSystemDefaultLcid; + +typedef struct _LOCALE_ENTRY +{ + const CHAR Locale[16]; + LCID Lcid : 24; + ULONG Flags : 8; +} LOCALE_ENTRY; + +// This table is sorted alphabetically to allow binary search +static const LOCALE_ENTRY RtlpLocaleTable[] = +{ + { "", 0x0007F }, // LOCALE_INVARIANT + { "af", 0x00036 }, + { "af-ZA", 0x00436 }, + { "am", 0x0005E }, + { "am-ET", 0x0045E }, + { "ar", 0x00001 }, + // { "ar-145", 0x04801 }, // reserved + { "ar-AE", 0x03801 }, + { "ar-BH", 0x03C01 }, + { "ar-DZ", 0x01401 }, + { "ar-EG", 0x00C01 }, + { "ar-IQ", 0x00801 }, + { "ar-JO", 0x02C01 }, + { "ar-KW", 0x03401 }, + { "ar-LB", 0x03001 }, + { "ar-LY", 0x01001 }, + { "ar-MA", 0x01801 }, + { "ar-OM", 0x02001 }, + // { "ar-Ploc-SA", 0x04401 }, // reserved + { "ar-QA", 0x04001 }, + { "ar-SA", 0x00401 }, + { "ar-SY", 0x02801 }, + { "ar-TN", 0x01C01 }, + { "ar-YE", 0x02401 }, + { "arn", 0x0007A }, + { "arn-CL", 0x0047A }, + { "as", 0x0004D }, + { "as-IN", 0x0044D }, + { "az", 0x0002C }, + { "az-Cyrl", 0x0742C }, + { "az-Cyrl-AZ", 0x0082C }, // Doc: reserved + { "az-Latn", 0x0782C }, + { "az-Latn-AZ", 0x0042C }, + { "ba", 0x0006D }, + { "ba-RU", 0x0046D }, + { "be", 0x00023 }, + { "be-BY", 0x00423 }, + { "bg", 0x00002 }, + { "bg-BG", 0x00402 }, + { "bin", 0x00066 }, // Doc: reserved + { "bin-NG", 0x00466 }, // Doc: reserved + { "bn", 0x00045 }, + { "bn-BD", 0x00845 }, + { "bn-IN", 0x00445 }, + { "bo", 0x00051 }, + // { "bo-BT", 0x00851 }, // reserved + { "bo-CN", 0x00451 }, + { "br", 0x0007E }, + { "br-FR", 0x0047E }, + { "bs", 0x0781A }, + { "bs-Cyrl", 0x0641A }, + { "bs-Cyrl-BA", 0x0201A }, + { "bs-Latn", 0x0681A }, + { "bs-Latn-BA", 0x0141A }, + { "ca", 0x00003 }, + { "ca-ES", 0x00403 }, + { "ca-ES-valencia", 0x00803 }, + { "chr", 0x0005C }, + { "chr-Cher", 0x07C5C }, + { "chr-Cher-US", 0x0045C }, + { "co", 0x00083 }, + { "co-FR", 0x00483 }, + { "cs", 0x00005 }, + { "cs-CZ", 0x00405 }, + { "cy", 0x00052 }, + { "cy-GB", 0x00452 }, + { "da", 0x00006 }, + { "da-DK", 0x00406 }, + { "de", 0x00007 }, + { "de-AT", 0x00C07 }, + { "de-CH", 0x00807 }, + { "de-DE", 0x00407 }, + { "de-DE_phoneb", 0x10407 }, + { "de-LI", 0x01407 }, + { "de-LU", 0x01007 }, + { "dsb", 0x07C2E }, + { "dsb-DE", 0x0082E }, + { "dv", 0x00065 }, + { "dv-MV", 0x00465 }, + { "dz-BT", 0x00C51 }, + { "el", 0x00008 }, + { "el-GR", 0x00408 }, + { "en", 0x00009 }, + { "en-029", 0x02409 }, // Doc: reserved + { "en-AE", 0x04C09 }, + { "en-AU", 0x00C09 }, + // { "en-BH", 0x05009 }, // reserved + { "en-BZ", 0x02809 }, + { "en-CA", 0x01009 }, + // { "en-EG", 0x05409 }, // reserved + { "en-GB", 0x00809 }, + { "en-HK", 0x03C09 }, + { "en-ID", 0x03809 }, // reserved + { "en-IE", 0x01809 }, + { "en-IN", 0x04009 }, + { "en-JM", 0x02009 }, + // { "en-JO", 0x05809 }, // reserved + // { "en-KW", 0x05C09 }, // reserved + { "en-MY", 0x04409 }, + { "en-NZ", 0x01409 }, + { "en-PH", 0x03409 }, + { "en-SG", 0x04809 }, + // { "en-TR", 0x6009 }, // reserved + { "en-TT", 0x02C09 }, + { "en-US", 0x00409 }, + // { "en-YE", 0x6409 }, // reserved + { "en-ZA", 0x01C09 }, + { "en-ZW", 0x03009 }, + { "es", 0x0000A }, + { "es-419", 0x0580A }, // Doc: reserved + { "es-AR", 0x02C0A }, + { "es-BO", 0x0400A }, + { "es-CL", 0x0340A }, + { "es-CO", 0x0240A }, + { "es-CR", 0x0140A }, + { "es-CU", 0x05C0A }, + { "es-DO", 0x01C0A }, + { "es-EC", 0x0300A }, + { "es-ES", 0x00C0A }, + { "es-ES_tradnl", 0x0040A }, + { "es-GT", 0x0100A }, + { "es-HN", 0x0480A }, + { "es-MX", 0x0080A }, + { "es-NI", 0x04C0A }, + { "es-PA", 0x0180A }, + { "es-PE", 0x0280A }, + { "es-PR", 0x0500A }, + { "es-PY", 0x03C0A }, + { "es-SV", 0x0440A }, + { "es-US", 0x0540A }, + { "es-UY", 0x0380A }, + { "es-VE", 0x0200A }, + { "et", 0x00025 }, + { "et-EE", 0x00425 }, + { "eu", 0x0002D }, + { "eu-ES", 0x0042D }, + { "fa", 0x00029 }, + { "fa-IR", 0x00429 }, + { "ff", 0x00067 }, + { "ff-Latn", 0x07C67 }, + { "ff-Latn-NG", 0x00467 }, + { "ff-Latn-SN", 0x00867 }, + { "ff-NG", 0x00467 | LCID_ALT_NAME }, + { "fi", 0x0000B }, + { "fi-FI", 0x0040B }, + { "fil", 0x00064 }, + { "fil-PH", 0x00464 }, + { "fo", 0x00038 }, + { "fo-FO", 0x00438 }, + { "fr", 0x0000C }, + // { "fr-015", 0x0E40C }, // reserved + { "fr-029", 0x01C0C }, + { "fr-BE", 0x0080C }, + { "fr-CA", 0x00C0C }, + { "fr-CD", 0x0240C }, + { "fr-CH", 0x0100C }, + { "fr-CI", 0x0300C }, + { "fr-CM", 0x02C0C }, + { "fr-FR", 0x0040C }, + { "fr-HT", 0x03C0C }, + { "fr-LU", 0x0140C }, + { "fr-MA", 0x0380C }, + { "fr-MC", 0x0180C }, + { "fr-ML", 0x0340C }, + { "fr-RE", 0x0200C }, + { "fr-SN", 0x0280C }, + { "fy", 0x00062 }, + { "fy-NL", 0x00462 }, + { "ga", 0x0003C }, + { "ga-IE", 0x0083C }, + { "gd", 0x00091 }, + { "gd-GB", 0x00491 }, + { "gl", 0x00056 }, + { "gl-ES", 0x00456 }, + { "gn", 0x00074 }, + { "gn-PY", 0x00474 }, + { "gsw", 0x00084 }, + { "gsw-FR", 0x00484 }, + { "gu", 0x00047 }, + { "gu-IN", 0x00447 }, + { "ha", 0x00068 }, + { "ha-Latn", 0x07C68 }, + { "ha-Latn-NG", 0x00468 }, + { "haw", 0x00075 }, + { "haw-US", 0x00475 }, + { "he", 0x0000D }, + { "he-IL", 0x0040D }, + { "hi", 0x00039 }, + { "hi-IN", 0x00439 }, + { "hr", 0x0001A }, + { "hr-BA", 0x0101A }, + { "hr-HR", 0x0041A }, + { "hsb", 0x0002E }, + { "hsb-DE", 0x0042E }, + { "hu", 0x0000E }, + { "hu-HU", 0x0040E }, + { "hu-HU_technl", 0x1040E }, + { "hy", 0x0002B }, + { "hy-AM", 0x0042B }, + { "ibb", 0x00069 }, // Doc: reserved + { "ibb-NG", 0x00469 }, // Doc: reserved + { "id", 0x00021 }, + { "id-ID", 0x00421 }, + { "ig", 0x00070 }, + { "ig-NG", 0x00470 }, + { "ii", 0x00078 }, + { "ii-CN", 0x00478 }, + { "is", 0x0000F }, + { "is-IS", 0x0040F }, + { "it", 0x00010 }, + { "it-CH", 0x00810 }, + { "it-IT", 0x00410 }, + { "iu", 0x0005D }, + { "iu-Cans", 0x0785D }, + { "iu-Cans-CA", 0x0045D }, + { "iu-Latn", 0x07C5D }, + { "iu-Latn-CA", 0x0085D }, + { "ja", 0x00011 }, + { "ja-JP", 0x00411 }, + { "ja-JP_radstr", 0x040411 }, + // { "ja-Ploc-JP", 0x00811 }, // reserved + { "ka", 0x00037 }, + { "ka-GE", 0x00437 }, + { "ka-GE_modern", 0x10437 }, + // { "khb-Talu-CN", 0x00490 }, // reserved + { "kk", 0x0003F }, + { "kk-Cyrl", 0x0003F | LCID_ALT_NAME }, // Doc: 0x0783F, reserved + { "kk-KZ", 0x0043F }, + // { "kk-Latn", 0x07C3F }, // reserved + // { "kk-Latn-KZ", 0x0083F }, // reserved + { "kl", 0x0006F }, + { "kl-GL", 0x0046F }, + { "km", 0x00053 }, + { "km-KH", 0x00453 }, + { "kn", 0x0004B }, + { "kn-IN", 0x0044B }, + { "ko", 0x00012 }, + { "ko-KR", 0x00412 }, + { "kok", 0x00057 }, + { "kok-IN", 0x00457 }, + { "kr", 0x00071 }, // Doc: reserved + { "kr-Latn-NG", 0x00471 }, + { "ks", 0x00060 }, + { "ks-Arab", 0x00460 }, // Neutral locale + { "ks-Deva-IN", 0x00860 }, + { "ku", 0x00092 }, + { "ku-Arab", 0x07C92 }, + { "ku-Arab-IQ", 0x00492 }, + { "ky", 0x00040 }, + { "ky-KG", 0x00440 }, + { "la", 0x00076 }, // reserved + { "la-001", 0x00476 }, // Doc: la-VA + { "lb", 0x0006E }, + { "lb-LU", 0x0046E }, + { "lo", 0x00054 }, + { "lo-LA", 0x00454 }, + { "lt", 0x00027 }, + { "lt-LT", 0x00427 }, + { "lv", 0x00026 }, + { "lv-LV", 0x00426 }, + { "mi", 0x00081 }, + { "mi-NZ", 0x00481 }, + { "mk", 0x0002F }, + { "mk-MK", 0x0042F }, + { "ml", 0x0004C }, + { "ml-IN", 0x0044C }, + { "mn", 0x00050 }, + { "mn-Cyrl", 0x07850 }, + { "mn-MN", 0x00450 }, + { "mn-Mong", 0x07C50 }, + { "mn-Mong-CN", 0x00850 }, // Doc: reserved + { "mn-Mong-MN", 0x00C50 }, + { "mni", 0x00058 }, // Doc: reserved + { "mni-IN", 0x00458 }, // Doc: reserved + { "moh", 0x0007C }, + { "moh-CA", 0x0047C }, + { "mr", 0x0004E }, + { "mr-IN", 0x0044E }, + { "ms", 0x0003E }, + { "ms-BN", 0x0083E }, + { "ms-MY", 0x0043E }, + { "mt", 0x0003A }, + { "mt-MT", 0x0043A }, + { "my", 0x00055 }, + { "my-MM", 0x00455 }, + { "nb", 0x07C14 }, + { "nb-NO", 0x00414 }, + { "ne", 0x00061 }, + { "ne-IN", 0x00861 }, + { "ne-NP", 0x00461 }, + { "nl", 0x00013 }, + { "nl-BE", 0x00813 }, + { "nl-NL", 0x00413 }, + { "nn", 0x07814 }, + { "nn-NO", 0x00814 }, + { "no", 0x00014 }, + { "nso", 0x0006C }, + { "nso-ZA", 0x0046C }, + { "oc", 0x00082 }, + { "oc-FR", 0x00482 }, + { "om", 0x00072 }, + { "om-ET", 0x00472 }, + { "or", 0x00048 }, + { "or-IN", 0x00448 }, + { "pa", 0x00046 }, + { "pa-Arab", 0x07C46 }, + { "pa-Arab-PK", 0x00846 }, + { "pa-IN", 0x00446 }, + { "pap", 0x00079 }, // Doc: reserved + { "pap-029", 0x00479 }, // Doc: reserved + { "pl", 0x00015 }, + { "pl-PL", 0x00415 }, + // { "plt-MG", 0x0048D }, // reserved + { "prs", 0x0008C }, + { "prs-AF", 0x0048C }, + { "ps", 0x00063 }, + { "ps-AF", 0x00463 }, + { "pt", 0x00016 }, + { "pt-BR", 0x00416 }, + { "pt-PT", 0x00816 }, + { "qps-ploc", 0x00501 }, + { "qps-ploca", 0x005FE }, + { "qps-plocm", 0x009FF }, + { "quc", 0x00086 }, // Doc: 0x00093, reserved + // { "quc-CO", 0x00493 }, // reserved + { "quc-Latn-GT", 0x00486 }, // Doc: qut-GT, reserved + { "qut", 0x00086 | LCID_ALT_NAME }, + { "qut-GT", 0x00486 | LCID_ALT_NAME }, // reserved + { "quz", 0x0006B }, + { "quz-BO", 0x0046B }, + { "quz-EC", 0x0086B }, + { "quz-PE", 0x00C6b }, + { "rm", 0x00017 }, + { "rm-CH", 0x00417 }, + { "ro", 0x00018 }, + { "ro-MD", 0x00818 }, + { "ro-RO", 0x00418 }, + { "ru", 0x00019 }, + { "ru-MD", 0x00819 }, + { "ru-RU", 0x00419 }, + { "rw", 0x00087 }, + { "rw-RW", 0x00487 }, + { "sa", 0x0004F }, + { "sa-IN", 0x0044F }, + { "sah", 0x00085 }, + { "sah-RU", 0x00485 }, + { "sd", 0x00059 }, + { "sd-Arab", 0x07C59 }, + { "sd-Arab-PK", 0x00859 }, + { "sd-Deva-IN", 0x00459 }, // Doc: reserved + { "se", 0x0003B }, + { "se-FI", 0x00C3B }, + { "se-NO", 0x0043B }, + { "se-SE", 0x0083B }, + { "si", 0x0005B }, + { "si-LK", 0x0045B }, + { "sk", 0x0001B }, + { "sk-SK", 0x0041B }, + { "sl", 0x00024 }, + { "sl-SI", 0x00424 }, + { "sma", 0x0783B }, + { "sma-NO", 0x0183B }, + { "sma-SE", 0x01C3B }, + { "smj", 0x07C3B }, + { "smj-NO", 0x0103B }, + { "smj-SE", 0x0143B }, + { "smn", 0x0703B }, + { "smn-FI", 0x0243B }, + { "sms", 0x0743B }, + { "sms-FI", 0x0203B }, + { "so", 0x00077 }, // Doc: reserved + { "so-SO", 0x00477 }, + { "sq", 0x0001C }, + { "sq-AL", 0x0041C }, + { "sr", 0x07C1A }, + { "sr-Cyrl", 0x06C1A }, + { "sr-Cyrl-BA", 0x01C1A }, + { "sr-Cyrl-CS", 0x00C1A }, + { "sr-Cyrl-ME", 0x0301A }, + { "sr-Cyrl-RS", 0x0281A }, + { "sr-Latn", 0x0701A }, + { "sr-Latn-BA", 0x0181A }, + { "sr-Latn-CS", 0x0081A }, + { "sr-Latn-ME", 0x02C1A }, + { "sr-Latn-RS", 0x0241A }, + { "st", 0x00030 }, + { "st-ZA", 0x00430 }, + { "sv", 0x0001D }, + { "sv-FI", 0x0081D }, + { "sv-SE", 0x0041D }, + { "sw", 0x00041 }, + { "sw-KE", 0x00441 }, + { "syr", 0x0005A }, + { "syr-SY", 0x0045A }, + { "ta", 0x00049 }, + { "ta-IN", 0x00449 }, + { "ta-LK", 0x00849 }, + // { "tdd-Tale-CN", 0x0048F }, // reserved + { "te", 0x0004A }, + { "te-IN", 0x0044A }, + { "tg", 0x00028 }, + { "tg-Cyrl", 0x07C28 }, + { "tg-Cyrl-TJ", 0x00428 }, + { "th", 0x0001E }, + { "th-TH", 0x0041E }, + { "ti", 0x00073 }, + { "ti-ER", 0x00873 }, + { "ti-ET", 0x00473 }, + { "tk", 0x00042 }, + { "tk-TM", 0x00442 }, + // { "tmz-MA", 0x00C5F }, // reserved + { "tn", 0x00032 }, + { "tn-BW", 0x00832 }, + { "tn-ZA", 0x00432 }, + { "tr", 0x0001F }, + { "tr-TR", 0x0041F }, + { "ts", 0x00031 }, + { "ts-ZA", 0x00431 }, + { "tt", 0x00044 }, + { "tt-RU", 0x00444 }, + { "tzm", 0x0005F }, + { "tzm-Arab-MA", 0x0045F }, + { "tzm-Latn", 0x07C5F }, + { "tzm-Latn-DZ", 0x0085F }, + { "tzm-Tfng", 0x0785F }, + { "tzm-Tfng-MA", 0x0105F }, + { "ug", 0x00080 }, + { "ug-CN", 0x00480 }, + { "uk", 0x00022 }, + { "uk-UA", 0x00422 }, + { "ur", 0x00020 }, + { "ur-IN", 0x00820 }, + { "ur-PK", 0x00420 }, + { "uz", 0x00043 }, + { "uz-Cyrl", 0x07843 }, + { "uz-Cyrl-UZ", 0x00843 }, // Doc: reserved + { "uz-Latn", 0x07C43 }, + { "uz-Latn-UZ", 0x00443 }, + { "ve", 0x00033 }, + { "ve-ZA", 0x00433 }, + { "vi", 0x0002A }, + { "vi-VN", 0x0042A }, + { "wo", 0x00088 }, + { "wo-SN", 0x00488 }, + { "xh", 0x00034 }, + { "xh-ZA", 0x00434 }, + { "yi", 0x0003D }, // Doc: reserved + { "yi-001", 0x0043D }, + { "yo", 0x0006A }, + { "yo-NG", 0x0046A }, + { "zh", 0x07804 }, + { "zh-CN", 0x00804 }, + { "zh-CN_stroke", 0x20804 }, + { "zh-Hans", 0x00004 }, + { "zh-Hant", 0x07C04 }, + { "zh-HK", 0x00C04 }, + { "zh-HK_radstr", 0x40C04 }, + { "zh-MO", 0x01404 }, + { "zh-MO_radstr", 0x41404 }, + { "zh-SG", 0x01004 }, + { "zh-SG_stroke", 0x21004 }, + { "zh-TW", 0x00404 }, + { "zh-TW_pronun", 0x30404 }, + { "zh-TW_radstr", 0x40404 }, + // { "zh-yue-HK", 0x0048E }, // reserved + { "zu", 0x00035 }, + { "zu-ZA", 0x00435 }, +}; + +// This table will be sorted by LCID at runtime +static USHORT RtlpLocaleIndexTable[_ARRAYSIZE(RtlpLocaleTable)]; + +typedef struct _SORT_ENTRY +{ + LCID Lcid; + USHORT Index; +} SORT_ENTRY, *PSORT_ENTRY; + +// Callback function for qsort to sort the SORT_ENTRY table by LCID +static int __cdecl LcidSortEntryCompare(const void* a, const void* b) +{ + PSORT_ENTRY SortEntryA = (PSORT_ENTRY)a; + PSORT_ENTRY SortEntryB = (PSORT_ENTRY)b; + return SortEntryA->Lcid - SortEntryB->Lcid; +} + +// +// Creates a temporary table, that maps the LCIDs to the index in the +// alphabetical table. This table is then sorted by LCID and the indices +// are used to create the final table. +// +NTSTATUS +NTAPI +RtlpInitializeLocaleTable(VOID) +{ + PSORT_ENTRY SortTable; + SIZE_T SortTableSize; + + NtQueryDefaultLocale(TRUE, &RtlpUserDefaultLcid); + NtQueryDefaultLocale(FALSE, &RtlpSystemDefaultLcid); + + SortTableSize = sizeof(SortTable[0]) * ARRAYSIZE(RtlpLocaleTable); + SortTable = RtlAllocateHeap(RtlGetProcessHeap(), 0, SortTableSize); + if (SortTable == NULL) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* Copy the LCIDs and the index */ + for (USHORT i = 0; i < ARRAYSIZE(RtlpLocaleTable); i++) + { + SortTable[i].Lcid = RtlpLocaleTable[i].Lcid; + SortTable[i].Index = i; + } + + /* Sort the table by LCID */ + qsort(SortTable, + ARRAYSIZE(RtlpLocaleTable), + sizeof(SortTable[0]), + LcidSortEntryCompare); + + /* Copy the sorted indices to the global table */ + for (USHORT i = 0; i < ARRAYSIZE(RtlpLocaleTable); i++) + { + RtlpLocaleIndexTable[i] = SortTable[i].Index; + } + + RtlFreeHeap(RtlGetProcessHeap(), 0, SortTable); + + return STATUS_SUCCESS; +} + +_Must_inspect_result_ +static +ULONG +FindIndexByLcid( + _In_ LCID Lcid) +{ + USHORT TableIndex; + LONG Low = 0; + LONG High = ARRAYSIZE(RtlpLocaleTable) - 1; + LONG Middle; + LCID CurrentLcid; + + while (Low <= High) + { + Middle = (Low + High) / 2; + + /* Use the indirection table to get the real table entry */ + TableIndex = RtlpLocaleIndexTable[Middle]; + ASSERT(TableIndex < ARRAYSIZE(RtlpLocaleTable)); + + /* Compare the LCID (including the alternative name flag!) */ + CurrentLcid = RtlpLocaleTable[TableIndex].Lcid; + if (CurrentLcid < Lcid) + { + Low = Middle + 1; + } + else if (CurrentLcid > Lcid) + { + High = Middle - 1; + } + else /* CurrentLcid == Lcid */ + { + return RtlpLocaleIndexTable[Middle]; + } + } + + return MAXULONG; +} + +#define LOWERCASE_CHAR(Char) \ + (((Char) >= 'A' && (Char) <= 'Z') ? ((Char) + ('a' - 'A')) : (Char)) + +_Must_inspect_result_ +static +INT +CompareLocaleNames( + _In_ PCSTR AsciiLocaleName, + _In_ PCUNICODE_STRING UnicodeLocaleName) +{ + ULONG i; + + /* Do a case-insensitive comparison. */ + for (i = 0; i < UnicodeLocaleName->Length / sizeof(WCHAR); i++) + { + /* Make the 2 chars lower case for comparison */ + CHAR Char1 = LOWERCASE_CHAR(AsciiLocaleName[i]); + WCHAR Char2 = LOWERCASE_CHAR(UnicodeLocaleName->Buffer[i]); + + /* Keep comparing, while they are equal */ + if (Char1 == Char2) + { + continue; + } + + /* Check if the ASCII string ends first */ + if (AsciiLocaleName[i] == '\0') + { + /* The 1st string is shorter than the 2nd, i.e. smaller */ + return -1; + } + + /* Return the difference between the two characters */ + return (INT)Char1 - (INT)Char2; + } + + /* The strings match up to the lenth of the unicode string. + If the ASCII string ends here, they are equal. */ + if (AsciiLocaleName[i] == '\0') + { + return 0; + } + + /* The 1st string is longer than the 2nd, i.e. larger */ + return 1; +} + +_Must_inspect_result_ +static +ULONG +FindIndexByLocaleName( + _In_ PCUNICODE_STRING LocaleName) +{ + LONG Low = 0; + LONG High = ARRAYSIZE(RtlpLocaleTable) - 1; + LONG Middle; + PCSTR CurrentLocaleName; + INT CompareResult; + + while (Low <= High) + { + Middle = (Low + High) / 2; + + CurrentLocaleName = RtlpLocaleTable[Middle].Locale; + CompareResult = CompareLocaleNames(CurrentLocaleName, LocaleName); + if (CompareResult < 0) + { + Low = Middle + 1; + } + else if (CompareResult > 0) + { + High = Middle - 1; + } + else /* CompareResult == 0 */ + { + return Middle; + } + } + + return MAXULONG; +} + +_Must_inspect_result_ +static +BOOLEAN +CopyAsciizToUnicodeString( + _Inout_ PUNICODE_STRING UnicodeString, + _In_ PCSTR AsciiString) +{ + SIZE_T AsciiLength = strlen(AsciiString); + + /* Make sure we can copy the full string, including the terminating 0 */ + if (UnicodeString->MaximumLength < (AsciiLength + 1) * sizeof(WCHAR)) + { + return FALSE; + } + + /* Copy the string manually */ + for (SIZE_T i = 0; i < AsciiLength; i++) + { + UnicodeString->Buffer[i] = (WCHAR)AsciiString[i]; + } + + /* Add the terminating 0 and update the Length */ + UnicodeString->Buffer[AsciiLength] = UNICODE_NULL; + UnicodeString->Length = (USHORT)(AsciiLength * sizeof(WCHAR)); + + return TRUE; +} + +static +BOOLEAN +IsNeutralLocale( + _In_ LCID Lcid) +{ + /* Check if the LCID is within the neutral locale range */ + if (((Lcid <= MAX_PRIMARY_LANGUAGE) && (Lcid != LOCALE_INVARIANT)) || + (Lcid == 0x0460) /* ks-Arab */ || + ((Lcid & 0xFFFF) > MAX_BASIC_LCID)) + { + return TRUE; + } + + return FALSE; +} + +NTSTATUS +NTAPI +RtlLcidToLocaleName( + _In_ LCID Lcid, + _Inout_ PUNICODE_STRING LocaleName, + _In_ ULONG Flags, + _In_ BOOLEAN AllocateDestinationString) +{ + ULONG LocaleIndex; + + /* Check for invalid flags */ + if (Flags & ~0x2) + { + DPRINT1("RtlLcidToLocaleName: Invalid flags: 0x%lx\n", Flags); + return STATUS_INVALID_PARAMETER_3; + } + + /* Check if the LocaleName buffer is valid */ + if ((LocaleName == NULL) || (LocaleName->Buffer == NULL)) + { + DPRINT1("RtlLcidToLocaleName: Invalid buffer\n"); + return STATUS_INVALID_PARAMETER_2; + } + + /* Validate LCID */ + if (Lcid & ~NLS_VALID_LOCALE_MASK) + { + DPRINT1("RtlLcidToLocaleName: Invalid LCID: 0x%lx\n", Lcid); + return STATUS_INVALID_PARAMETER_1; + } + + /* Check if neutral locales were requested */ + if ((Flags & RTL_LOCALE_ALLOW_NEUTRAL_NAMES) == 0) + { + /* Check if this is a neutral locale */ + if (IsNeutralLocale(Lcid)) + { + DPRINT("RtlLcidToLocaleName: Neutral LCID: 0x%lx\n", Lcid); + return STATUS_INVALID_PARAMETER_1; + } + } + + /* Handle special LCIDs */ + switch (Lcid) + { + case LOCALE_USER_DEFAULT: + Lcid = RtlpUserDefaultLcid; + break; + + case LOCALE_SYSTEM_DEFAULT: + case LOCALE_CUSTOM_DEFAULT: + Lcid = RtlpSystemDefaultLcid; + break; + + case LOCALE_CUSTOM_UI_DEFAULT: + return STATUS_UNSUCCESSFUL; + } + + /* Try to find the locale by LCID */ + LocaleIndex = FindIndexByLcid(Lcid); + if (LocaleIndex == MAXULONG) + { + DPRINT("RtlLcidToLocaleName: LCID 0x%lx not found\n", Lcid); + return STATUS_INVALID_PARAMETER_1; + } + + /* Copy the locale name to the buffer */ + if (!CopyAsciizToUnicodeString(LocaleName, RtlpLocaleTable[LocaleIndex].Locale)) + { + DPRINT("RtlLcidToLocaleName: Buffer too small\n"); + return STATUS_BUFFER_TOO_SMALL; + } + + return STATUS_SUCCESS; +} + +_Must_inspect_result_ +static +NTSTATUS +RtlpLocaleNameToLcidInternal( + _In_ PCUNICODE_STRING LocaleName, + _Out_ PLCID Lcid, + _In_ ULONG Flags) +{ + ULONG LocaleIndex; + LCID FoundLcid; + + /* Check if LocaleName points to a valid unicode string */ + if ((LocaleName == NULL) || (LocaleName->Buffer == NULL)) + { + DPRINT1("RtlpLocaleNameToLcidInternal: Invalid buffer\n"); + return STATUS_INVALID_PARAMETER_1; + } + + /* Check if the Lcid pointer is valid */ + if (Lcid == NULL) + { + DPRINT1("RtlpLocaleNameToLcidInternal: Lcid is NULL\n"); + return STATUS_INVALID_PARAMETER_2; + } + + /* Check for invalid flags */ + if (Flags & ~0x3) + { + DPRINT1("RtlpLocaleNameToLcidInternal: Invalid flags: 0x%lx\n", Flags); + return STATUS_INVALID_PARAMETER_3; + } + + /* Try to find the locale */ + LocaleIndex = FindIndexByLocaleName(LocaleName); + if (LocaleIndex == MAXULONG) + { + DPRINT("RtlpLocaleNameToLcidInternal: Locale name not found\n"); + return STATUS_INVALID_PARAMETER_1; + } + + /* Extract the LCID without the flags */ + FoundLcid = RtlpLocaleTable[LocaleIndex].Lcid & NLS_VALID_LOCALE_MASK; + + /* Check if neutral locales were requested */ + if ((Flags & RTL_LOCALE_ALLOW_NEUTRAL_NAMES) == 0) + { + /* Check if this is a neutral locale */ + if (IsNeutralLocale(FoundLcid)) + { + DPRINT("RtlpLocaleNameToLcidInternal: Neutral LCID: 0x%lx\n", FoundLcid); + return STATUS_INVALID_PARAMETER_1; + } + } + + /* Copy the LCID to the output buffer */ + *Lcid = FoundLcid; + + return STATUS_SUCCESS; +} + + +NTSTATUS +NTAPI +RtlLocaleNameToLcid( + _In_ PCWSTR LocaleName, + _Out_ PLCID Lcid, + _In_ ULONG Flags) +{ + UNICODE_STRING LocaleNameString; + + /* Convert the string to a UNICODE_STRING */ + RtlInitUnicodeString(&LocaleNameString, LocaleName); + + /* Forward to internal function */ + return RtlpLocaleNameToLcidInternal(&LocaleNameString, Lcid, Flags); +} + +_Success_(return != FALSE) +BOOLEAN +NTAPI +RtlLCIDToCultureName( + _In_ LCID Lcid, + _Inout_ PUNICODE_STRING String) +{ + NTSTATUS Status; + + /* Forward to RtlLcidToLocaleName, include neutral names */ + Status = RtlLcidToLocaleName(Lcid, String, RTL_LOCALE_ALLOW_NEUTRAL_NAMES, FALSE); + if (!NT_SUCCESS(Status)) + { + DPRINT1("RtlLcidToLocaleName failed with status 0x%lx\n", Status); + return FALSE; + } + + return TRUE; +} + +_Success_(return != FALSE) +BOOLEAN +NTAPI +RtlCultureNameToLCID( + _In_ PCUNICODE_STRING String, + _Out_ PLCID Lcid) +{ + NTSTATUS Status; + + if ((String == NULL) || + (String->Buffer == NULL) || + (String->Buffer[0] == UNICODE_NULL)) + { + return FALSE; + } + + /* Forward to internal function, include neutral names */ + Status = RtlpLocaleNameToLcidInternal(String, Lcid, RTL_LOCALE_ALLOW_NEUTRAL_NAMES); + if (!NT_SUCCESS(Status)) + { + DPRINT1("RtlpLocaleNameToLcidInternal failed with status 0x%lx\n", Status); + return FALSE; + } + + return TRUE; +} + +BOOLEAN +NTAPI +RtlIsValidLocaleName( + _In_ LPCWSTR LocaleName, + _In_ ULONG Flags) +{ + UNIMPLEMENTED; + return TRUE; +} + +NTSTATUS +NTAPI +RtlConvertLCIDToString( + _In_ LCID LcidValue, + _In_ ULONG Base, + _In_ ULONG Padding, + _Out_writes_(Size) PWSTR pResultBuf, + _In_ ULONG Size) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} diff --git a/sdk/lib/rtl/path.c b/sdk/lib/rtl/path.c index e045e16ebb48a..4104daeb838e6 100644 --- a/sdk/lib/rtl/path.c +++ b/sdk/lib/rtl/path.c @@ -2571,8 +2571,8 @@ RtlDosSearchPath_Ustr(IN ULONG Flags, NTSTATUS Status; RTL_PATH_TYPE PathType; PWCHAR p, End, CandidateEnd, SegmentEnd; - SIZE_T SegmentSize, ByteCount, PathSize, MaxPathSize = 0; - USHORT NamePlusExtLength, WorstCaseLength, ExtensionLength = 0; + SIZE_T WorstCaseLength, NamePlusExtLength, SegmentSize, ByteCount, PathSize, MaxPathSize = 0; + USHORT ExtensionLength = 0; PUNICODE_STRING FullIsolatedPath; DPRINT("DOS Path Search: %lx %wZ %wZ %wZ %wZ %wZ\n", Flags, PathString, FileNameString, ExtensionString, CallerBuffer, DynamicString); @@ -2669,7 +2669,8 @@ RtlDosSearchPath_Ustr(IN ULONG Flags, while (End > FileNameString->Buffer) { /* If we find a path separator, there's no extension */ - if (IS_PATH_SEPARATOR(*--End)) break; + --End; + if (IS_PATH_SEPARATOR(*End)) break; /* Otherwise, did we find an extension dot? */ if (*End == L'.') @@ -2689,17 +2690,20 @@ RtlDosSearchPath_Ustr(IN ULONG Flags, /* Start parsing the path name, looking for path separators */ End = &PathString->Buffer[PathString->Length / sizeof(WCHAR)]; p = End; - while ((p > PathString->Buffer) && (*--p == L';')) + while (p > PathString->Buffer) { - /* This is the size of the path -- handle a trailing slash */ - PathSize = End - p - 1; - if ((PathSize) && !(IS_PATH_SEPARATOR(*(End - 1)))) PathSize++; + if (*--p == L';') + { + /* This is the size of the path -- handle a trailing slash */ + PathSize = End - p - 1; + if ((PathSize) && !(IS_PATH_SEPARATOR(*(End - 1)))) PathSize++; - /* Check if we found a bigger path than before */ - if (PathSize > MaxPathSize) MaxPathSize = PathSize; + /* Check if we found a bigger path than before */ + if (PathSize > MaxPathSize) MaxPathSize = PathSize; - /* Keep going with the path after this path separator */ - End = p; + /* Keep going with the path after this path separator */ + End = p; + } } /* This is the trailing path, run the same code as above */ @@ -2749,7 +2753,7 @@ RtlDosSearchPath_Ustr(IN ULONG Flags, /* Now check if our initial static buffer is too small */ if (StaticCandidateString.MaximumLength < - (SegmentSize + ExtensionLength + FileNameString->Length)) + (SegmentSize + ExtensionLength + FileNameString->Length + sizeof(UNICODE_NULL))) { /* At this point we should've been using our static buffer */ ASSERT(StaticCandidateString.Buffer == StaticCandidateBuffer); @@ -2784,8 +2788,7 @@ RtlDosSearchPath_Ustr(IN ULONG Flags, } /* Now allocate the dynamic string */ - StaticCandidateString.MaximumLength = FileNameString->Length + - WorstCaseLength; + StaticCandidateString.MaximumLength = WorstCaseLength; StaticCandidateString.Buffer = RtlpAllocateStringMemory(WorstCaseLength, TAG_USTR); if (!StaticCandidateString.Buffer) @@ -2832,6 +2835,7 @@ RtlDosSearchPath_Ustr(IN ULONG Flags, StaticCandidateString.Length = (USHORT)(CandidateEnd - StaticCandidateString.Buffer) * sizeof(WCHAR); + ASSERT(StaticCandidateString.Length < StaticCandidateString.MaximumLength); /* Check if this file exists */ DPRINT("BUFFER: %S\n", StaticCandidateString.Buffer); @@ -2901,7 +2905,8 @@ RtlDosSearchPath_Ustr(IN ULONG Flags, while (End > p) { /* If there's a path separator, there's no extension */ - if (IS_PATH_SEPARATOR(*--End)) break; + --End; + if (IS_PATH_SEPARATOR(*End)) break; /* Othwerwise, did we find an extension dot? */ if (*End == L'.') diff --git a/sdk/lib/rtl/rtl.h b/sdk/lib/rtl/rtl.h index 037b2ee2c9b93..d818fcad4dc08 100644 --- a/sdk/lib/rtl/rtl.h +++ b/sdk/lib/rtl/rtl.h @@ -56,6 +56,7 @@ /* Use intrinsics for x86 and x64 */ #if defined(_M_IX86) || defined(_M_AMD64) +#ifndef InterlockedCompareExchange #define InterlockedCompareExchange _InterlockedCompareExchange #define InterlockedIncrement _InterlockedIncrement #define InterlockedDecrement _InterlockedDecrement @@ -64,5 +65,6 @@ #define InterlockedBitTestAndSet _interlockedbittestandset #define InterlockedBitTestAndSet64 _interlockedbittestandset64 #endif +#endif #endif /* RTL_H */ diff --git a/sdk/lib/rtl/threadpool.c b/sdk/lib/rtl/threadpool.c new file mode 100644 index 0000000000000..efdfa45461830 --- /dev/null +++ b/sdk/lib/rtl/threadpool.c @@ -0,0 +1,3517 @@ +/* + * Thread pooling + * + * Copyright (c) 2006 Robert Shearman + * Copyright (c) 2014-2016 Sebastian Lackner + * + * 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 + */ + + +#ifdef __REACTOS__ +#include +#define NDEBUG +#include "wine/list.h" +#include + +#define ERR(fmt, ...) DPRINT1(fmt, ##__VA_ARGS__) +#define FIXME(fmt, ...) DPRINT(fmt, ##__VA_ARGS__) +#define WARN(fmt, ...) DPRINT(fmt, ##__VA_ARGS__) +#define TRACE(fmt, ...) DPRINT(fmt, ##__VA_ARGS__) +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(_x) (sizeof((_x))/sizeof((_x)[0])) +#endif + +typedef struct _THREAD_NAME_INFORMATION +{ + UNICODE_STRING ThreadName; +} THREAD_NAME_INFORMATION, *PTHREAD_NAME_INFORMATION; + +typedef void (CALLBACK *PNTAPCFUNC)(ULONG_PTR,ULONG_PTR,ULONG_PTR); +typedef void (CALLBACK *PRTL_THREAD_START_ROUTINE)(LPVOID); +typedef DWORD (CALLBACK *PRTL_WORK_ITEM_ROUTINE)(LPVOID); +typedef void (NTAPI *RTL_WAITORTIMERCALLBACKFUNC)(PVOID,BOOLEAN); +typedef VOID (CALLBACK *PRTL_OVERLAPPED_COMPLETION_ROUTINE)(DWORD,DWORD,LPVOID); + +typedef void (CALLBACK *PTP_IO_CALLBACK)(PTP_CALLBACK_INSTANCE,void*,void*,IO_STATUS_BLOCK*,PTP_IO); +NTSYSAPI NTSTATUS WINAPI TpSimpleTryPost(PTP_SIMPLE_CALLBACK,PVOID,TP_CALLBACK_ENVIRON *); +#define PRTL_WORK_ITEM_ROUTINE WORKERCALLBACKFUNC + +#define CRITICAL_SECTION RTL_CRITICAL_SECTION +#define GetProcessHeap() RtlGetProcessHeap() +#define GetCurrentProcess() NtCurrentProcess() +#define GetCurrentThread() NtCurrentThread() +#define GetCurrentThreadId() HandleToULong(NtCurrentTeb()->ClientId.UniqueThread) +#else +#include +#include +#include + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "winternl.h" + +#include "wine/debug.h" +#include "wine/list.h" + +#include "ntdll_misc.h" + +WINE_DEFAULT_DEBUG_CHANNEL(threadpool); +#endif + +/* + * Old thread pooling API + */ + +struct rtl_work_item +{ + PRTL_WORK_ITEM_ROUTINE function; + PVOID context; +}; + +#define EXPIRE_NEVER (~(ULONGLONG)0) +#define TIMER_QUEUE_MAGIC 0x516d6954 /* TimQ */ + +#ifndef __REACTOS__ +static RTL_CRITICAL_SECTION_DEBUG critsect_compl_debug; +#endif + +static struct +{ + HANDLE compl_port; + RTL_CRITICAL_SECTION threadpool_compl_cs; +} +old_threadpool = +{ + NULL, /* compl_port */ +#ifdef __REACTOS__ + {0}, /* threadpool_compl_cs */ +#else + { &critsect_compl_debug, -1, 0, 0, 0, 0 }, /* threadpool_compl_cs */ +#endif +}; + +#ifndef __REACTOS__ +static RTL_CRITICAL_SECTION_DEBUG critsect_compl_debug = +{ + 0, 0, &old_threadpool.threadpool_compl_cs, + { &critsect_compl_debug.ProcessLocksList, &critsect_compl_debug.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": threadpool_compl_cs") } +}; +#endif + +struct timer_queue; +struct queue_timer +{ + struct timer_queue *q; + struct list entry; + ULONG runcount; /* number of callbacks pending execution */ + RTL_WAITORTIMERCALLBACKFUNC callback; + PVOID param; + DWORD period; + ULONG flags; + ULONGLONG expire; + BOOL destroy; /* timer should be deleted; once set, never unset */ + HANDLE event; /* removal event */ +}; + +struct timer_queue +{ + DWORD magic; + RTL_CRITICAL_SECTION cs; + struct list timers; /* sorted by expiration time */ + BOOL quit; /* queue should be deleted; once set, never unset */ + HANDLE event; + HANDLE thread; +}; + +/* + * Object-oriented thread pooling API + */ + +#define THREADPOOL_WORKER_TIMEOUT 5000 +#define MAXIMUM_WAITQUEUE_OBJECTS (MAXIMUM_WAIT_OBJECTS - 1) + +/* internal threadpool representation */ +struct threadpool +{ + LONG refcount; + LONG objcount; + BOOL shutdown; + CRITICAL_SECTION cs; + /* Pools of work items, locked via .cs, order matches TP_CALLBACK_PRIORITY - high, normal, low. */ + struct list pools[3]; + RTL_CONDITION_VARIABLE update_event; + /* information about worker threads, locked via .cs */ + int max_workers; + int min_workers; + int num_workers; + int num_busy_workers; + HANDLE compl_port; + TP_POOL_STACK_INFORMATION stack_info; +}; + +enum threadpool_objtype +{ + TP_OBJECT_TYPE_SIMPLE, + TP_OBJECT_TYPE_WORK, + TP_OBJECT_TYPE_TIMER, + TP_OBJECT_TYPE_WAIT, + TP_OBJECT_TYPE_IO, +}; + +struct io_completion +{ + IO_STATUS_BLOCK iosb; + ULONG_PTR cvalue; +}; + +/* internal threadpool object representation */ +struct threadpool_object +{ + void *win32_callback; /* leave space for kernelbase to store win32 callback */ + LONG refcount; + BOOL shutdown; + /* read-only information */ + enum threadpool_objtype type; + struct threadpool *pool; + struct threadpool_group *group; + PVOID userdata; + PTP_CLEANUP_GROUP_CANCEL_CALLBACK group_cancel_callback; + PTP_SIMPLE_CALLBACK finalization_callback; + BOOL may_run_long; + HMODULE race_dll; + TP_CALLBACK_PRIORITY priority; + /* information about the group, locked via .group->cs */ + struct list group_entry; + BOOL is_group_member; + /* information about the pool, locked via .pool->cs */ + struct list pool_entry; + RTL_CONDITION_VARIABLE finished_event; + RTL_CONDITION_VARIABLE group_finished_event; + HANDLE completed_event; + LONG num_pending_callbacks; + LONG num_running_callbacks; + LONG num_associated_callbacks; + /* arguments for callback */ + union + { + struct + { + PTP_SIMPLE_CALLBACK callback; + } simple; + struct + { + PTP_WORK_CALLBACK callback; + } work; + struct + { + PTP_TIMER_CALLBACK callback; + /* information about the timer, locked via timerqueue.cs */ + BOOL timer_initialized; + BOOL timer_pending; + struct list timer_entry; + BOOL timer_set; + ULONGLONG timeout; + LONG period; + LONG window_length; + } timer; + struct + { + PTP_WAIT_CALLBACK callback; + LONG signaled; + /* information about the wait object, locked via waitqueue.cs */ + struct waitqueue_bucket *bucket; + BOOL wait_pending; + struct list wait_entry; + ULONGLONG timeout; + HANDLE handle; + DWORD flags; + RTL_WAITORTIMERCALLBACKFUNC rtl_callback; + } wait; + struct + { + PTP_IO_CALLBACK callback; + /* locked via .pool->cs */ + unsigned int pending_count, skipped_count, completion_count, completion_max; + BOOL shutting_down; + struct io_completion *completions; + } io; + } u; +}; + +/* internal threadpool instance representation */ +struct threadpool_instance +{ + struct threadpool_object *object; + DWORD threadid; + BOOL associated; + BOOL may_run_long; + struct + { + CRITICAL_SECTION *critical_section; + HANDLE mutex; + HANDLE semaphore; + LONG semaphore_count; + HANDLE event; + HMODULE library; + } cleanup; +}; + +/* internal threadpool group representation */ +struct threadpool_group +{ + LONG refcount; + BOOL shutdown; + CRITICAL_SECTION cs; + /* list of group members, locked via .cs */ + struct list members; +}; + +#ifndef __REACTOS__ +/* global timerqueue object */ +static RTL_CRITICAL_SECTION_DEBUG timerqueue_debug; +#endif + +static struct +{ + CRITICAL_SECTION cs; + LONG objcount; + BOOL thread_running; + struct list pending_timers; + RTL_CONDITION_VARIABLE update_event; +} +timerqueue = +{ +#ifdef __REACTOS__ + {0}, /* cs */ +#else + { &timerqueue_debug, -1, 0, 0, 0, 0 }, /* cs */ +#endif + 0, /* objcount */ + FALSE, /* thread_running */ + LIST_INIT( timerqueue.pending_timers ), /* pending_timers */ +#if __REACTOS__ + 0, +#else + RTL_CONDITION_VARIABLE_INIT /* update_event */ +#endif +}; + +#ifndef __REACTOS__ +static RTL_CRITICAL_SECTION_DEBUG timerqueue_debug = +{ + 0, 0, &timerqueue.cs, + { &timerqueue_debug.ProcessLocksList, &timerqueue_debug.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": timerqueue.cs") } +}; + +/* global waitqueue object */ +static RTL_CRITICAL_SECTION_DEBUG waitqueue_debug; +#endif + +static struct +{ + CRITICAL_SECTION cs; + LONG num_buckets; + struct list buckets; +} +waitqueue = +{ +#ifdef __REACTOS__ + {0}, /* cs */ +#else + { &waitqueue_debug, -1, 0, 0, 0, 0 }, /* cs */ +#endif + 0, /* num_buckets */ + LIST_INIT( waitqueue.buckets ) /* buckets */ +}; + +#ifndef __REACTOS__ +static RTL_CRITICAL_SECTION_DEBUG waitqueue_debug = +{ + 0, 0, &waitqueue.cs, + { &waitqueue_debug.ProcessLocksList, &waitqueue_debug.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": waitqueue.cs") } +}; +#endif + +struct waitqueue_bucket +{ + struct list bucket_entry; + LONG objcount; + struct list reserved; + struct list waiting; + HANDLE update_event; + BOOL alertable; +}; + +#ifndef __REACTOS__ +/* global I/O completion queue object */ +static RTL_CRITICAL_SECTION_DEBUG ioqueue_debug; +#endif + +static struct +{ + CRITICAL_SECTION cs; + LONG objcount; + BOOL thread_running; + HANDLE port; + RTL_CONDITION_VARIABLE update_event; +} +ioqueue = +{ +#ifdef __REACTOS__ + .cs = {0}, +#else + .cs = { &ioqueue_debug, -1, 0, 0, 0, 0 }, +#endif +}; + +#ifndef __REACTOS__ +static RTL_CRITICAL_SECTION_DEBUG ioqueue_debug = +{ + 0, 0, &ioqueue.cs, + { &ioqueue_debug.ProcessLocksList, &ioqueue_debug.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": ioqueue.cs") } +}; +#endif + +static inline struct threadpool *impl_from_TP_POOL( TP_POOL *pool ) +{ + return (struct threadpool *)pool; +} + +static inline struct threadpool_object *impl_from_TP_WORK( TP_WORK *work ) +{ + struct threadpool_object *object = (struct threadpool_object *)work; + assert( object->type == TP_OBJECT_TYPE_WORK ); + return object; +} + +static inline struct threadpool_object *impl_from_TP_TIMER( TP_TIMER *timer ) +{ + struct threadpool_object *object = (struct threadpool_object *)timer; + assert( object->type == TP_OBJECT_TYPE_TIMER ); + return object; +} + +static inline struct threadpool_object *impl_from_TP_WAIT( TP_WAIT *wait ) +{ + struct threadpool_object *object = (struct threadpool_object *)wait; + assert( object->type == TP_OBJECT_TYPE_WAIT ); + return object; +} + +static inline struct threadpool_object *impl_from_TP_IO( TP_IO *io ) +{ + struct threadpool_object *object = (struct threadpool_object *)io; + assert( object->type == TP_OBJECT_TYPE_IO ); + return object; +} + +static inline struct threadpool_group *impl_from_TP_CLEANUP_GROUP( TP_CLEANUP_GROUP *group ) +{ + return (struct threadpool_group *)group; +} + +static inline struct threadpool_instance *impl_from_TP_CALLBACK_INSTANCE( TP_CALLBACK_INSTANCE *instance ) +{ + return (struct threadpool_instance *)instance; +} + +#ifdef __REACTOS__ +ULONG NTAPI threadpool_worker_proc(PVOID param ); +#else +static void CALLBACK threadpool_worker_proc( void *param ); +#endif +static void tp_object_submit( struct threadpool_object *object, BOOL signaled ); +static void tp_object_execute( struct threadpool_object *object, BOOL wait_thread ); +static void tp_object_prepare_shutdown( struct threadpool_object *object ); +static BOOL tp_object_release( struct threadpool_object *object ); +static struct threadpool *default_threadpool = NULL; + +static BOOL array_reserve(void **elements, unsigned int *capacity, unsigned int count, unsigned int size) +{ + unsigned int new_capacity, max_capacity; + void *new_elements; + + if (count <= *capacity) + return TRUE; + + max_capacity = ~(SIZE_T)0 / size; + if (count > max_capacity) + return FALSE; + + new_capacity = max(4, *capacity); + while (new_capacity < count && new_capacity <= max_capacity / 2) + new_capacity *= 2; + if (new_capacity < count) + new_capacity = max_capacity; + + if (!(new_elements = RtlReAllocateHeap( GetProcessHeap(), 0, *elements, new_capacity * size ))) + return FALSE; + + *elements = new_elements; + *capacity = new_capacity; + + return TRUE; +} + +static void set_thread_name(const WCHAR *name) +{ +#ifndef __REACTOS__ // This is impossible on non vista+ + THREAD_NAME_INFORMATION info; + + RtlInitUnicodeString(&info.ThreadName, name); + NtSetInformationThread(GetCurrentThread(), ThreadNameInformation, &info, sizeof(info)); +#endif +} + +#ifndef __REACTOS__ +static void CALLBACK process_rtl_work_item( TP_CALLBACK_INSTANCE *instance, void *userdata ) +{ + struct rtl_work_item *item = userdata; + + TRACE("executing %p(%p)\n", item->function, item->context); + item->function( item->context ); + + RtlFreeHeap( GetProcessHeap(), 0, item ); +} + +/*********************************************************************** + * RtlQueueWorkItem (NTDLL.@) + * + * Queues a work item into a thread in the thread pool. + * + * PARAMS + * function [I] Work function to execute. + * context [I] Context to pass to the work function when it is executed. + * flags [I] Flags. See notes. + * + * RETURNS + * Success: STATUS_SUCCESS. + * Failure: Any NTSTATUS code. + * + * NOTES + * Flags can be one or more of the following: + *|WT_EXECUTEDEFAULT - Executes the work item in a non-I/O worker thread. + *|WT_EXECUTEINIOTHREAD - Executes the work item in an I/O worker thread. + *|WT_EXECUTEINPERSISTENTTHREAD - Executes the work item in a thread that is persistent. + *|WT_EXECUTELONGFUNCTION - Hints that the execution can take a long time. + *|WT_TRANSFER_IMPERSONATION - Executes the function with the current access token. + */ +NTSTATUS WINAPI RtlQueueWorkItem( PRTL_WORK_ITEM_ROUTINE function, PVOID context, ULONG flags ) +{ + TP_CALLBACK_ENVIRON environment; + struct rtl_work_item *item; + NTSTATUS status; + + TRACE( "%p %p %lu\n", function, context, flags ); + + item = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*item) ); + if (!item) + return STATUS_NO_MEMORY; + + memset( &environment, 0, sizeof(environment) ); + environment.Version = 1; + environment.u.s.LongFunction = (flags & WT_EXECUTELONGFUNCTION) != 0; + environment.u.s.Persistent = (flags & WT_EXECUTEINPERSISTENTTHREAD) != 0; + + item->function = function; + item->context = context; + + status = TpSimpleTryPost( process_rtl_work_item, item, &environment ); + if (status) RtlFreeHeap( GetProcessHeap(), 0, item ); + return status; +} + +/*********************************************************************** + * iocp_poller - get completion events and run callbacks + */ +static DWORD CALLBACK iocp_poller(LPVOID Arg) +{ + HANDLE cport = Arg; + + while( TRUE ) + { + PRTL_OVERLAPPED_COMPLETION_ROUTINE callback; + LPVOID overlapped; + IO_STATUS_BLOCK iosb; +#ifdef __REACTOS__ + NTSTATUS res = NtRemoveIoCompletion( cport, (PVOID)&callback, (PVOID)&overlapped, &iosb, NULL ); +#else + NTSTATUS res = NtRemoveIoCompletion( cport, (PULONG_PTR)&callback, (PULONG_PTR)&overlapped, &iosb, NULL ); +#endif + if (res) + { + ERR("NtRemoveIoCompletion failed: 0x%lx\n", res); + } + else + { + DWORD transferred = 0; + DWORD err = 0; + + if (iosb.Status == STATUS_SUCCESS) + transferred = iosb.Information; + else + err = RtlNtStatusToDosError(iosb.Status); + + callback( err, transferred, overlapped ); + } + } + return 0; +} + +/*********************************************************************** + * RtlSetIoCompletionCallback (NTDLL.@) + * + * Binds a handle to a thread pool's completion port, and possibly + * starts a non-I/O thread to monitor this port and call functions back. + * + * PARAMS + * FileHandle [I] Handle to bind to a completion port. + * Function [I] Callback function to call on I/O completions. + * Flags [I] Not used. + * + * RETURNS + * Success: STATUS_SUCCESS. + * Failure: Any NTSTATUS code. + * + */ +NTSTATUS WINAPI RtlSetIoCompletionCallback(HANDLE FileHandle, PRTL_OVERLAPPED_COMPLETION_ROUTINE Function, ULONG Flags) +{ + IO_STATUS_BLOCK iosb; + FILE_COMPLETION_INFORMATION info; + + if (Flags) FIXME("Unknown value Flags=0x%lx\n", Flags); + + if (!old_threadpool.compl_port) + { + NTSTATUS res = STATUS_SUCCESS; + + RtlEnterCriticalSection(&old_threadpool.threadpool_compl_cs); + if (!old_threadpool.compl_port) + { + HANDLE cport; + + res = NtCreateIoCompletion( &cport, IO_COMPLETION_ALL_ACCESS, NULL, 0 ); + if (!res) + { + /* FIXME native can start additional threads in case of e.g. hung callback function. */ + res = RtlQueueWorkItem( iocp_poller, cport, WT_EXECUTEDEFAULT ); + if (!res) + old_threadpool.compl_port = cport; + else + NtClose( cport ); + } + } + RtlLeaveCriticalSection(&old_threadpool.threadpool_compl_cs); + if (res) return res; + } + + info.CompletionPort = old_threadpool.compl_port; + info.CompletionKey = (ULONG_PTR)Function; + + return NtSetInformationFile( FileHandle, &iosb, &info, sizeof(info), FileCompletionInformation ); +} +#endif + +static inline PLARGE_INTEGER get_nt_timeout( PLARGE_INTEGER pTime, ULONG timeout ) +{ + if (timeout == INFINITE) return NULL; + pTime->QuadPart = (ULONGLONG)timeout * -10000; + return pTime; +} + +/************************** Timer Queue Impl **************************/ + +static void queue_remove_timer(struct queue_timer *t) +{ + /* We MUST hold the queue cs while calling this function. This ensures + that we cannot queue another callback for this timer. The runcount + being zero makes sure we don't have any already queued. */ + struct timer_queue *q = t->q; + + assert(t->runcount == 0); + assert(t->destroy); + + list_remove(&t->entry); + if (t->event) + NtSetEvent(t->event, NULL); + RtlFreeHeap(GetProcessHeap(), 0, t); + + if (q->quit && list_empty(&q->timers)) + NtSetEvent(q->event, NULL); +} + +static void timer_cleanup_callback(struct queue_timer *t) +{ + struct timer_queue *q = t->q; + RtlEnterCriticalSection(&q->cs); + + assert(0 < t->runcount); + --t->runcount; + + if (t->destroy && t->runcount == 0) + queue_remove_timer(t); + + RtlLeaveCriticalSection(&q->cs); +} + +static DWORD WINAPI timer_callback_wrapper(LPVOID p) +{ + struct queue_timer *t = p; + t->callback(t->param, TRUE); + timer_cleanup_callback(t); + return 0; +} + +static inline ULONGLONG queue_current_time(void) +{ + LARGE_INTEGER now, freq; + NtQueryPerformanceCounter(&now, &freq); + return now.QuadPart * 1000 / freq.QuadPart; +} + +static void queue_add_timer(struct queue_timer *t, ULONGLONG time, + BOOL set_event) +{ + /* We MUST hold the queue cs while calling this function. */ + struct timer_queue *q = t->q; + struct list *ptr = &q->timers; + + assert(!q->quit || (t->destroy && time == EXPIRE_NEVER)); + + if (time != EXPIRE_NEVER) + LIST_FOR_EACH(ptr, &q->timers) + { + struct queue_timer *cur = LIST_ENTRY(ptr, struct queue_timer, entry); + if (time < cur->expire) + break; + } + list_add_before(ptr, &t->entry); + + t->expire = time; + + /* If we insert at the head of the list, we need to expire sooner + than expected. */ + if (set_event && &t->entry == list_head(&q->timers)) + NtSetEvent(q->event, NULL); +} + +static inline void queue_move_timer(struct queue_timer *t, ULONGLONG time, + BOOL set_event) +{ + /* We MUST hold the queue cs while calling this function. */ + list_remove(&t->entry); + queue_add_timer(t, time, set_event); +} + +static void queue_timer_expire(struct timer_queue *q) +{ + struct queue_timer *t = NULL; + + RtlEnterCriticalSection(&q->cs); + if (list_head(&q->timers)) + { + ULONGLONG now, next; + t = LIST_ENTRY(list_head(&q->timers), struct queue_timer, entry); + if (!t->destroy && t->expire <= ((now = queue_current_time()))) + { + ++t->runcount; + if (t->period) + { + next = t->expire + t->period; + /* avoid trigger cascade if overloaded / hibernated */ + if (next < now) + next = now + t->period; + } + else + next = EXPIRE_NEVER; + queue_move_timer(t, next, FALSE); + } + else + t = NULL; + } + RtlLeaveCriticalSection(&q->cs); + + if (t) + { + if (t->flags & WT_EXECUTEINTIMERTHREAD) + timer_callback_wrapper(t); + else + { + ULONG flags + = (t->flags + & (WT_EXECUTEINIOTHREAD | WT_EXECUTEINPERSISTENTTHREAD + | WT_EXECUTELONGFUNCTION | WT_TRANSFER_IMPERSONATION)); + NTSTATUS status = RtlQueueWorkItem(timer_callback_wrapper, t, flags); + if (status != STATUS_SUCCESS) + timer_cleanup_callback(t); + } + } +} + +static ULONG queue_get_timeout(struct timer_queue *q) +{ + struct queue_timer *t; + ULONG timeout = INFINITE; + + RtlEnterCriticalSection(&q->cs); + if (list_head(&q->timers)) + { + t = LIST_ENTRY(list_head(&q->timers), struct queue_timer, entry); + assert(!t->destroy || t->expire == EXPIRE_NEVER); + + if (t->expire != EXPIRE_NEVER) + { + ULONGLONG time = queue_current_time(); + timeout = t->expire < time ? 0 : t->expire - time; + } + } + RtlLeaveCriticalSection(&q->cs); + + return timeout; +} + +#ifdef __REACTOS__ +ULONG NTAPI timer_queue_thread_proc(PVOID p) +#else +static void WINAPI timer_queue_thread_proc(LPVOID p) +#endif +{ + struct timer_queue *q = p; + ULONG timeout_ms; + + set_thread_name(L"wine_threadpool_timer_queue"); + timeout_ms = INFINITE; + for (;;) + { + LARGE_INTEGER timeout; + NTSTATUS status; + BOOL done = FALSE; + + status = NtWaitForSingleObject( + q->event, FALSE, get_nt_timeout(&timeout, timeout_ms)); + + if (status == STATUS_WAIT_0) + { + /* There are two possible ways to trigger the event. Either + we are quitting and the last timer got removed, or a new + timer got put at the head of the list so we need to adjust + our timeout. */ + RtlEnterCriticalSection(&q->cs); + if (q->quit && list_empty(&q->timers)) + done = TRUE; + RtlLeaveCriticalSection(&q->cs); + } + else if (status == STATUS_TIMEOUT) + queue_timer_expire(q); + + if (done) + break; + + timeout_ms = queue_get_timeout(q); + } + + NtClose(q->event); + RtlDeleteCriticalSection(&q->cs); + q->magic = 0; + RtlFreeHeap(GetProcessHeap(), 0, q); + RtlExitUserThread( 0 ); +#ifdef __REACTOS__ + return STATUS_SUCCESS; +#endif +} + +static void queue_destroy_timer(struct queue_timer *t) +{ + /* We MUST hold the queue cs while calling this function. */ + t->destroy = TRUE; + if (t->runcount == 0) + /* Ensure a timer is promptly removed. If callbacks are pending, + it will be removed after the last one finishes by the callback + cleanup wrapper. */ + queue_remove_timer(t); + else + /* Make sure no destroyed timer masks an active timer at the head + of the sorted list. */ + queue_move_timer(t, EXPIRE_NEVER, FALSE); +} + +/*********************************************************************** + * RtlCreateTimerQueue (NTDLL.@) + * + * Creates a timer queue object and returns a handle to it. + * + * PARAMS + * NewTimerQueue [O] The newly created queue. + * + * RETURNS + * Success: STATUS_SUCCESS. + * Failure: Any NTSTATUS code. + */ +NTSTATUS WINAPI RtlCreateTimerQueue(PHANDLE NewTimerQueue) +{ + NTSTATUS status; + struct timer_queue *q = RtlAllocateHeap(GetProcessHeap(), 0, sizeof *q); + if (!q) + return STATUS_NO_MEMORY; + + RtlInitializeCriticalSection(&q->cs); + list_init(&q->timers); + q->quit = FALSE; + q->magic = TIMER_QUEUE_MAGIC; + status = NtCreateEvent(&q->event, EVENT_ALL_ACCESS, NULL, SynchronizationEvent, FALSE); + if (status != STATUS_SUCCESS) + { + RtlFreeHeap(GetProcessHeap(), 0, q); + return status; + } + status = RtlCreateUserThread(GetCurrentProcess(), NULL, FALSE, 0, 0, 0, + timer_queue_thread_proc, q, &q->thread, NULL); + if (status != STATUS_SUCCESS) + { + NtClose(q->event); + RtlFreeHeap(GetProcessHeap(), 0, q); + return status; + } + + *NewTimerQueue = q; + return STATUS_SUCCESS; +} + +/*********************************************************************** + * RtlDeleteTimerQueueEx (NTDLL.@) + * + * Deletes a timer queue object. + * + * PARAMS + * TimerQueue [I] The timer queue to destroy. + * CompletionEvent [I] If NULL, return immediately. If INVALID_HANDLE_VALUE, + * wait until all timers are finished firing before + * returning. Otherwise, return immediately and set the + * event when all timers are done. + * + * RETURNS + * Success: STATUS_SUCCESS if synchronous, STATUS_PENDING if not. + * Failure: Any NTSTATUS code. + */ +NTSTATUS WINAPI RtlDeleteTimerQueueEx(HANDLE TimerQueue, HANDLE CompletionEvent) +{ + struct timer_queue *q = TimerQueue; + struct queue_timer *t, *temp; + HANDLE thread; + NTSTATUS status; + + if (!q || q->magic != TIMER_QUEUE_MAGIC) + return STATUS_INVALID_HANDLE; + + thread = q->thread; + + RtlEnterCriticalSection(&q->cs); + q->quit = TRUE; + if (list_head(&q->timers)) + /* When the last timer is removed, it will signal the timer thread to + exit... */ + LIST_FOR_EACH_ENTRY_SAFE(t, temp, &q->timers, struct queue_timer, entry) + queue_destroy_timer(t); + else + /* However if we have none, we must do it ourselves. */ + NtSetEvent(q->event, NULL); + RtlLeaveCriticalSection(&q->cs); + + if (CompletionEvent == INVALID_HANDLE_VALUE) + { + NtWaitForSingleObject(thread, FALSE, NULL); + status = STATUS_SUCCESS; + } + else + { + if (CompletionEvent) + { + FIXME("asynchronous return on completion event unimplemented\n"); + NtWaitForSingleObject(thread, FALSE, NULL); + NtSetEvent(CompletionEvent, NULL); + } + status = STATUS_PENDING; + } + + NtClose(thread); + return status; +} + +static struct timer_queue *get_timer_queue(HANDLE TimerQueue) +{ + static struct timer_queue *default_timer_queue; + + if (TimerQueue) + return TimerQueue; + else + { + if (!default_timer_queue) + { + HANDLE q; + NTSTATUS status = RtlCreateTimerQueue(&q); + if (status == STATUS_SUCCESS) + { + PVOID p = InterlockedCompareExchangePointer( (void **) &default_timer_queue, q, NULL ); + if (p) + /* Got beat to the punch. */ + RtlDeleteTimerQueueEx(q, NULL); + } + } + return default_timer_queue; + } +} + +/*********************************************************************** + * RtlCreateTimer (NTDLL.@) + * + * Creates a new timer associated with the given queue. + * + * PARAMS + * TimerQueue [I] The queue to hold the timer. + * NewTimer [O] The newly created timer. + * Callback [I] The callback to fire. + * Parameter [I] The argument for the callback. + * DueTime [I] The delay, in milliseconds, before first firing the + * timer. + * Period [I] The period, in milliseconds, at which to fire the timer + * after the first callback. If zero, the timer will only + * fire once. It still needs to be deleted with + * RtlDeleteTimer. + * Flags [I] Flags controlling the execution of the callback. In + * addition to the WT_* thread pool flags (see + * RtlQueueWorkItem), WT_EXECUTEINTIMERTHREAD and + * WT_EXECUTEONLYONCE are supported. + * + * RETURNS + * Success: STATUS_SUCCESS. + * Failure: Any NTSTATUS code. + */ +NTSTATUS WINAPI RtlCreateTimer(HANDLE TimerQueue, HANDLE *NewTimer, + RTL_WAITORTIMERCALLBACKFUNC Callback, + PVOID Parameter, DWORD DueTime, DWORD Period, + ULONG Flags) +{ + NTSTATUS status; + struct queue_timer *t; + struct timer_queue *q = get_timer_queue(TimerQueue); + + if (!q) return STATUS_NO_MEMORY; + if (q->magic != TIMER_QUEUE_MAGIC) return STATUS_INVALID_HANDLE; + + t = RtlAllocateHeap(GetProcessHeap(), 0, sizeof *t); + if (!t) + return STATUS_NO_MEMORY; + + t->q = q; + t->runcount = 0; + t->callback = Callback; + t->param = Parameter; + t->period = Period; + t->flags = Flags; + t->destroy = FALSE; + t->event = NULL; + + status = STATUS_SUCCESS; + RtlEnterCriticalSection(&q->cs); + if (q->quit) + status = STATUS_INVALID_HANDLE; + else + queue_add_timer(t, queue_current_time() + DueTime, TRUE); + RtlLeaveCriticalSection(&q->cs); + + if (status == STATUS_SUCCESS) + *NewTimer = t; + else + RtlFreeHeap(GetProcessHeap(), 0, t); + + return status; +} + +/*********************************************************************** + * RtlUpdateTimer (NTDLL.@) + * + * Changes the time at which a timer expires. + * + * PARAMS + * TimerQueue [I] The queue that holds the timer. + * Timer [I] The timer to update. + * DueTime [I] The delay, in milliseconds, before next firing the timer. + * Period [I] The period, in milliseconds, at which to fire the timer + * after the first callback. If zero, the timer will not + * refire once. It still needs to be deleted with + * RtlDeleteTimer. + * + * RETURNS + * Success: STATUS_SUCCESS. + * Failure: Any NTSTATUS code. + */ +NTSTATUS WINAPI RtlUpdateTimer(HANDLE TimerQueue, HANDLE Timer, + DWORD DueTime, DWORD Period) +{ + struct queue_timer *t = Timer; + struct timer_queue *q = t->q; + + RtlEnterCriticalSection(&q->cs); + /* Can't change a timer if it was once-only or destroyed. */ + if (t->expire != EXPIRE_NEVER) + { + t->period = Period; + queue_move_timer(t, queue_current_time() + DueTime, TRUE); + } + RtlLeaveCriticalSection(&q->cs); + + return STATUS_SUCCESS; +} + +/*********************************************************************** + * RtlDeleteTimer (NTDLL.@) + * + * Cancels a timer-queue timer. + * + * PARAMS + * TimerQueue [I] The queue that holds the timer. + * Timer [I] The timer to update. + * CompletionEvent [I] If NULL, return immediately. If INVALID_HANDLE_VALUE, + * wait until the timer is finished firing all pending + * callbacks before returning. Otherwise, return + * immediately and set the timer is done. + * + * RETURNS + * Success: STATUS_SUCCESS if the timer is done, STATUS_PENDING if not, + or if the completion event is NULL. + * Failure: Any NTSTATUS code. + */ +NTSTATUS WINAPI RtlDeleteTimer(HANDLE TimerQueue, HANDLE Timer, + HANDLE CompletionEvent) +{ + struct queue_timer *t = Timer; + struct timer_queue *q; + NTSTATUS status = STATUS_PENDING; + HANDLE event = NULL; + + if (!Timer) + return STATUS_INVALID_PARAMETER_1; + q = t->q; + if (CompletionEvent == INVALID_HANDLE_VALUE) + { + status = NtCreateEvent(&event, EVENT_ALL_ACCESS, NULL, SynchronizationEvent, FALSE); + if (status == STATUS_SUCCESS) + status = STATUS_PENDING; + } + else if (CompletionEvent) + event = CompletionEvent; + + RtlEnterCriticalSection(&q->cs); + t->event = event; + if (t->runcount == 0 && event) + status = STATUS_SUCCESS; + queue_destroy_timer(t); + RtlLeaveCriticalSection(&q->cs); + + if (CompletionEvent == INVALID_HANDLE_VALUE && event) + { + if (status == STATUS_PENDING) + { + NtWaitForSingleObject(event, FALSE, NULL); + status = STATUS_SUCCESS; + } + NtClose(event); + } + + return status; +} + +/*********************************************************************** + * timerqueue_thread_proc (internal) + */ +#ifdef __REACTOS__ +ULONG NTAPI timerqueue_thread_proc(PVOID param ) +#else +static void CALLBACK timerqueue_thread_proc( void *param ) +#endif +{ + ULONGLONG timeout_lower, timeout_upper, new_timeout; + struct threadpool_object *other_timer; + LARGE_INTEGER now, timeout; + struct list *ptr; + + TRACE( "starting timer queue thread\n" ); + set_thread_name(L"wine_threadpool_timerqueue"); + + RtlEnterCriticalSection( &timerqueue.cs ); + for (;;) + { + NtQuerySystemTime( &now ); + + /* Check for expired timers. */ + while ((ptr = list_head( &timerqueue.pending_timers ))) + { + struct threadpool_object *timer = LIST_ENTRY( ptr, struct threadpool_object, u.timer.timer_entry ); + assert( timer->type == TP_OBJECT_TYPE_TIMER ); + assert( timer->u.timer.timer_pending ); + if (timer->u.timer.timeout > now.QuadPart) + break; + + /* Queue a new callback in one of the worker threads. */ + list_remove( &timer->u.timer.timer_entry ); + timer->u.timer.timer_pending = FALSE; + tp_object_submit( timer, FALSE ); + + /* Insert the timer back into the queue, except it's marked for shutdown. */ + if (timer->u.timer.period && !timer->shutdown) + { + timer->u.timer.timeout += (ULONGLONG)timer->u.timer.period * 10000; + if (timer->u.timer.timeout <= now.QuadPart) + timer->u.timer.timeout = now.QuadPart + 1; + + LIST_FOR_EACH_ENTRY( other_timer, &timerqueue.pending_timers, + struct threadpool_object, u.timer.timer_entry ) + { + assert( other_timer->type == TP_OBJECT_TYPE_TIMER ); + if (timer->u.timer.timeout < other_timer->u.timer.timeout) + break; + } + list_add_before( &other_timer->u.timer.timer_entry, &timer->u.timer.timer_entry ); + timer->u.timer.timer_pending = TRUE; + } + } + + timeout_lower = timeout_upper = MAXLONGLONG; + + /* Determine next timeout and use the window length to optimize wakeup times. */ + LIST_FOR_EACH_ENTRY( other_timer, &timerqueue.pending_timers, + struct threadpool_object, u.timer.timer_entry ) + { + assert( other_timer->type == TP_OBJECT_TYPE_TIMER ); + if (other_timer->u.timer.timeout >= timeout_upper) + break; + + timeout_lower = other_timer->u.timer.timeout; + new_timeout = timeout_lower + (ULONGLONG)other_timer->u.timer.window_length * 10000; + if (new_timeout < timeout_upper) + timeout_upper = new_timeout; + } + + /* Wait for timer update events or until the next timer expires. */ + if (timerqueue.objcount) + { + timeout.QuadPart = timeout_lower; + RtlSleepConditionVariableCS( &timerqueue.update_event, &timerqueue.cs, &timeout ); + continue; + } + + /* All timers have been destroyed, if no new timers are created + * within some amount of time, then we can shutdown this thread. */ + timeout.QuadPart = (ULONGLONG)THREADPOOL_WORKER_TIMEOUT * -10000; + if (RtlSleepConditionVariableCS( &timerqueue.update_event, &timerqueue.cs, + &timeout ) == STATUS_TIMEOUT && !timerqueue.objcount) + { + break; + } + } + + timerqueue.thread_running = FALSE; + RtlLeaveCriticalSection( &timerqueue.cs ); + + TRACE( "terminating timer queue thread\n" ); + RtlExitUserThread( 0 ); +#ifdef __REACTOS__ + return STATUS_SUCCESS; +#endif +} + +/*********************************************************************** + * tp_new_worker_thread (internal) + * + * Create and account a new worker thread for the desired pool. + */ +static NTSTATUS tp_new_worker_thread( struct threadpool *pool ) +{ + HANDLE thread; + NTSTATUS status; + + status = RtlCreateUserThread( GetCurrentProcess(), NULL, FALSE, 0, + pool->stack_info.StackReserve, pool->stack_info.StackCommit, + threadpool_worker_proc, pool, &thread, NULL ); + if (status == STATUS_SUCCESS) + { + InterlockedIncrement( &pool->refcount ); + pool->num_workers++; + NtClose( thread ); + } + return status; +} + +/*********************************************************************** + * tp_timerqueue_lock (internal) + * + * Acquires a lock on the global timerqueue. When the lock is acquired + * successfully, it is guaranteed that the timer thread is running. + */ +static NTSTATUS tp_timerqueue_lock( struct threadpool_object *timer ) +{ + NTSTATUS status = STATUS_SUCCESS; + assert( timer->type == TP_OBJECT_TYPE_TIMER ); + + timer->u.timer.timer_initialized = FALSE; + timer->u.timer.timer_pending = FALSE; + timer->u.timer.timer_set = FALSE; + timer->u.timer.timeout = 0; + timer->u.timer.period = 0; + timer->u.timer.window_length = 0; + + RtlEnterCriticalSection( &timerqueue.cs ); + + /* Make sure that the timerqueue thread is running. */ + if (!timerqueue.thread_running) + { + HANDLE thread; + status = RtlCreateUserThread( GetCurrentProcess(), NULL, FALSE, 0, 0, 0, + timerqueue_thread_proc, NULL, &thread, NULL ); + if (status == STATUS_SUCCESS) + { + timerqueue.thread_running = TRUE; + NtClose( thread ); + } + } + + if (status == STATUS_SUCCESS) + { + timer->u.timer.timer_initialized = TRUE; + timerqueue.objcount++; + } + + RtlLeaveCriticalSection( &timerqueue.cs ); + return status; +} + +/*********************************************************************** + * tp_timerqueue_unlock (internal) + * + * Releases a lock on the global timerqueue. + */ +static void tp_timerqueue_unlock( struct threadpool_object *timer ) +{ + assert( timer->type == TP_OBJECT_TYPE_TIMER ); + + RtlEnterCriticalSection( &timerqueue.cs ); + if (timer->u.timer.timer_initialized) + { + /* If timer was pending, remove it. */ + if (timer->u.timer.timer_pending) + { + list_remove( &timer->u.timer.timer_entry ); + timer->u.timer.timer_pending = FALSE; + } + + /* If the last timer object was destroyed, then wake up the thread. */ + if (!--timerqueue.objcount) + { + assert( list_empty( &timerqueue.pending_timers ) ); + RtlWakeAllConditionVariable( &timerqueue.update_event ); + } + + timer->u.timer.timer_initialized = FALSE; + } + RtlLeaveCriticalSection( &timerqueue.cs ); +} + +/*********************************************************************** + * waitqueue_thread_proc (internal) + */ +#ifdef __REACTOS__ +void NTAPI waitqueue_thread_proc(PVOID param ) +#else +static void CALLBACK waitqueue_thread_proc( void *param ) +#endif +{ + struct threadpool_object *objects[MAXIMUM_WAITQUEUE_OBJECTS]; + HANDLE handles[MAXIMUM_WAITQUEUE_OBJECTS + 1]; + struct waitqueue_bucket *bucket = param; + struct threadpool_object *wait, *next; + LARGE_INTEGER now, timeout; + DWORD num_handles; + NTSTATUS status; + + TRACE( "starting wait queue thread\n" ); + set_thread_name(L"wine_threadpool_waitqueue"); + + RtlEnterCriticalSection( &waitqueue.cs ); + + for (;;) + { + NtQuerySystemTime( &now ); + timeout.QuadPart = MAXLONGLONG; + num_handles = 0; + + LIST_FOR_EACH_ENTRY_SAFE( wait, next, &bucket->waiting, struct threadpool_object, + u.wait.wait_entry ) + { + assert( wait->type == TP_OBJECT_TYPE_WAIT ); + if (wait->u.wait.timeout <= now.QuadPart) + { + /* Wait object timed out. */ + if ((wait->u.wait.flags & WT_EXECUTEONLYONCE)) + { + list_remove( &wait->u.wait.wait_entry ); + list_add_tail( &bucket->reserved, &wait->u.wait.wait_entry ); + } + if ((wait->u.wait.flags & (WT_EXECUTEINWAITTHREAD | WT_EXECUTEINIOTHREAD))) + { + InterlockedIncrement( &wait->refcount ); + wait->num_pending_callbacks++; + RtlEnterCriticalSection( &wait->pool->cs ); + tp_object_execute( wait, TRUE ); + RtlLeaveCriticalSection( &wait->pool->cs ); + tp_object_release( wait ); + } + else tp_object_submit( wait, FALSE ); + } + else + { + if (wait->u.wait.timeout < timeout.QuadPart) + timeout.QuadPart = wait->u.wait.timeout; + + assert( num_handles < MAXIMUM_WAITQUEUE_OBJECTS ); + InterlockedIncrement( &wait->refcount ); + objects[num_handles] = wait; + handles[num_handles] = wait->u.wait.handle; + num_handles++; + } + } + + if (!bucket->objcount) + { + /* All wait objects have been destroyed, if no new wait objects are created + * within some amount of time, then we can shutdown this thread. */ + assert( num_handles == 0 ); + RtlLeaveCriticalSection( &waitqueue.cs ); + timeout.QuadPart = (ULONGLONG)THREADPOOL_WORKER_TIMEOUT * -10000; + status = NtWaitForMultipleObjects( 1, &bucket->update_event, TRUE, bucket->alertable, &timeout ); + RtlEnterCriticalSection( &waitqueue.cs ); + + if (status == STATUS_TIMEOUT && !bucket->objcount) + break; + } + else + { + handles[num_handles] = bucket->update_event; + RtlLeaveCriticalSection( &waitqueue.cs ); + status = NtWaitForMultipleObjects( num_handles + 1, handles, TRUE, bucket->alertable, &timeout ); + RtlEnterCriticalSection( &waitqueue.cs ); + + if (status >= STATUS_WAIT_0 && status < STATUS_WAIT_0 + num_handles) + { + wait = objects[status - STATUS_WAIT_0]; + assert( wait->type == TP_OBJECT_TYPE_WAIT ); + if (wait->u.wait.bucket) + { + /* Wait object signaled. */ + assert( wait->u.wait.bucket == bucket ); + if ((wait->u.wait.flags & WT_EXECUTEONLYONCE)) + { + list_remove( &wait->u.wait.wait_entry ); + list_add_tail( &bucket->reserved, &wait->u.wait.wait_entry ); + } + if ((wait->u.wait.flags & (WT_EXECUTEINWAITTHREAD | WT_EXECUTEINIOTHREAD))) + { + wait->u.wait.signaled++; + wait->num_pending_callbacks++; + RtlEnterCriticalSection( &wait->pool->cs ); + tp_object_execute( wait, TRUE ); + RtlLeaveCriticalSection( &wait->pool->cs ); + } + else tp_object_submit( wait, TRUE ); + } + else + WARN("wait object %p triggered while object was destroyed\n", wait); + } + + /* Release temporary references to wait objects. */ + while (num_handles) + { + wait = objects[--num_handles]; + assert( wait->type == TP_OBJECT_TYPE_WAIT ); + tp_object_release( wait ); + } + } + + /* Try to merge bucket with other threads. */ + if (waitqueue.num_buckets > 1 && bucket->objcount && + bucket->objcount <= MAXIMUM_WAITQUEUE_OBJECTS * 1 / 3) + { + struct waitqueue_bucket *other_bucket; + LIST_FOR_EACH_ENTRY( other_bucket, &waitqueue.buckets, struct waitqueue_bucket, bucket_entry ) + { + if (other_bucket != bucket && other_bucket->objcount && other_bucket->alertable == bucket->alertable && + other_bucket->objcount + bucket->objcount <= MAXIMUM_WAITQUEUE_OBJECTS * 2 / 3) + { + other_bucket->objcount += bucket->objcount; + bucket->objcount = 0; + + /* Update reserved list. */ + LIST_FOR_EACH_ENTRY( wait, &bucket->reserved, struct threadpool_object, u.wait.wait_entry ) + { + assert( wait->type == TP_OBJECT_TYPE_WAIT ); + wait->u.wait.bucket = other_bucket; + } + list_move_tail( &other_bucket->reserved, &bucket->reserved ); + + /* Update waiting list. */ + LIST_FOR_EACH_ENTRY( wait, &bucket->waiting, struct threadpool_object, u.wait.wait_entry ) + { + assert( wait->type == TP_OBJECT_TYPE_WAIT ); + wait->u.wait.bucket = other_bucket; + } + list_move_tail( &other_bucket->waiting, &bucket->waiting ); + + /* Move bucket to the end, to keep the probability of + * newly added wait objects as small as possible. */ + list_remove( &bucket->bucket_entry ); + list_add_tail( &waitqueue.buckets, &bucket->bucket_entry ); + + NtSetEvent( other_bucket->update_event, NULL ); + break; + } + } + } + } + + /* Remove this bucket from the list. */ + list_remove( &bucket->bucket_entry ); + if (!--waitqueue.num_buckets) + assert( list_empty( &waitqueue.buckets ) ); + + RtlLeaveCriticalSection( &waitqueue.cs ); + + TRACE( "terminating wait queue thread\n" ); + + assert( bucket->objcount == 0 ); + assert( list_empty( &bucket->reserved ) ); + assert( list_empty( &bucket->waiting ) ); + NtClose( bucket->update_event ); + + RtlFreeHeap( GetProcessHeap(), 0, bucket ); + RtlExitUserThread( 0 ); +} + +/*********************************************************************** + * tp_waitqueue_lock (internal) + */ +static NTSTATUS tp_waitqueue_lock( struct threadpool_object *wait ) +{ + struct waitqueue_bucket *bucket; + NTSTATUS status; + HANDLE thread; + BOOL alertable = (wait->u.wait.flags & WT_EXECUTEINIOTHREAD) != 0; + assert( wait->type == TP_OBJECT_TYPE_WAIT ); + + wait->u.wait.signaled = 0; + wait->u.wait.bucket = NULL; + wait->u.wait.wait_pending = FALSE; + wait->u.wait.timeout = 0; + wait->u.wait.handle = INVALID_HANDLE_VALUE; + + RtlEnterCriticalSection( &waitqueue.cs ); + + /* Try to assign to existing bucket if possible. */ + LIST_FOR_EACH_ENTRY( bucket, &waitqueue.buckets, struct waitqueue_bucket, bucket_entry ) + { + if (bucket->objcount < MAXIMUM_WAITQUEUE_OBJECTS && bucket->alertable == alertable) + { + list_add_tail( &bucket->reserved, &wait->u.wait.wait_entry ); + wait->u.wait.bucket = bucket; + bucket->objcount++; + + status = STATUS_SUCCESS; + goto out; + } + } + + /* Create a new bucket and corresponding worker thread. */ + bucket = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*bucket) ); + if (!bucket) + { + status = STATUS_NO_MEMORY; + goto out; + } + + bucket->objcount = 0; + bucket->alertable = alertable; + list_init( &bucket->reserved ); + list_init( &bucket->waiting ); + + status = NtCreateEvent( &bucket->update_event, EVENT_ALL_ACCESS, + NULL, SynchronizationEvent, FALSE ); + if (status) + { + RtlFreeHeap( GetProcessHeap(), 0, bucket ); + goto out; + } + + status = RtlCreateUserThread( GetCurrentProcess(), NULL, FALSE, 0, 0, 0, + (PTHREAD_START_ROUTINE)waitqueue_thread_proc, bucket, &thread, NULL ); + if (status == STATUS_SUCCESS) + { + list_add_tail( &waitqueue.buckets, &bucket->bucket_entry ); + waitqueue.num_buckets++; + + list_add_tail( &bucket->reserved, &wait->u.wait.wait_entry ); + wait->u.wait.bucket = bucket; + bucket->objcount++; + + NtClose( thread ); + } + else + { + NtClose( bucket->update_event ); + RtlFreeHeap( GetProcessHeap(), 0, bucket ); + } + +out: + RtlLeaveCriticalSection( &waitqueue.cs ); + return status; +} + +/*********************************************************************** + * tp_waitqueue_unlock (internal) + */ +static void tp_waitqueue_unlock( struct threadpool_object *wait ) +{ + assert( wait->type == TP_OBJECT_TYPE_WAIT ); + + RtlEnterCriticalSection( &waitqueue.cs ); + if (wait->u.wait.bucket) + { + struct waitqueue_bucket *bucket = wait->u.wait.bucket; + assert( bucket->objcount > 0 ); + + list_remove( &wait->u.wait.wait_entry ); + wait->u.wait.bucket = NULL; + bucket->objcount--; + + NtSetEvent( bucket->update_event, NULL ); + } + RtlLeaveCriticalSection( &waitqueue.cs ); +} + +#ifdef __REACTOS__ +ULONG NTAPI ioqueue_thread_proc(PVOID param ) +#else +static void CALLBACK ioqueue_thread_proc( void *param ) +#endif +{ + struct io_completion *completion; + struct threadpool_object *io; + IO_STATUS_BLOCK iosb; +#ifdef __REACTOS__ + PVOID key, value; +#else + ULONG_PTR key, value; +#endif + BOOL destroy, skip; + NTSTATUS status; + + TRACE( "starting I/O completion thread\n" ); + set_thread_name(L"wine_threadpool_ioqueue"); + + RtlEnterCriticalSection( &ioqueue.cs ); + + for (;;) + { + RtlLeaveCriticalSection( &ioqueue.cs ); + if ((status = NtRemoveIoCompletion( ioqueue.port, &key, &value, &iosb, NULL ))) + ERR("NtRemoveIoCompletion failed, status %#lx.\n", status); + RtlEnterCriticalSection( &ioqueue.cs ); + + destroy = skip = FALSE; + io = (struct threadpool_object *)key; + + TRACE( "io %p, iosb.Status %#lx.\n", io, iosb.Status ); + + if (io && (io->shutdown || io->u.io.shutting_down)) + { + RtlEnterCriticalSection( &io->pool->cs ); + if (!io->u.io.pending_count) + { + if (io->u.io.skipped_count) + --io->u.io.skipped_count; + + if (io->u.io.skipped_count) + skip = TRUE; + else + destroy = TRUE; + } + RtlLeaveCriticalSection( &io->pool->cs ); + if (skip) continue; + } + + if (destroy) + { + --ioqueue.objcount; + TRACE( "Releasing io %p.\n", io ); + io->shutdown = TRUE; + tp_object_release( io ); + } + else if (io) + { + RtlEnterCriticalSection( &io->pool->cs ); + + TRACE( "pending_count %u.\n", io->u.io.pending_count ); + + if (io->u.io.pending_count) + { + --io->u.io.pending_count; + if (!array_reserve((void **)&io->u.io.completions, &io->u.io.completion_max, + io->u.io.completion_count + 1, sizeof(*io->u.io.completions))) + { + ERR( "Failed to allocate memory.\n" ); + RtlLeaveCriticalSection( &io->pool->cs ); + continue; + } + + completion = &io->u.io.completions[io->u.io.completion_count++]; + completion->iosb = iosb; +#ifdef __REACTOS__ + completion->cvalue = (ULONG_PTR)value; +#else + completion->cvalue = value; +#endif + + tp_object_submit( io, FALSE ); + } + RtlLeaveCriticalSection( &io->pool->cs ); + } + + if (!ioqueue.objcount) + { + /* All I/O objects have been destroyed; if no new objects are + * created within some amount of time, then we can shutdown this + * thread. */ + LARGE_INTEGER timeout = {.QuadPart = (ULONGLONG)THREADPOOL_WORKER_TIMEOUT * -10000}; + if (RtlSleepConditionVariableCS( &ioqueue.update_event, &ioqueue.cs, + &timeout) == STATUS_TIMEOUT && !ioqueue.objcount) + break; + } + } + + ioqueue.thread_running = FALSE; + RtlLeaveCriticalSection( &ioqueue.cs ); + + TRACE( "terminating I/O completion thread\n" ); + + RtlExitUserThread( 0 ); + +#ifdef __REACTOS__ + return STATUS_SUCCESS; +#endif +} + +static NTSTATUS tp_ioqueue_lock( struct threadpool_object *io, HANDLE file ) +{ + NTSTATUS status = STATUS_SUCCESS; + + assert( io->type == TP_OBJECT_TYPE_IO ); + + RtlEnterCriticalSection( &ioqueue.cs ); + + if (!ioqueue.port && (status = NtCreateIoCompletion( &ioqueue.port, + IO_COMPLETION_ALL_ACCESS, NULL, 0 ))) + { + RtlLeaveCriticalSection( &ioqueue.cs ); + return status; + } + + if (!ioqueue.thread_running) + { + HANDLE thread; + + if (!(status = RtlCreateUserThread( GetCurrentProcess(), NULL, FALSE, + 0, 0, 0, ioqueue_thread_proc, NULL, &thread, NULL ))) + { + ioqueue.thread_running = TRUE; + NtClose( thread ); + } + } + + if (status == STATUS_SUCCESS) + { + FILE_COMPLETION_INFORMATION info; + IO_STATUS_BLOCK iosb; + +#ifdef __REACTOS__ + info.Port = ioqueue.port; + info.Key = io; +#else + info.CompletionPort = ioqueue.port; + info.CompletionKey = (ULONG_PTR)io; +#endif + + status = NtSetInformationFile( file, &iosb, &info, sizeof(info), FileCompletionInformation ); + } + + if (status == STATUS_SUCCESS) + { + if (!ioqueue.objcount++) + RtlWakeConditionVariable( &ioqueue.update_event ); + } + + RtlLeaveCriticalSection( &ioqueue.cs ); + return status; +} + +/*********************************************************************** + * tp_threadpool_alloc (internal) + * + * Allocates a new threadpool object. + */ +static NTSTATUS tp_threadpool_alloc( struct threadpool **out ) +{ +#ifdef __REACTOS__ + IMAGE_NT_HEADERS *nt = RtlImageNtHeader( NtCurrentTeb()->ProcessEnvironmentBlock->ImageBaseAddress ); +#else + IMAGE_NT_HEADERS *nt = RtlImageNtHeader( NtCurrentTeb()->Peb->ImageBaseAddress ); +#endif + struct threadpool *pool; + unsigned int i; + + pool = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*pool) ); + if (!pool) + return STATUS_NO_MEMORY; + + pool->refcount = 1; + pool->objcount = 0; + pool->shutdown = FALSE; + +#ifdef __REACTOS__ + RtlInitializeCriticalSection( &pool->cs ); +#else + RtlInitializeCriticalSectionEx( &pool->cs, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO ); + + pool->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": threadpool.cs"); +#endif + + for (i = 0; i < ARRAY_SIZE(pool->pools); ++i) + list_init( &pool->pools[i] ); + RtlInitializeConditionVariable( &pool->update_event ); + + pool->max_workers = 500; + pool->min_workers = 0; + pool->num_workers = 0; + pool->num_busy_workers = 0; + pool->stack_info.StackReserve = nt->OptionalHeader.SizeOfStackReserve; + pool->stack_info.StackCommit = nt->OptionalHeader.SizeOfStackCommit; + + TRACE( "allocated threadpool %p\n", pool ); + + *out = pool; + return STATUS_SUCCESS; +} + +/*********************************************************************** + * tp_threadpool_shutdown (internal) + * + * Prepares the shutdown of a threadpool object and notifies all worker + * threads to terminate (after all remaining work items have been + * processed). + */ +static void tp_threadpool_shutdown( struct threadpool *pool ) +{ + assert( pool != default_threadpool ); + + pool->shutdown = TRUE; + RtlWakeAllConditionVariable( &pool->update_event ); +} + +/*********************************************************************** + * tp_threadpool_release (internal) + * + * Releases a reference to a threadpool object. + */ +static BOOL tp_threadpool_release( struct threadpool *pool ) +{ + unsigned int i; + + if (InterlockedDecrement( &pool->refcount )) + return FALSE; + + TRACE( "destroying threadpool %p\n", pool ); + + assert( pool->shutdown ); + assert( !pool->objcount ); + for (i = 0; i < ARRAY_SIZE(pool->pools); ++i) + assert( list_empty( &pool->pools[i] ) ); +#ifndef __REACTOS__ + pool->cs.DebugInfo->Spare[0] = 0; +#endif + RtlDeleteCriticalSection( &pool->cs ); + + RtlFreeHeap( GetProcessHeap(), 0, pool ); + return TRUE; +} + +/*********************************************************************** + * tp_threadpool_lock (internal) + * + * Acquires a lock on a threadpool, specified with an TP_CALLBACK_ENVIRON + * block. When the lock is acquired successfully, it is guaranteed that + * there is at least one worker thread to process tasks. + */ +static NTSTATUS tp_threadpool_lock( struct threadpool **out, TP_CALLBACK_ENVIRON *environment ) +{ + struct threadpool *pool = NULL; + NTSTATUS status = STATUS_SUCCESS; + + if (environment) + { +#ifndef __REACTOS__ //Windows 7 stuff + /* Validate environment parameters. */ + if (environment->Version == 3) + { + TP_CALLBACK_ENVIRON_V3 *environment3 = (TP_CALLBACK_ENVIRON_V3 *)environment; + + switch (environment3->CallbackPriority) + { + case TP_CALLBACK_PRIORITY_HIGH: + case TP_CALLBACK_PRIORITY_NORMAL: + case TP_CALLBACK_PRIORITY_LOW: + break; + default: + return STATUS_INVALID_PARAMETER; + } + } +#endif + pool = (struct threadpool *)environment->Pool; + } + + if (!pool) + { + if (!default_threadpool) + { + status = tp_threadpool_alloc( &pool ); + if (status != STATUS_SUCCESS) + return status; + + if (InterlockedCompareExchangePointer( (void *)&default_threadpool, pool, NULL ) != NULL) + { + tp_threadpool_shutdown( pool ); + tp_threadpool_release( pool ); + } + } + + pool = default_threadpool; + } + + RtlEnterCriticalSection( &pool->cs ); + + /* Make sure that the threadpool has at least one thread. */ + if (!pool->num_workers) + status = tp_new_worker_thread( pool ); + + /* Keep a reference, and increment objcount to ensure that the + * last thread doesn't terminate. */ + if (status == STATUS_SUCCESS) + { + InterlockedIncrement( &pool->refcount ); + pool->objcount++; + } + + RtlLeaveCriticalSection( &pool->cs ); + + if (status != STATUS_SUCCESS) + return status; + + *out = pool; + return STATUS_SUCCESS; +} + +/*********************************************************************** + * tp_threadpool_unlock (internal) + * + * Releases a lock on a threadpool. + */ +static void tp_threadpool_unlock( struct threadpool *pool ) +{ + RtlEnterCriticalSection( &pool->cs ); + pool->objcount--; + RtlLeaveCriticalSection( &pool->cs ); + tp_threadpool_release( pool ); +} + +/*********************************************************************** + * tp_group_alloc (internal) + * + * Allocates a new threadpool group object. + */ +static NTSTATUS tp_group_alloc( struct threadpool_group **out ) +{ + struct threadpool_group *group; + + group = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*group) ); + if (!group) + return STATUS_NO_MEMORY; + + group->refcount = 1; + group->shutdown = FALSE; + +#ifdef __REACTOS__ + RtlInitializeCriticalSection( &group->cs ); +#else + RtlInitializeCriticalSectionEx( &group->cs, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO ); + + group->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": threadpool_group.cs"); +#endif + + list_init( &group->members ); + + TRACE( "allocated group %p\n", group ); + + *out = group; + return STATUS_SUCCESS; +} + +/*********************************************************************** + * tp_group_shutdown (internal) + * + * Marks the group object for shutdown. + */ +static void tp_group_shutdown( struct threadpool_group *group ) +{ + group->shutdown = TRUE; +} + +/*********************************************************************** + * tp_group_release (internal) + * + * Releases a reference to a group object. + */ +static BOOL tp_group_release( struct threadpool_group *group ) +{ + if (InterlockedDecrement( &group->refcount )) + return FALSE; + + TRACE( "destroying group %p\n", group ); + + assert( group->shutdown ); + assert( list_empty( &group->members ) ); + +#ifndef __REACTOS__ + group->cs.DebugInfo->Spare[0] = 0; +#endif + RtlDeleteCriticalSection( &group->cs ); + + RtlFreeHeap( GetProcessHeap(), 0, group ); + return TRUE; +} + +/*********************************************************************** + * tp_object_initialize (internal) + * + * Initializes members of a threadpool object. + */ +static void tp_object_initialize( struct threadpool_object *object, struct threadpool *pool, + PVOID userdata, TP_CALLBACK_ENVIRON *environment ) +{ + BOOL is_simple_callback = (object->type == TP_OBJECT_TYPE_SIMPLE); + + object->refcount = 1; + object->shutdown = FALSE; + + object->pool = pool; + object->group = NULL; + object->userdata = userdata; + object->group_cancel_callback = NULL; + object->finalization_callback = NULL; + object->may_run_long = 0; + object->race_dll = NULL; + object->priority = TP_CALLBACK_PRIORITY_NORMAL; + + memset( &object->group_entry, 0, sizeof(object->group_entry) ); + object->is_group_member = FALSE; + + memset( &object->pool_entry, 0, sizeof(object->pool_entry) ); + RtlInitializeConditionVariable( &object->finished_event ); + RtlInitializeConditionVariable( &object->group_finished_event ); + object->completed_event = NULL; + object->num_pending_callbacks = 0; + object->num_running_callbacks = 0; + object->num_associated_callbacks = 0; + + if (environment) + { + if (environment->Version != 1 && environment->Version != 3) + FIXME( "unsupported environment version %lu\n", environment->Version ); + + object->group = impl_from_TP_CLEANUP_GROUP( environment->CleanupGroup ); + object->group_cancel_callback = environment->CleanupGroupCancelCallback; + object->finalization_callback = environment->FinalizationCallback; + object->may_run_long = environment->u.s.LongFunction != 0; + object->race_dll = environment->RaceDll; +#ifndef __REACTOS__ //Windows 7 stuff + if (environment->Version == 3) + { + TP_CALLBACK_ENVIRON_V3 *environment_v3 = (TP_CALLBACK_ENVIRON_V3 *)environment; + + object->priority = environment_v3->CallbackPriority; + assert( object->priority < ARRAY_SIZE(pool->pools) ); + } +#endif + if (environment->ActivationContext) + FIXME( "activation context not supported yet\n" ); + + if (environment->u.s.Persistent) + FIXME( "persistent threads not supported yet\n" ); + } + + if (object->race_dll) + LdrAddRefDll( 0, object->race_dll ); + + TRACE( "allocated object %p of type %u\n", object, object->type ); + + /* For simple callbacks we have to run tp_object_submit before adding this object + * to the cleanup group. As soon as the cleanup group members are released ->shutdown + * will be set, and tp_object_submit would fail with an assertion. */ + + if (is_simple_callback) + tp_object_submit( object, FALSE ); + + if (object->group) + { + struct threadpool_group *group = object->group; + InterlockedIncrement( &group->refcount ); + + RtlEnterCriticalSection( &group->cs ); + list_add_tail( &group->members, &object->group_entry ); + object->is_group_member = TRUE; + RtlLeaveCriticalSection( &group->cs ); + } + + if (is_simple_callback) + tp_object_release( object ); +} + +static void tp_object_prio_queue( struct threadpool_object *object ) +{ + ++object->pool->num_busy_workers; + list_add_tail( &object->pool->pools[object->priority], &object->pool_entry ); +} + +/*********************************************************************** + * tp_object_submit (internal) + * + * Submits a threadpool object to the associated threadpool. This + * function has to be VOID because TpPostWork can never fail on Windows. + */ +static void tp_object_submit( struct threadpool_object *object, BOOL signaled ) +{ + struct threadpool *pool = object->pool; + NTSTATUS status = STATUS_UNSUCCESSFUL; + + assert( !object->shutdown ); + assert( !pool->shutdown ); + + RtlEnterCriticalSection( &pool->cs ); + + /* Start new worker threads if required. */ + if (pool->num_busy_workers >= pool->num_workers && + pool->num_workers < pool->max_workers) + status = tp_new_worker_thread( pool ); + + /* Queue work item and increment refcount. */ + InterlockedIncrement( &object->refcount ); + if (!object->num_pending_callbacks++) + tp_object_prio_queue( object ); + + /* Count how often the object was signaled. */ + if (object->type == TP_OBJECT_TYPE_WAIT && signaled) + object->u.wait.signaled++; + + /* No new thread started - wake up one existing thread. */ + if (status != STATUS_SUCCESS) + { + assert( pool->num_workers > 0 ); + RtlWakeConditionVariable( &pool->update_event ); + } + + RtlLeaveCriticalSection( &pool->cs ); +} + +/*********************************************************************** + * tp_object_cancel (internal) + * + * Cancels all currently pending callbacks for a specific object. + */ +static void tp_object_cancel( struct threadpool_object *object ) +{ + struct threadpool *pool = object->pool; + LONG pending_callbacks = 0; + + RtlEnterCriticalSection( &pool->cs ); + if (object->num_pending_callbacks) + { + pending_callbacks = object->num_pending_callbacks; + object->num_pending_callbacks = 0; + list_remove( &object->pool_entry ); + + if (object->type == TP_OBJECT_TYPE_WAIT) + object->u.wait.signaled = 0; + } + if (object->type == TP_OBJECT_TYPE_IO) + { + object->u.io.skipped_count += object->u.io.pending_count; + object->u.io.pending_count = 0; + } + RtlLeaveCriticalSection( &pool->cs ); + + while (pending_callbacks--) + tp_object_release( object ); +} + +static BOOL object_is_finished( struct threadpool_object *object, BOOL group ) +{ + if (object->num_pending_callbacks) + return FALSE; + if (object->type == TP_OBJECT_TYPE_IO && object->u.io.pending_count) + return FALSE; + + if (group) + return !object->num_running_callbacks; + else + return !object->num_associated_callbacks; +} + +/*********************************************************************** + * tp_object_wait (internal) + * + * Waits until all pending and running callbacks of a specific object + * have been processed. + */ +static void tp_object_wait( struct threadpool_object *object, BOOL group_wait ) +{ + struct threadpool *pool = object->pool; + + RtlEnterCriticalSection( &pool->cs ); + while (!object_is_finished( object, group_wait )) + { + if (group_wait) + RtlSleepConditionVariableCS( &object->group_finished_event, &pool->cs, NULL ); + else + RtlSleepConditionVariableCS( &object->finished_event, &pool->cs, NULL ); + } + RtlLeaveCriticalSection( &pool->cs ); +} + +static void tp_ioqueue_unlock( struct threadpool_object *io ) +{ + assert( io->type == TP_OBJECT_TYPE_IO ); + + RtlEnterCriticalSection( &ioqueue.cs ); + + assert(ioqueue.objcount); + + if (!io->shutdown && !--ioqueue.objcount) + NtSetIoCompletion( ioqueue.port, 0, 0, STATUS_SUCCESS, 0 ); + + RtlLeaveCriticalSection( &ioqueue.cs ); +} + +/*********************************************************************** + * tp_object_prepare_shutdown (internal) + * + * Prepares a threadpool object for shutdown. + */ +static void tp_object_prepare_shutdown( struct threadpool_object *object ) +{ + if (object->type == TP_OBJECT_TYPE_TIMER) + tp_timerqueue_unlock( object ); + else if (object->type == TP_OBJECT_TYPE_WAIT) + tp_waitqueue_unlock( object ); + else if (object->type == TP_OBJECT_TYPE_IO) + tp_ioqueue_unlock( object ); +} + +/*********************************************************************** + * tp_object_release (internal) + * + * Releases a reference to a threadpool object. + */ +static BOOL tp_object_release( struct threadpool_object *object ) +{ + if (InterlockedDecrement( &object->refcount )) + return FALSE; + + TRACE( "destroying object %p of type %u\n", object, object->type ); + + assert( object->shutdown ); + assert( !object->num_pending_callbacks ); + assert( !object->num_running_callbacks ); + assert( !object->num_associated_callbacks ); + + /* release reference to the group */ + if (object->group) + { + struct threadpool_group *group = object->group; + + RtlEnterCriticalSection( &group->cs ); + if (object->is_group_member) + { + list_remove( &object->group_entry ); + object->is_group_member = FALSE; + } + RtlLeaveCriticalSection( &group->cs ); + + tp_group_release( group ); + } + + tp_threadpool_unlock( object->pool ); + + if (object->race_dll) + LdrUnloadDll( object->race_dll ); + + if (object->completed_event && object->completed_event != INVALID_HANDLE_VALUE) + NtSetEvent( object->completed_event, NULL ); + + RtlFreeHeap( GetProcessHeap(), 0, object ); + return TRUE; +} + +static struct list *threadpool_get_next_item( const struct threadpool *pool ) +{ + struct list *ptr; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(pool->pools); ++i) + { + if ((ptr = list_head( &pool->pools[i] ))) + break; + } + + return ptr; +} + +/*********************************************************************** + * tp_object_execute (internal) + * + * Executes a threadpool object callback, object->pool->cs has to be + * held. + */ +static void tp_object_execute( struct threadpool_object *object, BOOL wait_thread ) +{ + TP_CALLBACK_INSTANCE *callback_instance; + struct threadpool_instance instance; + struct io_completion completion; + struct threadpool *pool = object->pool; + TP_WAIT_RESULT wait_result = 0; + NTSTATUS status; + + object->num_pending_callbacks--; + + /* For wait objects check if they were signaled or have timed out. */ + if (object->type == TP_OBJECT_TYPE_WAIT) + { + wait_result = object->u.wait.signaled ? WAIT_OBJECT_0 : WAIT_TIMEOUT; + if (wait_result == WAIT_OBJECT_0) object->u.wait.signaled--; + } + else if (object->type == TP_OBJECT_TYPE_IO) + { + assert( object->u.io.completion_count ); + completion = object->u.io.completions[--object->u.io.completion_count]; + } + + /* Leave critical section and do the actual callback. */ + object->num_associated_callbacks++; + object->num_running_callbacks++; + RtlLeaveCriticalSection( &pool->cs ); + if (wait_thread) RtlLeaveCriticalSection( &waitqueue.cs ); + + /* Initialize threadpool instance struct. */ + callback_instance = (TP_CALLBACK_INSTANCE *)&instance; + instance.object = object; + instance.threadid = GetCurrentThreadId(); + instance.associated = TRUE; + instance.may_run_long = object->may_run_long; + instance.cleanup.critical_section = NULL; + instance.cleanup.mutex = NULL; + instance.cleanup.semaphore = NULL; + instance.cleanup.semaphore_count = 0; + instance.cleanup.event = NULL; + instance.cleanup.library = NULL; + + switch (object->type) + { + case TP_OBJECT_TYPE_SIMPLE: + { + TRACE( "executing simple callback %p(%p, %p)\n", + object->u.simple.callback, callback_instance, object->userdata ); + object->u.simple.callback( callback_instance, object->userdata ); + TRACE( "callback %p returned\n", object->u.simple.callback ); + break; + } + + case TP_OBJECT_TYPE_WORK: + { + TRACE( "executing work callback %p(%p, %p, %p)\n", + object->u.work.callback, callback_instance, object->userdata, object ); + object->u.work.callback( callback_instance, object->userdata, (TP_WORK *)object ); + TRACE( "callback %p returned\n", object->u.work.callback ); + break; + } + + case TP_OBJECT_TYPE_TIMER: + { + TRACE( "executing timer callback %p(%p, %p, %p)\n", + object->u.timer.callback, callback_instance, object->userdata, object ); + object->u.timer.callback( callback_instance, object->userdata, (TP_TIMER *)object ); + TRACE( "callback %p returned\n", object->u.timer.callback ); + break; + } + + case TP_OBJECT_TYPE_WAIT: + { + TRACE( "executing wait callback %p(%p, %p, %p, %lu)\n", + object->u.wait.callback, callback_instance, object->userdata, object, wait_result ); + object->u.wait.callback( callback_instance, object->userdata, (TP_WAIT *)object, wait_result ); + TRACE( "callback %p returned\n", object->u.wait.callback ); + break; + } + + case TP_OBJECT_TYPE_IO: + { + TRACE( "executing I/O callback %p(%p, %p, %#Ix, %p, %p)\n", + object->u.io.callback, callback_instance, object->userdata, + completion.cvalue, &completion.iosb, (TP_IO *)object ); + object->u.io.callback( callback_instance, object->userdata, + (void *)completion.cvalue, &completion.iosb, (TP_IO *)object ); + TRACE( "callback %p returned\n", object->u.io.callback ); + break; + } + + default: + assert(0); + break; + } + + /* Execute finalization callback. */ + if (object->finalization_callback) + { + TRACE( "executing finalization callback %p(%p, %p)\n", + object->finalization_callback, callback_instance, object->userdata ); + object->finalization_callback( callback_instance, object->userdata ); + TRACE( "callback %p returned\n", object->finalization_callback ); + } + + /* Execute cleanup tasks. */ + if (instance.cleanup.critical_section) + { + RtlLeaveCriticalSection( instance.cleanup.critical_section ); + } + if (instance.cleanup.mutex) + { + status = NtReleaseMutant( instance.cleanup.mutex, NULL ); + if (status != STATUS_SUCCESS) goto skip_cleanup; + } + if (instance.cleanup.semaphore) + { + status = NtReleaseSemaphore( instance.cleanup.semaphore, instance.cleanup.semaphore_count, NULL ); + if (status != STATUS_SUCCESS) goto skip_cleanup; + } + if (instance.cleanup.event) + { + status = NtSetEvent( instance.cleanup.event, NULL ); + if (status != STATUS_SUCCESS) goto skip_cleanup; + } + if (instance.cleanup.library) + { + LdrUnloadDll( instance.cleanup.library ); + } + +skip_cleanup: + if (wait_thread) RtlEnterCriticalSection( &waitqueue.cs ); + RtlEnterCriticalSection( &pool->cs ); + + /* Simple callbacks are automatically shutdown after execution. */ + if (object->type == TP_OBJECT_TYPE_SIMPLE) + { + tp_object_prepare_shutdown( object ); + object->shutdown = TRUE; + } + + object->num_running_callbacks--; + if (object_is_finished( object, TRUE )) + RtlWakeAllConditionVariable( &object->group_finished_event ); + + if (instance.associated) + { + object->num_associated_callbacks--; + if (object_is_finished( object, FALSE )) + RtlWakeAllConditionVariable( &object->finished_event ); + } +} + +/*********************************************************************** + * threadpool_worker_proc (internal) + */ +#ifdef __REACTOS__ +ULONG NTAPI threadpool_worker_proc(PVOID param ) +#else +static void CALLBACK threadpool_worker_proc( void *param ) +#endif +{ + struct threadpool *pool = param; + LARGE_INTEGER timeout; + struct list *ptr; + + TRACE( "starting worker thread for pool %p\n", pool ); + set_thread_name(L"wine_threadpool_worker"); + + RtlEnterCriticalSection( &pool->cs ); + for (;;) + { + while ((ptr = threadpool_get_next_item( pool ))) + { + struct threadpool_object *object = LIST_ENTRY( ptr, struct threadpool_object, pool_entry ); + assert( object->num_pending_callbacks > 0 ); + + /* If further pending callbacks are queued, move the work item to + * the end of the pool list. Otherwise remove it from the pool. */ + list_remove( &object->pool_entry ); + if (object->num_pending_callbacks > 1) + tp_object_prio_queue( object ); + + tp_object_execute( object, FALSE ); + + assert(pool->num_busy_workers); + pool->num_busy_workers--; + + tp_object_release( object ); + } + + /* Shutdown worker thread if requested. */ + if (pool->shutdown) + break; + + /* Wait for new tasks or until the timeout expires. A thread only terminates + * when no new tasks are available, and the number of threads can be + * decreased without violating the min_workers limit. An exception is when + * min_workers == 0, then objcount is used to detect if the last thread + * can be terminated. */ + timeout.QuadPart = (ULONGLONG)THREADPOOL_WORKER_TIMEOUT * -10000; + if (RtlSleepConditionVariableCS( &pool->update_event, &pool->cs, &timeout ) == STATUS_TIMEOUT && + !threadpool_get_next_item( pool ) && (pool->num_workers > max( pool->min_workers, 1 ) || + (!pool->min_workers && !pool->objcount))) + { + break; + } + } + pool->num_workers--; + RtlLeaveCriticalSection( &pool->cs ); + + TRACE( "terminating worker thread for pool %p\n", pool ); + tp_threadpool_release( pool ); + RtlExitUserThread( 0 ); +#ifdef __REACTOS__ + return STATUS_SUCCESS; +#endif +} + +/*********************************************************************** + * TpAllocCleanupGroup (NTDLL.@) + */ +NTSTATUS WINAPI TpAllocCleanupGroup( TP_CLEANUP_GROUP **out ) +{ + TRACE( "%p\n", out ); + + return tp_group_alloc( (struct threadpool_group **)out ); +} + +/*********************************************************************** + * TpAllocIoCompletion (NTDLL.@) + */ +NTSTATUS WINAPI TpAllocIoCompletion( TP_IO **out, HANDLE file, PTP_IO_CALLBACK callback, + void *userdata, TP_CALLBACK_ENVIRON *environment ) +{ + struct threadpool_object *object; + struct threadpool *pool; + NTSTATUS status; + + TRACE( "%p %p %p %p %p\n", out, file, callback, userdata, environment ); + + if (!(object = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object) ))) + return STATUS_NO_MEMORY; + + if ((status = tp_threadpool_lock( &pool, environment ))) + { + RtlFreeHeap( GetProcessHeap(), 0, object ); + return status; + } + + object->type = TP_OBJECT_TYPE_IO; + object->u.io.callback = callback; + if (!(object->u.io.completions = RtlAllocateHeap( GetProcessHeap(), 0, 8 * sizeof(*object->u.io.completions) ))) + { + tp_threadpool_unlock( pool ); + RtlFreeHeap( GetProcessHeap(), 0, object ); + return status; + } + + if ((status = tp_ioqueue_lock( object, file ))) + { + tp_threadpool_unlock( pool ); + RtlFreeHeap( GetProcessHeap(), 0, object->u.io.completions ); + RtlFreeHeap( GetProcessHeap(), 0, object ); + return status; + } + + tp_object_initialize( object, pool, userdata, environment ); + + *out = (TP_IO *)object; + return STATUS_SUCCESS; +} + +/*********************************************************************** + * TpAllocPool (NTDLL.@) + */ +NTSTATUS WINAPI TpAllocPool( TP_POOL **out, PVOID reserved ) +{ + TRACE( "%p %p\n", out, reserved ); + + if (reserved) + FIXME( "reserved argument is nonzero (%p)\n", reserved ); + + return tp_threadpool_alloc( (struct threadpool **)out ); +} + +/*********************************************************************** + * TpAllocTimer (NTDLL.@) + */ +NTSTATUS WINAPI TpAllocTimer( TP_TIMER **out, PTP_TIMER_CALLBACK callback, PVOID userdata, + TP_CALLBACK_ENVIRON *environment ) +{ + struct threadpool_object *object; + struct threadpool *pool; + NTSTATUS status; + + TRACE( "%p %p %p %p\n", out, callback, userdata, environment ); + + object = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*object) ); + if (!object) + return STATUS_NO_MEMORY; + + status = tp_threadpool_lock( &pool, environment ); + if (status) + { + RtlFreeHeap( GetProcessHeap(), 0, object ); + return status; + } + + object->type = TP_OBJECT_TYPE_TIMER; + object->u.timer.callback = callback; + + status = tp_timerqueue_lock( object ); + if (status) + { + tp_threadpool_unlock( pool ); + RtlFreeHeap( GetProcessHeap(), 0, object ); + return status; + } + + tp_object_initialize( object, pool, userdata, environment ); + + *out = (TP_TIMER *)object; + return STATUS_SUCCESS; +} + +static NTSTATUS tp_alloc_wait( TP_WAIT **out, PTP_WAIT_CALLBACK callback, PVOID userdata, + TP_CALLBACK_ENVIRON *environment, DWORD flags ) +{ + struct threadpool_object *object; + struct threadpool *pool; + NTSTATUS status; + + object = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*object) ); + if (!object) + return STATUS_NO_MEMORY; + + status = tp_threadpool_lock( &pool, environment ); + if (status) + { + RtlFreeHeap( GetProcessHeap(), 0, object ); + return status; + } + + object->type = TP_OBJECT_TYPE_WAIT; + object->u.wait.callback = callback; + object->u.wait.flags = flags; + + status = tp_waitqueue_lock( object ); + if (status) + { + tp_threadpool_unlock( pool ); + RtlFreeHeap( GetProcessHeap(), 0, object ); + return status; + } + + tp_object_initialize( object, pool, userdata, environment ); + + *out = (TP_WAIT *)object; + return STATUS_SUCCESS; +} + +/*********************************************************************** + * TpAllocWait (NTDLL.@) + */ +NTSTATUS WINAPI TpAllocWait( TP_WAIT **out, PTP_WAIT_CALLBACK callback, PVOID userdata, + TP_CALLBACK_ENVIRON *environment ) +{ + TRACE( "%p %p %p %p\n", out, callback, userdata, environment ); + return tp_alloc_wait( out, callback, userdata, environment, WT_EXECUTEONLYONCE ); +} + +/*********************************************************************** + * TpAllocWork (NTDLL.@) + */ +NTSTATUS WINAPI TpAllocWork( TP_WORK **out, PTP_WORK_CALLBACK callback, PVOID userdata, + TP_CALLBACK_ENVIRON *environment ) +{ + struct threadpool_object *object; + struct threadpool *pool; + NTSTATUS status; + + TRACE( "%p %p %p %p\n", out, callback, userdata, environment ); + + object = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*object) ); + if (!object) + return STATUS_NO_MEMORY; + + status = tp_threadpool_lock( &pool, environment ); + if (status) + { + RtlFreeHeap( GetProcessHeap(), 0, object ); + return status; + } + + object->type = TP_OBJECT_TYPE_WORK; + object->u.work.callback = callback; + tp_object_initialize( object, pool, userdata, environment ); + + *out = (TP_WORK *)object; + return STATUS_SUCCESS; +} + +/*********************************************************************** + * TpCancelAsyncIoOperation (NTDLL.@) + */ +void WINAPI TpCancelAsyncIoOperation( TP_IO *io ) +{ + struct threadpool_object *this = impl_from_TP_IO( io ); + + TRACE( "%p\n", io ); + + RtlEnterCriticalSection( &this->pool->cs ); + + TRACE("pending_count %u.\n", this->u.io.pending_count); + + this->u.io.pending_count--; + if (object_is_finished( this, TRUE )) + RtlWakeAllConditionVariable( &this->group_finished_event ); + if (object_is_finished( this, FALSE )) + RtlWakeAllConditionVariable( &this->finished_event ); + + RtlLeaveCriticalSection( &this->pool->cs ); +} + +/*********************************************************************** + * TpCallbackLeaveCriticalSectionOnCompletion (NTDLL.@) + */ +VOID WINAPI TpCallbackLeaveCriticalSectionOnCompletion( TP_CALLBACK_INSTANCE *instance, CRITICAL_SECTION *crit ) +{ + struct threadpool_instance *this = impl_from_TP_CALLBACK_INSTANCE( instance ); + + TRACE( "%p %p\n", instance, crit ); + + if (!this->cleanup.critical_section) + this->cleanup.critical_section = crit; +} + +/*********************************************************************** + * TpCallbackMayRunLong (NTDLL.@) + */ +NTSTATUS WINAPI TpCallbackMayRunLong( TP_CALLBACK_INSTANCE *instance ) +{ + struct threadpool_instance *this = impl_from_TP_CALLBACK_INSTANCE( instance ); + struct threadpool_object *object = this->object; + struct threadpool *pool; + NTSTATUS status = STATUS_SUCCESS; + + TRACE( "%p\n", instance ); + + if (this->threadid != GetCurrentThreadId()) + { + ERR("called from wrong thread, ignoring\n"); + return STATUS_UNSUCCESSFUL; /* FIXME */ + } + + if (this->may_run_long) + return STATUS_SUCCESS; + + pool = object->pool; + RtlEnterCriticalSection( &pool->cs ); + + /* Start new worker threads if required. */ + if (pool->num_busy_workers >= pool->num_workers) + { + if (pool->num_workers < pool->max_workers) + { + status = tp_new_worker_thread( pool ); + } + else + { + status = STATUS_TOO_MANY_THREADS; + } + } + + RtlLeaveCriticalSection( &pool->cs ); + this->may_run_long = TRUE; + return status; +} + +/*********************************************************************** + * TpCallbackReleaseMutexOnCompletion (NTDLL.@) + */ +VOID WINAPI TpCallbackReleaseMutexOnCompletion( TP_CALLBACK_INSTANCE *instance, HANDLE mutex ) +{ + struct threadpool_instance *this = impl_from_TP_CALLBACK_INSTANCE( instance ); + + TRACE( "%p %p\n", instance, mutex ); + + if (!this->cleanup.mutex) + this->cleanup.mutex = mutex; +} + +/*********************************************************************** + * TpCallbackReleaseSemaphoreOnCompletion (NTDLL.@) + */ +VOID WINAPI TpCallbackReleaseSemaphoreOnCompletion( TP_CALLBACK_INSTANCE *instance, HANDLE semaphore, DWORD count ) +{ + struct threadpool_instance *this = impl_from_TP_CALLBACK_INSTANCE( instance ); + + TRACE( "%p %p %lu\n", instance, semaphore, count ); + + if (!this->cleanup.semaphore) + { + this->cleanup.semaphore = semaphore; + this->cleanup.semaphore_count = count; + } +} + +/*********************************************************************** + * TpCallbackSetEventOnCompletion (NTDLL.@) + */ +VOID WINAPI TpCallbackSetEventOnCompletion( TP_CALLBACK_INSTANCE *instance, HANDLE event ) +{ + struct threadpool_instance *this = impl_from_TP_CALLBACK_INSTANCE( instance ); + + TRACE( "%p %p\n", instance, event ); + + if (!this->cleanup.event) + this->cleanup.event = event; +} + +/*********************************************************************** + * TpCallbackUnloadDllOnCompletion (NTDLL.@) + */ +VOID WINAPI TpCallbackUnloadDllOnCompletion( TP_CALLBACK_INSTANCE *instance, HMODULE module ) +{ + struct threadpool_instance *this = impl_from_TP_CALLBACK_INSTANCE( instance ); + + TRACE( "%p %p\n", instance, module ); + + if (!this->cleanup.library) + this->cleanup.library = module; +} + +/*********************************************************************** + * TpDisassociateCallback (NTDLL.@) + */ +VOID WINAPI TpDisassociateCallback( TP_CALLBACK_INSTANCE *instance ) +{ + struct threadpool_instance *this = impl_from_TP_CALLBACK_INSTANCE( instance ); + struct threadpool_object *object = this->object; + struct threadpool *pool; + + TRACE( "%p\n", instance ); + + if (this->threadid != GetCurrentThreadId()) + { + ERR("called from wrong thread, ignoring\n"); + return; + } + + if (!this->associated) + return; + + pool = object->pool; + RtlEnterCriticalSection( &pool->cs ); + + object->num_associated_callbacks--; + if (object_is_finished( object, FALSE )) + RtlWakeAllConditionVariable( &object->finished_event ); + + RtlLeaveCriticalSection( &pool->cs ); + this->associated = FALSE; +} + +/*********************************************************************** + * TpIsTimerSet (NTDLL.@) + */ +BOOL WINAPI TpIsTimerSet( TP_TIMER *timer ) +{ + struct threadpool_object *this = impl_from_TP_TIMER( timer ); + + TRACE( "%p\n", timer ); + + return this->u.timer.timer_set; +} + +/*********************************************************************** + * TpPostWork (NTDLL.@) + */ +VOID WINAPI TpPostWork( TP_WORK *work ) +{ + struct threadpool_object *this = impl_from_TP_WORK( work ); + + TRACE( "%p\n", work ); + + tp_object_submit( this, FALSE ); +} + +/*********************************************************************** + * TpReleaseCleanupGroup (NTDLL.@) + */ +VOID WINAPI TpReleaseCleanupGroup( TP_CLEANUP_GROUP *group ) +{ + struct threadpool_group *this = impl_from_TP_CLEANUP_GROUP( group ); + + TRACE( "%p\n", group ); + + tp_group_shutdown( this ); + tp_group_release( this ); +} + +/*********************************************************************** + * TpReleaseCleanupGroupMembers (NTDLL.@) + */ +VOID WINAPI TpReleaseCleanupGroupMembers( TP_CLEANUP_GROUP *group, BOOL cancel_pending, PVOID userdata ) +{ + struct threadpool_group *this = impl_from_TP_CLEANUP_GROUP( group ); + struct threadpool_object *object, *next; + struct list members; + + TRACE( "%p %u %p\n", group, cancel_pending, userdata ); + + RtlEnterCriticalSection( &this->cs ); + + /* Unset group, increase references, and mark objects for shutdown */ + LIST_FOR_EACH_ENTRY_SAFE( object, next, &this->members, struct threadpool_object, group_entry ) + { + assert( object->group == this ); + assert( object->is_group_member ); + + if (InterlockedIncrement( &object->refcount ) == 1) + { + /* Object is basically already destroyed, but group reference + * was not deleted yet. We can safely ignore this object. */ + InterlockedDecrement( &object->refcount ); + list_remove( &object->group_entry ); + object->is_group_member = FALSE; + continue; + } + + object->is_group_member = FALSE; + tp_object_prepare_shutdown( object ); + } + + /* Move members to a new temporary list */ + list_init( &members ); + list_move_tail( &members, &this->members ); + + RtlLeaveCriticalSection( &this->cs ); + + /* Cancel pending callbacks if requested */ + if (cancel_pending) + { + LIST_FOR_EACH_ENTRY( object, &members, struct threadpool_object, group_entry ) + { + tp_object_cancel( object ); + } + } + + /* Wait for remaining callbacks to finish */ + LIST_FOR_EACH_ENTRY_SAFE( object, next, &members, struct threadpool_object, group_entry ) + { + tp_object_wait( object, TRUE ); + + if (!object->shutdown) + { + /* Execute group cancellation callback if defined, and if this was actually a group cancel. */ + if (cancel_pending && object->group_cancel_callback) + { + TRACE( "executing group cancel callback %p(%p, %p)\n", + object->group_cancel_callback, object->userdata, userdata ); + object->group_cancel_callback( object->userdata, userdata ); + TRACE( "callback %p returned\n", object->group_cancel_callback ); + } + + if (object->type != TP_OBJECT_TYPE_SIMPLE) + tp_object_release( object ); + } + + object->shutdown = TRUE; + tp_object_release( object ); + } +} + +/*********************************************************************** + * TpReleaseIoCompletion (NTDLL.@) + */ +void WINAPI TpReleaseIoCompletion( TP_IO *io ) +{ + struct threadpool_object *this = impl_from_TP_IO( io ); + BOOL can_destroy; + + TRACE( "%p\n", io ); + + RtlEnterCriticalSection( &this->pool->cs ); + this->u.io.shutting_down = TRUE; + can_destroy = !this->u.io.pending_count && !this->u.io.skipped_count; + RtlLeaveCriticalSection( &this->pool->cs ); + + if (can_destroy) + { + tp_object_prepare_shutdown( this ); + this->shutdown = TRUE; + tp_object_release( this ); + } +} + +/*********************************************************************** + * TpReleasePool (NTDLL.@) + */ +VOID WINAPI TpReleasePool( TP_POOL *pool ) +{ + struct threadpool *this = impl_from_TP_POOL( pool ); + + TRACE( "%p\n", pool ); + + tp_threadpool_shutdown( this ); + tp_threadpool_release( this ); +} + +/*********************************************************************** + * TpReleaseTimer (NTDLL.@) + */ +VOID WINAPI TpReleaseTimer( TP_TIMER *timer ) +{ + struct threadpool_object *this = impl_from_TP_TIMER( timer ); + + TRACE( "%p\n", timer ); + + tp_object_prepare_shutdown( this ); + this->shutdown = TRUE; + tp_object_release( this ); +} + +/*********************************************************************** + * TpReleaseWait (NTDLL.@) + */ +VOID WINAPI TpReleaseWait( TP_WAIT *wait ) +{ + struct threadpool_object *this = impl_from_TP_WAIT( wait ); + + TRACE( "%p\n", wait ); + + tp_object_prepare_shutdown( this ); + this->shutdown = TRUE; + tp_object_release( this ); +} + +/*********************************************************************** + * TpReleaseWork (NTDLL.@) + */ +VOID WINAPI TpReleaseWork( TP_WORK *work ) +{ + struct threadpool_object *this = impl_from_TP_WORK( work ); + + TRACE( "%p\n", work ); + + tp_object_prepare_shutdown( this ); + this->shutdown = TRUE; + tp_object_release( this ); +} + +/*********************************************************************** + * TpSetPoolMaxThreads (NTDLL.@) + */ +VOID WINAPI TpSetPoolMaxThreads( TP_POOL *pool, DWORD maximum ) +{ + struct threadpool *this = impl_from_TP_POOL( pool ); + + TRACE( "%p %lu\n", pool, maximum ); + + RtlEnterCriticalSection( &this->cs ); + this->max_workers = max( maximum, 1 ); + this->min_workers = min( this->min_workers, this->max_workers ); + RtlLeaveCriticalSection( &this->cs ); +} + +/*********************************************************************** + * TpSetPoolMinThreads (NTDLL.@) + */ +BOOL WINAPI TpSetPoolMinThreads( TP_POOL *pool, DWORD minimum ) +{ + struct threadpool *this = impl_from_TP_POOL( pool ); + NTSTATUS status = STATUS_SUCCESS; + + TRACE( "%p %lu\n", pool, minimum ); + + RtlEnterCriticalSection( &this->cs ); + + while (this->num_workers < minimum) + { + status = tp_new_worker_thread( this ); + if (status != STATUS_SUCCESS) + break; + } + + if (status == STATUS_SUCCESS) + { + this->min_workers = minimum; + this->max_workers = max( this->min_workers, this->max_workers ); + } + + RtlLeaveCriticalSection( &this->cs ); + return !status; +} + +/*********************************************************************** + * TpSetTimer (NTDLL.@) + */ +VOID WINAPI TpSetTimer( TP_TIMER *timer, LARGE_INTEGER *timeout, LONG period, LONG window_length ) +{ + struct threadpool_object *this = impl_from_TP_TIMER( timer ); + struct threadpool_object *other_timer; + BOOL submit_timer = FALSE; + ULONGLONG timestamp; + + TRACE( "%p %p %lu %lu\n", timer, timeout, period, window_length ); + + RtlEnterCriticalSection( &timerqueue.cs ); + + assert( this->u.timer.timer_initialized ); + this->u.timer.timer_set = timeout != NULL; + + /* Convert relative timeout to absolute timestamp and handle a timeout + * of zero, which means that the timer is submitted immediately. */ + if (timeout) + { + timestamp = timeout->QuadPart; + if ((LONGLONG)timestamp < 0) + { + LARGE_INTEGER now; + NtQuerySystemTime( &now ); + timestamp = now.QuadPart - timestamp; + } + else if (!timestamp) + { + if (!period) + timeout = NULL; + else + { + LARGE_INTEGER now; + NtQuerySystemTime( &now ); + timestamp = now.QuadPart + (ULONGLONG)period * 10000; + } + submit_timer = TRUE; + } + } + + /* First remove existing timeout. */ + if (this->u.timer.timer_pending) + { + list_remove( &this->u.timer.timer_entry ); + this->u.timer.timer_pending = FALSE; + } + + /* If the timer was enabled, then add it back to the queue. */ + if (timeout) + { + this->u.timer.timeout = timestamp; + this->u.timer.period = period; + this->u.timer.window_length = window_length; + + LIST_FOR_EACH_ENTRY( other_timer, &timerqueue.pending_timers, + struct threadpool_object, u.timer.timer_entry ) + { + assert( other_timer->type == TP_OBJECT_TYPE_TIMER ); + if (this->u.timer.timeout < other_timer->u.timer.timeout) + break; + } + list_add_before( &other_timer->u.timer.timer_entry, &this->u.timer.timer_entry ); + + /* Wake up the timer thread when the timeout has to be updated. */ + if (list_head( &timerqueue.pending_timers ) == &this->u.timer.timer_entry ) + RtlWakeAllConditionVariable( &timerqueue.update_event ); + + this->u.timer.timer_pending = TRUE; + } + + RtlLeaveCriticalSection( &timerqueue.cs ); + + if (submit_timer) + tp_object_submit( this, FALSE ); +} + +/*********************************************************************** + * TpSetWait (NTDLL.@) + */ +VOID WINAPI TpSetWait( TP_WAIT *wait, HANDLE handle, LARGE_INTEGER *timeout ) +{ + struct threadpool_object *this = impl_from_TP_WAIT( wait ); + ULONGLONG timestamp = MAXLONGLONG; + + TRACE( "%p %p %p\n", wait, handle, timeout ); + + RtlEnterCriticalSection( &waitqueue.cs ); + + assert( this->u.wait.bucket ); + this->u.wait.handle = handle; + + if (handle || this->u.wait.wait_pending) + { + struct waitqueue_bucket *bucket = this->u.wait.bucket; + list_remove( &this->u.wait.wait_entry ); + + /* Convert relative timeout to absolute timestamp. */ + if (handle && timeout) + { + timestamp = timeout->QuadPart; + if ((LONGLONG)timestamp < 0) + { + LARGE_INTEGER now; + NtQuerySystemTime( &now ); + timestamp = now.QuadPart - timestamp; + } + } + + /* Add wait object back into one of the queues. */ + if (handle) + { + list_add_tail( &bucket->waiting, &this->u.wait.wait_entry ); + this->u.wait.wait_pending = TRUE; + this->u.wait.timeout = timestamp; + } + else + { + list_add_tail( &bucket->reserved, &this->u.wait.wait_entry ); + this->u.wait.wait_pending = FALSE; + } + + /* Wake up the wait queue thread. */ + NtSetEvent( bucket->update_event, NULL ); + } + + RtlLeaveCriticalSection( &waitqueue.cs ); +} + +/*********************************************************************** + * TpSimpleTryPost (NTDLL.@) + */ +NTSTATUS WINAPI TpSimpleTryPost( PTP_SIMPLE_CALLBACK callback, PVOID userdata, + TP_CALLBACK_ENVIRON *environment ) +{ + struct threadpool_object *object; + struct threadpool *pool; + NTSTATUS status; + + TRACE( "%p %p %p\n", callback, userdata, environment ); + + object = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*object) ); + if (!object) + return STATUS_NO_MEMORY; + + status = tp_threadpool_lock( &pool, environment ); + if (status) + { + RtlFreeHeap( GetProcessHeap(), 0, object ); + return status; + } + + object->type = TP_OBJECT_TYPE_SIMPLE; + object->u.simple.callback = callback; + tp_object_initialize( object, pool, userdata, environment ); + + return STATUS_SUCCESS; +} + +/*********************************************************************** + * TpStartAsyncIoOperation (NTDLL.@) + */ +void WINAPI TpStartAsyncIoOperation( TP_IO *io ) +{ + struct threadpool_object *this = impl_from_TP_IO( io ); + + TRACE( "%p\n", io ); + + RtlEnterCriticalSection( &this->pool->cs ); + + this->u.io.pending_count++; + + RtlLeaveCriticalSection( &this->pool->cs ); +} + +/*********************************************************************** + * TpWaitForIoCompletion (NTDLL.@) + */ +void WINAPI TpWaitForIoCompletion( TP_IO *io, BOOL cancel_pending ) +{ + struct threadpool_object *this = impl_from_TP_IO( io ); + + TRACE( "%p %d\n", io, cancel_pending ); + + if (cancel_pending) + tp_object_cancel( this ); + tp_object_wait( this, FALSE ); +} + +/*********************************************************************** + * TpWaitForTimer (NTDLL.@) + */ +VOID WINAPI TpWaitForTimer( TP_TIMER *timer, BOOL cancel_pending ) +{ + struct threadpool_object *this = impl_from_TP_TIMER( timer ); + + TRACE( "%p %d\n", timer, cancel_pending ); + + if (cancel_pending) + tp_object_cancel( this ); + tp_object_wait( this, FALSE ); +} + +/*********************************************************************** + * TpWaitForWait (NTDLL.@) + */ +VOID WINAPI TpWaitForWait( TP_WAIT *wait, BOOL cancel_pending ) +{ + struct threadpool_object *this = impl_from_TP_WAIT( wait ); + + TRACE( "%p %d\n", wait, cancel_pending ); + + if (cancel_pending) + tp_object_cancel( this ); + tp_object_wait( this, FALSE ); +} + +/*********************************************************************** + * TpWaitForWork (NTDLL.@) + */ +VOID WINAPI TpWaitForWork( TP_WORK *work, BOOL cancel_pending ) +{ + struct threadpool_object *this = impl_from_TP_WORK( work ); + + TRACE( "%p %u\n", work, cancel_pending ); + + if (cancel_pending) + tp_object_cancel( this ); + tp_object_wait( this, FALSE ); +} + +/*********************************************************************** + * TpSetPoolStackInformation (NTDLL.@) + */ +NTSTATUS WINAPI TpSetPoolStackInformation( TP_POOL *pool, TP_POOL_STACK_INFORMATION *stack_info ) +{ + struct threadpool *this = impl_from_TP_POOL( pool ); + + TRACE( "%p %p\n", pool, stack_info ); + + if (!stack_info) + return STATUS_INVALID_PARAMETER; + + RtlEnterCriticalSection( &this->cs ); + this->stack_info = *stack_info; + RtlLeaveCriticalSection( &this->cs ); + + return STATUS_SUCCESS; +} + +/*********************************************************************** + * TpQueryPoolStackInformation (NTDLL.@) + */ +NTSTATUS WINAPI TpQueryPoolStackInformation( TP_POOL *pool, TP_POOL_STACK_INFORMATION *stack_info ) +{ + struct threadpool *this = impl_from_TP_POOL( pool ); + + TRACE( "%p %p\n", pool, stack_info ); + + if (!stack_info) + return STATUS_INVALID_PARAMETER; + + RtlEnterCriticalSection( &this->cs ); + *stack_info = this->stack_info; + RtlLeaveCriticalSection( &this->cs ); + + return STATUS_SUCCESS; +} + +static void CALLBACK rtl_wait_callback( TP_CALLBACK_INSTANCE *instance, void *userdata, TP_WAIT *wait, TP_WAIT_RESULT result ) +{ + struct threadpool_object *object = impl_from_TP_WAIT(wait); + object->u.wait.rtl_callback( userdata, result != STATUS_WAIT_0 ); +} + +/*********************************************************************** + * RtlRegisterWait (NTDLL.@) + * + * Registers a wait for a handle to become signaled. + * + * PARAMS + * NewWaitObject [I] Handle to the new wait object. Use RtlDeregisterWait() to free it. + * Object [I] Object to wait to become signaled. + * Callback [I] Callback function to execute when the wait times out or the handle is signaled. + * Context [I] Context to pass to the callback function when it is executed. + * Milliseconds [I] Number of milliseconds to wait before timing out. + * Flags [I] Flags. See notes. + * + * RETURNS + * Success: STATUS_SUCCESS. + * Failure: Any NTSTATUS code. + * + * NOTES + * Flags can be one or more of the following: + *|WT_EXECUTEDEFAULT - Executes the work item in a non-I/O worker thread. + *|WT_EXECUTEINIOTHREAD - Executes the work item in an I/O worker thread. + *|WT_EXECUTEINPERSISTENTTHREAD - Executes the work item in a thread that is persistent. + *|WT_EXECUTELONGFUNCTION - Hints that the execution can take a long time. + *|WT_TRANSFER_IMPERSONATION - Executes the function with the current access token. + */ +NTSTATUS WINAPI RtlRegisterWait( HANDLE *out, HANDLE handle, RTL_WAITORTIMERCALLBACKFUNC callback, + void *context, ULONG milliseconds, ULONG flags ) +{ + struct threadpool_object *object; + TP_CALLBACK_ENVIRON environment; + LARGE_INTEGER timeout; + NTSTATUS status; + TP_WAIT *wait; + + TRACE( "out %p, handle %p, callback %p, context %p, milliseconds %lu, flags %lx\n", + out, handle, callback, context, milliseconds, flags ); + + memset( &environment, 0, sizeof(environment) ); + environment.Version = 1; + environment.u.s.LongFunction = (flags & WT_EXECUTELONGFUNCTION) != 0; + environment.u.s.Persistent = (flags & WT_EXECUTEINPERSISTENTTHREAD) != 0; + + flags &= (WT_EXECUTEONLYONCE | WT_EXECUTEINWAITTHREAD | WT_EXECUTEINIOTHREAD); + if ((status = tp_alloc_wait( &wait, rtl_wait_callback, context, &environment, flags ))) + return status; + + object = impl_from_TP_WAIT(wait); + object->u.wait.rtl_callback = callback; + + RtlEnterCriticalSection( &waitqueue.cs ); + TpSetWait( (TP_WAIT *)object, handle, get_nt_timeout( &timeout, milliseconds ) ); + + *out = object; + RtlLeaveCriticalSection( &waitqueue.cs ); + + return STATUS_SUCCESS; +} + +/*********************************************************************** + * RtlDeregisterWaitEx (NTDLL.@) + * + * Cancels a wait operation and frees the resources associated with calling + * RtlRegisterWait(). + * + * PARAMS + * WaitObject [I] Handle to the wait object to free. + * + * RETURNS + * Success: STATUS_SUCCESS. + * Failure: Any NTSTATUS code. + */ +NTSTATUS WINAPI RtlDeregisterWaitEx( HANDLE handle, HANDLE event ) +{ + struct threadpool_object *object = handle; + NTSTATUS status; + + TRACE( "handle %p, event %p\n", handle, event ); + + if (!object) return STATUS_INVALID_HANDLE; + + TpSetWait( (TP_WAIT *)object, NULL, NULL ); + + if (event == INVALID_HANDLE_VALUE) TpWaitForWait( (TP_WAIT *)object, TRUE ); + else + { + assert( object->completed_event == NULL ); + object->completed_event = event; + } + + RtlEnterCriticalSection( &object->pool->cs ); + if (object->num_pending_callbacks + object->num_running_callbacks + + object->num_associated_callbacks) status = STATUS_PENDING; + else status = STATUS_SUCCESS; + RtlLeaveCriticalSection( &object->pool->cs ); + + TpReleaseWait( (TP_WAIT *)object ); + return status; +} + +/*********************************************************************** + * RtlDeregisterWait (NTDLL.@) + * + * Cancels a wait operation and frees the resources associated with calling + * RtlRegisterWait(). + * + * PARAMS + * WaitObject [I] Handle to the wait object to free. + * + * RETURNS + * Success: STATUS_SUCCESS. + * Failure: Any NTSTATUS code. + */ +NTSTATUS WINAPI RtlDeregisterWait(HANDLE WaitHandle) +{ + return RtlDeregisterWaitEx(WaitHandle, NULL); +} + +#ifdef __REACTOS__ +VOID +NTAPI +RtlpInitializeThreadPooling( + VOID) +{ + RtlInitializeCriticalSection(&old_threadpool.threadpool_compl_cs); + RtlInitializeCriticalSection(&timerqueue.cs); + RtlInitializeCriticalSection(&waitqueue.cs); + RtlInitializeCriticalSection(&ioqueue.cs); +} +#endif diff --git a/sdk/lib/rtl/timerqueue.c b/sdk/lib/rtl/timerqueue.c index 596588bdafdf9..195059ae1eab0 100644 --- a/sdk/lib/rtl/timerqueue.c +++ b/sdk/lib/rtl/timerqueue.c @@ -64,405 +64,6 @@ struct timer_queue #define EXPIRE_NEVER (~(ULONGLONG) 0) #define TIMER_QUEUE_MAGIC 0x516d6954 /* TimQ */ -static void queue_remove_timer(struct queue_timer *t) -{ - /* We MUST hold the queue cs while calling this function. This ensures - that we cannot queue another callback for this timer. The runcount - being zero makes sure we don't have any already queued. */ - struct timer_queue *q = t->q; - - assert(t->runcount == 0); - assert(t->destroy); - - list_remove(&t->entry); - if (t->event) - NtSetEvent(t->event, NULL); - RtlFreeHeap(RtlGetProcessHeap(), 0, t); - - if (q->quit && list_empty(&q->timers)) - NtSetEvent(q->event, NULL); -} - -static void timer_cleanup_callback(struct queue_timer *t) -{ - struct timer_queue *q = t->q; - RtlEnterCriticalSection(&q->cs); - - assert(0 < t->runcount); - --t->runcount; - - if (t->destroy && t->runcount == 0) - queue_remove_timer(t); - - RtlLeaveCriticalSection(&q->cs); -} - -static VOID WINAPI timer_callback_wrapper(LPVOID p) -{ - struct queue_timer *t = p; - t->callback(t->param, TRUE); - timer_cleanup_callback(t); -} - -static inline ULONGLONG queue_current_time(void) -{ - LARGE_INTEGER now, freq; - NtQueryPerformanceCounter(&now, &freq); - return now.QuadPart * 1000 / freq.QuadPart; -} - -static void queue_add_timer(struct queue_timer *t, ULONGLONG time, - BOOL set_event) -{ - /* We MUST hold the queue cs while calling this function. */ - struct timer_queue *q = t->q; - struct list *ptr = &q->timers; - - assert(!q->quit || (t->destroy && time == EXPIRE_NEVER)); - - if (time != EXPIRE_NEVER) - LIST_FOR_EACH(ptr, &q->timers) - { - struct queue_timer *cur = LIST_ENTRY(ptr, struct queue_timer, entry); - if (time < cur->expire) - break; - } - list_add_before(ptr, &t->entry); - - t->expire = time; - - /* If we insert at the head of the list, we need to expire sooner - than expected. */ - if (set_event && &t->entry == list_head(&q->timers)) - NtSetEvent(q->event, NULL); -} - -static inline void queue_move_timer(struct queue_timer *t, ULONGLONG time, - BOOL set_event) -{ - /* We MUST hold the queue cs while calling this function. */ - list_remove(&t->entry); - queue_add_timer(t, time, set_event); -} - -static void queue_timer_expire(struct timer_queue *q) -{ - struct queue_timer *t = NULL; - - RtlEnterCriticalSection(&q->cs); - if (list_head(&q->timers)) - { - ULONGLONG now, next; - t = LIST_ENTRY(list_head(&q->timers), struct queue_timer, entry); - if (!t->destroy && t->expire <= ((now = queue_current_time()))) - { - ++t->runcount; - if (t->period) - { - next = t->expire + t->period; - /* avoid trigger cascade if overloaded / hibernated */ - if (next < now) - next = now + t->period; - } - else - next = EXPIRE_NEVER; - queue_move_timer(t, next, FALSE); - } - else - t = NULL; - } - RtlLeaveCriticalSection(&q->cs); - - if (t) - { - if (t->flags & WT_EXECUTEINTIMERTHREAD) - timer_callback_wrapper(t); - else - { - ULONG flags - = (t->flags - & (WT_EXECUTEINIOTHREAD | WT_EXECUTEINPERSISTENTTHREAD - | WT_EXECUTELONGFUNCTION | WT_TRANSFER_IMPERSONATION)); - NTSTATUS status = RtlQueueWorkItem(timer_callback_wrapper, t, flags); - if (status != STATUS_SUCCESS) - timer_cleanup_callback(t); - } - } -} - -static ULONG queue_get_timeout(struct timer_queue *q) -{ - struct queue_timer *t; - ULONG timeout = INFINITE; - - RtlEnterCriticalSection(&q->cs); - if (list_head(&q->timers)) - { - t = LIST_ENTRY(list_head(&q->timers), struct queue_timer, entry); - assert(!t->destroy || t->expire == EXPIRE_NEVER); - - if (t->expire != EXPIRE_NEVER) - { - ULONGLONG time = queue_current_time(); - timeout = t->expire < time ? 0 : (ULONG)(t->expire - time); - } - } - RtlLeaveCriticalSection(&q->cs); - - return timeout; -} - -static DWORD WINAPI timer_queue_thread_proc(LPVOID p) -{ - struct timer_queue *q = p; - ULONG timeout_ms; - - timeout_ms = INFINITE; - for (;;) - { - LARGE_INTEGER timeout; - NTSTATUS status; - BOOL done = FALSE; - - status = NtWaitForSingleObject( - q->event, FALSE, get_nt_timeout(&timeout, timeout_ms)); - - if (status == STATUS_WAIT_0) - { - /* There are two possible ways to trigger the event. Either - we are quitting and the last timer got removed, or a new - timer got put at the head of the list so we need to adjust - our timeout. */ - RtlEnterCriticalSection(&q->cs); - if (q->quit && list_empty(&q->timers)) - done = TRUE; - RtlLeaveCriticalSection(&q->cs); - } - else if (status == STATUS_TIMEOUT) - queue_timer_expire(q); - - if (done) - break; - - timeout_ms = queue_get_timeout(q); - } - - NtClose(q->event); - RtlDeleteCriticalSection(&q->cs); - q->magic = 0; - RtlFreeHeap(RtlGetProcessHeap(), 0, q); - RtlpExitThreadFunc(STATUS_SUCCESS); - return 0; -} - -static void queue_destroy_timer(struct queue_timer *t) -{ - /* We MUST hold the queue cs while calling this function. */ - t->destroy = TRUE; - if (t->runcount == 0) - /* Ensure a timer is promptly removed. If callbacks are pending, - it will be removed after the last one finishes by the callback - cleanup wrapper. */ - queue_remove_timer(t); - else - /* Make sure no destroyed timer masks an active timer at the head - of the sorted list. */ - queue_move_timer(t, EXPIRE_NEVER, FALSE); -} - -/*********************************************************************** - * RtlCreateTimerQueue (NTDLL.@) - * - * Creates a timer queue object and returns a handle to it. - * - * PARAMS - * NewTimerQueue [O] The newly created queue. - * - * RETURNS - * Success: STATUS_SUCCESS. - * Failure: Any NTSTATUS code. - */ -NTSTATUS WINAPI RtlCreateTimerQueue(PHANDLE NewTimerQueue) -{ - NTSTATUS status; - struct timer_queue *q = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof *q); - if (!q) - return STATUS_NO_MEMORY; - - RtlInitializeCriticalSection(&q->cs); - list_init(&q->timers); - q->quit = FALSE; - q->magic = TIMER_QUEUE_MAGIC; - status = NtCreateEvent(&q->event, EVENT_ALL_ACCESS, NULL, SynchronizationEvent, FALSE); - if (status != STATUS_SUCCESS) - { - RtlFreeHeap(RtlGetProcessHeap(), 0, q); - return status; - } - status = RtlpStartThreadFunc(timer_queue_thread_proc, q, &q->thread); - if (status != STATUS_SUCCESS) - { - NtClose(q->event); - RtlFreeHeap(RtlGetProcessHeap(), 0, q); - return status; - } - - NtResumeThread(q->thread, NULL); - *NewTimerQueue = q; - return STATUS_SUCCESS; -} - -/*********************************************************************** - * RtlDeleteTimerQueueEx (NTDLL.@) - * - * Deletes a timer queue object. - * - * PARAMS - * TimerQueue [I] The timer queue to destroy. - * CompletionEvent [I] If NULL, return immediately. If INVALID_HANDLE_VALUE, - * wait until all timers are finished firing before - * returning. Otherwise, return immediately and set the - * event when all timers are done. - * - * RETURNS - * Success: STATUS_SUCCESS if synchronous, STATUS_PENDING if not. - * Failure: Any NTSTATUS code. - */ -NTSTATUS WINAPI RtlDeleteTimerQueueEx(HANDLE TimerQueue, HANDLE CompletionEvent) -{ - struct timer_queue *q = TimerQueue; - struct queue_timer *t, *temp; - HANDLE thread; - NTSTATUS status; - - if (!q || q->magic != TIMER_QUEUE_MAGIC) - return STATUS_INVALID_HANDLE; - - thread = q->thread; - - RtlEnterCriticalSection(&q->cs); - q->quit = TRUE; - if (list_head(&q->timers)) - /* When the last timer is removed, it will signal the timer thread to - exit... */ - LIST_FOR_EACH_ENTRY_SAFE(t, temp, &q->timers, struct queue_timer, entry) - queue_destroy_timer(t); - else - /* However if we have none, we must do it ourselves. */ - NtSetEvent(q->event, NULL); - RtlLeaveCriticalSection(&q->cs); - - if (CompletionEvent == INVALID_HANDLE_VALUE) - { - NtWaitForSingleObject(thread, FALSE, NULL); - status = STATUS_SUCCESS; - } - else - { - if (CompletionEvent) - { - DPRINT1("asynchronous return on completion event unimplemented\n"); - NtWaitForSingleObject(thread, FALSE, NULL); - NtSetEvent(CompletionEvent, NULL); - } - status = STATUS_PENDING; - } - - NtClose(thread); - return status; -} - -static struct timer_queue *get_timer_queue(HANDLE TimerQueue) -{ - static struct timer_queue *default_timer_queue; - - if (TimerQueue) - return TimerQueue; - else - { - if (!default_timer_queue) - { - HANDLE q; - NTSTATUS status = RtlCreateTimerQueue(&q); - if (status == STATUS_SUCCESS) - { - PVOID p = InterlockedCompareExchangePointer( - (void **) &default_timer_queue, q, NULL); - if (p) - /* Got beat to the punch. */ - RtlDeleteTimerQueueEx(q, NULL); - } - } - return default_timer_queue; - } -} - -/*********************************************************************** - * RtlCreateTimer (NTDLL.@) - * - * Creates a new timer associated with the given queue. - * - * PARAMS - * NewTimer [O] The newly created timer. - * TimerQueue [I] The queue to hold the timer. - * Callback [I] The callback to fire. - * Parameter [I] The argument for the callback. - * DueTime [I] The delay, in milliseconds, before first firing the - * timer. - * Period [I] The period, in milliseconds, at which to fire the timer - * after the first callback. If zero, the timer will only - * fire once. It still needs to be deleted with - * RtlDeleteTimer. - * Flags [I] Flags controlling the execution of the callback. In - * addition to the WT_* thread pool flags (see - * RtlQueueWorkItem), WT_EXECUTEINTIMERTHREAD and - * WT_EXECUTEONLYONCE are supported. - * - * RETURNS - * Success: STATUS_SUCCESS. - * Failure: Any NTSTATUS code. - */ -NTSTATUS WINAPI RtlCreateTimer(HANDLE TimerQueue, PHANDLE NewTimer, - WAITORTIMERCALLBACKFUNC Callback, - PVOID Parameter, DWORD DueTime, DWORD Period, - ULONG Flags) -{ - NTSTATUS status; - struct queue_timer *t; - struct timer_queue *q = get_timer_queue(TimerQueue); - - if (!q) return STATUS_NO_MEMORY; - if (q->magic != TIMER_QUEUE_MAGIC) return STATUS_INVALID_HANDLE; - - t = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof *t); - if (!t) - return STATUS_NO_MEMORY; - - t->q = q; - t->runcount = 0; - t->callback = Callback; - t->param = Parameter; - t->period = Period; - t->flags = Flags; - t->destroy = FALSE; - t->event = NULL; - - status = STATUS_SUCCESS; - RtlEnterCriticalSection(&q->cs); - if (q->quit) - status = STATUS_INVALID_HANDLE; - else - queue_add_timer(t, queue_current_time() + DueTime, TRUE); - RtlLeaveCriticalSection(&q->cs); - - if (status == STATUS_SUCCESS) - *NewTimer = t; - else - RtlFreeHeap(RtlGetProcessHeap(), 0, t); - - return status; -} - NTSTATUS WINAPI RtlSetTimer( @@ -483,100 +84,6 @@ RtlSetTimer( Flags); } -/*********************************************************************** - * RtlUpdateTimer (NTDLL.@) - * - * Changes the time at which a timer expires. - * - * PARAMS - * TimerQueue [I] The queue that holds the timer. - * Timer [I] The timer to update. - * DueTime [I] The delay, in milliseconds, before next firing the timer. - * Period [I] The period, in milliseconds, at which to fire the timer - * after the first callback. If zero, the timer will not - * refire once. It still needs to be deleted with - * RtlDeleteTimer. - * - * RETURNS - * Success: STATUS_SUCCESS. - * Failure: Any NTSTATUS code. - */ -NTSTATUS WINAPI RtlUpdateTimer(HANDLE TimerQueue, HANDLE Timer, - DWORD DueTime, DWORD Period) -{ - struct queue_timer *t = Timer; - struct timer_queue *q = t->q; - - RtlEnterCriticalSection(&q->cs); - /* Can't change a timer if it was once-only or destroyed. */ - if (t->expire != EXPIRE_NEVER) - { - t->period = Period; - queue_move_timer(t, queue_current_time() + DueTime, TRUE); - } - RtlLeaveCriticalSection(&q->cs); - - return STATUS_SUCCESS; -} - -/*********************************************************************** - * RtlDeleteTimer (NTDLL.@) - * - * Cancels a timer-queue timer. - * - * PARAMS - * TimerQueue [I] The queue that holds the timer. - * Timer [I] The timer to update. - * CompletionEvent [I] If NULL, return immediately. If INVALID_HANDLE_VALUE, - * wait until the timer is finished firing all pending - * callbacks before returning. Otherwise, return - * immediately and set the timer is done. - * - * RETURNS - * Success: STATUS_SUCCESS if the timer is done, STATUS_PENDING if not, - or if the completion event is NULL. - * Failure: Any NTSTATUS code. - */ -NTSTATUS WINAPI RtlDeleteTimer(HANDLE TimerQueue, HANDLE Timer, - HANDLE CompletionEvent) -{ - struct queue_timer *t = Timer; - struct timer_queue *q; - NTSTATUS status = STATUS_PENDING; - HANDLE event = NULL; - - if (!Timer) - return STATUS_INVALID_PARAMETER_1; - q = t->q; - if (CompletionEvent == INVALID_HANDLE_VALUE) - { - status = NtCreateEvent(&event, EVENT_ALL_ACCESS, NULL, SynchronizationEvent, FALSE); - if (status == STATUS_SUCCESS) - status = STATUS_PENDING; - } - else if (CompletionEvent) - event = CompletionEvent; - - RtlEnterCriticalSection(&q->cs); - t->event = event; - if (t->runcount == 0 && event) - status = STATUS_SUCCESS; - queue_destroy_timer(t); - RtlLeaveCriticalSection(&q->cs); - - if (CompletionEvent == INVALID_HANDLE_VALUE && event) - { - if (status == STATUS_PENDING) - { - NtWaitForSingleObject(event, FALSE, NULL); - status = STATUS_SUCCESS; - } - NtClose(event); - } - - return status; -} - /* * @implemented */ diff --git a/sdk/lib/rtl/wait.c b/sdk/lib/rtl/wait.c deleted file mode 100644 index bab26365d5c87..0000000000000 --- a/sdk/lib/rtl/wait.c +++ /dev/null @@ -1,275 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS system libraries - * PURPOSE: Rtl user wait functions - * FILE: lib/rtl/wait.c - * PROGRAMERS: - * Alex Ionescu (alex@relsoft.net) - * Eric Kohl - * KJK::Hyperion - */ - -/* INCLUDES *****************************************************************/ - -#include - -#define NDEBUG -#include - -typedef struct _RTLP_WAIT -{ - HANDLE Object; - BOOLEAN CallbackInProgress; - HANDLE CancelEvent; - LONG DeleteCount; - HANDLE CompletionEvent; - ULONG Flags; - WAITORTIMERCALLBACKFUNC Callback; - PVOID Context; - ULONG Milliseconds; -} RTLP_WAIT, *PRTLP_WAIT; - -/* PRIVATE FUNCTIONS *******************************************************/ - -static inline PLARGE_INTEGER get_nt_timeout( PLARGE_INTEGER pTime, ULONG timeout ) -{ - if (timeout == INFINITE) return NULL; - pTime->QuadPart = (ULONGLONG)timeout * -10000; - return pTime; -} - -static VOID -NTAPI -Wait_thread_proc(LPVOID Arg) -{ - PRTLP_WAIT Wait = (PRTLP_WAIT) Arg; - NTSTATUS Status; - BOOLEAN alertable = (Wait->Flags & WT_EXECUTEINIOTHREAD) != 0; - HANDLE handles[2] = { Wait->CancelEvent, Wait->Object }; - LARGE_INTEGER timeout; - HANDLE completion_event; - -// TRACE("\n"); - - while (TRUE) - { - Status = NtWaitForMultipleObjects( 2, - handles, - WaitAny, - alertable, - get_nt_timeout( &timeout, Wait->Milliseconds ) ); - - if (Status == STATUS_WAIT_1 || Status == STATUS_TIMEOUT) - { - BOOLEAN TimerOrWaitFired; - - if (Status == STATUS_WAIT_1) - { - // TRACE( "object %p signaled, calling callback %p with context %p\n", - // Wait->Object, Wait->Callback, - // Wait->Context ); - TimerOrWaitFired = FALSE; - } - else - { - // TRACE( "wait for object %p timed out, calling callback %p with context %p\n", - // Wait->Object, Wait->Callback, - // Wait->Context ); - TimerOrWaitFired = TRUE; - } - Wait->CallbackInProgress = TRUE; - Wait->Callback( Wait->Context, TimerOrWaitFired ); - Wait->CallbackInProgress = FALSE; - - if (Wait->Flags & WT_EXECUTEONLYONCE) - break; - } - else if (Status != STATUS_USER_APC) - break; - } - - completion_event = Wait->CompletionEvent; - if (completion_event) NtSetEvent( completion_event, NULL ); - - if (InterlockedIncrement( &Wait->DeleteCount ) == 2 ) - { - NtClose( Wait->CancelEvent ); - RtlFreeHeap( RtlGetProcessHeap(), 0, Wait ); - } -} - - -/* FUNCTIONS ***************************************************************/ - - -/*********************************************************************** - * RtlRegisterWait - * - * Registers a wait for a handle to become signaled. - * - * PARAMS - * NewWaitObject [I] Handle to the new wait object. Use RtlDeregisterWait() to free it. - * Object [I] Object to wait to become signaled. - * Callback [I] Callback function to execute when the wait times out or the handle is signaled. - * Context [I] Context to pass to the callback function when it is executed. - * Milliseconds [I] Number of milliseconds to wait before timing out. - * Flags [I] Flags. See notes. - * - * RETURNS - * Success: STATUS_SUCCESS. - * Failure: Any NTSTATUS code. - * - * NOTES - * Flags can be one or more of the following: - *|WT_EXECUTEDEFAULT - Executes the work item in a non-I/O worker thread. - *|WT_EXECUTEINIOTHREAD - Executes the work item in an I/O worker thread. - *|WT_EXECUTEINPERSISTENTTHREAD - Executes the work item in a thread that is persistent. - *|WT_EXECUTELONGFUNCTION - Hints that the execution can take a long time. - *|WT_TRANSFER_IMPERSONATION - Executes the function with the current access token. - */ -NTSTATUS -NTAPI -RtlRegisterWait(PHANDLE NewWaitObject, - HANDLE Object, - WAITORTIMERCALLBACKFUNC Callback, - PVOID Context, - ULONG Milliseconds, - ULONG Flags) -{ - PRTLP_WAIT Wait; - NTSTATUS Status; - - //TRACE( "(%p, %p, %p, %p, %d, 0x%x)\n", NewWaitObject, Object, Callback, Context, Milliseconds, Flags ); - - Wait = RtlAllocateHeap( RtlGetProcessHeap(), 0, sizeof(RTLP_WAIT) ); - if (!Wait) - return STATUS_NO_MEMORY; - - Wait->Object = Object; - Wait->Callback = Callback; - Wait->Context = Context; - Wait->Milliseconds = Milliseconds; - Wait->Flags = Flags; - Wait->CallbackInProgress = FALSE; - Wait->DeleteCount = 0; - Wait->CompletionEvent = NULL; - - Status = NtCreateEvent( &Wait->CancelEvent, - EVENT_ALL_ACCESS, - NULL, - NotificationEvent, - FALSE ); - - if (Status != STATUS_SUCCESS) - { - RtlFreeHeap( RtlGetProcessHeap(), 0, Wait ); - return Status; - } - - Flags = Flags & (WT_EXECUTEINIOTHREAD | WT_EXECUTEINPERSISTENTTHREAD | - WT_EXECUTELONGFUNCTION | WT_TRANSFER_IMPERSONATION); - - Status = RtlQueueWorkItem( Wait_thread_proc, - Wait, - Flags ); - - if (Status != STATUS_SUCCESS) - { - NtClose( Wait->CancelEvent ); - RtlFreeHeap( RtlGetProcessHeap(), 0, Wait ); - return Status; - } - - *NewWaitObject = Wait; - return Status; -} - -/*********************************************************************** - * RtlDeregisterWaitEx - * - * Cancels a wait operation and frees the resources associated with calling - * RtlRegisterWait(). - * - * PARAMS - * WaitObject [I] Handle to the wait object to free. - * - * RETURNS - * Success: STATUS_SUCCESS. - * Failure: Any NTSTATUS code. - */ -NTSTATUS -NTAPI -RtlDeregisterWaitEx(HANDLE WaitHandle, - HANDLE CompletionEvent) -{ - PRTLP_WAIT Wait = (PRTLP_WAIT) WaitHandle; - NTSTATUS Status = STATUS_SUCCESS; - - //TRACE( "(%p)\n", WaitHandle ); - - NtSetEvent( Wait->CancelEvent, NULL ); - if (Wait->CallbackInProgress) - { - if (CompletionEvent != NULL) - { - if (CompletionEvent == INVALID_HANDLE_VALUE) - { - Status = NtCreateEvent( &CompletionEvent, - EVENT_ALL_ACCESS, - NULL, - NotificationEvent, - FALSE ); - - if (Status != STATUS_SUCCESS) - return Status; - - (void)InterlockedExchangePointer( &Wait->CompletionEvent, CompletionEvent ); - - if (Wait->CallbackInProgress) - NtWaitForSingleObject( CompletionEvent, FALSE, NULL ); - - NtClose( CompletionEvent ); - } - else - { - (void)InterlockedExchangePointer( &Wait->CompletionEvent, CompletionEvent ); - - if (Wait->CallbackInProgress) - Status = STATUS_PENDING; - } - } - else - Status = STATUS_PENDING; - } - - if (InterlockedIncrement( &Wait->DeleteCount ) == 2 ) - { - Status = STATUS_SUCCESS; - NtClose( Wait->CancelEvent ); - RtlFreeHeap( RtlGetProcessHeap(), 0, Wait ); - } - - return Status; -} - -/*********************************************************************** - * RtlDeregisterWait - * - * Cancels a wait operation and frees the resources associated with calling - * RtlRegisterWait(). - * - * PARAMS - * WaitObject [I] Handle to the wait object to free. - * - * RETURNS - * Success: STATUS_SUCCESS. - * Failure: Any NTSTATUS code. - */ -NTSTATUS -NTAPI -RtlDeregisterWait(HANDLE WaitHandle) -{ - return RtlDeregisterWaitEx(WaitHandle, NULL); -} - -/* EOF */ diff --git a/sdk/lib/ucrt/CMakeLists.txt b/sdk/lib/ucrt/CMakeLists.txt new file mode 100644 index 0000000000000..526935896f868 --- /dev/null +++ b/sdk/lib/ucrt/CMakeLists.txt @@ -0,0 +1,127 @@ + +set(CMAKE_CXX_STANDARD 17) + +# Replace the old CRT include directory with the UCRT include directory +get_property(INCLUDE_DIRS DIRECTORY . PROPERTY INCLUDE_DIRECTORIES) +list(REMOVE_ITEM INCLUDE_DIRS "${REACTOS_SOURCE_DIR}/sdk/include/crt") +set_property(DIRECTORY . PROPERTY INCLUDE_DIRECTORIES ${INCLUDE_DIRS}) +include_directories(${REACTOS_SOURCE_DIR}/sdk/include/ucrt) + +if(MSVC) + # Disable warning C4083: expected ')'; found identifier '' + add_compile_options($<$:/wd4083>) + + # Disable warning C4189: 'cvt': local variable is initialized but not referenced + add_compile_options($<$:/wd4189>) +endif() + +# Internal includes +include_directories(BEFORE inc) + +if(${ARCH} STREQUAL "i386") + include_directories(inc/i386) +endif() + +remove_definitions(-D_WIN32_WINNT=0x502 -DWINVER=0x502) +add_compile_definitions( + WINVER=0x600 + _WIN32_WINNT=0x600 + _UCRT + _CORECRT_BUILD + _CRT_DECLARE_GLOBAL_VARIABLES_DIRECTLY + _GCC_NO_SAL_ATTRIIBUTES + CRTDLL +) + +if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR + CMAKE_C_COMPILER_ID STREQUAL "Clang") + # Silence GCC/Clang warnings + add_compile_options( + -Wno-unknown-warning-option + -Wno-unused-function + -Wno-unknown-pragmas + -Wno-builtin-declaration-mismatch + -Wno-parentheses + -Wno-unused-variable + -Wno-sign-compare + -Wno-enum-compare + -Wno-switch + -Wno-write-strings + -Wno-comment + -Wno-narrowing + -Wno-misleading-indentation + -Wno-missing-braces + -Wno-unused-value + -Wno-unused-local-typedef + -Wno-unused-function + -Wno-writable-strings + -Wno-microsoft-template + -Wno-switch + -Wno-ignored-pragmas + -Wno-empty-body + -Wno-tautological-constant-out-of-range-compare + -Wno-ignored-attributes + -Wno-uninitialized + ) + add_compile_options($<$:-Wno-reorder>) +endif() + +if(CMAKE_C_COMPILER_ID STREQUAL "Clang") + add_compile_definitions( + _lrotl=___lrotl + _rotl=___rotl + _rotl64=___rotl64 + _lrotr=___lrotr + _rotr=___rotr + _rotr64=___rotr64 + ) +endif() + +include(conio/conio.cmake) +include(convert/convert.cmake) +include(dll/dll.cmake) +include(env/env.cmake) +include(exec/exec.cmake) +include(filesystem/filesystem.cmake) +include(float/float.cmake) +include(heap/heap.cmake) +include(initializers/initializers.cmake) +include(internal/internal.cmake) +include(locale/locale.cmake) +include(lowio/lowio.cmake) +include(math/math.cmake) +include(mbstring/mbstring.cmake) +include(misc/misc.cmake) +include(startup/startup.cmake) +include(stdio/stdio.cmake) +include(stdlib/stdlib.cmake) +include(string/string.cmake) +include(time/time.cmake) + +# TODO: build a _DEBUG version +add_library(ucrt OBJECT + ${UCRT_CONIO_SOURCES} + ${UCRT_CONVERT_SOURCES} + ${UCRT_DLL_SOURCES} + ${UCRT_ENV_SOURCES} + ${UCRT_EXEC_SOURCES} + ${UCRT_FILESYSTEM_SOURCES} + ${UCRT_FLOAT_SOURCES} + ${UCRT_HEAP_SOURCES} + ${UCRT_INITIALIZERS_SOURCES} + ${UCRT_INTERNAL_SOURCES} + ${UCRT_LOCALE_SOURCES} + ${UCRT_LOWIO_SOURCES} + ${UCRT_MATH_SOURCES} + ${UCRT_MBSTRING_SOURCES} + ${UCRT_MISC_SOURCES} + ${UCRT_STARTUP_SOURCES} + ${UCRT_STDIO_SOURCES} + ${UCRT_STDLIB_SOURCES} + ${UCRT_STRING_SOURCES} + ${UCRT_TIME_SOURCES} + ${UCRT_VCRUNTIME_SOURCES} +) + +target_link_libraries(ucrt vcruntime) +add_dependencies(ucrt psdk asm) diff --git a/sdk/lib/ucrt/conio/cgets.cpp b/sdk/lib/ucrt/conio/cgets.cpp new file mode 100644 index 0000000000000..7ec4ae6dcfe60 --- /dev/null +++ b/sdk/lib/ucrt/conio/cgets.cpp @@ -0,0 +1,129 @@ +// +// cgets.cpp +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// Defines _cgets() and _cgets_s(), which read a string from the console. +// +#include +#include +#include + + + +extern "C" { extern intptr_t __dcrt_lowio_console_input_handle; } + + + +// Use of the following buffer variables is primarily for syncronizing with +// _cgets_s. _cget_s fills the MBCS buffer and if the user passes in single +// character buffer and the unicode character is not converted to single byte +// MBC, then _cget_s should buffer that character so that next call to +// _cgetws_s can return the same character. +extern "C" { extern wchar_t __console_wchar_buffer; } +extern "C" { extern int __console_wchar_buffer_used; } + + + +// Reads a string from the console; always null-terminates the buffer. Returns +// 0 on success; returns an errno error code on failure. +extern "C" errno_t __cdecl _cgets_s(char* const source_string, size_t const size_in_bytes, size_t* const size_read) +{ + _VALIDATE_CLEAR_OSSERR_RETURN_ERRCODE(source_string != nullptr, EINVAL); + _VALIDATE_CLEAR_OSSERR_RETURN_ERRCODE(size_in_bytes > 0, EINVAL); + _RESET_STRING(source_string, size_in_bytes); + + _VALIDATE_CLEAR_OSSERR_RETURN_ERRCODE(size_read != nullptr, EINVAL); + + errno_t error = 0; + char* string = source_string; + + __acrt_lock(__acrt_conio_lock); + __try + { + // The implementation of cgets is slightly tricky. The reason being, + // the code page for console is different from the CRT code page. + // What this means is the program may interpret character + // differently from it's acctual value. To fix this, what we really + // want to do is read the input as unicode string and then convert + // it to proper MBCS representation. + // + // This fix this we are really converting from Unicode to MBCS. + // This adds performance problem as we may endup doing this + // character by character. The basic problem here is that we have + // no way to know how many UNICODE characters will be needed to fit + // them in given size of MBCS buffer. To fix this issue we will be + // converting one Unicode character at a time to MBCS. This makes + // this slow, but then this is already console input, + *size_read = 0; + + size_t available = size_in_bytes - 1; + do + { + wchar_t wchar_buff[2]; + size_t sizeRead = 0; + + error = _cgetws_s(wchar_buff, _countof(wchar_buff), &sizeRead); + if (error != 0) + break; + + if (wchar_buff[0] == '\0') + break; + + int size_converted = 0; + errno_t const wctomb_result = wctomb_s(&size_converted, string, available, wchar_buff[0]); + if (wctomb_result != 0) + { + // Put the wide character back in the buffer so that the + // unutilized wide character is still in the stream: + __console_wchar_buffer = wchar_buff[0]; + __console_wchar_buffer_used = 1; + break; + } + + string += size_converted; + *size_read += size_converted; + available -= size_converted; + } + while (available > 0); + } + __finally + { + __acrt_unlock(__acrt_conio_lock); + } + __endtry + + *string++ = '\0'; + + if (error != 0) + errno = error; + + return error; +} + + + +// Reads a string from the console via ReadConsole on a cooked console handle. +// string[0] must contain the maximum length of the string. The number of +// characters written is stored in string[1]. The return value is a pointer to +// string[2] on success; nullptr on failure. +extern "C" char* __cdecl _cgets(_Inout_z_ char* const string) +{ + _VALIDATE_CLEAR_OSSERR_RETURN(string != nullptr, EINVAL, nullptr); + _VALIDATE_CLEAR_OSSERR_RETURN(string[0] > 0, EINVAL, nullptr); + + size_t const size_in_bytes = static_cast(string[0]); + + size_t size_read = 0; + // warning 26018: Potential overflow of null terminated buffer using expression string+2 + // Suppressing warning since _cgets is purposefully unsafe. +#pragma warning(suppress:__WARNING_POTENTIAL_BUFFER_OVERFLOW_NULLTERMINATED) + errno_t const result = _cgets_s(string + 2, size_in_bytes, &size_read); + + // warning 26018: Potential overflow of null terminated buffer using expression string[1] + // Suppressing warning since _cgets is purposefully unsafe. +#pragma warning(suppress:__WARNING_POTENTIAL_BUFFER_OVERFLOW_NULLTERMINATED) + string[1] = static_cast(size_read); + + return result == 0 ? string + 2 : nullptr; +} diff --git a/sdk/lib/ucrt/conio/cgetws.cpp b/sdk/lib/ucrt/conio/cgetws.cpp new file mode 100644 index 0000000000000..3b40b722a3c39 --- /dev/null +++ b/sdk/lib/ucrt/conio/cgetws.cpp @@ -0,0 +1,157 @@ +// +// cgetws.cpp +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// Defines _cgetws() and _cgetws_s(), which read a wide string from the console. +// +#include +#include +#include +#include + +// Use of the following buffer variables is primarily for syncronizing with +// _cgets_s. _cget_s fills the MBCS buffer and if the user passes in single +// character buffer and the unicode character is not converted to single byte +// MBC, then _cget_s should buffer that character so that next call to +// _cgetws_s can return the same character. +extern "C" { wchar_t __console_wchar_buffer = 0; } +extern "C" { int __console_wchar_buffer_used = 0; } + + + +// Reads a string from the console; always null-terminates the buffer. Returns +// 0 on success; returns an errno error code on failure. +extern "C" errno_t __cdecl _cgetws_s(wchar_t* const string_buffer, size_t const size_in_words, size_t* const size_read) +{ + _VALIDATE_CLEAR_OSSERR_RETURN_ERRCODE(string_buffer != nullptr, EINVAL); + _VALIDATE_CLEAR_OSSERR_RETURN_ERRCODE(size_in_words > 0, EINVAL); + _RESET_STRING(string_buffer, size_in_words); + + _VALIDATE_CLEAR_OSSERR_RETURN_ERRCODE(size_read != nullptr, EINVAL); + + __acrt_lock(__acrt_conio_lock); + errno_t retval = 0; + __try + { + wchar_t* string = string_buffer; + + // We need to decrement size_in_words because ReadConsole reads as many + // characters as the parameter passed. It doesn't null-terminate: + size_t size_remaining = size_in_words - 1; + *size_read = 0; + + // If size_in_words was 1, then there's only room for the null terminator: + if (size_remaining == 0) + __leave; + + // If there is a buffered character, first fill with the buffered + // character then proceed with reading from the console: + if (__console_wchar_buffer_used != 0) + { + *string++ = __console_wchar_buffer; + --size_remaining; + (*size_read)++; + + if (__console_wchar_buffer == L'\0') + size_remaining = 0; + + __console_wchar_buffer = 0; + } + + if (size_remaining == 0) + __leave; + + /* + * __dcrt_lowio_console_input_handle, the handle to the console input, is created the first + * time that either _getch() or _cgets() or _kbhit() is called. + */ + + if (__dcrt_lowio_ensure_console_input_initialized() == FALSE) + { + __acrt_errno_map_os_error(GetLastError()); + retval = errno; + __leave; + } + + ULONG old_state; + __dcrt_get_input_console_mode(&old_state); + __dcrt_set_input_console_mode(ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_ECHO_INPUT); + + ULONG wchars_read; + BOOL read_console_result = __dcrt_read_console( + string, + static_cast(size_remaining), + &wchars_read); + + if (!read_console_result) + { + __acrt_errno_map_os_error(GetLastError()); + retval = errno; + __leave; + } + + // Set the length of the string and null terminate it: + if (wchars_read >= 2 && string[wchars_read - 2] == L'\r') + { + *size_read += wchars_read - 2; + string[wchars_read - 2] = L'\0'; + } + else if (wchars_read == size_remaining && string[wchars_read - 1] == L'\r') + { + // Special case 1: \r\n straddles the boundary: + string[wchars_read - 1] = L'\0'; + *size_read += wchars_read - 1; + } + else if (wchars_read == 1 && string[0] == L'\n') + { + // Special case 2: Read a single \n: + string[0] = L'\0'; + *size_read += 0; + } + else + { + *size_read += wchars_read; + string[wchars_read] = L'\0'; + } + + __dcrt_set_input_console_mode(old_state); + } + __finally + { + __acrt_unlock(__acrt_conio_lock); + } + __endtry + + return retval; +} + + + +// Reads a string from the console via ReadConsole on a cooked console handle. +// string[0] must contain the maximum length of the string. The number of +// characters written is stored in string[1]. The return value is a pointer to +// string[2] on success; nullptr on failure. +// +// Note that _cgetws() does NOT check the pushback character buffer, so it will +// not return any character that is pushed back by a call to _ungetwch(). +extern "C" wchar_t* __cdecl _cgetws(_Inout_z_ wchar_t* const string) +{ + _VALIDATE_CLEAR_OSSERR_RETURN(string != nullptr, EINVAL, nullptr); + _VALIDATE_CLEAR_OSSERR_RETURN(string[0] > 0, EINVAL, nullptr); + + size_t const size_in_words = static_cast(string[0]); + + size_t size_read = 0; + // warning 26018: Potential overflow of null terminated buffer using expression string+2 + // Suppressing warning since _cgetws is purposefully unsafe. +#pragma warning(suppress:__WARNING_POTENTIAL_BUFFER_OVERFLOW_NULLTERMINATED) + errno_t const result = _cgetws_s(string + 2, size_in_words, &size_read); + + // warning 26018: Potential overflow of null terminated buffer using expression string[1] + // Suppressing warning since _cgetws is purposefully unsafe. +#pragma warning(suppress:__WARNING_POTENTIAL_BUFFER_OVERFLOW_NULLTERMINATED) + string[1] = static_cast(size_read); + + return result == 0 ? string + 2 : nullptr; +} diff --git a/sdk/lib/ucrt/conio/conio.cmake b/sdk/lib/ucrt/conio/conio.cmake new file mode 100644 index 0000000000000..7e6e7842f2835 --- /dev/null +++ b/sdk/lib/ucrt/conio/conio.cmake @@ -0,0 +1,17 @@ + +list(APPEND UCRT_CONIO_SOURCES + conio/cgets.cpp + conio/cgetws.cpp + conio/cprintf.cpp + conio/cputs.cpp + conio/cputws.cpp + conio/cscanf.cpp + conio/getch.cpp + conio/getwch.cpp + conio/initcon.cpp + conio/initconin.cpp + conio/pipe.cpp + conio/popen.cpp + conio/putch.cpp + conio/putwch.cpp +) diff --git a/sdk/lib/ucrt/conio/cprintf.cpp b/sdk/lib/ucrt/conio/cprintf.cpp new file mode 100644 index 0000000000000..17da406e18dad --- /dev/null +++ b/sdk/lib/ucrt/conio/cprintf.cpp @@ -0,0 +1,104 @@ +// +// cprintf.cpp +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The standard output functions, which perform formatted output to the +// console. +// +#include + + +using namespace __crt_stdio_output; + + + +template